/[gxemul]/upstream/0.4.6/src/devices/dev_dreamcast_g2.c
This is repository of my old source code which isn't updated any more. Go to git.rot13.org for current projects!
ViewVC logotype

Contents of /upstream/0.4.6/src/devices/dev_dreamcast_g2.c

Parent Directory Parent Directory | Revision Log Revision Log


Revision 43 - (show annotations)
Mon Oct 8 16:22:43 2007 UTC (16 years, 7 months ago) by dpavlin
File MIME type: text/plain
File size: 7640 byte(s)
0.4.6
1 /*
2 * Copyright (C) 2006-2007 Anders Gavare. All rights reserved.
3 *
4 * Redistribution and use in source and binary forms, with or without
5 * modification, are permitted provided that the following conditions are met:
6 *
7 * 1. Redistributions of source code must retain the above copyright
8 * notice, this list of conditions and the following disclaimer.
9 * 2. Redistributions in binary form must reproduce the above copyright
10 * notice, this list of conditions and the following disclaimer in the
11 * documentation and/or other materials provided with the distribution.
12 * 3. The name of the author may not be used to endorse or promote products
13 * derived from this software without specific prior written permission.
14 *
15 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
16 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
17 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
18 * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
19 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
20 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
21 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
22 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
23 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
24 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
25 * SUCH DAMAGE.
26 *
27 *
28 * $Id: dev_dreamcast_g2.c,v 1.5 2007/06/15 19:11:15 debug Exp $
29 *
30 * COMMENT: Dreamcast G2 bus
31 *
32 * Register offsets are from KOS, NetBSD sources, etc.
33 *
34 * TODO:
35 * Figure out what all these registers do!
36 */
37
38 #include <stdio.h>
39 #include <stdlib.h>
40 #include <string.h>
41
42 #include "cpu.h"
43 #include "device.h"
44 #include "machine.h"
45 #include "memory.h"
46 #include "misc.h"
47
48
49 #ifdef UNSTABLE_DEVEL
50 #define debug fatal
51 #endif
52
53 #define NREGS (0x100/sizeof(uint32_t))
54
55 struct dreamcast_g2_data {
56 uint32_t dma_reg[NREGS];
57 uint32_t extdma_reg[NREGS];
58 uint32_t unknown_reg[NREGS];
59 };
60
61 /* dma_reg[] offsets: */
62 #define PVR_STATE 0x00
63 #define PVR_LEN 0x04
64 #define PVR_DST 0x08
65 #define PVR_LMMODE0 0x84
66 #define PVR_LMMODE1 0x88
67
68 /*
69 * External DMA: 4 channels
70 *
71 * Note: Addresses and sizes must be 32-byte aligned.
72 * DIR is 0 for CPU to External device, 1 for External to CPU.
73 * MODE should be 5 for transfers to/from the SPU.
74 */
75 #define EXTDMA_CTRL_EXT_ADDR 0x00 /* EXTDMA_CTRL_* are repeated */
76 #define EXTDMA_CTRL_SH4_ADDR 0x04 /* 4 times (once for each channel) */
77 #define EXTDMA_CTRL_SIZE 0x08
78 #define EXTDMA_CTRL_DIR 0x0c
79 #define EXTDMA_CTRL_MODE 0x10
80 #define EXTDMA_CTRL_CTRL1 0x14
81 #define EXTDMA_CTRL_CTRL2 0x18
82 #define EXTDMA_CTRL_UNKNOWN 0x1c
83
84 #define EXTDMA_WAITSTATE 0x90
85 #define EXTDMA_MAGIC 0xbc
86 #define EXTDMA_MAGIC_VALUE 0x4659404f
87
88 #define EXTDMA_STAT_EXT_ADDR 0xc0 /* EXTDMA_STAT_* are repeated 4 */
89 #define EXTDMA_STAT_SH4_ADDR 0xc4 /* times too */
90 #define EXTDMA_STAT_SIZE 0xc8
91 #define EXTDMA_STAT_STATUS 0xcc
92
93
94 DEVICE_ACCESS(dreamcast_g2)
95 {
96 struct dreamcast_g2_data *d = extra;
97 uint64_t idata = 0, odata = 0;
98
99 if (writeflag == MEM_WRITE)
100 idata = memory_readmax64(cpu, data, len);
101
102 /* Default read: */
103 if (writeflag == MEM_READ)
104 odata = d->dma_reg[relative_addr / sizeof(uint32_t)];
105
106 switch (relative_addr) {
107
108 case PVR_LMMODE0: /* 0x84 */
109 case PVR_LMMODE1: /* 0x88 */
110 if (writeflag == MEM_WRITE) {
111 if (idata == 0) {
112 /* Done by IP.BIN during startup... */
113 } else {
114 fatal("[ dreamcast_g2: UNIMPLEMENTED write "
115 "0x84/0x88: TODO ]\n");
116 exit(1);
117 }
118 } else {
119 fatal("[ dreamcast_g2: read from 0x84/0x88: TODO ]\n");
120 exit(1);
121 }
122 break;
123
124 case 0x8c:
125 if (writeflag == MEM_WRITE) {
126 fatal("[ dreamcast_g2: write to 0x8c: TODO ]\n");
127 exit(1);
128 } else {
129 /* 0x20 means G2 DMA in progress? */
130 /* 0x11 = mask which has to do with AICA */
131 odata = 0x11 * (random() & 1);
132 }
133 break;
134
135 default:if (writeflag == MEM_READ) {
136 fatal("[ dreamcast_g2: read from addr 0x%x ]\n",
137 (int)relative_addr);
138 } else {
139 fatal("[ dreamcast_g2: write to addr 0x%x: 0x%x ]\n",
140 (int)relative_addr, (int)idata);
141 }
142 exit(1);
143 }
144
145 /* Default write: */
146 if (writeflag == MEM_WRITE)
147 d->dma_reg[relative_addr / sizeof(uint32_t)] = idata;
148
149 if (writeflag == MEM_READ)
150 memory_writemax64(cpu, data, len, odata);
151
152 return 1;
153 }
154
155
156 DEVICE_ACCESS(dreamcast_g2_extdma)
157 {
158 struct dreamcast_g2_data *d = extra;
159 uint64_t idata = 0, odata = 0;
160 int reg = relative_addr, channel = 0;
161
162 if (writeflag == MEM_WRITE)
163 idata = memory_readmax64(cpu, data, len);
164
165 /* Default read: */
166 if (writeflag == MEM_READ)
167 odata = d->extdma_reg[relative_addr / sizeof(uint32_t)];
168
169 if (reg < 0x7f) {
170 channel = (reg >> 5) & 3;
171 reg &= 0x1f;
172 }
173
174 if (reg >= 0xc0 && reg < 0xff) {
175 channel = (reg >> 4) & 3;
176 reg = 0xc0 + (reg & 0xf);
177 }
178
179 switch (reg) {
180
181 case EXTDMA_WAITSTATE:
182 break;
183
184 case 0x94:
185 /* Written to by boot stage 1 in IP.BIN? */
186 if (writeflag == MEM_WRITE) {
187 if (idata != 0x271) {
188 fatal("Unimplemented write to extdma 0x94\n");
189 exit(1);
190 }
191 }
192 break;
193
194 default:if (writeflag == MEM_READ) {
195 fatal("[ dreamcast_g2_extdma: read from addr 0x%x ]\n",
196 (int)relative_addr);
197 } else {
198 fatal("[ dreamcast_g2_extdma: write to addr 0x%x: "
199 "0x%x ]\n", (int)relative_addr, (int)idata);
200 }
201 exit(1);
202 }
203
204 /* Default write: */
205 if (writeflag == MEM_WRITE)
206 d->extdma_reg[relative_addr / sizeof(uint32_t)] = idata;
207
208 if (writeflag == MEM_READ)
209 memory_writemax64(cpu, data, len, odata);
210
211 return 1;
212 }
213
214
215 DEVICE_ACCESS(dreamcast_g2_unknown)
216 {
217 struct dreamcast_g2_data *d = extra;
218 uint64_t idata = 0, odata = 0;
219
220 if (writeflag == MEM_WRITE)
221 idata = memory_readmax64(cpu, data, len);
222
223 /* Default read: */
224 if (writeflag == MEM_READ)
225 odata = d->unknown_reg[relative_addr / sizeof(uint32_t)];
226
227 switch (relative_addr) {
228
229 case 0x90:
230 case 0x94:
231 if (writeflag != MEM_WRITE || idata != 0x222) {
232 fatal("[ dreamcast_g2_unknown: unimplemented 0x90 ]\n");
233 exit(1);
234 }
235 break;
236
237 case 0xa0:
238 case 0xa4:
239 if (writeflag != MEM_WRITE || idata != 0x2001) {
240 fatal("[ dreamcast_g2_unknown: unimplemented 0xa0 ]\n");
241 exit(1);
242 }
243 break;
244
245 case 0xe4:
246 /* Writing 0x1fffff resets a disabled GD-ROM drive? */
247 if (writeflag != MEM_WRITE || idata != 0x1fffff) {
248 fatal("[ dreamcast_g2_unknown: unimplemented 0xe4 ]\n");
249 exit(1);
250 }
251 break;
252
253 default:if (writeflag == MEM_READ) {
254 fatal("[ dreamcast_g2_unknown: read from addr 0x%x ]\n",
255 (int)relative_addr);
256 } else {
257 fatal("[ dreamcast_g2_unknown: write to addr 0x%x: "
258 "0x%x ]\n", (int)relative_addr, (int)idata);
259 }
260 exit(1);
261 }
262
263 /* Default write: */
264 if (writeflag == MEM_WRITE)
265 d->unknown_reg[relative_addr / sizeof(uint32_t)] = idata;
266
267 if (writeflag == MEM_READ)
268 memory_writemax64(cpu, data, len, odata);
269
270 return 1;
271 }
272
273
274 DEVINIT(dreamcast_g2)
275 {
276 struct machine *machine = devinit->machine;
277 struct dreamcast_g2_data *d;
278
279 CHECK_ALLOCATION(d = malloc(sizeof(struct dreamcast_g2_data)));
280 memset(d, 0, sizeof(struct dreamcast_g2_data));
281
282 memory_device_register(machine->memory, devinit->name,
283 0x005f6800, 0x100, dev_dreamcast_g2_access, d, DM_DEFAULT, NULL);
284
285 memory_device_register(machine->memory, devinit->name, 0x005f7800,
286 0x100, dev_dreamcast_g2_extdma_access, d, DM_DEFAULT, NULL);
287
288 memory_device_register(machine->memory, devinit->name, 0x005f7400,
289 0x100, dev_dreamcast_g2_unknown_access, d, DM_DEFAULT, NULL);
290
291 return 1;
292 }
293

  ViewVC Help
Powered by ViewVC 1.1.26