//D1Test.bcpl -- machine-dependent part of "Test" overlay
//	Last edited: 20 November 1979

manifest [ get "d1dmux.d" ]
manifest [ get "d1regmem.d" ]
manifest [ get "d1instrs.d" ]

external [
// OS
	DoubleAdd

// MINIT0
	@MBlock

// MASM
	WssCS1; SelfRel

// MMENU
	PrintActionTime

// MDEBUG
	CheckData; ErrorStop; SaveDGen; RestoreDGen; TestAborted; @NDWords

// MPATTERN
	NextData

// MTEST
	LastVal

// MDATA
	@ShouldBe; @BitsChecked; @DataWas

// D1I0
	@DMuxTab; DMuxSelect

// D1TABLES
	@MEMLEN

// D1ASM
	@Xct; @XctL16; @XctR16; @XctLFF; @XctL16T; @SelectTask; ReadDMux

// D1REG
	PutRegData; GetRegData

// D1RW
	MPutMemData; @SaveMBase; @SaveT

// D1VM
	SetVirtP

// D1TESTASM
	OtherNAM

// Defined here
	ValidateTest
// These procedures are called from the OtherProc table in D1TestAsm.
	ShmvLp; WFLp; RFLp; ProcVALp
// These procedures are called from the OtherPrint table in D1TestAsm.
	ShmvPrint; WFRFPrint; ProcVAPrint
]

//X is RegX, MemX+NREGS, or NREGS+NMEMS+OtherX
let ValidateTest(X) be
[	SetVirtP(false)
	LastVal = X; DMuxSelect = DMuxTab
]


and ShmvLp(X) = valof
[	for I = 0 to 49 do
	[ NextData()
	  let lmask = -1 lshift (16-(ShouldBe!0 & 17B))
	  let rmask = -1 rshift (16-((ShouldBe!0 rshift 4) & 17B))
	  PutRegData(SHCx,ShouldBe)
	  let Opx = ShouldBe!0 rshift 14
	  Xct(table [ SFTN; SFTL; SFTR; SFTB ] ! Opx)
	  ReadDMux(); DataWas!0 = DMuxTab!dSHMV
	  SaveDGen()
	  ShouldBe!0 = selecton Opx into
	  [
	case 0:	0
	case 1:	lmask
	case 2:	rmask
	case 3:	lmask % rmask
	  ]
	  if CheckData() then ErrorStop("shmv wrong after ",
		selecton Opx into
		[
	case 0:	"ShiftNoMask"
	case 1: "ShiftLMask"
	case 2:	"ShiftRMask"
	case 3:	"ShiftBothMasks"
		] )
	  RestoreDGen()
	]
	if TestAborted then ErrorStop()
	PrintActionTime(); resultis true
]


and ShmvPrint(X) be
[	WssCS1("using ShiftNoMask, ShiftLMask, ShiftRMask, and ShiftBothMasks")
]


and RFILp(P,S,Val) = valof
[	XctL16(LT,Val); Xct(RF); Xct(NOOP)
	resultis (Val & 30000B)+(((P+S+1) & 17B) lshift 8)+((15-S) & 17B)
]


and WFILp(P,S,Val) = valof
[	XctL16(LT,Val); Xct(WF); Xct(NOOP)
	let Z = (15-P-S) & 17B
	resultis (Val & 30000B)+(Z lshift 8)+(Z lshift 4)+P
]


//These two ignore the data pattern, manipulating ShouldBe directly.
and RFLp(X) = WFRFLp(X,lv RFILp)
and WFLp(X) = WFRFLp(X,lv WFILp)


and WFRFLp(X,lvProc) = valof
[	let AVec = vec 1; AVec!0 = 0
	for P = 0 to 17B do for S = 0 to 17B do
	[ AVec!1 = (P lshift 4)+S
	  ShouldBe!0 = (rv lvProc)(P,S,AVec!1)
	  GetRegData(SHCx,DataWas)
	  if CheckData() then
		ErrorStop(SelfRel(OtherNAM+X)," failed for A = ",AVec)
	]
	if TestAborted then ErrorStop()
	PrintActionTime(); resultis true
]


and WFRFPrint(X) be
[	WssCS1("for P = 0 to 17B, for S = 0 to 17B")
]


and ProcVALp(X) = valof
[	let V1,AVec = vec 2,vec 1; AVec!0 = 0; V1!0 = 0
	SelectTask(0); PutRegData(MCRx,table [ NoWake+DisHold ] )
	for I = 0 to MEMLEN!(BRx+BRx+1)-1 do
	[ AVec!1 = I; SaveMBase = I; XctLFF(LMB0,I)
	  NextData()
	  MPutMemData(BRx,ShouldBe,AVec)
	  SaveT = ShouldBe!2; XctL16T(SaveT); V1!1 = SaveT
	  DoubleAdd(ShouldBe,V1)
	  Xct(DUMMYFT); Xct(NOOP); ReadDMux()
	  MBlock(DataWas,DMuxTab+dPVAH,2)
	  if CheckData() then
		ErrorStop(SelfRel(OtherNAM+X)," failed on BR = ",AVec)
	]
	if TestAborted then ErrorStop()
	PrintActionTime(); resultis true
]


and ProcVAPrint(X) be
[	WssCS1("with DUMMYREF←T using BR's 0 to 37")
]