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

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

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

前ページから続きます。
⑤その他のTIPS

<INIT1サブルーチン>
PICで対応できない命令、TPA命令でAレジスタに代入される値は0xD0
INIT1    LDX      PRSTRT          ;INIT1   LDX      PRSTRT
         movlw    0xD0            ;        TPA
         movwf    Areg            ;        STAA     0,X
         movwi    INDF0++         ;        INX
         movwi    0[INDF0]        ;        STAA     0,X
         STX      PREND           ;        STX      PREND
         return                   ;        RTS


<BREAKサブルーチンの一例>
BREAK    PSHA                     ;BREAK   PSHA
         movlb    .14             ;        LDAA     BRKCHK
         movf     PIR3,W          ;        BMI      BR5
         movlb    .0
         btfsc     WREG,RCIF
         call     _IN             ;        BSR      IN
BR5      PULA                     ;BR5     PULA
BR6      return                   ;BR6     RTS



<AUTOサブルーチン>
PICで対応できない命令、TPA命令でAレジスタに代入される値は0xD1
AUTO    movlw    0xD1             ;AUTO    TPA
        movwf    Areg
        movwf    AFLG             ;        STAA     AFLG
        call     EXPRPP           ;        JSR      EXPRPP
        SUBAI    10               ;        SUBA     #10
        SBCBI    0                ;        SBCB     #0
SETLN   STAA     LN+1             ;SETLN   STAA     LN+1
        STAB     LN               ;        STAB     LN
        return                    ;        RTS



<MEMTSTルーチンの一例>
MEMTST    movf    Areg,W            ;MEMTST  INX
          movwi   ++INDF0           ;        LDAB     1,X
          movlw   HIGH(UMBTM)       ;        STAA     1,X
          subwf   FSR0H,W           ;        LDAA     1,X
          skpz                      ;        STAB     1,X
          bra     MEMTST            ;        CMPA     #$AA
          movlw   LOW(UMBTM)        ;        BEQ      MEMTST
          subwf   FSR0L,W
          skpz
          bra     MEMTST



0x8000はflash領域を指すFSRアドレスへ変換するための補正値
文字列データへのアクセスはアドレスの補正が必要
PICで対応できない命令、TPA命令でAレジスタに代入される値は0xD1
      call    INIT2             ;        BSR      INIT2
C3    call    NWLINE            ;C3      JSR      NWLINE
      LDXI    RDYMSG+0x8000     ;        LDX      #RDYMSG
      call    PD                ;        JSR      PD
      movlw   0xD1              ;        TPA
      movwf   Areg
      movwf   LNADRS            ;        STAA     LNADRS



<SIZEサブルーチン>
変数RAMENDを使用しないため、RAMENDに代入される数値をRAMENDの代わりに使用
SIZE   LDAAI    LOW(UMBTM)          ;SIZE    LDAA     RAMEND+1
       LDABI    HIGH(UMBTM)         ;        LDAB     RAMEND
       SUBA     PREND+1             ;        SUBA     PREND+1
       SBCB     PREND               ;        SBCB     PREND
       return                       ;        RTS



<STMTルーチン>
LNADRSの指すアドレスがBUFFER内のとき実行文はダイレクトコマンド
LNADRSの指すアドレスがBUFFER内でないとき実行文には行何号がついている
オリジナルのコードではBUFFERがゼロページに存在するためLNADRSの上位バイトが0かどうかのみ判定
STMT    STX      LNADRS               ;STMT       STX      LNADRS
        moviw    0[INDF0]             ;           LDAA     0,X
        lslf     WREG,F               ;           ASLA
        movlw    HIGH(BUFFER)         ;           LDAA     LNADRS
        xorwf    LNADRS,W
        skpnz                         ;           BLS      C7
        bra      C3
        skpnc
        bra      C3



<SKBサブルーチン>
6800のTST命令はキャリーを強制クリアする。
SKB    moviw    0[INDF0]    ;SKB    LDAA     0,X
       movwf    Areg
       CMPAI    0x20        ;       CMPA     #$20
       skpnz                ;       BEQ      SKB2
       bra      SKB2
       TSTA                 ;       TSTA
       bcf      STATUS,C    ;;carry clr
       skpnz                ;       BEQ      L468
       bra      L468
       CMPAI    ':'         ;       CMPA     #':
       SEC                  ;       SEC
