2023-02-20 03:27:35 +00:00
|
|
|
#ifndef __RSP_H__
|
|
|
|
#define __RSP_H__
|
|
|
|
|
|
|
|
#include "rsp_vu.h"
|
|
|
|
#include "recomp.h"
|
2024-05-13 00:35:54 +00:00
|
|
|
#include <cstdio>
|
2023-02-20 03:27:35 +00:00
|
|
|
|
|
|
|
enum class RspExitReason {
|
|
|
|
Invalid,
|
|
|
|
Broke,
|
|
|
|
ImemOverrun,
|
2023-10-23 19:32:30 +00:00
|
|
|
UnhandledJumpTarget,
|
|
|
|
Unsupported
|
2023-02-20 03:27:35 +00:00
|
|
|
};
|
|
|
|
|
|
|
|
extern uint8_t dmem[];
|
|
|
|
extern uint16_t rspReciprocals[512];
|
|
|
|
extern uint16_t rspInverseSquareRoots[512];
|
|
|
|
|
|
|
|
#define RSP_MEM_B(offset, addr) \
|
2023-10-23 19:32:30 +00:00
|
|
|
(*reinterpret_cast<int8_t*>(dmem + (0xFFF & (((offset) + (addr)) ^ 3))))
|
2023-02-20 03:27:35 +00:00
|
|
|
|
|
|
|
#define RSP_MEM_BU(offset, addr) \
|
2023-10-23 19:32:30 +00:00
|
|
|
(*reinterpret_cast<uint8_t*>(dmem + (0xFFF & (((offset) + (addr)) ^ 3))))
|
2024-05-13 00:35:54 +00:00
|
|
|
|
|
|
|
static inline uint32_t RSP_MEM_W_LOAD(uint32_t offset, uint32_t addr) {
|
|
|
|
uint32_t out;
|
|
|
|
for (int i = 0; i < 4; i++) {
|
|
|
|
reinterpret_cast<uint8_t*>(&out)[i ^ 3] = RSP_MEM_BU(offset + i, addr);
|
|
|
|
}
|
|
|
|
return out;
|
|
|
|
}
|
|
|
|
|
|
|
|
static inline void RSP_MEM_W_STORE(uint32_t offset, uint32_t addr, uint32_t val) {
|
|
|
|
for (int i = 0; i < 4; i++) {
|
|
|
|
RSP_MEM_BU(offset + i, addr) = reinterpret_cast<uint8_t*>(&val)[i ^ 3];
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
static inline uint32_t RSP_MEM_HU_LOAD(uint32_t offset, uint32_t addr) {
|
|
|
|
uint16_t out;
|
|
|
|
for (int i = 0; i < 2; i++) {
|
|
|
|
reinterpret_cast<uint8_t*>(&out)[(i + 2) ^ 3] = RSP_MEM_BU(offset + i, addr);
|
|
|
|
}
|
|
|
|
return out;
|
|
|
|
}
|
|
|
|
|
|
|
|
static inline uint32_t RSP_MEM_H_LOAD(uint32_t offset, uint32_t addr) {
|
|
|
|
int16_t out;
|
|
|
|
for (int i = 0; i < 2; i++) {
|
|
|
|
reinterpret_cast<uint8_t*>(&out)[(i + 2) ^ 3] = RSP_MEM_BU(offset + i, addr);
|
|
|
|
}
|
|
|
|
return out;
|
|
|
|
}
|
|
|
|
|
|
|
|
static inline void RSP_MEM_H_STORE(uint32_t offset, uint32_t addr, uint32_t val) {
|
|
|
|
for (int i = 0; i < 2; i++) {
|
|
|
|
RSP_MEM_BU(offset + i, addr) = reinterpret_cast<uint8_t*>(&val)[(i + 2) ^ 3];
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2023-02-20 03:27:35 +00:00
|
|
|
#define RSP_ADD32(a, b) \
|
|
|
|
((int32_t)((a) + (b)))
|
|
|
|
|
|
|
|
#define RSP_SUB32(a, b) \
|
|
|
|
((int32_t)((a) - (b)))
|
|
|
|
|
|
|
|
#define RSP_SIGNED(val) \
|
|
|
|
((int32_t)(val))
|
|
|
|
|
|
|
|
#define SET_DMA_DMEM(dmem_addr) dma_dmem_address = (dmem_addr)
|
|
|
|
#define SET_DMA_DRAM(dram_addr) dma_dram_address = (dram_addr)
|
|
|
|
#define DO_DMA_READ(rd_len) dma_rdram_to_dmem(rdram, dma_dmem_address, dma_dram_address, (rd_len))
|
|
|
|
#define DO_DMA_WRITE(wr_len) dma_dmem_to_rdram(rdram, dma_dmem_address, dma_dram_address, (wr_len))
|
|
|
|
|
|
|
|
static inline void dma_rdram_to_dmem(uint8_t* rdram, uint32_t dmem_addr, uint32_t dram_addr, uint32_t rd_len) {
|
|
|
|
rd_len += 1; // Read length is inclusive
|
|
|
|
dram_addr &= 0xFFFFF8;
|
|
|
|
assert(dmem_addr + rd_len <= 0x1000);
|
|
|
|
for (uint32_t i = 0; i < rd_len; i++) {
|
|
|
|
RSP_MEM_B(i, dmem_addr) = MEM_B(0, (int64_t)(int32_t)(dram_addr + i + 0x80000000));
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
static inline void dma_dmem_to_rdram(uint8_t* rdram, uint32_t dmem_addr, uint32_t dram_addr, uint32_t wr_len) {
|
|
|
|
wr_len += 1; // Write length is inclusive
|
|
|
|
dram_addr &= 0xFFFFF8;
|
|
|
|
assert(dmem_addr + wr_len <= 0x1000);
|
|
|
|
for (uint32_t i = 0; i < wr_len; i++) {
|
|
|
|
MEM_B(0, (int64_t)(int32_t)(dram_addr + i + 0x80000000)) = RSP_MEM_B(i, dmem_addr);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
#endif
|