簡體   English   中英

DASM 匯編器中的 ASCII 到 C64 屏幕代碼

[英]ASCII to C64 Screen Codes In DASM Assembler

我正在通過 C64 模擬器學習 6502 micro 的匯編。 目前正在嘗試將字符串輸出到屏幕。 這是我的代碼:

    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

因為我的編輯器(win 10 上的記事本++)使用類似 ascii 的字符代碼, message"HELLO"是位 48 45 4C 4C 4F。 這會在屏幕的左上角提供以下輸出: 在此處輸入圖片說明

通過查看此處的准將屏幕代碼表,我猜這是正確的。

如果我將第 6 行更改為lda hexmsg,x那么我得到的正是我想要的, HELLO一詞。

我對 DASM 匯編程序還不是很熟悉,並且無法找到它的完整文檔(如果存在)。 我發現的大多數教程只是讓你聲明message .byte "HELLO"或類似的東西,它只是有效,因為他們使用的匯編程序會自動將類似 ascii 的文本字符串自動轉換為 commodore 字符串,但 DASM 似乎沒有要做到這一點。

有誰知道我可以讓 DASM 做到這一點的方法,或者推薦另一種方法來簡單地將字符串輸入到匯編程序中,而不是手動將我的字符串輸入為一堆十六進制數據?

啊哈,ASCII 編碼與 Commodore 屏幕代碼。 我們都去過那里。 您有幾個選擇:

  1. 不要直接寫入屏幕內存,而是使用內核 CHROUT 例程(可能通過更高級別的字符串輸出例程)。 那么您只需要擔心 ASCII 和 PETSCII 之間的差異,但這是另一個睡前故事。 此外,這對文本很有用,但對游戲來說很糟糕,因為與直接寫入相比,內核速度較慢。

  2. 編寫一個小轉換例程,在程序啟動時運行,吃掉你的字符串表,並吐出轉換后的屏幕代碼等價物。 快速且高效,前提是您的字符串都在一起並且您沒有編寫基於 ROM 的應用程序(該應用程序無法進行就地轉換)。

  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

這是 DASM aseembler 的修補版本。
http://iancoog.altervista.org/C/dasm2.20.07-iAN_Rev_N.rar

您可以使用SCRUSCRL指令來轉換 ASCII->Screencode 轉換。

label SCRU  "string"
label SCRL  "string"

SCRU用於制作大寫文本,即使輸入小寫也是如此。 SCRL保持外殼。

如果它可以幫助,這里有一個小的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!")
            

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM