1/*****************************************************************************\
2 Snes9x - Portable Super Nintendo Entertainment System (TM) emulator.
3 This file is licensed under the Snes9x License.
4 For further information, consult the LICENSE file in the root directory.
5\*****************************************************************************/
6
7#ifndef _SNES9X_H_
8#define _SNES9X_H_
9
10#ifndef VERSION
11#define VERSION "1.60"
12#endif
13
14#include "port.h"
15#include "65c816.h"
16#include "messages.h"
17
18#ifdef ZLIB
19#include <zlib.h>
20#define FSTREAM gzFile
21#define READ_FSTREAM(p, l, s) gzread(s, p, l)
22#define WRITE_FSTREAM(p, l, s) gzwrite(s, p, l)
23#define GETS_FSTREAM(p, l, s) gzgets(s, p, l)
24#define GETC_FSTREAM(s) gzgetc(s)
25#define OPEN_FSTREAM(f, m) gzopen(f, m)
26#define REOPEN_FSTREAM(f, m) gzdopen(f, m)
27#define FIND_FSTREAM(f) gztell(f)
28#define REVERT_FSTREAM(s, o, p) gzseek(s, o, p)
29#define CLOSE_FSTREAM(s) gzclose(s)
30#else
31#define FSTREAM FILE *
32#define READ_FSTREAM(p, l, s) fread(p, 1, l, s)
33#define WRITE_FSTREAM(p, l, s) fwrite(p, 1, l, s)
34#define GETS_FSTREAM(p, l, s) fgets(p, l, s)
35#define GETC_FSTREAM(s) fgetc(s)
36#define OPEN_FSTREAM(f, m) fopen(f, m)
37#define REOPEN_FSTREAM(f, m) fdopen(f, m)
38#define FIND_FSTREAM(s) ftell(s)
39#define REVERT_FSTREAM(s, o, p) fseek(s, o, p)
40#define CLOSE_FSTREAM(s) fclose(s)
41#endif
42
43#include "stream.h"
44
45#define STREAM Stream *
46#define READ_STREAM(p, l, s) s->read(p,l)
47#define WRITE_STREAM(p, l, s) s->write(p,l)
48#define GETS_STREAM(p, l, s) s->gets(p,l)
49#define GETC_STREAM(s) s->get_char()
50#define OPEN_STREAM(f, m) openStreamFromFSTREAM(f, m)
51#define REOPEN_STREAM(f, m) reopenStreamFromFd(f, m)
52#define FIND_STREAM(s) s->pos()
53#define REVERT_STREAM(s, o, p) s->revert(p, o)
54#define CLOSE_STREAM(s) s->closeStream()
55
56#define SNES_WIDTH 256
57#define SNES_HEIGHT 224
58#define SNES_HEIGHT_EXTENDED 239
59#define MAX_SNES_WIDTH (SNES_WIDTH * 2)
60#define MAX_SNES_HEIGHT (SNES_HEIGHT_EXTENDED * 2)
61#define IMAGE_WIDTH (Settings.SupportHiRes ? MAX_SNES_WIDTH : SNES_WIDTH)
62#define IMAGE_HEIGHT (Settings.SupportHiRes ? MAX_SNES_HEIGHT : SNES_HEIGHT_EXTENDED)
63
64#define NTSC_MASTER_CLOCK 21477272.727272 // 21477272 + 8/11 exact
65#define PAL_MASTER_CLOCK 21281370.0
66
67#define SNES_MAX_NTSC_VCOUNTER 262
68#define SNES_MAX_PAL_VCOUNTER 312
69#define SNES_HCOUNTER_MAX 341
70
71#ifndef ALLOW_CPU_OVERCLOCK
72#define ONE_CYCLE 6
73#define SLOW_ONE_CYCLE 8
74#define TWO_CYCLES 12
75#else
76#define ONE_CYCLE (Settings.OneClockCycle)
77#define SLOW_ONE_CYCLE (Settings.OneSlowClockCycle)
78#define TWO_CYCLES (Settings.TwoClockCycles)
79#endif
80#define ONE_DOT_CYCLE 4
81
82#define SNES_CYCLES_PER_SCANLINE (SNES_HCOUNTER_MAX * ONE_DOT_CYCLE)
83#define SNES_SCANLINE_TIME (SNES_CYCLES_PER_SCANLINE / NTSC_MASTER_CLOCK)
84
85#define SNES_WRAM_REFRESH_HC_v1 530
86#define SNES_WRAM_REFRESH_HC_v2 538
87#define SNES_WRAM_REFRESH_CYCLES 40
88
89#define SNES_HBLANK_START_HC 1096 // H=274
90#define SNES_HDMA_START_HC 1106 // FIXME: not true
91#define SNES_HBLANK_END_HC 4 // H=1
92#define SNES_HDMA_INIT_HC 20 // FIXME: not true
93#define SNES_RENDER_START_HC (128 * ONE_DOT_CYCLE) // FIXME: Snes9x renders a line at a time.
94
95#define SNES_TR_MASK (1 << 4)
96#define SNES_TL_MASK (1 << 5)
97#define SNES_X_MASK (1 << 6)
98#define SNES_A_MASK (1 << 7)
99#define SNES_RIGHT_MASK (1 << 8)
100#define SNES_LEFT_MASK (1 << 9)
101#define SNES_DOWN_MASK (1 << 10)
102#define SNES_UP_MASK (1 << 11)
103#define SNES_START_MASK (1 << 12)
104#define SNES_SELECT_MASK (1 << 13)
105#define SNES_Y_MASK (1 << 14)
106#define SNES_B_MASK (1 << 15)
107
108#define DEBUG_MODE_FLAG (1 << 0) // debugger
109#define TRACE_FLAG (1 << 1) // debugger
110#define SINGLE_STEP_FLAG (1 << 2) // debugger
111#define BREAK_FLAG (1 << 3) // debugger
112#define SCAN_KEYS_FLAG (1 << 4) // CPU
113#define HALTED_FLAG (1 << 12) // APU
114#define FRAME_ADVANCE_FLAG (1 << 9)
115
116#define ROM_NAME_LEN 23
117#define AUTO_FRAMERATE 200
118
119struct SCPUState
120{
121 uint32 Flags;
122 int32 Cycles;
123 int32 PrevCycles;
124 int32 V_Counter;
125 uint8 *PCBase;
126 bool8 NMIPending;
127 bool8 IRQLine;
128 bool8 IRQTransition;
129 bool8 IRQLastState;
130 bool8 IRQExternal;
131 int32 IRQPending;
132 int32 MemSpeed;
133 int32 MemSpeedx2;
134 int32 FastROMSpeed;
135 bool8 InDMA;
136 bool8 InHDMA;
137 bool8 InDMAorHDMA;
138 bool8 InWRAMDMAorHDMA;
139 uint8 HDMARanInDMA;
140 int32 CurrentDMAorHDMAChannel;
141 uint8 WhichEvent;
142 int32 NextEvent;
143 bool8 WaitingForInterrupt;
144 uint32 AutoSaveTimer;
145 bool8 SRAMModified;
146};
147
148enum
149{
150 HC_HBLANK_START_EVENT = 1,
151 HC_HDMA_START_EVENT = 2,
152 HC_HCOUNTER_MAX_EVENT = 3,
153 HC_HDMA_INIT_EVENT = 4,
154 HC_RENDER_EVENT = 5,
155 HC_WRAM_REFRESH_EVENT = 6
156};
157
158enum
159{
160 IRQ_NONE = 0x0,
161 IRQ_SET_FLAG = 0x1,
162 IRQ_CLEAR_FLAG = 0x2,
163 IRQ_TRIGGER_NMI = 0x4
164};
165
166struct STimings
167{
168 int32 H_Max_Master;
169 int32 H_Max;
170 int32 V_Max_Master;
171 int32 V_Max;
172 int32 HBlankStart;
173 int32 HBlankEnd;
174 int32 HDMAInit;
175 int32 HDMAStart;
176 int32 NMITriggerPos;
177 int32 NextIRQTimer;
178 int32 IRQTriggerCycles;
179 int32 WRAMRefreshPos;
180 int32 RenderPos;
181 bool8 InterlaceField;
182 int32 DMACPUSync; // The cycles to synchronize DMA and CPU. Snes9x cannot emulate correctly.
183 int32 NMIDMADelay; // The delay of NMI trigger after DMA transfers. Snes9x cannot emulate correctly.
184 int32 IRQFlagChanging; // This value is just a hack.
185 int32 APUSpeedup;
186 bool8 APUAllowTimeOverflow;
187};
188
189struct SSettings
190{
191 bool8 TraceDMA;
192 bool8 TraceHDMA;
193 bool8 TraceVRAM;
194 bool8 TraceUnknownRegisters;
195 bool8 TraceDSP;
196 bool8 TraceHCEvent;
197 bool8 TraceSMP;
198
199 bool8 SuperFX;
200 uint8 DSP;
201 bool8 SA1;
202 bool8 C4;
203 bool8 SDD1;
204 bool8 SPC7110;
205 bool8 SPC7110RTC;
206 bool8 OBC1;
207 uint8 SETA;
208 bool8 SRTC;
209 bool8 BS;
210 bool8 BSXItself;
211 bool8 BSXBootup;
212 bool8 MSU1;
213 bool8 MouseMaster;
214 bool8 SuperScopeMaster;
215 bool8 JustifierMaster;
216 bool8 MultiPlayer5Master;
217 bool8 MacsRifleMaster;
218
219 bool8 ForceLoROM;
220 bool8 ForceHiROM;
221 bool8 ForceHeader;
222 bool8 ForceNoHeader;
223 bool8 ForceInterleaved;
224 bool8 ForceInterleaved2;
225 bool8 ForceInterleaveGD24;
226 bool8 ForceNotInterleaved;
227 bool8 ForcePAL;
228 bool8 ForceNTSC;
229 bool8 PAL;
230 uint32 FrameTimePAL;
231 uint32 FrameTimeNTSC;
232 uint32 FrameTime;
233
234 bool8 SoundSync;
235 bool8 SixteenBitSound;
236 uint32 SoundPlaybackRate;
237 uint32 SoundInputRate;
238 bool8 Stereo;
239 bool8 ReverseStereo;
240 bool8 Mute;
241 bool8 DynamicRateControl;
242 int32 DynamicRateLimit; /* Multiplied by 1000 */
243 int32 InterpolationMethod;
244
245 bool8 SupportHiRes;
246 bool8 Transparency;
247 uint8 BG_Forced;
248 bool8 DisableGraphicWindows;
249
250 bool8 DisplayTime;
251 bool8 DisplayFrameRate;
252 bool8 DisplayWatchedAddresses;
253 bool8 DisplayPressedKeys;
254 bool8 DisplayMovieFrame;
255 bool8 AutoDisplayMessages;
256 uint32 InitialInfoStringTimeout;
257 uint16 DisplayColor;
258 bool8 BilinearFilter;
259
260 bool8 Multi;
261 char CartAName[PATH_MAX + 1];
262 char CartBName[PATH_MAX + 1];
263
264 bool8 DisableGameSpecificHacks;
265 bool8 BlockInvalidVRAMAccessMaster;
266 bool8 BlockInvalidVRAMAccess;
267 int32 HDMATimingHack;
268
269 bool8 ForcedPause;
270 bool8 Paused;
271 bool8 StopEmulation;
272
273 uint32 SkipFrames;
274 uint32 TurboSkipFrames;
275 uint32 AutoMaxSkipFrames;
276 bool8 TurboMode;
277 uint32 HighSpeedSeek;
278 bool8 FrameAdvance;
279 bool8 Rewinding;
280
281 bool8 NetPlay;
282 bool8 NetPlayServer;
283 char ServerName[128];
284 int Port;
285
286 bool8 MovieTruncate;
287 bool8 MovieNotifyIgnored;
288 bool8 WrongMovieStateProtection;
289 bool8 DumpStreams;
290 int DumpStreamsMaxFrames;
291
292 bool8 TakeScreenshot;
293 int8 StretchScreenshots;
294 bool8 SnapshotScreenshots;
295 char InitialSnapshotFilename[PATH_MAX + 1];
296 bool8 FastSavestates;
297
298 bool8 ApplyCheats;
299 bool8 NoPatch;
300 bool8 IgnorePatchChecksum;
301 bool8 IsPatched;
302 int32 AutoSaveDelay;
303 bool8 DontSaveOopsSnapshot;
304 bool8 UpAndDown;
305
306 bool8 OpenGLEnable;
307
308 bool8 SeparateEchoBuffer;
309 uint32 SuperFXClockMultiplier;
310 int OverclockMode;
311 int OneClockCycle;
312 int OneSlowClockCycle;
313 int TwoClockCycles;
314 int MaxSpriteTilesPerLine;
315};
316
317struct SSNESGameFixes
318{
319 uint8 SRAMInitialValue;
320 uint8 Uniracers;
321};
322
323enum
324{
325 PAUSE_NETPLAY_CONNECT = (1 << 0),
326 PAUSE_TOGGLE_FULL_SCREEN = (1 << 1),
327 PAUSE_EXIT = (1 << 2),
328 PAUSE_MENU = (1 << 3),
329 PAUSE_INACTIVE_WINDOW = (1 << 4),
330 PAUSE_WINDOW_ICONISED = (1 << 5),
331 PAUSE_RESTORE_GUI = (1 << 6),
332 PAUSE_FREEZE_FILE = (1 << 7)
333};
334
335void S9xSetPause(uint32);
336void S9xClearPause(uint32);
337void S9xExit(void);
338void S9xMessage(int, int, const char *);
339
340extern struct SSettings Settings;
341extern struct SCPUState CPU;
342extern struct STimings Timings;
343extern struct SSNESGameFixes SNESGameFixes;
344extern char String[513];
345
346#endif
347