Skip to content

Instantly share code, notes, and snippets.

@h1romas4
Last active December 11, 2022 12:28
Show Gist options
  • Save h1romas4/d9606059d2102bf2ae278fe07b57d2cf to your computer and use it in GitHub Desktop.
Save h1romas4/d9606059d2102bf2ae278fe07b57d2cf to your computer and use it in GitHub Desktop.
z88dk MSX ROM 向けアセンブラビルドサンプル
{
// .vscode/tasks.json
"version": "2.0.0",
"tasks": [
{
"label": "Assemble",
"type": "shell",
"linux": {
"command": "zcc",
"args": [
"+msx",
"-subtype=rom",
"-create-app",
"-vn",
"--list",
"-o",
"test",
"${workspaceFolder}/src/msx/test.asm"
]
}
},
]
}
; test.asm by @aburi6800 (thanks!)
; https://twitter.com/aburi6800/status/1431507993527418884
; @see
; https://github.com/z88dk/z88dk/blob/master/doc/overview.md#a-quick-note-for-asm-code
; code_user is for read-only code
; called by the crt as entry to program
SECTION code_user
PUBLIC _main
; メイン
_main:
CALL INIT ; 初期化処理
LOOP:
LD DE,$1 ; DEレジスタに加算する値を設定
; BCD形式で指定する(&H50=50)
CALL ADDSCORE
CALL PRTSCORE
CALL BREAKX ; BIOS CTRL+STOP呼び出し
; - CTRl+STOPが押されるとキャリーフラグが立つ
RET C
XOR A ; Aレジスタの値をクリア
JR LOOP
RET ; 未到達ですが気持ちリターンしておく
; 初期化
INIT:
LD IX,SCORE
LD (IX),0
LD (IX+1),0
LD (IX+2),0
; ■固定文字列の表示
LD HL,$192C ; HLレジスタに表示先のVRAMアドレスを設定(12,9)
LD BC,DUMMY1 ; BCレジスタに表示文字列データのアドレスを設定
CALL PRTSTR
LD HL,$1952 ; HLレジスタに表示先のVRAMアドレスを設定(18,10)
LD BC,DUMMY2 ; BCレジスタに表示文字列データのアドレスを設定
CALL PRTSTR
RET
; スコア加算サブルーチン
ADDSCORE:
LD IX,SCORE ; IXレジスタにスコアのアドレスを設定
; ■5〜6桁目の加算
LD A,E ; AレジスタにEレジスタの値をロード
ADD A,(IX+2) ; Aレジスタの値に(IX+2)の値を加算
; 桁溢れした場合はキャリーフラグが立つ
DAA ; Aレジスタの値を内部10進に補正
LD (IX+2),A ; Aレジスタの値を(IX+2)に格納
; ■3〜4桁目の加算
LD A,D ; AレジスタにDレジスタの値をロード
ADC A,(IX+1) ; Aレジスタの値に(IX+1)+キャリーフラグを加算
; 桁溢れした場合はキャリーフラグが立つ
DAA ; Aレジスタの値を内部10進に補正
LD (IX+1),A ; Aレジスタの値を(IX+1)に格納
; ■1〜2桁目の加算
LD A,0 ; Aレジスタに0をロード
ADC A,(IX) ; Aレジスタに(IX)+キャリーフラグの値を加算
; 桁溢れした場合はキャリーフラグが立つ
; が、これ以上桁がないので無視する
DAA ; Aレジスタの値を内部10進に補正
LD (IX),A ; Aレジスタの値を(IX)に格納
RET
; スコア表示サブルーチン
PRTSCORE:
PUSH BC
PUSH HL
LD BC,SCORE ; BCレジスタにスコアの1〜2桁目のアドレスを設定
LD HL,SCORELOC ; HLレジスタにスコアの表示開始アドレスを設定
CALL PRTSC1 ; スコアの1〜2桁目を表示
INC BC ; BCレジスタの値を1加算(=スコアの3〜4桁目のアドレスが設定される)
INC HL ; HLレジスタの値を1加算(=スコアの表示位置を1つ右に移動)
CALL PRTSC1 ; スコアの3〜4桁目を表示
INC BC ; BCレジスタの値を1加算(=スコアの5〜6桁目のアドレスが設定される)
INC HL ; HLレジスタの値を1加算(=スコアの表示位置を1つ右に移動)
CALL PRTSC1 ; スコアの5〜6桁目を表示
POP HL
POP BC
RET
PRTSC1:
; ■上1桁の処理
LD A,(BC) ; Aレジスタにスコアのアドレスの値をロード
SRL A ; Aレジスタの値を4回右シフトして、上位4ビットを取り出す
SRL A
SRL A
SRL A
CALL PRTSC2 ; スコア表示
; このサブルーチン内で定義している表示処理を呼び出す
; ■下1桁の処理
LD A,(BC) ; Aレジスタにスコアのアドレスの値をロード
INC HL ; HLレジスタの値を1加算(=スコアの表示位置を1つ右に移動)
PRTSC2:
; ■表示するデータの準備
AND $F ; 上位4ビットをゼロにする(=下位4ビットの値だけ取り出す)
ADD A,$30 ; 値にキャラクタコード&H30('0')を加える
CALL WRTVRM ; BIOS WRTVRM呼び出し
; - HL : 書き込み先のVRAMアドレス
; - A : 書き込むデータ
RET
; 文字列表示サブルーチン
; IN : HL=表示開始VRAMアドレス
; BC=表示文字データの開始アドレス
PRTSTR:
PUSH HL
PUSH BC
PRTLOOP:
LD A,(BC) ; AレジスタにBCレジスタの示すアドレスのデータを取得
OR 0 ; 0かどうか
JR Z,PRTEND ; 0の場合はPRTENDへ
CALL WRTVRM ; BIOS WRTVRM呼び出し
; - HL : 書き込み先のVRAMアドレス
; - A : 書き込むデータ
INC HL ; HL=HL+1
INC BC ; BC=BC+1
JR PRTLOOP
PRTEND:
POP BC
POP HL
RET
; 8ビットの値を16進数で表示するサブルーチン
; IN : A=表示する値(8ビット)
; OUT : NONE
PUTA:
PUSH BC ; 使用するレジスタの値をスタックに退避
PUSH AF
CALL PUTHEX ; Aレジスタの値を16進数で表示
POP AF ; スタックに退避したレジスタの値を復帰
POP BC
RET
; 16ビットの値を16進数で表示するサブルーチン
; Aレジスタの値を破壊します
; IN : HL=表示する値(16ビット)
; OUT : NONE
PUTHL:
PUSH BC ; 使用するレジスタの値をスタックに退避
PUSH AF
LD A,H ; AレジスタにHレジスタの値をロード
CALL PUTHEX ; Aレジスタの値を16進数で表示
LD A,L ; AレジスタにLレジスタの値をロード
CALL PUTHEX ; Aレジスタの値を16進数で表示
POP AF ; スタックに退避したレジスタの値を復帰
POP BC
RET
; 1バイトの値を16進数2桁で表示するサブルーチン
; A,Cレジスタの値を破壊します
; IN : A=表示する値
PUTHEX:
LD C,A ; Aレジスタの値をCレジスタにロード
SRL A ; Aレジスタの値を4回右シフトして、上位4ビットを取り出す
SRL A
SRL A
SRL A
CALL PUTONE ; 1文字表示
LD A,C ; Cレジスタの値をAレジスタに戻す
AND $F ; 下位4ビットだけ取り出す
CALL PUTONE
RET
; 4ビットの値を16進数1桁で表示するサブルーチン
; Aレジスタの値を破壊します
PUTONE:
CP $A
JR NC,PUTLET ; 10以上であればA~Fを表示
ADD A,$30 ; 値にキャラクタコード&H30('0')を加える
CALL CHPUT
RET
PUTLET:
ADD A,$37 ; 値に&H37("7")を加える
; 10以上が設定されるため、結果は&H41("A")~&H46("F")となる
CALL CHPUT
RET
; rodata_user if for constant data
; kept in rom if program is in rom
SECTION rodata_user
CHPUT: EQU $00A2 ; BIOS CHPUT
RDVRM: EQU $004A ; BIOS RDVRM
WRTVRM: EQU $004D ; BIOS WRTVRM
BREAKX: EQU $00B7 ; BIOS CTRL+STOP
SCORELOC: EQU $194D ; スコア表示先のVPRAMアドレス
DUMMY1: DB "SCORE",0 ; "SCORE"
DUMMY2: DB "00",0 ; スコア下2桁の表示文字列
; bss_user is for zeroed ram variables
; zeroed by crt when program started
SECTION bss_user
; スコア
SCORE:
defs 3
; data_user is for initially non-zero ram variables
; initialized in ram by crt if the program is in rom
SECTION data_user
# build
zcc +msx -subtype=rom -create-app -vn -o test src/msx/test.asm
# z88dk/lib/target/msx/classic/msx_crt0.asm を使わずに自前でプログラムに開始アドレスを
# つけたり ROM ヘッダーつけたり SP などの初期化をする場合
zcc +msx -subtype=rom -create-app -vn -o --no-crt test src/msx/test.asm
# build (manual)
z80asm -b src/msx/test.asm
z88dk-appmake +msxrom -b src/msx/test.bin
@h1romas4
Copy link
Author

h1romas4 commented Sep 3, 2021

C-BIOS (Japan) (MSX2)  cbios  - MAME 0 235 (LP64)_021

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment