{EERomTest.mc, HGM, 4-Nov-84 2:29:52} { This program makes 3 passes over the whole chip. First it writes 0 into each word. It checks each word as it is written. After checking a word, it bumps the MP. After writing the whole chip, it makes a read pass. Then it repeats the cycle with FFFF. Then it makes another pass with the address of the word as the data pattern. After all 3 passes complete, the MP will be 6144. That takes two minutes. Remember, it has to wait 10ms after writing each word. Then it loops checking the address pattern. The MP gets bumped each pass, and the decimal points will be on. Start the test over again if you want to write things again. This way you can't wear out the chip by going home when the test is running. } Reserve[0F5F, 0FFF]; {section used by the CP Kernel } SetTask[0]; StartAddress[Go]; RegDef[address, R, 1]; {Multibus (word) addressess used to access EERom} RegDef[rhAddr, RH, 1]; RegDef[location, R, 2]; {addressess in EERom} RegDef[expected, R, 3]; RegDef[found, R, 4]; RegDef[temp, R, 5]; RegDef[rhTemp, RH, 5]; RegDef[passCount, R, 6]; Set[Write0, 00]; Set[Write1, 01]; Set[Write2, 02]; Set[Write3, 03]; Set[Read0, 00]; Set[Read1, 02]; Set[Read2, 04]; Set[Read3, 06]; Set[Read4, 08]; Set[Read5, 0A]; Set[Read6, 0C]; Trap: temp ← RRot1 ErrnIBnStkp, ClrIntErr, CANCELBR[$, 0F], c1, at[0]; Xbus ← temp LRot0, XwdDisp, c2; DISP2[TrapType], c3; Parity: GOTO[GoToGo], c1, at[0,4,TrapType]; Init: GOTO[GoToGo], c1, at[1,4,TrapType]; Stack: GOTO[GoToGo], c1, at[2,4,TrapType]; IB: GOTO[GoToGo], c1, at[3,4,TrapType]; GoToGo: Noop, c2; Noop, GOTO[Go], c3; Go: Noop, c1; passCount ← 0, c2; ExtCtrl ← 5, {Init Incr, Zero, UnBlank} c3; SetupEPromCio: rhAddr ← 5, {EProm} c1; address ← 90, c2; address ← address LRot8 {9000}, c3; IO ← [rhAddr, address + 0], {Master Interrupt Control} c1; MDR ← 0, c2; Noop, c3; IO ← [rhAddr, address + 1], {Master Config Control} c1; MDR ← 094, {Enable Ports A, B, and C} c2; Noop, c3; IO ← [rhAddr, address + 0F], {Port C Data} c1; MDR ← 08, {No Output Enable} c2; Noop, c3; SetupTimerCio: rhAddr ← 4, c1; Noop, c2; Noop, c3; IO ← [rhAddr, address + 0], {Master Interrupt Control} c1; MDR ← 0, c2; address ← address + 20, c3; IO ← [rhAddr, address + 0B], {Port B Direction} c1; MDR ← 0F0, {Low 4 bits out} c2; address ← address - 20, c3; IO ← [rhAddr, address + 1], {Master Config Control} c1; MDR ← 084, {Enable Ports A+B} c2; Noop, c3; SetupZerosPass: expected ← 0, c1; location ← 0, c2; Noop, c3; WriteZeros: Noop, c1; L1 ← Write0, c2; CALL[Write], c3; CheckZeros: Noop, c1, at[Write0, 10, WriteRet]; L1 ← Read0, c2; CALL[Read], c3; Noop, c1, at[Read0, 10, ReadRet]; Noop, c2; [] ← expected xor found, ZeroBr, c3; BRANCH[WriteZerosDidntWork, $], c1; location ← location + 1, c2; Noop, c3; ExtCtrl ← 3, {Gets Bumped on rising edge} c1; ExtCtrl ← 7, c2; Noop, c3; temp ← location LRot8, c1; [] ← temp and 8, ZeroBr, c2; BRANCH[$, WriteZeros], c3; {MP should be 2048.} WriteZerosWorked: Noop, c1; Noop, c2; Noop, c3; VerifyZeros: Noop, c1; location ← 0, c2; Noop, c3; {Read things again.} ReadZeros: Noop, c1; L1 ← Read1, c2; CALL[Read], c3; Noop, c1, at[Read1, 10, ReadRet]; Noop, c2; [] ← expected xor found, ZeroBr, c3; BRANCH[ReadZerosDidntWork, $], c1; location ← location + 1, c2; Noop, c3; temp ← location LRot8, c1; [] ← temp and 8, ZeroBr, c2; BRANCH[$, ReadZeros], c3; SetupOnesPass: expected ← expected xor ~expected, c1; location ← 0, c2; Noop, c3; WriteOnes: Noop, c1; L1 ← Write1, c2; CALL[Write], c3; CheckOnes: Noop, c1, at[Write1, 10, WriteRet]; L1 ← Read2, c2; CALL[Read], c3; Noop, c1, at[Read2, 10, ReadRet]; Noop, c2; [] ← expected xor found, ZeroBr, c3; BRANCH[WriteOnesDidntWork, $], c1; location ← location + 1, c2; Noop, c3; ExtCtrl ← 3, {Gets Bumped on rising edge} c1; ExtCtrl ← 7, c2; Noop, c3; temp ← location LRot8, c1; [] ← temp and 8, ZeroBr, c2; BRANCH[$, WriteOnes], c3; {MP should be 4096.} WriteOnesWorked: Noop, c1; Noop, c2; Noop, c3; VerifyOnes: Noop, c1; location ← 0, c2; Noop, c3; {Read things again.} ReadOnes: Noop, c1; L1 ← Read3, c2; CALL[Read], c3; Noop, c1, at[Read3, 10, ReadRet]; Noop, c2; [] ← expected xor found, ZeroBr, c3; BRANCH[ReadOnesDidntWork, $], c1; location ← location + 1, c2; Noop, c3; temp ← location LRot8, c1; [] ← temp and 8, ZeroBr, c2; BRANCH[$, ReadOnes], c3; SetupAddressPass: expected ← 0, c1; location ← 0, c2; Noop, c3; WriteAddress: Noop, c1; L1 ← Write2, c2; CALL[Write], c3; CheckAddress: Noop, c1, at[Write2, 10, WriteRet]; L1 ← Read4, c2; CALL[Read], c3; Noop, c1, at[Read4, 10, ReadRet]; Noop, c2; [] ← expected xor found, ZeroBr, c3; BRANCH[WriteAddressDidntWork, $], c1; location ← location + 1, c2; expected ← expected + 1, c3; ExtCtrl ← 3, {Gets Bumped on rising edge} c1; ExtCtrl ← 7, c2; Noop, c3; temp ← location LRot8, c1; [] ← temp and 8, ZeroBr, c2; BRANCH[$, WriteAddress], c3; {MP should be 6144.} WriteAddressWorked: Noop, c1; Noop, c2; Noop, c3; VerifyAddress: expected ← 0, c1; location ← 0, c2; Noop, c3; {Read things again.} ReadAddress: Noop, c1; L1 ← Read5, c2; CALL[Read], c3; Noop, c1, at[Read5, 10, ReadRet]; Noop, c2; [] ← expected xor found, ZeroBr, c3; BRANCH[ReadAddressDidntWork, $], c1; location ← location + 1, c2; expected ← expected + 1, c3; temp ← location LRot8, c1; [] ← temp and 8, ZeroBr, c2; BRANCH[$, ReadAddress], c3; EverythingWorked: Q ← 0F0, {DP on after all 3 write passes} c1; ExtCtrl ← Q + 3, {Gets Bumped on rising edge} c2; ExtCtrl ← Q + 7, GOTO[VerifyAddress], c3; {----------------------------------------------------------------} {For hardware/microcode debugging...} WriteLoop: Noop, c1; L1 ← Write3, c2; CALL[Write], c3; Noop, c1, at[Write3, 10, WriteRet]; Noop, c2; GOTO[WriteLoop], c3; ReadLoop: Noop, c1; L1 ← Read6, c2; CALL[Read], c3; Noop, c1, at[Read6, 10, ReadRet]; Noop, c2; GOTO[ReadLoop], c3; {----------------------------------------------------------------} WriteZerosDidntWork: GOTO[Err3], c2; ReadZerosDidntWork: GOTO[Err3], c2; WriteOnesDidntWork: GOTO[Err3], c2; ReadOnesDidntWork: GOTO[Err3], c2; WriteAddressDidntWork: GOTO[Err3], c2; ReadAddressDidntWork: GOTO[Err3], c2; Err3: GOTO[Go], c3; {----------------------------------------------------------------} FlapMData: rhAddr ← 5, {EProm} c1; address ← 90, c2; address ← address LRot8 {9000}, c3; IO ← [rhAddr, address + 0F], {Port C Data} c1; MDR ← 08, {No OE} c2; expected ← 0, c3; rhAddr ← 4, {Timer CIO} c1; Noop, c2; address ← address + 20, c3; IO ← [rhAddr, address + 03], {Port A Direction} c1; MDR ← 0, {Output} c2; address ← address - 20, c3; rhAddr ← 5, {EProm CIO} c1; Noop, c2; Noop, c3; IO ← [rhAddr, address + 0E], {Port B Data} c1; MDR ← location, c2; Noop, c3; IO ← [rhAddr, address + 0D], {Port A Data} c1; MDR ← 08, {No write} c2; rhAddr ← 4, {Timer CIO} c3; FlapMDataLoop: IO ← [rhAddr, address + 0D], {Port A Data} c1; MDR ← expected, c2; expected ← expected+1, GOTO[FlapMDataLoop], c3; {----------------------------------------------------------------} Write: rhAddr ← 5, {EProm CIO} c1; Noop, c2; temp ← location LRot8, {High byte of address in EERom} c3; IO ← [rhAddr, address + 0F], {Port C Data} c1; MDR ← 08, {No OE} c2; Noop, c3; rhAddr ← 4, {Timer CIO} c1; Noop, c2; address ← address + 20, c3; IO ← [rhAddr, address + 03], {Port A Direction} c1; MDR ← 0, {Output} c2; address ← address - 20, c3; rhAddr ← 5, {EProm CIO} c1; Noop, c2; Noop, c3; IO ← [rhAddr, address + 0E], {Port B Data} c1; MDR ← location, c2; Noop, c3; IO ← [rhAddr, address + 0D], {Port A Data} c1; MDR ← temp or 08, {No write} c2; Noop, c3; WriteHighByte: rhAddr ← 4, {Timer CIO} c1; expected ← expected LRot8, c2; Noop, c3; IO ← [rhAddr, address + 0D], {Port A Data} c1; MDR ← expected, c2; expected ← expected LRot8, c3; IO ← [rhAddr, address + 0E], {Port B Data} c1; MDR ← 05, {EERom High Byte} c2; Noop, c3; WritePulseForHighByte: rhAddr ← 5, {EProm CIO} c1; Noop, c2; Noop, c3; IO ← [rhAddr, address + 0D], {Port A Data} c1; MDR ← temp, {Write} c2; Noop, c3; IO ← [rhAddr, address + 0D], {Port A Data} c1; MDR ← temp or 08, {No Write} c2; Noop, c3; WriteLowByte: rhAddr ← 4, {Timer CIO} c1; Noop, c2; Noop, c3; IO ← [rhAddr, address + 0D], {Port A Data} c1; MDR ← expected, c2; Noop, c3; IO ← [rhAddr, address + 0E], {Port B Data} c1; MDR ← 04, {EERom Low Byte} c2; Noop, c3; WritePulseForLowByte: rhAddr ← 5, {EProm CIO} c1; Noop, c2; Noop, c3; IO ← [rhAddr, address + 0D], {Port A Data} c1; MDR ← temp, {Write} c2; Noop, c3; IO ← [rhAddr, address + 0D], {Port A Data} c1; MDR ← temp or 08, {No Write} c2; Noop, c3; WriteFinished: rhAddr ← 4, {Timer CIO} c1; Noop, c2; address ← address + 20, c3; IO ← [rhAddr, address + 03], {Port A Direction} c1; MDR ← 0FF, {Input} c2; address ← address - 20, c3; Noop, c1; Noop, c2; temp ← 0, c3; {Have to wait 10ms after each write. With a 100ns clock, this takes 36 ms.} WriteDallyLoop: Noop, c1; temp ← temp + 1, CarryBr, c2; BRANCH[WriteDallyLoop, $], c3; Noop, c1; L1Disp, c2; DISP4[WriteRet], c3; {----------------------------------------------------------------} Read: rhAddr ← 4, {Timer CIO} c1; Noop, c2; address ← address + 20, c3; IO ← [rhAddr, address + 03], {Port A Direction} c1; MDR ← 0FF, {Input} c2; address ← address - 20, c3; rhAddr ← 5, {EProm CIO} c1; Noop, c2; Noop, c3; IO ← [rhAddr, address + 0E], {Port B Data} c1; MDR ← location, c2; temp ← location LRot8, c3; IO ← [rhAddr, address + 0D], {Port A Data} c1; MDR ← temp or 08, {No write} c2; Noop, c3; IO ← [rhAddr, address + 0F], {Port C Data} c1; MDR ← 00, {OE} c2; Noop, c3; ReadHighByte: rhAddr ← 4, {Timers CIO} c1; Noop, c2; Noop, c3; IO ← [rhAddr, address + 0E], {Port B Data} c1; MDR ← 05, {EERom High Byte} c2; Noop, c3; IO ← [rhAddr, address + 0D], {Port A Data} c1; Noop, c2; found ← MD, c3; ReadLowByte: IO ← [rhAddr, address + 0E], {Port B Data} c1; MDR ← 04, {EERom Low Byte} c2; found ← found LRot8, c3; IO ← [rhAddr, address + 0D], {Port A Data} c1; Noop, c2; found ← found or MD, c3; ReadFinished: rhAddr ← 5, {EProm CIO} c1; Noop, c2; Noop, c3; IO ← [rhAddr, address + 0F], {Port C Data} c1; MDR ← 08, {No OE} c2; Noop, c3; Noop, c1; L1Disp, c2; DISP4[ReadRet], c3; {----------------------------------------------------------------} SpinPromAddresses: rhAddr ← 5, {EProm} c1; address ← 90, c2; address ← address LRot8 {9000}, c3; IO ← [rhAddr, address + 0], {Master Interrupt Control} c1; MDR ← 0, c2; Noop, c3; IO ← [rhAddr, address + 1], {Master Config Control} c1; MDR ← 094, {Enable Ports A, B, and C} c2; temp ← address + 20, c3; {Things should default to Bit Mode and Output} { IO ← [rhAddr, temp + 03], {Port A Direction} c1; MDR ← 0, {All bits output} c2; Noop, c3; IO ← [rhAddr, temp + 0B], {Port B Direction} c1; MDR ← 0, {All bits output} c2; Noop, c3; IO ← [rhAddr, address + 06], {Port C Direction} c1; MDR ← 0, {All bits output} c2; Noop, c3; IO ← [rhAddr, temp + 00], {Port A Mode} c1; MDR ← 0, {Bit Port} c2; Noop, c3; IO ← [rhAddr, temp + 08], {Port B Mode} c1; MDR ← 0, {Bit Port} c2; Noop, c3; } IO ← [rhAddr, address + 0F], {Port C Data} c1; MDR ← 0, {PromOE'} c2; GOTO[SpinNextChip], c3; SpinLoop: IO ← [rhAddr, address + 0E], {Port B Data} c1; MDR ← temp, c2; temp ← temp LRot8, c3; IO ← [rhAddr, address + 0D], {Port A Data} c1; MDR ← temp, temp ← temp LRot8, c2; Noop, c3; {Read data comes in on another chip/address} Noop, c1; temp ← temp + 1, CarryBr, c2; BRANCH[SpinLoop, $], c3; ExtCtrl ← 3, {Gets Bumped on rising edge} c1; ExtCtrl ← 7, c2; passCount ← passCount + 1, c3; SpinNextChip: rhAddr ← 4, {Timers} c1; Noop, c2; Q ← address + 20, c3; IO ← [rhAddr, address + 0], {Master Interrupt Control} c1; MDR ← 1, {Reset} c2; Noop, c3; IO ← [rhAddr, address + 0], {Master Interrupt Control} c1; MDR ← 0, c2; Noop, c3; IO ← [rhAddr, Q + 0B], {Port B Direction} c1; MDR ← 0F0, c2; Noop, c3; IO ← [rhAddr, address + 1], {Master Config Control} c1; MDR ← 080, {Enable Port B} c2; Noop, c3; IO ← [rhAddr, address + 0E], {Port B Data} c1; MDR ← rhTemp, c2; Noop, c3; rhAddr ← 5, {EProms} c1; Noop, c2; Noop, c3; Q ← rhTemp + 1, c1, LOOPHOLE[byteTiming]; Q ← Q and 07, c2; rhTemp ← Q LRot0, GOTO[SpinLoop], c3; {------------------------------------------------------------------------------------}