Complete re-write of Philips CD-i CDIC handling; re-promoted to working (#9038)

* -cdi: Significantly improved compatibility and re-promoted to working. [Ryan Holtz, CD-i Fan]
This commit is contained in:
MooglyGuy 2021-12-25 13:49:11 +01:00 committed by GitHub
parent 5594736bd5
commit 022361c683
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
6 changed files with 969 additions and 1061 deletions

View File

@ -80,63 +80,59 @@ TODO:
void cdi_state::cdimono1_mem(address_map &map)
{
map(0x00000000, 0x0007ffff).ram().share("mcd212:planea");
map(0x00200000, 0x0027ffff).ram().share("mcd212:planeb");
map(0x00300000, 0x00303bff).rw(m_cdic, FUNC(cdicdic_device::ram_r), FUNC(cdicdic_device::ram_w));
map(0x000000, 0xffffff).rw(FUNC(cdi_state::bus_error_r), FUNC(cdi_state::bus_error_w));
map(0x000000, 0x07ffff).ram().share("mcd212:planea");
map(0x200000, 0x27ffff).ram().share("mcd212:planeb");
map(0x300000, 0x303bff).rw(m_cdic, FUNC(cdicdic_device::ram_r), FUNC(cdicdic_device::ram_w));
#if ENABLE_UART_PRINTING
map(0x00301400, 0x00301403).r(m_maincpu, FUNC(scc68070_device::uart_loopback_enable));
map(0x301400, 0x301403).r(m_maincpu, FUNC(scc68070_device::uart_loopback_enable));
#endif
map(0x00303c00, 0x00303fff).rw(m_cdic, FUNC(cdicdic_device::regs_r), FUNC(cdicdic_device::regs_w));
map(0x00310000, 0x00317fff).rw(m_slave_hle, FUNC(cdislave_hle_device::slave_r), FUNC(cdislave_hle_device::slave_w));
map(0x00318000, 0x0031ffff).noprw();
map(0x00320000, 0x00323fff).rw("mk48t08", FUNC(timekeeper_device::read), FUNC(timekeeper_device::write)).umask16(0xff00); /* nvram (only low bytes used) */
map(0x00400000, 0x0047ffff).rom().region("maincpu", 0);
map(0x004fffe0, 0x004fffff).rw(m_mcd212, FUNC(mcd212_device::regs_r), FUNC(mcd212_device::regs_w));
map(0x00500000, 0x0057ffff).ram();
map(0x00580000, 0x00cfffff).noprw();
map(0x00d00000, 0x00dfffff).ram(); // DVC RAM block 1
map(0x00e00000, 0x00e7ffff).rw(FUNC(cdi_state::dvc_r), FUNC(cdi_state::dvc_w));
map(0x00e80000, 0x00efffff).ram(); // DVC RAM block 2
map(0x00f00000, 0x00ffffff).noprw();
map(0x303c00, 0x303fff).rw(m_cdic, FUNC(cdicdic_device::regs_r), FUNC(cdicdic_device::regs_w));
map(0x310000, 0x317fff).rw(m_slave_hle, FUNC(cdislave_hle_device::slave_r), FUNC(cdislave_hle_device::slave_w));
map(0x318000, 0x31ffff).noprw();
map(0x320000, 0x323fff).rw("mk48t08", FUNC(timekeeper_device::read), FUNC(timekeeper_device::write)).umask16(0xff00); /* nvram (only low bytes used) */
map(0x400000, 0x47ffff).rom().region("maincpu", 0);
map(0x4fffe0, 0x4fffff).rw(m_mcd212, FUNC(mcd212_device::regs_r), FUNC(mcd212_device::regs_w));
map(0x500000, 0x57ffff).ram();
map(0xd00000, 0xdfffff).ram(); // DVC RAM block 1
map(0xe00000, 0xe7ffff).rw(FUNC(cdi_state::dvc_r), FUNC(cdi_state::dvc_w));
map(0xe80000, 0xefffff).ram(); // DVC RAM block 2
}
void cdi_state::cdimono2_mem(address_map &map)
{
map(0x00000000, 0x0007ffff).ram().share("mcd212:planea");
map(0x00200000, 0x0027ffff).ram().share("mcd212:planeb");
map(0x000000, 0x07ffff).ram().share("mcd212:planea");
map(0x200000, 0x27ffff).ram().share("mcd212:planeb");
#if ENABLE_UART_PRINTING
map(0x00301400, 0x00301403).r(m_maincpu, FUNC(scc68070_device::uart_loopback_enable));
map(0x301400, 0x301403).r(m_maincpu, FUNC(scc68070_device::uart_loopback_enable));
#endif
//map(0x00300000, 0x00303bff).rw("cdic", FUNC(cdicdic_device::ram_r), FUNC(cdicdic_device::ram_w));
//map(0x00303c00, 0x00303fff).rw("cdic", FUNC(cdicdic_device::regs_r), FUNC(cdicdic_device::regs_w));
//map(0x00310000, 0x00317fff).rw("slave", FUNC(cdislave_hle_device::slave_r), FUNC(cdislave_hle_device::slave_w));
//map(0x00318000, 0x0031ffff).noprw();
map(0x00320000, 0x00323fff).rw("mk48t08", FUNC(timekeeper_device::read), FUNC(timekeeper_device::write)).umask16(0xff00); /* nvram (only low bytes used) */
map(0x00400000, 0x0047ffff).rom().region("maincpu", 0);
map(0x004fffe0, 0x004fffff).rw(m_mcd212, FUNC(mcd212_device::regs_r), FUNC(mcd212_device::regs_w));
//map(0x00500000, 0x0057ffff).ram();
map(0x00500000, 0x00ffffff).noprw();
//map(0x00e00000, 0x00efffff).ram();
//map(0x300000, 0x303bff).rw("cdic", FUNC(cdicdic_device::ram_r), FUNC(cdicdic_device::ram_w));
//map(0x303c00, 0x303fff).rw("cdic", FUNC(cdicdic_device::regs_r), FUNC(cdicdic_device::regs_w));
//map(0x310000, 0x317fff).rw("slave", FUNC(cdislave_hle_device::slave_r), FUNC(cdislave_hle_device::slave_w));
//map(0x318000, 0x31ffff).noprw();
map(0x320000, 0x323fff).rw("mk48t08", FUNC(timekeeper_device::read), FUNC(timekeeper_device::write)).umask16(0xff00); /* nvram (only low bytes used) */
map(0x400000, 0x47ffff).rom().region("maincpu", 0);
map(0x4fffe0, 0x4fffff).rw(m_mcd212, FUNC(mcd212_device::regs_r), FUNC(mcd212_device::regs_w));
}
void cdi_state::cdi910_mem(address_map &map)
{
map(0x00000000, 0x0007ffff).ram().share("mcd212:planea");
map(0x00180000, 0x001fffff).rom().region("maincpu", 0); // boot vectors point here
map(0x000000, 0x07ffff).ram().share("mcd212:planea");
map(0x180000, 0x1fffff).rom().region("maincpu", 0); // boot vectors point here
map(0x00200000, 0x0027ffff).ram().share("mcd212:planeb");
map(0x200000, 0x27ffff).ram().share("mcd212:planeb");
#if ENABLE_UART_PRINTING
map(0x00301400, 0x00301403).r(m_maincpu, FUNC(scc68070_device::uart_loopback_enable));
map(0x301400, 0x301403).r(m_maincpu, FUNC(scc68070_device::uart_loopback_enable));
#endif
// map(0x00300000, 0x00303bff).rw("cdic", FUNC(cdicdic_device::ram_r), FUNC(cdicdic_device::ram_w));
// map(0x00303c00, 0x00303fff).rw("cdic", FUNC(cdicdic_device::regs_r), FUNC(cdicdic_device::regs_w));
// map(0x00310000, 0x00317fff).rw("slave_hle", FUNC(cdislave_hle_device::slave_r), FUNC(cdislave_hle_device::slave_w));
// map(0x00318000, 0x0031ffff).noprw();
map(0x00320000, 0x00323fff).rw("mk48t08", FUNC(timekeeper_device::read), FUNC(timekeeper_device::write)).umask16(0xff00); /* nvram (only low bytes used) */
map(0x004fffe0, 0x004fffff).rw(m_mcd212, FUNC(mcd212_device::regs_r), FUNC(mcd212_device::regs_w));
// map(0x00500000, 0x0057ffff).ram();
map(0x00500000, 0x00ffffff).noprw();
// map(0x00e00000, 0x00efffff).ram(); // DVC
// map(0x300000, 0x303bff).rw("cdic", FUNC(cdicdic_device::ram_r), FUNC(cdicdic_device::ram_w));
// map(0x303c00, 0x303fff).rw("cdic", FUNC(cdicdic_device::regs_r), FUNC(cdicdic_device::regs_w));
// map(0x310000, 0x317fff).rw("slave_hle", FUNC(cdislave_hle_device::slave_r), FUNC(cdislave_hle_device::slave_w));
// map(0x318000, 0x31ffff).noprw();
map(0x320000, 0x323fff).rw("mk48t08", FUNC(timekeeper_device::read), FUNC(timekeeper_device::write)).umask16(0xff00); /* nvram (only low bytes used) */
map(0x4fffe0, 0x4fffff).rw(m_mcd212, FUNC(mcd212_device::regs_r), FUNC(mcd212_device::regs_w));
// map(0x500000, 0x57ffff).ram();
map(0x500000, 0xffffff).noprw();
// map(0xe00000, 0xefffff).ram(); // DVC
}
@ -265,6 +261,32 @@ void quizard_state::machine_reset()
}
/**********************
* BERR Handling *
**********************/
uint16_t cdi_state::bus_error_r(offs_t offset)
{
if(!machine().side_effects_disabled())
{
m_maincpu->set_buserror_details(offset*2, true, m_maincpu->get_fc());
m_maincpu->set_input_line(M68K_LINE_BUSERROR, ASSERT_LINE);
m_maincpu->set_input_line(M68K_LINE_BUSERROR, CLEAR_LINE);
}
return 0xff;
}
void cdi_state::bus_error_w(offs_t offset, uint16_t data)
{
if(!machine().side_effects_disabled())
{
m_maincpu->set_buserror_details(offset*2, false, m_maincpu->get_fc());
m_maincpu->set_input_line(M68K_LINE_BUSERROR, ASSERT_LINE);
m_maincpu->set_input_line(M68K_LINE_BUSERROR, CLEAR_LINE);
}
}
/**********************
* Quizard Protection *
**********************/
@ -885,7 +907,7 @@ ROM_END
/* YEAR NAME PARENT COMPAT MACHINE INPUT CLASS INIT COMPANY FULLNAME */
// BIOS / System
CONS( 1991, cdimono1, 0, 0, cdimono1, cdi, cdi_state, empty_init, "Philips", "CD-i (Mono-I) (PAL)", MACHINE_NOT_WORKING | MACHINE_IMPERFECT_GRAPHICS | MACHINE_IMPERFECT_SOUND | MACHINE_SUPPORTS_SAVE )
CONS( 1991, cdimono1, 0, 0, cdimono1, cdi, cdi_state, empty_init, "Philips", "CD-i (Mono-I) (PAL)", MACHINE_IMPERFECT_GRAPHICS | MACHINE_IMPERFECT_SOUND | MACHINE_SUPPORTS_SAVE )
CONS( 1991, cdimono2, 0, 0, cdimono2, cdimono2, cdi_state, empty_init, "Philips", "CD-i (Mono-II) (NTSC)", MACHINE_NOT_WORKING )
CONS( 1991, cdi910, 0, 0, cdi910, cdimono2, cdi_state, empty_init, "Philips", "CD-i 910-17P Mini-MMC (PAL)", MACHINE_NOT_WORKING )
CONS( 1991, cdi490a, 0, 0, cdimono1, cdi, cdi_state, empty_init, "Philips", "CD-i 490", MACHINE_NOT_WORKING )

