楽天市場
[無料でホームページを作成] [通報・削除依頼]

PICで電大版TINYBASIC 実装編その3

<実装編その3:BASICインタープリタの移植2>

前ページから続きます。
③変数の割付けアドレスの検討
先述しましたが6800のコードでは変数が$1A~$FFのアドレスに割付けられています。
6800においてはこれら全ての変数にDirect命令が適用でき、短いコードでアクセスできます。
一方エンハンスドミッドレンジのPICの場合,バンクは0のままでバンク切り替えしないことを前提にすると
最短のコードでアクセスできる領域はバンク0のRAM(0x20~0x6F)とバンク共通RAM(0x70~0x7F)を
合わせた96バイトとなります。
そこで、6800のコードでDirect命令を使用している変数のみバンク0に配置し、
残りの変数はバンク1以降に配置してFSRで間接アドレッシングすることを考えました。

検討結果を以下に示します。
右側でコメントアウトしているのがオリジナルコード、左側がPICのコードです。

注意1.変数RAMENDは使用していません。
注意2.BUFFER以降80バイトを変数FORSPの後ろに移動しています。
注意3.BASICで使用するA~Zの変数領域がオリジナルの0x82から0x38に移動しています。
       インタープリタのコードはこの領域が0x82に存在することを前提に作成されていますが、
       インタープリタをPICに移植する際にインタープリタ側のコードを修正します。
注意4.変数SUBSPとFORSPはバンク共通RAM(0x70~0x7F)に移動
注意5. BUFFER以降の領域にはFSRアドレスを割り当てます。(BUFFERの実アドレスは0xA0)

    cblock    0x20                 ;        ORG    $001A
    V:2                   ;0x20    ;V       RMB    2
    _W:2                  ;0x22    ;W       RMB    2
    _Z:2                  ;0x24    ;Z       RMB    2
    RND:2                 ;0x26    ;RND     RMB    2
    LN:2                  ;0x28    ;LN      RMB    2
    PX:2                  ;0x2A    ;PX      RMB    2
    SP:2                  ;0x2C    ;SP      RMB    2
    LNADRS:2              ;0x2E    ;LNADRS  RMB    2
    BUFEND:2              ;0x30    ;BUFEND  RMB    2
    LDFLG                 ;0x32    ;LDFLG   RMB    1
    AFLG                  ;0x33    ;AFLG    RMB    1
    CHCNT                 ;0x34    ;CHCNT   RMB    1
    _F                    ;0x35    ;F       RMB    1
                                   ;BUFFER  RMB    80
                                   ;EXSTK   EQU    *
    EXSP:2                ;0x36    ;EXSP    RMB    2
    ATOZ:52               ;0x38    ;        RMB    52
    PRSTRT:2              ;0x6C    ;PRSTRT  RMB    2
    PREND:2               ;0x6E    ;PREND   RMB    2
                                   ;RAMEND  RMB    2
    SUBSP:2               ;0x70    ;SUBSP   RMB    2
    FORSP:2               ;0x72    ;FORSP   RMB    2
                                   ;        RMB    64
                                   ;FORSTK  EQU    *
    Areg                  ;0x74
    Breg                  ;0x75
    XHreg                 ;0x76
    XLreg                 ;0x77
    SHreg                 ;0x78
   ハードウエアスタックのスタックポインタ
    SLreg                 ;0x79   ハードウエアスタックのスタックポインタ
    Temp                  ;0x7A
    TSTATUS               ;0x7B
   BASICランチャーで使用
    TAreg                 ;0x7C   BASICランチャーで使用
    TBreg                 ;0x7D   BASICランチャーで使用
    THreg                 ;0x7E   BASICランチャーで使用
    TLreg                 ;0x7F   BASICランチャーで使用
    endc

BUFFER    equ    0x70-0x20+0x2000    ;UMTOP   EQU    $0940
EXSTK     equ    BUFFER+80           ;UMBTM   EQU    $7FFF
FORSTK    equ    EXSTK+64            ;BRKCHK  EQU    $8004
STACK     equ    FORSTK+0x37         ;STACK   EQU    $A047
SUBBTM    equ    STACK+3             ;SUBBTM  EQU    $A04A
SUBSTK    equ    FORSTK+0x60         ;SUBSTK  EQU    $A080



④スタックポインタの扱いをどうするか
6800ではRAM上にスタックポインタを形成するためスタック容量は自由に設定できますが、
エンハンスドミッドレンジのPICでは16段のハードウエアスタックなので、いったんオーバー
フローを起こすと戻り先を失ってプログラムがクラッシュします。
電大版TINYBASICではFOR-NEXT用に独立のスタックを用いてスタックのオーバーフローを防止していますが、
これ以外にもたとえば括弧を多重に使った演算などを行うとPICの16段のスタックは簡単にオーバーフローして
しまいます。
PICのハードウエアスタックのためにオリジナルの電大版TINYBASICで設定しているスタックのほかに
新たにスタック領域を作成してハードウエアスタックを逃避させる工夫が必要です。
ハードウエアスタックのスタック

○考えかた
デバッグ時の経験から最もスタックを消費するのはEXPR3ルーチンなので,
EXPR3ルーチンの前でハードウエアスタックをPUSH,EXPR3ルーチンの後でPOPさせる。
スタック領域はRAMの最後尾から240バイトとする。

img_20180618-122046.jpg