NES 如何增加ROM支持种类?

2019-07-20 22:12发布

本帖最后由 zdfwyh 于 2016-5-8 18:37 编辑

移植了综合例程中NES程序到我的407板子上,运行很好,不过发现部分ROM不支持,但在Mapper目录下有源文件,只不过未移植,我想参考已经移植好的Mapper进行移植,比如,移植91号Mapper文件(因为我正好有这么一个ROM游戏不支持),却是没有显示,不知道为什么,谁能帮我看看呀.
主要修改的地方为
nes_mapper.c中添加#include "mapper/091.cpp"
同时代码修改如下
[mw_shl_code=c,true]//支持的Mapper号,自己添加
const int MapTab[] =
{
        0,1,2,3,4,6,7,8,11,13,15,16,17,18,19,21,22,23,24,25,32,33,34,
        64,65,66,67,69,70,71,72,73,75,76,78,79,85,87,88,91,99,113,//增加91
        189,225,227,240,245,
        -1,//最后一个,-1,表示不支持的map号
};[/mw_shl_code]
[mw_shl_code=c,true]void Mapper_Init(void)
{
        uint32 probe;
        NES_Mapper->Reset         = Mapper_Reset;
        NES_Mapper->Write         = Mapper_Write;
        NES_Mapper->Read          = Mapper_Read;
        NES_Mapper->WriteLow      = Mapper_WriteLow;
        NES_Mapper->ReadLow       = Mapper_ReadLow;        
        NES_Mapper->HSync         = Mapper_HSync;
        NES_Mapper->VSync         = Mapper_VSync;
        VROM_mask = 0xFFFF;
        for(probe = 0x8000; probe; probe >>= 1)
        {
                if((VROM_1K_SIZE-1) & probe) break;
                VROM_mask >>= 1;
        }
        
        switch (MapperNo)
        {
                case 0 :MAP0_Init();break;
                case 1 :MAP1_Init();break;
                 case 2 :MAP2_Init();break;
                 case 3 :MAP3_Init();break;
                 case 4 :MAP4_Init();break;
                 case 6 :MAP6_Init();break;
                 case 7 :MAP7_Init();break;
                 case 8 :MAP8_Init();break;
                 case 11:MAP11_Init();break;
                 case 13:MAP13_Init();break;
                 case 15:MAP15_Init();break;
                 case 16:MAP16_Init();break;
                 case 17:MAP17_Init();break;
                 case 18:MAP18_Init();break;
                 case 19:MAP19_Init();break;
                 case 21:MAP21_Init();break;
                 case 22:MAP22_Init();break;
                 case 23:MAP23_Init();break;
                 case 24:MAP24_Init();break;
                 case 25:MAP25_Init();break;
                 case 32:MAP32_Init();break;
                 case 33:MAP33_Init();break;
                 case 34:MAP34_Init();break;
                 case 64:MAP64_Init();break;
                 case 65:MAP65_Init();break;
                 case 66:MAP66_Init();break;
                 case 67:MAP67_Init();break;
                 case 69:MAP69_Init();break;
                 case 70:MAP70_Init();break;
                 case 71:MAP71_Init();break;
                 case 72:MAP72_Init();break;
                 case 73:MAP73_Init();break;
                 case 75:MAP75_Init();break;
                 case 76:MAP76_Init();break;
                 case 78:MAP78_Init();break;
                 case 79:MAP79_Init();break;
                 case 85:MAP85_Init();break;
                 case 87:MAP87_Init();break;
                 case 88:MAP88_Init();break;
                case 91:MAP91_Init();break;//增加91
                 case 99:MAP99_Init();break;
                 case 113:MAP113_Init();break;
                 case 189:MAP189_Init();break;
                 case 225:MAP225_Init();break;
                 case 227:MAP227_Init();break;
                 case 240:MAP240_Init();break;
                 case 245:MAP245_Init();break;
                default:break;
        }
        NES_Mapper->Reset();
}
[/mw_shl_code]
nes_main.c中
[mw_shl_code=c,true]//加载ROM
//返回值:0,成功
//    1,内存错误
//    3,map错误
u8 nes_load_rom(void)
{  
    u8* p;  
        u8 i;
        u8 res=0;
        p=(u8*)romfile;        
        if(strncmp((char*)p,"NES",3)==0)
        {  
                RomHeader->ctrl_z=p[3];
                RomHeader->num_16k_rom_banks=p[4];
                RomHeader->num_8k_vrom_banks=p[5];
                RomHeader->flags_1=p[6];
                RomHeader->flags_2=p[7];
                if(RomHeader->flags_1&0x04)p+=512;                //有512字节的trainer:
                if(RomHeader->num_8k_vrom_banks>0)                //存在VROM,进行预解码
                {               
                        VROM_banks=p+16+(RomHeader->num_16k_rom_banks*0x4000);
#if        NES_RAM_SPEED==1        //1:内存占用小 0:速度快         
                        VROM_tiles=VROM_banks;         
#else  
                        VROM_tiles=mymalloc(SRAMEX,RomHeader->num_8k_vrom_banks*8*1024);//这里可能申请多达1MB内存!!!
                        if(VROM_tiles==0)VROM_tiles=VROM_banks;//内存不够用的情况下,尝试VROM_titles与VROM_banks共用内存                        
                        compile(RomHeader->num_8k_vrom_banks*8*1024/16,VROM_banks,VROM_tiles);  
#endif        
                }else
                {
                        VROM_banks=mymalloc(SRAMIN,8*1024);
                        VROM_tiles=mymalloc(SRAMEX,8*1024);
                        if(!VROM_banks||!VROM_tiles)res=1;
                }         
                VROM_1K_SIZE = RomHeader->num_8k_vrom_banks * 8;
                VROM_8K_SIZE = RomHeader->num_8k_vrom_banks;  
                MapperNo=(RomHeader->flags_1>>4)|(RomHeader->flags_2&0xf0);
                if(RomHeader->flags_2 & 0x0E)MapperNo=RomHeader->flags_1>>4;//忽略高四位,如果头看起来很糟糕
                printf("use map:%d ",MapperNo);
                for(i=0;i<255;i++)  // 查找支持的Mapper号
                {               
                        if (MapTab==MapperNo)break;               
                        if (MapTab==-1)res=3;
                }
                if(res==0)
                {
                        switch(MapperNo)
                        {
                                case 1:  
                                        MAP1=mymalloc(SRAMIN,sizeof(Mapper1Res));
                                        if(!MAP1)res=1;
                                        break;
                                case 4:  
                                case 6:
                                case 16:
                                case 17:
                                case 18:
                                case 19:
                                case 21:
                                case 23:
                                case 24:
                                case 25:
                                case 64:
                                case 65:
                                case 67:
                                case 69:
                                case 85:
                                case 91://增加91
                                case 189:
                                        MAPx=mymalloc(SRAMIN,sizeof(MapperCommRes));
                                        if(!MAPx)res=1;
                                        break;  
                                default:
                                        break;
                        }
                }
        }
        return res;        //返回执行结果
}
//释放内存
void nes_sram_free(void)
{
        myfree(SRAMIN,NES_RAM);               
        myfree(SRAMIN,NES_SRAM);        
        myfree(SRAMIN,RomHeader);        
        myfree(SRAMIN,NES_Mapper);
        myfree(SRAMIN,spr_ram);               
        myfree(SRAMIN,ppu);        
        myfree(SRAMIN,apu);        
        myfree(SRAMIN,wave_buffers);        
        myfree(SRAMIN,i2sbuf1);        
        myfree(SRAMIN,i2sbuf2);         
        myfree(SRAMEX,romfile);         
        if((VROM_tiles!=VROM_banks)&&VROM_banks&&VROM_tiles)//如果分别为VROM_banks和VROM_tiles申请了内存,则释放
        {
                myfree(SRAMIN,VROM_banks);
                myfree(SRAMEX,VROM_tiles);                 
        }
        switch (MapperNo)//释放map内存
        {
                case 1:                         //释放内存
                        myfree(SRAMIN,MAP1);
                        break;                 
                case 4:
                case 6:
                case 16:
                case 17:
                case 18:
                case 19:
                case 21:
                case 23:
                case 24:
                case 25:
                case 64:
                case 65:
                case 67:
                case 69:
                case 85:
                case 91://增加91
                case 189:
                        myfree(SRAMIN,MAPx);break;                         //释放内存
                default:break;
        }
        NES_RAM=0;        
        NES_SRAM=0;
        RomHeader=0;
        NES_Mapper=0;
        spr_ram=0;
        ppu=0;
        apu=0;
        wave_buffers=0;
        i2sbuf1=0;
        i2sbuf2=0;
        romfile=0;
        VROM_banks=0;
        VROM_tiles=0;
        MAP1=0;
        MAPx=0;
}

