SSブログ
English Version

3チップ構成68Kマイコンの構想(その12)Blocking/Deblocking [68K]

 前回の記事でプリント基板化のためのパターン設計について書きましたが、プリント基板製造をSeeedさんに注文し待ち状態です^^

 今回はCP/M-68KのSDカードアクセス時のブロッキング/デブロッキング処理を追加しました。
 3チップ構成のCP/M-80の時はCP/Mのメモリサイズを最大の64KBにしたいこともあってSDカードアクセス処理でブロッキング/デブロッキング処理には対応していませんでした。
 今回のCP/M-68KではBIOSのメモリサイズをあまり気にしなくてもいいこと、及びコマンドのサイズがCP/M-80と比較して大きめなのでコマンド実行時に少し待ち時間が発生してしまうのでブロッキング/デブロッキング処理に対応しました。

 SDカードのブロック長は512バイトなのでCP/Mのセクタ(128バイト)の4つ分に該当します。
 今回の対応で変更したワークエリアは
  1. PICと68K間のSDデータ渡し用の領域(SDバッファ)を128バイトから512バイトに変更
  2. SDバッファ内のデータがSDに書き込み済みでない場合の変更フラグを追加
  3. SDバッファの属性としてsector番号での管理をSDのブロック番号の管理に変更

の変更を行いました。

 BIOS内のWriteSectorコール時にD1レジスタに下記の情報が渡されます。
  1. d1.w = 0 : normal write
  2. d1.w = 1 : write to a directory sector
  3. d1.w = 2 : write to first sector of new block

 WriteSector処理での追加処理としては最初にSDバッファがヒット(今回の書込みセクタが含まれている)場合はSDの先読みは不要で含まれていない場合は変更フラグがオンならSDバッファをSDに書き込み後、先読みが必要か判断します。
 3)の場合は先読み不要でそれ以外の場合は先読みが必要になります。
 DMAの内容をSDバッファに書き込み、変更フラグをオンにし、2)の場合は即座にSDバッファ内容をSDに書き込みます(変更フラグはオフにする)。

 ReadSector処理に関してはSDバッファにヒットしている場合はSDバッファからセクタ内容を読み取り、ヒットしない場合は変更フラグがオンの場合SDバッファを書込んだ後、必要なSDブロックの内容をSDバッファに読込みます。
 SDバッファにヒットした場合、変更フラグがオンでもSDへの書込みは不要ですが、今回は長時間変更フラグがオンになる(その間、電源断等が発生すると書込み情報が失われる)のを避けるため、ReadSector処理ではありますがSDへの書込みを行うようにしました。

 文章で書くと少しややこしいですが、プログラム的には若干の追加で対応可能です。
 (ワークエリアはSDバッファが4倍に増えるけどプログラムコードのサイズはあまり増えない)

 参考に今回対応したBIOSのReadSectorとWriteSectorの部分の抜粋を以下に貼っておきます。

BIOS内ブロッキング/デブロッキング処理
212 * caliculate sector number 213 * d2 -> logical sector number in buffer 214 * d3 -> SD block No 215 CalSdSec: 216 0000017A 4283 clr.l d3 217 0000017C 363900000002 move.w track,d3 218 00000182 ED8B lsl.l #SEC_TR_SFT,d3 219 00000184 4282 clr.l d2 220 00000186 343900000004 move.w sector,d2 221 0000018C D682 add.l d2,d3 222 0000018E 2403 move.l d3,d2 223 00000190 028200000003 andi.l #$03,d2 * logical sec in buffer 224 00000196 E48B lsr.l #SD_SFT,d3 225 00000198 4E75 rts 226 227 * read sector 228 * d0.w -> 0:no error, 1:error 229 read: 230 0000019A 610000A8 bsr flush * if no error then d0.w=0 231 0000019E 66000038 bne rdend * if error 232 000001A2 61D6 bsr CalSdSec 233 000001A4 B6A90002 cmp.l OSdSec(a1),d3 234 000001A8 67000014 beq rd010 * if hit buffer 235 236 000001AC 12BC0004 move.b #FC_READ,(a1) 237 000001B0 23430002 move.l d3,OSdSec(a1) 238 000001B4 4E70 reset 239 000001B6 30290006 move.w ORetVal(a1),d0 * get return val 240 000001BA 6600001C bne rdend * if error 241 242 000001BE C4FC0080 rd010: mulu #SEC_SIZE,d2 243 000001C2 D4BC0007FE00 add.l #PICDMA,d2 244 000001C8 2042 move.l d2,a0 245 000001CA 247900000006 move.l dma,a2 246 000001D0 747F moveq #(SEC_SIZE-1),d2 247 000001D2 14D8 rdcpy: move.b (a0)+,(a2)+ * DMA is able to be odd 248 000001D4 51CAFFFC dbf d2,rdcpy 249 000001D8 4E75 rdend: rts 250 251 252 * write sector 253 * d1.w <- 0:normal write 1:directory write 2:write to first sector of new block 254 * d0.w -> 0:no error, 1:error 255 write: 256 000001DA 4280 clr.l d0 * set no error value 257 000001DC 619C bsr CalSdSec 258 000001DE B6A90002 cmp.l OSdSec(a1),d3 259 000001E2 67000024 beq wr010 * if hit buffer 260 261 000001E6 6100005C bsr flush 262 000001EA 66000056 bne wrend * if error 263 264 000001EE 23430002 move.l d3,OSdSec(a1) 265 000001F2 B27C0002 cmp.w #2,d1 266 000001F6 67000010 beq wr010 * if new block 267 268 000001FA 12BC0004 move.b #FC_READ,(a1) 269 000001FE 4E70 reset 270 00000200 30290006 move.w ORetVal(a1),d0 * get return val 271 00000204 6600003C bne wrend * if error 272 273 00000208 C4FC0080 wr010: mulu #SEC_SIZE,d2 274 0000020C D4BC0007FE00 add.l #PICDMA,d2 275 00000212 2042 move.l d2,a0 276 00000214 247900000006 move.l dma,a2 277 0000021A 747F moveq #(SEC_SIZE-1),d2 278 0000021C 10DA wrcpy: move.b (a2)+,(a0)+ 279 0000021E 51CAFFFC dbf d2,wrcpy 280 281 00000222 13FC000100000001 move.b #1,ChgFlg * set change flag 282 0000022A B27C0001 cmp #1,d1 283 0000022E 66000012 bne wrend * if not directory wite 284 285 00000232 423900000001 clr.b ChgFlg 286 00000238 12BC0005 move.b #FC_WRITE,(a1) 287 0000023C 4E70 reset 288 0000023E 30290006 move.w ORetVal(a1),d0 * get return val 289 00000242 4E75 wrend: rts 290 291 292 * flush disk 293 * d0.w -> 0:no err, $ffff:cann't flush 294 00000244 4240 flush: clr.w d0 295 00000246 103900000001 move.b ChgFlg,d0 296 0000024C 67000012 beq flend 297 00000250 423900000001 clr.b ChgFlg 298 00000256 12BC0005 move.b #FC_WRITE,(a1) 299 0000025A 4E70 reset 300 0000025C 30290006 move.w ORetVal(a1),d0 * get return val 301 00000260 4E75 flend: rts 302 303


 ブロッキング/デブロッキング対処後の動作例として「XMODEMアプリの作成」の記事で載せたxmodemでのファイル送信中のロジアナ波形のbefore/Afterを貼っておきます。

