SSブログ
English Version

レトロマイコンZ80ボードの構想(その15)エスケープシーケンスの実験 [Z80]

 前回の「レトロマイコンZ80ボードの構想(その14)CP/MでのWM動作実験」ではWordMasterにANSIエスケープコード用のパッチを入れて動かしましたが、今回はPIC側のCONOUT処理に次のエスケープシーケンスの処理を入れてみました。
  • 画面クリア : ESC+'*'
  • カーソル位置制御 : ESC+'='+nm
    n:Y position,m:X position(position offset:20H)

 picleソース側への追加なので前回記事のような限られた領域にZ80のコードを詰め込むより簡単です。

 試しに ここ から QTITRIS.COM(キャラクタ版テトリス)をダウンロードして動かしてみました。

 下記の操作ログはエスケープシーケンスのサブセット対応(37行目~73行目部分)したpicleのリストを表示後、runコマンドで実行し、CP/Mブート後、QTITRISを起動している様子です。


簡易的なエスケープシーケンス対応実験ログ
:l 1:# CP/M boot test for PIC24FJ64GA004 with picle 2:# Ver 0.03 by skyriver 2018/03/21 3: 4:use LibCpm; 5:use LibSpi; 6: 7:var ProgStart,ProgWrk,_WrkVal,_PicDma; 8:var EscFlg,EscY; 9: 10: 11:proc PicSrv() { 12: var i,fno,rval; 13: 14: while (1) { 15: while ( LATB[-1] & 8 ) {} # wait halt 16: PmpOn(); 17: PmpSetAdr( ProgWrk ); 18: fno = MemRd(); # dummy 19: for ( i=0; i<9; i=i+1 ) { 20: _WrkVal[i] = MemRd(); 21: } 22: fno = _WrkVal[0]; # function No 23: if ( fno = 1 ) { # CONST 24: if ( InpChk_() ) { 25: rval = $ff; 26: } else { 27: rval = 0; 28: } 29: } 30: else if ( fno = 2 ) { # CONIN 31: if ( InpChk_() ) { 32: rval = InpChar_(); 33: } else { 34: rval = InpChar_(); 35: } 36: } 37: else if ( fno = 3 ) { # CONOUT 38: var c; 39: c = _WrkVal[2]; 40: if ( EscFlg = 0 ) { 41: if ( c = $1b ) { 42: EscFlg = 1; 43: } 44: PrnChar_( c ); 45: } 46: else if ( EscFlg = 1 ) { 47: if ( c = '*' ) { # clear screen 48: PrnStr_( "[2J" ); 49: PrnChar_($1b); 50: PrnStr_("[1;1H"); 51: EscFlg = 0; 52: } 53: else if ( c = '=' ) { # move cur 54: EscFlg = 2; 55: } else { 56: PrnChar_( c ); 57: EscFlg = 0; 58: } 59: } 60: else if ( EscFlg = 2 ) { 61: EscY = c - $1f; 62: EscFlg = 3; 63: } 64: else if ( EscFlg = 3 ) { 65: PrnChar_( '[' ); 66: PrnDec_( EscY ); 67: PrnChar_( ';' ); 68: PrnDec_( c - $1f ); 69: PrnChar_( 'H' ); 70: EscFlg = 0; 71: } 72: rval = 0; 73: } 74: else if ( fno = 4 ) { # READ 75: var track; 76: track = _WrkVal + 4; 77: rval = BlkRead( track[0]*64 + _WrkVal[8] ); 78: if ( rval = 0 ) { 79: PmpSetAdr( _PicDma ); 80: for ( i = 0; i < 128; i=i+1 ) { 81: MemWr( _SpiBuf[ i ] ); 82: } 83: } 84: } 85: else if ( fno = 5 ) { # WRITE 86: var track; 87: track = _WrkVal + 4; 88: PmpSetAdr( _PicDma ); 89: i = MemRd(); # dummy 90: for ( i = 0; i < 128; i=i+1 ) { 91: _SpiBuf[ i ] = MemRd(); 92: } 93: rval = BlkWrite( track[0]*64 + _WrkVal[8] ); 94: } else { 95: PrnStr_( "\nFunc err" ); 96: } 97: PmpSetAdr( ProgWrk + 1 ); 98: MemWr( rval ); 99: 100: PmpOff(); 101: LATC[0] = $0000; # reset on 102: BusRelease(); 103: LATC[0] = $0001; # reset off 104: } 105:} 106: 107: 108:proc main() { 109: var i; 110: init(); 111: initPmp(); 112: initSpi(); 113: initSd(); 114: 115: ProgStart = $0100; # Prog start addr 116: ProgWrk = $ff70; # Prog work addr 117: _PicDma = $ff80; 118: _WrkVal = Alloc( 5 ); 119: 120: if ( BlkRead( 0 ) <> 0) { 121: PrnStr_( "NG" ); 122: SetCsOff(); 123: } else { 124: SetCsOff(); 125: PmpOn(); 126: 127: PmpSetAdr( 0 ); 128: MemWr( $c3 ); 129: MemWr( ProgStart ); 130: MemWr( ProgStart / 256 ); 131: 132: PmpSetAdr( ProgStart ); 133: for ( i = 0; i < 128; i=i+1 ) { 134: MemWr( _SpiBuf[ i ] ); 135: } 136: PmpOff(); 137: LATC[0] = $0000; # reset on 138: BusRelease(); 139: LATC[0] = $0001; # reset off 140: PicSrv(); 141: } 142:} :run loading... 64k CP/M Version 2.2 COPYRIGHT (C) 1979, DIGITAL RESEARCH a>dir A: ASM COM : BIOS ASM : CPM SYS : DDT COM A: DEBLOCK ASM : DISKDEF LIB : DSKMAINT COM : DUMP ASM A: DUMP COM : ED COM : LOAD COM : PIP COM A: READ ME : STAT COM : SUBMIT COM : WM HLP A: XMODE PRN : XSUB COM : D COM : XMODEM PRN A: XMODEM HEX : XMODEM2 ASM : XMODEM COM : DUMP PRN A: XMODEM CFG : XMODEM ASM : DUMP HEX : XMODE HEX A: XMODE REL : XMODE ASM : XMODE COM : XMODE BAK A: WMM COM : M80 COM : L80 COM : QTITRIS COM A: QUATRIS SCO : ESCTEST TXT : STDESC PRN : STDESC HEX A: LINE TXT a>QTITRIS



 テトリスが起動した画面のキャプチャが下の画面です。
 数字キーで操作するので結構難しい(Z80が16MHz動作なので最低速設定にしても早すぎる・・)
 因みにWordStarは他にも表示属性設定等のエスケープシーケンスを使っているのできれいな画面にはなりませんでしたが、PIC側で対応するのは容易だと思います。

 WindowsとCP/M間のファイルのやり取りは前回記事のコメント欄にも書いたようにCP/M側でXMODEMというアプリを使っています(Windows側はTeraTermのXMODEM送受信機能を使用)。
 ファイルのやり取りの際、SDカードを経由する必要がなくなったので便利になりましたが、私の環境では大きなファイルの転送に失敗(オプション指定でZ80のクロック設定しても駄目)することがあるので対策を考え中です。
 PIC側に今回のようなコンソールデータの変換ロジックを入れるとバイナリデータの透過性が保証できなくなる問題が新たに発生します。(転送にはPUN:ディバイスを使えば解決できるけどね)

