;;; -*- Mode:LISP; Package:K-KBUG; Base:10; Readtable:CL -*-
;;;
;;; WARM-FILES.LISP
;;;
;;;
;;; This file provides some user functions to boot the K processor and
;;; download system files.
;;;
;;; The function (MEGA-BOOT) builds a new cold load, writes the cold load
;;; to the K processor, and boots the K processor.  Then it downloads the
;;; files on the *warm-loaded-files* list.  Next, it runs the function
;;; (LISP-INTERNALS::WARM-BOOT) on the K processor, which initializes the
;;; package system and evaluator.  Finally, it downloads the files on the
;;; *hot-loaded-files* list.
;;;
;;; When supplied with a non-NIL optional argument, MEGA-BOOT does not
;;; build a new cold load.  Instead, it reuses the last one created.
;;;
;;; Each entry of *warm-loaded-files* and *hot-loaded-files* is either a string
;;; (the filename) or a list of two elements, the filename and a second value.
;;; This second value controls whether or not the corresponding KENV file should
;;; be loaded.  If it is true, or the entry is just a filename, then the KENV
;;; file is loaded on the lambda at the same time the KFASL file is loaded on
;;; the K processor.  If it is NIL, then the KENV file is suppressed.
;;;
;;; Note:  When the lambda is freshly booted, it needs to know what slot the K
;;; processor is in before MEGA-BOOT can be run.  The function which does this
;;; is (LAM:K-LOCAL-SETUP <slot>), where <slot> is the slot number of the K 
;;; memory board (the one with the LED's)
;;;
;;; (James Rauen 4-Mar-88 20:25:13)


(defparameter *warm-loaded-files*
   ;These are the files which are needed to get the package system and
   ;interpreter running.
   ;** if you add files here, remember to add them to the k-warm system in SIMULATION-SYSDEF.
        '(
	  "jb:k.math;generic"
	  "jb:k.math;arithmetic"
	  "jb:k.math;convert"
	  "jb:k.math;fixnum"

	  "jb:k.array;array2"
	  "jb:k.array;character"
	  "jb:k.array;string"

	  "jb:k.list;lists"
	  "jb:k.list;bald"
	  "jb:k;nseq"

	  "jb:k;equal"
	  "jb:k;hash"

	  "jb:k;throw"
	  "jb:k;stack-groups"
	  "jb:k;control-pdl"
	  "jb:k;boot-stack-groups"
	  "jb:k;package"
	  "jb:k;warm-boot"

	  "jb:k.interpreter;vanilla-interpreter"
	  "jb:k;defmacro"
	  "jb:k;top-level-forms"

	  "jb:k;miscellaneous-functions"
	  ))

(defparameter *hot-loaded-files*
  ;These are all the other K source files we want to load.
  '(
    ("jb:k.lisp-io;readtable" NIL)
    "jb:k.lisp-io;reader"
    ("jb:k.lisp-io;high-level-streams" NIL)
    "jb:k.lisp-io;printer"
    "jb:k.lisp-io;format"

    "jb:k.interpreter;mini-lisp-listener"

;    "jb:k;vcmem-driver"
;    "jb:k;k-uc-tv"

    "jb:k.math;bignum"
;    "jb:k.math;float"
    "jb:k.math;rational"
;    "jb:k.math;complex"

;    "jb:k;hot-boot"

    "jb:k.math;cross-support"	;functions in here exist mostly for cross compiler.
		))



;;; changed to prevent arbitrary bashing of KFASL/KENV files by :RECOMPILE  - pfc 5/2/88
;;; copies the .LISP file to create a new version before :RECOMPILE takes place --pfc 5/3/88

