2021年12月27日月曜日

Z8K CP/Mボード その2

こんなものを試す人はかなりのハッカー基質の人だと思い、Githubの説明はあまり親切でないのと、英語があまりにひどいので、CP/M-8000を起動させるための補足をしておきます。

準備

作業はDebian系のディストリビューションで行うことを想定しています。ATMEGAのコードをビルドし書き込むために、gcc-avr, avr-libc, avrdude をインストールしておきます。Z8000のコードをアセンブルするために、GNUのサイトからbinutils をダウンロードして、 Z8001クロス開発環境 binutilsをビルドしてみるを参考にビルドしてください。私が確認しているは使っているのは、binutils-2.34 です。

ATMEGA164のヒューズビット設定 

Z8001MBと同じくZ8K CP/Mでは、Z8001を起動するためにATMEGA164Pが使われていますが、JTAGの禁止と外部クロック入力にするためヒューズビットの書き換えが必要です。値は、LFUSE : 0xE0, HFUSE : 0xD9 です。ATmega164PのJTAGを禁止するを参照し、avrdudeを使って書き換えてください。

マシンモニタの書き込み

z8kboot ディレクトリでmakeを実行してください。z8kbooter.elf が作られます。 チップへの書き込みは、make write で実行できます。

CP/M-8000のビルド

COFFに変換済みのcpmsys.o と libcpm.a が入れてあるので、cpm8kディレクトリで、makeするだけです。cpm8k.bin が作られます。

CP/M-8000のディスクイメージの作成

cpmtoolsをインストールし、/etc/cpmtools/diskdefsにcpm8kディレクトリにあるdiskdefsを追加します。diska/b/c/d ディレクトリにディスクイメージに含めたいファイルを入れて、make dskimg を実行します。disk.img   ができるので、dd でCFに書き込めばOKのはずです。ディスクイメージに入れるCP/M-8000のコマンド類は、 http://www.cpm.z80.de/download/cpm8k11.zip を解凍すると得られるDISKn.ZIPに含まれています。

こんな状況になると予想しておらず、慌てて書いたので間違っているかもしれません。

2021年12月26日日曜日

Z8K CP/Mボード

 私がGithubにあげているZ8001MBの回路図をもとに、tomi9さんがCP/M-8000を動作させることができるPCBを作成され、一枚送ってくださいました。


PCBだけでなくCFのソケットとGALも同封されており、あとは手持ちの部品だけで行ける状態でした。tomi9さん、ありがとうございます。自分もいつかはPCBを作ってみたいとは思っているのですが、なかなか勇気が出ません。ラッピングワイヤーでの手配線だと、すぐに回路の修正がききますが、PCBだとそう簡単にはできません。

久しぶり(中学高の技術の授業以来?)のPCBでの組み立てで、ちょっと一投目は緊張しましたが、最難関のCFソケットのはんだ付けを済ませ、Z8536以外の部品を組みつけて、現在、動かせるところまで来ています。

2021年10月16日土曜日

FUZIX:z80packのカーネル初期化

 FUZIXカーネルの初期化の部分を見ていきます。

Kernel/platform-z80pack/fuzix.lnk に、カーネルがどのようなコードがリンクされてつくられるかが記述されています。

platform-z80pack/crt0.rel
platform-z80pack/commonmem.rel
platform-z80pack/z80pack.rel
platform-z80pack/main.rel
 :
 :
syscall_level2.rel
syscall_net.rel
select.rel
platform-z80pack/net_native.relか

カーネルの先頭はcrt0.rel で、対応するソースコードはcrt0.sです。中身を見ると、割り込みを禁止して、スタックポインタを設定しています。次にコールされているinit_earlyはz80pack,sにあり、メモリバンクのサイズとバンク数を設定します。

init:
        di
        ld sp, #kstack_top

        ; Configure memory map
        call init_early

