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