/************************************************************************** * * * Copyright (C) 1994, Silicon Graphics, Inc. * * * * These coded instructions, statements, and computer programs contain * * unpublished proprietary information of Silicon Graphics, Inc., and * * are protected by Federal copyright law. They may not be disclosed * * to third parties or copied or duplicated in any form, in whole or * * in part, without the prior written consent of Silicon Graphics, Inc. * * * *************************************************************************/ #include #include #include #ifndef _FINALROM /* * guParseGbiDL works in conjunction with the dlprint tool. dlprint must be * running on the host Indy. guParseGbiDL, sends a bunch of blocks of data, * with a minimum of one display list, but typically, the principle display * list with a bunch of branched or nested display lists, as well as all the * vertex and matrix data that will be used. After all the blocks of data * are sent, a GU_PARSE_READY command is sent, and dlprint parses out the * data printing it to stdout. * * In order to know what data to send, guParseGbiDL must step through the * display list, find all the gSPDisplayList and gSPBranchList calls, go * to those lists, and also find and send info for all the matrix and vertex * calls. */ void guParseGbiDL(u64 *gbi_dl, u32 nbytes, u8 flags) { guDLPrintCB cntlBlk; Gfx* dlStk[11]; s32 dlcount = 0; Gfx *curGfx,*dlPtr,*vaddr; s8 op; u32 *word0; u32 *word1; u32 segments[16]; u32 param, seg; u32 paddr,len; cntlBlk.dataSize = nbytes; cntlBlk.flags = flags; cntlBlk.dlType = GU_PARSE_GBI_TYPE; cntlBlk.paddr = osVirtualToPhysical(gbi_dl); osWriteHost(&cntlBlk,sizeof(cntlBlk)); osWriteHost(gbi_dl,nbytes); dlStk[0] = (Gfx*)gbi_dl; while((dlcount >= 0) && (dlcount <= 10)) { curGfx = dlStk[dlcount]; /* get the current graphics display list */ op = *((s8*)curGfx); /* get the first byte */ dlStk[dlcount]++; /* increment to next gfx command */ switch(op) { case G_MOVEWORD: word0 = (u32*)curGfx; /* get ptr to first word */ if(((*word0) & 0x000000ff) == G_MW_SEGMENT) { u32 seg; seg = (((*word0) & 0x00ffff00) >> 8) >> 2; word1 = word0 + 1; segments[seg] = *word1; } break; case G_ENDDL: dlcount--; break; case G_DL: word0 = (u32*)curGfx; /* get ptr to first word */ param = ((*word0) & 0x00ff0000) >> 16; /* get param */ word1 = word0 + 1; /* get pointer to second word */ #if BUILD_VERSION >= VERSION_J seg = ((*word1) & 0x0f000000) >> 24; /* get the segment */ #else seg = ((*word1) & 0xff000000) >> 24; /* get the segment */ #endif paddr = segments[seg] + ((*word1) & 0x00ffffff); vaddr = (Gfx*)osPhysicalToVirtual(paddr); len = 1; dlPtr = vaddr; while((*(s8*)dlPtr) != G_ENDDL) { len++; dlPtr++; } len *= sizeof(Gfx); cntlBlk.dataSize = len; cntlBlk.dlType = GU_PARSE_GBI_TYPE; cntlBlk.paddr = paddr; osWriteHost(&cntlBlk,sizeof(cntlBlk)); osWriteHost((u8*)vaddr,len); if(param == G_DL_PUSH) { if(dlcount < 10) dlcount++; else osSyncPrintf("Display lists nested too deep!!!\n"); } dlStk[dlcount] = (Gfx*)vaddr; break; case G_VTX: case G_MOVEMEM: case G_MTX: word0 = (u32*)curGfx; /* get ptr to first word */ word1 = word0 + 1; /* get pointer to second word */ #if BUILD_VERSION >= VERSION_J seg = ((*word1) & 0x0f000000) >> 24; /* get the segment */ #else seg = ((*word1) & 0xff000000) >> 24; /* get the segment */ #endif paddr = segments[seg] + ((*word1) & 0x00ffffff); vaddr = (Gfx*)osPhysicalToVirtual(paddr); len = (*word0) & 0x0000ffff; cntlBlk.dataSize = len; /* always send 32 bytes, the most used */ cntlBlk.dlType = GU_PARSE_MEM_BLOCK; cntlBlk.paddr = paddr; osWriteHost(&cntlBlk,sizeof(cntlBlk)); osWriteHost((u8*)vaddr,len); break; } } cntlBlk.dlType = GU_PARSE_READY; osWriteHost(&cntlBlk,sizeof(cntlBlk)); } #endif