SNES inital commit:

Loads of warnings but now builds (and runs!) with mingw64
Only has super mario world hooked up
Missing sound, eeprom saving, and lots of things
Set to be a debug only driver for now
This commit is contained in:
tmaul 2011-12-19 19:47:54 +00:00
parent 2e64290c01
commit ee29dde329
9 changed files with 10354 additions and 2 deletions

View File

@ -1,6 +1,6 @@
alldir = burn burn/devices burn/sound burn/drivers burn/drivers/capcom burn/drivers/cave burn/drivers/cps3 \
burn/drivers/galaxian burn/drivers/irem burn/drivers/konami burn/drivers/megadrive burn/drivers/misc_post90s \
burn/drivers/misc_pre90s burn/drivers/neogeo burn/drivers/pgm burn/drivers/psikyo burn/drivers/sega \
burn/drivers/misc_pre90s burn/drivers/neogeo burn/drivers/pgm burn/drivers/psikyo burn/drivers/sega burn/drivers/snes \
burn/drivers/taito burn/drivers/toaplan burner burner/win32 cpu \
cpu/a68k cpu/arm cpu/arm7 cpu/h6280 cpu/hd6309 cpu/i8039 cpu/konami cpu/m68k cpu/m6502 cpu/m6800 cpu/m6805 \
cpu/m6809 cpu/nec cpu/s2650 cpu/sh2 cpu/z80 depend/kaillera/client depend/libs/libpng depend/libs/zlib \
@ -62,7 +62,9 @@ drvobj = d_dodonpachi.o d_donpachi.o d_esprade.o d_feversos.o d_gaia.o d_guwang
\
d_parent.o \
\
d_megadrive.o
d_megadrive.o \
\
d_snes.o
depobj := about.o bzip.o cona.o debugger.o drv.o dwmapi_core.o dynhuff.o fba_kaillera.o image_win32.o inpc.o inpcheat.o inpd.o \
inpdipsw.o inps.o ips_manager.o localise.o main.o mdi.o media.o memcard.o menu.o misc_win32.o neocdlist.o neocdsel.o \
@ -137,6 +139,8 @@ depobj := about.o bzip.o cona.o debugger.o drv.o dwmapi_core.o dynhuff.o fba_ka
\
megadrive.o \
\
snes_65816.o snes_spc700.o snes_mem.o snes_ppu.o snes_main.o snes_io.o
ifdef DEBUG
depobj += m68kdasm.o

View File

