GWMON-80用 MC6850 I/Oモジュール作成

前回紹介した80系機械語モニタ GWMON-80用に Grant’s Z80 マイコンでも使用しているモトローラMC6850シリアルLSI用のI/Oモジュールを作成してみたいと思います。

I/Oモジュールの仕様について

以下のREADME.mdの後半にも書かれているとおり、I/Oモジュールとしては4つのサブルーチンが必要です。
https://github.com/kuninet/glitchworks_monitor/blob/master/README.md#writing-io-modules

サブルーチン名説明
SETUP・スタックポインタの設定
・デバイスの初期化
CINNE・エコーなし1文字入力
CIN・エコーあり1文字入力
COUT・1文字出力

今回は、i8251汎用I/Oモジュール(io_modules/i8251.asm)をベースにポーリング型のシリアル通信の実装をしてみます。

SETUPルーチン

まずはSETUPルーチンです。上記の表にもあるとおりZ80/8080システムとしての初期設定を実施します。

シリアルデバイスのI/Oポート定義

シリアルデバイスのI/OポートアドレスをEQUで定義します。今回はGrant’s Z80マイコンの仕様にあわせて以下のように、制御ポート80h、データポート81hとします。

CTLPRT  equ 80H
DATPRT  equ 81H

スタックポインターの設定

スタックポインターは通常 最上位アドレスFFFFhからへ設定します。今回 バンク切り替えしないシステムではそのままでOKですが、私が作った128k SRAMボード(KZ80-1MSRAM)の場合は固定RAM領域が7FFFhですので、自分の環境にあった設定に変更します。

 
SETUP:  LXI SP, 0FFFFH

シリアルデバイスの初期化

つづいてシリアルデバイスの初期化を行います。INIUART$に定義されたデータを制御ポートへ指定バイト数分出力するルーチンになっています。MC6850の初期化はi8251よりもシンプルでリセット(03h)と通信設定「割り込みなし、8bitノンパリティ、64分周」(16h)にします。
送出バイト数も忘れず 2へ修正します。

        MVI B, 02H              ; length of ini string
INURT:  MOV A, M
        :
        :
;Init string for the 6850, x64 clock, 8N1
INIUART:  db 03H,16H

CINNE(エコーなし一文字入力)ルーチン

エコーなし1文字入力ルーチンでは、MC6850のコントロールポート(80h)をREADしてステータスレジスタの値に01hのビット(受信OK)が立っていたらデータポート(81h)から読み込むようにします。

CINNE:  IN CTLPRT
        ANI 01H
        JZ CINNE
        IN DATPRT
        RET

CIN(エコーあり一文字入力)ルーチン

エコーあり一文字入力は i8251.asmを真似て エコーなし一文字入力ルーチンをCallした後 データポートへ1文字出力することにします。
(後述する出力可フラグをチェックしたほうがベターかも…)

CIN:    CALL CINNE
        OUT DATPRT

COUT(一文字出力)ルーチン

エコーあり一文字出力は、MC6850のコントロールポート(80h)をREADしてステータスレジスタの値に02hのビット(送信OK)が立っていたらデータポート(81h)へ出力するようにします。
一文字入力と一文字出力のReadyフラグが8251とMC6850では逆になってますが大枠としては同じロジックでいけそうです。

COUT:   PUSH B
        MOV B, A
COUT1:  IN CTLPRT
        ANI 02H
        JZ COUT1
        MOV A, B
        OUT DATPRT
        POP B
        RET

Grant’s Z80 ユニバーサル基板マイコンで 稼働テスト!

ここまで対応したI/Oモジュールを、GWMON-80のメインモジュール(monitor.asm)と合体させて、CP/MのMAC.COMでアセンブリしたものを、GWごろに作成したGrant’s Z80 ユニバーサル基板マイコン用のROMとして焼いて動かして、無事稼働しました!!
シリアルのスピードは115200bpsですが、ポーリング型でも意外と取りこぼし無く動きます。今後 SBC8080データパックのソースを参考にさせていただいて 割り込み駆動型などへも挑戦してみたいと思います。^^)>
今回修正したソースは、以下のgithubにもUPしています。前回のビルドスクリプトを改良してMC6850用モジュールビルドも自動化していきたいと思います。
https://github.com/kuninet/glitchworks_monitor/blob/master/io_modules/MC6850.asm

