3 (define-macro (bitmask encoding . field-values)
7 (fields (list (list #\space 0 0))))
8 (if (< i (string-length encoding))
9 (let ((c (string-ref encoding i)))
26 (if (and (char=? c (car (car fields)))
27 (= pos (caddr (car fields))))
29 (set-car! (cddr (car fields)) (+ pos 1))
37 (cons (list c pos (+ pos 1)) fields))))))
40 (error "invalid bitmask" encoding))
44 (let* ((width (- (caddr f) (cadr f)))
45 (shift (- pos (caddr f))))
52 (cdr (reverse fields))
55 (define (bitfield encoding name limit shift value)
56 (if (or (< value 0) (>= value limit))
57 (error "value does not fit in field" name value encoding)
58 (arithmetic-shift value shift)))
60 ;------------------------------------------------------------------------------
62 ; Byte-oriented file register operations.
64 (define (addwf f #!optional (d 'f) (a 'a))
68 (make-listing "addwf" (file-text f) (dest-text d 'f) (access-text a 'a)))
70 (asm-16 (bitmask "0010 01da ffff ffff" (dest d) (access a) (file f))))))
72 (define (addwfc f #!optional (d 'f) (a 'a))
76 (make-listing "addwfc" (file-text f) (dest-text d 'f) (access-text a 'a)))
78 (asm-16 (bitmask "0010 00da ffff ffff" (dest d) (access a) (file f))))))
80 (define (andwf f #!optional (d 'f) (a 'a))
84 (make-listing "andwf" (file-text f) (dest-text d 'f) (access-text a 'a)))
86 (asm-16 (bitmask "0001 01da ffff ffff" (dest d) (access a) (file f))))))
88 (define (clrf f #!optional (a 'a))
92 (make-listing "clrf" (file-text f) (access-text a 'a)))
94 (asm-16 (bitmask "0110 101a ffff ffff" (access a) (file f))))))
96 (define (comf f #!optional (d 'f) (a 'a))
100 (make-listing "comf" (file-text f) (dest-text d 'f) (access-text a 'a)))
102 (asm-16 (bitmask "0001 11da ffff ffff" (dest d) (access a) (file f))))))
104 (define (cpfseq f #!optional (a 'a))
108 (make-listing "cpfseq" (file-text f) (access-text a 'a)))
110 (asm-16 (bitmask "0110 001a ffff ffff" (access a) (file f))))))
112 (define (cpfsgt f #!optional (a 'a))
116 (make-listing "cpfsgt" (file-text f) (access-text a 'a)))
118 (asm-16 (bitmask "0110 010a ffff ffff" (access a) (file f))))))
120 (define (cpfslt f #!optional (a 'a))
124 (make-listing "cpfslt" (file-text f) (access-text a 'a)))
126 (asm-16 (bitmask "0110 000a ffff ffff" (access a) (file f))))))
128 (define (decf f #!optional (d 'f) (a 'a))
132 (make-listing "decf" (file-text f) (dest-text d 'f) (access-text a 'a)))
134 (asm-16 (bitmask "0000 01da ffff ffff" (dest d) (access a) (file f))))))
136 (define (decfsz f #!optional (d 'f) (a 'a))
140 (make-listing "decfsz" (file-text f) (dest-text d 'f) (access-text a 'a)))
142 (asm-16 (bitmask "0010 11da ffff ffff" (dest d) (access a) (file f))))))
144 (define (dcfsnz f #!optional (d 'f) (a 'a))
148 (make-listing "dcfsnz" (file-text f) (dest-text d 'f) (access-text a 'a)))
150 (asm-16 (bitmask "0100 11da ffff ffff" (dest d) (access a) (file f))))))
152 (define (incf f #!optional (d 'f) (a 'a))
156 (make-listing "incf" (file-text f) (dest-text d 'f) (access-text a 'a)))
158 (asm-16 (bitmask "0010 10da ffff ffff" (dest d) (access a) (file f))))))
160 (define (incfsz f #!optional (d 'f) (a 'a))
164 (make-listing "incfsz" (file-text f) (dest-text d 'f) (access-text a 'a)))
166 (asm-16 (bitmask "0011 11da ffff ffff" (dest d) (access a) (file f))))))
168 (define (infsnz f #!optional (d 'f) (a 'a))
172 (make-listing "infsnz" (file-text f) (dest-text d 'f) (access-text a 'a)))
174 (asm-16 (bitmask "0100 10da ffff ffff" (dest d) (access a) (file f))))))
176 (define (iorwf f #!optional (d 'f) (a 'a))
180 (make-listing "iorwf" (file-text f) (dest-text d 'f) (access-text a 'a)))
182 (asm-16 (bitmask "0001 00da ffff ffff" (dest d) (access a) (file f))))))
184 (define (movf f #!optional (d 'f) (a 'a))
188 (make-listing "movf" (file-text f) (dest-text d 'f) (access-text a 'a)))
190 (asm-16 (bitmask "0101 00da ffff ffff" (dest d) (access a) (file f))))))
192 (define (movff fs fd)
196 (make-listing "movff" (file-text fs) (file-text fd)))
198 (asm-16 (bitmask "1100 ffff ffff ffff" (file-full fs)))
199 (asm-16 (bitmask "1111 ffff ffff ffff" (file-full fd))))))
201 (define (movwf f #!optional (a 'a))
205 (make-listing "movwf" (file-text f) (access-text a 'a)))
207 (asm-16 (bitmask "0110 111a ffff ffff" (access a) (file f))))))
209 (define (mulwf f #!optional (a 'a))
213 (make-listing "mulwf" (file-text f) (access-text a 'a)))
215 (asm-16 (bitmask "0000 001a ffff ffff" (access a) (file f))))))
217 (define (negf f #!optional (a 'a))
221 (make-listing "negf" (file-text f) (access-text a 'a)))
223 (asm-16 (bitmask "0110 110a ffff ffff" (access a) (file f))))))
225 (define (rlcf f #!optional (d 'f) (a 'a))
229 (make-listing "rlcf" (file-text f) (dest-text d 'f) (access-text a 'a)))
231 (asm-16 (bitmask "0011 01da ffff ffff" (dest d) (access a) (file f))))))
233 (define (rlncf f #!optional (d 'f) (a 'a))
237 (make-listing "rlncf" (file-text f) (dest-text d 'f) (access-text a 'a)))
239 (asm-16 (bitmask "0100 01da ffff ffff" (dest d) (access a) (file f))))))
241 (define (rrcf f #!optional (d 'f) (a 'a))
245 (make-listing "rrcf" (file-text f) (dest-text d 'f) (access-text a 'a)))
247 (asm-16 (bitmask "0011 00da ffff ffff" (dest d) (access a) (file f))))))
249 (define (rrncf f #!optional (d 'f) (a 'a))
253 (make-listing "rrncf" (file-text f) (dest-text d 'f) (access-text a 'a)))
255 (asm-16 (bitmask "0100 00da ffff ffff" (dest d) (access a) (file f))))))
257 (define (setf f #!optional (a 'a))
261 (make-listing "setf" (file-text f) (access-text a 'a)))
263 (asm-16 (bitmask "0110 100a ffff ffff" (access a) (file f))))))
265 (define (subfwb f #!optional (d 'f) (a 'a))
269 (make-listing "subfwb" (file-text f) (dest-text d 'f) (access-text a 'a)))
271 (asm-16 (bitmask "0101 01da ffff ffff" (dest d) (access a) (file f))))))
273 (define (subwf f #!optional (d 'f) (a 'a))
277 (make-listing "subwf" (file-text f) (dest-text d 'f) (access-text a 'a)))
279 (asm-16 (bitmask "0101 11da ffff ffff" (dest d) (access a) (file f))))))
281 (define (subwfb f #!optional (d 'f) (a 'a))
285 (make-listing "subwfb" (file-text f) (dest-text d 'f) (access-text a 'a)))
287 (asm-16 (bitmask "0101 10da ffff ffff" (dest d) (access a) (file f))))))
289 (define (swapf f #!optional (d 'f) (a 'a))
293 (make-listing "swapf" (file-text f) (dest-text d 'f) (access-text a 'a)))
295 (asm-16 (bitmask "0011 10da ffff ffff" (dest d) (access a) (file f))))))
297 (define (tstfsz f #!optional (a 'a))
301 (make-listing "tstfsz" (file-text f) (access-text a 'a)))
303 (asm-16 (bitmask "0110 011a ffff ffff" (access a) (file f))))))
305 (define (xorwf f #!optional (d 'f) (a 'a))
309 (make-listing "xorwf" (file-text f) (dest-text d 'f) (access-text a 'a)))
311 (asm-16 (bitmask "0001 10da ffff ffff" (dest d) (access a) (file f))))))
313 ; Bit-oriented file register operations.
315 (define (bcf f b #!optional (a 'a))
319 (make-listing "bcf" (file-text f) (bit-text b) (access-text a 'a)))
321 (asm-16 (bitmask "1001 bbba ffff ffff" (bit b) (access a) (file f))))))
323 (define (bsf f b #!optional (a 'a))
327 (make-listing "bsf" (file-text f) (bit-text b) (access-text a 'a)))
329 (asm-16 (bitmask "1000 bbba ffff ffff" (bit b) (access a) (file f))))))
331 (define (btfsc f b #!optional (a 'a))
335 (make-listing "btfsc" (file-text f) (bit-text b) (access-text a 'a)))
337 (asm-16 (bitmask "1011 bbba ffff ffff" (bit b) (access a) (file f))))))
339 (define (btfss f b #!optional (a 'a))
343 (make-listing "btfss" (file-text f) (bit-text b) (access-text a 'a)))
345 (asm-16 (bitmask "1010 bbba ffff ffff" (bit b) (access a) (file f))))))
347 (define (btg f b #!optional (a 'a))
351 (make-listing "btg" (file-text f) (bit-text b) (access-text a 'a)))
353 (asm-16 (bitmask "0111 bbba ffff ffff" (bit b) (access a) (file f))))))
355 ; Control operations.
358 (make-short-relative-branch-instruction
362 (asm-16 (bitmask "1110 0010 nnnn nnnn" dist-8bit)))))
365 (make-short-relative-branch-instruction
369 (asm-16 (bitmask "1110 0110 nnnn nnnn" dist-8bit)))))
372 (make-short-relative-branch-instruction
376 (asm-16 (bitmask "1110 0011 nnnn nnnn" dist-8bit)))))
379 (make-short-relative-branch-instruction
383 (asm-16 (bitmask "1110 0111 nnnn nnnn" dist-8bit)))))
386 (make-short-relative-branch-instruction
390 (asm-16 (bitmask "1110 0101 nnnn nnnn" dist-8bit)))))
393 (make-short-relative-branch-instruction
397 (asm-16 (bitmask "1110 0001 nnnn nnnn" dist-8bit)))))
400 (make-short-relative-branch-instruction
404 (asm-16 (bitmask "1110 0100 nnnn nnnn" dist-8bit)))))
407 ;; (make-long-relative-branch-instruction
410 ;; (lambda (dist-11bit)
411 ;; (asm-16 (bitmask "1101 0nnn nnnn nnnn" dist-11bit)))))
413 (define (bra-or-goto l)
414 (make-long-relative-or-absolute-branch-instruction
419 (asm-16 (bitmask "1101 0nnn nnnn nnnn" dist-11bit)))
421 (asm-16 (bitmask "1110 1111 nnnn nnnn" (modulo pos-20bit (expt 2 8))))
422 (asm-16 (bitmask "1111 nnnn nnnn nnnn" (quotient pos-20bit (expt 2 8)))))))
425 (make-short-relative-branch-instruction
429 (asm-16 (bitmask "1110 0000 nnnn nnnn" dist-8bit)))))
431 (define (call l #!optional (s 0))
435 (make-listing "call" (label-text l) (lit-text s)))
441 (let ((pos-div-2 (quotient (label-pos l) 2)))
442 (asm-16 (bitmask "1110 110s kkkk kkkk" s (quotient pos-div-2 4096)))
443 (asm-16 (bitmask "1111 kkkk kkkk kkkk" (modulo pos-div-2 4096)))))))))
449 (make-listing "clrwdt"))
451 (asm-16 (bitmask "0000 0000 0000 0100")))))
457 (make-listing "daw"))
459 (asm-16 (bitmask "0000 0000 0000 0111")))))
465 (make-listing "goto" (label-text l)))
471 (let ((pos-div-2 (quotient (label-pos l) 2)))
472 (asm-16 (bitmask "1110 1111 kkkk kkkk" (quotient pos-div-2 4096)))
473 (asm-16 (bitmask "1111 kkkk kkkk kkkk" (modulo pos-div-2 4096)))))))))
479 (make-listing "nop"))
481 (asm-16 (bitmask "0000 0000 0000 0000")))))
487 (make-listing "pop"))
489 (asm-16 (bitmask "0000 0000 0000 0110")))))
495 (make-listing "push"))
497 (asm-16 (bitmask "0000 0000 0000 0101")))))
500 (make-long-relative-branch-instruction
504 (asm-16 (bitmask "1101 1nnn nnnn nnnn" dist-11bit)))))
506 (define (rcall-or-call l)
507 (make-long-relative-or-absolute-branch-instruction
512 (asm-16 (bitmask "1101 1nnn nnnn nnnn" dist-11bit)))
514 (asm-16 (bitmask "1110 1100 nnnn nnnn" (modulo pos-20bit (expt 2 8))))
515 (asm-16 (bitmask "1111 nnnn nnnn nnnn" (quotient pos-20bit (expt 2 8)))))))
521 (make-listing "reset"))
523 (asm-16 (bitmask "0000 0000 1111 1111")))))
525 (define (retfie #!optional (s 0))
529 (make-listing "retfie" (lit-text s)))
531 (asm-16 (bitmask "0000 0000 0001 000s" s)))))
533 (define (return #!optional (s 0))
537 (make-listing "return" (lit-text s)))
539 (asm-16 (bitmask "0000 0000 0001 001s" s)))))
545 (make-listing "sleep"))
547 (asm-16 (bitmask "0000 0000 0000 0011")))))
549 (define (make-short-relative-branch-instruction mnemonic l generate)
553 (make-listing mnemonic (label-text l)))
559 (let ((dist (- (label-pos l) (+ self 2))))
560 (if (and (>= dist -256)
563 (generate (modulo (quotient dist 2) 256))
564 (error "short relative branch target is too far or improperly aligned" l dist))))))))
566 (define (make-long-relative-branch-instruction mnemonic l generate)
570 (make-listing mnemonic (label-text l)))
576 (let ((dist (- (label-pos l) (+ self 2))))
577 (if (and (>= dist -2048)
580 (generate (modulo (quotient dist 2) 2048))
581 (error "long relative branch target is too far or improperly aligned" l dist))))))))
583 (define (make-long-relative-or-absolute-branch-instruction mnemonic1 mnemonic2 l generate1 generate2)
587 (make-listing mnemonic1 (label-text l))) ;; TODO should show mnemonic1 when it's used, or mnemonic2
589 (asm-at-assembly ;; TODO seems to mix up generation of call vs rcall, see the rom_get example FOO
591 (let ((dist (- (label-pos l) (+ self 2))))
592 (if (and (>= dist -2048)
598 (let ((dist (- (label-pos l) (+ self 2))))
599 (generate1 (modulo (quotient dist 2) 2048))))
603 (let ((pos (label-pos l)))
604 (if (and (< pos (expt 2 21))
606 (generate2 (quotient pos 2))
607 (error "goto branch target is too far or unaligned" l pos))))))))
609 ; Literal operations.
615 (make-listing "addlw" (lit-text k)))
617 (asm-16 (bitmask "0000 1111 kkkk kkkk" (lit k))))))
623 (make-listing "andlw" (lit-text k)))
625 (asm-16 (bitmask "0000 1011 kkkk kkkk" (lit k))))))
631 (make-listing "iorlw" (lit-text k)))
633 (asm-16 (bitmask "0000 1001 kkkk kkkk" (lit k))))))
639 (make-listing "lfsr" (file-text f) (lit-text k)))
641 (asm-16 (bitmask "1110 1110 00ff kkkk" (file f) (quotient (lit k) 256)))
642 (asm-16 (bitmask "1111 0000 kkkk kkkk" (modulo (lit k) 256))))))
648 (make-listing "movlb" (lit-text k)))
650 (asm-16 (bitmask "0000 0001 0000 kkkk" (lit k))))))
656 (make-listing "movlw" (lit-text k)))
658 (asm-16 (bitmask "0000 1110 kkkk kkkk" (lit k))))))
664 (make-listing "mullw" (lit-text k)))
666 (asm-16 (bitmask "0000 1101 kkkk kkkk" (lit k))))))
672 (make-listing "retlw" (lit-text k)))
674 (asm-16 (bitmask "0000 1100 kkkk kkkk" (lit k))))))
680 (make-listing "sublw" (lit-text k)))
682 (asm-16 (bitmask "0000 1000 kkkk kkkk" (lit k))))))
688 (make-listing "xorlw" (lit-text k)))
690 (asm-16 (bitmask "0000 1010 kkkk kkkk" (lit k))))))
692 ; Data memory program memory operations.
698 (make-listing "tblrd*"))
700 (asm-16 (bitmask "0000 0000 0000 1000")))))
706 (make-listing "tblrd*+"))
708 (asm-16 (bitmask "0000 0000 0000 1001")))))
714 (make-listing "tblrd*-"))
716 (asm-16 (bitmask "0000 0000 0000 1010")))))
722 (make-listing "tblrd+*"))
724 (asm-16 (bitmask "0000 0000 0000 1011")))))
730 (make-listing "tblwt*"))
732 (asm-16 (bitmask "0000 0000 0000 1100")))))
738 (make-listing "tblwt*+"))
740 (asm-16 (bitmask "0000 0000 0000 1101")))))
746 (make-listing "tblwt*-"))
748 (asm-16 (bitmask "0000 0000 0000 1110")))))
754 (make-listing "tblwt+*"))
756 (asm-16 (bitmask "0000 0000 0000 1111")))))
758 ;------------------------------------------------------------------------------
768 (make-listing "andlw" (lit-text k)))
770 (asm-16 (+ #b0000101100000000 (lit8 k))))))
776 (make-listing "iorlw" (lit-text k)))
778 (asm-16 (+ #b0000100100000000 (lit8 k))))))
784 (make-listing "lfsr" (lit-text f) "," (lit-text k)))
786 (asm-16 (+ #b1110111000000000 (* (lit2 f) 16) (quotient (lit12 k) 256)))
787 (asm-16 (+ #b1111000000000000 (modulo (lit12 k) 256))))))
793 (make-listing "movlb" (lit-text k)))
795 (asm-16 (+ #b0000000100000000 (lit4 k))))))
801 (make-listing "movlw" (lit-text k)))
803 (asm-16 (+ #b0000111000000000 (lit8 k))))))
809 (make-listing "mullw" (lit-text k)))
811 (asm-16 (+ #b0000110100000000 (lit8 k))))))
817 (make-listing "retlw" (lit-text k)))
819 (asm-16 (+ #b0000110000000000 (lit8 k))))))
825 (make-listing "sublw" (lit-text k)))
827 (asm-16 (+ #b0000100000000000 (lit8 k))))))
833 (make-listing "xorlw" (lit-text k)))
835 (asm-16 (+ #b0000101000000000 (lit8 k))))))
841 (make-listing "tblrd*"))
843 (asm-16 #b0000000000001000))))
849 (make-listing "tblrd*+"))
851 (asm-16 #b0000000000001001))))
857 (make-listing "tblrd*-"))
859 (asm-16 #b0000000000001010))))
865 (make-listing "tblrd+*"))
867 (asm-16 #b0000000000001011))))
873 (make-listing "tblwt*"))
875 (asm-16 #b0000000000001100))))
881 (make-listing "tblwt*+"))
883 (asm-16 #b0000000000001101))))
889 (make-listing "tblwt*-"))
891 (asm-16 #b0000000000001110))))
897 (make-listing "tblwt+*"))
899 (asm-16 #b0000000000001111))))
902 (if (and (>= n 0) (<= n 3))
904 (error "2 bit literal expected but got" n)))
907 (if (and (>= n 0) (<= n 255))
909 (error "8 bit literal expected but got" n)))
912 (if (and (>= n 0) (<= n 2047))
914 (error "12 bit literal expected but got" n)))
918 (define (make-instruction cycles listing-thunk code-thunk)
922 (define (make-listing mnemonic . operands)
924 (define (operand-list operands)
927 (let ((rest (operand-list (cdr operands))))
928 (string-append (car operands)
929 (if (string=? rest "")
931 (string-append ", " rest))))))
936 (make-string (- 8 (string-length mnemonic)) #\space)
937 (operand-list operands))))
942 (else (error "destination bit must be w or f"))))
944 (define (dest-text d default)
945 (cond ((eq? d default) "")
948 (else (error "destination bit must be w or f"))))
953 (else (error "access bit must be a or b"))))
955 (define (access-text a default)
956 (cond ((eq? a default) "")
959 (else (error "access bit must be a or b"))))
969 (string-append "0x" (number->string k 16))))
972 (string-append "-" (text (abs k)))
982 (if (or (>= f #xf80) (< #x080))
984 (error "illegal file register")))
986 (define (file-full f)
989 (define (file-text f)
990 (let ((x (assv f file-reg-names)))
992 (symbol->string (cdr x))
995 (define (label-text label)
997 (string-append "0x" (number->string label 16))
998 (symbol->string (asm-label-id label))))
1000 (define (label-pos label)
1003 (asm-label-pos label)))
1005 ;------------------------------------------------------------------------------
1010 (define STKPTR #xffc)
1011 (define PCLATU #xffb)
1012 (define PCLATH #xffa)
1014 (define TBLPTRU #xff8)
1015 (define TBLPTRH #xff7)
1016 (define TBLPTRL #xff6)
1017 (define TABLAT #xff5)
1018 (define PRODH #xff4)
1019 (define PRODL #xff3)
1020 (define INDF0 #xfef)
1021 (define POSTINC0 #xfee)
1022 (define POSTDEC0 #xfed)
1023 (define PREINC0 #xfec)
1024 (define PLUSW0 #xfeb)
1025 (define FSR0H #xfea)
1026 (define FSR0L #xfe9)
1028 (define INDF1 #xfe7)
1029 (define POSTINC1 #xfe6)
1030 (define POSTDEC1 #xfe5)
1031 (define PREINC1 #xfe4)
1032 (define PLUSW1 #xfe3)
1033 (define FSR1H #xfe2)
1034 (define FSR1L #xfe1)
1036 (define INDF2 #xfdf)
1037 (define POSTINC2 #xfde)
1038 (define POSTDEC2 #xfdd)
1039 (define PREINC2 #xfdc)
1040 (define PLUSW2 #xfdb)
1041 (define FSR2H #xfda)
1042 (define FSR2L #xfd9)
1043 (define STATUS #xfd8)
1044 (define TMR1H #xfcf)
1045 (define TMR1L #xfce)
1046 (define PORTE #xf84)
1047 (define PORTD #xf83)
1048 (define PORTC #xf82)
1049 (define PORTB #xf81)
1050 (define PORTA #xf80)
1052 (define file-reg-names '(
1150 ;------------------------------------------------------------------------------
1152 (define (label-offset-reference label offset)
1157 (asm-16 (+ (asm-label-pos label) offset)))))
1159 (define (label-instr label opcode)
1164 (let ((pos (asm-label-pos label)))
1165 (asm-8 (+ (quotient pos 256) opcode))
1166 (asm-8 (modulo pos 256))))))
1168 ;------------------------------------------------------------------------------
1170 (define irda_send_newline #x0078)
1171 (define irda_send #x007E)
1172 (define irda_recv_with_1_sec_timeout #x00A2)
1173 (define irda_recv #x00A4)
1174 (define sec_sleep #x00B0)
1175 (define msec_sleep #x00B6)
1176 (define delay_7 #x00D4)
1177 (define led_set #x00D6)
1178 (define bit_set #x00EC)
1179 (define FLASH_execute_erase #x0106)
1180 (define FLASH_execute_write #x0108)
1181 (define parse_hex_byte #x0184)
1182 (define parse_hex_digit #x0194)
1183 (define irda_send_hex #x01AE)
1184 (define irda_send_nibble #x01B6)
1186 ;------------------------------------------------------------------------------