-cmi2x: Fix 6809 interrupt vectoring. [Ryan Holtz]

This commit is contained in:
therealmogminer@gmail.com 2016-09-25 04:22:02 +02:00
parent 75e538c17f
commit 3953342c25
5 changed files with 258 additions and 179 deletions

View File

@ -24,26 +24,26 @@ const device_type I8214 = &device_creator<i8214_device>;
//**************************************************************************
// INLINE HELPERS
// HELPERS
//**************************************************************************
//-------------------------------------------------
// trigger_interrupt -
//-------------------------------------------------
inline void i8214_device::trigger_interrupt(int level)
void i8214_device::trigger_interrupt(int level)
{
if (LOG) logerror("I8214 '%s' Interrupt Level %u\n", tag(), level);
m_a = level;
// disable interrupts
// disable more interrupts from being latched
m_int_dis = 1;
// disable next level group
m_write_enlg(0);
// toggle interrupt line
// set interrupt line
m_write_irq(ASSERT_LINE);
m_write_irq(CLEAR_LINE);
}
@ -53,19 +53,17 @@ inline void i8214_device::trigger_interrupt(int level)
// check_interrupt -
//-------------------------------------------------
inline void i8214_device::check_interrupt()
void i8214_device::check_interrupt()
{
int level;
if (m_int_dis || !m_etlg || !m_inte) return;
if (m_int_dis || !m_etlg) return;
for (level = 7; level >= 0; level--)
for (int level = 7; level >= 0; level--)
{
if (!BIT(m_r, 7 - level))
{
if (m_sgs)
{
if (level > m_b)
if (level > m_current_status)
{
trigger_interrupt(level);
}
@ -88,10 +86,17 @@ inline void i8214_device::check_interrupt()
// i8214_device - constructor
//-------------------------------------------------
i8214_device::i8214_device(const machine_config &mconfig, const char *tag, device_t *owner, UINT32 clock) :
device_t(mconfig, I8214, "I8214", tag, owner, clock, "i8214", __FILE__),
m_write_irq(*this),
m_write_enlg(*this)
i8214_device::i8214_device(const machine_config &mconfig, const char *tag, device_t *owner, UINT32 clock)
: device_t(mconfig, I8214, "I8214", tag, owner, clock, "i8214", __FILE__)
, m_write_irq(*this)
, m_write_enlg(*this)
, m_inte(0)
, m_int_dis(0)
, m_a(0)
, m_current_status(0)
, m_r(0xff)
, m_sgs(0)
, m_etlg(1)
{
}
@ -107,12 +112,13 @@ void i8214_device::device_start()
m_write_enlg.resolve_safe();
m_int_dis = 0;
m_etlg = 1;
// register for state saving
save_item(NAME(m_inte));
save_item(NAME(m_int_dis));
save_item(NAME(m_a));
save_item(NAME(m_b));
save_item(NAME(m_current_status));
save_item(NAME(m_r));
save_item(NAME(m_sgs));
save_item(NAME(m_etlg));
@ -139,9 +145,9 @@ UINT8 i8214_device::a_r()
void i8214_device::b_w(UINT8 data)
{
m_b = data & 0x07;
m_current_status = data & 0x07;
if (LOG) logerror("I8214 '%s' B: %01x\n", tag(), m_b);
if (LOG) logerror("I8214 '%s' B: %01x\n", tag(), m_current_status);
// enable interrupts
m_int_dis = 0;
@ -154,14 +160,16 @@ void i8214_device::b_w(UINT8 data)
//-------------------------------------------------
// r_w -
// r_w - update the interrupt request
// state for a given line
//-------------------------------------------------
void i8214_device::r_w(UINT8 data)
void i8214_device::r_w(int line, int state)
{
if (LOG) logerror("I8214 '%s' R: %02x\n", tag(), data);
if (LOG) logerror("I8214 '%s' R%d: %d\n", tag(), line, state);
m_r = data;
m_r &= ~(1 << line);
m_r |= (state << line);
check_interrupt();
}

View File

@ -63,23 +63,24 @@ public:
UINT8 a_r();
void b_w(UINT8 data);
void r_w(UINT8 data);
void r_w(int line, int state);
protected:
// device-level overrides
virtual void device_start() override;
private:
inline void trigger_interrupt(int level);
inline void check_interrupt();
void trigger_interrupt(int level);
void check_interrupt();
void update_interrupt_line();
devcb_write_line m_write_irq;
devcb_write_line m_write_enlg;
int m_inte; // interrupt enable
int m_int_dis; // interrupt disable flip-flop
int m_int_dis; // interrupt (latch) disable flip-flop
int m_a; // request level
int m_b; // current status register
int m_current_status;
UINT8 m_r; // interrupt request latch
int m_sgs; // status group select
int m_etlg; // enable this level group

View File

@ -157,37 +157,37 @@
#define MAPSEL_P1_A_DMA3 0x0e
#define MAPSEL_P1_A_DMA4 0x0f
#define IRQ_ACINT_LEVEL (7 - 0)
#define IRQ_MIDINT_LEVEL (7 - 0)
#define IRQ_TIMINT_LEVEL (7 - 1)
#define IRQ_INTP1_LEVEL (7 - 2)
#define IRQ_IPI1_LEVEL (7 - 3)
#define IRQ_SMIDINT_LEVEL (7 - 3)
#define IRQ_AIC_LEVEL (7 - 4)
#define IRQ_ACINT_LEVEL (0 ^ 7)
#define IRQ_MIDINT_LEVEL (0 ^ 7)
#define IRQ_TIMINT_LEVEL (1 ^ 7)
#define IRQ_INTP1_LEVEL (2 ^ 7)
#define IRQ_IPI1_LEVEL (3 ^ 7)
#define IRQ_SMIDINT_LEVEL (3 ^ 7)
#define IRQ_AIC_LEVEL (4 ^ 7)
#define IRQ_CHINT2_LEVEL (8)
#define IRQ_CHINT4_LEVEL (9)
#define IRQ_CHINT6_LEVEL (10)
#define IRQ_CHINT8_LEVEL (11)
#define IRQ_CHINT1_LEVEL (12)
#define IRQ_CHINT3_LEVEL (13)
#define IRQ_CHINT5_LEVEL (14)
#define IRQ_CHINT7_LEVEL (15)
#define IRQ_CHINT8_LEVEL (15 ^ 7)
#define IRQ_CHINT7_LEVEL (14 ^ 7)
#define IRQ_CHINT6_LEVEL (13 ^ 7)
#define IRQ_CHINT5_LEVEL (12 ^ 7)
#define IRQ_CHINT4_LEVEL (11 ^ 7)
#define IRQ_CHINT3_LEVEL (10 ^ 7)
#define IRQ_CHINT2_LEVEL (9 ^ 7)
#define IRQ_CHINT1_LEVEL (8 ^ 7)
static const int ch_int_levels[8] =
{
IRQ_CHINT8_LEVEL, IRQ_CHINT7_LEVEL, IRQ_CHINT6_LEVEL, IRQ_CHINT5_LEVEL, IRQ_CHINT4_LEVEL, IRQ_CHINT3_LEVEL, IRQ_CHINT2_LEVEL, IRQ_CHINT1_LEVEL
12, 8, 13, 9, 14, 10, 15, 11 //IRQ_CHINT8_LEVEL, IRQ_CHINT7_LEVEL, IRQ_CHINT6_LEVEL, IRQ_CHINT5_LEVEL, IRQ_CHINT4_LEVEL, IRQ_CHINT3_LEVEL, IRQ_CHINT2_LEVEL, IRQ_CHINT1_LEVEL
};
#define IRQ_PERRINT_LEVEL (7 - 0)
#define IRQ_RTCINT_LEVEL (7 - 0)
#define IRQ_RINT_LEVEL (7 - 1)
#define IRQ_INTP2_LEVEL (7 - 2)
#define IRQ_IPI2_LEVEL (7 - 3)
#define IRQ_TOUCHINT_LEVEL (7 - 4)
#define IRQ_PENINT_LEVEL (7 - 5)
#define IRQ_ADINT_LEVEL (7 - 6)
#define IRQ_DISKINT_LEVEL (7 - 7)
#define IRQ_PERRINT_LEVEL (0 ^ 7)
#define IRQ_RTCINT_LEVEL (0 ^ 7)
#define IRQ_RINT_LEVEL (1 ^ 7)
#define IRQ_INTP2_LEVEL (2 ^ 7)
#define IRQ_IPI2_LEVEL (3 ^ 7)
#define IRQ_TOUCHINT_LEVEL (4 ^ 7)
#define IRQ_PENINT_LEVEL (5 ^ 7)
#define IRQ_ADINT_LEVEL (6 ^ 7)
#define IRQ_DISKINT_LEVEL (7 ^ 7)
#define FDC_CONTROL_INTEN (1 << 2)
@ -215,21 +215,26 @@ public:
static void set_channel_number(device_t &device, int channel) { dynamic_cast<cmi01a_device&>(device).m_channel = channel; }
DECLARE_WRITE8_MEMBER( cmi01a_ptm_c0 );
DECLARE_WRITE8_MEMBER( ptm_out0 );
DECLARE_WRITE8_MEMBER( write );
DECLARE_READ8_MEMBER( read );
DECLARE_WRITE_LINE_MEMBER( cmi01a_1_ca2_w );
DECLARE_WRITE_LINE_MEMBER( ch_int );
DECLARE_WRITE_LINE_MEMBER( cmi01a_1_cb2_w );
DECLARE_WRITE_LINE_MEMBER( pia_0_ca2_w );
DECLARE_WRITE_LINE_MEMBER( pia_0_cb2_w );
DECLARE_WRITE_LINE_MEMBER( pia_0_irqa );
DECLARE_WRITE_LINE_MEMBER( pia_0_irqb );
DECLARE_WRITE8_MEMBER( pia_1_a_w );
DECLARE_WRITE8_MEMBER( pia_1_b_w );
DECLARE_WRITE_LINE_MEMBER( pia_1_irqa );
DECLARE_WRITE_LINE_MEMBER( pia_1_irqb );
DECLARE_WRITE_LINE_MEMBER( ptm_irq );
DECLARE_READ_LINE_MEMBER( eosi_r );
DECLARE_READ_LINE_MEMBER( zx_r );
DECLARE_WRITE8_MEMBER( cmi01a_2_a_w );
DECLARE_WRITE8_MEMBER( cmi01a_2_b_w );
virtual void sound_stream_update(sound_stream &stream, stream_sample_t **inputs, stream_sample_t **outputs, int samples) override;
protected:
@ -253,6 +258,7 @@ private:
void zx_timer_cb();
void run_voice();
void update_wave_addr(int inc);
void update_interrupts();
emu_timer * m_zx_timer;
UINT8 m_zx_flag;
@ -269,7 +275,14 @@ private:
double m_freq;
bool m_active;
int m_ptm_output;
int m_ptm_out0;
int m_pia_0_irqa;
int m_pia_0_irqb;
int m_pia_1_irqa;
int m_pia_1_irqb;
int m_ptm_irq;
int m_irq_state;
};
const device_type CMI01A_CHANNEL_CARD = &device_creator<cmi01a_device>;
@ -288,24 +301,24 @@ cmi01a_device::cmi01a_device(const machine_config &mconfig, const char *tag, dev
MACHINE_CONFIG_FRAGMENT( cmi01a_device )
MCFG_DEVICE_ADD("cmi01a_pia_0", PIA6821, 0) // pia_cmi01a_1_config
MCFG_PIA_CA2_HANDLER(WRITELINE(cmi01a_device, cmi01a_1_ca2_w))
MCFG_PIA_CB2_HANDLER(WRITELINE(cmi01a_device, cmi01a_1_cb2_w))
MCFG_PIA_IRQA_HANDLER(WRITELINE(cmi01a_device, ch_int))
MCFG_PIA_IRQB_HANDLER(WRITELINE(cmi01a_device, ch_int))
MCFG_PIA_CA2_HANDLER(WRITELINE(cmi01a_device, pia_0_ca2_w))
MCFG_PIA_CB2_HANDLER(WRITELINE(cmi01a_device, pia_0_cb2_w))
MCFG_PIA_IRQA_HANDLER(WRITELINE(cmi01a_device, pia_0_irqa))
MCFG_PIA_IRQB_HANDLER(WRITELINE(cmi01a_device, pia_0_irqb))
MCFG_DEVICE_ADD("cmi01a_pia_1", PIA6821, 0) // pia_cmi01a_2_config
MCFG_PIA_READCA1_HANDLER(READLINE(cmi01a_device, zx_r))
MCFG_PIA_READCA2_HANDLER(READLINE(cmi01a_device, eosi_r))
MCFG_PIA_WRITEPA_HANDLER(WRITE8(cmi01a_device, cmi01a_2_a_w))
MCFG_PIA_WRITEPB_HANDLER(WRITE8(cmi01a_device, cmi01a_2_b_w))
MCFG_PIA_IRQA_HANDLER(WRITELINE(cmi01a_device, ch_int))
MCFG_PIA_IRQB_HANDLER(WRITELINE(cmi01a_device, ch_int))
MCFG_PIA_WRITEPA_HANDLER(WRITE8(cmi01a_device, pia_1_a_w))
MCFG_PIA_WRITEPB_HANDLER(WRITE8(cmi01a_device, pia_1_b_w))
MCFG_PIA_IRQA_HANDLER(WRITELINE(cmi01a_device, pia_1_irqa))
MCFG_PIA_IRQB_HANDLER(WRITELINE(cmi01a_device, pia_1_irqb))
MCFG_DEVICE_ADD("cmi01a_ptm", PTM6840, 0) // ptm_cmi01a_config
MCFG_PTM6840_INTERNAL_CLOCK(2000000)
MCFG_PTM6840_EXTERNAL_CLOCKS(250000, 500000, 500000)
MCFG_PTM6840_OUT0_CB(WRITE8(cmi01a_device, cmi01a_ptm_c0))
MCFG_PTM6840_IRQ_CB(WRITELINE(cmi01a_device, ch_int))
MCFG_PTM6840_OUT0_CB(WRITE8(cmi01a_device, ptm_out0))
MCFG_PTM6840_IRQ_CB(WRITELINE(cmi01a_device, ptm_irq))
MACHINE_CONFIG_END
machine_config_constructor cmi01a_device::device_mconfig_additions() const
@ -351,6 +364,24 @@ void cmi01a_device::device_reset()
m_ptm->set_g1(1);
m_ptm->set_g2(1);
m_ptm->set_g3(1);
m_pia_0_irqa = 0;
m_pia_0_irqb = 0;
m_pia_1_irqa = 0;
m_pia_1_irqb = 0;
m_ptm_irq = 0;
m_irq_state = 0;
m_segment_cnt = 0;
m_new_addr = 0;
m_env_dir_ctrl = 0;
m_vol_latch = 0;
m_flt_latch = 0;
m_freq = 0.0;
m_active = false;
m_ptm_out0 = 0;
}
class cmi_state : public driver_device
@ -467,6 +498,8 @@ public:
DECLARE_WRITE8_MEMBER( cpufunc_w );
DECLARE_READ8_MEMBER( parity_r );
DECLARE_WRITE8_MEMBER( mapsel_w );
DECLARE_READ8_MEMBER( irq_ram_r );
DECLARE_WRITE8_MEMBER( irq_ram_w );
// MIDI/SMPTE
DECLARE_WRITE16_MEMBER( midi_dma_w );
@ -578,9 +611,6 @@ protected:
address_space *m_cpu1space;
address_space *m_cpu2space;
UINT8 *m_q133_rom;
UINT8 m_q133_acia_irq;
private:
emu_timer *m_map_switch_timer;
@ -606,7 +636,10 @@ private:
void write_fdc_ctrl(UINT8 data);
void fdc_dma_transfer();
int m_int_state[2];
// Q133 CPU Card
UINT8 *m_q133_rom;
UINT8 m_q133_acia_irq;
UINT8 m_hp_int;
std::unique_ptr<UINT8[]> m_shared_ram;
std::unique_ptr<UINT8[]> m_scratch_ram[2];
@ -618,6 +651,9 @@ private:
UINT8 m_map_ram_latch;
int m_cpu_active_space[2]; // TODO: Make one register
int m_cpu_map_switch[2];
UINT8 m_irq_address[2][2];
int m_m6809_bs_hack_cnt;
int m_m6809_bs_hack_cpu;
/* Q219 lightpen/graphics card */
std::unique_ptr<UINT8[]> m_video_ram;
@ -711,7 +747,7 @@ void cmi_state::hblank()
else
m_q219_b_touch = 1 << 5;
m_q219_pia->ca1_w(!_touch);
m_q219_pia->ca1_w(!_touch ? 1 : 0);
if (!_touch || !_tfh)
{
@ -886,6 +922,23 @@ WRITE8_MEMBER( cmi_state::map_w )
m_map_switch_timer->adjust(attotime::from_ticks(data & 0xf, M6809_CLOCK), cpunum);
}
READ8_MEMBER( cmi_state::irq_ram_r )
{
int cpunum = (&space.device() == m_maincpu1) ? 0 : 1;
if (m_m6809_bs_hack_cnt > 0 && m_m6809_bs_hack_cpu == cpunum)
{
m_m6809_bs_hack_cnt--;
return m_irq_address[cpunum][offset];
}
return m_scratch_ram[cpunum][0xf8 + offset];
}
WRITE8_MEMBER( cmi_state::irq_ram_w )
{
int cpunum = (&space.device() == m_maincpu1) ? 0 : 1;
m_scratch_ram[cpunum][0xf8 + offset] = data;
}
void cmi_state::device_timer(emu_timer &timer, device_timer_id id, int param, void *ptr)
{
switch (id)
@ -916,7 +969,6 @@ void cmi_state::device_timer(emu_timer &timer, device_timer_id id, int param, vo
m_cmi10_pia_u20->ca1_w(m_scnd);
m_scnd ^= 1;
m_cmi10_pia_u21->ca1_w(m_scnd);
m_map_switch_timer->adjust(attotime::never);
break;
}
}
@ -1635,7 +1687,7 @@ WRITE_LINE_MEMBER( cmi_state::wd1791_drq )
*/
WRITE_LINE_MEMBER( cmi01a_device::cmi01a_1_ca2_w )
WRITE_LINE_MEMBER( cmi01a_device::pia_0_ca2_w )
{
// upate_stream()
if (!state)
@ -1646,10 +1698,62 @@ WRITE_LINE_MEMBER( cmi01a_device::cmi01a_1_ca2_w )
}
}
WRITE_LINE_MEMBER( cmi01a_device::ch_int )
WRITE_LINE_MEMBER( cmi01a_device::pia_0_irqa )
{
//printf("CH%d INT: %x\n", m_channel, state);
dynamic_cast<cmi_state*>(owner())->set_interrupt(CPU_1, ch_int_levels[m_channel], state ? ASSERT_LINE : CLEAR_LINE);
m_pia_0_irqa = state;
//printf("CH%d pia0 irqa int: %x\n", m_channel, state);
update_interrupts();
}
WRITE_LINE_MEMBER( cmi01a_device::pia_0_irqb )
{
m_pia_0_irqb = state;
//printf("CH%d pia0 irqb int: %x\n", m_channel, state);
update_interrupts();
}
WRITE8_MEMBER( cmi_state::master_tune_w )
{
// double mfreq = (double)data * ((double)MASTER_OSCILLATOR / 2.0) / 256.0;
}
WRITE8_MEMBER( cmi01a_device::pia_1_a_w )
{
// top two
}
WRITE8_MEMBER( cmi01a_device::pia_1_b_w )
{
}
WRITE_LINE_MEMBER( cmi01a_device::pia_1_irqa )
{
m_pia_1_irqa = state;
//printf("CH%d pia1 irqa int: %x\n", m_channel, state);
update_interrupts();
}
WRITE_LINE_MEMBER( cmi01a_device::pia_1_irqb )
{
m_pia_1_irqb = state;
//printf("CH%d pia1 irqb int: %x\n", m_channel, state);
update_interrupts();
}
void cmi01a_device::update_interrupts()
{
int old_state = m_irq_state;
m_irq_state = m_pia_0_irqa || m_pia_0_irqb || m_pia_1_irqa || m_pia_1_irqb || m_ptm_irq;
if (m_irq_state != old_state)
dynamic_cast<cmi_state*>(owner())->set_interrupt(CPU_1, ch_int_levels[m_channel], m_irq_state ? ASSERT_LINE : CLEAR_LINE);
}
WRITE_LINE_MEMBER( cmi01a_device::ptm_irq )
{
m_ptm_irq = state;
//printf("CH%d ptm irq int: %x\n", m_channel, state);
update_interrupts();
}
void cmi01a_device::device_timer(emu_timer &timer, device_timer_id id, int param, void *ptr)
@ -1675,7 +1779,7 @@ void cmi01a_device::zx_timer_cb()
if (m_zx_flag == 0)
{
/* Low to high transition - clock flip flop */
int op = m_ptm_output;
int op = m_ptm_out0;
/* Set /ZCINT */
if (op != m_zx_ff)
@ -1717,7 +1821,7 @@ void cmi01a_device::run_voice()
}
}
WRITE_LINE_MEMBER( cmi01a_device::cmi01a_1_cb2_w )
WRITE_LINE_MEMBER( cmi01a_device::pia_0_cb2_w )
{
//streams_update();
@ -1764,6 +1868,7 @@ WRITE_LINE_MEMBER( cmi01a_device::cmi01a_1_cb2_w )
void cmi01a_device::update_wave_addr(int inc)
{
int old_cnt = m_segment_cnt;
//printf("update_wave_addr, m_segment_cnt %04x\n", m_segment_cnt);
if (inc)
++m_segment_cnt;
@ -1772,7 +1877,7 @@ void cmi01a_device::update_wave_addr(int inc)
m_pia_1->cb1_w((m_segment_cnt & 0x4000) >> 14);
/* TODO Update zero crossing flag */
m_pia_1->ca1_w((m_segment_cnt & 0x40));
m_pia_1->ca1_w((m_segment_cnt & 0x40) >> 6);
/* Clock a latch on a transition */
if ((old_cnt & 0x40) && !(m_segment_cnt & 0x40))
@ -1825,7 +1930,7 @@ WRITE8_MEMBER( cmi01a_device::write )
{
/* PTM addressing is a little funky */
int a0 = offset & 1;
int a1 = (m_ptm_output && BIT(offset, 3)) || (!BIT(offset, 3) && BIT(offset, 2));
int a1 = (m_ptm_out0 && BIT(offset, 3)) || (!BIT(offset, 3) && BIT(offset, 2));
int a2 = BIT(offset, 1);
//printf("CH%d PTM: [%x] %x, %d %d %d, %02x\n", m_channel, (a2 << 2) | (a1 << 1) | a0, data, a2, a1, a0, offset);
@ -1870,7 +1975,7 @@ READ8_MEMBER( cmi01a_device::read )
case 0x10: case 0x11: case 0x12: case 0x13: case 0x14: case 0x15: case 0x16: case 0x17:
{
int a0 = offset & 1;
int a1 = (m_ptm_output && BIT(offset, 3)) || (!BIT(offset, 3) && BIT(offset, 2));
int a1 = (m_ptm_out0 && BIT(offset, 3)) || (!BIT(offset, 3) && BIT(offset, 2));
int a2 = BIT(offset, 1);
data = m_ptm->read(space, (a2 << 2) | (a1 << 1) | a0);
@ -1881,16 +1986,16 @@ READ8_MEMBER( cmi01a_device::read )
return data;
}
WRITE8_MEMBER( cmi01a_device::cmi01a_ptm_c0 )
WRITE8_MEMBER( cmi01a_device::ptm_out0 )
{
m_ptm_output = data;
m_ptm_out0 = data;
}
WRITE_LINE_MEMBER( cmi_state::cmi02_ptm_irq )
{
//printf("cmi02_ptm_irq: %d\n", state);
m_cmi02_ptm_irq = state;
set_interrupt(CPU_1, IRQ_TIMINT_LEVEL, m_cmi02_ptm_irq ? ASSERT_LINE : CLEAR_LINE);
//printf("CMI-02 PTM IRQ: %d\n", state);
}
READ8_MEMBER( cmi_state::cmi02_r )
@ -1966,8 +2071,8 @@ WRITE8_MEMBER( cmi_state::cmi02_w )
case 0x30:
m_maincpu1->set_input_line(M6809_IRQ_LINE, CLEAR_LINE);
data ^= 0xff;
m_i8214_2->b_w(data & 0x7);
m_i8214_2->sgs_w((data >> 3) & 1);
m_i8214_2->b_w(data & 0x7);
break;
case 0x31: case 0x32:
@ -2000,8 +2105,8 @@ WRITE8_MEMBER( cmi_state::i8214_cpu1_w )
//printf("i8214_cpu1_w: %02x\n", data);
m_maincpu1->set_input_line(M6809_IRQ_LINE, CLEAR_LINE);
data ^= 0xff;
m_i8214_0->b_w(data & 0x7);
m_i8214_0->sgs_w((data >> 3) & 1);
m_i8214_0->b_w(data & 0x7);
}
@ -2009,8 +2114,8 @@ WRITE8_MEMBER( cmi_state::i8214_cpu2_w )
{
m_maincpu2->set_input_line(M6809_IRQ_LINE, CLEAR_LINE);
data ^= 0xff;
m_i8214_1->b_w(data & 0x7);
m_i8214_1->sgs_w((data >> 3) & 1);
m_i8214_1->b_w(data & 0x7);
}
// TODO: replace with AM_SHARE
@ -2097,8 +2202,10 @@ void cmi_state::install_peripherals(int cpunum)
space->install_readwrite_handler(0xfd00, 0xfeff, read8_delegate(FUNC(cmi_state::shared_ram_r),this), write8_delegate(FUNC(cmi_state::shared_ram_w),this));
space->install_ram(0xff00, 0xfffd, &m_scratch_ram[cpunum][0]);
space->install_ram(0xff00, 0xfff7, &m_scratch_ram[cpunum][0]);
space->install_ram(0xfffa, 0xfffd, &m_scratch_ram[cpunum][0xfa]);
space->install_readwrite_handler(0xfff8, 0xfff9, read8_delegate(FUNC(cmi_state::irq_ram_r),this), write8_delegate(FUNC(cmi_state::irq_ram_w),this));
space->install_read_handler(0xfffe, 0xffff, read8_delegate(FUNC(cmi_state::vector_r),this));
}
@ -2117,91 +2224,76 @@ WRITE_LINE_MEMBER( cmi_state::ptm_q219_irq )
IRQ_CALLBACK_MEMBER( cmi_state::cpu1_interrupt_callback )
{
/* Switch to mapping A */
m_cpu_active_space[0] = MAPPING_A;
update_address_space(0, m_map_sel[MAPSEL_P1_A]);
m_cpu_active_space[CPU_1] = MAPPING_A;
update_address_space(CPU_1, m_map_sel[MAPSEL_P1_A]);
if (irqline == INPUT_LINE_IRQ0)
{
UINT16 address;
address_space &cmi_space = m_maincpu1->space(AS_PROGRAM);
int vector = (m_hp_int ? 0xffe0 : 0xffd0);
int level = (m_hp_int ? m_i8214_2->a_r() : m_i8214_0->a_r()) ^ 7;
m_irq_address[CPU_1][0] = m_cpu1space->read_byte(vector + level*2);
m_irq_address[CPU_1][1] = m_cpu1space->read_byte(vector + level*2 + 1);
if (m_hp_int)
{
int level = m_i8214_2->a_r() ^ 0x7;
address = (cmi_space.read_byte(0xffe0 + level*2) << 8) | cmi_space.read_byte(0xffe0 + level*2 + 1);
//m_hp_int = 0;
}
else
{
int level = m_i8214_0->a_r() ^ 0x7;
address = (cmi_space.read_byte(0xffd0 + level*2) << 8) | cmi_space.read_byte(0xffd0 + level*2 + 1);
}
m_maincpu1->set_pc(address);
m_m6809_bs_hack_cnt = 2;
m_m6809_bs_hack_cpu = CPU_1;
//printf("cpu1 interrupt, will be pushing address %02x%02x\n", m_irq_address[CPU_1][0], m_irq_address[CPU_1][1]);
}
return 0;
}
IRQ_CALLBACK_MEMBER( cmi_state::cpu2_interrupt_callback )
{
/* Switch to mapping A */
m_cpu_active_space[1] = MAPPING_A;
update_address_space(1, m_map_sel[MAPSEL_P2_A]);
m_cpu_active_space[CPU_2] = MAPPING_A;
update_address_space(CPU_2, m_map_sel[MAPSEL_P2_A]);
/* */
if (irqline == INPUT_LINE_IRQ0)
{
int level = m_i8214_1->a_r() ^ 0x7;
m_irq_address[CPU_2][0] = m_cpu2space->read_byte(0xffe0 + level*2);
m_irq_address[CPU_2][1] = m_cpu2space->read_byte(0xffe0 + level*2 + 1);
address_space &cmi_space = m_maincpu2->space(AS_PROGRAM);
UINT16 address = (cmi_space.read_byte(0xffe0 + level*2) << 8) | cmi_space.read_byte(0xffe0 + level*2 + 1);
m_m6809_bs_hack_cnt = 2;
m_m6809_bs_hack_cpu = CPU_2;
m_maincpu2->set_pc(address);
//printf("cpu1 interrupt, will be pushing address %02x%02x\n", m_irq_address[CPU_2][0], m_irq_address[CPU_2][1]);
}
return 0;
}
void cmi_state::set_interrupt(int cpunum, int level, int state)
{
//printf("CPU%d Int: %x State: %x (Cur: %x)\n", cpunum, level, state, m_int_state[cpunum]);
//printf("CPU%d Int: %x State: %x\n", cpunum + 1, level, state);
if (state == ASSERT_LINE)
m_int_state[cpunum] |= (1 << level);
else
m_int_state[cpunum] &= ~(1 << level);
//printf("New int state: %02x\n", m_int_state[cpunum]);
if (cpunum == CPU_1)
{
if (level < 8)
m_i8214_2->r_w(~m_int_state[cpunum]);
else
m_i8214_0->r_w(~(m_int_state[cpunum] >> 8));
}
else
{
m_i8214_1->r_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::i8214_1_int_w )
{
//printf("i8214_1_int_w: %d\n", state);
m_maincpu1->set_input_line(M6809_IRQ_LINE, state ? ASSERT_LINE : CLEAR_LINE);
if (state)
{
//machine().debug_break();
m_maincpu1->set_input_line(M6809_IRQ_LINE, ASSERT_LINE);
}
}
WRITE_LINE_MEMBER( cmi_state::i8214_2_int_w )
{
//printf("i8214_2_int_w: %d\n", state);
m_maincpu2->set_input_line(M6809_IRQ_LINE, state ? ASSERT_LINE : CLEAR_LINE);
if (state)
m_maincpu2->set_input_line(M6809_IRQ_LINE, ASSERT_LINE);
}
WRITE_LINE_MEMBER( cmi_state::i8214_3_int_w )
{
//printf("i8214_3_int_w: %d\n", state);
//if (state)
m_hp_int = state;
m_maincpu1->set_input_line(M6809_IRQ_LINE, state ? ASSERT_LINE : CLEAR_LINE);
m_hp_int = state;
if (state)
m_maincpu1->set_input_line(M6809_IRQ_LINE, ASSERT_LINE);
}
@ -2262,21 +2354,6 @@ WRITE8_MEMBER( cmi_state::q133_1_portb_w )
m_msm5832->cs_w(1);
}
WRITE8_MEMBER( cmi_state::master_tune_w )
{
// double mfreq = (double)data * ((double)MASTER_OSCILLATOR / 2.0) / 256.0;
}
WRITE8_MEMBER( cmi01a_device::cmi01a_2_a_w )
{
// top two
}
WRITE8_MEMBER( cmi01a_device::cmi01a_2_b_w )
{
}
/*
PA0-7 = BKA0-7 (display)
@ -2512,22 +2589,22 @@ void cmi_state::machine_reset()
for (int cpunum = 0; cpunum < 2; ++cpunum)
{
address_space &space = (cpunum == CPU_1 ? m_maincpu1->space(AS_PROGRAM) : m_maincpu2->space(AS_PROGRAM));
address_space *space = (cpunum == CPU_1 ? m_cpu1space : m_cpu2space);
space.unmap_readwrite(0x0000, 0xffff);
space->unmap_readwrite(0x0000, 0xffff);
/* Select A (system) spaces */
m_cpu_active_space[cpunum] = MAPPING_A;
install_peripherals(cpunum);
m_irq_address[cpunum][0] = space->read_byte(0xfff8);
m_irq_address[cpunum][1] = space->read_byte(0xfff9);
}
// TODO - we need to detect empty disk drive!!
m_fdc_status |= FDC_STATUS_READY;
m_int_state[0] = 0;
m_int_state[1] = 0;
/* CMI-07 */
m_cmi07_ctrl = 0;
m_cmi07cpu->set_input_line(INPUT_LINE_RESET, ASSERT_LINE);
@ -2539,6 +2616,8 @@ void cmi_state::machine_reset()
m_ank_irqb = 0;
m_q133_acia_irq = 0;
m_cmi02_ptm_irq = 0;
m_m6809_bs_hack_cnt = 0;
m_m6809_bs_hack_cpu = 0;
}
void cmi_state::machine_start()
@ -2595,10 +2674,12 @@ static MACHINE_CONFIG_START( cmi2x, cmi_state )
MCFG_CPU_PROGRAM_MAP(maincpu1_map)
MCFG_CPU_VBLANK_INT_DRIVER("screen", cmi_state, cmi_iix_vblank)
MCFG_CPU_IRQ_ACKNOWLEDGE_DRIVER(cmi_state, cpu1_interrupt_callback)
MCFG_QUANTUM_PERFECT_CPU("maincpu1")
MCFG_CPU_ADD("maincpu2", M6809E, Q209_CPU_CLOCK)
MCFG_CPU_PROGRAM_MAP(maincpu2_map)
MCFG_CPU_IRQ_ACKNOWLEDGE_DRIVER(cmi_state, cpu2_interrupt_callback)
MCFG_QUANTUM_PERFECT_CPU("maincpu2")
MCFG_CPU_ADD("muskeys", M6802, 3840000)
MCFG_CPU_PROGRAM_MAP(muskeys_map)

View File

@ -153,18 +153,9 @@ Notes:
#include "bus/rs232/rs232.h"
#include "softlist.h"
void v1050_state::set_interrupt(UINT8 mask, int state)
void v1050_state::set_interrupt(int line, int state)
{
if (state)
{
m_int_state |= mask;
}
else
{
m_int_state &= ~mask;
}
m_pic->r_w(~(m_int_state & m_int_mask));
m_pic->r_w(line, (m_int_mask & (1 << state)) ? 0 : 1);
}
void v1050_state::bankswitch()
@ -989,7 +980,6 @@ void v1050_state::machine_start()
// register for state saving
save_item(NAME(m_int_mask));
save_item(NAME(m_int_state));
save_item(NAME(m_f_int_enb));
save_item(NAME(m_fdc_irq));
save_item(NAME(m_fdc_drq));

View File

@ -49,14 +49,14 @@
#define V1050_VIDEORAM_SIZE 0x8000
#define V1050_VIDEORAM_MASK 0x7fff
#define INT_RS_232 0x01
#define INT_WINCHESTER 0x02
#define INT_KEYBOARD 0x04
#define INT_FLOPPY 0x08
#define INT_VSYNC 0x10
#define INT_DISPLAY 0x20
#define INT_EXPANSION_B 0x40
#define INT_EXPANSION_A 0x80
#define INT_RS_232 0
#define INT_WINCHESTER 1
#define INT_KEYBOARD 2
#define INT_FLOPPY 3
#define INT_VSYNC 4
#define INT_DISPLAY 5
#define INT_EXPANSION_B 6
#define INT_EXPANSION_A 7
class v1050_state : public driver_device
{
@ -157,7 +157,7 @@ protected:
private:
void bankswitch();
void update_fdc();
void set_interrupt(UINT8 mask, int state);
void set_interrupt(int line, int state);
void scan_keyboard();
void set_baud_sel(int sel);
@ -192,7 +192,6 @@ public: // HACK for MC6845
// interrupt state
UINT8 m_int_mask; // interrupt mask
UINT8 m_int_state; // interrupt status
int m_f_int_enb; // floppy interrupt enable
bool m_fdc_irq;
bool m_fdc_drq;