mirror of
https://github.com/holub/mame
synced 2025-04-17 22:13:04 +03:00
nec/pc88va_sgp.cpp: make RMW shifting more reliable, add 1bpp to 1bpp/4bpp OPs
This commit is contained in:
parent
044fb3002a
commit
9ed724e2ce
@ -103,8 +103,8 @@ brk 8Ch AH=02h read calendar clock -> CH = hour, CL = minutes, DH = seconds, DL
|
||||
#define LOGGFXCTRL(...) LOGMASKED(LOG_GFXCTRL, __VA_ARGS__)
|
||||
|
||||
// TODO: verify clocks
|
||||
#define MASTER_CLOCK XTAL(8'000'000) // may be XTAL(31'948'800) / 4? (based on PC-8801 and PC-9801)
|
||||
#define FM_CLOCK (XTAL(31'948'800) / 4) // 3993600
|
||||
#define MASTER_CLOCK (XTAL(31'948'800) / 4) // (based on PC-8801 and PC-9801)
|
||||
#define FM_CLOCK (XTAL(31'948'800) / 4) // 3993600, / 8 for regular pc88va
|
||||
|
||||
|
||||
|
||||
@ -1366,6 +1366,7 @@ void pc88va_state::pc88va(machine_config &config)
|
||||
SPEAKER(config, m_lspeaker).front_left();
|
||||
SPEAKER(config, m_rspeaker).front_right();
|
||||
|
||||
// TODO: YM2203 for vanilla pc88va
|
||||
// PC-88VA-12 "Sound Board II", YM2608B
|
||||
YM2608(config, m_opna, FM_CLOCK);
|
||||
m_opna->set_addrmap(0, &pc88va_state::opna_map);
|
||||
|
@ -8,7 +8,7 @@ Unknown part number, used as GPU for PC88VA
|
||||
|
||||
TODO:
|
||||
- timing details;
|
||||
- unemulated CLS, LINE and SCAN;
|
||||
- unemulated CLS, LINE, SCAN;
|
||||
- Uneven src/dst sizes or color depths (mostly for PATBLT);
|
||||
- specifics about what exactly happens in work area when either SGP runs or is idle;
|
||||
- famista: during gameplay it BITBLT same source to destination 0x00037076
|
||||
@ -209,10 +209,10 @@ void pc88va_sgp_device::start_exec()
|
||||
}
|
||||
case 0x0006:
|
||||
{
|
||||
const u16 color_code = m_data->read_word(vdp_pointer + 2);
|
||||
m_color_code = m_data->read_word(vdp_pointer + 2);
|
||||
LOGCOMMAND("SGP: (PC=%08x) SET COLOR %04x\n"
|
||||
, vdp_pointer
|
||||
, color_code
|
||||
, m_color_code
|
||||
);
|
||||
next_pc += 2;
|
||||
break;
|
||||
@ -363,6 +363,7 @@ bool pc88va_sgp_device::tpmod_1_src(u16 src, u16 dst) { return src != 0; }
|
||||
bool pc88va_sgp_device::tpmod_2_dst(u16 src, u16 dst) { return dst == 0; }
|
||||
bool pc88va_sgp_device::tpmod_3_never(u16 src, u16 dst) { return false; }
|
||||
|
||||
|
||||
/*
|
||||
* ---x ---- ---- ---- SF (0) shift source according to destination position
|
||||
* ---- x--- ---- ---- VD vertical transfer direction (1) negative (0) positive
|
||||
@ -420,8 +421,7 @@ void pc88va_sgp_device::execute_blit(u16 draw_mode, bool is_patblt)
|
||||
return;
|
||||
}
|
||||
|
||||
// TODO: pceva2tb:SKYBD.BAT wants a 1bpp to 4bpp translation
|
||||
if (m_src.pixel_mode == 0 || m_src.pixel_mode != m_dst.pixel_mode)
|
||||
if (m_src.pixel_mode != m_dst.pixel_mode && m_src.pixel_mode != 0 && m_dst.pixel_mode != 1)
|
||||
{
|
||||
static const char *const pixel_mode[] = { "1bpp", "4bpp", "8bpp", "rgb565" };
|
||||
|
||||
@ -434,24 +434,71 @@ void pc88va_sgp_device::execute_blit(u16 draw_mode, bool is_patblt)
|
||||
u32 src_address = m_src.address + (yi * m_src.fb_pitch);
|
||||
u32 dst_address = m_dst.address + (yi * m_dst.fb_pitch);
|
||||
|
||||
// TODO: should fetch on demand, depending on color mode/start dot etc.
|
||||
// TODO: should fetch on demand, depending on m_dst.pixel_mode etc.
|
||||
// m_src.start_dot is used by famista (pitcher throws)
|
||||
for (int xi = 0; xi < m_src.hsize; xi ++)
|
||||
{
|
||||
switch(m_src.pixel_mode)
|
||||
{
|
||||
// 1bpp
|
||||
case 0:
|
||||
{
|
||||
const u32 src_offset = src_address + ((xi + m_src.start_dot) >> 3);
|
||||
const u8 src_nibble = ((xi + m_src.start_dot) ^ 7) & 7;
|
||||
|
||||
// famista, before expanding (1bpp -> 1bpp)
|
||||
if (m_dst.pixel_mode == 0)
|
||||
{
|
||||
const u32 dst_offset = dst_address + ((xi + m_dst.start_dot) >> 3);
|
||||
const u8 dst_nibble = ((xi + m_dst.start_dot) ^ 7) & 7;
|
||||
|
||||
u8 src = (m_data->read_byte(src_offset) >> src_nibble) & 0x1;
|
||||
u8 result = m_data->read_byte(dst_offset);
|
||||
u8 dst = (result >> dst_nibble) & 0x1;
|
||||
|
||||
if ((this->*tpmod_table[tp_mod])(src, dst))
|
||||
{
|
||||
result &= ~(1 << dst_nibble);
|
||||
result |= ((this->*rop_table[logical_op])(src, dst) & 1) << dst_nibble;
|
||||
m_data->write_byte(dst_offset, result);
|
||||
}
|
||||
}
|
||||
else if (m_dst.pixel_mode == 1) // famista and pceva2tb:SKYBD.BAT (1bpp -> 4bpp)
|
||||
{
|
||||
const u32 dst_offset = dst_address + ((xi + m_dst.start_dot) >> 1);
|
||||
const u8 dst_nibble = (((xi + m_dst.start_dot) ^ 1) & 1) * 4;
|
||||
|
||||
u8 src = (m_data->read_byte(src_offset) >> src_nibble) & 0x1;
|
||||
u8 result = m_data->read_byte(dst_offset);
|
||||
u8 dst = (result >> dst_nibble) & 0xf;
|
||||
|
||||
if ((this->*tpmod_table[tp_mod])(src, dst))
|
||||
{
|
||||
result &= dst_nibble ? 0x0f : 0xf0;
|
||||
result |= ((this->*rop_table[logical_op])(src, dst) ? m_color_code & 0xf : 0) << dst_nibble;
|
||||
m_data->write_byte(dst_offset, result);
|
||||
}
|
||||
}
|
||||
|
||||
break;
|
||||
}
|
||||
// 4bpp (shinraba)
|
||||
case 1:
|
||||
{
|
||||
const u8 nibble = xi & 1;
|
||||
const u32 dst_offset = dst_address + ((xi + m_dst.start_dot) >> 1);
|
||||
const u32 src_offset = src_address + ((xi + m_src.start_dot) >> 1);
|
||||
const u8 src_nibble = (((xi + m_src.start_dot) ^ 1) & 1) * 4;
|
||||
|
||||
u8 src = (m_data->read_byte(src_address + (xi >> 1)) >> (nibble * 4)) & 0xf;
|
||||
u8 dst = m_data->read_byte(dst_offset);
|
||||
u8 result = dst & (nibble ? 0x0f : 0xf0);
|
||||
const u32 dst_offset = dst_address + ((xi + m_dst.start_dot) >> 1);
|
||||
const u8 dst_nibble = (((xi + m_dst.start_dot) ^ 1) & 1) * 4;
|
||||
|
||||
u8 src = (m_data->read_byte(src_offset) >> src_nibble) & 0xf;
|
||||
u8 result = m_data->read_byte(dst_offset);
|
||||
u8 dst = (result >> dst_nibble) & 0xf;
|
||||
|
||||
if ((this->*tpmod_table[tp_mod])(src, dst))
|
||||
{
|
||||
result |= (this->*rop_table[logical_op])(src, dst) << (nibble * 4);
|
||||
result &= dst_nibble ? 0x0f : 0xf0;
|
||||
result |= (this->*rop_table[logical_op])(src, dst) << dst_nibble;
|
||||
m_data->write_byte(dst_offset, result);
|
||||
}
|
||||
|
||||
@ -461,9 +508,10 @@ void pc88va_sgp_device::execute_blit(u16 draw_mode, bool is_patblt)
|
||||
// 8bpp (tetris)
|
||||
case 2:
|
||||
{
|
||||
const u32 src_offset = src_address + (xi + m_src.start_dot);
|
||||
const u32 dst_offset = dst_address + (xi + m_dst.start_dot);
|
||||
|
||||
u8 src = m_data->read_byte(src_address + xi) & 0xff;
|
||||
u8 src = m_data->read_byte(src_offset) & 0xff;
|
||||
u8 dst = m_data->read_byte(dst_offset) & 0xff;
|
||||
u8 result = dst;
|
||||
|
||||
@ -479,9 +527,10 @@ void pc88va_sgp_device::execute_blit(u16 draw_mode, bool is_patblt)
|
||||
// RGB565 (ballbrkr title)
|
||||
case 3:
|
||||
{
|
||||
const u32 src_offset = src_address + ((xi + m_src.start_dot) << 1);
|
||||
const u32 dst_offset = dst_address + ((xi + m_dst.start_dot) << 1);
|
||||
|
||||
u16 src = m_data->read_word(src_address + (xi << 1)) & 0xffff;
|
||||
u16 src = m_data->read_word(src_offset) & 0xffff;
|
||||
u16 dst = m_data->read_word(dst_offset) & 0xffff;
|
||||
u16 result = dst;
|
||||
|
||||
|
@ -30,6 +30,7 @@ private:
|
||||
|
||||
u16 m_vdp_address[2]{};
|
||||
u32 m_work_address = 0;
|
||||
u16 m_color_code;
|
||||
|
||||
struct BufferArea {
|
||||
u8 start_dot = 0;
|
||||
|
Loading…
Reference in New Issue
Block a user