INSERT[D0LANG];
:TITLE[d0wsr];
*Edit by ERF 1 May 1981
*Edit 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];
ReadRX:	Return, At[7406];
Send:	Return, At[7460];
Recv:	Return, At[7464];
RecvB:	Return, At[7410];
RecvW:	Return, At[7411];

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

OverlayArea:	*get code (0-10b) into T
	Stack2 ← 7400C, Call[RecvB], At[7500];
*Point Stack2 at task 0, location 7510 + code
	Stack2 ← (Stack2) or (110C), At[7501];
	Stack2 ← (Stack2) + T, At[7502];
	Stack3 ← pStk1, Call[RecvW], At[7503]; *get data
*StkP ← pStk1, Stack3 ← value being written
	StkP ← Stack3, Stack3 ← T, NoRegILockOK, At[7504];
	Stack1 ← 7400C, At[7505];
*Point Stack1 at task 0, location EnterTask0
	Stack1 ← (Stack1) + (116C), At[7506];
*Point Stack 0 at task 17, location NextCom (7404)
	Stack0 ← 177400C, At[7507];
	Stack0 ← (Stack0) + (4C), At[7512];
NotifyBothWays:
	APCTask&APC ← Stack&-1, At[7513]; *get here three times...
	Return, At[7514];
	
SetTask[0];

NotifyNextCom:	*Restore original T[0], point to return address
	T ← Stack&-1, GoTo[NotifyBothWays], At[7515];
EnterTask0:
	Stack&+1 ← T, At[7516];		*Save T[0] in Stack1
*Point to value in Stack3, then T ← value, point to write location in Stack2
	Stack&+2, GoTo[NotifyNextCom], At[7517];

RV[R0,0];
RV[R17,17];

WriteR0:
	R0 ← T, GoTo[NotifyNextCom], At[7510];
	R17 ← T, GoTo[NotifyNextCom], At[7511];

:END;