more sms wip, better ROM detect, line callback change

git-svn-id: file:///home/notaz/opt/svn/PicoDrive@762 be3aeb3a-fb24-0410-a615-afba39da0efa
This commit is contained in:
notaz 2009-08-27 21:44:52 +00:00
parent 200772b790
commit 87b0845f37
19 changed files with 414 additions and 186 deletions

View file

@ -71,18 +71,31 @@ static int uncompress2(void *dest, int destLen, void *source, int sourceLen)
return inflateEnd(&stream); return inflateEnd(&stream);
} }
static const char *get_ext(const char *path)
{
const char *ext;
if (strlen(path) < 4)
return ""; // no ext
// allow 2 or 3 char extensions for now
ext = path + strlen(path) - 2;
if (ext[-1] != '.') ext--;
if (ext[-1] != '.')
return "";
return ext;
}
pm_file *pm_open(const char *path) pm_file *pm_open(const char *path)
{ {
pm_file *file = NULL; pm_file *file = NULL;
const char *ext; const char *ext;
FILE *f; FILE *f;
if (path == NULL) return NULL; if (path == NULL)
return NULL;
if (strlen(path) < 5) ext = NULL; // no ext ext = get_ext(path);
else ext = path + strlen(path) - 3; if (strcasecmp(ext, "zip") == 0)
if (ext && strcasecmp(ext, "zip") == 0)
{ {
struct zipent *zipentry; struct zipent *zipentry;
gzFile gzf = NULL; gzFile gzf = NULL;
@ -90,21 +103,19 @@ pm_file *pm_open(const char *path)
int i; int i;
zipfile = openzip(path); zipfile = openzip(path);
if (zipfile != NULL) if (zipfile != NULL)
{ {
/* search for suitable file (right extension or large enough file) */ /* search for suitable file (right extension or large enough file) */
while ((zipentry = readzip(zipfile)) != NULL) while ((zipentry = readzip(zipfile)) != NULL)
{ {
if (zipentry->uncompressed_size >= 128*1024) goto found_rom_zip; ext = get_ext(zipentry->name);
if (strlen(zipentry->name) < 5) continue;
ext = zipentry->name + strlen(zipentry->name) - 2; if (zipentry->uncompressed_size >= 32*1024)
if (ext[-1] != '.') ext--; goto found_rom_zip;
if (ext[-1] != '.') ext--;
for (i = 0; i < sizeof(rom_exts)/sizeof(rom_exts[0]); i++) for (i = 0; i < sizeof(rom_exts)/sizeof(rom_exts[0]); i++)
if (strcasecmp(ext, rom_exts[i]) == 0) goto found_rom_zip; if (strcasecmp(ext, rom_exts[i]) == 0)
goto found_rom_zip;
} }
/* zipfile given, but nothing found suitable for us inside */ /* zipfile given, but nothing found suitable for us inside */
@ -115,12 +126,13 @@ found_rom_zip:
gzf = zip2gz(zipfile, zipentry); gzf = zip2gz(zipfile, zipentry);
if (gzf == NULL) goto zip_failed; if (gzf == NULL) goto zip_failed;
file = malloc(sizeof(*file)); file = calloc(1, sizeof(*file));
if (file == NULL) goto zip_failed; if (file == NULL) goto zip_failed;
file->file = zipfile; file->file = zipfile;
file->param = gzf; file->param = gzf;
file->size = zipentry->uncompressed_size; file->size = zipentry->uncompressed_size;
file->type = PMT_ZIP; file->type = PMT_ZIP;
strncpy(file->ext, ext, sizeof(file->ext) - 1);
return file; return file;
zip_failed: zip_failed:
@ -132,7 +144,7 @@ zip_failed:
return NULL; return NULL;
} }
} }
else if (ext && strcasecmp(ext, "cso") == 0) else if (strcasecmp(ext, "cso") == 0)
{ {
cso_struct *cso = NULL, *tmp = NULL; cso_struct *cso = NULL, *tmp = NULL;
int size; int size;
@ -179,7 +191,7 @@ zip_failed:
cso->fpos_in = ftell(f); cso->fpos_in = ftell(f);
cso->fpos_out = 0; cso->fpos_out = 0;
cso->block_in_buff = -1; cso->block_in_buff = -1;
file = malloc(sizeof(*file)); file = calloc(1, sizeof(*file));
if (file == NULL) goto cso_failed; if (file == NULL) goto cso_failed;
file->file = f; file->file = f;
file->param = cso; file->param = cso;
@ -197,7 +209,7 @@ cso_failed:
f = fopen(path, "rb"); f = fopen(path, "rb");
if (f == NULL) return NULL; if (f == NULL) return NULL;
file = malloc(sizeof(*file)); file = calloc(1, sizeof(*file));
if (file == NULL) { if (file == NULL) {
fclose(f); fclose(f);
return NULL; return NULL;
@ -207,6 +219,7 @@ cso_failed:
file->param = NULL; file->param = NULL;
file->size = ftell(f); file->size = ftell(f);
file->type = PMT_UNCOMPRESSED; file->type = PMT_UNCOMPRESSED;
strncpy(file->ext, ext, sizeof(file->ext) - 1);
fseek(f, 0, SEEK_SET); fseek(f, 0, SEEK_SET);
#ifndef __EPOC32__ // makes things worse on Symbian #ifndef __EPOC32__ // makes things worse on Symbian
@ -421,36 +434,50 @@ static unsigned char *cd_realloc(void *old, int filesize)
return rom; return rom;
} }
static unsigned char *PicoCartAlloc(int filesize) static unsigned char *PicoCartAlloc(int filesize, int is_sms)
{ {
int alloc_size; int alloc_size;
unsigned char *rom; unsigned char *rom;
if (PicoAHW & PAHW_MCD) return cd_realloc(NULL, filesize); if (PicoAHW & PAHW_MCD)
return cd_realloc(NULL, filesize);
alloc_size=filesize+0x7ffff; if (is_sms) {
if((filesize&0x3fff)==0x200) alloc_size-=0x200; // make size power of 2 for easier banking handling
alloc_size&=~0x7ffff; // use alloc size of multiples of 512K, so that memhandlers could be set up more efficiently int s = 0, tmp = filesize;
if((filesize&0x3fff)==0x200) alloc_size+=0x200; while ((tmp >>= 1) != 0)
else if(alloc_size-filesize < 4) alloc_size+=4; // padding for out-of-bound exec protection s++;
if (filesize > (1 << s))
s++;
alloc_size = 1 << s;
}
else {
// align to 512K for memhandlers
alloc_size = (filesize + 0x7ffff) & ~0x7ffff;
}
if (alloc_size - filesize < 4)
alloc_size += 4; // padding for out-of-bound exec protection
// Allocate space for the rom plus padding // Allocate space for the rom plus padding
rom=(unsigned char *)malloc(alloc_size); rom = calloc(alloc_size, 1);
if(rom) memset(rom+alloc_size-0x80000,0,0x80000);
return rom; return rom;
} }
int PicoCartLoad(pm_file *f,unsigned char **prom,unsigned int *psize,int is_sms) int PicoCartLoad(pm_file *f,unsigned char **prom,unsigned int *psize,int is_sms)
{ {
unsigned char *rom=NULL; int size, bytes_read; unsigned char *rom;
if (f==NULL) return 1; int size, bytes_read;
if (f == NULL)
return 1;
size = f->size; size = f->size;
if (size <= 0) return 1; if (size <= 0) return 1;
size = (size+3)&~3; // Round up to a multiple of 4 size = (size+3)&~3; // Round up to a multiple of 4
// Allocate space for the rom plus padding // Allocate space for the rom plus padding
rom=PicoCartAlloc(size); rom = PicoCartAlloc(size, is_sms);
if (rom == NULL) { if (rom == NULL) {
elprintf(EL_STATUS, "out of memory (wanted %i)", size); elprintf(EL_STATUS, "out of memory (wanted %i)", size);
return 2; return 2;
@ -493,10 +520,20 @@ int PicoCartLoad(pm_file *f,unsigned char **prom,unsigned int *psize,int is_sms)
// Check for SMD: // Check for SMD:
if (size >= 0x4200 && (size&0x3fff) == 0x200 && if (size >= 0x4200 && (size&0x3fff) == 0x200 &&
((rom[0x2280] == 'S' && rom[0x280] == 'E') || (rom[0x280] == 'S' && rom[0x2281] == 'E'))) { ((rom[0x2280] == 'S' && rom[0x280] == 'E') || (rom[0x280] == 'S' && rom[0x2281] == 'E'))) {
elprintf(EL_STATUS, "SMD format detected.");
DecodeSmd(rom,size); size-=0x200; // Decode and byteswap SMD DecodeSmd(rom,size); size-=0x200; // Decode and byteswap SMD
} }
else Byteswap(rom,size); // Just byteswap else Byteswap(rom,size); // Just byteswap
} }
else
{
if (size >= 0x4200 && (size&0x3fff) == 0x200) {
elprintf(EL_STATUS, "SMD format detected.");
// at least here it's not interleaved
size -= 0x200;
memmove(rom, rom + 0x200, size);
}
}
if (prom) *prom = rom; if (prom) *prom = rom;
if (psize) *psize = size; if (psize) *psize = size;

View file

@ -270,11 +270,19 @@ void PDebugShowSprite(unsigned short *screen, int stride, int which)
void PDebugDumpMem(void) void PDebugDumpMem(void)
{ {
dump_ram(Pico.ram, "dumps/ram.bin");
dump_ram_noswab(Pico.zram, "dumps/zram.bin"); dump_ram_noswab(Pico.zram, "dumps/zram.bin");
dump_ram(Pico.vram, "dumps/vram.bin");
dump_ram(Pico.cram, "dumps/cram.bin"); dump_ram(Pico.cram, "dumps/cram.bin");
if (PicoAHW & PAHW_SMS)
{
dump_ram_noswab(Pico.vramb, "dumps/vram.bin");
}
else
{
dump_ram(Pico.ram, "dumps/ram.bin");
dump_ram(Pico.vram, "dumps/vram.bin");
dump_ram(Pico.vsram,"dumps/vsram.bin"); dump_ram(Pico.vsram,"dumps/vsram.bin");
}
if (PicoAHW & PAHW_MCD) if (PicoAHW & PAHW_MCD)
{ {
@ -296,6 +304,9 @@ void PDebugZ80Frame(void)
{ {
int lines, line_sample; int lines, line_sample;
if (PicoAHW & PAHW_SMS)
return;
if (Pico.m.pal) { if (Pico.m.pal) {
lines = 312; lines = 312;
line_sample = 68; line_sample = 68;
@ -332,3 +343,11 @@ void PDebugZ80Frame(void)
timers_cycle(); timers_cycle();
} }
void PDebugCPUStep(void)
{
if (PicoAHW & PAHW_SMS)
z80_run(1);
else
SekStepM68k();
}

View file

@ -6,4 +6,5 @@ void PDebugShowPalette(unsigned short *screen, int stride);
void PDebugShowSprite(unsigned short *screen, int stride, int which); void PDebugShowSprite(unsigned short *screen, int stride, int which);
void PDebugDumpMem(void); void PDebugDumpMem(void);
void PDebugZ80Frame(void); void PDebugZ80Frame(void);
void PDebugCPUStep(void);

View file

@ -40,7 +40,7 @@ unsigned char *HighCol=DefHighCol;
#else #else
unsigned char HighCol[8+320+8]; unsigned char HighCol[8+320+8];
#endif #endif
unsigned short DefOutBuff[320*2]; static unsigned int DefOutBuff[320*2/2];
void *DrawLineDest=DefOutBuff; // pointer to dest buffer where to draw this line to void *DrawLineDest=DefOutBuff; // pointer to dest buffer where to draw this line to
static int HighCacheA[41+1]; // caches for high layers static int HighCacheA[41+1]; // caches for high layers
@ -1269,7 +1269,7 @@ static void FinalizeLine8bit(int sh)
int len, rs = rendstatus; int len, rs = rendstatus;
static int dirty_count; static int dirty_count;
if (!sh && Pico.m.dirtyPal == 1 && DrawScanline < 222) if (!sh && Pico.m.dirtyPal == 1)
{ {
// a hack for mid-frame palette changes // a hack for mid-frame palette changes
if (!(rs & PDRAW_SONIC_MODE)) if (!(rs & PDRAW_SONIC_MODE))
@ -1306,22 +1306,6 @@ static void (*FinalizeLine)(int sh);
// -------------------------------------------- // --------------------------------------------
static void DrawBlankedLine(void)
{
int sh=(Pico.video.reg[0xC]&8)>>3; // shadow/hilight?
if (PicoScanBegin != NULL)
PicoScanBegin(DrawScanline);
BackFill(Pico.video.reg[7], sh);
if (FinalizeLine != NULL)
FinalizeLine(sh);
if (PicoScanEnd != NULL)
PicoScanEnd(DrawScanline);
}
static int DrawDisplay(int sh) static int DrawDisplay(int sh)
{ {
unsigned char *sprited = &HighLnSpr[DrawScanline][0]; unsigned char *sprited = &HighLnSpr[DrawScanline][0];
@ -1420,23 +1404,46 @@ PICO_INTERNAL void PicoFrameStart(void)
rendstatus = 0; rendstatus = 0;
if ((Pico.video.reg[12]&6) == 6) if ((Pico.video.reg[12]&6) == 6)
rendstatus |= PDRAW_INTERLACE; // interlace mode rendstatus |= PDRAW_INTERLACE; // interlace mode
if (Pico.video.reg[1] & 8)
rendstatus |= PDRAW_240LINES;
if (Pico.m.dirtyPal) Pico.m.dirtyPal = 2; // reset dirty if needed if (Pico.m.dirtyPal)
Pico.m.dirtyPal = 2; // reset dirty if needed
DrawScanline=0; DrawScanline=0;
PrepareSprites(1); PrepareSprites(1);
skip_next_line=0; skip_next_line=0;
} }
static void PicoLine(void) static void DrawBlankedLine(int line, int offs)
{
int sh = (Pico.video.reg[0xC]&8)>>3; // shadow/hilight?
if (PicoScanBegin != NULL)
PicoScanBegin(line + offs);
BackFill(Pico.video.reg[7], sh);
if (FinalizeLine != NULL)
FinalizeLine(sh);
if (PicoScanEnd != NULL)
PicoScanEnd(line + offs);
}
static void PicoLine(int line, int offs)
{ {
int sh; int sh;
if (skip_next_line>0) { skip_next_line--; return; } // skip rendering lines if (skip_next_line > 0) {
skip_next_line--;
return;
}
sh=(Pico.video.reg[0xC]&8)>>3; // shadow/hilight? sh=(Pico.video.reg[0xC]&8)>>3; // shadow/hilight?
DrawScanline = line;
if (PicoScanBegin != NULL) if (PicoScanBegin != NULL)
skip_next_line = PicoScanBegin(DrawScanline); skip_next_line = PicoScanBegin(line + offs);
// Draw screen: // Draw screen:
BackFill(Pico.video.reg[7], sh); BackFill(Pico.video.reg[7], sh);
@ -1447,31 +1454,40 @@ static void PicoLine(void)
FinalizeLine(sh); FinalizeLine(sh);
if (PicoScanEnd != NULL) if (PicoScanEnd != NULL)
skip_next_line = PicoScanEnd(DrawScanline); skip_next_line = PicoScanEnd(line + offs);
} }
void PicoDrawSync(int to, int blank_last_line) void PicoDrawSync(int to, int blank_last_line)
{ {
for (; DrawScanline < to; DrawScanline++) int line, offs = 0;
if (!(rendstatus & PDRAW_240LINES))
offs = 8;
for (line = DrawScanline; line < to; line++)
{ {
#if !CAN_HANDLE_240_LINES #if !CAN_HANDLE_240_LINES
if (DrawScanline >= 224) break; if (line >= 224) break;
#endif #endif
PicoLine(); PicoLine(line, offs);
} }
#if !CAN_HANDLE_240_LINES #if !CAN_HANDLE_240_LINES
if (DrawScanline >= 224) { DrawScanline = 240; return; } if (line >= 224) {
DrawScanline = 240;
return;
}
#endif #endif
// last line // last line
if (DrawScanline <= to) if (line <= to)
{ {
if (blank_last_line) if (blank_last_line)
DrawBlankedLine(); DrawBlankedLine(line, offs);
else PicoLine(); else PicoLine(line, offs);
DrawScanline++; line++;
} }
DrawScanline = line;
} }
void PicoDrawSetColorFormat(int which) void PicoDrawSetColorFormat(int which)
@ -1483,8 +1499,10 @@ void PicoDrawSetColorFormat(int which)
case 0: FinalizeLine = FinalizeLineBGR444; break; case 0: FinalizeLine = FinalizeLineBGR444; break;
default:FinalizeLine = NULL; break; default:FinalizeLine = NULL; break;
} }
PicoDrawSetColorFormatMode4(which);
#if OVERRIDE_HIGHCOL #if OVERRIDE_HIGHCOL
if (which) HighCol=DefHighCol; if (which)
HighCol=DefHighCol;
#endif #endif
} }

View file

@ -1,7 +1,16 @@
/*
* TODO:
* - TMS9918 modes?
* - gg mode?
* - column scroll (reg 0 bit7)
* - 224/240 line modes
* - doubled sprites
*/
#include "pico_int.h" #include "pico_int.h"
static void (*FinalizeLineM4)(void); static void (*FinalizeLineM4)(void);
static int skip_next_line; static int skip_next_line;
static int screen_offset;
#define PLANAR_PIXEL(x,p) \ #define PLANAR_PIXEL(x,p) \
t = pack & (0x80808080 >> p); \ t = pack & (0x80808080 >> p); \
@ -54,85 +63,145 @@ static int TileFlipM4(int sx,int addr,int pal)
return 1; /* Tile blank */ return 1; /* Tile blank */
} }
struct TileStrip static void draw_sprites(int scanline)
{ {
int nametab; // Position in VRAM of name table (for this tile line) struct PicoVideo *pv = &Pico.video;
int line; // Line number in pixels 0x000-0x3ff within the virtual tilemap unsigned int sprites_addr[8];
int hscroll; // Horizontal scroll value in pixels for the line unsigned int sprites_x[8];
int xmask; // X-Mask (0x1f - 0x7f) for horizontal wraparound in the tilemap unsigned char *sat;
int *hc; // cache for high tile codes and their positions int xoff = 8; // relative to HighCol, which is (screen - 8)
int cells; // cells (tiles) to draw (32 col mode doesn't need to update whole 320) int sprite_base, addr_mask;
}; int i, s, h;
static void DrawStrip(struct TileStrip *ts, int cellskip) if (pv->reg[0] & 8)
xoff = 0;
sat = (unsigned char *)Pico.vram + ((pv->reg[5] & 0x7e) << 7);
if (pv->reg[1] & 2) {
addr_mask = 0xfe; h = 16;
} else {
addr_mask = 0xff; h = 8;
}
sprite_base = (pv->reg[6] & 4) << (13-2-1);
for (i = s = 0; i < 64 && s < 8; i++)
{
int y;
y = sat[i] + 1;
if (y == 0xd1)
break;
if (y + h <= scanline || scanline < y)
continue; // not on this line
sprites_x[s] = xoff + sat[0x80 + i*2];
sprites_addr[s] = sprite_base + ((sat[0x80 + i*2 + 1] & addr_mask) << (5-1)) +
((scanline - y) << (2-1));
s++;
}
// now draw all sprites backwards
for (--s; s >= 0; s--)
TileNormM4(sprites_x[s], sprites_addr[s], 0x10);
}
// tilex_ty_prio merged to reduce register pressure
static void draw_strip(const unsigned short *nametab, int dx, int cells, int tilex_ty_prio)
{ {
int tilex,dx,ty,code=0,addr=0,cells;
int oldcode = -1, blank = -1; // The tile we know is blank int oldcode = -1, blank = -1; // The tile we know is blank
int pal=0; int addr = 0, pal = 0;
// Draw tiles across screen: // Draw tiles across screen:
tilex=((-ts->hscroll)>>3)+cellskip; for (; cells > 0; dx += 8, tilex_ty_prio++, cells--)
ty=(ts->line&7)<<1; // Y-Offset into tile
dx=((ts->hscroll-1)&7)+1;
cells = ts->cells - cellskip;
if (dx != 8) cells++; // have hscroll, need to draw 1 cell more
dx+=cellskip<<3;
for (; cells > 0; dx+=8,tilex++,cells--)
{ {
int zero; int code, zero;
code=Pico.vram[ts->nametab + (tilex & 0x1f)]; code = nametab[tilex_ty_prio & 0x1f];
if (code==blank) continue; if (code == blank)
continue;
if ((code ^ tilex_ty_prio) & 0x1000) // priority differs?
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+=ty; addr += tilex_ty_prio >> 16;
if (code&0x0400) addr^=0xe; // Y-flip if (code & 0x0400)
addr ^= 0xe; // Y-flip
pal=((code>>7)&0x10); pal = (code>>7) & 0x10;
} }
if (code&0x0200) zero = TileFlipM4(dx, addr, pal); if (code&0x0200) zero = TileFlipM4(dx, addr, pal);
else zero = TileNormM4(dx, addr, pal); else zero = TileNormM4(dx, addr, pal);
if (zero) blank=code; // We know this tile is blank now if (zero)
blank = code; // We know this tile is blank now
} }
} }
static void DrawLayer(int cellskip, int maxcells) static void DrawDisplayM4(int scanline)
{ {
struct PicoVideo *pvid=&Pico.video; struct PicoVideo *pv = &Pico.video;
struct TileStrip ts; unsigned short *nametab;
int vscroll; int line, tilex, dx, ty, cells;
int cellskip = 0; // XXX
ts.cells=maxcells; int maxcells = 32;
// Find name table:
ts.nametab=(pvid->reg[2]&0x0e) << (10-1);
// Get horizontal scroll value, will be masked later
ts.hscroll=0;//pvid->reg[8];
vscroll=0;//pvid->reg[9]; // Get vertical scroll value
// Find the line in the name table // Find the line in the name table
ts.line=(vscroll+DrawScanline)&0xff; line = pv->reg[9] + scanline; // vscroll + scanline
ts.nametab+=(ts.line>>3) << (6-1); if (line >= 224)
line -= 224;
DrawStrip(&ts, cellskip); // Find name table:
} nametab = Pico.vram;
nametab += (pv->reg[2] & 0x0e) << (10-1);
nametab += (line>>3) << (6-1);
static void DrawDisplayM4(void) dx = pv->reg[8]; // hscroll
{ if (scanline < 16 && (pv->reg[0] & 0x40))
DrawLayer(0, 32); dx = 0; // hscroll disabled for top 2 rows
tilex = ((-dx >> 3) + cellskip) & 0x1f;
ty = (line & 7) << 1; // Y-Offset into tile
cells = maxcells - cellskip;
dx = ((dx - 1) & 7) + 1;
if (dx != 8)
cells++; // have hscroll, need to draw 1 cell more
dx += cellskip << 3;
// low priority tiles
if (PicoDrawMask & PDRAW_LAYERB_ON)
draw_strip(nametab, dx, cells, tilex | 0x0000 | (ty << 16));
// sprites
if (PicoDrawMask & PDRAW_SPRITES_LOW_ON)
draw_sprites(scanline);
// high priority tiles (use virtual layer switch just for fun)
if (PicoDrawMask & PDRAW_LAYERA_ON)
draw_strip(nametab, dx, cells, tilex | 0x1000 | (ty << 16));
if (pv->reg[0] & 0x20)
// first column masked
((int *)HighCol)[2] = ((int *)HighCol)[3] = 0xe0e0e0e0;
} }
void PicoFrameStartMode4(void) void PicoFrameStartMode4(void)
{ {
DrawScanline = 0;
skip_next_line = 0; skip_next_line = 0;
screen_offset = 24;
rendstatus = PDRAW_192LINES;
if ((Pico.video.reg[0] & 6) == 6 && (Pico.video.reg[1] & 0x18)) {
rendstatus &= ~PDRAW_192LINES;
if (Pico.video.reg[1] & 0x08) {
screen_offset = 0;
rendstatus |= PDRAW_240LINES;
}
else // it's 224 lines
screen_offset = 8;
}
} }
void PicoLineMode4(int line) void PicoLineMode4(int line)
@ -142,21 +211,19 @@ void PicoLineMode4(int line)
return; return;
} }
DrawScanline = line;
if (PicoScanBegin != NULL) if (PicoScanBegin != NULL)
skip_next_line = PicoScanBegin(DrawScanline); skip_next_line = PicoScanBegin(line + screen_offset);
// Draw screen: // Draw screen:
BackFill((Pico.video.reg[7] & 0x0f) | 0x10, 0); BackFill(Pico.video.reg[7] & 0x0f, 0);
if (Pico.video.reg[1] & 0x40) if (Pico.video.reg[1] & 0x40)
DrawDisplayM4(); DrawDisplayM4(line);
if (FinalizeLineM4 != NULL) if (FinalizeLineM4 != NULL)
FinalizeLineM4(); FinalizeLineM4();
if (PicoScanEnd != NULL) if (PicoScanEnd != NULL)
skip_next_line = PicoScanEnd(DrawScanline); skip_next_line = PicoScanEnd(line + screen_offset);
} }
void PicoDoHighPal555M4(void) void PicoDoHighPal555M4(void)
@ -203,16 +270,18 @@ static void FinalizeLineRGB555M4(void)
} }
} }
static void FinalizeLine8bitM4(void)
{
memcpy32(DrawLineDest, (int *)(HighCol+8), 256/4);
}
void PicoDrawSetColorFormatMode4(int which) void PicoDrawSetColorFormatMode4(int which)
{ {
switch (which) switch (which)
{ {
case 2: FinalizeLineM4 = FinalizeLine8bitM4; break;
case 1: FinalizeLineM4 = FinalizeLineRGB555M4; break; case 1: FinalizeLineM4 = FinalizeLineRGB555M4; break;
default:FinalizeLineM4 = NULL; break; default:FinalizeLineM4 = NULL; break;
} }
#if OVERRIDE_HIGHCOL
if (which)
HighCol = DefHighCol;
#endif
} }

