diff --git a/src/mame/nec/bungo.cpp b/src/mame/nec/bungo.cpp index 5dc2b7210de..1794725def4 100644 --- a/src/mame/nec/bungo.cpp +++ b/src/mame/nec/bungo.cpp @@ -136,6 +136,9 @@ void bungo_mini5sx_state::mini5sx_config(machine_config &config) // m_ppi_sys->in_pc_callback().set_constant(0xa0); // 0x80 cpu triple fault reset flag? // m_ppi_sys->out_pc_callback().set(FUNC(pc98lt_state::ppi_sys_beep_portc_w)); + // TODO: unverified, known to have a serial port + pc9801_serial(config); + I8255(config, m_ppi_prn, 0); // m_ppi_prn->in_pb_callback().set_ioport("PRNB"); diff --git a/src/mame/nec/bungo.h b/src/mame/nec/bungo.h index f0af4b8f2aa..385b9022835 100644 --- a/src/mame/nec/bungo.h +++ b/src/mame/nec/bungo.h @@ -38,6 +38,9 @@ private: u16 fake_dict_r(offs_t offset); + // just suppress for now, TBD + virtual void uart_irq_check() override {}; + void bungo_palette(palette_device &palette) const; uint32_t screen_update(screen_device &screen, bitmap_rgb32 &bitmap, const rectangle &cliprect); }; diff --git a/src/mame/nec/pc9801.cpp b/src/mame/nec/pc9801.cpp index 03795f9c082..24079224f0d 100644 --- a/src/mame/nec/pc9801.cpp +++ b/src/mame/nec/pc9801.cpp @@ -356,6 +356,7 @@ Keyboard TX commands: #include "emu.h" #include "pc9801.h" + #include "machine/input_merger.h" void pc98_base_state::rtc_w(uint8_t data) @@ -1657,9 +1658,25 @@ u8 pc9801_state::ppi_sys_portb_r() return res; } +void pc9801_state::uart_irq_check() +{ + m_pic1->ir4_w(m_uart_irq_pending & m_uart_irq_mask ? 1 : 0); +} + +template void pc98_base_state::update_uart_irq(int state) +{ + if (state) + m_uart_irq_pending |= 1 << N; + else + m_uart_irq_pending &= ~1 << N; + uart_irq_check(); +} + void pc98_base_state::ppi_sys_beep_portc_w(uint8_t data) { m_beeper->set_state(!(data & 0x08)); + m_uart_irq_mask = data & 7; + uart_irq_check(); } void pc9801vm_state::ppi_sys_dac_portc_w(uint8_t data) @@ -1668,6 +1685,8 @@ void pc9801vm_state::ppi_sys_dac_portc_w(uint8_t data) // TODO: some models have a finer grained volume control at I/O port 0xae8e // (98NOTE only?) m_dac1bit->set_output_gain(0, m_dac1bit_disable ? 0.0 : 1.0); + m_uart_irq_mask = data & 7; + uart_irq_check(); } /* @@ -2228,6 +2247,23 @@ void pc9801vm_state::pc9801_ide(machine_config &config) SOFTWARE_LIST(config, "cd_list").set_original("pc98_cd"); } +void pc98_base_state::pc9801_serial(machine_config &config) +{ + // clocked by PIT channel 2 + I8251(config, m_sio, 0); + m_sio->txd_handler().set("serial", FUNC(rs232_port_device::write_txd)); + m_sio->rts_handler().set("serial", FUNC(rs232_port_device::write_rts)); + m_sio->dtr_handler().set("serial", FUNC(rs232_port_device::write_dtr)); + m_sio->rxrdy_handler().set([this] (int state) { update_uart_irq<0>(state); }); + m_sio->txempty_handler().set([this] (int state) { update_uart_irq<1>(state); }); + m_sio->txrdy_handler().set([this] (int state) { update_uart_irq<2>(state); }); + + rs232_port_device &rs232(RS232_PORT(config, "serial", default_rs232_devices, nullptr)); + rs232.rxd_handler().set(m_sio, FUNC(i8251_device::write_rxd)); + rs232.cts_handler().set(m_sio, FUNC(i8251_device::write_cts)); + rs232.dsr_handler().set(m_sio, FUNC(i8251_device::write_dsr)); +} + void pc9801_state::pc9801_common(machine_config &config) { PIT8253(config, m_pit, 0); @@ -2274,7 +2310,7 @@ void pc9801_state::pc9801_common(machine_config &config) pc9801_mouse(config); pc9801_cbus(config); - I8251(config, m_sio, 0); + pc9801_serial(config); PC9801_MEMSW(config, m_memsw, 0); @@ -2292,12 +2328,12 @@ void pc9801_state::pc9801_common(machine_config &config) m_screen->set_screen_update(FUNC(pc9801_state::screen_update)); m_screen->screen_vblank().set(FUNC(pc9801_state::vrtc_irq)); - UPD7220(config, m_hgdc[0], 21.0526_MHz_XTAL / 8); + UPD7220(config, m_hgdc[0], 21.0526_MHz_XTAL / 8, "screen"); m_hgdc[0]->set_addrmap(0, &pc9801_state::upd7220_1_map); m_hgdc[0]->set_draw_text(FUNC(pc9801_state::hgdc_draw_text)); m_hgdc[0]->vsync_wr_callback().set(m_hgdc[1], FUNC(upd7220_device::ext_sync_w)); - UPD7220(config, m_hgdc[1], 21.0526_MHz_XTAL / 8); + UPD7220(config, m_hgdc[1], 21.0526_MHz_XTAL / 8, "screen"); m_hgdc[1]->set_addrmap(0, &pc9801_state::upd7220_2_map); m_hgdc[1]->set_display_pixels(FUNC(pc9801_state::hgdc_display_pixels)); diff --git a/src/mame/nec/pc9801.h b/src/mame/nec/pc9801.h index 5f7c017c240..895963ad372 100644 --- a/src/mame/nec/pc9801.h +++ b/src/mame/nec/pc9801.h @@ -33,6 +33,7 @@ #include "machine/upd4991a.h" #include "machine/upd765.h" +#include "bus/rs232/rs232.h" #include "bus/scsi/pc9801_sasi.h" #include "bus/scsi/scsi.h" #include "bus/scsi/scsihd.h" @@ -71,7 +72,6 @@ #include "formats/nfd_dsk.h" #define RTC_TAG "rtc" -#define UPD8251_TAG "upd8251" #define SASIBUS_TAG "sasi" #define ATTRSEL_REG 0 @@ -98,6 +98,7 @@ public: , m_ppi_sys(*this, "ppi_sys") , m_ppi_prn(*this, "ppi_prn") , m_beeper(*this, "beeper") + , m_sio(*this, "sio") { } @@ -112,13 +113,20 @@ protected: required_device m_ppi_sys; required_device m_ppi_prn; optional_device m_beeper; + required_device m_sio; void rtc_w(uint8_t data); void ppi_sys_beep_portc_w(uint8_t data); + virtual void uart_irq_check() = 0; + template void update_uart_irq(int state); + + void pc9801_serial(machine_config &config); + static void floppy_formats(format_registration &fr); u8 m_sys_type = 0; + u8 m_uart_irq_mask = 0, m_uart_irq_pending = 0; }; class pc9801_state : public pc98_base_state @@ -142,7 +150,6 @@ public: , m_pic1(*this, "pic8259_master") , m_pic2(*this, "pic8259_slave") , m_memsw(*this, "memsw") - , m_sio(*this, UPD8251_TAG) , m_sasibus(*this, SASIBUS_TAG) , m_sasi_data_out(*this, "sasi_data_out") , m_sasi_data_in(*this, "sasi_data_in") @@ -175,7 +182,6 @@ protected: required_device m_pic2; private: required_device m_memsw; - required_device m_sio; optional_device m_sasibus; optional_device m_sasi_data_out; optional_device m_sasi_data_in; @@ -352,6 +358,10 @@ private: void ppi_mouse_portc_w(uint8_t data); TIMER_DEVICE_CALLBACK_MEMBER( mouse_irq_cb ); + +// UART SIO +protected: + virtual void uart_irq_check() override; }; /********************************************************** diff --git a/src/mame/nec/pc98ha.cpp b/src/mame/nec/pc98ha.cpp index d6e9814a7a5..21110ec1bc3 100644 --- a/src/mame/nec/pc98ha.cpp +++ b/src/mame/nec/pc98ha.cpp @@ -151,7 +151,8 @@ void pc98lt_state::lt_io(address_map &map) map.unmap_value_high(); // map(0x0000, 0x001f) // PIC (bit 3 ON slave / master), V50 internal / map(0x0020, 0x002f).w(FUNC(pc98lt_state::rtc_w)).umask16(0x00ff); - map(0x0030, 0x0037).rw(m_ppi_sys, FUNC(i8255_device::read), FUNC(i8255_device::write)).umask16(0xff00); //i8251 RS232c / i8255 system port + map(0x0030, 0x0037).rw(m_ppi_sys, FUNC(i8255_device::read), FUNC(i8255_device::write)).umask16(0xff00); + map(0x0030, 0x0033).rw(m_sio, FUNC(i8251_device::read), FUNC(i8251_device::write)).umask16(0x00ff); //i8251 RS232c / i8255 system port map(0x0040, 0x0047).rw(m_ppi_prn, FUNC(i8255_device::read), FUNC(i8255_device::write)).umask16(0x00ff); map(0x0040, 0x0047).rw(m_keyb, FUNC(pc9801_kbd_device::rx_r), FUNC(pc9801_kbd_device::tx_w)).umask16(0xff00); //i8255 printer port / i8251 keyboard // map(0x0070, 0x007f) // PIT, V50 internal @@ -418,6 +419,13 @@ static void pc9801_floppies(device_slot_interface &device) // device.option_add("35hd", FLOPPY_35_HD); } +void pc98lt_state::uart_irq_check() +{ + m_maincpu->set_input_line(4, m_uart_irq_pending & m_uart_irq_mask ? ASSERT_LINE : CLEAR_LINE); +} + + + void pc98lt_state::lt_config(machine_config &config) { const XTAL xtal = XTAL(8'000'000); @@ -427,10 +435,9 @@ void pc98lt_state::lt_config(machine_config &config) // TODO: jumps off the weeds if divided by / 4 after timer check, DMA issue? // m_maincpu->set_tclk(xtal / 4); m_maincpu->set_tclk(xtal / 100); -// m_maincpu->tout2_cb().set_inputline(m_maincpu, INPUT_LINE_IRQ2); // m_pit->out_handler<0>().set(m_pic1, FUNC(pic8259_device::ir0_w)); -// m_pit->out_handler<2>().set(m_sio, FUNC(i8251_device::write_txc)); -// m_pit->out_handler<2>().append(m_sio, FUNC(i8251_device::write_rxc)); + m_maincpu->tout2_cb().set(m_sio, FUNC(i8251_device::write_txc)); + m_maincpu->tout2_cb().append(m_sio, FUNC(i8251_device::write_rxc)); // m_maincpu->set_irq_acknowledge_callback("pic8259_master", FUNC(pic8259_device::inta_cb)); @@ -444,6 +451,8 @@ void pc98lt_state::lt_config(machine_config &config) // m_ppi_sys->in_pc_callback().set_constant(0xa0); // 0x80 cpu triple fault reset flag? m_ppi_sys->out_pc_callback().set(FUNC(pc98lt_state::ppi_sys_beep_portc_w)); + pc9801_serial(config); + I8255(config, m_ppi_prn, 0); m_ppi_prn->in_pb_callback().set_ioport("PRNB"); diff --git a/src/mame/nec/pc98ha.h b/src/mame/nec/pc98ha.h index 63b1cb1477a..e872fd03904 100644 --- a/src/mame/nec/pc98ha.h +++ b/src/mame/nec/pc98ha.h @@ -64,6 +64,8 @@ private: u8 m_floppy_mode = 0; u8 m_fdc_ctrl = 0; + + virtual void uart_irq_check() override; }; class pc98ha_state : public pc98lt_state diff --git a/src/mame/nec/pc_h98.cpp b/src/mame/nec/pc_h98.cpp index 001912b1904..663a8e22294 100644 --- a/src/mame/nec/pc_h98.cpp +++ b/src/mame/nec/pc_h98.cpp @@ -44,6 +44,7 @@ void pc_hyper98_state::pc_h98_io(address_map &map) { pc_hyper98_state::pc9801bx2_io(map); // ... +// map(0x4*a*, 0x4*a*) μPD72120 "AGDC" } // TODO: backported from pc9801_epson.cpp, needs mods