広告

80系機械語モニタ GWMON-80

8080/8085/Z80で稼働する機械語モニター GWMON-80を最近よく使わせてもらっています。

機械語モニタ GWMON-80について

  • 機械語モニタGWMON-80はgithubで公開されています。なんと2018年にメンテされている機械語モニターです。素晴らしい。
  • 機能は以下の通りで、シンプルなものとなっています。
    • Z80のクロスコンパイラなどで出力されるインテルHEX形式データのロード機能を持っています。
    • LEDチカチカさせたりZ80でI/Oポートをよく叩く私としてはIN/OUT命令が装備されているのがお気に入りです。
 
D XXXX YYYY Dump memory from XXXX to YYYY 
E XXXX Edit memory starting at XXXX (type an X and press enter to exit entry) 
G XXXX GO starting at address XXXX (JMP in, no RET) 
I XX Input from I/O port XX and display as hex 
O XX YY Output to I/O port XX byte YY 
L Load an Intel HEX file into memory 

ビルド方法について

ビルド用バッチファイル

  • README.mdを読んでいただけると分かりますが、ビルドはモニター本体(MONITOR.ASM)と自分の環境に合ったI/Oモジュール(xxxx.ASM)を1つのファイルへ合体させてCP/Mのアセンブラでアセンブルすることとなっています。ビルド方法はプロジェクト範囲外ということで好きにやってくださいってことでした。
  • そこでビルドについて検討して、Windows10 Pro環境で以下のツールを使うことでアセンブルができました。手作業で毎回ビルドするとコマンドを忘れがちなのでWindowsのバッチファイルを作成しました。gistにUPしています。
  • ちなみに、他のクロスアセンブラでも若干のソース修正が必要ですが可能です。The MacroAssembla(ASL)では ラベルに”$”が使えなかったり、文字列の指定を “(ダブルクォート)に変更することでアセンブリ可能でした。
  • このビルド用バッチではgithubからソース類をもってきて、スタートアドレス/スタックポインタアドレス等の変更を行った後、CP/M ExecuterでMAC.COM(マクロアセンブラ)を起動する流れとなっています。
  • 依存関係を元に必要なビルドだけを実施できるとカッコイイですが、そこはまた今後の課題ということで ^^)>
  • KZ80-CPUB+SBC8080 SUBやSBC8080+SUBボードで使用している8251用のI/Oモジュールを合体させるスクリプトになっています。
  • KZ80-1MSRAM用にスタックポインタをFFFFh→7FFFhへ変更したソースも生成しています。

バッチファイルを動作させるディレクトリ

  • バッチファイルを動作させるディレクトリは、以下の構造を想定しています。
.
│ build.bat
├─build\
│ [build terget Dir]
├─cpm32_04\
│ │ [CP/M Executer Dir]
│ ├─src
│ └─utl
├─glitchworks_monitor\ [GWMON-80 git checkout Dir]
│ └─io_modules
├─mac-b\ [ CP/M MacroAssembla MAC.COM]
└─src\ 
  • cpm32_04ディレクトリはCP/M program EXEcutor for Win32を展開したディレクトリ、mac-bディレクトリはMAC BINARY (8080 Macro Assembla)を展開したディレクトリです。

ビルドバッチファイルの実行

  • ビルドバッチファイルを実行すると build\ ディレクトリにモニターのソースが生成されMAC.COMでアセンブルされた リストファイル(.PRN)とインテルHEX形式のオブジェクト(.HEX)が生成されます。
 
> build.bat

動くとこんな感じ

  • 機械語モニターを動かすとこんな感じです。

つぎは…

ビルドができたので、つづいて別のシリアルチップ用にI/Oモジュールを書いてみたいと思います。Grant’s Z80コンピューターで使ってるモトローラMC6850チップ用のモジュールを作ってみたいと思っています。


KZ80-IOB REV1

以前ユニバーサルボードに試作した 8255A(PPI)搭載ボードに、端末(PC/Mac)接続用シリアル(i8251)を一緒に搭載したI/Oボードのプリント基板を起こしてみました。SBC8080バスに接続できるので、KZ80-CPUB/SBC8080 CPUルーズキット等と一緒に使います。

☆端末(PC/Mac)接続用シリアル(i8251)はI/OアドレスによってはSBC8080 SUBルーズキットの8251とバッティングします。

