#lang scheme/base
(require
(lib "match.ss")
(lib "pretty.ss")
"../ns.ss" "../asm.ss"
"../tools.ss"
"../coma/macro.ss"
)
(provide (all-defined-out))
(instruction-set
(addwf (f d a) "0010 01da ffff ffff")
(addwfc (f d a) "0010 00da ffff ffff")
(andwf (f d a) "0001 01da ffff ffff")
(comf (f d a) "0001 11da ffff ffff")
(rlcf (f d a) "0011 01da ffff ffff")
(rlncf (f d a) "0100 01da ffff ffff")
(rrcf (f d a) "0011 00da ffff ffff")
(rrncf (f d a) "0100 00da ffff ffff")
(subfwb (f d a) "0101 01da ffff ffff")
(subwf (f d a) "0101 11da ffff ffff")
(subwfb (f d a) "0101 10da ffff ffff")
(swapf (f d a) "0011 10da ffff ffff")
(xorwf (f d a) "0001 10da ffff ffff")
(decf (f d a) "0000 01da ffff ffff")
(incf (f d a) "0010 10da ffff ffff")
(iorwf (f d a) "0001 00da ffff ffff")
(movf (f d a) "0101 00da ffff ffff")
(incfsz (f d a) "0011 11da ffff ffff")
(infsnz (f d a) "0100 10da ffff ffff")
(decfsz (f d a) "0010 11da ffff ffff")
(decfsnz (f d a) "0100 11da ffff ffff")
(tstfsz (f a) "0110 011a ffff ffff")
(clrf (f a) "0110 101a ffff ffff")
(cpfseq (f a) "0110 001a ffff ffff")
(cpfsgt (f a) "0110 010a ffff ffff")
(movwf (f a) "0110 111a ffff ffff")
(mulwf (f a) "0000 001a ffff ffff")
(cpfslt (f a) "0110 000a ffff ffff")
(setf (f a) "0110 100a ffff ffff")
(negf (f a) "0110 110a ffff ffff")
(movff (s d) "1100 ssss ssss ssss" "1111 dddd dddd dddd")
(bpf (p f b a) "100p bbba ffff ffff")
(btfsp (p f b a) "101p bbba ffff ffff")
(btg (f b a) "0111 bbba ffff ffff")
(bpc (p R) "1110 001p RRRR RRRR")
(bpn (p R) "1110 011p RRRR RRRR")
(bpov (p R) "1110 010p RRRR RRRR")
(bpz (p R) "1110 000p RRRR RRRR")
(bra (R) "1101 0RRR RRRR RRRR")
(_call (s l h) "1110 110s llll llll" "1111 hhhh hhhh hhhh") (clrwdt () "0000 0000 0000 0100")
(daw () "0000 0000 0000 0111")
(_goto (l h) "1110 1111 llll llll" "1111 hhhh hhhh hhhh") (nop () "0000 0000 0000 0000")
(_nop (d) "1111 dddd dddd dddd") (pop () "0000 0000 0000 0110")
(push () "0000 0000 0000 0101")
(reset () "0000 0000 1111 1111")
(rcall (R) "1101 1RRR RRRR RRRR")
(retfie (s) "0000 0000 0001 000s")
(retlw (k) "0000 1100 kkkk kkkk")
(return (s) "0000 0000 0001 001s")
(sleep () "0000 0000 0000 0011")
(addlw (k) "0000 1111 kkkk kkkk")
(andlw (k) "0000 1011 kkkk kkkk")
(iorlw (k) "0000 1001 kkkk kkkk")
(movlb (k) "0000 0001 0000 kkkk")
(movlw (k) "0000 1110 kkkk kkkk")
(mullw (k) "0000 1101 kkkk kkkk")
(sublw (k) "0000 1000 kkkk kkkk")
(xorlw (k) "0000 1010 kkkk kkkk")
(tblrd* () "0000 0000 0000 1000")
(tblrd*+ () "0000 0000 0000 1001")
(tblrd*- () "0000 0000 0000 1010")
(tblrd+* () "0000 0000 0000 1011")
(tblwt* () "0000 0000 0000 1100")
(tblwt*+ () "0000 0000 0000 1101")
(tblwt*- () "0000 0000 0000 1110")
(tblwt+* () "0000 0000 0000 1111")
(_lfsr (f l h) "1110 1110 00ff hhhh" "1111 0000 llll llll")
)
(check-set-mode! 'report-failed)
(check ((asm-fn (asm: movlw)) 0 123) => '(3707))
(define (page addr) (>>> addr 8))
(define-syntax-rule (delegate-asm name) (asm-fn (asm: name)))
(define-lowlevel-ops
((dup here) `(#x6EEC))
((drop here) `(#x50ED))
((db here x) `(,(int x)))
((d2 here lo hi) `(,(bior (int8 lo)
(<<< (int8 hi) 8))))
((jsr here exit address) (smart-jsr here exit address))
((lfsr here f addr) ((delegate-asm _lfsr) here f addr (page addr)))
((goto here addr) ((delegate-asm _goto) here addr (page addr)))
((call here addr s) ((delegate-asm _call) here s addr (page addr)))
((call0 here addr) ((delegate-asm _call) here 0 addr (page addr))))
(define (smart-jsr here exit address)
(let-values
(((short long)
(if (zero? exit)
(values (asm: rcall) (asm: call0))
(values (asm: bra) (asm: goto)))))
(let ((jsr (if (relative-ok? here address) short long)))
((asm-fn jsr) here address))))
(define (relative-ok? here addr)
(let ((relative-addr (- addr(+ here 1))))
(asm-fits? relative-addr
11
operand:signed)))