It is currently Fri Oct 20, 2017 11:09 am

All times are UTC - 7 hours





Post new topic Reply to topic  [ 8 posts ] 
Author Message
PostPosted: Sun Sep 15, 2013 7:12 pm 
Offline
User avatar

Joined: Sun Jul 29, 2012 10:13 am
Posts: 38
Location: Chicago, IL
So I got MMC5 wrapped up enough to run Castlevania 3 with the exception of the vertical scrolling that crops up right in the beginning. I've seen this posted several times before and ran through all suggested fixes with no luck, so I'm wondering if my issue is different/deeper. Here's what I'm seeing:

Image

And here's the relevant code:

MMC5
Code:
...
   case 0x5203:
      // IRQ Counter
      m.IrqLatch = int(v)
      m.IrqCounter = 0
   case 0x5204:
      if !m.IrqEnabled {
         m.IrqEnabled = (v&0x80 == 0x80)
      }
...

func (m *Mmc5) ReadIrqStatus() Word {
   m.IrqStatus &= 0x7F
   return m.IrqStatus
}

func (m *Mmc5) AcknowledgeIrq() {
   m.IrqStatus &= 0x7F
}

func (m *Mmc5) NotifyScanline() {
   if ppu.inScanline() {
      if ppu.renderingEnabled() {
         if m.IrqStatus&0x40 == 0x0 {
            m.IrqStatus = 0x40
            m.IrqCounter = 0
         } else {
            m.IrqCounter++
            if m.IrqCounter == m.IrqLatch {
               cpu.RequestInterrupt(InterruptIrq)
               m.IrqStatus |= 0x80
            }
         }
      } else {
            m.IrqStatus &= 0xBF
        }
   }
}


PPU
Code:
...
   // Last tick of a scanline
   if p.Cycle == 341 {
        if m, ok := rom.(*Mmc5); ok {
            m.NotifyScanline()
        }
      p.Cycle = 0
      p.Scanline++
   }

...


CPU
Code:
   case InterruptIrq:
      if !c.getIrqDisable() {
         c.PerformIrq()
            c.InterruptRequested = InterruptNone
      }


I note the CPU code up above because it was mentioned before in a similar post that the author wasn't handling maskable interrupts correctly.

Edit: Also worth noting, the screenshot is immediately when the screen loads up, so it looks like the proper background gets rendered insanely late.


Top
 Profile  
 
PostPosted: Sun Sep 15, 2013 10:37 pm 
Offline
User avatar

Joined: Wed Dec 06, 2006 8:18 pm
Posts: 2801
It might not be IRQ related. Maybe it's related to how you handle mid-frame scroll updates. Another thing to check is IRQ acknowledgements.


Top
 Profile  
 
PostPosted: Mon Sep 16, 2013 6:48 am 
Offline
User avatar

Joined: Sun Jul 29, 2012 10:13 am
Posts: 38
Location: Chicago, IL
What in particular about acknowledgements? I think the bulk of my IRQ code is what I posted.

Any other games that do mid-frame scrolling that I can test against? Seems like a possibility.


Top
 Profile  
 
PostPosted: Mon Sep 16, 2013 8:33 am 
Offline
Formerly Fx3
User avatar

Joined: Fri Nov 12, 2004 4:59 pm
Posts: 3064
Location: Brazil
Here my IRQ code for MMC5.

Code:
static unsigned int mmc5_last_line = 261;
static void irq_mmc5_clock(const unsigned int PPU_line, const unsigned int PPU_addr)
{
   if(PPU_line == mmc5_last_line)
      return;
   mmc5_last_line = PPU_line;

//At any time when the MMC5 detects that the PPU is inactive,
//the In Frame signal is automatically cleared.
   if( !ppu_is_rendering() )
   {
      map005.reads &= 0x80;
      return;
   }

/* - If In Frame Signal is clear...
    a) Set In Frame signal
    b) Reset IRQ counter to 0
    c) Clear IRQ pending flag (automatically acknowledging IRQ)
 - otherwise...
    a) Increment IRQ counter
    b) If IRQ counter now equals the trigger value, raise IRQ pending flag   */
   if(map005.reads & 0x40)
   {
      map005.irq_counter++;
      if(map005.irq_counter == map005.irq_latch)
      {
         map005.reads |= 0x80;
         if(map005.irq_flag) {
            cpu_irqtrigger(TIRQ_MPR);
         }
      }
   }
   else
   {
      map005.reads = 0x40;
      map005.irq_counter = 0;
      cpu_irqcancel(TIRQ_MPR);       
   }
}


Top
 Profile  
 
PostPosted: Mon Sep 16, 2013 8:37 am 
Online
User avatar

Joined: Sat Jan 22, 2005 8:51 am
Posts: 427
Location: Chicago, IL
fergus_maximus wrote:
I note the CPU code up above because it was mentioned before in a similar post that the author wasn't handling maskable interrupts correctly.

I think you're referring to my post.

If I remember correctly, it was broken because the IRQ was only being recognized when the IRQ flag was clear at the time that the mapper asserted an IRQ. In the case of Castlevania 3, I think the IRQ flag is cleared after the IRQ is asserted. So, basically, instead of just checking the irq_asserted && !irq_flag condition once, it needs to be checked on every CPU instruction.

_________________
get nemulator
http://nemulator.com


Top
 Profile  
 
PostPosted: Tue Sep 17, 2013 6:22 am 
Offline
User avatar

Joined: Sun Jul 29, 2012 10:13 am
Posts: 38
Location: Chicago, IL
Radically breaking the IRQ doesn't seem to affect the situation at all (except for the status bar getting whacky) so I'm thinking maybe it is the mid-frame scroll updates. My IRQ implementation looks just like what Zepper shared, with the IRQ clocking at the end of every scanline.


Top
 Profile  
 
PostPosted: Tue Sep 17, 2013 11:02 am 
Offline
User avatar

Joined: Wed Dec 06, 2006 8:18 pm
Posts: 2801
The only other thing besides how you handle mid-frame scroll changes I can think of, would be maybe how you handle MMC5 nametable mirroring.


Top
 Profile  
 
PostPosted: Tue Sep 17, 2013 11:03 am 
Offline
User avatar

Joined: Sun Jul 29, 2012 10:13 am
Posts: 38
Location: Chicago, IL
Scratch that, it does seem to be the IRQ. I forced the IRQ latch in the MMC5 mapper to always be 8 (since it appears to be rendering the background way too late, I made it trigger the IRQ way super early) and ended up with this:
Image
Currently I'm only clocking the mapper IRQ at the end of a scanline, and only if it's in scanline 0-239. Is there someplace else it should be getting clocked?

Edit: Also triple verified that (per the Skinny docs) I'm handling mid-frame scroll changes just fine. This problem also happens before anything has scrolled, it's immediately when the screen comes up.


Top
 Profile  
 
Display posts from previous:  Sort by  
Post new topic Reply to topic  [ 8 posts ] 

All times are UTC - 7 hours


Who is online

Users browsing this forum: James and 7 guests


You cannot post new topics in this forum
You cannot reply to topics in this forum
You cannot edit your posts in this forum
You cannot delete your posts in this forum
You cannot post attachments in this forum

Search for:
Jump to:  
Powered by phpBB® Forum Software © phpBB Group