mieki256's diary



2019/04/26(金) [n年前の日記]

#1 [pc] Z80のアセンブラでHello Worldをしてみたり

Z80のアセンブラで何かしらを書いて、アセンブルしてバイナリを作って、MZ-700 のエミュレータ上で動かす、といった作業が実際にできるのかどうか気になったので、少し調べて試してみたり。環境は Windows10 x64。

必要なもの。 :

必要になるのは、
  • MZ-700 エミュレータ
  • MZ-700 モニタROM (IPL.ROM)
  • MZ-700 フォントROM (FONT.ROM)
  • Z80用のアセンブラ(Windows上で動くもの)
ぐらいだろうか…。

MZ-700 のエミュレータは、以前は MZ700WIN が入手できたけど、もはや入手が難しいので、EmuZ-700 を利用させてもらうことにした。

_EmuZ-700 / EmuZ-800 / EmuZ-1500 謎WIPページ
_Common Source Code Project

binary.zip をダウンロードして解凍すると、100種類以上のレトロPCエミュレータが入ってるので…。mz700.txt と binary/mz700.exe を、任意のフォルダにコピーする。この mz700.exe が、EmuZ-700。

mz700.exe を実行するためには、IPL.ROM と FONT.ROM が必要になる。

IPL.ROM は、MZ-700/80K/C/1200用互換モニタ MZ-NEW MONITOR を利用させてもらう。

_MZ-NEW MONITOR 使用許諾条件
_MZ-NEW MONITOR 使用許諾条件 (Internet Archive)

(※ 2019/04/28追記。上記リンク先が404になったので、Internet Archive のページを追加。)

mz_newmon.zip をDLして解凍すると、ROMSフォルダの中に、NEWMON.ROM、NEWMON7.ROM があるので…。MZ-700版の NEWMON7.ROM を mz700.exe と同じフォルダにコピーして、IPL.ROM にリネームする。

FONT.ROM は、以下のページを参考にして作成。

_MZ-700WIN フォントデータの作成

MKFNT.zip をDLして解凍。DOS窓を開いて、解凍したフォルダをカレントディレクトリにして、以下を実行。
mkfnt mz700fon
MZ700FON.DAT というファイルができるから、mz700.exe と同じフォルダにコピーして、FONT.ROM にリネームする。

この状態で、mz700.exe を実行すると、EmuZ-700 が起動する。

emuz-700_ss1.png

これでエミュレータは動いた。ありがたや。

次に、Windows上で利用できる Z80アセンブラを入手する。今回は、Z80AS を利用させてもらう。

_We Love MZ-700

上記リンク先ページの真ん中あたりで Z80AS が公開されているので、z80as_012.zip をDL。解凍すると、中に z80as.exe というファイルがあるので、パスが通った場所にコピーする。

これで環境は整った。

Hello wroldのソースを書く。 :

まずはとにかく Hello world だろう…。ということで、画面に「HELLO WORLD」と表示するだけのソースを書いてみる。

適当なエディタで、Z80向けのアセンブラソースを書く。アセンブラソースの拡張子は .asm にしておけばいいのだろうか。

今回は、以下のソースを参考に書いてみたり。ありがたや。

_marukun700/tinyimas700_v1_src: TinyIMAS for MZ-700 source
_tinyimas700_v1_src/tinyimas.asm at master - marukun700/tinyimas700_v1_src

_helloasm.asm
; Display "HELLO WORLD" in MZ-700

; define monitor subroutine

LETNL EQU 0006h
MSG EQU 0015h
        
        ORG 1200h

        ; start

        CALL LETNL      ; newline
        
        LD DE,MSGDT0
        CALL MSG        ; display "HELLO WORLD"
        
        CALL LETNL
        
        LD DE,MSGDT1    ; display "IN MZ-700"
        CALL MSG
        
        RET
        
MSGDT0:
        DB "- HELLO WORLD -"
        DB 0Dh

MSGDT1:
        DB "- IN MZ-700 -"
        DB 0Dh

        END

