我试图理解汇编 6502 中的这种寻址模式。
例如我们在程序中有这样的指令:
我们知道“text”标签低于$2000 - 高字节是20,低字节是00,累加器中我们有数字30。现在第一个问题是:当我输入时发生了什么这STA $80.
是否意味着我们存储的整个地址累加器是0080?现在假设我们在 $80 下放置数字 00,在 $81 下放置数字 20。Y 为零。现在为什么当我使用这个时:
sta ($80),y
Run Code Online (Sandbox Code Playgroud)
我得到的地址是2000?这是怎么回事?在0080下我们只有00(字节)而不是整个地址(2字节)2000。我知道($80)意味着我们去$80指向的地址。但我们只存储了 00,而不是整个地址 2000。如果有任何帮助,我将不胜感激。
我正在用C编写我的第一个NES模拟器.目标是使其易于理解并且周期准确(尽管不一定必须具有代码效率),以便以正常的"硬件"速度玩游戏.当深入研究6502的技术参考时,似乎指令消耗了多个CPU周期 - 并且根据给定条件(例如分支)也有不同的周期.我的计划是创建读写函数,并通过使用a来寻址模式来对操作码进行分组switch.
问题是:当我有一个多周期指令,例如a时BRK,我是否需要模拟每个周期中发生的事情:
#Method 1
cycle - action
1 - read BRK opcode
2 - read padding byte (ignored)
3 - store high byte of PC
4 - store low byte of PC
5 - store status flags with B flag set
6 - low byte of target address
7 - high byte of target address
Run Code Online (Sandbox Code Playgroud)
...或者我可以在一个'周期'(一个switch case)中执行所有必需的操作,而在剩余的周期中什么都不做?
#Method 2
1 - read BRK opcode,
read padding byte (ignored),
store high byte of …Run Code Online (Sandbox Code Playgroud) 我正在制作 NES 游戏。我正在定义几个常量来帮助我管理精灵。我有
spriteyposition = $0200
spritetile = $0201
spriteattribute = $0202
spritexposition = $0203
sprite1 = $00
sprite2 = $04
sprite3 = $08
sprite4 = $0c
sprite5 = $10
sprite6 = $14
sprite7 = $18
sprite8 = $1c
Run Code Online (Sandbox Code Playgroud)
我的用例如下:
我想修改精灵1的y位置
我愿意:
ldx sprite1
lda spriteyposition, x
adc #$8
sta spriteyposition, x
Run Code Online (Sandbox Code Playgroud)
在我的用例中 spriteyposition 应该是一个内存指针,但我有一种感觉,汇编程序将其视为常规数字
我如何将 spriteyposition 称为内存地址而不是数字?
我正在关注本教程:https : //skilldrick.github.io/easy6502/
在寄存器和标志部分,有一个部分说“如果你仔细观察,你会注意到在这个操作之后进位标志被设置为 1。所以你就是这样知道的。”
问题是,我无法确定进位标志显示在哪里。
就在说明之前,它指出:“最后一部分显示了处理器标志。每个标志都是一位,因此所有七个标志都位于一个字节中。”
这是我所看到的:

