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