簡単に説明しておくと…。
  • ORG 1200h で、「このプログラムは 1200h番地から始まるプログラムだよ」と指定する。
  • MZ-80K や MZ-700 は、1200h番地以降にユーザの作ったプログラムを読み込むので、ほとんどの場合、ORG 1200h を最初に書くことになるはず。
  • xxx EQU yyyyh で、xxx というシンボルに、yyyyh という数値を定義する。
  • ソースの最後には、END と書いておく。
  • xxxx: はラベル。
  • DB "HOGE" で、HOGE をASCIIコードにしたバイナリ列を記述できる。
  • DB 01h,02h,03h と書けば、01h,02h,03h というバイナリを記述できる。
  • 16進数を記述する時は、0003h とか 0D000h のように、最後に h をつける。

その他の仕様は、Z80AS のドキュメントを参照のこと。

_Z80 Abusolute Assembler 'Z80AS'

Z80のニーモニック(命令?)については、以下が参考になりそう。

_Z-80の命令の簡単な解説(1)
_Z-80の命令の簡単な解説(2)
_8ビットCPU Z80 (命令セット)
_Z80 Code Refference -
_Z80 MNemonic Refference -

さて。MZ-700 のモニタROMには、改行をしてくれるサブルーチンや、メッセージを表示してくれるサブルーチンが用意されてるので、今回はソレを使わせてもらう。前述のソース内では、CALL LETNL や CALL MSG が、それらのサブルーチンを呼び出している行。

モニタROMにどんなサブルーチンが用意されているかは、以下を眺めればおおよそ分かる。たぶん。

_1Z-009Amonitor_note.pdf
_SP-1002 - Enri's Home PAGE (mz-80K)

1Z-009A が、MZ-700のモニタの型番で、SP-1002 が、MZ-80K のモニタの型番。MZ-700 のモニタは、MZ-80K のモニタと中身が完全に同じではないけれど、サブルーチンを呼び出す際のアドレスが合わせてあったりするので、ある程度は互換性がある。

プログラム側のメインルーチンで RET が呼ばれると、モニタの処理に戻ってくる模様。

アセンブルする。 :

ソースを書いたのでアセンブルする。DOS窓上で以下を打つ。
z80as helloasm.asm
helloasm.bin という、Z80用のバイナリファイルができた。バイナリエディタの類で中身を覗いてみると…。

helloasm_bin_ss1.png

Z80の各命令が、Z80用のバイナリに変換されて並んでいることが分かる。アセンブルはできているっぽい。

このままだと、MZ-700のエミュレータでは読み込めないので、.mzt 形式(カセットテープ相当のファイル)として出力させる。
z80as -mHELLOASM helloasm.asm
helloasm.mzt が出力された。

Z80AS は、-m オプションをつけることで、アセンブル結果を .mzt 形式にして出力することができる。
  • -mHOGE とつければ、テープに保存されたファイルのファイル名は「HOGE」になるし、
  • -mFUGA とつければ、テープに保存されたファイルのファイル名は「FUGA」になる。
今回は -mHELLOASM とつけてるので、テープに保存されたファイル名は「HELLOASM」になる。

MZ-80系の場合、テープに保存する際のファイル名は英数大文字にしておいたほうが良さそう。元々は小文字が存在しないPCだったようだし…。

エミュレータ上で実行。 :

MZ-700のエミュレータ、EmuZ-700 上で、先ほどアセンブルして出来上がったファイルを読み込んで実行してみる。

EmuZ-700 を起動すると、
 MZ-700
*
と表示されて入力待ちになる。L[Enter] と打ち込んで、「テープからロードせよ」と指示する。(L は LOAD の L。)

メニューの、CMT → Play を選択。ファイル選択ダイアログが開くので、先ほど生成した helloasm.mzt を選択してやる。実機であれば、データレコーダにカセットテープを入れて、データレコーダのPlayボタンを押した状態に相当する。

EmuZ-700 画面下部のステータスバーに、テープの読み込み状況が表示される。ある程度進むと、画面上に、「LO. HELLOASM」と表示される。「テープに入っているファイル名(HELLOASM)は認識したよ」「このまま読み込みを続けるよ」ということ。

