; MaxcImpConv.mu -- conversion between Maxc and Imp packet formats

;	Last modified April 13, 1978  10:49 AM

; This microcode runs only on Alto-I.
; It contains emulator-level microcode, intended to be called via trap
; opcodes, for converting between the Imp and Maxc2 data formats.
; The Imp format is just a continuous bit stream, packed into 16-bit words.
; The Maxc format is the same continuous bit stream, but packed either
; 32 or 36 bits per Maxc word and stored in Alto memory in the correct
; format for (36-bit) Maxc memory operations.

; All instructions assume that the first 72 bits of a message (Imp and
; Host leader) have been dealt with by the software.  Thus, transfers start
; with the 73rd bit, which happens to fall in the middle of an Alto word
; in Imp format.

; In the descriptions of block formats:
;	00, 01, etc., are names for 4-bit nibbles.
;	** is a nibble whose value is undefined (source) or may be
;	   clobbered arbitrarily (destination).
;	XX is a nibble that must be preserved (destination).
;	-- is a zero nibble.

!1, 2, T32May, T32No;
!1, 2, T32Int, T32Dis;
!1, 2, CT32Lp, CT32Dn;
!1, 2, T36May, T36No;
!1, 2, T36Int, T36Dis;
!1, 2, CT36Lp, CT36Dn;
!1, 2, CT36L1, CT36D1;
!1, 2, CT36L2, CT36D2;
!1, 2, CT36L3, CT36D3;
!1, 2, F32May, F32No;
!1, 2, F32Int, F32Dis;
!1, 2, CF32Lp, CF32Dn;
!1, 2, F36May, F36No;
!1, 2, F36Int, F36Dis;
!1, 2, CF36Lp, CF36Dn;
!1, 2, CF36L1, CF36D1;
!1, 2, CF36L2, CF36D2;
!1, 2, CF36L3, CF36D3;

$170000	$170000;
$177777	$177777;

; Convert Imp message to Maxc 32-bit format.
; It is assumed that the first 8 bits of the source block have
; already been consumed.
; AC0/ first destination address
; AC1/ first source address
; AC3/ Maxc word count

; Source block format:
;	** ** 00 01	<- AC1
;	02 03 04 05
;	06 07 ** **

; Destination block format:
;	00 01 02 03	<- AC0
;	04 05 06 07
;	** ** ** **

ConvTo32:
	MAR← AC1;			Fetch (** ** 00 01) from source block
	T← 377;				Mask just right byte
	L← MD AND T, TASK;
	SAD← L;				Save as leftover

; Main loop.
; AC1 points to last word read, AC0 to next word to write.
; Each time through the loop, AC1 is incremented by 2, AC0 incremented by 3,
; and AC3 decremented by 1.

; Store first 16 bits of Maxc word (00 01 02 03).
; SAD has (-- -- 00 01).
CT32Lp:	MAR← T← AC1+1;			Fetch next source word (02 03 04 05)
	L← NWW, BUS=0;			Test for interrupt
	L← T, T← 377, SH<0, :T32May;	[T32May, T32No]
T32No:	AC1← L;				Update source address
T32Dis:	L← MD AND T, T← MD;		L← (-- -- 04 05), T← (02 03 04 05)
	T← 177400 . T;			T← (02 03 -- --)
	T← SAD OR T;			T← (02 03 00 01)
	MAR← AC0;			Store into destination block
	SAD← L, L← T;			SAD← new leftover (-- -- 04 05)
	MTEMP← L LCY 8;			MTEMP← (00 01 02 03)
	TASK;
	MD← MTEMP;

; Now store second 16 bits of Maxc word (04 05 06 07).
; SAD has (-- -- 04 05).
	MAR← L← AC1+1;			Fetch next source word (06 07 00 01)
	AC1← L;
	T← 377;
	L← MD AND T, T← MD;		L← (-- -- 00 01), T← (06 07 00 01)
	T← 177400 . T;			T← (06 07 -- --)
	T← SAD OR T;			T← (06 07 04 05)
	SAD← L, L← T;			SAD← new leftover (-- -- 00 01)
	MAR← T← AC0+1;			Store into destination block
	MTEMP← L LCY 8, T← 0+T+1;	MTEMP← (04 05 06 07)
	L← AC3-1;			Decrement Maxc word count
	MD← MTEMP;			Store (04 05 06 07)
	AC3← L, L← 0+T+1, SH=0, TASK;	Update count, skip over unused word
	AC0← L, :CT32Lp;		[CT32Lp, CT32Dn]

