diff options
Diffstat (limited to 'src')
104 files changed, 6554 insertions, 4450 deletions
diff --git a/src/devices/bus/a2bus/mouse.cpp b/src/devices/bus/a2bus/mouse.cpp index 6c0c7410c9a..9a4c7526ee6 100644 --- a/src/devices/bus/a2bus/mouse.cpp +++ b/src/devices/bus/a2bus/mouse.cpp @@ -66,15 +66,9 @@ #include "mouse.h" /*************************************************************************** - PARAMETERS + CONSTANTS ***************************************************************************/ -//************************************************************************** -// GLOBAL VARIABLES -//************************************************************************** - -const device_type A2BUS_MOUSE = &device_creator<a2bus_mouse_device>; - #define MOUSE_ROM_REGION "a2mse_rom" #define MOUSE_PIA_TAG "a2mse_pia" #define MOUSE_MCU_TAG "a2mse_mcu" @@ -83,9 +77,14 @@ const device_type A2BUS_MOUSE = &device_creator<a2bus_mouse_device>; #define MOUSE_XAXIS_TAG "a2mse_x" #define MOUSE_YAXIS_TAG "a2mse_y" -#define TIMER_QUADRATURE 0 -MACHINE_CONFIG_FRAGMENT( mouse ) +/*************************************************************************** + GLOBAL VARIABLES +***************************************************************************/ + +const device_type A2BUS_MOUSE = &device_creator<a2bus_mouse_device>; + +static MACHINE_CONFIG_FRAGMENT( mouse ) MCFG_CPU_ADD(MOUSE_MCU_TAG, M68705P3, 2043600) MCFG_M68705_PORTA_R_CB(READ8(a2bus_mouse_device, mcu_port_a_r)) MCFG_M68705_PORTB_R_CB(READ8(a2bus_mouse_device, mcu_port_b_r)) @@ -123,92 +122,85 @@ static INPUT_PORTS_START( mouse ) PORT_BIT( 0xff, 0x00, IPT_MOUSE_Y) PORT_SENSITIVITY(40) PORT_KEYDELTA(0) PORT_PLAYER(1) INPUT_PORTS_END + /*************************************************************************** - FUNCTION PROTOTYPES + DEVICE CONFIGURATION ***************************************************************************/ -//------------------------------------------------- -// input_ports - device-specific input ports -//------------------------------------------------- +/*------------------------------------------------- + input_ports - device-specific input ports +-------------------------------------------------*/ ioport_constructor a2bus_mouse_device::device_input_ports() const { - return INPUT_PORTS_NAME( mouse ); + return INPUT_PORTS_NAME(mouse); } -//------------------------------------------------- -// machine_config_additions - device-specific -// machine configurations -//------------------------------------------------- +/*------------------------------------------------- + machine_config_additions - device-specific + machine configurations +-------------------------------------------------*/ machine_config_constructor a2bus_mouse_device::device_mconfig_additions() const { - return MACHINE_CONFIG_NAME( mouse ); + return MACHINE_CONFIG_NAME(mouse); } -//------------------------------------------------- -// rom_region - device-specific ROM region -//------------------------------------------------- +/*------------------------------------------------- + rom_region - device-specific ROM region +-------------------------------------------------*/ const tiny_rom_entry *a2bus_mouse_device::device_rom_region() const { - return ROM_NAME( mouse ); + return ROM_NAME(mouse); } -//************************************************************************** -// LIVE DEVICE -//************************************************************************** + +/*************************************************************************** + LIVE DEVICE +***************************************************************************/ a2bus_mouse_device::a2bus_mouse_device(const machine_config &mconfig, device_type type, const char *name, const char *tag, device_t *owner, uint32_t clock, const char *shortname, const char *source) : device_t(mconfig, type, name, tag, owner, clock, shortname, source), device_a2bus_card_interface(mconfig, *this), m_pia(*this, MOUSE_PIA_TAG), m_mcu(*this, MOUSE_MCU_TAG), - m_mouseb(*this, MOUSE_BUTTON_TAG), m_mousex(*this, MOUSE_XAXIS_TAG), m_mousey(*this, MOUSE_YAXIS_TAG), + m_mouseb(*this, MOUSE_BUTTON_TAG), m_mousexy(*this, { MOUSE_XAXIS_TAG, MOUSE_YAXIS_TAG }), m_rom(*this, MOUSE_ROM_REGION), + m_rom_bank(0), m_port_a_in(0), m_port_b_in(0), - last_mx(0), last_my(0), count_x(0), count_y(0), - m_read_timer(nullptr) + m_last{ 0, 0 }, m_count{ 0, 0 } { - m_rom_bank = 0; } a2bus_mouse_device::a2bus_mouse_device(const machine_config &mconfig, const char *tag, device_t *owner, uint32_t clock) : a2bus_mouse_device(mconfig, A2BUS_MOUSE, "Apple II Mouse Card", tag, owner, clock, "a2mouse", __FILE__) { - m_rom_bank = 0; } -//------------------------------------------------- -// device_start - device-specific startup -//------------------------------------------------- +/*------------------------------------------------- + device_start - device-specific startup +-------------------------------------------------*/ void a2bus_mouse_device::device_start() { // set_a2bus_device makes m_slot valid set_a2bus_device(); - // allocate a timer for the quadrature magic - m_read_timer = timer_alloc(TIMER_QUADRATURE, nullptr); - m_read_timer->adjust(attotime::never, TIMER_QUADRATURE); - // register save state variables save_item(NAME(m_port_a_in)); save_item(NAME(m_port_b_in)); - save_item(NAME(last_mx)); - save_item(NAME(last_my)); - save_item(NAME(count_x)); - save_item(NAME(count_y)); + save_item(NAME(m_last)); + save_item(NAME(m_count)); + + m_port_b_in = 0x00; } void a2bus_mouse_device::device_reset() { m_rom_bank = 0; - last_mx = last_my = count_x = count_y = 0; - m_port_a_in = 0; - m_port_b_in = 0x80; - - m_read_timer->adjust(attotime::from_hz(600.0), TIMER_QUADRATURE, attotime::from_hz(600.0)); + m_last[0] = m_last[1] = m_count[0] = m_count[1] = 0; + m_port_a_in = 0x00; } /*------------------------------------------------- @@ -220,7 +212,6 @@ uint8_t a2bus_mouse_device::read_c0nx(address_space &space, uint8_t offset) return m_pia->read(space, offset & 3); } - /*------------------------------------------------- write_c0nx - called for writes to this card's c0nx space -------------------------------------------------*/ @@ -271,12 +262,28 @@ WRITE8_MEMBER(a2bus_mouse_device::mcu_port_a_w) READ8_MEMBER(a2bus_mouse_device::mcu_port_b_r) { - uint8_t b_in = m_port_b_in; + enum { XAXIS, YAXIS }; + constexpr u8 BUTTON = 0x80; + constexpr u8 X0 = 0x02; // gate, must go 0/1 for each pixel moved + constexpr u8 X1 = 0x01; // direction, 0 = left, 1 = right + constexpr u8 Y0 = 0x04; // direction, 0 = up, 1 = down + constexpr u8 Y1 = 0x08; // gate, must go 0/1 for each pixel moved + + // update button now + if (m_mouseb->read()) + { + m_port_b_in &= ~BUTTON; + } + else + { + m_port_b_in |= BUTTON; + } - // clear the gates, leave everything else alone between pulses - m_port_b_in &= 0x85; + // update the axes + update_axis<XAXIS, X1, X0>(); + update_axis<YAXIS, Y0, Y1>(); - return b_in; + return m_port_b_in; } WRITE8_MEMBER(a2bus_mouse_device::mcu_port_b_w) @@ -296,83 +303,35 @@ WRITE8_MEMBER(a2bus_mouse_device::mcu_port_c_w) m_pia->portb_w(data << 4); } -/* - X0 = direction, 0 = left, 1 = right - X1 = gate, must go 0/1 for each pixel moved - Y0 = direction, 0 = up, 1 = down - Y1 = gate, must go 0/1 for each pixel moved - - The direction must stay constant for a given train of gate pulses or the MCU will get confused. -*/ -void a2bus_mouse_device::device_timer(emu_timer &timer, device_timer_id id, int param, void *ptr) +template <unsigned AXIS, u8 DIR, u8 CLK> void a2bus_mouse_device::update_axis() { - if (id == TIMER_QUADRATURE) - { - int new_mx, new_my; - m_port_b_in = 0x80; + // read the axis + const int new_m = m_mousexy[AXIS]->read(); - // update button now - if (m_mouseb->read()) m_port_b_in &= ~0x80; + // did it change? + int diff = new_m - m_last[AXIS]; - // read the axes - new_mx = m_mousex->read(); - new_my = m_mousey->read(); + // check for wrap + if (diff > 0x80) + diff = 0x100 - diff; + if (diff < -0x80) + diff = -0x100 - diff; - // did X change? - if (new_mx != last_mx) - { - int diff = new_mx - last_mx; - - /* check for wrap */ - if (diff > 0x80) - diff = 0x100-diff; - if (diff < -0x80) - diff = -0x100-diff; - - count_x += diff; - last_mx = new_mx; - } - - // did Y change? - if (new_my != last_my) - { - int diff = new_my - last_my; - - /* check for wrap */ - if (diff > 0x80) - diff = 0x100-diff; - if (diff < -0x80) - diff = -0x100-diff; + m_count[AXIS] += diff; + m_last[AXIS] = new_m; - count_y += diff; - last_my = new_my; - } - - if (count_x) + if (m_count[AXIS]) + { + m_port_b_in ^= CLK; + if (m_count[AXIS] < 0) { - if (count_x < 0) - { - count_x++; - } - else - { - count_x--; - m_port_b_in |= 0x01; // X1 - } - m_port_b_in |= 0x02; // X0 + m_count[AXIS]++; + if (m_port_b_in & CLK) m_port_b_in &= ~DIR; } - else if (count_y) + else { - if (count_y < 0) - { - count_y++; - } - else - { - count_y--; - m_port_b_in |= 0x04; // Y0 - } - m_port_b_in |= 0x08; // Y1 + m_count[AXIS]--; + if (m_port_b_in & CLK) m_port_b_in |= DIR; } } } diff --git a/src/devices/bus/a2bus/mouse.h b/src/devices/bus/a2bus/mouse.h index c5a36319d79..b3148eaa7ff 100644 --- a/src/devices/bus/a2bus/mouse.h +++ b/src/devices/bus/a2bus/mouse.h @@ -8,8 +8,8 @@ *********************************************************************/ -#ifndef __A2BUS_MOUSE__ -#define __A2BUS_MOUSE__ +#ifndef MAME_DEVICES_A2BUS_MOUSE_H +#define MAME_DEVICES_A2BUS_MOUSE_H #include "emu.h" #include "a2bus.h" @@ -33,7 +33,6 @@ public: virtual machine_config_constructor device_mconfig_additions() const override; virtual const tiny_rom_entry *device_rom_region() const 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; DECLARE_WRITE8_MEMBER(pia_out_a); DECLARE_WRITE8_MEMBER(pia_out_b); @@ -57,18 +56,19 @@ protected: required_device<pia6821_device> m_pia; required_device<m68705p_device> m_mcu; - required_ioport m_mouseb, m_mousex, m_mousey; + required_ioport m_mouseb; + required_ioport_array<2> m_mousexy; private: + template <unsigned AXIS, u8 DIR, u8 CLK> void update_axis(); + required_region_ptr<uint8_t> m_rom; int m_rom_bank; - uint8_t m_port_a_in; - uint8_t m_port_b_in; - int last_mx, last_my, count_x, count_y; - emu_timer *m_read_timer; + uint8_t m_port_a_in, m_port_b_in; + int m_last[2], m_count[2]; }; // device type definition extern const device_type A2BUS_MOUSE; -#endif /* __A2BUS_MOUSE__ */ +#endif // MAME_DEVICES_A2BUS_MOUSE_H diff --git a/src/devices/cpu/cop400/cop400.cpp b/src/devices/cpu/cop400/cop400.cpp index a7bc8230b5b..9f5d7f7ae47 100644 --- a/src/devices/cpu/cop400/cop400.cpp +++ b/src/devices/cpu/cop400/cop400.cpp @@ -10,29 +10,28 @@ Type ROM RAM G D IN - COP410 512x8 32x4 none - COP411 512x8 32x4 0-2 0-1 none - COP401 none 32x4 none - COP413? - COP414? - COP415? - COP405? + COP410 512x8 32x4 N/A + COP411 512x8 32x4 0-2 0-1 N/A + COP413 512x8 32x4 N/A N/A + COP401 N/A 32x4 N/A COP420 1024x8 64x4 - COP421 1024x8 64x4 none - COP422 1024x8 64x4 2-3 2-3 none - COP402 none 64x4 - - COP444 2048x8 128x4 - COP445 2048x8 128x4 none - COP424 1024x8 64x4 - COP425 1024x8 64x4 none - COP426 1024x8 64x4 2-3 2-3 - COP404 none none - - COP440 2048x8 160x4 - COP441 2048x8 160x4 - COP442 2048x8 160x4 + COP421 1024x8 64x4 N/A + COP422 1024x8 64x4 2-3 2-3 N/A + COP402 N/A 64x4 + + COP444L 2048x8 128x4 + COP445L 2048x8 128x4 N/A + COP404L N/A 128x4 + + COP424C 1024x8 64x4 + COP425C 1024x8 64x4 N/A + COP426C 1024x8 64x4 2-3 2-3 + + COP444C 2048x8 128x4 + COP445C 2048x8 128x4 N/A + COP446C 2048x8 128x4 2-3 2-3 + COP404C N/A 128x4 **************************************************************************** @@ -48,10 +47,9 @@ TODO: - - CKO sync input + - COP410L/COP410C - save internal RAM when CKO is RAM power supply pin - - COP413/COP414/COP415/COP405 - - COP404 opcode map switching, dual timer, microbus enable + - COP404L opcode map switching, dual timer, microbus enable */ @@ -67,12 +65,17 @@ const device_type COP402 = &device_creator<cop402_cpu_device>; const device_type COP420 = &device_creator<cop420_cpu_device>; const device_type COP421 = &device_creator<cop421_cpu_device>; const device_type COP422 = &device_creator<cop422_cpu_device>; -const device_type COP404 = &device_creator<cop404_cpu_device>; -const device_type COP424 = &device_creator<cop424_cpu_device>; -const device_type COP425 = &device_creator<cop425_cpu_device>; -const device_type COP426 = &device_creator<cop426_cpu_device>; -const device_type COP444 = &device_creator<cop444_cpu_device>; -const device_type COP445 = &device_creator<cop445_cpu_device>; +const device_type COP404L = &device_creator<cop404l_cpu_device>; +const device_type COP444L = &device_creator<cop444l_cpu_device>; +const device_type COP445L = &device_creator<cop445l_cpu_device>; +const device_type COP404C = &device_creator<cop404c_cpu_device>; +const device_type COP424C = &device_creator<cop424c_cpu_device>; +const device_type COP425C = &device_creator<cop425c_cpu_device>; +const device_type COP426C = &device_creator<cop426c_cpu_device>; +const device_type COP444C = &device_creator<cop444c_cpu_device>; +const device_type COP445C = &device_creator<cop445c_cpu_device>; +const device_type COP446C = &device_creator<cop446c_cpu_device>; + /*************************************************************************** @@ -203,8 +206,17 @@ cop400_cpu_device::cop400_cpu_device(const machine_config &mconfig, device_type } break; - case COP444_FEATURE: - m_opcode_map = COP444_OPCODE_MAP; + case COP444L_FEATURE: + m_opcode_map = COP444L_OPCODE_MAP; + + for (int r = 0; r < 8; r++) { + m_InstLen[0x60 + r] = 2; // JMP + m_InstLen[0x68 + r] = 2; // JSR + } + break; + + case COP424C_FEATURE: + m_opcode_map = COP424C_OPCODE_MAP; for (int r = 0; r < 8; r++) { m_InstLen[0x60 + r] = 2; // JMP @@ -252,36 +264,58 @@ cop422_cpu_device::cop422_cpu_device(const machine_config &mconfig, const char * { } -cop404_cpu_device::cop404_cpu_device(const machine_config &mconfig, const char *tag, device_t *owner, uint32_t clock) - : cop400_cpu_device(mconfig, COP404, "COP404", tag, owner, clock, "cop404", __FILE__, 11, 7, COP444_FEATURE, 0xf, 0xf, 0xf, true, true, nullptr, ADDRESS_MAP_NAME(data_128b)) +cop404l_cpu_device::cop404l_cpu_device(const machine_config &mconfig, const char *tag, device_t *owner, uint32_t clock) + : cop400_cpu_device(mconfig, COP404L, "COP404L", tag, owner, clock, "cop404l", __FILE__, 11, 7, COP444L_FEATURE, 0xf, 0xf, 0xf, true, true, nullptr, ADDRESS_MAP_NAME(data_128b)) +{ +} + +cop444l_cpu_device::cop444l_cpu_device(const machine_config &mconfig, const char *tag, device_t *owner, uint32_t clock) + : cop400_cpu_device(mconfig, COP444L, "COP444L", tag, owner, clock, "cop444l", __FILE__, 11, 7, COP444L_FEATURE, 0xf, 0xf, 0xf, true, true, ADDRESS_MAP_NAME(program_2kb), ADDRESS_MAP_NAME(data_128b)) +{ +} + +cop445l_cpu_device::cop445l_cpu_device(const machine_config &mconfig, const char *tag, device_t *owner, uint32_t clock) + : cop400_cpu_device(mconfig, COP445L, "COP445L", tag, owner, clock, "cop445l", __FILE__, 11, 7, COP444L_FEATURE, 0x7, 0x3, 0, true, false, ADDRESS_MAP_NAME(program_2kb), ADDRESS_MAP_NAME(data_128b)) +{ +} + +cop404c_cpu_device::cop404c_cpu_device(const machine_config &mconfig, const char *tag, device_t *owner, uint32_t clock) + : cop400_cpu_device(mconfig, COP404C, "COP404C", tag, owner, clock, "cop404c", __FILE__, 11, 7, COP424C_FEATURE, 0xf, 0xf, 0xf, true, true, nullptr, ADDRESS_MAP_NAME(data_128b)) +{ +} + +cop424c_cpu_device::cop424c_cpu_device(const machine_config &mconfig, const char *tag, device_t *owner, uint32_t clock) + : cop400_cpu_device(mconfig, COP424C, "COP424C", tag, owner, clock, "cop424c", __FILE__, 10, 6, COP424C_FEATURE, 0xf, 0xf, 0xf, true, true, ADDRESS_MAP_NAME(program_1kb), ADDRESS_MAP_NAME(data_64b)) { } -cop424_cpu_device::cop424_cpu_device(const machine_config &mconfig, const char *tag, device_t *owner, uint32_t clock) - : cop400_cpu_device(mconfig, COP424, "COP424", tag, owner, clock, "cop424", __FILE__, 10, 6, COP444_FEATURE, 0xf, 0xf, 0xf, true, true, ADDRESS_MAP_NAME(program_1kb), ADDRESS_MAP_NAME(data_64b)) +cop425c_cpu_device::cop425c_cpu_device(const machine_config &mconfig, const char *tag, device_t *owner, uint32_t clock) + : cop400_cpu_device(mconfig, COP425C, "COP425C", tag, owner, clock, "cop425c", __FILE__, 10, 6, COP424C_FEATURE, 0xf, 0xf, 0, true, false, ADDRESS_MAP_NAME(program_1kb), ADDRESS_MAP_NAME(data_64b)) { } -cop425_cpu_device::cop425_cpu_device(const machine_config &mconfig, const char *tag, device_t *owner, uint32_t clock) - : cop400_cpu_device(mconfig, COP425, "COP425", tag, owner, clock, "cop425", __FILE__, 10, 6, COP444_FEATURE, 0xf, 0xf, 0, true, false, ADDRESS_MAP_NAME(program_1kb), ADDRESS_MAP_NAME(data_64b)) +cop426c_cpu_device::cop426c_cpu_device(const machine_config &mconfig, const char *tag, device_t *owner, uint32_t clock) + : cop400_cpu_device(mconfig, COP426C, "COP426C", tag, owner, clock, "cop426c", __FILE__, 10, 6, COP424C_FEATURE, 0xe, 0xe, 0xf, true, true, ADDRESS_MAP_NAME(program_1kb), ADDRESS_MAP_NAME(data_64b)) { } -cop426_cpu_device::cop426_cpu_device(const machine_config &mconfig, const char *tag, device_t *owner, uint32_t clock) - : cop400_cpu_device(mconfig, COP426, "COP426", tag, owner, clock, "cop426", __FILE__, 10, 6, COP444_FEATURE, 0xe, 0xe, 0xf, true, true, ADDRESS_MAP_NAME(program_1kb), ADDRESS_MAP_NAME(data_64b)) +cop444c_cpu_device::cop444c_cpu_device(const machine_config &mconfig, const char *tag, device_t *owner, uint32_t clock) + : cop400_cpu_device(mconfig, COP444C, "COP444C", tag, owner, clock, "cop444c", __FILE__, 11, 7, COP424C_FEATURE, 0xf, 0xf, 0xf, true, true, ADDRESS_MAP_NAME(program_2kb), ADDRESS_MAP_NAME(data_128b)) { } -cop444_cpu_device::cop444_cpu_device(const machine_config &mconfig, const char *tag, device_t *owner, uint32_t clock) - : cop400_cpu_device(mconfig, COP444, "COP444", tag, owner, clock, "cop444", __FILE__, 11, 7, COP444_FEATURE, 0xf, 0xf, 0xf, true, true, ADDRESS_MAP_NAME(program_2kb), ADDRESS_MAP_NAME(data_128b)) +cop445c_cpu_device::cop445c_cpu_device(const machine_config &mconfig, const char *tag, device_t *owner, uint32_t clock) + : cop400_cpu_device(mconfig, COP445C, "COP445C", tag, owner, clock, "cop445c", __FILE__, 11, 7, COP424C_FEATURE, 0xf, 0xf, 0, true, false, ADDRESS_MAP_NAME(program_2kb), ADDRESS_MAP_NAME(data_128b)) { } -cop445_cpu_device::cop445_cpu_device(const machine_config &mconfig, const char *tag, device_t *owner, uint32_t clock) - : cop400_cpu_device(mconfig, COP445, "COP445", tag, owner, clock, "cop445", __FILE__, 11, 7, COP444_FEATURE, 0x7, 0x3, 0, true, false, ADDRESS_MAP_NAME(program_2kb), ADDRESS_MAP_NAME(data_128b)) +cop446c_cpu_device::cop446c_cpu_device(const machine_config &mconfig, const char *tag, device_t *owner, uint32_t clock) + : cop400_cpu_device(mconfig, COP446C, "COP446C", tag, owner, clock, "cop446c", __FILE__, 11, 7, COP424C_FEATURE, 0xe, 0xe, 0xf, true, true, ADDRESS_MAP_NAME(program_2kb), ADDRESS_MAP_NAME(data_128b)) { } + + /*************************************************************************** INLINE FUNCTIONS ***************************************************************************/ @@ -335,7 +369,7 @@ void cop400_cpu_device::WRITE_G(uint8_t data) INSTRUCTION(illegal) { - logerror("COP400: PC = %04x, Illegal opcode = %02x\n", PC-1, ROM(PC-1)); + logerror("COP400: PC = %03x, Illegal opcode = %02x\n", PC-1, ROM(PC-1)); } #include "cop400op.hxx" @@ -606,7 +640,7 @@ const cop400_cpu_device::cop400_opcode_func cop400_cpu_device::COP420_OPCODE_MAP OP(jp) , OP(jp) , OP(jp) , OP(jp) , OP(jp) , OP(jp) , OP(jp) , OP(jid) }; -const cop400_cpu_device::cop400_opcode_func cop400_cpu_device::COP444_OPCODE_23_MAP[256] = +const cop400_cpu_device::cop400_opcode_func cop400_cpu_device::COP444L_OPCODE_23_MAP[256] = { OP(ldd) , OP(ldd) , OP(ldd) , OP(ldd) , OP(ldd) , OP(ldd) , OP(ldd) , OP(ldd) , OP(ldd) , OP(ldd) , OP(ldd) , OP(ldd) , OP(ldd) , OP(ldd) , OP(ldd) , OP(ldd) , @@ -645,23 +679,23 @@ const cop400_cpu_device::cop400_opcode_func cop400_cpu_device::COP444_OPCODE_23_ OP(xad) , OP(xad) , OP(xad) , OP(xad) , OP(xad) , OP(xad) , OP(xad) , OP(xad) }; -void cop400_cpu_device::cop444_op23(uint8_t opcode) +void cop400_cpu_device::cop444l_op23(uint8_t opcode) { uint8_t opcode23 = fetch(); - (this->*COP444_OPCODE_23_MAP[opcode23])(opcode23); + (this->*COP444L_OPCODE_23_MAP[opcode23])(opcode23); } -const cop400_cpu_device::cop400_opcode_func cop400_cpu_device::COP444_OPCODE_33_MAP[256] = +const cop400_cpu_device::cop400_opcode_func cop400_cpu_device::COP444L_OPCODE_33_MAP[256] = { OP(illegal) , OP(skgbz0) , OP(illegal) , OP(skgbz2) , OP(illegal) , OP(illegal) , OP(illegal) , OP(illegal) , OP(illegal) , OP(illegal) , OP(illegal) , OP(illegal) , OP(illegal) , OP(illegal) , OP(illegal) , OP(illegal) , OP(illegal) , OP(skgbz1) , OP(illegal) , OP(skgbz3) , OP(illegal) , OP(illegal) , OP(illegal) , OP(illegal) , OP(illegal) , OP(illegal) , OP(illegal) , OP(illegal) , OP(illegal) , OP(illegal) , OP(illegal) , OP(illegal) , OP(illegal) , OP(skgz) , OP(illegal) , OP(illegal) , OP(illegal) , OP(illegal) , OP(illegal) , OP(illegal) , - OP(inin) , OP(inil) , OP(ing) , OP(illegal) , OP(cqma) , OP(illegal) , OP(inl) , OP(ctma) , + OP(inin) , OP(inil) , OP(ing) , OP(illegal) , OP(cqma) , OP(illegal) , OP(inl) , OP(illegal) , OP(illegal) , OP(illegal) , OP(illegal) , OP(illegal) , OP(illegal) , OP(illegal) , OP(illegal) , OP(illegal) , - OP(it) , OP(illegal) , OP(omg) , OP(illegal) , OP(camq) , OP(illegal) , OP(obd) , OP(camt) , + OP(illegal) , OP(illegal) , OP(omg) , OP(illegal) , OP(camq) , OP(illegal) , OP(obd) , OP(illegal) , OP(illegal) , OP(illegal) , OP(illegal) , OP(illegal) , OP(illegal) , OP(illegal) , OP(illegal) , OP(illegal) , OP(illegal) , OP(illegal) , OP(illegal) , OP(illegal) , OP(illegal) , OP(illegal) , OP(illegal) , OP(illegal) , @@ -691,22 +725,22 @@ const cop400_cpu_device::cop400_opcode_func cop400_cpu_device::COP444_OPCODE_33_ OP(lbi) , OP(lbi) , OP(lbi) , OP(lbi) , OP(lbi) , OP(lbi) , OP(lbi) , OP(lbi) }; -void cop400_cpu_device::cop444_op33(uint8_t opcode) +void cop400_cpu_device::cop444l_op33(uint8_t opcode) { uint8_t opcode33 = fetch(); - (this->*COP444_OPCODE_33_MAP[opcode33])(opcode33); + (this->*COP444L_OPCODE_33_MAP[opcode33])(opcode33); } -const cop400_cpu_device::cop400_opcode_func cop400_cpu_device::COP444_OPCODE_MAP[256] = +const cop400_cpu_device::cop400_opcode_func cop400_cpu_device::COP444L_OPCODE_MAP[256] = { OP(clra) , OP(skmbz0) , OP(xor_) , OP(skmbz2) , OP(xis) , OP(ld) , OP(x) , OP(xds) , OP(lbi) , OP(lbi) , OP(lbi) , OP(lbi) , OP(lbi) , OP(lbi) , OP(lbi) , OP(lbi) , - OP(casc) , OP(skmbz1) , OP(cop444_xabr), OP(skmbz3) , OP(xis) , OP(ld) , OP(x) , OP(xds) , + OP(casc) , OP(skmbz1) , OP(cop444l_xabr), OP(skmbz3) , OP(xis) , OP(ld) , OP(x) , OP(xds) , OP(lbi) , OP(lbi) , OP(lbi) , OP(lbi) , OP(lbi) , OP(lbi) , OP(lbi) , OP(lbi) , - OP(skc) , OP(ske) , OP(sc) , OP(cop444_op23) , OP(xis) , OP(ld) , OP(x) , OP(xds) , + OP(skc) , OP(ske) , OP(sc) , OP(cop444l_op23) , OP(xis) , OP(ld) , OP(x) , OP(xds) , OP(lbi) , OP(lbi) , OP(lbi) , OP(lbi) , OP(lbi) , OP(lbi) , OP(lbi) , OP(lbi) , - OP(asc) , OP(add) , OP(rc) , OP(cop444_op33) , OP(xis) , OP(ld) , OP(x) , OP(xds) , + OP(asc) , OP(add) , OP(rc) , OP(cop444l_op33) , OP(xis) , OP(ld) , OP(x) , OP(xds) , OP(lbi) , OP(lbi) , OP(lbi) , OP(lbi) , OP(lbi) , OP(lbi) , OP(lbi) , OP(lbi) , OP(comp) , OP(skt) , OP(rmb2) , OP(rmb3) , OP(nop) , OP(rmb1) , OP(smb2) , OP(smb1) , @@ -737,6 +771,136 @@ const cop400_cpu_device::cop400_opcode_func cop400_cpu_device::COP444_OPCODE_MAP OP(jp) , OP(jp) , OP(jp) , OP(jp) , OP(jp) , OP(jp) , OP(jp) , OP(jid) }; +const cop400_cpu_device::cop400_opcode_func cop400_cpu_device::COP424C_OPCODE_23_MAP[256] = +{ + OP(ldd) , OP(ldd) , OP(ldd) , OP(ldd) , OP(ldd) , OP(ldd) , OP(ldd) , OP(ldd) , + OP(ldd) , OP(ldd) , OP(ldd) , OP(ldd) , OP(ldd) , OP(ldd) , OP(ldd) , OP(ldd) , + OP(ldd) , OP(ldd) , OP(ldd) , OP(ldd) , OP(ldd) , OP(ldd) , OP(ldd) , OP(ldd) , + OP(ldd) , OP(ldd) , OP(ldd) , OP(ldd) , OP(ldd) , OP(ldd) , OP(ldd) , OP(ldd) , + OP(ldd) , OP(ldd) , OP(ldd) , OP(ldd) , OP(ldd) , OP(ldd) , OP(ldd) , OP(ldd) , + OP(ldd) , OP(ldd) , OP(ldd) , OP(ldd) , OP(ldd) , OP(ldd) , OP(ldd) , OP(ldd) , + OP(ldd) , OP(ldd) , OP(ldd) , OP(ldd) , OP(ldd) , OP(ldd) , OP(ldd) , OP(ldd) , + OP(ldd) , OP(ldd) , OP(ldd) , OP(ldd) , OP(ldd) , OP(ldd) , OP(ldd) , OP(ldd) , + + OP(ldd) , OP(ldd) , OP(ldd) , OP(ldd) , OP(ldd) , OP(ldd) , OP(ldd) , OP(ldd) , + OP(ldd) , OP(ldd) , OP(ldd) , OP(ldd) , OP(ldd) , OP(ldd) , OP(ldd) , OP(ldd) , + OP(ldd) , OP(ldd) , OP(ldd) , OP(ldd) , OP(ldd) , OP(ldd) , OP(ldd) , OP(ldd) , + OP(ldd) , OP(ldd) , OP(ldd) , OP(ldd) , OP(ldd) , OP(ldd) , OP(ldd) , OP(ldd) , + OP(ldd) , OP(ldd) , OP(ldd) , OP(ldd) , OP(ldd) , OP(ldd) , OP(ldd) , OP(ldd) , + OP(ldd) , OP(ldd) , OP(ldd) , OP(ldd) , OP(ldd) , OP(ldd) , OP(ldd) , OP(ldd) , + OP(ldd) , OP(ldd) , OP(ldd) , OP(ldd) , OP(ldd) , OP(ldd) , OP(ldd) , OP(ldd) , + OP(ldd) , OP(ldd) , OP(ldd) , OP(ldd) , OP(ldd) , OP(ldd) , OP(ldd) , OP(ldd) , + + OP(xad) , OP(xad) , OP(xad) , OP(xad) , OP(xad) , OP(xad) , OP(xad) , OP(xad) , + OP(xad) , OP(xad) , OP(xad) , OP(xad) , OP(xad) , OP(xad) , OP(xad) , OP(xad) , + OP(xad) , OP(xad) , OP(xad) , OP(xad) , OP(xad) , OP(xad) , OP(xad) , OP(xad) , + OP(xad) , OP(xad) , OP(xad) , OP(xad) , OP(xad) , OP(xad) , OP(xad) , OP(xad) , + OP(xad) , OP(xad) , OP(xad) , OP(xad) , OP(xad) , OP(xad) , OP(xad) , OP(xad) , + OP(xad) , OP(xad) , OP(xad) , OP(xad) , OP(xad) , OP(xad) , OP(xad) , OP(xad) , + OP(xad) , OP(xad) , OP(xad) , OP(xad) , OP(xad) , OP(xad) , OP(xad) , OP(xad) , + OP(xad) , OP(xad) , OP(xad) , OP(xad) , OP(xad) , OP(xad) , OP(xad) , OP(xad) , + + OP(xad) , OP(xad) , OP(xad) , OP(xad) , OP(xad) , OP(xad) , OP(xad) , OP(xad) , + OP(xad) , OP(xad) , OP(xad) , OP(xad) , OP(xad) , OP(xad) , OP(xad) , OP(xad) , + OP(xad) , OP(xad) , OP(xad) , OP(xad) , OP(xad) , OP(xad) , OP(xad) , OP(xad) , + OP(xad) , OP(xad) , OP(xad) , OP(xad) , OP(xad) , OP(xad) , OP(xad) , OP(xad) , + OP(xad) , OP(xad) , OP(xad) , OP(xad) , OP(xad) , OP(xad) , OP(xad) , OP(xad) , + OP(xad) , OP(xad) , OP(xad) , OP(xad) , OP(xad) , OP(xad) , OP(xad) , OP(xad) , + OP(xad) , OP(xad) , OP(xad) , OP(xad) , OP(xad) , OP(xad) , OP(xad) , OP(xad) , + OP(xad) , OP(xad) , OP(xad) , OP(xad) , OP(xad) , OP(xad) , OP(xad) , OP(xad) +}; + +void cop400_cpu_device::cop424c_op23(uint8_t opcode) +{ + uint8_t opcode23 = fetch(); + + (this->*COP424C_OPCODE_23_MAP[opcode23])(opcode23); +} + +const cop400_cpu_device::cop400_opcode_func cop400_cpu_device::COP424C_OPCODE_33_MAP[256] = +{ + OP(illegal) , OP(skgbz0) , OP(illegal) , OP(skgbz2) , OP(illegal) , OP(illegal) , OP(illegal) , OP(illegal) , + OP(illegal) , OP(illegal) , OP(illegal) , OP(illegal) , OP(illegal) , OP(illegal) , OP(illegal) , OP(illegal) , + OP(illegal) , OP(skgbz1) , OP(illegal) , OP(skgbz3) , OP(illegal) , OP(illegal) , OP(illegal) , OP(illegal) , + OP(illegal) , OP(illegal) , OP(illegal) , OP(illegal) , OP(illegal) , OP(illegal) , OP(illegal) , OP(illegal) , + OP(illegal) , OP(skgz) , OP(illegal) , OP(illegal) , OP(illegal) , OP(illegal) , OP(illegal) , OP(illegal) , + OP(inin) , OP(inil) , OP(ing) , OP(illegal) , OP(cqma) , OP(illegal) , OP(inl) , OP(ctma) , + OP(illegal) , OP(illegal) , OP(illegal) , OP(illegal) , OP(illegal) , OP(illegal) , OP(illegal) , OP(illegal) , + OP(it) , OP(illegal) , OP(omg) , OP(illegal) , OP(camq) , OP(illegal) , OP(obd) , OP(camt) , + + OP(illegal) , OP(illegal) , OP(illegal) , OP(illegal) , OP(illegal) , OP(illegal) , OP(illegal) , OP(illegal) , + OP(illegal) , OP(illegal) , OP(illegal) , OP(illegal) , OP(illegal) , OP(illegal) , OP(illegal) , OP(illegal) , + OP(ogi) , OP(ogi) , OP(ogi) , OP(ogi) , OP(ogi) , OP(ogi) , OP(ogi) , OP(ogi) , + OP(ogi) , OP(ogi) , OP(ogi) , OP(ogi) , OP(ogi) , OP(ogi) , OP(ogi) , OP(ogi) , + OP(lei) , OP(lei) , OP(lei) , OP(lei) , OP(lei) , OP(lei) , OP(lei) , OP(lei) , + OP(lei) , OP(lei) , OP(lei) , OP(lei) , OP(lei) , OP(lei) , OP(lei) , OP(lei) , + OP(illegal) , OP(illegal) , OP(illegal) , OP(illegal) , OP(illegal) , OP(illegal) , OP(illegal) , OP(illegal) , + OP(halt) , OP(illegal) , OP(illegal) , OP(illegal) , OP(illegal) , OP(illegal) , OP(illegal) , OP(illegal) , + + OP(lbi) , OP(lbi) , OP(lbi) , OP(lbi) , OP(lbi) , OP(lbi) , OP(lbi) , OP(lbi) , + OP(lbi) , OP(lbi) , OP(lbi) , OP(lbi) , OP(lbi) , OP(lbi) , OP(lbi) , OP(lbi) , + OP(lbi) , OP(lbi) , OP(lbi) , OP(lbi) , OP(lbi) , OP(lbi) , OP(lbi) , OP(lbi) , + OP(lbi) , OP(lbi) , OP(lbi) , OP(lbi) , OP(lbi) , OP(lbi) , OP(lbi) , OP(lbi) , + OP(lbi) , OP(lbi) , OP(lbi) , OP(lbi) , OP(lbi) , OP(lbi) , OP(lbi) , OP(lbi) , + OP(lbi) , OP(lbi) , OP(lbi) , OP(lbi) , OP(lbi) , OP(lbi) , OP(lbi) , OP(lbi) , + OP(lbi) , OP(lbi) , OP(lbi) , OP(lbi) , OP(lbi) , OP(lbi) , OP(lbi) , OP(lbi) , + OP(lbi) , OP(lbi) , OP(lbi) , OP(lbi) , OP(lbi) , OP(lbi) , OP(lbi) , OP(lbi) , + + OP(lbi) , OP(lbi) , OP(lbi) , OP(lbi) , OP(lbi) , OP(lbi) , OP(lbi) , OP(lbi) , + OP(lbi) , OP(lbi) , OP(lbi) , OP(lbi) , OP(lbi) , OP(lbi) , OP(lbi) , OP(lbi) , + OP(lbi) , OP(lbi) , OP(lbi) , OP(lbi) , OP(lbi) , OP(lbi) , OP(lbi) , OP(lbi) , + OP(lbi) , OP(lbi) , OP(lbi) , OP(lbi) , OP(lbi) , OP(lbi) , OP(lbi) , OP(lbi) , + OP(lbi) , OP(lbi) , OP(lbi) , OP(lbi) , OP(lbi) , OP(lbi) , OP(lbi) , OP(lbi) , + OP(lbi) , OP(lbi) , OP(lbi) , OP(lbi) , OP(lbi) , OP(lbi) , OP(lbi) , OP(lbi) , + OP(lbi) , OP(lbi) , OP(lbi) , OP(lbi) , OP(lbi) , OP(lbi) , OP(lbi) , OP(lbi) , + OP(lbi) , OP(lbi) , OP(lbi) , OP(lbi) , OP(lbi) , OP(lbi) , OP(lbi) , OP(lbi) +}; + +void cop400_cpu_device::cop424c_op33(uint8_t opcode) +{ + uint8_t opcode33 = fetch(); + + (this->*COP424C_OPCODE_33_MAP[opcode33])(opcode33); +} + +const cop400_cpu_device::cop400_opcode_func cop400_cpu_device::COP424C_OPCODE_MAP[256] = +{ + OP(clra) , OP(skmbz0) , OP(xor_) , OP(skmbz2) , OP(xis) , OP(ld) , OP(x) , OP(xds) , + OP(lbi) , OP(lbi) , OP(lbi) , OP(lbi) , OP(lbi) , OP(lbi) , OP(lbi) , OP(lbi) , + OP(casc) , OP(skmbz1) , OP(cop444l_xabr), OP(skmbz3) , OP(xis) , OP(ld) , OP(x) , OP(xds) , + OP(lbi) , OP(lbi) , OP(lbi) , OP(lbi) , OP(lbi) , OP(lbi) , OP(lbi) , OP(lbi) , + OP(skc) , OP(ske) , OP(sc) , OP(cop444l_op23) , OP(xis) , OP(ld) , OP(x) , OP(xds) , + OP(lbi) , OP(lbi) , OP(lbi) , OP(lbi) , OP(lbi) , OP(lbi) , OP(lbi) , OP(lbi) , + OP(asc) , OP(add) , OP(rc) , OP(cop444l_op33) , OP(xis) , OP(ld) , OP(x) , OP(xds) , + OP(lbi) , OP(lbi) , OP(lbi) , OP(lbi) , OP(lbi) , OP(lbi) , OP(lbi) , OP(lbi) , + + OP(comp) , OP(skt) , OP(rmb2) , OP(rmb3) , OP(nop) , OP(rmb1) , OP(smb2) , OP(smb1) , + OP(cop420_ret) , OP(retsk) , OP(adt) , OP(smb3) , OP(rmb0) , OP(smb0) , OP(cba) , OP(xas) , + OP(cab) , OP(aisc) , OP(aisc) , OP(aisc) , OP(aisc) , OP(aisc) , OP(aisc) , OP(aisc) , + OP(aisc) , OP(aisc) , OP(aisc) , OP(aisc) , OP(aisc) , OP(aisc) , OP(aisc) , OP(aisc) , + OP(jmp) , OP(jmp) , OP(jmp) , OP(jmp) , OP(jmp) , OP(jmp) , OP(jmp) , OP(jmp) , + OP(jsr) , OP(jsr) , OP(jsr) , OP(jsr) , OP(jsr) , OP(jsr) , OP(jsr) , OP(jsr) , + OP(stii) , OP(stii) , OP(stii) , OP(stii) , OP(stii) , OP(stii) , OP(stii) , OP(stii) , + OP(stii) , OP(stii) , OP(stii) , OP(stii) , OP(stii) , OP(stii) , OP(stii) , OP(stii) , + + OP(jp) , OP(jp) , OP(jp) , OP(jp) , OP(jp) , OP(jp) , OP(jp) , OP(jp) , + OP(jp) , OP(jp) , OP(jp) , OP(jp) , OP(jp) , OP(jp) , OP(jp) , OP(jp) , + OP(jp) , OP(jp) , OP(jp) , OP(jp) , OP(jp) , OP(jp) , OP(jp) , OP(jp) , + OP(jp) , OP(jp) , OP(jp) , OP(jp) , OP(jp) , OP(jp) , OP(jp) , OP(jp) , + OP(jp) , OP(jp) , OP(jp) , OP(jp) , OP(jp) , OP(jp) , OP(jp) , OP(jp) , + OP(jp) , OP(jp) , OP(jp) , OP(jp) , OP(jp) , OP(jp) , OP(jp) , OP(jp) , + OP(jp) , OP(jp) , OP(jp) , OP(jp) , OP(jp) , OP(jp) , OP(jp) , OP(jp) , + OP(jp) , OP(jp) , OP(jp) , OP(jp) , OP(jp) , OP(jp) , OP(jp) , OP(lqid) , + + OP(jp) , OP(jp) , OP(jp) , OP(jp) , OP(jp) , OP(jp) , OP(jp) , OP(jp) , + OP(jp) , OP(jp) , OP(jp) , OP(jp) , OP(jp) , OP(jp) , OP(jp) , OP(jp) , + OP(jp) , OP(jp) , OP(jp) , OP(jp) , OP(jp) , OP(jp) , OP(jp) , OP(jp) , + OP(jp) , OP(jp) , OP(jp) , OP(jp) , OP(jp) , OP(jp) , OP(jp) , OP(jp) , + OP(jp) , OP(jp) , OP(jp) , OP(jp) , OP(jp) , OP(jp) , OP(jp) , OP(jp) , + OP(jp) , OP(jp) , OP(jp) , OP(jp) , OP(jp) , OP(jp) , OP(jp) , OP(jp) , + OP(jp) , OP(jp) , OP(jp) , OP(jp) , OP(jp) , OP(jp) , OP(jp) , OP(jp) , + OP(jp) , OP(jp) , OP(jp) , OP(jp) , OP(jp) , OP(jp) , OP(jp) , OP(jid) +}; /*************************************************************************** TIMER CALLBACKS @@ -817,7 +981,12 @@ void cop400_cpu_device::serial_tick() void cop400_cpu_device::counter_tick() { - m_skt_latch = 1; + T++; + + if (!T) { + m_skt_latch = 1; + m_idle = false; + } } void cop400_cpu_device::inil_tick() @@ -846,17 +1015,17 @@ void cop400_cpu_device::device_timer(emu_timer &timer, device_timer_id id, int p { switch (id) { - case TIMER_SERIAL: - serial_tick(); - break; + case TIMER_SERIAL: + serial_tick(); + break; - case TIMER_COUNTER: - counter_tick(); - break; + case TIMER_COUNTER: + counter_tick(); + break; - case TIMER_INIL: - inil_tick(); - break; + case TIMER_INIL: + inil_tick(); + break; } } @@ -890,7 +1059,7 @@ void cop400_cpu_device::device_start() if (m_has_counter) { m_counter_timer = timer_alloc(TIMER_COUNTER); - m_counter_timer->adjust(attotime::zero, 0, attotime::from_ticks(m_cki * 1024, clock())); + m_counter_timer->adjust(attotime::zero, 0, attotime::from_ticks(m_cki * 4, clock())); } /* allocate IN latch timer */ @@ -925,32 +1094,27 @@ void cop400_cpu_device::device_start() save_item(NAME(m_halt)); save_item(NAME(m_idle)); - state_add(STATE_GENPC, "GENPC", m_pc).mask(0xfff).noshow(); - state_add(STATE_GENPCBASE, "CURPC", m_prevpc).mask(0xfff).noshow(); - state_add(STATE_GENFLAGS, "GENFLAGS", m_flags).mask(0x3).callimport().callexport().noshow().formatstr("%3s"); - - state_add(COP400_PC, "PC", m_pc).mask(0xfff); - - if (m_featuremask & (COP410_FEATURE | COP420_FEATURE | COP444_FEATURE)) - { - state_add(COP400_SA, "SA", m_sa).mask(0xfff); - state_add(COP400_SB, "SB", m_sb).mask(0xfff); - if (m_featuremask & (COP420_FEATURE | COP444_FEATURE)) - { - state_add(COP400_SC, "SC", m_sc).mask(0xfff); - } + // setup debugger state display + offs_t pc_mask = m_program->addrmask(); + + state_add(STATE_GENPC, "GENPC", m_pc).mask(pc_mask).noshow(); + state_add(STATE_GENPCBASE, "CURPC", m_prevpc).mask(pc_mask).noshow(); + state_add(STATE_GENFLAGS, "GENFLAGS", m_flags).mask(0x7).callimport().callexport().noshow().formatstr("%3s"); + state_add(COP400_PC, "PC", m_pc).mask(pc_mask); + state_add(COP400_SA, "SA", m_sa).mask(pc_mask); + state_add(COP400_SB, "SB", m_sb).mask(pc_mask); + if (!(m_featuremask & COP410_FEATURE)) { + state_add(COP400_SC, "SC", m_sc).mask(pc_mask); + } + state_add(COP400_B, "B", m_b); + state_add(COP400_A, "A", m_a).mask(0xf); + state_add(COP400_G, "G", m_g).mask(0xf); + state_add(COP400_Q, "Q", m_q); + state_add(COP400_SIO, "SIO", m_sio).mask(0xf); + state_add(COP400_EN, "EN", m_en).mask(0xf); + if (m_featuremask & COP424C_FEATURE) { + state_add(COP400_T, "T", m_t); } - - state_add(COP400_A, "A", m_a).mask(0xf); - state_add(COP400_B, "B", m_b); - state_add(COP400_C, "C", m_c).mask(0x1); - - state_add(COP400_EN, "EN", m_en).mask(0xf); - state_add(COP400_G, "G", m_g).mask(0xf); - state_add(COP400_Q, "Q", m_q); - - state_add(COP400_SIO, "SIO", m_sio).mask(0xf); - state_add(COP400_SKL, "SKL", m_skl).mask(0x1); m_icountptr = &m_icount; @@ -964,8 +1128,8 @@ void cop400_cpu_device::device_start() m_in[0] = m_in[1] = m_in[2] = m_in[3] = 0; m_si = 0; m_skip_lbi = 0; - m_last_skip = 0; - m_skip = 0; + m_last_skip = false; + m_skip = false; } @@ -987,8 +1151,8 @@ void cop400_cpu_device::device_reset() T = 0; m_skt_latch = 1; - m_halt = 0; - m_idle = 0; + m_halt = false; + m_idle = false; } /*************************************************************************** @@ -1017,7 +1181,7 @@ void cop400_cpu_device::execute_run() m_halt = IN_CKO(); } - if (m_halt) { + if (m_halt || m_idle) { m_icount--; continue; } @@ -1032,7 +1196,7 @@ void cop400_cpu_device::execute_run() if ((function != OP(jp)) && (function != OP(jmp)) && (function != OP(jsr)) && !m_skip_lbi) { // store skip logic m_last_skip = m_skip; - m_skip = 0; + m_skip = false; // push next PC PUSH(PC); @@ -1054,7 +1218,7 @@ void cop400_cpu_device::execute_run() opcode = fetch(); } - m_skip = 0; + m_skip = false; continue; } @@ -1078,10 +1242,11 @@ void cop400_cpu_device::state_import(const device_state_entry &entry) { switch (entry.index()) { - case STATE_GENFLAGS: - m_c = (m_flags >> 1) & 1; - m_skl = (m_flags >> 0) & 1; - break; + case STATE_GENFLAGS: + m_skt_latch = BIT(m_flags, 2); + m_c = BIT(m_flags, 1); + m_skl = BIT(m_flags, 0); + break; } } @@ -1089,9 +1254,9 @@ void cop400_cpu_device::state_export(const device_state_entry &entry) { switch (entry.index()) { - case STATE_GENFLAGS: - m_flags = (m_c ? 0x02 : 0x00) | (m_skl ? 0x01 : 0x00); - break; + case STATE_GENFLAGS: + m_flags = (m_skt_latch ? 0x04 : 0x00) | (m_c ? 0x02 : 0x00) | (m_skl ? 0x01 : 0x00); + break; } } @@ -1099,12 +1264,12 @@ void cop400_cpu_device::state_string_export(const device_state_entry &entry, std { switch (entry.index()) { - case STATE_GENFLAGS: - str = string_format("%c%c%c", - m_c ? 'C' : '.', - m_skl ? 'S' : '.', - m_skt_latch ? 'T' : '.'); - break; + case STATE_GENFLAGS: + str = string_format("%c%c%c", + m_c ? 'C' : '.', + m_skl ? 'S' : '.', + m_skt_latch ? 'T' : '.'); + break; } } @@ -1114,8 +1279,14 @@ offs_t cop400_cpu_device::disasm_disassemble(std::ostream &stream, offs_t pc, co 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); + } - if ( m_featuremask & COP444_FEATURE ) + if ( m_featuremask & COP444L_FEATURE ) { return CPU_DISASSEMBLE_NAME(cop444)(this, stream, pc, oprom, opram, options); } diff --git a/src/devices/cpu/cop400/cop400.h b/src/devices/cpu/cop400/cop400.h index 50a0042e537..2db42811447 100644 --- a/src/devices/cpu/cop400/cop400.h +++ b/src/devices/cpu/cop400/cop400.h @@ -71,7 +71,8 @@ enum COP400_Q, COP400_EN, COP400_SIO, - COP400_SKL + COP400_SKL, + COP400_T }; /* input lines */ @@ -83,7 +84,7 @@ enum COP400_IN2, COP400_IN3, - /* COP404 */ + /* COP404L */ COP400_MB, COP400_DUAL, COP400_SEL10, @@ -190,12 +191,14 @@ protected: enum { COP410_FEATURE = 0x01, COP420_FEATURE = 0x02, - COP444_FEATURE = 0x04 + COP444L_FEATURE = 0x04, + COP424C_FEATURE = 0x08 }; enum { TIMER_SERIAL, TIMER_COUNTER, + TIMER_COUNTER_T, TIMER_INIL }; @@ -239,11 +242,11 @@ protected: uint8_t m_si; /* serial input */ /* skipping logic */ - int m_skip; /* skip next instruction */ + bool m_skip; /* skip next instruction */ int m_skip_lbi; /* skip until next non-LBI instruction */ - int m_last_skip; /* last value of skip */ - int m_halt; /* halt mode */ - int m_idle; /* idle mode */ + bool m_last_skip; /* last value of skip */ + bool m_halt; /* halt mode */ + bool m_idle; /* idle mode */ /* execution logic */ int m_InstLen[256]; /* instruction length in bytes */ @@ -264,9 +267,12 @@ protected: static const cop400_opcode_func COP420_OPCODE_23_MAP[256]; static const cop400_opcode_func COP420_OPCODE_33_MAP[256]; static const cop400_opcode_func COP420_OPCODE_MAP[256]; - static const cop400_opcode_func COP444_OPCODE_23_MAP[256]; - static const cop400_opcode_func COP444_OPCODE_33_MAP[256]; - static const cop400_opcode_func COP444_OPCODE_MAP[256]; + static const cop400_opcode_func COP444L_OPCODE_23_MAP[256]; + static const cop400_opcode_func COP444L_OPCODE_33_MAP[256]; + static const cop400_opcode_func COP444L_OPCODE_MAP[256]; + static const cop400_opcode_func COP424C_OPCODE_23_MAP[256]; + static const cop400_opcode_func COP424C_OPCODE_33_MAP[256]; + static const cop400_opcode_func COP424C_OPCODE_MAP[256]; void serial_tick(); void counter_tick(); @@ -325,7 +331,7 @@ protected: void lbi(uint8_t opcode); void lei(uint8_t opcode); void xabr(uint8_t opcode); - void cop444_xabr(uint8_t opcode); + void cop444l_xabr(uint8_t opcode); void skc(uint8_t opcode); void ske(uint8_t opcode); void skgz(uint8_t opcode); @@ -351,11 +357,12 @@ protected: void cop410_op33(uint8_t opcode); void cop420_op23(uint8_t opcode); void cop420_op33(uint8_t opcode); - void cop444_op23(uint8_t opcode); - void cop444_op33(uint8_t opcode); + void cop444l_op23(uint8_t opcode); + void cop444l_op33(uint8_t opcode); + void cop424c_op23(uint8_t opcode); + void cop424c_op33(uint8_t opcode); void skgbz(int bit); void skmbz(int bit); - }; @@ -423,56 +430,92 @@ public: /* COP444 family */ -// COP404 is a ROMless version of the COP444, which can emulate a COP410C/COP411C, COP424C/COP425C, or a COP444C/COP445C -class cop404_cpu_device : public cop400_cpu_device +// COP404L is a ROMless version of the COP444, which can emulate a COP410/COP411, COP424/COP425, or a COP444/COP445 +class cop404l_cpu_device : public cop400_cpu_device { public: // construction/destruction - cop404_cpu_device(const machine_config &mconfig, const char *tag, device_t *owner, uint32_t clock); + cop404l_cpu_device(const machine_config &mconfig, const char *tag, device_t *owner, uint32_t clock); }; -// COP424 is functionally equivalent to COP444, with only 1K ROM and 64x4 bytes RAM -class cop424_cpu_device : public cop400_cpu_device +class cop444l_cpu_device : public cop400_cpu_device { public: // construction/destruction - cop424_cpu_device(const machine_config &mconfig, const char *tag, device_t *owner, uint32_t clock); + cop444l_cpu_device(const machine_config &mconfig, const char *tag, device_t *owner, uint32_t clock); }; -// COP425 is a 24-pin package version of the COP424, lacking the IN ports -class cop425_cpu_device : public cop400_cpu_device +// COP445 is a 24-pin package version of the COP444, lacking the IN ports +class cop445l_cpu_device : public cop400_cpu_device { public: // construction/destruction - cop425_cpu_device(const machine_config &mconfig, const char *tag, device_t *owner, uint32_t clock); + cop445l_cpu_device(const machine_config &mconfig, const char *tag, device_t *owner, uint32_t clock); }; -// COP426 is a 20-pin package version of the COP424, with only L0-L7, G2-G3, D2-D3 ports -class cop426_cpu_device : public cop400_cpu_device +// COP404C +class cop404c_cpu_device : public cop400_cpu_device { public: // construction/destruction - cop426_cpu_device(const machine_config &mconfig, const char *tag, device_t *owner, uint32_t clock); + cop404c_cpu_device(const machine_config &mconfig, const char *tag, device_t *owner, uint32_t clock); }; -class cop444_cpu_device : public cop400_cpu_device +// COP424C is functionally equivalent to COP444C, with only 1K ROM and 64x4 bytes RAM +class cop424c_cpu_device : public cop400_cpu_device { public: // construction/destruction - cop444_cpu_device(const machine_config &mconfig, const char *tag, device_t *owner, uint32_t clock); + cop424c_cpu_device(const machine_config &mconfig, const char *tag, device_t *owner, uint32_t clock); }; -// COP445 is a 24-pin package version of the COP444, lacking the IN ports -class cop445_cpu_device : public cop400_cpu_device +// COP425C is a 24-pin package version of the COP424C, lacking the IN ports +class cop425c_cpu_device : public cop400_cpu_device +{ +public: + // construction/destruction + cop425c_cpu_device(const machine_config &mconfig, const char *tag, device_t *owner, uint32_t clock); +}; + + +// COP426C is a 20-pin package version of the COP424C, with only L0-L7, G2-G3, D2-D3 ports +class cop426c_cpu_device : public cop400_cpu_device +{ +public: + // construction/destruction + cop426c_cpu_device(const machine_config &mconfig, const char *tag, device_t *owner, uint32_t clock); +}; + + +// COP444C +class cop444c_cpu_device : public cop400_cpu_device +{ +public: + // construction/destruction + cop444c_cpu_device(const machine_config &mconfig, const char *tag, device_t *owner, uint32_t clock); +}; + + +// COP445C +class cop445c_cpu_device : public cop400_cpu_device { public: // construction/destruction - cop445_cpu_device(const machine_config &mconfig, const char *tag, device_t *owner, uint32_t clock); + cop445c_cpu_device(const machine_config &mconfig, const char *tag, device_t *owner, uint32_t clock); +}; + + +// COP446C +class cop446c_cpu_device : public cop400_cpu_device +{ +public: + // construction/destruction + cop446c_cpu_device(const machine_config &mconfig, const char *tag, device_t *owner, uint32_t clock); }; @@ -483,12 +526,15 @@ extern const device_type COP402; extern const device_type COP420; extern const device_type COP421; extern const device_type COP422; -extern const device_type COP404; -extern const device_type COP424; -extern const device_type COP425; -extern const device_type COP426; -extern const device_type COP444; -extern const device_type COP445; - +extern const device_type COP404L; +extern const device_type COP444L; +extern const device_type COP445L; +extern const device_type COP404C; +extern const device_type COP424C; +extern const device_type COP425C; +extern const device_type COP426C; +extern const device_type COP444C; +extern const device_type COP445C; +extern const device_type COP446C; #endif /* __COP400__ */ diff --git a/src/devices/cpu/cop400/cop400op.hxx b/src/devices/cpu/cop400/cop400op.hxx index cf363be8ce6..17d72956828 100644 --- a/src/devices/cpu/cop400/cop400op.hxx +++ b/src/devices/cpu/cop400/cop400op.hxx @@ -35,7 +35,7 @@ INSTRUCTION( asc ) if (A > 0xF) { C = 1; - m_skip = 1; + m_skip = true; A &= 0xF; } else @@ -86,7 +86,7 @@ INSTRUCTION( aisc ) if (A > 0x0f) { - m_skip = 1; + m_skip = true; A &= 0xF; } } @@ -238,7 +238,7 @@ INSTRUCTION( casc ) if (A > 0xF) { C = 1; - m_skip = 1; + m_skip = true; A &= 0xF; } else @@ -413,7 +413,7 @@ INSTRUCTION( cop420_ret ) INSTRUCTION( retsk ) { POP(); - m_skip = 1; + m_skip = true; } /* @@ -431,7 +431,7 @@ INSTRUCTION( retsk ) INSTRUCTION( halt ) { - m_halt = 1; + m_halt = true; } /* @@ -447,8 +447,8 @@ INSTRUCTION( halt ) INSTRUCTION( it ) { - m_halt = 1; - m_idle = 1; + m_halt = true; + m_idle = true; } /*************************************************************************** @@ -732,7 +732,7 @@ INSTRUCTION( xds ) B = B ^ r; - if (Bd == 0x0f) m_skip = 1; + if (Bd == 0x0f) m_skip = true; } /* @@ -767,7 +767,7 @@ INSTRUCTION( xis ) B = B ^ r; - if (Bd == 0x00) m_skip = 1; + if (Bd == 0x00) m_skip = true; } /* @@ -979,7 +979,7 @@ INSTRUCTION( xabr ) /* - Processor: COP444 + Processor: COP444L Mnemonic: XABR @@ -992,7 +992,7 @@ INSTRUCTION( xabr ) */ -INSTRUCTION( cop444_xabr ) +INSTRUCTION( cop444l_xabr ) { uint8_t Br = A & 0x07; uint8_t Bd = B & 0x0f; @@ -1020,7 +1020,7 @@ INSTRUCTION( cop444_xabr ) INSTRUCTION( skc ) { - if (C == 1) m_skip = 1; + if (C == 1) m_skip = true; } /* @@ -1038,7 +1038,7 @@ INSTRUCTION( skc ) INSTRUCTION( ske ) { - if (A == RAM_R(B)) m_skip = 1; + if (A == RAM_R(B)) m_skip = true; } /* @@ -1056,7 +1056,7 @@ INSTRUCTION( ske ) INSTRUCTION( skgz ) { - if (IN_G() == 0) m_skip = 1; + if (IN_G() == 0) m_skip = true; } /* @@ -1081,7 +1081,7 @@ INSTRUCTION( skgz ) void cop400_cpu_device::skgbz(int bit) { - if (!BIT(IN_G(), bit)) m_skip = 1; + if (!BIT(IN_G(), bit)) m_skip = true; } INSTRUCTION( skgbz0 ) { skgbz(0); } @@ -1111,7 +1111,7 @@ INSTRUCTION( skgbz3 ) { skgbz(3); } void cop400_cpu_device::skmbz(int bit) { - if (!BIT(RAM_R(B), bit)) m_skip = 1; + if (!BIT(RAM_R(B), bit)) m_skip = true; } INSTRUCTION( skmbz0 ) { skmbz(0); } @@ -1137,7 +1137,7 @@ INSTRUCTION( skt ) if (m_skt_latch) { m_skt_latch = 0; - m_skip = 1; + m_skip = true; } } diff --git a/src/devices/cpu/cop400/cop410ds.cpp b/src/devices/cpu/cop400/cop410ds.cpp index a187506d8b5..4570417538f 100644 --- a/src/devices/cpu/cop400/cop410ds.cpp +++ b/src/devices/cpu/cop400/cop410ds.cpp @@ -25,19 +25,19 @@ CPU_DISASSEMBLE(cop410) if (page == 2 || page == 3) //JP pages 2,3 { address = (uint16_t)((pc & 0x180) | (opcode & 0x7F)); - util::stream_format(stream, "JP %03x", address); + util::stream_format(stream, "JP %03X", address); } else { if ((opcode & 0xC0) == 0xC0) //JP other pages { address = (uint16_t)((pc & 0x1C0) | (opcode & 0x3F)); - util::stream_format(stream, "JP %03x", address); + util::stream_format(stream, "JP %03X", address); } else //JSRP { address = (uint16_t)(0x80 | (opcode & 0x3F)); - util::stream_format(stream, "JSRP %03x", address); + util::stream_format(stream, "JSRP %03X", address); flags = DASMFLAG_STEP_OVER; } } @@ -65,13 +65,13 @@ CPU_DISASSEMBLE(cop410) else if (opcode >= 0x60 && opcode <= 0x61) { address = ((opcode & 0x01) << 8) | next_opcode; - util::stream_format(stream, "JMP %03x", address); + util::stream_format(stream, "JMP %03X", address); bytes = 2; } else if (opcode >= 0x68 && opcode <= 0x69) { address = ((opcode & 0x01) << 8) | next_opcode; - util::stream_format(stream, "JSR %03x", address); + util::stream_format(stream, "JSR %03X", address); flags = DASMFLAG_STEP_OVER; bytes = 2; } diff --git a/src/devices/cpu/cop400/cop420ds.cpp b/src/devices/cpu/cop400/cop420ds.cpp index 6281e7f53ef..39ea87ba9b4 100644 --- a/src/devices/cpu/cop400/cop420ds.cpp +++ b/src/devices/cpu/cop400/cop420ds.cpp @@ -25,19 +25,19 @@ CPU_DISASSEMBLE(cop420) if (page == 2 || page == 3) //JP pages 2,3 { address = (uint16_t)((pc & 0x380) | (opcode & 0x7F)); - util::stream_format(stream, "JP %03x", address); + util::stream_format(stream, "JP %03X", address); } else { if ((opcode & 0xC0) == 0xC0) //JP other pages { address = (uint16_t)((pc & 0x3C0) | (opcode & 0x3F)); - util::stream_format(stream, "JP %03x", address); + util::stream_format(stream, "JP %03X", address); } else //JSRP { address = (uint16_t)(0x80 | (opcode & 0x3F)); - util::stream_format(stream, "JSRP %03x", address); + util::stream_format(stream, "JSRP %03X", address); flags = DASMFLAG_STEP_OVER; } } @@ -65,13 +65,13 @@ CPU_DISASSEMBLE(cop420) else if (opcode >= 0x60 && opcode <= 0x63) { address = ((opcode & 0x03) << 8) | next_opcode; - util::stream_format(stream, "JMP %03x", address); + util::stream_format(stream, "JMP %03X", address); bytes = 2; } else if (opcode >= 0x68 && opcode <= 0x6B) { address = ((opcode & 0x03) << 8) | next_opcode; - util::stream_format(stream, "JSR %03x", address); + util::stream_format(stream, "JSR %03X", address); flags = DASMFLAG_STEP_OVER; bytes = 2; } diff --git a/src/devices/cpu/cop400/cop424ds.cpp b/src/devices/cpu/cop400/cop424ds.cpp new file mode 100644 index 00000000000..fc8396f4903 --- /dev/null +++ b/src/devices/cpu/cop400/cop424ds.cpp @@ -0,0 +1,401 @@ +// license:BSD-3-Clause +// copyright-holders:Curt Coder +/*************************************************************************** + + cop424ds.c + + National Semiconductor COP424C/COP444C Emulator. + +***************************************************************************/ + +#include "emu.h" + +CPU_DISASSEMBLE(cop424) +{ + uint8_t opcode = oprom[0]; + uint8_t next_opcode = oprom[1]; + uint16_t address; + uint32_t flags = 0; + int bytes = 1; + + if ((opcode >= 0x80 && opcode <= 0xBE) || (opcode >= 0xC0 && opcode <= 0xFE)) + { + int page = pc >> 6; + + if (page == 2 || page == 3) //JP pages 2,3 + { + address = (uint16_t)((pc & 0x780) | (opcode & 0x7F)); + util::stream_format(stream, "JP %03X", address); + } + else + { + if ((opcode & 0xC0) == 0xC0) //JP other pages + { + address = (uint16_t)((pc & 0x7C0) | (opcode & 0x3F)); + util::stream_format(stream, "JP %03X", address); + } + else //JSRP + { + address = (uint16_t)(0x80 | (opcode & 0x3F)); + util::stream_format(stream, "JSRP %03X", address); + flags = DASMFLAG_STEP_OVER; + } + } + } + else if (opcode >= 0x08 && opcode <= 0x0F) + { + util::stream_format(stream, "LBI 0,%u", ((opcode & 0xF) + 1) & 0xF); + } + else if (opcode >= 0x18 && opcode <= 0x1F) + { + util::stream_format(stream, "LBI 1,%u", ((opcode & 0xF) + 1) & 0xF); + } + else if (opcode >= 0x28 && opcode <= 0x2F) + { + util::stream_format(stream, "LBI 2,%u", ((opcode & 0xF) + 1) & 0xF); + } + else if (opcode >= 0x38 && opcode <= 0x3F) + { + util::stream_format(stream, "LBI 3,%u", ((opcode & 0xF) + 1) & 0xF); + } + else if (opcode >= 0x51 && opcode <= 0x5F) + { + util::stream_format(stream, "AISC %u", opcode & 0xF); + } + else if (opcode >= 0x60 && opcode <= 0x67) + { + address = ((opcode & 0x07) << 8) | next_opcode; + util::stream_format(stream, "JMP %03X", address); + bytes = 2; + } + else if (opcode >= 0x68 && opcode <= 0x6f) + { + address = ((opcode & 0x07) << 8) | next_opcode; + util::stream_format(stream, "JSR %03X", address); + flags = DASMFLAG_STEP_OVER; + bytes = 2; + } + else if (opcode >= 0x70 && opcode <= 0x7F) + { + util::stream_format(stream, "STII %u", opcode & 0xF); + } + else + { + switch (opcode) + { + case 0: + util::stream_format(stream, "CLRA"); + break; + + case 1: + util::stream_format(stream, "SKMBZ 0"); + break; + + case 2: + util::stream_format(stream, "XOR"); + break; + + case 3: + util::stream_format(stream, "SKMBZ 2"); + break; + + case 4: + util::stream_format(stream, "XIS 0"); + break; + + case 5: + util::stream_format(stream, "LD 0"); + break; + + case 6: + util::stream_format(stream, "X 0"); + break; + + case 7: + util::stream_format(stream, "XDS 0"); + break; + + case 0x10: + util::stream_format(stream, "CASC"); + break; + + case 0x11: + util::stream_format(stream, "SKMBZ 1"); + break; + + case 0x12: + util::stream_format(stream, "XABR"); + break; + + case 0x13: + util::stream_format(stream, "SKMBZ 3"); + break; + + case 0x14: + util::stream_format(stream, "XIS 1"); + break; + + case 0x15: + util::stream_format(stream, "LD 1"); + break; + + case 0x16: + util::stream_format(stream, "X 1"); + break; + + case 0x17: + util::stream_format(stream, "XDS 1"); + break; + + case 0x20: + util::stream_format(stream, "SKC"); + break; + + case 0x21: + util::stream_format(stream, "SKE"); + break; + + case 0x22: + util::stream_format(stream, "SC"); + break; + + case 0x23: + bytes = 2; + + if (next_opcode <= 0x7f) + { + address = (uint16_t)(next_opcode & 0x7F); + util::stream_format(stream, "LDD %u,%u", address >> 4, address & 0x0F); + } + else if (next_opcode >= 0x80) + { + address = (uint16_t)(next_opcode & 0x7f); + util::stream_format(stream, "XAD %u,%u", address >> 4, address & 0x0F); + } + break; + + case 0x24: + util::stream_format(stream, "XIS 2"); + break; + + case 0x25: + util::stream_format(stream, "LD 2"); + break; + + case 0x26: + util::stream_format(stream, "X 2"); + break; + + case 0x27: + util::stream_format(stream, "XDS 2"); + break; + + case 0x30: + util::stream_format(stream, "ASC"); + break; + + case 0x31: + util::stream_format(stream, "ADD"); + break; + + case 0x32: + util::stream_format(stream, "RC"); + break; + + case 0x33: + bytes = 2; + + if (next_opcode >= 0x50 && next_opcode <= 0x5F) + { + util::stream_format(stream, "OGI %u", next_opcode & 0xF); + } + else if (next_opcode >= 0x60 && next_opcode <= 0x6F) + { + util::stream_format(stream, "LEI %u", next_opcode & 0xF); + } + else if (next_opcode >= 0x80) + { + util::stream_format(stream, "LBI %u,%u", (next_opcode >> 4) & 0x07, next_opcode & 0xF); + } + else + { + switch (next_opcode) + { + case 0x01: + util::stream_format(stream, "SKGBZ 0"); + break; + + case 0x03: + util::stream_format(stream, "SKGBZ 2"); + break; + + case 0x11: + util::stream_format(stream, "SKGBZ 1"); + break; + + case 0x13: + util::stream_format(stream, "SKGBZ 3"); + break; + + case 0x21: + util::stream_format(stream, "SKGZ"); + break; + + case 0x28: + util::stream_format(stream, "ININ"); + break; + + case 0x29: + util::stream_format(stream, "INIL"); + break; + + case 0x2A: + util::stream_format(stream, "ING"); + break; + + case 0x2C: + util::stream_format(stream, "CQMA"); + break; + + case 0x2E: + util::stream_format(stream, "INL"); + break; + + case 0x2F: + util::stream_format(stream, "CTMA"); + break; + + case 0x38: + util::stream_format(stream, "HALT"); + break; + + case 0x39: + util::stream_format(stream, "IT"); + break; + + case 0x3A: + util::stream_format(stream, "OMG"); + break; + + case 0x3C: + util::stream_format(stream, "CAMQ"); + break; + + case 0x3E: + util::stream_format(stream, "OBD"); + break; + + case 0x3F: + util::stream_format(stream, "CAMT"); + break; + + + default: + util::stream_format(stream, "Invalid"); + break; + } + } + break; + + case 0x34: + util::stream_format(stream, "XIS 3"); + break; + + case 0x35: + util::stream_format(stream, "LD 3"); + break; + + case 0x36: + util::stream_format(stream, "X 3"); + break; + + case 0x37: + util::stream_format(stream, "XDS 3"); + break; + + case 0x40: + util::stream_format(stream, "COMP"); + break; + + case 0x41: + util::stream_format(stream, "SKT"); + break; + + case 0x42: + util::stream_format(stream, "RMB 2"); + break; + + case 0x43: + util::stream_format(stream, "RMB 3"); + break; + + case 0x44: + util::stream_format(stream, "NOP"); + break; + + case 0x45: + util::stream_format(stream, "RMB 1"); + break; + + case 0x46: + util::stream_format(stream, "SMB 2"); + break; + + case 0x47: + util::stream_format(stream, "SMB 1"); + break; + + case 0x48: + util::stream_format(stream, "RET"); + flags = DASMFLAG_STEP_OUT; + break; + + case 0x49: + util::stream_format(stream, "RETSK"); + flags = DASMFLAG_STEP_OUT; + break; + + case 0x4A: + util::stream_format(stream, "ADT"); + break; + + case 0x4B: + util::stream_format(stream, "SMB 3"); + break; + + case 0x4C: + util::stream_format(stream, "RMB 0"); + break; + + case 0x4D: + util::stream_format(stream, "SMB 0"); + break; + + case 0x4E: + util::stream_format(stream, "CBA"); + break; + + case 0x4F: + util::stream_format(stream, "XAS"); + break; + + case 0x50: + util::stream_format(stream, "CAB"); + break; + + case 0xBF: + util::stream_format(stream, "LQID"); + break; + + case 0xFF: + util::stream_format(stream, "JID"); + break; + + default: + util::stream_format(stream, "Invalid"); + break; + } + } + + return bytes | flags | DASMFLAG_SUPPORTED; +} diff --git a/src/devices/cpu/cop400/cop444ds.cpp b/src/devices/cpu/cop400/cop444ds.cpp index 2f92a21c252..cae2274546c 100644 --- a/src/devices/cpu/cop400/cop444ds.cpp +++ b/src/devices/cpu/cop400/cop444ds.cpp @@ -4,7 +4,7 @@ cop444ds.c - National Semiconductor COP444 Emulator. + National Semiconductor COP444L Emulator. ***************************************************************************/ @@ -25,19 +25,19 @@ CPU_DISASSEMBLE(cop444) if (page == 2 || page == 3) //JP pages 2,3 { address = (uint16_t)((pc & 0x780) | (opcode & 0x7F)); - util::stream_format(stream, "JP %03x", address); + util::stream_format(stream, "JP %03X", address); } else { if ((opcode & 0xC0) == 0xC0) //JP other pages { address = (uint16_t)((pc & 0x7C0) | (opcode & 0x3F)); - util::stream_format(stream, "JP %03x", address); + util::stream_format(stream, "JP %03X", address); } else //JSRP { address = (uint16_t)(0x80 | (opcode & 0x3F)); - util::stream_format(stream, "JSRP %03x", address); + util::stream_format(stream, "JSRP %03X", address); flags = DASMFLAG_STEP_OVER; } } @@ -65,13 +65,13 @@ CPU_DISASSEMBLE(cop444) else if (opcode >= 0x60 && opcode <= 0x67) { address = ((opcode & 0x07) << 8) | next_opcode; - util::stream_format(stream, "JMP %03x", address); + util::stream_format(stream, "JMP %03X", address); bytes = 2; } else if (opcode >= 0x68 && opcode <= 0x6f) { address = ((opcode & 0x07) << 8) | next_opcode; - util::stream_format(stream, "JSR %03x", address); + util::stream_format(stream, "JSR %03X", address); flags = DASMFLAG_STEP_OVER; bytes = 2; } @@ -261,18 +261,6 @@ CPU_DISASSEMBLE(cop444) util::stream_format(stream, "INL"); break; - case 0x2F: - util::stream_format(stream, "CTMA"); - break; - - case 0x38: - util::stream_format(stream, "HALT"); - break; - - case 0x39: - util::stream_format(stream, "IT"); - break; - case 0x3A: util::stream_format(stream, "OMG"); break; @@ -285,11 +273,6 @@ CPU_DISASSEMBLE(cop444) util::stream_format(stream, "OBD"); break; - case 0x3F: - util::stream_format(stream, "CAMT"); - break; - - default: util::stream_format(stream, "Invalid"); break; diff --git a/src/devices/cpu/m6805/6805ops.hxx b/src/devices/cpu/m6805/6805ops.hxx index 88e3ae5da8c..e8c0a5b0fc0 100644 --- a/src/devices/cpu/m6805/6805ops.hxx +++ b/src/devices/cpu/m6805/6805ops.hxx @@ -1,5 +1,5 @@ // license:BSD-3-Clause -// copyright-holders:Aaron Giles +// copyright-holders:Aaron Giles, Vas Crabb /* HNZC @@ -14,10 +14,13 @@ HNZC */ -#define OP_HANDLER(_name) void m6805_base_device::_name() -#define DERIVED_OP_HANDLER(_arch,_name) void _arch##_device::_name() +#define OP_HANDLER(name) void m6805_base_device::name() +#define OP_HANDLER_BIT(name) template <unsigned B> void m6805_base_device::name() +#define OP_HANDLER_BRA(name) template <bool C> void m6805_base_device::name() +#define OP_HANDLER_MODE(name) template <m6805_base_device::addr_mode M> void m6805_base_device::name() + +#define DERIVED_OP_HANDLER(arch, name) void arch##_device::name() -#define OP_HANDLER_BIT(_name) void m6805_base_device::_name(uint8_t bit) OP_HANDLER( illegal ) { @@ -27,291 +30,262 @@ OP_HANDLER( illegal ) /* $00/$02/$04/$06/$08/$0A/$0C/$0E BRSET direct,relative ---- */ OP_HANDLER_BIT( brset ) { - uint8_t t,r; + u8 t, r; DIRBYTE(r); IMMBYTE(t); CLC; - - if (r&bit) { - SEC; - PC+=SIGNED(t); - } + if (BIT(r, B)) { SEC; PC += SIGNED(t); } } /* $01/$03/$05/$07/$09/$0B/$0D/$0F BRCLR direct,relative ---- */ OP_HANDLER_BIT( brclr ) { - uint8_t t,r; + u8 t, r; DIRBYTE(r); IMMBYTE(t); SEC; - - if (!(r&bit)) { - CLC; - PC+=SIGNED(t); - } + if (!BIT(r, B)) { CLC; PC += SIGNED(t); } } /* $10/$12/$14/$16/$18/$1A/$1C/$1E BSET direct ---- */ OP_HANDLER_BIT( bset ) { - uint8_t t,r; - DIRBYTE(t); r=t|bit; - WM(EAD,r); + u8 t; + DIRBYTE(t); + WM(EAD, t | (u8(1) << B)); } /* $11/$13/$15/$17/$19/$1B/$1D/$1F BCLR direct ---- */ -OP_HANDLER_BIT( bclr) +OP_HANDLER_BIT( bclr ) { - uint8_t t,r; - DIRBYTE(t); r=t&(~bit); - WM(EAD,r); + u8 t; + DIRBYTE(t); + WM(EAD, t & ~(u8(1) << B)); } /* $20 BRA relative ---- */ -OP_HANDLER( bra ) -{ - uint8_t t; - IMMBYTE(t); - PC+=SIGNED(t); -} - /* $21 BRN relative ---- */ -OP_HANDLER( brn ) -{ - SKIPBYTE(); -} +OP_HANDLER_BRA( bra ) { BRANCH( true ); } /* $22 BHI relative ---- */ -OP_HANDLER( bhi ) -{ - BRANCH( !(CC&(CFLAG|ZFLAG)) ); -} - /* $23 BLS relative ---- */ -OP_HANDLER( bls ) -{ - BRANCH( CC&(CFLAG|ZFLAG) ); -} +OP_HANDLER_BRA( bhi ) { BRANCH( !(CC & (CFLAG | ZFLAG)) ); } /* $24 BCC relative ---- */ -OP_HANDLER( bcc ) -{ - BRANCH( !(CC&CFLAG) ); -} - /* $25 BCS relative ---- */ -OP_HANDLER( bcs ) -{ - BRANCH( CC&CFLAG ); -} +OP_HANDLER_BRA( bcc ) { BRANCH( !(CC & CFLAG) ); } /* $26 BNE relative ---- */ -OP_HANDLER( bne ) -{ - BRANCH( !(CC&ZFLAG) ); -} - /* $27 BEQ relative ---- */ -OP_HANDLER( beq ) -{ - BRANCH( CC&ZFLAG ); -} +OP_HANDLER_BRA( bne ) { BRANCH( !(CC & ZFLAG) ); } /* $28 BHCC relative ---- */ -OP_HANDLER( bhcc ) -{ - BRANCH( !(CC&HFLAG) ); -} - /* $29 BHCS relative ---- */ -OP_HANDLER( bhcs ) -{ - BRANCH( CC&HFLAG ); -} +OP_HANDLER_BRA( bhcc ) { BRANCH( !(CC & HFLAG) ); } /* $2a BPL relative ---- */ -OP_HANDLER( bpl ) -{ - BRANCH( !(CC&NFLAG) ); -} - /* $2b BMI relative ---- */ -OP_HANDLER( bmi ) -{ - BRANCH( CC&NFLAG ); -} +OP_HANDLER_BRA( bpl ) { BRANCH( !(CC & NFLAG) ); } /* $2c BMC relative ---- */ -OP_HANDLER( bmc ) -{ - BRANCH( !(CC&IFLAG) ); -} - /* $2d BMS relative ---- */ -OP_HANDLER( bms ) -{ - BRANCH( CC&IFLAG ); -} +OP_HANDLER_BRA( bmc ) { BRANCH( !(CC & IFLAG) ); } /* $2e BIL relative ---- */ OP_HANDLER( bil ) { - BRANCH(m_irq_state[M6805_IRQ_LINE] != CLEAR_LINE); + bool const C = true; + BRANCH( m_irq_state[M6805_IRQ_LINE] != CLEAR_LINE ); } -DERIVED_OP_HANDLER( hd63705, bil ) +/* $2f BIH relative ---- */ +OP_HANDLER( bih ) { - BRANCH(m_nmi_state != CLEAR_LINE); + bool const C = false; + BRANCH( m_irq_state[M6805_IRQ_LINE] != CLEAR_LINE ); } -/* $2f BIH relative ---- */ -OP_HANDLER( bih ) +DERIVED_OP_HANDLER( hd63705, bil ) { - BRANCH(m_irq_state[M6805_IRQ_LINE] == CLEAR_LINE); + bool const C = true; + BRANCH( m_nmi_state != CLEAR_LINE ); } DERIVED_OP_HANDLER( hd63705, bih ) { - BRANCH(m_nmi_state == CLEAR_LINE); + bool const C = false; + BRANCH( m_nmi_state != CLEAR_LINE ); } /* $30 NEG direct -*** */ -OP_HANDLER( neg_di ) +/* $60 NEG indexed, 1 byte offset -*** */ +/* $70 NEG indexed -*** */ +OP_HANDLER_MODE( neg ) { - uint8_t t; - uint16_t r; - DIRBYTE(t); - r=-t; + u8 t; + ARGBYTE(t); + u16 const r = -t; CLR_NZC; - SET_FLAGS8(0,t,r); - WM(EAD,r); + SET_FLAGS8(0, t, r); + WM(EAD, r); } /* $31 ILLEGAL */ +/* $61 ILLEGAL */ +/* $71 ILLEGAL */ /* $32 ILLEGAL */ +/* $62 ILLEGAL */ +/* $72 ILLEGAL */ /* $33 COM direct -**1 */ -OP_HANDLER( com_di ) +/* $63 COM indexed, 1 byte offset -**1 */ +/* $73 COM indexed -**1 */ +OP_HANDLER_MODE( com ) { - uint8_t t; - DIRBYTE(t); + u8 t; + ARGBYTE(t); t = ~t; CLR_NZ; SET_NZ8(t); SEC; - WM(EAD,t); + WM(EAD, t); } /* $34 LSR direct -0** */ -OP_HANDLER( lsr_di ) +/* $64 LSR indexed, 1 byte offset -0** */ +/* $74 LSR indexed -0** */ +OP_HANDLER_MODE( lsr ) { - uint8_t t; - DIRBYTE(t); + u8 t; + ARGBYTE(t); CLR_NZC; - CC |= (t&0x01); + CC |= BIT(t, 0); t >>= 1; SET_Z8(t); - WM(EAD,t); + WM(EAD, t); } /* $35 ILLEGAL */ +/* $65 ILLEGAL */ +/* $75 ILLEGAL */ /* $36 ROR direct -*** */ -OP_HANDLER( ror_di ) +/* $66 ROR indexed, 1 byte offset -*** */ +/* $76 ROR indexed -*** */ +OP_HANDLER_MODE( ror ) { - uint8_t t,r; - DIRBYTE(t); - r = (CC & 0x01) << 7; + u8 t; + ARGBYTE(t); + u8 r = BIT(CC, 0) << 7; CLR_NZC; - CC |= (t & 0x01); - r |= t>>1; + CC |= BIT(t, 0); + r |= t >> 1; SET_NZ8(r); - WM(EAD,r); + WM(EAD, r); } /* $37 ASR direct ?*** */ -OP_HANDLER( asr_di ) +/* $67 ASR indexed, 1 byte offset ?*** */ +/* $77 ASR indexed ?*** */ +OP_HANDLER_MODE( asr ) { - uint8_t t; - DIRBYTE(t); - CLR_NZC; CC|=(t&0x01); - t>>=1; t|=((t&0x40)<<1); + u8 t; + ARGBYTE(t); + CLR_NZC; + CC |= BIT(t, 0); + t = (t >> 1) | (t & 0x80); SET_NZ8(t); - WM(EAD,t); + WM(EAD, t); } /* $38 LSL direct ?*** */ -OP_HANDLER( lsl_di ) +/* $68 LSL indexed, 1 byte offset ?*** */ +/* $78 LSL indexed ?*** */ +OP_HANDLER_MODE( lsl ) { - uint8_t t; - uint16_t r; - DIRBYTE(t); - r = t << 1; + u8 t; + ARGBYTE(t); + u16 const r = t << 1; CLR_NZC; - SET_FLAGS8(t,t,r); - WM(EAD,r); + SET_FLAGS8(t, t, r); + WM(EAD, r); } /* $39 ROL direct -*** */ -OP_HANDLER( rol_di ) +/* $69 ROL indexed, 1 byte offset -*** */ +/* $79 ROL indexed -*** */ +OP_HANDLER_MODE( rol ) { - uint16_t t,r; - DIRBYTE(t); - r = CC & 0x01; - r |= t << 1; + u16 t; + ARGBYTE(t); + u16 const r = BIT(CC, 0) | (t << 1); CLR_NZC; - SET_FLAGS8(t,t,r); - WM(EAD,r); + SET_FLAGS8(t, t, r); + WM(EAD, r); } /* $3a DEC direct -**- */ -OP_HANDLER( dec_di ) +/* $6a DEC indexed, 1 byte offset -**- */ +OP_HANDLER_MODE( dec ) { - uint8_t t; - DIRBYTE(t); + u8 t; + ARGBYTE(t); --t; - CLR_NZ; SET_FLAGS8D(t); - WM(EAD,t); + CLR_NZ; + SET_FLAGS8D(t); + WM(EAD, t); } /* $3b ILLEGAL */ +/* $6b ILLEGAL */ +/* $7b ILLEGAL */ /* $3c INC direct -**- */ -OP_HANDLER( inc_di ) +/* $6c INC indexed, 1 byte offset -**- */ +/* $7c INC indexed -**- */ +OP_HANDLER_MODE( inc ) { - uint8_t t; - DIRBYTE(t); + u8 t; + ARGBYTE(t); ++t; - CLR_NZ; SET_FLAGS8I(t); - WM(EAD,t); + CLR_NZ; + SET_FLAGS8I(t); + WM(EAD, t); } /* $3d TST direct -**- */ -OP_HANDLER( tst_di ) +/* $6d TST indexed, 1 byte offset -**- */ +/* $7d TST indexed -**- */ +OP_HANDLER_MODE( tst ) { - uint8_t t; - DIRBYTE(t); - CLR_NZ; SET_NZ8(t); + u8 t; + ARGBYTE(t); + CLR_NZ; + SET_NZ8(t); } /* $3e ILLEGAL */ +/* $6e ILLEGAL */ +/* $7e ILLEGAL */ /* $3f CLR direct -0100 */ -OP_HANDLER( clr_di ) +/* $6f CLR indexed, 1 byte offset -0100 */ +/* $7f CLR indexed -0100 */ +OP_HANDLER_MODE( clr ) { - DIRECT; - CLR_NZ; SEZ; - WM(EAD,0); + ARGADDR; + CLR_NZ; + SEZ; + WM(EAD, 0); } /* $40 NEGA inherent ?*** */ OP_HANDLER( nega ) { - uint16_t r; + u16 r; r = -A; CLR_NZC; SET_FLAGS8(0,A,r); A = r; @@ -344,7 +318,7 @@ OP_HANDLER( lsra ) /* $46 RORA inherent -*** */ OP_HANDLER( rora ) { - uint8_t r; + u8 r; r = (CC & 0x01) << 7; CLR_NZC; CC |= (A & 0x01); @@ -365,7 +339,7 @@ OP_HANDLER( asra ) /* $48 LSLA inherent ?*** */ OP_HANDLER( lsla ) { - uint16_t r; + u16 r; r = A << 1; CLR_NZC; SET_FLAGS8(A,A,r); @@ -375,7 +349,7 @@ OP_HANDLER( lsla ) /* $49 ROLA inherent -*** */ OP_HANDLER( rola ) { - uint16_t t,r; + u16 t,r; t = A; r = CC & 0x01; r |= t << 1; @@ -422,7 +396,7 @@ OP_HANDLER( clra ) /* $50 NEGX inherent ?*** */ OP_HANDLER( negx ) { - uint16_t r; + u16 r; r = -X; CLR_NZC; SET_FLAGS8(0,X,r); @@ -456,7 +430,7 @@ OP_HANDLER( lsrx ) /* $56 RORX inherent -*** */ OP_HANDLER( rorx ) { - uint8_t r; + u8 r; r = (CC & 0x01) << 7; CLR_NZC; CC |= (X & 0x01); @@ -474,10 +448,10 @@ OP_HANDLER( asrx ) SET_NZ8(X); } -/* $58 ASLX inherent ?*** */ -OP_HANDLER( aslx ) +/* $58 LSLX inherent ?*** */ +OP_HANDLER( lslx ) { - uint16_t r; + u16 r; r = X << 1; CLR_NZC; SET_FLAGS8(X,X,r); @@ -487,7 +461,7 @@ OP_HANDLER( aslx ) /* $59 ROLX inherent -*** */ OP_HANDLER( rolx ) { - uint16_t t,r; + u16 t,r; t = X; r = CC & 0x01; r |= t<<1; @@ -531,255 +505,6 @@ OP_HANDLER( clrx ) SEZ; } -/* $60 NEG indexed, 1 byte offset -*** */ -OP_HANDLER( neg_ix1 ) -{ - uint8_t t; - uint16_t r; - IDX1BYTE(t); r=-t; - CLR_NZC; SET_FLAGS8(0,t,r); - WM(EAD,r); -} - -/* $61 ILLEGAL */ - -/* $62 ILLEGAL */ - -/* $63 COM indexed, 1 byte offset -**1 */ -OP_HANDLER( com_ix1 ) -{ - uint8_t t; - IDX1BYTE(t); t = ~t; - CLR_NZ; SET_NZ8(t); SEC; - WM(EAD,t); -} - -/* $64 LSR indexed, 1 byte offset -0** */ -OP_HANDLER( lsr_ix1 ) -{ - uint8_t t; - IDX1BYTE(t); - CLR_NZC; - CC |= (t & 0x01); - t >>= 1; - SET_Z8(t); - WM(EAD,t); -} - -/* $65 ILLEGAL */ - -/* $66 ROR indexed, 1 byte offset -*** */ -OP_HANDLER( ror_ix1 ) -{ - uint8_t t,r; - IDX1BYTE(t); - r = (CC & 0x01) << 7; - CLR_NZC; - CC |= (t & 0x01); - r |= t>>1; - SET_NZ8(r); - WM(EAD,r); -} - -/* $67 ASR indexed, 1 byte offset ?*** */ -OP_HANDLER( asr_ix1 ) -{ - uint8_t t; - IDX1BYTE(t); - CLR_NZC; CC|=(t&0x01); - t>>=1; t|=((t&0x40)<<1); - SET_NZ8(t); - WM(EAD,t); -} - -/* $68 LSL indexed, 1 byte offset ?*** */ -OP_HANDLER( lsl_ix1 ) -{ - uint8_t t; - uint16_t r; - IDX1BYTE(t); - r = t << 1; - CLR_NZC; - SET_FLAGS8(t,t,r); - WM(EAD,r); -} - -/* $69 ROL indexed, 1 byte offset -*** */ -OP_HANDLER( rol_ix1 ) -{ - uint16_t t,r; - IDX1BYTE(t); - r = CC & 0x01; - r |= t << 1; - CLR_NZC; - SET_FLAGS8(t,t,r); - WM(EAD,r); -} - -/* $6a DEC indexed, 1 byte offset -**- */ -OP_HANDLER( dec_ix1 ) -{ - uint8_t t; - IDX1BYTE(t); - --t; - CLR_NZ; SET_FLAGS8D(t); - WM(EAD,t); -} - -/* $6b ILLEGAL */ - -/* $6c INC indexed, 1 byte offset -**- */ -OP_HANDLER( inc_ix1 ) -{ - uint8_t t; - IDX1BYTE(t); - ++t; - CLR_NZ; SET_FLAGS8I(t); - WM(EAD,t); -} - -/* $6d TST indexed, 1 byte offset -**- */ -OP_HANDLER( tst_ix1 ) -{ - uint8_t t; - IDX1BYTE(t); - CLR_NZ; SET_NZ8(t); -} - -/* $6e ILLEGAL */ - -/* $6f CLR indexed, 1 byte offset -0100 */ -OP_HANDLER( clr_ix1 ) -{ - INDEXED1; - CLR_NZC; SEZ; - WM(EAD,0); -} - -/* $70 NEG indexed -*** */ -OP_HANDLER( neg_ix ) -{ - uint8_t t; - uint16_t r; - IDXBYTE(t); r=-t; - CLR_NZC; SET_FLAGS8(0,t,r); - WM(EAD,r); -} - -/* $71 ILLEGAL */ - -/* $72 ILLEGAL */ - -/* $73 COM indexed -**1 */ -OP_HANDLER( com_ix ) -{ - uint8_t t; - IDXBYTE(t); t = ~t; - CLR_NZ; SET_NZ8(t); SEC; - WM(EAD,t); -} - -/* $74 LSR indexed -0** */ -OP_HANDLER( lsr_ix ) -{ - uint8_t t; - IDXBYTE(t); - CLR_NZC; - CC |= (t & 0x01); - t >>= 1; - SET_Z8(t); - WM(EAD,t); -} - -/* $75 ILLEGAL */ - -/* $76 ROR indexed -*** */ -OP_HANDLER( ror_ix ) -{ - uint8_t t,r; - IDXBYTE(t); - r = (CC & 0x01) << 7; - CLR_NZC; - CC |= (t & 0x01); - r |= t >> 1; - SET_NZ8(r); - WM(EAD,r); -} - -/* $77 ASR indexed ?*** */ -OP_HANDLER( asr_ix ) -{ - uint8_t t; - IDXBYTE(t); - CLR_NZC; - CC |= (t & 0x01); - t = (t & 0x80) | (t >> 1); - SET_NZ8(t); - WM(EAD,t); -} - -/* $78 LSL indexed ?*** */ -OP_HANDLER( lsl_ix ) -{ - uint8_t t; - uint16_t r; - IDXBYTE(t); r=t<<1; - CLR_NZC; SET_FLAGS8(t,t,r); - WM(EAD,r); -} - -/* $79 ROL indexed -*** */ -OP_HANDLER( rol_ix ) -{ - uint16_t t,r; - IDXBYTE(t); - r = CC & 0x01; - r |= t << 1; - CLR_NZC; - SET_FLAGS8(t,t,r); - WM(EAD,r); -} - -/* $7a DEC indexed -**- */ -OP_HANDLER( dec_ix ) -{ - uint8_t t; - IDXBYTE(t); - --t; - CLR_NZ; SET_FLAGS8D(t); - WM(EAD,t); -} - -/* $7b ILLEGAL */ - -/* $7c INC indexed -**- */ -OP_HANDLER( inc_ix ) -{ - uint8_t t; - IDXBYTE(t); - ++t; - CLR_NZ; SET_FLAGS8I(t); - WM(EAD,t); -} - -/* $7d TST indexed -**- */ -OP_HANDLER( tst_ix ) -{ - uint8_t t; - IDXBYTE(t); - CLR_NZ; SET_NZ8(t); -} - -/* $7e ILLEGAL */ - -/* $7f CLR indexed -0100 */ -OP_HANDLER( clr_ix ) -{ - INDEXED; - CLR_NZC; SEZ; - WM(EAD,0); -} - /* $80 RTI inherent #### */ OP_HANDLER( rti ) { @@ -823,6 +548,7 @@ DERIVED_OP_HANDLER( hd63705, swi ) SEI; RM16(0x1ffa, &m_pc); } + /* $84 ILLEGAL */ /* $85 ILLEGAL */ @@ -862,29 +588,32 @@ DERIVED_OP_HANDLER( hd63705, swi ) /* $96 ILLEGAL */ /* $97 TAX inherent ---- */ -OP_HANDLER( tax ) -{ - X = A; -} +OP_HANDLER( tax ) { X = A; } /* $98 CLC */ +OP_HANDLER( clc ) { CLC; } /* $99 SEC */ +OP_HANDLER( sec ) { SEC; } /* $9A CLI */ +OP_HANDLER( cli ) +{ +#if IRQ_LEVEL_DETECT + if (m_irq_state != CLEAR_LINE) m_pending_interrupts |= 1 << M6805_IRQ_LINE; +#else + CLI; +#endif +} /* $9B SEI */ +OP_HANDLER( sei ) { SEI; } /* $9C RSP inherent ---- */ -OP_HANDLER( rsp ) -{ - S = SP_MASK; -} +OP_HANDLER( rsp ) { S = SP_MASK; } /* $9D NOP inherent ---- */ -OP_HANDLER( nop ) -{ -} +OP_HANDLER( nop ) { } /* $9E ILLEGAL */ @@ -895,913 +624,244 @@ OP_HANDLER( txa ) } /* $a0 SUBA immediate ?*** */ -OP_HANDLER( suba_im ) -{ - uint16_t t,r; - IMMBYTE(t); - r = A - t; - CLR_NZC; - SET_FLAGS8(A,t,r); - A = r; -} - -/* $a1 CMPA immediate ?*** */ -OP_HANDLER( cmpa_im ) -{ - uint16_t t,r; - IMMBYTE(t); - r = A - t; - CLR_NZC; - SET_FLAGS8(A,t,r); -} - -/* $a2 SBCA immediate ?*** */ -OP_HANDLER( sbca_im ) -{ - uint16_t t,r; - IMMBYTE(t); - r = A - t - (CC & 0x01); - CLR_NZC; - SET_FLAGS8(A,t,r); - A = r; -} - -/* $a3 CPX immediate -*** */ -OP_HANDLER( cpx_im ) -{ - uint16_t t,r; - IMMBYTE(t); - r = X - t; - CLR_NZC; - SET_FLAGS8(X,t,r); -} - -/* $a4 ANDA immediate -**- */ -OP_HANDLER( anda_im ) -{ - uint8_t t; - IMMBYTE(t); - A &= t; - CLR_NZ; - SET_NZ8(A); -} - -/* $a5 BITA immediate -**- */ -OP_HANDLER( bita_im ) -{ - uint8_t t,r; - IMMBYTE(t); - r = A & t; - CLR_NZ; - SET_NZ8(r); -} - -/* $a6 LDA immediate -**- */ -OP_HANDLER( lda_im ) -{ - IMMBYTE(A); - CLR_NZ; - SET_NZ8(A); -} - -/* $a7 ILLEGAL */ - -/* $a8 EORA immediate -**- */ -OP_HANDLER( eora_im ) -{ - uint8_t t; - IMMBYTE(t); - A ^= t; - CLR_NZ; - SET_NZ8(A); -} - -/* $a9 ADCA immediate **** */ -OP_HANDLER( adca_im ) -{ - uint16_t t,r; - IMMBYTE(t); - r = A + t + (CC & 0x01); - CLR_HNZC; - SET_FLAGS8(A,t,r); - SET_H(A,t,r); - A = r; -} - -/* $aa ORA immediate -**- */ -OP_HANDLER( ora_im ) -{ - uint8_t t; - IMMBYTE(t); - A |= t; - CLR_NZ; - SET_NZ8(A); -} - -/* $ab ADDA immediate **** */ -OP_HANDLER( adda_im ) -{ - uint16_t t,r; - IMMBYTE(t); - r = A + t; - CLR_HNZC; - SET_FLAGS8(A,t,r); - SET_H(A,t,r); - A = r; -} - -/* $ac ILLEGAL */ - -/* $ad BSR ---- */ -OP_HANDLER( bsr ) -{ - uint8_t t; - IMMBYTE(t); - PUSHWORD(m_pc); - PC += SIGNED(t); -} - -/* $ae LDX immediate -**- */ -OP_HANDLER( ldx_im ) -{ - IMMBYTE(X); - CLR_NZ; - SET_NZ8(X); -} - -/* $af ILLEGAL */ - /* $b0 SUBA direct ?*** */ -OP_HANDLER( suba_di ) -{ - uint16_t t,r; - DIRBYTE(t); - r = A - t; - CLR_NZC; - SET_FLAGS8(A,t,r); - A = r; -} - -/* $b1 CMPA direct ?*** */ -OP_HANDLER( cmpa_di ) -{ - uint16_t t,r; - DIRBYTE(t); - r = A - t; - CLR_NZC; - SET_FLAGS8(A,t,r); -} - -/* $b2 SBCA direct ?*** */ -OP_HANDLER( sbca_di ) -{ - uint16_t t,r; - DIRBYTE(t); - r = A - t - (CC & 0x01); - CLR_NZC; - SET_FLAGS8(A,t,r); - A = r; -} - -/* $b3 CPX direct -*** */ -OP_HANDLER( cpx_di ) -{ - uint16_t t,r; - DIRBYTE(t); - r = X - t; - CLR_NZC; - SET_FLAGS8(X,t,r); -} - -/* $b4 ANDA direct -**- */ -OP_HANDLER( anda_di ) -{ - uint8_t t; - DIRBYTE(t); - A &= t; - CLR_NZ; - SET_NZ8(A); -} - -/* $b5 BITA direct -**- */ -OP_HANDLER( bita_di ) -{ - uint8_t t,r; - DIRBYTE(t); - r = A & t; - CLR_NZ; - SET_NZ8(r); -} - -/* $b6 LDA direct -**- */ -OP_HANDLER( lda_di ) -{ - DIRBYTE(A); - CLR_NZ; - SET_NZ8(A); -} - -/* $b7 STA direct -**- */ -OP_HANDLER( sta_di ) -{ - CLR_NZ; - SET_NZ8(A); - DIRECT; - WM(EAD,A); -} - -/* $b8 EORA direct -**- */ -OP_HANDLER( eora_di ) -{ - uint8_t t; - DIRBYTE(t); - A ^= t; - CLR_NZ; - SET_NZ8(A); -} - -/* $b9 ADCA direct **** */ -OP_HANDLER( adca_di ) -{ - uint16_t t,r; - DIRBYTE(t); - r = A + t + (CC & 0x01); - CLR_HNZC; - SET_FLAGS8(A,t,r); - SET_H(A,t,r); - A = r; -} - -/* $ba ORA direct -**- */ -OP_HANDLER( ora_di ) -{ - uint8_t t; - DIRBYTE(t); - A |= t; - CLR_NZ; - SET_NZ8(A); -} - -/* $bb ADDA direct **** */ -OP_HANDLER( adda_di ) -{ - uint16_t t,r; - DIRBYTE(t); - r = A + t; - CLR_HNZC; - SET_FLAGS8(A,t,r); - SET_H(A,t,r); - A = r; -} - -/* $bc JMP direct -*** */ -OP_HANDLER( jmp_di ) -{ - DIRECT; - PC = EA; -} - -/* $bd JSR direct ---- */ -OP_HANDLER( jsr_di ) -{ - DIRECT; - PUSHWORD(m_pc); - PC = EA; -} - -/* $be LDX direct -**- */ -OP_HANDLER( ldx_di ) -{ - DIRBYTE(X); - CLR_NZ; - SET_NZ8(X); -} - -/* $bf STX direct -**- */ -OP_HANDLER( stx_di ) -{ - CLR_NZ; - SET_NZ8(X); - DIRECT; - WM(EAD,X); -} - /* $c0 SUBA extended ?*** */ -OP_HANDLER( suba_ex ) -{ - uint16_t t,r; - EXTBYTE(t); - r = A - t; - CLR_NZC; - SET_FLAGS8(A,t,r); - A = r; -} - -/* $c1 CMPA extended ?*** */ -OP_HANDLER( cmpa_ex ) -{ - uint16_t t,r; - EXTBYTE(t); - r = A - t; - CLR_NZC; - SET_FLAGS8(A,t,r); -} - -/* $c2 SBCA extended ?*** */ -OP_HANDLER( sbca_ex ) -{ - uint16_t t,r; - EXTBYTE(t); - r = A - t - (CC & 0x01); - CLR_NZC; - SET_FLAGS8(A,t,r); - A = r; -} - -/* $c3 CPX extended -*** */ -OP_HANDLER( cpx_ex ) -{ - uint16_t t,r; - EXTBYTE(t); - r = X - t; - CLR_NZC; - SET_FLAGS8(X,t,r); -} - -/* $c4 ANDA extended -**- */ -OP_HANDLER( anda_ex ) -{ - uint8_t t; - EXTBYTE(t); - A &= t; - CLR_NZ; - SET_NZ8(A); -} - -/* $c5 BITA extended -**- */ -OP_HANDLER( bita_ex ) -{ - uint8_t t,r; - EXTBYTE(t); - r = A & t; - CLR_NZ; - SET_NZ8(r); -} - -/* $c6 LDA extended -**- */ -OP_HANDLER( lda_ex ) -{ - EXTBYTE(A); - CLR_NZ; - SET_NZ8(A); -} - -/* $c7 STA extended -**- */ -OP_HANDLER( sta_ex ) -{ - CLR_NZ; - SET_NZ8(A); - EXTENDED; - WM(EAD,A); -} - -/* $c8 EORA extended -**- */ -OP_HANDLER( eora_ex ) -{ - uint8_t t; - EXTBYTE(t); - A ^= t; - CLR_NZ; - SET_NZ8(A); -} - -/* $c9 ADCA extended **** */ -OP_HANDLER( adca_ex ) -{ - uint16_t t,r; - EXTBYTE(t); - r = A + t + (CC & 0x01); - CLR_HNZC; - SET_FLAGS8(A,t,r); - SET_H(A,t,r); - A = r; -} - -/* $ca ORA extended -**- */ -OP_HANDLER( ora_ex ) -{ - uint8_t t; - EXTBYTE(t); - A |= t; - CLR_NZ; - SET_NZ8(A); -} - -/* $cb ADDA extended **** */ -OP_HANDLER( adda_ex ) -{ - uint16_t t,r; - EXTBYTE(t); - r = A + t; - CLR_HNZC; - SET_FLAGS8(A,t,r); - SET_H(A,t,r); - A = r; -} - -/* $cc JMP extended -*** */ -OP_HANDLER( jmp_ex ) -{ - EXTENDED; - PC = EA; -} - -/* $cd JSR extended ---- */ -OP_HANDLER( jsr_ex ) -{ - EXTENDED; - PUSHWORD(m_pc); - PC = EA; -} - -/* $ce LDX extended -**- */ -OP_HANDLER( ldx_ex ) -{ - EXTBYTE(X); - CLR_NZ; - SET_NZ8(X); -} - -/* $cf STX extended -**- */ -OP_HANDLER( stx_ex ) -{ - CLR_NZ; - SET_NZ8(X); - EXTENDED; - WM(EAD,X); -} - /* $d0 SUBA indexed, 2 byte offset ?*** */ -OP_HANDLER( suba_ix2 ) -{ - uint16_t t,r; - IDX2BYTE(t); - r = A - t; - CLR_NZC; - SET_FLAGS8(A,t,r); - A = r; -} - -/* $d1 CMPA indexed, 2 byte offset ?*** */ -OP_HANDLER( cmpa_ix2 ) -{ - uint16_t t,r; - IDX2BYTE(t); - r = A - t; - CLR_NZC; - SET_FLAGS8(A,t,r); -} - -/* $d2 SBCA indexed, 2 byte offset ?*** */ -OP_HANDLER( sbca_ix2 ) -{ - uint16_t t,r; - IDX2BYTE(t); - r = A - t - (CC & 0x01); - CLR_NZC; - SET_FLAGS8(A,t,r); - A = r; -} - -/* $d3 CPX indexed, 2 byte offset -*** */ -OP_HANDLER( cpx_ix2 ) -{ - uint16_t t,r; - IDX2BYTE(t); - r = X - t; - CLR_NZC; - SET_FLAGS8(X,t,r); -} - -/* $d4 ANDA indexed, 2 byte offset -**- */ -OP_HANDLER( anda_ix2 ) -{ - uint8_t t; - IDX2BYTE(t); - A &= t; - CLR_NZ; - SET_NZ8(A); -} - -/* $d5 BITA indexed, 2 byte offset -**- */ -OP_HANDLER( bita_ix2 ) -{ - uint8_t t,r; - IDX2BYTE(t); - r = A & t; - CLR_NZ; - SET_NZ8(r); -} - -/* $d6 LDA indexed, 2 byte offset -**- */ -OP_HANDLER( lda_ix2 ) -{ - IDX2BYTE(A); - CLR_NZ; - SET_NZ8(A); -} - -/* $d7 STA indexed, 2 byte offset -**- */ -OP_HANDLER( sta_ix2 ) -{ - CLR_NZ; - SET_NZ8(A); - INDEXED2; - WM(EAD,A); -} - -/* $d8 EORA indexed, 2 byte offset -**- */ -OP_HANDLER( eora_ix2 ) -{ - uint8_t t; - IDX2BYTE(t); - A ^= t; - CLR_NZ; - SET_NZ8(A); -} - -/* $d9 ADCA indexed, 2 byte offset **** */ -OP_HANDLER( adca_ix2 ) -{ - uint16_t t,r; - IDX2BYTE(t); - r = A + t + (CC & 0x01); - CLR_HNZC; - SET_FLAGS8(A,t,r); - SET_H(A,t,r); - A = r; -} - -/* $da ORA indexed, 2 byte offset -**- */ -OP_HANDLER( ora_ix2 ) -{ - uint8_t t; - IDX2BYTE(t); - A |= t; - CLR_NZ; - SET_NZ8(A); -} - -/* $db ADDA indexed, 2 byte offset **** */ -OP_HANDLER( adda_ix2 ) -{ - uint16_t t,r; - IDX2BYTE(t); - r = A + t; - CLR_HNZC; - SET_FLAGS8(A,t,r); - SET_H(A,t,r); - A = r; -} - -/* $dc JMP indexed, 2 byte offset -*** */ -OP_HANDLER( jmp_ix2 ) -{ - INDEXED2; - PC = EA; -} - -/* $dd JSR indexed, 2 byte offset ---- */ -OP_HANDLER( jsr_ix2 ) -{ - INDEXED2; - PUSHWORD(m_pc); - PC = EA; -} - -/* $de LDX indexed, 2 byte offset -**- */ -OP_HANDLER( ldx_ix2 ) -{ - IDX2BYTE(X); - CLR_NZ; - SET_NZ8(X); -} - -/* $df STX indexed, 2 byte offset -**- */ -OP_HANDLER( stx_ix2 ) -{ - CLR_NZ; - SET_NZ8(X); - INDEXED2; - WM(EAD,X); -} - /* $e0 SUBA indexed, 1 byte offset ?*** */ -OP_HANDLER( suba_ix1 ) +/* $f0 SUBA indexed ?*** */ +OP_HANDLER_MODE( suba ) { - uint16_t t,r; - IDX1BYTE(t); - r = A - t; + u16 t; + ARGBYTE(t); + u16 const r = A - t; CLR_NZC; - SET_FLAGS8(A,t,r); + SET_FLAGS8(A, t, r); A = r; } +/* $a1 CMPA immediate ?*** */ +/* $b1 CMPA direct ?*** */ +/* $c1 CMPA extended ?*** */ +/* $d1 CMPA indexed, 2 byte offset ?*** */ /* $e1 CMPA indexed, 1 byte offset ?*** */ -OP_HANDLER( cmpa_ix1 ) +/* $f1 CMPA indexed ?*** */ +OP_HANDLER_MODE( cmpa ) { - uint16_t t,r; - IDX1BYTE(t); - r = A - t; + u16 t; + ARGBYTE(t); + u16 const r = A - t; CLR_NZC; - SET_FLAGS8(A,t,r); + SET_FLAGS8(A, t, r); } +/* $a2 SBCA immediate ?*** */ +/* $b2 SBCA direct ?*** */ +/* $c2 SBCA extended ?*** */ +/* $d2 SBCA indexed, 2 byte offset ?*** */ /* $e2 SBCA indexed, 1 byte offset ?*** */ -OP_HANDLER( sbca_ix1 ) +/* $f2 SBCA indexed ?*** */ +OP_HANDLER_MODE( sbca ) { - uint16_t t,r; - IDX1BYTE(t); - r = A - t - (CC & 0x01); + u16 t; + ARGBYTE(t); + u16 const r = A - t - BIT(CC, 0); CLR_NZC; - SET_FLAGS8(A,t,r); + SET_FLAGS8(A, t, r); A = r; } +/* $a3 CPX immediate -*** */ +/* $b3 CPX direct -*** */ +/* $c3 CPX extended -*** */ +/* $d3 CPX indexed, 2 byte offset -*** */ /* $e3 CPX indexed, 1 byte offset -*** */ -OP_HANDLER( cpx_ix1 ) +/* $f3 CPX indexed -*** */ +OP_HANDLER_MODE( cpx ) { - uint16_t t,r; - IDX1BYTE(t); - r = X - t; + u16 t; + ARGBYTE(t); + u16 const r = X - t; CLR_NZC; - SET_FLAGS8(X,t,r); + SET_FLAGS8(X, t, r); } +/* $a4 ANDA immediate -**- */ +/* $b4 ANDA direct -**- */ +/* $c4 ANDA extended -**- */ +/* $d4 ANDA indexed, 2 byte offset -**- */ /* $e4 ANDA indexed, 1 byte offset -**- */ -OP_HANDLER( anda_ix1 ) +/* $f4 ANDA indexed -**- */ +OP_HANDLER_MODE( anda ) { - uint8_t t; - IDX1BYTE(t); + u8 t; + ARGBYTE(t); A &= t; CLR_NZ; SET_NZ8(A); } +/* $a5 BITA immediate -**- */ +/* $b5 BITA direct -**- */ +/* $c5 BITA extended -**- */ +/* $d5 BITA indexed, 2 byte offset -**- */ /* $e5 BITA indexed, 1 byte offset -**- */ -OP_HANDLER( bita_ix1 ) +/* $f5 BITA indexed -**- */ +OP_HANDLER_MODE( bita ) { - uint8_t t,r; - IDX1BYTE(t); - r = A & t; + u8 t; + ARGBYTE(t); + u8 const r = A & t; CLR_NZ; SET_NZ8(r); } +/* $a6 LDA immediate -**- */ +/* $b6 LDA direct -**- */ +/* $c6 LDA extended -**- */ +/* $d6 LDA indexed, 2 byte offset -**- */ /* $e6 LDA indexed, 1 byte offset -**- */ -OP_HANDLER( lda_ix1 ) +/* $f6 LDA indexed -**- */ +OP_HANDLER_MODE( lda ) { - IDX1BYTE(A); + ARGBYTE(A); CLR_NZ; SET_NZ8(A); } +/* $a7 ILLEGAL */ +/* $b7 STA direct -**- */ +/* $c7 STA extended -**- */ +/* $d7 STA indexed, 2 byte offset -**- */ /* $e7 STA indexed, 1 byte offset -**- */ -OP_HANDLER( sta_ix1 ) +/* $f7 STA indexed -**- */ +OP_HANDLER_MODE( sta ) { CLR_NZ; SET_NZ8(A); - INDEXED1; - WM(EAD,A); + ARGADDR; + WM(EAD, A); } +/* $a8 EORA immediate -**- */ +/* $b8 EORA direct -**- */ +/* $c8 EORA extended -**- */ +/* $d8 EORA indexed, 2 byte offset -**- */ /* $e8 EORA indexed, 1 byte offset -**- */ -OP_HANDLER( eora_ix1 ) +/* $f8 EORA indexed -**- */ +OP_HANDLER_MODE( eora ) { - uint8_t t; - IDX1BYTE(t); + u8 t; + ARGBYTE(t); A ^= t; CLR_NZ; SET_NZ8(A); } +/* $a9 ADCA immediate **** */ +/* $b9 ADCA direct **** */ +/* $c9 ADCA extended **** */ +/* $d9 ADCA indexed, 2 byte offset **** */ /* $e9 ADCA indexed, 1 byte offset **** */ -OP_HANDLER( adca_ix1 ) +/* $f9 ADCA indexed **** */ +OP_HANDLER_MODE( adca ) { - uint16_t t,r; - IDX1BYTE(t); - r = A + t + (CC & 0x01); + u16 t; + ARGBYTE(t); + u16 const r = A + t + BIT(CC, 0); CLR_HNZC; - SET_FLAGS8(A,t,r); - SET_H(A,t,r); + SET_FLAGS8(A, t, r); + SET_H(A, t, r); A = r; } +/* $aa ORA immediate -**- */ +/* $ba ORA direct -**- */ +/* $ca ORA extended -**- */ +/* $da ORA indexed, 2 byte offset -**- */ /* $ea ORA indexed, 1 byte offset -**- */ -OP_HANDLER( ora_ix1 ) +/* $fa ORA indexed -**- */ +OP_HANDLER_MODE( ora ) { - uint8_t t; - IDX1BYTE(t); + u8 t; + ARGBYTE(t); A |= t; CLR_NZ; SET_NZ8(A); } +/* $ab ADDA immediate **** */ +/* $bb ADDA direct **** */ +/* $cb ADDA extended **** */ +/* $db ADDA indexed, 2 byte offset **** */ /* $eb ADDA indexed, 1 byte offset **** */ -OP_HANDLER( adda_ix1 ) +/* $fb ADDA indexed **** */ +OP_HANDLER_MODE( adda ) { - uint16_t t,r; - IDX1BYTE(t); - r = A + t; + u16 t; + ARGBYTE(t); + u16 const r = A + t; CLR_HNZC; - SET_FLAGS8(A,t,r); - SET_H(A,t,r); + SET_FLAGS8(A, t, r); + SET_H(A, t, r); A = r; } +/* $ac ILLEGAL */ +/* $bc JMP direct -*** */ +/* $cc JMP extended -*** */ +/* $dc JMP indexed, 2 byte offset -*** */ /* $ec JMP indexed, 1 byte offset -*** */ -OP_HANDLER( jmp_ix1 ) +/* $fc JMP indexed -*** */ +OP_HANDLER_MODE( jmp ) { - INDEXED1; + ARGADDR; PC = EA; } -/* $ed JSR indexed, 1 byte offset ---- */ -OP_HANDLER( jsr_ix1 ) +/* $ad BSR ---- */ +OP_HANDLER( bsr ) { - INDEXED1; + u8 t; + IMMBYTE(t); PUSHWORD(m_pc); - PC = EA; -} - -/* $ee LDX indexed, 1 byte offset -**- */ -OP_HANDLER( ldx_ix1 ) -{ - IDX1BYTE(X); - CLR_NZ; - SET_NZ8(X); -} - -/* $ef STX indexed, 1 byte offset -**- */ -OP_HANDLER( stx_ix1 ) -{ - CLR_NZ; - SET_NZ8(X); - INDEXED1; - WM(EAD,X); -} - -/* $f0 SUBA indexed ?*** */ -OP_HANDLER( suba_ix ) -{ - uint16_t t,r; - IDXBYTE(t); - r = A - t; - CLR_NZC; - SET_FLAGS8(A,t,r); - A = r; -} - -/* $f1 CMPA indexed ?*** */ -OP_HANDLER( cmpa_ix ) -{ - uint16_t t,r; - IDXBYTE(t); - r = A - t; - CLR_NZC; - SET_FLAGS8(A,t,r); -} - -/* $f2 SBCA indexed ?*** */ -OP_HANDLER( sbca_ix ) -{ - uint16_t t,r; - IDXBYTE(t); - r = A - t - (CC & 0x01); - CLR_NZC; - SET_FLAGS8(A,t,r); - A = r; -} - -/* $f3 CPX indexed -*** */ -OP_HANDLER( cpx_ix ) -{ - uint16_t t,r; - IDXBYTE(t); - r = X - t; - CLR_NZC; - SET_FLAGS8(X,t,r); -} - -/* $f4 ANDA indexed -**- */ -OP_HANDLER( anda_ix ) -{ - uint8_t t; - IDXBYTE(t); - A &= t; - CLR_NZ; - SET_NZ8(A); -} - -/* $f5 BITA indexed -**- */ -OP_HANDLER( bita_ix ) -{ - uint8_t t,r; - IDXBYTE(t); - r = A & t; - CLR_NZ; - SET_NZ8(r); -} - -/* $f6 LDA indexed -**- */ -OP_HANDLER( lda_ix ) -{ - IDXBYTE(A); - CLR_NZ; - SET_NZ8(A); -} - -/* $f7 STA indexed -**- */ -OP_HANDLER( sta_ix ) -{ - CLR_NZ; - SET_NZ8(A); - INDEXED; - WM(EAD,A); -} - -/* $f8 EORA indexed -**- */ -OP_HANDLER( eora_ix ) -{ - uint8_t t; - IDXBYTE(t); - A ^= t; - CLR_NZ; - SET_NZ8(A); -} - -/* $f9 ADCA indexed **** */ -OP_HANDLER( adca_ix ) -{ - uint16_t t,r; - IDXBYTE(t); - r = A + t + (CC & 0x01); - CLR_HNZC; - SET_FLAGS8(A,t,r); - SET_H(A,t,r); - A = r; -} - -/* $fa ORA indexed -**- */ -OP_HANDLER( ora_ix ) -{ - uint8_t t; - IDXBYTE(t); - A |= t; - CLR_NZ; - SET_NZ8(A); -} - -/* $fb ADDA indexed **** */ -OP_HANDLER( adda_ix ) -{ - uint16_t t,r; - IDXBYTE(t); - r = A + t; - CLR_HNZC; - SET_FLAGS8(A,t,r); - SET_H(A,t,r); - A = r; -} - -/* $fc JMP indexed -*** */ -OP_HANDLER( jmp_ix ) -{ - INDEXED; - PC = EA; + PC += SIGNED(t); } +/* $bd JSR direct ---- */ +/* $cd JSR extended ---- */ +/* $dd JSR indexed, 2 byte offset ---- */ +/* $ed JSR indexed, 1 byte offset ---- */ /* $fd JSR indexed ---- */ -OP_HANDLER( jsr_ix ) +OP_HANDLER_MODE( jsr ) { - INDEXED; + ARGADDR; PUSHWORD(m_pc); PC = EA; } +/* $ae LDX immediate -**- */ +/* $be LDX direct -**- */ +/* $ce LDX extended -**- */ +/* $de LDX indexed, 2 byte offset -**- */ +/* $ee LDX indexed, 1 byte offset -**- */ /* $fe LDX indexed -**- */ -OP_HANDLER( ldx_ix ) +OP_HANDLER_MODE( ldx ) { - IDXBYTE(X); + ARGBYTE(X); CLR_NZ; SET_NZ8(X); } +/* $af ILLEGAL */ +/* $bf STX direct -**- */ +/* $cf STX extended -**- */ +/* $df STX indexed, 2 byte offset -**- */ +/* $ef STX indexed, 1 byte offset -**- */ /* $ff STX indexed -**- */ -OP_HANDLER( stx_ix ) +OP_HANDLER_MODE( stx ) { CLR_NZ; SET_NZ8(X); - INDEXED; - WM(EAD,X); + ARGADDR; + WM(EAD, X); } diff --git a/src/devices/cpu/m6805/m6805.cpp b/src/devices/cpu/m6805/m6805.cpp index bc1844f5bbf..f07a1249244 100644 --- a/src/devices/cpu/m6805/m6805.cpp +++ b/src/devices/cpu/m6805/m6805.cpp @@ -1,5 +1,5 @@ // license:BSD-3-Clause -// copyright-holders:Aaron Giles +// copyright-holders:Aaron Giles, Vas Crabb /*** m6805: Portable 6805 emulator ****************************************** m6805.c (Also supports hd68705 and hd63705 variants) @@ -42,44 +42,92 @@ #define IRQ_LEVEL_DETECT 0 -const uint8_t m6805_base_device::m_flags8i[256]= /* increment */ -{ - 0x02,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, - 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, - 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, - 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, - 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, - 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, - 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, - 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, - 0x04,0x04,0x04,0x04,0x04,0x04,0x04,0x04,0x04,0x04,0x04,0x04,0x04,0x04,0x04,0x04, - 0x04,0x04,0x04,0x04,0x04,0x04,0x04,0x04,0x04,0x04,0x04,0x04,0x04,0x04,0x04,0x04, - 0x04,0x04,0x04,0x04,0x04,0x04,0x04,0x04,0x04,0x04,0x04,0x04,0x04,0x04,0x04,0x04, - 0x04,0x04,0x04,0x04,0x04,0x04,0x04,0x04,0x04,0x04,0x04,0x04,0x04,0x04,0x04,0x04, - 0x04,0x04,0x04,0x04,0x04,0x04,0x04,0x04,0x04,0x04,0x04,0x04,0x04,0x04,0x04,0x04, - 0x04,0x04,0x04,0x04,0x04,0x04,0x04,0x04,0x04,0x04,0x04,0x04,0x04,0x04,0x04,0x04, - 0x04,0x04,0x04,0x04,0x04,0x04,0x04,0x04,0x04,0x04,0x04,0x04,0x04,0x04,0x04,0x04, - 0x04,0x04,0x04,0x04,0x04,0x04,0x04,0x04,0x04,0x04,0x04,0x04,0x04,0x04,0x04,0x04 +#define OP(name) (&m6805_base_device::name) +#define OP_T(name) (&m6805_base_device::name<true>) +#define OP_F(name) (&m6805_base_device::name<false>) +#define OP_IM(name) (&m6805_base_device::name<addr_mode::IM>) +#define OP_DI(name) (&m6805_base_device::name<addr_mode::DI>) +#define OP_EX(name) (&m6805_base_device::name<addr_mode::EX>) +#define OP_IX(name) (&m6805_base_device::name<addr_mode::IX>) +#define OP_IX1(name) (&m6805_base_device::name<addr_mode::IX1>) +#define OP_IX2(name) (&m6805_base_device::name<addr_mode::IX2>) +const m6805_base_device::op_handler_func m6805_base_device::m_ophndlr[256] = +{ + /* 0/8 1/9 2/A 3/B 4/C 5/D 6/E 7/F */ + /* 0 */ OP(brset<0>),OP(brclr<0>),OP(brset<1>),OP(brclr<1>),OP(brset<2>),OP(brclr<2>),OP(brset<3>),OP(brclr<3>), + OP(brset<4>),OP(brclr<4>),OP(brset<5>),OP(brclr<5>),OP(brset<6>),OP(brclr<6>),OP(brset<7>),OP(brclr<7>), + /* 1 */ OP(bset<0>), OP(bclr<0>), OP(bset<1>), OP(bclr<1>), OP(bset<2>), OP(bclr<2>), OP(bset<3>), OP(bclr<3>), + OP(bset<4>), OP(bclr<4>), OP(bset<5>), OP(bclr<5>), OP(bset<6>), OP(bclr<6>), OP(bset<7>), OP(bclr<7>), + /* 2 */ OP_T(bra), OP_F(bra), OP_T(bhi), OP_F(bhi), OP_T(bcc), OP_F(bcc), OP_T(bne), OP_F(bne), + OP_T(bhcc), OP_F(bhcc), OP_T(bpl), OP_F(bpl), OP_T(bmc), OP_F(bmc), OP(bil), OP(bih), + /* 3 */ OP_DI(neg), OP(illegal), OP(illegal), OP_DI(com), OP_DI(lsr), OP(illegal), OP_DI(ror), OP_DI(asr), + OP_DI(lsl), OP_DI(rol), OP_DI(dec), OP(illegal), OP_DI(inc), OP_DI(tst), OP(illegal), OP_DI(clr), + /* 4 */ OP(nega), OP(illegal), OP(illegal), OP(coma), OP(lsra), OP(illegal), OP(rora), OP(asra), + OP(lsla), OP(rola), OP(deca), OP(illegal), OP(inca), OP(tsta), OP(illegal), OP(clra), + /* 5 */ OP(negx), OP(illegal), OP(illegal), OP(comx), OP(lsrx), OP(illegal), OP(rorx), OP(asrx), + OP(lslx), OP(rolx), OP(decx), OP(illegal), OP(incx), OP(tstx), OP(illegal), OP(clrx), + /* 6 */ OP_IX1(neg), OP(illegal), OP(illegal), OP_IX1(com), OP_IX1(lsr), OP(illegal), OP_IX1(ror), OP_IX1(asr), + OP_IX1(lsl), OP_IX1(rol), OP_IX1(dec), OP(illegal), OP_IX1(inc), OP_IX1(tst), OP(illegal), OP_IX1(clr), + /* 7 */ OP_IX(neg), OP(illegal), OP(illegal), OP_IX(com), OP_IX(lsr), OP(illegal), OP_IX(ror), OP_IX(asr), + OP_IX(lsl), OP_IX(rol), OP_IX(dec), OP(illegal), OP_IX(inc), OP_IX(tst), OP(illegal), OP_IX(clr), + /* 8 */ OP(rti), OP(rts), OP(illegal), OP(swi), OP(illegal), OP(illegal), OP(illegal), OP(illegal), + OP(illegal), OP(illegal), OP(illegal), OP(illegal), OP(illegal), OP(illegal), OP(illegal), OP(illegal), + /* 9 */ OP(illegal), OP(illegal), OP(illegal), OP(illegal), OP(illegal), OP(illegal), OP(illegal), OP(tax), + OP(clc), OP(sec), OP(cli), OP(sei), OP(rsp), OP(nop), OP(illegal), OP(txa), + /* A */ OP_IM(suba), OP_IM(cmpa), OP_IM(sbca), OP_IM(cpx), OP_IM(anda), OP_IM(bita), OP_IM(lda), OP(illegal), + OP_IM(eora), OP_IM(adca), OP_IM(ora), OP_IM(adda), OP(illegal), OP(bsr), OP_IM(ldx), OP(illegal), + /* B */ OP_DI(suba), OP_DI(cmpa), OP_DI(sbca), OP_DI(cpx), OP_DI(anda), OP_DI(bita), OP_DI(lda), OP_DI(sta), + OP_DI(eora), OP_DI(adca), OP_DI(ora), OP_DI(adda), OP_DI(jmp), OP_DI(jsr), OP_DI(ldx), OP_DI(stx), + /* C */ OP_EX(suba), OP_EX(cmpa), OP_EX(sbca), OP_EX(cpx), OP_EX(anda), OP_EX(bita), OP_EX(lda), OP_EX(sta), + OP_EX(eora), OP_EX(adca), OP_EX(ora), OP_EX(adda), OP_EX(jmp), OP_EX(jsr), OP_EX(ldx), OP_EX(stx), + /* D */ OP_IX2(suba),OP_IX2(cmpa),OP_IX2(sbca),OP_IX2(cpx), OP_IX2(anda),OP_IX2(bita),OP_IX2(lda), OP_IX2(sta), + OP_IX2(eora),OP_IX2(adca),OP_IX2(ora), OP_IX2(adda),OP_IX2(jmp), OP_IX2(jsr), OP_IX2(ldx), OP_IX2(stx), + /* E */ OP_IX1(suba),OP_IX1(cmpa),OP_IX1(sbca),OP_IX1(cpx), OP_IX1(anda),OP_IX1(bita),OP_IX1(lda), OP_IX1(sta), + OP_IX1(eora),OP_IX1(adca),OP_IX1(ora), OP_IX1(adda),OP_IX1(jmp), OP_IX1(jsr), OP_IX1(ldx), OP_IX1(stx), + /* F */ OP_IX(suba), OP_IX(cmpa), OP_IX(sbca), OP_IX(cpx), OP_IX(anda), OP_IX(bita), OP_IX(lda), OP_IX(sta), + OP_IX(eora), OP_IX(adca), OP_IX(ora), OP_IX(adda), OP_IX(jmp), OP_IX(jsr), OP_IX(ldx), OP_IX(stx) }; -const uint8_t m6805_base_device::m_flags8d[256]= /* decrement */ -{ - 0x02,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, - 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, - 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, - 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, - 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, - 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, - 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, - 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, - 0x04,0x04,0x04,0x04,0x04,0x04,0x04,0x04,0x04,0x04,0x04,0x04,0x04,0x04,0x04,0x04, - 0x04,0x04,0x04,0x04,0x04,0x04,0x04,0x04,0x04,0x04,0x04,0x04,0x04,0x04,0x04,0x04, - 0x04,0x04,0x04,0x04,0x04,0x04,0x04,0x04,0x04,0x04,0x04,0x04,0x04,0x04,0x04,0x04, - 0x04,0x04,0x04,0x04,0x04,0x04,0x04,0x04,0x04,0x04,0x04,0x04,0x04,0x04,0x04,0x04, - 0x04,0x04,0x04,0x04,0x04,0x04,0x04,0x04,0x04,0x04,0x04,0x04,0x04,0x04,0x04,0x04, - 0x04,0x04,0x04,0x04,0x04,0x04,0x04,0x04,0x04,0x04,0x04,0x04,0x04,0x04,0x04,0x04, - 0x04,0x04,0x04,0x04,0x04,0x04,0x04,0x04,0x04,0x04,0x04,0x04,0x04,0x04,0x04,0x04, - 0x04,0x04,0x04,0x04,0x04,0x04,0x04,0x04,0x04,0x04,0x04,0x04,0x04,0x04,0x04,0x04 +const uint8_t m6805_base_device::m_flags8i[256] = /* increment */ +{ + /* 0 1 2 3 4 5 6 7 8 9 A B C D E F */ + /*0*/ 0x02,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + /*1*/ 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + /*2*/ 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + /*3*/ 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + /*4*/ 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + /*5*/ 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + /*6*/ 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + /*7*/ 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + /*8*/ 0x04,0x04,0x04,0x04,0x04,0x04,0x04,0x04,0x04,0x04,0x04,0x04,0x04,0x04,0x04,0x04, + /*9*/ 0x04,0x04,0x04,0x04,0x04,0x04,0x04,0x04,0x04,0x04,0x04,0x04,0x04,0x04,0x04,0x04, + /*A*/ 0x04,0x04,0x04,0x04,0x04,0x04,0x04,0x04,0x04,0x04,0x04,0x04,0x04,0x04,0x04,0x04, + /*B*/ 0x04,0x04,0x04,0x04,0x04,0x04,0x04,0x04,0x04,0x04,0x04,0x04,0x04,0x04,0x04,0x04, + /*C*/ 0x04,0x04,0x04,0x04,0x04,0x04,0x04,0x04,0x04,0x04,0x04,0x04,0x04,0x04,0x04,0x04, + /*D*/ 0x04,0x04,0x04,0x04,0x04,0x04,0x04,0x04,0x04,0x04,0x04,0x04,0x04,0x04,0x04,0x04, + /*E*/ 0x04,0x04,0x04,0x04,0x04,0x04,0x04,0x04,0x04,0x04,0x04,0x04,0x04,0x04,0x04,0x04, + /*F*/ 0x04,0x04,0x04,0x04,0x04,0x04,0x04,0x04,0x04,0x04,0x04,0x04,0x04,0x04,0x04,0x04 +}; + +const uint8_t m6805_base_device::m_flags8d[256] = /* decrement */ +{ + /* 0 1 2 3 4 5 6 7 8 9 A B C D E F */ + /*0*/ 0x02,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + /*1*/ 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + /*2*/ 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + /*3*/ 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + /*4*/ 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + /*5*/ 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + /*6*/ 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + /*7*/ 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + /*8*/ 0x04,0x04,0x04,0x04,0x04,0x04,0x04,0x04,0x04,0x04,0x04,0x04,0x04,0x04,0x04,0x04, + /*9*/ 0x04,0x04,0x04,0x04,0x04,0x04,0x04,0x04,0x04,0x04,0x04,0x04,0x04,0x04,0x04,0x04, + /*A*/ 0x04,0x04,0x04,0x04,0x04,0x04,0x04,0x04,0x04,0x04,0x04,0x04,0x04,0x04,0x04,0x04, + /*B*/ 0x04,0x04,0x04,0x04,0x04,0x04,0x04,0x04,0x04,0x04,0x04,0x04,0x04,0x04,0x04,0x04, + /*C*/ 0x04,0x04,0x04,0x04,0x04,0x04,0x04,0x04,0x04,0x04,0x04,0x04,0x04,0x04,0x04,0x04, + /*D*/ 0x04,0x04,0x04,0x04,0x04,0x04,0x04,0x04,0x04,0x04,0x04,0x04,0x04,0x04,0x04,0x04, + /*E*/ 0x04,0x04,0x04,0x04,0x04,0x04,0x04,0x04,0x04,0x04,0x04,0x04,0x04,0x04,0x04,0x04, + /*F*/ 0x04,0x04,0x04,0x04,0x04,0x04,0x04,0x04,0x04,0x04,0x04,0x04,0x04,0x04,0x04,0x04 }; /* what they say it is ... */ @@ -88,8 +136,8 @@ const uint8_t m6805_base_device::m_cycles1[] = /* 0 1 2 3 4 5 6 7 8 9 A B C D E F */ /*0*/ 10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10, /*1*/ 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, - /*2*/ 4, 0, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, - /*3*/ 6, 0, 0, 6, 6, 0, 6, 6, 6, 6, 6, 6, 0, 6, 6, 0, + /*2*/ 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, + /*3*/ 6, 0, 0, 6, 6, 0, 6, 6, 6, 6, 6, 0, 6, 6, 0, 6, /*4*/ 4, 0, 0, 4, 4, 0, 4, 4, 4, 4, 4, 0, 4, 4, 0, 4, /*5*/ 4, 0, 0, 4, 4, 0, 4, 4, 4, 4, 4, 0, 4, 4, 0, 4, /*6*/ 7, 0, 0, 7, 7, 0, 7, 7, 7, 7, 7, 0, 7, 7, 0, 7, @@ -487,8 +535,6 @@ uint32_t m6805_base_device::execute_input_lines() const /* execute instructions on this CPU until icount expires */ void m6805_base_device::execute_run() { - uint8_t ireg; - S = SP_ADJUST( S ); /* Taken from CPU_SET_CONTEXT when pointer'afying */ do @@ -500,271 +546,9 @@ void m6805_base_device::execute_run() debugger_instruction_hook(this, PC); - ireg = M_RDOP(PC++); + u8 const ireg = M_RDOP(PC++); - switch (ireg) - { - case 0x00: brset(0x01); break; - case 0x01: brclr(0x01); break; - case 0x02: brset(0x02); break; - case 0x03: brclr(0x02); break; - case 0x04: brset(0x04); break; - case 0x05: brclr(0x04); break; - case 0x06: brset(0x08); break; - case 0x07: brclr(0x08); break; - case 0x08: brset(0x10); break; - case 0x09: brclr(0x10); break; - case 0x0A: brset(0x20); break; - case 0x0B: brclr(0x20); break; - case 0x0C: brset(0x40); break; - case 0x0D: brclr(0x40); break; - case 0x0E: brset(0x80); break; - case 0x0F: brclr(0x80); break; - case 0x10: bset(0x01); break; - case 0x11: bclr(0x01); break; - case 0x12: bset(0x02); break; - case 0x13: bclr(0x02); break; - case 0x14: bset(0x04); break; - case 0x15: bclr(0x04); break; - case 0x16: bset(0x08); break; - case 0x17: bclr(0x08); break; - case 0x18: bset(0x10); break; - case 0x19: bclr(0x10); break; - case 0x1a: bset(0x20); break; - case 0x1b: bclr(0x20); break; - case 0x1c: bset(0x40); break; - case 0x1d: bclr(0x40); break; - case 0x1e: bset(0x80); break; - case 0x1f: bclr(0x80); break; - case 0x20: bra(); break; - case 0x21: brn(); break; - case 0x22: bhi(); break; - case 0x23: bls(); break; - case 0x24: bcc(); break; - case 0x25: bcs(); break; - case 0x26: bne(); break; - case 0x27: beq(); break; - case 0x28: bhcc(); break; - case 0x29: bhcs(); break; - case 0x2a: bpl(); break; - case 0x2b: bmi(); break; - case 0x2c: bmc(); break; - case 0x2d: bms(); break; - case 0x2e: bil(); break; - case 0x2f: bih(); break; - case 0x30: neg_di(); break; - case 0x31: illegal(); break; - case 0x32: illegal(); break; - case 0x33: com_di(); break; - case 0x34: lsr_di(); break; - case 0x35: illegal(); break; - case 0x36: ror_di(); break; - case 0x37: asr_di(); break; - case 0x38: lsl_di(); break; - case 0x39: rol_di(); break; - case 0x3a: dec_di(); break; - case 0x3b: illegal(); break; - case 0x3c: inc_di(); break; - case 0x3d: tst_di(); break; - case 0x3e: illegal(); break; - case 0x3f: clr_di(); break; - case 0x40: nega(); break; - case 0x41: illegal(); break; - case 0x42: illegal(); break; - case 0x43: coma(); break; - case 0x44: lsra(); break; - case 0x45: illegal(); break; - case 0x46: rora(); break; - case 0x47: asra(); break; - case 0x48: lsla(); break; - case 0x49: rola(); break; - case 0x4a: deca(); break; - case 0x4b: illegal(); break; - case 0x4c: inca(); break; - case 0x4d: tsta(); break; - case 0x4e: illegal(); break; - case 0x4f: clra(); break; - case 0x50: negx(); break; - case 0x51: illegal(); break; - case 0x52: illegal(); break; - case 0x53: comx(); break; - case 0x54: lsrx(); break; - case 0x55: illegal(); break; - case 0x56: rorx(); break; - case 0x57: asrx(); break; - case 0x58: aslx(); break; - case 0x59: rolx(); break; - case 0x5a: decx(); break; - case 0x5b: illegal(); break; - case 0x5c: incx(); break; - case 0x5d: tstx(); break; - case 0x5e: illegal(); break; - case 0x5f: clrx(); break; - case 0x60: neg_ix1(); break; - case 0x61: illegal(); break; - case 0x62: illegal(); break; - case 0x63: com_ix1(); break; - case 0x64: lsr_ix1(); break; - case 0x65: illegal(); break; - case 0x66: ror_ix1(); break; - case 0x67: asr_ix1(); break; - case 0x68: lsl_ix1(); break; - case 0x69: rol_ix1(); break; - case 0x6a: dec_ix1(); break; - case 0x6b: illegal(); break; - case 0x6c: inc_ix1(); break; - case 0x6d: tst_ix1(); break; - case 0x6e: illegal(); break; - case 0x6f: clr_ix1(); break; - case 0x70: neg_ix(); break; - case 0x71: illegal(); break; - case 0x72: illegal(); break; - case 0x73: com_ix(); break; - case 0x74: lsr_ix(); break; - case 0x75: illegal(); break; - case 0x76: ror_ix(); break; - case 0x77: asr_ix(); break; - case 0x78: lsl_ix(); break; - case 0x79: rol_ix(); break; - case 0x7a: dec_ix(); break; - case 0x7b: illegal(); break; - case 0x7c: inc_ix(); break; - case 0x7d: tst_ix(); break; - case 0x7e: illegal(); break; - case 0x7f: clr_ix(); break; - case 0x80: rti(); break; - case 0x81: rts(); break; - case 0x82: illegal(); break; - case 0x83: swi(); break; - case 0x84: illegal(); break; - case 0x85: illegal(); break; - case 0x86: illegal(); break; - case 0x87: illegal(); break; - case 0x88: illegal(); break; - case 0x89: illegal(); break; - case 0x8a: illegal(); break; - case 0x8b: illegal(); break; - case 0x8c: illegal(); break; - case 0x8d: illegal(); break; - case 0x8e: illegal(); break; - case 0x8f: illegal(); break; - case 0x90: illegal(); break; - case 0x91: illegal(); break; - case 0x92: illegal(); break; - case 0x93: illegal(); break; - case 0x94: illegal(); break; - case 0x95: illegal(); break; - case 0x96: illegal(); break; - case 0x97: tax(); break; - case 0x98: CLC; break; - case 0x99: SEC; break; -#if IRQ_LEVEL_DETECT - case 0x9a: CLI; if (m_irq_state != CLEAR_LINE) m_pending_interrupts |= 1 << M6805_IRQ_LINE; break; -#else - case 0x9a: CLI; break; -#endif - case 0x9b: SEI; break; - case 0x9c: rsp(); break; - case 0x9d: nop(); break; - case 0x9e: illegal(); break; - case 0x9f: txa(); break; - case 0xa0: suba_im(); break; - case 0xa1: cmpa_im(); break; - case 0xa2: sbca_im(); break; - case 0xa3: cpx_im(); break; - case 0xa4: anda_im(); break; - case 0xa5: bita_im(); break; - case 0xa6: lda_im(); break; - case 0xa7: illegal(); break; - case 0xa8: eora_im(); break; - case 0xa9: adca_im(); break; - case 0xaa: ora_im(); break; - case 0xab: adda_im(); break; - case 0xac: illegal(); break; - case 0xad: bsr(); break; - case 0xae: ldx_im(); break; - case 0xaf: illegal(); break; - case 0xb0: suba_di(); break; - case 0xb1: cmpa_di(); break; - case 0xb2: sbca_di(); break; - case 0xb3: cpx_di(); break; - case 0xb4: anda_di(); break; - case 0xb5: bita_di(); break; - case 0xb6: lda_di(); break; - case 0xb7: sta_di(); break; - case 0xb8: eora_di(); break; - case 0xb9: adca_di(); break; - case 0xba: ora_di(); break; - case 0xbb: adda_di(); break; - case 0xbc: jmp_di(); break; - case 0xbd: jsr_di(); break; - case 0xbe: ldx_di(); break; - case 0xbf: stx_di(); break; - case 0xc0: suba_ex(); break; - case 0xc1: cmpa_ex(); break; - case 0xc2: sbca_ex(); break; - case 0xc3: cpx_ex(); break; - case 0xc4: anda_ex(); break; - case 0xc5: bita_ex(); break; - case 0xc6: lda_ex(); break; - case 0xc7: sta_ex(); break; - case 0xc8: eora_ex(); break; - case 0xc9: adca_ex(); break; - case 0xca: ora_ex(); break; - case 0xcb: adda_ex(); break; - case 0xcc: jmp_ex(); break; - case 0xcd: jsr_ex(); break; - case 0xce: ldx_ex(); break; - case 0xcf: stx_ex(); break; - case 0xd0: suba_ix2(); break; - case 0xd1: cmpa_ix2(); break; - case 0xd2: sbca_ix2(); break; - case 0xd3: cpx_ix2(); break; - case 0xd4: anda_ix2(); break; - case 0xd5: bita_ix2(); break; - case 0xd6: lda_ix2(); break; - case 0xd7: sta_ix2(); break; - case 0xd8: eora_ix2(); break; - case 0xd9: adca_ix2(); break; - case 0xda: ora_ix2(); break; - case 0xdb: adda_ix2(); break; - case 0xdc: jmp_ix2(); break; - case 0xdd: jsr_ix2(); break; - case 0xde: ldx_ix2(); break; - case 0xdf: stx_ix2(); break; - case 0xe0: suba_ix1(); break; - case 0xe1: cmpa_ix1(); break; - case 0xe2: sbca_ix1(); break; - case 0xe3: cpx_ix1(); break; - case 0xe4: anda_ix1(); break; - case 0xe5: bita_ix1(); break; - case 0xe6: lda_ix1(); break; - case 0xe7: sta_ix1(); break; - case 0xe8: eora_ix1(); break; - case 0xe9: adca_ix1(); break; - case 0xea: ora_ix1(); break; - case 0xeb: adda_ix1(); break; - case 0xec: jmp_ix1(); break; - case 0xed: jsr_ix1(); break; - case 0xee: ldx_ix1(); break; - case 0xef: stx_ix1(); break; - case 0xf0: suba_ix(); break; - case 0xf1: cmpa_ix(); break; - case 0xf2: sbca_ix(); break; - case 0xf3: cpx_ix(); break; - case 0xf4: anda_ix(); break; - case 0xf5: bita_ix(); break; - case 0xf6: lda_ix(); break; - case 0xf7: sta_ix(); break; - case 0xf8: eora_ix(); break; - case 0xf9: adca_ix(); break; - case 0xfa: ora_ix(); break; - case 0xfb: adda_ix(); break; - case 0xfc: jmp_ix(); break; - case 0xfd: jsr_ix(); break; - case 0xfe: ldx_ix(); break; - case 0xff: stx_ix(); break; - } + (this->*m_ophndlr[ireg])(); m_icount -= m_cycles1[ireg]; burn_cycles(m_cycles1[ireg]); } diff --git a/src/devices/cpu/m6805/m6805.h b/src/devices/cpu/m6805/m6805.h index 5d0dfede083..d60bc5bcec2 100644 --- a/src/devices/cpu/m6805/m6805.h +++ b/src/devices/cpu/m6805/m6805.h @@ -26,6 +26,18 @@ public: m6805_base_device(const machine_config &mconfig, const char *tag, device_t *owner, uint32_t clock, const device_type type, const char *name, uint32_t addr_width, const char *shortname, const char *source); protected: + enum class addr_mode { IM, DI, EX, IX, IX1, IX2 }; + + enum + { + M6805_PC = 1, + M6805_S, + M6805_CC, + M6805_A, + M6805_X, + M6805_IRQ_STATE + }; + m6805_base_device(const machine_config &mconfig, const char *tag, device_t *owner, uint32_t clock, const device_type type, const char *name, uint32_t addr_width, address_map_delegate internal_map, const char *shortname, const char *source); // device-level overrides @@ -55,63 +67,39 @@ protected: // for devices with timing-sensitive peripherals virtual void burn_cycles(unsigned count) { } -private: - // opcode/condition tables - static const uint8_t m_flags8i[256]; - static const uint8_t m_flags8d[256]; - static const uint8_t m_cycles1[256]; - -protected: - enum - { - M6805_PC = 1, - M6805_S, - M6805_CC, - M6805_A, - M6805_X, - M6805_IRQ_STATE - }; - void rd_s_handler_b(uint8_t *b); void rd_s_handler_w(PAIR *p); void wr_s_handler_b(uint8_t *b); void wr_s_handler_w(PAIR *p); void RM16(uint32_t addr, PAIR *p); - void brset(uint8_t bit); - void brclr(uint8_t bit); - void bset(uint8_t bit); - void bclr(uint8_t bit); - - void bra(); - void brn(); - void bhi(); - void bls(); - void bcc(); - void bcs(); - void bne(); - void beq(); - void bhcc(); - void bhcs(); - void bpl(); - void bmi(); - void bmc(); - void bms(); + template <unsigned B> void brset(); + template <unsigned B> void brclr(); + template <unsigned B> void bset(); + template <unsigned B> void bclr(); + + template <bool C> void bra(); + template <bool C> void bhi(); + template <bool C> void bcc(); + template <bool C> void bne(); + template <bool C> void bhcc(); + template <bool C> void bpl(); + template <bool C> void bmc(); virtual void bil(); virtual void bih(); void bsr(); - void neg_di(); - void com_di(); - void lsr_di(); - void ror_di(); - void asr_di(); - void lsl_di(); - void rol_di(); - void dec_di(); - void inc_di(); - void tst_di(); - void clr_di(); + template <addr_mode M> void neg(); + template <addr_mode M> void com(); + template <addr_mode M> void lsr(); + template <addr_mode M> void ror(); + template <addr_mode M> void asr(); + template <addr_mode M> void lsl(); + template <addr_mode M> void rol(); + template <addr_mode M> void dec(); + template <addr_mode M> void inc(); + template <addr_mode M> void tst(); + template <addr_mode M> void clr(); void nega(); void coma(); @@ -130,38 +118,13 @@ protected: void lsrx(); void rorx(); void asrx(); - void aslx(); -// void lslx(); + void lslx(); void rolx(); void decx(); void incx(); void tstx(); void clrx(); - void neg_ix1(); - void com_ix1(); - void lsr_ix1(); - void ror_ix1(); - void asr_ix1(); - void lsl_ix1(); - void rol_ix1(); - void dec_ix1(); - void inc_ix1(); - void tst_ix1(); - void clr_ix1(); - - void neg_ix(); - void com_ix(); - void lsr_ix(); - void ror_ix(); - void asr_ix(); - void lsl_ix(); - void rol_ix(); - void dec_ix(); - void inc_ix(); - void tst_ix(); - void clr_ix(); - void rti(); void rts(); virtual void swi(); @@ -169,102 +132,30 @@ protected: void tax(); void txa(); + void clc(); + void sec(); + void cli(); + void sei(); + void rsp(); void nop(); - void suba_im(); - void cmpa_im(); - void sbca_im(); - void cpx_im(); - void anda_im(); - void bita_im(); - void lda_im(); - void eora_im(); - void adca_im(); - void ora_im(); - void adda_im(); - - void ldx_im(); - void suba_di(); - void cmpa_di(); - void sbca_di(); - void cpx_di(); - void anda_di(); - void bita_di(); - void lda_di(); - void sta_di(); - void eora_di(); - void adca_di(); - void ora_di(); - void adda_di(); - void jmp_di(); - void jsr_di(); - void ldx_di(); - void stx_di(); - void suba_ex(); - void cmpa_ex(); - void sbca_ex(); - void cpx_ex(); - void anda_ex(); - void bita_ex(); - void lda_ex(); - void sta_ex(); - void eora_ex(); - void adca_ex(); - void ora_ex(); - void adda_ex(); - void jmp_ex(); - void jsr_ex(); - void ldx_ex(); - void stx_ex(); - void suba_ix2(); - void cmpa_ix2(); - void sbca_ix2(); - void cpx_ix2(); - void anda_ix2(); - void bita_ix2(); - void lda_ix2(); - void sta_ix2(); - void eora_ix2(); - void adca_ix2(); - void ora_ix2(); - void adda_ix2(); - void jmp_ix2(); - void jsr_ix2(); - void ldx_ix2(); - void stx_ix2(); - void suba_ix1(); - void cmpa_ix1(); - void sbca_ix1(); - void cpx_ix1(); - void anda_ix1(); - void bita_ix1(); - void lda_ix1(); - void sta_ix1(); - void eora_ix1(); - void adca_ix1(); - void ora_ix1(); - void adda_ix1(); - void jmp_ix1(); - void jsr_ix1(); - void ldx_ix1(); - void stx_ix1(); - void suba_ix(); - void cmpa_ix(); - void sbca_ix(); - void cpx_ix(); - void anda_ix(); - void bita_ix(); - void lda_ix(); - void sta_ix(); - void eora_ix(); - void adca_ix(); - void ora_ix(); - void adda_ix(); - void jmp_ix(); - void jsr_ix(); - void ldx_ix(); - void stx_ix(); + template <addr_mode M> void suba(); + template <addr_mode M> void cmpa(); + template <addr_mode M> void sbca(); + template <addr_mode M> void cpx(); + template <addr_mode M> void anda(); + template <addr_mode M> void bita(); + template <addr_mode M> void lda(); + template <addr_mode M> void sta(); + template <addr_mode M> void eora(); + template <addr_mode M> void adca(); + template <addr_mode M> void ora(); + template <addr_mode M> void adda(); + template <addr_mode M> void jmp(); + template <addr_mode M> void jsr(); + template <addr_mode M> void ldx(); + template <addr_mode M> void stx(); void illegal(); @@ -298,6 +189,15 @@ protected: // address spaces address_space *m_program; direct_read_data *m_direct; + +private: + typedef void (m6805_base_device::*op_handler_func)(); + + // opcode/condition tables + static const op_handler_func m_ophndlr[256]; + static const uint8_t m_flags8i[256]; + static const uint8_t m_flags8d[256]; + static const uint8_t m_cycles1[256]; }; diff --git a/src/devices/cpu/m6805/m6805defs.h b/src/devices/cpu/m6805/m6805defs.h index 2fc83194500..d6452d33185 100644 --- a/src/devices/cpu/m6805/m6805defs.h +++ b/src/devices/cpu/m6805/m6805defs.h @@ -53,9 +53,9 @@ #define SP_ADJUST(s) ( ( (s) & SP_MASK ) | SP_LOW ) /* macros to access memory */ -#define IMMBYTE(b) {b = M_RDOP_ARG(PC++);} -#define IMMWORD(w) {w.d = 0; w.b.h = M_RDOP_ARG(PC); w.b.l = M_RDOP_ARG(PC+1); PC+=2;} -#define SKIPBYTE() {M_RDOP_ARG(PC++);} +#define IMMBYTE(b) do { b = M_RDOP_ARG(PC++); } while (false) +#define IMMWORD(w) do { w.d = 0; w.b.h = M_RDOP_ARG(PC); w.b.l = M_RDOP_ARG(PC+1); PC+=2; } while (false) +#define SKIPBYTE() do { M_RDOP_ARG(PC++); } while (false) #define PUSHBYTE(b) wr_s_handler_b(&b) #define PUSHWORD(w) wr_s_handler_w(&w) @@ -91,15 +91,15 @@ #define SET_FLAGS8(a,b,r) {SET_N8(r); SET_Z8(r); SET_C8(r);} /* for treating an unsigned uint8_t as a signed int16_t */ -#define SIGNED(b) ((int16_t)(b & 0x80 ? b | 0xff00 : b)) +#define SIGNED(b) (int16_t(b & 0x80 ? b | 0xff00 : b)) /* Macros for addressing modes */ -#define DIRECT EAD=0; IMMBYTE(m_ea.b.l) -#define IMM8 EA = PC++ +#define DIRECT do { EAD=0; IMMBYTE(m_ea.b.l); } while (false) +#define IMM8 do { EA = PC++; } while (false) #define EXTENDED IMMWORD(m_ea) -#define INDEXED EA = X -#define INDEXED1 {EAD = 0; IMMBYTE(m_ea.b.l); EA += X;} -#define INDEXED2 {IMMWORD(m_ea); EA += X;} +#define INDEXED do { EA = X; } while (false) +#define INDEXED1 do { EAD = 0; IMMBYTE(m_ea.b.l); EA += X; } while (false) +#define INDEXED2 do { IMMWORD(m_ea); EA += X;} while (false) /* macros to set status flags */ #if defined(SEC) @@ -117,13 +117,32 @@ #define CLI CC &=~ IFLAG /* macros for convenience */ -#define DIRBYTE(b) {DIRECT; b = RM(EAD);} -#define EXTBYTE(b) {EXTENDED; b = RM(EAD);} -#define IDXBYTE(b) {INDEXED; b = RM(EAD);} -#define IDX1BYTE(b) {INDEXED1; b = RM(EAD);} -#define IDX2BYTE(b) {INDEXED2; b = RM(EAD);} +#define ARGADDR \ + do { switch (M) { \ + case addr_mode::IM: static_assert(addr_mode::IM != M, "invalid mode for this instruction"); break; \ + case addr_mode::DI: DIRECT; break; \ + case addr_mode::EX: EXTENDED; break; \ + case addr_mode::IX: INDEXED; break; \ + case addr_mode::IX1: INDEXED1; break; \ + case addr_mode::IX2: INDEXED2; break; \ + } } while (false) +#define DIRBYTE(b) do { DIRECT; b = RM(EAD); } while (false) +#define EXTBYTE(b) do { EXTENDED; b = RM(EAD); } while (false) +#define IDXBYTE(b) do { INDEXED; b = RM(EAD); } while (false) +#define IDX1BYTE(b) do { INDEXED1; b = RM(EAD); } while (false) +#define IDX2BYTE(b) do { INDEXED2; b = RM(EAD); } while (false) +#define ARGBYTE(b) \ + do { switch (M) { \ + case addr_mode::IM: IMMBYTE(b); break; \ + case addr_mode::DI: DIRBYTE(b); break; \ + case addr_mode::EX: EXTBYTE(b); break; \ + case addr_mode::IX: IDXBYTE(b); break; \ + case addr_mode::IX1: IDX1BYTE(b); break; \ + case addr_mode::IX2: IDX2BYTE(b); break; \ + } } while (false) + /* Macros for branch instructions */ -#define BRANCH(f) { uint8_t t; IMMBYTE(t); if(f) { PC += SIGNED(t); } } +#define BRANCH(f) do { uint8_t t; IMMBYTE(t); if (bool(f) == bool(C)) PC += SIGNED(t); } while (false) /* pre-clear a PAIR union; clearing h2 and h3 only might be faster? */ #define CLEAR_PAIR(p) p->d = 0 diff --git a/src/devices/cpu/m6805/m68705.cpp b/src/devices/cpu/m6805/m68705.cpp index b678954e386..5a2d666ea7a 100644 --- a/src/devices/cpu/m6805/m68705.cpp +++ b/src/devices/cpu/m6805/m68705.cpp @@ -2,6 +2,25 @@ #include "m68705.h" #include "m6805defs.h" +/**************************************************************************** + * Configurable logging + ****************************************************************************/ + +#define LOG_INT (1U << 1) +#define LOG_IOPORT (1U << 2) +#define LOG_TIMER (1U << 3) +#define LOG_EPROM (1U << 4) + +//#define VERBOSE (LOG_GENERAL | LOG_IOPORT | LOG_TIMER | LOG_EPROM) +//#define LOG_OUTPUT_FUNC printf +#include "logmacro.h" + +#define LOGINT(...) LOGMASKED(LOG_INT, __VA_ARGS__) +#define LOGIOPORT(...) LOGMASKED(LOG_IOPORT, __VA_ARGS__) +#define LOGTIMER(...) LOGMASKED(LOG_TIMER, __VA_ARGS__) +#define LOGEPROM(...) LOGMASKED(LOG_EPROM, __VA_ARGS__) + + namespace { std::pair<u16, char const *> const m68705p_syms[] = { @@ -52,7 +71,10 @@ ROM_END } // anonymous namespace -device_type const M68705 = &device_creator<m68705_device>; +/**************************************************************************** + * Global variables + ****************************************************************************/ + device_type const M68705P3 = &device_creator<m68705p3_device>; device_type const M68705P5 = &device_creator<m68705p5_device>; device_type const M68705R3 = &device_creator<m68705r3_device>; @@ -60,79 +82,7 @@ device_type const M68705U3 = &device_creator<m68705u3_device>; /**************************************************************************** - * M68705 device (no peripherals) - ****************************************************************************/ - -m68705_device::m68705_device(machine_config const &mconfig, char const *tag, device_t *owner, u32 clock) - : m6805_base_device(mconfig, tag, owner, clock, M68705, "M68705", 12, "m68705", __FILE__) -{ -} - -m68705_device::m68705_device( - machine_config const &mconfig, - char const *tag, - device_t *owner, - u32 clock, - device_type type, - char const *name, - u32 addr_width, - address_map_delegate internal_map, - char const *shortname, - char const *source) - : m6805_base_device(mconfig, tag, owner, clock, type, name, addr_width, internal_map, shortname, source) -{ -} - -/* Generate interrupt - m68705 version */ -void m68705_device::interrupt() -{ - if ((m_pending_interrupts & ((1 << M6805_IRQ_LINE) | M68705_INT_MASK)) != 0 ) - { - if ((CC & IFLAG) == 0) - { - PUSHWORD(m_pc); - PUSHBYTE(m_x); - PUSHBYTE(m_a); - PUSHBYTE(m_cc); - SEI; - standard_irq_callback(0); - - if ((m_pending_interrupts & (1 << M68705_IRQ_LINE)) != 0 ) - { - m_pending_interrupts &= ~(1 << M68705_IRQ_LINE); - RM16(0xfffa, &m_pc); - } - else if ((m_pending_interrupts & (1 << M68705_INT_TIMER)) != 0) - { - m_pending_interrupts &= ~(1 << M68705_INT_TIMER); - RM16(0xfff8, &m_pc); - } - } - m_icount -= 11; - } -} - -void m68705_device::device_reset() -{ - m6805_base_device::device_reset(); - - RM16(0xfffe, &m_pc); -} - -void m68705_device::execute_set_input(int inputnum, int state) -{ - if (m_irq_state[inputnum] != state) - { - m_irq_state[inputnum] = (state == ASSERT_LINE) ? ASSERT_LINE : CLEAR_LINE; - - if (state != CLEAR_LINE) - m_pending_interrupts |= 1 << inputnum; - } -} - - -/**************************************************************************** - * M68705 "new" device + * MC68705 base device ****************************************************************************/ /* @@ -223,7 +173,7 @@ Ux Parts: */ -m68705_new_device::m68705_new_device( +m68705_device::m68705_device( machine_config const &mconfig, char const *tag, device_t *owner, @@ -234,7 +184,7 @@ m68705_new_device::m68705_new_device( address_map_delegate internal_map, char const *shortname, char const *source) - : m68705_device(mconfig, tag, owner, clock, type, name, addr_width, internal_map, shortname, source) + : m6805_base_device(mconfig, tag, owner, clock, type, name, addr_width, internal_map, shortname, source) , device_nvram_interface(mconfig, *this) , m_user_rom(*this, DEVICE_SELF, u32(1) << addr_width) , m_port_open_drain{ false, false, false, false } @@ -254,14 +204,20 @@ m68705_new_device::m68705_new_device( { } -template <offs_t B> READ8_MEMBER(m68705_new_device::eprom_r) +template <offs_t B> READ8_MEMBER(m68705_device::eprom_r) { + if (pcr_vpon() && !pcr_ple()) + LOGEPROM("read EPROM %04X prevented when Vpp high and /PLE = 0\n", B + offset); + // read locked out when /VPON and /PLE are asserted return (!pcr_vpon() || !pcr_ple()) ? m_user_rom[B + offset] : 0xff; } -template <offs_t B> WRITE8_MEMBER(m68705_new_device::eprom_w) +template <offs_t B> WRITE8_MEMBER(m68705_device::eprom_w) { + LOGEPROM("EPROM programming latch write%s%s: %04X = %02\n", + !pcr_vpon() ? " [Vpp low]" : "", !pcr_ple() ? " [disabled]" : "", B + offset, data); + // programming latch enabled when /VPON and /PLE are asserted if (pcr_vpon() && pcr_ple()) { @@ -278,65 +234,80 @@ template <offs_t B> WRITE8_MEMBER(m68705_new_device::eprom_w) } } -template <std::size_t N> void m68705_new_device::set_port_open_drain(bool value) +template <std::size_t N> void m68705_device::set_port_open_drain(bool value) { m_port_open_drain[N] = value; } -template <std::size_t N> void m68705_new_device::set_port_mask(u8 mask) +template <std::size_t N> void m68705_device::set_port_mask(u8 mask) { + if (configured() || started()) + throw emu_fatalerror("Attempt to set physical port mask after configuration"); m_port_mask[N] = mask; } -template <std::size_t N> READ8_MEMBER(m68705_new_device::port_r) +template <std::size_t N> READ8_MEMBER(m68705_device::port_r) { - if (!m_port_cb_r[N].isnull()) m_port_input[N] = m_port_cb_r[N](space, 0, ~m_port_ddr[N]); + if (!m_port_cb_r[N].isnull()) + { + u8 const newval(m_port_cb_r[N](space, 0, ~m_port_ddr[N] & ~m_port_mask[N]) & ~m_port_mask[N]); + if (newval != m_port_input[N]) + { + LOGIOPORT("read PORT%c: new input = %02X & %02X (was %02x)\n", + char('A' + N), newval, ~m_port_ddr[N] & ~m_port_mask[N], m_port_input[N]); + } + m_port_input[N] = newval; + } return m_port_mask[N] | (m_port_latch[N] & m_port_ddr[N]) | (m_port_input[N] & ~m_port_ddr[N]); } -template <std::size_t N> WRITE8_MEMBER(m68705_new_device::port_latch_w) +template <std::size_t N> WRITE8_MEMBER(m68705_device::port_latch_w) { data &= ~m_port_mask[N]; u8 const diff = m_port_latch[N] ^ data; + if (diff) + LOGIOPORT("write PORT%c latch: %02X & %02X (was %02x)\n", char('A' + N), data, m_port_ddr[N], m_port_latch[N]); m_port_latch[N] = data; if (diff & m_port_ddr[N]) port_cb_w<N>(); } -template <std::size_t N> WRITE8_MEMBER(m68705_new_device::port_ddr_w) +template <std::size_t N> WRITE8_MEMBER(m68705_device::port_ddr_w) { data &= ~m_port_mask[N]; if (data != m_port_ddr[N]) { + LOGIOPORT("write DDR%c: %02X (was %02x)\n", char('A' + N), data, m_port_ddr[N]); m_port_ddr[N] = data; port_cb_w<N>(); } } -template <std::size_t N> void m68705_new_device::port_cb_w() +template <std::size_t N> void m68705_device::port_cb_w() { u8 const data(m_port_open_drain[N] ? m_port_latch[N] | ~m_port_ddr[N] : m_port_latch[N]); u8 const mask(m_port_open_drain[N] ? (~m_port_latch[N] & m_port_ddr[N]) : m_port_ddr[N]); m_port_cb_w[N](space(AS_PROGRAM), 0, data, mask); } -READ8_MEMBER(m68705_new_device::tdr_r) +READ8_MEMBER(m68705_device::tdr_r) { return m_tdr; } -WRITE8_MEMBER(m68705_new_device::tdr_w) +WRITE8_MEMBER(m68705_device::tdr_w) { + LOGTIMER("write TDR: %02X * (1 << %u)\n", data, tcr_ps()); m_tdr = data; } -READ8_MEMBER(m68705_new_device::tcr_r) +READ8_MEMBER(m68705_device::tcr_r) { // in MOR controlled mode, only TIR, TIM and TOPT are visible return m_tcr | (tcr_topt() ? 0x37 : 0x00); } -WRITE8_MEMBER(m68705_new_device::tcr_w) +WRITE8_MEMBER(m68705_device::tcr_w) { // 7 TIR RW Timer Interrupt Request Status // 6 TIM RW Timer Interrupt Mask @@ -363,39 +334,42 @@ WRITE8_MEMBER(m68705_new_device::tcr_w) if (tcr_topt()) { - m_tcr = (m_tcr & 0x3f) | (data & 0xc0); + LOGTIMER("write TCR: TIR=%u (%s) TIM=%u\n", + BIT(data, 7), (tcr_tir() && !BIT(data, 7)) ? "cleared" : "unaffected", BIT(data, 6)); + m_tcr = (m_tcr & ((data & 0x80) | 0x3f)) | (data & 0x40); } else { + LOGTIMER("write TCR: TIR=%u (%s) TIM=%u TIN=%u TIE=%u PSC=%u PS=(1 << %u)\n", + BIT(data, 7), (tcr_tir() && !BIT(data, 7)) ? "cleared" : "unaffected", BIT(data, 6), + BIT(data, 5), BIT(data, 4), + BIT(data, 3), data & 0x07); if (BIT(data, 3)) m_prescaler = 0; - m_tcr = (m_tcr & 0x08) | (data & 0xf7); + m_tcr = (m_tcr & ((data & 0x80) | 0x08)) | (data & 0x77); } - // TODO: this is tied up with /INT2 on R/U devices - if (tcr_tir() && !tcr_tim()) - set_input_line(M68705_INT_TIMER, ASSERT_LINE); - else - set_input_line(M68705_INT_TIMER, CLEAR_LINE); + // this is a level-sensitive interrupt (unlike the edge-triggered inputs) + execute_set_input(M68705_INT_TIMER, (tcr_tir() && !tcr_tim()) ? ASSERT_LINE : CLEAR_LINE); } -READ8_MEMBER(m68705_new_device::misc_r) +READ8_MEMBER(m68705_device::misc_r) { logerror("unsupported read MISC\n"); return 0xff; } -WRITE8_MEMBER(m68705_new_device::misc_w) +WRITE8_MEMBER(m68705_device::misc_w) { logerror("unsupported write MISC = %02X\n", data); } -READ8_MEMBER(m68705_new_device::pcr_r) +READ8_MEMBER(m68705_device::pcr_r) { return m_pcr; } -WRITE8_MEMBER(m68705_new_device::pcr_w) +WRITE8_MEMBER(m68705_device::pcr_w) { // 7 1 // 6 1 @@ -406,23 +380,30 @@ WRITE8_MEMBER(m68705_new_device::pcr_w) // 1 /PGE RW Program Enable // 0 /PLE RW Programming Latch Enable + LOGEPROM("write PCR: /PGE=%u%s /PLE=%u\n", BIT(data, 1), BIT(data, 0) ? " [inhibited]" : "", BIT(data, 0)); + // lock out /PGE if /PLE is not asserted data |= ((data & 0x01) << 1); // write EPROM if /PGE is asserted (erase requires UV so don't clear bits) - if (pcr_vpon() && !pcr_pge() && !BIT(data, 1)) - m_user_rom[m_pl_addr] |= m_pl_data; + if (!pcr_pge() && !BIT(data, 1)) + { + LOGEPROM("write EPROM%s: %04X = %02X | %02X\n", + pcr_vpon() ? "" : " prevented when Vpp low", m_pl_addr, m_pl_data, m_user_rom[m_pl_addr]); + if (pcr_vpon()) + m_user_rom[m_pl_addr] |= m_pl_data; + } m_pcr = (m_pcr & 0xfc) | (data & 0x03); } -READ8_MEMBER(m68705_new_device::acr_r) +READ8_MEMBER(m68705_device::acr_r) { logerror("unsupported read ACR\n"); return 0xff; } -WRITE8_MEMBER(m68705_new_device::acr_w) +WRITE8_MEMBER(m68705_device::acr_w) { // 7 conversion complete // 6 @@ -450,20 +431,20 @@ WRITE8_MEMBER(m68705_new_device::acr_w) logerror("unsupported write ACR = %02X\n", data); } -READ8_MEMBER(m68705_new_device::arr_r) +READ8_MEMBER(m68705_device::arr_r) { logerror("unsupported read ARR\n"); return 0xff; } -WRITE8_MEMBER(m68705_new_device::arr_w) +WRITE8_MEMBER(m68705_device::arr_w) { logerror("unsupported write ARR = %02X\n", data); } -void m68705_new_device::device_start() +void m68705_device::device_start() { - m68705_device::device_start(); + m6805_base_device::device_start(); save_item(NAME(m_port_input)); save_item(NAME(m_port_latch)); @@ -496,9 +477,9 @@ void m68705_new_device::device_start() m_pl_addr = 0xffff; } -void m68705_new_device::device_reset() +void m68705_device::device_reset() { - m68705_device::device_reset(); + m6805_base_device::device_reset(); // reset digital I/O port_ddr_w<0>(space(AS_PROGRAM), 0, 0x00, 0xff); @@ -516,10 +497,13 @@ void m68705_new_device::device_reset() m_pcr |= 0xfb; // b2 (/VPON) is driven by external input and hence unaffected by reset if (CLEAR_LINE != m_vihtp) + { + LOG("loading bootstrap vector\n"); RM16(0xfff6, &m_pc); + } } -void m68705_new_device::execute_set_input(int inputnum, int state) +void m68705_device::execute_set_input(int inputnum, int state) { switch (inputnum) { @@ -531,25 +515,67 @@ void m68705_new_device::execute_set_input(int inputnum, int state) m_vihtp = (ASSERT_LINE == state) ? ASSERT_LINE : CLEAR_LINE; break; default: - m68705_device::execute_set_input(inputnum, state); + if (m_irq_state[inputnum] != state) + { + m_irq_state[inputnum] = (state == ASSERT_LINE) ? ASSERT_LINE : CLEAR_LINE; + + if (state != CLEAR_LINE) + m_pending_interrupts |= 1 << inputnum; + else if (M68705_INT_TIMER == inputnum) + m_pending_interrupts &= ~(1 << inputnum); // this one's is level-sensitive + } } } -void m68705_new_device::nvram_default() +void m68705_device::nvram_default() { } -void m68705_new_device::nvram_read(emu_file &file) +void m68705_device::nvram_read(emu_file &file) { file.read(&m_user_rom[0], m_user_rom.bytes()); } -void m68705_new_device::nvram_write(emu_file &file) +void m68705_device::nvram_write(emu_file &file) { file.write(&m_user_rom[0], m_user_rom.bytes()); } -void m68705_new_device::burn_cycles(unsigned count) +void m68705_device::interrupt() +{ + if (m_pending_interrupts & M68705_INT_MASK) + { + if ((CC & IFLAG) == 0) + { + PUSHWORD(m_pc); + PUSHBYTE(m_x); + PUSHBYTE(m_a); + PUSHBYTE(m_cc); + SEI; + standard_irq_callback(0); + + if (BIT(m_pending_interrupts, M68705_IRQ_LINE)) + { + LOGINT("servicing /INT interrupt\n"); + m_pending_interrupts &= ~(1 << M68705_IRQ_LINE); + RM16(0xfffa, &m_pc); + } + else if (BIT(m_pending_interrupts, M68705_INT_TIMER)) + { + LOGINT("servicing timer/counter interrupt\n"); + RM16(0xfff8, &m_pc); + } + else + { + throw emu_fatalerror("Unknown pending interrupt"); + } + } + m_icount -= 11; + burn_cycles(11); + } +} + +void m68705_device::burn_cycles(unsigned count) { // handle internal timer/counter source if (!tcr_tin()) // TODO: check tcr_tie() and gate on TIMER if appropriate @@ -560,6 +586,7 @@ void m68705_new_device::burn_cycles(unsigned count) if (decrements && (decrements >= m_tdr)) { + LOGTIMER("timer/counter expired%s%s\n", tcr_tir() ? " [overrun]" : "", tcr_tim() ? " [masked]" : ""); m_tcr |= 0x80; if (!tcr_tim()) set_input_line(M68705_INT_TIMER, ASSERT_LINE); @@ -569,6 +596,30 @@ void m68705_new_device::burn_cycles(unsigned count) } } +template <std::size_t N> void m68705_device::add_port_latch_state() +{ + state_add(M68705_LATCHA + N, util::string_format("LATCH%c", 'A' + N).c_str(), m_port_latch[N]).mask(~m_port_mask[N] & 0xff); +} + +template <std::size_t N> void m68705_device::add_port_ddr_state() +{ + state_add(M68705_DDRA + N, util::string_format("DDR%c", 'A' + N).c_str(), m_port_ddr[N]).mask(~m_port_mask[N] & 0xff); +} + +void m68705_device::add_timer_state() +{ + state_add(M68705_PS, "PS", m_prescaler).mask(0x7f); + state_add(M68705_TDR, "TDR", m_tdr).mask(0xff); + state_add(M68705_TCR, "TCR", m_tcr).mask(0xff); +} + +void m68705_device::add_eprom_state() +{ + state_add(M68705_PCR, "PCR", m_pcr).mask(0xff); + state_add(M68705_PLA, "PLA", m_pl_addr).mask(0xffff); + state_add(M68705_PLD, "PLD", m_pl_data).mask(0xff); +} + /**************************************************************************** * M68705Px family @@ -606,13 +657,28 @@ m68705p_device::m68705p_device( char const *name, char const *shortname, char const *source) - : m68705_new_device(mconfig, tag, owner, clock, type, name, 11, address_map_delegate(FUNC(m68705p_device::p_map), this), shortname, source) + : m68705_device(mconfig, tag, owner, clock, type, name, 11, address_map_delegate(FUNC(m68705p_device::p_map), this), shortname, source) { set_port_open_drain<0>(true); // Port A is open drain with internal pull-ups set_port_mask<2>(0xf0); // Port C is four bits wide set_port_mask<3>(0xff); // Port D isn't present } +void m68705p_device::device_start() +{ + m68705_device::device_start(); + + add_port_latch_state<0>(); + add_port_latch_state<1>(); + add_port_latch_state<2>(); + add_port_ddr_state<0>(); + add_port_ddr_state<1>(); + add_port_ddr_state<2>(); + add_timer_state(); + add_eprom_state(); + state_add(M68705_MOR, "MOR", get_user_rom()[0x0784]).mask(0xff); +} + offs_t m68705p_device::disasm_disassemble( std::ostream &stream, offs_t pc, @@ -662,7 +728,7 @@ m68705u_device::m68705u_device( address_map_delegate internal_map, char const *shortname, char const *source) - : m68705_new_device(mconfig, tag, owner, clock, type, name, 12, internal_map, shortname, source) + : m68705_device(mconfig, tag, owner, clock, type, name, 12, internal_map, shortname, source) { set_port_open_drain<0>(true); // Port A is open drain with internal pull-ups } @@ -680,6 +746,24 @@ m68705u_device::m68705u_device( { } +void m68705u_device::device_start() +{ + m68705_device::device_start(); + + add_port_latch_state<0>(); + add_port_latch_state<1>(); + add_port_latch_state<2>(); + add_port_latch_state<3>(); + add_port_ddr_state<0>(); + add_port_ddr_state<1>(); + add_port_ddr_state<2>(); + add_timer_state(); + add_eprom_state(); + state_add(M68705_MOR, "MOR", get_user_rom()[0x0f38]).mask(0xff); + + // TODO: MISC register +} + offs_t m68705u_device::disasm_disassemble( std::ostream &stream, offs_t pc, @@ -734,6 +818,13 @@ m68705r_device::m68705r_device( { } +void m68705r_device::device_start() +{ + m68705u_device::device_start(); + + // TODO: ADC +} + offs_t m68705r_device::disasm_disassemble( std::ostream &stream, offs_t pc, @@ -801,7 +892,7 @@ tiny_rom_entry const *m68705r3_device::device_rom_region() const u8 m68705r3_device::get_mask_options() const { - return get_user_rom()[0x0784] & 0xf7; // no SNM bit + return get_user_rom()[0x0f38] & 0xf7; // no SNM bit } @@ -821,5 +912,5 @@ tiny_rom_entry const *m68705u3_device::device_rom_region() const u8 m68705u3_device::get_mask_options() const { - return get_user_rom()[0x0784] & 0xf7; // no SNM bit + return get_user_rom()[0x0f38] & 0xf7; // no SNM bit } diff --git a/src/devices/cpu/m6805/m68705.h b/src/devices/cpu/m6805/m68705.h index e89517e5735..0f7896c8d19 100644 --- a/src/devices/cpu/m6805/m68705.h +++ b/src/devices/cpu/m6805/m68705.h @@ -7,11 +7,11 @@ #include "m6805.h" + //************************************************************************** // GLOBAL VARIABLES //************************************************************************** -extern device_type const M68705; extern device_type const M68705P3; extern device_type const M68705P5; extern device_type const M68705R3; @@ -24,80 +24,73 @@ extern device_type const M68705U3; // ======================> m68705_device -class m68705_device : public m6805_base_device -{ -public: - m68705_device(machine_config const &mconfig, char const *tag, device_t *owner, u32 clock); - -protected: - enum - { - M68705_A = M6805_A, - M68705_PC = M6805_PC, - M68705_S = M6805_S, - M68705_X = M6805_X, - M68705_CC = M6805_CC, - M68705_IRQ_STATE = M6805_IRQ_STATE - }; - - m68705_device( - machine_config const &mconfig, - char const *tag, - device_t *owner, - u32 clock, - device_type type, - char const *name, - u32 addr_width, - address_map_delegate internal_map, - char const *shortname, - char const *source); - - virtual void device_reset() override; - virtual void execute_set_input(int inputnum, int state) override; - virtual void interrupt() override; -}; - - -// ======================> m68705_new_device - #define MCFG_M68705_PORTA_R_CB(obj) \ - devcb = &m68705_new_device::set_port_cb_r<0>(*device, DEVCB_##obj); + devcb = &m68705_device::set_port_cb_r<0>(*device, DEVCB_##obj); #define MCFG_M68705_PORTB_R_CB(obj) \ - devcb = &m68705_new_device::set_port_cb_r<1>(*device, DEVCB_##obj); + devcb = &m68705_device::set_port_cb_r<1>(*device, DEVCB_##obj); #define MCFG_M68705_PORTC_R_CB(obj) \ - devcb = &m68705_new_device::set_port_cb_r<2>(*device, DEVCB_##obj); + devcb = &m68705_device::set_port_cb_r<2>(*device, DEVCB_##obj); #define MCFG_M68705_PORTD_R_CB(obj) \ - devcb = &m68705_new_device::set_port_cb_r<3>(*device, DEVCB_##obj); + devcb = &m68705_device::set_port_cb_r<3>(*device, DEVCB_##obj); #define MCFG_M68705_PORTA_W_CB(obj) \ - devcb = &m68705_new_device::set_port_cb_w<0>(*device, DEVCB_##obj); + devcb = &m68705_device::set_port_cb_w<0>(*device, DEVCB_##obj); #define MCFG_M68705_PORTB_W_CB(obj) \ - devcb = &m68705_new_device::set_port_cb_w<1>(*device, DEVCB_##obj); + devcb = &m68705_device::set_port_cb_w<1>(*device, DEVCB_##obj); #define MCFG_M68705_PORTC_W_CB(obj) \ - devcb = &m68705_new_device::set_port_cb_w<2>(*device, DEVCB_##obj); + devcb = &m68705_device::set_port_cb_w<2>(*device, DEVCB_##obj); -class m68705_new_device : public m68705_device, public device_nvram_interface +class m68705_device : public m6805_base_device, public device_nvram_interface { public: // static configuration helpers template<std::size_t N, typename Object> static devcb_base &set_port_cb_r(device_t &device, Object &&obj) - { return downcast<m68705_new_device &>(device).m_port_cb_r[N].set_callback(std::forward<Object>(obj)); } + { return downcast<m68705_device &>(device).m_port_cb_r[N].set_callback(std::forward<Object>(obj)); } template<std::size_t N, typename Object> static devcb_base &set_port_cb_w(device_t &device, Object &&obj) - { return downcast<m68705_new_device &>(device).m_port_cb_w[N].set_callback(std::forward<Object>(obj)); } + { return downcast<m68705_device &>(device).m_port_cb_w[N].set_callback(std::forward<Object>(obj)); } protected: enum { + M68705_A = M6805_A, + M68705_PC = M6805_PC, + M68705_S = M6805_S, + M68705_X = M6805_X, + M68705_CC = M6805_CC, + M68705_IRQ_STATE = M6805_IRQ_STATE, + + M68705_LATCHA = 0x10, + M68705_LATCHB, + M68705_LATCHC, + M68705_LATCHD, + M68705_DDRA, + M68705_DDRB, + M68705_DDRC, + M68705_DDRD, + + M68705_PS, + M68705_TDR, + M68705_TCR, + + M68705_PCR, + M68705_PLD, + M68705_PLA, + + M68705_MOR + }; + + enum + { PORT_COUNT = 4 }; - m68705_new_device( + m68705_device( machine_config const &mconfig, char const *tag, device_t *owner, @@ -143,11 +136,17 @@ protected: virtual void nvram_read(emu_file &file) override; virtual void nvram_write(emu_file &file) override; + virtual void interrupt() override; virtual void burn_cycles(unsigned count) override; u8 *const get_user_rom() const { return &m_user_rom[0]; } virtual u8 get_mask_options() const = 0; + template <std::size_t N> void add_port_latch_state(); + template <std::size_t N> void add_port_ddr_state(); + void add_timer_state(); + void add_eprom_state(); + private: bool tcr_tir() const { return BIT(m_tcr, 7); } bool tcr_tim() const { return BIT(m_tcr, 6); } @@ -186,7 +185,7 @@ private: // ======================> m68705p_device -class m68705p_device : public m68705_new_device +class m68705p_device : public m68705_device { public: DECLARE_WRITE8_MEMBER(pa_w) { port_input_w<0>(space, offset, data, mem_mask); } @@ -206,6 +205,8 @@ protected: char const *shortname, char const *source); + virtual void device_start() override; + virtual offs_t disasm_disassemble( std::ostream &stream, offs_t pc, @@ -217,7 +218,7 @@ protected: // ======================> m68705u_device -class m68705u_device : public m68705_new_device +class m68705u_device : public m68705_device { public: DECLARE_WRITE8_MEMBER(pa_w) { port_input_w<0>(space, offset, data, mem_mask); } @@ -248,6 +249,8 @@ protected: char const *shortname, char const *source); + virtual void device_start() override; + virtual offs_t disasm_disassemble( std::ostream &stream, offs_t pc, @@ -277,6 +280,8 @@ protected: char const *shortname, char const *source); + virtual void device_start() override; + virtual offs_t disasm_disassemble( std::ostream &stream, offs_t pc, diff --git a/src/devices/machine/68230pit.cpp b/src/devices/machine/68230pit.cpp index 2e03051727a..9f7f71e6028 100644 --- a/src/devices/machine/68230pit.cpp +++ b/src/devices/machine/68230pit.cpp @@ -31,7 +31,7 @@ #define LOG_DR 0x20 #define LOG_INT 0x40 -#define VERBOSE 0 // (LOG_PRINTF | LOG_SETUP | LOG_GENERAL | LOG_INT | LOG_BIT | LOG_DR) +#define VERBOSE 0 //(LOG_PRINTF | LOG_SETUP | LOG_GENERAL | LOG_INT | LOG_BIT | LOG_DR) #define LOGMASK(mask, ...) do { if (VERBOSE & mask) logerror(__VA_ARGS__); } while (0) #define LOGLEVEL(mask, level, ...) do { if ((VERBOSE & mask) >= level) logerror(__VA_ARGS__); } while (0) @@ -142,19 +142,30 @@ pit68230_device::pit68230_device(const machine_config &mconfig, const char *tag, //------------------------------------------------- void pit68230_device::device_start () { - LOG("%s\n", FUNCNAME); + LOGSETUP("%s\n", FUNCNAME); - // resolve callbacks + // NOTE: + // Not using resolve_safe for the m_px_in_cb's is a temporary way to be able to check + // if a handler is installed with isnull(). The safe function installs a dummy default + // handler which disable the isnull() test. TODO: Need a better fix? + + // resolve callbacks Port A m_pa_out_cb.resolve_safe(); m_pa_in_cb.resolve(); + + // resolve callbacks Port B m_pb_out_cb.resolve_safe(); m_pb_in_cb.resolve(); + + // resolve callbacks Port C m_pc_out_cb.resolve_safe(); - m_pc_in_cb.resolve(); // A temporary way to check if handler is installed with isnull(). TODO: Need better fix. + m_pc_in_cb.resolve(); + m_h1_out_cb.resolve_safe(); m_h2_out_cb.resolve_safe(); m_h3_out_cb.resolve_safe(); m_h4_out_cb.resolve_safe(); + m_tirq_out_cb.resolve_safe(); m_pirq_out_cb.resolve_safe(); @@ -186,7 +197,7 @@ void pit68230_device::device_start () //------------------------------------------------- void pit68230_device::device_reset () { - LOG("%s %s \n",tag(), FUNCNAME); + LOGSETUP("%s %s \n",tag(), FUNCNAME); m_pgcr = 0; m_psrr = 0; @@ -203,6 +214,7 @@ void pit68230_device::device_reset () m_tcr = 0; m_tivr = 0x0f; m_tirq_out_cb(CLEAR_LINE); m_tsr = 0; + LOGSETUP("%s %s DONE!\n",tag(), FUNCNAME); } /* @@ -280,9 +292,60 @@ void pit68230_device::device_timer (emu_timer &timer, device_timer_id id, int32_ } } -void pit68230_device::h1_set (uint8_t state) +WRITE_LINE_MEMBER( pit68230_device::h1_w ) +{ + LOGBIT("%s %s H1 set to %d\n", tag(), FUNCNAME, state); + + // Set the direct level in PSR + m_psr = ((state == 0) ? (m_psr & ~REG_PSR_H1L) : (m_psr | REG_PSR_H1L)); + + // Set the programmed assert level in PSR + if (m_pgcr & REG_PGCR_H1_SENSE) + m_psr = ((state != 0) ? (m_psr & ~REG_PSR_H1S) : (m_psr | REG_PSR_H1S)); + else + m_psr = ((state == 0) ? (m_psr & ~REG_PSR_H1S) : (m_psr | REG_PSR_H1S)); +} + +WRITE_LINE_MEMBER( pit68230_device::h2_w ) { - if (state) m_psr |= 1; else m_psr &= ~1; + LOGBIT("%s %s H2 set to %d\n", tag(), FUNCNAME, state); + + // Set the direct level in PSR + m_psr = ((state == 0) ? (m_psr & ~REG_PSR_H2L) : (m_psr | REG_PSR_H2L)); + + // Set the programmed assert level in PSR + if (m_pgcr & REG_PGCR_H2_SENSE) + m_psr = ((state != 0) ? (m_psr & ~REG_PSR_H2S) : (m_psr | REG_PSR_H2S)); + else + m_psr = ((state == 0) ? (m_psr & ~REG_PSR_H2S) : (m_psr | REG_PSR_H2S)); +} + +WRITE_LINE_MEMBER( pit68230_device::h3_w ) +{ + LOGBIT("%s %s H3 set to %d\n", tag(), FUNCNAME, state); + + // Set the direct level in PSR + m_psr = ((state == 0) ? (m_psr & ~REG_PSR_H3L) : (m_psr | REG_PSR_H3L)); + + // Set the programmed assert level in PSR + if (m_pgcr & REG_PGCR_H3_SENSE) + m_psr = ((state != 0) ? (m_psr & ~REG_PSR_H3S) : (m_psr | REG_PSR_H3S)); + else + m_psr = ((state == 0) ? (m_psr & ~REG_PSR_H3S) : (m_psr | REG_PSR_H3S)); +} + +WRITE_LINE_MEMBER( pit68230_device::h4_w ) +{ + LOGBIT("%s %s H4 set to %d\n", tag(), FUNCNAME, state); + + // Set the direct level in PSR + m_psr = ((state == 0) ? (m_psr & ~REG_PSR_H4L) : (m_psr | REG_PSR_H4L)); + + // Set the programmed assert level in PSR + if (m_pgcr & REG_PGCR_H4_SENSE) + m_psr = ((state != 0) ? (m_psr & ~REG_PSR_H4S) : (m_psr | REG_PSR_H4S)); + else + m_psr = ((state == 0) ? (m_psr & ~REG_PSR_H4S) : (m_psr | REG_PSR_H4S)); } // TODO: remove this method and replace it with a call to pb_update_bit() in force68k.cpp @@ -293,7 +356,7 @@ void pit68230_device::portb_setbit(uint8_t bit, uint8_t state) void pit68230_device::pa_update_bit(uint8_t bit, uint8_t state) { - LOGBIT("%s %s bit %d to %d\n",tag(), FUNCNAME, bit, state); + LOGBIT("%s %s bit %d to %d\n", tag(), FUNCNAME, bit, state); // Check if requested bit is an output bit and can't be affected if (m_paddr & (1 << bit)) { @@ -860,9 +923,8 @@ the instantaneous pin level is read and no input latching is performed except at data bus interface. Writes to this address are answered with DTACK, but the data is ignored.*/ uint8_t pit68230_device::rr_pitreg_paar() { - // NOTE: no side effect emulated so using ..padr uint8_t ret; - ret = m_pa_in_cb(); + ret = m_pa_in_cb.isnull() ? 0 : m_pa_in_cb(); LOGR("%s %s <- %02x\n",tag(), FUNCNAME, ret); return ret; } @@ -873,9 +935,8 @@ the instantaneous pin level is read and no input latching is performed except at data bus interface.Writes to this address are answered with DTACK, but the data is ignored.*/ uint8_t pit68230_device::rr_pitreg_pbar() { - // NOTE: no side effect emulated so using ..pbdr uint8_t ret; - ret = m_pb_in_cb(); + ret = m_pb_in_cb.isnull() ? 0 : m_pb_in_cb(); LOGR("%s %s <- %02x\n",tag(), FUNCNAME, ret); return ret; } diff --git a/src/devices/machine/68230pit.h b/src/devices/machine/68230pit.h index 79c30aa0b2a..396ba854891 100644 --- a/src/devices/machine/68230pit.h +++ b/src/devices/machine/68230pit.h @@ -131,7 +131,8 @@ class pit68230_device : public device_t//, public device_execute_interface DECLARE_WRITE8_MEMBER (write); DECLARE_READ8_MEMBER (read); - void h1_set (uint8_t state); + // TODO: remove these methods and replace it with a call to methods below in force68k.cpp + void h1_set (uint8_t state){ if (state) m_psr |= 1; else m_psr &= ~1; } void portb_setbit (uint8_t bit, uint8_t state); // Bit updaters @@ -140,6 +141,11 @@ class pit68230_device : public device_t//, public device_execute_interface void pc_update_bit(uint8_t bit, uint8_t state); void update_tin(uint8_t); + DECLARE_WRITE_LINE_MEMBER( h1_w ); + DECLARE_WRITE_LINE_MEMBER( h2_w ); + DECLARE_WRITE_LINE_MEMBER( h3_w ); + DECLARE_WRITE_LINE_MEMBER( h4_w ); + DECLARE_WRITE_LINE_MEMBER( pa0_w ){ pa_update_bit(0, state); } DECLARE_WRITE_LINE_MEMBER( pa1_w ){ pa_update_bit(1, state); } DECLARE_WRITE_LINE_MEMBER( pa2_w ){ pa_update_bit(2, state); } @@ -270,6 +276,17 @@ protected: }; enum { + REG_PSR_H1S = 0x01, + REG_PSR_H2S = 0x02, + REG_PSR_H3S = 0x04, + REG_PSR_H4S = 0x08, + REG_PSR_H1L = 0x10, + REG_PSR_H2L = 0x20, + REG_PSR_H3L = 0x40, + REG_PSR_H4L = 0x80, + }; + + enum { REG_TCR_TIMER_ENABLE = 0x01 }; diff --git a/src/devices/machine/68561mpcc.cpp b/src/devices/machine/68561mpcc.cpp index 7ee3880877c..c07216fd640 100644 --- a/src/devices/machine/68561mpcc.cpp +++ b/src/devices/machine/68561mpcc.cpp @@ -1,481 +1,1195 @@ -// license:BSD-3-Clause -// copyright-holders:Sergey Svishchev -/********************************************************************* +// license:BSD-3-Clause copyright-holders: Joakim Larsson Edstrom +/*************************************************************************** - 68561mpcc.c + MPCC Multi-Protocol Communications Controller emulation + + The MPCC was introduced in the late 80:ies by Rockwell + + The variants in the MPCC family are as follows: + + - 68560 with an 8 bit data bus + - 68560A with an 8 bit data bus and some enhancements + - 68561 with a 16 bit data bus + - 68561A with a 16 bit data bus and some enhancements + +FEATURES +------------------------------------------------------------------ + * Full duplex synchronous/asynchronous receiver and transmitter + * Implements IBM Binary Synchronous Communications (BSC) in two coding formats: ASCII and EBCDIC + * Supports other synchronous character -oriented protocols (COP), such as six -bit BSC, X3.28k. ISO IS1745, ECMA-16, etc. + * Supports synchronous bit oriented protocols (BOP), such as SDLC, HDLC, X.25, etc. + * Asynchronous and isochronous modes + * Modem handshake interface + * High speed serial data rate (DC to 4 MHz) + * Internal oscillator and baud rate generator with programmable data rate + * Crystal or TTL level clock input and buffered clock output (8 MHz) + * Direct interface to 68008/68000 asynchronous bus + * Eight -character receiver and transmitter buffer registers + * 22 directly addressable registers for flexible option selection, complete status reporting, and data transfer + * Three separate programmable interrupt vector numbers for receiver, transmitter and serial interface + * Maskable interrupt conditions for receiver, transmitter and serial interface + * Programmable microprocessor bus data transfer; polled, interrupt and two -channel DMA transfer compatible with MC68440/MC68450 + * Clock control register for receiver clock divisor and receiver and transmitter clock routing + * Selectable full/half duplex, autoecho and local loop -back modes + * Selectable parity (enable, odd, even) and CRC (control field enable, CRC -16, CCITT V.41, VRC/LRC) + *------------------------------------------------------------------------------------------- + * x = Features that has been implemented p = partly n = features that will not + *------------------------------------------------------------------------------------------- +*/ - Rockwell 68561 MPCC (Multi Protocol Communications Controller) +#include "emu.h" +#include "68561mpcc.h" - skeleton driver, just enough for besta.c console to work +//************************************************************************** +// MACROS / CONSTANTS +//************************************************************************** +#define LOG_GENERAL 0x001 +#define LOG_SETUP 0x002 +#define LOG_PRINTF 0x004 +#define LOG_READ 0x008 +#define LOG_INT 0x010 +#define LOG_CMD 0x020 +#define LOG_TX 0x040 +#define LOG_RCV 0x080 +#define LOG_CTS 0x100 +#define LOG_DCD 0x200 +#define LOG_SYNC 0x400 +#define LOG_CHAR 0x800 +#define LOG_RX 0x1000 + +#define VERBOSE 0 // (LOG_PRINTF | LOG_SETUP | LOG_GENERAL) + +#define LOGMASK(mask, ...) do { if (VERBOSE & mask) logerror(__VA_ARGS__); } while (0) +#define LOGLEVEL(mask, level, ...) do { if ((VERBOSE & mask) >= level) logerror(__VA_ARGS__); } while (0) + +#define LOG(...) LOGMASK(LOG_GENERAL, __VA_ARGS__) +#define LOGSETUP(...) LOGMASK(LOG_SETUP, __VA_ARGS__) +#define LOGR(...) LOGMASK(LOG_READ, __VA_ARGS__) +#define LOGINT(...) LOGMASK(LOG_INT, __VA_ARGS__) +#define LOGCMD(...) LOGMASK(LOG_CMD, __VA_ARGS__) +#define LOGTX(...) LOGMASK(LOG_TX, __VA_ARGS__) +#define LOGRCV(...) LOGMASK(LOG_RCV, __VA_ARGS__) +#define LOGCTS(...) LOGMASK(LOG_CTS, __VA_ARGS__) +#define LOGDCD(...) LOGMASK(LOG_DCD, __VA_ARGS__) +#define LOGSYNC(...) LOGMASK(LOG_SYNC, __VA_ARGS__) +#define LOGCHAR(...) LOGMASK(LOG_CHAR, __VA_ARGS__) +#define LOGRX(...) LOGMASK(LOG_RX, __VA_ARGS__) + +#if VERBOSE & LOG_PRINTF +#define logerror printf +#endif -*********************************************************************/ +#ifdef _MSC_VER +#define FUNCNAME __func__ +#define LLFORMAT "%I64d" +#else +#define FUNCNAME __PRETTY_FUNCTION__ +#define LLFORMAT "%lld" +#endif +//************************************************************************** +// DEVICE DEFINITIONS +//************************************************************************** +// device type definition +const device_type MPCC = &device_creator<mpcc_device>; +const device_type MPCC68560 = &device_creator<mpcc68560_device>; +const device_type MPCC68560A = &device_creator<mpcc68560A_device>; +const device_type MPCC68561 = &device_creator<mpcc68561_device>; +const device_type MPCC68561A = &device_creator<mpcc68561A_device>; + +//************************************************************************** +// LIVE DEVICE +//************************************************************************** + +mpcc_device::mpcc_device(const machine_config &mconfig, device_type type, const char *name, const char *tag, device_t *owner, uint32_t clock, uint32_t variant, const char *shortname, const char *source) + : device_t(mconfig, type, name, tag, owner, clock, shortname, source), + device_serial_interface(mconfig, *this), + m_variant(variant), + m_rxc(0), + m_txc(0), + m_brg_rate(0), + m_rcv(0), + m_rxd(0), + m_tra(0), + m_out_txd_cb(*this), + m_out_dtr_cb(*this), + m_out_rts_cb(*this), + m_out_rtxc_cb(*this), + m_out_trxc_cb(*this), + m_out_int_cb(*this), + m_rsr(0), + m_rcr(0), + m_rdr(0), + m_rivnr(0), + m_rier(0), + m_tsr(0), + m_tcr(0), + m_tdr(0), + m_tivnr(0), + m_tier(0), + m_sisr(0), + m_sicr(0), + m_sivnr(0), + m_sier(0), + m_psr1(0), + m_psr2(0), + m_ar1(0), + m_ar2(0), + m_brdr1(0), + m_brdr2(0), + m_ccr(0), + m_ecr(0) +{ + for (auto & elem : m_int_state) + elem = 0; +} -#include "emu.h" -#include "68561mpcc.h" +mpcc_device::mpcc_device(const machine_config &mconfig, const char *tag, device_t *owner, uint32_t clock) + : device_t(mconfig, MPCC, "Rockwell MPCC", tag, owner, clock, "mpcc", __FILE__), + device_serial_interface(mconfig, *this), + m_variant(TYPE_MPCC), + m_rxc(0), + m_txc(0), + m_brg_rate(0), + m_rcv(0), + m_rxd(0), + m_tra(0), + m_out_txd_cb(*this), + m_out_dtr_cb(*this), + m_out_rts_cb(*this), + m_out_rtxc_cb(*this), + m_out_trxc_cb(*this), + m_out_int_cb(*this), + m_rsr(0), + m_rcr(0), + m_rdr(0), + m_rivnr(0), + m_rier(0), + m_tsr(0), + m_tcr(0), + m_tdr(0), + m_tivnr(0), + m_tier(0), + m_sisr(0), + m_sicr(0), + m_sivnr(0), + m_sier(0), + m_psr1(0), + m_psr2(0), + m_ar1(0), + m_ar2(0), + m_brdr1(0), + m_brdr2(0), + m_ccr(0), + m_ecr(0) +{ + for (auto & elem : m_int_state) + elem = 0; +} -const device_type MPCC68561 = &device_creator<mpcc68561_t>; +mpcc68560_device::mpcc68560_device(const machine_config &mconfig, const char *tag, device_t *owner, uint32_t clock) + : mpcc_device(mconfig, MPCC68560, "MPCC 68560", tag, owner, clock, TYPE_MPCC68560, "mpcc68560", __FILE__){ } +mpcc68560A_device::mpcc68560A_device(const machine_config &mconfig, const char *tag, device_t *owner, uint32_t clock) + : mpcc_device(mconfig, MPCC68560A, "MPCC 68560A", tag, owner, clock, TYPE_MPCC68560A, "mpcc68560A", __FILE__){ } -/*************************************************************************** - PARAMETERS -***************************************************************************/ +mpcc68561_device::mpcc68561_device(const machine_config &mconfig, const char *tag, device_t *owner, uint32_t clock) + : mpcc_device(mconfig, MPCC68561, "MPCC 68561", tag, owner, clock, TYPE_MPCC68561, "mpcc68561", __FILE__){ } -#define LOG_MPCC (1) +mpcc68561A_device::mpcc68561A_device(const machine_config &mconfig, const char *tag, device_t *owner, uint32_t clock) + : mpcc_device(mconfig, MPCC68561A, "MPCC 68561A", tag, owner, clock, TYPE_MPCC68561A, "mpcc68561A", __FILE__){ } -/*************************************************************************** - IMPLEMENTATION -***************************************************************************/ +//------------------------------------------------- +// device_start - device-specific startup +//------------------------------------------------- +void mpcc_device::device_start() +{ + LOGSETUP("%s\n", FUNCNAME); + + // resolve callbacks + m_out_txd_cb.resolve_safe(); + m_out_dtr_cb.resolve_safe(); + m_out_rts_cb.resolve_safe(); + m_out_rtxc_cb.resolve_safe(); + m_out_trxc_cb.resolve_safe(); + m_out_int_cb.resolve_safe(); + + // state saving + save_item(NAME(m_int_state)); + save_item(NAME(m_rsr)); + save_item(NAME(m_rcr)); + save_item(NAME(m_rdr)); + save_item(NAME(m_rivnr)); + save_item(NAME(m_rier)); + save_item(NAME(m_tsr)); + save_item(NAME(m_tcr)); + save_item(NAME(m_tdr)); + save_item(NAME(m_tivnr)); + save_item(NAME(m_tier)); + save_item(NAME(m_sisr)); + save_item(NAME(m_sicr)); + save_item(NAME(m_sivnr)); + save_item(NAME(m_sier)); + save_item(NAME(m_psr1)); + save_item(NAME(m_psr2)); + save_item(NAME(m_ar1)); + save_item(NAME(m_ar2)); + save_item(NAME(m_brdr1)); + save_item(NAME(m_brdr2)); + save_item(NAME(m_ccr)); + save_item(NAME(m_ecr)); + LOG(" - MPCC variant %02x\n", m_variant); + + device_serial_interface::register_save_state(machine().save(), this); +} -mpcc68561_t::mpcc68561_t(const machine_config &mconfig, const char *tag, device_t *owner, uint32_t clock) : - device_t(mconfig, MPCC68561, "Rockwell 68561 MPCC", tag, owner, clock, "mpcc68561", __FILE__), mode(0), reg(0), status(0), IRQV(0), MasterIRQEnable(0), lastIRQStat(0), IRQType(), - intrq_cb(*this) +//------------------------------------------------- +// device_reset - device-specific reset +//------------------------------------------------- +void mpcc_device::device_reset() { + LOGSETUP("%s %s \n",tag(), FUNCNAME); + + // Reset RS232 emulation + receive_register_reset(); + transmit_register_reset(); + + // Device reset values + m_rsr = 0x00; + m_rcr = 0x01; + m_rivnr = 0x0f; + m_rier = 0x00; + m_tsr = 0x80; + m_tcr = 0x01; + m_tivnr = 0x0f; + m_tier = 0x00; + m_sisr = 0x00; + m_sicr = 0x00; + m_sivnr = 0x0f; + m_sier = 0x00; + m_psr1 = 0x00; + m_psr2 = 0x00; + m_ar1 = 0x00; + m_ar2 = 0x00; + m_brdr1 = 0x01; + m_brdr2 = 0x00; + m_ccr = 0x00; + m_ecr = 0x04; + + // Clear fifos + m_tx_data_fifo.clear(); + m_rx_data_fifo.clear(); + + // Init out callbacks to known inactive state + m_out_txd_cb(1); + m_out_dtr_cb(1); + m_out_rts_cb(1); + m_out_rtxc_cb(1); + m_out_trxc_cb(1); + m_out_int_cb(1); } -/*------------------------------------------------- - mpcc_updateirqs --------------------------------------------------*/ +/* + * Serial device implementation + */ -void mpcc68561_t::updateirqs() +void mpcc_device::device_timer(emu_timer &timer, device_timer_id id, int param, void *ptr) { - int irqstat; + device_serial_interface::device_timer(timer, id, param, ptr); +} - irqstat = 0; - if (MasterIRQEnable) +WRITE_LINE_MEMBER(mpcc_device::cts_w) +{ + if (state == CLEAR_LINE) { - if ((channel[0].txIRQEnable) && (channel[0].txIRQPending)) - { - IRQType = IRQ_B_TX; - irqstat = 1; - } - else if ((channel[1].txIRQEnable) && (channel[1].txIRQPending)) + uint8_t old_sisr = m_sisr; + + m_sisr &= ~REG_SISR_CTSLVL; + if ( (old_sisr & REG_SISR_CTSLVL) && + (m_sicr & REG_SICR_RTSLVL) && + (m_tcr & REG_TCR_TEN)) { - IRQType = IRQ_A_TX; - irqstat = 1; + m_sisr |= REG_SISR_CTST; + if (m_sier & REG_SIER_CTS) + { + // TODO: make sure interrupt is issued with the next negative transition of TxC + trigger_interrupt(INT_SR_CTS); + // TODO: Make sure TxC has negative transition after CTS goes inactive before INT can be reset in SISR7 + } } - else if ((channel[0].extIRQEnable) && (channel[0].extIRQPending)) + } + else + m_sisr |= REG_SISR_CTSLVL; +} + +WRITE_LINE_MEMBER(mpcc_device::dsr_w) +{ + if (state == ASSERT_LINE) + { + uint8_t old_sisr = m_sisr; + + m_sisr |= REG_SISR_DSRLVL; + if ( !(old_sisr & REG_SISR_DSRLVL) && + !(m_rcr & REG_RCR_RRES)) { - IRQType = IRQ_B_EXT; - irqstat = 1; + m_sisr |= REG_SISR_DSRT; + if (m_sier & REG_SIER_DSR) + { + // TODO: make sure interrupt is issued with the next negative transition of RxC + trigger_interrupt(INT_SR_DSR); + // TODO: Make sure RxC has negative transition after DSR goes inactive before INT can be reset in SISR6 + } } - else if ((channel[1].extIRQEnable) && (channel[1].extIRQPending)) + } + else + m_sisr &= ~REG_SISR_DSRLVL; +} + +WRITE_LINE_MEMBER(mpcc_device::dcd_w) +{ + if (state == CLEAR_LINE) + { + uint8_t old_sisr = m_sisr; + + m_sisr &= ~REG_SISR_DCDLVL; + if ( (old_sisr & REG_SISR_DCDLVL) && + !(m_rcr & REG_RCR_RRES)) { - IRQType = IRQ_A_EXT; - irqstat = 1; + m_sisr |= REG_SISR_DCDT; + if (m_sier & REG_SIER_DCD) + { + // TODO: make sure interrupt is issued with the next negative transition of RxC + trigger_interrupt(INT_SR_DCD); + // TODO: Make sure RxC has negative transition before INT can be reset in SISR5 + } } } else + m_sisr |= REG_SISR_DCDLVL; +} + +//------------------------------------------------- +// get_brg_rate - helper function +//------------------------------------------------- +uint32_t mpcc_device::get_brg_rate() +{ + uint32_t rate; + uint32_t brg_const; + + brg_const = (m_brdr1 | m_brdr2 << 8); // Baud rate divider + brg_const += (m_ccr & REG_CCR_PSCDIV) ? 3 : 2; // Add prescaler factor + brg_const += (m_psr2 & REG_PSR2_PSEL_MSK) == REG_PSR2_PSEL_ASCII ? 2 : 1; // Add K factor + rate = clock() / brg_const; + + return rate; +} + +//------------------------------------------------- +// get_tx_rate - helper function +//------------------------------------------------- +uint32_t mpcc_device::get_tx_rate() +{ + uint32_t rate; + + // Check if TxC is an input and use it instead of the BRG + if ((m_ccr & REG_CCR_TCLO) == 0) + { + rate = m_txc; + } + else { - IRQType = IRQ_NONE; + rate = get_brg_rate(); } -// printf("mpcc: irqstat %d, last %d\n", irqstat, lastIRQStat); -// printf("ch0: en %d pd %d ch1: en %d pd %d\n", channel[0].txIRQEnable, channel[0].txIRQPending, channel[1].txIRQEnable, channel[1].txIRQPending); + return rate; +} - // don't spam the driver with unnecessary transitions - if (irqstat != lastIRQStat) - { - lastIRQStat = irqstat; +//------------------------------------------------- +// get_clock_div - helper function +//------------------------------------------------- +uint32_t mpcc_device::get_clock_div() +{ + uint32_t clk_div = 1; - // tell the driver the new IRQ line status if possible -#if LOG_MPCC - printf("mpcc68561 IRQ status => %d\n", irqstat); -#endif - if(!intrq_cb.isnull()) - intrq_cb(irqstat); + switch (m_ccr & REG_CCR_CLKDIV_MSK) + { + case REG_CCR_CLKDIV_X1 : clk_div = 1; break; + case REG_CCR_CLKDIV_X16: clk_div = 16; break; + case REG_CCR_CLKDIV_X32: clk_div = 32; break; + case REG_CCR_CLKDIV_X64: clk_div = 64; break; } + + return clk_div; } -/*------------------------------------------------- - mpcc_initchannel --------------------------------------------------*/ -void mpcc68561_t::initchannel(int ch) +//------------------------------------------------- +// get_rx_rate - helper function +//------------------------------------------------- +uint32_t mpcc_device::get_rx_rate() { - channel[ch].syncHunt = 1; + uint32_t rate; + + // Check if TxC is an input and use it instead of the BRG + if ((m_ccr & REG_CCR_RCLKIN) == 0) + { + rate = m_rxc / get_clock_div(); + } + else + { + rate = get_brg_rate(); + } + + return rate; } -/*------------------------------------------------- - mpcc_resetchannel --------------------------------------------------*/ -void mpcc68561_t::resetchannel(int ch) +//------------------------------------------------- +// get_word_length - get word length +//------------------------------------------------- +uint32_t mpcc_device::get_word_length() { - emu_timer *timersave = channel[ch].baudtimer; + int bits = 5; + + switch (m_psr2 & REG_PSR2_CHLN_MSK) + { + case REG_PSR2_CHLN_5: bits = 5; break; + case REG_PSR2_CHLN_6: bits = 6; break; + case REG_PSR2_CHLN_7: bits = 7; break; + case REG_PSR2_CHLN_8: bits = 8; break; + } - memset(&channel[ch], 0, sizeof(Chan)); + return bits; +} - channel[ch].txUnderrun = 1; - channel[ch].baudtimer = timersave; +//------------------------------------------------- +// get_stop_bits - translate stop bit settings for serial interface +//------------------------------------------------- +device_serial_interface::stop_bits_t mpcc_device::get_stop_bits() +{ + switch (m_psr2 & REG_PSR2_STP_MSK) + { + case REG_PSR2_STP_1: return STOP_BITS_1; + case REG_PSR2_STP_1_5: return STOP_BITS_1_5; + case REG_PSR2_STP_2: return STOP_BITS_2; + } - channel[ch].baudtimer->adjust(attotime::never, ch); + return STOP_BITS_0; } -/*------------------------------------------------- - mpcc68561_baud_expire - baud rate timer expiry --------------------------------------------------*/ +//------------------------------------------------- +// get_parity - translate parity settings for serial interface +//------------------------------------------------- +device_serial_interface::parity_t mpcc_device::get_parity() +{ + parity_t parity; + + if (m_ecr & REG_ECR_PAREN) + { + if (m_ecr & REG_ECR_ODDPAR) + parity = PARITY_ODD; + else + parity = PARITY_EVEN; + } + else + { + parity = PARITY_NONE; + } + return parity; +} -void mpcc68561_t::device_timer(emu_timer &timer, device_timer_id id, int param, void *ptr) +//------------------------------------------------- +// update_serial - +//------------------------------------------------- +void mpcc_device::update_serial() { - Chan *pChan = &channel[id]; - int brconst = pChan->reg_val[13]<<8 | pChan->reg_val[14]; - int rate; + int data_bits = get_word_length(); + stop_bits_t stop_bits = get_stop_bits(); + parity_t parity = get_parity(); - if (brconst) + LOGSETUP(" %s() %s Setting data frame %d+%d%c%s\n", FUNCNAME, m_owner->tag(), 1, + data_bits, parity == PARITY_NONE ? 'N' : parity == PARITY_EVEN ? 'E' : 'O', + stop_bits == STOP_BITS_1 ? "1" : (stop_bits == STOP_BITS_2 ? "2" : "1.5")); + + set_data_frame(1, data_bits, parity, stop_bits); + + // Setup the Receiver + // check if the receiver is in reset mode + if (m_rcr & REG_RCR_RRES) { - rate = clock() / brconst; + LOGSETUP("- Rx in reset\n"); + set_rcv_rate(0); } + // Rx is running else { - rate = 0; + LOGSETUP("- Rx enabled\n"); + m_brg_rate = get_rx_rate(); + + LOGSETUP("- BRG rate %d\n", m_brg_rate); + set_rcv_rate(m_brg_rate); } - // is baud counter IRQ enabled on this channel? - // always flag pending in case it's enabled after this - pChan->baudIRQPending = 1; - if (pChan->baudIRQEnable) + // Setup the Transmitter + // check if Rx is in reset + if (m_tcr & REG_TCR_TRES) + { + LOGSETUP("- Tx in reset\n"); + set_tra_rate(0); + } + // Tx is running + else { - if (pChan->extIRQEnable) + // Check that Tx is enabled + if (m_tcr & REG_TCR_TEN) + { + LOGSETUP("- Tx enabled\n"); + m_brg_rate = get_tx_rate(); + + LOGSETUP("- BRG rate %d\n", m_brg_rate); + set_tra_rate(m_brg_rate); + } + else { - pChan->extIRQPending = 1; - pChan->baudIRQPending = 0; - updateirqs(); + LOGSETUP("- Tx disabled\n"); + set_tra_rate(0); } } +} - // reset timer according to current register values - if (rate) +//------------------------------------------------- +// tra_callback - is called for each bit that needs to be transmitted +//------------------------------------------------- +void mpcc_device::tra_callback() +{ + // Check if transmitter is idle as in disabled + if (!(m_tcr & REG_TCR_TEN)) + { + // transmit idle TODO: Support TCR TICS bit + LOGTX("%s idle bit\n", FUNCNAME); + m_out_txd_cb(1); + } +#if 0 + // Check if we are transmitting break TODO: Figure out Break support + else if (...) { - timer.adjust(attotime::from_hz(rate), 0, attotime::from_hz(rate)); + // transmit break + m_out_txd_cb(0); } +#endif + // Check if there is more bits to send + else if (!is_transmit_register_empty()) + { + // Get the next bit + int db = transmit_register_get_data_bit(); + LOGTX("%s bit: %d\n", FUNCNAME, db ? 1 : 0); + + // transmit data + m_out_txd_cb(db); + } + // Otherwise we don't know why we are called... else { - timer.adjust(attotime::never, 0, attotime::never); + logerror("%s %s Failed to transmit\n", FUNCNAME, m_owner->tag()); } } -/*------------------------------------------------- - device_start - device-specific startup --------------------------------------------------*/ +//------------------------------------------------- +// tra_complete - is called when the transmitter shift register has sent the last bit +//------------------------------------------------- +void mpcc_device::tra_complete() +{ + // check if transmitter is enabled and we are not sending BREAK level + if ((m_tcr & REG_TCR_TEN) && !(m_tcr & REG_TCR_TICS)) + { // check if there are more data in the fifo + if (!m_tx_data_fifo.empty()) + { + transmit_register_setup(m_tx_data_fifo.dequeue()); // Reload the shift register + m_tsr |= REG_TSR_TDRA; // Mark fifo as having room for more data + } + else + { + m_out_rts_cb(CLEAR_LINE); // TODO: respect the RTSLV bit + m_sicr &= ~REG_SICR_RTSLVL; + } + + // Check if Tx interrupts are enabled + if (m_tier & REG_TIER_TDRA) + { + // TODO: Check circumstances, eg int on first or every character etc + trigger_interrupt(INT_TX_TDRA); + } + } // Check if sending BREAK + else if (m_tcr & REG_TCR_TICS) + { + // TODO: Should transmit content of AR2, needs investigation + m_out_txd_cb(0); + } + else + { + // transmit mark + m_out_txd_cb(1); + } +} -void mpcc68561_t::device_start() +//------------------------------------------------- +// rcv_callback - called when it is time to sample incomming data bit +//------------------------------------------------- +void mpcc_device::rcv_callback() { - intrq_cb.resolve_safe(); + // Check if the Receiver is enabled + if (!(m_rcr & REG_RCR_RRES)) + { + receive_register_update_bit(m_rxd); + } +} - memset(channel, 0, sizeof(channel)); +//------------------------------------------------- +// rcv_complete - +//------------------------------------------------- +void mpcc_device::rcv_complete() +{ + uint8_t data; - mode = 0; - reg = 0; - status = 0; - IRQV = 0; - MasterIRQEnable = 0; - lastIRQStat = 0; - IRQType = IRQ_NONE; + receive_register_extract(); + data = get_received_char(); + LOGRX("%s %02x [%c]\n", FUNCNAME, isascii(data) ? data : ' ', data); - channel[0].baudtimer = timer_alloc(0); + // receive_data(data); + if (m_rx_data_fifo.full()) + { + // receive overrun error detected, new data is lost + m_rsr |= REG_RSR_ROVRN; + // interrupt if rx overrun interrupt is enabled + if (m_rier & REG_RIER_ROVRN) + { + trigger_interrupt(INT_RX_ROVRN); + } + } + else + { + m_rx_data_fifo.enqueue(data); + m_rsr |= REG_RSR_RDA; + // interrupt if rx data availble is enabled + if (m_rier & REG_RIER_RDA) + { + trigger_interrupt(INT_RX_RDA); + } + } } - -/*------------------------------------------------- - device_reset - device-specific reset --------------------------------------------------*/ -void mpcc68561_t::device_reset() +//------------------------------------------------- +// write_rx - called by terminal through rs232/diserial +// when character is sent to board +//------------------------------------------------- +WRITE_LINE_MEMBER(mpcc_device::write_rx) { - IRQType = IRQ_NONE; - MasterIRQEnable = 0; - IRQV = 0; + LOGRCV("%s(%d)\n", FUNCNAME, state); + m_rxd = state; - initchannel(0); - resetchannel(0); + //only use rx_w when self-clocked + if(m_rxc != 0 || m_brg_rate != 0) + device_serial_interface::rx_w(state); } -/*------------------------------------------------- - mpcc_set_status --------------------------------------------------*/ -void mpcc68561_t::set_status(int _status) +/* + * Interrupts + */ +//------------------------------------------------- +// check_interrupts - +//------------------------------------------------- +void mpcc_device::check_interrupts() { - status = _status; -} + int state = 0; + LOGINT("%s %s \n",tag(), FUNCNAME); -/*------------------------------------------------- - mpcc_acknowledge --------------------------------------------------*/ + // loop over all interrupt sources + for (auto & elem : m_int_state) + { + state |= elem; + } -void mpcc68561_t::acknowledge() -{ - if(!intrq_cb.isnull()) - intrq_cb(0); + // update IRQ line + // If we are not serving any interrupt the IRQ is asserted already and we need to do nothing + if ((state & INT_ACK) == 0) + { + // If there is a new interrupt not yet acknowledged IRQ needs to be asserted + if (state & INT_REQ) + { + m_out_int_cb(ASSERT_LINE); + } + // Otherwise we just clear the IRQ line allowing other devices to interrupt + else + { + m_out_int_cb(CLEAR_LINE); + } + } } -/*------------------------------------------------- - mpcc_getreg --------------------------------------------------*/ +//------------------------------------------------- +// reset_interrupts - +//------------------------------------------------- -uint8_t mpcc68561_t::getreg() +void mpcc_device::reset_interrupts() { - /* Not yet implemented */ - #if LOG_MPCC - printf("mpcc: port A reg %d read 0x%02x\n", reg, channel[0].reg_val[reg]); - #endif - - if (reg == 0) + LOGINT("%s %s \n",tag(), FUNCNAME); + // reset internal interrupt sources + for (auto & elem : m_int_state) { - uint8_t rv = 0; - - Chan *ourCh = &channel[0]; + elem = 0; + } - rv |= (ourCh->txUnderrun) ? 0x40 : 0; - rv |= (ourCh->syncHunt) ? 0x10 : 0; - rv |= channel[0].reg_val[0] & 0x05; // pick up TXBE and RXBF bits + // check external interrupt sources + check_interrupts(); +} - return rv; - } - else if (reg == 10) +//----------------------------------------------------------------------- +// trigger_interrupt - called when a potential interrupt condition occurs +//------------------------------------------------- +void mpcc_device::trigger_interrupt(int source) +{ + LOGINT("%s %s: %02x\n",FUNCNAME, tag(), source); + switch(source) { - return 0; + case INT_TX_TDRA: + case INT_TX_TFC: + case INT_TX_TUNRN: + case INT_TX_TFERR: + m_int_state[TX_INT_PRIO] = INT_REQ; + break; + case INT_RX_RDA: + case INT_RX_EOF: + case INT_RX_CPERR: + case INT_RX_FRERR: + case INT_RX_ROVRN: + case INT_RX_RAB: + m_int_state[RX_INT_PRIO] = INT_REQ; + break; + case INT_SR_CTS: + case INT_SR_DSR: + case INT_SR_DCD: + m_int_state[SR_INT_PRIO] = INT_REQ; + break; } - return channel[0].reg_val[reg]; + check_interrupts(); } -/*------------------------------------------------- - mpcc_putreg --------------------------------------------------*/ - -void mpcc68561_t::putreg(int ch, uint8_t data) +//------------------------------------------------- +// Read register +//------------------------------------------------- +READ8_MEMBER( mpcc_device::read ) { - Chan *pChan = &channel[ch]; + uint8_t data = 0; - channel[ch].reg_val[reg] = data; - #if LOG_MPCC - printf("mpcc: port %c reg %d write 0x%02x\n", 'A'+ch, reg, data); - #endif + switch(offset) + { + case 0x00: data = do_rsr(); break; + case 0x01: data = do_rcr(); break; + case 0x02: data = do_rdr(); break; + case 0x04: data = m_rivnr; logerror("MPCC: Reg RIVNR not implemented\n"); break; + case 0x05: data = do_rier(); break; + case 0x08: data = m_tsr; break; logerror("MPCC: Reg TSR not implemented\n"); break; + case 0x09: data = do_tcr(); break; + //case 0x0a: data = m_tdr; break; // TDR is a write only register + case 0x0c: data = do_tivnr(); break; + case 0x0d: data = do_tier(); break; + case 0x10: data = do_sisr(); break; + case 0x11: data = do_sicr(); break; + case 0x14: data = m_sivnr; logerror("MPCC: Reg SIVNR not implemented\n"); break; + case 0x15: data = do_sier(); break; + case 0x18: data = do_psr1(); break; + case 0x19: data = do_psr2(); break; + case 0x1a: data = m_ar1; logerror("MPCC: Reg AR1 not implemented\n"); break; + case 0x1b: data = m_ar2; logerror("MPCC: Reg AR2 not implemented\n"); break; + case 0x1c: data = do_brdr1(); break; + case 0x1d: data = do_brdr2(); break; + case 0x1e: data = do_ccr(); break; + case 0x1f: data = do_ecr(); break; + default: logerror("%s invalid register accessed: %02x\n", m_owner->tag(), offset); + } + LOGR(" * %s Reg %02x -> %02x \n", m_owner->tag(), offset, data); + return data; +} - switch (reg) +//------------------------------------------------- +// Write register +//------------------------------------------------- +WRITE8_MEMBER( mpcc_device::write ) +{ + LOGSETUP(" * %s Reg %02x <- %02x \n", m_owner->tag(), offset, data); + switch(offset) { - case 0: // command register - switch ((data >> 3) & 7) - { - case 1: // select high registers (handled elsewhere) - break; - - case 2: // reset external and status IRQs - pChan->syncHunt = 0; - break; - - case 5: // ack Tx IRQ - pChan->txIRQPending = 0; - updateirqs(); - break; - - case 0: // nothing - case 3: // send SDLC abort - case 4: // enable IRQ on next Rx byte - case 6: // reset errors - case 7: // reset highest IUS - // we don't handle these yet - break; + case 0x00: do_rsr(data); break; + case 0x01: do_rcr(data); break; + //case 0x02: m_rdr = data; break; // RDR is a read only register + case 0x04: m_rivnr = data; logerror("MPCC: Reg RIVNR not implemented\n"); break; + case 0x05: do_rier(data); break; + case 0x08: m_tsr = data; logerror("MPCC: Reg TSR not implemented\n"); break; + case 0x09: do_tcr(data); break; + case 0x0a: m_tdr = data; LOGCHAR("*%c", data); do_tdr(data); break; + case 0x0c: do_tivnr(data); break; + case 0x0d: do_tier(data); break; + case 0x10: do_sisr(data); break; + case 0x11: do_sicr(data); break; + case 0x14: m_sivnr = data; logerror("MPCC: Reg SIVNR not implemented\n"); break; + case 0x15: do_sier(data); break; + case 0x18: do_psr1(data); break; + case 0x19: do_psr2(data); break; + case 0x1a: m_ar1 = data; logerror("MPCC: Reg AR1 not implemented\n"); break; + case 0x1b: m_ar2 = data; logerror("MPCC: Reg AR2 not implemented\n"); break; + case 0x1c: do_brdr1(data); break; + case 0x1d: do_brdr2(data); break; + case 0x1e: do_ccr(data); break; + case 0x1f: do_ecr(data); break; + default: logerror("%s invalid register accessed: %02x\n", m_owner->tag(), offset); + } +} - } - break; +void mpcc_device::do_rsr(uint8_t data) +{ + LOG("%s -> %02x\n", FUNCNAME, data); + m_rsr = data; +} - case 1: // Tx/Rx IRQ and data transfer mode defintion - pChan->extIRQEnable = (data & 1); - pChan->txIRQEnable = (data & 2) ? 1 : 0; - pChan->rxIRQEnable = (data >> 3) & 3; - updateirqs(); - break; +uint8_t mpcc_device::do_rsr() +{ + uint8_t data = m_rsr; + LOG("%s <- %02x\n", FUNCNAME, data); + return data; +} - case 2: // IRQ vector - IRQV = data; - break; +void mpcc_device::do_rcr(uint8_t data) +{ + LOG("%s -> %02x\n", FUNCNAME, data); + m_rcr = data; + LOGSETUP(" - Rx DMA : %s\n", (m_rcr & REG_RCR_RDSREN) ? "enabled" : "disabled"); + LOGSETUP(" - Rx DONE out : %s\n", (m_rcr & REG_RCR_DONEEN) ? "enabled" : "disabled"); + LOGSETUP(" - Rx RSYN out : %s\n", (m_rcr & REG_RCR_RSYNEN) ? "enabled" : "disabled"); + LOGSETUP(" - Rx strip SYN: %s\n", (m_rcr & REG_RCR_STRSYN) ? "enabled" : "disabled"); + LOGSETUP(" - Rx Abort : %s\n", (m_rcr & REG_RCR_RABTEN) ? "enabled" : "disabled"); + LOGSETUP(" - Rx Mode : %s\n", (m_rcr & REG_RCR_RRES ) ? "reset" : "normal"); + + update_serial(); +} - case 3: // Rx parameters and controls - pChan->rxEnable = (data & 1); - pChan->syncHunt = (data & 0x10) ? 1 : 0; - break; +uint8_t mpcc_device::do_rcr() +{ + uint8_t data = m_rcr; + LOG("%s <- %02x\n", FUNCNAME, data); + return data; +} - case 5: // Tx parameters and controls -// printf("ch %d TxEnable = %d [%02x]\n", ch, data & 8, data); - pChan->txEnable = data & 8; +uint8_t mpcc_device::do_rdr() +{ + uint8_t data = 0; - if (pChan->txEnable) - { - pChan->reg_val[0] |= 0x04; // Tx empty - } - break; + if (!m_rx_data_fifo.empty()) + { + // load data from the FIFO + data = m_rx_data_fifo.dequeue(); + } + else + { + LOGRX("data_read: Attempt to read out character from empty FIFO\n"); + logerror("data_read: Attempt to read out character from empty FIFO\n"); + } - case 4: // Tx/Rx misc parameters and modes - case 6: // sync chars/SDLC address field - case 7: // sync char/SDLC flag - break; + LOGRX("%s <- %02x [%c]\n", FUNCNAME, isascii(data) ? data : ' ', data); + return data; +} - case 9: // master IRQ control - MasterIRQEnable = (data & 8) ? 1 : 0; - updateirqs(); - // channel reset command - switch ((data>>6) & 3) - { - case 0: // do nothing - break; +void mpcc_device::do_rier(uint8_t data) +{ + LOG("%s -> %02x\n", FUNCNAME, data); + m_rier = data; + LOGSETUP(" - Rx INT on Rx data available : %s\n", (m_rier & REG_RIER_RDA) ? "enabled" : "disabled"); + LOGSETUP(" - Rx INT on End of Frame : %s\n", (m_rier & REG_RIER_EOF) ? "enabled" : "disabled"); + LOGSETUP(" - Rx INT on CRC/Parity error : %s\n", (m_rier & REG_RIER_CPERR) ? "enabled" : "disabled"); + LOGSETUP(" - Rx INT on Frame error : %s\n", (m_rier & REG_RIER_FRERR) ? "enabled" : "disabled"); + LOGSETUP(" - Rx INT on Receiver overrun : %s\n", (m_rier & REG_RIER_ROVRN) ? "enabled" : "disabled"); + LOGSETUP(" - Rx INT on Abort/Break : %s\n", (m_rier & REG_RIER_RAB) ? "enabled" : "disabled"); +} - case 1: // reset channel B - resetchannel(0); - break; +uint8_t mpcc_device::do_rier() +{ + uint8_t data = m_rier; + LOG("%s <- %02x\n", FUNCNAME, data); + return data; +} - case 3: // force h/w reset (entire chip) - IRQType = IRQ_NONE; - MasterIRQEnable = 0; - IRQV = 0; +void mpcc_device::do_tdr(uint8_t data) +{ + LOG("%s -> %d [%c]\n", FUNCNAME, data, isprint(data) ? data : ' '); + // Check of Tx fifo has room + if (m_tx_data_fifo.full()) + { + logerror("- TX FIFO is full, discarding data\n"); + LOGTX("- TX FIFO is full, discarding data\n"); + } + else // ..there is still room + { + m_tx_data_fifo.enqueue(data); + if (m_tx_data_fifo.full()) + { + m_tsr &= ~REG_TSR_TDRA; // Mark fifo as full + } + } - initchannel(0); - resetchannel(0); + // Check if Tx is enabled + if (m_tcr & REG_TCR_TEN) + { + LOGTX("- TX is enabled\n"); + if (is_transmit_register_empty()) // Is the shift register loaded? + { + LOGTX("- Setting up transmitter\n"); + transmit_register_setup(m_tx_data_fifo.dequeue()); // Load the shift register, reload is done in tra_complete() + m_tsr |= REG_TSR_TDRA; // Now there is a slot in the FIFO available again + } + else + { + LOGTX("- Transmitter not empty\n"); + } + } +} - // make sure we stop yanking the IRQ line if we were - updateirqs(); - break; +void mpcc_device::do_tcr(uint8_t data) +{ + LOG("%s -> %02x\n", FUNCNAME, data); + m_tcr = data; + LOGSETUP(" - Tx : %s\n", (m_tcr & REG_TCR_TEN) ? "enabled" : "disabled"); + LOGSETUP(" - Tx DMA : %s\n", (m_tcr & REG_TCR_TDSREN) ? "enabled" : "disabled"); + LOGSETUP(" - Tx Idle character : %s\n", (m_tcr & REG_TCR_TICS) ? "AR2" : "high"); + LOGSETUP(" - Tx Half Word next : %s\n", (m_tcr & REG_TCR_THW) ? "yes" : "no"); + LOGSETUP(" - Tx Last character : %s\n", (m_tcr & REG_TCR_TLAST) ? "yes" : "no"); + LOGSETUP(" - Tx SYN : %s\n", (m_tcr & REG_TCR_TSYN) ? "enabled" : "disabled"); + LOGSETUP(" - Tx Abort command : %s\n", (m_tcr & REG_TCR_TABT) ? "active" : "inactive"); + LOGSETUP(" - Tx Mode : %s\n", (m_tcr & REG_TCR_TRES) ? "reset" : "normal"); + + update_serial(); +} - } - break; +uint8_t mpcc_device::do_tcr() +{ + uint8_t data = m_tcr; + LOG("%s <- %02x\n", FUNCNAME, data); + return data; +} - case 10: // misc transmitter/receiver control bits - case 11: // clock mode control - case 12: // lower byte of baud rate gen - case 13: // upper byte of baud rate gen - break; +void mpcc_device::do_tivnr(uint8_t data) +{ + LOG("%s -> %02x\n", FUNCNAME, data); + m_tivnr = data; + LOGSETUP(" - Tx Int vector: %02x\n", m_tivnr); +} - case 14: // misc control bits - if (data & 0x01) // baud rate generator enable? - { - int brconst = pChan->reg_val[13]<<8 | pChan->reg_val[14]; - int rate = clock() / brconst; +uint8_t mpcc_device::do_tivnr() +{ + uint8_t data = m_tivnr; + LOG("%s <- %02x\n", FUNCNAME, data); + return data; +} - pChan->baudtimer->adjust(attotime::from_hz(rate), 0, attotime::from_hz(rate)); - } - break; +void mpcc_device::do_tier(uint8_t data) +{ + LOG("%s -> %02x\n", FUNCNAME, data); + m_tier = data; + LOGSETUP(" - Tx INT on FIFO slot available : %s\n", (m_tier & REG_TIER_TDRA) ? "enabled" : "disabled"); + LOGSETUP(" - Tx INT on Frame complete : %s\n", (m_tier & REG_TIER_TFC ) ? "enabled" : "disabled"); + LOGSETUP(" - Tx INT on Underrun : %s\n", (m_tier & REG_TIER_TUNRN) ? "enabled" : "disabled"); + LOGSETUP(" - Tx INT on Frame error : %s\n", (m_tier & REG_TIER_TFERR) ? "enabled" : "disabled"); +} - case 15: // external/status interrupt control - pChan->baudIRQEnable = (data & 2) ? 1 : 0; - pChan->DCDEnable = (data & 8) ? 1 : 0; - pChan->CTSEnable = (data & 0x20) ? 1 : 0; - pChan->txUnderrunEnable = (data & 0x40) ? 1 : 0; - break; - } +uint8_t mpcc_device::do_tier() +{ + uint8_t data = m_tier; + LOG("%s <- %02x\n", FUNCNAME, data); + return data; } -/*------------------------------------------------- - mpcc68561_get_reg_a --------------------------------------------------*/ +void mpcc_device::do_sisr(uint8_t data) +{ + LOG("%s -> %02x\n", FUNCNAME, data); + if (data & REG_SISR_CTST) m_sisr &= ~REG_SISR_CTST; + if (data & REG_SISR_DSRT) m_sisr &= ~REG_SISR_DSRT; + if (data & REG_SISR_DCDT) m_sisr &= ~REG_SISR_DCDT; + + LOGSETUP(" - CTS %d transitioned: %d\n", (m_sisr & REG_SISR_CTSLVL) ? 1 :0, (m_sisr & REG_SISR_CTST) ? 1 : 0); + LOGSETUP(" - DSR %d transitioned: %d\n", (m_sisr & REG_SISR_DSRLVL) ? 1 :0, (m_sisr & REG_SISR_DSRT) ? 1 : 0); + LOGSETUP(" - DCD %d transitioned: %d\n", (m_sisr & REG_SISR_DCDLVL) ? 1 :0, (m_sisr & REG_SISR_DCDT) ? 1 : 0); +} -uint8_t mpcc68561_t::get_reg_a(int reg) +uint8_t mpcc_device::do_sisr() { - return channel[0].reg_val[reg]; + uint8_t data = m_sisr; + LOG("%s <- %02x\n", FUNCNAME, data); + return data; } +void mpcc_device::do_sicr(uint8_t data) +{ + LOG("%s -> %02x\n", FUNCNAME, data); + + // If RTS is activated the RTS output latch can only be reset by an empty FIFO. + if ( !(m_sicr & REG_SICR_RTSLVL) && + (data & REG_SICR_RTSLVL)) + { + m_out_rts_cb(ASSERT_LINE); // TODO: respect the RTSLV bit + } + + m_sicr = data; + if (m_sicr & REG_SICR_DTRLVL) + { + m_out_dtr_cb(ASSERT_LINE); + } + else + { + m_out_dtr_cb(CLEAR_LINE); + } -/*------------------------------------------------- - mpcc68561_set_reg_a --------------------------------------------------*/ + LOGSETUP(" - RTS level : %s\n", (m_sicr & REG_SICR_RTSLVL) ? "high" : "low"); + LOGSETUP(" - DTR level : %s\n", (m_sicr & REG_SICR_DTRLVL) ? "high" : "low"); + LOGSETUP(" - Echo Mode : %s\n", (m_sicr & REG_SICR_ECHO) ? "enabled" : "disabled"); + LOGSETUP(" - Test Mode : %s\n", (m_sicr & REG_SICR_TEST) ? "enabled" : "disabled"); +} -void mpcc68561_t::set_reg_a(int reg, uint8_t data) +uint8_t mpcc_device::do_sicr() { - channel[0].reg_val[reg] = data; + uint8_t data = m_sicr; + LOG("%s <- %02x\n", FUNCNAME, data); + return data; } +void mpcc_device::do_sier(uint8_t data) +{ + LOG("%s -> %02x\n", FUNCNAME, data); + m_sier = data; + LOGSETUP(" - Serial interface INT on CTS: %s\n", (m_sier & REG_SIER_CTS) ? "enabled" : "disabled"); + LOGSETUP(" - Serial interface INT on DSR: %s\n", (m_sier & REG_SIER_DSR) ? "enabled" : "disabled"); + LOGSETUP(" - Serial interface INT on DCD: %s\n", (m_sier & REG_SIER_DCD) ? "enabled" : "disabled"); +} +uint8_t mpcc_device::do_sier() +{ + uint8_t data = m_sier; + LOG("%s <- %02x\n", FUNCNAME, data); + return data; +} -/*------------------------------------------------- - mpcc68561_r --------------------------------------------------*/ +void mpcc_device::do_psr1(uint8_t data) +{ + LOG("%s -> %02x\n", FUNCNAME, data); + m_psr1 = data; + LOGSETUP(" - Zero Address option: %s\n", (m_psr1 & REG_PSR1_ADRZ) ? "enabled" : "disabled" ); + LOGSETUP(" - IPARS option : %s\n", (m_psr1 & REG_PSR1_IPARS) ? "enabled" : "disabled" ); + LOGSETUP(" - Control Field Width: %s\n", (m_psr1 & REG_PSR1_CTLEX) ? "16 bit" : "8 bit" ); + LOGSETUP(" - Address Extend : %s\n", (m_psr1 & REG_PSR1_ADDEX) ? "enabled" : "disabled" ); + + update_serial(); +} -READ8_MEMBER( mpcc68561_t::reg_r) +uint8_t mpcc_device::do_psr1() { - uint8_t result = 0; + uint8_t data = m_psr1; + LOG("%s <- %02x\n", FUNCNAME, data); + return data; +} - offset %= 4; +void mpcc_device::do_psr2(uint8_t data) +{ + LOG("%s -> %02x\n", FUNCNAME, data); + m_psr2 = data; + LOGSETUP(" - %s data bus\n", (m_psr2 & REG_PSR2_WDBYT) ? "16 bit (not implemented)" : "8 bit" ); + LOGSETUP(" - %s stop bits\n",(m_psr2 & REG_PSR2_STP_MSK) == REG_PSR2_STP_1 ? "1" : + ( (m_psr2 & REG_PSR2_STP_MSK) == REG_PSR2_STP_1_5 ? "1.5" : + ( (m_psr2 & REG_PSR2_STP_MSK) == REG_PSR2_STP_2 ? "2" : "Unknown"))); + LOGSETUP(" - %d bit characters\n", 5 + ((m_psr2 & REG_PSR2_CHLN_MSK) >> 3)); + LOGSETUP(" - Protocol %d %s\n", m_psr2 & REG_PSR2_PSEL_MSK, (m_psr2 & REG_PSR2_PSEL_MSK) != REG_PSR2_PSEL_ASCII ? "(not implemented)" : ""); + + update_serial(); +} - switch(offset) - { - case 1: - /* Channel A (Modem Port) Control */ - if (mode == 1) - mode = 0; - else - reg = 0; +uint8_t mpcc_device::do_psr2() +{ + uint8_t data = m_psr2; + LOG("%s <- %02x\n", FUNCNAME, data); + return data; +} - result = getreg(); - break; +/* + * Clocks and Baud Rates + */ +void mpcc_device::do_brdr1(uint8_t data) +{ + LOG("%s -> %02x\n", FUNCNAME, data); + m_brdr1 = data; + LOGSETUP(" - Baudrate Divider 1: %02x\n", m_brdr1); - case 3: - /* Channel A (Modem Port) Data */ - return channel[0].rxData; - break; - } - return result; + update_serial(); } +uint8_t mpcc_device::do_brdr1() +{ + uint8_t data = m_brdr1; + LOG("%s <- %02x\n", FUNCNAME, data); + return data; +} +void mpcc_device::do_brdr2(uint8_t data) +{ + LOG("%s -> %02x\n", FUNCNAME, data); + m_brdr2 = data; + LOGSETUP(" - Baudrate Divider 2: %02x\n", m_brdr2); -/*------------------------------------------------- - mpcc68561_w --------------------------------------------------*/ + update_serial(); +} -WRITE8_MEMBER( mpcc68561_t::reg_w ) +uint8_t mpcc_device::do_brdr2() { - Chan *pChan; - - offset &= 3; + uint8_t data = m_brdr2; + LOG("%s <- %02x\n", FUNCNAME, data); + return data; +} -// printf(" mode %d data %x offset %d \n", mode, data, offset); +void mpcc_device::do_ccr(uint8_t data) +{ + LOG("%s -> %02x\n", FUNCNAME, data); + m_ccr = data; + LOGSETUP(" - Prescaler: x%d\n", (m_ccr & REG_CCR_PSCDIV) ? 3 : 2); + LOGSETUP(" - TxC used as: %s\n", (m_ccr & REG_CCR_TCLO) ? "output" : "input"); + LOGSETUP(" - RxC taken from: %s source, (ASYNC mode only)\n", (m_ccr & REG_CCR_TCLO) ? "internal" : "external"); + LOGSETUP(" - External RxC divisor: x%d\n",(m_ccr & REG_CCR_CLKDIV_MSK) == REG_CCR_CLKDIV_X1 ? 1 : + ( (m_ccr & REG_CCR_CLKDIV_MSK) == REG_CCR_CLKDIV_X16 ? 16 : + ( (m_ccr & REG_CCR_CLKDIV_MSK) == REG_CCR_CLKDIV_X32 ? 32 : 64))); + + update_serial(); +} - switch(offset) - { - case 1: - /* Channel A (Modem Port) Control */ - if (mode == 0) - { - if((data & 0xf0) == 0) // not a reset command - { - mode = 1; - reg = data & 0x0f; -// putareg(data & 0xf0); - } - else if (data == 0x10) - { - pChan = &channel[0]; - // clear ext. interrupts - pChan->extIRQPending = 0; - pChan->baudIRQPending = 0; - updateirqs(); - } - } - else - { - mode = 0; - putreg(0, data); - } - break; +uint8_t mpcc_device::do_ccr() +{ + uint8_t data = m_ccr; + LOG("%s <- %02x\n", FUNCNAME, data); + return data; +} - case 3: - /* Channel A (Modem Port) Data */ - pChan = &channel[0]; +void mpcc_device::do_ecr(uint8_t data) +{ + LOG("%s -> %02x\n", FUNCNAME, data); + m_ecr = data; + LOGSETUP(" - Parity : %s\n", (m_ecr & REG_ECR_PAREN) ? "enabled" : "disabled"); + LOGSETUP(" - Parity : %s\n", (m_ecr & REG_ECR_ODDPAR) ? "odd" : "even"); + LOGSETUP(" - CRC : %s\n", (m_ecr & REG_ECR_CFCRC) ? "enabled" : "disabled"); + LOGSETUP(" - CRC Polynominal: %s\n", (m_ecr & REG_ECR_CRCSEL_MSK) == REG_ECR_CRCSEL_V41 ? "CCITT V.41 (BOP)" : + ( (m_ecr & REG_ECR_CRCSEL_MSK) == REG_ECR_CRCSEL_C16 ? "CRC-16 (BSC)" : + ( (m_ecr & REG_ECR_CRCSEL_MSK) == REG_ECR_CRCSEL_VRC ? "VRC/LRC (BSC, ASCII, non-transp)" : + "Not used"))); + + update_serial(); +} - if (pChan->txEnable) - { - pChan->txData = data; - // local loopback? - if (pChan->reg_val[14] & 0x10) - { - pChan->rxData = data; - pChan->reg_val[0] |= 0x01; // Rx character available - } - pChan->reg_val[1] |= 0x01; // All sent - pChan->reg_val[0] |= 0x04; // Tx empty - pChan->txUnderrun = 1; - pChan->txIRQPending = 1; - updateirqs(); - } - break; - } +uint8_t mpcc_device::do_ecr() +{ + uint8_t data = m_ecr; + LOG("%s <- %02x\n", FUNCNAME, data); + return data; } diff --git a/src/devices/machine/68561mpcc.h b/src/devices/machine/68561mpcc.h index ed38b7bdb01..a2c06dbaaf5 100644 --- a/src/devices/machine/68561mpcc.h +++ b/src/devices/machine/68561mpcc.h @@ -1,102 +1,461 @@ // license:BSD-3-Clause -// copyright-holders:Sergey Svishchev -/********************************************************************* +// copyright-holders:Joakim Larsson Edstrom +/*************************************************************************** + + MPCC Multi-Protocol Communications Controller emulation + +**************************************************************************** + _____ _____ + UDS* 1|* \_/ |48 IACK* + DTACK* 2| |47 LDS* + RxD 3| |46 DTC* + D10 4| |45 D9 _____ _____ + DTR* 5| |44 CS* A0 1|* \_/ |40 IACK* + DSR* 6| |43 DACK* DTACK* 2| |39 DS* + DCD* 7| |42 GND RxD* 3| |38 DTC* + D11 8| |41 D0 DTR* 4| |37 CS* + RDSR* 9| |40 D8 DSR* 5| |36 DACK* + A1 10| |39 D1 DCD* 6| |35 GND + GND 11| |38 D2 RDSR* 7| |34 D0 + A4 12| |37 D3 A1 8| |33 D1 + A2 13| R68561 |36 D4 GND 9| R68560 |32 D2 + A3 14| R68561A |35 D5 A4 10| R68560A |31 D3 + RxC 15| |34 D6 A2 11| |30 D4 + D12 16| |33 D15 A3 12| |29 D5 + TxC 17| |32 D7 RxC 13| |28 D6 + BCLK 18| |31 RESET* TxC 14| |27 D7 + EXTAL 19| |30 CTS* BCLK 15| |26 RESET* + XTAL 20| |29 Vcc EXTAL 16| |25 CTS* + D13 21| |28 D14 XTAL 17| |24 Vcc + R/W* 22| |27 DONE* R/W* 18| |23 DONE* + IRQ* 23| |26 TxD IRQ* 19| |22 TxD + RTS* 24|_____________|25 TDSR* RTS* 20|_____________|21 TDSR* + 16 bit data bus 8 bit data bus + Also in 68 pin PLCE Also in 44 pin PLCE + +***************************************************************************/ + +#ifndef MPCC68561_H +#define MPCC68561_H + +#include "emu.h" + +/* Variant ADD macros - use the right one to enable the right feature set! */ +#define MCFG_MPCC68560_ADD(_tag, _clock, _rx, _tx) \ + MCFG_DEVICE_ADD(_tag, MPCC68560, _clock) \ + MCFG_MPCC_CLOCK(_rx, _tx) + +#define MCFG_MPCC68560A_ADD(_tag, _clock, _rx, _tx) \ + MCFG_DEVICE_ADD(_tag, MPCC68560A, _clock) \ + MCFG_MPCC_CLOCK(_rx, _tx) - 68561mpcc.h +#define MCFG_MPCC68561_ADD(_tag, _clock, _rx, _tx) \ + MCFG_DEVICE_ADD(_tag, MPCC68561, _clock) \ + MCFG_MPCC_CLOCK(_rx, _tx) - Rockwell 68561 MPCC (Multi Protocol Communications Controller) +#define MCFG_MPCC68561A_ADD(_tag, _clock, _rx, _tx) \ + MCFG_DEVICE_ADD(_tag, MPCC68561A, _clock) \ + MCFG_MPCC_CLOCK(_rx, _tx) - skeleton driver +/* Generic ADD macro - Avoid using it directly, see above for correct variant instead */ +#define MCFG_MPCC_ADD(_tag, _clock, _rxa, _txa, _rxb, _txb) \ + MCFG_DEVICE_ADD(_tag, MPCC, _clock) \ + MCFG_MPCC_CLOCK(_rx, _tx) -*********************************************************************/ +/* Generic macros */ +#define MCFG_MPCC_CLOCK(_rx, _tx) \ + mpcc_device::configure_clocks(*device, _rx, _tx); -#ifndef __68561MPCC_H__ -#define __68561MPCC_H__ +/* Callbacks to be called by us for signals driven by the MPCC */ +#define MCFG_MPCC_OUT_TXD_CB(_devcb) \ + devcb = &mpcc_device::set_out_txd_callback(*device, DEVCB_##_devcb); -#define MCFG_MPCC68561_INTRQ_CALLBACK(_write) \ - devcb = &mpcc68561_t::set_intrq_wr_callback(*device, DEVCB_##_write); +#define MCFG_MPCC_OUT_DTR_CB(_devcb) \ + devcb = &mpcc_device::set_out_dtr_callback(*device, DEVCB_##_devcb); -class mpcc68561_t : public device_t +#define MCFG_MPCC_OUT_RTS_CB(_devcb) \ + devcb = &mpcc_device::set_out_rts_callback(*device, DEVCB_##_devcb); + +#define MCFG_MPCC_OUT_TRXC_CB(_devcb) \ + devcb = &mpcc_device::set_out_trxc_callback(*device, DEVCB_##_devcb); + +#define MCFG_MPCC_OUT_RTXC_CB(_devcb) \ + devcb = &mpcc_device::set_out_rtxc_callback(*device, DEVCB_##_devcb); + +#define MCFG_MPCC_OUT_INT_CB(_devcb) \ + devcb = &mpcc_device::set_out_int_callback(*device, DEVCB_##_devcb); + + + +//************************************************************************** +// TYPE DEFINITIONS +//************************************************************************** +class mpcc_device : public device_t, + public device_serial_interface { public: - enum IRQType_t { - IRQ_NONE, - IRQ_A_RX, - IRQ_A_RX_SPECIAL, - IRQ_B_RX, - IRQ_B_RX_SPECIAL, - IRQ_A_TX, - IRQ_B_TX, - IRQ_A_EXT, - IRQ_B_EXT - }; + // construction/destruction + mpcc_device(const machine_config &mconfig, device_type type, const char *name, const char *tag, device_t *owner, uint32_t clock, uint32_t variant, const char *shortname, const char *source); + mpcc_device(const machine_config &mconfig, const char *tag, device_t *owner, uint32_t clock); - mpcc68561_t(const machine_config &mconfig, const char *tag, device_t *owner, uint32_t clock); + template<class _Object> static devcb_base &set_out_txd_callback(device_t &device, _Object object) { return downcast<mpcc_device &>(device).m_out_txd_cb.set_callback(object); } + template<class _Object> static devcb_base &set_out_dtr_callback(device_t &device, _Object object) { return downcast<mpcc_device &>(device).m_out_dtr_cb.set_callback(object); } + template<class _Object> static devcb_base &set_out_rts_callback(device_t &device, _Object object) { return downcast<mpcc_device &>(device).m_out_rts_cb.set_callback(object); } + template<class _Object> static devcb_base &set_out_rtxc_callback(device_t &device, _Object object) { return downcast<mpcc_device &>(device).m_out_rtxc_cb.set_callback(object); } + template<class _Object> static devcb_base &set_out_trxc_callback(device_t &device, _Object object) { return downcast<mpcc_device &>(device).m_out_trxc_cb.set_callback(object); } - template<class _Object> static devcb_base &set_intrq_wr_callback(device_t &device, _Object object) { return downcast<mpcc68561_t &>(device).intrq_cb.set_callback(object); } + template<class _Object> static devcb_base &set_out_int_callback(device_t &device, _Object object) { return downcast<mpcc_device &>(device).m_out_int_cb.set_callback(object); } - uint8_t get_reg_a(int reg); - void set_reg_a(int reg, uint8_t data); + static void configure_clocks(device_t &device, int rxc, int txc) + { + mpcc_device &dev = downcast<mpcc_device &>(device); + dev.m_rxc = rxc; + dev.m_txc = txc; + } - void set_status(int status); + DECLARE_READ8_MEMBER( read ); + DECLARE_WRITE8_MEMBER( write ); - DECLARE_READ8_MEMBER(reg_r); - DECLARE_WRITE8_MEMBER(reg_w); + // interrupt acknowledge + DECLARE_READ8_MEMBER( iack ); + + /* Callbacks to be called by others for signals driven by connected devices */ + DECLARE_WRITE_LINE_MEMBER( write_rx ); + DECLARE_WRITE_LINE_MEMBER( cts_w ); + DECLARE_WRITE_LINE_MEMBER( dsr_w ); + DECLARE_WRITE_LINE_MEMBER( dcd_w ); + DECLARE_WRITE_LINE_MEMBER( rxc_w ) {} // { m_chanA->rxc_w(state); } + DECLARE_WRITE_LINE_MEMBER( txc_w ) {} // { m_chanA->txc_w(state); } protected: + // device-level overrides 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; -private: - struct Chan { - bool txIRQEnable; - bool rxIRQEnable; - bool extIRQEnable; - bool baudIRQEnable; - bool txIRQPending; - bool rxIRQPending; - bool extIRQPending; - bool baudIRQPending; - bool txEnable; - bool rxEnable; - bool txUnderrun; - bool txUnderrunEnable; - bool syncHunt; - bool DCDEnable; - bool CTSEnable; - uint8_t rxData; - uint8_t txData; - - emu_timer *baudtimer; - - uint8_t reg_val[22]; - }; - - int mode; - int reg; - int status; - int IRQV; - int MasterIRQEnable; - int lastIRQStat; - IRQType_t IRQType; - - Chan channel[2]; - - devcb_write_line intrq_cb; - - void updateirqs(); - void initchannel(int ch); - void resetchannel(int ch); - void acknowledge(); - uint8_t getreg(); - void putreg(int ch, uint8_t data); -}; + // device_serial_interface overrides + virtual void tra_callback() override; + virtual void tra_complete() override; + virtual void rcv_callback() override; + virtual void rcv_complete() override; -/*************************************************************************** - MACROS -***************************************************************************/ + // serial device setup helpers + uint32_t get_brg_rate(); + uint32_t get_tx_rate(); + uint32_t get_rx_rate(); + uint32_t get_clock_div(); + uint32_t get_word_length(); + stop_bits_t get_stop_bits(); + parity_t get_parity(); + void update_serial(); + + /* + * Interrupts + */ + void check_interrupts(); + void reset_interrupts(); + void trigger_interrupt(int source); + enum + { + INT_TX_TDRA, // Tx char available + INT_TX_TFC, // Tx frame complete + INT_TX_TUNRN, // Tx underrun detected + INT_TX_TFERR, // Tx frame error detected + INT_RX_RDA, // Rx interrupt on Receiver Data Available + INT_RX_EOF, // Rx interrupt on End of frame + INT_RX_CPERR, // Rx interrupt on CRC or Parity error + INT_RX_FRERR, // Rx interrupt on Frame error + INT_RX_ROVRN, // Rx interrupt on Receiver overrun + INT_RX_RAB, // Rx interrupt on Abort/Break + INT_SR_CTS, // Serial interface interrupt on CTS asserted + INT_SR_DSR, // Serial interface interrupt on DSR asserted + INT_SR_DCD, // Serial interface interrupt on DCD asserted + }; + + enum + { + RX_INT_PRIO = 0x00, // Highest interrupt priority + TX_INT_PRIO = 0x01, + SR_INT_PRIO = 0x02 // Lowest interrupt priority + }; + + enum + { + INT_REQ = 0x01, // Interrupt requested + INT_ACK = 0x02 // Interrupt acknowledged + }; + + // Variants in the MPCC family + enum + { + TYPE_MPCC = 0x001, + TYPE_MPCC68560 = 0x002, + TYPE_MPCC68560A = 0x004, + TYPE_MPCC68561 = 0x008, + TYPE_MPCC68561A = 0x010, + }; + +#define SET_TYPE_A ( mpcc_device::TYPE_MPCC68560A | mpcc_device::TYPE_MPCC68561A ) + + // State variables + int m_variant; + int m_rxc; + int m_txc; + int m_brg_rate; + int m_rcv; + int m_rxd; + int m_tra; + int m_int_state[3]; // Three priority levels Rx, Tx and Serial interface + + // Callbacks + devcb_write_line m_out_txd_cb; + devcb_write_line m_out_dtr_cb; + devcb_write_line m_out_rts_cb; + devcb_write_line m_out_rtxc_cb; + devcb_write_line m_out_trxc_cb; + + devcb_write_line m_out_int_cb; + + /* + * Register handling + */ + // RSR - Rx Status Register + uint8_t m_rsr; + uint8_t do_rsr(); + void do_rsr(uint8_t data); + enum + { + REG_RSR_RDA = 0x80, // Rx Data available + REG_RSR_EOF = 0x40, // End of frame detected (BOP and BSC modes) + REG_RSR_RHW = 0x20, // Odd number of frame data bytes reeived in 16 bit mode. + REG_RSR_CPERR = 0x10, // CRC or parity error detected + REG_RSR_FRERR = 0x08, // Frame error detected + REG_RSR_ROVRN = 0x04, // Rx overrun detected + REG_RSR_RAB = 0x02, // Rx Abort break detected + REG_RSR_RIDLE = 0x01, // Rx idle detcted (15+ high consecutive bits accounted for) + }; + + // RCR - Rx Control Register + uint8_t m_rcr; + uint8_t do_rcr(); + void do_rcr(uint8_t data); + enum + { + REG_RCR_RDSREN = 0x40, // Rx Data Service Request Enable (DMA) + REG_RCR_DONEEN = 0x20, // DONE output enable + REG_RCR_RSYNEN = 0x10, // RSYNEN output enable + REG_RCR_STRSYN = 0x08, // STRIP SYN character (COP mode) + REG_RCR_RABTEN = 0x02, // Receiver Abort Enable (BOP mode) + REG_RCR_RRES = 0x01, // Receiver Reset command/Enable + }; + + uint8_t m_rdr; + uint8_t do_rdr(); + // TODO: investigate if 4 x 16 bit wide FIFO is needed for 16 bit mode + util::fifo<uint8_t, 8> m_rx_data_fifo; + + uint8_t m_rivnr; + + // RIER - Rx Interrupt Enable Register + uint8_t m_rier; + uint8_t do_rier(); + void do_rier(uint8_t data); + enum { + REG_RIER_RDA = 0x80, // Rx interrupt on Receiver Data Available + REG_RIER_EOF = 0x40, // Rx interrupt on End of frame + REG_RIER_CPERR = 0x10, // Rx interrupt on CRC or Parity error + REG_RIER_FRERR = 0x08, // Rx interrupt on Frame error + REG_RIER_ROVRN = 0x04, // Rx interrupt on Receiver overrun + REG_RIER_RAB = 0x02, // Rx interrupt on Abort/Break + }; + + // TSR - Tx Status Register + uint8_t m_tsr; + uint8_t do_tsr(); + void do_tsr(uint8_t data); + enum + { + REG_TSR_TDRA = 0x80, // Tx Fifo Full or not + REG_TSR_TFC = 0x40, // Tx Frame Complete + REG_TSR_TUNRN = 0x04, // Tx underrun + REG_TSR_TFERR = 0x02, // Tx Frame Error + }; + + // TCR - Tx Control Register + uint8_t m_tcr; + uint8_t do_tcr(); + void do_tcr(uint8_t data); + enum + { + REG_TCR_TEN = 0x80, // Tx enable + REG_TCR_TDSREN = 0x40, // DMA enable + REG_TCR_TICS = 0x20, // Tx Idle Char Select, 'A' variant differs + REG_TCR_THW = 0x10, // Indicates that last 16 bit word has only 8 bits, in 16 bits mode only + REG_TCR_TLAST = 0x08, // Indicates the last byte to be written in to TDR (BOP, BCS or COP) + REG_TCR_TSYN = 0x04, // SYN enable (BCS or COP) + REG_TCR_TABT = 0x02, // Abort command (BOP) + REG_TCR_TRES = 0x01, // Tx Reset command + }; + + // TDR - Tx Data Register (write only) + uint8_t m_tdr; + void do_tdr(uint8_t data); + // TODO: investigate if 4 x 16 bit wide FIFO is needed for 16 bit mode + util::fifo<uint8_t, 8> m_tx_data_fifo; + + // TIVNR - Tx Interrupt Vector Number Register + uint8_t m_tivnr; + uint8_t do_tivnr(); + void do_tivnr(uint8_t data); + + // TIER - Tx Interrupt Enable Register + uint8_t m_tier; + uint8_t do_tier(); + void do_tier(uint8_t data); + enum + { + REG_TIER_TDRA = 0x80, // TX Character available interrupt + REG_TIER_TFC = 0x40, // TX Frame complete interrupt + REG_TIER_TUNRN = 0x04, // TX Underrun interrupt + REG_TIER_TFERR = 0x02, // TX Frame error interrupt + }; + + // SISR - Serial Interface Status Register + uint8_t m_sisr; + uint8_t do_sisr(); + void do_sisr(uint8_t data); + enum + { + REG_SISR_CTST = 0x80, // Clear To Send Transition Status + REG_SISR_DSRT = 0x40, // Data Set Ready Transition Status + REG_SISR_DCDT = 0x20, // Data Carrier Detect Transition Status + REG_SISR_CTSLVL = 0x10, // Clear To Send Level + REG_SISR_DSRLVL = 0x08, // Data Set Ready Level + REG_SISR_DCDLVL = 0x04, // Data Carrier Detect Level + }; + + // SICR - Serial Interface Control Register + uint8_t m_sicr; + uint8_t do_sicr(); + void do_sicr(uint8_t data); + enum + { + REG_SICR_RTSLVL = 0x80, // RTS level + REG_SICR_DTRLVL = 0x40, // DTR level + REG_SICR_ECHO = 0x04, // Echo Mode + REG_SICR_TEST = 0x02, // Test Mode + }; + + uint8_t m_sivnr; + // SIER - Serial interface Interrupt Enable + uint8_t m_sier; + uint8_t do_sier(); + void do_sier(uint8_t data); + enum + { + REG_SIER_CTS = 0x80, + REG_SIER_DSR = 0x40, + REG_SIER_DCD = 0x20, + }; + + // PSR1 Protocol Selection Register 1 + uint8_t m_psr1; + uint8_t do_psr1(); + void do_psr1(uint8_t data); + enum + { + REG_PSR1_ADRZ = 0x08, // Zero adress option (BOP) (A models only) + REG_PSR1_IPARS = 0x04, // IPARS option (COP) + REG_PSR1_CTLEX = 0x02, // Control field width 8/16 bit (BOP) (A models only) + REG_PSR1_ADDEX = 0x01, // Address extend option (BOP) (A models only) + }; + + // PSR2 Protocol Selection Register 2 + uint8_t m_psr2; + uint8_t do_psr2(); + void do_psr2(uint8_t data); + enum + { + REG_PSR2_WDBYT = 0x80, // 8/16 bit data bus selector + REG_PSR2_STP_MSK = 0x60, // Stop bits selection field + REG_PSR2_STP_1 = 0x00, // 1 Stop bits + REG_PSR2_STP_1_5 = 0x20, // 1.5 Stop bits + REG_PSR2_STP_2 = 0x40, // 2 Stop bits + REG_PSR2_CHLN_MSK = 0x18, // char len selection field + REG_PSR2_CHLN_5 = 0x00, // 5 bit char len + REG_PSR2_CHLN_6 = 0x08, // 6 bit char len + REG_PSR2_CHLN_7 = 0x10, // 7 bit char len + REG_PSR2_CHLN_8 = 0x18, // 8 bit char len + REG_PSR2_PSEL_MSK = 0x07, // Protocol selection field + REG_PSR2_PSEL_BOPP = 0x00, // Protocol selection BOP Primary + REG_PSR2_PSEL_BOPS = 0x01, // Protocol selection BOP Secondary + REG_PSR2_PSEL_RSV = 0x02, // Protocol selection Reserved + REG_PSR2_PSEL_COP = 0x03, // Protocol selection COP + REG_PSR2_PSEL_BCSE = 0x04, // Protocol selection BCS EBCDIC + REG_PSR2_PSEL_BCSA = 0x05, // Protocol selection BCS ASCII + REG_PSR2_PSEL_ASCII = 0x06, // Protocol selection ASYNC + REG_PSR2_PSEL_ISOC = 0x07, // Protocol selection ISOC + }; + + uint8_t m_ar1; + uint8_t m_ar2; + + + // BRDR1 - Baud Rate Divisor Register 1 (Lo) + uint8_t m_brdr1; + uint8_t do_brdr1(); + void do_brdr1(uint8_t data); + + // BRDR2 - Baud Rate Divisor Register 2 (Hi) + uint8_t m_brdr2; + uint8_t do_brdr2(); + void do_brdr2(uint8_t data); + + // CCR - Clock Control Register + uint8_t m_ccr; + uint8_t do_ccr(); + void do_ccr(uint8_t data); + enum + { + REG_CCR_PSCDIV = 0x10, // Internal prescaler Divider x2 or x3 + REG_CCR_TCLO = 0x08, // TxC input/output selection + REG_CCR_RCLKIN = 0x04, // RxC from internal/external source selection + REG_CCR_CLKDIV_MSK = 0x03, // External RxC prescaler Divider + REG_CCR_CLKDIV_X1 = 0x00, // x1 - ISOC only + REG_CCR_CLKDIV_X16 = 0x01, // x16 - ASYNC only + REG_CCR_CLKDIV_X32 = 0x02, // x32 - ASYNC only + REG_CCR_CLKDIV_X64 = 0x03, // x64 - ASYNC only + }; + + // ECR - Error Control Regsiter + uint8_t m_ecr; + uint8_t do_ecr(); + void do_ecr(uint8_t data); + enum + { + REG_ECR_PAREN = 0x80, // Parity Enable + REG_ECR_ODDPAR = 0x40, // Odd/Even Parity + REG_ECR_CFCRC = 0x08, // CRC Enable + REG_ECR_CRCPRE = 0x04, // CRC Preset 0 (BSC) or 1 (BOP) + REG_ECR_CRCSEL_MSK = 0x03, // CRC Polynominal Selection Mask + REG_ECR_CRCSEL_V41 = 0x00, // CCITT V.41 (BOP) CRC Polynomial + REG_ECR_CRCSEL_C16 = 0x01, // CRC-16 (BSC) CRC Polynomial + REG_ECR_CRCSEL_VRC = 0x02, // VRC/LRC (BSC, ASCII, non-transp) CRC Polynomial + }; + +}; + +// device type definition +extern const device_type MPCC; +extern const device_type MPCC68560; +extern const device_type MPCC68560A; extern const device_type MPCC68561; +extern const device_type MPCC68561A; + +class mpcc68560_device : public mpcc_device { public : mpcc68560_device(const machine_config &mconfig, const char *tag, device_t *owner, uint32_t clock); }; +class mpcc68560A_device : public mpcc_device { public : mpcc68560A_device(const machine_config &mconfig, const char *tag, device_t *owner, uint32_t clock); }; +class mpcc68561_device : public mpcc_device { public : mpcc68561_device(const machine_config &mconfig, const char *tag, device_t *owner, uint32_t clock); }; +class mpcc68561A_device : public mpcc_device { public : mpcc68561A_device(const machine_config &mconfig, const char *tag, device_t *owner, uint32_t clock); }; -#endif /* __68561MPCC_H__ */ +#endif // MPCC68561_H diff --git a/src/devices/machine/i8251.cpp b/src/devices/machine/i8251.cpp index 2fc9ef798b6..2c33c6decb3 100644 --- a/src/devices/machine/i8251.cpp +++ b/src/devices/machine/i8251.cpp @@ -24,7 +24,7 @@ #define VERBOSE 0 -#define LOG(x) do { if (VERBOSE) logerror x; } while (0) +#define LOG(...) do { if (VERBOSE) logerror(__VA_ARGS__); } while (0) //************************************************************************** // DEVICE DEFINITIONS @@ -33,12 +33,26 @@ const device_type I8251 = &device_creator<i8251_device>; const device_type V53_SCU = &device_creator<v53_scu_device>; +template class device_finder<i8251_device, false>; +template class device_finder<i8251_device, true>; +template class device_finder<v53_scu_device, false>; +template class device_finder<v53_scu_device, true>; + + //------------------------------------------------- // i8251_device - constructor //------------------------------------------------- -i8251_device::i8251_device(const machine_config &mconfig, device_type type, const char *name, const char *tag, device_t *owner, uint32_t clock, const char *shortname) - : device_t(mconfig, type, name, tag, owner, clock, shortname, __FILE__), +i8251_device::i8251_device( + const machine_config &mconfig, + device_type type, + const char *name, + const char *tag, + device_t *owner, + uint32_t clock, + const char *shortname, + const char *source) + : device_t(mconfig, type, name, tag, owner, clock, shortname, source), device_serial_interface(mconfig, *this), m_txd_handler(*this), m_dtr_handler(*this), @@ -56,25 +70,12 @@ i8251_device::i8251_device(const machine_config &mconfig, device_type type, cons } i8251_device::i8251_device(const machine_config &mconfig, const char *tag, device_t *owner, uint32_t clock) - : device_t(mconfig, I8251, "8251 USART", tag, owner, clock, "i8251", __FILE__), - device_serial_interface(mconfig, *this), - m_txd_handler(*this), - m_dtr_handler(*this), - m_rts_handler(*this), - m_rxrdy_handler(*this), - m_txrdy_handler(*this), - m_txempty_handler(*this), - m_syndet_handler(*this), - m_cts(1), - m_dsr(1), - m_rxd(0), - m_rxc(0), - m_txc(0) + : i8251_device(mconfig, I8251, "8251 USART", tag, owner, clock, "i8251", __FILE__) { } v53_scu_device::v53_scu_device(const machine_config &mconfig, const char *tag, device_t *owner, uint32_t clock) - : i8251_device(mconfig, V53_SCU, "V53 SCU", tag, owner, clock, "v53_scu") + : i8251_device(mconfig, V53_SCU, "V53 SCU", tag, owner, clock, "v53_scu", __FILE__) { } @@ -121,15 +122,11 @@ void i8251_device::device_start() void i8251_device::update_rx_ready() { - int state; - - state = m_status & I8251_STATUS_RX_READY; + int state = m_status & I8251_STATUS_RX_READY; - /* masked? */ - if ((m_command & (1<<2))==0) - { + // masked? + if (!BIT(m_command, 2)) state = 0; - } m_rxrdy_handler(state != 0); } @@ -142,19 +139,22 @@ void i8251_device::update_rx_ready() void i8251_device::receive_clock() { - m_rxc_count++; - - if (m_rxc_count == m_br_factor) - m_rxc_count = 0; - else - return; - /* receive enable? */ - if (m_command & (1<<2)) + if (BIT(m_command, 2)) { + const bool sync = is_receive_register_synchronized(); + if (sync) + { + --m_rxc_count; + if (m_rxc_count) + return; + } + //logerror("I8251\n"); /* get bit received from other side and update receive register */ receive_register_update_bit(m_rxd); + if (is_receive_register_synchronized()) + m_rxc_count = sync ? m_br_factor : (3 * m_br_factor / 2); if (is_receive_register_full()) { @@ -167,25 +167,24 @@ void i8251_device::receive_clock() /*------------------------------------------------- is_tx_enabled -------------------------------------------------*/ -bool i8251_device::is_tx_enabled(void) const +bool i8251_device::is_tx_enabled() const { - return BIT(m_command , 0) != 0 && m_cts == 0; + return BIT(m_command , 0) && !m_cts; } /*------------------------------------------------- check_for_tx_start -------------------------------------------------*/ -void i8251_device::check_for_tx_start(void) +void i8251_device::check_for_tx_start() { - if (is_tx_enabled() && (m_status & (I8251_STATUS_TX_EMPTY | I8251_STATUS_TX_READY)) == I8251_STATUS_TX_EMPTY) { - start_tx(); - } + if (is_tx_enabled() && (m_status & (I8251_STATUS_TX_EMPTY | I8251_STATUS_TX_READY)) == I8251_STATUS_TX_EMPTY) + start_tx(); } /*------------------------------------------------- start_tx -------------------------------------------------*/ -void i8251_device::start_tx(void) +void i8251_device::start_tx() { transmit_register_setup(m_tx_data); m_status &= ~I8251_STATUS_TX_EMPTY; @@ -199,23 +198,25 @@ void i8251_device::start_tx(void) void i8251_device::transmit_clock() { m_txc_count++; - - if (m_txc_count == m_br_factor) - m_txc_count = 0; - else + if (m_txc_count != m_br_factor) return; - if (is_transmit_register_empty()) { - if ((m_status & I8251_STATUS_TX_READY) == 0 && (is_tx_enabled() || (m_flags & I8251_DELAYED_TX_EN) != 0)) { + m_txc_count = 0; + + if (is_transmit_register_empty()) + { + if ((m_status & I8251_STATUS_TX_READY) == 0 && (is_tx_enabled() || (m_flags & I8251_DELAYED_TX_EN) != 0)) start_tx(); - } else { + else m_status |= I8251_STATUS_TX_EMPTY; - } + update_tx_ready(); update_tx_empty(); } + /* if diserial has bits to send, make them so */ - if (!is_transmit_register_empty()) { + if (!is_transmit_register_empty()) + { uint8_t data = transmit_register_get_data_bit(); m_txd_handler(data); } @@ -223,7 +224,7 @@ void i8251_device::transmit_clock() #if 0 /* hunt mode? */ /* after each bit has been shifted in, it is compared against the current sync byte */ - if (m_command & (1<<7)) + if (BIT(m_command, 7)) { /* data matches sync byte? */ if (m_data == m_sync_bytes[m_sync_byte_offset]) @@ -236,7 +237,7 @@ void i8251_device::transmit_clock() if (m_sync_byte_offset == m_sync_byte_count) { /* ent hunt mode */ - m_command &=~(1<<7); + m_command &= ~(1<<7); } } else @@ -295,7 +296,7 @@ void i8251_device::update_tx_empty() void i8251_device::device_reset() { - LOG(("I8251: Reset\n")); + LOG("I8251: Reset\n"); /* what is the default setup when the 8251 has been reset??? */ @@ -342,52 +343,34 @@ void i8251_device::device_reset() WRITE8_MEMBER(i8251_device::command_w) { /* command */ - LOG(("I8251: Command byte\n")); + LOG("I8251: Command byte\n"); m_command = data; - LOG(("Command byte: %02x\n", data)); + LOG("Command byte: %02x\n", data); - if (data & (1<<7)) - { - LOG(("hunt mode\n")); - } + if (BIT(data, 7)) + LOG("hunt mode\n"); - if (data & (1<<5)) - { - LOG(("/rts set to 0\n")); - } + if (BIT(data, 5)) + LOG("/rts set to 0\n"); else - { - LOG(("/rts set to 1\n")); - } + LOG("/rts set to 1\n"); - if (data & (1<<2)) - { - LOG(("receive enable\n")); - } + if (BIT(data, 2)) + LOG("receive enable\n"); else - { - LOG(("receive disable\n")); - } + LOG("receive disable\n"); - if (data & (1<<1)) - { - LOG(("/dtr set to 0\n")); - } + if (BIT(data, 1)) + LOG("/dtr set to 0\n"); else - { - LOG(("/dtr set to 1\n")); - } + LOG("/dtr set to 1\n"); - if (data & (1<<0)) - { - LOG(("transmit enable\n")); - } + if (BIT(data, 0)) + LOG("transmit enable\n"); else - { - LOG(("transmit disable\n")); - } + LOG("transmit disable\n"); /* bit 7: @@ -419,12 +402,10 @@ WRITE8_MEMBER(i8251_device::command_w) m_rts_handler(!BIT(data, 5)); m_dtr_handler(!BIT(data, 1)); - if (data & (1<<4)) - { + if (BIT(data, 4)) m_status &= ~(I8251_STATUS_PARITY_ERROR | I8251_STATUS_OVERRUN_ERROR | I8251_STATUS_FRAMING_ERROR); - } - if (data & (1<<6)) + if (BIT(data, 6)) { // datasheet says "returns to mode format", not // completely resets the chip. behavior of DEC Rainbow @@ -432,15 +413,15 @@ WRITE8_MEMBER(i8251_device::command_w) m_flags |= I8251_EXPECTING_MODE; } - check_for_tx_start(); + check_for_tx_start(); update_rx_ready(); update_tx_ready(); - update_tx_empty(); + update_tx_empty(); } WRITE8_MEMBER(i8251_device::mode_w) { - LOG(("I8251: Mode byte\n")); + LOG("I8251: Mode byte = %X\n", data); m_mode_byte = data; @@ -472,60 +453,56 @@ WRITE8_MEMBER(i8251_device::mode_w) 3 = x64 */ - LOG(("I8251: Asynchronous operation\n")); + LOG("I8251: Asynchronous operation\n"); - LOG(("Character length: %d\n", (((data >> 2) & 0x03) + 5))); + const int data_bits_count = ((data >> 2) & 0x03) + 5; + LOG("Character length: %d\n", data_bits_count); parity_t parity; - - if (data & (1 << 4)) + if (BIT(data, 4)) { - LOG(("enable parity checking\n")); - - if (data & (1 << 5)) + if (BIT(data, 5)) { - LOG(("even parity\n")); + LOG("enable parity checking (even parity)\n"); parity = PARITY_EVEN; } else { - LOG(("odd parity\n")); + LOG("enable parity checking (odd parity)\n"); parity = PARITY_ODD; } } else { - LOG(("parity check disabled\n")); + LOG("parity check disabled\n"); parity = PARITY_NONE; } stop_bits_t stop_bits; - switch ((data >> 6) & 0x03) { case 0: default: stop_bits = STOP_BITS_0; - LOG(("stop bit: inhibit\n")); + LOG("stop bit: inhibit\n"); break; case 1: stop_bits = STOP_BITS_1; - LOG(("stop bit: 1 bit\n")); + LOG("stop bit: 1 bit\n"); break; case 2: stop_bits = STOP_BITS_1_5; - LOG(("stop bit: 1.5 bits\n")); + LOG("stop bit: 1.5 bits\n"); break; case 3: stop_bits = STOP_BITS_2; - LOG(("stop bit: 2 bits\n")); + LOG("stop bit: 2 bits\n"); break; } - int data_bits_count = ((data >> 2) & 0x03) + 5; set_data_frame(1, data_bits_count, parity, stop_bits); receive_register_reset(); @@ -537,13 +514,13 @@ WRITE8_MEMBER(i8251_device::mode_w) case 3: m_br_factor = 64; break; } - m_rxc_count = m_txc_count = 0; + m_txc_count = 0; #if 0 /* data bits */ m_receive_char_length = (((data >> 2) & 0x03) + 5); - if (data & (1 << 4)) + if (BIT(data, 4)) { /* parity */ m_receive_char_length++; @@ -580,7 +557,7 @@ WRITE8_MEMBER(i8251_device::mode_w) 3 = 8 bits bit 1,0 = 0 */ - LOG(("I8251: Synchronous operation\n")); + LOG("I8251: Synchronous operation\n"); /* setup for sync byte(s) */ m_flags |= I8251_EXPECTING_SYNC_BYTE; @@ -603,9 +580,9 @@ WRITE8_MEMBER(i8251_device::control_w) { if (m_flags & I8251_EXPECTING_SYNC_BYTE) { - LOG(("I8251: Sync byte\n")); + LOG("I8251: Sync byte\n"); - LOG(("Sync byte: %02x\n", data)); + LOG("Sync byte: %02x\n", data); /* store sync byte written */ m_sync_bytes[m_sync_byte_offset] = data; m_sync_byte_offset++; @@ -639,7 +616,7 @@ READ8_MEMBER(i8251_device::status_r) { uint8_t status = (m_dsr << 7) | m_status; - LOG(("status: %02x\n", status)); + LOG("status: %02x\n", status); return status; } @@ -653,7 +630,7 @@ WRITE8_MEMBER(i8251_device::data_w) { m_tx_data = data; - LOG(("data_w %02x\n" , data)); + LOG("data_w %02x\n" , data); /* writing clears */ m_status &=~I8251_STATUS_TX_READY; @@ -687,9 +664,8 @@ void i8251_device::receive_character(uint8_t ch) /* char has not been read and another has arrived! */ if (m_status & I8251_STATUS_RX_READY) - { m_status |= I8251_STATUS_OVERRUN_ERROR; - } + m_status |= I8251_STATUS_RX_READY; update_rx_ready(); @@ -703,7 +679,7 @@ void i8251_device::receive_character(uint8_t ch) READ8_MEMBER(i8251_device::data_r) { - LOG(("read data: %02x, STATUS=%02x\n",m_rx_data,m_status)); + LOG("read data: %02x, STATUS=%02x\n",m_rx_data,m_status); /* reading clears */ m_status &= ~I8251_STATUS_RX_READY; @@ -728,9 +704,9 @@ WRITE_LINE_MEMBER(i8251_device::write_cts) { m_cts = state; - check_for_tx_start(); - update_tx_ready(); - update_tx_empty(); + check_for_tx_start(); + update_tx_ready(); + update_tx_empty(); } WRITE_LINE_MEMBER(i8251_device::write_dsr) diff --git a/src/devices/machine/i8251.h b/src/devices/machine/i8251.h index a556851beb7..82659caed11 100644 --- a/src/devices/machine/i8251.h +++ b/src/devices/machine/i8251.h @@ -8,8 +8,8 @@ *********************************************************************/ -#ifndef __I8251_H__ -#define __I8251_H__ +#ifndef MAME_DEVICES_MACHINE_I8251_H +#define MAME_DEVICES_MACHINE_I8251_H //************************************************************************** @@ -42,7 +42,6 @@ class i8251_device : public device_t, { public: // construction/destruction - i8251_device(const machine_config &mconfig, device_type type, const char *name, const char *tag, device_t *owner, uint32_t clock, const char *shortname); i8251_device(const machine_config &mconfig, const char *tag, device_t *owner, uint32_t clock); // static configuration helpers @@ -82,6 +81,16 @@ public: }; protected: + i8251_device( + const machine_config &mconfig, + device_type type, + const char *name, + const char *tag, + device_t *owner, + uint32_t clock, + const char *shortname, + const char *source); + // device-level overrides virtual void device_start() override; virtual void device_reset() override; @@ -92,9 +101,9 @@ protected: void update_tx_empty(); void transmit_clock(); void receive_clock(); - bool is_tx_enabled(void) const; - void check_for_tx_start(void); - void start_tx(void); + bool is_tx_enabled() const; + void check_for_tx_start(); + void start_tx(); enum @@ -155,5 +164,10 @@ public: extern const device_type I8251; extern const device_type V53_SCU; +extern template class device_finder<i8251_device, false>; +extern template class device_finder<i8251_device, true>; +extern template class device_finder<v53_scu_device, false>; +extern template class device_finder<v53_scu_device, true>; + -#endif /* __I8251_H__ */ +#endif // MAME_DEVICES_MACHINE_I8251_H diff --git a/src/devices/machine/z80scc.cpp b/src/devices/machine/z80scc.cpp index c08026c95c3..f81ab259fa1 100644 --- a/src/devices/machine/z80scc.cpp +++ b/src/devices/machine/z80scc.cpp @@ -1,4 +1,5 @@ -// license:BSD-3-Clause copyright-holders: Joakim Larsson Edstrom +// license:BSD-3-Clause +// copyright-holders: Joakim Larsson Edstrom /*************************************************************************** Z80-SCC Serial Communications Controller emulation @@ -72,41 +73,40 @@ DONE (x) (p=partly) NMOS CMOS ESCC EMSCC #include "z80scc.h" + //************************************************************************** -// MACROS / CONSTANTS +// CONFIGURABLE LOGGING //************************************************************************** -#define LOG_GENERAL 0x001 -#define LOG_SETUP 0x002 -#define LOG_PRINTF 0x004 -#define LOG_READ 0x008 -#define LOG_INT 0x010 -#define LOG_CMD 0x020 -#define LOG_TX 0x040 -#define LOG_RCV 0x080 -#define LOG_CTS 0x100 -#define LOG_DCD 0x200 -#define LOG_SYNC 0x400 - -#define VERBOSE 0 // (LOG_PRINTF | LOG_SETUP | LOG_GENERAL) - -#define LOGMASK(mask, ...) do { if (VERBOSE & mask) logerror(__VA_ARGS__); } while (0) -#define LOGLEVEL(mask, level, ...) do { if ((VERBOSE & mask) >= level) logerror(__VA_ARGS__); } while (0) - -#define LOG(...) LOGMASK(LOG_GENERAL, __VA_ARGS__) -#define LOGSETUP(...) LOGMASK(LOG_SETUP, __VA_ARGS__) -#define LOGR(...) LOGMASK(LOG_READ, __VA_ARGS__) -#define LOGINT(...) LOGMASK(LOG_INT, __VA_ARGS__) -#define LOGCMD(...) LOGMASK(LOG_CMD, __VA_ARGS__) -#define LOGTX(...) LOGMASK(LOG_TX, __VA_ARGS__) -#define LOGRCV(...) LOGMASK(LOG_RCV, __VA_ARGS__) -#define LOGCTS(...) LOGMASK(LOG_CTS, __VA_ARGS__) -#define LOGDCD(...) LOGMASK(LOG_DCD, __VA_ARGS__) -#define LOGSYNC(...) LOGMASK(LOG_SYNC, __VA_ARGS__) - -#if VERBOSE & LOG_PRINTF -#define logerror printf -#endif +#define LOG_SETUP (1U << 1) +#define LOG_PRINTF (1U << 2) +#define LOG_READ (1U << 3) +#define LOG_INT (1U << 4) +#define LOG_CMD (1U << 5) +#define LOG_TX (1U << 6) +#define LOG_RCV (1U << 7) +#define LOG_CTS (1U << 8) +#define LOG_DCD (1U << 9) +#define LOG_SYNC (1U << 10) + +//#define VERBOSE (LOG_GENERAL | LOG_SETUP) +//#define LOG_OUTPUT_FUNC printf +#include "logmacro.h" + +#define LOGSETUP(...) LOGMASKED(LOG_SETUP, __VA_ARGS__) +#define LOGR(...) LOGMASKED(LOG_READ, __VA_ARGS__) +#define LOGINT(...) LOGMASKED(LOG_INT, __VA_ARGS__) +#define LOGCMD(...) LOGMASKED(LOG_CMD, __VA_ARGS__) +#define LOGTX(...) LOGMASKED(LOG_TX, __VA_ARGS__) +#define LOGRCV(...) LOGMASKED(LOG_RCV, __VA_ARGS__) +#define LOGCTS(...) LOGMASKED(LOG_CTS, __VA_ARGS__) +#define LOGDCD(...) LOGMASKED(LOG_DCD, __VA_ARGS__) +#define LOGSYNC(...) LOGMASKED(LOG_SYNC, __VA_ARGS__) + + +//************************************************************************** +// MACROS / CONSTANTS +//************************************************************************** #ifdef _MSC_VER #define FUNCNAME __func__ diff --git a/src/devices/sound/msm5205.cpp b/src/devices/sound/msm5205.cpp index 845e10737ac..9d84cae1dd4 100644 --- a/src/devices/sound/msm5205.cpp +++ b/src/devices/sound/msm5205.cpp @@ -61,28 +61,23 @@ const device_type MSM6585 = &device_creator<msm6585_device>; msm5205_device::msm5205_device(const machine_config &mconfig, const char *tag, device_t *owner, u32 clock) - : device_t(mconfig, MSM5205, "MSM5205", tag, owner, clock, "msm5205", __FILE__), - device_sound_interface(mconfig, *this), - m_s1(false), - m_s2(false), - m_bitwidth(4), - m_vclk_cb(*this) + : msm5205_device(mconfig, MSM5205, "MSM5205", tag, owner, clock, "msm5205", __FILE__) { } msm5205_device::msm5205_device(const machine_config &mconfig, device_type type, const char *name, const char *tag, device_t *owner, u32 clock, const char *shortname, const char *source) - : device_t(mconfig, type, name, tag, owner, clock, shortname, source), - device_sound_interface(mconfig, *this), - m_s1(false), - m_s2(false), - m_bitwidth(4), - m_vclk_cb(*this) + : device_t(mconfig, type, name, tag, owner, clock, shortname, source), + device_sound_interface(mconfig, *this), + m_s1(false), + m_s2(false), + m_bitwidth(4), + m_vclk_cb(*this) { } msm6585_device::msm6585_device(const machine_config &mconfig, const char *tag, device_t *owner, u32 clock) - : msm5205_device(mconfig, MSM6585, "MSM6585", tag, owner, clock, "msm6585", __FILE__) + : msm5205_device(mconfig, MSM6585, "MSM6585", tag, owner, clock, "msm6585", __FILE__) { } diff --git a/src/emu/debug/debugcmd.cpp b/src/emu/debug/debugcmd.cpp index 5469670caa6..cc6738ee9f6 100644 --- a/src/emu/debug/debugcmd.cpp +++ b/src/emu/debug/debugcmd.cpp @@ -136,6 +136,7 @@ debugger_commands::debugger_commands(running_machine& machine, debugger_cpu& cpu m_console.register_command("printf", CMDFLAG_NONE, 0, 1, MAX_COMMAND_PARAMS, std::bind(&debugger_commands::execute_printf, this, _1, _2, _3)); m_console.register_command("logerror", CMDFLAG_NONE, 0, 1, MAX_COMMAND_PARAMS, std::bind(&debugger_commands::execute_logerror, this, _1, _2, _3)); m_console.register_command("tracelog", CMDFLAG_NONE, 0, 1, MAX_COMMAND_PARAMS, std::bind(&debugger_commands::execute_tracelog, this, _1, _2, _3)); + m_console.register_command("tracesym", CMDFLAG_NONE, 0, 1, MAX_COMMAND_PARAMS, std::bind(&debugger_commands::execute_tracesym, this, _1, _2, _3)); m_console.register_command("quit", CMDFLAG_NONE, 0, 0, 0, std::bind(&debugger_commands::execute_quit, this, _1, _2, _3)); m_console.register_command("exit", CMDFLAG_NONE, 0, 0, 0, std::bind(&debugger_commands::execute_quit, this, _1, _2, _3)); m_console.register_command("do", CMDFLAG_NONE, 0, 1, 1, std::bind(&debugger_commands::execute_do, this, _1, _2, _3)); @@ -725,6 +726,42 @@ void debugger_commands::execute_tracelog(int ref, int params, const char *param[ /*------------------------------------------------- + execute_tracesym - execute the tracesym command +-------------------------------------------------*/ + +void debugger_commands::execute_tracesym(int ref, int params, const char *param[]) +{ + // build a format string appropriate for the parameters and validate them + std::stringstream format; + u64 values[MAX_COMMAND_PARAMS]; + for (int i = 0; i < params; i++) + { + // find this symbol + symbol_entry *sym = m_cpu.get_visible_symtable()->find(param[i]); + if (!sym) + { + m_console.printf("Unknown symbol: %s\n", param[i]); + return; + } + + // build the format string + util::stream_format(format, "%s=%s ", + param[i], + sym->format().empty() ? "%16X" : sym->format()); + + // validate the parameter + if (!validate_number_parameter(param[i], &values[i])) + return; + } + + // then do a printf + char buffer[1024]; + if (mini_printf(buffer, format.str().c_str(), params, values)) + m_cpu.get_visible_cpu()->debug()->trace_printf("%s", buffer); +} + + +/*------------------------------------------------- execute_quit - execute the quit command -------------------------------------------------*/ @@ -2496,6 +2533,7 @@ void debugger_commands::execute_trace_internal(int ref, int params, const char * { const char *action = nullptr; bool detect_loops = true; + bool logerror = false; device_t *cpu; FILE *f = nullptr; const char *mode; @@ -2507,8 +2545,25 @@ void debugger_commands::execute_trace_internal(int ref, int params, const char * /* validate parameters */ if (!validate_cpu_parameter((params > 1) ? param[1] : nullptr, &cpu)) return; - if (!validate_boolean_parameter((params > 2) ? param[2] : nullptr, &detect_loops)) - return; + if (params > 2) + { + std::stringstream stream; + stream.str(param[2]); + + std::string flag; + while (std::getline(stream, flag, '|')) + { + if (!core_stricmp(flag.c_str(), "noloop")) + detect_loops = false; + else if (!core_stricmp(flag.c_str(), "logerror")) + logerror = true; + else + { + m_console.printf("Invalid flag '%s'\n", flag.c_str()); + return; + } + } + } if (!debug_command_parameter_command(action = (params > 3) ? param[3] : nullptr)) return; @@ -2533,7 +2588,7 @@ void debugger_commands::execute_trace_internal(int ref, int params, const char * } /* do it */ - cpu->debug()->trace(f, trace_over, detect_loops, action); + cpu->debug()->trace(f, trace_over, detect_loops, logerror, action); if (f) m_console.printf("Tracing CPU '%s' to file %s\n", cpu->tag(), filename.c_str()); else diff --git a/src/emu/debug/debugcmd.h b/src/emu/debug/debugcmd.h index ac57622abd5..02e8ceb5299 100644 --- a/src/emu/debug/debugcmd.h +++ b/src/emu/debug/debugcmd.h @@ -98,6 +98,7 @@ private: void execute_printf(int ref, int params, const char **param); void execute_logerror(int ref, int params, const char **param); void execute_tracelog(int ref, int params, const char **param); + void execute_tracesym(int ref, int params, const char **param); void execute_quit(int ref, int params, const char **param); void execute_do(int ref, int params, const char **param); void execute_step(int ref, int params, const char **param); diff --git a/src/emu/debug/debugcpu.cpp b/src/emu/debug/debugcpu.cpp index 98fa6c9f038..178f4cf7f32 100644 --- a/src/emu/debug/debugcpu.cpp +++ b/src/emu/debug/debugcpu.cpp @@ -1668,10 +1668,10 @@ device_debug::device_debug(device_t &device) // add all registers into it std::string tempstr; - for (auto &entry : m_state->state_entries()) + for (const auto &entry : m_state->state_entries()) { strmakelower(tempstr.assign(entry->symbol())); - m_symtable.add(tempstr.c_str(), (void *)(uintptr_t)entry->index(), get_state, set_state); + m_symtable.add(tempstr.c_str(), (void *)(uintptr_t)entry->index(), get_state, set_state, entry->format_string()); } } @@ -1684,6 +1684,10 @@ device_debug::device_debug(device_t &device) if (m_state != nullptr && m_symtable.find("curpc") == nullptr) m_symtable.add("curpc", nullptr, get_current_pc); } + + // set up trace + using namespace std::placeholders; + m_device.machine().add_logerror_callback(std::bind(&device_debug::errorlog_write_line, this, _1)); } @@ -2623,14 +2627,14 @@ u32 device_debug::compute_opcode_crc32(offs_t pc) const // trace - trace execution of a given device //------------------------------------------------- -void device_debug::trace(FILE *file, bool trace_over, bool detect_loops, const char *action) +void device_debug::trace(FILE *file, bool trace_over, bool detect_loops, bool logerror, const char *action) { // delete any existing tracers m_trace = nullptr; // if we have a new file, make a new tracer if (file != nullptr) - m_trace = std::make_unique<tracer>(*this, *file, trace_over, detect_loops, action); + m_trace = std::make_unique<tracer>(*this, *file, trace_over, detect_loops, logerror, action); } @@ -3291,11 +3295,12 @@ bool device_debug::registerpoint::hit() // tracer - constructor //------------------------------------------------- -device_debug::tracer::tracer(device_debug &debug, FILE &file, bool trace_over, bool detect_loops, const char *action) +device_debug::tracer::tracer(device_debug &debug, FILE &file, bool trace_over, bool detect_loops, bool logerror, const char *action) : m_debug(debug) , m_file(file) , m_action((action != nullptr) ? action : "") , m_detect_loops(detect_loops) + , m_logerror(logerror) , m_loops(0) , m_nextdex(0) , m_trace_over(trace_over) @@ -3447,3 +3452,14 @@ device_debug::dasm_comment::dasm_comment(offs_t address, u32 crc, const char *te m_color(std::move(color)) { } + + +//------------------------------------------------- +// dasm_comment - constructor +//------------------------------------------------- + +void device_debug::errorlog_write_line(const char *line) +{ + if (m_trace && m_trace->logerror()) + trace_printf("%s", line); +}
\ No newline at end of file diff --git a/src/emu/debug/debugcpu.h b/src/emu/debug/debugcpu.h index c01cc0e0646..383940c21cb 100644 --- a/src/emu/debug/debugcpu.h +++ b/src/emu/debug/debugcpu.h @@ -263,7 +263,7 @@ public: void track_mem_data_clear() { m_track_mem_set.clear(); } // tracing - void trace(FILE *file, bool trace_over, bool detect_loops, const char *action); + void trace(FILE *file, bool trace_over, bool detect_loops, bool logerror, const char *action); void trace_printf(const char *fmt, ...) ATTR_PRINTF(2,3); void trace_flush() { if (m_trace != nullptr) m_trace->flush(); } @@ -280,6 +280,7 @@ 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 void breakpoint_update_flags(); @@ -336,12 +337,13 @@ private: class tracer { public: - tracer(device_debug &debug, FILE &file, bool trace_over, bool detect_loops, const char *action); + tracer(device_debug &debug, FILE &file, bool trace_over, bool detect_loops, bool logerror, const char *action); ~tracer(); void update(offs_t pc); void vprintf(const char *format, va_list va); void flush(); + bool logerror() const { return m_logerror; } private: static const int TRACE_LOOPS = 64; @@ -351,6 +353,7 @@ private: std::string m_action; // action to perform during a trace offs_t m_history[TRACE_LOOPS]; // history of recent PCs bool m_detect_loops; // whether or not we should detect loops + bool m_logerror; // whether or not we should collect logerror output int m_loops; // number of instructions in a loop int m_nextdex; // next index bool m_trace_over; // true if we're tracing over diff --git a/src/emu/debug/debughlp.cpp b/src/emu/debug/debughlp.cpp index ded8cafb993..dd46472abb2 100644 --- a/src/emu/debug/debughlp.cpp +++ b/src/emu/debug/debughlp.cpp @@ -86,6 +86,7 @@ static const help_item static_help_list[] = " printf <format>[,<item>[,...]] -- prints one or more <item>s to the console using <format>\n" " logerror <format>[,<item>[,...]] -- outputs one or more <item>s to the error.log\n" " tracelog <format>[,<item>[,...]] -- outputs one or more <item>s to the trace file using <format>\n" + " tracesym <item>[,...]] -- outputs one or more <item>s to the trace file\n" " history [<cpu>,<length>] -- outputs a brief history of visited opcodes\n" " trackpc [<bool>,<cpu>,<bool>] -- visually track visited opcodes [boolean to turn on and off, for the given cpu, clear]\n" " trackmem [<bool>,<bool>] -- record which PC writes to each memory address [boolean to turn on and off, clear]\n" @@ -385,6 +386,22 @@ static const help_item static_help_list[] = " Outputs A=<aval>, B=<bval> on one line, and C=<a+bval> on a second line.\n" }, { + "tracesym", + "\n" + " tracesym <item>[,...]\n" + "\n" + "The tracesym command prints the specified symbols and routes the output to the currently open trace " + "file (see the 'trace' command for details). If no file is currently open, tracesym does nothing. " + "\n" + "Examples:\n" + "\n" + "tracelog pc\n" + " Outputs PC=<pcval> where <pcval> is displayed in the default format.\n" + "\n" + "printf a,b\n" + " Outputs A=<aval>, B=<bval> on one line.\n" + }, + { "trackpc", "\n" " trackpc [<bool>,<cpu>,<bool>]\n" @@ -818,14 +835,15 @@ static const help_item static_help_list[] = { "trace", "\n" - " trace {<filename>|OFF}[,<cpu>[,<detectloops>[,<action>]]]\n" + " trace {<filename>|OFF}[,<cpu>[,[noloop|logerror][,<action>]]]\n" "\n" "Starts or stops tracing of the execution of the specified <cpu>. If <cpu> is omitted, " "the currently active CPU is specified. When enabling tracing, specify the filename in the " "<filename> parameter. To disable tracing, substitute the keyword 'off' for <filename>. " - "<detectloops> should be either true or false. If <detectloops> is true or omitted, the trace " - "will have loops detected and condensed to a single line. If it is false, the trace will contain " - "every opcode as it is executed. If you " + "<detectloops> should be either true or false. If 'noloop' is omitted, the trace " + "will have loops detected and condensed to a single line. If 'noloop' is specified, the trace " + "will contain every opcode as it is executed. If 'logerror' is specified, logerror output " + "will augment the trace. If you " "wish to log additional information on each trace, you can append an <action> parameter which " "is a command that is executed before each trace is logged. Generally, this is used to include " "a 'tracelog' command. Note that you may need to embed the action within braces { } in order " @@ -840,16 +858,22 @@ static const help_item static_help_list[] = "trace dribling.tr,0\n" " Begin tracing the execution of CPU #0, logging output to dribling.tr.\n" "\n" - "trace starswep.tr,0,false\n" + "trace starswep.tr,0,noloop\n" " Begin tracing the execution of CPU #0, logging output to starswep.tr, with loop detection disabled.\n" "\n" + "trace starswep.tr,0,logerror\n" + " Begin tracing the execution of CPU #0, logging output (along with logerror output) to starswep.tr.\n" + "\n" + "trace starswep.tr,0,logerror|noloop\n" + " Begin tracing the execution of CPU #0, logging output (along with logerror output) to starswep.tr, with loop detection disabled.\n" + "\n" "trace >>pigskin.tr\n" " Begin tracing the currently active CPU, appending log output to pigskin.tr.\n" "\n" "trace off,0\n" " Turn off tracing on CPU #0.\n" "\n" - "trace asteroid.tr,0,true,{tracelog \"A=%02X \",a}\n" + "trace asteroid.tr,0,,{tracelog \"A=%02X \",a}\n" " Begin tracing the execution of CPU #0, logging output to asteroid.tr. Before each line, " "output A=<aval> to the tracelog.\n" }, diff --git a/src/emu/debug/express.cpp b/src/emu/debug/express.cpp index a9f9e38816f..0aa123f1d11 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); + 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 access virtual bool is_lval() const override; @@ -203,11 +203,12 @@ const char *expression_error::code_string() const // symbol_entry - constructor //------------------------------------------------- -symbol_entry::symbol_entry(symbol_table &table, symbol_type type, const char *name, void *ref) +symbol_entry::symbol_entry(symbol_table &table, symbol_type type, const char *name, const std::string &format, void *ref) : m_next(nullptr), m_table(table), m_type(type), m_name(name), + m_format(format), m_ref(ref) { } @@ -232,7 +233,7 @@ 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), + : 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), m_value(0) @@ -241,7 +242,7 @@ integer_symbol_entry::integer_symbol_entry(symbol_table &table, const char *name integer_symbol_entry::integer_symbol_entry(symbol_table &table, const char *name, u64 constval) - : symbol_entry(table, SMT_INTEGER, name, &m_value), + : symbol_entry(table, SMT_INTEGER, name, "", &m_value), m_getter(internal_getter), m_setter(nullptr), m_value(constval) @@ -249,8 +250,8 @@ integer_symbol_entry::integer_symbol_entry(symbol_table &table, const char *name } -integer_symbol_entry::integer_symbol_entry(symbol_table &table, const char *name, void *ref, symbol_table::getter_func getter, symbol_table::setter_func setter) - : symbol_entry(table, SMT_INTEGER, name, ref), +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), m_getter(getter), m_setter(setter), m_value(0) @@ -323,7 +324,7 @@ void integer_symbol_entry::internal_setter(symbol_table &table, void *symref, u6 //------------------------------------------------- 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), + : symbol_entry(table, SMT_FUNCTION, name, "", ref), m_minparams(minparams), m_maxparams(maxparams), m_execute(execute) @@ -434,10 +435,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) +void symbol_table::add(const char *name, void *ref, 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)); + m_symlist.emplace(name, std::make_unique<integer_symbol_entry>(*this, name, ref, getter, setter, format_string)); } diff --git a/src/emu/debug/express.h b/src/emu/debug/express.h index b9ddde14501..2627d198115 100644 --- a/src/emu/debug/express.h +++ b/src/emu/debug/express.h @@ -116,13 +116,14 @@ protected: }; // construction/destruction - symbol_entry(symbol_table &table, symbol_type type, const char *name, void *ref); + symbol_entry(symbol_table &table, symbol_type type, const char *name, const std::string &format, void *ref); public: virtual ~symbol_entry(); // getters symbol_entry *next() const { return m_next; } const char *name() const { return m_name.c_str(); } + const std::string &format() const { return m_format; } // type checking bool is_function() const { return (m_type == SMT_FUNCTION); } @@ -138,6 +139,7 @@ protected: symbol_table & m_table; // pointer back to the owning table 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 }; @@ -181,7 +183,7 @@ 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); + 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); 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/distate.h b/src/emu/distate.h index e10cdd1c16a..22db6cc22af 100644 --- a/src/emu/distate.h +++ b/src/emu/distate.h @@ -65,6 +65,7 @@ public: bool visible() const { return ((m_flags & DSF_NOSHOW) == 0); } bool divider() const { return m_flags & DSF_DIVIDER; } device_state_interface *parent_state() const {return m_device_state;} + const std::string &format_string() const { return m_format; } protected: // device state flags diff --git a/src/emu/logmacro.h b/src/emu/logmacro.h new file mode 100644 index 00000000000..14f80772461 --- /dev/null +++ b/src/emu/logmacro.h @@ -0,0 +1,20 @@ +// license:BSD-3-Clause +// copyright-holders:Vas Crabb +#if defined(MAME_EMU_LOGMACRO_H) || !defined(__EMU_H__) +#error This file should only be included once per compilation unit after all other headers +#endif +#define MAME_EMU_LOGMACRO_H + +#ifndef VERBOSE +#define VERBOSE 0 +#endif + +#ifndef LOG_OUTPUT_FUNC +#define LOG_OUTPUT_FUNC logerror +#endif + +#define LOG_GENERAL (1U << 0) + +#define LOGMASKED(mask, ...) do { if (VERBOSE & (mask)) (LOG_OUTPUT_FUNC)(__VA_ARGS__); } while (false) + +#define LOG(...) LOGMASKED(LOG_GENERAL, __VA_ARGS__) diff --git a/src/frontend/mame/luaengine.cpp b/src/frontend/mame/luaengine.cpp index 34d9c769338..a1ecf792d8e 100644 --- a/src/frontend/mame/luaengine.cpp +++ b/src/frontend/mame/luaengine.cpp @@ -769,6 +769,12 @@ void lua_engine::initialize() return sol::make_object(sol(), sol::nil); return sol::make_object(sol(), driver_list::driver(i)); }; + emu["wait"] = lua_CFunction([](lua_State *L) { + lua_engine *engine = mame_machine_manager::instance()->lua(); + luaL_argcheck(L, lua_isnumber(L, 1), 1, "waiting duration expected"); + engine->machine().scheduler().timer_set(attotime::from_double(lua_tonumber(L, 1)), timer_expired_delegate(FUNC(lua_engine::resume), engine), 0, L); + return lua_yield(L, 0); + }); emu.new_usertype<emu_file>("file", sol::call_constructor, sol::constructors<sol::types<const char *, uint32_t>>(), "read", [](emu_file &file, sol::buffer *buff) { buff->set_len(file.read(buff->get_ptr(), buff->get_len())); return buff; }, @@ -1709,6 +1715,17 @@ void lua_engine::close() lua_close(m_lua_state); } +void lua_engine::resume(void *ptr, int nparam) +{ + lua_State *L = static_cast<lua_State *>(ptr); + int stat = lua_resume(L, nullptr, 0); + if((stat != LUA_OK) && (stat != LUA_YIELD)) + { + osd_printf_error("[LUA ERROR] in resume: %s\n", lua_tostring(L, -1)); + lua_pop(L, 1); + } +} + void lua_engine::run(sol::load_result res) { if(res.valid()) diff --git a/src/frontend/mame/luaengine.h b/src/frontend/mame/luaengine.h index b03fabb1f8b..dfc860f21e5 100644 --- a/src/frontend/mame/luaengine.h +++ b/src/frontend/mame/luaengine.h @@ -120,6 +120,7 @@ private: void on_machine_resume(); void on_machine_frame(); + void resume(void *ptr, int nparam); void register_function(sol::function func, const char *id); bool execute_function(const char *id); sol::object call_plugin(const std::string &name, sol::object in); diff --git a/src/lib/formats/apd_dsk.cpp b/src/lib/formats/apd_dsk.cpp new file mode 100644 index 00000000000..cd5de8ad206 --- /dev/null +++ b/src/lib/formats/apd_dsk.cpp @@ -0,0 +1,124 @@ +// license:BSD-3-Clause +// copyright-holders:Nigel Barnes +/********************************************************************* + + formats/apd_dsk.c + + Archimedes Protected Disk Image format + +*********************************************************************/ + +#include <zlib.h> +#include "formats/apd_dsk.h" + +static const uint8_t APD_HEADER[8] = { 0x41, 0x50, 0x44, 0x58, 0x30, 0x30, 0x30, 0x31 }; +static const uint8_t GZ_HEADER[2] = { 0x1f, 0x8b }; + +apd_format::apd_format() +{ +} + +const char *apd_format::name() const +{ + return "apd"; +} + +const char *apd_format::description() const +{ + return "Archimedes Protected Disk Image"; +} + +const char *apd_format::extensions() const +{ + return "apd"; +} + +int apd_format::identify(io_generic *io, uint32_t form_factor) +{ + char h[8]; + + io_generic_read(io, h, 0, 8); + if (!memcmp(h, GZ_HEADER, sizeof(GZ_HEADER)) || !memcmp(h, APD_HEADER, sizeof(APD_HEADER))) { + return 100; + } + + return 0; +} + +bool apd_format::load(io_generic *io, uint32_t form_factor, floppy_image *image) +{ + uint64_t size = io_generic_size(io); + std::vector<uint8_t> img(size); + io_generic_read(io, &img[0], 0, size); + + int err; + std::vector<uint8_t> gz_ptr; + z_stream d_stream; + int inflate_size = (img[size - 1] << 24) | (img[size - 2] << 16) | (img[size - 3] << 8) | img[size - 4]; + uint8_t *in_ptr = &img[0]; + + gz_ptr.resize(inflate_size); + + d_stream.zalloc = nullptr; + d_stream.zfree = nullptr; + d_stream.opaque = nullptr; + d_stream.next_in = in_ptr; + d_stream.avail_in = size; + d_stream.next_out = &gz_ptr[0]; + d_stream.avail_out = inflate_size; + + err = inflateInit2(&d_stream, MAX_WBITS | 16); + if (err != Z_OK) { + LOG_FORMATS("inflateInit2 error: %d\n", err); + return false; + } + err = inflate(&d_stream, Z_FINISH); + if (err != Z_STREAM_END && err != Z_OK) { + LOG_FORMATS("inflate error: %d\n", err); + return false; + } + err = inflateEnd(&d_stream); + if (err != Z_OK) { + LOG_FORMATS("inflateEnd error: %d\n", err); + return false; + } + size = inflate_size; + img = gz_ptr; + + if (memcmp(&img[0], APD_HEADER, sizeof(APD_HEADER))) { + LOG_FORMATS("apd_dsk: floppy image has incorrect header\n"); + return false; + } + + int data = 0x7d0; + for (int track = 0; track < 83; track++) { + for (int side = 0; side < 2; side++) { + uint32_t sdlen = little_endianize_int32(*(uint32_t *)(&img[(track * 2 + side) * 12 + 8 + 0x0])); + uint32_t ddlen = little_endianize_int32(*(uint32_t *)(&img[(track * 2 + side) * 12 + 8 + 0x4])); + uint32_t qdlen = little_endianize_int32(*(uint32_t *)(&img[(track * 2 + side) * 12 + 8 + 0x8])); + + if (sdlen > 0) { + generate_track_from_bitstream(track, side, &img[data], sdlen, image); + data += (sdlen + 7) >> 3; + } + if (ddlen > 0) { + generate_track_from_bitstream(track, side, &img[data], ddlen, image); + data += (ddlen + 7) >> 3; + } + if (qdlen > 0) { + generate_track_from_bitstream(track, side, &img[data], qdlen, image); + data += (qdlen + 7) >> 3; + } + } + } + image->set_variant(floppy_image::DSDD); + + return true; +} + +bool apd_format::supports_save() const +{ + return false; +} + +const floppy_format_type FLOPPY_APD_FORMAT = &floppy_image_format_creator<apd_format>; diff --git a/src/lib/formats/apd_dsk.h b/src/lib/formats/apd_dsk.h new file mode 100644 index 00000000000..3bf40055a7b --- /dev/null +++ b/src/lib/formats/apd_dsk.h @@ -0,0 +1,31 @@ +// license:BSD-3-Clause +// copyright-holders:Nigel Barnes +/********************************************************************* + + formats/apd_dsk.h + + Archimedes Protected Disk Image format + +*********************************************************************/ + +#ifndef APD_DSK_H_ +#define APD_DSK_H_ + +#include "flopimg.h" + +class apd_format : public floppy_image_format_t { +public: + apd_format(); + + virtual const char *name() const override; + virtual const char *description() const override; + virtual const char *extensions() const override; + + virtual int identify(io_generic *io, uint32_t form_factor) override; + virtual bool load(io_generic *io, uint32_t form_factor, floppy_image *image) override; + virtual bool supports_save() const override; +}; + +extern const floppy_format_type FLOPPY_APD_FORMAT; + +#endif diff --git a/src/lib/netlist/analog/nld_bjt.h b/src/lib/netlist/analog/nld_bjt.h index 14b6b2ba484..6b8436fa9b0 100644 --- a/src/lib/netlist/analog/nld_bjt.h +++ b/src/lib/netlist/analog/nld_bjt.h @@ -122,7 +122,7 @@ public: { } - NETLIB_IS_DYNAMIC() + NETLIB_IS_DYNAMIC(true) //NETLIB_RESETI(); NETLIB_UPDATEI(); diff --git a/src/lib/netlist/analog/nld_fourterm.h b/src/lib/netlist/analog/nld_fourterm.h index 3861d57f6ad..635c305ead5 100644 --- a/src/lib/netlist/analog/nld_fourterm.h +++ b/src/lib/netlist/analog/nld_fourterm.h @@ -118,7 +118,7 @@ public: { } - NETLIB_IS_DYNAMIC() + NETLIB_IS_DYNAMIC(true) param_double_t m_cur_limit; /* current limit */ diff --git a/src/lib/netlist/analog/nld_twoterm.cpp b/src/lib/netlist/analog/nld_twoterm.cpp index e160e669079..0e53d77f1f5 100644 --- a/src/lib/netlist/analog/nld_twoterm.cpp +++ b/src/lib/netlist/analog/nld_twoterm.cpp @@ -300,6 +300,13 @@ NETLIB_UPDATE(VS) NETLIB_NAME(twoterm)::update(); } +NETLIB_TIMESTEP(VS) +{ + this->set(1.0 / m_R(), + m_compiled.evaluate(std::vector<double>({netlist().time().as_double()})), + 0.0); +} + // ---------------------------------------------------------------------------------------- // nld_CS // ---------------------------------------------------------------------------------------- @@ -319,6 +326,13 @@ NETLIB_UPDATE(CS) NETLIB_NAME(twoterm)::update(); } +NETLIB_TIMESTEP(CS) +{ + const double I = m_compiled.evaluate(std::vector<double>({netlist().time().as_double()})); + set_mat(0.0, 0.0, -I, + 0.0, 0.0, I); +} + } //namespace analog namespace devices { diff --git a/src/lib/netlist/analog/nld_twoterm.h b/src/lib/netlist/analog/nld_twoterm.h index 8de5aedbfc9..c02cfd29a76 100644 --- a/src/lib/netlist/analog/nld_twoterm.h +++ b/src/lib/netlist/analog/nld_twoterm.h @@ -34,6 +34,7 @@ #define NLD_TWOTERM_H_ #include "nl_base.h" +#include "plib/pfunction.h" // ----------------------------------------------------------------------------- // Macros @@ -280,7 +281,7 @@ public: //register_term("2", m_N); } - NETLIB_IS_TIMESTEP() + NETLIB_IS_TIMESTEP(true) NETLIB_TIMESTEPI(); param_double_t m_C; @@ -312,7 +313,7 @@ public: //register_term("2", m_N); } - NETLIB_IS_TIMESTEP() + NETLIB_IS_TIMESTEP(true) NETLIB_TIMESTEPI(); param_double_t m_L; @@ -426,9 +427,7 @@ public: register_subalias("K", m_N); } - - NETLIB_IS_DYNAMIC() - + NETLIB_IS_DYNAMIC(true) NETLIB_UPDATE_TERMINALSI(); diode_model_t m_model; @@ -454,17 +453,25 @@ public: NETLIB_CONSTRUCTOR_DERIVED(VS, twoterm) , m_R(*this, "R", 0.1) , m_V(*this, "V", 0.0) + , m_func(*this,"FUNC", "") { register_subalias("P", m_P); register_subalias("N", m_N); + if (m_func() != "") + m_compiled.compile_postfix(std::vector<pstring>({{"T"}}), m_func()); } + NETLIB_IS_TIMESTEP(m_func() != "") + NETLIB_TIMESTEPI(); + protected: NETLIB_UPDATEI(); NETLIB_RESETI(); param_double_t m_R; param_double_t m_V; + param_str_t m_func; + plib::pfunction m_compiled; }; // ----------------------------------------------------------------------------- @@ -476,16 +483,24 @@ NETLIB_OBJECT_DERIVED(CS, twoterm) public: NETLIB_CONSTRUCTOR_DERIVED(CS, twoterm) , m_I(*this, "I", 1.0) + , m_func(*this,"FUNC", "") { register_subalias("P", m_P); register_subalias("N", m_N); + if (m_func() != "") + m_compiled.compile_postfix(std::vector<pstring>({{"T"}}), m_func()); } + NETLIB_IS_TIMESTEP(m_func() != "") + NETLIB_TIMESTEPI(); +protected: + NETLIB_UPDATEI(); NETLIB_RESETI(); -protected: param_double_t m_I; + param_str_t m_func; + plib::pfunction m_compiled; }; diff --git a/src/lib/netlist/build/doxygen.conf b/src/lib/netlist/build/doxygen.conf index adf69b30e54..762fa0477a9 100644 --- a/src/lib/netlist/build/doxygen.conf +++ b/src/lib/netlist/build/doxygen.conf @@ -24,7 +24,7 @@ # for the list of possible encodings. # The default value is: UTF-8. -DOXYFILE_ENCODING = UTF-8 +DOXYFILE_ENCODING = UTF-8 # The PROJECT_NAME tag is a single word (or a sequence of words surrounded by # double-quotes, unless you are using Doxywizard) that should identify the @@ -32,33 +32,33 @@ DOXYFILE_ENCODING = UTF-8 # title of most generated pages and in a few other places. # The default value is: My Project. -PROJECT_NAME = "My Project" +PROJECT_NAME = Netlist documentaton # The PROJECT_NUMBER tag can be used to enter a project or revision number. This # could be handy for archiving the generated documentation or if some version # control system is used. -PROJECT_NUMBER = +PROJECT_NUMBER = # Using the PROJECT_BRIEF tag one can provide an optional one line description # for a project that appears at the top of each page and should give viewer a # quick idea about the purpose of the project. Keep the description short. -PROJECT_BRIEF = +PROJECT_BRIEF = # With the PROJECT_LOGO tag one can specify a logo or an icon that is included # in the documentation. The maximum height of the logo should not exceed 55 # pixels and the maximum width should not exceed 200 pixels. Doxygen will copy # the logo to the output directory. -PROJECT_LOGO = +PROJECT_LOGO = # The OUTPUT_DIRECTORY tag is used to specify the (relative or absolute) path # into which the generated documentation will be written. If a relative path is # entered, it will be relative to the location where doxygen was started. If # left blank the current directory will be used. -OUTPUT_DIRECTORY = doxy +OUTPUT_DIRECTORY = doxy # If the CREATE_SUBDIRS tag is set to YES then doxygen will create 4096 sub- # directories (in 2 levels) under the output directory of each output format and @@ -68,7 +68,7 @@ OUTPUT_DIRECTORY = doxy # performance problems for the file system. # The default value is: NO. -CREATE_SUBDIRS = NO +CREATE_SUBDIRS = NO # If the ALLOW_UNICODE_NAMES tag is set to YES, doxygen will allow non-ASCII # characters to appear in the names of generated files. If set to NO, non-ASCII @@ -76,7 +76,7 @@ CREATE_SUBDIRS = NO # U+3044. # The default value is: NO. -ALLOW_UNICODE_NAMES = NO +ALLOW_UNICODE_NAMES = NO # The OUTPUT_LANGUAGE tag is used to specify the language in which all # documentation generated by doxygen is written. Doxygen will use this @@ -91,14 +91,14 @@ ALLOW_UNICODE_NAMES = NO # Ukrainian and Vietnamese. # The default value is: English. -OUTPUT_LANGUAGE = English +OUTPUT_LANGUAGE = English # If the BRIEF_MEMBER_DESC tag is set to YES, doxygen will include brief member # descriptions after the members that are listed in the file and class # documentation (similar to Javadoc). Set to NO to disable this. # The default value is: YES. -BRIEF_MEMBER_DESC = YES +BRIEF_MEMBER_DESC = YES # If the REPEAT_BRIEF tag is set to YES, doxygen will prepend the brief # description of a member or function before the detailed description @@ -107,7 +107,7 @@ BRIEF_MEMBER_DESC = YES # brief descriptions will be completely suppressed. # The default value is: YES. -REPEAT_BRIEF = YES +REPEAT_BRIEF = YES # This tag implements a quasi-intelligent brief description abbreviator that is # used to form the text in various listings. Each string in this list, if found @@ -118,14 +118,14 @@ REPEAT_BRIEF = YES # the entity):The $name class, The $name widget, The $name file, is, provides, # specifies, contains, represents, a, an and the. -ABBREVIATE_BRIEF = +ABBREVIATE_BRIEF = # If the ALWAYS_DETAILED_SEC and REPEAT_BRIEF tags are both set to YES then # doxygen will generate a detailed section even if there is only a brief # description. # The default value is: NO. -ALWAYS_DETAILED_SEC = NO +ALWAYS_DETAILED_SEC = NO # If the INLINE_INHERITED_MEMB tag is set to YES, doxygen will show all # inherited members of a class in the documentation of that class as if those @@ -133,14 +133,14 @@ ALWAYS_DETAILED_SEC = NO # operators of the base classes will not be shown. # The default value is: NO. -INLINE_INHERITED_MEMB = NO +INLINE_INHERITED_MEMB = NO # If the FULL_PATH_NAMES tag is set to YES, doxygen will prepend the full path # before files name in the file list and in the header files. If set to NO the # shortest path that makes the file name unique will be used # The default value is: YES. -FULL_PATH_NAMES = YES +FULL_PATH_NAMES = YES # The STRIP_FROM_PATH tag can be used to strip a user-defined part of the path. # Stripping is only done if one of the specified strings matches the left-hand @@ -152,7 +152,7 @@ FULL_PATH_NAMES = YES # will be relative from the directory where doxygen is started. # This tag requires that the tag FULL_PATH_NAMES is set to YES. -STRIP_FROM_PATH = ../.. +STRIP_FROM_PATH = ../.. # The STRIP_FROM_INC_PATH tag can be used to strip a user-defined part of the # path mentioned in the documentation of a class, which tells the reader which @@ -161,14 +161,14 @@ STRIP_FROM_PATH = ../.. # specify the list of include paths that are normally passed to the compiler # using the -I flag. -STRIP_FROM_INC_PATH = +STRIP_FROM_INC_PATH = # If the SHORT_NAMES tag is set to YES, doxygen will generate much shorter (but # less readable) file names. This can be useful is your file systems doesn't # support long names like on DOS, Mac, or CD-ROM. # The default value is: NO. -SHORT_NAMES = NO +SHORT_NAMES = NO # If the JAVADOC_AUTOBRIEF tag is set to YES then doxygen will interpret the # first line (until the first dot) of a Javadoc-style comment as the brief @@ -177,7 +177,7 @@ SHORT_NAMES = NO # description.) # The default value is: NO. -JAVADOC_AUTOBRIEF = YES +JAVADOC_AUTOBRIEF = YES # If the QT_AUTOBRIEF tag is set to YES then doxygen will interpret the first # line (until the first dot) of a Qt-style comment as the brief description. If @@ -185,7 +185,7 @@ JAVADOC_AUTOBRIEF = YES # requiring an explicit \brief command for a brief description.) # The default value is: NO. -QT_AUTOBRIEF = YES +QT_AUTOBRIEF = YES # The MULTILINE_CPP_IS_BRIEF tag can be set to YES to make doxygen treat a # multi-line C++ special comment block (i.e. a block of //! or /// comments) as @@ -203,20 +203,20 @@ MULTILINE_CPP_IS_BRIEF = NO # documentation from any documented member that it re-implements. # The default value is: YES. -INHERIT_DOCS = YES +INHERIT_DOCS = YES # If the SEPARATE_MEMBER_PAGES tag is set to YES then doxygen will produce a new # page for each member. If set to NO, the documentation of a member will be part # of the file/class/namespace that contains it. # The default value is: NO. -SEPARATE_MEMBER_PAGES = NO +SEPARATE_MEMBER_PAGES = NO # The TAB_SIZE tag can be used to set the number of spaces in a tab. Doxygen # uses this value to replace tabs by spaces in code fragments. # Minimum value: 1, maximum value: 16, default value: 4. -TAB_SIZE = 4 +TAB_SIZE = 4 # This tag can be used to specify a number of aliases that act as commands in # the documentation. An alias has the form: @@ -228,13 +228,13 @@ TAB_SIZE = 4 # "Side Effects:". You can put \n's in the value part of an alias to insert # newlines. -ALIASES = +ALIASES = # This tag can be used to specify a number of word-keyword mappings (TCL only). # A mapping has the form "name=value". For example adding "class=itcl::class" # will allow you to use the command class in the itcl::class meaning. -TCL_SUBST = +TCL_SUBST = # Set the OPTIMIZE_OUTPUT_FOR_C tag to YES if your project consists of C sources # only. Doxygen will then generate output that is more tailored for C. For @@ -242,7 +242,7 @@ TCL_SUBST = # members will be omitted, etc. # The default value is: NO. -OPTIMIZE_OUTPUT_FOR_C = NO +OPTIMIZE_OUTPUT_FOR_C = NO # Set the OPTIMIZE_OUTPUT_JAVA tag to YES if your project consists of Java or # Python sources only. Doxygen will then generate output that is more tailored @@ -250,19 +250,19 @@ OPTIMIZE_OUTPUT_FOR_C = NO # qualified scopes will look different, etc. # The default value is: NO. -OPTIMIZE_OUTPUT_JAVA = NO +OPTIMIZE_OUTPUT_JAVA = NO # Set the OPTIMIZE_FOR_FORTRAN tag to YES if your project consists of Fortran # sources. Doxygen will then generate output that is tailored for Fortran. # The default value is: NO. -OPTIMIZE_FOR_FORTRAN = NO +OPTIMIZE_FOR_FORTRAN = NO # Set the OPTIMIZE_OUTPUT_VHDL tag to YES if your project consists of VHDL # sources. Doxygen will then generate output that is tailored for VHDL. # The default value is: NO. -OPTIMIZE_OUTPUT_VHDL = NO +OPTIMIZE_OUTPUT_VHDL = NO # Doxygen selects the parser to use depending on the extension of the files it # parses. With this tag you can assign which parser to use for a given @@ -281,7 +281,7 @@ OPTIMIZE_OUTPUT_VHDL = NO # Note that for custom extensions you also need to set FILE_PATTERNS otherwise # the files are not read by doxygen. -EXTENSION_MAPPING = +EXTENSION_MAPPING = # If the MARKDOWN_SUPPORT tag is enabled then doxygen pre-processes all comments # according to the Markdown format, which allows for more readable @@ -291,7 +291,7 @@ EXTENSION_MAPPING = # case of backward compatibilities issues. # The default value is: YES. -MARKDOWN_SUPPORT = YES +MARKDOWN_SUPPORT = YES # When enabled doxygen tries to link words that correspond to documented # classes, or namespaces to their corresponding documentation. Such a link can @@ -299,7 +299,7 @@ MARKDOWN_SUPPORT = YES # globally by setting AUTOLINK_SUPPORT to NO. # The default value is: YES. -AUTOLINK_SUPPORT = YES +AUTOLINK_SUPPORT = YES # If you use STL classes (i.e. std::string, std::vector, etc.) but do not want # to include (a tag file for) the STL sources as input, then you should set this @@ -309,13 +309,13 @@ AUTOLINK_SUPPORT = YES # diagrams that involve STL classes more complete and accurate. # The default value is: NO. -BUILTIN_STL_SUPPORT = NO +BUILTIN_STL_SUPPORT = NO # If you use Microsoft's C++/CLI language, you should set this option to YES to # enable parsing support. # The default value is: NO. -CPP_CLI_SUPPORT = NO +CPP_CLI_SUPPORT = NO # Set the SIP_SUPPORT tag to YES if your project consists of sip (see: # http://www.riverbankcomputing.co.uk/software/sip/intro) sources only. Doxygen @@ -323,7 +323,7 @@ CPP_CLI_SUPPORT = NO # of private inheritance when no explicit protection keyword is present. # The default value is: NO. -SIP_SUPPORT = NO +SIP_SUPPORT = NO # For Microsoft's IDL there are propget and propput attributes to indicate # getter and setter methods for a property. Setting this option to YES will make @@ -333,7 +333,7 @@ SIP_SUPPORT = NO # should set this option to NO. # The default value is: YES. -IDL_PROPERTY_SUPPORT = YES +IDL_PROPERTY_SUPPORT = YES # If member grouping is used in the documentation and the DISTRIBUTE_GROUP_DOC # tag is set to YES then doxygen will reuse the documentation of the first @@ -341,7 +341,7 @@ IDL_PROPERTY_SUPPORT = YES # all members of a group must be documented explicitly. # The default value is: NO. -DISTRIBUTE_GROUP_DOC = NO +DISTRIBUTE_GROUP_DOC = NO # If one adds a struct or class to a group and this option is enabled, then also # any nested class or struct is added to the same group. By default this option @@ -357,7 +357,7 @@ GROUP_NESTED_COMPOUNDS = NO # \nosubgrouping command. # The default value is: YES. -SUBGROUPING = YES +SUBGROUPING = YES # When the INLINE_GROUPED_CLASSES tag is set to YES, classes, structs and unions # are shown inside the group in which they are included (e.g. using \ingroup) @@ -378,7 +378,7 @@ INLINE_GROUPED_CLASSES = NO # Man pages) or section (for LaTeX and RTF). # The default value is: NO. -INLINE_SIMPLE_STRUCTS = NO +INLINE_SIMPLE_STRUCTS = NO # When TYPEDEF_HIDES_STRUCT tag is enabled, a typedef of a struct, union, or # enum is documented as struct, union, or enum with the name of the typedef. So @@ -389,7 +389,7 @@ INLINE_SIMPLE_STRUCTS = NO # types are typedef'ed and only the typedef is referenced, never the tag name. # The default value is: NO. -TYPEDEF_HIDES_STRUCT = NO +TYPEDEF_HIDES_STRUCT = NO # The size of the symbol lookup cache can be set using LOOKUP_CACHE_SIZE. This # cache is used to resolve symbols given their name and scope. Since this can be @@ -402,7 +402,7 @@ TYPEDEF_HIDES_STRUCT = NO # the optimal cache size from a speed point of view. # Minimum value: 0, maximum value: 9, default value: 0. -LOOKUP_CACHE_SIZE = 0 +LOOKUP_CACHE_SIZE = 0 #--------------------------------------------------------------------------- # Build related configuration options @@ -416,25 +416,25 @@ LOOKUP_CACHE_SIZE = 0 # normally produced when WARNINGS is set to YES. # The default value is: NO. -EXTRACT_ALL = NO +EXTRACT_ALL = NO # If the EXTRACT_PRIVATE tag is set to YES, all private members of a class will # be included in the documentation. # The default value is: NO. -EXTRACT_PRIVATE = NO +EXTRACT_PRIVATE = NO # If the EXTRACT_PACKAGE tag is set to YES, all members with package or internal # scope will be included in the documentation. # The default value is: NO. -EXTRACT_PACKAGE = NO +EXTRACT_PACKAGE = NO # If the EXTRACT_STATIC tag is set to YES, all static members of a file will be # included in the documentation. # The default value is: NO. -EXTRACT_STATIC = NO +EXTRACT_STATIC = NO # If the EXTRACT_LOCAL_CLASSES tag is set to YES, classes (and structs) defined # locally in source files will be included in the documentation. If set to NO, @@ -442,7 +442,7 @@ EXTRACT_STATIC = NO # for Java sources. # The default value is: YES. -EXTRACT_LOCAL_CLASSES = YES +EXTRACT_LOCAL_CLASSES = YES # This flag is only useful for Objective-C code. If set to YES, local methods, # which are defined in the implementation section but not in the interface are @@ -450,7 +450,7 @@ EXTRACT_LOCAL_CLASSES = YES # included. # The default value is: NO. -EXTRACT_LOCAL_METHODS = NO +EXTRACT_LOCAL_METHODS = NO # If this flag is set to YES, the members of anonymous namespaces will be # extracted and appear in the documentation as a namespace called @@ -459,7 +459,7 @@ EXTRACT_LOCAL_METHODS = NO # are hidden. # The default value is: NO. -EXTRACT_ANON_NSPACES = NO +EXTRACT_ANON_NSPACES = NO # If the HIDE_UNDOC_MEMBERS tag is set to YES, doxygen will hide all # undocumented members inside documented classes or files. If set to NO these @@ -467,7 +467,7 @@ EXTRACT_ANON_NSPACES = NO # section is generated. This option has no effect if EXTRACT_ALL is enabled. # The default value is: NO. -HIDE_UNDOC_MEMBERS = NO +HIDE_UNDOC_MEMBERS = NO # If the HIDE_UNDOC_CLASSES tag is set to YES, doxygen will hide all # undocumented classes that are normally visible in the class hierarchy. If set @@ -475,28 +475,28 @@ HIDE_UNDOC_MEMBERS = NO # has no effect if EXTRACT_ALL is enabled. # The default value is: NO. -HIDE_UNDOC_CLASSES = NO +HIDE_UNDOC_CLASSES = NO # If the HIDE_FRIEND_COMPOUNDS tag is set to YES, doxygen will hide all friend # (class|struct|union) declarations. If set to NO, these declarations will be # included in the documentation. # The default value is: NO. -HIDE_FRIEND_COMPOUNDS = NO +HIDE_FRIEND_COMPOUNDS = NO # If the HIDE_IN_BODY_DOCS tag is set to YES, doxygen will hide any # documentation blocks found inside the body of a function. If set to NO, these # blocks will be appended to the function's detailed documentation block. # The default value is: NO. -HIDE_IN_BODY_DOCS = NO +HIDE_IN_BODY_DOCS = NO # The INTERNAL_DOCS tag determines if documentation that is typed after a # \internal command is included. If the tag is set to NO then the documentation # will be excluded. Set it to YES to include the internal documentation. # The default value is: NO. -INTERNAL_DOCS = NO +INTERNAL_DOCS = NO # If the CASE_SENSE_NAMES tag is set to NO then doxygen will only generate file # names in lower-case letters. If set to YES, upper-case letters are also @@ -505,53 +505,53 @@ INTERNAL_DOCS = NO # and Mac users are advised to set this option to NO. # The default value is: system dependent. -CASE_SENSE_NAMES = YES +CASE_SENSE_NAMES = YES # If the HIDE_SCOPE_NAMES tag is set to NO then doxygen will show members with # their full class and namespace scopes in the documentation. If set to YES, the # scope will be hidden. # The default value is: NO. -HIDE_SCOPE_NAMES = NO +HIDE_SCOPE_NAMES = NO # If the HIDE_COMPOUND_REFERENCE tag is set to NO (default) then doxygen will # append additional text to a page's title, such as Class Reference. If set to # YES the compound reference will be hidden. # The default value is: NO. -HIDE_COMPOUND_REFERENCE= NO +HIDE_COMPOUND_REFERENCE = NO # If the SHOW_INCLUDE_FILES tag is set to YES then doxygen will put a list of # the files that are included by a file in the documentation of that file. # The default value is: YES. -SHOW_INCLUDE_FILES = YES +SHOW_INCLUDE_FILES = YES # If the SHOW_GROUPED_MEMB_INC tag is set to YES then Doxygen will add for each # grouped member an include statement to the documentation, telling the reader # which file to include in order to use the member. # The default value is: NO. -SHOW_GROUPED_MEMB_INC = NO +SHOW_GROUPED_MEMB_INC = NO # If the FORCE_LOCAL_INCLUDES tag is set to YES then doxygen will list include # files with double quotes in the documentation rather than with sharp brackets. # The default value is: NO. -FORCE_LOCAL_INCLUDES = NO +FORCE_LOCAL_INCLUDES = NO # If the INLINE_INFO tag is set to YES then a tag [inline] is inserted in the # documentation for inline members. # The default value is: YES. -INLINE_INFO = YES +INLINE_INFO = YES # If the SORT_MEMBER_DOCS tag is set to YES then doxygen will sort the # (detailed) documentation of file and class members alphabetically by member # name. If set to NO, the members will appear in declaration order. # The default value is: YES. -SORT_MEMBER_DOCS = YES +SORT_MEMBER_DOCS = YES # If the SORT_BRIEF_DOCS tag is set to YES then doxygen will sort the brief # descriptions of file, namespace and class members alphabetically by member @@ -559,7 +559,7 @@ SORT_MEMBER_DOCS = YES # this will also influence the order of the classes in the class list. # The default value is: NO. -SORT_BRIEF_DOCS = NO +SORT_BRIEF_DOCS = NO # If the SORT_MEMBERS_CTORS_1ST tag is set to YES then doxygen will sort the # (brief and detailed) documentation of class members so that constructors and @@ -578,7 +578,7 @@ SORT_MEMBERS_CTORS_1ST = NO # appear in their defined order. # The default value is: NO. -SORT_GROUP_NAMES = NO +SORT_GROUP_NAMES = NO # If the SORT_BY_SCOPE_NAME tag is set to YES, the class list will be sorted by # fully-qualified names, including namespaces. If set to NO, the class list will @@ -588,7 +588,7 @@ SORT_GROUP_NAMES = NO # list. # The default value is: NO. -SORT_BY_SCOPE_NAME = NO +SORT_BY_SCOPE_NAME = NO # If the STRICT_PROTO_MATCHING option is enabled and doxygen fails to do proper # type resolution of all parameters of a function it will reject a match between @@ -598,38 +598,38 @@ SORT_BY_SCOPE_NAME = NO # accept a match between prototype and implementation in such cases. # The default value is: NO. -STRICT_PROTO_MATCHING = NO +STRICT_PROTO_MATCHING = NO # The GENERATE_TODOLIST tag can be used to enable (YES) or disable (NO) the todo # list. This list is created by putting \todo commands in the documentation. # The default value is: YES. -GENERATE_TODOLIST = YES +GENERATE_TODOLIST = YES # The GENERATE_TESTLIST tag can be used to enable (YES) or disable (NO) the test # list. This list is created by putting \test commands in the documentation. # The default value is: YES. -GENERATE_TESTLIST = YES +GENERATE_TESTLIST = YES # The GENERATE_BUGLIST tag can be used to enable (YES) or disable (NO) the bug # list. This list is created by putting \bug commands in the documentation. # The default value is: YES. -GENERATE_BUGLIST = YES +GENERATE_BUGLIST = YES # The GENERATE_DEPRECATEDLIST tag can be used to enable (YES) or disable (NO) # the deprecated list. This list is created by putting \deprecated commands in # the documentation. # The default value is: YES. -GENERATE_DEPRECATEDLIST= YES +GENERATE_DEPRECATEDLIST = YES # The ENABLED_SECTIONS tag can be used to enable conditional documentation # sections, marked by \if <section_label> ... \endif and \cond <section_label> # ... \endcond blocks. -ENABLED_SECTIONS = +ENABLED_SECTIONS = # The MAX_INITIALIZER_LINES tag determines the maximum number of lines that the # initial value of a variable or macro / define can have for it to appear in the @@ -640,28 +640,28 @@ ENABLED_SECTIONS = # documentation regardless of this setting. # Minimum value: 0, maximum value: 10000, default value: 30. -MAX_INITIALIZER_LINES = 30 +MAX_INITIALIZER_LINES = 30 # Set the SHOW_USED_FILES tag to NO to disable the list of files generated at # the bottom of the documentation of classes and structs. If set to YES, the # list will mention the files that were used to generate the documentation. # The default value is: YES. -SHOW_USED_FILES = YES +SHOW_USED_FILES = YES # Set the SHOW_FILES tag to NO to disable the generation of the Files page. This # will remove the Files entry from the Quick Index and from the Folder Tree View # (if specified). # The default value is: YES. -SHOW_FILES = YES +SHOW_FILES = YES # Set the SHOW_NAMESPACES tag to NO to disable the generation of the Namespaces # page. This will remove the Namespaces entry from the Quick Index and from the # Folder Tree View (if specified). # The default value is: YES. -SHOW_NAMESPACES = YES +SHOW_NAMESPACES = YES # The FILE_VERSION_FILTER tag can be used to specify a program or script that # doxygen should invoke to get the current version for each file (typically from @@ -671,7 +671,7 @@ SHOW_NAMESPACES = YES # by doxygen. Whatever the program writes to standard output is used as the file # version. For an example see the documentation. -FILE_VERSION_FILTER = +FILE_VERSION_FILTER = # The LAYOUT_FILE tag can be used to specify a layout file which will be parsed # by doxygen. The layout file controls the global structure of the generated @@ -684,7 +684,7 @@ FILE_VERSION_FILTER = # DoxygenLayout.xml, doxygen will parse it automatically even if the LAYOUT_FILE # tag is left empty. -LAYOUT_FILE = +LAYOUT_FILE = # The CITE_BIB_FILES tag can be used to specify one or more bib files containing # the reference definitions. This must be a list of .bib files. The .bib @@ -694,7 +694,7 @@ LAYOUT_FILE = # LATEX_BIB_STYLE. To use this feature you need bibtex and perl available in the # search path. See also \cite for info how to create references. -CITE_BIB_FILES = +CITE_BIB_FILES = #--------------------------------------------------------------------------- # Configuration options related to warning and progress messages @@ -705,7 +705,7 @@ CITE_BIB_FILES = # messages are off. # The default value is: NO. -QUIET = NO +QUIET = NO # The WARNINGS tag can be used to turn on/off the warning messages that are # generated to standard error (stderr) by doxygen. If WARNINGS is set to YES @@ -714,14 +714,14 @@ QUIET = NO # Tip: Turn warnings on while writing the documentation. # The default value is: YES. -WARNINGS = YES +WARNINGS = YES # If the WARN_IF_UNDOCUMENTED tag is set to YES then doxygen will generate # warnings for undocumented members. If EXTRACT_ALL is set to YES then this flag # will automatically be disabled. # The default value is: YES. -WARN_IF_UNDOCUMENTED = YES +WARN_IF_UNDOCUMENTED = YES # If the WARN_IF_DOC_ERROR tag is set to YES, doxygen will generate warnings for # potential errors in the documentation, such as not documenting some parameters @@ -729,7 +729,7 @@ WARN_IF_UNDOCUMENTED = YES # markup commands wrongly. # The default value is: YES. -WARN_IF_DOC_ERROR = YES +WARN_IF_DOC_ERROR = YES # This WARN_NO_PARAMDOC option can be enabled to get warnings for functions that # are documented, but have no documentation for their parameters or return @@ -737,13 +737,13 @@ WARN_IF_DOC_ERROR = YES # parameter documentation, but not about the absence of documentation. # The default value is: NO. -WARN_NO_PARAMDOC = NO +WARN_NO_PARAMDOC = NO # If the WARN_AS_ERROR tag is set to YES then doxygen will immediately stop when # a warning is encountered. # The default value is: NO. -WARN_AS_ERROR = NO +WARN_AS_ERROR = NO # The WARN_FORMAT tag determines the format of the warning messages that doxygen # can produce. The string should contain the $file, $line, and $text tags, which @@ -753,13 +753,13 @@ WARN_AS_ERROR = NO # FILE_VERSION_FILTER) # The default value is: $file:$line: $text. -WARN_FORMAT = "$file:$line: $text" +WARN_FORMAT = "$file:$line: $text" # The WARN_LOGFILE tag can be used to specify a file to which warning and error # messages should be written. If left blank the output is written to standard # error (stderr). -WARN_LOGFILE = +WARN_LOGFILE = #--------------------------------------------------------------------------- # Configuration options related to the input files @@ -771,7 +771,7 @@ WARN_LOGFILE = # spaces. See also FILE_PATTERNS and EXTENSION_MAPPING # Note: If this tag is empty the current directory is searched. -INPUT = ".." "../analog" "../documentation" +INPUT = ".." "../analog" "../documentation" # This tag can be used to specify the character encoding of the source files # that doxygen parses. Internally doxygen uses the UTF-8 encoding. Doxygen uses @@ -780,7 +780,7 @@ INPUT = ".." "../analog" "../documentation" # possible encodings. # The default value is: UTF-8. -INPUT_ENCODING = UTF-8 +INPUT_ENCODING = UTF-8 # If the value of the INPUT tag contains directories, you can use the # FILE_PATTERNS tag to specify one or more wildcard patterns (like *.cpp and @@ -796,13 +796,13 @@ INPUT_ENCODING = UTF-8 # *.m, *.markdown, *.md, *.mm, *.dox, *.py, *.pyw, *.f90, *.f, *.for, *.tcl, # *.vhd, *.vhdl, *.ucf, *.qsf, *.as and *.js. -FILE_PATTERNS = *.h *.cpp +FILE_PATTERNS = *.h *.cpp # The RECURSIVE tag can be used to specify whether or not subdirectories should # be searched for input files as well. # The default value is: NO. -RECURSIVE = NO +RECURSIVE = NO # The EXCLUDE tag can be used to specify files and/or directories that should be # excluded from the INPUT source files. This way you can easily exclude a @@ -811,14 +811,14 @@ RECURSIVE = NO # Note that relative paths are relative to the directory from which doxygen is # run. -EXCLUDE = +EXCLUDE = # The EXCLUDE_SYMLINKS tag can be used to select whether or not files or # directories that are symbolic links (a Unix file system feature) are excluded # from the input. # The default value is: NO. -EXCLUDE_SYMLINKS = NO +EXCLUDE_SYMLINKS = NO # If the value of the INPUT tag contains directories, you can use the # EXCLUDE_PATTERNS tag to specify one or more wildcard patterns to exclude @@ -827,7 +827,7 @@ EXCLUDE_SYMLINKS = NO # Note that the wildcards are matched against the file with absolute path, so to # exclude all test directories for example use the pattern */test/* -EXCLUDE_PATTERNS = +EXCLUDE_PATTERNS = # The EXCLUDE_SYMBOLS tag can be used to specify one or more symbol names # (namespaces, classes, functions, etc.) that should be excluded from the @@ -838,33 +838,33 @@ EXCLUDE_PATTERNS = # Note that the wildcards are matched against the file with absolute path, so to # exclude all test directories use the pattern */test/* -EXCLUDE_SYMBOLS = +EXCLUDE_SYMBOLS = # The EXAMPLE_PATH tag can be used to specify one or more files or directories # that contain example code fragments that are included (see the \include # command). -EXAMPLE_PATH = +EXAMPLE_PATH = # If the value of the EXAMPLE_PATH tag contains directories, you can use the # EXAMPLE_PATTERNS tag to specify one or more wildcard pattern (like *.cpp and # *.h) to filter out the source-files in the directories. If left blank all # files are included. -EXAMPLE_PATTERNS = +EXAMPLE_PATTERNS = # If the EXAMPLE_RECURSIVE tag is set to YES then subdirectories will be # searched for input files to be used with the \include or \dontinclude commands # irrespective of the value of the RECURSIVE tag. # The default value is: NO. -EXAMPLE_RECURSIVE = NO +EXAMPLE_RECURSIVE = NO # The IMAGE_PATH tag can be used to specify one or more files or directories # that contain images that are to be included in the documentation (see the # \image command). -IMAGE_PATH = "../documentation" +IMAGE_PATH = "../documentation" # The INPUT_FILTER tag can be used to specify a program that doxygen should # invoke to filter for each input file. Doxygen will invoke the filter program @@ -885,7 +885,7 @@ IMAGE_PATH = "../documentation" # need to set EXTENSION_MAPPING for the extension otherwise the files are not # properly processed by doxygen. -INPUT_FILTER = +INPUT_FILTER = # The FILTER_PATTERNS tag can be used to specify filters on a per file pattern # basis. Doxygen will compare the file name with each pattern and apply the @@ -898,14 +898,14 @@ INPUT_FILTER = # need to set EXTENSION_MAPPING for the extension otherwise the files are not # properly processed by doxygen. -FILTER_PATTERNS = +FILTER_PATTERNS = # If the FILTER_SOURCE_FILES tag is set to YES, the input filter (if set using # INPUT_FILTER) will also be used to filter the input files that are used for # producing the source files to browse (i.e. when SOURCE_BROWSER is set to YES). # The default value is: NO. -FILTER_SOURCE_FILES = NO +FILTER_SOURCE_FILES = NO # The FILTER_SOURCE_PATTERNS tag can be used to specify source filters per file # pattern. A pattern will override the setting for FILTER_PATTERN (if any) and @@ -913,14 +913,14 @@ FILTER_SOURCE_FILES = NO # *.ext= (so without naming a filter). # This tag requires that the tag FILTER_SOURCE_FILES is set to YES. -FILTER_SOURCE_PATTERNS = +FILTER_SOURCE_PATTERNS = # If the USE_MDFILE_AS_MAINPAGE tag refers to the name of a markdown file that # is part of the input, its contents will be placed on the main page # (index.html). This can be useful if you have a project on for instance GitHub # and want to reuse the introduction page also for the doxygen output. -USE_MDFILE_AS_MAINPAGE = +USE_MDFILE_AS_MAINPAGE = #--------------------------------------------------------------------------- # Configuration options related to source browsing @@ -933,20 +933,20 @@ USE_MDFILE_AS_MAINPAGE = # also VERBATIM_HEADERS is set to NO. # The default value is: NO. -SOURCE_BROWSER = NO +SOURCE_BROWSER = NO # Setting the INLINE_SOURCES tag to YES will include the body of functions, # classes and enums directly into the documentation. # The default value is: NO. -INLINE_SOURCES = NO +INLINE_SOURCES = NO # Setting the STRIP_CODE_COMMENTS tag to YES will instruct doxygen to hide any # special comment blocks from generated source code fragments. Normal C, C++ and # Fortran comments will always remain visible. # The default value is: YES. -STRIP_CODE_COMMENTS = YES +STRIP_CODE_COMMENTS = YES # If the REFERENCED_BY_RELATION tag is set to YES then for each documented # function all documented functions referencing it will be listed. @@ -958,7 +958,7 @@ REFERENCED_BY_RELATION = NO # all documented entities called/used by that function will be listed. # The default value is: NO. -REFERENCES_RELATION = NO +REFERENCES_RELATION = NO # If the REFERENCES_LINK_SOURCE tag is set to YES and SOURCE_BROWSER tag is set # to YES then the hyperlinks from functions in REFERENCES_RELATION and @@ -976,7 +976,7 @@ REFERENCES_LINK_SOURCE = YES # The default value is: YES. # This tag requires that the tag SOURCE_BROWSER is set to YES. -SOURCE_TOOLTIPS = YES +SOURCE_TOOLTIPS = YES # If the USE_HTAGS tag is set to YES then the references to source code will # point to the HTML generated by the htags(1) tool instead of doxygen built-in @@ -998,7 +998,7 @@ SOURCE_TOOLTIPS = YES # The default value is: NO. # This tag requires that the tag SOURCE_BROWSER is set to YES. -USE_HTAGS = NO +USE_HTAGS = NO # If the VERBATIM_HEADERS tag is set the YES then doxygen will generate a # verbatim copy of the header file for each class for which an include is @@ -1006,7 +1006,7 @@ USE_HTAGS = NO # See also: Section \class. # The default value is: YES. -VERBATIM_HEADERS = YES +VERBATIM_HEADERS = YES # If the CLANG_ASSISTED_PARSING tag is set to YES then doxygen will use the # clang parser (see: http://clang.llvm.org/) for more accurate parsing at the @@ -1025,7 +1025,7 @@ CLANG_ASSISTED_PARSING = NO # specified with INPUT and INCLUDE_PATH. # This tag requires that the tag CLANG_ASSISTED_PARSING is set to YES. -CLANG_OPTIONS = +CLANG_OPTIONS = #--------------------------------------------------------------------------- # Configuration options related to the alphabetical class index @@ -1036,14 +1036,14 @@ CLANG_OPTIONS = # classes, structs, unions or interfaces. # The default value is: YES. -ALPHABETICAL_INDEX = YES +ALPHABETICAL_INDEX = YES # The COLS_IN_ALPHA_INDEX tag can be used to specify the number of columns in # which the alphabetical index list will be split. # Minimum value: 1, maximum value: 20, default value: 5. # This tag requires that the tag ALPHABETICAL_INDEX is set to YES. -COLS_IN_ALPHA_INDEX = 5 +COLS_IN_ALPHA_INDEX = 5 # In case all classes in a project start with a common prefix, all classes will # be put under the same header in the alphabetical index. The IGNORE_PREFIX tag @@ -1051,7 +1051,7 @@ COLS_IN_ALPHA_INDEX = 5 # while generating the index headers. # This tag requires that the tag ALPHABETICAL_INDEX is set to YES. -IGNORE_PREFIX = +IGNORE_PREFIX = #--------------------------------------------------------------------------- # Configuration options related to the HTML output @@ -1060,7 +1060,7 @@ IGNORE_PREFIX = # If the GENERATE_HTML tag is set to YES, doxygen will generate HTML output # The default value is: YES. -GENERATE_HTML = YES +GENERATE_HTML = YES # The HTML_OUTPUT tag is used to specify where the HTML docs will be put. If a # relative path is entered the value of OUTPUT_DIRECTORY will be put in front of @@ -1068,14 +1068,14 @@ GENERATE_HTML = YES # The default directory is: html. # This tag requires that the tag GENERATE_HTML is set to YES. -HTML_OUTPUT = html +HTML_OUTPUT = html # The HTML_FILE_EXTENSION tag can be used to specify the file extension for each # generated HTML page (for example: .htm, .php, .asp). # The default value is: .html. # This tag requires that the tag GENERATE_HTML is set to YES. -HTML_FILE_EXTENSION = .html +HTML_FILE_EXTENSION = .html # The HTML_HEADER tag can be used to specify a user-defined HTML header file for # each generated HTML page. If the tag is left blank doxygen will generate a @@ -1095,7 +1095,7 @@ HTML_FILE_EXTENSION = .html # of the possible markers and block names see the documentation. # This tag requires that the tag GENERATE_HTML is set to YES. -HTML_HEADER = +HTML_HEADER = # The HTML_FOOTER tag can be used to specify a user-defined HTML footer for each # generated HTML page. If the tag is left blank doxygen will generate a standard @@ -1105,7 +1105,7 @@ HTML_HEADER = # that doxygen normally uses. # This tag requires that the tag GENERATE_HTML is set to YES. -HTML_FOOTER = +HTML_FOOTER = # The HTML_STYLESHEET tag can be used to specify a user-defined cascading style # sheet that is used by each HTML page. It can be used to fine-tune the look of @@ -1117,7 +1117,7 @@ HTML_FOOTER = # obsolete. # This tag requires that the tag GENERATE_HTML is set to YES. -HTML_STYLESHEET = +HTML_STYLESHEET = # The HTML_EXTRA_STYLESHEET tag can be used to specify additional user-defined # cascading style sheets that are included after the standard style sheets @@ -1130,7 +1130,7 @@ HTML_STYLESHEET = # list). For an example see the documentation. # This tag requires that the tag GENERATE_HTML is set to YES. -HTML_EXTRA_STYLESHEET = "../documentation/doc.css" +HTML_EXTRA_STYLESHEET = "../documentation/doc.css" # The HTML_EXTRA_FILES tag can be used to specify one or more extra images or # other source files which should be copied to the HTML output directory. Note @@ -1140,7 +1140,7 @@ HTML_EXTRA_STYLESHEET = "../documentation/doc.css" # files will be copied as-is; there are no commands or markers available. # This tag requires that the tag GENERATE_HTML is set to YES. -HTML_EXTRA_FILES = +HTML_EXTRA_FILES = # The HTML_COLORSTYLE_HUE tag controls the color of the HTML output. Doxygen # will adjust the colors in the style sheet and background images according to @@ -1151,7 +1151,7 @@ HTML_EXTRA_FILES = # Minimum value: 0, maximum value: 359, default value: 220. # This tag requires that the tag GENERATE_HTML is set to YES. -HTML_COLORSTYLE_HUE = 220 +HTML_COLORSTYLE_HUE = 220 # The HTML_COLORSTYLE_SAT tag controls the purity (or saturation) of the colors # in the HTML output. For a value of 0 the output will use grayscales only. A @@ -1159,7 +1159,7 @@ HTML_COLORSTYLE_HUE = 220 # Minimum value: 0, maximum value: 255, default value: 100. # This tag requires that the tag GENERATE_HTML is set to YES. -HTML_COLORSTYLE_SAT = 100 +HTML_COLORSTYLE_SAT = 100 # The HTML_COLORSTYLE_GAMMA tag controls the gamma correction applied to the # luminance component of the colors in the HTML output. Values below 100 @@ -1170,7 +1170,7 @@ HTML_COLORSTYLE_SAT = 100 # Minimum value: 40, maximum value: 240, default value: 80. # This tag requires that the tag GENERATE_HTML is set to YES. -HTML_COLORSTYLE_GAMMA = 80 +HTML_COLORSTYLE_GAMMA = 80 # If the HTML_TIMESTAMP tag is set to YES then the footer of each generated HTML # page will contain the date and time when the page was generated. Setting this @@ -1179,7 +1179,7 @@ HTML_COLORSTYLE_GAMMA = 80 # The default value is: NO. # This tag requires that the tag GENERATE_HTML is set to YES. -HTML_TIMESTAMP = NO +HTML_TIMESTAMP = NO # If the HTML_DYNAMIC_SECTIONS tag is set to YES then the generated HTML # documentation will contain sections that can be hidden and shown after the @@ -1187,7 +1187,7 @@ HTML_TIMESTAMP = NO # The default value is: NO. # This tag requires that the tag GENERATE_HTML is set to YES. -HTML_DYNAMIC_SECTIONS = NO +HTML_DYNAMIC_SECTIONS = YES # With HTML_INDEX_NUM_ENTRIES one can control the preferred number of entries # shown in the various tree structured indices initially; the user can expand @@ -1214,7 +1214,7 @@ HTML_INDEX_NUM_ENTRIES = 100 # The default value is: NO. # This tag requires that the tag GENERATE_HTML is set to YES. -GENERATE_DOCSET = NO +GENERATE_DOCSET = NO # This tag determines the name of the docset feed. A documentation feed provides # an umbrella under which multiple documentation sets from a single provider @@ -1222,7 +1222,7 @@ GENERATE_DOCSET = NO # The default value is: Doxygen generated docs. # This tag requires that the tag GENERATE_DOCSET is set to YES. -DOCSET_FEEDNAME = "Doxygen generated docs" +DOCSET_FEEDNAME = "Doxygen generated docs" # This tag specifies a string that should uniquely identify the documentation # set bundle. This should be a reverse domain-name style string, e.g. @@ -1230,7 +1230,7 @@ DOCSET_FEEDNAME = "Doxygen generated docs" # The default value is: org.doxygen.Project. # This tag requires that the tag GENERATE_DOCSET is set to YES. -DOCSET_BUNDLE_ID = org.doxygen.Project +DOCSET_BUNDLE_ID = org.doxygen.Project # The DOCSET_PUBLISHER_ID tag specifies a string that should uniquely identify # the documentation publisher. This should be a reverse domain-name style @@ -1238,13 +1238,13 @@ DOCSET_BUNDLE_ID = org.doxygen.Project # The default value is: org.doxygen.Publisher. # This tag requires that the tag GENERATE_DOCSET is set to YES. -DOCSET_PUBLISHER_ID = org.doxygen.Publisher +DOCSET_PUBLISHER_ID = org.doxygen.Publisher # The DOCSET_PUBLISHER_NAME tag identifies the documentation publisher. # The default value is: Publisher. # This tag requires that the tag GENERATE_DOCSET is set to YES. -DOCSET_PUBLISHER_NAME = Publisher +DOCSET_PUBLISHER_NAME = Publisher # If the GENERATE_HTMLHELP tag is set to YES then doxygen generates three # additional HTML index files: index.hhp, index.hhc, and index.hhk. The @@ -1262,14 +1262,14 @@ DOCSET_PUBLISHER_NAME = Publisher # The default value is: NO. # This tag requires that the tag GENERATE_HTML is set to YES. -GENERATE_HTMLHELP = NO +GENERATE_HTMLHELP = NO # The CHM_FILE tag can be used to specify the file name of the resulting .chm # file. You can add a path in front of the file if the result should not be # written to the html output directory. # This tag requires that the tag GENERATE_HTMLHELP is set to YES. -CHM_FILE = +CHM_FILE = # The HHC_LOCATION tag can be used to specify the location (absolute path # including file name) of the HTML help compiler (hhc.exe). If non-empty, @@ -1277,20 +1277,20 @@ CHM_FILE = # The file has to be specified with full path. # This tag requires that the tag GENERATE_HTMLHELP is set to YES. -HHC_LOCATION = +HHC_LOCATION = # The GENERATE_CHI flag controls if a separate .chi index file is generated # (YES) or that it should be included in the master .chm file (NO). # The default value is: NO. # This tag requires that the tag GENERATE_HTMLHELP is set to YES. -GENERATE_CHI = NO +GENERATE_CHI = NO # The CHM_INDEX_ENCODING is used to encode HtmlHelp index (hhk), content (hhc) # and project file content. # This tag requires that the tag GENERATE_HTMLHELP is set to YES. -CHM_INDEX_ENCODING = +CHM_INDEX_ENCODING = # The BINARY_TOC flag controls whether a binary table of contents is generated # (YES) or a normal table of contents (NO) in the .chm file. Furthermore it @@ -1298,14 +1298,14 @@ CHM_INDEX_ENCODING = # The default value is: NO. # This tag requires that the tag GENERATE_HTMLHELP is set to YES. -BINARY_TOC = NO +BINARY_TOC = NO # The TOC_EXPAND flag can be set to YES to add extra items for group members to # the table of contents of the HTML help documentation and to the tree view. # The default value is: NO. # This tag requires that the tag GENERATE_HTMLHELP is set to YES. -TOC_EXPAND = NO +TOC_EXPAND = NO # If the GENERATE_QHP tag is set to YES and both QHP_NAMESPACE and # QHP_VIRTUAL_FOLDER are set, an additional index file will be generated that @@ -1314,14 +1314,14 @@ TOC_EXPAND = NO # The default value is: NO. # This tag requires that the tag GENERATE_HTML is set to YES. -GENERATE_QHP = NO +GENERATE_QHP = NO # If the QHG_LOCATION tag is specified, the QCH_FILE tag can be used to specify # the file name of the resulting .qch file. The path specified is relative to # the HTML output folder. # This tag requires that the tag GENERATE_QHP is set to YES. -QCH_FILE = +QCH_FILE = # The QHP_NAMESPACE tag specifies the namespace to use when generating Qt Help # Project output. For more information please see Qt Help Project / Namespace @@ -1329,7 +1329,7 @@ QCH_FILE = # The default value is: org.doxygen.Project. # This tag requires that the tag GENERATE_QHP is set to YES. -QHP_NAMESPACE = org.doxygen.Project +QHP_NAMESPACE = org.doxygen.Project # The QHP_VIRTUAL_FOLDER tag specifies the namespace to use when generating Qt # Help Project output. For more information please see Qt Help Project / Virtual @@ -1338,7 +1338,7 @@ QHP_NAMESPACE = org.doxygen.Project # The default value is: doc. # This tag requires that the tag GENERATE_QHP is set to YES. -QHP_VIRTUAL_FOLDER = doc +QHP_VIRTUAL_FOLDER = doc # If the QHP_CUST_FILTER_NAME tag is set, it specifies the name of a custom # filter to add. For more information please see Qt Help Project / Custom @@ -1346,7 +1346,7 @@ QHP_VIRTUAL_FOLDER = doc # filters). # This tag requires that the tag GENERATE_QHP is set to YES. -QHP_CUST_FILTER_NAME = +QHP_CUST_FILTER_NAME = # The QHP_CUST_FILTER_ATTRS tag specifies the list of the attributes of the # custom filter to add. For more information please see Qt Help Project / Custom @@ -1354,21 +1354,21 @@ QHP_CUST_FILTER_NAME = # filters). # This tag requires that the tag GENERATE_QHP is set to YES. -QHP_CUST_FILTER_ATTRS = +QHP_CUST_FILTER_ATTRS = # The QHP_SECT_FILTER_ATTRS tag specifies the list of the attributes this # project's filter section matches. Qt Help Project / Filter Attributes (see: # http://qt-project.org/doc/qt-4.8/qthelpproject.html#filter-attributes). # This tag requires that the tag GENERATE_QHP is set to YES. -QHP_SECT_FILTER_ATTRS = +QHP_SECT_FILTER_ATTRS = # The QHG_LOCATION tag can be used to specify the location of Qt's # qhelpgenerator. If non-empty doxygen will try to run qhelpgenerator on the # generated .qhp file. # This tag requires that the tag GENERATE_QHP is set to YES. -QHG_LOCATION = +QHG_LOCATION = # If the GENERATE_ECLIPSEHELP tag is set to YES, additional index files will be # generated, together with the HTML files, they form an Eclipse help plugin. To @@ -1380,7 +1380,7 @@ QHG_LOCATION = # The default value is: NO. # This tag requires that the tag GENERATE_HTML is set to YES. -GENERATE_ECLIPSEHELP = NO +GENERATE_ECLIPSEHELP = NO # A unique identifier for the Eclipse help plugin. When installing the plugin # the directory name containing the HTML and XML files should also have this @@ -1388,7 +1388,7 @@ GENERATE_ECLIPSEHELP = NO # The default value is: org.doxygen.Project. # This tag requires that the tag GENERATE_ECLIPSEHELP is set to YES. -ECLIPSE_DOC_ID = org.doxygen.Project +ECLIPSE_DOC_ID = org.doxygen.Project # If you want full control over the layout of the generated HTML pages it might # be necessary to disable the index and replace it with your own. The @@ -1399,7 +1399,7 @@ ECLIPSE_DOC_ID = org.doxygen.Project # The default value is: NO. # This tag requires that the tag GENERATE_HTML is set to YES. -DISABLE_INDEX = NO +DISABLE_INDEX = NO # The GENERATE_TREEVIEW tag is used to specify whether a tree-like index # structure should be generated to display hierarchical information. If the tag @@ -1416,7 +1416,7 @@ DISABLE_INDEX = NO # The default value is: NO. # This tag requires that the tag GENERATE_HTML is set to YES. -GENERATE_TREEVIEW = NO +GENERATE_TREEVIEW = NO # The ENUM_VALUES_PER_LINE tag can be used to set the number of enum values that # doxygen will group on one line in the generated HTML documentation. @@ -1426,21 +1426,21 @@ GENERATE_TREEVIEW = NO # Minimum value: 0, maximum value: 20, default value: 4. # This tag requires that the tag GENERATE_HTML is set to YES. -ENUM_VALUES_PER_LINE = 4 +ENUM_VALUES_PER_LINE = 4 # If the treeview is enabled (see GENERATE_TREEVIEW) then this tag can be used # to set the initial width (in pixels) of the frame in which the tree is shown. # Minimum value: 0, maximum value: 1500, default value: 250. # This tag requires that the tag GENERATE_HTML is set to YES. -TREEVIEW_WIDTH = 250 +TREEVIEW_WIDTH = 250 # If the EXT_LINKS_IN_WINDOW option is set to YES, doxygen will open links to # external symbols imported via tag files in a separate window. # The default value is: NO. # This tag requires that the tag GENERATE_HTML is set to YES. -EXT_LINKS_IN_WINDOW = NO +EXT_LINKS_IN_WINDOW = NO # Use this tag to change the font size of LaTeX formulas included as images in # the HTML documentation. When you change the font size after a successful @@ -1449,7 +1449,7 @@ EXT_LINKS_IN_WINDOW = NO # Minimum value: 8, maximum value: 50, default value: 10. # This tag requires that the tag GENERATE_HTML is set to YES. -FORMULA_FONTSIZE = 10 +FORMULA_FONTSIZE = 10 # Use the FORMULA_TRANPARENT tag to determine whether or not the images # generated for formulas are transparent PNGs. Transparent PNGs are not @@ -1460,7 +1460,7 @@ FORMULA_FONTSIZE = 10 # The default value is: YES. # This tag requires that the tag GENERATE_HTML is set to YES. -FORMULA_TRANSPARENT = YES +FORMULA_TRANSPARENT = YES # Enable the USE_MATHJAX option to render LaTeX formulas using MathJax (see # http://www.mathjax.org) which uses client side Javascript for the rendering @@ -1471,7 +1471,7 @@ FORMULA_TRANSPARENT = YES # The default value is: NO. # This tag requires that the tag GENERATE_HTML is set to YES. -USE_MATHJAX = YES +USE_MATHJAX = YES # When MathJax is enabled you can set the default output format to be used for # the MathJax output. See the MathJax site (see: @@ -1481,7 +1481,7 @@ USE_MATHJAX = YES # The default value is: HTML-CSS. # This tag requires that the tag USE_MATHJAX is set to YES. -MATHJAX_FORMAT = HTML-CSS +MATHJAX_FORMAT = HTML-CSS # When MathJax is enabled you need to specify the location relative to the HTML # output directory using the MATHJAX_RELPATH option. The destination directory @@ -1494,14 +1494,14 @@ MATHJAX_FORMAT = HTML-CSS # The default value is: http://cdn.mathjax.org/mathjax/latest. # This tag requires that the tag USE_MATHJAX is set to YES. -MATHJAX_RELPATH = http://cdn.mathjax.org/mathjax/latest +MATHJAX_RELPATH = http://cdn.mathjax.org/mathjax/latest # The MATHJAX_EXTENSIONS tag can be used to specify one or more MathJax # extension names that should be enabled during MathJax rendering. For example # MATHJAX_EXTENSIONS = TeX/AMSmath TeX/AMSsymbols # This tag requires that the tag USE_MATHJAX is set to YES. -MATHJAX_EXTENSIONS = +MATHJAX_EXTENSIONS = # The MATHJAX_CODEFILE tag can be used to specify a file with javascript pieces # of code that will be used on startup of the MathJax code. See the MathJax site @@ -1509,7 +1509,7 @@ MATHJAX_EXTENSIONS = # example see the documentation. # This tag requires that the tag USE_MATHJAX is set to YES. -MATHJAX_CODEFILE = +MATHJAX_CODEFILE = # When the SEARCHENGINE tag is enabled doxygen will generate a search box for # the HTML output. The underlying search engine uses javascript and DHTML and @@ -1530,7 +1530,7 @@ MATHJAX_CODEFILE = # The default value is: YES. # This tag requires that the tag GENERATE_HTML is set to YES. -SEARCHENGINE = YES +SEARCHENGINE = YES # When the SERVER_BASED_SEARCH tag is enabled the search engine will be # implemented using a web server instead of a web client using Javascript. There @@ -1542,7 +1542,7 @@ SEARCHENGINE = YES # The default value is: NO. # This tag requires that the tag SEARCHENGINE is set to YES. -SERVER_BASED_SEARCH = NO +SERVER_BASED_SEARCH = NO # When EXTERNAL_SEARCH tag is enabled doxygen will no longer generate the PHP # script for searching. Instead the search results are written to an XML file @@ -1558,7 +1558,7 @@ SERVER_BASED_SEARCH = NO # The default value is: NO. # This tag requires that the tag SEARCHENGINE is set to YES. -EXTERNAL_SEARCH = NO +EXTERNAL_SEARCH = NO # The SEARCHENGINE_URL should point to a search engine hosted by a web server # which will return the search results when EXTERNAL_SEARCH is enabled. @@ -1569,7 +1569,7 @@ EXTERNAL_SEARCH = NO # Searching" for details. # This tag requires that the tag SEARCHENGINE is set to YES. -SEARCHENGINE_URL = +SEARCHENGINE_URL = # When SERVER_BASED_SEARCH and EXTERNAL_SEARCH are both enabled the unindexed # search data is written to a file for indexing by an external tool. With the @@ -1577,7 +1577,7 @@ SEARCHENGINE_URL = # The default file is: searchdata.xml. # This tag requires that the tag SEARCHENGINE is set to YES. -SEARCHDATA_FILE = searchdata.xml +SEARCHDATA_FILE = searchdata.xml # When SERVER_BASED_SEARCH and EXTERNAL_SEARCH are both enabled the # EXTERNAL_SEARCH_ID tag can be used as an identifier for the project. This is @@ -1585,7 +1585,7 @@ SEARCHDATA_FILE = searchdata.xml # projects and redirect the results back to the right project. # This tag requires that the tag SEARCHENGINE is set to YES. -EXTERNAL_SEARCH_ID = +EXTERNAL_SEARCH_ID = # The EXTRA_SEARCH_MAPPINGS tag can be used to enable searching through doxygen # projects other than the one defined by this configuration file, but that are @@ -1595,7 +1595,7 @@ EXTERNAL_SEARCH_ID = # EXTRA_SEARCH_MAPPINGS = tagname1=loc1 tagname2=loc2 ... # This tag requires that the tag SEARCHENGINE is set to YES. -EXTRA_SEARCH_MAPPINGS = +EXTRA_SEARCH_MAPPINGS = #--------------------------------------------------------------------------- # Configuration options related to the LaTeX output @@ -1604,7 +1604,7 @@ EXTRA_SEARCH_MAPPINGS = # If the GENERATE_LATEX tag is set to YES, doxygen will generate LaTeX output. # The default value is: YES. -GENERATE_LATEX = YES +GENERATE_LATEX = YES # The LATEX_OUTPUT tag is used to specify where the LaTeX docs will be put. If a # relative path is entered the value of OUTPUT_DIRECTORY will be put in front of @@ -1612,7 +1612,7 @@ GENERATE_LATEX = YES # The default directory is: latex. # This tag requires that the tag GENERATE_LATEX is set to YES. -LATEX_OUTPUT = latex +LATEX_OUTPUT = latex # The LATEX_CMD_NAME tag can be used to specify the LaTeX command name to be # invoked. @@ -1623,14 +1623,14 @@ LATEX_OUTPUT = latex # The default file is: latex. # This tag requires that the tag GENERATE_LATEX is set to YES. -LATEX_CMD_NAME = latex +LATEX_CMD_NAME = latex # The MAKEINDEX_CMD_NAME tag can be used to specify the command name to generate # index for LaTeX. # The default file is: makeindex. # This tag requires that the tag GENERATE_LATEX is set to YES. -MAKEINDEX_CMD_NAME = makeindex +MAKEINDEX_CMD_NAME = makeindex # If the COMPACT_LATEX tag is set to YES, doxygen generates more compact LaTeX # documents. This may be useful for small projects and may help to save some @@ -1638,7 +1638,7 @@ MAKEINDEX_CMD_NAME = makeindex # The default value is: NO. # This tag requires that the tag GENERATE_LATEX is set to YES. -COMPACT_LATEX = NO +COMPACT_LATEX = NO # The PAPER_TYPE tag can be used to set the paper type that is used by the # printer. @@ -1647,7 +1647,7 @@ COMPACT_LATEX = NO # The default value is: a4. # This tag requires that the tag GENERATE_LATEX is set to YES. -PAPER_TYPE = a4 +PAPER_TYPE = a4 # The EXTRA_PACKAGES tag can be used to specify one or more LaTeX package names # that should be included in the LaTeX output. The package can be specified just @@ -1659,7 +1659,7 @@ PAPER_TYPE = a4 # If left blank no extra packages will be included. # This tag requires that the tag GENERATE_LATEX is set to YES. -EXTRA_PACKAGES = +EXTRA_PACKAGES = # The LATEX_HEADER tag can be used to specify a personal LaTeX header for the # generated LaTeX document. The header should contain everything until the first @@ -1675,7 +1675,7 @@ EXTRA_PACKAGES = # to HTML_HEADER. # This tag requires that the tag GENERATE_LATEX is set to YES. -LATEX_HEADER = +LATEX_HEADER = # The LATEX_FOOTER tag can be used to specify a personal LaTeX footer for the # generated LaTeX document. The footer should contain everything after the last @@ -1686,7 +1686,7 @@ LATEX_HEADER = # Note: Only use a user-defined footer if you know what you are doing! # This tag requires that the tag GENERATE_LATEX is set to YES. -LATEX_FOOTER = +LATEX_FOOTER = # The LATEX_EXTRA_STYLESHEET tag can be used to specify additional user-defined # LaTeX style sheets that are included after the standard style sheets created @@ -1697,7 +1697,7 @@ LATEX_FOOTER = # list). # This tag requires that the tag GENERATE_LATEX is set to YES. -LATEX_EXTRA_STYLESHEET = +LATEX_EXTRA_STYLESHEET = # The LATEX_EXTRA_FILES tag can be used to specify one or more extra images or # other source files which should be copied to the LATEX_OUTPUT output @@ -1705,7 +1705,7 @@ LATEX_EXTRA_STYLESHEET = # markers available. # This tag requires that the tag GENERATE_LATEX is set to YES. -LATEX_EXTRA_FILES = +LATEX_EXTRA_FILES = # If the PDF_HYPERLINKS tag is set to YES, the LaTeX that is generated is # prepared for conversion to PDF (using ps2pdf or pdflatex). The PDF file will @@ -1714,7 +1714,7 @@ LATEX_EXTRA_FILES = # The default value is: YES. # This tag requires that the tag GENERATE_LATEX is set to YES. -PDF_HYPERLINKS = YES +PDF_HYPERLINKS = YES # If the USE_PDFLATEX tag is set to YES, doxygen will use pdflatex to generate # the PDF file directly from the LaTeX files. Set this option to YES, to get a @@ -1722,7 +1722,7 @@ PDF_HYPERLINKS = YES # The default value is: YES. # This tag requires that the tag GENERATE_LATEX is set to YES. -USE_PDFLATEX = YES +USE_PDFLATEX = YES # If the LATEX_BATCHMODE tag is set to YES, doxygen will add the \batchmode # command to the generated LaTeX files. This will instruct LaTeX to keep running @@ -1731,14 +1731,14 @@ USE_PDFLATEX = YES # The default value is: NO. # This tag requires that the tag GENERATE_LATEX is set to YES. -LATEX_BATCHMODE = NO +LATEX_BATCHMODE = NO # If the LATEX_HIDE_INDICES tag is set to YES then doxygen will not include the # index chapters (such as File Index, Compound Index, etc.) in the output. # The default value is: NO. # This tag requires that the tag GENERATE_LATEX is set to YES. -LATEX_HIDE_INDICES = NO +LATEX_HIDE_INDICES = NO # If the LATEX_SOURCE_CODE tag is set to YES then doxygen will include source # code with syntax highlighting in the LaTeX output. @@ -1748,7 +1748,7 @@ LATEX_HIDE_INDICES = NO # The default value is: NO. # This tag requires that the tag GENERATE_LATEX is set to YES. -LATEX_SOURCE_CODE = NO +LATEX_SOURCE_CODE = NO # The LATEX_BIB_STYLE tag can be used to specify the style to use for the # bibliography, e.g. plainnat, or ieeetr. See @@ -1756,7 +1756,7 @@ LATEX_SOURCE_CODE = NO # The default value is: plain. # This tag requires that the tag GENERATE_LATEX is set to YES. -LATEX_BIB_STYLE = plain +LATEX_BIB_STYLE = plain # If the LATEX_TIMESTAMP tag is set to YES then the footer of each generated # page will contain the date and time when the page was generated. Setting this @@ -1764,7 +1764,7 @@ LATEX_BIB_STYLE = plain # The default value is: NO. # This tag requires that the tag GENERATE_LATEX is set to YES. -LATEX_TIMESTAMP = NO +LATEX_TIMESTAMP = NO #--------------------------------------------------------------------------- # Configuration options related to the RTF output @@ -1775,7 +1775,7 @@ LATEX_TIMESTAMP = NO # readers/editors. # The default value is: NO. -GENERATE_RTF = NO +GENERATE_RTF = NO # The RTF_OUTPUT tag is used to specify where the RTF docs will be put. If a # relative path is entered the value of OUTPUT_DIRECTORY will be put in front of @@ -1783,7 +1783,7 @@ GENERATE_RTF = NO # The default directory is: rtf. # This tag requires that the tag GENERATE_RTF is set to YES. -RTF_OUTPUT = rtf +RTF_OUTPUT = rtf # If the COMPACT_RTF tag is set to YES, doxygen generates more compact RTF # documents. This may be useful for small projects and may help to save some @@ -1791,7 +1791,7 @@ RTF_OUTPUT = rtf # The default value is: NO. # This tag requires that the tag GENERATE_RTF is set to YES. -COMPACT_RTF = NO +COMPACT_RTF = NO # If the RTF_HYPERLINKS tag is set to YES, the RTF that is generated will # contain hyperlink fields. The RTF file will contain links (just like the HTML @@ -1803,7 +1803,7 @@ COMPACT_RTF = NO # The default value is: NO. # This tag requires that the tag GENERATE_RTF is set to YES. -RTF_HYPERLINKS = NO +RTF_HYPERLINKS = NO # Load stylesheet definitions from file. Syntax is similar to doxygen's config # file, i.e. a series of assignments. You only have to provide replacements, @@ -1813,14 +1813,14 @@ RTF_HYPERLINKS = NO # default style sheet that doxygen normally uses. # This tag requires that the tag GENERATE_RTF is set to YES. -RTF_STYLESHEET_FILE = +RTF_STYLESHEET_FILE = # Set optional variables used in the generation of an RTF document. Syntax is # similar to doxygen's config file. A template extensions file can be generated # using doxygen -e rtf extensionFile. # This tag requires that the tag GENERATE_RTF is set to YES. -RTF_EXTENSIONS_FILE = +RTF_EXTENSIONS_FILE = # If the RTF_SOURCE_CODE tag is set to YES then doxygen will include source code # with syntax highlighting in the RTF output. @@ -1830,7 +1830,7 @@ RTF_EXTENSIONS_FILE = # The default value is: NO. # This tag requires that the tag GENERATE_RTF is set to YES. -RTF_SOURCE_CODE = NO +RTF_SOURCE_CODE = NO #--------------------------------------------------------------------------- # Configuration options related to the man page output @@ -1840,7 +1840,7 @@ RTF_SOURCE_CODE = NO # classes and files. # The default value is: NO. -GENERATE_MAN = NO +GENERATE_MAN = NO # The MAN_OUTPUT tag is used to specify where the man pages will be put. If a # relative path is entered the value of OUTPUT_DIRECTORY will be put in front of @@ -1849,7 +1849,7 @@ GENERATE_MAN = NO # The default directory is: man. # This tag requires that the tag GENERATE_MAN is set to YES. -MAN_OUTPUT = man +MAN_OUTPUT = man # The MAN_EXTENSION tag determines the extension that is added to the generated # man pages. In case the manual section does not start with a number, the number @@ -1858,14 +1858,14 @@ MAN_OUTPUT = man # The default value is: .3. # This tag requires that the tag GENERATE_MAN is set to YES. -MAN_EXTENSION = .3 +MAN_EXTENSION = .3 # The MAN_SUBDIR tag determines the name of the directory created within # MAN_OUTPUT in which the man pages are placed. If defaults to man followed by # MAN_EXTENSION with the initial . removed. # This tag requires that the tag GENERATE_MAN is set to YES. -MAN_SUBDIR = +MAN_SUBDIR = # If the MAN_LINKS tag is set to YES and doxygen generates man output, then it # will generate one additional man file for each entity documented in the real @@ -1874,7 +1874,7 @@ MAN_SUBDIR = # The default value is: NO. # This tag requires that the tag GENERATE_MAN is set to YES. -MAN_LINKS = NO +MAN_LINKS = NO #--------------------------------------------------------------------------- # Configuration options related to the XML output @@ -1884,7 +1884,7 @@ MAN_LINKS = NO # captures the structure of the code including all documentation. # The default value is: NO. -GENERATE_XML = NO +GENERATE_XML = NO # The XML_OUTPUT tag is used to specify where the XML pages will be put. If a # relative path is entered the value of OUTPUT_DIRECTORY will be put in front of @@ -1892,7 +1892,7 @@ GENERATE_XML = NO # The default directory is: xml. # This tag requires that the tag GENERATE_XML is set to YES. -XML_OUTPUT = xml +XML_OUTPUT = xml # If the XML_PROGRAMLISTING tag is set to YES, doxygen will dump the program # listings (including syntax highlighting and cross-referencing information) to @@ -1901,7 +1901,7 @@ XML_OUTPUT = xml # The default value is: YES. # This tag requires that the tag GENERATE_XML is set to YES. -XML_PROGRAMLISTING = YES +XML_PROGRAMLISTING = YES #--------------------------------------------------------------------------- # Configuration options related to the DOCBOOK output @@ -1911,7 +1911,7 @@ XML_PROGRAMLISTING = YES # that can be used to generate PDF. # The default value is: NO. -GENERATE_DOCBOOK = NO +GENERATE_DOCBOOK = NO # The DOCBOOK_OUTPUT tag is used to specify where the Docbook pages will be put. # If a relative path is entered the value of OUTPUT_DIRECTORY will be put in @@ -1919,7 +1919,7 @@ GENERATE_DOCBOOK = NO # The default directory is: docbook. # This tag requires that the tag GENERATE_DOCBOOK is set to YES. -DOCBOOK_OUTPUT = docbook +DOCBOOK_OUTPUT = docbook # If the DOCBOOK_PROGRAMLISTING tag is set to YES, doxygen will include the # program listings (including syntax highlighting and cross-referencing @@ -1940,7 +1940,7 @@ DOCBOOK_PROGRAMLISTING = NO # still experimental and incomplete at the moment. # The default value is: NO. -GENERATE_AUTOGEN_DEF = NO +GENERATE_AUTOGEN_DEF = NO #--------------------------------------------------------------------------- # Configuration options related to the Perl module output @@ -1952,7 +1952,7 @@ GENERATE_AUTOGEN_DEF = NO # Note that this feature is still experimental and incomplete at the moment. # The default value is: NO. -GENERATE_PERLMOD = NO +GENERATE_PERLMOD = NO # If the PERLMOD_LATEX tag is set to YES, doxygen will generate the necessary # Makefile rules, Perl scripts and LaTeX code to be able to generate PDF and DVI @@ -1960,7 +1960,7 @@ GENERATE_PERLMOD = NO # The default value is: NO. # This tag requires that the tag GENERATE_PERLMOD is set to YES. -PERLMOD_LATEX = NO +PERLMOD_LATEX = NO # If the PERLMOD_PRETTY tag is set to YES, the Perl module output will be nicely # formatted so it can be parsed by a human reader. This is useful if you want to @@ -1970,7 +1970,7 @@ PERLMOD_LATEX = NO # The default value is: YES. # This tag requires that the tag GENERATE_PERLMOD is set to YES. -PERLMOD_PRETTY = YES +PERLMOD_PRETTY = YES # The names of the make variables in the generated doxyrules.make file are # prefixed with the string contained in PERLMOD_MAKEVAR_PREFIX. This is useful @@ -1978,7 +1978,7 @@ PERLMOD_PRETTY = YES # overwrite each other's variables. # This tag requires that the tag GENERATE_PERLMOD is set to YES. -PERLMOD_MAKEVAR_PREFIX = +PERLMOD_MAKEVAR_PREFIX = #--------------------------------------------------------------------------- # Configuration options related to the preprocessor @@ -1988,7 +1988,7 @@ PERLMOD_MAKEVAR_PREFIX = # C-preprocessor directives found in the sources and include files. # The default value is: YES. -ENABLE_PREPROCESSING = YES +ENABLE_PREPROCESSING = YES # If the MACRO_EXPANSION tag is set to YES, doxygen will expand all macro names # in the source code. If set to NO, only conditional compilation will be @@ -1997,7 +1997,7 @@ ENABLE_PREPROCESSING = YES # The default value is: NO. # This tag requires that the tag ENABLE_PREPROCESSING is set to YES. -MACRO_EXPANSION = NO +MACRO_EXPANSION = NO # If the EXPAND_ONLY_PREDEF and MACRO_EXPANSION tags are both set to YES then # the macro expansion is limited to the macros specified with the PREDEFINED and @@ -2005,21 +2005,21 @@ MACRO_EXPANSION = NO # The default value is: NO. # This tag requires that the tag ENABLE_PREPROCESSING is set to YES. -EXPAND_ONLY_PREDEF = NO +EXPAND_ONLY_PREDEF = NO # If the SEARCH_INCLUDES tag is set to YES, the include files in the # INCLUDE_PATH will be searched if a #include is found. # The default value is: YES. # This tag requires that the tag ENABLE_PREPROCESSING is set to YES. -SEARCH_INCLUDES = YES +SEARCH_INCLUDES = YES # The INCLUDE_PATH tag can be used to specify one or more directories that # contain include files that are not input files but should be processed by the # preprocessor. # This tag requires that the tag SEARCH_INCLUDES is set to YES. -INCLUDE_PATH = +INCLUDE_PATH = # You can use the INCLUDE_FILE_PATTERNS tag to specify one or more wildcard # patterns (like *.h and *.hpp) to filter out the header-files in the @@ -2027,7 +2027,7 @@ INCLUDE_PATH = # used. # This tag requires that the tag ENABLE_PREPROCESSING is set to YES. -INCLUDE_FILE_PATTERNS = +INCLUDE_FILE_PATTERNS = # The PREDEFINED tag can be used to specify one or more macro names that are # defined before the preprocessor is started (similar to the -D option of e.g. @@ -2037,7 +2037,7 @@ INCLUDE_FILE_PATTERNS = # recursively expanded use the := operator instead of the = operator. # This tag requires that the tag ENABLE_PREPROCESSING is set to YES. -PREDEFINED = +PREDEFINED = # If the MACRO_EXPANSION and EXPAND_ONLY_PREDEF tags are set to YES then this # tag can be used to specify a list of macro names that should be expanded. The @@ -2046,7 +2046,7 @@ PREDEFINED = # definition found in the source code. # This tag requires that the tag ENABLE_PREPROCESSING is set to YES. -EXPAND_AS_DEFINED = +EXPAND_AS_DEFINED = # If the SKIP_FUNCTION_MACROS tag is set to YES then doxygen's preprocessor will # remove all references to function-like macros that are alone on a line, have @@ -2056,7 +2056,7 @@ EXPAND_AS_DEFINED = # The default value is: YES. # This tag requires that the tag ENABLE_PREPROCESSING is set to YES. -SKIP_FUNCTION_MACROS = YES +SKIP_FUNCTION_MACROS = YES #--------------------------------------------------------------------------- # Configuration options related to external references @@ -2075,40 +2075,40 @@ SKIP_FUNCTION_MACROS = YES # the path). If a tag file is not located in the directory in which doxygen is # run, you must also specify the path to the tagfile here. -TAGFILES = +TAGFILES = # When a file name is specified after GENERATE_TAGFILE, doxygen will create a # tag file that is based on the input files it reads. See section "Linking to # external documentation" for more information about the usage of tag files. -GENERATE_TAGFILE = +GENERATE_TAGFILE = # If the ALLEXTERNALS tag is set to YES, all external class will be listed in # the class index. If set to NO, only the inherited external classes will be # listed. # The default value is: NO. -ALLEXTERNALS = NO +ALLEXTERNALS = NO # If the EXTERNAL_GROUPS tag is set to YES, all external groups will be listed # in the modules index. If set to NO, only the current project's groups will be # listed. # The default value is: YES. -EXTERNAL_GROUPS = YES +EXTERNAL_GROUPS = YES # If the EXTERNAL_PAGES tag is set to YES, all external pages will be listed in # the related pages index. If set to NO, only the current project's pages will # be listed. # The default value is: YES. -EXTERNAL_PAGES = YES +EXTERNAL_PAGES = YES # The PERL_PATH should be the absolute path and name of the perl script # interpreter (i.e. the result of 'which perl'). # The default file (with absolute path) is: /usr/bin/perl. -PERL_PATH = /usr/bin/perl +PERL_PATH = /usr/bin/perl #--------------------------------------------------------------------------- # Configuration options related to the dot tool @@ -2121,7 +2121,7 @@ PERL_PATH = /usr/bin/perl # powerful graphs. # The default value is: YES. -CLASS_DIAGRAMS = YES +CLASS_DIAGRAMS = NO # You can define message sequence charts within doxygen comments using the \msc # command. Doxygen will then run the mscgen tool (see: @@ -2130,20 +2130,20 @@ CLASS_DIAGRAMS = YES # the mscgen tool resides. If left empty the tool is assumed to be found in the # default search path. -MSCGEN_PATH = +MSCGEN_PATH = # You can include diagrams made with dia in doxygen documentation. Doxygen will # then run dia to produce the diagram and insert it in the documentation. The # DIA_PATH tag allows you to specify the directory where the dia binary resides. # If left empty dia is assumed to be found in the default search path. -DIA_PATH = +DIA_PATH = # If set to YES the inheritance and collaboration graphs will hide inheritance # and usage relations if the target is undocumented or is not a class. # The default value is: YES. -HIDE_UNDOC_RELATIONS = YES +HIDE_UNDOC_RELATIONS = YES # If you set the HAVE_DOT tag to YES then doxygen will assume the dot tool is # available from the path. This tool is part of Graphviz (see: @@ -2152,7 +2152,7 @@ HIDE_UNDOC_RELATIONS = YES # set to NO # The default value is: YES. -HAVE_DOT = YES +HAVE_DOT = YES # The DOT_NUM_THREADS specifies the number of dot invocations doxygen is allowed # to run in parallel. When set to 0 doxygen will base this on the number of @@ -2162,7 +2162,7 @@ HAVE_DOT = YES # Minimum value: 0, maximum value: 32, default value: 0. # This tag requires that the tag HAVE_DOT is set to YES. -DOT_NUM_THREADS = 0 +DOT_NUM_THREADS = 0 # When you want a differently looking font in the dot files that doxygen # generates you can specify the font name using DOT_FONTNAME. You need to make @@ -2172,21 +2172,21 @@ DOT_NUM_THREADS = 0 # The default value is: Helvetica. # This tag requires that the tag HAVE_DOT is set to YES. -DOT_FONTNAME = Helvetica +DOT_FONTNAME = Helvetica # The DOT_FONTSIZE tag can be used to set the size (in points) of the font of # dot graphs. # Minimum value: 4, maximum value: 24, default value: 10. # This tag requires that the tag HAVE_DOT is set to YES. -DOT_FONTSIZE = 10 +DOT_FONTSIZE = 10 # By default doxygen will tell dot to use the default font as specified with # DOT_FONTNAME. If you specify a different font using DOT_FONTNAME you can set # the path where dot can find it using this tag. # This tag requires that the tag HAVE_DOT is set to YES. -DOT_FONTPATH = +DOT_FONTPATH = # If the CLASS_GRAPH tag is set to YES then doxygen will generate a graph for # each documented class showing the direct and indirect inheritance relations. @@ -2194,7 +2194,7 @@ DOT_FONTPATH = # The default value is: YES. # This tag requires that the tag HAVE_DOT is set to YES. -CLASS_GRAPH = YES +CLASS_GRAPH = YES # If the COLLABORATION_GRAPH tag is set to YES then doxygen will generate a # graph for each documented class showing the direct and indirect implementation @@ -2203,14 +2203,14 @@ CLASS_GRAPH = YES # The default value is: YES. # This tag requires that the tag HAVE_DOT is set to YES. -COLLABORATION_GRAPH = YES +COLLABORATION_GRAPH = YES # If the GROUP_GRAPHS tag is set to YES then doxygen will generate a graph for # groups, showing the direct groups dependencies. # The default value is: YES. # This tag requires that the tag HAVE_DOT is set to YES. -GROUP_GRAPHS = YES +GROUP_GRAPHS = YES # If the UML_LOOK tag is set to YES, doxygen will generate inheritance and # collaboration diagrams in a style similar to the OMG's Unified Modeling @@ -2218,7 +2218,7 @@ GROUP_GRAPHS = YES # The default value is: NO. # This tag requires that the tag HAVE_DOT is set to YES. -UML_LOOK = NO +UML_LOOK = NO # If the UML_LOOK tag is enabled, the fields and methods are shown inside the # class node. If there are many fields or methods and many nodes the graph may @@ -2231,7 +2231,7 @@ UML_LOOK = NO # Minimum value: 0, maximum value: 100, default value: 10. # This tag requires that the tag HAVE_DOT is set to YES. -UML_LIMIT_NUM_FIELDS = 10 +UML_LIMIT_NUM_FIELDS = 10 # If the TEMPLATE_RELATIONS tag is set to YES then the inheritance and # collaboration graphs will show the relations between templates and their @@ -2239,7 +2239,7 @@ UML_LIMIT_NUM_FIELDS = 10 # The default value is: NO. # This tag requires that the tag HAVE_DOT is set to YES. -TEMPLATE_RELATIONS = NO +TEMPLATE_RELATIONS = NO # If the INCLUDE_GRAPH, ENABLE_PREPROCESSING and SEARCH_INCLUDES tags are set to # YES then doxygen will generate a graph for each documented file showing the @@ -2248,7 +2248,7 @@ TEMPLATE_RELATIONS = NO # The default value is: YES. # This tag requires that the tag HAVE_DOT is set to YES. -INCLUDE_GRAPH = YES +INCLUDE_GRAPH = YES # If the INCLUDED_BY_GRAPH, ENABLE_PREPROCESSING and SEARCH_INCLUDES tags are # set to YES then doxygen will generate a graph for each documented file showing @@ -2257,7 +2257,7 @@ INCLUDE_GRAPH = YES # The default value is: YES. # This tag requires that the tag HAVE_DOT is set to YES. -INCLUDED_BY_GRAPH = YES +INCLUDED_BY_GRAPH = YES # If the CALL_GRAPH tag is set to YES then doxygen will generate a call # dependency graph for every global function or class method. @@ -2269,7 +2269,7 @@ INCLUDED_BY_GRAPH = YES # The default value is: NO. # This tag requires that the tag HAVE_DOT is set to YES. -CALL_GRAPH = NO +CALL_GRAPH = NO # If the CALLER_GRAPH tag is set to YES then doxygen will generate a caller # dependency graph for every global function or class method. @@ -2281,14 +2281,14 @@ CALL_GRAPH = NO # The default value is: NO. # This tag requires that the tag HAVE_DOT is set to YES. -CALLER_GRAPH = NO +CALLER_GRAPH = NO # If the GRAPHICAL_HIERARCHY tag is set to YES then doxygen will graphical # hierarchy of all classes instead of a textual one. # The default value is: YES. # This tag requires that the tag HAVE_DOT is set to YES. -GRAPHICAL_HIERARCHY = YES +GRAPHICAL_HIERARCHY = YES # If the DIRECTORY_GRAPH tag is set to YES then doxygen will show the # dependencies a directory has on other directories in a graphical way. The @@ -2297,7 +2297,7 @@ GRAPHICAL_HIERARCHY = YES # The default value is: YES. # This tag requires that the tag HAVE_DOT is set to YES. -DIRECTORY_GRAPH = YES +DIRECTORY_GRAPH = YES # The DOT_IMAGE_FORMAT tag can be used to set the image format of the images # generated by dot. For an explanation of the image formats see the section @@ -2314,7 +2314,7 @@ DIRECTORY_GRAPH = YES # The default value is: png. # This tag requires that the tag HAVE_DOT is set to YES. -DOT_IMAGE_FORMAT = png +DOT_IMAGE_FORMAT = png # If DOT_IMAGE_FORMAT is set to svg, then this option can be set to YES to # enable generation of interactive SVG images that allow zooming and panning. @@ -2326,32 +2326,32 @@ DOT_IMAGE_FORMAT = png # The default value is: NO. # This tag requires that the tag HAVE_DOT is set to YES. -INTERACTIVE_SVG = NO +INTERACTIVE_SVG = NO # The DOT_PATH tag can be used to specify the path where the dot tool can be # found. If left blank, it is assumed the dot tool can be found in the path. # This tag requires that the tag HAVE_DOT is set to YES. -DOT_PATH = +DOT_PATH = # The DOTFILE_DIRS tag can be used to specify one or more directories that # contain dot files that are included in the documentation (see the \dotfile # command). # This tag requires that the tag HAVE_DOT is set to YES. -DOTFILE_DIRS = +DOTFILE_DIRS = # The MSCFILE_DIRS tag can be used to specify one or more directories that # contain msc files that are included in the documentation (see the \mscfile # command). -MSCFILE_DIRS = +MSCFILE_DIRS = # The DIAFILE_DIRS tag can be used to specify one or more directories that # contain dia files that are included in the documentation (see the \diafile # command). -DIAFILE_DIRS = +DIAFILE_DIRS = # When using plantuml, the PLANTUML_JAR_PATH tag should be used to specify the # path where java can find the plantuml.jar file. If left blank, it is assumed @@ -2359,12 +2359,12 @@ DIAFILE_DIRS = # generate a warning when it encounters a \startuml command in this case and # will not generate output for the diagram. -PLANTUML_JAR_PATH = +PLANTUML_JAR_PATH = # When using plantuml, the specified paths are searched for files specified by # the !include statement in a plantuml block. -PLANTUML_INCLUDE_PATH = +PLANTUML_INCLUDE_PATH = # The DOT_GRAPH_MAX_NODES tag can be used to set the maximum number of nodes # that will be shown in the graph. If the number of nodes in a graph becomes @@ -2376,7 +2376,7 @@ PLANTUML_INCLUDE_PATH = # Minimum value: 0, maximum value: 10000, default value: 50. # This tag requires that the tag HAVE_DOT is set to YES. -DOT_GRAPH_MAX_NODES = 50 +DOT_GRAPH_MAX_NODES = 50 # The MAX_DOT_GRAPH_DEPTH tag can be used to set the maximum depth of the graphs # generated by dot. A depth value of 3 means that only nodes reachable from the @@ -2388,7 +2388,7 @@ DOT_GRAPH_MAX_NODES = 50 # Minimum value: 0, maximum value: 1000, default value: 0. # This tag requires that the tag HAVE_DOT is set to YES. -MAX_DOT_GRAPH_DEPTH = 0 +MAX_DOT_GRAPH_DEPTH = 0 # Set the DOT_TRANSPARENT tag to YES to generate images with a transparent # background. This is disabled by default, because dot on Windows does not seem @@ -2400,7 +2400,7 @@ MAX_DOT_GRAPH_DEPTH = 0 # The default value is: NO. # This tag requires that the tag HAVE_DOT is set to YES. -DOT_TRANSPARENT = NO +DOT_TRANSPARENT = NO # Set the DOT_MULTI_TARGETS tag to YES to allow dot to generate multiple output # files in one run (i.e. multiple -o and -T options on the command line). This @@ -2409,7 +2409,7 @@ DOT_TRANSPARENT = NO # The default value is: NO. # This tag requires that the tag HAVE_DOT is set to YES. -DOT_MULTI_TARGETS = NO +DOT_MULTI_TARGETS = NO # If the GENERATE_LEGEND tag is set to YES doxygen will generate a legend page # explaining the meaning of the various boxes and arrows in the dot generated @@ -2417,11 +2417,11 @@ DOT_MULTI_TARGETS = NO # The default value is: YES. # This tag requires that the tag HAVE_DOT is set to YES. -GENERATE_LEGEND = YES +GENERATE_LEGEND = YES # If the DOT_CLEANUP tag is set to YES, doxygen will remove the intermediate dot # files that are used to generate the various graphs. # The default value is: YES. # This tag requires that the tag HAVE_DOT is set to YES. -DOT_CLEANUP = YES +DOT_CLEANUP = YES diff --git a/src/lib/netlist/build/makefile b/src/lib/netlist/build/makefile index 7ee5a204629..a5cc092b7f8 100644 --- a/src/lib/netlist/build/makefile +++ b/src/lib/netlist/build/makefile @@ -50,6 +50,7 @@ POBJS := \ $(POBJ)/pchrono.o \ $(POBJ)/pdynlib.o \ $(POBJ)/pexception.o \ + $(POBJ)/pfunction.o \ $(POBJ)/pfmtlog.o \ $(POBJ)/poptions.o \ $(POBJ)/pparser.o \ diff --git a/src/lib/netlist/devices/nld_system.cpp b/src/lib/netlist/devices/nld_system.cpp index f555e41720a..2a403c070a3 100644 --- a/src/lib/netlist/devices/nld_system.cpp +++ b/src/lib/netlist/devices/nld_system.cpp @@ -132,82 +132,13 @@ namespace netlist NETLIB_UPDATE(function) { - //nl_double val = INPANALOG(m_I[0]) * INPANALOG(m_I[1]) * 0.2; - //OUTANALOG(m_Q, val); - nl_double stack[20]; - unsigned ptr = 0; - std::size_t e = m_precompiled.size(); - for (std::size_t i = 0; i<e; i++) + for (std::size_t i=0; i < static_cast<unsigned>(m_N()); i++) { - rpn_inst &rc = m_precompiled[i]; - switch (rc.m_cmd) - { - case ADD: - ptr--; - stack[ptr-1] = stack[ptr] + stack[ptr-1]; - break; - case MULT: - ptr--; - stack[ptr-1] = stack[ptr] * stack[ptr-1]; - break; - case SUB: - ptr--; - stack[ptr-1] = stack[ptr-1] - stack[ptr]; - break; - case DIV: - ptr--; - stack[ptr-1] = stack[ptr-1] / stack[ptr]; - break; - case POW: - ptr--; - stack[ptr-1] = std::pow(stack[ptr-1], stack[ptr]); - break; - case PUSH_INPUT: - stack[ptr++] = (*m_I[static_cast<unsigned>(rc.m_param)])(); - break; - case PUSH_CONST: - stack[ptr++] = rc.m_param; - break; - } + m_vals[i] = (*m_I[i])(); } - m_Q.push(stack[ptr-1]); + m_Q.push(m_precompiled.evaluate(m_vals)); } - void NETLIB_NAME(function)::compile() - { - plib::pstring_vector_t cmds(m_func(), " "); - m_precompiled.clear(); - - for (std::size_t i=0; i < cmds.size(); i++) - { - pstring cmd = cmds[i]; - rpn_inst rc; - if (cmd == "+") - rc.m_cmd = ADD; - else if (cmd == "-") - rc.m_cmd = SUB; - else if (cmd == "*") - rc.m_cmd = MULT; - else if (cmd == "/") - rc.m_cmd = DIV; - else if (cmd == "pow") - rc.m_cmd = POW; - else if (cmd.startsWith("A")) - { - rc.m_cmd = PUSH_INPUT; - rc.m_param = cmd.substr(1).as_long(); - } - else - { - bool err = false; - rc.m_cmd = PUSH_CONST; - rc.m_param = cmd.as_double(&err); - if (err) - netlist().log().fatal("nld_function: unknown/misformatted token <{1}> in <{2}>", cmd, m_func()); - } - m_precompiled.push_back(rc); - } - } NETLIB_DEVICE_IMPL(dummy_input) NETLIB_DEVICE_IMPL(frontier) diff --git a/src/lib/netlist/devices/nlid_system.h b/src/lib/netlist/devices/nlid_system.h index 8d2cd8162f8..a81d0dd4240 100644 --- a/src/lib/netlist/devices/nlid_system.h +++ b/src/lib/netlist/devices/nlid_system.h @@ -11,12 +11,18 @@ #ifndef NLID_SYSTEM_H_ #define NLID_SYSTEM_H_ +#include <cstddef> +#include <memory> #include <vector> -#include "nl_setup.h" -#include "nl_base.h" -#include "nl_factory.h" #include "analog/nld_twoterm.h" +#include "nl_base.h" +#include "nl_time.h" +#include "plib/palloc.h" +#include "plib/pfmtlog.h" +#include "plib/pfunction.h" +#include "plib/pstring.h" +#include "plib/putil.h" namespace netlist { @@ -309,9 +315,15 @@ namespace netlist , m_func(*this, "FUNC", "") , m_Q(*this, "Q") { + std::vector<pstring> inps; for (int i=0; i < m_N(); i++) - m_I.push_back(plib::make_unique<analog_input_t>(*this, plib::pfmt("A{1}")(i))); - compile(); + { + pstring n = plib::pfmt("A{1}")(i); + m_I.push_back(plib::make_unique<analog_input_t>(*this, n)); + inps.push_back(n); + m_vals.push_back(0.0); + } + m_precompiled.compile_postfix(inps, m_func()); } protected: @@ -321,32 +333,13 @@ namespace netlist private: - enum rpn_cmd - { - ADD, - MULT, - SUB, - DIV, - POW, - PUSH_CONST, - PUSH_INPUT - }; - - struct rpn_inst - { - rpn_inst() : m_cmd(ADD), m_param(0.0) { } - rpn_cmd m_cmd; - nl_double m_param; - }; - - void compile(); - param_int_t m_N; param_str_t m_func; analog_output_t m_Q; std::vector<std::unique_ptr<analog_input_t>> m_I; - std::vector<rpn_inst> m_precompiled; + std::vector<double> m_vals; + plib::pfunction m_precompiled; }; // ----------------------------------------------------------------------------- diff --git a/src/lib/netlist/nl_base.h b/src/lib/netlist/nl_base.h index 171a81292ae..dfaa5a8fbba 100644 --- a/src/lib/netlist/nl_base.h +++ b/src/lib/netlist/nl_base.h @@ -85,18 +85,26 @@ class NETLIB_NAME(name) : public device_t : device_t(owner, name) /*! Add this to a device definition to mark the device as dynamic. - * If this is added to device definition the device is treated as an analog - * dynamic device, i.e. #NETLIB_UPDATE_TERMINALSI is called on a each step - * of the Newton-Raphson step of solving the linear equations. + * If NETLIB_IS_DYNAMIC(true) is added to the device definition the device + * is treated as an analog dynamic device, i.e. #NETLIB_UPDATE_TERMINALSI + * is called on a each step of the Newton-Raphson step + * of solving the linear equations. + * + * You may also use e.g. NETLIB_IS_DYNAMIC(m_func() != "") to only make the + * device a dynamic device if parameter m_func is set. */ -#define NETLIB_IS_DYNAMIC() \ - public: virtual bool is_dynamic() const override { return true; } +#define NETLIB_IS_DYNAMIC(expr) \ + public: virtual bool is_dynamic() const override { return expr; } /*! Add this to a device definition to mark the device as a time-stepping device. * * You have to implement NETLIB_TIMESTEP in this case as well. Currently, only * the capacitor and inductor devices uses this. * + * You may also use e.g. NETLIB_IS_TIMESTEP(m_func() != "") to only make the + * device a dynamic device if parameter m_func is set. This is used by the + * Voltage Source element. + * * Example: * * NETLIB_TIMESTEP_IS_TIMESTEP() @@ -109,8 +117,8 @@ class NETLIB_NAME(name) : public device_t * } * */ -#define NETLIB_IS_TIMESTEP() \ - public: virtual bool is_timestep() const override { return true; } +#define NETLIB_IS_TIMESTEP(expr) \ + public: virtual bool is_timestep() const override { return expr; } /*! Used to implement the time stepping code. * diff --git a/src/lib/netlist/plib/pfunction.cpp b/src/lib/netlist/plib/pfunction.cpp new file mode 100644 index 00000000000..c0f3e18a4f2 --- /dev/null +++ b/src/lib/netlist/plib/pfunction.cpp @@ -0,0 +1,104 @@ +// license:GPL-2.0+ +// copyright-holders:Couriersud +/* + * palloc.c + * + */ + +#include <cmath> +#include "pfunction.h" +#include "pfmtlog.h" +#include "putil.h" +#include "pexception.h" + +namespace plib { + +void pfunction::compile_postfix(const std::vector<pstring> &inputs, const pstring expr) +{ + plib::pstring_vector_t cmds(expr, " "); + m_precompiled.clear(); + int stk = 0; + + for (pstring &cmd : cmds) + { + rpn_inst rc; + if (cmd == "+") + { rc.m_cmd = ADD; stk -= 1; } + else if (cmd == "-") + { rc.m_cmd = SUB; stk -= 1; } + else if (cmd == "*") + { rc.m_cmd = MULT; stk -= 1; } + else if (cmd == "/") + { rc.m_cmd = DIV; stk -= 1; } + else if (cmd == "pow") + { rc.m_cmd = POW; stk -= 1; } + else if (cmd == "sin") + { rc.m_cmd = SIN; stk -= 0; } + else if (cmd == "cos") + { rc.m_cmd = COS; stk -= 0; } + else + { + for (unsigned i = 0; i < inputs.size(); i++) + { + if (inputs[i] == cmd) + { + rc.m_cmd = PUSH_INPUT; + rc.m_param = i; + stk += 1; + break; + } + } + if (rc.m_cmd != PUSH_INPUT) + { + bool err = false; + rc.m_cmd = PUSH_CONST; + rc.m_param = cmd.as_double(&err); + if (err) + throw plib::pexception(plib::pfmt("nld_function: unknown/misformatted token <{1}> in <{2}>")(cmd)(expr)); + stk += 1; + } + } + if (stk < 1) + throw plib::pexception(plib::pfmt("nld_function: stack underflow on token <{1}> in <{2}>")(cmd)(expr)); + m_precompiled.push_back(rc); + } + if (stk != 1) + throw plib::pexception(plib::pfmt("nld_function: stack count different to one on <{2}>")(expr)); +} + +#define ST1 stack[ptr] +#define ST2 stack[ptr-1] + +#define OP(OP, ADJ, EXPR) \ +case OP: \ + ptr-=ADJ; \ + stack[ptr-1] = EXPR; \ + break; + +double pfunction::evaluate(const std::vector<double> &values) +{ + double stack[20]; + unsigned ptr = 0; + for (auto &rc : m_precompiled) + { + switch (rc.m_cmd) + { + OP(ADD, 1, ST2 + ST1) + OP(MULT, 1, ST2 * ST1) + OP(SUB, 1, ST2 - ST1) + OP(DIV, 1, ST2 / ST1) + OP(POW, 1, std::pow(ST2, ST1)) + OP(SIN, 0, std::sin(ST2)); + OP(COS, 0, std::cos(ST2)); + case PUSH_INPUT: + stack[ptr++] = values[static_cast<unsigned>(rc.m_param)]; + break; + case PUSH_CONST: + stack[ptr++] = rc.m_param; + break; + } + } + return stack[ptr-1]; +} + +} diff --git a/src/lib/netlist/plib/pfunction.h b/src/lib/netlist/plib/pfunction.h new file mode 100644 index 00000000000..2ad32106569 --- /dev/null +++ b/src/lib/netlist/plib/pfunction.h @@ -0,0 +1,70 @@ +// license:GPL-2.0+ +// copyright-holders:Couriersud +/* + * pfunction.h + * + */ + +#ifndef PFUNCTION_H_ +#define PFUNCTION_H_ + +#include <vector> + +#include "pconfig.h" +#include "pstring.h" + +namespace plib { + + //============================================================ + // function evaluation - reverse polish notation + //============================================================ + + /*! Class providing support for precompiled rpn expressions + * + */ + class pfunction + { + enum rpn_cmd + { + ADD, + MULT, + SUB, + DIV, + POW, + SIN, + COS, + PUSH_CONST, + PUSH_INPUT + }; + struct rpn_inst + { + rpn_inst() : m_cmd(ADD), m_param(0.0) { } + rpn_cmd m_cmd; + double m_param; + }; + public: + pfunction() + { + } + + /*! Compile a rpn expression + * + * @param inputs Vector of input variables, e.g. {"A","B"} + * @param expr Reverse polish notation expression, e.g. "A B + 1.3 /" + */ + void compile_postfix(const std::vector<pstring> &inputs, const pstring expr); + /*! Evaluate the expression + * + * @param values for input variables, e.g. {1.1, 2.2} + * @return value of expression + */ + double evaluate(const std::vector<double> &values); + + private: + std::vector<rpn_inst> m_precompiled; //!< precompiled expression + }; + + +} + +#endif /* PEXCEPTION_H_ */ diff --git a/src/lib/netlist/solver/nld_solver.h b/src/lib/netlist/solver/nld_solver.h index 637e7d56b89..5430fc4ce28 100644 --- a/src/lib/netlist/solver/nld_solver.h +++ b/src/lib/netlist/solver/nld_solver.h @@ -62,7 +62,7 @@ NETLIB_OBJECT(solver) /* automatic time step */ , m_dynamic_ts(*this, "DYNAMIC_TS", 0) - , m_dynamic_lte(*this, "DYNAMIC_LTE", 5e-5) // diff/timestep + , m_dynamic_lte(*this, "DYNAMIC_LTE", 1e-5) // diff/timestep , m_dynamic_min_ts(*this, "DYNAMIC_MIN_TIMESTEP", 1e-6) // nl_double timestep resolution , m_log_stats(*this, "LOG_STATS", 1) // nl_double timestep resolution diff --git a/src/mame/drivers/aa310.cpp b/src/mame/drivers/aa310.cpp index f62ebc51a4b..00e468750b5 100644 --- a/src/mame/drivers/aa310.cpp +++ b/src/mame/drivers/aa310.cpp @@ -87,6 +87,7 @@ #include "cpu/arm/arm.h" #include "includes/archimds.h" #include "formats/acorn_dsk.h" +#include "formats/apd_dsk.h" #include "machine/i2cmem.h" #include "machine/ram.h" #include "machine/wd_fdc.h" @@ -351,7 +352,8 @@ INPUT_PORTS_END FLOPPY_FORMATS_MEMBER( aa310_state::floppy_formats ) FLOPPY_ACORN_ADFS_NEW_FORMAT, - FLOPPY_ACORN_ADFS_OLD_FORMAT + FLOPPY_ACORN_ADFS_OLD_FORMAT, + FLOPPY_APD_FORMAT FLOPPY_FORMATS_END static SLOT_INTERFACE_START( aa310_floppies ) diff --git a/src/mame/drivers/aztarac.cpp b/src/mame/drivers/aztarac.cpp index dcdda3ae0cf..725e74d485d 100644 --- a/src/mame/drivers/aztarac.cpp +++ b/src/mame/drivers/aztarac.cpp @@ -198,22 +198,27 @@ MACHINE_CONFIG_END ROM_START( aztarac ) ROM_REGION( 0xc000, "maincpu", 0 ) - ROM_LOAD16_BYTE( "l8_6.bin", 0x000000, 0x001000, CRC(25f8da18) SHA1(e8179ba3683e39c8225b549ead74c8af2d0a0b3e) ) - ROM_LOAD16_BYTE( "n8_0.bin", 0x000001, 0x001000, CRC(04e20626) SHA1(2b6a04992037257830df2c01a6da748fb4449f79) ) - ROM_LOAD16_BYTE( "l7_7.bin", 0x002000, 0x001000, CRC(230e244c) SHA1(42283a368144acf2aad2ef390e312e0951c3ea64) ) - ROM_LOAD16_BYTE( "n7_1.bin", 0x002001, 0x001000, CRC(37b12697) SHA1(da288b077902e3205600a021c3fac5730f9fb832) ) - ROM_LOAD16_BYTE( "l6_8.bin", 0x004000, 0x001000, CRC(1293fb9d) SHA1(5a8d512372fd38f1a55f990f5c3eb51833c463d8) ) - ROM_LOAD16_BYTE( "n6_2.bin", 0x004001, 0x001000, CRC(712c206a) SHA1(eb29f161189c14d84896502940e3ab6cc3bd1cd0) ) - ROM_LOAD16_BYTE( "l5_9.bin", 0x006000, 0x001000, CRC(743a6501) SHA1(da83a8f756466bcd94d4b0cc28a1a1858e9532f3) ) - ROM_LOAD16_BYTE( "n5_3.bin", 0x006001, 0x001000, CRC(a65cbf99) SHA1(dd06f98c0989604bd4ac6317e545e1fcf6722e75) ) - ROM_LOAD16_BYTE( "l4_a.bin", 0x008000, 0x001000, CRC(9cf1b0a1) SHA1(dd644026f49d8430c0b4cf4c750dc33c013c19fc) ) - ROM_LOAD16_BYTE( "n4_4.bin", 0x008001, 0x001000, CRC(5f0080d5) SHA1(fb1303f9a02067faea2ac4d523051c416de9cf35) ) - ROM_LOAD16_BYTE( "l3_b.bin", 0x00a000, 0x001000, CRC(8cc7f7fa) SHA1(fefb9a4fdd63878bc5d8138e3e8456cb6638425a) ) - ROM_LOAD16_BYTE( "n3_5.bin", 0x00a001, 0x001000, CRC(40452376) SHA1(1d058b7ecd2bbff3393950aab9215b262908475b) ) + ROM_LOAD16_BYTE( "6.l8", 0x000000, 0x001000, CRC(25f8da18) SHA1(e8179ba3683e39c8225b549ead74c8af2d0a0b3e) ) + ROM_LOAD16_BYTE( "0.n8", 0x000001, 0x001000, CRC(04e20626) SHA1(2b6a04992037257830df2c01a6da748fb4449f79) ) + ROM_LOAD16_BYTE( "7.l7", 0x002000, 0x001000, CRC(230e244c) SHA1(42283a368144acf2aad2ef390e312e0951c3ea64) ) + ROM_LOAD16_BYTE( "1.n7", 0x002001, 0x001000, CRC(37b12697) SHA1(da288b077902e3205600a021c3fac5730f9fb832) ) + ROM_LOAD16_BYTE( "8.l6", 0x004000, 0x001000, CRC(1293fb9d) SHA1(5a8d512372fd38f1a55f990f5c3eb51833c463d8) ) + ROM_LOAD16_BYTE( "2.n6", 0x004001, 0x001000, CRC(712c206a) SHA1(eb29f161189c14d84896502940e3ab6cc3bd1cd0) ) + ROM_LOAD16_BYTE( "9.l5", 0x006000, 0x001000, CRC(743a6501) SHA1(da83a8f756466bcd94d4b0cc28a1a1858e9532f3) ) + ROM_LOAD16_BYTE( "3.n5", 0x006001, 0x001000, CRC(a65cbf99) SHA1(dd06f98c0989604bd4ac6317e545e1fcf6722e75) ) + ROM_LOAD16_BYTE( "a.l4", 0x008000, 0x001000, CRC(9cf1b0a1) SHA1(dd644026f49d8430c0b4cf4c750dc33c013c19fc) ) + ROM_LOAD16_BYTE( "4.n4", 0x008001, 0x001000, CRC(5f0080d5) SHA1(fb1303f9a02067faea2ac4d523051c416de9cf35) ) + ROM_LOAD16_BYTE( "b.l3", 0x00a000, 0x001000, CRC(8cc7f7fa) SHA1(fefb9a4fdd63878bc5d8138e3e8456cb6638425a) ) + ROM_LOAD16_BYTE( "5.n3", 0x00a001, 0x001000, CRC(40452376) SHA1(1d058b7ecd2bbff3393950aab9215b262908475b) ) ROM_REGION( 0x10000, "audiocpu", 0 ) - ROM_LOAD( "j4_c.bin", 0x0000, 0x1000, CRC(e897dfcd) SHA1(750df3d08512d8098a13ec62677831efa164c126) ) - ROM_LOAD( "j3_d.bin", 0x1000, 0x1000, CRC(4016de77) SHA1(7232ec003f1b9d3623d762f3270108a1d1837846) ) + ROM_LOAD( "c.j4", 0x0000, 0x1000, CRC(e897dfcd) SHA1(750df3d08512d8098a13ec62677831efa164c126) ) + ROM_LOAD( "d.j3", 0x1000, 0x1000, CRC(4016de77) SHA1(7232ec003f1b9d3623d762f3270108a1d1837846) ) + + ROM_REGION( 0x3000, "proms", 0 ) /* not hooked up */ + ROM_LOAD( "l5.l5", 0x0000, 0x0020, CRC(317fb438) SHA1(3130e1dbde06228707ba46ae85d8df8cc8f32b67) ) + ROM_LOAD( "k8.k8", 0x0000, 0x1000, CRC(596ad8d9) SHA1(7e2d2d3e02712911ef5ef55d1df5740f6ec28bcb) ) + ROM_LOAD( "k9.k9", 0x0000, 0x1000, CRC(b8544823) SHA1(78ff1fcb7e640929765533592015cfccef690179) ) ROM_END diff --git a/src/mame/drivers/cclimber.cpp b/src/mame/drivers/cclimber.cpp index 79d17c18954..65f4aca72f1 100644 --- a/src/mame/drivers/cclimber.cpp +++ b/src/mame/drivers/cclimber.cpp @@ -308,6 +308,13 @@ WRITE8_MEMBER(cclimber_state::nmi_mask_w) } +READ8_MEMBER(cclimber_state::bagmanf_a000_r) +{ + // Should this actually use the same PAL16R6 as the parent set? + return 0x3f; +} + + /* Note that River Patrol reads/writes to a000-a4f0. This is a bug in the code. The instruction at 0x0593 should say LD DE,$8000 */ @@ -436,22 +443,23 @@ ADDRESS_MAP_END static ADDRESS_MAP_START( bagmanf_map, AS_PROGRAM, 8, cclimber_state ) AM_RANGE(0x0000, 0x5fff) AM_ROM AM_RANGE(0x6000, 0x6bff) AM_RAM /* Crazy Kong only */ - AM_RANGE(0x8000, 0x83ff) AM_RAM - AM_RANGE(0x8800, 0x88ff) AM_RAM AM_SHARE("bigspriteram") + AM_RANGE(0x8000, 0x8000) AM_READ_PORT("P1") + AM_RANGE(0x8800, 0x8800) AM_READ_PORT("P2") + AM_RANGE(0x8800, 0x88ff) AM_RAM AM_SHARE("bigspriteram") // wrong AM_RANGE(0x8900, 0x8bff) AM_RAM /* not used, but initialized */ AM_RANGE(0x9000, 0x93ff) AM_RAM AM_SHARE("videoram") AM_RANGE(0xffe0, 0xffff) AM_RAM AM_SHARE("column_scroll") // wrong, is this area even connected? + AM_RANGE(0x9800, 0x9800) AM_READ_PORT("SYSTEM") AM_RANGE(0x9800, 0x981f) AM_RAM AM_SHARE("spriteram") AM_RANGE(0x98dc, 0x98df) AM_RAM AM_SHARE("bigspritectrl") // wrong AM_RANGE(0x9800, 0x9bff) AM_RAM AM_SHARE("colorram") AM_RANGE(0x9c00, 0x9fff) AM_RAM /* not used, but initialized */ - AM_RANGE(0xa000, 0xa000) AM_READ_PORT("P1") AM_WRITE(nmi_mask_w) + AM_RANGE(0xa000, 0xa000) AM_READ(bagmanf_a000_r) AM_WRITE(nmi_mask_w) AM_RANGE(0xa001, 0xa002) AM_WRITEONLY AM_SHARE("flip_screen") AM_RANGE(0xa004, 0xa004) AM_DEVWRITE("cclimber_audio", cclimber_audio_device, sample_trigger_w) - - AM_RANGE(0xa800, 0xa800) AM_READ_PORT("P2") AM_DEVWRITE("cclimber_audio", cclimber_audio_device, sample_rate_w) + AM_RANGE(0xa800, 0xa800) AM_READNOP AM_DEVWRITE("cclimber_audio", cclimber_audio_device, sample_rate_w) AM_RANGE(0xb000, 0xb000) AM_READ_PORT("DSW") AM_DEVWRITE("cclimber_audio", cclimber_audio_device, sample_volume_w) - AM_RANGE(0xb800, 0xb800) AM_READ_PORT("SYSTEM") + AM_RANGE(0xb800, 0xb800) AM_READNOP ADDRESS_MAP_END static ADDRESS_MAP_START( toprollr_decrypted_opcodes_map, AS_DECRYPTED_OPCODES, 8, cclimber_state ) @@ -613,27 +621,9 @@ static INPUT_PORTS_START( ckong ) INPUT_PORTS_END static INPUT_PORTS_START( bagmanf ) - PORT_START("P1") - PORT_BIT( 0x01, IP_ACTIVE_LOW, IPT_COIN1 ) - PORT_BIT( 0x02, IP_ACTIVE_LOW, IPT_COIN2 ) - PORT_BIT( 0x04, IP_ACTIVE_LOW, IPT_START1 ) - PORT_BIT( 0x08, IP_ACTIVE_LOW, IPT_JOYSTICK_LEFT ) PORT_8WAY - PORT_BIT( 0x10, IP_ACTIVE_LOW, IPT_JOYSTICK_RIGHT ) PORT_8WAY - PORT_BIT( 0x20, IP_ACTIVE_LOW, IPT_JOYSTICK_UP ) PORT_8WAY - PORT_BIT( 0x40, IP_ACTIVE_LOW, IPT_JOYSTICK_DOWN ) PORT_8WAY - PORT_BIT( 0x80, IP_ACTIVE_LOW, IPT_BUTTON1 ) - - PORT_START("P2") - PORT_BIT( 0x01, IP_ACTIVE_LOW, IPT_COIN3 ) - PORT_BIT( 0x02, IP_ACTIVE_LOW, IPT_COIN4 ) - PORT_BIT( 0x04, IP_ACTIVE_LOW, IPT_START2 ) - PORT_BIT( 0x08, IP_ACTIVE_LOW, IPT_JOYSTICK_LEFT ) PORT_8WAY PORT_COCKTAIL - PORT_BIT( 0x10, IP_ACTIVE_LOW, IPT_JOYSTICK_RIGHT ) PORT_8WAY PORT_COCKTAIL - PORT_BIT( 0x20, IP_ACTIVE_LOW, IPT_JOYSTICK_UP ) PORT_8WAY PORT_COCKTAIL - PORT_BIT( 0x40, IP_ACTIVE_LOW, IPT_JOYSTICK_DOWN ) PORT_8WAY PORT_COCKTAIL - PORT_BIT( 0x80, IP_ACTIVE_LOW, IPT_BUTTON1 ) PORT_COCKTAIL + PORT_INCLUDE( ckong ) - PORT_START("DSW") + PORT_MODIFY("DSW") PORT_DIPNAME( 0x03, 0x02, DEF_STR( Lives ) ) PORT_DIPLOCATION("SW1:1,2") PORT_DIPSETTING( 0x03, "2" ) PORT_DIPSETTING( 0x02, "3" ) @@ -656,8 +646,6 @@ static INPUT_PORTS_START( bagmanf ) PORT_DIPNAME( 0x80, 0x80, DEF_STR( Cabinet ) ) /* Cabinet type set through edge connector, not dip switch (verified on real pcb) */ PORT_DIPSETTING( 0x80, DEF_STR( Upright ) ) PORT_DIPSETTING( 0x00, DEF_STR( Cocktail ) ) - - PORT_START("SYSTEM") INPUT_PORTS_END /* Similar to normal Crazy Kong except for the lives per game */ @@ -2277,6 +2265,7 @@ ROM_END this set also explains why the cannonball set above contained a number of bagman roms, it was clearly a half-converted board. + A bootleg of "Le Bagnard" with a KCK-series motherboard has also been observed. */ ROM_START( bagmanf ) ROM_REGION( 0x6000, "maincpu", 0 ) @@ -2297,8 +2286,8 @@ ROM_START( bagmanf ) ROM_REGION( 0x2000, "gfx2", ROMREGION_ERASE00 ) ROM_REGION( 0x0060, "proms", 0 ) - ROM_LOAD( "v6", 0x0000, 0x0020, CRC(b3fc1505) SHA1(5b94adde0428a26b815c7eb9b3f3716470d349c7) ) - ROM_LOAD( "u6", 0x0020, 0x0020, CRC(26aada9e) SHA1(f59645e606ea4f0dd0fc4ea47dd03f526c534941) ) + ROM_LOAD( "v6", 0x0020, 0x0020, CRC(b3fc1505) SHA1(5b94adde0428a26b815c7eb9b3f3716470d349c7) ) + ROM_LOAD( "u6", 0x0000, 0x0020, CRC(26aada9e) SHA1(f59645e606ea4f0dd0fc4ea47dd03f526c534941) ) ROM_LOAD( "t6", 0x0040, 0x0020, CRC(676b3166) SHA1(29b9434cd34d43ea5664e436e2a24b54f8d88aac) ) /* as well as one of the program roms, the daughterboard contains the speech hardware + roms */ diff --git a/src/mame/drivers/dec0.cpp b/src/mame/drivers/dec0.cpp index 11b387ccca6..ec8a5206c7f 100644 --- a/src/mame/drivers/dec0.cpp +++ b/src/mame/drivers/dec0.cpp @@ -168,6 +168,7 @@ Notes: #include "cpu/h6280/h6280.h" #include "cpu/z80/z80.h" #include "cpu/mcs51/mcs51.h" +#include "cpu/m6805/m68705.h" #include "includes/dec0.h" #include "sound/2203intf.h" #include "sound/3812intf.h" @@ -1668,6 +1669,9 @@ static MACHINE_CONFIG_DERIVED( midresb, midres ) MCFG_CPU_REPLACE("audiocpu", M6502, 1500000 ) MCFG_CPU_PROGRAM_MAP(dec0_s_map) + MCFG_CPU_ADD("mcu", M68705R3, XTAL_3_579545MHz) + MCFG_DEVICE_DISABLE() + MCFG_SOUND_MODIFY("ym2") MCFG_YM3812_IRQ_HANDLER(INPUTLINE("audiocpu", 0)) MCFG_SOUND_ROUTE(ALL_OUTPUTS, "mono", 0.80) @@ -1685,6 +1689,10 @@ static MACHINE_CONFIG_DERIVED( midresb, midres ) MACHINE_CONFIG_END +static MACHINE_CONFIG_DERIVED( midresbj, midresb ) + MCFG_DEVICE_REMOVE("mcu") +MACHINE_CONFIG_END + /******************************************************************************/ ROM_START( hbarrel ) @@ -2685,7 +2693,7 @@ ROM_START( ffantasybl ) ROM_REGION( 0x10000, "audiocpu", 0 ) /* 6502 sound */ ROM_LOAD( "15.bin", 0x8000, 0x8000, CRC(9871b98d) SHA1(2b6c46bc2b10a28946d6ad8251e1a156a0b99947) ) - ROM_REGION( 0x10000, "cpu2", 0 ) /* 68705 MCU */ // (labeled on PCB as Z80, but it isn't!) + ROM_REGION( 0x1000, "mcu", 0 ) /* 68705 MCU */ // (labeled on PCB as Z80, but it isn't!) ROM_LOAD( "68705u3.bin", 0x00000, 0x1000, NO_DUMP ) // nor dumped, maybe it's the same as the midresb one? ROM_REGION( 0x20000, "gfx1", 0 ) /* chars */ @@ -3181,7 +3189,7 @@ ROM_START( midresb ) ROM_REGION( 0x10000, "audiocpu", 0 ) /* 6502 sound */ // same as hippodrome / fighting fantasy... ROM_LOAD( "15.bin", 0x8000, 0x8000, CRC(9871b98d) SHA1(2b6c46bc2b10a28946d6ad8251e1a156a0b99947) ) - ROM_REGION( 0x10000, "cpu2", 0 ) /* 68705 MCU */ + ROM_REGION( 0x1000, "mcu", 0 ) /* 68705 MCU */ ROM_LOAD( "68705r3.bin", 0x00000, 0x1000, CRC(ad5b1c13) SHA1(3616dc5969323a54e3e171d169f76250ae4e711a) ) ROM_REGION( 0x20000, "gfx1", 0 ) /* chars */ @@ -3233,7 +3241,7 @@ ROM_START( midresbj ) ROM_REGION( 0x10000, "audiocpu", 0 ) /* 6502 sound */ ROM_LOAD( "15", 0x0000, 0x10000, CRC(99d47166) SHA1(a9a1adfe47be8dd3e4d6f8c783447e09be1747b2) ) - ROM_REGION( 0x10000, "cpu2", ROMREGION_ERASE00 ) /* 68705 MCU */ + ROM_REGION( 0x1000, "mcu", ROMREGION_ERASE00 ) /* 68705 MCU */ //ROM_LOAD( "68705r3.bin", 0x00000, 0x1000, CRC(ad5b1c13) SHA1(3616dc5969323a54e3e171d169f76250ae4e711a) ) // unpopulated socket ROM_REGION( 0x20000, "gfx1", 0 ) /* chars */ @@ -3416,7 +3424,7 @@ GAME( 1988, drgninjab, baddudes, baddudes, drgninja, dec0_state, baddudes, ROT0 // this is a common bootleg board GAME( 1989, midresb, midres, midresb, midresb, dec0_state, midresb, ROT0, "bootleg", "Midnight Resistance (bootleg with 68705)", MACHINE_SUPPORTS_SAVE ) // need to hook up 68705? (probably unused) -GAME( 1989, midresbj, midres, midresb, midresb, dec0_state, midresb, ROT0, "bootleg", "Midnight Resistance (Joystick bootleg)", MACHINE_SUPPORTS_SAVE ) +GAME( 1989, midresbj, midres, midresbj, midresb, dec0_state, midresb, ROT0, "bootleg", "Midnight Resistance (Joystick bootleg)", MACHINE_SUPPORTS_SAVE ) GAME( 1989, ffantasybl, hippodrm, ffantasybl, ffantasybl, dec0_state, ffantasybl, ROT0, "bootleg", "Fighting Fantasy (bootleg with 68705)", MACHINE_IMPERFECT_GRAPHICS | MACHINE_SUPPORTS_SAVE ) // 68705 not dumped, might be the same as midresb GAME( 1988, drgninjab2, baddudes, baddudes, drgninja, dec0_state, baddudes, ROT0, "bootleg", "Dragonninja (bootleg with 68705)", MACHINE_SUPPORTS_SAVE ) // is this the same board as above? (region warning hacked to World, but still shows Japanese text) diff --git a/src/mame/drivers/fccpu20.cpp b/src/mame/drivers/fccpu20.cpp index 5d951b25216..c8017ba0e82 100644 --- a/src/mame/drivers/fccpu20.cpp +++ b/src/mame/drivers/fccpu20.cpp @@ -11,57 +11,112 @@ * * * || - * || || CPU-20 + * || || CPU-21 - main board * ||||--||_____________________________________________________________ * ||||--|| | * || || _ |__ * || | | | - * || | | | - * || | | | - * || | | | - * || | | | - * || | | | - * || | |VME| - * || | | | - * || | |P1 | - * || | | | - * || | | | - * || | | | - * || | | | - * || | | | - * || | | | - * || |_| | - * || |___| - * || | - * || | - * || | - * || | - * || | - * || | + * RST o-[| | | | + * || +-------+ | | | + * ABT o-[| | XTAL | | | | + * || | 50MHz | +-----------------------+ | | | + * RUN C| +-------+ | MPCC | | | | + * HALT C| +-------+ | R68561P | | |VME| + * BM C| | XTAL | +-----------------------+ | | | + * || | 40MHz | +-----------------------+ | |P1 | + * || +-------+ | PIT | | | | + * FLMA C| +-------+ | MC68230P8 | | | | + * EPROM C| | XTAL | +-----------------------+ | | | + * 2WST C| | 32MHz | | | | + * 4WST C| +-------+ | | | + * 6WST C| | | | + * 8WST C| |_| | + * 12WST C| +--------------------+ |___| + * 14WST C| | BIM | | + * || | MC68153L | | + * || +--------------------+ | + * CSH o-[| | * || | + * R/H o-[| | * || | + * DIP0 - +----------------+ | + * . - | | |___ + * . - | | +---+ _| | + * . - | CPU | | |+------------+ | | | + * . - | M68020 | | || 27128 | | | | + * . - | | | || EPROM | | | | + * . - | | | |+------------+ | | | + * DIP7 - | | | F | | |VME| + * || +----------------+ | L |+------------+ | | | + * || | M || 27128 | | |P2 | + * [|||O +------------+ | E || EPROM | | | | + * +-|||| | | | |+------------+ | | | + * | |||| | FPU | | m | | | | + * | |||| | 68881 | | e |+------------+ | | | + * | |||| | | | m || 27128 | | | | + * | |||| | | | || EPROM | | | | + * P4 | |||| +------------+ | b |+------------+ | | | + * | |||| | u | | | | + * +-|||| | s |+------------+ |_| | + * [|||O | || 27128 | |___| + * || || | || EPROM | | + * ||||--|| +---++------------+ | + * ||||--||-------------------------------------------------------------+ + * || + * + * + * || + * || || CPU-21 - slave board (SRAM-22 - connected via FLME mem bus) + * ||||--||_____________________________________________________________ + * ||||--|| | + * || || 64 x 64Kbit SRAM = 512KB __|__ + * || +-----------+ +-----------+ +-----------+ +-----------+| | | + * || |IMS1600 | | | | | | || | | + * || +-----------+ +-----------+ +-----------+ +-----------+| | | + * RUN C| | | | | | | | || | | + * || +-----------+ +-----------+ +-----------+ +-----------+| | | + * || | | | | | | | || | | + * || +-----------+ +-----------+ +-----------+ +-----------+| |VME| + * SEL0 C| | | | | | | | || | | + * SEL1 C| +-----------+ +-----------+ +-----------+ +-----------+| |P1 | + * || | | | | | | | || | | + * || +-----------+ +-----------+ +-----------+ +-----------+| | | + * || | | | | | | | || | | + * || +-----------+ +-----------+ +-----------+ +-----------+| | | + * || | | | | | | | || | | + * || +-----------+ +-----------+ +-----------+ +-----------+| | | + * || | | | | | | | ||_| | + * || +-----------+ +-----------+ +-----------+ +-----------+ |___| + * || | | | | | | | | | + * || +-----------+ +-----------+ +-----------+ +-----------+ | + * || | | | | | | | | | + * || +-----------+ +-----------+ +-----------+ +-----------+ | + * || | | | | | + * || +-----------+ +-----------+ +-----------+ +-----------+ | + * || | | | | | | | | | + * || +-----------+ +-----------+ +-----------+ +-----------+ | * || |___ - * || _| | - * || | | | - * || | | | - * || | | | - * || | | | - * || | |VME| - * || | | | - * || | |P2 | - * || | | | - * || | | | - * || | | | - * || | | | - * || | | | - * || | | | - * || | | | - * || | | | - * || |_| | - * || |___| - * || || + - * ||||--|| | - * ||||--||--------------------------------------------------------------+ + * || +---++-----------+ +-----------+ _| | + * || | || | | || | | + * || | |+-----------+ +-----------+| | | + * || | || | | || | | + * || | |+-----------+ +-----------+| | | + * || | F || | | || |VME| + * || | L |+-----------+ +-----------+| | | + * || | M | | |P2 | + * [|||O | E | | | | + * +-|||| | | | | | + * | |||| | m | | | | + * | |||| | e | | | | + * | |||| | m | | | | + * | |||| | | | | | + * P8? | |||| | b | | | | + * | |||| | u | +-----------------------+ | | | + * +-|||| | s | | MPCC | |_| | + * [|||O | | | R68561P | |___| + * || || | | +-----------------------+ | + * ||||--|| +---+ (XTAL) | + * ||||--||------------------------------------------------------------+ * || * * History of Force Computers @@ -103,9 +158,11 @@ Basadressen av I / O-enheter: * FBFF0000-FBFFFFFF VME A16 D8-D32 * FC000000-FCFEFFFF VME A24 D8-D16 * FCFF0000-FCFFFFFF VME A16 D8-D16 + * FF800000 MPCC + * FF800200 MPCC1 - on daughter board + * FF800600 MPCC2 - on daughter board * FF800800 BIM * FF800C00 PIT - * FF800000 MPCC * FF800A00 RTC * -------------------------------------------------------------------------- * @@ -142,9 +199,9 @@ Basadressen av I / O-enheter: *--------------------------------------------------------------------------- * TODO: * - Find accurate documentation and adjust memory map - * - Add layout - * - Write & add 68561 UART - * - Add 68230 PIT + * - Add PCB layout + * - Improve 68561 UART + * - Improve hookup of 68230 PIT * - Add variants of boards in the CPU-20 and CPU-21 family * - Add FGA, DUSCC devices and CPU-22 variants * @@ -158,6 +215,7 @@ Basadressen av I / O-enheter: #include "bus/rs232/rs232.h" #include "machine/68230pit.h" #include "machine/68153bim.h" +#include "machine/68561mpcc.h" #include "machine/clock.h" #define LOG_GENERAL 0x01 @@ -192,6 +250,9 @@ cpu20_state(const machine_config &mconfig, device_type type, const char *tag) , m_maincpu (*this, "maincpu") , m_pit (*this, "pit") , m_bim (*this, "bim") + , m_mpcc (*this, "mpcc") + , m_mpcc2 (*this, "mpcc2") + , m_mpcc3 (*this, "mpcc3") { } DECLARE_READ32_MEMBER (bootvect_r); @@ -204,10 +265,18 @@ cpu20_state(const machine_config &mconfig, device_type type, const char *tag) virtual void machine_start () override; virtual void machine_reset () override; + /* PIT callbacks */ + DECLARE_READ8_MEMBER (pita_r); + DECLARE_READ8_MEMBER (pitb_r); + DECLARE_READ8_MEMBER (pitc_r); + private: required_device<m68000_base_device> m_maincpu; required_device<pit68230_device> m_pit; required_device<bim68153_device> m_bim; + required_device<mpcc68561_device> m_mpcc; + required_device<mpcc68561_device> m_mpcc2; + required_device<mpcc68561_device> m_mpcc3; // Pointer to System ROMs needed by bootvect_r and masking RAM buffer for post reset accesses uint32_t *m_sysrom; @@ -224,8 +293,10 @@ static ADDRESS_MAP_START (cpu20_mem, AS_PROGRAM, 32, cpu20_state) AM_RANGE (0x00000008, 0x003fffff) AM_RAM /* RAM installed in machine start */ AM_RANGE (0xff040000, 0xff04ffff) AM_RAM /* RAM installed in machine start */ AM_RANGE (0xff000000, 0xff00ffff) AM_ROM AM_REGION("roms", 0x0000) -// AM_RANGE (0xff800000, 0xff80000f) AM_DEVREADWRITE8("mpcc", mpcc68561_device, read, write, 0x00ff00ff) -// AM_RANGE (0xff800200, 0xff80020f) AM_DEVREADWRITE8("pit2", pit68230_device, read, write, 0xff00ff00) + AM_RANGE (0xff800000, 0xff80001f) AM_DEVREADWRITE8("mpcc", mpcc68561_device, read, write, 0xffffffff) + AM_RANGE (0xff800200, 0xff80021f) AM_DEVREADWRITE8("mpcc2", mpcc68561_device, read, write, 0xffffffff) +// AM_RANGE (0xff800200, 0xff8003ff) AM_DEVREADWRITE8("pit2", pit68230_device, read, write, 0xff00ff00) + AM_RANGE (0xff800600, 0xff80061f) AM_DEVREADWRITE8("mpcc3", mpcc68561_device, read, write, 0xffffffff) AM_RANGE (0xff800800, 0xff80080f) AM_DEVREADWRITE8("bim", bim68153_device, read, write, 0xff00ff00) // AM_RANGE (0xff800a00, 0xff800a0f) AM_DEVREADWRITE8("rtc", rtc_device, read, write, 0x00ff00ff) AM_RANGE (0xff800c00, 0xff800dff) AM_DEVREADWRITE8("pit", pit68230_device, read, write, 0xffffffff) @@ -254,6 +325,8 @@ void cpu20_state::machine_reset () /* Reset pointer to bootvector in ROM for bootvector handler bootvect_r */ if (m_sysrom == &m_sysram[0]) /* Condition needed because memory map is not setup first time */ m_sysrom = (uint32_t*)(memregion ("roms")->base()); + + m_pit->h1_w(1); // signal no ACFAIL or SYSFAIL } #if 0 @@ -310,6 +383,48 @@ void cpu20_state::update_irq_to_maincpu() } } +/* 8 configuration DIP switches + + Baud B3 B2 B1 B0 + 9600 0 0 0 1 + 28800 0 0 1 0 + 38400 1 0 1 0 + 57600 0 0 1 1 + + B3: 8 bit 38400 baud + + B4: + + B5: + + B6: Auto execute FF00C0000 + + B7: memory size? +*/ +#define BR7N9600 0x01 +#define BR7N28800 0x02 +#define BR7N38400 0x06 +#define BR7N57600 0x03 +#define BR8N38400 0x08 +#define FORCEBUG 0x30 +READ8_MEMBER (cpu20_state::pita_r){ + LOG("%s\n", FUNCNAME); + + return FORCEBUG | BR7N9600; +} + +/* Enabling/Disabling of VME IRQ 1-7 */ +READ8_MEMBER (cpu20_state::pitb_r){ + LOG("%s\n", FUNCNAME); + return 0xff; +} + +/* VME bus release software settings (output) (ROR, RAT, RATAR, RATBCLR, RORAT, RORRAT */ +READ8_MEMBER (cpu20_state::pitc_r){ + LOG("%s\n", FUNCNAME); + return 0xff; +} + static SLOT_INTERFACE_START(fccpu20_vme_cards) SLOT_INTERFACE("fcisio", VME_FCISIO1) SLOT_INTERFACE("fcscsi", VME_FCSCSI1) @@ -325,20 +440,62 @@ static MACHINE_CONFIG_START (cpu20, cpu20_state) MCFG_CPU_IRQ_ACKNOWLEDGE_DEVICE("bim", bim68153_device, iack) MCFG_VME_DEVICE_ADD("vme") - MCFG_VME_SLOT_ADD ("vme", "slot1", fccpu20_vme_cards, nullptr) + MCFG_VME_SLOT_ADD ("vme", "vme1", fccpu20_vme_cards, nullptr) /* PIT Parallel Interface and Timer device, assumed strapped for on board clock */ - MCFG_DEVICE_ADD ("pit", PIT68230, XTAL_8_664MHz) + MCFG_DEVICE_ADD ("pit", PIT68230, XTAL_32MHz / 4) /* Crystal not verified */ + MCFG_PIT68230_PA_INPUT_CB(READ8(cpu20_state, pita_r)) + MCFG_PIT68230_PB_INPUT_CB(READ8(cpu20_state, pitb_r)) + MCFG_PIT68230_PC_INPUT_CB(READ8(cpu20_state, pitc_r)) MCFG_PIT68230_TIMER_IRQ_CB(DEVWRITELINE("bim", bim68153_device, int2_w)) -// MCFG_DEVICE_ADD ("pit2", PIT68230, XTAL_8_664MHz) - - MCFG_MC68153_ADD("bim", XTAL_16MHz / 2) + /* BIM */ + MCFG_MC68153_ADD("bim", XTAL_32MHz / 8) MCFG_BIM68153_OUT_INT_CB(WRITELINE(cpu20_state, bim_irq_callback)) /*INT0 - Abort switch */ /*INT1 - MPCC@8.064 MHz aswell */ /*INT2 - PI/T timer */ /*INT3 - SYSFAIL/IRQVMX/ACFAIL/MPCC2/3 */ + + /* MPCC */ +#define RS232P1_TAG "rs232p1" +#define RS232P2_TAG "rs232p2" +#define RS232P3_TAG "rs232p3" + // MPCC + MCFG_MPCC68561_ADD ("mpcc", XTAL_32MHz / 4, 0, 0) + MCFG_MPCC_OUT_TXD_CB(DEVWRITELINE(RS232P1_TAG, rs232_port_device, write_txd)) + MCFG_MPCC_OUT_DTR_CB(DEVWRITELINE(RS232P1_TAG, rs232_port_device, write_dtr)) + MCFG_MPCC_OUT_RTS_CB(DEVWRITELINE(RS232P1_TAG, rs232_port_device, write_rts)) + MCFG_MPCC_OUT_INT_CB(DEVWRITELINE("bim", bim68153_device, int1_w)) + /* Additional MPCC sits on slave boards like SRAM-22 */ + // MPCC2 + MCFG_MPCC68561_ADD ("mpcc2", XTAL_32MHz / 4, 0, 0) + MCFG_MPCC_OUT_TXD_CB(DEVWRITELINE(RS232P2_TAG, rs232_port_device, write_txd)) + MCFG_MPCC_OUT_DTR_CB(DEVWRITELINE(RS232P2_TAG, rs232_port_device, write_dtr)) + MCFG_MPCC_OUT_RTS_CB(DEVWRITELINE(RS232P2_TAG, rs232_port_device, write_rts)) + MCFG_MPCC_OUT_INT_CB(DEVWRITELINE("bim", bim68153_device, int3_w)) + // MPCC3 + MCFG_MPCC68561_ADD ("mpcc3", XTAL_32MHz / 4, 0, 0) + MCFG_MPCC_OUT_TXD_CB(DEVWRITELINE(RS232P3_TAG, rs232_port_device, write_txd)) + MCFG_MPCC_OUT_DTR_CB(DEVWRITELINE(RS232P3_TAG, rs232_port_device, write_dtr)) + MCFG_MPCC_OUT_RTS_CB(DEVWRITELINE(RS232P3_TAG, rs232_port_device, write_rts)) + MCFG_MPCC_OUT_INT_CB(DEVWRITELINE("bim", bim68153_device, int3_w)) + + // MPCC - RS232 + MCFG_RS232_PORT_ADD (RS232P1_TAG, default_rs232_devices, "terminal") + MCFG_RS232_RXD_HANDLER (DEVWRITELINE ("mpcc", mpcc68561_device, write_rx)) + MCFG_RS232_CTS_HANDLER (DEVWRITELINE ("mpcc", mpcc68561_device, cts_w)) + + // MPCC2 - RS232 + MCFG_RS232_PORT_ADD (RS232P2_TAG, default_rs232_devices, nullptr) + MCFG_RS232_RXD_HANDLER (DEVWRITELINE ("mpcc2", mpcc68561_device, write_rx)) + MCFG_RS232_CTS_HANDLER (DEVWRITELINE ("mpcc2", mpcc68561_device, cts_w)) + + // MPCC3 - RS232 + MCFG_RS232_PORT_ADD (RS232P3_TAG, default_rs232_devices, nullptr) + MCFG_RS232_RXD_HANDLER (DEVWRITELINE ("mpcc3", mpcc68561_device, write_rx)) + MCFG_RS232_CTS_HANDLER (DEVWRITELINE ("mpcc3", mpcc68561_device, cts_w)) + MACHINE_CONFIG_END /* ROM definitions */ @@ -364,7 +521,7 @@ ROM_END * : 0 Reg control <- 57 - Lev:7 Auto Disable:0 Int Enable:1 Vector:0 Auto Clear:1 Flag:0 * : 1 Reg control <- 54 - Lev:4 Auto Disable:0 Int Enable:1 Vector:0 Auto Clear:1 Flag:0 * : 2 Reg control <- 55 - Lev:5 Auto Disable:0 Int Enable:1 Vector:0 Auto Clear:1 Flag:0 - * : 3 Reg control <- 54 - Lev:4 Auto Disable:0 Int Enable:1 Vector:0 Auto Clear:1 Flag:0 + * : 3 Reg control <- 54 - Lev:4 Auto Disable:0 Int Enable:1 Vector:0 Auto Clear:1 Flag:0 * * PIT setup: * :pit Reg 0a -> 00 @@ -384,6 +541,30 @@ ROM_END - PC2 used as I/O pin,CLK and x32 prescaler are used - Timer reload the preload values when reaching 0 (zero) - Timer is enabled + * MPCC setup + * : Reg 19 <- 1e - PSR2: Byte mode, 1 Stop bit, 8 bit data, ASYNC mode + * : Reg 1c <- 8a - BRDR1: Baud Rate Divider 1 + * : Reg 1d <- 00 - BRDR1: Baud Rate Divider 2 + * : Reg 1e <- 1c - CCR: x3 Mode, TxC is output, internal RxC, ISOC + * : Reg 1f <- 00 - ECR: No parity + * : Reg 0d <- 00 - TIER: interrupts disabled + * : Reg 15 <- 00 - SIER: interrupts disabled + * : Reg 05 <- 80 - RIER: enable RDA interrupts + * : Reg 01 <- 01 - RCR: Reset receiver command + * : Reg 01 <- 00 - RCR: Reciver in normal operation + * : Reg 09 <- 01 - TCR: Reset transmitter command + * : Reg 09 <- 80 - TCR: Transmitter in normal operation + * : Reg 11 <- c0 - SICR: Assert RTS, Assert DTR + * : Reg 08 -> 80 - TSR: Tx FIFO has room + * : Reg 0a <- 0a - TDR: send 0x0a to Tx FIFO... etc + * + * TDR outputs: + * "Disk Controller installed + * Disk #0: Header sector error = 145 + * Disk #1: Header sector error = 145 + * Out of PDOS boot disk table entries. + * I'LL Retry them all." + * */ /* Driver */ diff --git a/src/mame/drivers/fccpu30.cpp b/src/mame/drivers/fccpu30.cpp index 33ea2d70ce7..04beb099114 100644 --- a/src/mame/drivers/fccpu30.cpp +++ b/src/mame/drivers/fccpu30.cpp @@ -70,6 +70,14 @@ * * History of Force Computers *--------------------------- + * 1981 Force Computers was founded in San Jose, California. Over time a European headquarter was opened + * in Munich, Germany, and a Japanese headquarter in Tokyo + * 1996 Force was aquired by Solectron Corporation in 1996 + * 2004 Force was sold off from Solectron to Motorola + * 2008 Force was aquired by Emerson as part of the Motorola Embedded Division + * 2016 Force was aquired by Platinum Equity as part of the Emerson Network Power Division + * + * Force developed and produced VME board products based on SPARC, Pentium, PowerPC and 68K. * * Misc links about Force Computes and this board: *------------------------------------------------ diff --git a/src/mame/drivers/gladiatr.cpp b/src/mame/drivers/gladiatr.cpp index 828fa447413..7b915a13739 100644 --- a/src/mame/drivers/gladiatr.cpp +++ b/src/mame/drivers/gladiatr.cpp @@ -270,22 +270,6 @@ WRITE8_MEMBER(gladiatr_state::gladiatr_irq_patch_w) WRITE_LINE_MEMBER(gladiatr_state::tclk_w) { m_tclk_val = state != 0; - - // these are actually edge-triggered, but MAME only supports polled inputs - - u8 const new_in0_val(m_in0->read()); - if (BIT(~new_in0_val & (new_in0_val ^ m_in0_val), 5)) - m_cctl_p1 = (m_cctl_p1 & 0xfc) | BIT(~new_in0_val, 5) | (BIT(~new_in0_val, 5) << 1); - else - m_cctl_p1 = (m_cctl_p1 & 0xfe) | BIT(~new_in0_val, 5); - m_in0_val = new_in0_val; - - u8 const new_in1_val(m_in0->read()); - if (BIT(~new_in1_val & (new_in1_val ^ m_in1_val), 5)) - m_cctl_p2 = (m_cctl_p2 & 0xfc) | BIT(~new_in1_val, 5) | (BIT(~new_in1_val, 5) << 1); - else - m_cctl_p2 = (m_cctl_p2 & 0xfe) | BIT(~new_in1_val, 5); - m_in1_val = new_in1_val; } READ8_MEMBER(gladiatr_state::cctl_p1_r) @@ -370,6 +354,33 @@ READ8_MEMBER(gladiatr_state::csnd_p2_r) } +INPUT_CHANGED_MEMBER(gladiatr_state::p1_s1) +{ + // P11 gets the value of 1P-S2 at the moment 1P-S1 was pressed + if (oldval && !newval) + m_cctl_p1 = (m_cctl_p1 & 0xfd) | (BIT(m_cctl_p1, 0) << 1); +} + +INPUT_CHANGED_MEMBER(gladiatr_state::p1_s2) +{ + // P10 is high when 1P-S2 is pressed + m_cctl_p1 = (m_cctl_p1 & 0xfe) | (newval ? 0x00 : 0x01); +} + +INPUT_CHANGED_MEMBER(gladiatr_state::p2_s1) +{ + // P21 gets the value of 2P-S2 at the moment 2P-S1 was pressed + if (oldval && !newval) + m_cctl_p2 = (m_cctl_p2 & 0xfd) | (BIT(m_cctl_p2, 0) << 1); +} + +INPUT_CHANGED_MEMBER(gladiatr_state::p2_s2) +{ + // P20 is high when 2P-S2 is pressed + m_cctl_p2 = (m_cctl_p2 & 0xfe) | (newval ? 0x00 : 0x01); +} + + READ8_MEMBER(ppking_state::ppking_f1_r) { @@ -622,8 +633,8 @@ static INPUT_PORTS_START( gladiatr ) PORT_BIT( 0x02, IP_ACTIVE_LOW, IPT_JOYSTICK_LEFT ) PORT_8WAY PORT_BIT( 0x04, IP_ACTIVE_LOW, IPT_JOYSTICK_UP ) PORT_8WAY PORT_BIT( 0x08, IP_ACTIVE_LOW, IPT_JOYSTICK_DOWN ) PORT_8WAY - PORT_BIT( 0x10, IP_ACTIVE_LOW, IPT_BUTTON1 ) PORT_8WAY - PORT_BIT( 0x20, IP_ACTIVE_LOW, IPT_BUTTON2 ) PORT_8WAY + PORT_BIT( 0x10, IP_ACTIVE_LOW, IPT_BUTTON1 ) PORT_CHANGED_MEMBER(DEVICE_SELF, gladiatr_state, p1_s1, 0) + PORT_BIT( 0x20, IP_ACTIVE_LOW, IPT_BUTTON2 ) PORT_CHANGED_MEMBER(DEVICE_SELF, gladiatr_state, p2_s2, 0) PORT_BIT( 0x40, IP_ACTIVE_LOW, IPT_START1 ) PORT_BIT( 0x80, IP_ACTIVE_LOW, IPT_START2 ) @@ -632,8 +643,8 @@ static INPUT_PORTS_START( gladiatr ) PORT_BIT( 0x02, IP_ACTIVE_LOW, IPT_JOYSTICK_LEFT ) PORT_8WAY PORT_COCKTAIL PORT_BIT( 0x04, IP_ACTIVE_LOW, IPT_JOYSTICK_UP ) PORT_8WAY PORT_COCKTAIL PORT_BIT( 0x08, IP_ACTIVE_LOW, IPT_JOYSTICK_DOWN ) 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( 0x10, IP_ACTIVE_LOW, IPT_BUTTON1 ) PORT_COCKTAIL PORT_CHANGED_MEMBER(DEVICE_SELF, gladiatr_state, p2_s1, 0) + PORT_BIT( 0x20, IP_ACTIVE_LOW, IPT_BUTTON2 ) PORT_COCKTAIL PORT_CHANGED_MEMBER(DEVICE_SELF, gladiatr_state, p2_s2, 0) PORT_BIT( 0xc0, IP_ACTIVE_LOW, IPT_UNUSED ) // coin counter outputs PORT_START("IN2") // cctl p1 @@ -1143,16 +1154,12 @@ DRIVER_INIT_MEMBER(gladiatr_state,gladiatr) membank("bank2")->set_entry(0); m_tclk_val = false; - m_in0_val = 0xff; - m_in1_val = 0xff; m_cctl_p1 = 0xff; m_cctl_p2 = 0xff; m_ucpu_p1 = 0xff; m_csnd_p1 = 0xff; save_item(NAME(m_tclk_val)); - save_item(NAME(m_in0_val)); - save_item(NAME(m_in1_val)); save_item(NAME(m_cctl_p1)); save_item(NAME(m_cctl_p2)); save_item(NAME(m_ucpu_p1)); diff --git a/src/mame/drivers/goldstar.cpp b/src/mame/drivers/goldstar.cpp index bf75c1ca50f..906f2e20c3d 100644 --- a/src/mame/drivers/goldstar.cpp +++ b/src/mame/drivers/goldstar.cpp @@ -922,8 +922,22 @@ ADDRESS_MAP_END /* need to check item by item... - PPIs are OK. - RAM/ROM are OK. + + PPIs are OK: + B800 = 9B (A, B, C, all input) + B810 = 9B (A, B, C, all input) + B820 = 90 (A input, B & C output) + + RAM/ROM/NVRAM are OK. + + Reels RAM and scroll are OK. + (only reel 2 seems to be used by the game) + + Video & atr RAM are OK. + + PSG is OK. + + AY8910 ports are OK. */ static ADDRESS_MAP_START( mbstar_map, AS_PROGRAM, 8, goldstar_state ) AM_RANGE(0x0000, 0x7fff) AM_ROM @@ -4111,6 +4125,163 @@ static INPUT_PORTS_START( bingownga ) PORT_DIPSETTING( 0x28, "1 Coin/10 Credits" ) INPUT_PORTS_END +static INPUT_PORTS_START( mbstar ) + PORT_START("IN0") + PORT_BIT( 0x01, IP_ACTIVE_LOW, IPT_OTHER ) PORT_CODE(KEYCODE_1) PORT_NAME("IN0-1") + PORT_BIT( 0x02, IP_ACTIVE_LOW, IPT_SERVICE ) PORT_CODE(KEYCODE_2) PORT_NAME("Increment top's 'S' (bet?)") // Increment top's 'S' (looks like bet) + PORT_BIT( 0x04, IP_ACTIVE_LOW, IPT_OTHER ) PORT_CODE(KEYCODE_3) PORT_NAME("IN0-3") + PORT_BIT( 0x08, IP_ACTIVE_LOW, IPT_OTHER ) PORT_CODE(KEYCODE_4) PORT_NAME("IN0-4") + PORT_BIT( 0x10, IP_ACTIVE_LOW, IPT_SERVICE ) PORT_CODE(KEYCODE_5) PORT_NAME("Collect") // Collect. Also used to blank the BK. + PORT_BIT( 0x20, IP_ACTIVE_LOW, IPT_OTHER ) PORT_CODE(KEYCODE_6) PORT_NAME("IN0-6") + PORT_BIT( 0x40, IP_ACTIVE_LOW, IPT_SERVICE ) PORT_CODE(KEYCODE_7) PORT_NAME("Bookkeeping: Down") // BK: down. + PORT_BIT( 0x80, IP_ACTIVE_LOW, IPT_SERVICE ) PORT_CODE(KEYCODE_8) PORT_NAME("Bookkeeping: Set/Enter - Start") // BK: enter. (start?) + + PORT_START("IN1") + PORT_BIT( 0x01, IP_ACTIVE_LOW, IPT_OTHER ) PORT_CODE(KEYCODE_Q) PORT_NAME("IN1-1") + PORT_BIT( 0x02, IP_ACTIVE_LOW, IPT_OTHER ) PORT_CODE(KEYCODE_W) PORT_NAME("IN1-2") + PORT_BIT( 0x04, IP_ACTIVE_LOW, IPT_OTHER ) PORT_CODE(KEYCODE_E) PORT_NAME("IN1-3") + PORT_BIT( 0x08, IP_ACTIVE_LOW, IPT_OTHER ) PORT_CODE(KEYCODE_R) PORT_NAME("IN1-4") + PORT_BIT( 0x10, IP_ACTIVE_LOW, IPT_OTHER ) PORT_CODE(KEYCODE_T) PORT_NAME("IN1-5") + PORT_BIT( 0x20, IP_ACTIVE_LOW, IPT_OTHER ) PORT_CODE(KEYCODE_Y) PORT_NAME("IN1-6") + PORT_BIT( 0x40, IP_ACTIVE_LOW, IPT_OTHER ) PORT_CODE(KEYCODE_U) PORT_NAME("IN1-7") + PORT_BIT( 0x80, IP_ACTIVE_LOW, IPT_OTHER ) PORT_CODE(KEYCODE_I) PORT_NAME("IN1-8") + + PORT_START("IN2") + PORT_BIT( 0x01, IP_ACTIVE_LOW, IPT_OTHER ) PORT_CODE(KEYCODE_A) PORT_NAME("IN2-1") + PORT_BIT( 0x02, IP_ACTIVE_LOW, IPT_OTHER ) PORT_CODE(KEYCODE_S) PORT_NAME("IN2-2") + PORT_BIT( 0x04, IP_ACTIVE_LOW, IPT_OTHER ) PORT_CODE(KEYCODE_D) PORT_NAME("IN2-3") + PORT_BIT( 0x08, IP_ACTIVE_LOW, IPT_OTHER ) PORT_CODE(KEYCODE_F) PORT_NAME("IN2-4") + PORT_BIT( 0x10, IP_ACTIVE_LOW, IPT_OTHER ) PORT_CODE(KEYCODE_G) PORT_NAME("IN2-5") + PORT_BIT( 0x20, IP_ACTIVE_LOW, IPT_OTHER ) PORT_CODE(KEYCODE_H) PORT_NAME("IN2-6") + PORT_BIT( 0x40, IP_ACTIVE_LOW, IPT_OTHER ) PORT_CODE(KEYCODE_J) PORT_NAME("IN2-7") + PORT_BIT( 0x80, IP_ACTIVE_LOW, IPT_OTHER ) PORT_CODE(KEYCODE_K) PORT_NAME("IN2-8") + + PORT_START("IN3") + PORT_BIT( 0x01, IP_ACTIVE_LOW, IPT_OTHER ) PORT_CODE(KEYCODE_Z) PORT_NAME("IN3-1") + PORT_BIT( 0x02, IP_ACTIVE_LOW, IPT_OTHER ) PORT_CODE(KEYCODE_X) PORT_NAME("IN3-2") + PORT_BIT( 0x04, IP_ACTIVE_LOW, IPT_OTHER ) PORT_CODE(KEYCODE_C) PORT_NAME("IN3-3") + PORT_BIT( 0x08, IP_ACTIVE_LOW, IPT_SERVICE ) PORT_CODE(KEYCODE_V) PORT_NAME("Coin 1") PORT_IMPULSE(2) // coin 1 + PORT_BIT( 0x10, IP_ACTIVE_LOW, IPT_SERVICE ) PORT_CODE(KEYCODE_B) PORT_NAME("Coin 2") PORT_IMPULSE(2) // coin 2 + PORT_BIT( 0x20, IP_ACTIVE_LOW, IPT_SERVICE ) PORT_CODE(KEYCODE_N) PORT_NAME("Note") // note acceptor + PORT_BIT( 0x40, IP_ACTIVE_LOW, IPT_SERVICE ) PORT_CODE(KEYCODE_M) PORT_NAME("Remote") // remote credits + PORT_BIT( 0x80, IP_ACTIVE_LOW, IPT_SERVICE ) PORT_CODE(KEYCODE_L) PORT_NAME("Coin 3 (tokens)") // coin 3 (tokens) + + PORT_START("IN4") + PORT_BIT( 0x01, IP_ACTIVE_LOW, IPT_OTHER ) PORT_CODE(KEYCODE_1_PAD) PORT_NAME("IN4-1") + PORT_BIT( 0x02, IP_ACTIVE_LOW, IPT_SERVICE ) PORT_CODE(KEYCODE_2_PAD) PORT_NAME("Operator Bookkeeping") // operator bookkeeping + PORT_BIT( 0x04, IP_ACTIVE_LOW, IPT_OTHER ) PORT_CODE(KEYCODE_3_PAD) PORT_NAME("IN4-3") + PORT_BIT( 0x08, IP_ACTIVE_LOW, IPT_OTHER ) PORT_CODE(KEYCODE_4_PAD) PORT_NAME("IN4-4") + PORT_BIT( 0x10, IP_ACTIVE_LOW, IPT_SERVICE ) PORT_CODE(KEYCODE_5_PAD) PORT_NAME("Payout") // payout? + PORT_BIT( 0x20, IP_ACTIVE_LOW, IPT_OTHER ) PORT_CODE(KEYCODE_6_PAD) PORT_NAME("IN4-6") + PORT_BIT( 0x40, IP_ACTIVE_LOW, IPT_OTHER ) PORT_CODE(KEYCODE_7_PAD) PORT_NAME("IN4-7") + PORT_BIT( 0x80, IP_ACTIVE_LOW, IPT_SERVICE ) PORT_CODE(KEYCODE_8_PAD) PORT_NAME("Supervisor Bookkeeping") // supervisor bookkeeping + + PORT_START("DSW1") + PORT_DIPNAME( 0x01, 0x01, "DSW1") + 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_START("DSW2") + PORT_DIPNAME( 0x01, 0x01, "DSW2") + 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, 0x00, DEF_STR( Unknown ) ) // enter in a different mode, and no attract. + 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 ) ) // seems to accellerate the different mode. + 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_START("DSW3") + PORT_DIPNAME( 0x01, 0x01, "DSW3") + 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_START("DSW4") + PORT_DIPNAME( 0x01, 0x01, "DSW4") + 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 ) ) +INPUT_PORTS_END + + static INPUT_PORTS_START( magodds ) PORT_START("IN0") /* d800 */ PORT_BIT( 0x01, IP_ACTIVE_LOW, IPT_UNKNOWN ) @@ -11372,7 +11543,58 @@ ROM_END C: DM74LS374N D: DS1232 + Unknown Zilog 40pin IC (scratched): + (could be either a Z86C15 or Z86C91 MCU) + + +-----V-----+ + VCC -|01 40|- 74LS08N (Pin 01) + XTAL 8MHz <-|02 39|- GAL16V8 (Pin 17) + XTAL 8MHz >-|03 Z 38|- 74LS374 (Pin 03) + N/C -|04 I 37|- 74LS374 (Pin 04) + N/C -|05 L 36|- 74LS374 (Pin 07) + 74LS08N (Pin 10) -|06 O 35|- 74LS374 (Pin 08) + GAL16V8 (Pin 07) -|07 G 34|- 74LS374 (Pin 13) + GAL16V8 (Pin 08) -|08 33|- 74LS374 (Pin 14) + 74LS374 (Pin 11) -|09 32|- 74LS374 (Pin 17) + N/C -|10 31|- 74LS374 (Pin 18) + GND -|11 30|- 74LS374 (Pin 01) + N/C -|12 29|- 74LS08N (Pin 02) + 27C512 (A08) -|13 28|- 27C512 (Q7) + 27C512 (A09) -|14 27|- 27C512 (Q6) + 27C512 (A10) -|15 26|- 27C512 (Q5) + 27C512 (A11) -|16 25|- 27C512 (Q4) + 27C512 (A12) -|17 24|- 27C512 (Q3) + 27C512 (A13) -|18 23|- 27C512 (Q2) + 27C512 (A14) -|19 22|- 27C512 (Q1) + 27C512 (A15) -|20 21|- 27C512 (Q0) + +-----------+ + + 40-Pin DIP Pin Identification for Z86C15 MCU (for reference): + --------------------------------------------------------- + Pin Symbol Function Direction + --------------------------------------------------------- + 01 VCC Power Supply Input + 02 CLKOUT Z8 System Clock Output + 03 RCIN RC Oscillator Clock Input + 04 P37 Port 3, Pin 7 Output + 05 P30 Port 3, Pin 0 Input + 06 /RESET Reset Input + 07 AGND Analog Ground + 08 NC Not Connected + 09 /WDTOUT Watch-Dog Timer Output + 10 P35 Port 3, Pin 5 Output + 11 GND Ground + 12 P32 Port 3, Pin 2 Input + 13-20 P00-P07 Port 0, Pins 0,1,2,3,4,5,6,7 In/Output + 21-28 P10-P17 Port 1, Pins 0,1,2,3,4,5,6,7 In/Output + 29 P34 Port 3, Pin 4 Output + 30 P33 Port 3, Pin 3 Input + 31-38 P20-P27 Port 2, Pins 0,1,2,3,4,5,6,7 In/Output + 39 P31 Port 3, Pin 1 Input + 40 P36 Port 3, Pin 6 Output + --------------------------------------------------------- + BASE Board (based on WING W4): XTAL: 11.98135MHZ @@ -15826,7 +16048,7 @@ GAME( 1991, megaline, 0, megaline, megaline, driver_device, 0, GAMEL( 1993, bingowng, 0, bingowng, bingowng, driver_device, 0, ROT0, "Wing Co., Ltd.", "Bingo (set 1)", 0, layout_bingowng ) GAMEL( 1993, bingownga, bingowng, bingownga,bingownga,driver_device, 0, ROT0, "Wing Co., Ltd.", "Bingo (set 2)", 0, layout_bingowng ) -GAME( 2002, mbs2euro, 0, mbstar, lucky8, driver_device, 0, ROT0, "Auto-Data Graz", "Mega Bonus Star II (Euro, Millennium Edition)", MACHINE_NOT_WORKING ) // need more work in memory map, inputs, and reels alignment. +GAME( 2002, mbs2euro, 0, mbstar, mbstar, driver_device, 0, ROT0, "Auto-Data Graz", "Mega Bonus Star II (Euro, Millennium Edition)", MACHINE_NOT_WORKING ) // need more work in memory map, inputs, and reels alignment. // --- Flaming 7's hardware (W-4 derivative) --- diff --git a/src/mame/drivers/hh_cop400.cpp b/src/mame/drivers/hh_cop400.cpp index b65e6ac645c..ba183efa5c7 100644 --- a/src/mame/drivers/hh_cop400.cpp +++ b/src/mame/drivers/hh_cop400.cpp @@ -14,11 +14,12 @@ #include "cpu/cop400/cop400.h" #include "sound/dac.h" #include "sound/volt_reg.h" +//#include "rendlay.h" // internal artwork #include "bship82.lh" // clickable #include "ctstein.lh" // clickable -#include "einvaderc.lh" // test-layout(but still playable) +#include "einvaderc.lh" #include "funjacks.lh" // clickable #include "funrlgl.lh" #include "h2hbaskb.lh" @@ -43,7 +44,7 @@ public: // devices required_device<cpu_device> m_maincpu; - optional_ioport_array<5> m_inp_matrix; // max 5 + optional_ioport_array<6> m_inp_matrix; // max 6 // misc common u8 m_l; // MCU port L write data @@ -469,8 +470,6 @@ MACHINE_CONFIG_END The first version was on TMS1100 (see hh_tms1k.c), this is the reprogrammed second release with a gray case instead of black. - NOTE!: MAME external artwork is required - ***************************************************************************/ class einvaderc_state : public hh_cop400_state @@ -556,7 +555,7 @@ INPUT_PORTS_END static MACHINE_CONFIG_START( einvaderc, einvaderc_state ) /* basic machine hardware */ - MCFG_CPU_ADD("maincpu", COP444, 1000000) // approximation - RC osc. R=47K, C=100pf + MCFG_CPU_ADD("maincpu", COP444L, 900000) // approximation - RC osc. R=47K, C=100pf MCFG_COP400_CONFIG(COP400_CKI_DIVISOR_16, COP400_CKO_OSCILLATOR_OUTPUT, false) // guessed MCFG_COP400_READ_IN_CB(IOPORT("IN.0")) MCFG_COP400_WRITE_D_CB(WRITE8(einvaderc_state, write_d)) @@ -565,6 +564,11 @@ static MACHINE_CONFIG_START( einvaderc, einvaderc_state ) MCFG_COP400_WRITE_SO_CB(WRITELINE(einvaderc_state, write_so)) MCFG_COP400_WRITE_L_CB(WRITE8(einvaderc_state, write_l)) + /* video hardware */ + MCFG_SCREEN_SVG_ADD("screen", "svg") + MCFG_SCREEN_REFRESH_RATE(50) + MCFG_SCREEN_SIZE(913, 1080) + MCFG_SCREEN_VISIBLE_AREA(0, 913-1, 0, 1080-1) MCFG_TIMER_DRIVER_ADD_PERIODIC("display_decay", hh_cop400_state, display_decay_tick, attotime::from_msec(1)) MCFG_DEFAULT_LAYOUT(layout_einvaderc) @@ -794,8 +798,11 @@ MACHINE_CONFIG_END /*************************************************************************** - Mattel Dalla$ - * x + Mattel Dalla$ (J.R. handheld) + * COP444 MCU label COP444L-HYN/N + * 8-digit 7seg display, 1-bit sound + + This is a board game, only the handheld device is emulated here. ***************************************************************************/ @@ -809,48 +816,110 @@ public: required_device<dac_bit_interface> m_dac; - DECLARE_WRITE8_MEMBER(write_d); + void prepare_display(); DECLARE_WRITE8_MEMBER(write_l); + DECLARE_WRITE8_MEMBER(write_d); DECLARE_WRITE8_MEMBER(write_g); DECLARE_READ8_MEMBER(read_in); }; // handlers -WRITE8_MEMBER(mdallas_state::write_d) +void mdallas_state::prepare_display() { + set_display_segmask(0xff, 0xff); + display_matrix(8, 8, m_l, ~(m_d << 4 | m_g)); } WRITE8_MEMBER(mdallas_state::write_l) { + // L: digit segment data + m_l = data; + prepare_display(); +} + +WRITE8_MEMBER(mdallas_state::write_d) +{ + // D: select digit, input mux high + m_inp_mux = (m_inp_mux & 0xf) | (data << 4 & 3); + m_d = data & 0xf; + prepare_display(); } WRITE8_MEMBER(mdallas_state::write_g) { + // G: select digit, input mux low + m_inp_mux = (m_inp_mux & 0x30) | (data & 0xf); + m_g = data & 0xf; + prepare_display(); } READ8_MEMBER(mdallas_state::read_in) { // IN: multiplexed inputs - return 0; + return read_inputs(6) & 0xf; } // config +/* physical button layout and labels is like this: + + < ON> [YES] [NO] [NEXT] + [W] [N] [S] [E] + [7] [8] [9] [STATUS] + [4] [5] [6] [ASSETS] + [1] [2] [3] [START] + [CLEAR] [0] [MOVE] [ENTER] +*/ + static INPUT_PORTS_START( mdallas ) - PORT_START("IN.0") - PORT_BIT( 0x01, IP_ACTIVE_LOW, IPT_BUTTON1 ) + PORT_START("IN.0") // G0 port IN + PORT_BIT( 0x01, IP_ACTIVE_LOW, IPT_KEYPAD ) PORT_CODE(KEYCODE_C) PORT_CODE(KEYCODE_DEL) PORT_NAME("Clear") + PORT_BIT( 0x02, IP_ACTIVE_LOW, IPT_KEYPAD ) PORT_CODE(KEYCODE_0) PORT_CODE(KEYCODE_0_PAD) PORT_NAME("0") + PORT_BIT( 0x04, IP_ACTIVE_LOW, IPT_KEYPAD ) PORT_CODE(KEYCODE_M) PORT_NAME("Move") + PORT_BIT( 0x08, IP_ACTIVE_LOW, IPT_KEYPAD ) PORT_CODE(KEYCODE_ENTER) PORT_CODE(KEYCODE_ENTER_PAD) PORT_NAME("Enter") + + PORT_START("IN.1") // G1 port IN + PORT_BIT( 0x01, IP_ACTIVE_LOW, IPT_KEYPAD ) PORT_CODE(KEYCODE_1) PORT_CODE(KEYCODE_1_PAD) PORT_NAME("1") + PORT_BIT( 0x02, IP_ACTIVE_LOW, IPT_KEYPAD ) PORT_CODE(KEYCODE_2) PORT_CODE(KEYCODE_2_PAD) PORT_NAME("2") + PORT_BIT( 0x04, IP_ACTIVE_LOW, IPT_KEYPAD ) PORT_CODE(KEYCODE_3) PORT_CODE(KEYCODE_3_PAD) PORT_NAME("3") + PORT_BIT( 0x08, IP_ACTIVE_LOW, IPT_KEYPAD ) PORT_CODE(KEYCODE_S) PORT_NAME("Start") + + PORT_START("IN.2") // G2 port IN + PORT_BIT( 0x01, IP_ACTIVE_LOW, IPT_KEYPAD ) PORT_CODE(KEYCODE_4) PORT_CODE(KEYCODE_4_PAD) PORT_NAME("4") + PORT_BIT( 0x02, IP_ACTIVE_LOW, IPT_KEYPAD ) PORT_CODE(KEYCODE_5) PORT_CODE(KEYCODE_5_PAD) PORT_NAME("5") + PORT_BIT( 0x04, IP_ACTIVE_LOW, IPT_KEYPAD ) PORT_CODE(KEYCODE_6) PORT_CODE(KEYCODE_6_PAD) PORT_NAME("6") + PORT_BIT( 0x08, IP_ACTIVE_LOW, IPT_KEYPAD ) PORT_CODE(KEYCODE_A) PORT_NAME("Assets") + + PORT_START("IN.3") // G3 port IN + PORT_BIT( 0x01, IP_ACTIVE_LOW, IPT_KEYPAD ) PORT_CODE(KEYCODE_7) PORT_CODE(KEYCODE_7_PAD) PORT_NAME("7") + PORT_BIT( 0x02, IP_ACTIVE_LOW, IPT_KEYPAD ) PORT_CODE(KEYCODE_8) PORT_CODE(KEYCODE_8_PAD) PORT_NAME("8") + PORT_BIT( 0x04, IP_ACTIVE_LOW, IPT_KEYPAD ) PORT_CODE(KEYCODE_9) PORT_CODE(KEYCODE_9_PAD) PORT_NAME("9") + PORT_BIT( 0x08, IP_ACTIVE_LOW, IPT_KEYPAD ) PORT_CODE(KEYCODE_T) PORT_NAME("Status") + + PORT_START("IN.4") // D0 port IN + PORT_BIT( 0x01, IP_ACTIVE_LOW, IPT_KEYPAD ) PORT_CODE(KEYCODE_Q) PORT_NAME("West") // W + PORT_BIT( 0x02, IP_ACTIVE_LOW, IPT_UNUSED ) + PORT_BIT( 0x04, IP_ACTIVE_LOW, IPT_KEYPAD ) PORT_CODE(KEYCODE_X) PORT_NAME("Next") + PORT_BIT( 0x08, IP_ACTIVE_LOW, IPT_KEYPAD ) PORT_CODE(KEYCODE_R) PORT_NAME("East") // E + + PORT_START("IN.5") // D1 port IN + PORT_BIT( 0x01, IP_ACTIVE_LOW, IPT_KEYPAD ) PORT_CODE(KEYCODE_N) PORT_NAME("No") + PORT_BIT( 0x02, IP_ACTIVE_LOW, IPT_KEYPAD ) PORT_CODE(KEYCODE_Y) PORT_NAME("Yes") + PORT_BIT( 0x04, IP_ACTIVE_LOW, IPT_KEYPAD ) PORT_CODE(KEYCODE_E) PORT_NAME("South") // S + PORT_BIT( 0x08, IP_ACTIVE_LOW, IPT_KEYPAD ) PORT_CODE(KEYCODE_W) PORT_NAME("North") // N INPUT_PORTS_END static MACHINE_CONFIG_START( mdallas, mdallas_state ) /* basic machine hardware */ - MCFG_CPU_ADD("maincpu", COP444, 1000000) // approximation - RC osc. R=57K, C=101pf + MCFG_CPU_ADD("maincpu", COP444L, 1000000) // approximation - RC osc. R=57K, C=101pf MCFG_COP400_CONFIG(COP400_CKI_DIVISOR_16, COP400_CKO_OSCILLATOR_OUTPUT, false) // guessed - MCFG_COP400_WRITE_D_CB(WRITE8(mdallas_state, write_d)) MCFG_COP400_WRITE_L_CB(WRITE8(mdallas_state, write_l)) + MCFG_COP400_WRITE_D_CB(WRITE8(mdallas_state, write_d)) MCFG_COP400_WRITE_G_CB(WRITE8(mdallas_state, write_g)) + MCFG_COP400_READ_IN_CB(READ8(mdallas_state, read_in)) MCFG_COP400_WRITE_SO_CB(DEVWRITELINE("dac", dac_bit_interface, write)) MCFG_TIMER_DRIVER_ADD_PERIODIC("display_decay", hh_cop400_state, display_decay_tick, attotime::from_msec(1)) @@ -1371,6 +1440,9 @@ ROM_END ROM_START( einvaderc ) ROM_REGION( 0x0800, "maincpu", 0 ) ROM_LOAD( "copl444-hrz_n_inv_ii", 0x0000, 0x0800, CRC(76400f38) SHA1(0e92ab0517f7b7687293b189d30d57110df20fe0) ) + + ROM_REGION( 80636, "svg", 0) + ROM_LOAD( "einvaderc.svg", 0, 80636, CRC(a52d0166) SHA1(f69397ebcc518701f30a47b4d62e5a700825375a) ) // by hap, ver. 18 jan 2017 ROM_END @@ -1388,7 +1460,7 @@ ROM_END ROM_START( mdallas ) ROM_REGION( 0x0800, "maincpu", 0 ) - ROM_LOAD( "copl444l-htn_n", 0x0000, 0x0800, CRC(7848b78c) SHA1(778d24512180892f58c49df3c72ca77b2618d63b) ) + ROM_LOAD( "copl444l-hyn_n", 0x0000, 0x0800, CRC(7848b78c) SHA1(778d24512180892f58c49df3c72ca77b2618d63b) ) ROM_END @@ -1422,11 +1494,11 @@ CONS( 1979, ctstein, 0, 0, ctstein, ctstein, driver_device, 0, "Cas CONS( 1980, h2hbaskb, 0, 0, h2hbaskb, h2hbaskb, driver_device, 0, "Coleco", "Head to Head Basketball/Hockey/Soccer (COP420L version)", MACHINE_SUPPORTS_SAVE ) -CONS( 1981, einvaderc, einvader, 0, einvaderc, einvaderc, driver_device, 0, "Entex", "Space Invader (Entex, COP444L version)", MACHINE_SUPPORTS_SAVE | MACHINE_REQUIRES_ARTWORK ) +CONS( 1981, einvaderc, einvader, 0, einvaderc, einvaderc, driver_device, 0, "Entex", "Space Invader (Entex, COP444L version)", MACHINE_SUPPORTS_SAVE ) CONS( 1979, funjacks, 0, 0, funjacks, funjacks, driver_device, 0, "Mattel", "Funtronics Jacks", MACHINE_SUPPORTS_SAVE | MACHINE_CLICKABLE_ARTWORK ) CONS( 1979, funrlgl, 0, 0, funrlgl, funrlgl, driver_device, 0, "Mattel", "Funtronics Red Light Green Light", MACHINE_SUPPORTS_SAVE ) -CONS( 1981, mdallas, 0, 0, mdallas, mdallas, driver_device, 0, "Mattel", "Dalla$ (J.R. handheld)", MACHINE_SUPPORTS_SAVE | MACHINE_NOT_WORKING ) // *** +CONS( 1981, mdallas, 0, 0, mdallas, mdallas, driver_device, 0, "Mattel", "Dalla$ (J.R. handheld)", MACHINE_SUPPORTS_SAVE ) // *** CONS( 1980, plus1, 0, 0, plus1, plus1, driver_device, 0, "Milton Bradley", "Plus One", MACHINE_SUPPORTS_SAVE | MACHINE_NOT_WORKING ) // *** CONS( 1981, lightfgt, 0, 0, lightfgt, lightfgt, driver_device, 0, "Milton Bradley", "Lightfight", MACHINE_SUPPORTS_SAVE | MACHINE_CLICKABLE_ARTWORK ) diff --git a/src/mame/drivers/hh_tms1k.cpp b/src/mame/drivers/hh_tms1k.cpp index 5c908fdbb50..2bb9278f981 100644 --- a/src/mame/drivers/hh_tms1k.cpp +++ b/src/mame/drivers/hh_tms1k.cpp @@ -122,6 +122,8 @@ brighter: tc4/h2hfootb(offense), bankshot(cue ball), ... - stopthiep: unable to start a game (may be intentional?) - tbreakup: some of the leds flicker (rom and PLAs doublechecked) + - 7in1ss: in 2-player mode, game select and skill select can be configured + after selecting a game? - bship discrete sound, netlist is documented - finish bshipb SN76477 sound - improve elecbowl driver @@ -158,7 +160,7 @@ #include "ebball3.lh" #include "ebaskb2.lh" #include "efootb4.lh" -#include "einvader.lh" // test-layout(but still playable) +#include "einvader.lh" #include "elecbowl.lh" #include "elecdet.lh" #include "esbattle.lh" @@ -2901,8 +2903,6 @@ MACHINE_CONFIG_END TMS1100, the second more widespread release runs on a COP400. There are also differences with the overlay mask. - NOTE!: MAME external artwork is required - ***************************************************************************/ class einvader_state : public hh_tms1k_state @@ -2990,6 +2990,11 @@ static MACHINE_CONFIG_START( einvader, einvader_state ) MCFG_TMS1XXX_WRITE_R_CB(WRITE16(einvader_state, write_r)) MCFG_TMS1XXX_WRITE_O_CB(WRITE16(einvader_state, write_o)) + /* video hardware */ + MCFG_SCREEN_SVG_ADD("screen", "svg") + MCFG_SCREEN_REFRESH_RATE(50) + MCFG_SCREEN_SIZE(939, 1080) + MCFG_SCREEN_VISIBLE_AREA(0, 939-1, 0, 1080-1) MCFG_TIMER_DRIVER_ADD_PERIODIC("display_decay", hh_tms1k_state, display_decay_tick, attotime::from_msec(1)) MCFG_DEFAULT_LAYOUT(layout_einvader) @@ -3721,7 +3726,7 @@ INPUT_PORTS_END static MACHINE_CONFIG_START( ginv1000, ginv1000_state ) /* basic machine hardware */ - MCFG_CPU_ADD("maincpu", TMS1370, 325000) // approximation + MCFG_CPU_ADD("maincpu", TMS1370, 340000) // approximation MCFG_TMS1XXX_READ_K_CB(READ8(ginv1000_state, read_k)) MCFG_TMS1XXX_WRITE_R_CB(WRITE16(ginv1000_state, write_r)) MCFG_TMS1XXX_WRITE_O_CB(WRITE16(ginv1000_state, write_o)) @@ -8038,6 +8043,9 @@ ROM_START( einvader ) ROM_LOAD( "tms1100_common2_micro.pla", 0, 867, CRC(7cc90264) SHA1(c6e1cf1ffb178061da9e31858514f7cd94e86990) ) ROM_REGION( 365, "maincpu:opla", 0 ) ROM_LOAD( "tms1100_einvader_output.pla", 0, 365, CRC(490158e1) SHA1(61cace1eb09244663de98d8fb04d9459b19668fd) ) + + ROM_REGION( 44398, "svg", 0) + ROM_LOAD( "einvader.svg", 0, 44398, CRC(48de88fd) SHA1(56a2b9c997a447277b45902ab542eda54e7d5a2f) ) // by hap, ver. 23 mar 2016 ROM_END @@ -8528,7 +8536,7 @@ CONS( 1979, ebball, 0, 0, ebball, ebball, driver_device, 0, "Ent CONS( 1979, ebball2, 0, 0, ebball2, ebball2, driver_device, 0, "Entex", "Electronic Baseball 2 (Entex)", MACHINE_SUPPORTS_SAVE ) CONS( 1980, ebball3, 0, 0, ebball3, ebball3, driver_device, 0, "Entex", "Electronic Baseball 3 (Entex)", MACHINE_SUPPORTS_SAVE ) CONS( 1979, esbattle, 0, 0, esbattle, esbattle, driver_device, 0, "Entex", "Space Battle (Entex)", MACHINE_SUPPORTS_SAVE ) -CONS( 1980, einvader, 0, 0, einvader, einvader, driver_device, 0, "Entex", "Space Invader (Entex, TMS1100 version)", MACHINE_SUPPORTS_SAVE | MACHINE_REQUIRES_ARTWORK ) +CONS( 1980, einvader, 0, 0, einvader, einvader, driver_device, 0, "Entex", "Space Invader (Entex, TMS1100 version)", MACHINE_SUPPORTS_SAVE ) CONS( 1980, efootb4 , 0, 0, efootb4, efootb4, driver_device, 0, "Entex", "Color Football 4 (Entex)", MACHINE_SUPPORTS_SAVE ) CONS( 1980, ebaskb2 , 0, 0, ebaskb2, ebaskb2, driver_device, 0, "Entex", "Electronic Basketball 2 (Entex)", MACHINE_SUPPORTS_SAVE ) CONS( 1980, raisedvl, 0, 0, raisedvl, raisedvl, driver_device, 0, "Entex", "Raise The Devil", MACHINE_SUPPORTS_SAVE ) diff --git a/src/mame/drivers/ibmpcjr.cpp b/src/mame/drivers/ibmpcjr.cpp index 1a79d4eec40..b050a5ed0e0 100644 --- a/src/mame/drivers/ibmpcjr.cpp +++ b/src/mame/drivers/ibmpcjr.cpp @@ -657,6 +657,7 @@ static MACHINE_CONFIG_START( ibmpcjr, pcjr_state) /* Software lists */ MCFG_SOFTWARE_LIST_ADD("cart_list","ibmpcjr_cart") MCFG_SOFTWARE_LIST_ADD("flop_list","ibmpcjr_flop") + MCFG_SOFTWARE_LIST_COMPATIBLE_ADD("pc_list","ibm5150") MACHINE_CONFIG_END static GFXDECODE_START( ibmpcjx ) @@ -680,7 +681,7 @@ static MACHINE_CONFIG_DERIVED( ibmpcjx, ibmpcjr ) MCFG_DEVICE_MODIFY(RAM_TAG) MCFG_RAM_DEFAULT_SIZE("512K") MCFG_RAM_EXTRA_OPTIONS("") // only boots with 512k currently - MACHINE_CONFIG_END +MACHINE_CONFIG_END diff --git a/src/mame/drivers/kurukuru.cpp b/src/mame/drivers/kurukuru.cpp index 33c82310780..a0b1a5727e4 100644 --- a/src/mame/drivers/kurukuru.cpp +++ b/src/mame/drivers/kurukuru.cpp @@ -113,6 +113,130 @@ AB = NEC C1663C 8926B. + Pinout: + + solder side |##| components + -------------------|--|----------------- + gnd |01| gnd + gnd |02| gnd + +5v |03| +5v + +5v |04| +5v + -5v |05| -5v + +12v |06| +12v + | | + hole (no connector) |07| hole (no connector) + | | + Coin B (10Y) meter |08| Coin A (100Y) meter + hopper motor |09| unknown out (ULN2003, pin15) + speaker - |10| speaker + + (ULN2003, pin13) unknown out |11| unknown out (ULN2003, pin12) + green |12| red + sync |13| blue + (ULN2003, pin13) unknown out |14| video gnd + | | + medal in |15| management + coin B (10Y) in |16| reset + coin A (100Y) in |17| unknown in (active) + +5v |<|-- (diode) |18| (diode) --|>| +5v + +5v |<|-- (diode) |19| (diode) --|>| +5v + | | + Botechin (5th) |20| (1st) Boketa + (active) unknown in |21| (2nd) Kunio + (active) unknown in |22| (3rd) Pyon-Pyon + start |23| (4th) Pyokorin + payout |24| hopper in (opto in) + | | + not used |25| not used + not used |26| not used + gnd |27| gnd + gnd |28| gnd + + + Pyon Pyon Jump DIP switches: + + .---------------------------------------------------------------------------------. + | DIP Switches bank #1 1 2 3 4 5 6 7 8 | + +-------------------------------------+-------------------------------------------+ + +-----------------+-------------------+-------------------------------------------+ + | Coinage Coin A | 1 coin / 11 medal | off off off | + +-----------------+-------------------+-------------------------------------------+ + | Coinage Coin A | 1 coin / 10 medal | off off on | + +-----------------+-------------------+-------------------------------------------+ + | Coinage Coin A | 1 coin / 6 medal | off on off | + +-----------------+-------------------+-------------------------------------------+ + | Coinage Coin A | 1 coin / 5 medal | off on on | + +-----------------+-------------------+-------------------------------------------+ + | Coinage Coin A | 1 coin / 4 medal | on off off | + +-----------------+-------------------+-------------------------------------------+ + | Coinage Coin A | 1 coin / 3 medal | on off on | + +-----------------+-------------------+-------------------------------------------+ + | Coinage Coin A | 1 coin / 2 medal | on on off | + +-----------------+-------------------+-------------------------------------------+ + | Coinage Coin A | 1 coin / 1 medal | on on on | + +-----------------+-------------------+-------------------------------------------+ + | Coin A (100Y) | Exchange | off | + +-----------------+-------------------+-------------------------------------------+ + | Coin A (100Y) | Credit | on | + +-----------------+-------------------+-------------------------------------------+ + | Win | Medal out | off | + +-----------------+-------------------+-------------------------------------------+ + | Win | Credit | on | + +-----------------+-------------------+-------------------------------------------+ + | Coinage config | Coin A: Payout | off | + +-----------------+-------------------+-------------------------------------------+ + | Coinage config | Coin A: Normal | on | + +-----------------+-------------------+-------------------------------------------+ + | Payout Mode | Manual | off | + +-----------------+-------------------+-------------------------------------------+ + | Payout Mode | Automatic | on | + +-----------------+-------------------+-------------------------------------------+ + | Repeat last bet | No | off | + +-----------------+-------------------+-------------------------------------------+ + | Repeat last bet | Yes | on | + '-----------------+-------------------+-------------------------------------------' + + .---------------------------------------------------------------------------------. + | DIP Switches bank #2 1 2 3 4 5 6 7 8 | + +-------------------------------------+-------------------------------------------+ + +-----------------+-------------------+-------------------------------------------+ + | Percentage | 95% | on on on | + +-----------------+-------------------+-------------------------------------------+ + | Percentage | 90% | on on off | + +-----------------+-------------------+-------------------------------------------+ + | Percentage | 85% | on off on | + +-----------------+-------------------+-------------------------------------------+ + | Percentage | 80% | on off off | + +-----------------+-------------------+-------------------------------------------+ + | Percentage | 75% | off on on | + +-----------------+-------------------+-------------------------------------------+ + | Percentage | 70% | off on off | + +-----------------+-------------------+-------------------------------------------+ + | Percentage | 60% | off off on | + +-----------------+-------------------+-------------------------------------------+ + | Percentage | 50% | off off off | + +-----------------+-------------------+-------------------------------------------+ + | Winwave | Small | off | + +-----------------+-------------------+-------------------------------------------+ + | Winwave | Big | on | + +-----------------+-------------------+-------------------------------------------+ + | M.Medal | Off | off | + +-----------------+-------------------+-------------------------------------------+ + | M.Medal | On | on | + +-----------------+-------------------+-------------------------------------------+ + | HG | 20-1 | off off | + +-----------------+-------------------+-------------------------------------------+ + | HG | 50-1 | off on | + +-----------------+-------------------+-------------------------------------------+ + | HG | 100-1 | on off | + +-----------------+-------------------+-------------------------------------------+ + | HG | 200-1 | on on | + +-----------------+-------------------+-------------------------------------------+ + | unknown | off | + +-------------------------------------+-------------------------------------------+ + | unknown | on | + '-------------------------------------+-------------------------------------------' + + ************************************************************************************ General Notes.... diff --git a/src/mame/drivers/m6805evs.cpp b/src/mame/drivers/m6805evs.cpp index bec8b22e84b..f42260193ce 100644 --- a/src/mame/drivers/m6805evs.cpp +++ b/src/mame/drivers/m6805evs.cpp @@ -6,28 +6,63 @@ Motorola M68HC05EVS evaluation system Chips: Main board: XC68HC26P, R65C52P2, MS62256l-70PC, MS6264L-70PC, eprom. Xtal = 3.6864MHz -Emulator board: MC68C705P9CP, undumped 28-pin prom. Xtal = 4MHz +Emulator board: MC68HC705P9CP, undumped 28-pin prom. Xtal = 4MHz R65C52 = Dual ACIA with inbuilt baud rate divider, uses 8 addresses, uses the 3.6864MHz crystal XC68HC26P = PPI (3 ports), uses 8 addresses. 2014-01-12 Skeleton driver -The rom is larger than the available address space, but not all of it is programmed. The code -ranges are 800-18FF,1FF0-1FFF. There must be a banking scheme in use. +Memory map: +0000, 0000 PORTA Port A data register +0001, 0001 PORTB Port B data register +0002, 0002 PORTC Port C data register +0003, 0003 PORTD Port D data register +0004, 0004 DDRA Data direction register A +0005, 0005 DDRB Data direction register B +0006, 0006 DDRC Data direction register C +0007, 0007 DDRD Data direction register D +0008, 0009 unimplemented +000A, 000A SCR SIOP control register +000B, 000B SSR SIOP status register +0009, 0009 SDR SIOP data register +000D, 0011 unimplemented +0012, 0012 TCR Timer control register +0013, 0013 TDR Timer data register +0014, 0014 ICRH Input capture register high +0015, 0015 ICRL Input capture register low +0016, 0016 OCRH Output compare register high +0017, 0017 OCRL Output compare register low +0018, 0018 TRH Timer register high +0019, 0019 TRL Timer register low +001A, 001A ATRH Alternate timer register high +001B, 001B ATRL Alternate timer register low +001C, 001C EPROG EPROM programming register +001D, 001D ADDR ADC data register +001E, 001E ADSCR ADC status/control register +001F, 001F reserved +0020, 004F Page zero user EPROM +0050, 007F unimplemented +0080, 00FF RAM +0100, 08FF User EPROM +0900, 0900 MOR Mask option register +0901, 1EFF unimplemented +1F00, 1FEF Bootloader ROM +1FF1, 1FF7 reserved +1FF8, 1FF9 Timer interrupt vector +1FFA, 1FFB External interrupt vector +1FFC, 1FFD Software interrupt vector +1FFE, 1FFF Reset vector -Memory map guess -000-07F Stack (and user ram?) -080-0FF RAM (or devices?) -100-FFF ROM ToDo: +- Add CMOS family support to M6085 CPU core (different timings, different peripherals) - Everything ******************************************************************************************************/ #include "emu.h" -#include "cpu/m6805/m68705.h" +#include "cpu/m6805/m6805.h" class m6805evs_state : public driver_device @@ -45,10 +80,15 @@ private: static ADDRESS_MAP_START( m6805evs_mem, AS_PROGRAM, 8, m6805evs_state ) - AM_RANGE(0x0000, 0x00ff) AM_RAM - AM_RANGE(0x0100, 0x07ff) AM_ROM AM_REGION("roms", 0x1100) - AM_RANGE(0x0800, 0x0fef) AM_ROM AM_REGION("roms", 0x0800) - AM_RANGE(0x0ff0, 0x0fff) AM_ROM AM_REGION("roms", 0x1ff0) + ADDRESS_MAP_GLOBAL_MASK(0x1fff) + ADDRESS_MAP_UNMAP_HIGH + + // AM_RANGE(0x0000, 0x001f) I/O registers live here + AM_RANGE(0x0020, 0x004f) AM_ROM AM_REGION("eprom", 0x0020) + AM_RANGE(0x0080, 0x00ff) AM_RAM + AM_RANGE(0x0100, 0x0900) AM_ROM AM_REGION("eprom", 0x0100) + // AM_RANGE(0x1f00, 0x1fef) bootloader ROM lives here + AM_RANGE(0x1ff8, 0x1fff) AM_ROM AM_REGION("eprom", 0x1ff0) ADDRESS_MAP_END static INPUT_PORTS_START( m6805evs ) @@ -60,12 +100,12 @@ void m6805evs_state::machine_reset() static MACHINE_CONFIG_START( m6805evs, m6805evs_state ) /* basic machine hardware */ - MCFG_CPU_ADD("maincpu", M68705, XTAL_4MHz) + MCFG_CPU_ADD("maincpu", M6805, XTAL_4MHz) MCFG_CPU_PROGRAM_MAP(m6805evs_mem) MACHINE_CONFIG_END ROM_START(m6805evs) - ROM_REGION(0x2000, "roms", 0) + ROM_REGION(0x2000, "eprom", 0) ROM_LOAD( "evsbug12.bin", 0x0000, 0x2000, CRC(8b581aef) SHA1(eacf425cc8a042085ccc4097cc61570b633b1e38) ) ROM_END diff --git a/src/mame/drivers/maxaflex.cpp b/src/mame/drivers/maxaflex.cpp index a5760a9e949..aa86318b42c 100644 --- a/src/mame/drivers/maxaflex.cpp +++ b/src/mame/drivers/maxaflex.cpp @@ -13,12 +13,16 @@ ******************************************************************************/ #include "emu.h" +#include "includes/atari400.h" + #include "cpu/m6502/m6502.h" #include "cpu/m6805/m68705.h" -#include "includes/atari400.h" + +#include "machine/6821pia.h" + #include "sound/speaker.h" #include "sound/pokey.h" -#include "machine/6821pia.h" + #include "video/gtia.h" #include "maxaflex.lh" @@ -28,54 +32,37 @@ class maxaflex_state : public atari_common_state { public: maxaflex_state(const machine_config &mconfig, device_type type, const char *tag) - : atari_common_state(mconfig, type, tag), - m_mcu(*this, "mcu"), - m_speaker(*this, "speaker"), - m_region_maincpu(*this, "maincpu"), - m_dsw(*this, "dsw"), - m_coin(*this, "coin"), - m_console(*this, "console"), - m_joy01(*this, "djoy_0_1"), - m_joy23(*this, "djoy_2_3") - { } - - uint8_t m_portA_in; - uint8_t m_portA_out; - uint8_t m_ddrA; - uint8_t m_portB_in; + : atari_common_state(mconfig, type, tag) + , m_mcu(*this, "mcu") + , m_speaker(*this, "speaker") + , m_region_maincpu(*this, "maincpu") + , m_dsw(*this, "dsw") + , m_coin(*this, "coin") + , m_console(*this, "console") + , m_joy01(*this, "djoy_0_1") + , m_joy23(*this, "djoy_2_3") + { + } + uint8_t m_portB_out; - uint8_t m_ddrB; - uint8_t m_portC_in; uint8_t m_portC_out; - uint8_t m_ddrC; - uint8_t m_tdr; - uint8_t m_tcr; - timer_device *m_mcu_timer; - void mmu(uint8_t new_mmu); DECLARE_READ8_MEMBER(mcu_portA_r); DECLARE_WRITE8_MEMBER(mcu_portA_w); - DECLARE_READ8_MEMBER(mcu_portB_r); DECLARE_WRITE8_MEMBER(mcu_portB_w); - DECLARE_READ8_MEMBER(mcu_portC_r); DECLARE_WRITE8_MEMBER(mcu_portC_w); - DECLARE_READ8_MEMBER(mcu_ddr_r); - DECLARE_WRITE8_MEMBER(mcu_portA_ddr_w); - DECLARE_WRITE8_MEMBER(mcu_portB_ddr_w); - DECLARE_WRITE8_MEMBER(mcu_portC_ddr_w); - DECLARE_READ8_MEMBER(mcu_tdr_r); - DECLARE_WRITE8_MEMBER(mcu_tdr_w); - DECLARE_READ8_MEMBER(mcu_tcr_r); - DECLARE_WRITE8_MEMBER(mcu_tcr_w); DECLARE_INPUT_CHANGED_MEMBER(coin_inserted); DECLARE_READ8_MEMBER(pia_pa_r); DECLARE_READ8_MEMBER(pia_pb_r); WRITE8_MEMBER(pia_pb_w) { mmu(data); } WRITE_LINE_MEMBER(pia_cb2_w) { } // This is used by Floppy drive on Atari 8bits Home Computers TIMER_DEVICE_CALLBACK_MEMBER(mf_interrupt); - TIMER_DEVICE_CALLBACK_MEMBER(mcu_timer_proc); - int atari_input_disabled(); + +protected: virtual void machine_reset() override; - //required_device<cpu_device> m_maincpu; // maincpu is already contained in atari_common_state + + bool atari_input_disabled() const { return !BIT(m_portB_out, 7); } + void mmu(uint8_t new_mmu); + required_device<cpu_device> m_mcu; required_device<speaker_sound_device> m_speaker; required_region_ptr<uint8_t> m_region_maincpu; @@ -120,14 +107,16 @@ void maxaflex_state::mmu(uint8_t new_mmu) READ8_MEMBER(maxaflex_state::mcu_portA_r) { - m_portA_in = m_dsw->read() | (m_coin->read() << 4) | (m_console->read() << 5); - return (m_portA_in & ~m_ddrA) | (m_portA_out & m_ddrA); + return + ((m_dsw->read() << 0) & 0x0f) | + ((m_coin->read() << 4) & 0x10) | + ((m_console->read() << 5) & 0x20) | + 0xc0; } WRITE8_MEMBER(maxaflex_state::mcu_portA_w) { - m_portA_out = data; - m_speaker->level_w(data >> 7); + m_speaker->level_w(BIT(data, 7)); } /* Port B: @@ -141,34 +130,29 @@ WRITE8_MEMBER(maxaflex_state::mcu_portA_w) 7 (out) TOFF - enables/disables user controls */ -READ8_MEMBER(maxaflex_state::mcu_portB_r) -{ - return (m_portB_in & ~m_ddrB) | (m_portB_out & m_ddrB); -} - WRITE8_MEMBER(maxaflex_state::mcu_portB_w) { - uint8_t diff = data ^ m_portB_out; + const uint8_t diff = data ^ m_portB_out; m_portB_out = data; /* clear coin interrupt */ - if (data & 0x04) - m_mcu->set_input_line(M6805_IRQ_LINE, CLEAR_LINE ); - - /* AUDMUTE */ - machine().sound().system_enable((data >> 5) & 1); + if (BIT(data, 2)) + m_mcu->set_input_line(M6805_IRQ_LINE, CLEAR_LINE); /* RES600 */ - if (diff & 0x10) - m_maincpu->set_input_line(INPUT_LINE_RESET, (data & 0x10) ? CLEAR_LINE : ASSERT_LINE); + if (BIT(diff, 4)) + m_maincpu->set_input_line(INPUT_LINE_RESET, BIT(data, 4) ? CLEAR_LINE : ASSERT_LINE); + + /* AUDMUTE */ + machine().sound().system_enable(BIT(data, 5)); /* latch for lamps */ - if ((diff & 0x40) && !(data & 0x40)) + if (BIT(diff, 6) && !BIT(data, 6)) { - output().set_lamp_value(0, (m_portC_out >> 0) & 1); - output().set_lamp_value(1, (m_portC_out >> 1) & 1); - output().set_lamp_value(2, (m_portC_out >> 2) & 1); - output().set_lamp_value(3, (m_portC_out >> 3) & 1); + output().set_lamp_value(0, BIT(m_portC_out, 0)); + output().set_lamp_value(1, BIT(m_portC_out, 1)); + output().set_lamp_value(2, BIT(m_portC_out, 2)); + output().set_lamp_value(3, BIT(m_portC_out, 3)); } } @@ -178,117 +162,28 @@ WRITE8_MEMBER(maxaflex_state::mcu_portB_w) 2 (out) lamp START 3 (out) lamp OVER */ -READ8_MEMBER(maxaflex_state::mcu_portC_r) -{ - return (m_portC_in & ~m_ddrC) | (m_portC_out & m_ddrC); -} - WRITE8_MEMBER(maxaflex_state::mcu_portC_w) { /* uses a 7447A, which is equivalent to an LS47/48 */ - static const uint8_t ls48_map[16] = - { 0x3f,0x06,0x5b,0x4f,0x66,0x6d,0x7c,0x07,0x7f,0x67,0x58,0x4c,0x62,0x69,0x78,0x00 }; + constexpr static uint8_t ls48_map[16] = + { 0x3f, 0x06, 0x5b, 0x4f, 0x66, 0x6d, 0x7c, 0x07, 0x7f, 0x67, 0x58, 0x4c, 0x62, 0x69, 0x78, 0x00 }; m_portC_out = data & 0x0f; /* displays */ - switch( m_portB_out & 0x3 ) + switch (m_portB_out & 0x03) { - case 0x0: output().set_digit_value(0, ls48_map[m_portC_out]); break; - case 0x1: output().set_digit_value(1, ls48_map[m_portC_out]); break; - case 0x2: output().set_digit_value(2, ls48_map[m_portC_out]); break; - case 0x3: break; - } -} - -READ8_MEMBER(maxaflex_state::mcu_ddr_r) -{ - return 0xff; -} - -WRITE8_MEMBER(maxaflex_state::mcu_portA_ddr_w) -{ - m_ddrA = data; -} - -WRITE8_MEMBER(maxaflex_state::mcu_portB_ddr_w) -{ - m_ddrB = data; -} - -WRITE8_MEMBER(maxaflex_state::mcu_portC_ddr_w) -{ - m_ddrC = data; -} - -TIMER_DEVICE_CALLBACK_MEMBER(maxaflex_state::mcu_timer_proc) -{ - if ( --m_tdr == 0x00 ) - { - if ( (m_tcr & 0x40) == 0 ) - { - //timer interrupt! - generic_pulse_irq_line(*m_mcu, M68705_INT_TIMER, 1); - } - } -} - -/* Timer Data Reg */ -READ8_MEMBER(maxaflex_state::mcu_tdr_r) -{ - return m_tdr; -} - -WRITE8_MEMBER(maxaflex_state::mcu_tdr_w) -{ - m_tdr = data; -} - -/* Timer control reg */ -READ8_MEMBER(maxaflex_state::mcu_tcr_r) -{ - return m_tcr & ~0x08; -} - -WRITE8_MEMBER(maxaflex_state::mcu_tcr_w) -{ - m_tcr = data; - if ( (m_tcr & 0x40) == 0 ) - { - int divider; - attotime period; - - if ( !(m_tcr & 0x20) ) - { - /* internal clock / 4*/ - divider = 4; - } - else - { - /* external clock */ - divider = 1; - } - - if ( m_tcr & 0x07 ) - { - /* use prescaler */ - divider = divider * (1 << (m_tcr & 0x7)); - } - - period = attotime::from_hz(3579545) * divider; - m_mcu_timer->adjust(period, 0, period); + case 0x0: output().set_digit_value(0, ls48_map[m_portC_out]); break; + case 0x1: output().set_digit_value(1, ls48_map[m_portC_out]); break; + case 0x2: output().set_digit_value(2, ls48_map[m_portC_out]); break; + case 0x3: break; } } INPUT_CHANGED_MEMBER(maxaflex_state::coin_inserted) { if (!newval) - m_mcu->set_input_line(M6805_IRQ_LINE, HOLD_LINE ); -} - -int maxaflex_state::atari_input_disabled() -{ - return (m_portB_out & 0x80) == 0x00; + m_mcu->set_input_line(M6805_IRQ_LINE, ASSERT_LINE); } @@ -307,20 +202,6 @@ static ADDRESS_MAP_START(a600xl_mem, AS_PROGRAM, 8, maxaflex_state ) AM_RANGE(0xd800, 0xffff) AM_ROM /* OS */ ADDRESS_MAP_END -static ADDRESS_MAP_START( mcu_mem, AS_PROGRAM, 8, maxaflex_state ) - ADDRESS_MAP_GLOBAL_MASK(0x7ff) - AM_RANGE(0x0000, 0x0000) AM_READ(mcu_portA_r) AM_WRITE(mcu_portA_w) - AM_RANGE(0x0001, 0x0001) AM_READ(mcu_portB_r) AM_WRITE(mcu_portB_w) - AM_RANGE(0x0002, 0x0002) AM_READ(mcu_portC_r) AM_WRITE(mcu_portC_w) - AM_RANGE(0x0004, 0x0004) AM_READ(mcu_ddr_r) AM_WRITE(mcu_portA_ddr_w) - AM_RANGE(0x0005, 0x0005) AM_READ(mcu_ddr_r) AM_WRITE(mcu_portB_ddr_w) - AM_RANGE(0x0006, 0x0006) AM_READ(mcu_ddr_r) AM_WRITE(mcu_portC_ddr_w) - AM_RANGE(0x0008, 0x0008) AM_READ(mcu_tdr_r) AM_WRITE(mcu_tdr_w) - AM_RANGE(0x0009, 0x0009) AM_READ(mcu_tcr_r) AM_WRITE(mcu_tcr_w) - AM_RANGE(0x0010, 0x007f) AM_RAM - AM_RANGE(0x0080, 0x07ff) AM_ROM -ADDRESS_MAP_END - static INPUT_PORTS_START( a600xl ) @@ -363,7 +244,7 @@ static INPUT_PORTS_START( a600xl ) /* Max-A-Flex specific ports */ PORT_START("coin") - PORT_BIT(0x1, IP_ACTIVE_LOW, IPT_COIN1 ) PORT_CHANGED_MEMBER(DEVICE_SELF, maxaflex_state,coin_inserted, 0) + PORT_BIT(0x1, IP_ACTIVE_LOW, IPT_COIN1) PORT_CHANGED_MEMBER(DEVICE_SELF, maxaflex_state, coin_inserted, 0) PORT_START("dsw") PORT_DIPNAME(0xf, 0x9, "Coin/Time" ) @@ -404,11 +285,8 @@ void maxaflex_state::machine_reset() pokey->write(15,0); // Supervisor board reset - m_portA_in = m_portA_out = m_ddrA = 0; - m_portB_in = m_portB_out = m_ddrB = 0; - m_portC_in = m_portC_out = m_ddrC = 0; - m_tdr = m_tcr = 0; - m_mcu_timer = machine().device<timer_device>("mcu_timer"); + m_portB_out = 0xff; + m_portC_out = 0xff; output().set_lamp_value(0, 0); output().set_lamp_value(1, 0); @@ -430,8 +308,11 @@ static MACHINE_CONFIG_START( maxaflex, maxaflex_state ) MCFG_CPU_PROGRAM_MAP(a600xl_mem) MCFG_TIMER_DRIVER_ADD_SCANLINE("scantimer", maxaflex_state, mf_interrupt, "screen", 0, 1) - MCFG_CPU_ADD("mcu", M68705, 3579545) - MCFG_CPU_PROGRAM_MAP(mcu_mem) + MCFG_CPU_ADD("mcu", M68705P3, 3579545) + MCFG_M68705_PORTA_R_CB(READ8(maxaflex_state, mcu_portA_r)) + MCFG_M68705_PORTA_W_CB(WRITE8(maxaflex_state, mcu_portA_w)) + MCFG_M68705_PORTB_W_CB(WRITE8(maxaflex_state, mcu_portB_w)) + MCFG_M68705_PORTC_W_CB(WRITE8(maxaflex_state, mcu_portC_w)) MCFG_DEVICE_ADD("gtia", ATARI_GTIA, 0) MCFG_GTIA_READ_CB(IOPORT("console")) @@ -445,8 +326,6 @@ static MACHINE_CONFIG_START( maxaflex, maxaflex_state ) MCFG_PIA_WRITEPB_HANDLER(WRITE8(maxaflex_state, pia_pb_w)) MCFG_PIA_CB2_HANDLER(WRITELINE(maxaflex_state, pia_cb2_w)) - MCFG_TIMER_DRIVER_ADD("mcu_timer", maxaflex_state, mcu_timer_proc) - /* video hardware */ MCFG_SCREEN_ADD("screen", RASTER) MCFG_SCREEN_VBLANK_TIME(ATTOSECONDS_IN_USEC(0)) @@ -536,7 +415,7 @@ ROM_END GAME( 1984, maxaflex, 0, maxaflex, a600xl, driver_device, 0, ROT0, "Exidy", "Max-A-Flex", MACHINE_IS_BIOS_ROOT ) -GAME( 1982, mf_achas, maxaflex, maxaflex, a600xl, driver_device, 0, ROT0, "Exidy / First Star Software", "Astro Chase (Max-A-Flex)", 0 ) -GAME( 1983, mf_brist, maxaflex, maxaflex, a600xl, driver_device, 0, ROT0, "Exidy / First Star Software", "Bristles (Max-A-Flex)", 0 ) -GAME( 1983, mf_flip, maxaflex, maxaflex, a600xl, driver_device, 0, ROT0, "Exidy / First Star Software", "Flip & Flop (Max-A-Flex)", 0 ) +GAME( 1982, mf_achas, maxaflex, maxaflex, a600xl, driver_device, 0, ROT0, "Exidy / First Star Software", "Astro Chase (Max-A-Flex)", 0 ) +GAME( 1983, mf_brist, maxaflex, maxaflex, a600xl, driver_device, 0, ROT0, "Exidy / First Star Software", "Bristles (Max-A-Flex)", 0 ) +GAME( 1983, mf_flip, maxaflex, maxaflex, a600xl, driver_device, 0, ROT0, "Exidy / First Star Software", "Flip & Flop (Max-A-Flex)", 0 ) GAME( 1984, mf_bdash, maxaflex, maxaflex, a600xl, driver_device, 0, ROT0, "Exidy / First Star Software", "Boulder Dash (Max-A-Flex)", 0 ) diff --git a/src/mame/drivers/novag6502.cpp b/src/mame/drivers/novag6502.cpp index 9c38552d1db..46608a6230c 100644 --- a/src/mame/drivers/novag6502.cpp +++ b/src/mame/drivers/novag6502.cpp @@ -57,8 +57,6 @@ instead of magnet sensors. #include "bus/rs232/rs232.h" #include "machine/mos6551.h" #include "machine/nvram.h" -#include "sound/beep.h" -#include "video/hd44780.h" // internal artwork #include "novag_sexpert.lh" // clickable @@ -70,13 +68,9 @@ class novag6502_state : public novagbase_state { public: novag6502_state(const machine_config &mconfig, device_type type, const char *tag) - : novagbase_state(mconfig, type, tag), - m_lcd(*this, "hd44780") + : novagbase_state(mconfig, type, tag) { } - // devices/pointers - optional_device<hd44780_device> m_lcd; - TIMER_DEVICE_CALLBACK_MEMBER(irq_on) { m_maincpu->set_input_line(M6502_IRQ_LINE, ASSERT_LINE); } TIMER_DEVICE_CALLBACK_MEMBER(irq_off) { m_maincpu->set_input_line(M6502_IRQ_LINE, CLEAR_LINE); } @@ -93,8 +87,6 @@ public: DECLARE_WRITE8_MEMBER(sexpert_lcd_data_w); DECLARE_READ8_MEMBER(sexpert_input1_r); DECLARE_READ8_MEMBER(sexpert_input2_r); - DECLARE_PALETTE_INIT(sexpert); - HD44780_PIXEL_UPDATE(sexpert_pixel_update); DECLARE_MACHINE_RESET(sexpert); DECLARE_DRIVER_INIT(sexpert); DECLARE_INPUT_CHANGED_MEMBER(sexpert_cpu_freq); @@ -247,6 +239,29 @@ void novagbase_state::display_matrix(int maxx, int maxy, u32 setx, u32 sety, boo } +// LCD + +PALETTE_INIT_MEMBER(novagbase_state, novag_lcd) +{ + palette.set_pen_color(0, rgb_t(138, 146, 148)); // background + palette.set_pen_color(1, rgb_t(92, 83, 88)); // lcd pixel on + palette.set_pen_color(2, rgb_t(131, 136, 139)); // lcd pixel off +} + +HD44780_PIXEL_UPDATE(novagbase_state::novag_lcd_pixel_update) +{ + // char size is 5x8 + if (x > 4 || y > 7) + return; + + if (line < 2 && pos < 8) + { + // internal: (8+8)*1, external: 1*16 + bitmap.pix16(1 + y, 1 + line*8*6 + pos*6 + x) = state ? 1 : 2; + } +} + + // generic input handlers u16 novagbase_state::read_inputs(int columns) @@ -308,34 +323,14 @@ READ8_MEMBER(novag6502_state::supercon_input2_r) Super Expert ******************************************************************************/ -// LCD - -PALETTE_INIT_MEMBER(novag6502_state, sexpert) -{ - palette.set_pen_color(0, rgb_t(138, 146, 148)); // background - palette.set_pen_color(1, rgb_t(92, 83, 88)); // lcd pixel on - palette.set_pen_color(2, rgb_t(131, 136, 139)); // lcd pixel off -} - -HD44780_PIXEL_UPDATE(novag6502_state::sexpert_pixel_update) -{ - // char size is 5x8 - if (x > 4 || y > 7) - return; - - if (line < 2 && pos < 8) - { - // internal: (8+8)*1, external: 1*16 - bitmap.pix16(1 + y, 1 + line*8*6 + pos*6 + x) = state ? 1 : 2; - } -} +// TTL/generic WRITE8_MEMBER(novag6502_state::sexpert_lcd_control_w) { // d0: HD44780 RS // d1: HD44780 R/W // d2: HD44780 E - m_lcd_control = data; + m_lcd_control = data & 7; } WRITE8_MEMBER(novag6502_state::sexpert_lcd_data_w) @@ -345,8 +340,6 @@ WRITE8_MEMBER(novag6502_state::sexpert_lcd_data_w) m_lcd->write(space, m_lcd_control & 1, data); } -// TTL/generic - WRITE8_MEMBER(novag6502_state::sexpert_leds_w) { // d0-d7: chessboard leds @@ -825,11 +818,11 @@ static MACHINE_CONFIG_START( sexpert, novag6502_state ) MCFG_SCREEN_UPDATE_DEVICE("hd44780", hd44780_device, screen_update) MCFG_SCREEN_PALETTE("palette") MCFG_PALETTE_ADD("palette", 3) - MCFG_PALETTE_INIT_OWNER(novag6502_state, sexpert) + MCFG_PALETTE_INIT_OWNER(novagbase_state, novag_lcd) MCFG_HD44780_ADD("hd44780") MCFG_HD44780_LCD_SIZE(2, 8) - MCFG_HD44780_PIXEL_UPDATE_CB(novag6502_state, sexpert_pixel_update) + MCFG_HD44780_PIXEL_UPDATE_CB(novagbase_state, novag_lcd_pixel_update) MCFG_TIMER_DRIVER_ADD_PERIODIC("display_decay", novagbase_state, display_decay_tick, attotime::from_msec(1)) MCFG_DEFAULT_LAYOUT(layout_novag_sexpert) diff --git a/src/mame/drivers/novag68k.cpp b/src/mame/drivers/novag68k.cpp index e76b6e79863..7319344d262 100644 --- a/src/mame/drivers/novag68k.cpp +++ b/src/mame/drivers/novag68k.cpp @@ -10,17 +10,24 @@ such as Arena(in editmode). TODO: - - x + - verify irq/beeper timing + - RS232 port ****************************************************************************** Diablo 68000: -- x +- M68000 @ 16MHz, IRQ ~256Hz +- 2*8KB RAM TC5565 battery-backed, 2*32KB hashtable RAM TC55257 3*32KB ROM +- HD44780 LCD controller (16x1) +- R65C51P2 ACIA @ 1.8432MHz, RS232 +- magnetic sensors, 8*8 chessboard leds ******************************************************************************/ #include "includes/novagbase.h" #include "cpu/m68000/m68000.h" +#include "machine/mos6551.h" +#include "machine/nvram.h" // internal artwork #include "novag_diablo68k.lh" // clickable @@ -33,9 +40,12 @@ public: : novagbase_state(mconfig, type, tag) { } - // devices/pointers - // Diablo 68000 + DECLARE_WRITE8_MEMBER(diablo68k_control_w); + DECLARE_WRITE8_MEMBER(diablo68k_lcd_data_w); + DECLARE_WRITE8_MEMBER(diablo68k_leds_w); + DECLARE_READ8_MEMBER(diablo68k_input1_r); + DECLARE_READ8_MEMBER(diablo68k_input2_r); }; @@ -46,6 +56,49 @@ public: Diablo 68000 ******************************************************************************/ +// TTL + +WRITE8_MEMBER(novag68k_state::diablo68k_control_w) +{ + // d1: HD44780 RS + // other: ? + m_lcd_control = data & 7; + + // d7: enable beeper + m_beeper->set_state(data >> 7 & 1); + + // d4-d6: input mux, led select + m_inp_mux = 1 << (data >> 4 & 0x7) & 0xff; + display_matrix(8, 8, m_led_data, m_inp_mux); + m_led_data = 0; // ? +} + +WRITE8_MEMBER(novag68k_state::diablo68k_lcd_data_w) +{ + // d0-d7: HD44780 data + m_lcd->write(space, m_lcd_control >> 1 & 1, data); +} + +WRITE8_MEMBER(novag68k_state::diablo68k_leds_w) +{ + // d0-d7: chessboard leds + m_led_data = data; +} + +READ8_MEMBER(novag68k_state::diablo68k_input1_r) +{ + // d0-d7: multiplexed inputs (chessboard squares) + return ~read_inputs(8) & 0xff; +} + +READ8_MEMBER(novag68k_state::diablo68k_input2_r) +{ + // d0-d2: multiplexed inputs (side panel) + // other: ? + return ~read_inputs(8) >> 8 & 7; +} + + /****************************************************************************** Address Maps @@ -54,8 +107,15 @@ public: // Diablo 68000 static ADDRESS_MAP_START( diablo68k_map, AS_PROGRAM, 16, novag68k_state ) - AM_RANGE( 0x000000, 0x00ffff ) AM_ROM - AM_RANGE( 0xff8000, 0xffffff ) AM_RAM + AM_RANGE(0x000000, 0x00ffff) AM_ROM + AM_RANGE(0x200000, 0x20ffff) AM_ROM AM_REGION("maincpu", 0x10000) + AM_RANGE(0x280000, 0x28ffff) AM_RAM + AM_RANGE(0x300000, 0x300007) AM_DEVREADWRITE8("acia", mos6551_device, read, write, 0xff00) + AM_RANGE(0x380000, 0x380001) AM_WRITE8(diablo68k_leds_w, 0xff00) AM_READNOP + AM_RANGE(0x3a0000, 0x3a0001) AM_WRITE8(diablo68k_lcd_data_w, 0xff00) + AM_RANGE(0x3c0000, 0x3c0001) AM_READWRITE8(diablo68k_input2_r, diablo68k_control_w, 0xff00) + AM_RANGE(0x3e0000, 0x3e0001) AM_READ8(diablo68k_input1_r, 0xff00) + AM_RANGE(0xff8000, 0xffbfff) AM_RAM AM_SHARE("nvram") ADDRESS_MAP_END @@ -200,16 +260,36 @@ INPUT_PORTS_END static MACHINE_CONFIG_START( diablo68k, novag68k_state ) /* basic machine hardware */ - MCFG_CPU_ADD("maincpu", M68000, XTAL_8MHz/2) - MCFG_CPU_PERIODIC_INT_DRIVER(novag68k_state, irq2_line_hold, 250) // guessed + MCFG_CPU_ADD("maincpu", M68000, XTAL_16MHz) + MCFG_CPU_PERIODIC_INT_DRIVER(novag68k_state, irq2_line_hold, 256) // guessed MCFG_CPU_PROGRAM_MAP(diablo68k_map) + MCFG_DEVICE_ADD("acia", MOS6551, 0) + MCFG_MOS6551_XTAL(XTAL_1_8432MHz) + + MCFG_NVRAM_ADD_0FILL("nvram") + + /* video hardware */ + MCFG_SCREEN_ADD("screen", LCD) + MCFG_SCREEN_REFRESH_RATE(60) // arbitrary + MCFG_SCREEN_VBLANK_TIME(ATTOSECONDS_IN_USEC(2500)) + MCFG_SCREEN_SIZE(6*16+1, 10) + MCFG_SCREEN_VISIBLE_AREA(0, 6*16, 0, 10-1) + MCFG_SCREEN_UPDATE_DEVICE("hd44780", hd44780_device, screen_update) + MCFG_SCREEN_PALETTE("palette") + MCFG_PALETTE_ADD("palette", 3) + MCFG_PALETTE_INIT_OWNER(novagbase_state, novag_lcd) + + MCFG_HD44780_ADD("hd44780") + MCFG_HD44780_LCD_SIZE(2, 8) + MCFG_HD44780_PIXEL_UPDATE_CB(novagbase_state, novag_lcd_pixel_update) + MCFG_TIMER_DRIVER_ADD_PERIODIC("display_decay", novagbase_state, display_decay_tick, attotime::from_msec(1)) MCFG_DEFAULT_LAYOUT(layout_novag_diablo68k) /* sound hardware */ MCFG_SPEAKER_STANDARD_MONO("mono") - MCFG_SOUND_ADD("beeper", BEEP, 1000) // guessed + MCFG_SOUND_ADD("beeper", BEEP, 1024) // guessed MCFG_SOUND_ROUTE(ALL_OUTPUTS, "mono", 0.25) MACHINE_CONFIG_END @@ -223,7 +303,7 @@ ROM_START( diablo68 ) ROM_REGION16_BE( 0x20000, "maincpu", 0 ) ROM_LOAD16_BYTE("evenurom.bin", 0x00000, 0x8000, CRC(03477746) SHA1(8bffcb159a61e59bfc45411e319aea6501ebe2f9) ) ROM_LOAD16_BYTE("oddlrom.bin", 0x00001, 0x8000, CRC(e182dbdd) SHA1(24dacbef2173fa737636e4729ff22ec1e6623ca5) ) - ROM_LOAD16_BYTE("book.bin", 0x10000, 0x8000, CRC(553a5c8c) SHA1(ccb5460ff10766a5ca8008ae2cffcff794318108) ) + ROM_LOAD16_BYTE("book.bin", 0x10000, 0x8000, CRC(553a5c8c) SHA1(ccb5460ff10766a5ca8008ae2cffcff794318108) ) // no odd rom ROM_END @@ -233,4 +313,4 @@ ROM_END ******************************************************************************/ /* YEAR NAME PARENT COMPAT MACHINE INPUT INIT COMPANY, FULLNAME, FLAGS */ -CONS( 1991, diablo68, 0, 0, diablo68k, diablo68k, driver_device, 0, "Novag", "Diablo 68000", MACHINE_NOT_WORKING | MACHINE_CLICKABLE_ARTWORK ) +CONS( 1991, diablo68, 0, 0, diablo68k, diablo68k, driver_device, 0, "Novag", "Diablo 68000", MACHINE_CLICKABLE_ARTWORK ) diff --git a/src/mame/drivers/osborne1.cpp b/src/mame/drivers/osborne1.cpp index f94df70c8b5..99b68229b14 100644 --- a/src/mame/drivers/osborne1.cpp +++ b/src/mame/drivers/osborne1.cpp @@ -180,7 +180,7 @@ static INPUT_PORTS_START( osborne1 ) PORT_BIT(0x01, IP_ACTIVE_LOW, IPT_UNUSED) PORT_START("RESET") - PORT_BIT(0x80, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_NAME("RESET") PORT_CODE(KEYCODE_F12) + PORT_BIT(0x80, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_NAME("RESET") PORT_CODE(KEYCODE_F12) PORT_CHANGED_MEMBER(DEVICE_SELF, osborne1_state, reset_key, 0) PORT_BIT(0x40, IP_ACTIVE_LOW, IPT_UNUSED) PORT_BIT(0x20, IP_ACTIVE_LOW, IPT_UNUSED) PORT_BIT(0x10, IP_ACTIVE_LOW, IPT_UNUSED) diff --git a/src/mame/drivers/pc9801.cpp b/src/mame/drivers/pc9801.cpp index da1f6bebdcc..33140a2ebf5 100644 --- a/src/mame/drivers/pc9801.cpp +++ b/src/mame/drivers/pc9801.cpp @@ -17,6 +17,7 @@ - some later SWs put "Invalid command byte 05" (Absolutely Mahjong on Epson logo) - investigate on POR bit - test 2dd more + - clean-ups/split into devices. TODO (PC-9801RS): - extra features; @@ -542,6 +543,8 @@ public: struct { uint8_t pal_entry; uint8_t r[0x100],g[0x100],b[0x100]; + uint16_t read_bank; + uint16_t write_bank; }m_analog256; struct { uint8_t mode; @@ -592,6 +595,13 @@ public: DECLARE_WRITE16_MEMBER(grcg_gvram_w); DECLARE_READ16_MEMBER(grcg_gvram0_r); DECLARE_WRITE16_MEMBER(grcg_gvram0_w); + + DECLARE_READ16_MEMBER(pc9821_grcg_gvram_r); + DECLARE_WRITE16_MEMBER(pc9821_grcg_gvram_w); + DECLARE_READ16_MEMBER(pc9821_grcg_gvram0_r); + DECLARE_WRITE16_MEMBER(pc9821_grcg_gvram0_w); + uint16_t m_pc9821_256vram_bank; + DECLARE_READ16_MEMBER(upd7220_grcg_r); DECLARE_WRITE16_MEMBER(upd7220_grcg_w); void egc_blit_w(uint32_t offset, uint16_t data, uint16_t mem_mask); @@ -742,7 +752,8 @@ public: #define DISPLAY_REG 7 #define ANALOG_16_MODE 0 -#define ANALOG_256_MODE 0x10 +#define ANALOG_256_MODE (0x20 >> 1) +#define GDC_IS_5MHz (0x84 >> 1) void pc9801_state::device_timer(emu_timer &timer, device_timer_id id, int param, void *ptr) { @@ -2296,23 +2307,55 @@ READ16_MEMBER(pc9801_state::timestamp_r) /* basically a read-back of various registers */ // bit 1: GDC clock select (port 0x6a, selects with 0x84 & bit 0) -// bit 0: +// bit 0: current setting READ8_MEMBER(pc9801_state::ext2_video_ff_r) { uint8_t res; res = 0; - + switch(m_ext2_ff) { +// case 0x00: ? +// case 0x01: 200 line color / b&w mode (i/o 0x68 -> 0x02) +// case 0x02: Odd-numbered raster mask (i/o 0x68 -> 0x08) case 0x03: res = m_video_ff[DISPLAY_REG]; break; // display reg +// case 0x04: palette mode (i/o 0x6a -> 0x00) +// case 0x05: GDC sync mode (i/o 0x6a -> 0x40) +// case 0x06: unknown (i/o 0x6a -> 0x44) +// case 0x07: EGC compatibility mode (i/o 0x6a -> 0x04) +// case 0x08: Protected mode f/f (i/o 0x6a -> 0x06) +// case 0x09: GDC clock #0 (i/o 0x6a -> 0x82) case 0x0a: res = m_ex_video_ff[ANALOG_256_MODE]; break; // 256 color mode +// case 0x0b: VRAM access mode (i/o 0x6a -> 0x62) +// case 0x0c: unknown +// case 0x0d: VRAM boundary mode (i/o 0x6a -> 0x68) +// case 0x0e: 65536 color GFX mode (i/o 0x6a -> 0x22) +// case 0x0f: 65,536 color palette mode (i/o 0x6a -> 0x24) +// case 0x10: unknown (i/o 0x6a -> 0x6a) +// case 0x11: Reverse mode related (i/o 0x6a -> 0x26) +// case 0x12: 256 color overscan color (i/o 0x6a -> 0x2c) +// case 0x13: Reverse mode related (i/o 0x6a -> 0x28) +// case 0x14: AGDC Drawing processor selection (i/o 0x6a -> 0x66) +// case 0x15: unknown (i/o 0x6a -> 0x60) +// case 0x16: unknown (i/o 0x6a -> 0xc2) +// case 0x17: bitmap config direction (i/o 0x6a -> 0x6c) +// case 0x18: High speed palette write (i/o 0x6a -> 0x2a) +// case 0x19: unknown (i/o 0x6a -> 0x48) +// case 0x1a: unknown (i/o 0x6a -> 0xc8) +// case 0x1b: unknown (i/o 0x6a -> 0x2e) +// case 0x1c: unknown (i/o 0x6a -> 0x6e) +// case 0x1d: unknown (i/o 0x6a -> 0xc0) +// case 0x1e: unknown (i/o 0x6a -> 0x80 or 0x46?) +// case 0x1f: unknown (i/o 0x6a -> 0x08) default: if(m_ext2_ff < 0x20) popmessage("PC-9821: read ext2 f/f with value %02x",m_ext2_ff); break; } + res|= (m_ex_video_ff[GDC_IS_5MHz] << 1); + return res; } @@ -2333,15 +2376,70 @@ WRITE8_MEMBER(pc9801_state::winram_w) offset = (offset & 0x1ffff) | (m_pc9821_window_bank & 0xfe) * 0x10000; }*/ +// TODO: analog 256 mode needs HW tests +READ16_MEMBER(pc9801_state::pc9821_grcg_gvram_r) +{ + if(m_ex_video_ff[ANALOG_256_MODE]) + { + return space.read_word(0xf00000|(offset*2)|((m_analog256.write_bank)*0x8000),mem_mask); + } + + return grcg_gvram_r(space,offset,mem_mask); +} + +WRITE16_MEMBER(pc9801_state::pc9821_grcg_gvram_w) +{ + if(m_ex_video_ff[ANALOG_256_MODE]) + { + space.write_word(0xf00000|(offset*2)|(m_analog256.write_bank*0x8000),data,mem_mask); + return; + } + + grcg_gvram_w(space,offset,data,mem_mask); +} + +READ16_MEMBER(pc9801_state::pc9821_grcg_gvram0_r) +{ + if(m_ex_video_ff[ANALOG_256_MODE]) + { + switch(offset*2) + { + case 4: return m_analog256.write_bank; +// case 6: return m_analog256.read_bank; + } + + //return 0; + } + + return grcg_gvram0_r(space,offset,mem_mask); +} + +WRITE16_MEMBER(pc9801_state::pc9821_grcg_gvram0_w) +{ + if(m_ex_video_ff[ANALOG_256_MODE]) + { + //printf("%08x %08x\n",offset*2,data); + switch(offset*2) + { + case 4: COMBINE_DATA(&m_analog256.write_bank); break; +// case 6: COMBINE_DATA(&m_analog256.read_bank); break; + } + //return; + } + + grcg_gvram0_w(space,offset,data,mem_mask); +} + + static ADDRESS_MAP_START( pc9821_map, AS_PROGRAM, 32, pc9801_state ) //AM_RANGE(0x00080000, 0x0009ffff) AM_READWRITE8(winram_r, winram_w, 0xffffffff) AM_RANGE(0x000a0000, 0x000a3fff) AM_READWRITE16(tvram_r, tvram_w, 0xffffffff) AM_RANGE(0x000a4000, 0x000a4fff) AM_READWRITE8(pc9801rs_knjram_r, pc9801rs_knjram_w, 0xffffffff) - AM_RANGE(0x000a8000, 0x000bffff) AM_READWRITE16(grcg_gvram_r, grcg_gvram_w, 0xffffffff) + AM_RANGE(0x000a8000, 0x000bffff) AM_READWRITE16(pc9821_grcg_gvram_r, pc9821_grcg_gvram_w, 0xffffffff) AM_RANGE(0x000cc000, 0x000cdfff) AM_ROM AM_REGION("sound_bios",0) //sound BIOS // AM_RANGE(0x000d8000, 0x000d9fff) AM_ROM AM_REGION("ide",0) AM_RANGE(0x000da000, 0x000dbfff) AM_RAM // ide ram - AM_RANGE(0x000e0000, 0x000e7fff) AM_READWRITE16(grcg_gvram0_r,grcg_gvram0_w, 0xffffffff) + AM_RANGE(0x000e0000, 0x000e7fff) AM_READWRITE16(pc9821_grcg_gvram0_r,pc9821_grcg_gvram0_w, 0xffffffff) AM_RANGE(0x000e8000, 0x000fffff) AM_DEVICE16("ipl_bank", address_map_bank_device, amap16, 0xffffffff) AM_RANGE(0x00f00000, 0x00f9ffff) AM_RAM AM_SHARE("ext_gvram") AM_RANGE(0xffee8000, 0xffefffff) AM_DEVICE16("ipl_bank", address_map_bank_device, amap16, 0xffffffff) diff --git a/src/mame/drivers/pitnrun.cpp b/src/mame/drivers/pitnrun.cpp index 0147a3716a2..80d20ddf5b9 100644 --- a/src/mame/drivers/pitnrun.cpp +++ b/src/mame/drivers/pitnrun.cpp @@ -66,22 +66,25 @@ K1000233A */ #include "emu.h" -#include "cpu/z80/z80.h" +#include "includes/pitnrun.h" + #include "cpu/m6805/m68705.h" +#include "cpu/z80/z80.h" + #include "machine/gen_latch.h" #include "machine/watchdog.h" + #include "sound/ay8910.h" -#include "includes/pitnrun.h" INTERRUPT_GEN_MEMBER(pitnrun_state::nmi_source) { - if(m_nmi) device.execute().set_input_line(INPUT_LINE_NMI, PULSE_LINE); + if (m_nmi) device.execute().set_input_line(INPUT_LINE_NMI, PULSE_LINE); } WRITE8_MEMBER(pitnrun_state::nmi_enable_w) { - m_nmi = data & 1; + m_nmi = data & 1; } WRITE8_MEMBER(pitnrun_state::hflip_w) @@ -136,15 +139,6 @@ static ADDRESS_MAP_START( pitnrun_sound_io_map, AS_IO, 8, pitnrun_state ) AM_RANGE(0x98, 0x98) AM_WRITENOP ADDRESS_MAP_END -static ADDRESS_MAP_START( pitnrun_mcu_map, AS_PROGRAM, 8, pitnrun_state ) - ADDRESS_MAP_GLOBAL_MASK(0x7ff) - AM_RANGE(0x0000, 0x0000) AM_READWRITE(m68705_portA_r,m68705_portA_w) - AM_RANGE(0x0001, 0x0001) AM_READWRITE(m68705_portB_r,m68705_portB_w) - AM_RANGE(0x0002, 0x0002) AM_READ(m68705_portC_r) - AM_RANGE(0x0003, 0x007f) AM_RAM - AM_RANGE(0x0080, 0x07ff) AM_ROM -ADDRESS_MAP_END - static INPUT_PORTS_START( pitnrun ) PORT_START("SYSTEM") @@ -231,8 +225,12 @@ static MACHINE_CONFIG_START( pitnrun, pitnrun_state ) MCFG_CPU_IO_MAP(pitnrun_sound_io_map) MCFG_CPU_VBLANK_INT_DRIVER("screen", pitnrun_state, irq0_line_hold) - MCFG_CPU_ADD("mcu", M68705,XTAL_18_432MHz/6) /* verified on pcb */ - MCFG_CPU_PROGRAM_MAP(pitnrun_mcu_map) + MCFG_CPU_ADD("mcu", M68705P5, XTAL_18_432MHz/6) /* verified on pcb */ + MCFG_M68705_PORTA_R_CB(READ8(pitnrun_state, m68705_portA_r)) + MCFG_M68705_PORTB_R_CB(READ8(pitnrun_state, m68705_portB_r)) + MCFG_M68705_PORTC_R_CB(READ8(pitnrun_state, m68705_portC_r)) + MCFG_M68705_PORTA_W_CB(WRITE8(pitnrun_state, m68705_portA_w)) + MCFG_M68705_PORTB_W_CB(WRITE8(pitnrun_state, m68705_portB_w)) MCFG_WATCHDOG_ADD("watchdog") diff --git a/src/mame/drivers/polepos.cpp b/src/mame/drivers/polepos.cpp index b6952cf028d..1e6f5df0f07 100644 --- a/src/mame/drivers/polepos.cpp +++ b/src/mame/drivers/polepos.cpp @@ -2208,6 +2208,39 @@ ROM_END | 4 | | OFF | | ON | | | 3 | | ON | | ON | | '-------------------------------+-----+-----+-----+-----+-----------------------' + + + Pinouts / Edge Connectors.... + + + 'A' board connector. 'B' board connector. 'C' board connector. + ---------------+--+------------------ ---------------+--+------------------ ---------------+--+------------------ + Solder Side |PN| Components Side Solder Side |PN| Components Side Solder Side |PN| Components Side + ---------------+--+------------------ ---------------+--+------------------ ---------------+--+------------------ + |01| GND GND |01| GND +5V |01| +5V + GEARS SWITCH |02| GND |02| +5V |02| +5V + 50 PTS COIN-IN |03| GND |03| |03| + |04| GND +5V |04| +5V |04| + 25 PTS COIN-IN |05| GND |05| COMMON ACCEL + BREAK (HI) |05| + +5V |06| +5V BRAKE POT |06| ACCEL POT |06| + +5V |07| +5V |07| COMMON ACCEL + BREAK (LO) |07| GND + +5V |08| +5V |08| GND |08| VIDEO GND + |09| AUDIO SIGNAL 4(***) |09| AUDIO SIGNAL 1(***) VIDEO SYNC |09| VIDEO BLUE + |10| AUDIO SIGNAL 3(***) |10| AUDIO SIGNAL 2(***) VIDEO GREEN |10| VIDEO RED + +12V |11| GND |11| GND |11| + WHEEL X SIGNAL |12| |12| |12| + WHEEL Z SIGNAL |13| |13| |13| + -5V |14| |14| |14| + AUDIO SIGNAL 1(*) |15| AMP AUDIO SIGNAL (**) |15| GND |15| GND + AUDIO SIGNAL 2(*) |16| AMP AUDIO SIGNAL (**) |16| GND |16| GND + AUDIO SIGNAL 3(*) |17| |17| GND |17| GND + AUDIO SIGNAL 4(*) |18| |18| GND |18| GND + + + (*) To 'B' connector. + (**) To 'D' connector. + (***) To 'A' connector. + */ ROM_START( polepos2bs ) /* Z80 memory/ROM data */ diff --git a/src/mame/drivers/polyplay.cpp b/src/mame/drivers/polyplay.cpp index 90d5c11b305..c281bca19f5 100644 --- a/src/mame/drivers/polyplay.cpp +++ b/src/mame/drivers/polyplay.cpp @@ -369,8 +369,20 @@ ROM_END ROM_START( polyplay2 ) ROM_REGION( 0x10000, Z80CPU_TAG, 0 ) + ROM_LOAD( "2_1.ROM", 0x0000, 0x2000, CRC(d728ca42) SHA1(7359a59ba7f205b3ac95c8a0946093f24bdaa4da) ) + ROM_LOAD( "2_2.ROM", 0x2000, 0x2000, CRC(52316236) SHA1(88c159621d40953240c5d2f1d6dcebb8f5e1ee81) ) + ROM_LOAD( "2_3.ROM", 0x4000, 0x2000, CRC(e199d303) SHA1(fea2c3c659222553f36b3e922c6ac017f7111025) ) + ROM_LOAD( "2_4.ROM", 0x6000, 0x2000, CRC(1324c2e2) SHA1(c0102d5abbb2f4dbb5b8dff5ad515bc3f2af9166) ) + ROM_LOAD( "2_5.ROM", 0x8000, 0x2000, CRC(2e959fe9) SHA1(1f0a80bb26d0ae332d4a4313ec22ab7eefcf1e34) ) + ROM_LOAD( "2_6.ROM", 0xA000, 0x2000, CRC(85774542) SHA1(420349a0d812bc0052a77cbc6c5ab84262e58b32) ) + + ROM_REGION( 0x800, "gfx1", 0 ) + ROM_LOAD( "1_1.bin", 0x0000, 0x0800, CRC(4f028af9) SHA1(319537234069b43cfffafe567cc599ae05f24e23) ) +ROM_END + +ROM_START( polyplay2c ) + ROM_REGION( 0x10000, Z80CPU_TAG, 0 ) ROM_LOAD( "2_1.bin", 0x0000, 0x2000, CRC(bf22f44f) SHA1(dd412b45f49ceffe336d905043c7af2447c577a0) ) - ROM_LOAD( "2_2.bin", 0x2000, 0x2000, CRC(e54b8be8) SHA1(23037102eab60fd03c349ad154b2498139e84dd4) ) ROM_LOAD( "2_3.bin", 0x4000, 0x2000, CRC(ac43ec6b) SHA1(1662e10d80d47c1e3c54d4ef232c0d671fecce96) ) ROM_LOAD( "2_4.bin", 0x6000, 0x2000, CRC(703f3d46) SHA1(5ab571cb63ffdbce86b6e452988402e5c1098009) ) @@ -381,5 +393,6 @@ ROM_START( polyplay2 ) ROM_END /* game driver */ -GAME( 1986, polyplay, 0, polyplay_zre, polyplay, driver_device, 0, ROT0, "VEB Polytechnik Karl-Marx-Stadt", "Poly-Play (ZRE)", 0 ) -GAME( 1989, polyplay2, 0, polyplay_zrepp, polyplay, driver_device, 0, ROT0, "VEB Polytechnik Karl-Marx-Stadt", "Poly-Play (ZRE-PP - Czech)", 0 ) +GAME( 1986, polyplay, 0, polyplay_zre, polyplay, driver_device, 0, ROT0, "VEB Polytechnik Karl-Marx-Stadt", "Poly-Play (ZRE)", 0 ) +GAME( 1989, polyplay2, 0, polyplay_zrepp, polyplay, driver_device, 0, ROT0, "VEB Polytechnik Karl-Marx-Stadt", "Poly-Play (ZRE-PP)", 0 ) +GAME( 1989, polyplay2c, polyplay2, polyplay_zrepp, polyplay, driver_device, 0, ROT0, "VEB Polytechnik Karl-Marx-Stadt", "Poly-Play (ZRE-PP - Czech)", 0 ) diff --git a/src/mame/drivers/retofinv.cpp b/src/mame/drivers/retofinv.cpp index ce56ec15ff2..eefdd9f1dfc 100644 --- a/src/mame/drivers/retofinv.cpp +++ b/src/mame/drivers/retofinv.cpp @@ -6,7 +6,16 @@ Return of the Invaders driver by Jarek Parchanski, Andrea Mazzoleni -the game was developed by UPL for Taito. +UPL is said to have developed Return of the Invaders for Taito, but some digging +in the ROMs reveals the following strings: + + Programed by NAKAKUMA AKIRA + V 1.0 (85.3.15) + + NOBUO KODERA + AKIRA NAKAKUMA + HIKARU KASAHARA + COMIX LTD. 1985. Notes: - I derived the ROM names from the board diagram in the manual. There might @@ -31,11 +40,11 @@ Notes: ***************************************************************************/ #include "emu.h" +#include "includes/retofinv.h" + #include "cpu/z80/z80.h" -#include "cpu/m6805/m68705.h" #include "machine/watchdog.h" #include "sound/sn76496.h" -#include "includes/retofinv.h" void retofinv_state::machine_start() @@ -43,23 +52,6 @@ void retofinv_state::machine_start() save_item(NAME(m_main_irq_mask)); save_item(NAME(m_sub_irq_mask)); save_item(NAME(m_cpu2_m6000)); - - if (m_68705 != nullptr) // only for the parent (with MCU) - { - save_item(NAME(m_from_main)); - save_item(NAME(m_from_mcu)); - save_item(NAME(m_mcu_sent)); - save_item(NAME(m_main_sent)); - save_item(NAME(m_portA_in)); - save_item(NAME(m_portA_out)); - save_item(NAME(m_ddrA)); - save_item(NAME(m_portB_in)); - save_item(NAME(m_portB_out)); - save_item(NAME(m_ddrB)); - save_item(NAME(m_portC_in)); - save_item(NAME(m_portC_out)); - save_item(NAME(m_ddrC)); - } } WRITE8_MEMBER(retofinv_state::cpu1_reset_w) @@ -74,9 +66,7 @@ WRITE8_MEMBER(retofinv_state::cpu2_reset_w) WRITE8_MEMBER(retofinv_state::mcu_reset_w) { - /* the bootlegs don't have a MCU, so make sure it's there before trying to reset it */ - if (m_68705 != nullptr) - m_68705->set_input_line(INPUT_LINE_RESET, data ? CLEAR_LINE : ASSERT_LINE); + m_68705->reset_w(data ? CLEAR_LINE : ASSERT_LINE); } WRITE8_MEMBER(retofinv_state::cpu2_m6000_w) @@ -91,8 +81,8 @@ READ8_MEMBER(retofinv_state::cpu0_mf800_r) WRITE8_MEMBER(retofinv_state::soundcommand_w) { - m_soundlatch->write(space, 0, data); - m_audiocpu->set_input_line(0, HOLD_LINE); + m_soundlatch->write(space, 0, data); + m_audiocpu->set_input_line(0, HOLD_LINE); } WRITE8_MEMBER(retofinv_state::irq0_ack_w) @@ -119,8 +109,17 @@ WRITE8_MEMBER(retofinv_state::coinlockout_w) machine().bookkeeping().coin_lockout_w(0,~data & 1); } +READ8_MEMBER(retofinv_state::mcu_status_r) +{ + /* bit 4 = when 1, mcu is ready to receive data from main cpu */ + /* bit 5 = when 1, mcu has sent data to the main cpu */ + return + ((CLEAR_LINE == m_68705->host_semaphore_r()) ? 0x10 : 0x00) | + ((CLEAR_LINE != m_68705->mcu_semaphore_r()) ? 0x20 : 0x00); +} -static ADDRESS_MAP_START( main_map, AS_PROGRAM, 8, retofinv_state ) + +static ADDRESS_MAP_START( bootleg_map, AS_PROGRAM, 8, retofinv_state ) AM_RANGE(0x0000, 0x5fff) AM_ROM AM_RANGE(0x7fff, 0x7fff) AM_WRITE(coincounter_w) AM_RANGE(0x7b00, 0x7bff) AM_ROM /* space for diagnostic ROM? The code looks */ @@ -132,7 +131,6 @@ static ADDRESS_MAP_START( main_map, AS_PROGRAM, 8, retofinv_state ) AM_RANGE(0xc000, 0xc000) AM_READ_PORT("P1") AM_RANGE(0xc001, 0xc001) AM_READ_PORT("P2") AM_RANGE(0xc002, 0xc002) AM_READNOP /* bit 7 must be 0, otherwise game resets */ - AM_RANGE(0xc003, 0xc003) AM_READ(mcu_status_r) AM_RANGE(0xc004, 0xc004) AM_READ_PORT("SYSTEM") AM_RANGE(0xc005, 0xc005) AM_READ_PORT("DSW1") AM_RANGE(0xc006, 0xc006) AM_READ_PORT("DSW2") @@ -140,16 +138,21 @@ static ADDRESS_MAP_START( main_map, AS_PROGRAM, 8, retofinv_state ) AM_RANGE(0xc800, 0xc800) AM_WRITE(irq0_ack_w) AM_RANGE(0xc801, 0xc801) AM_WRITE(coinlockout_w) AM_RANGE(0xc802, 0xc802) AM_WRITE(cpu2_reset_w) - AM_RANGE(0xc803, 0xc803) AM_WRITE(mcu_reset_w) // AM_RANGE(0xc804, 0xc804) AM_WRITE(irq1_ack_w) // presumably (meaning memory map is shared with cpu 1) AM_RANGE(0xc805, 0xc805) AM_WRITE(cpu1_reset_w) AM_RANGE(0xd000, 0xd000) AM_DEVWRITE("watchdog", watchdog_timer_device, reset_w) AM_RANGE(0xd800, 0xd800) AM_WRITE(soundcommand_w) - AM_RANGE(0xe000, 0xe000) AM_READ(mcu_r) - AM_RANGE(0xe800, 0xe800) AM_WRITE(mcu_w) AM_RANGE(0xf800, 0xf800) AM_READ(cpu0_mf800_r) ADDRESS_MAP_END +static ADDRESS_MAP_START( main_map, AS_PROGRAM, 8, retofinv_state ) + AM_IMPORT_FROM(bootleg_map) + AM_RANGE(0xc003, 0xc003) AM_READ(mcu_status_r) + AM_RANGE(0xc803, 0xc803) AM_WRITE(mcu_reset_w) + AM_RANGE(0xe000, 0xe000) AM_DEVREAD("68705", taito68705_mcu_device, data_r) + AM_RANGE(0xe800, 0xe800) AM_DEVWRITE("68705", taito68705_mcu_device, data_w) +ADDRESS_MAP_END + static ADDRESS_MAP_START( sub_map, AS_PROGRAM, 8, retofinv_state ) AM_RANGE(0x0000, 0x1fff) AM_ROM AM_RANGE(0x8000, 0x87ff) AM_RAM_WRITE(fg_videoram_w) AM_SHARE("fg_videoram") @@ -168,18 +171,6 @@ static ADDRESS_MAP_START( sound_map, AS_PROGRAM, 8, retofinv_state ) AM_RANGE(0xe000, 0xffff) AM_ROM /* space for diagnostic ROM */ ADDRESS_MAP_END -static ADDRESS_MAP_START( mcu_map, AS_PROGRAM, 8, retofinv_state ) - ADDRESS_MAP_GLOBAL_MASK(0x7ff) - AM_RANGE(0x0000, 0x0000) AM_READWRITE(mcu_portA_r, mcu_portA_w) - AM_RANGE(0x0001, 0x0001) AM_READWRITE(mcu_portB_r, mcu_portB_w) - AM_RANGE(0x0002, 0x0002) AM_READWRITE(mcu_portC_r, mcu_portC_w) - AM_RANGE(0x0004, 0x0004) AM_WRITE(mcu_ddrA_w) - AM_RANGE(0x0005, 0x0005) AM_WRITE(mcu_ddrB_w) - AM_RANGE(0x0006, 0x0006) AM_WRITE(mcu_ddrC_w) - AM_RANGE(0x0010, 0x007f) AM_RAM - AM_RANGE(0x0080, 0x07ff) AM_ROM -ADDRESS_MAP_END - static INPUT_PORTS_START( retofinv ) @@ -382,8 +373,7 @@ static MACHINE_CONFIG_START( retofinv, retofinv_state ) MCFG_CPU_PROGRAM_MAP(sound_map) MCFG_CPU_PERIODIC_INT_DRIVER(retofinv_state, nmi_line_pulse, 2*60) - MCFG_CPU_ADD("68705", M68705,18432000/6) /* 3.072 MHz? */ - MCFG_CPU_PROGRAM_MAP(mcu_map) + MCFG_CPU_ADD("68705", TAITO68705_MCU, 18432000/6) /* 3.072 MHz? */ MCFG_QUANTUM_TIME(attotime::from_hz(6000)) /* 100 CPU slices per frame - enough for the sound CPU to read all commands */ @@ -418,8 +408,10 @@ MACHINE_CONFIG_END /* bootleg has no mcu */ static MACHINE_CONFIG_DERIVED( retofinb, retofinv ) - MCFG_DEVICE_REMOVE("68705") + MCFG_CPU_MODIFY("maincpu") + MCFG_CPU_PROGRAM_MAP(bootleg_map) + MCFG_DEVICE_REMOVE("68705") MACHINE_CONFIG_END @@ -441,7 +433,7 @@ ROM_START( retofinv ) ROM_REGION( 0x10000, "audiocpu", 0 ) ROM_LOAD( "a37-05.17", 0x0000, 0x2000, CRC(9025abea) SHA1(2f03e8572f23624d7cd1215a55109e97fd66e271) ) - ROM_REGION( 0x0800, "68705", 0 ) /* 8k for the microcontroller */ + ROM_REGION( 0x0800, "68705:mcu", 0 ) /* 2k for the microcontroller */ /* the only available dump is from a bootleg board, and is not the real thing (see notes at top of driver) */ ROM_LOAD( "a37-09.37", 0x00000, 0x0800, BAD_DUMP CRC(79bd6ded) SHA1(4967e95b4461c1bfb4e933d1804677799014f77b) ) diff --git a/src/mame/drivers/segae.cpp b/src/mame/drivers/segae.cpp index 1fe88f41c31..b8770aaf79b 100644 --- a/src/mame/drivers/segae.cpp +++ b/src/mame/drivers/segae.cpp @@ -956,15 +956,16 @@ ROM_START( fantzn2 ) ROM_LOAD( "317-0057.key", 0x0000, 0x2000, CRC(ee43d0f0) SHA1(72cb75a4d8352fe372db12046a59ea044360d5c3) ) ROM_END +// Game ID# 833-6407-01 OPA OPA ROM_START( opaopa ) ROM_REGION( 0x50000, "maincpu", 0 ) - ROM_LOAD( "epr11224.ic7", 0x00000, 0x08000, CRC(024b1244) SHA1(59a522ac3d98982cc4ddb1c81f9584d3da453649) ) /* encrypted */ + ROM_LOAD( "epr-11054.ic7", 0x00000, 0x08000, CRC(024b1244) SHA1(59a522ac3d98982cc4ddb1c81f9584d3da453649) ) /* encrypted */ /* The following are 8 0x4000 banks that get mapped to reads from 0x8000 - 0xbfff */ - ROM_LOAD( "epr11223.ic5", 0x10000, 0x08000, CRC(6bc41d6e) SHA1(8997a4ac2a9704f1400d0ec16b259ee496a7efef) ) /* encrypted */ - ROM_LOAD( "epr11222.ic4", 0x18000, 0x08000, CRC(395c1d0a) SHA1(1594bad13e78c5fad4db644cd85a6bac1eaddbad) ) /* encrypted */ - ROM_LOAD( "epr11221.ic3", 0x20000, 0x08000, CRC(4ca132a2) SHA1(cb4e4c01b6ab070eef37c0603190caafe6236ccd) ) /* encrypted */ - ROM_LOAD( "epr11220.ic2", 0x28000, 0x08000, CRC(a165e2ef) SHA1(498ff4c5d3a2658567393378c56be6ed86ac0384) ) /* encrypted */ + ROM_LOAD( "epr-11053.ic5", 0x10000, 0x08000, CRC(6bc41d6e) SHA1(8997a4ac2a9704f1400d0ec16b259ee496a7efef) ) /* encrypted */ + ROM_LOAD( "epr-11052.ic4", 0x18000, 0x08000, CRC(395c1d0a) SHA1(1594bad13e78c5fad4db644cd85a6bac1eaddbad) ) /* encrypted */ + ROM_LOAD( "epr-11051.ic3", 0x20000, 0x08000, CRC(4ca132a2) SHA1(cb4e4c01b6ab070eef37c0603190caafe6236ccd) ) /* encrypted */ + ROM_LOAD( "epr-11050.ic2", 0x28000, 0x08000, CRC(a165e2ef) SHA1(498ff4c5d3a2658567393378c56be6ed86ac0384) ) /* encrypted */ ROM_REGION( 0x2000, "key", 0 ) /* MC8123 key */ ROM_LOAD( "317-0042.key", 0x0000, 0x2000, CRC(d6312538) SHA1(494ac7f080775c21dc7d369e6ea78f3299e6975a) ) diff --git a/src/mame/drivers/stfight.cpp b/src/mame/drivers/stfight.cpp index 6b0e86508b3..2f6586d9bcd 100644 --- a/src/mame/drivers/stfight.cpp +++ b/src/mame/drivers/stfight.cpp @@ -1055,13 +1055,13 @@ ROM_END // Note: Marked MACHINE_IMPERFECT_SOUND due to YM2203 clock issue -GAME( 1986, empcity, 0, stfight, stfight, stfight_state, empcity, ROT0, "Seibu Kaihatsu", "Empire City: 1931 (bootleg?)", MACHINE_IMPERFECT_SOUND | MACHINE_SUPPORTS_SAVE ) -GAME( 1986, empcityu, empcity, stfight, stfight, stfight_state, stfight, ROT0, "Seibu Kaihatsu (Taito / Romstar license)", "Empire City: 1931 (US)", MACHINE_IMPERFECT_SOUND | MACHINE_SUPPORTS_SAVE ) // different title logo -GAME( 1986, empcityj, empcity, stfight, stfight, stfight_state, stfight, ROT0, "Seibu Kaihatsu (Taito license)", "Empire City: 1931 (Japan)", MACHINE_IMPERFECT_SOUND | MACHINE_SUPPORTS_SAVE ) -GAME( 1986, empcityi, empcity, stfight, stfight, stfight_state, stfight, ROT0, "Seibu Kaihatsu (Eurobed license)", "Empire City: 1931 (Italy)", MACHINE_IMPERFECT_SOUND | MACHINE_SUPPORTS_SAVE ) -GAME( 1986, stfight, empcity, stfight, stfight, stfight_state, stfight, ROT0, "Seibu Kaihatsu (Tuning license)", "Street Fight (Germany)", MACHINE_IMPERFECT_SOUND | MACHINE_SUPPORTS_SAVE ) -GAME( 1986, stfighta, empcity, stfight, stfight, stfight_state, stfight, ROT0, "Seibu Kaihatsu", "Street Fight (bootleg?)", MACHINE_IMPERFECT_SOUND | MACHINE_SUPPORTS_SAVE ) -GAME( 1986, stfightgb,empcity, stfight, stfight, stfight_state, stfight, ROT0, "Seibu Kaihatsu (Tuning license)", "Street Fight (Germany - Benelux)", MACHINE_IMPERFECT_SOUND | MACHINE_SUPPORTS_SAVE ) - -/* Cross Shooter uses the same base board, but different video board */ -GAME( 1987, cshootert, airraid, cshooter, cshooter, stfight_state, cshooter, ROT270, "Seibu Kaihatsu (Taito license)", "Cross Shooter (2 PCB Stack)", MACHINE_NOT_WORKING | MACHINE_IMPERFECT_SOUND | MACHINE_SUPPORTS_SAVE ) +GAME( 1986, empcity, 0, stfight, stfight, stfight_state, empcity, ROT0, "Seibu Kaihatsu", "Empire City: 1931 (bootleg?)", MACHINE_IMPERFECT_SOUND | MACHINE_SUPPORTS_SAVE ) +GAME( 1986, empcityu, empcity, stfight, stfight, stfight_state, stfight, ROT0, "Seibu Kaihatsu (Taito / Romstar license)", "Empire City: 1931 (US)", MACHINE_IMPERFECT_SOUND | MACHINE_SUPPORTS_SAVE ) // different title logo +GAME( 1986, empcityj, empcity, stfight, stfight, stfight_state, stfight, ROT0, "Seibu Kaihatsu (Taito license)", "Empire City: 1931 (Japan)", MACHINE_IMPERFECT_SOUND | MACHINE_SUPPORTS_SAVE ) +GAME( 1986, empcityi, empcity, stfight, stfight, stfight_state, stfight, ROT0, "Seibu Kaihatsu (Eurobed license)", "Empire City: 1931 (Italy)", MACHINE_IMPERFECT_SOUND | MACHINE_SUPPORTS_SAVE ) +GAME( 1986, stfight, empcity, stfight, stfight, stfight_state, stfight, ROT0, "Seibu Kaihatsu (Tuning license)", "Street Fight (Germany)", MACHINE_IMPERFECT_SOUND | MACHINE_SUPPORTS_SAVE ) +GAME( 1986, stfighta, empcity, stfight, stfight, stfight_state, stfight, ROT0, "Seibu Kaihatsu", "Street Fight (bootleg?)", MACHINE_IMPERFECT_SOUND | MACHINE_SUPPORTS_SAVE ) +GAME( 1986, stfightgb,empcity, stfight, stfight, stfight_state, stfight, ROT0, "Seibu Kaihatsu (Tuning license)", "Street Fight (Germany - Benelux)", MACHINE_IMPERFECT_SOUND | MACHINE_SUPPORTS_SAVE ) + +// Cross Shooter uses the same base board, but different video board +GAME( 1987, cshootert,airraid, cshooter, cshooter, stfight_state, cshooter, ROT270, "Seibu Kaihatsu (Taito license)", "Cross Shooter (2 PCB Stack)", MACHINE_NOT_WORKING | MACHINE_IMPERFECT_SOUND | MACHINE_SUPPORTS_SAVE ) diff --git a/src/mame/drivers/vicdual.cpp b/src/mame/drivers/vicdual.cpp index e4a76ec2f7c..41fd5feed8d 100644 --- a/src/mame/drivers/vicdual.cpp +++ b/src/mame/drivers/vicdual.cpp @@ -2547,24 +2547,37 @@ ROM_START( depthcho ) ROM_LOAD( "316-0014.u28", 0x0020, 0x0020, CRC(7b7a8492) SHA1(6ba8d891cc6eb0dd80051377b6b832e8894655e7) ) /* sequence PROM */ ROM_END +/* Fully working PCB set from my full-size Sub Hunter upright machine. + +Essentally this pcb set is a Taito-made license of +'Depthcharge' by Gremlin. + +PCB markings are: +- DP070001 / DPN00001 (main) (paper label DP80) +- DP070002 / DPN00002 (sound) (paper label DP80) +Serial number 430229 + +12x program Proms were harris 7643 +2x gfx proms were Harris 7603 */ + ROM_START( subhunt ) ROM_REGION( 0x10000, "maincpu", 0 ) - ROM_LOAD_NIB_LOW ( "dp04", 0x0000, 0x0400, CRC(0ace1aef) SHA1(071256dd63e2e449093a65a4c9b006be5e17b786) ) - ROM_LOAD_NIB_HIGH( "dp01", 0x0000, 0x0400, CRC(da9e835b) SHA1(505c969b479aeab11bb6a21ef06837280846d90a) ) - ROM_LOAD_NIB_LOW ( "dp10", 0x0400, 0x0400, CRC(de752f20) SHA1(513a92554d14a09d6b80ba8017d161c7cda9ed8c) ) - ROM_LOAD_NIB_HIGH( "316-0028.u77", 0x0400, 0x0400, CRC(597ae441) SHA1(8d3af5e64e838a57057d46f97a7b1c1037c1a0cf) ) // dp07 - ROM_LOAD_NIB_LOW ( "dp05", 0x0800, 0x0400, CRC(1c0530cf) SHA1(b1f2b1038ee063533669341f1a71755eecc2e1a9) ) - ROM_LOAD_NIB_HIGH( "316-0023.u52", 0x0800, 0x0400, CRC(9244b613) SHA1(6587035ec22d90194cdc3efaed3571a1ab975e1c) ) // dp02 - ROM_LOAD_NIB_LOW ( "dp11", 0x0c00, 0x0400, CRC(0007044a) SHA1(c8d7c693e3059ff020563336fe712c234e94b8f9) ) - ROM_LOAD_NIB_HIGH( "dp08", 0x0c00, 0x0400, CRC(4d4e3ec8) SHA1(a0d5392fe5795cc6bf7373f194186506283c947c) ) - ROM_LOAD_NIB_LOW ( "dp06", 0x1000, 0x0400, CRC(63e1184b) SHA1(91934cb041365dabdc58a831312577fdb0dc923b) ) - ROM_LOAD_NIB_HIGH( "dp03", 0x1000, 0x0400, CRC(d70dbfd8) SHA1(0183a6b1ffd87a9e28588a7a9aa18aeb003560f0) ) - ROM_LOAD_NIB_LOW ( "dp12", 0x1400, 0x0400, CRC(170d7718) SHA1(4348e4e2dbb1edd9a4228fd3ccef58c50f1ae129) ) - ROM_LOAD_NIB_HIGH( "dp09", 0x1400, 0x0400, CRC(97466803) SHA1(f04ba4a1a960836974a85832596fc3a92a711094) ) + ROM_LOAD_NIB_LOW ( "dp04.u63", 0x0000, 0x0400, CRC(0ace1aef) SHA1(071256dd63e2e449093a65a4c9b006be5e17b786) ) + ROM_LOAD_NIB_HIGH( "dp01.u51", 0x0000, 0x0400, CRC(da9e835b) SHA1(505c969b479aeab11bb6a21ef06837280846d90a) ) + ROM_LOAD_NIB_LOW ( "dp10.u89", 0x0400, 0x0400, CRC(de752f20) SHA1(513a92554d14a09d6b80ba8017d161c7cda9ed8c) ) + ROM_LOAD_NIB_HIGH( "316-0028.u77", 0x0400, 0x0400, CRC(597ae441) SHA1(8d3af5e64e838a57057d46f97a7b1c1037c1a0cf) ) // dp07.u77 + ROM_LOAD_NIB_LOW ( "dp05.u64", 0x0800, 0x0400, CRC(1c0530cf) SHA1(b1f2b1038ee063533669341f1a71755eecc2e1a9) ) + ROM_LOAD_NIB_HIGH( "316-0023.u52", 0x0800, 0x0400, CRC(9244b613) SHA1(6587035ec22d90194cdc3efaed3571a1ab975e1c) ) // dp02.u52 + ROM_LOAD_NIB_LOW ( "dp11.u90", 0x0c00, 0x0400, CRC(0007044a) SHA1(c8d7c693e3059ff020563336fe712c234e94b8f9) ) + ROM_LOAD_NIB_HIGH( "dp08.u78", 0x0c00, 0x0400, CRC(4d4e3ec8) SHA1(a0d5392fe5795cc6bf7373f194186506283c947c) ) + ROM_LOAD_NIB_LOW ( "dp06.u65", 0x1000, 0x0400, CRC(63e1184b) SHA1(91934cb041365dabdc58a831312577fdb0dc923b) ) + ROM_LOAD_NIB_HIGH( "dp03.u53", 0x1000, 0x0400, CRC(d70dbfd8) SHA1(0183a6b1ffd87a9e28588a7a9aa18aeb003560f0) ) + ROM_LOAD_NIB_LOW ( "dp12.u91", 0x1400, 0x0400, CRC(170d7718) SHA1(4348e4e2dbb1edd9a4228fd3ccef58c50f1ae129) ) + ROM_LOAD_NIB_HIGH( "dp09.u79", 0x1400, 0x0400, CRC(97466803) SHA1(f04ba4a1a960836974a85832596fc3a92a711094) ) ROM_REGION( 0x0040, "user1", 0 ) - ROM_LOAD( "316-0013.u27", 0x0000, 0x0020, CRC(690ef530) SHA1(6c0de3fa87a341cd378fefb8e06bf7918db9a074) ) /* control PROM */ - ROM_LOAD( "316-0014.u28", 0x0020, 0x0020, CRC(7b7a8492) SHA1(6ba8d891cc6eb0dd80051377b6b832e8894655e7) ) /* sequence PROM */ + ROM_LOAD( "316-0013.u27", 0x0000, 0x0020, CRC(690ef530) SHA1(6c0de3fa87a341cd378fefb8e06bf7918db9a074) ) /* dp13.u27 - control PROM */ + ROM_LOAD( "316-0014.u28", 0x0020, 0x0020, CRC(7b7a8492) SHA1(6ba8d891cc6eb0dd80051377b6b832e8894655e7) ) /* dp14.u28 - sequence PROM */ ROM_END diff --git a/src/mame/drivers/zorba.cpp b/src/mame/drivers/zorba.cpp index cc1faf0c449..e348c55db0d 100644 --- a/src/mame/drivers/zorba.cpp +++ b/src/mame/drivers/zorba.cpp @@ -1,5 +1,5 @@ // license:BSD-3-Clause -// copyright-holders:Robbbert +// copyright-holders:Robbbert, Vas Crabb /************************************************************************************************************ Telcon Industries/Modular Micros/Gemini Electronics Zorba @@ -36,6 +36,10 @@ The startup screen varies across each company: - Modular Micros: "ZORBA" graphical logo with "MODULAR MICROS, INC." below in normal text - Gemini: "GEMINI ZORBA" graphical logo +Strangely, the Zorba configures its keyboard UART for 8N2 but the keyboard we're emulating sends 8N1. +If you type too fast or hold down a key until it repeats, characters will be dropped/corrupted. It's +possible we have a dump of a different CP/M-compatible keyboard, not the one supplied with the Zorba. + Status: - Boots up, and the keyboard works @@ -44,8 +48,6 @@ ToDo: - Add masking feature (only used for the UARTs) - Connect devices to the above hardware - Fix the display -- Connect the PIT to the UARTs -- Replace the ascii keyboard with the real one, if possible - Dump Telcon and Gemini BIOSes - Emulate the Co-Power-88 expansion (allows PC-DOS, CP/M-86, etc. to be used) - Probably lots of other things @@ -53,105 +55,44 @@ ToDo: *************************************************************************************************************/ - #include "emu.h" +#include "includes/zorba.h" + +#include "machine/zorbakbd.h" + +#include "bus/centronics/ctronics.h" +#include "bus/rs232/rs232.h" + #include "cpu/z80/z80.h" #include "cpu/m6805/m68705.h" -#include "machine/i8251.h" -#include "machine/6821pia.h" -#include "machine/z80dma.h" + +#include "machine/input_merger.h" +#include "machine/latch.h" #include "machine/pit8253.h" -#include "video/i8275.h" -#include "sound/beep.h" -#include "machine/keyboard.h" -#include "machine/wd_fdc.h" + #include "softlist.h" -class zorba_state : public driver_device -{ -public: - zorba_state(const machine_config &mconfig, device_type type, const char *tag) - : driver_device(mconfig, type, tag) - , m_palette(*this, "palette") - , m_maincpu(*this, "maincpu") - , m_beep(*this, "beeper") - , m_dma(*this, "dma") - , m_u0(*this, "uart0") - , m_u1(*this, "uart1") - , m_u2(*this, "uart2") - , m_pia0(*this, "pia0") - , m_pia1(*this, "pia1") - , m_crtc(*this, "crtc") - , m_fdc (*this, "fdc") - , m_floppy0(*this, "fdc:0") - , m_floppy1(*this, "fdc:1") - {} - -public: - const uint8_t *m_p_chargen; - DECLARE_DRIVER_INIT(zorba); - DECLARE_MACHINE_RESET(zorba); - DECLARE_READ8_MEMBER(ram_r); - DECLARE_WRITE8_MEMBER(ram_w); - DECLARE_READ8_MEMBER(rom_r); - DECLARE_WRITE8_MEMBER(rom_w); - DECLARE_WRITE8_MEMBER(intmask_w); - DECLARE_WRITE_LINE_MEMBER(busreq_w); - DECLARE_READ8_MEMBER(memory_read_byte); - DECLARE_WRITE8_MEMBER(memory_write_byte); - DECLARE_READ8_MEMBER(io_read_byte); - DECLARE_WRITE8_MEMBER(io_write_byte); - DECLARE_WRITE8_MEMBER(pia0_porta_w); - DECLARE_WRITE8_MEMBER(kbd_put); - DECLARE_READ8_MEMBER(keyboard_r); - DECLARE_WRITE_LINE_MEMBER(irq0_w); - DECLARE_WRITE_LINE_MEMBER(fdc_drq_w); - DECLARE_WRITE_LINE_MEMBER(fdc_intrq_w); - I8275_DRAW_CHARACTER_MEMBER(zorba_update_chr); - required_device<palette_device> m_palette; - -private: - uint8_t m_term_data; - uint8_t m_fdc_rq; - required_device<cpu_device> m_maincpu; - required_device<beep_device> m_beep; - required_device<z80dma_device> m_dma; - required_device<i8251_device> m_u0; - required_device<i8251_device> m_u1; - required_device<i8251_device> m_u2; - required_device<pia6821_device> m_pia0; - required_device<pia6821_device> m_pia1; - required_device<i8275_device> m_crtc; - required_device<fd1793_t> m_fdc; - required_device<floppy_connector> m_floppy0; - required_device<floppy_connector> m_floppy1; -}; +namespace { -static ADDRESS_MAP_START( zorba_mem, AS_PROGRAM, 8, zorba_state ) +ADDRESS_MAP_START( zorba_mem, AS_PROGRAM, 8, zorba_state ) AM_RANGE( 0x0000, 0x3fff ) AM_READ_BANK("bankr0") AM_WRITE_BANK("bankw0") AM_RANGE( 0x4000, 0xffff ) AM_RAM ADDRESS_MAP_END -static ADDRESS_MAP_START( zorba_kbdmem, AS_PROGRAM, 8, zorba_state ) - ADDRESS_MAP_GLOBAL_MASK(0x7ff) - AM_RANGE( 0x000, 0x07f ) AM_RAM // internal RAM - AM_RANGE( 0x080, 0x7ff ) AM_ROM // internal EPROM -ADDRESS_MAP_END -static ADDRESS_MAP_START( zorba_io, AS_IO, 8, zorba_state ) +ADDRESS_MAP_START( zorba_io, AS_IO, 8, zorba_state ) ADDRESS_MAP_GLOBAL_MASK(0xff) AM_RANGE(0x00, 0x03) AM_DEVREADWRITE("pit", pit8254_device, read, write) - AM_RANGE(0x04, 0x04) AM_READWRITE(rom_r,rom_w) - AM_RANGE(0x05, 0x05) AM_READWRITE(ram_r,ram_w) + AM_RANGE(0x04, 0x04) AM_READWRITE(rom_r, rom_w) + AM_RANGE(0x05, 0x05) AM_READWRITE(ram_r, ram_w) AM_RANGE(0x10, 0x11) AM_DEVREADWRITE("crtc", i8275_device, read, write) AM_RANGE(0x20, 0x20) AM_DEVREADWRITE("uart0", i8251_device, data_r, data_w) AM_RANGE(0x21, 0x21) AM_DEVREADWRITE("uart0", i8251_device, status_r, control_w) AM_RANGE(0x22, 0x22) AM_DEVREADWRITE("uart1", i8251_device, data_r, data_w) AM_RANGE(0x23, 0x23) AM_DEVREADWRITE("uart1", i8251_device, status_r, control_w) - //AM_RANGE(0x24, 0x24) AM_DEVREADWRITE("uart2", i8251_device, data_r, data_w) - //AM_RANGE(0x25, 0x25) AM_DEVREADWRITE("uart2", i8251_device, status_r, control_w) - AM_RANGE(0x24, 0x25) AM_READ(keyboard_r) AM_WRITENOP + AM_RANGE(0x24, 0x24) AM_DEVREADWRITE("uart2", i8251_device, data_r, data_w) + AM_RANGE(0x25, 0x25) AM_DEVREADWRITE("uart2", i8251_device, status_r, control_w) AM_RANGE(0x26, 0x26) AM_WRITE(intmask_w) AM_RANGE(0x30, 0x30) AM_DEVREADWRITE("dma", z80dma_device, read, write) AM_RANGE(0x40, 0x43) AM_DEVREADWRITE("fdc", fd1793_t, read, write) @@ -159,83 +100,294 @@ static ADDRESS_MAP_START( zorba_io, AS_IO, 8, zorba_state ) AM_RANGE(0x60, 0x63) AM_DEVREADWRITE("pia1", pia6821_device, read, write) ADDRESS_MAP_END + +INPUT_PORTS_START( zorba ) + PORT_START("CNF") + PORT_CONFNAME(0x01, 0x00, "Parallel Printer") PORT_CHANGED_MEMBER(DEVICE_SELF, zorba_state, printer_type, 0) + PORT_CONFSETTING(0x00, "Centronics") + PORT_CONFSETTING(0x01, "Prowriter") +INPUT_PORTS_END + + +SLOT_INTERFACE_START( zorba_floppies ) + SLOT_INTERFACE( "525dd", FLOPPY_525_DD ) +SLOT_INTERFACE_END + + +// F4 Character Displayer +const gfx_layout u5_charlayout = +{ + 8, 11, // 8 x 11 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, 1*8, 2*8, 3*8, 4*8, 5*8, 6*8, 7*8, 8*8, 9*8, 10*8 }, + 8*16 // every char takes 16 bytes +}; + +GFXDECODE_START( zorba ) + GFXDECODE_ENTRY( "chargen", 0x0000, u5_charlayout, 0, 1 ) +GFXDECODE_END + + +MACHINE_CONFIG_START( zorba, zorba_state ) + // basic machine hardware + MCFG_CPU_ADD("maincpu", Z80, XTAL_24MHz / 6) + MCFG_CPU_PROGRAM_MAP(zorba_mem) + MCFG_CPU_IO_MAP(zorba_io) + MCFG_MACHINE_RESET_OVERRIDE(zorba_state, zorba) + + /* video hardware */ + MCFG_SCREEN_ADD_MONOCHROME("screen", RASTER, rgb_t::green()) + MCFG_SCREEN_REFRESH_RATE(50) + MCFG_SCREEN_UPDATE_DEVICE("crtc", i8275_device, screen_update) + MCFG_GFXDECODE_ADD("gfxdecode", "palette", zorba) + MCFG_PALETTE_ADD_MONOCHROME_HIGHLIGHT("palette") + + /* sound hardware */ + MCFG_SPEAKER_STANDARD_MONO("mono") + MCFG_SOUND_ADD("beeper", BEEP, 800) // should be horizontal frequency / 16, so depends on CRTC parameters + MCFG_SOUND_ROUTE(ALL_OUTPUTS, "mono", 1.00) + + MCFG_INPUT_MERGER_ACTIVE_HIGH("irq0") + MCFG_INPUT_MERGER_OUTPUT_HANDLER(WRITELINE(zorba_state, irq_w<0>)) + MCFG_INPUT_MERGER_ACTIVE_HIGH("irq1") + MCFG_INPUT_MERGER_OUTPUT_HANDLER(WRITELINE(zorba_state, irq_w<1>)) + MCFG_INPUT_MERGER_ACTIVE_HIGH("irq2") + MCFG_INPUT_MERGER_OUTPUT_HANDLER(WRITELINE(zorba_state, irq_w<2>)) + + /* devices */ + MCFG_DEVICE_ADD("dma", Z80DMA, XTAL_24MHz/6) + // busack on cpu connects to bai pin + MCFG_Z80DMA_OUT_BUSREQ_CB(WRITELINE(zorba_state, busreq_w)) //connects to busreq on cpu + MCFG_Z80DMA_OUT_INT_CB(DEVWRITELINE("irq0", input_merger_active_high_device, in0_w)) + //ba0 - not connected + MCFG_Z80DMA_IN_MREQ_CB(READ8(zorba_state, memory_read_byte)) + MCFG_Z80DMA_OUT_MREQ_CB(WRITE8(zorba_state, memory_write_byte)) + MCFG_Z80DMA_IN_IORQ_CB(READ8(zorba_state, io_read_byte)) + MCFG_Z80DMA_OUT_IORQ_CB(WRITE8(zorba_state, io_write_byte)) + + MCFG_DEVICE_ADD("uart0", I8251, 0) // U32 COM port J2 + MCFG_I8251_TXD_HANDLER(DEVWRITELINE("rs232", rs232_port_device, write_txd)) // TODO: this line has a LED attached + MCFG_I8251_DTR_HANDLER(DEVWRITELINE("rs232", rs232_port_device, write_dtr)) + MCFG_I8251_RTS_HANDLER(DEVWRITELINE("rs232", rs232_port_device, write_rts)) + MCFG_I8251_RXRDY_HANDLER(WRITELINE(zorba_state, tx_rx_rdy_w<1>)) + MCFG_I8251_TXRDY_HANDLER(WRITELINE(zorba_state, tx_rx_rdy_w<0>)) + + MCFG_DEVICE_ADD("uart1", I8251, 0) // U31 printer port J3 + MCFG_I8251_TXD_HANDLER(DEVWRITELINE("serprn", rs232_port_device, write_txd)) + MCFG_I8251_RTS_HANDLER(DEVWRITELINE("serprn", rs232_port_device, write_rts)) + MCFG_I8251_RXRDY_HANDLER(WRITELINE(zorba_state, tx_rx_rdy_w<3>)) + MCFG_I8251_TXRDY_HANDLER(WRITELINE(zorba_state, tx_rx_rdy_w<2>)) + + MCFG_DEVICE_ADD("uart2", I8251, 0) // U30 serial keyboard J6 + MCFG_I8251_TXD_HANDLER(DEVWRITELINE("keyboard", zorba_keyboard_device, txd_w)) + MCFG_I8251_RXRDY_HANDLER(WRITELINE(zorba_state, tx_rx_rdy_w<5>)) + MCFG_I8251_TXRDY_HANDLER(WRITELINE(zorba_state, tx_rx_rdy_w<4>)) + + // port A - disk select etc, beeper + // port B - parallel interface + MCFG_DEVICE_ADD("pia0", PIA6821, 0) + MCFG_PIA_WRITEPA_HANDLER(WRITE8(zorba_state, pia0_porta_w)) + MCFG_PIA_WRITEPB_HANDLER(DEVWRITE8("parprndata", output_latch_device, write)) + MCFG_PIA_CB2_HANDLER(DEVWRITELINE("parprn", centronics_device, write_strobe)) + + // IEEE488 interface + MCFG_DEVICE_ADD("pia1", PIA6821, 0) + MCFG_PIA_READPA_HANDLER(DEVREAD8(IEEE488_TAG, ieee488_device, dio_r)) // TODO: gated with PB1 + MCFG_PIA_WRITEPA_HANDLER(DEVWRITE8(IEEE488_TAG, ieee488_device, dio_w)) // TODO: gated with PB1 + MCFG_PIA_READPB_HANDLER(READ8(zorba_state, pia1_portb_r)) + MCFG_PIA_WRITEPB_HANDLER(WRITE8(zorba_state, pia1_portb_w)) + MCFG_PIA_CA2_HANDLER(DEVWRITELINE(IEEE488_TAG, ieee488_device, ifc_w)) + MCFG_PIA_CB2_HANDLER(DEVWRITELINE(IEEE488_TAG, ieee488_device, ren_w)) + MCFG_PIA_IRQA_HANDLER(DEVWRITELINE("irq1", input_merger_active_high_device, in0_w)) + MCFG_PIA_IRQB_HANDLER(DEVWRITELINE("irq1", input_merger_active_high_device, in1_w)) + + // PIT + MCFG_DEVICE_ADD("pit", PIT8254, 0) + MCFG_PIT8253_CLK0(XTAL_24MHz / 3) + MCFG_PIT8253_CLK1(XTAL_24MHz / 3) + MCFG_PIT8253_CLK2(XTAL_24MHz / 3) + MCFG_PIT8253_OUT0_HANDLER(WRITELINE(zorba_state, br1_w)) + MCFG_PIT8253_OUT1_HANDLER(DEVWRITELINE("uart1", i8251_device, write_txc)) + MCFG_DEVCB_CHAIN_OUTPUT(DEVWRITELINE("uart1", i8251_device, write_rxc)) + MCFG_PIT8253_OUT2_HANDLER(DEVWRITELINE("uart2", i8251_device, write_txc)) + MCFG_DEVCB_CHAIN_OUTPUT(DEVWRITELINE("uart2", i8251_device, write_rxc)) + + // CRTC + MCFG_DEVICE_ADD("crtc", I8275, XTAL_14_31818MHz/7) + MCFG_I8275_CHARACTER_WIDTH(8) + MCFG_I8275_DRAW_CHARACTER_CALLBACK_OWNER(zorba_state, zorba_update_chr) + MCFG_I8275_DRQ_CALLBACK(DEVWRITELINE("dma", z80dma_device, rdy_w)) + MCFG_I8275_IRQ_CALLBACK(DEVWRITELINE("irq0", input_merger_active_high_device, in1_w)) + + // Floppies + MCFG_FD1793_ADD("fdc", XTAL_24MHz / 24) + MCFG_WD_FDC_INTRQ_CALLBACK(DEVWRITELINE("irq2", input_merger_active_high_device, in0_w)) + MCFG_WD_FDC_DRQ_CALLBACK(DEVWRITELINE("irq2", input_merger_active_high_device, in1_w)) + MCFG_FLOPPY_DRIVE_ADD("fdc:0", zorba_floppies, "525dd", floppy_image_device::default_floppy_formats) + MCFG_FLOPPY_DRIVE_SOUND(true) + MCFG_FLOPPY_DRIVE_ADD("fdc:1", zorba_floppies, "525dd", floppy_image_device::default_floppy_formats) + MCFG_FLOPPY_DRIVE_SOUND(true) + + // J1 IEEE-488 + MCFG_IEEE488_BUS_ADD() + MCFG_IEEE488_SRQ_CALLBACK(DEVWRITELINE("pia1", pia6821_device, ca2_w)) // TODO: gated with PB1 from PIA + + // J2 EIA RS232/internal modem + // TODO: this has additional lines compared to a regular RS232 port (TxC in, RxC in, RxC out, speaker in, power) + MCFG_RS232_PORT_ADD("rs232", default_rs232_devices, nullptr) + MCFG_RS232_RXD_HANDLER(DEVWRITELINE("uart0", i8251_device, write_rxd)) // TODO: this line has a LED attached + MCFG_RS232_CTS_HANDLER(DEVWRITELINE("uart0", i8251_device, write_cts)) // TODO: this line has a LED attached + MCFG_RS232_DSR_HANDLER(DEVWRITELINE("uart0", i8251_device, write_dsr)) + + // J3 Parallel printer + MCFG_CENTRONICS_OUTPUT_LATCH_ADD("parprndata", "parprn") + MCFG_CENTRONICS_ADD("parprn", centronics_devices, "printer") + MCFG_CENTRONICS_BUSY_HANDLER(DEVWRITELINE("uart1", i8251_device, write_cts)) + MCFG_DEVCB_CHAIN_OUTPUT(DEVWRITELINE("uart1", i8251_device, write_dsr)) // TODO: shared with serial CTS + MCFG_CENTRONICS_FAULT_HANDLER(WRITELINE(zorba_state, printer_fault_w)) + MCFG_CENTRONICS_SELECT_HANDLER(WRITELINE(zorba_state, printer_select_w)) + + // J3 Serial printer + MCFG_RS232_PORT_ADD("serprn", default_rs232_devices, nullptr) + MCFG_RS232_RXD_HANDLER(DEVWRITELINE("uart1", i8251_device, write_rxd)) // TODO: this line has a LED attached + + // J6 TTL-level serial keyboard + MCFG_DEVICE_ADD("keyboard", ZORBA_KEYBOARD, 0) + MCFG_ZORBA_KEYBOARD_RXD_CB(DEVWRITELINE("uart2", i8251_device, write_rxd)) + MCFG_QUANTUM_PERFECT_CPU("keyboard:mcu") + + MCFG_SOFTWARE_LIST_ADD("flop_list", "zorba") +MACHINE_CONFIG_END + +} // anonymous namespace + + +//------------------------------------------------- +// Initialise/reset +//------------------------------------------------- + +DRIVER_INIT_MEMBER( zorba_state, zorba ) +{ + uint8_t *main = memregion("maincpu")->base(); + + membank("bankr0")->configure_entry(0, &main[0x0000]); + membank("bankr0")->configure_entry(1, &main[0x10000]); + membank("bankw0")->configure_entry(0, &main[0x0000]); + + save_item(NAME(m_intmask)); + save_item(NAME(m_tx_rx_rdy)); + save_item(NAME(m_irq)); + + save_item(NAME(m_printer_prowriter)); + save_item(NAME(m_printer_fault)); + save_item(NAME(m_printer_select)); + + save_item(NAME(m_term_data)); + + m_printer_prowriter = false; + m_printer_fault = 0; + m_printer_select = 0; +} + +MACHINE_RESET_MEMBER( zorba_state, zorba ) +{ + m_uart2->write_cts(0); // always asserted + + m_intmask = 0x00; + m_tx_rx_rdy = 0x00; + m_irq = 0x00; + + m_printer_prowriter = BIT(m_config_port->read(), 0); + m_pia0->cb1_w(m_printer_prowriter ? m_printer_select : m_printer_fault); + + m_read_bank->set_entry(1); // point at rom + membank("bankw0")->set_entry(0); // always write to ram + + m_maincpu->reset(); +} + + +//------------------------------------------------- +// Memory banking control +//------------------------------------------------- + READ8_MEMBER( zorba_state::ram_r ) { - membank("bankr0")->set_entry(0); + if (!space.debugger_access()) + m_read_bank->set_entry(0); return 0; } WRITE8_MEMBER( zorba_state::ram_w ) { - membank("bankr0")->set_entry(0); + m_read_bank->set_entry(0); } READ8_MEMBER( zorba_state::rom_r ) { - membank("bankr0")->set_entry(1); + if (!space.debugger_access()) + m_read_bank->set_entry(1); return 0; } WRITE8_MEMBER( zorba_state::rom_w ) { - membank("bankr0")->set_entry(1); + m_read_bank->set_entry(1); } -WRITE_LINE_MEMBER( zorba_state::irq0_w ) -{ - if (state) - { - m_maincpu->set_input_line_vector(0, 0x88); - m_maincpu->set_input_line(0, ASSERT_LINE); - } - else - m_maincpu->set_input_line(0, CLEAR_LINE); -} -WRITE_LINE_MEMBER( zorba_state::fdc_intrq_w ) -{ - m_fdc_rq = (m_fdc_rq & 2) | state; - if (m_fdc_rq == 1) - { - m_maincpu->set_input_line_vector(0, 0x80); - m_maincpu->set_input_line(0, ASSERT_LINE); - } - else - if (m_fdc_rq == 0) - m_maincpu->set_input_line(0, CLEAR_LINE); -} +//------------------------------------------------- +// Interrupt vectoring glue +//------------------------------------------------- -WRITE_LINE_MEMBER( zorba_state::fdc_drq_w ) +WRITE8_MEMBER( zorba_state::intmask_w ) { - m_fdc_rq = (m_fdc_rq & 1) | (state << 1); - if (m_fdc_rq == 2) - { - m_maincpu->set_input_line_vector(0, 0x80); - m_maincpu->set_input_line(0, ASSERT_LINE); - } - else - if (m_fdc_rq == 0) - m_maincpu->set_input_line(0, CLEAR_LINE); + m_intmask = data & 0x3f; // only six lines physically present + irq_w<3>(BIT(m_intmask & m_tx_rx_rdy, 0) | BIT(m_intmask & m_tx_rx_rdy, 1)); + irq_w<4>(BIT(m_intmask & m_tx_rx_rdy, 2) | BIT(m_intmask & m_tx_rx_rdy, 3)); + irq_w<5>(BIT(m_intmask & m_tx_rx_rdy, 4) | BIT(m_intmask & m_tx_rx_rdy, 5)); } -WRITE8_MEMBER( zorba_state::intmask_w ) +template <unsigned N> WRITE_LINE_MEMBER( zorba_state::tx_rx_rdy_w ) { + m_tx_rx_rdy = (m_tx_rx_rdy & ~(1 << N)) | ((state ? 1 : 0) << N); + irq_w<(N >> 1) + 3>(BIT(m_intmask & m_tx_rx_rdy, N & ~1) | BIT(m_intmask & m_tx_rx_rdy, N | 1)); } -static INPUT_PORTS_START( zorba ) -INPUT_PORTS_END - -DRIVER_INIT_MEMBER( zorba_state, zorba ) +template <unsigned N> WRITE_LINE_MEMBER( zorba_state::irq_w ) { - uint8_t *main = memregion("maincpu")->base(); - - membank("bankr0")->configure_entry(0, &main[0x0000]); - membank("bankr0")->configure_entry(1, &main[0x10000]); - membank("bankw0")->configure_entry(0, &main[0x0000]); + m_irq = (m_irq & ~(1 << N)) | ((state ? 1 : 0) << N); + + // TODO: get a good dump of the interrupt vector PROM and get rid of this hack + // There are six interrupt sources: + // * IRQ0: DMAC/CRTC shared + // * IRQ1: IEEE488 (PIA IRQA/IRQB shared) + // * IRQ2: FDC INTRQ/DRQ shared + // * IRQ3: RS232 TXRDY/RXRDY selectable + // * IRQ4: Serial printer TXRDY/RXRDY selectable + // * IRQ5: Keyboard TXRDY/RXRDY selectable + // Valid vectors are 0x80, 0x84, 0x88, 0x8c, 0x90 and 0x94 + // Floppy needs to be on 0x80, and RS232 is apparently on 0x88 + // Everything else, including priority, is a complete guess + u8 vector; + if (BIT(m_irq, 2)) vector = 0x80; + else if (BIT(m_irq, 3)) vector = 0x88; + else vector = 0x84; // very wrong, need test cases for other things + + m_maincpu->set_input_line_and_vector( + INPUT_LINE_IRQ0, + m_irq ? ASSERT_LINE : CLEAR_LINE, + vector); } + //------------------------------------------------- -// Z80DMA +// DMA controller handlers //------------------------------------------------- WRITE_LINE_MEMBER( zorba_state::busreq_w ) @@ -268,19 +420,28 @@ WRITE8_MEMBER(zorba_state::io_write_byte) address_space& prog_space = m_maincpu->space(AS_IO); if (offset == 0x10) - { m_crtc->dack_w(space, 0, data); - } else - { prog_space.write_byte(offset, data); - } } -static SLOT_INTERFACE_START( zorba_floppies ) - SLOT_INTERFACE( "525dd", FLOPPY_525_DD ) -SLOT_INTERFACE_END +//------------------------------------------------- +// PIT handlers +//------------------------------------------------- + +WRITE_LINE_MEMBER( zorba_state::br1_w ) +{ + // TODO: these can be jumpered to inputs from J2 so a modem can generate Baud rates + // TODO: receive clock is exposed on J2 for external devices without Baud rate generators + m_uart0->write_txc(state); + m_uart0->write_rxc(state); +} + + +//------------------------------------------------- +// PIA handlers +//------------------------------------------------- WRITE8_MEMBER( zorba_state::pia0_porta_w ) { @@ -300,6 +461,50 @@ WRITE8_MEMBER( zorba_state::pia0_porta_w ) m_floppy1->get_device()->mon_w(BIT(data, 4)); } +READ8_MEMBER( zorba_state::pia1_portb_r ) +{ + // 0 (output only) + // 1 (output only) + // 2 (output only) + // 3 EOI gated with PB2 (active high) + // 4 (output only) + // 5 DAV gated with PB2 (active high) + // 6 NDAC gated with PB1 (active high) + // 7 NRFD gated with PB1 (active high) + + const uint8_t outputs(m_pia0->b_output()); + return + (m_ieee->eoi_r() << 3) | + (m_ieee->dav_r() << 5) | + (m_ieee->ndac_r() << 6) | + (m_ieee->nrfd_r() << 7) | + (BIT(outputs, 1) ? 0x00 : 0xc0) | + (BIT(outputs, 2) ? 0x00 : 0x28); +} + +WRITE8_MEMBER( zorba_state::pia1_portb_w ) +{ + // 0 DIO direction + // 1 NDAC/NRFD data direction, SRQ gate + // 2 EOI/DAV data direction + // 3 EOI gated with PB2 (active low) + // 4 ATN + // 5 DAV gated with PB2 (active low) + // 6 NDAC gated with PB1 (active low) + // 7 NRFD gated with PB1 (active low) + + m_ieee->eoi_w(BIT(data, 3) & BIT(~data, 2)); + m_ieee->atn_w(BIT(data, 4)); + m_ieee->dav_w(BIT(data, 5) & BIT(~data, 2)); + m_ieee->ndac_w(BIT(data, 6) & BIT(~data, 1)); + m_ieee->nrfd_w(BIT(data, 7) & BIT(~data, 1)); +} + + +//------------------------------------------------- +// Video +//------------------------------------------------- + I8275_DRAW_CHARACTER_MEMBER( zorba_state::zorba_update_chr ) { int i; @@ -321,138 +526,47 @@ I8275_DRAW_CHARACTER_MEMBER( zorba_state::zorba_update_chr ) } -/* F4 Character Displayer */ -static const gfx_layout u5_charlayout = -{ - 8, 11, /* 8 x 11 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, 1*8, 2*8, 3*8, 4*8, 5*8, 6*8, 7*8, 8*8, 9*8, 10*8 }, - 8*16 /* every char takes 16 bytes */ -}; - -static GFXDECODE_START( zorba ) - GFXDECODE_ENTRY( "chargen", 0x0000, u5_charlayout, 0, 1 ) -GFXDECODE_END +//------------------------------------------------- +// Printer port glue +//------------------------------------------------- -MACHINE_RESET_MEMBER( zorba_state, zorba ) +WRITE_LINE_MEMBER( zorba_state::printer_fault_w ) { - m_fdc_rq = 0; - m_p_chargen = memregion("chargen")->base(); - membank("bankr0")->set_entry(1); // point at rom - membank("bankw0")->set_entry(0); // always write to ram - m_maincpu->reset(); + // connects to CB1 for Centronics + m_printer_fault = state; + if (!m_printer_prowriter) + m_pia0->cb1_w(state); } -READ8_MEMBER( zorba_state::keyboard_r ) +WRITE_LINE_MEMBER( zorba_state::printer_select_w ) { - if (offset) - return (m_term_data) ? 0x87 : 0x85; - - uint8_t data = m_term_data; - m_term_data = 0; - return data; + // connects to CB1 for Prowriter + m_printer_select = state; + if (m_printer_prowriter) + m_pia0->cb1_w(state); } -WRITE8_MEMBER( zorba_state::kbd_put ) +INPUT_CHANGED_MEMBER( zorba_state::printer_type ) { - m_term_data = data; + m_printer_prowriter = newval; + m_pia0->cb1_w(m_printer_prowriter ? m_printer_select : m_printer_fault); } -static MACHINE_CONFIG_START( zorba, zorba_state ) - // basic machine hardware - MCFG_CPU_ADD("maincpu", Z80, XTAL_24MHz / 6) - MCFG_CPU_PROGRAM_MAP(zorba_mem) - MCFG_CPU_IO_MAP(zorba_io) - MCFG_MACHINE_RESET_OVERRIDE(zorba_state, zorba) - - /* keyboard */ - MCFG_CPU_ADD("kbdcpu", M68705, XTAL_3_579545MHz) // MC68705P3S (0x80 bytes ram, 0x780 bytes of rom) - MCFG_CPU_PROGRAM_MAP(zorba_kbdmem) - - /* video hardware */ - MCFG_SCREEN_ADD_MONOCHROME("screen", RASTER, rgb_t::green()) - MCFG_SCREEN_REFRESH_RATE(50) - MCFG_SCREEN_UPDATE_DEVICE("crtc", i8275_device, screen_update) - MCFG_GFXDECODE_ADD("gfxdecode", "palette", zorba) - MCFG_PALETTE_ADD_MONOCHROME_HIGHLIGHT("palette") - - /* sound hardware */ - MCFG_SPEAKER_STANDARD_MONO("mono") - MCFG_SOUND_ADD("beeper", BEEP, 800) - MCFG_SOUND_ROUTE(ALL_OUTPUTS, "mono", 1.00) - - /* devices */ - MCFG_DEVICE_ADD("dma", Z80DMA, XTAL_24MHz/6) - // busack on cpu connects to bai pin - MCFG_Z80DMA_OUT_BUSREQ_CB(WRITELINE(zorba_state, busreq_w)) //connects to busreq on cpu - MCFG_Z80DMA_OUT_INT_CB(WRITELINE(zorba_state, irq0_w)) // connects to IRQ0 on IM2 controller - //ba0 - not connected - MCFG_Z80DMA_IN_MREQ_CB(READ8(zorba_state, memory_read_byte)) - MCFG_Z80DMA_OUT_MREQ_CB(WRITE8(zorba_state, memory_write_byte)) - MCFG_Z80DMA_IN_IORQ_CB(READ8(zorba_state, io_read_byte)) - MCFG_Z80DMA_OUT_IORQ_CB(WRITE8(zorba_state, io_write_byte)) - - MCFG_DEVICE_ADD("uart0", I8251, 0) // U32 COM port J2 - - MCFG_DEVICE_ADD("uart1", I8251, 0) // U31 printer port J3 - - MCFG_DEVICE_ADD("uart2", I8251, 0) // U30 serial keyboard J6 - - // port A - disk select etc, beeper - // port B - parallel interface - MCFG_DEVICE_ADD("pia0", PIA6821, 0) - MCFG_PIA_WRITEPA_HANDLER(WRITE8(zorba_state, pia0_porta_w)) - - // IEEE488 interface - MCFG_DEVICE_ADD("pia1", PIA6821, 0) - - MCFG_DEVICE_ADD("pit", PIT8254, 0) - MCFG_PIT8253_CLK0(XTAL_24MHz / 3) /* Timer 0: clock to J2 comm port */ - MCFG_PIT8253_CLK1(XTAL_24MHz / 3) /* Timer 1: clock to U31 */ - MCFG_PIT8253_CLK2(XTAL_24MHz / 3) /* Timer 2: clock to U30 */ - - MCFG_DEVICE_ADD("crtc", I8275, XTAL_14_31818MHz/7) - MCFG_I8275_CHARACTER_WIDTH(8) - MCFG_I8275_DRAW_CHARACTER_CALLBACK_OWNER(zorba_state, zorba_update_chr) - MCFG_I8275_DRQ_CALLBACK(DEVWRITELINE("dma", z80dma_device, rdy_w)) - MCFG_I8275_IRQ_CALLBACK(WRITELINE(zorba_state, irq0_w)) - MCFG_FD1793_ADD("fdc", XTAL_24MHz / 24) - MCFG_WD_FDC_INTRQ_CALLBACK(WRITELINE(zorba_state, fdc_intrq_w)) - MCFG_WD_FDC_DRQ_CALLBACK(WRITELINE(zorba_state, fdc_drq_w)) - MCFG_FLOPPY_DRIVE_ADD("fdc:0", zorba_floppies, "525dd", floppy_image_device::default_floppy_formats) - MCFG_FLOPPY_DRIVE_SOUND(true) - MCFG_FLOPPY_DRIVE_ADD("fdc:1", zorba_floppies, "525dd", floppy_image_device::default_floppy_formats) - MCFG_FLOPPY_DRIVE_SOUND(true) - - /* Keyboard */ - MCFG_DEVICE_ADD("keyboard", GENERIC_KEYBOARD, 0) - MCFG_GENERIC_KEYBOARD_CB(WRITE8(zorba_state, kbd_put)) - - MCFG_SOFTWARE_LIST_ADD("flop_list", "zorba") -MACHINE_CONFIG_END ROM_START( zorba ) ROM_REGION( 0x14000, "maincpu", ROMREGION_ERASEFF ) ROM_LOAD( "780000.u47", 0x10000, 0x1000, CRC(6d58f2c5) SHA1(7763f08c801cd36e5a761c6dc9f30a50b3bc482d) ) - ROM_REGION( 0x800, "kbdcpu", 0 ) - ROM_LOAD( "8999-1 3-28-83", 0x080, 0x780, CRC(79fe6c0d) SHA1(4b6fca9379d5199d1347ad1187cbfdebfc4c73e7) ) - ROM_REGION( 0x1000, "chargen", 0 ) ROM_LOAD( "773000.u5", 0x0000, 0x1000, CRC(d0a2f8fc) SHA1(29aee7ee657778c46e9800abd4955e6d4b33ef68) ) ROM_REGION( 0x60, "proms", 0 ) - ROM_LOAD( "74ls288.u37", 0x0000, 0x0020, CRC(0a67edd6) SHA1(c1ece8978a3a061e0130d43907fa63a71e75e75d) ) - ROM_LOAD( "74ls288.u38", 0x0020, 0x0020, CRC(5ec93ea7) SHA1(3a84c098474b05d5cbe1939a3e15f66d06470581) ) - ROM_LOAD( "74ls288.u77", 0x0040, 0x0020, CRC(946e03b0) SHA1(24240bdd7bdf507a5b51628fb36ad1266fc53a28) ) // suspected bad dump + ROM_LOAD( "74ls288.u37", 0x0000, 0x0020, CRC(0a67edd6) SHA1(c1ece8978a3a061e0130d43907fa63a71e75e75d) BAD_DUMP ) // looks like interrupt vector PROM dumped with scrambled lines + ROM_LOAD( "74ls288.u38", 0x0020, 0x0020, CRC(5ec93ea7) SHA1(3a84c098474b05d5cbe1939a3e15f66d06470581) BAD_DUMP ) // looks like bad dump of address decode PROM + ROM_LOAD( "74ls288.u77", 0x0040, 0x0020, CRC(946e03b0) SHA1(24240bdd7bdf507a5b51628fb36ad1266fc53a28) BAD_DUMP ) // looks like bad dump of address decode PROM ROM_END -COMP( 1984?, zorba, 0, 0, zorba, zorba, zorba_state, zorba, "Modular Micros", "Zorba (Modular Micros)", MACHINE_NOT_WORKING ) +COMP( 1984?, zorba, 0, 0, zorba, zorba, zorba_state, zorba, "Modular Micros", "Zorba (Modular Micros)", MACHINE_NOT_WORKING | MACHINE_SUPPORTS_SAVE ) // Undumped versions (see startup screen notes at top of file) // COMP( 1983, zorbat, zorba, 0, zorba, zorba, zorba_state, zorba, "Telcon Industries", "Zorba (Telcon Industries)", MACHINE_NOT_WORKING ) diff --git a/src/mame/includes/cclimber.h b/src/mame/includes/cclimber.h index 30cf4b45d85..2b1ec8a32b6 100644 --- a/src/mame/includes/cclimber.h +++ b/src/mame/includes/cclimber.h @@ -63,6 +63,7 @@ public: DECLARE_READ8_MEMBER(yamato_p1_r); DECLARE_WRITE8_MEMBER(toprollr_rombank_w); DECLARE_WRITE8_MEMBER(nmi_mask_w); + DECLARE_READ8_MEMBER(bagmanf_a000_r); DECLARE_WRITE8_MEMBER(cclimber_colorram_w); DECLARE_WRITE8_MEMBER(cannonb_flip_screen_w); diff --git a/src/mame/includes/gladiatr.h b/src/mame/includes/gladiatr.h index 60166ed4b99..39c99eb8391 100644 --- a/src/mame/includes/gladiatr.h +++ b/src/mame/includes/gladiatr.h @@ -83,8 +83,6 @@ public: , m_in2(*this, "IN2") , m_coins(*this, "COINS") , m_tclk_val(false) - , m_in0_val(0xff) - , m_in1_val(0xff) , m_cctl_p1(0xff) , m_cctl_p2(0xff) , m_ucpu_p1(0xff) @@ -123,6 +121,11 @@ public: DECLARE_WRITE8_MEMBER(csnd_p1_w); DECLARE_READ8_MEMBER(csnd_p2_r); + DECLARE_INPUT_CHANGED_MEMBER(p1_s1); + DECLARE_INPUT_CHANGED_MEMBER(p1_s2); + DECLARE_INPUT_CHANGED_MEMBER(p2_s1); + DECLARE_INPUT_CHANGED_MEMBER(p2_s2); + DECLARE_DRIVER_INIT(gladiatr); DECLARE_MACHINE_RESET(gladiator); @@ -137,7 +140,6 @@ private: required_ioport m_coins; bool m_tclk_val; - u8 m_in0_val, m_in1_val; u8 m_cctl_p1, m_cctl_p2; u8 m_ucpu_p1, m_csnd_p1; diff --git a/src/mame/includes/novagbase.h b/src/mame/includes/novagbase.h index 102956fa22c..9c575c10bea 100644 --- a/src/mame/includes/novagbase.h +++ b/src/mame/includes/novagbase.h @@ -8,6 +8,7 @@ #include "emu.h" #include "sound/beep.h" +#include "video/hd44780.h" class novagbase_state : public driver_device { @@ -16,6 +17,7 @@ public: : driver_device(mconfig, type, tag), m_maincpu(*this, "maincpu"), m_beeper(*this, "beeper"), + m_lcd(*this, "hd44780"), m_inp_matrix(*this, "IN.%u", 0), m_display_wait(33), m_display_maxy(1), @@ -25,6 +27,7 @@ public: // devices/pointers required_device<cpu_device> m_maincpu; optional_device<beep_device> m_beeper; + optional_device<hd44780_device> m_lcd; optional_ioport_array<8> m_inp_matrix; // misc common @@ -51,6 +54,9 @@ public: void set_display_segmask(u32 digits, u32 mask); void display_matrix(int maxx, int maxy, u32 setx, u32 sety, bool update = true); + DECLARE_PALETTE_INIT(novag_lcd); + HD44780_PIXEL_UPDATE(novag_lcd_pixel_update); + protected: virtual void machine_start() override; virtual void machine_reset() override; diff --git a/src/mame/includes/osborne1.h b/src/mame/includes/osborne1.h index bbe12f9efcb..56754a43e82 100644 --- a/src/mame/includes/osborne1.h +++ b/src/mame/includes/osborne1.h @@ -81,6 +81,8 @@ public: DECLARE_WRITE_LINE_MEMBER(serial_acia_irq_func); + DECLARE_INPUT_CHANGED_MEMBER(reset_key); + DECLARE_DRIVER_INIT(osborne1); virtual void machine_reset() override; virtual void video_start() override; diff --git a/src/mame/includes/retofinv.h b/src/mame/includes/retofinv.h index 6ff49e40255..77405bec825 100644 --- a/src/mame/includes/retofinv.h +++ b/src/mame/includes/retofinv.h @@ -1,56 +1,28 @@ // license:BSD-3-Clause // copyright-holders:Jarek Parchanski, Andrea Mazzoleni +#include "machine/taito68705interface.h" + #include "machine/gen_latch.h" + class retofinv_state : public driver_device { public: retofinv_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_subcpu(*this, "sub"), - m_68705(*this, "68705"), - m_gfxdecode(*this, "gfxdecode"), - m_palette(*this, "palette"), - m_soundlatch(*this, "soundlatch"), - m_fg_videoram(*this, "fg_videoram"), - m_sharedram(*this, "sharedram"), - m_bg_videoram(*this, "bg_videoram") { } - - required_device<cpu_device> m_maincpu; - required_device<cpu_device> m_audiocpu; - required_device<cpu_device> m_subcpu; - optional_device<cpu_device> m_68705; - 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_fg_videoram; - required_shared_ptr<uint8_t> m_sharedram; - required_shared_ptr<uint8_t> m_bg_videoram; - - uint8_t m_main_irq_mask; - uint8_t m_sub_irq_mask; - uint8_t m_cpu2_m6000; - uint8_t m_from_main; - uint8_t m_from_mcu; - int m_mcu_sent; - int m_main_sent; - uint8_t m_portA_in; - uint8_t m_portA_out; - uint8_t m_ddrA; - uint8_t m_portB_in; - uint8_t m_portB_out; - uint8_t m_ddrB; - uint8_t m_portC_in; - uint8_t m_portC_out; - uint8_t m_ddrC; - int m_fg_bank; - int m_bg_bank; - tilemap_t *m_bg_tilemap; - tilemap_t *m_fg_tilemap; + : driver_device(mconfig, type, tag) + , m_maincpu(*this, "maincpu") + , m_audiocpu(*this, "audiocpu") + , m_subcpu(*this, "sub") + , m_68705(*this, "68705") + , m_gfxdecode(*this, "gfxdecode") + , m_palette(*this, "palette") + , m_soundlatch(*this, "soundlatch") + , m_fg_videoram(*this, "fg_videoram") + , m_sharedram(*this, "sharedram") + , m_bg_videoram(*this, "bg_videoram") + { + } DECLARE_WRITE8_MEMBER(cpu1_reset_w); DECLARE_WRITE8_MEMBER(cpu2_reset_w); @@ -62,17 +34,6 @@ public: DECLARE_WRITE8_MEMBER(irq1_ack_w); DECLARE_WRITE8_MEMBER(coincounter_w); DECLARE_WRITE8_MEMBER(coinlockout_w); - DECLARE_READ8_MEMBER(mcu_portA_r); - DECLARE_WRITE8_MEMBER(mcu_portA_w); - DECLARE_WRITE8_MEMBER(mcu_ddrA_w); - DECLARE_READ8_MEMBER(mcu_portB_r); - DECLARE_WRITE8_MEMBER(mcu_portB_w); - DECLARE_WRITE8_MEMBER(mcu_ddrB_w); - DECLARE_READ8_MEMBER(mcu_portC_r); - DECLARE_WRITE8_MEMBER(mcu_portC_w); - DECLARE_WRITE8_MEMBER(mcu_ddrC_w); - DECLARE_WRITE8_MEMBER(mcu_w); - DECLARE_READ8_MEMBER(mcu_r); DECLARE_READ8_MEMBER(mcu_status_r); DECLARE_WRITE8_MEMBER(bg_videoram_w); DECLARE_WRITE8_MEMBER(fg_videoram_w); @@ -82,13 +43,36 @@ public: TILE_GET_INFO_MEMBER(bg_get_tile_info); TILE_GET_INFO_MEMBER(fg_get_tile_info); - virtual void machine_start() override; - virtual void video_start() override; DECLARE_PALETTE_INIT(retofinv); uint32_t screen_update(screen_device &screen, bitmap_ind16 &bitmap, const rectangle &cliprect); - void draw_sprites(bitmap_ind16 &bitmap); INTERRUPT_GEN_MEMBER(main_vblank_irq); INTERRUPT_GEN_MEMBER(sub_vblank_irq); + +protected: + virtual void machine_start() override; + virtual void video_start() override; + + void draw_sprites(bitmap_ind16 &bitmap); + + required_device<cpu_device> m_maincpu; + required_device<cpu_device> m_audiocpu; + required_device<cpu_device> m_subcpu; + optional_device<taito68705_mcu_device> m_68705; + 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_fg_videoram; + required_shared_ptr<uint8_t> m_sharedram; + required_shared_ptr<uint8_t> m_bg_videoram; + + uint8_t m_main_irq_mask; + uint8_t m_sub_irq_mask; + uint8_t m_cpu2_m6000; + int m_fg_bank; + int m_bg_bank; + tilemap_t *m_bg_tilemap; + tilemap_t *m_fg_tilemap; }; diff --git a/src/mame/includes/stfight.h b/src/mame/includes/stfight.h index 145b9d54f4a..7197093f469 100644 --- a/src/mame/includes/stfight.h +++ b/src/mame/includes/stfight.h @@ -13,37 +13,26 @@ public: }; stfight_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_mcu(*this, "mcu"), - m_msm(*this, "msm"), - m_palette(*this, "palette"), - m_decrypted_opcodes(*this, "decrypted_opcodes"), - m_stfight_video(*this, "stfight_vid"), - m_airraid_video(*this, "airraid_vid") - { } - - required_device<cpu_device> m_maincpu; - required_device<cpu_device> m_audiocpu; - required_device<cpu_device> m_mcu; - required_device<msm5205_device> m_msm; - required_device<palette_device> m_palette; - - optional_shared_ptr<uint8_t> m_decrypted_opcodes; - optional_device<stfight_video_device> m_stfight_video; - optional_device<airraid_video_device> m_airraid_video; - - uint8_t *m_decrypt; - uint8_t m_fm_data; - uint8_t m_cpu_to_mcu_data; - uint8_t m_cpu_to_mcu_empty; - - uint16_t m_adpcm_data_offs; - uint8_t m_adpcm_nibble; - uint8_t m_adpcm_reset; - - uint8_t m_coin_state; + : driver_device(mconfig, type, tag) + , m_coin_mech(*this, "COIN") + , m_maincpu(*this, "maincpu") + , m_audiocpu(*this, "audiocpu") + , m_mcu(*this, "mcu") + , m_msm(*this, "msm") + , m_main_bank(*this, "mainbank") + , m_samples(*this, "adpcm") + , m_decrypted_opcodes(*this, "decrypted_opcodes") + , m_coin_state(0) + , m_fm_data(0) + , m_cpu_to_mcu_empty(true) + , m_cpu_to_mcu_data(0x0f) + , m_port_a_out(0xff) + , m_port_c_out(0xff) + , m_vck2(false) + , m_adpcm_reset(true) + , m_adpcm_data_offs(0x0000) + { + } DECLARE_WRITE_LINE_MEMBER(stfight_adpcm_int); @@ -59,13 +48,8 @@ public: DECLARE_WRITE8_MEMBER(stfight_bank_w); - DECLARE_READ8_MEMBER(stfight_fm_r); - - virtual void machine_start() override; - virtual void machine_reset() override; - INTERRUPT_GEN_MEMBER(stfight_vb_interrupt); // MCU specifics @@ -74,8 +58,34 @@ public: DECLARE_WRITE8_MEMBER(stfight_68705_port_b_w); DECLARE_WRITE8_MEMBER(stfight_68705_port_c_w); - uint8_t m_portC_out; - 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; + + required_ioport m_coin_mech; + + required_device<cpu_device> m_maincpu; + required_device<cpu_device> m_audiocpu; + required_device<cpu_device> m_mcu; + required_device<msm5205_device> m_msm; + + required_memory_bank m_main_bank; + + required_region_ptr<uint8_t> m_samples; + optional_shared_ptr<uint8_t> m_decrypted_opcodes; + + uint8_t m_coin_state; + + uint8_t m_fm_data; + + bool m_cpu_to_mcu_empty; + uint8_t m_cpu_to_mcu_data; + uint8_t m_port_a_out; + uint8_t m_port_c_out; + + bool m_vck2; + bool m_adpcm_reset; + uint16_t m_adpcm_data_offs; }; diff --git a/src/mame/includes/zorba.h b/src/mame/includes/zorba.h new file mode 100644 index 00000000000..9eae677473f --- /dev/null +++ b/src/mame/includes/zorba.h @@ -0,0 +1,113 @@ +// license:BSD-3-Clause +// copyright-holders:Robbbert, Vas Crabb + +#include "sound/beep.h" + +#include "bus/ieee488/ieee488.h" + +#include "machine/6821pia.h" +#include "machine/i8251.h" +#include "machine/wd_fdc.h" +#include "machine/z80dma.h" + +#include "video/i8275.h" + + +class zorba_state : public driver_device +{ +public: + zorba_state(const machine_config &mconfig, device_type type, const char *tag) + : driver_device(mconfig, type, tag) + , m_config_port(*this, "CNF") + , m_read_bank(*this, "bankr0") + , m_p_chargen(*this, "chargen") + , m_maincpu(*this, "maincpu") + , m_dma(*this, "dma") + , m_uart0(*this, "uart0") + , m_uart1(*this, "uart1") + , m_uart2(*this, "uart2") + , m_pia0(*this, "pia0") + , m_pia1(*this, "pia1") + , m_palette(*this, "palette") + , m_crtc(*this, "crtc") + , m_beep(*this, "beeper") + , m_fdc (*this, "fdc") + , m_floppy0(*this, "fdc:0") + , m_floppy1(*this, "fdc:1") + , m_ieee(*this, IEEE488_TAG) + { + } + +public: + DECLARE_DRIVER_INIT(zorba); + DECLARE_MACHINE_RESET(zorba); + + // Memory banking control + DECLARE_READ8_MEMBER(ram_r); + DECLARE_WRITE8_MEMBER(ram_w); + DECLARE_READ8_MEMBER(rom_r); + DECLARE_WRITE8_MEMBER(rom_w); + + // Interrupt vectoring glue + DECLARE_WRITE8_MEMBER(intmask_w); + template <unsigned N> DECLARE_WRITE_LINE_MEMBER(tx_rx_rdy_w); + template <unsigned N> DECLARE_WRITE_LINE_MEMBER(irq_w); + + // DMA controller handlers + DECLARE_WRITE_LINE_MEMBER(busreq_w); + DECLARE_READ8_MEMBER(memory_read_byte); + DECLARE_WRITE8_MEMBER(memory_write_byte); + DECLARE_READ8_MEMBER(io_read_byte); + DECLARE_WRITE8_MEMBER(io_write_byte); + + // PIT handlers + DECLARE_WRITE_LINE_MEMBER(br1_w); + + // PIA handlers + DECLARE_WRITE8_MEMBER(pia0_porta_w); + DECLARE_READ8_MEMBER(pia1_portb_r); + DECLARE_WRITE8_MEMBER(pia1_portb_w); + + // Video + I8275_DRAW_CHARACTER_MEMBER(zorba_update_chr); + + // Printer port glue + DECLARE_WRITE_LINE_MEMBER(printer_fault_w); + DECLARE_WRITE_LINE_MEMBER(printer_select_w); + DECLARE_INPUT_CHANGED_MEMBER(printer_type); + +private: + required_ioport m_config_port; + + required_memory_bank m_read_bank; + required_region_ptr<uint8_t> m_p_chargen; + + required_device<cpu_device> m_maincpu; + required_device<z80dma_device> m_dma; + required_device<i8251_device> m_uart0; + required_device<i8251_device> m_uart1; + required_device<i8251_device> m_uart2; + required_device<pia6821_device> m_pia0; + required_device<pia6821_device> m_pia1; + + required_device<palette_device> m_palette; + required_device<i8275_device> m_crtc; + + required_device<beep_device> m_beep; + + required_device<fd1793_t> m_fdc; + required_device<floppy_connector> m_floppy0; + required_device<floppy_connector> m_floppy1; + + required_device<ieee488_device> m_ieee; + + uint8_t m_intmask; + uint8_t m_tx_rx_rdy; + uint8_t m_irq; + + bool m_printer_prowriter; + int m_printer_fault; + int m_printer_select; + + uint8_t m_term_data; +}; diff --git a/src/mame/layout/einvader.lay b/src/mame/layout/einvader.lay index 81021899dbf..7f2d4f87dd0 100644 --- a/src/mame/layout/einvader.lay +++ b/src/mame/layout/einvader.lay @@ -4,82 +4,29 @@ <!-- define elements --> <element name="static_black"><rect><color red="0.0" green="0.0" blue="0.0" /></rect></element> + <element name="static_white"><rect><color red="0.8" green="0.8" blue="0.8" /></rect></element> + <element name="text_score"><text string="SCORE"><color red="0.8" green="0.8" blue="0.8" /></text></element> <element name="digit" defstate="0"> - <led7seg><color red="1.0" green="0.20" blue="0.22" /></led7seg> - </element> - <element name="led" defstate="0"> - <disk state="0"><color red="0.2" green="0.04" blue="0.05" /></disk> - <disk state="1"><color red="1.0" green="0.20" blue="0.22" /></disk> + <led7seg><color red="1.0" green="0.165" blue="0.165" /></led7seg> </element> <!-- build screen --> - <view name="Test Layout"> - <bounds left="0" right="12" top="0" bottom="28" /> - <bezel element="static_black"> - <bounds left="0" right="12" top="0" bottom="28" /> - </bezel> - - <bezel name="digit9" element="digit"><bounds x="0" y="0" width="4" height="6" /></bezel> - <bezel name="digit8" element="digit"><bounds x="4" y="0" width="4" height="6" /></bezel> - <bezel name="digit7" element="digit"><bounds x="8" y="0" width="4" height="6" /></bezel> - - <!-- led matrix --> - - <bezel name="lamp0" element="led"><bounds x="0" y="10" width="1" height="1" /></bezel> - <bezel name="lamp1" element="led"><bounds x="2" y="10" width="1" height="1" /></bezel> - <bezel name="lamp2" element="led"><bounds x="4" y="10" width="1" height="1" /></bezel> - <bezel name="lamp3" element="led"><bounds x="6" y="10" width="1" height="1" /></bezel> - <bezel name="lamp4" element="led"><bounds x="8" y="10" width="1" height="1" /></bezel> - <bezel name="lamp5" element="led"><bounds x="10" y="10" width="1" height="1" /></bezel> - - <bezel name="lamp10" element="led"><bounds x="0" y="12" width="1" height="1" /></bezel> - <bezel name="lamp11" element="led"><bounds x="2" y="12" width="1" height="1" /></bezel> - <bezel name="lamp12" element="led"><bounds x="4" y="12" width="1" height="1" /></bezel> - <bezel name="lamp13" element="led"><bounds x="6" y="12" width="1" height="1" /></bezel> - <bezel name="lamp14" element="led"><bounds x="8" y="12" width="1" height="1" /></bezel> - <bezel name="lamp15" element="led"><bounds x="10" y="12" width="1" height="1" /></bezel> - - <bezel name="lamp20" element="led"><bounds x="0" y="14" width="1" height="1" /></bezel> - <bezel name="lamp21" element="led"><bounds x="2" y="14" width="1" height="1" /></bezel> - <bezel name="lamp22" element="led"><bounds x="4" y="14" width="1" height="1" /></bezel> - <bezel name="lamp23" element="led"><bounds x="6" y="14" width="1" height="1" /></bezel> - <bezel name="lamp24" element="led"><bounds x="8" y="14" width="1" height="1" /></bezel> - <bezel name="lamp25" element="led"><bounds x="10" y="14" width="1" height="1" /></bezel> - - <bezel name="lamp30" element="led"><bounds x="0" y="16" width="1" height="1" /></bezel> - <bezel name="lamp31" element="led"><bounds x="2" y="16" width="1" height="1" /></bezel> - <bezel name="lamp32" element="led"><bounds x="4" y="16" width="1" height="1" /></bezel> - <bezel name="lamp33" element="led"><bounds x="6" y="16" width="1" height="1" /></bezel> - <bezel name="lamp34" element="led"><bounds x="8" y="16" width="1" height="1" /></bezel> - <bezel name="lamp35" element="led"><bounds x="10" y="16" width="1" height="1" /></bezel> - - <bezel name="lamp40" element="led"><bounds x="0" y="18" width="1" height="1" /></bezel> - <bezel name="lamp41" element="led"><bounds x="2" y="18" width="1" height="1" /></bezel> - <bezel name="lamp42" element="led"><bounds x="4" y="18" width="1" height="1" /></bezel> - <bezel name="lamp43" element="led"><bounds x="6" y="18" width="1" height="1" /></bezel> - <bezel name="lamp44" element="led"><bounds x="8" y="18" width="1" height="1" /></bezel> - <bezel name="lamp45" element="led"><bounds x="10" y="18" width="1" height="1" /></bezel> - - <bezel name="lamp50" element="led"><bounds x="0" y="20" width="1" height="1" /></bezel> - <bezel name="lamp51" element="led"><bounds x="2" y="20" width="1" height="1" /></bezel> - <bezel name="lamp52" element="led"><bounds x="4" y="20" width="1" height="1" /></bezel> - <bezel name="lamp53" element="led"><bounds x="6" y="20" width="1" height="1" /></bezel> - <bezel name="lamp54" element="led"><bounds x="8" y="20" width="1" height="1" /></bezel> - <bezel name="lamp55" element="led"><bounds x="10" y="20" width="1" height="1" /></bezel> - - <bezel name="lamp6" element="led"><bounds x="2" y="22" width="1" height="1" /></bezel> - <bezel name="lamp7" element="led"><bounds x="8" y="22" width="1" height="1" /></bezel> + <view name="Internal Layout"> + <bounds left="-0.1" right="20.1" top="4.6" bottom="33.1" /> + <screen index="0"> + <bounds x="0" y="10" width="20" height="23" /> + </screen> - <bezel name="lamp60" element="led"><bounds x="0" y="24" width="1" height="1" /></bezel> - <bezel name="lamp61" element="led"><bounds x="2" y="24" width="1" height="1" /></bezel> - <bezel name="lamp62" element="led"><bounds x="4" y="24" width="1" height="1" /></bezel> - <bezel name="lamp63" element="led"><bounds x="6" y="24" width="1" height="1" /></bezel> - <bezel name="lamp64" element="led"><bounds x="8" y="24" width="1" height="1" /></bezel> - <bezel name="lamp65" element="led"><bounds x="10" y="24" width="1" height="1" /></bezel> + <bezel element="static_white"><bounds x="6.6" y="4.59" width="6.8" height="3.81" /></bezel> + <bezel element="static_black"><bounds x="6.8" y="4.8" width="6.4" height="3.4" /></bezel> + <bezel element="text_score"><bounds x="2" y="5.75" width="4.6" height="1.5" /></bezel> + <bezel name="digit9" element="digit"><bounds x="7" y="5" width="2" height="3" /></bezel> + <bezel name="digit8" element="digit"><bounds x="9" y="5" width="2" height="3" /></bezel> + <bezel name="digit7" element="digit"><bounds x="11" y="5" width="2" height="3" /></bezel> </view> </mamelayout> diff --git a/src/mame/layout/einvaderc.lay b/src/mame/layout/einvaderc.lay index 0916b783796..3eb8570986e 100644 --- a/src/mame/layout/einvaderc.lay +++ b/src/mame/layout/einvaderc.lay @@ -4,82 +4,29 @@ <!-- define elements --> <element name="static_black"><rect><color red="0.0" green="0.0" blue="0.0" /></rect></element> + <element name="static_white"><rect><color red="0.8" green="0.8" blue="0.8" /></rect></element> + <element name="text_score"><text string="SCORE"><color red="0.8" green="0.8" blue="0.8" /></text></element> <element name="digit" defstate="0"> - <led7seg><color red="1.0" green="0.20" blue="0.22" /></led7seg> - </element> - <element name="led" defstate="0"> - <disk state="0"><color red="0.2" green="0.04" blue="0.05" /></disk> - <disk state="1"><color red="1.0" green="0.20" blue="0.22" /></disk> + <led7seg><color red="1.0" green="0.165" blue="0.165" /></led7seg> </element> <!-- build screen --> - <view name="Test Layout"> - <bounds left="0" right="12" top="0" bottom="28" /> - <bezel element="static_black"> - <bounds left="0" right="12" top="0" bottom="28" /> - </bezel> - - <bezel name="digit0" element="digit"><bounds x="0" y="0" width="4" height="6" /></bezel> - <bezel name="digit1" element="digit"><bounds x="4" y="0" width="4" height="6" /></bezel> - <bezel name="digit2" element="digit"><bounds x="8" y="0" width="4" height="6" /></bezel> - - <!-- led matrix --> - - <bezel name="lamp90" element="led"><bounds x="0" y="10" width="1" height="1" /></bezel> - <bezel name="lamp91" element="led"><bounds x="2" y="10" width="1" height="1" /></bezel> - <bezel name="lamp92" element="led"><bounds x="4" y="10" width="1" height="1" /></bezel> - <bezel name="lamp93" element="led"><bounds x="6" y="10" width="1" height="1" /></bezel> - <bezel name="lamp94" element="led"><bounds x="8" y="10" width="1" height="1" /></bezel> - <bezel name="lamp95" element="led"><bounds x="10" y="10" width="1" height="1" /></bezel> - - <bezel name="lamp80" element="led"><bounds x="0" y="12" width="1" height="1" /></bezel> - <bezel name="lamp81" element="led"><bounds x="2" y="12" width="1" height="1" /></bezel> - <bezel name="lamp82" element="led"><bounds x="4" y="12" width="1" height="1" /></bezel> - <bezel name="lamp83" element="led"><bounds x="6" y="12" width="1" height="1" /></bezel> - <bezel name="lamp84" element="led"><bounds x="8" y="12" width="1" height="1" /></bezel> - <bezel name="lamp85" element="led"><bounds x="10" y="12" width="1" height="1" /></bezel> - - <bezel name="lamp40" element="led"><bounds x="0" y="14" width="1" height="1" /></bezel> - <bezel name="lamp41" element="led"><bounds x="2" y="14" width="1" height="1" /></bezel> - <bezel name="lamp42" element="led"><bounds x="4" y="14" width="1" height="1" /></bezel> - <bezel name="lamp43" element="led"><bounds x="6" y="14" width="1" height="1" /></bezel> - <bezel name="lamp44" element="led"><bounds x="8" y="14" width="1" height="1" /></bezel> - <bezel name="lamp45" element="led"><bounds x="10" y="14" width="1" height="1" /></bezel> - - <bezel name="lamp50" element="led"><bounds x="0" y="16" width="1" height="1" /></bezel> - <bezel name="lamp51" element="led"><bounds x="2" y="16" width="1" height="1" /></bezel> - <bezel name="lamp52" element="led"><bounds x="4" y="16" width="1" height="1" /></bezel> - <bezel name="lamp53" element="led"><bounds x="6" y="16" width="1" height="1" /></bezel> - <bezel name="lamp54" element="led"><bounds x="8" y="16" width="1" height="1" /></bezel> - <bezel name="lamp55" element="led"><bounds x="10" y="16" width="1" height="1" /></bezel> - - <bezel name="lamp60" element="led"><bounds x="0" y="18" width="1" height="1" /></bezel> - <bezel name="lamp61" element="led"><bounds x="2" y="18" width="1" height="1" /></bezel> - <bezel name="lamp62" element="led"><bounds x="4" y="18" width="1" height="1" /></bezel> - <bezel name="lamp63" element="led"><bounds x="6" y="18" width="1" height="1" /></bezel> - <bezel name="lamp64" element="led"><bounds x="8" y="18" width="1" height="1" /></bezel> - <bezel name="lamp65" element="led"><bounds x="10" y="18" width="1" height="1" /></bezel> - - <bezel name="lamp70" element="led"><bounds x="0" y="20" width="1" height="1" /></bezel> - <bezel name="lamp71" element="led"><bounds x="2" y="20" width="1" height="1" /></bezel> - <bezel name="lamp72" element="led"><bounds x="4" y="20" width="1" height="1" /></bezel> - <bezel name="lamp73" element="led"><bounds x="6" y="20" width="1" height="1" /></bezel> - <bezel name="lamp74" element="led"><bounds x="8" y="20" width="1" height="1" /></bezel> - <bezel name="lamp75" element="led"><bounds x="10" y="20" width="1" height="1" /></bezel> - - <bezel name="lamp97" element="led"><bounds x="2" y="22" width="1" height="1" /></bezel> - <bezel name="lamp96" element="led"><bounds x="8" y="22" width="1" height="1" /></bezel> + <view name="Internal Layout"> + <bounds left="-0.1" right="20.1" top="4.6" bottom="33.76" /> + <screen index="0"> + <bounds x="0" y="10" width="20" height="23.66" /> + </screen> - <bezel name="lamp30" element="led"><bounds x="0" y="24" width="1" height="1" /></bezel> - <bezel name="lamp31" element="led"><bounds x="2" y="24" width="1" height="1" /></bezel> - <bezel name="lamp32" element="led"><bounds x="4" y="24" width="1" height="1" /></bezel> - <bezel name="lamp33" element="led"><bounds x="6" y="24" width="1" height="1" /></bezel> - <bezel name="lamp34" element="led"><bounds x="8" y="24" width="1" height="1" /></bezel> - <bezel name="lamp35" element="led"><bounds x="10" y="24" width="1" height="1" /></bezel> + <bezel element="static_white"><bounds x="6.6" y="4.59" width="6.8" height="3.81" /></bezel> + <bezel element="static_black"><bounds x="6.8" y="4.8" width="6.4" height="3.4" /></bezel> + <bezel element="text_score"><bounds x="2" y="5.75" width="4.6" height="1.5" /></bezel> + <bezel name="digit0" element="digit"><bounds x="7" y="5" width="2" height="3" /></bezel> + <bezel name="digit1" element="digit"><bounds x="9" y="5" width="2" height="3" /></bezel> + <bezel name="digit2" element="digit"><bounds x="11" y="5" width="2" height="3" /></bezel> </view> </mamelayout> diff --git a/src/mame/layout/mdallas.lay b/src/mame/layout/mdallas.lay index b34eca393fb..e4e2a98443e 100644 --- a/src/mame/layout/mdallas.lay +++ b/src/mame/layout/mdallas.lay @@ -8,28 +8,28 @@ <view name="Internal Layout"> <bounds left="0" right="80" top="0" bottom="15" /> - <bezel name="digit0" element="digit"> + <bezel name="digit7" element="digit"> <bounds x="0" y="0" width="10" height="15" /> </bezel> - <bezel name="digit1" element="digit"> + <bezel name="digit6" element="digit"> <bounds x="10" y="0" width="10" height="15" /> </bezel> - <bezel name="digit2" element="digit"> + <bezel name="digit5" element="digit"> <bounds x="20" y="0" width="10" height="15" /> </bezel> - <bezel name="digit3" element="digit"> + <bezel name="digit4" element="digit"> <bounds x="30" y="0" width="10" height="15" /> </bezel> - <bezel name="digit4" element="digit"> + <bezel name="digit3" element="digit"> <bounds x="40" y="0" width="10" height="15" /> </bezel> - <bezel name="digit5" element="digit"> + <bezel name="digit2" element="digit"> <bounds x="50" y="0" width="10" height="15" /> </bezel> - <bezel name="digit6" element="digit"> + <bezel name="digit1" element="digit"> <bounds x="60" y="0" width="10" height="15" /> </bezel> - <bezel name="digit7" element="digit"> + <bezel name="digit0" element="digit"> <bounds x="70" y="0" width="10" height="15" /> </bezel> diff --git a/src/mame/layout/novag_diablo68k.lay b/src/mame/layout/novag_diablo68k.lay index dbbd38dab55..f56d9de4757 100644 --- a/src/mame/layout/novag_diablo68k.lay +++ b/src/mame/layout/novag_diablo68k.lay @@ -329,7 +329,7 @@ <bezel element="hl" inputtag="IN.0" inputmask="0x01"><bounds x="73" y="73" width="10" height="10" /><color alpha="0.4" /></bezel> <!-- lcd panel --> -<!-- + <screen index="0"> <bounds x="86.5" y="9.5" width="24.25" height="2.5" /> </screen> @@ -338,7 +338,7 @@ <bezel element="static_lcd"><bounds x="86" y="11.9" width="25.25" height="1.1" /></bezel> <bezel element="static_lcd"><bounds x="86" y="8.5" width="0.6" height="3.5" /></bezel> <bezel element="static_lcd"><bounds x="110.65" y="8.5" width="0.6" height="3.5" /></bezel> ---> + <!-- right side buttons --> <bezel element="but" inputtag="IN.7" inputmask="0x400"><bounds x="87.75" y="24.00" width="2.5" height="2.5" /></bezel> diff --git a/src/mame/machine/osborne1.cpp b/src/mame/machine/osborne1.cpp index cd649cef91a..cb9f84f5bf3 100644 --- a/src/mame/machine/osborne1.cpp +++ b/src/mame/machine/osborne1.cpp @@ -252,6 +252,14 @@ WRITE_LINE_MEMBER( osborne1_state::serial_acia_irq_func ) } +INPUT_CHANGED_MEMBER( osborne1_state::reset_key ) +{ + // This key affects NMI + if (!m_ub6a_q) + m_maincpu->set_input_line(INPUT_LINE_NMI, newval ? CLEAR_LINE : ASSERT_LINE); +} + + DRIVER_INIT_MEMBER( osborne1_state, osborne1 ) { m_bank_0xxx->configure_entries(0, 1, m_ram->pointer(), 0); @@ -443,10 +451,6 @@ TIMER_CALLBACK_MEMBER(osborne1_state::video_callback) m_beep_state = (ra & 0x04) ? 1 : 0; m_speaker->level_w((BIT(port_b, 5) && m_beep_state) ? 1 : 0); - // Check reset key if necessary - it affects NMI - if (!m_ub6a_q) - m_maincpu->set_input_line(INPUT_LINE_NMI, (m_btn_reset->read() & 0x80) ? CLEAR_LINE : ASSERT_LINE); - m_video_timer->adjust(machine().first_screen()->time_until_pos(y + 1, 0)); } diff --git a/src/mame/machine/retofinv.cpp b/src/mame/machine/retofinv.cpp deleted file mode 100644 index 34aa9733b2a..00000000000 --- a/src/mame/machine/retofinv.cpp +++ /dev/null @@ -1,133 +0,0 @@ -// license:BSD-3-Clause -// copyright-holders:Jarek Parchanski, Andrea Mazzoleni -#include "emu.h" -#include "cpu/z80/z80.h" -#include "includes/retofinv.h" - - -/*************************************************************************** - - Return of Invaders 68705 protection interface - -***************************************************************************/ - - -READ8_MEMBER(retofinv_state::mcu_portA_r) -{ -//logerror("%04x: 68705 port A read %02x\n",space.device().safe_pc(),m_portA_in); - return (m_portA_out & m_ddrA) | (m_portA_in & ~m_ddrA); -} - -WRITE8_MEMBER(retofinv_state::mcu_portA_w) -{ -//logerror("%04x: 68705 port A write %02x\n",space.device().safe_pc(),data); - m_portA_out = data; -} - -WRITE8_MEMBER(retofinv_state::mcu_ddrA_w) -{ - m_ddrA = data; -} - - - -/* - * Port B connections: - * - * all bits are logical 1 when read (+5V pullup) - * - * 1 W IRQ ack and enable latch which holds data from main Z80 memory - * 2 W loads latch to Z80 - */ - - -READ8_MEMBER(retofinv_state::mcu_portB_r) -{ - return (m_portB_out & m_ddrB) | (m_portB_in & ~m_ddrB); -} - -WRITE8_MEMBER(retofinv_state::mcu_portB_w) -{ -//logerror("%04x: 68705 port B write %02x\n",space.device().safe_pc(),data); - - if ((m_ddrB & 0x02) && (~data & 0x02) && (m_portB_out & 0x02)) - { - m_portA_in = m_from_main; - if (m_main_sent) m_68705->set_input_line(0, CLEAR_LINE); - m_main_sent = 0; -//logerror("read command %02x from main cpu\n",m_portA_in); - } - if ((m_ddrB & 0x04) && (data & 0x04) && (~m_portB_out & 0x04)) - { -//logerror("send command %02x to main cpu\n",m_portA_out); - m_from_mcu = m_portA_out; - m_mcu_sent = 1; - } - - m_portB_out = data; -} - -WRITE8_MEMBER(retofinv_state::mcu_ddrB_w) -{ - m_ddrB = data; -} - - -/* - * Port C connections: - * - * all bits are logical 1 when read (+5V pullup) - * - * 0 R 1 when pending command Z80->68705 - * 1 R 0 when pending command 68705->Z80 - */ - - -READ8_MEMBER(retofinv_state::mcu_portC_r) -{ - m_portC_in = 0; - if (m_main_sent) m_portC_in |= 0x01; - if (!m_mcu_sent) m_portC_in |= 0x02; -//logerror("%04x: 68705 port C read %02x\n",space.device().safe_pc(),m_portC_in); - return (m_portC_out & m_ddrC) | (m_portC_in & ~m_ddrC); -} - -WRITE8_MEMBER(retofinv_state::mcu_portC_w) -{ -logerror("%04x: 68705 port C write %02x\n",space.device().safe_pc(),data); - m_portC_out = data; -} - -WRITE8_MEMBER(retofinv_state::mcu_ddrC_w) -{ - m_ddrC = data; -} - - -WRITE8_MEMBER(retofinv_state::mcu_w) -{ -logerror("%04x: mcu_w %02x\n",space.device().safe_pc(),data); - m_from_main = data; - m_main_sent = 1; - m_68705->set_input_line(0, ASSERT_LINE); -} - -READ8_MEMBER(retofinv_state::mcu_r) -{ -logerror("%04x: mcu_r %02x\n",space.device().safe_pc(),m_from_mcu); - m_mcu_sent = 0; - return m_from_mcu; -} - -READ8_MEMBER(retofinv_state::mcu_status_r) -{ - int res = 0; - - /* bit 4 = when 1, mcu is ready to receive data from main cpu */ - /* bit 5 = when 1, mcu has sent data to the main cpu */ -//logerror("%04x: mcu_status_r\n",space.device().safe_pc()); - if (!m_main_sent) res |= 0x10; - if (m_mcu_sent) res |= 0x20; - - return res; -} diff --git a/src/mame/machine/stfight.cpp b/src/mame/machine/stfight.cpp index d90cbc127bc..521555bbc33 100644 --- a/src/mame/machine/stfight.cpp +++ b/src/mame/machine/stfight.cpp @@ -10,11 +10,11 @@ ***************************************************************************/ #include "emu.h" -#include "cpu/z80/z80.h" -#include "sound/msm5205.h" #include "includes/stfight.h" - +#include "cpu/m6805/m68705.h" +#include "cpu/z80/z80.h" +#include "sound/msm5205.h" /* @@ -37,7 +37,7 @@ Encryption PAL 16R4 on CPU board */ -DRIVER_INIT_MEMBER(stfight_state,empcity) +DRIVER_INIT_MEMBER(stfight_state, empcity) { uint8_t *rom = memregion("maincpu")->base(); @@ -64,35 +64,40 @@ DRIVER_INIT_MEMBER(stfight_state,empcity) } -DRIVER_INIT_MEMBER(stfight_state,stfight) +DRIVER_INIT_MEMBER(stfight_state, stfight) { DRIVER_INIT_CALL(empcity); } -DRIVER_INIT_MEMBER(stfight_state,cshooter) +DRIVER_INIT_MEMBER(stfight_state, cshooter) { } void stfight_state::machine_start() { - membank("mainbank")->configure_entries(0, 4, memregion("maincpu")->base() + 0x10000, 0x4000); - membank("mainbank")->set_entry(0); + m_main_bank->configure_entries(0, 4, memregion("maincpu")->base() + 0x10000, 0x4000); + m_main_bank->set_entry(0); + + save_item(NAME(m_coin_state)); save_item(NAME(m_fm_data)); + save_item(NAME(m_cpu_to_mcu_empty)); - save_item(NAME(m_adpcm_data_offs)); - save_item(NAME(m_adpcm_nibble)); + save_item(NAME(m_cpu_to_mcu_data)); + save_item(NAME(m_port_a_out)); + save_item(NAME(m_port_c_out)); + + save_item(NAME(m_vck2)); save_item(NAME(m_adpcm_reset)); - save_item(NAME(m_coin_state)); - save_item(NAME(m_portC_out)); + save_item(NAME(m_adpcm_data_offs)); } void stfight_state::machine_reset() { m_fm_data = 0; - m_adpcm_reset = 1; - m_cpu_to_mcu_empty = 1; + m_cpu_to_mcu_empty = true; + m_adpcm_reset = true; // Coin signals are active low m_coin_state = 3; @@ -102,15 +107,7 @@ void stfight_state::machine_reset() // - in fact I don't even know how/where it's switched in! WRITE8_MEMBER(stfight_state::stfight_bank_w) { - uint8_t bank_num = 0; - - if(data & 0x80) - bank_num |= 2; - - if(data & 0x04) - bank_num |= 1; - - membank("mainbank")->set_entry(bank_num); + m_main_bank->set_entry(bitswap(data, 7, 2)); } /* @@ -169,26 +166,19 @@ WRITE8_MEMBER(stfight_state::stfight_coin_w) WRITE_LINE_MEMBER(stfight_state::stfight_adpcm_int) { - static int m_vck2 = 0; - // Falling edge triggered interrupt at half the rate of /VCK? - if (m_vck2) - m_mcu->set_input_line(0, HOLD_LINE); - - m_vck2 ^= 1; + m_mcu->set_input_line(M68705_IRQ_LINE, m_vck2 ? ASSERT_LINE : CLEAR_LINE); + m_vck2 = !m_vck2; if (!m_adpcm_reset) { - const uint8_t *samples = memregion("adpcm")->base(); - uint8_t adpcm_data = samples[m_adpcm_data_offs & 0x7fff]; + uint8_t adpcm_data = m_samples[(m_adpcm_data_offs >> 1) & 0x7fff]; - if (m_adpcm_nibble == 0) + if (!BIT(m_adpcm_data_offs, 0)) adpcm_data >>= 4; - else - ++m_adpcm_data_offs; + ++m_adpcm_data_offs; m_msm->data_w(adpcm_data & 0x0f); - m_adpcm_nibble ^= 1; } } @@ -205,10 +195,11 @@ WRITE8_MEMBER(stfight_state::stfight_fm_w) READ8_MEMBER(stfight_state::stfight_fm_r) { - uint8_t data = m_fm_data; + uint8_t const data = m_fm_data; // Acknowledge the command - m_fm_data &= ~0x80; + if (!space.debugger_access()) + m_fm_data &= ~0x80; return data; } @@ -221,51 +212,45 @@ READ8_MEMBER(stfight_state::stfight_fm_r) WRITE8_MEMBER(stfight_state::stfight_mcu_w) { m_cpu_to_mcu_data = data & 0x0f; - m_cpu_to_mcu_empty = 0; + m_cpu_to_mcu_empty = false; } WRITE8_MEMBER(stfight_state::stfight_68705_port_a_w) { - m_adpcm_data_offs = data << 8; + m_port_a_out = data; } READ8_MEMBER(stfight_state::stfight_68705_port_b_r) { - return (ioport("COIN")->read() << 6) | (m_cpu_to_mcu_empty << 4) | m_cpu_to_mcu_data; + return + (m_coin_mech->read() << 6) | + (m_cpu_to_mcu_empty ? 0x10 : 0x00) | + (m_cpu_to_mcu_data & 0x0f); } WRITE8_MEMBER(stfight_state::stfight_68705_port_b_w) { // Acknowledge Z80 command - if (BIT(mem_mask, 5) && !BIT(data, 5)) - m_cpu_to_mcu_empty = 1; + if (!BIT(data, 5)) + m_cpu_to_mcu_empty = true; } WRITE8_MEMBER(stfight_state::stfight_68705_port_c_w) { // Signal a valid coin on the falling edge - if (BIT(mem_mask, 0) && BIT(m_portC_out, 0) && !BIT(data, 0)) + if (BIT(m_port_c_out, 0) && !BIT(data, 0)) m_coin_state &= ~1; - if (BIT(mem_mask, 1) && BIT(m_portC_out, 1) && !BIT(data, 1)) + if (BIT(m_port_c_out, 1) && !BIT(data, 1)) m_coin_state &= ~2; - if (BIT(mem_mask, 2)) - { - if (BIT(data, 2)) - { - m_adpcm_reset = 1; - m_adpcm_nibble = 0; - m_msm->reset_w(1); - } - else - { - m_adpcm_reset = 0; - m_msm->reset_w(0); - } - } + // Latch ADPCM data address when dropping the reset line + m_adpcm_reset = BIT(data, 2); + if (!m_adpcm_reset && BIT(m_port_c_out, 2)) + m_adpcm_data_offs = m_port_a_out << 9; + m_msm->reset_w(m_adpcm_reset ? ASSERT_LINE : CLEAR_LINE); - if (BIT(mem_mask, 3)) - m_maincpu->set_input_line(INPUT_LINE_NMI, BIT(data, 3) ? CLEAR_LINE : ASSERT_LINE); + // Generate NMI on host CPU (used on handshake error or stuck coin) + m_maincpu->set_input_line(INPUT_LINE_NMI, BIT(data, 3) ? CLEAR_LINE : ASSERT_LINE); - m_portC_out = data; + m_port_c_out = data; } diff --git a/src/mame/machine/taito68705interface.cpp b/src/mame/machine/taito68705interface.cpp index 7605053dbe8..3cb18183b9a 100644 --- a/src/mame/machine/taito68705interface.cpp +++ b/src/mame/machine/taito68705interface.cpp @@ -21,6 +21,7 @@ matmania.cpp - maniach nycaptor.cpp - nycaptor renegade.cpp - renegade + retofinv.cpp - retofinv slapfght.cpp - slapfght xain.cpp - xsleena @@ -37,7 +38,6 @@ bublbobl.cpp - bub68705 - this is a bootleg, not an official Taito hookup changela.cpp - changela - looks like an ancestor of arkanoid without automatic semaphores mexico86.cpp - knightb, mexico86 - bootleg 68705s - retofinv.cpp - the current MCU dump is a bootleg at least sqix.cpp - hotsmash - kaneko hookup, different from Taito ones. there are other drivers (and games in existing drivers) that could hookup here, but currently lack MCU dumps. diff --git a/src/mame/machine/zorbakbd.cpp b/src/mame/machine/zorbakbd.cpp new file mode 100644 index 00000000000..1cb8be7ce20 --- /dev/null +++ b/src/mame/machine/zorbakbd.cpp @@ -0,0 +1,315 @@ +// license:BSD-3-Clause +// copyright-holders:Vas Crabb +/* + * TTL-level serial matrix keyboard + * + * The keyboard MCU handles scanning the matrix and converting key down/ + * up events to high-level characters for the host computer. The DIP + * switches are only read on startup. + * + * TODO: the eight "holes" generate control codes, six of them are break, home and the arrows + * + * Strangely, the Zorba configures its keyboard UART for 8N2 but this + * keyboard sends 8N1. If you type too fast or hold down a key until it + * repeats, characters will be dropped/corrupted. It's possible this is + * a dump of a different CP/M-compatible keyboard, not the one supplied + * with the Zorba. + * + * The Zorba manual describes a keyboard PROM with enough space to map + * all eight modifier combinations independently, however this keyboard + * contains no PROMs (just the MCU and demultiplexer), and the internal + * MCU EPROM only contains three tables for normal, shift, and control + * (caps lock is computed off the normal table by checking for letter + * characters). + * + * 0 1 2 3 4 5 6 7 + * 0 F1 F13 3 # KP8 i I s S KP2 , < + * 1 F2 F14 4 $ KP9 o O d D KP3 . > + * 2 F3 F15 5 % p P f F / ? + * 3 F4 F16 6 ^ [ { g G KP0 + * 4 F5 F17 7 & tab ] } h H shift KP. + * 5 F6 F18 8 * q Q KP4 j J z Z + * 6 F7 F19 9 ( w W KP5 k K x X + * 7 F8 ~ 0 ) e E KP6 l L c C space + * 8 F9 \ | - _ r R s-lock ; : v V newline + * 9 F10 ESC = + t T ctrl ' " b B KP- + * 10 F11 1 ! del y Y c-lock return n N + * 11 F12 2 @ KP7 u U a A KP1 m M + */ +#include "emu.h" +#include "zorbakbd.h" + +#include "cpu/m6805/m68705.h" + + +namespace { + +INPUT_PORTS_START(zorba_keyboard) + PORT_START("ROW0") + PORT_BIT( 0x01, IP_ACTIVE_LOW, IPT_KEYBOARD ) PORT_NAME("F1") PORT_CODE(KEYCODE_F1) PORT_CHAR(UCHAR_MAMEKEY(F1)) + PORT_BIT( 0x02, IP_ACTIVE_LOW, IPT_KEYBOARD ) PORT_NAME("F13") PORT_CODE(KEYCODE_F13) PORT_CHAR(UCHAR_MAMEKEY(F13)) + PORT_BIT( 0x04, IP_ACTIVE_LOW, IPT_KEYBOARD ) PORT_CODE(KEYCODE_3) PORT_CHAR('3') PORT_CHAR('#') + PORT_BIT( 0x08, IP_ACTIVE_LOW, IPT_KEYBOARD ) PORT_NAME("KP 8") PORT_CODE(KEYCODE_8_PAD) PORT_CHAR(UCHAR_MAMEKEY(8_PAD)) + PORT_BIT( 0x10, IP_ACTIVE_LOW, IPT_KEYBOARD ) PORT_CODE(KEYCODE_I) PORT_CHAR('i') PORT_CHAR('I') + PORT_BIT( 0x20, IP_ACTIVE_LOW, IPT_KEYBOARD ) PORT_CODE(KEYCODE_S) PORT_CHAR('s') PORT_CHAR('S') + PORT_BIT( 0x40, IP_ACTIVE_LOW, IPT_KEYBOARD ) PORT_NAME("KP 2") PORT_CODE(KEYCODE_2_PAD) PORT_CHAR(UCHAR_MAMEKEY(2_PAD)) + PORT_BIT( 0x80, IP_ACTIVE_LOW, IPT_KEYBOARD ) PORT_CODE(KEYCODE_COMMA) PORT_CHAR(',') PORT_CHAR('<') + + PORT_START("ROW1") + PORT_BIT( 0x01, IP_ACTIVE_LOW, IPT_KEYBOARD ) PORT_NAME("F2") PORT_CODE(KEYCODE_F2) PORT_CHAR(UCHAR_MAMEKEY(F2)) + PORT_BIT( 0x02, IP_ACTIVE_LOW, IPT_KEYBOARD ) PORT_NAME("F14") PORT_CODE(KEYCODE_F14) PORT_CHAR(UCHAR_MAMEKEY(F14)) + PORT_BIT( 0x04, IP_ACTIVE_LOW, IPT_KEYBOARD ) PORT_CODE(KEYCODE_4) PORT_CHAR('4') PORT_CHAR('$') + PORT_BIT( 0x08, IP_ACTIVE_LOW, IPT_KEYBOARD ) PORT_NAME("KP 9") PORT_CODE(KEYCODE_9_PAD) PORT_CHAR(UCHAR_MAMEKEY(9_PAD)) + PORT_BIT( 0x10, IP_ACTIVE_LOW, IPT_KEYBOARD ) PORT_CODE(KEYCODE_O) PORT_CHAR('o') PORT_CHAR('O') + PORT_BIT( 0x20, IP_ACTIVE_LOW, IPT_KEYBOARD ) PORT_CODE(KEYCODE_D) PORT_CHAR('d') PORT_CHAR('D') + PORT_BIT( 0x40, IP_ACTIVE_LOW, IPT_KEYBOARD ) PORT_NAME("KP 3") PORT_CODE(KEYCODE_3_PAD) PORT_CHAR(UCHAR_MAMEKEY(3_PAD)) + PORT_BIT( 0x80, IP_ACTIVE_LOW, IPT_KEYBOARD ) PORT_CODE(KEYCODE_STOP) PORT_CHAR('.') PORT_CHAR('>') + + PORT_START("ROW2") + PORT_BIT( 0x01, IP_ACTIVE_LOW, IPT_KEYBOARD ) PORT_NAME("F3") PORT_CODE(KEYCODE_F3) PORT_CHAR(UCHAR_MAMEKEY(F3)) + PORT_BIT( 0x02, IP_ACTIVE_LOW, IPT_KEYBOARD ) PORT_NAME("F15") PORT_CODE(KEYCODE_F15) PORT_CHAR(UCHAR_MAMEKEY(F15)) + PORT_BIT( 0x04, IP_ACTIVE_LOW, IPT_KEYBOARD ) PORT_CODE(KEYCODE_5) PORT_CHAR('5') PORT_CHAR('%') + PORT_BIT( 0x08, IP_ACTIVE_LOW, IPT_UNKNOWN ) // b9 + PORT_BIT( 0x10, IP_ACTIVE_LOW, IPT_KEYBOARD ) PORT_CODE(KEYCODE_P) PORT_CHAR('p') PORT_CHAR('P') + PORT_BIT( 0x20, IP_ACTIVE_LOW, IPT_KEYBOARD ) PORT_CODE(KEYCODE_F) PORT_CHAR('f') PORT_CHAR('F') + PORT_BIT( 0x40, IP_ACTIVE_LOW, IPT_UNKNOWN ) // b3 + PORT_BIT( 0x80, IP_ACTIVE_LOW, IPT_KEYBOARD ) PORT_CODE(KEYCODE_SLASH) PORT_CHAR('/') PORT_CHAR('?') + + PORT_START("ROW3") + PORT_BIT( 0x01, IP_ACTIVE_LOW, IPT_KEYBOARD ) PORT_NAME("F4") PORT_CODE(KEYCODE_F4) PORT_CHAR(UCHAR_MAMEKEY(F4)) + PORT_BIT( 0x02, IP_ACTIVE_LOW, IPT_KEYBOARD ) PORT_NAME("F16") PORT_CODE(KEYCODE_F16) PORT_CHAR(UCHAR_MAMEKEY(F16)) + PORT_BIT( 0x04, IP_ACTIVE_LOW, IPT_KEYBOARD ) PORT_CODE(KEYCODE_6) PORT_CHAR('6') PORT_CHAR('^') + PORT_BIT( 0x08, IP_ACTIVE_LOW, IPT_UNKNOWN ) // b7 + PORT_BIT( 0x10, IP_ACTIVE_LOW, IPT_KEYBOARD ) PORT_CODE(KEYCODE_OPENBRACE) PORT_CHAR('[') PORT_CHAR('{') + PORT_BIT( 0x20, IP_ACTIVE_LOW, IPT_KEYBOARD ) PORT_CODE(KEYCODE_G) PORT_CHAR('g') PORT_CHAR('G') + PORT_BIT( 0x40, IP_ACTIVE_LOW, IPT_UNKNOWN ) // b4 + PORT_BIT( 0x80, IP_ACTIVE_LOW, IPT_KEYBOARD ) PORT_NAME("KP 0") PORT_CODE(KEYCODE_0_PAD) PORT_CHAR(UCHAR_MAMEKEY(0_PAD)) + + PORT_START("ROW4") + PORT_BIT( 0x01, IP_ACTIVE_LOW, IPT_KEYBOARD ) PORT_NAME("F5") PORT_CODE(KEYCODE_F5) PORT_CHAR(UCHAR_MAMEKEY(F5)) + PORT_BIT( 0x02, IP_ACTIVE_LOW, IPT_KEYBOARD ) PORT_NAME("F17") PORT_CODE(KEYCODE_F17) PORT_CHAR(UCHAR_MAMEKEY(F17)) + PORT_BIT( 0x04, IP_ACTIVE_LOW, IPT_KEYBOARD ) PORT_CODE(KEYCODE_7) PORT_CHAR('7') PORT_CHAR('&') + PORT_BIT( 0x08, IP_ACTIVE_LOW, IPT_KEYBOARD ) PORT_NAME("TAB") PORT_CODE(KEYCODE_TAB) PORT_CHAR(9) + PORT_BIT( 0x10, IP_ACTIVE_LOW, IPT_KEYBOARD ) PORT_CODE(KEYCODE_CLOSEBRACE) PORT_CHAR(']') PORT_CHAR('}') + PORT_BIT( 0x20, IP_ACTIVE_LOW, IPT_KEYBOARD ) PORT_CODE(KEYCODE_H) PORT_CHAR('h') PORT_CHAR('H') + PORT_BIT( 0x40, IP_ACTIVE_LOW, IPT_KEYBOARD ) PORT_NAME("SHIFT") PORT_CODE(KEYCODE_LSHIFT) PORT_CODE(KEYCODE_RSHIFT) PORT_CHAR(UCHAR_SHIFT_1) + PORT_BIT( 0x80, IP_ACTIVE_LOW, IPT_KEYBOARD ) PORT_NAME("KP .") PORT_CODE(KEYCODE_DEL_PAD) PORT_CHAR(UCHAR_MAMEKEY(DEL_PAD)) + + PORT_START("ROW5") + PORT_BIT( 0x01, IP_ACTIVE_LOW, IPT_KEYBOARD ) PORT_NAME("F6") PORT_CODE(KEYCODE_F6) PORT_CHAR(UCHAR_MAMEKEY(F6)) + PORT_BIT( 0x02, IP_ACTIVE_LOW, IPT_KEYBOARD ) PORT_NAME("F18") PORT_CODE(KEYCODE_F18) PORT_CHAR(UCHAR_MAMEKEY(F18)) + PORT_BIT( 0x04, IP_ACTIVE_LOW, IPT_KEYBOARD ) PORT_CODE(KEYCODE_8) PORT_CHAR('8') PORT_CHAR('*') + 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_NAME("KP 4") PORT_CODE(KEYCODE_4_PAD) PORT_CHAR(UCHAR_MAMEKEY(4_PAD)) + PORT_BIT( 0x20, IP_ACTIVE_LOW, IPT_KEYBOARD ) PORT_CODE(KEYCODE_J) PORT_CHAR('j') PORT_CHAR('J') + PORT_BIT( 0x40, IP_ACTIVE_LOW, IPT_KEYBOARD ) PORT_CODE(KEYCODE_Z) PORT_CHAR('z') PORT_CHAR('Z') + PORT_BIT( 0x80, IP_ACTIVE_LOW, IPT_UNKNOWN ) // b5 + + PORT_START("ROW6") + PORT_BIT( 0x01, IP_ACTIVE_LOW, IPT_KEYBOARD ) PORT_NAME("F7") PORT_CODE(KEYCODE_F7) PORT_CHAR(UCHAR_MAMEKEY(F7)) + PORT_BIT( 0x02, IP_ACTIVE_LOW, IPT_KEYBOARD ) PORT_NAME("F19") PORT_CODE(KEYCODE_F19) PORT_CHAR(UCHAR_MAMEKEY(F19)) + PORT_BIT( 0x04, IP_ACTIVE_LOW, IPT_KEYBOARD ) PORT_CODE(KEYCODE_9) PORT_CHAR('9') PORT_CHAR('(') + PORT_BIT( 0x08, IP_ACTIVE_LOW, IPT_KEYBOARD ) PORT_CODE(KEYCODE_W) PORT_CHAR('w') PORT_CHAR('W') + PORT_BIT( 0x10, IP_ACTIVE_LOW, IPT_KEYBOARD ) PORT_NAME("KP 5") PORT_CODE(KEYCODE_5_PAD) PORT_CHAR(UCHAR_MAMEKEY(5_PAD)) + PORT_BIT( 0x20, IP_ACTIVE_LOW, IPT_KEYBOARD ) PORT_CODE(KEYCODE_K) PORT_CHAR('k') PORT_CHAR('K') + PORT_BIT( 0x40, IP_ACTIVE_LOW, IPT_KEYBOARD ) PORT_CODE(KEYCODE_X) PORT_CHAR('x') PORT_CHAR('X') + PORT_BIT( 0x80, IP_ACTIVE_LOW, IPT_UNKNOWN ) // b6 + + PORT_START("ROW7") + PORT_BIT( 0x01, IP_ACTIVE_LOW, IPT_KEYBOARD ) PORT_NAME("F8") PORT_CODE(KEYCODE_F8) PORT_CHAR(UCHAR_MAMEKEY(F8)) + PORT_BIT( 0x02, IP_ACTIVE_LOW, IPT_KEYBOARD ) PORT_NAME("~ PRINT") PORT_CODE(KEYCODE_TILDE) PORT_CHAR('~') PORT_CHAR(UCHAR_MAMEKEY(PRTSCR)) + PORT_BIT( 0x04, IP_ACTIVE_LOW, IPT_KEYBOARD ) PORT_CODE(KEYCODE_0) PORT_CHAR('0') PORT_CHAR(')') + PORT_BIT( 0x08, IP_ACTIVE_LOW, IPT_KEYBOARD ) PORT_CODE(KEYCODE_E) PORT_CHAR('e') PORT_CHAR('E') + PORT_BIT( 0x10, IP_ACTIVE_LOW, IPT_KEYBOARD ) PORT_NAME("KP 6") PORT_CODE(KEYCODE_6_PAD) PORT_CHAR(UCHAR_MAMEKEY(6_PAD)) + PORT_BIT( 0x20, IP_ACTIVE_LOW, IPT_KEYBOARD ) PORT_CODE(KEYCODE_L) PORT_CHAR('l') PORT_CHAR('L') + PORT_BIT( 0x40, IP_ACTIVE_LOW, IPT_KEYBOARD ) PORT_CODE(KEYCODE_C) PORT_CHAR('c') PORT_CHAR('C') + PORT_BIT( 0x80, IP_ACTIVE_LOW, IPT_KEYBOARD ) PORT_CODE(KEYCODE_SPACE) PORT_CHAR(' ') + + PORT_START("ROW8") + PORT_BIT( 0x01, IP_ACTIVE_LOW, IPT_KEYBOARD ) PORT_NAME("F9") PORT_CODE(KEYCODE_F9) PORT_CHAR(UCHAR_MAMEKEY(F9)) + PORT_BIT( 0x02, IP_ACTIVE_LOW, IPT_KEYBOARD ) PORT_CODE(KEYCODE_BACKSLASH) PORT_CHAR('\\') PORT_CHAR('|') + PORT_BIT( 0x04, IP_ACTIVE_LOW, IPT_KEYBOARD ) PORT_CODE(KEYCODE_MINUS) PORT_CHAR('-') PORT_CHAR('_') + PORT_BIT( 0x08, IP_ACTIVE_LOW, IPT_KEYBOARD ) PORT_CODE(KEYCODE_R) PORT_CHAR('r') PORT_CHAR('R') + PORT_BIT( 0x10, IP_ACTIVE_LOW, IPT_KEYBOARD ) PORT_NAME("SHIFT LOCK") PORT_CODE(KEYCODE_LALT) + 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_V) PORT_CHAR('v') PORT_CHAR('V') + PORT_BIT( 0x80, IP_ACTIVE_LOW, IPT_KEYBOARD ) PORT_NAME("NEW LINE") PORT_CODE(KEYCODE_ENTER_PAD) PORT_CHAR(UCHAR_MAMEKEY(ENTER_PAD)) + + PORT_START("ROW9") + PORT_BIT( 0x01, IP_ACTIVE_LOW, IPT_KEYBOARD ) PORT_NAME("F10") PORT_CODE(KEYCODE_F10) PORT_CHAR(UCHAR_MAMEKEY(F10)) + PORT_BIT( 0x02, IP_ACTIVE_LOW, IPT_KEYBOARD ) PORT_NAME("ESC") PORT_CODE(KEYCODE_ESC) PORT_CHAR(UCHAR_MAMEKEY(ESC)) + PORT_BIT( 0x04, IP_ACTIVE_LOW, IPT_KEYBOARD ) PORT_CODE(KEYCODE_EQUALS) PORT_CHAR('=') PORT_CHAR('+') + PORT_BIT( 0x08, IP_ACTIVE_LOW, IPT_KEYBOARD ) PORT_CODE(KEYCODE_T) PORT_CHAR('t') PORT_CHAR('T') + PORT_BIT( 0x10, IP_ACTIVE_LOW, IPT_KEYBOARD ) PORT_NAME("CTRL") PORT_CODE(KEYCODE_LCONTROL) PORT_CHAR(UCHAR_MAMEKEY(LCONTROL)) + PORT_BIT( 0x20, IP_ACTIVE_LOW, IPT_KEYBOARD ) PORT_CODE(KEYCODE_QUOTE) PORT_CHAR('\'') PORT_CHAR('"') + PORT_BIT( 0x40, IP_ACTIVE_LOW, IPT_KEYBOARD ) PORT_CODE(KEYCODE_B) PORT_CHAR('b') PORT_CHAR('B') + PORT_BIT( 0x80, IP_ACTIVE_LOW, IPT_KEYBOARD ) PORT_NAME("KP -") PORT_CODE(KEYCODE_MINUS_PAD) PORT_CHAR(UCHAR_MAMEKEY(MINUS_PAD)) + + PORT_START("ROW10") + PORT_BIT( 0x01, IP_ACTIVE_LOW, IPT_KEYBOARD ) PORT_NAME("F11") PORT_CODE(KEYCODE_F11) PORT_CHAR(UCHAR_MAMEKEY(F11)) + PORT_BIT( 0x02, IP_ACTIVE_LOW, IPT_KEYBOARD ) PORT_CODE(KEYCODE_1) PORT_CHAR('1') PORT_CHAR('!') + PORT_BIT( 0x04, IP_ACTIVE_LOW, IPT_KEYBOARD ) PORT_NAME("BS DEL") PORT_CODE(KEYCODE_BACKSPACE) PORT_CHAR(8) PORT_CHAR(UCHAR_MAMEKEY(DEL)) + PORT_BIT( 0x08, IP_ACTIVE_LOW, IPT_KEYBOARD ) PORT_CODE(KEYCODE_Y) PORT_CHAR('y') PORT_CHAR('Y') + PORT_BIT( 0x10, IP_ACTIVE_LOW, IPT_KEYBOARD ) PORT_NAME("CAPS LOCK") PORT_CODE(KEYCODE_CAPSLOCK) PORT_CHAR(UCHAR_MAMEKEY(CAPSLOCK)) + PORT_BIT( 0x20, IP_ACTIVE_LOW, IPT_KEYBOARD ) PORT_NAME("RETURN") PORT_CODE(KEYCODE_ENTER) PORT_CHAR(13) + PORT_BIT( 0x40, IP_ACTIVE_LOW, IPT_KEYBOARD ) PORT_CODE(KEYCODE_N) PORT_CHAR('n') PORT_CHAR('N') + PORT_BIT( 0x80, IP_ACTIVE_LOW, IPT_UNKNOWN ) // e0 + + PORT_START("ROW11") + PORT_BIT( 0x01, IP_ACTIVE_LOW, IPT_KEYBOARD ) PORT_NAME("F12") PORT_CODE(KEYCODE_F12) PORT_CHAR(UCHAR_MAMEKEY(F12)) + 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_NAME("KP 7") PORT_CODE(KEYCODE_7_PAD) PORT_CHAR(UCHAR_MAMEKEY(7_PAD)) + PORT_BIT( 0x08, IP_ACTIVE_LOW, IPT_KEYBOARD ) PORT_CODE(KEYCODE_U) PORT_CHAR('u') PORT_CHAR('U') + PORT_BIT( 0x10, IP_ACTIVE_LOW, IPT_KEYBOARD ) PORT_CODE(KEYCODE_A) PORT_CHAR('a') PORT_CHAR('A') + PORT_BIT( 0x20, IP_ACTIVE_LOW, IPT_KEYBOARD ) PORT_NAME("KP 1") PORT_CODE(KEYCODE_1_PAD) PORT_CHAR(UCHAR_MAMEKEY(1_PAD)) + PORT_BIT( 0x40, IP_ACTIVE_LOW, IPT_KEYBOARD ) PORT_CODE(KEYCODE_M) PORT_CHAR('m') PORT_CHAR('M') + PORT_BIT( 0x80, IP_ACTIVE_LOW, IPT_UNKNOWN ) // e1 + + PORT_START("ROW12") + PORT_BIT( 0xff, IP_ACTIVE_LOW, IPT_UNUSED ) // scanned but the tables are too small so it would post garbage + + PORT_START("ROW13") + PORT_BIT( 0xff, IP_ACTIVE_LOW, IPT_UNUSED ) // scanned but the tables are too small so it would post garbage + + PORT_START("ROW14") + PORT_BIT( 0xff, IP_ACTIVE_LOW, IPT_UNUSED ) // scanned but the tables are too small so it would post garbage + + PORT_START("ROW15") + PORT_DIPNAME( 0x07, 0x07, "Diagnostic Mode" ) + PORT_DIPSETTING( 0x07, "0 (Normal)" ) + PORT_DIPSETTING( 0x06, "1 (Dump Tables)" ) + PORT_DIPSETTING( 0x05, "2 (Report Revision)" ) + PORT_DIPSETTING( 0x04, "3 (Serial Test)" ) + PORT_DIPSETTING( 0x03, "4 (Serial Echo)" ) + PORT_DIPSETTING( 0x02, "5 (Output Test)" ) + PORT_DIPSETTING( 0x01, "6 (Normal)" ) + PORT_DIPSETTING( 0x00, "7 (Dump Tables)" ) + PORT_DIPNAME( 0x08, 0x08, "Key Repeat" ) + PORT_DIPSETTING( 0x08, DEF_STR(On) ) + PORT_DIPSETTING( 0x00, DEF_STR(Off) ) + PORT_DIPNAME( 0x10, 0x10, "Baud Rate" ) + PORT_DIPSETTING( 0x10, "1200" ) + PORT_DIPSETTING( 0x00, "300" ) + PORT_DIPNAME( 0x20, 0x20, "Key Click" ) + PORT_DIPSETTING( 0x20, DEF_STR(On) ) + PORT_DIPSETTING( 0x00, DEF_STR(Off) ) + 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) ) +INPUT_PORTS_END + + +MACHINE_CONFIG_FRAGMENT(zorba_keyboard) + // MC68705P3S + MCFG_CPU_ADD("mcu", M68705P3, XTAL_3_579545MHz * 1.05) // the 1.05 is a hack to get better sync with the host's USART - something's off in our timings + MCFG_M68705_PORTA_R_CB(READ8(zorba_keyboard_device, mcu_pa_r)); + MCFG_M68705_PORTB_R_CB(READ8(zorba_keyboard_device, mcu_pb_r)); + MCFG_M68705_PORTB_W_CB(WRITE8(zorba_keyboard_device, mcu_pb_w)); + MCFG_M68705_PORTC_W_CB(WRITE8(zorba_keyboard_device, mcu_pc_w)); + + // TODO: beeper frequency is unknown, using value from Sun keyboard for now + MCFG_SPEAKER_STANDARD_MONO("bell") + MCFG_SOUND_ADD("beeper", BEEP, ATTOSECONDS_TO_HZ(480 * ATTOSECONDS_PER_MICROSECOND)) + MCFG_SOUND_ROUTE(ALL_OUTPUTS, "bell", 0.4) +MACHINE_CONFIG_END + + +ROM_START(zorba_keyboard) + ROM_REGION(0x0800, "mcu", 0) + ROM_LOAD( "8999-1 3-28-83", 0x080, 0x780, CRC(79fe6c0d) SHA1(4b6fca9379d5199d1347ad1187cbfdebfc4c73e7) ) +ROM_END + +} // anonymous namespace + + +device_type const ZORBA_KEYBOARD = &device_creator<zorba_keyboard_device>; + + +zorba_keyboard_device::zorba_keyboard_device( + machine_config const &mconfig, + char const *tag, + device_t *owner, + uint32_t clock) + : device_t( + mconfig, + ZORBA_KEYBOARD, + "Zorba Keyboard", + tag, + owner, + clock, + "zorba_kbd", + __FILE__) + , m_rows(*this, "ROW%u", 0) + , m_beeper(*this, "beeper") + , m_rxd_cb(*this) + , m_txd_high(true) + , m_row_select(0) +{ +} + + +WRITE_LINE_MEMBER(zorba_keyboard_device::txd_w) +{ + m_txd_high = CLEAR_LINE != state; +} + + +READ8_MEMBER(zorba_keyboard_device::mcu_pa_r) +{ + return m_rows[m_row_select]->read(); +} + + +READ8_MEMBER(zorba_keyboard_device::mcu_pb_r) +{ + return m_txd_high ? 0x7f : 0xff; +} + + +WRITE8_MEMBER(zorba_keyboard_device::mcu_pb_w) +{ + // TODO: bits 2/3/4 do something; some photos show F17/F18/F19 with LED windows + m_rxd_cb(BIT(data, 6) ? 0 : 1); + m_beeper->set_state(BIT(data, 5) ? 0 : 1); + machine().output().set_value("led_key_caps_lock", BIT(data, 1) ? 0 : 1); + machine().output().set_value("led_key_shift_lock", BIT(data, 0) ? 0 : 1); +} + + +WRITE8_MEMBER(zorba_keyboard_device::mcu_pc_w) +{ + m_row_select = data & 0x0f; +} + + +void zorba_keyboard_device::device_start() +{ + m_rxd_cb.resolve_safe(); + + save_item(NAME(m_txd_high)); + save_item(NAME(m_row_select)); + + m_txd_high = true; + m_row_select = 0; +} + + +machine_config_constructor zorba_keyboard_device::device_mconfig_additions() const +{ + return MACHINE_CONFIG_NAME(zorba_keyboard); +} + + +ioport_constructor zorba_keyboard_device::device_input_ports() const +{ + return INPUT_PORTS_NAME(zorba_keyboard); +} + + +tiny_rom_entry const *zorba_keyboard_device::device_rom_region() const +{ + return ROM_NAME(zorba_keyboard); +} diff --git a/src/mame/machine/zorbakbd.h b/src/mame/machine/zorbakbd.h new file mode 100644 index 00000000000..196a4831c41 --- /dev/null +++ b/src/mame/machine/zorbakbd.h @@ -0,0 +1,43 @@ +// license:BSD-3-Clause +// copyright-holders:Vas Crabb +#ifndef MAME_MACHINE_ZORBAKBD_H +#define MAME_MACHINE_ZORBAKBD_H + +#include "sound/beep.h" + + +extern device_type const ZORBA_KEYBOARD; + +#define MCFG_ZORBA_KEYBOARD_RXD_CB(cb) \ + zorba_keyboard_device::set_rxd_cb(*device, DEVCB_##cb); + +class zorba_keyboard_device : public device_t +{ +public: + template <typename Obj> static devcb_base &set_rxd_cb(device_t &device, Obj &&object) + { return downcast<zorba_keyboard_device &>(device).m_rxd_cb.set_callback(std::forward<Obj>(object)); } + + zorba_keyboard_device(machine_config const &mconfig, char const *tag, device_t *owner, uint32_t clock); + + DECLARE_WRITE_LINE_MEMBER(txd_w); + + DECLARE_READ8_MEMBER(mcu_pa_r); + DECLARE_READ8_MEMBER(mcu_pb_r); + DECLARE_WRITE8_MEMBER(mcu_pb_w); + DECLARE_WRITE8_MEMBER(mcu_pc_w); + +protected: + virtual void device_start() override; + virtual machine_config_constructor device_mconfig_additions() const override; + virtual ioport_constructor device_input_ports() const override; + virtual tiny_rom_entry const *device_rom_region() const override; + + required_ioport_array<16> m_rows; + required_device<beep_device> m_beeper; + devcb_write_line m_rxd_cb; + + bool m_txd_high; + u8 m_row_select; +}; + +#endif // MAME_MACHINE_ZORBAKBD_H
\ No newline at end of file diff --git a/src/mame/mame.lst b/src/mame/mame.lst index 814e9ed6883..286b32df7f8 100644 --- a/src/mame/mame.lst +++ b/src/mame/mame.lst @@ -31023,6 +31023,7 @@ poly880 // @source:polyplay.cpp polyplay // polyplay2 // +polyplay2c // @source:pong.cpp breakout // (c) 1976 Atari diff --git a/src/osd/modules/debugger/debugosx.mm b/src/osd/modules/debugger/debugosx.mm index 56e85e21105..60599415e69 100644 --- a/src/osd/modules/debugger/debugosx.mm +++ b/src/osd/modules/debugger/debugosx.mm @@ -8,7 +8,7 @@ // TODO: -// * Automatic scrolling for console and log views +// * Automatic scrolling for console view // * Keyboard shortcuts in error log and device windows // * Don't accept keyboard input while the game is running // * Interior focus rings - standard/exterior focus rings look really ugly here diff --git a/src/osd/modules/debugger/osx/debugconsole.mm b/src/osd/modules/debugger/osx/debugconsole.mm index e96d0757ba7..041e7fc314e 100644 --- a/src/osd/modules/debugger/osx/debugconsole.mm +++ b/src/osd/modules/debugger/osx/debugconsole.mm @@ -48,6 +48,7 @@ [regScroll setHasVerticalScroller:YES]; [regScroll setAutohidesScrollers:YES]; [regScroll setBorderType:NSBezelBorder]; + [regScroll setDrawsBackground:NO]; [regScroll setDocumentView:regView]; [regView release]; @@ -59,6 +60,7 @@ [dasmScroll setHasVerticalScroller:YES]; [dasmScroll setAutohidesScrollers:YES]; [dasmScroll setBorderType:NSBezelBorder]; + [dasmScroll setDrawsBackground:NO]; [dasmScroll setDocumentView:dasmView]; [dasmView release]; @@ -70,6 +72,7 @@ [consoleScroll setHasVerticalScroller:YES]; [consoleScroll setAutohidesScrollers:YES]; [consoleScroll setBorderType:NSBezelBorder]; + [consoleScroll setDrawsBackground:NO]; [consoleScroll setDocumentView:consoleView]; [consoleView release]; diff --git a/src/osd/modules/debugger/osx/debugview.mm b/src/osd/modules/debugger/osx/debugview.mm index ecc55349283..97854b22d70 100644 --- a/src/osd/modules/debugger/osx/debugview.mm +++ b/src/osd/modules/debugger/osx/debugview.mm @@ -184,7 +184,7 @@ static void debugwin_view_update(debug_view &view, void *osdprivate) - (void)typeCharacterAndScrollToCursor:(char)ch { debug_view_xy const oldPos = view->cursor_position(); view->process_char(ch); - if (view->cursor_supported() && view->cursor_visible()) + if (view->cursor_supported()) { debug_view_xy const newPos = view->cursor_position(); if ((newPos.x != oldPos.x) || (newPos.y != oldPos.y)) diff --git a/src/osd/modules/debugger/osx/deviceinfoviewer.mm b/src/osd/modules/debugger/osx/deviceinfoviewer.mm index dc2b2114005..8a275d9c573 100644 --- a/src/osd/modules/debugger/osx/deviceinfoviewer.mm +++ b/src/osd/modules/debugger/osx/deviceinfoviewer.mm @@ -218,6 +218,7 @@ [contentScroll setHasVerticalScroller:YES]; [contentScroll setAutohidesScrollers:YES]; [contentScroll setBorderType:NSNoBorder]; + [contentScroll setDrawsBackground:NO]; [contentScroll setDocumentView:contentView]; [contentView release]; [[window contentView] addSubview:contentScroll]; diff --git a/src/osd/modules/debugger/osx/devicesviewer.mm b/src/osd/modules/debugger/osx/devicesviewer.mm index 2bdb0253299..210f353d76d 100644 --- a/src/osd/modules/debugger/osx/devicesviewer.mm +++ b/src/osd/modules/debugger/osx/devicesviewer.mm @@ -145,6 +145,7 @@ [devicesScroll setHasVerticalScroller:YES]; [devicesScroll setAutohidesScrollers:YES]; [devicesScroll setBorderType:NSNoBorder]; + [devicesScroll setDrawsBackground:NO]; [devicesScroll setDocumentView:devicesView]; [devicesView release]; [[window contentView] addSubview:devicesScroll]; diff --git a/src/osd/modules/debugger/osx/disassemblyviewer.mm b/src/osd/modules/debugger/osx/disassemblyviewer.mm index d2c3decff11..88934ffbb8c 100644 --- a/src/osd/modules/debugger/osx/disassemblyviewer.mm +++ b/src/osd/modules/debugger/osx/disassemblyviewer.mm @@ -88,6 +88,7 @@ [dasmScroll setHasVerticalScroller:YES]; [dasmScroll setAutohidesScrollers:YES]; [dasmScroll setBorderType:NSNoBorder]; + [dasmScroll setDrawsBackground:NO]; [dasmScroll setDocumentView:dasmView]; [dasmView release]; [[window contentView] addSubview:dasmScroll]; diff --git a/src/osd/modules/debugger/osx/errorlogviewer.mm b/src/osd/modules/debugger/osx/errorlogviewer.mm index c40d9f89b69..5b78fdd7272 100644 --- a/src/osd/modules/debugger/osx/errorlogviewer.mm +++ b/src/osd/modules/debugger/osx/errorlogviewer.mm @@ -31,6 +31,7 @@ [logScroll setHasVerticalScroller:YES]; [logScroll setAutohidesScrollers:YES]; [logScroll setBorderType:NSNoBorder]; + [logScroll setDrawsBackground:NO]; [logScroll setDocumentView:logView]; [logView release]; [window setContentView:logScroll]; diff --git a/src/osd/modules/debugger/osx/memoryviewer.mm b/src/osd/modules/debugger/osx/memoryviewer.mm index b30a983ac30..8f0c87701c7 100644 --- a/src/osd/modules/debugger/osx/memoryviewer.mm +++ b/src/osd/modules/debugger/osx/memoryviewer.mm @@ -87,6 +87,7 @@ [memoryScroll setHasVerticalScroller:YES]; [memoryScroll setAutohidesScrollers:YES]; [memoryScroll setBorderType:NSNoBorder]; + [memoryScroll setDrawsBackground:NO]; [memoryScroll setDocumentView:memoryView]; [memoryView release]; [[window contentView] addSubview:memoryScroll]; diff --git a/src/osd/modules/debugger/osx/pointsviewer.mm b/src/osd/modules/debugger/osx/pointsviewer.mm index e10633076aa..7875e9c91b3 100644 --- a/src/osd/modules/debugger/osx/pointsviewer.mm +++ b/src/osd/modules/debugger/osx/pointsviewer.mm @@ -72,6 +72,7 @@ [breakScroll setHasVerticalScroller:YES]; [breakScroll setAutohidesScrollers:YES]; [breakScroll setBorderType:NSNoBorder]; + [breakScroll setDrawsBackground:NO]; [breakScroll setDocumentView:breakView]; [breakView release]; breakTab = [[NSTabViewItem alloc] initWithIdentifier:@""]; @@ -87,6 +88,7 @@ [watchScroll setHasVerticalScroller:YES]; [watchScroll setAutohidesScrollers:YES]; [watchScroll setBorderType:NSNoBorder]; + [watchScroll setDrawsBackground:NO]; [watchScroll setDocumentView:watchView]; [watchView release]; watchTab = [[NSTabViewItem alloc] initWithIdentifier:@""]; diff --git a/src/osd/modules/lib/osdobj_common.cpp b/src/osd/modules/lib/osdobj_common.cpp index dcca53b4361..5bacf0c341d 100644 --- a/src/osd/modules/lib/osdobj_common.cpp +++ b/src/osd/modules/lib/osdobj_common.cpp @@ -131,7 +131,7 @@ const options_entry osd_options::s_option_entries[] = { nullptr, nullptr, OPTION_HEADER, "PORTAUDIO OPTIONS" }, { OSDOPTION_PA_API, OSDOPTVAL_NONE, OPTION_STRING, "PortAudio API" }, { OSDOPTION_PA_DEVICE, OSDOPTVAL_NONE, OPTION_STRING, "PortAudio device" }, - { OSDOPTION_PA_LATENCY "(0.001-0.25)", "0", OPTION_FLOAT, "suggested latency in seconds, 0 for default" }, + { OSDOPTION_PA_LATENCY "(0-0.25)", "0", OPTION_FLOAT, "suggested latency in seconds, 0 for default" }, #endif #ifdef SDLMAME_MACOSX diff --git a/src/osd/modules/sound/pa_sound.cpp b/src/osd/modules/sound/pa_sound.cpp index fb92689504f..a54adca958b 100644 --- a/src/osd/modules/sound/pa_sound.cpp +++ b/src/osd/modules/sound/pa_sound.cpp @@ -49,78 +49,75 @@ public: virtual void set_mastervolume(int attenuation); private: - /* Lock free SPSC ring buffer */ + // Lock free SPSC ring buffer template <typename T> struct audio_buffer { T* buf; int size; int reserve; - std::atomic<int> rd_pos, wr_pos; + std::atomic<int> playpos, writepos; - audio_buffer(int size, int reserve) : size(size), reserve(reserve) { - rd_pos = wr_pos = 0; + audio_buffer(int size, int reserve) : size(size + reserve), reserve(reserve) { + playpos = writepos = 0; buf = new T[size](); } ~audio_buffer() { delete[] buf; } int count() { - int diff; - diff = wr_pos - rd_pos; - diff = diff < 0 ? size + diff : diff; - diff -= reserve; - return diff < 0 ? 0 : diff; + int diff = writepos - playpos; + return diff < 0 ? size + diff : diff; } - void increment_wrpos(int n) { - wr_pos = (wr_pos + n) % size; + void increment_writepos(int n) { + writepos.store((writepos + n) % size); } int write(const T* src, int n, int attenuation) { - n = std::min<int>(n, size - count()); + n = std::min<int>(n, size - reserve - count()); - if (wr_pos + n > size) { - att_memcpy(buf + wr_pos, src, sizeof(T) * (size - wr_pos), attenuation); - att_memcpy(buf, src + (size - wr_pos), sizeof(T) * (n - (size - wr_pos)), attenuation); + if (writepos + n > size) { + att_memcpy(buf + writepos, src, sizeof(T) * (size - writepos), attenuation); + att_memcpy(buf, src + (size - writepos), sizeof(T) * (n - (size - writepos)), attenuation); } else { - att_memcpy(buf + wr_pos, src, sizeof(T) * n, attenuation); + att_memcpy(buf + writepos, src, sizeof(T) * n, attenuation); } - increment_wrpos(n); + increment_writepos(n); return n; } - void increment_rdpos(int n) { - rd_pos = (rd_pos + n) % size; + void increment_playpos(int n) { + playpos.store((playpos + n) % size); } int read(T* dst, int n) { n = std::min<int>(n, count()); - if (rd_pos + n > size) { - std::memcpy(dst, buf + rd_pos, sizeof(T) * (size - rd_pos)); - std::memcpy(dst + (size - rd_pos), buf, sizeof(T) * (n - (size - rd_pos))); + if (playpos + n > size) { + std::memcpy(dst, buf + playpos, sizeof(T) * (size - playpos)); + std::memcpy(dst + (size - playpos), buf, sizeof(T) * (n - (size - playpos))); } else { - std::memcpy(dst, buf + rd_pos, sizeof(T) * n); + std::memcpy(dst, buf + playpos, sizeof(T) * n); } - increment_rdpos(n); + increment_playpos(n); return n; } int clear(int n) { - n = std::min<int>(n, size - count()); + n = std::min<int>(n, size - reserve - count()); - if (wr_pos + n > size) { - std::memset(buf + wr_pos, 0, sizeof(T) * (size - wr_pos)); - std::memset(buf, 0, sizeof(T) * (n - (size - wr_pos))); + if (writepos + n > size) { + std::memset(buf + writepos, 0, sizeof(T) * (size - writepos)); + std::memset(buf, 0, sizeof(T) * (n - (size - writepos))); } else { - std::memset(buf + wr_pos, 0, sizeof(T) * n); + std::memset(buf + writepos, 0, sizeof(T) * n); } - increment_wrpos(n); + increment_writepos(n); return n; } @@ -185,7 +182,10 @@ int sound_pa::init(osd_options const &options) m_overflows = 0; m_has_overflowed = false; m_has_underflowed = false; + m_osd_ticks = 0; m_skip_threshold_ticks = 0; + m_osd_tps = osd_ticks_per_second(); + m_buffer_min_ct = INT_MAX; try { m_ab = new audio_buffer<s16>(m_sample_rate, 2); @@ -194,8 +194,6 @@ int sound_pa::init(osd_options const &options) goto error; } - m_osd_tps = osd_ticks_per_second(); - err = Pa_Initialize(); if (err != paNoError) goto pa_error; @@ -342,7 +340,7 @@ int sound_pa::callback(s16* output_buffer, size_t number_of_samples) // if adjustment is less than two milliseconds, don't bother if (adjust / 2 > sample_rate() / 500) { - m_ab->increment_rdpos(adjust); + m_ab->increment_playpos(adjust); m_has_overflowed = true; } @@ -355,9 +353,8 @@ int sound_pa::callback(s16* output_buffer, size_t number_of_samples) m_ab->read(output_buffer, buf_ct); std::memset(output_buffer + buf_ct, 0, (number_of_samples - buf_ct) * sizeof(s16)); - // rd_pos == wr_pos only happens when buffer hasn't received any samples, - // i.e. before update_audio_stream has been called - if (m_ab->rd_pos != m_ab->wr_pos) + // if update_audio_stream has been called, note the underflow + if (m_osd_ticks) m_has_underflowed = true; m_skip_threshold_ticks = m_osd_ticks; @@ -371,9 +368,6 @@ void sound_pa::update_audio_stream(bool is_throttled, const s16 *buffer, int sam if (!sample_rate()) return; - // for determining buffer overflows, take the sample here instead of in the callback - m_osd_ticks = osd_ticks(); - #if LOG_BUFCNT if (m_log.good()) m_log << m_ab->count() << std::endl; @@ -394,6 +388,9 @@ void sound_pa::update_audio_stream(bool is_throttled, const s16 *buffer, int sam } m_ab->write(buffer, samples_this_frame * 2, m_attenuation); + + // for determining buffer overflows, take the sample here instead of in the callback + m_osd_ticks = osd_ticks(); } void sound_pa::set_mastervolume(int attenuation) diff --git a/src/tools/unidasm.cpp b/src/tools/unidasm.cpp index 2c6e58a0f74..e1667a9b9e7 100644 --- a/src/tools/unidasm.cpp +++ b/src/tools/unidasm.cpp @@ -83,6 +83,7 @@ CPU_DISASSEMBLE( coldfire ); CPU_DISASSEMBLE( cop410 ); CPU_DISASSEMBLE( cop420 ); CPU_DISASSEMBLE( cop444 ); +CPU_DISASSEMBLE( cop424 ); CPU_DISASSEMBLE( cp1610 ); CPU_DISASSEMBLE( cquestlin ); CPU_DISASSEMBLE( cquestrot ); @@ -251,6 +252,7 @@ static const dasm_table_entry dasm_table[] = { "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) }, |