mirror of
https://github.com/RaySollium99/picodrive.git
synced 2025-09-05 15:27:46 -04:00
sms vdp, add zoomed sprites, column vscroll blocking, mode 2 graphics
This commit is contained in:
parent
032c76a3a2
commit
0df7401c02
5 changed files with 360 additions and 95 deletions
|
@ -212,7 +212,7 @@ void PDebugShowPalette(unsigned short *screen, int stride)
|
||||||
|
|
||||||
Pico.m.dirtyPal = 1;
|
Pico.m.dirtyPal = 1;
|
||||||
if (PicoIn.AHW & PAHW_SMS)
|
if (PicoIn.AHW & PAHW_SMS)
|
||||||
PicoDoHighPal555M4();
|
PicoDoHighPal555SMS();
|
||||||
else
|
else
|
||||||
PicoDoHighPal555(1, 0, est);
|
PicoDoHighPal555(1, 0, est);
|
||||||
Pico.m.dirtyPal = 1;
|
Pico.m.dirtyPal = 1;
|
||||||
|
|
|
@ -1988,7 +1988,7 @@ void PicoDrawUpdateHighPal(void)
|
||||||
sh = 0; // no s/h support
|
sh = 0; // no s/h support
|
||||||
|
|
||||||
if (PicoIn.AHW & PAHW_SMS)
|
if (PicoIn.AHW & PAHW_SMS)
|
||||||
PicoDoHighPal555M4();
|
PicoDoHighPal555SMS();
|
||||||
else if (FinalizeLine == FinalizeLine8bit)
|
else if (FinalizeLine == FinalizeLine8bit)
|
||||||
PicoDoHighPal555_8bit(sh, 0, est);
|
PicoDoHighPal555_8bit(sh, 0, est);
|
||||||
else
|
else
|
||||||
|
@ -2027,7 +2027,7 @@ void PicoDrawSetOutFormat(pdso_t which, int use_32x_line_mode)
|
||||||
}
|
}
|
||||||
if (PicoIn.AHW & PAHW_32X)
|
if (PicoIn.AHW & PAHW_32X)
|
||||||
PicoDrawSetOutFormat32x(which, use_32x_line_mode);
|
PicoDrawSetOutFormat32x(which, use_32x_line_mode);
|
||||||
PicoDrawSetOutputMode4(which);
|
PicoDrawSetOutputSMS(which);
|
||||||
rendstatus_old = -1;
|
rendstatus_old = -1;
|
||||||
Pico.m.dirtyPal = 1;
|
Pico.m.dirtyPal = 1;
|
||||||
}
|
}
|
||||||
|
@ -2038,7 +2038,7 @@ void PicoDrawSetOutBufMD(void *dest, int increment)
|
||||||
// kludge for no-copy mode, using ALT_RENDERER layout
|
// kludge for no-copy mode, using ALT_RENDERER layout
|
||||||
PicoDrawSetInternalBuf(dest, increment);
|
PicoDrawSetInternalBuf(dest, increment);
|
||||||
} else if (FinalizeLine == NULL) {
|
} else if (FinalizeLine == NULL) {
|
||||||
PicoDrawSetInternalBuf(dest, increment); // needed for Mode4
|
PicoDrawSetInternalBuf(dest, increment); // needed for SMS
|
||||||
PicoDraw2SetOutBuf(dest, increment);
|
PicoDraw2SetOutBuf(dest, increment);
|
||||||
} else if (dest != NULL) {
|
} else if (dest != NULL) {
|
||||||
DrawLineDestBase = dest;
|
DrawLineDestBase = dest;
|
||||||
|
|
431
pico/mode4.c
431
pico/mode4.c
|
@ -1,40 +1,45 @@
|
||||||
/*
|
/*
|
||||||
* mode4/SMS renderer
|
* SMS renderer
|
||||||
* (C) notaz, 2009-2010
|
* (C) notaz, 2009-2010
|
||||||
|
* (C) kub, 2021
|
||||||
|
*
|
||||||
|
* currently supports VDP mode 4 (SMS and GG) and mode 2
|
||||||
*
|
*
|
||||||
* This work is licensed under the terms of MAME license.
|
* This work is licensed under the terms of MAME license.
|
||||||
* See COPYING file in the top-level directory.
|
* See COPYING file in the top-level directory.
|
||||||
*/
|
*/
|
||||||
/*
|
/*
|
||||||
* TODO:
|
* TODO:
|
||||||
* - TMS9918 modes?
|
* - other TMS9918 modes?
|
||||||
* - gg mode?
|
|
||||||
* - column scroll (reg 0 bit7)
|
|
||||||
* - 224/240 line modes
|
|
||||||
* - doubled sprites
|
|
||||||
*/
|
*/
|
||||||
#include "pico_int.h"
|
#include "pico_int.h"
|
||||||
#include <platform/common/upscale.h>
|
#include <platform/common/upscale.h>
|
||||||
|
|
||||||
static void (*FinalizeLineM4)(int line);
|
static void (*FinalizeLineSMS)(int line);
|
||||||
static int skip_next_line;
|
static int skip_next_line;
|
||||||
static int screen_offset, line_offset;
|
static int screen_offset, line_offset;
|
||||||
|
|
||||||
static void TileBGM4(int sx, int pal)
|
|
||||||
|
/* Mode 4 */
|
||||||
|
/*========*/
|
||||||
|
|
||||||
|
static void TileBGM4(u16 sx, int pal)
|
||||||
{
|
{
|
||||||
u32 *pd = (u32 *)(Pico.est.HighCol + sx);
|
u32 *pd = (u32 *)(Pico.est.HighCol + sx);
|
||||||
pd[0] = pd[1] = pal ? 0x10101010 : 0;
|
pd[0] = pd[1] = pal ? 0x10101010 : 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// 8 pixels are arranged to have 1 bit in each byte of a 32 bit word. To pull
|
||||||
|
// the 4 bitplanes together multiply with each bit distance (multiples of 1<<7)
|
||||||
#define PLANAR_PIXELL(x,p) \
|
#define PLANAR_PIXELL(x,p) \
|
||||||
t = pack & (0x80808080 >> p); \
|
t = (pack>>(7-p)) & 0x01010101; \
|
||||||
t = ((t >> (7-p)) | (t >> (14-p)) | (t >> (21-p)) | (t >> (28-p))) & 0x0f; \
|
t = (t*0x10204080) >> 28; \
|
||||||
pd[x] = pal|t;
|
pd[x] = pal|t;
|
||||||
|
|
||||||
static void TileNormM4Low(int sx, unsigned int pack, int pal)
|
static void TileNormLowM4(u16 sx, unsigned int pack, int pal)
|
||||||
{
|
{
|
||||||
unsigned char *pd = Pico.est.HighCol + sx;
|
u8 *pd = Pico.est.HighCol + sx;
|
||||||
unsigned int t;
|
u32 t;
|
||||||
|
|
||||||
PLANAR_PIXELL(0, 0)
|
PLANAR_PIXELL(0, 0)
|
||||||
PLANAR_PIXELL(1, 1)
|
PLANAR_PIXELL(1, 1)
|
||||||
|
@ -46,10 +51,10 @@ static void TileNormM4Low(int sx, unsigned int pack, int pal)
|
||||||
PLANAR_PIXELL(7, 7)
|
PLANAR_PIXELL(7, 7)
|
||||||
}
|
}
|
||||||
|
|
||||||
static void TileFlipM4Low(int sx, unsigned int pack, int pal)
|
static void TileFlipLowM4(u16 sx, unsigned int pack, int pal)
|
||||||
{
|
{
|
||||||
unsigned char *pd = Pico.est.HighCol + sx;
|
u8 *pd = Pico.est.HighCol + sx;
|
||||||
unsigned int t;
|
u32 t;
|
||||||
|
|
||||||
PLANAR_PIXELL(0, 7)
|
PLANAR_PIXELL(0, 7)
|
||||||
PLANAR_PIXELL(1, 6)
|
PLANAR_PIXELL(1, 6)
|
||||||
|
@ -62,16 +67,16 @@ static void TileFlipM4Low(int sx, unsigned int pack, int pal)
|
||||||
}
|
}
|
||||||
|
|
||||||
#define PLANAR_PIXEL(x,p) \
|
#define PLANAR_PIXEL(x,p) \
|
||||||
t = pack & (0x80808080 >> p); \
|
t = (pack>>(7-p)) & 0x01010101; \
|
||||||
if (t) { \
|
if (t) { \
|
||||||
t = ((t >> (7-p)) | (t >> (14-p)) | (t >> (21-p)) | (t >> (28-p))) & 0x0f; \
|
t = (t*0x10204080) >> 28; \
|
||||||
pd[x] = pal|t; \
|
pd[x] = pal|t; \
|
||||||
}
|
}
|
||||||
|
|
||||||
static void TileNormM4(int sx, unsigned int pack, int pal)
|
static void TileNormM4(u16 sx, unsigned int pack, int pal)
|
||||||
{
|
{
|
||||||
unsigned char *pd = Pico.est.HighCol + sx;
|
u8 *pd = Pico.est.HighCol + sx;
|
||||||
unsigned int t;
|
u32 t;
|
||||||
|
|
||||||
PLANAR_PIXEL(0, 0)
|
PLANAR_PIXEL(0, 0)
|
||||||
PLANAR_PIXEL(1, 1)
|
PLANAR_PIXEL(1, 1)
|
||||||
|
@ -83,10 +88,10 @@ static void TileNormM4(int sx, unsigned int pack, int pal)
|
||||||
PLANAR_PIXEL(7, 7)
|
PLANAR_PIXEL(7, 7)
|
||||||
}
|
}
|
||||||
|
|
||||||
static void TileFlipM4(int sx, unsigned int pack, int pal)
|
static void TileFlipM4(u16 sx, unsigned int pack, int pal)
|
||||||
{
|
{
|
||||||
unsigned char *pd = Pico.est.HighCol + sx;
|
u8 *pd = Pico.est.HighCol + sx;
|
||||||
unsigned int t;
|
u32 t;
|
||||||
|
|
||||||
PLANAR_PIXEL(0, 7)
|
PLANAR_PIXEL(0, 7)
|
||||||
PLANAR_PIXEL(1, 6)
|
PLANAR_PIXEL(1, 6)
|
||||||
|
@ -98,34 +103,59 @@ static void TileFlipM4(int sx, unsigned int pack, int pal)
|
||||||
PLANAR_PIXEL(7, 0)
|
PLANAR_PIXEL(7, 0)
|
||||||
}
|
}
|
||||||
|
|
||||||
static void draw_sprites(int scanline)
|
static void TileDoubleM4(int sx, unsigned int pack, int pal)
|
||||||
|
{
|
||||||
|
u8 *pd = Pico.est.HighCol + sx;
|
||||||
|
u32 t;
|
||||||
|
|
||||||
|
PLANAR_PIXEL(0, 0)
|
||||||
|
PLANAR_PIXEL(1, 0)
|
||||||
|
PLANAR_PIXEL(2, 1)
|
||||||
|
PLANAR_PIXEL(3, 1)
|
||||||
|
PLANAR_PIXEL(4, 2)
|
||||||
|
PLANAR_PIXEL(5, 2)
|
||||||
|
PLANAR_PIXEL(6, 3)
|
||||||
|
PLANAR_PIXEL(7, 3)
|
||||||
|
PLANAR_PIXEL(8, 4)
|
||||||
|
PLANAR_PIXEL(9, 4)
|
||||||
|
PLANAR_PIXEL(10, 5)
|
||||||
|
PLANAR_PIXEL(11, 5)
|
||||||
|
PLANAR_PIXEL(12, 6)
|
||||||
|
PLANAR_PIXEL(13, 6)
|
||||||
|
PLANAR_PIXEL(14, 7)
|
||||||
|
PLANAR_PIXEL(15, 7)
|
||||||
|
}
|
||||||
|
|
||||||
|
static void DrawSpritesM4(int scanline)
|
||||||
{
|
{
|
||||||
struct PicoVideo *pv = &Pico.video;
|
struct PicoVideo *pv = &Pico.video;
|
||||||
unsigned int sprites_addr[8];
|
unsigned int sprites_addr[8];
|
||||||
unsigned int sprites_x[8];
|
unsigned int sprites_x[8];
|
||||||
unsigned int pack;
|
unsigned int pack;
|
||||||
unsigned char *sat;
|
u8 *sat;
|
||||||
int xoff = 8; // relative to HighCol, which is (screen - 8)
|
int xoff = 8; // relative to HighCol, which is (screen - 8)
|
||||||
int sprite_base, addr_mask;
|
int sprite_base, addr_mask;
|
||||||
|
int zoomed = pv->reg[1] & 0x1; // zoomed sprites, e.g. Earthworm Jim
|
||||||
int i, s, h;
|
int i, s, h;
|
||||||
|
|
||||||
if (pv->reg[0] & 8)
|
if (pv->reg[0] & 8)
|
||||||
xoff = 0;
|
xoff = 0;
|
||||||
xoff += line_offset;
|
xoff += line_offset;
|
||||||
|
|
||||||
sat = (unsigned char *)PicoMem.vram + ((pv->reg[5] & 0x7e) << 7);
|
sat = (u8 *)PicoMem.vram + ((pv->reg[5] & 0x7e) << 7);
|
||||||
if (pv->reg[1] & 2) {
|
if (pv->reg[1] & 2) {
|
||||||
addr_mask = 0xfe; h = 16;
|
addr_mask = 0xfe; h = 16;
|
||||||
} else {
|
} else {
|
||||||
addr_mask = 0xff; h = 8;
|
addr_mask = 0xff; h = 8;
|
||||||
}
|
}
|
||||||
|
if (zoomed) h *= 2;
|
||||||
sprite_base = (pv->reg[6] & 4) << (13-2-1);
|
sprite_base = (pv->reg[6] & 4) << (13-2-1);
|
||||||
|
|
||||||
for (i = s = 0; i < 64; i++)
|
for (i = s = 0; i < 64; i++)
|
||||||
{
|
{
|
||||||
int y;
|
int y;
|
||||||
y = sat[MEM_LE2(i)] + 1;
|
y = (sat[MEM_LE2(i)] + 1) & 0xff;
|
||||||
if (y == 0xd1)
|
if (y == 0xd1 && !((pv->reg[0] & 6) == 6 && (pv->reg[1] & 0x18)))
|
||||||
break;
|
break;
|
||||||
if (y + h <= scanline || scanline < y)
|
if (y + h <= scanline || scanline < y)
|
||||||
continue; // not on this line
|
continue; // not on this line
|
||||||
|
@ -136,7 +166,7 @@ static void draw_sprites(int scanline)
|
||||||
|
|
||||||
sprites_x[s] = xoff + sat[MEM_LE2(0x80 + i*2)];
|
sprites_x[s] = xoff + sat[MEM_LE2(0x80 + i*2)];
|
||||||
sprites_addr[s] = sprite_base + ((sat[MEM_LE2(0x80 + i*2 + 1)] & addr_mask) << (5-1)) +
|
sprites_addr[s] = sprite_base + ((sat[MEM_LE2(0x80 + i*2 + 1)] & addr_mask) << (5-1)) +
|
||||||
((scanline - y) << (2-1));
|
((scanline - y) >> zoomed << (2-1));
|
||||||
s++;
|
s++;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -147,30 +177,32 @@ static void draw_sprites(int scanline)
|
||||||
// now draw all sprites backwards
|
// now draw all sprites backwards
|
||||||
for (--s; s >= 0; s--) {
|
for (--s; s >= 0; s--) {
|
||||||
pack = CPU_LE2(*(u32 *)(PicoMem.vram + sprites_addr[s]));
|
pack = CPU_LE2(*(u32 *)(PicoMem.vram + sprites_addr[s]));
|
||||||
TileNormM4(sprites_x[s], pack, 0x10);
|
if (zoomed) TileDoubleM4(sprites_x[s], pack, 0x10);
|
||||||
|
else TileNormM4(sprites_x[s], pack, 0x10);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// cells_dx, tilex_ty merged to reduce register pressure
|
||||||
// tilex_ty_prio merged to reduce register pressure
|
static void DrawStripLowM4(const u16 *nametab, int cells_dx, int tilex_ty)
|
||||||
static void draw_strip_low(const unsigned short *nametab, int dx, int cells, int tilex_ty_prio)
|
|
||||||
{
|
{
|
||||||
int oldcode = -1;
|
int oldcode = -1;
|
||||||
int addr = 0, pal = 0;
|
int addr = 0, pal = 0;
|
||||||
|
|
||||||
// Draw tiles across screen:
|
// Draw tiles across screen:
|
||||||
for (; cells > 0; dx += 8, tilex_ty_prio++, cells--)
|
for (; cells_dx > 0; cells_dx += 8, tilex_ty++, cells_dx -= 0x10000)
|
||||||
{
|
{
|
||||||
unsigned int pack;
|
unsigned int pack;
|
||||||
unsigned code;
|
unsigned code;
|
||||||
|
|
||||||
code = nametab[tilex_ty_prio & 0x1f];
|
code = nametab[tilex_ty& 0x1f];
|
||||||
|
if (code & 0x1000) // priority high?
|
||||||
|
continue;
|
||||||
|
|
||||||
if (code != oldcode) {
|
if (code != oldcode) {
|
||||||
oldcode = code;
|
oldcode = code;
|
||||||
// Get tile address/2:
|
// Get tile address/2:
|
||||||
addr = (code & 0x1ff) << 4;
|
addr = (code & 0x1ff) << 4;
|
||||||
addr += tilex_ty_prio >> 16;
|
addr += tilex_ty>> 16;
|
||||||
if (code & 0x0400)
|
if (code & 0x0400)
|
||||||
addr ^= 0xe; // Y-flip
|
addr ^= 0xe; // Y-flip
|
||||||
|
|
||||||
|
@ -178,34 +210,34 @@ static void draw_strip_low(const unsigned short *nametab, int dx, int cells, int
|
||||||
}
|
}
|
||||||
|
|
||||||
pack = CPU_LE2(*(u32 *)(PicoMem.vram + addr)); /* Get 4 bitplanes / 8 pixels */
|
pack = CPU_LE2(*(u32 *)(PicoMem.vram + addr)); /* Get 4 bitplanes / 8 pixels */
|
||||||
if (pack == 0) TileBGM4(dx, pal);
|
if (pack == 0) TileBGM4(cells_dx, pal);
|
||||||
else if (code & 0x0200) TileFlipM4Low(dx, pack, pal);
|
else if (code & 0x0200) TileFlipLowM4(cells_dx, pack, pal);
|
||||||
else TileNormM4Low(dx, pack, pal);
|
else TileNormLowM4(cells_dx, pack, pal);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
// tilex_ty_prio merged to reduce register pressure
|
|
||||||
static void draw_strip_high(const unsigned short *nametab, int dx, int cells, int tilex_ty_prio)
|
static void DrawStripHighM4(const u16 *nametab, int cells_dx, int tilex_ty)
|
||||||
{
|
{
|
||||||
int oldcode = -1, blank = -1; // The tile we know is blank
|
int oldcode = -1, blank = -1; // The tile we know is blank
|
||||||
int addr = 0, pal = 0;
|
int addr = 0, pal = 0;
|
||||||
|
|
||||||
// Draw tiles across screen:
|
// Draw tiles across screen:
|
||||||
for (; cells > 0; dx += 8, tilex_ty_prio++, cells--)
|
for (; cells_dx > 0; cells_dx += 8, tilex_ty++, cells_dx -= 0x10000)
|
||||||
{
|
{
|
||||||
unsigned int pack;
|
unsigned int pack;
|
||||||
unsigned code;
|
unsigned code;
|
||||||
|
|
||||||
code = nametab[tilex_ty_prio & 0x1f];
|
code = nametab[tilex_ty& 0x1f];
|
||||||
if (code == blank)
|
if (code == blank)
|
||||||
continue;
|
continue;
|
||||||
if ((code ^ tilex_ty_prio) & 0x1000) // priority differs?
|
if (!(code & 0x1000)) // priority low?
|
||||||
continue;
|
continue;
|
||||||
|
|
||||||
if (code != oldcode) {
|
if (code != oldcode) {
|
||||||
oldcode = code;
|
oldcode = code;
|
||||||
// Get tile address/2:
|
// Get tile address/2:
|
||||||
addr = (code & 0x1ff) << 4;
|
addr = (code & 0x1ff) << 4;
|
||||||
addr += tilex_ty_prio >> 16;
|
addr += tilex_ty>> 16;
|
||||||
if (code & 0x0400)
|
if (code & 0x0400)
|
||||||
addr ^= 0xe; // Y-flip
|
addr ^= 0xe; // Y-flip
|
||||||
|
|
||||||
|
@ -217,15 +249,15 @@ static void draw_strip_high(const unsigned short *nametab, int dx, int cells, in
|
||||||
blank = code;
|
blank = code;
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
if (code & 0x0200) TileFlipM4(dx, pack, pal);
|
if (code & 0x0200) TileFlipM4(cells_dx, pack, pal);
|
||||||
else TileNormM4(dx, pack, pal);
|
else TileNormM4(cells_dx, pack, pal);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
static void DrawDisplayM4(int scanline)
|
static void DrawDisplayM4(int scanline)
|
||||||
{
|
{
|
||||||
struct PicoVideo *pv = &Pico.video;
|
struct PicoVideo *pv = &Pico.video;
|
||||||
unsigned short *nametab;
|
u16 *nametab, *nametab2;
|
||||||
int line, tilex, dx, ty, cells;
|
int line, tilex, dx, ty, cells;
|
||||||
int cellskip = 0; // XXX
|
int cellskip = 0; // XXX
|
||||||
int maxcells = 32;
|
int maxcells = 32;
|
||||||
|
@ -236,6 +268,7 @@ static void DrawDisplayM4(int scanline)
|
||||||
// Find name table:
|
// Find name table:
|
||||||
nametab = PicoMem.vram;
|
nametab = PicoMem.vram;
|
||||||
if ((pv->reg[0] & 6) == 6 && (pv->reg[1] & 0x18)) {
|
if ((pv->reg[0] & 6) == 6 && (pv->reg[1] & 0x18)) {
|
||||||
|
// 224/240 line mode
|
||||||
line &= 0xff;
|
line &= 0xff;
|
||||||
nametab += ((pv->reg[2] & 0x0c) << (10-1)) + (0x700 >> 1);
|
nametab += ((pv->reg[2] & 0x0c) << (10-1)) + (0x700 >> 1);
|
||||||
} else {
|
} else {
|
||||||
|
@ -244,11 +277,12 @@ static void DrawDisplayM4(int scanline)
|
||||||
// old SMS only, masks line:7 with reg[2]:0 for address calculation
|
// old SMS only, masks line:7 with reg[2]:0 for address calculation
|
||||||
//if ((pv->reg[2] & 0x01) == 0) line &= 0x7f;
|
//if ((pv->reg[2] & 0x01) == 0) line &= 0x7f;
|
||||||
}
|
}
|
||||||
nametab += (line>>3) << (6-1);
|
nametab2 = nametab + ((scanline>>3) << (6-1));
|
||||||
|
nametab = nametab + ((line>>3) << (6-1));
|
||||||
|
|
||||||
dx = pv->reg[8]; // hscroll
|
dx = pv->reg[8]; // hscroll
|
||||||
if (scanline < 16 && (pv->reg[0] & 0x40))
|
if (scanline < 16 && (pv->reg[0] & 0x40))
|
||||||
dx = 0; // hscroll disabled for top 2 rows
|
dx = 0; // hscroll disabled for top 2 rows (e.g. Fantasy Zone II)
|
||||||
|
|
||||||
tilex = ((-dx >> 3) + cellskip) & 0x1f;
|
tilex = ((-dx >> 3) + cellskip) & 0x1f;
|
||||||
ty = (line & 7) << 1; // Y-Offset into tile
|
ty = (line & 7) << 1; // Y-Offset into tile
|
||||||
|
@ -261,41 +295,250 @@ static void DrawDisplayM4(int scanline)
|
||||||
dx += line_offset;
|
dx += line_offset;
|
||||||
|
|
||||||
// low priority tiles
|
// low priority tiles
|
||||||
if (!(pv->debug_p & PVD_KILL_B))
|
if (!(pv->debug_p & PVD_KILL_B)) {
|
||||||
draw_strip_low(nametab, dx, cells, tilex | 0x0000 | (ty << 16));
|
if (pv->reg[0] & 0x80) {
|
||||||
|
// vscroll disabled for rightmost 8 columns (e.g. Gauntlet)
|
||||||
|
int dx2 = dx + (cells-8)*8, tilex2 = tilex + (cells-8), ty2 = scanline & 7;
|
||||||
|
DrawStripLowM4(nametab, dx | ((cells-8) << 16), tilex | (ty << 16));
|
||||||
|
DrawStripLowM4(nametab2, dx2 | (8 << 16), tilex2 | (ty2 << 17));
|
||||||
|
} else
|
||||||
|
DrawStripLowM4(nametab , dx | ( cells << 16), tilex | (ty << 16));
|
||||||
|
}
|
||||||
|
|
||||||
// sprites
|
// sprites
|
||||||
if (!(pv->debug_p & PVD_KILL_S_LO))
|
if (!(pv->debug_p & PVD_KILL_S_LO))
|
||||||
draw_sprites(scanline);
|
DrawSpritesM4(scanline);
|
||||||
|
|
||||||
// high priority tiles (use virtual layer switch just for fun)
|
// high priority tiles (use virtual layer switch just for fun)
|
||||||
if (!(pv->debug_p & PVD_KILL_A))
|
if (!(pv->debug_p & PVD_KILL_A)) {
|
||||||
draw_strip_high(nametab, dx, cells, tilex | 0x1000 | (ty << 16));
|
if (pv->reg[0] & 0x80) {
|
||||||
|
int dx2 = dx + (cells-8)*8, tilex2 = tilex + (cells-8), ty2 = scanline & 7;
|
||||||
|
DrawStripHighM4(nametab, dx | ((cells-8) << 16), tilex | (ty << 16));
|
||||||
|
DrawStripHighM4(nametab2, dx2 | (8 << 16), tilex2 | (ty2 << 17));
|
||||||
|
} else
|
||||||
|
DrawStripHighM4(nametab , dx | ( cells << 16), tilex | (ty << 16));
|
||||||
|
}
|
||||||
|
|
||||||
if (pv->reg[0] & 0x20) {
|
if (pv->reg[0] & 0x20) {
|
||||||
// first column masked, caculate offset to start of line
|
// first column masked with background, caculate offset to start of line
|
||||||
dx = (dx&~0x1f) / 4;
|
dx = (dx&~0x1f) / 4;
|
||||||
((u32 *)Pico.est.HighCol)[dx+2] = ((u32 *)Pico.est.HighCol)[dx+3] = 0xe0e0e0e0;
|
ty = 0xe0e0e0e0; // really (pv->reg[7]&0x3f) * 0x01010101, but the looks...
|
||||||
|
((u32 *)Pico.est.HighCol)[dx+2] = ((u32 *)Pico.est.HighCol)[dx+3] = ty;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
static void FinalizeLineRGB555M4(int line);
|
|
||||||
void PicoFrameStartMode4(void)
|
/* Mode 2 */
|
||||||
|
/*========*/
|
||||||
|
|
||||||
|
/* Background */
|
||||||
|
|
||||||
|
#define TMS_PIXELBG(x,p) \
|
||||||
|
t = (pack>>(7-p)) & 0x01; \
|
||||||
|
t = (pal >> (t << 2)) & 0x0f; \
|
||||||
|
pd[x] = t;
|
||||||
|
|
||||||
|
static void TileNormBgM2(u16 sx, unsigned int pack, int pal)
|
||||||
|
{
|
||||||
|
u8 *pd = Pico.est.HighCol + sx;
|
||||||
|
unsigned int t;
|
||||||
|
|
||||||
|
TMS_PIXELBG(0, 0)
|
||||||
|
TMS_PIXELBG(1, 1)
|
||||||
|
TMS_PIXELBG(2, 2)
|
||||||
|
TMS_PIXELBG(3, 3)
|
||||||
|
TMS_PIXELBG(4, 4)
|
||||||
|
TMS_PIXELBG(5, 5)
|
||||||
|
TMS_PIXELBG(6, 6)
|
||||||
|
TMS_PIXELBG(7, 7)
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Sprites */
|
||||||
|
|
||||||
|
#define TMS_PIXELSP(x,p) \
|
||||||
|
t = (pack>>(7-p)) & 0x01; \
|
||||||
|
if (t) \
|
||||||
|
pd[x] = pal;
|
||||||
|
|
||||||
|
static void TileNormSprM2(u16 sx, unsigned int pack, int pal)
|
||||||
|
{
|
||||||
|
u8 *pd = Pico.est.HighCol + sx;
|
||||||
|
unsigned int t;
|
||||||
|
|
||||||
|
TMS_PIXELSP(0, 0)
|
||||||
|
TMS_PIXELSP(1, 1)
|
||||||
|
TMS_PIXELSP(2, 2)
|
||||||
|
TMS_PIXELSP(3, 3)
|
||||||
|
TMS_PIXELSP(4, 4)
|
||||||
|
TMS_PIXELSP(5, 5)
|
||||||
|
TMS_PIXELSP(6, 6)
|
||||||
|
TMS_PIXELSP(7, 7)
|
||||||
|
}
|
||||||
|
|
||||||
|
static void TileDoubleSprM2(u16 sx, unsigned int pack, int pal)
|
||||||
|
{
|
||||||
|
u8 *pd = Pico.est.HighCol + sx;
|
||||||
|
unsigned int t;
|
||||||
|
|
||||||
|
TMS_PIXELSP(0, 0)
|
||||||
|
TMS_PIXELSP(1, 0)
|
||||||
|
TMS_PIXELSP(2, 1)
|
||||||
|
TMS_PIXELSP(3, 1)
|
||||||
|
TMS_PIXELSP(4, 2)
|
||||||
|
TMS_PIXELSP(5, 2)
|
||||||
|
TMS_PIXELSP(6, 3)
|
||||||
|
TMS_PIXELSP(7, 3)
|
||||||
|
TMS_PIXELSP(8, 4)
|
||||||
|
TMS_PIXELSP(9, 4)
|
||||||
|
TMS_PIXELSP(10, 5)
|
||||||
|
TMS_PIXELSP(11, 5)
|
||||||
|
TMS_PIXELSP(12, 6)
|
||||||
|
TMS_PIXELSP(13, 6)
|
||||||
|
TMS_PIXELSP(14, 7)
|
||||||
|
TMS_PIXELSP(15, 7)
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Draw sprites into a scanline, max 4 */
|
||||||
|
static void DrawSpritesM2(int scanline)
|
||||||
|
{
|
||||||
|
struct PicoVideo *pv = &Pico.video;
|
||||||
|
unsigned int sprites_addr[4];
|
||||||
|
unsigned int sprites_x[4];
|
||||||
|
unsigned int pack;
|
||||||
|
u8 *sat;
|
||||||
|
int xoff = 8; // relative to HighCol, which is (screen - 8)
|
||||||
|
int sprite_base, addr_mask;
|
||||||
|
int zoomed = pv->reg[1] & 0x1; // zoomed sprites
|
||||||
|
int i, s, h;
|
||||||
|
|
||||||
|
xoff += line_offset;
|
||||||
|
|
||||||
|
sat = (u8 *)PicoMem.vramb + ((pv->reg[5] & 0x7e) << 7);
|
||||||
|
if (pv->reg[1] & 2) {
|
||||||
|
addr_mask = 0xfc; h = 16;
|
||||||
|
} else {
|
||||||
|
addr_mask = 0xff; h = 8;
|
||||||
|
}
|
||||||
|
if (zoomed) h *= 2;
|
||||||
|
|
||||||
|
sprite_base = (pv->reg[6] & 0x7) << 11;
|
||||||
|
|
||||||
|
/* find sprites on this scanline */
|
||||||
|
for (i = s = 0; i < 32; i++)
|
||||||
|
{
|
||||||
|
int y;
|
||||||
|
y = (sat[MEM_LE2(4*i)] + 1) & 0xff;
|
||||||
|
if (y == 0xd1)
|
||||||
|
break;
|
||||||
|
if (y > 0xe0)
|
||||||
|
y -= 256;
|
||||||
|
if (y + h <= scanline || scanline < y)
|
||||||
|
continue; // not on this line
|
||||||
|
if (s >= 4) {
|
||||||
|
pv->status |= SR_SOVR | i;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
sprites_x[s] = 4*i;
|
||||||
|
sprites_addr[s] = sprite_base + ((sat[MEM_LE2(4*i + 2)] & addr_mask) << 3) +
|
||||||
|
((scanline - y) >> zoomed);
|
||||||
|
s++;
|
||||||
|
}
|
||||||
|
|
||||||
|
// really half-assed but better than nothing
|
||||||
|
if (s > 1)
|
||||||
|
pv->status |= SR_C;
|
||||||
|
|
||||||
|
// now draw all sprites backwards
|
||||||
|
for (--s; s >= 0; s--) {
|
||||||
|
int x, w = (zoomed ? 16: 8);
|
||||||
|
i = sprites_x[s];
|
||||||
|
x = sat[MEM_LE2(i+1)] + xoff;
|
||||||
|
if (sat[MEM_LE2(i+3)] & 0x80)
|
||||||
|
x -= 32;
|
||||||
|
if (x > 0) {
|
||||||
|
pack = PicoMem.vramb[MEM_LE2(sprites_addr[s])];
|
||||||
|
if (zoomed) TileDoubleSprM2(x, pack, sat[MEM_LE2(i+3)] & 0xf);
|
||||||
|
else TileNormSprM2(x, pack, sat[MEM_LE2(i+3)] & 0xf);
|
||||||
|
}
|
||||||
|
if((pv->reg[1] & 0x2) && (x+=w) > 0) {
|
||||||
|
pack = PicoMem.vramb[MEM_LE2(sprites_addr[s]+0x10)];
|
||||||
|
if (zoomed) TileDoubleSprM2(x, pack, sat[MEM_LE2(i+3)] & 0xf);
|
||||||
|
else TileNormSprM2(x, pack, sat[MEM_LE2(i+3)] & 0xf);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Draw the background into a scanline; cells, dx, tilex, ty merged to reduce registers */
|
||||||
|
static void DrawStripM2(const u8 *nametab, const u8 *coltab, const u8 *pattab, int cells_dx, int tilex_ty)
|
||||||
|
{
|
||||||
|
// Draw tiles across screen:
|
||||||
|
for (; cells_dx > 0; cells_dx += 8, tilex_ty++, cells_dx -= 0x10000)
|
||||||
|
{
|
||||||
|
unsigned int pack, pal;
|
||||||
|
unsigned code;
|
||||||
|
|
||||||
|
code = nametab[tilex_ty& 0x1f] << 3;
|
||||||
|
pal = coltab[code];
|
||||||
|
pack = pattab[code];
|
||||||
|
TileNormBgM2(cells_dx, pack, pal);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Draw a scanline */
|
||||||
|
static void DrawDisplayM2(int scanline)
|
||||||
|
{
|
||||||
|
struct PicoVideo *pv = &Pico.video;
|
||||||
|
u8 *nametab, *coltab, *pattab;
|
||||||
|
int tilex, dx, cells;
|
||||||
|
int cellskip = 0; // XXX
|
||||||
|
int maxcells = 32;
|
||||||
|
|
||||||
|
// name, color, pattern table:
|
||||||
|
nametab = PicoMem.vramb + ((pv->reg[2]<<10) & 0x3c00);
|
||||||
|
coltab = PicoMem.vramb + ((pv->reg[3]<< 6) & 0x2000);
|
||||||
|
pattab = PicoMem.vramb + ((pv->reg[4]<<11) & 0x2000);
|
||||||
|
|
||||||
|
nametab += ((scanline>>3) << 5);
|
||||||
|
coltab += ((scanline>>6) <<11) + (scanline & 0x7);
|
||||||
|
pattab += ((scanline>>6) <<11) + (scanline & 0x7);
|
||||||
|
|
||||||
|
tilex = cellskip & 0x1f;
|
||||||
|
cells = maxcells - cellskip;
|
||||||
|
dx = (cellskip << 3) + line_offset + 8;
|
||||||
|
|
||||||
|
// tiles
|
||||||
|
if (!(pv->debug_p & PVD_KILL_B))
|
||||||
|
DrawStripM2(nametab, coltab, pattab, dx | (cells << 16), tilex | (scanline << 16));
|
||||||
|
|
||||||
|
// sprites
|
||||||
|
if (!(pv->debug_p & PVD_KILL_S_LO))
|
||||||
|
DrawSpritesM2(scanline);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/* Common/global */
|
||||||
|
/*===============*/
|
||||||
|
|
||||||
|
static void FinalizeLineRGB555SMS(int line);
|
||||||
|
|
||||||
|
void PicoFrameStartSMS(void)
|
||||||
{
|
{
|
||||||
int lines = 192, columns = 256, coffs;
|
int lines = 192, columns = 256, coffs;
|
||||||
skip_next_line = 0;
|
skip_next_line = 0;
|
||||||
screen_offset = 24;
|
screen_offset = 24;
|
||||||
Pico.est.rendstatus = PDRAW_32_COLS;
|
Pico.est.rendstatus = PDRAW_32_COLS;
|
||||||
|
|
||||||
if ((Pico.video.reg[0] & 6) == 6 && (Pico.video.reg[1] & 0x18)) {
|
switch ((Pico.video.reg[0]&0x06) | (Pico.video.reg[1]&0x18)) {
|
||||||
if (Pico.video.reg[1] & 0x08) {
|
// SMS2 only 224/240 line modes, e.g. Micro Machines
|
||||||
|
case 0x06|0x08:
|
||||||
screen_offset = 0;
|
screen_offset = 0;
|
||||||
lines = 240;
|
lines = 240;
|
||||||
}
|
break;
|
||||||
else {
|
case 0x06|0x10:
|
||||||
screen_offset = 8;
|
screen_offset = 8;
|
||||||
lines = 224;
|
lines = 224;
|
||||||
}
|
break;
|
||||||
}
|
}
|
||||||
if (PicoIn.opt & POPT_EN_SOFTSCALE) {
|
if (PicoIn.opt & POPT_EN_SOFTSCALE) {
|
||||||
line_offset = 0;
|
line_offset = 0;
|
||||||
|
@ -304,7 +547,7 @@ void PicoFrameStartMode4(void)
|
||||||
line_offset = PicoIn.opt & POPT_DIS_32C_BORDER ? 0 : 32;
|
line_offset = PicoIn.opt & POPT_DIS_32C_BORDER ? 0 : 32;
|
||||||
|
|
||||||
coffs = line_offset;
|
coffs = line_offset;
|
||||||
if (FinalizeLineM4 == FinalizeLineRGB555M4)
|
if (FinalizeLineSMS == FinalizeLineRGB555SMS)
|
||||||
line_offset = 0 /* done in FinalizeLine */;
|
line_offset = 0 /* done in FinalizeLine */;
|
||||||
|
|
||||||
if (Pico.est.rendstatus != rendstatus_old || lines != rendlines) {
|
if (Pico.est.rendstatus != rendstatus_old || lines != rendlines) {
|
||||||
|
@ -317,7 +560,7 @@ void PicoFrameStartMode4(void)
|
||||||
Pico.est.DrawLineDest = (char *)DrawLineDestBase + screen_offset * DrawLineDestIncrement;
|
Pico.est.DrawLineDest = (char *)DrawLineDestBase + screen_offset * DrawLineDestIncrement;
|
||||||
}
|
}
|
||||||
|
|
||||||
void PicoLineMode4(int line)
|
void PicoLineSMS(int line)
|
||||||
{
|
{
|
||||||
if (skip_next_line > 0) {
|
if (skip_next_line > 0) {
|
||||||
skip_next_line--;
|
skip_next_line--;
|
||||||
|
@ -329,11 +572,13 @@ void PicoLineMode4(int line)
|
||||||
|
|
||||||
// Draw screen:
|
// Draw screen:
|
||||||
BackFill(Pico.video.reg[7] & 0x0f, 0, &Pico.est);
|
BackFill(Pico.video.reg[7] & 0x0f, 0, &Pico.est);
|
||||||
if (Pico.video.reg[1] & 0x40)
|
if (Pico.video.reg[1] & 0x40) {
|
||||||
DrawDisplayM4(line);
|
if (Pico.video.reg[0] & 0x04) DrawDisplayM4(line);
|
||||||
|
else DrawDisplayM2(line);
|
||||||
|
}
|
||||||
|
|
||||||
if (FinalizeLineM4 != NULL)
|
if (FinalizeLineSMS != NULL)
|
||||||
FinalizeLineM4(line);
|
FinalizeLineSMS(line);
|
||||||
|
|
||||||
if (PicoScanEnd != NULL)
|
if (PicoScanEnd != NULL)
|
||||||
skip_next_line = PicoScanEnd(line + screen_offset);
|
skip_next_line = PicoScanEnd(line + screen_offset);
|
||||||
|
@ -342,7 +587,12 @@ void PicoLineMode4(int line)
|
||||||
Pico.est.DrawLineDest = (char *)Pico.est.DrawLineDest + DrawLineDestIncrement;
|
Pico.est.DrawLineDest = (char *)Pico.est.DrawLineDest + DrawLineDestIncrement;
|
||||||
}
|
}
|
||||||
|
|
||||||
void PicoDoHighPal555M4(void)
|
/* Fixed palette for TMS9918 modes */
|
||||||
|
static u16 tmspal[32] = {
|
||||||
|
0x00,0x00,0x08,0x0c,0x10,0x30,0x01,0x3c,0x02,0x03,0x05,0x0f,0x04,0x33,0x15,0x3f
|
||||||
|
};
|
||||||
|
|
||||||
|
void PicoDoHighPal555SMS(void)
|
||||||
{
|
{
|
||||||
unsigned int *spal=(void *)PicoMem.cram;
|
unsigned int *spal=(void *)PicoMem.cram;
|
||||||
unsigned int *dpal=(void *)Pico.est.HighPal;
|
unsigned int *dpal=(void *)Pico.est.HighPal;
|
||||||
|
@ -350,9 +600,11 @@ void PicoDoHighPal555M4(void)
|
||||||
int i;
|
int i;
|
||||||
|
|
||||||
Pico.m.dirtyPal = 0;
|
Pico.m.dirtyPal = 0;
|
||||||
|
if (!(Pico.video.reg[0] & 0x4))
|
||||||
|
spal = (u32 *)tmspal;
|
||||||
|
|
||||||
/* cram is always stored as shorts, even though real hardware probably uses bytes */
|
/* cram is always stored as shorts, even though real hardware probably uses bytes */
|
||||||
for (i = 0x20/2; i > 0; i--, spal++, dpal++) {
|
if (PicoIn.AHW & PAHW_SMS) for (i = 0x20/2; i > 0; i--, spal++, dpal++) {
|
||||||
t = *spal;
|
t = *spal;
|
||||||
#if defined(USE_BGR555)
|
#if defined(USE_BGR555)
|
||||||
t = ((t & 0x00030003)<< 3) | ((t & 0x000c000c)<<6) | ((t & 0x00300030)<<9);
|
t = ((t & 0x00030003)<< 3) | ((t & 0x000c000c)<<6) | ((t & 0x00300030)<<9);
|
||||||
|
@ -363,42 +615,55 @@ void PicoDoHighPal555M4(void)
|
||||||
#else
|
#else
|
||||||
t = ((t & 0x00030003)<<14) | ((t & 0x000c000c)<<7) | ((t & 0x00300030)>>1);
|
t = ((t & 0x00030003)<<14) | ((t & 0x000c000c)<<7) | ((t & 0x00300030)>>1);
|
||||||
t |= (t >> 2) | ((t >> 4) & 0x08610861);
|
t |= (t >> 2) | ((t >> 4) & 0x08610861);
|
||||||
|
#endif
|
||||||
|
*dpal = t;
|
||||||
|
} else for (i = 0x20/2; i > 0; i--, spal++, dpal++) { // GG palette 4 bit/col
|
||||||
|
t = *spal;
|
||||||
|
#if defined(USE_BGR555)
|
||||||
|
t = ((t & 0x000f000f)<< 1) | ((t & 0x00f000f0)<<2) | ((t & 0x0f000f00)<<3);
|
||||||
|
t |= (t >> 4) & 0x04210421;
|
||||||
|
#elif defined(USE_BGR565)
|
||||||
|
t = ((t & 0x000f000f)<< 1) | ((t & 0x00f000f0)<<3) | ((t & 0x0f000f00)<<4);
|
||||||
|
t |= (t >> 4) & 0x08610861;
|
||||||
|
#else
|
||||||
|
t = ((t & 0x000f000f)<<12) | ((t & 0x00f000f0)<<3) | ((t & 0x0f000f00)>>7);
|
||||||
|
t |= (t >> 4) & 0x08610861;
|
||||||
#endif
|
#endif
|
||||||
*dpal = t;
|
*dpal = t;
|
||||||
}
|
}
|
||||||
Pico.est.HighPal[0xe0] = 0;
|
Pico.est.HighPal[0xe0] = 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
static void FinalizeLineRGB555M4(int line)
|
static void FinalizeLineRGB555SMS(int line)
|
||||||
{
|
{
|
||||||
if (Pico.m.dirtyPal)
|
if (Pico.m.dirtyPal)
|
||||||
PicoDoHighPal555M4();
|
PicoDoHighPal555SMS();
|
||||||
|
|
||||||
// standard FinalizeLine can finish it for us,
|
// standard FinalizeLine can finish it for us,
|
||||||
// with features like scaling and such
|
// with features like scaling and such
|
||||||
FinalizeLine555(0, line, &Pico.est);
|
FinalizeLine555(0, line, &Pico.est);
|
||||||
}
|
}
|
||||||
|
|
||||||
static void FinalizeLine8bitM4(int line)
|
static void FinalizeLine8bitSMS(int line)
|
||||||
{
|
{
|
||||||
unsigned char *pd = Pico.est.DrawLineDest + line_offset;
|
u8 *pd = Pico.est.DrawLineDest + line_offset;
|
||||||
unsigned char *ps = Pico.est.HighCol + line_offset + 8;
|
u8 *ps = Pico.est.HighCol + line_offset + 8;
|
||||||
|
|
||||||
if (DrawLineDestIncrement) {
|
if (DrawLineDestIncrement) {
|
||||||
if (PicoIn.opt & POPT_EN_SOFTSCALE)
|
if (PicoIn.opt & POPT_EN_SOFTSCALE)
|
||||||
rh_upscale_nn_4_5(pd, 320, ps, 256, 256, f_nop);
|
rh_upscale_nn_4_5(pd, 320, ps, 256, 256, f_nop);
|
||||||
else
|
else if (pd != ps)
|
||||||
memcpy(pd, ps, 256);
|
memcpy(pd, ps, 256);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void PicoDrawSetOutputMode4(pdso_t which)
|
void PicoDrawSetOutputSMS(pdso_t which)
|
||||||
{
|
{
|
||||||
switch (which)
|
switch (which)
|
||||||
{
|
{
|
||||||
case PDF_8BIT: FinalizeLineM4 = FinalizeLine8bitM4; break;
|
case PDF_8BIT: FinalizeLineSMS = FinalizeLine8bitSMS; break;
|
||||||
case PDF_RGB555: FinalizeLineM4 = FinalizeLineRGB555M4; break;
|
case PDF_RGB555: FinalizeLineSMS = FinalizeLineRGB555SMS; break;
|
||||||
default: FinalizeLineM4 = NULL;
|
default: FinalizeLineSMS = NULL;
|
||||||
PicoDrawSetInternalBuf(Pico.est.Draw2FB, 328); break;
|
PicoDrawSetInternalBuf(Pico.est.Draw2FB, 328); break;
|
||||||
}
|
}
|
||||||
rendstatus_old = -1;
|
rendstatus_old = -1;
|
||||||
|
|
|
@ -687,10 +687,10 @@ void PicoDraw2Init(void);
|
||||||
PICO_INTERNAL void PicoFrameFull();
|
PICO_INTERNAL void PicoFrameFull();
|
||||||
|
|
||||||
// mode4.c
|
// mode4.c
|
||||||
void PicoFrameStartMode4(void);
|
void PicoFrameStartSMS(void);
|
||||||
void PicoLineMode4(int line);
|
void PicoLineSMS(int line);
|
||||||
void PicoDoHighPal555M4(void);
|
void PicoDoHighPal555SMS(void);
|
||||||
void PicoDrawSetOutputMode4(pdso_t which);
|
void PicoDrawSetOutputSMS(pdso_t which);
|
||||||
|
|
||||||
// memory.c
|
// memory.c
|
||||||
PICO_INTERNAL void PicoMemSetup(void);
|
PICO_INTERNAL void PicoMemSetup(void);
|
||||||
|
|
|
@ -402,7 +402,7 @@ void PicoFrameMS(void)
|
||||||
|
|
||||||
if ((pv->reg[0] & 6) == 6 && (pv->reg[1] & 0x18))
|
if ((pv->reg[0] & 6) == 6 && (pv->reg[1] & 0x18))
|
||||||
lines_vis = (pv->reg[1] & 0x08) ? 240 : 224;
|
lines_vis = (pv->reg[1] & 0x08) ? 240 : 224;
|
||||||
PicoFrameStartMode4();
|
PicoFrameStartSMS();
|
||||||
hint = pv->reg[0x0a];
|
hint = pv->reg[0x0a];
|
||||||
|
|
||||||
for (y = 0; y < lines; y++)
|
for (y = 0; y < lines; y++)
|
||||||
|
@ -412,7 +412,7 @@ void PicoFrameMS(void)
|
||||||
pv->v_counter = y - 6;
|
pv->v_counter = y - 6;
|
||||||
|
|
||||||
if (y < lines_vis && !skip)
|
if (y < lines_vis && !skip)
|
||||||
PicoLineMode4(y);
|
PicoLineSMS(y);
|
||||||
|
|
||||||
if (y <= lines_vis)
|
if (y <= lines_vis)
|
||||||
{
|
{
|
||||||
|
@ -448,10 +448,10 @@ void PicoFrameDrawOnlyMS(void)
|
||||||
int lines_vis = 192;
|
int lines_vis = 192;
|
||||||
int y;
|
int y;
|
||||||
|
|
||||||
PicoFrameStartMode4();
|
PicoFrameStartSMS();
|
||||||
|
|
||||||
for (y = 0; y < lines_vis; y++)
|
for (y = 0; y < lines_vis; y++)
|
||||||
PicoLineMode4(y);
|
PicoLineSMS(y);
|
||||||
}
|
}
|
||||||
|
|
||||||
// vim:ts=2:sw=2:expandtab
|
// vim:ts=2:sw=2:expandtab
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue