PC-6001用の32KByte ROMカードを作ってみる

[2015/02/01] その後の調査で分かったことを追記しました

16KByte ROMカード編からの続きです。ちょっと変化球です。話を単純にするため、初代機に限定します。

16KByte ROMカードを作る事でPC-6001のROM領域を全て埋めてしまったので、これ以上、メモリを増やすにはバンク切り替えをすることになりますが、それは他の方が実践されているので、別の方法を試してみます。

RAM領域を使う

16KByte ROMカードを作った時点でのメモリ構成はこうなりました。

この時点で残っているのは外部RAM領域です。ここがRAMに割り当てられているのはハード的な理由だけでなく、BASIC(の各命令)もRAM領域であることを前提としているからです。

ハード的な理由の一つは、ここがVRAMに割り当てられるからです。PC-6001のグラフィックチップ(MC6847)は、VRAMをチップ内に持っていません。外部に接続されたRAMを利用し、PC-6001では、その領域をZ80のメモリ空間と共有しています。また、MC6847はページ切り替え機能を持ちませんが、PC-6001では、MC6847に参照させるメモリアドレスを変更することが出来るようになっています。

指定できるVRAMの先頭アドレスは8000H,A000H,C000H,E000Hの4つです。RAMを増設していないPC-6001(RAM16K)では、C000HとE000Hの2つのページを持てるということになり、BASICでは、C000HからのVRAMをページ1、E000Hからをページ2と呼んでいます。これだとVRAMがRAM領域を占めていて、プログラムを置く領域が無いように見えるのですが、MC6847のVRAMは最大でも6KByteちょっとを使うだけでVRAM割り当て分の後ろの方は空いていますから、BASICではそこを利用しています。また、BASICのページ1ではスクリーンモードをテキストモードに限定することでVRAM使用量を減らし、プログラム用の領域を確保しています。

PC-6001にRAMを増設すると、8000HとA000Hからの領域を使えるようになるので、BASICでは、その領域をページ3、ページ4に割り当てています。

このように、8000HからBFFFHをRAMにしなければ画面数を増やせないのですが、ページ数にこだわらず、また、BASICを使わないのであれば、この領域がRAMである必要は無いわけです。よしじゃあROMにしましょう。

注意)PC-6001のメモリアクセスはRAM領域とROM領域で異なります。ROM領域の読込みで(書込みもですが)WAITが1つ入るため、同じプログラムでもRAMで実行するのとROMで実行するのとでは処理速度が変わってきます。また、RAM領域には読み書き速度の足りているメモリを使用しなければならないということです。

メモリ構成

4000HからBFFFHをフラッシュメモリ[EN29F002T]に割り当てるのですが、これまでのようなフラッシュメモリの先頭から使うのはやめて、PC-6001とフラッシュメモリのアドレスを揃えるようにしました。A0-A15を一致させるということです。こうした理由は後々の伏線的なものです。最初からフラッシュメモリを贅沢に使っているので、どこをどう使っても一緒ですし。

RAM領域をROMに割り当てるとして、D0-D7/A0-A15はそのまま接続し、これまで通り、2つの外部ROM領域はCS2/CS3信号で判断できますが、外部RAM領域にも対応させる必要があります。A12-A15とMREQとRDを使うのがセオリーですが、PC-6001ではRAM領域にDRAMを使うための信号であるRAS/CAS/DRDが外部に出ているので、これを使ってみます。

追記:2015/01/31 回路図差し替えました。RAS2/EXCASが共にLOWの時がDRAMアクセスのタイミングとしなければならないので74LS32が必要になります

DRAMアクセス用の信号である、RAS2とEXCASのActive状態を判定して、それとCS2とCS3でフラッシュメモリの選択(CE)をします。フラッシュメモリのリード(OE)は、DRAMのRAS/EXCASとDRDを使うように変更します。DRAMのRASとEXCASとDRDが全てLOWの時にメモリアクセスが発生します。

[ここから追記:2015/02/01] DRAMへのアクセスは、RAS2/EXCASがLOWとなった後にDRAMに繋がれているWEの状態で入出力が決まりますが、PC-6001では、RAS2/EXCASでアドレス指定した後に、DRD2がLOWとなったタイミングでデータを読み出すようになっています。内部DRAMと外部DRAMでは、DRD/DRD2とで信号が別になっているため、DRD2を見るだけで外部DRAMアクセスが発生したことを判別できることになります。つまり、回路は次のようにシンプルになるはずです。初代PC-6001で動作確認しました。mkII以降は未確認です。もちろん、ROMではなくDRAMもしくはSRAMを使う場合にはRAS/EXCASを使わなければなりません。