Before


 対処後は下図の赤丸部分に示すようにSDカードのアクセス回数が減少しています。

After


★2018/10/17 追記
 コメントに書いたようにCP/MからBIOSのWriteSectorには新たに確保したブロックの最初のセクタ書込み(D1レジスタ=2)であるという情報が渡されています。
 今回はCP/Mのブロックサイズを2048バイトにしているので、この情報からSDカードの4ブロック分(SDカードのブロックサイズは512バイト)、先読み無しで書込んでも問題ないはずなので改善してみました。
 ワークエリアとして新たに先読み不要カウンタと先読み無しで書込んだブロック番号の保存用ワークを追加して、念のためにSDカードのブロック番号が連番であることも確認するようにしています。
 また、ワークエリアを絶対アドレス指定でアクセスするとコード効率が悪くなるのでアドレスレジスタとのオフセットでアクセスするように一部変更しました。

 CP/Mの2ブロック分をバイナリモードで単純に書き込むテストプログラムを作りSDカードへの書込み動作を確認してみました。新規ファイルへの書込み動作のみを確認するためにファイルオープン後の書込み開始前と書込み終了後のファイルクローズ前にキー入力処理を入れることでファイルへの書込み中の波形をロジアナで確認しました。

 下のキャプチャがロジアナ波形のBefore/After比較になります。

 対処前はCP/Mブロックの最初の書込みだけ先読みがない状態なのでSDへの書込みの4回に3回は先読みが発生しています。

Before


 改善後は新規書込みの場合、常に先読み無しでSDカードへの書込みが行われていて想定通りの動作になっています。

After


 今回、CPM.SYSを何度か変更して評価するにあたり、CP/M-68Kで採用されているCP/Mローダのおかげで、AドライブのCPM.SYSファイルを入れ替えてCP/Mを再立ち上げするだけでいいので効率的に作業が出来ました。

 CP/Mのファイルセットに含まれているサイズが大きめのDDT68000.68K(431セクタ、54KB)のファイルをpipコマンドで空ディスクにコピーする時間を計ってみたところ 5.2秒から4.9秒に改善されました(あまり変わらないですねw)


[TOP] [ 前へ ] 連載記事 [ 次へ ]

nice!(0)  コメント(2) 

3チップ構成68Kマイコンの構想(その11)回路図整理とパターン設計 [68K]

 前回の記事で書いたようにCP/M-68K用のXMODEMを作り、ネットで公開されているCP/M-68Kのアプリで容易に遊べるようになったので回路図の整理とプリント基板のパターンを設計してみました。

 今回の回路はCP/M-80が動く3チップ構成のPic24CPMと回路構成は共通点が多いです。
 今回は最初からPCB製造をメーカーに出すことを前提にしたのでCNCでの作成のための条件であった「Via処理後はViaが基板面から出っ張るのでTQFPの半田付け作業の邪魔にならないようにTQFPの直下にはViaを打たない」という縛りを無くしました。
 この結果、Pic24CPMの回路と比較し、MC68008(48ピン)はZ80(40ピン)よりピン数が多いですが、CP/M-80の時よりボードサイズを数ミリ小さくできました(基板サイズは96 x 66[mm])。

 回路図は下図のとおりで使用しているICは
  • MC68008P10
    10MHz版のバスが8bit幅の68Kチップ。PICからクロックを供給する関係で8MHzで動作。
  • K6T4008C1B-DB70
    512KBのSRAM。アクセスタイムは70ns。
  • PIC24FJ64GA004
    16bitPICマイコン。セルフコンパイラの独自言語picleを使って制御。

の3チップです。

