mirror of
https://github.com/holub/mame
synced 2025-04-16 13:34:55 +03:00
(nw) fp1100: improved handshaking between cpus
upd7801: fixed problem with first INTF2 being ignored.
This commit is contained in:
parent
db318046c4
commit
17d174d812
@ -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;
|
||||
}
|
||||
}
|
||||
|
@ -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()
|
||||
|
Loading…
Reference in New Issue
Block a user