1
0
mirror of https://github.com/PDP-10/its.git synced 2026-02-24 08:12:12 +00:00

KL10 microcode.

Plus assorted KL10-related documents.
This commit is contained in:
Lars Brinkhoff
2018-06-11 10:12:23 +02:00
parent d5ad381a90
commit 6d577568a2
30 changed files with 8840 additions and 2 deletions

367
src/ucode/arith.6 Executable file
View File

@@ -0,0 +1,367 @@
.TOC "ADD, SUB"
.DCODE
270: R-PF, AC, J/ADD
I-PFõ`ÃYñ2—Á‰D
RPW, M, J/ADD
RPW, B, J/ADD
.UCODE
=00****
ADD: AR_ARõPa°YAD/A+B,AD øÓ ǧõlI©
=
.DCODE
274: R-PF, AC, J/SUB
I-PF, AC,ñ2—Ó«B
RPW, M, J/SUB
RPW, B, J/SUB
.UCODE
=00****
SUB: AR_ACö !R_AR
= AR_AR-BR,AD FLAGS,EXIT
.TOC "MUL, IMUL"
.DCODE
220: R, ACõe/“MUL
I, AC, J/ù3jÌ“
RW, M, J/IMUL
RW, B, J/IMUL
.UCODE
.IFNOT/IMUùWO¡T
=00*01*
IMULI:
.IF/IMULI.ùô*
=00*000
IMULI: SKP AR18,GEN AC0,SIGNS DISP, ;OPTIMIZE SPECIAL CASE
TIME/3T,SC_#,#/17.
=010 MQ_AR,AR_AC0, ;HERE FOR IMULI OF + BY +
CLR ARX,FE_#,#/-9., ; 9 STEPS WILL DO
CALL,J/Mú³)Õ…
.ENDIF/IMULI.OPT
IMUL: MQ_AúK Ò¿AC0, ;M'IER Tùè&ÑY M'CAND TO AR
CLR ARX,øÑo£Y#/-18.,
CALL,J/MULSUB ;CALL MULTIPLY SUBROUTINE
.IF/IMULI.OPT
=110 AR_SHIFT,SKP AR NE,INH CRY18, ;HERE FROM IMULI
I FETCH,J/MUL1 ; AFTER SHORT MULTIPLY
.ENDIF/IMULI.OPT
SC_#,#/35.,SKP AR SIG ;CHECK OVERFLOW AND STORE
=
=1****0
IMUL2: AR_SHIFT,B WRITE,J/ST6 ;STORE LOW WORD OF PRODUCT
SET AROV,AR_SIGN,J/IMUL2 ;NOTE OVERFLOW...
.DCODE
224: R, DBL AC, J/MUL
I, DBL AC, J/MUL
RW, M, J/MUL
RW, DBL B, J/MUL
.UCODE
=00*000
MUL: MQ_AR,CLR ARX, ;MULTIPLIER TO MQ
AR_AC0,FE_#,#/-18., ;SETUP MULTIPLICAND AND STEP CNT
CALL,J/MULSUB ;AND GO TO SUBROUTINE
=100 GEN AR*BR,AD/AND,SKP AD0 ;M'IER NEG, CHECK M'CAND & PROD TOO
=110
MUL1: SC_#,#/35.,EXIT ;STORE DOUBLE RESULT
SET AROV,J/MUL1 ;MUST HAVE SQUARED 400000,,0
=
.TOC "MULTIPLY SUBROUTINE"
; ENTER WITH MULTIPLIER IN MQ,
; MULTIPLICAND IN AR!ARX, MINUS STEP COUNT IN FE
; RETURNS PRODUCT IN AR!ARX!MQ.
; RETURN 4, 6 TELLS SIGN OF MULTIPLIER
; 4 AND 6 ARE USED SO CALLER CAN IGNORE
; DIFFERENCE BY ALIGNMENT OF CALL LOC'N
;[TIME=4+2(-FE)+(# OF ARITH STEPS)] ... IF FE=-18, 40-58.
MUL "FE_FE+1,DISP/MUL,MQ/MQ*.25"
MULSUB: BR_AR LONG,AR_0S,ARX_0S, ;M'CAND TO BR LONG, CLEAR PROD
MUL,J/MULP ;START THE MULTIPLICATION
=000 ;GRAB AN 8-WORD BLOCK
MULP:
=011 (AR+ARX+MQ)*2,FE_SC,RETURN6 ;DISCARD REDUNDANT SIGN BIT
=100 AR_AR*.25 LONG,MUL,J/MULP ;M'IER BITS 00 AFTER POS STEP
AR_(AR+BR)*.25,ARX/ADX*.25, ;01 AFTER +
MUL,J/MULP
AR_(AR-2BR)*.25,ARX/ADX*.25, ;10 AFTER +
MUL,J/MULM
AR_(AR-BR)*.25,ARX/ADX*.25,
MUL,J/MULM ;11 AFTER +
=000 ;ANOTHER 8-WORD BLOCK FOR
MULM: ; AFTER SUBTRACTION STEPS
=011 (AR+ARX+MQ)*2,FE_SC,RETURN4 ;M'IER WAS NEGATIVE
=100 AR_(AR+BR)*.25,ARX/ADX*.25, ;M'IER BITS 00 AFTER NEG STEP
MUL,J/MULP
AR_(AR+2BR)*.25,ARX/ADX*.25, ;01 AFTER -
MUL,J/MULP
AR_(AR-BR)*.25,ARX/ADX*.25, ;10 AFTER -
MUL,J/MULM
AR_AR*.25 LONG,MUL,J/MULM ;11 AFTER -
;HERE TO CONTINUE A LONG MULTIPLICATION
; WITH PARTIAL PRODUCT IN AR LONG
MULREE: AD/0S,MUL,J/MULP ;DIVE IN WITHOUT CLOBBERING AR
.TOC "DIV, IDIV"
.DCODE
230: R, DBL AC, J/IDIV
I, DBL AC, J/IDIV
RW, M, J/IDIV
RW, DBL B, J/IDIV
234: R, DBL AC, J/DIV
I, DBL AC, J/DIV
RW, M, J/DIV
RW, DBL B, J/DIV
.UCODE
=00*000
DIV: BR/AR,ARX+MQ_0.M, ;DIVISOR TO BR
AR_AC1*2,ARL/AD*2, ;LOW DIVIDEND TO AR
CALL.M,J/DIV1 ;GET HIGH DIVIDEND
=10
IDIV: BR/AR,ARX+MQ_0.M,SC_1, ;DIVISOR TO BR
AR_AC0,ARL/AD,CALL.M, ;DIVIDEND TO AR
SKP AR0,J/DIV2 ;TEST DIVISOR SIGN
=011
NODIVD: SET NO DIVIDE,J/NOP ;HERE IF DIVIDE IMPOSSIBLE
=110 ARX_AR,AR_-BRX, ;REMAIN TO ARX, GET CORRECT QUOTIENT
SC_#,#/36.,EXIT
ARX_AR,AR_BRX, ;HERE FOR POS QUOTIENT
SC_#,#/36.,EXIT
=
;HERE ON Dù5¤Ä TO SET UP DIVIDEND
DIV1: BRX/ARX,ARX_AR,AR_AC0, ;CLR BRX, DIVIDEND IN AR LONG
FE_#,#/33.,TIME/3T, ;SETUP ITERATION COUNT
SIGNS DIútJ_DIVS1 ;ENTER SUBR
;HERE ON IDIV TO SET UP DIVIDEND. SKIP IF DIVISOR NEG
; ALSO CALLED BY ADJBP
=1****0
DIV2: BRX/ARX,ARX_SHIFT,AR_SIGùË»‡LR BRX, DIVIDEND TO AR LONG
FE_#,#/33., ;SETUP LOOP COUNT
SKP AR0,J/DIVS1 ;ENTER SUBR ACCORDING TO SIGNS
BRX/ARX,ARX_SHIFT,AR_SIGN, ;CLR BRX, DIVIDEND TO AR LONG
FE_#,#/33., ;SETUP LOOP COUNT
SKP AR0,J/DIVS2 ;ENTER SUBR ACCORDING TO SIGNS
.TOC "INTEGER DIVIDE SUBROUTINE"
; ENTER WITH SIGNS DISPATCH OF DIVISOR AND DIVIDEND,
; DIVISOR IN BR, BRX CLR; DIVIDEND IN AR!ARX
; STEP COUNT IN FE (# OF QUOTIENT BITS -2)
; IF NO DIVIDE, RETURN 3 WITH IFETCH STARTED
; OTHERWISE, RETURN WITH SIGNED REMAINDER IN AR,
; POSITIVE QUOTIENT IN BRX AND MQ.
; RETURN 6 IF QUOTIENT SHOULD BE NEGATIVE,
; RETURN 7 IF QUOTIENT SHOULD BE POSITIVE.
;[TIME=14+3(FE)+3(D'END NEG)+3(RESTORE REQ'D)+1(REMAINDER NEG)]
; ... IF FE=33, 113-120
DIVIDE "FE_FE-1,DISP/DIV,MQ/MQ*2"
=1**100
DIVS1: DIVIDE,AR_2(AR-BR),
ARX/ADX*2,J/DIVS3 ;BOTH D'END AND D'SOR POS
AR_-AR LONG,J/DIVS1 ;MAKE POúh"I­IDEND, THEN CHK
DIVS2: DIVIDE,AR_2(AR+BR),
ARX/ADX*2,J/DIVS4 ;D'END POS, D'Sùô<C3B9>NG
AR_-AR LONG,J/DIVS2
=1*010
DIVS3÷BbI­ù1"¬ƒúWÙ(ƒR+BR),ARX/ADX*2,
ARL/AD*2,CALL.M,J/DIVLP ;START DIVIDING
I FETCH,RETURN3 ;RETURN TO CALLER WITH NO DIVIDE
AR_-BR,BRX/ARX,RETURN6 ;D'END NEG, SO NEGATE QUO & REM
BRX/ARX,RETURN7 ;EVERYTHING POSITIVE
=1**010
DIVS4: DIVIDE,AR_2(AR-BR),ARX/ADX*2,
ARL/AD*2,CALL.M,J/DIVLP ;BEGIN DIVISION FOR REAL BITS
I FETCH,RETURN3 ;ABORT FOR IMPOSSIBLE DIVISION
BRX/ARX,RETURN6 ;NEGATE QUO
AR_-BR,BRX/ARX,RETURN7 ;NEGATE REM
.TOC "BASIC DIVIDE LOOP"
; THE LOOP ITSELF IS AN INNER SUBROUTINE, TO MAKE IT SUITABLE
; FOR USE IN DOUBLE-LENGTH DIVISION.
; THE DOUBLE LENGTH REMAINDER IS RETURNED IN BR!BRX (RESTORED)
; THE SINGLE LENGTH QUOTIENT (LOW PART IF DBL-LEN DIVISION) IN ARX
; RETURN 6 IF QUOTIENT (REALLY AC0.XOR.BR) NEGATIVE, OR 7 IF POSITIVE
;[TIME=12+3(FE)+3(RESTORE REQ'D)] ... IF FE=33, 111-114.
=1*000
økL¡÷BbI­IDE,AR_2(AR+BR),ARX/ADX*2õ—Ä“VLP
DIVIDE,ARûì”A¥õ°©)YARX/Aø2YùKâI­LP
DIV-: DIVIDE,AR_2(AR-BR),ARX/ADX*2,J/DIVLP
DIV+: DIVIDE,AR_2(AR+BR),ARX/ADX*2,J/DIVLP
DIVIDE,AR_AR+BR,ARX/ADX,J/DIVX
ñ1$Ö“øVA¥_AR-BR,ARX/ADX,J/DIVX
DIVIDE,AR_AR-BR,ARX/ADX,J/DIVX ;NO SHIFT ON FINAL STEP
DIVIDE,AR_AR+BR,ARX/ADX,J/DIVX
;HERE AFTER FINAL DIVIDE STEP
; MQ HAS POSITIVE FORM QUOTIENT
; AR!ø4¬ AS REMAINDER, EXCEPT THATôj UST BE RESTORED IF Iúˆ
; NEGATIVE (IT'S NEGATIVE IF THERE WAS NO CARRY ON FINAL STEP)
; THEôéI<C3A9>INAL DIVIDEND IS STILL INôa°Y SO WE CHECK ITS SIGN
; TO DETERMINE WHETHER TO NEGATE THE (RESTORED) REMAINDER.
=1**100
DIVX: AR_AR+BR LONG ;RESTORE REMAIN WITH POS D'SOR
BR_AR LONG,ARX/MQ,FE_SC, ;LONG REMAIN TO BR, QUO TO ARX
SKP AC0+,RETURN6 ;RETURN TESTING D'END SIGN
AR_AR-BR LONG ;RESTORE REMAIN WITH NEG D'SOR
BR_AR LONG,ARX/MQ,FE_SC,
SKP AC0-,RETURN6
;SUBROUTINE FOR FIRST PART OF LONG DIVISIONS
; ENTER AT DDVSUB WITH SKP BR0
; RETURN3 IF SHOULD RESUME WITH ADD STEP
; RETURN5 IF SHOULD RESUME WITH SUBTRACT
=000
DDVLP: AR_2(AR+BR),ARX/ADX*2,DIVIDE,J/DDVLP
AR_2(AR-BR),ARX/ADX*2,DIVIDE,J/DDVLP
DDVSUB: AR_2(AR-BR),ARX/ADX*2,DIVIDE,J/DDVLP
AR_2(AR+BR),ARX/ADX*2,DIVIDE,J/DDVLP
AR_MQ,MQ_AR,FE_#,#/32.,RETURN3
AR_MQ,MQ_AR,FE_#,#/32.,RETURN5
AR_MQ,MQ_AR,FE_#,#/32.,RETURN5
AR_MQ,MQ_AR,FE_#,#/32.,RETURN3
.TOC "DOUBLE INúcÅ¥ ARITHMETIC -- DADD, DSUBõˆ"M«ùD‰ù5

.DCODE
.IFNOT/DBL.INT
114: I, J/UUO
I, J/UUO
I, J/UUO
I, J/UUO
.IF/DBL.INT
114: R, B/0, J/DASMD ;DADD
R, B/2, J/DASMD ;DSUB
R, B/4, J/DASMD ;DMUL
R, J/DDIV
.UCODE
;HERE FOR DOUBLE WORD ADD, SUBTRACT, MULTIPLY, OR DIVIDE
;ENTER WITH (E) IN AR, E IN VMA
=00**00
DDIV: ARX_AC3,CLR MQ,J/DDIV0 ;GET LOWEST PART OF D'END
DASMD: BR/AR,AR_AC1*2,ARL/AD*2, ;HIGH MEM WORD TO BR
VMA_VMA+1,LOAD ARX, ;ASK FOR LOW WORD
MQ_0.S,CALL.S,J/XFERW ;AND WAIT FOR IT
=11 ARX_ARX*2 ;SHIFT LOW MEM WORD LEFT
= BRX/ARX,ARX_AR,AR_AC0, ;ALL DATA IN PLACE
SC_#,#/35.,B DISP ;DO THE OPERATION
;HERE WITH (E) IN BR, (E+1)*2 IN BRX
; (AC) IN AR, (AC+1)*2 IN ARX
=00* AR_AR+BR LONG,AD FLAGS,EXIT DBL ;DADD
AR_AR-BR LONG,ø1F™AGS,Eûj ‰BL ;DSUB
MQ_SHIFT,AR_0S,ARX_0S, ;DMUL, USE AC1 AS INITIAL M'IER
FE_#,#/-18.,J/DMULT ;SETUP STEP COUNT
=
;HEREô§ÒADOUBLE WORD MULTIPLY
=1*00*
DMULT: AD/0S,MUL,CALL.M,J/MULP ;BEGIN MULTIPLY
=10* AR_AR+BR LONG ;CANCEL EFFECTS OF LOW BIT 0
MQ_AR,AR_MQ ;EXCH HI AND LOW PRODUCT WORDS
;HERE AFTER 1ST CALL ON MPY SUBR. SAVE LOW WORD OF PROD, GET HIGH M'IER
AC3_AR ;LOW WORD OF PRODUCT
AR_AC0 ;GET HIGH M'IER WORD
=1**000 MQ_AR,AR_MQ,CALL, ;DIVE IN AGAIN
FE_#,#/-18.,J/MULREE ;CONTINUE THE MULTIPLY
=100 GEN AR*BR,AD/AND,SKP AD0 ;SKP IF M'IER, M'CAND, & PROD NEG
=110
DMUL1: AC0_AR,AR_SIGN,
SC_#,#/35.,J/DMUL2 ;STORE HIGH WORD OF PRODUCT
SET AROV,J/DMUL1
;MULTIPLY NOW COMPLETE, STORE RESULTS WITH PROPER SIGN IN BIT 0
DMUL2: BR/AR,AR_SHIFT ;GET 2ND WITH SIGN, SAVE SIGN
AC1_AR,AR_ARX,ARX/MQ ;READY TO BUILD 3RD WORD
ARX_SHIFT,AR_BR,MQ_MQ*2 ;SIGNIFICANT Bù5) ©O ARX, SIGN TO AR
AR_SHIFT,ARX_AC3, ;3RD WORD IN AR, GET LOW
MQ_MQ*.25 ;EXTRA PROD BIT TO MQ 35
AC2_AR,AR_MQ ;,I FETCH WHEN TIMING FIXED
=0* ARX_SHIFT,AR_BR,I FETCH, ;LOW WORD AND SIGN READY
CALL,J/SHIFT ; GET LOW WORD TO AR
STRAC3: AC3_AR,FINISH ;GANZ GETAN
÷r"Ò‹ FOR DOUBLø¨$ΩEGER DIVISION
÷pi ø4Ð(), ARX HAS (AC3õ+A<>D MQ IS CLEAR
DDIV0: T0_AR,AR_ARX,ARX_ARX*8,SC_1 ;SAVE (E) IN T0
BRX/ARX,ARX_SHIFT, ;AC3 3-35 TO BRX, 1-2 TO ARX
AR_AC2,SC_#,#/2 ;øñj ƒC2 READY
AR_SHIFT,BR/ARõD‰wAC2 BITS 2-35 WITH AC3 1-2
ARX_AC1,VMA_VMA+1 ;READY TO GET (E+1)
BR/AR,AR_ARX,ARX_BR*2, ;LOW DOUBLE WORD NOW IN BR LONG
SC_1,FE_1
ARX_SHIFT,AR_AC0,SKP AD0 ;HIGH DOUBLEWORD IN AR LONG
=0
DDIV1: BR_AR LONG,AR_BRX,ARX_BR, ;HI POS D'END TO BR
LOAD AR,J/DDIV2 ;GET LOW D'SOR READY
BR_AR LONG,AR_-BR LONG, ;NEGATE LOW D'END
FE_-1,SKP CRY0 ;TEST FOR CARRY PROPAGATION
=0 BR_AR LONG,AR_BR COMP LONG,J/DDIV1
BR_AR LONG,AR_-BR LONG,J/DDIV1 ;FINISH NEGATION OF D'END
=0*
DDIV2: T1_AR,MQ_ARX,ARX_0S, ;LOWEST D'END TO T1, NEXT TO MQ
CALL,J/XFERW ; WAIT FOR (E+1)
ARX_SHIFT,AR_T0,SKP FE0 ;DIVISOR NOW IN AR LONG
=0 AR_BR LONG,BR_AR LONG, ;PUT OPERANDS IN PLACE FOR DIV
SIGNS DISP,J/DDIV3 ;TEST D'SOR SIGN
AR_BR LONG,BR_AR LONG,SET SR2, ;NOTE D'END NEGATIVE
SIGNS DISP,J/DDIV3
;HERE WITH THE DIVISOR IN BR LONG,
; THE HIGH PART OF THE MAGNITUDE OF THE DIVIDEND IN AR LONG,
; AND THE LOW PART OF THE MAGNITUDE OF THE DIVIDEND IN MQ AND T1
; SKIP IF DIVISOR NEGATIVE, & CHECK FOR NO-DIVIDE.
=011
DDIV3: AR_2(AR-BR),ARX/ADX*2,MQ_MQ*2, ;SEE IF FIRST DIVIDE STEP
SKP CRY0,J/DDIV4 ; GENERATES A 1
AR_2(AR+BR),ARX/ADX*2,MQ_MQ*2,SKP CRY0
=000
DDIV4: FE_#,#/33.,SKP BR0,CALL,J/DDVLP ;GO DO FIRST HALF OF DIVIDE
I FETCH,J/NODIVD ;TOO MANY QUOTIENT BITS
=011 AC1_AR,CLR SC,J/DDIV6 ;SAVE HI QUOTIENT IN AC1
=101 AC1_AR,SC_1S ;SET FLAG FOR RESUMPTION
=
DDIV6: AR_T1 ;GET LOWEST DIVIDEND BITS
=100 MQ_AR,AR_MQ,CALL, ;FINISH DIVISION, GENERATING
SKP SC0,J/DIVLP ; 35 MORE QUOTIENT BITS
=110 AR_AC1,SR DISP,SET SR3,J/DDVX1 ;QUOTIENT NEGATIVE. NOTE
AR_AC1,SR DISP ;HERE'S HIGH PART OF QUOTIENT
=1101
DDVX1: BR_AR LONG,AR_BR LONG,J/DDVX2 ;POS REMAINDER. GO STORE
BR_AR LONG,AR_-BR LONG,J/DDVX2 ;NEGATE REMAINDER
DDVX2: AC2_AR,AR_SIGN,SC_#,#/35.
AR_SHIFT,SR DISP ;GET LOW WORD OF REM. TEST QUO SIGN
=1110 AC3_AR,AR_BR,ARX/ADX*2, ;GET QUOTIENT, SQUEEZE OUT HOLE
EXIT DBL

690
src/ucode/basic.23 Executable file
View File

@@ -0,0 +1,690 @@
.TOC "THE INSTRUCTION LOOP"
;INSTRUCTION DECODE, EA COMPUTATION, AND OPERAND FETCH
; IN GENERAL, AN INSTRUCTION IS STARTED AT XCTGO.
; AT THIS TIME THE INSTRUCTION IS IN ARX AND IR, AND PC HAS ITS ADDRESS.
; THE DRAM OUTPUTS AND "AC" BITS WILL SETTLE DURING THIS
; MICROINSTRUCTION, AND WILL BE LATCHED BY THE CLOCK WHICH ENDS
; THE CYCLE. XCTGO DISPATCHES ON THE STATE OF THE
; INDIRECT AND INDEX BITS OF THE ARX (EA MOD DISP) TO COMPEA OR
; ONE OF THE THREE LOCATIONS FOLLOWING IT.
; IF INDIRECT IS SPECIFIED, THE INDIRECT POINTER IS FETCHED (AT
; COMPEA+2 OR +3 DEPENDING ON WHETHER INDEXING IS ALSO SPECIFIED).
; WE WAIT FOR IT AT INDRCT, AND THEN LOOP BACK TO COMPEA. WHEN NO
; INDIRECT IS CALLED FOR, WE COMPUTE THE INSTRUCTION'S EFFECTIVE ADDRESS
; (EA) AT COMPEA OR COMPEA+1 (DEPENDING ON WHETHER INDEXING IS CALLED
; FOR), AND PERFORM THE FUNCTION "A READ", WHOSE OPERATION DEPENDS
; ON THE DRAM A FIELD, AS FOLLOWS:
;
; MACRO A-FLD MEM FUNCTION VMA DISPATCH
; I 0 NONE AD(=EA) DRAM J
; I-PF 1 FETCH PC+1 DRAM J
; 2 NONE AD 42
; W 3 WR TST AD 43
; R 4 READ AD 44
; R-PF 5 READ AD 45
; RW 6 READ/WR TST AD 46
; RPW 7 RD-PSE/WR TST AD 47
;
; A FIELD VALUES 0 AND 1 ARE USED FOR INSTRUCTIONS WHICH NEITHER
; READ NOR WRITE THE CONTENTS OF EA (IMMEDIATE-MODE INSTRUCTIONS,
; JUMPS, ETC). THESE DISPATCH FROM "A READ" DIRECTLY TO THE MICROCODE
; WHICH HANDLES THE INSTRUCTION. IF THE A FIELD CONTAINS 1, "A READ"
; CAUSES A PREFETCH (FROM PC+1), SO THAT THE MBOX CAN WORK ON GETTING
; THE NEXT INSTRUCTION INTO ARX WHILE THE EBOX PERFORMS THIS ONE.
; IF THE A FIELD CONTAINS 3, THE MBOX PERFORMS A PAGING CHECK ON
; EA, AND CAUSES A PAGE FAIL IF THAT LOCATION IS NOT WRITABLE.
; THE MICROCODE GOES TO 43 TO WAIT FOR COMPLETION OF THE PAGE CHECK,
; AND AT THAT LOCATION LOADS AC INTO AR. THE WRITABILITY OF EA IS
; VERIFIED AT THIS TIME TO PREVENT INCORRECTLY SETTING FLAGS OR
; THE PROCESSOR STATE IF THE INSTRUCTION WILL BE ABORTED BY PAGE
; FAILURE. LOCATION 43 THEN DISPATCHES TO THE HANDLER FOR THE
; CURRENT INSTRUCTION.
; A FIELD VALUES 4 TO 7 PERFORM READS FROM EA. 6 AND 7 ALSO TEST
; THE WRITABILITY OF THE LOCATION, AND 7 PERFORMS THE FIRST HALF OF
; A READ-PAUSE-WRITE CYCLE IF EA IS AN UN-CACHED ADDRESS. THE DISPATCH
; IS TO 40+A, WHERE WE WAIT FOR MEMORY DATA TO ARRIVE IN AR. IF THE A
; FIELD WAS 5, WE PREFETCH FROM PC+1 AS SOON AS THE DATA ARRIVES.
; IN ANY CASE, WE DISPATCH ACCORDING TO THE DRAM J FIELD TO THE
; HANDLER FOR THE INSTRUCTION.
; IF A PAGE FAIL OCCURS AT ANY TIME (EITHER IN THIS CODE OR DURING
; INSTRUCTION EXECUTION) THE MICROPROCESSOR TRAPS TO CRAM LOCATION
; 1777, WHERE IT CAUSES A PAGE FAIL TRAP.
; MOST INSTRUCTIONS (THE MOVE, HALFWORD, AND BOOLEAN GROUPS,
; PLUS ADD AND SUB) ARE PERFORMED BY HANDLERS CONSISTING OF ONE OR
; TWO MICROINSTRUCTIONS WHICH LEAVE THE RESULT IN AR, AND COMPLETE
; BY INVOKING THE "EXIT" MACRO. EXIT USES THE MEM/B WRITE FUNCTION
; TO BEGIN A STORE TO MEMORY FOR THOSE MODES IN WHICH THE RESULT
; GOES TO MEMORY, AND DISP/DRAM B TO GET TO ONE OF THE MICROINSTRUCTIONS
; FOLLOWING ST0. THIS CODE DEPENDS ON A CERTAIN AMOUNT OF CORRELATION
; BETWEEN THE DRAM A AND B FIELDS. IN PARTICULAR, STAC (STORE AC)
; ASSUMES THAT A PREFETCH HAS OCCURRED, WHILE THE OTHERS ASSUME THAT
; NO PREFETCH HAS OCCURED. THUS NORMAL AND IMMEDIATE MODES, WHOSE
; RESULTS GO ONLY TO AC, MUST PREFETCH IN THE DRAM A FIELD, WHILE
; MEM, BOTH, AND SELF MODES, WHOSE RESULTS GO TO MEMORY, MUST NOT.
; (THIS RESTRICTION IS AVOIDED FOR THOSE INSTRUCTIONS WHICH NEVER
; PREFETCH -- IN MUL, DIV, AND IDIV BY USE OF THE EXIT TO ST2AC,
; AND IN IMUL AND THE SINGLE PRECISION FLOATING POINT
; INSTRUCTIONS BY A RESTRICTED EXIT TO ST6.)
; ANOTHER LARGE SET OF INSTRUCTIONS (SKIP, AOS, SOS, JUMP, AOJ,
; SOJ, AOBJ, CAI, CAM, AND THE TEST GROUP) KNOWS WHERE TO PUT THE
; RESULTS WITHOUT MODE INFORMATION, AND THEY USE THE DRAM B FIELD TO
; DETERMINE WHETHER TO SKIP OR JUMP, AS A FUNCTION OF THEIR OPERANDS.
; SKIP, AOS, AND SOS ARE CONSIDERED SELF-MODE INSTRUCTIONS,
; AND AFTER MAKING THE FETCH DECISION (AND RE-WRITING MEMORY, IN
; THE CASE OF AOS OR SOS), JUMP TO STSELF TO DECIDE WHETHER OR NOT
; TO PUT THE RESULT ALSO IN AC. THE OTHER INSTRUCTIONS OF THIS SET
; JUMP TO STORAC OR NOP AFTER MAKING THE FETCH DECISION, DEPENDING
; ON WHETHER OR NOT THE OPCODE DEFINITION REQUIRES MODIFICATION OF AC.
; (NOTE THE DIFFERENCE BETWEEN STAC AND FINI ON THE ONE HAND,
; AND STORAC AND NOP ON THE OTHER -- STORAC AND NOP MUST BE USED WHEN
; THE NEXT INSTRUCTION FETCH OCCURS ON THE PRECEDING EBOX CYCLE, BECAUSE
; NICOND MUST NOT IMMEDIATELY FOLLOW A FETCH (ONE CYCLE REQUIRED FOR
; VMA AC REF TO MAKE IT THROUGH THE NICOND LOGIC), STAC AND FINI ARE
; USED WHEN THERE HAS BEEN AN INTERVENING CYCLE.)
.TOC "NEXT INSTRUCTION DISPATCH"
;START BY PUTTING PC WORD IN AR, JUMP HERE
0:
START: SET FLAGS_AR,BR/AR,J/BRJMP ;LOAD UP FLAGS
CONT: VMA/PC,FETCH,J/XCTW ;HERE TO CONTINUE FROM PC
; DISP/NICOND (THE "NXT INSTR" MACRO) BRINGS US TO ONE OF THE
; LOCATIONS FOLLOWING "NEXT". PC HAS BEEN UPDATED TO ADDRESS THE NEXT
; INSTRUCTION IN THE NORMAL FLOW, AND IF IT IS FROM MEMORY
; (AS OPPOSED TO AC'S), THE INSTRUCTION IS IN ARX AND IR.
; THE NICOND DISPATCH IS PRIORITY ENCODED, AS FOLLOWS:
; [FOR FULL DETAILS, SEE PRINT CON2]
;(1) IF PI CYCLE IS TRUE, GO TO NEXT FOR SECOND HALF
; OF STANDARD OR VECTOR INTERRUPT.
;(2) IF THE RUN FLOP (CON RUN) IS OFF, GO TO NEXT+2, FROM WHICH THE
; MICROCODE WILL ENTER THE HALT LOOP TO WAIT FOR THE CONSOLE TO RESTART
; INSTRUCTION PROCESSING.
;(3) IF THE METER HAS A REQUEST, GO TO NEXT+4 (MTRINT) TO SERVE IT.
;(4) IF THE PI SYSTEM HAS A REQUEST READY, GO TO NEXT+6 (INTRPT)
; TO START A PI CYCLE.
;(5) IF CON UCODE STATE 05 (TRACK EN) IS SET, GO TO NEXT+10 OR 11.
; THIS FLOP IS ENTIRELY UNDER CONTROL OF THE MICROCODE, AND IS ONLY
; USED FOR THE SPECIAL STATISTICS-GATHERING MICROCODE.
;(6) IF THE LAST INSTRUCTION SET A TRAP FLAG, GO TO NEXT+13 OR +17,
; IT DOESN'T MATTER WHICH.
;(7) IF VMA CONTAINS AN AC ADDRESS, IMPLYING THAT THE NEXT
; INSTRUCTION IS TO COME OUT OF FAST MEMORY, GO TO NEXT+16 TO GET IT.
;(10) --NORMAL CASE-- THE INSTRUCTION IS IN ARX, READY TO GO, GO
; TO NEXT+12 (XCTGO).
=11*0000 ;USE LOC'NS INACCESSIBLE TO DRAM
NEXT: SET PI CYCLE,GEN FE, ;2ND PART OF INTERRUPT
BYTE DISP,J/PICYC2 ;SKIP IF VECTOR INT
=0010 AR_0S,SET HALTED,J/HALT1 ;HERE IF RUN FLOP OFF
=0100
MTRINT: CLR ACCOUNT EN,J/MTRREQ ;HERE IF METER REQUEST UP
AR_EBUS,SC_#,#/2,J/PICYC1 ;HERE IF TAKE INTRPT DOESNT FIND
=0110 ; A METER REQUEST
INTRPT: AR_EBUS,SC_#,#/2,J/PICYC1 ;HERE IF INTERRUPT PENDING
.IF/TRACKS
=1000 AR_TRX+1,GEN CRY18,SKP CRY0,J/TRK1 ;HERE TO STORE PC BEFORE
AR_TRX+1,GEN CRY18,SKP CRY0,J/TRK1 ; EXECUTING NEXT INSTR
.ENDIF/TRACKS
.IF/OP.CNT
=1000 SC_#,#/9.,SKP USER,J/OPCT1 ;COUNT THIS INSTR
SC_#,#/9.,SKP USER,J/OPCT1
.ENDIF/OP.CNT
.IF/OP.TIME
=1000 AR_2,CLR TRK+PA EN,J/OPTM1 ;TIME OUT THIS INSTR
AR_2,CLR TRK+PA EN,J/OPTM1
.ENDIF/OP.TIME
;-- THE NICOND DISPATCH BLOCK CONTINUES ON THE NEXT PAGE --
;-- NICOND DISPATCH CONTINUED --
=1010
XCTGO: BRX/ARX,SET ACCOUNT EN, ;SAVE INSTR, ENABLE ACCOUNTING,
EA MOD DISP,J/COMPEA,AR_1S ;GO CALCULATE EA, -1 FOR SOJ HACK
.IFNOT/ONE PROCEED
TRAP: VMA_420+TRAP,J/TRAPX ;HERE IF TRAP BITS SET
.IF/ONE PROCEED
TRAP: GET ECL EBUS,SC_1,J/TR3CHK ;TRAP, CHECK FOR ONE PROCEED
.ENDIF/ONE PROCEED
=1110 ARX_FM(VMA),TIME/3T,LOAD IR,J/XCTGO ;HERE IF INSTR IS IN FM
.IFNOT/ONE PROCEED
VMA_420+TRAP,J/TRAPX ;HERE IF TRAP BITS SET
.IF/ONE PROCEED
ARX_FM(VMA),TIME/3T,LOAD IR, ;HERE IF TRAP AND VMA->ACS
J/TRAP ;FETCH THE INSTR THEN TRAP
.ENDIF/ONE PROCEED
.IF/ONE PROCEED
;HERE ON TRAPS, WITH INSTRUCTION IN ARX AND IR, 1 IN SC,
;AND ECL EBUS GRABBED. UNFORTUNATELY THE HARDWARE CAREFULLY
;CLEARS THE TRAP BITS IN THE PC WORD ON A NICOND, BUT
;WE CAN USE A DIAGNOSTIC FUNCTION TO READ THE TRAP CYC BITS (SCD4).
;THE "ADDRESS BREAK INHIBIT" HAIR (SCD5) IS USED TO
;DETECT WHEN AN INSTRUCTION IS COMPLETED.
;IF THIS IS A TRAP 3, AND SCD ADDR BRK CYC IS TRUE, WE ARE
;IN THE MIDDLE OF A ONE-PROCEED, SO SUPPRESS THE TRAP.
;SCD ADDR BRK CYC IS ON WHEN NICOND IS DONE WITH
;ADR BRK INH SET IN THE PC FLAGS (I.E. JUST STARTING
;OR RE-STARTING THE INSTRUCTION BEING ONE-PROCEEDED.)
TR3CHK: AR03-04_SCD TRAP CYC
VMA_420+TRAP,SH DISP,J/TR3DSP ;VMA -> TRAP INST, CHECK TRAP NUMBER
=11100
TR3DSP:
=01
REL ECL EBUS,J/TRAPX ;TRAP 1 - TAKE TRAP
REL ECL EBUS,J/TRAPX ;TRAP 2 - TAKE TRAP
AR05_SCD ADDR BRK CYC ;TRAP 3 - CHECK FOR ONE PROCEED
GEN P AND SC,SKP SCAD NE ;SKIP IF ONE-PROCEEDING
=1***0
REL ECL EBUS,J/TRAPX ;NO, TAKE THE TRAP
REL ECL EBUS ;YES, DO THE INSTR THEN
TRAP3,J/XCTGO ;ARRANGE FOR ANOTHER TRAP
;WHEN THE INSTRUCTION COMPLETES
.ENDIF/ONE PROCEED
;HERE ON TRAPS, VMA SETUP WITH 420+TRAP CODE
TRAPX: LOAD ARX,PT REF ;GET AND XCT TRAP INSTR
SET PC+1 INH ;DON'T INCREMENT PC FOR THIS INSTR
;HERE AFTER FETCHING INSTR TO BE EXECUTED
XCTW: ARX_MEM,LOAD IR,J/XCTGO ;GET INSTR TO XCT
.TOC "EFFECTIVE ADDRESS COMPUTATION AND OPERAND FETCH"
;COME HERE WITH -1 IN AR IF YOU EXPECT SOJ TO WORK!
=11***00 ;HERE WITH XR CALC IN PROG
COMPEA: AR_ARX (AD),A READ, ;NO MOD, GET OPERAND IF ANY
MQ_AR ;SOJ SERIES EXPECTS -1 IN MQ
AR_ARX+XR,A READ, ;INDEXED, NO @
MQ_AR ;SOJ SERIES EXPECTS -1 IN MQ
GEN ARX,A INDRCT, ;DO INDIRECT, NO INDEX
SKP INTRPT,J/INDRCT
GEN ARX+XR,A INDRCT, ;BOTH @ AND XR
SKP INTRPT,J/INDRCT
=11****0
INDRCT: ARX_MEM,J/INDLP ;GET INDIRECT POINTER, EVAL
TAKINT: ARX_MEM,TAKE INTRPT ;INTERRUPT DURING INDIRECT
;APPARENTLY A INDRCT AT COMPEA+2/+3 CAN
; CAUSE AR AS WELL AS ARX TO BE CLOBBERED BY ARX_MEM.
;HENCE WE MUST RESTORE THE -1 THAT THE SOJ SERIES DEPENDS ON.
INDLP: EA MOD DISP,AR_1S,J/COMPEA ;EVALUATE POINTER
.TOC "WAIT FOR (E)"
;THE EXECUTE CODE FOR EACH INSTRUCTION IS ENTERED WITH
; THE OPCODE AND AC # IN BRX AND IR, THE LAST INDIRECT WORD
; IN ARX, AND AR AND VMA SETUP AS A FUNCTION OF THE A
; FIELD OF THE DISPATCH RAM. A PREFETCH IS IN PROGRESS IF THE
; DRAM A FIELD WAS 1 OR 5 (OR IF IR CONTAINS "JRST 0,").
;ON "A READ", THE HARDWARE DISPATCHES TO THE EXECUTE CODE FOR
; THE INSTRUCTION IF THE DRAM A FIELD IS 0 OR 1. IF THE A FIELD
; CONTAINS 2-7, THE HARDWARE DISPATCHES TO 40+A, BELOW:
;COME HERE ON "A READ" FUNCTION IF DRAM A FIELD IS 3
; A "WRITE TST" IS IN PROGRESS
43: BR/AR,AR_AC0,MB WAIT, ;WAIT FOR PERMISSION TO WRITE
TIME/3T,IR DISP,J/0 ;AND GO TO EXECUTE CODE
;HERE ON "A READ" FUNCTION IF DRAM A FIELD IS 4
; A "LOAD AR" IS IN PROGRESS
44: BR/AR,AR_MEM,TIME/3T, ;GET OPERAND
IR DISP,J/0 ; START EXECUTE
;HERE ON "A READ" IF A FIELD IS 5
; A "LOAD AR" IS IN PROGRESS, AND WE MUST PREFETCH WHEN IT COMPLETES
45: BR/AR,FIN XFER,I FETCH, ;GET OPERAND, PREFETCH,
TIME/3T,IR DISP,J/0 ; & START EXECUTE
;HERE ON "A READ" IF A FIELD IS 6
; A "LOAD AR" IS IN PROGRESS, BUT PAGING IS TESTING WRITABILITY
46: BR/AR,AR_MEM,TIME/3T, ;GET OPERAND
IR DISP,J/0 ; START EXECUTE
;HERE ON "A READ" IF A FIELD IS 7
; A "READ-PAUSE-WRITE" IS IN PROGRESS
47: BR/AR,AR_MEM,TIME/3T, ;GET OPERAND
IR DISP,J/0 ; START EXECUTE
.TOC "TERMINATION"
;DISPATCH HERE WITH THE "EXIT" MACRO,
; OR JUMP DIRECTLY TO ONE OF THESE LOCATIONS.
=11*000
ST0: ;BASE FOR B DISP IN EXIT MACRO
=001
ST2AC: AC0_AR,AR_SIGN,I FETCH,J/STD1 ;HERE TO STORE AC0 & AC1
FIN STORE,EXIT DBL ;MULB, DIVB, ETC ...
FIN STORE,I FETCH, ;SELF MODE
SKP AC#0,J/STSELF ; RESULT TO AC TOO?
=101
STAC: AC0_AR,NXT INSTR ;NORMAL AND IMMEDIATE MODES
ST6:
IFNOP:
STMEM: FIN STORE,I FETCH,J/NOP ;MEM MODE
IFSTAC:
STBOTH: FIN STORE,I FETCH,J/STORAC ;BOTH MODE
=
;HERE TO FINISH, AFTER FETCHING NEXT INSTRUCTION.
; WE MUST GUARANTEE AT LEAST ONE EBOX CYCLE BETWEEN FETCH AND NICOND,
; TO ALLOW VMA AC REF TO MAKE IT THROUGH THE NICOND LOGIC.
=11***0
STSELF: ;SKIP, AOS, SOS COME HERE
STORAC: SR_0,J/STAC ;STORE AC, TOO
NOP: J/FINI ;DELAY THEN NXT INSTR
.IF/JPC SUPPORT
=11*110
NJPCP: AR_PC,SKP USER,J/JPCEX ;FOR JPC HACK - SKIP IF NOT JUMPING
.ENDIF/JPC SUPPORT
FINI: SR_0,NXT INSTR ;GET NEXT INSTR IN ARX & IR,
; LOAD PC, TEST PI CYCLE, RUN,
; PI READY, TRAPS
;HERE TO STORE ARITHMETIC DOUBLE RESULTS
DSTAC: AC0_AR,AR_SIGN ;HERE WITH FETCH STARTED
STD1: AR_SHIFT,SR_0 ;BRING IN LOW PART
STAC1: AC1_AR,NXT INSTR AFTER AC1 ;STORE AC1
;HERE TO GET MICRO-CODE VERSION #. FIXED LOC'N SO SOFTWARE CAN FIND IT
137:
UVERS: BR/AR,AR0-8_#,#/VERS,J/GTAR08 ;COPY VERSION TO AR
.TOC "MOVE GROUP, EXCH, BLT"
.DCODE
200: R-PF, AC, J/MOVE ;BASIC MOVE
I-PF, AC, J/MOVE
.IF/WRTST
W, M, J/MOVE
.IFNOT/WRTST
I, B/1, J/MOVEM
.ENDIF/WRTST
RPW, S, J/MOVE
204: R-PF, AC, J/MOVS
I-PF, AC, J/MOVS
W, M, J/MOVS
RPW, S, J/MOVS
210: R-PF, AC, J/MOVN
I-PF, AC, J/MOVN
W, M, J/MOVN
RPW, S, J/MOVN
214: R-PF, AC, J/MOVM
I-PF, AC, J/MOVM
W, M, J/MOVM
RPW, S, J/MOVM
.UCODE
; ENTER WITH 0,E, (E), OR (AC) IN AR
=00****
MOVS: AR_AR SWAP,EXIT ;ALSO USED BY HALFWORD GROUP
=
=00****
MOVM: BR/AR,SKP AR0,J/MOVE ;FORCE POSITIVE
=
=00****
MOVN: BR/AR,J/MOVNEG ;GET NEGATIVE
=
=00*000
MOVE: EXIT ;STORE AS IS FROM AR
MOVNEG: AR_-BR,AD FLAGS,FETCH WAIT,J/MOVE
;EXCH, BLT
.DCODE
250: RPW, B/0, J/EXCH
I, J/BLT
.UCODE
=00***0
MOVEM: ;LIKE EXCH, EXCEPT NO STORE AC
EXCH: ARX_AR,AR_AC0,STORE,J/STMAC ;PUT AC AT E, THEN STORE AC
BLT: MQ_AR,ARX_AR, ;END ADDR TO MQ & ARX
ARR_AC0,ARL_ARL,J/BLT1 ;FIRST DEST ADDR TO AR
.TOC "HALFWORD GROUP"
; DESTINATION LEFT HALF
.DCODE
500: R-PF, AC, J/HLL
I-PF, AC, J/HLL
RPW, M, J/HRR ;HLLM = HRR EXCEPT FOR STORE
RPW, S, J/MOVE ;HLLS = MOVES
R-PF, AC, J/HRL
I-PF, AC, J/HRL
RPW, M, J/HRLM
RPW, S, J/HRLS
510: R-PF, AC, J/HLLZ
I-PF, AC, J/HLLZ
W, M, J/HLLZ
RPW, S, J/HLLZ
R-PF, AC, J/HRLZ
I-PF, AC, J/HRLZ
W, M, J/HRLZ
RPW, S, J/HRLZ
520: R-PF, AC, J/HLLO
I-PF, AC, J/HLLO
W, M, J/HLLO
RPW, S, J/HLLO
R-PF, AC, J/HRLO
I-PF, AC, J/HRLO
W, M, J/HRLO
RPW, S, J/HRLO
530: R-PF, AC, J/HLLE
I-PF, AC, J/HLLE
W, M, J/HLLE
RPW, S, J/HLLE
R-PF, AC, J/HRLE
I-PF, AC, J/HRLE
W, M, J/HRLE
RPW, S, J/HRLE
; DESTINATION RIGHT HALF
540: R-PF, AC, J/HRR
I-PF, AC, J/HRR
RPW, M, J/HLL ;HRRM = HLL EXCEPT FOR STORE
RPW, S, J/MOVE ;HRRS = MOVES
R-PF, AC, J/HLR
I-PF, AC, J/HLR
RPW, M, J/HLRM
RPW, S, J/HLRS
550: R-PF, AC, J/HRRZ
I-PF, AC, J/HRRZ
W, M, J/HRRZ
RPW, S, J/HRRZ
R-PF, AC, J/HLRZ
I-PF, AC, J/HLRZ
W, M, J/HLRZ
RPW, S, J/HLRZ
560: R-PF, AC, J/HRRO
I-PF, AC, J/HRRO
W, M, J/HRRO
RPW, S, J/HRRO
R-PF, AC, J/HLRO
I-PF, AC, J/HLRO
W, M, J/HLRO
RPW, S, J/HLRO
570: R-PF, AC, J/HRRE
I-PF, AC, J/HRRE
W, M, J/HRRE
RPW, S, J/HRRE
R-PF, AC, J/HLRE
I-PF, AC, J/HLRE
W, M, J/HLRE
RPW, S, J/HLRE
.UCODE
;FIRST, THE 16 OPS WHICH DO NOT AFFECT THE "OTHER" HALF.
;THESE MUST BE TREATED SEPARATELY, BECAUSE THEY COMBINE MEMORY DATA
;IN AR WITH DATA FROM THE FM. ENTER WITH 0,E OR (E) IN AR.
=00***0
HRR: ARL_AC0,ARR_ARR,EXIT ;HRR, HRRI, HLLM
=00****
HLL: ARR_AC0,ARL_ARL,EXIT ;HLL, HLLI, HRRM
= ;HRRS, HLLS ARE BOTH EQUIVALENT TO MOVES
=00****
HRL: ARL_ARR,ARR_AC0,EXIT ;HRL, HRLI
=
=00****
HLR: ARR_ARL,ARL_AC0,EXIT ;HLR, HLRI
=
=00***0
HRLM: ARL_ARR,ARR_AC0,J/MOVS ;HRLM
HRLS: ARL_ARR,ARR_ARR,EXIT ;HRLS
=
=00***0
HLRM: ARR_ARL,ARL_AC0,J/MOVS ;HLRM
HLRS: ARR_ARL,ARL_ARL,EXIT ;HLRS
=
;NOW THE HALFWORD OPS WHICH CONTROL THE "OTHER" HALF
; ENTER WITH 0,E, (E), OR (AC) IN AR
=00****
HRRE: SKP AR18 ;SELECT HRRZ OR HRRO ON SIGN
=
=00***0
HRRZ: ARL_0S,ARR_ARR,EXIT
HRRO: ARL_1S,ARR_ARR,EXIT
=
=00****
HRLE: SKP AR18
=
=00***0
HRLZ: ARL_ARR,ARR_0S,EXIT
HRLO: ARL_ARR,ARR_1S,EXIT
=
=00****
HLRE: SKP AR0
=
=00***0
HLRZ: ARR_ARL,ARL_0S,EXIT
HLRO: ARR_ARL,ARL_1S,EXIT
=
=00****
HLLE: SKP AR0
=
=00***0
HLLZ: ARR_0S,ARL_ARL,EXIT
HLLO: ARR_1S,ARL_ARL,EXIT
=
.TOC "DMOVE, DMOVN, DMOVEM, DMOVNM"
;DOUBLE-WORD MOVES
.DCODE
120: R, B/0, J/DMOVE
R, B/1, J/DMOVN
.UCODE
; ENTER WITH (E) IN AR
=00****
DMOVN:
DMOVE: VMA_VMA+1,LOAD ARX,B DISP ;PICK UP (E+1)
=
=1**00
ARX_MEM,J/STDAC ;GO STORE DOUBLE AC
ARX_MEM,MQ_0.S,CALL.S,J/GTDBR ;LOAD BR WITH DOUBLE OPERAND
=11 AR_-BR LONG,AD FLAGS, ;NEGATE DOUBLE OPERAND
SC_#,#/35. ;& STORE RESULT
DBLST: AC0_AR,AR_0S,I FETCH,J/STD1 ;STORE HIGH WORD, READY LOW
;DOUBLE MOVES TO MEMORY
.DCODE
124: W, J/DMOVEM
W, J/DMOVNM
.UCODE
;ENTER WITH (AC) IN AR
=00**00
DMOVEM: ARX_AC1,STORE,SC_#,#/36.,J/DMVM1
DMOVNM: ARX_AC1,MQ_0.S,CALL.S,J/GTDBR ;HIGH WORD IS ALREADY IN AR
=11 AR_-BR LONG,AD FLAGS, ;NEGATE
STORE,SC_#,#/35. ; & STORE
=
DMVM1: MEM_AR,VMA_VMA+1,AR_0S
AR_SHIFT,STORE,J/STMEM
GTDBR: ARX_ARX*2 ;SHIFT OUT LOW SIGN
LDBRL: BR_AR LONG,RETURN3 ;COPY TO BR LONG
.TOC "BOOLEAN GROUP"
.DCODE
400: I-PF, AC, J/SETZ
I-PF, AC, J/SETZ
IW, M, J/SETZ
IW, B, J/SETZ
.UCODE
=00****
SETZ: AR_0S,EXIT
=
.DCODE
404: R-PF, AC, J/AND
I-PF, AC, J/AND
RPW, M, J/AND
RPW, B, J/AND
.UCODE
=00****
AND: AR_AR*AC0,AD/AND,EXIT
=
.DCODE
410: R-PF, AC, J/ANDCA
I-PF, AC, J/ANDCA
RPW, M, J/ANDCA
RPW, B, J/ANDCA
.UCODE
=00****
ANDCA: AR_AR*AC0,AD/ANDCB,EXIT
=
.DCODE
414: R-PF, AC, J/MOVE ;SETM = MOVE
I-PF, AC, J/MOVE
RPW, M, J/MOVE ;SETMM = NOP THAT WRITES MEMORY
RPW, B, J/MOVE ;SETMB = MOVE THAT WRITES MEMORY
420: R-PF, AC, J/ANDCM
I-PF, AC, J/ANDCM
RPW, M, J/ANDCM
RPW, B, J/ANDCM
.UCODE
=00****
ANDCM: AR_AR*AC0,AD/ANDCA,EXIT
=
.DCODE
424: R-PF, J/TDN
I-PF, J/TDN
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
RPW, M, J/XOR
RPW, B, J/XOR
.UCODE
=00****
XOR: AR_AR*AC0,AD/XOR,EXIT
=
.DCODE
434: R-PF, AC, J/IOR
I-PF, AC, J/IOR
RPW, M, J/IOR
RPW, B, J/IOR
.UCODE
=00****
IOR: AR_AR*AC0,AD/OR,EXIT
=
.DCODE
440: R-PF, AC, J/ANDCB
I-PF, AC, J/ANDCB
RPW, M, J/ANDCB
RPW, B, J/ANDCB
.UCODE
=00****
ANDCB: AR_AR*AC0,AD/ANDC,EXIT
=
.DCODE
444: R-PF, AC, J/EQV
I-PF, AC, J/EQV
RPW, M, J/EQV
RPW, B, J/EQV
.UCODE
=00****
EQV: AR_AR*AC0,AD/EQV,EXIT
=
.DCODE
450: I-PF, AC, J/SETCA
I-PF, AC, J/SETCA
IW, M, J/SETCA
IW, B, J/SETCA
.UCODE
=00****
SETCA: AR_AR*AC0,AD/SETCB,EXIT
=
.DCODE
454: R-PF, AC, J/ORCA
I-PF, AC, J/ORCA
RPW, M, J/ORCA
RPW, B, J/ORCA
.UCODE
=00****
ORCA: AR_AR*AC0,AD/ORCB,EXIT
=
.DCODE
460: R-PF, AC, J/SETCM
I-PF, AC, J/SETCM
RPW, M, J/SETCM
RPW, B, J/SETCM
.UCODE
=00****
SETCM: ADA/AR,AD/SETCA,AR/AD,EXIT
=
.DCODE
464: R-PF, AC, J/ORCM
I-PF, AC, J/ORCM
RPW, M, J/ORCM
RPW, B, J/ORCM
.UCODE
=00****
ORCM: AR_AR*AC0,AD/ORCA,EXIT
=
.DCODE
470: R-PF, AC, J/ORCB
I-PF, AC, J/ORCB
RPW, M, J/ORCB
RPW, B, J/ORCB
.UCODE
=00****
ORCB: AR_AR*AC0,AD/ORC,EXIT
=
.DCODE
474: I-PF, AC, J/SETO
I-PF, AC, J/SETO
IW, M, J/SETO
IW, B, J/SETO
.UCODE
=00****
SETO: AR_1S,EXIT
=

4
src/ucode/bcirc.3 Executable file
View File

@@ -0,0 +1,4 @@
.SET/CIRC.BIG.OPT=1
.SET/CIRC=1

157
src/ucode/blt.9 Executable file
View File

@@ -0,0 +1,157 @@
.TOC "BLT"
; ENTER WITH 0,E IN AR
;IN THE LOOP, ARX CONTAINS THE CURRENT DESTINATION ADDRESS,
; BRX CONTAINS THE TERMINAL ADDRESS, AND BR CONTAINS THE DIFFERENCE
; BETWEEN THE SOURCE AND DESTINATION ADDRESSES.
;UNLIKE EARLIER -10 PROCESSORS, THIS CODE CHECKS FOR THE CASE IN WHICH
; THE DESTINATION ADDRESS IN RH(AC) IS GREATER THAN E, AND RATHER THAN
; STOPPING AFTER ONE WORD, COPIES DOWNWARD (EFFECTIVELY DECREMENTING
; AC BY 1,,1 ON EACH STEP, RATHER THAN INCREMENTING).
;THIS CODE ALSO 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.
;BLT: ARX_AR,MQ_AR,ARR_AC0,ARL_ARL ;END TO ARX & MQ, DEST TO AR
BLT1: BR/AR,ARX_AR,BRX/ARX, ;DST TO BR & ARX, END TO BRX
AR_AC0 ;SRC TO ARL
ARR_ARL,ARL_0.M ;SRC TO ARR
AR_AR-BR ;SRC-DST TO ARR
.IF/BACK.BLT
BR/AR,SKP ARX LE BRX ;SRC-DST TO BR. UP OR DOWN?
=00 AR_MQ-1,CALL,J/BLTAC ;DOWN, READY WITH E-1
AR_MQ+1,CALL,J/BLTAC ;UP, PUT E+1 IN AR FOR AC
DOWN: VMA_ARX+BR,LOAD AR,J/DN1 ;DOWN, START THE LOOP
.IFNOT/BACK.BLT
=0* BR/AR,AR_MQ+1,CALL,J/BLTAC ;SRC-DST TO BR, E+1 IN AR
.ENDIF/BACK.BLT
SKP BR EQ -1,J/UP ;IS THIS CORE CLEARING CASE?
;HERE TO SETUP FINAL AC
BLTAC: ARL_ARR,AR_AR+BR ;FINAL DEST TO LH, SRC TO RH
AR_AR SWAP,SR_BLT(SRC) ;REARRANGE
AC0_AR,RETURN2
;HERE FOR UPWARD BLT (AC RH .LE. E)
=0
UP: VMA_ARX+BR,LOAD AR,J/UP1 ;NOT CLEAR CORE
SKP P!S XCT,VMA_ARX+BR,LOAD AR ;DO NOT OPTIMIZE UNDER EXT ADDR
;USE EVEN LOC'NS OF THIS BLOCK OF 4 IN SPECIAL "CLEAR CORE" CASE
=00 AR_MEM,CALL,SR_BLT(DST),J/UP2 ;GET THE WORD TO STORE IN ALL
UP1: AR_MEM,CALL,SR_BLT(DST),J/UP2 ;GET SOURCE WORD
CALL,SR_BLT(DST),J/UP2 ;HERE TO STORE SAME SRC AGAIN
VMA_ARX+BR,LOAD AR,J/UP1 ;HERE TO GET NEXT SRC
UP2: VMA_ARX,STORE,SKP INTRPT ;OK, GET DST ADDRESS
=0
UP3: SKP ARX LT BRX,J/UP4 ;CHECK FOR LAST TRANSFER
MEM_AR,J/BLTPF ;FINISH THIS, GO SERVE INTRPT
=0
UP4: FIN STORE,I FETCH,J/NOP ;THAT'S ALL, FOLKS
MEM_AR,ARX_ARX+1, ;STORE DST,
SR_BLT(SRC),RETURN2 ; CONTINUE
;BLT CONTINUED - HERE FOR DOWNWARD BLT (AC RH .GT. E)
.IF/BACK.BLT
DN1: AR_MEM,SR_BLT(DST) ;WAIT FOR SOURCE DATA
VMA_ARX,STORE,SKP INTRPT ;OK, START DST REF
=0 SKP ARX LE BRX,J/DN3 ;CHECK FOR END CONDITION
MEM_AR,J/BLTPF ;FINISH STORE, TAKE INTRPT
=0
DN3: MEM_AR,ARX_ARX-1, ;NOT END, LOOP
SR_BLT(SRC),J/DOWN
FIN STORE,I FETCH,J/NOP ;END
.ENDIF/BACK.BLT
.TOC "STORING OF JPC"
.IF/JPC SUPPORT
AOBJPC: ;HERE TO STORE JPC FOR AOBJN/AOBJP
SOJJPC: ;HERE FOR SOJ SERIES
AOJJPC: ;HERE FOR AOJ SERIES
AC0_AR,B DISP
=*1*000 ;HERE FOR JUMP SERIES
JMPJPC: GEN AR-1,SKP AR0,SIGNS DISP,J/JPCP ;LE
SKP AR NE,J/NJPCP ;E
SKP AR0,J/JPCP ;L
J/FINI ;-
GEN AR-1,SKP AR0,SIGNS DISP,J/NJPCP ;G
SKP AR NE,J/JPCP ;N
SKP AR0,J/NJPCP ;GE
AR_PC,SC_#,#/32.,SKP USER,J/JPCEX ;A
=*1*110
JPCP: NXT INSTR ;NOT JUMPING
JPCIFY: AR_PC,SC_#,#/32.,SKP USER,J/JPCEX ;JUMPING
;THIS IS LIKE STORAC, EXCEPT IT STORES THE JPC ALSO.
;CALLED WITH SKP USER, BECAUSE WRITING IN FM USES THE COND
;FIELD, WHICH MEANS JPCSTO CAN'T DO THE SKP USER ITSELF.
=0
JPCSTO: AC0_AR,AR_PC,SC_#,#/32.,J/JPCEX
AC0_AR,AR_PC,SC_#,#/32.,J/JPCUSR
.IFNOT/JPC.RING
=*1***0
JPCEX: XJPC_AR,NXT INSTR AFTER JPC
JPCUSR: JPC_AR,NXT INSTR AFTER JPC
.IF/JPC.RING
;COME HERE WITH: SKP USER,SC_#,#/32.
=*1***0
JPCEX: AR_XJPC+1,J/JPCEX1
JPCUSR: AR_JPC+1
JPC_AR,SH DISP,AR_PC
=*10000
JPC0_AR,NXT INSTR AFTER JPC
JPC1_AR,NXT INSTR AFTER JPC
JPC2_AR,NXT INSTR AFTER JPC
JPC3_AR,NXT INSTR AFTER JPC
JPC4_AR,NXT INSTR AFTER JPC
JPC5_AR,NXT INSTR AFTER JPC
JPC6_AR,NXT INSTR AFTER JPC
JPC7_AR,NXT INSTR AFTER JPC
JPC10_AR,NXT INSTR AFTER JPC
JPC11_AR,NXT INSTR AFTER JPC
JPC12_AR,NXT INSTR AFTER JPC
JPC13_AR,NXT INSTR AFTER JPC
JPC14_AR,NXT INSTR AFTER JPC
JPC15_AR,NXT INSTR AFTER JPC
JPC16_AR,NXT INSTR AFTER JPC
JPC17_AR,NXT INSTR AFTER JPC
JPCEX1: XJPC_AR,SH DISP,AR_PC
=*10000
XJPC0_AR,NXT INSTR AFTER JPC
XJPC1_AR,NXT INSTR AFTER JPC
XJPC2_AR,NXT INSTR AFTER JPC
XJPC3_AR,NXT INSTR AFTER JPC
XJPC4_AR,NXT INSTR AFTER JPC
XJPC5_AR,NXT INSTR AFTER JPC
XJPC6_AR,NXT INSTR AFTER JPC
XJPC7_AR,NXT INSTR AFTER JPC
XJPC10_AR,NXT INSTR AFTER JPC
XJPC11_AR,NXT INSTR AFTER JPC
XJPC12_AR,NXT INSTR AFTER JPC
XJPC13_AR,NXT INSTR AFTER JPC
XJPC14_AR,NXT INSTR AFTER JPC
XJPC15_AR,NXT INSTR AFTER JPC
XJPC16_AR,NXT INSTR AFTER JPC
XJPC17_AR,NXT INSTR AFTER JPC
.ENDIF/JPC.RING
.ENDIF/JPC SUPPORT

226
src/ucode/byte.7 Executable file
View File

@@ -0,0 +1,226 @@
.TOC "BYTE GROUP -- IBP, ILDB, LDB, IDPB, DPB"
.DCODE
;133: R, J/IBP ;OR ADJBP
134: RW, J/ILDB ;CAN'T USE RPW BECAUSE OF FPD
R, J/LDB
RW, J/IDPB
R, J/DPB
.UCODE
;ALL FIVE INSTRUCTIONS OF THIS GROUP ARE CALLED WITH THE BYTE POINTER
;IN THE AR. ALL INSTRUCTIONS SHARE COMMON SUBROUTINES, SO THAT
;THE 10/11 INTERFACE AND STRING MAY ALSO USE THESE SUBROUTINES
;IBP OR ADJBP
;IBP IF AC#0, ADJBP OTHERWISE
; HERE WITH THE BASE POINTER IN AR
;IBP: SKP AC#0 ;IS THIS IBP OR ADJBP?
.IF/ADJBP
=1**000
IBP1: T0_AR,BR/AR, ;SAVE POINTER FOR ADJBP
SC_S,AR_0S,CALL,J/GETSC ; GET BYTE SIZE
.ENDIF/ADJBP
=001
IBP2: BR/AR,P_P-S,CALL.M, ;NEW P UNLESS OVERFLOW
SKP SCAD0,J/IBPS
.IF/ADJBP
BR/AR,AR_BR,J/ADJBP ;HOLD S IN BR AND MQ
.ENDIF/ADJBP
=101 FIN STORE,I FETCH,J/NOP ;IBP DONE
=
=00*000
ILDB: BR/AR,P_P-S,BYTE DISP, ;START IBP
CALL.M,J/IBPS ;AND CALL SUBR
=100
LDB: ARX_AR,SC_P,CALL,J/BYTEA ;BEGIN EA COMPUTATION
SC_FE+SC,CALL,J/LDB1 ;SC_P+S WHILE LOADING AR
=111 AC0_AR,CLR FPD,I FETCH,J/NOP ;DONE
=
=00*000
IDPB: BR/AR,P_P-S,BYTE DISP, ;START IBP
CALL.M,J/IBPS
=100
DPB: ARX_AR,SC_P,CALL,J/BYTEA ;COMPUTE EFFECTIVE BYTE ADDR
AR_AC0,TIME/3T,SC_#-SC,#/36., ;COMPUTE 36-P
CALL,SKP SCAD0,J/DPB1 ;CALL DEPOSITOR
=111
BFIN: FIN STORE,I FETCH ;DONE
=
=*1***0
CLRFPD: CLR FPD,J/FINI ;CAN'T DO THIS UNTIL STORE COMPLETE
J/FINI ;HERE FROM BLKO/BLKI PI
=
.TOC "INCREMENT BYTE POINTER SUBROUTINE"
;THIS SUBROUTINE IS CALLED BY THE INSTRUCTIONS ILDB, IDPB AS
;WELL AS THE MICROCODED 10/11 INTERFACE HANDLER.
;CALL WITH BYTE DISP TESTING FPD AND SIGN OF P-S
;[TIME=2+2(BP OVFLO)]
=1**010 ;BR12 IRELEVANT
IBPS: STORE,RETURN4 ;SIMPLE, NO OVERFLOW
FE_#,#/36.,GEN AR+1,TIME/2T, ;HERE IF OVRFLO OF WORD
ARX_AR,J/NXTWRD
AR_BR,RETURN4 ;FPD WAS SET, RESTORE AR
AR_BR,RETURN4 ; AND CONVERT TO LDB OR DPB
= ;TEST BR12 ONLY
NXTWRD: AR_AR+1,P_FE-S,STORE,
TIME/2T,RETURN4
.TOC "BYTE EFFECTIVE ADDRESS EVALUATOR"
;ENTER WITH POINTER IN AR, ARX, AND BR
;RETURN1 WITH (EA) LOADING INTO AR AND ARX,
;FPD SET, P IN SC, AND S IN FE
;[TIME=4+1(INDEXED)+?(INDIRECT)]
BYTEA: MEM_AR,FE_S,SET FPD, ;PUT AWAY UPDATED POINTER
EA MOD DISP ;EVAL BP ADDR
=11**00
BFETCH: VMA_ARX,BYTE READ,RETURN1 ;START DATA FETCH
VMA_ARX+XR,BYTE READ,RETURN1 ;ADDRESS IS INDEXED
GEN ARX,BYTE INDRCT,J/BYTEI ;DO INDIRECT
GEN ARX+XR,BYTE INDRCT,J/BYTEI ;INDIRECT INDEXED!!!
BYTEI: ARX_MEM,SKP INTRPT ;WAIT FOR INDIRECT WORD
=0 EA MOD DISP,J/BFETCH ;PROCEED IN ADDR EVAL
SR DISP,J/CLEAN ;INTERRUPTED, CLEAN UP AS REQ'D
.TOC "LOAD BYTE SUBROUTINE"
;ENTER WITH S IN FE, P+S IN SC, AND AR LOAD IN PROGRESS
;SKP INTERRUPT AT ENTRY IS OPTIONAL
;RETURN2 WITH BYTE RIGHT JUSTIFIED IN AR
;[TIME=7]
=1****0
LDB1: AR_MEM,SC_#-SC,#/36.,SKP SCAD0, ;36-(P+S)
TIME/3T,J/LDB2
AR_MEM,SR DISP,J/CLEAN ;HERE IF INTERRUPT PENDING
=
=*1***0
LDB2: ARX_SHIFT,AR_0S,SC_FE,J/SHIFT ;BYTE IN ARX HI, READY TO SHIFT
ARX_AR,AR_0S, ;P+S > 36, PUT BYTE IN ARX HI
SC_FE+SC,SKP SCAD0 ;ADJUST S AND SHIFT BYTE
;PUT BYTE INTO AR RIGHT-JUSTIFIED
; THIS INSTRUCTION ALSO CALLED ALONE AS A SUBROUTINE
=1****0
SHIFT: AR_SHIFT,RETURN2 ;RETURN WITH BYTE IN AR
RETURN2 ;BYTE WAS OFF THE END, RETURN AR=0
.TOC "DEPOSIT BYTE SUBROUTINE"
;ENTER WITH BYTE RIGHT JUSTIFIED IN AR, POINTER IN BR,
; S IN FE, 36-P IN SC, AND LOAD AR-ARX STARTED
; SKP IF P>36
;RETURN3 WITH FINAL STORE IN PROGRESS
;[TIME=11]
=1****0
DPB1: MQ_AR,AR_MEM,ARX_MEM, ;GET WORD TO ROTATE 36-P
GEN FE-SC,TIME/3T, ;COMPUTE S-(36-P)
SKP SCAD0,J/DPB2 ;CHECK THAT P+S<36
MB WAIT,RETURN3 ;P>36, STORE NOTHING
=*1***0
DPB2: FE_SC ;P+S>36, S_36-P
ARX_SHIFT,AR_MQ,SC_FE, ;ARX HAS P,X,S
FE_#-SC,#/72. ;SC_S, FE_72-(36-P)=36+P
SC_#-SC,#/36. ;SC_36-S (KNOWN .LE. P)
AR_SHIFT,ARX_SHIFT, ;S,P,X
SC_FE-SC ;SC_(36+P)-(36-S)=P+S
AR_SHIFT,STORE,RETURN3 ;DONE, STORE IT BACK
.TOC "ADJBP"
;HERE FOR ADJUST BYTE POINTER (IBP WITH NON-ZERO AC)
; BYTE SIZE (S) IS RIGHT ADJUSTED IN BR AND MQ
; FULL POINTER IS IN AR, AND SAVED IN T0
.IF/ADJBP
ADJBP: SC_P,AR+ARX+MQ_0.M, ;GET P
SKP BR EQ ;CHECK SIZE IS NON-ZERO
=1***00
BRX/ARX,P_SC,CALL.M,J/SIXDIV ;DIVIDE P BY S
AR_T0,J/IFSTAC ;OOPS, S=0, RETURN UNALTERED POINTER
T1_AR,AR_0S,ARX_0S, ;SAVE P/S
SC_FE-SC ;36-P IN SC
=
=*1**0*
P_SC,MQ_0.M,CALL.M,J/SIXDIV ;36-P IN AR0-5
AR_AR+T1,SKP AD NE ;(P/S)+(36-P/S)=BYTES/WORD
=*1***0
I FETCH,J/NODIVD ;ABORT, BYTES/WORD=0
T1_AR,BR/AR,AR_ARX ;SAVE BYTES/WORD, READY TO
; DIVIDE BY IT
T2_AR,AR_MQ ;SAVE REMAIN(36-P/S), GET (36-P)/S
AR_AR*AC0,AD/A+B,ARL/AD, ;ADJUSTMENT IN AR
ARX+MQ_0.M
;COMPUTE QUOTIENT Q AND REMAINDER R OF ADJUSTMENT/(BYTES/WORD)
; SUCH THAT ADJUSTMENT=Q*(BYTES/WORD)+R, 1 .LE. R .LE. (BYTES/WORD)
; SINCE ADJUSTMENT IS CALCULATED RELATIVE TO LEFT-MOST BYTE OF
; A WORD, THIS GIVES Q AS THE NUMBER OF WORDS BY WHICH TO INDEX THE
; BYTE POINTER, AND R AS THE NUMBER OF BYTES FROM THE LEFT OF THE
; WORD. MULTIPLYING R BY THE BYTE SIZE WILL GIVE THE NUMBER OF BITS
; FROM THE LEFTMOST BYTE, AND ADDING REMAIN(36-P/S) WILL GIVE NUMBER
; OF BITS FROM BIT 0. FINALLY, WE MUST SUBTRACT THIS FROM 36 TO GET
; THE CORRECT P FIELD, WHICH IS ALWAYS RELATIVE TO THE RIGHT EDGE OF
; THE WORD.
=*1*100
AC0_AR,SC_1,CALL,J/DIV2 ;DO THE BASIC DIVIDE
=110 ARX_-BRX,FE_#,#/-4,J/ADJD1 ;NEG QUO ==> NEG REMAIN
ARX/MQ,SKP AR NE,FE_#,#/-4 ;POS QUO. IS REMAIN .GT. 0?
=1****0
ADJD1: AR_AR+T1,J/ADJD2 ;INCREASE REMAIN TO MEET CONSTRAINT
BR/AR,AR_ARX (ADX), ;REMAIN IN RANGE,
ARL+ARX_0.M,J/ADJD3 ; QUOTIENT TO ARR
ADJD2: BR/AR,AR_ARX-1, ;HOLD UPDATED REMAINDER,
ARL+ARX_0.M ; GET CORRESPONDING QUOTIENT
ADJD3: AR_AR+T0,INH CRY18, ;ADD Q TO Y OF POINTER,
BRX/ARX ;CLR BRX
=1**00*
AC0_AR,AR_0S,SC_S,CALL,J/GETSC ;SAVE UPDATED Y, GET SIZE
MQ_AR,AR_T2,CLR ARX, ;M'IER IS S, GET REMAIN(36-P/S)
CALL,J/MULREE ;COMPUTE (R*S)+REMAIN(36-P/S)
=11* AR_ARX*2,I FETCH ;PUT THAT IN AR0-5
SC_P-#,#/36.,AR_AC0
P_-SC,J/STAC ;THAT'S NEW P, DONE
.ENDIF/ADJBP
;SUBROUTINE TO GET CONTENTS OF SC RIGHT ALIGNED IN AR
;[TIME=6]
GETSC: AR0-8_SC ;PUT SC INTO AR
GETEXP: ARX_AR,SC_#,#/9.,J/SHIFT ;HERE WITH DATA IN AR0-8
;SUBROUTINE FOR SHORT DIVISION, BR KNOWN POSITIVE
; CALL WITH MQ CLEAR, DIVISOR RIGHT-ALIGNED IN BR, AND DIVIDEND
; IN AR0-5 (OR LEFT-ALIGNED IN ARX IF ENTERING AT SDIV)
; RETURN QUOTIENT IN AR AND MQ, REMAIN IN ARX
;[TIME=22+3(RESTORE REQ'D)]
;TO IMPROVE ADJBP PERFORMANCE, INSERT THE INSTRUCTION SHOWN BELOW
; (SIXDZ), AND CHANGE THE CALLS TO SIXDIV TO "SKP SCAD NE,J/SIXDZ"
;=0
;SIXDZ: AR_0S,ARX_0S,FE_#,#/36.,RETURN2 ;HERE IF DIVIDEND IS ZERO
SIXDIV: ARX_AR,AR_0S,FE_#,#/4,J/SDIV-
=*1*0*0
SDIV: DIVIDE,AR_2(AR+BR),ARX/ADX*2,J/SDIV
SDIV-: DIVIDE,AR_2(AR-BR),ARX/ADX*2,J/SDIV
DIVIDE,AR_AR+BR,J/SDIVR ;NO SHIFT ON FINAL STEP
DIVIDE,AR_AR-BR
=1**1*0
SDIVR: AR_AR+BR ;NO CRY0 MEANS RESTORE REQ'D
ARX_AR,AR_MQ, ;RETURN QUO IN AR, REMAIN IN ARX
FE_#,#/36.,RETURN2

1463
src/ucode/define.32 Executable file

File diff suppressed because it is too large Load Diff

642
src/ucode/eis.6 Executable file
View File

@@ -0,0 +1,642 @@
.IF/EIS
îñKªO‡ "EXTø³¢E‰ INSTúUaÔ“ùó<C3B9>Súˆ"E‡ODING"
;GET HERE WITH E0 IN BR, (E0) IN AR
; (ø¬ “S THEôèE¥ATION WORD, AND HAS THE NORMAL -10 ù3©Ô¥UCTION
; FORMAúˆ­ABITS 0-8 ARE OPCODE, 9-12 IGNOúQb,A13 @, 14-17 XR,ñ¢<C3B1>‰ƒND 18-35 Y. THE AC USED øsæÅ§ FROM THE ø¶*E<>D INSú”ªÃ©ION.îñNÐCŸù´*Ô‹ôX <58>úSæ cökYµ
;Eû"Ή:FE_#õpi0[÷ ¯[20,SKP SCAD0, ;ør"× LEGAL OPERATION
; ARX_AR,AR_BRX ;OPRô' ƒRX, GøµA‡ FROMô©XñOX
EXT1: AR_BR,J/UUO ;OPCODE > 17
AR0-8_FE+#,#/20 ;PLUG OPR INú“ÐE±úgDAAC
øñg ƒR,LOAøˆ$ÒYAR_ARX,ARL_0.M,
EA MOD DISP
=00
EXTöN„Åc_AR,AR_BR,ùKâØ©5 ;SAVE E1, REø1, ©O SAVE E0
ARLûìMYAR_ARX+XR,J/EXTöCE <09>EN ARû  “NDRCT,SKP INTRPT,J/EXT3
GEN ARX+XR,A INDRCT,
SKP INTRPT,J/EXT3
=0
EXT3: AR_MEM,ARX_ù±f¬•õñlTiñ¢„Á¥_MEM,TAKE INTRPúƒEE±T4: ARL_0.M,EA MOD Dù4è,•/EXT2
EXT5: ø¬/Á¥,VMA_AR+1,IR DIútJ_2000 ;ENTER EXTENDED INSTúH$A<>DLER
;THE EXúgDD INSTRUCTù3ç §øµI§ "HIDøg"AUNDER THE LUUO'S BY THIS
; USE OF ôRi ‰ù4è,•/2000" TO øiЃTCH Tùè*HM. TùPL«UO'S úò$Ñ
; Hø5¢ ©HE SAME OPCODESôi XTENDED OPERATIONS AúQPA§úrcÎD UNIQUE
; CRAù¨&O‡ATIONS IN ú’" ¥ø3£ÅAö,0Aú“Ð1a17. WHEN WE SPECIFY J/2000,
; THEôéA ADDRESS Bø°çÍúh°aö*OAöl·Y WHICH ACCESSES CRAM LOCATIONS
; 2ö  ©ùè0cöè!E‡AUSE ADDRESS BITS 01 AND 02 ARE IGNùô¢ÄAWHEN BIT 00
; ù4ÐT¥UE (CRA, CRM).
2005: AR_AC3,J/CMúĉ;HIDDø³<C3B8>BHIND ùaͧ
200ö΄ÙR AR,ARX_1S,SC_ôk¯c5.,J/EDIT ;HIDDø³<C3B8>BùgDAL-EDIT
.IF/DECIMAL
2010: AR_AC0 COMP,J/DBIN ;HIDDEN BEHIND L-DBIN
2011: AR_AC1,ARL/AD,SC_1,ARX+MQ_0.M,
BYTE DISP,J/BDEC ;HIDDEN BEHIND L-BDEC
.ENDIF/DECIMAL
2012: AR_AC3,LOAD AR,J/MVST ;HIDDEN BEHIND L-MVS
.TOC "EIS -- STRING MOVE"
; HERE WITH AC3 (DEST LEN) IN AR
;SLEN IS THE COMPLEMENT OF THE SHORTER STRING LENGTH
;DLEN IS <SRC LEN>-<DST LEN>
MVST: BR/AR,AR_MEM, ;HOLD AC3, WAIT FOR FILLER
FE_AR0-8,SKP SCAD NE ;CHECK FOR FLAGS IN DEST LEN
=0 ARX_AC0,J/MVST1 ;GET SRC LEN, FLAGS
AR_E0,J/UUO ;NO FLAGS ALLOWED IN DST LEN
MVST1: FILL_AR,AR_ARX ;SAVE FILL CHAR
FE_AR0-8,AR0-8_#,#/0 ;SEPARATE FLAGS OFF
ARX_AR,AR_AR-BR,SKP AD0 ;COMPUTE SRC-DST LEN
=0 DLEN_AR,AR_BR COMP,J/MVST2 ;SRC LONGER
DLEN_AR,AR_ARX COMP ;DST LONGER
MVST2: SLEN_AR,ARX_AR,MQ_AR,AR_0S ;-SHORT LEN -1 TO MQ
AR0-8_FE,BRX/ARX ; AND BRX
SFLGS_AR,B DISP
=100 CLR AR,ARX_1S,SC_#,#/15.,J/MOVS2;TRANSLATE, BUILD MASK
AR_E1,J/MVSO1 ;OFFSET, SIGN EXTEND E1
ARX_BRX+1,AR/ADX,SR_SRC,J/MOVST1 ;LEFT JUSTIFY
AR_DLEN,SKP AD0,J/MOVRJ ;RIGHT JUSTIFY
MVSO1: ARX_DSTP,SKP AR18,ARL_0.M ;CHECK SIGN FOR EXTENDING
=0
MVSO2: E1_AR,AR_ARX,J/MVSO3 ;SAVE AGAIN, GET POINTER
ARL_1S,J/MVSO2 ;NEG, MAKE MINUS
MVSO3: SC_S,CLR ARX,AR_1S ;PREPARE TO BUILD MASK
MOVS2: AR_SHIFT,SR_SRC
MSK_AR
=000
MOVELP: AR_SLEN+1,CALL,J/SRCMOD ;PICK UP SOURCE BYTE
AR_DLEN,J/MOVSTX ;(1) LENGTH EXHAUSTED
=100
MOVPUT: SR_SRC+DST,CALL,J/PUTDST ;(4) NORMAL, STORE DST BYTE
I FETCH,AR_DLEN,J/MVABT ;(5) ABORT
=110 SR_SRC,J/MOVELP ;(6) DPB DONE
=
;HERE TO ABORT A STRING MOVE DUE TO TRANSLATE OR OFFSET FAILURE
MVABT: BR/AR,AR_-SLEN,SKP AR0 ;WHICH STRING LONGER?
=0
MVABT1: AC3_AR,FETCH WAIT,J/MVABT2 ;PUT AWAY DEST LEN
AR_AR-BR,J/MVABT1 ;DEST LEN WAS GREATER
MVABT2: AR_SLEN COMP,SKP BR0 ;GET UNDECREMENTED SLEN
=0 AR_AR+BR ;SRC LONGER BY (DLEN)
MVEND: AR_AR*SFLGS,AD/OR,SR_0,J/STAC ;PUT BACK REMAINING LENGTH
;HERE TO BEGIN RIGHT-JUSTIFIED MOVE
=00
MOVRJ: ARX_AR,AR_SRCP,SR_SRC,J/MVSKP ;SRC LONGER, SKIP OVER SOME
SR_DSTF,CALL,J/MOVF1 ;DST LONGER, FILL IT
=11 ARX_BRX+1,AR/ADX,SR_SRC,J/MOVST1 ;DONE FILLING
=0
MVSKP: ARX_ARX-1 (AD),FE_#,#/36.,
SIGNS DISP,SKP INTRPT,J/MVSK1
P_FE-S,AR_AR+1,J/MVSKP
=110
MVSK1: P_P-S,SKP SCAD0,J/MVSKP ;BUMP POINTER
SRCP_AR,GEN ARX,SIGNS DISP,AR_0.M
=110 BRX/ARX,AR_SLEN COMP,ARX/AD,J/MVSK3 ;INTERRUPTED
DLEN_AR,J/MVSK4 ;DONE FILLING
MVSK3: AC3_AR,AR_ARX*BRX,AD/A+B+1 ;DEST HAS SHORT LEN
SR_0,J/STRPF2 ;FIX UP AC0, SERVE INTRPT
;HERE FOR NO-MODIFICATION STRING MOVES
=000
MOVST1: SLEN_AR,BRX/ARX, ;PUT UPDATED LEN AWAY
AR+ARX+MQ_0.M,CALL.M,
SIGNS DISP,J/GSRC
MOVSTX: SKP AR0,ARX_AR,AR_0S,J/MOVST2 ;SHORT LEN EXHAUSTED
=010 SR_SRC+DST,CALL,J/PUTDST
=110
MVSK4: ARX_BRX+1,AR/ADX,SR_SRC,J/MOVST1
=
=00
MOVST2: TEST ARX,TEST FETCH, ;SKIP IF BOTH LENGTHS =0
AC3_AR,AR_ARX,J/MVEND ;CLEAR DEST LEN, REBUILD SRC
SR_DST,CALL,J/MOVF1 ;SOURCE GONE, FILL OUT DST
=11 AR_SFLGS,VMA_PC+1,J/SFET1 ;DONE FILLING
;NOTE -- IT AIN'T AS EASY AS IT LOOKS TO BUM A CYCLE OUT OF THIS
; ROUTINE, BECAUSE AN INTERRUPT, IF ANY, HAS TO BE TAKEN AFTER THE
; POINTER UPDATE AND BEFORE THE LENGTH UPDATE. GOOD HUNTING!
=01*
MOVF1: AR_FILL,CALL,J/PUTDST
AR_DLEN+1,SKP INTRPT,J/MOVF2
=0
MOVF2: DLEN_AR,SIGNS DISP,J/MOVF3 ;DONE?
SR DISP,J/CLEAN ;BREAK OUT FOR INTERRUPT
=011
MOVF3: RETURN2 ;YES, DONE
J/MOVF1 ;NO, DO ANOTHER
.TOC "EIS -- STRING COMPARE"
;HERE WITH AC3 (DEST LENGTH) IN AR
CMPS: BR/AR,ARX_AR,FE_AR0-8,AR_AC0 ;DEST LEN TO BR, GET SRC LEN
FE_FE OR AR0-8, ;GATHER HIGH BITS OF LEN'S
SKP AR GT BR ;WHICH STRING LONGER?
=0
CMPS1: LOAD AR,AR_ARX-1,ARX_AR-1, ;SRC SHORTER
GEN FE,SKP SCAD NE,J/CMPS2 ;CHECK LEN'S PURE
VMA_VMA+1,J/CMPS1 ;SRC LONGER, GET DST FILLER
=0
CMPS2: AR_MEM,BR/AR,BRX/ARX,J/CMPS4 ;DECREMENTED LEN'S TO BR'S
MB WAIT,AR_E0,J/UUO ;OOPS, ILLEGAL BITS IN LEN'S
;HERE IS THE COMPARE LOOP.
; MQ CONTAINS THE FILL CHARACTER FOR THE SHORTER STRING,
; BR CONTAINS THE REMAINING DESTINATION LENGTH,
; BRX CONTAINS THE REMAINING SOURCE LENGTH
=0
CMPS3: ARX0_MQ35,J/CMPSX ;WE GOT INEQUALITY. GET SIGN
CMPS4: MQ_AR,ARX_AR,FE_#,#/36., ;FILL TO MQ & ARX
AR_BR,SKP ARX0 ;MORE CHARS IN SRC STRING?
=000 AR_SRCP,ARX_SRCP, ;READY WITH SRC POINTER
SR_ED(S),CALL,J/GSRC1 ;GO GET SRC BYTE
AR_ARX,ARX_0S,SR_0,SIGNS DISP ;SRC DONE. TEST DEST LEN
=010 T0_AR,AR_MQ,SIGNS DISP,J/CMPS5 ;SRC (OR SRC FILL) TO T0,
=110 ;TEST FOR END OF DEST STRING
CMPSX: GEN ARX,CMS FETCH,J/NOP ;QUIT WITH COMPARE COND IN ARX
=
;HERE TO GET DESTINATION BYTE. SRC IS IN T0, FILL CHAR IN AR
;HERE WITH SIGNS DISP, TO AVOID CALL ON CMPDST IF DST LEN EXHAUSTED
=101
CMPS5: SR_ED(+D),CALL,J/CMPDST ;GO FOR DESTINATION BYTE
AR_AR*T0,AD/XOR, ;AR ZERO IF EQUAL
ARX/MQ,MQ_MQ*2 ;FILL TO ARX, CRY TO MQ35
BR/AR,BRX/ARX, ;EQUALITY TO BR, FILL TO BRX
AR_BR,ARX_BRX,SKP BR0 ;LENGTHS TO AR, ARX
=0 AC3_AR,ARX_AR,AR_ARX (AD), ;UPDATE DEST LEN IN AC3
SIGNS DISP,J/CMPS6 ;TEST SRC LEN
ARX_AR,AR_ARX (AD) ;DEST LEN EXHAUSTED
=110
CMPS6: AC0_AR,AR_ARX-1,ARX_AR-1,J/CMPS7 ;UPDATE SRC LEN IN AC0
AR_ARX-1,ARX_AR-1 ;SRC EXHAUSTED PREVIOUSLY
CMPS7: BR/AR,BRX/ARX, ;LENGTHS TO BR'S
SKP BR EQ,AR/ADX,J/CMPS3 ;CHECK FOR EQUALITY
=0
CMPDST: AR_DSTP,ARX_DSTP,FE_#,#/36., ;GET DEST BYTE FOR COMPARE
CALL,J/IDST ;UPDATE DEST POINTER
SC_FE+SC,SKP INTRPT,J/LDB1 ;GET DEST BYTE
.TOC "EIS -- DECIMAL TO BINARY CONVERSION"
; HERE WITH AC0 (SRC LEN) IN AR COMPLEMENTED
; IN THE LOOP, AC3 CONTAINS 10 (DECIMAL), BR'BRX HAS ACCUMULATED BINARY
.IF/DECIMAL
DBIN: BR/AR,FE_AR0-8 COMP,AR0-8_#,#/-1 ;FORCE OUT FLAGS
SLEN_AR,AR_0S,SIGNS DISP
=101 AR0-8_FE,MQ_0.S,ARX_AC4,J/DBS1 ;BUILD SFLGS
B DISP ;OFFSET OR TRANSLATE?
=110 AR0-8_FE,J/DBST ;TRANSLATE, LET S FLAG SET LATER
AR0-8_FE OR #,#/400 ;OFFSET, SET S FLAG
DBST: SFLGS_AR,AR_0S,ARX_0S,J/DBS2 ;CLEAR BINARY
DBS1: SFLGS_AR,ARX_ARX*2 ;HERE WHEN SIG ALREADY ON
AR_AC3 ;ACCUMULATED BINARY IN AR
DBS2: BR_AR LONG,AR_1,CLR ARX
AR_AR*10,B DISP,SC_#,#/4 ;GET CONSTANT 10 FOR COMPARE
=110 AC3_AR,AR_ARX,ARX_1S,J/DBS3 ;PREPARE TO BUILD MASK
AC3_AR ;OFFSET
AR_E1 ;GET OFFSET
ARL_1S.M,SKP AR18 ;SIGN EXTEND IT
=0 ARL_0S ;OOPS, TWAS POS
E1_AR,AR_1S ;NOW READY TO BUILD MASK
DBS3: AR_SHIFT,SR_DB
MSK_AR,AR_BR LONG ;SAVE MASK, GET INITIAL INPUT
=0*0
DBINLP: BR_AR LONG,AR_SLEN+1, ;BINARY BACK TO BR, COUNT LENGTH
CALL,J/SRCMOD ;PICK UP A DIGIT
SKP AR2,VMA_PC+1,J/DBXIT ;(1) DONE, TEST M FLAG
ARX_AR,AR+MQ_0.M,GEN AR-AC3, ;(4) NORMAL, ADD IN DIGIT
SKP CRY0,J/DBIN2 ;TEST FOR DIGIT >9
AR_SLEN COMP,J/DBABT ;(5) ABORT
;HERE TO ADD IN A DIGIT
=0
DBIN2: BR_AR LONG,AR_BR LONG,J/DBIN3 ;DIGIT TO BR LONG, BINARY TO AR LONG
AR_SLEN COMP,J/DBABT ;DIGIT >9, ABORT
DBIN3: AR_AR*5 LONG ;ALREADY HAVE BINARY *2
AR_2(AR+BR) LONG,J/DBINLP ;ADD IN DIGIT, SHIFT LEFT
;HERE ON ABORT
DBABT: AR_AR*SFLGS,AD/OR ;COMBINE FLAGS WITH +LEN REMAINING
AC0_AR,AR_BR LONG,SC_#,#/35., ;PUT BACK UNUSED LENGTH
VMA_PC+1,J/STOR34 ;END WITH NO SKIP
;HERE AT END
=0
DBXIT: AR_BR LONG,VMA_VMA+1, ; M FLAG=0
SC_#,#/35.,J/STOR34 ;GO FOR NEXT INSTR
AR_-BR LONG,VMA_VMA+1, ;NEGATE
SC_#,#/35.
STOR34: AC3_AR,AR_SIGN,FETCH ;STORE HIGH PART
AR_SHIFT,SR_0 ;GET LOW READY
STAC4: AC4_AR,FINISH
.TOC "EIS -- BINARY TO DECIMAL CONVERSION"
; AC0,AC1 = BINARY INTEGER INPUT
; AC3 = FLAGS, MAX LENGTH OF DECIMAL STRING
; AC4 = DESTINATION STRING POINTER
; TEMPS ARE USED AS FOLLOWS:
; SLEN= # OF SIGNIFICANT DIGITS
; T1,2= 10.**(SLEN) THE LOWEST POWER OF TEN LARGER THAN BINARY
;FPD IS SET IF THE INSTRUCTION WAS INTERRUPTED AFTER
; CONVERSION OF THE BINARY INTEGER TO FRACTION FORM.
; (AND THUS BY IMPLICATION, AFTER STORING FILLERS)
=011
BDEC: ARX_SHIFT,AR_AC0,SKP AD0, ;BINARY INTEGER NOW IN AR LONG
SC_#,#/20,J/BD1 ;IS IT NEGATIVE?
ARX_AR,AR_E1,B DISP ;CONT FROM INTRPT OR PGF
=0
BDDR1: AR_AC3,SR_BDT,J/BDDR3 ;RESUME WITH FRACTION IN AR LONG
SKP AR18,ARL_0.M ;OFFSET MODE. EXTEND E1
=0
BDDR2: E1_AR,J/BDDR1 ;GET REST OF FRACTION
ARL_1S,J/BDDR2 ;E1 NEGATIVE
BDDR3: BR/AR,CLR EXP, ;SEPARATE FLAGS & LENGTH
BRX/ARX,ARX_AC0 ;LOW FRAC TO BRX, HI TO ARX
AR_AR*BR,AD/ANDCA,BR/AR ;JUST FLAGS TO AR, JUST LEN TO BR
AC3_AR,AR_ARX ;GET HI FRAC TO AR
BR/AR,VMA_PC+1, ;FRAC TO BR LONG, GET VMA READY
AR_-BR,SKP CRY0,J/BDDR4 ;CHECK FOR MORE TO GO
=0
BD1: SKP AR NE,AD LONG,J/BD2 ;TEST FOR ZERO LONG
AR_-AR LONG,SC_#,#/30,J/BD3 ;MAKE POSITIVE, SET N&M FLAGS
=00
BD2: BR_AR LONG,AR_1 LONG, ;BINARY RIGHT-ALIGNED IN BR,
SC_#,FE_#,#/20.,J/BD4 ;LOOK FOR LARGER POWER OF TEN
BD3: BR_AR LONG,AR_AC3, ;SAVE POS BINARY, GET AC FLAGS
CALL,J/SETFLG ; SET FLAGS AS NEEDED
=11 AC3_AR,AR_BR*.5 LONG,J/BD2 ;SAVE NEW FLAGS, SHIFT BINARY RIGHT
;HERE TO FIND THE SMALLEST POWER OF TEN LARGER THAN THE BINARY INTEGER.
;BINARY IS IN BR LONG, AND POSITIVE UNLESS IT WAS 1B0. IN THIS CASE THE
;COMPARISON WILL NEVER FIND A LARGER POWER OF TEN, BUT THE COUNT IN FE
;WILL RUN OUT, AND WE WILL CORRECTLY COMPUTE 22 DIGITS REQUIRED.
=010 ;IGNORE BR SIGN
BD4: AR_AR*10 LONG,FE_FE-1,J/BD6 ;THIS POWER IS TOO SMALL
SC_FE-SC-1,T1_AR,AR_ARX,J/BD7 ;THIS POWER IS BIG ENOUGH
FE_FE-1 ;10.**21 IS TOO SMALL, USE 22
SC_FE-SC-1,T1_AR,AR_ARX,J/BD7 ;10.**21 IS BIG ENOUGH
BD6: GEN AR-BR-1,DISP/DIV,J/BD4 ;COMPARE BINARY TO 10**N
;HERE HAVING FOUND THE NUMBER OF DIGITS REQUIRED TO REPRESENT THE
; GIVEN INTEGER. THE ONE'S COMPLEMENT OF THE NUMBER OF DIGITS IS NOW
; IN SC, AND T1/T2 IS GETTING A POWER OF TEN LARGER THAN THE INPUT.
=0*
BD7: T2_AR,AR_1S,CALL,J/GETSC ;SAVE (10**N), GET -# OF DIGITS
SLEN_AR,ARX_AR*4 COMP ;-# OF SIGNIFICANT DIGITS-1
AR_AC3 ;GET FLAGS, LENGTH
FE_AR0-8,AR0-8_#,#/0 ;LEN IN AR, FLAGS IN FE
AR_ARX*.25-AR-1,SKP CRY0, ;-# OF FILL CHARS -1
SC_FE-#,#/400 ;SC0 SET IF S FLAG =0
=0 ARX_AR+1,AR_0.M,J/BD8 ;ENOUGH SPACE. -FILL CNT TO ARX
I FETCH,J/NOP ;OVERFLOW
BD8: AR0-8_FE.M,SKP SC0, ;FLAGS TO AR. S FLAG =0?
GEN ARX COMP,SIGNS DISP ; OR EXACT LENGTH?
=110 T0_AR,LOAD AR,J/BDF1 ;FLAGS TO T0, GET FILLER
BD9: AC3_AR,J/BDDV1 ;NO FILL. FLAGS TO AC3
=00
BDF1: AR_MEM,SR_BDF,CALL,J/RET1 ;GET FILLER, GO WAIT FOR PARITY
FILL_AR,AR_ARX,CALL,J/MOVF2 ;FILL AS REQUIRED
=11 AR_T0,J/BD9 ;GET FLAGS BACK
;SETUP FOR LONG DIVISION OF BINARY BY 10**N
;BR STILL HAS BINARY RIGHT ALIGNED (IE, LOW SIGN SQUEEZED OUT BY
; SHIFTING HIGH WORD RIGHT). BR IS POSITIVE UNLESS INPUT INTEGER WAS
; 1B0, IN WHICH CASE BR IS -1B1. T1,T2 HAS LARGER POWER OF TEN, UNLESS
; BINARY EXCEEDS 10**21, IN WHICH CASE T1,T2 CONTAINS 10**21. SINCE
; BINARY CANNOT BE AS LARGE AS 2 * 10**21, THE FIRST DIVIDE STEP
; IS GUARANTEED TO GENERATE A 1 IN THIS CASE ONLY, AND TO REDUCE THE
; BINARY TO LESS THAN 10**21.
BDDV1: ARX_T2,CLR AR ;FILL DONE. GET 10**N
=110 AR_T1,MQ_AR, ;D'SOR SET IN AR, MQ CLR
SKP BR0,CALL,J/BDDV2 ; CHK D'END SIGN
ARX_AR,AR_AC0,SET FPD,B DISP ;DONE, GET FULL QUO IN AR LONG
=0 AR_AR+1 LONG,SR_BDT,J/BDD1 ;PREVENT 9'S DISEASE
BR_AR LONG,AR_E1 ;OFFSET MODE, MUST SIGN EXT E1
ARL_0.M,SKP AR18
=0
BDE2: E1_AR,AR_BR+1 LONG,J/BDD1 ;UPDATE E1
ARL_1S,J/BDE2 ;MAKE FULL E1 NEG
=000
BDDV2: AR_BR LONG,BR_AR LONG, ;BEGIN LONG DIVISION
SC_#,FE_#,#/34., ;STEP COUNTS FOR BOTH PARTS
CALL,J/DDVSUB
AR_-BR,ARX/ADX,BR_AR LONG, ;HERE IF BINARY WAS 1B0
SC_#,FE_#,#/34., ; IT'S NOW 1B1
CALL,J/DDVSUB
=011 AC0_AR,AR_MQ,ARL/AD,MQ_0.M, ;HALF DONE WITH DIVISION
FE_SC,J/DDVLP ;RESUME WITH ADD STEP
=101 AC0_AR,AR_MQ,ARL/AD,MQ_0.M,
FE_SC,J/DDVSUB ;RESUME WITH SUBTRACT STEP
=
;HERE WITH QUOTIENT OF <INPUT INTEGER>/<10**N> IN AR LONG, WITH THE
; BINARY POINT BETWEEN BITS 0 AND 1 OF AR. THUS, BIT 0 WILL BE SET
; IFF THE INPUT INTEGER WAS GREATER THAN OR EQUAL TO 10**21.
; SINCE THIS IS A TRUNCATED FRACTION, IT IS NOT GREATER THAN THE TRUE
; QUOTIENT, AND THE ERROR IS LESS THAN 2**-71. WE ADD 2**-71, TO
; GUARANTEE THAT OUR FRACTION IS GREATER THAN THE TRUE QUOTIENT,
; WITH AN ERROR NO GREATER THAN 2**-71. WE WILL THEN MULTIPLY THIS
; FRACTION BY 10 N TIMES, REMOVING THE INTEGER PART AT EACH STEP
; TO EXTRACT THE N DIGITS. SINCE N IS AT MOST 21, THIS IS A MULTIPLI-
; CATION BY AT MOST 10**21, SO THE ERROR IS AT MOST (2**-71)*(10**21).
; SINCE THIS IS LESS THAN ONE, THE ERROR DOES NOT INTRUDE INTO THE
; OUTPUT DIGIT STRING.
;HERE IS LOOP TO EXTRACT DIGITS FROM FRACTION IN AC0,AC1
BDD1: BR_AR LONG,VMA_PC+1, ;START NEXT LOOP ITERATION
AR_SLEN+1,SKP CRY0 ;ANY MORE DIGITS?
=0 ;HERE TO RESUME AFTER INTERRUPT
BDDR4: SLEN_AR,MQ_AR,SC_1, ;YES, SAVE LENGTH REMAINING
AR_BR LONG, ; AND GET FRACTION
SIGNS DISP,J/BDD2 ;CHECK FOR 1ST DIGIT OF 10**21
AR_0S,ARX_0S,CLR FPD, ;NO, DONE. CLEAR AC0 & AC1
VMA_VMA+1
AC0_AR,FETCH,J/STRAC1 ;MOVE FETCH WHEN TIMING FIXED
=101 ;LOOK AT BR0 ONLY
BDD2: AR_AR*1.25 LONG,SC_#,#/4 ;NEXT DIGIT TO AR0-3
ARX_AR,AR_0S,SKP INTRPT ;READY TO SHIFT IN DIGIT
=0 AR_SHIFT,B DISP,J/BDD3 ;STORE IT
AR_BR LONG,SR_0,J/B2DPF ;UPDATE REGS & QUIT
;HERE TO STORE DIGIT IN AR FOR BDEC
=0
BDD3: VMA_AR+E1,LOAD AR,J/BDD4 ;TRANSLATE: GET TABLE ENTRY
AR_AR+E1,J/BDD7 ;OFFSET AR AND STORE IT
BDD4: SKP MQ EQ -1,TIME/3T,ARX_0.M ;LAST DIGIT?
=0
BDD5: AR_MEM,J/BDD6 ;NO, STORE RH (POS DIGIT)
ARX_AC3,J/BDD5 ;YES, LOOK AT M FLAG
BDD6: SKP ARX2,ARX_AR SWAP,ARL_0.M
=100
BDD7: SR_BDD,CALL,J/PUTDST
AR_ARX,ARL_0.M,J/BDD7 ;M SET ON LAST DIGIT, USE LH
AR_BR LONG,SR_BDT, ;GET FRACTION BACK
SIGNS DISP ;CHECK BR0 FOR INTEGER PART
=
=101 AR_AR*10 LONG ;DISCARD PREVIOUS DIGIT
P_P AND #,#/37,J/BDD1 ;CLEAR AR0, GO FOR NEXT
.ENDIF/DECIMAL
.TOC "EIS -- SRCMOD SUBROUTINE TO GET MODIFIED SOURCE BYTE"
;SLEN = COMPLEMENT OF LENGTH
;MSK = MASK
;E1 = EFFECTIVE ADDRESS OF OPERATION WORD (SIGN EXTENDED IF OFFSET)
;CALL WITH: AR_SLEN+1,CALL,J/SRCMOD
;RETURNS: 1 LENGTH EXHAUSTED: FLAGS IN AR
; 2 (EDIT ONLY) NO SIGNIFICANCE: FLAGS IN FE
; 3 (EDIT ONLY) SIGNIFICANCE START: BYTE IN AR, FLAGS IN FE
; 4 NORMAL: BYTE IN AR
; 5 ABORT: OUT OF RANGE OR TRANSLATE FAILURE
; BR, BRX, PRESERVED.
; B=0 IF TRANSLATE, =1 IF OFFSET MODE, =2 IF EDIT, =4 IF CVTDBT
=00
SRCMOD: SLEN_AR,AR+ARX+MQ_0.M,CALL.M, ;PUT LENGTH AWAY, GET BYTE
SIGNS DISP,J/GSRC ;CHECK FOR LENGTH EXHAUSTION
AR_SFLGS,SR_0,RETURN1 ;LEN =0, DONE
E1,TIME/2T,B DISP ;BYTE IN AR
=110 AR_AR*.5 LONG,E1,J/XLATE ;LOW BIT TO ARX0, BYTE/2 TO AR LOW
AR_AR+E1,TIME/3T ;OFFSET, ADD OFFSET, TEST MASK
TEST AR.MSK,SKP CRY0,RETURN4 ;RETURN 4 IF OK, 5 OUT OF RANGE
;HERE ON TRANSLATE-MODE OPERATIONS, WITH THE BYTE/2 IN AR, AND
; THE LEAST SIGNIFICANT BIT OF THE BYTE IN ARX0. PERFORM THE
; TABLE LOOKUP, AND OPERATE AS CONTROLLED BY THE HIGH THREE BITS
; OF THE TABLE ENTRY.
XLATE: VMA_AR+E1,LOAD AR ;GET FUNCTION FROM TABLE
TRNAR: AR_MEM,SKP ARX0,SC_#,#/18. ;WHICH HALF?
=0 ARX_AR,AR0-3 DISP, ;LH, MOVE TO ARX LEFT
AR_SFLGS,J/TRNFNC
ARX_AR SWAP,AR18-21 DISP, ;RH, MOVE THAT TO ARX LEFT
AR_SFLGS,J/TRNFNC
;HERE ON TRANSLATE OPERATION TO PERFORM FUNCTIONS REQUIRED BY
; THE 3 HIGH ORDER BITS OF THE TRANSLATE FUNCTION HALFWORD.
; WE HAVE DISPATCHED ON THOSE THREE BITS, WITH THE FUNCTION
; HALFWORD IN LH(ARX), AND THE FLAGS FROM AC0 IN AR.
=0001
TRNFNC: SFLGS_AR,FE_P,AR_SHIFT, ;SAVE FLAGS, GET FCN IN AR RIGHT
SIGNS DISP,J/TRNRET ;WAS S FLAG ALREADY SET?
TRNABT: SFLGS_AR,FE_P AND #,#/3,RETURN5 ;ABORT
P_P AND #,#/67,J/TRNFNC ;CLEAR M FLAG
P_P OR #,#/10,J/TRNFNC ;SET M FLAG
TRNSIG: P_P OR #,#/20,J/TRNFNC ;SET N FLAG
P_P OR #,#/20,J/TRNABT ;SET N AND ABORT
P_P AND #,#/67,J/TRNSIG ;CLEAR M, THEN SET N
P_P OR #,#/30,J/TRNFNC ;SET N AND M
=011
TRNRET: ARX_AR*MSK,AD/AND, ;S FLAG IS 0, GET BYTE IN AR
SKP AR18,B DISP,J/TRNSS ;IS THIS EDIT?
AR_AR*MSK,AD/AND,RETURN4 ;RETURN NORMAL SINCE S FLAG SET
=100
TRNSS: AR_DLEN,B DISP,J/TRNNS1 ;NO SIG ON MOVE OR D2B
AR_SFLGS,SC_#,#/40,J/TRNSS1 ;SIG START, SET FLAG
VMA_E0+1,LOAD AR,RETURN2 ;EDIT NO SIG. GET FILL
AR_DSTP,FE_#,#/36.,RETURN3 ;EDIT SIG START
=0**
TRNNS1: AR_AR-1,J/TRNNS2 ;COMPENSATE FOR IGNORING SRC
AR_SLEN+1,J/SRCMOD ;D2B HAS NO DEST LENGTH
TRNNS2: DLEN_AR,SIGNS DISP
=011 AR_SLEN,J/SRCMOD ;SLEN = DST LEN, DON'T CHANGE IT
AR_SLEN+1,J/SRCMOD ;SLEN REFLECTS SRC LENGTH
; COUNT DOWN FOR BYTE SKIPPED
TRNSS1: P_P OR SC
SFLGS_AR,AR_ARX,RETURN4 ;RETURN WITH SIG SET
;SUBROUTINE TO GET BYTE FROM SOURCE STRING
; CALL GSRC WITH SIGNS DISP TO CHECK FOR LENGTH EXHAUSTION
; [TIME = 17 + 3(BP OVERFLOW)]
=011
GSRC: AR_DLEN,RETURN1 ;LEN RAN OUT
GETSRC: AR_SRCP,ARX_SRCP,FE_#,#/36.
=0
GSRC1: P_P-S,SC/SCAD,CALL.M, ;UPDATE POINTER
SKP SCAD0,J/GSRC2 ;TEST FOR WORD OVERFLOW
SC_FE+SC,SKP INTRPT,J/LDB1 ;GET BYTE & RETURN TO CALLER
=0
GSRC2: SRCP_AR,ARX_AR,FE_S, ;STORE POINTER,
EA MOD DISP,J/BFETCH ; GO EVALUATE THE ADDRESS
AR_AR+1,P_FE-S,SC/SCAD,J/GSRC2
;SUBR TO STORE AR IN DEST STRING
; [TIME = 24 + 3(BP OVERFLOW)]
=00
PUTDST: MQ_AR,AR_DSTP,ARX_DSTP,
FE_#,#/36.,CALL,J/IDST
AR_MQ,SC_#-SC,#/36.,SKP SCAD0,
CALL,J/DPB1
=11 MEM_AR,RETURN6
;SUBROUTINES TO UPDATE STRING POINTERS
IDST: P_P-S,SC/SCAD,SKP SCAD0 ;TEST FOR WORD OVERFLOW
=0
IDST1: DSTP_AR,ARX_AR,FE_S, ;STORE POINTER,
EA MOD DISP,J/BFETCH ; GO GET THE WORD ADDRESSED
AR_AR+1,P_FE-S,SC/SCAD,J/IDST1
.ENDIF/EIS
XFERW: FIN XFER,MB WAIT,RETURN2 ;FINISH TRANSFER, RETURN
.IF/EIS
.TOC "EIS -- EDIT FUNCTION"
; HERE WITH E0, E1 SETUP, 0 IN AR, -1 IN ARX, AND 15 IN SC
EDIT: AR_SHIFT,ARX_AC0 ;MASK TO AR, FLAGS ETC TO ARX
=1*0 MSK_AR,AR_ARX (AD), ;SAVE MASK, GET FLAGS IN AR
VMA_ARX,LOAD AR, ;GET FIRST PATTERN OPERATOR
CALL,J/TRNABT ;GET PBN INTO FE
EDITLP: SC_# AND AR0-8,#/30, ;PBN*8 IN SC
SFLGS_AR,ARX_AR ;UPDATED AC NOW IN AC AND ARX
=0* SC_FE+SC,SR_0,CALL,J/XFERW ;PATTERN IN AR, PBN*9 IN SC
AR_SHIFT,SH DISP,SC_#,#/5 ;PATTERN BYTE TO AR0-8,
=0001 ; DISP ON HIGH 3 BITS
EDDISP: GEN #+AR0-8,#/-5,
SKP SCAD0,J/EDOPR ;(0XX) OPERATE GROUP
AR_AR*8,SKP ARX0,J/EDMSG ;(1XX) MESSAGE
J/EDNOP ;(2XX) UNDEFINED
J/EDNOP ;(3XX) UNDEFINED
J/EDNOP ;(4XX) UNDEFINED
MQ_ARX,ARX_ARX*4,
SC_FE+1,J/EDSKPT ;(5XX) SKIP IF MINUS
MQ_ARX,ARX_ARX*2,
SC_FE+1,J/EDSKPT ;(6XX) SKIP IF NON-ZERO
AR_AR*8,SC_FE+1,J/EDSKP ;(7XX) SKIP ALWAYS
;HERE TO DECODE OPERATE GROUP
=0
EDOPR: J/EDNOP ;OPR .GE. 005 UNDEFINED
SH DISP,J/OPDISP ;(00X), DISP ON LOW 3 BITS
=000
OPDISP: AR_ARX,SC_#,#/-4, ;(000) STOP
VMA_PC+1,J/EDSTOP
SR_ED(S),J/EDSEL ;(001) SELECT
AR_DSTP,SKP ARX0,J/EDSSIG ;(002) START SIGNIFICANCE
AR_ARX,J/EDFLDS ;(003) FIELD SEPARATOR
VMA_AC3,LOAD ARX, ;(004) EXCH MARK AND DEST
MQ_ARX,J/EDEXMD
=
;HERE TO TERMINATE EDIT INSTRUCTION
; SC HAS -4, FE HAS CURRENT PBN, VMA HAS PC IF ABORT, PC+1 IF DONE
EDSTOP: FE_FE-#,#/3,SKP SCAD0
=0 AR_AR+1,INH CRY18,
P_P AND SC,J/SFET1
P_P+1
SFET1: FETCH+1,J/STORAC
;HERE FOR SKPM & SKPN, WITH APPROPRIATE BIT IN ARX0
EDSKPT: AR_AR*8,SKP ARX0,ARX/MQ ;SKIP DISTANCE TO AR0-5
;HERE AT END OF OPERATION TO UPDATE PBN
=0
EDNOP: FE_FE-#,#/3,SKP SCAD0, ;END OF PATTERN WORD?
AR_ARX,J/EDNXT1
EDSKP: FE_P+SC,J/EDNOP ;ADD SKIP DISTANCE
=0
EDNXT1: AR_AR+1,INH CRY18, ;BUMP TO NEXT WORD
FE_FE-#,#/4, ;REDUCE PBN
SKP SCAD0,J/EDNXT1
FE_FE+#,#/4 ;RESTORE PBN POS, INCR IT
SC_P AND #,#/74,VMA_AR,LOAD AR ;FLAGS & EDIT BIT TO SC, GET PATTERN
P_FE OR SC,J/EDITLP ;SET NEW PBN, GO DO NEXT PATTERN
;HERE TO EXCHANGE MARK AND DESTINATION POINTERS
EDEXMD: AR_DSTP ;READY TO STORE DEST PTR
FIN XFER,STORE ;WAIT FOR MARK, STORE DSTP
MEM_AR,AR_ARX ;READY TO UPDATE DSTP
DSTP_AR,ARX/MQ,J/EDNOP ;DONE, GET NEXT OPR
;HERE FOR FIELD SEPARATOR (CLEAR FLAGS IN AC 0-2)
EDFLDS: P_P AND #,#/7,J/EDSEND ;EASY ENOUGH
;HERE FOR SIG START
=00
EDSSIG: VMA_AC3,STORE,CALL,J/EDFLT ;SAVE MARK, GET FLOAT
FE_FE-#,#/3,SKP SCAD0, ;S FLAG ALREADY SET, NOP
AR_ARX,J/EDNXT1
=11
EDSEND: FE_P AND #,#/3,ARX_AR,J/EDNOP ;READY TO DO NEXT OP
;HERE FOR MESSAGE CHAR
=00
EDMSG: VMA_E0+1,LOAD AR,J/EDSFIL ;NO SIG, PUT FILLER
SC_P,AR_0S,CALL,J/GETSC ;GET MESSAGE SELECT IN AR
=11 VMA_AR+E0+1,LOAD AR,J/EDMPUT ;STORE MESSAGE
;HERE FOR SELECT
=0*
EDSEL: AR_SRCP,ARX_SRCP,FE_#,#/36.,
CALL,J/GSRC1 ;GO GET SRC BYTE
AR_AR*.5 LONG,E1 ;GOT IT, DIVIDE BY 2
=000 VMA_AR+E1,LOAD AR,CALL,J/TRNAR ;GO TRANSLATE BY HALFWORDS
=010
EDSFIL: AR_MEM,J/EDSF1 ;(2) NO SIGNIFICANCE, STORE FILL
GEN P-S,SKP SCAD0,BRX/ARX,J/EDSFLT ;(3) SIG START, DO FLOAT CHAR
EDSPUT: SR_ED(+D),CALL,J/PUTDST ;(4) NORMAL, STORE AT DST
VMA/PC,SC_#,#/-4,J/EDSTOP ;(5) ABORT
EDFPUT: AR_SFLGS,J/EDSEND ;(6) BUMP PBN AND GO TO NEXT
EDMPUT: AR_MEM,J/EDSPUT ;FILL OR MSG IN AR, STORE IT
;HERE WHEN TIME TO STORE FILL CHAR
EDSF1: SKP AR NE,J/EDFPUT ;IS THERE ONE?
;HERE WHEN SELECT STARTS SIGNIFICANCE
=00
EDSFLT: VMA_AC3,STORE,CALL,J/EDFLT ;STORE DEST AT MARK ADDR
P_FE,AR_AR+1,J/EDSFLT ;FORCE STANDARD POINTER FORM
=11 SFLGS_AR,AR_BRX,J/EDSPUT ;SET S FLAG, GET BYTE, STORE IT
;HERE IS SUBROUTINE TO STORE FLOAT CHAR
EDFLT: MEM_AR,AR_2 ;GET FLOAT FROM E0+2
=0* VMA_AR+E0,LOAD AR,CALL,J/XFERW
SKP AR NE
=100 AR_SFLGS,SC_#,#/40,J/SETFLG ;NO FLOAT CHR, SET S FLAG
SR_ED(+D),CALL,J/PUTDST ;STORE FLOAT CHR IN DST
=111 AR_SFLGS,SC_#,#/40 ;SET S FLAG AND RETURN
SETFLG: P_P OR SC,RETURN3 ;NO FLOAT CHR, SET S FLAG
.ENDIF/EIS

552
src/ucode/fp.5 Executable file
View File

@@ -0,0 +1,552 @@
.TOC "SINGLE FLOATING ADD & SUB -- FAD, FADR, FSB, FSBRôCE
 .DCODE
.ù1§O©/UFA.ø‘§
130: I, J/UUO ;UFA
I, J/UUO ;DFN
.ENDIF/UFA.DFN
140: R, FL-AC, B0/0, J/FAD
R, B0/0, J/FADL
RW, FL-MEM, B0/0, J/FAD
RW, FL-BOTH,B0/0, J/FAD
R, FL-AC, J/FADR
I, FL-AC, B0/0, J/FADRI
RW, FL-MEM, J/FADR
RW, øÓŸTH, J/FADR
150: R, FL-AC, B0/1, J/FSB
R, B0/1, J/FSBL
RW, FL-MEM, B0/1, J/FSB
RW, FL-BOTH,B0/1, J/FSB
R, Fù`ÃY J/FSBR
I, Fù`ÃY B0/1, J/FSBRI
RW, FL-MEM, J/FSBR
RW, FL-BOTH, J/FSBR
.UCODE
.IFNOT/FPLONG
=00**00
FAD:
FSB: SR_#,#/1,B DISP,J/FADR ;FLAG NO ROUND, GO FAD/FSB
FMP: SR_#,#/1,J/FMPR
FDV: SR_#,#/1,J/FDVR
FADL:
FSBL:
FMPL:
FDVL: AR_BR,J/UUO ;LONG MODE BECOMES UUO
=
.IF/FPLONG
=00***0
FAD:
FSB: SR_#,#/1,B DISP,J/FADR ;FLAG TRUNCATE MODE, GO FAD
FADL:
FSBL: SR_#,#/2,B DISP,J/FADR ;FLAG LONG MODE
.ENDIF/FPLONG
=
=00*010
FADRI:
FSBRI: AR_AR SWAP,B DISP
FADR: FE_EXP,EXP_SIGN,SC/SCAD,
ARX_0S,J/FAS
=111
FSBR: FE_EXP,SC/SCAD,EXP_SIGN,ARX_0S
= AR_-AR,J/FAS ;NEGATE SUBTRAHEND
;FIND OPERAND WITH LARGER EXP, LEAVING IT IN BR,
; AND ITS EXP-1 IN FE. THE SMALLER OPERAND IS LEFT IN AR,
; SHIFTED RIGHT BY THE DIFFERENCE BETWEEN THE EXPONENTS -1
FAS: BR/AR,BRX/ARX,AR_AC0 ;SAVE MEM OP IN BR, GET AC
SC_EXP-SC,EXP_SIGN,SKP SCAD0 ;FIND LARGER OPERAND
=0 FE_FE+SC,BR/AR,AR_BR*2,J/FAS1 ;AC EXP .GE. MEM
MQ_AR,SC_#+SC,#/37., ;MEM OP LARGER, SHIFT AC OP
SKP SCAD0,J/FAS2 ;COMPUTE SHIFT AMOUNT
FAS1: MQ_AR,SC_#-SC,#/36.,SKP SCAD0 ;CHECK SHIFT AMOUNT
=0
FAS2: MQ_SHIFT,ARX/MQ,AR_SIGN,J/FAS3 ;LOW TO MQ, READY TO GET HI
AR_SIGN,ARX_AR, ;HERE IF EXP DIFF .GT. 36
SC_#+SC,#/36.,SKP SCAD0 ; .GT. 72?
=0 ARX_SHIFT,MQ_0.M,FE_FE+1,J/FAS5
ARX_AR,MQ_0.M,FE_FE+1,J/FAS5 ;SHIFTED CLEAR OUT
FAS3: AR_SHIFT,ARL/SH,ARX/MQ,
MQ_0.M,FE_FE+1 ;READY TO ADD
FAS5: AR_(AR+2BR)*.25,ARX/ADX*.25, ;HERE FOR ADD OR SUB
NORM,J/SNORM
.TOC "SINGLE FLOATING MULTIPLY -- FMP, FMPR"
.DCODE
160: R, FL-AC, J/FMP
R, J/FMPL
RW, FL-MEM, J/FMP
RW, FL-BOTH,J/FMP
R, FL-AC, J/FMPR
I, FL-AC, J/FMPRI
RW, FL-MEM, J/FMPR
RW, FL-BOTH,J/FMPR
.UCODE
.IF/FPLONG
=00***0
FMP: SR_#,#/1,J/FMPR ;FLAG TRUNCATE MODE
FMPL: SR_#,#/2,J/FMPR ;LONG MODE
=
.ENDIF/FPLONG
=00***0
FMPRI: AR_AR SWAP
FMPR: SC_EXP,EXP_SIGN,ARX_0S ;PREPARE M'IER FRACTION
= MQ_AR,AR_AC0,FE_#,#/-14. ;M'IER TO MQ, GET M'CAND
=01* SC_EXP+SC,EXP_SIGN, ;SEPARATE M'CAND FRACTION FROM EXP
CALL.S,J/MULSUB ;AND BEGIN MULTIPLY
=11* FE_#+SC,#/-200,NORM AR,J/SNORM
=
.TOC "úrgG™E FLOø5$Î<> DIVIDE --ô¢VY FDVR"
.DCODE
170: RõcL[ø0Ö •/FDV
R, FL-AC, J/Fø•¦
 RW, FL-MEM, J/FDV
RW, FL-BOTH,J/FDV
R, FL-AC, J/FDVR
I, FL-AC, J/FDVRI
RW, FL-MEM, J/FDVR
RW, FL-BOTH,J/FDVR
.UCODE
.IF/FPLONG
=00***0
FDVL: Fø·âØ¡-1,EXP_SIGN,ARX+MQ_0.S,J/øÑ+Lcñ¢£D­: SR_#,#/1,J/FDVR ;FLAG TRUNøpjEAMODE
=
.ø³¢I<EFBFBD>/FPLOùÑÆŠ{00***öEF‰VRI: ø4¯Á¥ SWAP
FDVúN„Ó‡ûñlPW1,EXP_SIGN,ARX+MQ_0.S ;SETUP DIVISOR
=îñOX0a BR/AúK!R±/ARX,ñ"D»‰IVISOúH*OABR, Cù”<C3B9>B¥X
ø4¯Á‡0,FE_ôk¯e7., ;øñj ‰IVIDEùÑ §TEP CùõgT
SKú Äa,CALLõ—ƉVCHKîñCE=c0 SKPô©0YCALL,ùKâI­- ;OùkBGIN Dù5¤Ó“ON
úqj <20>L NO øk,•/IFNOú<44>O DIVù1"¬ASORRYñ¢†ŠwRETURùÈ$E¥E WITù(ÕŸTIENTôg ƒRX. úñPTŸOK 29ô$Ö“DE STø´)¬ATO
êÁ¥ANTEEô Ö“NG A úSêΉING Bù5E­EN IFô$EAFIRSTôêE¡ GENEúPjE§
; AôjÏ©IENT øRj ŸF ZERùë<C3B9> ©HEREFùô¢¬ATHE Múp<C3BA>O<EFBFBD> QUOTù1gTAIS EIú
; INô¤ÔA7 OR ÷ A<>D NORù¨+É™L FINøˆ$ÔAIN ONø¨)ÔP.
îñOX±a AR_AúVF_FE+#õˆ×²Y ;NEøðjI­E QUOúbΩ
SùtB¥ EQ,Jõñ¢V<C2A2>EG ;CùaËAFOR Mùô¢ £UO TOôçÍ‹
ARûðiXU.25,AúV/Á¥X*.25õ“§Ò›, ;JUùÒÐI§ 36 Bù5) ƒWAY FúSæ SB
ñ1¢ß<C2A2>E+#,#õìJ_SNORMñ.èO§ QUOTù1gTY NORMø3$Ú‹
=
;HERE IF QUOTIENT SHOULD BE NEGATIVE, WITH POSITIVE FORM INîñNÐA¥ AND ø4¬.A SKIPôc ¥EMAINøi QIN BRõ($ÓAZERO.ô$ÎATHIS øpiÅY
; Wø¨!ÌAR ARû BCAUSEôi ‡ONTAIùÔÐTE ENTù4¢ £UOTIEùÕ
; IF, HOWEVER, THE REMAINDER IS NOT ZERO, WE INFER
; Tùj ƒN INFù3¤Ô PRECù4äÏ<C3A4> DIVIúrgÎAWOULDôâÎRATE ù³éEAONESîñNÐI<C390> THE ú5gÔ“ENT. ôc ©HAT Iúh*H CASEõˆ+ÅALEAVEôiXAWITH ú’"<22>; QUOTIENT, SO THE NEGATION PROCESS WILL WORK CORRECTLY TO RETURNñ¢<C3B1> ©HE HIøòO¥DER Pø4ª ŸF THEôgF“NITE-ú¢Ã“SION ùÑcÁ©IVE Qú³êINT.
÷¬Š<>DVNEG÷BiÅ© SR1,ø4¯Á¥*.25 ù“çGYNORM,ùKéΟRM
ø4¬_aS,J/Fø•§E<C2A7> ;Rø³`É<>DER Wø³ª ©O ZERùãE wHERE øÓé <20>DVL
ñ¢—I<EFBFBD>/FPLOùÑÆŠ
;FDVùŽ„Æ_EXP-ö+"Ø¡_SIGNõ<4E>æRAARX+Mú#E=a00
Fø•¦1u AR_AølVB¥_AR Lùó£¬ ;SAVø¨"I­ISOR ù3<C3B9>B¥ LONGñ¢„‰§C_#,#õîW,‡ALL ÷t¢Á‰Y TO úr$Æ© LOW økI‰END
ARX_SHIFT,AR_AC0, ;DIVIDEND IN PLACE
SC_FE,FE_#,#/24., ;EXP TO SC, STEP COUNT TO FE
SKP AD0,J/FDVCHK ;GO CHECK FOR NO DIVIøFŠ{010 Cø3&,§KP BRö %/<2F>DVL2 ñ.ãÏABEGINô$Ö“DE
úqj <20>L NO øk,•/IFNOúD»‡AN'T økI‰E, ABùôª

=11ö`Ò¿AC0,SúWѬG/5, ÷s¢ÇAQUO, øÓ ÇATRUNCø5" ODE
SR DISP,J/FDVL4 ; WAS IT 26 OR 27 STEPS?
AR_AC0,SR_#,#/1, ;POS Qú³ÆŠ SR Dù4è,•/FDVLöƒE=
;COME HERE TO START THE DIVISION. ON THE FIRST STEP, WE CHEørÆŠw TO Sø±PWETHERôP1AHAS Bø±g <20>ENERAúb “N THEôjÏ©IENT.ô$ÆASO,
; 26 ADDITIONAL STEPS WILL GENERATE THE FULL 27 SIGNIFICANT BITS
; OFô$EAQUOTIø³ª.A IF Nùõ e7 STEúÐA¥E REQú²iE‰.
÷¬Š<>DVL2:ñ1$Ö“DE,ARûì”A¥-BR),ø4¬/ƒDX*2,ùKãD­L3 ;Fù4©ÔADIVIDø¨)ÔP
Dù5¤Ä,AR_2(AR+BúJVA¥X/ADX*2 ; DOESôj <20>ø³¢ÒƒúPAA1?
Š<>ø•¦3u DISP/DIV,MQ/MQ*2, ÷s§¬Aú<41>eÅAAN EXú”  ‰IVIDE STEPñ¢„‰ƒR_2(AR+BR),ARX/ø1,*e,J/DIVLP ; WITHùõj ‡OUNTING FE
SRûìVS‡_#+SCõˆ×±YJ/DIV- ;Yø´Ö e7 STEPS WIù“NŸRMALIûQPQ«ùãE ‰ù4è/‰IV,MQõóhªeõ<65>i_eõi-…R),ARX/ADX*2,J/økL¡
SRûìVS‡_#+SCõˆ×±YùKâI­õcE wWE COù±PHRE AFTER DùògGATHE DIVISION, EITHERô ŸúH7ASTEPSñ¢<C3B1> ƒúh)E£ú²iE‰ TO GENERAúPAAùÓéMƒùmE‰ QUOTù1gTAFROM ùÓéMƒùmE‰
; OPERANDS. ùÓë <C3AB>ù1êÒôêÔAWHAT EXPONø³ª ©ùPRMAINDER SHOULD HAVE.ñ¢†Š{öEF‰VL4: SC_EXP-#,#õì®Yñ"D»‰IVIDEND EXP-27îñBDÁ¥_BR,SùtA¥ö %/<2F>DVL6 ÷qâÔAREMAIùÑ"ÒYô"Ó© D'ENøˆ<>N
SøwâØ¡-#,#/öM—, ;D'END Eû²mñ¢„‰ƒúWáRYSKP AR0
îñNäE¥E WITH REMAINDEúH$ÎAAR, Iú”ÐE±P IN úpÆŠwôåÉ¡ôc ‰'END (AND THEREøÓéEAREM) NEGATIVE.îñCE=a
FDVL6: Eû/Ó‡õ<E280A1>¬Ô DISP, ;TEST FOR UNDERFLùõÆŠ SKP AR EQõ—ƉVL7 ;ôé ¥EM =0
AR_-BR,SKP CRY0, ñ.çE<C3A7>ATE REM, CHECK =0
GEN úpÖB³úPD“SP ; AND Lùóå <C3A5>OR EXú*Æ™ùãE=c10 EXP_-SC-1,J/øÑ+Lo ;ONE'S COMPLEù±gTAø¶(
 AR_0S ;REM =0 OR EXP UFLOîñOX±a
FDVL7: AøloÁ¥õ<C2A5>iXWMQ_0.ù«‰wúpkEAúQfÁ“ùÑ"Ò
AR_MQ,AúSÁ‰õ—Ó<E28094>R2 ;Gùè'O¥MALIZE QUOTIENT
ARûì)¬•/FDVL7
.ENDIF/FPLONøãE

;SUBR TOôäE‡ùh#O¥ô¦OƒTING NO DIVIDE
; ENTER WITH SKP ON DIVIøgDASIGN, IN AR LONG, WITH
$Ö“SOR EXP IN SC, økI§OR IN BR
=0îñQ¢V‡HK: SC_EXP-SC,Eû/Ó“øóS—P BR0õ—ƉVCK1
AR_-AR LONG,J/FDVCHK ;øñj ¡OSITIúÑPD“úÒbE<62>øƒE=añ¢£D­ørغGEN AR-2BR,SKP øt¬°Y ;TEúuFŸúH'OADIVIDø£E úpï£WSC,#/ö-Û¬¥ETURN2 ;AND CORRECT EXP
GEN AR+2BR,SKP CRY0, ;SAME TEST, NEG DIVISOR
úpï£WSC,#/ö-Û¬¥øµ*Ò<>2 ;ANøˆE EXPôçÒ¥ø°êIŸùÃE ]TOC "ú± ¬Aø§,AFSC, IBP"
;ENTø´<C3B8>W“TH (Eõ($ÎAø4†Š]IF/UFø+¢F<C2A2>ñ¢„®‰øsâE
130: R, J/UFAñ¢„Ò¡W, J/DFN
.UCODE
=00**õLЉøÓ<C3B8> <09>ø·àÒa-8,AR0-8_#õˆ×°Yñ"]ÓƒúÑPLŸúè"Ø¡õˆ!Ì¥ SO Cø3<C3B8>
 ARX_0S,J/DFN1 ; DETECT FRACúgÎA÷¨
UFA: FE_EXP,SC/SCAD,EXP_SIGN,AúV/°§
=
=000 BR_AR LONG,AR_AC0,CALL,J/ø¶(D
=100ñ0iX¿ø4A¥_SIGNõ<4E>iL_AD, ;READû(*OAUNNORMALIZø¨)̓ù“"ÒAOP
ñ0àÌ™õÓVJ_úr$Æ©ñ¢„Á¥_SIGNõ<4E>iX_AD ;LOSTôæÁ™LER Oú U§E ITSôäÇ<C3A4>ñ¢„Á¥_AR+BúK)Ë¡ôb <20>ø«‰wIS REúufTAúrcΓøÒaÁ<61>T?
SC_Fø«$ <>øµ!È
=
`Ãc_AR,J/FINIñ"D»<44>ùëC™ø°i ¥ESULT AC
SKP EXP NE,BR/AR ;IS RIGHT SHIFT REQ'D?
=0ñ4åÐAø4˜,<2C>ETCH WAIT,ùKêÆƒ4 ;NOõˆ$ÓARESULT NEG÷ãE ƒúWáRU.5,GEN FE-ôk¯göíÖS—P SCAøˆ'EYFETCH WAIT
=0 øÑo­c,SET FLOV
FE_øÑU±YSC/SCAD,SKP AR0
=0
UFA4÷B`Òa-8_SCõ—Ó©ø0؉÷t'ÓY PUT IN EXP STRø2cÈ©ñ¢„Á¥ö \_[SC-1,J/STAC1 ;NEG, ú´â ‡ùóhLMENT OF EXúE

DFNö.„Á¥ûë`ÒYSKP CRY0 ; LOW FRACTION =0?
=0 AúL¸¿FE,STùô¢¬ñ"]Ó©ORE LOW WORD BAørÐTŸ MEM
ARX_AC0 COMP,J/STMAC ;ôâÔAøsæÐ™EMENTø±H“GH WORD
AR0-8_FE,STORE, ;LOW WORD WAS ZERO, INSTALLôlP
ARX_-AC0,J/STMAC ÷h#Å© NEGATED HIGH WORD
.ENDIF/UFA.DFNîñCŠ.DCODE
132: I, FL-AC, J/FSC
R, J/IBP ;ADJBP IF AC .NE. 0
.UCODE
=00***0
.IF/ADJBP
IBP: SKP AC#0,J/IBP1 ;IS IT IBP, OR ADJBP?
.IFNOT/ADJBP
IBP: J/IBP2
.ENDIF/ADJBP
;FSC
;ENTER WITH E IN AR
=00****
FSC: SC_EA,ARX+MQ_0.M,
AR_AC0,ARL/AD
= FE_EXP+SC,EXP_SIGN,J/SNR2 ;NORMALIZE SCALED RESULT
.TOC "FIX, FIXR, FLTR, EXTEND"
.DCODE
122: R, J/FIX ;UNROUNDED
.IF/EIS
R, J/EXTEND ;EXTENDED INSTRUCTION SET
.IFNOT/EIS
I, J/UUO
.ENDIF/EIS
126: R, J/FIXR ;ROUNDED
R, FL-AC, J/FLTR
.UCODE
;FLTR
;ENTER WITH (E) IN AR
=00***0
FLTR: FE_#,#/277,ARX_AR,SKP AR0, ;BINARY POINT TO RIGHT OF ARX
AR_SIGN,J/SNORM ; SIGN EXTENDED. GO NORMALIZE
;FIX AND FIXR
;ENTER WITH (E) IN AR
; FIX AND FIXR DIFFER ONLY IN THE ROUNDING CRITERION:
;FIXR ADDS 1 TO THE INTEGER PART IF THE FRACTION PART IS ONE-HALF
;OR GREATER. FIX DROPS THE FRACTION PART OF POSITIVE NUMBERS, BUT ADDS
;1 TO THE INTEGER PART OF NEGATIVE NUMBERS IF THE FRACTION PART IS NOT
;ALL ZERO.
; THIS IS IMPLEMENTED BY CHOOSING A FRACTION (THE ROUNDING
;CONSTANT) TO ADD TO THE INPUT, SUCH THAT A CARRY WILL OCCUR INTO THE
;INTEGER PART UNDER THE APPROPRIATE CONDITIONS. FOR FIXR, THE ROUNDING
;CONSTANT IS EXACTLY ONE-HALF. FOR FIX, IT IS ZERO ON POSITIVE INPUT,
;OR THE LARGEST POSSIBLE FRACTION (ALL 1S) ON NEGATIVE INPUT.
=00****
FIXR: FE_EXP-#,#/244,SKP SCAD0, ;GET BINARY POINT POSITION
ARX_1B1,J/FIX1 ;GET ROUNDING CONSTANT
=
.IFNOT/EIS
;1005: ;REALLY IN SKPJMP FILE TO PREVENT 1005 BEING USED TWICE
;FIX: FE_EXP-#,#/244,SKP SCAD0, ;GET BINARY POINT POSITION
; ARX_AR SIGN,J/FIX1 ;SET ROUNDING CONSTANT, GO FIX
.IF/EIS
=00***0
FIX: FE_EXP-#,#/244,SKP SCAD0, ;GET BINARY POINT POSITION
ARX_AR SIGN,J/FIX1 ;SET ROUNDING CONSTANT, GO FIX
EXTEND: FE_#+AR0-8,#/-20,SKP SCAD0, ;VALID EXTENDED OPERATION?
ARX_AR,AR_BRX,J/EXT1 ; OPR TO ARX, AC TO AR
=
.ENDIF/EIS
=0
FIX1: SET AROV,J/IFNOP ;CAN'T DO IT, GIVE UP
BR/AR,CLR AR,ARX_ARX*2 ;ROUNDING CONSTANT READY IN ARX
BR_AR LONG,AR_BR,CLR ARX, ;MANTISSA TO AR LONG
SC_#,#/9. ;READY TO SHIFT OFF EXPONENT
ARX_SHIFT,AR_SIGN, ;MANTISSA LEFT ALIGNED IN ARX
SC_FE+#,#/36.,SKP SCAD0 ;ANY INTEGER BITS?
=0 MQ_SHIFT, ;YES, PUT THEM IN MQ
AR_ARX (ADX),CLR ARX, ;SHIFT MANTISSA LEFT 36 PLACES
I FETCH,J/FIX2 ;AND PREFETCH NEXT
AR_0S,I FETCH,J/STORAC ;ALL SIGNIFICANCE LOST
FIX2: ARX_SHIFT,AR_MQ ;INTEGER IN AR, FRACTION IN ARX
AR_AR+BR,AD LONG,J/STAC ;ROUND AND STORE
.TOC "SINGLE PRECISION FLOATING NORMALIZATION"
;HERE TO NORMALIZE SINGLE PRECISION RESULTS
;SR2-3 TELL HOW TO STORE RESULTS:
;XX00 ... ROUND, SINGLE PRECISION
;XX01 ... TRUNCATE, SINGLE PRECISION
;XX10 ... LONG MODE (IMPLIES TRUNCATION)
;IN ADDITION, THIS CODE SETS SR 1 IF ANSWER IS NEGATIVE, SO X1YZ
; CORRESPONDS TO X0YZ EXCEPT THAT THE RESULT MUST BE NEGATED.
;DISPATCH TO SNORM WITH "DISP/NORM,AR/AD*.25"
; THUS THE 8 POSSIBILITIES ARE:
;SNORM AD=0 AR=0 EITHER ANSWER IS ZERO, OR MSB IS IN ARX
;SNORM+1 AD0 AR NEG RESULT IS NEG. MAKE POS, TRY AGAIN
;SNORM+2 AD1-6 AR3-8 MSB TOO FAR LEFT, SHIFT RIGHT & RETRY
;SNORM+3 AD7 AR9 RESULT IS CORRECTLY NORMALIZED
;SNORM+4 AD8 AR10 SHIFT LEFT ONCE FOR NORMALIZATION
;SNORM+5 AD9 AR11 SHIFT LEFT 2 PLACES
;SNORM+6 AD10 AR12 SHIFT LEFT THRICE
;SNORM+7 AD11-35 AR13-35 SHIFT LEFT A LOT, TRY AGAIN
=000
SNORM: AR_ARX,ARL/SH,SKP ARX NE, ;AR IS ZERO, GET ARX
ARX_0.M,J/SNZERO
NORM -AR,SET SR1,J/SNORM ;REMEMBER NEGATIVE, GO POSITIVE
SNR2: AR_AR*.25 LONG,FE_FE+#,#/2, ;SHIFT RIGHT,
NORM,J/SNORM ;TRY AGAIN
SR DISP,J/SROUND ;AD7 -> AR9, IS ROUND REQ'D?
AR_AR*2 LONG,FE_FE-1, ;AD8 -> AR10, ONCE LEFT AND DONE
SR DISP,J/SROUND
AR_AR*4 LONG,FE_FE-#,#/2, ;AD9 -> AR11
SR DISP,J/SROUND
AR_AR*8 LONG,FE_FE-#,#/3, ;AD10 -> AR12
SR DISP,J/SROUND
ADA EN/0S,ADB/AR*4,AD/ANDCA, ;GENERATE AR*4
AR/AD*2,ARX/ADX*2, ; AR_AR*8 LONG
SC_#,#/12., ;READY TO SHIFT FARTHER
GEN CRY18,SKP CRY0 ; TEST AR0-19 FOR ZERO
=0 AR_AR*8 LONG,BR_AR LONG, ;IT WAS IN AR13-19
FE_FE-#,#/6,NORM,J/SN1 ; NOW IN AR10-16, AD8-14
MQ_SHIFT,AR_ARX (ADX), ;13-19=0, SHIFT TO TRY 20-35
CLR ARX,SC_#,#/10.
ARX_SHIFT,AR_MQ*.25, ;REPOSITION FRACTION IN AR LONG
FE_FE-#,#/13., ;COMPENSATE EXPONENT
NORM,J/SNORM
=100
SN1: AR_BR*2 LONG,FE_FE+#,#/2, ;MSB IN AD8, SO IN BR10
SR DISP,J/SROUND
AR_BR*4 LONG,FE_FE+1, ;MSB IN AD9, THUS IN BR11
SR DISP,J/SROUND
SR DISP,J/SROUND ;AD10 -> AR9, A LUCKY GUESS
AR_AR*8 LONG,BR_AR LONG, ;TRY SHIFTING 3 MORE
FE_FE-#,#/3,NORM,J/SN1
;HERE WHEN AD ENTIRELY ZERO ON NORMALIZE ATTEMPT. SKIP IF ARX
; IS NOT ZERO, HAVING COPIED IT TO AR (IE, LEFT SHIFT 36 PLACES).
; OTHERWISE, THE ENTIRE RESULT IS ZERO, SO WE STORE THAT.
=0
SNZERO: CLR FE,AR+ARX+MQ_0.M, ;RESULT = 0
SR DISP,J/SRND5
AR_AR*.25 LONG,FE_FE-#,#/34., ;HAVE MOVED LEFT 36, GO RIGHT 2
NORM,J/SNORM ;AND TRY THAT
;WE GET HERE WITH A NORMALIZED POSITIVE FRACTION IN AR'ARX,
; THE CORRECTED EXPONENT IN FE, AND SR INDICATES THE PROPER SIGN
; FOR THE RESULT AND WHETHER THE ANSWER SHOULD BE ROUNDED,
; TRUNCATED, OR LONG.
.IF/FPLONG
=100
.IFNOT/FPLONG
=1*0
.ENDIF/FPLONG
SROUND: BR_AR LONG,AR_0S,J/SRND2 ;PREPARE TO ROUND BY ADDING THE
; PART OF THE FRACTION WE WILL
; DISCARD (CARRY IF ARX0)
BR_AR LONG,CLR AR,ARX_1S, ;TRUNCATE MODE
SR DISP,J/STRNC ; HANDLING DEPENDS ON SIGN
.IF/FPLONG
BR_AR LONG,CLR AR,ARX_1S, ;LONG MODE
SC_#,#/9.
= ARX_SHIFT,SR DISP ;MASK = 0,,000777 TO ARX
=01*
BR_AR LONG,AR_BR LONG,J/SRND4 ;POS, TRUNCATE BY ANDING
AR_AR+BR,ARX/ADX,BR_AR LONG, ;NEG, MUST DIDDLE
NORM,J/SRND3 ; NORM FORCES LONG ARITH
.ENDIF/FPLONG
;HERE TO PERFORM ROUNDING OR TRUNCATION OF SINGLE-PRECISION RESULTS,
; AND CHECK FOR CARRY INTO EXPONENT FIELD REQUIRING RENORMALIZATION
=0*1
STRNC: AR_BR,CLR ARX,J/SRND4 ;POS TRUNCATE, GO STUFF IN EXP
SRND2: AR_AR+BR,NORM,CLR ARX ;NORM FORCES LONG ARITH
; SO THIS ADDS ARX TO BR'BRX
=1*0
SRND3: AR_AR*.5,FE_FE+1 ;RENORMALIZE
SRND4: EXP_FE TST,SR DISP, ;STUFF EXP, CHECK NEG OR LONG
ARX_ARX*BRX,AD/ANDCB ;CLEAR TRUNCATED FRACTION
;HERE TO STORE RESULT AS A FUNCTION OF SINGLE OR LONG PRECISION
; AND POSITIVE OR NEGATIVE...
.IF/FPLONG
=001
.IFNOT/FPLONG
=0*1
.ENDIF/FPLONG
SRND5: SR_0,B WRITE,J/ST6 ;POS & NOT LONG
.IF/FPLONG
SLNG3: AC0_AR,AR_0S,SC_#,#/27.,J/SLNG4 ;STORE HIGH PART OF LONG ANS
.ENDIF/FPLONG
AR_-AR,SR_0,B WRITE,J/ST6 ;NEG & NOT LONG
.IF/FPLONG
AR_-AR LONG,J/SLNG3 ;LONG NEG, MAKE IT SO
SLNG4: AR_SHIFT,I FETCH
AR0-8_FE-SC,BYTE DISP, ;TEST FOR EXP UNDERFLOW
SKP AR EQ ; OR LOW WORD ZERO
=110
.ENDIF/FPLONG
STRAC1: SR_0,J/STAC1 ;PUT AWAY LOW WORD OF LONG RESULT
.IF/FPLONG
AR_0S,SR_0,J/STAC1 ;CLEAR LOW WORD IN AC1
.ENDIF/FPLONG
.TOC "DOUBLE FLOATING ARITHMETIC -- DFAD, DFSB, DFMP, DFDV"
.DCODE
110: R, B/0, J/DFLOAT ;DFAD
R, B/2, J/DFLOAT ;DFSB
R, B/4, J/DFLOAT ;DFMP
R, B/6, J/DFLOAT ;DFDV
.UCODE
=00**0*
DFLOAT: FE_EXP,EXP_SIGN,SC/SCAD,MQ_0.S,
VMA_VMA+1,LOAD ARX,
CALL.S,J/XFERW ;GET LOW WORD
ARX_ARX*2,B DISP ;LOW BIT 0 IGNORED
=
=00*
DFAS: BR_AR LONG,AR_AC1*2,J/DFAS1 ;MEM OP READY, GET AC OP
AR_-AR LONG,J/DFAS ;DFSB, NEGATE AND ADD
AR_AC1,BR_AR LONG, ;HERE FOR DOUBLE FLOATING MUL
FE_#,#/-18.,J/DFMP
GEN AR*AC0,AD/XOR,SKP AD0, ;DFDV. WILL QUO BE NEG?
BR_AR LONG, ;SAVE D'SOR IN BR, BRX
SC_FE-1,J/DFDV
;HERE FOR DFAD AND DFSB
; MEM OPERAND IS IN BR (NEGATED IF DFSB)
; FE AND SC HAVE ITS EXPONENT
=0*0
DFAS1: ARX_AR,AR_AC0,CALL,J/EXPD ;AC OPERAND IN PLACE
=1*0
DFAS2: ARX_AR,AR_SIGN, ;GET SHIFTED HIGH WORD
GEN #+SC,#/-36., ;IS ANY SHIFT REQUIRED?
SKP SCAD0,J/DFAS3
ARX_AR,AR_SIGN, ;DIFF IS > 36
SC_#+SC,#/36.,SKP SCAD0 ;CHECK FOR >72
=0 AC0_AR,MQ_SHIFT,AR_ARX (ADX),
ARX/MQ,J/DFAS4 ;36 < DIFF < 72
AR_BR,ARL/AD,ARX_BRX, ;DIFF >72
MQ_0.M,J/DNTRY ;NORMALIZE LARGER OP
=0
DFAS3: AR_ARX,ARL/SH,ARX/MQ, ;NO SHIFT REQUIRED
MQ_0.M,J/DFAS5
AR_SHIFT ;BEGIN SHIFTING SMALLER OP
AC0_AR,AR_ARX,ARX/MQ ;HI PART TO AC
MQ_SHIFT,AR_ARX (ADX), ;MID PART TO MQ
CLR ARX ;SHIFT ZEROS IN FROM RIGHT
DFAS4: MQ_SHIFT,ARX/MQ,AR_AC0 ;ALL PIECES NOW IN PLACE
DFAS5: AR_AR+BR,ARX/ADX,SC_#,#/4, ;HERE WHEN OPERANDS ALIGNED
NORM,J/DNORM ;ADD, AND NORMALIZE RESULT
;SUBROUTINE TO CHOOSE OPERAND WITH SMALLER EXPONENT, AND
; PREPARE FOR SHIFTING IT.
; ENTER WITH ONE OPERAND FRACTION IN BR, ITS EXPONENT IN FE & SC,
; THE OTHER OP IN AR WITH ITS EXPONENT IN AR0-8
; RETURN THE LARGER EXPONENT IN FE, AND 36-(MAGNITUDE OF DIFFERENCE)
; IN SC. RETURN 4 IF SC POSITIVE, 5 IF NEGATIVE.
EXPD: SC_EXP-SC,EXP_SIGN,SKP SCAD0 ;COMPARE MAGNITUDES
=0 AR_BR,ARX_BRX,BR/AR,BRX/ARX, ;AC OP IS LARGER MAGNITUDE
FE_FE+SC,J/EXPD1 ;ITS EXP TO FE
MQ_ARX,SC_#+SC,#/36., ;CHECK FOR EXP DIFF > 36
SKP SCAD0,RETURN4
EXPD1: MQ_ARX,SC_#-SC,#/36., ;AC EXP .GE. MEM
SKP SCAD0,RETURN4 ;SHIFT MEM OP
;DFMP
; GET HERE WITH MEM OPERAND (M'CAND) IN BR!BRX
; AR HAS (AC1), LOW HALF OF M'IER
=00*
DFMP: MQ_AR,AR_0S,ARX_0S, ;SETUP LOW M'IER
SC_#+SC,#/-200, ;CORRECT EXPONENT
CALL,J/MULREE ;MULTIPLY BY THE LOW PART
=10* AR_AR+BR LONG ;OOPS, LOW SIGN WAS SET
MQ_AR,AR_AC0,FE_#,#/-14. ;READY TO CONTINUE WITH HIGH PART
;HERE TO USE HIGH MULTIPLIER
SC_EXP+SC,EXP_SIGN.M, ;EXTRACT EXP FROM HIGH WORD
SKP AR0 ;CHECK FOR NEG M'IER
=010
DFMP2: MQ_AR,AR_MQ,CALL,J/MULREE ;GO BACK IN FOR HIGH PART
EXP_1,J/DFMP2 ;OOPS, NEG, MOVE SIGN TO BIT 8
=110
DNTRY: SC_#,#/4,GEN AR,NORM,J/DNORM ;NORMALIZE THE ANSWER
=
;DFDV
; GET HERE WITH DIVISOR IN BR!BRX, ITS EXP-1 IN SC
; SKIP IF D'SOR AND D'END SIGNS DIFFER
=000
DFDV: AR_AC1*2,CALL,J/DFDV1 ;GET LOW D'END, GO START DIVIDE
SR_1,AR_AC1*2,CALL,J/DFDV1 ;NOTE NEG QUO
=011 AC1_AR,AR_MQ,ARL/AD,FE_FE+1, ;HERE FROM DDVSUB. NEW STEP CNT
MQ_0.M,CALL.M,J/DIV+ ; SAVE HIGH QUO, RESUME
=101 AC1_AR,AR_MQ,ARL/AD,FE_FE+1,
MQ_0.M,CALL.M,J/DIV-
=111 AR_AC1,ARX/MQ,SC_#,#/4, ;POSITIVE QUOTIENT TO AR LONG
NORM,J/DNORM ;NORMALIZE AND ROUND
=00
DFDV1: ARX_AR,AR_AC0,SKP AD0, ;TEST DIVIDEND SIGN
FE_#,#/26., ;SETUP COUNT FOR HIGH QUO
CALL,J/FDVCHK ;GO CHECK DIVIDABILITY
=10 SKP BR0,J/DDVSUB ;BEGIN DIVISION (RETURN ABOVE)
SET FL NO DIV,J/IFNOP ;ABORT THE DIVISION
.TOC "DOUBLE PRECISION NORMALIZATION"
=000
DNORM: SKP ARX+MQ NE,SC_#,#/35.,J/DNZERO ;AR=0
BR/AR,BRX/ARX,AR_MQ COMP, ;RESULT NEG, MAKE POS
SR_1,J/DNNEG ;FLAG NEGATIVE
AR_AR*.25 LONG,MQ_MQ*.25,
FE_FE+#,#/4,J/DNHI ;MSB IN AR 1-6
AR_AR*.25 LONG,
FE_FE+#,#/2,J/DROUND ;MSB IN AR7
AR_AR*.5 LONG,FE_FE+1 ;MSB IN AR8
DROUND: AR_AR+1,ARX/ADX,NORM, ;MSB IS AR9, RIGHT ON
SC_#,#/35.,J/DRND1
(AR+ARX+MQ)*2,FE_FE-1,J/DROUND ;MSB IN AR10
AR_SHIFT,FE_FE-SC ;SOMEWHERE IN AR 11-35
DNSHFT: BR/AR,AR_ARX,ARX/MQ ;SHIFT THE WHOLE THING
MQ_SHIFT,AR_ARX (ADX),CLR ARX
MQ_SHIFT,ARX/MQ,AR_BR,SC_#,#/10.,
NORM,J/DNORM ;GIVE IT ANOTHER GO
DNNEG: AR_AR+1,SKP CRY0 ;COMPLETE NEGATION OF MQ
=0 MQ_AR,AR_BR COMP,ARX_BRX COMP,
NORM,J/DNORM ;NORMALIZE THE POS FORM

1219
src/ucode/io.51 Executable file

File diff suppressed because it is too large Load Diff

14
src/ucode/its.9 Executable file
View File

@@ -0,0 +1,14 @@
.TOC "MICROCODE CONDITIONAL ASSEMBLY PARAMETERS FOR ITS"
.SET/ITSPAGE=1 ;ITS-STYLE PAGING
.SET/MAP=0 ;NO MAP INSTRUCTION
.SET/PFAIL.PIHACK=1 ;PI OFF ON PAGE FAILURE
.SET/JRSTON=1 ;JRST 17, TURNS ON PI THEN DOES JRST 2,
.SET/LPM.SPM=1 ;LPMR AND SPM INSTRUCTIONS
.SET/XCTR=1 ;XCTR INSTRUCTIONS (PXCT AND PXCTI)
.SET/EIS=0 ;NO STRING STUFF FOR NOW
.SET/DECIMAL=0 ;NO DECIMAL STUFF FOR NOW
.SET/CIRC=1 ;WINNING CIRC INSTRUCTION
.SET/MVSQZ=0 ;RANDOM MVSQZ INSTRUCTION
.SET/KLPAGE=1 ;U CODE CONTROLS PAGE REFILLS
.SET/NXT.INSTR.BITES=0 ;FIXED IN REV 9?

6
src/ucode/jpc.4 Executable file
View File

@@ -0,0 +1,6 @@
.TOC "PARAMETER FILE FOR SINGLE JPC FEATURE"
.SET/JPC.RING=0
.SET/JPC=1
;.SET/NXT.INSTR.BITES=0 ;CAN'T RUN WITH THIS=1, HAS PF GTR 6 TICKS LOSSAGE
;ABOVE COMMENTED OUT SINCE IT IS NOW THE DEFAULT AND PROVOKES A CRUFTY WARNING

5
src/ucode/jpcr.3 Executable file
View File

@@ -0,0 +1,5 @@
.TOC "PARAMETER FILE FOR RING OF 16 JPC'S FEATURE"
.SET/JPC.RING=1
.SET/JPC=1

4
src/ucode/jpctst.2 Executable file
View File

@@ -0,0 +1,4 @@
.TOC "PARAMETER FILE FOR TESTING SINGLE JPC FEATURE"
.SET/JPC TEST=1

126
src/ucode/lisp.18 Executable file
View File

@@ -0,0 +1,126 @@
.TOC "LISP INSTRUCTIONS"
.IF/LISP
;;; MARK: LSPGCM A,FOO
;;; LISP GARBAGE COLLECTION MARK INSTRUCTION.
;;; IF THE GCSTBR IS NOT SET UP, BEHAVES AS A UUO (OPCODE 070).
;;; OTHERWISE, MARKS THE ITEM IN A IF POSSIBLE, THEN RETURNS
;;; TO ONE OF SEVERAL PLACES:
;;; MARK-1 BOTH CAR AND CDR NEED MARKING (CAR IN A, CDR IN A+1)
;;; MARK ONE OF CAR OR CDR NEED MARKING (ITEM IN A)
;;; MARK+1 ITEM ALREADY MARKED, OR NOT MARKABLE
;;; FOO+N BIT 4.8 WAS SET IN GCST TABLE (N=BITS 4.3-4.1),
;;; INDICATING SOMETHING FUNNY LIKE A SYMBOL OR A SAR.
;TO HELP SEE WHAT'S GOING ON, ;AR ARX BR BRX MQ
; REGISTER CONTENTS AFTER EACH STEP ARE SHOWN ;------ ------- ------- ------- -------
;LSPGCM: BR/AR,MQ_AR,AR_GCSTBR,SKP AD NE,J/LGCM0 ;START OF GC MARK INSTR
=0
LGCM0: AR_BR,J/UUO ;GCSTBR NOT SET UP => UUO
SC_#,#/44-SEGLOG,BR/AR,ARX_AC0,AR_0.C ;0 ITEM GCSTBR EFFADR
ARX_SHIFT,AR_ARX (AD) ;ITEM SEG# GCSTBR EFFADR
VMA_ARX+BR,LOAD ARX,AR_SHIFT ;WD#_33 -LOAD- EFFADR
SC_AR0-8 AND #,#/37,BR/AR,AR_0.C ;0 -LOAD- WD#_33 EFFADR
ARX_MEM,AR0-8_#,#/400 ;SETZ TBLENT WD#_33 EFFADR
SKP ARX0,SC_#-SC,#/44,BRX/ARX ;SETZ TBLENT WD#_33 TBLENT EFFADR
=0 I FETCH,J/NOP ;NOT MARKABLE => NEXT INSTRUCTION
AR_ARX (AD),ARX_AR ;TBLENT SETZ WD#_33 TBLENT EFFADR
AR_0S,FE_AR0-8 AND #,
#/207,SKP SCAD NE ;0 SETZ WD#_33 TBLENT EFFADR
;HERE FOR MARKABLE NON-FUNNY THINGS
=0 MQ_SHIFT,AR_BRX,ARX_BR,
SC_#,#/SEGLOG-5,J/LGCM1 ;TBLENT WD#_33 TBLENT MARKBIT
;HERE FOR MARKABLE FUNNY THINGS (SYMBOLS, ETC.)
VMA_MQ,FE_FE-#,#/201,BYTE DISP
=110
LGCM3: VMA_VMA+1,FE_FE-1,BYTE DISP,J/LGCM3 ;LOOP TO GENERATE EFFADR+N
FETCH,J/NOP
LGCM1: ARX_SHIFT,AR_MQ ;MARKBIT BITSADR TBLENT
BR/AR,VMA_ARX,LOAD AR ;-LOAD- MARKBIT TBLENT
AR_MEM ;BITS MARKBIT TBLENT
AD/AND,ADA/AR,ADB/BR,SKP AD NE
=0 I FETCH,J/NOP ;ALREADY MARKED
AR_AR*BR,AD/ANDCB,STORE ;BITS\MARKBIT TBLENT
MEM_AR,AR_BRX ;TBLENT
GEN # AND AR0-8,#/GCBCDR,SKP SCAD NE
=0 I FETCH,J/NOP ;DON'T MARK THROUGH
VMA_AC0,LOAD ARX ;TBLENT -LOAD-
ARX_MEM,VMA/PC,GEN # AND AR0-8,
#/GCBCAR,SKP SCAD NE ; CARCDR
=0 ARL_0.S,ARR_ARXR,J/LGCM2 ;ONLY MARK CDR
ARL_0.S,ARR_ARXR,VMA_VMA-1 ;0,,CDR CARCDR
ARX_AR (AD),SKP AD NE,ARR_0.S,ARL_ARXL ;0,,CAR 0,,CDR
=0 REFETCH,AR_AR SWAP,J/STAC ;CDR IS NIL => MARK ONLY CAR
ARX_AR (AD),SKP AD NE,AR_ARX ;0,,CDR 0,,CAR
=0
LGCM2: REFETCH,J/STAC ;CAR IS NIL => MARK ONLY CDR
AC1_AR,AR_ARX
AR_AR SWAP,FETCH,J/STAC ;CDR IN AC1, CAR IN AC0, RET TO INST-1
;;; SWEEP: LSPGCS A,N
;;; LISP GARBAGE COLLECTION SWEEP INSTRUCTION.
;;; IF THE GCSTBR IS NOT SET UP, BEHAVES AS A UUO (OPCODE 071).
;;; OTHERWISE, SWEEPS UP A SECTION OF MEMORY.
;;; A/ AOBJN POINTER TO REGION OF MEMORY TO SWEEP: <# CELLS>,,<START ADR>
;;; THE CELLS ARE N WORDS LONG.
;;; A+1/ POINTER TO NEXT WORD OF MARK BITS TO USE. A BIT=0 => MARKED.
;;; A+2/ FREELIST (TO BE ADDED TO THE FRONT OF).
;;; A+3/ COUNT OF RECLAIMED CELLS, TO BE INCREMENTED.
;;; THE INSTRUCTION OPERATES IN GROUPS OF 40 WORDS (ONE WORD OF MARK BITS).
;;; IT CHECKS FOR INTERRUPTS ONLY THAT OFTEN, AFTER CHECKPOINTING ITSELF
;;; BACK INTO THE FOUR AC'S. IF A PAGE FAULT OR OTHER MEMORY ERROR OCCURS,
;;; IT WILL RESTART CORRECTLY AT THE BEGINNING OF THE GROUP OF 40 WORDS.
;LSPGCS: BR/AR,SC_EA,AR_GCSTBR,SKP AD NE,J/LGCS0 ;START OF GC SWEEP INSTR
=0
LGCS0: AR_BR,J/UUO ;MAYBE CRAP OUT AS UUO
AR_BR+1000000 ;BR GETS 1,,N (FOR BUMPING AOBJN PTR)
ARX_AC2,BR/AR ;WE STANDARDLY KEEP THE FREELIST IN BRX,
BRX/ARX,VMA_AC1,LOAD ARX ; THE AOBJN PTR IN ARX, THE COUNT IN MQ,
AR_AC3,FE_SC ; AND THE MARK BITS POINTED TO BY AC1
MQ_AR,CLR AR,SC_#,#/40,J/LGCS1 ; IN AR (CONSTANTLY SHIFTED OVER).
=010
LGCS7: NXT INSTR ;DONE, NO INTERRUPT
NXT INSTR ;DONE, INTERRUPT PENDING
LGCS1: ARX_MEM,J/LGCS6 ;NOT DONE, NO INTERRUPT
FIN XFER,REFETCH,J/NOP ;NOT DONE, INTERRUPT PENDING
=
LGCS6: AR_SHIFT,ARX_AR (AD),SC_#,#/4
ARX_AC0,AR_SHIFT,SH DISP,SC_#,#/-40,J/LGCS3
=0**0
LGCS2: AR_AC1+1,VMA/AD,SKP ARX0,J/LGCS4
LGCS3: AR_SHIFT,SH DISP,SC_FE+SC,SKP SCAD0,ARX_ARX+BR,J/LGCS2
AR_AC1+1,VMA/AD,SKP ARX0,J/LGCS4
AR_ARX (AD),ARX_AR
= AR_BR,BR/AR
AR_BRX,ARX_BR,VMA_BR,BR/AR,BRX/ARX,STORE
MEM_AR,AR_MQ+1
MQ_AR,AR_BRX,BRX/ARX,J/LGCS3
=0
LGCS4: I FETCH,AC1_AR,AR_MQ,MQ_ARX,J/LGCS5
LOAD ARX,AC1_AR,AR_MQ,MQ_ARX
LGCS5: AC3_AR,AR_BRX
AC2_AR,AR_MQ
AC0_AR
AD/0S,SIGNS DISP,SKP INTRPT,J/LGCS7
.ENDIF/LISP
.TOC "LISP DEBUGGING INSTRUCTION"
;;; LSPDBG A,
;;; PUTS STBR IN A, GCSTBR IN A+1
;LSPDBG: AR_GCSTBR,J/LSPDB1
LSPDB1: AC1_AR,I FETCH
AR_STBR,J/STAC

4
src/ucode/lithp.2 Executable file
View File

@@ -0,0 +1,4 @@
.TOC "PARAMETER FILE FOR LISP MICROCODE"
.SET/LISP=1

1264
src/ucode/macro.43 Executable file

File diff suppressed because it is too large Load Diff

233
src/ucode/music.16 Executable file
View File

@@ -0,0 +1,233 @@
.TOC "MUSIC MICROCODE"
.IF/MUSIC
;;; MUSIC MICROCODE FOR KL-10
;;;
;;; BASIC SETUP:
;;; THERE ARE SIX VOICES.
;;; MUSIC IS PLAYED BY PUTTING BITS IN A REGISTER
;;; WHICH LIVES IN THE NETWORK IMP INTERFACE. THIS
;;; REGISTER IS LOADED BY A DATAO. THE BITS ARE LOADED
;;; AT SUCH A RATE THAT THE LOW SIX BITS PRODUCE SQUARE
;;; WAVES OF THE CORRECT FREQUENCIES. TO ACCOMPLISH THIS,
;;; THE KL-10'S 10.-USEC INTERVAL TIMER IS USURPED.
;;;
;;; FOR EACH VOICE THERE IS A BASE REGISTER (VNBR),
;;; A TIME (VNTIM, THE INVERSE OF THE FREQUENCY),
;;; AND A COUNTER (VNCTR).
;;; THERE ARE ALSO SEVERAL OTHER REGISTERS:
;;; MUSDEV CONTAINS A DATAO INSTRUCTION TO THE REGISTER.
;;; MUSMIN THE MINIMUM INTERVAL BETWEEN CHANGES TO THE
;;; REGISTER. USED TO PREVENT GOBBLING TOO MUCH
;;; MACHINE TIME. MEASURED IN 10.-USEC UNITS,
;;; WITH THE BINARY POINT BETWEEN THE HALVES
;;; OF THE WORD.
;;; CN7777 CONTAINS 7777, WHICH IS THE MAXIMUM INTERVAL
;;; THE TIMER'S 12.-BIT COUNTER CAN HANDLE.
;;; MUSBT1 THE BITS TO LOAD INTO THE REGISTER WHEN THE
;;; TIMER NEXT GOES OFF.
;;; MUSBT2 THE BITS TO TOGGLE AFTER THE REGISTER IS LOADED.
;;; MUSAOB AN AOBJN POINTER TO THE MUSIC DATA.
;;; MUSTIM THE QUANTITY FOR THE INTERVAL TIMER'S LIMIT
;;; REGISTER AFTER IT NEXT GOES OFF. THIS IS IN
;;; THE LEFT HALF, WITH THE CONTROL BITS FOR THE TIMER.
;;; CHDTIM THE TIME REMAINING FOR THE CURRENT CHORD,
;;; IN 10.-USEC UNITS.
;;; EACH BASE REGISTER POINTS TO A 64.-WORD TABLE. EACH
;;; ENTRY IS THE INVERSE FREQUENCY OF A TONE FOR THAT VOICE,
;;; MEASURED IN 10.-USEC UNITS, WITH THE BINARY POINT
;;; BETWEEN THE HALVES OF THE WORD.
;;; THE AOBJN POINTER POINTS TO A TABLE OF 2-WORD ENTRIES.
;;; THE FIRST WORD OF EACH ENTRY HAS SIX 6-BIT BYTES, ONE
;;; FOR EACH VOICE, THE FIRST VOICE BEING LEFTMOST.
;;; EACH BYTE IS USED AS AN INDEX INTO A VOICE TABLE TO
;;; FETCH AN INVERSE FREQUENCY. THE SECOND WORD IS THE
;;; LENGTH OF THE CHORD IN 10.-USEC TICKS (BINARY POINT
;;; AT THE RIGHT END OF THE WORD). WHEN THIS WORD IS
;;; FETCHED, IT IS WRITTEN BACK WITH THE SIGN BIT SET SO
;;; THAT THE MACRO-CODE CAN CHECK THE PROGRESS OF THE
;;; MUSIC PLAYER.
;;;
;;; THE MUSIC ALGORITHM:
;;; THE INSTRUCTION PLAY=DATAO TIM, IS PUT IN THE FIRST
;;; LOCATION OF THE INTERVAL TIMER'S INTERRUPT VECTOR.
;;; WHEN EXECUTED AS A PI INSTRUCTION, PLAY DOES:
;;;
;;; CONO TIM,<460000+C(MUSTIM)> ;RESET TIMER, RESTART
;;; DATAO MUSREG,MUSBT1
;;; XOR MUSBT2 INTO MUSBT1
;;; SET MUSBT2 TO 0
;;; COMPUTE MUSTIM=LOGAND(<-1,,0>,
;;; MAX(MUSMIN,
;;; MIN(V1CTR, V2CTR, ...,
;;; V6CTR, 7777)))
;;; FOR N FROM 1 TO 6 DO
;;; BEGIN
;;; SUBTRACT MUSTIM FROM V<N>CTR
;;; IF RESULT NEGATIVE, SET BIT IN MUSBT2
;;; FOR VOICE <N>, AND KEEP ADDING
;;; V<N>TIM INTO V<N>CTR UNTIL POSITIVE
;;; END
;;; SUBTRACT MUSTIM FROM CHDTIM
;;; IF RESULT NEGATIVE THEN
;;; IF MUSAOB HAS RUN OUT THEN
;;; TAKE PI CYCLE 2 (SECOND INT INSTR)
;;; ELSE BEGIN
;;; FETCH VOICES WORD (SIX 6-BIT BYTES)
;;; FETCH DURATION WORD, PUT IN CHDTIM
;;; BUMP MUSAOB BY <2,,2>
;;; FOR N FROM 1 TO 6 DO
;;; BEGIN
;;; CLEAR V<N>CTR
;;; FETCH V<N>TIM TO THE WORD
;;; ADDRESSED BY C(V<N>BR)
;;; PLUS A 6-BIT BYTE
;;; END
;;; DISMISS INTERRUPT
;;; END
=0
PLAY0: AR_BR,J/UUO ;IF NOT PI CYCLE, BE A UUO
GET ECL EBUS,AR_AR SWAP
CONO TIM ;START THE TIMER FOR NEXT TICK
REL ECL EBUS
GEN MUSDEV,LOAD IR ;SET UP FOR DATAO TO REGISTER
=10 AR_MUSBT1,CALL,SKP IO LEGAL,J/GTEBUS ;DO THE DATAO
AR_MUSBT2 ;XOR MUSBT2 INTO MUSBT1
AR_AR*MUSBT1,AD/XOR
MUSBT1_AR
AR_CN7777,BRX/ARX ;FIND MIN OF 7777 AND ALL VNCTRS
BR/AR,SKP AR GT FM,V1CTR,ARX/AD ;"SKP GT" IS AN XOR OPERATION
=0
PLAY01: BR/AR,SKP AR GT FM,V2CTR,ARX/AD,J/PLAY23
AR_ARX*BR,AD/XOR,J/PLAY01 ;XOR'ING IN XOR'D QUANTITY
=0
PLAY12: BR/AR,SKP AR GT FM,V3CTR,ARX/AD,J/PLAY23
AR_ARX*BR,AD/XOR,J/PLAY12
=0
PLAY23: BR/AR,SKP AR GT FM,V4CTR,ARX/AD,J/PLAY34
AR_ARX*BR,AD/XOR,J/PLAY23
=0
PLAY34: BR/AR,SKP AR GT FM,V5CTR,ARX/AD,J/PLAY45
AR_ARX*BR,AD/XOR,J/PLAY34
=0
PLAY45: BR/AR,SKP AR GT FM,V6CTR,ARX/AD,J/PLAY56
AR_ARX*BR,AD/XOR,J/PLAY45
=0
PLAY56: BR/AR,SKP AR GT FM,MUSMIN,ARX/AD,J/PLAY6M
AR_ARX*BR,AD/XOR,J/PLAY56
=0
PLAY6M: AR_ARX*BR,AD/XOR ;MAX RESULT WITH MUSMIN
ARL_ARL,CLR/ARR
ARX_-AR-1,P_#,#/6 ;CONTROL BITS FOR TIMER
MUSTIM_AR
;THE THEORY BEHIND USING "ARX_-AR-1" INSTEAD OF "ARX_-AR" IS TO
;AVOID UNFORTUNATE COINCIDENCES WHERE WE REACH ZERO EXACTLY,
;SINCE WE ARE REALLY DOING A SIGN BIT CHECK. THE EXTRA 1 ONLY
;THROWS IT OFF BY (10. USEC)*(2^-18) = .38 PICOSEC.
PLAYV1: AR_ARX+V1CTR,SKP AD0
=0 V1CTR_AR,BRX/ARX,ARX_BRX*2,J/PLAYQ1
BRX/ARX,ARX_BRX*2+1
BRX/ARX,ARX_BRX,J/PLAYZ1
=0
PLAYX1: V1CTR_AR,J/PLAYV2
PLAYZ1: AR_AR+V1TIM,SKP AD0,J/PLAYX1
PLAYQ1: BRX/ARX,ARX_BRX
PLAYV2: AR_ARX+V2CTR,SKP AD0
=0 V2CTR_AR,BRX/ARX,ARX_BRX*2,J/PLAYQ2
BRX/ARX,ARX_BRX*2+1
BRX/ARX,ARX_BRX,J/PLAYZ2
=0
PLAYX2: V2CTR_AR,J/PLAYV3
PLAYZ2: AR_AR+V2TIM,SKP AD0,J/PLAYX2
PLAYQ2: BRX/ARX,ARX_BRX
PLAYV3: AR_ARX+V3CTR,SKP AD0
=0 V3CTR_AR,BRX/ARX,ARX_BRX*2,J/PLAYQ3
BRX/ARX,ARX_BRX*2+1
BRX/ARX,ARX_BRX,J/PLAYZ3
=0
PLAYX3: V3CTR_AR,J/PLAYV4
PLAYZ3: AR_AR+V3TIM,SKP AD0,J/PLAYX3
PLAYQ3: BRX/ARX,ARX_BRX
PLAYV4: AR_ARX+V4CTR,SKP AD0
=0 V4CTR_AR,BRX/ARX,ARX_BRX*2,J/PLAYQ4
BRX/ARX,ARX_BRX*2+1
BRX/ARX,ARX_BRX,J/PLAYZ4
=0
PLAYX4: V4CTR_AR,J/PLAYV5
PLAYZ4: AR_AR+V4TIM,SKP AD0,J/PLAYX4
PLAYQ4: BRX/ARX,ARX_BRX
PLAYV5: AR_ARX+V5CTR,SKP AD0
=0 V5CTR_AR,BRX/ARX,ARX_BRX*2,J/PLAYQ5
BRX/ARX,ARX_BRX*2+1
BRX/ARX,ARX_BRX,J/PLAYZ5
=0
PLAYX5: V5CTR_AR,J/PLAYV6
PLAYZ5: AR_AR+V5TIM,SKP AD0,J/PLAYX5
PLAYQ5: BRX/ARX,ARX_BRX
PLAYV6: AR_ARX+V6CTR,SKP AD0
=0 V6CTR_AR,BRX/ARX,ARX_BRX*2,AR_ARX,J/PLAYQ6
BRX/ARX,ARX_BRX*2+1
BRX/ARX,ARX_BRX,J/PLAYZ6
=0
PLAYX6: V6CTR_AR,J/PLAY40
PLAYZ6: AR_AR+V6TIM,SKP AD0,J/PLAYX6
PLAYQ6: BRX/ARX,ARX_BRX
PLAY40: AR_BRX,ARX_AR SWAP
MUSBT2_AR
AR_ARX+CHDTIM,SKP AD0
=0 CHDTIM_AR,J/PIDONE
AR_MUSAOB+1,GEN CRY18,SKP AD0
=0 J/PICY2V
VMA_AR,LOAD ARX
AR_AR+1,GEN CRY18
MUSAOB_AR
ARX_MEM
VMA_VMA+1,LOAD AR
AR_MEM
CHDTIM_AR
P_P OR #,#/40,STORE
MEM_AR,AR_0S,SC_#,#/6
V1CTR_AR,ARX_SHIFT,AR_ARX (AD)
VMA_ARX+FM,V1BR,ARX_SHIFT,LOAD AR
AR_MEM
V1TIM_AR,AR_0S
V2CTR_AR,ARX_SHIFT,AR_ARX (AD)
VMA_ARX+FM,V2BR,ARX_SHIFT,LOAD AR
AR_MEM
V2TIM_AR,AR_0S
V3CTR_AR,ARX_SHIFT,AR_ARX (AD)
VMA_ARX+FM,V3BR,ARX_SHIFT,LOAD AR
AR_MEM
V3TIM_AR,AR_0S
V4CTR_AR,ARX_SHIFT,AR_ARX (AD)
VMA_ARX+FM,V4BR,ARX_SHIFT,LOAD AR
AR_MEM
V1TIM_AR,AR_0S
V5CTR_AR,ARX_SHIFT,AR_ARX (AD)
VMA_ARX+FM,V5BR,ARX_SHIFT,LOAD AR
AR_MEM
V1TIM_AR,AR_0S
V6CTR_AR,ARX_SHIFT,AR_ARX (AD)
VMA_ARX+FM,V6BR,ARX_SHIFT,LOAD AR
AR_MEM
V6TIM_AR,J/PIDONE
.ENDIF/MUSIC

4
src/ucode/muzak.2 Executable file
View File

@@ -0,0 +1,4 @@
.TOC "PARAMETER FILE FOR MUSIC MICROCODE"
.SET/MUSIC=1

209
src/ucode/shift.6 Executable file
View File

@@ -0,0 +1,209 @@
.TOC "ROTATES AND LOGICAL SHIFTS -- ROT, LSH, JFFO"
.DCODE
240: I, B/0, J/ASH
I, B/0, J/ROT
I, B/2, J/LSH
I, J/JFFO
I, B/1, J/ASHC
I, J/ROTC
I, J/LSHC
.IFNOT/CIRC
I, J/UUO
.IF/CIRC
I, J/CIRC
.ENDIF/CIRC
.UCODE
;ENTER WITH 0,E IN AR
; NOTE THAT VALUES OF SC GREATER THAN 36
; CAUSE THE SHIFTER TO SELECT ARX.
=00***0
LSH: AR_AC0,ARL/AD,ARX_0.M,SC_EA,
SKP AR18,J/SHR1
JFFO: AR_AC0,SKP AD NE,SC_#,#/6
=
=0 AC1_AR,I FETCH,J/NOP ;AC WAS ZERO, NO JUMP
ARX+MQ_0.M,FE_P,SKP SCAD NE, ;TEST FIRST 6 BITS
AR_SHIFT,ARL/SH ;DISCARD THEM
=1****0
JFFO1: AR_SHIFT,FE_P,SKP SCAD NE, ;TEST NEXT 6 BITS
ARX_ARX-1,J/JFFO1 ;LOOP, COUNTING, TILL NE
P_FE,ARR_0.S, ;RESTORE 6 NON-ZERO BITS
ARX_ARX*-6 ;GET POS GROUP COUNT*6
=*1***0
JFFO2: SKP AR0,AR_2(AR+1), ;LOOP TO FIND A 1
ARX_ARX+1,J/JFFO2 ;COUNTING AS WE GO
.IFNOT/JPC
AR_ARX-1,FETCH,J/STRAC1
.IF/JPC
AR_ARX-1,FETCH,SKP USER
=0 AC1_AR,AR_PC,SC_#,#/32.,J/JPCEX
AC1_AR,AR_PC,SC_#,#/32.,J/JPCUSR
.ENDIF/JPC
=00***0
ASH: SC_EA,SKP AR18, ;GET SHIFT AMOUNT
AR_0S,J/ASHL ;SET LOW PART = 0
ROT: AR_AC0,ARX_AC0,SC_EA,SKP AR18
=
;SINGLE-WORD LSH/ROT
; FOR ROT, B=0, AR AND ARX BOTH CONTAIN AC
; FOR LSH, B=2, AR HAS AC, ARX IS ZERO
=00
SHR1: AR_SHIFT,SC_#+SC,#/-36., ;DO POS (LEFT) SHIFT, CHK RANGE
SKP SCAD0,J/SHR2
ARX_AR (AD),AR_ARX (ADX),
SC_#+SC,#/36.,
B DISP,SKP SCAD0,J/SHR1 ;MAKE NEG SHIFT TO EQUIV POS
SHR2: AR_SHIFT,SC_#+SC,#/-36.,
SKP SCAD0,J/SHR2 ;BRING SC INTO RANGE
AC0_AR,I FETCH,J/NOP ;DONE
.TOC "ROTATE AND LOGICAL SHIFT COMBINED -- ROTC, LSHC"
=00***0
ASHC: SC_EA,SKP AR18, ;SETUP SHIFT COUNT
AR_AC1*2,J/ASHL ;GET LOW WORD
ROTC: ARX_AC1
= AR_AC0,SC_EA,SKP AR18 ;SETUP BOTH AC'S
=1****0
ROT3: MQ_SHIFT,ARX_AR (AD),
AR_ARX (ADX),J/ROT4
ARX_AR (AD),AR_ARX (ADX),
SC_#+SC,#/36.,SKP SCAD0,J/ROT3
ROT4: AR_MQ,ARX_SHIFT,
SC_#+SC,#/-36.,SKP SCAD0
=0 MQ_SHIFT,ARX_AR (AD),
AR_ARX (ADX),J/ROT4
STDAC: AC0_AR,AR_ARX,I FETCH,J/STRAC1
.IFNOT/CIRC
1004: ;NEXT TO UUO
.IF/CIRC
=00**00
.ENDIF/CIRC
LSHC: ARX_AC1,MQ_0.M,J/LSHC1
.IF/CIRC
=01
CIRC: MQ_AR,AR_AC1,FE_#,SC_#,#/35.,CLR ARX,CALL,J/WDREV
=11 SC_EA,AR_AC0,SKP AR18,J/CIRC3
.ENDIF/CIRC
=
LSHC1: AR_AC0,SC_EA,FE_#,#/36.,SKP AR18
=*1***0
LSH2: MQ_SHIFT,AR_ARX (ADX),
ARX/MQ,FE_#,#/-36.,J/LSH3
ARX_AR (AD),AR_0.M,MQ_ARX,
SC_FE+SC,SKP SCAD0,J/LSH2
LSH3: AR_MQ,ARL/AD,ARX_SHIFT,MQ_0.M,
SC_FE+SC,SKP SCAD0
=0 MQ_SHIFT,AR_ARX (ADX),ARX/MQ,J/LSH3
AC0_AR,AR_ARX,I FETCH,J/STRAC1
.TOC "CIRC INSTRUCTION"
.IF/CIRC
=1****0
CIRC3: MQ_SHIFT,ARX_AR (AD),AR_ARX (ADX),J/CIRC4
ARX_AR (AD),AR_ARX (ADX),SC_#+SC,#/36.,SKP SCAD0,J/CIRC3
CIRC4: AR_MQ,ARX_SHIFT,SC_#+SC,#/-36.,SKP SCAD0
=1***00
MQ_SHIFT,ARX_AR (AD),AR_ARX (ADX),J/CIRC4
AC0_AR,AR_ARX,FE_#,SC_#,#/35.,ARX_0S,CALL,J/WDREV
=11 AR_ARX,CLR SC,I FETCH,J/STD1
;SUBROUTINE TO REVERSE A WORD IN AR, RETURNING IT IN ARX.
;ON ENTRY, ARX MUST BE CLEAR, AND SC AND FE MUST BOTH CONTAIN 35.
;ON EXIT, MQ IS COPIED INTO AR.
.IFNOT/CIRC.BIG.OPT
=*1***0
WDREV: BRX/ARX,SH DISP,J/WDREV1
AR_MQ,RETURN2
=1*0111
WDREV1: FE_FE-1,SC/SCAD,SKP SCAD0,ARX_BRX*2,J/WDREV
FE_FE-1,SC/SCAD,SKP SCAD0,ARX_BRX*2+1,J/WDREV
.IF/CIRC.BIG.OPT
=1****0
WDREV: SH DISP,BR/AR,AR_ARX (ADX),SC_#,#/32.,J/WDREV1
AR_MQ,RETURN2
=1*0000
WDREV1: AR_BR,ARX_SHIFT,FE_FE-#,#/4,SC/SCAD,SKP SCAD0,J/WDREV
AR_SHIFT,SC_#,#/10,J/WDREV2
AR_SHIFT,SC_#,#/4,J/WDREV2
AR_SHIFT,SC_#,#/14,J/WDREV2
AR_SHIFT,SC_#,#/2,J/WDREV2
AR_SHIFT,SC_#,#/12,J/WDREV2
AR_SHIFT,SC_#,#/6,J/WDREV2
AR_SHIFT,SC_#,#/16,J/WDREV2
AR_SHIFT,SC_#,#/1,J/WDREV2
AR_SHIFT,SC_#,#/11,J/WDREV2
AR_SHIFT,SC_#,#/5,J/WDREV2
AR_SHIFT,SC_#,#/15,J/WDREV2
AR_SHIFT,SC_#,#/3,J/WDREV2
AR_SHIFT,SC_#,#/13,J/WDREV2
AR_SHIFT,SC_#,#/7,J/WDREV2
AR_SHIFT,SC_#,#/17,J/WDREV2
WDREV2: AR0-5_AR0-5 OR SC
AR_BR,ARX_AR,FE_FE-#,#/4,SC/SCAD,SKP SCAD0,J/WDREV
.ENDIF/CIRC.BIG.OPT
.ENDIF/CIRC
.TOC "ARITHMETIC SHIFTS -- ASH, ASHC"
;COMMON CODE FOR ARITHMETIC SHIFTS
=*1***0
ASHL: ARX_AR,AR_AC0, ;INPUT NOW IN AR LONG
SKP SC NE,J/ASHL1 ;CHECK FOR NULL SHIFT
ARX_AR,AR_AC0, ;HERE IF RIGHT SHIFT
SC_#+SC,#/36.,SKP SCAD0 ;CHECK FOR LONG ONE
=1****0
ASHR1: BR/AR,ARX_SHIFT,AR_SIGN,J/ASHR2 ;LOW OUTPUT TO ARX
ARX_AR,AR_SIGN, ;HERE IF SHIFT COUNT .GT. 36
SC_#+SC,#/36., ;BRING COUNT UP BY 36
SKP SCAD0,J/ASHR1 ;LOOP TILL COUNT REASONABLE
ASHR2: BRX/ARX,ARX_BR, ;HIGH INPUT TO ARX
B DISP,J/ASHX
;HERE FOR LEFT ARITHMETIC SHIFT
=*1***0
ASHL1: I FETCH,J/NOP ;SHIFT 0 IS A NOP
BR_AR LONG,AR_SIGN ;SAVE INPUT, GEN SIGN WORD
BR/AR,AR_BR*2 LONG ;SAVE SIGN, GET MAGNITUDE BITS
=0*
ASHL2: BRX/ARX,ARX_AR,AR_BR, ;HI IN TO ARX, LOW TO BRX
CALL,J/SHIFT ;CALL SHIFTER TO GET BITS LOST
SKP AR SIG ;ANY SIGNIFICANT BITS?
=1****0
ASHL3: AR_ARX,ARX_BRX, ;RESTORE HI TO AR, LOW TO ARX
GEN #+SC,#/-36.,SKP SCAD0,J/ASHL4
SET AROV,J/ASHL3 ;BITS SHIFTED OUT NE SIGN
=*1***0
ASHL4: AR_ARX,ARX_0S, ;HERE IF E .GT. 36
SC_#+SC,#/-36.,J/ASHL2 ;SHIFT 36 PLACES, TRY AGAIN
MQ_SHIFT,AR_BRX,CLR ARX, ;HIGH OUTPUT TO MQ,
SC_#+SC,#/-1,B DISP ;COMPENSATE FOR EXTRA SHIFT
=1****0
ASHL5: AR_BR,BRX/ARX,ARX/MQ, ;SIGN TO AR, HIGH OUT TO ARX
SC_#,#/35., ;READY TO COMBINE THEM
B DISP,J/ASHX ;STORE AS APPROPRIATE
ARX_SHIFT,J/ASHL5 ;LOW OUTPUT TO ARX
;HERE TO GET FINAL RESULTS.
=*1***0
ASHX: AR_SHIFT,I FETCH,J/STORAC ;HERE AFTER ASH
AR_SHIFT,ARX_BRX, ;HERE AFTER ASHC
SC_#,#/35.,J/ST2AC

957
src/ucode/skpjmp.32 Executable file
View File

@@ -0,0 +1,957 @@
.TOC "TEST GROUP"
.DCODE
600: I-PF, J/TDN ;TRN- IS NOP
I-PF, J/TDN ;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-PF, J/TDN ;TDN- IS A NOP
I-PF, J/TDN ;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 1 AND 2 AS FOLLOWS:
; 0 0 NO MODIFICATION
; 0 1 ZEROS
; 1 0 COMPLEMENT
; 1 1 ONES
; THIS ORDER HAS NO SIGNIFICANCE EXCEPT THAT IT CORRESPONDS TO THE
; ORDER OF INSTRUCTIONS AT TGROUP.
;THE HIGH ORDER BIT OF THE B FIELD (B0) IS XOR'D WITH AD CRY0 TO
; DETERMINE THE SENSE OF THE SKIP:
; 0 SKIP IF CRY0=1 (TXX- AND TXXN)
; 1 SKIP IF CRY0=0 (TXXA AND TXXE)
=00*000
TDX: TEST FETCH,NO CRY, ;TDXA AND TRXA
B DISP,J/TDN
TSX: AR_AR SWAP,TEST FETCH,NO CRY, ;TSX, TSXA, TLX, AND TLXA
B DISP,J/TDN
TSXX: AR_AR SWAP ;TSXE, TSXN, TLXE, AND TLXN
TDXX: TEST AR.AC0,TEST FETCH,B DISP ;TDXE, TDXN, TRXE, AND TRXN
TDN: J/FINI ;NO MODIFICATION
TDZ: AR_AR*AC0,AD/ANDCA,TIME/2T,J/STAC ;ZEROS
TDC: AR_AR*AC0,AD/XOR,TIME/2T,J/STAC ;COMP
TDO: AR_AR*AC0,AD/OR,TIME/2T,J/STAC ;ONES
=
.TOC "COMPARE -- CAI, CAM"
.DCODE
300: I, SJC-, J/CAIM ;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
=00****
CAIM: GEN AR*AC0,COMP FETCH,J/NOP
=
.TOC "ARITHMETIC SKIPS -- AOS, SOS, SKIP"
;ENTER WITH (E) IN AR
.DCODE
330: R, SJC-, J/SKIP ;NOT A NOP IF AC .NE. 0
R, SJCL, J/SKIP
R, SJCE, J/SKIP
R, SJCLE, J/SKIP
R, SJCA, J/SKIP
R, SJCGE, J/SKIP
R, SJCN, J/SKIP
R, SJCG, J/SKIP
.UCODE
=00****
SKIP: FIN STORE,SKIP FETCH,
SKP AC#0,J/STSELF ;STORE IN SELF MODE
=
.DCODE
350: RPW, SJC-, J/AOS
RPW, SJCL, J/AOS
RPW, SJCE, J/AOS
RPW, SJCLE, J/AOS
RPW, SJCA, J/AOS
RPW, SJCGE, J/AOS
RPW, SJCN, J/AOS
RPW, SJCG, J/AOS
.UCODE
=00****
AOS: AR_AR+1,AD FLAGS,STORE,J/SKIP
=
.DCODE
370: RPW, SJC-, J/SOS
RPW, SJCL, J/SOS
RPW, SJCE, J/SOS
RPW, SJCLE, J/SOS
RPW, SJCA, J/SOS
RPW, SJCGE, J/SOS
RPW, SJCN, J/SOS
RPW, SJCG, J/SOS
.UCODE
=00****
SOS: AR_AR-1,AD FLAGS,STORE,J/SKIP
=
.TOC "CONDITIONAL JUMPS -- JUMP, AOJ, SOJ, AOBJ"
; ENTER WITH E IN VMA
.DCODE
320: I, SJC-, J/JUMP
I, SJCL, J/JUMP
I, SJCE, J/JUMP
I, SJCLE, J/JUMP
I, SJCA, J/JUMP
I, SJCGE, J/JUMP
I, SJCN, J/JUMP
I, SJCG, J/JUMP
.UCODE
=00****
.IFNOT/JPC
JUMP: AR_AC0,JUMP FETCH,J/NOP
.IF/JPC
JUMP: AR_AC0,JUMP FETCH,B DISP,J/JMPJPC
.ENDIF/JPC
=
.DCODE
340: I, 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
=00****
.IFNOT/JPC
AOJ: AR_AC0+1,AD FLAGS,JUMP FETCH,J/STORAC
.IF/JPC
AOJ: AR_AC0+1,AD FLAGS,JUMP FETCH,J/AOJJPC
.ENDIF/JPC
=
.DCODE
360: I, 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
;THE BASIC INSTRUCTION DISPATCH LOADS MQ WITH -1
;SO THAT WHEN WE GET HERE WE CAN ADD -1 TO THE AC IN
;A SINGLE MICRO-INSTRUCTION.
=00****
.IFNOT/JPC
SOJ: AR_MQ+AC0,AD FLAGS,JUMP FETCH,J/STORAC
.IF/JPC
SOJ: AR_MQ+AC0,AD FLAGS,JUMP FETCH,J/SOJJPC
.ENDIF/JPC
=
.DCODE
252: I, SJCGE, J/AOBJ
I, SJCL, J/AOBJ
.UCODE
=00****
.IFNOT/JPC
AOBJ: AR_AC0+1,GEN CRY18,JUMP FETCH,J/STORAC
.IF/JPC
AOBJ: AR_AC0+1,GEN CRY18,JUMP FETCH,J/AOBJPC
.ENDIF/JPC
=
.TOC "AC DECODE JUMPS -- JRST, JFCL"
.DCODE
254: I, J/JRST ;DISPATCHES TO 1 OF 16 ON AC BITS
I,TNN, J/JFCL
.UCODE
;A READ DETECTS JRST, AND DISPATCHES TO ONE OF 16 LOC'NS ON AC BITS
600: ;DRAM REQUIRES JRST AT MULTIPLE OF 200
.IFNOT/JPC
JRST: J/FINI ;(0) A READ PREFETCHES ON JRST 0,
.IF/JPC
JRST: AR_PC,SKP USER, ;(0) A READ PREFETCHES - GO STORE JPC
SC_#,#/32.,J/JPCEX
.ENDIF/JPC
601:
.IFNOT/ITSPAGE
PORTAL,BR/AR,J/BRJMP ;(1) PORTAL
.IF/ITSPAGE
BR/AR,J/BRJMP ;(1) NO PUBLIC PAGES => NO PORTAL
.ENDIF/ITSPAGE
602:
JRST2: EA MOD DISP,BR/AR,AR_ARX, ;(2) JRSTF
SC_#,#/9,J/JRSTF
603: J/UUO ;(3)
604: HALT,SKP IO LEGAL,J/IHALT ;(4) HALT
605: J/UUO ;(5)
606: J/UUO ;(6)
607: J/UUO ;(7)
610: DISMISS,BR/AR,J/BRJMP ;(10)
611: J/UUO ;(11)
612: DISMISS,J/JRST2 ;(12) JEN
613: J/UUO ;(13)
614: J/UUO ;(14)
615: J/UUO ;(15)
616: J/UUO ;(16)
617:
.IFNOT/JRSTON
J/UUO ;(17)
.IF/JRSTON
JRST17: BR/AR,BRX/ARX,AR_1,GEN CRY18, ;(17) JRSTON
ARX/AD,SC_#,#/7,J/JRSTON
.ENDIF/JRSTON
;JRST AND RESTORE FLAGS HAIR
=11***0
JRSTF: AR_PC,RSTR FLAGS_AR,J/JRSTF1 ;RESTORE FROM INDIRECT WORD
AR_XR,J/JRSTF ;INDEXED, RESTORE FROM REGISTER
;JRST AND RESTORE FLAGS HAIR - ONE-PROCEED VERSION.
;WE HAVE TO PREVENT JRSTF FROM TURNING OFF THE TRAP FLAGS.
;THIS MAKES ONE-PROCEED THROUGH JRST 2, WORK.
;IT DOESN'T HURT ANYTHING BECAUSE THE TRAP FLAGS NEVER NORMALLY
;STAY ON DURING EXECUTION OF AN INSTRUCTION.
;MUST COME TO JRSTF WITH 9 IN SC DUE TO DISP/SPEC & # CONFLICT.
;
;EVEN GROSSER HAIR- IF WE TOOK A PAGE FAULT ON THE INSTRUCTION
;FETCH AT THE NICOND, COULD DO AN ABORT INSTR AND LOSE THE
;TRAP FLAGS. MOSTLY THIS SCREWS ONE-PROCEED, BUT IT COULD
;SCREW OVERFLOW TRAPS IF INTERRUPTED OUT OF THEN THE PAGE
;SWAPPED OUT BEFORE PROGRAM RESUMED.
;TO FIX THIS WE DO 'SR_JRSTF' AND LET THE INSTRUCTION
;CLEAN-UP HANDLER TAKE CARE OF THE FLAGS.
;YET GROSSER HAIR! IN ORDER TO STORE THE RIGHT JPC,
;JRSTF DOES AR_PC AND THEN THE USER MODE FLAG IN THERE
;IS CHECKED, SINCE THE ONE IN THE HARDWARE HAS BEEN
;CLOBBERED BY THIS TIME. TO AVOID USING # TO DO THIS,
;JRSTF1 HAS TO PUT 1 INTO SC (USER = PC BIT 05 = LOW P BIT)
.IFNOT/ONE PROCEED
JRSTF1: SR_JRSTF,SC_1,J/BRJRF
.IF/ONE PROCEED
JRSTF1: SR_JRSTF,SC_1,SH DISP,J/BRJRF ;DISPATCH ON OLD TRAP BITS
=1*0011
.ENDIF/ONE PROCEED
.IFNOT/JPC
BRJRF:
BRJMP: VMA_BR,FETCH,J/NOP
.IF/JPC
BRJRF: VMA_BR,FETCH,GEN P AND SC,SKP SCAD NE,J/JPCEX
.ENDIF/JPC
.IF/ONE PROCEED ;DISP TABLE AFTER BRJRF
TRAP1,J/BRJRF ;TURN TRAP 1 BACK ON
TRAP2,J/BRJRF ;TURN TRAP 2 BACK ON
TRAP3,J/BRJRF ;TURN TRAP 3 BACK ON
.ENDIF/ONE PROCEED
.IF/JPC
BRJMP: VMA_BR,FETCH,J/JPCIFY
.ENDIF/JPC
.IF/JRSTON
;OKAY TO DO THIS INSTR IN USER MODE, SINCE WHEN IN
; USER MODE THE PI SYSTEM SHOULD BE ON ANYWAY.
;THIS INSTRUCTION IS USEFUL IN CONJUNCTION WITH THE
; PFAIL.PIHACK BUSINESS.
=*1**00
JRSTON: AR_SHIFT,ARX_BRX,REQ EBUS,CALL,J/WGRANT ;GOBBLE EBUS
=11 CONO PI ;TURN ON PI SYSTEM
.IF/ONE PROCEED
SC_#,#/9 ;SET UP SC FOR JRSTF
.ENDIF/ONE PROCEED
REL EBUS,AR_ARX, ;RELEASE EBUS, THEN
EA MOD DISP,J/JRSTF ; GO DO A JRSTF
.ENDIF/JRSTON
700: ;JFCL MUST BE AT JRST+100
JFCL: ARX_BRX,SC_#,#/13. ;GET BACK AC FIELD
=1***0*
AR_SHIFT,ARX_0S, ;MOVE AC TO AR32-35
SC_#,#/32.,CALL,J/SHIFT ;SHIFTER WILL MOVE TO 0-3
BR/AR,AR_PC,JFCL T ;GET PC FLAGS INTO AR
.IFNOT/JPC
TEST AR.BR,JFCL FETCH ;JUMP IF TEST SATISFIED
AR_AR*BR,AD/ANDCB ;CLEAR TESTED FLAGS IN AR
JFCL S,J/FINI ;SET PC FROM THEM
.IF/JPC
ARX_AR*BR,AD/ANDCB,SC_#,#/32. ;SET UP SC FOR JPC RING
TEST AR.BR,JFCL FETCH,AR_ARX,SKP CRY0
=*1***0
JFCL S,J/FINI ;NO JUMP, ALL DONE
JFCL S,AR_PC,SKP USER,J/JPCEX ;JUMP, GO RECORD JPC
.ENDIF/JPC
.TOC "HALT LOOP"
;HERE WHILE PROCESSOR IS "HALTED"
1016:
UUO107: ;OP 107 COMES HERE
IHALT: J/UUO ;HERE IF HALT IN USER/SUPER MODE
1017:
DHALT: AR_0S,SET HALTED, ;KERNEL OR CONSOLE HALT
VMA/PC,PC_VMA ; IF JRST 4, COPY EA TO PC
=1****0
HALT1: SKP -START,TIME/3T, ;CHECK FOR CONTINUE BUTTON
FE_AR0-8,ARX_AR,J/HALT2 ;PICK UP OPCODE IN CASE XCT
TAKE INTRPT ;HERE IF EXAMINE/DEPOSIT UP
=1****0
HALT2: GEN FE-1,BYTE DISP,CONTINUE,J/UNHALT ;INSTR FROM SWITCHES?
SKP INTRPT,J/HALT1
=110
UNHALT: SET CONS XCT,J/UXCT ;XCT ONE FROM "SWITCHES"
SKP AR EQ,J/START ;NOT AN INSTR. START, OR CONT?
.TOC "MAP, XCT"
.DCODE
256: R, J/XCT ;OPERAND FETCHED AS DATA
.IF/MAP
I, AC, J/MAP
.IFNOT/MAP
J/UUO
.ENDIF/MAP
.UCODE
.IF/MAP
=00***0
.IFNOT/MAP
1001: ;GET XCT NEAR UUO
.ENDIF/MAP
.IFNOT/XCTR
XCT: SKP INTRPT,J/XCT1 ;CHECK FOR XCT . LOOP
.IF/XCTR
XCT: SKP INTRPT,J/UXCT ;CHECK FOR XCT LOOP
.ENDIF/XCTR
.IF/MAP
MAP: MAP,BR/AR ;MAP E, GO READ BACK EBRG
=
.IF/KLPAGE ;IN KL PAGING MODE,
SR_MAP ;MAP CAN PAGE FAIL
.ENDIF/KLPAGE
.IFNOT/MAP
.IFNOT/XCTR
=
.ENDIF/XCTR
.ENDIF/MAP
=11***0
RDEBRG: AR_0S,SKP IO LEGAL,MB WAIT, ;FINISH READ REG FUNC
CALL,J/GETEEB ;AND GET EBUS
AR_EBUS REG ;READ DATA
REL ECL EBUS,B WRITE,J/ST6 ;GIVE IT TO USER
.TOC "ITS PAGE MAP INSTRUCTIONS -- LPM, SPM"
;THE WORDS LOADED OR STORED BY LPM AND SPM ARE AS FOLLOWS:
; (E) JPC (OR JPC RING POINTER)
; (E+1) ADDRESS BREAK WORD
; (E+2) PFW AS OF MOST RECENT PAGE FAIL
; (E+3) DBR1
; (E+4) DBR2
.IF/LPM.SPM
=00**00
LPM: ARX_AR,VMA_VMA+1,LOAD AR,J/LPM1 ;ARX_JPC,FETCH MAR
=10
SPM: CALL,SKP KERNEL,J/IOCHK ;SPM OKAY ONLY IN KERNEL MODE
.IFNOT/JPC SUPPORT
VMA_VMA+1
=
.IF/JPC SUPPORT
AR_JPC,STORE
= MEM_AR,VMA_VMA+1
.ENDIF/JPC SUPPORT
AR_UPFW,STORE,VMA_VMA+1
MEM_AR,VMA_VMA+1
AR_DBR1,STORE
MEM_AR,VMA_VMA+1
AR_DBR2,STORE,J/STMEM
=11***0
LPM1: AR_MEM,CALL,SKP KERNEL,J/GETEEB ;LPM LEGAL ONLY IN KERNEL MODE
DATAO APR
REL ECL EBUS,AR_ARX
.IF/JPC SUPPORT
JPC_AR
.ENDIF/JPC SUPPORT
VMA_VMA+1,LOAD AR
AR_MEM,VMA_VMA+1
BAG-BITING NO-OP
UPFW_AR,LOAD AR
AR_MEM,VMA_VMA+1
BAG-BITING NO-OP
DBR1_AR,LOAD AR
AR_MEM
BAG-BITING NO-OP
DBR2_AR,J/CLRPT1 ;REALLY LPMR - CLEAR PAGE TABLE
.ENDIF/LPM.SPM
.TOC "STACK INSTRUCTIONS -- PUSHJ, PUSH, POP, POPJ"
.DCODE
260: I, J/PUSHJ
R, B/0, J/PUSH
W, J/POP
I, J/POPJ
.UCODE
;PUSHJ
; ENTER WITH E IN AR
;PUSH
; ENTER WITH (E) IN AR
=00***0
PUSH: ARX_AC0+1,GEN CRY18,SKP CRY0, ;BUMP BOTH HALVES OF AC,
VMA/AD,STORE,J/STMAC ;PUT AR ONTO LIST
PUSHJ: BR/AR,AR_PC+1 ;SAVE JUMP ADDR, GET PC
= ARX_AC0+1,GEN CRY18,SKP CRY0, ;COMPUTE STACK ADDRESS
VMA/AD,STORE,J/JSTAC ;AND PREPARE TO STORE PC
=*1**00
JRA1: VMA_AR,LOAD ARX,CALL,J/XFERW ;GET SAVED AC
=10
.IFNOT/JPC
JSTAC: FIN STORE,VMA_BR,FETCH, ;STORE PC, JUMP ADDR TO VMA
AR_ARX,J/STORAC ;PREPARE TO STORE AC VALUE
.IF/JPC
JSTAC: FIN STORE,VMA_BR,FETCH, ;STORE AC, THEN RECORD JPC
AR_ARX,SKP USER,J/JPCSTO
.ENDIF/JPC
MEM_AR,TRAP2,J/JSTAC ;CAUSE PDL OVRFLO
=1****0
STMAC: FIN STORE,I FETCH, ;STORE RESULT, GET NEXT INSTR
AR_ARX,B DISP,J/STSELF ;STORE AC IF B=0
MEM_AR,TRAP2, ;PDL OVFLO, CAUSE TRAP
AR_ARX,J/IFSTAC ;UPDATE AC BEFORE TRAPPING
;POP, POPJ
=00***0
;ENTER WITH C(AC) IN AR, E IN BR, OK TO WRITE IN E
POP: VMA_AR,LOAD ARX,J/POP1 ;BEGIN DATA FETCH FROM STACK
;ENTER WITH E IN AR
POPJ: AR_AC0,VMA/AD,LOAD ARX ;START FETCH FROM STACK
= AR_AR-1,INH CRY18,SKP CRY0 ;DECR STACK POINTER, CHECK UNDERFLOW
.IFNOT/JPC.RING
=*1***0
ARX_MEM,TRAP2,J/POPJ1 ;UNDERFLOW OCCURRED
ARX_MEM ;GET STACK WORD
.IFNOT/JPC
POPJ1: AC0_AR,VMA_ARX,FETCH,J/NOP ;SET NEW AC VALUE, JUMP
.IF/JPC
POPJ1: AC0_AR,VMA_ARX,FETCH,J/JPCIFY
.ENDIF/JPC
.IF/JPC.RING
=*1***0
ARX_MEM,TRAP2 ;TWO TICKS SLOWER ON OVERFLOW, BUT WHO CARES?
ARX_MEM,SKP USER,SC_#,#/32. ;JPC.RING NEEDS 32. IN SC
AC0_AR,VMA_ARX,FETCH,J/JPCEX
AC0_AR,VMA_ARX,FETCH,J/JPCUSR
.ENDIF/JPC.RING
POP1: AR_AR-1,INH CRY18,SKP CRY0 ;ADJUST POINTER, CHECK TRAP
=*1***0
ARX_MEM,TRAP2 ;PDL OVFLO, CAUSE TRAP
ARX_MEM,SR_#,#/100 ;SET DEST CONTEXT FLAG
AR_ARX,AC0_AR, ;FIRST STORE AC
VMA_BR,STORE,J/STMEM ;THEN MEMORY
;PUT RESULT AWAY, THEN AC
.TOC "SUBROUTINE CALL/RETURN -- JSR, JSP, JSA, JRA"
.DCODE
264: I, J/JSR
I, J/JSP
I, J/JSA
I, J/JRA
.UCODE
=00***0
.IFNOT/JPC
JSP: AR_PC+1,FETCH,J/STORAC
.IF/JPC
JSP: AR_PC+1,FETCH,SKP USER,J/JPCSTO
.ENDIF/JPC
JSR: AR_PC+1,STORE
=
.IFNOT/JPC
FIN STORE,VMA_VMA+1,FETCH,J/NOP
.IF/JPC
FIN STORE,VMA_VMA+1,FETCH,J/JPCIFY
.ENDIF/JPC
=00***0
JSA: ARX_AR SWAP,AR_AC0,STORE,J/JSA1 ;SAVE E IN ARX LEFT, GET AC
JRA: BR/AR,AR_AC0 ;GET AC, SAVE JUMP ADDR
= ARR_ARL,ARL_0.M,J/JRA1 ;GET AC LEFT
JSA1: FIN STORE,VMA_VMA+1,FETCH ;JUMP TO E+1
.IFNOT/JPC
ARR_PC+1,ARL_ARXL,J/STAC ;PC+1,,E GOES TO AC
.IF/JPC
ARR_PC+1,ARL_ARXL,SKP USER,J/JPCSTO
.ENDIF/JPC
.TOC "UUO'S"
;LUUO'S TRAP TO CURRENT CONTEXT
; EXTENDED INSTRUCTION SET IS "HIDDEN" BENEATH LUUO OPCODES
.DCODE
000: I, J/UUO
.IF/EIS
I, SJCL, J/L-CMS ;CMSL HIDDEN BENEATH LUUO
I, SJCE, J/L-CMS
I, SJCLE, J/L-CMS
I, B/2, J/L-EDIT ;EDIT HIDDEN UNDER 004
I, SJCGE, J/L-CMS
I, SJCN, J/L-CMS
I, SJCG, J/L-CMS
.IF/DECIMAL
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
.IFNOT/DECIMAL
010: I, J/LUUO
I, J/LUUO
I, J/LUUO
I, J/LUUO
.ENDIF/DECIMAL
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
.IFNOT/EIS
I, J/LUUO
I, J/LUUO
I, J/LUUO
004: I, J/LUUO
I, J/LUUO
I, J/LUUO
I, J/LUUO
010: I, J/LUUO
I, J/LUUO
I, J/LUUO
I, J/LUUO
014: I, J/LUUO
I, J/LUUO
I, J/LUUO
I, J/LUUO
.ENDIF/EIS
;USER UUO'S 20-37
020: I, J/LUUO
I, J/LUUO
I, J/LUUO
I, J/LUUO
024: I, J/LUUO
I, J/LUUO
I, J/LUUO
I, J/LUUO
030: I, J/LUUO
I, J/LUUO
I, J/LUUO
I, J/LUUO
034: I, J/LUUO
I, J/LUUO
I, J/LUUO
I, 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
.IFNOT/JPC TEST
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
.IF/JPC TEST
I, SJC-, J/TJMP
I, SJCL, J/TJMP
I, SJCE, J/TJMP
I, SJCLE, J/TJMP
I, SJCA, J/TJMP
I, SJCGE, J/TJMP
I, SJCN, J/TJMP
I, SJCG, J/TJMP
.ENDIF/JPC TEST
.IFNOT/LISP
I, J/MUUO ;CLOSE
I, J/MUUO ;RELEAS
.IF/LISP
I, J/LSPGCM ;LSPGCM (OPCODE 070)
I, J/LSPGCS ;LSPGCS (OPCODE 071)
.ENDIF/LISP
I, J/MUUO ;MTAPE
I, J/MUUO ;UGETF
.IFNOT/XCTR
I, J/MUUO ;USETI
I, J/MUUO ;USETO
.IF/XCTR
R, J/PXCT ;PXCT FOR ITS (OPCODE 074)
R, J/PXCT ;PXCTI FOR ITS (OPCODE 075)
.ENDIF/XCTR
.IFNOT/LPM.SPM
I, J/MUUO ;LOOKUP
I, J/MUUO ;ENTER
.IF/LPM.SPM
R, J/LPM ;LOAD PAGE MAP (OPCODE 076)
W, J/SPM ;STORE PAGE MAP (OPCODE 077)
.ENDIF/LPM.SPM
;EXPANSION OPCODES
100:
.IFNOT/LISP
I, J/UUO ;UJEN
I, J/UUO
.IF/LISP
I, J/LSPDBG ;LSPDBG (OPCODE 100, TEMP)
I, J/LSP101
.ENDIF/LISP
I, J/UUO
I, J/UUO
.UCODE
;HERE FOR UNDEFINED OPS (UUO'S) AND ILLEGAL INSTRUCTIONS
;E IS IN AR, OPCODE AND AC IN BRX
1002: ;FIXED ADDRESS TO COOPERATE
;WITH EXTEND AND OTHER OPS
UUO: ;UNDEFINED OP'S .GE. 100
MUUO: ARX_BRX,SC_#,#/13.,
SKP INTRPT,CALL,J/ROTS
1003: AR_SHIFT,VMA_#,#/424,J/MUUO1
;HERE ON LUUO'S
; E IN AR, INSTR IN BRX
1005:
.IFNOT/EIS
FIX: FE_EXP-#,#/244,SKP SCAD0, ;GET BINARY POINT POSITION
ARX_AR SIGN,J/FIX1 ;SET ROUNDING CONSTANT, GO FIX
.IF/EIS
L-CMS: J/LUUO ;LOC FOR HIDING STRING COMPARE
.ENDIF/EIS
1006:
.IF/EIS
L-EDIT: ;HIDE EDIT HERE
.ENDIF/EIS
LUUO: ARX_BRX,SC_#,#/13.,
CALL,SKP INTRPT,J/ROTS ;COMBINE E WITH UUO
1007: AR_SHIFT,VMA_40,STORE ;STORE OPCODE ETC AT 40
FIN STORE,VMA_41,
LOAD ARX,J/XCTW ;GO PERFORM 41
.IF/EIS
.IF/DECIMAL
1010:
L-DBIN: J/LUUO ;DBIN AT 2010
1011:
L-BDEC: J/LUUO ;BDEC AT 2011
.ENDIF/DECIMAL
1012:
L-MVS: J/LUUO ;MOVE STRING AT 2012
.ENDIF/EIS
.IF/JPC TEST
=00****
TJMP: AR_AC0,JUMP FETCH,B DISP,J/JMPJPC
.ENDIF/JPC TEST
.IF/LISP
=00***0
LSPGCM: BR/AR,MQ_AR,AR_GCSTBR,SKP AD NE,J/LGCM0 ;START OF GC MARK INSTR
LSPGCS: BR/AR,SC_EA,AR_GCSTBR,SKP AD NE,J/LGCS0 ;START OF GC SWEEP INSTR
=
=00***0
LSPDBG: AR_GCSTBR,J/LSPDB1
LSP101: J/UUO
=
.ENDIF/LISP
;HERE ON MUUO'S
; E IN AR, OP AND AC IN BRX
;MUUO: ARX_BRX,SC_#,#/13.,CALL,J/ROTS
; AR_SHIFT,VMA_#,#/424
MUUO1: STORE,UPT REF ;FIRST, STORE INSTRUCTION
FIN STORE,AR_PC+1,VMA_VMA+1,STORE ;NEXT, PC
=11**00
MEM_AR,VMA_VMA+1,SC_#,#/70,
CALL,J/GTEEB1
DATAI PAG(L),CALL,J/PCTXT ;GET PROCESS CONTEXT VARIABLES
=11 LD PREV CTXT ;PCS FROM PC, CWSX FROM SXCT
AR_SHIFT,ARL_BRL.S, ;COMBINE UBR WITH AC BLKS, CWSX
STORE, ; STORE THAT AT 426
COND/EBUS CTL,EBUS CTL/2; & RELEASE ECL EBUS
MEM_AR,VMA_430+MODE ;NOW READY TO GET NEW PC
LOAD AR,UPT REF ;FETCH NEW PC
NEWPC: AR_MEM,SR_0,J/START ;USE IT
;ROTATE SUBROUTINE
=11***0
ROTS: AR_SHIFT,ARX_SHIFT,SC_#-SC,#/36.,RETURN3
TAKE INTRPT ;FIXES LUUO IN USER 41 LOOP BUG
.TOC "JSYS, ADJSP"
.DCODE
104:
.IFNOT/MVSQZ
I, J/UUO ;JSYS
.IF/MVSQZ
R, J/MVSQZ
.ENDIF/MVSQZ
I, B/0, J/ADJSP
.UCODE
;HERE FOR ADJSP INSTRUCTION
; ENTER WITH E IN AR, PREFETCH IN PROGRESS
.IFNOT/MVSQZ
1000: ;PUT ADJSP NEXT TO UUO
.IF/MVSQZ
=00***0
MVSQZ: FE_#,#/5,ARX_0S,MQ_MQ*.25, ;FE COUNTS LOOP, CLEAR MQ00,
J/MVSQZ0 ;ARX ACCUMULATES SQUOZE
.ENDIF/MVSQZ
ADJSP: ARL_ARR,ARR_ARR ;PUT E IN BOTH HALVES
= AR_AR*AC0,AD/A+B,INH CRY18, ;ADJUST POINTER,
ARX/AD,SKP AR0 ;SKIP IF NEGATIVE
=0 GEN AR*AC0,AD/ANDCA, ;TEST FOR - TO + CHANGE
SKP AD0,J/STMAC
GEN AR*AC0,AD/ANDCB, ;TEST FOR + TO - CHANGE
SKP AD0,J/STMAC
.IF/MVSQZ
=1****0
MVSQZ0: ARX_ARX*8,GEN P-#,#/41,
SKP SCAD0,J/MVSQZ1
AR_ARX,I FETCH,J/STORAC
=1****0
MVSQZ1: P_P-#,#/26,ARX_ARX*5,J/MVSQZ5
GEN P-#,#/20,ARX_ARX*5,
SKP SCAD0
=1****0
P_P-#,#/17,J/MVSQZ5
GEN P-#,#/16,SKP SCAD NE
=1****0
P_#,#/45,J/MVSQZ5
GEN P-#,#/1,SKP SCAD0
=1****0
P_P+#,#/42
MVSQZ5: BR/AR,BRX/ARX,ARX_AR,AR_0S,SC_#,#/6
ARX_SHIFT,AR_BR
ARX_ARX+BRX,AR_SHIFT,
FE_FE-1,SKP SCAD0,J/MVSQZ0
.ENDIF/MVSQZ
.TOC "XCT, PXCT, SXCT"
;HERE FOR EXTENDED ADDRESSING INSTRUCTIONS
.IFNOT/XCTR
=1****0
XCT1: SKP USER,J/PXCT ;HERE ON XCT, NO INTERRUPT
TAKE INTRPT ;GET OUT OF LONG XCT CHAIN
=1****0
.IFNOT/XADDR
PXCT: BR/AR,ARX_AR,SET PXCT,J/PXCTEA ;SETUP CONTROL FLOPS
.IF/XADDR
PXCT: SET PXCT
.ENDIF/XADDR
UXCT: ARX_AR (AD),LOAD IR,J/XCTGO, ;COPY INSTR TO ARX, IR
TIME/3T ;MAYBE THIS WILL FIX SUSPECTED LOSSAGE?
.IF/XCTR
=00***0
PXCT: CALL,SKP KERNEL,J/IOCHK ;XCTR OKAY ONLY IN KERNEL MODE
SKP INTRPT,J/XCTR ;XCTR AND XCTRI
=*1***0
XCTR: BR/AR,ARX_AR,SET PXCT,J/PXCTEA
TAKE INTRPT
=*1***0
UXCT: ARX_AR (AD),LOAD IR,J/XCTGO
TAKE INTRPT
.ENDIF/XCTR
.DCODE
.IFNOT/SXCT
106: I, J/UUO
I, J/UUO
.IF/SXCT ;NOTE: THE SXCT INSTRUCTION IS A TEMPORARY MECHANISM
106: R, J/SXCT ;INTENDED FOR DIAGNOSTICS ONLY
I, J/UUO107
.ENDIF/SXCT
.UCODE
.IF/SXCT
1014: ;PUT NEXT TO UUO107
SXCT: SKP KERNEL,CALL,J/IOCHK ;LEGAL IN KERNEL MODE ONLY
1015: BR/AR,ARX_AR,AR_AC0, ;SHUFFLE INSTR TO GET BASE REG
SET SXCT ;SETUP HARDWARE FLAGS
SKP AC#0 ;CHOOSE LOOP FOR EA CALC
=0 BR/AR,AR_BR,LOAD IR, ;AC0 IS BASE INDEX
BRX/ARX,ARL_0.M,
EA MOD DISP,J/SXCTB
.ENDIF/SXCT
;EXTENDED ADDRESSING CONTINUED
.IFNOT/XADDR
PXCTEA: AR_BR,LOAD IR,ARL_0.M, ;GET EXT ADDR FROM XR OR INDRCT
BRX/ARX,J/XIND2
=00
PXLOOP: GEN AR,A READ ;GO DO INSTR
AR_AR+XR,A READ
GEN AR,A INDRCT,SKP INTRPT,J/XIND1
GEN AR+XR,A INDRCT,SKP INTRPT
=1****0
XIND1: AR_MEM,ARX_MEM,EA TYPE DISP,J/XIND2
MB WAIT,TAKE INTRPT
=1***00
XIND2: EA MOD DISP,J/PXLOOP ;CURRENT OR PREV WITHOUT CWSX
AR_ARX (AD),A READ ;PREV AND CWSX
.IF/SXCT
AR_ARX (AD),A READ ;SXCT 0,
EA MOD DISP,J/SXCTB ;SXCT B,
=1***00
SXCTB: AR_AR+BR,A READ ;GO
AR_AR+XR,ARL_0.C,J/SXCTB ;NO MORE INDIRECTS
GEN AR,A INDRCT, ;FOLLOW INDRCT POINTER
SKP INTRPT,J/XIND1
GEN AR+XR,A INDRCT,
SKP INTRPT,J/XIND1
.ENDIF/SXCT
.ENDIF/XADDR