前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >VM技术(三)开始FC模拟器(一)

VM技术(三)开始FC模拟器(一)

作者头像
Pulsar-V
发布2019-08-02 09:34:50
9030
发布2019-08-02 09:34:50
举报
文章被收录于专栏:Pulsar-V

概述 依照前面CHIP8的基础,接下来我们想办法去构建FC模拟器,首先从CPU的模拟入手,FC的处理器有132条指令,下面我们先给出指令集的相关表,在下几章中,我们再来对每一个指令进行一一实现。

6502CPU

基本指令

1

2

3

4

5

6

7

8

9

10

11

12

13

14

ADC

AND

ASL

BCC

BCS

BEQ

BIT

BMI

BNE

BPL

BRK

BVC

BVS

CLC

CLD

CLI

CLV

CMP

CPX

CPY

DEC

DEX

DEY

EOR

INC

INX

INY

JMP

JSR

LDA

LDX

LDY

LSR

NOP

ORA

PHA

PHP

PLA

PLP

ROL

ROR

RTI

RTS

SBC

SEC

SED

SEI

STA

STX

STY

TAX

TAY

TSX

TXA

TXS

TYA

Branch Instructions 分支指令

Affect Flags: none

所有分支都是相对模式,长度为两个字节。语法是“Bxx Displacement”或“Bxx Label”。有关位移的更多信息,请参阅程序计数器上的注释。

当遇到操作码时,分支取决于标志位的状态。没有token的分支指令需要两个机器周期。如果采用分支,则添加一个;如果分支跨越页面边界,则添自增1。

MNEMONIC

HEX

BPL (Branch on PLus)

$10

BMI (Branch on MInus)

$30

BVC (Branch on oVerflow Clear)

$50

BVS (Branch on oVerflow Set)

$70

BCC (Branch on Carry Clear)

$90

BCS (Branch on Carry Set)

$B0

BNE (Branch on Not Equal)

$D0

BEQ (Branch on EQual)

$F0

没有BRA(BRanch Always 恒转移命令)指令,但它可以很容易地模仿分支的基础上的一个已知的条件。他的标志之一是溢出,除了加法和减法操作外,其他操作都不会改变溢出。

Flag (Processor Status) Instructions 标志(处理器状态)指令

影响标志:如后面所述

这些指令是隐含模式,长度为一个字节,需要两个CPU周期。

MNEMONIC

HEX

CLC (CLear Carry)

$18

SEC (SEt Carry)

$38

CLI (CLear Interrupt)

$58

SEI (SEt Interrupt)

$78

CLV (CLear oVerflow)

$B8

CLD (CLear Decimal)

$D8

SED (SEt Decimal)

$F8

程序计数器

当6502准备好执行下一条指令时,它会在获取指令之前递增程序计数器。一旦有了opcode,它就会将程序计数器的长度增加操作数的长度(如果有的话)。当计算分支或按字节创建假返回地址时,必须考虑到这一点(即,当打算使用RTS而不是JMP时,跳转地址由address -1组成)。

程序计数器首先加载的是最不重要的字节。因此,在创建一个假返回地址时,必须首先推送最重要的字节。

当计算分支时,一个6的正向分支跳过以下6个字节,因此,程序计数器有效地指向分支操作码地址之外的8个字节的地址;$FA(256-6)的后向分支在分支指令之前到达一个7字节的地址。

栈指令

Affects Flags: none

MODE

SYNTAX

HEX

LEN

TIM

Zero Page

STX $44

$86

2

3

Zero Page,Y

STX $44,Y

$96

2

4

Absolute

STX $4400

$8E

3

4

执行时间

Opcode执行时间通过机器CPU的周期来度量,其中一个等于两个时钟周期。许多指令需要一个额外的执行周期,如果一个页面的边界是交叉的;则表示为a+显示的时间值之后。

环绕式处理技术Wrap-Around

使用索引为零的页面操作时要小心,因为它们可能会被包围。例如,如果X寄存器持有$FF,而您执行LDA $80,则X不会像您所期望的那样访问$017F;相反,您可以访问$7F,即$80-1。这个特性可以被利用,但是要确保您的代码注释良好。 在编写将被重新定位的代码的情况下,在为将被调整的地址分配虚拟值时,必须全面考虑。对于虚拟标签,应该避免使用0和半标准的$FFFF。当您需要绝对码时,使用零页或零页值将导致零页操作码的汇编代码。对于$FFFF,问题是在地址+1中,当您将其换行到第0页时。

参考链接:

  1. https://wiki.nesdev.com/w/index.php/6502_assembly_optimisations
  2. https://www.atarimax.com/jindroush.atari.org/aopc.html#WRAP
  3. https://wiki.nesdev.com/w/index.php/CPU_unofficial_opcodes
  4. http://www.obelisk.me.uk/6502/reference.html
  5. https://en.wikipedia.org/wiki/Nintendo_Entertainment_System
本文参与 腾讯云自媒体同步曝光计划,分享自作者个人站点/博客。
如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 作者个人站点/博客 前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体同步曝光计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
目录
  • 6502CPU
    • 基本指令
      • Branch Instructions 分支指令
        • Flag (Processor Status) Instructions 标志(处理器状态)指令
          • 程序计数器
            • 栈指令
              • 执行时间
                • 环绕式处理技术Wrap-Around
                  • 参考链接:
                  领券
                  问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档