ブログの練習

ブログを書く練習です。
最近はレトロな計算機(電卓、マイコン、パソコンなど)
に関することを書き始めました。

Intel 4004 (その15) 周辺回路を現代の部品で作ってみる(Teensy編)

2023-05-10 11:08:50 | マイコン(4004)
できるだけ当時の部品で作るという当初の目標は達成できたので、次は現代の部品を使ったらどうなるかを試してみました。候補としては、
(1)Teensy 4.1+4004
(2)EMUZ80+4004メザニンボード
(3)TangNano9K+4004
あたりを考えたのですが。まずはread4001(Intel 4004 (その5) Mask ROM 4001を読んでみる)で4001を読んだ実績があるTeensy4.1で試してみることにしました。

read4001のときは3.3V→15Vの変換はFETの2N7000を使っていたのですが、これでいいのか若干気になっていたので別の部品も探してみました。見つけたのがこちら。
CD40109B Low-to-High Voltage Level Shifter (datasheet)

実際の信号で2N7000と比べてみました。
上から、入力(3.3Vパルス)、40109、2N7000(4.7kプルアップ)です。(100ns/div)

40109は立ち下がりの遅延が2N7000の倍の100nsぐらいありますが、それ以外はかなり良い特性です。出力制御(OE)も備えているのでこれを採用することにしました。

この他に、CD4504B(Voltage-Level Shifter)も候補にあったのですが、全ての点で40109の方が勝っていたので不採用です。
上から、入力(3.3Vパルス)、40109、4504。(50ns/div)


次に15V→3.3Vです。4004のデータシートによると、HはVss-0.5~Vss(今回の場合は+14.5~15V)、LはVss-12~Vss-6.5V(+3~8.5V)です。実際の信号を観測してみると、Lは+3~+5Vぐらい。

read4001の時と同じように、1段目をVcc=15VのCMOSで受けて、2段目をVcc=3.3VのCMOSで受ければ良さそうです。1段目は閾値を高くするためにVcc=15Vにする必要があるので標準CMOS、2段目はVcc=3.3Vでいいので高速な74HC4049(入力耐圧は+15V)を使うことにしました。

クロックドライバの3.3V→15Vは秋月で売っているMicrochipのMCP1402(datasheet)を使ってみることにしました。最初は5.185MHzのクロック源(MCLK)を外部に用意して、ソフトで2相クロック(CLK1, CLK2)を生成するという構成を試したのですが、Teensyの内部カウンタ(600MHz)でわりと安定したMCLKまで作れてしまいました。

完成した回路図がこちら。


次にプログラムです。
速度が要求されるので、ポートレジスタ直叩きとかやる必要があるかなあ、面倒だなあと思っていたのですが、digitalWriteの速度を測ってみたところ驚愕な速さだったのでデータバスを1ビットづつ読み書きするというお子様的なプログラミングで済ませてしまいました。
こんな感じのコードで、
#define digitalWrite digitalWriteFast
  digitalWrite(DOUT0, data & bit(0));
  digitalWrite(DOUT1, data & bit(1));
  digitalWrite(DOUT2, data & bit(2));
  digitalWrite(DOUT3, data & bit(3));

この速度。Teensy4.1の性能恐るべしです。(これ5ns/divですよ)



プログラムはクロックを生成しながら4004の命令サイクルにあわせてバスを読み書きするだけなので特筆すべきことは無いかな。

Lチカが動きました。


回路図やプログラムはGitHubに置きました。
GitHub - ryomuk/Teensy-4001: Intel 4001 (MCS-4 mask ROM) emulator using Teensy 4.1

GitHub - ryomuk/Teensy-4001: Intel 4001 (MCS-4 mask ROM) emulator using Teensy 4.1

Intel 4001 (MCS-4 mask ROM) emulator using Teensy 4.1 - GitHub - ryomuk/Teensy-4001: Intel 4001 (MCS-4 mask ROM) emulator using Teensy 4.1

GitHub

 

コメント
  • X
  • Facebookでシェアする
  • はてなブックマークに追加する
  • LINEでシェアする

Intel 4004 (その14) メモリ64KB化とプリント基板作成

