;;; -*- Mode:LISP; Package:MICRO; Base:8; Readtable:ZL -*-

(define-micro-function %clean-pages ()
 (locality a-mem)
a-clean-pages-scan-pointer (0)
a-clean-pages-steps (0)
 (locality i-mem)
	((a-clean-pages-steps) setz)
	((m-b) a-clean-pages-scan-pointer)
clean-pages-find-dirty-page
	((m-tem) m+a+1 m-zero a-clean-pages-steps)
	(jump-equal m-tem (a-constant 5) clean-pages-done)
	((a-clean-pages-steps) m-tem)
	((m-b) add m-b (a-constant 1))
	(CALL-GREATER-OR-EQUAL M-B A-V-PHYSICAL-PAGE-DATA-VALID-LENGTH clean-pages-ppd-wrap)
	((VMA-START-READ) ADD M-B A-V-PHYSICAL-PAGE-DATA)
	(ILLOP-IF-PAGE-FAULT)
	((M-TEM) (BYTE-FIELD 20 0) READ-MEMORY-DATA I-LONG)	;PHT entry index
	(JUMP-EQUAL M-TEM (A-CONSTANT 177777) clean-pages-find-dirty-page)	;No page here
	((VMA-START-READ M-T) ADD M-TEM A-V-PAGE-TABLE-AREA)
	(illop-if-page-fault)
	((m-tem) ldb (lisp-byte si:%%pht1-swap-status-code) md)
	(jump-equal m-tem (a-constant (eval si:%pht-swap-status-wired)) clean-pages-find-dirty-page)
	(jump-if-bit-set (lisp-byte si:%%pht1-modified-bit) md clean-pages-found-dirty-page)
	((vma-start-read) add m-t (a-constant 1))
	(illop-if-page-fault)
	((m-tem) ldb (lisp-byte si:%%pht2-map-status-code) md)
	(jump-equal md (a-constant si:%pht-map-status-read-write) clean-pages-found-dirty-page)
	(jump clean-pages-find-dirty-page)
	
clean-pages-ppd-wrap
	(POPJ-AFTER-NEXT (M-B) A-ZERO)
       (NO-OP)

clean-pages-found-dirty-page
	((C-PDL-BUFFER-POINTER-PUSH) M-T)		;PHT1 address. - randomly used below to restore m-t
							; original use is at coref-ccw-x
	((A-DISK-SWAP-OUT-CCW-POINTER) (A-CONSTANT DISK-SWAP-OUT-CCW-BASE))
     ;add main memory page frame number in M-B to CCW list.
;#-lambda(begin-comment)
	((WRITE-MEMORY-DATA) DPB M-B VMA-PHYS-PAGE-ADDR-PART (A-CONSTANT 1))
	((VMA-START-WRITE) A-DISK-SWAP-OUT-CCW-POINTER)
	(ILLOP-IF-PAGE-FAULT)
	((A-DISK-SWAP-OUT-CCW-POINTER)
	     ADD A-DISK-SWAP-OUT-CCW-POINTER M-ZERO ALU-CARRY-IN-ONE)
;#-lambda(end-comment)
;#-exp(begin-comment)
;	((m-t) dpb m-b vma-phys-page-addr-part a-zero)
;	(call translate-cadr-physical-to-nubus)
;	((md) m-lam)
;	((vma-start-write) a-disk-swap-out-ccw-pointer)
;	(illop-if-page-fault)
;	((md) (a-constant 1024.))
;	((vma-start-write) add vma (a-constant 1))
;	(illop-if-page-fault)
;	((a-disk-swap-out-ccw-pointer) add vma (a-constant 1))
;	((m-t) pdl-top)
;#-exp(end-comment)
	((A-DISK-SAVE-PGF-A) M-A)
	((A-DISK-SAVE-PGF-B) M-B)
	((A-DISK-SAVE-1) M-A)
clean-pages-collect-pages
	((M-T) (A-CONSTANT (EVAL PAGE-SIZE)))
	((A-DISK-SAVE-1) ADD M-T A-DISK-SAVE-1)
	(CALL-XCT-NEXT SEARCH-PAGE-HASH-TABLE)   ;Is next higher page in core?
       ((M-T) A-DISK-SAVE-1)  			 ; virt adr in M-T.
		; clobbers m-a m-b m-t a-tem1 a-tem3
	(JUMP-IF-BIT-CLEAR (lisp-byte si:%%PHT1-VALID-BIT) md clean-pages-got-all-pages) ;not found.
		;That page in core, does it need to be written?
	((M-T) VMA)				;Save PHT1 adr.
	((M-A) MD)				;Save PHT1.
	((VMA-START-READ) ADD M-T (A-CONSTANT 1))	;get PHT2
	(ILLOP-IF-PAGE-FAULT)
	((M-B) READ-MEMORY-DATA)
	(JUMP-IF-BIT-SET (lisp-byte si:%%PHT1-MODIFIED-BIT) M-A clean-pages-add)
	((m-tem) ldb (lisp-byte si:%%pht2-map-status-code) m-b)
	(jump-not-equal m-tem (a-constant (eval si:%pht-map-status-read-write)) clean-pages-got-all-pages)
clean-pages-add
	((md m-a) dpb m-zero (lisp-byte si:%%pht1-modified-bit) a-a) ;clear modified flag
	((VMA-START-WRITE) M-T)
	(ILLOP-IF-PAGE-FAULT)
	((M-TEM) PHT2-MAP-STATUS-CODE M-B)
	(JUMP-NOT-EQUAL M-TEM (A-CONSTANT 4) clean-pages-add-1)  ;change RW to RWF
	((M-TEM) (A-CONSTANT 3))
	((md M-B) DPB M-TEM (lisp-byte si:%%PHT2-MAP-STATUS-CODE) A-B)
	((VMA-START-WRITE) ADD M-T (A-CONSTANT 1))
	(ILLOP-IF-PAGE-FAULT)
	((MD) M-A)				;address the map
	(no-op)		;allow time
	((M-TEM) L2-MAP-STATUS-CODE)		;see if map is set up
	(JUMP-LESS-THAN M-TEM (A-CONSTANT 2) clean-pages-add-1)
	(CALL-XCT-NEXT LOAD-L2-MAP-FROM-CADR-PHYSICAL)  ;PHT2 same as 2ND LVL MAP(on cadr)
       ((M-LAM) M-B)
clean-pages-add-1
   ;add main memory page frame number in M-B to CCW list.
;#-lambda(begin-comment)
	((WRITE-MEMORY-DATA) DPB M-B VMA-PHYS-PAGE-ADDR-PART (A-CONSTANT 1))
	((VMA-START-WRITE) A-DISK-SWAP-OUT-CCW-POINTER)
	(ILLOP-IF-PAGE-FAULT)
	((A-DISK-SWAP-OUT-CCW-POINTER)
	   M+A+1 A-DISK-SWAP-OUT-CCW-POINTER M-ZERO)
;#-lambda(end-comment)
;#-exp (begin-comment)
;	((m-tem1) m-t)
;	((m-t) dpb m-b vma-phys-page-addr-part a-zero)
;	(call translate-cadr-physical-to-nubus)
;	((md) m-lam)
;	((vma-start-write) a-disk-swap-out-ccw-pointer)
;	(illop-if-page-fault)
;	((md) (a-constant 1024.))
;	((vma-start-write) add vma (a-constant 1))
;	(illop-if-page-fault)
;	((a-disk-swap-out-ccw-pointer) add vma (a-constant 1))
;	((m-t) m-tem1)
;#-exp(end-comment)
	((M-TEM) A-DISK-SWAP-OUT-CCW-POINTER)
	(JUMP-LESS-THAN M-TEM (A-CONSTANT DISK-SWAP-OUT-CCW-MAX) clean-pages-collect-pages)
clean-pages-got-all-pages
;#-lambda(begin-comment)
	((VMA-START-READ) ADD A-DISK-SWAP-OUT-CCW-POINTER (M-CONSTANT -1))
	(ILLOP-IF-PAGE-FAULT)
	((WRITE-MEMORY-DATA-START-WRITE) SUB READ-MEMORY-DATA (A-CONSTANT 1)) ;last CCW
	(ILLOP-IF-PAGE-FAULT)
;#-lambda(end-comment)
	((A-DISK-PAGE-WRITE-OP-COUNT) M+A+1 M-ZERO A-DISK-PAGE-WRITE-OP-COUNT)
	((M-A) A-DISK-SAVE-PGF-A)			;get back base virt adr.
	((M-B) A-DISK-SAVE-PGF-B)			;get back page frame number of first
							; page.  It is no longer used by
							; disk swap handler, but is needed
							; by COREFOUND2.
	((C-PDL-BUFFER-POINTER-PUSH) M-C)
	((M-C) (A-CONSTANT DISK-SWAP-OUT-CCW-BASE))	;M-C
	((m-tem4) a-disk-swap-out-ccw-pointer)
	((m-tem4) sub m-tem4 a-c)	;length of transfer in pages (for hexadec aging hack).
;#+exp	((m-tem4) ldb (byte-field 31. 1) m-tem4) ;divide by 2
	(CALL-XCT-NEXT DISK-SWAP-HANDLER)		;Do the write (virt adr in M-A)
       ((M-T) (A-CONSTANT DISK-WRITE-COMMAND))
	((M-C) C-PDL-BUFFER-POINTER-POP)
	((M-T) C-PDL-BUFFER-POINTER-POP)		;RESTORE PHT ENTRY ADDRESS
)