;-----------------------------------------------------------------
; MesaBLTLreal.Mu - Full implementation of BLTL.
; Last modified by Levin - February 27, 1979  5:43 PM
;-----------------------------------------------------------------

;-----------------------------------------------------------------
; BLTL - block transfer (long pointers)
;	assumes stack has precisely five words:
;	  stk0, stk1 - address of first word to read
;	  stk2	     - count of words to move
;	  stk3, stk4 - address of first word to write
;	the instruction is interruptible and leaves a state suitable
;	  for re-execution if an interrupt must be honored.
;-----------------------------------------------------------------
!1,1,BLTLsetBR;							shake BUS=0
!7,1,BLTLsetBRx;						shake IR←
!3,4,BLTLret0,BLTLret1,BLTLret2;
!1,2,BLTLnoint,BLTLint;
!1,2,BLTLintpend,BLTLloop;
!1,2,BLTLmore,BLTLdone;

; Note:  ROM code does stk7←L


BLTL:		MAR←BankReg;					access bank register
		T←stk1;						high source bits
		L←stk1+T;					L: high source *2
		temp←L LSH 1, IR←msr0;				temp: high source *4;
		L←MD, TASK;					L: old bank register
		saveret←L;					saveret: stashed register
		T←stk4;						T: high dest bits
		T←3.T, :BLTLsetBR;				(would like to avoid this)
;								returns to BLTLret0

BLTLloop:	L←T←stk2-1, BUS=0, :BLTLnoint;			decrement count, test done
BLTLnoint:	stk2←L, :BLTLmore;				T: -1 the last time

BLTLmore:	MAR←stk0;					fetch source word
		L←stk0+1;					bump source pointer
		stk0←L;
		L←stk3+1;					bump destination pointer
		T←MD;
		XMAR←stk3;					initiate store
		stk3←L, L←T;					L: data
		SINK←NWW, BUS=0, TASK;				check for possible interrupt
BLTLret0:	MD←M, :BLTLintpend;				stash data

BLTLintpend:	SINK←wdc, BUS=0, :BLTLloop;			check if enabled

BLTLint:	IR←sr2, :BLTLsetBR;				restore bank before interrupt
BLTLret2:	MD←saveret, :BLTint;				BLTint shakes branch

BLTLdone:	IR←sr1, :BLTLsetBR;				restore bank before exit
BLTLret1:	MD←saveret, L←saveret AND NOT T, :BLTdone;	BLTdone shakes branch


BLTLsetBR:	MAR←BankReg, :BLTLsetBRx;
BLTLsetBRx:	L←temp OR T, IDISP;				(used by BLTLret0 only)
		SINK←0, BUS=0, :BLTLret0;			force branch for BLTLret0
;								BLTLret1 and 2 must shake