PC-8001 SIO


PC−8001はSIOにμPD8251C(USART)を使用します。 CMT、シリアルソケットに繋がり、 シリアルソケットからRS−232Cとして使用出来ますが ターミナルモードの使用のみで、 N−BASICのRS−232C命令は使用出来ません。 N−BASICのRS−232C命令は オプション(PC−8011等)の為にあります。 ターミナルモードとCMTはポート020H〜021Hを使用 オプションのRS−232Cはポート0C1H〜0CFHを使用     PC−8001mkII、PC−8801では CMTはポート020H〜021Hを使用 ターミナルモード、RS−232Cもポート020H〜021Hを使用します。   CMTとシリアルソケット(他機種ではCMTとRS−232C)の切り換えは ポート030Hのd5−4のBS2、BS1の組み合わせになります。   PC−8001はボーレートは300/600ボーの切り換えなります PC−8001mkII、PC−8801では600/1200ボーの切り換えになります。  
主な設定 8251を使用する為にはコマンド指定で 内部リセット(IR=1)する必要があります。 リセットがかかるとモード設定が出来ますのでCMT等の設定を行います N−BASICでは8251の内部リセットが何時起きたのか分かりません そこでダミーのデーターをセットしてモード設定からコマンド指定 またはコマンド設定からコマンド指定して 次からのセットはコマンド指定(内部リセット)出来るようにしています    8251の内部リセット(N−BASIC内)   ポート021Hに00EH、040Hを出力      CMTロードの設定   8251の内部リセット後   ポート021Hに04EH(モードワード)、014H(コマンドワード)を出力    CMTセーブの設定   8251の内部リセット後   ポート021Hに0CEH(モードワード)、011H(コマンドワード)を出力    
使用ポート 020H:μPD8251データ 021H:μPD8251コントロール  コマンドワード(出力)   d7:EH   1=SYNCキャラクタの検出を始める、0=何もしない   d6:IR   1=内部リセットの実行       、0=何もしない   d5:RTS  1=センド要求を実行        、0=何もしない   d4:ER   1=全エラーフラグをリセット    、0=何もしない   d3:SBRK 1=ブレイクキャラクタの送信    、0=通常動作   d2:RxE  1=受信可             、0=受信不可   d1:DTR  1=データ・ターミナルレディを実行 、0=何もしない   d0:TxEN 1=送信可             、0=送信不可      EH   ハントイネーブル 同期モード時にSYNCキャラクタがくるの待つ    IR   内部リセット   8251をモード・ワード受け取り状態にする    RTS  センド要求    1で/RTS端子をLにする    ER   エラーリセット  PE、OE、FEを0にする    SBRK センドブレイク・キャラクタ 1でTxD端子をLとして通信ブレイク    RxE  受信イネーブル    DTR  データ・ターミナルレディ 1で/DTR端子をLにする    TxEN 送信イネーブル    ステータス(入力)   d7:DSR    1=レディ    、0=ビジィ   d6:SYNDET 1=キャラクタ検出、0=検出無し   d5:FE     1=エラー発生  、0=エラー無し   d4:OE     1=エラー発生  、0=エラー無し   d3:PE     1=エラー発生  、0=エラー無し   d2:T×E    1=エンプティ  、0=フル   d1:R×RDY  1=レディ    、0=ビジィ   d0:T×RDY  1=レディ    、0=ビジィ      DSR    データ・レディ     /DSR端子がLの時に1になる    SYNDET SYNCキャラクタ検出 SYNDET端子の内容    FE     フレミングエラー    ストップビットが検出されない    OE     オーバーランエラー   CPUがデータを読む前に次のデータが入った    PE     パリティエラー     入力データにパリティエラーの検出    T×E    送信バッファエンプティ TxEMPTY端子の内容    R×RDY  受信レディ       RxRDSY端子の内容    T×RDY  送信レディ       TxEN=1、/CTS=0の場合1    モードワード(出力)  非同期モード   d7:S2  ストップビット       11=2ビット、10=1+1/2ビット   d6:S1                01=1ビット、00=無効   d5:EP  偶数パリティ発生/チェック 1=偶数 、0=奇数   d4:PEN パリティ・イネーブル    1=実行可、0=実行不可   d3:L2  キャラクタ長        11=8ビット、10=7ビット   d2:L1                01=6ビット、00=5ビット   d1:B2  ボーレート         11=×64、10=×16   d0:B1                01=×1 、00=同期モード    同期モード   d7:SCS 単一キャラクタ同期     1=単一SYNCキャラクタ、0=ダブルSYNCキャラクタ   d6:ESD 外部同期検出        1=SYNDET入力、0=SYNDET出力   d5:EP  偶数パリティ発生/チェック 1=偶数 、0=奇数   d4:PEN パリティ・イネーブル    1=実行可、0=実行不可   d3:L2  キャラクタ長        11=8ビット、10=7ビット   d2:L1                01=6ビット、00=5ビット   d1:0   d0:0         030H(出力)  d7:未使用  d6:未使用  d5:CMT BS2  d4:CMT BS1  d3:CMT MOTOR 1=MOTORオン 、0=MOTORオフ  d2:CMT CHIN  1=マーク(2400Hz)、0=スペース(1200Hz)  d1:CRT 1=白黒、0=カラー  d0:CRT 1=80行、0=40行     BS2、BS1    11=SIO同期(使用しません)    10=SIO非同期(シリアルソケット)    01=CMT 300bps    00=CMT 600bps   040H(入力)  d7:未使用  d6:未使用  d5:CRT VRTC   1=垂直帰線期間、0=表示または水平帰線期間  d4:RTC μPD1990   DATA OUT  d3:EXP /EXTON 1=接続されていない、0=接続されている  d2:CMT CDIN CMTからのキャリア信号が検出されたら1  d1:PRT /STROBEを/PR、/ACKをCLK、D=0にしたFF(LS74)のQ  d0:PRT /READY    
CMTフォーマット FSKフォーマットで600ボー  ’1’になる波形 2400Hz 4サイクル  ’0’になる波形 1200Hz 2サイクル      1バイトデータの内容   ’0’、d0、d1、d2、d3、d4、d5、d6、d7、’1’、’1’      BASICファイル   ヘッダー部分    2.5秒のWAIT    0D3H*10    ファイルネーム6文字    0.1秒のWAIT   プログラム部分    プログラム本体((0EB54H、0EB55H)−(0EFA0H、0EFA1H)-1、最後は000H*3)    000H*10    1.3秒のWAIT      データファイル(PRINT#−1)    WAIT    09CH*6    データ、データ、...(データの区切りはカンマ)    WAIT      マシン語ファイル    3.8秒のWAIT    03AH    スタートアドレス(上位、下位の順)    チェックバイト NEG(アドレス上位+下位)      03AH    データ数(255バイト)    データ本体    チェックバイト NEG(データ数+データ本体の合計 MOD 256)         03AH    最終のデータ数    データ本体    チェックバイト NEG(最終のデータ数+データ本体の合計 MOD 256)      03AH    000H、000H    1.3秒のWAIT    *チェックバイトは合計で最下位1バイトが000Hになる値   <例>スタートアドレス0EA52Hの場合    ファイルの先頭03AH、0EAH、052H、0C4Hとなる    0EAH+052H+0C4H=00200H      
CMTのオートスタート CMTはコントロールはリモートのみなので オートスタートは出来ませんが プログラムで出来るだけオート化を図ります     BASICでマシン語のプログラムをロード、復帰または実行 I/O クレイジークライマー(エンパイアクライマー)の場合   まずBASICプログラムをロード、実行 マシン語プログラムがあるかPEEK文で判断する マシン語プログラムがあればメインへ、無ければロードプログラムを実行する    ロードプログラム   A$="MON"+CHR$(13)+"L"+CHR$(13)+CHR$(2)+"RUN"+CHR$(13)+CHR$(0)   A=VARPTR(A$)+1:POKE&HEDC0,PEEK(A):POKE&HEDC1,PEEK(A+1):POKE&HEA68,1   A$があるアドレスをVARPTRで取得 そのアドレス+1をファンクションキーのポインタとして設定 ファンクションキーフラグをオンにして A$の内容をファンクションキーを押したとみなされます つまりプログラム中でファンクションキーを押したように    MON  L  ^B  RUN   を実行します ロード中はキーを押したとはみなされないので ロード終了後に残りのコマンドが実行されます そして再び1本目のプログラムをRUNするのですが 今度はマシン語プログラムがロードされているので ロードプログラムは実行されずにメインルーチンへ飛びます 短所としてBASICプログラムをロードするのに ファイルネームを指定しなければいけません       ワークエリアをロードしてファンクションキーフラグをオンにする ポニカ ザ・レーサーの場合   1本目のIPLプログラムが0EA68H−0EACAHなので ロード終了後0EA68Hが001Hに書き換えられ ファンクションキーフラグがオンになります デフォルトでファンクションキーのポインタは    EDC0:C0 EA   となっており0EAC0H以降がファンクションキーの内容になります    EAC0:0D 0D 0D 6C :...l  EAC4:0D 67 65 63 :.gec  EAC8:63 30 0D    :c0.    L  GECC0   つまりIPLロード終了後、ファンクションキーを押したと判断して L[RET]を実行、ロード終了後、残りのファンクションキーの内容 GECC0[RET]を実行してゲームがスタートします BASICでVARPTRを使用したのを直接CMTロードで ワークエリアをロード(書き換え)してロード終了後に ファンクションキーを押した状態にするタイプです     マシン語ファイルをロード、終了後に実行   マシン語をロード、終了しだい実行されます スタック領域までロードされロード終了後、 本来ならモニタに帰る所をゲームプログラムの実行に ロードデータで書き換えられてしまっているので モニタへ戻らずにゲームが実行される仕組みです   MON、Lを実行するとスタック内0E8CBH−0E8CCHが 帰り値(05DE1H)を実行したいアドレスにロードして内容を書き換えます 帰り値 05DE1Hということは Lコマンド内05DDEHのCALL 05F3AHから帰るアドレスで 05F3AHはCMTロードルーチンになります つまりロード終了後、即ゲームプログラムが実行されます ただしモータはストップされないのでゲームプログラムの方でストップを行います スタックはモニタに移行すると再設定されるので 書き換えるスタックアドレスが変わる心配はありません ただしCLEAR文でマシン語領域を確保されるとスタック位置が変わる為 オートスタート出来なくなります   HAL研のジュピターランダーでは0C69CH−0E8FFHまでロードされ 0E8C8H−0E8FFHは0D7Hで埋まっている ロードが終了すると0E8CBH−0E8CCHが0D7H、0D7Hに 書き換わっているのでロード終了後0D7D7Hへジャンプします   FAN FUN、ザクサスのIPL部分が同じタイプになります     BASICファイルにマシン語データを埋め込む   BASICファイルは000H×10が見つかるまで ロード、メモリストアを行い続けます 終了後000H×10が書かれたアドレスが変数領域に設定されます   これを利用してプログラムの最終アドレス、変数領域アドレスを設定しなおして BASICプログラムの後ろにマシン語プログラムを埋め込み、セーブされたタイプです ただしデータ等000H×10以上は置けません どうしても必要になる場合、プログラムで構築、展開する必要がありますが その場合、変数領域アドレスを再設定しなければなりません     オリジナルフォーマット   マリオブラザース(ウェストサイド)   <テープの内容> IPLプログラム ローダー メイン(オリジナルフォーマット)     ワークエリアをロードしてファンクションキーフラグをオン ローダープログラムをロード、実行 メインプログラムは1ブロック(255バイト)+1 ロードすると1ブロック毎に1文字画面表示される   メインプログラムのフォーマット  ヘッダ    03CH  アドレス上位  nn      下位  mm  チェックサム(NEGヘッダ含まず)    ヘッダ    03CH  データ長    nn  データ  ロードメッセージ(1バイト)  チェックサム(NEGヘッダ含まず)     |  ヘッダ    03CH  エンドマーク 000H         000H     THE FAR WAY(ブレインメディア) <テープの内容> IPL兼ローダ 画面データ(オリジナルフォーマット) BASIC(オリジナルフォーマット)     ワークエリアをロードしてファンクションキーフラグをオンにして ファンクションキーポインタも0EDD0Hに上書き GEA7CでIPL内のローダ部分を実行 BASICプログラムをロードしたらBASICコマンドフックでRUN     画面、BASICプログラムのフォーマット  ヘッダ    088H×5  スタートアドレス下位、上位  エンド アドレス下位、上位  データ     スーパーペンギン (マイコンセンターRAM) <テープの内容> IPL兼ローダ マシン語プログラム(オリジナルフォーマット)     ワークエリアをロードしてファンクションキーフラグをオンにして ファンクションキーポインタも0EA77Hに上書き GEA7DでIPL内のローダ部分を実行 プログラムのロード終了後 IPL内のゲームプログラム一部(9バイト)を転送 STOP+RESET(ホットスタート)のアドレスを変更後 ゲームスタート   マシン語プログラムのフォーマット  ヘッダ    06EH  アドレス上位  nn      下位  mm  チェックサム(NEGヘッダ含まず)    ヘッダ    06EH  データ長    nn  データ  ロードメッセージ(1バイト)  チェックサム(NEGヘッダ含まず)     |  ヘッダ    06EH  エンドマーク 000H         000H     PC−8001mkII用 ロードランナー(システムソフト) <テープの内容> BASIC  ローダー(プログラム隠避、マシン語埋め込み) データ1   オリジナルフォーマット1 データ2   オリジナルフォーマット1 プログラム1 オリジナルフォーマット1 プログラム2 オリジナルフォーマット1 データ3   オリジナルフォーマット1 データ4   オリジナルフォーマット1 面データ01 オリジナルフォーマット2 面データ02 オリジナルフォーマット2 面データ03 オリジナルフォーマット2 面データ04 オリジナルフォーマット2 面データ05 オリジナルフォーマット2 面データ06 オリジナルフォーマット2 面データ07 オリジナルフォーマット2 面データ08 オリジナルフォーマット2 面データ09 オリジナルフォーマット2 面データ10 オリジナルフォーマット2 面データ11 オリジナルフォーマット2 面データ12 オリジナルフォーマット2 面データ13 オリジナルフォーマット2 面データ14 オリジナルフォーマット2 面データ15 オリジナルフォーマット2     BASICのローダ部分は行番号0FFFFHで隠されている  80BB:E8 03 でローダ部分の可視が出来る   BASICは更にマシン語が埋め込まれており 08400H−084C4Hがマシン語部分になる データ、プログラム等のアドレス指定はBASIC上で スタート、エンドアドレスの指定、ロード後に裏RAMに転送 面データは10面分のデータとなる    オリジナルフォーマット1   ヘッダ    03AH   データ長   nn   データ   チェックサム(NEG、ヘッダー除く)      |   ヘッダ    03AH   エンドマーク 000H          000H    オリジナルフォーマット2   ヘッダ    0D3H×10   ファイルネーム6バイト     ヘッダ    03AH   データ長   nn   データ   チェックサム(NEG、ヘッダー除く)      |   ヘッダ    03AH   エンドマーク 000H           000H     PC−8001mkII用 タイムシークレット(ボンドソフト) <テープの内容> BASIC ローダー(プログラム隠避) プログラム オリジナルフォーマット     BASIC部分で見る事が出来る範囲はタイトル表示部分までで ローダーのDATA(マシン語)、USR文等の実行部分は隠避されています ローダー部分はA面は1200bps、B面は 600bpsタイプになっています プログラムロードが終了するとCMTクローズ、スタック設定 ローダにあるCMTルーチンを裏RAM 07700Hに転送して 082F8Hの内容をジャンプしてゲームが始まります    ヘッダ     0AAH  スタートアドレス00000H (上位、下位の順)  チェックバイト NEG(アドレス上位+下位)    ヘッダ     0AAH  データ数    0FFH(255バイト)  データ本体  チェックバイト NEG(データ数+データ本体の合計 MOD 256)   |  ヘッダ     0AAH  最終のデータ数  データ本体  チェックバイト NEG(最終のデータ数+データ本体の合計 MOD 256)    ヘッダ     0AAH          000H     PC−8001mkII用 パンチボール マリオブラザース(ハドソン) <テープの内容> マシン語  ローダー プログラム オリジナルフォーマットNONTAMA     ローダーは0E4CBHから始まっています N80−BASICはN−BASICに比べ 0400Hワークエリアが取られるのでスタックも0400H分前にずれます つまりマシン語ファイルをロード、終了後に実行するタイプで 0E4CBH−0E4CCHがモニタに帰る所を ローダーをロードした時点で書き換えられているので ロード終了後、実行されます ローダーにはCMT読み込みルーチンがあり オールRAMにして0100Hからロードする様になっています プログラム本体は暗号化され単純なテープダンプでは判らない様にしてあります   最初にXORデータ0A3Hがローダー側でセットされ 1バイト目リードデータとXOR 0A3Hを行いメモリにストア 2バイト目リードデータとXOR 1バイト目リードデータを行いメモリストア... 以降、最終アドレスまで繰り返します 尚、チェックサムはXORで変換されたデータ総合計の最下位1バイトになります    ・―――――――――――――――――――・  |ロード値    前のロード値|ストア値|  |――――――――――――――+――――|  |060H XOR *0A3H|0C3H|  |00CH XOR  060H|06CH|  |009H XOR  00CH|005H|  |      :       | :  |  |      :       | :  |  ・―――――――――――――――――――・  *ローダーで設定された値    プログラム本体(暗号化)の先頭部分   60 0C 09 29 09 5F 1A 48   1B 52 1D 53 73 42 62 53   6A 52 66 46 76 4E 6E 5F   6E 4E 0C 55 75 3E 77 3C       ↓  メモリにストアされるプログラムの先頭部分   C3 6C 05 20 20 56 45 52   53 49 4F 4E 20 31 20 31   39 38 34 20 30 38 20 31   31 20 42 59 20 4B 49 4B   オリジナルフォーマットの内容  0FFH      ;テープヘッダ  NONTAMA   ;文字列  000H,001H ;先頭アドレス   00100H  000H,06CH ;最終アドレス+1 06C00H  000H,001H ;実行アドレス   00100H  06CH〜     ;プログラム本体(暗号化)       033H ;  02EH      ;チェックサム 1バイト  000H×11   ;エンドマーク(チェックは10個)     PC−8001mkII用 野球狂(ハドソン) <テープの内容> BASIC ローダー(プログラム隠避) プログラム オリジナルフォーマットNONTAMA     画面設定等BASICで行い 後ろに隠避されているマシン語を実行を行います ローダー本体は0E800Hへ転送、実行 プログラム自身はパンチボールとほぼ同様ですが NONTAMAの後の先頭アドレス〜実行アドレス6バイトの チェックサム1バイトがあります 最初にXORデータ0A3Hを用意して 1バイト目リードデータとXOR 0A3H 2バイト目リードデータとXOR 1バイト目リードデータ... となりますがメモリ読み込みROM、メモリ書き込みRAMにして 1バイト読み込みをしたらXORで変換したデータで チェックサムを行い、そのチェックサムを画面に表示します チェックサムはXORで変換されたデータ総合計の最下位1バイトになります    プログラム本体(暗号化)の先頭部分   92 92 93 5E 0D 1A D7 F2   E8 25 25 7D B0 12 0C C1   F9 E3 2E E0 F3 3E 9D 88   B6 B7 85 C8 9E 53 BD E8        ↓  メモリにストアされるプログラムの先頭部分   31 00 01 CD 53 17 CD 25   1A CD 00 58 CD A2 1E CD   38 1A CD CE 13 CD A3 15   3E 01 32 4D 56 CD EE 55     オリジナルフォーマットの内容  0FFH      ;テープヘッダ  NONTAMA   ;文字列  000H,001H ;先頭アドレス   00100H  000H,0B2H ;最終アドレス+1 0B200H  000H,001H ;実行アドレス   00100H  0B4H      ;先頭〜実行アドレスのチェックサム  092H〜     ;プログラム本体(暗号化)       0E4H ;  033H      ;チェックサム 1バイト  000H×12   ;エンドマーク(チェックは8個)     PC−8001mkII用 ガンマン(ハドソン) <テープの内容> マシン語  ローダー プログラム オリジナルフォーマット     ローダーは上記のパンチボールと同様0E4CBHから始まっています 0E4CBH−0E4CCHがモニタに帰る所を ローダーをロードした時点で書き換えられているので ロード終了後、実行されます ローダーにはCMT読み込みルーチンがあり 他機種のHu−BASICに近いファイルフォーマットを ロード、実行を行います プログラムはインフォメーションとデータに分けられ チェックサムというより1バイトごとリードデータを元に XORで変化されたチェックコードを採用されています インフォメーションはサイズ、ロードアドレスだけ使用 プログラムロード終了後、ロードアドレスを実行されます 暗号化はされていません    0D3H      16バイト  ’F’       1バイト  001H      FCB  001H      1バイト(ファイルタイプ?)  ファイルネーム   16バイト  予備?       1バイト(パスワード?)  サイズ       2バイト  ロードアドレス   2バイト  実行アドレス    2バイト  チェックコード   1バイト      0D3H      16バイト  ’F’       1バイト  002H      データ  データ   :  チェックコード   1バイト    
PC−8001のコーナへ Home へ戻る