RAM領域をROMとして使えるか試す

PC-6001初代機に差し込んでみたところ、フラッシュメモリの内容を読み込めました。PC-6001は起動時に増設RAM領域に対してテスト用のデータを書き込んで、同じ値が読み込めるかどうかでメモリ増設されているかどうかを判定していますから、RAM領域をROM化してもBASIC起動時はRAM 16KBのままです。

実験用に、Windows上のPC-6001エミュレータでゲームを起動してVRAMの内容をファイルに落とし、それをフラッシュメモリの8000Hに書き込んでから、PC-6001を起動して下記のBASICプログラムを実行します。

SCREEN命令を使って、画面をページ2のVRAMであるE000Hに切り換えてから、フラッシュメモリの8000Hからの画像データをVRAMに1バイト単位で転送するというものです。結果は、

ROM領域として読み込み出来ているようです。

ところで、フラッシュメモリの8000Hは、PC-6001の8000Hに割り当てられているわけで、その領域はビデオチップのVRAM領域として指定できます。VRAM先頭アドレスの指定方法は、I/OポートのB0Hを使います。

76543210
未使用CMTリレーVRAM addrタイマ割込
0:OFF,1:ON00:C000H
01:E000H
10:8000H
11:A000H
0:ON,1:OFF

8000HをVRAM先頭にするには、I/OのB0HにF4Hを書き込めばいいので、OUT命令を使ってみると...

ダメでしたー。原因は分かりません、というか、調べてません。写真のような模様がずっと表示されているのではなく、画面が常に変化しているので、読み込みが安定してないのかな...。 ビデオチップがRAMにアクセスする方法はZ80のメモリアクセスよりも速いので、フラッシュメモリのアクセスタイムが足りないか、そもそも読み込み方法自体が違うのだと思います。よくわかりません。 もっとも、この方法で表示できたとしても、1枚絵が瞬間的に表示されるというメリットがあるだけで、VRAMの使用量が多すぎて実用性は低いですね。

カセットポンで1枚絵が表示される起動プログラムはこんな感じで。


	ORG	$4000

	DB	'A'
	DB	'B'

	DW	START

START:
	; 画面出力アドレス(E000) / timer int off
	ld	a,$f3
	out	($b0),a

	ld	hl,$8000
	ld	de,$e000
	ld	bc,$19ff
	ldir

$$loop1:
	jr	$$loop1

[追記:2015/02/01] フラッシュメモリをVRAMアドレスに指定しても正しく表示されない原因をP6つくろうブログのえすびさんにご協力頂いて調べてみました。

まず、VDGが外部DRAMにアクセスして画面表示をする際はZ80のA14/A15が拡張バス側に出てこないそうです。当初、A14/A15が共にHIGHになると伺いました。つまり、VDGが8000HにアクセスしようとするとフラッシュメモリのC000Hにアクセスしてしまうことになります。PC-6001専用の拡張16KRAMを使い、そこをVRAMとする場合には、指定できるアドレスが8000HかA000Hで、それが拡張RAM側の0000Hか2000Hに割り当てられるので、拡張RAM側ではA14/A15を使ってアクセスしないのです。

であれば、フラッシュメモリのC000Hに画像データを配置し、VRAMアドレスに8000Hを指定すると、VDGの描画処理時はA15/A14が共に1となるのでフラッシュメモリのC000Hからの内容を表示するはずなのですが、残念ながらうまくいきませんでした。[参考用動画:cap00.MP4]

当初、内蔵RAMのC000Hからのデータと衝突しているのかと思ったのですが、その後、色々な組合せでフラッシュメモリに書き込みをしてみところ、フラッシュメモリの0000H,4000H,8000H,C000Hからのアドレスに同じ画像データを配置しておくと、フラッシュメモリ上の画像データを直接VDGに読み込ませることが出来ました。ここから推測するに、VDGが拡張RAM側からデータを読み取る時は、A14/A15が00,01,10,11のいずれかの組合せで出力されているように思えます。(あとは、私の作った基板の問題かもしれませんが、そこまで追試していません)

A14/A15の変化の原因を調べて回路に反映できたとしても、1枚絵を瞬間的に表示できるくらいの実用性しかありませんから、調査はここで打ち切りました。フラッシュメモリではなくSRAMを使って、カートリッジ側にCPUを持たせてSRAMを書き換え、描画はPC-6001内部のVDGにまかせる・・・といった遊び方をするのであれば、「VDGが外部RAMにアクセスする時はA14/A15は参考にならない」という情報は役に立つかも知れません。