2023-04-12 13:32:02 | マイコン(4004)
8080エミュレータで言語処理系等まで走るようになると、4KBというメモリでは少し窮屈なので増やしてみることにしました。4KBのときは4289からのアドレス8bitに4002からのバンクアドレス4bitで12bitでしたが、バンクアドレスを8bitににして、256byte×256バンクの64KBにします。実際には256byteのうち2byteをメモリ読み込みルーチンに使われてしまうので、使える領域は254byte×256バンクで63.5KBです。
64K×4bit=256Kbitのメモリを使いたかったのですが、探しても売っているところを見つけられませんでした。ヤフオクで256K×4bit=1MbitのHM624256が2個560円で売られていたのでそれを使うことにしましたが、今考えると同じ1Mでも128Kx8bitのHM628128の方が格段に入手性が良いのでそちらにすれば良かったと思っています。DIP以外のパッケージで良ければ今でも秋月で同等品が入手できるようなので。
ブレッドボードで改造するのは面倒だったのと、そろそろ基板を作りたいと思っていたところなので基板を作ることにしました。10cm×10cmを超えると急激に高くなると思っていたのですが、JLCPCBだとかなり安く作れるというのもブレッドボードでの確認を省略する動機になりました。

基板の大きさは秋月のユニバーサル基板に合わせるといいかと思ったのですが、A基板(155mm×114mm)でもちょっと小さく、その倍だと大きすぎるので、mmでもインチでもキリがいい190.5mm×127.0mmにしました。
とりあえずこの大きさに載るかどうか確認するために適当に並べたのがこちら。

載ることは載りましたが配線がスパゲッティになりました。4002のポートから出ているLEDを一箇所にまとめるために結構配線が増えたのが主な原因。
配線を綺麗にすることを念頭において引き直したのがこちら。

あまり違いが無いようにも見えますが、だいぶ良くなったと思います。
実は、初版(rev2.0)を発注した後にいくつか間違いを見つけてしまい、しかも送料をケチってしまったせいでなかなか届かず、我慢できなくなって初版が到着する前に修正版(rev.2.1)を発注するということをしてしまいました。
で、昨日到着したrev.2.1がこちら。(rev.2.0は4日前に届いたのですがお蔵入りです。)

部品を載せたのが冒頭の写真です。ホワイトセラミックのC4289は先日入手したものです。運良く入手できましたが、4289は4004より入手困難になっているような気がします。
電源を入れてみたところ無事動作しました。新規設計部分の64KBのRAMもメモリテストプログラムで正常動作が確認できました。


ブレッドボード版と並べたのがこちら。半分ぐらいの面積になりました。


回路図やガーバーファイル一式をGitHubに置きました。製作に必要な情報は全て置いてあるので、部品さえあれば同じものが作れます。
GitHub - ryomuk/emu8080on4004: Intel 8080 Emulator on 4004 Evaluation Board

GitHub - ryomuk/emu8080on4004: Intel 8080 Emulator on 4004 Evaluation Board

Intel 8080 Emulator on 4004 Evaluation Board. Contribute to ryomuk/emu8080on4004 development by creating an account on GitHub.

GitHub

 


あと、先日Twitterで教えてもらって驚いたのですが、HACKADAYの記事になったようです。
The 4004 Upgrade You’ve Been Waiting For

The 4004 Upgrade You’ve Been Waiting For

You know how it is. You have an older computer, and you can’t run the latest software on it. Time to upgrade, right? Well, if you have been in this situati...

Hackaday

 


HACKADAY.IOのアカウントを作ったので、そちらにも書いてみようかと思っています。
コメント
  • X
  • Facebookでシェアする
  • はてなブックマークに追加する
  • LINEでシェアする

Intel 4004 (その13) 8080エミュレータを作ってみる

