PASOPIA7エミュレータを作ろう日記。(別名、次はMULTI8だ日記) へっぽこプログラマは日々こんなこと考えながらエミュ開発してます(笑) 2004/10/4 EmuZ-2500の再実装も一段落ということで、実機を確保していたPASOPIA7の エミュレータ開発を開始します。 アーキテクチャは非常に奇怪で、何でこんな設計したんだろうと頭を捻る ところもありますが、MZ-2500のように複雑怪奇という訳でもなく。 まあ、比較的簡単に実装できるのではないかと思います。 設計自体はEmuZ-2500の再実装で培ったものを踏襲する予定です。 #実機代理落札、多謝>Moliceさん #書籍資料貸出、多謝>めがきらさん #Jayさん@InfoNESも狙ってたネタみたいなんで、ちと心苦しくもあり。 手始めに、ROMの吸出しから。 メモリ上にイメージを展開して、それをBSAVE #-1でデータレコーダに出力。 実際はデータレコーダのケーブルをPCのMICに直結して、直接録音。 録音したwavを変換してバイナリデータを取り出します。 BASIC上からはメモリマップは弄れないので、適当なマシン語のプログラムを 作成して、それをCALLすることでコピーします。 PUSH AF // メモリマップ取得 IN A, 22h AND A, 03h PUSH AF // メモリマップ変更 OR A, 01H // BASIC ROMの場合は、AND A, 02H OUT 3Ch, A // (src)のデータを(dst)にコピー LD A, (src) LD (dst), A // メモリマップ復帰 POP AF OUT 3Ch, A POP AF RET マシン語はこんな感じで、メモリマップを変更して1byte取得して、 メモリマップ復帰。 これを256*16回繰り返して、1回辺り4kbytesをe100-f100にコピーします。 100 data &hf5, &hdb, &h22, &he6, &h03, &hf5, &hf6, &h01 110 data &hd3, &h3c, &h3a, &h00, &h00, &h32, &h00, &h00 120 data &hf1, &hd3, &h3c, &hf1, &hc9 130 clear ,&hdfff 140 for a=&he000 to &he014 150 read d:poke a,d 160 next a 170 sum=0 180 for u=0 to &hf 190 print u 200 poke &he00c,&h40+u // 40,50,60,70 210 poke &he00f,&he1+u 220 for l=0 to &hff 230 poke &he00b,l 240 poke &he00e,l 250 a=&he000:call a 260 sum=sum+peek(&he100+u*256+l) 270 sum=sum and &hff 280 next l 290 next u 300 print sum BASIC ROMを吸い出す場合は、以下の個所を修正。 100 data &hf5, &hdb, &h22, &he6, &h03, &hf5, &he6, &h02 200 poke &he00c,&h00+u // 00,10,20,30,40,50,60,70 後は bsave #-1,"name",&he100,&h100 で出力します。 PC側は、PetitRecを使用して、48khz/8bit/monoで録音。 wavの変換の仕方。 データとしては、矩形波の波長で0/1を表現しています。(1200hz=0, 2400hz=1) 1byteのデータは、0bbbbbbbb1という形で送信します。 これに従って変換して、ヘッダと末尾を削ってやるだけです。 たごさんがPHC-25のROM吸出しに同じ方法を使用して、データ化けが酷くて 大変だったと書かれていましたので心配でしたが、一発でチェックサムの 合うデータが取れてしまって、ちと驚き。 漢字ROMも同じ要領(I/Oの叩き方は違いますが)で吸い出せますが、 すぐに使う訳でもないので、取り合えずペンディングです。 配列情報を用意して、Windowsのフォントから互換ROMを生成するツールを でっちあげようかなと。 キャラクタジェネレータROMについては、CPUに繋がっていないため、ソフト的には 吸出し不可。 暫定的に、FM-7用のフリーROMを流用して使用することにしますが、ひらがな、 カタカナの違いは何とかしないといけないですね。 これで、BIOS.ROM(16K), BASIC.ROM(32K), FONT.ROM(2K)の生成が完了。 楽がきのように別途ハードを作成しなくていいのは楽でいいですね。 2004/10/5 ソフト側の実装を開始。 developフォルダに、新たにpasopia7フォルダを掘る喜びを感じつつ、放置プレイ かましてるmz5500フォルダさん、御免よう。 基本的には再実装版のEmuZ-2500をベースにします。 アイコンは、例によって天丸さん御謹製アイコン集より。 メモリ管理部。 BIOS, BASIC ROM, VRAM, RAMのバンク切り替えの優先順位が怪しげだけど、 取り合えず実装しておきます。 VRAMがマッピングされて、テキストVRAMが選択されている場合は、同時に アトリビュートデータの読書きも行う。(アトリビュートの直接アクセス不可) VRAMがマッピングされて、パレット読書きが指定されている場合は、パレットの 読書きも行う。(書き込みのみ?) VRAMのアトリビュートの書き込みとかパレット周りとかで、CRTCとメモリの処理が 絡み合っているので、いっそ統合してしまった方がいいのだろうかと思案中。 crtc->draw_screen();ではなくmemory->draw_screen();と記述するのが美しく ないのが嫌だけど、クラス間のデータのやり取りを省けるから実装自体はすっきり するんだよなあ・・・。 サウンド。 SN76489AN自体はEmu5とかEmuGakiで実装済みなので、これを流用。レジスタの リセット部でボリュームがmaxになるというバグを発見したので潰しておく。 また、仕様が判らなくて放置していたノイズ生成部を、MESSを参考に実装。 この辺りの修正は、後でEmu5やEmuGakiに反映させないと。 で、PASOPIA-7では2チップ使用しているので、チップの部分だけ分離して 別クラス化。これをsoundクラス内で2つ生成して使用することにします。 I/O管理クラス。 MIOが立っていると、一時的にI/Oの全空間がRAMにマッピングされるという 謎機能がある以外は、EmuZ-2500と変わりなしです。 Z80CTC。 Emu5で実装したものを流用。 クロック入力が4mhzと高速でイベント駆動が厳しいため、16クロックおきに 纏めて処理をするようにしておきます。 タイミングの問題が出たら、その時にあらためて考えるということで。 ch.1の出力がbeepの波形になるので、soundクラスへ出力。 CPUと同じクロックで駆動しますので、usecではなくclockでイベントを登録 できるようにvm側を拡張しておきました。 キーボード&Z80PIO。 EmuZ-2500と、キーマトリックス以外は全く同じ。 取り合えず、常にキーを押していない状態を返すように仮実装。 2004/10/6 CRTC。 結局メモリとは分けることにしました。 画面生成については、大きく分けるとテキストモードかファイングラフィック モードか、またワイド表示かノーマル表示か、で合計4通り。 更に、テキスト色については単色でレジスターの値を使用するか、各文字毎に アトリビュートの値を使用するか、で処理が分かれます。 greenのプレーンがテキストと兼用で、どちらとして扱うかをレジスターか アトリビュートで選択する、など奇怪な仕様ですが、実装が困難なほど 複雑という訳でもなく、意外とあっさり実装が完了する。 テキストの表示ページの選択は、テキストVRAMのアドレスの下位3bitの ラスターアドレスで指定すればいいのかな? ここまで実装したところ、"How many disk drives(0-4)? _" が表示される ところまでは来ました。 大抵の部品が再利用できたこともありますが、3日とは思いの外に順調です。 2004/10/7 キーボード周り。 Z80PIOのポートAの出力をb0-b3, b4-b6に分けて、b[0-3]とb[4-6]のNANDを スキャンラインの指定に使用。アクティブローなので、双方がHのラインが 選択されます。 こうすると、7fを指定すると全ラインが選択されますので、何か1つでも キーが押されているかどうかの判定ができることに。 この辺りを実装したところ、取り合えずキー入力が可能になりました。 BASIC上でプログラムを実行することもできますが、VRAM操作がうまく いっていないらしく、文字が欠落したりスクロールから漏れたりと、 まだ問題も残っています。 漢字ROM自動生成について。 DIBSectionを作成して、そこに定義ファイルから読み込んだ文字を表示 (全角文字、または半角文字*2)する。 で、パターンを読み取って、バイナリファイルに出力するだけ。 プログラムを作成するのは簡単だけど、文字配列の定義ファイルを作成するのは ちょっと骨が折れそうです。 2004/10/8 現在出張先のビジネスホテルです。 画面消去が上手くいかない件。 BIOSを逆アセンブルして読んでみても、少なくともテキストモードでは vramに何かを書き込むような処理が見当たりません。 で、I/Oのアクセスログを見ると、0ehのbit2を立てて、22hに10hを出力する という謎の操作が。 この処理でvram消去をするようにしたところ、無事画面が消えるように なりました。多分実機では、画面描画時に一緒にRAMを消すようになって いるのでしょう。 漢字ROMの生成について。 プログラムの作成と定義ファイルを作成。 これは面倒というだけで難しい訳でもなし。 sigmarion3版の仮作成。 winmain内の実装はこれまでの使いまわしなので、プロジェクトを作成して ビルドすればそれで終わり。 しかし、2fpsとは速度でないなあ。Z80CTCが重過ぎるのは判ってるんだけど、 4MHz駆動じゃ仕方がない。 2004/10/10-12 10/10は虎菊コレクションの整理に参加してきました。 で、今後のネタの資料として、MZ-3500とかPASOPIA 700とかMULTI-8とか FP-1100とか借りてきてみたり。 これから1〜2年分のネタです、乞うご期待。 と今後のことの前に、目先のPASOPIA 7を。 PAC2スロット。 ここに刺さるデバイスの基底クラスを定義して、各々その派生クラスとして 実装してやります。 そして、PAC2クラスに基底クラスのポインタの配列をつくってやって、 アクセス時はこの配列経由で行ってやります。 …要するに、I/O周りの管理と同じやね。 漢字ROMパックとRAMパックを先行して実装。 RAMパックについては多分動作しているけど、初期化しないと使えない模様。 初期化プログラムは、所有していない本体添付のテープの中に入っているので、 ちょっと手が出せない状態です。 まだまだ未実装な箇所が多いですが、そこそこ安定動作するようになって きましたので、ここで一度公開しておきます。 2004/10/13 本日はディスク吸出しとテープの録音作業。 5インチドライブを接続したマシンにwin98seをインストールするのに手間取り ましたが、手持ちのディスクは一通りイメージ化できたのでよし。 後は細かいところ。 テキストの反転、点滅をする処理で、単色テキストであるかどうかの判定が 間違っていたのを修正。 バックスペースを押しても反応しないのが寂しいので、DELキーとして機能 するように拡張する。つい押してしまうんですよねえ。 PSGのクロックがm5のままになっていたのを修正。 Z80CTCのタイマーモードとカウンタモードが一部混乱していたのを修正。 2004/10/14 ディスクイメージが出来たら対応したいのが人情というもの。 という訳で、同じuPD765Aを使用しているM88のソースを参考というか丸写しと いうか、とにかくディスク周りの実装を始めました。 D88イメージの操作はEmuZ-2500用に作成したものをそのまま使えるように、 またイベント管理周りとか、多少修正しています。 後は、変数名とか関数名とかの命名規則をこちらに併せて置き換えとか。 2004/10/15 コンパイルが通るようになったので実験。 うーん、何か起動しない。 FDCアクセスのログを取ってみたところ、sence interrupt statusのリザルト フェーズに入ったところで、ステータスレジスタを延々読み続けてます。 BIOSを逆アセンブルして調べてみたところ、どうも0xc0が返ってくるのを 待っている? リザルトフェーズなのにCBが立たないというのも変ですが、取り合えず 修正したところ、先に進みました。 次、FILESを取ったらエラーが発生。 1セクタ読んで、次のセクターを読み始めて、何バイトか読んだところで 処理を中断してしまってます。 んー…あ、TC ON/OFFのアドレス間違ってるのか。 まあ他にも細かい問題ありましたが、主にこの2つを修正したら、無事に 読み込めるようになりました。 実機の元のオーナの方がディスクをメインに使用されていたため、 ソフト類も全部ディスクだったんですが、これで試せますね。 取り合えず、ゲームから。 ALPHOS、画面化けがありますけど、一応遊べますね。 ジョイスティックの対応をしたら、先に画面周りの修正やろうかなあ。 2004/10/17-18 土曜は吸出し環境の再構築で潰れ、日曜は夕方まで寝てました。 ああ、駄目人間。 で、友人と飯食ってから作業開始。 まず、ALPHOSの画面化けの件。 実機で動かしてみると、タイトル画面は背景が黒。 エミュレータ上だと青画面が消去されずに残ってしまっています。 多分画面消去絡みの問題だろうと当りをつけて、I/Oのログを取ってみても さっぱり判りません。 で、VRAMのバンクセレクト関係かと思ってログを取ってみると、0x75と メモリプレーンとデータプレーンで異なる値を出力しているところがあります。 ここで仮説。 メモリプレーンのbitが立つと、VRAMのCS,WE,REの各信号がCRTCの制御を 離れてCPUに接続される。 →CPUからVRAMに対して書き込みが行われる。 書き込まれる値は、データプレーンのbitが立つと、VRAMのデータバスと CPUのデータバスが接続されて、CPUから書き込まれた値が出力される。 →bitが立っていないときは、プルアップされて0xffが書き込まれる。 で、このように実装してみたところ、期待通りに動作しました。 MENUP7の背景も、ファイル名のところが赤くなるなど正しくなっています。 倉庫番も、VRAMからの読み込みが正しく出るようになったのか、壁に めり込むことがなくなったようです。 ALPHOSをジョイスティックでプレイしたくなったので、PACK SLOT2の ジョイスティックI/Fを実装。 雛形自体は既に実装してあったので、後は値を入れてやるだけ。 実装できたので実験…ALPHOS、ジョイスティック未対応なのねorz 標準で添付しているフォントROM、最後のほうの市町村区は要らないので 削ってやる。 書き忘れてましたけど、フォントの元はアポロさんのFM7用互換ROMです。 テキスト表示周り。 表示するページの選択処理が、以前のデバッグのときにコメントアウトした ままになっていたのを修正しました。何やってんの。>俺 PPC2002版はどうしようかなあ。 需要ないみたいだし、その割りに不可解な不具合多発で工数の無駄使いだし。 ちょっと様子見です。 2004/10/29-30 ちょっと気力なくしてお休みしてました。 暫く休んでて、やる気が出てきたので作業再開です。 高校時代の友人の結婚式に参列するため、名古屋行きの新幹線で開発してます。 KNOCKNなどで画面が消えてしまう件。 以前、I/Oの0eh, 22hに怪しげな出力をしているのを画面消去ではないかと 睨んで実装していたのですが、実はそうではなかったようです。 この辺の実装を削除したら、さっくり解決しました。 大貧民についても画面が正しく表示されるようになっています。 この辺の処理を削除しても、CLSは正しく機能してる模様。 単純に、以前はVRAMへのアクセス周りに問題があっただけのようですね。 データレコーダの対応。 取り合えず、暫定的にwavファイルのまま読み書きできるようにしました。 48kHz, 8bit, monoオンリーです。 csaveして出力されたファイルは、テープに録音してそのまま実機でcload できる…筈です、多分。 で、久々にデータレコーダの速度を体感してみて、余りの遅さに耐えられ なかったので、ついでに録音・再生中はタイミング調整を殺して全力で 動作するようにしてみました。 一瞬で、という訳にはいきませんが、私の環境では実機の4倍程度と まあ我慢できるレベルにはなっています。 2004/10/31 昨日は結婚式&2次会に出席してました。 今日は朝から自宅に戻るためにまた新幹線の中です。 やっぱノートはラップトップで使うものじゃないなあと思います(苦笑) nmi周り。 PASOPIA 7では、リセットスイッチはCPUのリセット信号ではなく、何故か nmiを発生させるようになっています。 また、初代pasopia互換モードのため、i/oの00h-03h, 08h-0bhにアクセス すると、やはりnmiを発生させてトラップするようになっています。 また、nmiが発生した原因か、スイッチかi/oトラップかを検出することが できるようになっています。 一風変わってますが、中々よくできた仕組みです。 という訳で、この辺を実装しました。 i/oトラップやリセットスイッチについてはinterruptクラスで、i/oトラップ やnmiの有効無効のフラグはinterruptクラスにおいて、駆動自体はmemory クラスから。nmi発生源の検出はcassetteクラスから。 あちこちに処理が分散して気持ち悪いですが、まあ仕方ないですね。 これで、今までメニューにはあったけど、正常に機能していなかった リセットが使用できるようになっています。 これで、手持ちのソフトは全て正常動作するようになった訳ですが。 途中で10日ほど放置かましたので、それを除けば2週間ほど。 m5の3日やpv-2000の6時間ほどではないですが、まあまあ順調だったかな。 残項目は、rs-232c、カーソルの形状、データレコーダのデータ形式、 後はメニュー周りとかコンフィグの実装、内蔵ROMの吸出しでしょうか。 カーソル形状、同じCRTCを使用しているX-1解説本(試験に出る〜)でも、 「X-1では使用していない」から解説がないんですよね。 この辺は、まあ実機で確認するしかないですか。 rs-232cはどうせ使用しないのに、やたら複雑なのでパス。 今の課題は内蔵ROM吸出しの確立ですか。 うまく吸い出せてないのは、プログラム中で実行したときとコマンドで 実行したときで、bsave #-1の出力波形が全然違うことが原因のようです。 取り合えず、1kbごとにプログラムを停止して、手入力でbsave #-1を 実行してもらうようにすればいいのですが、ちょっと頭悪い気がして。 どうしたもんでしょう。 2004/11/2-3 ちょっと体調壊してました。 一日寝て体調回復したので、カーソル周りの修正。 カーソルの開始ラスタ、表示・非表示・ブリンクなど、R10,R11の 設定を反映するようにしました。 終了ラスタについては7に固定しています。 BASIC上で、カナロックに応じてカーソルの形状が変化するようになった他、 カーソルが非表示になったりブリンクするようになっています。 HD46505の資料、探せば結構あるもんですねえ。 次回更新時は、コンフィグやメニュー周りの実装をします。 その後にROM吸出し周りを整理したら、PASOPIA 7は一先ず完了です。 2004/11/8 展示会の合間を縫って更新です。 コンフィグ周りやメニューの実装をしています。 機能的には特に変わっていないです。 それ以外は、波形が乱れて読み込めないテープの補修をしてました。 wavファイルを解析した結果として、テキストファイルに長波長、短波長、 不明瞭な場合は波長形を出力して、それを手でデータフォーマットに従って 修正して、更にwavに戻す、といった作業をすることで、本来の出力波形を 再生するという、非常に泥臭い作業です。 それでも、これで読めなかったテープが読めるようになると嬉しいですね。 以下、テープイメージについてちょっとメモ書き。 48KHzでは、長波長はon*20,off*20、短波長はon*10,off*10のサンプルが得られる。 長波長をH、短波長をLとする。 1バイトのデータは、10パルスで表現される。 L????????Hという形式で、?の部分がデータ。 ファイルの先頭には、Hが4800パルスほど出力される。(ピー、と長い部分) バイナリファイルの場合は、その後ヘッダにファイル名や先頭アドレス、 ファイルサイズなどの情報が入り、その後は実データが出力される。 BASICの場合は、2700パルス(270バイト)毎に、Hが960パルスほど出力される。 ピーーーーー、ジャー、ピー、ジャー、ピー、ジャー…といった感じ。 最初の長いピーーーーー、がファイルの先頭をあらわす。 ピー、の部分が各ブロックの先頭をあらわす。 ジャー、の部分が270バイト分のデータ。 以下、本体添付のカセットのB面の解析メモ。 TBASIC 0000 0080 スタートアドレス、サイズ? PCONV @PCONV 00E0 0009 KANJI 70ef 8a01 FDUTIL FORMAT @FORMAT fbaf 3002 @MFDD fbef ff00 @RAMPAC 00d2 0003 FDCOPY @MFDD fbef ff00 FDCOMP @MFDD fbef ff00 SAMPL3 music2 00da ff16 SAMPL4 pset2 00da ff16 2004/11/9 リセット時に、VRAMの内容をクリアするようにしました。 これは、まあ特に特記するようなことはないです。 I/Oトラップを仕込んだ際に、一部I/Oアドレスが重複登録されていたのを 修正しました。なんか妙なボケかましてるなあ。 2重登録しようとしたらエラーを返すようにした方がいいかもしれん。 27色のうち中間色について。 異なる色を交互に配置することで中間色を表現しているんですが、この配置が ABABABAB ABABABAB ABABABAB ABABABAB と縦縞になっているため、いまいち綺麗に見えないという問題がありました。 これはこれで実機通りの正しい実装なのですが、折角だからオプションで ABABABAB BABABABA ABABABAB BABABABA のように、交互に配置するモードも追加してみました。 実機が200lineということで、奇数ラインは偶数ラインのコピーか黒を表示 していたのですが、ここに中間色の配置を反転したものを挿入する形で実装 しています。 実機でも、ハードウェアの中間色機能を使用せずに、自前でタイリングを 行ったソフトがあったようですね。 windows ce版について。 2〜3fpsと遅くて仕方がないのですが、一番負荷になっているのは4MHzで 駆動しているZ-80CTCだったりします。 CPUも同クロックなのですが、こちらは1命令で複数クロックを消費するため、 まだ軽いくらいです。 という訳で、従来1文字表示する時間分毎に駆動していたのを、1ライン毎と もう少し大雑把に駆動するようにしました。 またカウンタモード時に、1クロック毎に桁上がりの判定をしていたのを、 先に指定クロックだけカウンタの値を変えて、それから桁上がりの判定を するように変更しました。 但し、データレコーダ駆動時は、パルス幅の計測に使用するタイマ精度が 落ちないように、1文字毎に駆動するように動的に変更しています。 sigmarion3@533MHzで8〜10fps程度と、劇的に速度が向上しています。 またサウンドも従来の4KHzから8KHzに変更しました。 これで、ALPHOSなんかも十分プレイできるようになった筈です。 なお、PC版は従来通りに常時1文字毎で駆動することにします。 LCD対応も、一応やっておきます。 多分需要は全然ないですが。 こいつは、タイミング調整とかvsync/hsyncとか影響する部分が大きいため、 素直に別バイナリにしてやることにします。 液晶の色合いが判らないので、昔風のコントラストの低い黄色がかった 色にしてやります。 画面生成部で注意すべきなのは、各行のVRAMのアドレス。 カーソルを動かして調べてみたところ、0<=y<8として、 start + 640 * (y & 3) + (y & 4 ? 8 : 0)) で表されるようです。 ROM吸出しについて、仕切り直し。 裏RAMにコピーして、一括してbsaveする方式でいきます。 取り合えず、実機での検証は後日に回して、コーディングだけでも。 f5 PUSH AF // メモリマップ取得 db22 IN A, 22h e603 AND 03h f5 PUSH AF // メモリマップ変更 3e01 LD A, 01h // BIOS=01h, BASIC=00h d33c OUT 3Ch, A // (src)のデータを(dst)にコピー 3a???? LD A, (src) // BIOS=4000-7fff, BASIC=0000-7fff // メモリマップ変更 (要らない?) f5 PUSH AF 3e02 LD A, 02h d33c OUT 3Ch, A f1 POP AF 32???? LD (dst), A // メモリマップ復帰 f1 POP AF d33c OUT 3Ch, A f1 POP AF c9 RET …前と殆ど同じですね。BIOSを吸い出す場合は、 100 data &hf5, &hdb, &h22, &he6, &h03, &hf5, &h3e, &h01 110 data &hd3, &h3c, &h3a, &h00, &h00, &h32, &h00, &h00 120 data &hf1, &hd3, &h3c, &hf1, &hc9 130 clear ,&hefff 140 for a=&hf000 to &hf014 150 read d:poke a,d 160 next a 170 for u=&h40 to &h7f 180 print hex$(u) 190 poke &hf00c,u 200 poke &hf00f,u 210 for l=0 to &hff 220 poke &hf00b,l 230 poke &hf00e,l 240 a=&hf000:call a 250 next l 260 next u を実行して、bsave #-1,"BIOS",&H4000,&H4000を実行。 BASICの場合は、 100 data &hf5, &hdb, &h22, &he6, &h03, &hf5, &h3e, &h00 170 for u=0 to &h7f と修正して実行して、bsave #-1,"BASIC",0,&H8000を実行。 後は、これを48khz,8bit,monoで録音して、wavconvに食わせてやる。 ついでに、漢字ROM吸出しも。 こちらは容量が128kbと大きいので、32kbずつ4回に分けて出力する。 f5 PUSH AF 3e?? LD A, 00H // PAC2スロット選択 (0-7) d31b OUT 1Bh, A 3e?? LD A, (l) // アドレス指定 (low, middle, high) d318 OUT 18h, A 3e?? LD A, (m) d319 OUT 19h, A 3e?? LD A, (h) d31a OUT 1Ah, A db18 IN A, 18h // データコピー 32???? LD (dst), A f1 POP AF c9 RET 100 data &hf5, &h3e, &h00, &hd3, &h1b, &h3e, &h00, &hd3 110 data &h18, &h3e, &h00, &hd3, &h19, &h3e, &h00, &hd3 120 data &h1a, &hdb, &h18, &h32, &h00, &h00, &hf1, &hc9 130 clear ,&hefff 140 for a=&hf000 to &hf017 150 read d:poke a,d 160 next a 170 input "slot (0-7)",s 180 print "0: 00000-07fff" 190 print "1: 08000-0ffff" 200 print "2: 10000-17fff" 210 print "3: 18000-1ffff" 220 input "range (0-3)",r 230 if r=0 then ms=&h00:h=0:goto 300 240 if r=1 then ms=&h80:h=0:goto 300 250 if r=2 then ms=&h00:h=1:goto 300 260 if r=3 then ms=&h80:h=1:goto 300 270 end 300 poke &hf002,s 310 poke &hf00e,h 320 for m=0 to &h7f 330 print hex$(m) 340 poke &hf00a,m+ms 350 poke &hf015,m 360 for l=0 to &hff 370 poke &hf006,l 380 poke &hf014,l 390 a=&hf000:call a 400 next l 410 next m これを実行して、rangeに0,1,2,3を指定します。 終わったら、bsave #-1,"KANJI",0,&h8000で各々録音して、wavconvに食わせる。 後は、出来上がったファイルをcopy /bで繋いでやればOK。 2004/12/4 ちょっとサボってました。 今日までやった作業としては、サウンドの再生時に音が途切れる問題の修正と、 8255のport cのビット操作の処理が正しくなかった問題の修正だけです。 2004/12/26 マルチ8のディスク対応に行き詰ってしまいましたので、気分転換に初代PASOPIAの 実装を進めようかと思います。 ROM吸出しは、PASOPIA7と同じくbsave #-1にて。 OA-BASIC版は、言語マニュアルが手元にないためbsaveの文法が判らないため保留。 2004/12/29 OA-BASICのbsaveの文法を、めがきらさんより教えて頂きました。 いつもお世話になってます。 ただ、帰省のスケジュールの都合で吸出し作業を行えなかったため、年明けに 独身寮に戻ってから吸出し作業を進めようかと。 帰省のための新幹線中で実装開始。 PASOPIA7のPASOPIA互換モードを考えると、恐らくVRAMと画面生成周り以外は 余り変わりないと思われます。 ただ、画面生成処理自体は大幅に変更が必要っぽいですので、一応別バイナリ とする予定です。 めがきらさんにお借りしたASCII誌のロードテストによると、VRAMアクセスは 2つの8255を経由して行うようです。 I/Oのアクセスログを見ると、$00-$03, $08-$0aに8255が割り付けられていて、 $01に書き込む内容を指定して、$00,$0aにアドレスの下位、上位を指定する模様。 $0aに$40を出力すると、VRAMに書き込まれるのかな? HD46505のログを見ると、水平文字表示数の指定が、実際の文字数+1になってます。 (指定する際に-1することを考慮した上です) width 80とすると、本来80-1を指定するところが、81-1を指定しています??? よく判らないので、取り合えず適当な値決め打ちで画面生成処理を実装して、 スクリーンショットだけ取っておきます。 文字のアトリビュートの指定はどうするんだろう。 2004/12/30 I/Oのアクセスログを読んで判った事。 HD46505で水平文字列表示数+1を指定していた件ですが、最初の1byteに文字の 色を指定して、その次から文字コードが入る模様。 今実機がないので確認できませんが、多分1行丸ごと同じ文字色なのかと。 画面モードは、08hで指定するようです。 $08 mmw- ---- mm = 0 : screen 0 = 1 : screen 1 = 2 : screen 2 w = 0 : width 36 = 1 : width 80 screen 1,2のグラフィック画面がVRAMでどう表現されるのかはまだ不明ですが、 screen 0については、これだけの情報で概ね動作するようです。 後は背景色の指定の仕方だけ調べないと。 2004/12/31-2005/1/1 vramのアクセス方法の解析続き。 取り合えずscreen 2を中心に実装中です。 正常に表示できていないところを見ると、まだまだ間違いがあるのでしょう。 01hに書き込む内容を出力。 00hにvramの下位アドレスを、0ahに上位アドレスを指定。 0ahのbit7が立っているとグラフィック? bit6が立っているとデータ書き込み? 1画面は800hバイト。 グラフィックの場合、スキャンライン毎に+800h? 0ahに上位アドレスを出力するとき、and 07hをして、or b。 bはand 30hをしている?←これはscreen2のときの処理? 2005/1/2-3 0ahのbit6は、L->Hに立ち上がったときに01hの値を書き込み。 但し、アドレスは直前の00h,0ahの値で決定される。 02hでvramの内容を読み込み、アドレスはその時点の00h,0ahの値で決定される。 ある1文字を示すvramのアドレスがa (a<3ffh)のとき、a+0000h. a+0800h, a+1000h,... のアトリビュート1bitのうち1つでも立っていると、その領域はグラフィック。 グラフィック時、アトリビュートの立っていないスキャンラインのパターンは00h。 但し、screen1の場合はスキャンラインは1文字辺り4ラインとなるため、vramの アドレスは1000h毎となる。 screen1の場合、上位4bit、下位4bitで各々1dotを示す。 このとき、4bitの値で色を示す。 screen2の場合は、単色でパターンを示す。 取り合えずこんな感じで、グラフィック周りの表示は正しいようです。 うーん、PASOPIA7のVRAM構成も変態的だったけど、初代様も劣らず変態やなあ。 PAC SLOT2については、基本的には同じっぽいです。 ただPAC拡張ユニットはサポートしていないようですので、RAM PAC2,32KBが 接続されていると仮定して実装しておきます。 漢字ROMは別途拡張ユニットとして増設するようですが、現状は詳細不明。 この辺はおいおい調査していきます。 ディスクドライブは、多分そのまま動くと思うんですが、ディスクBASICを 所有していないので、ちょっと保留です。 後は、EmuPIA 7について、ジョイスティックの実装をEmuZ-2500に準ずる形で 修正しておいて、公開します。 2005/1/5 OA-BASICのROM吸出し。 BSAVEのフォーマットがT-BASICと異なっているのですが、これはめがきらさんに 教えていただいたもので正解でした。 BSAVE "CT1","OABAS",0,32767,32768 でデータレコーダに$0000-$7fffを吸い出して、後はいつも通り。 これを現行のEmuPIAに食わせてやると、どうも暴走してしまいます。 逆アセンブルしてみると、初期化されていないメモリ内容を参照してメモリ バンクを切り替え、でRST 00H、をループしてスタック領域切れで暴走 している模様。 幾らなんでもそりゃないだろう、ということで暫く頭を悩ませていたのですが、 結論としては、ROMの内容を裏RAMにコピーして多少書き換えて、その上で動作 していました。 OUT #60,0でメモリバンクをROMに切り替えなおしてからBSAVE、で吸い出して 再チャレンジしたところ、今度はシステムディスクを要求して停止。 どうやら、OA-BASIC版では、ディスクインターフェースが存在している場合は 必ずディスクから起動することを要求するようです。 取り合えず、面倒なんでOA-BASIC版の場合はディスクを殺すように暫定対応 しておきます。 これで一応OA-BASICが起動するようになりました。 また、実機を調べた限りでは、$3cのbit2が立つとリセットする機能がある ようなので、これもついでに実装しています。 2005/1/7 仕事で名古屋に出張だったので、そのまま岐阜の実家に戻ってきました。 現状の問題として、OA-BASIC上でERASEとかWIDTHで画面が消えてくれない、 という件があります。 T-BASICではVRAM全領域を$20でクリアしているのですが、OA-BASICでは何か I/Oによって画面クリアしているっぽいです。 詳細は判らないのですが、画面消去を伴う際は必ずHD46505のパラメータを 初期化していますので、これをトリガとしてVRAMクリアするように手抜き実装 することにします。 2005/1/9 初代PASOPIAのサウンドは、Z-80CTCのカウンタ#1の出力を利用して音程を 生成しています。 ただ、音声生成処理とカウンタ駆動処理のタイミングの問題で、正しい 波形が生成されないため、真っ当に音が出ていません。 これは、別途音声用の波形生成処理を用意することにしました。 SOUND命令でO3のAを発生して、これが434Hzになるように合わせてあります。 T-BASIC版のデモのDOREMIで、それっぽい音が出るようになっています。 2005/8/14 ユーザの方から送っていただいたパッチの対応を行いました。 主にvram周りやhd46505の挙動に関する修正なのですが、その拘りの深さには ただただ圧倒されるばかりです。 本当にありがとうございました、対応遅くなってしまい申し訳ありません>H様 その他、eRX-78から導入した、イベントの発生タイミングをより正確なものと する修正を適用しています。 vram周りの修正は、vram/paletteのアクセス、アトリビュートの有効範囲などに 関する不具合。 hd46505については、こちらがレジスタの値を決め打ちして行っていた描画処理を、 出来る限り厳密に解釈して行うというもの。不正な値を指定すると、同期がずれて 画面が流れるという芸の細かさです。 その他、サウンド周りでbeepの周波数の修正、sn76489anのノイズ関連、ミュートの 実装など。 主にドアドアなどで不具合が発生していたのが改善するようです。 以下私信。 pac2の件ですが、起動直後にinp(&h1a)が0になるのは、初期化されていない rampac2が接続されている場合に発生するようです。 送っていただいた改善案はやや一般性に欠けるように思われましたので、 取り敢えずrampac2のイメージを生成する際には、フォーマット済みのものと するように変更しました。 ミュートの実装ですが、これはemuクラス内ではなく、vmクラス内で対応する ようにしました。 実機に関わる処理は、原則としてvmクラス内で行うという趣旨からです。 その他、変数の命名規則やインデントの下げ方などで、多少変更している箇所が ありますが、基本的には頂いたパッチをそのまま使用させていただきました。 別件として、マリちゃん危機一髪で音声テープの再生に対応するという案件が 残っています。 で、テープをお借りしていたので聴いてみたのですが・・・うーん、なんか 凄い脱力しそうな音声なんですが、対応どうしましょうか(苦笑)