;;;
;;; raven-memory.lisp
;;;
;;; On-board CPU memory spaces (I-, D-, T-, A-, M-, etc.)
;;;

(defvar *m-memory* (make-array '(#x40) :element-type '(unsigned-byte 32)
			       :initial-element 0)
  "M-Memory storage.")

(defvar *a-memory* (make-array '(#x400) :element-type '(unsigned-byte 32)
			       :initial-element 0)
  "A-Memory storage.")

(defvar *prom-memory* (make-array '(#x800) :element-type '(unsigned-byte 56)
				  :initial-element 0)
  "CPU I-Memory PROM Overlay.")

(defvar *i-memory* (make-array '(#x4000) :element-type '(unsigned-byte 56)
			       :initial-element 0)
  "CPU I-Memory.")

(defvar *t-memory* (make-array '(16) :element-type '(unsigned-byte 32)
			       :initial-element 0)
  "Tag-Classifier Memory.")

(defun write-t-memory (address data)
  (setf (aref *t-memory* address)
	(dpb (ldb (byte 1 30) data)
	     (byte 1 (ldb (byte 5 25) data))
	     (aref *t-memory* address))))

(defun read-t-memory (address data)
  (ldb (byte 1 (ldb (byte 5 25) data))
	     (aref *t-memory* address)))

(defun write-m-memory (address data)
  (setf (aref *m-memory* address) data)
  (setf (aref *a-memory* address) data))

(defun read-m-memory (address)
  (if (< address #x40)
      (aref *m-memory* address)
    (read-functional-source (logand address #x3f))))

(defun write-a-memory (address data)
  (setf (aref *a-memory* address) data))

(defun read-a-memory (address)
  (aref *a-memory* address))

(defun read-i-memory (address)
  (if (and (< address #x800)
	   T) ;; FIXME: Should be a bit in the MCR.
      (aref *prom-memory* address)
    (aref *i-memory* address)))

(defun write-i-memory (address data)
  (setf (aref *i-memory* address) data))

;; NOTE: Duplicate of function in dise1uc.
(defun read-one-instruction (stream)
  (read-byte stream)
  (let ((word 0))
    (dotimes (i 7)
      (setf word (dpb (read-byte stream)
		      (byte 8 (* i 8))
		      word)))
    word))

(defun load-prom-memory (filename)
  (with-open-file (romfile filename :direction :input
			   :element-type '(unsigned-byte 8))
		  (dotimes (i #x800)
		    (setf (aref *prom-memory* i)
			  (read-one-instruction romfile)))))

#|
(load-prom-memory #p"/home/nyef/src/lisp/aek/E1_eproms/prom_combined")


If you have dise1uc loaded then

(disassemble-instruction (aref *prom-memory* 0))

Should print ((M-0 TEST-SYNCH) SETZ).
|#

;;; EOF
