エントリー

PC-1401のRAMを12kByteに

 入手の段階で,すでにかなり使い込まれていて使い潰すことに決めたポケコンのPC-1401ですが,入手時の2007年12月の段階で,RAMを標準の4kBから10kBへ拡張してあります。

 しかし,フリーエリアは増えず,4kBのままでした。

 PC-1401は&3800から$3FFFまでの2kBと,&4000から&47FFまでの2kBの合計4kBです。それぞれ別チップ(6116)で,このアドレスでデコードされたCEがCPUから出てきます。&3800から&3FFFまでがF05,&4000から&47FFまでがF04のようです。

 このうち1つの6116を64kbitのSRAMに置き換えるのですが,腐るほどある256kBitを64kbitの代わり使うことにし,トータル10kBを狙った改造を当時行っています。

 しかしあいにくBASICのフリーエリアは4kBのまま増える事はなく,その後も問題の解決には至っていませんでした。

 当時の資料が見当たらなかったので実機を見て確認したのですが,6116はF04に,MB84256はF05に繋がっていました。そしてMB84256にはA11とA12がちゃんと配線されており,8kBをアクセス可能なようになっています。結果としてPC-1402と同じ回路になっているということです。

 メモリマップから考えるに,F04は1401と1402に共通の2kBである&4000から&47FFまで,F05は&2000から&3FFFまでの8kBがデコードされているようです。

 これだと,6116がF05に実装された場合,本来のメモリ&3800のイメージが&2800にも見えるはずで,当時の文献(I/Oです)を調べてみると,やはり&2000と&2800と&3000にイメージが出ていると言うことが書かれていました。なるほど。

 同様に,&5000から&57FFが&4000から$47FFまでのイメージになっているということで,それならF04の領域もフルデコードしてやれば夢の16kB実装になるんじゃないかとワクワクしたんですが,PC-1401はワークエリアが&46A0から&47FFまで置かれており,BASICのエリアは&45CFまでと決められていたのでした。

 あとでわかったことですが,どうやらF04は&4800から&4FFFまでと&5800から&5FFFまではデコードしておらず,Lowになりません。なんでそうしたのかわかりませんが,&4800移行にはメモリは存在しないことになっており,不用意に外部メモリへのアクセスが発生しないように,しっかり作ってあるという事かも知れません。

 それでも,&4800から&4FFFと&5800から&5FFFまでを除いた,&5000から&57FFまでの2kBがマシン語エリアとしても利用出来るなら,それはそれでかなり便利になると思います。(モニタを置いたり後述のBASICエリア拡張プログラムを置いたりすればBASICのフリーエリアを圧迫しません)

 とりあえず,現在の10kBのになっている状態をもう少しきちんと確かめていきます。まず&2000に実メモリがある事を確認します。&3000とは別の値が書き込めているのでこれは間違いなさそうです。

 したがって,私のPC-1401は&2000から&3FFFまでの8kBと,&4000から&47FFまでの2kBのトータル10kBというのが,結論です。

 しかし,MEMで返ってくる値が3534と,メモリ拡張改造前と変化しないのはどうしてかといえば,それはBASIC格納エリアを示すアドレスを示したワークエリアを見ればわかるはずです。

 PC-1401のBASICのスタートアドレスは&46E1から2バイト,エンドアドレスは&46E3から2バイトで格納されています。リセット直後の状態ではスタートアドレスは&3800,エンドアドレスは&3801となっています。

 これはメモリの拡張を行っても同じです。だからBASICのエリアが増えないんですね。スタートアドレスを&2000としてNEWとすれば,MEMは9678と返ってきて,見事にBASICのエリアが増えるのです。

 しかし,PC-1401は電源を切ると&3800に戻ってしまう仕様のため,&2000から置いたBASICのリストが電源を切ると見えなくなってしまうと言う事態に見舞われます。&2000に戻してやれば復活しますが,いちいち手動でやるのは面倒ですし,エンドアドレスも電源を切る前にメモしておかないといけないので大変です。うっかり忘れるとプログラムが戻せなくなってしまいますしね。

 そこで,久々のマシン語でBASICエリアを拡張するプログラムを作ってみました。プログラムを&2000から置いてCALL&2000とすれば,&201AをBASICのスタートアドレスとし,BASICのプログラムの終わりである&FFをサーチして,そのアドレスをエンドアドレスに設定してくれます。

