Fixed up address arithmetic.
[jars.git] / mars.scm
index b1aa9db..f2e3d99 100644 (file)
--- a/mars.scm
+++ b/mars.scm
 ;;
 
 (define core (make-vector core-size '()))
-
+(define (addr+ . args)
+  (foldl (lambda (a b)
+           (modulo (+ a b core-size) core-size))
+         0 args))
 
 ;;; Instructions
 ;;
 (define (execute-instr ptr)
   (let* ((instr (vector-ref core ptr))
          (A-pointer (eval-operand (instr-A-mode instr) (instr-A-num) ptr))
-         (B-pointer (eval-operand (instr-B-mode instr) (instr-B-num) ptr)))
+         (B-pointer (eval-operand (instr-B-mode instr) (instr-B-num) ptr))
+         (modifier (instr-modifier instr)))
     (case (instr-opcode instr)
-      ((DAT))
+      ((DAT) '()) ;Game over, man, game over!
       ((MOV))
       ((ADD))
       ((SUB))
   (case mode
     ((immediate) 0)
     ((direct) num)
-    ((indirect-A) (+ num (instr-A-num (vector-ref core (+ ptr num)))))
-    ((indirect-B) (+ num (instr-B-num (vector-ref core (+ ptr num)))))
+    ((indirect-A) (addr+ num (instr-A-num (vector-ref core (addr+ ptr num)))))
+    ((indirect-B) (addr+ num (instr-B-num (vector-ref core (addr+ ptr num)))))
     ((pre-indirect-A)
-     (let ((aux-instr (vector-ref core (+ ptr num))))
-       (instr-set-A-num! aux-instr (1 (instr-A-num aux-instr)))
-       (+ num (instr-A-num aux-instr))))
+     (let ((aux-instr (vector-ref core (addr+ ptr num))))
+       (instr-set-A-num! aux-instr (addr+ -1 (instr-A-num aux-instr)))
+       (addr+ num (instr-A-num aux-instr))))
     ((pre-indirect-B)
-     (let ((aux-instr (vector-ref core (+ ptr num))))
-       (instr-set-B-num! aux-instr (1 (instr-B-num aux-instr)))
-       (+ num (instr-B-num aux-instr))))
+     (let ((aux-instr (vector-ref core (addr+ ptr num))))
+       (instr-set-B-num! aux-instr (addr+ -1 (instr-B-num aux-instr)))
+       (addr+ num (instr-B-num aux-instr))))
     ((post-indirect-A)
-     (let* ((aux-instr (vector-ref core (+ ptr num)))
+     (let* ((aux-instr (vector-ref core (addr+ ptr num)))
             (old-A-num (instr-A-num aux-instr)))
-       (instr-set-A-num! aux-instr (+ 1 (instr-A-num aux-instr)))
-       (+ num old-A-num)))
+       (instr-set-A-num! aux-instr (addr+ 1 (instr-A-num aux-instr)))
+       (addr+ num old-A-num)))
     ((post-indirect-B)
-     (let* ((aux-instr (vector-ref core (+ ptr num)))
+     (let* ((aux-instr (vector-ref core (addr+ ptr num)))
             (old-B-num (instr-B-num aux-instr)))
-       (instr-set-B-num! aux-instr (+ 1 (instr-B-num aux-instr)))
-       (+ num old-B-num)))
+       (instr-set-B-num! aux-instr (addr+ 1 (instr-B-num aux-instr)))
+       (addr+ num old-B-num)))
     (else
      (error "Unrecognized mode" mode))))