Nov
11
2009

每个成功男人的背后,都有一个成功的女人

1
Oct
18
2009

十多年前的一首歌《壮志飞扬》

很奇怪,为什么我对以前的事情记忆这么好。这歌的歌词和旋律我丝毫也没忘记。

壮志飞扬
(记忆中这首歌应该是由林依轮和解晓东合唱的)

借风雷射透千年朱廊玉榭
论英雄气节 儿女情暂别
江河乍裂 万马惊破一天残月
扫尽乱云重叠 何惜一腔热血
但愿人间从此硝烟绝

且让那些如烟岁月
丈量古今谁是真豪杰
人生无非相聚离别
却要揭开一帘明月

我上三山五岳 指点清平世界
踏千层云海 举手与天接
我上三山五岳 指点清平世界
踏千层云海 举手与天接
平生悲欢都了却
壮志飞扬豪情正激越

1
Mar
11
2008

我不相信

原来,她正在试图改变自己.

为什么?

我真得不相信她会这样对我.或许,只有在孤独的时候,她才会想起我.也许只有在她自己周围没有其它朋友的时候,她才会回味我们相处的日子.

但我真的感觉到我很失败.什么都没有了,我的爱情,我的工作,我的代码,我的事业,我的勇气,我的决心,我的自信,我的一切,全没有了.一件件地,我亲眼看着它们消失了.

1
Feb
28
2008

淡水河边的烟火

静静地听着这熟悉的音乐,静静地等待着黎明的到来,静静地感受着仍然在挣扎的寒冷,我仿佛回到了曾经相似的昨天。夜很静,夜很冷,但夜即将过去。

淡水河边的烟火

看过了一场 精彩的烟火表演
我捕捉到你难得一见的笑靥
突然间忘记 这是一个分手的夜
在这熙来攘往热闹的淡水河边
从此不再相见 不再相见
你善变的脸像烟火
只有短短的一瞬间 一瞬间

看过了一场 精彩的烟火表演
我接受了你毫不眷恋的告别
突然间想起 你曾经许下的诺言
在这熙来攘往热闹的淡水河边
从此不再相见 不再相见
你说谎的眼像烟火
只有短短的一瞬间 一瞬间

今年这一场 精彩的烟火表演
我孤孤单单只有一个人
而现在的你 有谁陪在身边
在这熙来攘往热闹的淡水河边

0
Feb
26
2008

游戏人间

久违的声音,久违的心情,当再次走进郑智化歌迷联盟的时候,我发觉自己已经在那儿呆了7年了。

有一个卡啦OK伴奏,说是CD原版音质,我下载了下来,结果让我失望,原来还是那个REAL提取来的,还不如我自己处理过的完善。不过,听了一遍,果然却让我找到了久违的伤感。

============================

游戏人间   郑智化

——————————————

世界太啰嗦,不分对或错
像我这样的老百姓,谁会在乎我
有钱的当老大,没钱的难过活
就算是看不惯,我又能如何

爱人离开我,不说为什么
伤心难过的时候,我学会了喝酒
每次我都喝醉,还从来不犯错
明天酒醒以后,我依然是我

笑容太甜,泪水太咸
山盟海誓到了最后难免会变
烦恼太多,未来太远
何不陪我一起放荡游戏人间

 

日子怎么过,快乐不快乐
像这种无聊的问题,你不要问我
该来的会来,该走的会走
反正都是没把握,不必太强求

我有我的痛,我有我的梦
装疯卖傻的时候,你不要笑我
也许有一天,你我再相逢
睁开眼睛看清楚,我才是英雄

笑容太甜,泪水太咸
山盟海誓到了最后难免会变
烦恼太多,未来太远
何不陪我一起放荡游戏人间

 

酸甜苦辣尝过,人情冷暖看破
江湖的路上,我身不由己
是是非非抛开,恩恩怨怨不再
自由自在,我浪迹天涯

笑容太甜,泪水太咸
山盟海誓到了最后难免会变
烦恼太多,未来太远
何不陪我一起放荡游戏人间

笑容太甜,泪水太咸
山盟海誓到了最后难免会变
烦恼太多,未来太远
何不陪我一起放荡游戏人间

============================

完完整整的三段,一字一字打出来,眼睛再一次被它浸湿。

为什么世界还是如此。这首“不健康”的歌曲,我最喜欢听的歌曲,为什么一直还没有成为往事,还在活生生地描绘着当今的世界?

我会郁郁而终吗?真的会吗?我不快乐了吗?我的快乐哪里去了?我好怕……

0
Feb
26
2008

昨天做了件伟大的事

我的朋友要和老婆离婚,或者说,我一个最近几年才认识的朋友要和她老公离婚,被我劝好了。

没有交流和沟通的感情实在太可怕了,就好比僵尸一样,没有目的地“生活”,甚至“向往”黑暗。

清官难断家务事。我一个还没有结婚的小子,插手这件事做什么?我算老几?我有资格吗?

所以说,我犯了大忌。

他们都是我的朋友。既然走到一起,说明他们还是有“共同语言”的。在婚前他们生活了几年,从来没有吵到要分手。既然决定结婚,那说明他们之间肯定没有多么严重的不可容忍。婚后仅两三年,就要离婚,这又说明了一些问题。比如家庭环境,比如为人处事,比如感情疲惫,等等。他们吵架原来也都是因为小事。既然是小事,闹到离婚,对于一段经历了这么多年风吹雨打的感情来说,这种结局是多么的荒唐、多么的残酷、多么的让人惋惜。我不能看到这种事情的发生。我必须阻止他们做出令人难过的决定。我必须让他们看到事实的真相——他们在为了可怕的世界而改变对对方的态度,他们在为了可怕的环境而改变对对方的感情,他们甚至正在慢慢地走向对感情麻木的深渊。我必须挽救我的两个朋友,让他们不要盲目地纵身一跃——走向无比的黑暗和无尽的悔恨。

我犯了大忌,但为了我的两个朋友,值得。

我成功了。或许只是一时的成功。但我想,他们如果真正能互相搀扶,那么这个成功就是永恒的。

然而,明天的明天的明天,我和爱人吵到要离婚的时候,谁来劝我们呢?

 

幻灭的女神

 

我多么迷恋的 多么迷恋的
你的一颦一笑一动一摆
你那么遥远的 那么遥远的
我的一分一秒一生一世

为你而企盼 为你而绝望
为你笑 为你哭 为你愁
幻灭的女神 幻灭的女神
留在梦中别轻易离开我

为你而绽放 为你而凋落
为你生 为你活 为你死
幻灭的女神 幻灭的女神
留在梦中别轻易离开我

 

我多么迷恋的 多么迷恋的
你的一颦一笑一动一摆
你那么遥远的 那么遥远的
我的一分一秒一生一世

为你而企盼 为你而绝望
为你笑 为你哭 为你愁
幻灭的女神 幻灭的女神
留在梦中别轻易离开我

为你而绽放 为你而凋落
为你生 为你活 为你死
幻灭的女神 幻灭的女神
留在梦中别轻易离开我

 

为你而企盼 为你而绝望
为你笑 为你哭 为你愁
幻灭的女神 幻灭的女神
留在梦中别轻易离开我

为你而绽放 为你而凋落
为你生 为你活 为你死
幻灭的女神 幻灭的女神
留在梦中别轻易离开我

0
Sep
02
2005

PS模拟器设置过程.

0
Apr
30
2005

任天堂红白机 ( NES ) 文档

+—————————+
| 任天堂红白机 ( NES ) 文档 |
| 版本.2.00                 |
+—————————+

+——+
| 目录 |
+——+
 1. 说明
   A. 弃权声明
   B. 为什么?
   C. 任务
   D. 献给
   E. 鸣谢
 2. Acronymns
   A. 内部
   B. 硬件
 3. CPU
   A. 一般信息
   B. 内存地址
   C. 中断
   D. NES 定制细节
   E. 注意
 4. PPU
   A. 概述
   B. 内存映射
   C. Name Tables
   D. Pattern Tables
   E. Attribute Tables
   F. 调色板
   G. Name Table 镜像
   H. 调色板镜像
   I. 背景卷轴
   J. 屏幕和子图形的层
   K. 子图形和 SPR-RAM
   L. 子图形 #0 点击标记
   M. 水平和竖直空白
   N. $2005/2006 矩阵编码
   O. PPU 怪癖
   P. 注意
 5. pAPU
 6. 手柄, 摇杆, 扩展端口
   A. 概述
   B. 光线枪
   C. 四人分插
   D. 摇杆
   E. Power Pad
   F. R.O.B (Robot Operated Buddy)
   G. 信号
   H. 扩展端口
   I. 注意
 7. 硬件内存镜像
 8. 寄存器
 9. 文件格式
   A. iNES 格式 (.NES)
 10. 为 NES 设计程序
   A. 概述
   B. CPU 注意事项
   C. PPU 注意事项
 11. 模拟器
   A. 概述
   B. CPU 注意事项
   C. PPU 注意事项
   D. APU 注意事项
 12. 引用材料
          A. CPU Information
          B. PPU Information
          C. APU Information
          D. Memory Mapper Information
          E. Mailing Lists
          F. WWW Sites
          G. Hardware Information

+———+
| 1. 说明 |
+———+

  A. 弃权声明
  ———–
     我绝不为本文的信息所造成的结果负责. 这些都是公开的信息, 并且不应当被用于商业用途.
     如果你打算将本文用于商业用途, 请在开发之前与我联系, 使我能够和你商讨你的项目的大纲.
     我并没有打算在资金上阻碍任何人: 如果你打算进行真的NES开发, 与任天堂美国公司或任天堂
     公司联系将是明智的. 它们的地址是:

      Nintendo of America               Nintendo Company, Ltd.
      P.O. Box 957                      60 Fukuine
      Redmond, WA 98073                 Kamitakamatsu-cho,
      USA                               Higashiyama-ku,
                                        Koyoto 602, Japan
     All titles of cartridges and console systems are registered trademarks of their
     respective owners. ( 我不认为有必要把他们一个一个的单独列出来 ).

  B. 为什么?
  ———-
     在本文完成时, 只有一片概括了NES内部的文章: Marat Fayzullin 的文章, 也就是 "NES.DOC".

     虽然 Fayzullin 的文章在很多地方有缺陷, 它提供了一个强大的基础, 并且它里面确实有对如
     何完成那个小黑匣子有一定的陈述.

     我抓住了扩展 "NES.DOC" 的机会, 是以其他人的发现和我的经验为基础. 这些经验使得这篇文
     章变成它今天的样子. 本文开头部分像是 Fayzullin 的文章经过了缩写和一些修改的复制品.
     Marat Fayzullin 本人后来得到了我的文章, 之后他就像别人推荐这篇文章.

     在我开来, 如果没有 Marat 的 "NES.DOC", 我将永远没有写这一篇的动机.

  C. 任务
  ——-
     本文的目标很简单: 提供关于NES的最准确和最新的信息, 以及 Famicom 的相关信息.

  D. 献给
  ——-
     我把本文献给 Alex Krasivsky. Alex 是一个很好的朋友, 并且在我眼里, truly started the
     ball of emulation rolling. 开心的时间和悲伤的时间, Alex 都在.
     Spasibo, Alex; umnjy Russki…

  E. 鸣谢
  ——-
     感谢所有帮助使本文成文今天的样子的人. 没有你们我将无所作为.

      Alex Krasivsky            – bcat@lapkin.rosprint.ru
      Andrew Davie
      Avatar Z                  –
swahlen@nfinity.com
      Barubary                  – barubary@mailexcite.com
      Bluefoot                  – danmcc@injersey.com
      CiXeL
      Chi-Wen Yang              –
