diff options
author | 2020-06-28 19:37:27 +0200 | |
---|---|---|
committer | 2020-06-28 19:37:27 +0200 | |
commit | bc0b2c7b093ed57b8081c960c7e140f1a4c5192d (patch) | |
tree | 3aea60d3e527efbe1be45d287a695357e9c05fff | |
parent | 9c196024244f6b2152574a60b324a6e930250628 (diff) |
-cmi2x: Numerous fixes, now boots into System Software V19, and plays audio badly.
-rw-r--r-- | src/mame/audio/cmi01a.cpp | 142 | ||||
-rw-r--r-- | src/mame/audio/cmi01a.h | 16 | ||||
-rw-r--r-- | src/mame/drivers/cmi.cpp | 234 | ||||
-rw-r--r-- | src/mame/machine/cmi_mkbd.cpp | 60 | ||||
-rw-r--r-- | src/mame/machine/cmi_mkbd.h | 1 |
5 files changed, 305 insertions, 148 deletions
diff --git a/src/mame/audio/cmi01a.cpp b/src/mame/audio/cmi01a.cpp index 97e4655ce30..88246d809a8 100644 --- a/src/mame/audio/cmi01a.cpp +++ b/src/mame/audio/cmi01a.cpp @@ -8,7 +8,6 @@ #include "emu.h" #include "audio/cmi01a.h" -#include "machine/input_merger.h" #define VERBOSE (0) #include "logmacro.h" @@ -21,6 +20,7 @@ DEFINE_DEVICE_TYPE(CMI01A_CHANNEL_CARD, cmi01a_device, "cmi_01a", "Fairlight CMI cmi01a_device::cmi01a_device(const machine_config &mconfig, const char *tag, device_t *owner, uint32_t clock) : device_t(mconfig, CMI01A_CHANNEL_CARD, tag, owner, clock) , device_sound_interface(mconfig, *this) + , m_irq_merger(*this, "cmi01a_irq") , m_pia(*this, "cmi01a_pia_%u", 0U) , m_ptm(*this, "cmi01a_ptm") , m_cmi02_pia(*this, "^cmi02_pia_%u", 1U) @@ -37,41 +37,42 @@ void cmi01a_device::device_add_mconfig(machine_config &config) m_pia[0]->writepb_handler().set(FUNC(cmi01a_device::rp_w)); m_pia[0]->ca2_handler().set(FUNC(cmi01a_device::pia_0_ca2_w)); m_pia[0]->cb2_handler().set(FUNC(cmi01a_device::pia_0_cb2_w)); - m_pia[0]->irqa_handler().set("cmi01a_irq", FUNC(input_merger_device::in_w<0>)); - m_pia[0]->irqb_handler().set("cmi01a_irq", FUNC(input_merger_device::in_w<1>)); + m_pia[0]->irqa_handler().set(m_irq_merger, FUNC(input_merger_device::in_w<0>)); + m_pia[0]->irqb_handler().set(m_irq_merger, FUNC(input_merger_device::in_w<1>)); PIA6821(config, m_pia[1], 0); // pia_cmi01a_2_config m_pia[1]->readca1_handler().set(FUNC(cmi01a_device::zx_r)); m_pia[1]->readca2_handler().set(FUNC(cmi01a_device::eosi_r)); m_pia[1]->writepa_handler().set(FUNC(cmi01a_device::pia_1_a_w)); m_pia[1]->writepb_handler().set(FUNC(cmi01a_device::pia_1_b_w)); - m_pia[1]->irqa_handler().set("cmi01a_irq", FUNC(input_merger_device::in_w<2>)); - m_pia[1]->irqb_handler().set("cmi01a_irq", FUNC(input_merger_device::in_w<3>)); + m_pia[1]->irqa_handler().set(m_irq_merger, FUNC(input_merger_device::in_w<2>)); + m_pia[1]->irqb_handler().set(m_irq_merger, FUNC(input_merger_device::in_w<3>)); PTM6840(config, m_ptm, DERIVED_CLOCK(1, 1)); // ptm_cmi01a_config m_ptm->o1_callback().set(FUNC(cmi01a_device::ptm_o1)); - m_ptm->irq_callback().set("cmi01a_irq", FUNC(input_merger_device::in_w<4>)); + m_ptm->irq_callback().set(FUNC(cmi01a_device::ptm_irq)); - INPUT_MERGER_ANY_HIGH(config, "cmi01a_irq").output_handler().set(FUNC(cmi01a_device::cmi01a_irq)); + INPUT_MERGER_ANY_HIGH(config, m_irq_merger).output_handler().set(FUNC(cmi01a_device::cmi01a_irq)); } void cmi01a_device::sound_stream_update(sound_stream &stream, stream_sample_t **inputs, stream_sample_t **outputs, int samples) { - if (m_active && m_vol_latch) + if ((m_status & CHANNEL_STATUS_RUN) && m_vol_latch) { int length = samples; - int seg_addr = m_segment_cnt & 0x7f; + int mask = (m_status & CHANNEL_STATUS_LOAD) ? 0x7fff : 0x7f; + int addr = m_segment_cnt; + uint8_t *wave_ptr = &m_wave_ram[m_segment_cnt & 0x3fff]; stream_sample_t *buf = outputs[0]; while (length--) { - *buf++ = wave_ptr[seg_addr]; - seg_addr = (seg_addr + 1) & 0x7f; + *buf++ = wave_ptr[addr++ & 0x3fff] << 7; } - m_segment_cnt = (m_segment_cnt & ~0x7f) | seg_addr; + m_segment_cnt = (m_segment_cnt & ~mask) | addr; } else { @@ -89,7 +90,10 @@ void cmi01a_device::device_start() m_wave_ram = std::make_unique<uint8_t[]>(0x4000); m_zx_timer = timer_alloc(TIMER_ZX); + m_eosi_timer = timer_alloc(TIMER_EOSI); + m_zx_timer->adjust(attotime::never); + m_eosi_timer->adjust(attotime::never); m_stream = stream_alloc(0, 1, 44100); @@ -110,18 +114,25 @@ void cmi01a_device::device_reset() m_rp = 0; m_ws = 0; m_dir = 0; + m_pia0_cb2_state = 1; m_freq = 0.0; - m_active = false; + m_status = 0; m_ptm_o1 = 0; + + m_zx_timer->adjust(attotime::never); + m_eosi_timer->adjust(attotime::never); } WRITE_LINE_MEMBER( cmi01a_device::pia_0_ca2_w ) { - // update_stream() + m_status &= ~CHANNEL_STATUS_LOAD; + if (!state) { + m_status |= CHANNEL_STATUS_LOAD; + m_segment_cnt = 0x4000 | ((m_pia[0]->a_output() & 0x7f) << 7); m_new_addr = 1; m_pia[1]->cb1_w(1); @@ -152,7 +163,7 @@ READ_LINE_MEMBER( cmi01a_device::tri_r ) { bool top_terminal_count = (m_dir == ENV_DIR_UP && m_rp == 0); bool bottom_terminal_count = (m_dir == ENV_DIR_DOWN && m_rp == 0xff); - return (top_terminal_count || bottom_terminal_count) ? 1 : 0; + return (top_terminal_count || bottom_terminal_count) ? 0 : 1; } WRITE_LINE_MEMBER( cmi01a_device::cmi01a_irq ) @@ -167,9 +178,19 @@ void cmi01a_device::device_timer(emu_timer &timer, device_timer_id id, int param case TIMER_ZX: zx_timer_cb(); break; + case TIMER_EOSI: + eosi_timer_cb(); + break; } } +void cmi01a_device::eosi_timer_cb() +{ + m_pia[1]->cb1_w(0); + +// printf("End of sound\n"); +} + void cmi01a_device::zx_timer_cb() { /* Set ZX */ @@ -197,46 +218,71 @@ void cmi01a_device::zx_timer_cb() void cmi01a_device::run_voice() { int val_a = m_pia[1]->a_output(); - int pitch = ((val_a & 3) << 8) | m_pia[1]->b_output(); + int pitch = ((val_a & 3) << 8) + | m_pia[1]->b_output(); int o_val = (val_a >> 2) & 0xf; + LOG("CH%d running voice: PIA1 A output = %02x\n", m_channel, (uint8_t)val_a); + LOG("CH%d running voice: Pitch = %04x\n", m_channel, (uint16_t)pitch); + LOG("CH%d running voice: o_val = %x\n", m_channel, o_val); + int m_tune = m_cmi02_pia[0]->b_output(); - double mfreq = (double)(0xf00 | m_tune) * (MASTER_OSCILLATOR / 2.0 / 4096.0).dvalue(); + LOG("CH%d running voice: Tuning = %02x\n", m_channel, (uint8_t)m_tune); + double mfreq = (double)(0xf00 | m_tune) * (MASTER_OSCILLATOR.dvalue() / 2.0) / 4096.0; + LOG("CH%d running voice: mfreq = %f (%03x * %f)\n", m_channel, mfreq, 0xf00 | m_tune, (MASTER_OSCILLATOR / 2.0 / 4096.0).dvalue()); - double cfreq = ((double)(0x800 | (pitch << 1))* mfreq) / 4096.0; + double cfreq = ((double)(0x800 | (pitch << 1)) * mfreq) / 4096.0; + LOG("CH%d running voice: cfreq = %f (%04x * %f) / 4096.0\n", m_channel, mfreq, 0x800 | (pitch << 1), mfreq, cfreq); -// if (cfreq > 0.0) + if (cfreq > MASTER_OSCILLATOR.dvalue()) { - /* Octave register enabled? */ - if (!(o_val & 0x8)) - cfreq /= 2 << ((7 ^ o_val) & 7); + LOG("CH%d Ignoring voice run due to excessive frequency\n"); + return; + } + + LOG("CH%d Running voice\n", m_channel); + /* Octave register enabled? */ + if (!(o_val & 0x8)) + cfreq /= 2 << ((7 ^ o_val) & 7); + + cfreq /= 16.0f; - cfreq /= 16.0f; + m_freq = cfreq; - m_freq = cfreq; + LOG("CH%d running voice: Final freq: %f\n", m_channel, m_freq); - m_stream->set_sample_rate(cfreq); + m_stream->set_sample_rate(cfreq); - // Set timers and things? - attotime zx_period = attotime::from_ticks(64, cfreq); - m_zx_timer->adjust(zx_period, 0, zx_period); + // Set timers and things? + attotime zx_period = attotime::from_ticks(64, cfreq); + m_zx_timer->adjust(zx_period, 0, zx_period); - m_active = true; + if (m_status & CHANNEL_STATUS_LOAD) + { + int samples = 0x4000 - (m_segment_cnt & 0x3fff); + m_eosi_timer->adjust(attotime::from_ticks(samples, cfreq)); } } WRITE_LINE_MEMBER( cmi01a_device::pia_0_cb2_w ) { + int old_state = m_pia0_cb2_state; + m_pia0_cb2_state = state; + LOG("CH%d PIA0 CB2: %d\n", m_channel, state); + //streams_update(); /* RUN */ - if (state) + if (!old_state && m_pia0_cb2_state) { - m_segment_cnt = 0x4000 | ((m_pia[0]->a_output() & 0x7f) << 7); - m_new_addr = 1; + m_status |= CHANNEL_STATUS_RUN; - /* Clear /EOSI */ -// pia6821_cb1_w(card->pia[1], 0, 1); + /* Only reset address counter if /LOAD not asserted */ + if ((m_status & CHANNEL_STATUS_LOAD) == 0) + { + m_segment_cnt = 0x4000 | ((m_pia[0]->a_output() & 0x7f) << 7); + m_new_addr = 1; + } /* Clear ZX */ m_pia[1]->ca1_w(0); @@ -250,8 +296,11 @@ WRITE_LINE_MEMBER( cmi01a_device::pia_0_cb2_w ) run_voice(); } - else + + if (old_state && !m_pia0_cb2_state) { + m_status &= ~CHANNEL_STATUS_RUN; + /* Clear /EOSI */ m_pia[1]->cb1_w(1); @@ -260,8 +309,7 @@ WRITE_LINE_MEMBER( cmi01a_device::pia_0_cb2_w ) m_ptm->set_g3(1); m_zx_timer->adjust(attotime::never); - m_active = false; - m_zx_flag = 0; // TEST + m_eosi_timer->adjust(attotime::never); m_zx_ff = 0; } @@ -291,6 +339,11 @@ void cmi01a_device::update_wave_addr(int inc) /* Zero crossing interrupt is a pulse */ } +WRITE_LINE_MEMBER( cmi01a_device::ptm_irq ) +{ + m_irq_merger->in_w<4>(state); +} + WRITE_LINE_MEMBER( cmi01a_device::ptm_o1 ) { m_ptm_o1 = state; @@ -303,7 +356,7 @@ READ_LINE_MEMBER( cmi01a_device::eosi_r ) READ_LINE_MEMBER( cmi01a_device::zx_r ) { - return m_segment_cnt & 0x40; + return (m_segment_cnt & 0x40) >> 6; } void cmi01a_device::write(offs_t offset, uint8_t data) @@ -337,10 +390,12 @@ void cmi01a_device::write(offs_t offset, uint8_t data) break; case 0x8: case 0x9: case 0xa: case 0xb: + LOG("CH%d PIA0 Write: %d = %02x\n", m_channel, offset & 3, data); m_pia[0]->write(offset & 3, data); break; case 0xc: case 0xd: case 0xe: case 0xf: + LOG("CH%d PIA1 Write: %d = %02x\n", m_channel, (BIT(offset, 0) << 1) | BIT(offset, 1), data); m_pia[1]->write((BIT(offset, 0) << 1) | BIT(offset, 1), data); break; @@ -351,7 +406,10 @@ void cmi01a_device::write(offs_t offset, uint8_t data) int a1 = (m_ptm_o1 && BIT(offset, 3)) || (!BIT(offset, 3) && BIT(offset, 2)); int a2 = BIT(offset, 1); - //osd_printf_debug("CH%d PTM W: [%x] = %02x\n", m_channel, (a2 << 2) | (a1 << 1) | a0, data); + if ((offset == 5 || offset == 7) && (data < 0x30)) + data = 0xff; + + LOG("CH%d PTM Write: %d = %02x\n", m_channel, (a2 << 2) | (a1 << 1) | a0, data); m_ptm->write((a2 << 2) | (a1 << 1) | a0, data); break; } @@ -395,21 +453,23 @@ uint8_t cmi01a_device::read(offs_t offset) case 0x8: case 0x9: case 0xa: case 0xb: data = m_pia[0]->read(offset & 3); + LOG("CH%d PIA0 Read: %d = %02x\n", m_channel, offset & 3, data); break; case 0xc: case 0xd: case 0xe: case 0xf: data = m_pia[1]->read((BIT(offset, 0) << 1) | BIT(offset, 1)); + LOG("CH%d PIA1 Read: %d = %02x\n", m_channel, (BIT(offset, 0) << 1) | BIT(offset, 1), data); break; case 0x10: case 0x11: case 0x12: case 0x13: case 0x14: case 0x15: case 0x16: case 0x17: { int a0 = offset & 1; - int a1 = ((m_ptm_o1 && BIT(offset, 3)) || (!BIT(offset, 3) && BIT(offset, 2))) ? 1 : 0; + int a1 = (m_ptm_o1 && BIT(offset, 3)) || (!BIT(offset, 3) && BIT(offset, 2)); int a2 = BIT(offset, 1); data = m_ptm->read((a2 << 2) | (a1 << 1) | a0); - //osd_printf_debug("CH%d PTM R: [%x] %02x\n", m_channel, (a2 << 2) | (a1 << 1) | a0, data); + LOG("CH%d PTM Read: %d = %02x\n", m_channel, (a2 << 2) | (a1 << 1) | a0, data); break; } diff --git a/src/mame/audio/cmi01a.h b/src/mame/audio/cmi01a.h index d6faf8ebe37..6a11f655e63 100644 --- a/src/mame/audio/cmi01a.h +++ b/src/mame/audio/cmi01a.h @@ -11,10 +11,13 @@ #include "machine/6821pia.h" #include "machine/6840ptm.h" +#include "machine/input_merger.h" #define ENV_DIR_DOWN 0 #define ENV_DIR_UP 1 +#define CHANNEL_STATUS_LOAD 1 +#define CHANNEL_STATUS_RUN 2 class cmi01a_device : public device_t, public device_sound_interface { public: @@ -41,7 +44,9 @@ protected: virtual void device_timer(emu_timer &timer, device_timer_id id, int param, void *ptr) override; static const device_timer_id TIMER_ZX = 0; + static const device_timer_id TIMER_EOSI = 1; + required_device<input_merger_device> m_irq_merger; required_device_array<pia6821_device, 2> m_pia; required_device<ptm6840_device> m_ptm; @@ -53,6 +58,7 @@ private: DECLARE_WRITE_LINE_MEMBER(cmi01a_irq); void zx_timer_cb(); + void eosi_timer_cb(); void run_voice(); void update_wave_addr(int inc); @@ -61,18 +67,21 @@ private: uint8_t m_zx_flag; uint8_t m_zx_ff; + emu_timer * m_eosi_timer; + std::unique_ptr<uint8_t[]> m_wave_ram; uint16_t m_segment_cnt; uint8_t m_new_addr; // Flag uint8_t m_env_dir_ctrl; uint8_t m_vol_latch; uint8_t m_flt_latch; - uint8_t m_rp; - uint8_t m_ws; + uint8_t m_rp; + uint8_t m_ws; int m_dir; + int m_pia0_cb2_state; double m_freq; - bool m_active; + uint8_t m_status; int m_ptm_o1; @@ -90,6 +99,7 @@ private: void pia_1_b_w(uint8_t data); DECLARE_WRITE_LINE_MEMBER( ptm_o1 ); + DECLARE_WRITE_LINE_MEMBER( ptm_irq ); }; // device type definition diff --git a/src/mame/drivers/cmi.cpp b/src/mame/drivers/cmi.cpp index e12e5ae3fb6..5da94aebe20 100644 --- a/src/mame/drivers/cmi.cpp +++ b/src/mame/drivers/cmi.cpp @@ -12,7 +12,6 @@ To do: * V12 system software reports that it can't load MIDI support and then hangs. - * V19 system software simply hangs. Information from: @@ -161,7 +160,7 @@ static const int ch_int_levels[8] = { - 0xc ^ 7, 0x8 ^ 7, 0xd ^ 7, 0x9 ^ 7, 0xe ^ 7, 0xa ^ 7, 0xf ^ 7, 0xb ^ 7 + 12 ^ 7, 8 ^ 7, 13 ^ 7, 9 ^ 7, 14 ^ 7, 10 ^ 7, 15 ^ 7, 11 ^ 7 }; #define IRQ_PERRINT_LEVEL (0 ^ 7) @@ -251,6 +250,9 @@ public: template<int cpunum> uint8_t perr_r(offs_t offset); template<int cpunum> void perr_w(offs_t offset, uint8_t data); + uint16_t m_aic_ad565_in[16]; + uint8_t m_aic_mux_latch; + uint8_t aic_ad574_r(); template<int Dac> void aic_dac_w(uint8_t data); void aic_mux_latch_w(uint8_t data); @@ -319,7 +321,6 @@ public: DECLARE_READ_LINE_MEMBER( cmi02_pia2_ca1_r ); DECLARE_WRITE_LINE_MEMBER( cmi02_pia2_cb2_w ); - // ??? uint8_t cmi07_r(); void cmi07_w(uint8_t data); @@ -397,8 +398,7 @@ private: // Video void hblank(); - void update_video_pos(int y, int x, int byte_size); - void video_write(int offset); + template <int Y, int X, bool ByteSize> void update_video_pos(); // Floppy void dma_fdc_rom(); @@ -409,6 +409,7 @@ private: uint8_t *m_q133_rom; uint16_t m_int_state[2]; + uint8_t m_lp_int; uint8_t m_hp_int; std::unique_ptr<uint8_t[]> m_shared_ram; std::unique_ptr<uint8_t[]> m_scratch_ram[2]; @@ -461,7 +462,7 @@ uint32_t cmi_state::screen_update_cmi2x(screen_device &screen, bitmap_rgb32 &bit { const pen_t *pen = m_palette->pens(); uint8_t y_scroll = m_q219_pia->a_output(); - uint8_t invert = (!BIT(m_q219_pia->b_output(), 3)) & 1; + uint8_t invert = BIT(~m_q219_pia->b_output(), 3); for (int y = cliprect.min_y; y <= cliprect.max_y; ++y) { @@ -502,12 +503,8 @@ void cmi_state::hblank() if (v == m_lp_y_port->read()) { - if (_touch) - m_q219_b_touch = 1 << 5; - else - m_q219_b_touch = 0; - - m_q219_pia->ca1_w(_touch ? 1 : 0); + m_q219_b_touch = _touch ? 0 : (1 << 5); + m_q219_pia->ca1_w(_touch ? 0 : 1); if (!_touch || !_tfh) { @@ -528,11 +525,24 @@ void cmi_state::hblank() } -void cmi_state::update_video_pos(int y, int x, int byte_size) +template void cmi_state::update_video_pos< 0, 0, false>(); +template void cmi_state::update_video_pos< 0, 1, false>(); +template void cmi_state::update_video_pos< 0, -1, false>(); +template void cmi_state::update_video_pos< 0, 0, true>(); +template void cmi_state::update_video_pos< 1, 0, false>(); +template void cmi_state::update_video_pos< 1, 1, false>(); +template void cmi_state::update_video_pos< 1, -1, false>(); +template void cmi_state::update_video_pos< 1, 0, true>(); +template void cmi_state::update_video_pos<-1, 0, false>(); +template void cmi_state::update_video_pos<-1, 1, false>(); +template void cmi_state::update_video_pos<-1, -1, false>(); +template void cmi_state::update_video_pos<-1, 0, true>(); + +template <int Y, int X, bool ByteSize> void cmi_state::update_video_pos() { uint8_t *video_addr = &m_video_ram[m_y_pos * (512 / 8) + (m_x_pos / 8)]; - if (byte_size) + if (ByteSize) { *video_addr = m_video_data; } @@ -544,35 +554,8 @@ void cmi_state::update_video_pos(int y, int x, int byte_size) *video_addr |= m_video_data & bit_mask; } - if (y > 0) - m_y_pos = (m_y_pos + 1) & 0xff; - else if (y < 0) - m_y_pos = (m_y_pos - 1) & 0xff; - - if (x > 0) - m_x_pos = (m_x_pos + 1) & 0x1ff; - else if (x < 0) - m_x_pos = (m_x_pos - 1) & 0x1ff; -} - -void cmi_state::video_write(int offset) -{ - switch (offset) - { - case 0x0: update_video_pos( 0, 0, 0); break; - case 0x1: update_video_pos( 0, 1, 0); break; - case 0x2: update_video_pos( 0, -1, 0); break; - case 0x3: update_video_pos( 0, 0, 1); break; - case 0x4: update_video_pos( 1, 0, 0); break; - case 0x5: update_video_pos( 1, 1, 0); break; - case 0x6: update_video_pos( 1, -1, 0); break; - case 0x7: update_video_pos( 1, 0, 1); break; - case 0x8: update_video_pos(-1, 0, 0); break; - case 0x9: update_video_pos(-1, 1, 0); break; - case 0xa: update_video_pos(-1, -1, 0); break; - case 0xb: update_video_pos(-1, 0, 1); break; -// default: osd_printf_debug("Video Write %x %x\n", offset, m_video_data); - } + m_y_pos = (m_y_pos + Y) & 0xff; + m_x_pos = (m_x_pos + X) & 0x1ff; } uint8_t cmi_state::video_r(offs_t offset) @@ -582,7 +565,23 @@ uint8_t cmi_state::video_r(offs_t offset) m_video_data = m_video_ram[m_y_pos * (512 / 8) + (m_x_pos / 8)]; - video_write(offset); + switch (offset & 0x0f) + { + case 0x0: update_video_pos< 0, 0, false>(); break; + case 0x1: update_video_pos< 0, 1, false>(); break; + case 0x2: update_video_pos< 0, -1, false>(); break; + case 0x3: update_video_pos< 0, 0, true>(); break; + case 0x4: update_video_pos< 1, 0, false>(); break; + case 0x5: update_video_pos< 1, 1, false>(); break; + case 0x6: update_video_pos< 1, -1, false>(); break; + case 0x7: update_video_pos< 1, 0, true>(); break; + case 0x8: update_video_pos<-1, 0, false>(); break; + case 0x9: update_video_pos<-1, 1, false>(); break; + case 0xa: update_video_pos<-1, -1, false>(); break; + case 0xb: update_video_pos<-1, 0, true>(); break; + default: break; + } + return m_video_data; } @@ -603,7 +602,23 @@ uint8_t cmi_state::pia_q219_b_r() void cmi_state::video_w(offs_t offset, uint8_t data) { m_video_data = data; - video_write(offset); + + switch (offset & 0x0f) + { + case 0x0: update_video_pos< 0, 0, false>(); break; + case 0x1: update_video_pos< 0, 1, false>(); break; + case 0x2: update_video_pos< 0, -1, false>(); break; + case 0x3: update_video_pos< 0, 0, true>(); break; + case 0x4: update_video_pos< 1, 0, false>(); break; + case 0x5: update_video_pos< 1, 1, false>(); break; + case 0x6: update_video_pos< 1, -1, false>(); break; + case 0x7: update_video_pos< 1, 0, true>(); break; + case 0x8: update_video_pos<-1, 0, false>(); break; + case 0x9: update_video_pos<-1, 1, false>(); break; + case 0xa: update_video_pos<-1, -1, false>(); break; + case 0xb: update_video_pos<-1, 0, true>(); break; + default: break; + } } void cmi_state::vscroll_w(uint8_t data) @@ -689,8 +704,7 @@ template<int cpunum> uint8_t cmi_state::vector_r(offs_t offset) template<int cpunum> uint8_t cmi_state::map_r() { - uint8_t data = (m_cpu_active_space[1] << 2) | (m_cpu_active_space[0] << 1) | cpunum; - return data; + return (m_cpu_active_space[1] << 2) | (m_cpu_active_space[0] << 1) | cpunum; } template<int cpunum> void cmi_state::map_w(uint8_t data) @@ -706,7 +720,7 @@ template<int cpunum> uint8_t cmi_state::irq_ram_r(offs_t offset) if (m_m6809_bs_hack_cnt[cpunum] > 0) { m_m6809_bs_hack_cnt[cpunum]--; - LOG("CPU%d IRQ vector byte %d (offset %d): %02x\n", cpunum, 1 - m_m6809_bs_hack_cnt[cpunum], offset, m_irq_address[cpunum][offset]); + LOG("CPU%d IRQ vector byte %d (offset %d): %02x\n", cpunum + 1, 1 - m_m6809_bs_hack_cnt[cpunum], offset, m_irq_address[cpunum][offset]); return m_irq_address[cpunum][offset]; } return m_scratch_ram[cpunum][0xf8 + offset]; @@ -761,7 +775,6 @@ void cmi_state::cpufunc_w(uint8_t data) case 0: set_interrupt(cpunum, IRQ_IPI2_LEVEL, bit ? ASSERT_LINE : CLEAR_LINE); break; case 2: // TODO: Hardware trace - osd_printf_debug("TODO: Hardware trace %02x\n", data); break; case 4: m_cpu_map_switch[cpunum] = bit; break; @@ -919,7 +932,7 @@ static INPUT_PORTS_START( cmi2x ) PORT_BIT( 0xffff, VBLANK_START/2, IPT_LIGHTGUN_Y) PORT_NAME ("Lightpen Y") PORT_MINMAX(0, VBLANK_START - 1) PORT_SENSITIVITY(50) PORT_CROSSHAIR(Y, 1.0, 0.0, 0) PORT_START("LP_TOUCH") - PORT_BIT( 0x01, IP_ACTIVE_HIGH, IPT_BUTTON1 ) PORT_NAME ( "Lightpen Touch" ) PORT_CODE( MOUSECODE_BUTTON1 ) + PORT_BIT( 0x01, IP_ACTIVE_LOW, IPT_BUTTON1 ) PORT_NAME ( "Lightpen Touch" ) PORT_CODE( MOUSECODE_BUTTON1 ) INPUT_PORTS_END bool cmi_state::map_is_active(int cpunum, int map, uint8_t *map_info) @@ -1029,6 +1042,12 @@ void cmi_state::cmi07_w(uint8_t data) { LOG("%s: cmi07_w: %02x\n", machine().describe_context(), data); + if (true) + { + return; + } + + const uint8_t prev = m_cmi07_ctrl; m_cmi07_ctrl = data; m_cmi07cpu->set_input_line(INPUT_LINE_RESET, BIT(data, 0) ? CLEAR_LINE : ASSERT_LINE); @@ -1040,6 +1059,10 @@ void cmi_state::cmi07_w(uint8_t data) uint8_t map_info = (m_cpu_active_space[0] == MAPPING_A) ? m_map_sel[MAPSEL_P1_A] : m_map_sel[MAPSEL_P1_B]; update_address_space(0, map_info); + /* CPU 2 space is untouched by this update */ + if (BIT(prev & data, 7)) + return; + map_info = (m_cpu_active_space[1] == MAPPING_A) ? m_map_sel[MAPSEL_P2_A] : m_map_sel[MAPSEL_P2_B]; update_address_space(1, map_info); } @@ -1340,31 +1363,39 @@ uint8_t cmi_state::cmi02_r(offs_t offset) } else { - LOG("%s: CMI02 R: %x\n", machine().describe_context(), offset); - + uint8_t data = 0; switch (offset) { case 0x20: case 0x21: case 0x22: case 0x23: - return m_cmi02_pia[0]->read(offset & 3); + data = m_cmi02_pia[0]->read(offset & 3); + LOG("%s: CMI02 PIA 1 read (offset %d): %02x\n", machine().describe_context(), offset & 3, data); + return data; case 0x26: m_maincpu2->set_input_line(INPUT_LINE_HALT, ASSERT_LINE); /* LS123 one-shot with 10n and 150k */ m_jam_timeout_timer->adjust(attotime::from_usec(675)); + LOG("%s: CMI02 Jam Timeout timer trigger read: %02x\n", machine().describe_context(), 0xff); return 0xff; case 0x27: m_maincpu2->set_input_line(INPUT_LINE_HALT, CLEAR_LINE); + LOG("%s: CMI02 CPU2 Unhalt read: %02x\n", machine().describe_context(), 0xff); return 0xff; case 0x28: case 0x29: case 0x2a: case 0x2b: - return m_cmi02_pia[1]->read(offset & 3); + data = m_cmi02_pia[1]->read(offset & 3); + LOG("%s: CMI02 PIA 2 read (offset %d): %02x\n", machine().describe_context(), offset & 3, data); + return data; case 0x38: case 0x39: case 0x3a: case 0x3b: case 0x3c: case 0x3d: case 0x3e: case 0x3f: - return m_cmi02_ptm->read(offset & 7); + data = m_cmi02_ptm->read(offset & 7); + LOG("%s: CMI02 PTM read (offset %d): %02x\n", machine().describe_context(), offset & 7, data); + return data; default: - return 0; + LOG("%s: CMI02 Unknown read (offset %02x): %02x\n", machine().describe_context(), offset, 0x00); + return data; } } } @@ -1383,44 +1414,44 @@ void cmi_state::cmi02_w(offs_t offset, uint8_t data) } else { - if (offset == 0x30) - { - LOG("%s: CMI02 W: %x %x, clearing IRQ merger bit 1\n", machine().describe_context(), offset, data); - } - else - { - LOG("%s: CMI02 W: %x %x\n", machine().describe_context(), offset, data); - } - switch (offset) { case 0x20: case 0x21: case 0x22: case 0x23: + LOG("%s: CMI02 PIA 1 write (offset %d): %02x\n", machine().describe_context(), offset & 3, data); m_cmi02_pia[0]->write(offset & 3, data); break; case 0x28: case 0x29: case 0x2a: case 0x2b: + LOG("%s: CMI02 PIA 2 write (offset %d): %02x\n", machine().describe_context(), offset & 3, data); m_cmi02_pia[1]->write(offset & 3, data); break; case 0x30: - m_maincpu1_irq_merger->in_w<1>(0); + LOG("%s: CMI02 PICU 3 B/SGS write (clearing main CPU IRQ merger, clearing high-prio IRQ): %02x\n", machine().describe_context(), data); m_hp_int = 0; + m_maincpu1_irq_merger->in_w<1>(0); + //if (m_lp_int == 0) + // m_maincpu1->set_input_line(M6809_IRQ_LINE, CLEAR_LINE); m_i8214[2]->b_sgs_w(~(data & 0xf)); break; case 0x31: case 0x32: + LOG("%s: CMI02 INTP1 %s write: %02x\n", machine().describe_context(), (offset & 2) ? "clear" : "set", data); set_interrupt(0, IRQ_INTP1_LEVEL, (offset & 2) ? CLEAR_LINE : ASSERT_LINE); break; case 0x33: case 0x34: + LOG("%s: CMI02 INTP2 %s write: %02x\n", machine().describe_context(), (offset & 4) ? "clear" : "set", data); set_interrupt(1, IRQ_INTP2_LEVEL, (offset & 4) ? CLEAR_LINE : ASSERT_LINE); break; case 0x38: case 0x39: case 0x3a: case 0x3b: case 0x3c: case 0x3d: case 0x3e: case 0x3f: + LOG("%s: CMI02 PTM write (offset %d): %02x\n", machine().describe_context(), offset & 7, data); m_cmi02_ptm->write(offset & 7, data); break; default: + LOG("%s: CMI02 Unknown write (offset %02x): %02x\n", machine().describe_context(), offset, data); break; } } @@ -1441,8 +1472,11 @@ void cmi_state::install_video_ram(int cpunum) void cmi_state::i8214_cpu1_w(uint8_t data) { - LOG("%s: i8214_cpu1_w, clearing IRQ merger bit 0: %02x\n", machine().describe_context(), data); + //LOG("%s: i8214_cpu1_w, clearing IRQ merger bit 0: %02x\n", machine().describe_context(), data); m_maincpu1_irq_merger->in_w<0>(0); + m_lp_int = 0; + //if (m_hp_int == 0) + // m_maincpu1->set_input_line(M6809_IRQ_LINE, CLEAR_LINE); m_i8214[0]->b_sgs_w(~(data & 0xf)); } @@ -1469,7 +1503,6 @@ template<int cpunum> void cmi_state::perr_w(offs_t offset, uint8_t data) m_q256_ram[BIT(ram_index, 7)][(ram_index & 0x7f) * PAGE_SIZE + offset % PAGE_SIZE] = data; } -// TODO: replace with share() uint8_t cmi_state::shared_ram_r(offs_t offset) { return m_shared_ram[offset]; @@ -1477,15 +1510,16 @@ uint8_t cmi_state::shared_ram_r(offs_t offset) void cmi_state::shared_ram_w(offs_t offset, uint8_t data) { - //logerror("shared_ram_w: %04x = %02x\n", 0xfe00 + offset, data); m_shared_ram[offset] = data; } uint8_t cmi_state::aic_ad574_r() { - LOG("%s: AIC AD574 read\n", machine().describe_context()); - // To Do - return 0; + const bool adca = BIT(m_aic_mux_latch, 5); // false - MSB, true - LSB + const uint16_t val = m_aic_ad565_in[m_aic_mux_latch & 0x07]; + const uint8_t data = adca ? ((uint8_t)val) : (val >> 8); + LOG("%s: AIC AD574 read: %02x\n", machine().describe_context(), data); + return data; } template<int Dac> void cmi_state::aic_dac_w(uint8_t data) @@ -1497,20 +1531,35 @@ template<int Dac> void cmi_state::aic_dac_w(uint8_t data) void cmi_state::aic_mux_latch_w(uint8_t data) { LOG("%s: AIC mux latch write: %02x\n", machine().describe_context(), data); - set_interrupt(CPU_1, IRQ_AIC_LEVEL, (BIT(data, 6) && BIT(data, 7)) ? ASSERT_LINE : CLEAR_LINE); - // To Do + set_interrupt(CPU_1, IRQ_AIC_LEVEL, BIT(data, 7) ? ASSERT_LINE : CLEAR_LINE); + if (data & 0x07) + { + m_aic_mux_latch = data; + } + else + { + m_aic_mux_latch &= 0x07; + m_aic_mux_latch |= data & 0xf8; + } + if (!BIT(data, 6)) + { + LOG("%s: ADCR is 0, initiating ADC conversion request\n", machine().describe_context()); + m_aic_ad565_in[m_aic_mux_latch & 0x07] = 0; + } } void cmi_state::aic_ad565_msb_w(uint8_t data) { - LOG("%s: AIC AD565 MSB write: %02x\n", machine().describe_context(), data); - // To Do + m_aic_ad565_in[m_aic_mux_latch & 0x07] &= 0x00ff; + m_aic_ad565_in[m_aic_mux_latch & 0x07] |= (uint16_t)data << 8; + LOG("%s: AIC AD565 MSB write: %02x, input %04x\n", machine().describe_context(), data, m_aic_ad565_in[m_aic_mux_latch & 0x07]); } void cmi_state::aic_ad565_lsb_w(uint8_t data) { LOG("%s: AIC AD565 LSB write: %02x\n", machine().describe_context(), data); - // To Do + m_aic_ad565_in[m_aic_mux_latch & 0x07] &= 0xff00; + m_aic_ad565_in[m_aic_mux_latch & 0x07] |= data; } void cmi_state::install_peripherals(int cpunum) @@ -1540,7 +1589,7 @@ void cmi_state::install_peripherals(int cpunum) space->install_readwrite_handler(0xfc8c, 0xfc8f, read8sm_delegate(*m_q133_acia[3], FUNC(mos6551_device::read)), write8sm_delegate(*m_q133_acia[3], FUNC(mos6551_device::write))); space->install_readwrite_handler(0xfc90, 0xfc97, read8sm_delegate(*m_q133_ptm, FUNC(ptm6840_device::read)), write8sm_delegate(*m_q133_ptm, FUNC(ptm6840_device::write))); - space->install_write_handler(0xfca0, 0xfca0, write8smo_delegate(*this, FUNC(cmi_state::midi_latch_w))); + //space->install_write_handler(0xfca0, 0xfca0, write8smo_delegate(*this, FUNC(cmi_state::midi_latch_w))); space->install_readwrite_handler(0xfcbc, 0xfcbc, read8smo_delegate(*this, FUNC(cmi_state::cmi07_r)), write8smo_delegate(*this, FUNC(cmi_state::cmi07_w))); @@ -1603,6 +1652,10 @@ IRQ_CALLBACK_MEMBER( cmi_state::cpu1_interrupt_callback ) LOG("%s: CPU1 interrupt, will be pushing address %02x%02x\n", machine().describe_context(), m_irq_address[CPU_1][0], m_irq_address[CPU_1][1]); } + else + { + LOG("%s: Some other CPU1 interrupt, line %d\n", irqline); + } return 0; } @@ -1646,9 +1699,6 @@ void cmi_state::set_interrupt(int cpunum, int level, int state) { m_i8214[1]->r_all_w(~m_int_state[cpunum]); } - - //i8214_device *i8214 = ((cpunum == CPU_2) ? m_i8214[1] : (level < 8 ? m_i8214[2] : m_i8214[0])); - //i8214->r_w(level & 7, state ? 0 : 1); } WRITE_LINE_MEMBER( cmi_state::maincpu1_irq_w ) @@ -1668,7 +1718,8 @@ WRITE_LINE_MEMBER( cmi_state::i8214_1_int_w ) LOG("%s: i8214_1_int_w %d%s\n", machine().describe_context(), state, state ? ", setting IRQ merger bit 0" : ""); if (state) { - m_hp_int = 0; + m_lp_int = 1; + //m_maincpu1->set_input_line(M6809_IRQ_LINE, ASSERT_LINE); m_maincpu1_irq_merger->in_w<0>(state); } } @@ -1688,6 +1739,9 @@ WRITE_LINE_MEMBER( cmi_state::i8214_3_int_w ) m_hp_int = 1; m_maincpu1_irq_merger->in_w<1>(state); } + //m_hp_int = 1; + //m_maincpu1->set_input_line(M6809_IRQ_LINE, ASSERT_LINE); + //m_maincpu1->set_input_line(M6809_IRQ_LINE, state ? ASSERT_LINE : CLEAR_LINE); } @@ -1814,11 +1868,24 @@ void cmi_state::machine_reset() m_cmi07_ctrl = 0; m_cmi07cpu->set_input_line(INPUT_LINE_RESET, ASSERT_LINE); + // SMIDI + m_midicpu->set_input_line(INPUT_LINE_HALT, ASSERT_LINE); + m_cmi02_ptm_irq = 0; + m_cmi02_ptm->set_c2(1); + m_cmi02_ptm->set_g1(0); + m_cmi02_ptm->set_g2(0); + m_cmi02_ptm->set_g3(0); m_m6809_bs_hack_cnt[0] = 0; m_m6809_bs_hack_cnt[1] = 0; memset(m_map_sel, 0, 16); + + for (int i = 0; i < 4; i++) + { + m_q133_acia[i]->write_dsr(0); + m_q133_acia[i]->write_dcd(0); + } } void cmi_state::machine_start() @@ -1947,7 +2014,8 @@ void cmi_state::cmi2x(machine_config &config) m_cmi02_pia[1]->readca1_handler().set(FUNC(cmi_state::cmi02_pia2_ca1_r)); m_cmi02_pia[1]->cb2_handler().set(FUNC(cmi_state::cmi02_pia2_cb2_w)); - PTM6840(config, m_cmi02_ptm, SYSTEM_CAS_CLOCK); // ptm_cmi02_config, clock is incorrect + PTM6840(config, m_cmi02_ptm, SYSTEM_CAS_CLOCK); + m_cmi02_ptm->set_external_clocks(0, 0, 0); m_cmi02_ptm->o2_callback().set(FUNC(cmi_state::cmi02_ptm_o2)); m_cmi02_ptm->irq_callback().set(FUNC(cmi_state::cmi02_ptm_irq)); diff --git a/src/mame/machine/cmi_mkbd.cpp b/src/mame/machine/cmi_mkbd.cpp index b8bbd84e6b0..2128f88c5b1 100644 --- a/src/mame/machine/cmi_mkbd.cpp +++ b/src/mame/machine/cmi_mkbd.cpp @@ -56,6 +56,7 @@ cmi_music_keyboard_device::cmi_music_keyboard_device(const machine_config &mconf , m_dp3(*this, "dp3") , m_keypad_a_port(*this, "KEYPAD_A") , m_keypad_b_port(*this, "KEYPAD_B") + , m_analog(*this, "ANALOG") , m_key_mux_ports{ { *this, "KEY_%u_0", 0 }, { *this, "KEY_%u_1", 0 }, { *this, "KEY_%u_2", 0 }, { *this, "KEY_%u_3", 0 } } , m_digit(*this, "digit%u", 0U) { @@ -128,20 +129,6 @@ void cmi_music_keyboard_device::cmi10_u20_a_w(u8 data) void cmi_music_keyboard_device::cmi10_u20_b_w(u8 data) { - // connected to alphanumeric display control lines - u8 const addr = bitswap<2>(data, 0, 1); - - m_dp1->ce_w(BIT(data, 6)); - m_dp1->cu_w(BIT(data, 7)); - m_dp1->addr_w(addr); - - m_dp2->ce_w(BIT(data, 4)); - m_dp2->cu_w(BIT(data, 5)); - m_dp2->addr_w(addr); - - m_dp3->ce_w(BIT(data, 2)); - m_dp3->cu_w(BIT(data, 3)); - m_dp3->addr_w(addr); } READ_LINE_MEMBER( cmi_music_keyboard_device::cmi10_u20_cb1_r ) @@ -159,10 +146,30 @@ READ_LINE_MEMBER( cmi_music_keyboard_device::cmi10_u20_cb1_r ) WRITE_LINE_MEMBER( cmi_music_keyboard_device::cmi10_u20_cb2_w ) { - // connected to alphanumeric display write strobe + uint8_t data = m_cmi10_pia_u20->a_output() & 0x7f; + uint8_t b_port = m_cmi10_pia_u20->b_output(); + int addr = (BIT(b_port, 0) << 1) | BIT(b_port, 1); + + /* DP1 */ + m_dp1->ce_w(BIT(b_port, 6)); + m_dp1->cu_w(BIT(b_port, 7)); m_dp1->wr_w(state); + m_dp1->addr_w(addr); + m_dp1->data_w(data); + + /* DP2 */ + m_dp2->ce_w(BIT(b_port, 4)); + m_dp2->cu_w(BIT(b_port, 5)); m_dp2->wr_w(state); + m_dp2->addr_w(addr); + m_dp2->data_w(data); + + /* DP3 */ + m_dp3->ce_w(BIT(b_port, 2)); + m_dp3->cu_w(BIT(b_port, 3)); m_dp3->wr_w(state); + m_dp3->addr_w(addr); + m_dp3->data_w(data); } template <unsigned N> void cmi_music_keyboard_device::update_dp(offs_t offset, u16 data) @@ -194,9 +201,9 @@ u8 cmi_music_keyboard_device::cmi10_u21_a_r() u8 keyval; int state = 1; - if (mux == 0 && key == 3) + if (module == 1 && mux == 2 && key == 3) { - //keyval = input_port_read(device->machine, "ANALOG"); + keyval = m_analog->read(); /* Unpressed */ if (keyval <= 0) @@ -234,6 +241,18 @@ u8 cmi_music_keyboard_device::cmi10_u21_a_r() data |= BIT(keyval, key) << module; } + /* Now do KD7 */ + { + int bit = 0; + + if (BIT(sel, 3)) + bit = BIT(m_keypad_a_port->read(), sel & 7); + else if (!BIT(sel, 4)) + bit = BIT(m_keypad_b_port->read(), sel & 7); + + data |= (bit && BIT(sel, 7)) << 7; + } + return data; #endif } @@ -243,13 +262,9 @@ WRITE_LINE_MEMBER( cmi_music_keyboard_device::kbd_acia_int ) m_kbd_acia_irq = state; if (m_kbd_acia_irq) - { m_cpu->set_input_line(INPUT_LINE_IRQ0, ASSERT_LINE); - } else if (!m_cmi_acia_irq) - { m_cpu->set_input_line(INPUT_LINE_IRQ0, CLEAR_LINE); - } } WRITE_LINE_MEMBER( cmi_music_keyboard_device::cmi_acia_int ) @@ -435,6 +450,9 @@ static INPUT_PORTS_START(cmi_music_keyboard) PORT_START("KEY_2_3") PORT_BIT(0xff, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_NAME("F6") + + PORT_START("ANALOG") + PORT_BIT(0xff, 0x00, IPT_PEDAL) PORT_MINMAX(0, 128) PORT_SENSITIVITY(100) PORT_KEYDELTA(50) INPUT_PORTS_END ioport_constructor cmi_music_keyboard_device::device_input_ports() const diff --git a/src/mame/machine/cmi_mkbd.h b/src/mame/machine/cmi_mkbd.h index dd5a87e3b57..653083ce939 100644 --- a/src/mame/machine/cmi_mkbd.h +++ b/src/mame/machine/cmi_mkbd.h @@ -76,6 +76,7 @@ private: required_ioport m_keypad_a_port; required_ioport m_keypad_b_port; + required_ioport m_analog; required_ioport_array<3> m_key_mux_ports[4]; |