summaryrefslogtreecommitdiffstatshomepage
diff options
context:
space:
mode:
-rw-r--r--src/mame/sharp/x68k.cpp169
-rw-r--r--src/mame/sharp/x68k.h24
-rw-r--r--src/mame/sharp/x68k_mouse.cpp103
-rw-r--r--src/mame/sharp/x68k_mouse.h36
4 files changed, 158 insertions, 174 deletions
diff --git a/src/mame/sharp/x68k.cpp b/src/mame/sharp/x68k.cpp
index 8e5def0a501..c6787eeef39 100644
--- a/src/mame/sharp/x68k.cpp
+++ b/src/mame/sharp/x68k.cpp
@@ -119,6 +119,7 @@
#include "x68k.h"
#include "x68k_hdc.h"
#include "x68k_kbd.h"
+#include "x68k_mouse.h"
#include "machine/nvram.h"
@@ -174,127 +175,6 @@ TIMER_CALLBACK_MEMBER(x68k_state::led_callback)
}
-
-// mouse input
-// port B of the Z8530 SCC
-// typically read from the SCC data port on receive buffer full interrupt per byte
-int x68k_state::read_mouse()
-{
- char val = 0;
- char ipt = 0;
-
- if(!(m_scc->get_reg_b(5) & 0x02))
- return 0xff;
-
- switch(m_mouse.inputtype)
- {
- case 0:
- ipt = m_mouse1->read();
- break;
- case 1:
- val = m_mouse2->read();
- ipt = val - m_mouse.last_mouse_x;
- m_mouse.last_mouse_x = val;
- break;
- case 2:
- val = m_mouse3->read();
- ipt = val - m_mouse.last_mouse_y;
- m_mouse.last_mouse_y = val;
- break;
- }
- m_mouse.inputtype++;
- if(m_mouse.inputtype > 2)
- {
- int i_val = m_scc->get_reg_b(0);
- m_mouse.inputtype = 0;
- m_mouse.bufferempty = 1;
- i_val &= ~0x01;
- m_scc->set_reg_b(0, i_val);
- LOGMASKED(LOG_SYS, "SCC: mouse buffer empty\n");
- }
-
- return ipt;
-}
-
-/*
- 0xe98001 - Z8530 command port B
- 0xe98003 - Z8530 data port B (mouse input)
- 0xe98005 - Z8530 command port A
- 0xe98007 - Z8530 data port A (RS232)
-*/
-uint16_t x68k_state::scc_r(offs_t offset)
-{
- offset %= 4;
- switch(offset)
- {
- case 0:
- return m_scc->reg_r(0);
- case 1:
- return read_mouse();
- case 2:
- return m_scc->reg_r(1);
- case 3:
- return m_scc->reg_r(3);
- default:
- return 0xff;
- }
-}
-
-void x68k_state::scc_w(offs_t offset, uint16_t data)
-{
- offset %= 4;
-
- switch(offset)
- {
- case 0:
- m_scc->reg_w(0,(uint8_t)data);
- if((m_scc->get_reg_b(5) & 0x02) != m_scc_prev)
- {
- if(m_scc->get_reg_b(5) & 0x02) // Request to Send
- {
- int val = m_scc->get_reg_b(0);
- m_mouse.bufferempty = 0;
- val |= 0x01;
- m_scc->set_reg_b(0,val);
- }
- }
- break;
- case 1:
- m_scc->reg_w(2,(uint8_t)data);
- break;
- case 2:
- m_scc->reg_w(1,(uint8_t)data);
- break;
- case 3:
- m_scc->reg_w(3,(uint8_t)data);
- break;
- }
- m_scc_prev = m_scc->get_reg_b(5) & 0x02;
-}
-
-TIMER_CALLBACK_MEMBER(x68k_state::scc_ack)
-{
- if(m_mouse.bufferempty != 0) // nothing to do if the mouse data buffer is empty
- return;
-
-// if((m_ioc.irqstatus & 0xc0) != 0)
-// return;
-
- // hard-code the IRQ vector for now, until the SCC code is more complete
- if((m_scc->get_reg_a(9) & 0x08) || (m_scc->get_reg_b(9) & 0x08)) // SCC reg WR9 is the same for both channels
- {
- if((m_scc->get_reg_b(1) & 0x18) != 0) // if bits 3 and 4 of WR1 are 0, then Rx IRQs are disabled on this channel
- {
- if(m_scc->get_reg_b(5) & 0x02) // RTS signal
- {
- m_mouse.irqactive = true;
- m_mouse.irqvector = 0x54;
- update_ipl();
- }
- }
- }
-}
-
void x68k_state::set_adpcm()
{
uint32_t rate = adpcm_div[m_adpcm.rate];
@@ -833,7 +713,7 @@ void x68k_state::update_ipl()
new_ipl = 7;
else if (m_mfp_int)
new_ipl = 6;
- else if (m_mouse.irqactive)
+ else if (m_scc_int)
new_ipl = 5;
else if (m_exp_irq4[0] || m_exp_irq4[1])
new_ipl = 4;
@@ -946,18 +826,6 @@ uint8_t x68k_state::iack4()
return 0x18; // spurious interrupt
}
-uint8_t x68k_state::iack5()
-{
- if (!machine().side_effects_disabled())
- {
- m_mouse.irqactive = false;
- update_ipl();
- }
-
- // TODO: use vector from SCC
- return m_mouse.irqvector;
-}
-
void x68k_state::cpu_space_map(address_map &map)
{
map.global_mask(0xffffff);
@@ -965,7 +833,7 @@ void x68k_state::cpu_space_map(address_map &map)
map(0xfffff5, 0xfffff5).r(FUNC(x68k_state::iack2));
map(0xfffff7, 0xfffff7).r(m_hd63450, FUNC(hd63450_device::iack));
map(0xfffff9, 0xfffff9).r(FUNC(x68k_state::iack4));
- map(0xfffffb, 0xfffffb).r(FUNC(x68k_state::iack5));
+ map(0xfffffb, 0xfffffb).lr8(NAME([this]() { return m_scc->m1_r(); }));
map(0xfffffd, 0xfffffd).r(m_mfpdev, FUNC(mc68901_device::get_vector));
map(0xffffff, 0xffffff).lr8(NAME([] () { return m68000_base_device::autovector(7); }));
}
@@ -1005,7 +873,7 @@ void x68k_state::x68k_base_map(address_map &map)
map(0xe90000, 0xe91fff).rw(m_ym2151, FUNC(ym2151_device::read), FUNC(ym2151_device::write)).umask16(0x00ff);
map(0xe94000, 0xe94003).m(m_upd72065, FUNC(upd72065_device::map)).umask16(0x00ff);
map(0xe94004, 0xe94007).rw(FUNC(x68k_state::fdc_r), FUNC(x68k_state::fdc_w));
- map(0xe98000, 0xe99fff).rw(FUNC(x68k_state::scc_r), FUNC(x68k_state::scc_w));
+ map(0xe98000, 0xe99fff).rw(m_scc, FUNC(scc8530_device::ab_dc_r), FUNC(scc8530_device::ab_dc_w)).umask16(0x00ff);
map(0xe9a000, 0xe9bfff).rw(FUNC(x68k_state::ppi_r), FUNC(x68k_state::ppi_w));
map(0xe9c000, 0xe9dfff).rw(FUNC(x68k_state::ioc_r), FUNC(x68k_state::ioc_w));
map(0xe9e000, 0xe9e3ff).rw(FUNC(x68k_state::exp_r), FUNC(x68k_state::exp_w)); // FPU (Optional)
@@ -1068,16 +936,6 @@ static INPUT_PORTS_START( x68000 )
PORT_CONFNAME( 0x02, 0x02, "Enable fake bus errors")
PORT_CONFSETTING( 0x00, DEF_STR( Off ))
PORT_CONFSETTING( 0x02, DEF_STR( On ))
-
- PORT_START("mouse1") // mouse buttons
- PORT_BIT( 0x00000001, IP_ACTIVE_HIGH, IPT_BUTTON9) PORT_NAME("Left mouse button") PORT_CODE(MOUSECODE_BUTTON1)
- PORT_BIT( 0x00000002, IP_ACTIVE_HIGH, IPT_BUTTON10) PORT_NAME("Right mouse button") PORT_CODE(MOUSECODE_BUTTON2)
-
- PORT_START("mouse2") // X-axis
- PORT_BIT( 0xff, 0x00, IPT_MOUSE_X) PORT_SENSITIVITY(100) PORT_KEYDELTA(0) PORT_PLAYER(1)
-
- PORT_START("mouse3") // Y-axis
- PORT_BIT( 0xff, 0x00, IPT_MOUSE_Y) PORT_SENSITIVITY(100) PORT_KEYDELTA(0) PORT_PLAYER(1)
INPUT_PORTS_END
void x68k_state::floppy_load_unload(bool load, floppy_image_device *dev)
@@ -1151,10 +1009,6 @@ void x68k_state::machine_start()
m_spriteram = (uint16_t*)(memregion("user1")->base());
space.install_ram(0x000000,m_ram->size()-1,m_ram->pointer());
- // start mouse timer
- m_mouse_timer->adjust(attotime::zero, 0, attotime::from_msec(1)); // a guess for now
- m_mouse.inputtype = 0;
-
// start LED timer
m_led_timer->adjust(attotime::zero, 0, attotime::from_msec(400));
@@ -1173,11 +1027,11 @@ void x68k_state::machine_start()
m_dmac_int = false;
m_mfp_int = false;
+ m_scc_int = false;
m_exp_irq2[0] = m_exp_irq2[1] = false;
m_exp_irq4[0] = m_exp_irq4[1] = false;
m_exp_nmi[0] = m_exp_nmi[1] = false;
m_ioc.irqstatus = 0;
- m_mouse.irqactive = false;
m_current_ipl = 0;
m_adpcm.rate = 0;
m_adpcm.clock = 0;
@@ -1204,7 +1058,6 @@ void x68k_state::driver_start()
// copy last half of BIOS to a user region, to use for initial startup
memcpy(user2,(rom+0xff0000),0x10000);
- m_mouse_timer = timer_alloc(FUNC(x68ksupr_state::scc_ack), this);
m_led_timer = timer_alloc(FUNC(x68ksupr_state::led_callback), this);
m_fdc_tc = timer_alloc(FUNC(x68ksupr_state::floppy_tc_tick), this);
m_adpcm_timer = timer_alloc(FUNC(x68ksupr_state::adpcm_drq_tick), this);
@@ -1249,6 +1102,11 @@ static void keyboard_devices(device_slot_interface &device)
device.option_add("x68k", X68K_KEYBOARD);
}
+static void mouse_devices(device_slot_interface &device)
+{
+ device.option_add("x68k", X68K_MOUSE);
+}
+
void x68k_state::x68000_base(machine_config &config)
{
config.set_maximum_quantum(attotime::from_hz(60));
@@ -1281,7 +1139,12 @@ void x68k_state::x68000_base(machine_config &config)
m_hd63450->dma_read<0>().set("upd72065", FUNC(upd72065_device::dma_r));
m_hd63450->dma_write<0>().set("upd72065", FUNC(upd72065_device::dma_w));
- SCC8530(config, m_scc, 40_MHz_XTAL / 8);
+ SCC8530N(config, m_scc, 40_MHz_XTAL / 8);
+ m_scc->out_int_callback().set([this](int state) { m_scc_int = state; update_ipl(); });
+
+ rs232_port_device &mouse(RS232_PORT(config, "mouse_port", mouse_devices, "x68k"));
+ mouse.rxd_handler().set(m_scc, FUNC(scc8530_device::rxb_w));
+ m_scc->out_rtsb_callback().set(mouse, FUNC(rs232_port_device::write_rts));
RP5C15(config, m_rtc, 32.768_kHz_XTAL);
m_rtc->alarm().set(m_mfpdev, FUNC(mc68901_device::i0_w));
diff --git a/src/mame/sharp/x68k.h b/src/mame/sharp/x68k.h
index 2c1dc8552af..b5c40b213b6 100644
--- a/src/mame/sharp/x68k.h
+++ b/src/mame/sharp/x68k.h
@@ -20,7 +20,7 @@
#include "cpu/m68000/m68000.h"
#include "cpu/m68000/m68030.h"
#include "imagedev/floppy.h"
-#include "machine/8530scc.h"
+#include "machine/z80scc.h"
#include "machine/hd63450.h"
#include "machine/i8255.h"
#include "machine/mb87030.h"
@@ -64,9 +64,6 @@ public:
, m_expansion(*this, "exp%u", 1U)
, m_adpcm_out(*this, {"adpcm_outl", "adpcm_outr"})
, m_options(*this, "options")
- , m_mouse1(*this, "mouse1")
- , m_mouse2(*this, "mouse2")
- , m_mouse3(*this, "mouse3")
, m_eject_drv_out(*this, "eject_drv%u", 0U)
, m_ctrl_drv_out(*this, "ctrl_drv%u", 0U)
, m_access_drv_out(*this, "access_drv%u", 0U)
@@ -100,7 +97,7 @@ protected:
required_device<palette_device> m_pcgpalette;
required_device<mc68901_device> m_mfpdev;
required_device<rp5c15_device> m_rtc;
- required_device<scc8530_legacy_device> m_scc;
+ required_device<scc8530_device> m_scc;
required_device<ym2151_device> m_ym2151;
required_device<i8255_device> m_ppi;
required_device<screen_device> m_screen;
@@ -111,9 +108,6 @@ protected:
required_device_array<filter_volume_device, 2> m_adpcm_out;
required_ioport m_options;
- required_ioport m_mouse1;
- required_ioport m_mouse2;
- required_ioport m_mouse3;
output_finder<4> m_eject_drv_out;
output_finder<4> m_ctrl_drv_out;
@@ -178,24 +172,15 @@ protected:
uint8_t hdcvector = 0;
uint8_t prnvector = 0;
} m_ioc;
- struct
- {
- int inputtype = 0; // determines which input is to be received
- bool irqactive = false; // true if IRQ is being serviced
- uint8_t irqvector = 0;
- char last_mouse_x = 0; // previous mouse x-axis value
- char last_mouse_y = 0; // previous mouse y-axis value
- int bufferempty = 0; // non-zero if buffer is empty
- } m_mouse;
uint8_t m_ppi_portc = 0;
bool m_dmac_int = false;
bool m_mfp_int = false;
+ bool m_scc_int = false;
bool m_exp_irq2[2]{};
bool m_exp_irq4[2]{};
bool m_exp_nmi[2]{};
uint8_t m_current_ipl = 0;
int m_led_state = 0;
- emu_timer* m_mouse_timer = nullptr;
emu_timer* m_led_timer = nullptr;
unsigned char m_scc_prev = 0;
emu_timer* m_fdc_tc = nullptr;
@@ -233,7 +218,6 @@ protected:
void dma_irq(int state);
void dma_end(offs_t offset, uint8_t data);
- int read_mouse();
void set_adpcm();
void fm_irq(int state);
@@ -241,8 +225,6 @@ protected:
template <int N> void irq4_line(int state);
template <int N> void nmi_line(int state);
- void scc_w(offs_t offset, uint16_t data);
- uint16_t scc_r(offs_t offset);
void fdc_w(offs_t offset, uint16_t data);
uint16_t fdc_r(offs_t offset);
void ioc_w(offs_t offset, uint16_t data);
diff --git a/src/mame/sharp/x68k_mouse.cpp b/src/mame/sharp/x68k_mouse.cpp
new file mode 100644
index 00000000000..f30cfc7d25d
--- /dev/null
+++ b/src/mame/sharp/x68k_mouse.cpp
@@ -0,0 +1,103 @@
+// license:BSD-3-Clause
+// copyright-holders:Patrick Mackinlay
+
+#include "emu.h"
+#include "x68k_mouse.h"
+
+#include <algorithm>
+
+//#define VERBOSE (LOG_GENERAL)
+#include "logmacro.h"
+
+enum status_mask : u8
+{
+ STS_RB = 0x01, // right button
+ STS_LB = 0x02, // left button
+ STS_OX = 0x10, // x overflow
+ STS_UX = 0x20, // x underflow
+ STS_OY = 0x40, // y overflow
+ STS_UY = 0x80, // y underflow
+};
+
+DEFINE_DEVICE_TYPE(X68K_MOUSE, x68k_mouse_device, "x68k_mouse", "Sharp X68000 Mouse")
+
+x68k_mouse_device::x68k_mouse_device(machine_config const &mconfig, char const *tag, device_t *owner, u32 clock)
+ : buffered_rs232_device<3>(mconfig, X68K_MOUSE, tag, owner, clock)
+ , m_buttons(*this, "BTN")
+ , m_x_axis(*this, "X")
+ , m_y_axis(*this, "Y")
+{
+}
+
+void x68k_mouse_device::device_start()
+{
+ buffered_rs232_device<3>::device_start();
+
+ save_item(NAME(m_b));
+ save_item(NAME(m_x));
+ save_item(NAME(m_y));
+
+ set_data_frame(1, 8, PARITY_NONE, STOP_BITS_2);
+ set_tra_rate(4'800);
+
+ transmit_register_reset();
+
+ m_b = 0;
+ m_x = 0;
+ m_y = 0;
+}
+
+s16 read_axis(ioport_port &port, u16 &old_val)
+{
+ u16 const new_val = port.read();
+ s16 const delta = new_val - old_val;
+
+ old_val = new_val;
+
+ return delta;
+}
+
+void x68k_mouse_device::input_rts(int state)
+{
+ if (!state && fifo_empty())
+ {
+ u8 status = m_buttons->read();
+ s16 const dx = read_axis(*m_x_axis, m_x);
+ s16 const dy = read_axis(*m_y_axis, m_y);
+
+ if (dx || dy || m_b != status)
+ {
+ if (dy < -128)
+ status |= STS_UY;
+ if (dy > 127)
+ status |= STS_OY;
+ if (dx < -128)
+ status |= STS_UX;
+ if (dx > 127)
+ status |= STS_OX;
+
+ transmit_byte(status);
+ transmit_byte(s8(std::clamp<s16>(dx, -128, 127)));
+ transmit_byte(s8(std::clamp<s16>(dy, -128, 127)));
+
+ m_b = status & (STS_LB | STS_RB);
+ }
+ }
+}
+
+INPUT_PORTS_START(x68k)
+ PORT_START("BTN")
+ PORT_BIT(0x0002, IP_ACTIVE_HIGH, IPT_BUTTON1) PORT_CODE(MOUSECODE_BUTTON1)
+ PORT_BIT(0x0001, IP_ACTIVE_HIGH, IPT_BUTTON2) PORT_CODE(MOUSECODE_BUTTON2)
+
+ PORT_START("X")
+ PORT_BIT(0xfff, 0x000, IPT_MOUSE_X) PORT_SENSITIVITY(100) PORT_KEYDELTA(0)
+
+ PORT_START("Y")
+ PORT_BIT(0xfff, 0x000, IPT_MOUSE_Y) PORT_SENSITIVITY(100) PORT_KEYDELTA(0)
+INPUT_PORTS_END
+
+ioport_constructor x68k_mouse_device::device_input_ports() const
+{
+ return INPUT_PORTS_NAME(x68k);
+}
diff --git a/src/mame/sharp/x68k_mouse.h b/src/mame/sharp/x68k_mouse.h
new file mode 100644
index 00000000000..9028c831fe4
--- /dev/null
+++ b/src/mame/sharp/x68k_mouse.h
@@ -0,0 +1,36 @@
+// license:BSD-3-Clause
+// copyright-holders:Patrick Mackinlay
+
+#ifndef MAME_SHARP_X68K_MOUSE_H
+#define MAME_SHARP_X68K_MOUSE_H
+
+#pragma once
+
+#include "bus/rs232/rs232.h"
+
+class x68k_mouse_device : public buffered_rs232_device<3>
+{
+public:
+ x68k_mouse_device(machine_config const &mconfig, char const *tag, device_t *owner, u32 clock = 0);
+
+ virtual void input_rts(int state) override; // MSCTRL (active low)
+
+protected:
+ virtual ioport_constructor device_input_ports() const override ATTR_COLD;
+ virtual void device_start() override ATTR_COLD;
+
+ virtual void received_byte(u8 byte) override {}
+
+private:
+ required_ioport m_buttons;
+ required_ioport m_x_axis;
+ required_ioport m_y_axis;
+
+ u8 m_b;
+ u16 m_x;
+ u16 m_y;
+};
+
+DECLARE_DEVICE_TYPE(X68K_MOUSE, x68k_mouse_device)
+
+#endif // MAME_SHARP_X68K_MOUSE_H