-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathbus.cc
More file actions
112 lines (96 loc) · 2.85 KB
/
Copy pathbus.cc
File metadata and controls
112 lines (96 loc) · 2.85 KB
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
#include "bus.h"
#include "logging.h"
#include "cartridge.h"
#include "controller.h"
#include "cpu.h"
#include "ppu.h"
#include "dma.h"
#include <cstdint>
#include <iostream>
#include <memory>
#define CONTROLLER_POLL 0x4016
#define CONTROLLER_POLL2 0x4016
#define TRIGGER_OAM 0x4014
Bus::Bus() : cpu{this}, ppu{}, dma{this, &ppu} {}
Bus::~Bus() {}
void Bus::Cpu_write(uint16_t adr, uint8_t data) {
// if ever a cartridge read/write operation interferes with
// a CPU read/write, the cartridge has priority over the CPU
if (card->cpu_write(adr, data)) {
}
else if (adr >= 0x0000 && adr <= 0x1FFF) { // the CPU has "mirrors until
cpu_ram[adr & 0x07FF] = data;
} else if (adr >= 0x2000 && adr <= 0x3FFF) {
ppu.cpu_write(adr & 0x0007, data);
}
// special register of the CPU called OAMDMA
// the data it writes to this register (val)
// will be the top 2 bytes of where the copying
// from OAM starts. So if data = 0x02, we copy the data
// from 0x0200 to 0x02FF (256 bytes or entire OAM always)
else if (adr == TRIGGER_OAM) {
oamdma(data);
cpu.oam = true;
}
else if (adr == CONTROLLER_POLL) {
bool strobe = data & 0x01;
controller.detect_input();
if (!strobe && controller.prev_strobe) {
controller.shifted_count = 0;
}
controller.prev_strobe = strobe;
}
else if (adr >= 0x6000 && adr <= 0x7FFF) {
cartridge_ram[adr - 0x6000] = data;
}
}
uint8_t Bus::Cpu_read(uint16_t adr, bool bReadOnly) {
// data that can be read from cartridge as a reference
uint8_t data{0x00};
if (card->cpu_read(adr, data)) {
} else if (adr >= 0x0000 && adr <= 0x1FFF) {
data = cpu_ram[adr & 0x07FF]; // need to do the and operation because of
// mirroring which just allows the NES to
// access a single address from multiple
// different ones (reduces hardware)
}
// cpu accessing PPU registers to communicate with it
else if (adr >= 0x2000 && adr <= 0x3FFF) {
return ppu.cpu_read(adr & 0x0007, bReadOnly);
}
else if (adr == CONTROLLER_POLL) {
if (controller.prev_strobe) {
data = controller.input.a_button;
}
else if (controller.shifted_count >= 8) {
return 1;
}
else if (!controller.prev_strobe) {
data = 0x01 & controller.input.reg;
controller.shifted_count++;
controller.input.reg >>= 1;
}
}
else if (adr >= 0x6000 && adr <= 0x7FFF) {
data = cartridge_ram[adr - 0x6000];
}
return data;
}
void Bus::oamdma(uint8_t addr) {
dma.copy_256(addr);
}
void Bus::reset() {
total_clock_count = 0;
cpu.reset();
}
void Bus::clock() {
cpu.clock();
for (int i = 0; i < 3; i++) {
if (ppu.clock()) cpu.nmi();
total_clock_count++;
}
}
void Bus::insert_card(std::unique_ptr<Cartridge> c) {
card = std::move(c);
ppu.connectCard(card.get());
}