; Here when done
CT32Dn:	L← PC, SWMODE, :CnvXit;

; Here when possible interrupt (SH<0 branch pending)
T32May:	AC1← L, :T32Int;		[T32Int, T32Dis]
T32Int:	L← AC1-1, TASK;			Back up source pointer
	AC1← L;
CnvInt:	L← PC-1, SWMODE;		Back up PC
CnvXit:	PC← L, :START;

; Convert Imp message to Maxc 36-bit format.
; It is assumed that the first 8 bits of the source block have
; already been consumed.
; AC0/ first destination address
; AC1/ first source address
; AC3/ Maxc word count

; Source block format:
;	** ** 00 01	<- AC1
;	02 03 04 05
;	06 07 08 09
;	10 11 12 13
;	14 15 16 17
;	18 19 20 21
;	22 23 24 25
;	26 27 28 29
;	30 31 32 33
;	34 35 ** **

; Destination block format:
;	00 01 02 03	<- AC0
;	04 05 06 07
;	08 ** ** **
;	09 10 11 12
;	13 14 15 16
;	17 ** ** **
;	18 19 20 21
;	22 23 24 25
;	26 ** ** **
;	27 28 29 30
;	31 32 33 34
;	35 ** ** **

ConvTo36:
	MAR← AC1;			Fetch (** ** 00 01) from source block
	L← AC0-1;			Back up destination to first word -1
	AC0← L;
	T← 377;				Mask just right byte
	L← MD AND T, TASK;
	SAD← L;				Save as leftover

; Main loop.
; Each iteration converts 9 Alto words to 4 Maxc words (the latter are
; stored in 12 Alto words).  Hence each iteration increments AC1 by 9,
; increments AC0 by 12, and decrements AC3 by 4.
; AC1 points to last word read, AC0 to last word written.

; Store first 16 bits of first Maxc word (00 01 02 03).
; SAD has (-- -- 00 01)
CT36Lp:	MAR← T← AC1+1;			Fetch next source word (02 03 04 05)
	L← NWW, BUS=0;			Test for interrupt
	L← T, T← 377, SH<0, :T36May;	[T36May, T36No]
T36No:	AC1← L;				Update source address
T36Dis:	L← MD AND T, T← MD;		L← (-- -- 04 05), T← (02 03 04 05)
	T← 177400 . T;			T← (02 03 -- --)
	T← SAD OR T;			T← (02 03 00 01)
	SAD← L, L← T;			SAD← new leftover (-- -- 04 05)
	MAR← T← AC0+1;			Store into destination block
	MTEMP← L LCY 8, L← T;		MTEMP← (00 01 02 03)
	AC0← L, TASK;
	MD← MTEMP;

; Store second 16 bits of first Maxc word (04 05 06 07).
; SAD has (-- -- 04 05).
	MAR← L← AC1+1;			Fetch next source word (06 07 08 09)
	AC1← L;
	T← 377;
	L← MD AND T, T← MD;		L← (-- -- 08 09), T← (06 07 08 09)
	T← 177400 . T;			T← (06 07 -- --)
	T← SAD OR T;			T← (06 07 04 05)
	SAD← L LCY 8, L← T;		SAD← new leftover (08 09 -- --)
	MAR← T← AC0+1;			Store into destination block
	MTEMP← L LCY 8, L← T;		MTEMP← (04 05 06 07)
	AC0← L, TASK;
	MD← MTEMP;

; Store last 4 bits of first Maxc word (08 ** ** **).
; SAD has (08 09 -- --).
	MAR← L← AC0+1;			Store into destination block
	AC0← L;
	L← AC3-1;			Decrement and test Maxc word count
	AC3← L, SH=0, TASK;
	MD← SAD, :CT36L1;		[CT36L1, CT36D1] Store (08 ** ** **)