3チップ構成の68Kマイコンボードの回路図
★2018/10/31 追記
 R3は+5Vにプルアップするつもりでしたが3.3Vへのプルアップでも動作することを確認しました^^;


 次にパターン図ですが、上述したように今回はCNCでの基板作成は考慮せず、CNCのための条件もないので自由にパターンを作成しました。
 TQFP直下にviaを打ってもいいのでTQFP周辺の反対面(bottom面)のパターンも結構込み入っています。
 細い斜めの線はこの時点ではパターン化していないグランドの結線です。グランドをベタパターン化する際に接続される予定です。

パターン図(GNDベタ化前)


 下図がグランドベタ化後のトップ面のパターンです。
 パターンが込み合っているため、グランドをベタパターンにしても孤立した部分(茶色の部分)が多く発生し、グランドに接続できていなかった端子が何個か生じました。このため数個のviaを追加してトップ面とボトム面を接続することでグランドへのパスが出来るようにしています。

トップ面


 下図はボトム面のパターンです。

ボトム面


 おまけでDesignSparkPCBで3D表示した画面を貼っておきます。(上記のトップ面とボトム面接続用のvia追加前のものです)
 512KBのSRAM等、3Dデータがないものは直方体になっています。
 3チップ構成と言いながら4チップあるように見えますが、右端のICのようなものはSDカードホルダです。w

トップ面

ボトム面


 こんな小さなワンボード基板でCP/M-68Kが動くんですよ^^

★2019/11/25 追記
 完成したプリント基板を「3チップ構成68Kマイコンの構想(その13)プリント基板完成」の記事に掲載しました。


[TOP] [ 前へ ] 連載記事 [ 次へ ]

nice!(0)  コメント(0) 

3チップ構成68Kマイコンの構想(その10)XMODEMアプリの作成 [68K]

 前回の「3チップ構成68Kマイコンの構想(その9)メモリ拡張」で書いたように自作68Kボードのメモリを512KBに拡張できたので、CP/M-68Kの一般的アプリが動く環境になりました。CP/M-68K用として公開されているソフトがCP/M-80程に豊富なわけではありませんが探せば色々見つかります。

 ネットからダウンロードしたファイルを試してみたりする際にSDカードとのファイルのやり取りが手軽にできる環境がないと不便です。
 ネット上でCP/M-68K用のkermitを見つけましたが、kermitのクライアントのようでパソコンとファイルの送受信をするためにはパソコン側にkermitのホストを立ち上げる必要があります。しかし、CP/M用のコンソールとしてTeraTermを使っているので切替えの手間が必要になります。

 そこで「3チップ構成Pic24CPMマイコン(その5)XMODEMでファイル送受信」の記事で書いた自作のCP/M-80用のxmodemアプリをCP/M-68K用に移植しました。
 CP/M-80で使った HI-TECH C コンパイラはプロトタイプ宣言やunionなどにも対応していて使い易かったのですが、CP/M-68KのC言語コンパイラはK&Rの構文なので結構使いづらい・・・

 標準的なヘッダファイルもあまりないのでハマった点としてファイルオープン時のリターン値である stream address が符号拡張されて実装メモリ(MC68008のメモリ空間である1MBの前半部分)以外になり、(自作の68Kボードでは)実行が停止してしまう問題が発生しました。
 対策としては fopenbを使用する前に FILE *fopenb(); のように簡易的なプロトタイプ宣言をする必要があります。()内の引数は型宣言付きで記述するとエラーになりますが型宣言無しで記述するとエラーは発生しません。しかし、コンパイラは無視するので引数の数チェックを期待してもコンパイラはチェックしませんでした。(意味を示す判り易い表現で引数を書いておいた方がbetterだとは思います)
 68Kではアセンブラでアドレス用のレジスタ(A0~A7)の下位ワード(16bit)を設定した時等も上位ワードに符号拡張されるので注意が必要です。

DDTでのSend()処理の逆アセンブル
-l._Send _Send: 00007326 link A6,#$FFF2 0000732A move.l #$AEBC,(A7) 00007330 move.l $B358,-(A7) ._FileNam 00007336 jsr $7ABA ._fopenb 0000733C addq.l #$4,A7 0000733E ext.l D0     D0が0000B04A -> FFFFB04A に符号拡張されてしまう 00007340 move.l D0,$B34A ._Fp 00007346 bne $7352 00007348 move.l #$AEBE,(A7) 0000734E bsr $7164 ._ErrExit 00007352 move.w #$C,$FFFA(A6)


 少し手間取りましたが、CP/M-68K用のxmodemアプリが完成し、ファイルのやり取りがメチャ楽になりました^^
 xmodemができるまでは、pip xm16.c=con: のようにpipコマンドを使って TeraTerm のファイル送信機能(バイナリモードをON)を使っていましたが、シリアル通信速度が38400bpsではたまに取りこぼしが発生するので1キャラクタ毎に1msのウェイトを設定していて、転送に時間が掛かっていました。
(今回のMC68008は8MHz動作ですが、16MHzのZ80で動くPic24CPMではウェイト無しにTeraTermからの送信ができていた)

 今回作成した CP/M-68K用の xmodemアプリのコンパイルと使用例のログを以下に貼っておきます。
 冒頭で書いたように CP/M-68K のアプリはネットを探してもそれ程豊富ではない状況なので、今時 CP/M-68Kの新アプリを公開するサイトは希少だと思います。
 まぁアクセス数の少ない極東のこのブログで公開しても見つける人の方が希少かもしれません・・w

