Skip to content

Commit

Permalink
Move mouse to optional device, add timer to fix density
Browse files Browse the repository at this point in the history
  • Loading branch information
boamaod committed Dec 26, 2024
1 parent 97370cb commit c64a230
Show file tree
Hide file tree
Showing 3 changed files with 162 additions and 102 deletions.
119 changes: 17 additions & 102 deletions src/mame/ussr/juku.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -33,6 +33,8 @@

#include "emu.h"

#include "jukumouse.h"

#include "cpu/i8085/i8085.h"
#include "imagedev/floppy.h"
#include "machine/74148.h"
Expand All @@ -44,6 +46,7 @@
#include "machine/wd_fdc.h"
#include "sound/spkrdev.h"

#include "emuopts.h"
#include "screen.h"
#include "softlist_dev.h"
#include "speaker.h"
Expand Down Expand Up @@ -92,15 +95,11 @@ class juku_state : public driver_device
m_key_special(*this, "SPECIAL"),
m_screen(*this, "screen"),
m_speaker(*this, "speaker"),
m_mouse_x(*this, "MOUSE_X"),
m_mouse_y(*this, "MOUSE_Y"),
m_mouse_b(*this, "BUTTONS")
m_mouse(*this, "mouse")
{ }

void juku(machine_config &config);

DECLARE_INPUT_CHANGED_MEMBER(mouse_update);

protected:
virtual void machine_start() override ATTR_COLD;
virtual void machine_reset() override ATTR_COLD;
Expand All @@ -119,7 +118,7 @@ class juku_state : public driver_device
required_ioport m_key_special;
required_device<screen_device> m_screen;
required_device<speaker_sound_device> m_speaker;
optional_ioport m_mouse_x, m_mouse_y, m_mouse_b;
optional_device<juku_mouse_device> m_mouse;

int32_t m_width, m_height, m_hbporch, m_vbporch;

Expand All @@ -142,10 +141,6 @@ class juku_state : public driver_device
uint8_t pio0_portb_r();
void pio0_portc_w(uint8_t data);

uint8_t mouse_port_r();
uint8_t m_prev_mouse_x, m_prev_mouse_y;
uint8_t m_prev_mouse_byte;

void screen_width(uint8_t data);
void screen_hblank_period(uint8_t data);
void screen_hfporch(uint8_t data);
Expand Down Expand Up @@ -216,7 +211,6 @@ void juku_state::io_map(address_map &map)
map(0x1f, 0x1f).rw(FUNC(juku_state::fdc_data_r), FUNC(juku_state::fdc_data_w));
// mapping for cassette version (E5101?)
// map(0x1c, 0x1d).rw(m_sio[1], FUNC(i8251_device::read), FUNC(i8251_device::write));
map(0x80, 0x80).r(FUNC(juku_state::mouse_port_r));
}


