PC-850VSでZ80アセンブラ（1） Hello, Worldする


かつてパソコンが高価だった頃にパソコンのかわりに使われていたと洞窟の壁画に記されていたポケットコンピュータというハードウェアがあるのですが、SHARPのPC-G850VSという機種が未だに新品で販売されているという情報を入手しました。

8MH CPU, 32KB RAMという貧弱なハードウェア（Arduino並）ですが、QWERTYキーボードと液晶がついていてアセンブラでセルフ開発ができ、しかも乾電池4本で数十時間動き続けるというすぐれものです。
どうも老人たちの話によると、MSXという古代のパソコン（見たことも触ったこともない）相当の機能があるとのことです。
おそらく地球最後の8bitパソコンです。

QWERTYキーボードがついていてポケットサイズ（というにはちょっと大きいが）のハードウェアはなんでも好きなので絶滅する前に確保しておこうと思ったのと、気が向いたらついでにアセンブラ入門でもするかと思ってひとつ入手しました。
税込15660円でした。

![IMG_0436.JPG](https://qiita-image-store.s3.amazonaws.com/0/26038/4bf7e608-8a7a-2a6d-4d84-3b69931fb8dd.jpeg "IMG_0436.JPG")

（下に敷いてあるのはMacBook Pro 13inchです）


# Hello, Worldの前に

## マニュアルに載っているサンプルコードを動かしてみる

とても分厚い親切なマニュアルがついてきます。
288 ~ 299ページのチュートリアルをこなせばとりあえずアセンブラでプログラミングする手順が把握できます。
メモリのある領域をアスキーコードの20~9Fで埋めるプログラムを実行して、メモリマップを確認するというチュートリアルでした。

[BASIC] を押して、

    MON

で機械語モニタを起動して、

    D

で機械語が透けて見えます。

# Hello, Worldする

たいへんです。

## 画面に1文字表示してみる

PC-G850VS（を含むSHARPのZ80ベースのポケコン）には、IOCS（パソコンでいうところのBIOS）という機能があり、画面への出力、キーボードからの入力を行うにはこのIOCSの各ルーチンを呼び出せばよいようです。
この情報はマニュアルには載っておらず、[偉大な先人たちが自力で解析した情報を洞窟の壁画に書き記してくれています](http://www.akiyan.com/pc-g850_technical_data#bios)。

例えば画面に1文字表示する場合は、

1. レジスタAに表示したい文字のアスキーコードをセットする
2. レジスタDに文字を表示する画面上のY位置（行）をセットする
3. レジスタEに文字を表示する画面上のX位置（桁）をセットする
4. 0BE62HをCALLする

といった感じです。

画面(0, 0)に "A" を表示するアセンブラのコードは以下のような感じになります。
PC-G850VSのエディタは行番号が必要なラインエディタみたいな謎のエディタなので苦しみながら入力します。
( ``TEXT`` を押して、 ``E`` を押すと入力開始)

```CHARACTER.ASM
10 			ORG 0100H
20	START:	LD A, 'A'
30			LD D, 0H
40			LD E, 0H
50			CALL 0BE62H
60			RET
70			END
```

ところでKobitoのシンタクスハイライターは行番号付きのアセンブラをハイライトしてくれるんですね、すごい。

入力し終わったら ``ASMBL`` ( ``SHIFT`` + ``BASIC`` ) でアセンブラのメニューが出てくるので ``A`` を押します。
Z80アセンブラのメニューが出てくるので再び ``A`` を押すと、テキストエディタで入力していたアセンブラのソースコードが機械語に変換され、ORG命令で指定した番地（この例では0100H）からメモリに書き込まれます。
（PC-G850VSでは0100H以降がUserエリアのようです）

次に、(1) ``CLS`` キーを押すか、(2) ``BASIC`` キーを押してRUMモードにはいり、

    MON

と入力してEnterを押すと、機械語モニタというのが起動します。
（プロンプトが * になる）

この状態で、

    G 0100H

と入力してEnterを押すと、0100H番地からプログラムが実行されます。
液晶の1行目1桁目の文字が A に変わったことと思われます。

あとはこれをコピペしまくればHELLO, WORLD!と表示できそうですね。


## ようやくHello, World

テキストエディタで、C命令を使ってコピーして修正していきます。

C命令の書式:

```
C コピー元開始行番号, コピー元終了行番号, コピー先開始行番号
```

（取扱説明書 173ページより）

入力の動作がデフォルトでインサートではなくリプレースなので、インサートをしたい場合は ``INS`` キーを押します。（もう一度押すと解除されます）
ポケコンの操作はパソコンで一般的な操作からするとかなり癖がありますがキーイングにはあまり違和感がなく非常によくできていると思いました。
``2ndF`` キーがロックありの ``SHIFT`` キーです。``2ndF`` を駆使すると両手でホールドして親指だけで全てのキーが押せました。
キーボードの打鍵感が現代的な似たようなサイズのガジェットと比べると比べ物にならないほどよいのですが、基本的にキーボードから入力せざるをえないのでよくせざるをえないんだなぁという感じがします。

以下のプログラムを入力します。

```HELLO.ASM
10			ORG 0100H
20 START:	LD A, 'H'
30			LD D, 0H
40			LD E, 0H
50			CALL 0BE62H
60			LD A, 'E'
70			LD D, 0H
80			LD E, 1H
90			CALL 0BE62H
100			LD A, 'L'
110			LD D, 0H
120			LD E, 2H
130			CALL 0BE62H
140			LD A, 'L'
150			LD D, 0H
160			LD E, 3H
170			CALL 0BE62H
180			LD A, 'O'
190			LD D, 0H
200			LD E, 4H
210			CALL 0BE62H
220			LD A, ','
230			LD D, 0H
240			LD E, 5H
250			CALL 0BE62H
260			LD A, ' '
270			LD D, 0H
280			LD E, 6H
290			CALL 0BE62H
300			LD A, 'W'
310			LD D, 0H
320			LD E, 7H
330			CALL 0BE62H
340			LD A, 'O'
350			LD D, 0H
360			LD E, 8H
370			CALL 0BE62H
380			LD A, 'R'
390			LD D, 0H
400			LD E, 9H
410			CALL 0BE62H
420			LD A, 'L'
430			LD D, 0H
440			LD E, 0AH
450			CALL 0BE62H
460			LD A, 'D'
470			LD D, 0H
480			LD E, 0BH
490			CALL 0BE62H
500			LD A, '!'
510			LD D, 0H
520			LD E, 0CH
530			CALL 0BE62H
540			RET
550			END
```

大変頭が悪そうな感じになりました。
[CPUの歓声](http://togetter.com/li/675599)が聞こえてきそうですね。

1文字表示のときと同じ手順で機械語に変換してから実行してみます。

``ASMBL`` → ``A`` → ``A`` → ``CLS`` → ``G1011`` → ``↵``

![IMG_0446.JPG](https://qiita-image-store.s3.amazonaws.com/0/26038/6be8efc3-362e-54f2-a8cd-ac9b6a8e870e.jpeg "IMG_0446.JPG")

HELLO, WORLD!できました。
やったねたえちゃん。


## もっといいやりかたがあった

とりあえずIOCSの機能で「1文字表示する（0BE62H）」ができたのでそれを文字数分だけ繰り返せばHello, Worldできるだろと思ってやってみたのですが、IOCSの「文字列を表示する」機能を使ってもっと簡潔にHello, Worldを表示する方法があったのでそっちを試してみます。

```HELLO2.ASM
10			ORG 0100H
20			LD B,13  // Bレジスタに表示する文字数を指定する
30			LD D,0H  // Dレジスタに表示開始カーソル位置（行）を指定する
40			LD E,0H  // Eレジスタに表示開始カーソル位置（桁）を指定する
50			LD HL,WORD  // HLレジスタに文字列が格納されているメモリアドレスを指定する
60			CALL 0BFF1H  // IOCSの文字列表示を呼び出す
70			RET
80WORD:		DB 'HELLO, WORLD!'  // DB擬似命令でメモリ上に文字列を格納する
90			END
```

ソースコードを入力し終わったら、さっきと同じように

``ASMBL`` → ``A`` → ``A`` → ``CLS`` → ``G1011`` → ``↵``

で実行。
実行結果もさっきと同じになるはず。


## 文字を出力する前に画面を消去する

"MACHINE LANGUAGE MONITOR" と表示されていたのが残っているので、HELLO, WORLD!を出力する前に画面をいったんクリアしてみます。

```HELLO3.ASM
100			ORG 0100H
110START:
120			CALL CLS
130			LD B,13
140			LD D,0H
150			LD E,0H
160			LD HL,WORD
170			CALL 0BFF1H
180			RET
190WORD:
200			DB 'HELLO, WORLD!'
210CLS:
220			XOR A
230			LD B, 24*6
240			LD D, 0H
250			LD E, 0H
260			CALL 0BFEEH
270			RET
280			END
```

ソースコードを入力し終わったら、さっきと同じように

``ASMBL`` → ``A`` → ``A`` → ``CLS`` → ``G1011`` → ``↵``

で実行。

![IMG_0563.JPG](https://qiita-image-store.s3.amazonaws.com/0/26038/c1c9a1db-bcaa-92bf-cbef-7689be225db4.jpeg "IMG_0563.JPG")

めでたし。


# 参考情報

* http://www16.ocn.ne.jp/~ver0/document/pcg800iocs.html
* http://www.akiyan.com/pc-g850_technical_data#bios
* http://ha9.seikyou.ne.jp/home/akihi/pdf/C64_PocketBook.pdf
* http://www.systemax.jp/doc/Z80_text.html