4

我正在通过 C64 仿真器学习 6502 micro 的组装。当前正在尝试将字符串输出到屏幕。这是我的代码:

    processor 6502
    org $1000

    ldx #$00    ;using x register as column counter
print:
    lda message,x;load a with x bit from message
    sta $0400,x ;store this bit in row 0 col 0 address
    inx         ;x++
    cpx #$05    ;is x >= 5?
    bne print   ;if not x >= 5, loop again
    rts         ;return from program


message dc "HELLO"
hexmsg dc $08,$05,$0c,$0c,$0f

因为我的编辑器(win 10 上的记事本++)使用类似 ascii 的字符代码,所以"HELLO"inmessage是位 48 45 4C 4C 4F。这会在屏幕的左上角给出以下输出: 在此处输入图像描述

通过查看此处的准将屏幕代码表,我猜这是正确的。

如果我将第 6 行更改为,lda hexmsg,x那么我得到的正是我所追求的,单词HELLO.

我对 DASM 汇编器还不是很熟悉,并且很难找到它的完整文档(如果存在的话)。我发现的大多数教程只有你声明message .byte "HELLO"或类似的东西,它只是工作,因为他们使用的汇编程序自动将类似 ascii 的文本字符串自动转换为准将字符串,但 DASM 似乎没有这样做。

有谁知道我可以让 DASM 做到这一点的方法,或者推荐另一种方法来简单地将字符串输入到汇编程序中,而不是手动将我的字符串输入为一堆十六进制数据?

4

4 回答 4

6

啊哈,ASCII 编码与 Commodore 屏幕代码。我们都去过那里。你有几个选择:

  1. 不要直接写入屏幕内存,而是使用内核 CHROUT 例程(可能通过更高级别的字符串输出例程)。那么你只需要担心 ASCII 和 PETSCII 之间的区别,但这是另一个睡觉时间的故事。此外,这对文本很有用,但对游戏来说很糟糕,因为与直接写入相比,内核速度很慢。

  2. 编写一个小的转换例程,当你的程序启动时运行,吃掉你的字符串表,并吐出转换后的屏幕代码等价物。快速高效,前提是您的字符串都在一起,并且您没有编写基于 ROM 的应用程序(无法进行就地转换)。

  3. 编写一个 DASM 预处理器,它在构建脚本中的 DASM 之前运行,并且基本上与上面的 #2 进行相同的转换,但在汇编器看到它之前转换为源代码。这可能有点粗糙,您必须确保在修改原始源之前备份它。

  4. 获取 DASM 源代码并对其进行修补,以调用新数据类型(用于屏幕代码)的用户出口,该数据类型与 #2 相同,但在组装期间即时运行。很粗糙。

  5. 在您的字符串中使用小写字母,这将在汇编期间转换为大写屏幕代码等效项。您可能忽略了这样一个事实,即您看到的是字符串中字符的移位表示,在默认显示模式下是图形符号。

从所有 5 个选项的经验来看,我选择了 #2。

另外:切换到KickAssembler,其中

  • 更新,并积极维护
  • 提供更强大的功能
  • 与 VICE 很好地集成以进行调试
于 2017-04-19T15:03:38.910 回答
5

自从我对 6510 进行编程以来已经有一段时间了。(如果您没有被要求保存 C64 内存的每个字节..)还可以考虑用 0 字节来终止您的字符串,而不是在 X 寄存器中达到长度时终止。使它更方便一点,而不是计算字符串长度:D

processor 6502
org $1000

printstring:
    ldx #$00
printstrlp:
    lda message,x
    cmp #0
    beq quitstr
    cmp #32         ;' ' character
    beq noconv
    cmp #33         ;! character
    beq noconv
    cmp #42         ;* character
    beq noconv
    cmp #48         ;numbers 0-9
    bcs numconv
conv:
    sec
    sbc #$40
noconv: 
    sta $0400,x
    inx         
    bne printstrlp
quitstr:
    rts
numconv:
    cmp #58
    bcc noconv
    jmp conv

message dc "** HELLO C64 WORLD! **",0
于 2017-04-19T16:42:50.867 回答
4

这是 DASM 汇编器的补丁版本。
http://iancoog.altervista.org/C/dasm2.20.07-iAN_Rev_N.rar

你可以使用SCRUSCRL指令来转换 ASCII->Screencode 转换。

label SCRU  "string"
label SCRL  "string"

SCRU用于制作大写文本,即使输入的是小写字母。SCRL保持外壳。

于 2017-04-19T20:21:32.687 回答
0

如果它可以帮助,这里有一个小python脚本来做。只需调用它python3 str_conv.py code.asm message

import argparse
import os

mapping = [
 '@', 'A', 'B', 'C', 'D', 'E', 'F', 'G', 'H', 'I', 'J', 'K', 'L', 'M', 'N', 'O', 'P', 'Q', 'R', 'S', 
 'T', 'U', 'V', 'W', 'X', 'Y', 'Z', '[', '~', ']', '|', '\\', ' ', '!', '"', '#', '$', '%', '&', 
 '\'', '(', ')', '*', '+', ',', '-', '.', '/', '0', '1', '2', '3', '4', '5', '6', '7', '8', '9', 
 ':', ';', '<', '=', '>', '?'
]

if __name__ == "__main__":
    
    parser = argparse.ArgumentParser(description='Convert ASCII to C64 screen codes')
    parser.add_argument('file', help='assembly source code')
    parser.add_argument('label', help='label used in DASM')
    
    args = parser.parse_args()
    
    filepath = os.path.join(os.getcwd(), args.file)
    backup = os.path.join(os.getcwd(), args.file) + ".bck"
    os.rename(filepath, backup)

    label = args.label
    new_code = []    
    found = False
    
    for line_nb, line in enumerate(open(backup)): 
        if line.find("\\b{}\\b".format(label)) and '"' in line:
            text = line[line.find('"')+1:line.rfind('"')]
            
            new_line = "{}:\t.byte ".format(label)
            for i, char in enumerate(text):
                new_line += "{}{}".format(mapping.index(char), ", " if i != len(text)-1 else "\n")
            
            print(line_nb, new_line)
            new_code.append("; {}".format(line))
            new_code.append(new_line)
            found = True
        else:
            new_code.append(line)
            
    if not found:
        print("Label {} not found!".format(label))
    else:
        with open(filepath, "w") as new_file:
            for line in new_code:
                new_file.write(line)
        
        print("Done!")
            
于 2020-10-03T17:23:14.030 回答