]> Shamusworld >> Repos - virtualjaguar/blob - src/memory.cpp
Fix for bad branch handling in OP.
[virtualjaguar] / src / memory.cpp
1 //
2 // Jaguar memory and I/O physical (hosted!) memory
3 //
4 // by James Hammons
5 //
6 // JLH = James Hammons
7 //
8 // WHO  WHEN        WHAT
9 // ---  ----------  -----------------------------------------------------------
10 // JLH  12/10/2009  Repurposed this file. :-)
11 //
12
13 /*
14 $FFFFFF => 16,777,215
15 $A00000 => 10,485,760
16
17 Really, just six megabytes short of using the entire address space...
18 Why not? We could just allocate the entire space and then use the MMU code to do
19 things like call functions and whatnot...
20 In other words, read/write would just tuck the value into the host RAM space and
21 the I/O function would take care of any weird stuff...
22
23 Actually: writes would tuck in the value, but reads would have to be handled
24 correctly since some registers do not fall on the same address as far as reading
25 goes... Still completely doable though. :-)
26
27 N.B.: Jaguar RAM is only 2 megs. ROM is 6 megs max, IO is 128K
28 */
29
30 #include "memory.h"
31
32 uint8_t jagMemSpace[0xF20000];                                  // The entire memory space of the Jaguar...!
33
34 uint8_t * jaguarMainRAM = &jagMemSpace[0x000000];
35 uint8_t * jaguarMainROM = &jagMemSpace[0x800000];
36 uint8_t * cdRAM         = &jagMemSpace[0xDFFF00];
37 uint8_t * gpuRAM        = &jagMemSpace[0xF03000];
38 uint8_t * dspRAM        = &jagMemSpace[0xF1B000];
39
40 #if 0
41 union Word
42 {
43         uint16_t word;
44         struct {
45                 // This changes depending on endianness...
46 #ifdef __BIG_ENDIAN__
47                 uint8_t hi, lo;                                                 // Big endian
48 #else
49                 uint8_t lo, hi;                                                 // Little endian
50 #endif
51         };
52 };
53 #endif
54
55 #if 0
56 union DWord
57 {
58         uint32_t dword;
59         struct
60         {
61 #ifdef __BIG_ENDIAN__
62                 uint16_t hiw, low;
63 #else
64                 uint16_t low, hiw;
65 #endif
66         };
67 };
68 #endif
69
70 #if 0
71 static void test(void)
72 {
73         Word reg;
74         reg.word = 0x1234;
75         reg.lo = 0xFF;
76         reg.hi = 0xEE;
77
78         DWord reg2;
79         reg2.hiw = 0xFFFE;
80         reg2.low = 0x3322;
81         reg2.low.lo = 0x11;
82 }
83 #endif
84
85 // OR, we could do like so:
86 #if 0
87 #ifdef __BIG_ENDIAN__
88 #define DWORD_BYTE_HWORD_H 1
89 #define DWORD_BYTE_HWORD_L 2
90 #define DWORD_BYTE_LWORD_H 3
91 #define DWORD_BYTE_LWORD_L 4
92 #else
93 #define DWORD_BYTE_HWORD_H 4
94 #define DWORD_BYTE_HWORD_L 3
95 #define DWORD_BYTE_LWORD_H 2
96 #define DWORD_BYTE_LWORD_L 1
97 #endif
98 // But this starts to get cumbersome after a while... Is union really better?
99
100 //More union stuff...
101 unsigned long ByteSwap1 (unsigned long nLongNumber)
102 {
103    union u {unsigned long vi; unsigned char c[sizeof(unsigned long)];};
104    union v {unsigned long ni; unsigned char d[sizeof(unsigned long)];};
105    union u un;
106    union v vn;
107    un.vi = nLongNumber;
108    vn.d[0]=un.c[3];
109    vn.d[1]=un.c[2];
110    vn.d[2]=un.c[1];
111    vn.d[3]=un.c[0];
112    return (vn.ni);
113 }
114 #endif
115
116 //Not sure if this is a good approach yet...
117 //should be if we use proper aliasing, and htonl and friends...
118 #if 1
119 uint32_t & butch     = *((uint32_t *)&jagMemSpace[0xDFFF00]);   // base of Butch == interrupt control register, R/W
120 uint32_t & dscntrl   = *((uint32_t *)&jagMemSpace[0xDFFF04]);   // DSA control register, R/W
121 uint16_t & ds_data   = *((uint16_t *)&jagMemSpace[0xDFFF0A]);   // DSA TX/RX data, R/W
122 uint32_t & i2cntrl   = *((uint32_t *)&jagMemSpace[0xDFFF10]);   // i2s bus control register, R/W
123 uint32_t & sbcntrl   = *((uint32_t *)&jagMemSpace[0xDFFF14]);   // CD subcode control register, R/W
124 uint32_t & subdata   = *((uint32_t *)&jagMemSpace[0xDFFF18]);   // Subcode data register A
125 uint32_t & subdatb   = *((uint32_t *)&jagMemSpace[0xDFFF1C]);   // Subcode data register B
126 uint32_t & sb_time   = *((uint32_t *)&jagMemSpace[0xDFFF20]);   // Subcode time and compare enable (D24)
127 uint32_t & fifo_data = *((uint32_t *)&jagMemSpace[0xDFFF24]);   // i2s FIFO data
128 uint32_t & i2sdat2   = *((uint32_t *)&jagMemSpace[0xDFFF28]);   // i2s FIFO data (old)
129 uint32_t & unknown   = *((uint32_t *)&jagMemSpace[0xDFFF2C]);   // Seems to be some sort of I2S interface
130 #else
131 uint32_t butch, dscntrl, ds_data, i2cntrl, sbcntrl, subdata, subdatb, sb_time, fifo_data, i2sdat2, unknown;
132 #endif
133
134 #warning "Need to separate out this stuff (or do we???)"
135 //if we use a contiguous memory space, we don't need this shit...
136 //err, maybe we do, let's not be so hasty now... :-)
137
138 //#define ENDIANSAFE(x) htonl(x)
139
140 // The nice thing about doing it this way is that on big endian machines, htons/l
141 // compile to nothing and on Intel machines, it compiles down to a single bswap instruction.
142 // So endianness issues go away nicely without a lot of drama. :-D
143
144 #define BSWAP16(x) (htons(x))
145 #define BSWAP32(x) (htonl(x))
146 //this isn't endian safe...
147 #define BSWAP64(x) ((htonl(x & 0xFFFFFFFF) << 32) | htonl(x >> 32))
148 // Actually, we use ESAFExx() macros instead of this, and we use GCC to check the endianness...
149 // Actually, considering that "byteswap.h" doesn't exist elsewhere, the above
150 // is probably our best bet here. Just need to rename them to ESAFExx().
151
152 // Look at <endian.h> and see if that header is portable or not.
153
154 uint16_t & memcon1   = *((uint16_t *)&jagMemSpace[0xF00000]);
155 uint16_t & memcon2   = *((uint16_t *)&jagMemSpace[0xF00002]);
156 uint16_t & hc        = *((uint16_t *)&jagMemSpace[0xF00004]);
157 uint16_t & vc        = *((uint16_t *)&jagMemSpace[0xF00006]);
158 uint16_t & lph       = *((uint16_t *)&jagMemSpace[0xF00008]);
159 uint16_t & lpv       = *((uint16_t *)&jagMemSpace[0xF0000A]);
160 uint64_t & obData    = *((uint64_t *)&jagMemSpace[0xF00010]);
161 uint32_t & olp       = *((uint32_t *)&jagMemSpace[0xF00020]);
162 uint16_t & obf       = *((uint16_t *)&jagMemSpace[0xF00026]);
163 uint16_t & vmode     = *((uint16_t *)&jagMemSpace[0xF00028]);
164 uint16_t & bord1     = *((uint16_t *)&jagMemSpace[0xF0002A]);
165 uint16_t & bord2     = *((uint16_t *)&jagMemSpace[0xF0002C]);
166 uint16_t & hp        = *((uint16_t *)&jagMemSpace[0xF0002E]);
167 uint16_t & hbb       = *((uint16_t *)&jagMemSpace[0xF00030]);
168 uint16_t & hbe       = *((uint16_t *)&jagMemSpace[0xF00032]);
169 uint16_t & hs        = *((uint16_t *)&jagMemSpace[0xF00034]);
170 uint16_t & hvs       = *((uint16_t *)&jagMemSpace[0xF00036]);
171 uint16_t & hdb1      = *((uint16_t *)&jagMemSpace[0xF00038]);
172 uint16_t & hdb2      = *((uint16_t *)&jagMemSpace[0xF0003A]);
173 uint16_t & hde       = *((uint16_t *)&jagMemSpace[0xF0003C]);
174 uint16_t & vp        = *((uint16_t *)&jagMemSpace[0xF0003E]);
175 uint16_t & vbb       = *((uint16_t *)&jagMemSpace[0xF00040]);
176 uint16_t & vbe       = *((uint16_t *)&jagMemSpace[0xF00042]);
177 uint16_t & vs        = *((uint16_t *)&jagMemSpace[0xF00044]);
178 uint16_t & vdb       = *((uint16_t *)&jagMemSpace[0xF00046]);
179 uint16_t & vde       = *((uint16_t *)&jagMemSpace[0xF00048]);
180 uint16_t & veb       = *((uint16_t *)&jagMemSpace[0xF0004A]);
181 uint16_t & vee       = *((uint16_t *)&jagMemSpace[0xF0004C]);
182 uint16_t & vi        = *((uint16_t *)&jagMemSpace[0xF0004E]);
183 uint16_t & pit0      = *((uint16_t *)&jagMemSpace[0xF00050]);
184 uint16_t & pit1      = *((uint16_t *)&jagMemSpace[0xF00052]);
185 uint16_t & heq       = *((uint16_t *)&jagMemSpace[0xF00054]);
186 uint32_t & bg        = *((uint32_t *)&jagMemSpace[0xF00058]);
187 uint16_t & int1      = *((uint16_t *)&jagMemSpace[0xF000E0]);
188 uint16_t & int2      = *((uint16_t *)&jagMemSpace[0xF000E2]);
189 uint8_t  * clut      =   (uint8_t *) &jagMemSpace[0xF00400];
190 uint8_t  * lbuf      =   (uint8_t *) &jagMemSpace[0xF00800];
191 uint32_t & g_flags   = *((uint32_t *)&jagMemSpace[0xF02100]);
192 uint32_t & g_mtxc    = *((uint32_t *)&jagMemSpace[0xF02104]);
193 uint32_t & g_mtxa    = *((uint32_t *)&jagMemSpace[0xF02108]);
194 uint32_t & g_end     = *((uint32_t *)&jagMemSpace[0xF0210C]);
195 uint32_t & g_pc      = *((uint32_t *)&jagMemSpace[0xF02110]);
196 uint32_t & g_ctrl    = *((uint32_t *)&jagMemSpace[0xF02114]);
197 uint32_t & g_hidata  = *((uint32_t *)&jagMemSpace[0xF02118]);
198 uint32_t & g_divctrl = *((uint32_t *)&jagMemSpace[0xF0211C]);
199 uint32_t g_remain;                                                              // Dual register with $F0211C
200 uint32_t & a1_base   = *((uint32_t *)&jagMemSpace[0xF02200]);
201 uint32_t & a1_flags  = *((uint32_t *)&jagMemSpace[0xF02204]);
202 uint32_t & a1_clip   = *((uint32_t *)&jagMemSpace[0xF02208]);
203 uint32_t & a1_pixel  = *((uint32_t *)&jagMemSpace[0xF0220C]);
204 uint32_t & a1_step   = *((uint32_t *)&jagMemSpace[0xF02210]);
205 uint32_t & a1_fstep  = *((uint32_t *)&jagMemSpace[0xF02214]);
206 uint32_t & a1_fpixel = *((uint32_t *)&jagMemSpace[0xF02218]);
207 uint32_t & a1_inc    = *((uint32_t *)&jagMemSpace[0xF0221C]);
208 uint32_t & a1_finc   = *((uint32_t *)&jagMemSpace[0xF02220]);
209 uint32_t & a2_base   = *((uint32_t *)&jagMemSpace[0xF02224]);
210 uint32_t & a2_flags  = *((uint32_t *)&jagMemSpace[0xF02228]);
211 uint32_t & a2_mask   = *((uint32_t *)&jagMemSpace[0xF0222C]);
212 uint32_t & a2_pixel  = *((uint32_t *)&jagMemSpace[0xF02230]);
213 uint32_t & a2_step   = *((uint32_t *)&jagMemSpace[0xF02234]);
214 uint32_t & b_cmd     = *((uint32_t *)&jagMemSpace[0xF02238]);
215 uint32_t & b_count   = *((uint32_t *)&jagMemSpace[0xF0223C]);
216 uint64_t & b_srcd    = *((uint64_t *)&jagMemSpace[0xF02240]);
217 uint64_t & b_dstd    = *((uint64_t *)&jagMemSpace[0xF02248]);
218 uint64_t & b_dstz    = *((uint64_t *)&jagMemSpace[0xF02250]);
219 uint64_t & b_srcz1   = *((uint64_t *)&jagMemSpace[0xF02258]);
220 uint64_t & b_srcz2   = *((uint64_t *)&jagMemSpace[0xF02260]);
221 uint64_t & b_patd    = *((uint64_t *)&jagMemSpace[0xF02268]);
222 uint32_t & b_iinc    = *((uint32_t *)&jagMemSpace[0xF02270]);
223 uint32_t & b_zinc    = *((uint32_t *)&jagMemSpace[0xF02274]);
224 uint32_t & b_stop    = *((uint32_t *)&jagMemSpace[0xF02278]);
225 uint32_t & b_i3      = *((uint32_t *)&jagMemSpace[0xF0227C]);
226 uint32_t & b_i2      = *((uint32_t *)&jagMemSpace[0xF02280]);
227 uint32_t & b_i1      = *((uint32_t *)&jagMemSpace[0xF02284]);
228 uint32_t & b_i0      = *((uint32_t *)&jagMemSpace[0xF02288]);
229 uint32_t & b_z3      = *((uint32_t *)&jagMemSpace[0xF0228C]);
230 uint32_t & b_z2      = *((uint32_t *)&jagMemSpace[0xF02290]);
231 uint32_t & b_z1      = *((uint32_t *)&jagMemSpace[0xF02294]);
232 uint32_t & b_z0      = *((uint32_t *)&jagMemSpace[0xF02298]);
233 uint16_t & jpit1     = *((uint16_t *)&jagMemSpace[0xF10000]);
234 uint16_t & jpit2     = *((uint16_t *)&jagMemSpace[0xF10002]);
235 uint16_t & jpit3     = *((uint16_t *)&jagMemSpace[0xF10004]);
236 uint16_t & jpit4     = *((uint16_t *)&jagMemSpace[0xF10006]);
237 uint16_t & clk1      = *((uint16_t *)&jagMemSpace[0xF10010]);
238 uint16_t & clk2      = *((uint16_t *)&jagMemSpace[0xF10012]);
239 uint16_t & clk3      = *((uint16_t *)&jagMemSpace[0xF10014]);
240 uint16_t & j_int     = *((uint16_t *)&jagMemSpace[0xF10020]);
241 uint16_t & asidata   = *((uint16_t *)&jagMemSpace[0xF10030]);
242 uint16_t & asictrl   = *((uint16_t *)&jagMemSpace[0xF10032]);
243 uint16_t asistat;                                                                       // Dual register with $F10032
244 uint16_t & asiclk    = *((uint16_t *)&jagMemSpace[0xF10034]);
245 uint16_t & joystick  = *((uint16_t *)&jagMemSpace[0xF14000]);
246 uint16_t & joybuts   = *((uint16_t *)&jagMemSpace[0xF14002]);
247 uint32_t & d_flags   = *((uint32_t *)&jagMemSpace[0xF1A100]);
248 uint32_t & d_mtxc    = *((uint32_t *)&jagMemSpace[0xF1A104]);
249 uint32_t & d_mtxa    = *((uint32_t *)&jagMemSpace[0xF1A108]);
250 uint32_t & d_end     = *((uint32_t *)&jagMemSpace[0xF1A10C]);
251 uint32_t & d_pc      = *((uint32_t *)&jagMemSpace[0xF1A110]);
252 uint32_t & d_ctrl    = *((uint32_t *)&jagMemSpace[0xF1A114]);
253 uint32_t & d_mod     = *((uint32_t *)&jagMemSpace[0xF1A118]);
254 uint32_t & d_divctrl = *((uint32_t *)&jagMemSpace[0xF1A11C]);
255 uint32_t d_remain;                                                              // Dual register with $F0211C
256 uint32_t & d_machi   = *((uint32_t *)&jagMemSpace[0xF1A120]);
257 uint16_t & ltxd      = *((uint16_t *)&jagMemSpace[0xF1A148]);
258 uint16_t lrxd;                                                                  // Dual register with $F1A148
259 uint16_t & rtxd      = *((uint16_t *)&jagMemSpace[0xF1A14C]);
260 uint16_t rrxd;                                                                  // Dual register with $F1A14C
261 uint8_t  & sclk      = *((uint8_t *) &jagMemSpace[0xF1A150]);
262 uint8_t sstat;                                                                  // Dual register with $F1A150
263 uint32_t & smode     = *((uint32_t *)&jagMemSpace[0xF1A154]);
264
265 // Memory debugging identifiers
266
267 const char * whoName[10] =
268         { "Unknown", "Jaguar", "DSP", "GPU", "TOM", "JERRY", "M68K", "Blitter", "OP", "Debugger" };