yangfanw@ms4.hinet.net
      Chris Hickman             – typhoonz@parodius.com
      D                         – slf05@cc.usu.edu
      Dan Boris                 – dan.boris@coat.com
      David de Regt             – akilla@earthlink.net
      Donald Moore              – moore@futureone.com
      Fredrik Olsson            – flubba@hem2.passagen.se
      Icer Addis                – bldlust@maelstrom.net
      Jon Merkel                – jpm5974@omega.uta.edu
      Kevin Horton              – khorton@iquest.net
      Loopy                     – zxcvzxcv@netzero.net
      Marat Fayzullin           – fms@cs.umd.edu
      Mark Knibbs               – mark_k@iname.com
      Martin Nielsen            – mnielsen@get2net.dk
      Matt Conte                – itsbroke@classicgaming.com
      Matthew Richey            – mr6v@andrew.cmu.edu
      Memblers                  – 5010.0951@tcon.net
      MiKael Iushin             – acc@tulatelecom.ru
      Mike Perry                – mj-perry@uiuc.edu
      Morgan Johansson          – morgan.johansson@mbox301.swipnet.se
      Neill Corlett             – corlett@elwha.nrrc.ncsu.edu
      Pat Mccomack              – splat@primenet.com
      Patrik Alexandersson      – patrikus@hem2.passagen.se
      Paul Robson               – AutismUK@aol.com
      Ryan Auge                 – rauge@hay.net
      Stumble                   – stumble@alpha.pulsar.net
      Tennessee Carmel-Veilleux – veilleux@ameth.org
      Thomas Steen              – Thomas.Steen@no.jotankers.com
      Tony Young                – KBAAA@aol.com
      Vince Indriolo            – indriolo@nm.picker.com
      \FireBug\                 – lavos999@aol.com

     特别感谢 Stumble, 他通过IRC提供了无限的信息, 甚至不睡觉.

+————–+
| 2. Acronymns |
+————–+

  A. 内部
  ——-
     CPU     – 中央处理器: Self-explanitory. NES使用一个标准6502 ( NMOS )
     PPU     – 图形处理器: 用来控制图形,活动块和其他视频相关特点
     pAPU    – pseuedo-Audio 处理器: 固化于CPU; 产生 (5) 声音通道的波形:: 四个 (4) 模拟
               和一个 (1) 数字. 在NES内部没有处理音频的物理芯片.
     MMC     – 大量内存控制器: 微型控制器, 用来控制使NES游戏使用6502的64Kbyte以外的存储器.
               他们也可以被用来控制使用CHR-ROM,也许被用来产生“特别效果”,比如强制和中断,
               以及其他一些.
     VRAM    – 图形储存器: 这个储存器在PPU内部. NES中安装了16kbits 的VRAM.
     SPR-RAM – 子画面储存器: 用来储存子画面,共256 bytes. 虽然他也在PPU内部,但不是VRAM或者
               ROM的一部分.
     PRG-ROM – 程序只读储存器: 存储程序代码的存储器. 也可以认为是通过MMC控制的扩展存储器中
               的代码部分.
     PRG-RAM – 程序可写存储器: 于PRG-ROM同义,不过这个是RAM.
     CHR-ROM – 角色只读存储器: 在PPU外部的VRAM数据, 通过MMC在PPU内部与外部交换,或者在启动队
               列中“读入”VRAM.
     VROM    – 与CHR-ROM同义.
     SRAM    – 存档可写存储器: 一般用来保存RPG游戏的进度. 就像最终幻想系列的“水井”,和“塞
               尔达传说”.
     WRAM    – 与SRAM同义.
     DMC     – δ调制通道: APU中处理数字信号的通道. 通常被认为是PCM (Pulse信号调制器)通道.
     EX-RAM  – 扩展存储器: 在任天堂的MMC5中使用的,允许游戏扩展VRAM的容量.

  B. 硬件
  ——-
     NES     – 任天堂娱乐系统: Self-explanitory.
     Dany    – 与Famicom同义(硬件范围).
     Famicom – 与NES同义,但不支持原始的DMC数字音频重放.
     FDS     – Famicom磁盘系统: 安装在Famicom顶部,支持3"双面游戏软盘.

+——–+
| 3. CPU |
+——–+

  A. 一般信息
  ———–
     NES使用一个定制的NMOS 6502 CPU, 由Ricoh设计制造. 他最初的定制是添加了音频.

     NTSC制式的NES频率是 1.7897725MHZ, PAL的是 1.773447MHZ.

  B. 内存地址
  ———–
    +———+——-+——-+———————–+
    | 地址    | 大小  | 标记  |         描述          |
    +———+——-+——-+———————–+
    | $0000   | $800  |       | RAM                   |
    | $0800   | $800  | M     | RAM                   |
    | $1000   | $800  | M     | RAM                   |
    | $1800   | $800  | M     | RAM                   |
    | $2000   | 8     |       | Registers             |
    | $2008   | $1FF8 |  R    | Registers             |
    | $4000   | $20   |       | Registers             |
    | $4020   | $1FDF |       | Expansion ROM         |
    | $6000   | $2000 |       | SRAM                  |
    | $8000   | $4000 |       | PRG-ROM               |
    | $C000   | $4000 |       | PRG-ROM               |
    +———+——-+——-+———————–+
           标记图例: M = $0000的镜像
                        R = $2000-2008 每 8 bytes 的镜像
                            (e.g. $2008=$2000, $2018=$2000, etc.)

  C. 中断
  ——-
     6502有三种 (3) 中断: IRQ/BRK, NMI和RESET.

     每一种中断都有一个向量. 向量是当中断触发时“转到”的指定位置的16位地址.

     IRQ/BRK在两种情况下触发,因此它有分开的名字: 当软件中断请求被执行 (BRK指令),
     或者硬件中断请求被执行 (通过IRQ语句).

     RESET在启动时被触发. ROM被读入内存,并且6502转到指定的RESET向量. 没有寄存器被
     修改,没有内存被清空; 这些仅仅发生在启动时.

     NMI的意思是 Non-Maskable Interrupt (不可屏蔽中断–译注),发生在每次刷新时
     (VBlank). 这些刷新的间隔依赖于所用的系统 (PAL/NTSC).

     NMI在NTSC控制下刷新次数为 60次/秒, PAL为50次/秒. 6502的中断潜伏期为七 (7) 个周
     期; 这也就是说需要需要七 (7) 个周期来移入和移出一个中断.

     大多数中断应当返回RTI语句. 一些NES游戏不使用这种方法,比如SquareSoft的"Final Fa-
     ntasy 1"的标题. 他们的中断使用一种非常奇怪的方式返回: 通过手动操纵堆栈,然后返
     回一个RTS. 从技术上说这是有效的,但从精神上说这应当被避免.

     上述的中断使用下列的向量地址,它们在内存中的地址为:

       $FFFA = NMI
       $FFFC = RESET
       $FFFE – IRQ/BRK

     中断优先权如下:

       Highest = RESET
                 NMI
        Lowest = IRQ/BRK

  D. NES订制细节
  ————–
     NES的6502并不包括对decimal模式的支持. CLD和SED opcodes function normally, 但是p中
     的 ‘d’ bit在ADC和SBC中并未被使用. 在游戏中将CLD先执行于代码是普遍的行为,就像启动
     和RESET时的 ‘d’ 状态并不为人知一样.

     音频寄存器被放置于CPU内部; 所有波形的发生也都在CPU的内部.

  E. 注意
  ——-
     请注意那两个独立的16K PRG-ROM片断; 他们也许是线性的,但是他们是否独立依赖于游戏容
     量的大小. 有些游戏只用一 (1) 个16K的PRG-ROM,这就需要将他读入到$C000和$8000之中
     (两块内存都被写入–译注).

     大多数游戏将他们自己读入到$8000, 使用32K PRG-ROM 空间. 第一个这样做的游戏是Super
     Mario Brothers. 然而所有大于一 (1) 个 16K 容量的PRG-ROM也都把他们自己读入$8000.
     这些游戏使用Memory Mappers在PRG-ROM内外交换数据,CHR-ROM中也一样.

     当遇到BRK时,NES的6502将CPU状态标记推入有 ‘b’ CPU bit 集合的堆栈中. 在IRQ或者NMI时,
     CPU将状态标记推入清除了 ‘b’ bit的堆栈中. 这样做是因为事实上硬件IRQ (IRQ) 和软件IRQ
     (BRK) 使用同样的向量. 例如,一个中断会使用下面的代码来区别上述两种中断:

      C134: PLA                 ; 拷贝CPU状态标记
      C135: PHA                 ; 将状态标记返回到堆栈
      C136: AND #$10            ; 检查 D4 (‘b’ CPU bit)
      C138: BNE is_BRK_opcode   ; 如果固定了,则它是一个软件IRQ (BRK)

     执行NMI中的BRK将导致被推入的 ‘b’ bit被固定.

     6502在opcode $6C 有一个bug (绝对的间接跳跃). CPU并没有正确考虑到当 低字节 [low-byte]
     是$FF时的有效地址. 例如:

      C100: 4F
      C1FF: 00
      C200: 23
        ..
      D000: 6C FF C1 – JMP ($C1FF)

     逻辑上说,这样将转到地址$2300. 然而,事实上计算中的高字节 *NOT* increased on a page-
     wrap, 事实上转到了$4F00.

     应当被注意的是page wrappig并不发生在 间接地址索引模式 [indexed-indirect addressing
     modes].由于 0页面 [zero-page],所有 间接索引 [indexed-indirect] 的读写必须在计算后申请
     一个到有效地址的一个逻辑 与 [AND] #$FF. 例如:

      C000: LDX #3        ; 从 $0002+$0003 读间接地址 [indirect address],
      C002: LDA ($FF,X)   ; 不是 $0102+$0103.

 

