2023年7月16日日曜日

FM77AV40用1024KB増設RAMカードの製作

 FM77AV40用512KB増設RAMカードの容量を760KBに増加させました

2022年10月21日に「FM77AV40用512KB増設RAMカードの製作」を紹介しました。製作した基板のサイズは純正の256KB増設メモリカードよりはるかに小さなものでしたが、それでもまだ基板に余裕がありましたので、512KBメモリをもうひとつ載せられそうです。ということで、容量を倍増させたカードを製作してみることにしました。

これが製作した1024KB増設RAMカードです。(実際に増加する容量は760KBです。)

512KBメモリはSOP型のHM628512を自作変換基板にセットしたものを使用しています。


1024KB増設RAM


回路図を下に示します。

最初は通常のTTL-ICで試作しましたが、未使用のゲートが多く、あまりにも無駄が多いのでどうしようかと思っていたところに、知人からこういう時にはGALを使ったら良いかもとのアドバイスを受けて、GALに変更することにしました。


最初に試作した回路

Latticeの16V8Bを使用しましたが、3個のTTL-ICを1個のGALで置き換えることができました。


GALに変更

GALのプログラムにはMicrochip社のWINCUPLを用いました。

GALを使用するのは初めてだったのですが、実際に使用してみて、この程度のロジックをGALのプログラムに置き換えるのは、初心者でもそう難しいことではないと感じました。

参考までに、今回の置き換えの部分を示しますが、あとはそれぞれの入出力信号を16V8Bのピンに割り当てればOKです。

/* EQUATIONS */

CS1 = !(A18 & A19) ;

CS2 = !(A18 $ A19) ;

WE  = !(!RW & E) ;

OE  = !(RW & E) ;


製作した結果は

前回と同様、OS-9 Level2でフリーメモリを確認しました。

その結果が下記ですが、760KB増えています。


フリーメモリ確認


512KBのメモリを2個搭載しているので1024KBの容量なのですが、拡張メモリの範囲は$40000~$FFFFFの768KBですので、これだけ増加するはずですが、実際には$40000~$FDFFFの760KBの増加になっています。OS-9の場合は、最上位の$FE000~$FFFFFの$2000バイト(8Kバイト)は使用不可のようです。

この位のRAM容量があれば、一部をRAMディスクに充てることもできそうです。

以上、512KBの増設RAMの容量をさらに増やしてみたという報告でした。

現在48ピンのコネクタの入手は困難ですが、コネクタさえ入手できれば回路は簡単ですし512KBのSRAMも入手は容易ですので製作そのものは容易です。


2023年7月5日水曜日

コンパイラ作成の試み その3 番外編 (Z80版8ビットコンパイラの入力)

 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="">


この例で分かりますように、CP/MのBDOSを直接呼べますので、I/O関連のプログラムも容易に作成できます。ということで、GAMEやTL/1言語のようなマシンに密着したツールソフトを作成するのに向いている言語ではないかなという印象です。以上、書籍に掲載されていたCP/M版のZ80用の8ビットコンパイラを入力して、簡単なサンプルプログラムを作ってみたという報告でした。 

もし、使ってみたいという方がおられましたら、メールで連絡をくだされば実行ファイル(stellar.comとconvobj.com)を返信メールに添付してお送りできます。 (もっとも、書籍中の構文や文法の解説を読まないと、使ってみるのもなかなか大変ですが。)

2023年7月4日火曜日

コンパイラ作成の試み その2 言語の拡張(コメントとFOR文など)

 コンパイラ作成の試み その2 言語の拡張(FOR文で四苦八苦)


(表示用のアイコンとして入れてあります)

前回からずいぶんと時間が過ぎましたが、言語の拡張がなかなかうまくいかず、四苦八苦していますが、とりあえず現在の状況です。

拡張したのは以下の3つです。

1.コメント文が使えるようにした。

  プログラム作成時にはコメントアウト機能は必須だと思いますので、/*と*/で囲んだ部分はコメントとして読み飛ばされるようにしました。

2.PRINT文(PRINTLNも)の書式を変更した。

  C言語に慣れているせいか PRINT文の書式には違和感がありましたので、プリントする式部分を括弧で囲むように書式を変更しました。

  変更前:PRINT I, ": ", DATA[I];

  変更後:PRINT (I, ": ", DATA[I]);

3.FOR文を追加した。(...未完成)

  制御文としては、IF文、WHILE文、DO..WHILE文があるのですが、やはりFOR文があると便利ということで追加してみようと試みました。

1と2は何とか実現できたのですが、3のFOR文の追加については四苦八苦した挙句、一応それらしく動作するものができたのですが、動作が思ったようにはなりません。。。

  例えば FOR (I=0; I<10; I=I+1) PRINT(I,","); の場合

  結果は 1,2,3,4,5,6,7,8,9,10 となってしまうのです。

その理由ですが、FOR文を頭から見ていくため、まず I=0 の初期設定で I の値を設定し、次に I<10 の終了条件の真偽判定をして、真の場合は続いて I=I+1 の増分を実行してから PRINT文を実行した後にFOR文の先頭に戻るという手順を繰り返すために、繰り返しの1回目から制御変数の増分を実行してしまうためです。

この言語は全てをスタックに積む形式で行っているために、途中経過をどこかに保存しておくということができず、プログラムをシーケンシャルに実行していくために、このような結果になってしまっています。

(WHILE文やDO..WHILE文ではシーケンシャルに実行していって正しい結果が得られるような書式になっています。)

スタック言語ではFOR文のような、解析した順序とは異なる順序で実行しなければならない文は不可能なのでしょうか。それとも何か実現できるような手法があるのでしょうか。

(そういえば、中田先生のPL/0にもFOR文はありませんね、、、)

私の知識・経験不足のためにこれ以上は無理なようですので、言語の拡張はここまでにして、次は、中間言語に変換しているところを直接6809の命令語に変換するように変更して、6809機で動作するコードを生成するコンパイラに仕上げていこうと思います。