1 /******************************************************************************
2 * Arachnoid Graphics Plugin for Mupen64Plus
3 * http://bitbucket.org/wahrhaft/mupen64plus-video-arachnoid/
5 * Copyright (C) 2007 Kristofer Karlsson, Rickard Niklasson
7 * This program is free software; you can redistribute it and/or
8 * modify it under the terms of the GNU General Public License
9 * as published by the Free Software Foundation; either version 2
10 * of the License, or (at your option) any later version.
12 * This program is distributed in the hope that it will be useful,
13 * but WITHOUT ANY WARRANTY; without even the implied warranty of
14 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15 * GNU General Public License for more details.
17 * You should have received a copy of the GNU General Public License
18 * along with this program; if not, write to the Free Software
19 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
20 *****************************************************************************/
22 #include "DisplayListParser.h"
27 #include "OpenGLRenderer.h"
30 //-----------------------------------------------------------------------------
32 //! Definition of tasks that needs to be performed by the RSP
33 //! Used to process the dlist by the RSP (Reality Signal Processor)
34 //! Placed in DMEM at adress 0x04000fc0
35 //-----------------------------------------------------------------------------
40 unsigned int ucode_boot;
41 unsigned int ucode_boot_size;
43 unsigned int ucode_size;
44 unsigned int ucode_data;
45 unsigned int ucode_data_size;
46 unsigned int dram_stack;
47 unsigned int dram_stack_size;
48 unsigned int output_buff;
49 unsigned int output_buff_size;
50 unsigned int data_ptr;
51 unsigned int data_size;
52 unsigned int yield_data_ptr;
53 unsigned int yield_data_size;
58 unsigned long long force_structure_alignment;
61 //-----------------------------------------------------------------------------
63 //-----------------------------------------------------------------------------
64 DisplayListParser::DisplayListParser()
68 //-----------------------------------------------------------------------------
70 //-----------------------------------------------------------------------------
71 DisplayListParser::~DisplayListParser()
75 //-----------------------------------------------------------------------------
77 //-----------------------------------------------------------------------------
78 bool DisplayListParser::initialize(RSP* rsp, RDP* rdp, GBI* gbi, Memory* memory)
87 m_DListStackPointer = 0;
88 for (int i=0; i<MAX_DL_STACK_SIZE; ++i)
90 m_DlistStack[i].pc = 0;
91 m_DlistStack[i].countdown = MAX_DL_COUNT;
96 //-----------------------------------------------------------------------------
97 //* Process Display List
98 //! Parses the display list
99 //-----------------------------------------------------------------------------
100 void DisplayListParser::processDisplayList()
102 Task* task = (Task*)( m_memory->getDMEM(TASK_ADDRESS_RELATIVE_DMEM));
106 m_gbi->selectUCode(task->t.ucode, task->t.ucode_data, task->t.ucode_size, task->t.ucode_data_size);
109 m_DListStackPointer = 0;
110 m_DlistStack[m_DListStackPointer].pc = (unsigned int)task->t.data_ptr;
111 m_DlistStack[m_DListStackPointer].countdown = MAX_DL_COUNT;
114 while( m_DListStackPointer >= 0 )
116 //Cast memory pointer
117 //uint32* RDRAMu32 = (unsigned int*)graphicsInfo.RDRAM;
118 unsigned int* RDRAMu32 = m_memory->getRDRAMint32();
120 //Get ucode argument from memory (vertices, textures, matrices...)
121 MicrocodeArgument* ucodeArg = (MicrocodeArgument*)&RDRAMu32[(m_DlistStack[m_DListStackPointer].pc>>2)];
123 //Increment program counter
124 m_DlistStack[m_DListStackPointer].pc += 8;
126 //Call function to execute command
127 m_gbi->m_cmds[(ucodeArg->cmd)](ucodeArg);
130 MicrocodeArgument* ucodeNext = (MicrocodeArgument*)&RDRAMu32[(m_DlistStack[m_DListStackPointer].pc>>2)];
132 //If this was a rendering command
133 if ( ucodeArg->cmd == GBI::G_TRI1 ||
134 ucodeArg->cmd == GBI::G_TRI2 ||
135 ucodeArg->cmd == GBI::G_TRI4 ||
136 ucodeArg->cmd == GBI::G_QUAD ||
137 ucodeArg->cmd == GBI::G_DMA_TRI )
139 //If next is not a rendering command
140 if ( ucodeNext->cmd != GBI::G_TRI1 &&
141 ucodeNext->cmd != GBI::G_TRI2 &&
142 ucodeNext->cmd != GBI::G_TRI4 &&
143 ucodeNext->cmd != GBI::G_QUAD &&
144 ucodeNext->cmd != GBI::G_DMA_TRI )
146 OpenGLRenderer::getSingleton().render();
151 if ( m_DListStackPointer >= 0 && --m_DlistStack[m_DListStackPointer].countdown < 0 )
153 m_DListStackPointer--;
158 m_rdp->triggerInterrupt();
159 m_rsp->triggerInterrupt();
162 //-----------------------------------------------------------------------------
164 //-----------------------------------------------------------------------------
165 unsigned int DisplayListParser::getNextWord()
167 unsigned int word = *(unsigned int*)m_memory->getRDRAM( this->getPC() + 4 );
172 //-----------------------------------------------------------------------------
173 //!< @param segmentAddress Used to retrive RDRAM address witch is used to set program counter
174 //-----------------------------------------------------------------------------
175 void DisplayListParser::displayList(unsigned int segmentAddress)
177 unsigned int address = m_memory->getRDRAMAddress(segmentAddress);
179 if ( (address + 8) > m_memory->getRDRAMSize() ) {
183 if ( m_DListStackPointer < (MAX_DL_STACK_SIZE - 1))
185 m_DListStackPointer++;
186 m_DlistStack[m_DListStackPointer].pc = address;
187 m_DlistStack[m_DListStackPointer].countdown = MAX_DL_COUNT;
191 //-----------------------------------------------------------------------------
192 //! Branch Display List
193 //-----------------------------------------------------------------------------
194 void DisplayListParser::branchDisplayList(unsigned int dl)
196 unsigned int address = m_memory->getRDRAMAddress( dl );
198 if ( (address + 8) > m_memory->getRDRAMSize() ) {
202 m_DlistStack[m_DListStackPointer].pc = address;
203 m_DlistStack[m_DListStackPointer].countdown = MAX_DL_COUNT;
206 //-----------------------------------------------------------------------------
208 //-----------------------------------------------------------------------------
209 void DisplayListParser::DMADisplayList( unsigned int w0, unsigned int w1 )
211 //unsigned int dwAddr = (w1);//RSPSegmentAddr((gfx->words.w1));
212 unsigned int dwAddr = m_memory->getRDRAMAddress(w1);//RSPSegmentAddr((gfx->words.w1));
215 m_DListStackPointer++;
216 m_DlistStack[m_DListStackPointer].pc = dwAddr;
217 m_DlistStack[m_DListStackPointer].countdown = (((w0)>>16)&0xFF);