;DESIGNED TO RUN ON THE Motorola 68HC11 EVBU BOARD
;This program will read in pulses on PA7, and will use the
;pulse accumulator features to measure the pulse frequency using a
;1-sec timing window. The resulting frequency will be displayed
;to the monitor screen each second, in decimal format.
;This program is similar to "freq.asm" except that it uses hardware timing
;instead of (ugh - software delay loops) to effect much more accuracy.
.org $0000
outst0 .cequ $FFCA
outa .cequ $FFB8
TFLG2 .cequ $1025
TMSK2 .cequ $1024
PACNT .cequ $1027
PACTL .cequ $1026
TCNT .cequ $100E
jmp main
pc: ;RAM variable for pulse count information(2 bytes)
pcmsb: .rs 1
pclsb: .rs 1
temp: .rs 2 ;temporary variable for doing arithmetic
mytick: .rs 2
.org $0100
main: clr pcmsb ;initialize pulse count to zero
clr pclsb
clr PACNT
ldaa #$7E ;initialize psuedo interrupt vector
staa $00CD ;for pulse Acc. overflow interrupt
ldd #mypai
std $00CE
ldy #TFLG2
bset 0,Y,b'00100000 ;clear PAOVF flag by writing a one to it
ldy #TMSK2
bset 0,Y,b'00100000 ;enable PA overflow interrupt
ldy #PACTL
bclr 0,Y,b'10110000 ;PA7 as input/Event counter/falling edge
bset 0,Y,b'01000000 ;enable pulse accumulator
cli ;enable global interrupts
mytim: ;beginning of 1-sec hardware time delay loop
;1 sec encompasses 30 timer overflows plus 1,536 additional ticks
ldd TCNT ;read current tick count.
addd #(1536-32) ;Compute final tick count after 30 overflows occur
std mytick ;The 32 adjustment accounts for instr. exec. time
ldaa #30 ;loop counter to count overflows
lp1: ldy #TFLG2 ;address of the TFLG2 register
bset 0,Y,$80 ;clear the timer overflow flag bit
brclr 0,Y,$80,* ;loop until flag gets set
deca ;decrement a, loop 'till 30 overflows occur
bne lp1
lp2: ldd TCNT
cpd mytick ;wait until additional ticks expire
bls lp2
;OK -- 1 sec is up. First halt PA
ldy #PACTL
bclr 0,Y,b'01000000
;Write contents of pacnt to pclsb
ldab PACNT
stab pclsb
jsr disply ;display results to the screen
clr PACNT ;clear the pulse accumulator
clr pclsb ;clear RAM pulse count locations
clr pcmsb
;MUST USE INDEXED ADDRESSING FOR BSET AND BCLR
ldy #PACTL
bset 0,Y,b'01000000 ;restart the pulse accumulator
bra mytim ;start timing again
myflag: .rs 1 ;flag used to keep track of leading zeros
disply: ;subroutine to display characters to the screen
;largest frequency is 65,535 Hz. Will need to display 5 characters.
clr myflag ;variable to track leading zeros
ldd pc
ldx #10000 ;find ten thousands digit
idiv
std temp ;save remainder to RAM
ldab #48 ;add 48d to (IX) to convert number to ASCII
abx
xgdx ;exchange X with D
tba ;transfer B to A
cmpa #'0' ;see if its 0 - suppress if so
beq j1
inc myflag ;indicate future zeros not to be suppressed
jsr outa ;write result out using Buffalo routine
j1: ldd temp ;now find 1000's digit
ldx #1000
idiv
std temp
ldab #48
abx
xgdx
tba
addb myflag
cmpb #'0'
beq j2
inc myflag
jsr outa
j2: ldd temp ;now find 100's digit
ldx #100
idiv
std temp
ldab #48
abx
xgdx
tba
addb myflag
cmpb #'0'
beq j3
inc myflag
jsr outa
j3: ldd temp ;now find 10's digit
ldx #10
idiv
std temp
ldab #48
abx
xgdx
tba
addb myflag
cmpb #'0'
beq j4
inc myflag
jsr outa
j4: ldaa temp+1 ;remainder is the one's digit-never suppress
adda #48
jsr outa
ldx #term
jsr outst0 ;send a termination string
rts
term: .db " Hz",13,10,$04 ;termination string for each line(CRLF/EOT)
mypai: ;interrupt handler for pulse accumulator overflow
inc pcmsb ;add 256 to current pulse count
ldy #TFLG2
bset 0,Y,b'00100000 ;reset PAOVF flag by writing a 1 to it
rti
.end