概要

  • SBC8080バスにつながる I/Oボードです。
    • パラレルI/O(8255A)と端末(PC/Mac)接続用シリアルI/O(8251)を搭載しています。
    • 自作のFM音源チップ搭載Arduinoシールドを乗せるためのピンソケットが配備できるようになっています。(他の方は使いみちが無いかも….)
    • 若干回路をみなおして REV1.1 リリース1.0にすると思います。(時期未定ですが…)

回路について

  • 回路図はこちらです。
    • 回路図、ガーバーデータ等はgithubで管理しています。ご覧ください。
  • パラレルI/O(8255A)、シリアルI/O(8251)、FM音源の各チップのアドレスデコードは74HC138で実施しています。128kメモリーボード(KZ80-1MSRAM)のバンク切り替え用I/Oアドレスを80h番地固定にしていることと、SBC8080 SUBルーズキットとの互換性を考えて以下の設定が推奨です。基板上のジャンパピンを各1つ短絡することで設定できます。
    • パラレルI/O(8255A) ・・・・・・ C0h
    • シリアルI/O(8251) ・・・・・・ 00h
    • FM音源 ・・・・・・ 40h

  • シリアルI/O(8251)のクロック用に水晶振動子 4.9152MHzを74HC4060で32分周して153.5kHzを作り出しています。
  • パラレルI/O(8255A)の入出力端子としてポートA+ポートCの4ポート、ポートB+ポートCの4ポートを14ピンヘッダに出しています。
    • REV1では8255AのグループA/Bの組み合わせと合っていません。次のリビジョン(REV1.1)では変更する予定です。

部品組付けについて

  • 部品表はこちらにあります。OpenOffice等の表計算ソフトで読み込める形式となっています。
  • それほど変わった部品はありませんが、トランジスタ2SC1855は1回路分のNOT回路を構成するために使用しています。同等品であれば大丈夫だと思います。トランジスタのパターンが狭くてハンダ付けがしずらいと思います。すいません。

使用例

Lチカ

  • パラレルI/O(8251A)を使用したLEDチカチカをさせた例は以下になります。

  • LEDは以下のように配線してください。8255AのBポートへ出力する例となります。
    • BポートへLレベルを出力したLEDが光ります。

  • 以下がSBC8080データパック付属の機械語モニタで出力する際のプログラム例です。8255AのI/OアドレスはC0hとしています。
8000
MVI A,80
OUT C3
MVI A,AA
OUT C1
RET
EXEC 8000

FM音源装着

  • FM音源(YM2151)ボードを装着した例です。

使用する場合の注意

  • PC/Macを使ったシリアル通信はSBC8080 SUBルーズキットやSBCシリーズと同様 TTLレベルのUSB-シリアルコンバータで接続してください。GNDの位置がシルク上わかりずらいと思いますが「232C」と書かれた側がGNDです。
  • SBC8080 SUBルーズキットといっしょに使用する場合は、端末用シリアルI/O(8251)のI/Oアドレスをズラすか どちらかの8251を外して下さい。

これで、Z80 CPUボード(KZ80-CPUB)、メモリーボード(KZ80-1MSRAM)、I/Oボード(KZ80-IOB)がそろって、3枚一組でマイ・コンピューターとして動作できるようになりました。
ひとまず、このセットを KZ80-I (ケーゼットハチジュー・ワン)と命名したいと思っています。^^)/

KZ80-1MSRAM Rev.1 リリース0.9

以前 手配線でユニバーサルボードに試作した 128kBバンクRAM/ROMボードの基板を起こしてみました。

概要

  • SBC8080バスにつながる 128kBバンクメモリー+ROMボードです。
    • 名称の”1M”は1Mbitということで…^^) 1MBではありません。
    • 若干回路をみなおして リリース1.0にすると思います。(時期未定ですが…)
  • 本基板に関するKiCAD等の回路図/ガーバーデータ、機械語モニタ+TinyBASIC用 ソース、HEXデータはGirhubで管理しています。ご覧ください。
  • メモリーマップは以前の記事でも紹介したとおり、以下のようになっています。

