bool BuildMachineInst()
{
// check the states to see if a machine instruction can be assembled
// // assume everything will go okay untill proven otherwise
bool passed = true;
// start with machine NOP instuction
// this is used after the switch to see if an instruction was set up
// determine which MachineInstID is required based on the op instruction
opType = MachineInstruction.Nop;
switch ( (Symbol)opInst )
{
// ALU operations
case Symbol.ADD:
case Symbol.SUB:
case Symbol.MUL:
case Symbol.MAD:
case Symbol.LRP:
case Symbol.MOV:
case Symbol.CMP:
case Symbol.CND:
case Symbol.DP2ADD:
case Symbol.DP3:
case Symbol.DP4:
opType = (MachineInstruction)( (int)MachineInstruction.ColorOp1 + argCnt - 1 );
// if context is ps.1.x and Macro not on or a phase marker was found then put all ALU ops in phase 2 ALU container
if ( ( ( ( activeContexts & (uint)ContextKeyPattern.PS_1_1 ) > 0 ) && !macroOn ) || phaseMarkerFound )
{
instructionPhase = PhaseType.PHASE2ALU;
}
else
{
instructionPhase = PhaseType.PHASE1ALU;
}
// check for alpha op in destination register which is OpParrams[0]
// if no Mask for destination then make it .rgba
if ( opParams[ 0 ].MaskRep == 0 )
{
opParams[ 0 ].MaskRep = Gl.GL_RED_BIT_ATI | Gl.GL_GREEN_BIT_ATI | Gl.GL_BLUE_BIT_ATI | ALPHA_BIT;
}
if ( ( opParams[ 0 ].MaskRep & ALPHA_BIT ) > 0 )
{
do_Alpha = true;
opParams[ 0 ].MaskRep -= ALPHA_BIT;
if ( opParams[ 0 ].MaskRep == 0 )
{
opType = MachineInstruction.Nop; // only do alpha op
}
}
break;
case Symbol.TEXCRD:
opType = MachineInstruction.PassTexCoord;
if ( phaseMarkerFound )
{
instructionPhase = PhaseType.PHASE2TEX;
}
else
{
instructionPhase = PhaseType.PHASE1TEX;
}
break;
case Symbol.TEXLD:
opType = MachineInstruction.SampleMap;
if ( phaseMarkerFound )
{
instructionPhase = PhaseType.PHASE2TEX;
}
else
{
instructionPhase = PhaseType.PHASE1TEX;
}
break;
case Symbol.TEX: // PS_1_1 emulation
opType = MachineInstruction.Tex;
instructionPhase = PhaseType.PHASE1TEX;
break;
case Symbol.TEXCOORD: // PS_1_1 emulation
opType = MachineInstruction.TexCoord;
instructionPhase = PhaseType.PHASE1TEX;
break;
case Symbol.TEXREG2AR:
passed = ExpandMacro( texreg2ar_MacroMods );
break;
case Symbol.TEXREG2GB:
passed = ExpandMacro( texreg2gb_MacroMods );
break;
case Symbol.TEXDP3:
passed = ExpandMacro( texdp3_MacroMods );
break;
case Symbol.TEXDP3TEX:
passed = ExpandMacro( texdp3tex_MacroMods );
break;
case Symbol.TEXM3X2PAD:
passed = ExpandMacro( texm3x2pad_MacroMods );
break;
case Symbol.TEXM3X2TEX:
passed = ExpandMacro( texm3x2tex_MacroMods );
break;
case Symbol.TEXM3X3PAD:
// only 2 texm3x3pad instructions allowed
// use count to modify macro to select which mask to use
if ( texm3x3padCount < 2 )
{
texm3x3pad[ 4 ].ID = (Symbol)( (int)Symbol.R + texm3x3padCount );
texm3x3padCount++;
passed = ExpandMacro( texm3x3pad_MacroMods );
}
else
{
passed = false;
}
break;
case Symbol.TEXM3X3TEX:
passed = ExpandMacro( texm3x3tex_MacroMods );
break;
case Symbol.DEF:
opType = MachineInstruction.SetConstants;
instructionPhase = PhaseType.PHASE1TEX;
break;
case Symbol.PHASE: // PS_1_4 only
phaseMarkerFound = true;
break;
} // end of switch
if ( passed )
{
passed = ExpandMachineInstruction();
}
return passed;
}