mirror of
https://github.com/holub/mame
synced 2025-04-21 07:52:35 +03:00
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:
parent
5594736bd5
commit
022361c683
@ -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 )
|
||||
|
@ -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
@ -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
|
||||
|
@ -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);
|
||||
}
|
||||
|
@ -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;
|
||||
};
|
||||
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user