使用xa65制作Commodore 64 .prg文件及磁盘镜像遇问题求助
解决Commodore 64汇编程序在VICE中无法运行的问题
问题背景
参考《Using xa65 assembler to create Commodore 64 .prg》编写的汇编程序无法在VICE模拟器中正常运行,具体情况如下:
编写的基础汇编代码:
.byte $01, $08 lda #1 sta $0400 jmp $0801
汇编后十六进制转储确认代码编译正确,但使用VICE的"Autostart"功能无反应;尝试用c1541创建磁盘镜像:
c1541 -format diskname,id d64 my_diskimage.d64 -attach my_diskimage.d64 -write my_program.prg myprog
镜像挂载到#8驱动器后,执行LOAD "*",8,1时卡在加载状态。原以为带两字节头的二进制数据即可作为.prg文件,加载后输入SYS 2049即可启动,但问题未解决。
补充测试:手动将代码写入$C000并执行SYS调用也无效,操作代码:
POKE 49152, 1 POKE 49153, 169 POKE 49154, 0 POKE 49155, 141 POKE 49156, 76 POKE 49157, 4 POKE 49158, 192 POKE 49159, 0 SYS 49152
对应的.prg文件十六进制转储:
c000 01a9 008d 4c04 c000
问题分析与解答
1. VICE自动启动失败的原因
- .prg文件的两字节头是加载地址的小端存储,需由汇编器自动生成,而非手动写入代码中。你手动添加的
.byte $01, $08会被xa65当作程序代码的一部分,导致加载到$0801后,第一条执行的指令是$01(无效的6502指令),VICE自动启动时执行$0801会直接崩溃或无响应。 - 你的
jmp $0801会让程序跳回开头再次执行无效指令,进一步加剧问题。
2. 磁盘镜像加载卡住的原因
- 核心问题还是.prg文件格式错误:手动写入的头字节被计入程序长度,导致c1541写入磁盘时,目录项记录的文件信息与实际代码不匹配,LOAD过程无法正确解析文件内容,表现为卡住。
- 即使加载完成,程序本身的无效指令也会导致执行异常,看起来像是加载卡住。
手动POKE无效的原因
从十六进制转储和POKE操作来看,你完全搞错了6502指令的机器码结构:
lda #1的机器码是$A9 $01,你却把$01放在了$C000(第一条指令位置),导致第一条指令是无效的$01。sta $0400的机器码是$8D $00 $04(操作数低字节在前),你把$8D放到了$C004,而$C003是$00,变成了无效指令。jmp $C000的机器码是$4C $00 $C0,你把操作数顺序搞反,导致跳转地址错误。
解决方案
1. 正确编写并编译汇编程序
使用.org伪指令指定加载地址,让xa65自动生成.prg文件头:
.org $0801 ; 指定加载地址为$0801,xa65自动生成小端头$01 $08 lda #$31 ; 加载PETSCII字符"1"的编码(若用#1会显示特殊符号) sta $0400 ; 写入屏幕内存起始位置$0400 jmp * ; 无限循环,避免返回后执行系统垃圾代码
编译命令:
xa65 -o my_program.prg my_program.asm
2. 正确创建磁盘镜像
拆分命令避免格式问题:
# 先格式化磁盘镜像 c1541 -format diskname,id d64 my_diskimage.d64 # 再将.prg写入镜像 c1541 -attach my_diskimage.d64 -write my_program.prg MYPROG
在VICE中挂载镜像后,执行LOAD "MYPROG",8,1即可加载并运行,或直接Autostart该文件。
3. 正确的手动POKE测试
如果要手动验证代码,按6502指令结构编写POKE命令:
POKE 49152, 169 ; $A9,lda #操作码 POKE 49153, 49 ; $31,PETSCII数字"1"的编码 POKE 49154, 141 ; $8D,sta操作码 POKE 49155, 0 ; $0400的低字节 POKE 49156, 4 ; $0400的高字节 POKE 49157, 76 ; $4C,jmp操作码 POKE 49158, 0 ; $C000的低字节 POKE 49159, 192 ; $C000的高字节 SYS 49152
执行后屏幕左上角会显示数字"1"。
内容的提问来源于stack exchange,提问作者Peatherfed
相关产品推荐
相关产品推荐

