DB-Z, PV-F1, PI-3000, PI-4000 (ZAURUS) BASIC Tips Volume 4 Copyright(c)1988,1995 E.Kako & COR.(H.Ogasawara)  このドキュメントは「短期集中強制SC62015講座」として小笠原氏が書いた原稿に、私 (加古)が若干の手を加えた物です。  LH5801が「分かりやすさ、使いやすさ」ならSCは「ユニークさ」が特徴の変わり種CPU である。今回の新SCもその構成において、強力かつアンバランスなところが実に嬉しい 。PJ4月号に詳しい表が載っているが、どんな命令があり、どんなことができるかは分か りにくくなっている。そこでニモニックレベルでまとめて全体を見通せるようにするの が、今回の講座の目的である。実際にプログラムを組むときは、PJ4号(1988年)が必要だ が、その代わり他機種のユーザーが読んで興味をもってもらいたい。まだまだ謎めいたC PUであり、独自の解釈と解析を交えながらこの講座を進めていくことにする。 ○用語 n : 1バイト定数 mn : 2バイト定数 lmn : 3バイト定数 r3 : レジスタ X,Y,U,S (x) : 内RAM アドレッシングは(n),(BP+n),(BP+IX),(IX+n) (y) : 内RAM アドレッシングは(n),(BP+n),(BP+IY),(IY+n) (a) : 内RAM アドレッシング全ての場合の総称とする [〜] : 括弧内から任意のものを選べる ○内RAMアドレッシングモード (n) : 1バイトの値による直接指定 (BP+n) : ベースポインタ+8ビットオフセット (BP+IX): ベースポインタ+IX (BP+IY): ベースポインタ+IY (IX+n) : IX+8ビットオフセット (IY+n) : IY+8ビットオフセット ○外部メモリアドレッシングモード [lmn] : アドレスlmnのメモリ内容 [r3] : レジスタ(X,Y,U,R)によるメモリ指定 [r3++] : オートインクリメント、メモリの内容を参照したあとレジスタの値を増やす [--r3] : オートデクリメント、レジスタの値を減らしたあとメモリの内容を参照 [r3+n] : レジスタの値+8ビットオフセット [r3-n] : レジスタの値−8ビットオフセット [(a)] : 内RAM3バイトで示すアドレスの内容 [(a)+n] : 内RAM+8ビットオフセット 内RAMにはさらにアドレッシング [(a)-n] : 内RAM−8ビットオフセット モードが存在する ○レジスタ  レジスタ構成は次のようになっている。数はそんなに多くないが実際は内RAMもレジス タみたいなもので、レジスタを使わずにプログラムを書ける場合も多い。 A 8ビット アキュームレータ、Bとペアで16ビットのBAレジスタとしても使う B 8ビット Aとペアで使う、単独で使うことはまず無い I 16ビット カウンタ、下位8ビットをILレジスタとして使うことができる X 20ビット 汎用レジスタ、ポインタとして1Mバイトのメモリ空間をアクセス Y 20ビット  できる、下位8/16ビットだけの処理も一部命令で可能 U 20ビット ユーザースタックポインタである S 20ビット スタックポインタ PC 16ビット プログラムカウンタ、PSとセットで1Mバイトの空間をアクセスする PS 4ビット PCとは独立している、実行するプログラムのページが入る Z 1ビット ゼロフラグ あわせて1バイトのFレジスタになる C 1ビット キャリーフラグ ビット0がキャリー、ビット1がゼロ ○内RAM上の特殊なレジスタ(解析は独自のもの、不明な点が多い) BP (EC)1 ベースポインタ、内RAMのポインタになる IX (ED)1 内RAMのインデックスポインタ IY (EE)1 内RAMのサブインデックスポインタ AMC (EF)1 ADR.MODIFY CONTROL 使われ方不明 KO (F0)2 キーストローブ信号出力、E500ではSIOにも使われている KI (F2)1 キー信号の入力、キー割り込み機能(2種)ももっている EO (F3)2 汎用I/O出力、11ピンコネクタやSIOにも使われている EI (F5)2 汎用I/O入力 UCR (F7)1 シリアルポートUARTのコントロール→表1 USR (F8)1 受信状態 RXD (F9)1 UART受信バッファ TXD (FA)1 UART送信バッファ IMR (FB)1 割り込みのマスクレジスタ(マスクはソフトウェアによる) ISR (FC)1 割り込みモード SCR (FD)1 システムコントロール CMT,タイマ等 LCC (FE)1 LCD CONTRAST CONTROL(E500では未使用と思われる) SSR (FF)1 システムのモードが入る(?) 表1 UARTコントロールレジスタ ビット0 ストップビット 0...1 1...2 ビット1 ビット長 0...8ビット 1...7ビット ビット2,3 パリティ 0...Even 1...Odd 2...なし ビット4,5,6 ボーレート 1...300 2...600 3...1200 4...2400 5...4800 6...9600 ○データ転送  新SCはMVひとつのニモニックだけでLD,ST,MV等の意味を含み、このMVだけにやたらと多 くのアドレッシングモードがある。 <レジスタへの転送> MV A ,[ n, B, (x)1,[lmn],[r3],[++r3],[r3--],[r3+n],[r3-n],[(x)],[(x)+n],[(x)-n] ] MV IL ,[ n, (x)1,[lmn],[r3],[++r3],[r3--],[r3+n],[r3-n],[(x)],[(x)+n],[(x)-n] ] MV BA ,[ mn, I,X,Y,U.S, (x)2,[lmn],[r3],[++r3],[r3--],[r3+n],[r3-n],[(x)],[(x)+n],[(x)-n] ] MV I ,[ mn, BA,X,Y,U.S,(x)2,[lmn],[r3],[++r3],[r3--],[r3+n],[r3-n],[(x)],[(x)+n],[(x)-n] ] MV X ,[ lmn, BA,I,Y,U,S, (x)3,[lmn],[r3],[++r3],[r3--],[r3+n],[r3-n],[(x)],[(x)+n],[(x)-n] ] MV Y ,[ lmn, BA,I,X,U,S, (x)3,[lmn],[r3],[++r3],[r3--],[r3+n],[r3-n],[(x)],[(x)+n],[(x)-n] ] MV U ,[ lmn, BA,I,X,Y,S, (x)3,[lmn],[r3],[++r3],[r3--],[r3+n],[r3-n],[(x)],[(x)+n],[(x)-n] ] MV S ,[ lmn, BA,I,X,Y,U, (x)3,[lmn] ] ・定数を除いて、逆に右辺にレジスタの値を代入することも可能。 ・ILへ代入する場合、1レジスタの上位バイトには必ず0が入る。つまりIレジスタへ16ビ ットに拡張されるわけだが、符号拡張までは行われない。 ・サイズの異なる場合(24-20-16ビット間)は、大きい方の上位4ビットが捨てられる、も しくは大きい方の上位4ビットには0が入る。 <内RAMへのデータ転送> MV (x)1, [n, (y)1, [lmn],[r3],[++r3],[r3--],[r3+n],[r3-n],[(y)],[(y)+n],[(y)-n] ] MVW (x)2, [mn, (y)2, [lmn],[r3],[++r3],[r3--],[r3+n],[r3-n],[(y)],[(y)+n],[(y)-n] ] MVP (x)3, [lmn, (y)3, [lmn],[r3],[++r3],[r3--],[r3+n],[r3-n],[(y)],[(y)+n],[(y)-n] ] MVL (x)i, [ (y)i, [lmn], [++r3],[r3--],[r3+n],[r3-n],[(y)],[(y)+n],[(y)-n] ] MVLD (x)i, [ (y)i ] ・レジスタについては省略。(前に出ている) ・左辺から右辺への代入も可能。この場合(x)と(y)が逆になる。 ・MVLDは前に戻りながら転送する。(Z80のLDDRみたいなもの) ○データ交換 EX [ BA, I, X, Y, U, S ] , [ BA, I, X, Y, U, S ] EX A , B EXW (x)2 , (y)2 EXP (x)3 , (y)3 EXL (x)i , (y)i ○スタック関係  スタックポインタは2本ある。そのうちSがCALL,RETなどのシステム関係、Uが主にデー タの退避に使われる。そのため、サブルーチンへの引数をスタックで渡すことも可能。 PUSHU/POPU [ A,IL,BA,I,X,Y,F,IMR ] PUSHS/POPS F  これらのみ1バイトの命令で行える。Sのスタックにもレジスタの値をPUSH,POPできる が、OPコードは「MV [--S],R」や「MV R,[S++]」と全く同じものであり、2種類のニモニ ックを持っているにすぎない。拡大解釈すれば、X,Yレジスタもスタックポインタとして 使え、また内RAMの値も直接PUSH,POP可能だということである。全て書き出すと次のよう になる。(IMRも内RAMの一部である) PUSHX/POPX [ A,IL,BA,I, Y,U, (x)1,(x)2,(x)3,(x)i ] PUSHY/POPY [ A,IL,BA,I,X, U, (x)1,(x)2,(x)3,(x)i ] PUSHU/POPU [ A,IL,BA,I,X,Y, F, (x)1,(x)2,(x)3,(x)i ] PUSHS/POPS [ A,IL,BA,I,X,Y,U,F,(x)1,(x)2,(x)3,(x)i ]  CALL命令は2種類用意されている。同一ページ内のサブルーチンを呼ぶときはアドレス を2バイトで指定でき、メモリを食わないようになっている。そのかわりRET命令も専用に なり、CALLとの対応を間違えると暴走する。 CALLF lmn CALL mn (同一ページ内でのみ使用可能) RETF (CALLFの戻り、BASICに戻るときもこれ) RET (CALLの戻り) RETI (割り込み処理での戻り) ○ジャンプ命令  絶対番地ジャンプにはCALL同様全メモリエリアに飛べるものと同一ページ内だけで飛べ るものとがある。ただし、条件付の場合は同一ページ内のみ。 JPF lmn (全メモリエリア) JP mn (同一ページ内) JP [ r3, (x)3 ] JPZ/JPNZ mn JPC/JPNC mn  相対ジャンプは旧SCと同じように9ビットの範囲へ飛べる。ただし、オペランドの計算 方法が旧SCと少し異なる。 JR n JRZ/JRNZ n JRC/JRNC n ○加減算  かなり強力。ADCL,SBCLを使えば簡単に任意のバイト数の加減算ができる。レジスタ間 の演算では、8,16,20のうち、好きなビット長を選べる。Xレジスタの下位8ビットにだけ 加算したり、IレジスタにYの下位16ビットだけ加える、ということも可能。DADL,DSBLは 、BCDによる10進演算。ADCL,SBCLと違い、指定アドレスから前の方に向ってメモリが取ら れるので注意。(BCDはアドレスの低い方が、位が高くなる) ADD/SUB A , [ n,IL,I,X,Y,U,S,(x)1 ] ADD/SUB [IL,BA,I,X,Y,U,S] , [A,IL,BA,I,X,Y,U,S] ADD/SUB (x)1 , [ n,A ] ADC/SBC A , [ n,(x)1 ] ADC/SBC (x)1 , [ n,A ] ADCL/SBCL (x)i , [ A,(y)i ] DADL/DSBL (x)i , [ A,(y)i ] INC/DEC [ A,IL,BA,I,X,Y,U,S,(x)1 ]  この他にPMDFという命令がある。フラグの変化しない加算だと解釈しているがよく分かっていない。 ○論理演算  加減算とは逆にレジスタ処理が弱い(無い)。 AND/OR/XOR A , [ n,(x)1 ] AND/OR/XOR (x)1 , [ n,A,(y)1 ] AND/OR/XOR [lmn] , n TEST A , [ n,(x)1 ] TEST (x)1 , [ n,A ] TEST [lmn] , n ○比較命令  CMPWのときX,Y,U,Sレジスタは、下位16ビットのみ比較される。CMPPの比較は24ビット で行われ、レジスタの足りない上位ビットは0とみなされる。 CMP A , n CMP (x)1 , [ n,A,(y)1 ] CMP [lmn] , n CMPW (x)2 , [ BA,I,X,Y,U,S,(y)2 ] CMPP (x)3 , [ BA,I,X,Y,U,S,(y)3 ] ○シフト、ローテイト命令  SWAPは、上位4ビットと下位4ビットを入れ換えるのだが、4ビットのローテイトとも考 えられるのでここに入れた。DSLL/DSRLは、内RAMブロックの4ビットシフト。BCD演算用に 設けられたと思われる。DSLLは、指定メモリから前の方へ向ってシフトが行われるので、 注意が必要。 SHR/SHL [ A,(x)1 ] ROR/ROL [ A,(x)1 ] DSLL/DSRL (x)i SWAP A ○その他命令 NOP (1サイクルなにもしない、OPコードはZ80と同じ00) WAIT (Iレジスタの値だけWAIT、I+1サイクル) SC (C=1) RC (C=0) HALT (メインクロック ストップ) OFF (メイン,サブクロック ストップ) RESET (ソフトウェアによるリセット) IR (ソフトウェアによるインタラプト) TCL (不明) ○最後に  現在わかっている隠れ機能等もできるだけ含めてあるが、あくまで独自の解析であり、 今後訂正、拡張される可能性は十分ある。この連載に関する質問等は、私の所へお願いし ます。