//D1VM.bcpl
//	Procedures to manage the virtual memory on the record file and
//	the FastSearch procedure called by SearchBlocks.
//	Last edited: 17 December 1979

//VM mapping information is stored in two arrays broken into #2000-word
//chunks stored on the record file.  VAmem[VA] contains all information
//about that VA (presently its AA and "Emulator" bit). AAmem[AA] contains
//the top 7 bits of VA (or #377 if no corresponding VA), allowing
//information for an AA to be determined by indexing into AAmem, then
//searching at most 128 entries in VAmem.  AA and VA buffers compete for
//core storage with the symbol buffers managed by MSYM and MSYMOV.

//All in core blocks are kept in BlockTable, described by the BT structure,
//which has Dirty, Core, and Kind fields.  The Sym, VA, and AA
//structures also have auxiliary tables (HeadBlock, VAtab, and AAtab,
//respectively) that give the BlockAddr in the record file associated
//with that block.

get "mcommon.d"
get "d1.d"
manifest [ get "d1regmem.d" ]

external [
// OS
	SetBlock; Usc

// MSYM
	GetBlock

// MSYMOV
	MakeNewBlock

// MMPRGN
	UpdateMPDValues

// MCMD
	FormCmdMenu

// D1TABLES
	@MEMLEN; @MEMNAM

// D1CONFIG
	IMXmask

// Defined here
	LookUpAA; LookUpVA; SetVirtP; RetrieveBlock; FastSearch
	@VirtualP; VAtab; AAtab
	IMstab; RMstab; BRstab; TASKNstab; DEVICEstab
]

static [
	VAtab; AAtab; @VirtualP
	IMstab; RMstab; BRstab; TASKNstab; DEVICEstab
]

//Called both as an action and from D1Reset, D1Load, and D1I2.
let SetVirtP(Flag,nil,nil; numargs NA) be
[	VirtualP = Flag
//Changed DefMemName to be "VM" always
//	DefMemName = MEMNAM!(Flag ? IMx,IMXx)
	if NA ge 2 do
	[ UpdateMPDValues(); FormCmdMenu()
	]
]


and RetrieveBlock(TablePtr,Kind,Strategy,Block,InitVal; numargs NA) = valof
[	let Blk = nil
	if NA < 4 then Block = 0
	test TablePtr!0 eq 0
	ifso		//If block doesn't exist
	[ if NA < 5 then resultis 0	//No such Block
	  let B = MakeNewBlock(NPagesPerStandardBlock,Kind,Strategy,Block)
	  TablePtr!0 = B>>BT.BlockAddr
	  Blk = B>>BT.Core
	  SetBlock(Blk,InitVal,BlockSize)
	]
	ifnot Blk = (GetBlock(TablePtr!0,Kind,Strategy,Block))>>BT.Core
	resultis Blk
]

//Note: An AA may be a 16-bit quantity, in which case bits larger than
//the quantity of physical storage are thrown away by the hardware.
//Consequently, before transforming an AA into a VA, unused high-order
//bits are truncated.  However, a VA of -1 is used to represent
//not-in-VM, so not thrown away.

//Return the VA corresponding to AA (#137777 if none); if the lvPtr arg is
//provided, point this at the AA structure in core (only do this if there
//is some VA corresponding to AA).
and LookUpVA(AA,lvPtr; numargs NA) = valof
[	AA = AA & IMXmask
	let Block = RetrieveBlock(AAtab+(AA rshift BlockShift),AAKind,4)
	if Block eq 0 then resultis -1
	let AAPtr = Block+(AA & BlockMask)
	if NA ge 2 then rv lvPtr = AAPtr
	resultis AAPtr!0 & #137777
]


//Return the AA corresponding to VA; if the DVec argument is given, supply
//full particulars (presently just the EMU bit) in DVec in IM format.
//Returns negative if not in VM.
and LookUpAA(VA,DVec; numargs NA) = valof
[	let Val = -1
	if Usc(VA,MEMLEN!(IMx+IMx+1)) < 0 do
	[ let Block = RetrieveBlock(VAtab+(VA rshift BlockShift),VAKind,1)
	  if Block ne 0 then Val = Block!(VA & BlockMask)
	]
//**Temporary kludge until MicroD fixed
	if NA ge 2 then DVec!3 = (Val & #7777)+((Val & #140000) rshift 2)
	resultis Val & #137777
]

//Called from SearchBlocks in MSYM.  Returns BlockTable pointer for the
//block containing the nearest symbol le Addr in MemX, or 0 if don't know.
and FastSearch(Addr,MemX) = valof
[	let Block = 0
	switchon MemX into
	[
case IMx: Block =
	    RetrieveBlock(IMstab+((Addr & IMXmask) rshift (BlockShift+1)),
		IMKind,1)
	  Addr = Addr & (BlockMask+BlockMask+1); endcase
case RMx: Block = RMstab; endcase
case BRx: Block = BRstab; endcase
case TASKNx: Block = TASKNstab; endcase
case DEVICEx: Block = DEVICEstab; endcase
default:  resultis 0
	]
	if (Addr ge MEMLEN!(MemX+MemX+1)) % (Block eq 0) then resultis 0
	resultis GetBlock(Block>>Bytes.Byte↑Addr,SymKind,1,Block)
]