2022-02-28 15:04:25 +00:00
|
|
|
#pragma once
|
|
|
|
|
|
|
|
#include <vector>
|
|
|
|
|
|
|
|
#include "Types.hpp"
|
|
|
|
#include "CPU.hpp"
|
|
|
|
#include "PPU.hpp"
|
2022-03-03 16:29:56 +00:00
|
|
|
#include "APU.hpp"
|
2022-02-28 15:04:25 +00:00
|
|
|
#include "Cartridge.hpp"
|
2022-03-01 17:13:47 +00:00
|
|
|
#include "ControllerPort.hpp"
|
2022-02-28 15:04:25 +00:00
|
|
|
|
2022-02-28 15:39:33 +00:00
|
|
|
/**
|
|
|
|
* @brief The main bus for hardware to communicate.
|
|
|
|
*
|
|
|
|
* This is not a realistic representation of the NES's bus, as the
|
|
|
|
* CPU and PPU don't share a bus in the real world. However this
|
|
|
|
* bus class still doesn't give the CPU/PPU direct access to the other
|
|
|
|
* components address space.
|
|
|
|
*/
|
2022-02-28 15:04:25 +00:00
|
|
|
class Bus
|
|
|
|
{
|
|
|
|
friend class Debugger;
|
|
|
|
friend class MemoryViewer;
|
|
|
|
friend class NametableViewer;
|
2022-03-03 16:29:56 +00:00
|
|
|
friend class Palettes;
|
2022-02-28 15:04:25 +00:00
|
|
|
|
|
|
|
public:
|
2022-03-03 01:33:08 +00:00
|
|
|
Bus(Screen* screen);
|
2022-02-28 15:04:25 +00:00
|
|
|
|
2022-02-28 15:39:33 +00:00
|
|
|
/**
|
|
|
|
* @brief Reboot the NES.
|
|
|
|
*
|
|
|
|
* This equates to turning the NES off and on again.
|
|
|
|
* Internal state will be equal to the powerup state
|
|
|
|
*/
|
2022-02-28 15:04:25 +00:00
|
|
|
void Reboot();
|
2022-02-28 15:39:33 +00:00
|
|
|
|
|
|
|
/**
|
|
|
|
* @brief Resets the NES.
|
|
|
|
*
|
|
|
|
* Internal state will be equal to the reset state
|
|
|
|
*/
|
2022-02-28 15:04:25 +00:00
|
|
|
void Reset();
|
|
|
|
|
2022-02-28 15:39:33 +00:00
|
|
|
/**
|
|
|
|
* @brief Advance the emulator by one CPU cycle (and 3 PPU cycles).
|
|
|
|
*/
|
2022-02-28 15:04:25 +00:00
|
|
|
uint8_t Tick();
|
2022-02-28 15:39:33 +00:00
|
|
|
|
2022-03-06 22:31:52 +00:00
|
|
|
void DMATick();
|
|
|
|
|
2022-03-02 13:59:42 +00:00
|
|
|
void PPUTick();
|
|
|
|
|
2022-02-28 15:39:33 +00:00
|
|
|
/**
|
|
|
|
* @brief Advance the emulator by one CPU instruction.
|
|
|
|
*/
|
2022-02-28 15:04:25 +00:00
|
|
|
bool Instruction();
|
2022-02-28 15:39:33 +00:00
|
|
|
|
|
|
|
/**
|
|
|
|
* @brief Advance the emulator by one Frame.
|
|
|
|
* The emulator runs until the PPU triggers VBlankStart
|
|
|
|
*/
|
2022-02-28 15:04:25 +00:00
|
|
|
bool Frame();
|
|
|
|
|
2022-02-28 15:39:33 +00:00
|
|
|
/**
|
|
|
|
* @brief Read call from the CPU
|
|
|
|
*/
|
2022-02-28 15:04:25 +00:00
|
|
|
Byte ReadCPU(Word addr);
|
2022-02-28 15:39:33 +00:00
|
|
|
|
|
|
|
/**
|
|
|
|
* @brief Read call from the PPU
|
|
|
|
*/
|
2022-02-28 15:04:25 +00:00
|
|
|
Byte ReadPPU(Word addr);
|
2022-02-28 15:39:33 +00:00
|
|
|
|
|
|
|
/**
|
|
|
|
* @brief Write call from the CPU
|
|
|
|
*/
|
2022-02-28 15:04:25 +00:00
|
|
|
void WriteCPU(Word addr, Byte val);
|
2022-02-28 15:39:33 +00:00
|
|
|
|
|
|
|
/**
|
|
|
|
* @brief Write call from the PPU
|
|
|
|
*/
|
2022-02-28 15:04:25 +00:00
|
|
|
void WritePPU(Word addr, Byte val);
|
|
|
|
|
2022-02-28 15:39:33 +00:00
|
|
|
/**
|
|
|
|
* @brief Lets the PPU trigger NMIs.
|
|
|
|
*/
|
2022-02-28 15:04:25 +00:00
|
|
|
inline void NMI() { cpu.NMI(); }
|
2022-03-03 16:29:56 +00:00
|
|
|
inline void IRQ() { cpu.IRQ(); }
|
2022-02-28 15:04:25 +00:00
|
|
|
|
|
|
|
private:
|
|
|
|
std::vector<Byte> RAM, VRAM;
|
2022-03-03 16:29:56 +00:00
|
|
|
std::vector<Byte> palettes;
|
2022-02-28 15:04:25 +00:00
|
|
|
CPU cpu;
|
|
|
|
PPU ppu;
|
2022-03-03 16:29:56 +00:00
|
|
|
APU apu;
|
2022-02-28 15:04:25 +00:00
|
|
|
Cartridge cartridge;
|
2022-03-01 17:13:47 +00:00
|
|
|
ControllerPort controllerPort;
|
2022-03-02 13:59:42 +00:00
|
|
|
|
2022-03-06 22:31:52 +00:00
|
|
|
Byte preDMACycles = 0;
|
2022-03-08 15:03:19 +00:00
|
|
|
Word DMACyclesLeft = 0;
|
2022-03-06 22:31:52 +00:00
|
|
|
Byte DMAPage = 0;
|
|
|
|
Byte DMALatch = 0;
|
|
|
|
|
2022-03-02 13:59:42 +00:00
|
|
|
uint8_t ppuClock = 0;
|
2022-02-28 15:04:25 +00:00
|
|
|
};
|