%
Page Numbers: Yes First Page: 1
Heading:
IfuSubrs.mcJune 18, 1981 9:59 AM%
TITLE[IfuSubrs];
%*++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
CONTENTS

TEST
DESCRIPTION
get1Rand:Get one random number
iGetISubrScr:Return current value of iSubrScr
incClockIncrement a counter (clockCount) and pulse TIOA for scoping if count has right value
iPat16:initialize pat16X
nextPat16:return t = new pattern, ALU=0 if no more patterns
getPat16:return current pattern
iPat8:Initialize pat8X
nextPat8:Return new 8 bit pattern
getPat8:Return current 8 bit pattern
iIaddr:Initialize iAddrX
nextIAddr:Return next IfuM address
getIAddr:Return current ifuM address

These are Exception Entry Points

KfaultXMemory fault ifu entry point for instruction set X (X IN [0..3])
FGParityXFGparity ifu entry point for instruction set X (X IN [0..3])
ReschedXResched ifu entry point for instruction set X (X IN [0..3])
NotReadyXNot ready ifu entry point for instruction set X (X IN [0..3])
RamPEXRam PE ifu entry point for instruction set X (X IN [0..3])

These are opcode entry points

op0:Ifu opcode destination
op377:Ifu opcode destination
opIfAd10:Ifu opcode destination w/ ifuAd = 10 (address bits in IfuM). fast-Exit.
opIfAd11:Ifu opcode destination w/ IfuAd = 11. fast-Fetch
opIfAd12:Ifu opcode destination w/ IfuAd = 12. fast-Store
opIfAd13:Ifu opcode destination w/ IfuAd = 13. jump-Fail
opIfAd14:Ifu opcode destination w/ IfuAd = 14. unconditional-Jump
opIfAd15:Ifu opcode destination w/ IfuAd = 15. most opcodes dispatch to here
opIfAd16:ifu opcode destination w/ IfuAd = 16. jump-Succeed
opIfAd20Err:ifu opcode destination w/ IfuAd = 20. pause-Halt (should never get here)

Routines that use KLink, etc

afterDispatch:returns control after ifuJump via return link kept in KLINK
checkExceptions:returns control after IfuJump via KLink OR generates error
(after an exception dispatch)

Read Muffler values

readMufBit:Reads muffler bit, enter w/ t = address
readMuffler:Returns a muffler byte; enter w/ t = muffler address.
%*++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++