2023-03-22 11:22:20 | マイコン(4004)
電卓やVTLインタプリタを書いてみて、ずいぶん4004のアセンブラに慣れてきました。とはいえ、いろいろなものを4004のアセンブラで一から作るのは面倒です。8080のエミュレータを作ってしまえばモニターなり言語処理系なり、8080の膨大なソフトウェアを走らせることができるのではないかと思い、エミュレータを作ってみることにしました。CPUの動作なんて命令コードで分岐してレジスタの値を書き替えるだけなんだから1日か2日で作れるんじゃないかと高を括っていたのですが、意外に大変で、4004のモニターもメモリ読み書き周りを手直ししたり、8080のプログラム入力用にIntel HEXを読み込めるようにしたりという改造もあったので結局1週間ほどかかりました。
実験機の4004のプログラムに使えるROM領域は3.75KBあります、モニター周りの機能追加や、レジスタ操作、PUSH/POP、I/O、論理メモリ空間アクセス、等々のルーチンで2KB使ってしまうので、エミュレータ用に使えるメモリは1.75KBしかありません。
当初のもくろみでは、4004の間接ジャンプ命令で命令コード毎に分岐して分岐先に各命令の処理を書けば簡単だと思っていたのですが、さすがにそれでは無駄が多くてメモリが足りなくなるので、もう少し真面目にやることにしました。

8080の命令コード表を見ると、40H~BFHの128命令はかなり規則的な作りになっています。その外側もある程度は規則的なのですが、かなり雑多です。

01H~3FHとC0H~FFHをJIN命令(間接ジャンプ)で分岐テーブルを使って分岐させて命令毎の処理、40H~7FHはMOV命令なのでSRCレジスタとDSTレジスタをデコードしてMOVの共通ルーチン、80H~BFHは、SRCレジスタをデコードして、演算内容を分岐テーブルで分岐させて演算毎の共通ルーチンで処理、というような作りにしました。
MOV命令は01000000+DDD000+SSSという構造になっているので、SRCとDSTをデコードしてあとは共通ルーチンに任せるということです。

ちなみにHLT(=76H)のコードはMOV M, Mに相当するのですが、MOVのルーチンで判別してHLTの処理に飛ばしました。

いくつか実装をサボったものもあります。
まず、演算結果のbitの偶奇を示すPフラグです。ハードウェアで実装したら簡単そうですが、ソフトウェアで実装するのは結構コストがかかります。また、フラグの使用の有無にかかわらず演算ごとに計算するのはかなりの無駄です。このフラグを使ったプログラムは滅多に無いと思われるので実装するのをやめました。
次にDAA、10進数の補正命令です。4bit目のキャリーであるACフラグ(Auxiliary Carry, NECのマニュアルだとハーフキャリーやCY4と表記されていたりします。)を用意しておく必要があるのですが、現在の実装では面倒なのでサボりました。あと、割り込み関連のDI、EIも割り込み自体が無いので省略。(※2023/4/3追記, DAA命令に関する記述について修正しました。)
IN、OUTはシリアルポートへの入出力になっています。INでの入力は4004のソフトウェアUARTのGETCHARルーチンに飛ぶので、入力があるまで止まってしまうのですが、これを回避するにはハードウェア的な機能追加が必要なので今のところはあきらめています。(BASICで停止のためのCtrl-Cのチェックとかができないのでなんとかしたいです。)

意外に面倒だったのが論理演算です。4004にはAND, OR, XORなどの論理演算用の命令がありません。MCS-4 Assembly Language Programming Manualには4bitのANDルーチンの例(下記)が載っているのですが、ちょっと難解で理解できなかったので自前で書きました。


自前で書いたのがこちら。ループを使わずに1bitづつ調べているのでかなり長くなっています。

;;;---------------------------------------------------------------------------
;;; AND_R6_R7
;;; R6 = R6 & R7
;;;---------------------------------------------------------------------------
AND_R6_R7:
        CLB
        LD R7
        RAR
        JCN C, AND67_L1 ; jump if R7.bit0==1
        LD R6
        RAR
        CLC
        RAL
        XCH R6          ; R6.bit0=0
AND67_L1:        LD R7
        RAR
        RAR
        JCN C, AND67_L2 ; jump if R7.bit1==1
        LD R6
        RAR
        RAR
        CLC
        RAL
        RAL
        XCH R6          ; R6.bit1=0
AND67_L2:
        LD R7
        RAL
        RAL
        JCN C, AND67_L3 ; jump if R7.bit2==1
        LD R6
        RAL
        RAL
        CLC
        RAR
        RAR
        XCH R6          ; R6.bit2=0
AND67_L3:
        LD R7
        RAL
        JCN C, AND67_L4 ; jump if R7.bit3==1
        LD R6
        RAL
        CLC
        RAR
        XCH R6          ; R6.bit3=0
AND67_L4:
        BBL 0

