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と違っていろいろと拡張性が考えられているので使いやすいですね!

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

ユニバーサル基板に試作

回路が固まりましたので、実際にユニバーサル基板にしてみます。
データバスを配線し始めた頃の写真です。

基板裏の配線はいつもどおり、ちょっと太めのスズメッキ線で配線します。
このとき最近SBC80系バスばかり配線していて+5V/GNDが反対側の端子だということに気づかなかったのは内緒です。

配線が終わって記念写真です。
IC間の配線はAWG28、30のワイヤラッピング線を使用しました。ICソケットも今回は全部板バネ式です。(32ピンソケットもSOP型からDIP型へ変換した128kB RAMを使いたかったので細ピンヘッダが入る板バネ式にしました。)

稼働確認

SBC6303と40ピンフラットケーブルでつなぎます。
LILBUGは基本内蔵RAMがあれば起動するので、ちょっと安心です。いつもだとここで応答が無い!!と悩むので….

LILBUGが起動したので、さらに電大版TinyBASICを起動して HD6303内蔵I/Oの初期化&バンク切り替えを実験です。
電大版TinyBASICはメモリー直接アクセスのPEEK/POKE書式を装備していて便利です。

#(0)=$FF
#(2)=xx  (xx:バンク番号 1〜7)

内蔵I/O PORT1の初期化は以下のように、SBC6303データパックのBLINK.ASMを参考に実施しました。

  • 0番地にPORT1のデータの方向をセット。今回は全ビット出力としました。
  • 2番地へPORT1へ出力するデータを設定します。ここは数字で1〜7でバンク番号を指定します。

LILBUGのMコマンドで バンクメモリアドレス($4000〜$7FFF)のデータを変更してはバンク切り替えを実施して、別々のメモリー領域が出現することを確認しました。メモリーボード完成です!!

次は、メモリーチェックプログラムとか、LILBUGのユーザーコマンドとしてバンク切り替えコマンドを作ってみたいと思います。

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

Z80/8080 CPU用に128kB メモリーボードを作成して動いたので、次はSBC68系の128kB メモリーボードを作ってみたいと思います。

メモリーマップの検討

SBC68系はZ80/8080系と違ってメモリーマップドI/O、つまりメモリーアドレス上にI/O機器がつながっています。
伝統的に$0000〜$7FFFまではRAM。$8000台はI/O、$A000はスタック用RAM、$E000〜とか後ろの方はブートベクタの関係もあってROMにするのが通例です。
当初はPIAやACIA、自分で搭載したFM音源チップなどをすべて$C000台持っていってメモリー領域を確保するという案も検討しましたが、それだとSBC6800/SBC6809の基板にパターンカット等を実施する必要がありちょっとポリシーに反する感じ。以下の方針としました。

  • 固定RAM領域は $0000〜$3FFFの16kBとする。(もともと8kBなのでこれでも余ると思いました)
  • バンクメモリは $4000〜$7FFFの16kBで、7バンク準備。(ここまで128kB SRAMを使用)
  • $A000からのメモリー領域をオリジナルのMIKBUGや電大版BASICがスタックとして使っている(MC6810想定)のため、余ってきている8kB SRAMを配備することにする。

メモリーマップのイメージはこんな感じです。

バンク切り替えコントロール回路

固定RAM領域($0000〜$3FFF)と バンク切り替え領域はどちらも同容量(16kB)としましたので、128kB SRAMを8分割して使用することになります。よって前回と違ってメモリーの3本のアドレスバス信号線(A14、A15、A16)をうまいことコントロールすることにします。
またバンクレジスタ機能は今回はSBC6303のI/Oポートによってコントロールすることにします。(独自のラッチは作りません)

  • CPUが固定RAM領域($0000〜$3FFF)にアクセスする場合はバンクレジスタの値に関わらず A14=A15=A16=”L”とする。
  • CPUがバンクメモリ領域($4000〜$7FFF)にアクセスする場合は、バンクレジスタの示すアドレスを使用する。
    • ただしバンクレジスタに0(ゼロ)が設定されている場合は デフォルトのバンク1(A16=A15=”L”、A14=”H”)とする。

上記を満たすロジック回路を、今回もLogisimを使って2入力ゲートICでシミュレートしてみました。

ゲートIC x3で実現できそうです。

回路図の検討

バンクメモリなどのコントロール回路が決まったので、128k SRAM、8kSRAMをコントロールする回路図を書いてみました。

  • 128kB SRAMの CS1へはアドレスバスのA15を入れます。$0000〜7FFFまでのアドレスならA15=”L”なので…(CS2はVccへ)
  • 8kB SRAMの CS1にはA13、A14、A15を74HC138でデコードした線をつなぎます。(こちらもCS2はVccへ)
  • バンク切り替えコントロール回路へは SBC6303のI/O出力 P10、P11、P12ピンを接続。アドレスバス A14、A15をORゲートを通して 両方”L”のときに”L”を出力させてつなぎます。(74HC138のデコードの代替です)
  • バンク切り替え状況が目で見てわかるように SBC6303のI/O出力 P10、P11、P12ピンにNOTゲート経由でLEDを接続します。