+——–+
| 4. PPU |
+——–+

  A. 概述
  ——-
    镜像 (也被称为"shadowing") 是将特殊的地址或抵制范围通过硬件映射到其他地址的一种处理.

  B. 内存映射
  ———–
    这里有两 (2) 片内存映射. 第一部分被称为 "RAM Memory Map",是一段不算长的指向NES本身
    物理RAM的区域。第二部分是 "Programmer Memory Map",是比较长的描述全部NES和他如何被使
    用以及如何被操作的内存区域.

            RAM Memory Map
      +———+——-+——————–+
      | Address | Size  | Description        |
      +———+——-+——————–+
      | $0000   | $1000 | Pattern Table #0   |
      | $1000   | $1000 | Pattern Table #1   |
      | $2000   | $800  | Name Tables        |
      | $3F00   | $20   | Palettes           |
      +———+——-+——————–+

        Programmer Memory Map
      +———+——-+——-+——————–+
      | Address | Size  | Flags | Description        |
      +———+——-+——-+——————–+
      | $0000   | $1000 | C     | Pattern Table #0   |
      | $1000   | $1000 | C     | Pattern Table #1   |
      | $2000   | $3C0  |       | Name Table #0      |
      | $23C0   | $40   |  N    | Attribute Table #0 |
      | $2400   | $3C0  |  N    | Name Table #1      |
      | $27C0   | $40   |  N    | Attribute Table #1 |
      | $2800   | $3C0  |  N    | Name Table #2      |
      | $2BC0   | $40   |  N    | Attribute Table #2 |
      | $2C00   | $3C0  |  N    | Name Table #3      |
      | $2FC0   | $40   |  N    | Attribute Table #3 |
      | $3000   | $F00  |   R   |                    |
      | $3F00   | $10   |       | Image Palette #1   |
      | $3F10   | $10   |       | Sprite Palette #1  |
      | $3F20   | $E0   |    P  |                    |
      | $4000   | $C000 |     F |                    |
      +———+——-+——-+——————–+
                          C = Possibly CHR-ROM
                          N = Mirrored (see Subsection G)
                          P = Mirrored (see Subsection H)
                          R = Mirror of $2000-2EFF (VRAM)
                          F = Mirror of $0000-3FFF (VRAM)

  C. Name Tables
  ————–
     NES使用马赛克矩阵进行图形显示; 这样的格子被叫做 Name Table. 马赛克是 8×8像素 [pixels].
     完整的 Name Table 有 32*30 个马赛克 (256*240 像素). 紧记: NTSC和PAL单元在显示上有不同
     的刷新率.

     Name Tables 之中的马赛克的资料被保存在 Pattern Table 之中 (continue on).

  D. Pattern Tables
  —————–
     Pattern Table 包括了 Name Table 所需要的 8×8 的马赛克. 他保存了NES调色板中所有16色的
     4-bit 颜色矩阵的低两 (2) 位 [bit]. 例如:

       VRAM    Contents of                     Colour
       Addr   Pattern Table                    Result
      —— —————                  ——–
      $0000: %00010000 = $10 –+              …1…. Periods are used to
        ..   %00000000 = $00   |              ..2.2… represent colour 0.
        ..   %01000100 = $44   |              .3…3.. Numbers represent
        ..   %00000000 = $00   +– Bit 0      2…..2. the actual palette
        ..   %11111110 = $FE   |              1111111. colour #.
        ..   %00000000 = $00   |              2…..2.
        ..   %10000010 = $82   |              3…..3.
      $0007: %00000000 = $00 –+              ……..

      $0008: %00000000 = $00 –+
        ..   %00101000 = $28   |
        ..   %01000100 = $44   |
        ..   %10000010 = $82   +– Bit 1
        ..   %00000000 = $00   |
        ..   %10000010 = $82   |
        ..   %10000010 = $82   |
      $000F: %00000000 = $00 –+

     上面的 Pattern Table 的结果就是字符 ‘A’,就像右上角的 "Colour Result" 部分显示的.

  E. Attribute Tables
  ——————-
     Attribute Table 的每一个字节都描述了显示器上的一个 4*4 马赛克组. 有许多种方法来描述
     Attribute Table 中一 (1) 个字节的函数是怎样的:

       * 保存了 32*32 像素格子 中每 16*16 像素 的高两 (2) 位.
       * 保存了 十六 (16) 个 8×8 马赛克中的 高两 (2) 位.
       * 保存了 四 (4) 个 4*4 像素格子 的高两 (2) 位.

     这样说确实很乱; 下面的两个图表将有所帮助:

      +————+————+
      |  Square 0  |  Square 1  |  #0-F represents an 8×8 tile
      |   #0  #1   |   #4  #5   |
      |   #2  #3   |   #6  #7   |  Square [x] represents four (4) 8×8 tiles
      +————+————+   (i.e. a 16×16 pixel grid)
      |  Square 2  |  Square 3  |
      |   #8  #9   |   #C  #D   |
      |   #A  #B   |   #E  #F   |
      +————+————+

     真正的 attribute byte 格式如下 (与上面的相比较):

       Attribute Byte
         (Square #)
      —————-
          33221100
          ||||||+— Upper two (2) colour bits for Square 0 (Tiles #0,1,2,3)
          ||||+—– Upper two (2) colour bits for Square 1 (Tiles #4,5,6,7)
          ||+——- Upper two (2) colour bits for Square 2 (Tiles #8,9,A,B)
          +——— Upper two (2) colour bits for Square 3 (Tiles #C,D,E,F)

  F. 调色板
  ———
     NES有两个 16色 "调色板": 图形调色板和子图形调色板. 因为他们不储存物理RGB值,所以
     比起一个真正的调色板,它们更像 "查找表格".

     写到 $3F00-3FFF 的 D7-D6 字节将被忽略.

  G. Name Table 镜像
  ——————
     需要紧记的一点是在理解NES的时候,有许多镜像表格. 即使在使用 CHR-ROM-mapped Name Tables
     (mapper-specific).

     NES本身只有 2048 ($800) 字节的RAM给 Name Tables. 然而,就像在 Subsection B 中所表现
     得那样 NES 有升至 四 (4) 个 Name Tables 的地址容量.

     缺省的是许多 carts 伴随的是 "水平" 和 "垂直" 的镜像,允许你修改 Name Tables 所指向的NES
     PPU RAM 的位置. 这个镜像表格同时作用于两 (2) 个Name Tables; 你不可以独自选择 Name Tables.

     下面的表格将帮助理解NES中遇到的所有镜像类型. 请注意显示的地址 (大小为 12-bit) 都是 NES PPU
     RAM 的 Name Table 的一部分; 有人为认为这些与VRAM区域中的 "$2xxx" 同义:

        Name                       NT#0   NT#1   NT#2   NT#3   Flags
      +————————–+——+——+——+——+——-+
      | Horizontal               | $000 | $000 | $400 | $400 |       |
      | Vertical                 | $000 | $400 | $000 | $400 |       |
      | Four-screen              | $000 | $400 | $800 | $C00 | F     |
      | Single-screen            |      |      |      |      |  S    |
      | CHR-ROM mirroring        |      |      |      |      |   C   |
      +————————–+——+——+——+——+——-+
        F = 依赖于扩展的 2048 ($800) RAM (kept on the cart) 的四屏镜像,导致四 (4) 个独立的物理
            Name Tables.
        S = 拥有映射表 [mapper] 的单屏游戏,允许你选择哪个PPU RAM区域来使用 ($000, $400, $800,
            $C00); 所有的 NT 都指向同样的 PPU RAM 地址.
        C = 映射表 #68 (Afterburner 2),允许你将 CHR-ROM 镜像到 NES 的 PPU RAM 区域中 Name Tables
            区域. 很自然的这使得 Name Table 成为 ROM 基础,并且不能对它写入. 然而,这个特点可以通
            过映射表本身进行控制,使得你打开或关闭这个特点.

  H. 调色板镜像
  ————-
     镜像发生在图形调色板和子图形调色板之间. 任何写入 $3F00 的数据都被镜像到 $3F10. 任何写入 $3F04
     的数据都被镜像到 $3F14,如此. 如此…

     在图形调色板和子图形调色板的高三 (3) 色 Colour #0 被定义为透明 (实际上那里储存的颜色不被显示).

     PPU 使用 $3F00 来定义背景色.

     另一个长一些的解释,如下:

       * $0D 被写入 $3F00 (镜像到 $3F00)
       * $03 被写入 $3F08 (镜像到 $3F08)
       * $1A 被写入 $3F18
       * $3F08 被读入 累加器 [accumulator]

     PPU 使用 $0D 作为背景色,不论 $3F08 饱含了 $03 的值 (因为所有的调色板中的 colour #0 都被定义为
     透明色,它不被显示). 最后,累加器将保存 $1A 的值,它是 $3F18 的镜像. 然后 $1A 不被显示,因为
     colour #0 为透明色.

     图形和子图形调色板都被镜像到其他的VRAM区域; $3F20-3FFF 分别是他们的镜像.

     被写入 $3F00-3FFF 的 D7-D6 字节被忽略.

  I. 背景卷轴
  ———–
     NES能够独立于在背景之上的字画面来卷动背景 (pre-rendered Name Table + Pattern Table + Attribute
     Table). 背景能被水平和竖直卷动.

     卷轴工作如下:

      Horizontal Scrolling             Vertical Scrolling
        0          512
        +—–+—–+                      +—–+ 0
        |     |     |                      |     |
        |  A  |  B  |                      |  A  |
        |     |     |                      |     |
        +—–+—–+                      +—–+
                                           |     |
                                           |  B  |
                                           |     |
                                           +—–+ 480

     Name Table "A" 是通过在寄存器 $2000 中的 Bits D1-D0 来指定的,"B" 接下来的 Name Table (由于镜
     像,这是动态的). 它在同时使用水平和竖直卷轴的游戏时不工作.

     背景将跨越多个 Name Table,就像这里展示的:

      +—————+—————+
      | Name Table #2 | Name Table #3 |
      |    ($2800)    |    ($2C00)    |
      +—————+—————+
      | Name Table #0 | Name Table #1 |
      |    ($2000)    |    ($2400)    |
      +—————+—————+

     写到水平卷轴地址为 $2005 的值得范围是 0 至 256.
     写到垂直卷轴的值是 0-239; 超过 239 的值时不被考虑的 (例如: 248 被认为是 -8).

  J. 屏幕和子图形的层
  ——————-
     在NES显示的时候使用的是一种特殊的规则:

      FRONT                                BACK
      +—-+———–+—-+———–+—–+
      | CI | OBJs 0-63 | BG | OBJs 0-63 | EXT |
      +—-+———–+—-+———–+—–+
           | SPR-RAM   |    | SPR-RAM   |
           | BGPRI==0  |    | BGPRI==1  |
           +———–+    +———–+

     CI 的意思是 ‘Colour Intensity’ [颜色亮度], 与 $2001 的 D7-D5 等价. BG 是 背景 [BackGround],EXT
     是 扩展端口视频信号 [EXTension port video signal].

     ‘BGPRI’ 描述的是 SPR-RAM 中的 ‘Background Priority’ [背景优先权] bit,在 per-sprite 基础上 (D5,
     Byte 2).

     OBJ 数目描述真正的子图形数目,不是 马赛克索引值 [Title Index values].

     FRONT 被认为是在其他所有层上被看到的 (最后绘制),BACK 被认为是其他所有层之下的 (最先绘制).

  K. 子图形和 SPR-RAM
  ——————-
     NES支持64个子图形. 每个子画面的大小可以是 8×8 或者 8×16 像素. 子画面数据被保存在 VRAM 的 Partt-
     ern Table 区域.

     子画面的特征,比如 flipping 和 优先权,被保存在 SPR-RAM. SPR-RAM 的格式如下:

      +———–+———–+—–+————+
      | Sprite #0 | Sprite #1 | … | Sprite #63 |
      +-+——+–+———–+—–+————+
        |      |  
        +——+———-+————————————–+
        + Byte | Bits     | Description                          |
        +——+———-+————————————–+
        |  0   | YYYYYYYY | Y Coordinate – 1. Consider the coor- |
        |      |          | dinate the upper-left corner of the  |
        |      |          | sprite itself.                       |
        |  1   | IIIIIIII | Tile Index #                         |
        |  2   | vhp000cc | Attributes                           |
        |      |          |   v = Vertical Flip   (1=Flip)       |
        |      |          |   h = Horizontal Flip (1=Flip)       |
        |      |          |   p = Background Priority            |
        |      |          |         0 = In front                 |
        |      |          |         1 = Behind                   |
        |      |          |   c = Upper two (2) bits of colour   |
        |  3   | XXXXXXXX | X Coordinate (upper-left corner)     |
        +——+———-+————————————–+

     Tile Index # 被获得的方法与 Name Table 数据一样.

     大小为 8×16 的子画面函数有些不同. 一个有偶数 Tile Index # 的 8×16 子画面使用在 VRAM 中 $2000
     的 Pattern Table; 奇数 Tile Index #s 使用 $1000. *注意*: 寄存器 $2000 对 8×16子画面无效.

     所有 64 个子图形都包括一个内部优先权; 子画面 #0 的优先权比 #63高 (子画面 #0 应当被最后绘制,
     etc…).

     只有八 (8) 个子图形可以被显示在同一个扫描线 [scan-line] 上. 每个 SPR-RAM 入口都被检测来知道他
     是不是与其他的子图形在同一水平线上. 记得,这是在每个扫描线的基础上被执行的,不是在每个子画面
     的基础上 (例如,做256次,而不是 256/8 或者 256/16次).

     (注意: 在一个真正的NES单元,如果子画面被关闭了很长一段时间 ($2001的D4是0),SPR-RAM 将被降低. 一
     个被建议的观点是 SPR-RAM 是一个真正的 DRAM,D4 控制这个 DRAM 的刷新周期).

  L. 子图形 #0 点击标记
  ———————
     PPU有能力演算出子图形 #0的位置,并且把它的发现储存到 $2002 的 D6. 工作的方式如下:

     PPU扫描第一个真正的不透明 "子图形像素" 和第一个不透明 "背景像素". 背景像素是被Name Table使用中
     的马赛克. 记得colour #0 被定义为透明.

     导致 D6 被设置为 *IS* 的像素被绘制.

     下面的例子也许有所帮助. 下面是两个马赛克. 透明色 (colour #0) 被通过下划线字符 (‘_’) 定义. 一个
     星号 (‘*’) 在 D6 被设置时描述.

       Sprite         BG         Result
       ——         –         ——
      __1111__     ________     __1111__
      _111111_     _______2     _1111112   
      11222211     ______21     11222211
      112__211  +  _____211  =  112__*11  ‘*’ will be drawn as colour #2
      112__211     ____2111     112_2211
      11222211     ___21111     11222211
      _111111_     __211111     _1111111
      __1111__     _2111111     _2111111

     这同样适用于那些在 BG 下面 (通过 ‘Background Priority’ SPR-RAM bit),可是上面的例子应当为 ‘BG+Sprite’.

     同样,D6在每个VBlank之后清空 (设置为0).

  M. 水平和竖直空白
  —————–
     就像其他的控制台,NES有一个更新: 显示设备重新定位电子枪来显示可视数据. 最普通的显示设备是电视机. NTSC
     设备每秒钟刷新60次,PAL每秒50次.

     电子枪绘制像素时从左向右: 这种过程导致一 (1) 条水平扫描线被绘制. 在电子枪绘制完成一条完整的扫描线后,电
     子枪必须回到显示设备的左边,准备好去绘制下一条扫描线. 电子枪回到左边的过程叫做 水平空白期 [Horizontal
     Blank period] (HBlank).

     当电子枪完成绘制所有扫描线,它必须回到显示设备的最上端; 电子枪复位回到显示设备的最上端的时间叫做 竖直空
     白期 [Vertial Blank period] (VBlank).

     就像你能从下面的图表中看到的,电子枪或多或少的工作在 ‘Z’ 字形轨迹直到到达 VBlank,然后过程重复:

           +———–+
      +—>|***********| <– Scanline 0
      |    | ___—~~~ | <– HBlank
      V    |***********| <– Scanline 1
      B    | ___—~~~ | <– HBlank
      l    |    …    |      …
      a    |    …    |      …
      n    |***********| <– Scanline 239
      k    +—–+—–+
      |          |
      +–VBlank–+

    NTSC的NES是下面的刷新方式和屏幕格式:

      +——–+ 0 —-+
      |        |       |
      |        |       |
      | Screen |       +– (0-239) 256×240 on-screen results
      |        |       |
      |        |       |
      +——–+ 240 –+
      |   ??   |       +– (240-242) Unknown
      +——–+ 243 –+
      |        |       |
      | VBlank |       +– (243-262) VBlank
      |        |       |
      +——–+ 262 –+

     竖直空白 (VBlank) 标记被包括在 $2002 的 D7中. 它指出PPU是否处于VBlank. 一段程序可以通过读 $2002 重置D7.

  N. $2005/2006 矩阵编码
  ———————-
     有关于 $2005 和 $2006 寄存器的详细信息,参考 Loopy 的 $2005/2006 文档. 他的文档提供了的关于这些寄存器
     如何工作的完整准确的信息. 联系 Loopy 获得更多信息.

  O. PPU 怪癖
  ———–
     第一次读VRAM是无效的. 由于这种现象,NES返回 pseudo 缓冲值,而不是期待的线性值. 看下面的例子:

    VRAM $2000 contains $AA $BB $CC $DD.
    VRAM incrementation value is 1.
    The result of execution is printed in the comment field.

      LDA #$20
      STA $2006
      LDA #$00
      STA $2006        ; VRAM address now set at $2000
      LDA $2007        ; A=??     VRAM Buffer=$AA
      LDA $2007        ; A=$AA    VRAM Buffer=$BB
      LDA $2007        ; A=$BB    VRAM Buffer=$CC
      LDA #$20
      STA $2006
      LDA #$00
      STA $2006        ; VRAM address now set at $2000
      LDA $2007        ; A=$CC    VRAM Buffer=$AA
      LDA $2007        ; A=$AA    VRAM Buffer=$BB

     就像演示的,PPU将在第一次读入执行后传递增加他的内部地址. 这 *仅适用* 于 VRAM $0000-3FFF (例如: 调色板信
     息和他们各自的镜像不必忍受这种现象).

  P. 注意
  ——-
     PPU 将会在访问 $2007 后自动增加VRAM地址,加1或者32 (基于 $2000 的 D2).

 

+———+
| 5. pAPU |
+———+
     To be written. 现在的信息都不准确或不正确. 没有人现在有关于声音的100%准确的信息. 这一部分将在有人反编译
     NES的pAPU引擎并且提供给我信息 (或者信息的引用) 之后完成.

 

+————————-+
| 6. 手柄, 摇杆, 扩展端口 |
+————————-+

  A. 一般信息
  ———–
     NES支持无数的输入设备,包括手柄, 光线枪 (light guns),和四人娱乐设备 (四手柄分插).

     手柄 #1 和 #2 通过 $4016 和 $4017 分别访问.

     手柄通过strobing-method重置: 写入1,然后0 到 $4016. 阅读Subsection H以获得关于 "half-strobing" 信息.

     在一个完整的 strobe,手柄按键状态将会被作为一个单位流 [single-bit stream] (D0) 返回. 多重读取器需要
     读取关于控制器的所有信息.

      1 = A          9 = Ignored   17 = +–+
      2 = B         10 = Ignored   18 =    +– Signature
      3 = SELECT    11 = Ignored   19 =    |
      4 = START     12 = Ignored   20 = +–+
      5 = UP        13 = Ignored   21 = 0
      6 = DOWN      14 = Ignored   22 = 0
      7 = LEFT      15 = Ignored   23 = 0
      8 = RIGHT     16 = Ignored   24 = 0

     阅读 Subsection G 以获得关于信号的信息.

  B. 光线枪
  ———
     光线枪简单的使用 $4017 和 $4017 中的位,在 Section 8 中有表述. 阅读 D4, D3 和 D0.

     可以将两把光线枪同时接到两个手柄接口上.

  C. 四人分插
  ———–
     NES支持四人游戏适配器,来讲两 (2) 个手柄扩展至四 (4) 个. 使用四人分插的游戏有 Tengen 的 "Gauntlet II",
     和 Nintendo 的 "RC Pro Am 2".

     全部四 (4) 个控制器通过 $4016 或者 $4017 的 D0 读入状态,Subsection A 中有描述.

     对于寄存器 $4016,地址 #1-8 为手柄 #1,地址 #9-16 为手柄 #3. 对于寄存器 $4017,为手柄 #2 和 #4.

     下面是地址 #s 的列表和他们的结果.

      1 = A          9 = A         17 = +–+
      2 = B         10 = B         18 =    +– Signature
      3 = SELECT    11 = SELECT    19 =    |
      4 = START     12 = START     20 = +–+
      5 = UP        13 = UP        21 = 0
      6 = DOWN      14 = DOWN      22 = 0
      7 = LEFT      15 = LEFT      23 = 0
      8 = RIGHT     16 = RIGHT     24 = 0

     阅读 Subsection G 以获得关于信号的信息.

  D. 摇杆
  ——-
     Taito 的 "Arkanoid" 使用摇杆作为首选控制器.

     摇杆的位置是通过 $4017 的 D1 读取; 读取的数据是相反的 (0=1, 1=0). 第一个读取的值是 MSB,第八个读取值是
     (明显的) LSB. 有效值的范围是 98 至 242,98描述的是摇杆被完全逆时针转动.

     例如,如果读入 %01101011, 值将被按位反,变成 %10010100 也就是 146.

     摇杆也有一个按键,地址是 $4016的 D1. 值 1 表明键被按下.

  E. Power Pad
  ————
     目前无可用信息.

  F. R.O.B (Robot Operated Buddy)
  ——————————-
     目前无可用信息.

  G. 信号
  ——-
     信号允许程序员探测设备是否被连接到四 (4) 个端口,或者没有连上,如果连上了,设备是哪种类型. 正确的/已知
     的信号有:

      %0000 = Disconnected
      %0001 = Joypad ($4016 only)
      %0010 = Joypad ($4017 only)

  H. 扩展端口
  ———–
     手柄门处理需要双重书写: 1,然后0. 如果门处理并不完整,或者发生了不标准顺序,手柄就不再是通讯工具: 是扩
     展端口.

     对于NES用户,扩展端口在游戏机的底部被一块灰色小塑料覆盖. Famicom 用户在游戏机的前部有一个有限的扩展端口.
     通常被用来接手柄或者快速手柄 [turbo-joypads].

     这样的一个通讯的例子应当是下面的代码:

      LDA #%00000001
      STA $4016
      STA $4017           ; Begin read mode of expansion port
      LDA #%00000011      ; Write %110 to the expansion port
      STA $4016

     我从来没有遇到过使用这种方法交流的例子 [cart].

  I. 注意
  ——-
     无.

 

+—————–+
| 7. 硬件内存镜像 |
+—————–+

     虽然有大量的镜像被使用 (超过64), 本文档中0.53版的 "MMC" 章节依旧不固定,现在被删除了.

     所有的并不仅仅是损失,另一个由 \FireBug\ 写的文档 Vertigo 2099 包括几乎所有的存在的镜像的准确信息. 你可
     以通过下面的URL获得一份拷贝:

       http://free.prohosting.com/~nintendo/mappers.nfo

     请注意,我对上述文档中包含的信息没有任何责任. 联系 lavos999@aol.com 以获得更多信息.

 

+———–+
| 8. 寄存器 |
+———–+
     程序员通过寄存器与PPU和pAPU通讯,并不比通过允许代码修改NES的内存预设置多些什么. 如果没有寄存器,程序就
     无法工作: 时代.

     每个寄存器都有16位地址. 每个仅存期都在他有描述之后很快在 parentheses 中有一个静态域. 例如:

       R = Readable                    W = Writable
       2 = Double-write register      16 = 16-bit register

     注意: 16位寄存器实际上包含了两个线性8位寄存器,能够被 *独立* 指派. The reason for specifying them as 16-
     bit is for ease of documentation. 例如,"$4002+$4003" 意思是 D15-D8 应当在 $4003 中, D7-D0 应当在 $4002
     之中.

     注意: 表中未被列出的位认为未被使用.

    +———+———————————————————-+
    | Address | Description                                              |
    +———+———————————————————-+
    |  $2000  | PPU Control Register #1 (W)                              |
    |         |                                                          |
    |         |    D7: Execute NMI on VBlank                             |
    |         |           0 = Disabled                                   |
    |         |           1 = Enabled                                    |
    |         |    D6: PPU Master/Slave Selection –+                    |
    |         |           0 = Master                +– UNUSED           |
    |         |           1 = Slave               –+                    |
    |         |    D5: Sprite Size                                       |
    |         |           0 = 8×8                                        |
    |         |           1 = 8×16                                       |
    |         |    D4: Background Pattern Table Address                  |
    |         |           0 = $0000 (VRAM)                               |
    |         |           1 = $1000 (VRAM)                               |
    |         |    D3: Sprite Pattern Table Address                      |
    |         |           0 = $0000 (VRAM)                               |
    |         |           1 = $1000 (VRAM)                               |
    |         |    D2: PPU Address Increment                             |
    |         |           0 = Increment by 1                             |
    |         |           1 = Increment by 32                            |
    |         | D1-D0: Name Table Address                                |
    |         |         00 = $2000 (VRAM)                                |
    |         |         01 = $2400 (VRAM)                                |
    |         |         10 = $2800 (VRAM)                                |
    |         |         11 = $2C00 (VRAM)                                |
    +———+———————————————————-+
    |  $2001  | PPU Control Register #2 (W)                              |
    |         |                                                          |
    |         | D7-D5: Full Background Colour (when D0 == 1)             |
    |         |         000 = None  +————+                       |
    |         |         001 = Green              | NOTE: Do not use more |
    |         |         010 = Blue               |       than one type   |
    |         |         100 = Red   +————+                       |
    |         | D7-D5: Colour Intensity (when D0 == 0)                   |
    |         |         000 = None            +–+                       |
    |         |         001 = Intensify green    | NOTE: Do not use more |
    |         |         010 = Intensify blue     |       than one type   |
    |         |         100 = Intensify red   +–+                       |
    |         |    D4: Sprite Visibility                                 |
    |         |           0 = Sprites not displayed                      |
    |         |           1 = Sprites visible                            |
    |         |    D3: Background Visibility                             |
    |         |           0 = Background not displayed                   |
    |         |           1 = Background visible                         |
    |         |    D2: Sprite Clipping                                   |
    |         |           0 = Sprites invisible in left 8-pixel column   |
    |         |           1 = No clipping                                |
    |         |    D1: Background Clipping                               |
    |         |           0 = BG invisible in left 8-pixel column        |
    |         |           1 = No clipping                                |
    |         |    D0: Display Type                                      |
    |         |           0 = Colour display                             |
    |         |           1 = Monochrome display                         |
    +———+———————————————————-+
    |  $2002  | PPU Status Register (R)                                  |
    |         |                                                          |
    |         |    D7: VBlank Occurance                                  |
    |         |          0 = Not occuring                                |
    |         |          1 = In VBlank                                   |
    |         |    D6: Sprite #0 Occurance                               |
    |         |          0 = Sprite #0 not found                         |
    |         |          1 = PPU has hit Sprite #0                       |
    |         |    D5: Scanline Sprite Count                             |
    |         |          0 = Eight (8) sprites or less on current scan-  |
    |         |              line                                        |
    |         |          1 = More than 8 sprites on current scanline     |
    |         |    D4: VRAM Write Flag                                   |
    |         |          0 = Writes to VRAM are respected                |
    |         |          1 = Writes to VRAM are ignored                  |
    |         |                                                          |
    |         | NOTE: D7 is set to 0 after read occurs.                  |
    |         | NOTE: After a read occurs, $2005 is reset, hence the     |
    |         |       next write to $2005 will be Horizontal.            |
    |         | NOTE: After a read occurs, $2006 is reset, hence the     |
    |         |       next write to $2006 will be the high byte portion. |
    |         |                                                          |
    |         | For detailed information regarding D6, see Section 4,    |
    |         | Subsection L.                                            |
    +———+———————————————————-+
    |  $2003  | SPR-RAM Address Register (W)                             |
    |         |                                                          |
    |         | D7-D0: 8-bit address in SPR-RAM to access via $2004.     |
    +———+———————————————————-+
    |  $2004  | SPR-RAM I/O Register (W)                                 |
    |         |                                                          |
    |         | D7-D0: 8-bit data written to SPR-RAM.                    |
    +———+———————————————————-+
    |  $2005  | VRAM Address Register #1 (W2)                            |
    |         |                                                          |
    |         |  Commonly used used to "pan/scroll" the screen (sprites  |
    |         |  excluded) horizontally and vertically. However, there   |
    |         |  is no actual panning hardware inside the NES. This      |
    |         |  register controls VRAM addressing lines.                |
    |         |                                                          |
    |         | Refer to Section 4, Subsection N, for more information.  |
    +———+———————————————————-+
    |  $2006  | VRAM Address Register #2 (W2)                            |
    |         |                                                          |
    |         |  Commonly used to specify the 16-bit address in VRAM to  |
    |         |  access via $2007. However, this register controls VRAM  |
    |         |  addressing bits, and therefore should be used with      |
    |         |  knowledge of how it works, and when it works.           |
    |         |                                                          |
    |         | Refer to Section 4, Subsection N, for more information.  |
    +———+———————————————————-+
    |  $2007  | VRAM I/O Register (RW)                                   |
    |         |                                                          |
    |         | D7-D0: 8-bit data read/written from/to VRAM.             |
    +———+———————————————————-+
    |  $4000  | pAPU Pulse #1 Control Register (W)                       |
    |  $4001  | pAPU Pulse #1 Ramp Control Register (W)                  |
    |  $4002  | pAPU Pulse #1 Fine Tune (FT) Register (W)                |
    |  $4003  | pAPU Pulse #1 Coarse Tune (CT) Register (W)              |
    |  $4004  | pAPU Pulse #2 Control Register (W)                       |
    |  $4005  | pAPU Pulse #2 Ramp Control Register (W)                  |
    |  $4006  | pAPU Pulse #2 Fine Tune Register (W)                     |
    |  $4007  | pAPU Pulse #2 Coarse Tune Register (W)                   |
    |  $4008  | pAPU Triangle Control Register #1 (W)                    |
    |  $4009  | pAPU Triangle Control Register #2 (?)                    |
    |  $400A  | pAPU Triangle Frequency Register #1 (W)                  |
    |  $400B  | pAPU Triangle Frequency Register #2 (W)                  |
    |  $400C  | pAPU Noise Control Register #1 (W)                       |
    |  $400D  | Unused (???)                                             |
    |  $400E  | pAPU Noise Frequency Register #1 (W)                     |
    |  $400F  | pAPU Noise Frequency Register #2 (W)                     |
    |  $4010  | pAPU Delta Modulation Control Register (W)               |
    |  $4011  | pAPU Delta Modulation D/A Register (W)                   |
    |  $4012  | pAPU Delta Modulation Address Register (W)               |
    |  $4013  | pAPU Delta Modulation Data Length Register (W)           |
    +———+———————————————————-+
    |  $4014  | Sprite DMA Register (W)                                  |
    |         |                                                          |
    |         |  Transfers 256 bytes of memory into SPR-RAM. The address |
    |         |  read from is $100*N, where N is the value written.      |
    +———+———————————————————-+
    |  $4015  | pAPU Sound/Vertical Clock Signal Register (R)            |
    |         |                                                          |
    |         |    D6: Vertical Clock Signal IRQ Availability            |
    |         |           0 = One (1) frame occuring, hence IRQ cannot   |
    |         |               occur                                      |
    |         |           1 = One (1) frame is being interrupted via IRQ |
    |         |    D4: Delta Modulation                                  |
    |         |    D3: Noise                                             |
    |         |    D2: Triangle                                          |
    |         |    D1: Pulse #2                                          |
    |         |    D0: Pulse #1                                          |
    |         |           0 = Not in use                                 |
    |         |           1 = In use                                     |
    |         +———————————————————-+
    |         | pAPU Channel Control (W)                                 |
    |         |                                                          |
    |         |    D4: Delta Modulation                                  |
    |         |    D3: Noise                                             |
    |         |    D2: Triangle                                          |
    |         |    D1: Pulse #2                                          |
    |         |    D0: Pulse #1                                          |
    |         |           0 = Channel disabled                           |
    |         |           1 = Channel enabled                            |
    +———+———————————————————-+
    |  $4016  | Joypad #1 (RW)                                           |
    |         |                                                          |
    |         | READING:                                                 |
    |         |    D4: Zapper Trigger                                    |
    |         |           0 = Pulled                                     |
    |         |           1 = Released (not held)                        |
    |         |    D3: Zapper Sprite Detection                           |
    |         |           0 = Sprite not in position                     |
    |         |           1 = Sprite in front of cross-hair              |
    |         |    D0: Joypad Data                                       |
    |         +———————————————————-+
    |         | WRITING:                                                 |
    |         | Joypad Strobe (W)                                        |
    |         |                                                          |
    |         |    D0: Joypad Strobe                                     |
    |         |           0 = Clear joypad strobe                        |
    |         |           1 = Reset joypad strobe                        |
    |         +———————————————————-+
    |         | WRITING:                                                 |
    |         | Expansion Port Latch (W)                                 |
    |         |                                                          |
    |         |    D0: Expansion Port Method                             |
    |         |           0 = Write                                      |
    |         |           1 = Read                                       |
    +———+———————————————————-+
    |  $4017  | Joypad #2/SOFTCLK (RW)                                   |
    |         |                                                          |
    |         | READING:                                                 |
    |         |    D7: Vertical Clock Signal (External)                  |
    |         |           0 = Not occuring                               |
    |         |           1 = Occuring                                   |
    |         |    D6: Vertical Clock Signal (Internal)                  |
    |         |           0 = Occuring     (D6 of $4016 affected)        |
    |         |           1 = Not occuring (D6 of $4016 untouchable)     |
    |         |    D4: Zapper Trigger                                    |
    |         |           0 = Pulled                                     |
    |         |           1 = Released (not held)                        |
    |         |    D3: Zapper Sprite Detection                           |
    |         |           0 = Sprite not in position                     |
    |         |           1 = Sprite in front of cross-hair              |
    |         |    D0: Joypad Data                                       |
    |         +———————————————————-+
    |         | WRITING:                                                 |
    |         | Expansion Port Latch (W)                                 |
    |         |                                                          |
    |         |    D0: Expansion Port Method                             |
    |         |           0 = ???                                        |
    |         |           1 = Read                                       |
    +———+———————————————————-+

+————-+
| 9. 文件格式 |
+————-+

  A. iNES 格式 (.NES)
  ——————-
    +——–+——+——————————————+
    | Offset | Size | Content(s)                               |
    +——–+——+——————————————+
    |   0    |  3   | ‘NES’                                    |
    |   3    |  1   | $1A                                      |
    |   4    |  1   | 16K PRG-ROM page count                   |
    |   5    |  1   | 8K CHR-ROM page count                    |
    |   6    |  1   | ROM Control Byte #1                      |
    |        |      |   %####vTsM                              |
    |        |      |    |  ||||+- 0=Horizontal mirroring      |
    |        |      |    |  ||||   1=Vertical mirroring        |
    |        |      |    |  |||+– 1=SRAM enabled              |
    |        |      |    |  ||+— 1=512-byte trainer present  |
    |        |      |    |  |+—- 1=Four-screen mirroring     |
    |        |      |    |  |                                  |
    |        |      |    +–+—– Mapper # (lower 4-bits)     |
    |   7    |  1   | ROM Control Byte #2                      |
    |        |      |   %####0000                              |
    |        |      |    |  |                                  |
    |        |      |    +–+—– Mapper # (upper 4-bits)     |
    |  8-15  |  8   | $00                                      |
    | 16-..  |      | Actual 16K PRG-ROM pages (in linear      |
    |  …   |      | order). If a trainer exists, it precedes |
    |  …   |      | the first PRG-ROM page.                  |
    | ..-EOF |      | CHR-ROM pages (in ascending order).      |
    +——–+——+——————————————+

+——————-+
| 10. 为NES设计程序 |
+——————-+

  A. 一般信息
  ———–
    无.

 

  B. CPU 注意事项
  —————
     无. 阅读 Section 11, Subsection B 以获得更多信息.

  C. PPU 注意事项
  —————
     读写 VRAM 由一组处理过程组成:

      Writing to VRAM                    Reading from VRAM
      —————                    —————–
      1) Wait for VBlank                 1) Wait for VBlank
      2) Write upper VRAM address        2) Write upper VRAM address
         byte into $2006                    byte into $2006
      3) Write lower VRAM address        3) Write lower VRAM address
         byte into $2006                    byte into $2006
      4) Write data to $2007             4) Read $2007 (invalid data once)
                                         5) Read data from $2007

     注意: 读VRAM的步骤 #4 只有在 读VRAM数据不再 $3F00-3FFF 范围时才必要.

     注意: 访问 VRAM 只有在 VBlank 时才被执行. 尝试不在 VBlank 中访问 VRAM 将导致屏幕上出现垃圾. 阅读 Section
           4, Subsection N 以获得关于这样的现象发生的信息.

     等待 VBlank 是很简单的:

       8000 : LDA $2002
              BPL $8000

     读 $2002 将导致所有位被返回; 然而, 在读执行后,D7将被重置为0.

     就像前面说过的一样,事实上NES在屏幕上显示的调色板不是RGB. 然而,近似精确的代替品可以在通常的NES模拟器中找
     到. 联系合适的模拟器作者以获得一个正确的RGB调色板.

     确保不经常地通过 $2006 清空内部 VRAM 地址. 你会经常遇到由于调色板退色或者 VRAM 更新导致的显示器 "出现垃
     圾" (显示器上有方块,或者看起来像图形 "小故障" 的情况). 这种情况的原因是你的代码花费的时间比 VBlank 长. 
     当 VBlank 通过 PPU 中的数据刷新显示器时,它读取所有的内部 VRAM 地址,并且把它们作为 Name Table #0 的开始.
     解决方法是修改你的代码以重新指派 VRAM 地址到 $0000 (或者 $2000),这样刷新将成功. 代码可以是:

       LDA #$00
       STA $2006
       STA $2006

     你将在商业游戏经常发现这样的代码.

 