これは4bitのレジスタの論理積なので、8bitのレジスタの演算には次のように2回呼ぶ必要があります。

;;;---------------------------------------------------------------------------
;;; AND_P1_P2
;;; P1 = P1 & P2
;;;---------------------------------------------------------------------------
AND_P1_P2:
        LD P1_LO
        XCH R6
        LD P2_LO
        XCH R7
        JMS AND_R6_R7
        LD R6
        XCH P1_LO

        LD P1_HI
        XCH R6
        LD P2_HI
        XCH R7
        JMS AND_R6_R7
        LD R6
        XCH P1_HI
        BBL 0

8080で1命令(ANA)で済む1バイトの論理積の計算にこれだけのコードが必要になります。ORとXORも同様です。メモリが本当に厳しくなったら工夫して短くするところですが、今回はなんとか足りたのでこの実装で済ませました。

一通り書けたところで、動作確認です。全ての命令について、ステップ実行させながらレジスタ、フラグ、PC、SP、メモリの内容が仕様通りに動いているかを確認します。自動のテストプログラムを書くという方法もありますが、そうするとテストプログラム自体のデバッグも必要になるという無間地獄に陥るのでテストプログラム自体は単純な命令の羅列にして、結果を目視で確認するという手段をとりました。テストはかなり効果的で山ほどバグが見つかりました。


全ての命令で一応期待通りの動きが確認できたので、次は大規模なプログラムを走らせてみます。
ソースが入手可能で改変も可能なPalo Alto Tiny BASIC を試してみることにしました。ソースはhttps://www.autometer.de/unix4fun/z80pack/ftp/altair/から入手。

Pフラグ、DAA命令が使われていないことを確認。端末への入出力は、IN 1、OUT 1でデータ、IN 0がデータ有無を示す制御フラグのようだったので、エミュレータ側のIN、OUT命令をそれ用に設定。
アセンブラの"SHR"を">>"に、"AND"を"&"に修正、スタックポインタとメモリ領域のアドレスを修正したらすんなりアセンブルできてHEXファイルが生成できました。
実機にロードして実行してみたところ、"OK"のプロンプトが出てくれました。PRINT 123+234も正常。
しかしPRINT文やLIST出力の1行ごとに入力待ちになって停止してしまいます。
Tiny BASICでは、Ctrl-Cで止めるために入力のチェックがあり、入力が無ければ通過するのですが、4004実験機はGETCHARは入力があるまでそこで止まってしまうのでした。このあたりはハードウェアの改修も必要になるので、とりあえずの対処として、Tiny BASIC側でコマンド入力時以外のIN数カ所をコメントアウトして済ませることにしました。無限ループ時に止める手段が無くなるのですが仕方ありません。
以上の対処で動くようになった動画がこちら。ちゃんと動いているのは感動ですが、速度は思っていた以上に遅く、マンデルブロ集合の計算はあきらめました。



ソースコードと実験機の回路図はGitHubに置きました。
GitHub - ryomuk/emu8080on4004: Intel 8080 Emulator on 4004 Evaluation Board

GitHub - ryomuk/emu8080on4004: Intel 8080 Emulator on 4004 Evaluation Board

Intel 8080 Emulator on 4004 Evaluation Board. Contribute to ryomuk/emu8080on4004 development by creating an account on GitHub.

GitHub

 
コメント
  • X
  • Facebookでシェアする
  • はてなブックマークに追加する
  • LINEでシェアする

Intel 4004 (その12) VTLインタプリタを作ってみる

2023-03-12 11:36:51 | マイコン(4004)

4004用のVTLインタプリタを書いてみました。当初はMITS_Altair_680_Very_Tiny_Language_VTL-2_Manual.PDFに載っている6800版のオリジナルのソースか、白石孝次氏による8080への移植版(「マイクロBASICインタプリタの製作」, 月刊ASCII, 1978年2月(エンサイクロペディアASCII vol.1収録))を参考にして移植ベースで作るつもりだったのですが、どちらもサブルーチンを多段に呼びまくりなコードで、PCのスタックが4段しかない(サブルーチンを3段までしか呼べない)4004では同じ構造のまま移植するのは無理そうだったので、多少参考にする程度でゼロから書くことにしました。
とはいえ、数式を評価するルーチンが再帰的な呼出しになり、データRAMにスタック領域を用意してそこにレジスタやPCを積めるような仕組みを作ることになったので、最終的には多段呼び出しも可能になったのですが。
とりあえず動けばいいと思って書いたもので、かなり汚いプログラムなのですが、せっかくなのでGitHubで公開しました。内部レジスタ(P0~P7)の使い方など、直した方がいい点が多々ありますが、下手にリファクタリングして動かなくなるのもいやなのでこれ以上手を加えるのはやめます。これを直すくらいなら、もう一度ゼロから書き直す方が良さそう。