; Store first 16 bits of second Maxc word (09 10 11 12).
; SAD has (08 09 -- --)
CT36L1:	T← SAD;				T← (08 09 -- --)
	T← 7400 . T;			T← (-- 09 -- --)
	MAR← L← AC1+1;			Fetch next source word (10 11 12 13)
	AC1← L, L← T;
	XREG← L LCY 8;			XREG← (-- -- -- 09)
	T← 17;
	L← MD AND T, T← MD;		L← (-- -- -- 13), T← (10 11 12 13)
	SAD← L;				SAD← (-- -- -- 13)
	T← 177760 . T;			T← (10 11 12 --)
	L← T← XREG OR T;		L← T← (10 11 12 09)
	XREG← L MRSH 1;			Right-cycle (10 11 12 09) 4 bits
	L← T← XREG;
	XREG← L MRSH 1;
	L← T← XREG, TASK;
	XREG← L MRSH 1;

	MAR← L← AC0+1;			Store into destination block
	AC0← L;
	L← T← XREG;
	XREG← L MRSH 1;			XREG← (09 10 11 12)
	MD← XREG;

; Store second 16 bits of second Maxc word (13 14 15 16).
; SAD has (-- -- -- 13)
	MAR← L← AC1+1;			Fetch next source word (14 15 16 17)
	AC1← L;
	T← 17;
	L← MD AND T, T← MD;		L← (-- -- -- 17), T← (14 15 16 17)
	XH← L LSH 1;			XH← (-- -- -- 17) LSH 1
	T← 177760 . T;			T← (14 15 16 --)
	L← T← SAD OR T, TASK;		L← T← (14 15 16 13)
	XREG← L MRSH 1;			Right-cycle it 4 bits

	L← T← XREG;
	XREG← L MRSH 1;
	L← T← XREG, TASK;
	XREG← L MRSH 1;

	MAR← L← AC0+1;			Store into destination block
	AC0← L;
	L← T← XREG;
	XREG← L MRSH 1;			XREG← (13 14 15 16)
	MD← XREG;

; Store last 4 bits of second Maxc word (17 ** ** **).
; XH has (-- -- -- 17) LSH 1.
	L← T← XH;			= (-- -- -- 17) LSH 1.
	L← T← M+T+1;			= 4*X +1, where X = (-- -- -- 17)
	L← T← M+T+1;			= 8*X +3
	L← M+T+1;			= 16*X +7 = (-- -- 17 **)
	SAD← L LCY 8;			SAD← (17 ** -- --)
	MAR← L← AC0+1;			Store into destination block
	AC0← L;
	L← AC3-1;			Decrement and test Maxc word count
	AC3← L, SH=0, TASK;		Update count, done?
	MD← SAD, :CT36L2;		[CT36L2, CT36D2] Store (17 ** ** **)

; Store first 16 bits of third Maxc word (18 19 20 21).
; There are no leftover bits.
CT36L2:	MAR← L← AC1+1;			Fetch next source word (18 19 20 21)
	AC1← L;
	T← MD;				T← (18 19 20 21)
	MAR← L← AC0+1;			Store into destination block
	AC0← L, L← T, TASK;
	MD← M;				Store (18 19 20 21)

; Store second 16 bits of third Maxc word (22 23 24 25).
; There are no leftover bits.
	MAR← L← AC1+1;			Fetch next source word (22 23 24 25)
	AC1← L;
	T← MD;				T← (22 23 24 25)
	MAR← L← AC0+1;			Store into destination block
	AC0← L, L← T, TASK;
	MD← M;				Store (22 23 24 25)

; Store last 4 bits of third Maxc word (26 ** ** **).
; There are no leftover bits.
	MAR← L← AC1+1;			Fetch next source word (26 27 28 29)
	AC1← L;
	T← 7777;
	L← MD AND T, T← MD;		L← (-- 27 28 29), T← (26 27 28 29)
	SAD← L;				SAD← new leftover (-- 27 28 29)
	MAR← L← AC0+1;			Store into destination block
	AC0← L;
	L← AC3-1;			Decrement and test Maxc word count
	AC3← L, L← T, SH=0, TASK;	Update it, done?
	MD← M, :CT36L3;			[CT36L3, CT36D3] Store (26 ** ** **)

