;; Press Microcode -- "Main Microcode" (Font, PreScan passes)

; last modified by Ramshaw, March 30, 1981  2:51 PM
; -  patches to outermost loop and BCPL return code, (one more instruction).
; modified by Butterfield, March 7, 1980  4:21 PM
; - revamp Routine23's loop control - 3/7
; - use PressFloatMc's exit sequence for Routine23 - 3/6/80

%0, 1777, 37, TRAP1;	RAM trap location
$LREG	$R40;
#TriConMc.Mu;
!7,10,RRSHFT,RRSHFT2,,RRSHFT4,,,,RRSHFT8;
!7,10,RLSHFT,RLSHFT2,,RLSHFT4,,,,RLSHFT8;
!17,20,PStepDone,RMSK1,,RMSK2,,,,RMSK4,,,,,,,,RMSK8;
!1,2,ContinueCount,CountDone;
!1,2,ContinueI,NextPStep;
!1,2,ContinueJ,NextI;

#PressFloatMc.Mu;

; modified to include Routine23 (Rotor), and several routines removed

;  //-------------------------------------------------------------------------
;  let Rotor(Page) be  // Page => 16 16*16 bit squares.  All are rotated!
;  //-------------------------------------------------------------------------
;  [
;  let masktable=table [ #125252;#146314;0;#170360;0;0;0;#177400]
;
;  for count = 15 to 0 by -1 do
;     [
;     let pStepMinus1 = 15  // macro pStep = pStepMinus1 + 1
;     while pStepMinus1 gr 0 do
;        [
;        PstepMinus1 = pStepMinus1 rshift 1
;        let mask1 = masktable!pStepMinus1
;        for i = 20 - pStep - pStep to 0 by - pStep - pStep
;           [
;           let j = pStepMinus1
;           until j ls 0 do
;              [
;              let Word = Page + i + j
;              let mask2 = not mask1
;              let t1 = Word!0
;              let Word2 = Word + Pstep
;              let t2 = Word2!0
;              Word!0=(t1&mask1)+((t2 rshift Pstep)&mask2)
;              Word2!0=(t2&mask2)+((t1 lshift Pstep)&mask1)
;              j=j-1
;              ]
;           ]
;        ]
;     Page=Page+16
;     ]
;  ]

$PAGE		$R3;		AC0 synonym
$PSTEP		$R2;		AC1 (R register for shifts)
$RSLT		$R15;		R register for shifts
$RSLT2		$R16;		R register for shifts
$WORD		$R17;		R register for shifts
$J		$R6;		R register for BUS=0 -- shared with PC
$MASK1		$R70;
$MASK2		$R67;
$WORD2		$R66;
$I		$R65;
$T1		$R64;
$T2		$R63;
$COUNT		$R62;

Routine23:
  L← 17;  Initial COUNT and PSTEP
NextCount:
  COUNT← L;
  L← 17, SH<0;
NextPStep:
  PSTEP← L RSH 1, :ContinueCount;   !ContinueCount,CountDone;
ContinueCount:
  SINK← LREG, BUS;  BUS on the last value of PSTEP
  L← T← MASK1, :PStepDone;  !PStepDone,RMSK1,RMSK2,RMSK4,RMSK8

PStepDone:
  T← 20;
  L← PAGE +T;
  PAGE← L;
  L← COUNT -1, :NextCount;

CountDone:
  L←AC3+1, :PCgetsLret;  use PressFloat's error return sequence;

RMSK8:	L←177400, TASK, :RMSK;
RMSK4:	L←170360, TASK, :RMSK;
RMSK2:	RSLT←L RSH 1;
	L←RSLT;
RMSK1:	RSLT←L RSH 1;
	L←RSLT XOR T, TASK;
RMSK:	MASK1←L;		**

  L← 20;
NextI:
  T← PSTEP;
  L← LREG -T-1;
  L← LREG -T-1;
  I← L, L← T, SH<0;
NextJ:
  J← L, SH<0, :ContinueI;  !ContinueI,NextPStep
ContinueI:
  T← L← I, :ContinueJ;  !ContinueJ,NextI;
ContinueJ:

;word=page+i+j
	L←PAGE+T;
	T←J;
;t1=word!0
	MAR←L←LREG+T;
	WORD←L,T←0-1;
;mask2=not mask1
	L←MASK1 XOR T;
	MASK2←L;
	L←T←MD, TASK;
	T1←L;		**

	T←T1;
	L←MASK2 AND T;		(by the way, mask2=mask1 rshift pstep)

;word2!0=(t2&mask2)+((t1 lshift pstep)&mask1)
	SINK←PSTEP, BUS;
	RSLT2←L LSH 1, :RLSHFT;	!RLSHFT,2,4,8

RLSHFT4: T←RSLT2;
	L←RSLT2+T, TASK;
	RSLT2←L LSH 1;		**
RLSHFT2: T←RSLT2;
	L←RSLT2+T, TASK;
	RSLT2←L, :RLSHFT;	**
RLSHFT8: RSLT2←L LCY 8;

RLSHFT:	T←PSTEP;
;word2=word+Pstep; t2=Word2!0
	MAR←L←WORD+T+1;  ("+1" because PSTEP is really PStepMinus1)
	WORD2←L;
	L←MD;
	T2←L;

;word!0=(t1&mask1)+((t2 rshift pstep)&mask2)
	SINK←PSTEP, BUS, TASK;
	RSLT←L RSH 1, :RRSHFT;	** !RRSHFT,2,4,8
RRSHFT4: L←RSLT, TASK;
	RSLT←L RSH 1;		**
	L←RSLT, TASK;
	RSLT←L RSH 1;		**
RRSHFT2: L←RSLT, TASK;
	RSLT← L RSH 1, :RRSHFT;	**
RRSHFT8: L←T2, TASK;
	RSLT←L LCY 8;		**

RRSHFT:	T←MASK2;
	L←RSLT AND T;

	T←T1;
	MAR←WORD;
	T←MASK1.T;
	L←LREG OR T, TASK;
	MD←LREG;		**

	T←T2;
	MAR←WORD2;
	T←MASK2.T;
	L←RSLT2 OR T, TASK;
	MD←LREG;		**

;j=j-1; repeatwhile j ge 0
	L← J -1, :NextJ;