mirror of
https://github.com/holub/mame
synced 2025-05-17 19:24:59 +03:00
wicat: Reduce video glitchiness with more sensible interrupt handling
This commit is contained in:
parent
1b8d0decb5
commit
a279ee3773
@ -313,7 +313,7 @@ void i8275_device::device_timer(emu_timer &timer, device_timer_id id, int param,
|
||||
}
|
||||
}
|
||||
|
||||
if ((m_status & ST_IE) && m_scanline == m_irq_scanline)
|
||||
if ((m_status & ST_IE) && !(m_status & ST_IR) && m_scanline == m_irq_scanline)
|
||||
{
|
||||
//LOG("I8275 y %u x %u IRQ 1\n", y, x);
|
||||
m_status |= ST_IR;
|
||||
@ -557,7 +557,7 @@ WRITE8_MEMBER( i8275_device::write )
|
||||
case CMD_RESET:
|
||||
LOG("I8275 Reset\n");
|
||||
|
||||
m_status &= ~(ST_IE | ST_VE);
|
||||
m_status &= ~(ST_IE | ST_IR | ST_VE);
|
||||
LOG("I8275 IRQ 0\n");
|
||||
m_write_irq(CLEAR_LINE);
|
||||
m_write_drq(0);
|
||||
|
@ -26,6 +26,7 @@ Wicat - various systems.
|
||||
#include "machine/6522via.h"
|
||||
#include "machine/am9517a.h"
|
||||
#include "machine/im6402.h"
|
||||
#include "machine/input_merger.h"
|
||||
#include "machine/mc2661.h"
|
||||
#include "machine/mm58274c.h"
|
||||
#include "machine/wd_fdc.h"
|
||||
@ -52,7 +53,9 @@ public:
|
||||
m_uart5(*this, "uart5"),
|
||||
m_uart6(*this, "uart6"),
|
||||
m_videocpu(*this, "videocpu"),
|
||||
m_videoctrl(*this,"video"),
|
||||
m_videoctrl(*this, "videoctrl"),
|
||||
m_videoirq(*this, "videoirq"),
|
||||
m_crtc(*this, "video"),
|
||||
m_videodma(*this, "videodma"),
|
||||
m_videouart0(*this, "videouart0"),
|
||||
m_videouart1(*this, "videouart1"),
|
||||
@ -88,19 +91,16 @@ public:
|
||||
DECLARE_WRITE8_MEMBER(video_timer_w);
|
||||
DECLARE_READ8_MEMBER(vram_r);
|
||||
DECLARE_WRITE8_MEMBER(vram_w);
|
||||
DECLARE_READ8_MEMBER(video_ctrl_r);
|
||||
DECLARE_WRITE8_MEMBER(video_ctrl_w);
|
||||
DECLARE_READ8_MEMBER(video_status_r);
|
||||
DECLARE_WRITE_LINE_MEMBER(dma_hrq_w);
|
||||
DECLARE_WRITE_LINE_MEMBER(dma_nmi_cb);
|
||||
DECLARE_WRITE_LINE_MEMBER(crtc_cb);
|
||||
DECLARE_WRITE_LINE_MEMBER(crtc_irq_w);
|
||||
DECLARE_WRITE_LINE_MEMBER(crtc_irq_clear_w);
|
||||
DECLARE_READ8_MEMBER(hdc_r);
|
||||
DECLARE_WRITE8_MEMBER(hdc_w);
|
||||
DECLARE_READ8_MEMBER(fdc_r);
|
||||
DECLARE_WRITE8_MEMBER(fdc_w);
|
||||
DECLARE_READ16_MEMBER(via_r);
|
||||
DECLARE_WRITE16_MEMBER(via_w);
|
||||
DECLARE_WRITE_LINE_MEMBER(kb_data_ready);
|
||||
I8275_DRAW_CHARACTER_MEMBER(wicat_display_pixels);
|
||||
|
||||
required_shared_ptr<uint8_t> m_vram;
|
||||
@ -115,7 +115,9 @@ public:
|
||||
required_device<mc2661_device> m_uart5;
|
||||
required_device<mc2661_device> m_uart6;
|
||||
required_device<cpu_device> m_videocpu;
|
||||
required_device<i8275_device> m_videoctrl;
|
||||
required_device<ls259_device> m_videoctrl;
|
||||
required_device<input_merger_device> m_videoirq;
|
||||
required_device<i8275_device> m_crtc;
|
||||
required_device<am9517a_device> m_videodma;
|
||||
required_device<mc2661_device> m_videouart0;
|
||||
required_device<mc2661_device> m_videouart1;
|
||||
@ -143,19 +145,14 @@ private:
|
||||
void poll_kb();
|
||||
void send_key(uint8_t val);
|
||||
|
||||
emu_timer* m_video_timer;
|
||||
emu_timer* m_kb_timer;
|
||||
emu_timer* m_kb_serial_timer;
|
||||
static const device_timer_id VIDEO_TIMER = 0;
|
||||
static const device_timer_id KB_TIMER = 1;
|
||||
static const device_timer_id KB_SERIAL_TIMER = 2;
|
||||
|
||||
uint8_t m_portA;
|
||||
uint8_t m_portB;
|
||||
bool m_video_timer_irq;
|
||||
bool m_video_kb_irq;
|
||||
uint8_t m_nmi_enable;
|
||||
uint8_t m_crtc_irq;
|
||||
bool m_crtc_irq;
|
||||
uint16_t m_kb_data;
|
||||
uint8_t m_kb_bit;
|
||||
uint32_t m_kb_keys[8];
|
||||
@ -203,7 +200,7 @@ void wicat_state::wicat_video_io(address_map &map)
|
||||
map(0x0400, 0x047f).rw(FUNC(wicat_state::videosram_r), FUNC(wicat_state::videosram_w)); // XD2210 4-bit NOVRAM
|
||||
map(0x0500, 0x0500).w(FUNC(wicat_state::videosram_recall_w));
|
||||
map(0x0600, 0x0600).w(FUNC(wicat_state::videosram_store_w));
|
||||
map(0x0800, 0x080f).rw(FUNC(wicat_state::video_ctrl_r), FUNC(wicat_state::video_ctrl_w));
|
||||
map(0x0800, 0x0807).w("videoctrl", FUNC(ls259_device::write_d0)).umask16(0xffff);
|
||||
map(0x0a00, 0x0a1f).rw(FUNC(wicat_state::video_dma_r), FUNC(wicat_state::video_dma_w)); // AM9517A DMA
|
||||
map(0x0b00, 0x0b03).rw(FUNC(wicat_state::video_r), FUNC(wicat_state::video_w)); // i8275 CRTC
|
||||
map(0x0e00, 0x0eff).ram();
|
||||
@ -297,7 +294,6 @@ static void wicat_floppies(device_slot_interface &device)
|
||||
|
||||
void wicat_state::driver_start()
|
||||
{
|
||||
m_video_timer = timer_alloc(VIDEO_TIMER);
|
||||
m_kb_timer = timer_alloc(KB_TIMER);
|
||||
m_kb_serial_timer = timer_alloc(KB_SERIAL_TIMER);
|
||||
}
|
||||
@ -325,12 +321,8 @@ void wicat_state::machine_reset()
|
||||
m_videouart->sbs_w(0);
|
||||
m_videouart->crl_w(1);
|
||||
|
||||
m_video_timer_irq = false;
|
||||
m_video_kb_irq = false;
|
||||
m_video_timer->adjust(attotime::zero,0,attotime::from_hz(60));
|
||||
m_kb_timer->adjust(attotime::zero,0,attotime::from_msec(50));
|
||||
m_nmi_enable = 0;
|
||||
m_crtc_irq = CLEAR_LINE;
|
||||
m_crtc_irq = false;
|
||||
for(auto & elem : m_kb_keys)
|
||||
elem = 0;
|
||||
}
|
||||
@ -339,10 +331,6 @@ void wicat_state::device_timer(emu_timer &timer, device_timer_id id, int param,
|
||||
{
|
||||
switch (id)
|
||||
{
|
||||
case VIDEO_TIMER:
|
||||
m_video_timer_irq = true;
|
||||
m_videocpu->set_input_line(INPUT_LINE_IRQ0,ASSERT_LINE);
|
||||
break;
|
||||
case KB_TIMER:
|
||||
poll_kb();
|
||||
break;
|
||||
@ -576,9 +564,9 @@ READ8_MEMBER(wicat_state::video_r)
|
||||
switch(offset)
|
||||
{
|
||||
case 0x00:
|
||||
return m_videoctrl->read(space,0);
|
||||
return m_crtc->read(space,0);
|
||||
case 0x02:
|
||||
return m_videoctrl->read(space,1);
|
||||
return m_crtc->read(space,1);
|
||||
default:
|
||||
return 0xff;
|
||||
}
|
||||
@ -589,10 +577,10 @@ WRITE8_MEMBER(wicat_state::video_w)
|
||||
switch(offset)
|
||||
{
|
||||
case 0x00:
|
||||
m_videoctrl->write(space,0,data);
|
||||
m_crtc->write(space,0,data);
|
||||
break;
|
||||
case 0x02:
|
||||
m_videoctrl->write(space,1,data);
|
||||
m_crtc->write(space,1,data);
|
||||
break;
|
||||
}
|
||||
}
|
||||
@ -682,22 +670,16 @@ READ8_MEMBER(wicat_state::video_timer_r)
|
||||
uint8_t ret = 0x00;
|
||||
|
||||
if(offset == 0x00)
|
||||
{
|
||||
if(m_video_timer_irq)
|
||||
{
|
||||
ret |= 0x08;
|
||||
m_video_timer_irq = false;
|
||||
m_videocpu->set_input_line(INPUT_LINE_IRQ0,CLEAR_LINE);
|
||||
}
|
||||
if(m_video_kb_irq)
|
||||
{
|
||||
ret |= 0x10;
|
||||
m_video_kb_irq = false;
|
||||
m_videocpu->set_input_line(INPUT_LINE_IRQ0,CLEAR_LINE);
|
||||
}
|
||||
}
|
||||
return (m_videouart->dr_r() << 4) | (m_videouart->tbre_r() && m_videoctrl->q6_r() ? 0x08 : 0x00);
|
||||
if(offset == 0x02)
|
||||
{
|
||||
if (!machine().side_effects_disabled())
|
||||
{
|
||||
m_videouart->drr_w(1);
|
||||
m_videouart->drr_w(0);
|
||||
}
|
||||
return m_videouart->read(space,0);
|
||||
}
|
||||
return ret;
|
||||
}
|
||||
|
||||
@ -708,28 +690,10 @@ WRITE8_MEMBER(wicat_state::video_timer_w)
|
||||
m_videouart->write(space,0,data);
|
||||
}
|
||||
|
||||
READ8_MEMBER(wicat_state::video_ctrl_r)
|
||||
{
|
||||
return 0x00; // TODO
|
||||
}
|
||||
|
||||
WRITE8_MEMBER(wicat_state::video_ctrl_w)
|
||||
{
|
||||
if(offset == 0x07)
|
||||
m_nmi_enable = data;
|
||||
}
|
||||
|
||||
READ8_MEMBER(wicat_state::video_status_r)
|
||||
{
|
||||
// this port is read in the NVI IRQ routine, which if bit 2 is set, will unmask DMA channel 0. But no idea what triggers it...
|
||||
if(m_crtc_irq == ASSERT_LINE)
|
||||
{
|
||||
m_crtc_irq = CLEAR_LINE;
|
||||
m_videocpu->set_input_line(INPUT_LINE_IRQ0,CLEAR_LINE);
|
||||
return 0x04;
|
||||
}
|
||||
else
|
||||
return 0x00;
|
||||
return m_crtc_irq ? 0x04 : 0x00;
|
||||
}
|
||||
|
||||
WRITE_LINE_MEMBER(wicat_state::dma_hrq_w)
|
||||
@ -738,25 +702,22 @@ WRITE_LINE_MEMBER(wicat_state::dma_hrq_w)
|
||||
m_videodma->hack_w(state);
|
||||
}
|
||||
|
||||
WRITE_LINE_MEMBER(wicat_state::dma_nmi_cb)
|
||||
WRITE_LINE_MEMBER(wicat_state::crtc_irq_w)
|
||||
{
|
||||
if(state)
|
||||
if (state && m_videoctrl->q0_r())
|
||||
{
|
||||
if(m_nmi_enable != 0)
|
||||
m_videocpu->pulse_input_line(INPUT_LINE_NMI, attotime::zero);
|
||||
m_crtc_irq = true;
|
||||
m_videoirq->in_w<1>(1);
|
||||
}
|
||||
}
|
||||
|
||||
WRITE_LINE_MEMBER(wicat_state::kb_data_ready)
|
||||
WRITE_LINE_MEMBER(wicat_state::crtc_irq_clear_w)
|
||||
{
|
||||
m_video_kb_irq = state ? ASSERT_LINE : CLEAR_LINE;
|
||||
m_videocpu->set_input_line(INPUT_LINE_IRQ0,m_video_kb_irq);
|
||||
if (!state)
|
||||
{
|
||||
m_crtc_irq = false;
|
||||
m_videoirq->in_w<1>(0);
|
||||
}
|
||||
|
||||
WRITE_LINE_MEMBER(wicat_state::crtc_cb)
|
||||
{
|
||||
m_crtc_irq = state ? ASSERT_LINE : CLEAR_LINE;
|
||||
m_videocpu->set_input_line(INPUT_LINE_IRQ0,m_crtc_irq);
|
||||
}
|
||||
|
||||
I8275_DRAW_CHARACTER_MEMBER(wicat_state::wicat_display_pixels)
|
||||
@ -879,26 +840,43 @@ MACHINE_CONFIG_START(wicat_state::wicat)
|
||||
MCFG_DEVICE_PROGRAM_MAP(wicat_video_mem)
|
||||
MCFG_DEVICE_IO_MAP(wicat_video_io)
|
||||
|
||||
MCFG_INPUT_MERGER_ANY_HIGH("videoirq")
|
||||
MCFG_INPUT_MERGER_OUTPUT_HANDLER(INPUTLINE("videocpu", INPUT_LINE_IRQ0))
|
||||
|
||||
MCFG_DEVICE_ADD("videoctrl", LS259, 0)
|
||||
MCFG_ADDRESSABLE_LATCH_Q0_OUT_CB(WRITELINE(*this, wicat_state, crtc_irq_clear_w))
|
||||
MCFG_ADDRESSABLE_LATCH_Q6_OUT_CB(WRITELINE("tbreirq", input_merger_device, in_w<1>))
|
||||
MCFG_ADDRESSABLE_LATCH_Q7_OUT_CB(WRITELINE("dmairq", input_merger_device, in_w<1>))
|
||||
// Q1-Q5 are all used but unknown
|
||||
|
||||
MCFG_DEVICE_ADD("videodma", AM9517A, 8_MHz_XTAL) // clock is a bit of guess
|
||||
MCFG_AM9517A_OUT_HREQ_CB(WRITELINE(*this, wicat_state, dma_hrq_w))
|
||||
MCFG_AM9517A_OUT_EOP_CB(WRITELINE(*this, wicat_state, dma_nmi_cb))
|
||||
MCFG_AM9517A_OUT_EOP_CB(WRITELINE("dmairq", input_merger_device, in_w<0>))
|
||||
MCFG_AM9517A_IN_MEMR_CB(READ8(*this, wicat_state, vram_r))
|
||||
MCFG_AM9517A_OUT_MEMW_CB(WRITE8(*this, wicat_state, vram_w))
|
||||
MCFG_AM9517A_OUT_IOW_0_CB(WRITE8("video", i8275_device, dack_w))
|
||||
MCFG_IM6402_ADD("videouart", 0, 0)
|
||||
MCFG_IM6402_DR_CALLBACK(WRITELINE(*this, wicat_state, kb_data_ready))
|
||||
|
||||
MCFG_INPUT_MERGER_ALL_HIGH("dmairq")
|
||||
MCFG_INPUT_MERGER_OUTPUT_HANDLER(INPUTLINE("videocpu", INPUT_LINE_NMI))
|
||||
|
||||
MCFG_IM6402_ADD("videouart", 0, 1200)
|
||||
MCFG_IM6402_DR_CALLBACK(WRITELINE("videoirq", input_merger_device, in_w<2>))
|
||||
MCFG_IM6402_TBRE_CALLBACK(WRITELINE("tbreirq", input_merger_device, in_w<0>))
|
||||
|
||||
MCFG_INPUT_MERGER_ALL_HIGH("tbreirq")
|
||||
MCFG_INPUT_MERGER_OUTPUT_HANDLER(WRITELINE("videoirq", input_merger_device, in_w<3>))
|
||||
|
||||
// terminal (2x INS2651, 1x IM6042 - one of these is for the keyboard, another communicates with the main board, the third is unknown)
|
||||
MCFG_DEVICE_ADD("videouart0", MC2661, 5.0688_MHz_XTAL) // the INS2651 looks similar enough to the MC2661...
|
||||
MCFG_MC2661_TXD_HANDLER(WRITELINE("uart0", mc2661_device, rx_w))
|
||||
MCFG_MC2661_RXRDY_HANDLER(INPUTLINE("videocpu", INPUT_LINE_IRQ0))
|
||||
MCFG_MC2661_RXRDY_HANDLER(WRITELINE("videoirq", input_merger_device, in_w<0>))
|
||||
MCFG_MC2661_RTS_HANDLER(WRITELINE("uart0", mc2661_device, cts_w))
|
||||
MCFG_MC2661_DTR_HANDLER(WRITELINE("uart0", mc2661_device, dsr_w))
|
||||
|
||||
MCFG_DEVICE_ADD("videouart1", MC2661, 5.0688_MHz_XTAL)
|
||||
MCFG_MC2661_RXC(19200)
|
||||
MCFG_MC2661_TXC(19200)
|
||||
MCFG_MC2661_RXRDY_HANDLER(INPUTLINE("videocpu", INPUT_LINE_IRQ0))
|
||||
MCFG_MC2661_RXRDY_HANDLER(WRITELINE("videoirq", input_merger_device, in_w<4>))
|
||||
|
||||
MCFG_X2210_ADD("vsram") // XD2210
|
||||
|
||||
@ -912,7 +890,7 @@ MACHINE_CONFIG_START(wicat_state::wicat)
|
||||
MCFG_I8275_CHARACTER_WIDTH(10)
|
||||
MCFG_I8275_DRAW_CHARACTER_CALLBACK_OWNER(wicat_state, wicat_display_pixels)
|
||||
MCFG_I8275_DRQ_CALLBACK(WRITELINE("videodma", am9517a_device, dreq0_w))
|
||||
MCFG_I8275_IRQ_CALLBACK(WRITELINE(*this, wicat_state,crtc_cb))
|
||||
MCFG_I8275_VRTC_CALLBACK(WRITELINE(*this, wicat_state, crtc_irq_w))
|
||||
MCFG_VIDEO_SET_SCREEN("screen")
|
||||
|
||||
MCFG_DEFAULT_LAYOUT(layout_wicat)
|
||||
|
Loading…
Reference in New Issue
Block a user