@ -0,0 +1,103 @@
#include "snes.h"
unsigned char DoSnesReset = 0;
unsigned char SnesJoy1[12] = {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0};
static struct BurnInputInfo SnesInputList[] =
{
{"P1 Start", BIT_DIGITAL, SnesJoy1 + 7, "p1 start" },
{"P1 Up", BIT_DIGITAL, SnesJoy1 + 0, "p1 up" },
{"P1 Down", BIT_DIGITAL, SnesJoy1 + 1, "p1 down" },
{"P1 Left", BIT_DIGITAL, SnesJoy1 + 2, "p1 left" },
{"P1 Right", BIT_DIGITAL, SnesJoy1 + 3, "p1 right" },
{"P1 Button A", BIT_DIGITAL, SnesJoy1 + 6, "p1 fire 1" },
{"P1 Button B", BIT_DIGITAL, SnesJoy1 + 4, "p1 fire 2" },
{"P1 Button C", BIT_DIGITAL, SnesJoy1 + 5, "p1 fire 3" },
{"P1 Button X", BIT_DIGITAL, SnesJoy1 + 10, "p1 fire 4" },
{"P1 Button Y", BIT_DIGITAL, SnesJoy1 + 9, "p1 fire 5" },
{"P1 Button Z", BIT_DIGITAL, SnesJoy1 + 8, "p1 fire 6" },
{"P1 Mode", BIT_DIGITAL, SnesJoy1 + 11, "p1 select" },
{"Reset" , BIT_DIGITAL , &DoSnesReset , "reset" },
};
STDINPUTINFO(Snes)
static struct BurnDIPInfo SnesDIPList[]=
{
// Default Values
{0x11, 0xff, 0xff, 0x02, NULL },
};
STDDIPINFO(Snes)
static struct BurnRomInfo rSuperMarioWorldEuropeRev1RomDesc[] = {
{ "Super Mario World (Europe) (Rev 1).sfc", 524288, 0xb47f5f20, BRF_ESS | BRF_PRG },
};
STD_ROM_PICK(rSuperMarioWorldEuropeRev1)
STD_ROM_FN(rSuperMarioWorldEuropeRev1)
struct BurnDriverD BurnDrvrSuperMarioWorldEuropeRev1 = {
"Super Mario World (Europe) (Rev 1)", NULL, NULL, NULL, "1986",
"Super Mario World (Europe) (Rev 1)\0", NULL, "Nintendo", "Miscellaneous",
L"Super Mario World (Europe) (Rev 1)", NULL, NULL, NULL,
BDF_GAME_WORKING|BDF_16BIT_ONLY , 2, HARDWARE_SEGA_MEGADRIVE, GBF_SHOOT,0 ,
NULL, rSuperMarioWorldEuropeRev1RomInfo, rSuperMarioWorldEuropeRev1RomName,NULL,NULL, SnesInputInfo, SnesDIPInfo,
SnesInit, SnesExit, SnesFrame, NULL, SnesScan,
NULL,0x6000,512 , 244, 4, 3
};
static struct BurnRomInfo rSuperMarioWorldEuropeRomDesc[] = {
{ "Super Mario World (Europe).sfc", 524288, 0x3c41070f, BRF_ESS | BRF_PRG },
};
STD_ROM_PICK(rSuperMarioWorldEurope)
STD_ROM_FN(rSuperMarioWorldEurope)
struct BurnDriverD BurnDrvrSuperMarioWorldEurope = {
"Super Mario World (Europe)", NULL, NULL, NULL, "1986",
"Super Mario World (Europe)\0", NULL, "Nintendo", "Miscellaneous",
L"Super Mario World (Europe)", NULL, NULL, NULL,
BDF_GAME_WORKING|BDF_16BIT_ONLY , 2, HARDWARE_SEGA_MEGADRIVE, GBF_SHOOT,0 ,
NULL, rSuperMarioWorldEuropeRomInfo, rSuperMarioWorldEuropeRomName,NULL,NULL, SnesInputInfo, SnesDIPInfo,
SnesInit, SnesExit, SnesFrame, NULL, SnesScan,
NULL,0x6000,512 , 244, 4, 3
};
static struct BurnRomInfo rSuperMarioWorldJapanRomDesc[] = {
{ "Super Mario World (Japan).sfc", 524288, 0xec0ddac, BRF_ESS | BRF_PRG },
};
STD_ROM_PICK(rSuperMarioWorldJapan)
STD_ROM_FN(rSuperMarioWorldJapan)
struct BurnDriverD BurnDrvrSuperMarioWorldJapan = {
"Super Mario World (Japan)", NULL, NULL, NULL, "1986",
"Super Mario World (Japan)\0", NULL, "Nintendo", "Miscellaneous",
L"Super Mario World (Japan)", NULL, NULL, NULL,
BDF_GAME_WORKING|BDF_16BIT_ONLY , 2, HARDWARE_SEGA_MEGADRIVE, GBF_SHOOT,0 ,
NULL, rSuperMarioWorldJapanRomInfo, rSuperMarioWorldJapanRomName,NULL,NULL, SnesInputInfo, SnesDIPInfo,
SnesInit, SnesExit, SnesFrame, NULL, SnesScan,
NULL,0x6000,512 , 244, 4, 3
};
static struct BurnRomInfo rSuperMarioWorldUSARomDesc[] = {
{ "Super Mario World (USA).sfc", 524288, 0xb19ed489, BRF_ESS | BRF_PRG },
};
STD_ROM_PICK(rSuperMarioWorldUSA)
STD_ROM_FN(rSuperMarioWorldUSA)
struct BurnDriverD BurnDrvrSuperMarioWorldUSA = {
"Super Mario World (USA)", NULL, NULL, NULL, "1986",
"Super Mario World (USA)\0", NULL, "Nintendo", "Miscellaneous",
L"Super Mario World (USA)", NULL, NULL, NULL,
BDF_GAME_WORKING|BDF_16BIT_ONLY , 2, HARDWARE_SEGA_MEGADRIVE, GBF_SHOOT,0 ,
NULL, rSuperMarioWorldUSARomInfo, rSuperMarioWorldUSARomName,NULL,NULL, SnesInputInfo, SnesDIPInfo,
SnesInit, SnesExit, SnesFrame, NULL, SnesScan,
NULL,0x6000,512 , 244, 4, 3
};

View File

