;;;;;-*- Mode:LISP; Package:LAMBDA; Base:8; Readtable:ZL -*-
;;;
;;; (c) Copyright 1984,1985,1986 - Lisp Machine, Inc.
;;;


;a CSM program is expressed in the form of BLOCKS and STATEMENTS.

;a BLOCK represents 16 consecutive statements stored at a multiple of 16 boundary.
; the block is intended for use with a particular one of the 8 one-of-16 next address
; selection possibilities of the CSM state machine.  Each BLOCK as a symbolic name which
; is a LISP symbol.  The BLOCK is specified by giving its name, the condition to be tested,
; and the symbolic names of the 16 codewords of the block.

;a STATEMENT specifies a CSM codeword.  A next condition is also specified which can
; be either a BLOCK, or another statement.

;Each statement specifies whether it is allowable for a "foreign" NUBUS write to occur
; during this cycle.  If so, an "call" to the verification subroutine is loaded in
; the "mirror" image, if not, a transfer to CACHE-VALIDATION-ERROR.

;CSMRAM fields:

(defconst csm.state (byte 11. 0))
(defconst csm.condition (byte 3 11.))
(defconst csm.cache.mode (byte 2 14.))	;0 nothing, 1 read, 2 write if NU.xfer, 3 write if 
					; cache.hit
(defconst csm.MD.to.NUDATA.bus (byte 1 16.))
(defconst csm.RD.DATA.to.NUDATA.bus (byte 1 17.))
(defconst csm.cache.adr.from.NUADR (byte 1 18.))
(defconst csm.cache.hit.enable (byte 1 19.))
(defconst csm.memory.cycle.ending-L (byte 1 20.))  ;This bit defaulted high if not spec'd 
(defconst csm.count.nuadr (byte 1 21.))  ;this used to be called csm.verify.cycle, which
			;was really unused
(defconst csm.virtual.page.group (byte 1 22.))
(defconst csm.NU.idle (byte 1 23.))   ;drives section of quad-latch on bus-arbitration
	;print which in turn makes STARTs turn into START-ACKs (noops).
	;this can be used to noop out cycle after bus requested and it turns
	;out its not needed.
(defconst csm.statistics.bit (byte 1 24.))   ;used for scope trigger on error..
(defconst csm.lambda.STREQ (byte 1 25.))
(defconst csm.lambda.BREQ (byte 1 26.))
(defconst csm.request.noted-L (byte 1 27.))  ;This bit defaulted high if not spec'd
(defconst csm.parity (byte 4 28.))

(defconst csm.low.asserted.bits '(csm.request.noted-L csm.memory.cycle.ending-L))

;the following bits appear in the CSM code as if they were real bits, however,
; they are really ignored except that the one specified in the :statistics-bit-option
; to LOAD-CSM is loaded into the statistics bit.  Default is csm.cache.hit.bit.
(DEFVAR *CSM-STATISTICS-BIT-OPTION*)

(defconst csm.pseudo.bits
	  '(csm.error.bit
	     csm.requesting.nubus.bit
	     csm.cycle.starting.bit
	     csm.testing.mastership.bit
	     csm.cache.hit.bit
	     csm.fast.cache.hit.bit
	     csm.slow.cache.hit.bit
	     csm.test.slow.cache.bit
	     csm.test.completion.bit
	     csm.await.completion.bit
	     csm.cycle.complete.bit
	     csm.verify.bit
	     csm.verify.error.bit))

(DEFUN PRINT-CSM-REG ()
  (print-csmram-codeword (read-csm-reg)))

(defun print-csmram-codeword (data)
  (TERPRI)
  (LET ((FIELD-LIST '(csm.state 
		      csm.condition 
		      csm.cache.mode
		      csm.MD.to.NUDATA.bus
		      csm.RD.DATA.to.NUDATA.bus
		      csm.cache.adr.from.NUADR
		      csm.cache.hit.enable
		      csm.memory.cycle.ending-L
		      csm.count.nuadr
		      csm.virtual.page.group
		      csm.NU.idle
		      csm.statistics.bit
		      csm.lambda.STREQ
		      csm.lambda.BREQ
		      csm.request.noted-L
		      csm.parity)))
    (DOLIST (F FIELD-LIST)
      (FORMAT T "~s ~o " F (LDB (SYMEVAL F) data)))))

;timing note:  cache.request L is initially asserted by memory.start.this.UINST,
;  so the READ-REQUEST or WRITE-REQUEST codewords are fetched during the source cycle
;  of the UINST following ((xxx-start-xxx) ..), which is normally (and will be referred to)
;  as the CALL-CONDITIONAL.  Thus, READ-REQUEST, for example, appears  in the CSMREG
;  at the beginning of the execute cycle of the CALL-CONDITIONAL.  The first level
;  map was also "started" during the source cycle of the CALL-CONDITIONAL, and thus is
;  "valid" when READ-REQUEST appears in CSMREG.  The second level map, however, (which is
;  the one that really matters), has just started fetching when READ-REQUEST is in CSMREG
;  and is NOT valid.  However, READ-REQUEST causes cache to fetch anyway, so that
;  at the end of READ-REQUEST, a grand and glorious multiway branch can be made.

