summaryrefslogtreecommitdiffstatshomepage
path: root/src/devices/video/315_5313.cpp
diff options
context:
space:
mode:
author cam900 <dbtlrchl@naver.com>2019-10-24 12:08:02 +0900
committer cam900 <dbtlrchl@naver.com>2019-10-24 12:08:02 +0900
commitc1459feacc7566a6a4d91ffb4426cdc4c16bb38f (patch)
treee78b1de4a89b38ebaf58a1e283664f96d835dfcd /src/devices/video/315_5313.cpp
parentda07c8901b7aab5bfabe8f9c67af83515f87c465 (diff)
315_5313.cpp : Allow LCM scaling of horizontal resolution
megaplay.cpp : Use LCM of support horizontal resolution in both VDPs 315_5124.cpp : Allow dividing hcounter related to using LCM
Diffstat (limited to 'src/devices/video/315_5313.cpp')
-rw-r--r--src/devices/video/315_5313.cpp98
1 files changed, 58 insertions, 40 deletions
diff --git a/src/devices/video/315_5313.cpp b/src/devices/video/315_5313.cpp
index d664909bfae..397fcb436bd 100644
--- a/src/devices/video/315_5313.cpp
+++ b/src/devices/video/315_5313.cpp
@@ -153,6 +153,12 @@ static constexpr u8 line_315_5313_mode4[8] = {
, 37 /* SPRCOL_BASEHPOS */
};
+static const unsigned hres[4] = { 256, 256, 320, 320 };
+static const unsigned hres_mul[4] = { 5, 5, 4, 4 };
+
+inline u8 sega315_5313_device::get_hres() { return (MEGADRIVE_REG0C_RS0 | (MEGADRIVE_REG0C_RS1 << 1)) & 3; }
+int sega315_5313_device::screen_hpos() { return screen().hpos() / (m_lcm_scaling ? hres_mul[get_hres()] : 1); }
+
#define MAX_HPOSITION 480
@@ -184,6 +190,7 @@ sega315_5313_device::sega315_5313_device(const machine_config &mconfig, const ch
, m_scanline_counter(0)
, m_vblank_flag(0)
, m_imode(0)
+ , m_lcm_scaling(false)
, m_visible_scanlines(0)
, m_irq6_scanline(0)
, m_z80irq_scanline(0)
@@ -334,9 +341,9 @@ void sega315_5313_device::device_start()
memset(m_palette_lookup.get(), 0x00, 0x40 * 2);
if (!m_use_alt_timing)
- m_render_bitmap = std::make_unique<bitmap_rgb32>(320, 512); // allocate maximum sizes we're going to use, it's safer.
+ m_render_bitmap = std::make_unique<bitmap_rgb32>(1280, 512); // allocate maximum sizes we're going to use, it's safer.
else
- m_render_line = std::make_unique<u32[]>(320);
+ m_render_line = std::make_unique<u32[]>(1280);
m_render_line_raw = std::make_unique<u16[]>(320);
@@ -348,7 +355,7 @@ void sega315_5313_device::device_start()
save_pointer(NAME(m_palette_lookup), 0x40);
save_pointer(NAME(m_render_line_raw), 320);
if (m_use_alt_timing)
- save_pointer(NAME(m_render_line), 320);
+ save_pointer(NAME(m_render_line), 1280);
m_irq6_on_timer = machine().scheduler().timer_alloc(timer_expired_delegate(FUNC(sega315_5313_device::irq6_on_timer_callback), this));
m_irq4_on_timer = machine().scheduler().timer_alloc(timer_expired_delegate(FUNC(sega315_5313_device::irq4_on_timer_callback), this));
@@ -1234,7 +1241,7 @@ u16 sega315_5313_device::get_hposition()
}
else
{
- value4 = screen().hpos();
+ value4 = screen_hpos();
}
return value4;
@@ -1378,7 +1385,7 @@ void sega315_5313_device::render_spriteline_to_spritebuffer(int scanline)
int maxpixels = 0;
u16 base_address = 0;
- const int screenwidth = MEGADRIVE_REG0C_RS0 | (MEGADRIVE_REG0C_RS1 << 1);
+ const int screenwidth = get_hres();
switch (screenwidth & 3)
{
@@ -1654,14 +1661,15 @@ void sega315_5313_device::render_videoline_to_videobuffer(int scanline)
int non_window_lastcol;
const int screenheight = MEGADRIVE_REG01_240_LINE ? 240 : 224;
struct nametable_t tile;
+ unsigned horz = m_lcm_scaling ? hres[get_hres()] : 320;
/* Clear our Render Buffer */
- for (int x = 0; x < 320; x++)
+ for (int x = 0; x < horz; x++)
{
m_video_renderline[x] = MEGADRIVE_REG07_BGCOLOUR | 0x20000; // mark as BG
}
- memset(m_highpri_renderline.get(), 0, 320);
+ memset(m_highpri_renderline.get(), 0, horz);
/* is this line enabled? */
if (!MEGADRIVE_REG01_DISP_ENABLE)
@@ -1684,7 +1692,7 @@ void sega315_5313_device::render_videoline_to_videobuffer(int scanline)
const u16 window_down = MEGADRIVE_REG12_WINDOW_DOWN;
// const u16 window_vpos = MEGADRIVE_REG12_WINDOW_VPOS;
- const int screenwidth = MEGADRIVE_REG0C_RS0 | (MEGADRIVE_REG0C_RS1 << 1);
+ const int screenwidth = get_hres();
switch (screenwidth)
{
@@ -1977,7 +1985,7 @@ void sega315_5313_device::render_videoline_to_videobuffer(int scanline)
/* MEGADRIVE_REG0C_SHADOW_HIGLIGHT */
/* Low Priority Sprites */
- for (int x = 0; x < 320; x++)
+ for (int x = 0; x < horz; x++)
{
if (!MEGADRIVE_REG0C_SHADOW_HIGLIGHT)
{
@@ -2020,7 +2028,7 @@ void sega315_5313_device::render_videoline_to_videobuffer(int scanline)
}
/* High Priority A+B Tiles */
- for (int x = 0; x < 320; x++)
+ for (int x = 0; x < horz; x++)
{
if (!MEGADRIVE_REG0C_SHADOW_HIGLIGHT)
{
@@ -2046,7 +2054,7 @@ void sega315_5313_device::render_videoline_to_videobuffer(int scanline)
}
/* High Priority Sprites */
- for (int x = 0; x < 320; x++)
+ for (int x = 0; x < horz; x++)
{
if (!MEGADRIVE_REG0C_SHADOW_HIGLIGHT)
{
@@ -2089,6 +2097,8 @@ void sega315_5313_device::render_videobuffer_to_screenbuffer(int scanline)
{
const unsigned palette_per_scanline = scanline * 64;
u32 *lineptr;
+ unsigned horz = m_lcm_scaling ? hres[get_hres()] : 320;
+ unsigned mul = m_lcm_scaling ? hres_mul[get_hres()] : 1;
if (!m_use_alt_timing)
{
@@ -2114,27 +2124,27 @@ void sega315_5313_device::render_videobuffer_to_screenbuffer(int scanline)
}
}
- for (int x = 0; x < 320; x++)
+ for (int srcx = 0, xx = 0, dstx = 0; srcx < horz; dstx++)
{
- const u32 dat = m_video_renderline[x];
+ const u32 dat = m_video_renderline[srcx];
const u16 clut = (dat & 0x3f) + palette_per_scanline;
if (!(dat & 0x20000))
- m_render_line_raw[x] = 0x100;
+ m_render_line_raw[srcx] = 0x100;
else
- m_render_line_raw[x] = 0x000;
+ m_render_line_raw[srcx] = 0x000;
if (!MEGADRIVE_REG0C_SHADOW_HIGLIGHT)
{
if (dat & 0x10000)
{
- lineptr[x] = m_gfx_palette->pen(clut);
- m_render_line_raw[x] |= (dat & 0x3f) | 0x080;
+ lineptr[dstx] = m_gfx_palette->pen(clut);
+ m_render_line_raw[srcx] |= (dat & 0x3f) | 0x080;
}
else
{
- lineptr[x] = m_gfx_palette->pen(clut);
- m_render_line_raw[x] |= (dat & 0x3f) | 0x040;
+ lineptr[dstx] = m_gfx_palette->pen(clut);
+ m_render_line_raw[srcx] |= (dat & 0x3f) | 0x040;
}
}
else
@@ -2148,26 +2158,26 @@ void sega315_5313_device::render_videobuffer_to_screenbuffer(int scanline)
case 0x10000: // (sprite) low priority, no shadow sprite, no highlight = shadow
case 0x12000: // (sprite) low priority, shadow sprite, no highlight = shadow
case 0x16000: // (sprite) normal pri, shadow sprite, no highlight = shadow?
- lineptr[x] = m_gfx_palette_shadow->pen(clut);
- m_render_line_raw[x] |= (dat & 0x3f) | 0x000;
+ lineptr[dstx] = m_gfx_palette_shadow->pen(clut);
+ m_render_line_raw[srcx] |= (dat & 0x3f) | 0x000;
break;
case 0x4000: // normal pri, no shadow sprite, no highlight = normal;
case 0x8000: // low pri, highlight sprite = normal;
- lineptr[x] = m_gfx_palette->pen(clut);
- m_render_line_raw[x] |= (dat & 0x3f) | 0x040;
+ lineptr[dstx] = m_gfx_palette->pen(clut);
+ m_render_line_raw[srcx] |= (dat & 0x3f) | 0x040;
break;
case 0x14000: // (sprite) normal pri, no shadow sprite, no highlight = normal;
case 0x18000: // (sprite) low pri, highlight sprite = normal;
- lineptr[x] = m_gfx_palette->pen(clut);
- m_render_line_raw[x] |= (dat & 0x3f) | 0x080;
+ lineptr[dstx] = m_gfx_palette->pen(clut);
+ m_render_line_raw[srcx] |= (dat & 0x3f) | 0x080;
break;
case 0x0c000: // normal pri, highlight set = highlight?
case 0x1c000: // (sprite) normal pri, highlight set = highlight?
- lineptr[x] = m_gfx_palette_hilight->pen(clut);
- m_render_line_raw[x] |= (dat & 0x3f) | 0x0c0;
+ lineptr[dstx] = m_gfx_palette_hilight->pen(clut);
+ m_render_line_raw[srcx] |= (dat & 0x3f) | 0x0c0;
break;
case 0x0a000: // shadow set, highlight set - not possible
@@ -2175,18 +2185,30 @@ void sega315_5313_device::render_videobuffer_to_screenbuffer(int scanline)
case 0x1a000: // (sprite)shadow set, highlight set - not possible
case 0x1e000: // (sprite)shadow set, highlight set, normal set, not possible
default:
- lineptr[x] = m_render_line_raw[x] |= (machine().rand() & 0x3f);
+ lineptr[dstx] = m_render_line_raw[srcx] |= (machine().rand() & 0x3f);
break;
}
}
+ if (++xx >= mul)
+ {
+ srcx++;
+ xx = 0;
+ }
}
if (!m_32x_scanline_helper_func.isnull())
m_32x_scanline_helper_func(scanline);
if (!m_32x_scanline_func.isnull())
{
- for (int x = 0; x < 320; x++)
- m_32x_scanline_func(x, m_video_renderline[x] & 0x20000, lineptr[x]);
+ for (int srcx = 0, xx = 0, dstx = 0; srcx < horz; dstx++)
+ {
+ m_32x_scanline_func(srcx, m_video_renderline[srcx] & 0x20000, lineptr[dstx]);
+ if (++xx >= mul)
+ {
+ srcx++;
+ xx = 0;
+ }
+ }
}
}
@@ -2280,6 +2302,7 @@ void sega315_5313_device::vdp_handle_eof()
{
rectangle visarea;
int scr_width = 320;
+ int scr_mul = 1;
m_vblank_flag = 0;
//m_irq6_pending = 0; /* NO! (breaks warlock) */
@@ -2315,19 +2338,14 @@ void sega315_5313_device::vdp_handle_eof()
m_z80irq_scanline <<= 1;
}
- switch (MEGADRIVE_REG0C_RS0 | (MEGADRIVE_REG0C_RS1 << 1))
- {
- /* note, add 240 mode + init new timings! */
- case 0: scr_width = 256; break;
- case 1: scr_width = 256; break;
- case 2: scr_width = 320; break;
- case 3: scr_width = 320; break;
- }
+ /* note, add 240 mode + init new timings! */
+ scr_mul = m_lcm_scaling ? hres_mul[get_hres()] : 1;
+ scr_width = hres[get_hres()] * scr_mul;
// osd_printf_debug("my mode %02x", m_regs[0x0c]);
visarea.set(0, scr_width - 1, 0, m_visible_scanlines - 1);
- screen().configure(480, m_total_scanlines, visarea, screen().frame_period().attoseconds());
+ screen().configure(480 * scr_mul, m_total_scanlines, visarea, screen().frame_period().attoseconds());
}
@@ -2353,7 +2371,7 @@ TIMER_DEVICE_CALLBACK_MEMBER(sega315_5313_device::megadriv_scanline_timer_callba
{
if (param == 0)
{
- //printf("where are we? %d %d\n", screen().vpos(), screen().hpos());
+ //printf("where are we? %d %d\n", screen().vpos(), screen_hpos());
vdp_handle_eof();
//vdp_clear_bitmap();
}