ER[BS];

*I = 127

TARGET[ILC];

%BYTE INSTRUCTIONS

BYTE POINTERS HAVE THE FORMAT:
   B[0,5]   P-FIELD (NO. BITS TO RIGHT OF BYTE)
   B[6,13]  S-FIELD (SIZE OF BYTE)
   B[14]    IGNORED
   B[15], B[16,21], B[22,43] I, X, AND E FOR EFF. ADDR. CALC.

SPECIAL NOTES:
   FOR P>=44 NO BYTE IS PROCESSED
   S + P > 44 REFERS TO A BYTE OF SIZE 44-P
   INCREMENTING THE BYTE POINTER IS AS FOLLOWS:  IF (P←P-S) < 0, THEN
(P←(44-S) MOD 100) AND (BP[15,43]←BP[15,43]+1)
   INCREMENTING THE BYTE POINTER TAKES PLACE BEFORE LOADING OR DEPOSITING
%

MC[BIS&J,BIS,J];

%TO "IBP" FROM MAIN LOOP AFTER MAPVA←P←E OR FROM "RMWBPC" WITH J=1.
TIMING = M+R+W+5 (R+W=2 + (1 IF WORD BOUNDARY CROSSED) IF B.P. IN AC)
I = 14
%
	LEFADR←P OR Q, Q←RMWMQ, CALL[LOADMAP];
IBP:	RMWREF, Q←LX, MDR←X, INHINT, CALL[IBPAC,G=1], REFADR←P;
	GOTO[.-2,G=1], Q←RMWLE;
	P←BSPLIT←MDR, SETFC[BIS&J,J=1], Q←7777 777777R;
	Q←XTOP, SETF[J], RTEMP←P AND Q;
	MDR←P-Q-NJ, P←RTEMP;
	RETURN[J=1], P←P+1, WRESTART, X←20S; *KNOW LTEMP=20
	P←(P) U (440000 000000S), INHINT;
IBP1:	LX←MDR←P-Q, RETURN, SETF[J]; *RESULT INTO MDR FOR ISPLIT← LATER

IBPAC:	P←BSPLIT←Q, GOTO[RMWAMDR,H=1], Q←7777 777777R;
	Q←XTOP, RTEMP←P AND Q, POP, SETFC[BIS&J,J=1];
	X←MDR, SETF[J];
	MDR←LX←P-Q-NJ, P←RTEMP, DGOTO[IBP1];
	RETURN[J=1], P←(P+1) U (440000 000000S);


%"RMWBPC" ENTERED FROM THE MAIN LOOP AFTER MAPVA←P←E.  IT GOES TO "RBP"
IF BIS WAS SET; OTHERWISE, IT SETS BIS AND J, INCREMENTS THE BYTE
POINTER, AND RETURNS WITH THE INCREMENTED BYTE POINTER IN MDR.
TIMING = 7+R+W + (2+R PER BYTE POINTER INDIRECT) (R+W=5 FOR AC)
I = 2
%
RMWBPC:	SETSF[BIS&J], DGOTO[IBP];
	SETF[J], GOTO[RBP,J=1];

*TO "RBP" AFTER MAPVA←P←E IN THE MAIN LOOP.  RETURN AFTER MAPVA←P←E OF BYTE
*WITH SIZE AND POSITION FIELDS OF BYTE POINTER IN RTEMP.

SM[XCT0,IP[10 000000S]]; ***
MC[XCT2&K,XCT2,K];
SM[XCT1,IP[4 000000S]];

*I = 9

RBP5:	P←MAPVA←(MDR) U (ACBASE), A1, CALL[RREFX];
	Q←RLE, RETURN[G=0]; *RETURN ALWAYS TO RBP0
	LEFADR←P OR Q, Q←RMQ, CALL[LOADMAP];
RBP:	RREF, Q←LX, MDR←X, REFADR←P, GOTO[.-2,G=0], SETSF[XCT2&K];
	P←ISPLIT←Q, GOTO[RBP5,H=1];
	Q←LINDX, INSTR←P, SETFB[XCT0,K=1], POP, GOTO[BINDE,K=1];
	GOTO[BINDE];

RBP0:	P←ISPLIT←MDR, DGOTO[BINDE];
	Q←LINDX, INSTR←P, SETFB[XCT0,K=1], GOTO[BINDE,K=1];

*MUST WAIT ONE CYCLE AFTER CHANGING XCT1 BEFORE REF
SETXCT1: SETF[XCT1], GOTO[RETN];