実は….

実は上記の回路図は修正して正しく動いている(と思う)版です。
基板作成当初の回路図では何を勘違いしたか固定RAM領域のデコード部分が間違ってました…orz
修正した箇所はこちら..
(もともとは固定RAM領域の判断に74HC138のO0端子を使ってました…それだと$0000-1FFFしかデコードできてない….)

固定RAM領域の $2000-3FFFFへ書き込むと 間違って バンクRAMの $6000-7FFFへ書き込まれるという事になってしまっていました….
余っていた74HC32のORゲートを使うことで事なきを得ました。良かった〜♬

SBC8080バスにつながる128kBメモリーボード(3)

今回はSBC8080バスにつながる128kBメモリーボードの回路を検討して、ユニバーサル基板で試作するところまでをまとめます。

シリアルLSIは搭載するか?

当初の目論見では、128kメモリーボードにシリアルLSI 8251を搭載しようと考えていました。
しかし、ターゲットのユニバーサル基板をいつもの秋月電子タイプB基板にするつもりで部品配置を考えたところスペース的に載らないという結論となり断念しました。

よって、シリアル通信のためにSBC8080 SUBボードからRAM/ROMを外して使用します。

ROM/RAM切り替えとI/Oアドレス切り替え

アドレス0000h〜3FFFhの 16kB ROMと 128k RAMの切り替えについては A15、A14を74HC139でデコードできそうです。(出力が4つなのでうまいこと16kBづつデコードできそう)
ちなみに、ROMには負論理のCS端子、128kB RAMには正論理の CS1端子があるのでそれぞれ74HC139の同じ出力をつないで上げれば切り替えができそうです。
(最初は74HC04のNOTゲートでひっくり返そうと思ってました…^^)>)

バンクレジスタ部分のI/Oアドレスですが、もともとのSBC8080 SUBボードでも74HC139でデコードしていますので、メモリーデコードで使用した74HC139の余った部分のデコーダで40hへデコードできそうです。

その後は前回の回路図同様 IO書き込み信号(IOWR)と NORゲート(74HC02)を通してラッチ(74HC573)のラッチイネーブル(LE)端子へつなぎます。

回路図全体

回路図の全体図はこちらです。

  • バンク切り替えの状況を目で見て確認したかったのでNOTゲート(74HC04)をつなげた先にLEDをつけました。
  • メモリーのA16,A15のコントロールは前回検討した回路そのままです。

ユニバーサル基板での試作

この回路図に従って、秋月電子ユニバーサル基板タイプBへ 試作を実施します。
引き回したケーブルはマルツパーツでたたき売りしていたAWG28サイズの単芯ラッピングワイヤ(赤)と 地元部品店で購入したAWG28サイズの青、緑、白のラッピングワイヤです。

こちらは、データバス、アドレスバスまで配線して力尽きた写真…

裏面の電源関係は0.5mmのスズメッキ線で配線しました。

完成記念写真がこちらです。
以前作ったZ80 CPUボード、SBC8080 SUBボード(ROM/RAM外し)と一緒に稼働させます。

無事 機械語モニタも起動して RAM領域の 4000hや8000hに書き込みができました。

また、下記のような機械語プログラムでバンク切り替えの稼働も確認できました

4000
MVI A,1  ← バンク番号を指定
OUT 40h
RET
EXEC 4000
8000
DEFINE 01,02,03   ← 適当な値を入力して 別々のRAMが選択されていることを確認
DUMP 8000

SBC8080でもメモリーボードが稼働

ちなみに、CPUボードをSBC8080へ繋ぎ変えてみて稼働することを確認しています。

余談 : KiCADの74HC139シンボルに惑わされ…

スムーズにいったように書いてますが、実はKiCADの74HC139シンボルに惑わされて痛恨の配線ミスをしています。
以下は配線するときに作っていた回路図で、74HC139へつなぐアドレスバス A7,A6とA15,A14の線をつなぐ場所が反転しています。よく見るとKiCADのシンボルでは端子名がA、BではなくA1、A0となっていて デコード表との関係がわかりやすくなっているようです。これだとI/Oアドレスのデコードは80hになりまして…最初は「バンク切り替えが動かん!!」と悩みました…orz

ちゃんとデータシートを確認して端子番号を確認しなきゃという教訓でした….

SBC8080バスにつながる128kBメモリーボード(2)

前回、メモリーバンク切り替えのためのバンクレジスタの試作がうまくいきましたので、つぎは128kBメモリーのアドレス線A16/A15をコントロールする方法について検討してみます。

メモリーアドレス線コントロール案