回路について

  • 回路図はこちらです。
    • 回路図、ガーバーデータ等はgithubで管理しています。ご覧ください。
  • 74HC139でROM/RAMの切り替えとバンク切り替え用I/Oアドレスのデコードを行っています。
    • メモリーはROMが16kB、固定RAM域が16kB、バンクメモリ域が32kBとなっています。
  • 74HC573でバンクメモリー番号を保持しています。バンク番号はI/Oアドレス80hへ1、2,3のバンク番号を出力することで切り替えできます。(☆前回の試作のI/Oアドレスから変更しています。FM音源ボードとぶつかってしまって…(>_<))
    • 実際の128kBメモリーのアドレスバス A15、A16のコントロールは74HC543の出力をゲートICでデコードして接続しています。
    • バンク番号0(ゼロ)はバンク1へ読み替えて出力するようにしています。

部品組付けについて

  • 部品表はこちらにあります。OpenOffice等の表計算ソフトで読み込める形式となっています。
  • 1Mbit SRAMはHM628128、ROMは28C256型を想定しています。
    • 秋月電子で売っているSOPの1M bit SRAMでもDIP変換すれば使えるものがあります。☆ビンアサインがHM628128と異なるSRAMもあるようですので注意してください。

ソフトウェアについて

  • バンクメモリーの切り替えは、8080マシン語で書くと以下のようなコードとなります。
4000
MVI A,1  ← バンク番号を指定
OUT 80h
RET
EXEC 4000
8000
DEFINE 01,02,03   ← 適当な値を入力して 別々のRAMが選択されていることを確認
DUMP 8000
  • バンクメモリーの領域がSBC8080 SUBルーズキットのもともとのRAM領域となっているため、SBC8080データパックの機械語モニタ+TinyBASICなどのワークエリア、スタック域等を固定RAM域へズラす必要があります。
    • 参考として、機械語モニタ+TinyBASIC(PTBEXSA.ASM)のワークエリア、スタック域等の変更箇所は以下になります。
    • (10/21追記) こちらのソース/アセンブリ後のHEXファイルはgithubに添付しました。

[各種アドレスの変更]

FTOP    EQU 4000H
LTOP    EQU 5000H
VTOP    EQU 07000H
STACK   EQU 07E00H

[機械語モニタのTOPアドレス変更]

main:
    LXI H,-484
    DAD SP
    SPHL
    LXI H,482
    DAD SP
    XCHG;;
    LXI H,16384       ;<-- ココ
    CALL    CCPINT

こちらを変更した際のメモリーマップは以下のようになります。

想定している用途

  • わたしはバンク切り替えできるメモリーエリアにFM音源の演奏データを入れて、複数データを切り替えながら演奏してみたい! という用途で作りました。
  • 一時点でアクセスできるメモリーは64kBですが、64kBの壁を超えてメモリーにデータを置くことができますので、いろいろと楽しい使い方ができるのでは?と思っています。

KZ80-CPUB Rev.1

以前 ユニバーサル基板で作った Z80 CPUボード(SBC8080バス直結) のプリント基板を起こしました。

githubにガーバーデータを含めたデータを公開しています。
また、オレンジピコさんでも基板を販売していただけることとなりました。

