Почему символы смещены на 0x40 в моем эмуляторе Commodore 64?

У меня есть код 6502 для печати строки в памяти экрана после очистки экрана. К сожалению, если я напечатаю строку, например "HELLO WORLD", она будет отображаться искаженными символами. Я обнаружил, что это потому, что символы верхнего регистра начинаются с 0x01, а не с 0x41, как я думал из кодов PETSCII здесь.

Я могу исправить это, вычтя 0x40 из моей строки, но тогда все, кроме букв, будет неправильным, например, пробелы. Я просто не уверен, почему генератор символов превращает 0x01 в символ "А", а не 0x41. Он превращает 0x41 в перевернутый знак лопаты (как на колоде карт), и все, что находится над ним, кажется пограничными и странными символами.

Оглядевшись некоторое время, я нашел эту цитату на странице википедии для PETSCII, в которой, казалось, говорилось о проблеме, которую я пытаюсь решить, но я не уверен, как ее исправить, и нигде не могу найти никакой информации...

Фактический генератор символов ПЗУ использовал другой набор назначений. Например, чтобы отображать символы "@ABC" на экране, напрямую нажимая на экранную память, нужно было бы нажимать десятичные значения 0, 1, 2 и 3 вместо 64, 65, 66 и 67.

Я работаю на эмуляторе VICE x64 на Mac OS X, и я собираюсь с портом OS X 64tass.

Это код сборки без вычитания 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

Вот скриншот с выводом

Вот скриншот с выводом

Спасибо всем в комментариях!

Примечание, чтобы помочь другим

Вы можете установить, в какую строку и столбец CHROUT будет выводиться, установив позицию курсора с помощью PLOT

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

1 ответ

Решение

Вы, возможно, записываете ASCII-коды напрямую в экранную память, поэтому она компенсируется на 40 долларов.

Чтобы они были в PETSCII, вам нужно добавить опцию "-a" в 64tass. Но одного этого недостаточно. Ваш пример теперь будет смещен на $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"

Скомпилируйте его с не слишком старым 64-тассом, который переводит "{clr}" и "{swlc}" в управляющие коды 147 и 14. И не забывайте ключ "-a", чтобы включить поддержку Unicode, иначе ассемблер не будет сделать любой перевод строки и скопировать ее дословно (как необработанные байты).

Другие вопросы по тегам