File: controller.c

package info (click to toggle)
cen64 0.3%2Bgit20160403-1
  • links: PTS, VCS
  • area: main
  • in suites: stretch
  • size: 4,160 kB
  • sloc: ansic: 14,512; asm: 772; cpp: 663; makefile: 12
file content (113 lines) | stat: -rw-r--r-- 3,363 bytes parent folder | download | duplicates (3)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
//
// ri/controller.c: RAM interface controller.
//
// CEN64: Cycle-Accurate Nintendo 64 Emulator.
// Copyright (C) 2015, Tyler J. Stachecki.
//
// This file is subject to the terms and conditions defined in
// 'LICENSE', which is part of this source code package.
//

#include "common.h"
#include "bus/address.h"
#include "bus/controller.h"
#include "ri/controller.h"

#ifdef DEBUG_MMIO_REGISTER_ACCESS
const char *rdram_register_mnemonics[NUM_RDRAM_REGISTERS] = {
#define X(reg) #reg,
#include "ri/rdram_registers.md"
#undef X
};
#endif

#ifdef DEBUG_MMIO_REGISTER_ACCESS
const char *ri_register_mnemonics[NUM_RI_REGISTERS] = {
#define X(reg) #reg,
#include "ri/registers.md"
#undef X
};
#endif

// Initializes the RI.
int ri_init(struct ri_controller *ri, struct bus_controller *bus) {
  ri->bus = bus;

  // MESS uses these, so we will too?
  ri->regs[RI_MODE_REG] = 0xE;
  ri->regs[RI_CONFIG_REG] = 0x40;
  ri->regs[RI_SELECT_REG] = 0x14;
  ri->regs[RI_REFRESH_REG] = 0x63634;

  return 0;
}

// Reads a word from RDRAM.
int read_rdram(void *opaque, uint32_t address, uint32_t *word) {
  struct ri_controller *ri = (struct ri_controller *) opaque;
  unsigned offset = address - RDRAM_BASE_ADDRESS;

  memcpy(word, ri->ram + offset, sizeof(*word));
  *word = byteswap_32(*word);
  return 0;
}

// Reads a word from the RDRAM MMIO register space.
int read_rdram_regs(void *opaque, uint32_t address, uint32_t *word) {
  struct ri_controller *ri = (struct ri_controller *) opaque;
  unsigned offset = address - RDRAM_REGS_BASE_ADDRESS;
  enum rdram_register reg = (offset >> 2);

  *word = ri->rdram_regs[reg];
  debug_mmio_read(rdram, rdram_register_mnemonics[reg], *word);
  return 0;
}

// Reads a word from the RI MMIO register space.
int read_ri_regs(void *opaque, uint32_t address, uint32_t *word) {
  struct ri_controller *ri = (struct ri_controller *) opaque;
  unsigned offset = address - RI_REGS_BASE_ADDRESS;
  enum ri_register reg = (offset >> 2);

  *word = ri->regs[reg];
  debug_mmio_read(ri, ri_register_mnemonics[reg], *word);
  return 0;
}

// Writes a word to RDRAM.
int write_rdram(void *opaque, uint32_t address, uint32_t word, uint32_t dqm) {
  struct ri_controller *ri = (struct ri_controller *) opaque;
  unsigned offset = address - RDRAM_BASE_ADDRESS;
  uint32_t orig_word;

  memcpy(&orig_word, ri->ram + offset, sizeof(orig_word));
  orig_word = byteswap_32(orig_word) & ~dqm;
  word = byteswap_32(orig_word | word);
  memcpy(ri->ram + offset, &word, sizeof(word));
  return 0;
}

// Writes a word to the RDRAM MMIO register space.
int write_rdram_regs(void *opaque, uint32_t address, uint32_t word, uint32_t dqm) {
  struct ri_controller *ri = (struct ri_controller *) opaque;
  unsigned offset = address - RDRAM_REGS_BASE_ADDRESS;
  enum rdram_register reg = (offset >> 2);

  debug_mmio_write(rdram, rdram_register_mnemonics[reg], word, dqm);
  ri->rdram_regs[reg] &= ~dqm;
  ri->rdram_regs[reg] |= word;
  return 0;
}

// Writes a word to the RI MMIO register space.
int write_ri_regs(void *opaque, uint32_t address, uint32_t word, uint32_t dqm) {
  struct ri_controller *ri = (struct ri_controller *) opaque;
  unsigned offset = address - RI_REGS_BASE_ADDRESS;
  enum ri_register reg = (offset >> 2);

  debug_mmio_write(ri, ri_register_mnemonics[reg], word, dqm);
  ri->regs[reg] &= ~dqm;
  ri->regs[reg] |= word;
  return 0;
}