[/mw_shl_code]
Mapper文件091.cpp修改如下
[mw_shl_code=c,true]
/////////////////////////////////////////////////////////////////////
// Mapper 91
void MAP91_Reset()
{
  // set CPU bank pointers
//  set_CPU_bank4(num_8k_ROM_banks-2);
//  set_CPU_bank5(num_8k_ROM_banks-1);
//  set_CPU_bank6(num_8k_ROM_banks-2);
//  set_CPU_bank7(num_8k_ROM_banks-1);

  // set PPU bank pointers
  if(num_1k_VROM_banks)
  {
    set_PPU_banks(0,0,0,0,0,0,0,0);
  }
}

void MAP91_MemoryWrite(uint16 addr, uint8 data)
{
  switch(addr & 0xF00F)
  {
    case 0x6000:
      {
        set_PPU_bank0(data*2+0);
        set_PPU_bank1(data*2+1);
      }
      break;

    case 0x6001:
      {
        set_PPU_bank2(data*2+0);
        set_PPU_bank3(data*2+1);
      }
      break;

    case 0x6002:
      {
        set_PPU_bank4(data*2+0);
        set_PPU_bank5(data*2+1);
      }
      break;

    case 0x6003:
      {
        set_PPU_bank6(data*2+0);
        set_PPU_bank7(data*2+1);
      }
      break;

    case 0x7000:
      {
        set_CPU_bank4(data);
      }
      break;

    case 0x7001:
      {
        set_CPU_bank5(data);
      }
      break;

    case 0x7002:
      {
        MAPx->irq_counter = data;
      }
      break;

    case 0x7003:
      {
        MAPx->irq_enabled = data;
      }
      break;
   }
}