View file

@ -312,8 +312,12 @@ void PicoFrame(void)
void PicoFrameDrawOnly(void) void PicoFrameDrawOnly(void)
{ {
if (!(PicoAHW & PAHW_SMS)) {
PicoFrameStart(); PicoFrameStart();
PicoDrawSync(223, 0); PicoDrawSync(223, 0);
} else {
PicoFrameDrawOnlyMS();
}
} }
void PicoGetInternal(pint_t which, pint_ret_t *r) void PicoGetInternal(pint_t which, pint_ret_t *r)

View file

@ -129,6 +129,7 @@ typedef struct
void *param; /* additional file related field */ void *param; /* additional file related field */
unsigned int size; /* size */ unsigned int size; /* size */
pm_type type; pm_type type;
char ext[4];
} pm_file; } pm_file;
pm_file *pm_open(const char *path); pm_file *pm_open(const char *path);
size_t pm_read(void *ptr, size_t bytes, pm_file *stream); size_t pm_read(void *ptr, size_t bytes, pm_file *stream);
@ -170,6 +171,8 @@ extern int PicoDrawMask;
#define PDRAW_SONIC_MODE (1<<5) // mid-frame palette changes for 8bit renderer #define PDRAW_SONIC_MODE (1<<5) // mid-frame palette changes for 8bit renderer
#define PDRAW_PLANE_HI_PRIO (1<<6) // have layer with all hi prio tiles (mk3) #define PDRAW_PLANE_HI_PRIO (1<<6) // have layer with all hi prio tiles (mk3)
#define PDRAW_SHHI_DONE (1<<7) // layer sh/hi already processed #define PDRAW_SHHI_DONE (1<<7) // layer sh/hi already processed
#define PDRAW_240LINES (1<<8) // 240 line display (224 if not set)
#define PDRAW_192LINES (1<<9) // 192 line display (for SMS games)
extern int rendstatus; extern int rendstatus;
extern unsigned short HighPal[0x100]; extern unsigned short HighPal[0x100];
@ -179,9 +182,6 @@ extern unsigned char *PicoDraw2FB; // buffer for fast renderer in format (8+32
extern unsigned short *PicoCramHigh; // pointer to CRAM buff (0x40 shorts), converted to native device color (works only with 16bit for now) extern unsigned short *PicoCramHigh; // pointer to CRAM buff (0x40 shorts), converted to native device color (works only with 16bit for now)
extern void (*PicoPrepareCram)(); // prepares PicoCramHigh for renderer to use extern void (*PicoPrepareCram)(); // prepares PicoCramHigh for renderer to use
// mode4.c
void PicoDrawSetColorFormatMode4(int which);
// sound.c // sound.c
extern int PsndRate,PsndLen; extern int PsndRate,PsndLen;
extern short *PsndOut; extern short *PsndOut;

