#ifndef SWEET65_INC
#define SWEET65_INC
A       equ WREG
X       equ FSR0L
Y       equ FSR1L

STATU_S equ 0x79
A_S     equ 0x7a
BSR_S   equ 0x7b
X_S     equ 0x7c
FSR0L_S equ X_S
FSR0H_S equ 0x7d
Y_S     equ 0x7e
FSR1L_S equ Y_S
FSR1H_S equ 0x7f
GIE_S   equ 0x80

stash   macro   reg                   ;inline void stash(uint8_t* reg) {
#if (reg & GIE_S)                     ; if (reg & GIE_S) { // save interrupt bit...
        btfsc   INTCON,GIE            ;  if (INTCON & 1<<GIE)
        bsf     STATU_S,GIE           ;   STATU_S |= 1<<GIE; // above 5 bits of STATUS
        btfss   INTCON,GIE            ;  else //danger zone if interrupt comes?
        bcf     STATU_S,GIE           ;   STATU_S &= ~(1<<GIE);
#endif                                ; }
#if (reg & ~GIE_S)                    ; if (reg & ~GIE_S) { // save a file register
        bcf     INTCON,GIE            ;  INTCON &= ~(1<<GIE); // disable interrupts
        movwf   A_S                   ;  A_S = W;
#if ((reg & ~GIE_S) == STATU_S)       ;  switch (reg & ~GIE_S) {
        movf    STATU_S,w             ;  case STATU_S: // only 5 bits in STATUS reg
        andlw   0xe0                  ;
        iorwf   STATUS,w              ;   W = (STATU_S & ~0x1f) | (STATUS /*& 0x1f*/);
        movwf   STATU_S               ;   STATU_S = W;
        movf    A_S,w                 ;   W = A_S;
        exitm                         ;   break;
#endif                                ;
#if ((reg & ~GIE_S) == BSR_S)         ;
        movf    BSR,w                 ;  case BSR_S:
        movwf   BSR_S                 ;   BSR_S = BSR;
        movf    A_S,w                 ;   W = A_S;
        exitm                         ;   break;
#endif                                ;
#if ((reg & ~GIE_S) == X_S)           ;  case X_S:
        movf    X,w                   ;
        movwf   X_S                   ;   X_S = X;
        movf    A_S,w                 ;   W = A_S;
        exitm                         ;   break;
#endif                                ;
#if ((reg & ~GIE_S) == Y_S)           ;  case Y_S:
        movf    Y,w                   ;
        movwf   Y_S                   ;   Y_S = Y;
        movf    A_S,w                 ;   W = A_S;
        exitm                         ;   break;
#endif                                ;  }
#endif                                ; }
        endm                          ;}

gierest macro   reg                   ;inline void gierest(uint8_t* reg) {
#if (reg & GIE_S)                     ; if (reg & GIE_S) {
        btfsc   STATU_S,GIE           ;  if (STATU_S & (1<<GIE))
        bsf     INTCON,GIE            ;   INTCON |= 1<<GIE;
        btfss   STATU_S,GIE           ;  else
        bcf     INTCON,GIE            ;   INTCON &= ~(1<0x007f)                      ;  } else if (reg > 0x007f) {
        stash   GIE_S|STATU_S         ;   stash(GIE_S|STATU_S);
        stash   FSR0L_S               ;   stash(FSR0L_S);
        stash   FSR0H_S               ;   stash(FSR0H_S);
        movlw   low (reg)             ;
        movwf   FSR0L                 ;
        movlw   high (reg)            ;
        movwf   FSR0H                 ;   fsr0 = reg;
                                          subcmd cmd,INDF0,resul;
        movf    A_S,w                 ;   w = A_S; // required before unstash()
        unstash FSR0H_S               ;   unstash(FSR0H_S);
        unstash FSR0L_S               ;   unstash(FSR0L_S);
        unstash GIE_S|STATU_S         ;   unstash(GIE_S|STATU_S);
        exitm                         ;  else
#endif
                                          subcmd cmd,reg,resul;
        endm                          ;}

        ;; indexed indirect: (mem,X)
