summaryrefslogtreecommitdiffstatshomepage
path: root/src/devices/machine/generalplus_gpl16250soc_video.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'src/devices/machine/generalplus_gpl16250soc_video.cpp')
-rw-r--r--src/devices/machine/generalplus_gpl16250soc_video.cpp738
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;
}
}