;;;
;;; memory-nubus.lisp
;;;
;;; NuBus interface to the memory board.
;;;

(in-package :nevermore)

(declaim (type (simple-array (unsigned-byte 8) (*)) *memory-config-rom*))
(defvar *memory-config-rom* (make-array '(#x800) :element-type '(unsigned-byte 8)
				     :initial-element 0))

(declaim (type (simple-array (unsigned-byte 8) (*)) *memory-buffer*))
(defvar *memory-buffer* (make-array '(#x800000) :element-type '(unsigned-byte 8)
				      :initial-element 0))

(defvar *memory-test-unknown* 0)

(defun memory-nubus-read (slot address width)
  (declare (type (unsigned-byte 8) slot)
	   (type (unsigned-byte 24) address)
	   (ignorable slot))
  (cond ((= (logand address #xffe000) #xffe000)
	 (setf *inhibit-nubus-trace* t)
	 (setf (aref *memory-data*) (dpb (aref *memory-config-rom* (ldb (byte 11 2) address)) (byte 8 (* 8 (logand 3 address))) 0)))
	((= (logand address #xffffe0) #xffc000)
	 ;; control space
	 (setf (aref *memory-data*) 0)
	 (if (= address #xffc011) (setf (aref *memory-data*) *memory-test-unknown*)))
	((= (logand address #x800000) #x000000)
	 (setf *inhibit-nubus-trace* t)
	 (if (eq width :byte)
	     (setf (aref *memory-data*) (dpb (aref *memory-buffer* (logand #x7fffff address)) (byte 8 (* 8 (logand 3 address))) 0))
	     (setf (aref *memory-data*) (dpb (aref *memory-buffer* (+ (logand #x7fffff address) 3)) (byte 8 24)
					     (dpb (aref *memory-buffer* (+ (logand #x7fffff address) 2)) (byte 8 16)
						  (dpb (aref *memory-buffer* (+ (logand #x7fffff address) 1)) (byte 8 8)
						       (aref *memory-buffer* (logand #x7fffff address))))))))
	(t (setf *nubus-error* t)))
#+nil  (when (= address #xffe03c) (break))
  (values))

(defun memory-nubus-write (slot address width)
  (declare (type (unsigned-byte 8) slot)
	   (type (unsigned-byte 24) address)
	   (ignorable slot))
  (cond ((= (logand address #x800000) #x000000)
	 (setf *inhibit-nubus-trace* t)
	 (if (eq width :byte)
	     (setf (aref *memory-buffer* (logand #x7fffff address)) (ldb (byte 8 (* 8 (logand 3 address))) (aref *memory-data*)))
	   (progn
	     (setf (aref *memory-buffer* (+ (logand #x7fffff address) 3)) (ldb (byte 8 24) (aref *memory-data*)))
	     (setf (aref *memory-buffer* (+ (logand #x7fffff address) 2)) (ldb (byte 8 16) (aref *memory-data*)))
	     (setf (aref *memory-buffer* (+ (logand #x7fffff address) 1)) (ldb (byte 8  8) (aref *memory-data*)))
	     (setf (aref *memory-buffer* (+ (logand #x7fffff address) 0)) (ldb (byte 8  0) (aref *memory-data*))))))
	((= (logand address #x00ffffe0) #x00ffc000)
	 ;; control space
	 (case (ldb (byte 3 2) address)
	   (0 ;; memory config register
	    )
	   (2 ;; memory base test register
	    )
	   (4 ;; failure location / test register
	    )
	   (5 ;; status error latch
	    )
	   (6 ;; failure register
	    ))
	 (if (= address #xffc011) (setf *memory-test-unknown* (aref *memory-data*))))
	(t (setf *nubus-error* t)))
  (values))

#|
(with-open-file (romfile #p"/home/nyef/src/lisp/aek/E1_eproms/2243924-2_27S291.8MB"
			 :direction :input :element-type '(unsigned-byte 8))
		(dotimes (i #x800)
		  (setf (aref *memory-config-rom* (logxor #x400 i)) (read-byte romfile))))
|#

;;; EOF
