Create LICENSE
[clinton/Virtual-Jaguar-Rx.git] / 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 #if defined(_MSC_VER)
135 #pragma message("Warning: Need to separate out this stuff (or do we???)")
136 #else
137 #warning "Need to separate out this stuff (or do we???)"
138 #endif // _MSC_VER
139 //if we use a contiguous memory space, we don't need this shit...
140 //err, maybe we do, let's not be so hasty now... :-)
141
142 //#define ENDIANSAFE(x) htonl(x)
143
144 // The nice thing about doing it this way is that on big endian machines, htons/l
145 // compile to nothing and on Intel machines, it compiles down to a single bswap instruction.
146 // So endianness issues go away nicely without a lot of drama. :-D
147
148 #define BSWAP16(x) (htons(x))
149 #define BSWAP32(x) (htonl(x))
150 //this isn't endian safe...
151 #define BSWAP64(x) ((htonl(x & 0xFFFFFFFF) << 32) | htonl(x >> 32))
152 // Actually, we use ESAFExx() macros instead of this, and we use GCC to check the endianness...
153 // Actually, considering that "byteswap.h" doesn't exist elsewhere, the above
154 // is probably our best bet here. Just need to rename them to ESAFExx().
155
156 // Look at <endian.h> and see if that header is portable or not.
157
158 uint16_t & memcon1 = *((uint16_t *)&jagMemSpace[0xF00000]);
159 uint16_t & memcon2 = *((uint16_t *)&jagMemSpace[0xF00002]);
160 uint16_t & hc = *((uint16_t *)&jagMemSpace[0xF00004]);
161 uint16_t & vc = *((uint16_t *)&jagMemSpace[0xF00006]);
162 uint16_t & lph = *((uint16_t *)&jagMemSpace[0xF00008]);
163 uint16_t & lpv = *((uint16_t *)&jagMemSpace[0xF0000A]);
164 uint64_t & obData = *((uint64_t *)&jagMemSpace[0xF00010]);
165 uint32_t & olp = *((uint32_t *)&jagMemSpace[0xF00020]);
166 uint16_t & obf = *((uint16_t *)&jagMemSpace[0xF00026]);
167 uint16_t & vmode = *((uint16_t *)&jagMemSpace[0xF00028]);
168 uint16_t & bord1 = *((uint16_t *)&jagMemSpace[0xF0002A]);
169 uint16_t & bord2 = *((uint16_t *)&jagMemSpace[0xF0002C]);
170 uint16_t & hp = *((uint16_t *)&jagMemSpace[0xF0002E]);
171 uint16_t & hbb = *((uint16_t *)&jagMemSpace[0xF00030]);
172 uint16_t & hbe = *((uint16_t *)&jagMemSpace[0xF00032]);
173 uint16_t & hs = *((uint16_t *)&jagMemSpace[0xF00034]);
174 uint16_t & hvs = *((uint16_t *)&jagMemSpace[0xF00036]);
175 uint16_t & hdb1 = *((uint16_t *)&jagMemSpace[0xF00038]);
176 uint16_t & hdb2 = *((uint16_t *)&jagMemSpace[0xF0003A]);
177 uint16_t & hde = *((uint16_t *)&jagMemSpace[0xF0003C]);
178 uint16_t & vp = *((uint16_t *)&jagMemSpace[0xF0003E]);
179 uint16_t & vbb = *((uint16_t *)&jagMemSpace[0xF00040]);
180 uint16_t & vbe = *((uint16_t *)&jagMemSpace[0xF00042]);
181 uint16_t & vs = *((uint16_t *)&jagMemSpace[0xF00044]);
182 uint16_t & vdb = *((uint16_t *)&jagMemSpace[0xF00046]);
183 uint16_t & vde = *((uint16_t *)&jagMemSpace[0xF00048]);
184 uint16_t & veb = *((uint16_t *)&jagMemSpace[0xF0004A]);
185 uint16_t & vee = *((uint16_t *)&jagMemSpace[0xF0004C]);
186 uint16_t & vi = *((uint16_t *)&jagMemSpace[0xF0004E]);
187 uint16_t & pit0 = *((uint16_t *)&jagMemSpace[0xF00050]);
188 uint16_t & pit1 = *((uint16_t *)&jagMemSpace[0xF00052]);
189 uint16_t & heq = *((uint16_t *)&jagMemSpace[0xF00054]);
190 uint32_t & bg = *((uint32_t *)&jagMemSpace[0xF00058]);
191 uint16_t & int1 = *((uint16_t *)&jagMemSpace[0xF000E0]);
192 uint16_t & int2 = *((uint16_t *)&jagMemSpace[0xF000E2]);
193 uint8_t * clut = (uint8_t *) &jagMemSpace[0xF00400];
194 uint8_t * lbuf = (uint8_t *) &jagMemSpace[0xF00800];
195 uint32_t & g_flags = *((uint32_t *)&jagMemSpace[0xF02100]);
196 uint32_t & g_mtxc = *((uint32_t *)&jagMemSpace[0xF02104]);
197 uint32_t & g_mtxa = *((uint32_t *)&jagMemSpace[0xF02108]);
198 uint32_t & g_end = *((uint32_t *)&jagMemSpace[0xF0210C]);
199 uint32_t & g_pc = *((uint32_t *)&jagMemSpace[0xF02110]);
200 uint32_t & g_ctrl = *((uint32_t *)&jagMemSpace[0xF02114]);
201 uint32_t & g_hidata = *((uint32_t *)&jagMemSpace[0xF02118]);
202 uint32_t & g_divctrl = *((uint32_t *)&jagMemSpace[0xF0211C]);
203 uint32_t g_remain; // Dual register with $F0211C
204 uint32_t & a1_base = *((uint32_t *)&jagMemSpace[0xF02200]);
205 uint32_t & a1_flags = *((uint32_t *)&jagMemSpace[0xF02204]);
206 uint32_t & a1_clip = *((uint32_t *)&jagMemSpace[0xF02208]);
207 uint32_t & a1_pixel = *((uint32_t *)&jagMemSpace[0xF0220C]);
208 uint32_t & a1_step = *((uint32_t *)&jagMemSpace[0xF02210]);
209 uint32_t & a1_fstep = *((uint32_t *)&jagMemSpace[0xF02214]);
210 uint32_t & a1_fpixel = *((uint32_t *)&jagMemSpace[0xF02218]);
211 uint32_t & a1_inc = *((uint32_t *)&jagMemSpace[0xF0221C]);
212 uint32_t & a1_finc = *((uint32_t *)&jagMemSpace[0xF02220]);
213 uint32_t & a2_base = *((uint32_t *)&jagMemSpace[0xF02224]);
214 uint32_t & a2_flags = *((uint32_t *)&jagMemSpace[0xF02228]);
215 uint32_t & a2_mask = *((uint32_t *)&jagMemSpace[0xF0222C]);
216 uint32_t & a2_pixel = *((uint32_t *)&jagMemSpace[0xF02230]);
217 uint32_t & a2_step = *((uint32_t *)&jagMemSpace[0xF02234]);
218 uint32_t & b_cmd = *((uint32_t *)&jagMemSpace[0xF02238]);
219 uint32_t & b_count = *((uint32_t *)&jagMemSpace[0xF0223C]);
220 uint64_t & b_srcd = *((uint64_t *)&jagMemSpace[0xF02240]);
221 uint64_t & b_dstd = *((uint64_t *)&jagMemSpace[0xF02248]);
222 uint64_t & b_dstz = *((uint64_t *)&jagMemSpace[0xF02250]);
223 uint64_t & b_srcz1 = *((uint64_t *)&jagMemSpace[0xF02258]);
224 uint64_t & b_srcz2 = *((uint64_t *)&jagMemSpace[0xF02260]);
225 uint64_t & b_patd = *((uint64_t *)&jagMemSpace[0xF02268]);
226 uint32_t & b_iinc = *((uint32_t *)&jagMemSpace[0xF02270]);
227 uint32_t & b_zinc = *((uint32_t *)&jagMemSpace[0xF02274]);
228 uint32_t & b_stop = *((uint32_t *)&jagMemSpace[0xF02278]);
229 uint32_t & b_i3 = *((uint32_t *)&jagMemSpace[0xF0227C]);
230 uint32_t & b_i2 = *((uint32_t *)&jagMemSpace[0xF02280]);
231 uint32_t & b_i1 = *((uint32_t *)&jagMemSpace[0xF02284]);
232 uint32_t & b_i0 = *((uint32_t *)&jagMemSpace[0xF02288]);
233 uint32_t & b_z3 = *((uint32_t *)&jagMemSpace[0xF0228C]);
234 uint32_t & b_z2 = *((uint32_t *)&jagMemSpace[0xF02290]);
235 uint32_t & b_z1 = *((uint32_t *)&jagMemSpace[0xF02294]);
236 uint32_t & b_z0 = *((uint32_t *)&jagMemSpace[0xF02298]);
237 uint16_t & jpit1 = *((uint16_t *)&jagMemSpace[0xF10000]);
238 uint16_t & jpit2 = *((uint16_t *)&jagMemSpace[0xF10002]);
239 uint16_t & jpit3 = *((uint16_t *)&jagMemSpace[0xF10004]);
240 uint16_t & jpit4 = *((uint16_t *)&jagMemSpace[0xF10006]);
241 uint16_t & clk1 = *((uint16_t *)&jagMemSpace[0xF10010]);
242 uint16_t & clk2 = *((uint16_t *)&jagMemSpace[0xF10012]);
243 uint16_t & clk3 = *((uint16_t *)&jagMemSpace[0xF10014]);
244 uint16_t & j_int = *((uint16_t *)&jagMemSpace[0xF10020]);
245 uint16_t & asidata = *((uint16_t *)&jagMemSpace[0xF10030]);
246 uint16_t & asictrl = *((uint16_t *)&jagMemSpace[0xF10032]);
247 uint16_t asistat; // Dual register with $F10032
248 uint16_t & asiclk = *((uint16_t *)&jagMemSpace[0xF10034]);
249 uint16_t & joystick = *((uint16_t *)&jagMemSpace[0xF14000]);
250 uint16_t & joybuts = *((uint16_t *)&jagMemSpace[0xF14002]);
251 uint32_t & d_flags = *((uint32_t *)&jagMemSpace[0xF1A100]);
252 uint32_t & d_mtxc = *((uint32_t *)&jagMemSpace[0xF1A104]);
253 uint32_t & d_mtxa = *((uint32_t *)&jagMemSpace[0xF1A108]);
254 uint32_t & d_end = *((uint32_t *)&jagMemSpace[0xF1A10C]);
255 uint32_t & d_pc = *((uint32_t *)&jagMemSpace[0xF1A110]);
256 uint32_t & d_ctrl = *((uint32_t *)&jagMemSpace[0xF1A114]);
257 uint32_t & d_mod = *((uint32_t *)&jagMemSpace[0xF1A118]);
258 uint32_t & d_divctrl = *((uint32_t *)&jagMemSpace[0xF1A11C]);
259 uint32_t d_remain; // Dual register with $F0211C
260 uint32_t & d_machi = *((uint32_t *)&jagMemSpace[0xF1A120]);
261 uint16_t & ltxd = *((uint16_t *)&jagMemSpace[0xF1A148]);
262 uint16_t lrxd; // Dual register with $F1A148
263 uint16_t & rtxd = *((uint16_t *)&jagMemSpace[0xF1A14C]);
264 uint16_t rrxd; // Dual register with $F1A14C
265 uint8_t & sclk = *((uint8_t *) &jagMemSpace[0xF1A150]);
266 uint8_t sstat; // Dual register with $F1A150
267 uint32_t & smode = *((uint32_t *)&jagMemSpace[0xF1A154]);
268
269 // Memory debugging identifiers
270
271 const char * whoName[10] =
272 { "Unknown", "Jaguar", "DSP", "GPU", "TOM", "JERRY", "M68K", "Blitter", "OP", "Debugger" };