次は共有メモリーの初期化です。"s_", "l_"で始まるシンボルは、アセンプラが.area で定義したセクションに対し作った開始アドレスとサイズを示すシンボルです。_COMMONMENセクションは、fuzix.lnk で開始アドレスが0xf400と定義されています。_DATAセクションはリロケートされるセクションなので、その時々で場所とサイズが変化します。最初のブロック転送で、_DATAセクションを_COMMONMEMセクションにコピーし、2番めのブロック転送で_COMMONMENセクションに続く領域に_DSICARDセクションをコピー。3番目のブロックコピーでは_DATAセクションを0クリアしています。

	; move the common memory where it belongs    
	ld hl, #s__DATA
	ld de, #s__COMMONMEM
	ld bc, #l__COMMONMEM
	ldir
	; and the discard
	ld de, #s__DISCARD
	ld bc, #l__DISCARD
	ldir
	; then zero the data area
	ld hl, #s__DATA
	ld de, #s__DATA + 1
	ld bc, #l__DATA - 1
	ld (hl), #0
	ldir

続いてz80pack.sにあるinit_hardwareをコールしています。この中では、RAMとカーネルサイズの設定、タイマーを100Hzに設定、割り込みベクターの設定を行います。そしてこれらの初期化を終えたあと、FUZIXのメインに飛びます。

        ; Hardware setup
        call init_hardware

        ; Call the C main routine
        call _fuzix_main

カーネルロードから初期化しカーネルに実行を移すところまで見てみましたが、意外とあさりした印象を受けます。ここまでなら、なんとなくZ280MBに移植でるような気がします。

2021年10月9日土曜日

FUZIX:z80packのメモリマップ

 z80pack では、64kバイト以上のメモリが扱えるよう、バンク切り替えができるようになっています。バンクは0x0000からはじまり、256バイト単位でサイズを変更できます。バンクを切り替えると、外された他のバンクはCPUからはアクセスできなくなってしまいます。バンクより高位のメモリ空間は共通で、バンクを切り替えてもCPUからは常にアクセスできます。

MMUを制御するI/Oポートと機能は次のようになっています。

ポート 機能
20 バンク数設定
21 バンク番号設定
22 バンクサイズ設定 (256バイト単位)
23 共通領域ライトプロテクト

FUZIXではREADMEによると、カーネルをバンク0に置き、プロセスを1から7までに置くようになっています。Z80の64kバイトのメモリ空間の内、0x0000から0xefffまでの60kバイトがバンク切り替え領域です。0xf000から0xffffまでは共通領域で、カーネルがアプリケーションを管理するためのデータ構造や、バンク間のデータをコピーするためのコードとバッファなどがあります。


Z280MBにFUZIXを移植するには、z80packのメモリレイアウトは都合が良さそうです。Z280のMMUのページサイズは4kバイトなので、0x0000-0xefffの領域を異なる物理アドレスにマップすることで、バンク切り替えと同じ動作にできます。

2021年10月5日火曜日

FUZIX:z80packのブートディスク

z80packのブートディスクを見ていきます。

ブートディスクは、CP/Mでは標準の 8インチ IBM3740フォーマットです。

セクタサイズ 128
セクタ数/トラック 26
トラック数 77

ディスクの先頭から58トラックにはファイルシステムを置くことができますが、Makefileのdiskimageで作られるイメージでは空でファイルシステムは作られません。第1セクタは特別で、ブートコード bootblock.bin が書き込まれます。59トラック目から最後のトラックまでは、FUZIXのカーネル  fuzix.binが書き込まれています。READMEには、カーネルはディスクの60トラック目から書かれていることになっているのですが、bootblock.sを読んだ限りでは、59トラック目からが正しいようです。


PCがリセットされると、BIOSがディスクからブートコードをメモリの0x0000番地に読み込み実します。ブートコードは、128バイトに収まるように作ってあるので、大して複雑なことはできません。bootcode.sを読んでみると、59トラック目から順番にディスクアクセスし、0x0088番地からメモリに書き込んでいくだけのコードです。最後に0x0088にジャンプしてカーネルを実行を移します。



2021年9月30日木曜日

FUZIXをビルドしてみる

 Z280MBにFUZIXを移植する試みの第一歩です。

FUZIXの情報を求めてネットをさまよってたどり着いたのが、Oh!石さんの FUZIXをビルドしてみよう です。最近のバージョン 0.4pre1 のビルドに成功されていて参考になります。