@ -0,0 +1,275 @@
#pragma once
#include "tiles_generic.h"
#include "bitswap.h"
/* Useful definitions */
#define SNES_SCR_WIDTH 256 /* 32 characters 8 pixels wide */
#define SNES_SCR_HEIGHT_NTSC 224 /* Can be 224 or 240 height */
#define SNES_SCR_HEIGHT_PAL 274 /* ??? */
#define SNES_VTOTAL_NTSC 262 /* Maximum number of lines for NTSC systems */
#define SNES_VTOTAL_PAL 312 /* Maximum number of lines for PAL systems */
#define SNES_HTOTAL 341 /* Maximum number pixels per line (incl. hblank) */
#define SNES_DMA_BASE 0x4300 /* Base DMA register address */
#define SNES_MODE_20 0x1 /* Lo-ROM cart */
#define SNES_MODE_21 0x2 /* Hi-ROM cart */
#define SNES_MODE_22 0x4 /* Extended Lo-ROM cart - SDD-1 */
#define SNES_MODE_25 0x8 /* Extended Hi-ROM cart */
#define SNES_NTSC 0x00
#define SNES_PAL 0x10
#define SNES_VRAM_SIZE 0x20000 /* 128kb of video ram */
#define SNES_CGRAM_SIZE 0x202 /* 256 16-bit colours + 1 tacked on 16-bit colour for fixed colour */
#define SNES_OAM_SIZE 0x440 /* 1088 bytes of Object Attribute Memory */
#define SNES_SPCRAM_SIZE 0x10000 /* 64kb of spc700 ram */
#define SNES_EXROM_START 0x1000000
#define FIXED_COLOUR 256 /* Position in cgram for fixed colour */
/* Definitions for PPU Memory-Mapped registers */
#define INIDISP 0x2100
#define OBSEL 0x2101
#define OAMADDL 0x2102
#define OAMADDH 0x2103
#define OAMDATA 0x2104
#define BGMODE 0x2105 /* abcdefff = abcd: bg4-1 tile size | e: BG3 high priority | f: mode */
#define MOSAIC 0x2106 /* xxxxabcd = x: pixel size | abcd: affects bg 1-4 */
#define BG1SC 0x2107
#define BG2SC 0x2108
#define BG3SC 0x2109
#define BG4SC 0x210A
#define BG12NBA 0x210B
#define BG34NBA 0x210C
#define BG1HOFS 0x210D
#define BG1VOFS 0x210E
#define BG2HOFS 0x210F
#define BG2VOFS 0x2110
#define BG3HOFS 0x2111
#define BG3VOFS 0x2112
#define BG4HOFS 0x2113
#define BG4VOFS 0x2114
#define VMAIN 0x2115 /* i---ffrr = i: Increment timing | f: Full graphic | r: increment rate */
#define VMADDL 0x2116 /* aaaaaaaa = a: LSB of vram address */
#define VMADDH 0x2117 /* aaaaaaaa = a: MSB of vram address */
#define VMDATAL 0x2118 /* dddddddd = d: data to be written */
#define VMDATAH 0x2119 /* dddddddd = d: data to be written */
#define M7SEL 0x211A /* ab----yx = a: screen over | y: vertical flip | x: horizontal flip */
#define M7A 0x211B /* aaaaaaaa = a: COSINE rotate angle / X expansion */
#define M7B 0x211C /* aaaaaaaa = a: SINE rotate angle / X expansion */
#define M7C 0x211D /* aaaaaaaa = a: SINE rotate angle / Y expansion */
#define M7D 0x211E /* aaaaaaaa = a: COSINE rotate angle / Y expansion */
#define M7X 0x211F
#define M7Y 0x2120
#define CGADD 0x2121
#define CGDATA 0x2122
#define W12SEL 0x2123
#define W34SEL 0x2124
#define WOBJSEL 0x2125
#define WH0 0x2126 /* pppppppp = p: Left position of window 1 */
#define WH1 0x2127 /* pppppppp = p: Right position of window 1 */
#define WH2 0x2128 /* pppppppp = p: Left position of window 2 */
#define WH3 0x2129 /* pppppppp = p: Right position of window 2 */
#define WBGLOG 0x212A /* aabbccdd = a: BG4 params | b: BG3 params | c: BG2 params | d: BG1 params */
#define WOBJLOG 0x212B /* ----ccoo = c: Colour window params | o: Object window params */
#define TM 0x212C
#define TS 0x212D
#define TMW 0x212E
#define TSW 0x212F
#define CGWSEL 0x2130
#define CGADSUB 0x2131
#define COLDATA 0x2132
#define SETINI 0x2133
#define MPYL 0x2134
#define MPYM 0x2135
#define MPYH 0x2136
#define SLHV 0x2137
#define ROAMDATA 0x2138
#define RVMDATAL 0x2139
#define RVMDATAH 0x213A
#define RCGDATA 0x213B
#define OPHCT 0x213C
#define OPVCT 0x213D
#define STAT77 0x213E
#define STAT78 0x213F
#define APU00 0x2140
#define APU01 0x2141
#define APU02 0x2142
#define APU03 0x2143
#define WMDATA 0x2180
#define WMADDL 0x2181
#define WMADDM 0x2182
#define WMADDH 0x2183
/* Definitions for CPU Memory-Mapped registers */
extern UINT16 snes_cgram[SNES_CGRAM_SIZE];
extern UINT32 snesPal[0x20000];
/*SPC700*/
extern double spccycles;
extern double spctotal2;
extern double spctotal3;
void execspc();
static inline void clockspc(int cyc)
{
spccycles+=cyc;
if (spccycles>0) execspc();
}
/*65816*/
/*Registers*/
typedef union
{
UINT16 w;
struct
{
#ifndef BIG_ENDIAN
UINT8 l,h;
#else
UINT8 h,l;
#endif
} b;
} reg;
extern reg a,x,y,s;
extern unsigned long pbr,dbr;
extern UINT16 pc,dp;
extern INT32 ins,output;
extern INT32 timetolive;
extern INT32 inwai;
/*Opcode table*/
extern void (*opcodes[256][5])();
/*CPU modes : 0 = X1M1
1 = X1M0
2 = X0M1
3 = X0M0
4 = emulation*/
extern INT32 cpumode;
/*Current opcode*/
extern UINT8 opcode;
/*Global cycles count*/
extern INT32 cycles;
/*Memory*/
extern UINT8 *ram;
extern UINT8 *rom;
extern UINT8 *memlookup[2048];
extern UINT8 memread[2048],memwrite[2048];
extern UINT8 accessspeed[2048];
extern INT32 lorom;
UINT8 readmeml(unsigned long adress);
void writememl(unsigned long adress, unsigned char v);
static inline unsigned char readmem(unsigned long adress)
{
cycles-=accessspeed[(adress>>13)&0x7FF];
clockspc(accessspeed[(adress>>13)&0x7FF]);
if (memread[(adress>>13)&0x7FF])
{
return memlookup[(adress>>13)&0x7FF][adress&0x1FFF];
}
return readmeml(adress);
}
static inline void writemem(unsigned long ad, unsigned char v)
{
cycles-=accessspeed[(ad>>13)&0x7FF];
clockspc(accessspeed[(ad>>13)&0x7FF]);
if (memwrite[(ad>>13)&0x7FF])
memlookup[(ad>>13)&0x7FF][(ad)&0x1FFF]=v;
else
writememl(ad,v);
}
#define readmemw(a) (readmem(a))|((readmem((a)+1))<<8)
#define writememw(a,v) writemem(a,(v)&0xFF); writemem((a)+1,(v)>>8)
#define writememw2(a,v) writemem((a)+1,(v)>>8); writemem(a,(v)&0xFF)
/*Video*/
extern INT32 nmi,vbl,joyscan;
extern INT32 nmienable;
extern INT32 ppumask;
extern INT32 yirq,xirq,irqenable,irq;
extern INT32 lines;
extern int pal;
/*DMA registers*/
extern unsigned short dmadest[8],dmasrc[8],dmalen[8];
extern unsigned long hdmaaddr[8],hdmaaddr2[8];
extern unsigned char dmabank[8],dmaibank[8],dmactrl[8],hdmastat[8],hdmadat[8];
extern int hdmacount[8];
extern unsigned char hdmaena;
// debugging
void snemlog( TCHAR *format, ...);
// ppu stuff
void resetppu();
void initppu();
void initspc();
void makeopcodetable();
unsigned char readppu(unsigned short addr);
void writeppu(unsigned short addr, unsigned char val);
void drawline(int line);
// io stuff
void readjoy();
unsigned char readio(unsigned short addr);
unsigned char readjoyold(unsigned short addr);
void writeio(unsigned short addr, unsigned char val);
void writejoyold(unsigned short addr, unsigned char val);
struct CPU_P
{
int c,z,i,d,b,v,n,m,x,e;
};
extern CPU_P p;
// spc stuff
unsigned char readfromspc(unsigned short addr);
void writetospc(unsigned short addr, unsigned char val);
void resetspc();
extern unsigned char voiceon;
//snes.cpp stuff
// cpu stuff
void irq65816();
void nmi65816();
void reset65816();
extern int skipz,setzf;
//mem stuff
void allocmem();
void initsnem();
void resetsnem();
void execframe();
void loadrom(char *fn);
void initmem();
void freemem();
extern unsigned short srammask;
extern unsigned char *sram;
extern INT32 spctotal;
// snes_main.cpp
INT32 SnesInit();
INT32 SnesExit();
INT32 SnesFrame();
INT32 SnesScan(INT32 nAction,INT32 *pnMin);
extern unsigned char DoSnesReset;
extern unsigned char SnesJoy1[12];

