dev_dreamcast_gdrom.cc Source File

Back to the index.

dev_dreamcast_gdrom.cc
Go to the documentation of this file.
1 /*
2  * Copyright (C) 2006-2014 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  * COMMENT: Dreamcast GD-ROM
29  *
30  * TODO: This is mostly just a dummy so far. It is enough for NetBSD/dreamcast
31  * to read the GD-ROM (or actually, just a particular Live CD). It shouldn't
32  * be assumed to work for anything else.
33  */
34 
35 #include <stdio.h>
36 #include <stdlib.h>
37 #include <string.h>
38 
39 #include "cpu.h"
40 #include "device.h"
41 #include "diskimage.h"
42 #include "machine.h"
43 #include "memory.h"
44 #include "misc.h"
45 
47 
48 
49 // #define debug fatal
50 
51 #define NREGS_GDROM_DMA (0x100/sizeof(uint32_t))
52 
54  // 0x005f7000: GDROM control registers
55  uint8_t busy; /* Busy status */
56  uint8_t stat; /* Status */
57  int cnt; /* Data length in bytes */
58  uint8_t cond;
59 
60  int cmd_count;
61  uint8_t cmd[12];
62 
63  uint8_t *data;
64  int data_len;
66  int cur_cnt;
67 
68  // 0x005f7400: GDROM DMA
70 };
71 
72 /* Register offsets, from NetBSD: */
73 #define GDROM_BUSY 0x18
74 #define GDROM_DATA 0x80
75 #define GDROM_REGX 0x84
76 #define GDROM_UNKNOWN_0x88 0x88
77 #define GDROM_STAT 0x8c
78 #define GDROM_CNTLO 0x90
79 #define GDROM_CNTHI 0x94
80 #define GDROM_COND 0x9c
81 
82 // See the interrupt routine (gdrom_intr()) in NetBSD's dreamcast/dev/gdrom.c:
83 #define COND_DATA_AVAIL 0x08
84 
85 
86 static void alloc_data(struct dreamcast_gdrom_data *d)
87 {
88  d->data_len = d->cnt;
89 
90  CHECK_ALLOCATION(d->data = (uint8_t *) malloc(d->data_len));
91  memset(d->data, 0, d->data_len);
92 }
93 
94 
95 static void handle_command(struct cpu *cpu, struct dreamcast_gdrom_data *d)
96 {
97  int64_t sector_nr, sector_count;
98  int i, res;
99 
100  debug("[ GDROM cmd: ");
101  for (i=0; i<12; i++)
102  debug("%02x ", d->cmd[i]);
103  debug("(cnt=%i) ]\n", d->cnt);
104 
105  if (d->data != NULL)
106  free(d->data);
107  d->data = NULL;
108  d->cur_data_offset = 0;
109  d->cur_cnt = 0;
110 
111  switch (d->cmd[0]) {
112 
113  case 0x14:
114  /*
115  * Read Table-Of-Contents:
116  *
117  * See NetBSD's sys/arch/dreamcast/dev/gdrom.c: gdrom_read_toc().
118  */
119  if (d->cnt != 408) {
120  fatal("GDROM Read TOC not 408 bytes?\n");
121  exit(1);
122  }
123  alloc_data(d);
124 
125  /*
126  * From David Brownlee:
127  * "TOC from test booted real CD image on NetBSD/dreamcast
128  * 01000096,41002e4c,ffffffff * 97,01010000,41020000,6100e641,"
129  *
130  * TODO: Perhaps generalize this in the future, to support
131  * disk images with multiple TOCs and/or tracks.
132  */
133  memset(d->data, 0xff, d->cnt); /* Default data to 0xff */
134 
135  d->data[0*4] = 0x10; /* Track 1 */
136  d->data[0*4+1] = 0;
137  d->data[0*4+2] = 0;
138  d->data[0*4+3] = 0x96;
139 
140  d->data[1*4] = 0x41; /* Track 2 */
141  d->data[1*4+1] = 0;
142  d->data[1*4+2] = 0x2e;
143  d->data[1*4+3] = 0x4c;
144 
145  d->data[99*4] = 0x01; /* First track */
146  d->data[99*4+1] = 0x01;
147  d->data[99*4+2] = 0;
148  d->data[99*4+3] = 0;
149 
150  d->data[100*4] = 0x41; /* Last track */
151  d->data[100*4+1] = 0x02;
152  d->data[100*4+2] = 0;
153  d->data[100*4+3] = 0;
154 
155  d->data[101*4] = 0x61; /* Leadout */
156  d->data[101*4+1] = 0;
157  d->data[101*4+2] = 0xe6;
158  d->data[101*4+3] = 0x41;
159 
160  break;
161 
162  case 0x30:
163  /*
164  * Read sectors:
165  *
166  * See NetBSD's sys/arch/dreamcast/dev/gdrom.c: gdrom_read_sectors().
167  */
168  if (d->cmd[1] == 0x24) {
169  fatal("GDROM unimplemented data format 0x%02x. Continuing anway.\n", d->cmd[1]);
170  } else if (d->cmd[1] != 0x20) {
171  fatal("GDROM unimplemented data format 0x%02x\n",
172  d->cmd[1]);
173  exit(1);
174  }
175  sector_nr = d->cmd[2] * 65536 + d->cmd[3] * 256 + d->cmd[4];
176  sector_count = d->cmd[8] * 65536 + d->cmd[9] * 256 + d->cmd[10];
177 
178  // NetBSD/dreamcast uses correct length, but the Dreamcast PROM
179  // uses len = 0 (!), but sector count = 7,
180  // which means len = 0x3800. It also sets up DMA to
181  // transfer 0x3800 bytes, so I'm assuming that the
182  // sector count is to be trusted more than the length.
183  if (d->cnt == 0)
184  d->cnt = 2048 * sector_count;
185 
186  if (sector_count * 2048 != d->cnt) {
187  fatal("Huh? GDROM data_len=0x%x, but sector_count"
188  "=0x%x\n", (int)d->cnt, (int)sector_count);
189  exit(1);
190  }
191 
192  alloc_data(d);
193 
194  // Hm. This is an ugly hack to make a NetBSD/dreamcast
195  // live-cd work. It should be fixed (i.e. removed).
196  // When running with -Q (i.e. no PROM software emulation),
197  // experiments with the Dreamcast PROM can be made instead.
198  if (cpu->machine->prom_emulation) {
199  // printf("sector nr step 1 = %i\n", (int)sector_nr);
200 
201  // Hack to get NetBSD/dreamcast to work:
202  // See the variable "openpart_start" in NetBSD's
203  // sys/arch/dreamcast/dev/gdrom.c:
204  sector_nr -= 150;
205 
206  // printf("sector nr step 2 = %i\n", (int)sector_nr);
207  } else {
208  // printf("sector nr step 1 = %i\n", (int)sector_nr);
209  sector_nr -= 45150;
210  // printf("sector nr step 2 = %i\n", (int)sector_nr);
211  sector_nr += (diskimage_get_baseoffset(cpu->machine, 0, DISKIMAGE_IDE) / 2048);
212  // printf("sector nr step 3 = %i\n", (int)sector_nr);
213  }
214 
216  0, sector_nr * 2048, d->data, d->data_len);
217  if (!res) {
218  fatal("GDROM: diskimage_access failed? TODO\n");
219  free(d->data);
220  d->data = NULL;
221  }
222 
223  /* {
224  printf("(Dump of GDROM sector %i: \"", (int)sector_nr);
225  for (int k = 0; k < 256; ++k)
226  printf("%c", d->data[k] >= 32 ? d->data[k] : '.');
227  printf("\")\n");
228  } */
229 
230  break;
231 
232  case 0x70:
233  /*
234  * Mount:
235  *
236  * See NetBSD's sys/arch/dreamcast/dev/gdrom.c: gdrom_mount_disk().
237  */
238 
239  // Note/TODO: This is ignored for now.
240  break;
241 
242  default:fatal("GDROM handle_command: unimplemented command 0x%02x"
243  "\n", d->cmd[0]);
244  exit(1);
245  }
246 
247  // Any resulting data? Then set COND_DATA_AVAIL. Otherwise, clear
248  // that bit, and set count to zero.
249  if (d->data != NULL) {
250  d->cond |= COND_DATA_AVAIL;
251  } else {
252  d->cnt = 0;
253  d->cond &= ~COND_DATA_AVAIL;
254  }
255 
256  // NetBSD seems to sometimes request 32 sectors (2048 bytes each), i.e.
257  // 65536 bytes. That is represented as count = 0x0000 (when NetBSD reads
258  // from the CNTHI and CNTLO registers). That does not work very well.
259  // This is a hack/workaround for that.
260  if (d->cnt == 65536)
261  d->cnt = 32768;
262 
264 }
265 
267 {
268  // See NetBSD's gdrom.c.
269  d->stat = 6;
270 
272  d->stat = 0;
273  }
274 }
275 
276 
277 DEVICE_ACCESS(dreamcast_gdrom)
278 {
279  struct dreamcast_gdrom_data *d = (struct dreamcast_gdrom_data *) extra;
280  uint64_t idata = 0, odata = 0;
281 
282  if (writeflag == MEM_WRITE)
283  idata = memory_readmax64(cpu, data, len);
284 
285  switch (relative_addr) {
286 
287  case GDROM_BUSY:
288  if (writeflag == MEM_READ) {
289  odata = d->busy;
290  } else {
291  // fatal("[ Write to GDROM_BUSY: 0x%08x ]\n", (int)idata);
292  // I'm assuming that writing bits to BUSY clears them.
293  d->busy &= ~idata;
294  }
295  break;
296 
297  case GDROM_DATA:
298  if (len != sizeof(uint16_t)) {
299  fatal("Non-16bit GDROM data access? TODO\n");
300  exit(1);
301  }
302 
303  if (writeflag == MEM_READ) {
304  if (!(d->cond & COND_DATA_AVAIL)) {
305  fatal("Read from GDROM_DATA when no data"
306  " is available? TODO\n");
307  exit(1);
308  }
309 
310  if (d->cur_data_offset < d->data_len) {
311  odata = d->data[d->cur_data_offset ++];
312  odata |= (d->data[d->cur_data_offset ++] << 8);
313  d->cur_cnt += sizeof(uint16_t);
314  if (d->cur_cnt >= d->cnt) {
315  if (d->cur_data_offset >= d->data_len) {
316  d->cond &= ~COND_DATA_AVAIL;
317  } else {
318  d->cnt = d->data_len - d->cur_data_offset;
319  d->cur_cnt = 0;
320  }
321 
323  }
324  } else {
325  fatal("Read too much from GDROM_DATA\n");
326  exit(1);
327  }
328  } else {
329  if (d->busy & 0x08) {
330  if (d->cmd_count >= 12) {
331  fatal("Too much GDROM_DATA?\n");
332  exit(1);
333  }
334  /* Add data to cmd: */
335  d->cmd[d->cmd_count++] = idata;
336  d->cmd[d->cmd_count++] = idata >> 8;
337  if (d->cmd_count == 12) {
338  d->busy &= ~0x08;
339  handle_command(cpu, d);
340  }
341  } else {
342  fatal("Write to GDROM_DATA, but not waiting"
343  " for data?\n");
344  exit(1);
345  }
346  }
347  break;
348 
349  case GDROM_REGX:
350  if (writeflag == MEM_READ) {
351  debug("[ Read to GDROM_REGX? ]\n");
352  } else {
353  /* NetBSD/dreamcast writes 0 here. */
354  if (idata != 0)
355  debug("[ Write 0x%x to GDROM_REGX? ]\n", (int)idata);
356  }
357  break;
358 
359  case GDROM_UNKNOWN_0x88:
360  if (writeflag == MEM_READ) {
361  fatal("Read from GDROM_UNKNOWN_0x88?\n");
362  // exit(1);
363  } else {
364  if (idata != 0xb) {
365  fatal("[ Write to GDROM_UNKNOWN_0x88: TODO ]\n");
366  exit(1);
367  }
368  }
369  break;
370 
371  case GDROM_STAT:
372  if (writeflag == MEM_READ) {
374  odata = d->stat;
375  } else {
376  fatal("[ Write to GDROM_STAT? ]\n");
377 /* exit(1); */
378  }
379  break;
380 
381  case GDROM_CNTLO:
382  if (writeflag == MEM_READ) {
383  odata = d->cnt & 0xff;
384  } else {
385  d->cnt = (d->cnt & 0xff00) | (idata & 0xff);
386  }
387  break;
388 
389  case GDROM_CNTHI:
390  if (writeflag == MEM_READ) {
391  odata = (d->cnt >> 8) & 0xff;
392  } else {
393  d->cnt = (d->cnt & 0x00ff) | ((idata & 0xff) << 8);
394  }
395  break;
396 
397  case GDROM_COND:
398  if (writeflag == MEM_READ) {
399  odata = d->cond;
400  } else {
401  d->cond = idata;
402 
403  /*
404  * NetBSD/dreamcast writes 0xa0 to GDROM_COND to
405  * start a command. See gdrom_do_command() in NetBSD's
406  * sys/arch/dreamcast/dev/gdrom.c.
407  *
408  * Before sending anything, NetBSD expects:
409  * o) the lowest 4 bits of STAT to not be 6.
410  *
411  * After writing 0xa0 to GDROM_COND, NetBSD expects:
412  * o) (BUSY & 0x88) to be 0x08.
413  *
414  * NetBSD then sends 6 16-bit data words to GDROM_DATA.
415  */
416  if (idata == 0xa0) {
417  d->stat = 0; /* TODO */
418  d->busy |= 0x08;
419  d->cmd_count = 0;
420  } else if (idata == 0xef) {
421  debug("dreamcast_gdrom: ROM: TODO\n");
423  } else {
424  fatal("dreamcast_gdrom: unimplemented "
425  "GDROM_COND = 0x%02x\n", (int)idata);
426  exit(1);
427  }
428  }
429  break;
430 
431  default:if (writeflag == MEM_READ) {
432  fatal("[ dreamcast_gdrom: read from addr 0x%x ]\n",
433  (int)relative_addr);
434  } else {
435  fatal("[ dreamcast_gdrom: write to addr 0x%x: 0x%x ]\n",
436  (int)relative_addr, (int)idata);
437  }
438 
439  exit(1);
440  }
441 
442  if (writeflag == MEM_READ)
443  memory_writemax64(cpu, data, len, odata);
444 
445  return 1;
446 }
447 
448 
449 DEVICE_ACCESS(dreamcast_gdrom_dma)
450 {
451  struct dreamcast_gdrom_data *d = (struct dreamcast_gdrom_data *) extra;
452  uint64_t idata = 0, odata = 0;
453 
454  if (writeflag == MEM_WRITE)
455  idata = memory_readmax64(cpu, data, len);
456 
457  /* Default read: */
458  if (writeflag == MEM_READ)
459  odata = d->dma_reg[relative_addr / sizeof(uint32_t)];
460 
461  switch (relative_addr) {
462 
463  case 0x04: // destination address? e.g. 0x8c008000
464  case 0x08: // DMA length in bytes? e.g. 0x3800
465  case 0x0c: // count? e.g. 1
466  case 0x14: // "enable"?
467  break;
468 
469  case 0x18:
470  // GDROM DMA start?
471  if (idata != 0) {
472  if (d->dma_reg[0x0c / sizeof(uint32_t)] == 1 &&
473  d->dma_reg[0x14 / sizeof(uint32_t)] == 1) {
474  // GDROM DMA transfer.
475  uint32_t dst = d->dma_reg[0x04 / sizeof(uint32_t)];
476  int length = d->dma_reg[0x08 / sizeof(uint32_t)];
477  fatal("[ dreamcast_gdrom_dma: Transfering %i bytes to 0x%08" PRIx32" ]\n", length, dst);
478 
479  if (d->data == NULL) {
480  fatal("dreamcast_gdrom_dma: DMA transfer but d->data is NULL. TODO\n");
481  exit(1);
482  }
483 
484  dst &= 0x0fffffff; // 0x8c008000 => 0x0c008000
485  cpu->memory_rw(cpu, cpu->mem, dst,
486  d->data, d->data_len, MEM_WRITE, PHYSICAL);
487 
489 
490  idata = 0;
491  } else {
492  fatal("Unimplemented GDROM DMA start? TODO\n");
493  fatal(" %08x\n", (int) d->dma_reg[4 / sizeof(uint32_t)]);
494  fatal(" %08x\n", (int) d->dma_reg[8 / sizeof(uint32_t)]);
495  fatal(" %08x\n", (int) d->dma_reg[0xc / sizeof(uint32_t)]);
496  fatal(" %08x\n", (int) d->dma_reg[0x14 / sizeof(uint32_t)]);
497  exit(1);
498  }
499  }
500  break;
501 
502  default:if (writeflag == MEM_READ) {
503  fatal("[ dreamcast_gdrom_dma: read from addr 0x%x ]\n",
504  (int)relative_addr);
505  } else {
506  fatal("[ dreamcast_gdrom_dma: write to addr 0x%x: "
507  "0x%x ]\n", (int)relative_addr, (int)idata);
508  }
509 
510  exit(1);
511  }
512 
513  /* Default write: */
514  if (writeflag == MEM_WRITE)
515  d->dma_reg[relative_addr / sizeof(uint32_t)] = idata;
516 
517  if (writeflag == MEM_READ)
518  memory_writemax64(cpu, data, len, odata);
519 
520  return 1;
521 }
522 
523 
524 DEVINIT(dreamcast_gdrom)
525 {
526  struct dreamcast_gdrom_data *d;
527 
528  CHECK_ALLOCATION(d = (struct dreamcast_gdrom_data *) malloc(sizeof(struct dreamcast_gdrom_data)));
529  memset(d, 0, sizeof(struct dreamcast_gdrom_data));
530 
532  0x005f7000, 0x100, dev_dreamcast_gdrom_access, d,
533  DM_DEFAULT, NULL);
534 
535  memory_device_register(devinit->machine->memory, "gdrom_dma", 0x005f7400,
536  0x80, dev_dreamcast_gdrom_dma_access, d, DM_DEFAULT, NULL);
537 
538  return 1;
539 }
540 
data
u_short data
Definition: siireg.h:79
GDROM_COND
#define GDROM_COND
Definition: dev_dreamcast_gdrom.cc:80
dreamcast_gdrom_data
Definition: dev_dreamcast_gdrom.cc:53
dreamcast_sysasicvar.h
dreamcast_gdrom_data::cnt
int cnt
Definition: dev_dreamcast_gdrom.cc:57
dreamcast_gdrom_data::cond
uint8_t cond
Definition: dev_dreamcast_gdrom.cc:58
diskimage.h
debug
#define debug
Definition: dev_adb.cc:57
memory_device_register
void memory_device_register(struct memory *mem, const char *, uint64_t baseaddr, uint64_t len, int(*f)(struct cpu *, struct memory *, uint64_t, unsigned char *, size_t, int, void *), void *extra, int flags, unsigned char *dyntrans_data)
Definition: memory.cc:339
MEM_READ
#define MEM_READ
Definition: memory.h:116
DM_DEFAULT
#define DM_DEFAULT
Definition: memory.h:130
diskimage_access
int diskimage_access(struct machine *machine, int id, int type, int writeflag, off_t offset, unsigned char *buf, size_t len)
Definition: diskimage.cc:617
devinit::machine
struct machine * machine
Definition: device.h:41
machine::prom_emulation
int prom_emulation
Definition: machine.h:149
COND_DATA_AVAIL
#define COND_DATA_AVAIL
Definition: dev_dreamcast_gdrom.cc:83
device.h
dreamcast_gdrom_data::data_len
int data_len
Definition: dev_dreamcast_gdrom.cc:64
cmd
Definition: debugger_cmds.cc:1189
MEM_WRITE
#define MEM_WRITE
Definition: memory.h:117
dreamcast_gdrom_update_stat
void dreamcast_gdrom_update_stat(struct cpu *cpu, struct dreamcast_gdrom_data *d)
Definition: dev_dreamcast_gdrom.cc:266
PHYSICAL
#define PHYSICAL
Definition: memory.h:126
fatal
void fatal(const char *fmt,...)
Definition: main.cc:152
SYSASIC_EVENT_GDROM_DMA
#define SYSASIC_EVENT_GDROM_DMA
Definition: dreamcast_sysasicvar.h:62
dreamcast_gdrom_data::cur_data_offset
int cur_data_offset
Definition: dev_dreamcast_gdrom.cc:65
diskimage_get_baseoffset
int64_t diskimage_get_baseoffset(struct machine *machine, int id, int type)
Definition: diskimage.cc:222
misc.h
memory_readmax64
uint64_t memory_readmax64(struct cpu *cpu, unsigned char *buf, int len)
Definition: memory.cc:55
GDROM_UNKNOWN_0x88
#define GDROM_UNKNOWN_0x88
Definition: dev_dreamcast_gdrom.cc:76
machine.h
GDROM_STAT
#define GDROM_STAT
Definition: dev_dreamcast_gdrom.cc:77
devinit::name
char * name
Definition: device.h:43
dreamcast_gdrom_data::stat
uint8_t stat
Definition: dev_dreamcast_gdrom.cc:56
devinit
Definition: device.h:40
cpu.h
SYSASIC_EVENT_GDROM
#define SYSASIC_EVENT_GDROM
Definition: dreamcast_sysasicvar.h:67
GDROM_CNTHI
#define GDROM_CNTHI
Definition: dev_dreamcast_gdrom.cc:79
NREGS_GDROM_DMA
#define NREGS_GDROM_DMA
Definition: dev_dreamcast_gdrom.cc:51
machine::memory
struct memory * memory
Definition: machine.h:126
dreamcast_gdrom_data::cur_cnt
int cur_cnt
Definition: dev_dreamcast_gdrom.cc:66
cpu::mem
struct memory * mem
Definition: cpu.h:362
cpu::machine
struct machine * machine
Definition: cpu.h:328
DEVICE_ACCESS
DEVICE_ACCESS(dreamcast_gdrom)
Definition: dev_dreamcast_gdrom.cc:277
dreamcast_gdrom_data::dma_reg
uint32_t dma_reg[NREGS_GDROM_DMA]
Definition: dev_dreamcast_gdrom.cc:69
GDROM_BUSY
#define GDROM_BUSY
Definition: dev_dreamcast_gdrom.cc:73
dreamcast_gdrom_data::cmd
uint8_t cmd[12]
Definition: dev_dreamcast_gdrom.cc:61
dreamcast_gdrom_data::busy
uint8_t busy
Definition: dev_dreamcast_gdrom.cc:55
GDROM_DATA
#define GDROM_DATA
Definition: dev_dreamcast_gdrom.cc:74
DISKIMAGE_IDE
#define DISKIMAGE_IDE
Definition: diskimage.h:41
SYSASIC_TRIGGER_EVENT
#define SYSASIC_TRIGGER_EVENT(e)
Definition: dreamcast_sysasicvar.h:77
memory_writemax64
void memory_writemax64(struct cpu *cpu, unsigned char *buf, int len, uint64_t data)
Definition: memory.cc:89
GDROM_REGX
#define GDROM_REGX
Definition: dev_dreamcast_gdrom.cc:75
cpu
Definition: cpu.h:326
dreamcast_gdrom_data::cmd_count
int cmd_count
Definition: dev_dreamcast_gdrom.cc:60
dreamcast_gdrom_data::data
uint8_t * data
Definition: dev_dreamcast_gdrom.cc:63
cpu::memory_rw
int(* memory_rw)(struct cpu *cpu, struct memory *mem, uint64_t vaddr, unsigned char *data, size_t len, int writeflag, int cache_flags)
Definition: cpu.h:368
DEVINIT
DEVINIT(dreamcast_gdrom)
Definition: dev_dreamcast_gdrom.cc:524
GDROM_CNTLO
#define GDROM_CNTLO
Definition: dev_dreamcast_gdrom.cc:78
memory.h
diskimage_exist
int diskimage_exist(struct machine *machine, int id, int type)
Definition: diskimage.cc:106
CHECK_ALLOCATION
#define CHECK_ALLOCATION(ptr)
Definition: misc.h:239

Generated on Tue Aug 25 2020 19:25:06 for GXemul by doxygen 1.8.18