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