<commit_before>(ns chip8-clj.instructions
  (:require [chip8-clj.graphics :as graphics]
            [chip8-clj.utils :as utils]
            [chip8-clj.machine-state :as machine-state]
            [clojure.tools.logging :as log]))

(defn execute-0NNN
  [machine-state opcode]
  (log/info "execute-0NNN: Error: Not yet implemented")
  (System/exit 1))

(defn execute-00E0
  [machine-state opcode]
  (log/info "execute-00E0: Error: Not yet implemented")
  (System/exit 1))

(defn execute-00EE
  [machine-state opcode]
  (let [machine-state (assoc machine-state :stack-ptr (dec (:stack-ptr machine-state)))
        return-addr (get (:stack machine-state) (:stack-ptr machine-state))]
    (log/info (format "0x%04x 00EE 0x%04x ret 0x%04x" (:pc machine-state) opcode return-addr))
    (assoc machine-state :pc return-addr)))

(defn execute-1NNN
  [machine-state opcode]
  (let [imm (utils/get-nnn opcode)]
    (log/info (format "0x%04x 1NNN 0x%04x jmp 0x%04x" (:pc machine-state) opcode imm))
    (machine-state/set-pc machine-state imm)))

(defn execute-2NNN
  [machine-state opcode]
  (let [target-addr (utils/get-nnn opcode)]
    (log/info (format "0x%04x 2NNN 0x%04x cll 0x%04x" (:pc machine-state) opcode target-addr))
    (aset-int (:stack machine-state) (:stack-ptr machine-state) (+ (:pc machine-state) 2))
    (-> machine-state
        (assoc :stack-ptr (inc (:stack-ptr machine-state)))
        (assoc :pc target-addr))))

(defn execute-3XNN
  [machine-state opcode]
  (let [reg-num (utils/get-nibble1 opcode)
        imm (utils/get-byte1 opcode)
        reg-val (machine-state/get-register machine-state reg-num)]
    (log/info (format "0x%04x 3XNN 0x%04x skp V[%d](0x%02x) == 0x%02x" 
                       (:pc machine-state) opcode reg-num reg-val imm))
    (if (= reg-val imm)
        (machine-state/skip-next-pc machine-state)
        (machine-state/increment-pc machine-state))))

(defn execute-4XNN
  [machine-state opcode]
  (let [reg-num (utils/get-nibble1 opcode)
        imm (utils/get-byte1 opcode)
        reg-val (machine-state/get-register machine-state reg-num)]
    (log/info (format "0x%04x 4XNN 0x%04x skp V[%d](0x%02x) != 0x%02x" 
                       (:pc machine-state) opcode reg-num reg-val imm))
    (if (not= reg-val imm)
        (machine-state/skip-next-pc machine-state)
        (machine-state/increment-pc machine-state))))

(defn execute-5XY0
  [machine-state opcode]
  (let [reg-x-num (utils/get-nibble1 opcode)
        reg-y-num (utils/get-nibble2 opcode)
        reg-x-val (machine-state/get-register machine-state reg-x-num) 
        reg-y-val (machine-state/get-register machine-state reg-y-num)]
    (log/info (format "0x%04x 5XY0 0x%04x skp V[%d](0x%02x) == V[%d](0x%02x)" 
                       (:pc machine-state) opcode reg-x-num reg-x-val reg-y-val reg-y-val))
    (if (= reg-x-val reg-y-val)
        (machine-state/skip-next-pc machine-state)
        (machine-state/increment-pc machine-state))))

(defn execute-6XNN
  [machine-state opcode]
  (let [reg (utils/get-nibble1 opcode)
        imm (utils/get-byte1 opcode)]
    (log/info (format "0x%04x 6XNN 0x%04x set V[%d](0x%02x) = 0x%02x" 
                       (:pc machine-state) opcode reg imm imm))
    (-> machine-state
        (machine-state/set-register reg imm)
        (machine-state/increment-pc))))

