それではまずは古典で22文字出力の例を(22BPT):
#include "osecpu_ask.h"
junkApi_putConstString0('Wak');
junkApi_putConstString0('ayama');
junkApi_putConstString0('Bok');
junkApi_putConstString0('usuiW');
junkApi_putConstString6('akayam');
51 03 57 61 6B
51 05 61 79 61 6D 61
51 03 42 6F 6B
51 05 75 73 75 69 57
51 6C 3A F0 F9 C3 B4
- 解説。OSECPUでは0.5バイト単位で命令を記述します。そして"5"はAPI呼出し命令で、その後に引数が後続します。"5"の次の"1"は機能番号であり、これは文字列表示APIを意味します。だからみんな51で始まっているわけです。
- 「51 03 57 61 6B」についてもう少し詳しく見てみます。51の次の0は、文字列をどのようにエンコードしたかという情報を表しています。モード0は、UInt8形式です。次の3は文字列長を意味しています。「57 61 6B」はもちろん'Wak'のASCIIコードです。
- つまりOSECPUでは、たった5バイトだけでも任意の3文字を出力できてしまうのです。
- これはルールの(2)に違反しているように見えるかもしれません。・・・いやいや、とんでもない。これはデータなどではなく、れっきとしたプログラムです。JITコンパイラによって実行されるときには、
- R30レジスタに機能番号が代入されて、
- R31レジスタには文字長3が代入され、
- スタックから3バイトを確保し、
- そこへで律儀に57, 61, 6Bをひとつずつ書き込んで、
- そのポインタをP31に格納して、
- PCALL(P28);を実行して、
- その後スタックを開放する、
- という長いプログラムにちゃんと変換されているのです。なにかデータのように見えてしまうのは、OSECPUは徹底して機能密度を追求した結果、必要最低限の制御情報だけになり、データばかりになってしまったためです。
- ここまでの説明で、最初の4行については完全に理解できると思います。問題は最後の1行です。これはモード6です。
- モード6は文字列長の記述はなく、0という終端文字がくるまで文字列が続くとみなします。しかもモード6はUInt8ではなくUInt7なのです。つまり7ビットエンコードなのです。「C3AF0F9C3B4」を2進数に変換して、それを7ビットずつ区切って、それを16進数で表すと「61 6B 61 79 61 6D」にちゃんとなります。これでは終端文字がないではないかと思うでしょう。しかしOSECPUではファイル終端を検出すると0終端処理が行われるのでこれで問題ありません。とまあそんなわけで、最後の行に関しては7バイトで6文字を出力できているわけです。
- おっとこれは終了処理が何もありませんね。でもOSECPUは終了処理を書かなくてもファイル終端に正常終了処理を付与してから実行するので問題ありません。