diff options
Diffstat (limited to 'src/devices/machine/generalplus_gpl16250soc_video.cpp')
-rw-r--r-- | src/devices/machine/generalplus_gpl16250soc_video.cpp | 738 |
1 files changed, 43 insertions, 695 deletions
diff --git a/src/devices/machine/generalplus_gpl16250soc_video.cpp b/src/devices/machine/generalplus_gpl16250soc_video.cpp index a45961389cf..3967898d637 100644 --- a/src/devices/machine/generalplus_gpl16250soc_video.cpp +++ b/src/devices/machine/generalplus_gpl16250soc_video.cpp @@ -8,97 +8,6 @@ **********************************************************************/ -/* lots of games, including wrlshunt are not copying tilemap data properly - the analysis below is for wrlshunt, although gormiti could prove to be an easier case to look at - while jak_ths and jak_swc might be more difficult (the latter uses line/bitmap mode, but still - fails to copy the line data) - - - -- - - wrlshunt BG Tilemap location note - - background tilemap appears to be at 24ad30 - 24af87 (byte address) in RAM == 125698 - 1257c3 (word address) - there are pointers to this - (2879-287a) = 98 56 12 00 (00125698) (main background tilemap data is at this address) - (287b-287c) = 30 5e 12 00 (00125e30) (address for other layer tilemap) (or 'end' of above) - where do we get these copied to registers or used as a source to copy from? - - - -- callled from here - 058F79: call 054e56 (with values above, for tilemap 0) - and - 058FB1: call 054e56 (for tilemap 1) - (both of these are at the start of the function at 058F46, which we loop in at the moment, possible main loop for the menu?) - - there are other calls in the code, but those are the ones before sprites are uploaded for the menu - - -- - 054E91: r4 = [bp+27] (contains lower part of address) - 054E92: ds:[r1++] = r4 -- write 5698 to 2879 - 054E93: r4 = [bp+28] (contains upper part of address) - 054E94: ds:[r1] = r4 -- write 0012 to 287a - - (this is a huge function that ends at 55968, also has lots of calls in it) - - --- - - the base for tilemap params being written to RAM is 2879 + 0xe * tilmap number (0,1,2,3) - the code to calculate this offset from base uses 32-bit multiplication and even sign extends the tilemap number before using it, making it - look more complex than it really is! - - 054E7B: 0B0D 0088 bp = bp + 0088 - 054E7D: 9800 r4 = [bp+00] -- which tilemap? (0,1,2,3) - 054E7E: 2B0D 0088 bp = bp - 0088 - - 054E80: 973C r3 = r4 asr 4 -- sign extend tilemap 16-bit register r4 with r3 forming the upper word (always 0) - 054E81: 973B r3 = r3 asr 4 - 054E82: 973B r3 = r3 asr 4 - 054E83: 973B r3 = r3 asr 4 - - 054E84: D688 push r3, r3 to [sp] -- push onto stack for use in call below - 054E85: D888 push r4, r4 to [sp] - - 054E86: 964E r3 = 0e -- store 0000 000e as the 32-bit value to multply with - 054E87: 9840 r4 = 00 - 054E88: D890 push r3, r4 to [sp] -- push that onto stack for function call below - - 054E89: F045 D706 call 05d706 -- returns result in r1,r2 - - the result of this is then added to the base value of 2879 (which was stored earlier) - an additional offset is then added for each parameter. - - this code is repeated multiple times, with slight changes - - --- - - by the time you hit 055098 (which is a switch on tilemap type to disable a tilemap) the following params have been put at - 2879 ( tilemap 0 call ) - 2879 + 0x0e (tilemap 1 call ) - - tmap0 params - 5698 0012 | 5E30 0012 | 0280 01E0 | 0002 0020 0020 0000 0000 0100 0000 0000 - 125698 | 125e30 | = 640 = 480 - - tmap1 params - 7280 000D | 89F0 000D | 0280 01E0 | 0002 0020 0020 0002 0000 0040 0000 0000 - 0d7280 | 0d89f0 | = 640 = 480 | - - these parameter lists are not read after this? is there some kind of indirect dma mode, or is code not being called that should use them. - plenty more code is called, including more that looks a lot like the above, some use of 707f and at the end of the funciton, code to - write various tilemap registers, including reenabling the tilemap that was disabled around 055098. - - -- - - - if you return rand() on 707f reads sometimes you see - [:maincpu] pc:053775: r4 = r4 lsr r3 (5698 0009) : [:maincpu] result 002b (possible unrelated) - - (bg tile addressing is also done by tile #, like the sprites, not fixed step like smartfp) - - -*/ - #include "emu.h" #include "generalplus_gpl16250soc_video.h" @@ -118,20 +27,15 @@ DEFINE_DEVICE_TYPE(GCM394_VIDEO, gcm394_video_device, "gcm394_video", "GeneralPl gcm394_base_video_device::gcm394_base_video_device(const machine_config &mconfig, device_type type, const char *tag, device_t *owner, uint32_t clock) : device_t(mconfig, type, tag, owner, clock), - //device_gfx_interface(mconfig, *this, nullptr), device_video_interface(mconfig, *this), m_cpu(*this, finder_base::DUMMY_TAG), m_screen(*this, finder_base::DUMMY_TAG), -// m_scrollram(*this, "scrollram"), m_video_irq_cb(*this), m_palette(*this, "palette"), m_gfxdecode(*this, "gfxdecode"), m_space_read_cb(*this), m_rowscroll(*this, "^rowscroll"), m_rowzoom(*this, "^rowzoom"), -// m_pal_displaybank_high(0), -// m_pal_sprites(0x100), -// m_pal_back(0x000), m_alt_extrasprite_hack(0), m_alt_tile_addressing(0), m_renderer(*this, "renderer") @@ -295,17 +199,6 @@ void gcm394_base_video_device::decodegfx(const char* tag) void gcm394_base_video_device::device_start() { - for (uint8_t i = 0; i < 32; i++) - { - m_rgb5_to_rgb8[i] = (i << 3) | (i >> 2); - } - for (uint16_t i = 0; i < 0x8000; i++) - { - m_rgb555_to_rgb888[i] = (m_rgb5_to_rgb8[(i >> 10) & 0x1f] << 16) | - (m_rgb5_to_rgb8[(i >> 5) & 0x1f] << 8) | - (m_rgb5_to_rgb8[(i >> 0) & 0x1f] << 0); - } - m_video_irq_cb.resolve(); m_maxgfxelement = 0; @@ -319,10 +212,6 @@ void gcm394_base_video_device::device_start() m_screenpos_timer = timer_alloc(TIMER_SCREENPOS); m_screenpos_timer->adjust(attotime::never); - - save_item(NAME(m_screenbuf)); - save_item(NAME(m_rgb5_to_rgb8)); - save_item(NAME(m_rgb555_to_rgb888)); save_item(NAME(m_page0_addr_lsb)); save_item(NAME(m_page0_addr_msb)); save_item(NAME(m_page1_addr_lsb)); @@ -365,10 +254,8 @@ void gcm394_base_video_device::device_start() save_item(NAME(m_page3_addr_lsb)); save_item(NAME(m_page3_addr_msb)); save_item(NAME(m_spriteram)); - save_item(NAME(m_spriteextra)); save_item(NAME(m_paletteram)); save_item(NAME(m_maxgfxelement)); -// save_item(NAME(m_pal_displaybank_high)); save_item(NAME(m_alt_tile_addressing)); } @@ -390,16 +277,14 @@ void gcm394_base_video_device::device_reset() m_tmap1_scroll[i] = 0x0000; } - for (int i = 0; i < 0x400; i++) + for (int i = 0; i < 0x400*2; i++) { - m_spriteextra[i] = 0x0000; m_spriteram[i] = 0x0000; } for (int i=0;i<0x100 * 0x10;i++) m_paletteram[i] = machine().rand()&0x7fff; - m_707f = 0x0000; m_703a_palettebank = 0x0000; m_video_irq_enable = 0x0000; @@ -435,546 +320,7 @@ void gcm394_base_video_device::device_reset() m_page3_addr_lsb = 0; m_page3_addr_msb = 0; -} - -/************************* -* Video Hardware * -*************************/ - -template<gcm394_base_video_device::blend_enable_t Blend, gcm394_base_video_device::rowscroll_enable_t RowScroll, gcm394_base_video_device::flipx_t FlipX> -void gcm394_base_video_device::draw(const rectangle &cliprect, uint32_t line, uint32_t xoff, uint32_t yoff, uint32_t bitmap_addr, uint32_t tile, int32_t h, int32_t w, uint8_t bpp, uint32_t yflipmask, uint32_t palette_offset, int addressing_mode) -{ - uint32_t nc_bpp = ((bpp) + 1) << 1; - - // probably don't do this here as this SoC has extended palette for higher bpp modes - //palette_offset >>= nc_bpp; - //palette_offset <<= nc_bpp; - - uint32_t bits_per_row = nc_bpp * w / 16; - uint32_t words_per_tile; - - if (addressing_mode == 1) - { - words_per_tile = bits_per_row * h; - } - else - { - words_per_tile = 8; // seems to be correct for sprites regardless of size / bpp on smartfp - } - - int x_max; - if (m_707f & 0x0010) - { - x_max = 0x400; - } - else - { - x_max = 0x200; - } - - - uint32_t m = (bitmap_addr) + (words_per_tile * tile + bits_per_row * (line ^ yflipmask)); - - - uint32_t bits = 0; - uint32_t nbits = 0; - uint32_t y = line; - - int yy = (yoff + y);// &0x1ff; - //if (yy >= 0x01c0) - // yy -= 0x0200; - - if (yy > cliprect.max_y || yy < 0) - return; - - int y_index = yy * m_screen->width(); - - for (int32_t x = FlipX ? (w - 1) : 0; FlipX ? x >= 0 : x < w; FlipX ? x-- : x++) - { - int xx = xoff + x; - - bits <<= nc_bpp; - - if (nbits < nc_bpp) - { - uint16_t b = m_space_read_cb((m++)&0x7ffffff); // smartfp suggests either 0x7ffffff mask, or some bits are being set incorrectly, jak_s500 needs over 0x3ffffff at least - b = (b << 8) | (b >> 8); - bits |= b << (nc_bpp - nbits); - nbits += 16; - } - nbits -= nc_bpp; - - int pen = bits >> 16; - - int current_palette_offset = palette_offset; - - uint32_t pal = current_palette_offset + pen; - bits &= 0xffff; - - if (RowScroll) - xx -= 0;// (int16_t)m_scrollram[yy & 0x1ff]; - - xx &= (x_max-1); - if (xx >= (x_max-0x40)) - xx -= x_max; - - if (xx >= 0 && xx <= cliprect.max_x) - { - int pix_index = xx + y_index; - - uint16_t rgb = m_paletteram[pal]; - - if (!(rgb & 0x8000)) - { - if (Blend) - { - /* - m_screenbuf[pix_index] = (mix_channel((uint8_t)(m_screenbuf[pix_index] >> 16), m_rgb5_to_rgb8[(rgb >> 10) & 0x1f]) << 16) | - (mix_channel((uint8_t)(m_screenbuf[pix_index] >> 8), m_rgb5_to_rgb8[(rgb >> 5) & 0x1f]) << 8) | - (mix_channel((uint8_t)(m_screenbuf[pix_index] >> 0), m_rgb5_to_rgb8[rgb & 0x1f])); - */ - m_screenbuf[pix_index] = m_rgb555_to_rgb888[rgb]; - } - else - { - m_screenbuf[pix_index] = m_rgb555_to_rgb888[rgb]; - } - } - } - } -} - -void gcm394_base_video_device::draw_page(const rectangle &cliprect, uint32_t scanline, int priority, uint32_t bitmap_addr, uint16_t *regs, uint16_t *scroll, int which) -{ - uint32_t xscroll = scroll[0]; - uint32_t yscroll = scroll[1]; - uint32_t attr_reg = regs[0]; - uint32_t ctrl_reg = regs[1]; - uint32_t tilemap = regs[2]; - uint32_t palette_map = regs[3]; - address_space &space = m_cpu->space(AS_PROGRAM); - - // attr_reg bits - // -Bzz pppp hhww ffbb - // - // B = blend - // zz = depth - // pppp = palette - // ff = flips - // bb = bpp - // hh = height - // ww = width - - // ctrl_reg bits - // ---- ---B h--r ewRl - // - // e = enable - // l = bitmape/line mode - // r = rowscroll - // w = wallpaper mode - // R = regset mode - // h = high colour - // B = blend - - - if (!(ctrl_reg & 0x0008)) - { - return; - } - - if (((attr_reg & 0x3000) >> 12) != priority) - { - return; - } - - if (ctrl_reg & 0x0001) // bitmap mode jak_car2 and jak_s500 use for the ingame race sections, also have a bitmap test in test mode - { - if (0) - { - if (ctrl_reg & 0x0010) - popmessage("bitmap mode %08x with rowscroll\n", bitmap_addr); - else - popmessage("bitmap mode %08x\n", bitmap_addr); - } - - // note, in interlace modes it appears every other line is unused? (480 entry table, but with blank values) - // and furthermore the rowscroll and rowzoom tables only have 240 entries, not enough for every line - // the end of the rowscroll table (entries 240-255) contain something else, maybe garbage data as it's offscreen, maybe not - - uint32_t linebase = space.read_word(tilemap + scanline); // every other word is unused, but there are only enough entries for 240 lines then, sometimes to do with interlace mode? - uint16_t palette = space.read_word(palette_map + (scanline / 2)); - - if (scanline & 1) - palette >>= 8; - else - palette &= 0xff; - - if (!linebase) - return; - - linebase = linebase | (palette << 16); - - // this logic works for jak_s500 and the test modes to get the correct base, doesn't seem to work for jak_car2 ingame, maybe data is copied to wrong place? - int gfxbase = (bitmap_addr&0x7ffffff) + (linebase&0x7ffffff); - - for (int i = 0; i < 160; i++) // will have to be 320 for jak_car2 ingame, jak_s500 lines are wider than screen, and zoomed - { - uint16_t pix = m_space_read_cb((gfxbase++)&0x7ffffff); - int xx; - int y_index = scanline * m_screen->width(); - uint16_t pal; - - if ((scanline >= 0) && (scanline < 480)) - { - xx = i * 2; - - pal = (pix & 0xff) | 0x100; - - if (xx >= 0 && xx <= cliprect.max_x) - { - int pix_index = xx + y_index; - - uint16_t rgb = m_paletteram[pal]; - - if (!(rgb & 0x8000)) - { - m_screenbuf[pix_index] = m_rgb555_to_rgb888[rgb]; - } - } - - xx = (i * 2)+1; - pal = (pix >> 8) + 0x100; - - if (xx >= 0 && xx <= cliprect.max_x) - { - int pix_index = xx + y_index; - - uint16_t rgb = m_paletteram[pal]; - - if (!(rgb & 0x8000)) - { - m_screenbuf[pix_index] = m_rgb555_to_rgb888[rgb]; - } - } - } - } - } - else - { - uint32_t tile_h = 8 << ((attr_reg & 0x00c0) >> 6); - uint32_t tile_w = 8 << ((attr_reg & 0x0030) >> 4); - - int total_width; - int use_alt_drawmode = m_alt_tile_addressing; - int y_mask = 0; - - // just a guess based on this being set on the higher resolution tilemaps we've seen, could be 100% incorrect register - if ((attr_reg >> 15) & 0x1) - { - total_width = 1024; - y_mask = 0x1ff; - // use_alt_drawmode = 1; // probably doesn't control this - } - else - { - total_width = 512; - y_mask = 0xff; - // use_alt_drawmode = 0; // probably doesn't control this - } - - uint32_t tile_count_x = total_width / tile_w; - - uint32_t bitmap_y = (scanline + yscroll) & y_mask; - uint32_t y0 = bitmap_y / tile_h; - uint32_t tile_scanline = bitmap_y % tile_h; - uint32_t tile_address = tile_count_x * y0; - - for (uint32_t x0 = 0; x0 < tile_count_x; x0++, tile_address++) - { - uint32_t yy = ((tile_h * y0 - yscroll + 0x10) & y_mask) - 0x10; - uint32_t xx = (tile_w * x0 - xscroll) & (total_width-1); - uint32_t tile = (ctrl_reg & 0x0004) ? space.read_word(tilemap) : space.read_word(tilemap + tile_address); - - if (!tile) - continue; - - bool blend; - bool row_scroll; - bool flip_x; - uint32_t yflipmask; - uint32_t palette_offset; - - blend = (attr_reg & 0x4000 || ctrl_reg & 0x0100); - row_scroll = (ctrl_reg & 0x0010); - - if ((ctrl_reg & 0x0002) == 0) // RegSet:0 - { - uint16_t palette = (ctrl_reg & 0x0004) ? space.read_word(palette_map) : space.read_word(palette_map + tile_address / 2); - if (x0 & 1) - palette >>= 8; - - // 'palette' format - // --ff pppp - // - // f = flip bits - // p = palette - - flip_x = palette & 0x10; - yflipmask = (palette & 0x20) ? tile_h - 1 : 0; - palette_offset = (palette & 0x0f) << 4; - } - else // RegSet:1 - { - if (m_alt_tile_addressing == 0) - { - // smartfp needs the attribute table to contain extra tile bits even if regset is 1 - uint16_t palette = (ctrl_reg & 0x0004) ? space.read_word(palette_map) : space.read_word(palette_map + tile_address / 2); - if (x0 & 1) - palette >>= 8; - - // 'palette' format - // -- -ttt - // - // t = extra tile number bits - - tile |= (palette & 0x0007) << 16; - } - - flip_x = (attr_reg & 0x0004); - yflipmask = attr_reg & 0x0008 ? tile_h - 1 : 0; - palette_offset = (attr_reg & 0x0f00) >> 4; - } - - const uint8_t bpp = attr_reg & 0x0003; - - // HACKS - // There must be a select bit for the tilemap palettes somewhere, but where?! - - // the different games in paccon also expect a variety of different configs here, maybe a good place to look - - if (m_703a_palettebank & 1) // this actually seems to be the sprite palette bank enable, but for tkmag220 it gives us an easy way to ignore the logic below - { - if (which == 0) // tilemap 0 - { - if (ctrl_reg & 0x0002) // RegSet:1 - { - // smartfp has a conflict between the bootlogos and the first screen, it's in regset mode, no obvious difference in registers but needs palette from different places? - // not even m_707f changes here, which makes the m_707f case specific hacks for jak_s500 below very unlikely to actually be related - if ((bpp + 1) * 2 == 4) - if (m_alt_tile_addressing == 0) - palette_offset |= 0x200; - } - } - - if (which == 1) - { - // can't do this for jak_s500 logos - // jak_s500 also uses this tilemap in both 4 and 6bpp modes expecting the same palette base, so the hack used for smartfp on tilemap 0 is not applicable here - - // m_707f != 0x2d3 for jak_S500 main menu - if ((m_707f != 0x53) && (m_707f != 0x63) && (m_707f != 0x2d3)) - palette_offset |= 0x200; - } - - // jak_car2 screen transitions use layers 2 and 3 the same way, alternating each frame - if (which == 2) - { - // jak_s500 title screen + loading screen before race - if ((m_707f == 0x2d3) || (m_707f == 0x2db)) - palette_offset |= 0x200; - } - - } - //palette_offset |= m_pal_back; - - if (blend) - { - if (row_scroll) - { - if (flip_x) - draw<BlendOn, RowScrollOn, FlipXOn>(cliprect, tile_scanline, xx, yy, bitmap_addr, tile, tile_h, tile_w, bpp, yflipmask, palette_offset, use_alt_drawmode); - else - draw<BlendOn, RowScrollOn, FlipXOff>(cliprect, tile_scanline, xx, yy, bitmap_addr, tile, tile_h, tile_w, bpp, yflipmask, palette_offset, use_alt_drawmode); - } - else - { - if (flip_x) - draw<BlendOn, RowScrollOff, FlipXOn>(cliprect, tile_scanline, xx, yy, bitmap_addr, tile, tile_h, tile_w, bpp, yflipmask, palette_offset, use_alt_drawmode); - else - draw<BlendOn, RowScrollOff, FlipXOff>(cliprect, tile_scanline, xx, yy, bitmap_addr, tile, tile_h, tile_w, bpp, yflipmask, palette_offset, use_alt_drawmode); - } - } - else - { - if (row_scroll) - { - if (flip_x) - draw<BlendOff, RowScrollOn, FlipXOn>(cliprect, tile_scanline, xx, yy, bitmap_addr, tile, tile_h, tile_w, bpp, yflipmask, palette_offset, use_alt_drawmode); - else - draw<BlendOff, RowScrollOn, FlipXOff>(cliprect, tile_scanline, xx, yy, bitmap_addr, tile, tile_h, tile_w, bpp, yflipmask, palette_offset, use_alt_drawmode); - } - else - { - if (flip_x) - draw<BlendOff, RowScrollOff, FlipXOn>(cliprect, tile_scanline, xx, yy, bitmap_addr, tile, tile_h, tile_w, bpp, yflipmask, palette_offset, use_alt_drawmode); - else - draw<BlendOff, RowScrollOff, FlipXOff>(cliprect, tile_scanline, xx, yy, bitmap_addr, tile, tile_h, tile_w, bpp, yflipmask, palette_offset, use_alt_drawmode); - } - } - } - } -} - - -void gcm394_base_video_device::draw_sprite(const rectangle& cliprect, uint32_t scanline, int priority, uint32_t base_addr) -{ - uint32_t bitmap_addr = (m_sprite_702d_gfxbase_msb << 16) | m_sprite_7022_gfxbase_lsb; - uint32_t tile = m_spriteram[base_addr + 0]; - int16_t x = m_spriteram[base_addr + 1]; - int16_t y = m_spriteram[base_addr + 2]; - uint16_t attr = m_spriteram[base_addr + 3]; - - - if (!tile) // this check needs to come before the additional attribute bits are added in? (smartfp title) - { - return; - } - - int addressing_mode = 0; - - int screenwidth, screenheight, x_max; - if (m_707f & 0x0010) - { - screenwidth = 640; - screenheight = 480; - x_max = 0x400; - } - else - { - screenwidth = 320; - screenheight = 240; - x_max = 0x200; - } - - - // good for gormiti, smartfp, wrlshunt, paccon, jak_totm, jak_s500, jak_gtg - if ((m_7042_sprite & 0x0010) == 0x10) - addressing_mode = 0; // smartfp, paccon - else - addressing_mode = 1; - - if (m_alt_extrasprite_hack == 0) - if (addressing_mode == 0) // smartfp, paccon - tile |= m_spriteextra[base_addr / 4] << 16; - - if (m_alt_extrasprite_hack == 1) // jak_prft - tile |= (m_spriteextra[base_addr] & 0x000f) << 16; - - if (((attr & 0x3000) >> 12) != priority) - { - return; - } - - // attr PBzz pppp hhww ffdd - - // P = high palette bit - // b = blend enable - // zz = priority - // pppp = palette - // hh = height - // ww = width - // ff = flips - // dd = depth - - const uint32_t h = 8 << ((attr & 0x00c0) >> 6); - const uint32_t w = 8 << ((attr & 0x0030) >> 4); - - - if (!(m_7042_sprite & 0x0002)) - { - x = ((screenwidth / 2) + x) - w / 2; - y = ((screenheight / 2) - y) - (h / 2) + 8; - } - - x &= (x_max - 1); - y &= 0x01ff; - - uint32_t tile_line = ((scanline - y) + 0x200) % h; - int16_t test_y = (y + tile_line) & 0x1ff; - if (test_y >= 0x01c0) - test_y -= 0x0200; - - if (test_y != scanline) - { - return; - } - - bool blend = (attr & 0x4000); - - bool flip_x; - uint8_t bpp; - uint32_t yflipmask; - uint32_t palette_offset; - - // different attribute use? - if (screenwidth == 320) - { - if (m_alt_extrasprite_hack == 0) - { - flip_x = (attr & 0x0004); - yflipmask = attr & 0x0008 ? h - 1 : 0; - } - else - { - flip_x = 0; - yflipmask = 0; - } - - bpp = attr & 0x0003; - palette_offset = (attr & 0x0f00) >> 4; - } - else - { - flip_x = 0;// (attr & 0x0004); - yflipmask = 0;// attr& 0x0008 ? h - 1 : 0; - - bpp = attr & 0x0003; - palette_offset = (attr & 0x0f00) >> 4; - } - - if (m_703a_palettebank & 1) - palette_offset |= 0x100; - - if (attr & 0x8000) - palette_offset |= 0x200; - - if (blend) - { - if (flip_x) - draw<BlendOn, RowScrollOff, FlipXOn>(cliprect, tile_line, x, y, bitmap_addr, tile, h, w, bpp, yflipmask, palette_offset, addressing_mode); - else - draw<BlendOn, RowScrollOff, FlipXOff>(cliprect, tile_line, x, y, bitmap_addr, tile, h, w, bpp, yflipmask, palette_offset, addressing_mode); - } - else - { - if (flip_x) - draw<BlendOff, RowScrollOff, FlipXOn>(cliprect, tile_line, x, y, bitmap_addr, tile, h, w, bpp, yflipmask, palette_offset, addressing_mode); - else - draw<BlendOff, RowScrollOff, FlipXOff>(cliprect, tile_line, x, y, bitmap_addr, tile, h, w, bpp, yflipmask, palette_offset, addressing_mode); - } -} - -void gcm394_base_video_device::draw_sprites(const rectangle &cliprect, uint32_t scanline, int priority) -{ - // paccon suggests this, does older hardware have similar? - int numsprites = (m_7042_sprite & 0xff00) >> 8; - if (numsprites == 0) - numsprites = 0x100; - - for (uint32_t n = 0; n < numsprites; n++) - { - draw_sprite(cliprect, scanline, priority, 4 * n); - } + m_renderer->set_video_spaces(m_cpuspace, m_cs_space, m_csbase); } uint32_t gcm394_base_video_device::screen_update(screen_device &screen, bitmap_rgb32 &bitmap, const rectangle &cliprect) @@ -1021,48 +367,45 @@ uint32_t gcm394_base_video_device::screen_update(screen_device &screen, bitmap_r } //const uint16_t bgcol = 0x7c1f; // magenta - const uint16_t bgcol = 0x0000; // black - - +// const uint16_t bgcol = 0x0000; // black + bool highres; if (m_707f & 0x0010) { + highres = true; m_screen->set_visible_area(0, 640-1, 0, 480-1); } else { + highres = false; m_screen->set_visible_area(0, 320-1, 0, 240-1); } + address_space &mem = m_cpu->space(AS_PROGRAM); + + const uint32_t page0_addr = (m_page0_addr_msb << 16) | m_page0_addr_lsb; + const uint32_t page1_addr = (m_page1_addr_msb << 16) | m_page1_addr_lsb; + const uint32_t page2_addr = (m_page2_addr_msb << 16) | m_page2_addr_lsb; + const uint32_t page3_addr = (m_page3_addr_msb << 16) | m_page3_addr_lsb; + + const uint32_t sprites_addr = (m_sprite_702d_gfxbase_msb << 16) | m_sprite_7022_gfxbase_lsb; + + bitmap.fill(0, cliprect); + for (uint32_t scanline = (uint32_t)cliprect.min_y; scanline <= (uint32_t)cliprect.max_y; scanline++) { - uint32_t* bufferline = &m_screenbuf[scanline * m_screen->width()]; - - for (int x = 0; x < m_screen->width(); x++) - { - bufferline[x] = m_rgb555_to_rgb888[bgcol]; - } + uint32_t* dst = &bitmap.pix32(scanline, cliprect.min_x); for (int i = 0; i < 4; i++) { - const int draw_all = 1; - - if (1) - { - if ((!(machine().input().code_pressed(KEYCODE_Q))) || draw_all) draw_page(cliprect, scanline, i, (m_page0_addr_lsb | (m_page0_addr_msb<<16)), m_tmap0_regs, m_tmap0_scroll, 0); - if ((!(machine().input().code_pressed(KEYCODE_W))) || draw_all) draw_page(cliprect, scanline, i, (m_page1_addr_lsb | (m_page1_addr_msb<<16)), m_tmap1_regs, m_tmap1_scroll, 1); - if ((!(machine().input().code_pressed(KEYCODE_E))) || draw_all) draw_page(cliprect, scanline, i, (m_page2_addr_lsb | (m_page2_addr_msb<<16)), m_tmap2_regs, m_tmap2_scroll, 2); - if ((!(machine().input().code_pressed(KEYCODE_R))) || draw_all) draw_page(cliprect, scanline, i, (m_page3_addr_lsb | (m_page3_addr_msb<<16)), m_tmap3_regs, m_tmap3_scroll, 3); + m_renderer->draw_page(true, true, m_alt_tile_addressing ? false : true, m_703a_palettebank, cliprect, dst, scanline, i, page0_addr, m_tmap0_scroll, m_tmap0_regs, mem, m_paletteram, m_rowscroll, 0); + m_renderer->draw_page(true, true, m_alt_tile_addressing ? false : true, m_703a_palettebank, cliprect, dst, scanline, i, page1_addr, m_tmap1_scroll, m_tmap1_regs, mem, m_paletteram, m_rowscroll, 1); + m_renderer->draw_page(true, true, m_alt_tile_addressing ? false : true, m_703a_palettebank, cliprect, dst, scanline, i, page2_addr, m_tmap2_scroll, m_tmap2_regs, mem, m_paletteram, m_rowscroll, 2); + m_renderer->draw_page(true, true, m_alt_tile_addressing ? false : true, m_703a_palettebank, cliprect, dst, scanline, i, page3_addr, m_tmap3_scroll, m_tmap3_regs, mem, m_paletteram, m_rowscroll, 3); - } - if ((!(machine().input().code_pressed(KEYCODE_T))) || draw_all) draw_sprites(cliprect, scanline, i); + m_renderer->draw_sprites(true, true, m_alt_extrasprite_hack ? true : false, m_703a_palettebank, highres, cliprect, dst, scanline, i, sprites_addr, mem, m_paletteram, m_spriteram, -1); } - } - for (int y = cliprect.min_y; y <= cliprect.max_y; y++) - { - uint32_t *dest = &bitmap.pix32(y, cliprect.min_x); - uint32_t *src = &m_screenbuf[cliprect.min_x + m_screen->width() * y]; - memcpy(dest, src, sizeof(uint32_t) * ((cliprect.max_x - cliprect.min_x) + 1)); + m_renderer->apply_saturation_and_fade(bitmap, cliprect, scanline); } return 0; @@ -1391,6 +734,8 @@ WRITE16_MEMBER(gcm394_base_video_device::sprite_7042_extra_w) { LOGMASKED(LOG_GCM394_VIDEO, "%s:gcm394_base_video_device::sprite_7042_extra_w %04x\n", machine().describe_context(), data); m_7042_sprite = data; + m_renderer->set_video_reg_42(data); + //popmessage("extra modes %04x\n", data); } @@ -1470,7 +815,7 @@ READ16_MEMBER(gcm394_base_video_device::video_707c_r) READ16_MEMBER(gcm394_base_video_device::video_707f_r) { - uint16_t retdata = m_707f; + uint16_t retdata = m_renderer->get_video_reg_7f(); LOGMASKED(LOG_GCM394_VIDEO, "%s:gcm394_base_video_device::video_707f_r (returning %04x)\n", machine().describe_context(), retdata); return retdata; } @@ -1496,7 +841,7 @@ WRITE16_MEMBER(gcm394_base_video_device::video_707f_w) } m_707f = data; - + m_renderer->set_video_reg_7f(data); //popmessage("707f is %04x\n", data); } @@ -1558,6 +903,7 @@ WRITE16_MEMBER(gcm394_base_video_device::video_702a_w) { LOGMASKED(LOG_GCM394_VIDEO, "%s:gcm394_base_video_device::video_702a_w %04x\n", machine().describe_context(), data); m_702a = data; + m_renderer->set_video_reg_2a(data); } READ16_MEMBER(gcm394_base_video_device::video_curline_r) @@ -1582,15 +928,17 @@ WRITE16_MEMBER(gcm394_base_video_device::video_7030_brightness_w) { LOGMASKED(LOG_GCM394_VIDEO, "%s:gcm394_base_video_device::video_7030_brightness_w %04x\n", machine().describe_context(), data); m_7030_brightness = data; + m_renderer->set_video_reg_30(data); } void gcm394_base_video_device::update_raster_split_position() { // this might need updating to handle higher res modes LOGMASKED(LOG_GCM394_VIDEO, "update_raster_split_position: %04x,%04x\n", m_yirqpos, m_xirqpos); - if (m_xirqpos < 300 && m_yirqpos < 240) + if (m_xirqpos < 300 && m_yirqpos < 256) { - m_screenpos_timer->adjust(m_screen->time_until_pos(m_yirqpos, m_xirqpos)); + // where does -19 come from? needed for raster on paccon xevious to fire at correct line for bg scrolling to be seamless + m_screenpos_timer->adjust(m_screen->time_until_pos(m_yirqpos-19, m_xirqpos)); //printf("setting irq timer for y:%d x:%d", m_yirqpos, m_xirqpos); } else @@ -1623,6 +971,7 @@ WRITE16_MEMBER(gcm394_base_video_device::video_703c_tvcontrol1_w) { LOGMASKED(LOG_GCM394_VIDEO, "%s:gcm394_base_video_device::video_703c_tvcontrol1_w %04x\n", machine().describe_context(), data); m_703c_tvcontrol1 = data; + m_renderer->set_video_reg_3c(data); } READ16_MEMBER(gcm394_base_video_device::video_7051_r) @@ -1668,7 +1017,7 @@ WRITE16_MEMBER(gcm394_base_video_device::spriteram_w) } else if (m_707e_spritebank == 0x0001) { - m_spriteextra[offset] = data; + m_spriteram[offset + 0x400] = data; } else { @@ -1684,7 +1033,7 @@ READ16_MEMBER(gcm394_base_video_device::spriteram_r) } else if (m_707e_spritebank == 0x0001) { - return m_spriteextra[offset]; + return m_spriteram[offset + 0x400]; } else { @@ -1705,13 +1054,9 @@ WRITE16_MEMBER(gcm394_base_video_device::palette_w) { offset |= (m_703a_palettebank & 0x000c) << 6; m_paletteram[offset] = data; - - uint32_t pal = m_rgb555_to_rgb888[data & 0x7fff]; - int r = (pal >> 16) & 0xff; - int g = (pal >> 8) & 0xff; - int b = (pal >> 0) & 0xff; - - m_palette->set_pen_color(offset, rgb_t(r, g, b)); + + // for debug + m_palette->set_pen_color(offset, rgb_t((((data >> 15) & 0x1f)<<3), (((data >> 10) & 0x1f)<<3), (((data >> 0) & 0x1f)<<3))); } } @@ -1731,16 +1076,19 @@ READ16_MEMBER(gcm394_base_video_device::palette_r) WRITE16_MEMBER(gcm394_base_video_device::video_701c_w) { LOGMASKED(LOG_GCM394_VIDEO, "%s:gcm394_base_video_device::video_701c_w (unknown video reg?) %04x\n", machine().describe_context(), data); + m_renderer->set_video_reg_1c(data); } WRITE16_MEMBER(gcm394_base_video_device::video_701d_w) { LOGMASKED(LOG_GCM394_VIDEO, "%s:gcm394_base_video_device::video_701d_w (unknown video reg?) %04x\n", machine().describe_context(), data); + m_renderer->set_video_reg_1d(data); } WRITE16_MEMBER(gcm394_base_video_device::video_701e_w) { LOGMASKED(LOG_GCM394_VIDEO, "%s:gcm394_base_video_device::video_701e_w (unknown video reg?) %04x\n", machine().describe_context(), data); + m_renderer->set_video_reg_1e(data); } @@ -1787,7 +1135,7 @@ void gcm394_base_video_device::device_timer(emu_timer &timer, device_timer_id id m_screen->update_partial(m_screen->vpos()); // fire again, jak_dbz pinball needs this - m_screenpos_timer->adjust(m_screen->time_until_pos(m_yirqpos, m_xirqpos)); + m_screenpos_timer->adjust(m_screen->time_until_pos(m_yirqpos-19, m_xirqpos)); break; } } |