summaryrefslogtreecommitdiffstatshomepage
diff options
context:
space:
mode:
-rw-r--r--src/devices/cpu/t11/t11.cpp188
-rw-r--r--src/devices/cpu/t11/t11.h53
-rw-r--r--src/mame/drivers/atarisy2.cpp16
-rw-r--r--src/mame/drivers/bk.cpp4
-rw-r--r--src/mame/drivers/galgame.cpp10
-rw-r--r--src/mame/drivers/ms0515.cpp8
-rw-r--r--src/mame/drivers/vt240.cpp8
-rw-r--r--src/mame/includes/bk.h2
-rw-r--r--src/mame/machine/bk.cpp6
9 files changed, 193 insertions, 102 deletions
diff --git a/src/devices/cpu/t11/t11.cpp b/src/devices/cpu/t11/t11.cpp
index a93f69ae90e..4ab5a587193 100644
--- a/src/devices/cpu/t11/t11.cpp
+++ b/src/devices/cpu/t11/t11.cpp
@@ -49,11 +49,18 @@ t11_device::t11_device(const machine_config &mconfig, device_type type, const ch
: cpu_device(mconfig, type, tag, owner, clock)
, m_program_config("program", ENDIANNESS_LITTLE, 16, 16, 0)
, c_initial_mode(0)
+ , m_cp_state(0)
+ , m_vec_active(false)
+ , m_pf_active(false)
+ , m_hlt_active(false)
, m_out_reset_func(*this)
+ , m_in_iack_func(*this)
{
m_program_config.m_is_octal = true;
- memset(m_reg, 0x00, sizeof(m_reg));
- memset(&m_psw, 0x00, sizeof(m_psw));
+ for (auto &reg : m_reg)
+ reg.d = 0;
+ m_psw.d = 0;
+ m_ppc.d = 0;
}
t11_device::t11_device(const machine_config &mconfig, const char *tag, device_t *owner, uint32_t clock)
@@ -177,58 +184,94 @@ struct irq_table_entry
static const struct irq_table_entry irq_table[] =
{
- { 0<<5, 0x00 },
- { 4<<5, 0x38 },
- { 4<<5, 0x34 },
- { 4<<5, 0x30 },
- { 5<<5, 0x5c },
- { 5<<5, 0x58 },
- { 5<<5, 0x54 },
- { 5<<5, 0x50 },
- { 6<<5, 0x4c },
- { 6<<5, 0x48 },
- { 6<<5, 0x44 },
- { 6<<5, 0x40 },
- { 7<<5, 0x6c },
- { 7<<5, 0x68 },
- { 7<<5, 0x64 },
- { 7<<5, 0x60 }
+ { 0<<5, 0000 },
+ { 4<<5, 0070 },
+ { 4<<5, 0064 },
+ { 4<<5, 0060 },
+ { 5<<5, 0134 },
+ { 5<<5, 0130 },
+ { 5<<5, 0124 },
+ { 5<<5, 0120 },
+ { 6<<5, 0114 },
+ { 6<<5, 0110 },
+ { 6<<5, 0104 },
+ { 6<<5, 0100 },
+ { 7<<5, 0154 },
+ { 7<<5, 0150 },
+ { 7<<5, 0144 },
+ { 7<<5, 0140 }
};
void t11_device::t11_check_irqs()
{
- const struct irq_table_entry *irq = &irq_table[m_irq_state & 15];
- int priority = PSW & 0xe0;
-
- /* compare the priority of the interrupt to the PSW */
- if (irq->priority > priority)
+ // HLT is nonmaskable
+ if (m_ext_halt)
{
- int vector = irq->vector;
- int new_pc, new_psw;
+ m_ext_halt = false;
- /* call the callback; if we don't get -1 back, use the return value as our vector */
- int new_vector = standard_irq_callback(m_irq_state & 15);
- if (new_vector != -1)
- vector = new_vector;
-
- /* fetch the new PC and PSW from that vector */
- assert((vector & 3) == 0);
- new_pc = RWORD(vector);
- new_psw = RWORD(vector + 2);
-
- /* push the old state, set the new one */
+ // push the old state, set the new one
PUSH(PSW);
PUSH(PC);
- PCD = new_pc;
- PSW = new_psw;
- //t11_check_irqs();
+ PCD = m_initial_pc + 4;
+ PSW = 0340;
- /* count cycles and clear the WAIT flag */
+ // count cycles and clear the WAIT flag
m_icount -= 114;
m_wait_state = 0;
+
+ return;
+ }
+
+ // PF has next-highest priority
+ int priority = PSW & 0340;
+ if (m_power_fail && priority != 0340)
+ {
+ m_power_fail = false;
+ take_interrupt(T11_PWRFAIL);
+ return;
+ }
+
+ // compare the priority of the CP interrupt to the PSW
+ const struct irq_table_entry *irq = &irq_table[m_cp_state & 15];
+ if (irq->priority > priority)
+ {
+ // call the callback
+ standard_irq_callback(m_cp_state & 15);
+
+ // T11 encodes the interrupt level on DAL<12:8>
+ uint8_t iaddr = bitswap<4>(~m_cp_state & 15, 0, 1, 2, 3);
+ if (!m_vec_active)
+ iaddr |= 16;
+
+ // vector is input on DAL<7:2>
+ uint8_t vector = m_in_iack_func(iaddr);
+
+ // nonvectored or vectored interrupt depending on VEC
+ if (BIT(iaddr, 4))
+ take_interrupt(irq->vector);
+ else
+ take_interrupt(vector & ~3);
}
}
+void t11_device::take_interrupt(uint8_t vector)
+{
+ // fetch the new PC and PSW from that vector
+ assert((vector & 3) == 0);
+ uint16_t new_pc = RWORD(vector);
+ uint16_t new_psw = RWORD(vector + 2);
+
+ // push the old state, set the new one
+ PUSH(PSW);
+ PUSH(PC);
+ PCD = new_pc;
+ PSW = new_psw;
+
+ // count cycles and clear the WAIT flag
+ m_icount -= 114;
+ m_wait_state = 0;
+}
+
/*************************************
@@ -263,6 +306,7 @@ void t11_device::device_start()
m_program = &space(AS_PROGRAM);
m_cache = m_program->cache<1, 0, ENDIANNESS_LITTLE>();
m_out_reset_func.resolve_safe();
+ m_in_iack_func.resolve_safe(0377);
save_item(NAME(m_ppc.w.l));
save_item(NAME(m_reg[0].w.l));
@@ -276,7 +320,12 @@ void t11_device::device_start()
save_item(NAME(m_psw.w.l));
save_item(NAME(m_initial_pc));
save_item(NAME(m_wait_state));
- save_item(NAME(m_irq_state));
+ save_item(NAME(m_cp_state));
+ save_item(NAME(m_vec_active));
+ save_item(NAME(m_pf_active));
+ save_item(NAME(m_hlt_active));
+ save_item(NAME(m_power_fail));
+ save_item(NAME(m_ext_halt));
// Register debugger state
state_add( T11_PC, "PC", m_reg[7].w.l).formatstr("%06O");
@@ -344,27 +393,18 @@ void k1801vm2_device::state_string_export(const device_state_entry &entry, std::
void t11_device::device_reset()
{
- /* initial SP is 376 octal, or 0xfe */
- SP = 0x00fe;
+ // initial SP is 376 octal, or 0xfe
+ SP = 0376;
- /* initial PC comes from the setup word */
+ // initial PC comes from the setup word
PC = m_initial_pc;
- /* PSW starts off at highest priority */
- PSW = 0xe0;
-
- /* initialize the IRQ state */
- m_irq_state = 0;
+ // PSW starts off at highest priority
+ PSW = 0340;
- /* reset the remaining state */
- REGD(0) = 0;
- REGD(1) = 0;
- REGD(2) = 0;
- REGD(3) = 0;
- REGD(4) = 0;
- REGD(5) = 0;
- m_ppc.d = 0;
m_wait_state = 0;
+ m_power_fail = false;
+ m_ext_halt = false;
}
void k1801vm2_device::device_reset()
@@ -384,11 +424,35 @@ void k1801vm2_device::device_reset()
void t11_device::execute_set_input(int irqline, int state)
{
- /* set the appropriate bit */
- if (state == CLEAR_LINE)
- m_irq_state &= ~(1 << irqline);
- else
- m_irq_state |= 1 << irqline;
+ switch (irqline)
+ {
+ case CP0_LINE:
+ case CP1_LINE:
+ case CP2_LINE:
+ case CP3_LINE:
+ // set the appropriate bit
+ if (state == CLEAR_LINE)
+ m_cp_state &= ~(1 << irqline);
+ else
+ m_cp_state |= 1 << irqline;
+ break;
+
+ case VEC_LINE:
+ m_vec_active = (state != CLEAR_LINE);
+ break;
+
+ case PF_LINE:
+ if (state != CLEAR_LINE && !m_pf_active)
+ m_power_fail = true;
+ m_pf_active = (state != CLEAR_LINE);
+ break;
+
+ case HLT_LINE:
+ if (state != CLEAR_LINE && !m_hlt_active)
+ m_ext_halt = true;
+ m_hlt_active = (state != CLEAR_LINE);
+ break;
+ }
}
diff --git a/src/devices/cpu/t11/t11.h b/src/devices/cpu/t11/t11.h
index 5b4c4921dad..2b54933ba94 100644
--- a/src/devices/cpu/t11/t11.h
+++ b/src/devices/cpu/t11/t11.h
@@ -18,27 +18,42 @@ enum
#define T11_IRQ2 2 /* IRQ2 */
#define T11_IRQ3 3 /* IRQ3 */
-#define T11_RESERVED 0x000 /* Reserved vector */
-#define T11_TIMEOUT 0x004 /* Time-out/system error vector */
-#define T11_ILLINST 0x008 /* Illegal and reserved instruction vector */
-#define T11_BPT 0x00C /* BPT instruction vector */
-#define T11_IOT 0x010 /* IOT instruction vector */
-#define T11_PWRFAIL 0x014 /* Power fail vector */
-#define T11_EMT 0x018 /* EMT instruction vector */
-#define T11_TRAP 0x01C /* TRAP instruction vector */
-
class t11_device : public cpu_device
{
public:
+ enum
+ {
+ CP0_LINE = 0, // -AI4 (at PI time)
+ CP1_LINE = 1, // -AI3 (at PI time)
+ CP2_LINE = 2, // -AI2 (at PI time)
+ CP3_LINE = 3, // -AI1 (at PI time)
+ VEC_LINE = 4, // -AI5 (at PI time)
+ PF_LINE = 5, // -AI6 (at PI time)
+ HLT_LINE = 6 // -AI7 (at PI time)
+ };
+
// construction/destruction
t11_device(const machine_config &mconfig, const char *_tag, device_t *_owner, uint32_t _clock);
// configuration helpers
void set_initial_mode(const uint16_t mode) { c_initial_mode = mode; }
auto out_reset() { return m_out_reset_func.bind(); }
+ auto in_iack() { return m_in_iack_func.bind(); }
protected:
+ enum
+ {
+ T11_RESERVED = 000, // Reserved vector
+ T11_TIMEOUT = 004, // Time-out/system error vector
+ T11_ILLINST = 010, // Illegal and reserved instruction vector
+ T11_BPT = 014, // BPT instruction vector
+ T11_IOT = 020, // IOT instruction vector
+ T11_PWRFAIL = 024, // Power fail vector
+ T11_EMT = 030, // EMT instruction vector
+ T11_TRAP = 034 // TRAP instruction vector
+ };
+
t11_device(const machine_config &mconfig, device_type type, const char *tag, device_t *owner, uint32_t clock);
// device-level overrides
@@ -48,10 +63,10 @@ protected:
// device_execute_interface overrides
virtual uint32_t execute_min_cycles() const noexcept override { return 12; }
virtual uint32_t execute_max_cycles() const noexcept override { return 114; }
- virtual uint32_t execute_input_lines() const noexcept override { return 4; }
+ virtual uint32_t execute_input_lines() const noexcept override { return 7; }
+ virtual bool execute_input_edge_triggered(int inputnum) const noexcept override { return inputnum == PF_LINE || inputnum == HLT_LINE; }
virtual void execute_run() override;
virtual void execute_set_input(int inputnum, int state) override;
- virtual uint32_t execute_default_irq_vector(int inputnum) const noexcept override { return -1; }
// device_memory_interface overrides
virtual space_config_vector memory_space_config() const override;
@@ -69,13 +84,20 @@ protected:
PAIR m_ppc; /* previous program counter */
PAIR m_reg[8];
PAIR m_psw;
- uint16_t m_initial_pc;
- uint8_t m_wait_state;
- uint8_t m_irq_state;
+ uint16_t m_initial_pc;
+ uint8_t m_wait_state;
+ uint8_t m_cp_state;
+ bool m_vec_active;
+ bool m_pf_active;
+ bool m_hlt_active;
+ bool m_power_fail;
+ bool m_ext_halt;
int m_icount;
address_space *m_program;
memory_access_cache<1, 0, ENDIANNESS_LITTLE> *m_cache;
- devcb_write_line m_out_reset_func;
+
+ devcb_write_line m_out_reset_func;
+ devcb_read8 m_in_iack_func;
inline int ROPCODE();
inline int RBYTE(int addr);
@@ -85,6 +107,7 @@ protected:
inline void PUSH(int val);
inline int POP();
void t11_check_irqs();
+ void take_interrupt(uint8_t vector);
typedef void ( t11_device::*opcode_func )(uint16_t op);
static const opcode_func s_opcode_table[65536 >> 3];
diff --git a/src/mame/drivers/atarisy2.cpp b/src/mame/drivers/atarisy2.cpp
index bec71345faa..c40f954d2aa 100644
--- a/src/mame/drivers/atarisy2.cpp
+++ b/src/mame/drivers/atarisy2.cpp
@@ -148,24 +148,24 @@
void atarisy2_state::update_interrupts()
{
if (m_video_int_state)
- m_maincpu->set_input_line(3, ASSERT_LINE);
+ m_maincpu->set_input_line(t11_device::CP3_LINE, ASSERT_LINE);
else
- m_maincpu->set_input_line(3, CLEAR_LINE);
+ m_maincpu->set_input_line(t11_device::CP3_LINE, CLEAR_LINE);
if (m_scanline_int_state)
- m_maincpu->set_input_line(2, ASSERT_LINE);
+ m_maincpu->set_input_line(t11_device::CP2_LINE, ASSERT_LINE);
else
- m_maincpu->set_input_line(2, CLEAR_LINE);
+ m_maincpu->set_input_line(t11_device::CP2_LINE, CLEAR_LINE);
if (m_p2portwr_state)
- m_maincpu->set_input_line(1, ASSERT_LINE);
+ m_maincpu->set_input_line(t11_device::CP1_LINE, ASSERT_LINE);
else
- m_maincpu->set_input_line(1, CLEAR_LINE);
+ m_maincpu->set_input_line(t11_device::CP1_LINE, CLEAR_LINE);
if (m_p2portrd_state)
- m_maincpu->set_input_line(0, ASSERT_LINE);
+ m_maincpu->set_input_line(t11_device::CP0_LINE, ASSERT_LINE);
else
- m_maincpu->set_input_line(0, CLEAR_LINE);
+ m_maincpu->set_input_line(t11_device::CP0_LINE, CLEAR_LINE);
}
diff --git a/src/mame/drivers/bk.cpp b/src/mame/drivers/bk.cpp
index 1990e6d0dff..32dc0fabff7 100644
--- a/src/mame/drivers/bk.cpp
+++ b/src/mame/drivers/bk.cpp
@@ -166,10 +166,10 @@ INPUT_PORTS_END
void bk_state::bk0010(machine_config &config)
{
/* basic machine hardware */
- T11(config, m_maincpu, 3000000);
+ T11(config, m_maincpu, 3000000); // FIXME: actually K1801VM1
m_maincpu->set_initial_mode(0x36ff); /* initial mode word has DAL15,14,11,8 pulled low */
m_maincpu->set_addrmap(AS_PROGRAM, &bk_state::bk0010_mem);
- m_maincpu->set_irq_acknowledge_callback(FUNC(bk_state::bk0010_irq_callback));
+ m_maincpu->in_iack().set(FUNC(bk_state::bk0010_irq_callback));
/* video hardware */
screen_device &screen(SCREEN(config, "screen", SCREEN_TYPE_RASTER));
diff --git a/src/mame/drivers/galgame.cpp b/src/mame/drivers/galgame.cpp
index 5c87b3d2d03..ad9a4f604be 100644
--- a/src/mame/drivers/galgame.cpp
+++ b/src/mame/drivers/galgame.cpp
@@ -59,7 +59,7 @@ private:
virtual void machine_reset() override;
uint32_t screen_update_galaxygame(screen_device &screen, bitmap_ind16 &bitmap, const rectangle &cliprect);
INTERRUPT_GEN_MEMBER(galaxygame_irq);
- IRQ_CALLBACK_MEMBER(galaxygame_irq_callback);
+ uint8_t galaxygame_irq_callback(offs_t offset);
required_device<t11_device> m_maincpu;
required_device<palette_device> m_palette;
void galaxygame_map(address_map &map);
@@ -303,9 +303,9 @@ void galaxygame_state::galaxygame_map(address_map &map)
}
-IRQ_CALLBACK_MEMBER(galaxygame_state::galaxygame_irq_callback)
+uint8_t galaxygame_state::galaxygame_irq_callback(offs_t offset)
{
- device.execute().set_input_line(0, CLEAR_LINE);
+ m_maincpu->set_input_line(0, CLEAR_LINE);
return 0x40;
}
@@ -320,6 +320,8 @@ INTERRUPT_GEN_MEMBER(galaxygame_state::galaxygame_irq)
void galaxygame_state::machine_reset()
{
+ m_maincpu->set_input_line(t11_device::VEC_LINE, ASSERT_LINE);
+
m_clk = 0x00;
m_point_work_list_index = 0;
m_point_display_list_index = 0;
@@ -331,7 +333,7 @@ void galaxygame_state::galaxygame(machine_config &config)
T11(config, m_maincpu, 3000000);
m_maincpu->set_addrmap(AS_PROGRAM, &galaxygame_state::galaxygame_map);
m_maincpu->set_initial_mode(5 << 13);
- m_maincpu->set_irq_acknowledge_callback(FUNC(galaxygame_state::galaxygame_irq_callback));
+ m_maincpu->in_iack().set(FUNC(galaxygame_state::galaxygame_irq_callback));
m_maincpu->set_periodic_int(FUNC(galaxygame_state::galaxygame_irq), attotime::from_hz(60));
/* video hardware */
diff --git a/src/mame/drivers/ms0515.cpp b/src/mame/drivers/ms0515.cpp
index 86e77dcba66..ef6487b86bb 100644
--- a/src/mame/drivers/ms0515.cpp
+++ b/src/mame/drivers/ms0515.cpp
@@ -478,10 +478,10 @@ void ms0515_state::irq_encoder(int irq, int state)
{
if (m_irqs & (1 << i)) break;
}
- m_maincpu->set_input_line(3, (i & 8) ? ASSERT_LINE : CLEAR_LINE);
- m_maincpu->set_input_line(2, (i & 4) ? ASSERT_LINE : CLEAR_LINE);
- m_maincpu->set_input_line(1, (i & 2) ? ASSERT_LINE : CLEAR_LINE);
- m_maincpu->set_input_line(0, (i & 1) ? ASSERT_LINE : CLEAR_LINE);
+ m_maincpu->set_input_line(t11_device::CP3_LINE, (i & 8) ? ASSERT_LINE : CLEAR_LINE);
+ m_maincpu->set_input_line(t11_device::CP2_LINE, (i & 4) ? ASSERT_LINE : CLEAR_LINE);
+ m_maincpu->set_input_line(t11_device::CP1_LINE, (i & 2) ? ASSERT_LINE : CLEAR_LINE);
+ m_maincpu->set_input_line(t11_device::CP0_LINE, (i & 1) ? ASSERT_LINE : CLEAR_LINE);
}
/*
diff --git a/src/mame/drivers/vt240.cpp b/src/mame/drivers/vt240.cpp
index 667f2142c79..8262b6c96f9 100644
--- a/src/mame/drivers/vt240.cpp
+++ b/src/mame/drivers/vt240.cpp
@@ -137,10 +137,10 @@ void vt240_state::irq_encoder(int irq, int state)
if(m_irqs & (1 << i))
break;
}
- m_maincpu->set_input_line(3, (i & 8) ? ASSERT_LINE : CLEAR_LINE);
- m_maincpu->set_input_line(2, (i & 4) ? ASSERT_LINE : CLEAR_LINE);
- m_maincpu->set_input_line(1, (i & 2) ? ASSERT_LINE : CLEAR_LINE);
- m_maincpu->set_input_line(0, (i & 1) ? ASSERT_LINE : CLEAR_LINE);
+ m_maincpu->set_input_line(t11_device::CP3_LINE, (i & 8) ? ASSERT_LINE : CLEAR_LINE);
+ m_maincpu->set_input_line(t11_device::CP2_LINE, (i & 4) ? ASSERT_LINE : CLEAR_LINE);
+ m_maincpu->set_input_line(t11_device::CP1_LINE, (i & 2) ? ASSERT_LINE : CLEAR_LINE);
+ m_maincpu->set_input_line(t11_device::CP0_LINE, (i & 1) ? ASSERT_LINE : CLEAR_LINE);
}
WRITE_LINE_MEMBER(vt240_state::irq7_w)
diff --git a/src/mame/includes/bk.h b/src/mame/includes/bk.h
index b216893627e..91e7a4463d9 100644
--- a/src/mame/includes/bk.h
+++ b/src/mame/includes/bk.h
@@ -52,7 +52,7 @@ private:
virtual void video_start() override;
uint32_t screen_update_bk0010(screen_device &screen, bitmap_ind16 &bitmap, const rectangle &cliprect);
TIMER_CALLBACK_MEMBER(keyboard_callback);
- IRQ_CALLBACK_MEMBER(bk0010_irq_callback);
+ uint8_t bk0010_irq_callback(offs_t offset);
required_device<t11_device> m_maincpu;
required_device<cassette_image_device> m_cassette;
required_ioport_array<12> m_io_keyboard;
diff --git a/src/mame/machine/bk.cpp b/src/mame/machine/bk.cpp
index 3314c9f69f6..7fa379cfbd7 100644
--- a/src/mame/machine/bk.cpp
+++ b/src/mame/machine/bk.cpp
@@ -56,13 +56,15 @@ TIMER_CALLBACK_MEMBER(bk_state::keyboard_callback)
void bk_state::machine_start()
{
+ m_maincpu->set_input_line(t11_device::VEC_LINE, ASSERT_LINE);
+
m_kbd_timer = machine().scheduler().timer_alloc(timer_expired_delegate(FUNC(bk_state::keyboard_callback), this));
m_kbd_timer->adjust(attotime::from_hz(2400), 0, attotime::from_hz(2400));
}
-IRQ_CALLBACK_MEMBER(bk_state::bk0010_irq_callback)
+uint8_t bk_state::bk0010_irq_callback(offs_t offset)
{
- device.execute().set_input_line(0, CLEAR_LINE);
+ m_maincpu->set_input_line(0, CLEAR_LINE);
return m_key_irq_vector;
}