概要

  • SBC8080バスにつながる Z80 CPUボードです
    • ☆SBC8080との完全互換ではありません。
    • 外部リセット端子がつながってません
    • DMA関係の配線がされてません。(#BUSREQ/#BUSACK未配線や#IOR/W、#MEMR/WのHiZ未対応とか…)
  • 単体ではメモリー/ROM/シリアル等がありませんので、SBC8080 SUBルーズキット等と組み合わせてご使用下さい。

回路図について

  • 以前ユニバーサルボードで作成したときと回路は一緒です。プリント基板化に伴いバイパスコンデンサ、電源端子等も正しく書き加えました。

部品組み付けについて

  • 部品表はこちらに OpenOffice等の表計算ソフトデータとしてUPしてありますのでご覧ください。
  • Z80 CPUは CMOSタイプの Z84C0020PEC で動作確認しています。
  • ロジックICのインバータのみCMOSタイプ(74HC04 or 74HCU04)必須です。
  • 電解コンデンサは極性にご注意。(タンタルだと爆発の危険も…)

ソフトウェアについて

基板のデータ等

各種ライセンス等

  • girhubの方のライセンス文書にも書きましたが、MIT License のもとで公開します。

KiCADの回路図描きの練習から始めて、プリントパターンエディタの使い方の練習、オートルーターのセッティングなど色々とありましたので、今後じわじわとBLOGにまとめて行ければと思っています。

BASICで3Dグラフィック

TwitterでBASICで3Dグラフィックを出している方がいらっしゃいまして….

MC68000系のBASICではあったのですが、最近作っていた8080系のマイコンのBASICイケるかもと思いトライしてみました。

SBC8085で3Dグラフィック

SBC8085 (あ、製作記事書いてない…)と SBC8080データパックのGrant’s BASICで試してみました。
参考にさせていただいたソースとの違いが、50行目の追加(PI=3.14)と800行目をちょっと修正しました。あと16進定数は “&H”へ修正。
TeraTERMでTEK4010端末エミュレーションというもので別窓が開いてグラフィックが出ます。マイコンでグラフィックが ! ! ちょっと感動 ! !
(エスケープシーケンスみたいな感じでBASICからはキャラクター文字列が飛んできている感じ。)

SBC8085は3MHz駆動でシリアルコンソールも9600でして28分程度かかりました。

SBC80系 Z80マイコン(10MHz)でトライ

SBC80系バスにつながるZ80マイコン(10MHz)でもチャレンジしてみまして….
11分16秒ぐらいで描画できました。(下はさきほどとほとんど同じ画像ですな…^^) )
MZ-2000とおなじぐらいのスピードが出ました。

Grant’s 6chipマイコンで挑戦

シリアルスピードが影響しているかも?と思い、GWごろに手作りしたZ80マイコンでも同じBASICプログラムを試してみました。
なんとクロックが7.3728MHzとちょっと遅いはずですが最速wの11分14秒ぐらいでグラフィックが完成!
やはり文字列でドット位置の情報が飛んできているのでシリアルのスピードも効いてくるみたいです。

このBASICのグラフィックデモってMZシリーズの宣伝で雑誌でよく見かけた気がします。
当時PC-8001ユーザーだった私は、高精細グラフィックが出ているMZシリーズがうらやましかった思い出がありまして、マイコンでグラフィックが出て感無量です。
(T-T)

SBC68系 128kB バンクメモリボード(3)

SBC68系 128kBバンクメモリーボードのハードウェアができた(はず)なので、メモリーチェックプログラムとかLILBUGへバンク切り替えコマンドを追加してみたいと思います。

メモリーチェックプログラム

SBC6303データパックに拡張32kBメモリーボード用のチェックプログラムがありますので、そちらを参考にバンク切り替えしながらメモリーチェックを実施するプログラムを作ってみます。
以下がgistへUPしたソースです。

  • 今回のRAMボードで$A000-$BFFFに8kBのメモリーも配備したので、プログラムは$B000へ配置しました。
  • バンク切り替えにはHD6303のI/OポートP10〜P12を使用します。3bitの出力に1〜7までのバンク番号(0の場合はバンク1を選択)を出力することで切り替えできます。

実行結果はこんな感じです。うまくチェックできたみたいです。

LILBUGコマンド拡張してバンク切り替えコマンド

バンク切り替えのためにプログラムをいちいちロードしたりして切り替えるのが面倒なのでLILBUGコマンドを作ってみたいと思います。
LILBUGのマニュアルを読んでみると外部コマンドテーブルを作る事ができそう。ユーザーコマンドに該当がなければROM内のLILBUG標準コマンドが実行されるみたいです。

バンク切り替えはBコマンドとかにしたかったのですが、ブレークポイントで使われているため “K”コマンドということにしてみました。

使い方ですが、まずは LILBUGで $B000からGコマンドで実行してください。ユーザー用コマンドテーブルのポインタを更新してバンクメモリーをバンク1へ初期化してLILBUGへ移行します。

! G B000

コマンドの書式は ” K△n “(△:スペース)はバンク切り替えします。nはバンク番号で入力と共に切り替わります。(確認とかナシ)
バンク番号を入れず ” K△[CR] ” だと現在のバンク番号を表示します。

ソースはこちらもgistへ上げました。こちらです。
こちらのプログラムも$B000のRAMに配置しました。ROM化は LILBUG ROMに手が入るなぁと思ってちょっと考え中です。

LILBUGは MIKBUGと違っていろいろと拡張性が考えられているので使いやすいですね!