Expand Down Expand Up @@ -408,17 +402,6 @@ static INPUT_PORTS_START( juku )
PORT_START("SPECIAL")
PORT_BIT(0x40, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_CODE(KEYCODE_LSHIFT) PORT_CODE(KEYCODE_RSHIFT) PORT_CHAR(UCHAR_SHIFT_1)
PORT_BIT(0x80, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_CODE(KEYCODE_LCONTROL) PORT_CODE(KEYCODE_RCONTROL) PORT_CHAR(UCHAR_SHIFT_2)

// Optional mouse at system port X1
PORT_START("MOUSE_X")
PORT_BIT( 0xff, 0x00, IPT_MOUSE_X ) PORT_CODE(MOUSECODE_X) PORT_SENSITIVITY(50) PORT_CHANGED_MEMBER(DEVICE_SELF, FUNC(juku_state::mouse_update), 1)

PORT_START("MOUSE_Y")
PORT_BIT( 0xff, 0x00, IPT_MOUSE_Y ) PORT_CODE(MOUSECODE_Y) PORT_SENSITIVITY(50) PORT_CHANGED_MEMBER(DEVICE_SELF, FUNC(juku_state::mouse_update), 1)

PORT_START("BUTTONS")
PORT_BIT(0x02, IP_ACTIVE_HIGH, IPT_BUTTON1) PORT_CODE(MOUSECODE_BUTTON1) PORT_NAME("Left Button") PORT_CHANGED_MEMBER(DEVICE_SELF, FUNC(juku_state::mouse_update), 1)
PORT_BIT(0x01, IP_ACTIVE_HIGH, IPT_BUTTON2) PORT_CODE(MOUSECODE_BUTTON2) PORT_NAME("Right Button") PORT_CHANGED_MEMBER(DEVICE_SELF, FUNC(juku_state::mouse_update), 1)
INPUT_PORTS_END


Expand Down Expand Up @@ -605,75 +588,6 @@ void juku_state::speaker_w(int state)
}


//**************************************************************************
// MOUSE
//**************************************************************************

/*
* Calculate positive/negative delta from old and new relative value
*/
inline int delta(int o, int n)
{
if(o>n) {
if(o-n<128) return n-o;
else return n+255-o;
}
if(o<n) {
if(n-o<128) return n-o;
else return n-255-o;
}

return 0;
}

uint8_t juku_state::mouse_port_r()
{
// 7------- always 1
// -6------ always 0
// --5----- vertical active
// ---4---- vertical direction
// ----3--- horizontal active
// -----2-- horizontal direction
// ------1- left button
// -------0 right button

uint8_t data = 0b10000000;
int x = m_mouse_x->read(), y = m_mouse_y->read();
int dx = delta(m_prev_mouse_x, x);
int dy = delta(m_prev_mouse_y, y);

data |= m_mouse_b->read();

if (dx!=0) {
data |= dx > 0 ? 0b00001000 : 0b00001100;
m_prev_mouse_x = x;
}

if (dy!=0) {
data |= dy > 0 ? 0b00110000 : 0b00100000;
m_prev_mouse_y = y;
}

if (m_prev_mouse_byte != data) {
m_prev_mouse_byte = data;

LOG("m: ");
for (int i = 7; i >= 0; i--)
LOG("%d", BIT(data, i));
LOG(" \n");
}

return data;
}

INPUT_CHANGED_MEMBER(juku_state::mouse_update)
{

m_pic->ir6_w(CLEAR_LINE);
m_pic->ir6_w(HOLD_LINE);
}


//**************************************************************************
// MACHINE EMULATION
//**************************************************************************
Expand Down Expand Up @@ -749,6 +663,9 @@ void juku_state::machine_start()
membank("ram_4000")->set_base(&m_ram[0x4000]);
membank("ram_c000")->set_base(&m_ram[0xc000]);

if (m_mouse.found() && strcmp(mconfig().options().mouse_device(), "none") != 0)
m_maincpu->space(AS_IO).install_read_handler(0x80, 0x80, read8smo_delegate(*m_mouse, FUNC(juku_mouse_device::mouse_port_r)));

// register for save states
save_item(NAME(m_width));
save_item(NAME(m_height));
Expand All @@ -762,9 +679,6 @@ void juku_state::machine_start()
save_item(NAME(m_beep_state));
save_item(NAME(m_beep_level));
save_item(NAME(m_fdc_cur_cmd));
save_item(NAME(m_prev_mouse_byte));
save_item(NAME(m_prev_mouse_y));
save_item(NAME(m_prev_mouse_x));
save_pointer(NAME(m_ram), 0x10000);
}

Expand All @@ -782,9 +696,6 @@ void juku_state::machine_reset()
m_vblank_period_lsb = -1;
m_monitor_bits = 0U;
m_empty_screen_on_update = 0;
m_prev_mouse_byte = 0;
m_prev_mouse_y = 0;
m_prev_mouse_x = 0;
}