View File

@ -64,6 +64,9 @@ private:
uint16_t dvc_r(offs_t offset, uint16_t mem_mask = ~0);
void dvc_w(offs_t offset, uint16_t data, uint16_t mem_mask = ~0);
uint16_t bus_error_r(offs_t offset);
void bus_error_w(offs_t offset, uint16_t data);
required_shared_ptr<uint16_t> m_planea;
optional_device<cdislave_hle_device> m_slave_hle;
optional_device<m68hc05c8_device> m_servo;

File diff suppressed because it is too large Load Diff

View File

@ -32,7 +32,6 @@ TODO:
#include "sound/dmadac.h"
#include "cdrom.h"
//**************************************************************************
// TYPE DEFINITIONS
//**************************************************************************
@ -53,7 +52,6 @@ public:
// non-static internal members
void sample_trigger();
void process_delayed_command();
uint16_t regs_r(offs_t offset, uint16_t mem_mask = ~0);
void regs_w(offs_t offset, uint16_t data, uint16_t mem_mask = ~0);
@ -69,51 +67,86 @@ protected:
virtual void device_reset() override;
// internal callbacks
TIMER_CALLBACK_MEMBER( periodic_sample_trigger );
TIMER_CALLBACK_MEMBER( audio_sample_trigger );
TIMER_CALLBACK_MEMBER( initial_sample_trigger );
TIMER_CALLBACK_MEMBER( trigger_readback_int );
TIMER_CALLBACK_MEMBER(sector_tick);
TIMER_CALLBACK_MEMBER(audio_tick);
private:
enum
enum : uint8_t
{
CDIC_SECTOR_SYNC = 0,
CDIC_SECTOR_HEADER = 12,
CDIC_SECTOR_MODE = 15,
CDIC_SECTOR_FILE1 = 16,
CDIC_SECTOR_CHAN1 = 17,
CDIC_SECTOR_SUBMODE1 = 18,
CDIC_SECTOR_CODING1 = 19,
CDIC_SECTOR_FILE2 = 20,
CDIC_SECTOR_CHAN2 = 21,
CDIC_SECTOR_SUBMODE2 = 22,
CDIC_SECTOR_CODING2 = 23,
CDIC_SECTOR_DATA = 24,
CDIC_SECTOR_SIZE = 2352,
CDIC_SECTOR_DATASIZE = 2048,
CDIC_SECTOR_AUDIOSIZE = 2304,
CDIC_SECTOR_VIDEOSIZE = 2324,
CDIC_SUBMODE_EOF = 0x80,
CDIC_SUBMODE_RT = 0x40,
CDIC_SUBMODE_FORM = 0x20,
CDIC_SUBMODE_TRIG = 0x10,
CDIC_SUBMODE_DATA = 0x08,
CDIC_SUBMODE_AUDIO = 0x04,
CDIC_SUBMODE_VIDEO = 0x02,
CDIC_SUBMODE_EOR = 0x01
DISC_NONE,
DISC_MODE1,
DISC_MODE2,
DISC_CDDA,
DISC_TOC
};
int is_valid_sample_buf(uint16_t addr) const;
double sample_buf_freq(uint16_t addr) const;
int sample_buf_size(uint16_t addr) const;
enum
{
SECTOR_SYNC = 0,
SECTOR_HEADER = 12,
SECTOR_MODE = 15,
SECTOR_FILE1 = 16,
SECTOR_CHAN1 = 17,
SECTOR_SUBMODE1 = 18,
SECTOR_CODING1 = 19,
SECTOR_FILE2 = 20,
SECTOR_CHAN2 = 21,
SECTOR_SUBMODE2 = 22,
SECTOR_CODING2 = 23,
SECTOR_DATA = 24,
SECTOR_SIZE = 2352,
SECTOR_AUDIO_SIZE = 2304,
SECTOR_DATASIZE = 2048,
SECTOR_AUDIOSIZE = 2304,
SECTOR_VIDEOSIZE = 2324,
SUBMODE_EOF = 0x80,
SUBMODE_RT = 0x40,
SUBMODE_FORM = 0x20,
SUBMODE_TRIG = 0x10,
SUBMODE_DATA = 0x08,
SUBMODE_AUDIO = 0x04,
SUBMODE_VIDEO = 0x02,
SUBMODE_EOR = 0x01,
CODING_BPS_MASK = 0x30,
CODING_4BPS = 0x00,
CODING_8BPS = 0x10,
CODING_16BPS = 0x20,
CODING_BPS_MPEG = 0x30,
CODING_RATE_MASK = 0x0c,
CODING_37KHZ = 0x00,
CODING_18KHZ = 0x04,
CODING_RATE_RESV = 0x08,
CODING_44KHZ = 0x0c,
CODING_CHAN_MASK = 0x03,
CODING_MONO = 0x00,
CODING_STEREO = 0x01,
CODING_CHAN_RESV = 0x02,
CODING_CHAN_MPEG = 0x03,
SUBCODE_Q_CONTROL = 12,
SUBCODE_Q_TRACK = 13,
SUBCODE_Q_INDEX = 14,
SUBCODE_Q_MODE1_MINS = 15,
SUBCODE_Q_MODE1_SECS = 16,
SUBCODE_Q_MODE1_FRAC = 17,
SUBCODE_Q_MODE1_ZERO = 18,
SUBCODE_Q_MODE1_AMINS = 19,
SUBCODE_Q_MODE1_ASECS = 20,
SUBCODE_Q_MODE1_AFRAC = 21,
SUBCODE_Q_CRC0 = 22,
SUBCODE_Q_CRC1 = 23
};
devcb_write_line m_intreq_callback;
@ -139,36 +172,53 @@ private:
uint16_t m_interrupt_vector; // CDIC Interrupt Vector Register (0x303ffc)
uint16_t m_data_buffer; // CDIC Data Buffer Register (0x303ffe)
emu_timer *m_interrupt_timer;
cdrom_file *m_cd;
emu_timer *m_audio_sample_timer;
emu_timer *m_audio_playback_timer;
emu_timer *m_periodic_sample_timer[2];
int32_t m_audio_sample_freq;
int32_t m_audio_sample_size;
emu_timer *m_sector_timer;
uint8_t m_disc_command;
uint8_t m_disc_mode;
uint8_t m_disc_spinup_counter;
uint32_t m_curr_lba;
emu_timer *m_audio_timer;
uint8_t m_audio_sector_counter;
uint8_t m_audio_format_sectors;
bool m_decoding_audio_map;
uint16_t m_decode_addr;
uint8_t m_decode_delay;
attotime m_decode_period;
bool m_break_on_achan;
bool m_valid_audio_sample;
int m_xa_last[4];
std::unique_ptr<uint16_t[]> m_ram;
int16_t m_xa_last[4];
std::unique_ptr<uint8_t[]> m_ram;
std::unique_ptr<int16_t[]> m_samples[2];
static void decode_xa_mono(int32_t *cdic_xa_last, const uint8_t *xa, int16_t *dp);
static void decode_xa_mono8(int32_t *cdic_xa_last, const uint8_t *xa, int16_t *dp);
static void decode_xa_stereo(int32_t *cdic_xa_last, const uint8_t *xa, int16_t *dp);
static void decode_xa_stereo8(int32_t *cdic_xa_last, const uint8_t *xa, int16_t *dp);
void decode_8bit_xa_unit(int channel, uint8_t param, const uint8_t *data, int16_t *out_buffer);
void decode_4bit_xa_unit(int channel, uint8_t param, const uint8_t *data, uint8_t shift, int16_t *out_buffer);
void play_raw_group(const uint8_t *data);
void play_xa_group(const uint8_t coding, const uint8_t *data);
void play_audio_sector(const uint8_t coding, const uint8_t *data);
void process_audio_map();
static const int32_t s_cdic_adpcm_filter_coef[5][2];
bool is_mode2_sector_selected(const uint8_t *buffer);
bool is_mode2_audio_selected(const uint8_t *buffer);
uint32_t increment_cdda_frame_bcd(uint32_t bcd);
uint32_t increment_cdda_sector_bcd(uint32_t bcd);
void decode_audio_sector(const uint8_t *xa, int32_t triggered);
void play_audio_sector();
void process_disc_sector();
void process_sector_data(const uint8_t *buffer, const uint8_t *subcode_buffer);
void init_disc_read(uint8_t disc_mode);
void cancel_disc_read();
void handle_cdic_command();
void update_interrupt_state();
uint32_t lba_from_time();
static uint8_t get_sector_count_for_coding(uint8_t coding);
static void decode_xa_mono(int16_t *cdic_xa_last, const uint8_t *xa, int16_t *dp);
static void decode_xa_mono8(int16_t *cdic_xa_last, const uint8_t *xa, int16_t *dp);
static void decode_xa_stereo(int16_t *cdic_xa_last, const uint8_t *xa, int16_t *dp);
static void decode_xa_stereo8(int16_t *cdic_xa_last, const uint8_t *xa, int16_t *dp);
static const int16_t s_xa_filter_coef[4][2];
static const int32_t s_samples_per_sector;
static const uint16_t s_crc_ccitt_table[256];
};
// device type definition