xmodemアプリのコンパイル方法と使用例
N>xm68 /r xm68.c xm68.c Overwrite(Y/N) ?y received 55 block(s). N>c xm68 N>CP68 -I O: XM68.C XM68.I N>C068 XM68.I XM68.1 XM68.2 XM68.3 -F N>ERA XM68.I N>C168 XM68.1 XM68.2 XM68.S N>ERA XM68.1 N>ERA XM68.2 N>AS68 -L -U -S 0: XM68.S N>ERA XM68.S N>clink xm68 bdos N>LO68 -R -U_NOFLOAT -O XM68.68K 0:S.O XM68.O BDOS.O .O .O .O .O .O .O .O 0:CLIB N>ren xm68.rel=xm68.68k N>reloc xm68.rel xm68.68k N>stat xm68.* DRIVE N: USER : 0 RECS BYTES FCBS ATTRIBUTES NAME 134 18K 2 DIR RW N:XM68 .68K 55 8K 1 DIR RW N:XM68 .C 60 8K 1 DIR RW N:XM68 .O 283 36K 3 DIR RW N:XM68 .REL ---------------------------------------------- TOTAL: 70K 7 N: RW, FREE SPACE: 1,110K N>xm68 /s xm68.68k xm68.68k sent 134 block(s). N>xm68 usage : xm68 [/s /r /p] FileName /s : send[default] /r : receive /p : use PUN/RDR device Ver0.01c 2018/09/28 by skyriver N>


 上のログの末尾にあるヘルプメッセージからも判るように今回も '/p' オプションでBIOSに実装している puncher とreader を使った通信に対応しました。
 reader からの受信ではBIOSの仕様上、受信データの有無を確認するためのステータス取得ができないので、受信データがない場合にはリターン値を 0xffff にするような拡張を行っています。
★2018/09/30 追記 {
 CP/M-68Kのマニュアル上はpucher/readerではなく、Auxiliary Output/Input(汎用入出力)と記載されています。
}

 下のキャプチャはCP/M-68Kからのファイル送信中のロジアナ波形で、下図からは判りませんが拡大して見るとシリアル通信(38400bps)もキャラクタ間に隙間なく送信できています。

CP/M-68K側からxmodemでファイル送信中の波形例


 尚、今回開発したxmodemのソースと実行ファイルは下記のURLからダウンロード可能です。営利目的以外であれば自由に使って構いません。


★2018/09/30 追記
 今回作成したxmodemアプリでCP/Mとパソコン間でのバイナリも含めたファイルの送受信が手軽にできるようになったので「3チップ構成68Kマイコンの構想(その7)CP/Mのリロケート」の記事で書いたdump表示をTeraTermからコピペし、dump2binでバイナリ化後、Sレコード変換しなくても、CP/M上のsendc68コマンドでCP/M上のファイルをSレコード化してからxmodemでパソコンに持ってこれるようになりました。
 例えば sendc68 - cpm0400.sys >cpm0400.sr でCP/M本体をSレコードしてからxmodemでパソコンに持ってくれば、万が一、CP/Mが立ち上がらない状況になった場合にも、パソコン側からSレコードローダーで68K内メモリにダウンロードすることで最初のころに行っていたようなSレコードダウンロード方式によるCP/Mの起動が可能となります。


[TOP] [ 前へ ] 連載記事 [ 次へ ]
nice!(0)  コメント(2) 

3チップ構成68Kマイコンの構想(その9)メモリ拡張 [68K]

 前回の「3チップ構成68Kマイコンの構想(その8)ローダーによるCP/Mの起動」の記事で書いたようにCP/M-68KがSDカードからブートできるようになったので今回はメモリの拡張を行います。

 今まで128KBytesのM628128ALP-7を使っていましたがebayでポチった512KBytesのメモリ(K6T4008C1B-DB70)が手元にあるので交換しました。
 いずれもアクセスタイムは70nsです。K6T4008C1BはM628128ALPのCS2(30番ピン)と未使用ピン(1番ピン)にそれぞれA17、A18が割り振られておりピンアサインはアッパーコンパチなので追加配線は楽です。

 ソフトについてはメモリ容量の変更になるべく影響受けないように考慮していたのでBIOS内のgetseg用のテーブルのメモリサイズ情報のみの対応となります。

 メモリが512KBになったので今までメモリ不足で動かなかったデジタルリサーチ社の CBASIC(コンパイラ) を動かしてみました。

 Twiterでも紹介した「RetroBrew Computers Forum」の最後の方に書かれているアスキーアートを動かしてみました。

 このForumにはベンチマーク結果の例がいくつか書かれていて68Kのものでは

CB68(compiled) (68k @ 6 MHz) 4:23 <== I can get it to work on one of my slower 68ks

となっています。

 下記がasciiart.basのコンパイルから実行までのログです。