; Store first 16 bits of fourth Maxc word (27 28 29 30).
; SAD has (-- 27 28 29).
CT36L3:	MAR← L← AC1+1;			Fetch next source word (30 31 32 33)
	AC1← L;
	T← 7777;
	L← MD AND T, T← MD;		L← (-- 31 32 33), T← (30 31 32 33)
	T← 170000 . T;			T← (30 -- -- --)
	T← SAD OR T;			T← (30 27 28 29)
	SAD← L, L← T;			SAD← new leftover (-- 31 32 33)
	XREG← L MLSH 1;			Left cycle (30 27 28 29) 4 bits
	L← T← XREG;
	XREG← L MLSH 1;
	L← T← XREG, TASK;
	XREG← L MLSH 1;

	MAR← L← AC0+1;			Store into destination block
	AC0← L;
	L← T← XREG;
	XREG← L MLSH 1;			XREG← (27 28 29 30)
	MD← XREG;

; Store second 16 bits of fourth Maxc word (31 32 33 34).
; SAD has (-- 31 32 33).
	MAR← L← AC1+1;			Fetch next source word (34 35 00 01)
	AC1← L;
	T← 7777;
	L← MD AND T, T← MD;		L← (-- 35 00 01), T← (34 35 00 01)
	T← 170000 . T;			T← (34 -- -- --)
	T← SAD OR T;			T← (34 31 32 33)
	SAD← L, L← T, TASK;		SAD← new leftover (-- 35 00 01)
	XREG← L MLSH 1;			Left cycle (34 31 32 33) 4 bits

	L← T← XREG;
	XREG← L MLSH 1;
	L← T← XREG, TASK;
	XREG← L MLSH 1;

	MAR← L← AC0+1;			Store into destination block
	AC0← L;
	L← T← XREG;
	XREG← L MLSH 1;			XREG← (31 32 33 34)
	MD← XREG;

; Store last 4 bits of fourth Maxc word (35 ** ** **).
; SAD has (-- 35 00 01).
	T← 377;
	L← SAD AND T, T← SAD;		L← (-- -- 00 01), T← (-- 35 00 01)
	SAD← L, L← T;			SAD← (-- -- 00 01) for next iteration
	L← T← M+T+1;			= 2*X +1, where X = (-- 35 00 01)
	L← T← M+T+1;			= 4*X +3
	L← T← M+T+1;			= 8*X +7
	T← M+T+1;			= 16*X +15 = (35 ** ** **)
	MAR← L← AC0+1;			Store into destination block
	AC0← L;
	L← AC3-1;			Decrement and test word count
	AC3← L, L← T, SH=0, TASK;
	MD← M, :CT36Lp;			[CT36Lp, CT36Dn] Store (35 ** ** **)

; Here when done
CT36Dn:	L← PC, SWMODE, :CnvXit;
CT36D1:	L← PC, SWMODE, :CnvXit;
CT36D2:	L← PC, SWMODE, :CnvXit;
CT36D3:	L← PC, SWMODE, :CnvXit;

; Here when possible interrupt (SH<0 branch pending)
T36May:	AC1← L, :T36Int;		[T36Int, T36Dis]

; Here to interrupt
T36Int:	L← AC0+1;			Un-back-up destination pointer
	AC0← L, :T32Int;		Go back up source pointer and quit

; Convert Imp message from Maxc 32-bit format.
; It is assumed that the first 8 bits of the destination block have
; already been filled.
; AC0/ first destination address
; AC1/ first source address
; AC3/ Maxc word count
; Note:  The last 8 bits of the block are not transferred.  The caller
; must specify a Maxc word count one larger than the number of Maxc
; words actually present, and provide 2 words of extra space in the
; destination block.

; Source block format:
;	00 01 02 03	<- AC1
;	04 05 06 07
;	** ** ** **

; Destination block format:
;	XX XX 00 01	<- AC0
;	02 03 04 05
;	06 07 ** **

ConvFrom32:
	MAR← T← AC0;			Fetch first word of destination block
	L← 177777+T;			Back up destination pointer
	AC0← L;
	T← 177400;
	L← MD AND T, TASK;		L← (XX XX -- --)
	SAD← L LCY 8;			SAD← (-- -- XX XX)

; Main loop.
; AC1 points to next word to read, AC0 at last destination word written.
; Each time through the loop, AC0 is incremented by 2, AC1 incremented by 3,
; and AC3 decremented by 1.

; Transfer first 16 bits of source (00 01 02 03).  SAD has (-- -- XX XX)
CF32Lp:	MAR← AC1;			Fetch next source word (00 01 02 03)
	L← NWW, BUS=0;			Test for interrupts
	T← 377, SH<0, :F32May;		[F32May, F32No]
