From 52ef5130b7b48e744e163b477c2bbbd2ac533c77 Mon Sep 17 00:00:00 2001 From: Lars Brinkhoff Date: Mon, 11 Jun 2018 10:13:54 +0200 Subject: [PATCH] KS10 microcode. Plus assorted KS10-related documents. --- build/misc.tcl | 6 + doc/kshack/-read-.-this- | 14 + doc/kshack/1proc.bugs | 2 + doc/kshack/ainote.8 | 182 +++ doc/kshack/consol.24 | 134 ++ doc/kshack/dec124.doc | Bin 0 -> 7539 bytes doc/kshack/ks-cha.txt | Bin 0 -> 6233 bytes src/kshack/dcode.5 | 534 +++++++ src/kshack/extend.4 | 1115 +++++++++++++ src/kshack/flt.5 | 587 +++++++ src/kshack/inout.50 | 1254 +++++++++++++++ src/kshack/its.16 | 26 + src/kshack/itspag.98 | 424 +++++ src/kshack/ks10.47 | 2210 ++++++++++++++++++++++++++ src/kshack/pagef.10 | 787 +++++++++ src/kshack/simple.42 | 3246 ++++++++++++++++++++++++++++++++++++++ 16 files changed, 10521 insertions(+) create mode 100755 doc/kshack/-read-.-this- create mode 100755 doc/kshack/1proc.bugs create mode 100755 doc/kshack/ainote.8 create mode 100755 doc/kshack/consol.24 create mode 100755 doc/kshack/dec124.doc create mode 100755 doc/kshack/ks-cha.txt create mode 100755 src/kshack/dcode.5 create mode 100755 src/kshack/extend.4 create mode 100755 src/kshack/flt.5 create mode 100755 src/kshack/inout.50 create mode 100755 src/kshack/its.16 create mode 100755 src/kshack/itspag.98 create mode 100755 src/kshack/ks10.47 create mode 100755 src/kshack/pagef.10 create mode 100755 src/kshack/simple.42 diff --git a/build/misc.tcl b/build/misc.tcl index 5785cd9b..45f74aa6 100644 --- a/build/misc.tcl +++ b/build/misc.tcl @@ -827,6 +827,12 @@ expect ":KILL" # Write the RAM file to the front end filesystem: # :klfedr write ucode;u1 ram +# KS10 microcode. +# It doesn't seem to work very well when purified. +respond "*" ":kshack;micro kshack;mcr 262=kshack;its,ks10,simple,flt,extend,inout,itspag,pagef\r" +expect ":KILL" +respond "*" ":copy kshack; mcr ram, .; ram ram\r" + # XXFILE respond "*" ":midas sysbin;xxfile bin_sysen1;xxfile\r" expect ":KILL" diff --git a/doc/kshack/-read-.-this- b/doc/kshack/-read-.-this- new file mode 100755 index 00000000..14a407b4 --- /dev/null +++ b/doc/kshack/-read-.-this- @@ -0,0 +1,14 @@ + +This directory contains KS10 specific files for ITS. It contains: +The microcode assembler, microcode source files, etc. +KSDEFS and other KS10-specific documentation and definition files. +The new salvager NSALV. +KSFEDR, the 8080 front-end filesystem manipulation program. +MTBOOT, the KS10 boot tape writing program. +The MINI36 server, used by NSALV to retrieve files over Chaosnet. +Etc. + +The KSHACK directory on MC no longer contains the canonical versions of +these files. The KSHACK directory on AI is now the official KS10 hacking +directory. -Alan 12/30/85 + diff --git a/doc/kshack/1proc.bugs b/doc/kshack/1proc.bugs new file mode 100755 index 00000000..5e80fc42 --- /dev/null +++ b/doc/kshack/1proc.bugs @@ -0,0 +1,2 @@ +Some floating-point instructions clear all bits in FLG, +they will have to be fixed to only clear some LH bits. diff --git a/doc/kshack/ainote.8 b/doc/kshack/ainote.8 new file mode 100755 index 00000000..68d434a1 --- /dev/null +++ b/doc/kshack/ainote.8 @@ -0,0 +1,182 @@ +-*- Text -*- This is the file AI:KSHACK;AINOTE > + + + WHAT TO DO IF AI CRASHES + +******************************************************************************* +* Before following these directions, please try to find a system hacker to * +* take a look at the corpse first. * +* * +* If you do -anything- about a crashed ITS, leave an explanation in the log * +* book next to the system console. Include the date and time, your name, * +* what the problem was, what you did, and anything else relevant. And please * +* make it legible; three lines of random scrawls can't help the hackers fix * +* the problem. * +******************************************************************************* + + THE SIMPLEST CASE +In the most common sort of crash, AI will type a bug message and go to Exec +DDT. For example: + PI LEVEL 7 BUGHALT. FIND A WIZARD OR CONSIDER TAKING A CRASH DUMP. + THE SYSTEM HAS CRASHED AND CANNOT BE REVIVED WITHOUT EXPERT ATTENTION. + IF YOU CAN'T FIND HELP, RELOAD THE SYSTEM. + YOU ARE NOW IN DDT. + BUGPC/ CAIA PCLSR+3 $Q-1/ PUSHJ P,BUGNIL + +If the message says that the bug is "proceedable", you can try typing: + $P +to revive the system. If this works, be glad you don't have to read the rest +of this notice; however, you should still leave a note in the log book. + + LESS THAN SIMPLE +If the system cannot be revived, it must be reloaded. To reload, you must get +to DSKDMP. Type: + $U +to leave Exec DDT and start DSKDMP. When DSKDMP starts up it announces itself +by saying: + DSKDMP +If DSKDMP has something to complain about, it will type a error message; its +error messages are explained on the summary of DSKDMP commands taped to AI. If +you don't understand (or like) what DSKDMP is telling you, stop; let someone +who does understand check it out. + + CRASH DUMPS +Before reloading, you may want to take a crash dump. Crash dumps are +recommended if anything unusual was happening before the system crashed, or if +the remains look funny. To take a crash dump, get into DSKDMP and type: + D$CRASH; +where is somehow descriptive of the problem; AI will linefeed when +the crash has been dumped. You can list the CRASH directory by typing: + U$CRASH; +to see what filenames are already used. If you take a crash dump, send mail to +Bug-ITS giving the filename you used. + + RELOADING ITS +Look at AI's "Very Small Bulletin Board" envelope on the front of the system +console. The punch card in front will list which version of ITS is supposed to +be running. If, for instance, it says "NITS", then to reload AI, type: + .;NITS +This will cause DSKDMP to find the file DSK:.;@ NITS, load it into core, and +start it in Exec DDT -- thus, you will be talking to Exec DDT again, which will +linefeed to indicate it's ready for you. + +Now check for any special instructions someone might have left about patching +ITS before starting it. Typically, a patch will appear as a few cryptic +commands scrawled on a scrap of paper stuffed into the VSBB in front on the +punch cards, which must be typed to Exec DDT before you proceed further. If +you find such instructions, but can't figure out what they mean, stop now. + +To start ITS, type: + $G +to Exec DDT. ITS starts by running the Salvager over the filesystem, which +causes the disk to make noise -- don't worry, that's supposed to happen -- and +prints a series of messages to indicate its progress. If the Salvager finds +anything terribly wrong with the filesystem, it will refuse to let you bring +the system back up. If this happens, give up and find a hacker. + +Next, ITS pokes around to see if there are any surprising holes in its memory. +If it finds any, it will ask if they are OK. If there is a note in the VSBB +predicting the holes exactly, answer affirmatively; otherwise it is time to +find a system hacker. + +Now ITS checks whether it knows the time. If it doesn't, it tries to find the +current time from other machines on the local network. This may not work; if +it doesn't, AI will print an attention-getting message (including feeps) as it +comes up. In this case, you must log in and run the PDSET program. + + RUNNING PDSET +If ITS tells you to run PDSET, you might as well does this from the system +console. So type: +  +and after AI greets you, type: + :PDSET +to run the PDSET program. PDSET starts by warning you that what it does is +potentially dangerous. To set the date and time type: + yymmddD + hhmmssT + !. +where "yymmdd" is the date ("850520" for May 20, 1985) and "hhmmss" is the time +in 24-hour time ("145900" for 2:59 PM). At the instant you type the ".", PDSET +will set the time to what you specified. + +To leave PDSET type: + Q +and then log out: + $$U + + IF AI HALTS +If the processor halts, the 8080 front-end will print a halt code and a PC. +These will look something like: + %HLTD/000001 PC/704000,,071101 +Write these numbers in the log book. Also, if you take a crash dump, mention +these numbers in the mail you send to Bug-ITS. + +You should now be talking to the 8080 front-end. To check this, type a +linefeed or two; you should see the prompt: + KS10> +Now type: + ST 777700 +and the 8080 will try to start DSKDMP. If this works, DSKDMP will announce +itself, and you should go back to the middle of "Less Than Simple" and proceed +from there. + +If DSKDMP does not start up, cold boot the machine. + + COLD BOOTING +Push the white "BOOT" switch on the front of AI. This should initialize +everything, and load and start DSKDMP. DSKDMP will announce itself by typing: + DSKDMP +If nothing happens, make sure that some loser hasn't set the white "LOCK" +switch, also be sure that the "WRITE PROTECT" switch on the disk isn't set. +Now go back to "Reloading ITS" and proceed from there. + + ITS IS CLEARLY BROKEN, BUT IT'S STILL RUNNING +Are you sure? Make sure it is really the case that nobody is getting any work +done. Check people on both network terminals and hardwired lines. If you are +certain, then type: +  +to get the attention of the 8080 front-end. It should prompt you with: + KS10> +(if it doesn't, make sure the white "LOCK" switch hasn't accidently been set). +Type: + SH +to make the 8080 ask ITS to stop and go to Exec DDT. If this works, AI will +print a PI LEVEL 7 BUG message; go back to "Less Than Simple" and proceed from +there. + +If ITS ignores the 8080's request, type "" again and this time follow it +with: + HA +This should force the processor to halt, so go back to "If AI Halts" and +proceed from there. If this does not work, cold boot the machine. + + CALLING DEC +If you determine that the machine needs to be serviced by DEC, call them at +895-5711. Tell them we have "2020 system number 84019009N" and describe the +problem. If they claim they can't find the system in their records, be +insistent; the field service people can find the machine even if the phone +answering people can't. They will ask for the name and phone number of someone +to contact; it doesn't matter whose you give them -- the field service people +know MIT well enough that they don't need those. + + BRINGING AI DOWN +You should only bring AI down with good reason, e.g. the machine room is over +80, or it's time for PM. First, log in: + $U +(for instance, "DEC$U" if you're here to run PM.) Then run + :LOCK +It will prompt + _ +type + nDOWN +where "n" is an integer not less than five; this will make AI bring itself down +in "n" minutes (LOCK sees numbers in octal only). This interval must be at +least five minutes to give people a chance to clean up. LOCK will ask you for +a message explaining why you're bringing AI down; type in a short explanation +and include your UNAME (so the users know who to blame) and end with +  +Then + Q +to get out of LOCK and + $$U +to log out. Then just wait. diff --git a/doc/kshack/consol.24 b/doc/kshack/consol.24 new file mode 100755 index 00000000..978272b1 --- /dev/null +++ b/doc/kshack/consol.24 @@ -0,0 +1,134 @@ +-*- Text -*- This is the file AI:KSHACK;CONSOL > + + + Useful Console Commands + + +Talking to the 8080: + + Start talking to the 8080 + Stops whatever the 8080 is doing + Stop talking to the 8080 + + +Multiple commands can be given on a command line separated by commas. If +the RP command is the last command in the line, then the line will be +repeated. It stops when you type any character. An argument to RP causes +it to repeat the command roughly that many times. Useful are: "PM,RP", +"SI,RP", "EN,RP". + + +Booting the machine: + +BT BooT + Resets the machine and boots from disk. + Normally this loads and starts DSKDMP. + +MT MagTape boot + Resets the machine and boots from magtape. + +DS Disk Select + Selects which disk drive to boot from. + +MS Magtape Select + Selects which tape drive to boot from. + + +Debugging PDP-10 code: + +ST pc STart + DDT starts at 774000. + DSKDMP starts at 777700. + +SH SHutdown (Stop! Hold!) + Like raising switch 0 on a machine that has one. + +HA HAlt + +CO COntinue + +SI Single Instruction + +LA addr Load Address + +DM data Deposit Memory + +DN data Deposit Next + +EM [addr] Examine Memory + +EN Examine Next + +EX inst EXecute instruction + +ZM Zero Memory + This is VERY slow. It starts with low addresses, so ZM + followed by  is good enough to clear most memory that + you care about. + + +Debugging microcode: + +SM [upc] Start Microcode + 0 (the default) is the normal starting address. 1 just + writes a halt status block. + +MR Master Reset + Resets everything (whatever that is). + +CH Clock Halt + Stops the microcode in its tracks. + +CS Clock Start + Start the microcode up again. + +CP [steps] Clock Pulse + Single steps the microcode one or many steps. + +EJ Examine Jumps + Prints current upc and how the next upc is being computed. + +PM Pulse Machine + Like "CP,EJ". + +TR upc TRace + Like "PM,RP" except it stops when the current upc gets to + the specified value. Also uses twice as much paper. + +TE [state] Timer Enable + "TE 0" turns the timer off. Makes it possible to single + step the microcode with paging enabled without looping + taking timer interrupts. "TE 1" turns the timer on. Just + "TE" tells you what its state is. + +CE [state] Cache Enable + Turns the cache on and off. + +TP [state] Traps & Paging + Turns traps and paging on and off. + + +Halt Status Block: + +[ Note that the DEC microcode wants to write the halt status block + starting at 376000. ] + +500: MAG 506: BRX 514: PI +501: PC 507: ONE 515: XWD1 +502: HR 510: EBR 516: T0 +503: AR 511: UBR 517: T1 +504: ARX 512: MASK 520: VMA +505: BR 513: FLG + +It does -not- work to start the machine and read the halt status block +using DDT, you have to read it using the 8080. + + +Halt Codes: + + 0: Power Up 102: Bad Interrupt Table Pointer + 1: Halt Instruction 1000: Bad BWRITE Function + 2: Halted by 8080 1004: Bad NICOND Dispatch + 100: I/O Page Fail 1005: Failed Multiply Self-test + 101: Bad Interrupt Instruction 777777: Halted after "SM 1" command + diff --git a/doc/kshack/dec124.doc b/doc/kshack/dec124.doc new file mode 100755 index 0000000000000000000000000000000000000000..05859abc92ef2c1953ec7702d1cce535748ece71 GIT binary patch literal 7539 zcmd6sTXWmi6@~K({E9PrsHF*Io04KX>2x~O#SNqDSXAOXbwJ`!Ln_OO9 z@ABNsr_cAFIv2;IJa^^X1p4=luZkpJpO#ddToz4L=DAPZ^g*A}tU+b&O6uA#r};xY zaCI4HjYIuaS=ZS#Hyv+%;VbEo6s{MYKe#N#yljSmW$yo#v(j5?j{thjae zS+j7-qn3rg-&CVU`#CppLs2$v>K_k?r&*Cy5Aw#N8}_+nmbA5ZtE6gr(+|%kE-UJ$ zYG<;})xK$0?mofeWS{AY@YZ_n3 z14>@5#?dsv8iE}eri6?k9%<1@Q z^pBH|V~TDywwF}I=~&JojI#6b)1$T)y#~j{QQ>_`1O+TD~%NSTik~MI7~jl@w|3N#sY9wknirD*nz=6i1IoajU9)2iSx#t$j`6B{Tn# z>NkfY>VIH0M}2oLlyoahy;10o-&~&aO}3JO;h8TwQTMCzk$ZRp0H%6(bGV5yNQov3 zPgQIHPYCEIWzG$>gC@!Hr+sNt(woSwqte86Ug*vPz$9RgVc$HElMJUrbeSqrxA&$5jo%=)~hy^oW4>fV*o=4+ikxl6!!jZ1n ztoA69teEAkk_;zU)!gWcQos$Pi}JsGWDl2bR-SThOIFtnK}xE03)8O?%24WnOr(?f z&ko#=LfAi#*dJ(l5RsTyR#7@l_@e&)xjElO9QG$}yeJKeKndVbY96@1*z0$W+6V0f zj$jexqw-bqJr)HKjiWxKA?UqEs^VF>TqO;$$TK>awO#>zR<;|dqx}Cf1t?q!)t40= zvoHuY76TCLKmqiFq4DmV1Xl&$+*~Rh$#`EaNxiP&Sbq)3cymR!MnG1qEAgX{@GX_) zj3Cix3ZOc1c~SxS$+B$mz8H_dw(`3{E?xcBf$~Yf=lvJEcs53jnZVOI3|wHQs~6?H612l^6RxA1I4uK!D3?u-Yzc$nw0SaXFqcFqd_#HOx$V)#>u1L& zM||F)yA|numNpBl8RgBQY;PBaL#M}AZq`;bfCf4xI$;1zW9-D3w~_8q4SECyR4&)4 zFtu2SaD4v8(&G5!=3)fpRI|b~>mTUo-_x5#LNLEeZ2Z^VTxCQ|2bv_gxJxx|?psJO z!Hzf^O}c16WgB-_$W3)QZ|;RH*>aV8(Oq(mw%qa1u7!zkk}vnkY9)8|jV_E8qF@6xaj3Vd}SOu7q`6&4@L9ECYUuC}qPbsjX zyANKJ7pj$(u+lglZ*bUzO)|NQE|IQsB%_%iwcB{*`9*RkXMTjxGR(XUbD zK3Es{N}?G@c^Ub*k}GTh_;eK$OC!nF;Wc}sM=MdiHt;S?p6LuI^968uNYmc0Fkwb z417aVH7Pne3O0bCoRVgsnN1PuOV+u`B-|o z!yZgqt0{e!NX{PRHN=E3Y;KO3j<;+KO!6(aHOqY>0#f-cH)B}j{>wR^+o~2CGOvjs z)H3x>w^cxK{$Mu8S8tCdc0tW+?L-^&nT@M7&x)Zro<-W;98XP1{(Kj`t3Xfo&?J>${IVD})7j;{`RM+}(fzU6aw<<%!w_P=F|Wk+I9`JG<&Y1sSR|C@B`3xKPS48EZu= z_#!2)$tU&id7M!gUl@y`Q2B58{TB$2P#^@|JL&k;ZEGPgub<%=_ntw)7*!m7%UcX} z-?}{~XY$6Zb31W}Ti9V3>Di+YU$>R2cHkr@ErEx6kOCNBYl-e<5#0Vki5?Ie5i|+jTn8{ul$G$?d`oL6KLvkP>1`sx@ zaA4(^+-d%jUF2lFY1xw|W*}x6)M>EH(v*XU4qMRB4bf96;Vzg)0fXUF_sinJIH`84 zCvPVw7sr2(;cXLaW9c0-%FbUTRudY8D@G@_ri_|uU~YT(Vn?SOy&0Xmf3>(0UD<{( zlM0MFX&cPA6DulgqKyk<%Obm7u$E?eL4LPpRxqret0E+8o9(nrAZSF!iB5kVJ&i+11$0dSg*Aq^&KL~5$2Zh zlO@k+C)7`~r)R7TpPimvjF}c~08|^+SR_2>K9Li4pG*bx>pZ2Im=PT0+F~~(14fi9 zHHeOEu#-4enC%I$(|SirZL6*0UTT|vUXRaC-VW4W;P3Xj|6<@Kr-yoZJvtk>i`T5~ zghDpxqS%6|b*WY6GX_~+B*xnH(6R32_;BKspC{(jwh;k5`^h4XLgcyN8PYdp38H;# zcvdMctN*GM%-PlC`s&PWD`v0{&2N3yaG#{S(lVg~zHWL&R(3ayu8+oJ z8m735rNfSeT~d~1k!fM@xL@w8SvaK(sicd6ia{ek@Tew(ZJqC}B*&}@Y;l{whRWHU z5^;POzpySW=T?nlej*`5l`4MeW;x@tOzA?a--Y_$0QhRQ2$zBB zCiqcSt+|OEu&IKbFd~z6vITdYKolU;cvx`LWo-z9;aSaO+C>M%P)ROW>h0nm+v*T0b?5A$>aCqPK6r$+zS3mi_;UBm-_oyeOy|))soV;}+VV4< zRsdsm_f{v?7LriyDqyZ1QZG0nT-TC~&L%w-NA^wnHHH4GLY4Q4klgT*e;nZ@NVcWh z5>ng(XzWq83_`};9*4ZaS=OfY##)YlAAWKQ&xYclgu{vqHyVPVBR@(=rA@%SRo|$+ zkOo7Vg^dL=RSE`vA~e=MA^=wZi>9e2Y1W98H}d2>Pi(u6iJP{mADv$BYETKX@svOY eA3UggN=`4BsM_7GeyAJLuteR!QK{i?zWEP}caa_d literal 0 HcmV?d00001 diff --git a/doc/kshack/ks-cha.txt b/doc/kshack/ks-cha.txt new file mode 100755 index 0000000000000000000000000000000000000000..92be9c615ec374dbcb38ee279cae85c5334e3ae4 GIT binary patch literal 6233 zcmb7|TXP%75ry-L{S{Mq3FQJHfuw9lev&9Dp%hsc(vi!lJPfe|V8g`@vKK=5_xVoG zE(B7lR7K?~gS)dmJ>92IpPnomU9W?Cdo_RJE+4;lMb)%*w`hx4HO^N#586=I-L`eU zUaX5YEZVLPE-sgWx0^6a2JU~yf>j-xWWn=SS5;vVn#R{fxpz$&cQfbMc%O|HzFc&r zZ-Z;sp{QNJGW*{J=kvVg8(eVSnY#Tl+e9 zZFF4|`ln@#x2`O1Z8vt`#ject-qpe9)2-*{bXRju_ghumbd6i=7iDPNO-BScJDcuZ z9;-jM$znFz*72^$gKOd@xbUT|y;}yaC^fDrHbv=c`G8aSQ!aP0&Zli?+H7<$Xzkj! z$*^3}F08z@&vfE_?06t&cb*_%ZG%;!|DlfC*o2&~wxwT$jbe1q^2yiO#qA>Ip?UNy z%SNNi_n%(6=NFS#{QCUq+J5r*y7pB=tlh=Q^NUAp@;F7iGJxdau2?ARql=SQk2nz# zid9?3vgDJh+uT?>-28kx|7kJ=@hFw^pQmR}XT$!NM-HUlSibT^QUQPE3NZB0NUV;x zJe#=Px>&5Wl&J7|pEwKXCN@OXe8!T1TOIcPc(ix={r~Pg|DSs+<9X5C$}_fgZv1iV znwF|++%nc~te0bV=~f*upN$lgU!xTQP~dCa<bXM%ZHj2k+^g>39YD>(IP2)fniC@vQMYZaR zW)02^4MK7HfUl1}AvZd9N&!dyHC7@EdpM+_Un9=pWAozD-Bxj@h4NjzvA3e+!GrTo zs53&=bgPxs&`1vMyg6vQY>Gu4g>u(yDTm2%E$}FWd?I3F=e1wlaxB*tz|EW@+8bZ5 ziprNm4TF|{zPbMFetP`W&G?sP*Skns8gho|yI9^46T+NF+48AMtp0w3dZVdg=7D7IDbq8zC00O4lu7cmoy)kB1Y__GblmVDbE^ZsLB=QRlyy|{P{PzQ( zm3_;qnX|;PG8&M)ayw)lwsR6uzU97ucO34uir%SwJW$ncp!OU{oWDTL0w&^EaM_2pYT7}PQ)^EP#Nng z^XY~%HOH)Y-7atzNd0D?^?oVFo3M#Bo-U*^1Zoy9K>u{%58hcXSj5c+{3>NVAF0fI zA_5GpLIt&!xK1>2FMx;%0k)Q(SnAMjmO@fJ;T-|UDE-v^J7b?Ae#bF@gqNWe#KaUS z*Xh95Y)!7FS<~)IQ86+M5Vcuw-rO84$_}bG&V@W-!EgqBZ#J#!tWYGTo!^LN{eFtOnxH zxjAEmlDKNzokxZNygKMa8XGdSMZJLw!k4h<#C3vvyB5zL?@R-}Y^CkVY_U{knh=_7 zL^{m23uPn4d`VF=WQa|A-gW*)K2!sL8f@6(;P>)P*AEPKVAHZwWX$4z;@rl7>Ry(Qb5V;Bv1 zDB<9&OW$j5$%%8K$wS{ka5Zq*v}ccL58BBDBiJQ_#U0l{xUtAJso|xaAF72G&-A|kLJSB+3bvWb36E*FAGW5 z{@LiF7kkey+zpwz<<%*s=Ce7bve64Lh#h(3OQuJ2ibRPzV0lf z)vBWE;2ayG`|m0BVdIGr7c|cRri$@SriQn@_3^f50*egO!;7(8lalc^?c)zEn_@|L z<6WD^fT86L8Co)eTVUBHHG<3QD-0#wmnI4g{X3zh7jDg0Svuf`5*kB1f;Q{4)|ZSG za{ain+?!8V*Ny>GlwrT;XA{n(i3)NdxI@qkXanSV!R$}jrb_A?%@NS-&OkyX)>s=1 zCm)!#HcS_iWJfSP)YzdOAJShs1%pdmDbVE0?4BMwe+shk3}vMIm2$5TeAd`O+qdXT zKSkuZ20ggU%!JC{ph$ev6syWE7pRtPUEHZ~o&z=mpeN6*RV2OkYa!k;Kf5=8uy>BSlmjENyvmR zUSkF)d@#Lz4oIBu5s6T6`o#LP&6rYFY|T7k5-c)T_cfDk(R=J})HOVG{XkP%+dIgyZ=Al$4uj0Vcxn6<5kjXV4b@;xTb69rbtwOuvu?mex5bI~ ziA<7)Rhkv1p^x>AK=BeD{5SDtag(j6f6k3+Iu>~S9PO4Jpj78|cLfuq+VI1h!Fv;_ zT(C(`PI%@csS6^y>8h0#;^ATw@BfDE@i(z+xd^*Fh=ktllk>S+rBKAh)_&m4-(Eb2 zmZ*hCmU9kfHJUwaN=hG>FQR4rT*j_WEm7g4aMCwenme0DDnLkrsaZ_5rQ>Q&>E9wS%Fn8}>{E?|yjGX(2 zy2^o*_4H>Joz8xA-}aYNZ0X&(dtC=^*-mF?{7u7g9|m&2=;wl~G#I**CxX@6t4FUU%0n_ zHwg)neizNYb|=QRPbZHoTfe_~^=tp=M;?j6Kso-K7ZerqjqU*_Y_ka4mRTm<`0+f= zDAtb#QdAWVom1*D-4{B-s?P|94a7EUS#0{+=Y_uXH$_>rv{%Lv4aG|~>93Bm@4!oq l#B*~q%s96i5sXx@$A6rH(ll_Y_aaW|;{@VJ#s7(a{{;j}Lj3>$ literal 0 HcmV?d00001 diff --git a/src/kshack/dcode.5 b/src/kshack/dcode.5 new file mode 100755 index 00000000..339e73cc --- /dev/null +++ b/src/kshack/dcode.5 @@ -0,0 +1,534 @@ +;-*-Fundamental-*- Contents of KS10 Dispatch Memory + +000: I, J/UUO +001: I, SJCL, J/L-CMS + I, SJCE, J/L-CMS + I, SJCLE, J/L-CMS + I, B/2, J/L-EDIT + I, SJCGE, J/L-CMS + I, SJCN, J/L-CMS + I, SJCG, J/L-CMS +010: I, B/1, J/L-DBIN ;CVTDBO + I, B/4, J/L-DBIN ;CVTDBT + I, B/1, J/L-BDEC ;CVTBDO + I, B/0, J/L-BDEC ;CVTBDT +014: I, B/1, J/L-MVS ;MOVSO + I, B/0, J/L-MVS ;MOVST + I, B/2, J/L-MVS ;MOVSLJ + I, B/3, J/L-MVS ;MOVSRJ +020: I, J/L-XBLT + I, J/L-SPARE-A + I, J/L-SPARE-B + I, B/0, J/L-SPARE-C + I, B/1, J/L-SPARE-C + I, B/2, J/L-SPARE-C + I, B/4, J/L-SPARE-C + I, B/10, J/L-SPARE-C +030: I, B/0, J/LUUO + I, B/1, J/LUUO + I, B/2, J/LUUO + I, B/3, J/LUUO + I, B/4, J/LUUO + I, B/5, J/LUUO + I, B/6, J/LUUO + I, B/7, J/LUUO +040: I, J/MUUO ;CALL ;.IOT + I, J/MUUO ;INIT ;.OPEN + I, J/MUUO ;.OPER + I, J/MUUO ;.CALL + I, J/MUUO ;.USET + I, J/MUUO ;.BREAK + I, J/MUUO ;.STATUS + I, J/MUUO ;CALLI ;.ACCESS + I, J/MUUO ;OPEN + I, J/MUUO ;TTCALL + I, J/MUUO + I, J/MUUO + I, J/MUUO + I, J/MUUO ;RENAME + I, J/MUUO ;IN + I, J/MUUO ;OUT + I, J/MUUO ;SETSTS + I, J/MUUO ;STATO + I, J/MUUO ;GETSTS + I, J/MUUO ;STATZ + I, J/MUUO ;INBUF + I, J/MUUO ;OUTBUF + I, J/MUUO ;INPUT + I, J/MUUO ;OUTPUT + I, J/MUUO ;CLOSE + I, J/MUUO ;RELEAS + I, J/MUUO ;MTAPE + I, J/MUUO ;UGETF + I, J/MUUO ;USETI + I, J/MUUO ;USETO + I, J/MUUO ;LOOKUP + I, J/MUUO ;ENTER + +100: I, J/UUO ;UJEN + I, J/UUO101 +.IF/ITS +102: I, J/XCTRI + I, J/XCTR +.IFNOT/ITS +102: I, J/UUO102 + I, J/UUO103 +.ENDIF/ITS +104: I, J/JSYS ;JSYS +105: I-PF, B/0, J/ADJSP +106: I, J/UUO106 + I, J/UUO107 +110: DBL FL-R, J/DFAD +111: DBL FL-R, J/DFSB +112: DBL FL-R, DAC, J/DFMP +113: DBL FL-R, DAC, J/DFDV +114: DBL R, DAC, J/DADD + DBL R, DAC, J/DSUB +116: DBL R, DAC, J/DMUL +117: DBL R, DAC, J/DDIV +120: DBL R, DAC, J/DAC ;DMOVE + DBL R, AC, J/DMOVN ;DMOVN +122: FL-R, FL-AC, J/FIX ;FIX +123: I, READ/1, J/EXTEND ;EXTEND +124: DBL AC, J/DMOVN1 ;DMOVEM + W, J/DMOVNM ;DMOVNM +126: FL-R, FL-AC, ROUND, J/FIX ;FIXR +127: R, FL-AC, ROUND, J/FLTR ;FLTR +130: I, B/0, J/FP-LONG ;UFA + I, B/1, J/FP-LONG ;DFN +132: I, FL-AC, J/FSC +133: R, AC, J/IBP ;OR ADJBP +134: R, W TEST, J/ILDB ;CAN'T USE RPW BECAUSE OF FPD + R, J/LDB + R, W TEST, J/IDPB + R, J/DPB +140: FL-R, FL-AC, J/FAD +141: I, B/2, J/FP-LONG ;FADL +142: FL-RW, FL-MEM, J/FAD + FL-RW, FL-BOTH, J/FAD + FL-R, FL-AC, ROUND, J/FAD + FL-I, FL-AC, ROUND, J/FAD + FL-RW, FL-MEM, ROUND, J/FAD + FL-RW, FL-BOTH, ROUND, J/FAD +150: FL-R, FL-AC, J/FSB +151: I, B/3, J/FP-LONG ;FSBL +152: FL-RW, FL-MEM, J/FSB + FL-RW, FL-BOTH, J/FSB + FL-R, FL-AC, ROUND, J/FSB + FL-I, FL-AC, ROUND, J/FSB + FL-RW, FL-MEM, ROUND, J/FSB + FL-RW, FL-BOTH, ROUND, J/FSB +160: FL-R, FL-AC, J/FMP +161: I, B/4, J/FP-LONG ;FMPL +162: FL-RW, FL-MEM, J/FMP + FL-RW, FL-BOTH, J/FMP + FL-R, FL-AC, ROUND, J/FMP + FL-I, FL-AC, ROUND, J/FMP + FL-RW, FL-MEM, ROUND, J/FMP + FL-RW, FL-BOTH, ROUND, J/FMP +170: FL-R, FL-AC, J/FDV +171: I, B/5, J/FP-LONG ;FDVL +172: FL-RW, FL-MEM, J/FDV + FL-RW, FL-BOTH, J/FDV + FL-R, FL-AC, ROUND, J/FDV + FL-I, FL-AC, ROUND, J/FDV + FL-RW, FL-MEM, ROUND, J/FDV + FL-RW, FL-BOTH, ROUND, J/FDV + +200: R-PF, AC, J/STAC ;MOVE + I-PF, AC, J/STAC ;MOVEI + W, M, J/MOVE ;MOVEM + RW, S, J/STSELF ;MOVES +204: R-PF, AC, J/MOVS ;MOVS + I-PF, AC, J/MOVS ;MOVSI + W, M, J/MOVS ;MOVSM + RW, S, J/MOVS ;MOVSS +210: R-PF, AC, J/MOVN ;MOVN + I-PF, AC, J/MOVN ;MOVNI + W, M, J/MOVN ;MOVNM + RW, S, J/MOVN ;MOVNS +214: R-PF, AC, J/MOVM ;MOVM + I-PF, AC, J/STAC ;MOVMI + W, M, J/MOVM ;MOVMM + RW, S, J/MOVM ;MOVNS +220: R-PF, AC, J/IMUL + I-PF, AC, J/IMUL + RW, M, J/IMUL + RW, B, J/IMUL +224: R-PF, DAC, J/MUL + I-PF, DAC, J/MUL + RW, M, J/MUL + RW, DBL B, J/MUL +230: R-PF, DAC, J/IDIV + I-PF, DAC, J/IDIV + RW, M, J/IDIV + RW, DBL B, J/IDIV +234: R-PF, DAC, J/DIV + I-PF, DAC, J/DIV + RW, M, J/DIV + RW, DBL B, J/DIV +240: SH, J/ASH + SH, J/ROT + SH, J/LSH + I, J/JFFO + I-PF, J/ASHC +245: SHC, J/ROTC + SHC, J/LSHC +.IF/CIRC + I, J/CIRC ;That's whats in the DROM... +.IFNOT/CIRC +247: I, J/UUO247 ;RESERVED +.ENDIF/CIRC +250: R, W TEST, AC, J/EXCH +251: I, J/BLT +252: I, SJCGE, J/AOBJ + I, SJCL, J/AOBJ +254: I, VMA/0, AC DISP, J/JRST + I, J/JFCL +256: R, J/XCT ;OPERAND FETCHED AS DATA +.IF/ITS +257: IOT, AC, J/UUO257 +.IFNOT/ITS +257: IOT, AC, J/MAP +.ENDIF/ITS +260: I, B/0, J/PUSHJ + IR, B/2, J/PUSH + I, B/2, J/POP + I, J/POPJ +264: I, J/JSR + I, J/JSP + I, J/JSA + I, J/JRA +270: R-PF, AC, J/ADD + I-PF, AC, J/ADD + RW, M, J/ADD + RW, B, J/ADD +274: R-PF, AC, J/SUB + I-PF, AC, J/SUB + RW, M, J/SUB + RW, B, J/SUB + +300: I, SJC-, J/DONE ;CAI + I, SJCL, J/CAIM + I, SJCE, J/CAIM + I, SJCLE, J/CAIM + I, SJCA, J/CAIM + I, SJCGE, J/CAIM + I, SJCN, J/CAIM + I, SJCG, J/CAIM +310: R, SJC-, J/CAIM ;CAM + R, SJCL, J/CAIM + R, SJCE, J/CAIM + R, SJCLE, J/CAIM + R, SJCA, J/CAIM + R, SJCGE, J/CAIM + R, SJCN, J/CAIM + R, SJCG, J/CAIM +320: I, SJC-, J/DONE + I, SJCL, J/JUMP + I, SJCE, J/JUMP + I, SJCLE, J/JUMP + I, SJCA, J/JRST + I, SJCGE, J/JUMP + I, SJCN, J/JUMP + I, SJCG, J/JUMP +330: R, SJC-, J/SKIPS ;NOT A NOP IF AC .NE. 0 + R, SJCL, J/SKIPS + R, SJCE, J/SKIPS + R, SJCLE, J/SKIPS + R, SJCA, J/SKIPS + R, SJCGE, J/SKIPS + R, SJCN, J/SKIPS + R, SJCG, J/SKIPS +340: I-PF, SJC-, J/AOJ + I, SJCL, J/AOJ + I, SJCE, J/AOJ + I, SJCLE, J/AOJ + I, SJCA, J/AOJ + I, SJCGE, J/AOJ + I, SJCN, J/AOJ + I, SJCG, J/AOJ +350: RW, SJC-, J/AOS + RW, SJCL, J/AOS + RW, SJCE, J/AOS + RW, SJCLE, J/AOS + RW, SJCA, J/AOS + RW, SJCGE, J/AOS + RW, SJCN, J/AOS + RW, SJCG, J/AOS +360: I-PF, SJC-, J/SOJ + I, SJCL, J/SOJ + I, SJCE, J/SOJ + I, SJCLE, J/SOJ + I, SJCA, J/SOJ + I, SJCGE, J/SOJ + I, SJCN, J/SOJ + I, SJCG, J/SOJ +370: RW, SJC-, J/SOS + RW, SJCL, J/SOS + RW, SJCE, J/SOS + RW, SJCLE, J/SOS + RW, SJCA, J/SOS + RW, SJCGE, J/SOS + RW, SJCN, J/SOS + RW, SJCG, J/SOS + +400: I-PF, AC, J/SETZ + I-PF, AC, J/SETZ + IW, M, J/SETZ + IW, B, J/SETZ +404: R-PF, AC, J/AND + I-PF, AC, J/AND + RW, M, J/AND + RW, B, J/AND +410: R-PF, AC, J/ANDCA + I-PF, AC, J/ANDCA + RW, M, J/ANDCA + RW, B, J/ANDCA +414: R-PF, AC, J/MOVE ;SETM = MOVE + I-PF, AC, J/MOVE + RW, M, J/MOVE ;SETMM = NOP THAT WRITES MEMORY + RW, B, J/MOVE ;SETMB = MOVE THAT WRITES MEMORY +420: R-PF, AC, J/ANDCM + I-PF, AC, J/ANDCM + RW, M, J/ANDCM + RW, B, J/ANDCM +424: R, J/DONE + I, J/DONE + W, M, J/MOVE ;SETAM = MOVEM + W, M, J/MOVE ;SETAB, TOO +430: R-PF, AC, J/XOR + I-PF, AC, J/XOR + RW, M, J/XOR + RW, B, J/XOR +434: R-PF, AC, J/IOR + I-PF, AC, J/IOR + RW, M, J/IOR + RW, B, J/IOR +440: R-PF, AC, J/ANDCB + I-PF, AC, J/ANDCB + RW, M, J/ANDCB + RW, B, J/ANDCB +444: R-PF, AC, J/EQV + I-PF, AC, J/EQV + RW, M, J/EQV + RW, B, J/EQV +450: I-PF, AC, J/SETCA + I-PF, AC, J/SETCA + IW, M, J/SETCA + IW, B, J/SETCA +454: R-PF, AC, J/ORCA + I-PF, AC, J/ORCA + RW, M, J/ORCA + RW, B, J/ORCA +460: R-PF, AC, J/SETCM + I-PF, AC, J/SETCM + RW, M, J/SETCM + RW, B, J/SETCM +464: R-PF, AC, J/ORCM + I-PF, AC, J/ORCM + RW, M, J/ORCM + RW, B, J/ORCM +470: R-PF, AC, J/ORCB + I-PF, AC, J/ORCB + RW, M, J/ORCB + RW, B, J/ORCB +474: I-PF, AC, J/SETO + I-PF, AC, J/SETO + IW, M, J/SETO + IW, B, J/SETO + +500: R-PF, AC, J/HLL + I-PF, AC, J/HLL + RW, M, J/HRR ;HLLM = HRR EXCEPT FOR STORE + RW, S, J/MOVE ;HLLS = MOVES + R-PF, AC, J/HRL + I-PF, AC, J/HRL + RW, M, J/HRLM + RW, S, J/HRLS +510: R-PF, AC, J/HLLZ + I-PF, AC, J/HLLZ + W, M, J/HLLZ + RW, S, J/HLLZ + R-PF, AC, J/HRLZ + I-PF, AC, J/HRLZ + W, M, J/HRLZ + RW, S, J/HRLZ +520: R-PF, AC, J/HLLO + I-PF, AC, J/HLLO + W, M, J/HLLO + RW, S, J/HLLO + R-PF, AC, J/HRLO + I-PF, AC, J/HRLO + W, M, J/HRLO + RW, S, J/HRLO +530: R-PF, AC, J/HLLE + I-PF, AC, J/HLLE + W, M, J/HLLE + RW, S, J/HLLE + R-PF, AC, J/HRLE + I-PF, AC, J/HRLE + W, M, J/HRLE + RW, S, J/HRLE +540: R-PF, AC, J/HRR + I-PF, AC, J/HRR + RW, M, J/HLL ;HRRM = HLL EXCEPT FOR STORE + RW, S, J/MOVE ;HRRS = MOVES + R-PF, AC, J/HLR + I-PF, AC, J/HLR + RW, M, J/HLRM + RW, S, J/HLRS +550: R-PF, AC, J/HRRZ + I-PF, AC, J/HRRZ + W, M, J/HRRZ + RW, S, J/HRRZ + R-PF, AC, J/HLRZ + I-PF, AC, J/HLRZ + W, M, J/HLRZ + RW, S, J/HLRZ +560: R-PF, AC, J/HRRO + I-PF, AC, J/HRRO + W, M, J/HRRO + RW, S, J/HRRO + R-PF, AC, J/HLRO + I-PF, AC, J/HLRO + W, M, J/HLRO + RW, S, J/HLRO +570: R-PF, AC, J/HRRE + I-PF, AC, J/HRRE + W, M, J/HRRE + RW, S, J/HRRE + R-PF, AC, J/HLRE + I-PF, AC, J/HLRE + W, M, J/HLRE + RW, S, J/HLRE + +600: I, J/DONE ;TRN- IS NOP + I, J/DONE ;SO IS TLN- + I, TNE, J/TDXX + I, TNE, J/TSXX + I, TNA, J/TDX + I, TNA, J/TSX + I, TNN, J/TDXX + I, TNN, J/TSXX +610: I, J/DONE ;TDN- IS A NOP + I, J/DONE ;TSN- ALSO + R, TNE, J/TDXX + R, TNE, J/TSXX + R, TNA, J/TDX + R, TNA, J/TSX + R, TNN, J/TDXX + R, TNN, J/TSXX +620: I, TZ-, J/TDX + I, TZ-, J/TSX + I, TZE, J/TDXX + I, TZE, J/TSXX + I, TZA, J/TDX + I, TZA, J/TSX + I, TZN, J/TDXX + I, TZN, J/TSXX +630: R, TZ-, J/TDX + R, TZ-, J/TSX + R, TZE, J/TDXX + R, TZE, J/TSXX + R, TZA, J/TDX + R, TZA, J/TSX + R, TZN, J/TDXX + R, TZN, J/TSXX +640: I, TC-, J/TDX + I, TC-, J/TSX + I, TCE, J/TDXX + I, TCE, J/TSXX + I, TCA, J/TDX + I, TCA, J/TSX + I, TCN, J/TDXX + I, TCN, J/TSXX +650: R, TC-, J/TDX + R, TC-, J/TSX + R, TCE, J/TDXX + R, TCE, J/TSXX + R, TCA, J/TDX + R, TCA, J/TSX + R, TCN, J/TDXX + R, TCN, J/TSXX +660: I, TO-, J/TDX + I, TO-, J/TSX + I, TOE, J/TDXX + I, TOE, J/TSXX + I, TOA, J/TDX + I, TOA, J/TSX + I, TON, J/TDXX + I, TON, J/TSXX +670: R, TO-, J/TDX + R, TO-, J/TSX + R, TOE, J/TDXX + R, TOE, J/TSXX + R, TOA, J/TDX + R, TOA, J/TSX + R, TON, J/TDXX + R, TON, J/TSXX + +700: IOT, AC DISP, J/GRP700 ;APR & PI + IOT, AC DISP, J/GRP701 ;PAG & CCA +702: IOT, AC DISP, M, J/GRP702 ;.RD. & .WR. +703: I, B/3, J/IOT700 +704: IOT, J/UMOVE + IOT, J/UMOVEM +706: I, B/6, J/IOT700 + I, B/7, J/IOT700 +710: IOT, WORD-TNE, J/TIOX ;TIOE ;IORDI +711: IOT, WORD-TNN, J/TIOX ;TION ;IORDQ +712: IOT, B/10, J/RDIO ;RDIO ;IORD +713: IOT, B/10, J/WRIO ;WRIO ;IOWR +714: IOT, B/10, J/BIXUB ;BSIO ;IOWRI +715: IOT, B/14, J/BIXUB ;BCIO ;IOWRQ +716: I, B/6, J/IOT710 + I, B/7, J/IOT710 +720: IOT, TNE, J/TIOX ;TIOEB ;IORDBI +721: IOT, TNN, J/TIOX ;TIONB ;IORDBQ +722: IOT, B/0, J/RDIO ;RDIOB ;IORDB +723: IOT, B/0, J/WRIO ;WRIOB ;IOWRB +724: IOT, B/0, J/BIXUB ;BSIOB ;IOWRBI +725: IOT, B/4, J/BIXUB ;BCIOB ;IOWRBQ +726: I, B/6, J/IOT720 + I, B/7, J/IOT720 +730: I, B/0, J/IOT730 + I, B/1, J/IOT730 + I, B/2, J/IOT730 + I, B/3, J/IOT730 + I, B/4, J/IOT730 + I, B/5, J/IOT730 + I, B/6, J/IOT730 + I, B/7, J/IOT730 +740: I, B/0, J/IOT740 + I, B/1, J/IOT740 + I, B/2, J/IOT740 + I, B/3, J/IOT740 + I, B/4, J/IOT740 + I, B/5, J/IOT740 + I, B/6, J/IOT740 + I, B/7, J/IOT740 +750: I, B/0, J/IOT750 + I, B/1, J/IOT750 + I, B/2, J/IOT750 + I, B/3, J/IOT750 + I, B/4, J/IOT750 + I, B/5, J/IOT750 + I, B/6, J/IOT750 + I, B/7, J/IOT750 +760: I, B/0, J/IOT760 + I, B/1, J/IOT760 + I, B/2, J/IOT760 + I, B/3, J/IOT760 + I, B/4, J/IOT760 + I, B/5, J/IOT760 + I, B/6, J/IOT760 + I, B/7, J/IOT760 +770: I, B/0, J/IOT770 + I, B/1, J/IOT770 + I, B/2, J/IOT770 + I, B/3, J/IOT770 + I, B/4, J/IOT770 + I, B/5, J/IOT770 + I, B/6, J/IOT770 + I, B/7, J/IOT770 diff --git a/src/kshack/extend.4 b/src/kshack/extend.4 new file mode 100755 index 00000000..bdaf8043 --- /dev/null +++ b/src/kshack/extend.4 @@ -0,0 +1,1115 @@ +;;;-*-Fundamental-*- + +.TOC "EXTEND -- DISPATCH ROM ENTRIES" + + .DCODE +001: I, SJCL, J/L-CMS + I, SJCE, J/L-CMS + I, SJCLE, J/L-CMS + I, B/2, J/L-EDIT + I, SJCGE, J/L-CMS + I, SJCN, J/L-CMS + I, SJCG, J/L-CMS + +010: I, B/1, J/L-DBIN ;CVTDBO + I, B/4, J/L-DBIN ;CVTDBT + I, B/1, J/L-BDEC ;CVTBDO + I, B/0, J/L-BDEC ;CVTBDT + +014: I, B/1, J/L-MVS ;MOVSO + I, B/0, J/L-MVS ;MOVST + I, B/2, J/L-MVS ;MOVSLJ + I, B/3, J/L-MVS ;MOVSRJ + +020: I, J/L-XBLT + I, J/L-SPARE-A + I, J/L-SPARE-B + I, B/0, J/L-SPARE-C + I, B/1, J/L-SPARE-C + I, B/2, J/L-SPARE-C + I, B/4, J/L-SPARE-C + I, B/10, J/L-SPARE-C + .UCODE + +1740: +L-CMS: LUUO +1741: +L-EDIT: LUUO +1742: +L-DBIN: LUUO +1743: +L-BDEC: LUUO +1744: +L-MVS: LUUO +1746: +L-XBLT: LUUO +1747: +L-SPARE-A: LUUO +1750: +L-SPARE-B: LUUO +1751: +L-SPARE-C: LUUO + +;NOTE: WE DO NOT NEED TO RESERVE 3746 TO 3751 BECAUSE THE CODE +; AT EXTEND DOES A RANGE CHECK. + + .TOC "EXTEND -- INSTRUCTION SET DECODING" + +;EACH INSTRUCTION IN THE RANGE 1-23 GOES TO 1 OF 2 PLACES +; 1740-1747 IF NOT UNDER EXTEND +; 3740-3747 IF UNDER EXTEND + + .DCODE +123: I,READ/1, J/EXTEND + .UCODE + +1467: +EXTEND: MEM READ, [BR]_MEM ;FETCH INSTRUCTION +=0** TL [BR], #/760740, ;IN RANGE 0-17 (AND AC#=0) + CALL [BITCHK] ;TRAP IF NON-ZERO BITS FOUND + [BRX]_[HR].AND.# CLR RH, ;SPLIT OUT AC NUMBER + #/000740 ; FROM EXTEND INSTRUCTION + [BR]_[BR].OR.[BRX], ;LOAD IR AND AC # + HOLD RIGHT, LOAD IR ; .. + READ [BR], LOAD BYTE EA, ;LOAD XR # + J/EXTEA0 ;COMPUTE E1 + +EXTEA0: WORK[E0]_[AR] +EXTEA1: EA MODE DISP +=100* +EXTEA: [BR]_[BR]+XR +EXTDSP: [BR]_EA FROM [BR], LOAD VMA, + B DISP, J/EXTEXT + [BR]_[BR]+XR, START READ, PXCT EXTEND EA, LOAD VMA, J/EXTIND + VMA_[BR], START READ, PXCT EXTEND EA + +EXTIND: MEM READ, [BR]_MEM, HOLD LEFT, LOAD BYTE EA, J/EXTEA1 + +;HERE TO EXTEND SIGN FOR OFFSET MODES +=1110 +EXTEXT: WORK[E1]_[BR], ;SAVE E1 + DISP/DROM, J/3400 ;GO TO EXTENDED EXECUTE CODE + READ [BR], SKIP DP18 ;NEED TO EXTEND SIGN +=0 WORK[E1]_[BR], ;POSITIVE + DISP/DROM, J/3400 + [BR]_#, #/777777, HOLD RIGHT, ;NEGATIVE + J/EXTEXT + + .TOC "EXTEND -- MOVE STRING -- SETUP" + +;HERE TO MOVE A STRING +;COME HERE WITH: +; AR/ E0 +; BR/ E1 +; +3744: +MVS: [AR]_[AR]+1, ;GO FETCH FILL + LOAD VMA, ; BYTE + START READ, ; .. + CALL [GTFILL] ;SUBROUTINE TO COMPLETE +3754: [BR]_AC[DLEN] ;GET DEST LENGTH AND FLAGS +=0** TL [BR], #/777000, ;ANY FLAGS SET? + CALL [BITCHK] ;SEE IF ILLEGAL + [AR]_AC ;GET SRC LENGTH AND FLAGS +=0 [BRX]_[AR].AND.# CLR RH, ;COPY FLAGS TO BRX + #/777000, ; .. + CALL [CLRFLG] ;CLEAR FLAGS IN AR + ;NEW DLEN IS - + AC[DLEN]_[AR]-[BR], 3T, ;COMPUTE DIFFERENCE + SKIP DP0 ;WHICH IS SHORTER? +=0 [AR]_.NOT.[BR], ;DESTINATION + J/MVS1 ;GET NEGATIVE LENGTH + [AR]_.NOT.[AR] ;SOURCE +MVS1: WORK[SLEN]_[AR], ; .. + B DISP ;SEE WHAT TYPE OF MOVE +;SLEN NOW HAS --1 +=1100 + STATE_[SRC], J/MOVELP ;TRANSLATE--ALL SET + [BR]_AC[DSTP], J/MVSO ;OFFSET BUILD MASK + [ARX]_[AR], ;LEFT JUSTIFY + J/MOVST0 ; .. + [ARX]_AC[DLEN], ;RIGHT JUSTIFY + SKIP DP0, 4T, ;WHICH IS SHORTER? + J/MOVRJ + +MVSO: READ [BR], FE_S+2 ;GET DST BYTE SIZE + Q_0, BYTE STEP ;BUILD AN S BIT MASK +=0* +MVSO1: GEN MSK [AR], BYTE STEP, J/MVSO1 + [AR]_.NOT.Q ;BITS WHICH MUST NOT BE SET + WORK[MSK]_[AR].AND.[MASK], ;SAVE FOR SRCMOD + J/MOVLP0 ;GO ENTER LOOP + + .TOC "EXTEND -- MOVE STRING -- OFFSET/TRANSLATE" + +;HERE IS THE LOOP FOR OFFSET AND TRANSLATED MOVES +=000 +MOVELP: [AR]_WORK[SLEN]+1, ;UPDATE STRING LENGTH + CALL [SRCMOD] ;GET A SOURCE BYTE +=001 [ARX]_[AR], SKIP DP0, ;(1) LENGTH EXHAUSTED + J/MOVST2 ; SEE IF FILL IS NEEDED +=100 [AR]_-WORK[SLEN], ;(4) ABORT + J/MVABT ; .. + STATE_[SRC+DST], ;(5) NORMAL--STORE DST BYTE + CALL [PUTDST] ; .. +=111 +MOVLP0: STATE_[SRC], J/MOVELP ;(7) DPB DONE += + +;HERE TO ABORT A STRING MOVE DUE TO TRANSLATE OR OFFSET FAILURE + +MVABT: [BR]_AC[DLEN], ;WHICH STRING IS LONGER + SKIP DP0, 4T +=0 +MVABT1: AC[DLEN]_[AR], J/MVABT2 ;PUT AWAY DEST LEN + [AR]_[AR]-[BR], ;DEST LEN WAS GREATER + J/MVABT1 ;STICK BACK IN AC + +MVABT2: [AR]_.NOT.WORK[SLEN] ;GET UNDECREMENTED SLEN + READ [BR], SKIP DP0 ;NEED TO FIXUP SRC? +=0 [AR]_[AR]+[BR] ;SRC LONGER BY (DLEN) +MVEND: [AR]_[AR].OR.[BRX] ;PUT BACK SRC FLAGS + END STATE, J/STAC ;ALL DONE + + .TOC "EXTEND -- MOVE STRING -- MOVSRJ" + +=00 +MOVRJ: [AR]_AC[SRCP], J/MVSKP ;SRC LONGER, SKIP OVER SOME + STATE_[DSTF], ;DST LONGER, FILL IT + CALL [MOVFIL] ; .. +=11 [ARX]_WORK[SLEN]+1, ;DONE FILLING + J/MOVST1 ;GO MOVE STRING + +;HERE TO SKIP OVER EXTRA SOURCE BYTES +MVSKP: AC[SRCP]_[AR], ;PUT POINTER BACK + SKIP -1MS ;[121] Is there a timer interrupt? +=0 WORK[SV.AR]_[AR], J/MVSK2 ;[121][123] Yes, save regs for interrupt. + [ARX]_[ARX]-1, 3T, ;DONE SKIPPING? + SKIP DP0 +=0 IBP DP, IBP SCAD, ;NO--START THE IBP + SCAD DISP, SKIP IRPT, ;4-WAY DISPATCH + 3T, J/MVSKP1 ;GO BUMP POINTER + AC[DLEN]_0, ;LENGTHS ARE NOW EQUAL + J/MOVST4 ;GO MOVE STRING + +=00 +MVSKP1: [AR]_[BR], J/MVSKP ;NO OVERFLOW + [AR]_.NOT.WORK[SLEN], ;INTERRUPT [121] or timer + J/MVSK3 ; .. + SET P TO 36-S, ;WORD OVERFLOW + J/MVSKP2 ;FIXUP Y + [AR]_.NOT.WORK[SLEN] ;INTERRUPT +MVSK3: AC[DLEN]_[AR] ;RESET DLEN +=0 [AR]_[AR]+[ARX], + CALL [INCAR] ;ADD 1 TO AR + AC_[AR].OR.[BRX], ;PUT BACK FLAGS + J/ITRAP ;DO INTERRUPT TRAP + +MVSKP2: [AR]_[AR]+1, HOLD LEFT, ;BUMP Y + J/MVSKP ;KEEP GOING + + ;BEGIN EDIT [123] +MVSK2: WORK[SV.BR]_[BR] ;SAVE ALL + WORK[SV.ARX]_[ARX] ;THE REGISTERS + WORK[SV.BRX]_[BRX] ;FOR THE TICK +=0* CALL [TICK] ;UPDATE CLOCK AND SET INTERUPT + [AR]_WORK[SV.AR] ;NOW PUT + [BR]_WORK[SV.BR] ;THEM ALL + [ARX]_WORK[SV.ARX] ;BACK SO WE + [BRX]_WORK[SV.BRX], ;CAN CONTINUE + J/MVSKP + ;END EDIT [123] + .TOC "EXTEND -- MOVE STRING -- SIMPLE MOVE LOOP" + +;HERE FOR NO-MODIFICATION STRING MOVES +MOVST0: [ARX]_[ARX]+1 ;CANT DO [ARX]_[AR]+1 +MOVST1: STATE_[SRC] ;PREPARE FOR PAGE FAIL +=000 + WORK[SLEN]_[ARX], ;GO GET A SOURCE BYTE + SKIP DP0, CALL [GSRC] ; .. +MOVSTX: [ARX]_[AR], ;SHORT STRING RAN OUT + SKIP DP0, J/MOVST2 ;GO SEE IF FILL NEEDED +=010 STATE_[SRC+DST], ;WILL NEED TO BACK UP BOTH POINTERS + CALL [PUTDST] ;STORE BYTE +=110 +MOVST4: [ARX]_WORK[SLEN]+1, ;COUNT DOWN LENGTH + J/MOVST1 ;LOOP OVER STRING += +=00 +MOVST2: AC[DLEN]_0, J/MOVST3 ;CLEAR DEST LEN, REBUILD SRC + STATE_[DST], CALL [MOVFIL] ;FILL OUT DEST +=11 AC_[BRX], J/ENDSKP ;ALL DONE + +MOVST3: AC_[ARX].OR.[BRX] ;REBUILD SRC + END STATE, J/SKIPE ; .. + + .TOC "EXTEND -- COMPARE STRING" + +3740: +CMS: [ARX]_AC[DLEN] ;GET DEST LEN +=0** TL [ARX], #/777000, CALL [BITCHK] + [BRX]_AC ;GET SRC LEN +=0** TL [BRX], #/777000, CALL [BITCHK] + [BRX]-[ARX], 3T, SKIP DP0 ;WHICH STRING IS LONGER? +=0 [AR]_[AR]+1 ;SRC STRING IS LONGER + VMA_[AR]+1, START READ ;DST STRING +=0 [AR]_0, ;FORCE FIRST COMPARE TO BE + ;EQUAL + CALL [LOADQ] ;PUT FILL INTO Q + WORK[FILL]_Q, ;SAVE FILLER + J/CMS2 ;ENTER LOOP + +;HERE IS THE COMPARE LOOP. +; ARX/ CONATINS REMAINING DEST LENGTH +; BRX/ CONTAINS REMAINING SOURCE LENGTH +=0 +CMS3: ;BYTES ARE NOT EQUAL + END STATE, ;NO MORE SPECIAL PAGE FAIL ACTION + SKIP-COMP DISP ;SEE SKIP-COMP-TABLE +CMS4: [AR]_AC[SRCP] ;GET BYTE POINTER + READ [BRX], SKIP DP0 ;MORE IN SOURCE STRING? +=00 STATE_[EDIT-SRC], ;PREPARE FOR PAGE FAIL + CALL [GETSRC] ; GO GET BYTE + READ [ARX], SKIP DP0, ;NO MORE SRC--SEE IF MORE DEST + J/CMS5 ; .. + WORK[CMS]_[AR] ;SAVE SRC BYTE += + AC_[BRX] ;PUT BACK SRC LEN + STATE_[COMP-DST] ;HAVE TO BACK UP IF DST FAILS + READ [ARX], SKIP DP0 ;ANY MORE DEST? +=00 +CMS6: CALL [CMPDST] ;MORE DEST BYTES + [AR]_WORK[FILL], ;OUT OF DEST BYTES + J/CMS7 ;GO DO COMPARE + AC[DLEN]_[ARX] ;GOT A BYTE, UPDATE LENGTH += +CMS7: [AR]_[AR].AND.[MASK], ;MAKE MAGNITUDES + WORK[CMS] ;WARM UP RAM + [BR]_[MASK].AND.WORK[CMS], 2T ;GET SRC MAGNITUDE + [AR]_[BR]-[AR] REV ;UNSIGNED COMPARE +CMS2: [ARX]_[ARX]-1 ;UPDATE LENGTHS + [BRX]_[BRX]-1 ; .. + READ [AR], SKIP AD.EQ.0, J/CMS3 ;SEE IF EQUAL + +=0 +CMS5: Q_WORK[FILL], J/CMS8 ;MORE DST--GET SRC FILL + [AR]_0, J/CMS3 ;STRINGS ARE EQUAL +CMS8: STATE_[EDIT-DST] ;JUST DST POINTER ON PAGE FAIL + WORK[CMS]_Q, J/CMS6 ;MORE DST--SAVE SRC FILL + +=0 +CMPDST: [AR]_AC[DSTP], ;GET DEST POINTER + CALL [IDST] ;UPDATE IT + READ [AR], ;LOOK AT BYTE POINTER + FE_FE.AND.S#, S#/0770, ;MASK OUT BIT 6 + BYTE DISP, J/LDB1 ;GO LOAD BYTE + + .TOC "EXTEND -- DECIMAL TO BINARY CONVERSION" + +3742: +DBIN: [AR]_[777777] XWD 0 ;IF WE ARE IN OFFSET MODE + WORK[MSK]_[AR] ; ONLY ALLOW 18 BITS + ;RANGE CHECKED (0-10) LATER + [AR]_AC ;GET SRC LENGTH + [BRX]_[AR].AND.# CLR RH, ;SPLIT OUT FLAGS + #/777000 ; .. +=0* [ARX]_AC[BIN1], ;GET LOW WORD + CALL [CLARX0] ;CLEAR BIT 0 OF ARX + AC[BIN1]_[ARX] ;STORE BACK +=0 READ [BRX], SKIP DP0, ;IS S ALREADY SET? + CALL [CLRBIN] ;GO CLEAR BIN IF NOT + [AR]_[AR].AND.#, ;CLEAR FLAGS FROM LENGTH + #/000777, HOLD RIGHT, ; .. + B DISP ;SEE IF OFFSET OR TRANSLATE +=1110 +DBIN1: STATE_[CVTDB], J/DBIN2 ;TRANSLATE--LEAVE S ALONE + [BRX]_[BRX].OR.#, ;OFFSET--FORCE S TO 1 + #/400000, HOLD RIGHT, + J/DBIN1 +DBIN2: WORK[SLEN]_.NOT.[AR] ;STORE -SLEN-1 + +;HERE IS THE MAIN LOOP +=0*0 +DBINLP: [AR]_WORK[SLEN]+1, CALL [SRCMOD] ;(0) GET MODIFIED SRC BYTE + TL [BRX], #/100000, ;(1) DONE, IS M SET? + J/DBXIT + [AR]_.NOT.WORK[SLEN], ;(4) ABORT + J/DBABT ; .. + [AR]-#, #/10., ;(5) NORMAL--SEE IF 0-9 + 4T, SKIP DP18 ; .. +=0 [AR]_.NOT.WORK[SLEN], ;DIGIT TOO BIG + J/DBABT ;GO ABORT CVT + +;HERE TO ADD IN A DIGIT + [BR]_AC[BIN0], 4T, ;GET HIGH BINARY + SKIP AD.EQ.0 ;SEE IF SMALL +=00 +DBSLO: [ARX]_AC[BIN1], ;TOO BIG + CALL [DBSLOW] ;GO USE DOUBLE PRECISION PATHS + [BR]_AC[BIN1], ;GET LOW WORD + J/DBFAST ;MIGHT FIT IN 1 WORD + J/DBINLP ;RETURN FROM DBSLOW + ;GO DO NEXT DIGIT += +DBFAST: TL [BR], #/760000 ;WILL RESULT FIT IN 36 BITS? +=0 J/DBSLO ;MAY NOT FIT--USE DOUBLE WORD + [BR]_AC[BIN1]*2 ;COMPUTE AC*2 + [BR]_[BR]*2, AC[BIN1] ;COMPUTE AC*4 +=0 [BR]_[BR]+AC[BIN1], 2T, ;COMPUTE AC*5 + CALL [SBRL] ;COMPUTE AC*10 + AC[BIN1]_[AR]+[BR], 3T, ;NEW BINARY RESULT + J/DBINLP ;DO NEXT DIGIT + +;HERE IF NUMBER DOES NOT FIT IN ONE WORD + +=000 +DBSLOW: [BR]_AC[BIN0], ;FETCH HIGH WORD + CALL [MULBY4] ;MULTIPLY BY 4 + [ARX]_[ARX]+AC[BIN1], ;COMPUTE VALUE * 5 + SKIP CRY1, 4T, ;SEE IF OVERFLOW + CALL [ADDCRY] ;GO ADD CARRY +=101 [BR]_[BR]+AC[BIN0] ;ADD IN HIGH WORD += +=000 CALL [DBLDBL] ;MAKE * 10 + [ARX]_[ARX]+[AR], 3T, ;ADD IN NEW DIGIT + SKIP CRY1, ;SEE IF OVERFLOW + CALL [ADDCRY] ;ADD IN THE CARRY +=101 AC[BIN1]_[ARX] ;PUT BACK ANSWER += + AC[BIN0]_[BR], ; .. + RETURN [2] ;GO DO NEXT BYTE + +;HERE TO DOUBLE BR!ARX +=000 +MULBY4: CALL [DBLDBL] ;DOUBLE TWICE +DBLDBL: [BR]_[BR]+[BR] ;DOUBLE HIGH WORD FIRST + ;(SO WE DON'T DOUBLE CARRY) + [ARX]_[ARX]+[ARX], ;DOUBLE LOW WORD + SKIP CRY1, 3T, ;SEE IF CARRY + CALL [ADDCRY] ;ADD IN CARRY +=110 RETURN [1] ;ALL DONE += + +;HERE TO ADD THE CARRY +=0 +ADDCRY: RETURN [4] ;NO CARRY + CLEAR [ARX]0 ;KEEP LOW WORD POSITIVE + [BR]_[BR]+1, ;ADD CARRY + RETURN [4] ;ALL DONE + +;HERE TO ABORT CONVERSION +DBABT: [BRX]_[BRX].OR.[AR] ;PUT BACK UNUSED LENGTH + [PC]_[PC]-1, HOLD LEFT, ;DO NOT SKIP + J/DBDONE ;GO FIX UP SIGN COPY + +;HERE AT END +=0 +DBXIT: [ARX]_AC[BIN1], ;GET LOW WORD + J/DBNEG ;GO NEGATE +DBDONE: [AR]_AC[BIN1] ;FETCH LOW WORD + [BR]_AC[BIN0], 4T, ;GET HIGH WORD + SKIP DP0 ;WHAT SIGN +=0 CLEAR [AR]0, J/DBDN1 ;POSITIVE + [AR]_[AR].OR.#, #/400000, HOLD RIGHT +DBDN1: AC[BIN1]_[AR] ;STORE AC BACK +=0 AC_[BRX] TEST, ;RETURN FLAGS + SKIP DP0, CALL [CLRBIN] ;CLEAR BIN IS S=0 +ENDSKP: END STATE, J/SKIP ;NO--ALL DONE + +DBNEG: CLEAR ARX0 ;CLEAR EXTRA SIGN BIT + [ARX]_-[ARX], 3T, ;NEGATE AND SEE IF + SKIP AD.EQ.0, AC[BIN0] ; ANY CARRY +=0 [AR]_.NOT.AC[BIN0], 2T, J/STAC34 ;NO CARRY + [AR]_-AC[BIN0], 3T, ;CARRY + SKIP AD.EQ.0 ;SEE IF ALL ZERO +=0 [ARX]_[400000] XWD 0 ;MAKE COPY OF SIGN + ; UNLESS HIGH WORD IS ZERO +STAC34: AC[BIN0]_[AR] ;PUT BACK ANSWER + AC[BIN1]_[ARX], J/DBDONE ; .. + +;HELPER SUBROUTINE TO CLEAR AC[BIN0] AND AC[BIN1] IF S=0 +;CALL WITH: +; READ [BRX], SKIP DP0, CALL [CLRBIN] +;RETURNS 1 ALWAYS +=0 +CLRBIN: AC[BIN0]_0, J/CLRB1 + RETURN [1] +CLRB1: AC[BIN1]_0, RETURN [1] + + .TOC "EXTEND -- BINARY TO DECIMAL CONVERSION" + +3743: +BDEC: [BRX]_AC[DLEN], ;GET LENGTH AND FLAGS + SKIP FPD ;CONTINUE FROM INTERUPT? +=0 [BRX]_[BRX].AND.#, ;JUST KEEP THE FLAGS + #/777000, ; .. + J/BDEC0 ;COMPUTE NEW FLAGS +DOCVT: [AR]_AC, J/DOCVT1 ;ALL SET PRIOR TO TRAP +BDEC0: [ARX]_AC[1] ;GET LOW BINARY + [AR]_AC, SC_20. ;GET HIGH WORD, SET STEP COUNT +=0* WORK[BDL]_[ARX], ;SAVE IN CASE OF ABORT + CALL [CLARX0] ;MAKE SURE BIT 0 IS OFF + WORK[BDH]_[AR], ;SAVE HIGH WORD AND + SKIP DP0 ; TEST SIGN +=0 +BDEC1: [BRX]_0, HOLD LEFT, ;POSITIVE, CLEAR RH OF BRX + J/BDEC3 ;COMPUTE # OF DIGITS REQUIRED + [BRX]_[BRX].OR.#, ;NEGATIVE, SET M + #/100000, HOLD RIGHT ; .. +=0* +BDEC2: CLEAR ARX0, CALL [DBLNG1] ;NEGATE AR!ARX + AC_[AR] TEST, ;PUT BACK ANSWER + SKIP DP0 ;IF STILL MINUS WE HAVE + ; 1B0, AND NO OTHER BITS +=0 AC[1]_[ARX], J/BDEC1 ;POSITIVE NOW + [ARX]_[ARX]+1 ;JUST 1B0--ADD 1 + [BRX]_[BRX].OR.#, ;AND REMEMBER THAT WE DID + #/040000, HOLD RIGHT, ; IN LEFT HALF OF AC+3 + J/BDEC2 ; NEGATE IT AGAIN +=0 +BDEC3: [AR]_AC, J/BDEC4 ;GET HIGH AC + [BRX]_[BRX].OR.#, ;NO LARGER POWER OF 10 FITS + #/200000, ;SET N FLAG (CLEARLY NOT 0) + HOLD RIGHT, J/BDEC5 ;SETUP TO FILL, ETC. +=001 +BDEC4: [ARX]_AC[1], ;GET HIGH WORD + CALL [BDSUB] ;SEE IF 10**C(BRX) FITS +=011 [BRX]_[BRX]+1, ;NUMBER FITS--TRY A LARGER ONE + STEP SC, J/BDEC3 ;UNLESS WE ARE OUT OF NUMBERS +=111 TR [BRX], #/777777 ;ANY DIGITS REQUIRED? += +=0 [BRX]_[BRX].OR.#, ;SOME DIGITS NEEDED, + #/200000, HOLD RIGHT, ; SET N FLAG + J/BDEC5 ;CONTINUE BELOW + [BRX]_[BRX]+1 ;ZERO--FORCE AT LEAST 1 DIGIT + +=0 +BDEC5: [AR]_AC[DLEN], ;GET LENGTH + CALL [CLRFLG] ;REMOVE FLAGS FROM AR + [BR]_0 + [BR]_[BRX], HOLD LEFT ;GET # OF DIGITS NEEDED + [BR]_[BR]-[AR], ;NUMBER OF FILLS NEEDED + SKIP AD.LE.0 ;SEE IF ENOUGH ROOM +=0 [ARX]_WORK[BDL], ;DOES NOT FIT IN SPACE ALLOWED + J/BDABT ; DO NOT DO CONVERT + READ [BRX], SKIP DP0 ;IS L ALREADY SET +=0 AC[DLEN]_[BRX], ;NO--NO FILLERS + J/DOCVT ;GO CHURN OUT THE NUMBER + + +;HERE TO STORE LEADING FILLERS + [AR]_[BRX], HOLD RIGHT ;MAKE SURE THE FLAGS GET SET + AC[DLEN]_[AR] ; BEFORE WE PAGE FAIL + [AR]_WORK[E0] ;ADDRESS OF FILL (-1) + [AR]_[AR]+1, LOAD VMA, ;FETCH FILLER + START READ + MEM READ, [T0]_MEM ;GET FILLER INTO AR + STATE_[EDIT-DST] ;PAGE FAILS BACKUP DST + WORK[SLEN]_[BR]-1, 3T ;SAVE # OF FILLERS +BDFILL: [AR]_[T0], WORK[SLEN] ;RESTORE FILL BYTE AND + ; WARM UP RAM FILE + [BR]_WORK[SLEN]+1, 3T, ;MORE FILLERS NEEDED? + SKIP DP0 +=000 AC[DLEN]_[BRX], J/DOCVT ;ALL DONE FIX FLAGS AND CONVERT +=001 WORK[SLEN]_[BR], ;SAVE UPDATED LENGTH + CALL [PUTDST] ; AND STORE FILLER +=111 [BR]_AC[DLEN]-1 ;COUNT DOWN STRING LENGTH += + AC[DLEN]_[BR], J/BDFILL ;KEEP FILLING + +;HERE TO STORE THE ANSWER + +DOCVT1: [ARX]_AC[1], ;GET LOW WORD + J/DOCVT2 ;ENTER LOOP FROM BOTTOM +=010 +BDECLP: [BR]_[BR]+1, ;COUNT DIGITS + CALL [BDSUB] ;KEEP SUBTRACTING 10**C(BRX) +=110 WORK[BDH]_[AR] ;SAVE BINARY += + [AR]_[BR]+WORK[E1], ;OFFSET DIGIT + B DISP ;SEE WHICH MODE +=1110 READ [AR], LOAD VMA, ;TRANSLATE, START READING TABLE + START READ, J/BDTBL ; GO GET ENTRY FROM TABLE +BDSET: WORK[BDL]_[ARX] ;SAVE LOW BINARY +=00* STATE_[EDIT-DST], CALL [PUTDST] +=11* [BR]_AC[DLEN]-1 ;UPDATE STRING LENGTH + [AR]_WORK[BDH] + [ARX]_WORK[BDL] + TL [BR], #/040000 ;ARE WE CONVERTING 1B0? +=0 [ARX]_[ARX]+1, J/BDCFLG ;YES--FIX THE NUMBER AND CLEAR FLAG +DOCVT3: AC_[AR] + AC[1]_[ARX] + AC[DLEN]_[BR] ;STORE BACK NEW STRING LENGTH +DOCVT2: [BRX]_[BRX]-1, 3T, SKIP DP18 +=0 [BR]_-1, SET FPD, 3T, J/BDECLP + END STATE, CLR FPD, J/SKIP + +;HERE TO TRANSLATE 1 DIGIT +=0 +BDTBL: END STATE, ;DON'T CHANGE BYTE POINTER IF + ; THIS PAGE FAILS + CALL [LOADAR] ;GO PUT WORD IN AR + TR [BRX], #/777777 ;LAST DIGIT +=0 [AR]_0, HOLD RIGHT, J/BDSET + TL [BRX], #/100000 ;AND NEGATIVE +=0 [AR]_[AR] SWAP ;LAST AND MINUS, USE LH + [AR]_0, HOLD RIGHT, J/BDSET + +BDABT: [AR]_WORK[BDH], J/DAC + +BDCFLG: [BR]_[BR].AND.NOT.#, ;CLEAR FLAG THAT TELLS US + #/040000, HOLD RIGHT, ; TO SUBTRACT 1 AND + J/DOCVT3 ; CONTINUE CONVERTING + +;SUBROUTINE TO SUBRTACT A POWER OF 10 FROM AR!ARX +;CALL WITH: +; AR!ARX/ NUMBER TO BE CONVERTED +; BRX(RIGHT)/ POWER OF 10 +;RETURNS: +; 2 RESULT IS STILL POSITIVE +; 6 RESULT WOULD HAVE BEEN NEGATIVE (RESTORE DONE) +=0 +BDSUB: [T0]_[BRX]+#, 3T, WORK/DECLO, ;ADDRESS OF LOW WORD + J/BDSUB1 ;NO INTERRUPT + J/FIXPC ;INTERRUPT +=0* +BDSUB1: [T1]_[T0], LOAD VMA, ;PUT IN VMA, + CALL [CLARX0] ;FIX UP SIGN OF LOW WORD + [ARX]_[ARX]-RAM, 3T, ;SUBTRACT + SKIP CRY1 ;SEE IF OVERFLOW +=0 [AR]_[AR]-1 ;PROCESS CARRY + [T0]_[BRX]+#, 3T, WORK/DECHI ;ADDRESS OF HIGH WORD + READ [T0], LOAD VMA ;PLACE IN VMA + [AR]_[AR]-RAM, 4T, ;SUBTRACT + SKIP DP0 ;SEE IF IT FIT +=0 +CLARX0: CLEAR ARX0, ;IT FIT, KEEP LOW WORD + + RETURN [2] ; AND RETURN + [AR]_[AR]+RAM ;RESTORE + READ [T1], LOAD VMA + [ARX]_[ARX]+RAM, 3T, SKIP CRY1 +=0 +BDSUB2: CLEAR ARX0, ;KEEP LOW WORD + + RETURN [6] ;RETURN OVERFLOW + [AR]_[AR]+1, ;ADD BACK THE CARRY + J/BDSUB2 ;COMPLETE SUBTRACT + + .TOC "EXTEND -- EDIT -- MAIN LOOP" + +;HERE FOR EDIT INSTRUCTION +;CALL WITH: +; AR/ E0 ADDRESS OF FILL, FLOAT, AND MESSAGE TABLE +; BR/ E1 TRANSLATE TABLE +; +3741: +EDIT: VMA_[AR]+1, START READ, ;FIRST GET FILL BYTE + CALL [GTFILL] ;GO GET IT +3751: [BRX]_AC ;GET PATTERN POINTER +=0** TL [BRX], #/047777, ;MAKE SURE SECTION 0 + CALL [BITCHK] ; .. +EDITLP: VMA_[BRX], START READ ;FETCH PATTERN WORD + END STATE ;NO SPECIAL PAGE FAIL ACTION + [BR]_[BRX] SWAP ;GET PBN IN BITS 20 & 21 +=0 [BR]_[BR]*4, ; .. + CALL [LOADAR] ;GET PATTERN WORD + READ [BR], 3T, DISP/DP LEFT +=1100 + [AR]_[AR] SWAP, SC_7, J/MOVPAT ;(0) BITS 0-8 + [AR]_[AR] SWAP, J/MSKPAT ;(1) BITS 9-17 + [AR]_[AR]*.5, SC_6, J/MOVPAT ;(2) BITS 18-27 + [AR]_[AR].AND.#, #/777, J/EDISP ;(3) BITS 28-35 +=0 +MOVPAT: [AR]_[AR]*.5, STEP SC, J/MOVPAT ;SHIFT OVER +MSKPAT: [AR]_[AR].AND.#, #/777 + +;HERE WITH PATTERN BYTE RIGHT ADJUSTED IN AR +EDISP: [BR]_[AR]*.5, SC_2 ;SHIFT OVER +=0 +EDISP1: [BR]_[BR]*.5, STEP SC, J/EDISP1 + READ [BR], 3T, DISP/DP ;LOOK AT HIGH 3 BITS +=0001 ;(0) OPERATE GROUP + [AR]-#, #/5, 4T, ; SEE IF 0-4 + SKIP DP18, J/EDOPR + ;(1) MESSAGE BYTE + READ [BRX], SKIP DP0, + J/EDMSG + ;(2) UNDEFINED + J/EDNOP + ;(3) UNDEFINED + J/EDNOP + ;(4) UNDEFINED + J/EDNOP + ;(5) SKIP IF M SET + TL [BRX], #/100000, + J/EDSKP + ;(6) SKIP IF N SET + TL [BRX], #/200000, + J/EDSKP + ;(7) SKIP ALWAYS + J/EDSKP + + .TOC "EXTEND -- EDIT -- DECODE OPERATE GROUP" + +;HERE FOR OPERATE GROUP. SKIP IF IN RANGE +=0 +EDOPR: J/EDNOP ;OUT OF RANGE + READ [AR], 3T, DISP/DP ;DISPATCH ON TYPE +=1000 [PC]_[PC]+1, J/EDSTOP ;(0) STOP EDIT + STATE_[EDIT-SRC], ;(1) SELECT SOURCE BYTE + J/EDSEL + READ [BRX], SKIP DP0, ;(2) START SIGNIFICANCE + J/EDSSIG + [BRX]_[BRX].AND.#, ;(3) FIELD SEPERATOR + #/77777, HOLD RIGHT, + J/EDNOP + [BR]_AC[MARK] ;(4) EXCHANGE MARK AND DEST + VMA_[BR], START READ, + J/EDEXMD += + + .TOC "EXTEND -- EDIT -- STOP EDIT" + +;HERE TO END AN EDIT OPERATION. PC IS SET TO SKIP IF NORMAL END +; OR NON-SKIP IF ABORT +EDSTOP: [BR]_.NOT.[BRX], ;AD WILL NOT DO D.AND.NOT.A + FE_S#, S#/10 ;PRESET FE + [AR]_[BRX], 3T, FE_FE+P ;MOVE POINTER, UPBATE PBN + [BR].AND.#, 3T, ;WAS OLD NUMBER 3? + #/030000, SKIP ADL.EQ.0 ; .. +=0 +EDSTP1: [AR]_P, J/STAC ;NO--ALL DONE + [AR]_[AR]+1, ;YES--BUMP WORD # + FE_FE.AND.S#, S#/0700, ;KEEP ONLY FLAG BITS + J/EDSTP1 ;GO STOP EDIT + + .TOC "EXTEND -- EDIT -- START SIGNIFICANCE" + +;HERE WITH DST POINTER IN AR +=110 +EDSSIG: CALL [EDFLT] ;STORE FLT CHAR + J/EDNOP ;DO NEXT PATTERN BYTE + + .TOC "EXTEND -- EDIT -- EXCHANGE MARK AND DESTINATION" + +;HERE WITH ADDRESS OF MARK POINTER IN BR +=0 +EDEXMD: Q_AC[DSTP], ;GET DEST POINTER + CALL [LOADAR] ;GO PUT MARK IN AR + START WRITE ;START WRITE. SEPERATE STEP TO AVOID + ; PROBLEM ON DPM5 + MEM WRITE, MEM_Q ;PUT OLD DEST IN MARK + AC[DSTP]_[AR], J/EDNOP ;PUT BACK DEST POINTER + + .TOC "EXTEND -- EDIT -- PROCESS SOURCE BYTE" + +=0* +EDSEL: [AR]_AC[SRCP], ;PICK UP SRC POINTER + CALL [GETSRC] ;GET SOURCE BYTE + [AR]_[AR]*.5, WORK[E1] ;PREPARE TO TRANSLATE +=000 [AR]_[AR]+WORK[E1], ;GO TRANSLATE BY HALFWORDS + 2T, CALL [TRNAR] ; .. +=010 +EDFILL: READ [AR], ;(2) NO SIGNIFICANCE, GO FILL + SKIP AD.EQ.0, ; SEE IF ANY FILLER + J/EDFIL1 ; GO TO IT + STATE_[EDIT-SRC], ;(3) SIG START, DO FLOAT CHAR + J/EDSFLT +=100 J/EDSTOP ;(4) ABORT +=101 +EDSPUT: STATE_[EDIT-S+D], ;(5) NORMAL, STORE AT DST + CALL [PUTDST] ; .. +=111 + J/EDNOP ;(7) BYTE STORED += + +;HERE TO COMPLETE STORING FILL +=0 +EDFIL1: J/EDSPUT ;STORE FILLER + J/EDNOP ;NO FILLER TO STORE + +;HERE TO DO FLOAT BYTE +=110 +EDSFLT: WORK[FSIG]_[ARX], ;SAVE SIG CHAR + CALL [EDFLT] ;STORE FLOAT CHAR + [AR]_WORK[FSIG] ;RESTORE CHAR + [AR]_[AR].AND.# CLR LH, ;JUST KEEP THE BYTE IN CASE + #/77777, ; DEST BYTE .GT. 15 BITS + J/EDSPUT ;GO STORE CHAR WHICH STARTED THIS ALL + +;SUBRUTINE TO PROCESS FLOAT CHAR +;CALL WITH: +; AR/ POINTER TO STORE @ MARK +;RETURN 7 WITH FLOAT STORED +EDFLT: [BR]_AC[MARK] ;ADDRESS OF MARK POINTER + VMA_[BR], START WRITE ;READY TO STORE + [BR]_AC[DSTP] ;GET DST POINTER + MEM WRITE, MEM_[BR] ;STORE POINTER +=0 [AR]_0 XWD [2], ;FETCH FLOAT CHAR + CALL [EDBYTE] ;GET TBL BYTE + MEM READ, [AR]_MEM, ;GET FLOAT CHAR + SKIP AD.EQ.0 ;SEE IF NULL +=000 + [FLG]_[FLG].OR.#, ;REMEMBER TO BACKUP DST POINTER + STATE/EDIT-DST, ; WILL ALSO BACKUP SRC IF CALLED + HOLD LEFT, ; FROM SELECT + CALL [PUTDST] ; STORE FLOAT +=001 [BRX]_[BRX].OR.#, #/400000, + HOLD RIGHT, J/EDFLT1 ;NULL +=110 [BRX]_[BRX].OR.#, #/400000, + HOLD RIGHT, J/EDFLT1 ;MARK STORED += +EDFLT1: AC_[BRX], ;SAVE FLAGS SO WE DON'T + ;TRY TO DO THIS AGAIN IF + ;NEXT STORE PAGE FAILS + RETURN [7] ;AND RETURN + + .TOC "EXTEND -- EDIT -- MESSAGE BYTE" + +;HERE WITH SKIP ON S +=0 +EDMSG: [AR]_WORK[FILL], ;GET FILL BYTE + SKIP AD.EQ.0, 4T, ;SEE IF NULL + J/EDMSG1 ;GO STORE + [AR]_[AR].AND.# CLR LH, ;GET OFFSET INTO TABLE + #/77 +=0 [AR]_[AR]+1, WORK[E0], ;PLUS 1 + CALL [EDBYTE] ;GET TBL BYTE + MEM READ, [AR]_MEM ;FROM MEMORY +=000 +EDMSG1: STATE_[EDIT-DST], ;WHAT TO DO ON PAGE FAILS + CALL [PUTDST] ;STORE MESSAGE BYTE +=001 J/EDNOP ;NULL FILLER +=110 J/EDNOP ;NEXT BYTE += + +EDBYTE: [AR]_[AR]+WORK[E0] ;GET OFFSET INTO TABLE + VMA_[AR], START READ, ;START MEMORY CYCLE + RETURN [1] ;RETURN TO CALLER + + .TOC "EXTEND -- EDIT -- SKIP" + +=0 +;HERE TO SKIP ALWAYS +EDSKP: [AR]_[AR].AND.#, #/77, ;JUST KEEP SKIP DISTANCE + J/EDSKP1 ;CONTINUE BELOW +;HERE IF WE DO NOT WANT TO SKIP + J/EDNOP +EDSKP1: [AR]_([AR]+1)*2 ;GIVE 1 EXTRA SKIP + READ [AR], SCAD/A*2, ;PUT THE ADJUSTMENT + SCADA/BYTE5, 3T, LOAD SC, ; THE SC + J/EDNOP1 ;JOIN MAIN LOOP + + + .TOC "EXTEND -- EDIT -- ADVANCE PATTERN POINTER" + +EDNOP: SC_0 ;NO SKIP +EDNOP1: READ [BRX], 3T, FE_P ;PUT PBN IN FE + FE_FE.AND.S#, S#/30 ;JUST BYTE # + FE_FE+SC ;ADD IN ANY SKIP DISTANCE + FE_FE+S#, S#/10 ;BUMP PBN + [AR]_FE, ;GET NUMBER OF WORDS + LOAD SC ;PUT MSB WHERE IT CAN BE TESTED + ; QUICKLY + [AR]_[AR].AND.# CLR LH, ;KEEP ONLY 1 COPY + #/170, SKIP/SC ; .. +=0 +EDN1A: [AR]_[AR]*.5, SC_0, + J/EDNOP2 ;READY TO SHIFT OFF BYTE WITHIN + ; WORD + [AR]_[AR].OR.#, #/200, ;GET THE SIGN BIT OF THE FE + HOLD LEFT, ; INTO THE AR. ONLY HAPPENS ON + J/EDN1A ; SKP 76 OR SKP 77 +=0 +EDNOP2: [AR]_[AR]*.5, STEP SC, J/EDNOP2 + [BRX]_[BRX]+[AR], ;UPDATE WORD ADDRESS + HOLD LEFT + [AR]_P ;PUT PBN BACK IN BRX + [BRX]_[BRX].AND.#, ;JUST KEEP FLAGS + #/700000, ; .. + HOLD RIGHT + [AR]_[AR].AND.#, ;JUST KEEP PBN + #/030000 + [BRX]_[BRX].OR.[AR], ;FINAL ANSWER + HOLD RIGHT + AC_[BRX], J/EDITLP ;DO NEXT FUNCTION + + .TOC "EXTEND SUBROUTINES -- FILL OUT DESTINATION" + +;CALL WITH +; AC[DLEN]/ NEGATIVE NUMBER OF BYTES LEFT IN DEST +; FILL/ FILL BYTE +; RETURN [2] WITH FILLERS STORED +; +;NOTE: THIS ROUTINE NEED NOT TEST FOR INTERRUPTS ON EACH BYTE +; BECAUSE EVERY BYTE STORE DOES A MEMORY READ. +; +=01* +MOVF1: [AR]_WORK[FILL], 2T, ;GET FILL BYTE + CALL [PUTDST] ;PLACE IN DEST + [AR]_AC[DLEN] ;AMOUNT LEFT + AC[DLEN]_[AR]+1, 3T, ;STORE UPDATED LEN + SKIP DP0 ; AND SEE IF DONE +=0 RETURN [2] ;DONE +MOVFIL: WORK[FILL], J/MOVF1 ;DO ANOTHER BYTE + ;ENTERING HERE SAVES 150NS + ; PER BYTE BUT COSTS 300NS + ; PER FIELD MOVED. I ASSUME (BUT DO + ; NOT KNOW) THAT THIS SPEEDS + ; THINGS UP. + + .TOC"EXTEND SUBROUTINES -- GET MODIFIED SOURCE BYTE" + +;CALL WITH: +;SLEN = MINUS LENGTH OF STRING +;MSK = MASK FOR BYTE SIZE (1 IF BIT MUST BE ZERO) +;E1 = EFFECTIVE ADDRESS OF OPERATION WORD (SIGN EXTENDED IF OFFSET) +; [AR]_WORK[SLEN]+1, CALL [SRCMOD] +;RETURNS: +; 1 LENGTH EXHAUSTED +; 2 (EDIT ONLY) NO SIGNIFICANCE +; 3 (EDIT ONLY) SIGNIFICANCE START: +; 4 ABORT: OUT OF RANGE OR TRANSLATE FAILURE +; 5 NORMAL: BYTE IN AR +; +;DROM B SET AS FOLLOWS: +; 0 TRANSLATE +; 1 OFFSET +; 2 EDIT +; 4 CVTDBT +=00 +SRCMOD: WORK[SLEN]_[AR], ;PUT BACK SOURCE LENGTH + SKIP DP0, ;SEE IF DONE + CALL [GSRC] ;GET A SOURCE BYTE + END STATE, RETURN [1] ;DONE + WORK[E1], B DISP ;OFFSET OR TRANSLATE? += +=1110 [AR]_[AR]*.5, J/XLATE ;TRANSLATE + FIX [AR] SIGN, WORK[E1] ;IF WE ARE PROCESSING FULL WORD + ; BYTES, AND THEY ARE NEGATIVE, + ; AND THE OFFSET IS POSITIVE THEN + ; WE HAVE TO MAKE BITS -1 AND -2 + ; COPIES OF THE SIGN BIT. + [AR]_[AR]+WORK[E1], 2T ;OFFSET + [AR].AND.WORK[MSK], ;VALID BYTE? + SKIP AD.EQ.0, 4T, ;SKIP IF OK + RETURN [4] ;RETURN 4 IF BAD, 5 IF OK + + .TOC "EXTEND SUBROUTINES -- TRANSLATE" + +;HERE WITH BYTE IN AR 1-36. FETCH TABLE ENTRY. +XLATE: [AR]_[AR]+WORK[E1] ;COMPUTE ADDRESS +TRNAR: READ [AR], LOAD VMA, ;FETCH WORD + START READ ; .. +=0 [AR]_[AR]*2, ;GET BACK LSB + ;BIT 36 IS NOT PRESERVED + ; BY PAGE FAILS + CALL [LOADARX] ;PUT ENTRY IN ARX + TR [AR], #/1 ;WHICH HALF? +=0 +XLATE1: [AR]_[ARX], 3T, ;RH -- COPY TO AR + DISP/DP LEFT, ;DISPATCH ON CODE + J/TRNFNC ;DISPATCH TABLE + [ARX]_[ARX] SWAP, ;LH -- FLIP AROUND + J/XLATE1 ;START SHIFT + +;HERE ON TRANSLATE OPERATION TO PERFORM FUNCTIONS REQUIRED BY +; THE 3 HIGH ORDER BITS OF THE TRANSLATE FUNCTION HALFWORD. WE +; DISPATCH ON FUNCTION AND HAVE: +; BRX/ FLAGS +; ARX/ TABLE ENTRY IN RH +; +=0001 + ;(0) NOP +TRNFNC: READ [BRX], SKIP DP0, ;S FLAG ALREADY SET? + J/TRNRET ; .. + ;(1) ABORT + RETURN [4] + ;(2) CLEAR M FLAG + [BRX]_[BRX].AND.NOT.#, + #/100000, HOLD RIGHT, + J/TRNFNC + ;(3) SET M FLAG + [BRX]_[BRX].OR.#, + #/100000, HOLD RIGHT, + J/TRNFNC + ;(4) SET N FLAG +TRNSIG: [BRX]_[BRX].OR.#, + #/200000, HOLD RIGHT, + J/TRNFNC + ;(5) SET N FLAG THEN ABORT + [BRX]_[BRX].OR.#, + #/200000, HOLD RIGHT, + RETURN [4] + ;(6) CLEAR M THEN SET N + [BRX]_[BRX].AND.NOT.#, + #/100000, HOLD RIGHT, + J/TRNSIG + ;(7) SET N AND M + [BRX]_[BRX].OR.#, + #/300000, HOLD RIGHT, + J/TRNFNC + +;HERE TO COMPLETE A TRANSLATE + +=0 +TRNRET: READ [ARX], SKIP DP18, ;S-FLAG IS ZERO + B DISP, SKIP DP18, ;SEE IF EDIT OR SIG START + J/TRNSS ; .. +TRNSS1: [AR]_[ARX].AND.# CLR LH, ;S IS SET, JUST RETURN BYTE + #/77777, RETURN [5] ; .. + +=1100 +TRNSS: [AR]_AC[DLEN], ;NO SIG ON MOVE OR D2B + B DISP, J/TRNNS1 ;SEE IF D2B + [BRX]_[BRX].OR.#, ;SIG START ON MOVE OR D2B + #/400000, HOLD RIGHT, + J/TRNSS1 ;RETURN BYTE + [AR]_WORK[FILL], ;EDIT--NO SIG RETURN FILL + RETURN [2] ; .. + [AR]_AC[DSTP], ;EDIT--START OF SIG + RETURN [3] ; .. + +=1011 +TRNNS1: [AR]_[AR]-1, J/TRNNS2 ;COMPENSATE FOR IGNORING SRC + [AR]_WORK[SLEN]+1, ;DEC TO BIN HAS NO DEST LENGTH + J/SRCMOD ;JUST UPDATE SRC LENTH +TRNNS2: AC[DLEN]_[AR] TEST, ;PUT BACK DLEN AND + SKIP DP0 ; SEE WHICH IS NOW SHORTER +=0 [AR]_WORK[SLEN], ;DEST IS SHORTER. DO NOT CHANGE + J/SRCMOD ; AMOUNT LEFT + [AR]_WORK[SLEN]+1, ;GO LOOK AT NEXT BYTE + J/SRCMOD + + .TOC "EXTEND SUBROUTINES -- GET UNMODIFIED SOURCE BYTE" + +;CALL: +; GSRC WITH SKIP ON SOURCE LENGTH +; GETSRC IF LENGHT IS OK +;WITH: +; AC1/ SOURCE BYTE POINTER +;RETURNS: +; 1 IF LENGTH RAN OUT +; 2 IF OK (BYTE IN AR) +; +=0 +GSRC: [AR]_AC[DLEN], ;LENGTH RAN OUT + RETURN [1] ;RESTORE AR AND RETURN +GETSRC: [AR]_AC[SRCP] ;GET SRC PTR + IBP DP, IBP SCAD, ;UPDATE BYTE POINTER + SCAD DISP, 3T ;SEE IF OFLOW +=01 [AR]_[BR], J/GSRC1 ;NO OFLOW + SET P TO 36-S ;RESET P + [AR]_[AR]+1, HOLD LEFT ;BUMP Y + +GSRC1: AC[SRCP]_[AR] ;STORE UPDATED POINTER +=0 READ [AR], LOAD BYTE EA, ;SETUP TO FIGURE OUT + FE_P, 3T, CALL [BYTEAS] ; EFFECTIVE ADDRESS + READ [AR], ;LOOK AT POINTER + BYTE DISP, ;SEE IF 7 BIT + FE_FE.AND.S#, S#/0770, ;MASK OUT P FIELD + J/LDB1 ;GO GET THE BYTE + + .TOC "EXTEND SUBROUTINES -- STORE BYTE IN DESTINATION STRING" + +;CALL WITH: +; AR/ BYTE TO STORE +; AC4/ DESTINATION BYTE POINTER +;RETURNS: +; AR & AC4/ UPDATED BYTE POINTER +; ARX/ BYTE TO STORE +; BR/ WORD TO MERGE WITH +; 6 ALWAYS +; +PUTDST: [ARX]_[AR] ;SAVE BYTE +=0 [AR]_AC[DSTP], ;GET DEST POINTER + CALL [IDST] ;BUMP DEST POINTER + AD/A+B, A/ARX, B/ARX, ;SHIFT 7-BIT BYTE TO + SCAD/A, 3T, ; NATURAL PLACE, AND PUT + SCADA/BYTE5, LOAD FE ; INTO FE +=0* READ [AR], BYTE DISP, ;GO PUT BYTE IN MEMORY + CALL [DPB1] ; .. + RETURN [6] ;ALL DONE + + .TOC "EXTEND SUBROUTINES -- UPDATE DEST STRING POINTERS" + + +;SUBROUTINE TO BUMP DST POINTERS +;CALL WITH: +; AR/ AC[DSTP] +; RETURN 1 WITH UPDATED POINTER STORED +; +IDST: IBP DP, IBP SCAD, SCAD DISP, 3T +=0* [AR]_[BR], LOAD DST EA, J/IDSTX + SET P TO 36-S + [AR]_[AR]+1, HOLD LEFT, LOAD DST EA +IDSTX: AC[DSTP]_[AR], 3T, ;STORE PTR BACK + FE_P, DISP/EAMODE ;SAVE P FOR CMPDST +=100* +DSTEA: VMA_[AR]+XR, START READ, PXCT BYTE DATA, 3T, J/BYTFET + VMA_[AR], START READ, PXCT BYTE DATA, J/BYTFET + VMA_[AR]+XR, START READ, PXCT/BIS-DST-EA, 3T, J/DSTIND + VMA_[AR], START READ, PXCT/BIS-DST-EA, J/DSTIND + +DSTIND: MEM READ, [AR]_MEM, HOLD LEFT, LOAD DST EA + EA MODE DISP, J/DSTEA + + +;HERE TO TEST ILLEGAL BITS SET +;CALL WITH: +; SKIP IF ALL BITS LEGAL +; RETURN [4] IF OK, ELSE DO UUO +; +3556: ;EXTEND OF 0 COMES HERE +BITCHK: UUO +3557: RETURN [4] + +;HERE TO PUT FILL IN [AR] AND WORK[FILL] +GTFILL: MEM READ, ;WAIT FOR DATA + [AR]_MEM ;PLACE IN AR + WORK[FILL]_[AR], ;SAVE FOR LATER + RETURN [10] ;RETURN TO CALLER + +;SUBROUTINE TO CLEAR FLAGS IN AR +CLRFLG: [AR]_[AR].AND.#, ;CLEAR FLAGS IN AR + #/000777, ; .. + HOLD RIGHT, RETURN [1] + + .TOC "EXTEND -- PAGE FAIL CLEANUP" + +;BACK UP SOURCE POINTER +=0 +BACKS: [AR]_AC[SRCP], + CALL [BACKBP] ;BACKUP BP + AC[SRCP]_[BR], J/CLDISP + +CMSDST: [AR]_WORK[SV.BRX] ;GET OLD SRC LEN + AC_[AR]+1, 3T ;BACK UP +;BACK UP DESTINATION POINTER +=0 +BACKD: [AR]_AC[DSTP], + CALL [BACKBP] + AC[DSTP]_[BR], J/CLDISP + +;FAILURES DURING MOVE STRING (BACKUP LENGTHS) +STRPF: [AR]_-WORK[SLEN] ;GET AMOUNT LEFT +STRPF0: [BR]_AC[DLEN], 4T, ;WHICH STRING IS LONGER? + SKIP DP0 +=0 +STRPF1: AC[DLEN]_[AR], J/STPF1A ;SRC LONGER + [ARX]_[AR] ;COPY SRC LENGTH +=0 [ARX]_[ARX].OR.WORK[SV.BRX], ;REBUILD FLAGS + CALL [AC_ARX] ;RESET AC]SLEN] + [AR]_[AR]-[BR] ;MAKE DEST LEN +STRPF3: AC[DLEN]_[AR], ;PUT BACK DEST LEN + J/CLDISP ;DO NEXT CLEANUP + +STPF1A: [AR]_[AR]+[BR], J/STRPF2 + +PFDBIN: [AR]_-WORK[SLEN] ;RESTORE LENGTH +STRPF2: [AR]_[AR].OR.WORK[SV.BRX] +PFGAC0: AC_[AR], J/CLDISP ;PUT BACK SRC LEN AND FLAGS + +STRPF4: [AR]_.NOT.WORK[SLEN], J/STRPF0 + +BACKBP: IBP DP, SCAD/A+B, SCADA/BYTE1, SCADB/SIZE, ;P_P+S + RETURN [1] diff --git a/src/kshack/flt.5 b/src/kshack/flt.5 new file mode 100755 index 00000000..186f3429 --- /dev/null +++ b/src/kshack/flt.5 @@ -0,0 +1,587 @@ +;;;-*-Fundamental-*- + +.TOC "FLOATING POINT -- FAD, FSB" + + .DCODE +140: FL-R, FL-AC, J/FAD +142: FL-RW, FL-MEM, J/FAD + FL-RW, FL-BOTH, J/FAD + FL-R, FL-AC, ROUND, J/FAD + FL-I, FL-AC, ROUND, J/FAD + FL-RW, FL-MEM, ROUND, J/FAD + FL-RW, FL-BOTH, ROUND, J/FAD + +150: FL-R, FL-AC, J/FSB +152: FL-RW, FL-MEM, J/FSB + FL-RW, FL-BOTH, J/FSB + FL-R, FL-AC, ROUND, J/FSB + FL-I, FL-AC, ROUND, J/FSB + FL-RW, FL-MEM, ROUND, J/FSB + FL-RW, FL-BOTH, ROUND, J/FSB + .UCODE + +;BOTH FAD & FSB ARE ENTERED WITH THE MEMORY OPERAND IN AR +; SIGN SMEARED. THE EXPONENT IN BOTH SC AND FE. +1576: +FSB: [AR]_-[AR] ;MAKE MEMOP NEGATIVE + +1577: +FAD: [BR]_AC, SC_SC-EXP-1, 3T, SCAD DISP +=0* +FAS1: READ [BR], SKIP DP0, J/FAS2 ;BR .LE. AR + [ARX]_[AR] ;SWAP AR AND BR + [AR]_[BR], SC_EXP + [BR]_[ARX], SC_SC-FE-1 ;NUMBER OF SHIFT STEPS + READ [AR], FE_EXP, 2T, SKIP DP0 +=0 [AR]_+SIGN, J/FAS3 + [AR]_-SIGN, J/FAS3 + +=0 ;SIGN SMEAR BR AND UNNORMALIZE +FAS2: [BR]_+SIGN, J/FAS3 + [BR]_-SIGN, J/FAS3 + +FAS3: Q_0, STEP SC +=0 +FAS4: [BR]_[BR]*.5 LONG, STEP SC, ASHC, J/FAS4 + [AR]_[AR]+[BR], NORM DISP, J/SNORM + + .TOC "FLAOTING POINT -- FMP" + + .DCODE +160: FL-R, FL-AC, J/FMP +162: FL-RW, FL-MEM, J/FMP + FL-RW, FL-BOTH, J/FMP + + FL-R, FL-AC, ROUND, J/FMP + FL-I, FL-AC, ROUND, J/FMP + FL-RW, FL-MEM, ROUND, J/FMP + FL-RW, FL-BOTH, ROUND, J/FMP + .UCODE + +1570: +FMP: [BRX]_AC, ;GET AC + FE_SC+EXP, 3T, ;EXPONENT OF ANSWER + SKIP DP0 ;GET READY TO SMEAR SIGN +=0 [BRX]_+SIGN, J/FMP1 ;POSITIVE + [BRX]_-SIGN, J/FMP1 ;NEGATIVE +FMP1: Q_[AR], SC_27. ;GET MEMORY OPERAND +=01* [BRX]_[BRX]*.5 LONG, ;SHIFT RIGHT + CALL [MULSUB] ;MULTIPLY + Q_Q.AND.#, #/777000, ;WE ONLY COMPUTED + HOLD LEFT ; 27 BITS + [AR]_[ARX], FE_FE+2 ;SET SHIFT PATHS + [AR]_[AR]*.5 LONG, ;SHIFT OVER + FE_FE-200, ;ADJUST EXPONENT + NORM DISP, J/SNORM ;NORMALIZE & EXIT + + .TOC "FLOATING POINT -- FDV" + + .DCODE +170: FL-R, FL-AC, J/FDV +172: FL-RW, FL-MEM, J/FDV + FL-RW, FL-BOTH, J/FDV + + FL-R, FL-AC, ROUND, J/FDV + FL-I, FL-AC, ROUND, J/FDV + FL-RW, FL-MEM, ROUND, J/FDV + FL-RW, FL-BOTH, ROUND, J/FDV + .UCODE + + +1574: +FDV: [BR]_[AR], SKIP AD.EQ.0, AC ;COPY DIVSOR SEE IF 0 +=0 + [AR]_AC, FE_SC-EXP, SKIP DP0, ;GET AC & COMPUTE NEW + J/FDV0 ; EXPONENT + FL NO DIVIDE ;DIVIDE BY ZERO +=0 +FDV0: [AR]_+SIGN, J/FDV1 + [AR]_-SIGN, J/FDV2 +FDV1: [ARX]_[AR],FE_-FE+200,J/FDV3 ;COMPUTE 2*DVND +FDV2: [ARX]_-[AR],FE_-FE+200,J/FDV3 ;ABSOLUTE VALUE +FDV3: [BRX]_[BR]*2, SKIP DP0 ;ABSOLUTE VALUE +=0 +FDV4: [ARX]-[BRX], SKIP CRY0, 3T, J/FDV5 ;FLOATING NO DIV? + [BRX]_-[BR]*2, J/FDV4 ;FORCE ABSOLUTE VALUE +=0 +FDV5: [BRX]_[BRX]*.5, J/FDV6 ;SHIFT BACK ARX + FL NO DIVIDE ;UNNORMALIZED INPUT +=0 +FDV6: [AR]_[AR]*2, ;DO NOT DROP A BIT + CALL [SBRL] ;AT FDV7+1 + [BRX]-[ARX], SKIP AD.LE.0 ;IS ANSWER .LE. 1? +=00100 +FDV7: Q_0, SC_27., CALL [DIVSGN] ;DIVIDE +=00101 [AR]_[AR]*.5, FE_FE+1, J/FDV7 ;SCALE DV'END +=01100 +FDV8: [AR]_Q*.5, J/FDV9 ;PUT ANSWER IN AR +=01101 READ [AR], SKIP AD.EQ.0, ;-VE ANSWER, LOOK AT RMDR + CALL [SETSN] ; SEE HOW TO NEGATE +=01110 READ [AR], SKIP AD.EQ.0, ;-VE ANSWER, LOOK AT RMDR + CALL [SETSN] ; SEE HOW TO NEGATE +=01111 [AR]_Q*.5, J/FDV9 ;PUT ANSWER IN AR +=11111 [AR]_-Q*.5, J/FDV9 ;ZERO RMDR + +FDV9: Q_0, J/SNORM0 ;GO NORMALIZE + + .TOC "FLOATING POINT -- FLTR, FSC" + + .DCODE +127: R, FL-AC,ROUND, J/FLTR +132: I, FL-AC, J/FSC + .UCODE + +1616: +FLTR: [AR].AND.#, #/777000, 3T, SKIP ADL.EQ.0 ;SMALL POS NUMBER? +=0 [BR]_-[AR], SKIP DP0, 3T, J/FLTR1 ;NO--SEE IF MINUS + Q_0, FE_S#, S#/233, J/SNORM0 ;FITS IN 27 BITS +=0 +FLTR1: [BR].AND.#, #/777000, 3T, + SKIP ADL.EQ.0, J/FLTR1A ;SMALL NEGATIVE NUMBER + Q_0, FE_S#, S#/244, J/FLTR2 ;LARGE POS NUMBER +=0 +FLTR1A: Q_0, FE_S#, S#/244, J/FLTR2 ;BIG NUMBER + Q_0, FE_S#, S#/233, J/SNORM0 ;FITS IN 27 BITS +;AT THIS POINT WE KNOW THE NUMBER TAKES MORE THAN 27 BITS. WE JUST +; SHIFT 8 PLACES RIGHT AND NORMALIZE. WE COULD BE MORE CLEVER BUT +; THIS IS THE RARE CASE ANYWAY. +FLTR2: [AR]_[AR]*.5 LONG, ASHC, SC_6 ;SHOVE OVER TO THE RIGHT +=0 +FLTR3: [AR]_[AR]*.5 LONG, ASHC, ;SHIFT RIGHT 9 PLACES + STEP SC, J/FLTR3 ; SO IT WILL FIT +SNORM0: READ [AR], NORM DISP, J/SNORM ;NORMALIZE ANSWER + + +1621: +FSC: READ [AR], SC_SHIFT + Q_0, AC ;DON'T SHIFT IN JUNK + [AR]_AC, FE_SC+EXP, SKIP DP0 ;SIGN SMEAR +=0 [AR]_+SIGN, J/SNORM0 + [AR]_-SIGN, J/SNORM0 + + .TOC "FLOATING POINT -- FIX AND FIXR" + + .DCODE +122: FL-R, FL-AC, J/FIX +126: FL-R, FL-AC,ROUND, J/FIX + .UCODE + +1626: +FIX: Q_0, SCAD/A+B, SCADA/S#, ;CLEAR Q, SEE IF + S#/1534, SCADB/FE, 3T, ; ANSWER FITS IN + SCAD DISP ; 35 BITS. +=0* SET AROV, J/NIDISP ;TOO BIG + SC_FE+S#, S#/1544, 3T, SCAD DISP ;NEED TO MOVE LEFT? +=0* STEP SC, J/FIXL + SC_S#-FE, S#/232 ;NUMBER OF PLACES TO SHIFT + ; RIGHT + STEP SC ;ALREADY THERE +=0 +FIXR: [AR]_[AR]*.5 LONG, ASHC, ;SHIFT BINARY POINT + STEP SC, J/FIXR ; TO BIT 35.5 + [BR]_[ONE]*.5, B DISP, J/FIXX ;WHICH KIND OF FIX? + +=0 +FIXL: [AR]_[AR]*2, STEP SC, J/FIXL ;SHIFT LEFT + AC_[AR], NEXT INST ;WE ARE NOW DONE + +=0*11 +FIXX: READ [AR], SKIP DP0, J/FIXT ;FIX--SEE IF MINUS +FIXX1: [AR]_[AR]+[BR], FL-EXIT ;FIXR--ROUND UP +=0 +FIXT: AC_[AR], NEXT INST ;FIX & +, TRUNCATE + READ Q, SKIP AD.EQ.0 ;NEGATIVE--ANY FRACTION? +=0 [AR]_[AR]+1, FL-EXIT ;YES--ROUND UP + [BR]_.NOT.[MASK], ;MAYBE--GENERATE .75 + J/FIXX1 ;ROUND UP IF BIT 36 OR + ; 37 SET + + .TOC "FLOATING POINT -- SINGLE PRECISION NORMALIZE" + +;NORMALIZE DISPATCH IS A 9-WAY DISPATCH. THE HARDWARE LOOKS AT +; 4 SIGNALS: DP=0, DP BIT 8, DP BIT 9, DP BIT -2. THE 9 CASES +; ARE: + +; DP=0 DP08 DP09 DP00 ACTION TO TAKE +; 0 0 0 0 SHIFT LEFT +; +; 0 0 0 1 NEGATE AND RETRY +; +; 0 0 1 0 ALL DONE +; +; 0 0 1 1 NEGATE AND RETRY +; +; 0 1 0 0 SHIFT RIGHT +; +; 0 1 0 1 NEGATE AND RETRY +; +; 0 1 1 0 SHIFT RIGHT +; +; 0 1 1 1 NEGATE AND RETRY +; +; 1 - - - LOOK AT Q BITS + +;ENTER HERE WITH UNNORMALIZED NUMBER IN AR!Q. FE HOLDS THE NEW +; EXPONENT. CALL WITH NORM DISP +=0000 ;9-WAY DISPATCH +SNORM: [AR]_[AR]*2 LONG, DIV, FE_FE-1, NORM DISP, J/SNORM + Q_-Q, SKIP CRY0, 3T, J/SNNEG + READ [AR], NORM DISP, CALL [SROUND] + Q_-Q, SKIP CRY0, 3T, J/SNNEG + [AR]_[AR]*.5, FE_FE+1, CALL [SROUND] + Q_-Q, SKIP CRY0, 3T, J/SNNEG + [AR]_[AR]*.5, FE_FE+1, CALL [SROUND] + Q_-Q, SKIP CRY0, 3T, J/SNNEG + READ Q, SKIP AD.EQ.0, J/SNORM1 +=1110 [AR]_EXP, J/FLEX += +=0 +SNORM1: [AR]_[AR]*2 LONG, DIV, FE_FE-1, NORM DISP, J/SNORM +FLEX: FL-EXIT + +=0 +SNNEG: [AR]_.NOT.[AR], NORM DISP, J/SNNORM ;NEGATE HIGH WORD + ; (NO CARRY) + [AR]_-[AR], NORM DISP, J/SNNORM ;NEGATE HIGH WORD (W/CARRY) +=0000 +SNNORM: [AR]_[AR]*2 LONG, DIV, FE_FE-1, NORM DISP, J/SNNORM +=0010 READ [AR], NORM DISP, CALL [SROUND] +=0100 [AR]_[AR]*.5, FE_FE+1, CALL [SROUND] +=0110 [AR]_[AR]*.5, FE_FE+1, CALL [SROUND] +=1000 [AR]_[AR]*2 LONG, DIV, FE_FE-1, NORM DISP, J/SNNORM ;[120] +=1110 [AR]_EXP, B DISP += +=0111 TL [FLG], FLG.SN/1, J/SNNOT + [AR]_[AR].AND.[MASK], ;CLEAR ANY LEFT OVER BITS + J/SNNOT1 +=0 +SNNOT: [AR]_.NOT.[AR], J/SNNOT2 + READ Q, SKIP AD.EQ.0 +=0 [AR]_.NOT.[AR], J/SNNOT2 +SNNOT1: [AR]_-[AR], J/SNNOT2 ;NORMAL NEGATE AND EXIT +SNNOT2: [FLG]_[FLG].AND.NOT.#, FLG.SN/1, HOLD RIGHT + FL-EXIT + .TOC "FLOATING POINT -- ROUND ANSWER" + +=*01* +SROUND: [BR]_[ONE]*.5, B DISP, J/SRND1 + [AR]_[AR]*.5, FE_FE+1, J/SROUND ;WE WENT TOO FAR +=0111 +SRND1: RETURN [16] ;NOT ROUNDING INSTRUCTION + [AR]_[AR]+[BR], NORM DISP +=*01* RETURN [16] + [AR]_[AR]*.5, FE_FE+1, RETURN [16] + + .TOC "FLOATING POINT -- DFAD, DFSB" + + .DCODE +110: DBL FL-R, J/DFAD +111: DBL FL-R, J/DFSB + .UCODE + +;ENTER FROM A-READ CODE WITH: +;FE/ EXP +;SC/ EXP +;AR/ C(E) SHIFT RIGHT 2 PLACES +;ARX/ C(E+1) SHIFTED RIGHT 1 PLACE +1635: +DFSB: [ARX]_-[ARX] ;NEGATE LOW WORD + [AR]_-[AR]-.25, MULTI PREC/1 +1637: +DFAD: [BRX]_(AC[1].AND.[MAG])*.5, 3T ;GET LOW WORD + [BR]_AC*.5, 3T, ;GET AC AND START TO SHIFT + SC_SC-EXP-1, ;NUMBER OF PLACES TO SHIFT + SKIP DP0 ;SEE WHAT SIGN +=0 [BR]_+SIGN*.5, 3T, ;SIGN SMEAR + AC, SKIP/SC, J/DFAS1 ;SEE WHICH IS BIGGER + [BR]_-SIGN*.5, 3T, ;SIGN SMEAR + AC, SKIP/SC, J/DFAS1 ;SEE WHICH IS BIGGER +=0 +DFAS1: Q_[BRX], ;AR IS BIGGER + J/DFAS2 ;ADJUST BR!Q + [T0]_AC, ;BR IS BIGGER OR EQUAL + SC_EXP, 2T, J/DFAS3 ;SET SC TO THAT EXPONENT + +;HERE IF AR!ARX IS GREATER THAN BR!BRX +=0 +DFAS2: [T0]_[BR], CALL [DFADJ] ;ADJUST BR!Q + [BR]_[T0] ;PUT ANSWER BACK + Q_Q+[ARX], J/DFAS5 ;ADD LOW WORDS + +;HERE IS BR!BRX IF GREATER THAN OR EQUAL TO AR!ARX +DFAS3: Q_[ARX], ;SETUP TO SHIFT AR!ARX + SC_SC-FE-1 ;COMPUTE # OF PLACES + READ [T0], FE_EXP ;EXPONENT OF ANSWER +=0 [T0]_[AR], CALL [DFADJ] ;ADJUST AR!Q + [AR]_[T0] ;PUT ANSWER BACK + Q_Q+[BRX], J/DFAS5 ;ADD LOW WORDS + +;BIT DIDDLE TO GET THE ANSWER (INCLUDING 2 GUARD BITS) INTO +; AR!Q +DFAS5: [AR]_([AR]+[BR])*.5 LONG, ;ADD HIGH WORDS + MULTI PREC/1, ASHC ;INJECT SAVED CRY2 + [AR]_[AR]*2 LONG, ;SHIFT BACK LEFT + ASHC, MUL DISP ;SEE IF WE LOST A 1 +=1011 +DFAS6: [T1]_[T1].AND.NOT.[MASK], J/DFAS7 + Q_Q+.25, J/DFAS6 +DFAS7: [AR]_[AR]*2 LONG, ASHC, ;PUT IN GUARD BITS + FE_FE-1 + [AR]_[AR]*2 LONG, ASHC, + FE_FE-1 + Q_[T1].OR.Q, HOLD LEFT, J/DNORM0 + +;SUBROUTINE TO ADJUST NUMBER IN T0!Q +;RETURNS 1 WITH +; T0!Q ADJUSTED +; FLG.SN=1 IF WE SHIFTED OUT ANY 1 BITS (STICKY BIT) +; T1 HAS Q TWO STEPS PRIOR TO BEING DONE +DFADJ "STEP SC, ASHC, MUL DISP" + +=0**11 +DFADJ: [T0]_[T0]*2 LONG, DIV, ;MOVE EVERYTHING 2 PLACES + CALL [CLRSN] + [T0]_[T0]*2 LONG, DIV + [T0]_[T0]*2 LONG, DIV + [T0]_[T0]*.5 LONG, ASHC, ;SHIFT AT LEAST 1 PLACE + STEP SC +=1010 +DFADJ1: [T0]_[T0]*.5 LONG, ;UNNORMALIZE T0!Q + DFADJ, J/DFADJ1 ;LOOP TILL DONE +DFADJ2: [T1]_Q, ;SAVE GUARD BITS + MUL DISP, J/DFADJ5 ;LOOK AT LAST BIT + [FLG]_[FLG].OR.#, FLG.SN/1, HOLD RIGHT, J/DFADJ3 + [FLG]_[FLG].OR.#, FLG.SN/1, HOLD RIGHT, J/DFADJ4 + +=0 +DFADJ3: [T0]_[T0]*.5 LONG, ASHC, STEP SC, J/DFADJ3 +DFADJ4: [T1]_Q ;SAVE 2 GUARD BITS +=1011 +DFADJ5: [T0]_[T0]*.5 LONG, ASHC, J/DFADJ6 + [FLG]_[FLG].OR.#, FLG.SN/1, HOLD RIGHT, J/DFADJ5 +DFADJ6: [T0]_[T0]*.5 LONG, ASHC, RETURN [1] + + .TOC "FLOATING POINT -- DFMP" + + .DCODE +112: DBL FL-R, DAC, J/DFMP + .UCODE + +;SAME ENTRY CONDITIONS AS DFAD/DFSB +1631: +DFMP: Q_[ARX], SC_6 ;SHIFT MEM OP 8 PLACES +=0 +DFMP1: [AR]_[AR]*2 LONG, ASHC, ;SHIFT + STEP SC, J/DFMP1 + Q_Q*.5 + Q_Q.AND.#, #/077777, HOLD RIGHT + [BR]_Q ;COPY LOW WORD +; +; BRX * BR ==> C(E+1) * C(AC+1) +; + [BRX]_(AC[1].AND.[MAG])*.5 ;GET LOW AC +=0** [BRX]_[BRX]*.5, SC_35., CALL [MULSB1] +; +; BRX * Q ==> C(E) * C(AC+1) +; + Q_[AR], SC_35. ;GO MULT NEXT HUNK +=0** CALL [MULTIPLY] + [T0]_[ARX] ;SAVE PRODUCT + [ARX]_Q*.5, SC_FE ;PUT IN NEXT STEP +; +; BRX * BR ==> C(AC) * C(E+1) +; + [BRX]_AC*.5, ;PREPARE TO DO HIGH HALF + FE_SC+EXP, ;EXPONENT ON ANSWER + SKIP DP0, 3T +=0 [BRX]_+SIGN*.5, 3T, J/DFMP2 + [BRX]_-SIGN*.5, 3T +=0** +DFMP2: Q_[BR], SC_35., CALL [MULTIPLY] ;GO MULTIPLY + [T1]_Q ;SAVE FOR ROUNDING + [ARX]_[ARX]+[T0] ;PREPARE FOR LAST MUL +; +; BRX * Q ==> C(AC) * C(E) +; +=0** Q_[AR], SC_35., ;DO THE LAST MULTIPLY + CALL [MULTIPLY] ; .. + +;OK, WE NOW HAVE THE PRODUCT IN ARX!Q!T1. ALL WE NEED TO DO +; IS SOME BIT DIDDLES TO GET EVERYTHING IN THE RIGHT PLACE + [AR]_[ARX]*.5 LONG, ;SHIFT THE ANSWER + FE_FE+S#, S#/1576 ;CORRECT EXPONENT +=0**11 READ [T1], SKIP AD.EQ.0, ;SEE IF LOW ORDER 1 + CALL [SETSN] ; BITS AROUND SOMEPLACE + [AR]_[AR]*2 LONG, ASHC ;SHIFT LEFT + [BR]_[ONE]*.5 ;PLACE TO INSTERT BITS + TL [T1], #/200000 ;ANYTHING TO INJECT? +=0 Q_Q+[BR] ;YES--PUT IT IN + [AR]_[AR]*2 LONG, ASHC ;MAKE ROOM FOR MORE + TL [T1], #/100000 ;ANOTHER BIT NEEDED +=0 Q_Q+[BR] ;YES--PUT IN LAST BIT +DNORM0: READ [AR], NORM DISP, ;SEE WHAT WE NEED TO DO + FE_FE+S#, S#/2, J/DNORM ;ADJUST FOR INITIAL SHIFTS + + .TOC "FLOATING POINT -- DFDV" + + .DCODE +113: DBL FL-R, DAC, J/DFDV + .UCODE +1636: +DFDV: [BRX]_[ARX] ;COPY OPERAND (COULD SAVE TIME + ; WITH SEPERATE A-READ FOR DFDV) +=1**10 [T1]_0, CALL [CLRSN] ;CLEAR FLAG + [BR]_[AR], SKIP AD.LE.0, ;SEE IF POSITIVE + AC[1] ;WARM UP RAM +=0 +DFDV1: [ARX]_(AC[1].AND.[MAG])*.5, ;POSITIVE--GET AC + J/DFDV2 ; AND CONTINUE BELOW + [T1]_.NOT.[T1] ;DV'SOR NEGATIVE (OR ZERO) + [BRX]_-[BRX] ;NEGATE LOW WORD + AD/-B-.25, B/BR, DEST/AD, ;NEGATE HIGH WORD + MULTI PREC/1, 3T, ;ADDING IN CRY02 + SKIP DP0, AC[1], ;SEE IF STILL NEGATIVE + J/DFDV1 ; .. +DFDV2: [AR]_AC*.5, ;GET AC AND SHIFT + FE_SC-EXP, 3T, ;COMPUTE NEW EXPONENT + SKIP DP0 ;SEE IF NEGATIVE +=0 [AR]_+SIGN*.5, 3T, J/DFDV3 ;POSITIVE + [T1]_.NOT.[T1] ;NEGATIVE OR ZERO + [AR]_-SIGN*.5, 3T ;SIGN SMEAR + Q_-[ARX] ;NEGATE OPERAND + [AR]_(-[AR]-.25)*.5 LONG, ;NEGATE HIGH WORD + MULTI PREC/1, ;USE SAVED CARRY + ASHC, J/DFDV4 ;CONTINUE BELOW +=0 +DFDV3: Q_[ARX], ;COPY OPERAND + CALL [DDIVS] ;SHIFT OVER +DFDV4: [AR]-[BR], 3T, SKIP DP0 ;SEE IF OVERFLOW +=0 FL NO DIVIDE + [ARX]_Q ;START DIVISION +=0* Q_0, SC_26., CALL [DBLDIV] + [T0]_Q, SC_35. +=0* Q_Q.AND.NOT.[MAG], ;SEE IF ODD + SKIP AD.EQ.0, ;SKIP IF EVEN + CALL [DBLDIV] ;GO DIVIDE + Q_Q*.5 ;MOVE ANSWER OVER += + [T0]_[T0]*2 LONG, ASHC, ;DO FIRST NORM STEP + MUL DISP ; SEE IF A 1 FELL OUT +=1011 +DFDV4A: READ [T1], SKIP DP0, ;SHOULD RESULT BE NEGATIVE + FE_S#-FE, S#/202, ;CORRECT EXPONENT + J/DFDV4B ;LOOK BELOW + Q_Q+.25, J/DFDV4A ;PUT BACK THE BIT +=0 +DFDV4B: [AR]_[T0], NORM DISP, J/DNORM ;PLUS + [AR]_[T0], NORM DISP, J/DNNORM ;MINUS + + .TOC "FLOATING POINT -- DOUBLE PRECISION NORMALIZE" + +;NORMALIZE AR!Q +;DNORM0: READ [AR], NORM DISP, ;SEE WHAT WE NEED TO DO +; FE_FE+S#, S#/2, J/DNORM ;ADJUST FOR INITIAL SHIFTS +=0000 +DNORM: [AR]_[AR]*2 LONG, ;SHIFT LEFT + FE_FE-1, ASHC, ;ADJUST EXPONENT + NORM DISP, J/DNORM ;TRY AGAIN + TL [FLG], FLG.SN/1, J/DNEG ;RESULT IS NEGATIVE + READ [AR], NORM DISP, ;SEE IF WE WENT TOO FAR + CALL [DROUND] ; AND ROUND ANSWER + TL [FLG], FLG.SN/1, J/DNEG ;RESULT IS NEGATIVE + [AR]_[AR]*.5 LONG, ASHC, + FE_FE+1, CALL [DROUND] + TL [FLG], FLG.SN/1, J/DNEG ;RESULT IS NEGATIVE + [AR]_[AR]*.5 LONG, ASHC, + FE_FE+1, CALL [DROUND] + TL [FLG], FLG.SN/1, J/DNEG ;RESULT IS NEGATIVE + Q_[MAG].AND.Q, ;HIGH WORD IS ZERO + HOLD RIGHT, J/DNORM1 ;GO TEST LOW WORD +=1110 [FLG]_[FLG].AND.NOT.#, FLG.SN/1, HOLD RIGHT ;[122] CLEAR FLG.SN += + AC[1]_[ARX].AND.[MAG], ;STORE LOW WORD + J/STAC ;GO DO HIGH WORD + +DNORM1: READ Q, SKIP AD.EQ.0 ;TEST LOW WORD +=0 [AR]_[AR]*2 LONG, ;LOW WORD IS NON-ZERO + FE_FE-1, ASHC, ;ADJUST EXPONENT + NORM DISP, J/DNORM ;KEEP LOOKING + AC[1]_[AR], J/STAC ;WHOLE ANSWER IS ZERO + +;HERE TO NORMALIZE NEGATIVE D.P. RESULTS +=0 +DNEG: Q_.NOT.Q, J/DNEG1 ;ONES COMP + Q_-Q, SKIP CRY2, J/DNEG2 +DNEG1: [FLG]_[FLG].AND.NOT.#, FLG.SN/1, HOLD RIGHT +=0 +DNEG2: [AR]_.NOT.[AR], ;NO CARRY + NORM DISP, J/DNNORM ;GO NORMALIZE + [AR]_-[AR], ;CARRY + NORM DISP, J/DNNORM ;NORMALIZE + +=000* +DNNORM: [AR]_[AR]*2 LONG, ;SHIFT 1 PLACE + FE_FE-1, ASHC, ;ADJUST EXPONENT + NORM DISP, J/DNNORM ;LOOP TILL DONE +=001* READ [AR], NORM DISP, ;SEE IF WE WENT TOO FAR + CALL [DROUND] ; AND ROUND ANSWER +=010* [AR]_[AR]*.5 LONG, ASHC, + FE_FE+1, CALL [DROUND] +=011* [AR]_[AR]*.5 LONG, ASHC, + FE_FE+1, CALL [DROUND] +=100* Q_[MAG].AND.Q, ;HIGH WORD IS ZERO + HOLD RIGHT, J/DNNRM1 ;GO TEST LOW WORD +=111* [ARX]_[ARX].AND.[MASK] ;REMOVE ROUNDING BIT += +=00 [ARX]_[ARX].AND.[MAG], ;ALSO CLEAR SIGN + CALL [CHKSN] ;ONES COMP? +=10 [ARX]_[ARX].XOR.[MAG], ;YES--ONES COMP + J/DNN1 ;CONTINUE BELOW +=11 [ARX]_-[ARX], 3T, ;NEGATE RESULT + SKIP CRY1, J/DNN2 += +DNN1: [FLG]_[FLG].AND.NOT.#, FLG.SN/1, HOLD RIGHT ;CLEAR FLAG +=0 +DNN2: AC_.NOT.[AR], J/DNORM2 + AC_-[AR], 3T +DNORM2: AC[1]_[ARX].AND.[MAG], ;STORE LOW WORD + NEXT INST ;ALL DONE + +DNNRM1: READ Q, SKIP AD.EQ.0 ;TEST LOW WORD +=0 [AR]_[AR]*2 LONG, ;LOW WORD IS NON-ZERO + FE_FE-1, ASHC, ;ADJUST EXPONENT + NORM DISP, J/DNNORM ;KEEP LOOKING + AC[1]_[AR], J/STAC ;WHOLE ANSWER IS ZERO + +CHKSN: TL [FLG], FLG.SN/1, RETURN [2] + +;SUBROUTINE TO SET/CLEAR FLG.SN +;CALL WITH: +; CALL [SETSN], SKIP IF WE SHOULD CLEAR +;RETURNS 23 +=0 +SETSN: [FLG]_[FLG].OR.#, FLG.SN/1, HOLD RIGHT, RETURN [23] +CLRSN: [FLG]_[FLG].AND.NOT.#, FLG.SN/1, HOLD RIGHT, RETURN [23] + + +;SUBROUTINE TO ROUND A FLOATING POINT NUMBER +;CALL WITH: +; NUMBER IN AR!Q AND NORM DISP +;RETURNS 16 WITH ROUNDED NUMBER IN AR!ARX +; +=*01* +DROUND: [ARX]_(Q+1)*.5, ;ROUND AND SHIFT + SKIP CRY2, ;SEE IF OVERFLOW + J/DRND1 ;COMPLETE ROUNDING + [AR]_[AR]*.5 LONG, ;WE WENT TOO FAR + FE_FE+1, ASHC, J/DROUND ;SHIFT BACK AND ROUND +=*010 +DRND1: [AR]_EXP, RETURN [16] ;NO OVERFLOW +=011 [AR]_[AR]+.25, ;ADD CARRY (BITS 36 AND 37 + ; ARE COPIES OF Q BITS) + NORM DISP, ;SEE IF OVERFLOW + J/DRND1 ; .. +=110 [AR]_[AR]*.5, ;SHIFT RIGHT + FE_FE+1, ;KEEP EXP RIGHT + J/DRND1 ;ALL SET NOW += diff --git a/src/kshack/inout.50 b/src/kshack/inout.50 new file mode 100755 index 00000000..9a08f4d8 --- /dev/null +++ b/src/kshack/inout.50 @@ -0,0 +1,1254 @@ +;;;-*-Fundamental-*- + +.TOC "TRAPS" + +TRAP: [ARX]_PC WITH FLAGS ;SAVE THE PC WHICH CAUSED THE + WORK[TRAPPC]_[ARX], ; TRAP + SKIP KERNEL ;SEE IF UBR OR EBR +=0 [AR]_[AR]+[UBR], ;ADDRESS OF INSTRUCTION + MEM READ, ;WAIT FOR PREFETCH TO GET INTO THE CACHE. + ; MAY PAGE FAIL BUT THAT IS OK + START READ, ;START FETCH + VMA PHYSICAL, ;ABSOLUTE ADDRESSING + J/TRP1 ;JOIN COMMON CODE + + [AR]_[AR]+[EBR], ;WE COME HERE IN EXEC MODE + MEM READ, ;WAIT FOR PREFETCH TO GET INTO THE CACHE. + ; MAY PAGE FAIL BUT THAT IS OK + START READ, ;START FETCH + VMA PHYSICAL, ;ABSOLUTE ADDRESSING + J/TRP1 ;JOIN COMMON CODE + +TRP1: MEM READ, [HR]_MEM, ;PLACE INSTRUCTION IN HR + LOAD INST ;LOAD IR, XR, @ + [HR].AND.#, ;TEST TO SEE IF THIS + #/700000, 3T, ; IS A UUO + SKIP ADL.EQ.0 +=0 CHANGE FLAGS, ;NOT A UUO + HOLD USER/1, ;CLEAR TRAP FLAGS + J/XCT1 ;DO THE INSTRUCTION + UUO ;DO THE UUO + + .TOC "IO -- INTERNAL DEVICES" + + .DCODE +700: IOT,AC DISP, J/GRP700 + IOT,AC DISP, J/GRP701 + .UCODE + +1701: UUO ;DATAI APR, +1702: UUO ;BLKO APR, +1703: UUO ;DATAO APR, +1706: [BR]_APR, J/APRSZ ;CONSZ APR, +1707: [BR]_APR, J/APRSO ;CONSO APR, +1710: +RDERA: UUO ;BLKI PI, +1711: UUO ;DATAI PI, +1712: UUO ;BLKO PI, +1713: UUO ;DATAO PI, +1716: [BR]_[PI], J/CONSZ ;CONSZ PI, +1717: [BR]_[PI], J/CONSO ;CONSO PI, + +.IFNOT/ITS +1720: +GRP701: UUO ;BLKI PAG, +.ENDIF/ITS +1726: UUO ;CONSZ PAG, +1727: UUO ;CONSO PAG, + +;680I AND CACHE SWEEP STUFF +1730: UUO ;BLKI +.IF/PCST +1731: [BR]_WORK[PCST], J/RTNREG ;Read PC sample table pointer +.IFNOT/PCST +1731: UUO ;DATAI +.ENDIF/PCST +1732: UUO ;BLKO +.IF/PCST +1733: VMA_[AR], START READ, J/WRPCST ;Write PC sample table pointer +.IFNOT/PCST +1733: UUO ;DATAO +.ENDIF/PCST +1734: UUO ;CONO +1735: UUO ;CONI +1736: UUO ;CONSZ +1737: UUO ;CONSO + +APRSO: [BR]_[BR].AND.# CLR LH, #/7770 +CONSO: [BR].AND.[AR], SKIP ADR.EQ.0, J/SKIP + +APRSZ: [BR]_[BR].AND.# CLR LH, #/7770 +CONSZ: [BR].AND.[AR], SKIP ADR.EQ.0, J/DONE + +.IF/PCST +WRPCST: MEM READ, [BR]_MEM + WORK[PCST]_[BR], J/DONE +.ENDIF/PCST + +1700: +GRP700: +APRID: [BR]_#, + HARDWARE OPTIONS/HWOPT, + HARDWARE SERIAL NUMBER/HWSER +137: [BR]_#, + MICROCODE OPTIONS/OPT, + MICROCODE VERSION/UCV, + HOLD RIGHT, + J/RTNREG + +1704: +WRAPR: [BR]_WORK[APR] + [BR]_[BR].AND.NOT.#, ;CLEAR THE OLD PIA + #/7, HOLD LEFT ; .. + [ARX]_[AR].AND.#, #/7 ;PUT NEW PIA IN ARX + [BR]_[BR].OR.[ARX] ;PUT NEW PIA IN BR + [ARX]_[AR].AND.#, ;MASK THE DATA BITS + #/007760 ; DOWN TO ENABLES + TR [AR], #/100000 ;WANT TO ENABLE ANY? +=0 [BR]_[BR].OR.[ARX] ;YES--SET THEM + TR [AR], #/40000 ;WANT TO DISABLE ANY? +=0 [BR]_[BR].AND.NOT.[ARX] ;YES--CLEAR THEM + [BRX]_APR ;GET CURRENT STATUS + TR [AR], #/20000 ;WANT TO CLEAR FLAGS? +=0 [BRX]_[BRX].AND.NOT.[ARX] ;YES--CLEAR BITS + TR [AR], #/10000 ;WANT TO SET ANY FLAGS? +=0 [BRX]_[BRX].OR.[ARX] ;YES--SET FLAGS + TR [AR], #/30000 ;ANY CHANGE AT ALL? +=0 READ [BRX], ;YES--LOAD NEW FLAGS + J/WRAPR2 ;TURN OFF INTERRUPT 8080 +WRAPR1: READ [BR] ;FIX DPM TIMING BUG + READ [BR], ;ENABLE CONDITIONS + SET APR ENABLES + WORK[APR]_[BR], ;SAVE FOR RDAPR + J/DONE ;ALL DONE + +WRAPR2: READ [BRX], ;LOAD NEW FLAGS + SPEC/APR FLAGS ; .. + [BRX]_[BRX].AND.NOT.#, ;CLEAR INTERRUPT THE 8080 + #/002000, HOLD LEFT ; FLAG + READ [BRX], ;LOAD NEW FLAGS + SPEC/APR FLAGS, ; .. + J/WRAPR1 ;LOOP BACK + +1705: +RDAPR: [BR]_WORK[APR] + [BR]_[BR] SWAP, ;PUT ENABLES IN BOTH + HOLD RIGHT ; HALVES + [BR]_[BR].AND.#, ;SAVE ENABLES IN LH + #/7760, ; + HOLD RIGHT + [BR]_[BR].AND.#, ;SAVE PIA IN RH + #/7, + HOLD LEFT + [ARX]_APR ;READ THE APR FLAGS + [ARX]_[ARX].AND.# CLR LH, ;MASK OUT JUNK + #/007770 ;KEEP 8 FLAGS + [BR]_[BR].OR.[ARX], ;MASH THE STUFF TOGETHER + J/RTNREG ;RETURN + + .TOC "IO -- INTERNAL DEVICES -- EBR & UBR" + +.IF/ITS +1723: +WRUBR: VMA_[AR], START READ + MEM READ, [AR]_MEM, + 3T, SKIP DP0 ; Load AC blocks? +=0 [AR]_[AR].AND.#, ; No: Clear those bits in argument. + #/100003, + HOLD RIGHT, + J/WRUBR1 + [UBR]_[UBR].AND.#, ; Yes: Clear those bits in UBR. + #/100003, + HOLD RIGHT +WRUBR1: TL [AR], #/100000 ; Set base address? +=0 [UBR]_[UBR].AND.# CLR RH, ; Yes: Clear those bits in UBR. + #/407700, + J/WRUBR2 + [AR]_[AR].AND.# CLR RH, ; No: Clear those bits in argument. + #/407700 +WRUBR2: [UBR]_[UBR].OR.[AR], ; Put it all together + LOAD AC BLOCKS, ; and tell the hardware. + J/SWEEP + +.IFNOT/ITS +1723: +WRUBR: VMA_[AR], ;LOAD E INTO VMA + START READ ;START MEMORY + MEM READ, ;WAIT FOR DATA + [AR]_MEM, 3T, ;PUT IT INTO THE AR + SKIP DP0 ;SEE IF WE WANT TO LOAD + ; AC BLOCK NUMBERS +=0 [AR]_[AR].AND.#, ;NO--CLEAR JUNK IN AR + #/100000, ; LEAVE ONLY LOAD UBR + HOLD RIGHT, ; IN LEFT HALF + SKIP ADL.EQ.0, 3T, ;SEE IF WE WANT TO LOAD + J/ACBSET ;SKIP AROUND UBR LOAD + [UBR]_[UBR].AND.#, ;MASK OUT THE OLD + #/770077, ; AC BLOCK NUMBERS + HOLD RIGHT ;IN THE LEFT HALF + [AR].AND.#, ;SEE IF WE WANT TO LOAD + #/100000, 3T, ; UBR ALSO + SKIP ADL.EQ.0 +=0 +ACBSET: [BR]_[AR].AND.#, ;COPY UBR PAGE NUMBER + #/17777, ; INTO BR + J/SETUBR ;GO LOAD UBR + [UBR]_[UBR].OR.[AR], ;DO NOT LOAD UBR + ; PUT AC BLOCK # IN + HOLD RIGHT, ; THE LEFT HALF + LOAD AC BLOCKS, ;LOAD HARDWARE + J/DONE ;ALL DONE + +SETUBR: [BR]_0, ;CLEAR BR LEFT + SC_7, ;PUT THE COUNT IN SC + HOLD RIGHT +=0 +STUBRS: [BR]_[BR]*2, ;SHIFT BR OVER + STEP SC, ; 9 PLACES + J/STUBRS + [UBR]_[UBR].AND.#, ;MASK OUT OLD UBR + #/777774, ; BITS IN + HOLD RIGHT ; LEFT HALF + [UBR]_0, ;CLEAR RIGHT HALF + HOLD LEFT + [UBR]_[UBR].OR.[BR] ;PUT IN PAGE TABLE ADDRESS + [UBR]_[UBR].OR.[AR], ;PUT IN AC BLOCK # + HOLD RIGHT, ; IN LEFT HALF + LOAD AC BLOCKS, ;TELL HARDWARE + J/SWEEP ;CLEAR CACHE +.ENDIF/ITS + +1724: +WREBR: [AR]_[AR]*2, SC_6 +=0 +WREBR1: [AR]_[AR]*2, STEP SC, J/WREBR1 +.IF/FULL ;DO NOT ENABLE PAGING IN SMALL + ; MICROCODE. + [BR]_WORK[APR] + [BR]_[BR].AND.#, #/747777, HOLD LEFT + [AR].AND.#, #/20, 3T, SKIP ADL.EQ.0 +=0 [BR]_[BR].OR.#, #/030000, HOLD LEFT + READ [BR], SET APR ENABLES + WORK[APR]_[BR] +.ENDIF/FULL + [EBR]_[AR] + [EBR].AND.#, #/40, 3T, SKIP ADL.EQ.0 +=0 [EBR]_[EBR].OR.#, #/400000, HOLD RIGHT, J/SWEEP + [EBR]_[EBR].AND.NOT.#, #/400000, HOLD RIGHT, J/SWEEP + +1725: +RDEBR: [BR]_[EBR]*.5, SC_6 +=0 +RDEBR1: [BR]_[BR]*.5, STEP SC, J/RDEBR1 + [BR]_[BR].AND.#, #/63777 ;MASK TO JUST EBR + [BR]_0, ;CLEAR LEFT HALF + HOLD RIGHT, ; BITS + J/RTNREG ;RETURN ANSWER + +.IF/ITS +1721: +RDUBR: [BR]_[UBR] + [BR]_[BR].AND.#, + #/507703, + HOLD RIGHT, + J/RTNREG + +GETPCW: [BR]_[UBR] + [BR]_[BR].AND.#, + #/507703, + HOLD RIGHT, + RETURN [1] + +.IFNOT/ITS +1721: +RDUBR: [BR]_[UBR] +=0 [BRX]_[BR]*.5, SC_6, CALL [GTPCW1] + [BR]_[BR].AND.#, ;JUST RETURN USEFUL + #/507700, HOLD RIGHT, ; BITS + J/RTNREG + + +GETPCW: [BR]_[UBR] + [BRX]_[BR]*.5, SC_6 +=0 +GTPCW1: [BRX]_[BRX]*.5, STEP SC, J/GTPCW1 + [BRX]_[BRX].AND.#, #/17777 + [BR]_[BRX], HOLD LEFT, RETURN [1] +.ENDIF/ITS + + .TOC "IO -- INTERNAL DEVICES -- KL PAGING REGISTERS" + + .DCODE +702: IOT,AC DISP, M, J/GRP702 + .UCODE + +.IF/ITS +1760: +GRP702: +SDBR1: [BR]_WORK[DBR1], J/RTNREG +1761: +SDBR2: [BR]_WORK[DBR2], J/RTNREG +1762: +SDBR3: [BR]_WORK[DBR3], J/RTNREG +1763: +SDBR4: [BR]_WORK[DBR4], J/RTNREG +.IFNOT/ITS +1760: +GRP702: +RDSPB: [BR]_WORK[SBR], J/RTNREG +1761: +RDCSB: [BR]_WORK[CBR], J/RTNREG +1762: +RDPUR: [BR]_WORK[PUR], J/RTNREG +1763: +RDCSTM: [BR]_WORK[CSTM], J/RTNREG +.ENDIF/ITS + +1766: +RDHSB: [BR]_WORK[HSBADR], J/RTNREG + +.IFNOT/ITS +1767: UUO +.IF/ITS +1767: +SPM: [ARX]_WORK[DBR1] + VMA_[AR], START WRITE + MEM WRITE, MEM_[ARX] +=0 [ARX]_WORK[DBR2], CALL [SPM-NEXT] + MEM WRITE, MEM_[ARX] +=0 [ARX]_WORK[QUAN], CALL [SPM-NEXT] +.IFNOT/JPC + MEM WRITE, MEM_[ARX], J/DONE +.IF/JPC + MEM WRITE, MEM_[ARX] +=0 [ARX]_WORK[U.JPC], CALL [SPM-NEXT] + MEM WRITE, MEM_[ARX] +=0 [ARX]_WORK[E.JPC], CALL [SPM-NEXT] + MEM WRITE, MEM_[ARX], J/DONE +.ENDIF/JPC += + +SPM-NEXT: + [AR]_[AR]+1, LOAD VMA, HOLD LEFT, START WRITE, RETURN [1] + +.ENDIF/ITS + +.IF/ITS +;;; These guys could be careful and only sweep half of the page table (but all +;;; of the cache). +1770: +LDBR1: WORK[DBR1]_[AR], J/SWEEP +1771: +LDBR2: WORK[DBR2]_[AR], J/SWEEP +1772: +LDBR3: WORK[DBR3]_[AR], J/SWEEP +1773: +LDBR4: WORK[DBR4]_[AR], J/SWEEP +.IFNOT/ITS +1770: +WRSPB: START READ + MEM READ, [AR]_MEM + WORK[SBR]_[AR], J/DONE +1771: +WRCSB: START READ + MEM READ, [AR]_MEM + WORK[CBR]_[AR], J/DONE +1772: +WRPUR: START READ + MEM READ, [AR]_MEM + WORK[PUR]_[AR], J/DONE +1773: +WRCSTM: START READ + MEM READ, [AR]_MEM + WORK[CSTM]_[AR], J/DONE +.ENDIF/ITS + +1776: +WRHSB: START READ + MEM READ, [AR]_MEM + WORK[HSBADR]_[AR], J/DONE + +.IFNOT/ITS +1777: UUO +.IF/ITS +1777: +LPMR: START READ + MEM READ, [ARX]_MEM + WORK[DBR1]_[ARX] +=0 [AR]_[AR]+1, LOAD VMA, HOLD LEFT, START READ, + CALL [LOADARX] + WORK[DBR2]_[ARX] +=0 [AR]_[AR]+1, LOAD VMA, HOLD LEFT, START READ, + CALL [LOADARX] +.IFNOT/JPC + WORK[QUAN]_[ARX], J/SWEEP +.IF/JPC + WORK[QUAN]_[ARX] +=0 [AR]_[AR]+1, LOAD VMA, HOLD LEFT, START READ, + CALL [LOADARX] + WORK[U.JPC]_[ARX] +=0 [AR]_[AR]+1, LOAD VMA, HOLD LEFT, START READ, + CALL [LOADARX] + WORK[E.JPC]_[ARX], J/SWEEP +.ENDIF/JPC += +.ENDIF/ITS + + .TOC "IO -- INTERNAL DEVICES -- TIMER CONTROL" + +TICK: [AR]_WORK[TIME1], ;[123] GET LOW WORD + SPEC/CLRCLK ;[123] CLEAR CLOCK FLAG +TOCK: [BR]_0 XWD [10000] ;2^12 UNITS PER MS + [AR]_[AR]+[BR] ;INCREMENT THE TIMER + FIX [AR] SIGN, SKIP DP0 ;SEE IF IT OVERFLOWED +=0 +TOCK1: WORK[TIME1]_[AR], ;STORE THE NEW TIME + J/TOCK2 ;SKIP OVER THE OVERFLOW CODE + [AR]_WORK[TIME0] ;GET HIGH WORD +=0* [AR]_[AR]+1, ;BUMP IT + CALL [WRTIM1] ;STORE BACK IN RAM + [AR]_0, ;CAUSE LOW WORD WORD + J/TOCK1 ; TO GET STORED + +.IF/ITS +TOCK2: TR [PI], PI.IP1/1, ;PI in progress? + PI.IP2/1, PI.IP3/1, + PI.IP4/1, PI.IP5/1, + PI.IP6/1, PI.IP7/1 +=0 +TOCK3: [AR]_WORK[TTG], ;Yes: Skip quantum counter. + J/TOCK4 + [AR]_[BR]+WORK[QUAN] ;No: Increment quantum counter. += WORK[QUAN]_[AR], + J/TOCK3 + +TOCK4: [AR]_[AR]-[BR], ;COUNT DOWN TIME TO GO + SKIP AD.LE.0 ;SEE IF IT TIMED OUT +=0 +TOCK5: WORK[TTG]_[AR], ;SAVE NEW TIME TO GO + RETURN [2] ;ALL DONE + [AR]_[AR]+WORK[PERIOD] ;WHY THROW AWAY ALL THAT ACCURACY? +.IFNOT/ITS +TOCK2: [AR]_WORK[TTG] + [AR]_[AR]-[BR], ;COUNT DOWN TIME TO GO + SKIP AD.LE.0 ;SEE IF IT TIMED OUT +=0 +TOCK5: WORK[TTG]_[AR], ;SAVE NEW TIME TO GO + RETURN [2] ;ALL DONE + [AR]_WORK[PERIOD] +.ENDIF/ITS + [BR]_APR ;GET CURRENT FLAGS + [BR]_[BR].OR.#, #/40 ;SET TIMER INTERRUPT FLAG + READ [BR], ;PLACE ON DP AND + SPEC/APR FLAGS, ; LOAD INTO HARDWARE + J/TOCK5 ;ALL DONE + + .TOC "IO -- INTERNAL DEVICES -- WRTIME & RDTIME" + +1774: +WRTIME: START READ ;FETCH WORD AT E + MEM READ, ;WAIT FOR DATA + [AR]_MEM ;PUT WORD IN AR +=00 VMA_[HR]+1, ;BUMP E + START READ, ;START MEMORY + CALL [LOADARX] ;PUT DATA IN ARX + [ARX]_[ARX].AND.#, ;CLEAR PART HELD IN + #/770000, ; HARDWARE COUNTER + HOLD LEFT, CALL [WRTIM1] +=11 WORK[TIME1]_[ARX], ;IN WORK SPACE + J/DONE ;NEXT INSTRUCTION += +WRTIM1: WORK[TIME0]_[AR], ;SAVE THE NEW VALUE + RETURN [2] + +1764: +RDTIME: [BR]_TIME ;READ THE TIME + [ARX]_TIME ; AGAIN + [BRX]_TIME ; AGAIN + [BR].XOR.[ARX], ;SEE IF STABLE + SKIP AD.EQ.0 ; .. +=0 [ARX]_[BRX] ;NO THEN NEXT TRY MUST BE OK + [BR]_WORK[TIME0] + [ARX]_[ARX]+WORK[TIME1], ;COMBINE PARTS + SKIP/-1 MS ;SEE IF OVERFLOW HAPPENED +=00 SPEC/CLRCLK, ;CLEAR CLOCK FLAG + [AR]_WORK[TIME1], 2T, ;GET LOW WORD FOR TOCK + CALL [TOCK] ;UPDATE CLOCKS + READ [HR], LOAD VMA, ;DID NOT OVERFLOW + START WRITE, J/RDTIM1 ;STORE ANSWER + J/RDTIME ;TRY AGAIN += +RDTIM1: MEM WRITE, MEM_[BR] + VMA_[HR]+1, LOAD VMA, START WRITE + MEM WRITE, MEM_[ARX], J/DONE + + .TOC "IO -- INTERNAL DEVICES -- WRINT & RDINT" + + +1775: +WRINT: START READ + MEM READ, [AR]_MEM + WORK[PERIOD]_[AR] + WORK[TTG]_[AR], + J/DONE + +1765: +RDINT: [BR]_WORK[PERIOD], + J/RTNREG + + .TOC "IO -- INTERNAL DEVICES -- RDPI & WRPI" + +1715: +RDPI: [BR]_[PI], J/RTNREG + +1714: +WRPI: TR [AR], PI.CLR/1 +=0 [PI]_0 + TR [AR], PI.MBZ/17 + +=0 UUO + [BR]_[AR].AND.#,#/177 + [BR]_[BR] SWAP, HOLD RIGHT + TR [AR], PI.DIR/1 +=0 [PI]_[PI].AND.NOT.[BR], HOLD RIGHT + TR [AR], PI.REQ/1 +=0 [PI]_[PI].OR.[BR], HOLD RIGHT + TR [AR], PI.TSN/1 +=0 [PI]_[PI].OR.#,PI.ON/1, HOLD LEFT + TR [AR], PI.TSF/1 +=0 [PI]_[PI].AND.NOT.#,PI.ON/1, HOLD LEFT + TR [AR], PI.TCN/1 +=0 [PI]_[PI].OR.[BR], HOLD LEFT + TR [AR], PI.TCF/1 +=0**0 [PI]_[PI].AND.NOT.[BR], HOLD LEFT +PIEXIT: CALL LOAD PI +=1**1 + DONE += + + +;SUBROUTINE TO LOAD PI HARDWARE +;CALL WITH: +; CALL LOAD PI +;RETURNS 10 WITH PI HARDWARE LOADED +; +LOADPI: [T0]_[PI] SWAP ;PUT ACTIVE CHANS IN LH +LDPI2: [T0]_-1, HOLD LEFT ;DONT MASK RH + [T0]_[T0].AND.[PI] ;ONLY REQUEST CHANS THAT ARE ON + .NOT.[T0], LOAD PI, ;RELOAD HARDWARE + RETURN [10] ;RETURN TO CALLER + + .TOC "IO -- INTERNAL DEVICES -- SUBROUTINES" + + +;HERE WITH SOMETHING IN BR STORE IT @AR +RTNREG: VMA_[AR], START WRITE + MEM WRITE, MEM_[BR], J/DONE + +;CACHE SWEEP + +1722: +CLRPT: VMA_[AR], ;PUT CORRECT ADDRESS IN VMA + LOAD PAGE TABLE ;GET SET TO WRITE PAGE TABLE + [AR]_0 ;CLEAR ENTRY +.IF/ITS +1720: +GRP701: +CLRCSH: [AR]_#, #/377377 ;INITIAL VMA VALUE + SC_S#, S#/375 ;LOAD THE SC WITH NUMBER OF STEPS +.IFNOT/ITS +=0 [AR]_#,#/377377, ;INITIAL VMA VALUE + CALL [SSWEEP] ;LOAD THE SC +.ENDIF/ITS + [BR]_#, #/1001, ;CONSTANT TO KEEP ADDING + CLRCSH ;START TO CLEAR CACHE + READ [AR], CLRCSH ;FIRST THING TO CLEAR +=0 +CLRPTL: [AR]_[AR]-[BR], ;UPDATE AR (AND PUT ON DP) + CLRCSH, ;SWEEP ON NEXT STEP + STEP SC, ;SKIP IF WE ARE DONE + J/CLRPTL ;LOOP FOR ALL ENTRIES +.IFNOT/ITS + READ [AR], J/ZAPPTA ;CLEAR LAST ENTRY +.IF/ITS + READ [AR], J/DONE ;Clear last entry. +.ENDIF/ITS + +=0 +SWEEP: [AR]_#,#/377377, ;INITIAL VMA VALUE + CALL [SSWEEP] ;LOAD NUMBER OF STEPS INTO SC + [BR]_#, #/1001, ;CONSTANT TO KEEP ADDING + SWEEP ;START SWEEP + READ [AR], SWEEP ;FIRST THING TO CLEAR +=0 +SWEEPL: [AR]_[AR]-[BR], ;UPDATE AR (AND PUT ON DP) + SWEEP, ;SWEEP ON NEXT STEP + STEP SC, ;SKIP IF WE ARE DONE + J/SWEEPL ;LOOP FOR ALL ENTRIES + ;CLEAR LAST ENTRY AND +.IF/ITS + [AR]_0, J/DONE ;Clear last entry. +.IFNOT/ITS +ZAPPTA: WORK[PTA.U]_0 ; FORGET PAGE TABLE ADDRESS + WORK[PTA.E]_0, ;FORGET PAGE TABLE ADDRESS + J/DONE ;ALL DONE +.ENDIF/ITS + +SSWEEP: SC_S#, S#/375, ;NUMBER OF STEPS + RETURN [1] ;RETURN + +;WE COME HERE EITHER FROM NEXT INSTRUCTION DISPATCH OR PAGE FAIL +; LOGIC. IN ALL CASES, THE CURRENT INSTRUCTION IS CORRECTLY SETUP +; TO RESTART PROPERLY. + +;FIRST SET THE CORRECT PI IN PROGRESS BIT +; [FLG]_[FLG].OR.#,FLG.PI/1, HOLD RIGHT, +; J/PI ;SET PI CYCLE AND PROCESS PI +=1000 +PI: AD/D, DBUS/PI NEW, ;LOOK AT NEW LEVEL + DISP/DP LEFT, 3T, ;DISPATCH ON IT + J/PI ;GO TO 1 OF NEXT 7 PLACES +=1001 [PI]_[PI].OR.#, #/040000, HOLD LEFT, J/PIP1 +=1010 [PI]_[PI].OR.#, #/020000, HOLD LEFT, J/PIP2 +=1011 [PI]_[PI].OR.#, #/010000, HOLD LEFT, J/PIP3 +=1100 [PI]_[PI].OR.#, #/004000, HOLD LEFT, J/PIP4 +=1101 [PI]_[PI].OR.#, #/002000, HOLD LEFT, J/PIP5 +=1110 [PI]_[PI].OR.#, #/001000, HOLD LEFT, J/PIP6 +=1111 [PI]_[PI].OR.#, #/000400, HOLD LEFT, J/PIP7 +PIP1: [BRX]_0 XWD [1], J/PI10 ;REMEMBER WE ARE AT LEVEL 1 +PIP2: [BRX]_0 XWD [2], J/PI10 ;REMEMBER WE ARE AT LEVEL 2 +PIP3: [BRX]_0 XWD [3], J/PI10 ;REMEMBER WE ARE AT LEVEL 3 +PIP4: [BRX]_0 XWD [4], J/PI10 ;REMEMBER WE ARE AT LEVEL 4 +PIP5: [BRX]_0 XWD [5], J/PI10 ;REMEMBER WE ARE AT LEVEL 5 +PIP6: [BRX]_0 XWD [6], J/PI10 ;REMEMBER WE ARE AT LEVEL 6 +PIP7: [BRX]_0 XWD [7], J/PI10 ;REMEMBER WE ARE AT LEVEL 7 + +PI10: [AR]_[PI].AND.# CLR LH, ;TURN OFF PI SYSTEM + #/077577 ; TILL WE ARE DONE + .NOT.[AR], LOAD PI ; .. + ABORT MEM CYCLE ;NO MORE TRAPS +=0 [AR]_VMA IO READ, ;SETUP TO READ WRU BITS + WRU CYCLE/1, ; .. + CALL [STRTIO] ;START THE CYCLE + MEM READ, ;WAIT FOR DATA + [AR]_IO DATA, 3T, ;PUT DATA IN AR + SKIP ADR.EQ.0 ;SEE IF ANYONE THERE +=0 [ARX]_0, J/VECINT ;YES--VECTORED INTERRUPT + [AR]_[BRX]*2 ;N*2 + [AR]_[AR]+#, #/40, 3T, ;2*N+40 + HOLD LEFT ; .. + [AR]_[AR]+[EBR], ;ABSOULTE ADDRESS OF + J/PI40 ; INTERRUPT INSTRUCTION + +;HERE WITH ABSOLUTE ADDRESS OF INTERRUPT INSTRUCTION IN [AR] +PI40: VMA_[AR], VMA PHYSICAL READ ;FETCH THE INSTRUCTION +PI50: MEM READ, [AR]_MEM, LOAD VMA, ;FETCH INSTRUCTION + 3T, FORCE EXEC ;E IS EXEC MODE + [AR].XOR.#, #/254340, 3T, SKIP ADL.EQ.0 +=0 [AR].XOR.#, #/264000, SKIP ADL.EQ.0, 3T, J/PIJSR + [BR]_FLAGS ;SAVE FLAGS + AD/ZERO, LOAD FLAGS, + J/PIXPCW ;ENTER EXEC MODE AND ASSUME + ; WE HAVE AN XPCW +;IF WE HALT HERE ON A VECTORED INTERRUPT, WE HAVE +; T0/ WHAT WE READ FROM BUS AS VECTOR +; ARX/ EPT+100+DEVICE +; BR/ ADDRESS OF ILLEGAL INSTRUCTION +; BRX/ VECTOR (MASKED AND SHIFTED) +.IFNOT/1PROC +=0 +PIJSR: HALT [ILLII] ;NOT A JSR OR XPCW + START WRITE, FORCE EXEC ;PREPARE TO STORE OLD PC +=0*0 [BR]_PC WITH FLAGS, ;OLD PC + CALL [STOBR] ;STORE OLD PC +=1*0 [AR]_#, #/0, HOLD RIGHT, ;PREPARE TO CLEAR FLAGS + CALL [INCAR] ;BUMP POINTER +=1*1 [PC]_[AR], LOAD FLAGS, ;NEW PC + J/PISET ;CLEAR PI CYCLE & START + ; INTERRUPT PROGRAM += +.IF/1PROC +=0*0 +PIJSR: HALT [ILLII] ;NOT A JSR OR XPCW +=0*1 START WRITE, FORCE EXEC, ;STORE OLD PC + CALL [STORE-INT-PC] +=1*1 [AR]_#, #/0, HOLD RIGHT ;PREPARE TO CLEAR FLAGS + [AR]_[AR]+1, HOLD LEFT ;BUMP POINTER + [PC]_[AR], LOAD FLAGS, ;NEW PC + J/PISET ;CLEAR PI CYCLE & START + ; INTERRUPT PROGRAM +.ENDIF/1PROC + +;HERE TO PROCESS A VECTORED INTERRUPT. AT THIS POINT: +; AR/ WRU BITS (BIT 18 FOR DEVICE 0) +; ARX/ 0 +VECINT: [AR]_[AR]*2, ;SHIFT LEFT (UNSHIFTED ON DP) + SKIP DP18 ;ANYONE THERE? +=0 [ARX]_[ARX]+[XWD1], ;NO--BUMP BOTH HALVES + J/VECINT ;KEEP LOOKING + [AR]_VMA IO READ, ;SETUP FOR VECTOR CYCLE + VECTOR CYCLE/1 ; .. +=0 [AR]_[AR].OR.[ARX], ;PUT IN UNIT NUMBER + CALL [STRTIO] ;START CYCLE + MEM READ, ;WAIT FOR VECTOR (SEE DPM5) + [T0]_IO DATA ;GET VECTOR +=0 [BR]_[EBR]+#, 3T, #/100, ;EPT+100 + CALL [CLARXL] ;CLEAR ARX LEFT + [ARX]_[ARX]+[BR], ;EPT+100+DEVICE + VMA PHYSICAL READ ;FETCH WORD + MEM READ, [BR]_MEM, 3T, ;GET POINTER + SKIP ADR.EQ.0 ;SEE IF NON-ZERO +=0 [BRX]_([T0].AND.#)*.5, 3T, ;OK--MAKE VECTOR MOD 400 + #/774, J/VECIN1 ; AND SHIFT OVER + HALT [ILLINT] +VECIN1: [BRX]_[BRX]*.5 ;SHIFT 1 MORE PLACE + [BR]_[BR]+[BRX], ;ADDRESS OF WORD TO USE + LOAD VMA, FORCE EXEC, ;FORCE EXEC VIRTUAL ADDRESS + START READ, J/PI50 ;GO GET INSTRUCTION + + .TOC "PRIORITY INTERRUPTS -- DISMISS SUBROUTINE" + +;SUBROUTINE TO DISMISS THE HIGHEST PI IN PROGRESS +;RETURNS 4 ALWAYS + +;DISMISS: +; TR [PI], #/077400 ;ANY PI IN PROGRESS? +=0 +JEN1: [BR]_#, PI.IP1/1, J/DSMS1 ;YES--START LOOP + RETURN [4] ;NO--JUST RETURN + +DSMS1: [PI].AND.[BR], SKIP ADR.EQ.0 +=0 [PI]_[PI].AND.NOT.[BR], HOLD LEFT, RETURN [4] + [BR]_[BR]*.5, J/DSMS1 + + .TOC "ITS IO INSTRUCTIONS" + +.IF/ITSIO + + .DCODE +710: IOT, B/10, J/IORDI ; IORDI +711: IOT, B/14, J/IORDI ; IORDQ +712: IOT, B/10, J/IORD ; IORD +713: IOT, B/10, J/IOWR ; IOWR +714: IOT, B/10, J/IOWRI ; IOWRI +715: IOT, B/14, J/IOWRI ; IOWRQ + +720: IOT, B/0, J/IORDI ; IORDBI +721: IOT, B/4, J/IORDI ; IORDBQ +722: IOT, B/0, J/IORD ; IORDB +723: IOT, B/0, J/IOWR ; IOWRB +724: IOT, B/0, J/IOWRI ; IOWRBI +725: IOT, B/4, J/IOWRI ; IOWRBQ + .UCODE + +1460: +IORD: CLR IO BUSY, + VMA_[AR], START READ + MEM READ, [AR]_MEM, + J/IORD0 + +1614: +IORDI: CLR IO BUSY, + B DISP ; Which bus? +=10** [AR]_#, #/3, HOLD RIGHT, ; Unibus I + J/IORD0 + [AR]_#, #/1, HOLD RIGHT, ; Unibus Q + J/IORD0 + +IORD0: CLR IO LATCH, + B DISP ; Which mode? +=01** [ARX]_VMA IO READ, ; Byte mode + IO BYTE/1, + J/IORD1 + [ARX]_VMA IO READ ; Word mode +=0 +IORD1: VMA_[AR].OR.[ARX] WITH FLAGS, ; Set up VMA + CALL [IOWAIT] ; and wait for it + MEM READ, [BR]_IO DATA, ; Get data + B DISP ; Which mode? +=01** TR [AR], #/1, J/IORD2 ; Byte mode: which half? +IORDEX: AC_[BR], J/DONE ; Word mode: return it + +=0 +IORD2: [BR]_[BR]*.5, SC_5, J/IORD3 ; Odd byte: go shift it + [BR]_[BR].AND.#, #/377, J/IORDEX ; Even byte: return it + +=0 +IORD3: [BR]_[BR]*.5, STEP SC, J/IORD3 ; Shift it + [BR]_[BR].AND.#, #/377, J/IORDEX ; And return it + +1461: +IOWR: CLR IO BUSY, + VMA_[AR], START READ + MEM READ, [AR]_MEM, + J/IOWR0 + +1644: +IOWRI: CLR IO BUSY, + B DISP ; Which bus? +=10** [AR]_#, #/3, HOLD RIGHT, ; Unibus I + J/IOWR0 + [AR]_#, #/1, HOLD RIGHT, ; Unibus Q + J/IOWR0 + +IOWR0: [BR]_AC, ; Data to write + CLR IO LATCH, + B DISP ; Which mode? +=01** TR [AR], #/1, J/IOWR2 ; Byte mode: which half? + [ARX]_VMA IO WRITE ; Word mode +IOWR1: VMA_[AR].OR.[ARX] WITH FLAGS ; Set up VMA +=0 MEM WRITE, MEM_[BR], ; Put data + CALL [IOWAIT] ; and wait for it + DONE ; thats it + +=0 +IOWR2: [BR]_[BR]*2, SC_5, J/IOWR3 ; Odd byte: go shift it + [ARX]_VMA IO WRITE, IO BYTE/1, J/IOWR1 ; Even byte: all set + +=0 +IOWR3: [BR]_[BR]*2, STEP SC, J/IOWR3 ; Shift it + [ARX]_VMA IO WRITE, IO BYTE/1, J/IOWR1 ; All set + +.ENDIF/ITSIO + + .TOC "EXTERNAL IO INSTRUCTIONS" + +.IFNOT/ITSIO + + .DCODE +710: IOT, WORD-TNE, J/TIOX +711: IOT, WORD-TNN, J/TIOX +720: IOT, TNE, J/TIOX +721: IOT, TNN, J/TIOX + .UCODE + +1614: +TIOX: CALL [IORD] +1617: [BR]_[AR].AND.AC, TEST DISP + + .DCODE +712: IOT, B/10, J/RDIO +713: IOT, B/10, J/WRIO +722: IOT, B/0, J/RDIO +723: IOT, B/0, J/WRIO + .UCODE + +1460: +RDIO: CALL [IORD] +1463: AC_[AR], J/DONE + +1461: +WRIO: [BR]_AC, J/IOWR + + .DCODE +714: IOT, B/10, J/BIXUB +715: IOT, B/14, J/BIXUB +724: IOT, B/0, J/BIXUB +725: IOT, B/4, J/BIXUB + .UCODE + +1644: +BIXUB: [BRX]_[AR], ;SAVE EFFECTIVE ADDRESS + CALL [IORD] ;GO GET THE DATA +1647: [BR]_[AR], ;COPY DATA ITEM + B DISP ;SEE IF SET OR CLEAR +=1011 [BR]_[BR].OR.AC, ;SET BITS + J/BIXUB1 ;GO DO WRITE + [BR]_[BR].AND.NOT.AC, ;CLEAR BITS + J/BIXUB1 ;GO DO WRITE + +BIXUB1: [AR]_[BRX], ;RESTORE ADDRESS + J/IOWR + +;SUBROUTINE TO READ FROM AN IO DEVICE +;CALL WITH: +; SECTION 0 EFFECTIVE ADDRESS IN AR +; INSTRUCTION IN HR +;RETURN 3 WITH WORD OR BYTE IN AR +; +=0 +IORD: CLR IO BUSY, ;CLEAR BUSY + CALL [IOEA] ;COMPUTE IO EA + B DISP +=10111 [BR]_VMA IO READ, ;BYTE MODE + IO BYTE/1, ;SET BYTE FLAG + J/IORD1 ;GO DO C/A CYCLE +=11111 [BR]_VMA IO READ ;WORD MODE += +=0 +IORD1: VMA_[AR].OR.[BR] WITH FLAGS, + CALL [IOWAIT] ;WAIT FOR THINGS COMPLETE + MEM READ, ;MAKE SURE REALLY READY + [BR]_IO DATA, ;PUT DATA IN BR + B DISP ;SEE IF BYTE MODE +=0111 TR [AR], #/1, J/IORD2 ;BYTE MODE SEE IF ODD + [AR]_[BR], RETURN [3] ;ALL DONE + +;HERE ON WORD MODE +=0 +IORD2: [BR]_[BR]*.5, SC_5, ;LEFT BYTE + J/IORD3 ;GO SHIFT IT + [AR]_[BR].AND.#, ;MASK IT + #/377, RETURN [3] ;ALL DONE + +=0 +IORD3: [BR]_[BR]*.5, ;SHIFT OVER + STEP SC, J/IORD3 ; .. + [AR]_[BR].AND.#, ;MASK IT + #/377, RETURN [3] ;ALL DONE + +;ROUTINE TO WRITE TO AN IO DEVICE +;CALL WITH: +; SECTION 0 EFFECTIVE ADDRESS IN AR +; INSTRUCTION IN HR +; WORD OR BYTE IN BR +;RETURNS BACK TO USER +; +=0 +IOWR: CLR IO BUSY, ;CLEAR BUSY + CALL [IOEA] ;COMPUTE IO EA + B DISP +=10111 TR [AR], #/1, J/IOWR2 ;BYTE MODE +=11111 [ARX]_VMA IO WRITE ;SETUP FLAGS += +IOWR1: VMA_[AR].OR.[ARX] WITH FLAGS +=0 MEM WRITE, MEM_[BR], ;SEND DATA + CALL [IOWAIT] ;WAIT FOR DATA + DONE ;RETURN + +;HERE FOR BYTE MODE +=0 +IOWR2: [BR]_[BR]*2, SC_5, ;ODD--MOVE LEFT + J/IOWR3 ; .. + [ARX]_VMA IO WRITE, ;SETUP FLAGS + IO BYTE/1, J/IOWR1 ; .. + +=0 +IOWR3: [BR]_[BR]*2, STEP SC, ;SHIFT LEFT + J/IOWR3 ;KEEP SHIFTING + [ARX]_VMA IO WRITE, ;SETUP FLAGS + IO BYTE/1, J/IOWR1 ; .. + +;HERE TO COMPUTE IO EFFECTIVE ADDRESS +;CALL WITH: +; SECTION 0 EFFECTIVE ADDRESS IN AR +; INSTRUCTION IN HR +;RETURN 1 WITH EA IN AR +; +=0 +IOEA: VMA_[PC]-1, ;GET INSTRUCTION + START READ, ; .. + CALL [LOADAR] ;PUT WORD IN AR + [BRX]_.NOT.[AR] ;SEE IF IN RANGE 700-777 + TL [BRX], #/700000 ; .. +=0 +IOEA1: TL [HR], #/20, J/IOEA2 ;INDIRECT? + WORK[YSAVE]_[AR] CLR LH, ;DIRECT IO INSTRUCTION + J/IOEA1 ;SAVE Y FOR EA CALCULATION +=0 +IOEA2: [AR]_WORK[YSAVE], ;@--GET SAVED Y + J/IOEAI ;GET Y AND GO + EA MODE DISP ;WAS THERE INDEXING? +=1101 [ARX]_XR, SKIP ADL.LE.0, ;SEE IF LOCAL OR GLOBAL INDEXING + 2T, J/IOEAX ; .. + [AR]_WORK[YSAVE], ;JUST PLAIN IO + CLR IO LATCH, RETURN [1] + +IOEAI: READ [HR], DBUS/DP, ;LOAD XR FLOPS IN CASE + LOAD INST EA ; THERE IS INDEXING + TL [HR], #/17 ;WAS THERE ALSO INDEXING +=0 [AR]_[AR]+XR, 3T, HOLD LEFT ;YES--ADD IN INDEX VALUE + VMA_[AR], START READ ;FETCH DATA WORD + MEM READ, [AR]_MEM, ;GO GET DATA WORD + CLR IO LATCH, RETURN [1] + +=0 +IOEAX: [AR]_[ARX]+WORK[YSAVE], ;GLOBAL INDEXING + CLR IO LATCH, RETURN [1] + [AR]_[ARX]+WORK[YSAVE] ;LOCAL INDEXING + [AR]_0, HOLD RIGHT, + CLR IO LATCH, RETURN [1] + +.ENDIF/ITSIO + +;WAIT FOR IO TO COMPLETE +;RETURNS 1 OR PAGE FAILS +; +IOWAIT: SC_S#, S#/200, ;DELAY + [T0]_VMA, ;GET VMA + SKIP/-IO BUSY ;SEE IF BUSY YET +=00 +IOW1: CLR IO LATCH, ;WENT BUSY + WORK[SV.VMA]_[T0], ;MAKE SURE SV.VMA IS SETUP + J/IOW2 ;WAIT FOR IT TO CLEAR + SC_SC-1, SCAD DISP, 5T, ;SEE IF DONE YET + SKIP/-IO BUSY, ; .. + J/IOW1 ;BACK TO LOOP + CLR IO LATCH, ;WENT BUSY AND TIMEOUT + WORK[SV.VMA]_[T0], ;MAKE SURE SV.VMA IS SETUP + J/IOW2 ; .. + WORK[SV.VMA]_[T0], ;MAKE SURE SV.VMA IS SETUP + J/IOW5 ;GO TRAP + +IOW2: SC_S#, S#/777, ;GO TIME IO + SKIP/-IO BUSY ; .. +=0 +IOW3: CLR IO LATCH, ;TRY TO CLEAR LATCH + STEP SC, J/IOW4 ;STILL BUSY + RETURN [1] ;IDLE + +=0 +IOW4: CLR IO LATCH, 5T, ;TRY TO CLEAR LATCH + SKIP/-IO BUSY, ;SEE IF STILL BUSY + J/IOW3 ; .. +IOW5: [BRX]_[200000] XWD 0, J/HARD + + .TOC "SMALL SUBROUTINES" + +;HERE ARE A COLLECTION ON 1-LINE SUBROUTINES +LOADAR: MEM READ, [AR]_MEM, ;FROM MEMORY TO AR + RETURN [1] ;RETURN TO CALLER + +LOADARX: MEM READ, [ARX]_MEM, RETURN [1] + +LOADQ: MEM READ, Q_MEM, RETURN [1] + +ABORT: ABORT MEM CYCLE, RETURN [1] + +CLARXL: [ARX]_0, HOLD RIGHT, RETURN [1] + +INCAR: [AR]_[AR]+1, RETURN [1] + +SBRL: [BR]_[BR]*2, RETURN [1] + +STRTIO: VMA_[AR] WITH FLAGS, RETURN [1] + +STOBR: MEM WRITE, MEM_[BR], RETURN [4] + +STOPC: MEM WRITE, MEM_[PC], RETURN [1] + +AC_ARX: AC_[ARX], RETURN [1] + + .TOC "UNDEFINED IO INSTRUCTIONS" + + .DCODE +703: I, B/3, J/IOT700 +706: I, B/6, J/IOT700 + I, B/7, J/IOT700 + +716: I, B/6, J/IOT710 + I, B/7, J/IOT710 + +726: I, B/6, J/IOT720 + I, B/7, J/IOT720 + +730: I, B/0, J/IOT730 + I, B/1, J/IOT730 + I, B/2, J/IOT730 + I, B/3, J/IOT730 + I, B/4, J/IOT730 + I, B/5, J/IOT730 + I, B/6, J/IOT730 + I, B/7, J/IOT730 + +740: I, B/0, J/IOT740 + I, B/1, J/IOT740 + I, B/2, J/IOT740 + I, B/3, J/IOT740 + I, B/4, J/IOT740 + I, B/5, J/IOT740 + I, B/6, J/IOT740 + I, B/7, J/IOT740 + +750: I, B/0, J/IOT750 + I, B/1, J/IOT750 + I, B/2, J/IOT750 + I, B/3, J/IOT750 + I, B/4, J/IOT750 + I, B/5, J/IOT750 + I, B/6, J/IOT750 + I, B/7, J/IOT750 + +760: I, B/0, J/IOT760 + I, B/1, J/IOT760 + I, B/2, J/IOT760 + I, B/3, J/IOT760 + I, B/4, J/IOT760 + I, B/5, J/IOT760 + I, B/6, J/IOT760 + I, B/7, J/IOT760 + +770: I, B/0, J/IOT770 + I, B/1, J/IOT770 + I, B/2, J/IOT770 + I, B/3, J/IOT770 + I, B/4, J/IOT770 + I, B/5, J/IOT770 + I, B/6, J/IOT770 + I, B/7, J/IOT770 + .UCODE + +1650: +IOT700: UUO +1651: +IOT710: J/BLTX ;GO TO COMMON CODE FOR UBABLT INSTRS +1652: +IOT720: UUO +1653: +IOT730: UUO +1654: +IOT740: UUO +1655: +IOT750: UUO +1656: +IOT760: UUO +1657: +IOT770: UUO + + .TOC "UMOVE AND UMOVEM" + + .DCODE +704: IOT, J/UMOVE + IOT, J/UMOVEM + .UCODE + +1754: +UMOVE: VMA_[AR], ;LOAD VMA + START READ, ;START MEMORY + SPEC/PREV ;FORCE PREVIOUS + MEM READ, ;WAIT FOR MEMORY + [AR]_MEM, ;PUT DATA IN AR + J/STAC ;GO PUT AR IN AC + +1755: +UMOVEM: VMA_[AR], ;LOAD VMA + START WRITE, ;START MEMORY + SPEC/PREV ;FORCE PREVIOUS + [AR]_AC, ;FETCH AC + J/STMEM ;STORE IN MEMORY + +;HERE WITH HALT CODE IN THE T1 +=010* +HALTED: WORK[SV.ARX]_[ARX], ;SAVE TEMP REGISTER + CALL [SAVVMA] ;PUT VMA IN WORK[SV.VMA] +=110* ABORT MEM CYCLE, ;ABORT CYCLE IN PROGRESS + CALL [WRTHSB] ;WRITE HALT STATUS BLOCK +=111* +PWRON: [ARX]_0, VMA PHYSICAL WRITE ;STORE HALT CODE += + MEM WRITE, MEM_[T1] ; IN LOCATION 0 +=0 NEXT [ARX] PHYSICAL WRITE, + CALL [STOPC] +H1: SET HALT, J/HALTLP ;TELL CONSOLE WE HAVE HALTED + + +4: UNHALT, ;RESET CONSOLE + SKIP EXECUTE, J/CONT ;SEE IF CO OR EX +5: +HALTLP: SKIP/-CONTINUE, J/4 ;WAIT FOR CONTINUE + +=0 +CONT: VMA_[PC], ;LOAD PC INTO VMA + FETCH, ;START READ + J/XCTGO ;DO THE INSTRUCTION + [AR]_VMA IO READ ;PUT FLAGS IN AR +=0 [AR]_[AR].OR.#, ;PUT IN ADDRESS + #/200000, HOLD LEFT, ; OF CSL REGISTER + CALL [STRTIO] +CONT1: MEM READ, ;WAIT FOR DATA + [HR]_MEM, ;PUT IN HR + LOAD INST, ;LOAD IR, ETC. + J/XCT1 ;GO DO THE INSTRUCTION + + .TOC "WRITE HALT STATUS BLOCK" + +;THE HALT STATUS BLOCK LOOKS LIKE: + +; !=======================================================! +; !00! MAG ! +; !-------------------------------------------------------! +; !01! PC ! +; !-------------------------------------------------------! +; !02! HR ! +; !-------------------------------------------------------! +; !03! AR ! +; !-------------------------------------------------------! +; !04! ARX ! +; !-------------------------------------------------------! +; !05! BR ! +; !-------------------------------------------------------! +; !06! BRX ! +; !-------------------------------------------------------! +; !07! ONE ! +; !-------------------------------------------------------! +; !10! EBR ! +; !-------------------------------------------------------! +; !11! UBR ! +; !-------------------------------------------------------! +; !12! MASK ! +; !-------------------------------------------------------! +; !13! FLG ! +; !-------------------------------------------------------! +; !14! PI ! +; !-------------------------------------------------------! +; !15! XWD1 ! +; !-------------------------------------------------------! +; !16! T0 ! +; !-------------------------------------------------------! +; !17! T1 ! +; !=======================================================! +; ! VMA FLAGS ! VMA ! +; !=======================================================! + +;START AT 1 TO DUMP 2901 REGISTERS INTO MAIN MEMORY +1: WORK[SV.ARX]_[ARX], ;SAVE TEMP REGISTER + CALL [SAVVMA] ;WORK[SV.VMA]_VMA +11: [ARX]_WORK[HSBADR] +=10* ABORT MEM CYCLE, CALL [DUMP] + SET HALT, J/H1 + + +WRTHSB: [ARX]_WORK[HSBADR], ;GET ADDRESS OF HSB + SKIP AD.LE.0, 4T ;SEE IF VALID +=0 READ [MASK], LOAD PI, ;TURN OFF PI SYSTEM + J/DUMP ; AND GO TAKE DUMP + [ARX]_WORK[SV.ARX], + RETURN [2] ;DO NOT DUMP ANYTHING + +SAVVMA: [ARX]_VMA + WORK[SV.VMA]_[ARX], + RETURN [10] + +;DUMP OUT THE 2901 +DUMP: READ [ARX], VMA PHYSICAL WRITE +=0* MEM WRITE, MEM_[MAG], CALL [NEXT] + MEM WRITE, MEM_[PC] + NEXT [ARX] PHYSICAL WRITE +=0* MEM WRITE, MEM_[HR], CALL [NEXT] + MEM WRITE, MEM_[AR] +=0* WORK[SV.AR]_[AR], CALL [NEXT] + [AR]_WORK[SV.ARX] +=0* MEM WRITE, MEM_[AR], CALL [NEXT] + MEM WRITE, MEM_[BR] + NEXT [ARX] PHYSICAL WRITE +=0* MEM WRITE, MEM_[BRX], CALL [NEXT] + MEM WRITE, MEM_[ONE] + NEXT [ARX] PHYSICAL WRITE +=0* MEM WRITE, MEM_[EBR], CALL [NEXT] + MEM WRITE, MEM_[UBR] + NEXT [ARX] PHYSICAL WRITE +=0* MEM WRITE, MEM_[MASK], CALL [NEXT] + MEM WRITE, MEM_[FLG] + NEXT [ARX] PHYSICAL WRITE +=0* MEM WRITE, MEM_[PI], CALL [NEXT] + MEM WRITE, MEM_[XWD1] + NEXT [ARX] PHYSICAL WRITE +=0* MEM WRITE, MEM_[T0], CALL [NEXT] + MEM WRITE, MEM_[T1] +=0* [AR]_WORK[SV.VMA], CALL [NEXT] + MEM WRITE, MEM_[AR] +HSBDON: [AR]_WORK[SV.AR] + [ARX]_WORK[SV.VMA] + VMA_[ARX] + [ARX]_WORK[SV.ARX], + RETURN [6] diff --git a/src/kshack/its.16 b/src/kshack/its.16 new file mode 100755 index 00000000..e6f2050e --- /dev/null +++ b/src/kshack/its.16 @@ -0,0 +1,26 @@ +;;;-*-Fundamental-*- + +.TOC "MICROCODE CONDITIONAL ASSEMBLY PARAMETERS FOR ITS" + +.SET/CIRC=1 ;Enable CIRC instruction. + +.SET/ITS=1 ;ITS style microcode. + +.SET/JPC=0 ;No JPC initially. + +.SET/1PROC=1 ;One-Proceed feature. + +.SET/PCST=1 ;PC Sample Table + +.SET/ITSIO=1 ;ITS I/O instructions. + +.SET/TEST=0 ;1 => Testing some new feature. + +MICROCODE VERSION/=<99:107> + UCV=263. + +HARDWARE OPTIONS/=<90:92> + HWOPT=0 + +HARDWARE SERIAL NUMBER/=<93:107> + HWSER=1729. diff --git a/src/kshack/itspag.98 b/src/kshack/itspag.98 new file mode 100755 index 00000000..0bfc3c2c --- /dev/null +++ b/src/kshack/itspag.98 @@ -0,0 +1,424 @@ +; -*- Fundamental -*- + +.TOC "ITS PAGE REFILL CODE" + +.IF/ITS + +CLEANUP DONE "END STATE, SKIP IRPT, J/PFTRAP" +CLEANUP AND TRAP "[AR]_WORK[SV.VMA], SKIP/TRAP CYCLE, J/CLTRP" + +;ITS page table entry: +; (when shifted left once the valid bit, cache bit, write bit and page +; number will be in the right place for loading the hardware.) +PTE VALID/=<91> ;2.8 (internal to the microcode) +PTE AGE/=<94> ;2.5 + ALL=1 ; (actually a field of length 1) +PTE WRITE/=<94> ;2.5 (internal to the microcode) +PTE CACHE/=<95> ;2.4 +PTE PAGE/=<98:107> ;2.1 - 1.1 + +;Hardware page table control bits: +PT VALID/=<90> ;2.9 +PT WRITE/=<93> ;2.6 +PT CACHE/=<94> ;2.5 +PT PAGE/=<97:107> ;2.2 - 1.1 + EVEN=3776 + ALL=3777 + +; VMA flags: Page fail word flags: +;4.9 User mode User mode +;FORCE USER +;4.8 Exec mode Nonexistent IO register +NONEXISTENT IO REGISTER/=<91> ;J/IOW5 +;4.7 Instruction fetch Nonexistent memory +NONEXISTENT MEMORY/=<92> ;J/PFD +;4.6 Read Uncorrectable memory error +UNCORRECTABLE MEMORY ERROR/=<93> ;J/PFD, J/BADDATA +;4.5 Write test +;WRITE TEST +;4.4 Write Memory write +;WRITE CYCLE +;4.3 2.9 from page table entry +;4.2 Don't cache 2.8 from page table entry +PAGE ACCESS/=<96:97> +;4.1 Physical Physical +;PHYSICAL +;3.4 - 1.1 Address Address +ADDRESS HIGH/=<104:107> + MEMORY=3 ;20 bits of physical memory address. + IO=17 ;22 bits of IO address. + ALL=17 + +; (These VMA flags only from DP:) +;3.8 IO cycle IO cycle +;IO CYCLE +;3.7 WRU cycle +;3.6 Vector cycle +;3.5 Byte cycle IO byte cycle +;IO BYTE + +; (These VMA flags only from #:) +;3.9 - 3.7 XCTR control +;3.6 Hack for AREAD: DROM supplies 4.6 - 4.4 and 3.4 +;3.5 Ignore 4.9 - 3.7 from # and use 4.9 - 3.5 from DP instead. +;3.4 Load the VMA +;3.3 Extended address: Use 3.4 - 3.1 +;3.2 Wait: Start a cycle. +;3.1 Hack for BWRITE: DROM supplies 3.2 + + .DCODE +257: IOT, AC, J/UUO257 ;Used to be MAP + .UCODE + +1553: +UUO257: UUO + +;The hardware comes here with a page fail or pending interrupt: +3777: +PAGE-FAIL: + WORK[SV.AR]_[AR] + ;;INTERRUPT-TRAP macro (which nobody uses) does the above and comes + ;;here: +ITRAP: WORK[SV.ARX]_[ARX] ;J/MVSKP + WORK[SV.BRX]_[BRX] + [BRX]_VMA ;BRX: FLAGS,,VMA + WORK[SV.VMA]_[BRX], + SKIP IRPT ;See if interrupt (saves a dispatch) +=0000 +PFD: DBM/PF DISP, DBUS/DBM, ;Puts page fail condition on + AD/D, DEST/PASS, 4T, ;DP 18-21. + DISP/DP LEFT, J/PFD ;Dispatch on it. +=0001 WORK[SV.BR]_[BR], ;(1) Interrupt + J/PF-INT +=0011 [BRX]_IO DATA, ;(3) Parity + AD PARITY OK/0, ;Don't look at parity. + J/BADDATA +=0101 [BRX]_[100000] XWD 0, ;(5) NXM + J/HARD +=0111 [BRX]_[140000] XWD 0, ;(7) NXM & Parity + J/HARD +=1000 WORK[SV.BR]_[BR], ;(10) Read-only page + J/PFMAP +=1001 WORK[SV.BR]_[BR], ;[123] (11) 1 ms timer and movsrj + J/PF-INT +=1010 WORK[SV.BR]_[BR], ;(12) Nonexistent page + J/PFMAP +=1011 WORK[SV.BR]_[BR], ;(13) Exec/User mismatch + J/PFMAP += + +;Here is how a hard memory error is handled: +BADDATA: + WORK[BADW0]_[BRX] ;Save bad word. + [BRX]_[040000] XWD 0 + ;;I/O failures come here from J/IOW5 with 200000 in BRX: +HARD: WORK[SV.BR]_[BR] ;Finally save BR +=0 [BR]_VMA, ;VMA for page fail word. + CALL [ABORT] ;Clear page fault condition. + [BR]_[BR].AND.#, ;Save interesting flags: + FORCE USER/1, PHYSICAL/1, + IO CYCLE/1, IO BYTE/1, + ADDRESS HIGH/ALL, HOLD RIGHT += [BRX]_[BRX].OR.[BR] ;BRX: Page fail word + PAGE FAIL TRAP + +;Here is what happens when the initial dispatch on the page fail condition +;tells us an interrupt is pending: +PF-INT: SKIP IRPT ;Timer trap? +=00 [AR]_WORK[TIME1], ;Yes: Get low word. + SPEC/CLRCLK, ; Clear clock flag. + CALL [TOCK] ; Do the update. TOCK returns 2. + CLEANUP AND TRAP ;No: External interrupt. Jump away + ABORT MEM CYCLE ;Clear 1ms flags. += +.IF/PCST ;Take a PC sample every millisecond + [AR]_WORK[SV.VMA] ;Recover VMA and flags + [ARX]_WORK[PCST], SKIP DP0 ;Skip if PC sampling is enabled +=0 [ARX]_WORK[SV.ARX], J/PAGE-CONTINUE1 ;Disabled or table full + [BR]_PC WITH FLAGS + TL [AR], FETCH/1 ;Skip if PC points at current instruction +=0 [BR]_[BR]-1, HOLD LEFT ;No, back up the PC that gets stored + WORK[PCST]_[ARX]+[XWD1] ;Increment the AOBJN pointer + [ARX] LEFT_0 ;Clear high bits of physical address damn it + VMA_[ARX], VMA PHYSICAL WRITE ;Store PC into sample table + MEM WRITE, MEM_[BR], J/PAGE-CONTINUE +.IFNOT/PCST + [AR]_WORK[SV.VMA], ;Restore VMA and continue where + J/PAGE-CONTINUE ; we left off. +.ENDIF/PCST + +;Here we handle a soft page failure. BRX contains VMA FLAGS,,VMA. +PFMAP: ABORT MEM CYCLE ;Clear page fail condition. + TL [BRX], WRITE TEST/1 ;Write test? +=0 [BRX]_[BRX].OR.#, ;Yes: Turn into simple write. + WRITE CYCLE/1, HOLD RIGHT + [BRX]_[BRX].AND.#, ;Save interesting flags: + FORCE USER/1, WRITE CYCLE/1, PHYSICAL/1, + ADDRESS HIGH/MEMORY, HOLD RIGHT += [AR]_[BRX], ;Copy virtual address and + SC_9. ;prepare to shift 11 places. +=0 +PFMAP1: [AR]_[AR]*.5, ;Right adjust page # + STEP SC, J/PFMAP1 + [AR]_[AR].AND.# CLR LH, ;AR: index off DBR + #/77 += READ [BRX], SKIP DP0 ;User ref? +=0 READ [BRX], SKIP DP18, ;Exec high ref? + J/EXEC-DBR + READ [BRX], SKIP DP18, ;User high ref? + J/USER-DBR += + +=0 +USER-DBR: + [AR]_[AR]+WORK[DBR1], ;User low + J/GOTDBR + [AR]_[AR]+WORK[DBR2], ;User high + J/GOTDBR += + +=0 +EXEC-DBR: + [AR]_[AR]+WORK[DBR4], ;Exec low + J/GOTDBR + [AR]_[AR]+WORK[DBR3], ;Exec high + J/GOTDBR += + +;BRX: Original VMA FLAGS,,VMA modified as for a page fail word. +;AR: Address of page table word. +GOTDBR: VMA_[AR], START READ, VMA PHYSICAL + MEM READ, [BR]_MEM + TR [BRX], #/2000 ;Odd? +=0 [ARX]_[BR], ;Yes: entry is in right half, just copy it + J/PTWRH ; into ARX. + [ARX]_[BR] SWAP, ;No: entry is in left half, so copy in ARX + J/PTWLH ; is swapped first. += + +PTWRH: [BR]_[BR].AND.NOT.#, ;BR gets the word to write back with the + PTE AGE/ALL, ; age bits cleared in the right half. + HOLD LEFT, + SKIP DP18, J/PTWTST ;Test 2.9 of entry. + +PTWLH: [BR]_[BR].AND.NOT.#, ;BR gets the word to write back with the + PTE AGE/ALL, ; age bits cleared in the left half. + HOLD RIGHT, + SKIP DP0, J/PTWTST ;Test 2.9 of entry. + +=0 +PTWTST: TR [ARX], #/200000, J/PTWTS0 ;0X: Test 2.8 + TR [ARX], #/200000, J/PTWTS1 ;1X: Test 2.8 += + +=0 +PTWTS0: [BRX]_[BRX].OR.#, ;01: Read only + PAGE ACCESS/1, ;Indicate that in page fail word. + HOLD RIGHT, + J/READ-ONLY + PAGE FAIL TRAP ;00: Not accessible. += + +=0 +PTWTS1: [ARX]_[ARX].OR.#, ;11: Read/Write + PTE WRITE/1, ;Set Writable bit in page table. + HOLD LEFT, + J/PAGE-REFILL + [BRX]_[BRX].OR.#, ;10: Read/Write/First + PAGE ACCESS/2, ;Indicate that in page fail word. + HOLD RIGHT, + J/READ-ONLY += + +READ-ONLY: + TL [BRX], ;Were we perhaps trying to write? + WRITE CYCLE/1 +=0 PAGE FAIL TRAP ;That would be a problem wouldn't it! + [ARX]_[ARX].AND.NOT.#, ;Clear writable bit in page table. + PTE WRITE/1, + HOLD LEFT, + J/PAGE-REFILL += + +;BRX: Original VMA FLAGS,,VMA modified as for a page fail word. +;AR: Address of page table word. +;ARX: Half formed page table entry in right half. +;BR: Original page table word with the age bit set. +PAGE-REFILL: + VMA_[AR], ;Prepare to put the word back. + START WRITE, + VMA PHYSICAL + MEM WRITE, ;Write it back. + MEM_[BR] + [AR]_WORK[SV.VMA] ;AR: For PAGE-CONTINUE to use. + [BR]_[AR].AND.NOT.#, ;Clear bits which start a cycle. + READ CYCLE/1, WRITE CYCLE/1, + WRITE TEST/1, HOLD RIGHT + [BR]_[AR].AND.NOT.#, ;Make DEC page number even. + #/1000, HOLD LEFT + VMA_[BR], 3T, DP FUNC/1 ;Restore VMA and set User according to + ;what it was. + [ARX]_([ARX].OR.#)*2, ;Set Valid bit and shift into position. + 3T, PTE VALID/1, + LOAD PAGE TABLE ;Load page table on next instruction. + [ARX]_[ARX].AND.# CLR LH, ;Mask out all but the correct + PT VALID/1, PT WRITE/1, ; bits. Make the DEC physical + PT CACHE/1, PT PAGE/EVEN ; page number even. + [BR]_[BR].OR.#, ;Make DEC page number in VMA odd. + #/1000, HOLD LEFT + VMA_[BR], 3T, DP FUNC/1 ;Restore VMA again for the odd page. + [ARX]_[ARX].OR.#, ;Then the odd physical page. + #/1, HOLD LEFT, + LOAD PAGE TABLE ;Load page table on next instruction. + READ [ARX], + J/PAGE-CONTINUE + +;Return to interrupted microinstruction after a successful page table +;reload or a timer trap. AR should contain the right VMA to restart the +;memory cycle. +PAGE-CONTINUE: + [ARX]_WORK[SV.ARX] ;Restore saved stuff +PAGE-CONTINUE1: + [BR]_WORK[SV.BR] + [BRX]_WORK[SV.BRX] + VMA_[AR], ;MAKE MEM REQUEST + DP FUNC/1, 3T, ;FROM DATA PATH + WAIT/1 ;WAIT FOR PREVIOUS CYCLE TO + ; COMPLETE. (NEED THIS TO + ; START ANOTHER CYCLE) + [AR]_WORK[SV.AR], + RETURN [0] + +;;; Here we have hair to back us out of an instruction in case we have to +;;; deliver a page fault or an interrupt. Think of it as micro PCLSRing. +;;; Anybody who comes to this page to deliver a page fault better have set +;;; up BRX to contain the right page fail word first. Cleanup handlers +;;; better not smash it either. + +;PAGE FAIL TRAP macro does: +; TL [FLG], FLG.PI/1, ;PI cycle? +; J/PFT +=0 +PFT: HALT [IOPF] ;Yes: IO Page Failure + CLEANUP AND TRAP ;No: deliver hard page fault. += + +;CLEANUP AND TRAP macro does: +; [AR]_WORK[SV.VMA], +; SKIP/TRAP CYCLE, ;See if trap cycle. +; J/CLTRP +=0 +CLTRP: TL [AR], FETCH/1, ;Is this an instruction fetch? + J/CLTRP1 + [AR]_WORK[TRAPPC] ;This is a trap cycle. += READ [AR], LOAD FLAGS, ;Restore PC flags. + J/CLDISP + +=0 +.IF/1PROC ;Fault/interrupt while in instruction fetch +CLTRP1: TL [FLG], FLG.2PROC/1, J/CLTRP2 +.IFNOT/1PROC +CLTRP1: CLEANUP DONE ;Instruction fetch: Everything is clean. +.ENDIF/1PROC + ;;Many things jump here to backup the PC and cleanup. +FIXPC: [PC]_[PC]-1, HOLD LEFT += ;;Many things jump here to cleanup. +CLDISP: READ [FLG], DBUS/DP, DISP/DP, 3T, J/CLEANUP + ;;CLEANUP DISP macro (which nobody uses) does the above. + +.IF/1PROC +=0 +CLTRP2: TAKE 1-PROCEED TRAP ;Take one-proceed trap instead of this one + CLEANUP DONE +.ENDIF/1PROC + +=0000 +CLEANUP: ;;Dispatch table to cleanup after a page fault or interrupt. +CLEANED: ;;J/BLT-CLEANUP ;(0) Normal case: No more cleanup needed. + CLEANUP DONE ;Go deliver page fault or interrupt. +=0001 [AR]_WORK[SV.ARX], ;(1) BLT + J/BLT-CLEANUP + ;(2) Unused. +=0011 STATE_[EDIT-SRC], ;(3) SRC IN STRING MOVE + J/STRPF +=0100 STATE_[EDIT-DST], ;(4) DST IN STRING MOVE + J/STRPF +=0101 STATE_[SRC], ;(5) SRC+DST IN STRING MOVE + J/BACKD +=0110 STATE_[EDIT-DST], ;(6) FILL IN MOVSRJ + J/STRPF4 +=0111 STATE_[EDIT-SRC], ;(7) DEC TO BIN + J/PFDBIN +=1000 STATE_[EDIT-SRC], ;(10) SRC+DST IN COMP + J/CMSDST +=1001 END STATE, J/BACKS ;(11) EDIT SRC FAIL +=1010 END STATE, J/BACKD ;(12) EDIT DST FAIL +=1011 STATE_[EDIT-SRC], ;(13) SRC+DST IN EDIT + J/BACKD += + +;CLEANUP DONE macro does: +; END STATE, SKIP IRPT, J/PFTRAP +=0 +PFTRAP: TR [PI], ;Here to deliver page fault after cleanup. + PI.IP1/1, PI.IP2/1, ; This hack figures out what 3 locations to + PI.IP3/1, PI.IP4/1, ; use to deliver the page fault. + J/PFTDSP + TAKE INTERRUPT ;Here to deliver interrupt after cleanup. + ; J/PI after setting FLG.PI += + +=0 +PFTDSP: TR [PI], PI.IP1/1, PI.IP2/1, J/PFTDS1 + TR [PI], PI.IP5/1, PI.IP6/1, J/PFTDS0 +=0 +PFTDS1: TR [PI], PI.IP1/1, J/PFTD11 + TR [PI], PI.IP3/1, J/PFTD10 +=0 +PFTDS0: TR [PI], PI.IP5/1, J/PFTD01 + TR [PI], PI.IP7/1, J/PFTD00 +=0 +PFTD11: [AR]_0 XWD [443], J/PFTRAP1 + [AR]_0 XWD [446], J/PFTRAP1 +=0 +PFTD10: [AR]_0 XWD [451], J/PFTRAP1 + [AR]_0 XWD [454], J/PFTRAP1 +=0 +PFTD01: [AR]_0 XWD [457], J/PFTRAP1 + [AR]_0 XWD [462], J/PFTRAP1 +=0 +PFTD00: [AR]_0 XWD [465], J/PFTRAP1 + [AR]_0 XWD [440], J/PFTRAP1 += + +PFTRAP1: + [AR]_[AR]+[EBR], ; Where to store PFW + VMA PHYSICAL WRITE + MEM WRITE, ; Store PFW + MEM_[BRX] +.IF/1PROC +=0** NEXT [AR] PHYSICAL WRITE, ; Where to store old PC + CALL [STORE-INT-PC] +.IFNOT/1PROC + NEXT [AR] PHYSICAL WRITE ; Where to store old PC + [BR]_PC WITH FLAGS ; Get old PC + MEM WRITE, ; Store old PC + MEM_[BR] +.ENDIF/1PROC + [AR]_[AR]+1, ; Where to get new PC + VMA PHYSICAL READ, + J/GOEXEC + +.IF/1PROC +STORE-INT-PC: + [BR]_PC WITH FLAGS ; Get old PC + TL [FLG], FLG.1PROC/1 ; Was the instruction being one-proceeded? +=0 [BR]_[BR].OR.#, OIPBIT/1, ;It was, turn pc flag back on + HOLD RIGHT, J/STORE-INT-PC-2 +STORE-INT-PC-1: + MEM WRITE, MEM_[BR], RETURN [4] +STORE-INT-PC-2: + [FLG]_[FLG].AND.NOT.#, FLG.1PROC/1, ;Clear 1-proceed flags + FLG.2PROC/1, HOLD RIGHT, J/STORE-INT-PC-1 +.ENDIF/1PROC +.ENDIF/ITS diff --git a/src/kshack/ks10.47 b/src/kshack/ks10.47 new file mode 100755 index 00000000..2e9e6cf6 --- /dev/null +++ b/src/kshack/ks10.47 @@ -0,0 +1,2210 @@ +;;;-*-Fundamental-*- + + .NOBIN +.TITLE "KS10 MICROCODE FOR ITS" + ;FROM KS10 MICROCODE V117, 12 JANUARY 1979 -- DON LEWINE + +.TOC "MIT REVISION HISTORY" + +;;; 1/16/87 Merge in DEC versions 120-130 inclusive (see comments below) +;;; Change floating-point code to keep its hands off flag bits +;;; other than FLG.SN, so it doesn't interfere with one-proceed. +;;; 8/1/86 262. Try T/4T at XCTGO, see if one-proc in ACs works. +;;; Afraid not, foo. Took T/4T back out. +;;; +++ microcode 261 released +++ +;;; 6/8/86 Still 261. Fix XCTR BLT bug, addresses same, spaces different. +;;; 5/86 261. One-proceed more or less works, fix page age bug. +;;; 5/28/85 Version 261. Started on one-proceed feature. +;;; 5/4/85 Version 260. Added ITS I/O instructions. +;;; 11/24/84 Flushed PCLSRing hack. More trouble than it was worth. +;;; Also moved main program level page fail words back to the +;;; EPT. +;;; 11/21/84 Fixed last bug in PCLSRing hack: The PC stored in the MUUO +;;; old PC location needed to be incremented. +;;; 11/20/84 OK, I gave in and made the PCLSRing hack obtain the new PC +;;; from a new location as well. +;;; 11/19/84 Fixed PCLSRing hack to also store context word. Fixed +;;; RDUBR and WRUBR to deal in addresses rather than in page +;;; numbers. +;;; 11/16/84 Added special PCLSRing hack to page fail trapping. When +;;; page fault occurs in user mode, a duplicate copy of the old +;;; PC is stashed in the MUUO old PC location. +;;; 11/2/84 Fixed quantum counter to count in same units as other +;;; timers. Time spent at PI level is only approximately +;;; accounted for. +;;; 10/25/84 Added quantum counter. Moved main program level page +;;; fail words back to UPT. Moved all page fail words down +;;; to 440 to compact UPT and EPT. +;;; 10/18/84 Fixed interval timer to keep more accurate time on the +;;; average. +;;; 10/17/84 Finishing touches on ITS paging. +;;; 9/29/84 CIRC instruction. Version 259. + +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +;;; ;;; +;;; ;;; +;;; COPYRIGHT (C) 1976, 1977, 1978, 1979, DIGITAL ;;; +;;; EQUIPMENT CORP., MAYNARD, MASS. ;;; +;;; ;;; +;;; THIS SOFTWARE IS FURNISHED UNDER A LICENSE FOR USE ;;; +;;; ONLY ON A SINGLE COMPUTER SYSTEM AND MAY BE COPIED ;;; +;;; ONLY WITH THE INCLUSION OF THE ABOVE COPYRIGHT ;;; +;;; NOTICE. THIS SOFTWARE, OR ANY OTHER COPIES THEREOF, ;;; +;;; MAY NOT BE PROVIDED OR OTHERWISE MADE AVAILABLE TO ;;; +;;; ANY OTHER PERSON EXCEPT FOR USE ON SUCH SYSTEM AND ;;; +;;; TO ONE WHO AGREES TO THESE LICENSE TERMS. TITLE TO ;;; +;;; AND OWNERSHIP OF THE SOFTWARE SHALL AT ALL TIMES ;;; +;;; REMAIN IN DEC. ;;; +;;; ;;; +;;; THE INFORMATION IN THIS DOCUMENT IS SUBJECT TO ;;; +;;; CHANGE WITHOUT NOTICE AND SHOULD NOT BE CONSTRUED AS ;;; +;;; A COMMITMENT BY DIGITAL EQUIPMENT CORPORATION. ;;; +;;; ;;; +;;; DEC ASSUMES NO RESPONSIBILITY FOR THE USE OR ;;; +;;; RELIABILITY OF ITS SOFTWARE IN EQUIPMENT WHICH IS ;;; +;;; NOT SUPPLIED BY DEC. ;;; +;;; ;;; +;;; DESIGNED AND WRITTEN BY: ;;; +;;; DONALD A. LEWINE ;;; +;;; DIGITAL EQUIPMENT CORP. ;;; +;;; MARLBORO, MASS. ;;; +;;; MR1-2/E47 X6430 ;;; +;;; ;;; +;;; MAINTAINED BY: ;;; +;;; DONALD A. LEWINE ;;; +;;; DIGITAL EQUIPMENT CORP. ;;; +;;; MARLBORO, MASS. ;;; +;;; MR1-2/E47 X6430 ;;; +;;; ;;; +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; + + .TOC "DEC REVISION HISTORY" + +;REV WHY +;1 START KS10 MICROCODE BASED ON SM10 MICROCODE VERSION 510 +;2 UPDATE TO KS10 VERSION 512 +;3 FIX SOME DEFAULTS +;4 CHANGE HARDWARE TO MATCH ECO #215 +;5 START TO UPDATE IO MICROCODE +;6 MORE WORK ON IO +;7 MAKE INTERRUPT THE 8080 BE A PULSE. +;10 ADD NEW RDIO AND WRIO +;11 FIX PROBLEMS IN MUUO CODE & CORRECT T-FIELDS +;12 FIX PROBLEMS IN DDIV +;13 FIX UP PROBLEMS IN PI +;14 TURN ON WRITE FOR FL-EXIT +;15 FIX UP MAP INSTRUCTION +;16 MORE WORK ON KI-STYLE MAP +;17 INVERT HOLD RIGHT AND HOLD LEFT BITS +;20 FIXUP WRIO & RDIO EFFECTIVE ADDRESS CALC. +;21 FIX EDIT 15 +;22 HAVE LSH USE FAST SHIFT HARDWARE +;23 FIX T-FIELD VALUES FOR PRODUCTION HARDWARE +;24 REMOVE WRITE TEST FROM IO READS & WRITES +;25 REWRITE MUL & MULI TO BE FASTER AND SMALLER. ALSO MAKE ADJBP +; USE NEW MULSUB +;26 MAKE BYTES USE FAST SHIFT ECO. +;27 MAKE SURE VMA FETCH IS CORRECT +;30 MORE OF 25 (FORGOT FMP) +;31 FIX SOME PROBLEMS WITH TRAPS +;32 SPEED UP EFFECTIVE ADDRESS CALCULATION +;33 MORE OF 32 +;34 SPEED UP ASH & ROT +;35 FIX UP RDTIM SO THAT TIME DOES NOT GO BACKWARDS +;36 MORE OF 35 +;37 FIX UP PROBLEMS WITH INTERRUPTS AND DOUBLE F.P. +;40 IMPROVE LISTING FORMAT +;41 SPEEDUP KL-MODE PAGE REFILL +;42 FIX UP DDIV +;43 STILL MORE DDIV STUFF +;44 CORRECT PROBLEMS IN D.P. PARITY STUFF +;45 CORRECT THE BLT CLEAR-CORE CASE TO INTERRUPT CORRECTLY +;46 MORE OF 45 +;47 DO NOT ALLOW SOFTWARE INTERRUPTS IF THE PI LEVEL IS NOT +; ACTIVE. +;50 MAKE FDV WORK THE SAME AS THE KL10 +;51 FIX INTERRUPT IN CVTBDX. MAKE ABORT WORK LIKE SPEC. +;52 FIX BUG IN HALT LOOP +;53 FIX IOEA TO WORK IF NO @ OR INDEXING +;54 EDIT 47 BROKE JEN +;55 FIX FLAGS IN MULTIPLY. ALSO CODE BUMS +;56 MORE CODE BUMS +;57 CORRECT OVERFLOW TRAPS WHICH DO MUUOS TO NOT STORE +; THE TRAP FLAGS. + +;60 CORRECT TRAPS SO THAT DSKEA RUNS RIGHT +;61 MORE OF 60. NOTE: MICROCODE REQUIRES ECO #299!! +;62 ONE MORE TRY AT EDIT 60. +;63 CORRECT TOPS-10 STYLE PAGING SO THAT A WRITE VIOLATION SETS +; BIT 2 IN THE PAGE FAIL WORD (ACCESS ALLOWED). +;64 EDIT 63 BROKE HARD PAGE FAILS. (NXM, BAD DATA, AND IO NXM) +;65 INTERRUPTS OUT OF MOVSRJ INSTRUCTIONS DO STRANGE THINGS. +;66 IO NXM PAGE FAIL FOR MISSING UBA GIVES PC+1 IN PAGE FAIL BLOCK. +;67 ON A BAD DATA ERROR, STORE THE BAD WORD IN AC BLOCK 7 WORD 0 AND +; 1 +;70 FIX A BUG WHICH CAUSED INTERRUPTS OUT OF CVTBDT TO GENERATE A BAD +; ANSWER. +;71 CLEANUP SOME THINGS TO MAKE LIFE EASIER FOR FIELD SERVICE +;72 LOOK FOR 1-MS TRAP ON @ PAGE POINTERS AND ABORT REFILL IF +; SET. +;73 CORRECT EDIT 72. +;74 EDIT 67 GENERATES A DATA PATH PARITY ERROR BECAUSE OF THE BAD +; DATA. CORRECT TO NOT CHECK PARITY. +; ALSO CHANGE POP TO TIE UP BUS LESS. +;75 EDIT 60 BROKE TRAPS. MISSING =0 AT TRAP:. +;76 CORRECT BUG IN DFAD AND DFSB +;77 FIX PROBLEM SEEN IN SOME (ALL BUT ENGINEERING?) MACHINES CAUSED +; BY EDIT 76 +;100 CHANGE DFAD/DFSB TO HAVE 2 MORE GUARD BITS. THIS SHOULD PRODUCE +; KL10 ANSWERS FOR ALL NORMALIZED INPUTS +; ALSO FIX A BUG IN CVTBDX PAGE FAIL LOGIC. +;101 DFDV OF 0.0 / -0.5 HANGS THE MACHINE +;102 FIX CHOPPED FLOATING POINT INSTRUCTIONS +;103 CORRECT DFDV ROUNDING BUG. +;104 CORRECT PROBLEMS IN DFMP +;105 RDTIME SOMETIMES GIVES WRONG ANSWER. CARRY BETWEEN +; WORDS GETS LOST SOMETIME. +;106 MOVEM (ALSO, SETZM, SETOM, ETC.) SOMETIMES DOES NOT GENERATE +; A WRITE-TRAP IN 100% OF THE CASES THAT IT SHOULD. +;107 PXCT 14, DOES NOT GET THE INDEX REGISTER IN THE PREVIOUS +; CONTEXT ALL THE TIME. +;110 FIX TYPO IN EDIT 103 +;111 63. BIT BYTES DO NOT WORK CORRECTLY. DSKDA FAILS BECAUSE OF THIS +; PROBLEM. +;******* VERSION 111 WENT OUT WITH SYSTEM REV 2 ******* + +;112 FIX COMMENT IN TEST INSTRUCTIONS +;113 CORRECT IOEA TO COMPUTE CORRECT ADDRESS IF JUST LOCAL INDEXING +; IS USED. +;114 CORRECT INTERRUPT BUG IN DMUL +;115 CORRECT COMMENTS HALT STATUS BLOCK +;116 CORRECT PROBLEM WHERE CST MODIFIED BIT GETS SET BY MISTAKE. +;117 RDINT INSTRUCTION DOES NOT WORK AT ALL. IT STORES RANDOM TRASH +; IN THE WRONG PLACE. NEED TO LOAD BR NOT AR. + +;DEC changes after MIT version 261, merged in where relevant + +;120 FLOATING POINT OPERATIONS SOMETIMES GET THE WRONG RESULT WITH +; INPUTS OF UNNORMALIZED ZEROS. THIS SHOULD NEVER HAPPEN WITH +; FORTRAN OR ANY OTHER DEC LANGUAGE. +;121 PREVENT KEEP-ALIVE CRASHES FROM OCCURRING BECAUSE THE MOVSRJ +; INSTRUCTION CAN LOCK OUT THE 1MS TIMER INTERRUPTS FROM BEING +; HANDLED. THIS CAUSES THE OPERATING SYSTEM TO LOSE TRACK OF THE +; PASSAGE OF TIME. +;122 DFAD FOLLOWED BY A FSC OF -5 CAUSES THE FSC TO GET WRONG +; ANSWER. HAD TO CLEAR FLAG WORD AT EXIT OF DFAD TO FIX PROBLEM +;123 MORE CODE FOR EDIT 121. ADDED ANOTHER DISPATCH ADDRESS FOR +; PAGE FAIL CODE AT PFD:. +;124 ADD ASSEMBLY OPTIONS FOR NOCST AND INHIBIT CST UPDATE. (not in MIT ucode) +; ADD BLTUB/BLTBU TO GET UBA STYLE BYTES SWAPPED TO/FROM ILDB FORM. +; ADD ASSEMBLY OPTIONS FOR KI/KL PAGE. NEED THE SPACE FOR BLTUB/BU. (not in MIT ucode) +;125 SUPPORT THE "MAJOR/MINOR VERSION IN 136" UCODE STANDARD. (not in MIT ucode) +; FIX BAD CONSTRAINT FOR INHCST ASSEMBLIES (NOT CURRENTLY USED) (not in MIT ucode) +;126 FIX NON-TRIVIAL CASES OF RDUBR,WRUBR, AND PROCESS CONTEXT WORD. (not in MIT ucode) +;127 JSR IN A TRAP CYCLE STORES E+1 SOMETIMES. TRAP CYCLE WAS NOT BEING +; CLEARED (BY NICOND) BEFORE STARTING THE NEXT MEMORY READ. +;130 FIX UCODE HANG WITH STOPPPED CLOCKS ON WR (KL-PAGING REGISTER) IF (not in MIT ucode) +; PAGING IS ON. IDEALLY, WE WOULD REMOVE WRITE TEST FROM THE DROM +; FIELD, BUT IT'S TOO LATE TO ECO THE ROMS. +; RESTRICTION: WRITE KLPAGE REGISTER LOCATION MUST BE WRITABLE. + .TOC "HOW TO READ THE MICROCODE" + +; +; +; 1.0 FIELD DEFINITIONS +; +; THESE OCCUR AT THE BEGINNING OF THE LISTING, IN THE SOURCE FILE KS10.MIC +; (CONTROL AND DISPATCH RAM DEFINITIONS). THEY HAVE THE FORM: +; +; SYMBOL/=M,J +; +; THE PARAMETER (J) IS MEANINGFUL WHEN "D" IS SPECIFIED AS THE DEFAULT MECHANISM, +; AND IN THAT CASE, GIVES THE DEFAULT VALUE OF THE FIELD IN OCTAL. WHEN "F" IS +; SPECIFIED AS THE DEFAULT MECHANISM, (J) IS THE NAME OF A FIELD WHICH CONTAINS +; THE DEFAULT VALUE FOR THIS FIELD. +; +; THE PARAMETER (L) GIVES THE BIT POSITION OF THE LEFTMOST BIT IN THE FIELD. THE +; SAME METHOD IS USED AS FOR (R) BELOW. +; +; THE PARAMETER (R) GIVES THE FIELD POSITION IN DECIMAL AS THE BIT NUMBER OF THE +; RIGHTMOST BIT OF THE FIELD. BITS ARE NUMBERED FROM 0 ON THE LEFT. NOTE THAT +; THE POSITION OF BITS IN THE MICROWORD SHOWN IN THE LISTING BEARS NO RELATION TO +; THE ORDERING OF BITS IN THE HARDWARE MICROWORD, WHERE FIELDS ARE OFTEN BROKEN UP +; AND SCATTERED. +; +; THE PARAMETER (M) IS OPTIONAL, AND SELECTS A DEFAULT MECHANISM FOR THE FIELD. +; THE LEGAL VALUES OF THIS PARAMETER ARE THE CHARACTERS "D", "F", "T", "P", OR +; "+". +; +; "D" MEANS (J) IS THE DEFAULT VALUE OF THE FIELD IF NO EXPLICIT VALUE IS +; SPECIFIED. +; +; "F" IS USED TO CAUSE THIS FIELD TO DEFAULT TO SOME OTHER FIELD. +; +; "T" IS USED ON THE TIME FIELD TO SPECIFY THAT THE VALUE OF THE FIELD +; DEPENDS ON THE TIME PARAMETERS SELECTED FOR OTHER FIELDS. "T" IS NOT +; USED IN THE KS10. +; +; "P" IS USED ON THE PARITY FIELD TO SPECIFY THAT THE VALUE OF THE FIELD +; SHOULD DEFAULT SUCH THAT PARITY OF THE ENTIRE WORD IS ODD. "P" IS NOT +; USED ON THE KS10. +; +; "+" IS USED ON THE JUMP ADDRESS FIELD TO SPECIFY THAT THE DEFAULT JUMP +; ADDRESS IS THE ADDRESS OF THE NEXT INSTRUCTION ASSEMBLED (NOT, IN +; GENERAL, THE CURRENT LOCATION +1). +; +; IN GENERAL, A FIELD CORRESPONDS TO THE SET OF BITS WHICH PROVIDE SELECT INPUTS +; FOR MIXERS OR DECODERS, OR CONTROLS FOR ALU'S. +; +; + +; 2.0 VALUE DEFINITIONS +; +; FOLLOWING A FIELD DEFINITION, SYMBOLS MAY BE CREATED IN THAT FIELD TO CORRESPOND +; TO VALUES OF THE FIELD. THE FORM IS: +; +; SYMBOL=N +; +; "N" IS, IN OCTAL, THE VALUE OF SYMBOL WHEN USED IN THE FIELD. +; +; +; +; 3.0 LABEL DEFINITIONS +; +; A MICRO INSTRUCTION MAY BE LABELLED BY A SYMBOL FOLLOWED BY COLON PRECEDING THE +; MICROINSTRUCTION DEFINITION. THE ADDRESS OF THE MICROINSTRUCTION BECOMES THE +; VALUE OF THE SYMBOL IN THE FIELD NAMED "J". EXAMPLE: +; +; FOO: J/FOO +; +; THIS IS A MICROINSTRUCTION WHOSE "J" FIELD (JUMP ADDRESS) CONTAINS THE VALUE +; "FOO". IT ALSO DEFINES THE SYMBOL "FOO" TO BE THE ADDRESS OF ITSELF. +; THEREFORE, IF EXECUTED BY THE MICROPROCESSOR, IT WOULD LOOP ON ITSELF. +; +; +; +; 4.0 COMMENTS +; +; A SEMICOLON ANYWHERE ON A LINE CAUSES THE REST OF THE LINE TO BE IGNORED BY THE +; ASSEMBLER. THIS TEXT IS AN EXAMPLE OF COMMENTS. +; +; +; +; 5.0 MICROINSTRUCTION DEFINITION +; +; A WORD OF MICROCODE IS DEFINED BY SPECIFYING A FIELD NAME, FOLLOWED BY SLASH +; (/), FOLLOWED BY A VALUE. THE VALUE MAY BE A SYMBOL DEFINED FOR THAT FIELD, AN +; OCTAL DIGIT STRING, OR A DECIMAL DIGIT STRING (DISTINGUISHED BY THE FACT THAT IT +; CONTAINS "8" AND/OR "9" AND/OR IS TERMINATED BY A PERIOD). SEVERAL FIELDS MAY +; BE SPECIFIED IN ONE MICROINSTRUCTION BY SEPARATING FIELD/VALUE SPECIFICATIONS +; WITH COMMAS. EXAMPLE: +; +; AD/ZERO,RAMADR/AC*#,ACALU/AC+N,ACN/1,DBUS/DP +; +; +; 6.0 CONTINUATION +; +; THE DEFINITION OF A MICROINSTRUCTION MAY CONTINUED ONTO TWO OR MORE LINES BY +; BREAKING IT AFTER ANY COMMA. IN OTHER WORDS, IF THE LAST NON-BLANK, NON-COMMENT +; CHARACTER ON A LINE IS A COMMA, THE INSTRUCTION SPECIFICATION IS CONTINUED ON + +; THE FOLLOWING LINE. EXAMPLE: +; READ [AR], ;LOOK AT EFFECTIVE ADDRESS +; SKIP DP18, ;SEE IF RIGHT OR LEFT SHIFT +; SC_SHIFT-1, ;PUT NUMBER OF PLACE TO +; ;SHIFT IN SC +; LOAD FE, ; AND IN FE +; INST DISP ;GO DO THE SHIFT +; +; +; +; 7.0 MACROS +; +; A MACRO IS A SYMBOL WHOSE VALUE IS ONE OR MORE FIELD/VALUE SPECIFICATIONS AND/OR +; MACROS. A MACRO DEFINITION IS A LINE CONTAINING THE MACRO NAME FOLLOWED BY A +; QUOTED STRING WHICH IS THE VALUE OF THE MACRO. EXAMPLE: +; +; LOAD VMA "MEM/1, LDVMA/1 +; +; THE APPEARANCE OF A MACRO IN A MICROINSTRUCTION DEFINITION IS EQUIVALENT TO THE +; APPEARANCE OF ITS VALUE. +; +; MACRO MAY HAVE PARAMETERS ENCLOSED IN []. FOR EXAMPLE, +; +; []_[] "AD/A,A/@2,DEST/AD,B/@1" +; +; THE @1 GETS REPLACED BY WHAT IS WRITTEN IN THE FIRST SET OF [] AND @2 IS +; REPLACED BY WHAT IS WRITTEN IN THE SECOND SET OF []. THUS +; +; [AR]_[ARX] +; +; HAS THE SAME EFFECT AS SAYING +; +; AD/A,A/ARX,DEST/AD,B/AR +; +; +; SEE DESCRIPTION OF RULES FOR MACRO NAMES. +; +; 8.0 PSEUDO OPS +; +; THE MICRO ASSEMBLER HAS 13 PSEUDO-OPERATORS: +; +; .DCODE AND .UCODE SELECT THE RAM INTO WHICH SUBSEQUENT MICROCODE WILL BE +; LOADED, AND THEREFORE THE FIELD DEFINITIONS AND MACROS WHICH ARE +; MEANINGFUL IN SUBSEQUENT MICROCODE +; .TITLE DEFINES A STRING OF TEXT TO APPEAR IN THE PAGE HEADER, AND +; .TOC DEFINES AN ENTRY FOR THE TABLE OF CONTENTS AT THE BEGINNING. +; .SET DEFINES THE VALUE OF A CONDITIONAL ASSEMBLY PARAMETER, +; .CHANGE REDEFINES A CONDITIONAL ASSEMBLY PARAMETER, +; .DEFAULT ASSIGNS A VALUE TO AN UNDEFINED PARAMETER. +; .IF ENABLES ASSEMBLY IF THE VALUE OF THE PARAMETER IS NOT ZERO, +; .IFNOT ENABLES ASSEMBLY IF THE PARAMETER VALUE IS ZERO, AND +; .ENDIF RE-ENABLES ASSEMBLY IF SUPPRESSED BY THE PARAMETER NAMED. +; .NOBIN TURNS OFF THE BINARY A GETS RID OF THE SPACE USED TO LIST IT, +; .BIN TURN BINARY BACK ON AGAIN. +; .WIDTH CONTROLS THE NUMBER OF BITS IN THE CRAM + +; 9.0 LOCATION CONTROL +; +; A MICROINSTRUCTION "LABELLED" WITH A NUMBER IS ASSIGNED TO THAT ADDRESS. +; +; THE CHARACTER "=" AT THE BEGINNING OF A LINE, FOLLOWED BY A STRING OF 0'S, 1'S, +; AND/OR *'S, SPECIFIES A CONSTRAINT ON THE ADDRESS OF FOLLOWING +; MICROINSTRUCTIONS. THE NUMBER OF CHARACTERS IN THE CONSTRAINT STRING (EXCLUDING +; THE "=") IS THE NUMBER OF LOW-ORDER BITS CONSTRAINED IN THE ADDRESS. THE +; MICROASSEMBLER ATTEMPTS TO FIND AN UNUSED LOCATION WHOSE ADDRESS HAS 0 BITS IN +; THE POSITIONS CORRESPONDING TO 0'S IN THE CONSTRAINT STRING AND 1 BITS WHERE THE +; CONSTRAINT HAS 1'S. ASTERISKS DENOTE "DON'T CARE" BIT POSITIONS. +; +; IF THERE ARE ANY 0'S IN THE CONSTRAINT STRING, THE CONSTRAINT IMPLIES A BLOCK OF +; <2**N> MICROWORDS, WHERE N IS THE NUMBER OF 0'S IN THE STRING. ALL LOCATIONS IN +; THE BLOCK WILL HAVE 1'S IN THE ADDRESS BITS CORRESPONDING TO 1'S IN THE STRING, +; AND BIT POSITIONS DENOTED BY *'S WILL BE THE SAME IN ALL LOCATIONS OF THE BLOCK. +; +; IN SUCH A CONSTRAINT BLOCK, THE DEFAULT ADDRESS PROGRESSION IS COUNTING IN THE +; "0" POSITIONS OF THE CONSTRAINT STRING, BUT A NEW CONSTRAINT STRING OCCURING +; WITHIN A BLOCK MAY FORCE SKIPPING OVER SOME LOCATIONS OF THE BLOCK. WITHIN A +; BLOCK, A NEW CONSTRAINT STRING DOES NOT CHANGE THE PATTERN OF DEFAULT ADDRESS +; PROGRESSION, IT MERELY ADVANCES THE LOCATION COUNTER OVER THOSE LOCATIONS. THE +; MICROASSEMBLER WILL LATER FILL THEM IN. +; +; A NULL CONSTRAINT STRING ("=" FOLLOWED BY ANYTHING BUT "0", "1", OR "*") SERVES +; TO TERMINATE A CONSTRAINT BLOCK. EXAMPLES: +; +; =0 +; +; THIS SPECIFIES THAT THE LOW-ORDER ADDRESS BIT MUST BE ZERO-- THE MICROASSEMBLER +; FINDS AN EVEN-ODD PAIR OF LOCATIONS, AND PUTS THE NEXT TWO MICROINSTRUCTIONS +; INTO THEM. +; +; =11 +; THIS SPECIFIES THAT THE TWO LOW-ORDER BITS OF THE ADDRESS MUST BOTH BE ONES. +; SINCE THERE ARE NO 0'S IN THIS CONSTRAINT, THE ASSEMBLER FINDS ONLY ONE LOCATION +; MEETING THE CONSTRAINT. +; +; =0***** +; +; THIS SPECIFIES AN ADDRESS IN WHICH THE "40" BIT IS ZERO. DUE TO THE +; IMPLEMENTATION OF THIS FEATURE IN THE ASSEMBLER, THE DEFAULT ADDRESS PROGRESSION +; APPLIES ONLY TO THE LOW-ORDER 5 BITS, SO THIS CONSTRAINT FINDS ONE WORD IN WHICH +; THE "40" BIT IS ZERO, AND DOES NOT ATTEMPT TO FIND ONE IN WHICH THAT BIT IS A +; ONE. THIS LIMITATION HAS BEEN CHANGED WITH NEWER ASSEMBLER VERSIONS. HOWEVER +; NONE OF THE LOCATIONS IN THE MICROCODE REQUIRE ANYTHING BUT THE CONSTRAINT +; MENTIONED ABOVE. + + .TOC "CONDITIONAL ASSEMBLY DEFINITIONS" + +.DEFAULT/SIM=0 ;0=RUN ON REAL HARDWARE + ;1=RUN UNDER SIMULATOR + +.DEFAULT/FULL=1 ;0=INCLUDE ONLY BASIC INSTRUCTIONS + ;1=INCLUDE FULL INSTRUCTION SET + +.DEFAULT/CIRC=0 ;1=Assemble the CIRC instruction. + +.DEFAULT/ITS=0 ;0=DEC style microcode. + ;1=ITS style microcode. + +.DEFAULT/JPC=0 ;1=Assemble JPC feature. + +.DEFAULT/1PROC=0 ;1=Assemble one-proceed feature. + +.DEFAULT/PCST=0 ;1=Assemble PC sampling feature. + +.DEFAULT/ITSIO=0 ;1=Assemble ITS I/O instructions. + +.DEFAULT/TEST=0 ;1=Assemble some temporary experimental feature. + +.WIDTH/108 ;ONLY FIELDS BETWEEN BITS 0 AND 107 EVER + ; GET LOADED INTO THE CRAM. OTHER FIELDS + ; ARE USED FOR DEFAULTING PROCESS. + +;THIS IS USELESS AND BRAIN DAMAGED +;STUFF IS KEPT OUT OF DROM SPACE BY MORE GENERAL MECHANISMS +;.REGION/0,1377/2000,3777/1400,1777 +; ;TRY AND KEEP STUFF OUT OF DROM SPACE + +;WRITE A RAM FILE WITH THE FIELDS REARRANGED SO THE 8080 CAN HACK THEM +;The RAM file format appears to be: +; +;4000 sequential CRAM locations starting at 0. +;Each location is 96 bits expressed as 8 12-bit bytes and one +;padding byte packed into three words. Bytes are in right to +;left order within 36-bit words, and also within the 96-bit +;words. Thus RAM SRC through MARK are in the right 12 bits of +;the first 36-bit word and J is in the middle 12 bits of the +;third 36-bit word. Parity is even parity, computed separately +;for the two halves of the word packaged on different boards. +; +;.RAMFILE takes the fields in left-to-right (pdp10) order, +;thus the 8080's eight 12-bit bytes are given in order 2,1,0,5,4,3,pad,7,6 +;One parity bit is for 0-4, the other is for 5-7. + +.RAMFILE/ AD,RSRC,DBM,DBUS,A,CLKL,CLKR,B, ;WORDS 2-1 + RAMADR,DEST,LOADSC,LOADFE,CHKL,CHKR, + ODD PARITY<0:35,48:71>,0, ;WORD 0 + ODD PARITY<36:47,84:107>,CRY38,MEM, + DISP LOW,SPEC LOW,SKIP LOW, ;WORD 5 + # LOW, ;WORD 4 + FMWRITE,MULTI SHIFT,GENL,GENR,DIVIDE,MULTI PREC,# HIGH, ;WORD 3 + 12/0, ;PAD + J, ;WORD 7 + T,CALL,SKIP HIGH,SPEC HIGH,DISP HIGH ;WORD 6 + .TOC "2901 REGISTER USAGE" + +; !=========================================================================! +;0: ! MAG (ONES IN BITS 1-36, REST ZERO) ! +; !-------------------------------------------------------------------------! +;1: ! PC (ADDRESS OF CURRENT INSTRUCTION + 1) ! +; !-------------------------------------------------------------------------! +;2: ! HR (CURRENT INSTRUCTION) ! +; !-------------------------------------------------------------------------! +;3: ! AR (TEMP -- MEM OP AT INST START) ! +; !-------------------------------------------------------------------------! +;4: ! ARX (TEMP -- LOW ORDER HALF OF DOUBLE PREC) ! +; !-------------------------------------------------------------------------! +;5: ! BR (TEMP) ! +; !-------------------------------------------------------------------------! +;6: ! BRX (TEMP -- LOW ORDER HALF OF DOUBLE PREC BR!BRX) ! +; !-------------------------------------------------------------------------! +;7: ! ONE (THE CONSTANT 1) ! +; !-------------------------------------------------------------------------! +;10: ! EBR (EXEC BASE REGISTER) ! +; !-------------------------------------------------------------------------! +;11: ! UBR (USER BASE REGISTER) ! +; !-------------------------------------------------------------------------! +;12: ! MASK (ONES IN BITS 0-35, ZERO IN -1, -2, 36 AND 37) ! +; !-------------------------------------------------------------------------! +;13: ! FLG (FLAG BITS) ! PAGE FAIL CODE ! +; !-------------------------------------------------------------------------! +;14: ! PI (PI SYSTEM STATUS REGISTER [RDPI]) ! +; !-------------------------------------------------------------------------! +;15: ! XWD1 (1 IN EACH HALF WORD) ! +; !-------------------------------------------------------------------------! +;16: ! T0 (TEMP) ! +; !-------------------------------------------------------------------------! +;17: ! T1 (TEMP) ! +; !=========================================================================! + + .TOC "MICROCODE FIELDS -- LISTING FORMAT" + +; ; 3633 1561: +; ; 3634 SUB: [AR]_AC-[AR], +; ; 3635 AD FLAGS, 3T, +; U 1561, 1500,2551,0303,0274,4463,7701,4200,0001,0001 ; 3636 EXIT +; [--] [--] !!!! [][] !!![-][][-][]! !!! [----] +; ! ! !!!! ! ! !!!! ! ! ! ! !!! ! +; ! ! !!!! ! ! !!!! ! ! ! ! !!! +---- # (MAGIC NUMBER) +; ! ! !!!! ! ! !!!! ! ! ! ! !!! +; ! ! !!!! ! ! !!!! ! ! ! ! !!+------------- MULTI PREC, MULTI SHIFT, CALL +; ! ! !!!! ! ! !!!! ! ! ! ! !! (4S, 2S, 1S) +; ! ! !!!! ! ! !!!! ! ! ! ! !+-------------- FM WRITE, MEM, DIVIDE +; ! ! !!!! ! ! !!!! ! ! ! ! ! (4S, 2S, 1S) +; ! ! !!!! ! ! !!!! ! ! ! ! +--------------- CRY38, LOAD SC, LOAD FE +; ! ! !!!! ! ! !!!! ! ! ! ! (4S, 2S, 1S) +; ! ! !!!! ! ! !!!! ! ! ! +----------------- T +; ! ! !!!! ! ! !!!! ! ! ! +; ! ! !!!! ! ! !!!! ! ! +------------------- SKIP +; ! ! !!!! ! ! !!!! ! ! +; ! ! !!!! ! ! !!!! ! +---------------------- DISP +; ! ! !!!! ! ! !!!! ! +; ! ! !!!! ! ! !!!! +------------------------ SPEC +; ! ! !!!! ! ! !!!! +; ! ! !!!! ! ! !!!+--------------------------- CLOCKS & PARITY +; ! ! !!!! ! ! !!! (CLKR, GENR, CHKR, CLKL, GENL, CHKL) +; ! ! !!!! ! ! !!+---------------------------- DBM +; ! ! !!!! ! ! !! +; ! ! !!!! ! ! !+----------------------------- DBUS +; ! ! !!!! ! ! ! +; ! ! !!!! ! ! +------------------------------ RAM ADDRESS +; ! ! !!!! ! ! +; ! ! !!!! ! +--------------------------------- B +; ! ! !!!! ! +; ! ! !!!! +----------------------------------- A +; ! ! !!!! +; ! ! !!!+------------------------------------- DEST +; ! ! !!! +; ! ! !!+-------------------------------------- RSRC +; ! ! !! +; ! ! !+--------------------------------------- LSRC ] +; ! ! ! ] - AD +; ! ! +---------------------------------------- ALU ] +; ! ! +; ! +--------------------------------------------- J +; ! +; LOCATION OF THIS MICRO WORD + + .TOC "MICROCODE FIELDS -- DATAPATH CHIP" + +J/=<0:11>+ ;CRA1 + ;NEXT MICROCODE ADDRESS + +;ALU FUNCTIONS + +;NOTE: THE AD FIELD IS A 2 DIGIT FIELD. THE LEFT DIGIT IS THE +; 2901 ALU FUNCTION. THE RIGHT DIGIT IS THE 2901 SRC CODE FOR +; THE LEFT HALF. NORMALY THE RIGHT HALF SRC CODE IS THE SAME AS +; THE LEFT HALF. +AD/=<12:17>D,44 ;DPE1 & DPE2 + A+Q=00 + A+B=01 + 0+Q=02 + 0+B=03 + 0+A=04 + D+A=05 + D+Q=06 + 0+D=07 + Q-A-.25=10 + B-A-.25=11 + Q-.25=12 + B-.25=13 + A-.25=14 + A-D-.25=15 + Q-D-.25=16 + -D-.25=17 + A-Q-.25=20 + A-B-.25=21 + -Q-.25=22 + -B-.25=23 + -A-.25=24 + D-A-.25=25 + D-Q-.25=26 + D-.25=27 + A.OR.Q=30 + A.OR.B=31 + Q=32 + B=33 + A=34 + D.OR.A=35 + D.OR.Q=36 + D=37 + A.AND.Q=40 + A.AND.B=41 + +;MORE ALU FUNCTIONS + + ZERO=42 +; ZERO=43 +; ZERO=44 + D.AND.A=45 + D.AND.Q=46 +; ZERO=47 + .NOT.A.AND.Q=50 + .NOT.A.AND.B=51 +; Q=52 +; B=53 +; A=54 + .NOT.D.AND.A=55 + .NOT.D.AND.Q=56 +; ZERO=57 + A.XOR.Q=60 + A.XOR.B=61 +; Q=62 +; B=63 +; A=64 + D.XOR.A=65 + D.XOR.Q=66 +; D=67 + A.EQV.Q=70 + A.EQV.B=71 + .NOT.Q=72 + .NOT.B=73 + .NOT.A=74 + D.EQV.A=75 + D.EQV.Q=76 + .NOT.D=77 + +;THIS FIELD IS THE RIGHTMOST 3 BITS OF THE +; AD FIELD. IT IS USED ONLY TO DEFAULT THE RSRC +; FIELD. +LSRC/=<15:17> ;DPE1 + +;THIS IS THE SOURCE FOR THE RIGHT HALF OF THE +; DATA PATH. IT LETS US MAKE THE RIGHT AND LEFT +; HALF WORDS DO SLIGHTLY DIFFERENT THINGS. +RSRC/=<18:20>F,LSRC ;DPE2 + AQ=0 ;A Q + AB=1 ;A B + 0Q=2 ;0 Q + 0B=3 ;0 B + 0A=4 ;0 A + DA=5 ;D A + DQ=6 ;D Q + D0=7 ;D 0 + +;DESTINATION CONTROL +;SEE DPE1 AND DPE2 (2'S WEIGHT IS INVERTED ON DPE5) +DEST/=<21:23>D,3 ;DPE1 & DPE2 + A=0 ;A REG IS CHIP OUTPUT, AD IS WRITTEN + ; INTO REG FILE + AD=1 ;REG FILE GETS AD + Q_AD=2 ;REG FILE IS NOT LOADED + PASS=3 ;AD OUTPUT IS CHIP OUTPUT + ; Q AND REG FILE LEFT ALONE + Q_Q*2=4 ;ALSO REG FILE GETS AD*2 + AD*2=5 ;AND Q IS LEFT ALONE + Q_Q*.5=6 ;ALSO REG FILE GETS AD*.5 + AD*.5=7 ;AND Q IS LEFT ALONE + +; <24:25> ;UNUSED + +A/=<26:29> ;DPE1 & DPE2 + MAG=0 + PC=1 + HR=2 + AR=3 + ARX=4 + BR=5 + BRX=6 + ONE=7 + EBR=10 + UBR=11 + MASK=12 + FLG=13 + PI=14 + XWD1=15 + T0=16 + T1=17 + +; <30:31> ;UNUSED + +B/=<32:35>D,0 ;DPE1 & DPE2 + MAG=0 + PC=1 + HR=2 + AR=3 + ARX=4 + BR=5 + BRX=6 + ONE=7 + EBR=10 + UBR=11 + MASK=12 + FLG=13 + PI=14 + XWD1=15 + T0=16 + T1=17 + + .TOC "MICROCODE FIELDS -- RAM FILE ADDRESS AND D-BUS" + +RAMADR/=<36:38>D,4 ;DPE6 + AC#=0 ;AC NUMBER + AC*#=1 ;AC .FN. # + XR#=2 ;INDEX REGISTER + VMA=4 ;VIRTUAL MEMORY REFERENCE + RAM=6 ;VMA SUPPLIES 10-BIT RAM ADDRESS + #=7 ;ABSOLUTE RAM FILE REFERENCE + +; <39:39> + +;LEFT HALF ON DPE3 AND RIGHT HALF ON DPE4 +DBUS/=<40:41>D,1 ;DPE3 & DPE4 + PC FLAGS=0 ;PC FLAGS IN LEFT HALF + PI NEW=0 ;NEW PI LEVEL IN BITS 19-21 +; VMA=0 ;VMA IN BITS 27-35 + DP=1 ;DATA PATH + RAM=2 ;CACHE, AC'S AND WORKSPACE + DBM=3 ;DBM MIXER + +;LEFT HALF ON DPM1 AND RIGHT HALF ON DPM2 +DBM/=<42:44>D,7 ;DPM1 & DPM2 + SCAD DIAG=0 ;(LH) SCAD DIAGNOSTIC + PF DISP=0 ;PAGE FAIL DISP IN BITS 18-21 + APR FLAGS=0 ;APR FLAGS IN BITS 22-35 + BYTES=1 ;5 COPIES OF SCAD 1-7 + EXP=2 ;LH=EXPONENT, RH=TIME FRACTION + DP=3 ;DATA PATH + DP SWAP=4 ;DATA PATH SWAPPED + VMA=5 ;VMA FLAGS,,VMA + MEM=6 ;MEMORY BUFFER + #=7 ;NUMBER FIELD IN BOTH HALVES + + .TOC "MICROCODE FIELDS -- PARITY GENERATION & HALF WORD CONTROL" + +AD PARITY OK/=<108>D,0 ;**NOT STORED IN CRAM** + ;THIS BIT IS A 1 IF THE ALU IS DOING + ; SOMETHING WHICH DOES NOT INVALIDATE + ; PARITY. IT DOES NOT APPEAR IN THE + ; REAL MACHINE. WE JUST USE IT TO SET + ; THE DEFAULT FOR GENR & GENL + +CLKL/=<45:45>D,1 ;DPE5 + ;CLOCK THE LEFT HALF OF THE MACHINE +GENL/=<46:46>F,AD PARITY OK ;DPE4 FROM CRM2 PARITY EN LEFT H + ;STORE PARITY FOR 2901 LEFT +CHKL/=<47:47> ;DPE4 FROM CRM2 PARITY CHK LEFT H + ;CHECK LEFT HALF DBUS PARITY + +CLKR/=<48:48>D,1 ;DPE5 + ;CLOCK THE RIGHT HALF OF THE MACHINE +GENR/=<49:49>F,AD PARITY OK ;DPE4 FROM CRM2 PARITY EN RIGHT H + ;STORE PARITY FOR 2901 RIGHT +CHKR/=<50:50> ;DPE4 FROM CRM2 PARITY CHK RIGHT H + ;CHECK RIGHT HALF DBUS PARITY + + .TOC "MICROCODE FIELDS -- SPEC" + + +; +;THE FOLLOWING SPECIAL FUNCTION ARE DECODED ON DPE1, DPE5, AND DPMA: +; !=========================================================================! +; !S! EFFECT ! CRA6 SPEC ! CRA6 SPEC ! CRA6 SPEC ! +; !P! ON SHIFT ! EN 40 ! EN 20 ! EN 10 ! +; !E! PATHS ! E102 ON DPE5 ! E101 ON DPE5 ! E410 ON DPMA ! +; !C! (SEE DPE1) ! ! E411 ON DPMA ! E113 ON CRA2 ! +; !=========================================================================! +; !0! NORMAL ! CRY 18 INH ! PREVIOUS ! # ! +; !-------------------------------------------------------------------------! +; !1! ZERO ! IR LOAD ! XR LOAD ! CLR 1 MSEC ! +; !-------------------------------------------------------------------------! +; !2! ONES ! ! ! CLR IO LATCH ! +; !-------------------------------------------------------------------------! +; !3! ROT ! PI LOAD ! APR FLAGS ! CLR IO BUSY ! +; !-------------------------------------------------------------------------! +; !4! ASHC ! ASH TEST ! SET SWEEP ! PAGE WRITE ! +; !-------------------------------------------------------------------------! +; !5! LSHC ! EXP TEST ! APR EN ! NICOND ! +; !-------------------------------------------------------------------------! +; !6! DIV ! PC FLAGS ! PXCT OFF ! PXCT EN ! +; !-------------------------------------------------------------------------! +; !7! ROTC ! AC BLOCKS EN ! MEM CLR ! MEM WAIT ! +; !=========================================================================! +; THE DPM BOARD USES THE SPEC FIELD TO CONTROL THE +; DBM MIXER, AS FOLLOWS: +; +; !=====================================! +; ! S ! ! +; ! P ! ACTION WHEN DBM ! +; ! E ! SELECTS DP ! +; ! C ! GET DP BITS ! GET SCAD 1-7 ! +; !=====================================! +; ! 0 ! ALL ! NONE ! +; !-------------------------------------! +; ! 1 ! 7-35 ! 0-6 ! +; !-------------------------------------! +; ! 2 !0-6 AND 14-35 ! 7-13 ! +; !-------------------------------------! +; ! 3 !0-13 AND 21-35! 14-20 ! +; !-------------------------------------! +; ! 4 !0-20 AND 28-35! 21-27 ! +; !-------------------------------------! +; ! 5 ! 0-27 AND 35 ! 28-34 ! +; !-------------------------------------! +; ! 6 ! SAME AS ZERO ! +; !-------------------------------------! +; ! 7 ! SAME AS ZERO ! +; !=====================================! + +;THE SPEC FIELD IS DEFINED AS A 6-BIT FIELD. THE TOP 3 BITS +; ARE SPEC SEL A, SPEC SEL B, AND SPEC SEL C. THE LOW 3 BITS ARE +; THE SELECT CODE. + +SPEC/=<51:56>D,0 ;DPE1 & DPE5 & DPM1 & DPMA + #=10 ;DECODE # BITS + CLRCLK=11 ;CLEAR 1MS NICOND FLAG + CLR IO LATCH=12 ;CLEAR IO LATCH + CLR IO BUSY=13 ;CLEAR IO BUSY + LDPAGE=14 ;WRITE PAGE TABLE + NICOND=15 ;DOING NICOND DISPATCH + LDPXCT=16 ;LOAD PXCT FLAGS + WAIT=17 ;MEM WAIT + PREV=20 ;FORCE PREVIOUS CONTEXT + LOADXR=21 ;LOAD XR #, USES PXCT FIELD TO SELECT + ; CORRECT AC BLOCK + APR FLAGS=23 ;LOAD APR FLAGS + CLRCSH=24 ;CLEAR CACHE + APR EN=25 ;SET APR ENABLES + MEMCLR=27 ;CLEAR PAGE FAULT CONDITION + SWEEP=34 ;SET SWEEP + PXCT OFF=36 ;TURN OFF THE EFFECT OF PXCT + INHCRY18=40 ;INHIBIT CARRY INTO LEFT HALF + LOADIR=41 ;LOAD THE IR + LDPI=43 ;LOAD PI SYSTEM + ASHOV=44 ;TEST RESULT OF ASH + EXPTST=45 ;TEST RESULT OF FLOATING POINT + FLAGS=46 ;CHANGE PC FLAGS + LDACBLK=47 ;LOAD AC BLOCK NUMBERS + LDINST=61 ;LOAD INSTRUCTION + +;THE SPEC FIELD IS REDEFINED WHEN USED FOR BYTE MODE STUFF +BYTE/=<54:56> ;DPM1 (SPEC SEL) + BYTE1=1 + BYTE2=2 + BYTE3=3 + BYTE4=4 + BYTE5=5 + +;THE SPEC FIELD IS REDEFINED WHEN USED TO CONTROL SHIFT PATHS +SHSTYLE/=<54:56> ;DPE1 (SPEC SEL) + NORM=0 ;2 40-BIT REGISTERS + ZERO=1 ;SHIFT ZERO INTO 36 BITS (ASH TOP 2901) + ONES=2 ;SHIFT IN ONES + ROT=3 ;ROTATE + ASHC=4 ;ASHC + LSHC=5 ;LSHC + DIV=6 ;SPECIAL DIVIDE + ROTC=7 ;ROTATE DOUBLE + + .TOC "MICROCODE FIELDS -- DISPATCH" +; !=======================================================! +; ! D ! CRA1 ! CRA1 ! DPEA ! +; ! I ! DISP ! DISP ! DISP ! +; ! S ! 10 ! 20 ! 40 ! +; ! P ! ! ! ! +; !=======================================================! +; ! 0 ! DIAG ADR ! DIAG ADR ! 0 ! +; !-------------------------------------------------------! +; ! 1 ! RETURN ! RETURN ! DP 18-21 ! +; !-------------------------------------------------------! +; ! 2 ! MULTIPLY ! J ! J ! +; !-------------------------------------------------------! +; ! 3 ! PAGE FAIL ! AREAD ! AREAD ! +; !-------------------------------------------------------! +; ! 4 ! NICOND ! NOT USABLE ! NORM ! +; !-------------------------------------------------------! +; ! 5 ! BYTE ! NOT USABLE ! DP 32-35 ! +; !-------------------------------------------------------! +; ! 6 ! EA MODE ! NOT USABLE ! DROM A ! +; !-------------------------------------------------------! +; ! 7 ! SCAD ! NOT USABLE ! DROM B ! +; !=======================================================! +;NOTE: DISP EN 40 & DISP EN 10 ONLY CONTROL THE LOW 4 BITS OF THE +; JUMP ADDRESS. DISP EN 20 ONLY CONTROLS THE HI 7 BITS. TO DO +; SOMETHING TO ALL 11 BITS BOTH 20 & 40 OR 20 & 10 MUST BE ENABLED. + +DISP/=<57:62>D,70 ;CRA1 & DPEA + CONSOLE=00 ;CONSOLE DISPATCH + DROM=12 ;DROM + AREAD=13 ;AREAD + DP LEFT=31 ;DP 18-21 + NORM=34 ;NORMALIZE + DP=35 ;DP 32-35 + ADISP=36 ;DROM A FIELD + BDISP=37 ;DROM B FIELD + RETURN=41 ;RETURN + MUL=62 ;MULTIPLY + PAGE FAIL=63 ;PAGE FAIL + NICOND=64 ;NEXT INSTRUCTION DISPATCH + BYTE=65 ;BYTE SIZE AND POSITION + EAMODE=66 ;EFFECTIVE ADDRESS MODE + SCAD0=67 ;J!2 IF SCAD BIT 0 = 1 + + .TOC "MICROCODE FIELDS -- SKIP" +; !=======================================================! +; ! S ! CRA2 ! DPEA ! DPEA ! +; ! K ! SKIP ! SKIP ! SKIP ! +; ! I ! 10 ! 20 ! 40 ! +; ! P ! ! ! ! +; !=======================================================! +; ! 0 ! 0 ! 0 ! 0 ! +; !-------------------------------------------------------! +; ! 1 ! TRAP CYCLE ! CRY 02 ! CARRY OUT ! +; !-------------------------------------------------------! +; ! 2 ! AD=0 ! ADL SIGN ! ADL=0 ! +; !-------------------------------------------------------! +; ! 3 ! SC SIGN ! ADR SIGN ! ADR=0 ! +; !-------------------------------------------------------! +; ! 4 ! EXECUTE ! USER IOT ! -USER ! +; !-------------------------------------------------------! +; ! 5 ! -BUS IO BUSY ! JFCL SKIP ! FPD FLAG ! +; !-------------------------------------------------------! +; ! 6 ! -CONTINUE ! CRY 01 ! AC # IS ZERO ! +; !-------------------------------------------------------! +; ! 7 ! -1 MSEC ! TXXX ! INTERRUPT REQ ! +; !=======================================================! + +SKIP/=<63:68>D,70 ;CRA2 & DPEA + IOLGL=04 ;(.NOT.USER)!(USER IOT)!(CONSOLE EXECUTE MODE) + LLE=12 ;AD LEFT .LE. 0 + CRY0=31 ;AD CRY -2 + ADLEQ0=32 ;ADDER LEFT = 0 + ADREQ0=33 ;ADDER RIGHT = 0 + KERNEL=34 ;.NOT. USER + FPD=35 ;FIRST PART DONE + AC0=36 ;AC NUMBER IS ZERO + INT=37 ;INTERRUPT REQUEST + LE=42 ;(AD SIGN)!(AD.EQ.0) + CRY2=51 ;AD CRY 02 + DP0=52 ;AD SIGN + DP18=53 ;AD BIT 18 + IOT=54 ;USER IOT + JFCL=55 ;JFCL SKIP + CRY1=56 ;AD CRY 1 + TXXX=57 ;TEST INSTRUCTION SHOULD SKIP + TRAP CYCLE=61 ;THIS INSTRUCTION IS THE RESULT OF A + ; TRAP 1, 2, OR 3 + ADEQ0=62 ;AD.EQ.0 + SC=63 ;SC SIGN BIT + EXECUTE=64 ;CONSOLE EXECUTE MODE + -IO BUSY=65 ;.NOT. I/O LATCH + -CONTINUE=66 ;.NOT. CONTINUE + -1 MS=67 ;.NOT. 1 MS. TIMER + + .TOC "MICROCODE FIELDS -- TIME CONTROL" + +DT/=<109:111>D,0 ;**NOT STORED IN CRAM** + ;DEFAULT TIME FIELD (USED IN MACROS) + ; CAN BE OVERRIDDEN IN MACRO CALL + 2T=0 + 3T=1 + 4T=2 + 5T=3 + + +T/=<70:71>F,DT ;CSL5 (E601) + ;CLOCK TICKS MINUS TWO REQUIRED TO + ; DO A MICRO INSTRUCTION + 2T=0 ;TWO TICKS + 3T=1 ;THREE TICKS + 4T=2 ;FOUR TICKS + 5T=3 ;FIVE TICKS + + + .TOC "MICROCODE FIELDS -- RANDOM CONTROL BITS" + +CRY38/=<72> ;DPE5 + ;INJECT A CARRY INTO THE 2901 ADDER +LOADSC/=<73> ;DPM4 + ;LOAD THE STEP COUNTER FROM THE SCAD +LOADFE/=<74> ;DPM4 + ;LOAD THE FE REGISTER FROM THE SCAD +FMWRITE/=<75> ;DPE5 (E302) + ;WRITE THE RAM FILE. +MEM/=<76> ;DPM5 (E612) & DPE5 (E205) + ;START (OR COMPLETE) A MEMORY OR I/O CYCLE UNDER + ; CONTROL OF THE NUMBER FIELD. +DIVIDE/=<77> ;DPE5 + ;THIS MICROINSTRUCTION IS DOING A DIVIDE +MULTI PREC/=<78> ;DPE5 + ;MULTIPRECISION STEP IN DIVIDE, DFAD, DFSB +MULTI SHIFT/=<79> ;CSL5 (HAS NOTHING TO DO WITH DPE5 MULTI SHIFT) + ;FAST SHIFT +CALL/=<80> ;CRA2 (STACK IS ON CRA3) + ;THIS IS A CALL + + .TOC "MICROCODE FIELDS -- NUMBER FIELD" + +;HERE IS THE GENERAL FIELD +#/=<90:107> ;MANY PLACES + +;# REDEFINED WHEN USED AS SCAD CONTROL: +SCAD/=<90:92> ;DPM3 + A*2=0 + A.OR.B=1 + A-B-1=2 + A-B=3 + A+B=4 + A.AND.B=5 + A-1=6 + A=7 +SCADA/=<93:95> ;DPM3 + SC=0 + S#=1 + PTR44=2 ;44 AND BIT 6 (SEE DPM3) + BYTE1=3 + BYTE2=4 + BYTE3=5 + BYTE4=6 + BYTE5=7 +SCADB/=<96:97> ;DPM3 + FE=0 + EXP=1 + SHIFT=2 + SIZE=3 +S#/=<98:107> ;DPM3 + +;# REDEFINED WHEN USED AS STATE REGISTER CONTROL: +STATE/=<90:107> ;NOT USED BY HARDWARE + SIMPLE=0 ;SIMPLE INSTRUCTIONS + BLT=1 ;BLT IN PROGRESS +.IFNOT/ITS + MAP=400002 ;MAP IN PROGRESS +.ENDIF/ITS + SRC=3 ;MOVE STRING SOURCE IN PROGRESS + DST=4 ;MOVE STRING FILL IN PROGRESS + SRC+DST=5 ;MOVE STRING DEST IN PROGRESS + DSTF=6 ;FILLING DEST + CVTDB=7 ;CONVERT DEC TO BIN + COMP-DST=10 ;COMPARE DEST + EDIT-SRC=11 ;EDIT SOURCE + EDIT-DST=12 ;EDIT DEST + EDIT-S+D=13 ;BOTH SRC AND DST POINTERS + +.IF/1PROC +;# AS PC FLAGS +OIPBIT/=<98> ;BIT 8 OF PC IS ONE-PROCEED ON KS (NOT IN HARDWARE) +.ENDIF/1PROC + +;# REDEFINED WHEN USED AS WORSPACE ADDRESS + +WORK/=<98:107> ;DPE6 + BADW0=160 ;AC BLK 7 WORD 0 (BAD DATA FROM MEMORY) +.IFNOT/ITS + BADW1=161 ;AC BLK 7 WORD 1 (BAD DATA FROM MEMORY) +.ENDIF/ITS + MUL=200 ;TEMP FOR MULTIPLY + DIV=201 ;TEMP FOR DIVIDE + SV.VMA=210 ;SAVE VMA + SV.AR=211 ;SAVE AR + SV.ARX=212 ;SAVE ARX + SV.BR=213 ;SAVE BR + SV.BRX=214 ;SAVE BRX +.IF/ITS + DBR1=215 ;Pointer to page table for user low addresses. + DBR2=216 ;Pointer to page table for user high addresses. + DBR3=217 ;Pointer to page table for exec high addresses. + DBR4=220 ;Pointer to page table for exec low addresses. +.IFNOT/ITS + SBR=215 ;SPT BASE REGISTER + CBR=216 ;CST BASE ADDRESS + CSTM=217 ;CST MASK + PUR=220 ;PROCESS USE REGISTER +.ENDIF/ITS + ADJP=221 ;"P" FOR ADJBP + ADJS=222 ;"S" FOR ADJBP + ADJPTR=223 ;BYTE POINTER FOR ADJBP + ADJQ1=224 ;TEMP FOR ADJBP + ADJR2=225 ;TEMP FOR ADJBP + ADJBPW=226 ;(BYTES/WORD) FOR ADJBP + HSBADR=227 ;ADDRESS OF HALT STATUS BLOCK + APR=230 ;APR ENABLES + ; 2.5 - 2.4 Both set if paging enabled. + ; 2.3 - 1.5 Flags enabled + ; 1.3 - 1.1 PI level + ;More APR status is kept in APR FLAGS hardware: + ; 2.3 - 1.5 Flags set + ; 1.4 Some flag is interrupting +.IF/JPC + U.JPC=231 ;User mode JPC + E.JPC=232 ;Exec mode JPC +.ENDIF/JPC +.IF/PCST + PCST=233 ;AOBJN pointer to PC Sample Table +.ENDIF/PCST + +;THE FOLLOWING WORDS ARE USED BY EXTEND INSTRUCTION + E0=240 ;ORIGINAL EFFECTIVE ADDRESS + E1=241 ;EFFECTIVE ADDRESS OF WORD AT E0 + SLEN=242 ;SOURCE LENGTH + MSK=243 ;BYTE MASK + FILL=244 ;FILL BYTE + CMS=245 ;SRC BYTE IN STRING COMPARE + FSIG=246 ;PLACE TO SAVE ARX WHILE STORING + ; THE FLOAT CHAR + BDH=247 ;BINARY BEING CONVERTED TO + BDL=250 ; DECIMAL + +;TIMER STUFF + TIME0=300 ;HIGH ORDER 36 BITS OF TIME + TIME1=301 ;LOW ORDER 36 BITS OF TIME + PERIOD=302 ;INTERRUPT PERIOD + TTG=303 ;TIME TO GO TO NEXT INTERRUPT +.IF/ITS + QUAN=304 ;Quantum counter incremented by TOCK except + ;when PI in progress. +.ENDIF/ITS + +;DDIV STUFF + AC0=314 + AC1=315 + AC2=316 + AC3=317 + DDIV SGN=320 + DVSOR H=321 + DVSOR L=322 +;POWERS OF TEN + DECLO=344 ;LOW WORD + DECHI=373 ;HIGH WORD + + YSAVE=422 ;Y OF LAST INDIRECT POINTER +.IFNOT/ITS + PTA.E=423 ;ADDRESS OF EXEC PAGE MAP (NOT PROCESS TABLE) + PTA.U=424 ;ADDRESS OF USER PAGE MAP +.ENDIF/ITS + TRAPPC=425 ;SAVED PC FROM TRAP CYCLE + SV.AR1=426 ;ANOTHER PLACE TO SAVE AR + +;# REDEFINED WHEN USED AS PC FLAG CONTROL (ALL ON DPE9) + +SETOV/=<90> ;DPE9 + ;SET ARITHMETIC OVERFLOW +SETFOV/=<91> ;SET FLOATING OVERFLOW +SETNDV/=<92> ;SET NO DIVIDE + +;--------------------------------------------------------------------- + +CLRFPD/=<93> ;CLEAR FIRST PART DONE +SETFPD/=<94> ;SET FIRST PART DONE +HOLD USER/=<95> ;WHEN THIS BIT IS SET IT: + ; 1. PREVENTS SETTING USER IOT IN USER MODE + ; 2. PREVENTS CLEARING USER IN USER MODE + +;--------------------------------------------------------------------- + +; <96> ;SPARE +TRAP2/=<97> ;SET TRAP 2 +TRAP1/=<98> ;SET TRAP 1 + +;--------------------------------------------------------------------- + +LD PCU/=<99> ;LOAD PCU FROM USER +; <100> ;SPARE +; <101> ;SPARE + +;--------------------------------------------------------------------- + +; <102> ;SPARE +; <103> ;SPARE +JFCLFLG/=<104> ;DO A JFCL INSTRUCTION + +;--------------------------------------------------------------------- + +LD FLAGS/=<105> ;LOAD FLAGS FROM DP +; <106> +ADFLGS/=<107> ;UPDATE CARRY FLAGS + +;# REDEFINED WHEN USED AS MEMORY CYCLE CONTROL + +FORCE USER/=<90> ;FORCE USER MODE REFERENCE +FORCE EXEC/=<91> ;FORCE EXEC MODE REFERENCE + ; (DOES NOT WORK UNDER PXCT) +FETCH/=<92> ;THIS IS AN INSTRUCTION FETCH + +;--------------------------------------------------------------------- + +READ CYCLE/=<93> ;SELECT A READ CYCLE +WRITE TEST/=<94> ;PAGE FAILE IF NOT WRITTEN +WRITE CYCLE/=<95> ;SELECT A MEMORY WRITE CYCLE + +;--------------------------------------------------------------------- + +; <96> ;SPARE BIT +DONT CACHE/=<97> ;DO NOT LOOK IN CACHE +PHYSICAL/=<98> ;DO NOT INVOKE PAGING HARDWARE + +;--------------------------------------------------------------------- + +PXCT/=<99:101> ;WHICH PXCT BITS TO LOOK AT + CURRENT=0 + E1=1 + D1=3 + BIS-SRC-EA=4 + E2=5 + BIS-DST-EA=6 + D2=7 + +;--------------------------------------------------------------------- + +AREAD/=<102> ;LET DROM SELECT SYSLE TYPE AND VMA LOAD +DP FUNC/=<103> ;IGNORE # BITS 0-11 AND USE DP 0-13 INSTEAD + ; DP9 MEANS "FORCE PREVIOUS" +LDVMA/=<104> ;LOAD THE VMA + +;--------------------------------------------------------------------- + +EXT ADR/=<105> ;PUT VMA BITS 14-17 ONTO BUS +WAIT/=<106> ;START A MEMORY OR I/O CYCLE +BWRITE/=<107> ;START A MEMORY CYCLE IF DROM ASKS FOR IT + +;THESE BITS ARE USED ONLY TO SETUP DP FOR A DP FUNCTION + +; <99> ;PREVIOUS +IO CYCLE/=<100> ;THIS IS AN I/O CYCLE +WRU CYCLE/=<101> ;WHO ARE YOU CYCLE + +;--------------------------------------------------------------------- + +VECTOR CYCLE/=<102> ;READ INTERRUPT VECTOR +IO BYTE/=<103> ;BYTE CYCLE +; <104> + +;# REDEFINED WHEN USED AS PI RIGHT BITS +PI.ZER/=<90:92> ;ZEROS +PI.IP1/=<93> ;PI 1 IN PROG +PI.IP2/=<94> +PI.IP3/=<95> +PI.IP4/=<96> +PI.IP5/=<97> +PI.IP6/=<98> +PI.IP7/=<99> +PI.ON/=<100> ;SYSTEM IS ON +PI.CO1/=<101> ;CHAN 1 IS ON +PI.CO2/=<102> +I.CO3/=<103> +I.CO4/=<104> +I.CO5/=<105> +I.CO6/=<106> +I.CO7/=<107> + +;# REDEFINED WHEN USED AS WRPI DATA +PI.MBZ/=<90:93> ;MUST BE ZERO +PI.DIR/=<94> ;DROP INTERRUPT REQUESTS +PI.CLR/=<95> ;CLEAR SYSTEM +PI.REQ/=<96> ;REQUEST INTERRUPT +PI.TCN/=<97> ;TURN CHANNEL ON +PI.TCF/=<98> ;TURN CHANNEL OFF +PI.TSF/=<99> ;TURN SYSTEM OFF +PI.TSN/=<100> ;TURN SYSTEM ON +PI.SC1/=<101> ;SELECT CHANNEL 1 +PI.SC2/=<102> +PI.SC3/=<103> +PI.SC4/=<104> +PI.SC5/=<105> +PI.SC6/=<106> +PI.SC7/=<107> + +;# REDEFINED WHEN USED AS AC CONTROL + + +;THIS FIELD CONTROLS THE INPUT TO A 74LS181 ON DPE6. THE NUMBER +; FIELD HAS THIS FORMAT IN <98:107>: +; +; !-----!-----!-----!-----!-----!-----!-----!-----!-----!-----! +; !CARRY! S8 ! S4 ! S2 ! S1 ! MODE! B8 ! B4 ! B2 ! B1 ! +; ! IN ! FUNCTION ! ! DATA INPUTS ! +; !-----!-----------------------!-----!-----------------------! +; + +ACALU/=<98:103> + B=25 + AC+N=62 +ACN/=<104:107> + ;AC NAMES FOR STRING INSTRUCTIONS + SRCLEN=0 ;SOURCE LENGTH + SRCP=1 ;SOURCE POINTER + DLEN=3 ;DEST LENGTH + DSTP=4 ;DEST POINTER + MARK=3 ;POINTER TO MARK + BIN0=3 ;HIGH WORD OF BINARY + BIN1=4 ;LOW WORD OF BINARY + + +;# FIELD REDEFINED WHEN USE AS APRID DATA + +MICROCODE OPTIONS/=<90:98> +.IF/ITS + OPT=020 ;4.5 Indicates ITS ucode, just like on KL. +.IFNOT/ITS + OPT=000 +.ENDIF/ITS + +;Actually defined in configuration file: +; +; MICROCODE VERSION/=<99:107> +; UCV=259. +; +; HARDWARE OPTIONS/=<90:92> +; HWOPT=0 +; +; HARDWARE SERIAL NUMBER/=<93:107> +; HWSER=4097. + +;# FIELD REDEFINED WHEN USED AS A HALT CODE + +HALT/=<90:107> + ;CODES 0 TO 77 ARE "NORMAL" HALTS + POWER=0 ;POWER UP + HALT=1 ;HALT INSTRUCTION + CSL=2 ;CONSOLE HALT + ;CODES 100 TO 777 ARE SOFTWARE ERRORS + IOPF=100 ;I/O PAGE FAIL + ILLII=101 ;ILLEGAL INTERRUPT INSTRUCTION + ILLINT=102 ;BAD POINTER TO UNIBUS INTERRUPT VECTOR + ;CODES 1000 TO 1777 ARE HARDWARE ERRORS + BW14=1000 ;ILLEGAL BWRITE FUNCTION (BAD DROM) + NICOND 5=1004 ;ILLEGAL NICOND DISPATCH + MULERR=1005 ;VALUE COMPUTED FOR 10**21 WAS WRONG +.IFNOT/FULL + PAGEF=1777 ;PAGE FAIL IN SMALL MICROCODE +.ENDIF/FULL + + + +;# FIELD REDEFINED WHEN USED AS FLG BITS + +FLG.W/=<94> ;W BIT FROM PAGE MAP +FLG.PI/=<95> ;PI CYCLE +FLG.C/=<96> ;CACHE BIT FROM PAGE MAP +FLG.SN/=<97> ;SPECIAL NEGATE IN FDV & DFDV +.IF/1PROC +FLG.1PROC/=<98> ;1-PROCEED IN PROGRESS +FLG.2PROC/=<100> ;INSTRUCTION ACTUALLY RUNNING IF THIS IS SET TOO +;<99> RESERVED FOR JPC MODE +.ENDIF/1PROC + +;RIGHT HALF OF FLG USED TO RECOVER FROM PAGE FAILS + + .TOC "SUBFIELD DEFINITIONS FOR .RAMFILE" + +SPEC HIGH/=<51:53> +SPEC LOW/=<54:56> + +DISP HIGH/=<57:59> +DISP LOW/=<60:62> + +SKIP HIGH/=<63:65> +SKIP LOW/=<66:68> + +# HIGH/=<90:95> +# LOW/=<96:107> + + .TOC "DISPATCH ROM DEFINITIONS" + +;ALL ON DPEA + + .DCODE +A/=<2:5> ;OPERAND FETCH MODE + READ=0 ;READ + WRITE=1 ;WRITE + DREAD=2 ;DOUBLE READ + DBLAC=3 ;DOUBLE AC + SHIFT=4 ;SIMPLE SHIFT + DSHIFT=5 ;DOUBLE SHIFT + FPI=6 ;FLOATING POINT IMMEDIATE + FP=7 ;FLOATING POINT + RD-PF=10 ;READ, THEN START PREFETCH + DFP=11 ;DOUBLE FLOATING POINT + IOT=12 ;CHECK FOR IO LEGAL THEN SAME AS I + +B/=<8:11> ;STORE RESULTS AS + SELF=4 ;SELF + DBLAC=5 ;DOUBLE AC + DBLB=6 ;DOUBLE BOTH + AC=15 ;AC + MEM=16 ;MEMORY + BOTH=17 ;BOTH + +;B-FIELD WHEN USED IN FLOATING POINT OPERATIONS +ROUND/=<8> ;ROUND THE RESULT +MODE/=<9> ;SEPARATE ADD/SUB & MUL/DIV ETC. +FL-B/=<10:11> ;STORE RESULTS AS + AC=1 ;AC + MEM=2 ;MEMORY + BOTH=3 ;BOTH + +J/=<12:23> ;DISPATCH ADDRESS (MUST BE 1400 TO 1777) + +ACDISP/=<24> ;DISPATCH ON AC FIELD +I/=<25> ;IMMEDIATE DISPATCH. DISP/AREAD DOES A DISP/DROM + ; IF THIS BIT IS SET. +READ/=<26> ;START A READ AT AREAD +TEST/=<27> ;START A WRITE TEST AT AREAD +COND FUNC/=<28> ;START A MEMORY CYCLE ON BWRITE +VMA/=<29>D,1 ;LOAD THE VMA ON AREAD +WRITE/=<30> ;START A WRITE ON AREAD + .UCODE + + .TOC "HOW TO READ MACROS" +; +; 1.0 REGISTER TRANSFER MACROS +; +; MOST MACROS USED IN THE KS10 ARE USED TO OPERATE ON DATA IN (OR FROM/TO) 2901 +; REGISTERS. THE NAMES OF THE 2901 REGISTERS ARE MACRO PARAMETERS AND ARE +; ENCLOSED IN []. A TYPICAL MACRO IS: +; +; [AR]_[AR]+[BR] +; +; THE SYMBOL _ IS PRONOUNCED "GETS". THE ABOVE MACRO WOULD BE READ "THE AR GETS +; THE AR PLUS THE BR". +; +; IF A MACRO DOES NOT HAVE A _ IN IT, THERE IS NO RESULT STORED. THUS, [AR]-[BR] +; JUST COMPARES THE AR AND THE BR AND ALLOWS FOR SKIPS ON THE VARIOUS ALU BITS. +; +; +; +; 1.1 SPECIAL SYMBOLS +; +; THERE ARE A BUNCH OF SYMBOLS USED IN THE MACROS WHICH ARE NOT 2901 REGISTERS. +; THEY ARE DEFINED HERE: +; +; 1. AC -- THE AC SELECTED BY THE CURRENT INSTRUCTION. SEE DPEA +; +; 2. AC[] -- AC+N. AC[1] IS AC+1, AC[2] IS AC+2, ETC. +; +; 3. APR -- THE APR FLAGS FROM DPMA +; +; 4. EA -- THE EFFECTIVE ADDRESS. THAT IS, 0 IN THE LEFT HALF AND THE +; CONTENTS OF THE HR IN THE RIGHT HALF. +; +; 5. EXP -- THE F.P. EXPONENT FROM THE SCAD. [AR]_EXP WILL TAKE THE +; EXPONENT OUT OF THE FE AND PUT IT BACK INTO THE NUMBER IN THE AR. +; +; 6. FE -- THE FE REGISTER +; +; 7. FLAGS -- THE PC FLAGS (FROM DPE9) IN THE LEFT HALF. +; +; 8. Q -- THE Q REGISTER +; +; 9. RAM -- THE RAM FILE, RAM ADDRESS IS IN THE VMA. +; +; 10. P -- THE P FIELD OF THE BYTE POINTER. SAME IDEA AS EXP. +; +; 11. TIME -- THE 1MS. TIMER +; +; 12. VMA -- THE VMA. WHEN READ IT INCLUDES THE VMA FLAGS +; +; 13. XR -- INDEX REGISTER + +; 14. XWD -- HALF WORD. USED TO GENERATE CONSTANTS. FOR EXAMPLE, [AR]_0 XWD +; [40] WOULD LOAD THE CONSTANT 40 (OCTAL) INTO THE AR. +; +; 15. +SIGN AND -SIGN -- SIGN BITS USED TO SIGN SMEAR F.P. NUMBERS. FOR +; EXAMPLE, [AR]_+SIGN WOULD CLEAR AR BITS 0 TO 8. +; +; 16. WORK[] -- LOCATIONS IN THE WORKSPACE USED AS SCRATCH SPACE. FOR +; EXAMPLE, [AR]_WORK[CSTM] WOULD LOAD THE AR WITH THE CST MASK FROM THE +; RAM. CSTM IS A SYMBOL DEFINED IN THE WORK FIELD. +; +; +; +; +; 1.2 LONG +; +; LONG IS USED ON SHIFT OPERATIONS TO INDICATE THAT THE Q REGISTER IS ALSO +; SHIFTED. THIS SAYS NOTHING ABOUT HOW THE SHIFT PATHS ARE CONNECTED UP. +; +; +; +; 2.0 MEMORY MACROS +; +; MEMORY IS INDICATED BY THE SYMBOL "MEM". WHEN WE ARE WAITING FOR DATA FROM +; MEMORY THE "MEM READ" MACRO IS USED. WHEN WE ARE SENDING DATA TO MEMORY, THE +; "MEM WRITE" MACRO IS USED. EXAMPLE, +; MEM READ, ;WAIT FOR MEMORY +; [AR]_MEM ;LOAD DATA INTO AR +; VMA_ IS USED THE LOAD THE VMA. THUS, VMA_[PC] LOADS THE VMA FROM THE PC. +; +; +; +; 3.0 TIME CONTROL +; +; THERE ARE 2 SETS OF MACROS USED FOR TIME CONTROL. THE FIRST, SELECTS THE RAM +; ADDRESS TO SPEED UP THE NEXT INSTRUCTION. THESE MACROS ARE AC, AC[], XR, VMA, +; WORK[]. THE SECOND, SETS THE TIME FIELD. THESE ARE 2T, 3T, 4T, AND 5T TO +; SELECT 2, 3, 4, OR 5 TICKS. +; +; +; +; 4.0 SCAD MACROS +; +; THE SCAD MACROS LOOK LIKE THE 2901 MACROS EXECPT NO [] ARE REQUIRED. THERE ARE +; ONLY A FEW SYMBOLS USED. +; +; 1. FE -- THE FE REGISTER +; +; 2. SC -- THE SC REGISTER + +; 3. EXP -- THE EXPONENT FROM A F.P. NUMBER. FOR EXAMPLE FE_EXP LOADS THE +; FE FROM DP BITS 1-8. +; +; 4. SHIFT -- THE SHIFT COUNT FROM SHIFT INSTRUCTIONS. THAT IS DP BITS 18 +; AND 28-35. +; +; 5. S# -- THE SMALL NUMBER. THE 10 BIT MAGIC NUMBER INPUT TO THE SCADA +; MIXER. +; +; +; +; +; 5.0 CONTROL MACROS +; +; ALL CONTROL MACROS LOOK LIKE ENGLISH COMMANDS. SOME EXAMPLES, +; HOLD LEFT ;DO NOT CLOCK LEFT HALF OF DP +; SET APR ENABLES ;LOAD APR ENABLES FROM DP +; SET NO DIVIDE ;SET NO DIVIDE PC FLAG +; +; +; +; 6.0 SKIPS +; +; ALL SKIPS CAUSE THE NEXT MICRO INSTRUCTION TO COME FROM THE ODD WORD OF AN +; EVEN/ODD PAIR. THE MACROS HAVE THE FORMAT OF SKIP COND. THEY SKIP IF CONDITION +; IS TRUE. SOME EXAMPLES, +; SKIP AD.EQ.0 ;SKIP IF ADDER OUTPUT IS ZERO +; SKIP IRPT ;SKIP IF INTERRUPT IS PENDING +; +; +; +; 7.0 DISPATCH MACROS +; +; DISPATCH MACROS CAUSE THE MACHINE TO GO TO ONE OF MANY PLACES. IN MOST CASES +; THEY HAVE THE WORD "DISP" IN THE NAME OF THE MACRO. FOR EXAMPLE, MUL DISP, BYTE +; DISP. +; +; +; +; 8.0 SUPER MACROS +; +; THERE ARE PLACES WHERE ONE MICRO INSTRUCTION IS USED IN MANY PLACES. FOR +; EXAMPLE, MANY PLACES DETECT ILLEGAL OPERATIONS AND WANT TO GENERATE A TRAP TO +; THE MONITOR. WE COULD WRITE +; J/UUO +; BUT THIS WASTES A MICRO STEP DOING A USELESS JUMP. INSTEAD WE WRITE, +; UUO +; THIS MACRO IS THE FIRST STEP OF THE UUO ROUTINE AND JUMPS TO THE SECOND +; INSTRUCTION. WE WRITE THE EXPANSION OF THE UUO MACRO AS THE FIRST INSTRUCTION +; OF THE UUO ROUTINE SO THAT THE READER CAN SEE WHAT IT DOES. SOME EXAMPLES OF + +; SUPER MACROS ARE: +; PAGE FAIL TRAP ;GENERATE A PAGE FAIL TRAP +; DONE ;THIS INSTRUCTION IS NOW COMPLETE +; ; USED WITH A SKIP OR DISP WHERE +; ; SOME PATHS ARE NOP'S +; HALT [] ;JUMP TO HALT LOOP. ARGUMENT IS A +; ; CODE + + .TOC "MACROS -- DATA PATH CHIP -- GENERAL" + +.NOT.[] "AD/.NOT.A,A/@1" +[]+[] "AD/A+B,A/@1,B/@2" +[]-[] "AD/A-B-.25,A/@1,B/@2,ADD .25" +[]-# "AD/A-D-.25,DBUS/DBM,DBM/#,A/@1,ADD .25" +[].AND.# "AD/D.AND.A,DBUS/DBM,DBM/#,A/@1" +[].AND.Q "AD/A.AND.Q,A/@1,DEST/PASS" +[].AND.[] "AD/A.AND.B,A/@2,B/@1,DEST/PASS" +[].AND.NOT.[] "AD/.NOT.A.AND.B,A/@2,B/@1,DEST/PASS" +[].OR.[] "AD/A.OR.B,A/@2,B/@1,DEST/PASS" +[].XOR.# "AD/D.XOR.A,DBUS/DBM,DBM/#,A/@1" +[].XOR.VMA "AD/D.XOR.A,DBUS/DBM,DBM/VMA,A/@1" +[].XOR.[] "AD/A.XOR.B,A/@2,B/@1,DEST/PASS" +[]_#-[] "AD/D-A-.25,DEST/AD,A/@2,B/@1,DBUS/DBM,DBM/#,ADD .25" +[]_# "AD/D,DBUS/DBM,DBM/#,DEST/AD,B/@1" +[]_-1 "AD/-A-.25,A/ONE,DEST/AD,B/@1,ADD .25" +[]_-2 "AD/-A-.25,DEST/AD*2,A/ONE,B/@1,ADD .25" +[]_-Q "AD/-Q-.25,DEST/AD,B/@1,ADD .25" +[]_-Q*2 "AD/-Q-.25,DEST/AD*2,B/@1,ADD .25" +[]_-Q*.5 "AD/-Q-.25,DEST/AD*.5,B/@1,ADD .25" +[]_-[] "AD/-A-.25,A/@2,DEST/AD,B/@1,ADD .25" +[]_-[]-.25 "AD/-A-.25,A/@2,DEST/AD,B/@1" +[]_-[]*2 "AD/-A-.25,A/@2,DEST/AD*2,B/@1,ADD .25" +[]_.NOT.AC "AD/.NOT.D,DBUS/RAM,RAMADR/AC#,DEST/AD,B/@1" +[]_.NOT.AC[] "AD/.NOT.D,DBUS/RAM,RAMADR/AC*#,ACALU/AC+N,ACN/@2,DEST/AD,B/@1,DT/3T" +[]_.NOT.Q "AD/.NOT.Q,DEST/AD,B/@1" +[]_.NOT.[] "AD/.NOT.A,A/@2,DEST/AD,B/@1" +[]_0 "AD/ZERO,DEST/AD,B/@1" +[]_0*.5 LONG "AD/ZERO,DEST/Q_Q*.5,B/@1" +[]_0 XWD [] "AD/47,DEST/AD,B/@1,DBM/#,DBUS/DBM,#/@2,RSRC/DA,A/MASK" +[]_AC "AD/D,DBUS/RAM,RAMADR/AC#,DEST/AD,B/@1,AD PARITY" +[]_-AC "AD/-D-.25,DBUS/RAM,RAMADR/AC#,DEST/AD,B/@1,ADD .25" +[]_-AC[] "AD/-D-.25,DBUS/RAM,RAMADR/AC*#,ACALU/AC+N,ACN/@2,DEST/AD,B/@1,ADD .25,DT/3T" +[]_AC*.5 "AD/D,DBUS/RAM,RAMADR/AC#,DEST/AD*.5,B/@1,DT/3T" +[]_AC*.5 LONG "AD/D,DBUS/RAM,RAMADR/AC#,DEST/Q_Q*.5,B/@1,DT/3T" +[]_AC*2 "AD/D,DBUS/RAM,RAMADR/AC#,DEST/AD*2,B/@1,DT/3T" +[]_AC+1 "AD/D+A,DBUS/RAM,RAMADR/AC#,A/ONE,DEST/AD,B/@1" +[]_AC+1000001 "AD/D+A,DBUS/RAM,RAMADR/AC#,A/XWD1,DEST/AD,B/@1" +[]_AC+[] "AD/D+A,A/@2,DBUS/RAM,RAMADR/AC#,DEST/AD,B/@1,DT/3T" +[]_AC-1 "AD/D-A-.25,DBUS/RAM,RAMADR/AC#,A/ONE,DEST/AD,B/@1,ADD .25" +[]_AC-[] "AD/D-A-.25,A/@2,DBUS/RAM,RAMADR/AC#,DEST/AD,B/@1,ADD .25" +[]_AC-[]-.25 "AD/D-A-.25,A/@2,DBUS/RAM,RAMADR/AC#,DEST/AD,B/@1" +[]_AC[]-[] "AD/D-A-.25,A/@3,DBUS/RAM,RAMADR/AC*#,ACALU/AC+N,ACN/@2,DEST/AD,B/@1,ADD .25,DT/3T" +[]_AC[]-1 "AD/D-A-.25,A/ONE,DBUS/RAM,RAMADR/AC*#,ACALU/AC+N,ACN/@2,DEST/AD,B/@1,ADD .25,DT/3T" +[]_AC[].AND.[] "AD/D.AND.A,A/@3,DBUS/RAM,RAMADR/AC*#,ACALU/AC+N,ACN/@2,DEST/AD,B/@1,DT/3T" +[]_AC.AND.MASK "AD/D.AND.A,A/MASK,DBUS/RAM,RAMADR/AC#,DEST/AD,B/@1,AD PARITY" +[]_AC[] "AD/D,DBUS/RAM,RAMADR/AC*#,ACALU/AC+N,ACN/@2,DEST/AD,B/@1,AD PARITY,DT/3T" +[]_AC[]*2 "AD/D,DBUS/RAM,RAMADR/AC*#,ACALU/AC+N,ACN/@2,DEST/AD*2,B/@1,AD PARITY,DT/3T" +[]_AC[]*.5 "AD/D,DBUS/RAM,RAMADR/AC*#,ACALU/AC+N,ACN/@2,DEST/AD*.5,B/@1,AD PARITY,DT/3T" +[]_APR "AD/D,DBUS/DBM,DBM/APR FLAGS,DEST/AD,B/@1,DT/3T" +[]_CURRENT AC [] "AD/D,DBUS/RAM,RAMADR/#,ACALU/B,ACN/@2,DEST/AD,B/@1,AD PARITY,DT/3T" +[]_EA FROM [] "AD/57,RSRC/0A,A/@2,DEST/AD,B/@1" + +[]_EA "AD/57,RSRC/0A,A/HR,DEST/AD,B/@1" +[]_EXP "AD/D,DBUS/DBM,DBM/EXP,A/@1,B/@1,DEST/A,SCAD/A+B,SCADA/S#,S#/0,SCADB/FE,HOLD RIGHT,EXP TEST" +[]_FE "AD/D,DEST/AD*.5,B/@1,DBUS/DBM,DBM/DP,SCAD/A+B,SCADA/S#,S#/0,SCADB/FE,BYTE/BYTE5" +[]_FLAGS "AD/D.AND.A,DBUS/PC FLAGS,A/MASK,DEST/AD,B/@1,RSRC/0Q" +[]_P "AD/D,DEST/A,A/@1,B/@1,DBUS/DBM,DBM/DP,BYTE/BYTE1,SCAD/A+B,SCADA/S#,S#/0,SCADB/FE" +[]_PC WITH FLAGS "AD/D,DBUS/PC FLAGS,RSRC/0A,A/PC,DEST/AD,B/@1" +[]_Q "AD/Q,DEST/AD,B/@1" +[]_Q*.5 "AD/Q,DEST/AD*.5,B/@1" +[]_Q*2 "AD/Q,DEST/AD*2,B/@1" +[]_Q*2 LONG "AD/Q,DEST/Q_Q*2,B/@1" +[]_Q+1 "AD/A+Q,A/ONE,DEST/AD,B/@1" +[]_RAM "AD/D,DBUS/RAM,RAMADR/RAM,DEST/AD,B/@1,AD PARITY" +[]_TIME "AD/44,RSRC/DA,A/MASK,DBUS/DBM,DBM/EXP,DEST/AD,B/@1" +[]_VMA "AD/D,DEST/AD,B/@1,DBUS/DBM,DBM/VMA" +[]_XR "AD/D,DBUS/RAM,RAMADR/XR#,DEST/AD,B/@1" +[]_[] "AD/A,A/@2,DEST/AD,B/@1" +[]_[] SWAP "AD/D,DBUS/DBM,DBM/DP SWAP,DEST/A,A/@2,B/@1" +[]_[] XWD 0 "AD/45,DEST/AD,B/@1,DBM/#,DBUS/DBM,#/@2,RSRC/D0,A/MASK" +[]_[]*.5 "AD/A,A/@2,DEST/AD*.5,B/@1" +[]_[]*.5 LONG "AD/A,A/@2,DEST/Q_Q*.5,B/@1" +[]_[]*2 "AD/A,A/@2,DEST/AD*2,B/@1" +[]_[]*2 LONG "AD/A,A/@2,DEST/Q_Q*2,B/@1" +[]_[]*4 "AD/A+B,A/@2,B/@1,DEST/AD*2" +[]_[]+# "AD/D+A,DBUS/DBM,DBM/#,A/@2,DEST/AD,B/@1" +[]_[]+.25 "AD/0+A,A/@2,DEST/AD,B/@1, ADD .25" +[]_[]+0 "AD/0+A,A/@2,DEST/AD,B/@1" +[]_[]+1 "AD/A+B,A/ONE,B/@1,B/@2,DEST/AD" +[]_[]+1000001 "AD/D+A,A/@2,DBUS/DBM,DBM/#,#/1,DEST/AD,B/@1" +[]_[]+AC "AD/D+A,A/@2,DBUS/RAM,RAMADR/AC#,DEST/AD,B/@1" +[]_[]+AC[] "AD/D+A,A/@2,DBUS/RAM,RAMADR/AC*#,ACALU/AC+N,ACN/@3,DEST/AD,B/@1,DT/3T" +[]_[]+Q "AD/A+Q,A/@2,DEST/AD,B/@1" +[]_[]+RAM "AD/D+A,A/@2,DBUS/RAM,RAMADR/RAM,DEST/AD,B/@1" +[]_[]+XR "AD/D+A,DBUS/RAM,RAMADR/XR#,A/@2,DEST/AD,B/@1,HOLD LEFT" +[]_[]+[] "AD/A+B,A/@3,B/@1,B/@2,DEST/AD" +[]_[]+[]+.25 "AD/A+B,A/@3,B/@1,B/@2,DEST/AD, ADD .25" +[]_[]-# "AD/A-D-.25,DBUS/DBM,DBM/#,A/@2,DEST/AD,B/@1, ADD .25" +[]_[]-1 "AD/B-A-.25,B/@1,A/ONE,DEST/AD,ADD .25" +[]_[]-1000001 "AD/A-D-.25,A/@2,DBUS/DBM,DBM/#,#/1,DEST/AD,B/@1,ADD .25" +[]_[]-AC "AD/A-D-.25,A/@2,DBUS/RAM,RAMADR/AC#,DEST/AD,B/@1,ADD .25" +[]_[]-RAM "AD/A-D-.25,A/@2,DBUS/RAM,RAMADR/RAM,DEST/AD,B/@1,ADD .25" +[]_[]-[] "AD/B-A-.25,B/@1,B/@2,A/@3,DEST/AD,ADD .25" +[]_[]-[] REV "AD/A-B-.25,B/@1,B/@3,A/@2,DEST/AD,ADD .25" +[]_[].AND.# "AD/D.AND.A,DBUS/DBM,DBM/#,DEST/AD,A/@2,B/@1" +[]_[].AND.# CLR LH "AD/ZERO,RSRC/DA,DBUS/DBM,DBM/#,DEST/AD,A/@2,B/@1" +[]_[].AND.# CLR RH "AD/D.AND.A,RSRC/0Q,DBUS/DBM,DBM/#,DEST/AD,A/@2,B/@1" +[]_(AC[].AND.[])*.5 "AD/D.AND.A,DEST/AD*.5,A/@3,B/@1,RAMADR/AC*#,DBUS/RAM,ACALU/AC+N,ACN/@2" +[]_(Q+1)*.5 "AD/A+Q,A/ONE,DEST/AD*.5,B/@1" +[]_(#-[])*2 "AD/D-A-.25,DEST/AD*2,A/@2,B/@1,DBUS/DBM,DBM/#,ADD .25" +[]_(-[])*.5 "AD/-A-.25,A/@2,DEST/AD*.5,B/@1,ADD .25" +[]_(-[]-.25)*.5 LONG "AD/-A-.25,A/@2,DEST/Q_Q*.5,B/@1" +[]_(-[]-.25)*2 LONG "AD/-A-.25,A/@2,DEST/Q_Q*2,B/@1" + +[]_([].AND.#)*.5 "AD/D.AND.A,DBUS/DBM,DBM/#,DEST/AD*.5,A/@2,B/@1" +[]_([].AND.#)*2 "AD/D.AND.A,DBUS/DBM,DBM/#,DEST/AD*2,A/@2,B/@1" +[]_([].AND.NOT.#)*.5 "AD/.NOT.D.AND.A,DBUS/DBM,DBM/#,DEST/AD*.5,A/@2,B/@1" +[]_([].AND.NOT.#)*2 "AD/.NOT.D.AND.A,DBUS/DBM,DBM/#,DEST/AD*2,A/@2,B/@1" +[]_([].AND.[])*.5 "AD/A.AND.B,DEST/AD*.5,A/@3,B/@1,B/@2" +[]_([].AND.[])*2 "AD/A.AND.B,DEST/AD*2,A/@3,B/@1,B/@2" +[]_([].OR.#)*.5 "AD/D.OR.A,DBUS/DBM,DBM/#,DEST/AD*.5,A/@2,B/@1" +[]_([].OR.#)*2 "AD/D.OR.A,DBUS/DBM,DBM/#,DEST/AD*2,A/@2,B/@1" +[]_([]+#)*2 "AD/D+A,DBUS/DBM,DBM/#,DEST/AD*2,A/@2,B/@1" +[]_([]+1)*2 "AD/A+B,A/ONE,B/@1,B/@2,DEST/AD*2" +[]_([]+[])*.5 LONG "AD/A+B,A/@3,B/@1,B/@2,DEST/Q_Q*.5" +[]_([]+[])*2 LONG "AD/A+B,A/@3,B/@1,B/@2,DEST/Q_Q*2" +[]_([]-[])*.5 LONG "AD/B-A-.25,A/@3,B/@1,B/@2,DEST/Q_Q*.5, ADD .25" +[]_([]-[])*2 LONG "AD/B-A-.25,A/@3,B/@1,B/@2,DEST/Q_Q*2, ADD .25" +[]_([]+[]+.25)*.5 LONG "AD/A+B,A/@3,B/@1,B/@2,DEST/Q_Q*.5, ADD .25" +[]_[].AND.AC "AD/D.AND.A,DBUS/RAM,RAMADR/AC#,A/@2,DEST/AD,B/@1" +[]_[].AND.NOT.# "AD/.NOT.D.AND.A,DBUS/DBM,DBM/#,A/@2,DEST/AD,B/@1" +[]_[].AND.NOT.[] "AD/.NOT.A.AND.B,DEST/AD,B/@1,B/@2,A/@3" +[]_[].AND.NOT.AC "AD/.NOT.D.AND.A,DBUS/RAM,RAMADR/AC#,A/@2,DEST/AD,B/@1" +[]_[].AND.Q "AD/A.AND.Q,A/@2,DEST/AD,B/@1" +[]_[].AND.[] "AD/A.AND.B,A/@3,B/@1,B/@2,DEST/AD" +[]_[].EQV.AC "AD/D.EQV.A,DBUS/RAM,RAMADR/AC#,A/@2,DEST/AD,B/@1" +[]_[].EQV.Q "AD/A.EQV.Q,A/@2,DEST/AD,B/@1" +[]_[].OR.# "AD/D.OR.A,DBUS/DBM,DBM/#,A/@2,DEST/AD,B/@1" +[]_[].OR.AC "AD/D.OR.A,DBUS/RAM,RAMADR/AC#,A/@2,DEST/AD,B/@1" +[]_[].OR.FLAGS "AD/D.OR.A,DBUS/PC FLAGS,RSRC/0A,A/@1,DEST/AD,B/@1" +[]_[].OR.[] "AD/A.OR.B,A/@3,B/@2,B/@1,DEST/AD" +[]_[].XOR.# "AD/D.XOR.A,DBUS/DBM,DBM/#,DEST/AD,A/@2,B/@1" +[]_[].XOR.AC "AD/D.XOR.A,DBUS/RAM,RAMADR/AC#,A/@1,DEST/AD,B/@2" +[]_[].XOR.[] "AD/A.XOR.B,A/@3,B/@1,B/@2,DEST/AD" + +[] LEFT_0 "AD/57,RSRC/0B,DEST/AD,B/@1" +[] RIGHT_0 "AD/53,RSRC/D0,DEST/AD,B/@1" +[] LEFT_-1 "AD/54,RSRC/0B,DEST/AD,A/MASK,B/@1" +[] RIGHT_-1 "AD/53,RSRC/0A,DEST/AD,A/MASK,B/@1" + + +[]_+SIGN "[@1]_[@1].AND.#, #/777, HOLD RIGHT" +[]_-SIGN "[@1]_[@1].OR.#, #/777000, HOLD RIGHT" +;THE FOLLOWING 2 MACROS ARE USED IN DOUBLE FLOATING STUFF +; THEY ASSUME THAT THE OPERAND HAS BEEN SHIFTED RIGHT 1 PLACE. +; THEY SHIFT 1 MORE PLACE +[]_+SIGN*.5 "AD/.NOT.D.AND.A,A/@1,B/@1,DEST/AD*.5,DBUS/DBM,DBM/#,#/777400,RSRC/0A" +[]_-SIGN*.5 "AD/D.OR.A,A/@1,B/@1,DEST/AD*.5,DBUS/DBM,DBM/#,#/777400,RSRC/0A" + + .TOC "MACROS -- DATA PATH CHIP -- Q" + +Q-[] "AD/Q-A-.25,A/@1,ADD .25" +Q.AND.NOT.[] "AD/.NOT.A.AND.Q,A/@1,DEST/PASS" +Q_[] "AD/A,DEST/Q_AD,A/@1" +Q_[]-[] "AD/A-B-.25,A/@1,B/@2,DEST/Q_AD,ADD .25" +Q_[]+[] "AD/A+B,A/@1,B/@2,DEST/Q_AD" +Q_[].AND.[] "AD/A.AND.B,A/@1,B/@2,DEST/Q_AD" +Q_.NOT.AC[] "AD/.NOT.D,DBUS/RAM,RAMADR/AC*#,ACALU/AC+N,ACN/@1,DEST/Q_AD,DT/3T" +Q_-[] "AD/-A-.25,DEST/Q_AD,A/@1, ADD .25" +Q_-1 "Q_-[ONE]" +Q_-AC[] "AD/-D-.25,DBUS/RAM,RAMADR/AC*#,ACALU/AC+N,ACN/@1,DEST/Q_AD,ADD .25,DT/3T" +Q_-Q "AD/-Q-.25,ADD .25,DEST/Q_AD" +Q_AC "AD/D,DBUS/RAM,RAMADR/AC#,DEST/Q_AD,CHK PARITY" +Q_AC[] "AD/D,DBUS/RAM,RAMADR/AC*#,ACALU/AC+N,ACN/@1,DEST/Q_AD,CHK PARITY,DT/3T" +Q_AC[].AND.MASK "AD/D.AND.A,A/MASK,DBUS/RAM,RAMADR/AC*#,ACALU/AC+N,ACN/@1,DEST/Q_AD,CHK PARITY,DT/3T" +Q_AC[].AND.[] "AD/D.AND.A,A/@2,DBUS/RAM,RAMADR/AC*#,ACALU/AC+N,ACN/@1,DEST/Q_AD,CHK PARITY,DT/3T" +Q_.NOT.Q "AD/.NOT.Q,DEST/Q_AD" +Q_# "AD/D,DBUS/DBM,DBM/#,DEST/Q_AD" +Q_0 "AD/ZERO,DEST/Q_AD" +Q_0 XWD [] "AD/47,DEST/Q_AD,DBM/#,DBUS/DBM,#/@1,RSRC/DA,A/MASK" +Q_Q+.25 "AD/0+Q,DEST/Q_AD,ADD .25" +Q_Q+1 "AD/A+Q,A/ONE,DEST/Q_AD" +Q_Q-1 "AD/Q-A-.25,A/ONE,DEST/Q_AD, ADD .25" +Q_Q+AC "AD/D+Q,DBUS/RAM,RAMADR/AC#,DEST/Q_AD" +Q_Q*.5 "[MAG]_[MASK]*.5 LONG, SHSTYLE/NORM" +Q_Q*2 "[MASK]_[MAG]*2 LONG, SHSTYLE/NORM" +Q_Q.OR.# "AD/D.OR.Q,DBUS/DBM,DBM/#,DEST/Q_AD" +Q_Q.AND.# "AD/D.AND.Q,DBUS/DBM,DBM/#,DEST/Q_AD" +Q_Q.AND.[] "AD/A.AND.Q,A/@1,DEST/Q_AD" +Q_Q.AND.NOT.[] "AD/.NOT.A.AND.Q,A/@1,DEST/Q_AD" +Q_Q+[] "AD/A+Q,A/@1,DEST/Q_AD" +Q_[].AND.Q "AD/A.AND.Q,A/@1,DEST/Q_AD" +Q_[].OR.Q "AD/A.OR.Q,A/@1,DEST/Q_AD" + + .TOC "MACROS -- DATA PATH CHIP -- MISC." + +CLEAR []0 "AD/D.AND.A,A/@1,DBUS/DBM,DBM/#,#/377777,DEST/AD,B/@1,HOLD RIGHT" +CLEAR ARX0 "CLEAR [ARX]0" + +;CYCLE CHIP REGISTERS THRU AD SO WE CAN TEST BITS +READ XR "AD/D,DBUS/RAM,RAMADR/XR#" +READ [] "AD/B,B/@1" +READ Q "AD/Q" + +;TEST BITS IN REGISTERS (SKIP IF ZERO) +TR [] "AD/D.AND.A,DBUS/DBM,DBM/#,A/@1,SKIP ADR.EQ.0,DT/3T" +TL [] "AD/D.AND.A,DBUS/DBM,DBM/#,A/@1,SKIP ADL.EQ.0,DT/3T" + + +;CAUSE BITS -2 AND -1 TO MATCH BIT 0. +FIX [] SIGN "AD/D,DEST/A,A/@1,B/@1,DBUS/DP,HOLD RIGHT" + +;GENERATE A MASK IN Q AND ZERO A 2901 REGISTER +GEN MSK [] "AD/ZERO,DEST/Q_Q*2,B/@1,ONES" + + .TOC "MACROS -- STORE IN AC" + +FM WRITE "FMWRITE/1" + +AC[]_[] VIA AD "AD/B,DEST/PASS,B/@2,RAMADR/AC*#,ACALU/AC+N,ACN/@1,DBUS/DP,FM WRITE,CHK PARITY" +AC_[] VIA AD "AD/B,DEST/PASS,B/@1,RAMADR/AC#,DBUS/DP,FM WRITE,CHK PARITY" +AC[]_[] "AD/A,DEST/A,B/@2,A/@2,RAMADR/AC*#,ACALU/AC+N,ACN/@1,DBUS/DP, FM WRITE" +AC[]_[] TEST "AD/D,DBUS/DP,DEST/A,B/@2,A/@2,RAMADR/AC*#,ACALU/AC+N,ACN/@1,DBUS/DP, FM WRITE" +AC[]_[]+1 "AD/A+B,DEST/PASS,A/ONE,B/@2,RAMADR/AC*#,ACALU/AC+N,ACN/@1,DBUS/DP,FM WRITE" +AC[]_[]*2 "AD/A+B,DEST/PASS,A/@2,B/@2,RAMADR/AC*#,ACALU/AC+N,ACN/@1,DBUS/DP,FM WRITE" +AC_[] "AD/A,DEST/A,B/@1,A/@1,RAMADR/AC#,DBUS/DP, FM WRITE" +AC_[] TEST "AD/D,DBUS/DP,DEST/A,B/@1,A/@1,RAMADR/AC#,DBUS/DP, FM WRITE" +AC_[]+1 "AD/A+B,DEST/PASS,A/ONE,B/@1,RAMADR/AC#, FM WRITE" +AC_[]+Q "AD/A+Q,DEST/PASS,A/@1,B/@1,RAMADR/AC#, FM WRITE" +AC[]_[]+Q "AD/A+Q,DEST/PASS,A/@2,B/@2,RAMADR/AC*#,ACALU/AC+N,ACN/@1, FM WRITE" +AC[]_[]-[] "AD/A-B-.25,DEST/PASS,B/@3,A/@2,RAMADR/AC*#,ACALU/AC+N,ACN/@1,DBUS/DP,FM WRITE,ADD .25" +AC[]_[]+[] "AD/A+B,DEST/PASS,B/@3,A/@2,RAMADR/AC*#,ACALU/AC+N,ACN/@1,DBUS/DP,FM WRITE" +AC_[]+[] "AD/A+B,DEST/PASS,B/@2,A/@1,RAMADR/AC#,DBUS/DP,FM WRITE" +AC_[]-[] "AD/A-B-.25,DEST/PASS,B/@2,A/@1,RAMADR/AC#,DBUS/DP,FM WRITE,ADD .25" +AC[]_[].AND.[] "AD/A.AND.B,DEST/PASS,B/@3,A/@2,RAMADR/AC*#,ACALU/AC+N,ACN/@1,DBUS/DP,FM WRITE" +AC[]_Q.AND.[] "AD/A.AND.Q,DEST/PASS,A/@2,RAMADR/AC*#,ACALU/AC+N,ACN/@1,DBUS/DP,FM WRITE" +AC[]_[].EQV.Q "AD/A.EQV.Q,DEST/PASS,A/@2,RAMADR/AC*#,ACALU/AC+N,ACN/@1,DBUS/DP,FM WRITE" +AC[]_-[] "AD/-B-.25,DEST/PASS,B/@2,RAMADR/AC*#,ACALU/AC+N,ACN/@1,DBUS/DP,FM WRITE,ADD .25" +AC_-[] "AD/-A-.25,DEST/PASS,A/@1,RAMADR/AC#,DBUS/DP, ADD .25,FM WRITE" +AC_[].OR.[] "AD/A.OR.B,A/@1,B/@2,RAMADR/AC#,DBUS/DP, FM WRITE" +AC[]_.NOT.[] "AD/.NOT.B,DEST/PASS,B/@2,RAMADR/AC*#,ACALU/AC+N,ACN/@1,DBUS/DP,FM WRITE" +AC_.NOT.[] "AD/.NOT.B,DEST/PASS,B/@1,RAMADR/AC#,DBUS/DP,FM WRITE" +AC[]_-Q "AD/-Q-.25,RAMADR/AC*#,ACALU/AC+N,ACN/@1,DBUS/DP,FM WRITE,ADD .25" +AC_Q "AD/Q,RAMADR/AC#,DBUS/DP, FM WRITE" +AC[]_0 "AD/ZERO,RAMADR/AC*#,ACALU/AC+N,ACN/@1,DBUS/DP, FM WRITE" +AC[]_1 "AD/B,DEST/PASS,B/ONE,RAMADR/AC*#,ACALU/AC+N,ACN/@1,DBUS/DP,FM WRITE" +AC[]_Q "AD/Q,RAMADR/AC*#,ACALU/AC+N,ACN/@1,DBUS/DP, FM WRITE" + + .TOC "MACROS -- MICROCODE WORK SPACE" + + +WORK[]_Q "AD/Q,DEST/PASS,RAMADR/#,WORK/@1,FM WRITE" +Q_WORK[] "AD/D,DEST/Q_AD,RAMADR/#,DBUS/RAM,WORK/@1,DT/3T" +WORK[]_0 "AD/ZERO,DEST/PASS,RAMADR/#,WORK/@1,FM WRITE" +WORK[]_1 "AD/B,DEST/PASS,RAMADR/#,WORK/@1,B/ONE,FM WRITE" +WORK[]_[] "AD/B,DEST/PASS,RAMADR/#,WORK/@1,B/@2,FM WRITE" +WORK[]_[] CLR LH "AD/47,RSRC/AB,DEST/PASS,RAMADR/#,WORK/@1,B/@2,A/MASK,FM WRITE" +WORK[]_[]-1 "AD/A-B-.25,A/@2,B/ONE,DEST/PASS,RAMADR/#,WORK/@1,FM WRITE, ADD .25" +WORK[]_.NOT.[] "AD/.NOT.B,DEST/PASS,RAMADR/#,WORK/@1,B/@2,FM WRITE" +WORK[]_[].AND.[] "AD/A.AND.B,DEST/PASS,RAMADR/#,WORK/@1,A/@2,B/@3,FM WRITE" +WORK[]_[]+[] "AD/A+B,DEST/PASS,RAMADR/#,WORK/@1,A/@2,B/@3,FM WRITE" +[].AND.NOT.WORK[] "AD/.NOT.D.AND.A,A/@1,DBUS/RAM,RAMADR/#,WORK/@2,DT/3T" +[].AND.WORK[] "AD/D.AND.A,A/@1,DBUS/RAM,RAMADR/#,WORK/@2,DT/3T" +[]_[]+WORK[] "AD/D+A,A/@2,DEST/AD,B/@1,DBUS/RAM,RAMADR/#,WORK/@3,DT/3T" +[]_[].AND.WORK[] "AD/D.AND.A,A/@2,DEST/AD,B/@1,DBUS/RAM,RAMADR/#,WORK/@3,DT/3T" +[]_[].AND.NOT.WORK[] "AD/.NOT.D.AND.A,A/@2,DEST/AD,B/@1,DBUS/RAM,RAMADR/#,WORK/@3,DT/3T" +[]_[].OR.WORK[] "AD/D.OR.A,A/@2,DEST/AD,B/@1,DBUS/RAM,RAMADR/#,WORK/@3,DT/3T" +[]_WORK[] "AD/D,DEST/AD,B/@1,DBUS/RAM,RAMADR/#,WORK/@2,DT/3T" +[]_.NOT.WORK[] "AD/.NOT.D,DEST/AD,B/@1,DBUS/RAM,RAMADR/#,WORK/@2,DT/3T" +[]_-WORK[] "AD/-D-.25,ADD .25,DEST/AD,B/@1,DBUS/RAM,RAMADR/#,WORK/@2,DT/3T" +[]_WORK[]+1 "AD/D+A,A/ONE,DEST/AD,B/@1,DBUS/RAM,RAMADR/#,WORK/@2,DT/3T" +Q_Q-WORK[] "AD/Q-D-.25,DEST/Q_AD,DBUS/RAM,RAMADR/#,WORK/@1,ADD .25,DT/3T" +[]_[]-WORK[] "AD/A-D-.25,DEST/AD,A/@2,B/@1,DBUS/RAM,RAMADR/#,WORK/@3,ADD .25,DT/3T" + +RAM_[] "AD/B,DEST/PASS,RAMADR/RAM,B/@1,FM WRITE" + + .TOC "MACROS -- MEMORY CONTROL" + +MEM CYCLE "MEM/1" + +;THE FOLLOWING MACROS CONTROL MEMORY ADDRESS +LOAD VMA "MEM CYCLE,LDVMA/1" +FORCE EXEC "FORCE EXEC/1" +VMA PHYSICAL "PHYSICAL/1,FORCE EXEC/1,FORCE USER/0,EXT ADR/1,LOAD VMA" +VMA PHYSICAL WRITE "LOAD VMA,VMA PHYSICAL,WAIT/1,MEM/1,WRITE CYCLE/1,WRITE TEST/0" +VMA PHYSICAL READ "LOAD VMA,VMA PHYSICAL,WAIT/1,MEM/1,READ CYCLE/1,WRITE TEST/0" +VMA EXTENDED "EXT ADR/1" + +PXCT EA "PXCT/E1" +PXCT DATA "PXCT/D1" +PXCT BLT DEST "PXCT/D1" +PXCT BYTE PTR EA "PXCT/E2" +PXCT BYTE DATA "PXCT/D2" +PXCT STACK WORD "PXCT/D2" +PXCT BLT SRC "PXCT/D2" +PXCT EXTEND EA "PXCT/E2" + +;THE FOLLOWING MACROS GET MEMORY CYCLES STARTED +WRITE TEST "WRITE TEST/1,WAIT/1" +START READ "MEM CYCLE,READ CYCLE/1,WAIT/1" +START WRITE "MEM CYCLE,WRITE TEST,WRITE CYCLE/1,WAIT/1" +START NO TEST WRITE "MEM CYCLE,WRITE CYCLE/1,WAIT/1" +FETCH "START READ,FETCH/1,PXCT/CURRENT,WAIT/1" + +;THE FOLLOWING MACROS COMPLETE MEMORY CYCLES +MEM WAIT "MEM CYCLE,WAIT/1" +MEM READ "MEM WAIT,DBUS/DBM,DBM/MEM" +MEM WRITE "MEM WAIT,DT/3T" +SPEC MEM READ "SPEC/WAIT,DBUS/DBM,DBM/MEM" +SPEC MEM WRITE "SPEC/WAIT,DT/3T" + + +;THINGS WHICH WRITE MEMORY +MEM_[] "AD/B,DEST/PASS,B/@1,DBUS/DP,RAMADR/VMA,CHK PARITY" +MEM_Q "AD/Q,DBUS/DP,RAMADR/VMA" + + +;THINGS WHICH READ MEMORY +[]_IO DATA "AD/D,DBUS/DBM,RAMADR/VMA,DEST/AD,B/@1" +[]_MEM "AD/D,DBUS/DBM,RAMADR/VMA,DEST/AD,B/@1,CHK PARITY" +[]_MEM THEN FETCH "AD/D,DBUS/DBM,RAMADR/VMA,DEST/A,A/PC,B/@1,CHK PARITY, FETCH, LOAD VMA" +[]_MEM*.5 "AD/D,DBUS/DBM,RAMADR/VMA,DEST/AD*.5,B/@1,CHK PARITY" +[]_MEM.AND.MASK "AD/D.AND.A,A/MASK,DBUS/DBM,RAMADR/VMA,DEST/AD,B/@1,CHK PARITY" +[]_(MEM.AND.[])*.5 "AD/D.AND.A,A/@2,DBUS/DBM,RAMADR/VMA,DEST/AD*.5,B/@1,CHK PARITY" +Q_MEM "AD/D,DBUS/DBM,RAMADR/VMA,DEST/Q_AD,CHK PARITY" +[]_MEM AND READ [] "AD/D,DBUS/DBM,RAMADR/VMA,DEST/A,B/@1,A/@2,CHK PARITY" + .TOC "MACROS -- VMA" + +VMA_[] "AD/A,A/@1,DEST/PASS,LOAD VMA" +VMA_[] WITH FLAGS "AD/A,A/@1,DEST/PASS,LOAD VMA,WAIT/1, MEM/1, EXT ADR/1, DP FUNC/1, DT/3T" +VMA_[].OR.[] WITH FLAGS "AD/A.OR.B,A/@1,B/@2,DEST/PASS,LOAD VMA,WAIT/1, MEM/1, EXT ADR/1, DP FUNC/1, DT/3T" +VMA_[]+1 "AD/A+B,A/ONE,B/@1,DEST/AD,HOLD LEFT,LOAD VMA" +VMA_[]-1 "AD/B-A-.25,A/ONE,B/@1,ADD .25,HOLD LEFT,LOAD VMA" +VMA_[]+XR "AD/D+A,DBUS/RAM,RAMADR/XR#,A/@1,LOAD VMA" +VMA_[]+[] "AD/A+B,DEST/PASS,A/@1,B/@2,LOAD VMA" + +NEXT [] PHYSICAL WRITE "AD/A+B,A/ONE,B/@1,DEST/AD,HOLD LEFT,LOAD VMA, VMA PHYSICAL, START WRITE" + +;MACROS TO LOAD A 2901 REGISTER WITH VMA FLAG BITS +[]_VMA FLAGS "AD/45,DEST/AD,B/@1,DBM/#,DBUS/DBM,RSRC/D0,A/MASK" +[]_VMA IO READ "[@1]_VMA FLAGS,READ CYCLE/1,IO CYCLE/1,WRITE TEST/0, PHYSICAL/1, FORCE EXEC/1, FORCE USER/0" +[]_VMA IO WRITE "[@1]_VMA FLAGS,WRITE CYCLE/1,IO CYCLE/1,WRITE TEST/0, PHYSICAL/1, FORCE EXEC/1, FORCE USER/0" + + .TOC "MACROS -- TIME CONTROL" + +AC "RAMADR/AC#" +AC[] "RAMADR/AC*#,ACALU/AC+N,ACN/@1" +XR "RAMADR/XR#" +VMA "RAMADR/VMA" +WORK[] "RAMADR/#, WORK/@1" + +2T "T/2T" +3T "T/3T" +4T "T/4T" +5T "T/5T" + + .TOC "MACROS -- SCAD, SC, FE LOGIC" + +LOAD SC "LOADSC/1" +LOAD FE "LOADFE/1" +STEP SC "SCAD/A-1,SCADA/SC,LOAD SC,SKIP/SC" +SHIFT "SCAD/A+B,SCADA/S#,SCADB/FE,S#/1, LOAD FE, MULTI SHIFT/1" + +SC_SC-1 "SCAD/A-1,SCADA/SC,LOAD SC" +SC_SHIFT "SCAD/A+B,SCADA/S#,S#/0,SCADB/SHIFT,LOAD SC" +SC_SHIFT-1 "SCAD/A+B,SCADA/S#,S#/1777,SCADB/SHIFT,LOAD SC" +SC_SHIFT-2 "SCAD/A+B,SCADA/S#,S#/1776,SCADB/SHIFT,LOAD SC" +SC_-SHIFT "SCAD/A-B,SCADA/S#,S#/0000,SCADB/SHIFT,LOAD SC" +SC_-SHIFT-1 "SCAD/A-B,SCADA/S#,SCADB/SHIFT,S#/1777,LOAD SC" +SC_-SHIFT-2 "SCAD/A-B,SCADA/S#,SCADB/SHIFT,S#/1776,LOAD SC" +SC_SC-EXP "SCAD/A-B,SCADA/SC,SCADB/EXP,LOAD SC" +SC_SC-EXP-1 "SCAD/A-B-1,SCADA/SC,SCADB/EXP,LOAD SC" +SC_SC-FE-1 "SCAD/A-B-1,SCADA/SC,SCADB/FE,LOAD SC" +SC_SC-FE "SCAD/A-B,SCADA/SC,SCADB/FE,LOAD SC" +SC_EXP "SCAD/A+B,SCADA/S#,S#/0,SCADB/EXP,LOAD SC" +SC_S#-FE "SCAD/A-B,SCADA/S#,SCADB/FE,LOAD SC" +SC_FE+S# "SCAD/A+B,SCADA/S#,SCADB/FE,LOAD SC" +SC_FE "SCAD/A.OR.B,SCADA/S#,S#/0,SCADB/FE,LOAD SC" +SC_S# "SCAD/A,SCADA/S#,LOAD SC" + + +SC_36. "SC_S#,S#/36." +SC_35. "SC_S#,S#/35." +SC_34. "SC_S#,S#/34." +SC_28. "SC_S#,S#/28." +SC_27. "SC_S#,S#/27." +SC_26. "SC_S#,S#/26." +SC_24. "SC_S#,S#/24." +SC_22. "SC_S#,S#/22." +SC_20. "SC_S#,S#/20." +SC_19. "SC_S#,S#/19." +SC_14. "SC_S#,S#/14." +SC_11. "SC_S#,S#/11." +SC_9. "SC_S#,S#/9." +SC_8. "SC_S#,S#/8." +SC_7 "SC_S#,S#/7" +SC_6 "SC_S#,S#/6" +SC_5 "SC_S#,S#/5" +SC_4 "SC_S#,S#/4" +SC_3 "SC_S#,S#/3" +SC_2 "SC_S#,S#/2" +SC_1 "SC_S#,S#/1" +SC_0 "SC_S#,S#/0." +SC_-1 "SC_S#,S#/1777" +SC_-2 "SC_S#,S#/1776" + +FE_-FE "SCAD/A-B,SCADA/S#,S#/0,SCADB/FE,LOAD FE" +FE_-FE-1 "SCAD/A-B,SCADA/S#,S#/1777,SCADB/FE,LOAD FE" +FE_FE-19 "SCAD/A+B,SCADB/FE,SCADA/S#,S#/1550,LOAD FE" +FE_-FE+S# "SCAD/A-B,SCADA/S#,SCADB/FE,LOAD FE" +FE_FE+SC "SCAD/A+B,SCADA/SC,SCADB/FE, LOAD FE" +FE_FE.AND.S# "SCAD/A.AND.B,SCADA/S#,SCADB/FE, LOAD FE" +FE_P "SCAD/A,SCADA/BYTE1, LOAD FE" +FE_S "SCAD/A+B, SCADA/S#, S#/0 ,SCADB/SIZE, LOAD FE" +FE_S+2 "SCAD/A+B, SCADA/S#, S#/20, SCADB/SIZE, LOAD FE" +FE_-S-20 "SCAD/A-B,SCADA/S#,S#/1760,SCADB/SIZE, LOAD FE" +FE_-S-10 "SCAD/A-B,SCADA/S#,S#/1770,SCADB/SIZE, LOAD FE" +FE_S# "SCAD/A,SCADA/S#,LOAD FE" +FE_S#-FE "SCAD/A-B,SCADA/S#,SCADB/FE,LOAD FE" +FE_-2 "FE_S#,S#/1776" +FE_-12. "FE_S#,S#/1764" +FE_0 "FE_S#,S#/0" +FE_-1 "FE_S#,S#/1777" +FE_FE+1 "SCAD/A+B,SCADA/S#,SCADB/FE,S#/1,LOAD FE" +FE_FE+2 "SCAD/A+B,SCADA/S#,SCADB/FE,S#/2,LOAD FE" +FE_FE+10 "SCAD/A+B,SCADA/S#,SCADB/FE,S#/10,LOAD FE" +FE_FE-1 "SCAD/A+B,SCADA/S#,SCADB/FE,S#/1777,LOAD FE" +FE_FE+4 "SCAD/A+B,SCADA/S#,SCADB/FE,S#/4,LOAD FE" +FE_EXP "SCAD/A+B,SCADA/S#,S#/0,SCADB/EXP,LOAD FE" +FE_SC+EXP "SCAD/A+B,SCADA/SC,SCADB/EXP,LOAD FE" +FE_SC-EXP "SCAD/A-B,SCADA/SC,SCADB/EXP,LOAD FE" +FE_FE+P "SCAD/A+B,SCADA/BYTE1,SCADB/FE, LOAD FE" +FE_FE-200 "SCAD/A+B,SCADA/S#,S#/1600,SCADB/FE,LOAD FE" +FE_-FE+200 "SCAD/A-B,SCADA/S#,S#/200,SCADB/FE,LOAD FE" +FE_FE+S# "SCAD/A+B,SCADA/S#,SCADB/FE,LOAD FE" + + +GEN 17-FE "SCAD/A-B,SCADA/S#,S#/210,SCADB/FE" + + .TOC "MACROS -- DATA PATH FIELD CONTROL" + +HOLD LEFT "CLKL/0,GENL/0" +ADL PARITY "GENL/1" +CHK PARITY L "CHKL/1" + +HOLD RIGHT "CLKR/0,GENR/0" +ADR PARITY "GENR/1" +CHK PARITY R "CHKR/1" + +AD PARITY "AD PARITY OK/1" +CHK PARITY "CHKL/1,CHKR/1" +BAD PARITY "CHKL/0,CHKR/0" + +INH CRY18 "SPEC/INHCRY18" + + .TOC "MACROS -- SHIFT PATH CONTROL" + +ASH "SHSTYLE/NORM" ;ASH SHIFT +LSH "SHSTYLE/NORM" ;LSH SHIFT (SAME HARDWARE AS ASH BUT + ; BITS -2 AND -1 ARE PRESET TO ZERO) +ROT "SHSTYLE/ROT" +LSHC "SHSTYLE/LSHC" +ASHC "SHSTYLE/ASHC" +ROTC "SHSTYLE/ROTC" +ONES "SHSTYLE/ONES" ;SHIFT IN 1 BITS +DIV "SHSTYLE/DIV" ;SPECIAL PATH FOR DIVIDE (LIKE ROTC BUT + ; COMPLEMENT BIT AS IT GOES AROUND) + + .TOC "MACROS -- SPECIAL FUNCTIONS" + +LOAD IR "SPEC/LOADIR" ;LOAD INSTRUCTION REG FROM + ; DBUS0-DBUS8, LOAD AC# FROM + ; DBUS9-DBUS12 + ; UPDATE LAST-INST-PUBLIC PC FLAG +LOAD INST "SPEC/LDINST" +LOAD INST EA "SPEC/LOADXR,PXCT/CURRENT" +LOAD BYTE EA "SPEC/LOADXR,PXCT/E2" +LOAD IND EA "SPEC/LOADXR,PXCT/E1" +LOAD SRC EA "SPEC/LOADXR,PXCT/BIS-SRC-EA" +LOAD DST EA "SPEC/LOADXR,PXCT/BIS-DST-EA" +ADD .25 "CRY38/1" ;GENERATE CARRY IN TO BIT 37 +CALL [] "CALL/1,J/@1" ;CALL A SUBROUTINE +LOAD PXCT "SPEC/LDPXCT" ;LOAD PXCT FLAGS IF EXEC MODE +TURN OFF PXCT "SPEC/PXCT OFF" +LOAD PAGE TABLE "SPEC/LDPAGE" +LOAD AC BLOCKS "SPEC/LDACBLK" +SWEEP "SPEC/SWEEP,PHYSICAL/1" +CLRCSH "SPEC/CLRCSH,PHYSICAL/1" +LOAD PI "SPEC/LDPI" +SET HALT "SPEC/#,#/74" +CLEAR CONTINUE "SPEC/#,#/40" +CLEAR EXECUTE "SPEC/#,#/20" +CLEAR RUN "SPEC/#,#/10" +UNHALT "SPEC/#,#/62" +SET APR ENABLES "SPEC/APR EN" +ABORT MEM CYCLE "DBUS/DBM,RAMADR/VMA,DBM/MEM,AD/ZERO,SPEC/MEMCLR,LOAD VMA" +CLR IO BUSY "SPEC/CLR IO BUSY" +CLR IO LATCH "SPEC/CLR IO LATCH" + + .TOC "MACROS -- PC FLAGS" + +CHANGE FLAGS "SPEC/FLAGS" + +SET AROV "CHANGE FLAGS, HOLD USER/1, SETOV/1, TRAP1/1" +SET FOV "CHANGE FLAGS, HOLD USER/1, SETFOV/1, TRAP1/1" +SET NO DIVIDE "CHANGE FLAGS, HOLD USER/1, SETOV/1, SETNDV/1, TRAP1/1" +SET FL NO DIVIDE "SET NO DIVIDE, SETFOV/1" + +ASH AROV "SPEC/ASHOV" +SET FPD "CHANGE FLAGS, HOLD USER/1, SETFPD/1" +CLR FPD "CHANGE FLAGS, HOLD USER/1, CLRFPD/1" + +SET PDL OV "CHANGE FLAGS, HOLD USER/1, TRAP2/1" +SET TRAP1 "CHANGE FLAGS, HOLD USER/1, TRAP1/1" +SET TRAP3 "CHANGE FLAGS, HOLD USER/1, TRAP1/1, TRAP2/1" + +LOAD PCU "CHANGE FLAGS, LD PCU/1" +UPDATE USER "CHANGE FLAGS, HOLD USER/1" +LEAVE USER "CHANGE FLAGS, HOLD USER/0" + +JFCL FLAGS "CHANGE FLAGS, HOLD USER/1, JFCLFLG/1" + +LOAD FLAGS "CHANGE FLAGS, LD FLAGS/1" +EXP TEST "SPEC/EXPTST" +AD FLAGS "CHANGE FLAGS, ADFLGS/1, HOLD USER/1" + +NO DIVIDE "SET NO DIVIDE, J/NIDISP" +FL NO DIVIDE "SET FL NO DIVIDE, J/NIDISP" + + .TOC "MACROS -- PAGE FAIL FLAGS" + +STATE_[] "[FLG]_#,STATE/@1,HOLD LEFT" +END STATE "[FLG]_0, HOLD LEFT" + +END BLT "END STATE" +END MAP "END STATE" + + .TOC "MACROS -- SINGLE SKIPS" + ;SKIPS IF: +SKIP IF AC0 "SKIP/AC0" ;THE AC NUMBER IS ZERO +SKIP DP0 "SKIP/DP0" ;DP BIT 0=1 +SKIP DP18 "SKIP/DP18" ;DP BIT 18=1 +SKIP AD.EQ.0 "SKIP/ADEQ0,DT/3T" ;ADDER OUTPUT IS ZERO +SKIP AD.LE.0 "SKIP/LE,DT/3T" ;ADDER OUTPUT IS LESS THAN OR EQUAL + ; TO ZERO. +SKIP ADL.LE.0 "SKIP/LLE,DT/3T" ;ADDER LEFT IS LESS THAN OR EQUAL + ; TO ZERO. +SKIP FPD "SKIP/FPD" ;FIRST-PART-DONE PC FLAG IS SET +SKIP KERNEL "SKIP/KERNEL" ;USER=0 +SKIP IO LEGAL "SKIP/IOLGL" ;USER=0 OR USER IOT=1 +SKIP CRY0 "SKIP/CRY0" ;ADDER BIT CRY0=1 (NOT PC FLAG BIT) +SKIP CRY1 "SKIP/CRY1" ;ADDER BIT CRY1=1 (NOT PC FLAG BIT) +SKIP CRY2 "SKIP/CRY2,DT/3T" ;ADDER BIT CRY2=1 +SKIP JFCL "SKIP/JFCL" ;IF JFCL SHOULD JUMP +SKIP ADL.EQ.0 "SKIP/ADLEQ0" ;ALU BITS -2 TO 17 = 0 +SKIP ADR.EQ.0 "SKIP/ADREQ0" ;ALU BITS 18-35 = 0 +SKIP IRPT "SKIP/INT" ;INTERRUPT IS PENDING +SKIP -1MS "SKIP/-1 MS" ;DON'T SKIP IF 1MS TIMER HAS EXPIRED. +SKIP AC REF "SKIP/ACREF" ;VMA IS 0-17 +SKIP EXECUTE "SKIP/EXECUTE" ;CONSOLE EXECUTE +TXXX TEST "SKIP/TXXX" ;TEST INSTRUCTION SHOULD SKIP + + .TOC "MACROS -- SPECIAL DISPATCH MACROS" + +NEXT INST "DISP/NICOND,SPEC/NICOND,J/NICOND" +NEXT INST FETCH "DISP/NICOND,SPEC/NICOND,J/NICOND-FETCH" +EA MODE DISP "DISP/EAMODE,RAMADR/XR#" +AREAD "DISP/AREAD,WAIT/1,AREAD/1,MEM/1,J/0" +B DISP "DISP/BDISP" +BWRITE DISP "B DISP,MEM/1,BWRITE/1,WRITE CYCLE/1,J/BWRITE" +INST DISP "DISP/DROM,J/0" +EXIT "BWRITE DISP,SPEC/0, WRITE TEST/1" +AD FLAGS EXIT "BWRITE DISP, WRITE TEST/0, AD FLAGS" +FL-EXIT "WRITE CYCLE/1,WRITE TEST/1,MEM/1,BWRITE/1,B DISP,J/FL-BWRITE" +TEST DISP "B DISP,J/TEST-TABLE" +SKIP-COMP DISP "B DISP,J/SKIP-COMP-TABLE" +JUMP DISP "B DISP,J/JUMP-TABLE" +DONE "VMA_[PC],LOAD VMA, FETCH, NEXT INST FETCH" +JUMPA "[PC]_[AR],HOLD LEFT,LOAD VMA,FETCH,NEXT INST FETCH" +UUO "[HR]_[HR].AND.#,#/777740,HOLD RIGHT,J/UUOGO" +LUUO "[AR]_0 XWD [40], J/LUUO1" +PAGE FAIL TRAP "TL [FLG], FLG.PI/1, J/PFT" +TAKE INTERRUPT "[FLG]_[FLG].OR.#,FLG.PI/1,HOLD RIGHT,J/PI" +TAKE 1-PROCEED TRAP "[FLG]_[FLG].AND.NOT.#,FLG.1PROC/1,FLG.2PROC/1,HOLD RIGHT,J/1PROC-TRAP" +INTERRUPT TRAP "WORK[SV.AR]_[AR], J/ITRAP" +MUL DISP "DISP/MUL" +DIV DISP "DISP/DIV" +BYTE DISP "DISP/BYTE, DT/3T" +SCAD DISP "DISP/SCAD0" ;SKIP (2'S WEIGHT) IS SCAD IS MINUS +RETURN [] "DISP/RETURN,J/@1" +PI DISP "DISP/PI" +NORM DISP "DISP/NORM,DT/3T" +DISMISS "TR [PI], #/077400, CALL [JEN1],DT/3T" +CALL LOAD PI "[T0]_[PI] SWAP, CALL [LDPI2]" +HALT [] "AD/47,DEST/AD,B/T1,DBM/#,DBUS/DBM,HALT/@1,RSRC/DA,A/MASK, J/HALTED" +CLEANUP DISP "READ [FLG], DBUS/DP, DISP/DP, 3T, J/CLEANUP" + + .TOC "DISPATCH ROM MACROS" + .DCODE + +;"A FIELD" MACROS SAY HOW TO FETCH ARGUMENTS + +I "I/1" +I-PF "I/1,VMA/0,READ/1" +R "A/READ,READ/1" +R-PF "A/RD-PF,READ/1" +W "A/WRITE,TEST/1" +RW "A/READ,TEST/1,READ/1" +IW "I/1,TEST/1" ;IMMED WHICH STORE IN E. (SETZM, ETC.) +IR "I/1,READ/1" ;START READ A GO TO EXECUTE CODE +DBL R "A/DREAD,READ/1" ;AR!ARX _ E!E+1 +DBL AC "A/DBLAC" +SH "A/SHIFT,VMA/0,READ/1" +SHC "A/DSHIFT,VMA/0,READ/1" +FL-R "A/FP,READ/1" ;FLOATING POINT READ +FL-RW "A/FP,READ/1,TEST/1" +FL-I "A/FPI,READ/0" ;FLOATING POINT IMMEDIATE +DBL FL-R "A/DFP,READ/1" +IOT "A/IOT" ;CHECK FOR IO LEGAL + +;"B FIELD" MACROS SAY HOW TO STORE RESULTS + +AC "B/AC" +M "B/MEM,TEST/1,COND FUNC/1" +B "B/BOTH,TEST/1,COND FUNC/1" +S "B/SELF,TEST/1,COND FUNC/1" +DAC "B/DBLAC" +DBL B "B/DBLB,TEST/1,COND FUNC/1" +FL-AC "FL-B/AC" ;FLOATING POINT +FL-MEM "FL-B/MEM,TEST/1,COND FUNC/1" ;FLOATING POINT TO MEMORY +FL-BOTH "FL-B/BOTH,TEST/1,COND FUNC/1" ;FLOATING POINT TO BOTH +ROUND "ROUND/1" ;FLOATING POINT ROUNDED + + +;CONTROL BITS +W TEST "TEST/1" +AC DISP "ACDISP/1" + .UCODE diff --git a/src/kshack/pagef.10 b/src/kshack/pagef.10 new file mode 100755 index 00000000..46cbcfb0 --- /dev/null +++ b/src/kshack/pagef.10 @@ -0,0 +1,787 @@ +;;;-*-Fundamental-*- + + .NOBIN +.TOC "PAGE FAIL REFIL LOGIC" + +.IFNOT/ITS + +;WHEN THE CPU CAN NOT COMPLETE A MEMORY REFERENCE BECAUSE THE PAGE +; TABLE DOES NOT CONTAIN VALID INFORMATION FOR THE VIRTUAL PAGE INVOLVED +; THE HARDWARE CALLS THIS ROUTINE TO RELOAD THE HARDWARE PAGE TABLE. +; +;THIS CODE WILL EITHER DO THE RELOAD OR GENERATE A PAGE FAIL FOR THE +; SOFTWARE. THE INFORMATION LOADED CONSISTS OF THE PHYSICAL PAGE NUMBER, +; THE CACHE ENABLE BIT AND THE WRITE ENABLE BIT. + +;THIS LOGIC USES MANY VARIABLES. THEY ARE DESCRIBED BRIEFLY HERE: + +;THING WHERE KEPT USE +;OLD VMA WORKSPACE WORD 210 SAVES VMA +;OLD AR WORKSPACE WORD 211 SAVES AR +;OLD ARX WORKSPACE WORD 212 SAVES ARX +;OLD BR WORKSPACE WORD 213 SAVES BR +;OLD BRX WORKSPACE WORD 214 SAVES BRX +;KL PAGING BIT EBR BIT 1 (IN 2901) INDICATES KL STYLE (TOPS-20) PAGING +; INSTEAD OF KI STYLE (TOPS-10 AND DIAGNOSTIC) +; MODE PAGING +;W BIT FLG BIT 4 PAGE CAN BE WRITTEN +;C BIT FLG BIT 6 DATA IN THIS PAGE MAY BE PUT +; INTO CACHE +;PI CYCLE FLG BIT 5 STORING OLD PC DURING PI +;MAP FLAG FLG BIT 18 MAP INSTRUCTION IN PROGRESS +;CLEANUP CODE FLG BITS 32-35 WHAT TO DO SO INSTRUCTION MAY BE +; RESTARTED +;SPT BASE WORKSPACE WORD 215 ADDRESS OF SHARED-POINTER-TABLE +;CST BASE WORKSPACE WORD 216 ADDRESS OF CORE-STATUS-TABLE +;CST MASK WORKSPACE WORD 217 BITS TO KEEP ON CST UPDATE +;CST DATA (PUR) WORKSPACE WORD 220 BITS TO SET ON CST UPDATE +;PAGE TABLE ADDRESS AR WHERE THIS PAGE TABLE IS LOCATED +;PHYSICAL PAGE # (PPN) AR RESULT OF THIS PROCESS +;CST ENTRY AR CORE STATUS TABLE ENTRY +;SPT ENTRY AR WORD FROM SPT +;PAGE TABLE ENTRY AR WORD FROM PT +;PAGE NUMBER BR INDEX INTO CURENT PAGE TABLE +;PAGE FAIL WORD BRX WHAT HAPPENED (ALSO MAP RESULT) + +; +; +; +; KL10 PAGING - WORD FORMATS +; +;Section Pointer +; +;The section pointer is found in the user or exec section table. +;(Part of UPT or EPT.) +; +;Section pointer provides (via the SPT) the physical address of +;the PAGE TABLE for the given section. +; +; Code: 0 No-access (trap) +; 1 Immediate +; 2 Share +; 3 Indirect +; 4-7 Unused, reserved +; +; 0 1 2 3 4 5 6 18 35 +; +----+-+-+-+-+---------+-------------------------+ +; !CODE!P!W! !C!/////////! PAGE TABLE IDENTIFIER ! +; !010 ! ! ! ! !/////////! (SPT INDEX) ! +; +----+-+-+-+-+---------+-------------------------+ +; +; NORMAL SECTION POINTER (Code = 2) +; +; 0 2 3 4 5 6 9 18 35 +; +----+-+-+-+-+---+-----------+------------------------+ +; !CODE!P!W! !C!///!SECTION !SECTION TABLE IDENTIFIER! +; !011 ! ! ! ! !///!TABLE INDEX! (SPT INDEX) ! +; +----+-+-+-+-+---+-----------+------------------------+ +; +; INDIRECT SECTION POINTER (Code = 3) + +;PAGE POINTERS +; +;FOUND IN PAGE TABLES +; +; 0 1 2 3 4 5 6 12 35 +; +----+-+-+-+-+----+------------------------------+ +; !CODE!P!W! !C!////! PHYSICAL ADDRESS OF PAGE ! +; !001 ! ! ! ! !////! ! +; +----+-+-+-+-+----+------------------------------+ +; +; IMMEDIATE POINTER (code field = 1) +; +; B12-35 give PHYSICAL ADDRESS OF PAGE +; if B12-17 >< 0, page not in core-trap +; if B12-17 = 0, B23-35 give CORE PAGE +; NUMBER of page, B18-22 MBZ +; +; +; +; +; +; 0 2 3 6 18 35 +; +-----+-------+---------+------------------------+ +; !CODE !SAME AS!/////////! SPT INDEX ! +; !010 ! IMMED.!/////////! ! +; +-----+-------+---------+------------------------+ +; +; SHARED POINTER (code field = 2) +; +; B18-35 Give SPT INDEX (SPTX). SPTX + SPT BASE +; ADDRESS = physical core address of word +; holding physical address of page. + +; 0 1 2 3 6 9 17 18 35 +; +----+--------+---+-------+----------------------+ +; !CODE!SAME AS !///! PAGE ! PAGE TABLE IDENTIFIER! +; !011 ! IMMED. !///!NUMBER ! (SPT INDEX) ! +; +----+--------+---+-------+----------------------+ +; +; INDIRECT POINTER (code field = 3) +; +; This pointer type causes another pointer to be fetched +; and interpreted. The new pointer is found in word N +; (B9-17) of the page addressed by C(SPT + SPTX). +; +; +; +; SPT ENTRY +; +; Found in the SPT, i.e., when fetching C(SPT +SPTX) +; +; 12 35 +; +--------------------+---------------------------+ +; !////////////////////! PHYSICAL ADDRESS OF PAGE ! +; !////////////////////! OR PAGE TABLE ! +; +--------------------+---------------------------+ +; +; B12-35 Give PHYSICAL ADDRESS of page. +; +; The base address (physical core address) of the SPT +; resides in one AC of the reserved AC block. + +;PHYSICAL STORAGE ADDRESS +; +;Found in B12-35 of IMMEDIATE POINTERS and SPT ENTRIES. +; +; 12 17 18 23 35 +; +---------+----+-----------------+ +; ! !MBZ ! CORE PAGE NUMBER! +; ! ! ! IF B12-17 = 0 ! +; +---------+----+-----------------+ +; +; If B12-17 = 0, then B23-35 are CORE PAGE NUMBER (i.e., +; B14-26 of physical core address) of page and B18-22 +; MBZ. If B12-17 >< 0, then address is not core and +; pager traps. +; +; +; +;CORE STATUS TABLE ENTRY +; +;Found when fetching C(CBR + CORE PAGENO) +; +; 0 5 32 34 35 +; +-------+-------------------------------+------+-+ +; ! CODE ! ! !M! +; +-------+-------------------------------+------+-+ +; +; B0-5 are code field: +; +; 0 - unavailable, trap +; +; 1-77 - available +; +; +; +; B32-34 reserved for future hardware specification. +; +; B35 is "modified" bit, set on any write ref to page. + +;QUANTITIES IN HARDWARE REGISTERS +; +;SPT SPT Base Register +; +; 14 35 +; +--------------------------------+ +; ! PHYSICAL CORE WORD ADDRESS ! +; +--------------------------------+ +; +;CBR CST Base Register +; +; 14 35 +; +--------------------------------+ +; ! PHYSICAL CORE WORD ADDRESS ! +; +--------------------------------+ +; +;CSTMSK CST Update Mask +; +; 0 32 35 +; +------------------------------------------+---+-+ +; ! MASK !111!1! +; +------------------------------------------+---+-+ +; +; ANDed with CST word during update +; +;(B32-35 must be all 1's to preserve existing CST information) +; +;CSTDATA CST Update Data +; +; 0 32 34 35 +; +------------------------------------------+---+-+ +; ! DATA !000!0! +; +------------------------------------------+---+-+ +; +; IORed with CST word during update +; +;(B32-35 must be all 0's to preserve existing CST information) +; +;All unspecified bits and fields are reserved for future +;specification by DEC. +; + + .BIN + + .DCODE +257: IOT, AC, J/MAP + .UCODE + +1553: +MAP: [AR]_[AR].OR.#, ;ASSUME PHYSICAL REF + #/160000, ;FAKE ANSWER (Set Accessible, Writable, + HOLD RIGHT ;and "Software".) + [BRX]_VMA ;PUT VMA AND FLAGS IN BRX + [BRX]_[BRX].AND.#, ;JUST KEEP USER BIT + #/400000, HOLD RIGHT ; .. + WORK[SV.VMA]_[BRX] ;SAVE IN WORKSPACE + [BR]_WORK[APR] ;GET APR FLAGS + TR [BR], #/030000 ;PAGING ENABLED? +=0 STATE_[MAP], J/PFMAP ;YES--DO REAL MAP + AC_[AR], NEXT INST ;NO--RETURN VIRTUAL ADDRESS +;HARDWARE COMES HERE ON PAGE TABLE NOT VALID (OR INTERRUPT) WHEN +; STARTING A MEMORY REFERENCE. MICOWORD ADDRESS OF INSTRUCTION DOING +; MEM WAIT IS SAVED ON THE STACK. +3777: +PAGE-FAIL: + WORK[SV.AR]_[AR] +ITRAP: WORK[SV.BRX]_[BRX] + [BRX]_VMA + WORK[SV.VMA]_[BRX] + WORK[SV.ARX]_[ARX], + SKIP IRPT ;SEE IF INTERRUPT (SAVE DISPATCH) +=0000 +PFD: DBM/PF DISP, DBUS/DBM, ;BRING CODE TO 2901'S + AD/D, DEST/PASS, 4T, ;PUT ON DP 18-21 + DISP/DP LEFT, J/PFD ;DISPATCH ON IT +=0001 ;(1) INTERRUPT + WORK[SV.BR]_[BR], J/PFPI1 +=0011 ;(3) BAD DATA FROM MEMORY + [BRX]_IO DATA, ;GET THE BAD DATA + AD PARITY OK/0, ; DO NOT LOOK AT PARITY + J/BADDATA ;SAVE IN AC BLK 7 +=0101 ;(5) NXM ERROR + [BRX]_[370000] XWD 0, J/HARD +=0111 ;(7) NXM & BAD DATA + [BRX]_[370000] XWD 0, J/HARD +=1000 ;(10) WRITE VIOLATION + WORK[SV.BR]_[BR], J/PFMAP +=1010 ;(12) PAGE NOT VALID + WORK[SV.BR]_[BR], J/PFMAP +=1011 ;(13) EXEC/USER MISMATCH + WORK[SV.BR]_[BR], J/PFMAP += + +BADDATA: + WORK[BADW0]_[BRX] ;SAVE BAD WORD + WORK[BADW1]_[BRX] ;AGAIN + [BRX]_[360000] XWD 0, J/HARD + +;WE HAVE SAVED AR, ARX, BR AND BRX. WE MERGE IN HERE FROM MAP +; INSTRUCTION, SAVE THE VMA AND START THE PAGE FAIL WORD. +PFMAP: ABORT MEM CYCLE ;CLEAR PAGE FAIL + [FLG]_[FLG].OR.#, ;PRESET W AND C TO 1 + FLG.W/1, FLG.C/1, ;BITS INVOLVED + HOLD RIGHT ;LEAVE RH ALONE + TL [BRX], WRITE TEST/1 ;IS THIS A WRITE TEST? +=0 [BRX]_[BRX].OR.#, + #/10000, + HOLD RIGHT ;YES--TURN INTO WRITE REF + [BRX]_[BRX].AND.#, ;START PAGE FAIL WORD + #/411000, ;SAVE 3 INTERESTING BITS + HOLD RIGHT ;SAVE VIRTUAL ADDRESS + ;USER ADDR (400000) + ;WRITE REF (010000) + ;PAGED REF (001000) + [BRX]_[BRX].XOR.#, ;FIX BIT 8 + #/1000, HOLD RIGHT + [BR]_[BRX], ;COPY VIRTUAL ADDRESS + SC_7 ;PREPARE TO SHIFT 9 PLACES +=0 +PF25: [BR]_[BR]*.5, ;RIGHT ADJUST PAGE # + STEP SC, ;COUNT SHIFT STEPS + J/PF25 ;LOOP FOR 9 + [BR]_[BR].AND.# CLR LH, ;MASK TO 9 BITS + #/777 ; .. + TL [EBR], ;KI MODE REFILL? + #/40 ;FLAG BIT +=0 READ [BRX], ;USER REF? (KL MODE) + SKIP DP0, ; .. + J/PF30 ;CONTINUE AT PF30 + [ARX]_[BR]*.5, ;KI10 MODE REFILL + J/KIFILL ;GO HANDLE EASY CASE + +;HERE IN TOPS-20 MODE +;PICK UP CORRECT SECTION POINTER +=0 +PF30: [ARX]_WORK[PTA.E], ;EXEC MODE + SKIP AD.EQ.0, 4T, ;SEE IF VALID + J/PF35 ;CONTINUE BELOW + [ARX]_WORK[PTA.U], ;USER MODE + SKIP AD.EQ.0, 4T ;SEE IF VALID +=0 VMA_[ARX]+[BR], ;POINTER VALID + VMA PHYSICAL READ, ;START MEMORY + J/PF77 ;CONTINUE BELOW + [AR]_[UBR]+#, 3T, ;USER MODE + #/540, ;OFFSET TO UPT + J/PF40 ;GO GET POINTER + +=0 +PF35: VMA_[ARX]+[BR], ;POINTER VALID + VMA PHYSICAL READ, ;START MEMORY + J/PF77 ;CONTINUE BELOW + [AR]_[EBR]+#, 3T, ;EXEC MODE + #/540 ;OFFSET TO EPT +PF40: VMA_[AR], ;LOAD THE VMA + START READ, ;START THE MEMORY CRANKING + VMA PHYSICAL ;ABSOLUTE ADDRESS + MEM READ, ;WAIT FOR MEMORY + [AR]_MEM ;POINT POINTER IN AR +;LOOK AT SECTION POINTER AND DISPATCH ON TYPE +=000 +PF45: SC_7, ;FETCH SECTION 0 POINTER + CALL [SETPTR] ;FIGURE OUT POINTER TYPE +SECIMM: TL [AR], ;IMMEDIATE POINTER + #/77, ;TEST FOR 12-17 = 0 + J/PF50 ;CONTINUE AT PF50 + [AR]_[AR]+WORK[SBR], ;SHARED SECTION + J/SECSHR ;GO FETCH POINTER FROM SPT + [AR]_[AR]+WORK[SBR], ;INDIRECT SECTION POINTER + CALL [RDPT] ;GO FETCH SPT ENTRY +=111 TL [AR], ;12 TO 17 = 0? + #/77 ; .. += +=0 PAGE FAIL TRAP ;NO + [AR]_[AR]*2, ;FIRST SHIFT + STEP SC ;SC WAS LOADED AT PF45 +=0*0 +PF60: [AR]_[AR]*2, ;CONVERT TO ADDRESS OF + STEP SC, ; SECTION TABLE + J/PF60 + CALL [RDPT] ;READ SECTION TABLE +=1*1 J/PF45 ;TRY AGAIN += + +;HERE FOR SHARED SECTION. AR GETS THE ADDRESS OF PAGE TABLE +=0** +SECSHR: CALL [RDPT] ;READ WORD FROM SPT + TL [AR], #/77 ;TEST FOR BITS 12-17 = 0 + +;HERE WITH ADDRESS OF PAGE TABLE IN AR AND SKIP ON +; BITS 12 THRU 17 EQUAL TO ZERO +=0 +PF50: PAGE FAIL TRAP ;BITS 12-17 .NE. 0 + [ARX]_[AR].AND.# CLR LH, ;PAGE NUMBER OF PAGE TABLE + #/3777 ;11 BIT PHYSICAL PAGE # +=0* [AR]_[ARX], ;COPY ADDRESS + CALL [UPCST] ;UPDATE CST0 +PF70: [AR]_[AR].OR.WORK[PUR] ;PUT IN NEW AGE AND + ; USE BITS +=0** START NO TEST WRITE, ;START MEMORY WRITE + CALL [IBPX] ;GO STORE IN MEMORY + SC_7 ;THIS CAN BE BUMMED +=0 +PF75: [ARX]_[ARX]*2, ;CONVERT PAGE NUMBER TO + STEP SC, ; PAGE ADDRESS + J/PF75 ;LOOP OVER 9 STEPS + +;WE NOW HAVE THE ADDRESS OF THE PAGE TABLE ENTRY. GO +; READ IT AND START ANALYSIS + +;IF WE ARE HERE FOR THE FIRST TIME FOR THE USER OR EXEC SAVE THE +; ADDRESS OF THE PAGE TABLE IN PTA.E OR PTA.U SO THAT WE DO NOT +; HAVE TO DO THE SECTION LOOKUP EVERY TIME. + READ [BRX], SKIP DP0 ;USER OR EXEC REF? +=000 [AR]_WORK[PTA.E], ;EXEC MODE + SKIP AD.EQ.0, 4T, ;SEE IF SET YET + CALL [SHDREM] ;SHOULD WE REMEMBER PTR + [AR]_WORK[PTA.U], ;USER MODE + SKIP AD.EQ.0, 4T, ;SEE IF SET YET + CALL [SHDREM] ;SHOULD WE REMEMBER PTR + WORK[PTA.E]_[ARX], ;SAVE FOR EXEC + J/PF76 ;CONTINUE BELOW + WORK[PTA.U]_[ARX], ;SAVE FOR USER + J/PF76 ;CONTINUE BELOW +=111 +PF76: VMA_[ARX]+[BR], ;READ PAGE POINTER + START READ, + VMA PHYSICAL += +=00 +PF77: MEM READ, ;START ANALYSIS OF POINTER + [AR]_MEM, + CALL [SETPTR] +PTRIMM: TL [AR], ;IMMEDIATE POINTER + #/77, ;CHECK FOR BITS 0-5 + J/PF80 ;GO TO PF80 + [AR]_[AR]+WORK[SBR], ;SHARED POINTER + J/PTRSHR ;GO TO READ SPT + +;INDIRECT POINTER. CHANGE PAGE # AND LOOK FOR PAGE TABLE +PTRIND: [BR]_[AR] SWAP, ;PUT IN RIGHT HALF + SKIP/-1 MS ;DID CLOCK GO OFF +=0 WORK[SV.AR1]_[AR], ;YES--UPDATE CLOCK + J/PFTICK ; .. + [BR]_[BR].AND.# CLR LH, ;UPDATE PAGE # AND RESTART + #/777, ;MASK FOR PAGE # + SKIP IRPT ;SEE IF THIS IS A LOOP +=0 [AR]_[AR].AND.#, ;CHANGE INDIRECT POINTER + #/277000, ; INTO SHARE POINTER + HOLD RIGHT, ; .. + J/PF45 ;GO BACK AND TRY AGAIN + PAGE FAIL TRAP ;POINTER LOOP + +=0** +PTRSHR: CALL [RDPT] ;GO LOOK AT POINTER + TL [AR], ;BITS 12-17 .EQ. 0? + #/77 + +;HERE WITH FINAL POINTER. SKIP IF 12-17 NOT EQUAL TO ZERO +=00 +PF80: PAGE FAIL TRAP ;NO--TAKE A TRAP + [ARX]_[AR].AND.# CLR LH,;SAVE PHYSICAL PAGE # + #/3777, ;MASK TO 13 BITS + CALL [UPCST] ;UPDATE CST0 +;HERE WE HAVE CST ENTRY IN AR, PAGE FAIL WORD IN BRX. GO LOOK +; AT WRITABLE AND WRITTEN BITS +=11 +PF90: [BRX]_[BRX].OR.#, ;TRANSLATION IS VALID + #/100000, HOLD RIGHT ; .. + TL [FLG], FLG.W/1 ;IS THIS PAGE WRITABLE? +=0 [BRX]_[BRX].OR.#, ;YES--INDICATE THAT IN PFW + #/020000, + J/PF100 ;NOT WRITE VIOLATION + TL [BRX], ;IS THIS A WRITE REF? + WRITE TEST/1, WRITE CYCLE/1 +=0 PAGE FAIL TRAP ;WRITE VIOLATION +PF107: [AR]_[AR].OR.WORK[PUR], ;PUT IN NEW AGE + J/PF110 ;GO TO STORE CST ENTRY + +=0* +PFTICK: [AR]_WORK[TIME1], ;UPDATE TIMER + SPEC/CLRCLK, CALL [TOCK] + [AR]_WORK[SV.AR1], ;RESTORE AR + J/PTRIND ;GO TRY AGAIN + +;HERE IF PAGE IS WRITABLE +PF100: TL [BRX], WRITE CYCLE/1 ;IS THIS A WRITE REF? +=0 [AR]_[AR].OR.#, ;YES--SET WRITTEN BIT + #/1, + HOLD LEFT, + J/PF105 + TR [AR], ;NOT WRITE, ALREADY WRITTEN? + #/1 +=0 +PF105: [BRX]_[BRX].OR.#, ;WRITTEN SET BIT + #/040000, ;MARK PAGE AS + HOLD RIGHT, ;WRITABLE + J/PF107 ;STORE CST WORD + [FLG]_[FLG].AND.NOT.#, ;NOT WRITTEN, CAUSE TRAP ON + FLG.W/1, ; WRITE ATTEMPT + HOLD RIGHT, ;ONLY CLEAR LH + J/PF107 +=0** +PF110: START NO TEST WRITE, + CALL [IBPX] ;STORE CST ENTRY + +;HERE WHEN WE HAVE FIGURED OUT PHYSICAL ADDRESS (IN ARX) AND FLAGS +; (IN BRX) RELOAD PAGE TABLE. +PFDONE: TR [FLG], ;MAP INSTRUCTION? + #/400000 +=0 [AR]_[ARX], ;GET PHYSCIAL PAGE # + SC_7, ;PREPARE TO CONVERT TO + J/PF130 ; WORD ADDRESS + [AR]_WORK[SV.VMA],;RESTORE VMA + J/PF120 +=0 +PF130: [AR]_[AR]*2, ;CONVERT TO WORD # + STEP SC, + J/PF130 + [AR]_[AR].AND.#, ;JUST ADDRESS BITS + #/3, + HOLD RIGHT + END MAP ;CLEAR MAP FLAGS + [BRX]_[BRX].OR.#, ;TURN ON THE TRANSLATION + #/100000, ; VALID BIT + HOLD RIGHT ; IN LEFT HALF ONLY + TL [FLG], FLG.C/1 ;CACHE BIT SET? +=0 [BRX]_[BRX].OR.#, ;YES--SET IN MAP WORD + #/002000, HOLD RIGHT ; .. + [BRX]_[BRX].AND.#, ;PRESERVE WORD # + #/777, HOLD LEFT ; IN PAGE FAIL WORD + [AR]_[AR].OR.[BRX], ;COMPLETE MAP INSTRUCTION + EXIT + +PF120: [BR]_[AR] ;COPY PAGE FAIL WORD + [BR]_[AR].AND.NOT.#, ;CLEAR BITS WHICH START A CYCLE + READ CYCLE/1, ; .. + WRITE CYCLE/1, ; .. + WRITE TEST/1, ; .. + HOLD RIGHT ;JUST DO LEFT HALF + VMA_[BR], 3T, ;RESTORE VMA + DP FUNC/1 ;SET USER ACCORDING TO WHAT IT WAS + [ARX]_[ARX].AND.# CLR LH, ;JUST KEEP PAGE # + #/3777 ; .. + [BRX]_[ARX].OR.#, #/400000 ;SET VALID BITS + TL [FLG], FLG.W/1 ;WANT WRITE SET? +=0 [BRX]_[BRX].OR.#, #/040000 ;SET WRITE BIT + TL [FLG], FLG.C/1, ;WANT CACHE SET? + LOAD PAGE TABLE ;LOAD PAGE TABLE ON NEXT + ; MICRO INSTRUCTION +=0 [BRX]_[BRX].OR.#, ;SET CACHE BIT + #/020000, J/PF125 ;CACHE BIT + READ [BRX] ;LOAD PAGE TABLE +PF125: [ARX]_WORK[SV.ARX] + [BR]_WORK[SV.BR] + [BRX]_WORK[SV.BRX] + VMA_[AR], ;MAKE MEM REQUEST + DP FUNC/1, 3T, ;FROM DATA PATH + WAIT/1 ;WAIT FOR PREVIOUS CYCLE TO + ; COMPLETE. (NEED THIS TO + ; START ANOTHER CYCLE) + [AR]_WORK[SV.AR], + RETURN [0] +;SUBROUTINE TO START CST UPDATE +;CALL WITH: +; AR/ PHYSICAL PAGE NUMBER +;RETURN 2 WITH ENTRY IN AR, PAGE FAIL IF AGE TOO SMALL +=0** +UPCST: [AR]_[AR]+WORK[CBR], ;ADDRESS OF CST0 ENTRY + CALL [RDPT] ;READ OLD VALUE + TL [AR], ;0 - 5 = 0? + #/770000 ; .. +=0 [AR]_[AR].AND.WORK[CSTM], ;CLEAR AGE FIELD + RETURN [2] ;AGE IS NOT ZERO + PAGE FAIL TRAP ;AGE TOO SMALL + +;SUBROUTINE TO LOOK AT PAGE POINTER +;CALL WITH POINTER IN AR +;RETURNS 1 IF TYPE 1 +;RETURNS 2 IF TYPE 2 +;RETURNS 3 IF TYPE 3 +;GOES TO PFT IF TYPE 0 OR 4 THRU 7 +SETPTR: [ARX]_[AR].OR.#, ;AND C AND W BITS + #/753777 ; OF ALL POINTERS + [FLG]_[FLG].AND.[ARX], ; .. + HOLD RIGHT ;KEEP IN LH OF FLG + READ [AR], ;TYPE 4,5,6 OR 7? + SKIP DP0 ; .. +=0 TL [AR], ;HERE WE TEST FOR TYPE + #/300000, ; ZERO POINTER + J/STPTR1 ;CHECK AT STPTR1 + PAGE FAIL TRAP ;BAD TYPE +=0 +STPTR1: TL [AR], ;NOT ZERO + #/100000, ;SEPERATE TYPE 2 + J/STPTR2 ; .. + PAGE FAIL TRAP ;TYPE 0 + +=0 +STPTR2: TL [AR], ;SEPERATE TYPE 1 + #/200000, ; AND 3 + J/STPTR3 ; .. + RETURN [2] ;TYPE 2 + +=0 +STPTR3: RETURN [3] ;TYPE 3 + RETURN [1] ;TYPE 1 + +;SUBROUTINE TO FETCH A PAGE POINTER OR CST ENTRY +;CALL WITH ADDRESS IN AR +;RETURN 4 WITH WORD IN AR +; +RDPT: VMA_[AR], ;LOAD THE VMA + START READ, ;START MEM CYCLE + VMA PHYSICAL, ;ABSOLUTE ADDRESS + SKIP IRPT ;CHECK FOR INTERRUPTS +=0 MEM READ, ;NO INTERRUPTS + [AR]_MEM, ;PUT THE DATA INTO AR + RETURN [4] ;AND RETURN + PAGE FAIL TRAP ;INTERRUPT + + +;SUBROUTINE TO SEE IF WE SHOULD REMEMBER AN EXEC SECTION PTR +;CALL WITH SKIP ON ADR.EQ.0 +;RETURNS 2 IF WE SHOULD STORE AND 7 IF WE SHOULD NOT +; +=0 +SHDREM: RETURN [7] ;INDIRECT PTR + [AR]_.NOT.[FLG] ;FLIP BITS + TL [AR], FLG.W/1, FLG.C/1 ;BOTH BITS SET +=0 RETURN [7] ;NO--DON'T STORE + RETURN [2] ;STORE + +;HERE IN KI10 MODE +;BR CONTAINS PAGE # AND ARX CONTAINS PAGE #/2 + +KIFILL: READ [BRX], ;USER REF? + SKIP DP0 ; .. +=0 [BR]-#, ;EXEC--LESS THAN 340? + #/340, ; .. + SKIP DP18, 4T, ; .. + J/KIF10 ;FOLLOW EXEC PATH +KIUPT: [ARX]_[ARX]+[UBR], ;POINTER TO PAGE MAP ENTRY + LOAD VMA, ;PUT ADDRESS IN VMA + VMA PHYSICAL, ;ABSOLUTE ADDRESS + START READ, ;FETCH UPT WORD + J/KIF30 ;JOIN COMMON CODE +=0 +KIF10: [BR]-#, ;EXEC ADDRESS .GE. 340 + #/400, ; SEE IF .GT. 400 + SKIP DP18, 4T, ; .. + J/KIEPT ;LOOK AT KIF20 + [ARX]_[ARX]+#, 3T, ;EXEC ADDRESS .LT. 340 + #/600, ;IN EBR+600 + J/KIEPT ;JOIN COMMON CODE + +=0 +KIEPT: [ARX]_[ARX]+[EBR], ;ADD OFFSET TO + LOAD VMA, ; EPT + START READ, ;START FETCH + VMA PHYSICAL, ;ABSOLUTE ADDRESS + J/KIF30 ;GO GET POINTER + [ARX]_[ARX]+#, ;PER PROCESS PAGE + #/220, 3T, ; IS IN UPT + 400 + J/KIUPT ;JOIN COMMON CODE +KIF30: MEM READ, ;WAIT FOR DATA + [ARX]_MEM ;PLACE IT IN ARX + TR [BR], ;SEE IF EVEN OR ODD + #/1 ; .. + +=0 +KIF40: READ [ARX], ;ODD + SKIP DP18, ;SEE IF VALID + J/KIF50 ;JOIN COMMON CODE + [ARX]_[ARX] SWAP, ;EVEN--FLIP AROUND + J/KIF40 ; AND CONTINUE + +=0 +KIF50: PAGE FAIL TRAP +;AT THIS POINT WE HAVE THE PAGE MAP ENTRY IN RH OF AR + [FLG]_[FLG].AND.NOT.#, ;CLEAR W AND C + FLG.W/1, FLG.C/1 ; FLAGS + TR [ARX], #/020000 ;CACHE ENABLED? +=0 [FLG]_[FLG].OR.#, ;SET CACHE BITS + FLG.C/1, HOLD RIGHT ; .. + TR [ARX], #/040000 ;DO NOT CACHE + ;SEE IF CACHE BIT SET +=0 [BRX]_[BRX].OR.#, ;COPY BITS TO BRX + #/020000, + HOLD RIGHT + TR [ARX], ; .. + #/100000 +=0 [FLG]_[FLG].OR.#, ;SAVE W + FLG.W/1, ; .. + HOLD RIGHT, ; .. + J/KIF90 ;ALL DONE + TL [BRX], ;W=0, WRITE REF? + WRITE CYCLE/1 +=0 +KIF80: [BRX]_[BRX].OR.#, ;WRITE FAILURE + #/100000, HOLD RIGHT, ;INDICATE THAT ACCESS WAS ON + J/KIF50 ;GO PAGE FAIL + J/PFDONE ;ALL DONE + +KIF90: [BRX]_[BRX].OR.#, ;PAGE IS WRITABLE + #/40000, ;TURN ON IN BRX + J/PFDONE ;ALL SET + +;HERE ON HARD PAGE FAILURES +HARD: WORK[SV.BR]_[BR] ;SAVE BR (CLEANUP MAY NEED IT) +=0 [BR]_VMA, ;BUILD PAGE FAIL WORD + CALL [ABORT] ;CLEAR ERROR + [BR]_[BR].AND.#, ;SAVE THE FLAGS + #/401237, ; .. + HOLD RIGHT ; .. + [BRX]_[BRX].OR.[BR], ;COMPLETE PAGE FAIL WORD + J/KIF50 ;GO TRAP + +PFPI1: SKIP IRPT ;TIMER TRAP? +=00 + [AR]_WORK[TIME1], ;YES--GET LOW WORD + SPEC/CLRCLK, ;CLEAR CLOCK FLAG + CALL [TOCK] ;DO THE UPDATE + J/PFT1 ;EXTERNAL INTERRUPT + ABORT MEM CYCLE ;CLEAR 1MS FLAGS += +PFPI2: [AR]_WORK[SV.VMA], ;RESTORE VMA + J/PF125 + + +;HERE ON PAGE FAIL TRAP +=0 +PFT: HALT [IOPF] ;IO PAGE FAILURE +PFT1: [AR]_WORK[SV.VMA], + SKIP/TRAP CYCLE ;SEE IF TRAP CYCLE +=0 TL [AR], FETCH/1, ;IS THIS AN INSTRUCTION FETCH + J/PFT1A ;GO LOOK BELOW + [AR]_WORK[TRAPPC] ;RESTORE PC + READ [AR], LOAD FLAGS, J/CLDISP +=0 +PFT1A: J/CLEANED ;YES--NO PC TO BACK UP +FIXPC: [PC]_[PC]-1, HOLD LEFT ;DATA FAILURE--BACKUP PC +=0 +CLDISP: CLEANUP DISP ;GO CLEANUP AFTER PAGE FAIL +=0000 +CLEANUP: +CLEANED: ;(0) NORMAL CASE + END STATE, SKIP IRPT, ;NO MORE CLEANUP NEEDED + J/PFT2 ;HANDLE PAGE FAIL OR INTERRUPT + [AR]_WORK[SV.ARX], ;(1) BLT + J/BLT-CLEANUP + [PC]_[PC]+1, ;(2) MAP + J/MAPDON + STATE_[EDIT-SRC], ;(3) SRC IN STRING MOVE + J/STRPF + STATE_[EDIT-DST], ;(4) DST IN STRING MOVE + J/STRPF + STATE_[SRC], ;(5) SRC+DST IN STRING MOVE + J/BACKD + STATE_[EDIT-DST], ;(6) FILL IN MOVSRJ + J/STRPF4 + STATE_[EDIT-SRC], ;(7) DEC TO BIN + J/PFDBIN + STATE_[EDIT-SRC], ;(10) SRC+DST IN COMP + J/CMSDST + END STATE, J/BACKS ;(11) EDIT SRC FAIL + END STATE, J/BACKD ;(12) EDIT DST FAIL + STATE_[EDIT-SRC], ;(13) SRC+DST IN EDIT + J/BACKD += + +=0 +PFT2: [AR]_[UBR]+#, ;PREPARE TO STORE PFW + #/500, 3T, + J/PFT10 +PFT3: TAKE INTERRUPT ;PROCESS INTERRUPT +PFT10: VMA_[AR], ;WHERE TO STORE PFW + VMA PHYSICAL WRITE +=0 MEM WRITE, ;STORE PFW + MEM_[BRX], + CALL [NEXTAR] ;ADVANCE POINTER TO + ;PREPARE TO STORE PC + TL [EBR], #/400000 ;KL PAGING? +=0 [BR]_FLAGS,J/EAPF ;YES--DO EXTENDED THING + [BR]_PC WITH FLAGS ;GET OLD PC + MEM WRITE, ;STORE OLD PC + MEM_[BR], + J/EAPF1 + +MAPDON: END STATE, ;CLEAR MAP BIT + SKIP IRPT ;ANY INTERRUPT? +=0 [AR]_[BRX], ;RETURN PAGE FAIL WORD + EXIT + [PC]_[PC]-1, J/PFT3 ;INTERRUPTED OUT OF MAP + ; RETRY INSTRUCTION + + +=0 +EAPF: MEM WRITE, MEM_[BR], ;STORE FLAGS + CALL [NEXTAR] ;STORE PC WORD + MEM WRITE, MEM_[PC] ; .. +EAPF1: [AR]_[AR]+1, + VMA PHYSICAL READ, + J/GOEXEC + +NEXTAR: NEXT [AR] PHYSICAL WRITE, RETURN [1] + +.ENDIF/ITS diff --git a/src/kshack/simple.42 b/src/kshack/simple.42 new file mode 100755 index 00000000..a9bd4d39 --- /dev/null +++ b/src/kshack/simple.42 @@ -0,0 +1,3246 @@ +;;;-*-Fundamental-*- + + .BIN +.TOC "POWER UP SEQUENCE" + + .UCODE + +;HERE IS WHERE WE FIRE THE MACHINE UP DURING POWER ON + + +0: [MASK]_#, #/377777 ;BUILD A MASK WITH + [MASK]_[MASK]*2 ; A ONE IN 36-BITS AND 0 + [MASK]_[MASK].OR.#,#/1 ; IN BITS -2,-1,36,37 + [MAG]_[MASK]*.5 ;MAKE CONSTANT + [XWD1]_#, #/1 ;CONSTANT WITH 1 IN EACH + ; HALF WORD + [ONE]_0 XWD [1], ;THE CONSTANT 1 + CALL/1 ;RESET STACK (CAN NEVER RETURN + ; TO WHERE MR LEFT US) +.IFNOT/ITS +3: [AR]_0 XWD [376000] ;ADDRESS OF HALT STATUS + ; BLOCK +.IF/ITS +3: [AR]_0 XWD [500] ; ITS makes it 500, so start that way... +.ENDIF/ITS + WORK[HSBADR]_[AR] ;SAVE FOR HALT LOOP + [UBR]_0, ABORT MEM CYCLE ;CLEAR THE UBR AND RESET + ; MEMORY CONTROL LOGIC + [EBR]_0, LOAD AC BLOCKS ;CLEAR THE EBR AND FORCE + ; PREVIOUS AND CURRENT AC + ; BLOCKS TO ZERO + [FLG]_0, SET APR ENABLES ;CLEAR THE STATUS FLAGS AND + ; DISABLE ALL APR CONDITIONS + WORK[APR]_[FLG] ;ZERO REMEMBERED ENABLES + + WORK[TIME0]_[FLG] ;CLEAR TIME BASE + WORK[TIME1]_[FLG] ; .. +.IF/PCST + WORK[PCST]_[FLG] ;Turn off PC sampling +.ENDIF/PCST +.IF/FULL + AC[BIN0]_0 ;COMPUTE A TABLE OF POWERS OF + AC[BIN1]_1 ; TEN + [AR]_0, SC_19. ;WE WANT TO GET 22 NUMBERS + WORK[DECLO]_1 ;STARTING WITH 1 + WORK[DECHI]_0 ; .. + [HR]_#, WORK/DECLO ;ADDRESS OF LOW WORD + [BRX]_#, WORK/DECHI ;ADDRESS OF HIGH WORD +TENLP: [BRX]_[BRX]+1, LOAD VMA ;ADDRESS THE HIGH WORD +=0* [ARX]_AC[BIN1], ;LOW WORD TO ARX + CALL [DBSLOW] ;MULTIPLY BY TEN + RAM_[BR] ;SAVE HIGH WORD + [HR]_[HR]+1, LOAD VMA ;WHERE TO STORE LOW WORD + RAM_[ARX], STEP SC ;STORE LOW WORD AND SEE IF + ; WE ARE DONE +=0 J/TENLP ;NOT YET--KEEP GOING + [BR].XOR.#, 3T, SKIP ADL.EQ.0, #/330656 + ;DID WE GET THE RIGHT ANSWER + ; IN THE TOP 18 BITS? +=0**0 HALT [MULERR] ;NO--CPU IS BROKEN +.ENDIF/FULL + +=0**1 [PI]_0, CALL [LOADPI] ;CLEAR PI STATE +=1**1 ;CLEAR REGISTERS SO NO + ;PARITY ERROR HAPPEN +.IFNOT/FULL + [ARX]_0 ;WRITTEN WHILE COMPUTING POWERS + [BR]_0 ;OF 10 + [BRX]_0 +.ENDIF/FULL + [T1]_0 XWD [120] ;RH OF 120 CONTAINS START ADDRESS + ; FOR SIMULATOR. FOR THE REAL + ; MACHINE IT IS JUST DATA WITH + ; GOOD PARITY. += +;THE CODE UNDER .IF/SIM MUST USE THE SAME ADDRESS AS THE CODE +; UNDER .IFNOT/SIM SO THAT MICROCODE ADDRESSES DO NOT CHANGE BETWEEN +; VERSIONS +.IF/SIM + VMA_[T1], START READ ;READ THE WORD + MEM READ, [PC]_MEM, HOLD LEFT, J/START + ;GO FIRE UP SIMULATOR AT THE + ; PROGRAMS STARTING ADDRESS +.IFNOT/SIM + [PC]_0, ;CLEAR LH OF PC + LEAVE USER, ;ENTER EXEC MODE + LOAD FLAGS ;CLEAR TRAP FLAGS + [T1]_#, HALT/POWER, ;LOAD T1 WITH POWER UP CODE + J/PWRON ;ENTER HALT LOOP. DO NOT STORE + ; HALT STATUS BLOCK +.ENDIF/SIM + + .TOC "THE INSTRUCTION LOOP -- START NEXT INSTRUCTION" + +;ALL INSTRUCTIONS EXCEPT JUMP'S AND UUO'S END UP HERE +1400: +DONE: DONE +1401: VMA_[PC]+1, NEXT INST FETCH, FETCH +=0 +SKIP: VMA_[PC]+1, NEXT INST FETCH, FETCH + DONE + + +;16-WAY DISPATCH BASED ON NEXT INSTRUCTION +=0000 +NICOND: + +=0001 [AR]_0 XWD [423], ;TRAP TYPE 3 + ; GET ADDRESS OF TRAP INST + TURN OFF PXCT, ;CLEAR PXCT + J/TRAP ;PROCESS TRAP (INOUT.MIC) +=0010 [AR]_0 XWD [422], ;TRAP TYPE 2 + TURN OFF PXCT, ;CLEAR PXCT + J/TRAP ;GO TRAP +=0011 [AR]_0 XWD [421], ;TRAP TYPE 1 + TURN OFF PXCT, ;TURN OF PXCT + J/TRAP ;GO TRAP +=0101 HALT [CSL] ;"HA" COMMAND TO 8080 +=0111 +START: VMA_[PC], ;LOAD VMA + FETCH, ;INDICATE INSTRUCTION FETCH + J/XCTGO ;GO GET INSTRUCTION +;THE NEXT SET OF CASES ARE USED WHEN THERE IS A FETCH +; IN PROGESS +=1000 +NICOND-FETCH: +=1001 [AR]_0 XWD [423], ;TRAP TYPE 3 + TURN OFF PXCT, + J/TRAP +=1010 [AR]_0 XWD [422], ;TRAP TYPE 2 + TURN OFF PXCT, + J/TRAP +=1011 [AR]_0 XWD [421], ;TRAP TYPE 1 + TURN OFF PXCT, + J/TRAP +=1101 HALT [CSL] ;"HA" COMMAND TO 8080 +=1111 +.IF/1PROC +XCTGO: MEM READ, ;WAIT FOR MEMORY + [HR]_MEM AND READ [FLG], ;PUT DATA IN HR + LOAD INST, ;LOAD IR & AC # + NORM DISP, ;TEST FLG<8> (1-PROCEED FLAG) + J/INCPC ;GO BUMP PC +.IFNOT/1PROC +XCTGO: MEM READ, ;WAIT FOR MEMORY + [HR]_MEM, ;PUT DATA IN HR + LOAD INST, ;LOAD IR & AC # + J/INCPC ;GO BUMP PC +.ENDIF/1PROC += + +.IF/1PROC +=1011 ;FOR NORM DISP AT XCTGO +.ENDIF/1PROC +;HERE WE POINT PC TO NEXT INSTRUCTION WHILE WE WAIT FOR +; EFFECTIVE ADDRESS LOGIC TO SETTLE +INCPC: VMA_[PC]+1, ;ADDRESS OF NEXT INSTRUCTION + FETCH/1, ;INSTRUCTION FETCH + TURN OFF PXCT, ;CLEAR EFFECT OF PXCT + EA MODE DISP, ;DISPATCH OFF INDEXING AND @ + J/EACALC +.IF/1PROC +;COME HERE WHEN FLG.1PROC IS SET + TL [FLG], FLG.2PROC/1 ;Skip if this is the first time through +=0 TAKE 1-PROCEED TRAP + [FLG]_[FLG].OR.#, FLG.2PROC/1, HOLD RIGHT, J/INCPC ;Trap next time +.ENDIF/1PROC + +;MAIN EFFECTIVE ADDRESS CALCULATION +=0001 +EACALC: +; +; THE FIRST 4 CASES ARE USED ONLY FOR JRST +; + +;CASE 0 -- JRST 0,FOO(XR) + [PC]_[HR]+XR, ;UPDATE PC + HOLD LEFT, ;ONLY RH + LOAD VMA, FETCH, ;START GETTING IT + NEXT INST FETCH ;START NEXT INST + +;CASE 2 -- JRST 0,FOO + [PC]_[HR], ;NEW PC + HOLD LEFT, ;ONLY RH + LOAD VMA, FETCH, ;START GETTING IT + NEXT INST FETCH ;START NEXT INST + +;CASE 4 -- JRST 0,@FOO(XR) + [HR]_[HR]+XR, ;ADD IN INDEX + START READ, ;START TO FETCH @ WORD + LOAD VMA, ;PUT ADDRESS IN VMA + J/FETIND ;GO DO MEM WAIT (FORGET ABOUT JRST) + +;CASE 6 -- JRST 0,@FOO + VMA_[HR], ;LOAD UP ADDRESS + START READ, ;START TO FETCH @ WORD + J/FETIND ;GO DO MEM WAIT (FORGET ABOUT JRST) + +; +;THESE 4 ARE FOR THE NON-JRST CASE +; + +;CASE 10 -- JUST INDEXING +INDEX: [HR]_[HR]+XR, ;ADD IN INDEX REGISTER + HOLD LEFT ;JUST DO RIGHT HALF + +;CASE 12 -- NO INDEXING OR INDIRECT +NOMOD: [AR]_EA, ;PUT 0,,E IN AR + PXCT DATA, AREAD ;DO ONE OR MORE OF THE FOLLWING + ; ACCORDING TO THE DROM: + ;1. LOAD VMA + ;2. START READ OR WRITE + ;3. DISPATCH TO 40-57 + ; OR DIRECTLY TO EXECUTE CODE + +;CASE 14 -- BOTH INDEXING AND INDIRECT +BOTH: [HR]_[HR]+XR, ;ADD IN INDEX REGISTER + LOAD VMA, PXCT EA, ;PUT ADDRESS IN VMA + START READ, J/FETIND ;START CYCLE AND GO WAIT FOR DATA + +;CASE 16 -- JUST INDIRECT +INDRCT: VMA_[HR], ;LOAD ADDRESS OF @ WORD + START READ, PXCT EA ;START CYCLE + + +;HERE TO FETCH INDIRECT WORD +FETIND: MEM READ, [HR]_MEM, ;GET DATA WORD + HOLD LEFT, ;JUST RIGHT HALF + LOAD IND EA ;RELOAD @ AND INDEX FLOPS + +XCT2: VMA_[PC], ;PUT PC BACK IN VMA + FETCH/1, ;TURN ON FETCH FLAG + EA MODE DISP, ;REDO CALCULATION FOR + J/EACALC ; NEW WORD + + .TOC "ONE-PROCEED TRAP" + +.IF/1PROC +1PROC-TRAP: + [AR]_0 XWD [432] ; 432 in UPT gets old PC. + [AR]_[AR]+[UBR], + VMA PHYSICAL WRITE + [ARX]_PC WITH FLAGS + MEM WRITE, MEM_[ARX] + [AR]_[AR]+1, ; 433 in UPT holds new PC. + VMA PHYSICAL READ, + J/GOEXEC +.ENDIF/1PROC + + .TOC "THE INSTRUCTION LOOP -- FETCH ARGUMENTS" +;HERE ON AREAD DISP TO HANDLE VARIOUS CASES OF ARGUMENT FETCH + +;CASE 0 -- READ (E) +40: MEM READ, ;WAIT FOR DATA + [AR]_MEM, ;PUT WORD IN AR + INST DISP ;GO TO EXECUTE CODE + +;CASE 1 -- WRITE (E) +41: [AR]_AC, ;PUT AC IN AR + INST DISP ;GO TO EXECUTE CODE + +;CASE 2 -- DOUBLE READ +42: MEM READ, ;WAIT FOR DATA + [AR]_MEM ;PUT HI WORD IN AR + VMA_[HR]+1, PXCT DATA, ;POINT TO E+1 + START READ ;START MEMORY CYCLE + MEM READ, ;WAIT FOR DATA + [ARX]_MEM, ;LOW WORD IN ARX + INST DISP ;GO TO EXECUTE CODE + +;CASE 3 -- DOUBLE AC +43: [AR]_AC ;GET HIGH AC + [ARX]_AC[1], ;PUT C(AC+1) IN ARX + INST DISP ;GO TO EXECUTE CODE + +;CASE 4 -- SHIFT +44: +SHIFT: READ [AR], ;LOOK AT EFFECTIVE ADDRESS + SKIP DP18, ;SEE IF LEFT OR RIGHT + SC_SHIFT-1, ;PUT NUMBER OF PLACES TO SHIFT IN + LOAD FE, ; SC AND FE + INST DISP ;GO DO THE SHIFT + +;CASE 5 -- SHIFT COMBINED +45: Q_AC[1] ;PUT LOW WORD IN Q + [BR]_AC*.5 LONG ;PUT AC IN BR & SHIFT BR!Q RIGHT + [BR]_[BR]*.5 LONG, ;SHIFT BR!Q 1 MORE PLACE RIGHT + J/SHIFT ;GO DO SHIFT SETUP + +;CASE 6 -- FLOATING POINT IMMEDIATE +46: [AR]_[AR] SWAP, ;FLIP BITS TO LEFT HALF + J/FPR0 ;JOIN COMMON F.P. CODE + +;CASE 7 -- FLOATING POINT +47: MEM READ, ;WAIT FOR MEMORY (SPEC/MEM WAIT) + [AR]_MEM ;DATA INTO AR +=0 +FPR0: READ [AR], ;LOOK AT NUMBER + SC_EXP, FE_EXP, ;PUT EXPONENT IN SC & FE + SKIP DP0, ;SEE IF NEGATIVE + CALL [ARSIGN] ;EXTEND AR SIGN +FPR1: [ARX]_0, ;ZERO ARX + INST DISP ;GO TO EXECUTE CODE + +;CASE 10 -- READ THEN PREFETCH +50: MEM READ, ;WAIT FOR DATA + [AR]_MEM THEN FETCH, ;PUT DATA IN AR AND START A READ + ; VMA HAS PC+1. + INST DISP ;GO DO IT + +;CASE 11 -- DOUBLE FLOATING READ +51: SPEC MEM READ, ;WAIT FOR DATA + [BR]_MEM, ;HOLD IN BR + SC_EXP, FE_EXP, ;SAVE EXPONENT + SKIP DP0, 3T ;SEE IF MINUS +=0 [AR]_[AR]+1, ;POINT TO E+1 + LOAD VMA, PXCT DATA, ;PUT IN VMA + START READ, J/DFPR1 ;GO GET POSITIVE DATA + [AR]_[AR]+1, ;POINT TO E+1 + LOAD VMA, PXCT DATA, ;PUT IN VMA + START READ ;GO GET NEGATIVE DATA + [BR]_-SIGN, ;SMEAR MINUS SIGN + J/DFPR2 ;CONTINUE BELOW +DFPR1: [BR]_+SIGN ;SMEAR PLUS SIGN +DFPR2: MEM READ, 3T, ;WAIT FOR MEMORY + [ARX]_(MEM.AND.[MAG])*.5, + ASH ;SET SHIFT PATHS + [AR]_[BR]*.5 ;SHIFT AR + [AR]_[AR]*.5, ;COMPLETE SHIFTING + SC_FE ;PAGE FAIL MAY HAVE ZAPPED + ; THE SC. + VMA_[PC], FETCH, ;GET NEXT INST + INST DISP ;DO THIS ONE + +;CASE 12 -- TEST FOR IO LEGAL +52: SKIP IO LEGAL ;IS IO LEGAL? +=0 UUO ;NO + INST DISP ;YES--DO THE INSTRUCTION + + +;CASE 13 -- RESERVED +;53: + +;CASE 14 -- RESERVED +;54: + +;CASE 15 -- RESERVED +;55: + +;CASE 16 -- RESERVED +;56: + +;CASE 17 -- RESERVED +;57: + +;EXTEND AR SIGN. +;CALL WITH SKIP ON AR0, RETURNS 1 ALWAYS +=0 +ARSIGN: [AR]_+SIGN, RETURN [1] ;EXTEND + SIGN + [AR]_-SIGN, RETURN [1] ;EXTEND - SIGN + + .TOC "THE INSTRUCTION LOOP -- STORE ANSWERS" + +;NOTE: INSTRUCTIONS WHICH STORE IN BOTH AC AND MEMORY +; (E.G. ADDB, AOS) MUST STORE IN MEMORY FIRST +; SO THAT IF A PAGE FAIL HAPPENS THE AC IS +; STILL INTACT. + +1500: +BWRITE: ;BASE ADDRESS OF BWRITE DISPATCH + +;CASE 0 -- RESERVED +;1500: + +;CASE 1 -- RESERVED +;1501: + +;CASE 2 -- RESERVED +;1502: + +;CASE 3 -- RESERVED +;1503: + +;CASE 4 -- STORE SELF +1504: +STSELF: SKIP IF AC0, ;IS AC # ZERO? + J/STBTH1 ;GO TO STORE BOTH CASE + +;CASE 5 -- STORE DOUBLE AC +1505: +DAC: AC[1]_[ARX], ;STORE AC 1 + J/STAC ;GO STORE AC + +;CASE 6 -- STORE DOUBLE BOTH (KA10 STYLE MEM_AR ONLY) +1506: +STDBTH: MEM WRITE, ;WAIT FOR MEMORY + MEM_[AR], ;STORE AR + J/DAC ;NOW STORE AC & AC+1 + +;CASE 7 -- RESERVED +;1507: + +;CASE 10 -- RESERVED +;1510: + +;CASE 11 -- RESERVED +;1511: + +;CASE 12 -- RESERVED +;1512: + +;CASE 13 -- RESERVED +;1513: + +;CASE 14 -- RESERVED +1514: +FL-BWRITE: ;THE NEXT 4 CASES ARE ALSO + ;USED IN FLOATING POINT + HALT [BW14] + +;CASE 15 -- STORE AC +1515: +STAC: AC_[AR], ;STORE AC + NEXT INST ;DO NEXT INSTRUCTION + +;CASE 16 -- STORE IN MEMORY +1516: +STMEM: MEM WRITE, ;WAIT FOR MEMORY + MEM_[AR], ;STORE AR + J/DONE ;START FETCH OF NEXT + +;CASE 17 -- STORE BOTH +1517: +STBOTH: MEM WRITE, ;WAIT FOR MEMORY + MEM_[AR], ;STORE AR + J/STAC ;NOW STORE AC + +=0 +STBTH1: MEM WRITE, ;WAIT FOR MEMORY + MEM_[AR], ;STORE AR + J/STAC ;NOW STORE AC +STORE: MEM WRITE, ;WAIT FOR MEMORY + MEM_[AR], ;STORE AC + J/DONE ;START NEXT INST + + .TOC "MOVE GROUP" + + .DCODE +200: R-PF, AC, J/STAC ;MOVE + I-PF, AC, J/STAC ;MOVEI + W, M, J/MOVE ;MOVEM + RW, S, J/STSELF ;MOVES + +204: R-PF, AC, J/MOVS ;MOVS + I-PF, AC, J/MOVS ;MOVSI + W, M, J/MOVS ;MOVSM + RW, S, J/MOVS ;MOVSS + +210: R-PF, AC, J/MOVN ;MOVN + I-PF, AC, J/MOVN ;MOVNI + W, M, J/MOVN ;MOVNM + RW, S, J/MOVN ;MOVNS + +214: R-PF, AC, J/MOVM ;MOVM + I-PF, AC, J/STAC ;MOVMI + W, M, J/MOVM ;MOVMM + RW, S, J/MOVM ;MOVNS + .UCODE + +1402: +MOVS: [AR]_[AR] SWAP,EXIT + +1403: +MOVM: READ [AR], SKIP DP0, J/MOVE + +1404: +MOVE: EXIT +1405: +MOVN: [AR]_-[AR], ;NEGATE NUMBER + AD FLAGS, 3T, ;UPDATE FLAGS + J/MOVE ;STORE ANSWER + + .TOC "EXCH" + + .DCODE +250: R,W TEST, AC, J/EXCH + .UCODE + +1406: +EXCH: [BR]_AC, ;COPY AC TO THE BR + START WRITE ;START A WRITE CYCLE + MEM WRITE, ;COMPLETE WRITE CYCLE + MEM_[BR], ;STORE BR (AC) IN MEMORY + J/STAC ;STORE THE AR IN AC. NOTE: AR + ; WAS LOADED WITH MEMORY OPERAND + ; AS PART OF INSTRUCTION DISPATCH + + .TOC "HALFWORD GROUP" +; DESTINATION LEFT HALF + + .DCODE +500: R-PF, AC, J/HLL + I-PF, AC, J/HLL + RW, M, J/HRR ;HLLM = HRR EXCEPT FOR STORE + RW, S, J/MOVE ;HLLS = MOVES + + R-PF, AC, J/HRL + I-PF, AC, J/HRL + RW, M, J/HRLM + RW, S, J/HRLS + +510: R-PF, AC, J/HLLZ + I-PF, AC, J/HLLZ + W, M, J/HLLZ + RW, S, J/HLLZ + + R-PF, AC, J/HRLZ + I-PF, AC, J/HRLZ + W, M, J/HRLZ + RW, S, J/HRLZ + +520: R-PF, AC, J/HLLO + I-PF, AC, J/HLLO + W, M, J/HLLO + RW, S, J/HLLO + + R-PF, AC, J/HRLO + I-PF, AC, J/HRLO + W, M, J/HRLO + RW, S, J/HRLO + +530: R-PF, AC, J/HLLE + I-PF, AC, J/HLLE + W, M, J/HLLE + RW, S, J/HLLE + + R-PF, AC, J/HRLE + I-PF, AC, J/HRLE + W, M, J/HRLE + RW, S, J/HRLE + +; DESTINATION RIGHT HALF + +540: R-PF, AC, J/HRR + I-PF, AC, J/HRR + RW, M, J/HLL ;HRRM = HLL EXCEPT FOR STORE + RW, S, J/MOVE ;HRRS = MOVES + + R-PF, AC, J/HLR + I-PF, AC, J/HLR + RW, M, J/HLRM + RW, S, J/HLRS + +550: R-PF, AC, J/HRRZ + I-PF, AC, J/HRRZ + W, M, J/HRRZ + RW, S, J/HRRZ + + R-PF, AC, J/HLRZ + I-PF, AC, J/HLRZ + W, M, J/HLRZ + RW, S, J/HLRZ + +560: R-PF, AC, J/HRRO + I-PF, AC, J/HRRO + W, M, J/HRRO + RW, S, J/HRRO + + R-PF, AC, J/HLRO + I-PF, AC, J/HLRO + W, M, J/HLRO + RW, S, J/HLRO + +570: R-PF, AC, J/HRRE + I-PF, AC, J/HRRE + W, M, J/HRRE + RW, S, J/HRRE + + R-PF, AC, J/HLRE + I-PF, AC, J/HLRE + W, M, J/HLRE + RW, S, J/HLRE + + .UCODE + +;FIRST THE GUYS THAT LEAVE THE OTHER HALF ALONE + +;THE AR CONTAINS THE MEMORY OPERAND. SO WE WANT TO PUT THE LH OF +; AC INTO AR TO DO A HRR. OBVIOUS THING FOR HLL. +1407: +HRR: [AR]_AC,HOLD RIGHT,EXIT +1410: +HLL: [AR]_AC,HOLD LEFT,EXIT + +;HRL FLOW: +;AT HRL AR CONTAINS: +; +; !------------------!------------------! +; ! LH OF (E) ! RH OF (E) ! +; !------------------!------------------! +; +;AR_AR SWAP GIVES: +; +; !------------------!------------------! +; ! RH OF (E) ! LH OF (E) ! +; !------------------!------------------! +; +;AT HLL, AR_AC,HOLD LEFT GIVES: +; +; !------------------!------------------! +; ! RH OF (E) ! RH OF AC ! +; !------------------!------------------! +; +;THE EXIT MACRO CAUSES THE AR TO BE STORED IN AC (AT STAC). +; THE REST OF THE HALF WORD IN THIS GROUP ARE VERY SIMILAR. + +1411: +HRL: [AR]_[AR] SWAP,J/HLL +1412: +HLR: [AR]_[AR] SWAP,J/HRR + +1413: +HRLM: [AR]_[AR] SWAP + [AR]_AC,HOLD LEFT,J/MOVS +1414: +HRLS: [AR]_[AR] SWAP,HOLD RIGHT,EXIT + +1415: +HLRM: [AR]_[AR] SWAP + [AR]_AC,HOLD RIGHT,J/MOVS +1416: +HLRS: [AR]_[AR] SWAP,HOLD LEFT,EXIT + +;NOW THE HALFWORD OPS WHICH CONTROL THE "OTHER" HALF. +; ENTER WITH 0,,E (E) OR (AC) IN AR + +1417: +HRRE: READ [AR],SKIP DP18 +1420: +HRRZ: [AR] LEFT_0, EXIT +1421: +HRRO: [AR] LEFT_-1, EXIT + +1422: +HRLE: READ [AR],SKIP DP18 +1424: +HRLZ: [AR]_#,#/0,HOLD RIGHT,J/MOVS +1425: +HRLO: [AR]_#,#/777777,HOLD RIGHT,J/MOVS + +1423: +HLRE: READ [AR],SKIP DP0 +1426: +HLRZ: [AR]_#,#/0,HOLD LEFT,J/MOVS +1427: +HLRO: [AR]_#,#/777777,HOLD LEFT,J/MOVS + +1430: +HLLE: READ [AR],SKIP DP0 +1432: +HLLZ: [AR] RIGHT_0, EXIT +1433: +HLLO: [AR] RIGHT_-1, EXIT + + .TOC "DMOVE, DMOVN, DMOVEM, DMOVNM" + + .DCODE +120: DBL R, DAC, J/DAC + DBL R, AC, J/DMOVN + .UCODE + +1434: +DMOVN: CLEAR ARX0, CALL [DBLNGA] +1436: AC[1]_[ARX], J/STAC + + .DCODE +124: DBL AC, J/DMOVN1 + W, J/DMOVNM + .UCODE + + +1565: +DMOVNM: [ARX]_AC[1],CALL [DBLNEG] +1567: +DMOVN1: [HR]+[ONE], ;GET E+1 + LOAD VMA, ;PUT THAT IN VMA + START WRITE, ;STORE IN E+1 + PXCT DATA ;DATA CYCLE + MEM WRITE, MEM_[ARX] ;STORE LOW WORD + VMA_[HR], ;GET E + LOAD VMA, ;SAVE IN VMA + PXCT DATA, ;OPERAND STORE + START WRITE, ;START MEM CYCLE + J/STORE ;GO STORE AR + + .TOC "BOOLEAN GROUP" + + .DCODE +400: I-PF, AC, J/SETZ + I-PF, AC, J/SETZ + IW, M, J/SETZ + IW, B, J/SETZ + .UCODE + +1441: +SETZ: [AR]_0, EXIT + + .DCODE +404: R-PF, AC, J/AND + I-PF, AC, J/AND + RW, M, J/AND + RW, B, J/AND + .UCODE + +1442: +AND: [AR]_[AR].AND.AC,EXIT + + .DCODE +410: R-PF, AC, J/ANDCA + I-PF, AC, J/ANDCA + RW, M, J/ANDCA + RW, B, J/ANDCA + .UCODE + +1443: +ANDCA: [AR]_[AR].AND.NOT.AC,EXIT + + .DCODE +414: R-PF, AC, J/MOVE ;SETM = MOVE + I-PF, AC, J/MOVE + RW, M, J/MOVE ;SETMM = NOP THAT WRITES MEMORY + RW, B, J/MOVE ;SETMB = MOVE THAT WRITES MEMORY + +420: R-PF, AC, J/ANDCM + I-PF, AC, J/ANDCM + RW, M, J/ANDCM + RW, B, J/ANDCM + .UCODE + +1444: +ANDCM: [AR]_.NOT.[AR],J/AND + + .DCODE +424: R, J/DONE + I, J/DONE + W, M, J/MOVE ;SETAM = MOVEM + W, M, J/MOVE ;SETAB, TOO + .UCODE + + .DCODE +430: R-PF, AC, J/XOR + I-PF, AC, J/XOR + RW, M, J/XOR + RW, B, J/XOR + .UCODE + +1445: +XOR: [AR]_[AR].XOR.AC,EXIT + + .DCODE +434: R-PF, AC, J/IOR + I-PF, AC, J/IOR + RW, M, J/IOR + RW, B, J/IOR + .UCODE + +1446: +IOR: [AR]_[AR].OR.AC,EXIT + + .DCODE +440: R-PF, AC, J/ANDCB + I-PF, AC, J/ANDCB + RW, M, J/ANDCB + RW, B, J/ANDCB + .UCODE + +1447: +ANDCB: [AR]_.NOT.[AR],J/ANDCA + + .DCODE +444: R-PF, AC, J/EQV + I-PF, AC, J/EQV + RW, M, J/EQV + RW, B, J/EQV + .UCODE + +1450: +EQV: [AR]_[AR].EQV.AC,EXIT + + .DCODE +450: I-PF, AC, J/SETCA + I-PF, AC, J/SETCA + IW, M, J/SETCA + IW, B, J/SETCA + .UCODE + +1451: +SETCA: [AR]_.NOT.AC,EXIT + + .DCODE +454: R-PF, AC, J/ORCA + I-PF, AC, J/ORCA + RW, M, J/ORCA + RW, B, J/ORCA + .UCODE + +1452: +ORCA: [BR]_.NOT.AC + [AR]_[AR].OR.[BR],EXIT + + .DCODE +460: R-PF, AC, J/SETCM + I-PF, AC, J/SETCM + RW, M, J/SETCM + RW, B, J/SETCM + .UCODE + +1453: +SETCM: [AR]_.NOT.[AR],EXIT + + .DCODE +464: R-PF, AC, J/ORCM + I-PF, AC, J/ORCM + RW, M, J/ORCM + RW, B, J/ORCM + .UCODE + +1454: +ORCM: [AR]_.NOT.[AR],J/IOR + + .DCODE +470: R-PF, AC, J/ORCB + I-PF, AC, J/ORCB + RW, M, J/ORCB + RW, B, J/ORCB + .UCODE + +1455: +ORCB: [AR]_[AR].AND.AC,J/SETCM + + .DCODE +474: I-PF, AC, J/SETO + I-PF, AC, J/SETO + IW, M, J/SETO + IW, B, J/SETO + .UCODE + +1456: +SETO: [AR]_-[ONE], EXIT + + .TOC "ROTATES AND LOGICAL SHIFTS -- ROT, LSH, JFFO" + + .DCODE +240: SH, J/ASH + SH, J/ROT + SH, J/LSH + I, J/JFFO + I-PF, J/ASHC +245: SHC, J/ROTC + SHC, J/LSHC +.IF/CIRC + I, J/CIRC ;That's whats in the DROM... +.ENDIF/CIRC + .UCODE + + +;HERE IS THE CODE FOR LOGICAL SHIFT. THE EFFECTIVE ADDRESS IS +; IN AR. +1612: +LSH: [AR]_AC, ;PICK UP AC + FE_-FE-1, ;NEGATIVE SHIFT + J/LSHL ;SHIFT LEFT +1613: [AR]_AC.AND.MASK, ;MAKE IT LOOK POSITIVE + FE_FE+1, ;UNDO -1 AT SHIFT + J/ASHR ;GO SHIFT RIGHT + +LSHL: [AR]_[AR]*2, ;SHIFT LEFT + SHIFT, J/STAC ;FAST SHIFT & GO STORE AC + +;HERE IS THE CODE FOR ARITHMETIC SHIFT. THE EFFECTIVE ADDRESS IS +; IN AR. + +ASH36 LEFT "[AR]_[AR]*2 LONG, ASHC, STEP SC, ASH AROV" + +1622: +ASH: Q_0, J/ASHL0 ;HARDWARE ONLY DOES ASHC +1623: [AR]_AC, ;GET THE ARGUMENT + FE_FE+1 ;FE HAS NEGATIVE SHIFT COUNT +ASHR: [AR]_[AR]*.5, ;SHIFT RIGHT + ASH, SHIFT, ;FAST SHIFT + J/STAC ;STORE AC WHEN DONE + +ASHL0: [AR]_AC*.5, ;GET INTO 9 CHIPS + STEP SC ;SEE IF NULL SHIFT +=0 +ASHL: ASH36 LEFT, J/ASHL ;SHIFT LEFT + ;SLOW BECAUSE WE HAVE TO + ; TEST FOR OVERFLOW + +ASHX: [AR]_[AR]*2, J/STAC ;SHIFT BACK INTO 10 CHIPS + +;HERE IS THE CODE FOR ROTATE. THE EFFECTIVE ADDRESS IS +; IN AR. +1632: +ROT: [AR]_AC*.5, ;PICK UP THE AC (& SHIFT) + FE_-FE-1, ;NEGATIVE SHIFT COUNT + J/ROTL ;ROTATE LEFT +1633: [AR]_AC*.5, ;PICK UP THE AC (& SHIFT) + FE_FE+1 ;NEGATIVE SHIFT COUNT + [AR]_[AR]*.5 ;PUT IN 9 DIPS + [AR]_[AR]*.5, ;SHIFT RIGHT + ROT, SHIFT ;FAST SHIFT +ASHXX: [AR]_[AR]*2,J/ASHX ;SHIFT TO STD PLACE + +ROTL: [AR]_[AR]*.5 ;PUT IN RIGHT 36-BITS + [AR]_[AR]*2, ;ROTATE LEFT + ROT, SHIFT, ;FAST SHIFT + J/ASHXX ;ALL DONE--SHIFT BACK + +1462: +JFFO: [BR]_AC.AND.MASK, 4T, ;GET AC WITH NO SIGN + SKIP AD.EQ.0 ; EXTENSION. SKIP IF + ; ZERO. +=0 [PC]_[AR], ;NOT ZERO--JUMP + LOAD VMA, FETCH, ;GET NEXT INST + J/JFFO1 ;ENTER LOOP + AC[1]_0, J/DONE ;ZERO--DONE + +JFFO1: FE_-12. ;WHY -12.? WELL THE + ; HARDWARE LOOKS AT + ; BIT -2 SO THE FIRST + ; 2 STEPS MOVE THE BR + ; OVER. WE ALSO LOOK AT + ; THE DATA BEFORE THE SHIFT + ; SO WE END UP GOING 1 PLACE + ; TOO MANY. THAT MEANS THE + ; FE SHOULD START AT -3. + ; HOWEVER, WE COUNT THE FE BY + ; 4 (BECAUSE THE 2 LOW ORDER + ; BITS DO NOT COME BACK) SO + ; FE_-12. +=0 +JFFOL: [BR]_[BR]*2, ;SHIFT LEFT + FE_FE+4, ;COUNT UP BIT NUMBER + SKIP DP0, J/JFFOL ;LOOP TILL WE FIND THE BIT + [AR]_FE ;GET ANSWER BACK + [AR]_[AR].AND.# CLR LH,#/77 ;MASK TO 1 COPY + AC[1]_[AR], NEXT INST ;STORE AND EXIT + + .TOC "ROTATES AND LOGICAL SHIFTS -- LSHC" + +;SHIFT CONNECTIONS WHEN THE SPECIAL FUNCTION "LSHC" IS DONE: +; +; !-! !----!------------------------------------! +; !0!-->!0000! HIGH ORDER 36 BITS ! RAM FILE +; !-! !----!------------------------------------! +; ^ +; : +; .................................... +; : +; !----!------------------------------------! +; !0000! LOW ORDER 36 BITS ! Q-REGISTER +; !----!------------------------------------! +; ^ +; : +; !-! +; !0! +; !-! +; + +1464: +LSHC: STEP SC, J/LSHCL +1465: READ [AR], SC_-SHIFT-1 + STEP SC +=0 +LSHCR: [BR]_[BR]*.5 LONG,STEP SC,LSHC,J/LSHCR + [BR]_[BR]*2 LONG,J/LSHCX + +=0 +LSHCL: [BR]_[BR]*2 LONG,LSHC,STEP SC,J/LSHCL + [BR]_[BR]*2 LONG +LSHCX: [BR]_[BR]*2 LONG + AC_[BR], J/ASHCQ1 + + .TOC "ROTATES AND LOGICAL SHIFTS -- ASHC" + + +1466: +ASHC: READ [AR], ;PUT AR ON DP + SC_SHIFT, LOAD FE, ;PUT SHIFT IN BOTH SC AND FE + SKIP ADR.EQ.0 ;SEE IF NULL SHIFT +=0 Q_AC[1], ;NOT NULL--GET LOW WORD + J/ASHC1 ;CONTINUE BELOW +NIDISP: NEXT INST ;NULL--ALL DONE +ASHC1: [BR]_AC*.5 LONG, ;GET HIGH WORD + ;AND SHIFT Q + SKIP/SC ;SEE WHICH DIRECTION +=0 [BR]_[BR]*.5, ;ADJUST POSITION + SC_FE+S#, S#/1776, ;SUBRTACT 2 FROM FE + J/ASHCL ;GO LEFT + [BR]_[BR]*.5, ;ADJUST POSITION + SC_S#-FE, S#/1776 ;SC_-2-FE, SC_+# OF STEPS +=0 ;HERE TO GO RIGHT +ASHCR: [BR]_[BR]*.5 LONG, ;GO RIGHT + ASHC, ;SET DATA PATHS FOR ASHC (SEE DPE1) + STEP SC, J/ASHCR ;COUNT THE STEP AND KEEP LOOPING + [BR]_[BR]*2 LONG, ;PUT BACK WHERE IT GOES + ASHC, J/ASHCX ;COMPLETE INSTRUCTION + +=0 +ASHCL: [BR]_[BR]*2 LONG, ;GO LEFT + ASHC, ASH AROV, ;SEE IF OVERFLOW + STEP SC, J/ASHCL ;LOOP OVER ALL PLACES + [BR]_[BR]*2 LONG, ;SHIFT BACK WHERE IT GOES + ASHC, ASH AROV ;CAN STILL OVERFLOW +ASHCX: AC_[BR]+[BR], 3T, ;PUT BACK HIGH WORD + SKIP DP0 ;SEE HOW TO FIX LOW SIGN +=0 Q_Q.AND.#, #/377777, ;POSITIVE, CLEAR LOW SIGN + HOLD RIGHT, J/ASHCQ1 ;GO STORE ANSWER + Q_Q.OR.#, #/400000, ;NEGATIVE, SET LOW SIGN + HOLD RIGHT ;IN LEFT HALF +ASHCQ1: AC[1]_Q, NEXT INST ;PUT BACK Q AND EXIT + + .TOC "ROTATES AND LOGICAL SHIFTS -- ROTC" + +;SHIFT CONNECTIONS WHEN THE SPECIAL FUNCTION "ROTC" IS DONE: +; +; !----!------------------------------------! +; .....>!0000! HIGH ORDER 36 BITS ! RAM FILE +; : !----!------------------------------------! +; : ^ +; : : +; : ............................................ +; : : +; : : !----!------------------------------------! +; : ..!0000! LOW ORDER 36 BITS ! Q-REGISTER +; : !----!------------------------------------! +; : ^ +; : : +; :..............................................: +; + +1470: +ROTC: STEP SC, J/ROTCL +1471: READ [AR], SC_-SHIFT-1 + STEP SC +=0 +ROTCR: [BR]_[BR]*.5 LONG,STEP SC,ROTC,J/ROTCR + [BR]_[BR]*2 LONG,J/LSHCX + +=0 +ROTCL: [BR]_[BR]*2 LONG,ROTC,STEP SC,J/ROTCL + [BR]_[BR]*2 LONG, + J/LSHCX + + .TOC "CIRC" + +.IF/CIRC + +1665: +CIRC: Q_AC[1] ;PUT LOW WORD IN Q + [BR]_AC*.5 LONG ;PUT AC IN BR & SHIFT BR!Q RIGHT + [BR]_[BR]*.5 LONG ;SHIFT BR!Q 1 MORE PLACE RIGHT + READ [AR], ;LOOK AT EFFECTIVE ADDRESS + SKIP DP18, ;SEE IF LEFT OR RIGHT + SC_SHIFT-1 ;PUT NUMBER OF PLACES TO SHIFT IN + ; SC AND FE (ASSUMING LEFT SHIFT) +=0 STEP SC, J/CIRCL ;GO LEFT SHIFT + READ [AR], SC_-SHIFT-1 ;CORRECT FOR RIGHT SHIFT + STEP SC, J/CIRCR ;GO RIGHT SHIFT + +CIRCLA: [BR]_[BR]*.5 LONG, ROTC ;BOTH WORDS RIGHT + [BR]_[BR]*2, ROT, STEP SC ;FIRST WORD LEFT, STEP +=0 +CIRCL: [BR]_[BR]*2, ROT, J/CIRCLA ;FIRST WORD LEFT + [BR]_[BR]*2 LONG, J/LSHCX ;DONE + +CIRCRA: [BR]_[BR]*2 LONG, ROTC ;BOTH WORDS LEFT + [BR]_[BR]*.5, ROT, STEP SC ;FIRST WORD RIGHT, STEP +=0 +CIRCR: [BR]_[BR]*.5, ROT, J/CIRCRA ;FIRST WORD RIGHT + [BR]_[BR]*2 LONG, J/LSHCX ;DONE + +.ENDIF/CIRC + + .TOC "TEST GROUP" + + .DCODE + +;SPECIAL MACROS USED ONLY IN B-FIELD OF TEST INSTRUCTIONS +TN- "B/4" +TNE "B/0" +WORD-TNE "B/10" ;USED IN TIOE +TNA "B/0" +TNN "B/4" +WORD-TNN "B/14" ;USED IN TION +TZ- "B/5" +TZE "B/1" +TZA "B/1" +TZN "B/5" +TC- "B/6" +TCE "B/2" +TCA "B/2" +TCN "B/6" +TO- "B/7" +TOE "B/3" +TOA "B/3" +TON "B/7" + +600: I, J/DONE ;TRN- IS NOP + I, J/DONE ;SO IS TLN- + I, TNE, J/TDXX + I, TNE, J/TSXX + I, TNA, J/TDX + I, TNA, J/TSX + I, TNN, J/TDXX + I, TNN, J/TSXX + +610: I, J/DONE ;TDN- IS A NOP + I, J/DONE ;TSN- ALSO + R, TNE, J/TDXX + R, TNE, J/TSXX + R, TNA, J/TDX + R, TNA, J/TSX + R, TNN, J/TDXX + R, TNN, J/TSXX + +620: I, TZ-, J/TDX + I, TZ-, J/TSX + I, TZE, J/TDXX + I, TZE, J/TSXX + I, TZA, J/TDX + I, TZA, J/TSX + I, TZN, J/TDXX + I, TZN, J/TSXX + +630: R, TZ-, J/TDX + R, TZ-, J/TSX + R, TZE, J/TDXX + R, TZE, J/TSXX + R, TZA, J/TDX + R, TZA, J/TSX + R, TZN, J/TDXX + R, TZN, J/TSXX + +640: I, TC-, J/TDX + I, TC-, J/TSX + I, TCE, J/TDXX + I, TCE, J/TSXX + I, TCA, J/TDX + I, TCA, J/TSX + I, TCN, J/TDXX + I, TCN, J/TSXX + +650: R, TC-, J/TDX + R, TC-, J/TSX + R, TCE, J/TDXX + R, TCE, J/TSXX + R, TCA, J/TDX + R, TCA, J/TSX + R, TCN, J/TDXX + R, TCN, J/TSXX +660: I, TO-, J/TDX + I, TO-, J/TSX + I, TOE, J/TDXX + I, TOE, J/TSXX + I, TOA, J/TDX + I, TOA, J/TSX + I, TON, J/TDXX + I, TON, J/TSXX + +670: R, TO-, J/TDX + R, TO-, J/TSX + R, TOE, J/TDXX + R, TOE, J/TSXX + R, TOA, J/TDX + R, TOA, J/TSX + R, TON, J/TDXX + R, TON, J/TSXX + + .UCODE + +;THESE 64 INSTRUCTIONS ARE DECODED BY MASK MODE(IMMEDIATE OR MEMORY) +; IN THE A FIELD, DISPATCH TO HERE ON THE J FIELD, AND RE-DISPATCH +; FOR THE MODIFICATION ON THE B FIELD. + +; ENTER WITH 0,E OR (E) IN AR, B FIELD BITS 2 AND 3 AS FOLLOWS: +; 0 0 NO MODIFICATION +; 0 1 0S +; 1 0 COMPLEMENT +; 1 1 ONES +; THIS ORDER HAS NO SIGNIFICANCE EXCEPT THAT IT CORRESPONDS TO THE +; ORDER OF INSTRUCTIONS AT TGROUP. + +;THE BIT 1 OF THE B FIELD IS USED TO DETERMINE THE SENSE +; OF THE SKIP +; 1 SKIP IF AC.AND.MASK .NE. 0 (TXX- AND TXXN) +; 0 SKIP IF AC.AND.MASK .EQ. 0 (TXXA AND TXXE) + +;BIT 0 IS UNUSED AND MUST BE ZERO + + +1472: +TSX: [AR]_[AR] SWAP ;TSXX AND TLXX +1473: +TDX: [BR]_0,TEST DISP ; ALWAYS AND NEVER SKIP CASES + +1474: +TSXX: [AR]_[AR] SWAP ;TSXE, TSXN, TLXE, TLXN +1475: +TDXX: [BR]_[AR].AND.AC, ;TDXE, TDXN, TRXE, TRXN + TEST DISP + +;TEST DISP DOES AN 8 WAY BRANCH BASED ON THE B-FIELD OF DROM + +=1100 +TEST-TABLE: + +;CASE 0 & 4 -- TXNX +TXXX: READ [BR], TXXX TEST, 3T, J/DONE + +;CASE 1 & 5 -- TXZ AND TXZX + [AR]_.NOT.[AR],J/TXZX + +;CASE 2 & 6 -- TXC AND TXCX + [AR]_[AR].XOR.AC,J/TDONE + +;CASE 3 & 7 -- TXO AND TXOX + [AR]_[AR].OR.AC,J/TDONE + +;THE SPECIAL FUNCTION TXXX TEST CAUSES A MICROCODE SKIP IF +; AD.EQ.0 AND DROM B IS 0-3 OR AD.NE.0 AND DROM B IS 4-7. + +TXZX: [AR]_[AR].AND.AC +TDONE: AC_[AR],J/TXXX +; READ BR,TXXX TEST,J/DONE + + .TOC "COMPARE -- CAI, CAM" + + .DCODE + +;SPECIAL B-FIELD ENCODING USED BY SKIP-JUMP-COMPARE CLASS +; INSTRUCTIONS: + +SJC- "B/0" ;NEVER +SJCL "B/1" ;LESS +SJCE "B/2" ;EQUAL +SJCLE "B/3" ;LESS EQUAL +SJCA "B/4" ;ALWAYS +SJCGE "B/5" ;GREATER THAN OR EQUAL +SJCN "B/6" ;NOT EQUAL +SJCG "B/7" ;GREATER + + .UCODE + +;COMPARE TABLE +=1000 +SKIP-COMP-TABLE: + +;CASE 0 -- NEVER + DONE + +;CASE 1 -- LESS + READ [AR], SKIP DP0,J/DONE + +;CASE 2 -- EQUAL +SKIPE: READ [AR], SKIP AD.EQ.0,J/DONE + +;CASE 3 -- LESS OR EQUAL + READ [AR], SKIP AD.LE.0,J/DONE + +;CASE 4 -- ALWAYS + VMA_[PC]+1, NEXT INST FETCH, FETCH + +;CASE 5 -- GREATER THAN OR EQUAL + READ [AR], SKIP DP0,J/SKIP + +;CASE 6 -- NOT EQUAL + READ [AR], SKIP AD.EQ.0,J/SKIP + +;CASE 7 -- GREATER + READ [AR], SKIP AD.LE.0,J/SKIP + + .DCODE +300: I, SJC-, J/DONE ;CAI + I, SJCL, J/CAIM + I, SJCE, J/CAIM + I, SJCLE, J/CAIM + I, SJCA, J/CAIM + I, SJCGE, J/CAIM + I, SJCN, J/CAIM + I, SJCG, J/CAIM + +310: R, SJC-, J/CAIM ;CAM + R, SJCL, J/CAIM + R, SJCE, J/CAIM + R, SJCLE, J/CAIM + R, SJCA, J/CAIM + R, SJCGE, J/CAIM + R, SJCN, J/CAIM + R, SJCG, J/CAIM + .UCODE + +1476: +CAIM: [AR]_AC-[AR], 3T, SKIP-COMP DISP + + .TOC "ARITHMETIC SKIPS -- AOS, SOS, SKIP" +;ENTER WITH (E) IN AR + + .DCODE +330: R, SJC-, J/SKIPS ;NOT A NOP IF AC .NE. 0 + R, SJCL, J/SKIPS + R, SJCE, J/SKIPS + R, SJCLE, J/SKIPS + R, SJCA, J/SKIPS + R, SJCGE, J/SKIPS + R, SJCN, J/SKIPS + R, SJCG, J/SKIPS + .UCODE + +1477: +SKIPS: FIX [AR] SIGN, + SKIP IF AC0 +=0 AC_[AR],SKIP-COMP DISP + SKIP-COMP DISP + + .DCODE +350: RW, SJC-, J/AOS + RW, SJCL, J/AOS + RW, SJCE, J/AOS + RW, SJCLE, J/AOS + RW, SJCA, J/AOS + RW, SJCGE, J/AOS + RW, SJCN, J/AOS + RW, SJCG, J/AOS + .UCODE + +1431: +AOS: [AR]_[AR]+1, 3T, AD FLAGS +XOS: START WRITE + MEM WRITE,MEM_[AR],J/SKIPS + + .DCODE +370: RW, SJC-, J/SOS + RW, SJCL, J/SOS + RW, SJCE, J/SOS + RW, SJCLE, J/SOS + RW, SJCA, J/SOS + RW, SJCGE, J/SOS + RW, SJCN, J/SOS + RW, SJCG, J/SOS + .UCODE + +1437: +SOS: [AR]_[AR]-1, 3T, AD FLAGS, J/XOS + + .TOC "CONDITIONAL JUMPS -- JUMP, AOJ, SOJ, AOBJ" +; ENTER WITH E IN AR + +=1000 +JUMP-TABLE: + +;CASE 0 -- NEVER + AC_[BR], NEXT INST + +;CASE 1 -- LESS + AC_[BR] TEST, SKIP DP0, J/JUMP- + +;CASE 2 -- EQUAL + AC_[BR] TEST, SKIP AD.EQ.0, J/JUMP- + +;CASE 3 -- LESS THAN OR EQUAL + AC_[BR] TEST, SKIP AD.LE.0, J/JUMP- + +;CASE 4 -- ALWAYS +JMPA: AC_[BR], J/JUMPA + +;CASE 5 -- GREATER THAN OR EQUAL TO + AC_[BR] TEST, SKIP DP0, J/JUMPA + +;CASE 6 -- NOT EQUAL + AC_[BR] TEST, SKIP AD.EQ.0, J/JUMPA + +;CASE 7 -- GREATER + AC_[BR] TEST, SKIP AD.LE.0, J/JUMPA + +=0 +JUMP-: DONE + JUMPA + +=0 +JUMPA: JUMPA + DONE + + + .DCODE +320: I, SJC-, J/DONE + I, SJCL, J/JUMP + I, SJCE, J/JUMP + I, SJCLE, J/JUMP + I, SJCA, J/JRST + I, SJCGE, J/JUMP + I, SJCN, J/JUMP + I, SJCG, J/JUMP + .UCODE + +1440: +JUMP: [BR]_AC,JUMP DISP + + .DCODE +340: I-PF, SJC-, J/AOJ + I, SJCL, J/AOJ + I, SJCE, J/AOJ + I, SJCLE, J/AOJ + I, SJCA, J/AOJ + I, SJCGE, J/AOJ + I, SJCN, J/AOJ + I, SJCG, J/AOJ + .UCODE + +1611: +AOJ: [BR]_AC+1, AD FLAGS, 4T, JUMP DISP + + .DCODE +360: I-PF, SJC-, J/SOJ + I, SJCL, J/SOJ + I, SJCE, J/SOJ + I, SJCLE, J/SOJ + I, SJCA, J/SOJ + I, SJCGE, J/SOJ + I, SJCN, J/SOJ + I, SJCG, J/SOJ + .UCODE + +1542: +SOJ: [BR]_AC-1, AD FLAGS, 4T, JUMP DISP + + .DCODE +252: I, SJCGE, J/AOBJ + I, SJCL, J/AOBJ + .UCODE + +1547: +AOBJ: [BR]_AC+1000001, ;ADD 1 TO BOTH HALF WORDS + INH CRY18, 3T, ;NO CARRY INTO LEFT HALF + JUMP DISP ;HANDLE EITHER AOBJP OR AOBJN + + .TOC "AC DECODE JUMPS -- JRST, JFCL" + + .DCODE +254: I,VMA/0, AC DISP, J/JRST ;DISPATCHES TO 1 OF 16 + ; PLACES ON AC BITS + I, J/JFCL + .UCODE + +;JRST DISPATCHES TO ONE OF 16 LOC'NS ON AC BITS + +=0000 +1520: +JRST: JUMPA ;(0) JRST 0, +1521: JUMPA ;(1) PORTAL IS SAME AS JRST +1522: VMA_[PC]-1, START READ, ;(2) JRSTF + J/JRSTF +1523: UUO ;(3) +1524: SKIP KERNEL, J/HALT ;(4) HALT +1525: +XJRSTF0: VMA_[AR], START READ, ;(5) XJRSTF + J/XJRSTF +1526: SKIP KERNEL, J/XJEN ;(6) XJEN +1527: SKIP KERNEL, J/XPCW ;(7) XPCW +1530: VMA_[PC]-1, START READ, ;(10) + SKIP IO LEGAL, J/JRST10 +1531: UUO ;(11) +1532: VMA_[PC]-1, START READ, ;(12) JEN + SKIP IO LEGAL, J/JEN +1533: UUO ;(13) +1534: SKIP KERNEL, J/SFM ;(14) SFM +1535: UUO ;(15) +1536: UUO ;(16) +1537: UUO ;(17) + +=0* +JRSTF: MEM READ, ;WAIT FOR DATA + [HR]_MEM, ;STICK IN HR + LOAD INST EA, ;LOAD @ AND XR + CALL [JRST0] ;COMPUTE EA AGAIN + JUMPA ;JUMP + +JRST0: EA MODE DISP ;WHAT TYPE OF EA? +=100* +.IF/1PROC + [BR]_XR, ;INDEXED + LOAD FLAGS, ;GET FLAGS FROM XR + UPDATE USER, ;ALLOW USER TO SET + J/JRST2 + + [BR]_[HR], ;PLAIN + LOAD FLAGS, ;LOAD FLAGS FROM INST + UPDATE USER, ;ALLOW USER TO SET + J/JRST2 +.IFNOT/1PROC + READ XR, ;INDEXED + LOAD FLAGS, ;GET FLAGS FROM XR + UPDATE USER, ;ALLOW USER TO SET + RETURN [2] ;ALL DONE + + READ [HR], ;PLAIN + LOAD FLAGS, ;LOAD FLAGS FROM INST + UPDATE USER, ;ALLOW USER TO SET + RETURN [2] ;RETURN +.ENDIF/1PROC + [HR]_[HR]+XR, ;BOTH + LOAD VMA, ;FETCH IND WORD + START READ, ;START MEM CYCLE + J/JRST1 ;CONTINUE BELOW + + VMA_[HR], ;INDIRECT + START READ, ;FETCH IND WORD + PXCT EA, ;SETUP PXCT STUFF + J/JRST1 ;CONTINUE BELOW + +JRST1: MEM READ, ;WAIT FOR DATA + [HR]_MEM, ;LOAD THE HR + LOAD INST EA, ;LOAD @ AND XR + J/JRST0 ;LOOP BACK + +.IF/1PROC ;BR HAS PC FLAGS THAT WERE JUST LOADED +JRST2: TL [BR], OIPBIT/1 ;ARE WE TRYING TO ONE-PROCEED? +=0 [FLG]_[FLG].OR.#, FLG.1PROC/1, HOLD RIGHT, RETURN [2] + RETURN [2] +.ENDIF/1PROC + +=0 +HALT: UUO ;USER MODE + [PC]_[AR] ;EXEC MODE--CHANGE PC + HALT [HALT] ;HALT INSTRUCTION + +=0 +JRST10: UUO + J/JEN2 ;DISMISS INTERRUPT +=0000 +JEN: UUO ; FLAGS + MEM READ, + [HR]_MEM, ;GET INST + LOAD INST EA, ;LOAD XR & @ + CALL [JRST0] ;COMPUTE FLAGS +=0011 +JEN2: DISMISS ;DISMISS INTERRUPT +=0111 CALL LOAD PI ;RELOAD PI HARDWARE +=1111 JUMPA ;GO JUMP += + +1540: +JFCL: JFCL FLAGS, ;ALL DONE IN HARDWARE + SKIP JFCL, ;SEE IF SKIPS + 3T, ;ALLOW TIME + J/JUMP- ;JUMP IF WE SHOULD + + .TOC "EXTENDED ADDRESSING INSTRUCTIONS" + +=0000 +XJEN: UUO ;HERE IF USER MODE + DISMISS ;CLEAR HIGHEST INTERRUPT +=0101 READ [MASK], LOAD PI ;NO MORE INTERRUPTS +=1101 ABORT MEM CYCLE, ;AVOID INTERRUPT PAGE FAIL + J/XJRSTF0 ;START READING FLAG WORD += + +XJRSTF: MEM READ, [BR]_MEM ;PUT FLAGS IN BR + [AR]_[AR]+1, ;INCREMENT ADDRESS + LOAD VMA, ;PUT RESULT IN VMA + START READ ;START MEMORY + MEM READ, [PC]_MEM, ;PUT DATA IN PC + HOLD LEFT ;IGNORE SECTION NUMBER + READ [BR], LOAD FLAGS, ;LOAD NEW FLAGS + UPDATE USER ;SET BUT DON'T CLEAR USER FLAG +PISET: [FLG]_[FLG].AND.NOT.#, ;CLEAR PI CYCLE + FLG.PI/1, HOLD RIGHT, ;RELOAD PI HARDWARE + J/PIEXIT ; IN CASE THIS IS AN + ; INTERRUPT INSTRUCTION + +=0 +XPCW: UUO ;USER MODE + [BR]_FLAGS ;PUT FLAGS IN BR +=0*0 +PIXPCW: VMA_[AR], START WRITE, ;STORE FLAGS + CALL [STOBR] ;PUT BR IN MEMORY +=1*0 VMA_[AR]+1, LOAD VMA, + START WRITE, ;PREPEARE TO STORE PC + CALL [STOPC] ;PUT PC IN MEMORY +=1*1 [AR]_[AR]+1, ;DO NEW PC PART + START READ, J/XJRSTF += + +=0 +SFM: UUO + VMA_[AR], START WRITE ;STORE FLAGS + [AR]_FLAGS, J/STORE ;STORE AND EXIT + + .TOC "XCT, XCTR, XCTRI" + + .DCODE +.IF/ITS +102: I, J/XCTRI + I, J/XCTR +.ENDIF/ITS +256: R, J/XCT ;OPERAND FETCHED AS DATA + .UCODE + +.IF/ITS +1662: +XCTRI: SKIP KERNEL, J/XCTR1 +1663: +XCTR: SKIP KERNEL, J/XCTR1 +=0 +XCTR1: UUO + READ [HR], LOAD PXCT, START READ += MEM READ, [AR]_MEM, J/XCT + +1541: +XCT: [HR]_[AR], ;STUFF INTO HR + DBUS/DP, ;PLACE ON DBUS FOR IR + LOAD INST, ;LOAD IR, AC, XR, ETC. + PXCT/E1 ;ALLOW XR TO BE PREVIOUS +XCT1: WORK[YSAVE]_[HR] CLR LH,;SAVE FOR IO INSTRUCTIONS + J/XCT2 ;GO EXECUTE IT +.IFNOT/ITS +1541: +XCT: SKIP KERNEL ;SEE IF MAY BE PXCT +=0 +XCT1A: [HR]_[AR], ;STUFF INTO HR + DBUS/DP, ;PLACE ON DBUS FOR IR + LOAD INST, ;LOAD IR, AC, XR, ETC. + PXCT/E1, ;ALLOW XR TO BE PREVIOUS + J/XCT1 ;CONTINUE BELOW + READ [HR], ;LOAD PXCT FLAGS + LOAD PXCT, ; .. + J/XCT1A ;CONTINUE WITH NORMAL FLOW + +XCT1: WORK[YSAVE]_[HR] CLR LH,;SAVE FOR IO INSTRUCTIONS + J/XCT2 ;GO EXECUTE IT +.ENDIF/ITS + + .TOC "STACK INSTRUCTIONS -- PUSHJ, PUSH, POP, POPJ" + + .DCODE +260: I, B/0, J/PUSHJ + IR, B/2, J/PUSH + I, B/2, J/POP + I, J/POPJ + .UCODE + +;ALL START WITH E IN AR +1543: +PUSH: MEM READ, ;PUT MEMOP IN BR + [BR]_MEM ; .. +PUSH1: [ARX]_AC+1000001, ;BUMP BOTH HALVES OF AC + INH CRY18, ;NO CARRY + LOAD VMA, ;START TO STORE ITEM + START WRITE, ;START MEM CYCLE + PXCT STACK WORD, ;THIS IS THE STACK DATA WORD + 3T, ;ALLOW TIME + SKIP CRY0, ;GO TO STMAC, SKIP IF PDL OV + J/STMAC ; .. + +1544: +PUSHJ: [BR]_PC WITH FLAGS, ;COMPUTE UPDATED FLAGS + CLR FPD, ;CLEAR FIRST-PART-DONE + J/PUSH1 ; AND JOIN PUSH CODE + +=0 +STMAC: MEM WRITE, ;WAIT FOR MEMORY + MEM_[BR], ;STORE BR ON STACK + B DISP, ;SEE IF PUSH OR PUSHJ + J/JSTAC ;BELOW +;WE MUST STORE THE STACK WORD PRIOR TO SETTING PDL OV IN CASE OF +; PAGE FAIL. + MEM WRITE, ;WAIT FOR MEMORY + MEM_[BR] ;STORE BR +SETPDL: SET PDL OV, ;OVERFLOW + B DISP, ;SEE IF PUSH OR PUSHJ + J/JSTAC ;BELOW + +=00 +JSTAC: [PC]_[AR], ;PUSHJ--LOAD PC + LOAD VMA, ;LOAD ADDRESS + FETCH ;GET NEXT INST +JSTAC1: AC_[ARX], ;STORE BACK STACK PTR + NEXT INST ;DO NEXT INST + AC_[ARX], ;UPDATE STACK POINTER + J/DONE ;DO NEXT INST += + +1545: +POP: [ARX]_AC, ;GET POINTER + LOAD VMA, ;ADDRESS OF STACK WORD + START READ, 3T, ;START CYCLE + PXCT STACK WORD ;FOR PXCT + + MEM READ, ;LOAD BR (QUIT IF PAGE FAIL) + [BR]_MEM ;STACK WORD TO BR + + [ARX]_[ARX]+#, ;UPDATE POINTER + #/777777, ;-1 IN EACH HALF + INH CRY18, 3T, ;BUT NO CARRY + SKIP CRY0 ;SEE IF OVERFLOW + +=0 VMA_[AR], ;EFFECTIVE ADDRESS + PXCT DATA, ;FOR PXCT + START WRITE, ;WHERE TO STORE RESULT + J/POPX1 ;OVERFLOW + + VMA_[AR], ;EFFECTIVE ADDRESS + PXCT DATA, ;FOR PXCT + START WRITE ;WHERE TO STORE RESULT + + MEM WRITE, ;WAIT FOR MEM + MEM_[BR], ;STORE BR + B DISP, ;POP OR POPJ? + J/JSTAC ;STORE POINTER + + +POPX1: MEM WRITE, ;WAIT FOR MEMORY + MEM_[BR], ;STORE BR + J/SETPDL ;GO SET PDL OV + +1546: +POPJ: [ARX]_AC, ;GET POINTER + LOAD VMA, ;POINT TO STACK WORD + PXCT STACK WORD, 3T, ;FOR PXCT + START READ ;START READ + [ARX]_[ARX]+#, ;UPDATE POINTER + #/777777, ;-1 IN BOTH HALFS + INH CRY18, 3T, ;INHIBIT CARRY 18 + SKIP CRY0 ;SEE IF OVERFLOW +=0 SET PDL OV ;SET OVERFLOW + MEM READ, [PC]_MEM, ;STICK DATA IN PC + HOLD LEFT, ;NO FLAGS + J/JSTAC1 ;STORE POINTER + + .TOC "STACK INSTRUCTIONS -- ADJSP" + + .DCODE +105: I-PF, B/0, J/ADJSP + .UCODE + +1551: +ADJSP: [AR]_[AR] SWAP, ;MAKE 2 COPIES OF RH + HOLD RIGHT + [BR]_AC, ;READ AC, SEE IF MINUS + 3T, + SKIP DP0 +=0 AC_[BR]+[AR], ;UPDATE AC + INH CRY18, ;NO CARRY + SKIP DP0, ;SEE IF STILL OK + 3T, ;ALLOW TIME + J/ADJSP1 ;TEST FOR OFLO + AC_[BR]+[AR], ;UPDATE AC + INH CRY18, ;NO CARRY + SKIP DP0, ;SEE IF STILL MINUS + 3T, ;ALLOW TIME FOR SKIP + J/ADJSP2 ;CONTINUE BELOW + +=0 +ADJSP1: NEXT INST ;NO OVERFLOW + SET PDL OV, ;SET PDL OV + J/NIDISP ;GO DO NICOND DISP + +=0 +ADJSP2: SET PDL OV, ;SET PDL OV + J/NIDISP ;GO DO NICOND DISP + NEXT INST ;NO OVERFLOW + + .TOC "SUBROUTINE CALL/RETURN -- JSR, JSP, JSA, JRA" + + .DCODE +264: I, J/JSR + I, J/JSP + I, J/JSA + I, J/JRA + .UCODE + +1550: +JSP: [BR]_PC WITH FLAGS ;GET PC WITH FLAGS + CLR FPD, ;CLEAR FIRST-PART-DONE + AC_[BR], ;STORE FLAGS + J/JUMPA ;GO JUMP + +1552: +JSR: [BR]_PC WITH FLAGS, ;GET PC WITH FLAGS + CLR FPD ;CLEAR FIRST-PART-DONE + VMA_[AR], ;EFFECTIVE ADDRESS + START WRITE ;STORE OLD PC WORD + MEM WRITE, ;WAIT FOR MEMORY + MEM_[BR] ;STORE + [PC]_[AR]+1000001, ;PC _ E+1 + HOLD LEFT, ;NO JUNK IN LEFT + 3T, ;ALLOW TIME FOR DBM + J/DONE ;[127] START AT E+1 + ;[127] MUST NICOND TO CLEAR TRAP CYCLE + + +1554: +JSA: [BR]_[AR], ;SAVE E + START WRITE ;START TO STORE + [ARX]_[AR] SWAP ;ARX LEFT _ E +=0*0 [AR]_AC, ;GET OLD AC + CALL [IBPX] ;SAVE AR IN MEMORY +=1*0 [ARX]_[PC], ;ARX NOW HAS E,,PC + HOLD LEFT, ; .. + CALL [AC_ARX] ;GO PUT ARX IN AC +=1*1 [PC]_[BR]+1000001, ;NEW PC + 3T, ;ALLOW TIME + HOLD LEFT, ;NO JUNK IN PC LEFT + J/DONE ;[127] START AT E+1 + ;[127] MUST NICOND TO CLEAR TRAP CYCLE += + +1555: +JRA: [BR]_AC ;GET AC + [BR]_[BR] SWAP ;OLD E IN BR RIGHT + VMA_[BR], ;LOAD VMA + START READ ;FETCH SAVED AC + MEM READ, ;WAIT FOR MEMORY + [BR]_MEM, ;LOAD BR WITH SAVE AC + J/JMPA ;GO JUMP + + .TOC "ILLEGAL INSTRUCTIONS AND UUO'S" +;LUUO'S TRAP TO CURRENT CONTEXT + + .DCODE +030: I, B/0, J/LUUO + I, B/1, J/LUUO + I, B/2, J/LUUO + I, B/3, J/LUUO + I, B/4, J/LUUO + I, B/5, J/LUUO + I, B/6, J/LUUO + I, B/7, J/LUUO + +;MONITOR UUO'S -- TRAP TO EXEC + +040: I, J/MUUO ;CALL + I, J/MUUO ;INIT + I, J/MUUO + I, J/MUUO + I, J/MUUO + I, J/MUUO + I, J/MUUO + I, J/MUUO ;CALLI + I, J/MUUO ;OPEN + I, J/MUUO ;TTCALL + I, J/MUUO + I, J/MUUO + I, J/MUUO + I, J/MUUO ;RENAME + I, J/MUUO ;IN + I, J/MUUO ;OUT + I, J/MUUO ;SETSTS + I, J/MUUO ;STATO + I, J/MUUO ;GETSTS + I, J/MUUO ;STATZ + I, J/MUUO ;INBUF + I, J/MUUO ;OUTBUF + I, J/MUUO ;INPUT + I, J/MUUO ;OUTPUT + I, J/MUUO ;CLOSE + I, J/MUUO ;RELEAS + I, J/MUUO ;MTAPE + I, J/MUUO ;UGETF + I, J/MUUO ;USETI + I, J/MUUO ;USETO + I, J/MUUO ;LOOKUP + I, J/MUUO ;ENTER + +;EXPANSION OPCODES + +100: I, J/UUO ;UJEN + I, J/UUO101 +.IFNOT/ITS + I, J/UUO102 ;XCTRI in ITS + I, J/UUO103 ;XCTR in ITS +.ENDIF/ITS + +;RESERVED OPCODES + +000: I, J/UUO +104: I, J/JSYS ;JSYS +106: I, J/UUO106 + I, J/UUO107 +130: I, B/0, J/FP-LONG ;UFA + I, B/1, J/FP-LONG ;DFN +141: I, B/2, J/FP-LONG ;FADL +151: I, B/3, J/FP-LONG ;FSBL +161: I, B/4, J/FP-LONG ;FMPL +171: I, B/5, J/FP-LONG ;FDVL +.IFNOT/CIRC +247: I, J/UUO247 ;RESERVED +.ENDIF/CIRC + .UCODE + +1661: +UUO101: UUO + +.IFNOT/ITS +1662: +UUO102: UUO ;XCTRI in ITS +1663: +UUO103: UUO ;XCTR in ITS +.ENDIF/ITS + +1664: +JSYS: UUO +1666: +UUO106: UUO +1667: +UUO107: UUO +1660: +FP-LONG:UUO +.IFNOT/CIRC +1665: +UUO247: UUO +.ENDIF/CIRC + +;HERE FOR UUO'S WHICH TRAP TO EXEC +1556: +UUO: ;THIS TAG IS USED FOR ILLEGAL THINGS WHICH DO UUO TRAPS +MUUO: ;THIS TAG IS USED FOR MONITOR CALL INSTRUCTIONS + [HR]_[HR].AND.#, ;MASK OUT @ AND XR + #/777740, ;MASK + HOLD RIGHT ;KEEP RIGHT +;THE UUO MACRO DOES THE ABOVE INSTRUCTION AND GOES TO UUOGO +UUOGO: [ARX]_0 XWD [424] ;HERE FROM UUO MACRO + ;GET OFFSET TO UPT +=0 [ARX]_[ARX]+[UBR], ;ADDRESS OF MUUO WORD + CALL [ABORT] ;STOP MEMORY + READ [EBR], ;KL PAGING + SKIP DP0 ; ?? +=0 READ [ARX], ;GET THE ADDRESS + LOAD VMA, ;START WRITE + VMA PHYSICAL WRITE, ;ABSOLUTE ADDRESS + J/KIMUUO ;GO STORE KI STYLE + [AR]_[HR] SWAP ;PUT IN RIGHT HALF +=0 [AR]_FLAGS, ;FLAGS IN LEFT HALF + HOLD RIGHT, ;JUST WANT FLAGS + CALL [UUOFLG] ;CLEAR TRAP FLAGS + READ [ARX], ;LOOK AT ADDRESS + LOAD VMA, ;LOAD THE VMA + VMA PHYSICAL WRITE ;STORE FLAG WORD +=0* MEM WRITE, ;WAIT FOR MEMORY + MEM_[AR], CALL [NEXT] ;STORE + MEM WRITE, ;WAIT FOR MEMORY + MEM_[PC] ;STORE FULL WORD PC +=000 [HR]_0, ;SAVE E + HOLD RIGHT, CALL [NEXT] ;BUT CLEAR OPCODE +=010 +UUOPCW: MEM WRITE, ;WAIT FOR MEMORY + MEM_[HR], ;STORE INSTRUCTION IN KI + ; OR FULL WORD E IN KL + CALL [GETPCW] ;GET PROCESS-CONTEXT-WORD + +=011 NEXT [ARX] PHYSICAL WRITE, ;POINT TO NEXT WORD + CALL [STOBR] ;STORE PROCESS CONTEXT WORD + +;NOW WE MUST PICK ONE OF 8 NEW PC WORDS BASED ON PC FLAGS +=111 [BR]_0 XWD [430] ;OFFSET INTO UPT += + [BR]_[BR]+[UBR] ;ADDRESS OF WORD + [AR]_FLAGS ;GET FLAGS + TL [AR], ;LOOK AT FLAGS + #/600 ;TRAP SET? +=0 [BR]_[BR].OR.#, ;YES--POINT TO TRAP CASE + #/1, ; .. + HOLD LEFT ;LEAVE LEFT ALONE + TL [AR], ;USER OR EXEC + #/10000 ; .. +=0 [BR]_[BR].OR.#, ;USER + #/4, ;POINT TO USER WORDS + HOLD LEFT + READ [BR], ;LOOK AT ADDRESS + LOAD VMA, ;PLACE IN VMA + VMA PHYSICAL, ;PHYSICAL ADDRESS + START READ ;GET NEW PC WORD + ;;Page fault delivering code joins in here. + ;;J/EAPF1 DEC Paging + ;;J/PFTRAP1 ITS Paging +GOEXEC: MEM READ, ;WAIT FOR DATA + [AR]_MEM ;STICK IN AR + READ [AR], ;LOOK AT DATA + LOAD FLAGS, ;LOAD NEW FLAGS + LEAVE USER, ;ALLOW USER TO LOAD + LOAD PCU, ;SET PCU FROM USER + J/JUMPA ;JUMP + + +;HERE FOR TOPS-10 STYLE PAGING + +=00 +KIMUUO: MEM WRITE, ;STORE INSTRUCTION + MEM_[HR], CALL [NEXT] ;IN MEMORY +=10 [AR]_PC WITH FLAGS, ;GET PC WORD + CALL [UUOFLG] ;CLEAR TRAP FLAGS +=11 MEM WRITE, ;STORE PC WORD + MEM_[AR], ; .. + J/UUOPCW ;GO STORE PROCESS CONTEXT + +UUOFLG: [AR]_[AR].AND.NOT.#, ;CLEAR TRAP FLAGS + #/600, HOLD RIGHT, ; IN WORD TO SAVE + RETURN [1] ; BACK TO CALLER + +NEXT: NEXT [ARX] PHYSICAL WRITE, ;POINT TO NEXT WORD + RETURN [2] + +;HERE FOR LUUO'S +1557: +LUUO: [AR]_0 XWD [40] ;AR GET CONSTANT 40 +;THE LUUO MACRO DOES THE ABOVE INSTRUCTION AND GOES TO LUUO1 +400: ;FOR SIMULATOR +LUUO1: READ [AR], ;LOAD 40 INTO + LOAD VMA, ; THE VMA AND + START WRITE ; PREPARE TO STORE + [HR]_[HR].AND.#, ;CLEAR OUT INDEX AND @ + #/777740, ; .. + HOLD RIGHT + MEM WRITE, ;STORE LUUO IN 40 + MEM_[HR] + VMA_[AR]+1, ;POINT TO 41 + LOAD VMA, ;PUT 41 IN VMA + START READ, ;START FETCH + J/CONT1 ;GO EXECUTE THE INSTRUCTION + + .TOC "ARITHMETIC -- ADD, SUB" + + .DCODE +270: R-PF, AC, J/ADD + I-PF, AC, J/ADD + RW, M, J/ADD + RW, B, J/ADD + .UCODE + +1560: +ADD: [AR]_[AR]+AC, ;DO THE ADD + AD FLAGS EXIT, 3T ;UPDATE CARRY FLAGS + ;STORE ANSWER + ;MISSES 3-TICKS BY 3 NS. + + + .DCODE +274: R-PF, AC, J/SUB + I-PF, AC, J/SUB + RW, M, J/SUB + RW, B, J/SUB + .UCODE + +1561: +SUB: [AR]_AC-[AR], ;DO THE SUBTRACT + AD FLAGS EXIT, 3T ;UPDATE PC CARRY FLAGS + ;ALL DONE + ;MISSES 3-TICKS BY 3 NS. + + .TOC "ARITHMETIC -- DADD, DSUB" + + .DCODE +114: DBL R, DAC, J/DADD + DBL R, DAC, J/DSUB + .UCODE + +1457: +DADD: [ARX]_[ARX]+AC[1], 4T, ;ADD LOW WORDS + SKIP CRY1 ;SEE IF CARRY TO HIGH WORD +=0 +DADD1: [AR]_[AR]+AC, ;ADD HIGH WORDS + ADD .25, ;ADD IN ANY CARRY FROM LOW WORD + AD FLAGS, 4T, ;UPDATE PC FLAGS + J/CPYSGN ;COPY SIGN TO LOW WORD + [BR]_.NOT.[MASK] ;SET BITS 35 AND 36 IN + [AR]_[AR].OR.[BR], ; AR SO THAT ADD .25 WILL + HOLD LEFT, J/DADD1 ; ADD 1. + +1615: +DSUB: [ARX]_AC[1]-[ARX], 4T, ;SUBTRACT LOW WORD + SKIP CRY1 ;SEE IF CARRY +=0 [AR]_AC-[AR]-.25, ;NO CARRY + AD FLAGS, 4T, ;UPDATE PC FLAGS + J/CPYSGN ;GO COPY SIGN + [AR]_AC-[AR], 4T, ;THERE WAS A CARRY + AD FLAGS ;UPDATE CARRY FLAGS + +CPYSGN: FIX [AR] SIGN, SKIP DP0 +=0 [ARX]_[ARX].AND.#, #/377777, HOLD RIGHT, J/MOVE + [ARX]_[ARX].OR.#, #/400000, HOLD RIGHT, J/MOVE + + + .TOC "ARITHMETIC -- MUL, IMUL" + + .DCODE +220: R-PF, AC, J/IMUL + I-PF, AC, J/IMUL + RW, M, J/IMUL + RW, B, J/IMUL + .UCODE +1641: +IMUL: [BRX]_[AR], AC ;COPY C(E) + Q_AC, SC_35. ;GET THE AC +=0** [BRX]_[BRX]*.5 LONG, ;SHIFT RIGHT + CALL [MULSUB] ;MULTIPLY + READ [ARX], SKIP AD.EQ.0 ;SEE IF FITS +=0 [ARX]_[ARX]*2, J/IMUL2 ;NOT ZERO--SHIFT LEFT +IMUL1: [AR]_Q, EXIT ;POSITIVE + +IMUL2: [MASK].AND.NOT.[ARX], ;SEE IF ALL SIGN BITS + SKIP AD.EQ.0 ; .. +=0 FIX [ARX] SIGN, ;NOT ALL SIGN BITS + SKIP DP0, J/IMUL3 ;GIVE + OR - OVERFLOW + [AR]_[MAG].EQV.Q, EXIT ;NEGATIVE +=0 +IMUL3: [AR]_Q, SET AROV, J/MOVE + [AR]_[MAG].EQV.Q, SET AROV, J/MOVE + + + .DCODE +224: R-PF, DAC, J/MUL + I-PF, DAC, J/MUL + RW, M, J/MUL + RW, DBL B, J/MUL + .UCODE + + +1571: +MUL: Q_[AR], AC ;COPY C(E) + [T0]_[AR] ;SAVE FOR OVERFLOW TEST + [BRX]_AC, SC_35. ;GET THE AC +=0** [BRX]_[BRX]*.5 LONG, ;SHIFT OVER + CALL [MULSUB] ;MULTIPLY + [AR]_[ARX]*2 ;SHIFT OVER + FIX [AR] SIGN, SKIP DP0 ;SEE IF NEGATIVE +=0 [ARX]_[MAG].AND.Q, ;POSITIVE + EXIT + [T0].AND.[BRX], SKIP DP0 ;TRIED TO SQUARE 1B0? +=0 [ARX]_[MAG].EQV.Q, EXIT ;NO + [ARX]_[MAG].EQV.Q, ;YES + SET AROV, J/MOVE + + + .TOC "ARITHMETIC -- DMUL" + + .DCODE +116: DBL R, DAC, J/DMUL + .UCODE + +.IF/FULL +1566: +DMUL: [AR]_[AR]*.5 ;SHIFT MEM OPERAND RIGHT + [ARX]_([ARX].AND.[MAG])*.5 + [BR]_[ARX], ;COPY LOW WORD + SKIP FPD ;SEE IF FIRST PART DONE +; +; BRX * BR ==> C(E+1) * C(AC+1) +; +=000 [BRX]_(AC[1].AND.[MAG])*.5, 3T, ;GET LOW AC + CALL [DMULGO] ;START MULTIPLY + [ARX]_(AC[2].AND.[MAG])*.5, 3T, ;FIRST PART DONE + J/DMUL1 ;GO DO SECOND PART +=100 AC[3]_Q ;SALT AWAY 1 WORD OF PRODUCT += +; +; BRX * Q ==> C(E) * C(AC+1) +; +=0** Q_[AR], SC_35., ;GO MULT NEXT HUNK + CALL [QMULT] ; .. + [T0]_[ARX] ;SAVE PRODUCT + AC[2]_Q, [ARX]_Q*.5, ;SAVE PRODUCT + J/DMUL2 ;GO DO HIGH HALF +DMUL1: [T0]_AC[1]*.5 ;RESTORE T0 +=0*0 +; +; BRX * BR ==> C(AC) * C(E+1) +; +DMUL2: [BRX]_AC*.5, ;PREPARE TO DO HIGH HALF + CALL [DBLMUL] ; GO DO IT + AC[1]_[T0]*2, 3T, ;INTERRUPT, SAVE T0 + J/DMLINT ;SET FPD AND INTERRUPT + AC[2]_Q ;SAVE PRODUCT += + [ARX]_[ARX]+[T0] ;PREPARE FOR LAST MUL +; +; BRX * Q ==> C(AC) * C(E) +; +=0** Q_[AR], SC_35., ;DO THE LAST MULTIPLY + CALL [QMULT] ; GO DO IT + [ARX]_[ARX]*2, ;SHIFT BACK + CLR FPD ;CLEAR FPD + + AC_[ARX] TEST, SKIP DP0 ;PUT BACK INTO AC +=0 AC[1]_Q, J/DMTRAP ;POSITIVE + AC[1]_[MAG].EQV.Q ;NEGATIVE + Q_AC[2] + AC[2]_[MAG].EQV.Q + Q_AC[3] + AC[3]_[MAG].EQV.Q +DMTRAP: [AR]_PC WITH FLAGS, ;LOOK AT FLAGS + SKIP DP0 ;SEE IF AROV SET? +=0 DONE ;NO--ALL DONE + SET AROV, J/DONE ;YES--FORCE TRAP 1 ALSO + + +;WAYS TO CALL MULTIPLY +DMULGO: [ARX]_0 ;CLEAR ARX +DBLMUL: Q_[BR], SC_35. + [BRX]_[BRX]*.5 +=0** +QMULT: Q_Q*.5, + CALL [MULTIPLY] + [ARX]+[ARX], AD FLAGS, ;TEST FOR OVERFLOW + 3T, RETURN [4] ;AND RETURN + +DMLINT: SET FPD, J/FIXPC ;SET FPD, BACKUP PC + ; INTERRUPT +.IFNOT/FULL +1566: +DMUL: UUO +.ENDIF/FULL + +;MULTIPLY SUBROUTINE +;ENTERED WITH: +; MULTIPLIER IN Q +; MULTIPLICAND IN BRX +;RETURNS 4 WITH PRODUCT IN ARX!Q + +MUL STEP "A/BRX,B/ARX,DEST/Q_Q*.5,ASHC,STEP SC,MUL DISP" +MUL FINAL "A/BRX,B/ARX,DEST/Q_Q*2" + +MULSUB: [BRX]_[BRX]*.5 LONG +MULSB1: [ARX]_0*.5 LONG, ;CLEAR ARX AND SHIFT Q + STEP SC, ;COUNT FIRST STEP + J/MUL+ ;ENTER LOOP + +;MULTIPLY SUBROUTINE +;ENTERED WITH: +; MULTIPLIER IN Q +; MULTIPLICAND IN BRX +; PARTIAL PRODUCT IN ARX +;RETURNS 4 WITH Q*BRX+ARX IN ARX!Q + +MULTIPLY: + Q_Q*.5, ;SHIFT Q + STEP SC, ;COUNT FIRST STEP + J/MUL+ ;ENTER LOOP + +;HERE FOR POSITIVE STEPS +=010 ;0 IN A POSITIVE STEP +MUL+: AD/B, ;DON'T ADD + MUL STEP, ;SHIFT + J/MUL+ ;KEEP POSITIVE +=011 ;DONE + AD/B, ;DON'T ADD + MUL FINAL, ;SHIFT + RETURN [4] ;SHIFT Q AND RETURN +=110 ;1 IN A POSITIVE STEP + AD/B-A-.25, ADD .25, ;SUBTRACT + MUL STEP, ;SHIFT AND COUNT + J/MUL- ;NEGATIVE NOW +=111 ;DONE + AD/B-A-.25, ADD .25, ;SUBTRACT + MUL FINAL, ;SHIFT + RETURN [4] ; AND RETURN + +;HERE FOR NEGATIVE STEPS +=010 ;0 IN NEGATIVE STEP +MUL-: AD/A+B, ;ADD + MUL STEP, ;SHIFT AND COUNT + J/MUL+ ;POSITIVE NOW +=011 ;DONE + AD/A+B, ;ADD + MUL FINAL, ;SHIFT + RETURN [4] ;FIX Q AND RETURN +=110 ;1 IN NEGATIVE STEP + AD/B, ;DON'T ADD + MUL STEP, ;SHIFT AND COUNT + J/MUL- ;STILL NEGATIVE +=111 ;DONE + AD/B, ;DON'T ADD + MUL FINAL, ;SHIFT + RETURN [4] ;FIX Q AND RETURN + + .TOC "ARITHMETIC -- DIV, IDIV" + + .DCODE +230: R-PF, DAC, J/IDIV + I-PF, DAC, J/IDIV + RW, M, J/IDIV + RW, DBL B, J/IDIV + +234: R-PF, DAC, J/DIV + I-PF, DAC, J/DIV + RW, M, J/DIV + RW, DBL B, J/DIV + .UCODE + +1600: +IDIV: [BR]_[AR], AC ;COPY MEMORY OPERAND + Q_AC, ;LOAD Q + SKIP DP0 ;SEE IF MINUS +=0 [AR]_0, ;EXTEND + SIGN + J/DIV1 ;NOW SAME AS DIV + [AR]_-1, ;EXTEND - SIGN + J/DIV1 ;SAME AS DIV + +1601: +DIV: [BR]_[AR] ;COPY MEM OPERAND + [AR]_AC ;GET AC + Q_AC[1] ;AND AC+1 + READ [AR], ;TEST FOR NO DIVIDE + SKIP AD.EQ.0 +=000 .NOT.[AR], ;SEE IF ALL SIGN BITS IN AR + SKIP AD.EQ.0, ; .. + J/DIVA ;CONTINUE BELOW +=001 +DIV1: READ [BR], ;SEE IF DIVIDE BY + SKIP AD.EQ.0 ; ZERO +=100 +DIV2: SC_34., ;NOT ZERO--LOAD STEP COUNT + CALL [DIVSUB] ;DIVIDE +=101 NO DIVIDE ;DIVIDE BY ZERO +=110 [ARX]_[AR], ;COPY REMAINDER + J/IMUL1 ;STORE ANSWER += + + +=0 +DIVA: [BRX]_[AR], ;HIGH WORD IS NOT SIGNS + J/DIVB ;GO TEST FOR NO DIVIDE + READ [BR], ;ALL SIGN BITS + SKIP AD.EQ.0, ;SEE IF ZERO DIVIDE + J/DIV2 ;BACK TO MAIN FLOW + +DIVB: [ARX]_Q ;MAKE ABS VALUES + READ [AR], ;SEE IF + + SKIP DP0 +=00 READ [BR], ;SEE IF + + SKIP DP0, + J/DIVC ;CONTINUE BELOW + CLEAR [ARX]0, ;FLUSH DUPLICATE SIGN + CALL [DBLNG1] ;NEGATE AR!ARX +=11 READ [BR], ;SEE IF TOO BIG + SKIP DP0, + J/DIVC += +=0 +DIVC: [AR]-[BR], ;COMPUTE DIFFERENCE + SKIP DP0, ;SEE IF IT GOES + 3T, ;ALLOW TIME + J/NODIV ;TEST + [AR]+[BR], + SKIP DP0, ;SAME TEST FOR -VE BR + 3T, + J/NODIV +=0 +NODIV: NO DIVIDE ;TOO BIG + [AR]_[BRX], ;FITS + J/DIV1 ;GO BACK AND DIVIDE + + .TOC "ARITHMETIC -- DDIV" + + .DCODE +117: DBL R, DAC, J/DDIV + .UCODE + +.IF/FULL +1627: +DDIV: Q_[ARX].AND.[MAG] ;COPY LOW WORD + [BR]_[AR]*.5, ;COPY MEMORY OPERAND + SKIP AD.LE.0 ;SEE IF POSITIVE +=0 [BR]_[BR]*.5 LONG, ;POSITIVE + J/DDIV1 ;CONTINUE BELOW + [BR]_[BR]*.5 LONG, ;NEGATIVE OR ZERO + SKIP DP0 ;SEE WHICH? +=0 [MAG].AND.Q, ;SEE IF ALL ZERO + SKIP AD.EQ.0, J/DDIV1 ;CONTINUE BELOW + [T1]_0 XWD [5] ;NEGATE MEM OP + Q_Q.OR.#, #/600000, ;SIGN EXTEND THE LOW + HOLD RIGHT ; WORD + Q_-Q ;MAKE Q POSITIVE + [BR]_(-[BR]-.25)*.5 LONG, ;NEGATE HIGH WORD + ASHC, MULTI PREC/1, ;USE CARRY FROM LOW WORD + J/DDIV3 ;CONTINUE BELOW +=0 +DDIV1: [BR]_[BR]*.5 LONG, ;SHIFT OVER 1 PLACE + ASHC, J/DDIV2 ;CONTINUE BELOW + NO DIVIDE ;DIVIDE BY ZERO +DDIV2: [T1]_0 XWD [4] ;MEM OPERAND IS POSITIVE +DDIV3: [BRX]_Q, AC ;COPY Q + + [AR]_AC*.5, 2T, SKIP DP0 ;GET AC--SEE IF NEGATIVE +=0*1*0 +DDIV3A: Q_AC[1].AND.[MAG], ;POSITIVE (OR ZERO) + J/DDIV4 ;CONTINUE BELOW + [T1]_[T1].XOR.#, ;NEGATIVE + #/7, CALL [QDNEG] ;UPDATE SAVED FLAGS +=1*1*1 [AR]_[AR]*.5, ;SHIFT AR OVER + J/DDIV3A ;GO BACK AND LOAD Q += +=0 +DDIV4: [AR]_[AR]*.5 LONG, ;SHIFT AR OVER + CALL [DDIVS] ;SHIFT 1 MORE PLACE + [AR]-[BR], 3T, SKIP DP0 ;TEST MAGNITUDE +=0 [AR]-[BR], 2T, + SKIP AD.EQ.0, J/DDIV5 + [ARX]_Q, J/DDIV5A ;ANSWER FITS + +=0 +DDIV5: READ [T1], 3T, DISP/DP, J/NODDIV + Q-[BRX], 3T, SKIP DP0 +=0 READ [T1], 3T, DISP/DP, J/NODDIV + [ARX]_Q ;COPY LOW WORD + +;HERE WITH EVERYTHING SETUP AND READY TO GO +DDIV5A: Q_AC[2].AND.[MAG] +=0* Q_Q*.5, SC_34., CALL [DBLDIV] + [T0]_Q*2 LONG + Q_Q+[T0] + AC[0]_Q.AND.[MAG] ;STORE ANSWER +=0 Q_[ARX], CALL [DDIVS] ;SHIFT OUT EXTRA ZERO BIT + [ARX]_Q ; .. + Q_AC[3].AND.[MAG] +=0* [T0]_[AR]*.5 LONG, ;SHIFT Q, PUT AR ON DP + SC_34., ;LOAD SHIFT COUNT + SKIP DP0, ;LOOK AT AR SIGN + CALL [DBLDIV] ;GO DIVIDE + [T0]_Q*2 LONG + READ [T1], 3T, DISP/DP ;WHAT SIGN IS QUO +=1110 [T0]_[T0]+Q, ;POSITIVE QUO + J/DDIV5B ;CONTINUE BELOW + [T0]_-Q*2 ;NEGATIVE QUO + AD/-D-.25, DBUS/RAM, 3T, + RAMADR/AC#, DEST/Q_AD, + MULTI PREC/1 + AC_Q, SKIP AD.EQ.0 +=0 AC[1]_[T0], J/DDIV5C + AC[1]_0, J/DDIV6 + +DDIV5B: AC[1]_[T0].AND.[MAG], J/DDIV6 ;STORE LOW WORD IN + CASE + +DDIV5C: [T0]_[T0].OR.#, #/400000, HOLD RIGHT + AC[1]_[T0] + +DDIV6: READ [AR], SKIP DP0 ;LOOK AT AR SIGN +=0 +DDIV7: Q_[ARX], J/DDIV8 + Q_[ARX]+[BRX] + [AR]_[AR]+[BR], + MULTI PREC/1 + Q_Q+[BRX] + [AR]_[AR]+[BR], + MULTI PREC/1 +DDIV8: READ [T1], 3T, DISP/DP +=1101 +DDIV8A: [AR]_[AR]*2 LONG, ASHC, ;POSITIVE REMAINDER + J/DDIV9 ;CONTINUE BELOW + Q_-Q ;NEGATE REMAINDER IN AR!Q + [AR]_(-[AR]-.25)*2 LONG, + MULTI PREC/1, ASHC + +DDIV9: AC[2]_[AR]+[AR], 3T, + SKIP DP0 +=0 AC[3]_Q.AND.[MAG], + NEXT INST + Q_Q.AND.[MAG], AC[3] + AC[3]_[MAG].EQV.Q, + NEXT INST + + +;HERE IF WE WANT TO SET NO DIVIDE +=11011 +NODDIV: CALL [QDNEG] ;FIXUP AC TO AC+3 + NO DIVIDE ;ABORT DIVIDE + +DDIVS: [AR]_[AR]*.5 LONG, ASHC, RETURN [1] +.IFNOT/FULL +1627: +DDIV: UUO +.ENDIF/FULL + + .TOC "ARITHMETIC -- DIVIDE SUBROUTINE" + +;HERE IS THE SUBROUTINE TO DO DIVIDE +;ENTER WITH: +; AR!Q = D'END +; BR = D'SOR +;RETURN 2 WITH: +; AR = REMAINDER +; Q = QUOTIENT +;CALLER MUST CHECK FOR ZERO DIVIDE PRIOR TO CALL +; +=1000 +DIVSUB: Q_Q.AND.#, ;CLEAR SIGN BIT IN + #/377777, ;MASK + HOLD RIGHT, ;JUST CLEAR BIT 0 + CALL [DIVSGN] ;DO REAL DIVIDE +=1100 RETURN [2] ;ALL POSITIVE +=1101 Q_-Q, RETURN [2] ;-QUO +REM +=1110 Q_-Q ;ALL NEGATIVE +=1111 [AR]_-[AR], RETURN [2] ;NEGATIVE REMAINDER + +;HERE IS THE INNER DIVIDE SUBROUTINE +;SAME SETUP AS DIVSUB +;RETURNS WITH AR AND Q POSITIVE AND +; 14 IF ALL POSITIVE +; 15 IF -QUO +; 16 IF ALL NEGATIVE +; 17 IF NEGATIVE REMAINDER + +BASIC DIV STEP "DEST/Q_Q*2, DIV, A/BR, B/AR, STEP SC" +DIV STEP "BASIC DIV STEP, AD/A+B, DIVIDE/1" +FIRST DIV STEP "BASIC DIV STEP, AD/B-A-.25, ADD .25" + +DIVSGN: READ [AR], SKIP DP0 +=0 [ARX]_0, J/DVSUB2 ;REMAINDER IS POSITIVE + Q_-Q, SKIP AD.EQ.0 ;COMPLEMENT LOW WORD +=0 [AR]_.NOT.[AR], J/DVSUB1 ;COMPLEMENT HI WORD + [AR]_-[AR] ;TWO'S COMPLEMENT HI WORD SINCE + ; LOW WORD WAS ZERO +DVSUB1: [ARX]_#, #/100000 ;REMAINDER IS NEGATIVE +DVSUB2: READ [BR], SKIP DP0 ;IS THE DIVISOR NEGATIVE +=0 +DVSUB3: [AR]_[AR]*.5 LONG, ;START TO PUT IN 9-CHIPS + J/DIVSET ;JOIN MAIN STREAM + [BR]_-[BR] ;COMPLEMENT DIVISOR + [ARX]_[ARX].OR.#, ;ADJUST SIGN OF QUOTIENT + #/40000, J/DVSUB3 ;USE 9 CHIPS +DIVSET: [AR]_[AR]*.5 + [BR]_[BR]*.5 + [BR]_[BR]*.5 + FIRST DIV STEP +;HERE IS THE MAIN DIVIDE LOOP +=0 +DIVIDE: DIV STEP, J/DIVIDE + [T1]_[T1]*2 LONG, DIVIDE/1, DIV + [AR]_[AR]*.5, SKIP DP0 +=0 +FIX++: [AR]_[AR]*2 LONG, J/FIX1++ + [AR]_[AR]+[BR], J/FIX++ +FIX1++: [AR]_[AR]*2 LONG + Q_[MASK].AND.Q + READ [ARX], 3T, ;RETURN TO 1 OF 4 PLACES + DISP/1, ;BASED ON SIGN OF RESULT + J/14 ;RETURN + + .TOC "ARITHMETIC -- DOUBLE DIVIDE SUBROUTINE" +.IF/FULL +;CALL WITH: +; AR!ARX!Q = 3 WORD DV'END +; BR!BRX = 2 WORD DV'SOR +;RETURN 2 WITH: +; AR!ARX = 2 WORD REMAINDER +; CORRECT IF POSITIVE (Q IS ODD) +; WRONG (BY BR!BRX) IF NEGATIVE (Q IS EVEN) +; Q = 1 WORD QUOTIENT +;CALLER MUST CHECK FOR ZERO DIVIDE PRIOR TO CALL +; +;NOTE: THIS SUBROUTINE ONLY WORKS FOR POSITIVE NUMBERS +; +=0 +;HERE FOR NORMAL STARTUP +DBLDIV: [ARX]_([ARX]-[BRX])*2 LONG, ;SUBTRACT LOW WORD + LSHC, J/DIVHI ;GO ENTER LOOP +;SKIP ENTRY POINT IF FINAL STEP IN PREVIOUS ENTRY WAS IN ERROR + [ARX]_([ARX]+[BRX])*2 LONG, ;CORRECTION STEP + LSHC, J/DIVHI ;GO ENTER LOOP + +;HERE IS DOUBLE DIVIDE LOOP +DIVHI: AD/A+B, ;ADD (HARDWARE MAY OVERRIDE) + A/BR, B/AR, ;OPERANDS ARE AR AND BR + DEST/AD*2, ;SHIFT LEFT + SHSTYLE/NORM, ;SET SHIFT PATHS (SEE DPE1) + MULTI PREC/1, ;INJECT SAVED BITS + STEP SC ;COUNT DOWN LOOP +=0 AD/A+B, ;ADD (HARDWARE MAY OVERRIDE) + A/BRX, B/ARX, ;LOW WORDS + DEST/Q_Q*2, ;SHIFT WHOLE MESS LEFT + SHSTYLE/DIV, ;SET SHIFT PATHS (SEE DPE1) + DIVIDE/1, ;SAVE BITS + J/DIVHI ;KEEP LOOPING +;HERE WHEN ALL DONE + DEST/Q_Q*2, DIV, ;SHIFT IN LAST Q BIT + DIVIDE/1, ;GENERATE BIT + B/HR, RETURN [2] ;ZERO HR AND RETURN + + .TOC "ARITHMETIC -- SUBROUTINES FOR ARITHMETIC" + +;QUAD WORD NEGATE +;ARGUMENT IN AC!AC1!AC2!AC3 +;LEAVES COPY OF AC!AC1 IN AR!Q +;RETURNS TO CALL!24 +QDNEG: Q_-AC[3] + AC[3]_Q.AND.[MAG], ;PUT BACK LOW WORD + SKIP AD.EQ.0 ;SEE IF ANY CARRY +=0 +COM2A: Q_.NOT.AC[2], J/COM2 ;CARRY--DO 1'S COMPLEMENT + Q_-AC[2] ;NEXT WORD + AC[2]_Q.AND.[MAG], ;PUT BACK WORD + SKIP AD.EQ.0 +=0 +COM1A: Q_.NOT.AC[1], J/COM1 + Q_-AC[1] + AC[1]_Q.AND.[MAG], + SKIP AD.EQ.0 +=0 +COM0A: [AR]_.NOT.AC, J/COM0 + [AR]_-AC, 3T, J/COM0 + +COM2: AC[2]_Q.AND.[MAG], J/COM1A +COM1: AC[1]_Q.AND.[MAG], J/COM0A +COM0: AC_[AR], RETURN [24] +.ENDIF/FULL + +;DOUBLE WORD NEGATE +;ARGUMENT IN AR AND ARX +;RETURNS TO CALL!2 + +DBLNEG: CLEAR ARX0 ;FLUSH DUPLICATE SIGN +DBLNGA: [ARX]_-[ARX], ;FLIP LOW WORD + SKIP AD.EQ.0 ;SEE IF CARRY +=0 [AR]_.NOT.[AR], ;NO CARRY-- 1 COMP + AD FLAGS, J/CLARX0 ;CLEAR LOW SIGN + [AR]_-[AR], ;CARRY + AD FLAGS, 3T, J/CLARX0 + +;SAME THING BUT DOES NOT SET PC FLAGS +DBLNG1: [ARX]_-[ARX], SKIP AD.EQ.0 +=0 [AR]_.NOT.[AR], J/CLARX0 + [AR]_-[AR], J/CLARX0 + + .NOBIN +.TOC "BYTE GROUP -- IBP, ILDB, LDB, IDPB, DPB" + + +;ALL FIVE INSTRUCTIONS OF THIS GROUP ARE CALLED WITH THE BYTE POINTER +;IN THE AR. ALL INSTRUCTIONS SHARE COMMON SUBROUTINES. + +;IBP OR ADJBP +;IBP IF AC#0, ADJBP OTHERWISE +; HERE WITH THE BASE POINTER IN AR + +;HERE IS A MACRO TO DO IBP. WHAT HAPPENS IS: +; THE AR IS PUT ON THE DP. +; THE BR IS LOADED FROM THE DP WITH BITS 0-5 FROM SCAD +; THE SCAD COMPUTES P-S +; IBPS IS CALLED WITH A 4-WAY DISPATCH ON SCAD0 AND FIRST-PART-DONE +;THE MACRO IS WRITTEN WITH SEVERAL SUB-MACROS BECAUSE OF RESTRICTIONS +; IN THE MICRO ASSEMBLER + +IBP DP "AD/D, DEST/A, A/AR, B/BR, DBUS/DBM, DBM/DP, BYTE/BYTE1" +IBP SCAD "SCAD/A-B, SCADA/BYTE1, SCADB/SIZE" +IBP SPEC "SCAD DISP, SKIP FPD" +CALL IBP "IBP DP, IBP SCAD, IBP SPEC, CALL [IBPS], DT/3T" + +SET P TO 36-S "AD/D,DEST/A,A/BR,B/AR,DBUS/DBM,DBM/DP,SCAD/A-B,SCADB/SIZE,BYTE/BYTE1,SCADA/PTR44" + +;THE FOLLOWING MACRO IS USED FOR COUNTING SHIFTS IN THE BYTE ROUTINES. IT +; USES THE FE AND COUNTS BY 8. NOTE: BYTE STEP IS A 2S WEIGHT SKIP NOT 1S. +BYTE STEP "SCAD/A+B,SCADA/S#,S#/1770,SCADB/FE,LOAD FE, 3T,SCAD DISP" + + .BIN + + .DCODE +133: R, AC, J/IBP ;OR ADJBP +134: R,W TEST, J/ILDB ;CAN'T USE RPW BECAUSE OF FPD + R, J/LDB + R,W TEST, J/IDPB + R, J/DPB + .UCODE +1610: +IBP: SKIP IF AC0 ;SEE IF ADJBP +=000 WORK[ADJPTR]_[AR], ;SAVE POINTER + J/ADJBP ;GO ADJUST BYTE POINTER +=001 CALL IBP ;BUMP BYTE POINTER +=101 DONE ;POINTER STORED += + +1620: +ILDB: CALL IBP ;BUMP BYTE POINTER +1624: +LDB: READ [AR], ;LOOK AT POINTER + LOAD BYTE EA, FE_P, 3T, ;GET STUFF OUT OF POINTER + CALL [BYTEA] ;COMPUTE EFFECTIVE ADDRESS +1625: VMA_[PC], FETCH ;START FETCH OF NEXT INST +=0* READ [AR], ;LOOK AT POINTER + FE_FE.AND.S#, S#/0770, ;MASK OUT JUNK IN FE + BYTE DISP, ;DISPATCH ON BYTE SIZE + CALL [LDB1] ;GET BYTE + AC_[AR], CLR FPD, ;STORE AC + J/NIDISP ;GO DO NEXT INST + +1630: +IDPB: CALL IBP ;BUMP BYTE POINTER +1634: +DPB: [ARX]_AC*2 ;PUT 7 BIT BYTE IN 28-34 + AD/A, A/ARX, SCAD/A, ;PUT THE BYTE INTO + SCADA/BYTE5, 3T, ; INTO THE FE REGISTER + LOAD FE ; FE REGISTER + [ARX]_AC ;PUT BYTE IN ARX +=100 READ [AR], ;LOOK AT BYTE POINTER + LOAD BYTE EA, ;LOAD UP EFFECTIVE ADDRESS + CALL [BYTEA] ;COMPUTE EFFECTIVE ADDRESS + READ [AR], ;LOOK AT POINTER AGAIN + BYTE DISP, ;DISPATCH ON SIZE + CALL [DPB1] ;GO STORE BYTE +=111 CLR FPD, J/DONE ;ALL DONE += + + .TOC "BYTE GROUP -- INCREMENT BYTE POINTER SUBROUTINE" + +=00 +IBPS: [AR]_[BR], START WRITE, J/IBPX ;NO OVERFLOW, BR HAS ANSWER + RETURN [4] ;FIRST PART DONE SET + SET P TO 36-S, J/NXTWRD ;WORD OVERFLOW + RETURN [4] ;FPD WAS SET IGNORE OVERFLOW + ; AND RETURN + +NXTWRD: [AR]_[AR]+1, HOLD LEFT, START WRITE ;BUMP Y AND RETURN +IBPX: MEM WRITE, MEM_[AR], RETURN [4] + + + .TOC "BYTE GROUP -- BYTE EFFECTIVE ADDRESS EVALUATOR" + +;ENTER WITH POINTER IN AR +;RETURN1 WITH (EA) IN VMA AND WORD IN BR +BYTEAS: EA MODE DISP, ;HERE TO AVOID FPD + J/BYTEA0 ;GO COMPUTE EA +BYTEA: SET FPD, ;SET FIRST-PART-DONE + EA MODE DISP ;DISPATCH +=100* +BYTEA0: VMA_[AR]+XR, ;INDEXING + START READ, ;FETCH DATA WORD + PXCT BYTE DATA, ;FOR PXCT + J/BYTFET ;GO WAIT + VMA_[AR], ;PLAIN + START READ, ;START CYCLE + PXCT BYTE DATA, ;FOR PXCT + J/BYTFET ;GO WAIT + VMA_[AR]+XR, ;BOTH + START READ, ;START CYCLE + PXCT BYTE PTR EA, ;FOR PXCT + J/BYTIND ;GO DO INDIRECT + VMA_[AR], ;JUST @ + START READ, ;START READ + PXCT BYTE PTR EA ;FOR PXCT +BYTIND: MEM READ, ;WAIT FOR @ WORD + [AR]_MEM, ;PUT IN AR + HOLD LEFT, ;JUST IN RH (SAVE P & S) + LOAD BYTE EA, ;LOOP BACK + J/BYTEAS ; .. + +BYTFET: MEM READ, ;WAIT FOR BYTE DATA + [BR]_MEM.AND.MASK, ; WORD. UNSIGNED + RETURN [1] ;RETURN TO CALLER + + .TOC "BYTE GROUP -- LOAD BYTE SUBROUTINE" + +;CALL WITH: +; WORD IN BR +; POINTER IN AR +; P IN FE +; BYTE DISPATCH +;RETURN2 WITH BYTE IN AR +LDB SCAD "SCAD/A,BYTE/BYTE5" +7-BIT LDB "AD/D,DBUS/DBM,DBM/DP,DEST/A,A/BR,B/BR, LDB SCAD" + +=000 +LDB1: GEN 17-FE, 3T, ;GO SEE IF ALL THE BITS + SCAD DISP, ; ARE IN THE LEFT HALF + J/LDBSWP ;GO TO LDBSWP & SKIP IF LH + +;HERE ARE THE 7-BIT BYTES +=001 7-BIT LDB, SCADA/BYTE1, J/LDB7 +=010 7-BIT LDB, SCADA/BYTE2, J/LDB7 +=100 7-BIT LDB, SCADA/BYTE3, J/LDB7 +=101 7-BIT LDB, SCADA/BYTE4, J/LDB7 +=111 7-BIT LDB, SCADA/BYTE5, J/LDB7 += + +;FOR 7-BIT BYTES WE HAVE BYTE IN BR 28-35 AND JUNK IN REST OF BR. +; WE JUST MASK THE SELECTED BYTE AND SHIFT ONE PLACE RIGHT. +LDB7: AD/ZERO,RSRC/DA, ;LH_ZERO, RH_D.AND.A + DBUS/DBM,DBM/#,#/376, ;D INPUT IS 376 + A/BR, ;A IS BR + B/AR, ;PUT RESULT IN AR + DEST/AD*.5, 3T, ;SHIFT RESULT 1 PLACE + RETURN [2] ;RETURN TO CALLER + +;HERE FOR NORMAL BYTES +=00 +LDBSWP: FE_-FE, ;MAKE P NEGATIVE + J/LDBSH ;JOIN MAIN LDB LOOP +=10 [BR]_[BR] SWAP ;SHIFT 18 STEPS += + [BR]_0, HOLD RIGHT, ;PUT ZERO IN LH + FE_-FE+S#, S#/220 ;UPDATE FE +LDBSH: [BR]_[BR]*.5, ;SHIFT RIGHT + FE_FE+10, ;UPDATE THE FE + MULTI SHIFT/1 ;FAST SHIFT + READ [AR], FE_-S-10 ;GET SIZE + Q_0 ;CLEAR Q + GEN MSK [AR], ;PUT MASK IN Q (WIPEOUT AR) + FE_FE+10, ;COUNT UP ALL STEPS + MULTI SHIFT/1 ;FAST SHIFT + GEN MSK [AR] ;ONE MORE BIT + [AR]_[BR].AND.Q, RETURN [2] + + .NOBIN +.TOC "BYTE GROUP -- DEPOSIT BYTE IN MEMORY" + +;FLOW FOR DPB (NOT 7-BIT BYTE) +; +;FIRST SET ARX TO -1 AND Q TO ZERO AND ROTATE LEFT +; S PLACES GIVING: + +; ARX Q +; +------------------!------------------+ +; !111111111111000000!000000000000111111! +; +------------------!------------------+ +; !<--->! +; S BITS +; + +;NOW THE AC IS LOAD INTO THE ARX AND BOTH THE ARX AND Q +; ARE SHIFTED LEFT P BITS GIVING: + +; +------------------!------------------+ +; !??????BBBBBB000000!000000111111000000! +; +------------------!------------------+ +; <----><----> <----><----> +; JUNK BYTE MASK P BITS +; + +;AT THIS POINT WE ARE ALMOST DONE. WE NEED TO AND +; THE BR WITH .NOT. Q TO ZERO THE BITS FOR THE BYTE +; AND AND ARX WITH Q TO MASK OUT THE JUNK THIS GIVES: +; +; ARX +; +------------------+ +; !000000BBBBBB000000! +; +------------------! +; +; AR +; +------------------+ +; !DDDDDD000000DDDDDD! +; +------------------+ +; +;WE NOW OR THE AR WITH ARX TO GENERATE THE ANSWER. + + .BIN + +;DEPOSIT BYTE SUBROUTINE +;CALL WITH: +; BYTE POINTER IN AR +; BYTE TO STORE IN ARX +; WORD TO MERGE WITH IN BR +; (E) OF BYTE POINTER IN VMA +; 7-BIT BYTE IN FE +; BYTE DISPATCH +;RETURN2 WITH BYTE IN MEMORY +; +DPB SCAD "SCAD/A+B,SCADA/S#,SCADB/FE,S#/0" +7-BIT DPB "AD/D,DEST/A,A/BR,DBUS/DBM,DBM/DP,B/AR, DPB SCAD" + +=000 +DPB1: READ [AR], FE_-S-10, J/DPBSLO ;NOT SPECIAL +=001 7-BIT DPB, BYTE/BYTE1, J/DPB7 +=010 7-BIT DPB, BYTE/BYTE2, J/DPB7 +=100 7-BIT DPB, BYTE/BYTE3, J/DPB7 +=101 7-BIT DPB, BYTE/BYTE4, J/DPB7 +=111 7-BIT DPB, BYTE/BYTE5, J/DPB7 += +DPB7: [MAG]_[MASK]*.5, START WRITE + MEM WRITE, MEM_[AR], RETURN [2] + + +DPBSLO: Q_0 ;CLEAR Q + GEN MSK [MAG], ;GENERATE MASK IN Q (ZAP MAG) + FE_FE+10, ;COUNT STEPS + MULTI SHIFT/1 ;FAST SHIFT + GEN MSK [MAG] ;ONE MORE BITS + READ [AR], 3T, FE_P ;AMOUNT TO SHIFT + FE_FE.AND.S#, S#/0770 ;MASK OUT JUNK + Q_Q.AND.[MASK], ;CLEAR BITS 36 AND 37 + FE_-FE ;MINUS NUMBER OF STEPS + [ARX]_[ARX]*2 LONG, ;SHIFT BYTE AND MASK + FE_FE+10, ;COUNT OUT STEPS + MULTI SHIFT/1 ;FAST SHIFT +;AT THIS POINT WE HAVE DONE ALL THE SHIFTING WE NEED. THE BYTE IS +; IN ARX AND THE MASK IS IN Q. + [AR]_.NOT.Q + [AR]_[AR].AND.[BR] + [ARX]_[ARX].AND.Q + [AR]_[AR].OR.[ARX], + J/DPB7 + + .TOC "BYTE GROUP -- ADJUST BYTE POINTER" +.IF/FULL +;FIRST THE NUMBER OF BYTES PER WORD IS COMPUTED FROM THE +; FOLLOWING FORMULA: +; +; ( P ) ( 36-P ) +; BYTES PER WORD = INT( --- ) + INT( ---- ) +; ( S ) ( S ) +; +;THIS GIVES 2 BYTES PER WORD FOR THE FOLLOWING 12 BIT BYTE: +; !=====================================! +; ! 6 !////////////! 12 ! 6 ! +; !=====================================! +; P=18 AND S=12 +; +;WE GET 3 BYTES/WORD IF THE BYTES FALL IN THE NATURAL PLACE: +; !=====================================! +; ! 12 !\\\\\\\\\\\\! 12 ! +; !=====================================! +; P=12 AND S=12 + +;WE COME HERE WITH THE BYTE POINTER IN AR, AND ADJPTR +ADJBP: [ARX]_[AR] SWAP, ;MOVE SIZE OVER + SC_9. ;READY TO SHIFT +=0 +ADJBP0: [ARX]_[ARX]*.5, ;SHIFT P OVER + STEP SC, ; .. + J/ADJBP0 ; .. + [ARX]_([ARX].AND.#)*.5, ;SHIFT AND MASK + 3T, ;WAIT + #/176 ;6 BIT MASK + [ARX]_#, ;CLEAR LH + #/0, ; .. + HOLD RIGHT ; .. + WORK[ADJP]_[ARX] ;SAVE P + [BR]_([AR].AND.#)*.5, ;START ON S + 3T, ;EXTRACT S + #/007700 ; .. + [BR]_[BR] SWAP, ;SHIFT 18 PLACES + SC_3 ; .. + [BR]_0, ;CLEAR LH + HOLD RIGHT ; .. + +=0 +ADJBP1: [BR]_[BR]*.5, ;SHIFT S OVER + STEP SC, ; .. + J/ADJBP1 ; .. + WORK[ADJS]_[BR], ;SALT S AWAY + SKIP AD.EQ.0 ;SEE IF ZERO +=0 Q_[ARX], ;DIVIDE P BY S + SC_34., ;STEP COUNT + J/ADJBP2 ;SKIP NEXT WORD + [AR]_WORK[ADJPTR], J/MOVE ;S=0 -- SAME AS MOVE +=0* +ADJBP2: [AR]_#, ;FILL AR WITH SIGN BITS + #/0, ;POSITIVE + CALL [DIVSUB] ;GO DIVIDE + WORK[ADJQ1]_Q ;SAVE QUOTIENT + Q_#, ;COMPUTE (36-P)/S + #/36., ; .. + HOLD LEFT ;SMALL ANSWER + Q_Q-WORK[ADJP] ;SUBTRACT P + [BR]_WORK[ADJS] ;DIVIDE BY S + SC_34. ;STEP COUNT +=0* [AR]_#, ;MORE SIGN BITS + #/0, ; .. + CALL [DIVSUB] ;GO DIVIDE + WORK[ADJR2]_[AR] ;SAVE REMAINDER + [AR]_#, ;ASSUME NEGATIVE ADJ + #/777777 ;EXTEND SIGN + AD/D+Q, ;BR_(P/S)+((36-P)/S) + DEST/AD, ; .. + B/BR, ; .. + RAMADR/#, ; .. + DBUS/RAM, ; .. + WORK/ADJQ1, ; .. + 4T, ; .. + SKIP AD.EQ.0 ;SEE IF ZERO +=0 Q_Q+AC, ;GET ADJUSTMENT + SC_34., ;STEP COUNT + SKIP DP0, ;GO DO DIVIDE + 4T, ;WAIT FOR DP + J/ADJBP3 ;BELOW + NO DIVIDE ;0 BYTES/WORD + +;WE NOW DIVIDE THE ADJUSTMENT BY THE BYTES PER WORD AND FORCE THE +; REMAINDER (R) TO BE A POSITIVE NUMBER (MUST NOT BE ZERO). THE +; QUOTIENT IS ADDED TO THE Y FIELD IN THE BYTE POINTER AND THE NEW +; P FIELD IS COMPUTED BY: +; +; ( ( 36-P )) +; NEW P = 36-((R * S) + RMDR( ---- )) +; ( ( S )) +; +;WE NOW HAVE BYTES/WORD IN BR AND ADJUSTMENT IN Q. DIVIDE TO GET +; WORDS TO ADJUST BY. +=00 +ADJBP3: [AR]_#, ;POSITIVE ADJUSTMENT + #/0. + WORK[ADJBPW]_[BR], ;SAVE BYTES/WORD & COMPUTE + CALL [DIVSUB] ; ADJ/(BYTES/WORD) +;WE NOW WANT TO ADJUST THE REMAINDER SO THAT IT IS POSITIVE +=11 Q_#, ;ONLY RIGHT HALF + #/0, ; .. + HOLD RIGHT ; .. += + READ [AR], ;ALREADY + + SKIP AD.LE.0 ; .. +=0 +ADJBP4: AD/D+Q, ;ADD Q TO POINTER AND STORE + DEST/AD, ; .. + B/BR, ;RESULT TO BR + RAMADR/#, ;PTR IS IN RAM + DBUS/RAM, ; .. + WORK/ADJPTR, ; .. + INH CRY18, ;JUST RH + 3T, ;WAIT FOR RAM + J/ADJBP5 ;CONTINUE BELOW + Q_Q-1, ;NO--MAKE Q SMALLER + HOLD LEFT ; .. + [AR]_[AR]+WORK[ADJBPW], ;MAKE REM BIGGER + J/ADJBP4 ;NOW HAVE + REMAINDER + +ADJBP5: [BRX]_[AR], ;COMPUTE R*S + SC_35. ;STEP COUNT + Q_WORK[ADJS] ;GET S +=01* [BRX]_[BRX]*.5 LONG, ;SHIFT OVER + CALL [MULSUB] ; .. + AD/D+Q, ;AR_(R*S)+RMDR(36-P)/S + DEST/AD, ; .. + B/AR, ; .. + RAMADR/#, ; .. + 3T, ; .. + DBUS/RAM, ; .. + WORK/ADJR2 ; .. + [AR]_(#-[AR])*2, ;COMPUTE 36-AR + 3T, ;AND START LEFT + #/36. ; .. + [AR]_[AR] SWAP, ;PUT THE POSITION BACK + SC_9. ; .. + [AR]_#, ;CLEAR JUNK FROM RH + #/0, ; .. + HOLD LEFT ; .. +=0 +ADJBP6: [AR]_[AR]*2, ;LOOP OVER ALL BITS + STEP SC, ; .. + J/ADJBP6 ; .. + [BR]_[BR].AND.#, ; .. + #/007777, ; .. + HOLD RIGHT ; .. + AC_[AR].OR.[BR], ;ALL DONE + J/DONE +.IFNOT/FULL + +ADJBP: UUO ;NO ADJBP IN SMALL + ; MICROCODE +.ENDIF/FULL + + .NOBIN +.TOC "BLT" + +;THIS CODE PROVIDES A GUARANTEED RESULT IN AC ON COMPLETION OF +; THE TRANSFER (EXCEPT IN THE CASE AC IS PART OF BUT NOT THE LAST WORD +; OF THE DESTINATION BLOCK). WHEN AC IS NOT PART OF THE DESTINATION +; BLOCK, IT IS LEFT CONTAINING THE ADDRESSES OF THE FIRST WORD FOLLOWING +; THE SOURCE BLOCK (IN THE LH), AND THE FIRST WORD FOLLOWING THE DEST- +; INATION BLOCK (IN THE RH). IF AC IS THE LAST WORD OF THE DESTINATION +; BLOCK, IT WILL BE A COPY OF THE LAST WORD OF THE SOURCE BLOCK. + +;IN ADDITION, A SPECIAL-CASE CHECK IS MADE FOR THE CASE IN WHICH EACH +; WORD STORED IS USED AS THE SOURCE OF THE NEXT TRANSFER. IN THIS CASE, +; ONLY ONE READ NEED BE PERFORMED, AND THAT DATA MAY BE STORED FOR EACH +; TRANSFER. THUS THE COMMON USE OF BLT TO CLEAR CORE IS SPEEDED UP. + .BIN + +;HERE TO SETUP FOR A BLT/UBABLT, AC IN BRX, E.A. IN AR +;RETURN 2 WITH +; AR FINAL ADDR +; ARX SRC ADDR +; BR FINAL CONTENTS OF AC +; BRX DST ADDR +; READ OF FIRST SRC WORD IN PROGRESS, STATE=BLT +SETBLT: [ARX]_[BRX] SWAP ;COPY AC TO ARX (DST,,SRC) +=0 VMA_[ARX], ;ADDRESS OF FIRST WORD + START READ, + PXCT BLT SRC, + CALL [CLARXL] ;CLEAR THE LEFT HALF OF + [BRX]_0, ; BOTH SRC AND DEST + HOLD RIGHT + Q_[AR]-[BRX] ;NUMBER OF WORDS TO MOVE + [BR]_Q+1 ;LENGTH +1 + [BR]_[BR] SWAP, ;COPY TO BOTH HALFS + HOLD RIGHT + [BR]_AC+[BR], ;FINAL AC + INH CRY18 ;KEEP AC CORRECT IF DEST IS 777777 + STATE_[BLT],RETURN [2] ;SET PAGE FAIL FLAGS + + .DCODE +251: I, J/BLT + .UCODE + +1640: +BLT: [BRX]_AC,CALL [SETBLT] ;FETCH THE AC, SETUP BR, BRX, ARX, STATE +1642: AC_[BR], ;STORE BACK IN AC + CALL [LOADQ] ;LOAD FIRST WORD INTO Q +1643: [BR]_[ARX]+1000001, ;SRC+1 + 3T, + HOLD LEFT + [BR]-[BRX], 3T, ; Check for core clearing case + SKIP ADR.EQ.0, + J/BLTLP1 + +=0 ; This instruction is part of the loop for the normal case +BLTLP1: VMA_[BRX], ;NOT CLEARING CORE, GET DEST ADR + START WRITE, ;START TO STORE NEXT WORD + PXCT BLT DEST, ;WHERE TO STORE + J/BLTGO + + [BR]_VMA ; This is the clear core case. + ; Fetch back source VMA with flags. + VMA_[BRX], ; Start first write + START WRITE, + PXCT BLT DEST + [BR].XOR.VMA, ; Compare destination VMA flags with source + SKIP DP0, 3T, ; flags to see if user mode bits match. + J/BLTCLR ; Skips if they mismatch into normal case. + +=0 +BLTCLR: MEM WRITE, ; This instruction is part of the loop for + MEM_Q, ; The clear core case. + SKIP/-1 MS, ; 1 MS timer up? + J/BLTCL1 +BLTGO: MEM WRITE, ;STORE + MEM_Q +BLTGOT: [BRX]-[AR], ;BELOW E? + SKIP DP0, 3T +=0 END BLT, + J/DONE + [BRX]_[BRX]+1 ; Update destination address + VMA_[ARX]+1, ; and source address at the same time! + LOAD VMA, + PXCT BLT SRC, + START READ + MEM READ, + Q_MEM, + J/BLTLP1 + +=0 +BLTCL1: J/BLTGOT ;GO TAKE INTERRUPT + [BRX]-[AR], ;BELOW E? + SKIP DP0, 3T +=0 END BLT, ;NO--STOP BLT + J/DONE + [ARX]_[ARX]+1, ;FOR PAGE FAIL LOGIC + SKIP IRPT +=0 VMA_[BRX]+1, + LOAD VMA, + PXCT BLT DEST, + START WRITE, ;YES--KEEP STORING + J/BLTCLR + VMA_[BRX]+1, ;INTERRUPT + LOAD VMA, + PXCT BLT DEST, + START WRITE, + J/BLTGO + +; Cleanup dispatch for BLT does: +; [AR]_WORK[SV.ARX], J/BLT-CLEANUP +; (Remember, you can't touch BRX here!) +BLT-CLEANUP: + [AR]_[AR] SWAP ;PUT SRC IN LEFT HALF + [AR]_WORK[SV.BRX], + HOLD LEFT + AC_[AR], ;STORE THE AC AND RETURN + J/CLEANED + +.TOC "UBABLT - BLT BYTES TO/FROM UNIBUS FORMAT" + +;THESE INSTRUCTION MOVE WORDS FROM BYTE TO UNIBUS AND UNIBUS TO BYTE +;FORMAT. FORMATS ARE: +; +;BYTE FORMAT: +; +; ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +; ;; BYTE 0 ;; BYTE 1 ;; BYTE 2 ;; BYTE 3 ;; 4 BITS ;; +; ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +; +;UNIBUS FORMAT: +; +; ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +; ;; 2 BITS ;; BYTE 1 ;; BYTE 0 ;; 2 BITS ;; BYTE 3 ;; BYTE 2 ;; +; ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +; +;Fortunately, opcodes 716 and 717 aren't used by DECUUO's WAITS simulator, +;so it's okay for these to be legal in user mode. + +;---This DEC code seems to have been written by someone who didn't understand macros + +=0* +BLTX: [BRX]_AC, ;FETCH THE AC (DEST IN RH) + CALL [SETBLT] ;DO THE REST OF THE SETUP + AC_[BR] ;STORE THE FINAL AC IN AC +BLTXLP: MEM READ, ;READ THE SOURCE WORD + Q_MEM, ;FROM MEMORY + B DISP ;SKIP IF BLTUB (OPCODE 717) +=110 Q_Q*.5, ;BLTBU (OPCODE 716) - SHIFT RIGHT 1 BIT + J/BLTBU1 ;CONTINUE INSTRUCTION + AD/D.AND.Q,DBUS/DBM, ;BLTUB - MASK LOW BYTES, SHIFT LEFT + DBM/#,#/377,DEST/AD*2,B/T1 ;AND STORE RESULT +=00 FE_S#,S#/1767, ;-9 MORE BITS TO PUT LOW BYTE OF LH + CALL [T1LSH] ; IN TOP OF LH SHIFT LEFT +=01 FE_S#,S#/1772, ;-6 BITS TO PUT HI BYTE TO RIGHT + CALL [Q_RSH] ; OF LOW BYTE. +=11 Q_Q.AND.#,#/001774 ;KEEP ONLY HI BYTES += + AD/A.OR.Q,A/T1,DEST/AD, ;MERGE PAIRS OF BYTES. NOW SWAPPED, + B/T1 ;BUT STILL IN HALF-WORDS + AD/57,RSRC/0A,A/T1, ;CLEAR LH OF Q WHILE LOADING + DEST/Q_AD ;RH WITH LOW WORD + Q_Q*2 ;SHIFT LOW WORD ACROSS 1/2 WORD + Q_Q*2 ;AND INTO FINAL POSITION + [T1]_[T1].AND.# CLR RH, ;CLEAR ALL BUT HIGH 16-BIT WORD + #/777774,J/BLTXV ;FROM T1 AND CONTINUE +BLTBU1: Q_Q*.5 ;NOW IN 1/2 WORDS + Q_Q*.5,HOLD LEFT ;INSERT A NULL BIT IN RH + Q_Q*.5,HOLD LEFT ;ONE MORE - NOW IN HALF WORDS + AD/D.AND.Q,DBUS/DBM, ;BUT NOT SWAPPED. COPY RIGHT BYTE + DBM/#,#/377,DEST/AD*2,B/T1 ;TO T1 AND SHIFT LEFT 1 POSITION +=00 FE_S#,S#/1771, ;-7 BITS MORE + CALL [T1LSH] ;TO FINAL RESTING PLACE +=01 FE_S#,S#/1770, ;-8. LEFT BYTES MOVE RIGHT + CALL [Q_RSH] ;TO FINAL RESTING PLACE +=11 Q_Q.AND.#,#/377 ;WANT ONLY THE NEW BYTES += +BLTXV: Q_[T1].OR.Q, ;MERGE RESULTS + J/BLTXW ;AND STUFF IN MEMORY +T1LSH: [T1]_[T1]*2,SHIFT,RETURN [1] +Q_RSH: Q_Q*.5,SHIFT,RETURN [2] +BLTXW: VMA_[BRX],START WRITE, ;DEST TO VMA + PXCT BLT DEST + MEM WRITE,MEM_Q ;STORE + [BRX]-[AR],3T,SKIP DP0 ;DONE? +=0 END BLT,J/DONE ;YES + [BRX]_[BRX]+1 ;NO, INC DEST + VMA_[ARX]+1,LOAD VMA, ; AND SOURCE (LOADING VMA) + PXCT BLT SRC,START READ, ;START UP MEMORY + J/BLTXLP ;AND CONTINUE WITH NEXT WORD