2000 03 20 02 1A 01 01 13 02
2080 84 0A 82 10 46 E1 1B 24
2010 67 FF 29 04 10 46 E3 84
2018 1B 37

以下はアセンブルリストですが,ハンドアセンブルですのでアセンブラにはかからないと思います。

ORG $2000;
LIB $20 03 20 ;Start Address H
LIA $20 02 1A ;Start Address L
LIJ $01 01 01
LIQ $02 13 02
LP $04 84
MVB 0A ;XL<-A, XH<-B

LP $02 82
LIDP $46E1 10 46 E1
EXBD 1B ;$46E1<->A,B

loop:
IXL 24
CPIA $FF 67 FF
JRNZM loop 29 04
LIDP $46E3 10 46 E3
LP $04 84
EXBD 1B ;&46E3<->X
RTN 37

 使い方ですが,まず&2000から&45CFまでのRAMが存在するよう,改造が済んでいることが先です。もちろん,プログラム中のStart Addressを書き換えればどんなエリアもBASICの格納エリアに出来ますが,せっかくですので10kBのメモリ拡張を行っておいて下さい。

 リセット直後だけのおまじないで,POKE&201A,255,255として,空っぽのBASICエリアを&201Aから作っておいて下さい。

 その後CALL&2000とすれば,BASICのスタートエリアは&201Aに設定され,MEMの結果も9652になってくれます。以後は電源を入れる度にCALL&2000とすれば,書き込んだBASICもちゃんと復活してくれます。

 このプログラム,久々にマシン語を書いたと言うことで,とても楽しいものでした。白状するとPC-1200系のCPUできちんとマシン語のプログラムを書いた経験はなく,今回はレジスタの確認から始めて,ニーモニックの詳細までを見る事になりました。

 なんと言いますが,直交性が低いというのはこういうことを言うんだなあと痛感しました。特に,レジスタの値をRAMに書くと言うことが,なかなか出来ないのです。RAMの値をレジスタに書くことは出来るのですが,その逆の命令はなく,交換ならあるという感じです。交換だとレジスタが壊れてしまうので,他のレジスタに保存する必要があったりするのですが,そういうことをやっているとどんどんコードが増えていきます。

 Z80という直交性がそれ程良くないというCPUに慣れている私が思うくらいですから,68000のようなCPUに慣れた人だと,もう無理だと投げ出してしまうんじゃないでしょうか。

 直交性の悪さというのは,やりたいことが出来ないというストレスを生みます。それは,命令がないのか,どういうことが出来ないのかを記憶しておかなくてはさっとプログラムが書けないという事なので,習熟に時間がかかるという事も意味しています。

 つまり,ポケコンのCPUは「難しい」CPUだと言うことです。

 ただ,この制限があることで,マシン語のプログラミングはまるでパズルを解くかのような楽しさがあります。動くようにするまでに1度,そしてそれを最適化するのにもう一度,楽しさを味わえるんですね。

 おかげで,久々に徹夜をしました。楽しくてね・・・

 だからこのプログラム,結構短く書けていると思います。白状すると後半は「ポケコンマシン語入門」の記事からもらってきたのですが,それ以外は結構真面目に書いています。まあ,コアの部分をパクっているわけで,これをオリジナルというのは両親が許しません・・・

 ということで,改造から13年の時を経て,ようやくBASICのフリーエリアを拡大しました。

 次のテーマは,&4800から&5FFFまでの6kBを使えるようにすることです。前述のように,この部分にBASICのプログラムを置くことは出来ないので,MEMの返値を大きくすることは出来ないでしょう。

 しかし,現在メモリ拡張プログラムを&2000から置いているせいで,26バイトBASICのエリアが狭くなっています。これが気に入りません。&4800からこのプログラムを置けば(こんなこともあろうかとリロケータブルです),&2000からのエリアを潰しません。

 のみならず,マシン語モニタを置けばさらに便利になります。考えようによっては,BASICインタプリタから完全に保護されたマシン語領域を別途作る事が出来るという事です。他の機種のユーザーは,マシン語エリアをわざわざCLEAR文で確保していますが,そうなるとBASICのフリーエリアも小さくなってしまうわけで,むしろすっきりメモリを分けられることになるので,好ましいとも言えます。

 新たに&4800から&5FFFまでのメモリを配置する方法ですが,一番楽なのはF04エリアにある6116を84256に置き換えてしまうことです。

 でも,それでは今ひとつ芸がありません。そこで,先日PC-1245を18kBにした改造と同じように,256kBitのSRAMを有効活用し,ワンチップで16kBにしてみましょう。

 改造そのものは簡単で,6116を1つ取り外し,A13まできちんと繋ぎます。そしてF04とF05のORをとってCEを作り,F04かF05のどちらかをA14に突っ込みます。これで前半16kBをF04に,後半16kBをF05に割り当てることが出来ました。

 改造が済んだら正常に動作することを確認して,POKEで&4800と&5000,&5800などがちゃんと読み書きできるかどうかを確かめます。

 ところがここで問題発生。&5000から&57FFまでは問題なく読み書き出来ているのですが,&4800から&4FFFと&5800から&5FFFまでが書き込めないのです。きっとF04がこのアドレスのアクセスでデコードされておらず,出力が出ないせいだろうと考えて,それならデコーダを外部回路で作るまでだと意気込んでみましたが,あいにくA15がCPUから出てきていないことが判明しました。

 A15が出ていないなんてそんな馬鹿な,と思ったのですが,PC-1401の回路図ではA15は出ておらず,代わりに&8000から&FFFFまでに配置された外部ROMのCSが出ています。

 なんだ,&8000から&FFFFまでのCSってことは,つまりA15の反転だよなと,ここを使うことを考えました。デコーダはHC139を使って,A13が0,A14が1,A15が0の時にLowになるような回路を作りました。

 A14とA15の反転(ROMのCS)をHC139のAとBに,A13をGに入れます。そして出力のY3を84256のCEに繋ぐわけです。これで&4000から&5FFFまでがデコード出来るはずです。

 あれ,このCEって正論理だったのかもなあと,Y3ではなくY2につなぎ替えます。しかし結果は同じです。

 いろいろ理由を考えてみました。動かない理由を考えるというのは後ろ向きで嫌なもんですし,所詮は推測なので,他の理由で動かないのかも知れません。

 まず,PC-1250シリーズやPC-1400シリーズのSRAMは,OEがGNDに固定されています。ということは,積極的な出力の制御を行っていないのですから,CEを動かす前にリードなのかライトなのかを決めて,リードならアドレスを,ライトならアドレスとデータをCPUがバスに乗せておく必要があるわけです。

 つまり,アドレスを乗せただけではデータバスに出力が出てこないようにしないと,ライトの時にデータバスが衝突することになります。そう,F04というCPUからのCE信号には,OEも含まれているという事です。

 これを私のやったように,単にアドレスをデコードしただけだと,アドレスが出てきただけでデータバスに出力が乗ってしまいます。アドレスとデータとR/Wが一斉に動くなら話は別ですが,そういうタイミングは許されていないのでアドレスを先に乗せているなら,ライトをしようとデータをCPUが乗せてしまうとRAMもデータを吐き出しているという事になり,衝突が起こります。

 こうなると正常な書き込みなど出来るはずもなく,起動しないという事ではないかと思います。推測と勝手な前提による考察に過ぎず,波形を見て確かめてはいないのですが,可能性は高いでしょう。

 ということで,SRAMのCEにはOEもデコードしないといけないと考えたわけですが,OEがCPUから出てきていないため,ここで終了。結局&4000から&47FFと$5000から&57FFまでの4KBを選択するF04をそのまま使うことで手を打ちました。

 &4000から&47FFまではすでに実装済みでしたので,増えたのは&5000から&57FFまでのたった2KBに過ぎません。

 されど2KB。ここにBASICのスタートアドレスを書き換えるプログラムを置いてやれば&2000から&47FFまでがスカッとBASICのフリーエリアになり,9678バイトというPC-1402と同じ容量になりますし,さらにモニタを置いてやればフリーエリアを邪魔せず読み書きできるようになります。それでもまだおつりが来るほどの自由空間です。

 ということで,まずは先程のプログラムを改造です。BASICのスタートアドレスを&2000に修正し,&5000から書き込みます。POKE&2000,255,255としてCALL&5000としてNEWすれば,MEMの結果はちゃんと9678バイトと返ってきます。もちろんBASICの読み書きもバッチリです。

 以下は改造後に,クロスアセンブラを使って実際にアセンブルしたlstファイルです。