%
June 18, 1981 9:59 AM
Move incClock from ifuStepSubrs to here.
June 18, 1981 9:23 AM
Construct this file out of ifu1.mc
May 18, 1981 2:25 PM
Fix nextPat to invoke cycleRandV to get better performance from the random number generator.
February 1, 1980 7:58 PM
Fix stack handling bug in return code of addressing test. Fix old bug in fastStore code that was fetching rather than storing.
February 1, 1980 7:48 PM
Add code to mask out unwanted bits from getIfuLH in addressing test.
February 1, 1980 6:37 PM
Add iMemAddrs, an addressing logic test.
February 1, 1980 5:06 PM
Improve the set of patterns generated by pat16.
September 19, 1979 1:13 PM
Reset expectedDispatch<0 after invoking iSingleStepTest.
September 19, 1979 12:55 PM
Move beginIfu1 to the beginning of the file, add more and better comments, and set up iSingleStepTest to loop 400 times.
September 17, 1979 5:29 PM
Add iSingleStepTest.
July 3, 1979 1:53 AM
Increment return link in checkException by 1 -- because afterdispatch will also decrement it & we need compatability. This increment occurs after the potential error check where the link has been decremented to make error interpretation easier.
July 3, 1979 1:17 AM
Decrement return link in checkException by 1 -- so that it points to where we came from rather than where to return to, which is irrelevant..
July 3, 1979 12:06 AM
Add code to enable dynamically selected exception conditions.
June 29, 1979 11:46 AM
Modify afterDispatch to save POINTERS into (stack+1), but to return control with stkp = entering value. Do this since afterDispatch resets RBASE to defaultRegion, and some tests want to check the value that RBASE got set to when the IfuJump occured.
June 20, 1979 9:14 AM
Add call to resetIfu in iMemRandAddrs and cause beginIfu1 to invoke iMemRandAddrs.
June 20, 1979 8:50 AM
Add ifuLHmaskC masking to data in iMemRandAddrs
June 20, 1979 7:35 AM
Add random address generation test (iMemRandAddrs)
June 19, 1979 10:34 AM
Fix register clobbering bug in new version of ifuMemRW.
June 18, 1979 8:56 AM
Fix bug in 3rd pattern of nextPat16.
June 17, 1979 4:04 PM
Add entry points for all the exception conditions
June 15, 1979 3:24 PM
Enable random patterns in iMemRW
June 5, 1979 12:43 PM
Remove i.testCase2L since test2 has been removed from default diagnostic.
June 5, 1979 11:31 AM
Add disableConditionTask
May 30, 1979 10:08 AM
Add random numbers to pat16 code; diddle iMemRW to reset the Ifu only once.
May 9, 1979 9:05 AM
Fix subroutine mode error in ifuMScopeLoop. Move contents section to top of file & add more comments.
May 4, 1979 10:57 AM
Add scope loop for checking Ram speed.
May 3, 1979 8:44 AM
Add calls to setIUsingInstrSet before invoking initIfuM1Thru(3,16)
April 26, 1979 9:53 AM
Add pat8 subroutines.
April 25, 1979 12:13 PM
Add fastExit, fastFetch, fastStore code.
April 24, 1979 5:27 PM
Remove references to dispatchOffset, simplify afterDispatch.
April 22, 1979 5:10 PM
Move iAddFGParity thru itStep into ifuStepSubrs.mc
February 7, 1979 10:35 AM
Add breakpoints to rampe, kfault, resched entries; explicitly place all the entry points for the instructions.
February 6, 1979 2:16 PM
Add requisite noop after PcF←.
February 5, 1979 12:54 PM
Add ifAd20 -- ifu pause/halt code
February 5, 1979 9:59 AM
Change opifad13,14,16 to do ifuJumps directly.
January 18, 1979 6:44 PM
Fix misc. bugs in pattern16, muffler bit reading code
January 17, 1979 3:52 PM
More Rev-Bb mods: define exception code for instrSet 1 (locations 200,204,214,234,274). Define itMosFhSh.
January 15, 1979 4:52 PM
Rev-Bb mods: instrSet bits, complemented, are or’d into Exception addresses. InstrSet bits 2,3 pick bytes right to left. Cycled 0 pattern for Ifu memory test.
%

* June 18, 1981 9:59 AM
get1Rand: pushReturn[];
getRandom[];
returnP[];

iGetISubrScr: subroutine;
RBASE ← rbase[iSubrScr];
return, t ← iSubrScr, RBASE ← rbase[defaultRegion];* move elsewhere

