diff --git a/src/mame/nec/pc88va.cpp b/src/mame/nec/pc88va.cpp index 31e7f363b79..557777c1d91 100644 --- a/src/mame/nec/pc88va.cpp +++ b/src/mame/nec/pc88va.cpp @@ -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); diff --git a/src/mame/nec/pc88va_sgp.cpp b/src/mame/nec/pc88va_sgp.cpp index b70860358a7..6bcfd1e9f7c 100644 --- a/src/mame/nec/pc88va_sgp.cpp +++ b/src/mame/nec/pc88va_sgp.cpp @@ -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; diff --git a/src/mame/nec/pc88va_sgp.h b/src/mame/nec/pc88va_sgp.h index 24a53cc6f95..dd8c6232d80 100644 --- a/src/mame/nec/pc88va_sgp.h +++ b/src/mame/nec/pc88va_sgp.h @@ -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;