i_indir macro   cmd,resul,reg         ;inline void i_indir(uint5_t cmd, uint1_t
                                      ;                  resul, uint8_t* reg) {
        stash   GIE_S|STATU_S         ; stash(GIE_S|STATU_S); // STATU_S unnec.
        stash   FSR0L                 ; stash(FSR0L);
        stash   FSR0H                 ; stash(FSR0H);
        stash   FSR1L                 ; stash(Y); // intermediate result
        addword X_S,reg               ; fsr0 += reg;
        moviw   FSR0++                ; W = *fsr0++;
        movwf   FSR1L                 ; Y = W;
        moviw   FSR0                  ; W = *fsr0;
        movwf   FSR0H                 ;
        movf    FSR1L,w               ;
        movwf   FSR0L                 ; fsr0 = W << 8 | Y; // indirection
                                        subcmd  cmd,INDF0,resul;
#if (resul==w)                        ; if (resul == w)
        movwf   A_S                   ;  A_S = W;
#endif                                ;
        movf    STATUS,w              ;
        movwf   STATU_S               ; STATU_S = STATUS;
        movf    A_S,w                 ; w = A_S;
        unstash FSR1L                 ; unstash(FSR1L);
        unstash FSR0H                 ; unstash(FSR0H);
        unstash FSR0L                 ; unstash(FSR0L);
        unstash GIE_S|STATU_S         ; unstash(GIE_S|STATU_S);
        endm                          ;}

        ;; indirect indexed: (mem),Y
indir_i macro   cmd,resul,reg         ;inline void indir_i(uint5_t cmd, uint1_t
                                      ;                  resul, uint8_t* reg) {
        stash   GIE_S|STATU_S         ; stash(GIE_S|STATU_S); // STATU_S unnec.
        stash   FSR0L                 ; stash(FSR0L);
        stash   FSR0H                 ; stash(FSR0H);
        stash   FSR1L                 ; stash(FSR1L); // intermediate result
        stash   FSR1H                 ; stash(FSR1H);
        movlw   low reg               ;
        movwf   FSR0L                 ;
        movlw   high reg              ;
        movwf   FSR0H                 ; fsr0 = reg;
        moviw   FSR0++                ; W = *fsr0++;
        movwf   FSR1L                 ; Y = W;
        moviw   FSR0                  ; W = *fsr0;
        movwf   FSR1H                 ; fsr1 = W << 8 | Y;
        movf    Y_S,w                 ;
        addwf   FSR1L,f               ;
        movlw   0                     ;
        addwfc  FSR1H,f               ; fsr1 += Y_S;
                                        subcmd  cmd,INDF1,resul;
#if (resul==w)                        ; if (resul == w)
        movwf   A_S                   ;  A_S = w;
#endif                                ;
        movf    STATUS,w              ;
        movwf   STATU_S               ; STATU_S = STATUS;
        movf    A_S,w                 ; w = A_S;
        unstash FSR1H                 ; unstash(FSR1H);
        unstash FSR1L                 ; unstash(FSR1L);
        unstash FSR0H                 ; unstash(FSR0H);
        unstash FSR0L                 ; unstash(FSR0L);
        unstash GIE_S|STATU_S         ; unstash(GIE_S|STATU_S);
        endm                          ;}

adc#    macro   lit                   ;inline void adc#(uint8_t lit) {
        stash   GIE_S                 ; stash(GIE_S);
        btfsc   STATUS,C              ;
        addlw   1                     ;
        addlw   lit                   ; W += lit + ((STATUS & (1<<C)) ? 1 : 0);
        unstash GIE_S                 ; unstash(GIE_S);
        endm                          ;}

adc     macro   dest,indreg
        absol_a _addwfc,w,dest,indreg
        endm

adc?    macro   dest,indreg
#if (indreg == X) ; { // indexed indirect
        i_indir _addwfc,w,dest
        exitm
#endif ; }
#if (indreg == Y) ; { // indirect indexed
        indir_i _addwfc,w,dest
        exitm
#endif ; }
        endm

and#    macro   lit
        andlw   lit
        endm

and     macro   dest,indreg
        absol_a _andwf,w,dest,indreg
        endm

and?    macro   dest,indreg
#if (indreg == X) ; { // indexed indirect
        i_indir _andwf,w,dest
        exitm
#endif ; }
#if (indreg == Y) ; { // indirect indexed
        indir_i _andwf,w,dest
        exitm
#endif ; }
        endm

asl     macro   dest,indreg
        absol_a _lslf,w,dest,indreg
        endm

#define RAMBANK(addr) (((addr) & 0x1fff) / 0x50)
#define RAMOFST(addr) ((((addr) & 0x1fff) % 0x50) + 0x20)

