.TOC "TRACKS SUPPORT" ; ; Everything in this file was once part of IO.MIC; it has been split ; out because it is never used in production microcode. At this ; writing (edit 434), none of this code will fit without removing ; or rewriting something else. Use this at your own risk! ; ; According to the University of Essex, when TRACKS is used with ; address break enabled, the monitor cannot disable address break ; for the actual execution of the instruction unless we include ; "ABORT INSTR" as part of the TRACKS loop. Accordingly, this is ; now done for all the different flavors of TRACKS. Thanks, folks. ; ;[317] During an attempt to implement uncounting of doubly counted op ; codes for the OP.CNT conditional, we learned: (1) EA ; calculation requires that VMA be initialized to the instruction ; location (usually PC) for the local/global stuff to work properly. ; Beware! (This is important if you try to do something after ; fetching an instruction but before you EA calc it.) (2) NICOND ; clears the trap enable flag. If INSTR.STAT is on, this will force ; the dispatch to the statistics logic without taking the trap, ; which will thus be lost and gone forever. This is a hardware bug, ; but it's rather impossible to ECO it at this late date. ; ;[321] The solution to this is to ignore the statistics flag if a trap ; is ready. See the block at NEXT for details. (It's not really ; a hardware bug after all.) ; .IF/INSTR.STAT =00 PIDX: CLR TRACKS EN,J/IFNOP ;TURN TRACKS OFF .IF/TRACKS ARX_SHIFT,ARL_BRL,ARR_0.S,J/PIDO2 .IFNOT/TRACKS ARX_SHIFT,AR_2,J/PIDX1 ;[315] Turn statistics on .ENDIF/TRACKS =11 AR_TRX ;READ BACK POINTER ARL_0.M ;GET INDEX PART AR_AR+TRB,STORE,J/STMEM ;DONE WITH DATAI .IFNOT/TRACKS PIDX1: AR_ARX+AR*4 ;SAVE PAGE NUMBERS IN TRX REGISTERS TRB_AR ;INITIAL GARBAGE HERE =0* VMA_ARX,LOAD AR,PHYS REF, CALL [XFERW] ;[434] VMA_ARX+1,LOAD AR,PHYS REF ;[315] Must wait one cycle for =0* TRX_AR,ARX_ARX+1,CALL [XFERW] ;parity check before writing AC VMA_ARX+1,LOAD AR,PHYS REF ;[434] =0* TRX1_AR,ARX_ARX+1,CALL [XFERW] ;[315] Note that this will always VMA_ARX+1,LOAD AR,PHYS REF ;make it before AR is smashed =0* TRX2_AR,CALL [XFERW] ;[434] SET TRACKS EN ;[315] Might as well do this now TRX3_AR,I FETCH,J/NOP ;SAVE TABLE PAGE #, TURN ON .ENDIF/TRACKS PIDO2: TRX_AR,AR_ARX ;SET UP INDEX TRB_AR ;AND BASE SET TRACKS EN,J/IFNOP ;TURN TRACKS ON .IF/TRACKS ;HERE WHEN NICOND FINDS TRACKS ENABLED =0 TRK1: TRX_AR,J/TRK2 ;PUT BACK UPDATED INDEX AR_AR SWAP ;END OF BUFFER. RESET AR_-AR,J/TRK1 ; ORIGINAL INDEX TRK2: ARL_0.M AR_AR+TRB ;ADDRESS TRACKS BUFFER VMA_AR,PHYS REF ;TO MAKE MODEL A WORK AR_PC,STORE,PHYS REF ; PUT PC THERE MEM_AR,VMA/PC,CLR TRACKS EN ;PREVENT NICOND SEEING TRACKS... ABORT INSTR ;[306] Make address break work by ; copying AD BRK CYC to AD FAIL INH SET TRACKS EN ;...UNTIL NEXT TIME DISP/NICOND,J/NEXT ;GO DO NEXT INSTR .ENDIF/TRACKS .IF/OP.CNT ;HERE WHEN NICOND FINDS OPCODE COUNTING ENABLED ; SKIP IF USER MODE ;[316] Make this register usage compatible with timing version below by ; making it use TRX2 (for exec mode counts pointer) and TRX3 (for user mode ; counts pointer) instead of TRX and TRX+1. ;[317] A massive attempt to uncount doubly counted instructions when an ; interrupt was detected has been backed off. See INSTR.STAT dispatch logic ; above for commentary. ; =0 OPCT1: AR_TRX2,SKP AC REF,J/OPCT2 ;[316] TRX HAS PAGE # FOR EXEC TABLE AR_TRX3,SKP AC REF ;[316] NEXT PAGE IS FOR USER =0 OPCT2: AR_SHIFT,MQ_SHIFT, ;[317] Save VMA of increment CLR TRACKS EN,J/OPCT3 ;OPCODE INDEXES INTO TABLE ARX_FM(VMA),J/OPCT2 ;GET INSTR FROM FM ; =0* ;[434] OPCT3: VMA_AR,LOAD AR,PHYS REF, ;[306][434] GET TABLE ENTRY, make CALL [XFERW] ; address break work =0 BR/AR,AR_AR+1,STORE,CALL [TRKEN];ADD THIS OCCURANCE TO IT, keep old DISP/NICOND ;DO INSTR IN ARX ; ; In an attempt to prevent an interrupt after counting an instruction, ; we now fake the second NICOND in line. ; =0000 AR_BR,CLR TRACKS EN,J/OPFIX ;Some kind of odd condition. =0010 AR_BR,CLR TRACKS EN,J/OPFIX ; Uncount the instruction AR_BR,CLR TRACKS EN,J/OPFIX AR_BR,CLR TRACKS EN,J/OPFIX AR_BR,CLR TRACKS EN,J/OPFIX AR_BR,CLR TRACKS EN,J/OPFIX =1010 BRX/ARX,AR_ARX,SET ACCOUNT EN, ;The usual case XR,EA MOD DISP,J/COMPEA AR_BR,CLR TRACKS EN,J/OPFIX =1110 GEN ARX,LOAD IR,#/0,J/XCTGO ;Instruction in registers AR_BR,CLR TRACKS EN ; =0 OPFIX: VMA_MQ,STORE,PHYS REF,CALL [TRKEN];[434] Restore old count DISP/NICOND,J/NEXT ; and do it yet again ; ; Subroutine to wait for memory, set VMA to PC, and reenable TRACKS. ; Return 1. [434] ; TRKEN: MEM_AR,VMA/PC ;[434] SET TRACKS EN,RETURN [1] ;Turn TRACKS back on .ENDIF/OP.CNT .IF/OP.TIME ;HERE TO ADD UP TIME SPENT IN INSTR'S OPTM0: SC_#,#/9.,SKP USER,J/OPTM1 =0 OPTM1: BR_AR LONG,AR_TRX2,SKP AC REF, ;INSTR IN ARX PAGE IN AR J/OPTM2 BR_AR LONG,AR_TRX3,SKP AC REF, ;INSTR IN ARX PAGE IN AR J/OPTM2 =0 OPTM2: AR_SHIFT,ABORT INSTR,J/OPTM3 ;[306] GENERATE ADDR TO INCREMENT ;NEXT GET ADDR FOR THIS ARX_FM(VMA),J/OPTM2 ;GET NEXT INSTR FROM FM OPTM3: VMA_AR,LOAD AR,UNCSH PHYS REF ;BUMP COUNT LOCATION AR_MEM AR_AR+1,STORE MEM_AR,SKP USER =0 AR_TRX,J/OPTM4 AR_TRX1 OPTM4: AR_SHIFT,ARX_TRB TRB_AR ;SAVE NEXT LOC TO BUMP RD+CLR PA ;TIME TO AR MTR CTL/CLR PERF VMA_ARX,LOAD ARX,UNCSH PHYS REF ;GET TABLE ENTRY AR_AR-BR,ARL_0.S ;COMPENSATE TIME FOR THIS CODE BR/AR,ARX_MEM,SKP AR18 ;IF THIS WAS AN ENABLED STATE, =0 AR_ARX+BR,STORE ;WRITE IT BACK MEM_AR,VMA/PC ;NOW SETUP NEXT INSTR AGAIN ARX_BRX,SET TRK+PA EN ;RESTORE STATISTICS FLAGS DISP/NICOND,J/NEXT .ENDIF/OP.TIME ;THIS IS THE SECOND ORDER STATISTICS GATHERING CODE .IFNOT/SO2.CNT .IF/SO.CNT ;THIS IS NON DEBUGED CODE THAT IS IN A VERY PRIMATIVE STATE ;IT WAS ABANDONED BETWEEN EDITS AS THE MONITOR NEEDED SOMETHING ;SLIGHTLY DIFFERENT ;THIS IS CODE TO DO A SECOND ORDER STATISTIC IN THE SECOND 128K ;EACH ENTRY IS A HALF WORD ;THE LOW ORDER BIT OF CONCATENATION ;DETERMINES WHICH HALFWORD IS INCREMENTED. OFF IS HIGH ;IF A HALFWORD OVERFLOWS THE CODE TURNS ITSELF OFF AND WRITES -1 ;AT LOCATION 400000 ;TRX HIDES THE LOCATION PRESENTED TRB THE LAST OPCODE ; THIS IS IN THE NEXT LOOP COMMENTED HERE FOR DOCUMENTATION ;TRK0: ARX_TRB,BRX/ARX,SKP AC REF,J/TRK1;GET PREV INSTR HIDE THIS ONE =0 TRK1: AR_1,SC_#,#/9.,J/TRK2 ;SHIFT IN FIRST OPCODE ARX_FM(VMA),AR_ARX ;GET THE INSTRUCTION FROM FM BRX/ARX,AR_1,SC_#,#/9.,ARX_AR ; WHEN IT HIDES THERE TRK2: AR_SHIFT,SC_#,#/8.,ARX_BRX ;SETUP TO DO THE NEXT OPCODE AR_SHIFT,CLR TRACKS EN ;CONVIENT TO SHUT OFF TRACKS VMA_AR,LOAD ARX,PHYS REF,AR_ARX ;LOW BIT OF INSTR WHERE CAN TEST ARX_SHIFT,TRB_AR ;LOW BIT OF INSTR TO HIGH BIT ARL_0.S,ARR_1S,SKP ARX0 ;SEE WHICH HALFWORD TO INC ; ALSO SETTING UP FOR TEST IN ; LOW INCREMENT =0 ARL_1.M,ARR_0.M,J/TRK3 ;INC HIGH ARX_MEM ;INC LOW BR/AR,ARX_ARX+1,AR/ADX,STORE ;INCREMENT LOW HALF AND STORE IT TEST AR.BR,SKP CRY0 ;USING AND-1 HACK TO TEST OVFLOW =0 AR_0S,J/TRKLOS ;OVERFLOWED FIXUP TO LOSE MEM_AR,ARX_BRX,VMA/PC,AR_BRX ;NO OVERFLOW GET OUT ALSO TRKN1: SET TRACKS EN ; SAVE AWAY THIS OPCODE TRKND: DISP/NICOND,J/NEXT ;AND DO NEXT INSTR TRK3: ARX_MEM,BR/AR ;GET WORD TO INC AR_ARX+BR,STORE,SKP CRY0 ;COMPUTE AND CHECK FOR OVERFLOW =0 ARX_BRX,VMA/PC,MEM_AR,AR_BRX, ;SAVE AWAY THIS INSTR J/TRKN1 ; AND GET OUT AR_0.C,ARX_BRX,MEM_AR,J/TRKLOS ;SHUT DOWN TRACKS ON OVERFLOW TRKLOS: AR_1,SC_#,#/17. ;WHEN LOSS PUT -1 IN 400000 AR_SHIFT GEN AR,VMA/AD,PHYS REF ;SHUT OFF TRACKS AND QUIT AR_TRB,STORE MEM_AR,VMA/AD J/TRKND .ENDIF/SO.CNT .IF/SO2.CNT ;THIS ONE DOES THE COUNTING IN 128K STARTING AT AN ADDRESS PRESENTED IT ;THIS IS CODE TO DO A SECOND ORDER STATISTIC IN THE SECOND 128K ;EACH ENTRY IS A HALF WORD ;THE LOW ORDER BIT OF CONCATENATION ;DETERMINES WHICH HALFWORD IS INCREMENTED. OFF IS HIGH ;IF A HALFWORD OVERFLOWS THE CODE TURNS ITSELF OFF AND WRITES -1 ;AT LOCATION PRESENTED ;TRX HIDES THE LOCATION PRESENTED TRB THE LAST OPCODE ; THIS IS IN THE NEXT LOOP COMMENTED HERE FOR DOCUMENTATION ;TRK0: ARX_TRB,BRX/ARX,SKP AC REF,J/TRK1;GET PREV INSTR HIDE THIS ONE =0 TRK1: AR_0S,SC_#,#/9.,J/TRK2 ;SHIFT IN FIRST OPCODE ARX_FM(VMA),AR_ARX ;GET THE INSTRUCTION FROM FM BRX/ARX,AR_0S,SC_#,#/9.,ARX_AR ; WHEN IT HIDES THERE TRK2: AR_SHIFT,SC_#,#/8.,ARX_BRX ;SETUP TO DO THE NEXT OPCODE AR_SHIFT,CLR TRACKS EN ;CONVIENT TO SHUT OFF TRACKS AR_AR+TRX ;BUMPS BY NUMBER FED IT VMA_AR,LOAD ARX,PHYS REF,AR_ARX ;LOW BIT OF INSTR WHERE CAN TEST ARX_SHIFT,TRB_AR ;LOW BIT OF INSTR TO HIGH BIT ARL_0.S,ARR_1S,SKP ARX0 ;SEE WHICH HALFWORD TO INC ; ALSO SETTING UP FOR TEST IN ; LOW INCREMENT =0 ARL_1.M,ARR_0.M,J/TRK3 ;INC HIGH ARX_MEM,ABORT INSTR ;[306] INC LOW BR/AR,ARX_ARX+1,AR/ADX,STORE ;INCREMENT LOW HALF AND STORE IT TEST AR.BR,SKP CRY0 ;USING AND-1 HACK TO TEST OVFLOW =0 AR_0S,J/TRKLOS ;OVERFLOWED FIXUP TO LOSE MEM_AR,ARX_BRX,VMA/PC,AR_BRX ;NO OVERFLOW GET OUT ALSO TRKN1: SET TRACKS EN ; SAVE AWAY THIS OPCODE TRKND: DISP/NICOND,J/NEXT ;AND DO NEXT INSTR TRK3: ARX_MEM,BR/AR,ABORT INSTR ;[306] GET WORD TO INC AR_ARX+BR,STORE,SKP CRY0 ;COMPUTE AND CHECK FOR OVERFLOW =0 ARX_BRX,VMA/PC,MEM_AR,AR_BRX, ;SAVE AWAY THIS INSTR J/TRKN1 ; AND GET OUT AR_0.C,ARX_BRX,MEM_AR,J/TRKLOS ;SHUT DOWN TRACKS ON OVERFLOW TRKLOS: AR_TRX GEN AR,VMA/AD,PHYS REF ;WRITE -1 IN PRESENTED LOCATION AR_TRB,STORE MEM_AR,VMA/PC ;NEED AN INSTRUCTION TO GIVE J/TRKND ;TIME TO NICOND AFTER VMA/PC .ENDIF/SO2.CNT .ENDIF/INSTR.STAT