;  Row Rotation Microcode for Spruce

;  This code, merged with OrbitMc and TriconBodyMc into SpruceMc, will rotate eight rows
;  of data bytes, producing (in a new location) the rotated values.

; Input:
;	AC1: start address-1
;	AC2: ending address-1
;	AC3: words per row (WPR)

; Each row contains WPR words. In the output array, the first output byte is formed from the
;  high-order bits of the first words of each input row, the second byte comes from bit 1, etc; in
;  other words, "horizontal" samples have been converted to "vertical" samples.

!1,2, NEXTCOL, ROTDONE;		Columns exhausted test (outer)
!1,2, NEXTWD, WDDONE;		All registers filled from memory test (inner)
!1,2, NextIt, TRYNEXT;		Rows exhausted test (inner)
!1,2, ItGo, Update;			Inner-Inner loop finish test

ROWROT: L←WPR-1, :TESTDONE;			let RowRotate(inBufM1, outBufM1, wPL) be
TRYNEXT: L←RCNT-1;				   for column = 1 to wPL do
TESTDONE: RCNT←L, SH<0; 				      [oneColumn
	L←INBUF+1, :NEXTCOL; [NEXTCOL, ROTDONE]
NEXTCOL: INBUF←L, TASK;
	INADR←L;	**			      inBufM1, inAdr = inBufM1+1, inBufM1
	L←7, :TESTWD;			      for i = 0 to 7 do
TRYWD: L←WDCNT-1;				[
TESTWD: WDCNT←L, SH<0;				SHR!(7-i) = @inAdr
	MAR←T←INADR, :NEXTWD; [NEXTWD, WDDONE]
NEXTWD: L←WPR+T;					inAdr = inAdr+wPL
	INADR←L;					]
	SINK←WDCNT, BUS;
!7,10, LDSH1, LDSH2, LDSH3, LDSH4, LDSH5, LDSH6, LDSH7, LDSH8;
	L←MD, TASK, :LDSH1;
; Register load dispatch
LDSH1: SHR1←L, :TRYWD; **
LDSH2: SHR2←L, :TRYWD; **
LDSH3: SHR3←L, :TRYWD; **
LDSH4: SHR4←L, :TRYWD; **
LDSH5: SHR5←L, :TRYWD; **
LDSH6: SHR6←L, :TRYWD; **
LDSH7: SHR7←L, :TRYWD; **
LDSH8: SHR8←L, :TRYWD; **

WDDONE: L←7, :TESTIT;				      for wd = 1 to 8 do
TRYIT: L←WDCNT-1;
TESTIT: WDCNT←L, SH<0;					[oneOutputWord
	L←17,:NextIt; [NextIt, TRYNEXT]
ItLoop: L←BITCNT-1, BUS=0;
NextIt: SINK←LASTL, BUS, :ItGo;	[ItGo, Update]
!17, 10, UseSH8, UseSH7, UseSH6, UseSH5, UseSH4, UseSH3, UseSH2, UseSH1;
ItGo:	 BITCNT←L, :UseSH8;
UseSH1:  T←L←SHR1;
	SHR1←L LSH 1, :ItDo;					HOLD = HOLD lshift 1 +
UseSH2: T←L←SHR2;						HOLD = HOLD lshift 1 +
	SHR2←L LSH 1, :ItDo;						   SHR2 rshift 15
UseSH3: T←L←SHR3;						  .  .  .
	SHR3←L LSH 1, :ItDo;
UseSH4: T←L←SHR4;
	SHR4←L LSH 1, :ItDo;
UseSH5: T←L←SHR5;
	SHR5←L LSH 1, :ItDo;
UseSH6: T←L←SHR6;
	SHR6←L LSH 1, :ItDo;
UseSH7: T←L←SHR7;
	SHR7←L LSH 1, :ItDo;
UseSH8: T←L←SHR8;						HOLD = HOLD lshift 1 +
	SHR8←L LSH 1, :ItDo;						   SHR8 rshift 15
ItDo:	L←HOLD, TASK;					   	   SHR1 rshift 15
	HOLD←L MLSH 1, :ItLoop;	**				SHR1 = SHR1 lshift 1

!1777, 1, KillBus; some things have to change if anybody else needs 1777
Update:	 MAR←L←OUTBUF+1, :KillBus;
KillBus: OUTBUF←L, TASK;
	; available if can also do task
	MD←HOLD, :TRYIT;	**

ROTDONE: :NOVEM;				    // return

;; DCS, March 6, 1978  2:57 PM, Created to speed up Spruce bit map processing
;; March 6, 1978  6:27 PM, repair initial bugs
;; March 8, 1978  3:54 PM, word fetch in a loop, reverse order of register fill to reverse rotation direction
;; March 9, 1978  2:18 PM, tisk where you used to task, and vice versa
;; October 17, 1978  3:12 PM, collapse open code into loop
;; October 20, 1978  11:58 AM, move defs to SpruceDefs.Mu
;; November 6, 1978  9:51 PM, UseSH* table was backward
;;