~groovestomp/gsnes

ref: 8e7b491660f45697b5ca97b6a16e132e6fe8e670 gsnes/bus.c -rwxr-xr-x 3.0 KiB
8e7b4916 — GrooveStomp Fix some more instances of referencing the wrong executable 1 year, 5 months ago
                                                                                
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
114
/******************************************************************************
  GrooveStomp's NES Emulator
  Copyright (c) 2019 Aaron Oman (GrooveStomp)

  File: bus.c
  Created: 2019-10-16
  Updated: 2019-11-30
  Author: Aaron Oman
  Notice: GNU AGPLv3 License

  Based off of: One Lone Coder NES Emulator Copyright (C) 2019 Javidx9
  This program comes with ABSOLUTELY NO WARRANTY.
  This is free software, and you are welcome to redistribute it under certain
  conditions; See LICENSE for details.
 ******************************************************************************/
//! \file bus.c
#include <stdlib.h> // calloc, free

#include "bus.h"
#include "cpu.h"
#include "ppu.h"
#include "cart.h"
#include "util.h"

struct bus {
        struct cpu *cpu;
        struct ppu *ppu;
        struct cart *cart;
        uint8_t *cpuRam; // Dummy RAM for prototyping
        uint32_t tickCount;
};

struct bus *BusInit(struct cpu *cpu, struct ppu *ppu) {
        struct bus *bus = (struct bus *)calloc(1, sizeof(struct bus));
        if (NULL == bus)
                return NULL;

        bus->cpuRam = (uint8_t *)calloc(KB_AS_B(2), sizeof(uint8_t));
        if (NULL == bus->cpuRam) {
                BusDeinit(bus);
                return NULL;
        }

        bus->cpu = cpu;
        bus->ppu = ppu;

        return bus;
}

void BusDeinit(struct bus *bus) {
        if (NULL == bus) {
                return;
        }

        if (NULL != bus->cpuRam) {
                free(bus->cpuRam);
        }

        free(bus);
}

void BusWrite(struct bus *bus, uint16_t addr, uint8_t data) {
        if (CartCpuWrite(bus->cart, addr, data)) {

        } else if (addr >= 0x0000 && addr <= 0x1FFF) {
                // System RAM address range, mirrored every 2048.
                bus->cpuRam[addr & 0x07FF] = data;
        } else if (addr >= 0x2000 && addr <= 0x3FFF) {
                PpuWriteViaCpu(bus->ppu, addr & 0x0007, data);
        }
}

uint8_t BusRead(struct bus *bus, uint16_t addr, bool readOnly) {
        uint8_t data = 0x00;

        if (CartCpuRead(bus->cart, addr, &data)) {
                // Cartridge address range
        } else if (addr >= 0x0000 && addr <= 0x1FFF) {
                // System RAM address range, mirrored every 2048.
                data = bus->cpuRam[addr & 0x07FF];
        } else if (addr >= 0x2000 && addr <= 0x3FFF) {
                // PPU address range, mirrored every 8.
                data = PpuReadViaCpu(bus->ppu, addr & 0x0007, readOnly);
        }

        return data;
}

void BusAttachCart(struct bus *bus, struct cart *cart) {
        bus->cart = cart;
        PpuAttachCart(bus->ppu, cart);
}

void BusReset(struct bus *bus) {
        CartReset(bus->cart);
        CpuReset(bus->cpu);
        PpuReset(bus->ppu);
        bus->tickCount = 0;
}

void BusTick(struct bus *bus) {
        PpuTick(bus->ppu);

        if (0 == (bus->tickCount % 3)) {
                CpuTick(bus->cpu);
        }

        if (PpuGetNmi(bus->ppu)) {
                PpuSetNmi(bus->ppu, false);
                CpuNmi(bus->cpu);
        }

        bus->tickCount++;
}