(defun warm-compile-and-load-file (file &optional (compile-type :compile) (load-kenv-file t))
  (let ((kfasl-real-pathname (zl:probef (fs:merge-pathname-defaults file nil "KFASL" :newest))))
    (when (or (and (or (eq compile-type :compile)
		      (eq compile-type :recompile))
		   (cold:cold-file-needs-compiling? file kfasl-real-pathname))
	      (and (eq compile-type :recompile)
		   (not  (cold:cold-file-needs-compiling? file kfasl-real-pathname))
		   (progn
		    (let* ((pathname (fs:merge-pathname-defaults file fs:load-pathname-defaults))
			   (oldversion (zl:send (zl:send pathname :truename) :version))
			   (newpathname (fs:merge-pathname-defaults file fs:load-pathname-defaults
								    fs:*name-specified-default-type*
								    (1+ oldversion))))
		      (fs:copy-file pathname newpathname :copy-creation-date nil :copy-author nil))
		    t)
		   ))
      (global:pkg-goto 'user)
      (compiler:::nlisp:compile-file file)
      (global:pkg-goto 'k-kbug))
    (kbug-fasl file load-kenv-file)))

(defun hot-load (&optional (file-list *hot-loaded-files*) (compile-type :compile))
  "Warm-boot the K and load the files in FILE-LIST"
  (kbug-goto 'li:warm-boot)
  (sleep 0.1)
  (kbug-proceed)
  (sleep 10)
  (kbug-stop)
  (warm-load file-list compile-type))

(defun mega-boot (&key fast (compile-type :compile) (no-warn nil))
  (unless (or lam:*local-k-slot*
	      (not lam:*local-debugging*))  ;;wkf added check for non-local-debugging 5/11/88
    (error "~% You did not call (lam:k-local-setup n) 
             or (progn (lam:manual-debug-slot-setup #xfd) (k-setup) (lam:clear-debug-semaphore)) for non local debugging"))
  (telnet:without-more-processing *terminal-io*
    (let ((inhibit-fdefine-warnings no-warn))
      (progn (k-boot fast compile-type)
	     (hot-load *hot-loaded-files* compile-type)))))

(defun warm-load (&optional (file-list *warm-loaded-files*) (compile-type :compile))
  (dolist (f file-list)
    (cond
      ((stringp f)
       (warm-compile-and-load-file f compile-type))
      ((listp f)
       (let ((filename (car f))
	     (load-kenv-file? (cadr f)))
	 (warm-compile-and-load-file filename compile-type load-kenv-file?))))))

(defun k-boot (&optional inhibit-cold-load? (compile-type :compile))
  (si:pkg-goto 'k-kbug)
  (unless inhibit-cold-load?
    (k-cold:make-cold-load :compile-type compile-type)
    (setq k-cold:*mega-boot-cold-load-already-done* t))
  (si:pkg-goto 'k-kbug)
  (clear-breakpoint)
  (setq *breakpoints-installed* nil)
  (download-cold-load)
  
  ;; PSEUDO-BOOT reaches into the cold-load and jumps to the address of the boot function
  ;; which is at **INITIAL-CODE-ENTRY-POINT-BV-OFFSET**
  ;; MAKE-COLD-LOAD has initialized this to BOOT:COLD-BOOT-FUNCTION
  
  (pseudo-boot)
  
  ;; this call to K-RUN fires up  BOOT:COLD-BOOT-FUNCTION,BOOT:EVENT-HORIZON, and BOOT:SYNTHESIZE-COLD-LOAD
  ;; which stops with a call to TRAP::ILLOP to say "Cold load finished!"
  ;; which is picked up by the call to WHY below.
  
  (lam:k-run)
  (sleep 3)
  (do () ((= 1 (lam:k-read-spy-halt))))
  (why)
  (dotimes (i 5) (lam:k-step))
  
  ;;  BOOT:SYNTHESIZE-COLD-LOAD continues with a call to 
  ;;   BOOT:WARM-START which initializes the state of all traps and calls
  ;;     LI:FLUSH-CALL-STACK 
  ;;      (never returns, which is why you see that at the bottom of your stack in KBUG2...)
  ;;      calls
  ;;       BOOT:COLD-INITIALIZE-CALL-HARDWARE
  ;;       NUBUS-STUFF:CAUSE-DEBUGGER-TRAP to pause the machine in the debugger 
  ;;       BOOT:WAIT-FOR-DEBUGGER which simply loops calling itself
  ;; comments by Peter Cerrato  4/27/88
  
  (lam:k-run)
  (sleep 3)
  (do () ((kbug-stopped?)))
  (kbug-load-cold-info)
  (unless (eq inhibit-cold-load? :no-warm)
    (warm-load *warm-loaded-files* compile-type))
  )


(defun load-kenv-files ()
  (let ((*package* (zl:pkg-find-package "USER")))
    (flet ((load-kenv (filename)
	     (load (lisp:merge-pathnames filename ".kenv#>"))))
      (dolist (f k-cold:*cold-files*)
	(load-kenv f))
      (dolist (f k-kbug:*warm-loaded-files*)
	(load-kenv f)))))