bit     macro   src                   ;inline void bit(uint8_t* src) {
        stash   GIE_S|STATU_S         ; stash(GIE_S|STATU_S);
        stash   BSR_S                 ; stash(BSR_S);
#if (src < 0x80)                      ; if (src =0), Z=(A==x);
cmpflag macro                         ;inline void cmpflag(void) {
        lslf    WREG                  ; uint1_t carry = (W>>7) & 1;
        movf    STATUS,w              ; W <<= 1; // zero will still be a zero
        movwf   STATU_S               ; STATU_S = STATUS;
        movlw   0                     ; if (carry)
        rlf     WREG                  ;  STATU_S &= ~(1<<C);
        xorwf   STATU_S,f             ; else STATU_S |= 1<> 8;
        moviw   --FSR0                ; W = (*fsr0 & 0x00ff);
        unstash FSR0H_S               ; unstash(FSR0H_S);
        unstash FSR0L_S               ; unstash(FSR0L_S);
        unstash GIE_S|STATU_S         ; unstash(GIE_S|STATU_S);
        movwf   w,PCL                 ; goto (PCLATH << 8) | W; // jmp indirect
        endm                          ;}

jsr     macro   label
        pagesel label
        call    label
        endm

lda#    macro   lit
        movlw   lit
        endm

lda     macro   src,indreg            ;
        absol_a _movf,w,src
        endm

lda?    macro   src,indreg
#if (indreg == X) ; { // indexed indirect
        i_indir _movf,w,src
        exitm
#endif ; }
#if (indreg == Y) ; { // indirect indexed
        indir_i _movf,w,src
        exitm
#endif ; }
        endm

ld#     macro   indreg,lit
        stash   GIE_S|A_S
        movlw   lit
        movwf   indreg
        movf    A_S,w
        unstash GIE_S|A_S
        endm
ldx#    macro   lit
        ld#     X,lit
        endm
ldy#    macro   lit
        ld#     Y,lit
        endm

ld      macro   reg,src,indreg        ;void ld(uint8_t reg*, uint8_t* src,
                                      ;        uint8_t* indreg) {
#if (reg != indreg)                   ; if (reg != indreg) {
        stash   GIE_S|STATU_S         ;  stash(GIE_S|STATU_S);
#if ((indreg-0!=X) && (indreg-0)!=Y)  ;  if ((indreg != X) && (indreg != Y))
        movf    src,w                 ;
        movwf   reg                   ;   *reg = *src;
#else                                 ;
#if (indreg-0==X)                     ;  else if (indreg == X) {
        stash   FSR0L_S               ;   stash(FSR0L_S);
        stash   FSR0H_S               ;   stash(FSR0H_S);
        addword X,src                 ;   fsr0 += src;
        moviw   FSR0                  ;
        movwf   Y                     ;   Y = *fsr0;
        unstash FSR0H_S               ;   unstash(FSR0H_S);
        unstash FSR0L_S               ;   unstash(FSR0L_S);
#else                                 ;  } else /* if (indreg == Y) */ {
        stash   FSR1L_S               ;   stash(FSR1L_S);
        stash   FSR1H_S               ;   stash(FSR1H_S);
        addword Y,src                 ;   fsr1 += src;
        moviw   FSR1                  ;
        movwf   X                     ;   X = *fsr1;
        unstash FSR1H_S               ;   unstash(FSR1H_S);
        unstash FSR1L_S               ;   unstash(FSR1L_S);
#endif                                ;  }
        unstash GIE_S|STATU_S         ;  unstash(GIE_S|STATU_S);
#endif                                ; }
        endm                          ;}

ldx     macro   src,indreg
        ld      X,src,indreg
        endm
ldy     macro   src,indreg
        ld      Y,src,indreg
        endm

lsr     macro   dest,indreg
        absol_a _lsrf,f,dest,indreg
        endm

ora#    macro   lit
        iorlw   lit
        endm

ora     macro   dest,indreg
        absol_a _iorwf,w,dest,indreg
        endm

ora?    macro   dest,indreg
#if (indreg == X) ; { // indexed indirect
        i_indir _iorwf,w,dest
        exitm
#endif ; }
#if (indreg == Y) ; { // indirect indexed
        indir_i _iorwf,w,dest
        exitm
#endif ; }
        endm

rol     macro   dest,indreg
        absol_a _rlf,f,dest,indreg
        endm
ror     macro   dest,indreg
        absol_a _rrf,f,dest,indreg
        endm

rti     macro
        retfie
        endm

rts     macro
        return
        endm

sbc#    macro   lit                   ;inline void sbc#(uint8_t lit) {
        stash   GIE_S                 ; stash(GIE_S);
        btfsc   STATUS,C              ;
        addlw   -1                    ;
        addlw   -lit                  ; W -= lit + ((STATUS & (1<<C)) ? 0 : 1);
        unstash GIE_S                 ; unstash(GIE_S);
        endm                          ;}

sbc     macro   dest,indreg
        absol_a _addwfc_sub,w,dest,indreg
        endm