(defn execute-7XNN
  [machine-state opcode]
  (let [reg-num (utils/get-nibble1 opcode)
        imm (utils/get-byte1 opcode)
        reg-val (machine-state/get-register machine-state reg-num)
        result (+ reg-val imm)]
    (log/info (format "0x%04x 7XNN 0x%04x add V[%d](0x%02x) = V[%d](0x%02x) + 0x%02x" 
                       (:pc machine-state) opcode reg-num result reg-num reg-val imm))
    (-> machine-state
        (machine-state/set-register reg-num result)
        (machine-state/increment-pc))))

(defn execute-8XY0
  [machine-state opcode]
  (log/info "execute-8XY0: Error: Not yet implemented")
  (System/exit 1))

(defn execute-8XY1
  [machine-state opcode]
  (log/info "execute-8XY1: Error: Not yet implemented")
  (System/exit 1))

(defn execute-8XY2
  [machine-state opcode]
  (log/info "execute-8XY2: Error: Not yet implemented")
  (System/exit 1))

(defn execute-8XY3
  [machine-state opcode]
  (log/info "execute-8XY3: Error: Not yet implemented")
  (System/exit 1))

(defn execute-8XY4
  [machine-state opcode]
  (log/info "execute-8XY4: Error: Not yet implemented")
  (System/exit 1))

(defn execute-8XY5
  [machine-state opcode]
  (log/info "execute-8XY5: Error: Not yet implemented")
  
  (System/exit 1))

(defn execute-8XY6
  [machine-state opcode]
  (log/info "execute-8XY6: Error: Not yet implemented")
  (System/exit 1))

(defn execute-8XY7
  [machine-state opcode]
  (log/info "execute-8XY7: Error: Not yet implemented")
  (System/exit 1))

(defn execute-8XYE
  [machine-state opcode]
  (log/info "execute-8XYE: Error: Not yet implemented")
  (System/exit 1))

(defn execute-9XY0
  [machine-state opcode]
  (log/info "execute-9XY0: Error: Not yet implemented")
  (System/exit 1))

(defn execute-ANNN
  [machine-state opcode]
  (let [nnn (utils/get-nnn opcode)]
    (log/info (format "0x%04x ANNN 0x%04x sti I = 0x%03x" 
                       (:pc machine-state) opcode nnn))
    (-> machine-state
        (machine-state/set-addr-reg nnn)
        (machine-state/increment-pc))))

(defn execute-BNNN
  [machine-state opcode]
  (log/info "execute-BNNN: Error: Not yet implemented")
  (System/exit 1))

(defn execute-CXNN
  [machine-state opcode]
  (log/info "execute-CXNN: Error: Not yet implemented")
  (System/exit 1))

