zoukankan      html  css  js  c++  java
  • 【原创】NES第八波:怎么写一个HelloWorld

    这里我用的编辑工具还是6502Sim。

    第一步是确定容量:我写一个极短的汇编代码,16K容量就远远足够了。所以程序从$C000开始存放。图库大小也是最小就可以(即8K)。

    第二步是分派背景所在页和精灵所在页。不防定:背景=0页,精灵=1页。

    第三步是准备一个4K的背景用chr,和一个精灵用的chr。

    因为这次用不着显示精灵,所以精灵chr纯属是打酱油。不过也要用于填充,哪怕是4K的空白文件(字节要精确=4096)。

    背景用chr,要我们去制作了。可以从nes游戏里面分离出来(用yychr),也可以用我的字模工具制作。为了方便编程,大小字母和数字按放的位置可以依ascii的号码对应。也可以只做HeloWrd这几个字母。为了简化代码,本例只做8*8的字模。制作的方法,见《NES第五波》。

    注:YYCHR默认新建的文件有好几页。如果只想做一页,用我的字模工具,生成一个4K的就可以了。再用YYCHR打开,清空。另外再打开一个YYCHR,打开你想要chr。两个YYCHR可以互相粘贴。右键拉一个选框,就可以复制了。

    第四步是新建NES的文件头,用到我的工具NESInfo,见《NES第一波》。

    本例:mapper=0,PRG rom=1x16K,CHR rom=1x8K,镜像=水平,S-RAM=no,4屏=no,Trainer=no

    mapper:就是卡带的电路板分类号码。0代表最原始的电路板,即没有切页功能,也没有扩展功能。

    PRG rom:就是指程序空间的容量,匹配mapper0的容量就是1x16K和2x16K。有一个定律就是程序末尾必然在地址$FFFF。所以1X16K就是程序从$C000开始存放,2x16K就是程序从$8000开始存放。

    CHR rom:就是指图库空间的容量,匹配mapper0的容量就是1x8K。对应的地址是ppu$0000到ppu$1FFF

    镜像:指PPU的背景页,机内只有2页容量,但有4页地址,那么就会形成镜像。PPU的A10和A11连到卡带,由卡带对这两线的接线方式,决定镜像方式(水平或垂直)。

    水平镜像,指0页(ppu$2000)与1页(ppu$2400)镜像,那么可以进行2屏的垂直滚屏(即0页与2页(ppu$2800)都是可编辑的,可以连起来。)。2页与3页镜像,同理。

    垂直镜像,指0页与2页镜像,那么可以进行2屏的水平滚屏(即0页与1页(ppu$2400)都是可编辑的,可以连起来。)。1页与3页镜像,同理。

    PPU的背景页分布应该是这样的:

    【0页ppu$2000】【1页ppu$2400】
    
    【2页ppu$2800】【3页ppu$2B00】

    (不是说镜像页就不能编辑,而是没必要编辑,因为无论改哪面都是两面一起变的。)

    S-RAM:指卡带上是否增加一块电池维持的内存(地址在$6000到$7FFF)。模拟器会因为它而生成一个nes扩展文件。

    4屏:指卡带上是否增加ppu的两个背景页,那就不存要镜像了,前面“镜像”选项就无效。

    Trainer:原意教练,这里指卡带上是否增加一块512字节的ROM(地址在$5E00到$5FFF),选这个项的话,连接时要在文件头与PRG rom之间加一块512字节的Bin文件。有点麻烦,还是选no就好了。

    NESInfo,可以生成bin文件,也可以对bin文件直接编辑。所以修改还是很方便的。我们用NESInfo,生成一个Head.bin。即nes文件头bin。

    第五步写代码。因为代码的编幅太长,讲解代码我放在最后讲。编译工具,我用6502Sim。我选一个汉化版的,有高亮语法显示,有没有写错指令,一眼就知道。

    写好代码之后按“仿真”-“汇编F7”。如果没有报错,窗框一闪就关了,说明Pass。可以输出bin。

    按菜单“文件”-“保存代码Ctrl+K”;保存类型选"二进制映像.65b";然后一定要点“选项”;在代码地址栏的“开始于”=0xC000,这一项必须确认,这就是第一步选定的地址;确定;编辑文件名,保存。

    本例保存到代码的上一层文件夹,与head.bin、xx.chr等放一起,文件名:main.65b

    第六步连接。用DOS指令copy /b 将多个文件首尾连成一个新文件。批文件bat是文本文件,可以由记事本打开。学着写就行。

    必须注意的是,不能写错文件名。

    保存编辑好的批文件。双击批文件,我加了一句暂停指令,你要看清显示的结果,凡是写错文件名的,都没有显示出来,也就没有连接到nes文件里,但是没有报警的。所以必须看清楚了。

    6502源代码:

      1 ;开始地址:$c000
      2 ;结束地址:$ffff
      3 ;文件长度:$4000
      4 ; prg rom = 16K
      5 
      6         ;.start  reset
      7         .ORG    $C000
      8 reset:
      9     ; 默认启动代码
     10         SEI             ; 禁用中断
     11         CLD               
     12         LDX     #$ff    ; 初始化栈顶指针到$FF
     13         TXS
     14 
     15         ; 初始化内存
     16         INX        ; x=0了
     17 _loop_1:        ; 清理全部内存
     18     STA $00,x
     19     STA $0100,x
     20     STA $0200,x
     21     STA $0300,x
     22     STA $0400,x
     23     STA $0500,x
     24     STA $0600,x
     25     STA $0700,x
     26     INX
     27     BNE _loop_1
     28     
     29     ; PPU热机,大约要2帧的时间
     30 _vb1:            ; 1帧
     31         BIT $2002
     32         BPL _vb1
     33 _vb2:            ; 2帧
     34         BIT $2002
     35         BPL _vb2
     36             ; 以下可以对PPU操作了。
     37 
     38     ; 初始化PPU
     39         LDA #$00    ; 关屏
     40         STA $2001
     41 
     42     LDA #$3F    ; 写入配色盘(从0号盘开始)
     43     STA $2006
     44     LDA #$00
     45     STA $2006
     46     LDA #$0F    ;0#=黑色
     47     STA $2007
     48     LDA #$30    ;1#=白色
     49     STA $2007
     50     LDA #$2B    ;2#=浅蓝色
     51     STA $2007
     52     LDA #$15    ;3#=红色
     53     STA $2007
     54             ;...可以继续写入1号2号和3号盘。各4个字节。
     55             
     56     LDA #$20    ; 清除背景2000-23FF即0页背景。
     57     STA $2006
     58     LDA #$00
     59     STA $2006
     60     LDY #$04
     61 _loop_ppu_1:
     62     LDX #$00
     63     LDA #$00
     64 _loop_ppu_2:
     65     STA $2007
     66     DEX
     67     BNE _loop_ppu_2
     68     DEY
     69     BNE _loop_ppu_1
     70     
     71 _vb3:            ; 凑足够一帧
     72     BIT $2002
     73     BPL _vb3
     74 
     75         ; 设置PPU的工作方式  
     76         LDA #$08    ; (D7=0)禁nmi中断,
     77                 ; (D5=0)精灵=8*8,(D6=x)
     78                 ; (D4=0)图库:背景用0页,
     79                 ; (D3=1)图库:精灵用1页,
     80                 ; (D2=0)PPU写入自动+1,
     81                 ; (D1D0=00)命名表=2000
     82         STA $2000
     83             ; 开屏,也是正式设置PPU的显示方式
     84         LDA #$08    ; (D7D6D5=000)底色=黑
     85                 ; (D4=0)不显示精灵
     86                 ; (D3=1)显示背景(开屏)
     87                 ; (D2=0)左8列像素不显示精灵,可以将精灵藏在其中
     88                 ; (D1=0)左8列像素不显示背景,可用来做滚屏
     89                 ; (D0=0)显示模式=彩色
     90         STA $2001
     91 
     92 main:
     93     ; 黑屏,这样写入才不会花屏。如果动态写入要用中断。
     94     LDA #$00
     95     STA $2001
     96     
     97     ; 确定位置在$2021(即第2行的第2列);注,从$2000开始,每行32个图块
     98     LDA #$20
     99     STA $2006
    100     LDA #$21
    101     STA $2006
    102     
    103     ; 写入显示的内容
    104     ; 本例chr的字母是ascii的序号排的,所以这小字与ascii相符。
    105     LDA #$48    ; H
    106     STA $2007
    107     LDA #$65    ; e
    108     STA $2007
    109     LDA #$6c    ; l
    110     STA $2007
    111     LDA #$6c    ; l
    112     STA $2007    
    113     LDA #$6F    ; o
    114     STA $2007
    115     LDA #$57    ; W
    116     STA $2007
    117     LDA #$6F    ; o
    118     STA $2007
    119     LDA #$72    ; r
    120     sta $2007    
    121     LDA #$6c    ; l
    122     STA $2007
    123     LDA #$64    ; d
    124     STA $2007
    125     
    126     LDA #$00    ; 复位PPU的显示位置(对应0页($2000)背景就是(0,0))
    127     STA $2005
    128     STA $2005
    129     
    130     LDA #$08
    131     STA $2001
    132 end:
    133         JMP end
    134         
    135 
    136 nmi:
    137         RTI
    138 
    139 irq:
    140         RTI
    141 
    142 
    143         .ORG $fffa
    144         .DW nmi,reset,irq

    工程到我的网盘找。维京的梦 (ys168.com)

    续。。找个时间再续写代码的解析。

  • 相关阅读:
    nconf修改密码
    快速清空一个文
    freebsd安装snmp
    -bash: mail: command not found
    重置Cacti密码
    cacti添加被监控机全过程
    cacti图形字符乱码
    博客链接
    tar命令详解
    MainPresenter 实现类
  • 原文地址:https://www.cnblogs.com/fogota/p/15088175.html
Copyright © 2011-2022 走看看