File diff suppressed because it is too large Load Diff

View File

@ -0,0 +1,349 @@
/*Snem 0.1 by Tom Walker
I/O, or $42xx*/
#include "snes.h"
extern int intthisline;
int dmaops=0;
extern int framenum;
extern int oldnmi;
int padpos,padstat;
unsigned short pad[4];
void readjoy()
{
pad[0]=0;
if (SnesJoy1[6])
pad[0]|=0x8000;
if (SnesJoy1[4])
pad[0]|=0x4000;
if (SnesJoy1[11])
pad[0]|=0x2000;
if (SnesJoy1[7])
pad[0]|=0x1000;
if (SnesJoy1[0])
pad[0]|=0x0800;
if (SnesJoy1[1])
pad[0]|=0x0400;
if (SnesJoy1[2])
pad[0]|=0x0200;
if (SnesJoy1[3])
pad[0]|=0x0100;
if (SnesJoy1[5])
pad[0]|=0x0080;
if (SnesJoy1[10])
pad[0]|=0x0040;
if (SnesJoy1[9])
pad[0]|=0x0020;
if (SnesJoy1[8])
pad[0]|=0x0010;
padpos=16;
// printf("Read joy\n");
}
unsigned char readjoyold(unsigned short addr)
{
int temp;
if (addr==0x4016)
{
temp=pad[0]>>(padpos^15);
if (!(padstat&1)) padpos++;
if (padpos>15) temp=1;
// printf("Read 4016 %i %i %02X %06X\n",temp&1,padpos,padstat,pbr|pc);
return temp&1;
}
return 0xFF;
}
void writejoyold(unsigned short addr, unsigned char val)
{
if (addr==0x4016)
{
// printf("Write 4016 %02X\n",val);
if ((val&1) && !(padstat&1)) padpos=0;
padstat=val;
}
}
unsigned short mulr,divc,divr;
unsigned char mula,mulb,divb;
void writeio(unsigned short addr, unsigned char val)
{
int c,d=0,offset=0,speed;
unsigned char temp;
int delay=0;
switch (addr&0x1FF)
{
case 0x00:
nmienable=val&0x80;
irqenable=(val>>4)&3;
if (!irqenable) irq=0;
break;
case 0x02: /*Multiplicand A*/
mula=val;
return;
case 0x03: /*Multiplier B*/
mulb=val;
mulr=mula*mulb;
return;
case 0x04: /*Dividend C Low*/
divc&=0xFF00;
divc|=val;
return;
case 0x05: /*Dividend C High*/
divc&=0xFF;
divc|=(val<<8);
return;
case 0x06: /*Divisor B*/
divb=val;
if (divb)
{
divr=divc/divb;
mulr=divc%divb;
}
else
{
divr=0xFFFF;
mulr=divc;
}
return;
case 0x07: /*X low*/
xirq=(xirq&0x100)|val;
intthisline=0;
break;
case 0x08: /*X high*/
xirq=(xirq&0xFF)|(val&0x100);
intthisline=0;
break;
case 0x09: /*Y low*/
yirq=(yirq&0x100)|val;
break;
case 0x0A: /*Y high*/
yirq=(yirq&0xFF)|(val&0x100);
break;
case 0x0B: /*DMA enable*/
for (c=1;c<0x100;c<<=1)
{
if (val&c)
{
/* if (getvramaddr()==0xB000)
{
dmaops++;
if (dmaops==3) return;
}*/
// if (!dmalen[d]) printf("DMA %i ctrl %02X src %06X dest %02X size %04X %i\n",d,dmactrl[d],(dmabank[d]<<16)|dmasrc[d],dmadest[d],dmalen[d],dmaops);
do
{
if (dmactrl[d]&0x80)
{
// printf("Dest %04X+%04X SRC %06X %04X\n",dmadest[d],offset,dmabank[d],dmasrc[d]);
temp=readppu(dmadest[d]+offset);
writemem((dmabank[d]<<16)|dmasrc[d],temp);
}
else
{
temp=readmem((dmabank[d]<<16)|dmasrc[d]);
// if (dmabank[d]==0 && dmasrc[d]<0x2000) printf("%02X %06X %04X\n",temp,dmabank[d]|dmasrc[d],dmalen[d]);
writeppu(dmadest[d]+offset,temp);
}
if (!(dmactrl[d]&8))
{
if (dmactrl[d]&0x10) dmasrc[d]--;
else dmasrc[d]++;
}
switch (dmactrl[d]&7)
{
case 0: /*1 address write twice*/
case 2: /*1 address write once*/
break;
case 1: /*2 addresses*/
offset++;
offset&=1;
break;
default:
snemlog(L"Bad DMA mode %i\n",dmactrl[d]&7);
}
dmalen[d]--;
// delay+=16;
} while (dmalen[d]!=0);
}
d++;
}
// cycles-=delay;
// clockspc(delay);
break;
case 0x0C: /*HDMA enable*/
hdmaena=val;
// printf("HDMA ena : %02X %06X %i %i\n",val,pbr|pc,framenum,lines);
break;
case 0x0D: /*ROM speed select*/
if (val&1) speed=6;
else speed=8;
for (c=192;c<256;c++)
{
for (d=0;d<8;d++)
{
accessspeed[(c<<3)|d]=speed;
}
}
for (c=128;c<192;c++)
{
accessspeed[(c<<3)|4]=accessspeed[(c<<3)|5]=speed;
accessspeed[(c<<3)|6]=accessspeed[(c<<3)|7]=speed;
}
break;
case 0x100: case 0x110: case 0x120: case 0x130: /*DMA control*/
case 0x140: case 0x150: case 0x160: case 0x170:
dmactrl[(addr>>4)&7]=val;
// printf("Write ctrl %i %02X %06X\n",(addr>>4)&7,val,pbr|pc);
break;
case 0x101: case 0x111: case 0x121: case 0x131: /*DMA dest*/
case 0x141: case 0x151: case 0x161: case 0x171:
dmadest[(addr>>4)&7]=val|0x2100;
break;
case 0x102: case 0x112: case 0x122: case 0x132: /*DMA src low*/
case 0x142: case 0x152: case 0x162: case 0x172:
dmasrc[(addr>>4)&7]=(dmasrc[(addr>>4)&7]&0xFF00)|val;
break;
case 0x103: case 0x113: case 0x123: case 0x133: /*DMA src high*/
case 0x143: case 0x153: case 0x163: case 0x173:
dmasrc[(addr>>4)&7]=(dmasrc[(addr>>4)&7]&0xFF)|(val<<8);
break;
case 0x104: case 0x114: case 0x124: case 0x134: /*DMA src bank*/
case 0x144: case 0x154: case 0x164: case 0x174:
dmabank[(addr>>4)&7]=val;
break;
case 0x105: case 0x115: case 0x125: case 0x135: /*DMA size low*/
case 0x145: case 0x155: case 0x165: case 0x175:
dmalen[(addr>>4)&7]=(dmalen[(addr>>4)&7]&0xFF00)|val;
break;
case 0x106: case 0x116: case 0x126: case 0x136: /*DMA size high*/
case 0x146: case 0x156: case 0x166: case 0x176:
dmalen[(addr>>4)&7]=(dmalen[(addr>>4)&7]&0xFF)|(val<<8);
break;
case 0x107: case 0x117: case 0x127: case 0x137: /*HDMA ibank*/
case 0x147: case 0x157: case 0x167: case 0x177:
dmaibank[(addr>>4)&7]=val;
break;
case 0x108: case 0x118: case 0x128: case 0x138:
case 0x148: case 0x158: case 0x168: case 0x178:
hdmaaddr[(addr>>4)&7]=(hdmaaddr[(addr>>4)&7]&0xFF00)|val;
// printf("HDMA addr %i now %04X %06X\n",(addr>>4)&7,hdmaaddr[(addr>>4)&7],pbr|pc);
break;
case 0x109: case 0x119: case 0x129: case 0x139:
case 0x149: case 0x159: case 0x169: case 0x179:
hdmaaddr[(addr>>4)&7]=(hdmaaddr[(addr>>4)&7]&0xFF)|(val<<8);
// printf("HDMA addr %i now %04X %06X\n",(addr>>4)&7,hdmaaddr[(addr>>4)&7],pbr|pc);
break;
case 0x10A: case 0x11A: case 0x12A: case 0x13A: /*HDMA lines left*/
case 0x14A: case 0x15A: case 0x16A: case 0x17A:
hdmacount[(addr>>4)&7]=val;
break;
}
}
unsigned char readio(unsigned short addr)
{
int temp=0;
if (addr==0x4016 || addr==0x4017)
{
// printf("Read oldstyle joypad\n");
// dumpregs();
// exit(-1);
}
// if (addr!=0x4218 && addr!=0x4219) snemlog("Read IO %04X %02X:%04X %04X\n",addr,pbr>>16,pc,dp);
switch (addr&0x1FF)
{
case 0:
return 0;
case 0xB: /*DMA enable*/
return 0;
case 0x0C: /*HDMA enable*/
return hdmaena;
case 0x10: /*NMI*/
if (nmi) temp=0x80;
nmi=oldnmi=0;
return temp;
case 0x11: /*IRQ*/
if (irq) temp=0x80;
irq=0;
return temp;
case 0x12: /*VBL*/
if (vbl) temp|=0x80;
if (joyscan) temp|=1;
if (cycles<340) temp|=0x40; /*340=1364-(256 pixels * 4)*/
return temp;
case 0x13: /*I/O port*/
return 0;
case 0x14: /*Division Result Low*/
// printf("Read div low\n");
return divr;
case 0x15: /*Division Result High*/
// printf("Read div high\n");
return divr>>8;
case 0x16: /*Multiplication Result Low*/
// printf("Read mul low\n");
return mulr;
case 0x17: /*Multiplication Result High*/
// printf("Read mul high\n");
return mulr>>8;
case 0x18: /*Joypad #1*/
// printf("Read joy low %02X %06X %i\n",pad[0]>>8,pbr|pc,ins);
return pad[0]&0xFF;
case 0x19:
// printf("Read joy high %02X %06X\n",pad[0]&0xFF,pbr|pc);
return pad[0]>>8;
case 0x1A: case 0x1B: /*Joypad #2*/
case 0x1C: case 0x1D: /*Joypad #3*/
case 0x1E: case 0x1F: /*Joypad #4*/
return 0;
case 0x100: case 0x110: case 0x120: case 0x130: /*DMA control*/
case 0x140: case 0x150: case 0x160: case 0x170:
return dmactrl[(addr>>4)&7];
break;
case 0x101: case 0x111: case 0x121: case 0x131: /*DMA dest*/
case 0x141: case 0x151: case 0x161: case 0x171:
return dmadest[(addr>>4)&7]&0xFF;
break;
case 0x102: case 0x112: case 0x122: case 0x132: /*DMA src low*/
case 0x142: case 0x152: case 0x162: case 0x172:
return dmasrc[(addr>>4)&7]&0xFF;
break;
case 0x103: case 0x113: case 0x123: case 0x133: /*DMA src high*/
case 0x143: case 0x153: case 0x163: case 0x173:
return dmasrc[(addr>>4)&7]>>8;
break;
case 0x104: case 0x114: case 0x124: case 0x134: /*DMA src bank*/
case 0x144: case 0x154: case 0x164: case 0x174:
return dmabank[(addr>>4)&7];
break;
case 0x105: case 0x115: case 0x125: case 0x135: /*DMA size low*/
case 0x145: case 0x155: case 0x165: case 0x175:
return dmalen[(addr>>4)&7]&0xFF;
break;
case 0x106: case 0x116: case 0x126: case 0x136: /*DMA size high*/
case 0x146: case 0x156: case 0x166: case 0x176:
return dmalen[(addr>>4)&7]>>8;
break;
case 0x107: case 0x117: case 0x127: case 0x137: /*HDMA indirect bank*/
case 0x147: case 0x157: case 0x167: case 0x177:
return dmaibank[(addr>>4)&7]>>8;
break;
default:
return 0;
}
}

