compile using as11-ic * icb file: "fencdr.asm" * placed in system interrupt * samples at 1000 Hz * Gary Livick 14 May 2000 * patterned after work by Fred Martin 22 Apr 1996 * 6811 registers BASE EQU $1000 ADCTL EQU $1030 ; A/D Control/status Register ADR1 EQU $1031 ; A/D Result Register 1 ADR2 EQU $1032 ; A/D Result Register 2 ADR3 EQU $1033 ; A/D Result Register 3 ADR4 EQU $1034 ; A/D Result Register 4 TOC4INT EQU $E2 ; Timer Output Compare 4 ORG MAIN_START * low and high thresholds for counting pulses variable_encoder_low_threshold: FDB 80 variable_encoder_high_threshold: FDB 125 * tick counts variable_encoder0_counts: FDB 0 variable_encoder1_counts: FDB 0 variable_encoder2_counts: FDB 0 variable_encoder3_counts: FDB 0 * defer flag from main program to bypass this module when not needed variable_enable_encoders: FDB 0 * internal variables encoder0_state: FCB 0 encoder1_state: FCB 0 encoder2_state: FCB 0 encoder3_state: FCB 0 * install module into 1 kHz IC system interrupt on TOC4 subroutine_initialize_module: LDX #$BF00 ; pointer to interrupt base * get current interrupt vector and save as next vector LDD TOC4INT,X ; SystemInt on TOC4 STD interrupt_code_exit+1 * install ourself as new vector LDD #interrupt_code_start STD TOC4INT,X * reset encoder variables LDD #0 STAA encoder0_state STAA encoder1_state STAA encoder2_state STAA encoder3_state STD variable_enable_encoders STD variable_encoder0_counts STD variable_encoder1_counts STD variable_encoder2_counts STD variable_encoder3_counts RTS * encoder interrupt code: interrupt_code_start: LDD variable_enable_encoders TSTB BNE continue JMP interrupt_code_exit ;skip everything if encoders not enabled continue: LDX #BASE * get analog reading LDAA #$10 ; set ADCTL to read first four ports STAA ADCTL,X BRCLR ADCTL,X $80 * ; wait here until conversion flag is set * process register ADR1 for state of encoder 0 LDAA ADR1,X TST encoder0_state ; see if last state was 0 BNE test_falling0 ; if not, branch to test_falling CMPA variable_encoder_high_threshold+1 BLO encoder_1 ; if the reading is less, branch to next encoder * otherwise, there was a state change got_click0: LDY variable_encoder0_counts INY STY variable_encoder0_counts LDAA encoder0_state EORA #$FF STAA encoder0_state BRA encoder_1 ; now go do the next one test_falling0: CMPA variable_encoder_low_threshold+1 BLO got_click0 * process register ADR2 for state of encoder 1 encoder_1: LDAA ADR2,X TST encoder1_state ; see if last state was 1 BNE test_falling1 ; if not, branch to test_falling CMPA variable_encoder_high_threshold+1 BLO encoder_2 ; if the reading is less, branch to next encoder * otherwise, there was a state change got_click1: LDY variable_encoder1_counts INY STY variable_encoder1_counts LDAA encoder1_state EORA #$FF STAA encoder1_state BRA encoder_2 ; now go do the next one test_falling1: CMPA variable_encoder_low_threshold+1 BLO got_click1 process register ADR3 for state of encoder 2 encoder_2: LDAA ADR3,X TST encoder2_state ; see if last state was 0 BNE test_falling2 ; if not, branch to test_falling CMPA variable_encoder_high_threshold+1 BLO encoder_3 ; if the reading is less, branch to next encoder * otherwise, there was a state change got_click2: LDY variable_encoder2_counts INY STY variable_encoder2_counts LDAA encoder2_state EORA #$FF STAA encoder2_state BRA encoder_3 ; now go do the next one test_falling2: CMPA variable_encoder_low_threshold+1 BLO got_click2 * process register ADR4 for state of encoder 3 encoder_3: LDAA ADR4,X TST encoder3_state; see if last state was 0 BNE test_falling3 ; if not, branch to test_falling CMPA variable_encoder_high_threshold+1 BLO interrupt_code_exit ; if the reading is less, branch exit * otherwise, there was a state change got_click3: LDY variable_encoder3_counts INY STY variable_encoder3_counts LDAA encoder3_state EORA #$FF STAA encoder3_state BRA interrupt_code_exit ; done, go to the exit test_falling3: CMPA variable_encoder_low_threshold+1 BLO got_click3 interrupt_code_exit: JMP$0000 ; this value poked in by init routine