首页 > 其他分享 >6502 寻址模式详解

6502 寻址模式详解

时间:2023-03-23 22:14:08浏览次数:56  
标签:DL 读取 6502 ADD RD PCH 寻址 PCL 详解

6502 共有 13 种寻址模式:

  1. A:寄存器寻址。指令形式为 OPC A;目标数据位于 A 寄存器中,属于隐含寻址;使用这种寻址模式的指令都是 1 个字节长度,需要 2 个时钟周期
  2. abs:绝对地址寻址。指令形式为 OPC $LLHH;目标数据位于绝对地址 $HHLL
  3. abs,X:X 变址绝对地址寻址。指令形式为 OPC $LLHH,X;操作数是 16 位基址;有效地址由基址加上 X 寄存器中的值计算得到
  4. abs,Y:X 变址绝对地址寻址。指令形式为 OPC $LLHH,Y;操作数是 16 位基址;有效地址由基址加上 Y 寄存器中的值计算得到
  5. #:立即数寻址。指令形式为 OPC #$BB;目标数据即操作数 BB
  6. impl:隐含寻址。目标数据由指令码决定
  7. ind:间接寻址。指令形式为 OPC ($LLHH);操作数是 16 位间接地址; 有效地址是位于间接地址处的 16 位内容;读取有效地址时,不考虑跨页
  8. X,ind:X 变址间接寻址。指令形式为 OPC ($LL,X);操作数是 8 位间接地址基址; 基址与 X 寄存器的值进行无进位加法后得到间接地址,有效地址是位于间接地址处的 16 位地址;读取有效地址时,不考虑跨页
  9. ind,Y: 间接地址 Y 变址寻址。指令形式为 OPC ($LL),Y;操作数是一个 8 位间接地址;$LL 处存储的是 16 位基址,基址加上 Y 寄存器的值得到有效地址;读取 16 位基址时,不考虑跨页
  10. rel:相对寻址。指令形式为 OPC $BB;操作数 BB 为有符号数,表示偏移;目标地址由 PC 加上 BB 得到
  11. zpg:零页寻址。指令形式为 OPC $LL;操作数是一个 8 位绝对地址,目标数据位于 $00LL
  12. zpg,X:零页 X 变址寻址。指令形式为 OPC $LL,X;操作数是一个 8 位基址;有效地址由基址与 X 寄存器的值进行无进位加法后得到
  13. zpg,Y:零页 Y 变址寻址。指令形式为 OPC $LL,Y;操作数是一个 8 位基址;有效地址由基址与 Y 寄存器的值进行无进位加法后得到

6502 采用小端序,读取 16 位地址时,先读取到的是低 8 位,然后是高 8 位

我把每个寻址模式的时序整理成了表格,以便清晰地看出 CPU 内每个时钟周期的工作状态,对于理解 6502 的工作原理应该有所帮助。表格中的单元格如果为空白,表示对应的组件没有被修改。需要注意的是,以下时序只适用于正常指令(官方指令)。非法指令在解码时和执行时会激活额外的信号线,导致同样的寻址模式会多做一些事情或者同样的寻址模式却有不同的时长,往往需要单独总结。

我还做了一个网页,可以查询每个指令的时序和详细信息,点击这里体验。

zpg

Cycle ADH ADL IPC AI BI CI 说明
T0 PCH PCL 1 读取操作码
T1 PCH PCL 1 读取有效地址
T2 0 DL 0 读取目标数据
OPC = RD(PC++);
EA = RD(PC++);

zpx

Cycle ADH ADL IPC AI BI CI 说明
T0 PCH PCL 1 读取操作码
T1 PCH PCL 1 读取基址
T2 0 DL 0 X DL 0 加上 X 寄存器中的偏移,计算有效地址
T3 ADD 0 读取目标数据
OPC = RD(PC++);
EA = RD(PC++) + X;

zpy

Cycle ADH ADL IPC AI BI CI 说明
T0 PCH PCL 1 读取操作码
T1 PCH PCL 1 读取基址
T2 0 DL 0 Y DL 0 加上 Y 寄存器中的偏移,计算有效地址
T3 ADD 0 读取目标数据
OPC = RD(PC++);
EA = RD(PC++) + Y;

