/* * Xenoborg - Xbox Emulator * Copyright (C) 2006-2010 blueshogun96 * * Name: EmuNV2A.h * Desc: Handles emulation of the GPU. * * Changelog: * 4/26/11 - Framebuffer emulation is working okay. Still need to do a manual bitswap * from RGB to BGR. Sucks because OpenGL doesn't have this problem and D3DFMT_X8B8G8R8 * doesn't appear to be a valid render target format. * * 10/16/2010 - Initial writing. */ #include "XenoKrnl.h" #include "EmuNV2A.h" #include "EmuDirect3D.h" // Globals const DWORD dwFBAddr = 0xF0040000; // This won't be constant for long... const DWORD dwFBSize = 640*480*4; void* pFB = NULL; // Pointer to the actual framebuffer data D3DContext d3dContext; extern HWND g_EmuWnd; // Initializes the NV2A to it's default states BOOL EmuNV2AInit() { // Initialize Direct3D d3dContext.hWnd = g_EmuWnd; if( !EnableDirect3D( &d3dContext ) ) return FALSE; D3DClearRenderTarget( &d3dContext ); // Allocate the Xbox's framebuffer pointer // TODO: Don't just "assume" this size is constant... if( !( pFB = malloc( dwFBSize ) ) ) return EmuError( "Error allocating framebuffer pointer!" ); // TODO: Initialize other registers and render states. return TRUE; } // Uninitializes the NV2A void EmuNV2AUninit() { if( pFB ) { free( pFB ); pFB = NULL; } DisableDirect3D( &d3dContext ); } // Updates framebuffer void EmuNV2AUpdateFB() { extern BOOL bVSync; if( bVSync ) { bVSync = FALSE; D3DSwap( &d3dContext ); } } // NV2A hardware read/write functions BYTE EmuNV2ARead8( DWORD dwAddress ) { // Framebuffer read if( dwAddress >= dwFBAddr && dwAddress < (dwFBAddr+dwFBSize) ) return ((BYTE*)pFB)[dwAddress-dwFBAddr]; DbgPrintf( "NV2A: Unhandled Read8:= [0x%.08X]\n", dwAddress ); return 0; } void EmuNV2AWrite8( DWORD dwAddress, BYTE Value ) { // Framebuffer write if( dwAddress >= dwFBAddr && dwAddress < (dwFBAddr+dwFBSize) ) { // DbgPrintf( "NV2A: Framebuffer Write8:= 0x%.02X -> [0x%.08X]\n", Value, dwAddress ); ((BYTE*)pFB)[dwAddress-dwFBAddr] = Value; D3DFrameBufferWrite8( &d3dContext, dwAddress-dwFBAddr, Value ); // D3DSwap( &d3dContext ); return; } DbgPrintf( "NV2A: Unhandled Write8:= 0x%.02X -> [0x%.08X]\n", Value, dwAddress ); } WORD EmuNV2ARead16( DWORD dwAddress ) { DbgPrintf( "NV2A: Unhandled Read16:= [0x%.08X]\n", dwAddress ); return 0; } void EmuNV2AWrite16( DWORD dwAddress, WORD Value ) { DbgPrintf( "NV2A: Unhandled Write16:= 0x%.04X -> [0x%.08X]\n", Value, dwAddress ); } DWORD EmuNV2ARead32( DWORD dwAddress ) { // Framebuffer read if( dwAddress >= dwFBAddr && dwAddress < (dwFBAddr+dwFBSize) ) return ((DWORD*)pFB)[dwAddress-dwFBAddr]; DbgPrintf( "NV2A: Unhandled Read32:= [0x%.08X]\n", dwAddress ); return 0; } void EmuNV2AWrite32( DWORD dwAddress, DWORD Value ) { // Framebuffer write if( dwAddress >= dwFBAddr && dwAddress < (dwFBAddr+dwFBSize) ) { DbgPrintf( "NV2A: Framebuffer Write32:= 0x%.08X -> [0x%.08X]\n", Value, dwAddress ); ((DWORD*)pFB)[dwAddress-dwFBAddr] = Value; D3DFrameBufferWrite( &d3dContext, dwAddress-dwFBAddr, Value ); D3DSwap( &d3dContext ); return; } DbgPrintf( "NV2A: Unhandled Write32:= 0x%.08X -> [0x%.08X]\n", Value, dwAddress ); }