(DEFCONST SIMPLE-CSM
 '(  ;Note!! IDLE-TEST must be at 0 so CSM can be started there and initialize right!
     (IDLE-TEST (CSM.NU.IDLE 1
		 CSM.MEMORY.CYCLE.ENDING-L 1
		 CSM.REQUEST.NOTED-L 1)
		AWAIT-REQUEST
		T)

     (AWAIT-REQUEST
       (BLOCK 1)	;GND, -DEBUG.CLOCK.MODE.SYNCED, CACHE.REQUEST L, MEMORY.WRITE.CYCLE
       IDLE-TEST IDLE-TEST IDLE-TEST IDLE-TEST	;in debug.clock mode, dont try anything
						;  until clock running at full speed.
       READ-REQUEST WRITE-REQUEST-TO-MEMORY-0 IDLE-TEST IDLE-TEST ERROR)
     
     ;this block used by READ-TEST-1.  It tests conditions set up at end of READ.REQUEST,
     ; which corresponds to the end of the first execute cycle of the CALL-CONDITIONAL.
     ; (However, it tests them in "synced" form, which is why it is one cycle later).
     (READ-TEST-PAGE-FAULT
       (BLOCK 2)	;memory.cycle.permit, cache.permit, v.pg.eq.phys.pg, cache.hit
	READ-ABORT READ-ABORT READ-ABORT READ-ABORT	;all these no memory.cycle.permit
        READ-ABORT READ-ABORT READ-ABORT READ-ABORT
	READ-REQUEST-FROM-MEMORY READ-REQUEST-FROM-MEMORY  ;no cache.permit
	READ-REQUEST-FROM-MEMORY READ-REQUEST-FROM-MEMORY
	READ-TEST-2 READ-TEST-2			   ;WAIT TO CHECK CACHE
	READ-TEST-2 READ-TEST-2
	)
     
     (READ-TEST-SLOW-CACHE
       (BLOCK 2)	;memory.cycle.permit, cache.permit, v.pg.eq.phys.pg, cache.hit
	READ-ABORT READ-ABORT READ-ABORT READ-ABORT	;all these no memory.cycle.permit
        READ-ABORT READ-ABORT READ-ABORT READ-ABORT
	READ-REQUEST-FROM-MEMORY READ-REQUEST-FROM-MEMORY  ;no cache.permit
	READ-REQUEST-FROM-MEMORY READ-REQUEST-FROM-MEMORY
	READ-REQUEST-FROM-MEMORY		;Ignore v.pg.eq.phys.pg
	READ-SLOW-CACHE-HIT
	READ-REQUEST-FROM-MEMORY		;no hit
	READ-SLOW-CACHE-HIT			;!!
	)
     
     ;this block waits for mastership to be obtained
     (AWAIT-READ-CYCLE-MASTER
       (BLOCK 6)	;-BUSY, -MASTER, -MYSTRT, -MYRQST
       READ-REQUEST-STARTING READ-REQUEST-STARTING
       READ-REQUEST-FROM-MEMORY READ-REQUEST-FROM-MEMORY
       READ-REQUEST-FROM-MEMORY READ-REQUEST-FROM-MEMORY  ;no master
       READ-REQUEST-FROM-MEMORY READ-REQUEST-FROM-MEMORY  ;no master
       READ-REQUEST-STARTING READ-REQUEST-STARTING    ;same as above, busy not important here
       READ-REQUEST-FROM-MEMORY READ-REQUEST-FROM-MEMORY
       READ-REQUEST-FROM-MEMORY READ-REQUEST-FROM-MEMORY  ;no master
       READ-REQUEST-FROM-MEMORY READ-REQUEST-FROM-MEMORY  ;no master
       )
     
     ;this block waits for cycle completion once mastership has been noted
     (AWAIT-READ-CYCLE-COMPLETION
       (BLOCK 7)	;LAMBDA.DMASTER.SYNCED, NU.ACK.SYNCED, NU.TM.1.SYNCED, NU.TM.0.SYNCED
       ;master should not go away before cycle completed
       RR-HBM-ERR RR-HBM-ERR RR-HBM-ERR RR-HBM-ERR
       RR-HBM-ERR RR-HBM-ERR RR-HBM-ERR RR-HBM-ERR	;these not master now?
       READ-REQUEST-STARTED READ-BLOCK-INTERMEDIATE-ACK	;these no ACK
       READ-REQUEST-STARTED READ-BLOCK-INTERMEDIATE-ACK
       READ-REQUEST-TRY-AGAIN-LATER  READ-REQUEST-TIMEOUT
       READ-REQUEST-ERROR  READ-REQUEST-COMPLETE)

     ;THIS ONE USED ON FIRST CYCLE AFTER READ HAS STARTED. TM1 AND TM0 ARE AS SEND OUT BY US.
     (AWAIT-READ-CYCLE-COMPLETION-FIRST
       (BLOCK 7)	;LAMBDA.DMASTER.SYNCED, NU.ACK.SYNCED, NU.TM.1.SYNCED, NU.TM.0.SYNCED
       ;master should not go away before cycle completed
       RR-HBM-ERR RR-HBM-ERR RR-HBM-ERR RR-HBM-ERR
       RR-HBM-ERR RR-HBM-ERR RR-HBM-ERR RR-HBM-ERR	;these not master now?
       READ-REQUEST-STARTED READ-REQUEST-STARTED	;these no ACK
       READ-REQUEST-STARTED READ-REQUEST-STARTED
       READ-REQUEST-TRY-AGAIN-LATER  READ-REQUEST-TIMEOUT
       READ-REQUEST-ERROR  READ-REQUEST-COMPLETE)

     (TEST-WRITE-CYCLE-PERMIT
       (BLOCK 2)	;memory.cycle.permit, cache.permit, v.pg.eq.phys.pg, cache.hit
	READ-ABORT READ-ABORT READ-ABORT READ-ABORT	;all these no memory.cycle.permit
        READ-ABORT READ-ABORT READ-ABORT READ-ABORT
	WRITE-REQUEST-TO-MEMORY)

     ;this block waits for mastership to be obtained
     (AWAIT-WRITE-CYCLE-MASTER
       (BLOCK 6)	;-BUSY, -MASTER, -MYSTRT, -MYRQST
       WRITE-REQUEST-STARTING WRITE-REQUEST-STARTING
       WRITE-REQUEST-TO-MEMORY WRITE-REQUEST-TO-MEMORY
       WRITE-REQUEST-TO-MEMORY WRITE-REQUEST-TO-MEMORY
       WRITE-REQUEST-TO-MEMORY WRITE-REQUEST-TO-MEMORY
       WRITE-REQUEST-STARTING WRITE-REQUEST-STARTING
       WRITE-REQUEST-TO-MEMORY WRITE-REQUEST-TO-MEMORY
       WRITE-REQUEST-TO-MEMORY WRITE-REQUEST-TO-MEMORY
       WRITE-REQUEST-TO-MEMORY WRITE-REQUEST-TO-MEMORY)
     
     (AWAIT-WRITE-CYCLE-COMPLETION 
		;LAMBDA.DMASTER.SYNCED, NU.ACK.SYNCED, NU.TM.1.SYNCED, NU.TM.0.SYNCED
       (BLOCK 7)
       WR-HBM-ERR WR-HBM-ERR WR-HBM-ERR WR-HBM-ERR
       WR-HBM-ERR WR-HBM-ERR WR-HBM-ERR WR-HBM-ERR
       WRITE-REQUEST-STARTED WRITE-REQUEST-STARTED	;no ACK
       WRITE-REQUEST-STARTED WRITE-REQUEST-STARTED
       WRITE-REQUEST-TRY-AGAIN-LATER WRITE-REQUEST-TIMEOUT
       WRITE-REQUEST-ERROR WRITE-REQUEST-COMPLETE)       

     (cache-validation-error	;this symbol is specially known by the assembler/loaded.
       (csm.verify.error.bit 1  ;codewords in the other image which are supposedly 
	csm.error.bit 1)	;transfer here.
       cache-validation-error)

     (READ-REQUEST		;This happens during execute cycle of CALL-CONDITIONAL.
       (CSM.VIRTUAL.PAGE.GROUP 0  ;Level 2 map first available just before end of this cycle. 
  	CSM.CACHE.HIT.ENABLE 0
	CSM.CACHE.MODE 0
	CSM.MEMORY.CYCLE.ENDING-L 1
	CSM.REQUEST.NOTED-L 1)
       READ-TEST-1	;GENERATE CACHE.HIT, WHICH GETS STROBED INTO CACHE.HIT.SYNCED
        T)		; THIS CYCLE NECESSARY ONLY FOR CACHE TEST.
     
     (READ-TEST-1		;This happens during source cycle of ((..) MD) in case
       (			; of immediate use of memory data.
	CSM.VIRTUAL.PAGE.GROUP 0 
	CSM.CACHE.HIT.ENABLE 0   
	CSM.CACHE.MODE 1
	CSM.MEMORY.CYCLE.ENDING-L 1
	CSM.REQUEST.NOTED-L 1)
        READ-TEST-PAGE-FAULT
       T)
     
     (READ-TEST-2
       (		
	CSM.VIRTUAL.PAGE.GROUP 0 
	CSM.CACHE.HIT.ENABLE 1
	CSM.CACHE.MODE 1
	CSM.MEMORY.CYCLE.ENDING-L 1
	CSM.REQUEST.NOTED-L 1)
       READ-TEST-SLOW-CACHE
       T)
     (READ-ABORT
       (CSM.REQUEST.NOTED-L 0
	CSM.MEMORY.CYCLE.ENDING-L 0)
       READ-ABORT-1
       T)
     
     (READ-ABORT-1
       ()
       AWAIT-REQUEST
       T)
       
     (READ-SLOW-CACHE-HIT
       (CSM.CACHE.HIT.BIT 1		;pseudo
	CSM.SLOW.CACHE.HIT.BIT 1	;pseudo
	CSM.CACHE.HIT.ENABLE 0
	CSM.VIRTUAL.PAGE.GROUP 0
	CSM.REQUEST.NOTED-L 0		;acknowledge cache request.
	CSM.CACHE.MODE 0		;SEE COMMENT ON READ-FAST-CACHE-HIT.
	CSM.MEMORY.CYCLE.ENDING-L 0)
       READ-SLOW-CACHE-HIT-EXIT-1
       T)
     
     (READ-SLOW-CACHE-HIT-EXIT-1	;DELAY TO AVOID RETRIGGERING ON SAME REQUEST
       ()
       AWAIT-REQUEST
       T)

  ;main memory read stuff 
     (READ-REQUEST-FROM-MEMORY
       (CSM.REQUESTING.NUBUS.BIT 1	;PSEUDO
	CSM.TESTING.MASTERSHIP.BIT 1	;PSEUDO
	CSM.LAMBDA.STREQ 1
	CSM.LAMBDA.BREQ 1
	CSM.RD.DATA.TO.NUDATA.BUS 1
	CSM.MEMORY.CYCLE.ENDING-L 1
	CSM.REQUEST.NOTED-L 1)
       AWAIT-READ-CYCLE-MASTER
       T)
     (READ-REQUEST-STARTING
       (CSM.CYCLE.STARTING.BIT 1	;PSEUDO
	csm.test.completion.bit 1	;PSEUDO
	CSM.RD.DATA.TO.NUDATA.BUS 1
	CSM.REQUEST.NOTED-L 0		;acknowledge cache.request
	CSM.VIRTUAL.PAGE.GROUP 0
	CSM.CACHE.MODE 2		;WRITE CACHE IF NU XFER OCCURS
	CSM.MEMORY.CYCLE.ENDING-L 1)
       AWAIT-READ-CYCLE-COMPLETION-FIRST
       NIL)
     (READ-REQUEST-STARTED
       (csm.test.completion.bit	1	;pseudo
	csm.await.completion.bit 1	;pseudo
	CSM.RD.DATA.TO.NUDATA.BUS 1
	CSM.MEMORY.CYCLE.ENDING-L 1
	CSM.VIRTUAL.PAGE.GROUP 0
	CSM.CACHE.MODE 2		;WRITE CACHE IF NU XFER OCCURS
	csm.cache.adr.from.NUADR 1  	;address comes from frob within block if write.
	CSM.REQUEST.NOTED-L 1)
       AWAIT-READ-CYCLE-COMPLETION
       T)		;***
     (READ-REQUEST-FAILED-TO-START
       (CSM.MEMORY.CYCLE.ENDING-L 0
	csm.error.bit 1)
       READ-REQUEST-FAILED-TO-START)
     
     (READ-REQUEST-TRY-AGAIN-LATER	;SORT OF AN IDLE CYCLE, THEN TRY AGAIN.
       (CSM.MEMORY.CYCLE.ENDING-L 1
	CSM.REQUEST.NOTED-L 1)
       READ-REQUEST-FROM-MEMORY
       T)
     
     (READ-REQUEST-TIMEOUT
        (CSM.MEMORY.CYCLE.ENDING-L 0
 	csm.error.bit 1)
        READ-REQUEST-TIMEOUT)
     
     (READ-REQUEST-ERROR		;error signal received on NUBUS
       (CSM.MEMORY.CYCLE.ENDING-L 0
	csm.error.bit 1)
       READ-REQUEST-ERROR)
     
  ;ANYBODY WHO CAN GET HERE SHOULD ASSERT CSM.CACHE.MODE 2 SO CACHE GETS WRITTEN ON SAME
  ; CYCLE AS WE GET HERE. 
     (READ-REQUEST-COMPLETE
       (		;write data in cache..
	CSM.CYCLE.COMPLETE.BIT 1	;pseudo
	;CSM.CACHE.MODE 2		;write on NU xfer NOPE, TOO LATE
	CSM.MEMORY.CYCLE.ENDING-L 0
	CSM.RD.DATA.TO.NUDATA.BUS 1)
       AWAIT-REQUEST
       T)
     
     (READ-BLOCK-INTERMEDIATE-ACK
       (		;write data in cache..
	csm.test.completion.bit 1	;pseudo
	CSM.CACHE.MODE 2		;write on NU xfer (this would apply if next world of
					; block comes on next cycle)
	csm.cache.adr.from.NUADR 1
	CSM.VIRTUAL.PAGE.GROUP 0
	CSM.RD.DATA.TO.NUDATA.BUS 1
	CSM.MEMORY.CYCLE.ENDING-L 1
	CSM.REQUEST.NOTED-L 1
	csm.count.nuadr 1
	)
       AWAIT-READ-CYCLE-COMPLETION
       NIL)
     
     (RR-HBM-ERR			;master went away before ACK.
       (CSM.MEMORY.CYCLE.ENDING-L 0
	csm.error.bit 1)
       RR-HBM-ERR)

     (WRITE-REQUEST-TO-MEMORY-0
       (CSM.MD.TO.NUDATA.BUS 1
	CSM.MEMORY.CYCLE.ENDING-L 1
	CSM.REQUEST.NOTED-L 1)
       TEST-WRITE-CYCLE-PERMIT
       T)
     
     (WRITE-REQUEST-TO-MEMORY
       (CSM.REQUESTING.NUBUS.BIT 1	;PSEUDO
	CSM.TESTING.MASTERSHIP.BIT 1	;PSEUDO
	CSM.LAMBDA.STREQ 1
	CSM.LAMBDA.BREQ 1
	CSM.MD.TO.NUDATA.BUS 1
	CSM.MEMORY.CYCLE.ENDING-L 1
	CSM.REQUEST.NOTED-L 1)
       AWAIT-WRITE-CYCLE-MASTER
       T)
     
     (WRITE-REQUEST-STARTING
       (CSM.CYCLE.STARTING.BIT 1
	CSM.MD.TO.NUDATA.BUS 1
   	CSM.MEMORY.CYCLE.ENDING-L 1
	CSM.REQUEST.NOTED-L 1
	)
       AWAIT-WRITE-CYCLE-COMPLETION-1
       NIL)
     
     (AWAIT-WRITE-CYCLE-COMPLETION-1	;first cycle waiting for completion
       (csm.test.completion.bit 1	;pseudo
	CSM.MD.TO.NUDATA.BUS 1
	CSM.REQUEST.NOTED-L 0		;ack cache.request
	CSM.MEMORY.CYCLE.ENDING-L 1
	CSM.VIRTUAL.PAGE.GROUP 0
	CSM.CACHE.MODE 2)
       AWAIT-WRITE-CYCLE-COMPLETION
       NIL)
     
     (WRITE-REQUEST-STARTED		;rest of cycles waiting for completion
       (csm.test.completion.bit 1	;pseudo
	csm.await.completion.bit 1	;pseudo
	CSM.MD.TO.NUDATA.BUS 1
	CSM.MEMORY.CYCLE.ENDING-L 1
	CSM.VIRTUAL.PAGE.GROUP 0
	CSM.CACHE.MODE 2)
       AWAIT-WRITE-CYCLE-COMPLETION
       T)
     
     (WRITE-REQUEST-FAILED-TO-START
       (CSM.MEMORY.CYCLE.ENDING-L 0
	csm.error.bit 1)
       WRITE-REQUEST-FAILED-TO-START)
     
     (WRITE-REQUEST-TRY-AGAIN-LATER
       (CSM.MEMORY.CYCLE.ENDING-L 1
	CSM.REQUEST.NOTED-L 1)
       WRITE-REQUEST-TO-MEMORY
       T)
     
     (WRITE-REQUEST-TIMEOUT
       (CSM.MEMORY.CYCLE.ENDING-L 0
	csm.error.bit 1)
       WRITE-REQUEST-TIMEOUT)
     
     (WRITE-REQUEST-ERROR	       ;error reply received on NUBUS
       (CSM.MEMORY.CYCLE.ENDING-L 0
	csm.error.bit 1)
       WRITE-REQUEST-ERROR)
     
   ;CACHE IS WRITTEN ON CYCLE FOLLOWING RECEIPT OF ACK.  THUS ANYBODY WHO CAN GET HERE
   ; SHOULD ASSERT  CSM.CACHE.MODE 2
     (WRITE-REQUEST-COMPLETE
       (CSM.CYCLE.COMPLETE.BIT 1	;pseudo
	CSM.MEMORY.CYCLE.ENDING-L 0
	CSM.REQUEST.NOTED-L 1
	CSM.MD.TO.NUDATA.BUS 1)
       AWAIT-REQUEST
       T)
     
     (WR-HBM-ERR			;master went away before ACK.
       (CSM.MEMORY.CYCLE.ENDING-L 0	;AVOID HANGING WORLD
	csm.error.bit 1)
       WR-HBM-ERR)
 ))