View File

@ -0,0 +1,185 @@
#include <stdio.h>
#include "snes.h"
static INT32 frames;
INT32 intthisline;
INT32 framenum;
INT32 oldnmi=0;
INT32 spcclck;
double spcclck2,spcclck3;
void __cdecl snemlog(TCHAR *format,...)
{
bprintf(0,format);
}
void SnesReset()
{
resetppu();
resetspc();
reset65816();
frames=0;
}
INT32 SnesInit()
{
INT32 nret = 0;
INT32 counter=0;
char name[22];
INT32 len;
UINT16 temp,temp2;
allocmem();
initppu();
initspc();
makeopcodetable();
// initdsp();
SnesReset();
spccycles=-10000;
rom=(UINT8*)BurnMalloc(4096*1024);
BurnLoadRom(rom,0,0);
temp=rom[0x7FDC]|(rom[0x7FDD]<<8);
temp2=rom[0x7FDE]|(rom[0x7FDF]<<8);
if ((temp|temp2)==0xFFFF)
{
lorom=1;
}
else
{
lorom=0;
}
initmem();
if (((readmem(0xFFFD)<<8)|readmem(0xFFFC))==0xFFFF)
{
lorom^=1;
initmem();
}
len=counter;//-0x10000;
for (counter=0;counter<21;counter++)
{
name[counter]=readmem(0xFFC0+counter);
}
name[21]=0;
srammask=(1<<(readmem(0xFFD8)+10))-1;
if (!readmem(0xFFD8))
{
srammask=0;
}
if (readmem(0xFFD9)>1)
{
pal=1;
}
else
{
pal=0;
}
if (srammask)
{
memset(sram,0,srammask+1);
}
memset(ram,0x55,128*1024);
SnesReset();
return nret;
}
INT32 SnesExit()
{
freemem();
return 0;
}
INT32 SnesFrame()
{
if (DoSnesReset)
{
SnesReset();
}
nmi=vbl=0;
framenum++;
if (framenum==50)
{
spcclck=spctotal;
spcclck2=spctotal2;
spcclck3=spctotal3;
spctotal=0;
spctotal2=0.0f;
spctotal3=0.0f;
}
for (lines=0;lines<((pal)?312:262);lines++)
{
// snemlog("%i %02X:%04X %i %i %i\n",lines,pbr>>16,pc,irqenable,xirq,yirq);
if ((irqenable==2/* || irqenable==1*/) && (lines==yirq))
{
irq=1;
/*snemlog("Raise IRQ line %i %02X\n",lines,lines);*/
}
if (lines<225)
{
drawline(lines);
}
cycles+=1364;
intthisline=0;
while (cycles>0)
{
opcode=readmem(pbr|pc);
pc++;
opcodes[opcode][cpumode]();
if ((((irqenable==3) && (lines==yirq)) || (irqenable==1)) && !intthisline)
{
if (((1364-cycles)>>2)>=xirq)
{
irq=1;
intthisline=1;
// snemlog("Raise IRQ horiz %i %i\n",lines,irqenable);
}
}
ins++;
if (oldnmi!=nmi && nmienable && nmi)
{
nmi65816();
}
else if (irq && (!p.i || inwai))
{
irq65816();
}
oldnmi=nmi;
}
if (lines==0xE0)
{
nmi=1;
vbl=joyscan=1;
readjoy();
}
if (lines==0xE3)
{
joyscan=0;
}
}
frames++;
return 0;
}
INT32 SnesScan(INT32 nAction,INT32 *pnMin)
{
return 0;
}