View file

@ -427,6 +427,7 @@ PICO_INTERNAL void PicoFrameFull();
void PicoFrameStartMode4(void); void PicoFrameStartMode4(void);
void PicoLineMode4(int line); void PicoLineMode4(int line);
void PicoDoHighPal555M4(void); void PicoDoHighPal555M4(void);
void PicoDrawSetColorFormatMode4(int which);
// memory.c // memory.c
PICO_INTERNAL void PicoInitPc(unsigned int pc); PICO_INTERNAL void PicoInitPc(unsigned int pc);
@ -567,6 +568,7 @@ void PicoPowerMS(void);
void PicoResetMS(void); void PicoResetMS(void);
void PicoMemSetupMS(void); void PicoMemSetupMS(void);
void PicoFrameMS(void); void PicoFrameMS(void);
void PicoFrameDrawOnlyMS(void);
// emulation event logging // emulation event logging
#ifndef EL_LOGMASK #ifndef EL_LOGMASK

View file

@ -1,3 +1,13 @@
/*
* TODO:
* - start in a state as if BIOS ran
* - remaining status flags (OVR/COL)
* - RAM support in mapper
* - region support
* - Pause button (NMI)
* - SN76496 DAC-like usage
* - H counter
*/
#include "pico_int.h" #include "pico_int.h"
#include "sound/sn76496.h" #include "sound/sn76496.h"
@ -71,10 +81,12 @@ static unsigned char z80_sms_in(unsigned short a)
case 0x40: /* V counter */ case 0x40: /* V counter */
d = Pico.video.v_counter; d = Pico.video.v_counter;
elprintf(EL_HVCNT, "V counter read: %02x", d);
break; break;
case 0x41: /* H counter */ case 0x41: /* H counter */
d = Pico.m.rotate++; d = Pico.m.rotate++;
elprintf(EL_HVCNT, "H counter read: %02x", d);
break; break;
case 0x80: case 0x80:
@ -125,24 +137,28 @@ static void z80_sms_out(unsigned short a, unsigned char d)
} }
} }
static int bank_mask;
static void write_bank(unsigned short a, unsigned char d) static void write_bank(unsigned short a, unsigned char d)
{ {
d &= 0x3f; // XXX
switch (a & 0x0f) switch (a & 0x0f)
{ {
case 0x0c: case 0x0c:
elprintf(EL_STATUS|EL_ANOMALY, "%02x written to control reg!", d);
break; break;
case 0x0d: case 0x0d:
if (d != 0) if (d != 0)
elprintf(EL_STATUS|EL_ANOMALY, "bank0 changed to %d!", d); elprintf(EL_STATUS|EL_ANOMALY, "bank0 changed to %d!", d);
break; break;
case 0x0e: case 0x0e:
d &= bank_mask;
z80_map_set(z80_read_map, 0x4000, 0x7fff, Pico.rom + (d << 14), 0); z80_map_set(z80_read_map, 0x4000, 0x7fff, Pico.rom + (d << 14), 0);
#ifdef _USE_CZ80 #ifdef _USE_CZ80
Cz80_Set_Fetch(&CZ80, 0x4000, 0x7fff, (UINT32)Pico.rom + (d << 14)); Cz80_Set_Fetch(&CZ80, 0x4000, 0x7fff, (UINT32)Pico.rom + (d << 14));
#endif #endif
break; break;
case 0x0f: case 0x0f:
d &= bank_mask;
z80_map_set(z80_read_map, 0x8000, 0xbfff, Pico.rom + (d << 14), 0); z80_map_set(z80_read_map, 0x8000, 0xbfff, Pico.rom + (d << 14), 0);
#ifdef _USE_CZ80 #ifdef _USE_CZ80
Cz80_Set_Fetch(&CZ80, 0x8000, 0xbfff, (UINT32)Pico.rom + (d << 14)); Cz80_Set_Fetch(&CZ80, 0x8000, 0xbfff, (UINT32)Pico.rom + (d << 14));
@ -168,11 +184,23 @@ void PicoResetMS(void)
void PicoPowerMS(void) void PicoPowerMS(void)
{ {
int s, tmp;
memset(&Pico.ram,0,(unsigned int)&Pico.rom-(unsigned int)&Pico.ram); memset(&Pico.ram,0,(unsigned int)&Pico.rom-(unsigned int)&Pico.ram);
memset(&Pico.video,0,sizeof(Pico.video)); memset(&Pico.video,0,sizeof(Pico.video));
memset(&Pico.m,0,sizeof(Pico.m)); memset(&Pico.m,0,sizeof(Pico.m));
Pico.m.pal = 0; Pico.m.pal = 0;
// calculate a mask for bank writes.
// ROM loader has aligned the size for us, so this is safe.
s = 0; tmp = Pico.romsize;
while ((tmp >>= 1) != 0)
s++;
if (Pico.romsize > (1 << s))
s++;
tmp = 1 << s;
bank_mask = (tmp - 1) >> 14;
PicoReset(); PicoReset();
} }
@ -207,9 +235,11 @@ void PicoFrameMS(void)
int cycles_line = is_pal ? 58020 : 58293; /* (226.6 : 227.7) * 256 */ int cycles_line = is_pal ? 58020 : 58293; /* (226.6 : 227.7) * 256 */
int cycles_done = 0, cycles_aim = 0; int cycles_done = 0, cycles_aim = 0;
int lines_vis = 192; int lines_vis = 192;
int hint; // Hint counter
int y; int y;
PicoFrameStartMode4(); PicoFrameStartMode4();
hint = pv->reg[0x0a];
for (y = 0; y < lines; y++) for (y = 0; y < lines; y++)
{ {
@ -217,9 +247,22 @@ void PicoFrameMS(void)
if (y < lines_vis) if (y < lines_vis)
PicoLineMode4(y); PicoLineMode4(y);
if (y <= lines_vis)
{
if (--hint < 0)
{
hint = pv->reg[0x0a];
pv->pending_ints |= 2;
if (pv->reg[0] & 0x10) {
elprintf(EL_INTS, "hint");
z80_int();
}
}
}
else if (y == lines_vis + 1) { else if (y == lines_vis + 1) {
Pico.video.pending_ints |= 1; pv->pending_ints |= 1;
if (Pico.video.reg[1] & 0x20) { if (pv->reg[1] & 0x20) {
elprintf(EL_INTS, "vint"); elprintf(EL_INTS, "vint");
z80_int(); z80_int();
} }
@ -232,3 +275,14 @@ void PicoFrameMS(void)
PsndGetSamplesMS(); PsndGetSamplesMS();
} }
void PicoFrameDrawOnlyMS(void)
{
int lines_vis = 192;
int y;
PicoFrameStartMode4();
for (y = 0; y < lines_vis; y++)
PicoLineMode4(y);
}

View file

@ -245,8 +245,11 @@ static int emu_cd_check(int *pregion, const char *fname_in)
static int detect_media(const char *fname) static int detect_media(const char *fname)
{ {
static const short sms_offsets[] = { 0x7ff0, 0x3ff0, 0x1ff0 }; static const short sms_offsets[] = { 0x7ff0, 0x3ff0, 0x1ff0 };
static const char *sms_exts[] = { "sms", "gg", "sg" };
static const char *md_exts[] = { "gen", "bin", "smd" };
char buff0[32], buff[32];
unsigned short *d16;
pm_file *pmf; pm_file *pmf;
char buff[32];
char ext[5]; char ext[5];
int i; int i;
@ -264,35 +267,70 @@ static int detect_media(const char *fname)
if (pmf == NULL) if (pmf == NULL)
return PM_BAD; return PM_BAD;
if (pm_read(buff, 32, pmf) != 32) { if (pm_read(buff0, 32, pmf) != 32) {
pm_close(pmf); pm_close(pmf);
return PM_BAD; return PM_BAD;
} }
if (strncasecmp("SEGADISCSYSTEM", buff + 0x00, 14) == 0 || if (strncasecmp("SEGADISCSYSTEM", buff0 + 0x00, 14) == 0 ||
strncasecmp("SEGADISCSYSTEM", buff + 0x10, 14) == 0) { strncasecmp("SEGADISCSYSTEM", buff0 + 0x10, 14) == 0) {
pm_close(pmf); pm_close(pmf);
return PM_CD; return PM_CD;
} }
/* check for SMD evil */
if (pmf->size >= 0x4200 && (pmf->size & 0x3fff) == 0x200) {
if (pm_seek(pmf, sms_offsets[0] + 0x200, SEEK_SET) == sms_offsets[0] + 0x200 &&
pm_read(buff, 16, pmf) == 16 &&
strncmp("TMR SEGA", buff, 8) == 0)
goto looks_like_sms;
/* could parse further but don't bother */
goto extension_check;
}
/* MD header? Act as TMSS BIOS here */
if (pm_seek(pmf, 0x100, SEEK_SET) == 0x100 && pm_read(buff, 16, pmf) == 16) {
if (strncmp(buff, "SEGA", 4) == 0 || strncmp(buff, " SEG", 4) == 0)
goto looks_like_md;
}
for (i = 0; i < array_size(sms_offsets); i++) { for (i = 0; i < array_size(sms_offsets); i++) {
if (pm_seek(pmf, sms_offsets[i], SEEK_SET) != sms_offsets[i]) if (pm_seek(pmf, sms_offsets[i], SEEK_SET) != sms_offsets[i])
goto not_mark3; /* actually it could be but can't be detected */ continue;
if (pm_read(buff, 16, pmf) != 16) if (pm_read(buff, 16, pmf) != 16)
goto not_mark3; continue;
if (strncasecmp("TMR SEGA", buff, 8) == 0) { if (strncmp("TMR SEGA", buff, 8) == 0)
goto looks_like_sms;
}
extension_check:
/* probably some headerless thing. Maybe check the extension after all. */
for (i = 0; i < array_size(md_exts); i++)
if (strcasecmp(pmf->ext, md_exts[i]) == 0)
goto looks_like_md;
for (i = 0; i < array_size(sms_exts); i++)
if (strcasecmp(pmf->ext, sms_exts[i]) == 0)
goto looks_like_sms;
/* If everything else fails, make a guess on the reset vector */
d16 = (unsigned short *)(buff0 + 4);
if ((((d16[0] << 16) | d16[1]) & 0xffffff) >= pmf->size) {
lprintf("bad MD reset vector, assuming SMS\n");
goto looks_like_sms;
}
looks_like_md:
pm_close(pmf);
return PM_MD_CART;
looks_like_sms:
pm_close(pmf); pm_close(pmf);
return PM_MARK3; return PM_MARK3;
} }
}
not_mark3:
pm_close(pmf);
/* the main emu function is to emulate MD, so assume MD */
return PM_MD_CART;
}
static int extract_text(char *dest, const unsigned char *src, int len, int swab) static int extract_text(char *dest, const unsigned char *src, int len, int swab)
{ {
@ -450,6 +488,7 @@ int emu_reload_rom(char *rom_fname)
shutdown_MCD(); shutdown_MCD();
PicoPatchUnload(); PicoPatchUnload();
PicoAHW = 0;
if (media_type == PM_CD) if (media_type == PM_CD)
{ {

View file

@ -1803,7 +1803,7 @@ static void debug_menu_loop(void)
{ {
case 0: case 0:
if (inp & PBTN_MOK) if (inp & PBTN_MOK)
SekStepM68k(); PDebugCPUStep();
if (inp & PBTN_MA3) { if (inp & PBTN_MA3) {
while (inp & PBTN_MA3) while (inp & PBTN_MA3)
inp = in_menu_wait_any(-1); inp = in_menu_wait_any(-1);

View file

@ -0,0 +1,8 @@
platform/common/menu.o : revision.h
revision.h: FORCE
@echo "#define REVISION \"`svn info -r HEAD | grep Revision | cut -c 11-`\"" > /tmp/r.tmp
@diff -q $@ /tmp/r.tmp > /dev/null 2>&1 || mv -f /tmp/r.tmp $@
FORCE:

View file

@ -103,7 +103,6 @@ void pemu_prep_defconfig(void)
static int EmuScanBegin16(unsigned int num) static int EmuScanBegin16(unsigned int num)
{ {
if (!(Pico.video.reg[1]&8)) num += 8;
DrawLineDest = (unsigned short *) giz_screen + 321 * num; DrawLineDest = (unsigned short *) giz_screen + 321 * num;
if ((currentConfig.EmuOpt&0x4000) && (num&1) == 0) // (Pico.m.frame_count&1)) if ((currentConfig.EmuOpt&0x4000) && (num&1) == 0) // (Pico.m.frame_count&1))
@ -115,7 +114,6 @@ static int EmuScanBegin16(unsigned int num)
static int EmuScanBegin8(unsigned int num) static int EmuScanBegin8(unsigned int num)
{ {
// draw like the fast renderer // draw like the fast renderer
if (!(Pico.video.reg[1]&8)) num += 8;
HighCol = gfx_buffer + 328 * num; HighCol = gfx_buffer + 328 * num;
return 0; return 0;

View file

@ -65,7 +65,7 @@ ifeq "$(amalgamate)" "1"
OBJS += ../../picoAll.o OBJS += ../../picoAll.o
else else
OBJS += pico/area.o pico/cart.o pico/memory.o pico/misc.o pico/pico.o pico/sek.o pico/z80if.o \ OBJS += pico/area.o pico/cart.o pico/memory.o pico/misc.o pico/pico.o pico/sek.o pico/z80if.o \
pico/videoport.o pico/draw2.o pico/draw.o pico/patch.o pico/debug.o pico/videoport.o pico/draw2.o pico/draw.o pico/mode4.o pico/sms.o pico/patch.o pico/debug.o
# Pico - CD # Pico - CD
OBJS += pico/cd/pico.o pico/cd/memory.o pico/cd/sek.o pico/cd/LC89510.o \ OBJS += pico/cd/pico.o pico/cd/memory.o pico/cd/sek.o pico/cd/LC89510.o \
pico/cd/cd_sys.o pico/cd/cd_file.o pico/cd/cue.o pico/cd/gfx_cd.o \ pico/cd/cd_sys.o pico/cd/cd_file.o pico/cd/cue.o pico/cd/gfx_cd.o \
@ -120,12 +120,7 @@ DIRS = platform platform/gp2x platform/linux platform/common pico pico/cd pico/p
all: mkdirs PicoDrive all: mkdirs PicoDrive
include ../common/common_arm.mak include ../common/common_arm.mak
include ../common/revision.mak
platform/common/menu.o : revision.h
revision.h:
@echo "#define REVISION \"`svn info | grep Revision | cut -c 11-`\"" > /tmp/r.tmp
@diff -q $@ /tmp/r.tmp > /dev/null 2>&1 || mv -f /tmp/r.tmp $@
# partial linking helps profiled builds due to section merging # partial linking helps profiled builds due to section merging
PicoDrive.o : $(OBJS) ../common/helix/$(CROSS)helix-mp3.a PicoDrive.o : $(OBJS) ../common/helix/$(CROSS)helix-mp3.a

View file

@ -220,7 +220,6 @@ static void draw_pico_ptr(void)
static int EmuScanBegin16(unsigned int num) static int EmuScanBegin16(unsigned int num)
{ {
if (!(Pico.video.reg[1]&8)) num += 8;
DrawLineDest = (unsigned short *) g_screen_ptr + g_screen_width * num; DrawLineDest = (unsigned short *) g_screen_ptr + g_screen_width * num;
return 0; return 0;
@ -228,7 +227,6 @@ static int EmuScanBegin16(unsigned int num)
static int EmuScanBegin8(unsigned int num) static int EmuScanBegin8(unsigned int num)
{ {
if (!(Pico.video.reg[1]&8)) num += 8;
DrawLineDest = (unsigned char *) g_screen_ptr + g_screen_width * num; DrawLineDest = (unsigned char *) g_screen_ptr + g_screen_width * num;
return 0; return 0;
@ -247,8 +245,6 @@ static int EmuScanEnd16_rot(unsigned int num)
{ {
if ((num & 3) != 3) if ((num & 3) != 3)
return 0; return 0;
if (!(Pico.video.reg[1] & 8))
num += 8;
rotated_blit16(g_screen_ptr, rot_buff, num + 1, rotated_blit16(g_screen_ptr, rot_buff, num + 1,
!(Pico.video.reg[12] & 1) && !(PicoOpt & POPT_EN_SOFTSCALE)); !(Pico.video.reg[12] & 1) && !(PicoOpt & POPT_EN_SOFTSCALE));
return 0; return 0;
@ -264,8 +260,6 @@ static int EmuScanEnd8_rot(unsigned int num)
{ {
if ((num & 3) != 3) if ((num & 3) != 3)
return 0; return 0;
if (!(Pico.video.reg[1] & 8))
num += 8;
rotated_blit8(g_screen_ptr, rot_buff, num + 1, rotated_blit8(g_screen_ptr, rot_buff, num + 1,
!(Pico.video.reg[12] & 1)); !(Pico.video.reg[12] & 1));
return 0; return 0;
@ -439,7 +433,6 @@ static void vidResetMode(void)
} }
else if (currentConfig.EmuOpt & EOPT_16BPP) { else if (currentConfig.EmuOpt & EOPT_16BPP) {
PicoDrawSetColorFormat(1); PicoDrawSetColorFormat(1);
PicoDrawSetColorFormatMode4(1);
if (currentConfig.EmuOpt & EOPT_WIZ_TEAR_FIX) { if (currentConfig.EmuOpt & EOPT_WIZ_TEAR_FIX) {
gp2x_video_changemode(-16); gp2x_video_changemode(-16);
PicoScanBegin = EmuScanBegin16_rot; PicoScanBegin = EmuScanBegin16_rot;

View file

@ -97,16 +97,13 @@ PicoDrive : $(OBJS) ../common/helix/helix_mp3_x86.a
$(CC) $(CFLAGS) $^ $(LDFLAGS) -lm -lpng -Wl,-Map=PicoDrive.map -o $@ $(CC) $(CFLAGS) $^ $(LDFLAGS) -lm -lpng -Wl,-Map=PicoDrive.map -o $@
mkdirs: mkdirs:
mkdir -p $(DIRS) @mkdir -p $(DIRS)
include ../common/revision.mak
pico/carthw/svp/compiler.o : ../../pico/carthw/svp/gen_arm.c pico/carthw/svp/compiler.o : ../../pico/carthw/svp/gen_arm.c
pico/pico.o pico/cd/pico.o : ../../pico/pico_cmn.c ../../pico/pico_int.h pico/pico.o pico/cd/pico.o : ../../pico/pico_cmn.c ../../pico/pico_int.h
pico/memory.o pico/cd/memory.o : ../../pico/memory_cmn.c ../../pico/pico_int.h pico/memory.o pico/cd/memory.o : ../../pico/memory_cmn.c ../../pico/pico_int.h
platform/common/menu.o : revision.h
revision.h:
@echo "#define REVISION \"`svn info | grep Revision | cut -c 11-`\"" > /tmp/r.tmp
@diff -q $@ /tmp/r.tmp > /dev/null 2>&1 || mv -f /tmp/r.tmp $@
../../cpu/musashi/m68kops.c : ../../cpu/musashi/m68kops.c :
@make -C ../../cpu/musashi @make -C ../../cpu/musashi

View file

@ -186,7 +186,6 @@ static void draw_pico_ptr(void)
static int EmuScanBegin16(unsigned int num) static int EmuScanBegin16(unsigned int num)
{ {
if (!(Pico.video.reg[1]&8)) num += 8;
DrawLineDest = (unsigned short *)g_screen_ptr + num*800 + 800/2 - 320/2; DrawLineDest = (unsigned short *)g_screen_ptr + num*800 + 800/2 - 320/2;
//int w = (Pico.video.reg[12]&1) ? 320 : 256; //int w = (Pico.video.reg[12]&1) ? 320 : 256;
//DrawLineDest = (unsigned short *)g_screen_ptr + num*w; //DrawLineDest = (unsigned short *)g_screen_ptr + num*w;
@ -204,7 +203,6 @@ static int EmuScanEnd16(unsigned int num)
int sh = Pico.video.reg[0xC]&8; int sh = Pico.video.reg[0xC]&8;
int len, mask = 0xff; int len, mask = 0xff;
if (!(Pico.video.reg[1]&8)) num += 8;
pd=(unsigned short *)g_screen_ptr + num*800*2 + 800/2 - 320*2/2; pd=(unsigned short *)g_screen_ptr + num*800*2 + 800/2 - 320*2/2;
if (Pico.m.dirtyPal) if (Pico.m.dirtyPal)

View file

@ -261,8 +261,6 @@ static void EmuScanPrepare(void)
static int EmuScanSlowBegin(unsigned int num) static int EmuScanSlowBegin(unsigned int num)
{ {
if (!(Pico.video.reg[1]&8)) num += 8;
if (!dynamic_palette) if (!dynamic_palette)
HighCol = (unsigned char *)VRAM_CACHED_STUFF + num * 512 + 8; HighCol = (unsigned char *)VRAM_CACHED_STUFF + num * 512 + 8;
@ -271,8 +269,6 @@ static int EmuScanSlowBegin(unsigned int num)
static int EmuScanSlowEnd(unsigned int num) static int EmuScanSlowEnd(unsigned int num)
{ {
if (!(Pico.video.reg[1]&8)) num += 8;
if (Pico.m.dirtyPal) { if (Pico.m.dirtyPal) {
if (!dynamic_palette) { if (!dynamic_palette) {
do_slowmode_lines(num); do_slowmode_lines(num);

View file

@ -92,7 +92,7 @@ static const unsigned long mask_numbers[] = {
static int EmuScanBegin8(unsigned int num) static int EmuScanBegin8(unsigned int num)
{ {
DrawLineDest = PicoDraw2FB + 328*num + 328*8 + 8; DrawLineDest = PicoDraw2FB + 328*num + 8;
return 0; return 0;
} }
@ -105,7 +105,7 @@ static int EmuScanEndFit0(unsigned int num)
static int u = 0, num2 = 0; static int u = 0, num2 = 0;
if(!num) u = num2 = 0; if(!num) u = num2 = 0;
DrawLineDest = PicoDraw2FB + 328*(++num2) + 328*8 + 8; DrawLineDest = PicoDraw2FB + 328*(++num2) + 8;
u += 6666; u += 6666;