F32No:	L← MD AND T, T← MD;		L← (-- -- 02 03), T← (00 01 02 03)
F32Dis:	T← 177400 . T;			T← (00 01 -- --)
	T← SAD OR T;			T← (00 01 XX XX)
	SAD← L, L← T;			SAD← new leftover (-- -- 02 03)
	MAR← T← AC0+1;			Store into destination block
	MTEMP← L LCY 8, L← T;		MTEMP← (XX XX 00 01)
	AC0← L, TASK;
	MD← MTEMP;

; Transfer second 16 bits of source (04 05 06 07).  SAD has (-- -- 02 03)
	MAR← T← AC1+1;			Fetch next source word (04 05 06 07)
	L← 2+T;				Skip over unused word
	AC1← L;
	T← 377;
	L← MD AND T, T← MD;		L← (-- -- 06 07), T← (04 05 06 07)
	T← 177400 . T;			T← (04 05 -- --)
	T← SAD OR T;			T← (04 05 02 03)
	SAD← L, L← T;			SAD← new leftover (-- -- 06 07)
	MTEMP← L LCY 8;			MTEMP← (02 03 04 05)
	MAR← L← AC0+1;			Store into destination block
	AC0← L;
	L← AC3-1;			Decrement and test Maxc word count
	AC3← L, SH=0, TASK;
	MD← MTEMP, :CF32Lp;		[CF32Lp, CF32Dn] Store (02 03 04 05)

; Here when done.
CF32Dn:	L← PC, SWMODE, :CnvXit;

; Here when possible interrupt (SH<0 branch pending)
F32May:	L← MD AND T, T← MD, :F32Int;	[F32Int, F32Dis]
F32Int:	MAR← T← AC0+1;			Store leftover word
	L← SAD;				L← (-- -- XX XX)
	SAD← L LCY 8, L← T;		SAD← (XX XX -- --)
	AC0← L, TASK;
	MD← SAD, :CnvInt;		Go back up PC and quit

; Convert Imp message from Maxc 36-bit format.
; It is assumed that the first 8 bits of the destination block have
; already been filled.
; AC0/ first destination address
; AC1/ first source address
; AC3/ Maxc word count
; Note:  The last few bits of the block are not transferred.  The caller
; must specify a Maxc word count one larger than the number of Maxc
; words actually present, and provide 3 words of extra space in the
; destination block.

; Source block format:
;	00 01 02 03	<- AC1
;	04 05 06 07
;	08 ** ** **
;	09 10 11 12
;	13 14 15 16
;	17 ** ** **
;	18 19 20 21
;	22 23 24 25
;	26 ** ** **
;	27 28 29 30
;	31 32 33 34
;	35 ** ** **

; Destination block format:
;	XX XX 00 01	<- AC0
;	02 03 04 05
;	06 07 08 09
;	10 11 12 13
;	14 15 16 17
;	18 19 20 21
;	22 23 24 25
;	26 27 28 29
;	30 31 32 33
;	34 35 ** **

ConvFrom36:
	MAR← T← AC0;			Fetch first word of destination block
	L← 177777+T;			Back up destination pointer
	AC0← L;
	T← 177400;
	L← MD AND T;			L← (XX XX -- --)
	SAD← L LCY 8;			SAD← (-- -- XX XX)
	L← AC1-1, TASK;			Back up source pointer
	AC1← L;

; Main loop.
; Each iteration converts 4 Maxc words to 9 Alto words.  Hence each
; iteration increments AC1 by 12, increments AC0 by 9, and decrements
; AC3 by 4.  AC1 points to last word read, AC0 to last word written.

; Fetch first 16 bits of first Maxc word (00 01 02 03).
; SAD has (-- -- XX XX)
CF36Lp:	MAR← T← AC1+1;			Fetch next source word (00 01 02 03)
	L← NWW, BUS=0;			Test for interrupts
	L← T, T← 377, SH<0, :F36May;	[F36May, F36No]
F36No:	AC1← L;				Update source address
F36Dis:	L← MD AND T, T← MD;		L← (-- -- 02 03), T← (00 01 02 03)
	T← 177400 . T;			T← (00 01 -- --)
	T← SAD OR T;			T← (00 01 XX XX)
	SAD← L, L← T;			SAD← new leftover (-- -- 02 03)
	MAR← T← AC0+1;			Store into destination block
	MTEMP← L LCY 8, L← T;		MTEMP← (XX XX 00 01)
	AC0← L, TASK;
	MD← MTEMP;

