Create a directory for EEPROMs if it doesn't already exist
[clinton/Virtual-Jaguar-Rx.git] / src / memory.cpp
CommitLineData
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
17Really, just six megabytes short of using the entire address space...
18Why not? We could just allocate the entire space and then use the MMU code to do
19things like call functions and whatnot...
20In other words, read/write would just tuck the value into the host RAM space and
21the I/O function would take care of any weird stuff...
22
23Actually: writes would tuck in the value, but reads would have to be handled
24correctly since some registers do not fall on the same address as far as reading
25goes... Still completely doable though. :-)
26
27N.B.: Jaguar RAM is only 2 megs. ROM is 6 megs max, IO is 128K
28*/
29
30#include "memory.h"
31
32uint8_t jagMemSpace[0xF20000]; // The entire memory space of the Jaguar...!
33
34uint8_t * jaguarMainRAM = &jagMemSpace[0x000000];
35uint8_t * jaguarMainROM = &jagMemSpace[0x800000];
36uint8_t * cdRAM = &jagMemSpace[0xDFFF00];
37uint8_t * gpuRAM = &jagMemSpace[0xF03000];
38uint8_t * dspRAM = &jagMemSpace[0xF1B000];
39
40#if 0
41union 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
56union 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
71static 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...
101unsigned 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
119uint32_t & butch = *((uint32_t *)&jagMemSpace[0xDFFF00]); // base of Butch == interrupt control register, R/W
120uint32_t & dscntrl = *((uint32_t *)&jagMemSpace[0xDFFF04]); // DSA control register, R/W
121uint16_t & ds_data = *((uint16_t *)&jagMemSpace[0xDFFF0A]); // DSA TX/RX data, R/W
122uint32_t & i2cntrl = *((uint32_t *)&jagMemSpace[0xDFFF10]); // i2s bus control register, R/W
123uint32_t & sbcntrl = *((uint32_t *)&jagMemSpace[0xDFFF14]); // CD subcode control register, R/W
124uint32_t & subdata = *((uint32_t *)&jagMemSpace[0xDFFF18]); // Subcode data register A
125uint32_t & subdatb = *((uint32_t *)&jagMemSpace[0xDFFF1C]); // Subcode data register B
126uint32_t & sb_time = *((uint32_t *)&jagMemSpace[0xDFFF20]); // Subcode time and compare enable (D24)
127uint32_t & fifo_data = *((uint32_t *)&jagMemSpace[0xDFFF24]); // i2s FIFO data
128uint32_t & i2sdat2 = *((uint32_t *)&jagMemSpace[0xDFFF28]); // i2s FIFO data (old)
129uint32_t & unknown = *((uint32_t *)&jagMemSpace[0xDFFF2C]); // Seems to be some sort of I2S interface
130#else
131uint32_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
158uint16_t & memcon1 = *((uint16_t *)&jagMemSpace[0xF00000]);
159uint16_t & memcon2 = *((uint16_t *)&jagMemSpace[0xF00002]);
160uint16_t & hc = *((uint16_t *)&jagMemSpace[0xF00004]);
161uint16_t & vc = *((uint16_t *)&jagMemSpace[0xF00006]);
162uint16_t & lph = *((uint16_t *)&jagMemSpace[0xF00008]);
163uint16_t & lpv = *((uint16_t *)&jagMemSpace[0xF0000A]);
164uint64_t & obData = *((uint64_t *)&jagMemSpace[0xF00010]);
165uint32_t & olp = *((uint32_t *)&jagMemSpace[0xF00020]);
166uint16_t & obf = *((uint16_t *)&jagMemSpace[0xF00026]);
167uint16_t & vmode = *((uint16_t *)&jagMemSpace[0xF00028]);
168uint16_t & bord1 = *((uint16_t *)&jagMemSpace[0xF0002A]);
169uint16_t & bord2 = *((uint16_t *)&jagMemSpace[0xF0002C]);
170uint16_t & hp = *((uint16_t *)&jagMemSpace[0xF0002E]);
171uint16_t & hbb = *((uint16_t *)&jagMemSpace[0xF00030]);
172uint16_t & hbe = *((uint16_t *)&jagMemSpace[0xF00032]);
173uint16_t & hs = *((uint16_t *)&jagMemSpace[0xF00034]);
174uint16_t & hvs = *((uint16_t *)&jagMemSpace[0xF00036]);
175uint16_t & hdb1 = *((uint16_t *)&jagMemSpace[0xF00038]);
176uint16_t & hdb2 = *((uint16_t *)&jagMemSpace[0xF0003A]);
177uint16_t & hde = *((uint16_t *)&jagMemSpace[0xF0003C]);
178uint16_t & vp = *((uint16_t *)&jagMemSpace[0xF0003E]);
179uint16_t & vbb = *((uint16_t *)&jagMemSpace[0xF00040]);
180uint16_t & vbe = *((uint16_t *)&jagMemSpace[0xF00042]);
181uint16_t & vs = *((uint16_t *)&jagMemSpace[0xF00044]);
182uint16_t & vdb = *((uint16_t *)&jagMemSpace[0xF00046]);
183uint16_t & vde = *((uint16_t *)&jagMemSpace[0xF00048]);
184uint16_t & veb = *((uint16_t *)&jagMemSpace[0xF0004A]);
185uint16_t & vee = *((uint16_t *)&jagMemSpace[0xF0004C]);
186uint16_t & vi = *((uint16_t *)&jagMemSpace[0xF0004E]);
187uint16_t & pit0 = *((uint16_t *)&jagMemSpace[0xF00050]);
188uint16_t & pit1 = *((uint16_t *)&jagMemSpace[0xF00052]);
189uint16_t & heq = *((uint16_t *)&jagMemSpace[0xF00054]);
190uint32_t & bg = *((uint32_t *)&jagMemSpace[0xF00058]);
191uint16_t & int1 = *((uint16_t *)&jagMemSpace[0xF000E0]);
192uint16_t & int2 = *((uint16_t *)&jagMemSpace[0xF000E2]);
193uint8_t * clut = (uint8_t *) &jagMemSpace[0xF00400];
194uint8_t * lbuf = (uint8_t *) &jagMemSpace[0xF00800];
195uint32_t & g_flags = *((uint32_t *)&jagMemSpace[0xF02100]);
196uint32_t & g_mtxc = *((uint32_t *)&jagMemSpace[0xF02104]);
197uint32_t & g_mtxa = *((uint32_t *)&jagMemSpace[0xF02108]);
198uint32_t & g_end = *((uint32_t *)&jagMemSpace[0xF0210C]);
199uint32_t & g_pc = *((uint32_t *)&jagMemSpace[0xF02110]);
200uint32_t & g_ctrl = *((uint32_t *)&jagMemSpace[0xF02114]);
201uint32_t & g_hidata = *((uint32_t *)&jagMemSpace[0xF02118]);
202uint32_t & g_divctrl = *((uint32_t *)&jagMemSpace[0xF0211C]);
203uint32_t g_remain; // Dual register with $F0211C
204uint32_t & a1_base = *((uint32_t *)&jagMemSpace[0xF02200]);
205uint32_t & a1_flags = *((uint32_t *)&jagMemSpace[0xF02204]);
206uint32_t & a1_clip = *((uint32_t *)&jagMemSpace[0xF02208]);
207uint32_t & a1_pixel = *((uint32_t *)&jagMemSpace[0xF0220C]);
208uint32_t & a1_step = *((uint32_t *)&jagMemSpace[0xF02210]);
209uint32_t & a1_fstep = *((uint32_t *)&jagMemSpace[0xF02214]);
210uint32_t & a1_fpixel = *((uint32_t *)&jagMemSpace[0xF02218]);
211uint32_t & a1_inc = *((uint32_t *)&jagMemSpace[0xF0221C]);
212uint32_t & a1_finc = *((uint32_t *)&jagMemSpace[0xF02220]);
213uint32_t & a2_base = *((uint32_t *)&jagMemSpace[0xF02224]);
214uint32_t & a2_flags = *((uint32_t *)&jagMemSpace[0xF02228]);
215uint32_t & a2_mask = *((uint32_t *)&jagMemSpace[0xF0222C]);
216uint32_t & a2_pixel = *((uint32_t *)&jagMemSpace[0xF02230]);
217uint32_t & a2_step = *((uint32_t *)&jagMemSpace[0xF02234]);
218uint32_t & b_cmd = *((uint32_t *)&jagMemSpace[0xF02238]);
219uint32_t & b_count = *((uint32_t *)&jagMemSpace[0xF0223C]);
220uint64_t & b_srcd = *((uint64_t *)&jagMemSpace[0xF02240]);
221uint64_t & b_dstd = *((uint64_t *)&jagMemSpace[0xF02248]);
222uint64_t & b_dstz = *((uint64_t *)&jagMemSpace[0xF02250]);
223uint64_t & b_srcz1 = *((uint64_t *)&jagMemSpace[0xF02258]);
224uint64_t & b_srcz2 = *((uint64_t *)&jagMemSpace[0xF02260]);
225uint64_t & b_patd = *((uint64_t *)&jagMemSpace[0xF02268]);
226uint32_t & b_iinc = *((uint32_t *)&jagMemSpace[0xF02270]);
227uint32_t & b_zinc = *((uint32_t *)&jagMemSpace[0xF02274]);
228uint32_t & b_stop = *((uint32_t *)&jagMemSpace[0xF02278]);
229uint32_t & b_i3 = *((uint32_t *)&jagMemSpace[0xF0227C]);
230uint32_t & b_i2 = *((uint32_t *)&jagMemSpace[0xF02280]);
231uint32_t & b_i1 = *((uint32_t *)&jagMemSpace[0xF02284]);
232uint32_t & b_i0 = *((uint32_t *)&jagMemSpace[0xF02288]);
233uint32_t & b_z3 = *((uint32_t *)&jagMemSpace[0xF0228C]);
234uint32_t & b_z2 = *((uint32_t *)&jagMemSpace[0xF02290]);
235uint32_t & b_z1 = *((uint32_t *)&jagMemSpace[0xF02294]);
236uint32_t & b_z0 = *((uint32_t *)&jagMemSpace[0xF02298]);
237uint16_t & jpit1 = *((uint16_t *)&jagMemSpace[0xF10000]);
238uint16_t & jpit2 = *((uint16_t *)&jagMemSpace[0xF10002]);
239uint16_t & jpit3 = *((uint16_t *)&jagMemSpace[0xF10004]);
240uint16_t & jpit4 = *((uint16_t *)&jagMemSpace[0xF10006]);
241uint16_t & clk1 = *((uint16_t *)&jagMemSpace[0xF10010]);
242uint16_t & clk2 = *((uint16_t *)&jagMemSpace[0xF10012]);
243uint16_t & clk3 = *((uint16_t *)&jagMemSpace[0xF10014]);
244uint16_t & j_int = *((uint16_t *)&jagMemSpace[0xF10020]);
245uint16_t & asidata = *((uint16_t *)&jagMemSpace[0xF10030]);
246uint16_t & asictrl = *((uint16_t *)&jagMemSpace[0xF10032]);
247uint16_t asistat; // Dual register with $F10032
248uint16_t & asiclk = *((uint16_t *)&jagMemSpace[0xF10034]);
249uint16_t & joystick = *((uint16_t *)&jagMemSpace[0xF14000]);
250uint16_t & joybuts = *((uint16_t *)&jagMemSpace[0xF14002]);
251uint32_t & d_flags = *((uint32_t *)&jagMemSpace[0xF1A100]);
252uint32_t & d_mtxc = *((uint32_t *)&jagMemSpace[0xF1A104]);
253uint32_t & d_mtxa = *((uint32_t *)&jagMemSpace[0xF1A108]);
254uint32_t & d_end = *((uint32_t *)&jagMemSpace[0xF1A10C]);
255uint32_t & d_pc = *((uint32_t *)&jagMemSpace[0xF1A110]);
256uint32_t & d_ctrl = *((uint32_t *)&jagMemSpace[0xF1A114]);
257uint32_t & d_mod = *((uint32_t *)&jagMemSpace[0xF1A118]);
258uint32_t & d_divctrl = *((uint32_t *)&jagMemSpace[0xF1A11C]);
259uint32_t d_remain; // Dual register with $F0211C
260uint32_t & d_machi = *((uint32_t *)&jagMemSpace[0xF1A120]);
261uint16_t & ltxd = *((uint16_t *)&jagMemSpace[0xF1A148]);
262uint16_t lrxd; // Dual register with $F1A148
263uint16_t & rtxd = *((uint16_t *)&jagMemSpace[0xF1A14C]);
264uint16_t rrxd; // Dual register with $F1A14C
265uint8_t & sclk = *((uint8_t *) &jagMemSpace[0xF1A150]);
266uint8_t sstat; // Dual register with $F1A150
267uint32_t & smode = *((uint32_t *)&jagMemSpace[0xF1A154]);
268
269// Memory debugging identifiers
270
271const char * whoName[10] =
272 { "Unknown", "Jaguar", "DSP", "GPU", "TOM", "JERRY", "M68K", "Blitter", "OP", "Debugger" };