예제 #1
0
 public VifEmulator()
 {
     memory = new VuVector[1024];
     for (int i = 0; i < memory.Length; ++i)
     {
         memory[i] = new VuVector();
     }
     registers = new VifRegisters();
 }
예제 #2
0
        public static VuVector[] ReadBoundingBox(this BinaryReader br)
        {
            var box = new VuVector[8];

            for (int i = 0; i < box.Length; ++i)
            {
                box[i] = br.ReadV4_32();
            }
            return(box);
        }
예제 #3
0
        void ProcessVifCodeUnpack(BinaryReader br)
        {
            var vifcode = (VifCodeUnpack)registers.Code;

            registers.Num = vifcode.Num;
            //Console.WriteLine($"VIFcode: {VifCodeCmd.Unpack} vn={vifcode.Vn} vl={vifcode.Vl} NUM={vifcode.Num} ADDR={vifcode.Address:x4} FLG={vifcode.Flag} USN={vifcode.Unsigned} m={vifcode.Mask}");
            int  addr   = (int)((vifcode.Flag ? registers.TopS : 0) + vifcode.Address);
            int  cycle  = 0;
            bool isV4_5 = vifcode.Vn == VifUnpackVnType.V4 && vifcode.Vl == VifUnpackVlType.L_5;

            while (registers.Num > 0)
            {
                VuVector result = default;
                bool     doSkip = false;
                bool     doMode;
                bool     doMask;
                if (registers.CycleCl >= registers.CycleWl)
                {
                    doMode = true;
                    doMask = false;
                    // Skipping write
                    if (cycle < registers.CycleWl)
                    {
                        // Write when under write limit
                        result = br.ReadOneVifCodeUnpack(vifcode);
                    }

                    if (cycle == registers.CycleWl - 1)
                    {
                        doSkip = true;
                    }
                }
                else
                {
                    // Filling write
                    throw new NotImplementedException("Filling write not implemented");
                }

                // Write result
                result         = ApplyMaskAndMode(result, doMode && !isV4_5, doMask);
                memory[addr++] = result;
                --registers.Num;

                // TODO: figure out the proper behavior for filling write
                if (doSkip)
                {
                    addr += registers.CycleCl - registers.CycleWl;
                    cycle = 0;
                }
                else
                {
                    ++cycle;
                }
            }
        }
예제 #4
0
        VuVector ApplyMaskAndMode(VuVector vector, bool doMode, bool doMask)
        {
            if (!doMode && !doMask)
            {
                return(vector);
            }

            uint x = vector.X.Packed;
            uint y = vector.Y.Packed;
            uint z = vector.Z.Packed;
            uint w = vector.W.Packed;

            if (doMask)
            {
                throw new NotImplementedException("Masking not implemented");
            }

            if (doMode)
            {
                switch (registers.ModeMod)
                {
                case VifMode.None:
                    break;

                default:
                    throw new NotImplementedException("Addition decompression write not implemented");
                }
            }

            return(new VuVector
            {
                X = new VuFloat {
                    Packed = x
                },
                Y = new VuFloat {
                    Packed = y
                },
                Z = new VuFloat {
                    Packed = z
                },
                W = new VuFloat {
                    Packed = w
                },
            });
        }