Z80版8ビットコンパイラ stellarを入力してみました
5月20日の「コンパイラ作成の試み その1「ハイクラスC言語」のリストを入力」で参考文献として紹介しました「Z80CPU対応 新言語作成の技法 (大貫広幸著 MIA社)」中に掲載されています、CP/M-80で動作するコンパイラ言語 stellarのアセンブルリストを入力してみました。
120ページ以上ありましたが、何とか入力してCP/M-80のMacro-80でアセンブルして実行形式を作成することができました。
作成したファイルは
・stellar.com コンパイラ オブジェクトファイルを生成
・convobj.com 生成されたオブジェクトファイルをHEX形式に変換
の2つで、コンパイルの手順は 下に例を示しましたが、stellar.com でコンパイル、convobj.com でHEX形式に変換、save.comでディスクに保存した後に実行となります。
d>stellar mdump
Stellar compiler Rev 1.01 ( CP/M-80,MSX-DOS Version )
Copyright (c) 1984 H.Ohnuki / MIA
Program name : mdump
Function name : getchr
Function name : putchr
Function name : putnl
Function name : putstr
Function name : puthex
Function name : puthex1
Function name : bdos
Program 04EF (0100-05EE)
Data 0047 (4000-4046)
** End of compile, No error(s)
d>convobj mdump
Stellar utility, convert object ==> intel HEX
Rev 1.00 Copyright (c) 1984 H.Ohnuki / MIA
Program name : mdump = 0100
Function name : getchr = 0482
Function name : putchr = 04A1
Function name : putnl = 04C4
Function name : putstr = 0511
Function name : puthex = 0549
Function name : puthex1 = 057A
Function name : bdos = 05B6
Constant name : _work = 4000
Constant name : _var = 4030
Constant name : _code = 0100
Constant name : ngetchr = 0001
Constant name : nputchr = 0002
Variable name : d = 4030
Variable name : i = 4031
Variable name : sttadr = 4032
Variable name : endadr = 4036
Variable name : sadr = 403A
Variable name : eadr = 403C
Variable name : ch = 403E
Data name : msttadr = 020D
Data name : mendadr = 0217
Data name : header = 0221
End address : 05EE
Program size : 04EF [ 5 Page ]
d>save 5 mdump.com
d>
d>mdump
sttadr= $1234
endadr= $1567
+0 +1 +2 +3 +4 +5 +6 +7 +8 +9 +A +B +C +D +E +F 0123456789ABCDEF
1230: 55 E5 22 DD 55 CD E8 12 3E 32 2B CD 79 23 21 00 U.".U...>2+.y#!.
1240: 00 22 DF 55 3A 93 55 FE 7B 28 1F FE 9A C2 19 2A .".U:.U.{(.....*
1250: CD 1A 25 CD C5 17 FE 7B C2 19 2A 2A 6D 55 22 DF ..%....{..**mU".
1260: 55 CD E8 12 3E 32 2B CD 79 23 CD 50 15 2A DD 55 U...>2+.y#.P.*.U
1270: CD 48 22 2A DB 55 CD 48 22 21 F9 12 CD A5 22 2A .H"*.U.H"!...."*
1280: 69 55 2B 2B 22 D9 55 CD 93 11 2A DF 55 7C B5 20 iU++".U...*.U|.
1290: 19 2A DB 55 3E 21 CD 79 23 3E 34 CD 5E 23 2A D7 .*.U>!.y#>4.^#*.
12A0: 55 3E 20 CD 35 15 3E C2 18 19 CD 48 22 2A DB 55 U> .5.>....H"*.U
12B0: CD 48 22 21 04 13 CD A5 22 2A D7 55 3E 30 CD 35 .H"!...."*.U>0.5
12C0: 15 3E D2 DC 79 23 CD 68 15 E1 22 6D 55 01 06 00 .>..y#.h.."mU...
12D0: 21 DB 55 CD 0E 25 01 0F 00 21 73 55 CD 0E 25 21 !.U..%...!sU..%!
12E0: 73 55 CD 39 08 C3 1A 25 23 22 6D 55 EB 2A 6B 55 sU.9...%#"mU.*kU
12F0: B7 ED 52 EB D0 22 6B 55 C9 0A 3A B9 B9 21 BB BB ..R.."kU..:..!..
+0 +1 +2 +3 +4 +5 +6 +7 +8 +9 +A +B +C +D +E +F 0123456789ABCDEF
1300: 96 DA 00 00 08 3A B9 B9 21 BB BB 86 77 FE 23 CA .....:..!...w.#.
1310: 97 13 3D C2 19 2A 21 73 55 CD C0 08 B7 C4 7F 28 ..=..*!sU......(
1320: 21 73 55 7E E6 2F FE 02 C2 19 2A 01 0F 00 CD FE !sU~./....*.....
1330: 24 21 73 55 CB EE CD 39 08 2A DB 55 E5 2A 80 55 $!sU...9.*.U.*.U
1340: 22 DB 55 CD 1A 25 FE 2C C2 19 2A CD 1A 25 CD C5 ".U..%.,..*..%..
1350: 17 FE 7B C2 19 2A 3E 32 2A DB 55 CD 79 23 CD 50 ..{..*>2*.U.y#.P
1360: 15 CD 93 11 3E 21 2A DB 55 CD 79 23 3E 35 CD 5E ....>!*.U.y#>5.^
1370: 23 2A D7 55 3E 20 CD 35 15 3E C2 DC 79 23 CD 68 #*.U> .5.>..y#.h
1380: 15 E1 22 DB 55 01 0F 00 21 73 55 CD 0E 25 21 73 ..".U...!sU..%!s
1390: 55 CD 39 08 C3 1A 25 21 96 55 7E B7 C2 19 2A 2F U.9...%!.U~...*/
13A0: 77 CD 1A 25 FE 2C C2 19 2A CD 1A 25 CD 00 18 47 w..%.,..*..%...G
13B0: 3A 98 55 3D C2 48 2A 78 FE 7B C2 19 2A FD 7E FD :.U=.H*x.{..*.~.
13C0: B7 28 11 21 F7 17 3D 28 08 21 FF 13 CD 9A 22 18 .(.!..=(.!....".
13D0: 08 CD 9A 22 3E 47 CD 5E 23 CD 50 15 CD 93 11 2A ...">G.^#.P....*
13E0: D7 55 3E 10 CD 35 15 30 0C E5 3E 05 CD 5E 23 E1 .U>..5.0..>..^#.
13F0: 3E C2 CD 79 23 AF 32 96 55 CD 68 15 C3 1A 25 02 >..y#.2.U.h...%.
+0 +1 +2 +3 +4 +5 +6 +7 +8 +9 +A +B +C +D +E +F 0123456789ABCDEF
1400: 06 B8 2A E3 55 E5 2A E1 55 E5 21 00 00 22 E3 55 ..*.U.*.U.!..".U
1410: 22 E1 55 CD C5 17 FE 94 C2 19 2A 3E B7 CD 5E 23 ".U.......*>..^#
1420: 3E CA 21 00 00 CD 79 23 2A 69 55 2B 2B 22 E1 55 >.!...y#*iU++".U
1430: CD 1A 25 CD 91 10 3A 93 55 FE BD 28 2A FE 95 28 ..%...:.U..(*..(
1440: 08 2A E1 55 CD C2 23 18 0D CD 1A 25 FE 93 28 17 .*.U..#....%..(.
1450: CD 6F 14 CD 91 10 2A E3 55 7C B5 C4 C2 23 E1 22 .o....*.U|...#."
1460: E1 55 E1 22 E3 55 C9 CD 6F 14 CD 1A 25 18 A4 2A .U.".U..o...%..*
1470: E3 55 3E C3 CD 79 23 2A E1 55 CD C2 23 2A 69 55 .U>..y#*.U..#*iU
1480: 2B 2B 22 E3 55 C9 FE 3B C2 19 2A 3E C3 2A D9 55 ++".U..;..*>.*.U
1490: CD 79 23 2A 69 55 2B 2B 22 D9 55 C3 1A 25 FE 99 .y#*iU++".U..%..
14A0: C2 19 2A CD 1A 25 3D C2 19 2A 21 73 55 CD C0 08 ..*..%=..*!sU...
14B0: B7 28 0D 3E 98 32 73 55 21 00 00 22 80 55 18 1E .(.>.2sU!..".U..
14C0: 3A 73 55 47 E6 0F FE 08 C2 19 2A 2A 80 55 78 87 :sUG......**.Ux.
14D0: 38 0C 3E 18 CD 35 15 3E C3 DC 79 23 18 13 3E C3 8.>..5.>..y#..>.
14E0: CD 79 23 2A 69 55 2B 2B 22 80 55 21 73 55 CD 39 .y#*iU++".U!sU.9
14F0: 08 CD 1A 25 FE 3B C2 19 2A C3 1A 25 FE 3B C2 19 ...%.;..*..%.;..
+0 +1 +2 +3 +4 +5 +6 +7 +8 +9 +A +B +C +D +E +F 0123456789ABCDEF
1500: 2A 3A E9 55 B7 28 12 3E C3 2A EA 55 CD 79 23 2A *:.U.(.>.*.U.y#*
1510: 69 55 2B 2B 22 EA 55 18 05 3E C9 CD 5E 23 C3 1A iU++".U..>..^#..
1520: 25 FE 3B C2 19 2A 3E C3 2A 63 55 11 03 00 19 CD %.;..*>.*cU.....
1530: 79 23 C3 1A 25 E5 F5 ED 5B 69 55 13 13 B7 ED 52 y#..%...[iU....R
1540: D1 5D 7D 87 9F BC E1 20 05 CD 6F 23 B7 C9 37 C9 .]}.... ..o#..7.
1550: DD E1 2A D7 55 E5 2A D9 55 E5 21 00 00 22 D9 55 ..*.U.*.U.!..".U
1560: 2A 69 55 22 D7 55 DD E9 DD E1 2A D9 55 7C B5 C4 *iU".U....*.U|..
stellar言語の特徴ですが、基本データ長は8ビットです。(68系のTL/1と同じですね)
しかし、64KBのメモリ範囲をアクセスできる関数が用意されているので、それ程不都合はないようです。また、制御構文も if, while, until, for, loop文があるのでプログラムが組みやすいようです。
特筆すべきは、inline文が用意されていて、プログラム中に機械語命令やデータを入れることができることと、インデックスレジスタ IX,IYを操作する文があることです。
書籍にはサンプルとしてファイルダンプ fdumpとハノイの塔 hanoi がありましたので、それらを参考にして、メモリダンププログラム mdump を作成してみました。
/* memory dump */
prog mdump();
cons ngetchr := 1, /* get chr from console */
nputchr := 2; /* put chr to console */
var d, i,
sttadr[4], endadr[4],
sadr[2], eadr[2],
ch;
data msttadr: "sttadr= $",0,
mendadr: "endadr= $",0,
header: " +0 +1 +2 +3 +4 +5 +6 +7 +8 +9 +A +B +C +D +E +F 0123456789ABCDEF",0;
{
/* input disp adrs area */
putstr(;.msttadr);
for i:=0 to 3 {
sttadr[i] := getchr();
}
putnl();
putstr(;.mendadr);
for i:=0 to 3 {
endadr[i] := getchr();
}
putnl(2);
sadr[0] := (sttadr[0]-$30)*$10+(sttadr[1]-$30);
sadr[1] := (sttadr[2]-$30)*$10+(sttadr[3]-$30);
eadr[0] := (endadr[0]-$30)*$10+(endadr[1]-$30);
eadr[1] := (endadr[2]-$30)*$10+(endadr[3]-$30);
/* disp memory data */
sadr[1] := sadr[1] & $f0; /* start from adrlow=$x0 */
{
putstr(;.header);
putnl();
{
puthex(sadr[0]); puthex(sadr[1]);putchr(':');putchr(' '); /* disp adrs */
for i:=0 to 15 {
puthex(memory[sadr[0], (sadr[1])+i]); putchr(' '); /* disp by hex */
}
putchr(' ');
for i:=0 to 15 {
d:=memory[sadr[0], (sadr[1])+i];
ch:= ?(d>=$20 & d<=$7e;d,'.');
putchr(ch); /* disp by ascii */
}
putnl();
sadr[1] := sadr[1] + $10;
} until (((sadr[0] <> eadr[0]) & (sadr[1] = $00)) | ((sadr[0] = eadr[0]) & (sadr[1] > eadr[1])));
putnl();
sadr[0] := sadr[0] + 1;
} until ((sadr[0] > eadr[0]));
}
/***** subroutine *****/
getchr();
{
bdos(ngetchr);
}
putchr(x);
{
bdos(nputchr, x);
}
putnl(n);
cons
cr := $0d,
lf := $0a;
var
pn at ( _work );
{
if pn=0 then n:=1;
loop #,n {
bdos(nputchr, cr);
bdos(nputchr, lf);
}
}
putstr(;ix);
var x;
{
while x:=@[ix+] {
bdos(nputchr, x);
}
}
puthex(h);
{
puthex1(h>>4);
puthex1(h);
}
puthex1(h);
{
bdos(nputchr, ?((h:=h & $0f)<10 0005h="" _work="" a="" argn="1" at="" bdos="" br="" c="" call="" cd="" d1="" dd="" de="" e1="" e5="" e="" else="" f="" fd="" func="" h="" hl="" if="" inline="" ix="" iy="" ld="" pop="" push="" then="" var="" x="">10>
この例で分かりますように、CP/MのBDOSを直接呼べますので、I/O関連のプログラムも容易に作成できます。ということで、GAMEやTL/1言語のようなマシンに密着したツールソフトを作成するのに向いている言語ではないかなという印象です。以上、書籍に掲載されていたCP/M版のZ80用の8ビットコンパイラを入力して、簡単なサンプルプログラムを作ってみたという報告でした。
もし、使ってみたいという方がおられましたら、メールで連絡をくだされば実行ファイル(stellar.comとconvobj.com)を返信メールに添付してお送りできます。 (もっとも、書籍中の構文や文法の解説を読まないと、使ってみるのもなかなか大変ですが。)