Коды экранов от ASCII до C64 в DASM Ассемблере

Я изучаю ассемблер для 6502 micro через эмулятор C64. В данный момент пытаюсь вывести строки на экран. Вот мой код:

    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

Поскольку мой редактор (notepad++ на win 10) использует ascii-подобные char-коды, "HELLO" в message это биты 48 45 4C 4C 4F. Это дает следующий вывод в верхнем левом углу экрана: введите описание изображения здесь

Я думаю, это правильно, если посмотреть на таблицу кодов экранов коммодора здесь.

Если я изменю строку 6 на lda hexmsg,x тогда я получаю именно то, что мне нужно, слово HELLO,

Я еще не очень знаком с ассемблером DASM и не могу найти полную документацию по нему (если он существует). Большинство учебных пособий, которые я нашел, только что вы объявили message .byte "HELLO" или что-то подобное, и это просто работает, потому что ассемблер, который они используют, автоматически преобразует ascii-подобную текстовую строку в строку коммодора, но DASM, похоже, этого не делает.

Кто-нибудь знает, как я могу заставить DASM сделать это, или порекомендовать другой способ просто вводить строки в ассемблер, а не вводить вручную строки в виде набора шестнадцатеричных данных?

3 ответа

Решение

Вот исправленная версия DASM aseembler.
http://iancoog.altervista.org/C/dasm2.20.07-iAN_Rev_N.rar

Ты можешь использовать SCRU а также SCRL директивы для преобразования ASCII-> преобразование экранного кода.

label SCRU  "string"
label SCRL  "string"

SCRU для создания заглавного текста, даже если он введен в нижнем регистре. SCRL держит корпус.

Ага, кодировка ASCII против кодов экрана Commodore. Мы все были там. У вас есть несколько вариантов:

  1. Не пишите напрямую в экранную память, а используйте вместо этого подпрограмму Kernal CHROUT (возможно, через процедуру вывода строк более высокого уровня). Тогда все, о чем вам нужно беспокоиться, это различия между ASCII и PETSCII, но это история для другого времени сна. Кроме того, это хорошо для текста, но отстой для игр, поскольку Kernal медленнее, чем прямые записи.

  2. Напишите небольшую подпрограмму преобразования, которая запускается при запуске вашей программы, пожирает вашу таблицу строк и выплевывает преобразованные эквиваленты экранного кода. Быстро и эффективно, при условии, что все строки объединены, и вы не пишете приложение на основе ПЗУ (которое не сможет выполнить преобразование на месте).

  3. Напишите препроцессор DASM, который запускается перед DASM в вашем скрипте сборки и в основном выполняет то же преобразование, что и #2 выше, но в исходный код до того, как ассемблер его увидит. Это может быть немного грубовато, и вы должны быть уверены, что сделали резервную копию исходного источника, прежде чем копировать его.

  4. Получите исходный код DASM и исправьте его, чтобы вызвать пользовательский выход для нового типа данных (для экранных кодов), который выполняет те же функции, что и №2, но на лету во время сборки. Очень коряво.

  5. Используйте строчные буквы в своих строках, которые будут преобразованы в эквиваленты кода экрана в верхнем регистре во время сборки. Возможно, вы упустили из виду тот факт, что вы видите смещенное представление символов в строке, которое в режиме отображения по умолчанию представляет собой графические символы.

Исходя из опыта всех 5 вариантов, я остановился на #2.

Также: переключитесь на KickAssembler, который

  • новее и активно поддерживается
  • предлагает более мощные функции
  • очень хорошо интегрируется с VICE для отладки

Прошло некоторое время с тех пор, как я запрограммировал 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

Если это может помочь, вот небольшой скрипт на 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!")
            
Другие вопросы по тегам