mirror of
https://github.com/whaison/psxact.git
synced 2024-05-16 19:10:33 -04:00
Adding better I/O logging.
This commit is contained in:
parent
47971a0bad
commit
09c90456ee
|
@ -22,6 +22,8 @@ set(SOURCE_FILES
|
|||
src/gpu/gpu_draw.cpp
|
||||
src/gpu/gpu_draw_gouraud.cpp
|
||||
src/gpu/gpu_draw_texture.cpp
|
||||
src/input/input.cpp
|
||||
src/input/input.hpp
|
||||
src/memory/vram.cpp
|
||||
src/memory/vram.hpp
|
||||
src/spu/spu_core.cpp
|
||||
|
|
307
src/bus.cpp
307
src/bus.cpp
|
@ -1,14 +1,15 @@
|
|||
#include <cassert>
|
||||
#include <cstring>
|
||||
#include <exception>
|
||||
#include "bus.hpp"
|
||||
#include "cdrom/cdrom_core.hpp"
|
||||
#include "cpu/cpu_core.hpp"
|
||||
#include "dma/dma_core.hpp"
|
||||
#include "gpu/gpu_core.hpp"
|
||||
#include "input/input.hpp"
|
||||
#include "spu/spu_core.hpp"
|
||||
#include "utility.hpp"
|
||||
#include "timer/timer_core.hpp"
|
||||
#include "cdrom/cdrom_core.hpp"
|
||||
#include <stdexcept>
|
||||
#include <cstring>
|
||||
#include <cassert>
|
||||
#include "utility.hpp"
|
||||
|
||||
utility::memory_t<19> bios;
|
||||
utility::memory_t<21> wram;
|
||||
|
@ -23,111 +24,63 @@ void bus::initialize(const std::string &bios_file_name, const std::string &game_
|
|||
}
|
||||
|
||||
void bus::irq(int interrupt) {
|
||||
printf("bus::irq(%d)\n", interrupt);
|
||||
cpu::state.i_stat |= (1 << interrupt);
|
||||
}
|
||||
|
||||
uint32_t bus::read_byte(uint32_t address) {
|
||||
uint32_t bus::read(int width, uint32_t address) {
|
||||
if (utility::between<0x00000000, 0x007fffff>(address)) {
|
||||
return utility::read_byte(wram, address);
|
||||
switch (width) {
|
||||
case BYTE: return utility::read_byte(wram, address);
|
||||
case HALF: return utility::read_half(wram, address);
|
||||
case WORD: return utility::read_word(wram, address);
|
||||
}
|
||||
}
|
||||
|
||||
if (utility::between<0x1fc00000, 0x1fc7ffff>(address)) {
|
||||
return utility::read_byte(bios, address);
|
||||
switch (width) {
|
||||
case BYTE: return utility::read_byte(bios, address);
|
||||
case HALF: return utility::read_half(bios, address);
|
||||
case WORD: return utility::read_word(bios, address);
|
||||
}
|
||||
}
|
||||
|
||||
if (utility::between<0x1f800000, 0x1f8003ff>(address)) {
|
||||
return utility::read_byte(dmem, address);
|
||||
switch (width) {
|
||||
case BYTE: return utility::read_byte(dmem, address);
|
||||
case HALF: return utility::read_half(dmem, address);
|
||||
case WORD: return utility::read_word(dmem, address);
|
||||
}
|
||||
}
|
||||
|
||||
if (address == 0x1f000084 ||
|
||||
address == 0x1f801040) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
if (utility::between<0x1f801800, 0x1f801803>(address)) {
|
||||
return cdrom::mmio_read(BYTE, address);
|
||||
}
|
||||
|
||||
printf("bus::read_byte(0x%08x)\n", address);
|
||||
throw std::exception();
|
||||
}
|
||||
|
||||
uint32_t bus::read_half(uint32_t address) {
|
||||
if (utility::between<0x00000000, 0x007fffff>(address)) {
|
||||
return utility::read_half(wram, address);
|
||||
}
|
||||
|
||||
if (utility::between<0x1fc00000, 0x1fc7ffff>(address)) {
|
||||
return utility::read_half(bios, address);
|
||||
}
|
||||
|
||||
if (utility::between<0x1f800000, 0x1f8003ff>(address)) {
|
||||
return utility::read_half(dmem, address);
|
||||
if (utility::between<0x1f801040, 0x1f80104f>(address)) {
|
||||
return input::bus_read(width, address);
|
||||
}
|
||||
|
||||
if (utility::between<0x1f801070, 0x1f801077>(address)) {
|
||||
return cpu::mmio_read(HALF, address);
|
||||
return cpu::bus_read(width, address);
|
||||
}
|
||||
|
||||
if (utility::between<0x1f801080, 0x1f8010ff>(address)) {
|
||||
return dma::bus_read(width, address);
|
||||
}
|
||||
|
||||
if (utility::between<0x1f801100, 0x1f80110f>(address) ||
|
||||
utility::between<0x1f801110, 0x1f80111f>(address) ||
|
||||
utility::between<0x1f801120, 0x1f80112f>(address)) {
|
||||
return timer::bus_read(width, address);
|
||||
}
|
||||
|
||||
if (utility::between<0x1f801800, 0x1f801803>(address)) {
|
||||
return cdrom::bus_read(width, address);
|
||||
}
|
||||
|
||||
if (utility::between<0x1f801810, 0x1f801817>(address)) {
|
||||
return gpu::bus_read(width, address);
|
||||
}
|
||||
|
||||
if (utility::between<0x1f801c00, 0x1f801fff>(address)) {
|
||||
return spu::mmio_read(HALF, address);
|
||||
}
|
||||
|
||||
if (address == 0x1f801120 ||
|
||||
address == 0x1f801044) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
printf("bus::read_half(0x%08x)\n", address);
|
||||
throw std::exception();
|
||||
}
|
||||
|
||||
uint32_t bus::read_word(uint32_t address) {
|
||||
if (utility::between<0x00000000, 0x007fffff>(address)) {
|
||||
return utility::read_word(wram, address);
|
||||
}
|
||||
|
||||
if (utility::between<0x1fc00000, 0x1fc7ffff>(address)) {
|
||||
return utility::read_word(bios, address);
|
||||
}
|
||||
|
||||
if (utility::between<0x1f800000, 0x1f8003ff>(address)) {
|
||||
return utility::read_word(dmem, address);
|
||||
}
|
||||
|
||||
if (utility::between<0x1f801000, 0x1f801fff>(address)) {
|
||||
if (utility::between<0x1f801070, 0x1f80107f>(address)) {
|
||||
return cpu::mmio_read(WORD, address);
|
||||
}
|
||||
|
||||
if (utility::between<0x1f801080, 0x1f8010ff>(address)) {
|
||||
return dma::mmio_read(WORD, address);
|
||||
}
|
||||
|
||||
if (utility::between<0x1f801100, 0x1f80110f>(address) ||
|
||||
utility::between<0x1f801110, 0x1f80111f>(address) ||
|
||||
utility::between<0x1f801120, 0x1f80112f>(address)) {
|
||||
return timer::bus_read(WORD, address);
|
||||
}
|
||||
|
||||
if (utility::between<0x1f801800, 0x1f801803>(address)) {
|
||||
return cdrom::mmio_read(WORD, address);
|
||||
}
|
||||
|
||||
if (utility::between<0x1f801810, 0x1f801817>(address)) {
|
||||
return gpu::mmio_read(WORD, address);
|
||||
}
|
||||
|
||||
if (utility::between<0x1f801c00, 0x1f801fff>(address)) {
|
||||
return spu::mmio_read(WORD, address);
|
||||
}
|
||||
|
||||
printf("unhandled mmio read: $%08x\n", address);
|
||||
return 0;
|
||||
}
|
||||
|
||||
if (address == 0xfffe0130) {
|
||||
return 0;
|
||||
return spu::bus_read(width, address);
|
||||
}
|
||||
|
||||
if (utility::between<0x1f000000, 0x1f7fffff>(address) || // expansion region 1
|
||||
|
@ -136,13 +89,21 @@ uint32_t bus::read_word(uint32_t address) {
|
|||
return 0;
|
||||
}
|
||||
|
||||
printf("bus::read_word(0x%08x)\n", address);
|
||||
if (address == 0xfffe0130) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
printf("bus::read(%d, 0x%08x)\n", width, address);
|
||||
throw std::exception();
|
||||
}
|
||||
|
||||
void bus::write_byte(uint32_t address, uint32_t data) {
|
||||
void bus::write(int width, uint32_t address, uint32_t data) {
|
||||
if (utility::between<0x00000000, 0x007fffff>(address)) {
|
||||
return utility::write_byte(wram, address, data);
|
||||
switch (width) {
|
||||
case BYTE: return utility::write_byte(wram, address, data);
|
||||
case HALF: return utility::write_half(wram, address, data);
|
||||
case WORD: return utility::write_word(wram, address, data);
|
||||
}
|
||||
}
|
||||
|
||||
if (utility::between<0x1fc00000, 0x1fc7ffff>(address)) {
|
||||
|
@ -151,123 +112,41 @@ void bus::write_byte(uint32_t address, uint32_t data) {
|
|||
}
|
||||
|
||||
if (utility::between<0x1f800000, 0x1f8003ff>(address)) {
|
||||
return utility::write_byte(dmem, address, data);
|
||||
switch (width) {
|
||||
case BYTE: return utility::write_byte(dmem, address, data);
|
||||
case HALF: return utility::write_half(dmem, address, data);
|
||||
case WORD: return utility::write_word(dmem, address, data);
|
||||
}
|
||||
}
|
||||
|
||||
if (utility::between<0x1f801800, 0x1f801803>(address)) {
|
||||
return cdrom::mmio_write(BYTE, address, data);
|
||||
}
|
||||
|
||||
if (address == 0x1f802041) {
|
||||
return;
|
||||
}
|
||||
|
||||
printf("unknown byte write: $%08x <- $%08x\n", address, data);
|
||||
throw std::exception();
|
||||
}
|
||||
|
||||
void bus::write_half(uint32_t address, uint32_t data) {
|
||||
if (utility::between<0x00000000, 0x007fffff>(address)) {
|
||||
return utility::write_half(wram, address, data);
|
||||
}
|
||||
|
||||
if (utility::between<0x1fc00000, 0x1fc7ffff>(address)) {
|
||||
printf("bios write: $%08x <- $%08x\n", address, data);
|
||||
return;
|
||||
}
|
||||
|
||||
if (utility::between<0x1f800000, 0x1f8003ff>(address)) {
|
||||
return utility::write_half(dmem, address, data);
|
||||
if (utility::between<0x1f801040, 0x1f80104f>(address)) {
|
||||
return input::bus_write(width, address, data);
|
||||
}
|
||||
|
||||
if (utility::between<0x1f801070, 0x1f801077>(address)) {
|
||||
return cpu::mmio_write(HALF, address, data);
|
||||
return cpu::bus_write(width, address, data);
|
||||
}
|
||||
|
||||
if (utility::between<0x1f801080, 0x1f8010ff>(address)) {
|
||||
return dma::bus_write(width, address, data);
|
||||
}
|
||||
|
||||
if (utility::between<0x1f801100, 0x1f80110f>(address) ||
|
||||
utility::between<0x1f801110, 0x1f80111f>(address) ||
|
||||
utility::between<0x1f801120, 0x1f80112f>(address)) {
|
||||
return timer::bus_write(width, address, data);
|
||||
}
|
||||
|
||||
if (utility::between<0x1f801800, 0x1f801803>(address)) {
|
||||
return cdrom::bus_write(width, address, data);
|
||||
}
|
||||
|
||||
if (utility::between<0x1f801810, 0x1f801817>(address)) {
|
||||
return gpu::bus_write(width, address, data);
|
||||
}
|
||||
|
||||
if (utility::between<0x1f801c00, 0x1f801fff>(address)) {
|
||||
return spu::mmio_write(HALF, address, data);
|
||||
}
|
||||
|
||||
if (address == 0x1f801048 || // joy_mode
|
||||
address == 0x1f80104a || // joy_ctrl
|
||||
address == 0x1f80104e || // joy_baud
|
||||
address == 0x1f801100 ||
|
||||
address == 0x1f801104 ||
|
||||
address == 0x1f801108 ||
|
||||
address == 0x1f801110 ||
|
||||
address == 0x1f801114 ||
|
||||
address == 0x1f801118 ||
|
||||
address == 0x1f801120 ||
|
||||
address == 0x1f801124 ||
|
||||
address == 0x1f801128) {
|
||||
return;
|
||||
}
|
||||
|
||||
printf("unknown half write: $%08x <- $%08x\n", address, data);
|
||||
throw std::exception();
|
||||
}
|
||||
|
||||
void bus::write_word(uint32_t address, uint32_t data) {
|
||||
if (utility::between<0x00000000, 0x007fffff>(address)) {
|
||||
return utility::write_word(wram, address, data);
|
||||
}
|
||||
|
||||
if (utility::between<0x1fc00000, 0x1fc7ffff>(address)) {
|
||||
printf("bios write: $%08x <- $%08x\n", address, data);
|
||||
return;
|
||||
}
|
||||
|
||||
if (utility::between<0x1f800000, 0x1f8003ff>(address)) {
|
||||
return utility::write_word(dmem, address, data);
|
||||
}
|
||||
|
||||
if (utility::between<0x1f801000, 0x1f801fff>(address)) {
|
||||
if (utility::between<0x1f801070, 0x1f80107f>(address)) {
|
||||
return cpu::mmio_write(WORD, address, data);
|
||||
}
|
||||
|
||||
if (utility::between<0x1f801080, 0x1f8010ff>(address)) {
|
||||
return dma::mmio_write(WORD, address, data);
|
||||
}
|
||||
|
||||
if (utility::between<0x1f801100, 0x1f80110f>(address) ||
|
||||
utility::between<0x1f801110, 0x1f80111f>(address) ||
|
||||
utility::between<0x1f801120, 0x1f80112f>(address)) {
|
||||
return timer::bus_write(WORD, address, data);
|
||||
}
|
||||
|
||||
if (utility::between<0x1f801800, 0x1f801803>(address)) {
|
||||
return cdrom::mmio_write(WORD, address, data);
|
||||
}
|
||||
|
||||
if (utility::between<0x1f801810, 0x1f801817>(address)) {
|
||||
return gpu::mmio_write(WORD, address, data);
|
||||
}
|
||||
|
||||
if (utility::between<0x1f801c00, 0x1f801fff>(address)) {
|
||||
return spu::mmio_write(WORD, address, data);
|
||||
}
|
||||
|
||||
switch (address) {
|
||||
case 0x1f801000: assert(data == 0x1f000000); return;
|
||||
case 0x1f801004: assert(data == 0x1f802000); return;
|
||||
case 0x1f801008: assert(data == 0x0013243f); return;
|
||||
case 0x1f80100c: assert(data == 0x00003022); return;
|
||||
case 0x1f801010: assert(data == 0x0013243f); return;
|
||||
case 0x1f801014: assert(data == 0x200931e1); return;
|
||||
case 0x1f801018: assert(data == 0x00020843); return;
|
||||
case 0x1f80101c: assert(data == 0x00070777); return;
|
||||
case 0x1f801020: assert(data == 0x00031125); return;
|
||||
|
||||
case 0x1f801060: assert(data == 0x00000b88); return;
|
||||
}
|
||||
|
||||
printf("unhandled mmio write: $%08x <- $%08x\n", address, data);
|
||||
return;
|
||||
}
|
||||
|
||||
if (address == 0xfffe0130) {
|
||||
return;
|
||||
return spu::bus_write(width, address, data);
|
||||
}
|
||||
|
||||
if (utility::between<0x1f000000, 0x1f7fffff>(address) || // expansion region 1 bus_write
|
||||
|
@ -276,6 +155,24 @@ void bus::write_word(uint32_t address, uint32_t data) {
|
|||
return;
|
||||
}
|
||||
|
||||
printf("unknown word write: $%08x <- $%08x\n", address, data);
|
||||
switch (address) {
|
||||
case 0x1f801000: assert(data == 0x1f000000); return;
|
||||
case 0x1f801004: assert(data == 0x1f802000); return;
|
||||
case 0x1f801008: assert(data == 0x0013243f); return;
|
||||
case 0x1f80100c: assert(data == 0x00003022); return;
|
||||
case 0x1f801010: assert(data == 0x0013243f); return;
|
||||
case 0x1f801014: assert(data == 0x200931e1); return;
|
||||
case 0x1f801018: assert(data == 0x00020843); return;
|
||||
case 0x1f80101c: assert(data == 0x00070777); return;
|
||||
case 0x1f801020: assert(data == 0x00031125); return;
|
||||
|
||||
case 0x1f801060: assert(data == 0x00000b88); return;
|
||||
}
|
||||
|
||||
if (address == 0xfffe0130) {
|
||||
return;
|
||||
}
|
||||
|
||||
printf("bus::write(%d, 0x%08x, 0x%08x)\n", width, address, data);
|
||||
throw std::exception();
|
||||
}
|
||||
|
|
12
src/bus.hpp
12
src/bus.hpp
|
@ -15,17 +15,9 @@ namespace bus {
|
|||
|
||||
void irq(int interrupt);
|
||||
|
||||
uint32_t read_byte(uint32_t address);
|
||||
uint32_t read(int width, uint32_t address);
|
||||
|
||||
uint32_t read_half(uint32_t address);
|
||||
|
||||
uint32_t read_word(uint32_t address);
|
||||
|
||||
void write_byte(uint32_t, uint32_t);
|
||||
|
||||
void write_half(uint32_t, uint32_t);
|
||||
|
||||
void write_word(uint32_t, uint32_t);
|
||||
void write(int width, uint32_t address, uint32_t data);
|
||||
}
|
||||
|
||||
#endif //PSXACT_BUS_HPP
|
||||
|
|
|
@ -37,10 +37,10 @@ static void set_data(uint8_t data) {
|
|||
cdrom::state.data_fifo.push_back(data);
|
||||
}
|
||||
|
||||
uint32_t cdrom::mmio_read(int size, uint32_t address) {
|
||||
assert(size == BYTE);
|
||||
uint32_t cdrom::bus_read(int width, uint32_t address) {
|
||||
assert(width == BYTE);
|
||||
|
||||
printf("cdrom::bus_read(0x%08x)\n", address);
|
||||
printf("cdrom::bus_read(%d, 0x%08x)\n", width, address);
|
||||
|
||||
switch (address - 0x1f801800) {
|
||||
case 0: { // status register
|
||||
|
@ -66,10 +66,10 @@ uint32_t cdrom::mmio_read(int size, uint32_t address) {
|
|||
return 0;
|
||||
}
|
||||
|
||||
void cdrom::mmio_write(int size, uint32_t address, uint32_t data) {
|
||||
assert(size == BYTE);
|
||||
void cdrom::bus_write(int width, uint32_t address, uint32_t data) {
|
||||
assert(width == BYTE);
|
||||
|
||||
printf("cdrom::bus_write(0x%08x, 0x%02x)\n", address, data);
|
||||
printf("cdrom::bus_write(%d, 0x%08x, 0x%08x)\n", width, address, data);
|
||||
|
||||
switch (address - 0x1f801800) {
|
||||
case 0:
|
||||
|
@ -83,14 +83,9 @@ void cdrom::mmio_write(int size, uint32_t address, uint32_t data) {
|
|||
state.has_command = true;
|
||||
break;
|
||||
|
||||
case 1: // sound map data out
|
||||
break;
|
||||
|
||||
case 2: // sound map coding info
|
||||
break;
|
||||
|
||||
case 3: // audio volume for cd-right to spu-right
|
||||
break;
|
||||
case 1: break; // sound map data out
|
||||
case 2: break; // sound map coding info
|
||||
case 3: break; // audio volume for cd-right to spu-right
|
||||
}
|
||||
break;
|
||||
|
||||
|
@ -104,28 +99,21 @@ void cdrom::mmio_write(int size, uint32_t address, uint32_t data) {
|
|||
state.interrupt_enable = data;
|
||||
break;
|
||||
|
||||
case 2: // audio volume for cd-left to spu-left
|
||||
break;
|
||||
|
||||
case 3: // audio volume for cd-right to spu-left
|
||||
break;
|
||||
case 2: break; // audio volume for cd-right to spu-left
|
||||
case 3: break; // audio volume for cd-right to spu-left
|
||||
}
|
||||
break;
|
||||
|
||||
case 3:
|
||||
switch (state.index) {
|
||||
case 0: // request register
|
||||
break;
|
||||
case 0: break; // request register
|
||||
|
||||
case 1: // interrupt flag register
|
||||
state.interrupt_request &= ~data;
|
||||
break;
|
||||
|
||||
case 2: // audio volume for cd-left to spu-right
|
||||
break;
|
||||
|
||||
case 3: // apply volume changes
|
||||
break;
|
||||
case 2: break; // audio volume for cd-left to spu-right
|
||||
case 3: break; // apply volume changes
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
|
|
@ -19,9 +19,9 @@ namespace cdrom {
|
|||
|
||||
extern state_t state;
|
||||
|
||||
uint32_t mmio_read(int size, uint32_t address);
|
||||
uint32_t bus_read(int width, uint32_t address);
|
||||
|
||||
void mmio_write(int size, uint32_t address, uint32_t data);
|
||||
void bus_write(int width, uint32_t address, uint32_t data);
|
||||
|
||||
void run();
|
||||
}
|
||||
|
|
|
@ -171,10 +171,10 @@ void cpu::op_cop2() {
|
|||
printf("cop2 $%08x\n", state.code);
|
||||
} else {
|
||||
switch (decoder::rs()) {
|
||||
case 0: printf("mfc2 r%02d, r%02d\n", decoder::rt(), decoder::rd()); break;
|
||||
case 2: printf("cfc2 r%02d, r%02d\n", decoder::rt(), decoder::rd()); break;
|
||||
case 4: printf("mtc2 r%02d, r%02d\n", decoder::rt(), decoder::rd()); break;
|
||||
case 6: printf("ctc2 r%02d, r%02d\n", decoder::rt(), decoder::rd()); break;
|
||||
case 0: /*printf("mfc2 r%02d, r%02d\n", decoder::rt(), decoder::rd());*/ break;
|
||||
case 2: /*printf("cfc2 r%02d, r%02d\n", decoder::rt(), decoder::rd());*/ break;
|
||||
case 4: /*printf("mtc2 r%02d, r%02d\n", decoder::rt(), decoder::rd());*/ break;
|
||||
case 6: /*printf("ctc2 r%02d, r%02d\n", decoder::rt(), decoder::rd());*/ break;
|
||||
|
||||
default:
|
||||
printf("unimplemented cop2\n");
|
||||
|
@ -246,7 +246,7 @@ void cpu::op_jr() {
|
|||
|
||||
void cpu::op_lb() {
|
||||
auto address = rs() + decoder::iconst();
|
||||
auto data = read_data_byte(address);
|
||||
auto data = read_data(BYTE, address);
|
||||
data = utility::sclip<8>(data);
|
||||
|
||||
set_rt<1>(data);
|
||||
|
@ -254,7 +254,7 @@ void cpu::op_lb() {
|
|||
|
||||
void cpu::op_lbu() {
|
||||
auto address = rs() + decoder::iconst();
|
||||
auto data = read_data_byte(address);
|
||||
auto data = read_data(BYTE, address);
|
||||
|
||||
set_rt<1>(data);
|
||||
}
|
||||
|
@ -264,7 +264,7 @@ void cpu::op_lh() {
|
|||
if (address & 1) {
|
||||
enter_exception(0x4);
|
||||
} else {
|
||||
auto data = read_data_half(address);
|
||||
auto data = read_data(HALF, address);
|
||||
data = utility::sclip<16>(data);
|
||||
|
||||
set_rt<1>(data);
|
||||
|
@ -276,7 +276,7 @@ void cpu::op_lhu() {
|
|||
if (address & 1) {
|
||||
enter_exception(0x4);
|
||||
} else {
|
||||
auto data = read_data_half(address);
|
||||
auto data = read_data(HALF, address);
|
||||
|
||||
set_rt<1>(data);
|
||||
}
|
||||
|
@ -291,7 +291,7 @@ void cpu::op_lw() {
|
|||
if (address & 3) {
|
||||
enter_exception(0x4);
|
||||
} else {
|
||||
auto data = read_data_word(address);
|
||||
auto data = read_data(WORD, address);
|
||||
|
||||
set_rt<1>(data);
|
||||
}
|
||||
|
@ -315,7 +315,7 @@ void cpu::op_lwc3() {
|
|||
|
||||
void cpu::op_lwl() {
|
||||
auto address = rs() + decoder::iconst();
|
||||
auto data = read_data_word(address & ~3);
|
||||
auto data = read_data(WORD, address & ~3);
|
||||
|
||||
switch (address & 3) {
|
||||
default: data = (data << 24) | (rt<1>() & 0x00ffffff); break;
|
||||
|
@ -329,7 +329,7 @@ void cpu::op_lwl() {
|
|||
|
||||
void cpu::op_lwr() {
|
||||
auto address = rs() + decoder::iconst();
|
||||
auto data = read_data_word(address & ~3);
|
||||
auto data = read_data(WORD, address & ~3);
|
||||
|
||||
switch (address & 3) {
|
||||
default: data = (data >> 0) | (rt<1>() & 0x00000000); break;
|
||||
|
@ -391,7 +391,7 @@ void cpu::op_sb() {
|
|||
auto address = rs() + decoder::iconst();
|
||||
auto data = rt();
|
||||
|
||||
write_data_byte(address, data);
|
||||
write_data(BYTE, address, data);
|
||||
}
|
||||
|
||||
void cpu::op_sh() {
|
||||
|
@ -401,7 +401,7 @@ void cpu::op_sh() {
|
|||
} else {
|
||||
auto data = rt();
|
||||
|
||||
write_data_half(address, data);
|
||||
write_data(HALF, address, data);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -468,7 +468,7 @@ void cpu::op_sw() {
|
|||
} else {
|
||||
auto data = rt();
|
||||
|
||||
write_data_word(address, data);
|
||||
write_data(WORD, address, data);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -490,7 +490,7 @@ void cpu::op_swc3() {
|
|||
|
||||
void cpu::op_swl() {
|
||||
auto address = rs() + decoder::iconst();
|
||||
auto data = read_data_word(address & ~3);
|
||||
auto data = read_data(WORD, address & ~3);
|
||||
|
||||
switch (address & 3) {
|
||||
default: data = (data & 0xffffff00) | (rt() >> 24); break;
|
||||
|
@ -499,12 +499,12 @@ void cpu::op_swl() {
|
|||
case 3: data = (data & 0x00000000) | (rt() >> 0); break;
|
||||
}
|
||||
|
||||
write_data_word(address & ~3, data);
|
||||
write_data(WORD, address & ~3, data);
|
||||
}
|
||||
|
||||
void cpu::op_swr() {
|
||||
auto address = rs() + decoder::iconst();
|
||||
auto data = read_data_word(address & ~3);
|
||||
auto data = read_data(WORD, address & ~3);
|
||||
|
||||
switch (address & 3) {
|
||||
default: data = (data & 0x00000000) | (rt() << 0); break;
|
||||
|
@ -513,7 +513,7 @@ void cpu::op_swr() {
|
|||
case 3: data = (data & 0x00ffffff) | (rt() << 24); break;
|
||||
}
|
||||
|
||||
write_data_word(address & ~3, data);
|
||||
write_data(WORD, address & ~3, data);
|
||||
}
|
||||
|
||||
void cpu::op_syscall() {
|
||||
|
|
|
@ -33,9 +33,15 @@ void cpu::initialize() {
|
|||
}
|
||||
|
||||
void cpu::run(int count) {
|
||||
bool dis = false;
|
||||
|
||||
for (int i = 0; i < count; i++) {
|
||||
cpu::read_code();
|
||||
|
||||
if (dis) {
|
||||
disassemble();
|
||||
}
|
||||
|
||||
state.is_branch_delay_slot = state.is_branch;
|
||||
state.is_branch = false;
|
||||
|
||||
|
@ -124,70 +130,32 @@ void cpu::read_code() {
|
|||
|
||||
// todo: read i-cache
|
||||
|
||||
state.code = bus::read_word(map_address(state.regs.this_pc));
|
||||
state.code = bus::read(WORD, map_address(state.regs.this_pc));
|
||||
}
|
||||
|
||||
uint32_t cpu::read_data_byte(uint32_t address) {
|
||||
uint32_t cpu::read_data(int width, uint32_t address) {
|
||||
if (state.cop0.regs[12] & (1 << 16)) {
|
||||
return 0; // isc=1
|
||||
}
|
||||
|
||||
// todo: read d-cache?
|
||||
|
||||
return bus::read_byte(map_address(address));
|
||||
return bus::read(width, map_address(address));
|
||||
}
|
||||
|
||||
uint32_t cpu::read_data_half(uint32_t address) {
|
||||
if (state.cop0.regs[12] & (1 << 16)) {
|
||||
return 0; // isc=1
|
||||
}
|
||||
|
||||
// todo: read d-cache?
|
||||
|
||||
return bus::read_half(map_address(address));
|
||||
}
|
||||
|
||||
uint32_t cpu::read_data_word(uint32_t address) {
|
||||
if (state.cop0.regs[12] & (1 << 16)) {
|
||||
return 0; // isc=1
|
||||
}
|
||||
|
||||
// todo: read d-cache?
|
||||
|
||||
return bus::read_word(map_address(address));
|
||||
}
|
||||
|
||||
void cpu::write_data_byte(uint32_t address, uint32_t data) {
|
||||
void cpu::write_data(int width, uint32_t address, uint32_t data) {
|
||||
if (state.cop0.regs[12] & (1 << 16)) {
|
||||
return; // isc=1
|
||||
}
|
||||
|
||||
// todo: write d-cache?
|
||||
|
||||
return bus::write_byte(map_address(address), data);
|
||||
return bus::write(width, map_address(address), data);
|
||||
}
|
||||
|
||||
void cpu::write_data_half(uint32_t address, uint32_t data) {
|
||||
if (state.cop0.regs[12] & (1 << 16)) {
|
||||
return; // isc=1
|
||||
}
|
||||
uint32_t cpu::bus_read(int width, uint32_t address) {
|
||||
printf("cpu::bus_read(%d, 0x%08x)\n", width, address);
|
||||
|
||||
// todo: write d-cache?
|
||||
|
||||
return bus::write_half(map_address(address), data);
|
||||
}
|
||||
|
||||
void cpu::write_data_word(uint32_t address, uint32_t data) {
|
||||
if (state.cop0.regs[12] & (1 << 16)) {
|
||||
return; // isc=1
|
||||
}
|
||||
|
||||
// todo: write d-cache?
|
||||
|
||||
return bus::write_word(map_address(address), data);
|
||||
}
|
||||
|
||||
uint32_t cpu::mmio_read(int, uint32_t address) {
|
||||
switch (address) {
|
||||
case 0x1f801070:
|
||||
return state.i_stat;
|
||||
|
@ -197,7 +165,9 @@ uint32_t cpu::mmio_read(int, uint32_t address) {
|
|||
}
|
||||
}
|
||||
|
||||
void cpu::mmio_write(int, uint32_t address, uint32_t data) {
|
||||
void cpu::bus_write(int width, uint32_t address, uint32_t data) {
|
||||
printf("cpu::bus_write(%d, 0x%08x, 0x%08x)\n", width, address, data);
|
||||
|
||||
switch (address) {
|
||||
case 0x1f801070:
|
||||
state.i_stat = state.i_stat & data;
|
||||
|
|
|
@ -51,21 +51,13 @@ namespace cpu {
|
|||
|
||||
void read_code();
|
||||
|
||||
uint32_t read_data_byte(uint32_t address);
|
||||
uint32_t read_data(int width, uint32_t address);
|
||||
|
||||
uint32_t read_data_half(uint32_t address);
|
||||
void write_data(int width, uint32_t address, uint32_t data);
|
||||
|
||||
uint32_t read_data_word(uint32_t address);
|
||||
uint32_t bus_read(int width, uint32_t address);
|
||||
|
||||
void write_data_byte(uint32_t address, uint32_t data);
|
||||
|
||||
void write_data_half(uint32_t address, uint32_t data);
|
||||
|
||||
void write_data_word(uint32_t address, uint32_t data);
|
||||
|
||||
uint32_t mmio_read(int size, uint32_t address);
|
||||
|
||||
void mmio_write(int size, uint32_t address, uint32_t data);
|
||||
void bus_write(int width, uint32_t address, uint32_t data);
|
||||
|
||||
// --============--
|
||||
// Instructions
|
||||
|
|
|
@ -1,7 +1,7 @@
|
|||
#include <string>
|
||||
#include "cpu_core.hpp"
|
||||
|
||||
void disassemble_special(uint32_t pc) {
|
||||
void disassemble_special() {
|
||||
switch (cpu::state.code & 0x3f) {
|
||||
case 0x00: printf("sll r%02d, r%02d, #%d\n", cpu::decoder::rd(), cpu::decoder::rt(), cpu::decoder::sa()); break;
|
||||
|
||||
|
@ -40,12 +40,14 @@ void disassemble_special(uint32_t pc) {
|
|||
case 0x2b: printf("sltu r%02d, r%02d, r%02d\n", cpu::decoder::rd(), cpu::decoder::rs(), cpu::decoder::rt()); break;
|
||||
|
||||
default:
|
||||
printf("0x%08x | unknown (0x%08x)\n", pc, cpu::state.code);
|
||||
printf("unknown (0x%08x)\n", cpu::state.code);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
void disassemble_reg_imm(uint32_t pc) {
|
||||
void disassemble_reg_imm() {
|
||||
auto pc = cpu::state.regs.this_pc;
|
||||
|
||||
switch (cpu::decoder::rt()) {
|
||||
case 0x00: printf("bltz r%02d, #0x%08x\n", cpu::decoder::rs(), pc + 4 + (cpu::decoder::iconst() << 2)); break;
|
||||
case 0x01: printf("bgez r%02d, #0x%08x\n", cpu::decoder::rs(), pc + 4 + (cpu::decoder::iconst() << 2)); break;
|
||||
|
@ -54,7 +56,7 @@ void disassemble_reg_imm(uint32_t pc) {
|
|||
case 0x11: printf("bgezal r%02d, #0x%08x\n", cpu::decoder::rs(), pc + 4 + (cpu::decoder::iconst() << 2)); break;
|
||||
|
||||
default:
|
||||
printf("0x%08x | unknown (0x%08x)\n", pc, cpu::state.code);
|
||||
printf("unknown (0x%08x)\n", cpu::state.code);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
@ -62,9 +64,11 @@ void disassemble_reg_imm(uint32_t pc) {
|
|||
void cpu::disassemble() {
|
||||
auto pc = state.regs.this_pc;
|
||||
|
||||
printf("0x%08x | ", pc);
|
||||
|
||||
switch ((cpu::state.code >> 26) & 0x3f) {
|
||||
case 0x00: return disassemble_special(pc);
|
||||
case 0x01: return disassemble_reg_imm(pc);
|
||||
case 0x00: return disassemble_special();
|
||||
case 0x01: return disassemble_reg_imm();
|
||||
|
||||
case 0x02: printf("j 0x%08x\n", (pc & ~0x0fffffff) | ((cpu::state.code << 2) & 0x0fffffff)); break;
|
||||
case 0x03: printf("jal 0x%08x\n", (pc & ~0x0fffffff) | ((cpu::state.code << 2) & 0x0fffffff)); break;
|
||||
|
@ -98,13 +102,13 @@ void cpu::disassemble() {
|
|||
case 0x10: printf("rfe\n"); break;
|
||||
|
||||
default:
|
||||
printf("0x%08x | unknown (0x%08x)\n", pc, cpu::state.code);
|
||||
printf("unknown (0x%08x)\n", cpu::state.code);
|
||||
break;
|
||||
}
|
||||
break;
|
||||
|
||||
default:
|
||||
printf("0x%08x | unknown (0x%08x)\n", pc, cpu::state.code);
|
||||
printf("unknown (0x%08x)\n", cpu::state.code);
|
||||
break;
|
||||
}
|
||||
|
||||
|
@ -127,7 +131,7 @@ void cpu::disassemble() {
|
|||
case 0x2e: printf("swr r%02d, #%08x(r%02d)\n", cpu::decoder::rt(), cpu::decoder::iconst(), cpu::decoder::rs()); break;
|
||||
|
||||
default:
|
||||
printf("0x%08x | unknown (0x%08x)\n", pc, cpu::state.code);
|
||||
printf("unknown (0x%08x)\n", cpu::state.code);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -29,7 +29,9 @@ static uint32_t get_register_index(uint32_t address) {
|
|||
return (address >> 2) & 3;
|
||||
}
|
||||
|
||||
uint32_t dma::mmio_read(int size, uint32_t address) {
|
||||
uint32_t dma::bus_read(int width, uint32_t address) {
|
||||
printf("dma::bus_read(%d, 0x%08x)\n", width, address);
|
||||
|
||||
auto channel = get_channel_index(address);
|
||||
if (channel == 7) {
|
||||
switch (get_register_index(address)) {
|
||||
|
@ -50,7 +52,9 @@ uint32_t dma::mmio_read(int size, uint32_t address) {
|
|||
return 0;
|
||||
}
|
||||
|
||||
void dma::mmio_write(int size, uint32_t address, uint32_t data) {
|
||||
void dma::bus_write(int width, uint32_t address, uint32_t data) {
|
||||
printf("dma::bus_write(%d, 0x%08x, 0x%08x)\n", width, address, data);
|
||||
|
||||
auto channel = get_channel_index(address);
|
||||
if (channel == 7) {
|
||||
switch (get_register_index(address)) {
|
||||
|
@ -98,7 +102,7 @@ static void run_channel_2_data_read() {
|
|||
|
||||
for (int a = 0; a < ba; a++) {
|
||||
for (int s = 0; s < bs; s++) {
|
||||
bus::write_word(address, gpu::data());
|
||||
bus::write(WORD, address, gpu::data());
|
||||
address += 4;
|
||||
}
|
||||
}
|
||||
|
@ -118,7 +122,7 @@ static void run_channel_2_data_write() {
|
|||
|
||||
for (int a = 0; a < ba; a++) {
|
||||
for (int s = 0; s < bs; s++) {
|
||||
gpu::gp0(bus::read_word(address));
|
||||
gpu::gp0(bus::read(WORD, address));
|
||||
address += 4;
|
||||
}
|
||||
}
|
||||
|
@ -132,13 +136,13 @@ static void run_channel_2_list() {
|
|||
auto address = state.channels[2].address;
|
||||
|
||||
while (address != 0xffffff) {
|
||||
auto value = bus::read_word(address);
|
||||
auto value = bus::read(WORD, address);
|
||||
address += 4;
|
||||
|
||||
auto count = value >> 24;
|
||||
|
||||
for (auto index = 0; index < count; index++) {
|
||||
gpu::gp0(bus::read_word(address));
|
||||
gpu::gp0(bus::read(WORD, address));
|
||||
address += 4;
|
||||
}
|
||||
|
||||
|
@ -157,11 +161,11 @@ static void run_channel_6() {
|
|||
counter = counter ? counter : 0x10000;
|
||||
|
||||
for (int i = 1; i < counter; i++) {
|
||||
bus::write_word(address, address - 4);
|
||||
bus::write(WORD, address, address - 4);
|
||||
address -= 4;
|
||||
}
|
||||
|
||||
bus::write_word(address, 0x00ffffff);
|
||||
bus::write(WORD, address, 0x00ffffff);
|
||||
|
||||
state.channels[6].control &= ~0x11000000;
|
||||
|
||||
|
|
|
@ -15,9 +15,9 @@ namespace dma {
|
|||
} channels[7];
|
||||
};
|
||||
|
||||
uint32_t mmio_read(int size, uint32_t address);
|
||||
uint32_t bus_read(int width, uint32_t address);
|
||||
|
||||
void mmio_write(int size, uint32_t address, uint32_t data);
|
||||
void bus_write(int width, uint32_t address, uint32_t data);
|
||||
|
||||
void main();
|
||||
|
||||
|
|
|
@ -14,7 +14,7 @@ uint32_t gpu::data() {
|
|||
return (upper << 16) | lower;
|
||||
}
|
||||
|
||||
printf("gpu::read_data()\n");
|
||||
printf("gpu::data()\n");
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
@ -24,11 +24,14 @@ uint32_t gpu::stat() {
|
|||
// 27 Ready to send VRAM to CPU (0=No, 1=Ready) ;GP0(C0h) ;via GPUREAD
|
||||
// 28 Ready to receive DMA Block (0=No, 1=Ready) ;GP0(...) ;via GP0
|
||||
|
||||
printf("gpu::stat()\n");
|
||||
return (gpu::state.status & ~0x00080000) | 0x1c002000;
|
||||
}
|
||||
|
||||
uint32_t gpu::mmio_read(int size, uint32_t address) {
|
||||
assert(size == WORD);
|
||||
uint32_t gpu::bus_read(int width, uint32_t address) {
|
||||
assert(width == WORD);
|
||||
|
||||
printf("gpu::bus_read(%d, 0x%08x)\n", width, address);
|
||||
|
||||
switch (address) {
|
||||
case 0x1f801810: return data();
|
||||
|
@ -36,8 +39,10 @@ uint32_t gpu::mmio_read(int size, uint32_t address) {
|
|||
}
|
||||
}
|
||||
|
||||
void gpu::mmio_write(int size, uint32_t address, uint32_t data) {
|
||||
assert(size == WORD);
|
||||
void gpu::bus_write(int width, uint32_t address, uint32_t data) {
|
||||
assert(width == WORD);
|
||||
|
||||
printf("gpu::bus_write(%d, 0x%08x, 0x%08x)\n", width, address, data);
|
||||
|
||||
switch (address) {
|
||||
case 0x1f801810: return gp0(data);
|
||||
|
|
|
@ -66,9 +66,9 @@ namespace gpu {
|
|||
|
||||
extern state_t state;
|
||||
|
||||
uint32_t mmio_read(int size, uint32_t address);
|
||||
uint32_t bus_read(int width, uint32_t address);
|
||||
|
||||
void mmio_write(int size, uint32_t address, uint32_t data);
|
||||
void bus_write(int width, uint32_t address, uint32_t data);
|
||||
|
||||
uint32_t data();
|
||||
|
||||
|
|
17
src/input/input.cpp
Normal file
17
src/input/input.cpp
Normal file
|
@ -0,0 +1,17 @@
|
|||
#include <cstdio>
|
||||
#include "input.hpp"
|
||||
|
||||
uint32_t input::bus_read(int width, uint32_t address) {
|
||||
printf("input::bus_read(%d, 0x%08x)\n", width, address);
|
||||
|
||||
switch (address) {
|
||||
case 0x1f801044:
|
||||
return (1 << 0) | (1 << 2);
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
void input::bus_write(int width, uint32_t address, uint32_t data) {
|
||||
printf("input::bus_write(%d, 0x%08x, 0x%08x)\n", width, address, data);
|
||||
}
|
12
src/input/input.hpp
Normal file
12
src/input/input.hpp
Normal file
|
@ -0,0 +1,12 @@
|
|||
#ifndef PSXACT_INPUT_HPP
|
||||
#define PSXACT_INPUT_HPP
|
||||
|
||||
#include <cstdint>
|
||||
|
||||
namespace input {
|
||||
uint32_t bus_read(int width, uint32_t address);
|
||||
|
||||
void bus_write(int width, uint32_t address, uint32_t data);
|
||||
}
|
||||
|
||||
#endif //PSXACT_INPUT_HPP
|
|
@ -1,8 +1,11 @@
|
|||
#include <cstdio>
|
||||
#include "spu_core.hpp"
|
||||
|
||||
uint32_t spu::mmio_read(int size, uint32_t address) {
|
||||
uint32_t spu::bus_read(int width, uint32_t address) {
|
||||
printf("spu::bus_read(%d, 0x%08x)\n", width, address);
|
||||
return 0;
|
||||
}
|
||||
|
||||
void spu::mmio_write(int size, uint32_t address, uint32_t) {
|
||||
void spu::bus_write(int width, uint32_t address, uint32_t data) {
|
||||
printf("spu::bus_write(%d, 0x%08x, 0x%08x)\n", width, address, data);
|
||||
}
|
||||
|
|
|
@ -4,9 +4,9 @@
|
|||
#include <stdint.h>
|
||||
|
||||
namespace spu {
|
||||
uint32_t mmio_read(int size, uint32_t address);
|
||||
uint32_t bus_read(int width, uint32_t address);
|
||||
|
||||
void mmio_write(int size, uint32_t address, uint32_t data);
|
||||
void bus_write(int width, uint32_t address, uint32_t data);
|
||||
}
|
||||
|
||||
#endif
|
||||
|
|
|
@ -1,11 +1,11 @@
|
|||
#include <cstdio>
|
||||
#include "timer_core.hpp"
|
||||
|
||||
uint32_t timer::bus_read(int size, uint32_t address) {
|
||||
printf("timer::bus_read(%d, 0x%08x)\n", size, address);
|
||||
uint32_t timer::bus_read(int width, uint32_t address) {
|
||||
printf("timer::bus_read(%d, 0x%08x)\n", width, address);
|
||||
return 0;
|
||||
}
|
||||
|
||||
void timer::bus_write(int size, uint32_t address, uint32_t data) {
|
||||
printf("timer::bus_write(%d, 0x%08x, 0x%08x)\n", size, address, data);
|
||||
void timer::bus_write(int width, uint32_t address, uint32_t data) {
|
||||
printf("timer::bus_write(%d, 0x%08x, 0x%08x)\n", width, address, data);
|
||||
}
|
||||
|
|
|
@ -4,9 +4,9 @@
|
|||
#include <cstdint>
|
||||
|
||||
namespace timer {
|
||||
uint32_t bus_read(int size, uint32_t address);
|
||||
uint32_t bus_read(int width, uint32_t address);
|
||||
|
||||
void bus_write(int size, uint32_t address, uint32_t data);
|
||||
void bus_write(int width, uint32_t address, uint32_t data);
|
||||
}
|
||||
|
||||
#endif //PSXACT_TIMER_CORE_HPP
|
||||
|
|
Loading…
Reference in a new issue