Почему символы смещены на 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
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, иначе ассемблер не будет сделать любой перевод строки и скопировать ее дословно (как необработанные байты).