View File

@ -0,0 +1,278 @@
#include <stdio.h>
#include "snes.h"
extern int pal;
UINT16 srammask=0;
UINT8 *sram;
UINT8 *ram;
UINT8 *rom;
UINT8 *memlookup[2048];
UINT8 memread[2048];
UINT8 memwrite[2048];
UINT8 accessspeed[2048];
INT32 lorom;
void allocmem()
{
ram=(UINT8*)BurnMalloc(128*1024);
memset(ram,0x55,128*1024);
sram=(UINT8*)BurnMalloc(8192);
memset(sram,0,8192);
}
void freemem()
{
for (int i=0;i<2048;i++)
{
memlookup[i]=NULL;
memread[i]=0;
memwrite[i]=0;
accessspeed[i]=0;
}
if (ram !=NULL)
{
BurnFree(ram);
}
if (sram!=NULL)
{
BurnFree(sram);
}
if (rom!=NULL)
{
BurnFree(rom);
}
}
void initmem()
{
int c,d;
for (c=0;c<256;c++)
{
for (d=0;d<8;d++)
{
memread[(c<<3)|d]=memwrite[(c<<3)|d]=0;
}
}
if (lorom)
{
for (c=0;c<96;c++)
{
for (d=0;d<4;d++)
{
memread[(c<<3)|(d+4)]=1;
memlookup[(c<<3)|(d+4)]=&rom[((d*0x2000)+(c*0x8000))&0x3FFFFF];
memread[(c<<3)|(d+4)|0x400]=1;
memlookup[(c<<3)|(d+4)|0x400]=&rom[((d*0x2000)+(c*0x8000))&0x3FFFFF];
}
}
for (c=0;c<64;c++)
{
memread[(c<<3)|0]=memwrite[(c<<3)|0]=1;
memlookup[(c<<3)|0]=ram;
}
for (c=0;c<64;c++)
{
memread[(c<<3)|0x400]=memwrite[(c<<3)|0x400]=1;
memlookup[(c<<3)|0x400]=ram;
}
for (c=0;c<8;c++)
{
memread[(0x7E<<3)|c]=memwrite[(0x7E<<3)|c]=1;
memlookup[(0x7E<<3)|c]=&ram[c*0x2000];
memread[(0x7F<<3)|c]=memwrite[(0x7F<<3)|c]=1;
memlookup[(0x7F<<3)|c]=&ram[(c*0x2000)+0x10000];
}
}
else
{
for (c=0;c<2048;c++)
{
memread[c]=1;
memwrite[c]=0;
memlookup[c]=&rom[(c*0x2000)&0x3FFFFF];
}
for (c=0;c<64;c++)
{
for (d=1;d<4;d++)
{
memread[(c<<3)+d]=memwrite[(c<<3)+d]=0;
memread[(c<<3)+d+1024]=memwrite[(c<<3)+d+1024]=0;
}
}
for (c=0;c<64;c++)
{
memread[(c<<3)|0]=memwrite[(c<<3)|0]=1;
memlookup[(c<<3)|0]=ram;
memread[(c<<3)|1024]=memwrite[(c<<3)|1024]=1;
memlookup[(c<<3)|1024]=ram;
}
for (c=0;c<8;c++)
{
memread[(0x7E<<3)|c]=memwrite[(0x7E<<3)|c]=1;
memlookup[(0x7E<<3)|c]=&ram[c*0x2000];
memread[(0x7F<<3)|c]=memwrite[(0x7F<<3)|c]=1;
memlookup[(0x7F<<3)|c]=&ram[(c*0x2000)+0x10000];
}
for (c=0;c<16;c++)
{
memread[(0x70<<3)+c]=memwrite[(0x70<<3)+c]=1;
memlookup[(0x70<<3)+c]=sram;
}
}
/*Set up access speed table*/
for (c=0;c<64;c++)
{
accessspeed[(c<<3)|0]=8;
accessspeed[(c<<3)|1]=6;
accessspeed[(c<<3)|2]=6;
accessspeed[(c<<3)|3]=6;
accessspeed[(c<<3)|4]=accessspeed[(c<<3)|5]=8;
accessspeed[(c<<3)|6]=accessspeed[(c<<3)|7]=8;
}
for (c=64;c<128;c++)
{
for (d=0;d<8;d++)
{
accessspeed[(c<<3)|d]=8;
}
}
for (c=128;c<192;c++)
{
accessspeed[(c<<3)|0]=8;
accessspeed[(c<<3)|1]=6;
accessspeed[(c<<3)|2]=6;
accessspeed[(c<<3)|3]=6;
accessspeed[(c<<3)|4]=accessspeed[(c<<3)|5]=8;
accessspeed[(c<<3)|6]=accessspeed[(c<<3)|7]=8;
}
for (c=192;c<256;c++)
{
for (d=0;d<8;d++)
{
accessspeed[(c<<3)|d]=8;
}
}
}
unsigned char readmeml(unsigned long addr)
{
addr&=~0xFF000000;
if (((addr>>16)&0x7F)<0x40)
{
switch (addr&0xF000)
{
case 0x2000:
return readppu(addr);
case 0x4000:
if ((addr&0xE00)==0x200)
{
return readio(addr);
}
if ((addr&0xFFFE)==0x4016)
{
return readjoyold(addr);
}
//snemlog(L"Bad Read %06X\n",addr);
return 0;
case 0x6000:
case 0x7000:
if (!lorom)
{
return sram[addr&srammask];
}
default:
//snemlog(L"Bad read %06X\n",addr);
return 0xFF;
}
}
if ((addr>>16)>=0xD0 && (addr>>16)<=0xFE)
{
return 0;
}
if ((addr>>16)==0x70)
{
if (srammask)
{
return sram[addr&srammask];
}
return 0;
}
if ((addr>>16)==0x60)
{
return 0;
}
//snemlog(L"Bad read %06X\n",addr);
return 0xff;
}
void writememl(unsigned long addr, unsigned char val)
{
addr&=~0xFF000000;
if (((addr>>16)&0x7F)<0x40)
{
switch (addr&0xF000)
{
case 0x2000:
writeppu(addr,val);
return;
case 0x3000:
return;
case 0x4000:
if ((addr&0xE00)==0x200)
writeio(addr,val);
if ((addr&0xFFFE)==0x4016)
writejoyold(addr,val);
return;
case 0x5000:
return;
case 0x6000:
case 0x7000:
if (!lorom) sram[addr&srammask]=val;
return;
case 0x8000:
case 0x9000:
case 0xA000:
case 0xB000:
case 0xC000:
case 0xD000:
case 0xE000:
case 0xF000:
return;
default:
break;
//snemlog(L"Bad write %06X %02X\n",addr,val);
}
}
if ((addr>>16)>=0xD0 && (addr>>16)<=0xFE)
{
return;
}
if ((addr>>16)==0x70)
{
sram[addr&srammask]=val;
return;
}
//snemlog(L"Bad write %06X %02X\n",addr,val);
}

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff