;;;
;;; raven-mmu.lisp
;;;
;;; Memory address translation.
;;;

(in-package :nevermore)

(declaim (inline write-map-level-2-address))
(defun write-map-level-2-address ()
  (let* ((map-1 (aref *level-1-map* (ldb (byte 12 13) (aref *memory-data*))))
	 (map-2-address (dpb map-1 (byte 7 5)
			     (ldb (byte 5 8) (aref *memory-data*)))))
    (setf (aref *level-2-address* map-2-address) (aref *virtual-memory-address*)))
  (values))

(declaim (inline write-map-level-2-control))
(defun write-map-level-2-control ()
  (let* ((map-1 (aref *level-1-map* (ldb (byte 12 13) (aref *memory-data*))))
	 (map-2-address (dpb map-1 (byte 7 5)
			     (ldb (byte 5 8) (aref *memory-data*)))))
    (setf (aref *level-2-control* map-2-address) (aref *virtual-memory-address*)))
  (values))

(defun start-read ()
  (let ((lvl1 (aref *level-1-map* (ldb (byte 12 13) (aref *virtual-memory-address*)))))
    (setf *page-fault* nil)
    (format t "Level1: ~X~%" lvl1)
    (when (zerop (logand #x800 lvl1))
      (setf *page-fault* t)
      (format t "Page fault.~%"))))

(defun start-write ()
  (let* ((lvl1 (aref *level-1-map* (ldb (byte 12 13) (aref *virtual-memory-address*))))
	 (map-2-index (dpb lvl1 (byte 7 5) (ldb (byte 5 8) (aref *virtual-memory-address*))))
	 (map-2-control (aref *level-2-control* map-2-index))
	 (map-2-address (aref *level-2-address* map-2-index)))
    (setf *page-fault* nil)
    (format t "Level1: ~X~%" lvl1)
    (when (zerop (logand #x800 lvl1))
      (setf *page-fault* t)
      (format t "Page fault.~%")
      (return-from start-write))
    
    (format t "Level2Ctrl: ~X~%" map-2-control)
    (format t "Level2Addr: ~X~%" map-2-address)
    (when (zerop (logand #x200 map-2-control))
      (setf *page-fault* t)
      (format t "Page fault.~%")
      (return-from start-write))
    
    (when (zerop (logand #x100 map-2-control))
      (setf *page-fault* t)
      (format t "Page fault.~%")
      (return-from start-write))))


;;; EOF