%ENTER AT "DPB" WITH BYTE POINTER IN INSTR AFTER MAPVA←E OF BYTE
K=1 IFF XCT3=1 (SET BY "BINDE")
TIMING = 6+R+W + (2 IF FUNNY XCT) (R+W=5 IF DATA IN AC)
I = 25
%
DPBX:	RTEMP←P AND Q, CLEARFC[BIS&J,J=1];
PTOQ:	Q←P, RETURN;

	LEFADR←P, Q←RMWMQ, CALL[LOADMAP];
DPB:	CALL[SETXCT1,K=1], P←(REFADR←P) U (RMWLE);
	RMWREF, MDR←X, Q←INSTR, INHINT, CALL[DPBAC,G=1];
	A0, GOTO[.-3,G=1];
*ENTRY HERE FOR BLISP DATA TYPE STUFF
BDPB:	BSPLIT←Q, Q←A0, GOTO[PMDR,ALU#0];
	P←A1, XMASK, Q←LAC, X←20S, CALL[DPBX]; *KNOW LTEMP=20
	0Q RCY [44-Y], Q←MDR;
DPBY:	LTEMP←NOT P AND Q, Q←RTEMP, WRESTART, DECAC, RETURN[H=1];
	0Q RCY [44-Y], Q←LTEMP, INHINT;
	LX←MDR←P OR Q, RETURN;

DPBAC:	BSPLIT←Q, GOTO[RMWAMDR,H=1];
	P←A1, XMASK, Q←LAC, X←MDR, CALL[DPBX];
	0Q RCY [44-Y], Q←LX, POP, GOTO[DPBY];

*TO "LDB" WITH BYTE POINTER IN INSTR AFTER MAPVA←E OF BYTE
*TIMING = 5+R + (1 IF NO BYTE) + (2 IF FUNNY XCT) (R=1 IF DATA IN AC)
	LEFADR←P, Q←RMQ, CALL[LOADMAP];
LDB:	CALL[SETXCT1,K=1], P←(REFADR←P) U (RLE);
	CALL[LDBAC,G=1], RREF, MDR←X, Q←INSTR;
	GOTO[.-3,G=1];
	BSPLIT←Q, DGOTO[LDBAC1];
	P←MDR, Q←A0, CLEARFC[BIS&J,J=1], GOTO[LDBAC1,J=1];

LDBAC:	P←LX, BSPLIT←Q, GOTO[RAMDR,H=1];
	Q←A0, CLEARFC[BIS&J,J=1], POP;
LDBAC1:	PQ RCY [Y], XMASK, DGOTO[SETZ];
	LAC←P, ENDM[H=0];

DI[133,IBP,REMAPPC,SCRASH];
DI[134,RMWBPC,RBP0,LDB];
DI[135,RBP,RBP0,LDB];
DI[136,RMWBPC,RBP0,DPB];
DI[137,RBP,RBP0,DPB];

%SHIFT INSTRUCTIONS:
TIMING (SHIFT COUNT <=44):
   LSH    M + 5 = 14 CYCLES
   ROT    M + 4(L) OR 5(R) = 13 CYCLES (LEFT) OR 14 (RIGHT)
   ASH    M + 5(R) + 1 IF NUMBER < 0 = 14 OR 15 CYCLES RIGHT
          M + 5(L) + 1/SHIFT = 14 + E CYCLES LEFT
   LSHC   M + 6(L) OR 7(R) = 15 CYCLES (LEFT) OR 16 CYCLES (RIGHT)
   ROTC   M + 6(L) OR 7(R) = 15 CYCLES (LEFT) OR 16 CYCLES (RIGHT)
   ASHC   M + 8(R) = 17 CYCLES RIGHT
          M + 6(L) + 1/SHIFT = 15 + E CYCLES LEFT
MICROINSTRUCTIONS:
   SHFT   1
   LSH    11
   ROT    1
   ASH    7
   CSHFT  7
   LSHCL  3
   LSHCR  3
   ROTCL  3
   ROTCR  3
   ASHC   16
TOTAL     55
%

*ACCEPTS E IN P FROM MAIN LOOP
SHFT:	YSHIFT←P, P←Q←LAC, RETURN;

LSH:	GOTO[LSHL0,Y>=0], RTEMP←P, Q←NULL;
LSHR0:	NEGY;
LSHR:	PQ RCY [Y];
	LAC←P, RETURN[H=0];
	LTEMP←Q, P←Y, Q←44R, DGOTO[LSHR];
	Y←P-Q, P←Q←LTEMP, CALL[RETN];  *LOOP FOR ROT NOT LSH

LSHL0:	Q←RTEMP, P←A0, GOTO[LSHL];
ROT:	RTEMP←P, GOTO[LSHR0,Y<0];
LSHL:	PQ RCY [44-Y], Q←P;
	LAC←P, RETURN[H=0];
	LTEMP←Q, P←Y, Q←44R, DGOTO[LSHL];
	Y←P-Q, P←Q←LTEMP, CALL[RETN];  *LOOP FOR ROT NOT LSH

ASH:	GOTO[ASHL,Y>=0], RTEMP←P, Q←NULL;
	NEGY, GOTO[LSHR,ALU>=0];
ASHB:	Q←A1, GOTO[LSHR];

ASHL:	DECY;
	RETURN[Y<0], Q←A0, DECY;
	PQ LCY [1], ASHOVF, DECY, GOTO[.,Y>=0];
	RETURN;

%CSHFT ACCEPTS E IN P.  ON E<0 (RIGHT SHIFT), LEAVES AC IN
RTEMP AND STEMP, -E IN Y, AC+1 IN LTEMP AND Q, AND LOW PART OF
RESULT IN P.  AC POINTS TO AC+1 AND RESULT IS VALID IFF H=0.
STACK IS POPPED BEFORE RETURN.
ON E>=0 (LEFT SHIFT), LEAVES AC+1 IN RTEMP, TOP PART OF RESULT IN P,
AC POINTS TO AC, E IS IN Y, AND AC IS IN Q.
%

CSHFT:	YSHIFT←P, INCAC, Q←LAC;
	P←LAC, RTEMP←Q, GOTO[CSHFTL,Y>=0];
	NEGY, POP, LTEMP←P, GOTO[.+2];
CSHFTR:	LTEMP←P;
	PQ RCY [Y], Q←P, STEMP←Q, RETURN;

*NOTE MANDATORY 1 CYCLE WAIT BETWEEN Y← AND RCY[44-Y]
CSHFTL:	RTEMP←P;
	PQ RCY [44-Y], DECAC, RETURN;

LSHCL:	LAC←P, P←NULL, INCAC, Q←RTEMP, POP, GOTO[LSHL, H=0];
	LAC←A0, P←Y, Q←44R, DGOTO[LSHL];
	Y←P-Q, Q←RTEMP, P←LAC, DECAC, CALL[RETN];

LSHCR:	LAC←P, DECAC, Q←NULL, P←RTEMP, GOTO[LSHR,H=0];
	LAC←Q, P←Y, Q←44R, DGOTO[LSHR];
	Y←P-Q, P←RTEMP, Q←LAC, INCAC, CALL[RETN];

	Y←P-Q, P←LTEMP, Q←RTEMP, CALL[CSHFTL];
ROTCL:	P←B, B←Q, LAC←P, INCAC, Q←RTEMP, POP, GOTO[LSHL,H=0];
	P←Y, Q←44R, LTEMP←P, CALL[.-2]; *CALL TO CANCEL OUT POP

	Y←P-Q, Q←LTEMP, P←RTEMP, INCAC, CALL[CSHFTR];
ROTCR:	LAC←P, DECAC, P←STEMP, GOTO[LSHR,H=0];
	P←Y, Q←44L, RTEMP←P, GOTO[.-2];


*ACCEPTS E IN P
ASHC:	YSHIFT←P, INCAC, Q←LAC; **PATCHED
	P←LAC, RTEMP←Q, GOTO[ASHCL,Y>=0], POP, Q←NULL, DECAC;
	NEGY, POP, PQ LCY [1], Q←RTEMP, DGOTO[ASHCRP,ALU>=0];
*Y CONTAINS THE SHIFT COUNT FOR A RIGHT SHIFT, RTEMP AND Q CONTAIN
*LEFT HALF, P RIGHT HALF OF QUANTITY TO BE SHIFTED.  DGOTO IS PENDING IF
*NUMBER >= 0.
	PQ RCY [Y], Q←A0, INCAC;
	PQ RCY [1], Q←400000 000000S, GOTO[.+2,H=1];
	LAC←P OR Q, DECAC, P←RTEMP, Q←-1S, GOTO[LSHR];
	DECAC, P←Y, Q←44R, LPGRT←A1;
	Y←P-Q, P←RTEMP, Q←LPGRT;
	LAC←Q←A1, PQ RCY [1], INCAC, GOTO[LSHR];

ASHCRP: PQ RCY [1], Q←(RTEMP) RSH 1, GOTO[LSHCR,H=0];
	RTEMP←Q, GOTO[LSHCR];

ASHCL:	Q←2P, P←RTEMP, DECY, POP;
	GOTO[REMAPPC,Y<0], P, DECY; *NO SHIFT IF COUNT=0
	PQ LCY [1], ASHOVF, Q LSH 1, DECY, P, GOTO[.,Y>=0];
	LAC←P, Q RSH 1, P←400000 000000S, INCAC, GOTO[QTOAC,ALU>=0];
POQA:	LAC←P OR Q, ENDM;

DI[242,SHFT,LSH,PTOAC];
DI[241,SHFT,ROT,PTOAC];
DI[240,SHFT,ASH,PTOAC];
DI[244,ASHC,SCRASH,SCRASH];
DI[245,CSHFT,ROTCL,ROTCR];
DI[246,CSHFT,LSHCL,LSHCR];

%BLT INSTRUCTION
E IS IN P AT THE CALL.
RTEMP IS USED TO HOLD THE "UNTIL" FIELD, LAC THE FROM-TO, AND LTEMP
THE INCREMENTED FROM-TO.  AC IS CLOBBERED WITH AN UPDATED BLT POINTER
BEFORE EACH WORD IS TRANSFERRED SO IT WINDS UP WITH FROM+UNTIL-TO IN THE L.H.
AND WITH UNTIL IN THE R.H. (UNLESS IT IS THE LAST WORD WRITTEN BY BLT).
AT LEAST ONE WORD IS TRANSFERRED REGARDLESS OF THE "UNTIL" FIELD.
MUST ADVANCE AC AFTER THE WRITE AND AFTER THE END CHECK SO THAT THE BLT DOESN'T
GO ASTRAY IF IT RANGES ACCROSS THE BLT POINTER AND SO THAT IF THE BLT AC IS THE
LAST WORD WRITTEN IT DOESN'T GET CLOBBERED
TIMING = M + 3 + (2 + R + W)/WORD TRANSFERRED WHERE R=3 AND W=6 FOR AC'S
I = 23
%
BLT:	RTEMP←P, P←LAC, Q←1 000000S, GOTO[.+3];
BLTLP:	P←LTEMP, SETSF[INTCONDH], GOTO[REMAPPC,ALU>=0];
	LAC←P, GOTO[PI,H=1], Q←1 000000S;
	LTEMP←P+Q+1, PQ RCY [22], SAMASK[22];
	MAPVA←REFADR←P, GOTO[.+2];
BLRML:	LEFADR←Q, Q←RMQ, CALL[LOADMAP];
	RREF, Q←LX, GOTO[.+3,G=0];
	MDR←Q, GOTO[.+3,H=0], P←ICTR, Q←P;
	MAPVA←P←(Q) U (ACBASE), A1, CALL[RREFX];
	GOTO[BLRML,G=1], Q←(P) U (RLE), P←ICTR;

	P←LAC, BAMASK[22], ICTR←P+1, Q←BLTWLE;
	MAPVA←REFADR←P, CALL[.+1];
*! MAXC1 ONLY
	MDR;
*!
	WREF, LEFADR←P OR Q, Q←RTEMP, GOTO[BWM1,G=0];
BWM0:	P-Q, Q←MDR, GOTO[.+2,H=1];
	LX←Q, FRZBALUBC, GOTO[BLTLP];
	MAPVA←Q←(X) U (ACBASE), A1;
	WREFDXK, Q←(Q) U (BLTWLE);
	LEFADR←Q, Q←RTEMP;
BWM1:	P-Q, GOTO[BLTLP,G=0], P←LEFADR;
*LOADMAP RETURNS TO WREF ABOVE AND CAN'T HAPPEN TWICE
	P←(P) U (WLE), Q←LTEMP, GOTO[.+2,ALU>=0];
	LAC←Q, Q←WMQ, GOTO[LOADMAP];
	LEFADR←P, Q←WMQ, GOTO[LOADMAP]; *DON'T DECREMENT PC IF LAST WRITE TRAPS

DI[251,BLT,SCRASH,SCRASH];