***************************************************************** * * * (c) Copyright Hewlett-Packard Company, 1987. * * All rights are reserved. Copying or other * * reproduction of this program except for archival * * purposes is prohibited without the prior * * written consent of Hewlett-Packard Company. * * * * RESTRICTED RIGHTS LEGEND * * * * Use, duplication, or disclosure by the Government * * is subject to restrictions as set forth in * * paragraph (b) (3) (B) of the Rights in Technical * * Data and Computer Software clause in * * DAR 7-104.9(a). * * * * HEWLETT-PACKARD COMPANY * * Fort Collins, Colorado * * * ***************************************************************** * * * SOURCE TEXT FOR HP 9000, SERIES 300 COMPUTER TEST CODE. * * * * MODULE NAME: PTMUTIL (TIMER ROUTINES THAT USE THE MC6840 PTM)* * * * TODAYS EDIT: 1988/NOV/23 13:52 * * * * *JSW* COMMENTED OUT "GLITCH" MESSAGE * * * * *DAD* REMOVED CALL TO INITBUSER FROM INITPTM * * * * *DAD* FIXED ONTIME SUBROUTINE * * * * *DAD* FIXED DOCUMENTATION, AND MOVEMAT ENT OF PTMINT * * * ***************************************************************** PAGE NOSYMS LLEN 120 SPRINT * ******************************** * * * EXTERNAL REFERENCES * * * ******************************** * REFR FILL_VCTR,JUMPLONG REFR EXCEPTION,DISP * REFA PTM_GC,WHERE,LVL6INT * ******************************** * * * ENTRY POINT IN THIS TEXT * * * ******************************** * DEF INITPTM INITALIZES PTM AND SETS IT TO "0". NO PARAMS. DEF GETPTM WHAT TIME IZIT? RETURNS D0.L WITH TIME IN uS. DEF ONTIME ON INTERRUPT. A0.L IS TEST^,D0.W IS CALL/GOTO FLAG DEF SETPTM SET THE PTM TO A KNOWN TIME. D0.L IS TIME TO SET. DEF WAIT_PTM USER TIMED WAIT. PASS IN D1.L IN uS TO WAIT. DEF WAIT_1 WAITS 1 MILLY SECOND. USES WAIT_PTM, NO PARAMS. DEF SAVE_ONT SAVE ONTIME VALUE * PAGE * ******************************** * * * EQUATES USED BY THIS TEST * * * ******************************** * PTM EQU $5F8000 CACHE CONTROL REGISTER REG0 EQU 1 REGISTER 0 REG1 EQU 3 REGISTER 1 REG2 EQU 5 REGISTER 2 REG3 EQU 7 REGISTER 3 REG4 EQU 9 REGISTER 4 REG5 EQU 11 REGISTER 5 REG6 EQU 13 REGISTER 6 REG7 EQU 15 REGISTER 7 * * COMMANDS CNTROUTEN EQU $80 COUNTER OUTPUT ENABLE INTENABLE EQU $40 INTERRUPT ENABLE NORMAL16 EQU $00 NORMAL 16 BIT MODE DUAL8 EQU $04 DUAL 8 BIT MODE EXTCLOCK EQU $00 EXTERNAL CLOCK ENABLCLOX EQU $02 ENABLE CLOCK PRESET EQU $01 PRESET (CR10) CR_1 EQU $01 SELECT CNTR 1 (CR20) CR_3 EQU $00 SELECT CNTR 3 (CR20) CR_3DIV8 EQU $01 COUNTER 3 / 8 * * CRX3, CRX4 & CRX5 SINGLE EQU $08 SINGLE SHOT MODE CONTMODE EQU $00 CONTINUOUS MODE * * STATUS REGISTERD I1 EQU $01 COUNTER 1 INTERRUPT I2 EQU $02 COUNTER 2 INTERRUPT I3 EQU $04 COUNTER 3 INTERRUPT INTERRUPT EQU $80 OVERALL INTERRUPT * * FLAGS FOUND IN PTM_GC GC EQU 7 GC_MASK EQU $80 ACTIVE EQU 6 LOWRES EQU 5 * RORG 0 * ******************************** * Where the clock source is indicated by diagonal lines and is either * an "E" signal from the CPU/PAL circuitry (not stable or guarenteed to * always be the same value) or Cx (which is a simular to the Motorola * manual name). Cx for CR3 and CR1 is connecter to a 250 khz clock source * and CR2 is connected to the clock source as selected by CR3 (oc3). * * /-- (E) * /-- (Cxoc3)--------------\ /-- (Cxtal) 250 khz clock * CR2 /-(dual 8)-\ CR3 |oc3| /-- (E) CPU ~ 800 khz clock * +--------+--------+ CR3 TO +--------+--------+-div1 * | MSB | LSB | CR2 | MSB | LSB | *or* * +--------+--------+ clock +--------+--------+-div8 * |word| |word| * * The dual 8 mode provides an internal clock input link between * CR2 and CR3 plus making the output a 2 WORD block of data. * * * ~38.2 hr overflow 32 us RESOLUTION * * CR1 /-- (E) * +--------+--------+ * | MSB | LSB | * +--------+--------+ * |word| * \-- (Cxtal) * .262144 sec overflow 4 us RESOLUTION * ******************************** * * * PTM INITIALIZATION * * * * * ******************************** * INITPTM MOVE SR,-(A7) SAVE SR ORI #$0700,SR DISABLE INTERRUPTS * * JSR INITBUSER INIT BUS ERROR * MOVEM.L A0/D0-D2,-(A7) SAVE CALLER. LEA PTM+REG0,A0 POINTER TO PTM. MOVE.B (A0),D1 DUMMY READ DATA. * SUBQ.W #REG0,A0 NORMALIZE A0 SO THAT IT POINTS TO PTM BASE. * MOVEQ #CR_1,D1 WRITING THIS TO REG1 WILL SET REG 0 SECONDARY MOVE.B D1,REG1(A0) SELECT TO POINT TO CR #1. * D1 already set to value of PRESET * MOVEQ #PRESET,D1 RESET ($01) AND SET CR1 TO USE xtal CLOCK. MOVE.B D1,REG0(A0) * * MOVEQ #-1,D1 INITIALIZE LATCHES MOVE.L D1,REG2-1(A0) * MOVE.L D1,REG4-1(A0) * MOVE.L D1,REG6-1(A0) * * MOVEQ #CR_3,D1 WRITING THIS TO REG1 WILL SET REG 0 SECONDARY MOVE.B D1,REG1(A0) SELECT TO POINT TO CR #3. * MOVEQ #CONTMODE+CNTROUTEN+CR_3DIV8+DUAL8,D1 BIT PATTERN 00+80+01+04 hex MOVE.B D1,REG0(A0) CR3/|10000101|bin * CR3 = |ox on|NO ISR|{CONT|INOU|S MODE}|DUAL 8|XTAL IN|PRESCALE DIV 8| * MOVEQ #CR_1,D1 SELECT CR1 MOVE.B D1,REG1(A0) * MOVEQ #CONTMODE,D1 CLEAR RESET AND SET COMMAND FOR CONTINUOUS MODE MOVE.B D1,REG0(A0) GOZINTA CR1 *WARNING.. E IS CLOCK SOURCE.* * * SEE IF COUNTER 1 IS DOING ANYTHING MOVEQ #127,D0 TIMEOUT WONDER WHAT THIS IS? MOVEP.W REG2(A0),D1 GET CURRENT CR1 VALUE MSB OF COUNT. * INITPTML SUBQ.W #1,D0 DOWNDATE TIMEOUT * BMI.S INITPTMX * * MOVEP.W REG2(A0),D2 GET VALUE CMP.W D1,D2 CHECK FOR DELTA * BEQ INITPTML LOOP * MOVEQ #0,D0 CCR BIT "Z" = 1 * INITPTMX MOVEM.L (A7)+,A0/D0-D2 RESTORE MOVE (A7)+,SR RESTORE SR * RTS RETURN * PAGE * * ******************************** * * * GET CURRENT TIME IN us * * * ******************************** * * D0.L = CR2&CR3 D1.W - CR1 * * D0.L RETURNED WITH TIME IN 4uS RESOLUTION (D1&[MASK]+D0 -> D0) * GETPTM MOVEM.L A0/D1-D2,-(A7) SAVE LEA PTM,A0 POINTER * * USE MOVEM TO READ ALL 3 COUNTERS IN * ONE INSTRUCTION TO REDUCE TIME BETWEEN * READING EACH REGISTER! ALSO CHECK FOR * A GLITCH WHEN READ OF CR2 IS ON ONE * SIDE OF Tx AND THE READ OF CR3 IN ON * THE OTHER (CR2 IS READ THEN Tx CAUSES * CR3 TO BE LOADED FROM THE LATCHES AND * CR2 TO BE DECREMENTED). * MOVEM.L REG2-1(A0),D0-D2 GET CR1, CR2 & CR3 MOVEM.L D0-D2,-(A7) SAVE THEM MOVEP.W 1(A7),D1 NOW FORMAT THEM CORRECTLY MOVEP.L 5(A7),D0 * ADDA.W #12,A7 CLEAN UP THE STACK CMPI.W #$FFFF,D0 CHECK FOR GLITCH BNE.S NOGLITCH * MOVEM.L REG2-1(A0),D0-D2 GET CR1, CR2 & CR3 MOVEM.L D0-D2,-(A7) SAVE THEM MOVEP.W 1(A7),D1 NOW FORMAT THEM CORRECTLY MOVEP.L 5(A7),D0 * ADDA.W #12,A7 CLEAN UP THE STACK * JSR DISP * DC.W GLITCH-* NOGLITCH NOT.W D1 COMPLEMENT LSL.W #2,D1 TIMES 4us NOW IN us (LAST 2 LSB = 0.) ANDI.W #$001C,D1 MASK TO THE LEAST 31us AT 4us RESOLUTION NOT.L D0 COMPLEMENT IT LSL.L #5,D0 TIMES 8 TIMES 4us NOW IN us ADD.W D1,D0 38 HOUR CLOCK WITH 4us RESOLUTION. * D0 IS THE RETURN VALUE MOVEM.L (A7)+,A0/D1-D2 RESTORE RTS RETURN * PAGE * * ******************************** * * * SET TIME IN us * * * ******************************** * * TIME IN us IN D0.L GOES INTO CR2&CR3 * SETPTM MOVEM.L A0/D1,-(A7) SAVE LEA PTM,A0 POINTER MOVEQ #0,D1 ZERO LSR.L #5,D0 DIV 8 DIV 4us (32) ADDX.L D1,D0 ROUND NOT.L D0 NEGATE MOVEP.W D0,REG6(A0) SET CR3 LSB SWAP D0 MOVEP.W D0,REG4(A0) SET CR2 MSB MOVEM.L (A7)+,A0/D1 RESTORE RTS RETURN * PAGE * * ******************************** * * * INTERRUPT TIME IS SET IN us * * * ******************************** * * A0.L = ISR POINTER FOR INTERRUPT RETURN TO TEST PROGRAM. * * D0.L = TIME BEFORE INTERRUPT * D1.W = "GO TO" OR "CALL" FLAG. * (+) VALUE MEANS CALL * (0|-) VALUE MEANS "GO TO". * * IF TIME REQUESTED IN DO IS LESS THAN * $0003FFFC (~0.26 sec) THEN ONLY CR3 * WILL BE SET TO TIME DIVIDED BY 8 * AND TIME SETTINGS COME IN 8us STEPS, * AND CR3 IS SET UP FOR NORMAL 16 BIT * OPERATION, ELSE CR3 IS SET TO 0231 * HEX AND DUAL 8 BIT (800us) AND CR2 * IS SET TO TIME DIVIDED BY 800 AND * NORMAL 16 BIT MODE. THE MAXIMUM DELAY * IS ~52 sec. * ONTIME MOVE.L A0,WHERE(A6) SAVE ADDRESS ANDI.B #GC_MASK,D1 MASK BSET #ACTIVE,D1 SET ACTIVE MOVE.B D1,PTM_GC(A6) SAVE GOTO/CALL FLAG MOVE.L D0,-(A7) SAVE MOVE.W JUMPLONG,D1 JMP INSTRUCTION MOVE.W #LVL6INT,D0 LEVEL 6 VECTOR PEA PTMINT INTERRUPT SVC ROUTINE JSR FILL_VCTR FILL TRAP MOVE.L (A7)+,D0 RESTORE LEA PTM,A0 POINTER MOVEQ #CR_1,D1 SELECT CR1 MOVE.B D1,REG1(A0) * MOVE.B D1,REG0(A0) SET RESET MOVEQ #CR_3,D1 SELECT CR3 MOVE.B D1,REG1(A0) * MOVEQ #0,D1 ZERO ASR.L #2,D0 DIV 4us ADDX.L D1,D0 ROUND CMPI.L #$0000FFFF,D0 <2.09s BLS.S HIRES * * * 800us (LOW) RESOLUTION ONTIME * USE CR3 AS PRESCALER TO CLOCK CR2 * AT A 800us RATE. * BSET #LOWRES,PTM_GC(A6) SET LOW RES DIVU #200,D0 DIV 200 (800us) SWAP D0 * CMPI.W #100,D0 * REM>200/2 BLE.S ONTIME1 * ADDI.L #$10000,D0 * ROUND ONTIME1 MOVE.W #$0163,D0 CR3 = 01,99 * * SEND AN INTERRUPT ENABLE COMMAND MOVEQ #CONTMODE+CNTROUTEN+DUAL8,D1 BIT PATTERN 00+80+01+04 hex MOVE.B D1,REG0(A0) * SET UP CR2 & CR3 WITH DELAY MOVEP.L D0,REG4(A0) MOVEQ #CR_1+INTENABLE+CONTMODE+CNTROUTEN,D1 BIT PATTERN 00+80+01+04 hex MOVE.B D1,REG1(A0) * BRA.S ONTIME2 CONTINUE * * 4us (HIGH) RESOLUTION ONTIME * USE CR3 AS IN NORMAL 16 BIT MODE. * HIRES EQU * BCLR #LOWRES,PTM_GC(A6) MOVEQ #INTENABLE+CONTMODE+CNTROUTEN,D1 BIT PATTERN 00+80+01+04 hex MOVE.B D1,REG0(A0) * SET UP CR2 & CR3 WITH DELAY MOVEP.L D0,REG4(A0) MOVEQ #CR_1,D1 RESELECT CR1 MOVE.B D1,REG1(A0) * * ONTIME2 CLR.B REG0(A0) REMOVE RESET MOVEQ #20,D1 WAITAFEW SUBQ.W #1,D1 BNE WAITAFEW * MOVE #$2500,SR ENABLE INTERRUPTS * RTS * PTMINT MOVEM.L A1/D0,-(A7) SAVE LEA PTM,A1 GET STATUS MOVE.B REG1(A1),D0 * BGT NOPTMINT ABORT - NO PTM INT * * DISABLE FURTHER PTM INTERRUPTS * MOVEQ #CR_3,D0 MOVE.B D0,REG1(A1) CLR.B REG0(A1) MOVEQ #CR_1,D0 MOVE.B D0,REG1(A1) MOVEA.L WHERE(A6),A1 WHERE TO GO WITH CALL OR GO TO. BCLR #ACTIVE,PTM_GC(A6) BCLR #GC,PTM_GC(A6) WHAT TO DO (CALL (JSR) OR GO TO (JMP)). BNE.S PTMGO * * CALL A SUBROUTINE JSR (A1) CALL. MOVEM.L (A7)+,A1/D0 RESTORE RTE RETURN * JUMP TO SOME OTHER CODE PTMGO MOVE.L A1,-(A7) MOVEM.L 4(A7),A1/D0 RESTORE MOVE.L (A7),8(A7) MOVE WHERE ADDQ.L #8,A7 FIX STACK RTS GO * ---------------v ---v NOPTMINT MOVEM.L (A7)+,A1/D0 RESTORE <- HAS BUG, SHOULD BE "...,A1/D0... JMP EXCEPTION ABORT * **** SUBROUTINE TO RETURN IN D0 THE **** TIME LEFT FOR ONTIME INTERRUPT * SAVE_ONT BTST #ACTIVE,PTM_GC(A6) BEQ.S SAVE_ONX LEA PTM,A0 POINTER TO PTM * DISABLE INTERRUPT FROM CR2 & SELECT CR3 MOVEQ #CR_3,D0 SEND COMMAND MOVE.B D0,REG1(A0) * * DISABLE INTERRUPT FROM CR3 & SET SINGLE MOVEQ #SINGLE+CNTROUTEN,D0 MOVE.B D0,REG0(A0) BTST #LOWRES,PTM_GC(A6) BNE.S SAVE_LOW * * HIGH RESOLUTION (4us) CR3 ONLY MOVEQ #0,D0 GET VALUE MOVEP.W REG6(A0),D0 * LSL.L #2,D0 TIMES 4us BRA.S SAVE_ONT1 CONTINUE * * LOW RESOLUTION (800us) CR2 & CR3 SAVE_LOW MOVEM.L REG4-1(A0),D0-D1 GET CR2 & CR3 MOVEM.L D0-D1,-(A7) GET VALUE MOVEP.L 1(A7),D0 * ADDQ.L #8,A7 FIX STACK CMPI.W #$0163,D0 GLITCH VALUE? BEQ SAVE_LOW * TRY AGAIN CMPI.W #$0100,D0 ROUND BLT.S SAVE_LOW1 * ADDI.L #$00010000,D0 * SAVE_LOW1 CLR.W D0 * SWAP D0 SCALE IT MULU #800,D0 * TIMES 800 SAVE_ONT1 BCLR #ACTIVE,PTM_GC(A6) CLEAR FLAG SAVE_ONX RTS RETURN * PAGE * * ****************************************************************************** * * * SUBROUTINE NAME: WAIT_PTM/WAIT_1 * * * * PURPOSE: * * PARAMETER PASSED WAIT STATEMENT (USES D1.L IN MICRO SECONDS) * * PTM SHOULE BE INITIALIZED AT SOME TIME < 32 HOURS AGO. * * SAVES REGISTERS AS NEEDED. * * * ****************************************************************************** * ******************************************************************* * * * NOW WAIT JUST A VARIBLE MOMENT, YOU! LOOP ON THE PTM * * * * PASS IN THE NUMBER OF MICRO SECONDS TO WAIT IN D1.L! * * * ******************************************************************* * WAIT_PTM MOVEM.L D0-D1,-(SP) SAVE CALLER * DO_WAIT JSR GETPTM LOAD D0.L WITH CURRRENT TIME. * ADD.L D0,D1 SET D1 AS END TIME TO RETURN ON. * WAIT_LP_PTM JSR GETPTM LOAD D0.L WITH CURRRENT TIME. * CMP.L D0,D1 HAS TIME ELAPSED? * BHI WAIT_LP_PTM IF SO THWEN FALL THROUGH AND.... * MOVEM.L (SP)+,D0-D1 UN-SAVE CALLER * RTS * * ******************************************************************* * * * NOW WAIT JUST A ONE MILLISEC, YOU! * * * ******************************************************************* * WAIT_1 MOVEM.L D0-D1,-(SP) SAVE CALLER * MOVE.L #1000,D1 SET FOR 1 MILLI SECOND. * BRA DO_WAIT GO DO A 1 MILLI SECOND WAIT. * DC.W 0 LIBRARIAN.THINGIE * *GLITCH DC.B '*GLITCH*',$8D * END