FUZIXにはターゲットとしてZ280もあるのですが、まだ動作していないようなので、まずはz80packでFUZIXを動かし、その構造や動作を確認したいと思います。

FUZIXの実行環境構築

Ubuntu 20.04.3と WSLで確認しています。

SDCCのインストール

バージョンは4.1.0で、インストールはOh!石さんの記事に従って行っています。

z80packのインストール

バージョンは1.37です。こちらは、make installの前に、ホームディレクトリにbin/を作っておきます。make後はメッセージに従い $HOME/binをPATHに加えます。こうしないと、z80packの実行時にエラーが出ます。いちいちexportするのは面倒なので、.bashrcにでも書き加えておきます。
$ tar xvzf z80pack-1.37.tgz
$ cd z80pack-1.37/cpmsim/srcsim
$ make 
$ cd ../srctools
$ make
$ mkdir ~/bin
$ make install
$ export PATH=$PATH:$HOME/bin
cpmsim/cpm2で、CP/M 2.2 が起動するか確認しておきます。 Ctrl+\ で終了します。

FUZIXのビルド

GitHubからソースをクローンします。最新のコミットではkernelのコンパイルで失敗します。コンパイルが確認できているハッシュは、3d26de6eb800af0b1a5672b53ccbc0da6c1a3d1bです。
$ git clone https://github.com/EtchedPixels/FUZIX.git
$ cd FUZIX
$ git checkout 3d26de6e
Makefileを修正します。56行目あたりにビルドターゲットの指定があるので、z80packを指定します。90行目あたりのapps, kernel, diskimageターゲットから依存ターゲットのltoolsを削除します。
TARGET=z80pack
	...

