;;; -*- Mode:LISP; Package:SIM; Readtable:CL; Base:10 -*-

(defstruct (proc (:type :named-array)
		 )
  proc-frame-size
  proc-n-frames

  proc-frame-free-list
  proc-frame-free-list-ptr

  proc-frames
  proc-current-frame
  proc-open-frame
  proc-return-frame

  proc-main-memory
  proc-pc

  proc-l1-map
  proc-l2-map-control
  proc-l2-map-physical-page

  )

(defun new-proc (frame-size n-frames main-memory-size)
  (let ((proc (make-proc)))
    (setf (proc-frame-size proc) frame-size)
    (setf (proc-n-frames proc) n-frames)

    (setf (proc-frame-free-list proc) (make-array (proc-n-frames proc)))
    (setf (proc-frames proc) (make-array (* (proc-n-frames proc)
					    (proc-frame-size proc))))
    (setf (proc-main-memory proc) (make-array main-memory-size))

    (setf (proc-l1-map proc) (make-array 4096.))
    (setf (proc-l2-map-control proc) (make-array 4096.))
    (setf (proc-l2-map-physical-page proc) (make-array 4096.))

    (reset-proc proc)
    proc))

(defun reset-proc (proc)
  (dotimes (i (proc-n-frames proc))
    (setf (aref (proc-frame-free-list proc) i) i))
  (setf (proc-frame-free-list-ptr proc) 0)
    
  (array-initialize (proc-frames proc) 0)

  (setf (proc-current-frame proc) 0)
  (setf (proc-open-frame proc) 0)
  (setf (proc-return-frame proc) 0)

  (array-initialize (proc-main-memory proc) 0)

  (setf (proc-pc proc) 0)

  (array-initialize (proc-l1-map proc) 0)
  (array-initialize (proc-l2-map-control proc) 0)
  (array-initialize (proc-l2-map-physical-page proc) 0)

  )

(defstruct (alu-inst (:type :list))
  alu-inst-type
  alu-inst-dest-frame
  alu-inst-dest
  alu-inst-alu-op
  alu-inst-src-1-frame
  alu-inst-src-1
  alu-inst-src-2-frame
  alu-inst-src-2
  )

(defun execute-alu-instruction (inst)
  (let ((src-1 (aref (proc-frames *proc*)
		     (+ (ecase (alu-inst-src-1-frame inst)
			  (current (proc-current-frame *proc*))
			  (open (proc-open-frame *proc*))
			  (return (proc-return-frame *proc*)))
			(alu-inst-src-1 inst))))
	(src-2 (aref (proc-frames *proc*)
		     (+ (ecase (alu-inst-src-2-frame inst)
			  (current (proc-current-frame *proc*))
			  (open (proc-open-frame *proc*))
			  (return (proc-return-frame *proc*)))
			(alu-inst-src-2 inst))))
	(val))
    (ecase (alu-inst-alu-op inst)
      (move (setq val src-1))
      )
    (setf (aref (proc-frames *proc*)
		(+ (ecase (alu-inst-dest-frame inst)
		     (current (proc-current-frame *proc*))
		     (open (proc-open-frame *proc*))
		     (return (proc-return-frame *proc*)))
		   (alu-inst-dest inst))))))