abs

Cycle ADH ADL IPC AI BI CI 说明
T0 PCH PCL 1 读取操作码
T1 PCH PCL 1 读取有效地址的低 8 位
T2 PCH PCL 1 0 DL 0 读取有效地址的高 8 位
T3 DL ADD 0 读取目标数据
OPC = RD(PC++);
EA = WORD(RD(PC + 1), RD(PC));
PC += 2;

abx

Cycle ADH ADL IPC AI BI CI 说明
T0 PCH PCL 1 读取操作码
T1 PCH PCL 1 读取基址的低 8 位
T2 PCH PCL 1 X DL 0 读取基址的高 8 位, 加上 X 寄存器中的偏移
T3 DL ADD 0 0 DL ACR 读取目标数据,处理跨页。 若不跨页 (ACR = 0),则跳过 T4 周期
T4 ADD 0 再次读取目标数据
OPC = RD(PC++);
EA = WORD(RD(PC + 1), RD(PC)) + X;
PC += 2;

aby

Cycle ADH ADL IPC AI BI CI 说明
T0 PCH PCL 1 读取操作码
T1 PCH PCL 1 读取基址的低 8 位
T2 PCH PCL 1 Y DL 0 读取基址的高 8 位, 加上 Y 寄存器中的偏移
T3 DL ADD 0 0 DL ACR 读取目标数据,处理跨页。 若不跨页 (ACR = 0),则跳过 T4 周期
T4 ADD 0 再次读取目标数据
OPC = RD(PC++);
EA = WORD(RD(PC + 1), RD(PC)) + Y;
PC += 2;

ind

Cycle ADH ADL IPC AI BI CI 说明
T0 PCH PCL 1 读取操作码
T1 PCH PCL 1 读取间址的低 8 位
T2 PCH PCL 1 0 DL 0 读取间址的高 8 位
T3 DL ADD 0 0 ADD 1 读取有效地址的低 8 位,并把间址加 1(无进位)
T4 ADD 0 0 DL 0 读取有效地址的高 8 位
T5 DL ADD 0 读取目标数据
OPC = RD(PC++);
IA = WORD(RD(PC + 1), RD(PC));
EA = WORD(RD(WORD(HI(IA), LO(IA + 1))), RD(IA));
PC += 2;

inx

Cycle ADH ADL IPC AI BI CI 说明
T0 PCH PCL 1 读取操作码
T1 PCH PCL 1 读取 8 位基址
T2 0 DL 0 X DL 0 空读,加上 X 寄存器中的偏移计算间址
T3 ADD 0 0 ADD 1 读取有效地址的低 8 位,并把间址加 1(无进位)
T4 ADD 0 0 DL 0 读取有效地址的高 8 位
T5 DL ADD 0 读取目标数据
OPC = RD(PC++);
IA = BYTE(RD(PC++) + X);
EA = WORD(RD(BYTE(IA + 1)), RD(IA));

iny

Cycle ADH ADL IPC AI BI CI 说明
T0 PCH PCL 1 读取操作码
T1 PCH PCL 1 读取 8 位间址
T2 0 DL 0 0 DL 1 读取基址的低 8 位,并把间址加 1
T3 ADD 0 Y DL 0 读取基址的高 8 位,加上 Y 寄存器中的偏移计算有效地址
T4 DL ADD 0 0 DL ACR 读取目标数据并处理跨页, 若不跨页 (ACR = 0),则跳过 T5 周期
T5 ADD 0 再次读取目标数据
OPC = RD(PC++);
IA = BYTE(RD(PC++) + X);
EA = WORD(RD(BYTE(IA + 1)), RD(IA)) + Y;

rel

Cycle ADH ADL IPC PCH PCL AI BI CI 说明
T0 PCH PCL 1 读取操作码
T1 PCH PCL 1 读取偏移
T2 PCH PCL 0 DL PCL 0 空读,把 PC 加上偏移计算目标地址
T3 ADD 0 ADD PCH * ** 处理跨页。
* 若偏移量为正,则 BI 为 0;否则为 $FF
** 若跨页(ACR = 1)且偏移量为正,则 CI 为 1;否则为 0
T0 ADD 1 ADD 设置 PC 并读取操作码
OPC = RD(PC++);
OFF = RD(PC++);
PC = PC + OFF;

