/PDP-8 DHRYSTONE BY ZACHARY KIRTZ /BASED ON DHRYSTONE BY REINHOLD P. WEICKER /EAE INSTRUCTIONS MUY=7405 DVI=7407 SHL=7413 MQL=7421 MQA=7501 /DK8-EA/DK8-EC CLOCK INSTRUCTIONS CLEI=6131 /ENABLE CLOCK INTERRUPT CLED=6132 /DISABLE CLOCK INTERRUPT CLSKF=6133 /SKIP ON CLOCK FLAG (& CLEAR IT) /DK8-EP/DK8-ES INSTRUCTIONS CLZE=6130 /CLEAR CLOCK ENABLES PER AC CLSKP=6131 /SKIP ON CLOCK FLAGS CLOE=6132 /LOAD CLOCK ENABLES CLAB=6133 /LOAD CLOCK PRESET CLEN=6134 /READ CLOCK ENABLES CLSA=6135 /READ CLOCK STATUS CLBA=6136 /READ CLOCK PRESET CLCA=6137 /READ CLOCK COUNTER /KW12-A CLOCK INSTRUCTIONS CLSK=6131 /SKIP ON CLOCK INTERRUPT CLLR=6132 /LOAD CLOCK CONTROL CLAB=6133 /LOAD CLOCK PRESET CLEN=6134 /LOAD CLOCK ENABLES CLSA=6135 /READ CLOCK STATUS CLBA=6136 /READ CLOCK PRESET CLCA=6137 /READ CLOCK COUNTER /IDENT VALUES ID1=0 ID2=1 ID3=2 ID4=3 ID5=4 /MISC DEFS RECSZ=25 /RECORD STRUCT SIZE STRSZ=21 /STR_30 SIZE ARRDIM=14 /ARRAY DIMS *20 /MISC VARS CLKTP, 0 /CLOCK TYPE /BIT11=CLK AVAILABLE /BIT0=0 -> DK8ES /BIT0=1 -> KW12A ISEAE, 0 /IS EAE AVAILABLE RCNTH, 0 /HIGH ROUND COUNT /FIELD 0 GLOBAL VARIABLES GINT, 0 /INT_GLOB GBOOL, 0 /BOOL_GLOB GCH1, 0 /CH_1_GLOB GCH2, 0 /CH_2_GLOB /GLOBAL VARIABLE ADDRESSES GPTR, GREC /PTR_GLOB GNPTR, GNREC /NEXT_PTR_GLOB KGINT, GINT KGBOOL, GBOOL KGCH1, GCH1 KGCH2, GCH2 KGARR, GARR KGARR2, GARR2 /GLOBAL CONSTANTS IDENT1, ID1 IDENT2, ID2 IDENT3, ID3 IDENT4, ID4 IDENT5, ID5 RUNCNT, 7700 /RUN COUNT /MAIN LOCAL VARIABLES /PUTTING THESE IN PZ AT LEAST FOR NOW SINCE /IT MAKES MY LIFE EASIER, WE HAVE SPACE, AND /IT SHOULDN'T IMPACT PERFORMANCE MINT1, 0 /INT_1_LOC MINT2, 0 /INT_2_LOC MINT3, 0 /INT_3_LOC MENUM, 0 /ENUM_LOC MRIDX, 0 /RUN_INDEX /MAIN PROGRAM LOCAL VARIABLE POINTERS KMINT1, MINT1 /INT_1_LOC PTR KMINT3, MINT3 /INT_3_LOC PTR KMENUM, MENUM /ENUM_LOC PTR KMSTR1, MSTR1 /STR_1_LOC PTR KMSTR2, MSTR2 /STR_2_LOC PTR /TEMP VARIABLES TEMP1, .-. TEMP2, .-. TEMP3, .-. TEMP4, .-. TEMP6, .-. /THIS PAGE CONTAINS /MAIN FUNCTION BEGINING AND ENDING PAGE /MAIN START HLT IOF /DISABLE INTERRUPTS 7447 /SWITCH TO EAE MODE A /IF ON PDP-8E MODE B /DOES SCA DIV OTHERWISE 0 /USED AS DIV OPERAND /OTHERWISE, HARMLESS "AND 0" JMS I (PATEAE /CHECK IF WE HAVE EAE /DISABLE EAE CODE IF NOT CLA OSR /GET LSW CMA /COMPLEMENT /WANT TO RUN LSW+1 LOOPS /AT LEAST 1 LOOP DCA MLPLFT /SAVE TO LOOP COUNTER JMS I (PUTMSG /PRINT BEGIN MSG PRSTRT JMS I (PUTMSG /PRINT VERSION MSG PRVER CLA OSR /GET COUNT AGAIN IAC /ADD 1 FOR TRUE COUNT JMS I (PUTMSI /PRINT HIGH RUN COUNT PRRCTH TAD RUNCNT /PRINT LOW RUN COUNT JMS I (PUTMSI PRRCTL JMS I (STCLK /START THE CLOCK /(IF AVAILABLE) MNST, CLA TAD (12 /SET ARR2[8][7]=10 DCA I KAR287 JMP I (MLOOP /JUMP TO MAIN LOOP /MAIN LOOP RETURNS HERE /PRINT END RESULTS MNEND, ISZ MLPLFT /INCREMENT COUNTER JMP MNST /NOT DONE? LOOP AGAIN CLCA /DONE /GET KW12 COUNTER DCA MTIMER /SAVE FOR LATER CLLR /STOP KW12 HLT JMS I (PUTMSG /END MESSAGE PREND TAD ISEAE /PRINT EAE ENABLE JMS I (PUTMSI PREAE TAD CLKTP /PRINT TIME IF HAVE CLK SNA CLA JMP MNENCK /OTHERWISE SKIP IT TAD MTIMER /PRINT TIME JMS I (PUTMSI PRTIME MNENCK, TAD GINT /INT_GLOB MSG JMS I (PUTMSI PRGINT TAD GBOOL /BOOL_GLOB MSG JMS I (PUTMSI PRGBOOL TAD GCH1 /CH_1_GLOB MSG JMS I (PUTMSI PRGCH1 TAD GCH2 /CH_2_GLOB MSG JMS I (PUTMSI PRGCH2 TAD I KAR18 /LOAD ARR[8] JMS I (PUTMSI PRARR1 /ARR_2_GLOB MSG; GET ARR2[8][7] TAD I KAR287 /LOAD ARR[8][7] JMS I (PUTMSI PRARR2 TAD GPTR /PTR_GLOB MSG JMS I (PUTMSI PRPTR TAD GPTR /PRINT GPTR CONTENTS JMS I (PUTREC TAD GNPTR /NEXT_PTR_GLOB MSG JMS I (PUTMSI PRNPTR TAD GNPTR /PRINT GNPTR CONTENTS JMS I (PUTREC TAD MINT1 /INT_1_LOC MSG JMS I (PUTMSI PRLIT1 TAD MINT2 /INT_2_LOC MSG JMS I (PUTMSI PRLIT2 TAD MINT3 /INT_3_LOC MSG JMS I (PUTMSI PRLIT3 TAD MENUM /ENUM_LOC MSG JMS I (PUTMSI PRLENM TAD KMSTR1 /STR_1_LOC MSG JMS I (PUTMSS PRLST1 TAD KMSTR2 /STR_2_LOC MSG JMS I (PUTMSS PRLST2 HLT JMP I KEXIT /RETURN TO OS/8 MONITOR /LOCAL VARIABLES MTIMER, 0 /TIMER MLPLFT, 0 /LOOP COUNT /LOCAL CONSTANTS KAR18, GARR+10 /ARR1[8] KAR287, ARRDIM^10+GARR2+7 /ARR2[8][7] ADDR KEXIT, 7600 /THIS PAGE CONTAINS: /EAE DISABLE PATCH ROUTINE /CLOCK START AND CLOCK STOP ROUTINES PAGE /APPLY PATCHES TO ENABLE/DISABLE EAE PATEAE, 0 CLL CLA IAC RAL /MUL 2X2 MQL MUY 0002 /"AND Z 2" IF MUY DOESN'T WORK CLA /SEPARATE CLA AND MQA SO /SO GROUP 1 CLA IS USED DCA ISEAE /CLEAR FLG WHILE AC=0 MQA /GET RESULT TAD (-4 /CHECK IF 4 / SKP CLA CLA SZA JMP PECK ISZ ISEAE /SET EAE FLAG TAD (ENEPA-DISEPA /SETUP FOR AC=ENEPA /WILL BECOME ENEAE /WITH NEXT INST PECK, TAD (DISEPA-1 /SET DISABLE (OR EN) PATCH /ADDRESS DCA 10 PELO, TAD I 10 /LOAD ADDR SNA /IS 0? JMP I PATEAE /RETURN IF YES DCA TEMP1 /SAVE TO TEMP TAD I 10 /LOAD DATA DCA I TEMP1 /STORE WORD JMP PELO /LOOP BACK /BEGIN RUNNING A CLOCK IF AVAILABLE /CURRENTLY THIS SUPPORTS: / PDP-12 WITH KW12-A / PDP-8E WITH DK8ES STCLK, 0 CLA CLL CLLR /CLEAR CLOCK MODE CLA CMA /AC=7777 CLAB /CHECK IF WE HAVE A /CLOCK BY SETTING + READING /THE CLK BUF PRESET REG CLA /CLEAR AC CLBA /READ IT BACK IAC /INC BY 1; AC=0 IF CLK PRESENT SZA /IS IT PRESENT? JMP I STCLK /NO? RETURN JMS IS12 /OK. ARE WE ON A '12? SZL CLA IAC RAR /YES? SET TOP BIT /WHILE KEEPING LINK INTACT /TO INDICATE WE'RE A '12 IAC /SET BOTTOM BIT TO /INDICATE WE HAVE A CLK DCA CLKTP /SAVE CLOCK TYPE CLLR /CLEAR MODE AND RATE SZL /CLEAR ENABLES ON '12 CLEN CLA RAL /MOVE LINK TO LOW BIT TAD (CLKPAR-1 /GET CLK PARAMS ADDR DCA 10 /SAVE THEM TAD I 10 /LOAD FIRST PARAM ISZ 10 /SKIP PAST ANOTHER CLLR /SET MODE 1 TO CLEAR EVERYTHING CLSA /GET STATUS TO CLEAR EVENTS CLA TAD I 10 /GET NEXT PARAM CLLR /SET MODE 0 AND 100HZ JMP I STCLK /CLOCK PARAMS CLKPAR, /SET MODE 1 1000 /DK8ES 0100 /KW12A /SET MODE 0 AT 100HZ 0200 /DK8ES 5000 /KW12S /DETECT IF WE'RE RUNNING ON A PDP-12 /RESULT[LINK] IS RUNNING ON '12 IS12, 0 CLL CLA /CLEAR AC 6141 /TO LINC MODE 0017 /COMPLEMENT AC /"AND 17" IF NOT '12 0002 /BACK TO PDP8 MODE /"AND 2" IF NOT '12 IAC /INC BY 1 CLA SZL SNA /IF ON A '12, AC=0 /AND LINK=1 JMP I IS12 /RETURN NOW IF ON '12 CLL /CLEAR LINK TO INDICATE /NOT '12 JMP I IS12 /RETURN /THIS PAGE CONTAINS: /MAIN FUNCTION LOOP PAGE /MAIN LOOP MLOOP, CLA /SET ROUND COUNTER TO 0 DCA MRIDX MLPSRT, TAD MRIDX /CHECK RIDX!=RUNCNT CIA TAD RUNCNT SNA /BREAK IF NOT JMP I (MNEND /JUMP TO END JMS I (PROC5 /CALL PROC5 JMS I (PROC4 /CALL PROC4 CLA STL IAC RAL /MINT2=3 (AND MINT1=2, BUT DCA MINT2 /WE DON'T WORRY ABOUT THAT NOW TAD (DPSTR2 /COPY DPSTR2 TO MSTR2 DCA TEMP1 /USING STRCPY TAD KMSTR2 JMS I (STRCPY CLA IAC /SET MENUM TO IDENT2 (1) DCA MENUM TAD KMSTR2 /CALL FUNC2 WITH STR1,STR2 DCA TEMP1 TAD KMSTR1 JMS I (FUNC2 CLA CML RAL /INV RES AND SHIFT TO AC DCA GBOOL /SAVE TO GBOOL JMS I (MLPL1 /RUN FIRST LOOP TAD KGARR2 /PUT ARR2 ADDR IN PARAM[3] DCA TEMP3 TAD KGARR /PUT ARR ADDR IN PARAM[2] DCA TEMP2 TAD MINT3 /PUT MINT3 IN PARAM[1] DCA TEMP1 CLA STL IAC RAL /PUT MINT1 (CUR 3) IN PARAM[AC] JMS I (PROC8 /CALL PROC8 TAD GPTR /CALL PROC1 WITH GPTR JMS I (PROC1 JMS I (MLPL2 /PERFORM SECOND SUB LOOP TAD MINT2 CLL RAL /MUL BY MINT1 (CUR 3); MUL BY 2 TAD MINT2 /ADD ANOTHER DCA MINT2 /SAVE IT MLPP1B, HLT /PATCH 1 JUMP /REPLACED BY A JUMP TO /MLPP1H IF EAE IS DETECTED /OR MLPP1S IF NOT MLPP1E, DCA MINT1 /SAVE IT TAD MINT3 /MINT2=7*(MINT2-MINT3)-MINT1 CIA /MINT2-MINT3 TAD MINT2 MLPP2B, HLT /PATCH 1 JUMP /REPLACED BY A JUMP TO /MLPP2H IF EAE IS DETECTED /OR MLPP2S IF NOT MLPP2E, DCA MINT2 /SAVE IT TAD KMINT1 /CALL PROC2 WITH MINT1 ADDR JMS I (PROC2 ISZ MRIDX /INCREMENT RUN INDEX JMP MLPSRT /LOOP BACK AROUND /EAE ACCELERATED DIVISION /OF MINT2 BY MINT3 /THIS IS USED IF EAE IS DETECTED ON STARTUP MLPP1H, TAD MINT3 /SET DIVISOR TO MINT3 DCA MLPP1T TAD MINT2 /GET MINT2 BACK MQL DVI /MINT1=MINT2/MINT3 MLPP1T, 0 /DIV OPERAND /ALSO USED AS TEMP CLA MQA /NE: TAD MLPSDB JMP MLPP1E /JUMP BACK TO MAIN LOOP /EAE ACCELERATED MULTIPLY ROUTINE /MULTIPLIES (MINT2-MINT3) BY 7 THEN SUBTRACTS MINT1. /THIS IS USED IF EAE IS DETECTED DURING STARTUP MLPP2H, MQL MUY 7 CLA MQA /-(MINT1-X)==X-MINT1 CIA TAD MINT1 CIA JMP MLPP2E /JUMP BACK MAIN LOOP /EAE-LESS (SOFTWARE) DIVISION OF /MINT2 BY MINT3 USING ONLY ADDITION/SUBTRACTION /THIS IS USED IF EAE IS NOT DETECTED DURING STARTUP. MLPP1S, DCA MLPP1T /CLEAR COUNTER TAD MINT2 /REGET MINT2 CIA /NEGATE MLPP1L, /SUB LOOP TAD MINT3 /SUB ANOTHER SMA /CHECK IF DONE (AC IS POSITIVE) JMP MLPP1F /JUMP TO END IF YES ISZ MLPP1T /INC COUNTER JMP MLPP1L /LOOP BACK AROUND MLPP1F, CLA /DIV END TAD MLPP1T /GET RESULT JMP MLPP1E /JMP BACK TO MAIN LOOP /EAE-LESS MULTIPLY ROUTINE /MULTIPLIES (MINT2 - MINT3) BY 7 THEN SUBTRACTS MINT1. /THIS IS USED IF EAE IS NOT DETECTED DURING STARTUP. MLPP2S, CLL RAL /BY 2 CLL RAL /BY 4 CLL RAL /BY 8 TAD MINT3 /ADD ANOTHER MINT2 CIA /USE THE FACT THAT /X-Y == -(-X+Y) TO SAVE /ON SOME STORES/LOADS TAD MINT2 /ADD MINT3 (SUB MINT3) TAD MINT1 /ADD MINT1 (SUB MINT1) CIA /NEGATE FOR PROPER VALUE JMP MLPP2E /JUMP BACK TO MAIN LOOP /THIS PAGE CONTAINS /MAIN LOOP SUB LOOP ROUTINES /MLPL1 & MLPL2 PAGE /MAIN LOOP FIRST SUB LOOP MLPL1, 0 TAD (7 /MINT3 IS 7 AT THIS POINT DCA MINT3 /SET MINT3 TO THE RESULT TAD KMINT3 /LOAD MINT3 ADDR AS PARAM[2] DCA TEMP2 CLA STL IAC RAL /LOAD MINT2 (3) AS PARAM[1] DCA TEMP1 CLA IAC RAL /LOAD MINT1 (2) AS PARAM[AC] JMS I (PROC7 /CALL PROC7 JMP I MLPL1 /MAIN LOOP SECOND SUB LOOP MLPL2I, 0 /LOOP INDEX MLPL2, 0 CLA IAC /SET INDEX TO 'A' (1) DCA MLPL2I MLPL2S, TAD MLPL2I /CHECK INDEX<=GCH2 CIA TAD GCH2 SPA CLA /BREAK OUT IF NOT JMP I MLPL2 CLA STL IAC RAL /PUT 'C' (3) IN PARAM[1] DCA TEMP1 TAD MLPL2I /PUT INDEX IN PARAM[AC] JMS I (FUNC1 /CALL FUNC1 CIA /CHECK IF RESULT==MENUM TAD MENUM SZA CLA /LOOP BACK IF NOT JMP MLPL2L /LOOP BACK IF NOT TAD KMENUM /PUT MENUM ADDR IN PARAM[1] DCA TEMP1 /TAD IDENT1 /PUT IDENT1 IN PARAM[AC] JMS I (PROC6 /CALL PROC6 TAD (DPSTR3 /COPY DPSTR3 TO MSTR2 DCA TEMP1 TAD KMSTR2 JMS I (STRCPY TAD MRIDX /SET MINT2 & GINT TO INDEX DCA MINT2 TAD MRIDX DCA GINT MLPL2L, ISZ MLPL2I /INCREMENT INDEX JMP MLPL2S /LOOP BACK AROUND /THIS PAGE CONTAINS: /CHRCMP, STRCMP /MEMCPY, STRCPY PAGE /CHARACTER COMPARE FUNCTION /THIS IS USED BY STRING COMPARE /PARAM[AC] FIRST CHAR /PARAM[CCMP] SECOND CHAR /RESULT[AC] DIFFERENCE CCMP, 0 /SECOND CHAR ARG CHRCMP, 0 AND (77 /ONLY WANT 2ND HALF DCA 7 /STORE IN SCRATCH TAD CCMP /LOAD 2ND CHR INTO AC AND (77 /ONLY WANT 2ND HALF CIA /NEGATE 2ND CHR AND CLR LINK TAD 7 /SUB 2ND FROM 1ST JMP I CHRCMP /STRING COMPARE FUNCTION /PARAM[AC] FIRST STRING /PARAM[1] SECOND STRING /RESULT[AC] DIFFERENCE SCMPS1=10 /FIRST STRING SCMPS2=11 /SECOND STRING STRCMP, 0 TAD (-1 /DEC BY ONE FOR AUTOIDX DCA SCMPS1 /STORE 1ST TO SCRATCH CMA TAD TEMP1 /MOVE 2ND DCA SCMPS2 SCMPLP, TAD I SCMPS2 /LOAD 1ST HALF OF 2ND STR CIA CLL /SUB WORD FROM 1ST FROM 2ND TAD I SCMPS1 /LOAD 1ST HALF OF 1ST STR /LINK WILL BE SET AT THIS /POINT IF BOTH ARE SAME SZA CLA /ARE THEY THE SAME? JMP SCMPLC /NO? JUMP TO LONG CHECK TAD I SCMPS1 /IS 2ND HALF 0? AND (77 SZA CLA JMP SCMPLP /NO? LOOP BACK AGAIN JMP I STRCMP /YES? RETURN /LINK WILL BE SET FROM TAD SCMPLC, /LONG CHECK /CHECK EACH HALF WORD TAD SCMPS2 /COPY TO NON-AUTOIDX DCA TEMP2 TAD SCMPS1 DCA TEMP3 TAD I TEMP2 /1ST HALF FROM 2ND RTR;RTR;RTR DCA CCMP TAD I TEMP3 /1ST HALF FROM 1ST RTR;RTR;RTR JMS CHRCMP /COMPARE CHARS SZA /RETURN IF DIFF JMP SCMPRE /JUMP TO END TAD I TEMP2 /LOAD 2ND HALF OF 2ND STR DCA CCMP TAD I TEMP3 /LOAD 2ND HALF OF 1ST STR JMS CHRCMP /COMPARE CHARS;RES WILL BE DIFF SCMPRE, CLL /CLEAR LINK/EQUAL FLAG JMP I STRCMP /RETURN /STRING COPY FUNCTION /PARAM[AC] DST /PARAM[1] SRC SCPYSR=11 /SOURCE ADDRESS SCPYDS=10 /DESTINATION ADDRESS STRCPY, 0 TAD (-1 /SUB 1 FROM EACH DCA 10 /AND PUT IN AUTOIDX SCPYLP, TAD I TEMP1 /LOAD A WORD DCA I 10 /SAVE AT DST TAD I TEMP1 ISZ TEMP1 /INCREMENT SRC AND (77 /CHECK IF 2ND HALF IS ZERO SNA CLA /RETURN IF IT IS JMP I STRCPY /RETURN JMP SCPYLP /OTHERWISE, LOOP AGAIN /MEMORY COPY FUNCTION /PARAM[AC] DST /PARAM[1] SRC /PARAM[2] LENGTH MCPYLN=TEMP2 /LENGTH MCPYDS=10 /SOURCE ADDRESS MCPYSR=11 /DESTINATION ADDRESS MEMCPY, 0 TAD (-1 /SUB 1 FROM EACH DCA MCPYDS /AND PUT IN AUTOIDX CLA CMA /AC=-1 TAD TEMP1 DCA MCPYSR TAD MCPYLN /NEGATE LENGTH, SUB 1 CMA DCA MCPYLN MCPYLP, ISZ MCPYLN /INC COUNT, CHECK IF DONE JMP .+2 /SKIP RETURN JMP MCPYEN /JUMP TO END TAD I MCPYSR /READ A WORD DCA I MCPYDS /SAVE TO DST JMP MCPYLP /LOOP BACK AROUND MCPYEN, CLA /CLEAR AC FOR CALLER JMP I MEMCPY /RETURN /THIS PAGE CONTAINS: /PUTC, PUTCHR, PUTSTR /PUTOCT, PUTNL, PUTMSG /PUTMSI, PUTMSS, PUTREC PAGE /PRINT CHAR IMPLEMENTATION /PARAM[AC] CHAR /RESULT[AC] UNCHANGED PUTC, 0 TLS /SEND CHAR TSF /WAIT FOR PRINT FINISH JMP .-1 JMP I PUTC /RETURN /PRINT CHARACTER FUNCTION /PARAM[AC] CHARACTER /RESULT[AC] 8BIT CHAR PUTCHR, 0 AND (77 /ONLY WANT 1ST HALF SNA /RETURN IF ZERO JMP I PUTCHR TAD (-40 /CONVERT FROM 6BIT SPA /ASCII TO 8BIT ASCII TAD (100 /(ALPHA CHAR) TAD (240 JMS PUTC /ACTUALLY SEND CHAR JMP I PUTCHR /PRINT STRING FUNCTION /PARAM[AC] STRING ADDRESS PUTSTR, 0 DCA TEMP1 /SAVE ADDRESS PSTRLP, TAD I TEMP1 /GET CHAR RTR;RTR;RTR /GET FIRST HALF JMS PUTCHR /PRINT CHR SNA CLA /RETURN IF ZERO JMP I PUTSTR /(NULL CHR WAS PROVIDED) TAD I TEMP1 ISZ TEMP1 /INCREMENT POINTER JMS PUTCHR /PRINT CHR SNA CLA /RETURN IF ZERO JMP I PUTSTR JMP PSTRLP /LOOP BACK AROUND /PRINT OCTAL NUMBER /PARAM[AC] NUMBER TO PRINT POCTCT, 0 /PRINTED COUNT POCTTM, 0 /TEMP PUTOCT, 0 RAL /SHIFT OVER 1 DCA POCTTM /SAVE NUMBER TAD (-4 /SET COUNTER TO -4 DCA POCTCT POCTLP, CLA TAD POCTTM /GET CURR NUMBER RTL /SHIFT NEXT THREE INTO 1ST RAL DCA POCTTM /SAVE FOR LATER TAD POCTTM AND (7 /MASK OFF BOTTOM TAD (260 /ADD '0' TO GET ASCII CHAR JMS PUTC /PRINT CHAR ISZ POCTCT /CHECK HOW MANY LEFT JMP POCTLP /LOOP BACK AROUND JMP I PUTOCT /RETURN /SEND NEWLINE CHARACTER PUTNL, 0 CLA TAD (215 /PRINT CR JMS PUTC CLA TAD (212 /SEND LF JMS PUTC CLA /CLEAR AC FOR CALLER JMP I PUTNL /RETURN /PRINT A MESSAGE /PARAM[CALL+1] MESSAGE INDEX PUTMSG, 0 CLA TAD I PUTMSG /GET STR ADDR JMS PUTSTR /PRINT STRING JMS PUTNL /PRINT A NEWLINE ISZ PUTMSG /INCREMENT RETURN ADDR JMP I PUTMSG /RETURN /PRINT A MESSAGE FOLLOWED BY AN OCTAL NUMBER /PARAM[CALL+1] MESSAGE INDEX /PARAM[AC] OCTAL VALUE PMSITM, 0 /OCT VALUE TMP PUTMSI, 0 DCA PMSITM /SAVE OCT VAL TAD I PUTMSI /GET STR ADDR JMS PUTSTR /PRINT STRING TAD PMSITM /LOAD OCT VALUE JMS PUTOCT /PRINT IT JMS PUTNL /PRINT A NEWLINE ISZ PUTMSI /INCREMENT RETURN ADDR JMP I PUTMSI /RETURN /PRINT A MESSAGE STRING FOLLOWED BY ANOTHER STRING /PARAM[CALL+1] MESSAGE STRING /PARAM[AC] STRING PMSSTM, 0 /STR VALUE TMP PUTMSS, 0 DCA PMSSTM /SAVE STRING TAD I PUTMSS /GET MSG STR ADDR JMS PUTSTR /PRINT MSG STRING TAD PMSSTM /LOAD SECOND STR JMS PUTSTR /PRINT SECOND STRING JMS PUTNL /PRINT NEWLINE ISZ PUTMSS /INCREMENT RETURN ADDR JMP I PUTMSS /RETURN /PRINT DHRYSTONE RECORD CONTENTS /PARAM[AC] RECORD ADDRESS PRECRC=11 /RECORD ADDRESS PUTREC, 0 TAD (-1 DCA PRECRC /PUT REC ADDR IN AUTOIDX TAD I PRECRC /PTR_COMP MSG JMS PUTMSI PRCPTR TAD I PRECRC /DISCR MSG JMS PUTMSI PRDISC TAD I PRECRC /ENUM_COMP MSG JMS PUTMSI PRCENM TAD I PRECRC /INT_COMP MSG JMS PUTMSI PRCINT TAD PRECRC /STR_COMP MSG IAC JMS PUTMSS PRCSTR JMP I PUTREC /RETURN /THIS PAGE CONTAINS: /PROC2, PROC4, PROC5 /PROC7, & PROC8 PAGE /DHRYSTONE PROC_2 FUNCTION /PARAM[AC] INT ADDRESS P2INTP=TEMP1 /INT ADDRESS PROC2, 0 DCA P2INTP /SAVE ADDR CLA CMA /SET AC=-1 TAD GCH1 /CHECK GCH1=='A' SZA CLA JMP P2END /JUMP TO END IF NOT TAD GINT /*PINT=*PINT+10-1-GINT CIA /OR *PINT=*PINT+9-GINT TAD (11 TAD I P2INTP DCA I P2INTP P2END, JMP I PROC2 /DHRYSTONE PROC_4 FUNCTION PROC4, 0 CLA CMA /CHECK IF GCH1 IS 'A' (1) TAD GCH1 SNA CLA /AC = GBOOL == 'A' IAC /SET TRUE SZA /SET GBOOL TO LBOOL IF LBOOL=1 DCA GBOOL /BASICALLY GBOOL=GBOOL OR LBOOL CLA STL RTL /SET GCH2 TO 'B' (2) DCA GCH2 JMP I PROC4 /RETURN /DHRYSTONE PROC_5 FUNCTION PROC5, 0 CLA IAC /SET GCH1 TO 'A' (1) DCA GCH1 DCA GBOOL /SET GBOOL TO FALSE JMP I PROC5 /RETURN /DHRYSTONE PROC_7 FUNCTION /PARAM[AC] INT1 /PARAM[1] INT2 /PARAM[2] INTPTR PROC7, 0 TAD (2 /ADD 2 TO INT1 TO GET INTLOC TAD TEMP1 /ADD INT2 DCA I TEMP2 /SAVE RESULT TO INTPTR JMP I PROC7 /DHRYSTONE PROC_8 FUNCTION /PARAM[AC] INT1 /PARAM[1] INT2 /PARAM[2] 50 ARRAY ADDR /PARAM[3] 50X50 ARRAY ADDR P8INT2=TEMP1 /INT2 PARAM P8ARR1=TEMP2 /ARRAY1 PARAM P8ARR2=TEMP3 /ARRAY2 PARAM P8LINT=TEMP4 /LOCAL INT P8TMP1=TEMP6 /TEMP STORAGE 1 PROC8, 0 TAD (5 /ADD 5 TO INT1 FOR LINT DCA P8LINT /SAVE TO SCRATCH 4 TAD P8LINT /GET ADDR OF ARR1[LINT] TAD P8ARR1 DCA P8ARR1 /OVERWRITE ARR1 ADDR TAD P8INT2 /SAVE INT2 TO ARR1 DCA I P8ARR1 ISZ P8ARR1 /ARR1[LINT+1] TOO TAD P8INT2 DCA I P8ARR1 /SAVE ARR1[LINT+1]=ARR1[LINT] TAD P8ARR1 /GET ADDR OF ARR1[LINT+2] TAD (2 DCA P8ARR1 TAD P8LINT /SET TO LINT DCA I P8ARR1 P8P1B, HLT /PATCH START /REPLACED BY A JUMP TO /P8P1H IF EAE IS DETECTED /OR P8P1S IF NOT P8P1E, TAD P8LINT /ADD LINT FOR ARR2[LINT][LINT] TAD P8ARR2 DCA P8TMP1 /PUT IN TMP1 TAD P8LINT /STORE LINT AT ARR2[LINT][LINT] DCA I P8TMP1 ISZ P8TMP1 /AND ARR2[LINT][LINT+1] TAD P8LINT DCA I P8TMP1 STA CLL RAL /INCREMENT ARR2[LINT][LINT-1] TAD P8TMP1 /SUB 2 FROM ARR2[LINT][LINT+1] DCA P8TMP1 ISZ I P8TMP1 /INCREMENT BY ONE TAD P8TMP1 TAD (ARRDIM^3+1 DCA P8TMP1 TAD P8INT2 /ARR1[LINT] IS INT2 DCA I P8TMP1 /SAVE TO ARR2[LINT+3][LINT] TAD (5 /SET GINT TO 5 DCA GINT JMP I PROC8 /RETURN /EAE ACCELERATION RETRIEVAL OF /ARR2[LINT][0] /THIS IS USED IF EAE IS DETECTED DURING STARTUP P8P1H, TAD P8LINT MQL MUY /CALC ARR2[LINT] OFFSET ARRDIM CLA MQA /ADD ARR2 BASE TO OFFSET JMP P8P1E /JUMP TO TO CORE PROC8 /EAE-LESS IMPLEMENTATION FOR RETRIEVING /ARR2[LINT][0] /THIS IS USED IF EAE IS NOT DETECTED DURING STARTUP P8P1T, 0 P8P1S, TAD P8LINT /GET LINT RTL /MUL BY 4 DCA P8P1T /SAVE TO TEMP TAD P8P1T /GET IT BACK RAL /BY 8 TAD P8P1T /ADD BY 4 FOR BY 12 JMP P8P1E /RETURN /THIS PAGE CONTAINS: /FUNC1, FUNC3, PROC3, PROC6 PAGE /DHRYSTONE FUNC_1 FUNCTION /PARAM[AC] CHAR1 /PARAM[1] CHAR2 /RESULT[AC] ENUM VALUE F1CH2=1 /CHAR2 PARAM FUNC1, 0 CIA /CHECK CHAR1!=CHAR2 TAD F1CH2 SZA CLA /RETURN IDENT1 IF YES JMP I FUNC1 TAD F1CH2 /OTHERWISE SET GCH1=CHR1(=CHR2) DCA GCH1 /AND RETURN IDENT2 IAC /IDENT2=1 JMP I FUNC1 /RETURN /DHRYSTONE FUNC_3 FUNCTION /PARAM[AC] ENUM VALUE /RESULT[AC] BOOL VALUE FUNC3, 0 TAD (-ID3 /CHECK IF ENM==IDENT3;AC=-2 SZA CLA /RETURN FALSE IF NOT JMP I FUNC3 /RETURN FALSE IAC /SET AC TO TRUE (1) JMP I FUNC3 /RETURN /DHRYSTONE PROC_3 FUNCTION /PARAM[AC] RECORD PTR ADDRESS PROC3, 0 DCA TEMP1 /SAVE TO SCRATCH TAD GPTR /CHECK IF GPTR IS NULL SNA CLA JMP P3CP7 /GO DIRECTLY TO P7 CALL TAD I GPTR /GET GPTR->PTR_COMP DCA I TEMP1 /ASSIGN TO PROVIDED PTR P3CP7, TAD GINT /PLACE GINT IN PARAM[1] DCA TEMP1 CLA STL IAC RAL /PLACE GPTR->VAR1.INT_COMP TAD GPTR /ADDR IN PARAM[2] DCA TEMP2 TAD (12 /PLACE 10 IN PARAM[AC] JMS I (PROC7 /CALL PROC7 JMP I PROC3 /RETURN /DHRYSTONE PROC_6 FUNCTION /PARAM[AC] ENUM VALUE /PARAM[1] ENUM ADDRESS P6ENAD, 0 /ENUM ADDRESS PARAM P6ENVL, 0 /ENUM VALUE PARAM PROC6, 0 DCA P6ENVL /SAVE ENUM VAL TAD TEMP1 /SAVE ENUM ADDR DCA P6ENAD TAD P6ENVL /STORE ENUM VAL AT ADDR DCA I P6ENAD TAD P6ENVL /PLACE ENUM VAL IN PAR[AC] JMS FUNC3 /CALL FUNC3 SZA CLA /SET ENUM ADDR TO IDENT4 JMP P6F3FL /IF FUNC3 RET FALSE CLA STL IAC RAL /AC=IDENT4=3 DCA I P6ENAD P6F3FL, TAD P6JTBI /GENERATE JUMP TABLE TAD P6ENVL /ENTRY JMP INSTRUCTION DCA .+1 /STORE AT NEXT ADDRESS 0000 /WILL BECOME A JMP INTO JTBL P6JTBI, JMP P6JTBL /JUMP TABLE P6JTBL, JMP P6CSI1 /IDENT1 JMP P6CSI2 /IDENT2 JMP P6CSI3 /IDENT3 JMP P6CSI4 /IDENT4 JMP P6CSI5 /IDENT5 /P6CSI1, TAD IDENT1 /CASE: IDENT1 P6CSI1, JMP P6CSEN /STORE ENM VAL TO ADDR /JUMP TO SWITCH END P6CSI2, TAD (-144 /CASE: IDENT2 TAD GINT /CHECK GINT > 100 SPA CLA CLA STL IAC RAL /NO, SET IDENT4 JMP P6CSEN /JUMP TO END P6CSI3, IAC /CASE: IDENT3; ADR->IDENT2 JMP P6CSEN /JUMP TO END P6CSI4, TAD I P6ENAD /CASE: IDENT4; KEEP CURR VAL JMP P6CSEN /JUMP TO END P6CSI5, CLA STL RTL /CASE: IDENT5; ADR->IDENT3 P6CSEN, DCA I P6ENAD /SAVE VALUE TO ADDR JMP I PROC6 /RETURN /THIS PAGE CONTAINS /PROC1 PAGE /DHRYSTON PROC_1 FUNCTION /PARAM[AC] RECORD PTR P1PTR, 0 /FIRST RECORD ADDRESS P1NR, 0 /NEXT RECORD ADDRESS P1PCI, 0 /REC->INT_COMP ADDR P1NPCI, 0 /NEXT_REC->INT_COMP ADDR PROC1, 0 DCA P1PTR TAD I P1PTR /LOAD RECORD->PTR_COMP DCA P1NR /SAVE IT TAD GPTR /SET GPTR AS MEMCPY SRC (MQ) DCA TEMP1 TAD (RECSZ /SET MEMCPY LEN/PAR[1] DCA TEMP2 TAD P1NR /SET NEXT REC AS DST (AC) JMS I (MEMCPY /CALL MEMCPY CLA STL IAC RAL /GET ADR OF PTR->INT_COMP TAD P1PTR /ABOVE:AC=3 DCA P1PCI /SAVE TO PTR->INT_COMP ADDR TAD (5 /WRITE 5 TO PTR->INT_COMP DCA I P1PCI CLA STL IAC RAL /NR->INT_COMP = PTR->INT_COMP TAD P1NR /ABOVE:AC=3 DCA P1NPCI TAD (5 DCA I P1NPCI TAD P1NR /NR->PTR_COMP = PTR->PTR_COMP DCA I P1NR TAD P1NR /CALL PROC3 W/ ADDR OF JMS I (PROC3 /NR->PTR_COMP ISZ P1NR /CHECK NR->DISCR==IDENT1 TAD I P1NR /LOAD NR->DISCR SZA CLA /CHECK IF IDENT1 (0) JMP P1DNEQ CLA STL IAC RTL /AC=6 DCA I P1NPCI TAD P1NR /SET PARAM[1]= IAC /ADR(NR->ENUM_COMP) DCA TEMP1 CLA STL RTL /SET AC=PTR->ENUM_COMP TAD P1PTR /ABOVE:AC=2 DCA TEMP2 TAD I TEMP2 JMS I (PROC6 /CALL PROC6 CLA CMA /AC=-1 TAD P1NR DCA TEMP1 TAD I GPTR /SET NR->PTR_COMP= DCA I TEMP1 /GPTR->PTR_COM TAD P1NPCI /SET PARAM[2]= DCA TEMP2 /ADR(NR->INT_COMP) TAD (12 /SET PARAM[1]=10 DCA TEMP1 TAD I P1NPCI /PARAM[AC]=NR->INT_COMP JMS I (PROC7 /CALL PROC7 JMP I PROC1 /RETURN P1DNEQ, TAD I P1PTR /SET SRC TO PTR->NEXT DCA TEMP1 TAD (RECSZ /SET SIZE TO REC SIZE DCA TEMP2 TAD P1PTR /SET DST TO PTR JMS I (MEMCPY /CALL MEMCPY JMP I PROC1 /RETURN /THIS PAGE CONTAINS: /FUNC2 PAGE /DHRYSTONE FUNC_2 FUNCTION /PARAM[AC] FIRST STRING PTR /PARAM[1] SECOND STRING PTR /RESULT[LINK] BOOL VALUE F2STR1, 0 /FIRST STRING F2STR2, 0 /SECOND STRING FUNC2, 0 DCA F2STR1 /SAVE BOTH STRINGS TAD TEMP1 /COPY 2ND ADDR DCA F2STR2 F2LOOP, TAD F2STR2 /GET 3RD CHAR FROM STR2 IAC DCA TEMP3 TAD I TEMP3 AND (77 DCA TEMP1 TAD F2STR1 /GET 2ND CHAR FROM STR1 IAC DCA TEMP3 TAD I TEMP3 RTR;RTR;RTR AND (77 JMS I (FUNC1 /CALL FUNC1 SZA CLA /IF RES!=IDENT1 (0), LOOP BACK JMP F2LOOP TAD F2STR2 /LOAD STR2 AS STR2;LOOP END DCA TEMP1 TAD F2STR1 /LOAD STR1 AS STR1 JMS I (STRCMP /CALL STRCMP SPA CLA /RET FALSE FROM STRCMP JMP I FUNC2 TAD (12 /SET GINT TO 10 (LINT+1+7) DCA GINT JMP I FUNC2 /RETURN;LINK=1 FROM STRCMP /FIELD 0 "HEAP" VARIABLES PAGE /RECORD STRUCT DATA GREC, GNREC /PTR_COMP ID1 /DISCR ID3 /ENUM_COMP 50 /INT_COMP == 40 /STR_2_COMP TEXT \DHRYSTONE PROGRAM, SOME STRING\ GNREC, ZBLOCK RECSZ /MAIN FUNCTION LOCAL STRINGS /LEN IS STRSZ MSTR1, TEXT \DHRYSTONE PROGRAM, 1'ST STRING\ MSTR2, ZBLOCK STRSZ /GLOBAL ARRAYS GARR, ZBLOCK ARRDIM /12 LENGTH ARRAY /12 BY 12 ARRAY/MATRIX GARR2, ZBLOCK ARRDIM^ARRDIM /ENABLE EAE OFFSETS & PATCHES ENEPA, /MAIN LOOP FIRST PATCH /FOR DIVIDE RELOC MLPP1B MLPP1B; JMP MLPP1H /MAIN LOOP SECOND PATCH /FOR MULTIPLY RELOC MLPP2B MLPP2B; JMP MLPP2H /PROC8 PATCH /FOR MULTIPLY RELOC P8P1B P8P1B; JMP P8P1H /TERMINATOR RELOC 0 /DISABLE EAE OFFSETS & PATCHES DISEPA, /MAIN LOOP FIRST PATCH /FOR DIVIDE RELOC MLPP1B MLPP1B; JMP MLPP1S /MAIN LOOP SECOND PATCH /FOR MULTIPLY RELOC MLPP2B MLPP2B; JMP MLPP2S /PROC8 PATCH /FOR MULTIPLY RELOC P8P1B P8P1B; JMP P8P1S /TERMINATOR RELOC 0 /USED IN MAIN LOOP DPSTR2, TEXT \DHRYSTONE PROGRAM, 2'ND STRING\ DPSTR3, TEXT \DHRYSTONE PROGRAM, 3'RD STRING\ /BEGIN STRINGS PRSTRT, TEXT \DHRYSTONE BENCHMARK FOR PDP-8\ PRVER, TEXT \VERSION 2.1.0\ PRRCTH, TEXT \ROUND COUNT (HIGH): \ PRRCTL, TEXT \ROUND COUNT (LOW): \ /RESULT STRINGS PREND, TEXT \EXECUTION ENDS\ PREAE, TEXT \EAE ENABLED: \ PRTIME, TEXT \TIMER (100HZ): \ PRGINT, TEXT \INT_GLOB (GINT): \ PRGBOO, TEXT \BOOL_GLOB (BOOL): \ PRGCH1, TEXT \CH_1_GLOB (GCH1): \ PRGCH2, TEXT \CH_2_GLOB (GCH2): \ PRARR1, TEXT \ARR_1_GLOB (ARR1): \ PRARR2, TEXT \ARR_2_GLOB (ARR2): \ PRPTR, TEXT \PTR_GLOB (GPTR): \ PRNPTR, TEXT \NEXT_PTR_GLOB (NGPTR): \ PRCPTR, TEXT \ PTR_COMP: \ PRDISC, TEXT \ DISCR: \ PRCENM, TEXT \ ENUM_COMP: \ PRCINT, TEXT \ INT_COMP: \ PRCSTR, TEXT \ STR_COMP: \ PRLIT1, TEXT \INT_1_LOC (MINT1): \ PRLIT2, TEXT \INT_2_LOC (MINT2): \ PRLIT3, TEXT \INT_3_LOC (MINT3): \ PRLENM, TEXT \ENUM_LOC (MENUM): \ PRLST1, TEXT \STR_1_LOC (MSTR1): \ PRLST2, TEXT \STR_2_LOC (MSTR2): \ / /BEGIN PATCH TO SUPPORT DK8E-A/DK8E-C. /NOTE: WE RELY HERE ON CLLR == CLED!! /KLUDGE THE CODE UNTIL IT WORKS. /ONCE IT WORKS, INTEGRATE IT BETTER. /FIRST, JUST START UP THE DK8E-A/C. *STCLK+1 /A PROGRAMMABLE CLOCK WAS NOT FOUND. JUST ASSUME A FIXED CLOCK. CLEI /ENABLE CLOCK INTERRUPT ION /TAKE INTERRUPTS CLA IAC /SET CLOCK TYPE DCA CLKTP JMP I STCLK /RETURN /WHEN DONE, PRESERVE MTIMER, BUT DISABLE INTERRUPTS *MNEND+2 IOF NOP /THE FIXED RATE CLOCKS JUST REQUEST AN INTERRUPT. *1 INTRPT, ISZ I [MTIMER /BUMP COUNTER CLSKF TCF/6007 /BUGBUG: CLEARS AC, LINK! CLEI ION JMP I 0 /RETURN TO CALLER $