mirror of
				https://github.com/PabloMK7/citra.git
				synced 2025-10-30 21:30:04 +00:00 
			
		
		
		
	added code to LCD modules keep track of framebuffer location in FCRAM or VRAM
This commit is contained in:
		
							parent
							
								
									f78794961e
								
							
						
					
					
						commit
						f0525a1eb4
					
				
					 2 changed files with 153 additions and 15 deletions
				
			
		|  | @ -6,19 +6,107 @@ | |||
| #include "common/log.h" | ||||
| 
 | ||||
| #include "core/core.h" | ||||
| #include "core/mem_map.h" | ||||
| #include "core/hw/lcd.h" | ||||
| 
 | ||||
| #include "video_core/video_core.h" | ||||
| 
 | ||||
| namespace LCD { | ||||
| 
 | ||||
| Registers g_regs; | ||||
| 
 | ||||
| static const u32 kFrameTicks = 268123480 / 60;  ///< 268MHz / 60 frames per second
 | ||||
| 
 | ||||
| u64 g_last_ticks = 0; ///< Last CPU ticks
 | ||||
| 
 | ||||
| /**
 | ||||
|  * Sets whether the framebuffers are in the GSP heap (FCRAM) or VRAM | ||||
|  * @param  | ||||
|  */ | ||||
| void SetFramebufferLocation(const FramebufferLocation mode) { | ||||
|     switch (mode) { | ||||
|     case FRAMEBUFFER_LOCATION_FCRAM: | ||||
|         g_regs.framebuffer_top_left_1   = PADDR_TOP_LEFT_FRAME1; | ||||
|         g_regs.framebuffer_top_left_2   = PADDR_TOP_LEFT_FRAME2; | ||||
|         g_regs.framebuffer_top_right_1  = PADDR_TOP_RIGHT_FRAME1; | ||||
|         g_regs.framebuffer_top_right_2  = PADDR_TOP_RIGHT_FRAME2; | ||||
|         g_regs.framebuffer_sub_left_1   = PADDR_SUB_FRAME1; | ||||
|         //g_regs.framebuffer_sub_left_2  = unknown;
 | ||||
|         g_regs.framebuffer_sub_right_1  = PADDR_SUB_FRAME2; | ||||
|         //g_regs.framebufferr_sub_right_2 = unknown;
 | ||||
|         break; | ||||
| 
 | ||||
|     case FRAMEBUFFER_LOCATION_VRAM: | ||||
|         g_regs.framebuffer_top_left_1   = PADDR_VRAM_TOP_LEFT_FRAME1; | ||||
|         g_regs.framebuffer_top_left_2   = PADDR_VRAM_TOP_LEFT_FRAME2; | ||||
|         g_regs.framebuffer_top_right_1  = PADDR_VRAM_TOP_RIGHT_FRAME1; | ||||
|         g_regs.framebuffer_top_right_2  = PADDR_VRAM_TOP_RIGHT_FRAME2; | ||||
|         g_regs.framebuffer_sub_left_1   = PADDR_VRAM_SUB_FRAME1; | ||||
|         //g_regs.framebuffer_sub_left_2  = unknown;
 | ||||
|         g_regs.framebuffer_sub_right_1  = PADDR_VRAM_SUB_FRAME2; | ||||
|         //g_regs.framebufferr_sub_right_2 = unknown;
 | ||||
|         break; | ||||
|     } | ||||
| } | ||||
| 
 | ||||
| /**
 | ||||
|  * Gets the location of the framebuffers | ||||
|  * @return Location of framebuffers as FramebufferLocation enum | ||||
|  */ | ||||
| const FramebufferLocation GetFramebufferLocation() { | ||||
|     if ((g_regs.framebuffer_top_right_1 & ~Memory::VRAM_MASK) == Memory::VRAM_PADDR) { | ||||
|         return FRAMEBUFFER_LOCATION_VRAM; | ||||
|     } else if ((g_regs.framebuffer_top_right_1 & ~Memory::FCRAM_MASK) == Memory::FCRAM_PADDR) { | ||||
|         return FRAMEBUFFER_LOCATION_FCRAM; | ||||
|     } else { | ||||
|         ERROR_LOG(LCD, "unknown framebuffer location!"); | ||||
|     } | ||||
|     return FRAMEBUFFER_LOCATION_UNKNOWN; | ||||
| } | ||||
| 
 | ||||
| /**
 | ||||
|  * 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) { | ||||
|     switch (GetFramebufferLocation()) { | ||||
|     case FRAMEBUFFER_LOCATION_FCRAM: | ||||
|         return (const u8*)Memory::GetPointer(Memory::VirtualAddressFromPhysical_FCRAM(address)); | ||||
|     case FRAMEBUFFER_LOCATION_VRAM: | ||||
|         return (const u8*)Memory::GetPointer(Memory::VirtualAddressFromPhysical_VRAM(address)); | ||||
|     default: | ||||
|         ERROR_LOG(LCD, "unknown framebuffer location"); | ||||
|     } | ||||
|     return NULL; | ||||
| } | ||||
| 
 | ||||
| template <typename T> | ||||
| inline void Read(T &var, const u32 addr) { | ||||
|     ERROR_LOG(LCD, "unknown Read%d @ 0x%08X", sizeof(var) * 8, addr); | ||||
|     switch (addr) { | ||||
|     case REG_FRAMEBUFFER_TOP_LEFT_1: | ||||
|         var = g_regs.framebuffer_top_left_1; | ||||
|         break; | ||||
|     case REG_FRAMEBUFFER_TOP_LEFT_2: | ||||
|         var = g_regs.framebuffer_top_left_2; | ||||
|         break; | ||||
|     case REG_FRAMEBUFFER_TOP_RIGHT_1: | ||||
|         var = g_regs.framebuffer_top_right_1; | ||||
|         break; | ||||
|     case REG_FRAMEBUFFER_TOP_RIGHT_2: | ||||
|         var = g_regs.framebuffer_top_right_2; | ||||
|         break; | ||||
|     case REG_FRAMEBUFFER_SUB_LEFT_1: | ||||
|         var = g_regs.framebuffer_sub_left_1; | ||||
|         break; | ||||
|     case REG_FRAMEBUFFER_SUB_RIGHT_1: | ||||
|         var = g_regs.framebuffer_sub_right_1; | ||||
|         break; | ||||
|     default: | ||||
|         ERROR_LOG(LCD, "unknown Read%d @ 0x%08X", sizeof(var) * 8, addr); | ||||
|         break; | ||||
|     } | ||||
|      | ||||
| } | ||||
| 
 | ||||
| template <typename T> | ||||
|  | @ -51,6 +139,7 @@ void Update() { | |||
| /// Initialize hardware
 | ||||
| void Init() { | ||||
|     g_last_ticks = Core::g_app_core->GetTicks(); | ||||
|     SetFramebufferLocation(FRAMEBUFFER_LOCATION_FCRAM); | ||||
|     NOTICE_LOG(LCD, "initialized OK"); | ||||
| } | ||||
| 
 | ||||
|  |  | |||
|  | @ -8,6 +8,19 @@ | |||
| 
 | ||||
| namespace LCD { | ||||
| 
 | ||||
| struct Registers { | ||||
|     u32 framebuffer_top_left_1; | ||||
|     u32 framebuffer_top_left_2; | ||||
|     u32 framebuffer_top_right_1; | ||||
|     u32 framebuffer_top_right_2; | ||||
|     u32 framebuffer_sub_left_1; | ||||
|     u32 framebuffer_sub_left_2; | ||||
|     u32 framebuffer_sub_right_1; | ||||
|     u32 framebuffer_sub_right_2; | ||||
| }; | ||||
| 
 | ||||
| extern Registers g_regs; | ||||
| 
 | ||||
| enum { | ||||
|     TOP_ASPECT_X        = 0x5, | ||||
|     TOP_ASPECT_Y        = 0x3, | ||||
|  | @ -17,24 +30,60 @@ enum { | |||
|     BOTTOM_WIDTH        = 320, | ||||
| 
 | ||||
|     // Physical addresses in FCRAM used by ARM9 applications - these are correct for real hardware 
 | ||||
|     FRAMEBUFFER_SEL     = 0x20184E59, | ||||
|     TOP_LEFT_FRAME1     = 0x20184E60, | ||||
|     TOP_LEFT_FRAME2     = 0x201CB370, | ||||
|     TOP_RIGHT_FRAME1    = 0x20282160, | ||||
|     TOP_RIGHT_FRAME2    = 0x202C8670, | ||||
|     SUB_FRAME1          = 0x202118E0, | ||||
|     SUB_FRAME2          = 0x20249CF0, | ||||
|     PADDR_FRAMEBUFFER_SEL       = 0x20184E59, | ||||
|     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 - I'm not sure how these are actually allocated (so not real)
 | ||||
|     VRAM_FRAMEBUFFER_SEL    = 0x18184E59, | ||||
|     VRAM_TOP_LEFT_FRAME1    = 0x18184E60, | ||||
|     VRAM_TOP_LEFT_FRAME2    = 0x181CB370, | ||||
|     VRAM_TOP_RIGHT_FRAME1   = 0x18282160, | ||||
|     VRAM_TOP_RIGHT_FRAME2   = 0x182C8670, | ||||
|     VRAM_SUB_FRAME1         = 0x182118E0, | ||||
|     VRAM_SUB_FRAME2         = 0x18249CF0, | ||||
|     PADDR_VRAM_FRAMEBUFFER_SEL  = 0x18184E59, | ||||
|     PADDR_VRAM_TOP_LEFT_FRAME1  = 0x18184E60, | ||||
|     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, | ||||
| }; | ||||
| 
 | ||||
| enum { | ||||
|     REG_FRAMEBUFFER_TOP_LEFT_1  = 0x1EF00468,   // Main LCD, first framebuffer for 3D left
 | ||||
|     REG_FRAMEBUFFER_TOP_LEFT_2  = 0x1EF0046C,   // Main LCD, second framebuffer for 3D left
 | ||||
|     REG_FRAMEBUFFER_TOP_RIGHT_1 = 0x1EF00494,   // Main LCD, first framebuffer for 3D right
 | ||||
|     REG_FRAMEBUFFER_TOP_RIGHT_2 = 0x1EF00498,   // Main LCD, second framebuffer for 3D right
 | ||||
|     REG_FRAMEBUFFER_SUB_LEFT_1  = 0x1EF00568,   // Sub LCD, first framebuffer
 | ||||
|     REG_FRAMEBUFFER_SUB_LEFT_2  = 0x1EF0056C,   // Sub LCD, second framebuffer
 | ||||
|     REG_FRAMEBUFFER_SUB_RIGHT_1 = 0x1EF00594,   // Sub LCD, unused first framebuffer
 | ||||
|     REG_FRAMEBUFFER_SUB_RIGHT_2 = 0x1EF00598,   // Sub LCD, unused second framebuffer
 | ||||
| }; | ||||
| 
 | ||||
| /// 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); | ||||
| 
 | ||||
| /**
 | ||||
|  * Gets the location of the framebuffers | ||||
|  */ | ||||
| const FramebufferLocation GetFramebufferLocation(); | ||||
| 
 | ||||
| template <typename T> | ||||
| inline void Read(T &var, const u32 addr); | ||||
| 
 | ||||
|  |  | |||
		Loading…
	
	Add table
		Add a link
		
	
		Reference in a new issue