pc9801: make sure a read by itself can load the shifter

This commit is contained in:
cracyc 2024-11-13 10:31:01 -06:00
parent 5f7e56540d
commit 078031f62e
3 changed files with 22 additions and 8 deletions

View File

@ -865,7 +865,8 @@ void pc9801vm_state::egc_w(offs_t offset, uint16_t data, uint16_t mem_mask)
m_egc.leftover[0] = m_egc.leftover[1] = m_egc.leftover[2] = m_egc.leftover[3] = 0;
m_egc.count = (m_egc.regs[7] & 0xfff) + 1;
m_egc.first = true;
m_egc.init = false;
m_egc.start = false;
m_egc.loaded = false;
break;
}
}
@ -1116,6 +1117,7 @@ void pc9801vm_state::pc9801ux_io(address_map &map)
map(0x0439, 0x0439).rw(FUNC(pc9801vm_state::dma_access_ctrl_r), FUNC(pc9801vm_state::dma_access_ctrl_w));
map(0x043c, 0x043f).w(FUNC(pc9801vm_state::pc9801rs_bank_w)); //ROM/RAM bank
map(0x04a0, 0x04af).w(FUNC(pc9801vm_state::egc_w));
map(0x04ae, 0x04af).lr16(NAME([this]() { return m_egc.first; }));
map(0x3fd8, 0x3fdf).rw(m_pit, FUNC(pit8253_device::read), FUNC(pit8253_device::write)).umask16(0xff00);
}
@ -2027,7 +2029,7 @@ MACHINE_START_MEMBER(pc9801vm_state,pc9801rs)
save_item(NAME(m_egc.count));
save_item(NAME(m_egc.leftover));
save_item(NAME(m_egc.first));
save_item(NAME(m_egc.init));
save_item(NAME(m_egc.start));
save_item(NAME(m_grcg.mode));
save_item(NAME(m_vram_bank));

View File

@ -496,7 +496,8 @@ private:
int16_t count = 0;
uint16_t leftover[4]{};
bool first = false;
bool init = false;
bool start = false;
bool loaded = false;
} m_egc;
protected:

View File

@ -725,7 +725,7 @@ void pc9801vm_state::egc_blit_w(uint32_t offset, uint16_t data, uint16_t mem_mas
int dst_off = (m_egc.regs[6] >> 4) & 0xf, src_off = m_egc.regs[6] & 0xf;
offset = (offset & 0x3fff) + m_vram_bank * 0x10000;
if(!m_egc.init && (src_off > dst_off))
if(!m_egc.start && (src_off > dst_off))
{
if(BIT(m_egc.regs[2], 10))
{
@ -733,7 +733,7 @@ void pc9801vm_state::egc_blit_w(uint32_t offset, uint16_t data, uint16_t mem_mas
// leftover[0] is inited above, set others to same
m_egc.leftover[1] = m_egc.leftover[2] = m_egc.leftover[3] = m_egc.leftover[0];
}
m_egc.init = true;
m_egc.start = true;
return;
}
@ -741,7 +741,7 @@ void pc9801vm_state::egc_blit_w(uint32_t offset, uint16_t data, uint16_t mem_mas
if(m_egc.first)
{
mask &= dir ? ~((1 << dst_off) - 1) : ((1 << (16 - dst_off)) - 1);
m_egc.init = true;
m_egc.start = true;
}
// mask off the bits past the end of the blit
@ -816,7 +816,8 @@ void pc9801vm_state::egc_blit_w(uint32_t offset, uint16_t data, uint16_t mem_mas
if(m_egc.count <= 0)
{
m_egc.first = true;
m_egc.init = false;
m_egc.start = false;
m_egc.loaded = false;
m_egc.count = (m_egc.regs[7] & 0xfff) + 1;
}
}
@ -831,7 +832,17 @@ uint16_t pc9801vm_state::egc_blit_r(uint32_t offset, uint16_t mem_mask)
m_egc.pat[2] = m_video_ram[1][plane_off + (0x4000 * 3)];
m_egc.pat[3] = m_video_ram[1][plane_off];
}
m_egc.init = true;
if(m_egc.first && !m_egc.start && !m_egc.loaded)
{
int dst_off = (m_egc.regs[6] >> 4) & 0xf, src_off = m_egc.regs[6] & 0xf;
if(dst_off >= src_off) // check if it needs to be shifted into the next word
m_egc.start = true;
m_egc.loaded = true;
}
else
m_egc.start = true;
for(int i = 0; i < 4; i++)
m_egc.src[i] = egc_shift(i, m_video_ram[1][plane_off + (((i + 1) & 3) * 0x4000)]);