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