sbc?    macro   dest,indreg
#if (indreg == X) ; { // indexed indirect
        i_indir _addwfc_sub,w,dest
        exitm
#endif ; }
#if (indreg == Y) ; { // indirect indexed
        indir_i _addwfc_sub,w,dest
        exitm
#endif ; }
        endm

sta     macro   dest,indreg
        absol_a _movwf,f,dest,indreg
        endm

sta?    macro   dest,indreg
#if (indreg == X) ; { // indexed indirect
        i_indir _movwf,f,dest
        exitm
#endif ; }
#if (indreg == Y) ; { // indirect indexed
        indir_i _movwf,f,dest
        exitm
#endif ; }
        endm

st      macro   reg,dest,indreg       ;void st(uint8_t reg*, uint8_t* dest,
                                      ;        uint8_t* indreg) {
#if (reg != indreg)                   ; if (reg != indreg) {
        stash   GIE_S|STATU_S         ;  stash(GIE_S|STATU_S);
#if ((indreg-0!=X) && (indreg-0)!=Y)  ;  if ((indreg != X) && (indreg != Y))
        movf    reg,w                 ;
        movwf   dest                  ;   *dest = *reg;
#else                                 ;
#if (indreg-0==X)                     ;  else if (indreg == X) {
        stash   FSR0L_S               ;   stash(FSR0L_S);
        stash   FSR0H_S               ;   stash(FSR0H_S);
        addword X,dest                ;   fsr0 += dest;
        movf    Y,w                   ;
        movwi   FSR0                  ;   *fsr0 = Y;
        unstash FSR0H_S               ;   unstash(FSR0H_S);
        unstash FSR0L_S               ;   unstash(FSR0L_S);
#else                                 ;  } else /* if (indreg == Y) */ {
        stash   FSR1L_S               ;   stash(FSR1L_S);
        stash   FSR1H_S               ;   stash(FSR1H_S);
        addword Y,dest                ;   fsr1 += dest;
        movf    X,w                   ;
        movwi   FSR1                  ;   *fsr1 = X;
        unstash FSR1H_S               ;   unstash(FSR1H_S);
        unstash FSR1L_S               ;   unstash(FSR1L_S);
#endif                                ;  }
        unstash GIE_S|STATU_S         ;  unstash(GIE_S|STATU_S);
#endif                                ; }
        endm                          ;}

stx     macro   dest,indreg
        st      X,dest,indreg
        endm
sty     macro   dest,indreg
        st      Y,dest,indreg
        endm

tax     macro
        movwf   X
        endm

txa     macro
        movf    X,w
        endm

tay     macro
        movwf   Y
        endm

tya     macro
        movf    Y,w
        endm

movstkp macro   fsr
        stash   BSR_S
        banksel TOSH
        movf    TOSH,w
        movwf   fsr+1
        bsf     fsr+1,7
        movf    TOSL,w
        movwf   fsr
        movf    A_S,w
        unstash BSR_S
        endm

tsx     macro
        stash   GIE_S|STATU_S
        movstkp FSR0
        movf    A_S,w
        unstash GIE_S|STATU_S
        endm
txs     macro
        stash   GIE_S|STATU_S
        stash   BSR_S
        banksel TOSL
        movf    X,w
        movwf   TOSL
        movf    A_S,w
        unstash BSR_S
        unstash GIE_S|STATU_S
        endm

pha     macro
        stash   GIE_S|STATU_S
        stash   FSR0L_S
        stash   FSR0H_S
        movstkp FSR0
        movwi   FSR0++
        movf    A_S,w
        unstash FSR0H_S
        unstash FSR0L_S
        unstash GIE_S|STATU_S
        endm
pla     macro
        stash   GIE_S|STATU_S
        stash   FSR0L_S
        stash   FSR0H_S
        movstkp FSR0
        moviw   --FSR0
        unstash FSR0H_S
        unstash FSR0L_S
        unstash GIE_S|STATU_S
        endm

php     macro
        stash   GIE_S|STATU_S
        stash   FSR0L_S
        stash   FSR0H_S
        movstkp FSR0
        movf    STATU_S,w
        movwi   FSR0++
        movf    A_S,w
        unstash FSR0H_S
        unstash FSR0L_S
        unstash GIE_S|STATU_S
        endm
plp     macro
        stash   GIE_S|STATU_S
        stash   FSR0L_S
        stash   FSR0H_S
        movstkp FSR0
        moviw   --FSR0
        movwf   STATU_S
        bsf     STATU_S,GIE
        movf    A_S,w
        unstash FSR0H_S
        unstash FSR0L_S
        unstash GIE_S|STATU_S
        endm
#endif
Advertisements