INSERT[D0LANG];
NOMIDASINIT;
TITLE[d0wsr];
*last edited by CT June 10, 1979
SETTASK[17];

RV[REFR,77];	*memory refresh address

*The following registers hold the volatile state of the processor on a fault: 
RV[RXALU,76];	*ALU result and SALUF
RV[RXAPC,75];	*APCTask&APC
RV[RXCTASK,74];	*CTASK.NCIA
RV[RXPPB,73];	*Page,Parity,BootReason
RV[RXSTK,72];	*Stackpointer

RV[RTMP,71];	*temporary

*The following registers are used for D0-Midas communication (RTMP is also used):
RV[RWSTAT,70];	*status register
RV[RDATA,67];	*holds data

*FFault determines how faults will be treated when programs are running.  If it is
*zero, all faults will be reported to Midas.  If FFault is nonzero, the kernel will
*send control through location 120 when a fault occurs and PARITY # 0 (faults with
*PARITY = 0 are breakpoints).
RV[FFAULT,66];

*Registers between 360 and 367 are used by the Midas overlays.  The following 
*registers, used by WriteMI,  are also in this range.
RV[RADDR,65];

RV[RCNT,64];
RV[stack4,64];

RV[RW0,63];
RV[stack3,63];

RV[RW1,62];
RV[stack2,62];

RV[stack1,61];
MC[pStk1,361]; *pointer to stack1
RV[stack0,60];


*Constants for Recv and Send
MC[RecvByte,12];
MC[RecvWord,16];
MC[SendByte,21];
MC[SendWord,25];

*The following are at fixed locations in Kernel.mc:
UserFault:	Return, AT[120];
NextCom:	Return, AT[7404];
Send:	Return, AT[7460];
Recv:	Return, AT[7464];

*d0wsr overlay
*Used by Midas to write RM 0 and RM 11-17, which cannot be written with the stackpointer, since
*stack overflow would be caused.

OverlayArea:
	RWSTAT ← RecvByte, Call[Recv], at[7500]; *get code (0-10b) into T
	stack2 ← 365c, AT[7501];
	stack2 ← (lsh[stack2,4]) + (T), at[7502]; *stack2 points to task 0, location 7520 + code
	stack3 ← pStk1, at[7503];
	RWSTAT ← RecvWord, call[Recv], at[7504]; *get data
	stkp ← stack3, stack3 ← T, at[7505]; *stkp ← pStk1, stack3 ← value
	stack1 ← 7400c, at[7506];
	stack1 ← (stack1) + (115c), at[7507]; *stack1 points to task 0, location EnterTask0
	stack0 ← 177400c, at[7510];
	stack0 ← (stack0) + (4c), at[7511]; *stack0 points to task 17, location NextCom (7404)
NotifyBothWays:
	APC&APCTask ← Stack&-1,at[7512]; *get here three times...
	return, AT[7513];
	
	SetTask[0];
NotifyNextCom:
	T ← Stack&-1,goto[NotifyBothWays], AT[7514]; *Restore original T[0], point to return address
EnterTask0:
	Stack&+1 ← T, AT[7515];	*Save T[0] in Stack1
	Stack&+2, AT[7516];		*Point to value in stack3
	T ← Stack&-1, goto[NotifyBothWays], AT[7517]; *T← value, point to write location (in Stack2)

RV[R0,0];
RV[R11,11];
RV[R12,12];
RV[R13,13];
RV[R14,14];
RV[R15,15];
RV[R16,16];
RV[R17,17];

WriteR0:
	R0 ← T,goto[NotifyNextCom],at[7520];
	R11 ← T,goto[NotifyNextCom],at[7521];
	R12 ← T,goto[NotifyNextCom],at[7522];
	R13 ← T,goto[NotifyNextCom],at[7523];
	R14 ← T,goto[NotifyNextCom],at[7524];
	R15 ← T,goto[NotifyNextCom],at[7525];
	R16 ← T,goto[NotifyNextCom],at[7526];
	R17 ← T,goto[NotifyNextCom],at[7527];

	END;