{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;