1 ;;; File: "pic18-sim.scm"
5 ;------------------------------------------------------------------------------
9 (define pic18-stack #f)
11 (define pic18-wreg #f)
13 (define pic18-carry-flag #f)
14 (define pic18-deccarry-flag #f)
15 (define pic18-zero-flag #f)
16 (define pic18-overflow-flag #f)
17 (define pic18-negative-flag #f)
19 (define pic18-cycles #f)
20 (define pic18-exit #f)
24 (bitwise-and (arithmetic-shift (get-tos) -16) #xff))
26 (bitwise-and (arithmetic-shift (get-tos) -8) #xff))
28 (bitwise-and (get-tos) #xff))
30 (set-ram PCLATU (bitwise-and (arithmetic-shift (get-pc) -16)) #x1f)
31 (set-ram PCLATH (bitwise-and (arithmetic-shift (get-pc) -8)) #xff)
32 (bitwise-and (get-pc) #xfe))
35 (arithmetic-shift pic18-deccarry-flag 1)
36 (arithmetic-shift pic18-zero-flag 2)
37 (arithmetic-shift pic18-overflow-flag 3)
38 (arithmetic-shift pic18-negative-flag 4)))
40 (u8vector-ref pic18-ram adr))))
42 (define (set-ram adr byte)
44 (set-tos (+ (bitwise-and (get-tos) #x00ffff)
45 (arithmetic-shift (bitwise-and byte #x1f) 16))))
47 (set-tos (+ (bitwise-and (get-tos) #x1f00ff)
48 (arithmetic-shift byte 8))))
50 (set-tos (+ (bitwise-and (get-tos) #x1fff00)
53 (set-pc (+ (bitwise-and (arithmetic-shift (get-ram PCLATU) 16) #x1f)
54 (bitwise-and (arithmetic-shift (get-ram PCLATH) 8) #xff)
55 (bitwise-and byte #xfe))))
57 (set! pic18-carry-flag (bitwise-and byte 1))
58 (set! pic18-deccarry-flag (arithmetic-shift (bitwise-and byte 2) -1))
59 (set! pic18-zero-flag (arithmetic-shift (bitwise-and byte 4) -2))
60 (set! pic18-overflow-flag (arithmetic-shift (bitwise-and byte 8) -3))
61 (set! pic18-negative-flag (arithmetic-shift (bitwise-and byte 16) -4)))
63 (u8vector-set! pic18-ram adr byte))))
66 (u8vector-ref pic18-rom adr))
68 (define (set-rom adr byte)
69 (u8vector-set! pic18-rom adr byte))
71 (define (get-stack adr)
72 (vector-ref pic18-stack adr))
74 (define (set-stack adr pc)
75 (vector-set! pic18-stack adr pc))
84 (bitwise-and (get-ram STKPTR) #x1f))
89 (bitwise-and (get-ram STKPTR) #xe0))))
92 (vector-ref pic18-stack (- (get-sp) 1)))
95 (vector-set! pic18-stack (- (get-sp) 1) pc))
97 (define (stack-push pc)
98 (set-sp (+ (get-sp) 1))
103 (set-sp (- (get-sp) 1)))
106 (bitwise-and (get-ram BSR) #x0f))
111 (define (set-wreg byte)
112 (set! pic18-wreg byte))
115 (not (= 0 pic18-zero-flag)))
117 (define (set-zero-flag flag)
118 (set! pic18-zero-flag flag))
120 (define (negative-flag?)
121 (not (= 0 pic18-negative-flag)))
123 (define (set-negative-flag flag)
124 (set! pic18-negative-flag flag))
126 (define (carry-flag?)
127 (not (= 0 pic18-carry-flag)))
129 (define (set-carry-flag flag)
130 (set! pic18-carry-flag flag))
132 (define (deccarry-flag?)
133 (not (= 0 pic18-deccarry-flag)))
135 (define (set-deccarry-flag flag)
136 (set! pic18-deccarry-flag flag))
138 (define (overflow-flag?)
139 (not (= 0 pic18-overflow-flag)))
141 (define (set-overflow-flag flag)
142 (set! pic18-overflow-flag flag))
144 (define (pic18-sim-setup)
145 (set! pic18-ram (make-u8vector #x1000 0))
146 (set! pic18-rom (make-u8vector #x2000 0))
147 (set! pic18-stack (make-vector #x1f 0))
150 (set! pic18-carry-flag 0)
151 (set! pic18-deccarry-flag 0)
152 (set! pic18-zero-flag 0)
153 (set! pic18-overflow-flag 0)
154 (set! pic18-negative-flag 0))
156 (define (pic18-sim-cleanup)
159 (set! pic18-stack #f))
161 ;------------------------------------------------------------------------------
164 (let ((pc (- (get-pc) 2)))
165 (list (get-sp) " " (- pic18-cycles 1) " "
166 (substring (number->string (+ #x1000000 pc) 16) 1 7)
169 (define (illegal-opcode opcode)
171 (display (list (last-pc) " *illegal*")))
172 (error "illegal opcode" opcode))
174 (define decode-vector
175 (make-vector 256 illegal-opcode))
177 (define (decode-opcode opcode-bits shift action)
179 (error "shift=" shift))
180 (let ((n (arithmetic-shift 1 (- shift 8)))
181 (base (arithmetic-shift opcode-bits (- shift 8))))
185 (vector-set! decode-vector (+ base i) action)
188 (define (byte-oriented opcode mnemonic flags-changed operation)
189 (byte-oriented-aux opcode mnemonic flags-changed operation #f))
191 (define (byte-oriented-file opcode mnemonic flags-changed operation)
192 (byte-oriented-aux opcode mnemonic flags-changed operation #t))
194 (define (byte-oriented-aux opcode mnemonic flags-changed operation file?)
195 (let* ((f (bitwise-and opcode #xff))
196 (adr (if (= 0 (bitwise-and opcode #x100))
197 (if (= 0 (bitwise-and f #x80)) f (+ f #xf00))
198 (+ f (arithmetic-shift (get-bsr) 8)))))
200 (display (list (last-pc) " " mnemonic " "
201 (let ((x (assv adr file-reg-names)))
202 (if x (cdr x) (list "0x" (number->string adr 16))))
203 (if (or file? (not (= 0 (bitwise-and opcode #x200))))
207 (let* ((result (operation (get-ram adr)))
208 (result-8bit (bitwise-and result #xff)))
209 (if (or file? (not (= 0 (bitwise-and opcode #x200))))
210 (set-ram adr result-8bit)
211 (set-wreg result-8bit))
212 (if (not (eq? flags-changed 'none))
214 (set-zero-flag (if (= 0 result-8bit) 1 0))
215 (if (not (eq? flags-changed 'z))
217 (set-negative-flag (if (> result-8bit #x7f) 1 0))
218 (if (not (eq? flags-changed 'z-n))
220 (set-carry-flag (if (> result #xff) 1 0))
221 (if (not (eq? flags-changed 'c-z-n))
223 (set-deccarry-flag 0);;;;;;;;;;;;;;
224 (set-overflow-flag 0))))))))))));;;;;;;;;;;;;;
226 (define (bit-oriented opcode mnemonic operation)
227 (let* ((f (bitwise-and opcode #xff))
228 (adr (if (= 0 (bitwise-and opcode #x100))
229 (if (= 0 (bitwise-and f #x80)) f (+ f #xf00))
230 (+ f (arithmetic-shift (get-bsr) 8))))
231 (b (bitwise-and (arithmetic-shift opcode -9) 7)))
233 (display (list (last-pc) " " mnemonic " "
234 (let ((x (assv adr file-reg-names)))
235 (if x (cdr x) (list "0x" (number->string adr 16))))
238 (cdr (assv b '((0 . C)
248 (let* ((result (operation (get-ram adr) b))
249 (result-8bit (bitwise-and result #xff)))
250 (set-ram adr result-8bit))))
252 (define (short-relative-branch opcode mnemonic branch)
253 (let* ((n (bitwise-and opcode #xff))
254 (adr (+ (get-pc) (* 2 (if (> n #x7f) (- n #x100) n)))))
256 (display (list (last-pc) " " mnemonic " "
258 (number->string adr 16)
265 (define (long-relative-branch opcode mnemonic call?)
266 (let* ((n (bitwise-and opcode #x7ff))
267 (adr (+ (get-pc) (* 2 (if (> n #x3ff) (- n #x800) n)))))
269 (display (list (last-pc) " " mnemonic " "
271 (number->string adr 16)
274 (stack-push (get-pc)))
278 (define (call-branch opcode mnemonic)
279 (let ((adr (* 2 (+ (bitwise-and opcode #xff)
280 (arithmetic-shift (get-program-mem) 8)))))
282 (display (list (last-pc) " " mnemonic " "
284 (number->string adr 16)
285 (if (= 0 (bitwise-and opcode #x100))
289 (stack-push (get-pc))
290 (if (not (= 0 (bitwise-and opcode #x100)))
291 (error "call fast not implemented"))
294 (define (goto-branch opcode mnemonic)
295 (let ((adr (* 2 (+ (bitwise-and opcode #xff)
296 (arithmetic-shift (get-program-mem) 8)))))
298 (display (list (last-pc) " " mnemonic " "
300 (number->string adr 16)
304 (define (literal-operation opcode mnemonic flags-changed operation)
305 (let ((k (bitwise-and opcode #xff)))
307 (display (list (last-pc) " " mnemonic " "
308 (if (< k 10) k (list "0x" (number->string k 16)))
310 (let* ((result (operation k))
311 (result-8bit (bitwise-and result #xff)))
312 (set-wreg result-8bit)
313 (if (not (eq? flags-changed 'none))
315 (set-zero-flag (if (= 0 result-8bit) 1 0))
316 (if (not (eq? flags-changed 'z))
318 (set-negative-flag (if (> result-8bit #x7f) 1 0))
319 (if (not (eq? flags-changed 'z-n))
321 (set-carry-flag (if (> result #xff) 1 0))
322 (if (not (eq? flags-changed 'c-z-n))
324 (set-deccarry-flag 0);;;;;;;;;;;;;;
325 (set-overflow-flag 0))))))))))));;;;;;;;;;;;;;
327 (define (get-program-mem)
328 (set! pic18-cycles (+ pic18-cycles 1))
331 (msb (get-rom (+ pc 1))))
332 (set-pc (+ (get-pc) 2))
333 (+ (arithmetic-shift msb 8) lsb)))
339 (substring (number->string (+ #x100 n) 16) 1 3))
347 (display (list (hex (u8vector-ref pic18-ram i)) " "))
349 (display (list " WREG=" (hex (get-wreg)) "\n")))
351 (define (pic18-execute)
353 (set! pic18-cycles 0)
361 (display (list "WREG = d'" (get-wreg) "'\n")))
362 (let ((opcode (get-program-mem)))
363 (let ((proc (vector-ref decode-vector (arithmetic-shift opcode -8))))
367 (define trace-instr #t)
369 ;------------------------------------------------------------------------------
371 ; Byte-oriented file register operations.
373 (decode-opcode #b001001 10
375 (byte-oriented opcode "addwf" 'c-dc-z-ov-n
379 (decode-opcode #b001000 10
381 (byte-oriented opcode "addwfc" 'c-dc-z-ov-n
383 (+ f (get-wreg) (carry))))))
385 (decode-opcode #b000101 10
387 (byte-oriented opcode "andwf" 'z-n
389 (bitwise-and f (get-wreg))))))
391 (decode-opcode #b0110101 9
393 (byte-oriented-file opcode "clrf" 'z
397 (decode-opcode #b000111 10
399 (byte-oriented opcode "comf" 'z-n
403 (decode-opcode #b0110001 9
405 (byte-oriented-file opcode "cpfseq" 'none
407 (if (= f (get-wreg)) (skip))
410 (decode-opcode #b0110010 9
412 (byte-oriented-file opcode "cpfsgt" 'none
414 (if (> f (get-wreg)) (skip))
417 (decode-opcode #b0110000 9
419 (byte-oriented-file opcode "cpfslt" 'none
421 (if (< f (get-wreg)) (skip))
424 (decode-opcode #b000001 10
426 (byte-oriented opcode "decf" 'c-dc-z-ov-n
430 (decode-opcode #b001011 10
432 (byte-oriented opcode "decfsz" 'none
437 (decode-opcode #b010011 10
439 (byte-oriented opcode "dcfsnz" 'none
441 (if (not (= f 1)) (skip))
444 (decode-opcode #b001010 10
446 (byte-oriented opcode "incf" 'c-dc-z-ov-n
450 (decode-opcode #b001111 10
452 (byte-oriented opcode "incfsz" 'none
454 (if (= f #xff) (skip))
457 (decode-opcode #b010010 10
459 (byte-oriented opcode "infsnz" 'none
461 (if (not (= f #xff)) (skip))
464 (decode-opcode #b000100 10
466 (byte-oriented opcode "iorwf" 'z-n
468 (bitwise-ior f (get-wreg))))))
470 (decode-opcode #b010100 10
472 (byte-oriented opcode "movf" 'z-n
476 (decode-opcode #b1100 12
478 (byte-to-byte "movff")))
480 (decode-opcode #b0110111 9
482 (byte-oriented-file opcode "movwf" 'none
486 (decode-opcode #b0000001 9
488 (byte-oriented-file opcode "mulwf" 'none
492 (decode-opcode #b0110110 9
494 (byte-oriented-file opcode "negf" 'c-dc-z-ov-n
498 (decode-opcode #b001101 10
500 (byte-oriented opcode "rlcf" 'c-z-n
502 (+ (arithmetic-shift f 1) (carry))))))
504 (decode-opcode #b010001 10
506 (byte-oriented opcode "rlncf" 'z-n
508 (+ (arithmetic-shift f 1) (arithmetic-shift f -7))))))
510 (decode-opcode #b001100 10
512 (byte-oriented opcode "rrcf" 'c-z-n
514 (+ (arithmetic-shift f -1) (arithmetic-shift (carry) 7))))))
516 (decode-opcode #b010000 10
518 (byte-oriented opcode "rrncf" 'z-n
520 (+ (arithmetic-shift f -1) (arithmetic-shift f 7))))))
522 (decode-opcode #b0110100 9
524 (byte-oriented-file opcode "setf" 'z
528 (decode-opcode #b010101 10
530 (byte-oriented opcode "subfwb" 'c-dc-z-ov-n
532 (- (get-wreg) f (- 1 (carry)))))))
534 (decode-opcode #b010111 10
536 (byte-oriented opcode "subwf" 'c-dc-z-ov-n
540 (decode-opcode #b010110 10
542 (byte-oriented opcode "subwfb" 'c-dc-z-ov-n
544 (- f (get-wreg) (- 1 (carry)))))))
546 (decode-opcode #b001110 10
548 (byte-oriented opcode "swapf" 'none
550 (+ (arithmetic-shift f -4) (arithmetic-shift f 4))))))
552 (decode-opcode #b0110011 9
554 (byte-oriented-file opcode "tstfsz" 'none
556 (if (= f 0) (skip))))))
558 (decode-opcode #b000110 10
560 (byte-oriented opcode "xorwf" 'z-n
562 (bitwise-xor f (get-wreg))))))
564 ; Bit-oriented file register operations.
566 (decode-opcode #b1001 12
568 (bit-oriented opcode "bcf"
570 (bitwise-and f (bitwise-not (arithmetic-shift 1 b)))))))
572 (decode-opcode #b1000 12
574 (bit-oriented opcode "bsf"
576 (bitwise-ior f (arithmetic-shift 1 b))))))
578 (decode-opcode #b1011 12
580 (bit-oriented opcode "btfsc"
582 (if (= 0 (bitwise-and f (arithmetic-shift 1 b))) (skip))
585 (decode-opcode #b1010 12
587 (bit-oriented opcode "btfss"
589 (if (not (= 0 (bitwise-and f (arithmetic-shift 1 b)))) (skip))
592 (decode-opcode #b0111 12
594 (bit-oriented opcode "btg"
596 (bitwise-xor f (arithmetic-shift 1 b))))))
598 ; Control operations.
600 (decode-opcode #b11100010 8
602 (short-relative-branch opcode "bc"
604 (not (= 0 (carry)))))))
606 (decode-opcode #b11100110 8
608 (short-relative-branch opcode "bn"
610 (not (= 0 (negative)))))))
612 (decode-opcode #b11100011 8
614 (short-relative-branch opcode "bnc"
618 (decode-opcode #b11100111 8
620 (short-relative-branch opcode "bnn"
624 (decode-opcode #b11100101 8
626 (short-relative-branch opcode "bnov"
630 (decode-opcode #b11100001 8
632 (short-relative-branch opcode "bnz"
636 (decode-opcode #b11100100 8
638 (short-relative-branch opcode "bov"
640 (not (= 0 (overflow)))))))
642 (decode-opcode #b11010 11
644 (long-relative-branch opcode "bra" #f)))
646 (decode-opcode #b11100000 8
648 (short-relative-branch opcode "bz"
650 (not (= 0 (zero)))))))
652 (decode-opcode #b1110110 9
654 (call-branch opcode "call")))
656 (decode-opcode #b11101111 8
658 (goto-branch opcode "goto")))
660 (decode-opcode #b11011 11
662 (long-relative-branch opcode "rcall" #t)))
664 (decode-opcode #b1111 12
667 (display (list (last-pc) " nop ")))))
669 (decode-opcode #b00000000 8
671 (cond ((= opcode #b0000000000000100)
673 (display (list (last-pc) " clrwdt ")))
675 ((= opcode #b0000000000000111)
677 (display (list (last-pc) " daw ")))
679 ((= opcode #b0000000000000000)
681 (display (list (last-pc) " nop "))))
682 ((= opcode #b0000000000000110)
684 (display (list (last-pc) " pop ")))
686 ((= opcode #b0000000000000101)
688 (display (list (last-pc) " push ")))
689 (stack-push (get-pc)))
690 ((= opcode #b0000000011111111)
692 (display (list (last-pc) " reset ")))
694 ((= opcode #b0000000000010000)
696 (display (list (last-pc) " retfie ")))
699 ((= opcode #b0000000000010001)
701 (display (list (last-pc) " retfie FAST")))
702 (error "retfie fast not implemented")
705 ((= opcode #b0000000000010010)
707 (display (list (last-pc) " return ")))
710 ((= opcode #b0000000000010011)
712 (display (list (last-pc) " return FAST")))
713 (error "return fast not implemented")
716 ((= opcode #b0000000000000011)
718 (display (list (last-pc) " sleep ")))
719 (set! pic18-exit #t))
722 (display (list (last-pc) " ??? ")))
725 ; Literal operations.
727 (decode-opcode #b00001111 8
729 (literal-operation opcode "addlw" 'c-dc-z-ov-n
733 (decode-opcode #b00001011 8
735 (literal-operation opcode "andlw" 'z-n
737 (bitwise-and k (get-wreg))))))
739 (decode-opcode #b00001001 8
741 (literal-operation opcode "iorlw" 'z-n
743 (bitwise-ior k (get-wreg))))))
750 (make-listing "lfsr" (file-text f) (lit-text k)))
752 (asm-16 (bitmask "1110 1110 00ff kkkk" (file f) (quotient (lit k) 256)))
753 (asm-16 (bitmask "1111 0000 kkkk kkkk" (modulo (lit k) 256))))))
760 (make-listing "movlb" (lit-text k)))
762 (asm-16 (bitmask "0000 0001 0000 kkkk" (lit k))))))
764 (decode-opcode #b00001110 8
766 (literal-operation opcode "movlw" 'none
770 (decode-opcode #b00001101 8
772 (literal-operation opcode "mullw" 'none
776 (decode-opcode #b00001100 8
778 (literal-operation opcode "retlw" 'none
784 (decode-opcode #b00001000 8
786 (literal-operation opcode "sublw" 'c-dc-z-ov-n
790 (decode-opcode #b00001010 8
792 (literal-operation opcode "xorlw" 'z-n
794 (bitwise-xor k (get-wreg))))))
796 ; Program memory operations.
803 (make-listing "tblrd*"))
805 (asm-16 (bitmask "0000 0000 0000 1000")))))
812 (make-listing "tblrd*+"))
814 (asm-16 (bitmask "0000 0000 0000 1001")))))
821 (make-listing "tblrd*-"))
823 (asm-16 (bitmask "0000 0000 0000 1010")))))
830 (make-listing "tblrd+*"))
832 (asm-16 (bitmask "0000 0000 0000 1011")))))
839 (make-listing "tblwt*"))
841 (asm-16 (bitmask "0000 0000 0000 1100")))))
848 (make-listing "tblwt*+"))
850 (asm-16 (bitmask "0000 0000 0000 1101")))))
857 (make-listing "tblwt*-"))
859 (asm-16 (bitmask "0000 0000 0000 1110")))))
866 (make-listing "tblwt+*"))
868 (asm-16 (bitmask "0000 0000 0000 1111")))))
870 ;------------------------------------------------------------------------------
872 (define (read-hex-file filename)
874 (define addr-width 32)
876 (define (syntax-error)
877 (error "*** Syntax error in HEX file"))
880 (with-exception-catcher
884 (open-input-file filename)))))
886 (define mem (make-vector 16 #f))
888 (define (mem-store! a b)
891 (x (- addr-width 4)))
894 (let ((i (arithmetic-shift a (- x))))
895 (let ((v (vector-ref m i)))
897 (let ((v (make-vector 16 #f)))
900 (- a (arithmetic-shift i x))
905 (define (f m a n tail)
907 (define (g i a n tail)
909 (g (- i 1) (- a n) n (f (vector-ref m i) a n tail))
914 (cons (cons (- a 1) m) tail)
915 (g 15 a (quotient n 16) tail))
918 (f mem (expt 2 addr-width) (expt 2 addr-width) '()))
923 (define (read-hex-nibble)
924 (let ((c (read-char f)))
925 (cond ((and (char>=? c #\0) (char<=? c #\9))
926 (- (char->integer c) (char->integer #\0)))
927 ((and (char>=? c #\A) (char<=? c #\F))
928 (+ 10 (- (char->integer c) (char->integer #\A))))
929 ((and (char>=? c #\a) (char<=? c #\f))
930 (+ 10 (- (char->integer c) (char->integer #\a))))
934 (define (read-hex-byte)
935 (let* ((a (read-hex-nibble))
936 (b (read-hex-nibble)))
942 (let ((c (read-char f)))
943 (cond ((not (char? c)))
944 ((or (char=? c #\linefeed)
947 ((not (char=? c #\:))
950 (let* ((len (read-hex-byte))
953 (type (read-hex-byte)))
954 (let* ((adr (+ a2 (* 256 a1)))
955 (sum (+ len a1 a2 type)))
959 (let ((a (+ adr (* hi16 65536)))
962 (set! adr (modulo (+ adr 1) 65536))
971 (let* ((a1 (read-hex-byte))
972 (a2 (read-hex-byte)))
973 (set! sum (+ sum a1 a2))
974 (set! hi16 (+ a2 (* 256 a1)))))
977 (let ((check (read-hex-byte)))
978 (if (not (= (modulo (- sum) 256) check))
980 (let ((c (read-char f)))
981 (if (or (not (or (char=? c #\linefeed)
982 (char=? c #\return)))
990 (error "*** Could not open the HEX file")
993 ;------------------------------------------------------------------------------
995 (define (execute-hex-file filename)
996 (let ((program (read-hex-file filename)))
998 (for-each (lambda (x) (set-rom (car x) (cdr x))) program)
1000 (pic18-sim-cleanup)))