It is currently Sun Oct 22, 2017 5:04 am

All times are UTC - 7 hours





Post new topic Reply to topic  [ 11 posts ] 
Author Message
PostPosted: Wed Dec 21, 2016 10:11 pm 
Offline
User avatar

Joined: Tue Dec 04, 2012 3:28 pm
Posts: 337
Location: Canada
Working on learning verilog, so I've been using Loopy's mappers as a reference in writing some of my own.

The first thing I noticed is that he always has things running on the posedge of M2. However, when I try doing things that way the mapper doesn't work...I get nothing but a black screen.

Here's an example, an exact copy of his code from the MMC3 mapper. This version does NOT work:

Code:
always @ (posedge m2) begin
        if(nesprg_we & prgain[15] begin
            case({prgain[14:13],prgain[0]})
                0:{chrswap, prgswap, regsel} <= {nesprgdin[7:6],nesprgdin[2:0]};      //8000
                1:bankreg[regsel] <= nesprgdin;                                       //8001
                2:mirror <= nesprgdin[0];// & ~cfg_fourscreen;                        //A000
                3:wramen <= nesprgdin[7:6];                                           //A001
                4:irqlatch <= nesprgdin;                                             //C000
                6:irqen <= 0;
                7:irqen <= 1;
            endcase
        end


Here is an edited version that DOES work:

Code:
always @ (posedge prgain[15]) begin
        if(nesprg_we ==0) begin
            case({prgain[14:13],prgain[0]})
                0:{chrswap, prgswap, regsel} <= {nesprgdin[7:6],nesprgdin[2:0]};      //8000
                1:bankreg[regsel] <= nesprgdin;                                       //8001
                2:mirror <= nesprgdin[0];// & ~cfg_fourscreen;                        //A000
                3:wramen <= nesprgdin[7:6];                                           //A001
                4:irqlatch <= nesprgdin;                                             //C000
                6:irqen <= 0;
                7:irqen <= 1;
            endcase
        end


With those changes made I can boot a basic TLROM game, albeit without any IRQ (I haven't gotten that working yet).

Can anyone give any insight into this? Is using M2 the correct way, or is this something that the Powerpak relies on?


Top
 Profile  
 
PostPosted: Wed Dec 21, 2016 11:00 pm 
Online
User avatar

Joined: Mon Jan 03, 2005 10:36 am
Posts: 2963
Location: Tampere, Finland
The M2 input into PowerPak FPGA is inverted, so if you're trying to use the mapper outside PowerPak, you should reverse the polarity (m2_n or somesuch would be a better name).

_________________
Download STREEMERZ for NES from fauxgame.com! — Some other stuff I've done: kkfos.aspekt.fi


Top
 Profile  
 
PostPosted: Thu Dec 22, 2016 10:57 am 
Offline
User avatar

Joined: Tue Dec 04, 2012 3:28 pm
Posts: 337
Location: Canada
That makes a lot more sense, thanks!

So that being said, does the Powerpak invert most of it's inputs? I see in the powerpak.v file that it says "ALL SIGNALS ACTIVE HIGH", but ROMSEL and IRQ should both be active LOW. What is the benefit of having a bunch of signals inverted?


Top
 Profile  
 
PostPosted: Thu Dec 22, 2016 11:11 am 
Online
User avatar

Joined: Mon Jan 03, 2005 10:36 am
Posts: 2963
Location: Tampere, Finland
Nah, M2 is the odd one out. I think the reasoning was something along the lines of the M2 input being used as a clock for FPGA configuration, and the FPGA wants rising edge for it, so there's an external inverter.

_________________
Download STREEMERZ for NES from fauxgame.com! — Some other stuff I've done: kkfos.aspekt.fi


Top
 Profile  
 
PostPosted: Thu Dec 22, 2016 11:42 am 
Offline
User avatar

Joined: Tue Dec 04, 2012 3:28 pm
Posts: 337
Location: Canada
thefox wrote:
Nah, M2 is the odd one out. I think the reasoning was something along the lines of the M2 input being used as a clock for FPGA configuration, and the FPGA wants rising edge for it, so there's an external inverter.


Odd. Because I still have to invert both prg_rw and romsel to get things working.

Code:
wire m2_n = ~m2;

always @ (posedge m2_n) begin
        if(~nesprg_we & ~prgain[15]) begin           //PRG_RW and PRGAIN 15 (romsel) both inverted
            case({prgain[14:13],prgain[0]})
                0:{chrswap, prgswap, regsel} <= {nesprgdin[7:6],nesprgdin[2:0]};      //8000
                1:bankreg[regsel] <= nesprgdin;                                       //8001
                2:mirror <= nesprgdin[0];// & ~cfg_fourscreen;                        //A000
                3:wramen <= nesprgdin[7:6];                                           //A001
                4:irqlatch <= nesprgdin;                                             //C000
                6:irqen <= 0;
                7:irqen <= 1;
            endcase
        end


If I don't invert both of those, even after inverting M2 into M2_n, things don't work.


Top
 Profile  
 
PostPosted: Thu Dec 22, 2016 1:02 pm 
Offline
User avatar

Joined: Mon Apr 04, 2011 11:49 am
Posts: 1905
Location: WhereverIparkIt, USA
PRG R/W and /ROMSEL are low for writes to $8000-FFFF which is what you're trying to detect. You're not "inverting them to make it work", you're sensing them as low which is what you care about for your condition.

IDK much about the powerpak, but based on what thefox explained with the M2 inverter I would ignore that statement about all signals active high because it's simply not true.

_________________
If you're gonna play the Game Boy, you gotta learn to play it right. -Kenny Rogers


Top
 Profile  
 
PostPosted: Thu Dec 22, 2016 2:04 pm 
Offline
User avatar

Joined: Tue Dec 04, 2012 3:28 pm
Posts: 337
Location: Canada
infiniteneslives wrote:
You're not "inverting them to make it work", you're sensing them as low which is what you care about for your condition.


That's not quite what I meant.

I know that PRG RW and ROMSEL need to be low, but what I'm asking is why is it that they are being used high on this example? How would they work that way? Or is it because of the inverted M2 that this can be done?


Top
 Profile  
 
PostPosted: Thu Dec 22, 2016 4:03 pm 
Offline
User avatar

Joined: Mon Apr 04, 2011 11:49 am
Posts: 1905
Location: WhereverIparkIt, USA
There has to be some foolery going on to make that 'original code' work. Aside from that, syntactically it shouldn't even compile with the lacking close parenth that should be on the second line before the begin.

_________________
If you're gonna play the Game Boy, you gotta learn to play it right. -Kenny Rogers


Top
 Profile  
 
PostPosted: Thu Dec 22, 2016 4:03 pm 
Offline
User avatar

Joined: Sat Jul 12, 2014 3:04 pm
Posts: 936
nesprg_we is inverted from NESPRG_RW to be active-high (in the mapper's code) by powerpak.v, where the mapper gets instantiated and actually connected to the outside. That's why the comment about "all signals active high" is there.
Code:
    IBUF b18(.I(NES_PRG_RW),.O(nesprg_we));

    assign prgain[15]=!nesprg_ce; //(nesprg_ce is aka ROMSEL)

    `MAPxx mapper (     //all signals active high
        m2,                 //in:   6502 M2 clock
        m2_n,               //in:
        clk20,              //in:   20MHz clock from powerpak
        reset,              //in:
        ~nesprg_we,         //in:
        nesprg_oe,          //out:
        ~neschr_rd,         //in:
        ~neschr_wr,         //in:
        prgain,             //in:


Note that this means that powerpak.v's nesprg_we will be inverted compared to the map04.v's nesprg_we.

So, the example is using prgain[15] and nesprg_we high…because that's how it's set up for them to be in that scope.

It's just saying "If (writing to $8000)". $8000 is bit 15, so prga[15] is high, and prg_we [write-enable] is high because writing.


Top
 Profile  
 
PostPosted: Thu Dec 22, 2016 4:12 pm 
Offline
User avatar

Joined: Tue Dec 04, 2012 3:28 pm
Posts: 337
Location: Canada
infiniteneslives wrote:
lacking close parenth that should be on the second line before the begin.


Thats my bad. I must have missed it when I copied it down. It is there in the original.

Myask wrote:
nesprg_we is inverted from NESPRG_RW to be active-high (in the mapper's code) by powerpak.v, where the mapper gets instantiated and actually connected to the outside. That's why the comment about "all signals active high" is there.
Code:
    IBUF b18(.I(NES_PRG_RW),.O(nesprg_we));

    assign prgain[15]=!nesprg_ce; //(nesprg_ce is aka ROMSEL)

    `MAPxx mapper (     //all signals active high
        m2,                 //in:   6502 M2 clock
        m2_n,               //in:
        clk20,              //in:   20MHz clock from powerpak
        reset,              //in:
        ~nesprg_we,         //in:
        nesprg_oe,          //out:
        ~neschr_rd,         //in:
        ~neschr_wr,         //in:
        prgain,             //in:


Note that this means that powerpak.v's nesprg_we will be inverted compared to the map04.v's nesprg_we.

So, the example is using prgain[15] and nesprg_we high…because that's how it's set up for them to be in that scope.

It's just saying "If (writing to $8000)". $8000 is bit 15, so prga[15] is high, and prg_we [write-enable] is high because writing.


And that clears the rest up. That's where I was getting hung up, because looking at the code as it was, it didn't make any sense how it was working. Now that that has been cleared up I've gotten things working ok.

Thanks all for the input!


Top
 Profile  
 
PostPosted: Thu Dec 22, 2016 4:25 pm 
Offline
User avatar

Joined: Sat Jul 12, 2014 3:04 pm
Posts: 936
**$8000+; that is, $8000-FFFF. Dropped the plus.


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

All times are UTC - 7 hours


Who is online

Users browsing this forum: No registered users and 6 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