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