Avocado/src/system.h

158 lines
4.1 KiB
C
Raw Normal View History

2017-03-10 14:55:17 -05:00
#pragma once
2017-09-04 18:56:42 -04:00
#include <cstdint>
#include "cpu/cpu.h"
2019-11-21 17:56:55 -05:00
#include "device/cache_control.h"
2019-08-04 05:09:28 -04:00
#include "device/cdrom/cdrom.h"
#include "device/controller/controller.h"
#include "device/dma/dma.h"
#include "device/expansion2.h"
#include "device/gpu/gpu.h"
#include "device/interrupt.h"
2018-11-25 14:28:02 -05:00
#include "device/mdec/mdec.h"
#include "device/memory_control.h"
#include "device/ram_control.h"
#include "device/serial.h"
#include "device/spu/spu.h"
#include "device/timer.h"
#include "utils/macros.h"
#include "utils/timing.h"
2017-03-30 16:36:54 -04:00
2017-04-29 17:36:14 -04:00
#include <memory>
#include <vector>
/**
2017-04-26 13:27:22 -04:00
* NOTE:
* Build flags are configured with Premake5 build system
*/
2017-06-19 18:04:49 -04:00
/**
* #define ENABLE_IO_LOG
* Switch --enable-io-log
* Default: false
*
* Enables IO access buffer log
*/
2021-12-21 12:13:59 -05:00
/**
* #define ENABLE_BIOS_HOOKS
* Switch --enable-bios-hooks
* Default: false
*
* Enables BIOS syscall hooking/logging
*/
2017-03-30 16:36:54 -04:00
namespace bios {
struct Function;
}
struct System {
2017-03-10 14:55:17 -05:00
enum class State {
halted, // Cannot be run until reset
stop, // after reset
pause, // if debugger attach
run // normal state
2017-04-29 17:36:14 -04:00
};
static const int BIOS_BASE = 0x1fc00000;
static const int RAM_BASE = 0x00000000;
static const int SCRATCHPAD_BASE = 0x1f800000;
static const int EXPANSION_BASE = 0x1f000000;
static const int IO_BASE = 0x1f801000;
2017-04-29 17:36:14 -04:00
static const int BIOS_SIZE = 512 * 1024;
2021-11-12 19:29:34 -05:00
static const int RAM_SIZE_2MB = 2 * 1024 * 1024;
static const int RAM_SIZE_8MB = 8 * 1024 * 1024;
2017-04-29 17:36:14 -04:00
static const int SCRATCHPAD_SIZE = 1024;
static const int EXPANSION_SIZE = 1 * 1024 * 1024;
static const int IO_SIZE = 0x2000;
2017-04-29 17:36:14 -04:00
State state = State::stop;
2017-03-10 14:55:17 -05:00
std::array<uint8_t, BIOS_SIZE> bios;
2021-11-12 19:29:34 -05:00
std::vector<uint8_t> ram;
std::array<uint8_t, SCRATCHPAD_SIZE> scratchpad;
std::array<uint8_t, EXPANSION_SIZE> expansion;
bool debugOutput = true; // Print BIOS logs
bool biosLoaded = false;
uint64_t cycles;
2017-04-02 12:14:36 -04:00
// Devices
std::unique_ptr<mips::CPU> cpu;
std::unique_ptr<device::cdrom::CDROM> cdrom;
std::unique_ptr<device::controller::Controller> controller;
std::unique_ptr<device::dma::DMA> dma;
std::unique_ptr<Expansion2> expansion2;
std::unique_ptr<gpu::GPU> gpu;
std::unique_ptr<Interrupt> interrupt;
2018-11-25 14:28:02 -05:00
std::unique_ptr<mdec::MDEC> mdec;
std::unique_ptr<MemoryControl> memoryControl;
std::unique_ptr<RamControl> ramControl;
2019-11-21 17:56:55 -05:00
std::unique_ptr<CacheControl> cacheControl;
std::unique_ptr<spu::SPU> spu;
std::unique_ptr<Serial> serial;
std::array<std::unique_ptr<device::timer::Timer>, 3> timer;
2017-03-10 14:55:17 -05:00
template <typename T>
INLINE T readMemory(uint32_t address);
template <typename T>
INLINE void writeMemory(uint32_t address, T data);
2017-09-03 18:42:30 -04:00
void singleStep();
2017-03-30 16:36:54 -04:00
void handleBiosFunction();
2019-05-18 07:34:33 -04:00
void handleSyscallFunction();
2017-03-30 16:36:54 -04:00
System();
2017-03-10 14:55:17 -05:00
uint8_t readMemory8(uint32_t address);
uint16_t readMemory16(uint32_t address);
uint32_t readMemory32(uint32_t address);
void writeMemory8(uint32_t address, uint8_t data);
void writeMemory16(uint32_t address, uint16_t data);
void writeMemory32(uint32_t address, uint32_t data);
2019-05-18 07:34:33 -04:00
void printFunctionInfo(const char* functionNum, const bios::Function& f);
2017-04-21 18:38:12 -04:00
void emulateFrame();
2017-06-19 18:04:49 -04:00
void softReset();
bool isSystemReady();
2017-03-10 14:55:17 -05:00
// Helpers
std::string biosPath;
int biosLog = 0;
2017-03-10 14:55:17 -05:00
bool printStackTrace = false;
bool loadBios(const std::string& name);
bool loadExpansion(const std::vector<uint8_t>& _exe);
bool loadExeFile(const std::vector<uint8_t>& _exe);
2017-03-30 16:36:54 -04:00
void dumpRam();
2017-06-19 18:04:49 -04:00
#ifdef ENABLE_IO_LOG
struct IO_LOG_ENTRY {
enum class MODE { READ, WRITE } mode;
2017-09-04 19:00:28 -04:00
2017-06-19 18:04:49 -04:00
uint32_t size;
uint32_t addr;
uint32_t data;
2018-05-25 09:41:44 -04:00
uint32_t pc;
2017-06-19 18:04:49 -04:00
};
2017-09-04 19:00:28 -04:00
2017-06-19 18:04:49 -04:00
std::vector<IO_LOG_ENTRY> ioLogList;
#endif
template <class Archive>
void serialize(Archive& ar) {
ar(*cpu);
ar(*gpu);
ar(*spu);
ar(*interrupt);
ar(*dma);
ar(*cdrom);
ar(*memoryControl);
2019-11-21 17:56:55 -05:00
ar(*cacheControl);
ar(*serial);
ar(*mdec);
ar(*controller);
for (auto i : {0, 1, 2}) ar(*timer[i]);
ar(ram);
ar(scratchpad);
}
2018-08-07 02:27:30 -04:00
};