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

View file

@ -270,11 +270,19 @@ void PDebugShowSprite(unsigned short *screen, int stride, int which)
void PDebugDumpMem(void)
{
dump_ram(Pico.ram, "dumps/ram.bin");
dump_ram_noswab(Pico.zram, "dumps/zram.bin");
dump_ram(Pico.vram, "dumps/vram.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");
}
if (PicoAHW & PAHW_MCD)
{
@ -296,6 +304,9 @@ void PDebugZ80Frame(void)
{
int lines, line_sample;
if (PicoAHW & PAHW_SMS)
return;
if (Pico.m.pal) {
lines = 312;
line_sample = 68;
@ -332,3 +343,11 @@ void PDebugZ80Frame(void)
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 PDebugDumpMem(void);
void PDebugZ80Frame(void);
void PDebugCPUStep(void);

View file

@ -40,7 +40,7 @@ unsigned char *HighCol=DefHighCol;
#else
unsigned char HighCol[8+320+8];
#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
static int HighCacheA[41+1]; // caches for high layers
@ -1269,7 +1269,7 @@ static void FinalizeLine8bit(int sh)
int len, rs = rendstatus;
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
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)
{
unsigned char *sprited = &HighLnSpr[DrawScanline][0];
@ -1420,23 +1404,46 @@ PICO_INTERNAL void PicoFrameStart(void)
rendstatus = 0;
if ((Pico.video.reg[12]&6) == 6)
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;
PrepareSprites(1);
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;
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?
DrawScanline = line;
if (PicoScanBegin != NULL)
skip_next_line = PicoScanBegin(DrawScanline);
skip_next_line = PicoScanBegin(line + offs);
// Draw screen:
BackFill(Pico.video.reg[7], sh);
@ -1447,31 +1454,40 @@ static void PicoLine(void)
FinalizeLine(sh);
if (PicoScanEnd != NULL)
skip_next_line = PicoScanEnd(DrawScanline);
skip_next_line = PicoScanEnd(line + offs);
}
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 (DrawScanline >= 224) break;
if (line >= 224) break;
#endif
PicoLine();
PicoLine(line, offs);
}
#if !CAN_HANDLE_240_LINES
if (DrawScanline >= 224) { DrawScanline = 240; return; }
if (line >= 224) {
DrawScanline = 240;
return;
}
#endif
// last line
if (DrawScanline <= to)
if (line <= to)
{
if (blank_last_line)
DrawBlankedLine();
else PicoLine();
DrawScanline++;
DrawBlankedLine(line, offs);
else PicoLine(line, offs);
line++;
}
DrawScanline = line;
}
void PicoDrawSetColorFormat(int which)
@ -1483,8 +1499,10 @@ void PicoDrawSetColorFormat(int which)
case 0: FinalizeLine = FinalizeLineBGR444; break;
default:FinalizeLine = NULL; break;
}
PicoDrawSetColorFormatMode4(which);
#if OVERRIDE_HIGHCOL
if (which) HighCol=DefHighCol;
if (which)
HighCol=DefHighCol;
#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"
static void (*FinalizeLineM4)(void);
static int skip_next_line;
static int screen_offset;
#define PLANAR_PIXEL(x,p) \
t = pack & (0x80808080 >> p); \
@ -54,85 +63,145 @@ static int TileFlipM4(int sx,int addr,int pal)
return 1; /* Tile blank */
}
struct TileStrip
static void draw_sprites(int scanline)
{
int nametab; // Position in VRAM of name table (for this tile line)
int line; // Line number in pixels 0x000-0x3ff within the virtual tilemap
int hscroll; // Horizontal scroll value in pixels for the line
int xmask; // X-Mask (0x1f - 0x7f) for horizontal wraparound in the tilemap
int *hc; // cache for high tile codes and their positions
int cells; // cells (tiles) to draw (32 col mode doesn't need to update whole 320)
};
struct PicoVideo *pv = &Pico.video;
unsigned int sprites_addr[8];
unsigned int sprites_x[8];
unsigned char *sat;
int xoff = 8; // relative to HighCol, which is (screen - 8)
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 pal=0;
int addr = 0, pal = 0;
// Draw tiles across screen:
tilex=((-ts->hscroll)>>3)+cellskip;
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--)
for (; cells > 0; dx += 8, tilex_ty_prio++, cells--)
{
int zero;
int code, zero;
code=Pico.vram[ts->nametab + (tilex & 0x1f)];
if (code==blank) continue;
code = nametab[tilex_ty_prio & 0x1f];
if (code == blank)
continue;
if ((code ^ tilex_ty_prio) & 0x1000) // priority differs?
continue;
if (code != oldcode) {
oldcode = code;
// Get tile address/2:
addr = (code & 0x1ff) << 4;
addr+=ty;
if (code&0x0400) addr^=0xe; // Y-flip
addr += tilex_ty_prio >> 16;
if (code & 0x0400)
addr ^= 0xe; // Y-flip
pal=((code>>7)&0x10);
pal = (code>>7) & 0x10;
}
if (code&0x0200) zero = TileFlipM4(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 TileStrip ts;
int vscroll;
ts.cells=maxcells;
// 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
struct PicoVideo *pv = &Pico.video;
unsigned short *nametab;
int line, tilex, dx, ty, cells;
int cellskip = 0; // XXX
int maxcells = 32;
// Find the line in the name table
ts.line=(vscroll+DrawScanline)&0xff;
ts.nametab+=(ts.line>>3) << (6-1);
line = pv->reg[9] + scanline; // vscroll + scanline
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)
{
DrawLayer(0, 32);
dx = pv->reg[8]; // hscroll
if (scanline < 16 && (pv->reg[0] & 0x40))
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)
{
DrawScanline = 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)
@ -142,21 +211,19 @@ void PicoLineMode4(int line)
return;
}
DrawScanline = line;
if (PicoScanBegin != NULL)
skip_next_line = PicoScanBegin(DrawScanline);
skip_next_line = PicoScanBegin(line + screen_offset);
// Draw screen:
BackFill((Pico.video.reg[7] & 0x0f) | 0x10, 0);
BackFill(Pico.video.reg[7] & 0x0f, 0);
if (Pico.video.reg[1] & 0x40)
DrawDisplayM4();
DrawDisplayM4(line);
if (FinalizeLineM4 != NULL)
FinalizeLineM4();
if (PicoScanEnd != NULL)
skip_next_line = PicoScanEnd(DrawScanline);
skip_next_line = PicoScanEnd(line + screen_offset);
}
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)
{
switch (which)
{
case 2: FinalizeLineM4 = FinalizeLine8bitM4; break;
case 1: FinalizeLineM4 = FinalizeLineRGB555M4; 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)
{
if (!(PicoAHW & PAHW_SMS)) {
PicoFrameStart();
PicoDrawSync(223, 0);
} else {
PicoFrameDrawOnlyMS();
}
}
void PicoGetInternal(pint_t which, pint_ret_t *r)

View file

@ -129,6 +129,7 @@ typedef struct
void *param; /* additional file related field */
unsigned int size; /* size */
pm_type type;
char ext[4];
} pm_file;
pm_file *pm_open(const char *path);
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_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_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 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 void (*PicoPrepareCram)(); // prepares PicoCramHigh for renderer to use
// mode4.c
void PicoDrawSetColorFormatMode4(int which);
// sound.c
extern int PsndRate,PsndLen;
extern short *PsndOut;