Expand All @@ -798,7 +709,7 @@ void juku_state::juku(machine_config &config)
I8080A(config, m_maincpu, 20_MHz_XTAL/10);
m_maincpu->set_addrmap(AS_PROGRAM, &juku_state::mem_map);
m_maincpu->set_addrmap(AS_IO, &juku_state::io_map);
m_maincpu->in_inta_func().set("pic", FUNC(pic8259_device::acknowledge));
m_maincpu->in_inta_func().set(m_pic, FUNC(pic8259_device::acknowledge));

ADDRESS_MAP_BANK(config, m_bank);
m_bank->set_map(&juku_state::bank_map);
Expand Down Expand Up @@ -854,13 +765,13 @@ void juku_state::juku(machine_config &config)

// КР580ВВ51A
I8251(config, m_sio[0], 0);
m_sio[0]->rxrdy_handler().set("pic", FUNC(pic8259_device::ir2_w));
m_sio[0]->txrdy_handler().set("pic", FUNC(pic8259_device::ir3_w));
m_sio[0]->rxrdy_handler().set(m_pic, FUNC(pic8259_device::ir2_w));
m_sio[0]->txrdy_handler().set(m_pic, FUNC(pic8259_device::ir3_w));

// КР580ВВ51A (instead of FDC?)
I8251(config, m_sio[1], 0);
m_sio[1]->rxrdy_handler().set("pic", FUNC(pic8259_device::ir0_w));
m_sio[1]->txrdy_handler().set("pic", FUNC(pic8259_device::ir1_w));
m_sio[1]->rxrdy_handler().set(m_pic, FUNC(pic8259_device::ir0_w));
m_sio[1]->txrdy_handler().set(m_pic, FUNC(pic8259_device::ir1_w));

// Электроника МС 6105.1 "Колокольчик" (DEC VR201 analog)
SCREEN(config, m_screen, SCREEN_TYPE_RASTER);
Expand All @@ -875,6 +786,10 @@ void juku_state::juku(machine_config &config)
// К155ИВ1
TTL74148(config, m_key_encoder, 0);

// E4701
JUKU_MOUSE(config, m_mouse);
m_mouse->int_handler().set(m_pic, FUNC(pic8259_device::ir6_w));

// КР1818ВГ93 (for E6502 disk drive)
KR1818VG93(config, m_fdc, 16_MHz_XTAL/16);
m_fdc->drq_wr_callback().set(FUNC(juku_state::fdc_drq_w));
Expand Down
115 changes: 115 additions & 0 deletions src/mame/ussr/jukumouse.cpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,115 @@
// license:BSD-3-Clause
// copyright-holders:Märt Põder

#include "emu.h"
#include "jukumouse.h"

#define VERBOSE 1
#define LOG_OUTPUT_FUNC osd_printf_info

#include "logmacro.h"

DEFINE_DEVICE_TYPE(JUKU_MOUSE, juku_mouse_device, "juku_mouse", "Juku E510x mouse")

juku_mouse_device::juku_mouse_device(const machine_config &mconfig, const char *tag, device_t *owner, uint32_t clock)
: device_t(mconfig, JUKU_MOUSE, tag, owner, clock),
m_mouse_x(*this, "MOUSE_X"),
m_mouse_y(*this, "MOUSE_Y"),
m_mouse_b(*this, "BUTTONS"),
m_int_handler(*this)
{
}

void juku_mouse_device::device_start()
{
save_item(NAME(m_prev_mouse_y));
save_item(NAME(m_prev_mouse_x));
save_item(NAME(m_prev_byte));
m_mouse_timer = timer_alloc(FUNC(juku_mouse_device::poll_delta), this);
}

void juku_mouse_device::device_reset()
{
m_prev_mouse_y = 0;
m_prev_mouse_x = 0;
m_prev_byte = 0;
m_mouse_timer->adjust(attotime::zero, 0, attotime::from_hz(1400));
}

