5 (define-macro (bitmask encoding . field-values)
9 (fields (list (list #\space 0 0))))
10 (if (< i (string-length encoding))
11 (let ((c (string-ref encoding i)))
28 (if (and (char=? c (car (car fields)))
29 (= pos (caddr (car fields))))
31 (set-car! (cddr (car fields)) (+ pos 1))
39 (cons (list c pos (+ pos 1)) fields))))))
42 (error "invalid bitmask" encoding))
46 (let* ((width (- (caddr f) (cadr f)))
47 (shift (- pos (caddr f))))
54 (cdr (reverse fields))
57 (define (bitfield encoding name limit shift value)
58 (if (or (< value 0) (>= value limit))
59 (error "value does not fit in field" name value encoding)
60 (arithmetic-shift value shift)))
62 ;------------------------------------------------------------------------------
64 ; Byte-oriented file register operations.
66 (define (addwf f #!optional (d 'f) (a 'a))
70 (make-listing "addwf" (file-text f) (dest-text d 'f) (access-text a 'a)))
72 (asm-16 (bitmask "0010 01da ffff ffff" (dest d) (access a) (file f))))))
74 (define (addwfc f #!optional (d 'f) (a 'a))
78 (make-listing "addwfc" (file-text f) (dest-text d 'f) (access-text a 'a)))
80 (asm-16 (bitmask "0010 00da ffff ffff" (dest d) (access a) (file f))))))
82 (define (andwf f #!optional (d 'f) (a 'a))
86 (make-listing "andwf" (file-text f) (dest-text d 'f) (access-text a 'a)))
88 (asm-16 (bitmask "0001 01da ffff ffff" (dest d) (access a) (file f))))))
90 (define (clrf f #!optional (a 'a))
94 (make-listing "clrf" (file-text f) (access-text a 'a)))
96 (asm-16 (bitmask "0110 101a ffff ffff" (access a) (file f))))))
98 (define (comf f #!optional (d 'f) (a 'a))
102 (make-listing "comf" (file-text f) (dest-text d 'f) (access-text a 'a)))
104 (asm-16 (bitmask "0001 11da ffff ffff" (dest d) (access a) (file f))))))
106 (define (cpfseq f #!optional (a 'a))
110 (make-listing "cpfseq" (file-text f) (access-text a 'a)))
112 (asm-16 (bitmask "0110 001a ffff ffff" (access a) (file f))))))
114 (define (cpfsgt f #!optional (a 'a))
118 (make-listing "cpfsgt" (file-text f) (access-text a 'a)))
120 (asm-16 (bitmask "0110 010a ffff ffff" (access a) (file f))))))
122 (define (cpfslt f #!optional (a 'a))
126 (make-listing "cpfslt" (file-text f) (access-text a 'a)))
128 (asm-16 (bitmask "0110 000a ffff ffff" (access a) (file f))))))
130 (define (decf f #!optional (d 'f) (a 'a))
134 (make-listing "decf" (file-text f) (dest-text d 'f) (access-text a 'a)))
136 (asm-16 (bitmask "0000 01da ffff ffff" (dest d) (access a) (file f))))))
138 (define (decfsz f #!optional (d 'f) (a 'a))
142 (make-listing "decfsz" (file-text f) (dest-text d 'f) (access-text a 'a)))
144 (asm-16 (bitmask "0010 11da ffff ffff" (dest d) (access a) (file f))))))
146 (define (dcfsnz f #!optional (d 'f) (a 'a))
150 (make-listing "dcfsnz" (file-text f) (dest-text d 'f) (access-text a 'a)))
152 (asm-16 (bitmask "0100 11da ffff ffff" (dest d) (access a) (file f))))))
154 (define (incf f #!optional (d 'f) (a 'a))
158 (make-listing "incf" (file-text f) (dest-text d 'f) (access-text a 'a)))
160 (asm-16 (bitmask "0010 10da ffff ffff" (dest d) (access a) (file f))))))
162 (define (incfsz f #!optional (d 'f) (a 'a))
166 (make-listing "incfsz" (file-text f) (dest-text d 'f) (access-text a 'a)))
168 (asm-16 (bitmask "0011 11da ffff ffff" (dest d) (access a) (file f))))))
170 (define (infsnz f #!optional (d 'f) (a 'a))
174 (make-listing "infsnz" (file-text f) (dest-text d 'f) (access-text a 'a)))
176 (asm-16 (bitmask "0100 10da ffff ffff" (dest d) (access a) (file f))))))
178 (define (iorwf f #!optional (d 'f) (a 'a))
182 (make-listing "iorwf" (file-text f) (dest-text d 'f) (access-text a 'a)))
184 (asm-16 (bitmask "0001 00da ffff ffff" (dest d) (access a) (file f))))))
186 (define (movf f #!optional (d 'f) (a 'a))
190 (make-listing "movf" (file-text f) (dest-text d 'f) (access-text a 'a)))
192 (asm-16 (bitmask "0101 00da ffff ffff" (dest d) (access a) (file f))))))
194 (define (movff fs fd)
198 (make-listing "movff" (file-text fs) (file-text fd)))
200 (asm-16 (bitmask "1100 ffff ffff ffff" (file-full fs)))
201 (asm-16 (bitmask "1111 ffff ffff ffff" (file-full fd))))))
203 (define (movwf f #!optional (a 'a))
207 (make-listing "movwf" (file-text f) (access-text a 'a)))
209 (asm-16 (bitmask "0110 111a ffff ffff" (access a) (file f))))))
211 (define (mulwf f #!optional (a 'a))
215 (make-listing "mulwf" (file-text f) (access-text a 'a)))
217 (asm-16 (bitmask "0000 001a ffff ffff" (access a) (file f))))))
219 (define (negf f #!optional (a 'a))
223 (make-listing "negf" (file-text f) (access-text a 'a)))
225 (asm-16 (bitmask "0110 110a ffff ffff" (access a) (file f))))))
227 (define (rlcf f #!optional (d 'f) (a 'a))
231 (make-listing "rlcf" (file-text f) (dest-text d 'f) (access-text a 'a)))
233 (asm-16 (bitmask "0011 01da ffff ffff" (dest d) (access a) (file f))))))
235 (define (rlncf f #!optional (d 'f) (a 'a))
239 (make-listing "rlncf" (file-text f) (dest-text d 'f) (access-text a 'a)))
241 (asm-16 (bitmask "0100 01da ffff ffff" (dest d) (access a) (file f))))))
243 (define (rrcf f #!optional (d 'f) (a 'a))
247 (make-listing "rrcf" (file-text f) (dest-text d 'f) (access-text a 'a)))
249 (asm-16 (bitmask "0011 00da ffff ffff" (dest d) (access a) (file f))))))
251 (define (rrncf f #!optional (d 'f) (a 'a))
255 (make-listing "rrncf" (file-text f) (dest-text d 'f) (access-text a 'a)))
257 (asm-16 (bitmask "0100 00da ffff ffff" (dest d) (access a) (file f))))))
259 (define (setf f #!optional (a 'a))
263 (make-listing "setf" (file-text f) (access-text a 'a)))
265 (asm-16 (bitmask "0110 100a ffff ffff" (access a) (file f))))))
267 (define (subfwb f #!optional (d 'f) (a 'a))
271 (make-listing "subfwb" (file-text f) (dest-text d 'f) (access-text a 'a)))
273 (asm-16 (bitmask "0101 01da ffff ffff" (dest d) (access a) (file f))))))
275 (define (subwf f #!optional (d 'f) (a 'a))
279 (make-listing "subwf" (file-text f) (dest-text d 'f) (access-text a 'a)))
281 (asm-16 (bitmask "0101 11da ffff ffff" (dest d) (access a) (file f))))))
283 (define (subwfb f #!optional (d 'f) (a 'a))
287 (make-listing "subwfb" (file-text f) (dest-text d 'f) (access-text a 'a)))
289 (asm-16 (bitmask "0101 10da ffff ffff" (dest d) (access a) (file f))))))
291 (define (swapf f #!optional (d 'f) (a 'a))
295 (make-listing "swapf" (file-text f) (dest-text d 'f) (access-text a 'a)))
297 (asm-16 (bitmask "0011 10da ffff ffff" (dest d) (access a) (file f))))))
299 (define (tstfsz f #!optional (a 'a))
303 (make-listing "tstfsz" (file-text f) (access-text a 'a)))
305 (asm-16 (bitmask "0110 011a ffff ffff" (access a) (file f))))))
307 (define (xorwf f #!optional (d 'f) (a 'a))
311 (make-listing "xorwf" (file-text f) (dest-text d 'f) (access-text a 'a)))
313 (asm-16 (bitmask "0001 10da ffff ffff" (dest d) (access a) (file f))))))
315 ; Bit-oriented file register operations.
317 (define (bcf f b #!optional (a 'a))
321 (make-listing "bcf" (file-text f) (bit-text b) (access-text a 'a)))
323 (asm-16 (bitmask "1001 bbba ffff ffff" (bit b) (access a) (file f))))))
325 (define (bsf f b #!optional (a 'a))
329 (make-listing "bsf" (file-text f) (bit-text b) (access-text a 'a)))
331 (asm-16 (bitmask "1000 bbba ffff ffff" (bit b) (access a) (file f))))))
333 (define (btfsc f b #!optional (a 'a))
337 (make-listing "btfsc" (file-text f) (bit-text b) (access-text a 'a)))
339 (asm-16 (bitmask "1011 bbba ffff ffff" (bit b) (access a) (file f))))))
341 (define (btfss f b #!optional (a 'a))
345 (make-listing "btfss" (file-text f) (bit-text b) (access-text a 'a)))
347 (asm-16 (bitmask "1010 bbba ffff ffff" (bit b) (access a) (file f))))))
349 (define (btg f b #!optional (a 'a))
353 (make-listing "btg" (file-text f) (bit-text b) (access-text a 'a)))
355 (asm-16 (bitmask "0111 bbba ffff ffff" (bit b) (access a) (file f))))))
357 ; Control operations.
360 (make-short-relative-branch-instruction
364 (asm-16 (bitmask "1110 0010 nnnn nnnn" dist-8bit)))))
367 (make-short-relative-branch-instruction
371 (asm-16 (bitmask "1110 0110 nnnn nnnn" dist-8bit)))))
374 (make-short-relative-branch-instruction
378 (asm-16 (bitmask "1110 0011 nnnn nnnn" dist-8bit)))))
381 (make-short-relative-branch-instruction
385 (asm-16 (bitmask "1110 0111 nnnn nnnn" dist-8bit)))))
388 (make-short-relative-branch-instruction
392 (asm-16 (bitmask "1110 0101 nnnn nnnn" dist-8bit)))))
395 (make-short-relative-branch-instruction
399 (asm-16 (bitmask "1110 0001 nnnn nnnn" dist-8bit)))))
402 (make-short-relative-branch-instruction
406 (asm-16 (bitmask "1110 0100 nnnn nnnn" dist-8bit)))))
409 ;; (make-long-relative-branch-instruction
412 ;; (lambda (dist-11bit)
413 ;; (asm-16 (bitmask "1101 0nnn nnnn nnnn" dist-11bit)))))
415 (define (bra-or-goto l)
416 (make-long-relative-or-absolute-branch-instruction
421 (asm-16 (bitmask "1101 0nnn nnnn nnnn" dist-11bit)))
423 (asm-16 (bitmask "1110 1111 nnnn nnnn" (modulo pos-20bit (expt 2 8))))
424 (asm-16 (bitmask "1111 nnnn nnnn nnnn" (quotient pos-20bit (expt 2 8)))))))
427 (make-short-relative-branch-instruction
431 (asm-16 (bitmask "1110 0000 nnnn nnnn" dist-8bit)))))
433 (define (call l #!optional (s 0))
437 (make-listing "call" (label-text l) (lit-text s)))
443 (let ((pos-div-2 (quotient (label-pos l) 2)))
444 (asm-16 (bitmask "1110 110s kkkk kkkk" s (quotient pos-div-2 4096)))
445 (asm-16 (bitmask "1111 kkkk kkkk kkkk" (modulo pos-div-2 4096)))))))))
451 (make-listing "clrwdt"))
453 (asm-16 (bitmask "0000 0000 0000 0100")))))
459 (make-listing "daw"))
461 (asm-16 (bitmask "0000 0000 0000 0111")))))
467 (make-listing "goto" (label-text l)))
473 (let ((pos-div-2 (quotient (label-pos l) 2)))
474 (asm-16 (bitmask "1110 1111 kkkk kkkk" (quotient pos-div-2 4096)))
475 (asm-16 (bitmask "1111 kkkk kkkk kkkk" (modulo pos-div-2 4096)))))))))
481 (make-listing "nop"))
483 (asm-16 (bitmask "0000 0000 0000 0000")))))
489 (make-listing "pop"))
491 (asm-16 (bitmask "0000 0000 0000 0110")))))
497 (make-listing "push"))
499 (asm-16 (bitmask "0000 0000 0000 0101")))))
502 (make-long-relative-branch-instruction
506 (asm-16 (bitmask "1101 1nnn nnnn nnnn" dist-11bit)))))
508 (define (rcall-or-call l)
509 (make-long-relative-or-absolute-branch-instruction
514 (asm-16 (bitmask "1101 1nnn nnnn nnnn" dist-11bit)))
516 (asm-16 (bitmask "1110 1100 nnnn nnnn" (modulo pos-20bit (expt 2 8))))
517 (asm-16 (bitmask "1111 nnnn nnnn nnnn" (quotient pos-20bit (expt 2 8)))))))
523 (make-listing "reset"))
525 (asm-16 (bitmask "0000 0000 1111 1111")))))
527 (define (retfie #!optional (s 0))
531 (make-listing "retfie" (lit-text s)))
533 (asm-16 (bitmask "0000 0000 0001 000s" s)))))
535 (define (return #!optional (s 0))
539 (make-listing "return" (lit-text s)))
541 (asm-16 (bitmask "0000 0000 0001 001s" s)))))
547 (make-listing "sleep"))
549 (asm-16 (bitmask "0000 0000 0000 0011")))))
551 (define (make-short-relative-branch-instruction mnemonic l generate)
555 (make-listing mnemonic (label-text l)))
561 (let ((dist (- (label-pos l) (+ self 2))))
562 (if (and (>= dist -256)
565 (generate (modulo (quotient dist 2) 256))
566 (error "short relative branch target is too far or improperly aligned" l dist))))))))
568 (define (make-long-relative-branch-instruction mnemonic l generate)
572 (make-listing mnemonic (label-text l)))
578 (let ((dist (- (label-pos l) (+ self 2))))
579 (if (and (>= dist -2048)
582 (generate (modulo (quotient dist 2) 2048))
583 (error "long relative branch target is too far or improperly aligned" l dist))))))))
585 (define (make-long-relative-or-absolute-branch-instruction mnemonic1 mnemonic2 l generate1 generate2)
589 (make-listing mnemonic1 (label-text l))) ;; TODO should show mnemonic1 when it's used, or mnemonic2
591 (asm-at-assembly ;; TODO seems to mix up generation of call vs rcall, see the rom_get example FOO
593 (let ((dist (- (label-pos l) (+ self 2))))
594 (if (and (>= dist -2048)
600 (let ((dist (- (label-pos l) (+ self 2))))
601 (generate1 (modulo (quotient dist 2) 2048))))
605 (let ((pos (label-pos l)))
606 (if (and (< pos (expt 2 21))
608 (generate2 (quotient pos 2))
609 (error "goto branch target is too far or unaligned" l pos))))))))
611 ; Literal operations.
617 (make-listing "addlw" (lit-text k)))
619 (asm-16 (bitmask "0000 1111 kkkk kkkk" (lit k))))))
625 (make-listing "andlw" (lit-text k)))
627 (asm-16 (bitmask "0000 1011 kkkk kkkk" (lit k))))))
633 (make-listing "iorlw" (lit-text k)))
635 (asm-16 (bitmask "0000 1001 kkkk kkkk" (lit k))))))
641 (make-listing "lfsr" (file-text f) (lit-text k)))
643 (asm-16 (bitmask "1110 1110 00ff kkkk" (file f) (quotient (lit k) 256)))
644 (asm-16 (bitmask "1111 0000 kkkk kkkk" (modulo (lit k) 256))))))
650 (make-listing "movlb" (lit-text k)))
652 (asm-16 (bitmask "0000 0001 0000 kkkk" (lit k))))))
658 (make-listing "movlw" (lit-text k)))
660 (asm-16 (bitmask "0000 1110 kkkk kkkk" (lit k))))))
666 (make-listing "mullw" (lit-text k)))
668 (asm-16 (bitmask "0000 1101 kkkk kkkk" (lit k))))))
674 (make-listing "retlw" (lit-text k)))
676 (asm-16 (bitmask "0000 1100 kkkk kkkk" (lit k))))))
682 (make-listing "sublw" (lit-text k)))
684 (asm-16 (bitmask "0000 1000 kkkk kkkk" (lit k))))))
690 (make-listing "xorlw" (lit-text k)))
692 (asm-16 (bitmask "0000 1010 kkkk kkkk" (lit k))))))
694 ; Data memory program memory operations.
700 (make-listing "tblrd*"))
702 (asm-16 (bitmask "0000 0000 0000 1000")))))
708 (make-listing "tblrd*+"))
710 (asm-16 (bitmask "0000 0000 0000 1001")))))
716 (make-listing "tblrd*-"))
718 (asm-16 (bitmask "0000 0000 0000 1010")))))
724 (make-listing "tblrd+*"))
726 (asm-16 (bitmask "0000 0000 0000 1011")))))
732 (make-listing "tblwt*"))
734 (asm-16 (bitmask "0000 0000 0000 1100")))))
740 (make-listing "tblwt*+"))
742 (asm-16 (bitmask "0000 0000 0000 1101")))))
748 (make-listing "tblwt*-"))
750 (asm-16 (bitmask "0000 0000 0000 1110")))))
756 (make-listing "tblwt+*"))
758 (asm-16 (bitmask "0000 0000 0000 1111")))))
760 ;------------------------------------------------------------------------------
770 (make-listing "andlw" (lit-text k)))
772 (asm-16 (+ #b0000101100000000 (lit8 k))))))
778 (make-listing "iorlw" (lit-text k)))
780 (asm-16 (+ #b0000100100000000 (lit8 k))))))
786 (make-listing "lfsr" (lit-text f) "," (lit-text k)))
788 (asm-16 (+ #b1110111000000000 (* (lit2 f) 16) (quotient (lit12 k) 256)))
789 (asm-16 (+ #b1111000000000000 (modulo (lit12 k) 256))))))
795 (make-listing "movlb" (lit-text k)))
797 (asm-16 (+ #b0000000100000000 (lit4 k))))))
803 (make-listing "movlw" (lit-text k)))
805 (asm-16 (+ #b0000111000000000 (lit8 k))))))
811 (make-listing "mullw" (lit-text k)))
813 (asm-16 (+ #b0000110100000000 (lit8 k))))))
819 (make-listing "retlw" (lit-text k)))
821 (asm-16 (+ #b0000110000000000 (lit8 k))))))
827 (make-listing "sublw" (lit-text k)))
829 (asm-16 (+ #b0000100000000000 (lit8 k))))))
835 (make-listing "xorlw" (lit-text k)))
837 (asm-16 (+ #b0000101000000000 (lit8 k))))))
843 (make-listing "tblrd*"))
845 (asm-16 #b0000000000001000))))
851 (make-listing "tblrd*+"))
853 (asm-16 #b0000000000001001))))
859 (make-listing "tblrd*-"))
861 (asm-16 #b0000000000001010))))
867 (make-listing "tblrd+*"))
869 (asm-16 #b0000000000001011))))
875 (make-listing "tblwt*"))
877 (asm-16 #b0000000000001100))))
883 (make-listing "tblwt*+"))
885 (asm-16 #b0000000000001101))))
891 (make-listing "tblwt*-"))
893 (asm-16 #b0000000000001110))))
899 (make-listing "tblwt+*"))
901 (asm-16 #b0000000000001111))))
904 (if (and (>= n 0) (<= n 3))
906 (error "2 bit literal expected but got" n)))
909 (if (and (>= n 0) (<= n 255))
911 (error "8 bit literal expected but got" n)))
914 (if (and (>= n 0) (<= n 2047))
916 (error "12 bit literal expected but got" n)))
920 (define (make-instruction cycles listing-thunk code-thunk)
924 (define (make-listing mnemonic . operands)
926 (define (operand-list operands)
929 (let ((rest (operand-list (cdr operands))))
930 (string-append (car operands)
931 (if (string=? rest "")
933 (string-append ", " rest))))))
938 (make-string (- 8 (string-length mnemonic)) #\space)
939 (operand-list operands))))
944 (else (error "destination bit must be w or f"))))
946 (define (dest-text d default)
947 (cond ((eq? d default) "")
950 (else (error "destination bit must be w or f"))))
955 (else (error "access bit must be a or b"))))
957 (define (access-text a default)
958 (cond ((eq? a default) "")
961 (else (error "access bit must be a or b"))))
971 (string-append "0x" (number->string k 16))))
974 (string-append "-" (text (abs k)))
984 (if (or (>= f #xf80) (< #x080))
986 (error "illegal file register")))
988 (define (file-full f)
991 (define (file-text f)
992 (let ((x (assv f file-reg-names)))
994 (symbol->string (cdr x))
997 (define (label-text label)
999 (string-append "0x" (number->string label 16))
1000 (symbol->string (asm-label-id label))))
1002 (define (label-pos label)
1005 (asm-label-pos label)))
1007 ;------------------------------------------------------------------------------
1012 (define STKPTR #xffc)
1013 (define PCLATU #xffb)
1014 (define PCLATH #xffa)
1016 (define TBLPTRU #xff8)
1017 (define TBLPTRH #xff7)
1018 (define TBLPTRL #xff6)
1019 (define TABLAT #xff5)
1020 (define PRODH #xff4)
1021 (define PRODL #xff3)
1022 (define INDF0 #xfef)
1023 (define POSTINC0 #xfee)
1024 (define POSTDEC0 #xfed)
1025 (define PREINC0 #xfec)
1026 (define PLUSW0 #xfeb)
1027 (define FSR0H #xfea)
1028 (define FSR0L #xfe9)
1030 (define INDF1 #xfe7)
1031 (define POSTINC1 #xfe6)
1032 (define POSTDEC1 #xfe5)
1033 (define PREINC1 #xfe4)
1034 (define PLUSW1 #xfe3)
1035 (define FSR1H #xfe2)
1036 (define FSR1L #xfe1)
1038 (define INDF2 #xfdf)
1039 (define POSTINC2 #xfde)
1040 (define POSTDEC2 #xfdd)
1041 (define PREINC2 #xfdc)
1042 (define PLUSW2 #xfdb)
1043 (define FSR2H #xfda)
1044 (define FSR2L #xfd9)
1045 (define STATUS #xfd8)
1046 (define TMR1H #xfcf)
1047 (define TMR1L #xfce)
1048 (define PORTE #xf84)
1049 (define PORTD #xf83)
1050 (define PORTC #xf82)
1051 (define PORTB #xf81)
1052 (define PORTA #xf80)
1054 (define file-reg-names '(
1122 ;------------------------------------------------------------------------------
1124 (define (label-offset-reference label offset)
1129 (asm-16 (+ (asm-label-pos label) offset)))))
1131 (define (label-instr label opcode)
1136 (let ((pos (asm-label-pos label)))
1137 (asm-8 (+ (quotient pos 256) opcode))
1138 (asm-8 (modulo pos 256))))))
1140 ;------------------------------------------------------------------------------
1142 (define irda_send_newline #x0078)
1143 (define irda_send #x007E)
1144 (define irda_recv_with_1_sec_timeout #x00A2)
1145 (define irda_recv #x00A4)
1146 (define sec_sleep #x00B0)
1147 (define msec_sleep #x00B6)
1148 (define delay_7 #x00D4)
1149 (define led_set #x00D6)
1150 (define bit_set #x00EC)
1151 (define FLASH_execute_erase #x0106)
1152 (define FLASH_execute_write #x0108)
1153 (define parse_hex_byte #x0184)
1154 (define parse_hex_digit #x0194)
1155 (define irda_send_hex #x01AE)
1156 (define irda_send_nibble #x01B6)
1158 ;------------------------------------------------------------------------------