[英]How to create a std::wstring using the ascii codes of characters in C++?
[英]ASCII to C64 Screen Codes In DASM Assembler
我正在通过 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 的字符代码, message
的"HELLO"
是位 48 45 4C 4C 4F。 这会在屏幕的左上角提供以下输出:
通过查看此处的准将屏幕代码表,我猜这是正确的。
如果我将第 6 行更改为lda hexmsg,x
那么我得到的正是我想要的, HELLO
一词。
我对 DASM 汇编程序还不是很熟悉,并且无法找到它的完整文档(如果存在)。 我发现的大多数教程只是让你声明message .byte "HELLO"
或类似的东西,它只是有效,因为他们使用的汇编程序会自动将类似 ascii 的文本字符串自动转换为 commodore 字符串,但 DASM 似乎没有要做到这一点。
有谁知道我可以让 DASM 做到这一点的方法,或者推荐另一种方法来简单地将字符串输入到汇编程序中,而不是手动将我的字符串输入为一堆十六进制数据?
啊哈,ASCII 编码与 Commodore 屏幕代码。 我们都去过那里。 您有几个选择:
不要直接写入屏幕内存,而是使用内核 CHROUT 例程(可能通过更高级别的字符串输出例程)。 那么您只需要担心 ASCII 和 PETSCII 之间的差异,但这是另一个睡前故事。 此外,这对文本很有用,但对游戏来说很糟糕,因为与直接写入相比,内核速度较慢。
编写一个小转换例程,在程序启动时运行,吃掉你的字符串表,并吐出转换后的屏幕代码等价物。 快速且高效,前提是您的字符串都在一起并且您没有编写基于 ROM 的应用程序(该应用程序无法进行就地转换)。
编写一个 DASM 预处理器,它在构建脚本中的 DASM 之前运行,并且基本上执行与上述 #2 相同的转换,但是在汇编程序看到它之前转换为源代码。 这可能有点粗糙,您必须确保在修改之前备份原始源。
获取 DASM 源代码并对其进行修补以调用新数据类型(用于屏幕代码)的用户出口,该数据类型与#2 的功能相同,但在组装过程中即时运行。 非常粗糙。
在字符串中使用小写字母,这将在汇编期间转换为大写屏幕代码等效项。 您可能忽略了这样一个事实,即您看到的是字符串中字符的移位表示,在默认显示模式下是图形符号。
从所有 5 个选项的经验来看,我选择了 #2。
另外:切换到KickAssembler ,其中
自从我编程 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
这是 DASM aseembler 的修补版本。
http://iancoog.altervista.org/C/dasm2.20.07-iAN_Rev_N.rar
您可以使用SCRU
和SCRL
指令来转换 ASCII->Screencode 转换。
label SCRU "string"
label SCRL "string"
SCRU
用于制作大写文本,即使输入小写也是如此。 SCRL
保持外壳。
如果它可以帮助,这里有一个小的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!")
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.