任天堂产品系统文件
(Pinokio@163.com译、编2002/10/10)
目录
·1、系统简介·2、缩写表·3、中央处理器·4、图形处理器·5、声音处理器
·6、手柄、控制器和扩展口·7、内存映像硬件·8、I/O端口
·9、NES文件格式
·10、任天堂磁碟机系统
_____________________________________________________________________
1、系统简介
任天堂主机由6502处理器和一个特制的图形处理器组成。CPU是6502,而不是传言中的65C02(CMOS)。PPU的显存是和CPU的内存是分离的,可以通过对特殊端口的读/写来操作。卡带可能包含的内容有位于处理器地址$8000-$FFFF的ROM,和位于PPU地址$0000-$1FFF的VROM。由于NES只有2K的RAM,因此变量的可用的变量空间只有从$0000到$07FF共8个页面。在开机之后RAM和VRAM中的内容是0,但是注意:复位并不改变其中的内容。在更小的卡带,比如只有16KB的ROM,它占有$C000-$FFFF,而$8000-$BFFF的空间是不用的。那些大于32KB的卡带,它被特殊的电路分页到一定的地址空间。一些卡带在$6000-$7FFF有SRAM,那是电池存储的位置。卡带VROM被用来做图案表(例如Tile表,角色发生器等等)。通常的数量是8KB,包含两个图案表。大于8KB的VROM被特殊的电路分页到一定的地址空间。内部的VRAM在PPU内存里定位于$2000-$3FFF,它用来存储命名表(例如屏幕缓冲)。虽然PPU支持4个命名表,但只能支持两个的存放空间。另外的两个是开始两个的镜像。NES共有154条指令。
在本文本里,你将遇到如下形式的符号:“Dn"(5位,3位,等等)。位是按从最低位(0位)到最高位(7位)。所有的十六进制都在前面加上一个美圆符号($)($2002,$4026,等等)是在6502处理器汇编里常用的符号,二进制前面加上一个百分号%。
2、缩写表
NESFDSCPUPPUAPUMMCVRAMVROMROMRAMSPR-RAMSRAMDMC
任天堂娱乐系统任天堂磁碟机系统
中央处理器,NES使用一个定制的6502(NMOS)芯片,有些型号为6527图像处理器,用来处理背景,精灵和其他图像特性,通常为6538声音处理器,集合在CPU内部,包含4个模拟通道和1个数字通道
ROM和VROM的扩容控制,用来控制访问超过6502限制的64K地址,同样,也可以扩容VROM
图像RAM,PPU专用,2K字节
图像ROM,储存图像数据的地方,可以由MMC切换到VRAM里
程序ROM,实际程序储存的地方,扩容部分可以通过MMC切换到PRG-RAM里程序RAM,和ROM同义,不同的是它是RAM
精灵RAM,RAM中的256字节,专用于储存精灵,它不属于VRAM或ROM电池RAM,卡带上用来保存游戏记录的EPROM-电擦写ROM三角波调制通道,APU用来处理数字声音的,也写作PCM通道
Famicom任天堂家用计算机,即FC
EX-RAM扩展VRAM,用在MMC5里,可以扩展VRAM容量
3、中央处理器
NES定制的6502内部特别加上了声音处理单元。NTSC制式的NES使用1.7897725MHz主频,PAL制式使用1.773447MHz主频。CPU内存映像:
结束地址$1FFF$2007$3FFF$401F$5FFF$7FFF$BFFF$FFFF
开始地址用途$0000$2000$2008$4000$4020$6000$8000$C000
2K字节RAM,做4次镜象(即$0000-$07FF可用)寄存器
寄存器($2000-$2008的镜像,每8个字节镜像一次)寄存器扩展ROM
卡带的SRAM(需要有电池支持)卡带的下层ROM卡带的上层ROM
中断:
6502有3个中断IRQ/BRK、NMI和RESET,每个中断都有一个16位的向量,即指针,用来存放该中断发生时中断服务函数的地址。中断发生时CPU都会把状态标志和返回地址压栈,然后调用中断服务程序。
IRQ/BRK中断由一下两种情况产生:一是软件通过BRK指令产生,一是硬件通过IRQ引脚产生。
RESET在开机的时候触发,这是ROM被装入,6502跳到RESET向量指向的地址没有寄存器被修改,没有内存被清空,这些都只在开机是发生。
NMI指不可屏蔽中断,它在VBlank即屏幕刷新时发生,持续时间根据系统(NTSC/PAL)不同而不同。NTSC是每秒60次,而PAL是每秒50次。6502的中断延时是7个时钟周期,也就是说,进入和离开中断都需要7个时钟周期。它产生于PPU的每一帧结束,NMI中断可以由$2000的第7位的1/0控制允许/禁止。
大部分中断应该使用RTI指令返回,但是有些游戏不用,例如《最终幻想1》。它用一个很奇怪的方式:手工修改堆栈指针,然后执行RTS指令。这种方法在技术上是可行的,但是应该尽量避免。
以上中断在ROM内有以下对应的地址:
优先权中高
中断地址中断$FFFA$FFFC$FFFE
NMIRESET
IRQ/BR
低
K
特别说明:
NES的6502不支持10进制。虽然CLD和SED指令都正常工作,但是ADC和SBC都不使用CPU状态标志的“D”位。由于复位后“D”位的状态是不确定的,所以游戏通常在程序开始时使用一个CLD指令。
声音寄存器映射到CPU内部,所有波形发生的工作都在CPU内部完成。
注意那两个分开的16KROM段,它们可能是连续的,但是它们根据卡带的大小扮演不同的角色。有的卡带只有一个16KROM,那么它就同时被装入$8000和$COOO。
所有游戏都将它们自己装入$8000,使用32KRAM,但是它们都能够通过内存映射把多于一个16KROM装入$8000。VROM也是同样的道理。
当BRK中断发生的时候,CPU把状态标志压入堆栈,同时设置“B”标志。而IRQ中断发生时,CPU把状态标志压入堆栈,同时清除“B”标志。这是因为6502使用同一个向量来处理两种中断,用“B”标志来区分它们。你可以用以下程序来区别两种中断:
C134:PLA;拷贝CPU状态标志到AC135:PHA;把状态标志还回给堆栈C136:AND#$10;检查“B”标志C138:BNEis_BRK_opcode;如果设置了,就是软件中断(BRK)在NMI里指向BRK会导致已经被压栈的“B”标志被设置。
6502的$6C指令(间接绝对跳转)有一个BUG,当低位字节是$FF时CPU将不能正确计算有效地址。例如:
C100:4FC1FF:00C200:23..
D000:6CFFC1-JMP($C1FF)
本来它是应该跳到$2300的,但是在计算高位字节的时候,在页面边界处地址是不能再增加的,所以实际将跳转到$4F00。
需要注意的是,页面越界不会在变址间接寻址模式发生。由于0页面的限制,由于0页面的限制,所有变址间接寻址的读写都应该在计算有效地址之后和#$FF进行逻辑与操作。例如:
C000:LDX#3;从$0002+$0003读变址地址,C002:LDA($FF,X);不是$0102+$0103.
_______________________________________________________________________________
4、图形处理器
PPU时序:
NTSC制式
基频(Baseclock)CPU主频(Cpuclock)
总扫描线数(Totalscanlines)扫描线总周期(Scanlinetotalcycles)
水平扫描周期(H-Drawcycles)水平空白周期(H-Blankcycles)结束周期(Endcycles)帧周期(Framecycles)帧IRQ周期(FrameIRQcycles)帧率(Framerate)帧时间(Frameperiod)
21477270.0Hz1789772.5Hz262
PAL制式21281364.0Hz1773447.0Hz312
1364(15.75KHz)1362(15.625KHz)102434041364*2622983060(59.94Hz)
102433821362*3123546950Hz
1000.0/60.0(ms)1000.0/50.0(ms)
镜像是指通过硬件映射特殊的内存地址或范围的一个过程。PPU内存映像:
结束地址$0FFF$1FFF$23BF$23FF$27BF$27FF$2BBF$2BFF$2FBF$2FFF$3EFF$3F0F$3F1F$3FFF$7FFF
开始地址用途$0000$1000$2000$23C0$2400$27C0$2800$2BC0$2C00$2FC0$3000$3F00$3F10$3F20$4000
图案表0(256x2x8,可能是VROM)图案表1(256x2x8,可能是VROM)命名表0(32x30块)(镜像,见命名表镜像)
属性表0(镜像,见命名表镜像)命名表1(32x30块)(镜像,见命名表镜像)
属性表1(镜像,见命名表镜像)命名表2(32x30块)(镜像,见命名表镜像)
属性表2(镜像,见命名表镜像)命名表3(32x30块)(镜像,见命名表镜像)
属性表3(镜像,见命名表镜像)$2000-$2EFF的镜像背景调色板#1精灵调色板#1
镜像,(见调色板镜像)$0000-$3FFF的镜像
命名表:
NES的图像通过Tile矩阵来显示,这个网格就叫命名表。一个命名表和字符模式下的屏幕缓冲比较相象,它包含字符的代码,也就是30列的32Byte长度。每个Tile有8x8个象素,每个命名表有32x30个Tile,也就是256x240象素。PPU支持4个命名表,他们在$2000,$2400,$2800,$2C00。在NTSC制式下,上面和下面的8象素通常不显示出来,只有256x224象素;在PAL制式下,屏幕有256x240象素。
需要说的是,虽然PPU支持4个命名表,任天堂主机只支持2个命名表。另外两个被做了镜像。命名表保存了Tile的编号,而Tile存在图案表里。计算命名表里Tile号对应的实际地址的公式是:
(Tile号×16)+由$2000端口指定的图案表地址
命名表镜像:
NES只有2048字节($800)的VRAM给命名表使用,但是如前表所示,NES有能力寻址到4个命名表。缺省情况下,NES卡带都带有水平和垂直镜像,允许你改变命名表指向PPU的VRAM位置。这种方式同时影响两个命名表,你不能单独改变其中的一个。每个卡带都控制着PPU地址线的A10和A11。它可能将他们设置成以下4种可能的方式的1种。下面这个图表有助于理解NES里的各种镜像,指向PPUVRAM中命名表的12位地址相当于“$2xxxx”:
名字
水平
垂直
4屏幕
镜像命名表#0$000$000$000命名表#1$000$800$400
$X00命名表#2$400$000$800$X00命名表#3$400$800$C00$X00说明地址线地址线A11A10100110卡带里有2KVRAM,4个命名表物理上独立的所有的命名表指相同的VRAM区
域,X=0、4、8、C10单屏幕$X00
Mapper68#游戏映射VROM到PPUVRAM的命名表,这使得命名VROM镜表是基于VROM的,你不能写它但却可以通过mapper自己来控像制是否使用这种特性
图案表:
图案表储存了实际8x8象素的Tile,同时也储存了用来指向NES调色板全部16种颜色的4位元矩阵的低两位。PPU支持两个图案表在$0000和$1000。他们有以下格式:
VRAM地址图案表内容
$0000
..
..
..
..
..
..
$0007
$0008
..
..
..
..
..
..
$000F%00010000%00000000%01000100%00000000%11111110%00000000%10000010%00000000%00000000%00101000%01000100%10000010============$10$00$44$00组$FE0$00$82$00$00$28$44$82点表示0号颜色,数字表示实际调色板颜色代号颜色效果...1......2.2....3...3..2.....2.1111111.2.....2.3.....3.组%00000000=$001%10000010=$82%10000010=$82
%00000000=$00
注意在图案表里存储的是每个点的2个位。其他两个由属性表得到。所以,在屏幕上总体出现的颜色数是16,而每个块里只有4种颜色。
属性表:
每个命名表有它自己的属性表。属性表的每一个字节代表了屏幕上的一组4x4的Tile,一共有8x8个字节。有几种方法来描述属性表里一个字节的功能:
*保存32x32象素方格的高2位颜色,每16x16象素用2位;
*保存16个8x8Tile的高2位颜色;
*保存4个4x4Tile格子的高2位颜色。
看以下两个图表帮助理解:
1、一个16x16象素的格子:#0-F代表了一个8x8Tile,方块[x]代表了4个8x8Tile,方块
#0#1
#2#3方块1#4#5#6#7
方块
3
#C#D
#E#F方块2#8#9#A#B
2、属性表一个字节的实际格式定义如下(对应于上面的例子):
位
0、
1
2、
3
4、
5
6、
7描述方块0的高两位颜色(Tile#0,1,2,3)方块1的高两位颜色(Tile#4,5,6,7)方块2的高两位颜色(Tile#8,9,A,B)方块3的高两位颜色(Tile#C,D,E,F)
调色板:
NES有两个调色板,背景调色板和精灵调色板。调色板不包含实际的RGB值,它们更象一个索引表。写到$3F00-$3FFF的D6-D7字节被忽略。303132333435363738393A3B3C3D3E3F
202122232425262728292A2B2C2D2E2F
101112131415161718191A1B1C1D1E1F
000102030405060708090A0B0C0D0E0F
调色板镜像:
镜像发生在背景调色板和精灵调色板之间,例如所有写到$3F00的数据会被镜像到$3F10,$3F04镜像到$3F14。背景和精灵的最高3个调色板的0号色盘定义为透明,存在那里的颜色不会被画出来。PPU使用放在$3F00里的颜色作为背景色,详细如下:
*$0D被写到$3F00(镜像到$3F10);
*$03被写到$3F08(镜像到$3F18);
*$1A被写到$3F18;
*$3F08被读到累加器。
PPU使用$0D作为背景颜色,尽管$3F08有一个颜色$03(因为0号颜色在所有的调色板里都定义为透明)。最后,累加器上有一个值$1A,这是从$3F18映像过来的。又一次,这个$1A值没有被画出,因为所有的调色板的0号颜色被定义为透明。整个背景和精灵调色板同时也映像到VRAM的其他区域,$3F20-$3FFF全部都是这两个调色板分别的映像。写到$3F00-$3FFF的D6-D7字节被忽略。
背景滚动:
NES可以通过预提取命名表,图案表和属性表来使背景滚动,背景是独立于精灵而位于最下层的。可以水平和垂直滚动。
水平滚动
A512B垂直滚动AB0480命名表A通过$2000的D1-D0指定,B是跟在后面的一个命名表,根据镜像不同B是动态的。这个不能工作在水平和垂直同时滚动的游戏里。背景会跨越多个命名表,如下所示:
命名表命名表#2#3($2800)($2C00)
命名表命名表#0#1($2000)($2400)
在$2005里写到水平滚动的值可以从0-256,写到垂直滚动的值从0-239,239是考虑了负值的结果,例如248代表-8。
屏幕和精灵分层:
下面是NES画图的循序:
后
台
OBJs0-63
精灵RAM
BGPRI==0BOBJs0-G63精灵RAMBGPRI==1EXT前台CI
CI代表颜色亮度,相当于$2001的D7-D5;BG是背景;EXT是扩展口的图像信号。BGPRI代表VRAM里背景‘优先权’位,每个精灵都有的,即第二字节的D5位。OBJ数代表了实际精灵的号码,不是Tile索引值。前台高于任何其他层,最后被画上,后台低于任何其他层,最先被画上。
精灵和精灵RAM:
NES用一个页面(256字节)来存放动画,每个精灵4个字节,一共可以有64个动画/精灵,它们可以是8x8或8x16象素。动画/精灵图案被存储在VRAM的图案表其中一个里面。精灵属性,例如翻转和优先权被储存在一个特殊的256字节的精灵RAM,它不是CPU或PPU的地址的一部分。整个精灵RAM可以通过$4014的DMA方式来写,写一个8位的数到$4014就将这个8位数所指定的内存页面整个拷贝到精灵RAM上。也可以通过把开始地址放在$2003然后读/写于$2004(每次存取地址自动加一),它是一个一个字节存取的。动画/精灵的属性格式是:
动画/精灵属性RAM:
|精灵#0|精灵#1|...|精灵#62|精灵#63|
字节位
1描述YYYYYYY精灵左上角的Y坐标-1YIIIIIIITile索引号I
v=垂直翻转(1=翻转)
h=水平翻转(1=翻转)
2vhp000cp=背景优先权(0=前台1=后c台)
c=颜色的高2位
XXXXXXX精灵左上角的X坐标X3
Tile索引号就和命名表里的一样。精灵图案可以象Tile图案对于背景图片一样抓取。唯一的不同是在8x16的精灵时,上半部分(偶数号码)的Tile索引由精灵图案表的$0000开始,而下半部分(奇数号码)由$1000开始。$2000寄存器对8x16精灵无效。全部64个精灵有自己内部的优先权,0号最高(最后被画),63号最低(最先被画)。每条扫描线只能显示8个精灵,每个精灵RAM条目都会被检查是否处于其他精灵的水平范围内。注意,这是基于扫描线的,不是基于精灵的,也就是说,会进行256次检查,而不是256/8或256/16次。在一个真实的NES芯片里,如果精灵被禁止($2001的D4是0)很长一段时间,精灵数据会渐渐消失。可以理解为精灵RAM是一个DRAM,D4控制了DRAM的周期刷新信号。
碰撞标志:
碰撞标志是PPU状态寄存器($2002)的第6位(D6)。PPU能够找出0号精灵的位置,然后设置D6,它是这样工作的:PPU扫描出背景图案象素和精灵象素同时不是透明的第一个地方。比如,屏幕的背景是一个非透明颜色(颜色号>0),0号精灵的坐标是(12,34),它只是在第4行的开始才有象素,那么,碰撞标志在屏幕刷新到(12,37)时才被设置。要记住,0号颜色被定义为透明。引起D6被设置的象素必须是已经被画出来的。下面的例子能帮助理解,这是两个Tile,下划线表示透明的0号颜色,*号表示碰撞标志被设置。精灵背景结果
_________1111_
__
________111111
22
__1111________21122221
_111111_11
11222211_____21112__*1‘*’会用2号颜色画=1112__211+1出112__211____211112_221
1122221111
_111111____21111122221
__1111__11
__21111_111111
11
_211111_211111
11
这个例子说的是背景+精灵,但是对于靠近背景的精灵也通用,即精灵+精灵,通过设置背景优先权来实现。D6不可以通过读PPU的状态来复位,只在每次VBlank之后被清零。Hit标志可以用在水平或者垂直屏幕分割的时候,还有许多好玩的效果。
水平和垂直消隐:
所有的游戏机都有一个刷新动作,用来重新定位电子枪显示可见的数据。最通用的显示设备是电视机,它分为每秒刷新60次的NTSC制式和50次的PAL制式。电子枪从左到右画出象素,它每次只能画一条扫描线,画下一条之前要先回到左面并且做好准备,这之间有一段时间叫做水平消隐(HBlank)。在画完全部256条扫描线之后它又回到屏幕左上角准备下一次画屏幕(帧),这之间的一段时间就是垂直消隐(VBlank)。电子枪就是一个不断的走‘之’字形的过程。VBlank标志就是$2002的D7,它表明PPU是否在VBlank期间,当VBlank标志存在时,你就可以通过$2006和$2007访问PPU内存。一个程序可以通过读$2002来使D7复位。在屏幕刷新期间,我们不能访问PPU,而PPU会在CPU背后修改VRAM指针,这样我们很容易在写入VRAM时出错,为了让PPU停下来,可以对$2000和$2001写00。
访问PPURAM:
在一个任天堂主机,访问PPU内存只可以在VBlank期间。当在屏幕刷新时访问会破坏刷新地址寄存器,一般它经常用来做隐含的“分割屏幕”效果(见“在屏幕刷新的时候访问VRAM”)。很多小些的ROM用只读存储体(VROM)用做图案表。在这种情况下,你不可以写PPU地址,只可以读。
写PPU记忆体:
a)写高位地址字节到$2006b)写低位地址字节到$2006
c)写数据到$2007。每一个写操作后,地址会增加1($2000的第二位是0)或增加32($2000的第二位是1)。读PPU记忆体:
a)写高位地址字节到$2006b)写低位地址字节到$2006
c)从$2007读数据。从$2007读到的第一个字节是无效的(见下例)。然后每读一次地址就增加一($2000的第二位是0)或增加
32($2000的第二位是1)。
例子:VRAM的$2000里有$AA$BB$CC$DD。VRAM的增量是1。执行效果如下:
LDA#$20STA$2006LDA#$00
STA$2006;VRAM地址设为$2000LDA$2007;A=??VRAM缓冲=$AALDA$2007;A=$AAVRAM缓冲=$BBLDA$2007;A=$BBVRAM缓冲=$CCLDA#$20STA$2006LDA#$00
STA$2006;VRAM地址设为$2000LDA$2007;A=$CCVRAM缓冲=$AALDA$2007;A=$AAVRAM缓冲=$BB
这个只适用于$0000-$FEFF,访问调色板数据没有这种现象。
在屏幕刷新的时候访问VRAM:
前面说过,在屏幕刷新的时候存取VRAM的地址和数据是不合法的。许多程序存取这些寄存器来制造不同的滚动效果。比如,一些游戏从屏幕底部开始滚动,那么它可能向$2006写第一行的状态来复位屏幕滚动。更好的诡计是PPU在屏幕刷新时用VRAM的地址寄存器来储存当前地址。通过向$2006修改地址以及让PPU从一个不同的地方接着刷新。关于$2007如何影响屏幕刷新仍不了解。
当不知道向$2006中写什么数据时,看下面的图表。写到$2006的地址位0-45-9A、BC、DE、F
描述
Tiles的水平偏移量(例如1=8象素);水平位置=水平偏移量×8Tiles的垂直偏移量(例如1=8象素);垂直位置=垂直偏移量×8命名表的号码($2000,$2400,$2800,$2C00);
附加的垂直偏移量,单位:象素(0..3);扫描线=垂直偏移量+附加的垂直偏移量00
5、声音处理器
NES的集成CPU里包含了一个4声道的声音处理器(2A03),为播放音乐提供准模拟的声音。4个声道分别是:2个方波,一个三角波和一个噪声发生通道,每个声道的特性都不一样。
声道:
方波声道能够产生54.6Hz到12.4KHz的方波,它的主要特性是频率扫略功能和调整输出的占空周期;三角波声道可产生27.3Hz到55.9KHz分辨率是4位(16级)的三角波,它的主要特性是输出模拟三角波和线性计数器(可用来定时关闭声道);噪声通道能产生29.3Hz到44.7KHz的随机噪声,它的主要特性是产生伪随机数,在声道输出随机频率。
帧计数器:
2A03有一个内含的帧计数器,它能够产生60Hz(1/1帧率)、120Hz(1/2帧率)和240Hz(1/4帧率)的信号,提供给其他一些声音硬件使用。1/4帧率的信号是由CPU频率乘以2即3579545Hz再除以14915得到的。
声音硬件延迟:
在2A03复位之后,到各个声音硬件开始接收时钟信号之间有2048个时钟周期的延迟。当这2K个时钟周期之后,声音开始正常工作,输出使能有效。这种现象只发生在系统复位之后的2048个时钟周期内。这个资料的准确性有待验证。
控制寄存器:
2A03的声音控制寄存器在CPU内分配的特殊地址如下:寄存器地址$4000-$4003$4004-$4007$4008-$400B$400C-$400F$4015
描述方波1方波2三角波噪声
声道使能、音长计数状态
只有$4015是可读可写的,其他都是只能够写的,如果你读这些寄存器最可能得到的是$40(因为NES数据线的重负荷)。读这些只写寄存器对寄存器本身和声道都没有任何影响。每个声音通道都有4个寄存器,具体描述如下:
寄存器位$4000/$4004/$400C$4001/$4005
0123
音量衰减率右移量
1减少/0增加波长
4567无衰音长计数中止/
占空周期类型
减衰减循环使能扫描更新率
扫描使能
$4002/$4006/$400A波长低八位$4003/$4007/$400B/$400波长高三
音长计数值
F位$4008$4009/$400D$400E
$4015:音长状态(读)$4015:通道使能(写)声道结构体系:总表:设备
三角阶梯发生器线性计数器可编程定时器音长计数器4位DAC
音量衰减单元扫频单元
占空周期发生器波长转换器随机数发生器
三角波√√√√√
噪声
方波
线性计数值未使用播放采样率方方三
噪声
12角方方三
噪声
12角
音长计数中止/线性计数开始
未使用DMC未使用DMC未使用
随机数类型发生DMC的IRQ状态
√√√√
√√√√√√
√√
三角阶梯发生器:
这是一个5位的单向的计数器,只存在于三角波通道,计数器输出的低4位分别通到一个XNOR(异或非)门。4个XNOR门被同一个选通信号控制,当选通是0时,计数器输出的4个低位在门电路的输出端反相;当选通是1时,不反相。选通信号连到计数器的最高位,这样就可以在XNOR门的输出端产生一个计数序列,就造出了一个比较理想的三角阶梯信号发生器。XNOR门的输出反馈到一个4位的DAC输入端。当三角波的音长计数器或线性计数器是0时,这个5位的计算器会暂停,同时锁定,计数器不会被重设置到某一个特定的状态。在系统复位的时候,计数器装入0。计数器的时钟输入直接连接到三角波通道内一个11位的可编程定时器的输出端,这样,这个5位的三角波阶梯信号发生器的输出频率就是通道内可编程定时器频率的1/32。
线性计数器:($4008)
这是一个7位的递减计数器,只存在于三角波通道,计数器减到0时输出。计数器的时钟是240Hz(1/4帧率),用帧来计算长度就是0.25×N,其中N是预先装入的7位的值。计数器会保持计数状态直到输出0,这时线性计数器和三角阶梯发生器的时钟信号被禁止,导致两个计数器被锁定,线性计数器的输出保持是0,声道因此而出现静音。线性计算器有两种工作模式:装入和计数。在装入模式,所有的输入(写到$4008)的值都会在传送到
输出,也就没有计数;在计数模式,计数器会从当前值向下减,在$4008的数会被忽略。下表表示了如何通过$4008的最高位设置计数器:旧值011
新值X01
模式计数
在写周期没有变化,计数没有变化
可编程定时器($4002/3、$4006/7、$400A/B、$400F):
这是一个11位可预设的递减计数器,每个声音通道都有,但是注意在噪声通道不是直接可用的,详见“波长转换器”。这个计数器在计数完成的时候自动重载,因此它在减到0前会计算N+1个时钟周期,其中N是预装入的11位值。这个计数器直接使用6502的频率(1.79MHz)作为时钟,输出频率是1.79MHz/(N+1)。当到达计数终点的时候会产生一个1时钟周期的脉冲,而输出频率会被反馈到对应于声音通道的特殊设备。对于方波,这个计数终点脉冲会被送到占空周期发生器;对于三角波,会被送到三角阶梯发生器;对于噪声,会被送到随机数发生器。
音长计数器($4003、$4007、$400B、$400F):
这是一个7位的递减计数器,时钟是60Hz,每个声音通道都有。当计数器减到0,计数停止,相应的通道出现静音。可以通过设置音长计数时钟的禁止位来暂停计数,写1则中止计数,0则允许计数。在不同的寄存器里,这个位的位置不同,见寄存器表。计数值通过$4003、$4007、$400B和$400F的3-7位来写入。输入的5位值通过下面2个表转换到计数器的7位值:第3位=04-6位的值
01234567
帧
第7位=0第7位=1
05060A0C1418283050601E2407080E10
第3位=1
4-7位帧07F101202303404505606707808909A0AB0BC0CD0CE0EF0F
音长计数器的状态可以通过$4015来读取,0表示计数器处于0状态(停止在0),1表示
处于非0状态。通过写0到$4015可以令音长计数器永远处于0状态,使得声道被禁止;写1可以取消禁止状态,但它不会改变计数器里面的值。在系统复位时这个寄存器全部5个使用的位都被设置为0。
4位DAC:
这是一个标准的4位DAC(数模转换)单元,有16级输出电压,4个声道共用。在
2A03里,方波1和方波2混合通过引脚1输入,三角波和噪音通过引脚2输入。这些模拟量输出需要一个负的电流源,以使得电压的级输出变成平滑的声音信号。因为NES只外置了一个100欧姆的下拉电阻,使得输出波形的幅值很小,但是也获得最小的不平滑度。这个不平滑度小到难以发现,就算用示波器也不明显。
音量衰减单元($4000、$4004、$400C):
音量衰减器只存在于方波和噪声通道。当衰减禁止位(第4位)被设置为1,当前的音量值(0-3位)被直接送到DAC。在下列情况中,音量值会被忽略,而直接送0到DAC。·声道硬件要停止声音,例如音长计数器或扫频单元;
·处于占空周期或随机数发生器输出频率信号的负值部分,也即在声音使能的时候送到DAC的或者是音量值或者是0(无声)。
当衰减禁止位被清零,0-3位当前的值就是衰减率。衰减率是指音量从最大值向下线性衰减的速度,衰减速度是240/(N+1),N的值从$0-$F。当衰减到0之后,根据寄存器第5位的状态将发生两种情况:第5位
01
行为
音量停在0,声道静音
音量循环不断从最大值减到0
只有通过对寄存器进行写操作才能重新设置硬件的衰减状态,否则就一直按当前状态进行衰减甚至循环,即使寄存器的第4位被设置成禁止衰减也没有用。
扫频单元:
这个东西只存在在方波通道中。当寄存器的第7位被设为1,扫频被激活,波长会实时地增加或减少(对应频率降低或提高)。波长的值通过$4002/3和$4006/7被不断的读入和更新,写到那里的值会立刻反应到声音里。第4-6位代表了频率扫略速度,或者说$4002/3和$4006/7里波长值被改变的频率。刷新率是120Hz/(N+1),N是写入的值,从0-7。第3位控制扫频的模式,1表示波长减少,0表示波长增加。第0-2位是右移量,用来控制波长增量的右移量,见下表:第3位
01
表达式,N是右移量从0-7波长=波长+(波长>>N)波长=波长-(波长>>N)
当满足以下3个条件,波长寄存器每个周期都会被更新:·第7位被设置,即扫频使能;·右移量不等于0;·音量计数器的值非0。
以下两种情况会暂停扫描时钟,使声道静音,而不管扫描刷新率是多少或扫描使能位是否设置:
·11位的波长值小于$008;
·扫频处于增加模式,而进位标志=1。硬件在波长寄存器被更新之前总要检查进位标志的。
占空周期发生器($4000、$4004):
占空周期发生器只存在于方波通道,它使用可编程定时器的输出频率作为时钟,使用4位计数器来产生4种类型的占空周期,因此它的输出频率是可编程定时器的1/16,输出信号反馈到音量衰减器。占空类型见下表:
6、7位00011011一个时钟周期里的占空周期(正/负)2/144/128/812/4
波长转换器($400E):
这个东西只存在于噪声通道,用来将一个给定的4位值转换成11位的波长,然后送到可编程定时器。下表是转换关系:0-3位0123456789ABCDEF
音度1514131211111010109988765
音阶AAAAADAFCADADAAA
CPU时钟周期(11位波长+1)
00200400801002003004005006507F0BE0FE17D1FC3F97F2
随机数发生器($400E):
噪声通道有一个1位的伪随机数发生器,它是由一个15位的移位寄存器和一个异或门组成,它能够提供‘长’和‘短’两种类型的伪随机数序列:当寄存器第7位是0时,产生32767位的长序列(32K模式);是1时,产生93位的短序列(93位模式)。93位模式通常在声道中产生较高频率的声音回放。下表说明了在移位寄存器的那些位里进行异或:EDCBA9876543210<-------------<32K**93位**模式
当前的异或结果在下一个移位周期之前送到移位寄存器的0位,1个位的随机数从E引脚输出,反相然后送到音量衰减器。移位寄存器每接收到两个可编程定时器的时钟脉冲就移位一次,所以它的频率是可编程定时器的一半,也就是低一个音度。系统复位的时候移位寄存器被装入值1。
6、手柄、控制器和扩展口
NES支持很多种输入设备,主要有手柄,光枪、4适配器和摇杆。两个手柄分别通过$4016和$4017访问,用选通脉冲对手柄复位,即对$4016或$4017先写1后写0,这将在游戏手柄的电路里发生个脉冲,然后可以在$4016或$4017读取了。每次读取将返回一个单一的按钮的状态,在第0位(1表示按下,0表没有)。第1位表示了游戏棒是否和端口连接。如果连接就置0,否则是1。第6和7位的$4016/$4017好像有相同的重要性,不知是什么,有些游戏期望当一个按钮按下的时候在$4016/$4017得到$41。复位的时候返回0。
111111111122222012345678901234
信号
0000
读取#1按键
A键
2B键
3选择
4开始
56789
上下左右忽略
信号用来检测是4端口的接入状态:
%0000:没有连接设备%0001:只有$4016手柄%0010:只有$4017手柄光枪:
只是简单地使用了$4016或$4017的D0、D3和D4位,完全有可能同时接两支光枪。4适配器:
将手柄扩展到4个,支持4手柄的游戏有:Tengen的《GauntletII》和Nintendo的《RCProAm2》。全部4个控制器使用$4016或$4017的D0位。对于$4016端口,读1-8字节是手柄1,9-16字节是手柄3,$4017则对应手柄2和4。读
1取
1112222278901234
0000
2345678910111213141516
1P1P2P2P
按1P1P1P1P1P1P2P2P2P2P2P2P
选开选开信号
键AB上下左右AB上下左右
择始择始
摇杆:
有的游戏使用摇杆,例如Taito的《Arkanoid》。摇杆的位置通过$4017的D1来读取,第一个读的是MSB,第8个读的是LSB,有效值的范围是98-242,98代表了,摇杆完全是被逆时针转的。读到的数据要取反,例如读到%01101011,取反是%10010100,即146。摇杆还带有一个按钮,通过$4016的D1来读取,1代表按钮被按下。
扩展口:
NES都有一个扩展口,用来接手柄或双手柄。手柄初始化需要写1和0,如果初始化没有完成,或者循序错了,扩展口就可以用来通讯,例如:
LDA#%00000001STA$4016STA$4017;开始扩展口的读模式LDA#%00000011;写%110到扩展口STA$4016
确实有些卡带用这种方式来通讯。
任天堂主机内部输入/输出端口映射到$2000-$2007和$4000-$4017。一些端口的用处是未明的或未知的。任何有关信息将受到感激。
7、内存映射硬件
这里只提供一些硬件资料,软件方面请参考扩容资料。
Mapper其实就是硬件上的地址映射。用了切换ROM和VROM,更有的用于动态切换VROM。动态切换VROM通常有2种办法:一是用Latches,所谓Latch就是切换器,当PPU访问命名表遇到特定的数据时,自动切换去指定的VROM,例如圣火徽章外传就用了这种方法,它的特定数据是FE和FD,就是对话框的两个边^_^;二是用IRQ中断,算好PPU的时序和CPU的指令周期后设置IRQ计数器,等待到特定的时候就触发IRQ中断,调用中断服务切换VROM,例如三国志2-霸王之大陆就是这样,有的IRQ计数器是每个CPU周期增加1,有的是每条扫描线增加1,视硬件电路而定。
图例:
R:连接到ROM部分;
S:由ROM,MMC和NES共用;N:连接到卡带接口;W:连接到电池RAM;Pxxx:对应于CPU的;Vxxx:对应于PPU的;M2:时钟。+5V24)1RPA14
M223MMC12RPA15
PA1322N3RPA16
PA1421N4RPA17
P-CE20N5RP-CE
PD719S6WB-CE
PD018S7RVA12
R/W178RVA13
VA1016N9RVA14
VA1215N10RVA15
VA1114S
V1013S
11R/W12VA16/B
GND
-CE
RD387-001:+5V+5VGNDXX)XXGND
VA1038
4039
N
MMC2
020301
NNPA1PA1M2
43
VA1537R04RPA15
VA1236R05RPA14
VA1435R06SPA12
VA1234N07RPA13
VA1333R08RPA16
VA1VA1
VA8VA5VA9VA4VA3VA7VA261
323130292827262524RSSSSSSSS09101112131415RSSSSSNP-PD4PD3PD0PD1PD2R/WCE
16NP-CE
VA1V-VA10CE232221SSS
171819
20
SSSV-VA0VA6GNDRD
B-GNP-PA1PA1PA1PD6PA0PD7CEM2D+5VCE
83733323130S
S
S
W
29
2827
26
252423RRNR
PD03422PA1SR4PD53521PA1SR6PD13620PA1SN4PD43719PA1SR3PD23818PA1SR5PD339MMC3
17SNR/WGND4016?B-41CEW15GNDB-4214P-WEWNCEPA1431R13IRQPA14412VA16
R
R
7
12R3N4N5N6
7R8R9R1011
N
R?
VA1VA1VA1VA1GNVA1VA1VA1VA1VA10210D34205
MMC5:引功引功引功引功引功脚能脚能脚能脚能脚能1RC021VA14161PA1R6SPD5R481NC2RC122VA14262PA1R7SPD6R582
NC3RC223VA14363PA183B-R8SPD7R6WCE4
+5V
24VA1PA184R944
+5V64R7SVD05SVA025VA145PA185N0SPA065R8SVD16SVA126VA14666PA186N1SPA1R9SVD27SVA227VA14767PA187N2SPA2N3SVD38SVA3
28VA14868PA188N
3
SPA3N4
SVD49SVA429NC
49SPA469WA13
89SVD510VA530NC
50SPA570SWA14
90SVD611VA631V-51PA671CE-91SNCESW0SVD712VA732VA152PA7
72CE-SN0SW
192NC13SVA833V-53NWRSPA873NC93NC14SVA934V-54SRDS
PA9
74P-94R
CERVA015VA135PA1
R0NIRQ
55SNC950
75RVA116VA136PD0
56R1SWVCC
76B-96WWERVA217VA137R2SPD157+BA
T77NC97CL318VA138R3SPD2
58PA1
S1
78NC98SL319VA139R4SPD3
59PA179S2NM2
99
GND
20VA140R
5
S
PD4
60PA1
R3
80GND100RC3
MMC6:引功引功引功
引功引功引功引功脚
能脚能脚能脚能脚能脚能脚能1NPA1VA141311
GND
21R331IRQSPD551SPA561PA1R42M2
12
+5V
22VA132P-42R2NCESPA052SPA662PA1R83GND13HLD
23VA14363PA1R433
R/WSPD653SPA9N44GND14VA1
34
445464PA1N024GND
SPD2SPA1SPA7R
7
5GND
15VA1
+BA35PD34555N1
25TSSPD7
S
PA86NC16
NC
26VA136R8SPD146PA256+BAST7GND
17VA127VA1
P-R0N037GND47RCE57
GND8+5V
18VA128V-+BA48PA1R6SRD
38TSPA3
58
S29+5V
19VA129V-39R1SCESPD449PA4
59PA1SR310
+BA20VA130VA140PA160TN
2R
7S
PD0
50PA1R
6R
5
NES-CN-ROM-256-[02,05]:+5V
NCVA14VA13VA12VA11GNDR/W1615
14R13R12111009)74LS1610102030405060708+5V
P-CE
PD0
PD1
PD4
PD5
GND
GND
NES-AOROM-03NES-BN-ROM-01:+5VNCPA15PA16
PA17VA10GNDR/W1615141312111009)74LS1610102030405060708+5V
P-CEPD0
PD1
PD2
PD4
GND
GND
NES-CN-ROM-256-[02,05]:+5VNCLS32-13LS32-2LS32-9NC
GNDR/W161514R13R12111009)74LS1610102030405060708+5V
P-CEPD0PD1
PD2
GND
GND
GND
+5V14)01A14LS161-14A141312LS320203RLS161-13A15
A1411R04GND
A141005GND
LS161-12A160908R06NC
07GND
NES-ANROM-03:+5V16)01+5V
NCPA15151474LS1610203P-CEPD0
PA16
1304PD1
NC1205+5V
VA101106PD4
GND1007GND
R/W0908GND
+5V14)01-12-8-913LS0202R/W
-11203RR/W
P-CE11R04NC
CE10R05GND
-130906GND
-130807GND
CPU:
Loa
Q1Q2d
40393837)6502/652701020304AudAudRES
A0
io1io2ET+5V
INPINP
NMIR/WIRQM2
01
36353433323105A1
06A2
07A3
08A4
09A5
10A6
GNDCLKD03011A7
2912A8
2813A9
D12714
D22615
D32516
D42417
D52318
D62219
D72120
A10A11A12A13A14A15GND
PPU:
+5VALEAD0AD1AD2AD3AD4AD5AD6AD7A8A9A10A11A12A13RDWRRST40)01PR/W
VIDEOOUT
393837363534333231302928272625242322216528/6538
020304050607080910111213141516171819
20
PPPPPPPPPPPPPPPPPP
D0D1D2D3D4D5D6D7A2A1A0CEGNDGNDGNDGNDCLKINTGND
8、I/O端口
端口是预分配好的可访问地址,程序通过端口和PPU或APU交换信息。每个端口都是16位的
读写/
功能描述
位
PPU控制寄存器1命名表地址:
%10($2800)%11($2C00)
0-1
%00($2000)%01($2400)
请记住,因为镜像,只有2个真实的命名表,而不是4个;当滚动超出当前命名表时PPU会自动切换到另一个命名表垂直写,1=VRAM地址以32递增:命名表,VW=0
2
——>写
命名表,VW=1|写|V
端口
$2000读写
34567
$2001读写
01234
精灵图案表地址,1=$1000,0=$0000屏幕图案表地址,1=$1000,0=$0000精灵尺寸,1=8x16,0=8x8PPU主/从模式,没有在NES里使用Vblank使能,1=在Vblank时发生中断PPU控制寄存器2
显示模式,0=彩色,1=单色背景掩码,0=不显示屏幕的左8列精灵掩码,0=不在左8列显示精灵屏幕使能,1=显示图像,0=黑屏精灵使能,1=显示精灵,0=隐藏精灵
当D0=0:背景颜色,%000=黑,%001=蓝,%010=绿,%100=红;不用混合使用,因为可能会损坏PPU硬件
当D0=1:颜色亮度,%000没效果,%001强化蓝色,%010强化绿色,%100强化红色,不要混合使用
PPU状态寄存器:读取后$2005和$2006被复位,下一个写到$2005的数据是水平的,写到$2006的数据是高位未知(???)
VRAM写标志:0=写有效,1=写忽略
扫描线精灵计数:0=当前扫描线精灵个数小于等于8个,1=大于8个
5-7
$2002
读0-345
67
$2003写$2004读写$2005写$2006写$2007读写$4000写$4001写$4002写$4003写$4004写$4005写$4006写$4007写$4008写$4009?$400A写$400B写$400C写$400D$400E写$400F写$4010写$4011写$4012写$4013写$4014写$4015读写
01234
命中标志:1=精灵刷新碰到了#0精灵。在屏幕刷新状态,这个标志被复位为0
Vblank标志:1=PPU在Vblank状态。当Vblank结束或CPU读$2002时,该标志被复位为0
精灵RAM地址:用来设置通过$2004访问的256字节精灵RAM地址。每次访问$2004后该地址增加1
精灵RAM数据:用来读/写精灵内存。地址通过$2003来设置,每次访问后地址增加1
屏幕滚动偏移:第一个写的值会进入垂直滚动寄存器(若>239,被忽略)。第二个值出现在水平滚动寄存器
VRAM地址:设置$2007访问的VRAM地址。第一个写地址的高6位。第二个写低8位。每次访问$2007后地址增加
VRAM数据:用来访问VRAM数据,通过$2006设置的地址在每次访问之后会增加1或32APU方波#1控制端口APU方波#1音量控制端口APU方波#1细音调(FT)端口APU方波#1粗音调(CT)端口APU方波#2控制端口APU方波#2音量控制端口APU方波#2细音调(FT)端口APU方波#2粗音调(CT)端口APU三角波控制端口#1APU三角波控制端口#2APU三角波频率端口#1APU三角波频率端口#2APU噪声控制端口#1未使用(???)APU噪声频率端口#1APU噪声频率端口#2APU增量调制控制端口APU增量调制D/A端口APU增量调制地址端口APU增量调制数据长度
DMA访问精灵RAM:通过写一个值xx到这个端口,引起CPU内存地址为$xx00-$xxFF的区域传送到精灵内存声音通道切换
方波#1通道:1=声音使能,方波#2通道:1=声音使能,三角波通道:1=声音使能,噪声通道:1=声音使能,增量调制:1=声音使能,
5、76(只读)
$4016读写
01342、5-7
$4017读写
012、53467
未使用(???)
垂直时钟信号IRQ可用:0=1帧存在,因为没有IRQ;1=1帧被IRQ中断手柄1+选通
读:手柄1数据;写:选通,1=复位,0=清除;扩展端口:0=写,1=读
手柄1存在,0=连接光枪精灵检测:1=瞄准光枪扳机:0=按下,1=松开未知,6、7设为%10(???)手柄2+选通
读:手柄2数据;写:选通,1=复位,0=清除;扩展端口:0=??,1=读
手柄2存在,0=连接未使用(???)
光枪精灵检测:1=瞄准光枪扳机:0=按下,1=松开
垂直时钟信号(内部),0=存在,$4016的D6受影响;1=不存在$4016的D6不可触及
垂直时钟信号(外部),0=存在,1=不存在
9、NES文件格式
.NES文件为模拟用来储存NES卡带的映像。下面是一个.NES文件的结构。
字节数111
偏移内容
字符串“NES^Z”用来识别.NES文件16kBROM的数目8kBVROM的数目
D0:1=垂直镜像,0=水平镜像
D1:1=有电池记忆,SRAM地址$6000-$7FFFD2:1=在$7000-$71FF有一个512字节的trainerD3:1=4屏幕VRAM布局D4-D7:ROMMapper的低4位
0-34456
71D0-D3:保留,必须是0(准备作为副Mapper号^_^)D4-D7:ROMMapper的高4位保留,必须是0
ROM段升序排列,如果存在trainer,它的512字节摆在ROM段之前
VROM段,升序排列
8-F816-16KxM-EOF8KxN
10、任天堂磁碟机系统
任天堂家庭机磁碟系统(FDS)是它的扩展单位,它只是由任天堂公司生产以及只在亚洲国家销售。它有一个软盘驱动器可以插2.5寸软盘,可以以32KB的RAM(代替了ROM)来读进程序。8KB的VRAM(代替了VROM),其他的硬件描述于下。内存映像:
FDS的地址空间的描述:
2kBInternalRAM,mirrored4times
$0000
$2000Input/Output$5000ExpansionModules$600032kBProgramRAM$E0008kBFDSBIOSROM
FDS还增加了一些I/O端口于$4000-$40FF来控制磁盘系统,声音系统,IRQ记数器。
读写/位
端口功能描述
LowerByteofIRQCounterUpperByteofIRQCounterEnable/DisableIRQs
=StopIRQcounterandresetitsinterruptrequest
/=LoadIRQcounterwithavaluefrom$4020-$4021andstartitDataWriteRegister:Towritedatatothedisk,outputitintothisregister
ControlRegister
DriveMotor,0=on,1=off
=SetdriveheadtothestartofthefirsttrackDiskWrite,0=enabled,1=disabled
ScreenMirroring,0=vertical,1=horizontalUnknown(???)
DiskIRQs,0=disabled,1=enabledExPortOutput(???)DiskStatusRegister0Unknown(???)Unknown(???)
DataReadRegister:Toreaddatafromthedisk,inputitfromthisregister
DiskStatusRegister1
DiskPresence,0=inserted,1=notinsertedDiskReady,0=ready,1=notready
26
$4020W$4021W$4022W
2$4024W$4025W
01234-67$4026W$4030R
46$4031R$4032R
01
2$4033R
7
WriteProtection,0=unprotected,1=protectedExPortInput
BatteryStatus,0=ok,1=low
可屏蔽中断计数器:
FDS提供了一个16位的IRQ记数器连接到CPU时钟发生器。计数器开始于你写在$4021的一个预设在$4020-$4021的值。它在每个CPU时钟周期后减一。当计数器为零时,它从预设的值开始继续计数。这时就发生了一个IRQ。当垂直空白时,屏幕刷新时也会发生。$4022的第2个位用来控制IRQ计数器。当它是0,那么计数停止,要到达的IRQ被复位(如果有的话)。设置了1后,记数可以被恢复。
磁碟格式:
每个磁盘有两面,A和B,每面可以有65000字节的数据。要反转一个当前面,必须先拿出来,反转,重新插回去。数据在每个面上被储存于一系列的不同类型的块[1,2,3,4,3,4,...,3,4]。Block
1.SideHeaderBlock(56bytes)
Byte01-141516-19202122-242526-56
2.FileNumberBlock(2bytes)
3.FileHeaderBlock(16bytes)
0101-23-1011-1213-1415
4.FileDataBlock(variablelength)
01-...
Description$01
"*NINTENDO-HVC*"MakerIDSideNameVersionNumber
SideNumber,$00=SideA,$01=SideBAdditionalDiskData$08
ReservedSpace(notusedbyBIOS)$02
NumberofFilesonthisside$03
FileNumber(notusedbyBIOS?)FileName(notusedbyBIOS?)StartingAddressinmemoryFileSize
FileType:$00=ProgramData,$01=CharacterData,$02=ScreenData$04
Data(seeFileHeaderBlockforsize)
所以两字节地方都以最重要的字节开始。面的名称可能和相同游戏软盘的不同面不同,但它们是一样的。当文件被读取,开始的地址在RAM和VRAM都是实在的地址。
27
磁碟访问:
下面的图表显示了FDS如何从软盘中读/写。READ:$40257bit6bit5bit4bit2bit1bit0bitNoteWRITE:$40257bit6bit5bit4bit2bit1bit0bitNote
A__-_--_
B____--__---_--C___---______--1
D---___-2
E--_--_---_-___-___--_34
A)InitializationB)Motoron
C)WritestartmarkD)EnableIRQsE)Writeendmark1.2.3.4.
Delay,write[00000000]Write[10000000]
Writedata,($4030)=[xx0xxxxx]Delay
A__-_--_
B____--__---_--C_--_-_-D---_-_-E--_--_---_-_
A)InitializationB)Motoron
C)ReadstartmarkD)EnableIRQsE)Readendmark
---1.Readdata,($4030)=[xx0xxxxx]___2.Readdata,($4030)=[xxx0xxxx]--_12
对于读写是如何完成的并不清楚。虽然知道FDS每当一个字节从软盘里读出的时候就发生一个IRQ。FDS的IRQ处理器(是FDS的BIOS一部分)在$4031读取这个字节,然后指针指向下个字节。磁碟错误:
下面是软盘错误的信息:ERR010203040506
Meaning
NodiskNopower
BrokenprongonthediskWrongmakerIDWronggamenameWronggameversion
注释
没有软盘没有电源????
不正确的游戏名字不正确的游戏版本不正确的盘面(反转之)
一号软盘错二号软盘错三号软盘错
28
07Wrongsidenumber(flipthedisk)08Wrongdisk#109Wrongdisk#210Wrongdisk#3
111213141516171819202122232425262728293031
Allowsittorecognizescreendatadiffers(???)??WrongSideHeaderBlock("*NINTENDO-HVC*")不正确的盘面柱头块WrongSideHeaderBlockID($01)不正确的盘面柱头块号WrongFileNumberBlockID($02)不正确的文件块号WrongFileHeaderBlockID($03)不正确的文件头块号WrongFileDataBlockID($04)不正确的文件数据块号Errorwritingdatatothedisk写文件错Blockendsprematurely块过早结束Thediskunitandthesameperiodcan'ttakeit(???)??Thediskunitandthesameperiodcan'ttakeit(???)??Diskfull软盘满Datanumberofadiskdoesn'tmatchup(???)??
29
相关下载 |
原标题:Lavinia 冬日灵感指南|暖系调色盘 色彩是一种视觉可见得生动语言, 在艺术中被誉为独立得抽象体 在时尚界被视为灵感得新趋势 如何用明媚多姿详情>>
历经延期及变更开发团队等不同事件的艺术家养成手机游戏新作《调色盘Parade(パレットパレード)》,于8月30日宣布游戏的正式推出日期将定为9月19日。官方亦详情>>
PS婚纱摄影后期调色修片写真修片攻略对象电脑一台步骤分解1打开素材,新建曲线调整图层;2盖印图层,转换为智能对象,调整Camera Raw滤镜;3再次盖印图层,转换为智能对象,调整滤镜,建立详情>>
Photoshop如何快速给风景照片调色!攻略对象电脑一台Photoshop软件步骤分解1将风景照片在PS中打开,Ctrl+J拷贝一层,选择滤镜—camera Raw滤镜( cs6版本在文件—打开为—选择camer详情>>
Photoshop调色教程之城市旅拍攻略对象电脑一台步骤分解1lightroom定调色温:因为要高饱和所以加了色温让整体暖些。2黑色色阶:降低黑色色阶让暗部沉的多一些(不要黑死)高光:降低高详情>>
PS夏日午后调色案例攻略对象电脑一台步骤分解1打开原片,执行调整图层/曲线,单击红色方框内的自动调整,用曲线适当调整画面的对比度2执行调整图层/色相/饱和度,编辑黄色,用带加号详情>>
教你用Photoshop制作怀旧复古调色攻略对象电脑一台Photoshop软件步骤分解1打开素材,复制图层。2把素材二置入进来,滤镜 高模糊,Crtl+T点击右键水平翻,图层混合模式改“滤色”。3详情>>
调色是指通过色阶、曲线、色相/饱和度、图层模板等工具将图片特定的色调加以改变,形成另一色调的图片的过程。 调色是图片处理中典型的问题之一,在实践中难以把握。很多Photos详情>>
Photoshop调色之LAB调色技术的秘密攻略对象电脑一台步骤分解1打开原片,执行图像—模式—LAB颜色,执行色阶命令,选择A通道2选择B通道,将黑色滑标适当向右移动,灰色和白色适当向左详情>>
Photoshop夜拍风景照片调色攻略对象电脑一台步骤分解1打开一张手机拍的夜景照片,并且复制一层2提高曝光度和对比度,但是会发现灯照部分严重过曝3降低高光属性来调整4降低清晰详情>>
Photoshop调色之人物多重曝光攻略对象电脑一台步骤分解1新建图层,背景设置为白色到浅蓝色的渐变,降低透明度,打开纹理素材,栅格化,混合模式更改为正片叠底,高斯模糊,新建色相饱和度详情>>
教你用Photoshop调色工具人物调色攻略对象电脑一台Photoshop软件步骤分解1执行文件,打开命令,将外部的一张图打开,继续执行打开命令,打开外部的一张人物素材图,使用选择工具,移动详情>>
教你用Photoshop模仿欧美复古胶片的调色过程攻略对象电脑一台Photoshop软件步骤分解1首先打开素材图,ctrl+j复制一层,并且转为智能对象2然后到ACR里操作,群里有童鞋还不是很清详情>>
Photoshop调色教程 给照片打造浓郁的电影画面感效果攻略对象电脑一台Photoshop软件步骤分解1拉入素材天空云彩,Ctrl+t拉大图片到合适位置,工具栏里选取【橡皮擦工具】透明度30详情>>
教你用Photoshop古典花卉调色攻略对象电脑一台步骤分解1首先打开素材,新建通道混合器调整层,分别调节红通道、蓝通道2新建色彩平衡调整层,选择中间调,参数如下,将其混合模式设置详情>>
snapseed是大家比较常用的一款手机修图工具,小伙伴可以通过该软件将拍摄的照片修的美美哒,很多朋友发现有些网红修的图片都非常的好看,那么他们是什么修的呢?snapseed网红调色教程其实这个也是非详情>>
相信大家在使用手机修图的时候都是使用的snapseed,这款软件在修图的时候真的非常的好用,被称之为手机行的PS,今天小编给大家带来的如何用snapseed做出日系风格的图片。snapseed日系调色详情>>
中文名称:无限试驾2发布日期:2011-02-10更新日期:--文件大小:--游戏语言:英文英文名称:TestDriveUnlimited2游戏制作:EdenStudios详情>>
无限试驾2调色工具补丁类型:游戏工具补丁语言:简体中文更新时间:2011/02/1209:55:04补丁大小:109.0KB游戏标签:赛车刺激挑战竞技GAP调色工具具体使用方法:1.详情>>
堡垒之夜木制调色板是什么?堡垒之夜调色板刷新点!堡垒之夜手游第七赛季第四周的任务是放3次烟花,那么烟花具体位置在哪里呢?一起来看看吧!第七赛季详情>>
当我们去旅游拍的很多图片,都是因为光的原因人物偏暗,那么我们如何来突出人物的特点,而不影响背景呢?今天小详情>>
火焰解说 我的世界 3578 调试调色器准备乱涂乱画详情>>
游戏内调色,小清新养眼色调,老硬币的噩梦调色详情>>
在调色方面,曲线简直可以说是万能的,它不仅可以调整图像的亮度,对比度,还可以调整图像的色彩,今天来分享“曲线”的调色方法。1.曲线面板:预设、通道、曲线。2.亮曲线:提亮图案。原图:调整后:详情>>
对于偏爱乡村爱情的我来说,古装剧始终没有勾起我一点的兴趣。《芈月传》、《宫锁心玉》、《三生三世十里桃花》......我都没看过。直到一眼瞄见《延禧攻略》,就被这个剧的色调吸引了,然后始于颜值、陷于剧详情>>
小编为您搜罗的答案:当然可以,只不过,木质的质地是有细缝的,用完之后及时洗干净也会在缝隙中留下一点颜料痕迹,但是不影响下次使用。就像是塑料的调色盘,使用时间长次数多洗的及时或者不及时,都会有淡淡的颜色详情>>
小编为您搜罗的答案:倒一点松节油在调色板上,抹开,再用刮刀,混着松节油刮结块的颜料层<br/>用松节油刮两三遍后,就可以清理干净了,<br/>再用报纸或写过字的宣纸擦干净&详情>>
小编为您搜罗的答案:湖边紫色梦幻婚纱美女写真,看起来原图不错,但是调成梦幻紫色也是非常入眼的,本教程的调色方法非常独特。基本上不需要什么调色工具,只需要把图片反相,然后再适当调整图层混合模式,即可得到详情>>
导读:最后一天了,卤煮愉快的玩起了发色,谨以此贴献给同样爱捏人的你们。一开始捏脸的时候发色实在调不好,但是又想有某灵那样混搭的发色,一直没去弄。卤煮捏... 详情>>
火焰解说 我的世界 4099 超强调色任何颜色详情>>
不知道大家有没有去看斯皮尔伯格导演的《头号玩家》这部电影?在朋友圈刷屏这部电影之后,我也是很关注这部电影,直到那天朋友@果然聪写了一篇头号玩家调色思路的文章,我发现这部电影的海报确实是很有“内容”。在详情>>
导读由SiliconStudio制作,预计于2018年夏季推出艺术家养成游戏《调色盘Parade(パレットパレ┼ド)》(iOS Android)3月7日开放事前登录!今日于官网公开游戏系统画面,新一详情>>