JMP abs

Cycle ADH ADL IPC PCH PCL AI BI CI 说明
T0 PCH PCL 1 读取操作码
T1 PCH PCL 1 读取有效地址的低 8 位
T2 PCH PCL 0 0 DL 0 读取有效地址的高 8 位
T0 DL ADD 1 DL ADD 设置 PC 读取操作码
OPC = RD(PC++);
EA = WORD(RD(PC + 1), RD(PC));
PC = EA;

JMP ind

Cycle ADH ADL IPC PCH PCL AI BI CI 说明
T0 PCH PCL 1 读取操作码
T1 PCH PCL 1 读取间址低 8 位
T2 PCH PCL 1 0 DL 0 读取间址高 8 位
T3 DL ADD 0 0 ADD 1 读取有效地址低 8 位,把间址加 1 (无进位)
T4 ADD 0 0 DL 0 读取有效地址高 8 位
T0 DL ADD 1 DL ADD 设置 PC 读取操作码
OPC = RD(PC++);
IA = WORD(RD(PC + 1), RD(PC));
EA = WORD(RD(WORD(HI(IA), LO(IA + 1))), RD(IA));
PC = EA;

JSR abs

Cycle ADH ADL IPC PCH PCL S AI BI CI DOR 说明
T0 PCH PCL 1 读取操作码
T1 PCH PCL 1 读取有效地址的低 8 位
T2 $01 S 0 DL 0 S 0 将读到的有效地址低 8 位保存到 S 寄存器中,将原本 S 寄存器的内容保存到 ALU 中
T3 $01 ADD 0 $FF ADD 0 PCH 将 PCH 压栈
T4 $01 ADD 0 $FF ADD 0 PCL 将 PCL 压栈
T5 PCH PCL 1 读取有效地址的高 8 位
T0 DL S 1 DL S ADD 设置 PC,读取操作码,并从 ALU 中恢复 S 寄存器
OPC = RD(PC++);
EA = RD(PC++);
WR(S--, PCH);
WR(S--, PCL);
EA = WORD(RD(PC++), LO(EA));
PC = EA;

BRK

Cycle ADH ADL IPC PCH PCL S AI BI CI DOR 说明
T0 PCH PCL 1 读取操作码
T1 PCH PCL 0 空读
T2 $01 S 0 $FF S 0 PCH 将 PCH 压栈
T3 $01 ADD 0 $FF ADD 0 PCL 将 PCL 压栈
T4 $01 ADD 0 $FF ADD 0 P 将 P 寄存器的内容压栈
T5 $FF $FE 0 ADD 读取中断向量的低 8 位
T6 $FF $FF 0 0 DL 0 读取中断向量的高 8 位
T0 DL ADD 1 DL ADD 设置 PC 并读取操作码
OPC = RD(PC++);
WR(S--, PCH);
WR(S--, PCL);
WR(S--, P);
PC = WORD(RD(0xFFFF), RD(0xFFFE));

RTI

Cycle ADH ADL IPC PCH PCL S P AI BI CI 说明
T0 PCH PCL 1 读取操作码
T1 PCH PCL 1 空读
T2 $01 S 0 0 S 1 空读,栈指针加 1
T3 $01 ADD 0 0 ADD 1 从栈顶读 P 寄存器的内容,栈指针加 1
T4 $01 ADD 0 DL 0 ADD 1 从栈顶读 PCL 的内容,栈指针加 1
T5 $01 ADD 0 ADD 0 DL 0 从栈顶读 PCH 的内容
T0 DL ADD 1 DL ADD 设置 PC 并读取操作码
OPC = RD(PC++);
P = RD(++S);
PCL = RD(++S);
PCH = RD(++S);

RTS

