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
601 (let ((dist (- (label-pos l) (+ self 2))))
602 (if (and (>= dist -2048)
608 (let ((dist (- (label-pos l) (+ self 2))))
609 (generate1 (modulo (quotient dist 2) 2048))))
613 (let ((pos (label-pos l)))
614 (if (and (< pos (expt 2 21))
616 (generate2 (quotient pos 2))
617 (error "goto branch target is too far or unaligned" l pos))))))))
619 ; Literal operations.
625 (make-listing "addlw" (lit-text k)))
627 (asm-16 (bitmask "0000 1111 kkkk kkkk" (lit k))))))
633 (make-listing "andlw" (lit-text k)))
635 (asm-16 (bitmask "0000 1011 kkkk kkkk" (lit k))))))
641 (make-listing "iorlw" (lit-text k)))
643 (asm-16 (bitmask "0000 1001 kkkk kkkk" (lit k))))))
649 (make-listing "lfsr" (file-text f) (lit-text k)))
651 (asm-16 (bitmask "1110 1110 00ff kkkk" (file f) (quotient (lit k) 256)))
652 (asm-16 (bitmask "1111 0000 kkkk kkkk" (modulo (lit k) 256))))))
658 (make-listing "movlb" (lit-text k)))
660 (asm-16 (bitmask "0000 0001 0000 kkkk" (lit k))))))
666 (make-listing "movlw" (lit-text k)))
668 (asm-16 (bitmask "0000 1110 kkkk kkkk" (lit k))))))
674 (make-listing "mullw" (lit-text k)))
676 (asm-16 (bitmask "0000 1101 kkkk kkkk" (lit k))))))
682 (make-listing "retlw" (lit-text k)))
684 (asm-16 (bitmask "0000 1100 kkkk kkkk" (lit k))))))
690 (make-listing "sublw" (lit-text k)))
692 (asm-16 (bitmask "0000 1000 kkkk kkkk" (lit k))))))
698 (make-listing "xorlw" (lit-text k)))
700 (asm-16 (bitmask "0000 1010 kkkk kkkk" (lit k))))))
702 ; Data memory program memory operations.
708 (make-listing "tblrd*"))
710 (asm-16 (bitmask "0000 0000 0000 1000")))))
716 (make-listing "tblrd*+"))
718 (asm-16 (bitmask "0000 0000 0000 1001")))))
724 (make-listing "tblrd*-"))
726 (asm-16 (bitmask "0000 0000 0000 1010")))))
732 (make-listing "tblrd+*"))
734 (asm-16 (bitmask "0000 0000 0000 1011")))))
740 (make-listing "tblwt*"))
742 (asm-16 (bitmask "0000 0000 0000 1100")))))
748 (make-listing "tblwt*+"))
750 (asm-16 (bitmask "0000 0000 0000 1101")))))
756 (make-listing "tblwt*-"))
758 (asm-16 (bitmask "0000 0000 0000 1110")))))
764 (make-listing "tblwt+*"))
766 (asm-16 (bitmask "0000 0000 0000 1111")))))
768 ;------------------------------------------------------------------------------
778 (make-listing "andlw" (lit-text k)))
780 (asm-16 (+ #b0000101100000000 (lit8 k))))))
786 (make-listing "iorlw" (lit-text k)))
788 (asm-16 (+ #b0000100100000000 (lit8 k))))))
794 (make-listing "lfsr" (lit-text f) "," (lit-text k)))
796 (asm-16 (+ #b1110111000000000 (* (lit2 f) 16) (quotient (lit12 k) 256)))
797 (asm-16 (+ #b1111000000000000 (modulo (lit12 k) 256))))))
803 (make-listing "movlb" (lit-text k)))
805 (asm-16 (+ #b0000000100000000 (lit4 k))))))
811 (make-listing "movlw" (lit-text k)))
813 (asm-16 (+ #b0000111000000000 (lit8 k))))))
819 (make-listing "mullw" (lit-text k)))
821 (asm-16 (+ #b0000110100000000 (lit8 k))))))
827 (make-listing "retlw" (lit-text k)))
829 (asm-16 (+ #b0000110000000000 (lit8 k))))))
835 (make-listing "sublw" (lit-text k)))
837 (asm-16 (+ #b0000100000000000 (lit8 k))))))
843 (make-listing "xorlw" (lit-text k)))
845 (asm-16 (+ #b0000101000000000 (lit8 k))))))
851 (make-listing "tblrd*"))
853 (asm-16 #b0000000000001000))))
859 (make-listing "tblrd*+"))
861 (asm-16 #b0000000000001001))))
867 (make-listing "tblrd*-"))
869 (asm-16 #b0000000000001010))))
875 (make-listing "tblrd+*"))
877 (asm-16 #b0000000000001011))))
883 (make-listing "tblwt*"))
885 (asm-16 #b0000000000001100))))
891 (make-listing "tblwt*+"))
893 (asm-16 #b0000000000001101))))
899 (make-listing "tblwt*-"))
901 (asm-16 #b0000000000001110))))
907 (make-listing "tblwt+*"))
909 (asm-16 #b0000000000001111))))
912 (if (and (>= n 0) (<= n 3))
914 (error "2 bit literal expected but got" n)))
917 (if (and (>= n 0) (<= n 255))
919 (error "8 bit literal expected but got" n)))
922 (if (and (>= n 0) (<= n 2047))
924 (error "12 bit literal expected but got" n)))
928 (define (make-instruction cycles listing-thunk code-thunk)
932 (define (make-listing mnemonic . operands)
934 (define (operand-list operands)
937 (let ((rest (operand-list (cdr operands))))
938 (string-append (car operands)
939 (if (string=? rest "")
941 (string-append ", " rest))))))
946 (make-string (- 8 (string-length mnemonic)) #\space)
947 (operand-list operands))))
952 (else (error "destination bit must be w or f"))))
954 (define (dest-text d default)
955 (cond ((eq? d default) "")
958 (else (error "destination bit must be w or f"))))
963 (else (error "access bit must be a or b"))))
965 (define (access-text a default)
966 (cond ((eq? a default) "")
969 (else (error "access bit must be a or b"))))
979 (string-append "0x" (number->string k 16))))
982 (string-append "-" (text (abs k)))
992 (if (or (>= f #xf80) (< #x080))
994 (error "illegal file register")))
996 (define (file-full f)
999 (define (file-text f)
1000 (let ((x (assv f file-reg-names)))
1002 (symbol->string (cdr x))
1003 (let ((x (table-ref register-table f #f)))
1005 (apply string-append-with-separator (cons "/" x)) ;; TODO unreadable with picobit
1008 (define (label-text label)
1010 (string-append "0x" (number->string label 16))
1011 (symbol->string (asm-label-id label))))
1013 (define (label-pos label)
1016 (asm-label-pos label)))
1018 ;------------------------------------------------------------------------------
1023 (define STKPTR #xffc)
1024 (define PCLATU #xffb)
1025 (define PCLATH #xffa)
1027 (define TBLPTRU #xff8)
1028 (define TBLPTRH #xff7)
1029 (define TBLPTRL #xff6)
1030 (define TABLAT #xff5)
1031 (define PRODH #xff4)
1032 (define PRODL #xff3)
1033 (define INDF0 #xfef)
1034 (define POSTINC0 #xfee)
1035 (define POSTDEC0 #xfed)
1036 (define PREINC0 #xfec)
1037 (define PLUSW0 #xfeb)
1038 (define FSR0H #xfea)
1039 (define FSR0L #xfe9)
1041 (define INDF1 #xfe7)
1042 (define POSTINC1 #xfe6)
1043 (define POSTDEC1 #xfe5)
1044 (define PREINC1 #xfe4)
1045 (define PLUSW1 #xfe3)
1046 (define FSR1H #xfe2)
1047 (define FSR1L #xfe1)
1049 (define INDF2 #xfdf)
1050 (define POSTINC2 #xfde)
1051 (define POSTDEC2 #xfdd)
1052 (define PREINC2 #xfdc)
1053 (define PLUSW2 #xfdb)
1054 (define FSR2H #xfda)
1055 (define FSR2L #xfd9)
1056 (define STATUS #xfd8)
1057 (define TMR1H #xfcf)
1058 (define TMR1L #xfce)
1059 (define PORTE #xf84)
1060 (define PORTD #xf83)
1061 (define PORTC #xf82)
1062 (define PORTB #xf81)
1063 (define PORTA #xf80)
1065 (define file-reg-names '(
1163 ;------------------------------------------------------------------------------
1165 (define (label-offset-reference label offset)
1170 (asm-16 (+ (asm-label-pos label) offset)))))
1172 (define (label-instr label opcode)
1177 (let ((pos (asm-label-pos label)))
1178 (asm-8 (+ (quotient pos 256) opcode))
1179 (asm-8 (modulo pos 256))))))
1181 ;------------------------------------------------------------------------------
1183 (define irda_send_newline #x0078)
1184 (define irda_send #x007E)
1185 (define irda_recv_with_1_sec_timeout #x00A2)
1186 (define irda_recv #x00A4)
1187 (define sec_sleep #x00B0)
1188 (define msec_sleep #x00B6)
1189 (define delay_7 #x00D4)
1190 (define led_set #x00D6)
1191 (define bit_set #x00EC)
1192 (define FLASH_execute_erase #x0106)
1193 (define FLASH_execute_write #x0108)
1194 (define parse_hex_byte #x0184)
1195 (define parse_hex_digit #x0194)
1196 (define irda_send_hex #x01AE)
1197 (define irda_send_nibble #x01B6)
1199 ;------------------------------------------------------------------------------