CBASICでASCIIART
M>cb68 asciiart.bas -------------------------------------------------- CB68 CBASIC Compiler Version 1.0 Serial No. 3123-0000-000061 All Rights Reserved Copyright (c) 1983 Digital Research, Inc. -------------------------------------------------- end of pass 1 end of pass 2 1: 10 FOR Y=-12 TO 12 2: 20 FOR X=-39 TO 39 3: 30 CA=X*0.0458 4: 40 CB= Y*0.08333 5: 50 A=CA 6: 60 B=CB 7: 70 FOR I=0 TO 15 8: 80 T=A*A-B*B+CA 9: 90 B=2*A*B+CB 10: 100 A=T 11: 110 IF (A*A+B*B)>4 THEN GOTO 200 12: 120 NEXT I 13: 130 PRINT " "; 14: 140 GOTO 210 15: 200 IF I>9 THEN I=I+7 16: 205 PRINT CHR$(48+I); 17: 210 NEXT X 18: 220 PRINT 19: 230 NEXT Y end of compilation no errors detected code area size: 738 000002e2h data area size: 88 00000058h common area size: 0 00000000h symbol table space remaining: 49687 M>link68 asciiart.rel=asciiart.o,cb68.l68 -------------------------------------------------- LINK68 Overlay Linker Release 0.f Serial No. XXXX-0000 All Rights Reserved Copyright (c) 1983 Digital Research, Inc. -------------------------------------------------- asciiart.rel=asciiart.o,cb68.l68 M>reloc asciiart.rel asciiart.68k M>stat asciiart.* DRIVE M: USER : 0 RECS BYTES FCBS ATTRIBUTES NAME 92 12K 1 DIR RW M:ASCIIART.68K 3 2K 1 DIR RW M:ASCIIART.BAS 15 2K 1 DIR RW M:ASCIIART.O 182 24K 2 DIR RW M:ASCIIART.REL ---------------------------------------------- TOTAL: 40K 5 M: RW, FREE SPACE: 1,368K M>asciiart 000000011111111111111111122222233347E7AB322222111100000000000000000000000000000 000001111111111111111122222222333557BF75433222211111000000000000000000000000000 000111111111111111112222222233445C 643332222111110000000000000000000000000 011111111111111111222222233444556C 654433332211111100000000000000000000000 11111111111111112222233346 D978 BCF DF9 6556F4221111110000000000000000000000 111111111111122223333334469 D 6322111111000000000000000000000 1111111111222333333334457DB 85332111111100000000000000000000 11111122234B744444455556A 96532211111110000000000000000000 122222233347BAA7AB776679 A32211111110000000000000000000 2222233334567 9A A532221111111000000000000000000 222333346679 9432221111111000000000000000000 234445568 F B5432221111111000000000000000000 864332221111111000000000000000000 234445568 F B5432221111111000000000000000000 222333346679 9432221111111000000000000000000 2222233334567 9A A532221111111000000000000000000 122222233347BAA7AB776679 A32211111110000000000000000000 11111122234B744444455556A 96532211111110000000000000000000 1111111111222333333334457DB 85332111111100000000000000000000 111111111111122223333334469 D 6322111111000000000000000000000 11111111111111112222233346 D978 BCF DF9 6556F4221111110000000000000000000000 011111111111111111222222233444556C 654433332211111100000000000000000000000 000111111111111111112222222233445C 643332222111110000000000000000000000000 000001111111111111111122222222333557BF75433222211111000000000000000000000000000 000000011111111111111111122222233347E7AB322222111100000000000000000000000000000 M>


 気になる実行時間は・・・・5分32秒(332秒)でした orz
 因みにMC68008のクロックは8MHzです。

 あまりにも遅いので CBASIC について調べてみると製作者の Eubankさんが修士論文のプロジェクトとして開発したBASIC-Eが元版でこれをデジタルリサーチ社が商用化したもののようです。
 浮動小数点を14桁の2進化10進数(BCD)演算として組み込んでいたことから非常に人気があったとのことです(マイクロソフト社のMBASICでは丸め誤差が発生するので経理計算では使いにくい)

 BCD演算とバイナリ演算を比較するのは酷というものでしょう・・

 また、コンパイル後のリンク方法としては下記のような方法でもいいようですが、出力される ASCIIART.68K のサイズが大きくなりました(実行時間は変わりませんでした)

別なリンク方法
M>link68 asciiart.o,cb68.l68 -------------------------------------------------- LINK68 Overlay Linker Release 0.f Serial No. XXXX-0000 All Rights Reserved Copyright (c) 1983 Digital Research, Inc. -------------------------------------------------- asciiart.o,cb68.l68 M>stat asciiart.* DRIVE M: USER : 0 RECS BYTES FCBS ATTRIBUTES NAME 182 24K 2 DIR RW M:ASCIIART.68K 3 2K 1 DIR RW M:ASCIIART.BAS 15 2K 1 DIR RW M:ASCIIART.O ---------------------------------------------- TOTAL: 28K 4 M: RW, FREE SPACE: 1,380K M>


 ヘッダのリロケーションフラグを確認してみるとFFFFになっていないのでリロケーションフラグ(水色文字分)がアクティブ(ゼロ)になっていてASCIIART.RELと同じサイズなのでファイル名が".68K"となっていますが".REL"と同じもののようです(バイナリ比較まではしていません)。

asciiart.68kのヘッダ内容
M>dump asciiart.68k 0000 00 (000000): 601A 0000 2BF8 0000 0176 0000 0266 0000 *`...+x...v...f..* 0000 10 (000010): 0000 0000 0000 0000 0000 0000 4EF9 0000 *............Ny..* 0000 20 (000020): 0006 4BF9 0000 2BF8 49F9 0000 2BF8 4EB9 *..Ky..+xIy..+xN9* 0000 30 (000030): 0000 02E2 2C3C FFFF FFF4 4EB9 0000 27DC *...b,<...tN9..'\* 0000 40 (000040): 49F9 0000 2D6E 4EB9 0000 2202 6000 028E *Iy..-nN9..".`...* 0000 50 (000050): 2C3C FFFF FFD9 4EB9 0000 27DC 49F9 0000 *,<...YN9..'\Iy..* 0000 60 (000060): 2D76 4EB9 0000 2202 6000 022C 4BF9 0000 *-vN9..".`..,Ky..* 0000 70 (000070): 2D76 49F9 0000 2BFA 4EB9 0000 2402 49F9 *-vIy..+zN9..$.Iy* 0001 00 (000080): 0000 2D7E 4EB9 0000 2202 4BF9 0000 2D6E *..-~N9..".Ky..-n* 0001 10 (000090): 49F9 0000 2C02 4EB9 0000 2402 49F9 0000 *Iy..,.N9..$.Iy..* 0001 20 (0000A0): 2D86 4EB9 0000 2202 4BF9 0000 2D8E 49F9 *-.N9..".Ky..-.Iy* 0001 30 (0000B0): 0000 2D7E 4EB9 0000 21FC 4BF9 0000 2D96 *..-~N9..!|Ky..-.* 0001 40 (0000C0): 49F9 0000 2D86 4EB9 0000 21FC 2C3C 0000 *Iy..-.N9..!|,<..* 0001 50 (0000D0): 0000 4EB9 0000 27DC 49F9 0000 2D9E 4EB9 *..N9..'\Iy..-.N9*