(defconst cache-validate-subroutine '(  ;NOTE: CODE BELOW ASSUMES THIS TWO WORDS LONG.
      (csm.cache.mode 1
       csm.cache.adr.from.NUADR 1
       csm.virtual.page.group 0
       csm.verify.bit 1
       )
      (csm.cache.mode 3
       csm.cache.adr.from.NUADR 1
       csm.virtual.page.group 0
       )))

;CSM sensing of NUBUS:
;  example(), already NUBUS master, write cycle
;		   codeword in CSMREG.
;		     idle-test				test AWAIT-REQUEST
;cache.request, memory.write.cycle asserted
;		     write-request-to-memory-0
;						        test WRITE-CYCLE-PERMIT

;		     write-request-to-memory(0)
;  			assert STREQ, BREQ              test AWAIT-WRITE-CYCLE-MASTER
; if NO master, loop at write-request-to-memory

;-start asserted     write-request-to-memory(1)
;  on NUBUS--		hold STREQ, BREQ		test AWAIT-WRITE-CYCLE-MASTER

;-data first 	     write-request-starting
;  asserted on NUBUS

;-ACK may come back  write-cycle-completion-1
;					                test AWAIT-WRITE-CYCLE-COMPLETION
; if NO completion, do WRITE-REQUEST-STARTED, or maybe WRITE-REQUEST-TRY-AGAIN
;		     	or WRITE-REQUEST-TIMEOUT, WRITE-REQUEST-ERROR, or ...

