/[pcsx2_0.9.7]/trunk/pcsx2/Vif_Unpack.inl
ViewVC logotype

Contents of /trunk/pcsx2/Vif_Unpack.inl

Parent Directory Parent Directory | Revision Log Revision Log


Revision 62 - (show annotations) (download)
Tue Sep 7 11:08:22 2010 UTC (10 years, 2 months ago) by william
File size: 4909 byte(s)
Auto Commited Import of: pcsx2-0.9.7-r3738-debug in ./trunk
1 /* PCSX2 - PS2 Emulator for PCs
2 * Copyright (C) 2002-2010 PCSX2 Dev Team
3 *
4 * PCSX2 is free software: you can redistribute it and/or modify it under the terms
5 * of the GNU Lesser General Public License as published by the Free Software Found-
6 * ation, either version 3 of the License, or (at your option) any later version.
7 *
8 * PCSX2 is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY;
9 * without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
10 * PURPOSE. See the GNU General Public License for more details.
11 *
12 * You should have received a copy of the GNU General Public License along with PCSX2.
13 * If not, see <http://www.gnu.org/licenses/>.
14 */
15
16 #pragma once
17
18 // Old Vif Unpack Code
19 // Only here for testing/reference
20 template<const u32 VIFdmanum> void VIFunpack(u32 *data, vifCode *v, u32 size) {
21 //if (!VIFdmanum) DevCon.WriteLn("vif#%d, size = %d [%x]", VIFdmanum, size, data);
22 VURegs * VU;
23 u8 *cdata = (u8*)data;
24 u32 tempsize = 0;
25 const u32 memlimit = (VIFdmanum == 0) ? 0x1000 : 0x4000;
26
27 if (VIFdmanum == 0) {
28 VU = &VU0;
29 vifRegs = &vif0Regs;
30 vif = &vif0;
31 }
32 else {
33 VU = &VU1;
34 vifRegs = &vif1Regs;
35 vif = &vif1;
36 }
37
38 u32 *dest = (u32*)(VU->Mem + v->addr);
39
40 const VIFUnpackFuncTable& ft( VIFfuncTable[ v->cmd & 0x1f ] );
41 UNPACKFUNCTYPE func = vif->usn ? ft.funcU : ft.funcS;
42
43 size <<= 2;
44
45 if (vifRegs->cycle.cl >= vifRegs->cycle.wl) { // skipping write
46 if (v->addr >= memlimit) {
47 DevCon.Warning("Overflown at the start");
48 v->addr &= (memlimit - 1);
49 dest = (u32*)(VU->Mem + v->addr);
50 }
51
52 size = std::min<u32>(size, vifRegs->num * ft.gsize); //size will always be the same or smaller
53
54 tempsize = v->addr + ((((vifRegs->num-1) / vifRegs->cycle.wl) *
55 (vifRegs->cycle.cl - vifRegs->cycle.wl)) * 16) + (vifRegs->num * 16);
56
57 //Sanity Check (memory overflow)
58 if (tempsize > memlimit) {
59 if (((vifRegs->cycle.cl != vifRegs->cycle.wl) &&
60 ((memlimit + (vifRegs->cycle.cl - vifRegs->cycle.wl) * 16) == tempsize))) {
61 //It's a red herring, so ignore it! SSE unpacks will be much quicker.
62 DevCon.WriteLn("what!!!!!!!!!");
63 //tempsize = 0;
64 tempsize = size;
65 size = 0;
66 }
67 else {
68 DevCon.Warning("VIF%x Unpack ending %x > %x", VIFdmanum, tempsize, VIFdmanum ? 0x4000 : 0x1000);
69 tempsize = size;
70 size = 0;
71 }
72 }
73 else {
74 tempsize = size;
75 size = 0;
76 }
77 if (tempsize) {
78 int incdest = ((vifRegs->cycle.cl - vifRegs->cycle.wl) << 2) + 4;
79 size = 0;
80 int addrstart = v->addr;
81 //if((tempsize >> 2) != v->size) DevCon.Warning("split when size != tagsize");
82
83 //DbgCon.WriteLn("sorting tempsize :p, size %d, vifnum %d, addr %x", tempsize, vifRegs->num, v->addr);
84
85 while ((tempsize >= ft.gsize) && (vifRegs->num > 0)) {
86 if(v->addr >= memlimit) {
87 DevCon.Warning("Mem limit overflow");
88 v->addr &= (memlimit - 1);
89 dest = (u32*)(VU->Mem + v->addr);
90 }
91
92 func(dest, (u32*)cdata);
93 cdata += ft.gsize;
94 tempsize -= ft.gsize;
95
96 vifRegs->num--;
97 vif->cl++;
98
99 if (vif->cl == vifRegs->cycle.wl) {
100 dest += incdest;
101 v->addr +=(incdest * 4);
102 vif->cl = 0;
103 }
104 else {
105 dest += 4;
106 v->addr += 16;
107 }
108 }
109 if (v->addr >= memlimit) {
110 v->addr &=(memlimit - 1);
111 dest = (u32*)(VU->Mem + v->addr);
112 }
113 v->addr = addrstart;
114 if(tempsize > 0) size = tempsize;
115 }
116
117 if (size >= ft.dsize && vifRegs->num > 0) { //Else write what we do have
118 VIF_LOG("warning, end with size = %d", size);
119 // unpack one qword
120 //v->addr += (size / ft.dsize) * 4;
121 (vif->usn ? ft.oddU : ft.oddS)(dest, (u32*)cdata, size / ft.dsize);
122 size = 0;
123
124 //DbgCon.WriteLn("leftover done, size %d, vifnum %d, addr %x", size, vifRegs->num, v->addr);
125 }
126 }
127 else { // filling write
128 if(vifRegs->cycle.cl > 0) // Quicker and avoids zero division :P
129 if((u32)(((size / ft.gsize) / vifRegs->cycle.cl) * vifRegs->cycle.wl) < vifRegs->num)
130 DevCon.Warning("Filling write warning! %x < %x and CL = %x WL = %x", (size / ft.gsize), vifRegs->num, vifRegs->cycle.cl, vifRegs->cycle.wl);
131
132 DevCon.Warning("filling write %d cl %d, wl %d mask %x mode %x unpacktype %x addr %x", vifRegs->num, vifRegs->cycle.cl, vifRegs->cycle.wl, vifRegs->mask, vifRegs->mode, v->cmd & 0xf, vif->tag.addr);
133 while (vifRegs->num > 0) {
134 if (vif->cl == vifRegs->cycle.wl) {
135 vif->cl = 0;
136 }
137 // unpack one qword
138 if (vif->cl < vifRegs->cycle.cl) {
139 if(size < ft.gsize) { DevCon.WriteLn("Out of Filling write data!"); break; }
140 func(dest, (u32*)cdata);
141 cdata += ft.gsize;
142 size -= ft.gsize;
143 vif->cl++;
144 vifRegs->num--;
145 if (vif->cl == vifRegs->cycle.wl) {
146 vif->cl = 0;
147 }
148 }
149 else {
150 func(dest, (u32*)cdata);
151 v->addr += 16;
152 vifRegs->num--;
153 vif->cl++;
154 }
155 dest += 4;
156 if (vifRegs->num == 0) break;
157 }
158 }
159 }

  ViewVC Help
Powered by ViewVC 1.1.22