我试图找到关于6502 proccesor如何处理中断的信息,但我很困惑.我已经看过一些关于它的例子,但它就像一个普通的subrutine.
我对8086处理器有一些经验,我记得有一些代码可以处理不同的中断.
首先,如果有人能用一些代码解释NMI和IRQ之间的差异,我将非常感激.甚至更多,如果您获得有关处理中断的更多信息(例如)处理键盘中断.
下面是我在 Commodore 64 上进行内存复制的自我修改例程。
我写了char codes
并number of repeats
在一个表中,充满了screen_ram的这个套路。
我正在寻找优化建议。在这种情况下,我的优先事项是内存。
memCopy:
sourceAddress=*+1 ; mark self modifying addrres
fetchNewData:
lda data_table ; read char value into A
ldx data_table+1 ; read repeat value into x
inc sourceAddress
inc sourceAddress
cpx #00 ; if X=0
beq end ; finish copying
destination=*+1
- sta SCREEN_RAM
inc destination
dex
bne -
jmp fetchNewData
end:
rts
; data format: <char>,<number of repeats>,[<char>,<number of repeats>,...],00,00
data_table:
!by 01,03,02,02,......,00,00
Run Code Online (Sandbox Code Playgroud) 我从当时写的大量 6502 中了解到,并行数组比存储数据的结构更好。
想象一下,您想要一个怪物统计数据表,在 C 中可以像这样定义
struct Monster {
unsigned char hitPoints;
unsigned char damage;
unsigned char shieldLevel;
char* name;
};
Run Code Online (Sandbox Code Playgroud)
您可以将其存储为结构数组
static Monster s_monsters[] = {
{ 5, 1, 0, "orc", },
{ 50, 10, 5, "dragon", },
{ 10, 3, 1, "goblin", },
};
Run Code Online (Sandbox Code Playgroud)
或者您可以将其存储为并行数组(通常使用宏或工具来生成)。注意:我用 C 语言显示代码,但请想象它是 6502 汇编。
unsigned char Monster_hitPoints[] = { 5, 50, 10, };
unsigned char Monster_damage[] = { 1, 10, 3, },
unsigned char Monster_sheildLevel[] = { 0, 5, 1, };
unsigned char …
Run Code Online (Sandbox Code Playgroud) 我正在使用cc65 6502模拟器,它编译6502的代码.我希望链接6502代码和C代码并生成一个我可以执行的二进制文件.
我的C代码"main.c":
#include<stdio.h>
extern void foo(void);
int main() {
foo();
return 0;
}
Run Code Online (Sandbox Code Playgroud)
我的6502代码"foo.s":
foo:
LDA #$00
STA $0200
Run Code Online (Sandbox Code Playgroud)
代码可能看起来很简单,但我只是想实现成功的链接.但我无法摆脱以下错误:
Unresolved external '_foo' referenced in:
main.s(27)
ld65: Error: 1 unresolved external(s) found - cannot create output file
清除屏幕后,我有一些6502代码将字符串打印到屏幕内存.不幸的是,如果我打印一个字符串,例如"HELLO WORLD",它会出现乱码.我发现这是因为大写字符从0x01开始,而不是0x41,正如我在这里从PETSCII代码中想到的那样.
我可以通过从我的字符串中减去0x40来解决这个问题,但是除了字母之外的所有内容都是不正确的,例如空格.我只是不确定为什么字符发生器将0x01转换为字符'A'而不是0x41.它将0x41变成一个倒置的铲形标志(就像在一副牌上),它上面的所有东西似乎都是边界字符和奇怪的符号.
在环顾四周后,我在PETSCII的维基百科页面上找到了这个引用,它似乎说明了我试图解决的问题,但我不确定如何修复它,无法在任何地方找到任何信息......
实际的字符发生器ROM使用了一组不同的分配.例如,要通过直接选择屏幕内存来在屏幕上显示字符"@ABC",可以选择小数值0,1,2和3而不是64,65,66和67.
我在Mac OS X上运行VICE x64仿真器,而且我正在使用64位的OS X端口进行组装.
这是汇编代码而不减去0x40:
*=$c000
BORDER = $d020
INNER = $d021
start lda #0
sta BORDER
lda #0
sta INNER
jsr clear
jsr string
loop
jmp loop
clear ; clear screen
lda #$00
tax
lda #$20
clrloop
sta $0400, x ; clear each memory "row"
sta $0500, x
sta $0600, x
sta $0700, x
dex
bne clrloop ; clear if x != 0
rts
string ; load string
ldx #$0
strloop …
Run Code Online (Sandbox Code Playgroud) 即不同的寻址模式是否以某种方式编码在操作码中?可以通过编程方式提取它们还是这些信息仅存在于 6502 的文档中?我正在编写一个模拟器,我不关心性能。如果可能的话,最好有一个接受操作码并返回寻址模式的函数。
到目前为止,我还没有发现任何迹象表明代码中存在某种模式,除了所有零页指令似乎都设置了第三位之外。
我正在尝试了解旧微控制器的指令集,尤其是 6502。
可以在此处找到的指令集文档列出了两个移位指令(除了旋转指令之外):
ASL--算术左移
LSR--逻辑右移
为什么没有算术右移和逻辑左移指令?
我知道可以简单地向其自身添加一个数字,以逻辑地将其向左移动,但专用指令会更方便、更快,即使它只是这样做。但是缺少算术右移指令对我来说没有意义。
assembly arithmetic-expressions 6502 instruction-set bit-shift
我是汇编程序新手,所以这是一个简单的问题:
我的自定义子例程更改X
、Y
和A
寄存器。他们操纵这些来产生期望的结果。在例程启动时将这些值推入堆栈并在之前恢复它们是一个好主意吗RTS
?
我的意思是,这样我就可以编写可以从任何地方调用的例程,而不会弄乱“状态”或影响其他例程。但是这样使用栈可以吗?或者有更好的方法来做到这一点吗?
有人质疑 ATARI-2600 吗?
当一个字节存储在 TIA HMP0 寄存器中时,精细位置调整将应用于粗略光束位置。Stella 手册称该值可以是 -8 到 7 之间的任何值。其中 -8 是(二进制 1000),7 是(二进制 0111),因为半字节被读取为二进制补码。
我的问题是,当应用任何负的精细位置值时,我无法让 Sprite 渲染。作为演示,请观察由于 HMOVE 按栅格线移动的结果而为 Sprite 0 渲染的对角线。然而,当应用的值的高位为 1(也称为负数)时,精灵就会消失,并且该扫描线上没有任何内容。为了进行比较,Sprite 1 将屏幕长度渲染为一条直线,b/c 没有应用精细位置。
可见线循环的代码如下:
ScanLoop
REPEAT 10 ; wait to
nop ; get beam
REPEND ; arbitrarily near center
; All we do here is ++ the hi nibble in the Accumulator
; and apply it to HMP0 to adjust the fine position.
; QUESTION FOR READER: WHY DOESN'T THE SPRITE RENDER WHEN
; …
Run Code Online (Sandbox Code Playgroud) 我观看了 Ben Eater 的关于构建基于 6502 芯片的计算机的视频,但我陷入了第 3 部分(汇编语言 VS 机器代码)。他正在对 32k EEPROM 进行编程,并通过汇编进行编程以闪烁 LED。这是他使用的汇编程序http://sun.hasenbraten.de/vasm/ 这是他的代码:
但我有一个关于org
指令的问题,这就是我所理解的 org 告诉汇编器从哪个地址开始的意思?在图片中org
equals$8000
所以我认为第一个地址指令应该是8000
但是当他输出文件时它 equal 0000
。
为什么第一条指令的地址不是8000
?
6502 ×10
assembly ×8
c64 ×2
atari-2600 ×1
batari-basic ×1
bit-shift ×1
c ×1
disassembly ×1
eeprom ×1
emulation ×1
hexdump ×1
opcode ×1