128kB SRAMのうち8000h以上のアドレスについて3分割してバンクメモリーとして使いたいと考えています。
Z80ではアドレスバスとしてはA0〜A15の16本(16bit分)しかコントロールできませんので、前回試作したバンクレジスタの2bitと合わせて上手くコントロールしたいと思います。
想定している真理値表は以下のとおりで、考慮した点は以下になります。

  • アドレスバス A15が “L” (つまり0000h〜7FFFh)へアクセスする場合は メモリーのA16/A15共に”L”にする。
    • バンクレジスタに何が出力されていても無視です。
    • このメモリー領域はROMとRAMで半分づつつかいますが、そのコントロールはCSをコントロールする別の回路にします。
  • バンクレジスタへ誤って 0x00を出力された場合でも、デフォルトのバンク1を選択するようにします。
Z80 A15 バンクレジスタ DA1 バンクレジスタ DA0 128kメモリー A16 128kメモリー A15 備考
L x x L L 0000h〜7FFFhまで
H L L L H バンクレジスタに0(ゼロ)がセットされた場合
H L H L L バンク1
H H L H L バンク2
H H H H H バンク3

これによって以下のように128kB SRAMの全体を有効活用できるようになると考えています。

ロジック回路による実現方法

上記の真理値表を使って実際のロジック回路を検討してみます。
Mac上のLogisimを使ってパソコン上で検討しました。

Logisimは真理値表から回路図生成もできまして、オプションで「2入力ゲートを使う」とか「NAND優先」というオプションもあります。
上図はそれで生成してもらった回路です。^^)>
74HC00 x1個と74HC04 x1個の2つのゲートICでコントロールできそうです!

次は実際の基板を作るための回路図を検討します。

SBC8080バスにつながる128kBメモリーボード(1)

先日作成したZ80 CPUボードのようにSBC8080バスにつながる 128kB SRAMメモリーボードを作ってみたいと思います。

メモリーレイアウト案

128kBメモリーは オレンジピコ秋月電子で売っている 628128型の128kB SRAMを使います。(秋月電子で売ってるSOP型も変換基盤でDIPにしてそのうち使いたい…)
128kBのスタティックメモリーが数百円で買えるなんて….

メモリーレイアウトは以下の通りで、ROMを0000h〜3FFFh(16kB)、RAMは固定域として4000h〜7FFFh(16kB)、バンク切り替え領域として8000h〜FFFFh(32kB)にしてみます。(スタック領域として使われている部分を切り替えちゃいますが….)
当初ROM領域は8kBで良いかと思っていたのですが、SBC8080データパックの機械語モニタ+BASICが8kBを超えていたので16kBにしました。

8000h以降はアドレスバスのA15が”H”レベルとなります。その信号と、別に作るバンクレジスタ2bitを合体させて、 628128型メモリーのアドレスバスA16、A15ピンに与えてやることでバンク切り替えしたいと思います。
バンク切り替えした時に切り替えたプログラムもどこかへ行ってしまうと厄介なので、16kBの固定RAM領域を作っておきました。

バンクレジスタの試作

前述のとおりバンクレジスタは2bitあれば良いので、当初はPPI(8255A)で作ることも考えたのですが8回路Dラッチ(74HC573)で行けるのでは?と考えてブレッドボードで回路を試作してLチカをやってみました。

回路図はこちら。

  • Z80/8080のI/O書き込み要求信号(IOWR)とI/Oアドレスデコーダ(この回路図では74HC138)の信号(I/Oアドレス40h)をAND回路であわせ双方が”L”レベル(負論理で”1″)の時にデータバスに出ている情報をラッチさせます。
  • 74HC573のラッチイネーブル(LE)端子は正論理(端子名にオーバーラインなし)なので、”H”レベルとするため 74HC04のNOT回路を通して反転させています。
  • 74HC573はCMOSゲートなのでLEDをそのままつないでいます。

[2018/8/11] 当初掲載した回路図のLEDの向きが逆だったので修正しました…orz

実装したブレッドボードの写真はこちらです。

プログラムはこんな感じで、いつものGrant’s BASICでOUT命令を並べてみました。
試作回路では74HC138でI/Oアドレス40hにデコードしたので、OUT &h40,xx という感じでバンク番号を出力する感じです。(今回はメモリーではなくLEDを光らせているだけですけど….)

10 REM 74HC573 LED BLINK
20 OUT &H40,0
30 GOSUB 1000
40 OUT &H40,1
50 GOSUB 1000
60 OUT &H40,2
70 GOSUB 1000
80 OUT &H40,3
90 GOSUB 1000
100 GOTO 10
1000 REM WAIT
1010 FOR I=1 TO 1000:NEXT
1020 RETURN

LEDが 1 (01) → 2 (10) → 3(11) と思った通りLEDが点灯しました。バンクレジスタの試作は成功です。
手持ち部品に74HC02(NORゲート)がなくて思ったほどコンパクトな回路にはなりませんでした….

次は、128kBメモリーのアドレスバスA16/A15を作ってあげるロジック回路を検討します。