1 ;;; File: "pic18-sim.scm"
5 (define pic18-stack #f)
9 (define instrs-counts #f) ; counts how many times each instruction is executed
10 (define break-points '()) ; list of adresses at which the simulation stops
12 (define pic18-carry-flag #f)
13 (define pic18-deccarry-flag #f)
14 (define pic18-zero-flag #f)
15 (define pic18-overflow-flag #f)
16 (define pic18-negative-flag #f)
18 (define pic18-cycles #f)
19 (define pic18-exit #f)
23 (bitwise-and (arithmetic-shift (get-tos) -16) #xff))
25 (bitwise-and (arithmetic-shift (get-tos) -8) #xff))
27 (bitwise-and (get-tos) #xff))
29 (set-ram PCLATU (bitwise-and (arithmetic-shift (get-pc) -16) #x1f))
30 (set-ram PCLATH (bitwise-and (arithmetic-shift (get-pc) -8) #xff))
31 (bitwise-and (get-pc) #xfe))
34 (arithmetic-shift pic18-deccarry-flag 1)
35 (arithmetic-shift pic18-zero-flag 2)
36 (arithmetic-shift pic18-overflow-flag 3)
37 (arithmetic-shift pic18-negative-flag 4)))
38 ((assq adr (list (cons INDF0 (cons FSR0H FSR0L))
39 (cons INDF1 (cons FSR1H FSR1L))
40 (cons INDF2 (cons FSR2H FSR2L))))
43 (arithmetic-shift (bitwise-and (u8vector-ref pic18-ram
47 (u8vector-ref pic18-ram
49 ;; TODO pre/post inc/dec 0..2
51 (u8vector-ref pic18-ram adr))))
53 (define (set-ram adr byte)
55 (set-tos (+ (bitwise-and (get-tos) #x00ffff)
56 (arithmetic-shift (bitwise-and byte #x1f) 16))))
58 (set-tos (+ (bitwise-and (get-tos) #x1f00ff)
59 (arithmetic-shift byte 8))))
61 (set-tos (+ (bitwise-and (get-tos) #x1fff00)
64 (set-pc (+ (bitwise-and (arithmetic-shift (get-ram PCLATU) 16) #x1f)
65 (bitwise-and (arithmetic-shift (get-ram PCLATH) 8) #xff)
66 (bitwise-and byte #xfe))))
68 (set! pic18-carry-flag (bitwise-and byte 1))
69 (set! pic18-deccarry-flag (arithmetic-shift (bitwise-and byte 2) -1))
70 (set! pic18-zero-flag (arithmetic-shift (bitwise-and byte 4) -2))
71 (set! pic18-overflow-flag (arithmetic-shift (bitwise-and byte 8) -3))
72 (set! pic18-negative-flag (arithmetic-shift (bitwise-and byte 16) -4)))
73 ((assq adr (list (cons INDF0 (cons FSR0H FSR0L))
74 (cons INDF1 (cons FSR1H FSR1L))
75 (cons INDF2 (cons FSR2H FSR2L))))
77 (set-ram (bitwise-ior ;; TODO factor common code with get-ram ?
78 (arithmetic-shift (bitwise-and (u8vector-ref pic18-ram
82 (u8vector-ref pic18-ram
85 ;; TODO all other special array registers
87 (u8vector-set! pic18-ram adr byte))))
90 (u8vector-ref pic18-rom adr))
92 (define (set-rom adr byte)
93 (u8vector-set! pic18-rom adr byte))
95 (define (get-stack adr)
96 (vector-ref pic18-stack adr))
98 (define (set-stack adr pc)
99 (vector-set! pic18-stack adr pc))
108 (bitwise-and (get-ram STKPTR) #x1f))
113 (bitwise-and (get-ram STKPTR) #xe0))))
116 (vector-ref pic18-stack (- (get-sp) 1)))
119 (vector-set! pic18-stack (- (get-sp) 1) pc))
121 (define (stack-push pc)
122 (set-sp (+ (get-sp) 1))
127 (set-sp (- (get-sp) 1)))
130 (bitwise-and (get-ram BSR) #x0f))
135 (define (set-wreg byte)
136 (set! pic18-wreg byte))
139 (not (= 0 pic18-zero-flag)))
141 (define (set-zero-flag flag)
142 (set! pic18-zero-flag flag))
144 (define (negative-flag?)
145 (not (= 0 pic18-negative-flag)))
147 (define (set-negative-flag flag)
148 (set! pic18-negative-flag flag))
150 (define (carry-flag?)
151 (not (= 0 pic18-carry-flag)))
153 (define (set-carry-flag flag)
154 (set! pic18-carry-flag flag))
156 (define (deccarry-flag?)
157 (not (= 0 pic18-deccarry-flag)))
159 (define (set-deccarry-flag flag)
160 (set! pic18-deccarry-flag flag))
162 (define (overflow-flag?)
163 (not (= 0 pic18-overflow-flag)))
165 (define (set-overflow-flag flag)
166 (set! pic18-overflow-flag flag))
168 (define (pic18-sim-setup)
169 (set! pic18-ram (make-u8vector #x1000 0))
170 (set! pic18-rom (make-u8vector #x10000 0))
171 (set! pic18-stack (make-vector #x1f 0))
172 (set! instrs-counts (make-vector #x10000 0))
175 (set! pic18-carry-flag 0)
176 (set! pic18-deccarry-flag 0)
177 (set! pic18-zero-flag 0)
178 (set! pic18-overflow-flag 0)
179 (set! pic18-negative-flag 0))
181 (define (pic18-sim-cleanup)
184 (set! pic18-stack #f))
186 ;------------------------------------------------------------------------------
189 (let ((pc (- (get-pc) 2)))
190 (list (get-sp) " " (- pic18-cycles 1) " "
191 (substring (number->string (+ #x1000000 pc) 16) 1 7)
194 (define (illegal-opcode opcode)
196 (print (list (last-pc) " *illegal*")))
197 (error "illegal opcode" opcode))
199 (define decode-vector
200 (make-vector 256 illegal-opcode))
202 (define (decode-opcode opcode-bits shift action)
204 (error "shift=" shift))
205 (let ((n (arithmetic-shift 1 (- shift 8)))
206 (base (arithmetic-shift opcode-bits (- shift 8))))
210 (vector-set! decode-vector (+ base i) action)
213 (define (byte-oriented opcode mnemonic flags-changed operation)
214 (byte-oriented-aux opcode mnemonic flags-changed operation 'wreg))
215 (define (byte-oriented-file opcode mnemonic flags-changed operation)
216 (byte-oriented-aux opcode mnemonic flags-changed operation 'file))
217 (define (byte-oriented-wide opcode mnemonic flags-changed operation dest)
218 ;; for use with instructions that have results more than a byte wide, such
219 ;; as multiplication. the result goes at the given addresses
220 (byte-oriented-aux opcode mnemonic flags-changed operation dest)) ;; TODO do the same for literals
222 (define (byte-oriented-aux opcode mnemonic flags-changed operation dest)
223 (let* ((f (bitwise-and opcode #xff))
224 (adr (if (= 0 (bitwise-and opcode #x100))
225 ;; the upper 160 addresses of the first bank are the special
226 ;; registers #xF60 to #xFFF
227 (if (= 0 (bitwise-and f #x80)) f (+ f #xf00))
228 (+ f (arithmetic-shift (get-bsr) 8)))))
230 (print (list (last-pc) " " mnemonic " "
231 (let ((x (assv adr file-reg-names)))
232 (if x (cdr x) (list "0x" (number->string adr 16))))
233 (if (or (eq? dest 'wreg)
234 (= 0 (bitwise-and opcode #x200)))
238 (let* ((result (operation (get-ram adr)))
239 (result-8bit (bitwise-and result #xff)))
241 ;; result is more than a byte wide (i.e. multiplication)
242 ;; put it in the right destinations (dest is a list of addresses)
243 (let loop ((dest dest) (result result))
244 (if (not (null? dest))
245 ;; the head of the list is the lsb
246 (begin (set-ram (car dest) (bitwise-and result #xff))
247 (loop (cdr dest) (arithmetic-shift result -8))))))
248 ((or (eq? dest 'file) (not (= 0 (bitwise-and opcode #x200))))
249 ;; the result goes in memory (file)
250 (set-ram adr result-8bit))
252 ;; result goes in wreg
253 (set-wreg result-8bit)))
254 (if (not (eq? flags-changed 'none))
256 (set-zero-flag (if (= 0 result-8bit) 1 0))
257 (if (not (eq? flags-changed 'z))
259 (set-negative-flag (if (> result-8bit #x7f) 1 0))
260 (if (not (eq? flags-changed 'z-n))
262 (set-carry-flag (if (or (> result #xff)
265 (if (not (eq? flags-changed 'c-z-n))
267 (set-deccarry-flag 0);;;;;;;;;;;;;;
268 (set-overflow-flag 0))))))))))));;;;;;;;;;;;;;
270 (define (bit-oriented opcode mnemonic operation)
271 (let* ((f (bitwise-and opcode #xff))
272 (adr (if (= 0 (bitwise-and opcode #x100))
273 (if (= 0 (bitwise-and f #x80)) f (+ f #xf00))
274 (+ f (arithmetic-shift (get-bsr) 8))))
275 (b (bitwise-and (arithmetic-shift opcode -9) 7)))
277 (print (list (last-pc) " " mnemonic " "
278 (let ((x (assv adr file-reg-names)))
279 (if x (cdr x) (list "0x" (number->string adr 16))))
282 (cdr (assv b '((0 . C)
292 (let* ((result (operation (get-ram adr) b))
293 (result-8bit (bitwise-and result #xff)))
294 (set-ram adr result-8bit))))
296 (define (short-relative-branch opcode mnemonic branch)
297 (let* ((n (bitwise-and opcode #xff))
298 (adr (+ (get-pc) (* 2 (if (> n #x7f) (- n #x100) n)))))
300 (print (list (last-pc) " " mnemonic " "
301 (symbol->string (table-ref symbol-table adr)))))
307 (define (long-relative-branch opcode mnemonic call?)
308 (let* ((n (bitwise-and opcode #x7ff))
309 (adr (+ (get-pc) (* 2 (if (> n #x3ff) (- n #x800) n)))))
311 (print (list (last-pc) " " mnemonic " "
312 (symbol->string (table-ref symbol-table adr)))))
314 (stack-push (get-pc)))
318 (define (call-branch opcode mnemonic)
319 (let ((adr (* 2 (+ (bitwise-and opcode #xff)
320 (arithmetic-shift (bitwise-and (get-program-mem) #xfff) 8)))))
322 (print (list (last-pc) " " mnemonic " "
323 (symbol->string (table-ref symbol-table adr))
324 (if (= 0 (bitwise-and opcode #x100))
327 (stack-push (get-pc))
328 (if (not (= 0 (bitwise-and opcode #x100)))
329 (error "call fast not implemented"))
332 (define (goto-branch opcode mnemonic)
333 (let ((adr (* 2 (+ (bitwise-and opcode #xff)
334 (arithmetic-shift (bitwise-and (get-program-mem) #xfff) 8)))))
336 (print (list (last-pc) " " mnemonic " "
337 (symbol->string (table-ref symbol-table adr)))))
340 (define (literal-operation opcode mnemonic flags-changed operation)
341 (let ((k (bitwise-and opcode #xff)))
343 (print (list (last-pc) " " mnemonic " "
344 (if (< k 10) k (list "0x" (number->string k 16))))))
345 (let* ((result (operation k))
346 (result-8bit (bitwise-and result #xff)))
347 (set-wreg result-8bit)
348 (if (not (eq? flags-changed 'none))
350 (set-zero-flag (if (= 0 result-8bit) 1 0))
351 (if (not (eq? flags-changed 'z))
353 (set-negative-flag (if (> result-8bit #x7f) 1 0))
354 (if (not (eq? flags-changed 'z-n))
356 (set-carry-flag (if (> result #xff) 1 0))
357 (if (not (eq? flags-changed 'c-z-n))
359 (set-deccarry-flag 0);;;;;;;;;;;;;;
360 (set-overflow-flag 0))))))))))));;;;;;;;;;;;;;
362 (define (program-memory-read mnemonic read-adr-fun set-adr-fun)
364 (print (list (last-pc) " " mnemonic " ")))
365 (let ((adr (bitwise-ior (arithmetic-shift (get-ram TBLPTRU) 16)
366 (arithmetic-shift (get-ram TBLPTRH) 8)
368 (set-ram TABLAT (get-rom (bitwise-and (read-adr-fun adr)
369 ;; rom addresses are 21 bits wide
371 (let ((new-adr (bitwise-and (set-adr-fun adr) #x1fffff)))
372 (set-ram TBLPTRU (arithmetic-shift new-adr -16))
373 (set-ram TBLPTRH (bitwise-and (arithmetic-shift new-adr -8) #xff))
374 (set-ram TBLPTRL (bitwise-and new-adr #xff)))))
376 (define (get-program-mem)
377 (set! pic18-cycles (+ pic18-cycles 1))
380 (msb (get-rom (+ pc 1))))
381 (set-pc (+ (get-pc) 2))
382 (+ (arithmetic-shift msb 8) lsb)))
388 (substring (number->string (+ #x100 n) 16) 1 3))
396 (print (list (hex (u8vector-ref pic18-ram i)) " "))
398 (print (list " WREG=" (hex (get-wreg)) "\n")))
400 (define single-stepping-mode? #f)
401 (define (pic18-execute)
403 (set! pic18-cycles 0)
411 (print (list "WREG = d'" (get-wreg) "'\n")))
412 (let ((opcode (get-program-mem))
414 (vector-set! instrs-counts pc (+ (vector-ref instrs-counts pc) 1))
415 (if (member pc break-points)
416 (begin (pp (list "break point at: " (number->string pc 16)))
417 (set! trace-instr #t)
418 (set! single-stepping-mode? #t)))
419 (if single-stepping-mode? (step))
420 (let ((proc (vector-ref decode-vector (arithmetic-shift opcode -8))))
424 (define trace-instr #t)
427 (if (> pic18-carry-flag 0)
428 (begin (set! pic18-carry-flag #f)
432 ;------------------------------------------------------------------------------
434 ; Byte-oriented file register operations.
436 (decode-opcode #b001001 10
438 (byte-oriented opcode "addwf" 'c-dc-z-ov-n
442 (decode-opcode #b001000 10
444 (byte-oriented opcode "addwfc" 'c-dc-z-ov-n
446 (+ f (get-wreg) (carry))))))
448 (decode-opcode #b000101 10
450 (byte-oriented opcode "andwf" 'z-n
452 (bitwise-and f (get-wreg))))))
454 (decode-opcode #b0110101 9
456 (byte-oriented-file opcode "clrf" 'z
460 (decode-opcode #b000111 10
462 (byte-oriented opcode "comf" 'z-n
466 (decode-opcode #b0110001 9
468 (byte-oriented-file opcode "cpfseq" 'none
470 (if (= f (get-wreg)) (skip))
473 (decode-opcode #b0110010 9
475 (byte-oriented-file opcode "cpfsgt" 'none
477 (if (> f (get-wreg)) (skip))
480 (decode-opcode #b0110000 9
482 (byte-oriented-file opcode "cpfslt" 'none
484 (if (< f (get-wreg)) (skip))
487 (decode-opcode #b000001 10
489 (byte-oriented opcode "decf" 'c-dc-z-ov-n
493 (decode-opcode #b001011 10
495 (byte-oriented opcode "decfsz" 'none
500 (decode-opcode #b010011 10
502 (byte-oriented opcode "dcfsnz" 'none
504 (if (not (= f 1)) (skip))
507 (decode-opcode #b001010 10
509 (byte-oriented opcode "incf" 'c-dc-z-ov-n
513 (decode-opcode #b001111 10
515 (byte-oriented opcode "incfsz" 'none
517 (if (= f #xff) (skip))
520 (decode-opcode #b010010 10
522 (byte-oriented opcode "infsnz" 'none
524 (if (not (= f #xff)) (skip))
527 (decode-opcode #b000100 10
529 (byte-oriented opcode "iorwf" 'z-n
531 (bitwise-ior f (get-wreg))))))
533 (decode-opcode #b010100 10
535 (byte-oriented opcode "movf" 'z-n
539 (decode-opcode #b1100 12
541 (let* ((src (bitwise-and opcode #xfff))
542 ;; the destination is in the second 16-bit part, need to fetch
543 (dst (bitwise-and (get-program-mem) #xfff)))
545 (print (list (last-pc) " movff "
546 (let ((x (assv src file-reg-names)))
547 (if x (cdr x) (list "0x" (number->string src 16))))
549 (let ((x (assv dst file-reg-names)))
550 (if x (cdr x) (list "0x" (number->string dst 16)))) ;; TODO printing 2 args ruins the formatting
552 (set-ram dst (get-ram src)))))
554 (decode-opcode #b0110111 9
556 (byte-oriented-file opcode "movwf" 'none
560 (decode-opcode #b0000001 9
562 (byte-oriented-wide opcode "mulwf" 'none
565 (list PRODL PRODH))))
567 (decode-opcode #b0110110 9
569 (byte-oriented-file opcode "negf" 'c-dc-z-ov-n
573 (decode-opcode #b001101 10
575 (byte-oriented opcode "rlcf" 'c-z-n
577 ;; the carry flag will be set automatically
578 (+ (arithmetic-shift f 1) (carry))))))
580 (decode-opcode #b010001 10
582 (byte-oriented opcode "rlncf" 'z-n
584 (+ (arithmetic-shift f 1) (arithmetic-shift f -7))))))
586 (decode-opcode #b001100 10
588 (byte-oriented opcode "rrcf" 'c-z-n
590 (let ((r (+ (arithmetic-shift f -1) (arithmetic-shift (carry) 7))))
591 ;; roll through carry (if the result is over #xff, carry will be set)
592 (if (= (bitwise-and f 1) 1) (+ r #x100) r))))))
594 (decode-opcode #b010000 10
596 (byte-oriented opcode "rrncf" 'z-n
598 (+ (arithmetic-shift f -1) (arithmetic-shift f 7))))))
600 (decode-opcode #b0110100 9
602 (byte-oriented-file opcode "setf" 'z
606 (decode-opcode #b010101 10
608 (byte-oriented opcode "subfwb" 'c-dc-z-ov-n
610 (- (get-wreg) f (carry))))))
612 (decode-opcode #b010111 10
614 (byte-oriented opcode "subwf" 'c-dc-z-ov-n
618 (decode-opcode #b010110 10
620 (byte-oriented opcode "subwfb" 'c-dc-z-ov-n
622 (- f (get-wreg) (carry))))))
624 (decode-opcode #b001110 10
626 (byte-oriented opcode "swapf" 'none
628 (+ (arithmetic-shift f -4) (arithmetic-shift f 4))))))
630 (decode-opcode #b0110011 9
632 (byte-oriented-file opcode "tstfsz" 'none
634 (if (= f 0) (skip))))))
636 (decode-opcode #b000110 10
638 (byte-oriented opcode "xorwf" 'z-n
640 (bitwise-xor f (get-wreg))))))
642 ; Bit-oriented file register operations.
644 (decode-opcode #b1001 12
646 (bit-oriented opcode "bcf"
648 (bitwise-and f (bitwise-not (arithmetic-shift 1 b)))))))
650 (decode-opcode #b1000 12
652 (bit-oriented opcode "bsf"
654 (bitwise-ior f (arithmetic-shift 1 b))))))
656 (decode-opcode #b1011 12
658 (bit-oriented opcode "btfsc"
660 (if (= 0 (bitwise-and f (arithmetic-shift 1 b))) (skip))
663 (decode-opcode #b1010 12
665 (bit-oriented opcode "btfss"
667 (if (not (= 0 (bitwise-and f (arithmetic-shift 1 b)))) (skip))
670 (decode-opcode #b0111 12
672 (bit-oriented opcode "btg"
674 (bitwise-xor f (arithmetic-shift 1 b))))))
676 ; Control operations.
678 (decode-opcode #b11100010 8
680 (short-relative-branch opcode "bc"
682 (not (= 0 (carry)))))))
684 (decode-opcode #b11100110 8
686 (short-relative-branch opcode "bn" negative-flag?)))
688 (decode-opcode #b11100011 8
690 (short-relative-branch opcode "bnc"
694 (decode-opcode #b11100111 8
696 (short-relative-branch opcode "bnn" negative-flag?)))
698 (decode-opcode #b11100101 8
700 (short-relative-branch opcode "bnov"
702 (not (overflow-flag?))))))
704 (decode-opcode #b11100001 8
706 (short-relative-branch opcode "bnz"
708 (not (zero-flag?))))))
710 (decode-opcode #b11100100 8
712 (short-relative-branch opcode "bov" overflow-flag?)))
714 (decode-opcode #b11010 11
716 (long-relative-branch opcode "bra" #f)))
718 (decode-opcode #b11100000 8
720 (short-relative-branch opcode "bz" zero-flag?)))
722 (decode-opcode #b1110110 9
724 (call-branch opcode "call")))
726 (decode-opcode #b11101111 8
728 (goto-branch opcode "goto")))
730 (decode-opcode #b11011 11
732 (long-relative-branch opcode "rcall" #t)))
734 (decode-opcode #b1111 12
737 (print (list (last-pc) " nop ")))))
739 (decode-opcode #b00000000 8
741 (cond ((= opcode #b0000000000000100)
743 (print (list (last-pc) " clrwdt ")))
745 ((= opcode #b0000000000000111)
747 (print (list (last-pc) " daw ")))
749 ((= opcode #b0000000000000000)
751 (print (list (last-pc) " nop "))))
752 ((= opcode #b0000000000000110)
754 (print (list (last-pc) " pop ")))
756 ((= opcode #b0000000000000101)
758 (print (list (last-pc) " push ")))
759 (stack-push (get-pc)))
760 ((= opcode #b0000000011111111)
762 (print (list (last-pc) " reset ")))
764 ((= opcode #b0000000000010000)
766 (print (list (last-pc) " retfie ")))
769 ((= opcode #b0000000000010001)
771 (print (list (last-pc) " retfie FAST")))
772 (error "retfie fast not implemented")
775 ((= opcode #b0000000000010010)
777 (print (list (last-pc) " return ")))
780 ((= opcode #b0000000000010011)
782 (print (list (last-pc) " return FAST")))
783 (error "return fast not implemented")
786 ((= opcode #b0000000000000011)
788 (print (list (last-pc) " sleep ")))
789 (set! pic18-exit #t))
790 ;; program memory operations
791 ((= opcode #b0000000000001000)
792 (program-memory-read "tblrd*" identity identity))
793 ((= opcode #b0000000000001001)
794 (program-memory-read "tblrd*+" identity (lambda (adr) (+ adr 1))))
795 ((= opcode #b0000000000001010)
796 (program-memory-read "tblrd*-" identity (lambda (adr) (- adr 1))))
797 ((= opcode #b0000000000001011)
798 (program-memory-read "tblrd+*"
799 (lambda (adr) (+ adr 1))
800 (lambda (adr) (+ adr 1))))
801 ((= opcode #b0000000000001100)
802 (program-memory-write "tblwt*" identity identity)) ;; TODO not implemented
803 ((= opcode #b0000000000001101)
804 (program-memory-write "tblwt*+" identity (lambda (adr) (+ adr 1))))
805 ((= opcode #b0000000000001110)
806 (program-memory-write "tblwt*-" identity (lambda (adr) (- adr 1))))
807 ((= opcode #b0000000000001111)
808 (program-memory-write "tblwt+*"
809 (lambda (adr) (+ adr 1))
810 (lambda (adr) (+ adr 1))))
813 (print (list (last-pc) " ??? ")))
816 ; Literal operations.
818 (decode-opcode #b00001111 8
820 (literal-operation opcode "addlw" 'c-dc-z-ov-n
824 (decode-opcode #b00001011 8
826 (literal-operation opcode "andlw" 'z-n
828 (bitwise-and k (get-wreg))))))
830 (decode-opcode #b00001001 8
832 (literal-operation opcode "iorlw" 'z-n
834 (bitwise-ior k (get-wreg))))))
841 (make-listing "lfsr" (file-text f) (lit-text k)))
843 (asm-16 (bitmask "1110 1110 00ff kkkk" (file f) (quotient (lit k) 256)))
844 (asm-16 (bitmask "1111 0000 kkkk kkkk" (modulo (lit k) 256))))))
851 (make-listing "movlb" (lit-text k)))
853 (asm-16 (bitmask "0000 0001 0000 kkkk" (lit k))))))
855 (decode-opcode #b00001110 8
857 (literal-operation opcode "movlw" 'none
861 (decode-opcode #b00001101 8
863 (literal-operation opcode "mullw" 'none
867 (decode-opcode #b00001100 8
869 (literal-operation opcode "retlw" 'none
875 (decode-opcode #b00001000 8
877 (literal-operation opcode "sublw" 'c-dc-z-ov-n
881 (decode-opcode #b00001010 8
883 (literal-operation opcode "xorlw" 'z-n
885 (bitwise-xor k (get-wreg))))))
888 ;------------------------------------------------------------------------------
890 (define (read-hex-file filename)
892 (define addr-width 32)
894 (define (syntax-error)
895 (error "*** Syntax error in HEX file"))
898 (with-exception-catcher
902 (open-input-file filename)))))
904 (define mem (make-vector 16 #f))
906 (define (mem-store! a b)
909 (x (- addr-width 4)))
912 (let ((i (arithmetic-shift a (- x))))
913 (let ((v (vector-ref m i)))
915 (let ((v (make-vector 16 #f)))
918 (- a (arithmetic-shift i x))
923 (define (f m a n tail)
925 (define (g i a n tail)
927 (g (- i 1) (- a n) n (f (vector-ref m i) a n tail))
932 (cons (cons (- a 1) m) tail)
933 (g 15 a (quotient n 16) tail))
936 (f mem (expt 2 addr-width) (expt 2 addr-width) '()))
941 (define (read-hex-nibble)
942 (let ((c (read-char f)))
943 (cond ((and (char>=? c #\0) (char<=? c #\9))
944 (- (char->integer c) (char->integer #\0)))
945 ((and (char>=? c #\A) (char<=? c #\F))
946 (+ 10 (- (char->integer c) (char->integer #\A))))
947 ((and (char>=? c #\a) (char<=? c #\f))
948 (+ 10 (- (char->integer c) (char->integer #\a))))
952 (define (read-hex-byte)
953 (let* ((a (read-hex-nibble))
954 (b (read-hex-nibble)))
960 (let ((c (read-char f)))
961 (cond ((not (char? c)))
962 ((or (char=? c #\linefeed)
965 ((not (char=? c #\:))
968 (let* ((len (read-hex-byte))
971 (type (read-hex-byte)))
972 (let* ((adr (+ a2 (* 256 a1)))
973 (sum (+ len a1 a2 type)))
977 (let ((a (+ adr (* hi16 65536)))
980 (set! adr (modulo (+ adr 1) 65536))
989 (let* ((a1 (read-hex-byte))
990 (a2 (read-hex-byte)))
991 (set! sum (+ sum a1 a2))
992 (set! hi16 (+ a2 (* 256 a1)))))
995 (let ((check (read-hex-byte)))
996 (if (not (= (modulo (- sum) 256) check))
998 (let ((c (read-char f)))
999 (if (or (not (or (char=? c #\linefeed)
1000 (char=? c #\return)))
1004 (close-input-port f)
1008 (error "*** Could not open the HEX file")
1011 ;------------------------------------------------------------------------------
1013 (define (execute-hex-files . filenames)
1014 (let ((programs (map read-hex-file filenames)))
1016 (for-each (lambda (prog)
1017 (for-each (lambda (x) (set-rom (car x) (cdr x)))
1021 (pic18-sim-cleanup)))
1023 (define (show-profiling-data) ;; TODO temporary solution until we have the true profile working
1024 (for-each (lambda (adr)
1025 (let ((count (vector-ref instrs-counts adr)))
1027 (print (list (number->string adr 16) " "
1029 (iota (vector-length instrs-counts))))
1030 (define (dump-profiling-data file)
1031 (with-output-to-file file show-profiling-data))
1033 ;; debugging procedures
1034 (define (add-break-point adr) (set! break-points (cons adr break-points)))
1035 (define (continue) (set! single-stepping-mode? #f)) ;; TODO + the equivalent of ,c