+————+
| 11. 模拟器 |
+————+

  A. 一般信息
  ———–
     如果你准备用 C 或 C++ 编写模拟器,请熟悉指针. 熟悉指针将在处理镜像和 VRAM 地址时对你有很大帮助. 如果你在
     这方面非常迷惑,很明显的指针只不过是间接地址 — 它比在全部的 64K 数据交换更容易改变 32-bit 值.

     如果 SRAM ($6000-7FFF) 被禁用了,程序将忽略对这段内存的写入. 读入时将返回 总线 [bus] 上先前留下的数据,因
     此,模拟器将返回 0 (或者被 中断 [be trapped]).

     以 RAM 为基础的内存区域 ($0000-07FF) 在重置时 *不* 应当被置为 0; 它们应当在开关机时被设置为 0. (技术上说,
     the RAM is not zeroed on power on/off either: the RAM will slowly dissapate over time when the unit it
     off. 然而,对于一个模拟器来说,请确保冷启动和热启动做不同的事情).

     阅读 Section 12, Subection E 以获得邮件列表信息.

  B. CPU 注意事项
  —————
     NES不使用传言中的 65c02 (CMOS) CPU.

     忽略 bad opcodes (或者支持选项来捕获它). 一些 ROM 在这方面非常典型,例如 "Adventures of Lolo" 包含 bad 
     opcodes,这是由于在析取处理时 cartridge 上的拙劣的连接器所导致 (或者其他原因).

     (在总共256个 opcodes之外) NES中有154个正确的 opcodes.

  C. PPU 注意事项
  —————
     计算 Name Table 中马赛克数目的基本地址的公式是:

       (TILENUM * 16) + PATTERNTABLE

     TILENUM 是 Name Table 中的马赛克数目,PATTERNTABLE 是经由寄存器 $2000 定义的 Pattern Table Address.

     推荐 DOS 程序员使用 被称为 "MODE-Q" 的,一个 256×256x256 "tweaked" 视频模式来写模拟器. 尽量避免 Mode-X 模
     式,虽然它们不是链式的,但却导致慢的痛苦的图形处理.  链式模式 (像 MODE-13h) 是线性的,对高速图形工作很好.
     虽然 NES 分辨率是 256×240,但是上述册 "MODE-Q" 市和所有合适的需求.

     大多数模拟器不限制统一扫描线上的子图形个数,然而真正的 NES 在同一线上超过八 (8) 个子图形时会有低速闪烁。
     {放更多的垃圾在这里; 很容易…}

     模拟器 _不应当_ 屏蔽未使用的寄存器; 这样做将导致 cart 不工作.

  D. APU 注意事项
  —————
     To be written.

 

