/ ENIGMA M4 IMPLEMENTATION ON PDP-8
/
/ CONFIGURATION IS ALWAYS DONE THROUGH PDP-8 CONTROL PANEL
/ USE EXAMINE/DEPOSIT TO VERIFY/CHANGE ENIGMA MACHINE CONFIG
/ SEE *0020 BELOW FOR MAP OF OPTIONS
/
/ OPERATION (THERE ARE TWO MODES):
/
/ MINICOMPUTER MODE
/ SET PROGRAM COUNTER TO 0600
/ ENTER LETTER TO ENCIPHER IN SWITCH REGISTER
/ PRESS START OR CONT TO RUN
/ RESULT WILL BE DISPLAYED IN THE ACCUMULATOR
/
/ TELETYPE MODE
/ SET PROGRAM COUNTER TO 0200
/ PRESS START OR CONT TO RUN
/ TYPE CHARACTERS ON TELETYPE AND IT WILL TYPE RESULT
/ ONLY UPPERCASE A-Z WILL BE ACCEPTED
/
/ ALL NUMBERS ARE IN OCTAL UNLESS SPECIFIED OTHERWISE
/ (DECIMAL NUMBERS WILL HAVE A D AFTER THEM LIKE 8D)
/
/ LETTER TO VALUE TABLE:
/ A-01 H-10 O-17 V-26
/ B-02 I-11 P-20 W-27
/ C-03 J-12 Q-21 X-30
/ D-04 K-13 R-22 Y-31
/ E-05 L-14 S-23 Z-32
/ F-06 M-15 T-24
/ G-07 N-16 U-25
/
/
/_PAGES_0,1,2________________________________________________________
/AUTOINCREMENTING POINTER
*0010
PTR1, 0
/ENIGMA M4 MACHINE CONFIGURATION
*0020
INDC1, 01 /ADDRESS 0020 : 01-32 (1D-26D)
INDC2, 01 /ADDRESS 0021 : 01-32 (1D-26D)
INDC3, 01 /ADDRESS 0022 : 01-32 (1D-26D)
INDC4, 01 /ADDRESS 0023 : 01-32 (1D-26D)
ROTR1, 1 /ADDRESS 0024 : 1=BETA, 2=GAMMA
ROTR2, 01 /ADDRESS 0025 : 01-10 (1D-8D)
ROTR3, 02 /ADDRESS 0026 : 01-10 (1D-8D)
ROTR4, 03 /ADDRESS 0027 : 01-10 (1D-8D)
RING1, 01 /ADDRESS 0030 : 01-32 (1D-26D)
RING2, 01 /ADDRESS 0031 : 01-32 (1D-26D)
RING3, 01 /ADDRESS 0032 : 01-32 (1D-26D)
RING4, 01 /ADDRESS 0033 : 01-32 (1D-26D)
REFL, 1 /ADDRESS 0034 : 1=REFL B, 2=REFL C
MODE, 2 /ADDRESS 0035 : 1=MINICOMP, 2=TELETYPE
PLUG1, 00;00 /ADDRESS 0036 : 00 OFF, 01-32 (1D-26D)
PLUG2, 00;00 /ADDRESS 0040 : 00 OFF, 01-32 (1D-26D)
PLUG3, 00;00 /ADDRESS 0042 : 00 OFF, 01-32 (1D-26D)
PLUG4, 00;00 /ADDRESS 0044 : 00 OFF, 01-32 (1D-26D)
PLUG5, 00;00 /ADDRESS 0046 : 00 OFF, 01-32 (1D-26D)
PLUG6, 00;00 /ADDRESS 0050 : 00 OFF, 01-32 (1D-26D)
PLUG7, 00;00 /ADDRESS 0052 : 00 OFF, 01-32 (1D-26D)
PLUG8, 00;00 /ADDRESS 0054 : 00 OFF, 01-32 (1D-26D)
PLUG9, 00;00 /ADDRESS 0056 : 00 OFF, 01-32 (1D-26D)
PLUG10, 00;00 /ADDRESS 0060 : 00 OFF, 01-32 (1D-26D)
PLUG11, 00;00 /ADDRESS 0062 : 00 OFF, 01-32 (1D-26D)
PLUG12, 00;00 /ADDRESS 0064 : 00 OFF, 01-32 (1D-26D)
PLUG13, 00;00 /ADDRESS 0066 : 00 OFF, 01-32 (1D-26D)
/PAGE 0 VARIABLES AND CONSTANTS
CHAR, 0 /HOLDS THE CHARACTER
CINDC, 0 /ROTOR PARAMETER
CROTR, 0 /ROTOR PARAMETER
CRING, 0 /ROTOR PARAMETER
C0032, 0032 /26D
/ROTOR DATA (DO NOT MOVE)
*0107
/"EKMFLGDQVZNTOWYHXUSPAIBRCJ"; ROTOR_1M MILITARY 1
SROTR1, 05;13;15;06;14;07;04;21;26;32;16;24;17;
27;31;10;4030;25;23;20;01;11;02;22;03;12;
/"AJDKSIRUXBLHWTMCQGZNPYFVOE"; ROTOR_2M MILITARY 2
SROTR2, 01;12;04;13;4023;11;22;25;30;02;14;10;27;
24;15;03;21;07;32;16;20;31;06;26;17;05;
/"BDFHJLCPRTXVZNYEIWGAKMUSQO"; ROTOR_3M MILITARY 3
SROTR3, 02;04;06;10;12;14;03;20;22;24;30;26;32;
16;31;05;11;27;07;01;13;4015;25;23;21;17;
/"ESOVPZJAYQUIRHXLNFTGKDCMWB"; ROTOR_4M MILITARY 4
SROTR4, 05;23;17;26;20;32;12;01;31;4021;25;11;22;
10;30;14;16;06;24;07;13;04;03;15;27;02;
/"VZBRGITYUPSDNHLXAWMJQOFECK"; ROTOR_5M MILITARY 5
SROTR5, 26;32;02;22;07;11;24;31;25;20;23;04;16;
10;14;30;01;27;15;12;21;17;06;05;03;4013;
/"JPGVOUMFYQBENHZRDKASXLICTW"; ROTOR_6M MILITARY 6
SROTR6, 12;20;07;26;17;25;15;06;31;21;02;05;4016;
10;32;22;04;13;01;23;30;14;11;03;24;4027;
/"NZJHGRCXMYSWBOUFAIVLPEKQDT"; ROTOR_7M MILITARY 7
SROTR7, 16;32;12;10;07;22;03;30;15;31;23;27;4002;
17;25;06;01;11;26;14;20;05;13;21;04;4024;
/"FKQHTLXOCBJSPDZRAMEWNIUYGV"; ROTOR_8M MILITARY 8
SROTR8, 06;13;21;10;24;14;30;17;03;02;12;23;4020;
04;32;22;01;15;05;27;16;11;25;31;07;4026;
/"LEYJVCNIXWPBQMDRTAKZGFUHOS"; ROTOR_BETA MILITARY M4 BETA
SROTB, 14;05;31;12;26;03;16;11;30;27;20;02;21;
15;04;22;24;01;13;32;07;06;25;10;17;23;
/"FSOKANUERHMBTIYCWLQPZXVGJD"; ROTOR_GAMMA MILITARY M4 GAMMA
SROTG, 06;23;17;13;01;16;25;05;22;10;15;02;24;
11;31;03;27;14;21;20;32;30;26;07;12;04;
/"ENKQAUYWJICOPBLMDXZVFTHRGS", ROTOR_REFL4B MILITARY M4 B REFLECTOR
SREFLB, 05;16;13;21;01;25;31;27;12;11;03;17;20;
02;14;15;04;30;32;26;06;24;10;22;07;23;
/"RDOBJNTKVEHMLFCWZAXGYIPSUQ"; ROTOR_REFL4C MILITARY M4 C REFLECTOR
SREFLC, 22;04;17;02;12;16;24;13;26;05;10;15;14;
06;03;27;32;01;30;07;31;11;20;23;25;21;
*0577
STOP, HLT /FOR MINICOMP MODE THIS HALTS LEAVING
/USER AT ENTRY POINT 0600
/
/
/_PAGE_3_____________________________________________________________
*0600
ENTRY, CLA CLL /GET MODE
TAD MODE
TAD C7777 /SUBTRACT 1
SNA /SKIP NEXT INSTRUCTION IF NON ZERO
JMP MINI /JMP TO MINICOMP MODE
TELE, KSF /SKIP IF READER FLAG SET
JMP .-1 /WAIT FOR KEY
KRB /KBD->ACC, CLEAR FLAG
DCA CHAR /STORE CHAR SO WE CAN TEST IT
TAD CHAR /ALLOW ONLY A-Z (65-90)
TAD C7677 /SUBTRACT 65
SPA CLA /SKIP ON PLUS OR ZERO, CLEAR ACC
JMP TELE /LESS THAN 65, SKIP
TAD CHAR /RESTORE CHAR
TAD C7645 /SUBTRACT 91
SMA CLA /SKIP ON MINUS, CLEAR ACC
JMP TELE /MORE THAN 90, SKIP
CLA CLL /IT IS VALID A-Z, RESTORE CHAR
TAD CHAR
TAD C7700 /SUBTRACT 64 SO A=1 (1 BIASED)
JMS CIPHER /CALL CIPHER
TAD C0100 /ADD 64 SO a=65 (65 BIASED)
TSF /SKIP IF PRINT FLAG SET
JMP .-1 /LOOP UNTIL READY
TLS /PRINT
JMP TELE /WAIT FOR NEXT KEY
MINI, LAS /LOAD AC WITH SWITCH REGISTER
JMS CIPHER /CALL CIPHER
JMP I PSTOP /JMP TO STOP FOR HALT
CIPHER, 0 /SUBROUTINE RETURN ADDRESS STORE HERE
DCA CHAR /STORE ACC IN CHAR
PST, JMS I PSTEP /CALL STEP TO STEP THE ROTORS
PL1, JMS I PSPLUG /CALL PLUGBOARD TO SWAP THE LETTERS
F4, TAD INDC4 /SETUP AND CALL FORWARD ROTOR FOR 4
DCA CINDC
TAD ROTR4
DCA CROTR
TAD RING4
DCA CRING
JMS I PFROTOR
F3, TAD INDC3 /SETUP AND CALL FORWARD ROTOR FOR 3
DCA CINDC
TAD ROTR3
DCA CROTR
TAD RING3
DCA CRING
JMS I PFROTOR
F2, TAD INDC2 /SETUP AND CALL FORWARD ROTOR FOR 2
DCA CINDC
TAD ROTR2
DCA CROTR
TAD RING2
DCA CRING
JMS I PFROTOR
F1, TAD INDC1 /SETUP AND CALL FORWARD ROTOR FOR 1
DCA CINDC
TAD ROTR1
TAD C0010 /BETA/GAMMA ACTUALLY AT 9 AND 10 (+8)
DCA CROTR
TAD RING1
DCA CRING
JMS I PFROTOR
FREFL, CLA CLL IAC /LOAD ACC WITH 1
DCA CINDC
TAD REFL
TAD C0012 /REFLECTOR ACTUALLY AT 11 AND 12 (+10)
DCA CROTR
CLA CLL IAC /LOAD ACC WITH 1
DCA CRING
JMS I PFROTOR /CALL REFLECTOR
R1, TAD INDC1 /SETUP AND CALL REVERSE ROTOR FOR 1
DCA CINDC
TAD ROTR1
TAD C0010 /BETA/GAMMA ACTUALLY AT 9 AND 10 (+8)
DCA CROTR
TAD RING1
DCA CRING
JMS I PRROTOR
R2, TAD INDC2 /SETUP AND CALL REVERSE ROTOR FOR 2
DCA CINDC
TAD ROTR2
DCA CROTR
TAD RING2
DCA CRING
JMS I PRROTOR
R3, TAD INDC3 /SETUP AND CALL REVERSE ROTOR FOR 3
DCA CINDC
TAD ROTR3
DCA CROTR
TAD RING3
DCA CRING
JMS I PRROTOR
R4, TAD INDC4 /SETUP AND CALL REVERSE ROTOR FOR 4
DCA CINDC
TAD ROTR4
DCA CROTR
TAD RING4
DCA CRING
JMS I PRROTOR
PL2, JMS I PSPLUG /CALL PLUGBOARD TO SWAP THE LETTERS
STR1, CLA CLL /LOAD CHAR INTO ACC TO RETURN
TAD CHAR
JMP I CIPHER /RETURN FROM SUBROUTINE
/THIS PAGE VARIABLES AND CONSTANTS
C0010, 0010 /8D
C0012, 0012 /10D
C0100, 0100 /64D
C7700, 7700 /-64D
C7645, 7645 /-91D
C7677, 7677 /-65D
C7777, 7777 /-1D
PSTOP, STOP
PSTEP, STEP
PSPLUG, SPLUG
PFROTOR,FROTOR
PRROTOR,RROTOR
/
/
/_PAGE_4_____________________________________________________________
*1000
SPLUG, 0 /SUBROUTINE RETURN ADDRESS STORED HERE
CLA CLL
TAD PPLUG1 /RESET PLUGBOARD POINTER PTR1
DCA PTR1
TAD COUNT /SETUP COUNT AND INDEX FOR LOOP
CIA /NEGATE (INDEX COUNTS UP TO 0)
DCA INDEX1
LOOP, TAD I PTR1 /CHECK PLUGBOARD PAIR FIRST VALUE
SNA /SKIP NEXT INSTRUCTION IF NON ZERO
JMP DSBL /THIS PLUGBOARD PAIR IS DISABLED
CIA /NOT DISABLED, CONTINUE COMPARING TO OUR CHAR
TAD CHAR /ADD CHARACTER, IF IT MATCHES ACC WILL BE 0
SNA /SKIP NEXT INSTRUCTION IF NON ZERO
JMP MATCH1 /MATCH FIRST VALUE IN PAIR
CLA CLL /NOT ZERO, NO MATCH, CLEAR ACC
TAD I PTR1 /GET SECOND PAIR VALUE
CIA /COMPARE IT TO OUR CHARACTER
TAD CHAR
SNA /SKIP NEXT INSTRUCTION IF NON ZERO
JMP MATCH2 /IT IS ZERO, MATCH SECOND VALUE IN PAIR
LOOP2, CLA CLL /NO MATCH THIS PAIR
ISZ INDEX1
JMP LOOP
JMP I SPLUG /RETURN FROM SUBROUTINE
DSBL, TAD I PTR1 /THIS PAIR IS DISABLED, SKIP OTHER HALF
JMP LOOP2
MATCH1, TAD I PTR1 /FIRST WORD MATCHES, OBTAIN OTHER HALF
DCA CHAR
JMP I SPLUG /RETURN FROM SUBROUTINE
MATCH2, CLA CLL CMA RAL /SECOND WORD MATCHES, ACC=7776 (-2)
TAD PTR1 /ADD PTR1 TO ACC
DCA PTR1 /DEPOSIT PTR1-2 TO GET FIRST VALUE
JMP MATCH1
STEP, 0 /SUBROUTINE RETURN ADDRESS STORED HERE
CLA CLL /IS ROTOR3 IN NOTCH?
TAD ROTR3
JMS I PRPTR /SET ROTOR POINTER TO CORRECT ROTOR
TAD INDC3
DCA TEMP1
TAD I TEMP1
AND C4000 /KEEP ONLY NOTCH BIT
SZA /SKIP ON ZERO
JMP STEP3 /YES - 3 RIGHT ROTORS MOVE
TAD ROTR4 /IS ROTOR4 IN NOTCH?
JMS I PRPTR /SET ROTOR POINTER TO CORRECT ROTOR
TAD INDC4
DCA TEMP1
TAD I TEMP1
AND C4000 /KEEP ONLY NOTCH BIT
SZA /SKIP ON ZERO
JMP STEP2 /YES - 2 RIGHT ROTORS MOVE
JMP STEP1 /NO - 1 RIGHT ROTOR MOVES
STEP3, CLA CLL /STEP ROTOR 2
TAD INDC2
IAC
JMS I PRBACK /IF OVERFLOW ROLL IT BACK TO 1
DCA INDC2
/INTENTIONAL LACK OF JMP STEPS REMAINING
STEP2, CLA CLL /STEP ROTOR 3
TAD INDC3
IAC
JMS I PRBACK /IF OVERFLOW ROLL IT BACK TO 1
DCA INDC3
/INTENTIONAL LACK OF JMP STEPS REMAINING
STEP1, CLA CLL /STEP ROTOR 4
TAD INDC4
IAC
JMS I PRBACK /IF OVERFLOW ROLL IT BACK TO 1
DCA INDC4
/INTENTIONAL LACK OF JMP STEPS REMAINING
STEP0, JMP I STEP /RETURN FROM SUBROUTINE
/THIS PAGE VARIABLES AND CONSTANTS
C4000, 4000 /NOTCH BIT IN ROTORS
COUNT, 15 /13D
INDEX1, 0 /0D
PPLUG1, PLUG1-1 /POINTER TO WORD BEFORE PLUGBOARD
TEMP1, 0
PRPTR, RPTR
PRBACK, RBACK
/
/
/_PAGE_5_____________________________________________________________
*1200
FROTOR, 0
TAD CRING /CINDC+26-CRING+CHAR
CIA
TAD CINDC
TAD C0032
TAD CHAR
JMS RBACK
DCA TEMP2
TAD CROTR
JMS RPTR /SET ROTOR POINTER TO CORRECT ROTOR
TAD TEMP2
DCA TEMP2
TAD I TEMP2
AND C0077
CIA
TAD CINDC
CIA
TAD CRING
TAD C0032
JMS RBACK
DCA CHAR
JMP I FROTOR /RETURN FROM SUBROUTINE
RROTOR, 0
DCA TEMP3 /STORE 0
TAD C0032
CIA /NEGATE (INDEX COUNTS UP TO 0)
DCA INDEX2
LOOP3, ISZ TEMP3
TAD CRING /CINDC+26-CRING+CHAR
CIA
TAD CINDC
TAD C0032
TAD TEMP3
JMS RBACK
DCA TEMP2
TAD CROTR
JMS RPTR /SET ROTOR POINTER TO CORRECT ROTOR
TAD TEMP2
DCA TEMP2
TAD I TEMP2
AND C0077
CIA
TAD CINDC
CIA
TAD CRING
TAD C0032
JMS RBACK
CIA /COMPARE BY NEGATING
TAD CHAR /ADD CHARACTER, IF IT MATCHES ACC WILL BE 0
SNA /SKIP NEXT INSTRUCTION IF NON ZERO
JMP MATCH3 /MATCH FIRST VALUE IN PAIR
ISZ INDEX2
CLA CLL
JMP LOOP3
MATCH3, TAD TEMP3
DCA CHAR
JMP I RROTOR /RETURN FROM SUBROUTINE
RPTR, 0 /CALCULATE ROTOR POINTER
CIA
DCA TEMP4
PTRLP, TAD C0032
ISZ TEMP4
JMP PTRLP
TAD C0054
JMP I RPTR /RETURN FROM SUBROUTINE
RBACK, 0 /IF ACC>32, SUBTRACT 32 UNTIL IT IS
RBACK2, DCA TEMP4
TAD TEMP4
TAD C7746
SMA SZA
JMP RBACK2
CLA CLL
TAD TEMP4
JMP I RBACK /RETURN FROM SUBROUTINE
/THIS PAGE VARIABLES AND CONSTANTS
C0054, 0054 /CONSTANT TO GENERATE ROTOR PTR
C0077, 0077 /63D
C7746, 7746 /-26D
TEMP4, 0
INDEX2, 0
TEMP2, 0
TEMP3, 0
$ENTRY