(defn execute-DXYN
  [machine-state opcode]
  (let [reg-x-num (utils/get-nibble1 opcode)
        reg-y-num (utils/get-nibble2 opcode)
        imm (utils/get-nibble3 opcode)
        reg-x-val (machine-state/get-register machine-state reg-x-num) 
        reg-y-val (machine-state/get-register machine-state reg-y-num)
        addr-reg (machine-state/get-addr-reg machine-state)]
    (log/info (format "0x%04x DXVN 0x%04x drw V[%d](0x%02x), V[%d](0x%02x), %d, I(0x%04x)" 
                       (:pc machine-state) opcode reg-x-num reg-x-val reg-y-num reg-y-val imm addr-reg))

    (as-> machine-state $ 
      (machine-state/clear-carry-flag $)

      ; For each row in the sprite
      (reduce 
        (fn [machine-state row-index] 
          (let [memory-byte (machine-state/get-memory <commit_msg>Implemented the random bitwise and instruction<commit_after>(ns chip8-clj.instructions
  (:require [chip8-clj.graphics :as graphics]
            [chip8-clj.utils :as utils]
            [chip8-clj.machine-state :as machine-state]
            [clojure.tools.logging :as log]))

(defn execute-0NNN
  [machine-state opcode]
  (log/info "execute-0NNN: Error: Not yet implemented")
  (System/exit 1))

(defn execute-00E0
  [machine-state opcode]
  (log/info "execute-00E0: Error: Not yet implemented")
  (System/exit 1))

(defn execute-00EE
  [machine-state opcode]
  (let [machine-state (assoc machine-state :stack-ptr (dec (:stack-ptr machine-state)))
        return-addr (get (:stack machine-state) (:stack-ptr machine-state))]
    (log/info (format "0x%04x 00EE 0x%04x ret 0x%04x" (:pc machine-state) opcode return-addr))
    (assoc machine-state :pc return-addr)))

(defn execute-1NNN
  [machine-state opcode]
  (let [imm (utils/get-nnn opcode)]
    (log/info (format "0x%04x 1NNN 0x%04x jmp 0x%04x" (:pc machine-state) opcode imm))
    (machine-state/set-pc machine-state imm)))

(defn execute-2NNN
  [machine-state opcode]
  (let [target-addr (utils/get-nnn opcode)]
    (log/info (format "0x%04x 2NNN 0x%04x cll 0x%04x" (:pc machine-state) opcode target-addr))
    (aset-int (:stack machine-state) (:stack-ptr machine-state) (+ (:pc machine-state) 2))
    (-> machine-state
        (assoc :stack-ptr (inc (:stack-ptr machine-state)))
        (assoc :pc target-addr))))

(defn execute-3XNN
  [machine-state opcode]
  (let [reg-num (utils/get-nibble1 opcode)
        imm (utils/get-byte1 opcode)
        reg-val (machine-state/get-register machine-state reg-num)]
    (log/info (format "0x%04x 3XNN 0x%04x skp V[%d](0x%02x) == 0x%02x" 
                       (:pc machine-state) opcode reg-num reg-val imm))
    (if (= reg-val imm)
        (machine-state/skip-next-pc machine-state)
        (machine-state/increment-pc machine-state))))

(defn execute-4XNN
  [machine-state opcode]
  (let [reg-num (utils/get-nibble1 opcode)
        imm (utils/get-byte1 opcode)
        reg-val (machine-state/get-register machine-state reg-num)]
    (log/info (format "0x%04x 4XNN 0x%04x skp V[%d](0x%02x) != 0x%02x" 
                       (:pc machine-state) opcode reg-num reg-val imm))
    (if (not= reg-val imm)
        (machine-state/skip-next-pc machine-state)
        (machine-state/increment-pc machine-state))))

(defn execute-5XY0
  [machine-state opcode]
  (let [reg-x-num (utils/get-nibble1 opcode)
        reg-y-num (utils/get-nibble2 opcode)
        reg-x-val (machine-state/get-register machine-state reg-x-num) 
        reg-y-val (machine-state/get-register machine-state reg-y-num)]
    (log/info (format "0x%04x 5XY0 0x%04x skp V[%d](0x%02x) == V[%d](0x%02x)" 
                       (:pc machine-state) opcode reg-x-num reg-x-val reg-y-val reg-y-val))
    (if (= reg-x-val reg-y-val)
        (machine-state/skip-next-pc machine-state)
        (machine-state/increment-pc machine-state))))

(defn execute-6XNN
  [machine-state opcode]
  (let [reg (utils/get-nibble1 opcode)
        imm (utils/get-byte1 opcode)]
    (log/info (format "0x%04x 6XNN 0x%04x set V[%d](0x%02x) = 0x%02x" 
                       (:pc machine-state) opcode reg imm imm))
    (-> machine-state
        (machine-state/set-register reg imm)
        (machine-state/increment-pc))))

(defn execute-7XNN
  [machine-state opcode]
  (let [reg-num (utils/get-nibble1 opcode)
        imm (utils/get-byte1 opcode)
        reg-val (machine-state/get-register machine-state reg-num)
        result (+ reg-val imm)]
    (log/info (format "0x%04x 7XNN 0x%04x add V[%d](0x%02x) = V[%d](0x%02x) + 0x%02x" 
                       (:pc machine-state) opcode reg-num result reg-num reg-val imm))
    (-> machine-state
        (machine-state/set-register reg-num result)
        (machine-state/increment-pc))))

(defn execute-8XY0
  [machine-state opcode]
  (log/info "execute-8XY0: Error: Not yet implemented")
  (System/exit 1))

(defn execute-8XY1
  [machine-state opcode]
  (log/info "execute-8XY1: Error: Not yet implemented")
  (System/exit 1))

(defn execute-8XY2
  [machine-state opcode]
  (log/info "execute-8XY2: Error: Not yet implemented")
  (System/exit 1))

(defn execute-8XY3
  [machine-state opcode]
  (log/info "execute-8XY3: Error: Not yet implemented")
  (System/exit 1))

(defn execute-8XY4
  [machine-state opcode]
  (log/info "execute-8XY4: Error: Not yet implemented")
  (System/exit 1))

(defn execute-8XY5
  [machine-state opcode]
  (log/info "execute-8XY5: Error: Not yet implemented")
  
  (System/exit 1))

(defn execute-8XY6
  [machine-state opcode]
  (log/info "execute-8XY6: Error: Not yet implemented")
  (System/exit 1))

(defn execute-8XY7
  [machine-state opcode]
  (log/info "execute-8XY7: Error: Not yet implemented")
  (System/exit 1))

(defn execute-8XYE
  [machine-state opcode]
  (log/info "execute-8XYE: Error: Not yet implemented")
  (System/exit 1))

(defn execute-9XY0
  [machine-state opcode]
  (log/info "execute-9XY0: Error: Not yet implemented")
  (System/exit 1))

(defn execute-ANNN
  [machine-state opcode]
  (let [nnn (utils/get-nnn opcode)]
    (log/info (format "0x%04x ANNN 0x%04x sti I = 0x%03x" 
                       (:pc machine-state) opcode nnn))
    (-> machine-state
        (machine-state/set-addr-reg nnn)
        (machine-state/increment-pc))))

(defn execute-BNNN
  [machine-state opcode]
  (log/info "execute-BNNN: Error: Not yet implemented")
  (System/exit 1))

(defn execute-CXNN
  [machine-state opcode]
  (let [reg-num (utils/get-nibble1 opcode)
        imm (utils/get-byte1 opcode)
        rnd (rand-int 0xFF)
        result (bit-and imm rnd)]
    (log/info (format "0x%04x CXNN 0x%04x rnd V[%d](0x%02x) <- rand(0x%02x) & NN(0x%02x)" 
                       (:pc machine-state) opcode reg-num result rnd imm))
    (-> machine-state
        (machine-state/set-register reg-num result)
        (machine-state/increment-pc))))

(defn execute-DXYN
  [machine-state opcode]
  (let [reg-x-num (utils/get-nibble1 opcode)
        reg-y-num (utils/get-nibble2 opcode)
        imm (utils/get-nibble3 opcode)
        reg-x-val (machine-state/get-register machine-state reg-x-num) 
        reg-y-val (machine-state/get-register machine-state reg-y-num)
        addr-reg (machine-state/get-addr-reg machine-state)]
    (log/info (format "0x%04x DXVN 0x%04x drw V[%d](0x%02x), V[%d](0x%02x), %d, I(0x%04x)" 
                       (:pc machine-state) opcode reg-x-num reg-x-val reg-y-num reg-y-val imm addr-reg))

    (as-> machine-state $ 
      (machine-state/clear-carry-flag $)

      ; For each row in the sprite
      (reduce 
        (fn [machine-state row-index] 
          (let [memory-byte (machine-state/get-memory 
{'fraction_non_alphanumeric': 0.15093044539353265, 'fraction_numerical': 0.0336333129957291, 'mean_word_length': 2.857899382171227, 'pattern_counts': {'":': 0, '<': 4, '<?xml version=': 0, '>': 14, 'https://': 0, 'lorem ipsum': 0, 'www.': 0, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 0, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '7635157', 'n_tokens_mistral': 5205, 'n_tokens_neox': 4943, 'n_words': 1116}