+————–+
| 12. 引用材料 |
+————–+

  A. CPU Information
  ——————
    None.

  B. PPU Information
  ——————
    None.

  C. APU Information
  ——————
    None.

  D. MMC Information
  ——————
    None.

  E. Mailing Lists
  —————-
    There is a NES Development Mailing List in existence. Contact Mark Knibbs
    for more information. This list is for anyone who wishes to discuss tech-
    nical issues about the NES; it is not a list for picking up the latest
    and greatest information about NES emulators or what not.

  F. WWW Sites
  ————
    The following are a list of WWW sites which contain NES-oriented
    material. If you encounter errors, bad links, or other anomolies
    while visiting these sites, contact the site authors/owners, NOT
    me. Thanks.

    http://nesdev.parodius.com/

      Contains a verbose amount of documentation regarding anything
      NES-oriented, including hard-to-find mapper documentation. Seems
      to be a decent NES information depository.

    http://www.ameth.org/~veilleux/NES_info.html

      Currently only contains hardware-oriented material, such as
      overviews of cart and unit ASICs, mappers, and MMCs. Many
      pinout diagrams for mappers and NES units are available here.
      Also provides documentation on NES repair, modifying your NES
      to give stereo output, applying stereo mixing to your NES, and
      much much more.

  G. Hardware Information
  ———————–
    The following security bits may be purchased from MCM Electronics
    (
http://www.mcmelectronics.com/):

      For NES carts: 22-1145 (3.8mm security bit)
      For NES units: 22-1150 (4.5mm security bit)

    The 4.5mm security screw is also used for the Super Nintendo Enter-
    tainment System (SNES), and Nintendo 64.

*Translated by 天之川 (Blue Potato) [bspotato@yahoo.com.cn] [http://bspotato.51.net]*
*虽然已经尽全力翻译了,不过还是会有很多不恰当的地方. 如果你有很好的建议,请发信到上面的信箱中. 非常感谢*
*Chinese Edition Version: V1*

0
Apr
30
2005

[转]任天堂FBASIC的指令系统

任天堂FBASIC的指令系统


   一、直接指令

   1、CLEAR规定BASIC的使用内存,消除所有内存中的变量

   2、NEW消除BASIC程序及其变量

   3、LIST将内存中程序按行号大小列出于屏幕上

   4、RUN执行内存中的程序

   5、CONT 继续执行被中断的程序

   6、LOAD 从录音机磁带中读程序入内存

   7、SAVE 将程序资料写入录音机磁带

   8、LOAD ?校对磁带中的程序

   二、一般指令

   9、=给变量赋值

   10、PRINT 打印计算结果或数据资料

   11、INPTU 从键盘读入数据资料

   12、LINPUT 读取下整行的数据,包括“,”号

   13、DIM 定义下标变量

   14、GOTO 无条件跳转

   15、GOSUB 调用子程序

   16、RETURN 由子程序返回BOSUB处的主程序

   17、IF~THEN 条件转移

   18、FOR~TO~STEP NEXT 循环语句

   19、ON 随变量的值不同而跳转不同的子程序

   20、STOP 中断被执行程序

   21、CLEAR 清除内存变量

   22、END 使程序停止执行

   23、SWAP 将两个变量的内容互换

   24、REM 注释指令

   25、READ 读取DATA语句中的数据

   26、DATA 数据指令

   27、RESTORE 指定READ语句的读指针

   28、POKE 将数据写入内存单元或软开关

   三、特殊功能指令

   29、KEY 设定F1~F8功能键

   30、KEYLIST 显示功能键的定义状态

   31、PAUSE 暂停程序的执行

   32、SYSTEM 从BASIC状态返回原始状态

   33、VIEW 调出BG GRAPHIC画面

   34、BEEP 使电视发出蜂鸣声

   35、PLAY 演奏音乐指令

   四、函数指令

   36、ABS 绝对值函数

   37、SGN 符号(+1,-1,0)判别函数

   38、RND 随机函数

   39、ASC 将写符转换成ASCⅡ码

   40、CHR$ 将ASCⅡ码转换成字符串

   41、VAL 将16进制数转换成10进制数

   42、STR$ 将10进制数转换成字符串

   43、HEX$ 将10进制数转换成16进制数

   44、LEFT$ 从字符串左边读取字符

   45、RIGHT$ 从字符串右边读取字符

   46、MID$ 从字符串中间读取字符

   47、LEN 计算字符串长度

   48、PEEK 读取内存单元中的值

   49、POS 读取光标的水平位置值

   50、FRE 读取内存半日元的空余数目

   51、STICK 读取手柄的上下左右键值

   52、STRIG 读取手柄的SELE、STAR、A、B值

   53、CSRLIN 读取兴标的垂直位置值

   54、SCR$ 读取BG GRAPHIC画面中的数据

   55、INKEY$ 读取键盘输入的值

   五、画面控制语句

   56.LOCATE 设定显示位置的座标

   56.COLOCK 设定显示位置的颜色

   58.CGEN 决定背景面和动画面的角色分配

   59.CLS 清除屏幕中的数据

   60.CGSET 规定背景或动画面的颜色组合

   61.PALET 重新配色指令。可从64种颜色中调出32种

   62.DEF MOVE卡通的动作系列

   63.MOVE 使卡通行动

   64.ERA 令卡通停止并消失

   65.CUI 令卡通停止但不消失

   66.POSITION 定义卡通的座标

   67.XPOS 求卡通的水平座标值

   68.YPOS 求卡通的垂直座标值

   69.MOVE(n) 判断卡通动作是否完成

   70.DEF SPRITE 定义卡通的号码

   71.SPRITE 将卡通显示出来或消失

   72.SPRITE ON 将卡通画面叠加于背景画上

   73.SPRITE OFF 终止卡通画面的显示

   74.VCT 求卡通的运行方向

   六、未公布的指令

   75.INSTR 检索子符串在别一字符串中的位置

   76.ONERROR 设置错误转移入口

   77.ERL 给出错误语句的行号

   78.RESUME 错误处理程序返回

   79.TRON 设置程序为跟踪状态

   80.TROFF 解除跟踪

   81.AUTO 自动给出行号

   82.DELETE 删除部分行号

   83.RENUM 重编行号

   84.BGTOOL 调用BG画面

   85.FIND 查找指令

   86.GAME 调出4个BASIC程序

   87.SCREEN 设定屏幕显示格式

   88.FILTER 设定颜色的深浅

   89.CRASH 判断卡通是否相遇

   90.CAN 令卡通消失并中断程序

0
Apr
20
2005

[转] DEBUG命令详解

 Debug 原意是杀虫子。这里是机器调试工具。
    其实,Debug的由来,还有一则趣闻,在早期美国的一计算机房中,科学家正在紧张的工作。同时,许多台大型的计算机也在不停的运行着。大概是由于,机器过热,引来许的小虫子,以至于,计算机无法正常运行。科学们,只好停下来,捉虫子…虫子捉完了,计算机运行也正常了,后来,这个名词就沿用至今了….
  虽然,现在好的软件越来越多了,但是有些,我们只需动手,用Debug就可解决,且快而好!接下来,我们就一起学习Debug在各方面的运用吧!(在杀毒、加解密、系统…)下面我和大家一起学习一些,Debug的用法,虽然,现在好的软件越来越多了,但是有些,我们只需动手,用Debug就可解决,且快而好!
  
  Debug常用命令集
   
  名称 解释 格式
  a (Assemble) 逐行汇编 a [address]
  c (Compare) 比较两内存块 c range address
  d (Dump) 内存16进制显示 d [address]或 d [range]
  e (Enter) 修改内存字节 e address [list]
  f (fin) 预置一段内存 f range list
  g (Go) 执行程序 g [=address][address...]
  h (Hexavithmetic) 制算术运算 h value value
  i (Input) 从指定端口地址输入 i pataddress
  l (Load) 读盘 l [address [driver seetor>
  m (Move) 内存块传送 m range address
  n (Name) 置文件名  n filespec [filespec...]
  o (Output) 从指定端口地址输出 o portadress byte
  q (Quit) 结束  q
  r (Register) 显示和修改寄存器 r [register name]
  s (Search) 查找字节串  s range list
  t (Trace) 跟踪执行  t [=address] [value]
  u (Unassemble) 反汇编 u [address ]或range
  w (Write) 存盘  w [address[driver sector secnum>
  ? 联机帮助 ?
  
  debug小汇编a命令
  
  debug小汇编a命令是一个很有用的功能,许多的小程序都要他来做。
  
  编一些小程序比汇编要来得方便,快洁。
  在Debug中,中断是非常有用的,首先,让我们先了解一下中断。
    所谓中断,其实,就是,当你做某事时,有人过来找你有其他事,你先放下手中的事(计算机中,称为保护现场)
  ,再去与叫你的那个人办事去,等完了,你又回,接着做刚才的事。这是个很通俗的讲法。
    计算机在运行时,也会出现这种情况,我们叫之中断。
    下面是他的一些常用中断向量的入口值详解:(记住哦,很用的...呵呵)
  
  
  
  
  IBM PC 中断 int10
  ooH 屏幕方式设置
  
  入口:AH=0,AL=显示方式代码(0--6)
     0:40*25 黑白  
     1:40*25 彩色
     2:80*25 黑白
     3:80*25 彩色文本
     4:320*200 彩色
     5:320*200 黑白
     6:640*200 黑白图形模式
     7:80*25 单色字符(单色显示器) 
  
  0BH 色彩设置
  入口:AH=0B,BL=0 设背景色,BH=0--15  BL=1 设调色码,BH=0--1
  0CH 写图形点
  入口:AH=0C,CX:DX=列号:行号,AL=颜色
  ODH 读图形点
  入口:AH=0D,CX:DX=列号:行号
  返回:AL=颜色
  0EH 在当前页、当前光标处写字符
  入口:AH=0E,AL=字符的ASCII码,BL=前景色
  OFH 显示器状态
  入口:AH=0F
  返回:AL=当前显示器方式,AH=屏幕列数,BH=当前页号
  
  01H 光标设置
  入口:AH=1,CH=光标起始行号(00--0C),CL=光标结束行号(00--0C)
  注:CH > CL
  02H 光标定位
  入口:AH=2,BH=页号,DH:DL=起始行:列
  03H 读光标位置
  入口:AH=3,BH=页号。
  返回:DH:DL=起始行:列
  06H 窗口上卷
  入品:AH=6,AL=窗口上卷行数,CH:CL-DH:DL 窗口坐标
  注:AL=0 卷动整个窗口
  07H 窗口下卷
  入口:AH=7,AL=窗口下卷行数,CH:CL-DH:DL 窗口坐标
  08H 读当前光标处字符和属性
  入口:AH=8,BH=页号。
  返回:AH:AL=字符的颜色:字符的ASCII码
  注:颜色代码见下对照表
  09H:在当前光标处写字符和属性
  注:光标不下移
  入口:AH=9,BH=页号,BL:AL=字符的颜色:字符的ASCII码,CX=重复次数
  1 2 3 4 5 6 7 8
  BL R G B I R G B
  闪烁 字符底色 加亮 字符颜色
  
  中断向量号表
  
  中断号 解释 中断号 解释
  0 除数为0错 19 引导装入程序
  1 音步中断 1A 日时调用
  2 不可屏蔽中断NMI 1B 键盘阻断时得到控制权
  3 断电中断(CCH) 1C 时钟中断时得到控制权
  4 溢出中断 1D 指向CRT初始参数表
  5 屏幕打印中断 1E 指向盒带参数表
  6-7 保留 1F 1KB图形模式
  8 计时器中断(18.2秒) 20 结束DOS程序
  9 键盘中断 21 DOS功能调用
  A-D 保留 22 结束地址(建义用EXEC)
  E 软盘机中断 23 DOS Crtl-Break退出地址
  F 保留 24 DOS致命错向量
  10 屏幕I/O调用 25 DOS绝对磁盘读
  11 设备检查调用 26 DOS绝对磁盘写
  12 存储器检查调用 27 结束程序并驻留(建义用31h)
  13 软盘机I/O调用 28-3F DOS保留
  14 RS-233I/O调用 40-7F 未用
  15 盒带机I/O调用 80-85 BASIC保留
  16 键盘I/O调用 86-F0 BASIC解释程序用
  17 打印机I/O调用 F1-FF 未用
  18 ROM-BASIC入口
  
  
  指令名详解
  call 指令(过程调用)(控制指令-长转移)
  
  详解:
  
  段内直接调用
  
  段内间接调用(寄存器)
  
  段内间接调用(存储器)
  
  段间直接调用
  
  段间间接调用
  
  指令名
  jmp 指令(无条件转移指令)(控制指令-长转移)
  
  详解:
  段内直接跳转
  
  短段内直接跳转
  
  段内间接跳转(寄存器)
  
  段内间接跳转(存储器)
  
  段间直接跳转
  
  段间间接跳转
  
  指令名
  ret 指令(过程返回)(控制指令-长转移)
  
  详解:
  
  段内返回
  
  段内返回立即数加于sp
  
  段间返回
  
  段间返回立即数加于sp
  
  na/jnbe 指令(控制指令-短转移)   不小于或不等于时转移
  
  jae/jnb 指令 (控制指令-短转移)   大于或等于时转移
  
  jb/jnae 指令 (控制指令-短转移)   小于转移
  
  jbe/jna 指令 (控制指令-短转移)   小于或等 于转移
  
  jg/jnle 指令(控制指令-短转移)   大于转移
  
  jge/jnl 指令 (控制指令-短转移)   大于或等于转移
  
  jl/jnge 指令 (控制指令-短转移)   小于转移
  
  jle/jng 指令 (控制指令-短转移)   小于或等 于转移
  
  je/jz 指令 (控制指令-短转移)   等于转移
  
  jne/jnz 指令 (控制指令-短转移)   不等于转移
  
  jc 指令 (控制指令-短转移)   有进位时转移
  
  jnc 指令 (控制指令-短转移)   列进位时转移  
  jno 指令 (控制指令-短转移)   不溢出时转移
  jnp/jpo 指令 (控制指令-短转移)   奇偶性为奇数时转移
  
  jns 指令 (控制指令-短转移)   符号位为"0"转移
  
  jo 指令 (控制指令-短转移)   溢出转移
  
  jp/jpe 指令 (控制指令-短转移)   奇偶性为偶数时转移
  
  js 指令 (控制指令-短转移)   符号位为"1"时转移
  
  loop 指令 (循环控制指令-短转移)   cx 不为0时循环
  
  loope/loopz 指令 (循环控制指令-短转移)   cx 不为0且标志 z=1 时循环
   
  loopne/loopnz 指令 (循环控制指令-短转移)   cx 不为0且标志 z=0 时循环
  
  jcxz 指令 (循环控制指令-短转移)   cx 为0时转移
  
  ★int 指令 (中断指令)   中断指令(后详解)
  
  into 指令 (中断指令)   溢出中断
  
  iret 指令 (中断指令)   中断返回
  
  
  指令名
  shl 指令(逻辑左移)
  sal 指令(算术左移)
  shr 指令(逻辑右移)
  sar 指令(算术右移) 寄存器,1
  rol 指令(循环左移) 寄存器,cl
  ror 指令(循环右移) 存储器,1
  rcl 指令(通过进位的循环左移)存储器,cl
  rcr 指令(通过进位的循环右移)(逻辑运算)
  
  
  not 指令(取反运算)寄存器求反
  
  (逻辑运算)存储器求反
  
  and 指令(与运算) (逻辑运算)
   
  寄存器 and 寄存器 寄存器
  寄存器 and 存储器 寄存器
  
  存储器 and 寄存器 存储器
  
  立即数 and 存储器 存储器
  
  立即数 and 累加器 累加器
  
  or 指令(或运算)(逻辑运算)
  
  寄存器 or 寄存器 寄存器
  寄存器 or 存储器 寄存器
  
  存储器 or 寄存器 存储器
  
  立即数 or 存储器 存储器
  
  立即数 or 累加器 累加器
  
  test 指令(测试) (逻辑运算)
   
  寄存器 test 寄存器 
  寄存器 test 存储器
  寄存器 test 立即数
  存储器 test 立即数
  累加器 test 立即数
       
  movs 指令(串传送)(字符串操作指令)
  单个传送
  重复传送
       
  cmps 指令(串比较) (字符串操作指令)
  单个比较
  重复比较
       
  scas 指令(串扫描)(字符串操作指令)
  单个搜索
  重复搜索
       
  lods 指令(装入串)
  (字符串操作指令)
  单个装载
  重复装载
       
  stos 指令(保存串) (字符串操作指令)
  单个存储
  重复存储
  
  mov 指令(传送字或字节)(数据传送命令) 
  寄存器与寄存器间传送
  存储器与寄存器间传送
  立即数传送给存储器
  立即数传送给寄存器
  存储器传送给累加器
  累加器传送存储器
  寄存器传送给段寄存器
  存储器传送给段寄存器
  段寄存器传送给寄存器
  段寄存器传送给存储存器
       
  pop 指令(把字弹出堆栈) (数据传送命令)
  
  push 指令(把字压入堆栈)  
  存储器
  寄存器
  段寄器     
  xchg 指令(交换字或字节) (数据传送命令)  
  寄存器与寄存器交换
  存储器与寄存器交换
  寄存器与累加器交换
     
  in 指令(端口输入) (数据传送命令)
  直接输入
  间接输入
       
  out 指令(端口输出) (数据传送指令)  
  直接输出
  间接输出
       
  add 指令(加法)(算术指令)
  adc 指令(带进位加法)  
  寄存器+寄存器 寄存器
  寄存器+存储器 寄存器
  存储器+寄存器 存储器
  立即数+存储器 存储器
  立即数+累加器 累加器
       
  inc 指令(加1)(算术指令)  
  存储器增量
  寄存器增量
       
  sub 指令(减法) (算术指令)
  sbb 指令(带借位减法)  
  寄存器-寄存器 寄存器
  寄存器-存储器 寄存器
  存储器-寄存器 存储器
  立即数-存储器 存储器
  立即数-累加器 累加器
       
  dec 指令(减1)(算术指令)  
  存储器减量
  寄存器减量
       
  nec 指令(求反,以0减之)  
  寄存器求补
  存储器求补
       
  cmp 指令(比较)(算术指令)  
  寄存器与寄存器比较
  寄存器与存储器比较
  寄存器与立即数比较
  存储器与立即数比较
  累加器与立即数比较
       
  mul 指令(无符号乘法) (算术指令)
  imul 指令(整数乘法)  
  与8位寄存器相乘
  与16位寄存器相乘
  与8位存储单元相乘
  与16位存储单元相乘
       
  div 指令(无符号除法)(算术指令)
  idiv 指令(整数除法)  
  被8位寄存器除
  被16位寄存器除
  被8位存储单元除
  被16位存储单元除
  
  
  Debug实战
  1.查看主板的生产日期,版本
  D ffff:05
  D fe00:0e
  
  2.模拟Rest键功能
  A
  :100 jmp ffff:0000
  :105
  g
  
  3.快速格式化软盘
  L 100 0 0 * '插入一张己格式化软盘
  W 100 0 0 * '放入一张欲格式化软盘
  注:* 分别为:720K e |1.2M id |1.44M 21 
  
  4.硬盘格式化两种方法
  (1)G=c800:05
  (2) A 100
  mov ax,0703
  mov cx,0001
  mov dx,0080
  int 13
  int 3
  g 100
  5.加速键盘
  A 
  mov ax,0305
  mov bx,0000
  int 16
  int 20
  rcx
  10
  n fast.com
  w
  q
  
  6.关闭显示器(恢复时,按任意键)
  
  A
  mov ax,1201
  mov bl,36
  int 10
  mov ah,0
  int 16
  mov ax,1200
  int 10
  rcx
  10
  n crt-of.com
  w
  q
  7.硬盘DOS引导记录的修复
  在软驱中放入一张己格式化软盘
  debug
  -l 100 2 0 1
  -w 100 0 50 1
  把软盘放入故障机软驱中
  debug
  -l 100 0 50 1
  -w 100 2 0 1
  -q
  8.清coms中setup口令
  debug
  -a
  mov bx,0038
  mov cx,0000
  mov ax,bx
  out 70,al
  inc cx
  cmp cx,0006
  jnz 0106
  int 20
  -rcx
  :20
  -nclearpassword.com
  -w
  -q
  注:以上适合super与dtk机,对于ast机,因为他的口令放在coms的4ch-51h地址处,只要将:mov bx,0038 改为: mov
  bx,004c即可
  9.取消coms的密码(将coms数据清为初始化)
  -o 70,10
  -o 71,10
  -g
  -q
  10.将硬盘主引导记录保存到文件中
  
  debug
  -a
  mov ax,0201
  mov bx,0200
  mov cx,0001
  mov dx,0080
  mov int 13
  int 3
  -rcx
  :200
  -nboot.dat
  -w
  -q 
  11.调用中断实现重启计算机(可以成文件)
  debug
  -a
  int 19
  int 20
  -rcx
  :2
  -nreset.com
  -w
  -q
  
  
  
  
  DEBUG主要命令
  
  DEBUG是为汇编语言设计的一种高度工具,它通过单步、设置断点等方式为汇编语言程序员提供了非常有效的调试手段。
  一、DEBUG程序的调用
  在DOS的提示符下,可键入命令:
  C:\DEBUG [D:][PATH][FILENAME[.EXT>[PARM1][PARM2]
  其中,文件名是被调试文件的名字。如用户键入文件,则DEBUG将指定的文件装入存储器中,用户可对其进行调试。如果未键入文件名,则用户可以用当前存储器的内容工作,或者用DEBUG命令N和L把需要的文件装入存储器后再进行调试。命令中的D指定驱动器PATH为路径,PARM1和PARM2则为运行被调试文件时所需要的命令参数。
  在DEBUG程序调入后,将出现提示符,此时就可用DEBUG命令来调试程序。
  二、DEBUG的主要命令
  1、显示存储单元的命令D(DUMP),格式为:
  _D[address]或_D[range]
  例如,按指定范围显示存储单元内容的方法为:
  -d100 120
  18E4:0100 c7 06 04 02 38 01 c7 06-06 02 00 02 c7 06 08 02 G…8.G…..G…
  18E$:0110 02 02 bb 04 02 e8 02 00-CD 20 50 51 56 57 8B 37 ..;..h..M PQVW.
  7
  18E4:0120 8B
  其中0100至0120是DEBUG显示的单元内容,左边用十六进制表示每个字节,右边用ASCII字符表示每个字节,·表示不可显示的字符。这里没有指定段地址,D命令自动显示DS段的内容。如果只指定首地址,则显示从首地址开始的80个字节的内容。如果完全没有指定地址,则显示上一个D命令显示的最后一个单元后的内容。
  2、修改存储单元内容的命令有两种。
  ·输入命令E(ENTER),有两种格式如下:第一种格式可以用给定的内容表来替代指定范围的存储单元内容。命令格式为:
  -E address [list]
  例如,-E DS:100 F3′XYZ’8D
  其中F3,’X',’Y',’Z'和各占一个字节,该命令可以用这五个字节来替代存储单元DS:0100到0104的原先的内容。
  第二种格式则是采用逐个单元相继修改的方法。命令格式为:
  -E address
  例如,-E DS:100
  则可能显示为:
  18E4:0100 89.-
  如果需要把该单元的内容修改为78,则用户可以直接键入78,再按"空格"键可接着显示下一个单元的内容,如下:
  18E4:0100 89.78 1B.-
  这样,用户可以不断修改相继单元的内容,直到用ENTER键结束该命令为止。
  ·填写命令F(FILL),其格式为:
  -F range list
  例如:-F 4BA:0100 5 F3′XYZ’8D
  使04BA:0100~0104单元包含指定的五个字节的内容。如果list中的字节数超过指定的范围,则忽略超过的项;如果list的字节数小于指定的范围,则重复使用list填入,直到填满指定的所有单元为止。
  3)检查和修改寄存器内容的命令R(register),它有三种格式如下:
  ·显示CPU内所有寄存器内容和标志位状态,其格式为:
  -R
  例如,-r
  AX=0000 BX=0000 CX=010A DX=0000 SP=FFFE BP=0000 SI=0000 DI=0000
  DS=18E4 ES=18E4 SS=18E4 CS=18E4 IP=0100 NV UP DI PL NZ NA PO NC
  18E4:0100 C70604023801 MOV WORD PTR [0204],0138 DS:0204=0000
  ·显示和修改某个寄存器内容,其格式为:
  -R register name
  例如,键入
  -R AX
  系统将响应如下:
  AX F1F4
  :
  即AX寄存器的当前内容为F1F4,如不修改则按ENTER键,否则,可键入欲修改的内容,如:
  
  -R bx
  BX 0369
  :059F
  则把BX寄存器的内容修改为059F。
  ·显示和修改标志位状态,命令格式为:
  -RF系统将响应,如:
  OV DN EI NG ZR AC PE CY-
  此时,如不修改其内容可按ENTER键,否则,可键入欲修改的内容,如:
  OV DN EI NG ZR AC PE CY-PONZDINV
  即可,可见键入的顺序可以是任意的。
  4)运行命令G,其格式为:
  -G[=address1][address2[address3…>
  其中,地址1指定了运行的起始地址,如不指定则从当前的CS:IP开始运行。后面的地址均为断点地址,当指令执行到断点时,就停止执行并显示当前所有寄存器及标志位的内容,和下一条将要执行的指令。
  5)跟踪命令T(Trace),有两种格式:
  ·逐条指令跟踪
  -T [=address]
  从指定地址起执行一条指令后停下来,显示所有寄存器内容及标志位的值。如未指定地址则从当前的CS:IP开始执行。
  ·多条指令跟踪
  -T [=address][value]
  从指定地址起执行n条指令后停下来,n由value指定。
  6)汇编命令A(Assemble),其格式为:
  -A[address]
  该命令允许键入汇编语言语句,并能把它们汇编成机器代码,相继地存放在从指定地址开始的存储区中。必须注意:DEBUG把键入的数字均看成十六进制数,所以如要键入十进制数,则其后应加以说明,如100D。
  7)反汇编命令U(Unassemble)有两种格式。
  ·从指定地址开始,反汇编32个字节,其格式为:
  -U[address]
  例如:
  -u100
  18E4:0100 C70604023801 MOV WORD PTR[0204],0138
  18E4:0106 C70606020002 MOV WORD PTR[0206],0200
  18E4:010C C70606020202 MOV WORD PTR[0208],0202
  18E4:0112 BBO4O2 MOV BX,0204
  18E4:0115 E80200 CALL 011A
  18E4:0118 CD20 INT 20
  18E4:011A 50 PUSH AX
  18E4:011B 51 PUSH CX
  18E4:011C 56 PUSH SI
  18E4:011D 57 PUSH DI
  18E4:011E 8B37 MOV SI,[BX]
  如果地址被省略,则从上一个U命令的最后一条指令的下一个单元开始显示32个字节。
  ·对指定范围内的存储单元进行反汇编,格式为:
  -U[range]
  例如:
  -u100 10c
  18E4:0100 C70604023801 MOV WORD PTR[0204],0138
  18E4:0106 C70606020002 MOV WORD PTR[0206],0200
  18E4:010C C70606020202 MOV WORD PTR[0208],0202
  或
  -u100 112
  18E4:0100 C70604023801 MOV WORD PTR[0204],0138
  18E4:0106 C70606020002 MOV WORD PTR[0206],0200
  18E4:010C C70606020202 MOV WORD PTR[0208],0202
  
  可见这两种格式是等效的。
  8)命名命令N(Name),其格式为:
  -N filespecs [filespecs]
  命令把两个文件标识符格式化在CS:5CH和CS:6CH的两个文件控制块中,以便在其后用L或W命令把文件装入存盘。filespecs的格式可以是:
  [d:][path] filename[.ext]
  例如,
  -N myprog
  -L
  -
  可把文件myprog装入存储器。
  9)装入命令(Load),有两种功能。
  ·把磁盘上指定扇区范围的内容装入到存储器从指定地址开始的区域中。其格式为:
  -L[address[drive sector sector]
  ·装入指定文件,其格式为:
  -L[address]
  此命令装入已在CS:5CH中格式化了文件控制块所指定的文件。如未指定地址,则装入CS:0100开始的存储区中。
  10)写命令W(Write),有两种功能。
  ·把数据写入磁盘的指定扇区。其格式为:
  -W address drive sector sector
  ·把数据写入指定的文件中。其格式为:
  -W[address]
  此命令把指定的存储区中的数据写入由CS:5CH处的文件控制块所指定的文件中。如未指定地址则数据从CS:0100开始。要写入文件的字节数应先放入BX和CX中。
  11)退出DEBUG命令Q(Quit),其格式为:
  -Q
  它退出DEBUG,返回DOS。本命令并无存盘功能,如需存盘应先使用W命令。
  
  问题:初学者问一个低级问题,执行debug-a后,如果有一行输入错误,如何更改这一行?
  
  回答:
  加入进行如下输入:
  D:\PWIN95\Desktop>debug
  -a
  2129:0100movax,200
  2129:0103movbx,200
  2129:0106movcx,200
  2129:0109
  此时,发现movbx,200一句错误,应为movbx,20,可以敲回车返回"-"状态,然后输入:
  -a103
  2129:0103movbx,20
  如果多或者少若干行,不必重新输入,可以用M命令移动后面的程序来去掉或者增加程序空间。
0