Commit | Line | Data |
---|---|---|
cf76e892 JPM |
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" }; |