/*
* Calculate positive/negative delta from old and new relative value
*/
inline int delta(int o, int n)
{
if(o>n) {
if(o-n<128) return n-o;
else return n+255-o;
}
if(o<n) {
if(n-o<128) return n-o;
else return n-255-o;
}

return 0;
}

TIMER_CALLBACK_MEMBER( juku_mouse_device::poll_delta )
{
uint8_t buttons = m_mouse_b->read();
int x = m_mouse_x->read(), y = m_mouse_y->read();
int dx = delta(m_prev_mouse_x, x);
int dy = delta(m_prev_mouse_y, y);

if (dx != 0 || dy != 0 || (m_prev_byte & 0b11) != buttons) {
m_int_handler(CLEAR_LINE);
m_int_handler(ASSERT_LINE);
}
}

INPUT_PORTS_START( juku_mouse )
PORT_START("MOUSE_X")
PORT_BIT(0xff, 0x00, IPT_MOUSE_X) PORT_CODE(MOUSECODE_X) PORT_SENSITIVITY(23)

PORT_START("MOUSE_Y")
PORT_BIT(0xff, 0x00, IPT_MOUSE_Y) PORT_CODE(MOUSECODE_Y) PORT_SENSITIVITY(23)

PORT_START("BUTTONS")
PORT_BIT(0x02, IP_ACTIVE_HIGH, IPT_BUTTON1) PORT_CODE(MOUSECODE_BUTTON1) PORT_NAME("Left Button")
PORT_BIT(0x01, IP_ACTIVE_HIGH, IPT_BUTTON2) PORT_CODE(MOUSECODE_BUTTON2) PORT_NAME("Right Button")
INPUT_PORTS_END

uint8_t juku_mouse_device::mouse_port_r()
{
// 7------- always 1
// -6------ always 0
// --5----- vertical active
// ---4---- vertical direction
// ----3--- horizontal active
// -----2-- horizontal direction
// ------1- left button
// -------0 right button

uint8_t data = 0b10000000 | m_mouse_b->read();
int x = m_mouse_x->read(), y = m_mouse_y->read();
int dx = delta(m_prev_mouse_x, x);
int dy = delta(m_prev_mouse_y, y);

if (dx != 0) {
data |= dx > 0 ? 0b00001000 : 0b00001100;
m_prev_mouse_x = x;
}

if (dy != 0) {
data |= dy > 0 ? 0b00110000 : 0b00100000;
m_prev_mouse_y = y;
}

m_prev_byte = data;

return data;
}

ioport_constructor juku_mouse_device::device_input_ports() const
{
return INPUT_PORTS_NAME( juku_mouse );
}
30 changes: 30 additions & 0 deletions src/mame/ussr/jukumouse.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,30 @@
// license: BSD-3-Clause
// copyright-holders:Märt Põder

#ifndef MAME_USSR_JUKU_H
#define MAME_USSR_JUKU_H

#pragma once

class juku_mouse_device : public device_t
{
public:
juku_mouse_device(const machine_config &mconfig, const char *tag, device_t *owner, uint32_t clock = 0);
uint8_t mouse_port_r();
auto int_handler() { return m_int_handler.bind(); }
TIMER_CALLBACK_MEMBER( poll_delta );
protected:
virtual void device_start() override ATTR_COLD;
virtual void device_reset() override ATTR_COLD;
virtual ioport_constructor device_input_ports() const override ATTR_COLD;
private:
required_ioport m_mouse_x, m_mouse_y, m_mouse_b;
uint8_t m_prev_mouse_x, m_prev_mouse_y;
uint8_t m_prev_byte;
devcb_write_line m_int_handler;
emu_timer *m_mouse_timer;
};

DECLARE_DEVICE_TYPE(JUKU_MOUSE, juku_mouse_device)

#endif // MAME_USSR_JUKU_H

0 comments on commit c64a230

Please sign in to comment.