diff --git a/hash/pc88va.xml b/hash/pc88va.xml
index 592147ac9a6..24e1c1a92eb 100644
--- a/hash/pc88va.xml
+++ b/hash/pc88va.xml
@@ -581,6 +581,8 @@ Omake: if sound irqs don't run then needs to press key 0 pad to move on
]]>
+
+
@@ -591,7 +593,7 @@ Omake: if sound irqs don't run then needs to press key 0 pad to move on
-
+
diff --git a/src/mame/nec/pc88va.cpp b/src/mame/nec/pc88va.cpp
index 557777c1d91..22f2e2bc8f0 100644
--- a/src/mame/nec/pc88va.cpp
+++ b/src/mame/nec/pc88va.cpp
@@ -44,7 +44,7 @@ TODO:
- Support for PC8801 compatible mode & PC80S31K (floppy interface);
Notes:
-- hold F8 at POST to bring software dip settings menu
+- hold F8 at POST to bring software dip settings menu, F5 to cycle between pages;
- PC-88VA-91 is a ROM upgrade kit for a PC-88VA -> VA2/VA3.
Has four roms, marked by VAEG as VUROM00.ROM, VUROM08.ROM, VUROM1.ROM, VUDIC.ROM.
@@ -632,7 +632,7 @@ void pc88va_state::io_map(address_map &map)
// map(0x0124, 0x0125) ? (related to Transparent Color of Graphic Screen 0)
// map(0x0126, 0x0127) ? (related to Transparent Color of Graphic Screen 1)
map(0x012e, 0x012f).w(FUNC(pc88va_state::text_transpen_w));
-// map(0x0130, 0x0137) Picture Mask Parameter (global cliprect, olteus gameplay)
+ map(0x0130, 0x0137).w(FUNC(pc88va_state::picture_mask_w));
map(0x0142, 0x0142).rw(FUNC(pc88va_state::idp_status_r), FUNC(pc88va_state::idp_command_w)); //Text Controller (IDP) - (R) Status (W) command
map(0x0146, 0x0146).w(FUNC(pc88va_state::idp_param_w)); //Text Controller (IDP) - (R/W) Parameter
map(0x0148, 0x0148).w(FUNC(pc88va_state::text_control_1_w));
diff --git a/src/mame/nec/pc88va.h b/src/mame/nec/pc88va.h
index d8a656d6b57..b7fff21a09a 100644
--- a/src/mame/nec/pc88va.h
+++ b/src/mame/nec/pc88va.h
@@ -232,6 +232,11 @@ private:
u8 rop[2];
} m_singleplane;
+ struct {
+ u16 top, bottom;
+ u16 left, right;
+ } m_picture_mask;
+
u8 rop_execute(u8 plane_rop, u8 src, u8 dst, u8 pat);
u8 gvram_singleplane_r(offs_t offset);
void gvram_singleplane_w(offs_t offset, u8 data);
@@ -247,6 +252,7 @@ private:
void color_mode_w(offs_t offset, u16 data, u16 mem_mask = ~0);
void text_transpen_w(offs_t offset, u16 data, u16 mem_mask = ~0);
void text_control_1_w(u8 data);
+ void picture_mask_w(offs_t offset, u16 data, u16 mem_mask = ~0);
u8 m_kanji_cg_line = 0;
u8 m_kanji_cg_jis[2]{};
@@ -263,12 +269,12 @@ private:
void draw_graphic_layer(bitmap_rgb32 &bitmap, const rectangle &cliprect, u8 which);
void draw_indexed_gfx_1bpp(bitmap_rgb32 &bitmap, const rectangle &cliprect, u32 fb_start_offset, u8 pal_base);
- void draw_indexed_gfx_4bpp(bitmap_rgb32 &bitmap, const rectangle &cliprect, u32 fb_start_offset, u32 display_start_offset, u8 pal_base, u16 fb_width, u16 fb_height);
- void draw_direct_gfx_8bpp(bitmap_rgb32 &bitmap, const rectangle &cliprect, u32 fb_start_offset, u32 display_start_offset, u16 fb_width, u16 fb_height);
- void draw_direct_gfx_rgb565(bitmap_rgb32 &bitmap, const rectangle &cliprect, u32 fb_start_offset, u16 fb_width, u16 fb_height);
+ void draw_indexed_gfx_4bpp(bitmap_rgb32 &bitmap, const rectangle &cliprect, u32 fb_start_offset, u32 display_start_offset, u16 dsp_start_base, u16 scrollx, u8 pal_base, u16 fb_width, u16 fb_height);
+ void draw_direct_gfx_8bpp(bitmap_rgb32 &bitmap, const rectangle &cliprect, u32 fb_start_offset, u32 display_start_offset, u16 dsp_start_base, u16 scrollx, u16 fb_width, u16 fb_height);
+ void draw_direct_gfx_rgb565(bitmap_rgb32 &bitmap, const rectangle &cliprect, u32 fb_start_offset, u32 display_start_offset, u16 scrollx, u16 fb_width, u16 fb_height);
- void draw_packed_gfx_4bpp(bitmap_rgb32 &bitmap, const rectangle &cliprect, u32 fb_start_offset, u32 display_start_offset, u8 pal_base, u16 fb_width, u16 fb_height);
- void draw_packed_gfx_5bpp(bitmap_rgb32 &bitmap, const rectangle &cliprect, u32 fb_start_offset, u32 display_start_offset, u8 pal_base, u16 fb_width, u16 fb_height);
+ void draw_packed_gfx_4bpp(bitmap_rgb32 &bitmap, const rectangle &cliprect, u32 fb_start_offset, u32 display_start_offset, u16 scrollx, u8 pal_base, u16 fb_width, u16 fb_height);
+ void draw_packed_gfx_5bpp(bitmap_rgb32 &bitmap, const rectangle &cliprect, u32 fb_start_offset, u32 display_start_offset, u16 dsp_start_base, u16 scrollx, u8 pal_base, u16 fb_width, u16 fb_height);
uint32_t calc_kanji_rom_addr(uint8_t jis1,uint8_t jis2,int x,int y);
void draw_text(bitmap_rgb32 &bitmap, const rectangle &cliprect);
diff --git a/src/mame/nec/pc88va_sgp.cpp b/src/mame/nec/pc88va_sgp.cpp
index 6bcfd1e9f7c..de7a6ee5846 100644
--- a/src/mame/nec/pc88va_sgp.cpp
+++ b/src/mame/nec/pc88va_sgp.cpp
@@ -190,11 +190,11 @@ void pc88va_sgp_device::start_exec()
ptr->hsize = m_data->read_word(vdp_pointer + 4) & 0x0fff;
ptr->vsize = m_data->read_word(vdp_pointer + 6) & 0x0fff;
// NOTE: & 0xfffc causes pitch issues in boomer intro/title text, shinraba gameplay
- ptr->fb_pitch = m_data->read_word(vdp_pointer + 8) & 0xfffe;
+ ptr->fb_pitch = (s16)(m_data->read_word(vdp_pointer + 8) & 0xfffe);
ptr->address = (m_data->read_word(vdp_pointer + 10) & 0xfffe)
| (m_data->read_word(vdp_pointer + 12) << 16);
- LOGCOMMAND("SGP: (PC=%08x) SET %s %02x|H %4u|V %4u|Pitch %5u| address %08x\n"
+ LOGCOMMAND("SGP: (PC=%08x) SET %s %02x|H %4u|V %4u|Pitch %5d| address %08x\n"
, vdp_pointer
, mode ? "DESTINATION" : "SOURCE "
, param1
@@ -246,7 +246,7 @@ void pc88va_sgp_device::start_exec()
// in pixels
const u16 h_size = m_data->read_word(vdp_pointer + 6);
const u16 v_size = m_data->read_word(vdp_pointer + 8);
- const u16 fb_pitch = m_data->read_word(vdp_pointer + 10) & 0xfffe;
+ const s16 fb_pitch = m_data->read_word(vdp_pointer + 10) & 0xfffe;
const u32 src_address = (m_data->read_word(vdp_pointer + 12) & 0xfffe)
| (m_data->read_word(vdp_pointer + 14) << 16);
@@ -398,14 +398,14 @@ void pc88va_sgp_device::execute_blit(u16 draw_mode, bool is_patblt)
{
const u8 logical_op = draw_mode & 0xf;
const u8 tp_mod = (draw_mode >> 8) & 0x3;
-// const bool hd = !!BIT(draw_mode, 10);
+ const bool hd = !!BIT(draw_mode, 10);
// TODO: rtype gameplay enables VD
-// const bool vd = !!BIT(draw_mode, 11);
-// const bool sf = !!BIT(draw_mode, 12);
+ const bool vd = !!BIT(draw_mode, 11);
+ const bool sf = !!BIT(draw_mode, 12);
- if (draw_mode & 0xfc00)
+ if (hd || vd || sf)
{
- 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));
+ popmessage("SGP: Warning draw_mode = %04x (HD %d VD %d SF %d)", draw_mode, hd, vd, sf);
}
// boomer title screen just sets the same h/v size, irrelevant
diff --git a/src/mame/nec/pc88va_sgp.h b/src/mame/nec/pc88va_sgp.h
index dd8c6232d80..f0b6423edf2 100644
--- a/src/mame/nec/pc88va_sgp.h
+++ b/src/mame/nec/pc88va_sgp.h
@@ -37,7 +37,7 @@ private:
u8 pixel_mode = 0;
u16 hsize = 0;
u16 vsize = 0;
- u16 fb_pitch = 0;
+ s16 fb_pitch = 0;
u32 address = 0;
};
diff --git a/src/mame/nec/pc88va_v.cpp b/src/mame/nec/pc88va_v.cpp
index ed58d825cd5..3b57a4b106e 100644
--- a/src/mame/nec/pc88va_v.cpp
+++ b/src/mame/nec/pc88va_v.cpp
@@ -761,9 +761,13 @@ void pc88va_state::draw_graphic_layer(bitmap_rgb32 &bitmap, const rectangle &cli
// (almost likely an HW quirk, described in the docs)
// also animefrm swaps this with layer 2 (main canvas)
const u32 fsa = (layer_n == layer_fixed) ? 0x20000
- : (fb_strip_regs[0x00 / 2] & 0xfffc) | ((fb_strip_regs[0x02 / 2] & 0x3) << 16) >> 1;
+ : (fb_strip_regs[0x00 / 2] & 0xfffc) | ((fb_strip_regs[0x02 / 2] & 0x3) << 16);
+
+ u16 fbl = (fb_strip_regs[0x06 / 2] & 0x3ff) + 1;
+ // shinraba relies on this for Graphic B, assume same behaviour of upd7220 pc98:madoum*
+ if (fbl == 1)
+ fbl = 0x400;
- const u16 fbl = (fb_strip_regs[0x06 / 2] & 0x3ff) + 1;
const u8 x_dot_offs = fb_strip_regs[0x08 / 2];
const u16 ofx = fb_strip_regs[0x0a / 2] & 0x7fc;
const u16 ofy = fb_strip_regs[0x0c / 2] & 0x3ff;
@@ -773,7 +777,7 @@ void pc88va_state::draw_graphic_layer(bitmap_rgb32 &bitmap, const rectangle &cli
LOGFB("%d %08x FSA|\n\t%d FBW | %d FBL |\n\t %d OFX (%d dot)| %d OFY|\n\t %08x DSA|\n\t %04x (%d) DSH | %04x (%d) DSP\n"
, layer_n
- , fsa << 1
+ , fsa
, fbw
, fbl
, ofx
@@ -794,13 +798,18 @@ void pc88va_state::draw_graphic_layer(bitmap_rgb32 &bitmap, const rectangle &cli
rectangle fb_cliprect(cliprect.min_x, cliprect.max_x, dsp, dsp + fbl - 1);
split_cliprect &= fb_cliprect;
+ if (split_cliprect.empty())
+ continue;
+
+ // TODO: picture mask
+
if (!m_dm)
{
switch(gfx_ctrl & 3)
{
- case 1: draw_packed_gfx_4bpp(m_graphic_bitmap[which], split_cliprect, fsa, dsa, layer_pal_bank, fbw, fbl); break;
+ case 1: draw_packed_gfx_4bpp(m_graphic_bitmap[which], split_cliprect, fsa, dsa, ofx, layer_pal_bank, fbw, fbl); break;
default:
- popmessage("pc88va_v.cpp: unhandled %d GFX mode DM = 0", which);
+ popmessage("pc88va_v.cpp: unhandled %d GFX mode DM = 0 (Multiplane)", which);
break;
}
}
@@ -809,18 +818,18 @@ void pc88va_state::draw_graphic_layer(bitmap_rgb32 &bitmap, const rectangle &cli
switch(gfx_ctrl & 3)
{
//case 0: draw_indexed_gfx_1bpp(bitmap, cliprect, dsa, layer_pal_bank); break;
- case 1: draw_indexed_gfx_4bpp(m_graphic_bitmap[which], split_cliprect, fsa, dsa, layer_pal_bank, fbw, fbl); break;
+ case 1: draw_indexed_gfx_4bpp(m_graphic_bitmap[which], split_cliprect, fsa, dsa, dsp, ofx, layer_pal_bank, fbw, fbl); break;
case 2:
- if (m_pltm == 7)
+ if (is_5bpp)
{
- draw_packed_gfx_5bpp(m_graphic_bitmap[which], split_cliprect, fsa, dsa, layer_pal_bank, fbw, fbl);
+ draw_packed_gfx_5bpp(m_graphic_bitmap[which], split_cliprect, fsa, dsa, dsp, ofx, layer_pal_bank, fbw, fbl);
}
else
- draw_direct_gfx_8bpp(m_graphic_bitmap[which], split_cliprect, fsa, dsa, fbw, fbl);
+ draw_direct_gfx_8bpp(m_graphic_bitmap[which], split_cliprect, fsa, dsa, dsp, ofx, fbw, fbl);
break;
- case 3: draw_direct_gfx_rgb565(m_graphic_bitmap[which], split_cliprect, fsa, fbw, fbl); break;
+ case 3: draw_direct_gfx_rgb565(m_graphic_bitmap[which], split_cliprect, fsa, dsa, ofx, fbw, fbl); break;
default:
- popmessage("pc88va_v.cpp: unhandled %d GFX mode DM = 1", which);
+ popmessage("pc88va_v.cpp: unhandled %d GFX mode DM = 1 (Singleplane)", which);
break;
}
}
@@ -835,6 +844,7 @@ void pc88va_state::draw_graphic_layer(bitmap_rgb32 &bitmap, const rectangle &cli
);
}
+// TODO: incomplete
void pc88va_state::draw_indexed_gfx_1bpp(bitmap_rgb32 &bitmap, const rectangle &cliprect, u32 fb_start_offset, u8 pal_base)
{
for(int y = cliprect.min_y; y <= cliprect.max_y; y++)
@@ -844,7 +854,7 @@ void pc88va_state::draw_indexed_gfx_1bpp(bitmap_rgb32 &bitmap, const rectangle &
for(int x = cliprect.min_x; x <= cliprect.max_x; x += 8)
{
u16 x_char = (x >> 3);
- u32 bitmap_offset = line_offset + x_char;
+ u32 bitmap_offset = (line_offset + x_char) & 0x3ffff;
for (int xi = 0; xi < 8; xi ++)
{
@@ -858,21 +868,23 @@ void pc88va_state::draw_indexed_gfx_1bpp(bitmap_rgb32 &bitmap, const rectangle &
}
}
-void pc88va_state::draw_indexed_gfx_4bpp(bitmap_rgb32 &bitmap, const rectangle &cliprect, u32 fb_start_offset, u32 display_start_offset, u8 pal_base, u16 fb_width, u16 fb_height)
+void pc88va_state::draw_indexed_gfx_4bpp(bitmap_rgb32 &bitmap, const rectangle &cliprect, u32 fb_start_offset, u32 display_start_offset, u16 dsp_start_base, u16 scrollx, u8 pal_base, u16 fb_width, u16 fb_height)
{
// const u16 y_min = std::max(cliprect.min_y, y_start);
// const u16 y_max = std::min(cliprect.max_y, y_min + fb_height);
//printf("%d %d %d %08x %d\n", y_min, y_max, fb_width, start_offset, fb_height);
+ const u32 base_address = (fb_start_offset & 0x20000) | (display_start_offset & 0x1ffff);
+
for(int y = cliprect.min_y; y <= cliprect.max_y; y++)
{
- const u32 line_offset = ((y * fb_width) + fb_start_offset) & 0x3ffff;
+ const u32 line_offset = (((y - dsp_start_base) * fb_width) + base_address) & 0x3ffff;
for(int x = cliprect.min_x; x <= cliprect.max_x; x += 2)
{
u16 x_char = (x >> 1);
- u32 bitmap_offset = line_offset + x_char;
+ u32 bitmap_offset = (line_offset + x_char - (scrollx >> 6)) & 0x3ffff;
for (int xi = 0; xi < 2; xi ++)
{
@@ -885,20 +897,21 @@ void pc88va_state::draw_indexed_gfx_4bpp(bitmap_rgb32 &bitmap, const rectangle &
}
}
-void pc88va_state::draw_packed_gfx_5bpp(bitmap_rgb32 &bitmap, const rectangle &cliprect, u32 fb_start_offset, u32 display_start_offset, u8 pal_base, u16 fb_width, u16 fb_height)
+void pc88va_state::draw_packed_gfx_5bpp(bitmap_rgb32 &bitmap, const rectangle &cliprect, u32 fb_start_offset, u32 display_start_offset, u16 dsp_start_base, u16 scrollx, u8 pal_base, u16 fb_width, u16 fb_height)
{
// const u16 y_min = std::max(cliprect.min_y, y_start);
// const u16 y_max = std::min(cliprect.max_y, y_min + fb_height);
//printf("%d %d %d %08x %d\n", y_min, y_max, fb_width, start_offset, fb_height);
+ const u32 base_address = (fb_start_offset & 0x20000) | (display_start_offset & 0x1ffff);
for(int y = cliprect.min_y; y <= cliprect.max_y; y++)
{
- const u32 line_offset = ((y * fb_width) + fb_start_offset) & 0x3ffff;
+ const u32 line_offset = (((y - dsp_start_base) * fb_width) + base_address) & 0x3ffff;
for(int x = cliprect.min_x; x <= cliprect.max_x; x++)
{
- u32 bitmap_offset = line_offset + x;
+ u32 bitmap_offset = (line_offset + x - (scrollx >> 6)) & 0x3ffff;
u8 color = m_gvram[bitmap_offset] & 0x1f;
@@ -908,18 +921,19 @@ void pc88va_state::draw_packed_gfx_5bpp(bitmap_rgb32 &bitmap, const rectangle &c
}
}
-void pc88va_state::draw_direct_gfx_8bpp(bitmap_rgb32 &bitmap, const rectangle &cliprect, u32 fb_start_offset, u32 display_start_offset, u16 fb_width, u16 fb_height)
+void pc88va_state::draw_direct_gfx_8bpp(bitmap_rgb32 &bitmap, const rectangle &cliprect, u32 fb_start_offset, u32 display_start_offset, u16 dsp_start_base, u16 scrollx, u16 fb_width, u16 fb_height)
{
// const u16 y_min = std::max(cliprect.min_y, y_start);
// const u16 y_max = std::min(cliprect.max_y, y_min + fb_height);
+ const u32 base_address = (fb_start_offset & 0x20000) | (display_start_offset & 0x1ffff);
for(int y = cliprect.min_y; y <= cliprect.max_y; y++)
{
- const u32 line_offset = ((y * fb_width) + fb_start_offset) & 0x3ffff;
+ const u32 line_offset = (((y - dsp_start_base) * fb_width) + base_address) & 0x3ffff;
for(int x = cliprect.min_x; x <= cliprect.max_x; x++)
{
- u32 bitmap_offset = (line_offset + x) & 0x3ffff;
+ u32 bitmap_offset = (line_offset + x - (scrollx >> 6)) & 0x3ffff;
uint32_t color = (m_gvram[bitmap_offset] & 0xff);
@@ -936,19 +950,20 @@ void pc88va_state::draw_direct_gfx_8bpp(bitmap_rgb32 &bitmap, const rectangle &c
}
}
-void pc88va_state::draw_direct_gfx_rgb565(bitmap_rgb32 &bitmap, const rectangle &cliprect, u32 fb_start_offset, u16 fb_width, u16 fb_height)
+void pc88va_state::draw_direct_gfx_rgb565(bitmap_rgb32 &bitmap, const rectangle &cliprect, u32 fb_start_offset, u32 display_start_offset, u16 scrollx, u16 fb_width, u16 fb_height)
{
// const u16 y_min = std::max(cliprect.min_y, y_start);
// const u16 y_max = std::min(cliprect.max_y, y_min + fb_height);
+ const u32 base_address = (display_start_offset & 0x3ffff);
for(int y = cliprect.min_y; y <= cliprect.max_y; y++)
{
// pc88vad requires halved pitch for first screen
- const u32 line_offset = ((y * fb_width >> 1) + fb_start_offset) & 0x3ffff;
+ const u32 line_offset = ((y * fb_width >> 1) + base_address) & 0x3ffff;
for(int x = cliprect.min_x; x <= cliprect.max_x; x++)
{
- u32 bitmap_offset = (line_offset + x) << 1;
+ u32 bitmap_offset = ((line_offset + x - (scrollx >> 1)) << 1) & 0x3ffff;
uint16_t color = (m_gvram[bitmap_offset] & 0xff) | (m_gvram[bitmap_offset + 1] << 8);
@@ -963,20 +978,22 @@ void pc88va_state::draw_direct_gfx_rgb565(bitmap_rgb32 &bitmap, const rectangle
}
}
-// famista, probably all inufuto games
-void pc88va_state::draw_packed_gfx_4bpp(bitmap_rgb32 &bitmap, const rectangle &cliprect, u32 fb_start_offset, u32 display_start_offset, u8 pal_base, u16 fb_width, u16 fb_height)
+// famista, all inufuto games
+void pc88va_state::draw_packed_gfx_4bpp(bitmap_rgb32 &bitmap, const rectangle &cliprect, u32 fb_start_offset, u32 display_start_offset, u16 scrollx, u8 pal_base, u16 fb_width, u16 fb_height)
{
// const u16 y_min = std::max(cliprect.min_y, y_start);
// const u16 y_max = std::min(cliprect.max_y, y_min + fb_height);
+ const u32 base_offset = display_start_offset >> 2;
+
for(int y = cliprect.min_y; y <= cliprect.max_y; y++)
{
- const u32 line_offset = ((y * (fb_width >> 2)) + fb_start_offset) & 0x0ffff;
+ const u32 line_offset = ((y * (fb_width >> 2)) + base_offset) & 0x0ffff;
for(int x = cliprect.min_x; x <= cliprect.max_x; x += 8)
{
u16 x_char = (x >> 3);
- u32 bitmap_offset = (line_offset + x_char + (display_start_offset >> 2)) & 0x0ffff;
+ u32 bitmap_offset = (line_offset + x_char - (scrollx >> 2)) & 0x0ffff;
for (int xi = 0; xi < 8; xi ++)
{
@@ -1659,6 +1676,19 @@ void pc88va_state::text_transpen_w(offs_t offset, u16 data, u16 mem_mask)
popmessage("text transpen > 15 (%04x)", m_text_transpen);
}
+void pc88va_state::picture_mask_w(offs_t offset, u16 data, u16 mem_mask)
+{
+ switch(offset)
+ {
+ case 0: COMBINE_DATA(&m_picture_mask.left); m_picture_mask.left &= 0x3ff; break;
+ case 1: COMBINE_DATA(&m_picture_mask.right); m_picture_mask.right &= 0x3ff; break;
+ case 2: COMBINE_DATA(&m_picture_mask.top); m_picture_mask.top &= 0xff; break;
+ case 3: COMBINE_DATA(&m_picture_mask.bottom); m_picture_mask.bottom &= 0xff; break;
+ }
+
+// popmessage("x0 %d y0 %d - x1 %d y1 %d", m_picture_mask.left, m_picture_mask.top, m_picture_mask.right, m_picture_mask.bottom);
+}
+
/*
* $14c-$14f Kanji CG ports
* Alt method for access kanji ROM for drawing to graphic layers