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)))
39 ((assq adr (list (cons INDF0 (cons FSR0H FSR0L))
40 (cons INDF1 (cons FSR1H FSR1L))
41 (cons INDF2 (cons FSR2H FSR2L))))
44 (arithmetic-shift (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 (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)
135 (set! pic18-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 #x2000 0))
170 (set! pic18-stack (make-vector #x1f 0))
173 (set! pic18-carry-flag 0)
174 (set! pic18-deccarry-flag 0)
175 (set! pic18-zero-flag 0)
176 (set! pic18-overflow-flag 0)
177 (set! pic18-negative-flag 0))
179 (define (pic18-sim-cleanup)
182 (set! pic18-stack #f))
184 ;------------------------------------------------------------------------------
187 (let ((pc (- (get-pc) 2)))
188 (list (get-sp) " " (- pic18-cycles 1) " "
189 (substring (number->string (+ #x1000000 pc) 16) 1 7)
192 (define (illegal-opcode opcode)
194 (print (list (last-pc) " *illegal*")))
195 (error "illegal opcode" opcode))
197 (define decode-vector
198 (make-vector 256 illegal-opcode))
200 (define (decode-opcode opcode-bits shift action)
202 (error "shift=" shift))
203 (let ((n (arithmetic-shift 1 (- shift 8)))
204 (base (arithmetic-shift opcode-bits (- shift 8))))
208 (vector-set! decode-vector (+ base i) action)
211 (define (byte-oriented opcode mnemonic flags-changed operation)
212 (byte-oriented-aux opcode mnemonic flags-changed operation 'wreg))
213 (define (byte-oriented-file opcode mnemonic flags-changed operation)
214 (byte-oriented-aux opcode mnemonic flags-changed operation 'file))
215 (define (byte-oriented-wide opcode mnemonic flags-changed operation dest)
216 ;; for use with instructions that have results more than a byte wide, such
217 ;; as multiplication. the result goes at the given addresses
218 (byte-oriented-aux opcode mnemonic flags-changed operation dest)) ;; TODO do the same for literals
220 (define (byte-oriented-aux opcode mnemonic flags-changed operation dest)
221 (let* ((f (bitwise-and opcode #xff))
222 (adr (if (= 0 (bitwise-and opcode #x100))
223 (if (= 0 (bitwise-and f #x80)) f (+ f #xf00))
224 (+ f (arithmetic-shift (get-bsr) 8)))))
226 (print (list (last-pc) " " mnemonic " "
227 (let ((x (assv adr file-reg-names)))
228 (if x (cdr x) (list "0x" (number->string adr 16))))
229 (if (or (eq? dest 'wreg)
230 (= 0 (bitwise-and opcode #x200)))
234 (let* ((result (operation (get-ram adr)))
235 (result-8bit (bitwise-and result #xff)))
237 ;; result is more than a byte wide (i.e. multiplication)
238 ;; put it in the right destinations (dest is a list of addresses)
239 (let loop ((dest dest) (result result))
240 (if (not (null? dest))
241 ;; the head of the list is the lsb
242 (begin (set-ram (car dest) (bitwise-and result #xff))
243 (loop (cdr dest) (arithmetic-shift result -8))))))
244 ((or (eq? dest 'file) (not (= 0 (bitwise-and opcode #x200))))
245 ;; the result goes in memory (file)
246 (set-ram adr result-8bit))
248 ;; result goes in wreg
249 (set-wreg result-8bit)))
250 (if (not (eq? flags-changed 'none))
252 (set-zero-flag (if (= 0 result-8bit) 1 0))
253 (if (not (eq? flags-changed 'z))
255 (set-negative-flag (if (> result-8bit #x7f) 1 0))
256 (if (not (eq? flags-changed 'z-n))
258 (set-carry-flag (if (or (> result #xff)
261 (if (not (eq? flags-changed 'c-z-n))
263 (set-deccarry-flag 0);;;;;;;;;;;;;;
264 (set-overflow-flag 0))))))))))));;;;;;;;;;;;;;
266 (define (bit-oriented opcode mnemonic operation)
267 (let* ((f (bitwise-and opcode #xff))
268 (adr (if (= 0 (bitwise-and opcode #x100))
269 (if (= 0 (bitwise-and f #x80)) f (+ f #xf00))
270 (+ f (arithmetic-shift (get-bsr) 8))))
271 (b (bitwise-and (arithmetic-shift opcode -9) 7)))
273 (print (list (last-pc) " " mnemonic " "
274 (let ((x (assv adr file-reg-names)))
275 (if x (cdr x) (list "0x" (number->string adr 16))))
278 (cdr (assv b '((0 . C)
288 (let* ((result (operation (get-ram adr) b))
289 (result-8bit (bitwise-and result #xff)))
290 (set-ram adr result-8bit))))
292 (define (short-relative-branch opcode mnemonic branch)
293 (let* ((n (bitwise-and opcode #xff))
294 (adr (+ (get-pc) (* 2 (if (> n #x7f) (- n #x100) n)))))
296 (print (list (last-pc) " " mnemonic " "
298 (number->string adr 16)
305 (define (long-relative-branch opcode mnemonic call?)
306 (let* ((n (bitwise-and opcode #x7ff))
307 (adr (+ (get-pc) (* 2 (if (> n #x3ff) (- n #x800) n)))))
309 (print (list (last-pc) " " mnemonic " "
311 (number->string adr 16)
314 (stack-push (get-pc)))
318 (define (call-branch opcode mnemonic)
319 (let ((adr (* 2 (+ (bitwise-and opcode #xff)
320 (arithmetic-shift (get-program-mem) 8)))))
322 (print (list (last-pc) " " mnemonic " "
324 (number->string adr 16)
325 (if (= 0 (bitwise-and opcode #x100))
329 (stack-push (get-pc))
330 (if (not (= 0 (bitwise-and opcode #x100)))
331 (error "call fast not implemented"))
334 (define (goto-branch opcode mnemonic)
335 (let ((adr (* 2 (+ (bitwise-and opcode #xff)
336 (arithmetic-shift (get-program-mem) 8)))))
338 (print (list (last-pc) " " mnemonic " "
340 (number->string adr 16)
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)))
350 (let* ((result (operation k))
351 (result-8bit (bitwise-and result #xff)))
352 (set-wreg result-8bit)
353 (if (not (eq? flags-changed 'none))
355 (set-zero-flag (if (= 0 result-8bit) 1 0))
356 (if (not (eq? flags-changed 'z))
358 (set-negative-flag (if (> result-8bit #x7f) 1 0))
359 (if (not (eq? flags-changed 'z-n))
361 (set-carry-flag (if (> result #xff) 1 0))
362 (if (not (eq? flags-changed 'c-z-n))
364 (set-deccarry-flag 0);;;;;;;;;;;;;;
365 (set-overflow-flag 0))))))))))));;;;;;;;;;;;;;
367 (define (get-program-mem)
368 (set! pic18-cycles (+ pic18-cycles 1))
371 (msb (get-rom (+ pc 1))))
372 (set-pc (+ (get-pc) 2))
373 (+ (arithmetic-shift msb 8) lsb)))
379 (substring (number->string (+ #x100 n) 16) 1 3))
387 (print (list (hex (u8vector-ref pic18-ram i)) " "))
389 (print (list " WREG=" (hex (get-wreg)) "\n")))
391 (define (pic18-execute)
393 (set! pic18-cycles 0)
401 (print (list "WREG = d'" (get-wreg) "'\n")))
402 (let ((opcode (get-program-mem)))
403 (let ((proc (vector-ref decode-vector (arithmetic-shift opcode -8))))
407 (define trace-instr #t)
410 (if (> pic18-carry-flag 0)
411 (begin (set! pic18-carry-flag #f) ;; TODO is this how the PIC18 hardware does it ?
415 ;------------------------------------------------------------------------------
417 ; Byte-oriented file register operations.
419 (decode-opcode #b001001 10
421 (byte-oriented opcode "addwf" 'c-dc-z-ov-n
425 (decode-opcode #b001000 10
427 (byte-oriented opcode "addwfc" 'c-dc-z-ov-n
429 (+ f (get-wreg) (carry))))))
431 (decode-opcode #b000101 10
433 (byte-oriented opcode "andwf" 'z-n
435 (bitwise-and f (get-wreg))))))
437 (decode-opcode #b0110101 9
439 (byte-oriented-file opcode "clrf" 'z
443 (decode-opcode #b000111 10
445 (byte-oriented opcode "comf" 'z-n
449 (decode-opcode #b0110001 9
451 (byte-oriented-file opcode "cpfseq" 'none
453 (if (= f (get-wreg)) (skip))
456 (decode-opcode #b0110010 9
458 (byte-oriented-file opcode "cpfsgt" 'none
460 (if (> f (get-wreg)) (skip))
463 (decode-opcode #b0110000 9
465 (byte-oriented-file opcode "cpfslt" 'none
467 (if (< f (get-wreg)) (skip))
470 (decode-opcode #b000001 10
472 (byte-oriented opcode "decf" 'c-dc-z-ov-n
476 (decode-opcode #b001011 10
478 (byte-oriented opcode "decfsz" 'none
483 (decode-opcode #b010011 10
485 (byte-oriented opcode "dcfsnz" 'none
487 (if (not (= f 1)) (skip))
490 (decode-opcode #b001010 10
492 (byte-oriented opcode "incf" 'c-dc-z-ov-n
496 (decode-opcode #b001111 10
498 (byte-oriented opcode "incfsz" 'none
500 (if (= f #xff) (skip))
503 (decode-opcode #b010010 10
505 (byte-oriented opcode "infsnz" 'none
507 (if (not (= f #xff)) (skip))
510 (decode-opcode #b000100 10
512 (byte-oriented opcode "iorwf" 'z-n
514 (bitwise-ior f (get-wreg))))))
516 (decode-opcode #b010100 10
518 (byte-oriented opcode "movf" 'z-n
522 (decode-opcode #b1100 12
524 '(byte-to-byte "movff")
525 (byte-oriented opcode "movff" 'none
527 f)))) ;; TODO doesn't work
529 (decode-opcode #b0110111 9
531 (byte-oriented-file opcode "movwf" 'none
535 (decode-opcode #b0000001 9
537 (byte-oriented-wide opcode "mulwf" 'none
540 (list PRODL PRODH))))
542 (decode-opcode #b0110110 9
544 (byte-oriented-file opcode "negf" 'c-dc-z-ov-n
548 (decode-opcode #b001101 10
550 (byte-oriented opcode "rlcf" 'c-z-n
552 (+ (arithmetic-shift f 1) (carry))))))
554 (decode-opcode #b010001 10
556 (byte-oriented opcode "rlncf" 'z-n
558 (+ (arithmetic-shift f 1) (arithmetic-shift f -7))))))
560 (decode-opcode #b001100 10
562 (byte-oriented opcode "rrcf" 'c-z-n
564 (+ (arithmetic-shift f -1) (arithmetic-shift (carry) 7))))))
566 (decode-opcode #b010000 10
568 (byte-oriented opcode "rrncf" 'z-n
570 (+ (arithmetic-shift f -1) (arithmetic-shift f 7))))))
572 (decode-opcode #b0110100 9
574 (byte-oriented-file opcode "setf" 'z
578 (decode-opcode #b010101 10
580 (byte-oriented opcode "subfwb" 'c-dc-z-ov-n
582 (- (get-wreg) f (carry)))))) ;; TODO was (- 1 (carry)), but caused problems with the other
584 (decode-opcode #b010111 10
586 (byte-oriented opcode "subwf" 'c-dc-z-ov-n
590 (decode-opcode #b010110 10
592 (byte-oriented opcode "subwfb" 'c-dc-z-ov-n
594 (- f (get-wreg) (carry)))))) ;; TODO !carry didn't work
596 (decode-opcode #b001110 10
598 (byte-oriented opcode "swapf" 'none
600 (+ (arithmetic-shift f -4) (arithmetic-shift f 4))))))
602 (decode-opcode #b0110011 9
604 (byte-oriented-file opcode "tstfsz" 'none
606 (if (= f 0) (skip))))))
608 (decode-opcode #b000110 10
610 (byte-oriented opcode "xorwf" 'z-n
612 (bitwise-xor f (get-wreg))))))
614 ; Bit-oriented file register operations.
616 (decode-opcode #b1001 12
618 (bit-oriented opcode "bcf"
620 (bitwise-and f (bitwise-not (arithmetic-shift 1 b)))))))
622 (decode-opcode #b1000 12
624 (bit-oriented opcode "bsf"
626 (bitwise-ior f (arithmetic-shift 1 b))))))
628 (decode-opcode #b1011 12
630 (bit-oriented opcode "btfsc"
632 (if (= 0 (bitwise-and f (arithmetic-shift 1 b))) (skip))
635 (decode-opcode #b1010 12
637 (bit-oriented opcode "btfss"
639 (if (not (= 0 (bitwise-and f (arithmetic-shift 1 b)))) (skip))
642 (decode-opcode #b0111 12
644 (bit-oriented opcode "btg"
646 (bitwise-xor f (arithmetic-shift 1 b))))))
648 ; Control operations.
650 (decode-opcode #b11100010 8
652 (short-relative-branch opcode "bc"
654 (not (= 0 (carry)))))))
656 (decode-opcode #b11100110 8
658 (short-relative-branch opcode "bn"
660 (not (= 0 (negative)))))))
662 (decode-opcode #b11100011 8
664 (short-relative-branch opcode "bnc"
668 (decode-opcode #b11100111 8
670 (short-relative-branch opcode "bnn"
674 (decode-opcode #b11100101 8
676 (short-relative-branch opcode "bnov"
680 (decode-opcode #b11100001 8
682 (short-relative-branch opcode "bnz"
686 (decode-opcode #b11100100 8
688 (short-relative-branch opcode "bov"
690 (not (= 0 (overflow)))))))
692 (decode-opcode #b11010 11
694 (long-relative-branch opcode "bra" #f)))
696 (decode-opcode #b11100000 8
698 (short-relative-branch opcode "bz"
700 (not (= 0 (zero)))))))
702 (decode-opcode #b1110110 9
704 (call-branch opcode "call")))
706 (decode-opcode #b11101111 8
708 (goto-branch opcode "goto")))
710 (decode-opcode #b11011 11
712 (long-relative-branch opcode "rcall" #t)))
714 (decode-opcode #b1111 12
717 (print (list (last-pc) " nop ")))))
719 (decode-opcode #b00000000 8
721 (cond ((= opcode #b0000000000000100)
723 (print (list (last-pc) " clrwdt ")))
725 ((= opcode #b0000000000000111)
727 (print (list (last-pc) " daw ")))
729 ((= opcode #b0000000000000000)
731 (print (list (last-pc) " nop "))))
732 ((= opcode #b0000000000000110)
734 (print (list (last-pc) " pop ")))
736 ((= opcode #b0000000000000101)
738 (print (list (last-pc) " push ")))
739 (stack-push (get-pc)))
740 ((= opcode #b0000000011111111)
742 (print (list (last-pc) " reset ")))
744 ((= opcode #b0000000000010000)
746 (print (list (last-pc) " retfie ")))
749 ((= opcode #b0000000000010001)
751 (print (list (last-pc) " retfie FAST")))
752 (error "retfie fast not implemented")
755 ((= opcode #b0000000000010010)
757 (print (list (last-pc) " return ")))
760 ((= opcode #b0000000000010011)
762 (print (list (last-pc) " return FAST")))
763 (error "return fast not implemented")
766 ((= opcode #b0000000000000011)
768 (print (list (last-pc) " sleep ")))
769 (set! pic18-exit #t))
772 (print (list (last-pc) " ??? ")))
775 ; Literal operations.
777 (decode-opcode #b00001111 8
779 (literal-operation opcode "addlw" 'c-dc-z-ov-n
783 (decode-opcode #b00001011 8
785 (literal-operation opcode "andlw" 'z-n
787 (bitwise-and k (get-wreg))))))
789 (decode-opcode #b00001001 8
791 (literal-operation opcode "iorlw" 'z-n
793 (bitwise-ior k (get-wreg))))))
800 (make-listing "lfsr" (file-text f) (lit-text k)))
802 (asm-16 (bitmask "1110 1110 00ff kkkk" (file f) (quotient (lit k) 256)))
803 (asm-16 (bitmask "1111 0000 kkkk kkkk" (modulo (lit k) 256))))))
810 (make-listing "movlb" (lit-text k)))
812 (asm-16 (bitmask "0000 0001 0000 kkkk" (lit k))))))
814 (decode-opcode #b00001110 8
816 (literal-operation opcode "movlw" 'none
820 (decode-opcode #b00001101 8
822 (literal-operation opcode "mullw" 'none
826 (decode-opcode #b00001100 8
828 (literal-operation opcode "retlw" 'none
834 (decode-opcode #b00001000 8
836 (literal-operation opcode "sublw" 'c-dc-z-ov-n
840 (decode-opcode #b00001010 8
842 (literal-operation opcode "xorlw" 'z-n
844 (bitwise-xor k (get-wreg))))))
846 ; Program memory operations.
853 (make-listing "tblrd*"))
855 (asm-16 (bitmask "0000 0000 0000 1000")))))
862 (make-listing "tblrd*+"))
864 (asm-16 (bitmask "0000 0000 0000 1001")))))
871 (make-listing "tblrd*-"))
873 (asm-16 (bitmask "0000 0000 0000 1010")))))
880 (make-listing "tblrd+*"))
882 (asm-16 (bitmask "0000 0000 0000 1011")))))
889 (make-listing "tblwt*"))
891 (asm-16 (bitmask "0000 0000 0000 1100")))))
898 (make-listing "tblwt*+"))
900 (asm-16 (bitmask "0000 0000 0000 1101")))))
907 (make-listing "tblwt*-"))
909 (asm-16 (bitmask "0000 0000 0000 1110")))))
916 (make-listing "tblwt+*"))
918 (asm-16 (bitmask "0000 0000 0000 1111")))))
920 ;------------------------------------------------------------------------------
922 (define (read-hex-file filename)
924 (define addr-width 32)
926 (define (syntax-error)
927 (error "*** Syntax error in HEX file"))
930 (with-exception-catcher
934 (open-input-file filename)))))
936 (define mem (make-vector 16 #f))
938 (define (mem-store! a b)
941 (x (- addr-width 4)))
944 (let ((i (arithmetic-shift a (- x))))
945 (let ((v (vector-ref m i)))
947 (let ((v (make-vector 16 #f)))
950 (- a (arithmetic-shift i x))
955 (define (f m a n tail)
957 (define (g i a n tail)
959 (g (- i 1) (- a n) n (f (vector-ref m i) a n tail))
964 (cons (cons (- a 1) m) tail)
965 (g 15 a (quotient n 16) tail))
968 (f mem (expt 2 addr-width) (expt 2 addr-width) '()))
973 (define (read-hex-nibble)
974 (let ((c (read-char f)))
975 (cond ((and (char>=? c #\0) (char<=? c #\9))
976 (- (char->integer c) (char->integer #\0)))
977 ((and (char>=? c #\A) (char<=? c #\F))
978 (+ 10 (- (char->integer c) (char->integer #\A))))
979 ((and (char>=? c #\a) (char<=? c #\f))
980 (+ 10 (- (char->integer c) (char->integer #\a))))
984 (define (read-hex-byte)
985 (let* ((a (read-hex-nibble))
986 (b (read-hex-nibble)))
992 (let ((c (read-char f)))
993 (cond ((not (char? c)))
994 ((or (char=? c #\linefeed)
997 ((not (char=? c #\:))
1000 (let* ((len (read-hex-byte))
1001 (a1 (read-hex-byte))
1002 (a2 (read-hex-byte))
1003 (type (read-hex-byte)))
1004 (let* ((adr (+ a2 (* 256 a1)))
1005 (sum (+ len a1 a2 type)))
1009 (let ((a (+ adr (* hi16 65536)))
1010 (b (read-hex-byte)))
1012 (set! adr (modulo (+ adr 1) 65536))
1013 (set! sum (+ sum b))
1021 (let* ((a1 (read-hex-byte))
1022 (a2 (read-hex-byte)))
1023 (set! sum (+ sum a1 a2))
1024 (set! hi16 (+ a2 (* 256 a1)))))
1027 (let ((check (read-hex-byte)))
1028 (if (not (= (modulo (- sum) 256) check))
1030 (let ((c (read-char f)))
1031 (if (or (not (or (char=? c #\linefeed)
1032 (char=? c #\return)))
1036 (close-input-port f)
1040 (error "*** Could not open the HEX file")
1043 ;------------------------------------------------------------------------------
1045 (define (execute-hex-file filename)
1046 (let ((program (read-hex-file filename)))
1048 (for-each (lambda (x) (set-rom (car x) (cdr x))) program)
1050 (pic18-sim-cleanup)))