QTITRIS画面


★2018/03/24 追記
 下記のエスケープシーケンスを対応したことで無事 WordStar が動きました。
  • ESC+'C'+'0' : Reverse off(たぶん・・^^;)
  • ESC+'C'+'1' : Reverse on
  • ESC+'B'+'0' : Bold off
  • ESC+'B'+'1' : Bold on

 ANSIエスケープコードへの変換としては Reverse をそのままReverseに変換したところ、WordStarを終了してもReverseのままになったのでItalic(ESC+'[3m')に変換しています(TeraTermでは画面上は変化なし)。
 BoldはANSIのBold(ESC+'[1m')に変換していますがTeraTermでは文字が黄色になります。(設定で変更可能らしい)

 この頃のディスプレイはまだカラー化していないのでモノクロで識別可能な表示属性になっていますが、今ならエスケープシーケンスを色付きに対応させた方が見易くていいです(当時の状態の再現という観点では好ましくないかも)

 私は普段、秀丸エディタを使っていますが、今でもWordStarライクな操作にカスタマイズしています。
 WordStarを改めて使ってみると、今でもあまり遜色なく使えるエディタであることに驚かされました。

 WordStarのソースコードはアセンブラで13万7000行あり、開発者のRob Barnabyさんはこれを4ヵ月で作ったのだそうです。平均的な生産性で換算すると42人が1年かけて開発する規模だということです。すご~ぃですね。

 WordStarの画面はこんな感じです。

WordStar画面


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

nice!(0)  コメント(0) 
共通テーマ:趣味・カルチャー