GitHub - ryomuk/VTL4004: VTL Interpreter for 4004 Evaluation Board

GitHub - ryomuk/VTL4004: VTL Interpreter for 4004 Evaluation Board

VTL Interpreter for 4004 Evaluation Board. Contribute to ryomuk/VTL4004 development by creating an account on GitHub.

GitHub

 


プログラムを書くにあたり、いくつか準備をしました。まず1つ目は、前のブログ(Intel 4004 (その11) メモリ周りを改築する)に書いたメモリの拡張に関することです。物理メモリは00H~0FDHの254byte x 16バンクという、256byteごとに2byteの読み出しルーチンが書かれていて使いにくい空間なので、12bitのアドレスBA98.7654.3210を、BANK=3210、ADD=7654.BA98に変換してアクセスするルーチンを用意して、000H~0FDFHの論理空間に見せるようにしました。vtl.asmの LD_P1_PM12REG16P0, LD_PM12REG16P0_P1 がそのルーチンです。メモリ1byte読み出すのに30命令近く、実行時間で約300μ秒かかるということになってしまいましたが、これでメモリがかなり使い易くなりました。このメモリにはVTLのプログラムテキストを格納します。
プログラム領域のメモリはアクセスが遅いので、演算用の変数はデータレジスタに格納します。4002は4bit x 16キャラクターのレジスタを4つ(計32 byte)持っており、RAM0~3で計128 byteあります。
RAM0とRAM1にA~Zとシステム変数、RAM2にシステム変数や作業用変数、RAM3をスタック領域として使用することにしました。
当初のハードウェアでは入手性やコストの観点から4002-1(1個$8)を4つ使って、CMRAM0とCMRAM1に2個づつ継げていたのですが、4002-1を2つと4002-2(1個$20)を2つを同じライン(CMRAM0)に接続する方がCMRAMのラインを0に固定でき、アクセス毎に発生するDCL命令を省略できるのでそのようにしました。
eBayで注文したところ、最初4002-2ではなく4002-1が送られてきたのですが、店に連絡したらすぐに4002-2を再送してくれて返品も不要という対応をしてもらえて事なきを得ました。ICもちゃんとした新品で動作も良好。HIFIICというストアは信頼できそうです。
RAM3のスタック領域に内部レジスタをPUSH/POPするためルーチンと、変数をPUSH/POPするルーチンを用意しました。8bit CPUでは1命令で実行できるPUSH/POPですが、これにも30命令以上かかります。しかもレジスタ毎に別のルーチンをマクロで展開して作ったため、メモリもかなり食ってしまいました。このあたりは改善の余地がありそうです。
スタックを利用して返り先をスタックに積むようにすれば3段しか使えないJMSの代わりに、JUN命令でサブルーチンが実現できます。返るときにはvtl.asmのRETURN_P2を呼びます。12bitのアドレスに間接ジャンプする命令は無いので、8bitのラベルを使って間接ジャンプで飛んだ先で12bitにジャンプするという2段ジャンプのリターンになっています。
以上が主な準備です。

