{DESTest.mc, HGM, 4-Nov-84 2:29:40 Simple tests for DES chip on Dicentra Misc board. Each tick of the MP represents 256 good encryption blocks and 254 good decryption blocks. NB: This program assumes that Burdock loads the Key, Data, and Cipher U Regs with valid data. } Reserve[0F5F, 0FFF]; {section used by the CP Kernel } SetTask[0]; StartAddress[Go]; RegDef[address, R, 1]; {9000 => DES Chip} RegDef[rhAddr, RH, 1]; {6 => Byte mode, 7=> Word mode} RegDef[out1, R, 3]; RegDef[out2, R, 4]; RegDef[out3, R, 5]; RegDef[out4, R, 6]; RegDef[passCount, R, 0D]; RegDef[temp, R, 0E]; RegDef[uKey1, U, 21]; RegDef[uKey2, U, 22]; RegDef[uKey3, U, 23]; RegDef[uKey4, U, 24]; RegDef[uData1, U, 31]; RegDef[uData2, U, 32]; RegDef[uData3, U, 33]; RegDef[uData4, U, 34]; RegDef[uCipher1, U, 41]; RegDef[uCipher2, U, 42]; RegDef[uCipher3, U, 43]; RegDef[uCipher4, U, 44]; Set[L0.ResetForEncryption, 1]; Set[L0.ResetForDecryption, 2]; Set[L0.SetEncryptMode, 3]; Set[L0.SetDecryptMode, 4]; Set[L0.LoadEnKey, 5]; Set[L0.LoadDeKey, 6]; Set[L0.StartEncryption, 7]; Set[L0.StartDecryption, 8]; Trap: temp ← RRot1 ErrnIBnStkp, ClrIntErr, 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; GOTO[Go], c3; Go: address ← 90, c1; address ← address LRot8, {9000} c2; Noop, c3; Noop, c1; passCount ← 0, c2; ExtCtrl ← 5, {Init Incr, Zero, UnBlank} c3; MainLoop: Noop, c1; Noop, c2; Noop, c3; ResetTheChip: temp ← 00, L0 ← L0.ResetForEncryption, c1; CALL[StuffCommand], c2; SetEncryptionMode: temp ← 18, L0 ← L0.SetEncryptMode, c1, at[L0.ResetForEncryption, 10, StuffRet]; CALL[StuffMode], {ECB, Encrypt via Master Port} c2; LoadEncryptionKey: temp ← 11, L0 ← L0.LoadEnKey, c1, at[L0.SetEncryptMode, 10, StuffRet]; CALL[StuffCommand], c2; Noop, c1, at[L0.LoadEnKey, 10, StuffRet]; Noop, c2; Noop, c3; IO ← [rhAddr, address + 0], {DES Data} c1; MDR ← uKey1, c2; Noop, c3; IO ← [rhAddr, address + 0], {DES Data} c1; MDR ← uKey2, c2; Noop, c3; IO ← [rhAddr, address + 0], {DES Data} c1; MDR ← uKey3, c2; Noop, c3; IO ← [rhAddr, address + 0], {DES Data} c1; MDR ← uKey4, c2; Noop, c3; StartEncryption: temp ← 0C0, L0 ← L0.StartEncryption, c1; CALL[StuffCommand], c2; Noop, c1, at[L0.StartEncryption, 10, StuffRet]; Noop, c2; Noop, c3; LoadData: IO ← [rhAddr, address + 0], {DES Data} c1; MDR ← uData1, c2; Noop, c3; IO ← [rhAddr, address + 0], {DES Data} c1; MDR ← uData2, c2; Noop, c3; IO ← [rhAddr, address + 0], {DES Data} c1; MDR ← uData3, c2; Noop, c3; IO ← [rhAddr, address + 0], {DES Data} c1; MDR ← uData4, c2; Noop, c3; Noop, c1; Noop, c2; temp ← 20, c3; {Wait for the chip to crunch the bits. No pipelining.} DataDally: Noop, c1; temp ← temp - 1, ZeroBr, c2; BRANCH[DataDally, $], c3; GetEncryption: IO ← [rhAddr, address + 0], {DES Data} c1; Noop, c2; out1 ← MD, c3; IO ← [rhAddr, address + 0], {DES Data} c1; Noop, c2; out2 ← MD, c3; IO ← [rhAddr, address + 0], {DES Data} c1; Noop, c2; out3 ← MD, c3; IO ← [rhAddr, address + 0], {DES Data} c1; Noop, c2; out4 ← MD, c3; CheckEncryption: temp ← uCipher1, c1; [] ← out1 xor temp, NZeroBr, c2; BRANCH[$, Encr1Bad], c3; temp ← uCipher2, c1; [] ← out2 xor temp, NZeroBr, c2; BRANCH[$, Encr2Bad], c3; temp ← uCipher3, c1; [] ← out3 xor temp, NZeroBr, c2; BRANCH[$, Encr3Bad], c3; temp ← uCipher4, c1; [] ← out4 xor temp, NZeroBr, c2; BRANCH[$, Encr4Bad], c3; GoodEncryption: Noop, c1; passCount ← passCount + 1, PgCarryBr, c2; BRANCH[LoadData, $], c3; ResetForDecryption: temp ← 00, L0 ← L0.ResetForDecryption, c1; CALL[StuffCommand], c2; SetDecryptionMode: temp ← 08, L0 ← L0.SetDecryptMode, c1, at[L0.ResetForDecryption, 10, StuffRet]; CALL[StuffMode], {ECB, Decrypt via Master Port} c2; LoadDecryptionKey: temp ← 12, L0 ← L0.LoadDeKey, c1, at[L0.SetDecryptMode, 10, StuffRet]; CALL[StuffCommand], c2; Noop, c1, at[L0.LoadDeKey, 10, StuffRet]; Noop, c2; Noop, c3; IO ← [rhAddr, address + 0], {DES Data} c1; MDR ← uKey1, c2; Noop, c3; IO ← [rhAddr, address + 0], {DES Data} c1; MDR ← uKey2, c2; Noop, c3; IO ← [rhAddr, address + 0], {DES Data} c1; MDR ← uKey3, c2; Noop, c3; IO ← [rhAddr, address + 0], {DES Data} c1; MDR ← uKey4, c2; Noop, c3; StartDecryption: temp ← 0C0, L0 ← L0.StartDecryption, c1; CALL[StuffCommand], c2; Noop, c1, at[L0.StartDecryption, 10, StuffRet]; Noop, c2; Noop, c3; LoadCipher: IO ← [rhAddr, address + 0], {DES Data} c1; MDR ← uCipher1, c2; Noop, c3; IO ← [rhAddr, address + 0], {DES Data} c1; MDR ← uCipher2, c2; Noop, c3; IO ← [rhAddr, address + 0], {DES Data} c1; MDR ← uCipher3, c2; Noop, c3; IO ← [rhAddr, address + 0], {DES Data} c1; MDR ← uCipher4, c2; Noop, c3; {A slight delay seems to be necessary at 16MHZ.} Noop, c1; Noop, c2; Noop, c3; FillDecryptionPipeTest: temp ← passCount and 0FE, c1; [] ← temp, ZeroBr, c2; BRANCH[GetDecryption, $], c3; Noop, {passCount is 0 or 1} c1; passCount ← passCount + 1, c2; GOTO[LoadCipher], c3; GetDecryption: IO ← [rhAddr, address + 0], {DES Data} c1; Noop, c2; out1 ← MD, c3; IO ← [rhAddr, address + 0], {DES Data} c1; Noop, c2; out2 ← MD, c3; IO ← [rhAddr, address + 0], {DES Data} c1; Noop, c2; out3 ← MD, c3; IO ← [rhAddr, address + 0], {DES Data} c1; Noop, c2; out4 ← MD, c3; CheckDecryption: temp ← uData1, c1; [] ← out1 xor temp, NZeroBr, c2; BRANCH[$, Decr1Bad], c3; temp ← uData2, c1; [] ← out2 xor temp, NZeroBr, c2; BRANCH[$, Decr2Bad], c3; temp ← uData3, c1; [] ← out3 xor temp, NZeroBr, c2; BRANCH[$, Decr3Bad], c3; temp ← uData4, c1; [] ← out4 xor temp, NZeroBr, c2; temp ← passCount + 1, BRANCH[$, Decr4Bad], c3; GoodDecryption: temp ← temp and 0FE, c1; passCount ← passCount + 1, PgCarryBr, c2; BRANCH[$, NextPass], c3; temp ← temp xor 0FE, c1; [] ← temp, ZeroBr, c2; BRANCH[LoadCipher, $], c3; Noop, {passCount = 0FD or 0FE} c1; Noop, c2; GOTO[GetDecryption], c3; NextPass: Noop, c1; ExtCtrl ← 3, {Gets Bumped on rising edge}, c2; ExtCtrl ← 7, GOTO[MainLoop], c3; {------------------------------------------------------------------------------------} Encr1Bad: GOTO[ErrorInEncryption], c1; Encr2Bad: GOTO[ErrorInEncryption], c1; Encr3Bad: GOTO[ErrorInEncryption], c1; Encr4Bad: GOTO[ErrorInEncryption], c1; ErrorInEncryption: Noop, c2; GOTO[Go], c3; Decr1Bad: GOTO[ErrorInDecryption], c1; Decr2Bad: GOTO[ErrorInDecryption], c1; Decr3Bad: GOTO[ErrorInDecryption], c1; Decr4Bad: GOTO[ErrorInDecryption], c1; ErrorInDecryption: Noop, c2; GOTO[Go], c3; {------------------------------------------------------------------------------------} StuffCommand: rhAddr ← 6, c3; IO ← [rhAddr, address + 1], {DES Command} c1; MDR ← temp, L0Disp, c2; rhAddr ← 7, DISP4[StuffRet], c3; StuffMode: rhAddr ← 6, c3; IO ← [rhAddr, address + 3], {DES Mode} c1; MDR ← temp, L0Disp, c2; rhAddr ← 7, DISP4[StuffRet], c3; { BEWARE: You have to wait 6 des clock after storing a command or mode. This code assumes that the hardware provides that delay. } {------------------------------------------------------------------------------------} {Scope loops: Let normal stuff run a while to initialize things..} ScopeWriteLoopIO: IO ← [rhAddr, address + 0], c1; MDR ← temp, c2; Noop, c3; {Dally a while to let AddressStrobe happen.} Noop, c1; Noop, c2; Noop, c3; Noop, c1; Noop, c2; Noop, c3; Noop, c1; Noop, c2; Noop, c3; Noop, c1; Noop, c2; GOTO[ScopeWriteLoopIO], c3; ScopeReadLoopIO: IO ← [rhAddr, address + 0], c1; Noop, c2; temp ← MD, c3; {Dally a while to let AddressStrobe happen.} Noop, c1; Noop, c2; Noop, c3; Noop, c1; Noop, c2; Noop, c3; Noop, c1; Noop, c2; Noop, c3; Noop, c1; Noop, c2; Noop, GOTO[ScopeReadLoopIO], c3;