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 _FXINST_H_
8#define _FXINST_H_
9
10/*
11 * FxChip(GSU) register space specification
12 * (Register address space 3000-32ff)
13 *
14 * The 16 generic 16 bit registers:
15 * (Some have a special function in special circumstances)
16 * 3000 - R0 default source/destination register
17 * 3002 - R1 pixel plot X position register
18 * 3004 - R2 pixel plot Y position register
19 * 3006 - R3
20 * 3008 - R4 lower 16 bit result of lmult
21 * 300a - R5
22 * 300c - R6 multiplier for fmult and lmult
23 * 300e - R7 fixed point texel X position for merge
24 * 3010 - R8 fixed point texel Y position for merge
25 * 3012 - R9
26 * 3014 - R10
27 * 3016 - R11 return address set by link
28 * 3018 - R12 loop counter
29 * 301a - R13 loop point address
30 * 301c - R14 rom address for getb, getbh, getbl, getbs
31 * 301e - R15 program counter
32 *
33 * 3020-302f - unused
34 *
35 * Other internal registers
36 * 3030 - SFR status flag register (16bit)
37 * 3032 - unused
38 * 3033 - BRAMR Backup RAM register (8bit)
39 * 3034 - PBR program bank register (8bit)
40 * 3035 - unused
41 * 3036 - ROMBR rom bank register (8bit)
42 * 3037 - CFGR control flags register (8bit)
43 * 3038 - SCBR screen base register (8bit)
44 * 3039 - CLSR clock speed register (8bit)
45 * 303a - SCMR screen mode register (8bit)
46 * 303b - VCR version code register (8bit) (read only)
47 * 303c - RAMBR ram bank register (8bit)
48 * 303d - unused
49 * 303e - CBR cache base register (16bit)
50 *
51 * 3040-30ff - unused
52 *
53 * 3100-32ff - CACHERAM 512 bytes of GSU cache memory
54 *
55 * SFR status flag register bits:
56 * 0 -
57 * 1 Z Zero flag
58 * 2 CY Carry flag
59 * 3 S Sign flag
60 * 4 OV Overflow flag
61 * 5 G Go flag (set to 1 when the GSU is running)
62 * 6 R Set to 1 when reading ROM using R14 address
63 * 7 -
64 * 8 ALT1 Mode set-up flag for the next instruction
65 * 9 ALT2 Mode set-up flag for the next instruction
66 * 10 IL Immediate lower 8-bit flag
67 * 11 IH Immediate higher 8-bit flag
68 * 12 B Set to 1 when the WITH instruction is executed
69 * 13 -
70 * 14 -
71 * 15 IRQ Set to 1 when GSU caused an interrupt
72 * Set to 0 when read by 658c16
73 *
74 * BRAMR = 0, BackupRAM is disabled
75 * BRAMR = 1, BackupRAM is enabled
76 *
77 * CFGR control flags register bits:
78 * 0 -
79 * 1 -
80 * 2 -
81 * 3 -
82 * 4 -
83 * 5 MS0 Multiplier speed, 0=standard, 1=high speed
84 * 6 -
85 * 7 IRQ Set to 1 when GSU interrupt request is masked
86 *
87 * CLSR clock speed register bits:
88 * 0 CLSR clock speed, 0 = 10.7Mhz, 1 = 21.4Mhz
89 *
90 * SCMR screen mode register bits:
91 * 0 MD0 color depth mode bit 0
92 * 1 MD1 color depth mode bit 1
93 * 2 HT0 screen height bit 1
94 * 3 RAN RAM access control
95 * 4 RON ROM access control
96 * 5 HT1 screen height bit 2
97 * 6 -
98 * 7 -
99 *
100 * RON = 0 SNES CPU has ROM access
101 * RON = 1 GSU has ROM access
102 *
103 * RAN = 0 SNES has game pak RAM access
104 * RAN = 1 GSU has game pak RAM access
105 *
106 * HT1 HT0 Screen height mode
107 * 0 0 128 pixels high
108 * 0 1 160 pixels high
109 * 1 0 192 pixels high
110 * 1 1 OBJ mode
111 *
112 * MD1 MD0 Color depth mode
113 * 0 0 4 color mode
114 * 0 1 16 color mode
115 * 1 0 not used
116 * 1 1 256 color mode
117 *
118 * CBR cache base register bits:
119 * 15-4 Specify base address for data to cache from ROM or RAM
120 * 3-0 Are 0 when address is read
121 *
122 * Write access to the program counter (301e) from
123 * the SNES-CPU will start the GSU, and it will not
124 * stop until it reaches a stop instruction.
125 *
126 */
127
128// Number of banks in GSU RAM
129#define FX_RAM_BANKS 4
130
131// Emulate proper R14 ROM access (slower, but safer)
132#define FX_DO_ROMBUFFER
133
134// Address checking (definately slow)
135//#define FX_ADDRESS_CHECK
136
137struct FxRegs_s
138{
139 // FxChip registers
140 uint32 avReg[16]; // 16 Generic registers
141 uint32 vColorReg; // Internal color register
142 uint32 vPlotOptionReg; // Plot option register
143 uint32 vStatusReg; // Status register
144 uint32 vPrgBankReg; // Program bank index register
145 uint32 vRomBankReg; // Rom bank index register
146 uint32 vRamBankReg; // Ram bank index register
147 uint32 vCacheBaseReg; // Cache base address register
148 uint32 vCacheFlags; // Saying what parts of the cache was written to
149 uint32 vLastRamAdr; // Last RAM address accessed
150 uint32 *pvDreg; // Pointer to current destination register
151 uint32 *pvSreg; // Pointer to current source register
152 uint8 vRomBuffer; // Current byte read by R14
153 uint8 vPipe; // Instructionset pipe
154 uint32 vPipeAdr; // The address of where the pipe was read from
155
156 // Status register optimization stuff
157 uint32 vSign; // v & 0x8000
158 uint32 vZero; // v == 0
159 uint32 vCarry; // a value of 1 or 0
160 int32 vOverflow; // (v >= 0x8000 || v < -0x8000)
161
162 // Other emulator variables
163 int32 vErrorCode;
164 uint32 vIllegalAddress;
165
166 uint8 bBreakPoint;
167 uint32 vBreakPoint;
168 uint32 vStepPoint;
169
170 uint8 *pvRegisters; // 768 bytes located in the memory at address 0x3000
171 uint32 nRamBanks; // Number of 64kb-banks in FxRam (Don't confuse it with SNES-Ram!!!)
172 uint8 *pvRam; // Pointer to FxRam
173 uint32 nRomBanks; // Number of 32kb-banks in Cart-ROM
174 uint8 *pvRom; // Pointer to Cart-ROM
175
176 uint32 vMode; // Color depth/mode
177 uint32 vPrevMode; // Previous depth
178 uint8 *pvScreenBase;
179 uint8 *apvScreen[32]; // Pointer to each of the 32 screen colums
180 int32 x[32];
181 uint32 vScreenHeight; // 128, 160, 192 or 256 (could be overriden by cmode)
182 uint32 vScreenRealHeight; // 128, 160, 192 or 256
183 uint32 vPrevScreenHeight;
184 uint32 vScreenSize;
185 void (*pfPlot) (void);
186 void (*pfRpix) (void);
187
188 uint8 *pvRamBank; // Pointer to current RAM-bank
189 uint8 *pvRomBank; // Pointer to current ROM-bank
190 uint8 *pvPrgBank; // Pointer to current program ROM-bank
191
192 uint8 *apvRamBank[FX_RAM_BANKS]; // Ram bank table (max 256kb)
193 uint8 *apvRomBank[256]; // Rom bank table
194
195 uint8 bCacheActive;
196 uint8 *pvCache; // Pointer to the GSU cache
197 uint8 avCacheBackup[512]; // Backup of ROM when the cache has replaced it
198 uint32 vCounter;
199 uint32 vInstCount;
200 uint32 vSCBRDirty; // If SCBR is written, our cached screen pointers need updating
201
202 uint8 *avRegAddr; // To reference avReg in snapshot.cpp
203};
204
205extern struct FxRegs_s GSU;
206
207// GSU registers
208#define GSU_R0 0x000
209#define GSU_R1 0x002
210#define GSU_R2 0x004
211#define GSU_R3 0x006
212#define GSU_R4 0x008
213#define GSU_R5 0x00a
214#define GSU_R6 0x00c
215#define GSU_R7 0x00e
216#define GSU_R8 0x010
217#define GSU_R9 0x012
218#define GSU_R10 0x014
219#define GSU_R11 0x016
220#define GSU_R12 0x018
221#define GSU_R13 0x01a
222#define GSU_R14 0x01c
223#define GSU_R15 0x01e
224#define GSU_SFR 0x030
225#define GSU_BRAMR 0x033
226#define GSU_PBR 0x034
227#define GSU_ROMBR 0x036
228#define GSU_CFGR 0x037
229#define GSU_SCBR 0x038
230#define GSU_CLSR 0x039
231#define GSU_SCMR 0x03a
232#define GSU_VCR 0x03b
233#define GSU_RAMBR 0x03c
234#define GSU_CBR 0x03e
235#define GSU_CACHERAM 0x100
236
237// SFR flags
238#define FLG_Z (1 << 1)
239#define FLG_CY (1 << 2)
240#define FLG_S (1 << 3)
241#define FLG_OV (1 << 4)
242#define FLG_G (1 << 5)
243#define FLG_R (1 << 6)
244#define FLG_ALT1 (1 << 8)
245#define FLG_ALT2 (1 << 9)
246#define FLG_IL (1 << 10)
247#define FLG_IH (1 << 11)
248#define FLG_B (1 << 12)
249#define FLG_IRQ (1 << 15)
250
251// Test flag
252#define TF(a) (GSU.vStatusReg & FLG_##a)
253#define CF(a) (GSU.vStatusReg &= ~FLG_##a)
254#define SF(a) (GSU.vStatusReg |= FLG_##a)
255
256// Test and set flag if condition, clear if not
257#define TS(a, b) GSU.vStatusReg = ((GSU.vStatusReg & (~FLG_##a)) | ((!!(##b)) * FLG_##a))
258
259// Testing ALT1 & ALT2 bits
260#define ALT0 (!TF(ALT1) && !TF(ALT2))
261#define ALT1 ( TF(ALT1) && !TF(ALT2))
262#define ALT2 (!TF(ALT1) && TF(ALT2))
263#define ALT3 ( TF(ALT1) && TF(ALT2))
264
265// Sign extend from 8/16 bit to 32 bit
266#define SEX8(a) ((int32) ((int8) (a)))
267#define SEX16(a) ((int32) ((int16) (a)))
268
269// Unsign extend from 8/16 bit to 32 bit
270#define USEX8(a) ((uint32) ((uint8) (a)))
271#define USEX16(a) ((uint32) ((uint16) (a)))
272#define SUSEX16(a) ((int32) ((uint16) (a)))
273
274// Set/Clr Sign and Zero flag
275#define TSZ(num) TS(S, ((num) & 0x8000)); TS(Z, (!USEX16(num)))
276
277// Clear flags
278#define CLRFLAGS GSU.vStatusReg &= ~(FLG_ALT1 | FLG_ALT2 | FLG_B); GSU.pvDreg = GSU.pvSreg = &R0
279
280// Read current RAM-Bank
281#define RAM(adr) GSU.pvRamBank[USEX16(adr)]
282
283// Read current ROM-Bank
284#define ROM(idx) GSU.pvRomBank[USEX16(idx)]
285
286// Access the current value in the pipe
287#define PIPE GSU.vPipe
288
289// Access data in the current program bank
290#define PRGBANK(idx) GSU.pvPrgBank[USEX16(idx)]
291
292// Update pipe from ROM
293#if 0
294#define FETCHPIPE { PIPE = PRGBANK(R15); GSU.vPipeAdr = (GSU.vPrgBankReg << 16) + R15; }
295#else
296#define FETCHPIPE { PIPE = PRGBANK(R15); }
297#endif
298
299// ABS
300#define ABS(x) ((x) < 0 ? -(x) : (x))
301
302// Access source register
303#define SREG (*GSU.pvSreg)
304
305// Access destination register
306#define DREG (*GSU.pvDreg)
307
308#ifndef FX_DO_ROMBUFFER
309
310// Don't read R14
311#define READR14
312
313// Don't test and/or read R14
314#define TESTR14
315
316#else
317
318// Read R14
319#define READR14 GSU.vRomBuffer = ROM(R14)
320
321// Test and/or read R14
322#define TESTR14 if (GSU.pvDreg == &R14) READR14
323
324#endif
325
326// Access to registers
327#define R0 GSU.avReg[0]
328#define R1 GSU.avReg[1]
329#define R2 GSU.avReg[2]
330#define R3 GSU.avReg[3]
331#define R4 GSU.avReg[4]
332#define R5 GSU.avReg[5]
333#define R6 GSU.avReg[6]
334#define R7 GSU.avReg[7]
335#define R8 GSU.avReg[8]
336#define R9 GSU.avReg[9]
337#define R10 GSU.avReg[10]
338#define R11 GSU.avReg[11]
339#define R12 GSU.avReg[12]
340#define R13 GSU.avReg[13]
341#define R14 GSU.avReg[14]
342#define R15 GSU.avReg[15]
343#define SFR GSU.vStatusReg
344#define PBR GSU.vPrgBankReg
345#define ROMBR GSU.vRomBankReg
346#define RAMBR GSU.vRamBankReg
347#define CBR GSU.vCacheBaseReg
348#define SCBR USEX8(GSU.pvRegisters[GSU_SCBR])
349#define SCMR USEX8(GSU.pvRegisters[GSU_SCMR])
350#define COLR GSU.vColorReg
351#define POR GSU.vPlotOptionReg
352#define BRAMR USEX8(GSU.pvRegisters[GSU_BRAMR])
353#define VCR USEX8(GSU.pvRegisters[GSU_VCR])
354#define CFGR USEX8(GSU.pvRegisters[GSU_CFGR])
355#define CLSR USEX8(GSU.pvRegisters[GSU_CLSR])
356
357// Execute instruction from the pipe, and fetch next byte to the pipe
358#define FX_STEP \
359{ \
360 uint32 vOpcode = (uint32) PIPE; \
361 FETCHPIPE; \
362 (*fx_OpcodeTable[(GSU.vStatusReg & 0x300) | vOpcode])(); \
363}
364
365extern void (*fx_PlotTable[]) (void);
366extern void (*fx_OpcodeTable[]) (void);
367
368// Set this define if branches are relative to the instruction in the delay slot (I think they are)
369#define BRANCH_DELAY_RELATIVE
370
371#endif
372