; Fetch second 16 bits of first Maxc word (04 05 06 07).
; SAD has (-- -- 02 03)
	MAR← L← AC1+1;			Fetch next source word (04 05 06 07)
	AC1← L;
	T← 377;
	L← MD AND T, T← MD;		L← (-- -- 06 07), T← (04 05 06 07)
	T← 177400 . T;			T← (04 05 -- --)
	T← SAD OR T;			T← (04 05 02 03)
	SAD← L, L← T;			SAD← new leftover (-- -- 06 07)
	MAR← T← AC0+1;			Store into destination block
	MTEMP← L LCY 8, L← T;		MTEMP← (02 03 04 05)
	AC0← L, TASK;
	MD← MTEMP;

; Fetch last 4 bits of first Maxc word (08 ** ** **).
; SAD has (-- -- 06 07).
	MAR← L← AC1+1;			Fetch next source word (08 ** ** **)
	AC1← L;
	T← 170000;
	T← MD . T;			T← (08 -- -- --)
	T← SAD OR T;			T← (08 -- 06 07)
	L← AC3-1;			Decrement and test Maxc word count
	AC3← L, L← T, SH=0, TASK;
	SAD← L LCY 8, :CF36L1;		[CF36L1, CF36D1] SAD← (06 07 08 --)

; Fetch first 16 bits of second Maxc word (09 10 11 12).
; SAD has (06 07 08 --).
CF36L1:	MAR← L← AC1+1;			Fetch next source word (09 10 11 12)
	AC1← L;
	T← 7777;
	L← MD AND T, T← MD;		L← (-- 10 11 12), T← (09 10 11 12)
	XH← L;				XH← new leftover (-- 10 11 12)
	L← T← 170000 . T;		L← T← (09 -- -- --)
	XREG← L MLSH 1;			Left cycle it 4 bits
	L← T← XREG;
	XREG← L MLSH 1;
	L← T← XREG;
	XREG← L MLSH 1;
	L← T← XREG, TASK;
	XREG← L MLSH 1;			XREG← (-- -- -- 09)

	MAR← L← AC0+1;			Store into destination block
	AC0← L;
	T← SAD;				T← (06 07 08 --)
	L← XREG OR T, TASK;		L← (06 07 08 09)
	MD← M;

; Fetch second 16 bits of second Maxc word (13 14 15 16).
; XH has (-- 10 11 12).
	MAR← L← AC1+1;			Fetch next source word (13 14 15 16)
	AC1← L;
	T← 7777;
	L← MD AND T, T← MD;		L← (-- 14 15 16), T← (13 14 15 16)
	SAD← L;				SAD← new leftover (-- 14 15 16)
	T← 170000 . T;			T← (13 -- -- --)
	L← T← XH OR T;			L← T← (13 10 11 12)
	XREG← L MLSH 1;			Left cycle 4 bits
	L← T← XREG;
	XREG← L MLSH 1;
	L← T← XREG, TASK;
	XREG← L MLSH 1;

	MAR← L← AC0+1;			Store into destination block
	AC0← L;
	L← T← XREG;
	XREG← L MLSH 1;			XREG← (10 11 12 13)
	MD← XREG;

; Fetch last 4 bits of second Maxc word (17 ** ** **).
; SAD has (-- 14 15 16).
	MAR← L← AC1+1;			Fetch next source word (17 ** ** **)
	AC1← L;
	T← 170000;
	T← MD . T;			T← (17 -- -- --)
	L← SAD OR T, TASK;		L← (17 14 15 16)
	XREG← L MLSH 1;			Left cycle 4 bits

	L← T← XREG;
	XREG← L MLSH 1;
	L← T← XREG;
	XREG← L MLSH 1;
	L← T← XREG, TASK;
	XREG← L MLSH 1;			XREG← (14 15 16 17)

	MAR← L← AC0+1;			Store into destination block
	AC0← L;
	L← AC3-1;			Decrement and test Maxc word count
	AC3← L, SH=0, TASK;
	MD← XREG, :CF36L2;		[CF36L2, CF36D2] Store (14 15 16 17)