View File

@ -18,6 +18,8 @@ TODO:
#include "emu.h"
#include "machine/cdislavehle.h"
#include <algorithm>
#define LOG_IRQS (1 << 0)
#define LOG_COMMANDS (1 << 1)
#define LOG_READS (1 << 2)
@ -56,62 +58,57 @@ void cdislave_hle_device::prepare_readback(const attotime &delay, uint8_t channe
m_interrupt_timer->adjust(delay);
}
void cdislave_hle_device::perform_mouse_update()
INPUT_CHANGED_MEMBER( cdislave_hle_device::mouse_update )
{
uint16_t x = m_mousex->read();
uint16_t y = m_mousey->read();
uint8_t buttons = m_mousebtn->read();
const uint8_t button_state = m_mousebtn->read();
uint8_t button_bits = 0x01;
if (BIT(button_state, 0))
button_bits |= 0x02;
if (BIT(button_state, 1))
button_bits |= 0x04;
if (BIT(button_state, 2))
button_bits |= 0x06;
uint16_t old_mouse_x = m_real_mouse_x;
uint16_t old_mouse_y = m_real_mouse_y;
const uint16_t x = m_mousex->read();
const uint16_t y = m_mousey->read();
if (m_real_mouse_x == 0xffff)
int16_t deltax = 0;
int16_t deltay = 0;
if (m_input_mouse_x != 0xffff && m_input_mouse_y != 0xffff)
{
old_mouse_x = x & 0x3ff;
old_mouse_y = y & 0x3ff;
deltax = -(m_input_mouse_x - x);
deltay = -(m_input_mouse_y - y);
}
m_real_mouse_x = x & 0x3ff;
m_real_mouse_y = y & 0x3ff;
m_input_mouse_x = x;
m_input_mouse_y = y;
m_fake_mouse_x += (m_real_mouse_x - old_mouse_x);
m_fake_mouse_y += (m_real_mouse_y - old_mouse_y);
while (m_fake_mouse_x > 0x3ff)
{
m_fake_mouse_x += 0x400;
}
while (m_fake_mouse_y > 0x3ff)
{
m_fake_mouse_y += 0x400;
}
x = m_fake_mouse_x;
y = m_fake_mouse_y;
m_device_mouse_x = std::clamp(m_device_mouse_x + deltax, 0, 767);
m_device_mouse_y = std::clamp(m_device_mouse_y + deltay, 0, 559);
if (m_polling_active)
{
prepare_readback(attotime::zero, 0, 4, ((x & 0x380) >> 7) | (buttons << 4), x & 0x7f, (y & 0x380) >> 7, y & 0x7f, 0xf7);
const uint8_t byte3 = ((m_device_mouse_x & 0x380) >> 7) | (button_bits << 3);
const uint8_t byte2 = m_device_mouse_x & 0x7f;
const uint8_t byte1 = (m_device_mouse_y & 0x380) >> 7;
const uint8_t byte0 = m_device_mouse_y & 0x7f;
prepare_readback(attotime::zero, 0, 4, byte3, byte2, byte1, byte0, 0xf7);
}
}
INPUT_CHANGED_MEMBER( cdislave_hle_device::mouse_update )
{
perform_mouse_update();
}
static INPUT_PORTS_START(cdislave_mouse)
PORT_START("MOUSEX")
PORT_BIT(0x3ff, 0x000, IPT_MOUSE_X) PORT_SENSITIVITY(100) PORT_MINMAX(0x000, 0x3ff) PORT_KEYDELTA(2) PORT_CHANGED_MEMBER(DEVICE_SELF, cdislave_hle_device, mouse_update, 0)
PORT_BIT(0xffff, 0x000, IPT_MOUSE_X) PORT_SENSITIVITY(100) PORT_KEYDELTA(2) PORT_CHANGED_MEMBER(DEVICE_SELF, cdislave_hle_device, mouse_update, 0)
PORT_START("MOUSEY")
PORT_BIT(0x3ff, 0x000, IPT_MOUSE_Y) PORT_SENSITIVITY(100) PORT_MINMAX(0x000, 0x3ff) PORT_KEYDELTA(2) PORT_CHANGED_MEMBER(DEVICE_SELF, cdislave_hle_device, mouse_update, 0)
PORT_BIT(0xffff, 0x000, IPT_MOUSE_Y) PORT_SENSITIVITY(100) PORT_KEYDELTA(2) PORT_CHANGED_MEMBER(DEVICE_SELF, cdislave_hle_device, mouse_update, 0)
PORT_START("MOUSEBTN")
PORT_BIT(0x01, IP_ACTIVE_HIGH, IPT_BUTTON1) PORT_CODE(MOUSECODE_BUTTON1) PORT_NAME("Mouse Button 1") PORT_CHANGED_MEMBER(DEVICE_SELF, cdislave_hle_device, mouse_update, 0)
PORT_BIT(0x02, IP_ACTIVE_HIGH, IPT_BUTTON2) PORT_CODE(MOUSECODE_BUTTON2) PORT_NAME("Mouse Button 2") PORT_CHANGED_MEMBER(DEVICE_SELF, cdislave_hle_device, mouse_update, 0)
PORT_BIT(0xfc, IP_ACTIVE_HIGH, IPT_UNUSED)
PORT_BIT(0x01, IP_ACTIVE_HIGH, IPT_BUTTON1) PORT_CODE(MOUSECODE_BUTTON1) PORT_NAME("Button 1") PORT_CHANGED_MEMBER(DEVICE_SELF, cdislave_hle_device, mouse_update, 0)
PORT_BIT(0x02, IP_ACTIVE_HIGH, IPT_BUTTON2) PORT_CODE(MOUSECODE_BUTTON2) PORT_NAME("Button 2") PORT_CHANGED_MEMBER(DEVICE_SELF, cdislave_hle_device, mouse_update, 0)
PORT_BIT(0x04, IP_ACTIVE_HIGH, IPT_BUTTON3) PORT_CODE(MOUSECODE_BUTTON3) PORT_NAME("Button 3") PORT_CHANGED_MEMBER(DEVICE_SELF, cdislave_hle_device, mouse_update, 0)
PORT_BIT(0xf8, IP_ACTIVE_HIGH, IPT_UNUSED)
INPUT_PORTS_END
ioport_constructor cdislave_hle_device::device_input_ports() const
@ -156,20 +153,8 @@ uint16_t cdislave_hle_device::slave_r(offs_t offset)
void cdislave_hle_device::set_mouse_position()
{
// uint16_t x, y;
//printf( "Set mouse position: %02x %02x %02x\n", m_in_buf[0], m_in_buf[1], m_in_buf[2] );
m_fake_mouse_y = ((m_in_buf[1] & 0x0f) << 6) | (m_in_buf[0] & 0x3f);
m_fake_mouse_x = ((m_in_buf[1] & 0x70) << 3) | m_in_buf[2];
// x = m_fake_mouse_x;
// y = m_fake_mouse_y;
if (m_polling_active)
{
//prepare_readback(attotime::zero, 0, 4, (x & 0x380) >> 7, x & 0x7f, (y & 0x380) >> 7, y & 0x7f, 0xf7);
}
m_device_mouse_x = ((m_in_buf[1] & 0x70) << 3) | (m_in_buf[2] & 0x7f);
m_device_mouse_y = ((m_in_buf[1] & 0x0f) << 6) | (m_in_buf[0] & 0x3f);
}
void cdislave_hle_device::slave_w(offs_t offset, uint16_t data)
@ -290,20 +275,24 @@ void cdislave_hle_device::slave_w(offs_t offset, uint16_t data)
switch (data & 0x00ff)
{
case 0x82: // Mute Audio
{
LOGMASKED(LOG_COMMANDS, "slave_w: Channel %d: Mute Audio (0x82)\n", offset);
m_dmadac[0]->enable(0);
m_dmadac[1]->enable(0);
m_dmadac[0]->set_volume(0);
m_dmadac[1]->set_volume(0);
m_in_index = 0;
m_in_count = 0;
//cdic->audio_sample_timer->adjust(attotime::never);
break;
}
case 0x83: // Unmute Audio
{
LOGMASKED(LOG_COMMANDS, "slave_w: Channel %d: Unmute Audio (0x83)\n", offset);
m_dmadac[0]->enable(1);
m_dmadac[1]->enable(1);
m_dmadac[0]->set_volume(0x100);
m_dmadac[1]->set_volume(0x100);
m_in_index = 0;
m_in_count = 0;
break;
}
case 0xf0: // Set Front Panel LCD
LOGMASKED(LOG_COMMANDS, "slave_w: Channel %d: Set Front Panel LCD (0xf0)\n", offset);
m_in_count = 17;
@ -476,11 +465,11 @@ void cdislave_hle_device::device_start()
save_item(NAME(m_lcd_state));
save_item(NAME(m_real_mouse_x));
save_item(NAME(m_real_mouse_y));
save_item(NAME(m_input_mouse_x));
save_item(NAME(m_input_mouse_y));
save_item(NAME(m_fake_mouse_x));
save_item(NAME(m_fake_mouse_y));
save_item(NAME(m_device_mouse_x));
save_item(NAME(m_device_mouse_y));
m_interrupt_timer = machine().scheduler().timer_alloc(timer_expired_delegate(FUNC(cdislave_hle_device::trigger_readback_int), this));
m_interrupt_timer->adjust(attotime::never);
@ -513,11 +502,11 @@ void cdislave_hle_device::device_reset()
memset(m_lcd_state, 0, 16);
m_real_mouse_x = 0xffff;
m_real_mouse_y = 0xffff;
m_input_mouse_x = 0xffff;
m_input_mouse_y = 0xffff;
m_fake_mouse_x = 0;
m_fake_mouse_y = 0;
m_device_mouse_x = 0;
m_device_mouse_y = 0;
m_int_callback(CLEAR_LINE);
}

