- (let ((player (car players))
- (other-players (cdr players))
- (ptrs (player-ptrs player)))
- (let ((new-ptrs (execute-instr (car ptrs))))
- (if (null? new-ptrs)
- (run other-players (+ step 1))
- (begin
- (player-set-ptrs! (append (cdr ptrs) new-ptrs))
- (run (append other-players (list player)) (+ step 1)))))))))
-
-(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))
- (modifier (instr-modifier instr)))
- (case (instr-opcode instr)
- ((DAT) '()) ;Game over, man, game over!
- ((MOV))
- ((ADD))
- ((SUB))
- ((MUL))
- ((DIV))
- ((MOD))
- ((JMP))
- ((JMN))
- ((DJN))
- ((SEQ CMP))
- ((SNE))
- ((SLT))
- ((SPL))
- ((NOP))
+ (let* ((queue (car queues))
+ (remaining-queues (cdr queues))
+ (ptrs (queue-ptrs queues))
+ (new-ptrs (execute-instr core (car ptrs) (queue-owner queue))))
+ (if (null? new-ptrs)
+ (run other-players (- steps-left 1))
+ (begin
+ (player-set-ptrs! player (append (cdr ptrs) new-ptrs))
+ (run (append other-players (list player)) (- steps-left 1))))))))
+
+(define (execute-instr core ptr name)
+ (let* ((A-ptr (eval-operand core (core ptr 'A-mode) (core ptr 'A-num) ptr name))
+ (B-ptr (eval-operand core (core ptr 'B-mode) (core ptr 'B-num) ptr name))
+ (modifier (core ptr 'modifier)))
+ (case (core ptr 'opcode)
+ ((DAT)
+ '()) ;Game over, man, game over!
+ ((MOV)
+ (if (eq? modifier 'I)
+ (core B-ptr 'set-from! A-ptr name)
+ (combine-and-store core A-ptr B-ptr modifier name (lambda (x y) y)))
+ (list (addr+ ptr 1)))
+ ((ADD)
+ (combine-and-store core A-ptr B-ptr modifier name addr+)
+ (list (addr+ ptr 1)))
+ ((SUB)
+ (combine-and-store core A-ptr B-ptr modifier name
+ (lambda (x y) (addr+ x (- y))))
+ (list (addr+ ptr 1)))
+ ((MUL)
+ (combine-and-store core A-ptr B-ptr modifier name
+ (lambda (x y) (modulo (* (addr+ x core-size)
+ (addr+ y core-size))
+ core-size)))
+ (list (addr+ ptr 1)))
+ ((DIV)
+ (condition-case
+ (begin
+ (combine-and-store core A-ptr B-ptr modifier name
+ (lambda (x y) (quotient (addr x core-size)
+ (addr y core-size))))
+ (list (addr+ ptr 1)))
+ ((exn arithmetic) '())))
+ ((MOD)
+ (condition-case
+ (begin
+ (combine-and-store core A-ptr B-ptr modifier name
+ (lambda (x y) (remainder (addr x core-size)
+ (addr y core-size))))
+ (list (addr+ ptr 1)))
+ ((exn arithmetic) '())))
+ ((JMP)
+ (list (addr+ ptr (core A-ptr 'A-num))))
+ ((JMZ)
+ (list (addr+ ptr (if (instr-zero? B-ptr modifier #f)
+ ((core-get A-ptr) 'A-num)
+ 1))))
+ ((JMN)
+ (list (addr+ ptr (if (not (instr-zero? B-ptr modifier #f))
+ ((core-get A-ptr) 'A-num)
+ 1))))
+ ((DJN)
+ (list (addr+ ptr (if (not (instr-zero? B-ptr modifier #t))
+ ((core-get A-ptr) 'A-num)
+ 1))))
+ ((SEQ CMP)
+ (list (addr+ ptr (if (compare-instrs A-ptr B-ptr modifier =) 2 1))))
+ ((SNE)
+ (list (addr+ ptr (if (compare-instrs A-ptr B-ptr modifier =) 1 2))))
+ ((SLT)
+ (list (addr+ ptr (if (compare-instrs A-ptr B-ptr modifier <) 2 1))))
+ ((SPL)
+ (list (addr+ ptr 1) (addr+ ptr ((core-get A-ptr) 'A-num))))
+ ((NOP)
+ (list (addr+ ptr 1)))