diff --git a/src/devices/cpu/upd7810/upd7810.cpp b/src/devices/cpu/upd7810/upd7810.cpp index 54bc5e3757e..e88b33d91aa 100644 --- a/src/devices/cpu/upd7810/upd7810.cpp +++ b/src/devices/cpu/upd7810/upd7810.cpp @@ -2005,19 +2005,19 @@ void upd7801_device::execute_set_input(int irqline, int state) /* Check if the ES bit is set then check for rising edge, otherwise falling edge */ if ( MKL & 0x20 ) { - if ( m_int2 == CLEAR_LINE && state == ASSERT_LINE ) + if ( m_int2 != CLEAR_LINE && state == ASSERT_LINE ) { IRR |= INTF2; } } else { - if ( m_int2 == ASSERT_LINE && state == CLEAR_LINE ) + if ( m_int2 != ASSERT_LINE && state == CLEAR_LINE ) { IRR |= INTF2; } } - m_int2 = state; + m_int2 = !state; break; } } diff --git a/src/mame/drivers/fp1100.cpp b/src/mame/drivers/fp1100.cpp index 383830afd78..0122438e1ed 100644 --- a/src/mame/drivers/fp1100.cpp +++ b/src/mame/drivers/fp1100.cpp @@ -23,10 +23,7 @@ The keyboard is a separate unit. It contains a beeper. TODO: - - irq sources and communications; subcpu never enables its interrupts. - unimplemented instruction PER triggered (can be ignored) - - Most of this code is guesswork, because although schematics exist, - they are too blurry to read. - Display can be interlaced or non-interlaced. Interlaced not emulated. - Cassette Load is quite complex, using 6 pins of the sub-cpu. Not done. - subcpu is supposed to be in WAIT except in horizontal blanking period. @@ -100,10 +97,11 @@ private: void io_map(address_map &map); void main_map(address_map &map); void sub_map(address_map &map); + void handle_int_to_main(); uint8_t m_irq_mask; - uint8_t m_main_latch; - uint8_t m_sub_latch; + uint8_t m_latch_main_to_sub; + uint8_t m_latch_sub_to_main; uint8_t m_slot_num; uint8_t m_kbd_row; uint8_t m_col_border; @@ -111,6 +109,8 @@ private: uint8_t m_col_display; uint8_t m_centronics_busy; uint8_t m_cass_data[4]; + bool m_main_irq_status; + bool m_sub_irq_status; bool m_cassbit; bool m_cassold; @@ -183,27 +183,40 @@ WRITE8_MEMBER( fp1100_state::main_bank_w ) m_slot_num = (m_slot_num & 3) | ((data & 1) << 2); //?? } +// tell sub that latch has a byte WRITE8_MEMBER( fp1100_state::irq_mask_w ) { - machine().scheduler().synchronize(); // force resync m_irq_mask = data; - if (BIT(data, 7)) + handle_int_to_main(); + + if (BIT(data, 7) && !m_sub_irq_status) + { m_subcpu->set_input_line(UPD7810_INTF2, ASSERT_LINE); + LOG("%s: Sub IRQ asserted\n",machine().describe_context()); + m_sub_irq_status = true; + } + else + if (!BIT(data, 7) && m_sub_irq_status) + { + m_subcpu->set_input_line(UPD7810_INTF2, CLEAR_LINE); + LOG("%s: Sub IRQ cleared\n",machine().describe_context()); + m_sub_irq_status = false; + } + LOG("%s: IRQmask=%X\n",machine().describe_context(),data); } +// send byte from main to latch WRITE8_MEMBER( fp1100_state::main_to_sub_w ) { - m_sub_latch = data; LOG("%s: From main:%X\n",machine().describe_context(),data); -// m_subcpu->set_input_line(UPD7810_INTF2, ASSERT_LINE); + m_latch_main_to_sub = data; } READ8_MEMBER( fp1100_state::sub_to_main_r ) { - m_maincpu->set_input_line(0, CLEAR_LINE); - LOG("%s: To main:%X\n",machine().describe_context(),m_main_latch); - return m_main_latch; + LOG("%s: To main:%X\n",machine().describe_context(),m_latch_sub_to_main); + return m_latch_sub_to_main; } WRITE8_MEMBER( fp1100_state::slot_bank_w ) @@ -237,16 +250,15 @@ void fp1100_state::io_map(address_map &map) READ8_MEMBER( fp1100_state::main_to_sub_r ) { - m_subcpu->set_input_line(UPD7810_INTF2, CLEAR_LINE); - LOG("%s: To sub:%X\n",machine().describe_context(),m_sub_latch); - return m_sub_latch; + LOG("%s: To sub:%X\n",machine().describe_context(),m_latch_main_to_sub); + return m_latch_main_to_sub; } +// send byte from sub to latch WRITE8_MEMBER( fp1100_state::sub_to_main_w ) { - m_main_latch = data; + m_latch_sub_to_main = data; LOG("%s: From sub:%X\n",machine().describe_context(),data); - //m_maincpu->set_input_line_and_vector(0, ASSERT_LINE, 0xf0); // Z80 } /* @@ -278,7 +290,7 @@ d6,7 - not used */ WRITE8_MEMBER( fp1100_state::kbd_row_w ) { - m_kbd_row = data & 15; + m_kbd_row = data; m_beep->set_state(BIT(data, 4)); } @@ -290,7 +302,7 @@ void fp1100_state::sub_map(address_map &map) map(0xe001, 0xe001).mirror(0x3fe).rw(m_crtc, FUNC(mc6845_device::register_r), FUNC(mc6845_device::register_w)); map(0xe400, 0xe7ff).portr("DSW").w(FUNC(fp1100_state::kbd_row_w)); map(0xe800, 0xebff).rw(FUNC(fp1100_state::main_to_sub_r), FUNC(fp1100_state::sub_to_main_w)); - //map(0xec00, 0xefff) "Acknowledge of INT0" is coded in but isn't currently executed + map(0xec00, 0xefff).lw8("reset0", [this] (u8 data) { m_subcpu->set_input_line(UPD7810_INTF0, CLEAR_LINE); }); map(0xf000, 0xf3ff).w(FUNC(fp1100_state::colour_control_w)); map(0xf400, 0xff7f).rom().region("sub_ipl", 0x2400); } @@ -314,9 +326,13 @@ WRITE8_MEMBER( fp1100_state::porta_w ) READ8_MEMBER( fp1100_state::portb_r ) { - uint8_t data = m_keyboard[m_kbd_row]->read() ^ 0xff; - //m_subcpu->set_input_line(UPD7810_INTF0, BIT(data, 7) ? HOLD_LINE : CLEAR_LINE); - return data; + u8 data = m_keyboard[m_kbd_row & 15]->read() ^ 0xff; + LOG("%s: PortB:%X:%X\n",machine().describe_context(),m_kbd_row,data); + //m_subcpu->set_input_line(UPD7810_INTF0, BIT(data, 7) ? ASSERT_LINE : CLEAR_LINE); + if (BIT(m_kbd_row, 5)) + return data; + else + return 0; } /* @@ -339,20 +355,42 @@ d6 - Centronics strobe WRITE8_MEMBER( fp1100_state::portc_w ) { u8 bits = data ^ m_upd7801.portc; + m_upd7801.portc = data; + if (BIT(bits, 3)) - if (BIT(m_irq_mask, 4)) - if (!BIT(data, 3)) - { - m_maincpu->set_input_line_and_vector(0, ASSERT_LINE, 0xf0); // Z80 - LOG("%s: PortC:%X\n",machine().describe_context(),data); - } + { + LOG("%s: PortC:%X\n",machine().describe_context(),data); + handle_int_to_main(); + } if (BIT(bits, 5)) m_cass->change_state(BIT(data, 5) ? CASSETTE_MOTOR_ENABLED : CASSETTE_MOTOR_DISABLED, CASSETTE_MASK_MOTOR); if (BIT(bits, 6)) m_centronics->write_strobe(BIT(data, 6)); - m_upd7801.portc = data; } +// HOLD_LINE used because the interrupt is set and cleared by successive instructions, too fast for the maincpu to notice +void fp1100_state::handle_int_to_main() +{ + // IRQ is on if bit 4 of mask AND bit 3 portC + if (BIT(m_upd7801.portc, 3) && BIT(m_irq_mask, 4)) + { + if (!m_main_irq_status) + { + m_maincpu->set_input_line(0, HOLD_LINE); + LOG("%s: Main IRQ asserted\n",machine().describe_context()); +// m_main_irq_status = true; + } + } + else + { + if (m_main_irq_status) + { +// m_maincpu->set_input_line(0, CLEAR_LINE); +// LOG("%s: Main IRQ cleared\n",machine().describe_context()); + m_main_irq_status = false; + } + } +} /* Input ports */ static INPUT_PORTS_START( fp1100 ) @@ -361,8 +399,9 @@ static INPUT_PORTS_START( fp1100 ) PORT_START("KEY.1") PORT_BIT(0x80, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_NAME("Break") - PORT_BIT(0x70, IP_ACTIVE_LOW, IPT_UNUSED) - PORT_BIT(0x08, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_CODE(KEYCODE_CAPSLOCK) PORT_TOGGLE PORT_NAME("Caps") + PORT_BIT(0x60, IP_ACTIVE_LOW, IPT_UNUSED) + PORT_BIT(0x10, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_CODE(KEYCODE_PGUP) PORT_NAME("Kanji") // guess, it's in Japanese + PORT_BIT(0x08, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_CODE(KEYCODE_CAPSLOCK) PORT_NAME("Caps") PORT_BIT(0x04, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_CODE(KEYCODE_LALT) PORT_NAME("Graph") PORT_BIT(0x02, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_CODE(KEYCODE_LCONTROL) PORT_CODE(KEYCODE_RCONTROL) PORT_NAME("Ctrl") PORT_BIT(0x01, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_CODE(KEYCODE_LSHIFT) PORT_CODE(KEYCODE_RSHIFT) PORT_NAME("Shift") PORT_CHAR(UCHAR_SHIFT_1) @@ -478,13 +517,13 @@ static INPUT_PORTS_START( fp1100 ) PORT_BIT(0x01, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_CODE(KEYCODE_QUOTE) PORT_NAME(":") PORT_CHAR(':') PORT_CHAR('*') PORT_START("KEY.13") - PORT_BIT(0xff, IP_ACTIVE_LOW, IPT_UNUSED) + PORT_BIT(0xff, IP_ACTIVE_LOW, IPT_UNUSED) // Capslock LED on PORT_START("KEY.14") - PORT_BIT(0xff, IP_ACTIVE_LOW, IPT_UNUSED) + PORT_BIT(0xff, IP_ACTIVE_LOW, IPT_UNUSED) // Kanji LED on PORT_START("KEY.15") - PORT_BIT(0xff, IP_ACTIVE_LOW, IPT_UNUSED) + PORT_BIT(0xff, IP_ACTIVE_LOW, IPT_UNUSED) // LEDs off PORT_START("DSW") PORT_DIPNAME( 0x01, 0x01, "Text width" ) PORT_DIPLOCATION("SW1:1") @@ -595,6 +634,8 @@ INTERRUPT_GEN_MEMBER( fp1100_state::vblank_irq ) void fp1100_state::machine_reset() { + m_main_irq_status = false; + m_sub_irq_status = false; int i; uint8_t slot_type; const uint8_t id_type[4] = { 0xff, 0x00, 0x01, 0x04}; @@ -610,8 +651,8 @@ void fp1100_state::machine_reset() membank("bankw0")->set_entry(0); // always write to ram m_irq_mask = 0; - m_main_latch = 0; - m_sub_latch = 0; + m_latch_sub_to_main = 0; + m_latch_main_to_sub = 0; m_slot_num = 0; m_kbd_row = 0; m_col_border = 0; @@ -620,6 +661,7 @@ void fp1100_state::machine_reset() m_upd7801.porta = 0; m_upd7801.portb = 0; m_upd7801.portc = 0; + m_maincpu->set_input_line_vector(0, 0xF0); } void fp1100_state::init_fp1100()