Codebase list mupen64plus-rsp-hle / 428cd2a
Merge tag 'upstream/1.99.5+6+0d5a734e9425' into experimental Upstream version 1.99.5+6+0d5a734e9425 Sven Eckelmann 11 years ago
4 changed file(s) with 229 addition(s) and 123 deletion(s). Raw diff Collapse all Expand all
0 mupen64plus-rsp-hle (1.99.5+6+0d5a734e9425-1) UNRELEASED; urgency=low
1
2 * New Upstream Snapshot from 0d5a734e942501a78d199d53ad0099ce87855d3a
3
4 -- Sven Eckelmann <sven@narfation.org> Sat, 16 Jun 2012 22:07:18 +0200
5
06 mupen64plus-rsp-hle (1.99.5-3) unstable; urgency=low
17
28 * debian/patches:
141141 LDFLAGS += -arch x86_64
142142 else
143143 CFLAGS += -pipe -mmmx -msse -fomit-frame-pointer -arch i686 -mmacosx-version-min=10.5 -isysroot /Developer/SDKs/MacOSX10.5.sdk
144 LDFLAGS += -arch i686
144 LDFLAGS += -arch i686 -read_only_relocs suppress
145145 endif
146146 endif
147147 endif
248248 @echo " DESTDIR=path == path to prepend to all installation paths (only for packagers)"
249249 @echo " Debugging Options:"
250250 @echo " DEBUG=1 == add debugging symbols"
251 @echo " LTO=1 == enable experimental build with link-time optimization"
251252 @echo " V=1 == show verbose compiler output"
252253
253254 all: $(TARGET)
269270 -include $(OBJECTS:.o=.d)
270271
271272 CXXFLAGS += $(CFLAGS)
273 ifeq ($(LTO), 1)
274 CFLAGS += -flto
275 CXXFLAGS += -flto
276 LDFLAGS += -fuse-linker-plugin $(CXXFLAGS)
277 endif
272278
273279 # standard build rules
274280 $(OBJDIR)/%.o: $(SRCDIR)/%.c
363363 }
364364
365365 // Texel Formatting (RGBA16)
366 offset = ps_jpg_data.pMacroBlocks + oMBsize*mb;
366 offset = ps_jpg_data.pMacroBlocks + iMBsize*mb;
367367 y_offset = 0;
368368 u_offset = oMBsize/2;
369369
4141
4242 /* local functions */
4343
44
45 static void dump_binary(char *filename, unsigned char *bytes, unsigned size)
46 {
47 FILE *f;
48
49 // if file already exists, do nothing
50 f = fopen(filename, "r");
51 if (f == NULL)
52 {
53 // else we write bytes to the file
54 f= fopen(filename, "wb");
55 if (f != NULL) {
56 if (fwrite(bytes, 1, size, f) != size)
57 {
58 DebugMessage(M64MSG_ERROR, "Writing error on %s", filename);
59 }
60 fclose(f);
61 }
62 else
63 {
64 DebugMessage(M64MSG_ERROR, "Couldn't open %s for writing !", filename);
65 }
66 }
67 else
68 {
69 fclose(f);
70 }
71 }
72
73
74 /**
75 * Try to figure if the RSP was launched using osSpTask* functions
76 * and not run directly (in which case DMEM[0xfc0-0xfff] is meaningless).
77 *
78 * Previously, the ucode_size field was used to determine this,
79 * but it is not robust enough (hi Pokemon Stadium !) because games could write anything
80 * in this field : most ucode_boot discard the value and just use 0xf7f anyway.
81 *
82 * Using ucode_boot_size should be more robust in this regard.
83 **/
84 static int is_run_through_task(OSTask_t* task)
85 {
86 return (task->ucode_boot_size <= 0x1000
87 && task->ucode_boot_size >= 0);
88 }
89
90
4491 /**
4592 * Simulate the effect of setting the TASKDONE bit (aliased to SIG2)
4693 * and executing a break instruction (setting HALT and BROKE bits).
56103 //
57104 // 0x203 = TASKDONE | BROKE | HALT
58105 *rsp.SP_STATUS_REG |= 0x203;
106
107 // if INTERRUPT_ON_BREAK we generate the interrupt
108 if ((*rsp.SP_STATUS_REG & 0x40) != 0 )
109 {
110 *rsp.MI_INTR_REG |= 0x1;
111 rsp.CheckInterrupts();
112 }
59113 }
60114
61115
108162 }
109163 }
110164
111 // data = (short*)(rsp.RDRAM + task->ucode_data);
112
113165 for (i = 0; i < (task->data_size/4); i += 2)
114166 {
115167 inst1 = p_alist[i];
192244
193245 EXPORT unsigned int CALL DoRspCycles(unsigned int Cycles)
194246 {
195 OSTask_t *task = (OSTask_t*)(rsp.DMEM + 0xFC0);
247 OSTask_t *task = (OSTask_t*)(rsp.DMEM + 0xfc0);
248 int run_through_task = is_run_through_task(task);
249
196250 unsigned int i, sum=0;
197251
198 if( task->type == 1 && task->data_ptr != 0 && GraphicsHle)
199 {
200 if (rsp.ProcessDlistList != NULL)
201 {
202 rsp.ProcessDlistList();
203 }
204 taskdone();
205 if ((*rsp.SP_STATUS_REG & 0x40) != 0 )
206 {
207 *rsp.MI_INTR_REG |= 0x1;
208 rsp.CheckInterrupts();
209 }
210
211 *rsp.DPC_STATUS_REG &= ~0x0002;
212 return Cycles;
213 }
214 else if (task->type == 2 && AudioHle)
215 {
216 if (rsp.ProcessAlistList != NULL)
217 {
218 rsp.ProcessAlistList();
219 }
220 taskdone();
221 if ((*rsp.SP_STATUS_REG & 0x40) != 0 )
222 {
223 *rsp.MI_INTR_REG |= 0x1;
224 rsp.CheckInterrupts();
225 }
226 return Cycles;
227 }
228 else if (task->type == 7)
229 {
230 rsp.ShowCFB();
231 }
232
233 taskdone();
234 if ((*rsp.SP_STATUS_REG & 0x40) != 0 )
235 {
236 *rsp.MI_INTR_REG |= 0x1;
237 rsp.CheckInterrupts();
238 }
239
240 if (task->ucode_size <= 0x1000)
241 for (i=0; i<(task->ucode_size/2); i++)
252 char filename[256];
253
254 if (run_through_task)
255 {
256 // most ucode_boot procedure copy 0xf80 bytes of ucode whatever the ucode_size is.
257 // For practical purpose we use a ucode_size = min(0xf80, task->ucode_size)
258 unsigned int ucode_size = (task->ucode_size > 0xf80) ? 0xf80 : task->ucode_size;
259
260 for (i=0; i<ucode_size/2; i++)
242261 sum += *(rsp.RDRAM + task->ucode + i);
262
263 switch(task->type)
264 {
265 case 1: // GFX
266 {
267 if (GraphicsHle && rsp.ProcessDlistList != NULL)
268 {
269 rsp.ProcessDlistList();
270 taskdone();
271 *rsp.DPC_STATUS_REG &= ~0x0002;
272 return Cycles;
273 }
274 else
275 {
276 DebugMessage(M64MSG_WARNING, "GFX ucode through rsp plugin is not implemented");
277 }
278 break;
279 }
280
281 case 2: // AUDIO
282 {
283 if (AudioHle && rsp.ProcessAlistList != NULL)
284 {
285 rsp.ProcessAlistList();
286 taskdone();
287 return Cycles;
288 }
289 else
290 {
291 if (audio_ucode(task) == 0)
292 {
293 taskdone();
294 return Cycles;
295 }
296 }
297 break;
298 }
299
300 case 4: // JPEG
301 {
302 switch(sum)
303 {
304 case 0x278: // Zelda OOT during boot
305 taskdone();
306 return Cycles;
307 case 0x2caa6: // Zelda OOT, Pokemon Stadium {1,2} jpg decompression
308 ps_jpg_uncompress(task);
309 taskdone();
310 return Cycles;
311 case 0x130de: // Ogre Battle background decompression
312 ob_jpg_uncompress(task);
313 taskdone();
314 return Cycles;
315 }
316 break;
317 }
318
319 case 7: // CFB
320 {
321 rsp.ShowCFB();
322 taskdone();
323 return Cycles;
324 break;
325 }
326 }
327
328 DebugMessage(M64MSG_WARNING, "unknown OSTask: sum %x PC:%x", sum, *rsp.SP_PC_REG);
329
330 sprintf(&filename[0], "task_%x.log", sum);
331
332
333 // dump task
334 FILE *f = fopen(filename, "r");
335 if (f == NULL)
336 {
337 f = fopen(filename, "w");
338 fprintf(f,
339 "type = %d\n"
340 "flags = %d\n"
341 "ucode_boot = %#08x size = %#x\n"
342 "ucode = %#08x size = %#x\n"
343 "ucode_data = %#08x size = %#x\n"
344 "dram_stack = %#08x size = %#x\n"
345 "output_buff = %#08x *size = %#x\n"
346 "data = %#08x size = %#x\n"
347 "yield_data = %#08x size = %#x\n",
348 task->type, task->flags,
349 task->ucode_boot, task->ucode_boot_size,
350 task->ucode, task->ucode_size,
351 task->ucode_data, task->ucode_data_size,
352 task->dram_stack, task->dram_stack_size,
353 task->output_buff, task->output_buff_size,
354 task->data_ptr, task->data_size,
355 task->yield_data_ptr, task->yield_data_size);
356 fclose(f);
357 }
358 else
359 {
360 fclose(f);
361 }
362
363
364 // dump ucode_boot
365 sprintf(&filename[0], "ucode_boot_%x.bin", sum);
366 dump_binary(filename, rsp.RDRAM + (task->ucode_boot & 0x7fffff), task->ucode_boot_size);
367
368 // dump ucode
369 if (task->ucode != 0)
370 {
371 sprintf(&filename[0], "ucode_%x.bin", sum);
372 dump_binary(filename, rsp.RDRAM + (task->ucode & 0x7fffff), ucode_size);
373 }
374
375 // dump ucode_data
376 if (task->ucode_data != 0)
377 {
378 sprintf(&filename[0], "ucode_data_%x.bin", sum);
379 dump_binary(filename, rsp.RDRAM + (task->ucode_data & 0x7fffff), task->ucode_data_size);
380 }
381
382 // dump data
383 if (task->data_ptr != 0)
384 {
385 sprintf(&filename[0], "data_%x.bin", sum);
386 dump_binary(filename, rsp.RDRAM + (task->data_ptr & 0x7fffff), task->data_size);
387 }
388 }
243389 else
390 {
391 // For ucodes that are not run using the osSpTask* functions
392
393 // Try to identify the RSP code we should run
244394 for (i=0; i<(0x1000/2); i++)
245395 sum += *(rsp.IMEM + i);
246396
247
248 if (task->ucode_size > 0x1000)
249 {
250397 switch(sum)
251398 {
252 case 0x9E2: // banjo tooie (U) boot code
399 // CIC 6105 IPL3 run some code on the RSP
400 // We only emulate the part that modify RDRAM
401 //
402 // It is used for instance in Banjo Tooie, Zelda, Perfect Dark...
403 case 0x9E2: // banjo tooie (U)
404 case 0x9F2: // banjo tooie (E)
253405 {
254406 int i,j;
255 memcpy(rsp.IMEM + 0x120, rsp.RDRAM + 0x1e8, 0x1e8);
407 memcpy(rsp.IMEM + 0x120, rsp.RDRAM + 0x1e8, 0x1f0);
256408 for (j=0; j<0xfc; j++)
257409 for (i=0; i<8; i++)
258410 *(rsp.RDRAM+((0x2fb1f0+j*0xff0+i)^S8))=*(rsp.IMEM+((0x120+j*8+i)^S8));
259 }
260411 return Cycles;
261 case 0x9F2: // banjo tooie (E) + zelda oot (E) boot code
262 {
263 int i,j;
264 memcpy(rsp.IMEM + 0x120, rsp.RDRAM + 0x1e8, 0x1e8);
265 for (j=0; j<0xfc; j++)
266 for (i=0; i<8; i++)
267 *(rsp.RDRAM+((0x2fb1f0+j*0xff0+i)^S8))=*(rsp.IMEM+((0x120+j*8+i)^S8));
268 }
269 return Cycles;
270 }
271 }
272 else
273 {
274 switch(task->type)
275 {
276 case 2: // audio
277 if (audio_ucode(task) == 0)
278 return Cycles;
279 break;
280 case 4: // jpeg
281 switch(sum)
282 {
283 case 0x278: // used by zelda during boot
284 taskdone();
285 return Cycles;
286 case 0x2e4fc: // used by pokemon stadium {1,2} for jpg decompression
287 ps_jpg_uncompress(task);
288 taskdone();
289 return Cycles;
290 case 0x130de: // used by ogre battle for background decompression
291 ob_jpg_uncompress(task);
292 taskdone();
293 return Cycles;
294 default:
295 DebugMessage(M64MSG_WARNING, "unknown jpeg task: sum:%x", sum);
296 }
297 break;
298 }
299 }
300
301 {
302 FILE *f;
303 DebugMessage(M64MSG_WARNING, "unknown task: type:%d sum:%x PC:%lx", (int)task->type, sum, (unsigned long) rsp.SP_PC_REG);
304
305 if (task->ucode_size <= 0x1000)
306 {
307 f = fopen("imem.dat", "wb");
308 if (f == NULL || fwrite(rsp.RDRAM + task->ucode, 1, task->ucode_size, f) != task->ucode_size)
309 DebugMessage(M64MSG_WARNING, "couldn't write to RSP debugging file imem.dat");
310 fclose(f);
311
312 f = fopen("dmem.dat", "wb");
313 if (f == NULL || fwrite(rsp.RDRAM + task->ucode_data, 1, task->ucode_data_size, f) != task->ucode_data_size)
314 DebugMessage(M64MSG_WARNING, "couldn't write to RSP debugging file dmem.dat");
315 fclose(f);
316 }
317 else
318 {
319 f = fopen("imem.dat", "wb");
320 if (f == NULL || fwrite(rsp.IMEM, 1, 0x1000, f) != 0x1000)
321 DebugMessage(M64MSG_WARNING, "couldn't write to RSP debugging file imem.dat");
322 fclose(f);
323
324 f = fopen("dmem.dat", "wb");
325 if (f == NULL || fwrite(rsp.DMEM, 1, 0x1000, f) != 0x1000)
326 DebugMessage(M64MSG_WARNING, "couldn't write to RSP debugging file dmem.dat");
327 fclose(f);
328 }
412 }
413 }
414
415 DebugMessage(M64MSG_WARNING, "unknown RSP code: sum: %x PC:%x", sum, *rsp.SP_PC_REG);
416
417 // dump IMEM & DMEM for further analysis
418 sprintf(&filename[0], "imem_%x.bin", sum);
419 dump_binary(filename, rsp.IMEM, 0x1000);
420
421 sprintf(&filename[0], "dmem_%x.bin", sum);
422 dump_binary(filename, rsp.DMEM, 0x1000);
329423 }
330424
331425 return Cycles;