View File

@ -55,6 +55,9 @@ protected:
TIMER_CALLBACK_MEMBER( trigger_readback_int );
private:
void prepare_readback(const attotime &delay, uint8_t channel, uint8_t count, uint8_t data0, uint8_t data1, uint8_t data2, uint8_t data3, uint8_t cmd);
void set_mouse_position();
devcb_write_line m_int_callback;
required_device_array<dmadac_sound_device, 2> m_dmadac;
@ -63,12 +66,8 @@ private:
required_ioport m_mousey;
required_ioport m_mousebtn;
// internal state
class channel_state
struct channel_state
{
public:
channel_state() { }
uint8_t m_out_buf[4];
uint8_t m_out_index;
uint8_t m_out_count;
@ -88,18 +87,11 @@ private:
uint8_t m_lcd_state[16];
uint16_t m_real_mouse_x;
uint16_t m_real_mouse_y;
uint16_t m_input_mouse_x;
uint16_t m_input_mouse_y;
uint16_t m_fake_mouse_x;
uint16_t m_fake_mouse_y;
// static internal members
// non-static internal members
void prepare_readback(const attotime &delay, uint8_t channel, uint8_t count, uint8_t data0, uint8_t data1, uint8_t data2, uint8_t data3, uint8_t cmd);
void perform_mouse_update();
void set_mouse_position();
int16_t m_device_mouse_x;
int16_t m_device_mouse_y;
};