编辑:我没有使用任何调试器,因为我不打算安装任何软件,但建议值得赞赏
假设我们偶然发现指令 BPL $0x00
基地址(PC):0x400 值:BPL $00
凭直觉,人们可能会认为程序将挂在地址 0x400 处。
然而,我更倾向于说,它会首先获取 0x400 处的操作码,递增 PC,解码它需要读取操作数,获取操作数,递增 PC。
这样我们就到达了地址 0x402。届时,处理器将解码指令和操作码并在获取下一个操作码之前执行。
那么最终会发生什么呢?程序是分支到地址 0x400,还是像我预测的那样分支到地址 0x402?
我不确定在索引 x 和 y 地址模式下包装是如何工作的。我发现的文档很清楚索引部分被包裹在零页内,但是实际取消引用的 16 位地址呢,它是否也被限制在零页上?
假设我有这个代码:
LDX #$00
LDA #$05
STA $ff
LDA #$07
STA $0100
LDA #$08
STA $00
LDY #$0a
STY $0705
LDY #$0b
STY $0805
LDA ($ff,X)
Run Code Online (Sandbox Code Playgroud)
会A不会装$0a,或者$0b?
很明显,如果X加载了$01,那么地址将从$00( $ff + $01 == $00) 中查找。但是在这种情况下,我们将从中读取 16 位地址 lo 字节$ff- 是从 读取 hi 字节$0100还是从$00?
同样对于间接 y,假设我有以下代码:
LDY #$00
LDA #$30
STA $ff
LDA #$04
STA $00
LDA …Run Code Online (Sandbox Code Playgroud) 我正在6502组装中打印到屏幕上
在我写的监视器中
STA $01, y to store the value at the pointer
Run Code Online (Sandbox Code Playgroud)
当我在此行按Enter键时,它说指令无效?
有任何想法吗...?
对不起,如果问题似乎是"太基本".我是一名68K ASM编码器,但有一位朋友让我一瞥6502代码.我们有一个指向数据字符串的指针:
my_ptr ds 2
Run Code Online (Sandbox Code Playgroud)
使用以下代码设置此指针:
ldx sound_channel_busy
bne .abc_set_score1 ; at bottom of code
sta my_ptr ; fill the pointer
Run Code Online (Sandbox Code Playgroud)
读取数据完成
lda (my_ptr),y ; my_ptr + offset
Run Code Online (Sandbox Code Playgroud)
但正如我在6502 doc中看到的那样,y是一个字节.因此,使用超过255个字节的数据字符串是不可能的(我们想要读取10.000字节或更多的字符串.我建议我的朋友这样做:
1)将一个指针设置为"基础",将一个指针设置为我们在阅读时将要包含的临时指针
my_ptr ds 2
my_ptr_tmp ds 2
Run Code Online (Sandbox Code Playgroud)
2)用以下内容初始化:
ldx sound_channel_busy
bne .abc_set_score1
sta my_ptr
sta my_ptr_tmp ; Duplicate
Run Code Online (Sandbox Code Playgroud)
3)然后阅读使用:
lda (my_ptr_tmp) ; Read to acumulator
inc my_ptr_tmp ; One more on adress pointer
Run Code Online (Sandbox Code Playgroud)
但它不起作用,因为我的朋友是C开发者,我们没有调试器......不容易.在68K这似乎是合乎逻辑的,但在6502?
非常感谢你的帮助
我在6502程序集中编写了一个计算斐波纳契数的函数.我在C中调用该函数,然后将这两个文件编译为6502的单个二进制文件.但是我得到的输出是不同的.10的斐波纳契数是55,但它输出2649.它计算数量的斐波纳契数,但不计算0到10范围内的整数.例如,0的斐波纳契数是257,1表示它是258,10表示2649和等等.为什么我得到这样的输出.
我的C代码:"main.c"
#include<stdio.h>
int fib();
int main() {
unsigned int p = fib();
printf("%u\n",p);
return 0;
}
Run Code Online (Sandbox Code Playgroud)
其中fib()是6502程序集中的外部函数,它与C代码链接在一起.
我的6502代码:"fib.s"
fib:
//calculates fibonacci
Run Code Online (Sandbox Code Playgroud)
我用这两个文件编译 cl65 -t sim6502 main.c fib.s -o fib
因此,我试图通过将ascciASCIIcode存储在字节数组中来将ASCII打印到屏幕上,但是它只是在屏幕上呈现了很多杂色。
; Message: hello
*=$033C
BYTE $48,$45,$49,$49,$4F
*=$1000
START
JSR PRINT_MESSAGE
EXIT
RTS
PRINT_MESSAGE
LDX #$00 ; initialize x to 0
LDA $033C,X ; grab byte
JSR $FFD2 ; render text in A with Subroutine:CLRCHN
INX ; Incriment X
CPX #$05 ; We stop at 5
BNE $1006 ; Else we loop
RTS
Run Code Online (Sandbox Code Playgroud)