mirror of
https://github.com/mamedev/mame.git
synced 2024-11-16 07:48:32 +01:00
cmi2x: Modernization and cleanup
- Use interrupt vector read callbacks to handle context switching and special IRQ and RESET vectoring - Use addressable latch device for CPU function register
This commit is contained in:
parent
0480765f07
commit
ec77693858
1 changed files with 62 additions and 96 deletions
|
@ -91,6 +91,7 @@
|
|||
#include "machine/6821pia.h"
|
||||
#include "machine/6850acia.h"
|
||||
#include "machine/6840ptm.h"
|
||||
#include "machine/74259.h"
|
||||
#include "machine/7474.h"
|
||||
#include "machine/bankdev.h"
|
||||
#include "machine/clock.h"
|
||||
|
@ -257,8 +258,8 @@ public:
|
|||
void q133_1_portb_w(u8 data);
|
||||
|
||||
void cmi_iix_vblank(int state);
|
||||
IRQ_CALLBACK_MEMBER(cpu1_interrupt_callback);
|
||||
IRQ_CALLBACK_MEMBER(cpu2_interrupt_callback);
|
||||
u8 vfetch1_r(offs_t offset);
|
||||
u8 vfetch2_r(offs_t offset);
|
||||
|
||||
// Video-related
|
||||
u8 video_r(offs_t offset);
|
||||
|
@ -290,19 +291,16 @@ public:
|
|||
// Memory mapping
|
||||
template<int CpuNum> u8 rom_r(offs_t offset);
|
||||
void map_ram_w(offs_t offset, u8 data);
|
||||
template<int CpuNum> u8 vector_r(offs_t offset);
|
||||
template<int CpuNum> u8 map_r();
|
||||
template<int CpuNum> void map_w(u8 data);
|
||||
u8 atomic_r();
|
||||
void cpufunc_w(u8 data);
|
||||
template<int CpuNum> void ipi_w(int state);
|
||||
template<int CpuNum> void nmi_reset_w(int state);
|
||||
template<int CpuNum> void ms_w(int state);
|
||||
u8 parity_r(offs_t offset);
|
||||
void mapsel_w(offs_t offset, u8 data);
|
||||
template<int CpuNum> u8 irq_ram_r(offs_t offset);
|
||||
template<int CpuNum> void irq_ram_w(offs_t offset, u8 data);
|
||||
template<int CpuNum> u8 scratch_ram_r(offs_t offset);
|
||||
template<int CpuNum> void scratch_ram_w(offs_t offset, u8 data);
|
||||
template<int CpuNum> u8 scratch_ram_fa_r(offs_t offset);
|
||||
template<int CpuNum> void scratch_ram_fa_w(offs_t offset, u8 data);
|
||||
|
||||
// MIDI/SMPTE
|
||||
void midi_dma_w(offs_t offset, u16 data, u16 mem_mask = ~0);
|
||||
|
@ -432,8 +430,6 @@ private:
|
|||
int m_cpu_active_space[2]{};
|
||||
int m_cpu_map_switch[2]{};
|
||||
u8 m_curr_mapinfo[2]{};
|
||||
u8 m_irq_address[2][2]{};
|
||||
int m_m6809_bs_hack_cnt[2]{};
|
||||
|
||||
/* Q219 lightpen/graphics card */
|
||||
std::unique_ptr<u8[]> m_video_ram;
|
||||
|
@ -915,11 +911,6 @@ void cmi_state::map_ram_w(offs_t offset, u8 data)
|
|||
}
|
||||
}
|
||||
|
||||
template<int CpuNum> u8 cmi_state::vector_r(offs_t offset)
|
||||
{
|
||||
return m_q133_rom[(CpuNum ? 0xbfe : 0xffe) + offset];
|
||||
}
|
||||
|
||||
template<int CpuNum> u8 cmi_state::map_r()
|
||||
{
|
||||
return (m_cpu_active_space[1] << 2) | (m_cpu_active_space[0] << 1) | CpuNum;
|
||||
|
@ -930,25 +921,6 @@ template<int CpuNum> void cmi_state::map_w(u8 data)
|
|||
m_map_switch_timer->adjust(attotime::from_ticks(data & 0xf, M6809_CLOCK), CpuNum);
|
||||
}
|
||||
|
||||
template<int CpuNum> u8 cmi_state::irq_ram_r(offs_t offset)
|
||||
{
|
||||
if (machine().side_effects_disabled())
|
||||
return m_scratch_ram[CpuNum][0xf8 + 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, 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];
|
||||
}
|
||||
|
||||
template<int CpuNum> void cmi_state::irq_ram_w(offs_t offset, u8 data)
|
||||
{
|
||||
m_scratch_ram[CpuNum][0xf8 + offset] = data;
|
||||
}
|
||||
|
||||
TIMER_CALLBACK_MEMBER(cmi_state::switch_map)
|
||||
{
|
||||
m_cpu_active_space[param] = m_cpu_map_switch[param];
|
||||
|
@ -972,26 +944,19 @@ u8 cmi_state::atomic_r()
|
|||
return 0;
|
||||
}
|
||||
|
||||
void cmi_state::cpufunc_w(u8 data)
|
||||
template<int CpuNum> void cmi_state::ipi_w(int state)
|
||||
{
|
||||
int cpunum = data & 1;
|
||||
int idx = data & 6;
|
||||
int bit = (data & 8) >> 3;
|
||||
set_interrupt(CpuNum, IRQ_IPI2_LEVEL, state ? ASSERT_LINE : CLEAR_LINE);
|
||||
}
|
||||
|
||||
switch (idx)
|
||||
{
|
||||
case 0: set_interrupt(cpunum, IRQ_IPI2_LEVEL, bit ? ASSERT_LINE : CLEAR_LINE);
|
||||
break;
|
||||
case 2: // TODO: Hardware trace
|
||||
break;
|
||||
case 4: m_cpu_map_switch[cpunum] = bit;
|
||||
break;
|
||||
case 6: if (cpunum == CPU_1)
|
||||
m_maincpu1->set_input_line(M6809_FIRQ_LINE, bit ? ASSERT_LINE : CLEAR_LINE);
|
||||
else
|
||||
m_maincpu2->set_input_line(M6809_FIRQ_LINE, bit ? ASSERT_LINE : CLEAR_LINE);
|
||||
break;
|
||||
}
|
||||
template<int CpuNum> void cmi_state::nmi_reset_w(int state)
|
||||
{
|
||||
// TODO: Hardware trace
|
||||
}
|
||||
|
||||
template<int CpuNum> void cmi_state::ms_w(int state)
|
||||
{
|
||||
m_cpu_map_switch[CpuNum] = state;
|
||||
}
|
||||
|
||||
u8 cmi_state::parity_r(offs_t offset)
|
||||
|
@ -1140,7 +1105,7 @@ template <int CpuNum> void cmi_state::cpu_periphs_map(address_map &map)
|
|||
map(0x0800, 0x0bff).rom().region("q133", 0x2800 - CpuNum * 0x1000);
|
||||
map(0x0c40, 0x0c4f).rw(FUNC(cmi_state::parity_r), FUNC(cmi_state::mapsel_w));
|
||||
map(0x0c5a, 0x0c5b).noprw(); // Q077 HDD controller - not installed
|
||||
map(0x0c5e, 0x0c5e).rw(FUNC(cmi_state::atomic_r), FUNC(cmi_state::cpufunc_w));
|
||||
map(0x0c5e, 0x0c5e).r(FUNC(cmi_state::atomic_r)).w("cpulatch", FUNC(ls259_device::write_nibble_d3));
|
||||
map(0x0c5f, 0x0c5f).rw(FUNC(cmi_state::map_r<CpuNum>), FUNC(cmi_state::map_w<CpuNum>));
|
||||
map(0x0c80, 0x0c83).rw(m_q133_acia[0], FUNC(mos6551_device::read), FUNC(mos6551_device::write));
|
||||
map(0x0c84, 0x0c87).rw(m_q133_acia[1], FUNC(mos6551_device::read), FUNC(mos6551_device::write));
|
||||
|
@ -1160,10 +1125,7 @@ template <int CpuNum> void cmi_state::cpu_periphs_map(address_map &map)
|
|||
map(0x0cfc, 0x0cfc).w(FUNC(cmi_state::i8214_cpu1_w));
|
||||
map(0x0cfd, 0x0cfd).w(FUNC(cmi_state::i8214_cpu2_w));
|
||||
map(0x0d00, 0x0eff).rw(FUNC(cmi_state::shared_ram_r), FUNC(cmi_state::shared_ram_w));
|
||||
map(0x0f00, 0x0ff7).rw(FUNC(cmi_state::scratch_ram_r<CpuNum>), FUNC(cmi_state::scratch_ram_w<CpuNum>));
|
||||
map(0x0ff8, 0x0ff9).rw(FUNC(cmi_state::irq_ram_r<CpuNum>), FUNC(cmi_state::irq_ram_w<CpuNum>));
|
||||
map(0x0ffa, 0x0ffd).rw(FUNC(cmi_state::scratch_ram_fa_r<CpuNum>), FUNC(cmi_state::scratch_ram_fa_w<CpuNum>));
|
||||
map(0x0ffe, 0x0fff).r(FUNC(cmi_state::vector_r<CpuNum>));
|
||||
map(0x0f00, 0x0fff).rw(FUNC(cmi_state::scratch_ram_r<CpuNum>), FUNC(cmi_state::scratch_ram_w<CpuNum>));
|
||||
}
|
||||
|
||||
/* Input ports */
|
||||
|
@ -1188,16 +1150,6 @@ template <int CpuNum> void cmi_state::scratch_ram_w(offs_t offset, u8 data)
|
|||
m_scratch_ram[CpuNum][offset] = data;
|
||||
}
|
||||
|
||||
template <int CpuNum> u8 cmi_state::scratch_ram_fa_r(offs_t offset)
|
||||
{
|
||||
return m_scratch_ram[CpuNum][0xfa + offset];
|
||||
}
|
||||
|
||||
template <int CpuNum> void cmi_state::scratch_ram_fa_w(offs_t offset, u8 data)
|
||||
{
|
||||
m_scratch_ram[CpuNum][0xfa + offset] = data;
|
||||
}
|
||||
|
||||
bool cmi_state::map_is_active(int cpunum, int map, u8 *map_info)
|
||||
{
|
||||
if (m_cpu_active_space[cpunum] == MAPPING_A)
|
||||
|
@ -1720,48 +1672,57 @@ void cmi_state::ptm_q219_irq(int state)
|
|||
set_interrupt(CPU_2, IRQ_RINT_LEVEL, state);
|
||||
}
|
||||
|
||||
IRQ_CALLBACK_MEMBER( cmi_state::cpu1_interrupt_callback )
|
||||
u8 cmi_state::vfetch1_r(offs_t offset)
|
||||
{
|
||||
/* Switch to mapping A */
|
||||
// Switch to mapping 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)
|
||||
if ((offset & 0x000e) == 0x0008)
|
||||
{
|
||||
// IRQ vector
|
||||
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);
|
||||
|
||||
m_m6809_bs_hack_cnt[CPU_1] = 2;
|
||||
|
||||
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]);
|
||||
u8 irq_address = m_cpu1space->read_byte(vector + level * 2 + BIT(offset, 0));
|
||||
LOG("%s: CPU1 IRQ vector %s byte: %02x\n", machine().describe_context(), BIT(offset, 0) ? "low" : "high", irq_address);
|
||||
return irq_address;
|
||||
}
|
||||
else if ((offset & 0x000e) == 0x000e)
|
||||
{
|
||||
// RESET vector
|
||||
return m_q133_rom[offset & 0xfff];
|
||||
}
|
||||
else
|
||||
{
|
||||
LOG("%s: Some other CPU1 interrupt, line %d\n", irqline);
|
||||
LOG("%s: Some other CPU1 interrupt, fetching vector from $%04x\n", machine().describe_context(), offset);
|
||||
return m_scratch_ram[CPU_1][offset & 0xff];
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
IRQ_CALLBACK_MEMBER( cmi_state::cpu2_interrupt_callback )
|
||||
u8 cmi_state::vfetch2_r(offs_t offset)
|
||||
{
|
||||
/* Switch to mapping A */
|
||||
// Switch to mapping 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)
|
||||
if ((offset & 0x000e) == 0x0008)
|
||||
{
|
||||
// IRQ vector
|
||||
int level = m_i8214[1]->a_r() ^ 7;
|
||||
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);
|
||||
|
||||
m_m6809_bs_hack_cnt[CPU_2] = 2;
|
||||
|
||||
//osd_printf_debug("cpu1 interrupt, will be pushing address %02x%02x\n", m_irq_address[CPU_2][0], m_irq_address[CPU_2][1]);
|
||||
u8 irq_address = m_cpu2space->read_byte(0xffe0 + level*2 + BIT(offset, 0));
|
||||
LOG("%s: CPU2 IRQ vector %s byte: %02x (%s)\n", machine().describe_context(), BIT(offset, 0) ? "low" : "high", irq_address);
|
||||
return irq_address;
|
||||
}
|
||||
else if ((offset & 0x000e) == 0x000e)
|
||||
{
|
||||
// RESET vector
|
||||
return m_q133_rom[offset & 0xbff];
|
||||
}
|
||||
else
|
||||
{
|
||||
LOG("%s: Some other CPU2 interrupt, fetching vector from $%04x\n", machine().describe_context(), offset);
|
||||
return m_scratch_ram[CPU_2][offset & 0xff];
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
void cmi_state::set_interrupt(int cpunum, int level, int state)
|
||||
|
@ -1931,9 +1892,6 @@ void cmi_state::machine_reset()
|
|||
|
||||
/* Select A (system) spaces */
|
||||
m_cpu_active_space[cpunum] = MAPPING_A;
|
||||
|
||||
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!!
|
||||
|
@ -1954,8 +1912,6 @@ void cmi_state::machine_reset()
|
|||
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;
|
||||
|
||||
//m_midi_ptm[0]->set_g1(1); // /G1 has unknown source, "TIMER 1A /GATE" per schematic
|
||||
m_midi_ptm[0]->set_g2(0); // /G2 and /G3 wired to ground per schematic
|
||||
|
@ -2034,11 +1990,11 @@ void cmi_state::cmi2x(machine_config &config)
|
|||
{
|
||||
MC6809E(config, m_maincpu1, Q209_CPU_CLOCK);
|
||||
m_maincpu1->set_addrmap(AS_PROGRAM, &cmi_state::maincpu1_map);
|
||||
m_maincpu1->set_irq_acknowledge_callback(FUNC(cmi_state::cpu1_interrupt_callback));
|
||||
m_maincpu1->interrupt_vector_read().set(FUNC(cmi_state::vfetch1_r));
|
||||
|
||||
MC6809E(config, m_maincpu2, Q209_CPU_CLOCK);
|
||||
m_maincpu2->set_addrmap(AS_PROGRAM, &cmi_state::maincpu2_map);
|
||||
m_maincpu2->set_irq_acknowledge_callback(FUNC(cmi_state::cpu2_interrupt_callback));
|
||||
m_maincpu2->interrupt_vector_read().set(FUNC(cmi_state::vfetch2_r));
|
||||
|
||||
ADDRESS_MAP_BANK(config, m_cpu_periphs[0]).set_options(ENDIANNESS_BIG, 8, 16, 0x1000);
|
||||
m_cpu_periphs[0]->set_addrmap(AS_PROGRAM, &cmi_state::cpu_periphs_map<0>);
|
||||
|
@ -2046,6 +2002,16 @@ void cmi_state::cmi2x(machine_config &config)
|
|||
ADDRESS_MAP_BANK(config, m_cpu_periphs[1]).set_options(ENDIANNESS_BIG, 8, 16, 0x1000);
|
||||
m_cpu_periphs[1]->set_addrmap(AS_PROGRAM, &cmi_state::cpu_periphs_map<1>);
|
||||
|
||||
ls259_device &cpulatch(LS259(config, "cpulatch")); // 6D (Q209)
|
||||
cpulatch.q_out_cb<0>().set(FUNC(cmi_state::ipi_w<0>));
|
||||
cpulatch.q_out_cb<1>().set(FUNC(cmi_state::ipi_w<1>));
|
||||
cpulatch.q_out_cb<2>().set(FUNC(cmi_state::nmi_reset_w<0>));
|
||||
cpulatch.q_out_cb<3>().set(FUNC(cmi_state::nmi_reset_w<1>));
|
||||
cpulatch.q_out_cb<4>().set(FUNC(cmi_state::ms_w<0>));
|
||||
cpulatch.q_out_cb<5>().set(FUNC(cmi_state::ms_w<1>));
|
||||
cpulatch.q_out_cb<6>().set_inputline(m_maincpu1, M6809_FIRQ_LINE);
|
||||
cpulatch.q_out_cb<7>().set_inputline(m_maincpu2, M6809_FIRQ_LINE);
|
||||
|
||||
M68000(config, m_midicpu, 20_MHz_XTAL / 2);
|
||||
m_midicpu->set_addrmap(AS_PROGRAM, &cmi_state::midicpu_map);
|
||||
|
||||
|
|
Loading…
Reference in a new issue