void MAP91_HSync(int scanline)
{
  if(MAPx->irq_enabled)
  {
    if(0 <= scanline && scanline <= 240)
    {
      if(spr_enabled() || bg_enabled())
      {
        if(!MAPx->irq_counter)
        {
          MAPx->irq_enabled = 0;
                                        CPU_IRQ;
        }
        else
        {
          MAPx->irq_counter--;
        }
      }
    }
  }
}

void MAP91_Init()
{
        NES_Mapper->Reset = MAP91_Reset;
        NES_Mapper->Write = MAP91_MemoryWrite;
        NES_Mapper->HSync=        MAP91_HSync;
}

/////////////////////////////////////////////////////////////////////

[/mw_shl_code]
友情提示: 此问题已得到解决,问题已经关闭,关闭后问题禁止继续编辑,回答。
该问题目前已经被作者或者管理员关闭, 无法添加新回复
20条回答
ye781205
1楼-- · 2019-07-22 16:51
zdfwyh 发表于 2016-5-14 18:27
太牛了,佩服的五体投地.不过我的模拟器来自原子F407的代码,没有哪几个"保存","读取"等那四个按钮而且,跟你 ...

代码已传,在二楼
zdfwyh
2楼-- · 2019-07-22 21:26
ye781205 发表于 2016-5-14 19:35
代码已传,在二楼

谢谢
zdfwyh
3楼-- · 2019-07-23 00:26
ye781205 发表于 2016-5-14 19:35
代码已传,在二楼

真不好意思,你的代码我已经移植了,可是最后还差一个函数nes_load_file,主要是你的程序框架好像已经有了变化,跟原子移植的不同了,原子原来的函数不好用了,希望能再提供一下这个函数的代码,谢谢了!
ye781205
4楼-- · 2019-07-23 04:32
 精彩回答 2  元偷偷看……
zdfwyh
5楼-- · 2019-07-23 06:26
ye781205 发表于 2016-5-15 10:43
已传  。。。。。

谢谢,万分感谢!!
zdfwyh
6楼-- · 2019-07-23 07:24
 精彩回答 2  元偷偷看……

一周热门 更多>