diff options
author | R. Belmont <rb6502@users.noreply.github.com> | 2014-02-23 02:21:49 +0000 |
---|---|---|
committer | R. Belmont <rb6502@users.noreply.github.com> | 2014-02-23 02:21:49 +0000 |
commit | 9490ca46a23dbef9190d4255768bc23d6e37b671 (patch) | |
tree | 5eaf2cb28654bf58c871c881918e219535a4f951 /src/mess/drivers | |
parent | 6e5679d8738db2cb4b4b027ee8f8ce963f8d4c6b (diff) |
(MESS) rainbow: added IRQ management framework and vector control. [R. Belmont, Bavarese]
Diffstat (limited to 'src/mess/drivers')
-rw-r--r-- | src/mess/drivers/rainbow.c | 77 |
1 files changed, 69 insertions, 8 deletions
diff --git a/src/mess/drivers/rainbow.c b/src/mess/drivers/rainbow.c index 5a0184a4c6d..a05bfdbf1db 100644 --- a/src/mess/drivers/rainbow.c +++ b/src/mess/drivers/rainbow.c @@ -248,6 +248,8 @@ public: DECLARE_WRITE_LINE_MEMBER(kbd_rxready_w); DECLARE_WRITE_LINE_MEMBER(kbd_txready_w); + DECLARE_WRITE_LINE_MEMBER(irq_hi_w); + UINT32 screen_update_rainbow(screen_device &screen, bitmap_ind16 &bitmap, const rectangle &cliprect); INTERRUPT_GEN_MEMBER(vblank_irq); DECLARE_WRITE_LINE_MEMBER(write_keyboard_clock); @@ -257,6 +259,15 @@ protected: virtual void machine_start(); private: + enum + { + IRQ_8088_MAILBOX = 0, // vector 0x27/a7 + IRQ_8088_VBL, // vector 0x20/a0 + IRQ_8088_KBD, // vector 0x26/a6 + + IRQ_8088_MAX + }; + required_ioport m_inp1; required_ioport m_inp2; required_ioport m_inp3; @@ -279,6 +290,10 @@ private: required_shared_ptr<UINT8> m_shared; required_device<cpu_device> m_maincpu; + void raise_8088_irq(int ref); + void lower_8088_irq(int ref); + void update_8088_irqs(); + bool m_SCREEN_BLANK; int INT88, INTZ80; @@ -304,6 +319,9 @@ private: int m_unit; device_t *m_image[4]; + + int m_irq_high; + UINT32 m_irq_mask; }; @@ -324,6 +342,8 @@ void rainbow_state::machine_start() save_item(NAME(m_zflip)); save_item(NAME(m_kbd_tx_ready)); save_item(NAME(m_kbd_rx_ready)); + save_item(NAME(m_irq_high)); + save_item(NAME(m_irq_mask)); #ifdef FORCE_RAINBOW_100_LOGO UINT8 *rom = memregion("maincpu")->base(); @@ -531,6 +551,7 @@ void rainbow_state::machine_reset() m_kbd8251->write_cts(1); m_KBD = 0; + m_irq_high = 0; // RESET ALL LEDs output_set_value("led1", 1); @@ -549,7 +570,7 @@ void rainbow_state::machine_reset() MOTOR_DISABLE_counter = 2; // soon resets drv.LEDs m_unit = 0; - + m_irq_mask = 0; } UINT32 rainbow_state::screen_update_rainbow(screen_device &screen, bitmap_ind16 &bitmap, const rectangle &cliprect) @@ -600,6 +621,39 @@ WRITE8_MEMBER(rainbow_state::floating_bus_w) space.write_byte(offset,data); } +// interrupt handling and arbitration. priorities currently unknown. +void rainbow_state::update_8088_irqs() +{ + static const int vectors[] = { 0x27, 0x20, 0x26 }; + + if (m_irq_mask != 0) + { + for (int i = 0; i < IRQ_8088_MAX; i++) + { + if (m_irq_mask & (1<<i)) + { + m_i8088->set_input_line_and_vector(INPUT_LINE_INT0, ASSERT_LINE, vectors[i] | m_irq_high); + break; + } + } + } + else + { + m_i8088->set_input_line(INPUT_LINE_INT0, CLEAR_LINE); + } +} + +void rainbow_state::raise_8088_irq(int ref) +{ + m_irq_mask |= (1<<ref); + update_8088_irqs(); +} + +void rainbow_state::lower_8088_irq(int ref) +{ + m_irq_mask &= ~(1<<ref); + update_8088_irqs(); +} READ8_MEMBER(rainbow_state::share_z80_r) { @@ -728,7 +782,7 @@ WRITE8_MEMBER(rainbow_state::comm_control_w) READ8_MEMBER(rainbow_state::i8088_latch_r) { // printf("Read %02x from 8088 mailbox\n", m_8088_mailbox); - m_i8088->set_input_line(INPUT_LINE_INT0, CLEAR_LINE); + lower_8088_irq(IRQ_8088_MAILBOX); INT88 = false; // BISLANG: INTZ80 = false; // return m_8088_mailbox; @@ -760,7 +814,7 @@ READ8_MEMBER(rainbow_state::z80_latch_r) WRITE8_MEMBER(rainbow_state::z80_latch_w) { // printf("%02x to 8088 mailbox\n", data); - m_i8088->set_input_line_and_vector(INPUT_LINE_INT0, ASSERT_LINE, 0x27); + raise_8088_irq(IRQ_8088_MAILBOX); m_8088_mailbox = data; INT88 = true; @@ -938,12 +992,12 @@ READ8_MEMBER( rainbow_state::read_video_ram_r ) INTERRUPT_GEN_MEMBER(rainbow_state::vblank_irq) { - device.execute().set_input_line_and_vector(INPUT_LINE_INT0, ASSERT_LINE, 0x20); + raise_8088_irq(IRQ_8088_VBL); } WRITE8_MEMBER( rainbow_state::clear_video_interrupt ) { - m_i8088->set_input_line(INPUT_LINE_INT0, CLEAR_LINE); + lower_8088_irq(IRQ_8088_VBL); } READ8_MEMBER( rainbow_state::diagnostic_r ) @@ -1007,11 +1061,11 @@ void rainbow_state::update_kbd_irq() { if ((m_kbd_rx_ready) || (m_kbd_tx_ready)) { - m_i8088->set_input_line_and_vector(INPUT_LINE_INT0, ASSERT_LINE, 0x26); + raise_8088_irq(IRQ_8088_KBD); } else { - m_i8088->set_input_line(INPUT_LINE_INT0, CLEAR_LINE); + lower_8088_irq(IRQ_8088_KBD); } } @@ -1036,7 +1090,7 @@ WRITE_LINE_MEMBER(rainbow_state::kbd_txready_w) update_kbd_irq(); } -DECLARE_WRITE_LINE_MEMBER(rainbow_state::write_keyboard_clock) +WRITE_LINE_MEMBER(rainbow_state::write_keyboard_clock) { m_kbd8251->write_txc(state); m_kbd8251->write_rxc(state); @@ -1068,6 +1122,12 @@ TIMER_DEVICE_CALLBACK_MEMBER(rainbow_state::motor_tick) m_beep_counter--; } +// on 100-B, DTR from the keyboard 8051 controls bit 7 of IRQ vectors +WRITE_LINE_MEMBER(rainbow_state::irq_hi_w) +{ + m_irq_high = (state == ASSERT_LINE) ? 0x80 : 0; +} + static const vt_video_interface video_interface = { "chargen", @@ -1146,6 +1206,7 @@ static MACHINE_CONFIG_START( rainbow, rainbow_state ) MCFG_DEVICE_ADD("kbdser", I8251, 0) MCFG_I8251_TXD_HANDLER(WRITELINE(rainbow_state, kbd_tx)) + MCFG_I8251_DTR_HANDLER(WRITELINE(rainbow_state, irq_hi_w)) MCFG_I8251_RXRDY_HANDLER(WRITELINE(rainbow_state, kbd_rxready_w)) MCFG_I8251_TXRDY_HANDLER(WRITELINE(rainbow_state, kbd_txready_w)) |