[TOP] [ 前へ ] 連載記事 [ 次へ ]
nice!(0)  コメント(0) 

3チップ構成68Kマイコンの構想(その8)ローダーによるCP/Mの起動 [68K]

 前回の「3チップ構成68Kマイコンの構想(その7)CP/Mのリロケート」の記事でCP/Mのリロケートができたので、今回はCP/Mをローダーで起動できるようにします。

 CP/M-68KはCP/M本体のサイズが大きくなり、当時記録媒体として一般的なフロッピーディスクのブート用に割当てた数トラックに収まらなくなったこともあり、CP/M本体のファイル(CPM.SYS)はAドライブ上に置き、CP/M本体を起動するために必要な最小限の機能に絞ったBDOS相当の機能を持ったものがCP/Mローダー(CPMLDR)です。
 ネットで見つけた英語のマニュアル(CP/M-68K Operating System System Guide)には「CPMLDR is a miniature version of CP/M-68K」と書かれています。

 CP/Mのブートの概要は
  1. Cold Boot Loaderの起動
     1トラック目の最初のセクタ(128bytes)に保存したCold Boot LoaderをPIC側が68K内のメモリに展開し、起動する。
     PIC側からアクセスできる68K側のメモリ範囲は狭い(最初の1KB(000000-0003FF)と最後の1KB)ので今回はベクターテーブル内ではありますが、0x0380を開始アドレスとしました。

  2. CPMLDRのメモリ展開
     Cold Boot Loaderは2番目以降のセクタに記録されたCPMLDRをメモリに展開し、起動する。CPMLDRの開始アドレスは0x008000にしました。

  3. CP/Mの起動
     CPMLDRがAドライブのファイルシステム上にあるCPM.SYSを起動し、CP/Mが立ち上がります。

 結局、CP/M本体がディスク上にあることには変わりないのでブート用トラックの本数を増やしてそこにCPM.SYSを格納すればいいじゃないかとも思えますが、CPM.SYSがファイルシステム上にあることでCP/MのBIOS変更等の作業がかなり楽になるという大きなメリットがあります。また、ブートトラック数を増やすと従来のディスクとの互換性が崩れます。

 CPMLDRはミニチュアのCP/Mなので動かすためには専用のBIOSが必要になりますが、CP/M用のBIOSから機能を間引けばいいだけなので作業的には楽です。
 1点だけ注意が必要で、CP/M用のBIOSはTRAPでコールされるので RTE でリターンしますが、CPMLDRからは_biosのラベルへのコールになるのでリターンは通常の RTS 命令になります。

 CPMLDR用のBIOSに実装する(または間引く)機能はマニュアルに書いてありますが、今回作成したCPMLDR用BIOS(ldrbios.s)の一部を引用すると下記のような機能の実装にしています。
 18番目の「Get MRT」(アプリで使えるメモリ範囲の情報を返す機能)はマニュアルには「Not used now, but may be used in future releases.」と書かれていますが現在は当時から見れば遠い未来なので実装していませんw

CPMLDR用BIOSソースの抜粋
_bios: move.l #FuncNo,a1 lsl #2,d0 * d0 = d0*4 movea.l 6(pc,d0),a0 * code : 207B 0006 jsr (a0) * call handler rts biosbase: dc.l _init * 0 dc.l no_func * 1 dc.l no_func * 2 dc.l no_func * 3 dc.l conout * 4 dc.l no_func * 5 dc.l no_func * 6 dc.l no_func * 7 dc.l home * 8 dc.l seldsk * 9 dc.l settrk * 10 dc.l setsec * 11 dc.l setdma * 12 dc.l read * 13 dc.l no_func * 14 dc.l no_func * 15 dc.l sectran * 16 dc.l no_func * 17 dc.l no_func * 18 dc.l no_func * 19 dc.l no_func * 20 dc.l no_func * 21 dc.l setexc * 22 maxfuncs equ (*-biosbase)/4 no_func: move.b #FC_EXIT,(a1) reset bra * _init: rts


 CPMLDR用のbiosの準備が出来たら、アセンブルし、LDRLIBとリンクします。

