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

概述 依照前面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

本文参与腾讯云自媒体分享计划,欢迎正在阅读的你也加入,一起分享。

发表于

我来说两句

0 条评论
登录 后参与评论

扫码关注云+社区

领取腾讯云代金券