incClock: subroutine;
RBASE ← rbase[clockCount];
t ← clockCount ← (clockCount)+1;
t - (triggerCount);
skpif[ALU#0], TIOA ← triggerZero;
TIOA ← triggerValue;
return, RBASE ← rbase[defaultRegion];



* May 18, 1981 2:25 PM
%*++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
iPat16
nextPat16
getPat16
16 bit pattern subroutines
iPat16initialize pat16X
nextPat16return t = new pattern, ALU=0 if no more patterns
getPat16return current pattern
Eventually these will move to postamble.
%*++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++

iPat16:
subroutine;* initialize 16 bit pattern
t ← cm1;
return, pat16X ← t;

nextPat16:
subroutine;* rtns next 16 bit pattern
saveReturn[Klink];
top level;
RBASE ← rbase[pat16X];
t ← pat16X ← (pat16X) + 1;
t - (pat16End1C);* see if done w/ current pattern
branch[after1Pat16, ALU>=0], PD ← pat16X;* if not done, see if current pattern is zero

* IN [0..pat16End1C)
skpif[ALU#0];* init the pattern if this is first time thru
skip, t ←pat16 ← 1c;* pattern init; set to one
t ← pat16 ← (pat16) lsh 1;* left shift a one bit
branch[xitNextPat16ok];

after1Pat16:
t - (pat16End2C);* see if done w/ pattern 2
branch[after2Pat16, ALU>=0];

* IN [pat16End2C..pat16End2C)
* Pattern 2 = cycled zero bit
t # (pat16End1C);* see if first time in Pattern2
skpif[ALU#0];
pat16 ← 77777C;* set it to only one zero bit for first time
pat16 ← t ← lcy[pat16, pat16, 1];* left cycle it one
branch[xitNextPat16ok];

after2Pat16:* see if pattern 3
t - (pat16End3C);
skpif[ALU<=0];
branch[after3Pat16];* see if done w/ pattern 4

* IN [pat16End2C..pat16End3C):
Pattern 3
branch[xitNextPat16ok];* real work is done by getPat16

after3Pat16:
t - (pat16End4C);
skpif[ALU<=0];
branch[after4Pat16], rscr ← t-t;* all done
* IN [pat16End3C..pat16End4C):
Pattern 4
call[cycleRandV];
branch[xitNextPat16ok];* real work is done by getPat16

after4Pat16:
t - (pat16End5C);
skpif[ALU<=0];
branch[after5Pat16];* all done
* IN [pat16End4C..pat16End5C):
Pattern 5
branch[xitNextPat16ok];* real work is done by getPat16

after5Pat16:
t - (pat16End6C);
skpif[ALU<=0];
branch[xitNextPat16], rscr ← t-t;* all done
* IN [pat16End5C..pat16End6C):
Pattern 6
branch[xitNextPat16ok];* real work is done by getPat16

xitNextPat16ok:
rscr ← (pat16X)+1;* put non-zero value in rscr
xitNextPat16:
returnAndBranch[klink, rscr];* t = current pattern; ALU#0 means value ok

* February 1, 1980 5:39 PM
getPat16: subroutine;* Enter w/ T = ifu addr. rtn w/ next pattern in T
%
Currently there are four sets of patterns:
pattern1left cycled 1 bit
pattern2
left cycled 0 bit
pattern3
left cycled index
pattern4
random numbers
pattern5
words of all zeros alternated w/ all ones
pattern6
words of all ones alternated w/ all zeros
Pattern1 and pattern2 return the same value every time getPat16 is called, given a constant value for pat16X. Ie., the range for pat16X in pattern 1 is [0..pat16End1C), and when pat16X is zero, getPat16 always returns 1, when SpatX is one, getPat16 always returns 2, etc.
Pattern2 is similar to pattern1 except that it is a bitwise complement, ie., a single zero bit with the remaining bits all ones.
Pattern3 returns the current index left cycled. The calling program provides the index (low 16 bits only) in T. The first time pattern3 is in effect, it returns the current index. The next time getPat16 is called, the cycle count for pattern 3 increments and getPat16 returns the index left cycled 1, etc.
Pattern4 returns a random number.
Pattern5 returns a word of all zeros followed by a word of all ones
Pattern6 returns a word of all ones followed by a word of all zeros
%

mc[
shc.AisT, b2];
mc[
shc.BisT, b3];
set[
shc.countShift, 10];
mc[
shc.maskShiftCount, b4,b5,b6,b7]
mc[
shc.rmt, shc.BisT!];* deal w/ rm,,t
mc[
shc.rmrm, 0];

RBASE ← rbase[klink];* save return and preserve t.
klink ← link;
top level;

RBASE ← rbase[pat16X];
(pat16X)-(pat16End1C);* see which pattern we are using
branch[get16P2,ALU>=0];
* IN [0..pat16End1C)
pattern 1
* pattern 1 returns a cycled 1 bit.
branch[get16PXit], t←pat16;* nextPat16 did our work

get16P2:* return pattern 2 or greater
(pat16X)-(pat16End2C);
branch[get16P3, ALU>=0];
* IN [pat16End1C..pat16End2C)
pattern 2
* pattern 1 returns a cycled 0 bit.
branch[get16PXit], t ← pat16;* nextPat16 does our work

* February 1, 1980 5:35 PM
get16P3:
(pat16X) - (pat16End3C);
branch[get16P4, ALU>=0];
* IN [pat16End2C..pat16End3C)
pattern 3
%
Pattern3 returns a cycled version of the current index.
Begin by moving the current index into curSpattern, and then construct a shifter control value that will provide the correct cycle value. Always construct a SHC value that cycles rm,,t.
%
pat16 ← t;* ENTERED W/ T = low 16 bits of index

t ← pat16X;* construct SHC constant. begin w/
t ← lsh[t, shc.countShift];* positioning the shift count.
t ← t and (shc.maskShiftCount);

t ← t or (shc.rmrm);* add control bits
SHC ← t;
t ← pat16 ← shiftNoMask;
branch[get16Pxit];

get16P4:
(pat16X) - (pat16End4C);
branch[get16P5, ALU>=0];
* IN [pat16End3C..pat16End4C)
pattern 4
* pattern4 returns pseudo ranom numbers
noop;
getRandom[];* IN [Spat2EndC..Spat3EndC) (random numbers)
RBASE ← rbase[pat16X];
branch[get16PXit], pat16 ← t;

get16P5:
(pat16X) - (pat16End5C);
branch[get16P6, ALU>=0];
* IN [pat16End4C..pat16End5C)
pattern 5
* pattern5 returns all zeros alternating w/ all ones
t and (1c);
skpif[alu=0],t←a0;
t←a1;
branch[get16PXit], pat16 ← t;

get16P6:
(pat16X) - (pat16End6C);
branch[get16PXit, ALU>=0];
* IN [pat16End5C..pat16End6C)
pattern 6
* pattern6 returns all ones alternating w/ all zeros
t and (1c);
skpif[alu#0],t←a0;
t←a1;
branch[get16PXit], pat16 ← t;

get16PXit:
link ← Klink;
subroutine;
return, RBASE← rbase[defaultRegion];

getCur16pattern: subroutine;* return curSPattern in T
saveReturn[Klink];
RBASE ← rbase[pat16];
t ← pat16;
returnUsing[Klink];
* April 26, 1979 9:56 AM
%*++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
iPat8
nextPat8
getPat8
This code implements an 8 bit pattern generator. It is similar to the other pattern code except that there is only one pattern and it is a counter that ranges in [0..400).
%*++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
iPat8: subroutine;
t ← cm1;
return, pat8X ← t;
nextPat8: subroutine;
RBASE ← rbase[pat8X];
t ← pat8X ← (pat8X)+1, RBASE ← rbase[defaultRegion];
return, PD ← t-(400C);* ALU=0 when pattern is done
getPat8: subroutine;
RBASE ← rbase[pat8X];
return, t ← pat8X, RBASE ← rbase[defaultRegion];

* February 1, 1980 7:34 PM
%*++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
iIAddr
nextIAddr
getIAddr
ifu address loop control
%*++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
iIAddr: subroutine;* initialize Ifu addresses
t ← cm1;
return, IAddrX ← t;

nextIAddr:
subroutine;* rtns t = next ifu address (ALU#0 =>valid)
RBASE ← rbase[IAddrX];
t ← IAddrX ← (IAddrX)+1, RBASE ← rbase[defaultRegion];
return, t - (IfuEndAddrC);

getIAddr:
subroutine;* rtns t = current ifu address (ALU#0 =>valid)
RBASE ← rbase[IAddrX];
return, t ← IAddrX, RBASE ← rbase[defaultRegion];

iIAddrDownCtrl: subroutine;
t←IfuEndAddrC;
return, IAddrX←t;
nextIAddrDown: subroutine;
RBASE←rbase[IAddrX];
t← IAddrX← (IAddrX)-1, RBASE← rbase[defaultRegion];
skpif[ALU<0];
return, PD← 1c;
return, PD← 0c;* no more addrs

* July 3, 1979 12:57 AM
%*++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
IFU: EXCEPTION CONDITION ENTRY POINTS.
%*++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++

top level;
%*++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Instruction Set 3: Exception Condition Entry Points
Exception conditions occur in order of highest priority.
%*++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Kfault3:* instruction set 3: Memory fault
call[checkException], t ← exceptions.kfault3,at[0];
call[checkException], t ← exceptions.kfault3,at[1];
call[checkException], t ← exceptions.kfault3,at[2];
branch[checkException], t ← exceptions.kfault3,at[3];
FGParity3:* instruction set 3: Parity Error in FG data from memD
call[checkException], t ← exceptions.FGPe3,at[4];
call[checkException], t ← exceptions.FGPe3,at[5];
call[checkException], t ← exceptions.FGPe3,at[6];
branch[checkException], t ← exceptions.FGPe3,at[7];
Resched3:* instruction set 3: Want reschedule
call[checkException], t ← exceptions.resched3,at[14];
call[checkException], t ← exceptions.resched3,at[15];
call[checkException], t ← exceptions.resched3,at[16];
branch[checkException], t ← exceptions.resched3,at[17];
NotReady3:* instruction set 3: Ifu not yet ready to respond (pipe empty)
call[afterdispatch],at[34];
call[afterDispatch],at[35];
call[afterDispatch],at[36];
branch[afterDispatch],at[37];
RamPE3:* instruction set 3: Parity Error in Ifu Ram
call[checkException], t ← exceptions.RamPe3,,at[74];
call[checkException], t ← exceptions.RamPe3,,at[75];
call[checkException], t ← exceptions.RamPe3,,at[76];
branch[checkException], t ← exceptions.RamPe3,at[77];
%*++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Instruction Set 2: Exception Condition Entry Points
Exception conditions occur in order of highest priority.
%*++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Kfault2:* instruction set 2: Memory Fault
call[checkException], t ← exceptions.kfault2,at[100];
call[checkException], t ← exceptions.kfault2,at[101];
call[checkException], t ← exceptions.kfault2,at[102];
branch[checkException], t ← exceptions.kfault2,at[103];
FGParity2:* instruction set 2: Parity Error in FG data from memD
call[checkException], t ← exceptions.FGPe2,at[104];
call[checkException], t ← exceptions.FGPe2,at[105];
call[checkException], t ← exceptions.FGPe2,at[106];
branch[checkException], t ← exceptions.FGPe2,at[107];
Resched2:* instruction set 2: Want reschedule
call[checkException], t ← exceptions.resched2,at[114];
call[checkException], t ← exceptions.resched2,at[115];
call[checkException], t ← exceptions.resched2,at[116];
branch[checkException], t ← exceptions.resched2,at[117];
NotReady2:* instruction set 2: Ifu not yet ready to respond (pipe empty)
call[afterdispatch],at[134];
call[afterDispatch],at[135];
call[afterDispatch],at[136];
branch[afterDispatch],at[137];
RamPE2:* instruction set 2: Parity Error in Ifu Ram
call[checkException], t ← exceptions.RamPe2,at[174];
call[checkException], t ← exceptions.RamPe2,at[175];
call[checkException], t ← exceptions.RamPe2,at[176];
branch[checkException], t ← exceptions.RamPe2,at[177];
%*++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Instruction Set 1: Exception Condition Entry Points
Exception conditions occur in order of highest priority.
%*++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Kfault1:* instruction set 1: Memory Fault
call[checkException], t ← exceptions.kfault1,at[200];
call[checkException], t ← exceptions.kfault1,at[201];
call[checkException], t ← exceptions.kfault1,at[202];
branch[checkException], t ← exceptions.kfault1,at[203];
FGParity1:* instruction set 1: Parity Error in FG data from memD
call[checkException], t ← exceptions.FGPe1,at[204];
call[checkException], t ← exceptions.FGPe1,at[205];
call[checkException], t ← exceptions.FGPe1,at[206];
branch[checkException], t ← exceptions.FGPe1,at[207];
Resched1:* instruction set 1: Want reschedule
call[checkException], t ← exceptions.resched1,at[214];
call[checkException], t ← exceptions.resched1,at[215];
call[checkException], t ← exceptions.resched1,at[216];
branch[checkException], t ← exceptions.resched1,at[217];
NotReady1:* instruction set 1: Ifu not yet ready to respond (pipe empty)
call[afterdispatch],at[234];
call[afterDispatch],at[235];
call[afterDispatch],at[236];
branch[afterDispatch],at[237];
RamPE1:* instruction set 1: Parity Error in Ifu Ram
call[checkException], t ← exceptions.RamPe1,at[274];
call[checkException], t ← exceptions.RamPe1,at[275];
call[checkException], t ← exceptions.RamPe1,at[276];
branch[checkException], t ← exceptions.RamPe1,at[277];
%*++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Instruction Set 0: Exception Condition Entry Points
Exception conditions occur in order of highest priority.
%*++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Kfault0:* instruction set 0: Memory Fault
call[checkException], t ← exceptions.kfault0,at[300];
call[checkException], t ← exceptions.kfault0,at[301];
call[checkException], t ← exceptions.kfault0,at[302];
branch[checkException], t ← exceptions.kfault0,at[303];
FGParity0:* instruction set 0: Parity Error in FG data from memD
call[checkException], t ← exceptions.FGPe0,at[304];
call[checkException], t ← exceptions.FGPe0,at[305];
call[checkException], t ← exceptions.FGPe0,at[306];
branch[checkException], t ← exceptions.FGPe0,at[307];
Resched0:* instruction set 0: Want reschedule
call[checkException], t ← exceptions.resched0,at[314];
call[checkException], t ← exceptions.resched0,at[315];
call[checkException], t ← exceptions.resched0,at[316];
branch[checkException], t ← exceptions.resched0,at[317];
NotReady0:* instruction set 0: Ifu not yet ready to respond (pipe empty)
call[afterdispatch],at[334];
call[afterDispatch],at[335];
call[afterDispatch],at[336];
branch[afterDispatch],at[337];
RamPE0:* instruction set 0: Parity Error in Ifu Ram
call[checkException], t ← exceptions.RamPe0,at[374];
call[checkException], t ← exceptions.RamPe0,at[375];
call[checkException], t ← exceptions.RamPe0,at[376];
branch[checkException], t ← exceptions.RamPe0,at[377];
* February 1, 1980 8:00 PM
%*++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
IFU opcodes
This is the microcde that actuallty executes after an ifuJump.

In general, Klink, an RM location, contains the return link for the current opcode. The "fast" opcodes ignore klink (except for the fastExit opcode that checks CNT=0).
Manually place these opcodes because the diagnostic must know, at run time, where they are located.

about these locations & the names of the labels:
Notice that many labels look like opIfAdXX where XX is a two or three digit number. That number is exactly the number that gets loaded into the Ifu ram to address the location for the label. For example, you see immediately below that opIfAd10 is placed at location 40. The bits loaded into the Ifu Ram to address opIfAd10 are 10B. If you look at the IfuAddr bits on the Ifu drawings (IFU InstrAddr Bit Slice, p. 7 last time I saw it), you will find the value indicated by the label. Eg. IfuAddr=10 if the Ifu ram has selected the location opIfAd10. The processor provides the remaining two bits of control address in the IfuJump instruction.
%*++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++

opIfAd10:* fastExit code: branch to afterDispatch IF CNT=0&-1
dblbranch[fastExit0, fastExitCont, CNT=0&-1],at[40];
dblbranch[fastExit0, fastExitCont, CNT=0&-1],at[41];
dblbranch[fastExit0, fastExitCont, CNT=0&-1],at[42];
dblbranch[fastExit0, fastExitCont, CNT=0&-1],at[43];
fastExitCont: ifuJump[0];
fastExit0:
branch[afterDispatch];

opIfAd11:* fastFetch code: check stack (must be < 0) and fetch that location.
branch[fastFetch0], PD←stack,at[44];
branch[fastFetch0], PD←stack,at[45];
branch[fastFetch0], PD←stack,at[46];
branch[fastFetch0], PD←stack,at[47];
fastFetch0:
skpif[ALU<0];
stack ← 100000C;
FETCH ← stack, IfuJump[0];

opIfAd12:* fastStore code: store MD into location pointed to by stack, increment stack.
branch[fastStore0], (MD) # (stack),at[50];
branch[fastStore0], (MD) # (stack),at[51];
branch[fastStore0], (MD) # (stack),at[52];
branch[fastStore0], (MD) # (stack),at[53];
fastStore0:
skpif[ALU=0], t ← MD;
fastStoreError:
error;
stack ← (Store←stack)+1, DBuf←t, IfuJump[0];
opIfad13:* fastJFail dispatches here
branch[opIf13Jump], t ← (ID) - (PcX’),at[54];
branch[opIf13Jump], t ← (ID) - (PcX’),at[55];
branch[opIf13Jump], t ← (ID) - (PcX’),at[56];
t ← (ID) - (PcX’),at[57];
opIf13Jump:
t ← t-1;
PcF ← t;
noop;* wait for PcF← to take effect before the next ifuJump.
IFUJump[0];
opIfad14:* fastJ: one byte jumps here
IFUJump[], stack←ID,at[60];
IFUJump[], stack←ID,at[61];
IFUJump[], stack←ID,at[62];
IFUJump[], stack←ID,at[63];
opIfad15:* very common dispatch location for opcodes
call[afterDispatch],at[64];
call[afterDispatch],at[65];
call[afterDispatch],at[66];
branch[afterDispatch],at[67];
opIfad16:* successful jumps here
IFUJump[],at[70];
IFUJump[],at[71];
IFUJump[],at[72];
IFUJump[],at[73];

opIfad22Err
:* pause-halt here. IFU has gone awry. It probably picked up
branch[err],at[110];* a byte that was NOT an opcode byte. The IFU
branch[err],at[111];* ram has been "backgrounded" to point to this
branch[err],at[112];* location just so we can catch the IFU when it tries
branch[err],at[113];* to execute a random byte as if it were an opcode

* June 29, 1979 11:45 AM

%*++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
afterDispatch

SOME OTHER routine should set "expectedDispatch" to the absolute value of the location
where we expected to dispatch.

SET stack+1 to current value of POINTERS, then reset RBASE to defaultRegion. Return
with stkp at its original value (ie., users must increment stkp to see POINTERS).

We return via KLink
%*++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++

afterDispatch: subroutine;* come here after ifuNextMacro.
stkp+1, global;
stack&-1←POINTERS;

RBASE ← rbase[defaultRegion];* reset Rbase since Ifu causes it to change
rscr ← link;* compute where we came from
top level;

afterDispatch2:* enter here from checkException
t ← expectedDispatch;* was that where we wanted to go?
skpif[ALU>=0], rscr ← (rscr)-1;* link = where we came from +1
branch[afterDispRet];* don’t check return if expected val<0
t#(rscr);
skpif[ALU=0], t ← rscr2, RBASE ← rbase[klink];* restore T
afterDispErr:
breakpoint;* expectedDispatch # rscr
afterDispRet:
subroutine;
link←klink;
return, RBASE ← rbase[defaultRegion];
* July 3, 1979 1:53 AM
%*++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
checkExceptions
The various exception conditions (except for notReady) call this subroutine. If the exception that was called has been enabled, control proceeds through afterdispatch. Otherwise we stop at a breakpoint.

Return via KLink
%*++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++

checkException: subroutine;
KnowRbase[defaultRegion];* depend upon exceptionBit NOT in defaultRegion
exceptionBit ← t, global;
stkp+1;
stack&-1 ← POINTERS;* where afterDispatch saves POINTERS
RBASE ← rbase[defaultRegion];
rscr ← link;
rscr ← (rscr) -1;
top level;
RBASE ← rbase[exceptionsMask];
t ← exceptionsMask;
rscr2 ← t;
t ← exceptionBit, RBASE ← rbase[defaultRegion];
t and (rscr2);* see if current exception condition
skpif[ALU#0];* has been enabled
IfuExceptionErr:* rscr = return link to offending exception condition
error;* presumably klink = return link to source of ifu jump.
branch[afterDispatch2], rscr ← (rscr)+1;* reincrement exception since afterdispatch will decrement it.


* January 18, 1979 6:47 PM
%*++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
muffler reading routines
%*++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
readMufBit: subroutine;* read a muffler bit. Enter w/ t = address
* CLOBBERS T, rscr, rscr2, cnt, stkp
pushReturn[];
subroutine;* don’t clobber link w/ transfer of ctrl
cnt ← 10s;

readMufBitsL:

MidasStrobe ← t;
noop;
noop;
loopUntil[cnt=0&-1, ReadMufBitsL], t ← lsh[t, 1];

t ← link;
returnP[];

readMuffler: subroutine;* read a muffler byte and return its value
* in T. Enter with T = muffler address. Return 8 successive bits from that address.
* CLOBBERS T, rscr, rscr2, cnt, stkp

pushReturnAndT[];* tos = t
rscr2 ← t-t;* keep assembled bits in rscr2
rscr ← t-t;* rscr = loop count
readMufflerL:
rscr2 ← lsh[rscr2, 1];
call[readMufBit], t ← stack;* get current bit address
rscr2 ← (rscr2) or t;* add the current bit

t ← (stack)+1;* compute address of next bit
stack ← t;

(rscr)-(10c);* have we accumulated a byte yet?
loopUntil[ALU=0, readMufflerL], rscr ← (rscr)+1;

t ← rscr2;
pReturnP[];* tos-1 = return link