1 ;;; File: "pic18-sim.scm"
5 (define pic18-stack #f)
8 (define instrs-counts #f) ; counts how many times each instruction is executed
9 (define break-points '()) ; list of adresses at which the simulation stops
11 (define pic18-carry-flag #f)
12 (define pic18-deccarry-flag #f)
13 (define pic18-zero-flag #f)
14 (define pic18-overflow-flag #f)
15 (define pic18-negative-flag #f)
17 (define pic18-cycles #f)
18 (define pic18-exit #f)
20 (define fsr-alist (list (cons INDF0 (cons FSR0H FSR0L))
21 (cons INDF1 (cons FSR1H FSR1L))
22 (cons INDF2 (cons FSR2H FSR2L))))
26 (bitwise-and (arithmetic-shift (get-tos) -16) #xff))
28 (bitwise-and (arithmetic-shift (get-tos) -8) #xff))
30 (bitwise-and (get-tos) #xff))
32 (set-ram PCLATU (bitwise-and (arithmetic-shift (get-pc) -16) #x1f))
33 (set-ram PCLATH (bitwise-and (arithmetic-shift (get-pc) -8) #xff))
34 (bitwise-and (get-pc) #xfe))
37 (arithmetic-shift pic18-deccarry-flag 1)
38 (arithmetic-shift pic18-zero-flag 2)
39 (arithmetic-shift pic18-overflow-flag 3)
40 (arithmetic-shift pic18-negative-flag 4)))
44 (arithmetic-shift (bitwise-and (u8vector-ref pic18-ram
48 (u8vector-ref pic18-ram
50 ;; TODO pre/post inc/dec 0..2
52 (u8vector-ref pic18-ram adr))))
54 (define (set-ram adr byte)
56 (set-tos (+ (bitwise-and (get-tos) #x00ffff)
57 (arithmetic-shift (bitwise-and byte #x1f) 16))))
59 (set-tos (+ (bitwise-and (get-tos) #x1f00ff)
60 (arithmetic-shift byte 8))))
62 (set-tos (+ (bitwise-and (get-tos) #x1fff00)
65 (set-pc (+ (arithmetic-shift (get-ram PCLATU) 16)
66 (arithmetic-shift (get-ram PCLATH) 8)
67 (bitwise-and byte #xfe))))
69 (set! pic18-carry-flag (bitwise-and byte 1))
70 (set! pic18-deccarry-flag (arithmetic-shift (bitwise-and byte 2) -1))
71 (set! pic18-zero-flag (arithmetic-shift (bitwise-and byte 4) -2))
72 (set! pic18-overflow-flag (arithmetic-shift (bitwise-and byte 8) -3))
73 (set! pic18-negative-flag (arithmetic-shift (bitwise-and byte 16) -4)))
76 (set-ram (bitwise-ior ;; TODO factor common code with get-ram ?
77 (arithmetic-shift (bitwise-and (u8vector-ref pic18-ram
81 (u8vector-ref pic18-ram
84 ;; TODO all other special array registers
86 (u8vector-set! pic18-ram adr byte))))
89 (u8vector-ref pic18-rom adr))
91 (define (set-rom adr byte)
92 (u8vector-set! pic18-rom adr byte))
94 (define (get-stack adr)
95 (vector-ref pic18-stack adr))
97 (define (set-stack adr pc)
98 (vector-set! pic18-stack adr pc))
107 (bitwise-and (get-ram STKPTR) #x1f))
112 (bitwise-and (get-ram STKPTR) #xe0))))
115 (vector-ref pic18-stack (- (get-sp) 1)))
118 (vector-set! pic18-stack (- (get-sp) 1) pc))
120 (define (stack-push pc)
121 (set-sp (+ (get-sp) 1))
126 (set-sp (- (get-sp) 1)))
129 (bitwise-and (get-ram BSR) #x0f))
134 (define (set-wreg byte)
138 (not (= 0 pic18-zero-flag)))
140 (define (set-zero-flag flag)
141 (set! pic18-zero-flag flag))
143 (define (negative-flag?)
144 (not (= 0 pic18-negative-flag)))
146 (define (set-negative-flag flag)
147 (set! pic18-negative-flag flag))
149 (define (carry-flag?)
150 (not (= 0 pic18-carry-flag)))
152 (define (set-carry-flag flag)
153 (set! pic18-carry-flag flag))
155 (define (deccarry-flag?)
156 (not (= 0 pic18-deccarry-flag)))
158 (define (set-deccarry-flag flag)
159 (set! pic18-deccarry-flag flag))
161 (define (overflow-flag?)
162 (not (= 0 pic18-overflow-flag)))
164 (define (set-overflow-flag flag)
165 (set! pic18-overflow-flag flag))
167 (define (pic18-sim-setup)
168 (set! pic18-ram (make-u8vector #x1000 0))
169 (set! pic18-rom (make-u8vector #x10000 0))
170 (set! pic18-stack (make-vector #x1f 0))
171 (set! instrs-counts (make-vector #x10000 0))
174 (set! pic18-carry-flag 0)
175 (set! pic18-deccarry-flag 0)
176 (set! pic18-zero-flag 0)
177 (set! pic18-overflow-flag 0)
178 (set! pic18-negative-flag 0))
180 (define (pic18-sim-cleanup)
183 (set! pic18-stack #f))
185 ;------------------------------------------------------------------------------
188 (let ((pc (- (get-pc) 2)))
189 (list (get-sp) " " (- pic18-cycles 1) " "
190 (substring (number->string (+ #x1000000 pc) 16) 1 7)
193 (define (illegal-opcode opcode)
195 (print (list (last-pc) " *illegal*")))
196 (error "illegal opcode" opcode))
198 (define decode-vector
199 (make-vector 256 illegal-opcode))
201 (define (decode-opcode opcode-bits shift action)
203 (error "shift=" shift))
204 (let ((n (arithmetic-shift 1 (- shift 8)))
205 (base (arithmetic-shift opcode-bits (- shift 8))))
209 (vector-set! decode-vector (+ base i) action)
212 (define (byte-oriented opcode mnemonic flags-changed operation)
213 (byte-oriented-aux opcode mnemonic flags-changed operation 'wreg))
214 (define (byte-oriented-file opcode mnemonic flags-changed operation)
215 (byte-oriented-aux opcode mnemonic flags-changed operation 'file))
216 (define (byte-oriented-wide opcode mnemonic flags-changed operation dest)
217 ;; for use with instructions that have results more than a byte wide, such
218 ;; as multiplication. the result goes at the given addresses
219 (byte-oriented-aux opcode mnemonic flags-changed operation dest)) ;; TODO do the same for literals
221 (define (byte-oriented-aux opcode mnemonic flags-changed operation dest)
222 (let* ((f (bitwise-and opcode #xff))
223 (adr (if (= 0 (bitwise-and opcode #x100))
224 ;; the upper 160 addresses of the first bank are the special
225 ;; registers #xF60 to #xFFF
226 (if (= 0 (bitwise-and f #x80)) f (+ f #xf00))
227 (+ f (arithmetic-shift (get-bsr) 8)))))
229 (print (list (last-pc) " " mnemonic " "
230 (let ((x (assv adr file-reg-names)))
233 (let ((x (table-ref register-table f #f)))
234 (if #f ;x ;; TODO unreadable with picobit
235 (apply string-append-with-separator (cons "/" x))
236 (list "0x" (number->string adr 16))))))
237 (if (or (eq? dest 'wreg)
238 (= 0 (bitwise-and opcode #x200)))
242 (let* ((result (operation (get-ram adr)))
243 (result-8bit (bitwise-and result #xff)))
245 ;; result is more than a byte wide (i.e. multiplication)
246 ;; put it in the right destinations (dest is a list of addresses)
247 (let loop ((dest dest) (result result))
248 (if (not (null? dest))
249 ;; the head of the list is the lsb
250 (begin (set-ram (car dest) (bitwise-and result #xff))
251 (loop (cdr dest) (arithmetic-shift result -8))))))
252 ((or (eq? dest 'file) (not (= 0 (bitwise-and opcode #x200))))
253 ;; the result goes in memory (file)
254 (set-ram adr result-8bit))
256 ;; result goes in wreg
257 (set-wreg result-8bit)))
258 (if (not (eq? flags-changed 'none))
260 (set-zero-flag (if (= 0 result-8bit) 1 0))
261 (if (not (eq? flags-changed 'z))
263 (set-negative-flag (if (> result-8bit #x7f) 1 0))
264 (if (not (eq? flags-changed 'z-n))
266 (set-carry-flag (if (or (> result #xff)
269 (if (not (eq? flags-changed 'c-z-n))
271 (set-deccarry-flag 0);;;;;;;;;;;;;;
272 (set-overflow-flag 0))))))))))));;;;;;;;;;;;;;
274 (define (bit-oriented opcode mnemonic operation)
275 (let* ((f (bitwise-and opcode #xff))
276 (adr (if (= 0 (bitwise-and opcode #x100))
277 (if (= 0 (bitwise-and f #x80)) f (+ f #xf00))
278 (+ f (arithmetic-shift (get-bsr) 8))))
279 (b (bitwise-and (arithmetic-shift opcode -9) 7)))
281 (print (list (last-pc) " " mnemonic " "
282 (let ((x (assv adr file-reg-names)))
283 (if x (cdr x) (list "0x" (number->string adr 16))))
286 (cdr (assv b '((0 . C)
296 (let* ((result (operation (get-ram adr) b))
297 (result-8bit (bitwise-and result #xff)))
298 (set-ram adr result-8bit))))
300 (define (short-relative-branch opcode mnemonic branch)
301 (let* ((n (bitwise-and opcode #xff))
302 (adr (+ (get-pc) (* 2 (if (> n #x7f) (- n #x100) n)))))
304 (print (list (last-pc) " " mnemonic " "
305 (symbol->string (table-ref symbol-table adr)))))
311 (define (long-relative-branch opcode mnemonic call?)
312 (let* ((n (bitwise-and opcode #x7ff))
313 (adr (+ (get-pc) (* 2 (if (> n #x3ff) (- n #x800) n)))))
315 (print (list (last-pc) " " mnemonic " "
316 (symbol->string (table-ref symbol-table adr)))))
318 (stack-push (get-pc)))
322 (define (call-branch opcode mnemonic)
323 (let ((adr (* 2 (+ (bitwise-and opcode #xff)
324 (arithmetic-shift (bitwise-and (get-program-mem) #xfff) 8)))))
326 (print (list (last-pc) " " mnemonic " "
327 (symbol->string (table-ref symbol-table adr))
328 (if (= 0 (bitwise-and opcode #x100))
331 (stack-push (get-pc))
332 (if (not (= 0 (bitwise-and opcode #x100)))
333 (error "call fast not implemented"))
336 (define (goto-branch opcode mnemonic)
337 (let ((adr (* 2 (+ (bitwise-and opcode #xff)
338 (arithmetic-shift (bitwise-and (get-program-mem) #xfff) 8)))))
340 (print (list (last-pc) " " mnemonic " "
341 (symbol->string (table-ref symbol-table adr)))))
344 (define (literal-operation opcode mnemonic flags-changed operation)
345 (let ((k (bitwise-and opcode #xff)))
347 (print (list (last-pc) " " mnemonic " "
348 (if (< k 10) k (list "0x" (number->string k 16))))))
349 (let* ((result (operation k))
350 (result-8bit (bitwise-and result #xff)))
351 (set-wreg result-8bit)
352 (if (not (eq? flags-changed 'none))
354 (set-zero-flag (if (= 0 result-8bit) 1 0))
355 (if (not (eq? flags-changed 'z))
357 (set-negative-flag (if (> result-8bit #x7f) 1 0))
358 (if (not (eq? flags-changed 'z-n))
360 (set-carry-flag (if (> result #xff) 1 0))
361 (if (not (eq? flags-changed 'c-z-n))
363 (set-deccarry-flag 0);;;;;;;;;;;;;;
364 (set-overflow-flag 0))))))))))));;;;;;;;;;;;;;
366 (define (program-memory-read mnemonic read-adr-fun set-adr-fun)
368 (print (list (last-pc) " " mnemonic " ")))
369 (let ((adr (bitwise-ior (arithmetic-shift (get-ram TBLPTRU) 16)
370 (arithmetic-shift (get-ram TBLPTRH) 8)
372 (set-ram TABLAT (get-rom (bitwise-and (read-adr-fun adr)
373 ;; rom addresses are 21 bits wide
375 (let ((new-adr (bitwise-and (set-adr-fun adr) #x1fffff)))
376 (set-ram TBLPTRU (arithmetic-shift new-adr -16))
377 (set-ram TBLPTRH (bitwise-and (arithmetic-shift new-adr -8) #xff))
378 (set-ram TBLPTRL (bitwise-and new-adr #xff)))))
380 (define (get-program-mem)
381 (set! pic18-cycles (+ pic18-cycles 1))
384 (msb (get-rom (+ pc 1))))
385 (set-pc (+ (get-pc) 2))
386 (+ (arithmetic-shift msb 8) lsb)))
392 (substring (number->string (+ #x100 n) 16) 1 3))
400 (print (list (hex (u8vector-ref pic18-ram i)) " "))
402 (print (list " WREG=" (hex (get-wreg)) "\n")))
404 (define single-stepping-mode? #f)
405 (define (pic18-execute)
407 (set! pic18-cycles 0)
415 (print (list "WREG = d'" (get-wreg) "'\n")))
416 (let ((opcode (get-program-mem))
418 (vector-set! instrs-counts pc (+ (vector-ref instrs-counts pc) 1))
419 (if (member pc break-points)
420 (begin (pp (list "break point at: " (number->string pc 16)))
421 (set! trace-instr #t)
422 (set! single-stepping-mode? #t)))
423 (if single-stepping-mode? (step))
424 (let ((proc (vector-ref decode-vector (arithmetic-shift opcode -8))))
428 (define trace-instr #t)
431 (if (> pic18-carry-flag 0)
432 (begin (set! pic18-carry-flag #f)
436 ;------------------------------------------------------------------------------
438 ; Byte-oriented file register operations.
440 (decode-opcode #b001001 10
442 (byte-oriented opcode "addwf" 'c-dc-z-ov-n
446 (decode-opcode #b001000 10
448 (byte-oriented opcode "addwfc" 'c-dc-z-ov-n
450 (+ f (get-wreg) (carry))))))
452 (decode-opcode #b000101 10
454 (byte-oriented opcode "andwf" 'z-n
456 (bitwise-and f (get-wreg))))))
458 (decode-opcode #b0110101 9
460 (byte-oriented-file opcode "clrf" 'z
464 (decode-opcode #b000111 10
466 (byte-oriented opcode "comf" 'z-n
470 (decode-opcode #b0110001 9
472 (byte-oriented-file opcode "cpfseq" 'none
474 (if (= f (get-wreg)) (skip))
477 (decode-opcode #b0110010 9
479 (byte-oriented-file opcode "cpfsgt" 'none
481 (if (> f (get-wreg)) (skip))
484 (decode-opcode #b0110000 9
486 (byte-oriented-file opcode "cpfslt" 'none
488 (if (< f (get-wreg)) (skip))
491 (decode-opcode #b000001 10
493 (byte-oriented opcode "decf" 'c-dc-z-ov-n
497 (decode-opcode #b001011 10
499 (byte-oriented opcode "decfsz" 'none
504 (decode-opcode #b010011 10
506 (byte-oriented opcode "dcfsnz" 'none
508 (if (not (= f 1)) (skip))
511 (decode-opcode #b001010 10
513 (byte-oriented opcode "incf" 'c-dc-z-ov-n
517 (decode-opcode #b001111 10
519 (byte-oriented opcode "incfsz" 'none
521 (if (= f #xff) (skip))
524 (decode-opcode #b010010 10
526 (byte-oriented opcode "infsnz" 'none
528 (if (not (= f #xff)) (skip))
531 (decode-opcode #b000100 10
533 (byte-oriented opcode "iorwf" 'z-n
535 (bitwise-ior f (get-wreg))))))
537 (decode-opcode #b010100 10
539 (byte-oriented opcode "movf" 'z-n
543 (decode-opcode #b1100 12
545 (let* ((src (bitwise-and opcode #xfff))
546 ;; the destination is in the second 16-bit part, need to fetch
547 (dst (bitwise-and (get-program-mem) #xfff)))
549 (print (list (last-pc) " movff "
550 (let ((x (assv src file-reg-names)))
551 (if x (cdr x) (list "0x" (number->string src 16))))
553 (let ((x (assv dst file-reg-names)))
554 (if x (cdr x) (list "0x" (number->string dst 16)))) ;; TODO printing 2 args ruins the formatting
556 (set-ram dst (get-ram src)))))
558 (decode-opcode #b0110111 9
560 (byte-oriented-file opcode "movwf" 'none
564 (decode-opcode #b0000001 9
566 (byte-oriented-wide opcode "mulwf" 'none
569 (list PRODL PRODH))))
571 (decode-opcode #b0110110 9
573 (byte-oriented-file opcode "negf" 'c-dc-z-ov-n
577 (decode-opcode #b001101 10
579 (byte-oriented opcode "rlcf" 'c-z-n
581 ;; the carry flag will be set automatically
582 (+ (arithmetic-shift f 1) (carry))))))
584 (decode-opcode #b010001 10
586 (byte-oriented opcode "rlncf" 'z-n
588 (+ (arithmetic-shift f 1) (arithmetic-shift f -7))))))
590 (decode-opcode #b001100 10
592 (byte-oriented opcode "rrcf" 'c-z-n
594 (let ((r (+ (arithmetic-shift f -1) (arithmetic-shift (carry) 7))))
595 ;; roll through carry (if the result is over #xff, carry will be set)
596 (if (= (bitwise-and f 1) 1) (+ r #x100) r))))))
598 (decode-opcode #b010000 10
600 (byte-oriented opcode "rrncf" 'z-n
602 (+ (arithmetic-shift f -1) (arithmetic-shift f 7))))))
604 (decode-opcode #b0110100 9
606 (byte-oriented-file opcode "setf" 'z
610 (decode-opcode #b010101 10
612 (byte-oriented opcode "subfwb" 'c-dc-z-ov-n
614 (- (get-wreg) f (carry))))))
616 (decode-opcode #b010111 10
618 (byte-oriented opcode "subwf" 'c-dc-z-ov-n
622 (decode-opcode #b010110 10
624 (byte-oriented opcode "subwfb" 'c-dc-z-ov-n
626 (- f (get-wreg) (carry))))))
628 (decode-opcode #b001110 10
630 (byte-oriented opcode "swapf" 'none
632 (+ (arithmetic-shift f -4) (arithmetic-shift f 4))))))
634 (decode-opcode #b0110011 9
636 (byte-oriented-file opcode "tstfsz" 'none
638 (if (= f 0) (skip))))))
640 (decode-opcode #b000110 10
642 (byte-oriented opcode "xorwf" 'z-n
644 (bitwise-xor f (get-wreg))))))
646 ; Bit-oriented file register operations.
648 (decode-opcode #b1001 12
650 (bit-oriented opcode "bcf"
652 (bitwise-and f (bitwise-not (arithmetic-shift 1 b)))))))
654 (decode-opcode #b1000 12
656 (bit-oriented opcode "bsf"
658 (bitwise-ior f (arithmetic-shift 1 b))))))
660 (decode-opcode #b1011 12
662 (bit-oriented opcode "btfsc"
664 (if (= 0 (bitwise-and f (arithmetic-shift 1 b))) (skip))
667 (decode-opcode #b1010 12
669 (bit-oriented opcode "btfss"
671 (if (not (= 0 (bitwise-and f (arithmetic-shift 1 b)))) (skip))
674 (decode-opcode #b0111 12
676 (bit-oriented opcode "btg"
678 (bitwise-xor f (arithmetic-shift 1 b))))))
680 ; Control operations.
682 (decode-opcode #b11100010 8
684 (short-relative-branch opcode "bc"
686 (not (= 0 (carry)))))))
688 (decode-opcode #b11100110 8
690 (short-relative-branch opcode "bn" negative-flag?)))
692 (decode-opcode #b11100011 8
694 (short-relative-branch opcode "bnc"
698 (decode-opcode #b11100111 8
700 (short-relative-branch opcode "bnn" negative-flag?)))
702 (decode-opcode #b11100101 8
704 (short-relative-branch opcode "bnov"
706 (not (overflow-flag?))))))
708 (decode-opcode #b11100001 8
710 (short-relative-branch opcode "bnz"
712 (not (zero-flag?))))))
714 (decode-opcode #b11100100 8
716 (short-relative-branch opcode "bov" overflow-flag?)))
718 (decode-opcode #b11010 11
720 (long-relative-branch opcode "bra" #f)))
722 (decode-opcode #b11100000 8
724 (short-relative-branch opcode "bz" zero-flag?)))
726 (decode-opcode #b1110110 9
728 (call-branch opcode "call")))
730 (decode-opcode #b11101111 8
732 (goto-branch opcode "goto")))
734 (decode-opcode #b11011 11
736 (long-relative-branch opcode "rcall" #t)))
738 (decode-opcode #b1111 12
741 (print (list (last-pc) " nop ")))))
743 (decode-opcode #b00000000 8
745 (cond ((= opcode #b0000000000000100)
747 (print (list (last-pc) " clrwdt ")))
749 ((= opcode #b0000000000000111)
751 (print (list (last-pc) " daw ")))
753 ((= opcode #b0000000000000000)
755 (print (list (last-pc) " nop "))))
756 ((= opcode #b0000000000000110)
758 (print (list (last-pc) " pop ")))
760 ((= opcode #b0000000000000101)
762 (print (list (last-pc) " push ")))
763 (stack-push (get-pc)))
764 ((= opcode #b0000000011111111)
766 (print (list (last-pc) " reset ")))
768 ((= opcode #b0000000000010000)
770 (print (list (last-pc) " retfie ")))
773 ((= opcode #b0000000000010001)
775 (print (list (last-pc) " retfie FAST")))
776 (error "retfie fast not implemented")
779 ((= opcode #b0000000000010010)
781 (print (list (last-pc) " return ")))
784 ((= opcode #b0000000000010011)
786 (print (list (last-pc) " return FAST")))
787 (error "return fast not implemented")
790 ((= opcode #b0000000000000011)
792 (print (list (last-pc) " sleep ")))
793 (set! pic18-exit #t))
794 ;; program memory operations
795 ((= opcode #b0000000000001000)
796 (program-memory-read "tblrd*" identity identity))
797 ((= opcode #b0000000000001001)
798 (program-memory-read "tblrd*+" identity (lambda (adr) (+ adr 1))))
799 ((= opcode #b0000000000001010)
800 (program-memory-read "tblrd*-" identity (lambda (adr) (- adr 1))))
801 ((= opcode #b0000000000001011)
802 (program-memory-read "tblrd+*"
803 (lambda (adr) (+ adr 1))
804 (lambda (adr) (+ adr 1))))
805 ((= opcode #b0000000000001100)
806 (program-memory-write "tblwt*" identity identity)) ;; TODO not implemented
807 ((= opcode #b0000000000001101)
808 (program-memory-write "tblwt*+" identity (lambda (adr) (+ adr 1))))
809 ((= opcode #b0000000000001110)
810 (program-memory-write "tblwt*-" identity (lambda (adr) (- adr 1))))
811 ((= opcode #b0000000000001111)
812 (program-memory-write "tblwt+*"
813 (lambda (adr) (+ adr 1))
814 (lambda (adr) (+ adr 1))))
817 (print (list (last-pc) " ??? ")))
820 ; Literal operations.
822 (decode-opcode #b00001111 8
824 (literal-operation opcode "addlw" 'c-dc-z-ov-n
828 (decode-opcode #b00001011 8
830 (literal-operation opcode "andlw" 'z-n
832 (bitwise-and k (get-wreg))))))
834 (decode-opcode #b00001001 8
836 (literal-operation opcode "iorlw" 'z-n
838 (bitwise-ior k (get-wreg))))))
845 (make-listing "lfsr" (file-text f) (lit-text k)))
847 (asm-16 (bitmask "1110 1110 00ff kkkk" (file f) (quotient (lit k) 256)))
848 (asm-16 (bitmask "1111 0000 kkkk kkkk" (modulo (lit k) 256))))))
855 (make-listing "movlb" (lit-text k)))
857 (asm-16 (bitmask "0000 0001 0000 kkkk" (lit k))))))
859 (decode-opcode #b00001110 8
861 (literal-operation opcode "movlw" 'none
865 (decode-opcode #b00001101 8
867 (literal-operation opcode "mullw" 'none
871 (decode-opcode #b00001100 8
873 (literal-operation opcode "retlw" 'none
879 (decode-opcode #b00001000 8
881 (literal-operation opcode "sublw" 'c-dc-z-ov-n
885 (decode-opcode #b00001010 8
887 (literal-operation opcode "xorlw" 'z-n
889 (bitwise-xor k (get-wreg))))))
892 ;------------------------------------------------------------------------------
894 (define (read-hex-file filename)
896 (define addr-width 32)
898 (define (syntax-error)
899 (error "*** Syntax error in HEX file"))
902 (with-exception-catcher
906 (open-input-file filename)))))
908 (define mem (make-vector 16 #f))
910 (define (mem-store! a b)
913 (x (- addr-width 4)))
916 (let ((i (arithmetic-shift a (- x))))
917 (let ((v (vector-ref m i)))
919 (let ((v (make-vector 16 #f)))
922 (- a (arithmetic-shift i x))
927 (define (f m a n tail)
929 (define (g i a n tail)
931 (g (- i 1) (- a n) n (f (vector-ref m i) a n tail))
936 (cons (cons (- a 1) m) tail)
937 (g 15 a (quotient n 16) tail))
940 (f mem (expt 2 addr-width) (expt 2 addr-width) '()))
945 (define (read-hex-nibble)
946 (let ((c (read-char f)))
947 (cond ((and (char>=? c #\0) (char<=? c #\9))
948 (- (char->integer c) (char->integer #\0)))
949 ((and (char>=? c #\A) (char<=? c #\F))
950 (+ 10 (- (char->integer c) (char->integer #\A))))
951 ((and (char>=? c #\a) (char<=? c #\f))
952 (+ 10 (- (char->integer c) (char->integer #\a))))
956 (define (read-hex-byte)
957 (let* ((a (read-hex-nibble))
958 (b (read-hex-nibble)))
964 (let ((c (read-char f)))
965 (cond ((not (char? c)))
966 ((or (char=? c #\linefeed)
969 ((not (char=? c #\:))
972 (let* ((len (read-hex-byte))
975 (type (read-hex-byte)))
976 (let* ((adr (+ a2 (* 256 a1)))
977 (sum (+ len a1 a2 type)))
981 (let ((a (+ adr (* hi16 65536)))
984 (set! adr (modulo (+ adr 1) 65536))
993 (let* ((a1 (read-hex-byte))
994 (a2 (read-hex-byte)))
995 (set! sum (+ sum a1 a2))
996 (set! hi16 (+ a2 (* 256 a1)))))
999 (let ((check (read-hex-byte)))
1000 (if (not (= (modulo (- sum) 256) check))
1002 (let ((c (read-char f)))
1003 (if (or (not (or (char=? c #\linefeed)
1004 (char=? c #\return)))
1008 (close-input-port f)
1012 (error "*** Could not open the HEX file")
1015 ;------------------------------------------------------------------------------
1017 (define (execute-hex-files . filenames)
1018 (let ((programs (map read-hex-file filenames)))
1020 (for-each (lambda (prog)
1021 (for-each (lambda (x) (set-rom (car x) (cdr x)))
1025 (pic18-sim-cleanup)))
1027 (define (show-profiling-data) ;; TODO temporary solution until we have the true profile working
1028 (with-input-from-file asm-filename
1030 (let loop ((line (read-line)))
1031 (if (not (eq? line #!eof))
1032 (begin (if (not (eq? (string-ref line 0) #\tab)) ; not a label
1033 (let ((adr (string->number (car (split-string line
1036 (print (list (vector-ref instrs-counts adr)
1038 (print (list line "\n"))
1039 (loop (read-line))))))))
1040 (define (dump-profiling-data file)
1041 (with-output-to-file file show-profiling-data))
1043 ;; debugging procedures
1044 (define (add-break-point adr) (set! break-points (cons adr break-points)))
1045 (define (continue) (set! single-stepping-mode? #f)) ;; TODO + the equivalent of ,c
1047 (define (picobit-object o0 o1)
1048 (define (obj->ram o field)
1049 (get-ram (+ 512 (arithmetic-shift (- o 512) 2) field)))
1050 (define (ram-get-car o) ;; TODO shouldn't end up seeing any rom objects
1051 (bitwise-ior (arithmetic-shift (bitwise-and (obj->ram o 0) #x1f) 8)
1053 (define (ram-get-cdr o)
1054 (bitwise-ior (arithmetic-shift (bitwise-and (obj->ram o 2) #x1f) 8)
1056 (define (ram-get-entry o)
1057 (bitwise-ior (arithmetic-shift (bitwise-and (obj->ram o 0) #x1f) 11)
1058 (arithmetic-shift (obj->ram o 1) 3)
1059 (arithmetic-shift (obj->ram o 2) -5)))
1061 (define (show-pair ptr)
1062 (let ((obj (ram-get-car ptr))
1063 (next (ram-get-cdr ptr)))
1065 (cond ((= next 2)) ; '()
1066 ((and (> next 511) (< next 1280) ; ram
1067 (= (bitwise-and (obj->ram next 0) #x80) #x80) ; composite
1068 (= (bitwise-and (obj->ram next 2) #xe0) 0)) ; pair
1071 (else (display " . ")
1074 (define (show-obj o)
1075 (cond ((= o 0) (display #f))
1076 ((= o 1) (display #t))
1077 ((= o 2) (display '()))
1078 ((< o (+ 3 255 1 1)) ; fixnum
1081 (display "rom")) ;; TODO be more precise, since we should end up with a rom object, the quoted list
1083 (let ((obj (bitwise-ior (arithmetic-shift (obj->ram o 0) 24)
1084 (arithmetic-shift (obj->ram o 1) 16)
1085 (arithmetic-shift (obj->ram o 2) 8)
1087 (cond ((= (bitwise-and obj #xc0000000) 0)
1088 (display "ram-bignum"))
1089 ((= (bitwise-and obj #x80000000) #x80000000) ; ram composite
1090 (cond ((= (bitwise-and obj #x0000e000) 0) ; ram pair
1094 ((= (bitwise-and obj #x0000e000) #x2000)
1095 (display "#<symbol>"))
1096 ((= (bitwise-and obj #x0000e000) #x4000)
1097 (display "#<string>"))
1098 ((= (bitwise-and obj #x0000e000) #x6000)
1099 (display "#<vector>"))
1100 ((= (bitwise-and obj #x0000e000) #x8000)
1101 (display "#<cont: ")
1102 (show-obj (ram-get-cdr o))
1104 (show-obj (ram-get-car o))
1106 (else (display "unknown?"))))
1108 (display (string-append "{0x"
1109 (number->string (ram-get-entry o)
1112 (show-obj (ram-get-cdr o))
1114 (else (display "invalid"))))
1116 (show-obj (+ (* 256 (get-ram o1)) (get-ram o0)))
1119 (define (picobit-pc)
1120 (number->string (+ (* 256 (get-ram (table-ref reverse-register-table
1122 (get-ram (table-ref reverse-register-table
1125 (define (picobit-stack)
1126 (picobit-object (table-ref reverse-register-table "env0$86")
1127 (table-ref reverse-register-table "env1$85")))
1128 (define (picobit-continuation)
1129 (picobit-object (table-ref reverse-register-table "cont0$84")
1130 (table-ref reverse-register-table "cont1$83")))