;-----------------------------------------------------------------
; MesaXRAM.Mu - Overflow from Mesad.mu residing in RAM
; Last modified by Levin - August 2, 1978  8:39 AM
;-----------------------------------------------------------------

; Separate assembly requires...

#MesabROM.mu;

;-----------------------------------------------------------------
; BLT - block transfer
;	assumes stack has precisely three elements:
;	  stk0 - address of first word to read
;	  stk1 - count of words to move
;	  stk2 - 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,1777,402,BLTintpend,BLTloop;					BLTloop must match ramBLTloop
%1,1777,404,BLTnoint,BLTint;					BLTint must match ramBLTint
!1,2,BLTmore,BLTdone;
!1,2,BLTsource,BLTCsource;
!1,2,BLTeven,BLTodd;
!1,1,BLTintx;							shake branch from BLTloop
!1,1,Setstkp;							shake IDISP from BLTnoint

;  Entry sequence in ROM1; actual entry is at BLTloop

;BLT:		stk7←L, SWMODE, :BLTx;				stk7=0 <=> branch pending
;BLTx:		IR←msr0, :ramBLTloop;				IR← is harmless


BLTloop:	L←T←stk1-1, BUS=0, :BLTnoint;
BLTnoint:	stk1←L, L←BUS AND ~T, IDISP, :BLTmore;		L←0 on last iteration (value
;								on bus is irrelevant, since T
;								will be -1).  IDISP on last
;								cycle requires that Setstkp
;								be odd.

BLTmore:	T←cp, :BLTsource;

BLTsource:	MAR←stk0, :BLTupdate;				start data source fetch
BLTCsource:	XMAR←stk0+T, :BLTupdate;			start code source fetch

BLTupdate:	L←stk0+1;
		stk0←L;						update source pointer
		L←stk2+1;
		T←MD;						source data
		MAR←stk2;					start dest. write
		stk2←L, L←T;					update dest. pointer
		SINK←NWW, BUS=0, TASK;				check pending interrupts
		MD←M, :BLTintpend;				loop or check further

BLTintpend:	SINK←wdc, BUS=0, :BLTloop;			check if interrupts enabled

;	Must take an interrupt if here (via BLT or BITBLT)

BLTint:		SINK←stk7, BUS=0, :BLTintx;			test even/odd pc
BLTintx:	L←mpc-1, :BLTeven;				prepare to back up

BLTeven:	mpc←L, L←0, :BLTodd;				even - back up pc, clear ib
BLTodd:		ib←L, SWMODE;					odd - set ib non-zero
		:romIntstop;

;	BLT completed

BLTdone:	SINK←stk7, BUS=0, SWMODE, :Setstkp;		stk7=0 => return to 'nextA'
Setstkp:	stkp←L, :romnext;				'next' has proper SWMODE bit