#lang scheme/base
(require
(lib "match.ss")
(lib "pretty.ss")
"../live.ss" "../asm.ss"
"../tools.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")
(clrf (f a) "0110 101a ffff ffff")
(comf (f d a) "0001 11da ffff ffff")
(cpfseq (f a) "0110 001a ffff ffff")
(cpfsgt (f a) "0110 010a ffff ffff")
(cpfslt (f a) "0110 000a ffff ffff")
(decf (f d a) "0000 01da ffff ffff")
(decfsz (f d a) "0010 11da ffff ffff")
(dcfsnz (f d a) "0100 11da ffff ffff")
(incf (f d a) "0010 10da ffff ffff")
(incfsz (f d a) "0011 11da ffff ffff")
(infsnz (f d a) "0100 10da ffff ffff")
(iorwf (f d a) "0001 00da ffff ffff")
(movf (f d a) "0101 00da ffff ffff")
(~movff (s) "1100 ssss ssss ssss") (movwf (f a) "0110 111a ffff ffff")
(mulwf (f a) "0000 001a ffff ffff")
(negf (f a) "0110 110a 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")
(setf (f a) "0110 100a 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")
(tstfsz (f a) "0110 011a ffff ffff")
(xorwf (f d a) "0001 10da ffff ffff")
(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 (l s) "1110 110s llll llll") (clrwdt () "0000 0000 0000 0100")
(daw () "0000 0000 0000 0111")
(~goto (l) "1110 1111 llll llll") (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")
(~lfsr (f h) "1110 1110 00ff hhhh") (movlb (k) "0000 0001 0000 kkkk")
(movlw (k) "0000 1110 kkkk kkkk")
(mullw (k) "0000 1101 kkkk kkkk")
(retlw (k) "0000 1100 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")
)
(check-set-mode! 'report-failed)
(check ((asm-find 'movlw) 123) => '(3707))
(check ((dasm-find 14 8) 3707) => '(movlw (k . 123)))
(pseudo-ops
(assemblers: ~nop)
(~page (addr) (~nop (>>> addr 8)))
(dup () `(#x6EEC))
(drop () `(#x50ED))
(db (x) `(,(int x)))
(dw (x) `(,(int x)))
(d2 (lo hi) `(,(bior (int8 lo)
(<<< (int8 hi) 8))))
(jsr (exit address) (assemble-jsr exit address))
)
(pseudo-ops
(assemblers: ~goto ~call ~page)
(goto (addr) (append (~page addr) (~goto addr)))
(call (addr s) (append (~page addr) (~call addr s))) (call0 (addr) (append (~page addr) (~call addr 0)))
)
(define-syntax-rule (let-assemblers (name ...) body ...)
(let ((name (asm-find 'name)) ...) body ...))
(define assemble-jsr
(let-assemblers
(bra rcall goto call) (lambda (exit address)
(let-values
(((short long)
(if (zero? exit)
(values rcall call)
(values bra goto)))
((relative-address)
(- address (+ (pointer-get 'code) 1))))
((if (asm-fits? relative-address
11 operand:signed)
short long)
address)))))
(define (lfsr reg base bank)
`(lfsr ,reg ,(bior base (<<< bank 8))))
(define (pretty-asm lst)
(foldr
(match-lambda*
((('~lfsr reg (and bank (= number? #t)))
(('~nop (and base (= number? #t))) . r))
(cons (lfsr reg base bank) r))
((('~lfsr reg (and bank (= number? #t)))
(('label . l) ('~nop (and base (= number? #t))) . r))
(cons (lfsr reg base bank) r))
((('bpf p x y z) r)
(cons `(,(if (= p 0) 'bsf 'bcf) ,x ,y ,z) r))
((('btfsp p x y z) r)
(cons `(,(if (= p 0) 'btfss 'btfsc) ,x ,y ,z) r))
((('r 'bpz p addr) r)
(cons `(,(if (= p 0) 'bz 'bnz) ,addr) r))
((('bpz p addr) r)
(cons `(,(if (= p 0) 'bz 'bnz) ,addr) r))
((('r 'bpc p addr) r)
(cons `(,(if (= p 0) 'bc 'bnc) ,addr) r))
((('bpc p addr) r)
(cons `(,(if (= p 0) 'bc 'bnc) ,addr) r))
((('~movff s) (('~nop d) . r))
(cons `(movff ,s ,d) r))
((('~nop 'TOSU) r)
(cons '(_) r))
((head tail)
(cons head tail)))
'() lst))