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

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

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

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

В ПЗУ фактического генератора символов использовался другой набор назначений. Например, чтобы отобразить символы «@ABC» на экране, напрямую выполнив POKE в памяти экрана, нужно POKE использовать десятичные значения 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


person Joe Bentley    schedule 10.09.2014    source источник
comment
Вы читали это: wpguru.co.uk/2014/06/ ?   -  person Michael    schedule 10.09.2014
comment
@Michael Я попробую это, но даже в режиме без сдвига он должен отображать буквы верхнего регистра в 0x40 в соответствии с диаграммой PETSCII upload.wikimedia.org/wikipedia/commons/c/c4/   -  person Joe Bentley    schedule 10.09.2014
comment
Любое руководство по программированию C=64 должно иметь 2 таблицы символов, к которым вы можете обращаться: экранные коды и PETSCII. Когда вы сохраняете символы на экране за 400 долларов, вы используете экранные коды. экранные коды Google c64 -› sta.c64.org/cbm64scr.html   -  person    schedule 10.09.2014
comment
Спасибо, я не знал об этом! Я нашел инструмент преобразования здесь sta.c64.org/cbm64pettoscr.html.   -  person Joe Bentley    schedule 10.09.2014
comment
Хорошо, предложение @Michael, кажется, работает, то есть изменение набора символов верхнего/нижнего регистра, кажется, исправляет это и позволяет мне использовать 0x40 в качестве ожидаемых символов. Хорошо, это имеет смысл, так как он выдвигает буквы в более высокий конец в таблице кодов экрана. К сожалению, это не работает для строчных букв, поэтому в этом случае требуется другое преобразование.   -  person Joe Bentley    schedule 10.09.2014
comment
Кстати, обычная техника вывода символов в строку из источника PETSCII заключается в вызове CHROUT   -  person    schedule 10.09.2014


Ответы (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"

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

person guest01    schedule 10.09.2014
comment
Это отличный ответ! Спасибо вам и всем в комментариях, это очень полезно, я не думал использовать CHROUT. Это очень полезно - person Joe Bentley; 10.09.2014