aboutsummaryrefslogtreecommitdiffhomepage
path: root/src/core/hw
diff options
context:
space:
mode:
authorGravatar Tony Wasserka <NeoBrainX@gmail.com>2014-08-03 01:46:47 +0200
committerGravatar Tony Wasserka <NeoBrainX@gmail.com>2014-08-12 13:32:56 +0200
commit7b6a7d7dfb92d7a6d3537ea8b0339c2170d7eb84 (patch)
tree2b005f3358a228136e7711ddac790ed54bb67b1f /src/core/hw
parentbd798390d5c3d1bf9084abe9839597162608f575 (diff)
Pica/GPU: Change hardware registers to use physical addresses rather than virtual ones.
This cleans up the mess that address reading/writing had become and makes the code a *lot* more sensible. This adds a physical<->virtual address converter to mem_map.h. For further accuracy, we will want to properly extend this to support a wider range of address regions. For now, this makes simply homebrew applications work in a good manner though.
Diffstat (limited to 'src/core/hw')
-rw-r--r--src/core/hw/gpu.cpp102
-rw-r--r--src/core/hw/gpu.h66
2 files changed, 18 insertions, 150 deletions
diff --git a/src/core/hw/gpu.cpp b/src/core/hw/gpu.cpp
index fd40f8ac..591997aa 100644
--- a/src/core/hw/gpu.cpp
+++ b/src/core/hw/gpu.cpp
@@ -24,83 +24,6 @@ Regs g_regs;
u32 g_cur_line = 0; ///< Current vertical screen line
u64 g_last_line_ticks = 0; ///< CPU tick count from last vertical screen line
-/**
- * Sets whether the framebuffers are in the GSP heap (FCRAM) or VRAM
- * @param
- */
-void SetFramebufferLocation(const FramebufferLocation mode) {
- switch (mode) {
- case FRAMEBUFFER_LOCATION_FCRAM:
- {
- auto& framebuffer_top = g_regs.framebuffer_config[0];
- auto& framebuffer_sub = g_regs.framebuffer_config[1];
-
- framebuffer_top.address_left1 = PADDR_TOP_LEFT_FRAME1;
- framebuffer_top.address_left2 = PADDR_TOP_LEFT_FRAME2;
- framebuffer_top.address_right1 = PADDR_TOP_RIGHT_FRAME1;
- framebuffer_top.address_right2 = PADDR_TOP_RIGHT_FRAME2;
- framebuffer_sub.address_left1 = PADDR_SUB_FRAME1;
- //framebuffer_sub.address_left2 = unknown;
- framebuffer_sub.address_right1 = PADDR_SUB_FRAME2;
- //framebuffer_sub.address_right2 = unknown;
- break;
- }
-
- case FRAMEBUFFER_LOCATION_VRAM:
- {
- auto& framebuffer_top = g_regs.framebuffer_config[0];
- auto& framebuffer_sub = g_regs.framebuffer_config[1];
-
- framebuffer_top.address_left1 = PADDR_VRAM_TOP_LEFT_FRAME1;
- framebuffer_top.address_left2 = PADDR_VRAM_TOP_LEFT_FRAME2;
- framebuffer_top.address_right1 = PADDR_VRAM_TOP_RIGHT_FRAME1;
- framebuffer_top.address_right2 = PADDR_VRAM_TOP_RIGHT_FRAME2;
- framebuffer_sub.address_left1 = PADDR_VRAM_SUB_FRAME1;
- //framebuffer_sub.address_left2 = unknown;
- framebuffer_sub.address_right1 = PADDR_VRAM_SUB_FRAME2;
- //framebuffer_sub.address_right2 = unknown;
- break;
- }
- }
-}
-
-/**
- * Gets the location of the framebuffers
- * @return Location of framebuffers as FramebufferLocation enum
- */
-FramebufferLocation GetFramebufferLocation(u32 address) {
- if ((address & ~Memory::VRAM_MASK) == Memory::VRAM_PADDR) {
- return FRAMEBUFFER_LOCATION_VRAM;
- } else if ((address & ~Memory::FCRAM_MASK) == Memory::FCRAM_PADDR) {
- return FRAMEBUFFER_LOCATION_FCRAM;
- } else {
- ERROR_LOG(GPU, "unknown framebuffer location!");
- }
- return FRAMEBUFFER_LOCATION_UNKNOWN;
-}
-
-u32 GetFramebufferAddr(const u32 address) {
- switch (GetFramebufferLocation(address)) {
- case FRAMEBUFFER_LOCATION_FCRAM:
- return Memory::VirtualAddressFromPhysical_FCRAM(address);
- case FRAMEBUFFER_LOCATION_VRAM:
- return Memory::VirtualAddressFromPhysical_VRAM(address);
- default:
- ERROR_LOG(GPU, "unknown framebuffer location");
- }
- return 0;
-}
-
-/**
- * Gets a read-only pointer to a framebuffer in memory
- * @param address Physical address of framebuffer
- * @return Returns const pointer to raw framebuffer
- */
-const u8* GetFramebufferPointer(const u32 address) {
- u32 addr = GetFramebufferAddr(address);
- return (addr != 0) ? Memory::GetPointer(addr) : nullptr;
-}
-
template <typename T>
inline void Read(T &var, const u32 raw_addr) {
u32 addr = raw_addr - 0x1EF00000;
@@ -141,8 +64,8 @@ inline void Write(u32 addr, const T data) {
// TODO: Not sure if this check should be done at GSP level instead
if (config.address_start) {
// TODO: Not sure if this algorithm is correct, particularly because it doesn't use the size member at all
- u32* start = (u32*)Memory::GetPointer(config.GetStartAddress());
- u32* end = (u32*)Memory::GetPointer(config.GetEndAddress());
+ u32* start = (u32*)Memory::GetPointer(Memory::PhysicalToVirtualAddress(config.GetStartAddress()));
+ u32* end = (u32*)Memory::GetPointer(Memory::PhysicalToVirtualAddress(config.GetEndAddress()));
for (u32* ptr = start; ptr < end; ++ptr)
*ptr = bswap32(config.value); // TODO: This is just a workaround to missing framebuffer format emulation
@@ -155,8 +78,8 @@ inline void Write(u32 addr, const T data) {
{
const auto& config = g_regs.display_transfer_config;
if (config.trigger & 1) {
- u8* source_pointer = Memory::GetPointer(config.GetPhysicalInputAddress());
- u8* dest_pointer = Memory::GetPointer(config.GetPhysicalOutputAddress());
+ u8* source_pointer = Memory::GetPointer(Memory::PhysicalToVirtualAddress(config.GetPhysicalInputAddress()));
+ u8* dest_pointer = Memory::GetPointer(Memory::PhysicalToVirtualAddress(config.GetPhysicalOutputAddress()));
for (int y = 0; y < config.output_height; ++y) {
// TODO: Why does the register seem to hold twice the framebuffer width?
@@ -276,11 +199,22 @@ void Init() {
g_cur_line = 0;
g_last_line_ticks = Core::g_app_core->GetTicks();
-// SetFramebufferLocation(FRAMEBUFFER_LOCATION_FCRAM);
- SetFramebufferLocation(FRAMEBUFFER_LOCATION_VRAM);
-
auto& framebuffer_top = g_regs.framebuffer_config[0];
auto& framebuffer_sub = g_regs.framebuffer_config[1];
+
+ // Setup default framebuffer addresses (located in VRAM)
+ // .. or at least these are the ones used by system applets.
+ // There's probably a smarter way to come up with addresses
+ // like this which does not require hardcoding.
+ framebuffer_top.address_left1 = 0x181E6000;
+ framebuffer_top.address_left2 = 0x1822C800;
+ framebuffer_top.address_right1 = 0x18273000;
+ framebuffer_top.address_right2 = 0x182B9800;
+ framebuffer_sub.address_left1 = 0x1848F000;
+ //framebuffer_sub.address_left2 = unknown;
+ framebuffer_sub.address_right1 = 0x184C7800;
+ //framebuffer_sub.address_right2 = unknown;
+
// TODO: Width should be 240 instead?
framebuffer_top.width = 480;
framebuffer_top.height = 400;
diff --git a/src/core/hw/gpu.h b/src/core/hw/gpu.h
index 3065da89..d20311a0 100644
--- a/src/core/hw/gpu.h
+++ b/src/core/hw/gpu.h
@@ -249,72 +249,6 @@ static_assert(sizeof(Regs) == 0x1000 * sizeof(u32), "Invalid total size of regis
extern Regs g_regs;
-enum {
- TOP_ASPECT_X = 0x5,
- TOP_ASPECT_Y = 0x3,
-
- TOP_HEIGHT = 240,
- TOP_WIDTH = 400,
- BOTTOM_WIDTH = 320,
-
- // Physical addresses in FCRAM (chosen arbitrarily)
- PADDR_TOP_LEFT_FRAME1 = 0x201D4C00,
- PADDR_TOP_LEFT_FRAME2 = 0x202D4C00,
- PADDR_TOP_RIGHT_FRAME1 = 0x203D4C00,
- PADDR_TOP_RIGHT_FRAME2 = 0x204D4C00,
- PADDR_SUB_FRAME1 = 0x205D4C00,
- PADDR_SUB_FRAME2 = 0x206D4C00,
- // Physical addresses in FCRAM used by ARM9 applications
-/* PADDR_TOP_LEFT_FRAME1 = 0x20184E60,
- PADDR_TOP_LEFT_FRAME2 = 0x201CB370,
- PADDR_TOP_RIGHT_FRAME1 = 0x20282160,
- PADDR_TOP_RIGHT_FRAME2 = 0x202C8670,
- PADDR_SUB_FRAME1 = 0x202118E0,
- PADDR_SUB_FRAME2 = 0x20249CF0,*/
-
- // Physical addresses in VRAM
- // TODO: These should just be deduced from the ones above
- PADDR_VRAM_TOP_LEFT_FRAME1 = 0x181D4C00,
- PADDR_VRAM_TOP_LEFT_FRAME2 = 0x182D4C00,
- PADDR_VRAM_TOP_RIGHT_FRAME1 = 0x183D4C00,
- PADDR_VRAM_TOP_RIGHT_FRAME2 = 0x184D4C00,
- PADDR_VRAM_SUB_FRAME1 = 0x185D4C00,
- PADDR_VRAM_SUB_FRAME2 = 0x186D4C00,
- // Physical addresses in VRAM used by ARM9 applications
-/* PADDR_VRAM_TOP_LEFT_FRAME2 = 0x181CB370,
- PADDR_VRAM_TOP_RIGHT_FRAME1 = 0x18282160,
- PADDR_VRAM_TOP_RIGHT_FRAME2 = 0x182C8670,
- PADDR_VRAM_SUB_FRAME1 = 0x182118E0,
- PADDR_VRAM_SUB_FRAME2 = 0x18249CF0,*/
-};
-
-/// Framebuffer location
-enum FramebufferLocation {
- FRAMEBUFFER_LOCATION_UNKNOWN, ///< Framebuffer location is unknown
- FRAMEBUFFER_LOCATION_FCRAM, ///< Framebuffer is in the GSP heap
- FRAMEBUFFER_LOCATION_VRAM, ///< Framebuffer is in VRAM
-};
-
-/**
- * Sets whether the framebuffers are in the GSP heap (FCRAM) or VRAM
- * @param
- */
-void SetFramebufferLocation(const FramebufferLocation mode);
-
-/**
- * Gets a read-only pointer to a framebuffer in memory
- * @param address Physical address of framebuffer
- * @return Returns const pointer to raw framebuffer
- */
-const u8* GetFramebufferPointer(const u32 address);
-
-u32 GetFramebufferAddr(const u32 address);
-
-/**
- * Gets the location of the framebuffers
- */
-FramebufferLocation GetFramebufferLocation(u32 address);
-
template <typename T>
void Read(T &var, const u32 addr);