;;;-*- Mode:LISP; Package:K2; Readtable:CL; Base:10; compile-in-roots:("K-GLOBAL") -*- ;;; KBUG streams (export '( kbug-stream-initialize kbug-stream-peek-byte kbug-stream-peek-character kbug-stream-read-byte kbug-stream-read-character kbug-stream-write-byte kbug-stream-write-character )) ;;;||| Reworked file to remove (select-processor (:k ...) (:lambda ...)) 10/14/88 --wkf ;;; These two functions are used to determine if the debug master ;;; side or the K machine side of a KBUG stream is being used in ;;; the correct direction. (defun ldb (byte source) #+(target falcon) (if (vinc:fixnump byte) (hw:ldb source byte 0.) (etypecase byte (byte-spec (ldb-hard-case byte source)))) #+(target lambda) (lisp:ldb byte source)) (defun kbug-input-stream? (kbug-stream) "T if this processor is allowed to read from this stream." (= #+(target lambda) $$kbug-stream-flags-direction-FROM-k #+(target falcon) $$kbug-stream-flags-direction-TO-k (ldb %%kbug-stream-flags-direction (kbug-stream-flags kbug-stream)))) (defun kbug-output-stream? (kbug-stream) "T if this processor is allowed to write to this stream." (= #+(target lambda) $$kbug-stream-flags-direction-TO-k #+(target falcon) $$kbug-stream-flags-direction-FROM-k (ldb %%kbug-stream-flags-direction (kbug-stream-flags kbug-stream)))) (defun kbug-stream-pointer-1+ (kbug-stream pointer) "Given a KBUG stream and the value of one of its pointers, return the next location that the pointer will point to. That is, increment it but take into account any necessary wrapping." (let ((new-pointer (1+ pointer))) (if (>= new-pointer (kbug-stream-end kbug-stream)) (kbug-stream-base kbug-stream) new-pointer))) (defun kbug-stream-advance-in-pointer (kbug-stream) "Increment the in-pointer of KBUG-STREAM." (setf (kbug-stream-in-pointer kbug-stream) (kbug-stream-pointer-1+ kbug-stream (kbug-stream-in-pointer kbug-stream)))) (defun kbug-stream-advance-out-pointer (kbug-stream) (setf (kbug-stream-out-pointer kbug-stream) (kbug-stream-pointer-1+ kbug-stream (kbug-stream-out-pointer kbug-stream)))) ;;; Why read byte? Because we would have to deal with the boxedness issue if we ;;; read a Q. (defun initialize-kbug-stream (kbug-stream direction base end) (setf (kbug-stream-base kbug-stream) base) (setf (kbug-stream-end kbug-stream) end) (setf (kbug-stream-flags kbug-stream) (hw:dpb direction %%kbug-stream-flags-direction (kbug-stream-flags kbug-stream)))) (defun kbug-stream-needs-input (kbug-stream out-ptr) (do () ((not (= (kbug-stream-in-pointer kbug-stream) ;;wait for byte to exist in stream. out-ptr))))) (defun kbug-stream-needs-output (kbug-stream in-ptr+1) (do () ((not (= (kbug-stream-out-pointer kbug-stream) in-ptr+1))))) ;;; open code things and eliminate gratuitous memory references (defun kbug-stream-peek-byte (kbug-stream) (unless (kbug-input-stream? kbug-stream) #+(target falcon) (trap::illop "Input requested from write-only KBUG stream") #+(target lambda) (global:ferror nil "Input requested from a write-only KBUG stream")) (%kbug-stream-peek-byte kbug-stream (kbug-stream-out-pointer kbug-stream))) (defun %kbug-stream-peek-byte (kbug-stream out-ptr) ;;optimized by --wkf #+(target lambda) (progn (when (= (kbug-stream-in-pointer kbug-stream) out-ptr) (zl:process-wait "Readch" (kbug::make-fancy-wait-function #'zl:false #'(lambda () (not (= (kbug-stream-in-pointer kbug-stream) out-ptr)))))) (hw:dpb (ldb (byte 8 0) (kbug-get-comm-word out-ptr)) (byte 8 0) 0)) #+(target falcon) (progn (kbug-stream-needs-input kbug-stream out-ptr) (hw:vma-start-read-no-transport-vma-unboxed-md-unboxed (+ kbug-base-addr out-ptr)) (hw:dpb (hw:read-md) (byte 8 0) 0))) (defun kbug-stream-peek-character (kbug-stream) (cons:make-pointer vinc:$$dtp-character (kbug-stream-peek-byte kbug-stream))) (defun kbug-stream-read-byte (kbug-stream) (prog1 (kbug-stream-peek-byte kbug-stream) (kbug-stream-advance-out-pointer kbug-stream))) (defun kbug-stream-read-character (kbug-stream) (unless (kbug-input-stream? kbug-stream) #+(target falcon) (trap::illop "Input attempted from write-only KBUG stream") #+(target lambda) (zl::ferror nil "Input attempted from write-only KBUG stream")) (let* () #+(target falcon) (cons:make-pointer vinc:$$dtp-character (kbug-stream-read-byte kbug-stream)) #+(target lambda) (lisp:code-char (kbug-stream-read-byte kbug-stream)))) ;;; open code things and eliminate gratuitous memory references (defun kbug-stream-write-character (kbug-stream character) (unless (kbug-output-stream? kbug-stream) #+(target falcon) (trap::illop "Output attempted to read-only KBUG stream") #+(target lambda) (zl::ferror nil "Output attempted to read-only KBUG stream")) (let* ((in-ptr (kbug-stream-in-pointer kbug-stream)) (in-ptr+1 (kbug-stream-pointer-1+ kbug-stream in-ptr))) #+(target lambda) (when (= (kbug-stream-out-pointer kbug-stream) in-ptr+1) (zl:process-wait "Writech" (kbug::make-fancy-wait-function #'zl:false #'(lambda () (not (= (kbug-stream-out-pointer kbug-stream) in-ptr+1)))))) #+(target falcon) (kbug-stream-needs-output kbug-stream in-ptr+1) (kbug-set-comm-word in-ptr character) (setf (kbug-stream-in-pointer kbug-stream) (kbug-stream-pointer-1+ kbug-stream in-ptr)))) (defun kbug-stream-write-byte (kbug-stream byte) (unless (kbug-output-stream? kbug-stream) #+(target falcon) (trap::illop "Output attempted to read-only KBUG stream") #+(target lambda) (zl::ferror nil "Output attempted to read-only KBUG stream")) (let* ((in-ptr (kbug-stream-in-pointer kbug-stream)) (in-ptr+1 (kbug-stream-pointer-1+ kbug-stream in-ptr))) #+(target lambda) (when (= (kbug-stream-out-pointer kbug-stream) in-ptr+1) (zl:process-wait "Writech" (kbug::make-fancy-wait-function #'zl:false #'(lambda () (not (= (kbug-stream-out-pointer kbug-stream) in-ptr+1)))))) #+(target falcon) (kbug-stream-needs-output kbug-stream in-ptr+1) (kbug-set-comm-word in-ptr byte) (setf (kbug-stream-in-pointer kbug-stream) (kbug-stream-pointer-1+ kbug-stream in-ptr)))) #+(target lambda) (defun kbug-stream-string-out (kbug-stream string) (unless (kbug-output-stream? kbug-stream) #+(target falcon) (trap::illop "Output attempted to read-only KBUG stream") #+(target lambda) (zl:ferror nil "Output attempted to read-only KBUG stream")) (let ((base (kbug-stream-base kbug-stream)) (end (kbug-stream-end kbug-stream)) (chars-to-send (zl:length string))) (labels ((wait-for-space (string-index) (let* ((in-pointer (kbug-stream-in-pointer kbug-stream)) (in+1 (kbug-stream-pointer-1+ kbug-stream in-pointer))) #+(target lambda) (when (= (kbug-stream-out-pointer kbug-stream) in+1) (zl:process-wait "Writest" (kbug::make-fancy-wait-function #'zl:false #'(lambda () (not (= (kbug-stream-out-pointer kbug-stream) in+1)))))) #+(target falcon) (kbug-stream-needs-output kbug-stream in+1) ;; Now we have space, find out how much (let* ((out-pointer (kbug-stream-out-pointer kbug-stream)) (space (if (>= in-pointer out-pointer) (1- (+ (- end in-pointer) (- out-pointer base))) (- (- out-pointer in-pointer) 2)))) (send-string string-index in-pointer space)))) (increment-stream-pointer (pointer) (let ((new (1+ pointer))) (if (>= new end) base new))) (send-string (string-index buffer-index space) (cond ((= string-index chars-to-send) (setf (kbug-stream-in-pointer kbug-stream) buffer-index)) ((lisp:zerop space) (setf (kbug-stream-in-pointer kbug-stream) buffer-index) (wait-for-space string-index)) (t (kbug-set-comm-word buffer-index (lisp::char string string-index)) (send-string (1+ string-index) (increment-stream-pointer buffer-index) (1- space)))))) (wait-for-space 0)))) (defun kbug-stream-initialize (kbug-stream flags begin end) (setf (kbug-stream-base kbug-stream) begin) (setf (kbug-stream-end kbug-stream) end) (setf (kbug-stream-in-pointer kbug-stream) begin) (setf (kbug-stream-out-pointer kbug-stream) begin) (setf (kbug-stream-flags kbug-stream) flags))