L468   return               ;L468   RTS



<NEGXサブルーチン>
6800のCOM命令はキャリーを強制セットする。
NEGX    moviw    1[INDF0]        ;NEGX   NEG      1,X
        comf     WREG,F
        incf     WREG,F
        movwi    1[INDF0]
        skpz                     ;       BNE      L45B
        bra      L45B
        moviw    0[INDF0]        ;       DEC      0,X
        decf     WREG,F
        movwi    0[INDF0]
L45B    moviw    0[INDF0]        ;L45B   COM      0,X
        comf     WREG,F
        movwi    0[INDF0]
        bsf      STATUS,C        ;;carry set
RABS    return                   ;RABS    RTS



<EXPRルーチン>
EXPR3サブルーチン呼び出しの前後でハードウエアスタックの逃避/復帰を行う
EXPR    call    PSHSP            ;EXPR    BSR      EXPR3
        call    EXPR3
        call    REL              ;        BSR      REL
        call    POPSP
        TSTB                     ;        TSTB
        skpnz                    ;        BEQ      R5
        bra     R5
        PSHB                     ;        PSHB
        call    PSHSP            ;        BSR      EXPR3
        call    EXPR3
        call    POP              ;        JSR      POP
        call    POPSP
        LDX     EXSP             ;        LDX      EXSP



<TSTVサブルーチン>
A~Zの変数領域を$82から移動させたので補正
TSTV    call    SKB          ;TSTV    BSR      SKB8
        CMPAI   0x40         ;        CMPA     #$40
        skpnz                ;        BEQ      ARRAY
        bra     ARRAY
        CMPAI   'A'          ;        CMPA     #'A
        skpc                 ;        BCS      NOTV
        bra     NOTV
        CMPAI   'Z'+1        ;        CMPA     #'Z
        btfss   WREG,7       ;        BHI      NOTV
        bra     NOTV
        movlw   0x25         ;;AtoZ
        subwf   Areg,F
        ASLA                 ;         ASLA
        CLRB                 ;         CLRB
        INX                  ;         INX
        return               ;         RTS



<TSTSTKサブルーチン>
PICにはaddfsr命令があるのでINX8サブルーチンを廃止
TSTSTK    call    CMPX         ;TSTSTK  JSR      CMPX
          skpnz                ;        BEQ      TST3
          goto    TST3
          addfsr  FSR0,8       ;        BSR      INX8
TST2      CPXI    FORSTK       ;TST2    CPX      #FORSTK
          skpz                 ;        BNE      TSTSTK
          bra     TSTSTK
          bcf     STATUS,C     ;        SEC
TST3      return               ;        RTS



<LET4サブルーチン>
TSTEQサブルーチン内部でスタックポインタの補正を行うため仮想スタックポインタを使用しているPICと不整合
TSTEQ2にサブルーチンコールすると戻って来れなくなる。
LET4    STAA     _W+1          ;LET4    STAA     W+1
        STAB     _W            ;        STAB     W
        addfsr   FSR1,-2       ;        BSR      TSTEQ2
        call     TSTEQ
        call     EXPRPP        ;        BSR      EXPRPP
        STX      PX            ;        STX      PX
        LDX      _W            ;        LDX      W
        return                 ;        RTS



<INFFFサブルーチン>
機能追加
ESCキー押下でControl-C入力できるようにする
BSキー押下でControl-O入力できるようにする
INFFF    call    INEEE             ;INFFF   JSR      INEEE
         movwf   Areg              ;        CMPA     #$60
         btfsc   Areg,6            ;        BCS      L948
         bcf     Areg,5            ;        SUBA     #$20
         movlw   0x1B              ;L948    CMPA     #$25
         subwf   Areg,W            ;        BNE      L94E
         skpnz                     ;        LDAA     #$40
         bra     ESC               ;L94E    RTS
         movlw   0x08
         subwf   Areg,W
         skpz
         bra     OUTFFF
BS       movlw   0x0F
         bra     INFFF0
ESC      movlw   0x03

INFFF0   movwf   Areg

              return