apps:
	+(cd Applications: ...

kernel:
	mkdir -p Images ...
    
diskimage:
	mkdir -p Images ...

ユーティリティとクロス開発環境をコンパイルします。make install した後、/opt/fcc/binをPATHに加えておきます。

$ make stand
$ cd Library
$ make
$ sudo make USERCPU=z80 install
$ export PATH=$PATH:/opt/fcc/bin
クロス開発環境用のライブラリをコンパイルします。
$ cd libs
$ make -f Makefile.z80 USERCPU=z80
$ sudo make -f Makefile.z80 USERCPU=z80 install
FUZIXアプリケーションをコンパイルします。fcc(SDCC)でのコンパイルはかなり時間がかかるので、テレビでも見ながら気長に待ちます。
$ cd ../../
$ make apps
カーネルをコンパイルし、ルートファイルシステムとブートディスクのイメージを作成します。
$ make kernel
$ make diskimage

FUZIXの起動

ディスクイメージは、FUZIX/Images/z80pack/に作られています。これらをz80packにコピーしエミュレータを起動します。

$ cp FUZIX/Images/z80pack/boot.dsk z80pack-1.37/cpmsim/disks/drivea.dsk
$ cp FUZIX/Images/z80pack/hd_fuzix.dsk z80pack-1.37/cpmsim/disks/drivei.dsk
$ cd z80pack-1.37/cpmsim/
$ ./cpmsim

bootdev: には 0 を入力し、rootでログインすれば、プロンプトが出ます。

終了する場合はshutdownコマンドを実行後、Ctrl-\ を入力します。

 

 

2021年9月26日日曜日

Z280MB 考え直して高速化

 前回、Z280MBのこれ以上の高速化はやめておくと心に決めていたのですが、なにか釈然としないのと、ASCIIARTの実行速度を収集?しているはせりんさんからのリクエストもあり、外部クロックの12MHz化を試してみることにしました。

難しいというか面倒なのは、外部クロックを変更できるのが、リセット時にハードウェア的にのみできるということです。実際には、

  • /RESETの立ち上がりエッジで、/WAITをLowにしておく
  • AD0-AD7に初期化データを乗せておく
  • 2クロックサイクル以上、/WAITと初期化データを保持
最初はCPLDにまだ余裕があるので、/WAITをLowに保持するロジックを組み込もうと考えていたのですが、よく考えたら/RESETから適当にCRディレイ回路で/WAITを作れば良いと思いつきました。

問題は、2クロックサイクルが何のクロックサイクルかだったのですが、結局CLKピンからの出力2クロックサイクルのようです。データシートからは、外部入力クロックのXTALIのように読み取れるのですが、これに合わせると初期化できませんでした。長さは検証していないのですが、2クロックサイクル以上ならどうでも良いようです。

リセット回路にCRディレイ回路を付け足したのと、写真の赤線で囲んだところに、AD0-AD7に初期化データが乗せられるようにDIPスイッチとバッファが付け足してあります。

実行結果は、外部クロック6MHzから30秒ほど縮めて、1分33秒まで高速化できました。まあこれなら納得できます。



2021年9月5日日曜日

Z280MB ASCIIART(マンデルブロ集合)を実行してみて思うこと

 Z280MBにCP/Mを移植できたので、この界隈で試す人の多いASCIIARTを試してみました。


実行環境は、内部クロック12MHz / 外部クロック6MHz / MBASIC rev.5.21です。

結果は、キャッシュONで2分38秒、キャッシュOFFで5分11秒でした。結果をTwitterにあげたところ、Electrelicさんからリフレッシュを止めるともうちょっと速くなるとアドバイスをもらい試したところ、2分8秒まで改善しました。Z280MBはDRAMを使っていないので、リフレッシュは不要なのですが、こんなにリフレッシュサイクルが負荷になるとは思ってもいませんでした。

参考にさせてもらったElectrelicさんの記事はこちらです。Z280固有の初期化(その1)

結果は、はせりんさん 番外編:ASCIIART(マンデルブロ集合)ベンチマーク に掲載されたのですが、他のZ80系CPUに比べてお世辞にも速いとは言えません。同じクロックだと、確実に高速版Z80やHD64180に負けるでしょうし、キャッシュOFFの結果は悲惨です。

これ以上の高速化は、外部バスクロックの12MHz化とバーストモードを使うことが必要ですが、ハードウェアの改造や新規設計が必要になるのでやめておきます。

Z280には、ユーザ/システムの分離とか仮想メモリが可能なMMUとかI/D分離とか、他にも面白い機能があるので、浪漫あふれた古の石ということで良いのではないでしょうか。

CP/Mの次はFUZIXを移植してみたいと思っています。

Z280MB CP/Mを移植

ここしばらく、Z280MB に CP/M を移植していました。移植したバージョンは 2.2 です。EDでコードを書きASMでアセンブルできることを確認しています。

CP/M-8000 の移植は経験済みだったので、大して難しくないのかなと思っていたのですが、ディスクアクセス周りで苦戦して結構時間がかかってしまいました。かなり悩んだすえ、結局使っていたコンパクトフラッシュカードの問題だったようなのですが、おかげで、8-bit から16-bit PIOモードにコードを書き換えたりできたので良しとします。ディスクアクセスのブロッキング・デブロッキングは思いっきり手抜きです。気が向いたら書き換えることにします。

CP/M-8000と違って、CCPがコマンドで上書きされたり、メモリーの配置が全然違ったりで最初とまどったのですが、ネット上に情報が豊富にあり助けられました。今回の移植作業で、参考にしたサイトを上げておきます。

pineconeの電子工作 

 BIOSの作成過程が楽しく詳しく語られています。非常に参考になりました。

nekoJavaさんのCP/Mコーナー

 CP/M-8000のときも参考にさせてもらいました。CP/Mど素人の私にはありがたいサイトです。

Grant's homebuilt electronics

 コンパクトフラッシュをつなぐのに参考にさせてもらっています。

移植の成果は、Github にあげておきました。CP/Mのライセンスの関係でBIOSのソースコードのみを上げることにしました。BIOSをアセンブルし、できたバイナリをCPM.SYSと結合するMakefileとディスクイメージを作るシェルスクリプトを入れておきました。

まあ、試す人はいないと思いますが。


2021年7月24日土曜日

Z280MB CFカードを接続と回路図公開

 Z280MBにCFカードを接続できるように拡張しました。Z8002MBで作ったIDEインターフェースボードをそのまま流用し、その先にIDE-CF変換アダプタを接続しています。


CFカードのセクター読み書きができることは確認できているので、まずはCP/Mを移植してみようと思っています。

ハードウェアは一段落したので、GitHubに回路図を上げておきました。これを見て作ろうとする酔狂な人はいないとおもいますが。

Z280MB GitHubリポジトリ


2021年6月19日土曜日

Z280MB 起動する

Z280 MPU Boardは、はんだ不良などでかなり苦戦していたのですが、安定して動作するようになりました。

現在は簡単なマシン語モニタが動作しています。

  • メモリダンプ
  • メモリ書き換え
  • ジャンプ
  • インテルHEXファイルのロード
の必要最低限のことしかできませんが、EEPROMの書き換えが必要なくなり、だいぶ作業が楽になります。これからは、このモニターでテストコードを走らせながら、Z280特有の機能を試していきたいと思います。


その先にはボードを拡張して、CP/M や FUZIX を移植してみたいとも考えています。

2021年5月19日水曜日

Z280MB 組み立て

 GWを目一杯使って、Z280ボードを組み立てました。


16bit CPUは配線量が多く、老眼が進んできている自分にはかなりきついです。特にPLCCソケットのピンへのはんだ付けは、線同士が重なるので見づらくて正直あまり好きではありません。よく順番を考えながらはんだ付けしていかないと、あとで後悔します。白のラッピングワイヤがデータバス、オレンジがアドレスバス、青がバス制御とその他の信号ラインです。


ユニバーサル基板で作るのは、自分にはそろそろ限界なのかもしれません。次回はPCBを起こせるようになりたいものです。

このMPUボードは、CPUクロックが12MHz、SRAMが256kバイト、EEPROMが16kバイトの構成です。ROMは実際には2Mビット×2なのですが、そんなにもいらないので、16kバイト分だけ使えるようにしてあります。リセット直後は、64kバイトのメモリ空間にはROMしか現れず、MMUをつかってアドレス上位に置かれているSRAMをマッピングして使えるようにします。

現状では、UARTから”hello world"が出力できているレベルで、MMUなどの確認はできていません。回路図は動作が確認できたら公開するつもりです。



2021年5月2日日曜日

Z280のZ-BUS

当初、Z280を8-bitのZ80-Busで動かそうと思っていたのですが、はんだを始めたら調子が乗ってきたのと、あとで変更するのが結構面倒なことに気づいたので、はじめから16-bitのZ-BUSで行くことに変更しました。


Z-BUSでもアドレスとデータバスはマルチプレクスされているので、アドレス用の8-bitラッチが2個必要になります。
データバスの接続は、偶数番地がAD15-AD8に、奇数番地がAD7-AD0になります。バイトリードの場合は、Z280がAD15-AD0の上位と下位を選んでデータを読み込んでくれますが、バイトライトの場合は、AD15-AD0の上位と下位には同じデータが出されますので、A0で書き込むメモリチップを選択をする必要があります。ワードのリードライトでは、Z280がリトルエンディアンなので、上位と下位を入れ替えてくれます。

B/Wはバイトかワードアクセスを示し、R/Wはリードかライトを示します。/DSはデータの読み書きのタイミングをとる信号です。Z8000のZ-BUSと違うところは、メモリアクセスを示す/MREQがありません。ST3-ST0をデコードしてメモリアクセスかを判断する必要があり、1000と1001の場合がメモリアクセスを示します。

Z-BUSでのメモリアクセスのタイミングは下図のようになっています。Z8000と同じです。

2021年4月19日月曜日

Z280のクロック

 Z280のクロックは少し複雑です。チップからは、XTALI, XTALO, CLK の3本もクロック関係のピンが出ています。

Z280は内部にクロックオシレータを持っており、水晶振動子をXTALIとXTALOにつなぐか、XTALIに外部からクロック信号を入れると動作することになっています。内蔵オシレータからのクロックは1/2に分周され、CPUクロックになります。今手持ちのCPUは12MHz品なので、クロックは24MHzまで入れることができます。

外部バスのクロックは、CPUクロックを更に1/2, 1/4分周にすることができ、CLKピンから出力されます。デフォルトでリセット後は1/2にセットされるのですが、この分周比は、データシートによるとソフトウェアからでは変更できません。

これは、アクセススピードが遅いメモリやI/Oを接続することを考慮したものなのでしょうが、Z280を最速で動かすには、バスクロックをCPUクロックと同一にする必要があります。厄介なことに、この分周比を変更できるのは、リセット時にデータバス経由で値を渡す方法だけのようです。

2021年4月10日土曜日

Z280のZ80-Bus

 

Z280のZ80 Busですが、その名前と違い、メモリやI/Oと接続するための信号やタイミングはZ80とは完全に同じではありません。8-bitバスという点では同じなのですが。


データD0-D7とアドレスA0-A7は、AD0-AD7としてマルチプレクスされているので、アドレスを保持するためにZ8000と同じようにアドレスラッチが必要です。/ASは、AD0-AD7がアドレスを出していることを示す信号です。
/OEと/IEは、ADが出力か入力を示す信号で、ちょっと使いみちが思いつきませんが使わなくても大丈夫そうです。

Z80と違い、命令のフェッチでもデータのリードライトでも同じタイミングで行われます。

メモリリードでは、/MREQがLになり、続いて/RDがLになります。データはT3の立ち下がりで読み取られます。

メモリライトでは、/MREQがLになり、AD0-AD7にデータが出力され、続いて/WRがLになります。

よくある非同期バスなので、スタティックメモリをつなぐだけなら大して難しくはなさそうです。

I/Oアクセスは、タイミングは違えどメモリとほぼ同じようです。Z280には主要な周辺I/Oが組み込まれているので、I/Oアクセスの事はしばらく忘れておきます。


参考文献 
 Z280 PRELIMINARY Technical Manual
 Z280 Product Specification

2021年4月3日土曜日

Z280のリセット

Z280の資料を読み始めました。まずはリセットあたりから。

Z280のリセットは少々複雑です。 ハードウェアリセットは、/RESETピンを128クロックサイクルの間、Lにすることでかかります。 
外部バスをZ-BUSかZ80 Busにするかは、このリセット時にOPTピンで決定します。

 Z80 Bus --- opt = L 
 Z-BUS ----- opt = H or NC

/RESETピンをHに戻すときに、/WAITピンがLになっているとAD0-AD7ピンからデータを読み込んでBus Timing and Initialization Register を初期化できます。AD6をHにしておくとブートストラップモードになり、リセット後にUARTから256バイト読み込んで実行します。ROMレスなシステムを作るの使う機能で面白そうですが、スタンドアロンで動作できなくなってしまうので、今回は使わないつもりです。
他にも、メモリアクセス時のウエイト数を設定したり、外部バスクロックの設定ができたりするのですが、初期化に余分な回路が増えるため、この初期化方法は使わないことにします。

/RESETがLになっている間は、AD0 - AD15, A16 - A23 はHi-Z で、他の制御出力ピンはHになります。

参考文献 
 Z280 PRELIMINARY Technical Manual
 Z280 Product Specification

2021年3月30日火曜日

Zilog Z80280

 Z8000へのPCC移植がちょっと行き詰まってしまい、気分転換にはんだ付けがしたくなってきました。今回の目標はZilog の Z280を動かすことです。


この石は中国から購入したのですが、ほんまもんなのかがわかりません。時間かけたあげく無駄に終わる可能性もあります。前回のZ8002も中国から購入したのですが、(本当に10MHz品かは別として)こちらは動作しました。偽物を掴まされてたとしても、それはそれで楽しいので、手をつけてみます。

Z280は、Z80とコードレベルで互換性がある16bit CPUです。単純にCPUなわけではなく、MMUやDMA、タイマ、シリアルポートなどを集積したかなり豪華な構成になっています。メモリスペースはMMUを通して、64kByteから16MByteまで拡張されています。外部バスは、16bitのZ-BUSモードか8bitのZ80 Busを選べるようになっています。

もちろん、Z280の性能を活かし切るにはZ-BUSで使うことになるのですが、配線量が増えるし、偽物だったときの精神的ショックを抑えるため、まずはZ80 Busで動かしてみたいと思います。