CPMLDR用biosのアセンブルとリンク
M>as68 -l -p ldrbios.s >ldrbios.prn M>lo68 -s -t8000 -uLDR -o cpmldr.sys ldrlib ldrbios.o M>stat *.sys DRIVE M: USER : 0 RECS BYTES FCBS ATTRIBUTES NAME 174 22K 2 DIR RW M:CPM0400 .SYS 23 4K 1 DIR RW M:CPMLDR .SYS ---------------------------------------------- TOTAL: 26K 3 M: RW, FREE SPACE: 1,474K M>size68 cpmldr.sys cpmldr.sys:2468+380+1422=4270 (10AE ) stack size = 0 M>dump cpmldr.sys 0000 00 (000000): 601A 0000 09A4 0000 017C 0000 058E 0000 *`....$...|......* 0000 10 (000010): 0000 0000 0000 0000 8000 FFFF 4FF9 0000 *............Oy..* 0000 20 (000020): 8F20 4280 4EB9 0000 888E 303C 0016 323C *. B.N9....0<..2<* 0000 30 (000030): 0008 243C 0000 8030 4EB9 0000 888E 007C *..$<...0N9.....|* 0000 40 (000040): 2000 4FF9 0000 8F20 6000 0180 0057 2000 * .Oy... `....W .* 0000 50 (000050): 4E73 4E56 0000 48E7 0104 2A6E 0008 6012 *NsNV..Hg..*n..`.* 0000 60 (000060): 101D 4880 3E80 3F3C 0002 4EB9 0000 873C *..H.>.?<..N9...<* 0000 70 (000070): 548F 1015 66EA 4A9F 4CDF 2000 4E5E 4E75 *T...fjJ.L_ .N^Nu* 0001 00 (000080): 4E56 0000 48E7 0700 3E2E 0008 3007 6022 *NV..Hg..>...0.`"* 0001 10 (000090): 2EBC 0000 89C6 61BA 4EB9 0000 8000 2EBC *.<...Fa:N9.....<* 0001 20 (0000A0): 0000 89D4 61AC 601A 2EBC 0000 89ED 61A2 *...Ta,`..<...ma"* 0001 30 (0000B0): 6010 4A40 67DA B07C 0001 67E2 B07C 0002 *`.J@gZ0|..gb0|..* 0001 40 (0000C0): 67E6 2EBC 0000 8A03 6188 4EB9 0000 8000 *gf.<....a.N9....* 0001 50 (0000D0): 4A9F 4CDF 00C0 4E5E 4E75 4E56 0000 48E7 *J.L_.@N^NuNV..Hg* 0001 60 (0000E0): 031C 2A6E 0008 2EBC 0000 902E 4267 3F3C *..*n...<....Bg?<* 0001 70 (0000F0): 001A 4EB9 0000 873C 588F 2E8D 4267 3F3C *..N9...<X...Bg?<* 0002 00 (000100): 000F 4EB9 0000 873C 588F B07C 00FF 6D08 *..N9...<X.0|..m.* 0002 10 (000110): 3EBC 0001 6100 FF6A 422D 0020 2E8D 4267 *><..a..jB-. ..Bg* 0002 20 (000120): 3F3C 0014 4EB9 0000 873C 588F 4A40 6708 *?<..N9...<X.J@g.* 0002 30 (000130): 3EBC 0001 6100 FF4A 267C 0000 902E 0C53 *><..a..J&|.....S* 0002 40 (000140): 601A 6606 302B 001A 6608 3EBC 0002 6100 *`.f.0+..f.><..a.* 0002 50 (000150): FF30 286B 0016 2E2B 0002 DEAB 0006 3EBC *.0(k...+..^+..><* 0002 60 (000160): 0064 2F0C 2F3C 0000 904A 4EB9 0000 837A *.d/./<...JN9...z*


 CPMLDR.SYSができたので動作確認のために前回記事に書いた方法でパソコン側に持ってきてSレコードに変換し、Sレコードローダで68K内のメモリに展開して起動してみます。(その前に当然Aドライブ上に前回記事で作成したCP/MファイルをCPM.SYSのファイル名で入れておきます)
 CPMLDRはサイズが小さいのでCP/Mの起動が楽になりました^^
 CP/M本体の起動時はいきなりプロンプト("A>")が表示され、物静かなOSだなぁ~と思っていましたが、CPMLDRを起動するとバージョン等、色々表示されます。

CPMLDRでのCP/M起動
:\\ +B000-B886 # 3chips MC68008 OneBoard test 2018/09/02 +C000-CB3D #LibCpm CP/M(PMP) lib68K v0.03 2018/09/14 +D000-DEEA #LibSpi SPI lib V0.03 2018/09/05 +E000-E860 # 3chips MC68008 OneBoard Hello 2018/08/19 +F000-FE9F # 3chips MC68008 OneBoard S fomat loader 2018/08/30 :src $f000 :run 22222222222222222222222222222222222222222222222222222222222222222222222222222222 222222222222 :src :\< 2182 :run CP/M-68K(tm) Version 1.3 08/05/85 Copyright (c) 1985 Digital Research, Inc. Pic24CPM-68K ver0.01 2018/09/23 by skyriver A>dir A: COPY REL : CPM SYS : DDT REL : DDT68000 68K : INIT REL A: PIP REL : README TXT : RELOC REL : RELOC SUB : RELOC1 SUB A: SD REL : STAT REL A>


 残りはCold Boot Loaderですが、これはSDカードの読込みの仕組みが解っていれば実装は簡単です。
 アセンブル&リンク操作とアセンブル結果も貼っておきます。

boot68k.sのアセンブルとリンク
M>as68 -l -p boot68k.s >boot68k.prn M>lo68 -s -t0380 -o boot68k.sys boot68k.o M>type boot68k.prn C P / M 6 8 0 0 0 A s s e m b l e r Revision 02.10 Page 1 Source File: boot68k.s 1 ************************************** 2 * CP/M-68K boot loader 3 * For Pic24CPM68K with SD Card 4 * adapted to Blocking/Deblocking 5 * ver 0.03a 2018/10/14 by skyriver 6 ************************************** 7 8 9 BOOTSTART equ $0380 * start address of boot loader 10 CPMLDR equ $008000 * start address of CPM loader 11 LDR_SIZE equ $1200 * size of CPM loader 12 13 PICWRK equ $07fdf0 * PIC service work area 14 PICDMA equ $07fe00 * DMA for PIC 15 SEC_SIZE equ 128 * sector size 16 BLK_SIZE equ (SEC_SIZE*4) 17 CR equ 13 18 LF equ 10 19 20 LDR_BLK equ LDR_SIZE/BLK_SIZE 21 22 23 FC_EXIT equ 0 * EXIT CP/M 24 FC_CONST equ 1 * CONST 25 FC_CONIN equ 2 * CONIN 26 FC_CONOUT equ 3 * CONOUT 27 FC_READ equ 4 * READ SD Card 28 FC_WRITE equ 5 * WRITE SD Card 29 FC_PUNCH equ 6 * PUNCH 30 FC_READER equ 7 * READER 31 32 * ++++ work area for PIC Interface 33 FuncNo equ PICWRK * ds 1 : function No 34 ArgByte equ PICWRK+1 * ds 1 : byte argument 35 SdSec equ PICWRK+2 * ds 4 36 RetVal equ PICWRK+6 * ds 2 : return value 37 38 OArgByte equ 1 39 OSdSec equ 2 40 ORetVal equ 6 41 42 43 00000000 .text 44 45 * org BOOTSTART 46 47 00000000 227C0007FDF0 _boot: move.l #FuncNo,a1 48 00000006 4DF900000044 lea startmes,a6 49 50 0000000C 121E _bo10: move.b (a6)+,d1 51 0000000E 6704 beq _bo20 52 00000010 6140 bsr conout 53 00000012 60F8 bra _bo10 54 _bo20: 55 00000014 12BC0004 move.b #FC_READ,(a1) C P / M 6 8 0 0 0 A s s e m b l e r Revision 02.10 Page 2 Source File: boot68k.s 56 00000018 4280 clr.l d0 * SD block No.(include boot sec) 57 0000001A 267C00008000 move.l #CPMLDR,a3 * set COMLDR address 58 00000020 244B move.l a3,a2 59 00000022 94FC0080 suba #SEC_SIZE,a2 * sub boot sec size 60 00000026 7408 moveq #(LDR_BLK-1),d2 * set sector loop counter 61 62 00000028 23400002 loop: move.l d0,OSdSec(a1) * set SD block No. 63 0000002C 4E70 reset * read sector 64 0000002E 207C0007FE00 move.l #PICDMA,a0 65 00000034 727F moveq #(BLK_SIZE/4-1),d1 66 00000036 24D8 rdcpy: move.l (a0)+,(a2)+ 67 00000038 51C9FFFC dbf d1,rdcpy 68 69 0000003C 5240 addq.w #1,d0 * next block No. 70 0000003E 51CAFFE8 dbf d2,loop 71 72 00000042 4ED3 jmp (a3) 73 74 75 startmes: 76 00000044 0D2E2E2E206C6F61 dc.b CR,'... loading ',0 76 0000004C 64696E672000 77 78 .even 79 80 * console out 81 * d1.w <- data 82 * 83 conout: 84 00000052 024100FF andi.w #$00ff, d1 85 00000056 00410300 ori.w #FC_CONOUT*256,d1 86 0000005A 3281 move.w d1,(a1) 87 0000005C 4E70 reset 88 0000005E 4E75 rts 89 90 00000060 .end BOOTSTART C P / M 6 8 0 0 0 A s s e m b l e r Revision 02.10 Page 3 Source File: boot68k.s S y m b o l T a b l e ArgByte 0007FDF1 ABS BLK_SIZE 00000200 ABS BOOTSTAR 00000380 ABS CPMLDR 00008000 ABS CR 0000000D ABS FC_CONIN 00000002 ABS FC_CONOU 00000003 ABS FC_CONST 00000001 ABS FC_EXIT 00000000 ABS FC_PUNCH 00000006 ABS FC_READ 00000004 ABS FC_READE 00000007 ABS FC_WRITE 00000005 ABS FuncNo 0007FDF0 ABS LDR_BLK 00000009 ABS LDR_SIZE 00001200 ABS LF 0000000A ABS OArgByte 00000001 ABS ORetVal 00000006 ABS OSdSec 00000002 ABS PICDMA 0007FE00 ABS PICWRK 0007FDF0 ABS RetVal 0007FDF6 ABS SEC_SIZE 00000080 ABS SdSec 0007FDF2 ABS _bo10 0000000C TEXT _bo20 00000014 TEXT _boot 00000000 TEXT conout 00000052 TEXT loop 00000028 TEXT rdcpy 00000036 TEXT startmes 00000044 TEXT M>


 Cold Boot Loaderのリンク結果をSDカードの先頭ブロックに、次のブロック以降にCPMLDRを入れれば、SDカードからCP/Mがブート可能となり、CP/Mの起動が非常に楽になります^^
 尚、アセンブルやリンクはCP/M-68Kシミュレータ上で行った方が作業的には楽だと思いますが、今回は昔のCP/M移植手順を楽しむという意味で敢えて実機上で行っています。
 まぁインターネット上の豊富な情報や当時と比べれば処理能力が桁違いに高いパソコンを使ってはいるのですが・・w

Cold Boot LoaderによるCP/Mの起動
:run ... loading CP/M-68K(tm) Version 1.3 08/05/85 Copyright (c) 1985 Digital Research, Inc. Pic24CPM-68K ver0.01 2018/09/23 by skyriver A>dir A: COPY REL : CPM SYS : DDT REL : DDT68000 68K : INIT REL A: PIP REL : README TXT : RELOC REL : RELOC SUB : RELOC1 SUB A: SD REL : STAT REL A>


[TOP] [ 前へ ] 連載記事 [ 次へ ]

nice!(0)  コメント(0)