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)))))
414 (make-long-absolute-branch-instruction
418 (asm-16 (bitmask "1110 1111 nnnn nnnn" (modulo pos-20bit (expt 2 8))))
419 (asm-16 (bitmask "1111 nnnn nnnn nnnn" (quotient pos-20bit (expt 2 8)))))))
421 (define (bra-or-goto l)
422 (make-long-relative-or-absolute-branch-instruction
427 (asm-16 (bitmask "1101 0nnn nnnn nnnn" dist-11bit)))
429 (asm-16 (bitmask "1110 1111 nnnn nnnn" (modulo pos-20bit (expt 2 8))))
430 (asm-16 (bitmask "1111 nnnn nnnn nnnn" (quotient pos-20bit (expt 2 8)))))))
433 (make-short-relative-branch-instruction
437 (asm-16 (bitmask "1110 0000 nnnn nnnn" dist-8bit)))))
439 (define (call l #!optional (s 0))
443 (make-listing "call" (label-text l) (lit-text s)))
449 (let ((pos-div-2 (quotient (label-pos l) 2)))
450 (asm-16 (bitmask "1110 110s kkkk kkkk" s (quotient pos-div-2 4096)))
451 (asm-16 (bitmask "1111 kkkk kkkk kkkk" (modulo pos-div-2 4096)))))))))
457 (make-listing "clrwdt"))
459 (asm-16 (bitmask "0000 0000 0000 0100")))))
465 (make-listing "daw"))
467 (asm-16 (bitmask "0000 0000 0000 0111")))))
473 (make-listing "nop"))
475 (asm-16 (bitmask "0000 0000 0000 0000")))))
481 (make-listing "pop"))
483 (asm-16 (bitmask "0000 0000 0000 0110")))))
489 (make-listing "push"))
491 (asm-16 (bitmask "0000 0000 0000 0101")))))
494 (make-long-relative-branch-instruction
498 (asm-16 (bitmask "1101 1nnn nnnn nnnn" dist-11bit)))))
500 (define (rcall-or-call l)
501 (make-long-relative-or-absolute-branch-instruction
506 (asm-16 (bitmask "1101 1nnn nnnn nnnn" dist-11bit)))
508 (asm-16 (bitmask "1110 1100 nnnn nnnn" (modulo pos-20bit (expt 2 8))))
509 (asm-16 (bitmask "1111 nnnn nnnn nnnn" (quotient pos-20bit (expt 2 8)))))))
515 (make-listing "reset"))
517 (asm-16 (bitmask "0000 0000 1111 1111")))))
519 (define (retfie #!optional (s 0))
523 (make-listing "retfie" (lit-text s)))
525 (asm-16 (bitmask "0000 0000 0001 000s" s)))))
527 (define (return #!optional (s 0))
531 (make-listing "return" (lit-text s)))
533 (asm-16 (bitmask "0000 0000 0001 001s" s)))))
539 (make-listing "sleep"))
541 (asm-16 (bitmask "0000 0000 0000 0011")))))
543 (define (make-short-relative-branch-instruction mnemonic l generate)
547 (make-listing mnemonic (label-text l)))
553 (let ((dist (- (label-pos l) (+ self 2))))
554 (if (and (>= dist -256)
557 (generate (modulo (quotient dist 2) 256))
558 (error "short relative branch target is too far or improperly aligned" l dist))))))))
560 (define (make-long-relative-branch-instruction mnemonic l generate)
564 (make-listing mnemonic (label-text l)))
570 (let ((dist (- (label-pos l) (+ self 2))))
571 (if (and (>= dist -2048)
574 (generate (modulo (quotient dist 2) 2048))
575 (error "long relative branch target is too far or improperly aligned" l dist))))))))
577 (define (make-long-absolute-branch-instruction mnemonic l generate)
581 (make-listing mnemonic (label-text l)))
587 (let ((pos (label-pos l)))
588 (if (and (< pos (expt 2 21))
590 (generate (quotient pos 2))
591 (error "goto branch target is too far or unaligned" l pos))))))))
593 (define (make-long-relative-or-absolute-branch-instruction mnemonic1 mnemonic2 l generate1 generate2)
597 (make-listing mnemonic1 (label-text l))) ;; TODO should show mnemonic1 when it's used, or mnemonic2
602 (let ((dist (- (label-pos l) (+ self 2))))
603 (if (and (>= dist -2048)
609 (let ((dist (- (label-pos l) (+ self 2))))
610 (generate1 (modulo (quotient dist 2) 2048))))
615 (let ((pos (label-pos l)))
616 (if (and (< pos (expt 2 21))
618 (generate2 (quotient pos 2))
619 (error "goto branch target is too far or unaligned" l pos))))))))
621 ; Literal operations.
627 (make-listing "addlw" (lit-text k)))
629 (asm-16 (bitmask "0000 1111 kkkk kkkk" (lit k))))))
635 (make-listing "andlw" (lit-text k)))
637 (asm-16 (bitmask "0000 1011 kkkk kkkk" (lit k))))))
643 (make-listing "iorlw" (lit-text k)))
645 (asm-16 (bitmask "0000 1001 kkkk kkkk" (lit k))))))
651 (make-listing "lfsr" (file-text f) (lit-text k)))
653 (asm-16 (bitmask "1110 1110 00ff kkkk" (file f) (quotient (lit k) 256)))
654 (asm-16 (bitmask "1111 0000 kkkk kkkk" (modulo (lit k) 256))))))
660 (make-listing "movlb" (lit-text k)))
662 (asm-16 (bitmask "0000 0001 0000 kkkk" (lit k))))))
668 (make-listing "movlw" (lit-text k)))
670 (asm-16 (bitmask "0000 1110 kkkk kkkk" (lit k))))))
676 (make-listing "mullw" (lit-text k)))
678 (asm-16 (bitmask "0000 1101 kkkk kkkk" (lit k))))))
684 (make-listing "retlw" (lit-text k)))
686 (asm-16 (bitmask "0000 1100 kkkk kkkk" (lit k))))))
692 (make-listing "sublw" (lit-text k)))
694 (asm-16 (bitmask "0000 1000 kkkk kkkk" (lit k))))))
700 (make-listing "xorlw" (lit-text k)))
702 (asm-16 (bitmask "0000 1010 kkkk kkkk" (lit k))))))
704 ; Data memory program memory operations.
710 (make-listing "tblrd*"))
712 (asm-16 (bitmask "0000 0000 0000 1000")))))
718 (make-listing "tblrd*+"))
720 (asm-16 (bitmask "0000 0000 0000 1001")))))
726 (make-listing "tblrd*-"))
728 (asm-16 (bitmask "0000 0000 0000 1010")))))
734 (make-listing "tblrd+*"))
736 (asm-16 (bitmask "0000 0000 0000 1011")))))
742 (make-listing "tblwt*"))
744 (asm-16 (bitmask "0000 0000 0000 1100")))))
750 (make-listing "tblwt*+"))
752 (asm-16 (bitmask "0000 0000 0000 1101")))))
758 (make-listing "tblwt*-"))
760 (asm-16 (bitmask "0000 0000 0000 1110")))))
766 (make-listing "tblwt+*"))
768 (asm-16 (bitmask "0000 0000 0000 1111")))))
770 ;------------------------------------------------------------------------------
780 (make-listing "andlw" (lit-text k)))
782 (asm-16 (+ #b0000101100000000 (lit8 k))))))
788 (make-listing "iorlw" (lit-text k)))
790 (asm-16 (+ #b0000100100000000 (lit8 k))))))
796 (make-listing "lfsr" (lit-text f) "," (lit-text k)))
798 (asm-16 (+ #b1110111000000000 (* (lit2 f) 16) (quotient (lit12 k) 256)))
799 (asm-16 (+ #b1111000000000000 (modulo (lit12 k) 256))))))
805 (make-listing "movlb" (lit-text k)))
807 (asm-16 (+ #b0000000100000000 (lit4 k))))))
813 (make-listing "movlw" (lit-text k)))
815 (asm-16 (+ #b0000111000000000 (lit8 k))))))
821 (make-listing "mullw" (lit-text k)))
823 (asm-16 (+ #b0000110100000000 (lit8 k))))))
829 (make-listing "retlw" (lit-text k)))
831 (asm-16 (+ #b0000110000000000 (lit8 k))))))
837 (make-listing "sublw" (lit-text k)))
839 (asm-16 (+ #b0000100000000000 (lit8 k))))))
845 (make-listing "xorlw" (lit-text k)))
847 (asm-16 (+ #b0000101000000000 (lit8 k))))))
853 (make-listing "tblrd*"))
855 (asm-16 #b0000000000001000))))
861 (make-listing "tblrd*+"))
863 (asm-16 #b0000000000001001))))
869 (make-listing "tblrd*-"))
871 (asm-16 #b0000000000001010))))
877 (make-listing "tblrd+*"))
879 (asm-16 #b0000000000001011))))
885 (make-listing "tblwt*"))
887 (asm-16 #b0000000000001100))))
893 (make-listing "tblwt*+"))
895 (asm-16 #b0000000000001101))))
901 (make-listing "tblwt*-"))
903 (asm-16 #b0000000000001110))))
909 (make-listing "tblwt+*"))
911 (asm-16 #b0000000000001111))))
914 (if (and (>= n 0) (<= n 3))
916 (error "2 bit literal expected but got" n)))
919 (if (and (>= n 0) (<= n 255))
921 (error "8 bit literal expected but got" n)))
924 (if (and (>= n 0) (<= n 2047))
926 (error "12 bit literal expected but got" n)))
930 (define (make-instruction cycles listing-thunk code-thunk)
934 (define (make-listing mnemonic . operands)
936 (define (operand-list operands)
939 (let ((rest (operand-list (cdr operands))))
940 (string-append (car operands)
941 (if (string=? rest "")
943 (string-append ", " rest))))))
948 (make-string (- 8 (string-length mnemonic)) #\space)
949 (operand-list operands))))
954 (else (error "destination bit must be w or f"))))
956 (define (dest-text d default)
957 (cond ((eq? d default) "")
960 (else (error "destination bit must be w or f"))))
965 (else (error "access bit must be a or b"))))
967 (define (access-text a default)
968 (cond ((eq? a default) "")
971 (else (error "access bit must be a or b"))))
981 (string-append "0x" (number->string k 16))))
984 (string-append "-" (text (abs k)))
994 (if (or (>= f #xf80) (< #x080))
996 (error "illegal file register")))
998 (define (file-full f)
1001 (define (file-text f)
1002 (let ((x (assv f file-reg-names)))
1004 (symbol->string (cdr x))
1005 (let ((x (table-ref register-table f #f)))
1007 (apply string-append-with-separator (cons "/" x)) ;; TODO unreadable with picobit
1010 (define (label-text label)
1012 (string-append "0x" (number->string label 16))
1013 (symbol->string (asm-label-id label))))
1015 (define (label-pos label)
1018 (asm-label-pos label)))
1020 ;------------------------------------------------------------------------------
1025 (define STKPTR #xffc)
1026 (define PCLATU #xffb)
1027 (define PCLATH #xffa)
1029 (define TBLPTRU #xff8)
1030 (define TBLPTRH #xff7)
1031 (define TBLPTRL #xff6)
1032 (define TABLAT #xff5)
1033 (define PRODH #xff4)
1034 (define PRODL #xff3)
1035 (define INDF0 #xfef)
1036 (define POSTINC0 #xfee)
1037 (define POSTDEC0 #xfed)
1038 (define PREINC0 #xfec)
1039 (define PLUSW0 #xfeb)
1040 (define FSR0H #xfea)
1041 (define FSR0L #xfe9)
1043 (define INDF1 #xfe7)
1044 (define POSTINC1 #xfe6)
1045 (define POSTDEC1 #xfe5)
1046 (define PREINC1 #xfe4)
1047 (define PLUSW1 #xfe3)
1048 (define FSR1H #xfe2)
1049 (define FSR1L #xfe1)
1051 (define INDF2 #xfdf)
1052 (define POSTINC2 #xfde)
1053 (define POSTDEC2 #xfdd)
1054 (define PREINC2 #xfdc)
1055 (define PLUSW2 #xfdb)
1056 (define FSR2H #xfda)
1057 (define FSR2L #xfd9)
1058 (define STATUS #xfd8)
1059 (define TMR1H #xfcf)
1060 (define TMR1L #xfce)
1061 (define PORTE #xf84)
1062 (define PORTD #xf83)
1063 (define PORTC #xf82)
1064 (define PORTB #xf81)
1065 (define PORTA #xf80)
1067 (define file-reg-names '(
1165 ;------------------------------------------------------------------------------
1167 (define (label-offset-reference label offset)
1172 (asm-16 (+ (asm-label-pos label) offset)))))
1174 (define (label-instr label opcode)
1179 (let ((pos (asm-label-pos label)))
1180 (asm-8 (+ (quotient pos 256) opcode))
1181 (asm-8 (modulo pos 256))))))
1183 ;------------------------------------------------------------------------------
1185 (define irda_send_newline #x0078)
1186 (define irda_send #x007E)
1187 (define irda_recv_with_1_sec_timeout #x00A2)
1188 (define irda_recv #x00A4)
1189 (define sec_sleep #x00B0)
1190 (define msec_sleep #x00B6)
1191 (define delay_7 #x00D4)
1192 (define led_set #x00D6)
1193 (define bit_set #x00EC)
1194 (define FLASH_execute_erase #x0106)
1195 (define FLASH_execute_write #x0108)
1196 (define parse_hex_byte #x0184)
1197 (define parse_hex_digit #x0194)
1198 (define irda_send_hex #x01AE)
1199 (define irda_send_nibble #x01B6)
1201 ;------------------------------------------------------------------------------