View file

@ -427,6 +427,7 @@ PICO_INTERNAL void PicoFrameFull();
void PicoFrameStartMode4(void);
void PicoLineMode4(int line);
void PicoDoHighPal555M4(void);
void PicoDrawSetColorFormatMode4(int which);
// memory.c
PICO_INTERNAL void PicoInitPc(unsigned int pc);
@ -567,6 +568,7 @@ void PicoPowerMS(void);
void PicoResetMS(void);
void PicoMemSetupMS(void);
void PicoFrameMS(void);
void PicoFrameDrawOnlyMS(void);
// emulation event logging
#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 "sound/sn76496.h"
@ -71,10 +81,12 @@ static unsigned char z80_sms_in(unsigned short a)
case 0x40: /* V counter */
d = Pico.video.v_counter;
elprintf(EL_HVCNT, "V counter read: %02x", d);
break;
case 0x41: /* H counter */
d = Pico.m.rotate++;
elprintf(EL_HVCNT, "H counter read: %02x", d);
break;
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)
{
d &= 0x3f; // XXX
switch (a & 0x0f)
{
case 0x0c:
elprintf(EL_STATUS|EL_ANOMALY, "%02x written to control reg!", d);
break;
case 0x0d:
if (d != 0)
elprintf(EL_STATUS|EL_ANOMALY, "bank0 changed to %d!", d);
break;
case 0x0e:
d &= bank_mask;
z80_map_set(z80_read_map, 0x4000, 0x7fff, Pico.rom + (d << 14), 0);
#ifdef _USE_CZ80
Cz80_Set_Fetch(&CZ80, 0x4000, 0x7fff, (UINT32)Pico.rom + (d << 14));
#endif
break;
case 0x0f:
d &= bank_mask;
z80_map_set(z80_read_map, 0x8000, 0xbfff, Pico.rom + (d << 14), 0);
#ifdef _USE_CZ80
Cz80_Set_Fetch(&CZ80, 0x8000, 0xbfff, (UINT32)Pico.rom + (d << 14));
@ -168,11 +184,23 @@ void PicoResetMS(void)
void PicoPowerMS(void)
{
int s, tmp;
memset(&Pico.ram,0,(unsigned int)&Pico.rom-(unsigned int)&Pico.ram);
memset(&Pico.video,0,sizeof(Pico.video));
memset(&Pico.m,0,sizeof(Pico.m));
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();
}
@ -207,9 +235,11 @@ void PicoFrameMS(void)
int cycles_line = is_pal ? 58020 : 58293; /* (226.6 : 227.7) * 256 */
int cycles_done = 0, cycles_aim = 0;
int lines_vis = 192;
int hint; // Hint counter
int y;
PicoFrameStartMode4();
hint = pv->reg[0x0a];
for (y = 0; y < lines; y++)
{
@ -217,9 +247,22 @@ void PicoFrameMS(void)
if (y < lines_vis)
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) {
Pico.video.pending_ints |= 1;
if (Pico.video.reg[1] & 0x20) {
pv->pending_ints |= 1;
if (pv->reg[1] & 0x20) {
elprintf(EL_INTS, "vint");
z80_int();
}
@ -232,3 +275,14 @@ void PicoFrameMS(void)
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 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;
char buff[32];
char ext[5];
int i;
@ -264,35 +267,70 @@ static int detect_media(const char *fname)
if (pmf == NULL)
return PM_BAD;
if (pm_read(buff, 32, pmf) != 32) {
if (pm_read(buff0, 32, pmf) != 32) {
pm_close(pmf);
return PM_BAD;
}
if (strncasecmp("SEGADISCSYSTEM", buff + 0x00, 14) == 0 ||
strncasecmp("SEGADISCSYSTEM", buff + 0x10, 14) == 0) {
if (strncasecmp("SEGADISCSYSTEM", buff0 + 0x00, 14) == 0 ||
strncasecmp("SEGADISCSYSTEM", buff0 + 0x10, 14) == 0) {
pm_close(pmf);
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++) {
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)
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);
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)
{
@ -450,6 +488,7 @@ int emu_reload_rom(char *rom_fname)
shutdown_MCD();
PicoPatchUnload();
PicoAHW = 0;
if (media_type == PM_CD)
{

View file

@ -1803,7 +1803,7 @@ static void debug_menu_loop(void)
{
case 0:
if (inp & PBTN_MOK)
SekStepM68k();
PDebugCPUStep();
if (inp & PBTN_MA3) {
while (inp & PBTN_MA3)
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)
{
if (!(Pico.video.reg[1]&8)) num += 8;
DrawLineDest = (unsigned short *) giz_screen + 321 * num;
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)
{
// draw like the fast renderer
if (!(Pico.video.reg[1]&8)) num += 8;
HighCol = gfx_buffer + 328 * num;
return 0;

View file

@ -65,7 +65,7 @@ ifeq "$(amalgamate)" "1"
OBJS += ../../picoAll.o
else
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
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 \
@ -120,12 +120,7 @@ DIRS = platform platform/gp2x platform/linux platform/common pico pico/cd pico/p
all: mkdirs PicoDrive
include ../common/common_arm.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 $@
include ../common/revision.mak
# partial linking helps profiled builds due to section merging
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)
{
if (!(Pico.video.reg[1]&8)) num += 8;
DrawLineDest = (unsigned short *) g_screen_ptr + g_screen_width * num;
return 0;
@ -228,7 +227,6 @@ static int EmuScanBegin16(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;
return 0;
@ -247,8 +245,6 @@ static int EmuScanEnd16_rot(unsigned int num)
{
if ((num & 3) != 3)
return 0;
if (!(Pico.video.reg[1] & 8))
num += 8;
rotated_blit16(g_screen_ptr, rot_buff, num + 1,
!(Pico.video.reg[12] & 1) && !(PicoOpt & POPT_EN_SOFTSCALE));
return 0;
@ -264,8 +260,6 @@ static int EmuScanEnd8_rot(unsigned int num)
{
if ((num & 3) != 3)
return 0;
if (!(Pico.video.reg[1] & 8))
num += 8;
rotated_blit8(g_screen_ptr, rot_buff, num + 1,
!(Pico.video.reg[12] & 1));
return 0;
@ -439,7 +433,6 @@ static void vidResetMode(void)
}
else if (currentConfig.EmuOpt & EOPT_16BPP) {
PicoDrawSetColorFormat(1);
PicoDrawSetColorFormatMode4(1);
if (currentConfig.EmuOpt & EOPT_WIZ_TEAR_FIX) {
gp2x_video_changemode(-16);
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 $@
mkdirs:
mkdir -p $(DIRS)
@mkdir -p $(DIRS)
include ../common/revision.mak
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/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 :
@make -C ../../cpu/musashi

View file

@ -186,7 +186,6 @@ static void draw_pico_ptr(void)
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;
//int w = (Pico.video.reg[12]&1) ? 320 : 256;
//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 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;
if (Pico.m.dirtyPal)

View file

@ -261,8 +261,6 @@ static void EmuScanPrepare(void)
static int EmuScanSlowBegin(unsigned int num)
{
if (!(Pico.video.reg[1]&8)) num += 8;
if (!dynamic_palette)
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)
{
if (!(Pico.video.reg[1]&8)) num += 8;
if (Pico.m.dirtyPal) {
if (!dynamic_palette) {
do_slowmode_lines(num);

View file

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