任天堂产品系统文件 Version 2.2 (Aug/11/2001) English-Source By Marat Fayzullin Chinese-Source By Charset charset@263.net 禁止对本文件的非授权分离。连接到本页,请勿拷贝。 下边的文本描述了“任天堂”产品游戏机的硬件属性(在韩国和日本被称为“Famicon”,在欧洲是“Dandy”。注意:本文本的结果主要的是从实验中来,或许在很多地方不完整或不正确。“Nintendo Entertainment System”,“Famicom”,“Dandy”以及“任天堂”是Nintendo公司的注册商标。 本文本还有Bero的日语版本。Guillaume Tuloup的法语版本。 我还想要感谢下面的人们,他们给我了很多的帮助,给我相关资料来写个NES的模拟器。下面是他们的名单(按字母排列): Pascal Felber Patrick Lesaard Tink Goroh Pan of Anthrox Bas Vijfwinkel Kawasedo Paul Robson Marcel de Kogel Serge Skorobogatov Alex Krasivsky John Stiles ______________________________________________________________________ 目录 ·讲些什么和不讲什么 ·总的结构 ·CPU Memory Map (中央处理器内存映像) ·PPU Memory Map (图形处理器内存映像) ·I/O Ports (输入/输出端口) ·Interrupts (中断) ·Joysticks (游戏控制器) ·PPU Memory (图形处理器内存) Acessing PPU Memory (存取图形处理器内存) Name Tables (名称表) Pattern Tables (模式表) Attribute Tables (属性表) Palettes (调色板) Sprites (动画/精灵) ·PPU Details (图形处理器细节) Mirroring (镜像) VBlank Flag (VBlank标志) Hit Flag (Hit标志) Accessing VRAM During Refresh(刷新时读取显示内存) Accessing PPU Status Register(存取图形处理器状态寄存器) Accessing PPU Data Register (存取图形处理器数据寄存器) ·Sprites (动画/精灵) ·Memory Mappers (记忆体映像) Sequential (连续的) Konami (柯那米) VROM Switch (只读显示选择) 5202 Chip (5202芯片) Others (其它) ·Sound (声音) ·Famicom Disk System(卡带系统) Memory Map (记忆体映像) IRQ Counter (可屏蔽中断计数器) Sound Hardware (声音硬件) Disk Format (卡带格式) Disk Access (卡带存取) Disk Errors (卡带错误) ·.NES File Format(*.nes文件格式) _____________________________________________________________________ What Is Covered And What Not? 本文本谈到了:Nes Memory Layout, I/O Ports, Video Controller (PPU), Sound Hardware, and the most videly used Memory Switching Circiuts (mappers). (主机记忆体设置,输入/输出端口,显示控制器,声音硬件,记忆体选择电路?) 6502处理器并没有包含在本文本中,因为在其他地方你可以得到很详细的信息。你只要知道6502是怎么工作的。 还没有包括的有:奇特的记忆体映像,Famicom DiskSystem,以及一些秘密的硬件块,因为我没有足够的资料。如果你还有其他没有在本文本里的“任天堂”的信息,请写给 fms@cs.umd.edu。我将感激你的帮助。 在本文本里,你将遇到如下形式的符号:"Nth bit" (5th, 3rd,etc.)。位是按从最低位(0th)到最高位(7th)。 所有的十六进制都在前面加上一个美圆符号($)($2002,$4026,etc.)是 在6502处理器汇编里常用的符号。 ____________________________________________________________________ General Architecture 任天堂主机由6502处理器和一个自定义的显示控制器(PPU-Picture Processing Unit)。PPU的显存是和主处理器的内存分离的,可以通过对特殊端口的读/写来操作。 卡带可能包含在处理器地址的$8000-$FFFF的ROM,还可能是PPU地址$0000-$1FFF的VROM或VRAM。 在更小的卡带,比如只有16KB的ROM,它占有$C000-$FFFF,而$8000-$BFFF的空间是不用的。那些大于32KB的卡带,它被特殊的电路(?)分页到一定的地址空间。(查看"Mappers")一些卡带在$6000-$7FFF有RAM,那是可能或没有电池存储。 卡带VROM(VRAM)被用来做模式表(aka Tile Tables, Character Generators, etc.)。通常的数量是8KB,包含两个模式表。大于8KB 的VROM(VRAM),它被特殊的电路分页到一定的地址空间。(查看"Mappers") 内部的任天堂VRAM在PPU 内存里定位于$2000-$3FFF,它用来存储名字表(aka Screen Buffers, etc.屏幕缓冲)。虽然PPU 支持4个名字表,但只能支持两个的存放空间。另外的两个由开始的两个所镜像。 __________________________________________________________________________ CPU Memory Map --------------------------------------- $10000 Upper Bank of Cartridge ROM 卡带的上层ROM --------------------------------------- $C000 Lower Bank of Cartridge ROM 卡带的下层ROM --------------------------------------- $8000 Cartridge RAM (may be battery-backed) 卡带的RAM(可能有电池支持) --------------------------------------- $6000 Expansion Modules 扩充的模块 --------------------------------------- $5000 Input/Output 输入/输出 --------------------------------------- $2000 2kB Internal RAM, mirrored 4 times 2KB的内部RAM,做4次镜象 --------------------------------------- $0000 _________________________________________________________________________________ PPU Memory Map --------------------------------------- $4000 Empty 空 --------------------------------------- $3F20 Sprite Palette 动画/精灵调色板 --------------------------------------- $3F10 Image Palette 图象调色板 --------------------------------------- $3F00 Empty 空 --------------------------------------- $3000 Attribute Table 3 属性表3 --------------------------------------- $2FC0 Name Table 3 (32x30 tiles) 名字表3(32X30块) --------------------------------------- $2C00 Attribute Table 2 属性表2 --------------------------------------- $2BC0 Name Table 2 (32x30 tiles) 名字表2(32X30块) --------------------------------------- $2800 Attribute Table 1 属性表1 --------------------------------------- $27C0 Name Table 1 (32x30 tiles) 名字表1(32X30块) --------------------------------------- $2400 Attribute Table 0 属性表0 --------------------------------------- $23C0 Name Table 0 (32x30 tiles) 名字表0(32X30块) --------------------------------------- $2000 Pattern Table 1 (256x2x8, may be VROM) 调色板表1(256X2X8,可能是VROM) --------------------------------------- $1000 Pattern Table 0 (256x2x8, may be VROM) 调色板表0(256X2X8,可能是VROM) --------------------------------------- $0000 __________________________________________________________________________ I/O Ports 任天堂主机内部输入/输出端口映像于$2000-$2007和$4000-$4017。一些端口的用处是未明的或未知的。任何有关信息将受到感激。 ------+-----+--------------------------------------------------------------- $2000 | RW | PPU Control Register 1 | 0-1 | Name Table Address: | | | | +-----------+-----------+ | | | 2 ($2800) | 3 ($2C00) | | | +-----------+-----------+ | | | 0 ($2000) | 1 ($2400) | | | +-----------+-----------+ | | | | Remember that because of the mirroring there are only 2 | | real Name Tables, not 4. Also, PPU will automatically | | switch to another Name Table when running off the current | | Name Table during scroll (see picture above). | 2 | Vertical Write, 1 = PPU memory address increments by 32: | | | | Name Table, VW=0 Name Table, VW=1 | | +----------------+ +----------------+ | | |----> write | | | write | | | | | | V | | | | 3 | Sprite Pattern Table Address, 1 = $1000, 0 = $0000. | 4 | Screen Pattern Table Address, 1 = $1000, 0 = $0000. | 5 | Sprite Size, 1 = 8x16, 0 = 8x8. | 6 | PPU Master/Slave Mode, not used in NES. | 7 | VBlank Enable, 1 = generate interrupts on VBlank. ------+-----+--------------------------------------------------------------- $2001 | RW | PPU Control Register 2 | 0 | Unknown (???) | 1 | Image Mask, 0 = don't show left 8 columns of the screen. | 2 | Sprite Mask, 0 = don't show sprites in left 8 columns. | 3 | Screen Enable, 1 = show picture, 0 = blank screen. | 4 | Sprites Enable, 1 = show sprites, 0 = hide sprites. | 5-7 | Background Color, 0 = black, 1 = blue, 2 = green, 4 = red. | | Do not use any other numbers as you may damage PPU hardware. ------+-----+--------------------------------------------------------------- $2002 | R | PPU Status Register | 0-5 | Unknown (???) | 6 | Hit Flag, 1 = Sprite refresh has hit sprite #0. | | This flag resets to 0 when screen refresh starts | | (see "PPU Details"). | 7 | VBlank Flag, 1 = PPU is in VBlank state. | | This flag resets to 0 when VBlank ends or CPU reads $2002 | | (see "PPU Details"). ------+-----+--------------------------------------------------------------- $2003 | W | Sprite Memory Address | | Used to set the address of the 256-byte Sprite Memory to be | | accessed via $2004. This address will increment by 1 after | | each access to $2004. Sprite Memory contains coordinates, | | colors, and other sprite attributes (see "Sprites"). ------+-----+--------------------------------------------------------------- $2004 | RW | Sprite Memory Data | | Used to read/write the Sprite Memory. The address is set via | | $2003 and increments by 1 after each access. Sprite Memory | | contains coordinates, colors, and other sprite attributes | | sprites (see "Sprites"). ------+-----+--------------------------------------------------------------- $2005 | W | Screen Scroll Offsets | | There are two scroll registers, vertical and horizontal, | | which are both written via this port. The first value written | | will go into the Vertical Scroll Register (unless it is >239, | | then it will be ignored). The second value will appear in the | | Horizontal Scroll Register. Name Tables are assumed to be | | arranged in the following way: | | | | +-----------+-----------+ | | | 2 ($2800) | 3 ($2C00) | | | +-----------+-----------+ | | | 0 ($2000) | 1 ($2400) | | | +-----------+-----------+ | | | | When scrolled, the picture may span over several Name Tables. | | Remember that because of the mirroring there are only 2 real | | Name Tables, not 4. ------+-----+--------------------------------------------------------------- $2006 | W | PPU Memory Address | | Used to set the address of PPU Memory to be accessed via | | $2007. The first write to this register will set 8 lower | | address bits. The second write will set 6 upper bits. The | | address will increment either by 1 or by 32 after each | | access to $2007 (see "PPU Memory"). ------+-----+--------------------------------------------------------------- $2007 | RW | PPU Memory Data | | Used to read/write the PPU Memory. The address is set via | | $2006 and increments after each access, either by 1 or by 32 | | (see "PPU Memory"). ------+-----+--------------------------------------------------------------- $4000-$4013 | Sound Registers | See "Sound". ------+-----+--------------------------------------------------------------- $4014 | W | DMA Access to the Sprite Memory | | Writing a value N into this port causes an area of CPU memory | | at address $100*N to be transferred into the Sprite Memory. ------+-----+--------------------------------------------------------------- $4015 | W | Sound Channel Switch | 0 | Channel 1, 1 = enable sound. | 1 | Channel 2, 1 = enable sound. | 2 | Channel 3, 1 = enable sound. | 3 | Channel 4, 1 = enable sound. | 4 | Channel 5, 1 = enable sound. | 5-7 | Unused (???) ------+-----+--------------------------------------------------------------- $4016 | RW | Joystick1 + Strobe | 0 | Joystick1 Data (see "Joysticks). | 1 | Joystick1 Presence, 0 = connected. | 2-5 | Unused, set to 000 (???) | 6-7 | Unknown, set to 10 (???) ------+-----+--------------------------------------------------------------- $4017 | RW | Joystick2 + Strobe | 0 | Joystick2 Data (see "Joysticks). | 1 | Joystick2 Presence, 0 = connected. | 2-5 | Unused, set to 000 (???) | 6-7 | Unknown, set to 10 (???) ------+-----+--------------------------------------------------------------- ____________________________________________________________________________ Interrupts 任天堂主机使用不可屏蔽中断(NMI),它产生于PPU的每一帧结束(叫VBlank中断,垂直空白中断(?))。垂直空白中断可以由$2000的第7位的1/0控制允许/禁止。 当一个垂直空白中断发生时,CPU把返回地址和状态寄存器压栈,然后跳转到存储在$FFFA(NES的ROM)的地址。 中断句柄用于支持完成RTI命令的执行。RTI让CPU返回到程序的执行。在一本象样的6502处理器书上可以找到更多中断句柄的信息。 可屏蔽中断(IRQ)可以由卡带的外部电路产生(看"Mappers"),但大多数卡带并不产生它们。 __________________________________________________________________________________ Joysticks 两个任天堂的游戏棒可以通过$4016和$4017存取。为了复位游戏棒,先在$4016写$01,然后是$00。这将在游戏棒的电路里发生个闪光(??)。然后可以在$4016(Joystick#0)或$4017(Joystick#1)读取了。每次必然的(??)读取将返回一个单一的按钮在第0位的状态(1表示按下,0表没有)。 Read # | 1 2 3 4 5 6 7 8 -------+--------------------------------------------------------- Button | A B SELECT START UP DOWN LEFT RIGHT 第一位表示了游戏棒是否和端口连接。如果连接就置0,否则是1。第6和7位的$4016/$4017看起来有相同的重要性。复位的位返回0。有些游戏期望当一个按钮按下的时候在$4016/$4017得到$41。 _____________________________________________________________________________________ PPU Memory 1.Accessing PPU Memory 在一个任天堂主机,读/写PPU内存只可以在“显示空白”期间。当在屏幕刷新时存取时回破坏刷新地址寄存器,一般它经常用来做隐含的“分割屏幕”效果(看"PPU Details")。 很多小些的ROM有只读存储体(VROM)用做模式表。在这种情况下,你不可以写PPU地址,只可以读。 Writing to PPU memory: a) Write upper address byte into $2006 b) Write lower address byte into $2006 c) Write data into $2007. After each write, the address will increment either by 1 (bit 2 of $2000 is 0) or by 32 (bit 2 of $2000 is 1). Reading from PPU memory: a) Write upper address byte into $2006 b) Write lower address byte into $2006 c) Read data from $2007. The first byte read from $2007 will be invalid (see "PPU Details"). Then, the address will increment by 1 after each read. 2.Name Tables PPU支持4个名字表,他们在$2000,$2400,$2800,$2C00。一个名字表和字符模式下的屏幕缓冲比较相象。它包含字符的代码,也就是30列的32Byte长度。一个块有8X8象素。所以,一个完全的名字表有32X30块,也就是256X240象素。在NTSC制式下,上面和下面的8象素通常不显示出来,只有256X224象素。在PAL制式下,屏幕有256X240象素。 需要说的是,虽然PPU支持4个名字表,任天堂主机只支持2个名字表。另外两个被做了镜像。 3.Pattern Tables PPU支持两个模式表在$0000和$1000。一个模式表包含了块图象(模式块),他们有以下格式。 Character Colors Contents of Pattern Table ...*.... 00010000 00010000 $10 +-> 00000000 $00 ..O.O... 00202000 00000000 $00 | 00101000 $28 .#...#.. 03000300 01000100 $44 | 01000100 $44 O.....O. 20000020 00000000 $00 | 10000010 $82 *******. -> 11111110 -> 11111110 $FE | 00000000 $00 O.....O. 20000020 00000000 $00 | 10000010 $82 #.....#. 30000030 10000010 $82 | 10000010 $82 ........ 00000000 00000000 $00 | 00000000 $00 +---------+ 注意在模式表里存储的是每个块的2个字节。其他两个由属性表得到。所以,在屏幕上总体出现的颜色数是16,而每个块里只有4种颜色。 4.Attribute Tables 每个名字表有它自己的属性表。一个在表里的字节代表在屏幕上的一组4X4的块,一共有8X8个属性表。每个4X4块组又被细分为2X2如下方块。 (0,0) (1,0) 0| (2,0) (3,0) 1 (0,1) (1,1) | (2,1) (3,1) --------------+---------------- (0,2) (1,2) 2| (2,2) (3,2) 3 (0,3) (1,3) | (2,3) (3,3) 属性字节包含每个2X2方块的颜色号的上面2位(下面的2位存储在模式表里)。 Bits Function Tiles -------------------------------------------------------------- 7,6 Upper color bits for square 3 (2,2),(3,2),(2,3),(3,3) 5,4 Upper color bits for square 2 (0,2),(1,2),(0,3),(1,3) 3,2 Upper color bits for square 1 (2,0),(3,0),(2,1),(3,1) 1,0 Upper color bits for square 0 (0,0),(1,0),(0,1),(1,1) 5.Palettes 一共有2个16-字节调色板。一个在$3F00用于图片。另一个在$3F10,包括动画/精灵颜色。$3F00和$3F10在VRAM里镜像了对方(??),并定义了图片的背景颜色。 _____________________________________________________________________________________ PPU Details 就象你注意到的,PPU支持4个名字表和与之相应的属性表。然而VRAM只有2个名字表的空间。另外的两个表将是头两个的镜像。 哪个页面要被做镜像由卡带的电路所决定。每个卡带都控制着PPU地址的位A10 和A11(??)。它可能将他们设置成以下4种可能的方式的1种。 A11 A10 Effect ---------------------------------------------------------- 0 0 All four screen buffers are mapped to the same area of memory which repeats at $2000, $2400, $2800, and $2C00. 0 x "Upper" and "lower" screen buffers are mapped to separate areas of memory at $2000, $2400 and $2800, $2C00. x 0 "Left" and "right" screen buffers are mapped to separate areas of memory at $2000, $2800 and $2400,$2C00. x x All four screen buffers are mapped to separate areas of memory. In this case, the cartridge must contain 2kB of additional VRAM. 2.VBlank Flag 垂直空白标志包含PPU状态寄存器的第7位($2002)。它代表着PPU是否在刷新屏幕或者说发生了垂直空白。它从每一帧的末尾持续到下一帧屏幕刷新开始。当垂直空白标志存在时,你就可以通过$2006/$2007存取PPU内存。程序可以通过读PPU状态寄存器($2002)过早的复位垂直空白标志。 3.Hit Flag Hit标志是PPU状态寄存器($2002)的第6位。它从PPU开始显示0号动画/精灵和它的第一个非透明象素和第一个背景的非透明象素一致。比如,屏幕的背景是一个非透明颜色(>0),0号精灵的坐标是(12,34),它只是在第4行的开始才有象素,那么,Hit 标志在屏幕刷新到(12,37)时才被设置。 Hit标志可以在水平或者垂直屏幕分割的时候,还可以有许多好玩的效果。它不可以通过读PPU的状态来复位。它只是在每次PPU开始刷新屏幕时复位。 4.Accessing VRAM During Refresh 前面说过,在屏幕刷新的时候存取VRAM的地址和数据是不合法的。许多程序存取这些寄存器来制造不同的滚动效果。比如,一些游戏从屏幕底部开始滚动,那么它可能向$2006写第一行的状态来复位屏幕滚动。 比上面的诡计好的一个主意是PPU在屏幕刷新时用VRAM的地址寄存器来储存当前地址。通过向$2006修改地址以及让PPU从一个不同的地方接着刷新。关于$2007如何影响屏幕刷新仍不了解。 当不知道向$2006中写什么数据时,看下面的图表。 Address Written into $2006 xxYYSSYYYYYXXXXX | | | | | | | +---- Horizontal scroll in tiles (i.e. 1 = 8 pixels) | | +--------- Vertical scroll in tiles (i.e. 1 = 8 pixels) | +------------ Number of Name Table ($2000,$2400,$2800,$2C00) +-------------- Additional vertical scroll in pixels (0..3) 5.Accessing PPU Status Register To be written 6.Accessing PPU Data Register To be written ______________________________________________________________________________ Sprites 一共可以有64个动画/精灵,它们可以是8X8或8X16象素。动画/精灵模式被存储在PPU内存的模式表的其中一个里。动画/精灵属性被储存在一个特殊的256字节的动画/精灵内存,它不是CPU或PPU的地址的一部分。整个动画/精灵内存可以通过$4014的DMA方式来写。它可以通过把开始地址放在$2003然后读/写于$2004(每次存取地址自动加一),它是一个一个字节存取的。动画/精灵的属性格式是: Sprite Attribute RAM: | Sprite#0 | Sprite#1 | ... | Sprite#62 | Sprite#63 | | | +---- 4 bytes: 0: Y position of the left-top corner - 1 1: Sprite pattern number 2: Color and attributes: bits 1,0: two upper bits of color bits 2,3,4: Unknown (???) bit 5: if 1, display sprite behind background bit 6: if 1, flip sprite horizontally bit 7: if 1, flip sprite vertically 3: X position of the left-top corner 动画/精灵模式可以象块模式对于背景图片一样抓取。唯一的不同是在8X16的动画/精灵时,上半部分由动画/精灵模式表的$0000开始,而下半部分由$1000开始。 __________________________________________________________________________________ Memory Mappers 有很多不同的记忆体映像(MMC)用于任天堂的卡带中。它们要区分ROM和VROM页面。我将要试着区分所有所知的MMC。任何有用的将得到我的感激。MMC数目在 .NES File Format 中有详细说明。 To be written __________________________________________________________________________________ Sound To be written __________________________________________________________________________________ Famicom Disk System 任天堂家庭机卡带系统(FDS) 是它的扩展单位,它只是由任天堂公司生产以及只在亚洲国家销售。它由一个软盘驱动器可以插2.5寸软盘,可以以32KB的RAM(代替了ROM)来读进程序。8KB的VRAM(代替了VROM),其他的硬件描述于下。 1.Memory Map FDS的地址空间的描述 --------------------------------------- $10000 8kB FDS BIOS ROM --------------------------------------- $E000 32kB Program RAM --------------------------------------- $6000 Expansion Modules --------------------------------------- $5000 Input/Output --------------------------------------- $2000 2kB Internal RAM, mirrored 4 times --------------------------------------- $0000 FDS还增加了一些I/O端口于$4000-$40FF来控制磁盘系统,声音系统,IRQ记数器。 ------+-----+--------------------------------------------------------------- $4020 | W | Lower Byte of IRQ Counter ------+-----+--------------------------------------------------------------- $4021 | W | Upper Byte of IRQ Counter ------+-----+--------------------------------------------------------------- $4022 | W | Enable/Disable IRQs | 2 | \ = Stop IRQ counter and reset its interrupt request. | | / = Load IRQ counter with a value from $4020-$4021 and | | start it. ------+-----+--------------------------------------------------------------- $4024 | W | Data Write Register | | To write data to the disk, output it into this register. ------+-----+--------------------------------------------------------------- $4025 | W | Control Register | 0 | Drive Motor, 0 = on, 1 = off. | 1 | \ = Set drive head to the start of the first track. | 2 | Disk Write, 0 = enabled, 1 = disabled. | 3 | Screen Mirroring, 0 = vertical, 1 = horizontal. | 4-6 | Unknown (???) | 7 | Disk IRQs, 0 = disabled, 1 = enabled. ------+-----+--------------------------------------------------------------- $4026 | W | ExPort Output (???) ------+-----+--------------------------------------------------------------- $4030 | R | Disk Status Register 0 | 4 | Unknown (???) | 6 | Unknown (???) ------+-----+--------------------------------------------------------------- $4031 | R | Data Read Register | | To read data from the disk, input it from this register. ------+-----+--------------------------------------------------------------- $4032 | R | Disk Status Register 1 | 0 | Disk Presence, 0 = inserted, 1 = not inserted. | 1 | Disk Ready, 0 = ready, 1 = not ready. | 2 | Write Protection, 0 = unprotected, 1 = protected. ------+-----+--------------------------------------------------------------- $4033 | R | ExPort Input | 7 | Battery Status, 0 = ok, 1 = low. ------+-----+--------------------------------------------------------------- 2.IRQ Counter FDS提供了一个16位的IRQ记数器连接到CPU时钟发生器。计数器开始于你写在$4021的一个预设在$4020-$4021的值。它在每个CPU时钟周期后减一。当计数器为零时,它从预设的值开始继续计数。这时就发生了一个IRQ。当垂直空白时,屏幕刷新时也会发生。$4022的第2个位用来控制IRQ计数器。当它是0,那么记数停止,要到达的IRQ被复位(如果有的话)。设置了1后,记数可以被恢复。 3.Sound Hardware To be written 4.Disk Format 每个磁盘有两面,A 和 B,每面可以有65000字节的数据。要反转一个当前面,必须先拿出来,反转,重新插回去。数据在每个面上被储存于一系列的不同类型的块[1,2,3,4,3,4,...,3,4]。 ------------------------------------------------------ 1. Side Header Block (56 bytes) 0 $01 1-14 "*NINTENDO-HVC*" 15 Maker ID 16-19 Side Name 20 Version Number 21 Side Number $00 = Side A $01 = Side B 22-24 Additional Disk Data 25 $08 26-56 Reserved Space (not used by BIOS) ------------------------------------------------------ 2. File Number Block (2 bytes) 0 $02 1 Number of Files on this side ------------------------------------------------------ 3. File Header Block (16 bytes) 0 $03 1-2 File Number (not used by BIOS?) 3-10 File Name (not used by BIOS?) 11-12 Starting Address in memory 13-14 File Size 15 File Type $00 = Program Data $01 = Character Data $02 = Screen Data ------------------------------------------------------ 4. File Data Block (variable length) 0 $04 1-... Data (see File Header Block for size) ------------------------------------------------------ 所以两字节地方都以最重要的字节开始。面的名称可能和相同游戏软盘的不同面不同,但它们是一样的。(??)开始的地址在RAM和VRAM都是实在的地址,当文件被读取。 5.Disk Access 下面的图表显示了FDS如何从软盘中读/写。图表是Goroh 在他的FDS硬件文件里描述的。我做了下小修饰,由Goroh获得荣誉。 READ: $4025| A | B | C | D || E | A) Initialization 7bit |___|______|___|---||------___| B) Motor on 6bit |___|______|---|---||------___| C) Read start mark 5bit |---|------|---|---||---------| D) Enable IRQs 4bit |___|______|___|___||___---___| E) Read end mark 2bit |---|------|---|---||---------| 1. Read data, ($4030)=[xx0xxxxx] 1bit |---|---___|___|___||_________| 2. Read data, ($4030)=[xxx0xxxx] 0bit |___|------|---|---||------___| Note | | | | || 1 2 | WRITE: $4025| A | B | C | D || E | A) Initialization 7bit |___|______|______|---||------___| B) Motor on 6bit |___|______|___---|---||------___| C) Write start mark 5bit |---|------|------|---||---------| D) Enable IRQs 4bit |___|______|______|___||___---___| E) Write end mark 2bit |---|------|______|___||______---| 1. Delay, write [00000000] 1bit |---|---___|______|___||_________| 2. Write [10000000] 0bit |___|------|------|---||------___| 3. Write data, ($4030)=[xx0xxxxx] Note | | | 1 | 2 || 3 4 | 4. Delay 对于读写是如何完成的并不清楚。虽然知道FDS每当一个字节从软盘里读出的时候就发生一个IRQ。FDS的IRQ处理器(是FDS的BIOS一部分)在$4031读取这个字节,然后指针指向下个字节。 6.Disk Errors 下面时软盘错误的信息,打问号的是我不明白的。图表是从Goroh的文件来。 ERR.01 No disk 没有软盘 ERR.02 No power 没有电源 ERR.03 Broken prong on the disk ?? ERR.04 Wrong maker ID ?? ERR.05 Wrong game name 不正确的游戏名字 ERR.06 Wrong game version 不正确的游戏版本 ERR.07 Wrong side number (flip the disk) 不正确的盘面(反转之) ERR.08 Wrong disk #1 一号软盘错 ERR.09 Wrong disk #2 二号软盘错 ERR.10 Wrong disk #3 三号软盘错 ERR.20 Allows it to recognize screen data differs (???) ?? ERR.21 Wrong Side Header Block ("*NINTENDO-HVC*") 不正确的盘面柱头块 ERR.22 Wrong Side Header Block ID ($01) 不正确的盘面柱头块号 ERR.23 Wrong File Number Block ID ($02) 不正确的文件块号 ERR.24 Wrong File Header Block ID ($03) 不正确的文件头块号 ERR.25 Wrong File Data Block ID ($04) 不正确的文件数据块号 ERR.26 Error writing data to the disk 写文件错 ERR.27 Block ends prematurely 块过早结束 ERR.28 The disk unit and the same period can't take it (???) ?? ERR.29 The disk unit and the same period can't take it (???) ?? ERR.30 Disk full 软盘满 ERR.31 Data number of a disk doesn't match up (???) ?? ______________________________________________________________________________________ .NES File Format .NES文件为模拟用来储存NES卡带镜像。.NES首先由我Marat Fayzullin得到,在iNES以及其他模拟器的作者采纳。它已经作为储存NES ROM镜像的非正式标准。下面是一个.NES文件的结构。 Byte Contents --------------------------------------------------------------------------- 0-3 String "NES^Z" used to recognize .NES files. 4 Number of 16kB ROM banks. 5 Number of 8kB VROM banks. 6 bit 0 1 for vertical mirroring, 0 for horizontal mirroring bit 1 1 for battery-backed RAM at $6000-$7FFF bit 2 1 for a 512-byte trainer at $7000-$71FF bit 3 1 for a four-screen VRAM layout bit 4-7 Four lower bits of ROM Mapper Type. 7 bit 0-3 Reserved, must be zeroes! bit 4-7 Four higher bits of ROM Mapper Type. 8-15 Reserved, must be zeroes! 16-... ROM banks, in ascending order. If a trainer is present, its 512 bytes precede the ROM bank contents. ...-EOF VROM banks, in ascending order. --------------------------------------------------------------------------- 注意:这个结构以后很可能扩展。所以不要以之做长久的打算。新的扩展都要保证和旧的版本相适应。 8位的镜像可以给我们一共256种可能的镜像类型。如果你发现了一种新的镜像类型,请Email我,告诉它的说明和它的一些标本ROM。我会定位一个新的位置和声明新的数字。不要自己做这个数字,那会搞的一团糟。 下面是可信的一个镜像的类型表。画“-”符号的是iNES不可以很好支持的。 Mapper# Name Examples --------------------------------------------------------------------------- 0 No mapper All 32kB ROM + 8kB VROM games 1 Nintendo MMC1 Megaman2, Bomberman2, etc. 2 Simple ROM switch Castlevania, LifeForce, many games hacked for use with FFE copier 3 Simple VROM switch QBert, PipeDream, Cybernoid, many Japanese games 4 Nintendo MMC3 SilverSurfer, SuperContra, Immortal, etc. 5 Nintendo MMC5 Castlevania3 6 FFE F4xxx F4xxx games off FFE CDROM 7 32kB ROM switch WizardsAndWarriors, Solstice, etc. 8 FFE F3xxx F3xxx games off FFE CDROM 9 - Nintendo MMC2 Punchout 10 Nintendo MMC4 Punchout2 11 ColorDreams chip CrystalMines, TaginDragon, etc. 12 - FFE F6xxx F6xxx games off FFE CDROM 15 100-in-1 switch 100-in-1 cartridge 16 Bandai chip Japanese DragonBallZ series, etc. 17 FFE F8xxx F8xxx games off FFE CDROM 18 Jaleco SS8806 chip Japanese Baseball3, etc. 19 Namcot 106 chip Japanese GhostHouse2, Baseball90, etc. 20 Nintendo DiskSystem Reserved. Don't use this mapper! 21 Konami VRC4 Japanese WaiWaiWorld2, etc. 22 Konami VRC2 (a) Japanese TwinBee3 23 Konami VRC2 (b) Japanese WaiWaiWorld, MoonWindLegend, etc. 24 - Konami VRC6 ??? 32 Irem G-101 chip Japanese ImageFight, etc. 33 Taito TC0190/TC0350 Japanese PowerBlazer 34 32kB ROM switch ImpossibleMission2 and DeadlyTowers --------------------------------------------------------------------------- ?1996-1998 Copyright by Marat Fayzullin [fms@cs.umd.edu] Translator: Wu Jian [charset@263.net] Some of the Document is still not translated. Because I think they are too eazy. All the tables are not translated. Becaust I think that All Chinese can get them through. I am now writting a NES Emulator. But I met problems ... I do not know where to start. Because I want to make it in VB. It really is a mad thought, isn't it? But I really want to ... Thanks. This Page is translated by Wu Jian [charset@263.net]. THIS PAGE CAN BE VIEWED ONLY IN CHINESE-SIMPLEFIED SYSTEMS. IF YOU CAN NOT VIEW THEM PROPERLY, INSTALL CHINESE-SIMPLEFIED WITHIN YOUR InternetExplorer.