@@ -348,6 +348,39 @@ void dmac_send_vif1_irq(void* udata, int overshoot) {
348348 dmac_set_irq (dmac , DMAC_VIF1 );
349349}
350350
351+ void mfifo_handle_ref_tag (struct ps2_dmac * dmac ) {
352+ struct dmac_channel * c = dmac -> mfifo_drain ;
353+
354+ while (c -> qwc ) {
355+ uint128_t q = dmac_read_qword (dmac , c -> madr );
356+
357+ if (c == & dmac -> vif1 ) {
358+ // VIF1 FIFO
359+ ee_bus_write128 (dmac -> bus , 0x10005000 , q );
360+ } else {
361+ // GIF FIFO
362+ ee_bus_write128 (dmac -> bus , 0x10006000 , q );
363+ }
364+
365+
366+ c -> madr += 16 ;
367+ c -> qwc -- ;
368+ }
369+
370+ if (channel_is_done (c )) {
371+ // fprintf(stdout, "dmac: mfifo channel done end=%d tte-irq=%d\n", c->tag.end, c->tag.irq && (c->chcr & 0x80));
372+ dmac_set_irq (dmac , c == & dmac -> vif1 ? DMAC_VIF1 : DMAC_GIF );
373+
374+ c -> chcr &= ~0x100 ;
375+
376+ return ;
377+ }
378+
379+ if (c -> tag .id == 1 ) {
380+ c -> tadr = dmac -> rbor | (c -> madr & dmac -> rbsr );
381+ }
382+ }
383+
351384void mfifo_write_qword (struct ps2_dmac * dmac , uint128_t q ) {
352385 struct dmac_channel * c = dmac -> mfifo_drain ;
353386
@@ -365,11 +398,11 @@ void mfifo_write_qword(struct ps2_dmac* dmac, uint128_t q) {
365398 c -> madr += 16 ;
366399 c -> qwc -- ;
367400
368- // printf( "dmac: mfifo channel qwc=%d\n", c->qwc);
401+ // fprintf(stdout, "dmac: mfifo channel qwc=%d\n", c->qwc);
369402
370403 if (c -> qwc == 0 ) {
371404 if (channel_is_done (c )) {
372- printf ( "dmac: mfifo channel done end=%d tte-irq=%d\n" , c -> tag .end , c -> tag .irq && (c -> chcr & 0x80 ));
405+ // fprintf(stdout, "dmac: mfifo channel done end=%d tte-irq=%d\n", c->tag.end, c->tag.irq && (c->chcr & 0x80));
373406 dmac_set_irq (dmac , c == & dmac -> vif1 ? DMAC_VIF1 : DMAC_GIF );
374407
375408 c -> chcr &= ~0x100 ;
@@ -396,6 +429,8 @@ void mfifo_write_qword(struct ps2_dmac* dmac, uint128_t q) {
396429
397430 c -> tadr = dmac -> rbor | (c -> tadr & dmac -> rbsr );
398431
432+ // fprintf(stdout, "dmac: tadr=%08x madr=%08x qwc=%d tagid=%d end=%d\n", c->tadr, c->madr, c->qwc, c->tag.id, c->tag.end);
433+
399434 switch (c -> tag .id ) {
400435 case 1 :
401436 case 2 :
@@ -404,13 +439,21 @@ void mfifo_write_qword(struct ps2_dmac* dmac, uint128_t q) {
404439 case 7 : {
405440 c -> madr = dmac -> rbor | (c -> madr & dmac -> rbsr );
406441 } break ;
407- }
408442
409- printf ("dmac: tadr=%08x madr=%08x qwc=%d tagid=%d end=%d\n" , c -> tadr , c -> madr , c -> qwc , c -> tag .id , c -> tag .end );
443+ default : {
444+ mfifo_handle_ref_tag (dmac );
445+
446+ if (c -> tadr == dmac -> spr_from .madr ) {
447+ // fprintf(stdout, "dmac: MFIFO empty\n");
448+
449+ dmac_set_irq (dmac , DMAC_MEIS );
450+ }
451+ } return ;
452+ }
410453
411454 if (c -> qwc == 0 ) {
412455 if (channel_is_done (c )) {
413- printf ( "dmac: mfifo channel done end=%d tte-irq=%d\n" , c -> tag .end , c -> tag .irq && (c -> chcr & 0x80 ));
456+ // fprintf(stdout, "dmac: mfifo channel done end=%d tte-irq=%d\n", c->tag.end, c->tag.irq && (c->chcr & 0x80));
414457 dmac_set_irq (dmac , c == & dmac -> vif1 ? DMAC_VIF1 : DMAC_GIF );
415458
416459 c -> chcr &= ~0x100 ;
@@ -420,7 +463,7 @@ void mfifo_write_qword(struct ps2_dmac* dmac, uint128_t q) {
420463 }
421464
422465 if (c -> tadr == dmac -> spr_from .madr ) {
423- fprintf (stdout , "dmac: MFIFO empty\n" );
466+ // fprintf(stdout, "dmac: MFIFO empty\n");
424467
425468 dmac_set_irq (dmac , DMAC_MEIS );
426469 }
@@ -440,8 +483,9 @@ void dmac_handle_vif1_transfer(struct ps2_dmac* dmac) {
440483
441484 int mfifo_drain = (dmac -> ctrl >> 2 ) & 3 ;
442485
443- if (mfifo_drain == 2 )
486+ if (mfifo_drain == 2 ) {
444487 return ;
488+ }
445489
446490 int tte = (dmac -> vif1 .chcr >> 6 ) & 1 ;
447491 int mode = (dmac -> vif1 .chcr >> 2 ) & 3 ;
@@ -454,13 +498,13 @@ void dmac_handle_vif1_transfer(struct ps2_dmac* dmac) {
454498 event .name = "VIF1 DMA IRQ" ;
455499 event .udata = dmac ;
456500 event .callback = dmac_send_vif1_irq ;
457- event .cycles = 1000 ;
501+ event .cycles = 4000 ;
458502
459503 // We don't handle VIF1 reads
460504 if ((dmac -> vif1 .chcr & 1 ) == 0 ) {
461505 // Gran Turismo 3 sends a VIF1 read with QWC=0, presumably to
462506 // wait until the GIF FIFO is actually full, so we shouldn't send
463- // and interrupt there.
507+ // an interrupt there.
464508 if (dmac -> vif1 .qwc == 0 )
465509 return ;
466510
@@ -1241,15 +1285,15 @@ void ps2_dmac_write32(struct ps2_dmac* dmac, uint32_t addr, uint64_t data) {
12411285 int stall_drain = (dmac -> ctrl >> 6 ) & 3 ;
12421286
12431287 if (mfifo_drain || stall_ctrl || stall_drain ) {
1244- printf ( "dmac: mfifo_drain=%d stall_ctrl=%d stall_drain=%d\n" ,
1245- mfifo_drain , stall_ctrl , stall_drain
1246- );
1288+ // fprintf(stdout, "dmac: 32-bit mfifo_drain=%d stall_ctrl=%d stall_drain=%d\n",
1289+ // mfifo_drain, stall_ctrl, stall_drain
1290+ // );
12471291
12481292 switch (mfifo_drain ) {
12491293 case 0 : dmac -> mfifo_drain = NULL ; break ;
12501294 case 2 : dmac -> mfifo_drain = & dmac -> vif1 ; break ;
12511295 case 3 : dmac -> mfifo_drain = & dmac -> gif ; break ;
1252- default : printf ( "dmac: Invalid MFIFO drain channel %d\n" , mfifo_drain ); exit (1 );
1296+ default : fprintf ( stdout , "dmac: Invalid MFIFO drain channel %d\n" , mfifo_drain ); exit (1 );
12531297 }
12541298 }
12551299 } return ;
@@ -1262,46 +1306,41 @@ void ps2_dmac_write32(struct ps2_dmac* dmac, uint32_t addr, uint64_t data) {
12621306 case 0x1000F590 : dmac -> enable = data ; return ;
12631307 }
12641308
1265- if (c ) {
1266- switch (addr & 0xff ) {
1267- case 0x00 : {
1268- // c->chcr = data;
1269-
1270- // if (data & 0x100) {
1271- // dmac_handle_channel_start(dmac, addr);
1272- // }
1273-
1274- // Behavior required for IPU FMVs to work
1275- if ((c -> chcr & 0x100 ) == 0 ) {
1276- c -> chcr = data ;
1277-
1278- if (data & 0x100 ) {
1279- dmac_handle_channel_start (dmac , addr );
1280- }
1281- } else {
1282- // printf("dmac: channel %s value=%08x chcr=%08x\n", dmac_get_channel_name(dmac, addr), data, c->chcr);
1283- c -> chcr &= (data & 0x100 ) | 0xfffffeff ;
1284- }
1285- } return ;
1286- case 0x10 : {
1287- c -> madr = data ;
1309+ if (!c )
1310+ return ;
12881311
1289- // Clear MADR's MSB on SPR channels
1290- if (c == & dmac -> spr_to || c == & dmac -> spr_from ) {
1291- c -> madr &= 0x7fffffff ;
1292- }
1293- } return ;
1294- case 0x20 : c -> qwc = data & 0xffff ; return ;
1295- case 0x30 : c -> tadr = data ; return ;
1296- case 0x40 : c -> asr0 = data ; return ;
1297- case 0x50 : c -> asr1 = data ; return ;
1298- case 0x80 : c -> sadr = data & 0x3ff0 ; return ;
1299- }
1312+ switch (addr & 0xff ) {
1313+ case 0x00 : {
1314+ // Behavior required for IPU FMVs to work
1315+ if ((c -> chcr & 0x100 ) == 0 ) {
1316+ c -> chcr = data ;
13001317
1301- // printf("dmac: Unknown channel register %02x\n", addr & 0xff);
1318+ if (data & 0x100 ) {
1319+ dmac_handle_channel_start (dmac , addr );
1320+ }
1321+ } else {
1322+ // printf("dmac: channel %s value=%08x chcr=%08x\n", dmac_get_channel_name(dmac, addr), data, c->chcr);
1323+ c -> chcr &= (data & 0x100 ) | 0xfffffeff ;
1324+ }
1325+ } return ;
1326+ case 0x10 : {
1327+ c -> madr = data ;
13021328
1303- return ;
1329+ // Clear MADR's MSB on SPR channels
1330+ if (c == & dmac -> spr_to || c == & dmac -> spr_from ) {
1331+ c -> madr &= 0x7fffffff ;
1332+ }
1333+ } return ;
1334+ case 0x20 : c -> qwc = data & 0xffff ; return ;
1335+ case 0x30 : c -> tadr = data ; return ;
1336+ case 0x40 : c -> asr0 = data ; return ;
1337+ case 0x50 : c -> asr1 = data ; return ;
1338+ case 0x80 : c -> sadr = data & 0x3ff0 ; return ;
13041339 }
1340+
1341+ // printf("dmac: Unknown channel register %02x\n", addr & 0xff);
1342+
1343+ return ;
13051344}
13061345
13071346uint64_t ps2_dmac_read8 (struct ps2_dmac * dmac , uint32_t addr ) {
@@ -1388,15 +1427,15 @@ void ps2_dmac_write8(struct ps2_dmac* dmac, uint32_t addr, uint64_t data) {
13881427 int stall_drain = (dmac -> ctrl >> 6 ) & 3 ;
13891428
13901429 if (mfifo_drain || stall_ctrl || stall_drain ) {
1391- printf ( "dmac: mfifo_drain=%d stall_ctrl=%d stall_drain=%d\n" ,
1392- mfifo_drain , stall_ctrl , stall_drain
1393- );
1430+ // fprintf(stdout, "dmac: 8-bit mfifo_drain=%d stall_ctrl=%d stall_drain=%d\n",
1431+ // mfifo_drain, stall_ctrl, stall_drain
1432+ // );
13941433
13951434 switch (mfifo_drain ) {
13961435 case 0 : dmac -> mfifo_drain = NULL ; break ;
13971436 case 2 : dmac -> mfifo_drain = & dmac -> vif1 ; break ;
13981437 case 3 : dmac -> mfifo_drain = & dmac -> gif ; break ;
1399- default : printf ( "dmac: Invalid MFIFO drain channel %d\n" , mfifo_drain ); exit (1 );
1438+ default : fprintf ( stdout , "dmac: Invalid MFIFO drain channel %d\n" , mfifo_drain ); exit (1 );
14001439 }
14011440 }
14021441 } return ;
0 commit comments