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