# HG changeset patch # User Steve Losh # Date 1481948853 18000 # Node ID 8155568555ec110cac2be902ba7860682fc6c4ad # Parent 9671aac2bbb59b702b07b95e163db815c3629119 Fix screen-wrapping bullshit, move declarations, opcode->instruction diff -r 9671aac2bbb5 -r 8155568555ec src/emulator.lisp --- a/src/emulator.lisp Fri Dec 16 23:27:18 2016 -0500 +++ b/src/emulator.lisp Fri Dec 16 23:27:33 2016 -0500 @@ -1,5 +1,5 @@ (in-package :chip8) -(declaim (optimize (speed 1) (safety 3) (debug 3))) +(declaim (optimize (speed 3) (safety 1) (debug 2))) ;;;; Constants ---------------------------------------------------------------- @@ -78,6 +78,7 @@ :type (simple-array fixnum (#.(* +screen-height+ +screen-width+))) :read-only t) (video-dirty t :type boolean) + (screen-wrapping-enabled t :type boolean) (delay-timer 0 :type fixnum) (sound-timer 0 :type fixnum) (stack (make-array 16 :element-type 'int12 :fill-pointer 0) @@ -91,7 +92,7 @@ memory registers flag index program-counter delay-timer sound-timer - video video-dirty + video video-dirty screen-wrapping-enabled keys stack loaded-rom @@ -106,10 +107,6 @@ ;;;; Graphics ----------------------------------------------------------------- -(declaim - (ftype (function (chip int8 int8 int4) null) draw-sprite)) - - (defun-inline vref (chip x y) (aref (chip-video chip) (+ (* +screen-width+ y) x))) @@ -143,33 +140,40 @@ (+ #x50 (* character 5))) +(defun-inline wrap (chip x y) + (cond + ((chip-screen-wrapping-enabled chip) + (values (mod x +screen-width+) + (mod y +screen-height+) + t)) + ((and (in-range-p 0 x +screen-width+) + (in-range-p 0 y +screen-height+)) + (values x y t)) + (t (values nil nil nil)))) + (defun draw-sprite (chip start-x start-y size) (with-chip (chip) (setf flag 0) - (iterate - (repeat size) - (for i :from index) - (for y :from start-y) - (for sprite = (aref memory i)) - (iterate - (for x :from start-x) - (for col :from 7 :downto 0) - (when (and (in-range-p 0 x +screen-width+) - (in-range-p 0 y +screen-height+)) - (for old-pixel = (plusp (vref chip x y))) - (for new-pixel = (plusp (get-bit col sprite))) - (when (and old-pixel new-pixel) - (setf flag 1)) - (setf (vref chip x y) - (if (xor old-pixel new-pixel) 255 0))))) + (iterate (repeat size) + (for i :from index) + (for y :from start-y) + (for sprite = (aref memory i)) + (iterate + (for x :from start-x) + (for col :from 7 :downto 0) + (multiple-value-bind (x y draw) (wrap chip x y) + (when draw + (for old-pixel = (plusp (vref chip x y))) + (for new-pixel = (plusp (get-bit col sprite))) + (when (and old-pixel new-pixel) + (setf flag 1)) + (setf (vref chip x y) + (if (xor old-pixel new-pixel) 255 0)))))) (setf video-dirty t)) nil) ;;;; Keyboard ----------------------------------------------------------------- -(declaim - (ftype (function (chip (integer 0 (16)))) keydown keyup)) - (defun keydown (chip key) (setf (aref (chip-keys chip) key) t)) @@ -177,9 +181,9 @@ (setf (aref (chip-keys chip) key) nil)) -;;;; Opcodes ------------------------------------------------------------------ +;;;; Instructions ------------------------------------------------------------- (eval-when (:compile-toplevel :load-toplevel :execute) - (defun parse-opcode-argument-bindings (argument-list) + (defun parse-instruction-argument-bindings (argument-list) (flet ((normalize-arg (arg) (destructuring-bind (symbol &optional (nibbles 1)) (ensure-list arg) @@ -190,19 +194,19 @@ (when (not (eql symbol '_)) (collect `(,symbol (ldb (byte ,(* nibbles 4) ,(* position 4)) - opcode)))))))) + instruction)))))))) -(defmacro define-opcode (name argument-list &body body) +(defmacro define-instruction (name argument-list &body body) `(progn (declaim (ftype (function (chip int16) (values null &optional)) ,name)) - (defun ,name (chip opcode) - (declare (ignorable opcode)) + (defun ,name (chip instruction) + (declare (ignorable instruction)) (with-chip (chip) (macrolet ((register (index) `(aref registers ,index))) - (let ,(parse-opcode-argument-bindings argument-list) + (let ,(parse-instruction-argument-bindings argument-list) ,@body)) nil)))) @@ -215,42 +219,42 @@ (op-ld-reg
>_8 (register r)))) -(define-opcode op-shl (_ r _ _) ;; SHL +(define-instruction op-shl (_ r _ _) ;; SHL (setf (values (register r) flag) (<<_8 (register r)))) -(define-opcode op-ld-font