tandy2k: add mouse [Carl]

This commit is contained in:
cracyc 2019-02-16 14:53:30 -06:00
parent f7b53ed1bc
commit dbb4a1fb18
2 changed files with 186 additions and 5 deletions

View File

@ -14,11 +14,11 @@
- HDL is also connected to WP/TS input where TS is used to detect motor status
- 3 second motor off delay timer
- video (video RAM is at memory top - 0x1400, i.e. 0x1ec00)
- keyboard ROM
- hires graphics board
- keyboard ROM, same as earlier tandy 1000
- WD1010
- hard disk
- mouse
- clock/mouse 8042 mcu ROM, probably same as tandy 1000 isa clock/mouse adapter
- sab3019 rtc
*/
@ -219,6 +219,77 @@ READ8_MEMBER( tandy2k_state::kbint_clr_r )
return 0xff;
}
READ8_MEMBER( tandy2k_state::clkmouse_r )
{
uint8_t ret = 0;
switch (offset)
{
case 0:
if (!m_clkmouse_cnt)
return 0;
ret = m_clkmouse_cmd[--m_clkmouse_cnt];
m_pic1->ir2_w(0);
if (m_clkmouse_cnt > 0)
m_mcu_delay->adjust(attotime::from_msec(1));
break;
case 2:
ret = m_buttons->read();
if (m_clkmouse_cnt)
ret |= 1;
break;
}
return ret;
}
WRITE8_MEMBER( tandy2k_state::clkmouse_w )
{
switch (offset)
{
case 0:
m_pic1->ir2_w(0);
if (m_clkmouse_cnt < 8)
m_clkmouse_cmd[m_clkmouse_cnt++] = data;
break;
case 1:
break;
case 2:
if (m_clkmouse_cnt < 8)
m_clkmouse_cmd[m_clkmouse_cnt++] = data;
switch (m_clkmouse_cmd[0])
{
case 0x01: //set time
break;
case 0x02: //read time
break;
case 0x08:
if(m_clkmouse_cmd[1] > 0)
m_clkmouse_irq |= MO_IRQ;
else
m_clkmouse_irq &= ~MO_IRQ;
if(m_clkmouse_cmd[2] > 0)
m_clkmouse_irq |= BT_IRQ;
else
m_clkmouse_irq &= ~BT_IRQ;
break;
case 0x20:
if(m_clkmouse_cmd[1] > 0)
m_mouse_timer->adjust(attotime::from_hz(40), 0, attotime::from_hz(40));
else
m_mouse_timer->adjust(attotime::never);
break;
}
m_clkmouse_cnt = 0;
break;
case 3:
m_pic1->ir2_w(0);
m_clkmouse_cnt = 0;
m_clkmouse_irq = 0;
m_mouse_x = m_x_axis->read();
m_mouse_y = m_y_axis->read();
break;
}
}
READ8_MEMBER( tandy2k_state::fldtc_r )
{
if (LOG) logerror("FLDTC\n");
@ -315,6 +386,7 @@ void tandy2k_state::tandy2k_io(address_map &map)
map(0x00180, 0x00180).r(FUNC(tandy2k_state::hires_status_r)).umask16(0x00ff);
map(0x00180, 0x0018f).mirror(0x10).w(m_colpal, FUNC(palette_device::write8)).umask16(0x00ff).share("colpal");
map(0x001a0, 0x001a0).w(FUNC(tandy2k_state::hires_plane_w)).umask16(0x00ff);
map(0x002fc, 0x002ff).rw(FUNC(tandy2k_state::clkmouse_r), FUNC(tandy2k_state::clkmouse_w));
}
void tandy2k_state::tandy2k_hd_io(address_map &map)
@ -368,8 +440,47 @@ static INPUT_PORTS_START( tandy2k )
PORT_BIT(0x0100, IP_ACTIVE_HIGH, IPT_KEYBOARD) PORT_NAME("Home") PORT_CODE(KEYCODE_HOME) /* HOME 58 D8 */
PORT_BIT(0x0200, IP_ACTIVE_HIGH, IPT_KEYBOARD) PORT_NAME("F11") PORT_CODE(KEYCODE_F11) /* F11 59 D9 */
PORT_BIT(0x0400, IP_ACTIVE_HIGH, IPT_KEYBOARD) PORT_NAME("F12") PORT_CODE(KEYCODE_F12) /* F12 5a Da */
PORT_START("MOUSEBTN")
PORT_BIT( 0xff8f, IP_ACTIVE_HIGH, IPT_UNUSED )
PORT_BIT( 0x0010, IP_ACTIVE_LOW, IPT_BUTTON1 ) PORT_CODE(MOUSECODE_BUTTON1) PORT_CHANGED_MEMBER(DEVICE_SELF, tandy2k_state, input_changed, nullptr)
PORT_BIT( 0x0020, IP_ACTIVE_LOW, IPT_BUTTON2 ) PORT_CODE(MOUSECODE_BUTTON2) PORT_CHANGED_MEMBER(DEVICE_SELF, tandy2k_state, input_changed, nullptr)
PORT_BIT( 0x0040, IP_ACTIVE_LOW, IPT_UNUSED ) /* this would be button three but AFAIK no tandy mouse ever had one */
PORT_START("MOUSEX")
PORT_BIT( 0xffff, 0x00, IPT_MOUSE_X ) PORT_SENSITIVITY(50) PORT_KEYDELTA(0) PORT_CHANGED_MEMBER(DEVICE_SELF, tandy2k_state, input_changed, nullptr)
PORT_START("MOUSEY")
PORT_BIT( 0xffff, 0x00, IPT_MOUSE_Y ) PORT_SENSITIVITY(50) PORT_KEYDELTA(0) PORT_CHANGED_MEMBER(DEVICE_SELF, tandy2k_state, input_changed, nullptr)
INPUT_PORTS_END
INPUT_CHANGED_MEMBER(tandy2k_state::input_changed)
{
if (m_clkmouse_cnt || !m_clkmouse_irq)
return;
if ((m_clkmouse_irq & BT_IRQ) && (field.name()[5] == 'B'))
{
m_clkmouse_cnt = 1;
m_clkmouse_cmd[0] = 'B';
}
else if ((m_clkmouse_irq & MO_IRQ))
{
uint16_t x = m_x_axis->read();
uint16_t y = m_y_axis->read();
uint16_t dx = x - m_mouse_x;
uint16_t dy = y - m_mouse_y;
m_mouse_x = x;
m_mouse_y = y;
m_clkmouse_cnt = 5;
m_clkmouse_cmd[4] = 'M';
m_clkmouse_cmd[3] = dx & 0xff;
m_clkmouse_cmd[2] = dx >> 8;
m_clkmouse_cmd[1] = dy & 0xff;
m_clkmouse_cmd[0] = dy >> 8;
}
m_pic1->ir2_w(1);
}
// Video
uint32_t tandy2k_state::screen_update(screen_device &screen, bitmap_rgb32 &bitmap, const rectangle &cliprect)
@ -788,7 +899,8 @@ void tandy2k_state::machine_start()
program.install_ram(0x00000, ram_size - 1, ram);
m_char_ram.allocate(0x1000);
m_hires_en = 0;
m_mouse_timer = timer_alloc(MOUS_TIMER);
m_mcu_delay = timer_alloc(MCU_DELAY);
// register for state saving
save_item(NAME(m_dma_mux));
@ -804,6 +916,19 @@ void tandy2k_state::machine_start()
save_item(NAME(m_clkcnt));
save_item(NAME(m_outspkr));
save_item(NAME(m_spkrdata));
save_item(NAME(m_clkmouse_cmd));
save_item(NAME(m_clkmouse_cnt));
save_item(NAME(m_clkmouse_irq));
save_item(NAME(m_mouse_x));
save_item(NAME(m_mouse_y));
save_item(NAME(m_hires_en));
}
void tandy2k_state::machine_reset()
{
m_hires_en = 0;
m_clkmouse_cnt = 0;
m_clkmouse_irq = 0;
}
void tandy2k_state::device_reset_after_children()
@ -811,6 +936,33 @@ void tandy2k_state::device_reset_after_children()
m_pc_keyboard->enable(0);
}
void tandy2k_state::device_timer(emu_timer &timer, device_timer_id id, int param, void *ptr)
{
switch (id)
{
case MOUS_TIMER:
{
uint16_t x = m_x_axis->read();
uint16_t y = m_y_axis->read();
uint16_t dx = x - m_mouse_x;
uint16_t dy = y - m_mouse_y;
m_mouse_x = x;
m_mouse_y = y;
m_clkmouse_cnt = 5;
m_clkmouse_cmd[4] = 'A';
m_clkmouse_cmd[3] = dx & 0xff;
m_clkmouse_cmd[2] = dx >> 8;
m_clkmouse_cmd[1] = dy & 0xff;
m_clkmouse_cmd[0] = dy >> 8;
m_pic1->ir2_w(1);
break;
}
case MCU_DELAY:
m_pic1->ir2_w(1);
break;
}
}
rgb_t tandy2k_state::IRGB(uint32_t raw)
{
uint8_t i = (raw >> 3) & 1;

View File

@ -100,7 +100,10 @@ public:
m_centronics_fault(0),
m_centronics_select(0),
m_centronics_perror(0),
m_centronics_busy(0)
m_centronics_busy(0),
m_buttons(*this, "MOUSEBTN"),
m_x_axis(*this, "MOUSEX"),
m_y_axis(*this, "MOUSEY")
{
for (auto & elem : m_busdmarq)
{
@ -110,6 +113,7 @@ public:
void tandy2k_hd(machine_config &config);
void tandy2k(machine_config &config);
DECLARE_INPUT_CHANGED_MEMBER(input_changed);
private:
required_device<i80186_cpu_device> m_maincpu;
@ -138,7 +142,9 @@ private:
required_device<pc_keyboard_device> m_pc_keyboard; // temporary until the tandy keyboard has a rom dump
virtual void machine_start() override;
virtual void machine_reset() override;
virtual void device_reset_after_children() override;
virtual void device_timer(emu_timer &timer, device_timer_id id, int param, void *ptr) override;
uint32_t screen_update(screen_device &screen, bitmap_rgb32 &bitmap, const rectangle &cliprect);
@ -176,6 +182,8 @@ private:
DECLARE_WRITE8_MEMBER( drb_attr_w );
DECLARE_WRITE_LINE_MEMBER( kbdclk_w );
DECLARE_WRITE_LINE_MEMBER( kbddat_w );
DECLARE_READ8_MEMBER( clkmouse_r );
DECLARE_WRITE8_MEMBER( clkmouse_w );
DECLARE_READ8_MEMBER( irq_callback );
DECLARE_WRITE_LINE_MEMBER( fdc_drq_w );
DECLARE_WRITE_LINE_MEMBER( fdc_hdl_w );
@ -240,11 +248,32 @@ private:
int m_centronics_perror;
int m_centronics_busy;
enum
{
MO_IRQ = 1,
BT_IRQ = 2
};
enum
{
MOUS_TIMER,
MCU_DELAY
};
uint8_t m_clkmouse_cmd[8];
int m_clkmouse_cnt;
uint8_t m_clkmouse_irq;
uint16_t m_mouse_x, m_mouse_y;
emu_timer *m_mouse_timer;
emu_timer *m_mcu_delay;
void tandy2k_hd_io(address_map &map);
void tandy2k_io(address_map &map);
void tandy2k_mem(address_map &map);
void vpac_mem(address_map &map);
void vrambank_mem(address_map &map);
required_ioport m_buttons, m_x_axis, m_y_axis;
};
#endif // MAME_INCLUDES_TANDY2K_H