00001:5000 ORG $5000
00002:5000 START $5000
00003:5000
00004:5000 0320 LIB $20 ;Start Address H
00005:5002 0200 LIA $00 ;Start Address L
00006:5004 0101 LIJ $01
00007:5006 1302 LIQ $02
00008:5008 84 LP $04
00009:5009 0A MVB ;XL<-A, XH<-B
00010:500A
00011:500A 82 LP $02
00012:500B 1046E1 LIDP $46E1
00013:500E 1B EXBD ;$46E1<->A,B
00014:500F
00015:500F loop:
00016:500F 24 IXL
00017:5010 67FF CPIA $FF
00018:5012 2904 JRNZM loop
00019:5014 1046E3 LIDP $46E3
00020:5017 84 LP $04
00021:5018 1B EXBD ;&46E3<->X
00022:5019 37 RTN

 ダンプリストはこんな感じです。&5000から置いてください。

5000 : 03 20 02 00 01 01 13 02 : 3C
5008 : 84 0A 82 10 46 E1 1B 24 : 86
5010 : 67 FF 29 04 10 46 E3 84 : 50
5018 : 1B 37 : 52


 続けて,ポケコンの本からPC-1401用のリロケータブルなモニタを探してきます。アドレスが固定されていたり,BASICのプログラムが必要なモニタは却下です。

 ちょっと長いプログラムしか見つからなかったのですが,それは問題なし。&5100からさっさと入力してCALL&5100とすれば,モニタが起動します。

 これで,&5000から&57FFまで,BASICやワークエリアとは完全に切り離されたフリーエリアを持つPC-1401が完成し,ここにモニタやマシン語のプログラムを置くことが出来るようになりました。使い勝手は上々です。

 もうちょっと頭をひねれば,もしかしたら&4800から&5FFFまでの6KBが自由に使えたかも知れませんが,マシン語のフリーエリアが2KBから6KBになったところで,今の私に出来る事は限られていますから,もうこれでいいことにしましょう。


 しかし,今レトロPCブームが来ているとはいえ,ポケコンこんな風に使って遊んでいる人はいないでしょう。PC-1245,PC-1251,PC-1211のLCDが復活したことがきっかけになっていますが,改めて手帳サイズですぐ起動,マシン語で遊べてそこそこメモリもあるというコンピュータがいつも手元にあるというのは,頼もしいというか楽しいというか,いいもんだなと思いました。

 

 

ページ移動

ユーティリティ

2026年01月

- - - - 1 2 3
4 5 6 7 8 9 10
11 12 13 14 15 16 17
18 19 20 21 22 23 24
25 26 27 28 29 30 31

検索

エントリー検索フォーム
キーワード

ユーザー

新着画像

過去ログ

Feed