;-XFER last cycle    WRITE-REQUEST-STARTED
;   asserted						test AWAIT-WRITE-CYCLE-COMPLETION
;  cache written
;		     WRITE-REQUEST-COMPLETE
;							test AWAIT-REQUEST

;(W0) sampletime.   csm.breq and csm.streq asserted.
;	 CSM codeword:  WRITE-REQUEST-TO-MEMORY   test: AWAIT-WRITE-CYCLE-MASTER
;(W0) drivetime.
; ASSUMING MASTERSHIP IMMEDIATELY AVAILABLE
;(W1) sampletime.   strobbed into PAL.  decides to take start cycle.  PAL outputs drive
;		     CSM condition inputs.
;(W1) drivetime.   PAL outputs transferred to quad latch. begin to drive NUBUS with start.
;(W2) sampletime.   CSM codeword fetched which reflects bus when start was asserted.
;(W3) 
;(W4)
;(W5)


;the cache validation feature:
;  the high bit of the CSM address comes from NUBUS.WRITE.STARTING L, which is the
;NAND of -LAMBDA.DMASTER.SYNCED, NU.TM.1.SYNCED, NU.START.SYNCED, AND -NU.ACK.SYNCED.
;Thus, if a write cycle starts on the bus when we are not master, NUBUS.WRITE.STARTING L
;will assert.  The address gets captured in the NUADR register (since that loads
;on every NUBUS address.sampletime.)  The timing looks like this:

;S0							(start cycle on bus)
;C0	start synced, NUADRnn strobed
;S1     random codeword RC1 strobed
;	CSMRAM accesses   				(write data on bus)
;C1	validation test codeword strobed into CSMREG
;S2     CACHE.read to test for data going stale		(ACK traveling back on bus)
;C2	validation correct codeword strobed into CSMREG
;	CACHE.hit strobed into CACHE.hit.synced
;S3     CACHE.write to invalidate stale data		(soonest possible next start cycle.)
;	 (if CACHE.hit.synced)
;C3	soonest time NUADR could be restrobed.  This clock would be C0 for following write
;	       cycle.  Codeword which normally follows RC1 strobed.

;(key locn <rest of statement>)
(DEFCONST *CSM-ALIST* NIL)
(defvar *csm-main-block-locn*)  ;highest CSM adr used for main block.  Above here used
				; for calls on validate "subroutine".
(defvar *csm-validate-locn-pointer*)  ;Points to free location available for storage of
				;call on validate "subroutine".

;CSM words which supposedly cant be reached are filled with CACHE-VALIDATE-ERROR-WORD.
; The address is set to transfer to CACHE-VALIDATE-ERROR in the main image.

(defvar csmram-array (make-array 4096.))

(defun write-csmram-array (adr data)
  (aset (compute-parity-32 data) csmram-array adr))

(DEFUN LOAD-CSM-TO-ARRAY ()
  (load-csm ':fctn 'write-csmram-array))