Cycle ADH ADL IPC PCH PCL S AI BI CI 说明
T0 PCH PCL 1 读取操作码
T1 PCH PCL 1 空读
T2 $01 S 0 0 S 1 空读,栈指针加 1
T3 $01 ADD 0 0 ADD 1 从栈顶读 PCL,栈指针加 1
T4 $01 ADD 0 ADD 0 DL 0 从栈顶读 PCH
T5 DL ADD 1 DL ADD 空读,设置 PC 指针
T0 PCH PCL 1 读取操作码
OPC = RD(PC++);
PCL = RD(++S);
PCH = RD(++S);
PC++;

PHA, PHP

Cycle ADH ADL IPC S AI BI CI DOR 说明
T0 PCH PCL 1 读取操作码
T1 PCH PCL 0 空读
T2 $01 S 0 $FF S 0 A/P 将 A 或 P 寄存器的内容压栈
T0 PCH PCL 1 ADD 读取操作码
OPC = RD(PC++);
WR(S--, A);

PLA, PLP

Cycle ADH ADL IPC A/P S AI BI CI 说明
T0 PCH PCL 1 读取操作码
T1 PCH PCL 0 空读
T2 $01 S 0 0 S 1 空读,栈指针加 1
T3 $01 ADD 0 ADD 从栈顶读 A 或 P 的内容
T0 PCH PCL 1 DL 读取操作码,设置 A 或 P 寄存器
OPC = RD(PC++);
A = RD(++S);

参考

标签:DL,读取,6502,ADD,RD,PCH,寻址,PCL,详解
From: https://www.cnblogs.com/1bite/p/17246691.html

相关文章

  • LinkedList用法详解
    LinkedList用法详解https://blog.csdn.net/u013970897/article/details/106877472一、LinkedList简单介绍        LinkedList是List接口的实现类,因此......
  • Android开发-Android UI与布局详解
    1.UIUI - UserInterface - 用户界面 - 系统与用户信息交换的媒介软件设计=编码设计+UI设计AndroidUI=布局+控件2.布局layoutView:微件。用户......
  • CSS详解
    CascadingStyleSheets层叠样式表HTML+CSS+JavaScript框架+表现+交互一、初始及入门1.CSS概念CSS在网页中的应用CSS的发展史CSS的优势2.CSS基本语法标签style3.......
  • ESD二极管工作原理、封装、型号、选型(详解)
    常用静电防护保护器件——ESD二极管,对于电子工程师而言,并不陌生。在消费电子、家电、智能家居、可穿戴智能设备、汽车电子、安防、工业设备等产品领域中都能看到ESD二极管靓......
  • Mysql常用语法详解
    一、数据库创建数据库createdatabase数据库名;查询所有数据库showdatabases;查看正在创建的数据库信息showcreatedatabase数据库名;删除数据库dropdatabas......
  • SpringBoot详解
    一、介绍1.SpringBoot是一个基于Spring框架的开源框架,用于构建微服务和Web应用程序。它可以帮助开发者轻松创建独立的、基于Spring的应用程序,并在较短的时间内完......
  • 虚拟内存与malloc/new原理详解
    mallocmalloc()函数并不是系统调用,而是C库里的函数,用于动态分配内存。malloc()分配的是虚拟内存,而不是物理内存。如果分配后的虚拟内存没有被访问的话,是不会将虚拟内存......
  • 【web 开发基础】PHP 快速入门(9)-PHP 运算符之位运算符详解
    前言PHP开发基础开速入门系列目录:《【web开发基础】php开发基础快速入门(1)-PHP介绍及开发环境快速安装和基本使用介绍》《【web开发基础】php开发基础快速入门(2)-......
  • 数组详解
    数组的定义数组是相同类型数据的有序集合数组描述的是相同类型的若干个数据,按照一定的先后次序排列组合而来其中,每一个数据称作一个数组元素,每个数组元素可以通过......
  • 爬虫进阶之多线程爬虫问题详解
    大多数正常人在下载图片的时候都是一个一个点击保存,图片越多花费的时间越多,大大的降低了工作效率。如果是学了爬虫的,一定会想到多线程来自动下载保存图片。多线程介绍:多......