; Fetch first 16 bits of third Maxc word (18 19 20 21).
; There are no leftover bits.
CF36L2:	MAR← L← AC1+1;			Fetch next source word (18 19 20 21)
	AC1← L;
	T← MD;				T← (18 19 20 21)
	MAR← L← AC0+1;			Store into destination block
	AC0← L, L← T, TASK;
	MD← M;				Store (18 19 20 21)

; Fetch second 16 bits of third Maxc word (22 23 24 25).
; There are no leftover bits.
	MAR← L← AC1+1;			Fetch next source word (22 23 24 25)
	AC1← L;
	T← MD;				T← (22 23 24 25)
	MAR← L← AC0+1;			Store into destination block
	AC0← L, L← T, TASK;
	MD← M;				Store (22 23 24 25)

; Fetch last 4 bits of third Maxc word (26 ** ** **).
; There are no leftover bits.
	T← 170000;
	MAR← L← AC1+1;			Fetch next source word (26 ** ** **)
	AC1← L;
	L← AC3-1;			Decrement and test Maxc word count
	AC3← L;
	L← MD AND T, SH=0, TASK;	L← (26 -- -- --)
	SAD← L, :CF36L3;		[CF36L3, CF36D3]

; Fetch first 16 bits of fourth Maxc word (27 28 29 30).
; SAD has (26 -- -- --).
CF36L3:	MAR← L← AC1+1;			Fetch next source word (27 28 29 30)
	AC1← L;
	T← 17;
	L← MD AND T, T← MD;		L← (-- -- -- 30), T← (27 28 29 30)
	XH← L;				XH← new leftover (-- -- -- 30)
	L← T← 177760 . T;		L← T← (27 28 29 --)
	XREG← L MRSH 1;			Right cycle it 4 bits
	L← T← XREG;
	XREG← L MRSH 1;
	L← T← XREG;
	XREG← L MRSH 1;
	L← T← XREG, TASK;
	XREG← L MRSH 1;			XREG← (-- 27 28 29)

	MAR← L← AC0+1;			Store into destination block
	AC0← L;
	T← SAD;				T← (26 -- -- --)
	L← XREG OR T, TASK;		L← (26 27 28 29)
	MD← M;

; Fetch second 16 bits of fourth Maxc word (31 32 33 34).
; XH has (-- -- -- 30).
	MAR← L← AC1+1;			Fetch next source word (31 32 33 34)
	AC1← L;
	T← 17;
	L← MD AND T, T← MD;		L← (-- 14 15 16), T← (31 32 33 34)
	SAD← L;				SAD← new leftover (-- -- -- 34)
	T← 177760 . T;			T← (31 32 33 --)
	L← T← XH OR T;			L← T← (31 32 33 30)
	XREG← L MRSH 1;			Right cycle 4 bits
	L← T← XREG;
	XREG← L MRSH 1;
	L← T← XREG, TASK;
	XREG← L MRSH 1;

	MAR← L← AC0+1;			Store into destination block
	AC0← L;
	L← T← XREG;
	XREG← L MRSH 1;			XREG← (30 31 32 33)
	MD← XREG;

; Fetch last 4 bits of fourth Maxc word (35 ** ** **).
; SAD has (-- -- -- 34).
	MAR← L← AC1+1;			Fetch next source word (35 ** ** **)
	AC1← L;
	T← 170000;
	T← MD . T;			T← (35 -- -- --)
	L← SAD OR T, TASK;		L← (35 -- -- 34)
	XREG← L MLSH 1;			Left cycle 4 bits

	L← T← XREG;
	XREG← L MLSH 1;
	L← T← XREG;
	XREG← L MLSH 1;
	L← AC3-1;
	AC3← L;
	L← T← XREG, SH=0, TASK;
	SAD← L MLSH 1, :CF36Lp;		[CF36Lp, CF36Dn] SAD← (-- -- 34 35)

; Here when done
CF36Dn:	L← PC, SWMODE, :CnvXit;
CF36D1:	L← PC, SWMODE, :CnvXit;
CF36D2:	L← PC, SWMODE, :CnvXit;
CF36D3:	L← PC, SWMODE, :CnvXit;

; Here when possible interrupt (SH<0 branch pending)
F36May:	AC1← L, :F36Int;		[F36Int, F36Dis]

; Here to interrupt
F36Int:	:F32Int;			Store leftover word and quit