#ifndef __RSP_H__ #define __RSP_H__ #include "rsp_vu.h" #include "recomp.h" #include enum class RspExitReason { Invalid, Broke, ImemOverrun, UnhandledJumpTarget, Unsupported }; extern uint8_t dmem[]; extern uint16_t rspReciprocals[512]; extern uint16_t rspInverseSquareRoots[512]; #define RSP_MEM_B(offset, addr) \ (*reinterpret_cast(dmem + (0xFFF & (((offset) + (addr)) ^ 3)))) #define RSP_MEM_BU(offset, addr) \ (*reinterpret_cast(dmem + (0xFFF & (((offset) + (addr)) ^ 3)))) 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(&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(&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(&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(&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(&val)[(i + 2) ^ 3]; } } #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