Taito X1-005(Mapper 80)被大家熟悉的游戏只有一个——不动明王传。

这也是为什么我确实没有发现有人改造过这个芯片。只能找到它的Pinout说明(https://wiki.nesdev.com/w/index.php/Taito_X1-005_pinout)。那么所有工作就只能靠自己了。之前改造的卡带都是有现成案例的,照着别人的线路来做,用现成的脚本烧录。可以说除了手上的技巧。并没有什么实质性挑战,也不用搞懂太多FC相关的知识。而这次,没有一定知识的积累是玩不转了。

主要的知识点

  • 经过了几次成功的改造,对于Kazzo的原理应该有了基本的了解,对于卡带MASK ROM的针脚布局也有了一定的感觉。所以这个时候我已经不再需要去查找NESDEV里MASK ROM的针脚定义(况且其本身也不全)了,每当拿到新卡带,我都会首先用万用表把针脚都测量一遍。不同卡带之间在数据线和A16以下的地址线布局方面都是一样的。这里主要需要弄清楚的是MASK ROM芯片的A17/A18/CE#怎么和Mapper芯片连接的。接着就是确定lash芯片的WE#、OE#、CE#该如何飞线。
  • Flash芯片是怎么被烧写和读取的。这在前面的文章中已经补充完了。写Flash芯片的过程就是发指令写字节的循环过程。
  • FC切Bank的知识和Mapper芯片Register的概念。Mapper上有一组寄存器,通过给它们发送指令来实现Bank的切换,并且Mapper往往都提供了一个以上的地址窗口。这些知识弄懂了,就知道如何编写烧录脚本,利用多个窗口来转动转盘实现数据写入。前文对这些知识也有介绍。

原材料

Taito X1-005没什么高质量的游戏,作为个中翘楚,不动明王传也就是个一般般的水平。这也导致这个Mapper对应的游戏都极其便宜,也很容易买到。

image

lizhu

这就是我买到的准备用来开刀的卡带。Taito虽然游戏做的不咋地,但卡带的外壳做的却是很用心。卡带后盖内部的四个角上分别有一个立柱,前后盖合在一起的时候立柱起到了对前盖上卡扣的限位作用,使得其更紧固。这样前盖在受到外力横向挤压变形时也不容易使卡扣松脱。这个设计非常困扰我,以至于我拆的两盘卡都断了卡扣。

image

image

改造ROM

Taito X1-005自带WRAM,有一个电池就能记录。但奇怪的是,这个棒球游戏貌似是密码记录的,不知道为什么还放了块电池在这里。

改霸王的大陆的时候,卡带的中心就有个洞,好让外壳的中柱穿过。这盘卡也是一样,但是好在CHR是32pin的,不会让洞口在改完后被挡住,也就不需要额外来改造外壳。

PRG是28pin,会增加些飞线的工作量。同时,旁边有个电容会碍事,在处理PRG时需要先把这个电容拆下来焊到卡带背面去。

根据开头所说的,我把每个MASK ROM针脚都用万用表测量了一下,下面是结果:

image

在这里要引入一个卡带改造的分步技巧。当改造一盘新的卡带时由于不确定自己的改的一定正确,所以可采用CHR和PRG分步拆改的流程,拆改一个验证一个。具体步骤是:

“DUMP卡带ROM” –> “拆除CHR ROM” –> “焊接并飞线CHR Flash” –> “用Kazoo烧录CHR” –> “测试”

“拆除PRG ROM” –> “焊接并飞线PRG Flash” –> “用Kazoo烧录PRG” –> “测试” –> “改造完毕”

虽然没有人改造过Taito X1–005,但是却有人做过dump,Kazzo源代码库中提供了Taito X1-005的dump脚本。如果懒的dump,也可以去网上下载一个这游戏的rom文件。

但是因为没有Taito X1-005的烧录脚本,那么CHR改好之后怎么往里写入数据呢?幸好我有一块多出来的MMC1卡带(下面称:工具卡),并且在最初的改造中给它装了IC座。按照到目前为止了解到的基础知识,我知道Kazzo至少是按照Mapper的定义来操纵芯片Register的切Bank操作,确保数据被写入Flash芯片的每一个Bank中,而并不关心写的是什么数据。

image

所以我利用这个特点,把MMC1的烧录脚本中“mappernum”这个属性改成80,然后就可以把数据写进Flash芯片了。按这种办法,我们就事先得到了写好数据的PRG和CHR Flash了。

那么就可以按照上面我介绍的技巧来分两步改造了。

image

  • A16要飞线,和其他卡带改造一样的。
  • CHR改造比较简单,因为OE和CE都有,把WE#焊到金手指47pin(PPU /WR)就好了。30pin对应的PCB焊盘是悬空的,所以这里要飞线接到VCC去。
  • PRG也不复杂,WE#连到金手指14pin(CPU R/W), A17也要飞线到X1-005的47pin。
  • 查看X1-005的pinout,发现是没有PRG /CE的。所以需要用74HC00芯片结合CPU R/W造一个PRG /CE出来。这和改造Namcot-163的情形是类似的,只是电路有一点点差异。

image

image

这样Taito X1-005/Mapper 80卡带就改造完成了。

image

因为我们要烧录的游戏“不动明王传”是Mapper 207,nesdev的pinout说明有提到mapper80和207的差异在于mapper芯片的17pin和31pin。这里我把31pin在PCB上的连线切断,然后焊上一根线,让它成为一个跳线,这根跳线实际就是卡带金手指的18pin(VRAM A10),把它连到31pin就是mapper 80,连到17pin就是mapper 207。

为了测试我的改造是否正确,之前我用工具卡烧录的是原卡dump出来的棒球游戏。所以先把跳线接在31pin上,然后上机测试是否游戏可以正常运行。

烧录脚本

现在就到了考验知识积累的时候了。
https://wiki.nesdev.com/w/index.php/INES_Mapper_080 https://wiki.nesdev.com/w/index.php/INES_Mapper_207 https://wiki.nesdev.com/w/index.php/INES_Mapper_082

查询nesdev上的资料,发现mapper 80/82/207的register配置都是一样的,mapper 82的文档里有详细的说明。那么就按照这个来写烧录脚本吧。

image

Taito X1-005有4个8KB PRG Bank,前3个可切换,第4个固定对应到Rom的最后一个8KB区域(256KB的PRG rom一共可划分为32个8KB bank,最后一个8KB就是第31个)。烧录的逻辑是:

CPU Bank Rom Bank 说明
0 0 在这个位置循环切Bank,切一次写一次数据
1 1 在这个区域执行0x2aaa指令
2 2 在这个区域执行0x5555指令
3 31 在这个区域写最后一个Bank

CHR有2个2KB和4个1KB Bank,所有都可以切换。留两个最高位的bank用来写指令,低位开始的4个bank用于写数据。烧录的逻辑是:

CPU Bank Rom Bank 说明
0 0 从0开始,每循环切到第n+4个
1 1 从1开始,每循环切到第n+4个
2 2 从2开始,每循环切到第n+4个
3 3 从3开始,每循环切到第n+4个
4 8 对应到0x2000,以执行0x2aaa
5 13 对应到0x5000,以执行0x5555

根据上面的信息,就可以写烧录脚本了。Kazzo的烧录脚本封装了几个不同功能的函数,来由主程序调用,从而实现必要的操作:

  • cpu_dump/ppu_dump:从卡带中dump数据。
  • cpu_ram_access:读写SRAM备份上传存档数据。
  • program_initalize:(这里日本人写了个错别字)初始化参数,设置写指令,并设置CPU Bank与Flash Bank的对应关系,就是选择相应的窗口然后转动转盘,把要烧录的起始位置暴露在窗口中
  • cpu_transfer:写入PRG
  • ppu_transfer: 写入CHR

初始化函数的写法:

function program_initalize(d, cpu_banksize, ppu_banksize)
{
	cpu_write(d, 0x7ef8, 0); //disable W-RAM

	//把写指令设置在高位,确保对高位指令Flash的支持
	cpu_command(d, 0x0000, 0x8000, cpu_banksize);
	cpu_command(d, 0x2aaa, 0xa000, cpu_banksize);
	cpu_command(d, 0x5555, 0xc000, cpu_banksize);
	
	//第2,3个CPU Bank与Flash的第2,3个Bank对应,因为寄存器的最低2位为无效位,所以需要左移2位
	cpu_write(d, 0x7EFC, 1<<2); //switch $A000-$BFFF window to rom 2nd bank
	cpu_write(d, 0x7EFE, 2<<2); //switch $C000-$DFFF window to rom 3rd bank	


	//把两个写指令地址分别设置在PPU Bank的前两个2KB Bank,因为0x0000是2KB Bank,所以ppu_banksize要乘以2
  	ppu_command(d, 0x0000, 0x1000, ppu_banksize);
	ppu_command(d, 0x2aaa, 0x1800, ppu_banksize*2);
	ppu_command(d, 0x5555, 0x1c00, ppu_banksize*2);
	
	//把PPU Bank的最后两个(1KB Bank)对应到第9,13个rom bank,确保0x2aaa和0x5555能正确执行。
	cpu_write(d, 0x7EF4, 8); //switch $1000-$13FF window to rom 9th 1k bank
	cpu_write(d, 0x7EF5, 13); //switch $1000-$13FF window to rom 14th 1k bank
	
}

PRG烧写函数的写法:

function cpu_transfer(d, start, end, cpu_banksize)
{
	//在第一个窗口写入数据,写入一次转动prg rom到下一个Bank,再写入
	for(local i = start; i < end - 1; i += 1){
		cpu_write(d, 0x7EFA, i);
		cpu_program(d, 0x8000, cpu_banksize);
	}
	//写入最后一个固定Bank
	cpu_program(d, 0xE000, cpu_banksize);
}

CHR烧写函数的写法:

function ppu_transfer(d, start, end, ppu_banksize)
{
	//循环转动rom bank,每次把4个bank分别转动到与4个1KB PPU Bank对应,然后4个连续写入。
	for(local i = start; i < end; i += 4){
		//Use the four 1KB-window to switch rom banks
		cpu_write(d, 0x7EF2, i);
		cpu_write(d, 0x7EF3, i|1);
		cpu_write(d, 0x7EF4, i|2);
		cpu_write(d, 0x7EF5, i|3);
		
		//program the above 4 banks
		ppu_program(d, 0x1000, ppu_banksize * 4);
	}
}

因为要支持烧录Mapper 80/207两种游戏,所以需要对脚本重构一下,分成三个文件:

  • mapper_80.ag
  • mapper_207.ag
  • taito_x1_005.ai

可以从这里下载:
https://github.com/maximaas/Famicom-DIY/blob/master/repro/kazzo_scripts

切换开关

为了让卡带实现在Mapper 80和207之间自由切换,现在要把刚才引出的跳线和x1-005的17pin、31pin之间安装一个开关。

image

按照图中的样子把先前焊上的跳线和x1-005的17pin、31pin与一个三脚开关连接好。然后在卡带前盖上开一个小槽让开关的拨片刚好能在槽中自由拨动。最后用热熔胶把开关固定在前盖上。

image

槽是手工用刻刀切的,一定要平直工整。

image

卡带后盖也要对应开槽,注意切削的深度。

colsed

完成后合上前后盖,开关拨片刚好突出约半个毫米,用手指甲可以很方便的切换,同时不影响整体外观。

games

分别烧录了几个两种mapper的游戏,测试都很完美。

最后贴好贴纸。

sticker

以下是Taito X1-005的改造手册,用UltraEdit打开可以全屏不用翻页。

https://github.com/maximaas/Famicom-DIY/blob/master/repro/Taito X1-005.txt

卡带的图片贴纸文件:

https://github.com/maximaas/Famicom-DIY/tree/master/sticker/不动明王传

- End -