ロードが終わると、読み込んだプログラムが自動で実行される。

helloasm_mzt_ss1.png

「HELLO WORLD」が表示された。動いたっぽい。

ちなみに、再度実行したい時は、
GOTO$1200
と打ち込む。1200h番地にジャンプするらしい。

別のプログラムを書いてみる。 :

調子に乗って別のプログラムを書いてみる。画面全体を何度も書き換える処理を書いてみよう…。

_fillscrn.asm
; Fill screen in MZ-700
;
; EXIT : Q key or SHIFT + BREAK

GETKY EQU 001Bh
BRKEY EQU 001Eh
?BLNK   EQU 0DA6h
        
        
VRAM EQU 0D000h
VRAMA EQU 0D800h
        
        ORG 1200h

        ; start

        ; attribute VRAM fill
        LD A,70h
        LD HL,VRAMA
        LD BC,40*25
        CALL MEMFIL

        LD IX,CHRLIST
        LD A,(IX)
LOOP0:
        CALL ?BLNK      ; wait VBLANK

        LD HL,VRAM
        LD BC,40*25
        CALL MEMFIL     ; fill screen

        CALL GETKY
        CP 81           ; check ASCII 'Q' Key
        JP Z,SCRCLR

        CALL BRKEY      ; check SHIFT + BREAK
        JP Z,SCRCLR
        
        INC IX
        LD A,(IX)       ; get new display code
        CP 0
        JR NZ,LOOP0
        
        LD IX,CHRLIST
        LD A,(IX)
        JR LOOP0

SCRCLR:
        LD A,0
        LD HL,VRAM
        LD BC,40*25
        CALL MEMFIL     ; screen clear
        
        RET

MEMFIL:
        LD D,H
        LD E,L
        INC DE
        DEC BC
        LD (HL),A
        LDIR
        RET

CHRLIST:
        DB 70h,30h,74h,34h,78h,38h,7Ch,3Ch
        DB 00
        
        END

z80as -mFILLSCRN fillscrn.asm

_tinyimas700_v1_src/tinyimas.asm を参考にさせてもらいました。ありがたや。

実行結果は以下。



Qキーか SHIFT+BREAKキーで処理を抜ける。

一応簡単な説明を。MZ-700 は、0D000h からVRAMが、0D800hからアトリビュートVRAMが割り当てられているので、そのあたりに何かを書き込めば、文字を表示したり、色を変更したり等ができる。

_Programming MZ-700: Display

また、MZ-700は、1文字 8x8ドット、40x25文字のキャラクタ画面しか持ってないので、ドット単位のスクロールなんてできないのだけど。文字の中に1ドットずつずれてる横線があるので、今回はソレを使って画面を埋め尽くすことで、ドット単位のスクロールをしているような気分だけをほのかに味わっているという、なんだかちょっと悲しさが漂うプログラムだったりもする。

ということで、Z80のアセンブラでソースを書いて、アセンブルして、MZ-700のエミュレータ上で動かせることが確認できた。とメモ。

EmuZ-700について少しメモ。 :

EmuZ-700 は、実機動作の再現度を高めたエミュレータなので、実機と同程度の速度でテープ(.mzt)からプログラムを読み込むため、プログラムのロードに数分かかったりするのだけれど。

メニューの、Control → Full Speed にチェックを入れると、動作速度が上がってテープの読み込み時間も短くなることに今頃気づいた。とメモ。もちろん、ロード後は、件の項目のチェックを外さないとアレだけど。

以上です。

過去ログ表示

Prev - 2019/04 - Next
1 2 3 4 5 6
7 8 9 10 11 12 13
14 15 16 17 18 19 20
21 22 23 24 25 26 27
28 29 30

カテゴリで表示

検索機能は Namazu for hns で提供されています。(詳細指定/ヘルプ


注意: 現在使用の日記自動生成システムは Version 2.19.6 です。
公開されている日記自動生成システムは Version 2.19.5 です。

Powered by hns-2.19.6, HyperNikkiSystem Project