(defun write-current-csmram-to-file ()
  (LOAD-CSM-TO-ARRAY)
  (with-open-file (standard-output "SYS:lambda-ucode;ulambda-csmram lisp" ':write)
    (format t ";;;-*- Mode:LISP; Package:LAMBDA; Base:16.;readtable:zl -*-")
    (let ((spy-file-info
	    (COND ((< (SI:GET-SYSTEM-VERSION) 98.)
		   (cadar (get (si:get-source-file-name 'load-csm)
			       ':file-id-package-alist)))
		  (T (CONS (GET (SI:GET-SOURCE-FILE-NAME 'LOAD-CSM)
				':QFASL-SOURCE-FILE-UNIQUE-ID)
			   (THIRD (get (si:get-source-file-name 'load-csm)
				       ':COMPILE-DATA)))))))
      (format t "~&;;; LAMBDA CSMRAM PROGRAM")
      (format t "~&;;; From file ~S (created ~\time\)"
	      (car spy-file-info) (cdr spy-file-info))
      (format t "~&;;; This file created ~\datime\ by ~A" user-id))
    (format t "~&(setq csm-ram-list '(")
    (let ((zero-with-parity (compute-parity-32 0)))
      (dotimes (adr 10000)
	(format t "~&0~16r" (or (aref csmram-array adr) zero-with-parity))))
    (format t "~&))~&")
    (send standard-output ':truename)))

;overwrite the "compiled" SDU csmram file with the in-core csmram array.
;write the "normal" c.csmram file or the "fast-cache" c.fcsmram file.
;
(defun write-current-csmram-to-local-sdu-file (&optional fast-cache-file-p)
  (let ((csm-8b (make-array 16384. :type :art-8b))
	(zero-with-parity (compute-parity-32 0)))
    (do ((i 0 (1+ i)))
	((= i 16384.))
      (setf (aref csm-8b i)
	    (ldb (byte 8 (* 8 (logand i 3)))
		 (or (aref csmram-array (ash i -2)) zero-with-parity))))
    (sdu:overwrite-unix-file (if fast-cache-file-p
				 "//disk//lambda//c.fcsmram"
			       "//disk//lambda//c.csmram")
			     csm-8b)
    ))

;return an 8b array containing the csmram or fast-cache csmram
;from the local sdu file.
(defun read-csmram-from-local-sdu-file (&optional fast-cache-file-p)
  (let ((csm-8b (make-array 16384. :type :art-8b))
	(filename (if fast-cache-file-p "//disk//lambda//c.fcsmram" "//disk//lambda//c.csmram")))
    (setq sdu:temp-file (sdu:init-unix-file sdu:temp-file))
    (sdu:rw-file :read (sdu:open-unix-file filename sdu:temp-file) csm-8b 16384.)
    csm-8b))

;read the csmram from the local sdu file
;and compare it with the in-core csmram array.
;return number of <bytes> that differ.
(defun compare-csmram-with-local-sdu-file (&optional fast-cache-file-p)
  (let ((csm-8b (read-csmram-from-local-sdu-file fast-cache-file-p))
	(zero-with-parity (compute-parity-32 0)))
    (do ((i 0 (1+ i))
	 (diffs 0))
	((= i 16384.)
	 diffs)
      (when (neq (aref csm-8b i)
		 (ldb (byte 8 (* 8 (logand i 3)))
		      (or (aref csmram-array (ash i -2)) zero-with-parity)))
	(incf diffs))
      )))

;write a file containing the csmram in the SDU "compiled" format.
;use to write to a normal file server, as opposed to the local SDU file.
(defun write-current-csmram-to-BINARY-file (FILE)
  (LOAD-CSM-TO-ARRAY)
  (with-open-file (standard-output FILE :write)
    (let ((zero-with-parity (compute-parity-32 0)))
      (dotimes (adr 10000)
	(WRITE-BYTE (LDB (BYTE 8. 0.) (or (aref csmram-array adr) zero-with-parity)))
	(WRITE-BYTE (LDB (BYTE 8. 8.) (or (aref csmram-array adr) zero-with-parity)))
	(WRITE-BYTE (LDB (BYTE 8. 16.) (or (aref csmram-array adr) zero-with-parity)))
	(WRITE-BYTE (LDB (BYTE 8. 24.) (or (aref csmram-array adr) zero-with-parity)))))))



(DEFUN READ-CSM-AND-CHECK (ADR DATA &aux csm-data)
  (setq data (compute-parity-32 data))
  (cond (( (setq csm-data (READ-CSM ADR)) DATA)
	 (format T "~%Bad data in csm at address ~o : expected ~o but found ~o, dfrs "
		 adr data (read-csm adr))
	 (print-bits (logxor csm-data data))))) 

(DEFUN WRITE-CSM-AND-PRINT (ADR DATA)
  (FORMAT T "~%ADR:~s" ADR)
  (PRINT-CSMRAM-CODEWORD DATA)
  (WRITE-CSM-WITH-PARITY ADR DATA))

(defun write-csm-with-parity (adr data)
  (write-csm adr (compute-parity-32 data)))

;the high bit of the CSM address comes from "not (foreign write cycle starting
; on NUBUS)".  Thus, it is normally asserted and the "normal" CSM image is actually the
; high half of the CSM memory.  For each codeword in the normal (high) half, there is
; a corresponding codeword which gets accessed if a foreigh NUBUS memory write
; cycle flies past just then.  In some cases, this is an error, because executing that
; codeword is supposed to imply we have NUBUS mastership.  Otherwise, the mirror location
; contains an entry to the "verify subroutine".   This subroutine is open coded at each
; use, and exits back to the original codeword.

(defun lam-reset-cache nil
  (WRITE-CSM-REG-VIA-CSMRAM (compute-parity-32 0)))

(DEFVAR *NO-VERIFY-ERRORS*)

(DEFUN LOAD-CSM (&KEY &OPTIONAL
		 (PRGM SIMPLE-CSM)
		 (FCTN 'WRITE-CSM-WITH-PARITY)
		 (STATISTICS-BIT-OPTION 'csm.cache.hit.bit)
		 (PRINT NIL)
		 (CHECK NIL)
		 (*NO-VERIFY-ERRORS* t))
  (cond ((not (memq statistics-bit-option csm.pseudo.bits))
	 (ferror nil "statistics bit option unknown")))
  (COND ((ACCESS-PATH-LMI-SERIAL-PROTOCOL *PROC*)
	 (FORMAT TERMINAL-IO "Telling SDU to load CSM")
	 (FORMAT *PROC* "ALoading CSM~%")
	 (FUNCALL *PROC* ':STRING-OUT "1c")
	 (FUNCALL *PROC* ':READ-32))
	(T
	 (cond ((null PRINT))
	       ((eq fctn 'write-csm-with-parity)
		(setq fctn 'write-csm-and-print)))
	 (cond ((null CHECK))
	       ((eq fctn 'write-csm-with-parity)
		(setq fctn 'read-csm-and-check)))
	 (LET ((LOCN 20)	;Dont use block 0 because initialization entry there.
	       (BLOCK-LOC-BOUNDARY NIL)
	       (*CSM-STATISTICS-BIT-OPTION* STATISTICS-BIT-OPTION))
	   (SETQ *CSM-ALIST* NIL)
	   (DOLIST (S PRGM)
	     (COND ((EQ (CAR (CADR S)) 'BLOCK)
		    (SETQ *CSM-ALIST*
			  (CONS (LIST* (CAR S) LOCN (CDR S))
				*CSM-ALIST*))
		    (SETQ LOCN (+ LOCN 20)))
		   (T
		    (SETQ *CSM-ALIST*
			  (CONS (LIST* (CAR S) NIL (CDR S))
				*CSM-ALIST*)))))
	   (SETQ BLOCK-LOC-BOUNDARY LOCN)
	   (DOLIST (A-L *CSM-ALIST*)		;assign primary locns to statements
	     (COND ((NULL (CADR A-L))
		    (RPLACA (CDR A-L)
			    (COND ((EQ (CAR A-L) 'IDLE-TEST) 0)	;special case, crock crock.
				  ((CSM-FIND-LOC (CAR A-L)))	;if stored as part of block.
				  (T (PROG1 LOCN (SETQ LOCN (1+ LOCN)))))))))
	   (setq *csm-main-block-locn* locn
		 *csm-validate-locn-pointer* *csm-main-block-locn*)	   
	   (DOLIST (S PRGM)
	     (LET* ((A-L (ASSQ (CAR S) *CSM-ALIST*))
		    (LOCN (CADR A-L)))
	       (COND ((EQ (CAR (CADR S)) 'BLOCK)
		      (CSM-STORE-BLOCK FCTN LOCN (CDDR S)))
		     (T
		      (COND ((OR (< LOCN 20)
				 (NOT (< LOCN BLOCK-LOC-BOUNDARY)))
			     (CSM-STORE-WORD FCTN LOCN (CDR S))))))))
	   ))))

(DEFUN CSM-FIND-LOC (SYM &AUX TEM)
  (DOLIST (A-L *CSM-ALIST*)
    (COND ((EQ (CAR (CADDR A-L)) 'BLOCK)
	   (COND ((SETQ TEM (FIND-POSITION-IN-LIST SYM (CDDDR A-L)))
		  (RETURN (+ TEM (CADR A-L)))))))))

(DEFUN CSM-STORE-BLOCK (FCTN LOCN STATEMENT-LIST)
  (DOTIMES (REL-ADR 20)
    (LET ((S (ASSQ (CAR STATEMENT-LIST) *CSM-ALIST*)))
      (COND ((EQ (CAR STATEMENT-LIST) 'ERROR)
	     (CSM-STORE-ERROR FCTN (+ LOCN REL-ADR)))
	    ((NULL S)
	     (FERROR NIL "~%~s is an undefined statement" (CAR STATEMENT-LIST)))
	    (T (CSM-STORE-WORD FCTN (+ LOCN REL-ADR) (CDDR S))))
      (IF (CDR STATEMENT-LIST)
	  (SETQ STATEMENT-LIST (CDR STATEMENT-LIST))))))

(DEFUN CSM-STORE-WORD (FCTN LOCN STATEMENT)
  (LET ((WORD (CAR STATEMENT))
	(NEXT (CADR STATEMENT))
	(XFER-TO-IMAGE-ALLOWABLE (CADDR STATEMENT)))
    (FUNCALL FCTN		;"NORMAL" IMAGE
	     (+ 4000 LOCN)
	     (+ (CSM-EVAL-WORD WORD)
		(CSM-EVAL-NEXT NEXT)))
    (FUNCALL FCTN		;FOREIGN MEMORY WRITE STARTING IMAGE.
	     LOCN
	     (IF (OR XFER-TO-IMAGE-ALLOWABLE *NO-VERIFY-ERRORS*)
		 (CSM-CALL-CACHE-VALIDATE-SUBROUTINE FCTN STATEMENT LOCN)
	       (CSM-CACHE-VALIDATE-ERROR-CODEWORD)))
    ))

(DEFUN CSM-CACHE-VALIDATE-ERROR-CODEWORD ()
  (+ (CSM-EVAL-WORD '(CSM.VERIFY.ERROR.BIT 1
		      CSM.ERROR.BIT 1))
     (CSM-EVAL-NEXT 'CACHE-VALIDATION-ERROR)))

(DEFUN CSM-CALL-CACHE-VALIDATE-SUBROUTINE (FCTN STATEMENT LOCN)
  ;FOR NOW, STORE A SEPARATE COPY OF SUBROUINE FOR EACH LOCN ITS CALLED FROM.
  ; IT COULD STORE ONLY ONE COPY PER STATEMENT ITS CALLED FROM.
  STATEMENT	;NOT USED FOR NOW.
   ;switch back to main image for second word of subr
  (FUNCALL FCTN (+ 4000 *CSM-VALIDATE-LOCN-POINTER*)
	   (+ (CSM-EVAL-WORD (CADR CACHE-VALIDATE-SUBROUTINE))  ;2ND WORD OF SUBR
	      LOCN))   ;"return" to caller
  (FUNCALL FCTN *CSM-VALIDATE-LOCN-POINTER*    ;should not start another one..
	   (CSM-CACHE-VALIDATE-ERROR-CODEWORD))
		   
  (PROG1 (+ (CSM-EVAL-WORD (CAR CACHE-VALIDATE-SUBROUTINE))
	    *CSM-VALIDATE-LOCN-POINTER*)
	 (SETQ *CSM-VALIDATE-LOCN-POINTER* (1+ *CSM-VALIDATE-LOCN-POINTER*)))
  )

(DEFUN CSM-EVAL-WORD (FIELD-VALUE-LIST
		      &OPTIONAL
		      (VALUE-SO-FAR 0)
		      (DEFAULT-HIGH-LIST CSM.LOW.ASSERTED.BITS))
  (PROG (TEM FIELD VALUE)
	(SETQ TEM FIELD-VALUE-LIST)
   L    (COND ((NULL TEM)
	       (GO DEFAULT)))
	(SETQ FIELD (FIRST TEM)
	      VALUE (SECOND TEM))
	(COND ((MEMQ FIELD CSM.PSEUDO.BITS)
	       (COND ((EQ FIELD *CSM-STATISTICS-BIT-OPTION*)
		      (SETQ FIELD CSM.STATISTICS.BIT))
		     (T (GO N)))))	;IGNORE THIS ONE, ITS NOT SELECTED.
        (SETQ VALUE-SO-FAR
	      (DPB (EVAL VALUE) (EVAL FIELD) VALUE-SO-FAR))
   N	(SETQ TEM (CDDR TEM))
	(GO L)
  DEFAULT
	(COND ((NULL DEFAULT-HIGH-LIST)
	       (RETURN VALUE-SO-FAR))
	      ((NULL (GET (LOCF FIELD-VALUE-LIST) (CAR DEFAULT-HIGH-LIST)))
	       (SETQ VALUE-SO-FAR
		     (DPB 1 (SYMEVAL (CAR DEFAULT-HIGH-LIST)) VALUE-SO-FAR))))
	(SETQ DEFAULT-HIGH-LIST (CDR DEFAULT-HIGH-LIST))
	(GO DEFAULT)))

(DEFUN CSM-STORE-ERROR (FCTN LOCN)
  (FUNCALL FCTN LOCN (+ LOCN (CSM-EVAL-WORD NIL))))

(DEFUN CSM-EVAL-NEXT (NEXT)
  (LET ((A-L (ASSQ NEXT *CSM-ALIST*)))
    (IF (NULL A-L) (FERROR NIL "~%the symbol ~s is undefined" NEXT))
    (COND ((EQ (CAR (CADDR A-L)) 'BLOCK)
	   (CSM-EVAL-WORD `(CSM.CONDITION ,(CADR (CADDR A-L))
			    CSM.STATE ,(CADR A-L))
			  0
			  NIL))
	  (T (CSM-EVAL-WORD `(CSM.STATE ,(CADR A-L))
			    0
			    NIL)))))

(DEFUN CSM-SYMBOLIC-LOCATION (ADR)
  (DOLIST (A-L *CSM-ALIST*)
    (COND ((EQ (FIRST (THIRD A-L)) 'BLOCK)
	   (COND ((= (LOGAND ADR 7760) (SECOND A-L))
		  (RETURN `(BLOCK ,(FIRST A-L) (,(NTH (LOGAND ADR 17) (CDDDR A-L))))))))
	  ((= ADR (CADR A-L))
	   (RETURN (CAR A-L))))))

(DEFCONST CSM.BRANCH.TESTS
 '(  ()						;0 selects bits from state.sequence
     (MEMORY.WRITE.CYCLE CACHE.REQUEST 0 0)	;1
     (CACHE.HIT V.PG.EQ.PHYS.PG CACHE.PERMIT MEMORY.CYCLE.PERMIT) ;2
     ()		;3
     ()		;4
     (-END.OF.TRANSFER)		;5
     ()		;6
     (NU.TM.0 NU.TM.1 NU.ACK LAMBDA.DMASTER)))	;7

;each block consists of 16 CSM locations.  Has a symbolic name, an octal address,
; a branch-test-number and a list of following states.


;CSM blocks:
;  AWAIT-REQUEST.  select-condition 1.  
;    goes to:   cache-read-request on cache-request and not memory.write.cycle
;		cache-write-request on cache-request and memory.write.cycle.
;	plus (in future)  cache validate request from NUBUS.

;  READ-REQUEST-FROM-MEMORY.
;    request NUBUS

;  AWAIT-NUBUS.   select-condition 7.
;	
;  READ-REQUEST-START-CYCLE

;  AWAIT-READ-DATA.  select-condition 7.

;  reply to machine.


(DEFUN WRITE-VMA-START-READ-STEPPING (DATA)
  (WRITE-SPY-REG-AND-CHECK DATA)
  (LAM-EXECUTE (EXECUTOR LAM-EXECUTE-NOCLOCKS)
	       LAM-IR-OP LAM-OP-ALU
	       LAM-IR-OB LAM-OB-ALU
	       LAM-IR-M-SRC lam-m-src-spy-reg
	       LAM-IR-FUNC-DEST LAM-FUNC-DEST-VMA-START-READ
	       LAM-IR-ALUF LAM-ALU-SETM)
  (WRITE-CSM-REG-FROM-CSMRAM 0)			;start off at 0
 ;  (SM-STEP-LOOP ':CSM-PRINTOUT T)
  )

;this one just replies immediately.  Tries no memory cycles to avoid hanging machine
; when stepping.  Always aborts, simulating page fault.  Otherwise as close as possible
; to normal.
;--this one is now somewhat out of date versus the real thing.. it should still serve
; its purpose tho.
(DEFCONST FAKE-CSM
 '(  ;Note!! IDLE-TEST must be at 0 so CSM can be started there and initialize right!
     (IDLE-TEST (CSM.NU.IDLE 1
		 CSM.MEMORY.CYCLE.ENDING-L 1
		 CSM.REQUEST.NOTED-L 1)
		AWAIT-REQUEST)

     (AWAIT-REQUEST
       (BLOCK 1)	;GND, -DEBUG.CLOCK.MODE.SYNCED, CACHE.REQUEST L, MEMORY.WRITE.CYCLE
       read-request write-request-to-memory-0 idle-test idle-test
		;this one goes ahead even in debug.clock mode.
		;regular load waits if debug.clock mode
       READ-REQUEST WRITE-REQUEST-TO-MEMORY-0 IDLE-TEST IDLE-TEST ERROR)
     ;this block used by READ-TEST-1.  It tests conditions set up at end of READ.REQUEST,
     ; which corresponds to the end of the first execute cycle of the CALL-CONDITIONAL.
     ; (However, it tests them in "synced" form, which is why it is one cycle later).
     (READ-TEST-FAST-CACHE
       (BLOCK 2)	;memory.cycle.permit, cache.permit, v.pg.eq.phys.pg, cache.hit
	READ-ABORT READ-ABORT READ-ABORT READ-ABORT	;all these no memory.cycle.permit
        READ-ABORT READ-ABORT READ-ABORT READ-ABORT
 ;read-abort always
 ;	READ-REQUEST-FROM-MEMORY READ-REQUEST-FROM-MEMORY  ;no cache.permit
 ;	READ-REQUEST-FROM-MEMORY READ-REQUEST-FROM-MEMORY
 ;	READ-REQUEST-FROM-MEMORY READ-REQUEST-FROM-MEMORY  ;could try for slow.hit
 ;	READ-REQUEST-FROM-MEMORY		;no hit
 ;	READ-FAST-CACHE-HIT			;!!
	)
     ;this block waits for mastership to be obtained
     (AWAIT-READ-CYCLE-MASTER
       (BLOCK 6)	;-BUSY, -MASTER, -MYSTRT, -MYRQST
       READ-REQUEST-STARTING READ-REQUEST-STARTING
       READ-REQUEST-FROM-MEMORY READ-REQUEST-FROM-MEMORY
  ;       READ-REQUEST-FAILED-TO-START READ-REQUEST-FAILED-TO-START
       READ-REQUEST-FROM-MEMORY READ-REQUEST-FROM-MEMORY  ;no master
       READ-REQUEST-FROM-MEMORY READ-REQUEST-FROM-MEMORY  ;no master
       READ-REQUEST-STARTING READ-REQUEST-STARTING    ;same as above, busy not important here
       READ-REQUEST-FROM-MEMORY READ-REQUEST-FROM-MEMORY
  ;       READ-REQUEST-FAILED-TO-START READ-REQUEST-FAILED-TO-START 
       READ-REQUEST-FROM-MEMORY READ-REQUEST-FROM-MEMORY  ;no master
       READ-REQUEST-FROM-MEMORY READ-REQUEST-FROM-MEMORY  ;no master
       )
     ;this block waits for cycle completion once mastership has been noted
     (AWAIT-READ-CYCLE-COMPLETION
       (BLOCK 7)	;LAMBDA.DMASTER.SYNCED, NU.ACK.SYNCED, NU.TM.1.SYNCED, NU.TM.0.SYNCED
       ;master should not go away before cycle completed
       RR-HBM-ERR RR-HBM-ERR RR-HBM-ERR RR-HBM-ERR
       RR-HBM-ERR RR-HBM-ERR RR-HBM-ERR RR-HBM-ERR	;these not master now?
       READ-REQUEST-STARTED READ-BLOCK-INTERMEDIATE-ACK	;these no ACK
       READ-REQUEST-STARTED READ-BLOCK-INTERMEDIATE-ACK
       READ-REQUEST-TRY-AGAIN-LATER  READ-REQUEST-TIMEOUT
       READ-REQUEST-ERROR  READ-REQUEST-COMPLETE)

     (TEST-WRITE-CYCLE-PERMIT
       (BLOCK 2)	;memory.cycle.permit, cache.permit, v.pg.eq.phys.pg, cache.hit
	READ-ABORT READ-ABORT READ-ABORT READ-ABORT	;all these no memory.cycle.permit
        READ-ABORT READ-ABORT READ-ABORT READ-ABORT
  ;always ABORT.
  ;	WRITE-REQUEST-TO-MEMORY
	)

     ;this block waits for mastership to be obtained
     (AWAIT-WRITE-CYCLE-MASTER
       (BLOCK 6)	;-BUSY, -MASTER, -MYSTRT, -MYRQST
       WRITE-REQUEST-STARTING WRITE-REQUEST-STARTING
       WRITE-REQUEST-TO-MEMORY WRITE-REQUEST-TO-MEMORY
  ;       WRITE-REQUEST-FAILED-TO-START WRITE-REQUEST-FAILED-TO-START
       WRITE-REQUEST-TO-MEMORY WRITE-REQUEST-TO-MEMORY
       WRITE-REQUEST-TO-MEMORY WRITE-REQUEST-TO-MEMORY
       WRITE-REQUEST-STARTING WRITE-REQUEST-STARTING
       WRITE-REQUEST-TO-MEMORY WRITE-REQUEST-TO-MEMORY
  ;       WRITE-REQUEST-FAILED-TO-START WRITE-REQUEST-FAILED-TO-START
       WRITE-REQUEST-TO-MEMORY WRITE-REQUEST-TO-MEMORY
       WRITE-REQUEST-TO-MEMORY WRITE-REQUEST-TO-MEMORY)
     (AWAIT-WRITE-CYCLE-COMPLETION 
		;LAMBDA.DMASTER.SYNCED, NU.ACK.SYNCED, NU.TM.1.SYNCED, NU.TM.0.SYNCED
       (BLOCK 7)
       WR-HBM-ERR WR-HBM-ERR WR-HBM-ERR WR-HBM-ERR
       WR-HBM-ERR WR-HBM-ERR WR-HBM-ERR WR-HBM-ERR
       WRITE-REQUEST-STARTED WRITE-REQUEST-STARTED	;no ACK
       WRITE-REQUEST-STARTED WRITE-REQUEST-STARTED
       WRITE-REQUEST-TRY-AGAIN-LATER WRITE-REQUEST-TIMEOUT
       WRITE-REQUEST-ERROR WRITE-REQUEST-COMPLETE)       

     (READ-REQUEST		;This happens during execute cycle of CALL-CONDITIONAL.
       (CSM.VIRTUAL.PAGE.GROUP 1
  ;	CSM.CACHE.HIT.ENABLE 1
	CSM.CACHE.MODE 0;  1	;read
	CSM.MEMORY.CYCLE.ENDING-L 1
	CSM.REQUEST.NOTED-L 1)
       READ-TEST-1)
     (READ-TEST-1		;This happens during source cycle of ((..) MD) in case
       (			; of immediate use of memory data.
	CSM.VIRTUAL.PAGE.GROUP 1  ;On fast cache hit, memory.replying.now asserts
	CSM.CACHE.HIT.ENABLE 1    ; during this cycle.
	CSM.CACHE.MODE 0 ; 1
	CSM.MEMORY.CYCLE.ENDING-L 1
	CSM.REQUEST.NOTED-L 1)
       READ-TEST-FAST-CACHE)
     (READ-ABORT
       (CSM.REQUEST.NOTED-L 0
	CSM.MEMORY.CYCLE.ENDING-L 0)
       AWAIT-REQUEST)
     (READ-FAST-CACHE-HIT
       (CSM.VIRTUAL.PAGE.GROUP 1
	CSM.REQUEST.NOTED-L 0		;acknowledge cache request.
	CSM.CACHE.MODE 0 ;1		;causes data to appear on NUDATA bus.
	CSM.MEMORY.CYCLE.ENDING-L 0)
       AWAIT-REQUEST)
  ;main memory read stuff 
     (READ-REQUEST-FROM-MEMORY
       (CSM.LAMBDA.STREQ 1
	CSM.LAMBDA.BREQ 1
	CSM.RD.DATA.TO.NUDATA.BUS 1
	CSM.MEMORY.CYCLE.ENDING-L 1
	CSM.REQUEST.NOTED-L 1)
       AWAIT-READ-CYCLE-MASTER)
     (READ-REQUEST-STARTING
       (CSM.RD.DATA.TO.NUDATA.BUS 1
	CSM.REQUEST.NOTED-L 0		;acknowledge cache.request
	CSM.MEMORY.CYCLE.ENDING-L 1)
       AWAIT-READ-CYCLE-COMPLETION)
     (READ-REQUEST-STARTED
       (CSM.RD.DATA.TO.NUDATA.BUS 1
	CSM.MEMORY.CYCLE.ENDING-L 1
	CSM.REQUEST.NOTED-L 1)
       AWAIT-READ-CYCLE-COMPLETION)
     (READ-REQUEST-FAILED-TO-START
       (CSM.MEMORY.CYCLE.ENDING-L 0
	csm.error.bit 1)
       READ-REQUEST-FAILED-TO-START)
     (READ-REQUEST-TRY-AGAIN-LATER	;SORT OF AN IDLE CYCLE, THEN TRY AGAIN.
       (CSM.MEMORY.CYCLE.ENDING-L 1
	CSM.REQUEST.NOTED-L 1)
       READ-REQUEST-FROM-MEMORY)
     (READ-REQUEST-TIMEOUT
       (CSM.MEMORY.CYCLE.ENDING-L 0
	csm.error.bit 1)
       READ-REQUEST-TIMEOUT)
     (READ-REQUEST-ERROR		;error signal received on NUBUS
       (CSM.MEMORY.CYCLE.ENDING-L 0
	csm.error.bit 1)
       READ-REQUEST-ERROR)
     (READ-REQUEST-COMPLETE
       (		;write data in cache..
	CSM.CACHE.MODE 2	;write on NU xfer *** look into this
	CSM.MEMORY.CYCLE.ENDING-L 0
	CSM.RD.DATA.TO.NUDATA.BUS 1)
       AWAIT-REQUEST)
     (READ-BLOCK-INTERMEDIATE-ACK
       (		;write data in cache..
	CSM.CACHE.MODE 2	;write on NU xfer *** look into this
	CSM.RD.DATA.TO.NUDATA.BUS 1
	CSM.MEMORY.CYCLE.ENDING-L 1
	CSM.REQUEST.NOTED-L 1
	csm.count.nuadr 1
	)
       AWAIT-READ-CYCLE-COMPLETION)
     (RR-HBM-ERR			;master went away before ACK.
       (CSM.MEMORY.CYCLE.ENDING-L 0
	csm.error.bit 1)
       RR-HBM-ERR)

     (WRITE-REQUEST-TO-MEMORY-0
       (CSM.MD.TO.NUDATA.BUS 1
	CSM.MEMORY.CYCLE.ENDING-L 1
	CSM.REQUEST.NOTED-L 1)
       TEST-WRITE-CYCLE-PERMIT)
     (WRITE-REQUEST-TO-MEMORY
       (CSM.LAMBDA.STREQ 1
	CSM.LAMBDA.BREQ 1
	CSM.MD.TO.NUDATA.BUS 1
	CSM.MEMORY.CYCLE.ENDING-L 1
	CSM.REQUEST.NOTED-L 1)
       AWAIT-WRITE-CYCLE-MASTER)
     (WRITE-REQUEST-STARTING
       (CSM.MD.TO.NUDATA.BUS 1
	CSM.CACHE.MODE 2	;write on NU xfer *** look into this
			     ;**fine point: try to assure cache and memory same if
   	CSM.MEMORY.CYCLE.ENDING-L 1  ;write on bus just as we're trying to write it..
	CSM.REQUEST.NOTED-L 1
	)
       AWAIT-WRITE-CYCLE-COMPLETION-1)
     (AWAIT-WRITE-CYCLE-COMPLETION-1	;first cycle waiting for completion
       (CSM.MD.TO.NUDATA.BUS 1
	CSM.REQUEST.NOTED-L 0		;ack cache.request
	CSM.MEMORY.CYCLE.ENDING-L 1)
       AWAIT-WRITE-CYCLE-COMPLETION)
     (WRITE-REQUEST-STARTED		;rest of cycles waiting for completion
       (CSM.MD.TO.NUDATA.BUS 1
	CSM.MEMORY.CYCLE.ENDING-L 1)
       AWAIT-WRITE-CYCLE-COMPLETION)
     (WRITE-REQUEST-FAILED-TO-START
       (CSM.MEMORY.CYCLE.ENDING-L 0
	csm.error.bit 1)
       WRITE-REQUEST-FAILED-TO-START)
     (WRITE-REQUEST-TRY-AGAIN-LATER
       (CSM.MEMORY.CYCLE.ENDING-L 1
	CSM.REQUEST.NOTED-L 1)
       WRITE-REQUEST-TO-MEMORY)
     (WRITE-REQUEST-TIMEOUT
       (CSM.MEMORY.CYCLE.ENDING-L 0
	csm.error.bit 1)
       WRITE-REQUEST-TIMEOUT)
     (WRITE-REQUEST-ERROR	       ;error reply received on NUBUS
       (CSM.MEMORY.CYCLE.ENDING-L 0
	csm.error.bit 1)
       WRITE-REQUEST-ERROR)
     (WRITE-REQUEST-COMPLETE
       (CSM.MEMORY.CYCLE.ENDING-L 0
	CSM.REQUEST.NOTED-L 1
	CSM.MD.TO.NUDATA.BUS 1)
       AWAIT-REQUEST)
     (WR-HBM-ERR			;master went away before ACK.
       (CSM.MEMORY.CYCLE.ENDING-L 0	;AVOID HANGING WORLD
	csm.error.bit 1)
       WR-HBM-ERR)
))

