S$OB = 0 ; НЕ Использовать SOB .NLIST .INCLUDE /ASCII.MAC/ .INCLUDE /HWDF.MAC/ .INCLUDE /DSMAC.MAC/ .INCLUDE /MYMAC.MAC/ .INCLUDE /MACRO.MAC/ .LIST ; ; Во внешнем файле ; ; SP$ZER = 0 ; SP$CHE = 0 ; Кэширование включить (символ определён) или выключить (символ не определён) ; ;DEBU$G = 0 ; отладочный код R$$T11 = 0 ; определён - работаем под rt-11, не определён - системно-независимая версия M$TPS = 0 ; НЕ Использовать MTPS MODULE NAME=, REL=, VER=<03>, COMM= FROM SYSMAC IMPORT .SETTOP, .TRPSET, .SCCA, .TTYIN, .TTYOUT, .PRINT, .EXIT FROM ARITH IMPORT $QMUL, $DMUL, $QDIV, $DDIV .IF EQ M$TPS .MACRO MTPS PR,?L PUSH PR .EMIT .ENDM MTPS .ENDC PRO$CS =: ^O<173700> ; Серия Pro 3xx/Электроника-85 System CSR $SYPTR =: ^O<54> ; Указатель на базовую область данных RMON $CNTXT =: ^O<320> $CNFG2 =: ^O<370> ; System configuration word #2 C2.PC =: ^O<20000> ; 1 => System is a Pro 3xx. SECCNT =: ^D<16> ; Time of test in seconds CLKCNT =: ^D<50>*SECCNT ; Clock ticks count CLKCN2 =: ^D<64>*SECCNT ; Clock ticks count (pro) 60*16? No! 64! .IF NDF SP$CHE IACTCNT =: 0. ; Speed3 - without cache .IFF IACTCNT =: 400. ; Speed4 - with cache .ENDC CISLEN = ^D<31> ; CIS Numeric len ACTINIT $ASCII CRLF: .ASCII <200> ; ; PREPARE ; ; ; Main loop preparing for new action or exit if all done ; PROCEDURE PREP BEGIN LET SP := SPSAVE MTPS #PR7 .IF DF R$$T11 LET SV10 := #ILLOP .IFF LET @#V.TR10+2 := #PR0 LET @#V.TR10 := #ILLOP .ENDC MTPS #PR0 IF APHASE NE #0 THEN LET TCURR := TCURR + #1 LET APHASE := #-1 LET R1 := TCURR + R1 ; R1 := TCURR*2 LET R0 := R1 + R0 + R0 + R1 + #CMDPTR + #2 ; R0 := TCURR*8+TCURR*2 (Message, init(2), action(2), skip title LET CAPTR := R0 ; save pointer to init block LET ACTCNT := #1 CALL MULBLK LET R0 := #ADDM CALL @BLKBEG END LET APHASE := APHASE + #1 ; next Phase CALL SSHWL2 .IF NDF SP$CHE LET R1 := (R0) IF RESULT IS EQ THEN LET R1 := R1 + #1 END IF APHASE NE #0 THEN LET R1 := R1 + 4(R0) END LET R0 := R1 ; ; in R0 - block length in words ; out R1 - count ; LET R1 := #0 LET R2 := UPLIM - BLKBEG CALL $DDIV ; (R1 R2) / R0 -> (R1 R2) - result, R0 - remainder LET R1 := R2 - #1 ; number of blocks for available memtory count CLC LET R1 := R1 R.ROTATE 1 ; in words .IFF LET R1 := #IACTCNT .ENDC LET ACTCNT := R1 CALL MULBLK LET R0 := R0 - BLKBEG ; total size CLC LET R0 := R0 R.ROTATE 1 ; in words LET BLKSIZ := R0 LET ICNT := #0 ; repeat count LET ICNT2 := #0 ; double words .IF DF R$$T11 IF PROFLG NE #0 THEN LET CLKS := #CLKCN2+1 ; ticks counts for Pro CALL TVWAIT ; wati terminal i/o complete ELSE .IFTF LET CLKS := #CLKCNT+1 ; ticks counts for others .IFT END .ENDC MTPS #PR7 ; Set TicTak .IF DF R$$T11 LET @VLTC+2 := #PR7 .ENDC LET @VLTC := #TICTAK MTPS #PR0 LET R0 := #ADDM WAIT ; wait next tick (or tack :) ) ; ; EVALUATION ; ; ; The exit from this code is performed by the procedure TICTAK ; LOOP CALL @BLKBEG LET ICNT2 := ICNT2 + #1 IF RESULT IS EQ THEN LET ICNT := ICNT + #1 END END END PREP ; ; COUNT ; PROCEDURE TICTAK BEGIN .IF DF R$$T11 IF PROFLG NE #0 THEN TST @#173030 ; clean interrup request END IF FCTRLC NE #0 THEN ; check ^C flag .TTYIN .TTYIN CALL RESVEC .EXIT END .ENDC LET CLKS := CLKS - #1 IF RESULT IS NE 10$: ; empty clock interrupt procedure and ; ; Set PSW ; ENTRY $MTPS RTI END .IF DF R$$T11 .IFF LET @VLTC := #10$ .ENDC $GOTO SHOW END TICTAK ; ; SHOW ; PROCEDURE SHOW $ASCII TSPEED: .ASCII \ -> \<200> CSPEED: .ASCII \ OP./SEK\<200> BEGIN .IF DF R$$T11 CALL RESVEC .ENDC LET PARTP := (SP) LET SP := SPSAVE CALL CALC LET ISPEED+2 := R2 ; high LET ISPEED := R3 ; low CALL CNV10S $PRINT #CSPEED IF APHASE NE #0 THEN $PRINT #TSPEED CALL PCALC CALL CNV10S $PRINT #CSPEED ELSE LET ISPIDP+2 := ISPEED+2 ; high LET ISPIDP := ISPEED ; low END $PRINT #CRLF ; ; GOTO NEXT ACTION ; ENTRY NXTSTP IF TCURR LO #TST.CN-1 OR APHASE EQ #0 THEN JUMPTO PREP END .IF DF R$$T11 .EXIT .IFF LOOP HALT END .ENDC END SHOW ; ; SUPPORT PROCEDURES ; PROCEDURE MULBLK BEGIN LET R0 := BLKBEG LET R2 := CAPTR LET R3 := ACTCNT THRU R3 ; blocks count ; INIT LET R4 := (R2) ; block words count IF RESULT IS NE THEN LET R5 := 2(R2) ; first word command pointer THRU R4 LET (R0)+ := (R5)+ ; copy next block END ELSE LET (R0)+ := #NOP END IF APHASE NE #0 ; if not init calculating ; ACTION LET R4 := 4(R2) IF RESULT IS NE THEN LET R5 := 6(R2) ; first word command pointer THRU R4 LET (R0)+ := (R5)+ ; copy next block END END END END LET (R0)+ := (PC) ; and return at end RETURN END MULBLK ; ; CPU command not imlemented ; PROCEDURE ILLOP $ASCII NOOP: .ASCII / - KOMANDA NE REALIZOWANA/<200> BEGIN .IF DF R$$T11 CALL RESVEC .ENDC LET APHASE := #1 CALL SSHWL2 $PRINT #NOOP GOTO NXTSTP END ILLOP .IF DF R$$T11 ; ; Unexpected V4 trap ; PROCEDURE V4EXIT $ASCII MUNEXP: .ASCII / trap/<200> MV4: .ASCII /V4/<200> MV10: .ASCII /V10/<200> BEGIN PUSH #MV4 GOTO VXEXIT END V4EXIT ; ; Unexpected V10 trap ; PROCEDURE V10EXIT BEGIN PUSH #MV10 $GOTO VXEXIT END V10EXIT ; ; Common codce ; PROCEDURE VXEXIT BEGIN CALL RESVEC $PRINT (SP)+ $PRINT #MUNEXP .EXIT END VXEXIT ; ; ; PROCEDURE V4V10 BEGIN IF RESULT IS CC THEN ; V4 IF SV4 NE #0 THEN PUSH SV4 ELSE GOTO V4EXIT END ELSE ; V10 IF SV10 NE #0 THEN PUSH SV10 ELSE GOTO V10EXIT END END .TRPSET #AREA, #V4V10 RETURN END V4V10 .ENDC PROCEDURE PCALC BEGIN ; SPEEDP * SPEED ; ------------ ; SPEEDP - SPEED LET R0 := ISPIDP+2 ; high LET R1 := ISPIDP ; low LET R2 := ISPEED+2 ; high LET R3 := ISPEED ; low CALL $QMUL ; (R0 R1) * (R2 R3) -> (R0 R1 R2 R3) LET R4 := ISPIDP+2 ; high LET R5 := ISPIDP - ISPEED ; low LET R4 := R4 - CARRY - ISPEED+2 ; high JUMPTO $QDIV ; (R0 R1 R2 R3) / (R4 R5) -> (R0 R1 R2 R3) (R4 R5) END PCALC PROCEDURE CALC BEGIN LET R0 := ACTCNT ; actions (one or more PDP-11 commands) count in buf LET R2 := #0 LET R3 := PARTP - BLKBEG R.SHIFT 1 CALL $DMUL ; R0 R1 LET R2 := R1 LET R1 := R0 LET R0 := BLKSIZ CALL $DDIV ; R1 R2 LET R0 := R0 L.SHIFT 1 IF R0 HIS BLKSIZ THEN LET R2 := R2 + #1 END LET PARTC := R2 ; ; $DMUL ; ; ; $DDIV ; (R1 R2) / R0 -> (R1 R2) result R0 remainder ; LET R0 := ACTCNT ; actions (one or more PDP-11 commands) count in buf LET R2 := ICNT LET R3 := ICNT2 ; counter of the total execution of actions in the buffer CALL $DMUL ; (R2 R3) * R0 -> (R0 R1) LET R1 := R1 + PARTC LET R0 := R0 + CARRY LET R2 := R1 LET R1 := R0 LET R0 := #SECCNT ; execution count in sec CALL $DDIV ; (R1 R2) / R0 -> (R1 R2) (R0) LET R3 := R2 LET R2 := R1 RETURN END CALC PROCEDURE SSHWL2 BEGIN LET R0 := CAPTR LET R1 := -2(R0) $GOTO SSHOWL END SSHWL2 PROCEDURE SSHOWL $ASCII $EMPTY: .ASCII / empty/<200> BEGIN PUSH $PRINT R1 PUSH #-1 IF APHASE EQ #0 THEN LET TOP := #-1+6 PUSH R1 $PRINT #$EMPTY POP R1 END LET R1 := R1 + (SP)+ - (SP)+ LET R1 := - R1 + #MMXLEN IF RESULT IS GT THEN THRU R1 $TTYOUT #SPACE END END POP R0 RETURN END SSHOWL .IF DF R$$T11 PROCEDURE RESVEC BEGIN MTPS #PR7 .IF DF R$$T11 LET SV4 := #0 LET SV10 := #0 .IFF LET @#V.TR4 := SV4 LET @#V.TR4+2 := SV4+2 LET @#V.TR10 := SV10 LET @#V.TR10+2 := SV10+2 .ENDC LET @VLTC := SV100 LET @VLTC+2 := SV100+2 MTPS #PR0 RETURN END RESVEC PROCEDURE SAVVEC BEGIN MTPS #PR7 .IF NDF R$$T11 LET SV4 := @#V.TR4 LET SV4+2 := @#V.TR4+2 LET SV10 := @#V.TR10 LET SV10+2 := @#V.TR10+2 .ENDC LET SV100 := @VLTC LET SV100+2 := @VLTC+2 MTPS #PR0 RETURN END SAVVEC PROCEDURE TVWAIT BEGIN PUSH R5 IF OCNT NE #0 THEN LET R5 := OCNT PUSH REPEAT UNTILB (R5) EQ #0 POP ELSE THRU R5 := #0 END THRU R5 := #0 END ; REPEAT ; UNTIL #100 OFF.IN @TVCSR END POP R5 RETURN END TVWAIT .ENDC PROCEDURE CNV10S BEGIN LET R1 := #10. GOTO CNVS END CNV10S PROCEDURE CNV8S BEGIN LET R1 := #8. $GOTO CNVS END CNV8S ; ; R2 R3 ; PROCEDURE CNVS BEGIN LET R0 := #BUF THRU R4 := #EBUF-BUF LET (R0)+ :B= #SPACE END LET -(SP) := #4 LOOP LET R4 := #0 LET R5 := #0 LOOP IF R2 EQ #0 AND R3 LO R1 LEAVE LOOP ADD #1, R5 ADC R4 SUB R1, R3 SBC R2 END LET (SP) := (SP) - #1 IF RESULT IS EQ THEN LET -(R0) :B= #SPACE LET (SP) := #3 END LET -(R0) :B= R3 LET (R0) :B= (R0) SET.BY #'0 LET R2 := R4 LET R3 := R5 IF R2 EQ #0 AND R3 EQ #0 LEAVE LOOP END POP LET R1 := #BUF $GOTO $PRINT END CNVS $PDATA TVCSR: .WORD TPS TVBUF: .WORD TPB PROCEDURE $PRINT BEGIN .IF DF R$$T11 IF PROFLG NE #0 THEN .PRINT R1 REPEAT UNTILB (R1)+ EQ #200 RETURN ELSE .IFTF LOOP LET R0 := #0 LET R0 :B= R0 SET.BY (R1)+ IF R0 EQ #200 THEN RETURN END REPEAT UNTILB @TVCSR MI #0 LET @TVBUF :B= R0 END .IFT END .ENDC END $PRINT PROCEDURE $TTYOUT BEGIN .IF DF R$$T11 IF PROFLG NE #0 THEN .TTYOUT #SPACE ELSE .IFTF REPEAT UNTILB @TVCSR MI #0 LET @TVBUF :B= #SPACE .IFT END .ENDC RETURN END $TTYOUT .INCLUDE /TSTBLK.MAC/ $PDATA ; ; For ACTION ; ADDM: .WORD 23456. DMULP1: .WORD BUF01 .WORD BUF02 .WORD BUFR01 DMULP2: .WORD BUF03 .WORD BUF04 .WORD BUFR02 DADDN1: .WORD N05DSC .WORD N06DSC .WORD BUFR03 DADDN2: .WORD N07DSC .WORD N08DSC .WORD BUFR04 N01DSC: SZ$NUM <+123456789012345> N02DSC: SZ$NUM <+234567890123456> N03DSC: SZ$NUM <+11> N04DSC: SZ$NUM <+12> N05DSC: SZ$NUM <+123456789012345> N06DSC: SZ$NUM <+234567890123456> N07DSC: SZ$NUM <+11> N08DSC: SZ$NUM <+12> DNUM01: .FLT4 3.456789022E4 DNUM02: .FLT4 3.2109754321E4 DNUM03: .FLT4 1.0 DNUM04: .FLT4 1.0 DNUM05: .WORD 0,34567. DNUM06: .WORD 0,321. P01VAL: ;.PACKED +123456789012345 ;, P01LEN .EVEN ;D01: ; .WORD 60000+P01LEN ; .WORD P01VAL BUF01: .WORD 60000+CISLEN .WORD ADR01 BUF02: .WORD 60000+CISLEN .WORD ADR02 BUF03: .WORD 60000+CISLEN .WORD ADR03 BUF04: .WORD 60000+CISLEN .WORD ADR04 BUFR01: .WORD 60000+CISLEN .WORD ADRR01 BUFR02: .WORD 60000+CISLEN .WORD ADRR02 BUFR03: SZ$NUM <+000000000000000> BUFR04: SZ$NUM <+00> DMOVC: .WORD MBUF01 .WORD MBUF02 MBUF01: .WORD , ABUF01 MBUF02: .WORD , ABUF02 ABUF01: .BYTE 0,1,2,3,4,5,6,7,10,11,12,13,14,15,16,17 ABF01E: $VIRT $VIRTB: SPSAVE: .BLKW 1 .IF DF R$$T11 AREA: .BLKW 2 .ENDC APHASE: .BLKW 1 ; ACTION phase (0 - usabilty, 1 - init counting, 2 - ACTION counting) CAPTR: ; block pointer for 1 and 2 .BLKW 1 UPLIM: .BLKW 1 VLTC: .BLKW 2 .IF DF R$$T11 PROFLG: .BLKW 1 FCTRLC: .BLKW 1 OCNT: .BLKW 1 SV100: .BLKW 2 .ENDC SV4: .IF DF R$$T11 .BLKW 1 .IFF .BLKW 2 .ENDC SV10: .IF DF R$$T11 .BLKW 1 .IFF .BLKW 2 .ENDC ACTCNT: .BLKW 1 BLKSIZ: .BLKW 1 TCURR: .BLKW 1 CLKS: .BLKW 1 ICNT: ; counter of the total execution of actions in the buffer .BLKW 1 ICNT2: .BLKW 1 ISPEED: ; calculated speed .BLKW 2 ISPIDP: ; paired calculated speed .BLKW 2 PARTP: ; partial block execution pointer .BLKW 1 PARTC: ; partial block execution counter .BLKW 1 BUF: .BLKB 11. EBUF: .BLKB 1 ADR01: .BLKB CISLEN+1/2 ADR02: .BLKB CISLEN+1/2 ADR03: .BLKB CISLEN+1/2 ADR04: .BLKB CISLEN+1/2 ADRR01: .BLKB CISLEN+1/2 ADRR02: .BLKB CISLEN+1/2 ABUF02: .BLKB ABF01E-ABUF01 .EVEN BLKBEG: .BLKW 1 .=$VIRTB .MACRO $CODE $VIRT .ENDM $CODE ; ; ; PROCEDURE START BEGIN LET SPSAVE := SP .IF DF R$$T11 .EMIT <.TRPSET #AREA, #V4V10> .EMIT <.SCCA #AREA, #FCTRLC> .EMIT <.SETTOP #-2> LET UPLIM := R0 LET VLTC := #V.LTC LET VLTC+2 := #V.LTC+2 LET PROFLG := #0 LET FCTRLC := #0 LET OCNT := #0 LET APHASE := #1 ; go to phase 0 LET R0 := @#$SYPTR IF #C2.PC SET.IN $CNFG2(R0) THEN ; On Pro? LET PROFLG := #1 IF @#V.LTC EQ @#230 AND @#V.LTC+2 EQ @#230+2 THEN LET VLTC := #230 ;#100 LET VLTC+2 := #232 ;#102 END CALL GETCNT END CALL SAVVEC .IFF LET VLTC := #V.LTC LET VLTC+2 := #V.LTC+2 LET UPLIM := #157776 .ENDC MTPS #PR7 .IF DF R$$T11 .IFF LET @#V.TR4+2 := #PR7 ; .IFT ; LET SV4 := #10$ ; .IFF ; LET @#V.TR4 := #10$ ; ; .IFTF ; ; LET R0 := @#PRO$CS ; IF R0 EQ #233 THEN ; On Pro? ; ; LET PROFLG := #1 ; LET VLTC := #230 ; LET VLTC+2 := #232 ; ; END IF ; 10$: ; ; LET SP := SPSAVE .IFT LET SV4 := #20$ .IFF LET @#V.TR4 := #20$ .ENDC .IF NDF SP$CHE LET @#CCR := @#CCR SET.BY #CC.BP .IFF LET @#CCR := @#CCR OFF.BY #CC.BP .ENDC 20$: LET SP := SPSAVE CALL ACTINI ; init completed MTPS #PR0 $PRINT #MSPEED $PRINT #CRLF LET TCURR := #-1 LET EBUF :B= #200 LET BLKBEG := #BLKBEG+2 LET SP := SPSAVE PUSH #PREP .IF DF R$$T11 JUMPTO RESVEC .IFF LET @VLTC+2 := #PR7 RETURN .ENDC END START .IF DF R$$T11 PROCEDURE GETCNT BEGIN LET R5 := @#V.TPS + #2*2 LET R4 := R5 + #100 REPEAT LET R5 := R5 + #2 IF R5 HIS R4 GOTO 10$ IF (R5) NE #^O<105765> CONTINUE LOOP ; TSTB xx(R5) LET R5 := R5 + #2 IF #270 HI (R5) CONTINUE LOOP IF (R5) HI #400 CONTINUE LOOP UNTILB 3(R5) EQ #2 ; BEQ .. LET R4 := (R5) LET R5 := @#$SYPTR LET R5 := $CNTXT(R5) + R4 LET OCNT := R5 $PRINT #OCFND, NORET 10$: $PRINT #OCNFND, NORET END GETCNT .ENDC PROCEDURE ACTINI BEGIN LET R5 := SP .IF DF R$$T11 LET SV10 := #10$ .IFF LET @#V.TR10+2 := #PR7 LET @#V.TR10 := #10$ .ENDC ; ; Some "possible trap 10" init ; ; FPP SETD SETL 10$: .IF DF R$$T11 LET SV10 := #20$ .IFF LET @#V.TR10 := #20$ .ENDC ; CIS CVTNPI ; numeric to packed N01DSC, BUF01 CVTNPI ; numeric to packed N02DSC, BUF02 CVTNPI ; numeric to packed N03DSC, BUF03 CVTNPI ; numeric to packed N04DSC, BUF04 20$: LET SP := R5 RETURN OCFND: .ASCII /OCnt field found :)/<200> OCNFND: .ASCII /OCnt field not found :(/<200> MSPEED: .ASCII /tEST BYSTRODEJSTWIQ / .ASCII /V3.4.2 / .ASCII /(K\[, ESLI ON ESTX / .IF NDF SP$CHE .ASCII /WYKL@^EN)/ .IFF .ASCII /WKL@^EN)/ .ENDC .ASCII <200> .EVEN END ACTINI .MACRO $CODE .EMIT <.PSECT $CODE$, I, RO> .ENDM $CODE END SPEED .END START