;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