ラベル Z80 の投稿を表示しています。 すべての投稿を表示
ラベル Z80 の投稿を表示しています。 すべての投稿を表示

2024年12月30日月曜日

「FPGAボードで6809を作ってNitros9を走らせてみました」の基板化

 「FPGAボードで6809を作ってNitros9を走らせてみました」の基板を作成しました

2022年6月22日に上記のタイトルでアップしたCycloneⅡ(EP2C5T)搭載のFPGAボードの工作の際には、有り合わせの基板に手配線で仕上げました。それ以降、折に触れ使用してきましたが、いかにもそのやっつけ感が気になっていました。また、FPGAに書き込むプログラムを変えればZ80としても6809としても動作するのはすごいことなのですが、切り替えて使用するためにはその都度FPGAのプログラムを書き換えるという手間がかかります。

また、以前も参考にさせていただいたブログ「石原 博の覚書(https://blog.goo.ne.jp/ishihara-h/e/ea09920e03694aab5227db6f08fde76e)」を見ていて、プリント基板を作成できればZ80、6809のそれぞれ専用のボードが作れるなと思っていました。

そんな時に、倍ぐらいに価格が上がってしまっていたFPGAボードがAliExpressで以前のような価格で購入できるショップを見つけたので2枚購入し、プリント基板も作成することで、Z80、6809それぞれの専用ボードとすることにしました。

参考にしたオリジナルの記事

https://www.retrobrewcomputers.org/doku.php?id=boards:sbc:multicomp:cycloneii-c:start

の中にはプリント基板の回路等のデータがあることは知っていたのですが、それはEagleによるもので、以前、私が常用しているKiCadで読み込んで処理しようとしてうまくできずあきらめてしまっていたので、今回はEagleの無料版をインストールしてgerberデータを作成してみました。使い慣れたKiCadによるgerberデータではないので、正しく作られているのかどうか不安でしたが、そのまま発注してみました。

出来上がった基板が下の画像のものです。


基板とFPGAボード

かなりの高密度で、シルク印刷がパターンの穴等によって読めなくなっている箇所も複数あり、迷うところもありましたがオリジナルの記事等を参考にして何とか実装してみました。

それが下の画像の2枚です。


製作した基板2枚

私は基本、シリアル入力を使用するのですが、最初に作成した左の基板はうまく動かなかったので、PS/2キーボード入力、VGA出力に加えてRS-232Cコネクタまで実装してしまいました。動作させるために必要な最小限のものだけを実装したのが右の基板です。また、オリジナルで使用されているSDカードモジュールと同じものが入手できなかったので手持ちのもので間に合わせることになりましたが、モジュールを瞬間接着剤で固定して画像のように配線することで(多少見苦しいですが)無事に動作させることができました。

左下の6ピンのシリアル端子の上に乗っているのは、手持ちのUSB-シリアル変換ケーブルの端子配置に変換するためのアダプタで、最初に作成した基板が動作しなかった(ように見えた)のは、この配線を間違えていたためというお粗末な話でした。


参考までに、作成を通して気づいた点を列記しておきます。

1.gerberデータはオリジナルのデータからEagleで作成できますが、SDカードモジュール部のパターンと合致するモジュールは多分入手困難です。

2.シリアルの6ピン端子の配列は一般のUSB-シリアル変換ケーブルのピン配列と合致しない可能性があります。

3.512KBのSRAMのアクセススピードについてですが、上の画像のように、55nsのAS6C4008-55PCNだけでなく、70nsのHM628512CLP-7でも使用できました。

4.Z-80用としては mc-2g-1024.zip 中の14-Multicompを使用しましたが、何故かTTY版は正常に動作しませんでした。動作するVGA版をインストールしましたが、基板上のVDUFFD0端子をショートすることでシリアル入出力に切り替えることができました。

5.6809用としては multicomp09_nov2016.zip 中のものを使用しました。

6.FPGAボード上のROMに書き込むための手順については、ちかてつ.comさんの「Amazonの激安基板(CycloneⅡ)ではじめるFPGA開発(JICプログラミング編)(https://tikatetu.com/electronics/amazon-fpga-jic/)」を参考にさせていただきました。ありがとうございます。

今取り組んでいるいくつかのテーマがいずれもうまく進まず、いささか倦んでしまっていたのですが、ちょうど良い気分転換になりました。


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)を返信メールに添付してお送りできます。 (もっとも、書籍中の構文や文法の解説を読まないと、使ってみるのもなかなか大変ですが。)

2020年12月26日土曜日

Z80H 韋駄天用のCP/Mをソースから構成する

 Z80H韋駄天用のCP/Mを公開されているソースから構成しました


Z80Hの作者はX1-CP/Mから韋駄天用のCP/Mを構成されていますが、前回のブログでは、私は手持ちのFM-CP/Mを利用しました。しかし、X1-CP/MやFM-CP/Mから構成する方法では試してみることができる方は限られます。

そもそもCP/Mの本体部分は共通(だと思っています)ですので、公開されているソースからでも構成できるはずです。ということで、以前中日電工の菱田さんのブログを参考にしてCP/Mを構成した時と同じように構成してみましたので、菱田さんのブログの記事を参照しながら私の行ったその手順を解説します。

[1]ソースからバイナリを作成する

(1-1)ソースとアセンブラを入手する

公開されているページからソース cpm2-asm.zip をダウンロードします。(中日電工のブログ第17,18回 以下同様)

使用するのはこれを展開してできるファイルのうちの cpm22.z80 です。

アセンブラはVectorで入手できるZASM1.64を使用します。

(1-2)ソースのエラーを修正する(第19,35,36回)

このままアセンブルするとエラーが生じますので数箇所を修正します。

・END文の追加

・ラベルHALTをHLTに変更

・NFUNCTSの定義文を前方に移動

・CKSUMTBL: DEFB 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0 を次の2行に分割する

  CKSUMTBL: DEFW 0

      DEFB: 0,0,0,0,0,0,0,0,0,0,0,0,0,0

・ADD A,M をADD A,(HL) に変更(3箇所)

ブログ中のその他の変更はND80Zのためのものなので不要です。

(1-3)60K-CP/M用に設定する

先頭の MEM EQU 62 を60に変更する。

(1-4)アセンブルする

以上の修正を加えたソース(cpm60k.txt)をWindows上でアセンブルします。

>msdos zasm -L -Ccpm60k.bin cpm60k.txt

(1-5)得られたBINファイルの末尾256バイトを削除する

末尾の BIOS JUMP TABLE の部分はIDATENシステムの方で用意されるので不要です。

できあがったファイルは$0000~$15FFの6KBとなります。


[2]CP/Mディスクを作成する

(2-1)ソースを入力してアセンブルする

「6809活用研究」のZ80Hの記事中にはIPL20, CONFIG, BIOS14, KER14 のソースが掲載されていますので、それを入力してアセンブルします。

(2-2)システムディスクのイメージの作成

バイナリエディタなどで320KBサイズのディスクイメージを作成して、次の順にファイルを書き込みます。

・$0000 - $00FF に IPL         (TRK:0, SCT:1)

・$0100 - $16FF に cpm60k  (TRK:0, SCT:2 - 23)

・$1700 - $1CFF に bios14    (TRK:0, SCT:24 - 29)

・$1D00 - $1EFF に config    (TRK:0, SCT:30 - 31)

・$2000 - $3BFF に ker14     (TRK:1, SCT:1 - 28)

・$4000 以降(TRK:2以降)はDirectoryとProgram&Dataなので、様々なブログで公開されているCP/Mシステムからコピーすることで、トランジェントコマンドやアプリケーションが設定できます。

韋駄天システムはX1-CP/Mを元にしているので、システムのセクタが他のCP/Mとは異なり1セクタ前にずれています。(はせりんさまに教えていただきました。ありがとうございました。)

 最後に、$1CFFの値を$3C(60)に変更します。これは起動時に60K CP/Mと表示される値です。

(2-3)システムディスク、あるいはシステムイメージファイルの作成

私は以前のブログに書きましたように、ドライブ0にGOTEKを使用していますので、できあがったイメージファイル(.DSK)を.88ファイルに変換して、さらに.hfeファイルに変換してUSBメモリーに書き込めば終了です。

フロッピーディスクをお使いの方はイメージファイルをそのままディスクにベタに書き込めば良いのですが、その方法としては、RS-232Cカードや以前のブログでも紹介していますFT-245カードを使ってFM77やFM-7に転送して書き込むことになりますが、転送時間がかかっても良ければF-BASICのプログラムを組めば良いので、詳細は省略させていただきます。




試作第1作は修正箇所が見えていて見苦しかったので、作り直すとともにCPUをZilog Z84C0020PECに交換しました。



韋駄天システムは最終的には64K-CP/Mとなるのですが、今のところまだ60K-CP/Mのままです。

これで、ハンダ付けを伴う製作と雑誌記事からのソフトの入力の手間をを厭わなければ、FM77で8MHz動作のCP/Mが走ることになります。





2020年12月19日土曜日

Z80カードの第4作は77AV用のZ80Hカード(韋駄天)

 懲りもせずに、さらにZ80カードを作ってみました!

[12月21日追記]CP/Mも走りました!(はせりんさんのアドバイスのおかげです)


今回のZ80カードは、ほうめいさんによる77AV用のZ80Hカード(韋駄天)です。

「6809活用研究(工学社)」掲載の記事を見て、いつかは作ってみたいと思って記事のコピーを保存してあったのですが、ほうめいさんのブログ「まごころせいじつ堂」に回路図の訂正が載ったのを見て、ついに作ってみることにしました。

(うまく行けば、私の常用機であるFM77AV40SXでもCP/Mが走るかもという甘い希望を持っていますがどうでしょうか。) ←コネクタが違っていました。残念!


ハードの製作

ブログの回路図を元にしてKiCadで回路図を描き、ICの配置もブログの写真通りにしてプリント基板を製作しましたが、メモリーICを128KBに変更することで何とか10x8cmのサイズに収めることができました。

Z80Hは手持ちがありませんでしたので、古いD780C-1を使用してみましたが不思議なことに8MHzクロックのままで動作しています。

しかし、いつものようにポカをしてしまい、128KBメモリーのプルアップすべきCS端子をプルダウンしてしまったので、パターンカットや追加配線が必要となりました。




画像では、とりあえずメモリーのピン30を抜いて+5Vに接続していますが、こんなこともあろうかと作り直しを前提に、普段はTTL ICには使用しないことにしているソケットを使用しています。


FM77AVに装着した様子です。高さを8㎝に抑えたので、装着した状態でカバーを閉じることができます。

「6809活用研究」にはF-BasicのTiny Monitorも載っていましたので、入力して走らせてみました。



画像のように、コマンド M, D, S, R が機能していますのでハードは正常に動作しているようです。


CP/Mの移植

CP/Mの移植に必要なソフトも「6809活用研究」に載っているので、BIOS等はそれらを打ち込めばよいのですが、CP/M本体はX1用のものを使用することになっています。

もちろんX1用のCP/Mは所有していないので、最初に手持ちのFM-CP/Mのディスク中のFMCPM605.SYSが5インチ用の60K_CP/Mかと思って適用してみたり、動いている56K_CP/Mから60K_CP/Mを作成して適用してみたりしましたが、うまく行きません。さらに、CP/M2.2のソースをアセンブルしたものを適用したりしましたが、やはり動作しません。

ということで、CP/Mの移植については挑戦中ということで、先にそのまま入力していたBIOSなどのソースを改めて読んでいるところです。

[12月23日追記]FM-CP/Mの60K版を元にしたものが動作しましたので、次の課題は公開されているソースをアセンブルしたもので動作させることですね。


最後に

回路やソフトを公開して下さったほうめいさんに感謝いたします。

とりあえず製作した試作第一作の不完全なプリント基板(ミスがあるためパターンカットと追加配線が必要なのと、シルク印刷が不十分)ですが、余分が数枚ありますので、もしご希望の方がおられましたらメールで連絡を下さい。返信用封筒に切手を貼って送ってくださったら無料でお送りします。


2020年6月10日水曜日

FM-7用Z80カードの第3作を製作

富士通の回路を10x8㎝に収めたCP/Mカードを作ってしまいました

3月13日のブログ「FM-7用Z80カードの第2作などを製作」で紹介したI/O誌の記事を元にしたZ80カードでは富士通のCP/M-80が動作しましたし、特に不満はなかったのですが、実は、「F-BASIC解析マニュアル フェーズ2」に掲載されている富士通純正のCP/Mカードの回路図も、いずれ製作するつもりでKiCadで回路図を作成してありました。

しかし、IC数が19個と多いので10x10㎝の格安基板には収まりそうもなく(富士通純正のCP/Mカードのサイズは124x78mmです)、製作費を考えて二の足を踏んでいました。
でも10x10㎝以内のサイズに無理やり押し込んでみたらどうなるかと試してみたところ、何とか10x8cmのサイズに入りましたので、作ってみることにしました。

いつもですと電源ラインだけは太い線で手配線し、残りはFreeRouting.exeに任せるのですが、今回は電源ラインも太くする余裕もありませんし、また、いつも全ICにつけているパスコンもオリジナル回路を忠実に再現するということで少なくなっているので、安定して動作するかという点では不安がありますがとにかく作ってみたものが下の画像です。


製作した基板と完成基板


ICの配置はオリジナルと同じにしてありますし、他の部品もできる限り同じ配置になるようにしてあります。ご覧のように、これ以上は小さくできないというサイズです。

左:純正基板 右:製作した基板


左が純正のZ80カードで、右が製作したコンパクトサイズのZ80カードです。高さは同じ8cmで幅が10㎝と狭くなっています。


動作中の様子1



動作中の様子2


動作中の様子です。私としては珍しくミスがなく、組み立てたらすんなりと富士通のCP/M-80が動作しました。
まだ十分にテストしていませんが、今のところ純正基板と同様に動作しているように思えます。しかし上記しましたように、安定動作するかどうかはまだまだ確認する必要があります。

ということで、2種類のZ80基板を作ってしまいましたが、余った基板は現在発注してある40Pコネクタと共に配布する予定です。
(40Pコネクタが届くのが待ち遠しいです。今回は、以前作った基板から40Pコネクタを外して使用しました。)

2020年5月16日土曜日

FM-7用 58K CP/M-80が一応出来上がりました

RAMモードで動作する58K CP/M-80が一応出来上がりました


Z80カードを製作した勢いでつい手をだしてしまって、もっと簡単にできると思ったのに意外に手間取ってしまい、一ヶ月ほどもかかってしまいましたが、FM-7用のCP/Mが一応できあがりました。
まだまだ直すべき箇所が多々ありますので完成とは言いすぎですが、切りがないので一応の区切りとします。

実行画面


仮想ドライブ画面



装置全景(左がFM-7用のディスプレイ)



メモリマップ


前回のブログで紹介したのはROMモードで$0000~$7FFFの範囲で動作する26K CP/Mでしたが、BIOSを使用せずSubSystemを使用することで、下図のメモリマップのように$0000~$EFFFの範囲で動作する58K CP/Mとなりました。



  58K CP/M-80



3つのファイルから構成されています。


(1)CP/M本体
  サイト「The Unofficial CP/M Web site」中のソース cpm22.z80 を使用しました。
  中日電工さんのサイトに説明されている通りにソースのバグを修正し、ドライブ名の表示を大文字に変更しただけで、あとはオリジナル通りです。58K CP/Mとしてアセンブルしました。
(2)BIOS80
  BIOSのZ80部分で、BIOSのジャンプテーブル、DISKパラメータの他はほぼパラメータをセットしてコマンド番号を6809に送っているだけです。
(3)BIOS09
  BIOSの6809部分で、FM-7のBIOSは用いず、FDD関係はFDC (MB8877A) を直接コントロールし、それ以外はSubSystemを使用しています。


CP/Mとしての機能


CP/Mとしての機能はベーシックなもので、エスケープシーケンスなども実装していませんが、仮想ドライブは実装してありますので、フロッピーが2台、仮想ドライブが2台の計4台です。
ドライブA, Bがフロッピー、C, DがWindows上の仮想ドライブです。以前紹介したRS232Cカードを用いて38400baudで通信しています。



構成図

RS232Cのドライバも実装しているのでPUNCHとREADERも使えるのですが、実際にはまず使用することはなく、もっぱらWindows上のエディタでファイルを作成し、ドライブCかDにセットしたCP/Mのイメージファイル(.77または.DSK形式)にドラッグ&ドロップしてCP/Mでアセンブルしたり、必要があればフロッピーにコピーしたりして使用しています。


機能不足や不具合など


相変わらずブロッキング/デブロッキング機能は実装していませんので、ディスクアクセスは速くはありませんが、そのうちにということで今回はパス。(そもそもブロッキング/デブロッキングについては良く分かっていないので。)

現在分かっている不具合がいくつかあります。
(1)カーソルが表示されない。
  もちろん、SubSystemのCONSOLE CONTROLでカーソル表示をONにしていますが、6809側では表示されますが、Z80側に切り替わるとカーソルが消えます。
今のところ原因が分からず、直せていないので結構不便です。

(2)スタート時にドライブを指定する必要がある。
  スタート直後にディレクトリを表示させると、DIRやDIR A:は表示されるのですが、DIR B:などはダメです。最初にドライブチェンジのB:やC:などを一回実行しておけば以降は普通に表示できるのですが、なぜでしょうか。BIOSがおかしいのは間違いないのですが。


制作した2つのソフト


下にBIOS80とBIOS09を置いておきます。80系の知識がほとんどない私が作ったものなのでおかしな点が多々あるかと思いますが、おかしな箇所や不具合の原因などをご指摘いただけるとありがたいです。

◎BIOS80です。中日電工さんのブログで紹介されているZASM1.64でアセンブルしています。

 


 ◎BIOS09です。自作のクロスアセンブラでアセンブルしています。

 

上記のソフトはまだ制作途中ということで、エラー処理などは不十分ですのでディスクアクセスに失敗などするとハングアップしたりします。

ということで、不具合はありますが何とか使える状態なので、今は、最近入手した「応用CP/M 村瀬康治著」中のシステムコールの実習を一つずつ走らせて確認しているところです。

なお、仮想ドライブ構築ソフトCpmDrvWin.exeですが、もうしばらく使用して不具合が出ないかを確認してから公開する予定です。



2020年5月2日土曜日

CP/M用の仮想ドライブの構築ソフト(その2)

仮想ドライブ構築ソフトCpmDrvWin.exeをCP/Mに接続してみました。


前回報告したCpmDrvWin.exeをCP/Mに接続してみました。
書き直したのは、CP/MのBIOSの6809側のルーチンのみで、DrvNoが0(A:),1(B:)の時は従来のFDDアクセスルーチンのままで、2(C:),3(D:)の場合にはRS232Cを通してCpmDrvWinと通信して仮想ドライブ中のファイルを読み書きします。

具体的には、ファイルを読む場合にはCpmDrvWinに対して’R',DrvNo,TrkNo,SctNo(+チェックサム)という文字列を、書き込む場合には’W',DrvNo,TrkNo,SctNo(+チェックサム)という文字列を送って、その結果を受け取るだけです。



ディレクトリを表示

ドライブA:はフロッピーディスクで、ドライブC:とD:が仮想ドライブです。
まだテスト中ですので、BaudRateを4800baudと遅くしてありますが、完成時には38400baudになります。


ドライブC:のディレクトリ表示時

右のテキストボックスは受信したコマンド列を表示しています。
Trk2,Sct1から始まって、各2回ずつ読んでいるのが分かりますが、これはブロッキング・デブロッキングをちゃんと行っていないためです。(何とかしなければ...)


ドライブD:のディレクトリ表示時

ディレクトリの範囲はTrk2のSct1~16なのですが、ドライブD:の場合のように、ファイル数が少なくても、その範囲のセクタを全て読んで、空を表示しています。(これはBDOSの仕様なのか、それとも自作BIOSの責任なのか...)

前回のブログで書きましたように、左のリストボックス中にWindows上のファイルをドラッグ&ドロップしてファイルを追加すれば、CP/Mからそのファイルにアクセスすることができます。

また、CP/MとWindows上のCpmDrvWinとの間の通信部分は、Flex9用、F-Basic用などと共通で、8251A使用のRS232Cカードや以前発表した拡張I/Oボード上の6850(ACIA)使用の場合の通信ルーチンが使用できますが、FM-7でも6850(ACIA)の方はあっさりと38400baudで動いています。

未だ完成ではありませんが、とりあえずこの程度でできるのだというサンプルとして、BIOSに追加した仮想ドライブアクセスルーチンを記しておきます。

*================================================
*read windows virtual drive
RDWDRV EQU *
*read 256bytes
 BSR READSUB2
 LBRA RE0

*read 256bytes
READSUB2 EQU *
RDS0 CLR CSUM
 LDA #'R
 LBSR SNDCH read cmd
 BSR ADDCS
 LDA DRVNO
 LBSR SNDCH drv
 BSR ADDCS
 LDA TRKADR
 LBSR SNDCH trk
 BSR ADDCS
 LDA SCTADR
 BSR SETSCT2
 LBSR SNDCH sct
 BSR ADDCS
 LDA CSUM
 LBSR SNDCH csum
*wait receive ACKorNAKorESC
*  if NAK then re-send 'R',Drv,Trk,Sct,csum
*  if ESC then error return
*  if ACK then next
RDS1 LBSR RCVCH
 CMPA #NAK
 BEQ RDS0
 CMPA #ESC
 BNE RDS2
 LDA #$FF *error
 RTS *error end
*
RDS2 CMPA #ACK
 BNE RDS1
* send ACK
 LBSR SNDCH ACK
*receive data(256bytes),csum
*  data is saved to Buffer(X)
*  if csum error then send NAK
*  if csum ok then send ACK and to next process
RDS3 LDX #RCBBUF
 CLRB counter(256)
 CLR CSUM
RDSLOP LBSR RCVCH data
 STA ,X+
 BSR ADDCS
 DECB
 BNE RDSLOP
 LBSR RCVCH csum
 CMPA CSUM
 BEQ RDS4
 LDA #NAK
 LBSR SNDCH NAK
 BRA RDS3
*
RDS4 LDA #ACK
 LBSR SNDCH ACK
*wait receive ACK
RDS5 LBSR RCVCH
 CMPA #ACK
 BNE RDS5
 RTS
*
*return A:sct,BUFHL:0or1
SETSCT2 EQU *
 CLR BUFHL
 LDA SCTADR ;sct
 BITA #$01
 BEQ SE21
 DECA
 INC BUFHL ;0:even, 1:odd
SE21 LSRA
 INCA
 RTS
*
*--------------------
*add check sum
ADDCS EQU *
 ADDA CSUM
 STA CSUM
 RTS
*--------------------
*write windows virtual drive
WRWDRV EQU *
*read 256bytes
 LBSR READSUB2
*set write data
 BSR WRDTSET
*write
WRW2 CLR CSUM
 LDA #'W
 BSR SNDCH write cmd
 BSR ADDCS
 LDA DRVNO
 BSR SNDCH drv
 BSR ADDCS
 LDA TRKADR
 BSR SNDCH trk
 BSR ADDCS
 LDA SCTADR
 BSR SETSCT2
 BSR SNDCH sct
 BSR ADDCS
 LDA CSUM
 BSR SNDCH csum
*wait receive ACKorNAK
*  if NAK then re-send 'W',Drv,Trk,Sct,csum
*  if ESC then error return
*  if ACK then next
WRW3 BSR RCVCH
 CMPA #NAK
 BEQ WRW2
 CMPA #ESC
 BNE WRW4
 LDA #$FF  *error
 BRA WRW7 *error end
*
WRW4 CMPA #ACK
 BNE WRW3
*send data(256bytes),csum
*data is in Buffer(X)
WRW5 LDX #RCBBUF
 CLRB counter(256)
 CLR CSUM
WRWLOP2 LDA ,X+
 BSR SNDCH data
 BSR ADDCS
 DECB
 BNE WRWLOP2
 LDA CSUM
 BSR SNDCH csum
*wait receive ACKorNAK
*  if NAK then re-send data(256bytes),csum
*  if ACK then next
WRW6 BSR RCVCH
 CMPA #NAK
 BEQ WRW5
 CMPA #ACK
 BNE WRW6
 CLRA *no error
WRW7 STA PTOZ80
 LBRA TOZ80
*
*======================================

ということで、あちこちに不備があってまだまだ修正の必要がありますが、CP/M用の仮想ドライブのプロトタイプがとりあえずできたという報告でした。

2020年4月29日水曜日

CP/M用の仮想ドライブの構築ソフト

CP/M-80用の仮想ドライブ構築ソフトCpmDrvWin.exeを作りました。



FM-7用の自作Z-80カードのためのCP/Mを制作中ですが、何回も起動を繰り返すので、フロッピーディスクから起動したり、読み書きするのは結構面倒です。
とりあえず起動するのはフロッピーからでも仕方がないとして、せめて読み書きはもっと便利にしたいし、ファイルをWindowsとの間で自由にやり取りしたいと考えて、自作CP/MのBIOSの仕上げを中断して、仮想ドライブ構築ソフトCpmDrvWin.exeの制作に取り掛かりました。

今までにFlex9用、OS-9用、F-Basic用を作ってきましたが、CP/M用については、以前作ろうと試みたものの、CP/Mのファイルシステムが理解できず挫折していました。
今回は中日電工の菱田さんのブログで勉強しましたので大丈夫だとは思いましたが、それでも意外に時間がかかりました。

CP/Mのファイルシステムというかディレクトリの構成法は他のDOSと比較すると、原始的というかどうしてこうなっているのかと思えるもので、中でも特に、同じファイル名のディレクトリエクステントが複数存在する(それも、ディレクトリ全体を読まないと幾つあるかも分からない...)のには参りました。

とりあえず第1版として出来上がったものが動作している様子を示します。


CpmDrvWin.exeの動作画面


下のXM7上で動作しているFM-CP/Mと同じ情報が(並び順は異なりますが)表示されているのが分かると思います。
XM7ではスクロールアップしてしまったものはもう見ることはできませんが、CpmDrvWin.exeでは自由にスクロールアップダウンしてみることができます。


XM7上のFM-7 CP/Mの動作画面

機能としては、
・ファイルの追加(リストボックス中へのドラッグ&ドロップによる)
・ファイルの名称変更、削除、Windowsへの読み出し(ファイルを選択してからの右ボタンメニューによる)
・全ファイルのWindowsへの読み出し(編集メニュー中のコマンドによる)
があります。

現在は、表示されているドライブがWindows上の仮想ドライブとして見えるように、CP/M側のBIOSを手直し中です。
しばらく使用して不具合などを修正したら、CP/MのBIOSと共に公開する予定です。


2020年4月18日土曜日

FM-7用の自作CP/Mがとりあえず動作しました

自作したZ80カード用に制作しているCP/Mがとりあえず動作しました

 

動作しなかった原因は

前回は動作していないと報告しました。その原因はいくつかありましたが主なものは以下の2つでした。
(1)DMAADRSの読み方が間違っていた
 FDDの読み書き時に用いるバッファのアドレスをZ80で設定して6809で読む際に、例のビッグエンディアンとリトルエンディアンの違いに引っかかってしまった。

(2)CP/Mでもセクタ番号が1から始まっているものと思い込んでいた。
 CP/Mでははセクタ番号は1ではなく0から始まるのですが、参考にした本(「CP/M80の世界」 工学社)でも1から始まるように書かれていたので信じ込んでしまった。

(2)は決定的でした。(1)に気づいて修正してDirectoryが表示されるようになったのですが、ファイル内容をTYPEしてみると半分ゴミが混じるのです。
プログラムを何回見直しても間違いが見つからず困っていましたが、そういえば中日電工の菱田さんのブログではセクタ番号を0からにしていたなと思い出して、それに合わせてプログラムを書き直したところようやく動作しました。

動作の様子

動作画面を示します。


CP/M起動画面


6809用のBIOS09を別ファイルにしてあるので、CP/M本体(Z80側のBIOS80を含む)、BIOS09の順に読み込んで、BIOS09を起動すると6809側の初期化をした後Z80に動作を移してCP/Mが起動します。
FM-CP/M用のフロッピーディスクがありましたので、それを読み込ませています。


コマンドも動作しています


STATコマンドやTYPEコマンドが正常に動作しています。

メモリマップ

RAMディスクが無くなったので、TPAが$0100から$47FFまでと広くなりました。
サイズとしては25K CP/Mということでしょうか。
しかし、F-BASICと共存する形ですのでちょっと窮屈です。

左:以前のもの 右:今回のもの




以前報告した自作のRS232Cカードも装着しており、RS232CのI/Oルーチンも実装しているので、WindowsからHEXファイルを読み込めますし、それなりに使える状態になっているかなと思います。

これから

変更すべき重要な点は2つあります。
(1)ブロッキング、デブロッキングをまともにしていない。
書き込み時にはまずCP/Mでの2セクタ(256バイト)を読み込んで、それに書き込むべき1セクタ(128バイト)を重ね書きしてからそれをフロッピーに書き込んでいます。
また読み込み時も、連続したセクタの読み込みでバッファにデータがあっても毎回フロッピーを読み込んでいます。
とりあえず動作させるためでしたが、流石に何とかしないと恥ずかしい。

(2)メモリマップで分かりますようにF-BASICのROMが邪魔をしていますので、オールRAMの状態で動作するように手直しをしなければもったいない。

また、今どきフロッピーディスクでもないので、ドライブC:やD:にWindows上の仮想ドライブを設定してFlex09やOS-9のように仮想ドライブをメインにしたいという希望もあります。
これが実現できると、ファイルの保存がWindows上でできるので、使い勝手がそれなりに良いCP/Mになるのではないでしょうか。

自作のCP/Mであれば機能の拡張も可能でしょうし、お仕着せのメーカー製よりもいじりがいがありそうです。BIOS09を拡張すればあれこれできそうで楽しみです。

しかし、不思議なのですがCP/MはなぜFAT情報(に相当するもの)をディスクに持たない設計にしたのでしょう。以前、Flex09, OS-9, F-BASIC用の仮想ドライブソフト(FlexDrvWin.exe, OS9DrvWin.exe, FBasDrvWin.exe)を製作した時と同じようにCpmDrvWin.exeを作ろうとしたことがあったのですが、ディスクの入れ替え時の切り替えの面倒さでメゲてしまったことがありました。

最後に

まず中日電工の菱田さんに感謝いたします。
80系の経験がほとんどない私が曲がりなりにも作ることができたのも菱田さんのブログのおかげです。またND80Z3.5のマニュアル中のZ80や8080の命令表もとても分かりやすくて助かりました。

今はCP/Mのソースも公開されており、個人使用なら自由に使えるようですし、Z80カードも費用がそれ程かからず製作できますので、FM-7やFM-77をお持ちの方が遊んでみるのには向いているのではないでしょうか。
フロッピーディスクがなくても、RAMディスク版をオールRAMで動作させれば良いのですから、必要なのはZ80カードのみです。(RS232Cカードも必要かも)
280回も続くブログですが、117回まで読めばRAMディスク版が作れます。私は第87回ででき上がったファイル cpm22l.txt を元にしました。

参考にはならないと思いますが、私が製作したBIOS09を載せておきます。まだ途中の段階のものですが、FM-7のBIOSを使えばこの程度で動作するのだという見本ということで。
Z80の方は、基本的にパラメータを書き込んでコマンド番号を設定しているだけです。

*
* MY BIOS09 for CP/M-80
*
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
ENTRY EQU $6233
FBASE EQU $5406 ;BDOS ENTRY POINT
DPBASE EQU $6239 ;DISK PARAMETER HEADER BASE
TDRIVE EQU $04
TBUFF EQU $80 ;i/o buffer and command line storage.
TRKADRS EQU $4B90
SCTADRS EQU $4B92
DMAADRS EQU $4B94
DRVNO EQU $4B96
CMDNO   EQU $4B98
PTO09   EQU $4B99
PTOZ80  EQU $4B9B
KCSAVE  EQU $4B9D
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;

*---------- 6809 routine ----------
 ORG $6800
*
BIOS EQU $FBFA
ACK EQU $06 ;
NAK EQU $15 ;
ESC EQU $1B ;

*USART 8251A
SDATA EQU $FD06 ;DATA
SCMD EQU SDATA+1 ;CMD
SSTS EQU SDATA+1 ;STATUS

MRSTU EQU $40 ;master reset
MODEU EQU $4E ;1stopbit,non pari,8bit,16x
CLRTSU EQU $15 ;RTS=H,ER,RxE,TxEN
SERTSUR EQU $34 ;RTS=L,ER,RxE for receive
SERTSUS EQU $31 ;RTS=L,ER,TxEN for trans
TxEMPTY EQU $04

START EQU *
*initialize
* reset 8251A
 CLRA
 STA SCMD
 STA SCMD
 STA SCMD
 LDA #MRSTU ;reset
 STA SCMD
 LDA #MODEU ;1stop,nonpari,8bit,16x
 STA SCMD
* set command to 8251A
 LDA #CLRTSU ;RTS=H,ER,RxE,DTR,TxEN
 STA SCMD

*set Z80 cold start
*write to $0000
 LDX #0
 LDA #$C3
 STA ,X+
 LDD #ENTRY
 EXG A,B
 STD ,X++

*go to Z80
TOZ80 EQU *
 LDX #$FD05
 LDA #1
 STA ,X
 NOP

*from Z80
*****************************
CMDIN LDA CMDNO
 CMPA #2
 BEQ CONST
 CMPA #3
 BEQ CONIN
 CMPA #4
 LBEQ CONOUT
 CMPA #5
 LBEQ LIST
 CMPA #6
 LBEQ PUNCH
 CMPA #7
 LBEQ READER
 CMPA #8
 LBEQ HOME
 CMPA #9
 LBEQ SELDSK
 CMPA #10
 LBEQ SETTRK
 CMPA #11
 LBEQ SETSEC
 CMPA #12
 LBEQ SETDMA
 CMPA #13
 LBEQ READ
 CMPA #14
 LBEQ WRITE
 CMPA #15
 LBEQ LISTST
 CMPA #16
 LBEQ SECTRAN
 BRA TOZ80
*****************************
*
CONST EQU * ;2
 LDX #RCBKIN
 JSR [BIOS]
 CLRB ;00
 LDA RCBDBA+1 ;1:keyin, 0:none
 BEQ CS1 ;not keyin
 LDA RCBDBA ;keycode
 DECB ;ff
CS1 STA KCSAVE ;0 or keycode
 STB PTOZ80 ;0 or ff
 LBRA TOZ80

*
CONIN EQU * ;3
 LDA KCSAVE 0:none, !0:keycode
 BNE CI2
 LDX #RCBKIN
CI1 JSR [BIOS]
 LDA RCBDBA+1 ;keyin?
 BEQ CI1
 LDA RCBDBA
CI2 STA PTOZ80
 LBRA TOZ80

*
CONOUT EQU * ;4
 LDA PTO09
 LDX #RCBOUT
 STA RCBDBA
 LDD #$0001
 STD RCBLNH
 JSR [BIOS]
 LBRA TOZ80

*
LIST EQU * ;5
 LDA PTO09
 LBSR SNDCH
 LBRA TOZ80

*
PUNCH EQU * ;6
 LDA PTO09
 LBSR SNDCH ;rs232c
 LBRA TOZ80

*
READER EQU * ;7
 LBSR RCVCH ;rs232c
 STA PTOZ80
 LBRA TOZ80

*
HOME EQU * ;8
 LDX #RCBRST
 LDA PTO09
 STA 7,X
 JSR [BIOS]
 LBRA TOZ80

*
SELDSK EQU * ;9
 LBRA TOZ80

*
SETTRK EQU * ;10
 LDX #RCBRWD
 LDA TRKADRS
 CMPA #39
 BLS STT1
 CLRA
STT1 STA 4,X
 LBRA TOZ80

*
SETSEC EQU * ;11
 LDX #RCBRWD
 BSR SETSCT ;A:sct,B:side
 STD 5,X
 LBRA TOZ80

*
SETDMA EQU * ;12
 LBRA TOZ80

*
READ EQU * ;13
 BSR READSUB
*set read data
 LDX #RCBBUF
 TST BUFHL ;0:even, 1:odd
 BEQ RE1
 LDB #128
 ABX ;rcbbuf+128
RE1 PSHS D
 LDD DMAADRS
 EXG A,B
 TFR D,Y
 PULS D
 LDB #128
RLOP LDA ,X+
 STA ,Y+
 DECB
 BNE RLOP
 CLRA
 STA PTOZ80
 LBRA TOZ80

*
READSUB EQU *
 LDX #RCBRWD
 LDA #10 ;read cmd
 STA ,X
 LDD #RCBBUF
 STD 2,X
 LDA TRKADRS ;trk
 STA 4,X
 BSR SETSCT ;A:sct,B:side
RS2 STD 5,X ;sct,side
 LDA DRVNO ;drv
 STA 7,X
 JSR [BIOS]
 RTS

*
*return A:sct,B:side,BUFHL:0or1
SETSCT EQU *
 CLRB
 CLR BUFHL
 LDA SCTADRS ;sct
 BITA #$01
 BEQ SE1
 DECA
 INC BUFHL ;0:even, 1:odd
SE1 LSRA
 INCA
 CMPA #16
 BLS SE2
 SUBA #16
 INCB
SE2 RTS

*
WRITE EQU * ;14
*read
 BSR READSUB
*set write data
 LDX #RCBBUF
 TST BUFHL ;0:even, 1:odd
 BEQ WR0
 LDB #128
 ABX
WR0 PSHS D
 LDD DMAADRS
 EXG A,B
 TFR D,Y
 PULS D
 LDB #128
WLOP LDA ,Y+
 STA ,X+
 DECB
 BNE WLOP
*write
 LDX #RCBRWD
 LDA #9 ;write cmd
 STA ,X
 LDD #RCBBUF
 STD 2,X
 LDA TRKADRS ;trk
 STA 4,X
 BSR SETSCT ;A:sct,B:side
WR2 STD 5,X ;sct,side
 LDA DRVNO
 STA 7,X
 JSR [BIOS]
 CLRA
 STA PTOZ80
 LBRA TOZ80

BUFHL FCB 0

*
LISTST EQU * ;15
 CLRA not ready
 STA PTOZ80
 LBRA TOZ80

*
SECTRAN EQU * ;16
 LBRA TOZ80
*
*
RCBKIN FCB 21
 FCB 0
 FDB RCBDBA
 FDB 00

RCBOUT FCB 20
 FCB 0
 FDB RCBDBA
RCBLNH FDB 0001
*
RCBDBA RMB 2
*
RCBRST FCB 8
 FCB 0
 FDB 00
 FDB 00
 FCB 0
 FCB 0 DRVNO

RCBRWD FCB 9 9:dwrite, 10:dread
 FCB 0
 FDB RCBBUF
RCBTRK FCB 0 trk
RCBSCT FCB 0 sct
RCBSID FCB 0 side
RCBUNT FCB 0 DRVNO
*
*
*--------------------------------------
* receive from serial port
* (use USART 8251A)
*    A <- port
*
RCVCH EQU *
 LDA #SERTSUR ;RTS=L
 STA SCMD
 NOP
RCV1 LDA SSTS
 ASRA
 ASRA
 BCC RCV1
 LDA SDATA ;get data
 PSHS A
 LDA #CLRTSU ;RTS=H
 STA SCMD
 PULS A,PC
*
*--------------------------------------
* send to serial port
* (use USART 8251A)
*    port <- A
*
SNDCH EQU *
 PSHS A
 LDA #SERTSUS ;RTS=L
 STA SCMD
 NOP
SND1 LDA SSTS
 ASRA
 BCC SND1
 PULS A
 STA SDATA ;send data
 PSHS A
SND2 LDA SSTS
 BITA #TxEMPTY
 BEQ SND2
 LDA #CLRTSU ;RTS=H
 STA SCMD
 PULS A,PC
*

RCBBUF RMB 256

 END START


蛇足

製作したZ80カードですが、多少余りがありますので40Pコネクタとのセットで頒布しようと思い、ちょっと安い業者を見つけてコネクタを発注したのですが発送予定が何と7月末と言われました!
しかし待つしかありませんね。