Executed first instruction.
authorTim Vaughan <timv@ughan.xyz>
Thu, 14 Oct 2021 21:17:27 +0000 (23:17 +0200)
committerTim Vaughan <timv@ughan.xyz>
Thu, 14 Oct 2021 21:17:27 +0000 (23:17 +0200)
ez.el

diff --git a/ez.el b/ez.el
index 906b370..4cea075 100644 (file)
--- a/ez.el
+++ b/ez.el
 (defun ez-increment-pc (inc)
   (ez-set-pc (+ (ez-get-pc) inc)))
 
+(defun ez-read-pc-byte-and-inc ()
+  (let ((res (ez-mem-ref-byte (ez-get-pc))))
+    (ez-increment-pc 1)
+    res))
+
+(defun ez-read-pc-word-and-inc ()
+  (let ((res (ez-mem-ref-word (ez-get-pc))))
+    (ez-increment-pc 2)
+    res))
 
 ;; Instruction execution
 
    (t
     (ez-set-global-var (- var 16) val))))
 
+(defun ez-read-pc-var-and-inc ()
+  (ez-get-var (ez-read-pc-byte-and-inc)))
+
 (defun ez-execute-instr ()
-  (let ((op-byte (ez-mem-ref-byte (ez-get-pc))))
-    (ez-inc-pc 1)
+  (let ((opbyte (ez-read-pc-byte-and-inc))
+        (optype)
+        (opcode nil)
+        (operands))
     (cond
-     ((<= #x0 op-byte #x1f) (list '2op op-byte 'b 'b))
-     ((<= #x20 op-byte #x3F) (list '2op (- op-byte #x20) 'b 'v))
-     ((<= #x40 op-byte #x5F) (list '2op (- op-byte #x40) 'v 'b))
-     ((<= #x60 op-byte #x7F) (list '2op (- op-byte #x60) 'v 'v))
-     ((<= #x80 op-byte #x8F) (list '1op (- op-byte #x80) 'w))
-     ((<= #x90 op-byte #x9F) (list '1op (- op-byte #x90) 'b))
-     ((<= #xA0 op-byte #xAF) (list '1op (- op-byte #xa0) 'v))
-     ((<= #xB0 op-byte #xBF) (list '0op (- op-byte #xb0)))
-     ((<= #xC0 op-byte #xDF) (list '2op (- op-byte #xc0) 'var-instr-format))
-     ((<= #xE0 op-byte #xFF) (list 'var (- op-byte #xe0))
-      (let ((opcode (- op-byte #xe0))
-            (types (ez-mem-ref-byte (ez-get-pc))))
-        ))
-     )))
-
-(ez-get-instr ez-start-pc)
-(ez-mem-ref-byte ez-start-pc)
-
-(binformat #xe0)
-(binformat #x03)
-
+     ((<= #x0 opbyte #x1f)
+      (setq optype '2op
+            opcode opbyte
+            operands (list (ez-read-pc-byte-and-inc)
+                            (ez-read-pc-byte-and-inc))))
+     ((<= #x20 opbyte #x3F)
+      (setq optype '2op
+            opcode (- opbyte #x20)
+            operands (list (ez-read-pc-byte-and-inc)
+                           (ez-read-pc-var-and-inc))))
+     ((<= #x40 opbyte #x5F)
+      (setq optype '2op
+            opcode (- opbyte #x40)
+            operands (list (ez-read-pc-var-and-inc)
+                           (ez-read-pc-byte-and-inc))))
+     ((<= #x60 opbyte #x7F)
+      (setq optype '2op
+            opcode (- opbyte #x60)
+            operands (list (ez-read-pc-var-and-inc)
+                           (ez-read-pc-var-and-inc))))
+     ((<= #x80 opbyte #x8F)
+      (setq optype '1op
+            opcode (- opbyte #x80)
+            operands (list (ez-read-pc-word-and-inc))))
+     ((<= #x90 opbyte #x9F)
+      (setq optype '1op
+            opcode (- opbyte #x90)
+            operands (list (ez-read-pc-byte-and-inc))))
+     ((<= #xA0 opbyte #xAF)
+      (setq optype '1op
+            opcode (- opbyte #xa0)
+            operands (list (ez-read-pc-var-and-inc))))
+     ((<= #xB0 opbyte #xBF)
+      (setq optype '0op
+            opcode (- opbyte #xb0)))
+     ((<= #xC0 opbyte #xDF)
+      (error "Unsupported op" opbyte))
+     ((<= #xE0 opbyte #xFF)
+      (setq optype 'var
+            opcode (- opbyte #xe0)
+            operands (ez-read-var-operands-and-inc))))
+    (let ((table-row (assoc (list optype opcode) ez-op-table)))
+      (unless table-row
+        (error "Unsupported op" optype opcode))
+      (let ((mnemonic (elt table-row 1)))
+        (message "Optype:%s Opcode:%x Operands:%s"
+                 (symbol-name optype)
+                 opcode operands))
+      (apply (elt table-row 2) operands))))
+
+(defun ez-read-var-operands-and-inc ()
+  (let* ((type-byte (ez-read-pc-byte-and-inc))
+         (bleh (message (binformat type-byte)))
+         (types (let ((type1 (lsh type-byte -6)))
+                  (if (= type1 #b11)
+                      nil
+                    (cons type1
+                          (let ((type2 (lsh (logand #b110000 type-byte) -4)))
+                            (if (= type2 #b11)
+                                nil
+                              (cons type2
+                                    (let ((type3 (lsh (logand #b1100 type-byte) -2)))
+                                      (if (= type3 #b11)
+                                          nil
+                                        (cons type3
+                                              (let ((type4 (logand #b11)))
+                                                (if (= type4 #b11)
+                                                    nil
+                                                  (list type4)))))))))))))
+         (operands nil))
+    (mapcar
+     (lambda (type)
+       (cond
+        ((= type 0) (ez-read-pc-word-and-inc))
+        ((= type 1) (ez-read-pc-byte-and-inc))
+        ((= type 2) (ez-read-pc-var-and-inc))))
+     types)))
+
+(defvar ez-op-table
+  '(((var #x0) call_fv ez-op-callf)))
+
+(defun ez-op-callf (raddr &rest operands)
+  (let* ((r (* 2 raddr))
+         (L (ez-mem-ref-byte r))
+         (n (length operands))
+         (new-pc (+ r 1 (* L 2))))
+    (ez-add-call-stack-frame new-pc)
+    (dotimes (i L)
+      (if (< i n)
+          (ez-set-local-var (+ i 1) (elt operands i))
+        (ez-set-local-var (+ i 1) (ez-mem-ref-byte (+ r 1 (* 2 i)))))))
+  t)
 
 ;; Main
 
 (ez-load-file "zork1.z3")
 (ez-parse-header)
 (setq ez-call-stack (list (ez-make-call-stack-frame ez-start-pc)))
+(ez-execute-instr)
+
+(binformat #x9b)
+"10 01 10 11"
+
+(* 2 #x2b07)
+
+"10011011"
+
+#b00101111
+(lsh #x2f)
+
+ez-call-stack
+
+(binformat #x2f)
+"10 11 11"
+(* 2 #x2b07)
+
 
 (ez-get-obj 1)
 
       (binformat d new-s))))
 
 
-(binformat (ez-mem-ref-byte ez-start-pc))
-"11100000"
-
 
 ;;; ez.el ends here