为什么我的Commodore 64仿真器上的字符偏移了0x40?

时间:2014-09-10 17:18:00

标签: assembly 6502 c64

清除屏幕后,我有一些6502代码将字符串打印到屏幕内存。不幸的是,如果我打印一个字符串,例如“HELLO WORLD”,它会出现乱码。我发现这是因为我从PETSCII代码here开始想到大写字符从0x01开始,而不是0x41。

我可以通过从我的字符串中减去0x40来解决这个问题,但除了字母以外的所有内容都是不正确的,例如空格。我只是不确定为什么字符发生器将0x01转换为字符'A'而不是0x41。它将0x41变成一个倒置的铲形标志(就像在一副牌上),它上面的所有东西似乎都是边界字符和奇怪的符号。

在环顾四周后,我在PETSCII的维基百科页面上找到了这个引用,这似乎说明了我试图解决的问题,但我不知道如何修复它并且无法在任何地方找到任何信息...

  

实际的字符生成器ROM使用了不同的一组   分配。例如,在屏幕上显示字符“@ABC”   通过直接POKE屏幕内存,可以获得小数点   值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 lda hello, x ; load each byte in turn
        cmp #0       ; if we reached a null byte, break
        beq strexit
        sta $0400, x
        inx
        jmp strloop
strexit rts


hello   .text "HELLO WORLD"
        .byte 0

以下是输出的屏幕截图

Here is a screenshot of the output

感谢评论中的每个人!

帮助他人的旁注

您可以通过PLOT

设置光标位置来设置CHROUT将输出的行和列

http://sta.c64.org/cbm64krnfunc.html

1 个答案:

答案 0 :(得分:8)

您可能直接将ASCII代码写入屏幕内存,这就是为什么它会被40美元抵消。

要将它们放在PETSCII中,您需要在64tass中添加“-a”选项。但仅凭这一点还不够。您的示例现在将被$ c0(大写PETSCII字母)抵消。将文本更改为小写仍然可以提供40美元的抵消(小写PETSCII)。

您需要在屏幕上写入“屏幕”代码。幸运的是,如果你这样做,就会在64tass中进行内置转换:

        .enc screen            ; switch to screen code encoding
hello   .text "hello world"
        .byte 0
        .enc none

但请记住,屏幕代码中“@”为0,因此它会使你的循环变为空白。文本是小写的,但由于默认字体是大写,它最终会大写。将$ d018设置为$ 16以切换到小写字体,然后它将匹配您所写的内容。

适当的PETSCII示例如下:

    *=$c000

    lda #0
    sta $d020 ; border
    sta $d021 ; background

    ldx #0
lp  lda hello,x
    beq end
    jsr $ffd2 ;print character
    inx
    bne lp
end rts

hello .null "{clr}{swlc}HELLO WORLD"

使用不太旧的64tass编译它将“{clr}”和“{swlc}”转换为控制代码147和14.并且不要忘记“-a”开关以启用Unicode支持,否则汇编程序不会对字符串进行任何翻译,而是将其逐字复制(作为原始字节)。