実装したインタプリタの仕様の表をここに書こうと思ったのですが、このブログで表を書く方法がわからなかったのでやめました。GitHubのREADME.mdをご覧下さい。表に従って順に解説していきます。
プログラムサイズはモニターと合わせて約3.5KBになりました。8bit CPU版に比べると3~4倍でしょうか。8bitの値を操作するのにも複数の命令が必要なので仕方ありません。
オリジナルのVTLの変数の値域は0~65535ですが、マンデルブロ集合を計算したいので2の補数で-32768~32767とすることにしました。加算と減算ルーチンは変更無しで使えます。除算は正負を判断して絶対値の除算を行い符号を補正するという計算になります。乗算も除算と同様のことをやる必要があるかと思ったのですが、下位16bitだけ使うのであれば何もしなくていいようで、正数の乗算ルーチンのまま変更無しで動きました。これに伴い、行番号が1~32766となっています。
16進の数値が扱える方が何かとうれしいので、0で始まる数値は16進数として扱えるようにしました。出力も??=で16進4桁、?$=で16進2桁で表示するようにしました。
通常のPRINT(?=e, ?=STR)、改行抑止(;)、入力(A=?)、文字入出力(A=$, $=e)、GOTO(#=)、GOSUB(!=)、LIST(0)等々はオリジナルのVTLと同じです。
オリジナルのVTLではIF文は無く、#=(A=B)*100のようにGOTO先の行番号を比較演算子の結果との乗算で代用するという手法が使われていたようなのですが、乗算は計算コストが大きいのでIF文(;=)を実装しました。;=0 の後は次の行にスキップするのでコメント文の代用に使えます。なのでコメント文の実装はサボりました。
演算子に優先順位は無く、左から右に評価しますが、括弧内を先に評価する機能はさすがに実装しました。上の方に書いたJUN命令とスタックを使ったサブルーチンコールで数式の値計算(EVAL_EXPRESSION_PMINDEX_REG16P1)と因子の値計算(GETFACTOR_PMINDEX_REG16P1)の再帰呼出しをしています。
行の編集機能(挿入、削除等)はサボりました。真面目に実装すると結構メモリを食いそうなので。最初から行番号昇順のプログラムが入力されることを前提にします。

あと、配列とPEEK、POKEあたりを実装したかったのですが、マンデルブロ集合の計算に使わないので後回しになっています。

こちらが動作の様子です。


約2週間ほどかかってどうにか動くものが完成し、目標にしていたマンデルブロ集合の計算が出来ました。時間は2時間54分13秒。今回は速度は頑張りどころではないので完走できたことで満足です。

プログラムはこんな感じ。基本的に以前にF8用に書いた整数BASIC用のプログラムと同じです。不等号">"がVTLでは">="の意味であるということらしいので、比較文の数値がちょっと違います。

10 F=50
20 Y=-12
30 X=-39
40 C=X*229/100
50 D=Y*416/100
60 A=C
70 B=D
80 I=0
90 Q=B/F S=B-(Q*F)
100 T=((A*A)-(B*B))/F+C
110 B=2*((A*Q)+(A*S/F))+D
120 A=T
130 P=A/F Q=B/F
140 ;=((P*P)+(Q*Q))>5 #=180
150 I=I+1 ;=I<16 #=90
160 ?=" ";
170 #=200
180 ;=I>10 I=I+7
190 $=48+I
200 ;=X<39 X=X+1 #=40
210 ?=""
220 ;=Y<12 Y=Y+1 #=30


消費電力はシステム全体(表示用VFDは除く)で270mA前後とそれほど多くありませんでした。

発熱も4002が50度ぐらいになっている程度、CPUはあまり発熱していませんね。


最後に、試しに手動でコンパイルして変数アクセスや演算ルーチンを直接叩くようにして実行した結果です。55分56秒。実行時間は約1/3ぐらいに短縮しました。1桁くらい速くなるかと思っていたのですが、思ったほどは速くなりませんでした。構文解析や制御よりも演算自体に時間がかかっているということですね。


コメント
  • X
  • Facebookでシェアする
  • はてなブックマークに追加する
  • LINEでシェアする

Intel 4004 (その11) メモリ周りを改築する

2023-02-25 13:22:41 | マイコン(4004)
VTLを実装しようとプログラムを書き始めたのですが、メモリが足りない気がしてきました。もともと、6800や8080で768byte~1KBというようなプログラムなので、8bitの比較にすら数バイトかかる4004では2~3KBぐらいは欲しいところです。
軽微な(とはいっても数日かかりましたが)修正でメモリを増やす余地があることはわかっていたので、先にそちらをやることにしました。急がば回れです。
先日の記事(Intel 4004 (その9) メモリ領域へのアクセス)に書いたように、プログラムメモリのRAM領域が思ったように使えていませんでした。原因は、メモリ書き込み命令(WPM)が256byteのページ内に限定されていることです。
RAM領域にバンク切り替えを実装して、空いた空間をROM領域にするための改修を行いました。
まずは予備実験。4002のポートから3bit取り出して6116のA8~10に継げてみました。4004のポートはデータシートによるとH("0")が+5V、L("1")が-1.5~-7V。実測してみると-4Vぐらいなので、クランプ用ダイオード1N4148と電流制限用の10kΩの抵抗を付けました。1N4148のVfが実測で0.6Vぐらいあって、Lが-0.6Vぐらいになります。6116の定格がmin-0.5Vなのでちょと気になったのですが、このぐらいなら大丈夫なようでした。あと、"0"、"1"のHLが逆ですがRAMへのアドレス入力なのでまあいいでしょう。

動作しているところの写真を撮り忘れましたが、すんなり256byte x 8バンクで動作しました。
これでAddress=F00H~FFDH、BANK=0~7の物理RAM領域が出来たのですが、BANK=0~Fにできると、アドレスのbitの順番を入れ替えて000~FD0Hの論理的なメモリ領域を作り易いです。(実は、そのようなことをVTLの移植中に気がついたので、メモリ周りの改修を始めた次第です。)
6116(2048x8bit)はアドレスバスが11bitしかないので、16バンクにするにはもう1組増設する必要があります。一方、4289との接続が4bitなので8bit幅の半分を使わないというもったいない使い方をしています。
調べてみると、HM6268という4096 x 4bitのメモリがあることがわかりました。アドレス12bit、データ4bitなので、これ2つに置き替えれば無駄無く綺麗に作れそうです。

良く見ると~OEがありません。I/OをHi-Zにするのは~WEで済ませるようです。そんなので大丈夫かなあと不安になったのですが無いものは仕方ありません。大丈夫なのでしょう。
アドレスバスの順番が6116とだいぶ違うのですが、ブレッドボードの既存の配線を利用するためにバスは順不同で継げました。バンク指定も下位bitのA0~3とかになっています。まあ、RAM (=Random Access Memory)なので動作に問題は無いですが、気持ちが悪いので基板を作るときに修正するつもり。今の接続はこんな感じです。

次はROM領域の拡大。C3(アドレスのMSB)をチップセレクトに使って、000H~7FFHをROM、800H~FFFHがRAMにしていたのを、000H~EFFHをROM、F00H~FFFHをRAMに変更します。
2716(or 28C16)では容量が足りなくなるので2764/256、28C64/C256を使うことにしました。容量的には2732で十分なのですが、部品の入手性(特にEEPROMの)を考えると64や256の方が良さそうだったので28pin対応にしました。
ROM周辺の回路図はこんな感じ。ROMの1番ピンが部品によって違っていて、
2764/256はVpp(+5V)、28C64はBUSY出力、28C64BはNC、28C256はA14
なのですが、4KBしか使わないのでデフォルトでプルダウン、2764/256はVpp=5Vにジャンパ接続します。27番ピン27256だとA14、その他は~WEか~PGMなので、デフォルトでプルアップ、27256のときだけGNDに落とすようにします。

~CS_ROMと~CS_RAMの生成でインバーターが1個だけ足りなくなってしまったのでLS04を1個追加。場所が無いので小さい基板で増築。ついでなのでLS02のNORをインバーターに使っていたのをLS04に付け替えました。
メモリ周辺の回路全体はこんな感じになりました。

これに従ってブレッドボード上を改築したのが冒頭の画像です。
動くかどうか心配だったのですが、意外にもすんなり動きました。簡易にテストするプログラムを書いて確認。ROM領域は256byte毎の15ページにプログラムを配置して実行。RAM領域はバンクを切り替えながら同じアドレスに違う値を書き込んで、ちゃんと正しい値が(上書きされずに)書かれていることを確認をしました。この画像は16byte×16バンクを表示したもので、全体ではこの16倍のRAMがあります。

3.75KBのROM領域、4KBのRAM領域が確保できました。ここのRAMは主に入力バッファやVTLのプログラム領域(VTL言語で書かれたプログラムを格納する領域という意味です)とし、変数や演算用のメモリは4002の方のデータ領域(レジスタ)を使って作る予定です。
コメント
  • X
  • Facebookでシェアする
  • はてなブックマークに追加する
  • LINEでシェアする