assembly 使用xa65创建Commodore64.prg文件和磁盘映像

lymnna71  于 2023-06-23  发布在  其他
关注(0)|答案(1)|浏览(87)

我试过看Using xa65 assembler to create Commodore 64 .prg,但我不能让例子工作。
我用的是VICE模拟器。
所以我的超级基本汇编程序看起来像这样:

.byte $01, $08
lda #1
sta $0400
jmp $0801

并且在组装之后检查六角转储确认其被正确组装。就我在网上能找到的来说,这应该足够一个可用的.prg文件了。但是,如果我尝试使用VICE的“自动启动”功能,它不工作。所以我尝试使用c1541创建一个磁盘映像,命令如下:
c1541 -format diskname,id d64 my_diskimage.d64 -attach my_diskimage.d64 -write my_program.prg myprog
虽然我 * 可以 * 创建磁盘映像,并将其附加到驱动器#8,但运行LOAD "*",8,1不起作用。它只是卡在装载上。
我不知道我哪里做错了。我认为2字节的头加上二进制数据就足够了,加载后我可以简单地输入SYS 2049来启动程序。
我很想解决这个问题,但我也很好奇为什么

  1. VICE的自动启动失败。
    1.磁盘映像加载卡住。
    编辑:我尝试手动将输出值插入$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

当然,在我的戳中,我忽略了第一个$c000,因为那只是.prg标题。

pdkcd3nj

pdkcd3nj1#

POKE 49152, 1
POKE 49153, 169

POKE 49154, 0
POKE 49155, 141

POKE 49156, 76
POKE 49157, 4

POKE 49158, 192
POKE 49159, 0

我们这里的错误是字节序。每个字节成对反转。所以程序反汇编为:

ora (a9),x
    brk
    sta $044c
    cpy #$00

好的,所以你的每一条指令都被变异成了完全不同的东西,因为字节被交换了。

  • a901lda #1
  • 01a9ora (a9),x

由于这个原因,你的程序从十进制地址49152开始,也不会以rtsjmp指令结束,所以我预计它会使你的Commodore 64崩溃。
虽然我可以创建一个磁盘映像,并将其附加到驱动器#8,但运行LOAD“*",8,1不起作用。它只是卡在装载上。
当执行LOAD "*",8,1时,操作系统会忽略告诉计算机在内存中何处加载文件的头。它将把文件加载到BASIC启动的任何地方,这因型号而异(维克-20和PET的BASIC程序启动在不同的地址)。
因此,该命令末尾的,1也意味着这是一个BASIC程序,因此BASIC将尝试解释您的程序(它将失败;这不是一个BASIC程序;这是机器代码)。
这就是你的自动启动失败的原因。
我最好的猜测是,该文件加载好虽然。您可以检查VICE的优秀调试器。
在我的游戏中,要让自动启动工作,我需要把代码放在BASIC可以解释的文件的开头。不需要太多就像10 SYS 1234一样简单。但显然我们可以让汇编程序为我们找出入口点的地址。比如说

; The following is a short BASIC program
; 10 SYS 1234
; and causes the machine to jump to the machine code starting at init_entrypoint

* = $0801
    ; line number and SYS token
    .byte $0C, $08, $0A, $00, $9E, $20

    ; what's the address of the routine in decimal
    .byte $30 + ((init_entrypoint) / 1000)
    .byte $30 + ((init_entrypoint % 1000) / 100)
    .byte $30 + ((init_entrypoint % 100) / 10)
    .byte $30 + ((init_entrypoint % 10))

     ; null terminate the BASIC program
    .byte $00, $00, $00

init_entrypoint: ; here's your program OP
    lda #1
    sta $0400
    jmp init_entrypoint

这将组装成有效的BASIC(或者至少,当我上次构建它时是这样的!)),并且可以是RUN、LISTed、自动启动等。如果你想使用xa 65,你可能需要做一些调整。

相关问题