nec/pc88va_v.cpp: hook GDEN0 and VW

nec/pc88va_sgp.cpp: hook start_dot for destination transfers
This commit is contained in:
angelosa 2025-03-08 17:13:50 +01:00
parent be13ded5f6
commit 8e9f5d9e1d
4 changed files with 48 additions and 22 deletions

View File

@ -93,7 +93,7 @@ brk 8Ch AH=02h read calendar clock -> CH = hour, CL = minutes, DH = seconds, DL
#define LOG_FDC2 (1U << 3) // $1b4-$1b6 accesses (verbose)
#define LOG_GFXCTRL (1U << 4) // $5xx accesses
#define VERBOSE (LOG_GENERAL | LOG_FDC | LOG_GFXCTRL)
#define VERBOSE (LOG_GENERAL | LOG_FDC)
//#define LOG_OUTPUT_STREAM std::cout
#include "logmacro.h"

View File

@ -197,8 +197,10 @@ private:
uint16_t m_video_pri_reg[2];
u16 m_screen_ctrl_reg;
bool m_gden0;
bool m_dm;
bool m_ymmd;
u8 m_vw;
u16 m_gfx_ctrl_reg;
u16 m_color_mode;

View File

@ -404,10 +404,10 @@ void pc88va_sgp_device::execute_blit(u16 draw_mode, bool is_patblt)
if (draw_mode & 0xfc00)
{
popmessage("SGP: draw_mode = %04x (HD %d VD %d SF %d)", draw_mode, BIT(draw_mode, 10), BIT(draw_mode, 11), BIT(draw_mode, 12));
popmessage("SGP: Warning draw_mode = %04x (HD %d VD %d SF %d)", draw_mode, BIT(draw_mode, 10), BIT(draw_mode, 11), BIT(draw_mode, 12));
}
// TODO: boomer title screen
// boomer title screen just sets the same h/v size, irrelevant
if (is_patblt == true)
{
LOG("PATBLT\n");
@ -416,25 +416,22 @@ void pc88va_sgp_device::execute_blit(u16 draw_mode, bool is_patblt)
if (m_src.hsize != m_dst.hsize || m_src.vsize != m_dst.vsize)
{
LOG("BITBLT non-even sizes (%d x %d) x (%d x %d)\n", m_src.hsize, m_src.vsize, m_dst.hsize, m_dst.vsize);
LOG("SGP: Warning BITBLT non-even sizes (%d x %d) x (%d x %d)\n", m_src.hsize, m_src.vsize, m_dst.hsize, m_dst.vsize);
return;
}
if (m_src.pixel_mode == 0 || m_src.pixel_mode == 3 || m_src.pixel_mode != m_dst.pixel_mode)
{
LOG("BITBLT pixel mode %d x %d\n", m_src.pixel_mode, m_dst.pixel_mode);
LOG("SGP: Warning BITBLT pixel mode %d x %d\n", m_src.pixel_mode, m_dst.pixel_mode);
return;
}
//static const u8 shift_table = { 3, 1, 0, -1 };
//const u8 hsize_shift = m_src.pixel_mode == 1 ? 1 : 0;
for (int yi = 0; yi < m_src.vsize; yi ++)
{
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 what's the color mode/the start dot etc.
// TODO: should fetch on demand, depending on color mode/start dot etc.
for (int xi = 0; xi < m_src.hsize; xi ++)
{
switch(m_src.pixel_mode)
@ -443,14 +440,16 @@ void pc88va_sgp_device::execute_blit(u16 draw_mode, bool is_patblt)
case 1:
{
const u8 nibble = xi & 1;
const u32 dst_offset = dst_address + ((xi + m_dst.start_dot) >> 1);
u8 src = (m_data->read_byte(src_address + (xi >> 1)) >> (nibble * 4)) & 0xf;
u8 dst = m_data->read_byte(dst_address + (xi >> 1));
u8 dst = m_data->read_byte(dst_offset);
u8 result = dst & (nibble ? 0x0f : 0xf0);
if ((this->*tpmod_table[tp_mod])(src, dst))
{
result |= (this->*rop_table[logical_op])(src, dst) << (nibble * 4);
m_data->write_byte(dst_address + (xi >> 1), result);
m_data->write_byte(dst_offset, result);
}
break;
@ -459,14 +458,16 @@ void pc88va_sgp_device::execute_blit(u16 draw_mode, bool is_patblt)
// 8bpp (tetris)
case 2:
{
const u32 dst_offset = dst_address + (xi + m_dst.start_dot);
u8 src = m_data->read_byte(src_address + xi) & 0xff;
u8 dst = m_data->read_byte(dst_address + xi) & 0xff;
u8 dst = m_data->read_byte(dst_offset) & 0xff;
u8 result = dst;
if ((this->*tpmod_table[tp_mod])(src, dst))
{
result = (this->*rop_table[logical_op])(src, dst);
m_data->write_byte(dst_address + xi, result);
m_data->write_byte(dst_offset, result);
}
break;

View File

@ -57,6 +57,7 @@ void pc88va_state::video_start()
void pc88va_state::video_reset()
{
m_gden0 = false;
m_text_transpen = 0;
m_screen_ctrl_reg = 0;
m_color_mode = 0;
@ -691,6 +692,10 @@ void pc88va_state::draw_text(bitmap_rgb32 &bitmap, const rectangle &cliprect)
void pc88va_state::draw_graphic_layer(bitmap_rgb32 &bitmap, const rectangle &cliprect, u8 which)
{
// Master graphic enable
if (!m_gden0)
return;
// disable graphic B if screen 0 only setting is enabled
if (which && !m_ymmd)
return;
@ -704,9 +709,13 @@ void pc88va_state::draw_graphic_layer(bitmap_rgb32 &bitmap, const rectangle &cli
const u8 gfx_ctrl = (m_gfx_ctrl_reg >> (which * 8)) & 0x13;
// TODO: xak2 wants independent doubled Y axis on setup menu & Micro Cabin logo
// i.e. 200 lines draw on a 400 lines canvas
// H320 setting
const u32 pixel_size = 0x10000 >> BIT(gfx_ctrl, 4);
// xak2/fray/boomer all sets independent doubled Y axis
// i.e. 200 lines draw on a 400 lines canvas
const int v_sizes[4] = { 400, 408, 200, 204 };
const u32 line_size = (0x10000 * v_sizes[m_vw]) / m_screen->visible_area().height();
//popmessage("%08x %d %d %d", line_size, m_screen->visible_area().height(), m_vw, BIT(m_screen_ctrl_reg, 7));
const u8 layer_pal_bank = get_layer_pal_bank(2 + which);
@ -716,6 +725,7 @@ void pc88va_state::draw_graphic_layer(bitmap_rgb32 &bitmap, const rectangle &cli
, layer_pal_bank
);
// m_graphic_bitmap[which].fill(m_palette->pen(layer_pal_bank), cliprect);
m_graphic_bitmap[which].fill(0, cliprect);
const int layer_inc = (!is_5bpp) + 1;
@ -775,6 +785,9 @@ void pc88va_state::draw_graphic_layer(bitmap_rgb32 &bitmap, const rectangle &cli
switch(gfx_ctrl & 3)
{
case 1: draw_packed_gfx_4bpp(m_graphic_bitmap[which], split_cliprect, fsa, dsa, layer_pal_bank, fbw, fbl); break;
default:
popmessage("pc88va_v.cpp: unhandled %d GFX mode DM = 0", which);
break;
}
}
else
@ -792,15 +805,18 @@ void pc88va_state::draw_graphic_layer(bitmap_rgb32 &bitmap, const rectangle &cli
draw_direct_gfx_8bpp(m_graphic_bitmap[which], split_cliprect, fsa, fbw, fbl);
break;
case 3: draw_direct_gfx_rgb565(m_graphic_bitmap[which], split_cliprect, fsa, fbw, fbl); break;
default:
popmessage("pc88va_v.cpp: unhandled %d GFX mode DM = 1", which);
break;
}
}
}
// TODO: we eventually need primask_copyrozbitmap_trans here, or a custom copy, depending on what the "transpen" registers really do.
// TODO: primask_copyrozbitmap_trans
copyrozbitmap_trans(
bitmap, cliprect, m_graphic_bitmap[which],
0, 0,
pixel_size, 0, 0, pixel_size,
pixel_size, 0, 0, line_size,
false, 0
);
}
@ -1222,9 +1238,11 @@ void pc88va_state::recompute_parameters()
visarea.set(0, h_vis_area - 1, 0, v_vis_area - 1);
// TODO: vertical magnify, bit 7
// TODO: actual clock source must be external, assume known PC-88 XTALs, a bit off compared to PC-88 with the values above
const int clock_speed = BIT(m_crtc_regs[0x00], 6) ? (31'948'800 / 4) : (28'636'363 / 2);
// TODO: vertical global magnify at bit 7
// TODO: actual clock source must be external, assume known PC-88 XTALs
// TODO: a bit off compared to PC-88 equivalent with the configured values
// TODO: famista pukes a 31.2 Hz vertical in 24kHz mode
const int clock_speed = !!BIT(m_crtc_regs[0x00], 6) ? (31'948'800 / 4) : (28'636'363 / 2);
refresh = HZ_TO_ATTOSECONDS(clock_speed) * h_vis_area * v_vis_area;
@ -1487,10 +1505,15 @@ void pc88va_state::screen_ctrl_w(offs_t offset, u16 data, u16 mem_mask)
COMBINE_DATA(&m_screen_ctrl_reg);
m_ymmd = bool(BIT(m_screen_ctrl_reg, 11));
m_dm = bool(BIT(m_screen_ctrl_reg, 10));
// YMMD DM
// mightmag 0xb060 (0) screen 0 (0) multiplane
m_gden0 = !!(BIT(m_screen_ctrl_reg, 15));
m_ymmd = !!(BIT(m_screen_ctrl_reg, 11));
m_dm = !!(BIT(m_screen_ctrl_reg, 10));
m_vw = m_screen_ctrl_reg & 3;
if (m_vw & 1)
popmessage("pc88va_v.cpp: VW = %d (408/204 lines mode)", m_vw);
}
u16 pc88va_state::screen_ctrl_r()