**************** * SRPT.ASM - SMALL REPEATER CONTROLLER CODE * (C) 1993 Lance Lascari W S 2 B * * TODO: * cos checking needs to be moved to the tof service routine * Id timer needs to be restructured * - so we don't get awkward id'ing * ctcss encode is easy, I just haven't done it yet :) * ctcss decode shouldn't be too hard, I'm just busy/lazy * * - I/O - * PTT= PB 0 * AUDIO GATING = PB 1 * COS= PC 0 * CW TONE OUTPUT = PA 6 * DTMF DECODING: * DV* (INVERTED DV) = IRQ * D1 = PC 4 * D2 = PC 5 * D3 = PC 6 * D4 = PC 7 * * WRITTEN FOR A 68HC811E2 MICROCONTROLLER * Lance Lascari WS2B (and some of the cw routines derived from work * done on the 68705 by Dave Page ( K D 3 N C) * TONE IS GENERATED ON PA6 USING OUTPUT COMPARE 2 * * CWTONEVAL = (1/FREQUENCY)*10^6 **************** * EQUATES **************** CW_SPEED EQU $4FFF ; cw speed (I haven't come up with an eqn ) CWTONEVAL EQU !1250 ; 800 HZ BEEPTONE EQU !2000 ; 500 HZ TWO_+_HALF EQU !0076 ; Just values for delays FIVE_SEC EQU !0151 TEN_SEC EQU !0303 THIRTY_SEC EQU !0909 ONE_MINUTE EQU !1818 ; NUMBER OF 33 mS INCREMENTS TO DELAY THAT LONG TWO_MINUTE EQU !3636 THREE_MINS EQU !5454 ; I WOULD THINK WE WOULDN'T GO LONGER THAN THIS NINE_MINS EQU !16364 ; FOR ID TIMER * DTMF specifics.... NUM_O_CMDS EQU !8 ; SET TO THE NUMBER OF COMMAND STRINGS NUM_O_DIGS EQU !4 ; DIGITS PER STRING **************** #INCLUDE { c:\hc11\iasm11\includes\REGS.INC } **************** ************************************************************************ *************************** RAM VARIABLES ****************************** ************************************************************************ ORG $0090 TOTCNT RMB 2 ; TIMEOUT TIMER COUNTER TAILCNT RMB 2 ; TAIL/HANG TIMER COUNTER IDCNT RMB 2 ; ID TIMER COUNTER TIMERVAL RMB 2 ; FOR UTILITY TIMER ROUTINE MY_DELAY RMB 2 ; STORE ANY CUSTOM DELAY TIME HERE ID_ACT RMB 1 ; FLAG BYTE, SAYS ID TIMER IS RUNNING CW_DATA RMB 2 ; POINTER TO STRING PASSED TO SEND_CW() OC2_TONE RMB 2 ; BEEP AND CW TONE STORED HERE COS_ACT_F RMB 1 ; FLAG FOR DROP BEEP SAYS COS HAS BEEN ACTIVE TX_INH RMB 1 ; USE AS FLAG TO INHIBIT ALL TX ACTIVITY DTMF_BUFR RMB 4 ; HOLDS INCOMING DTMF STRINGS DTMF_FLAG RMB 1 ; SAYS THAT 4 DIGITS HAVE BEEN RX'D DTMF_ERR RMB 1 ; SAYS A BAD STRING WAS RECEIVED STR_CNT RMB 1 ; DTMF STRING COUNTER DURING COMPARES DIG_CNT RMB 1 ; 0-4 DIGIT COUNTER CMD_1_ RMB 1 ; DTMF variables that store the number CMD_2_ RMB 1 ; of "matched" digits.... CMD_3_ RMB 1 CMD_4_ RMB 1 CMD_5_ RMB 1 CMD_6_ RMB 1 CMD_7_ RMB 1 CMD_8_ RMB 1 PTR RMB 2 ; USE FOR GENERAL PURPOSES DTMF_PTR RMB 2 CHK_CMDS RMB 1 CHAR RMB 1 ; SCRATCHPAD PLACE FOR PUTTING ONE CHAR ********************************* ********************************* ********************************* ********************************* ********************************* ORG $F800 ; 68HC811E2 EEPROM BEGINNING RESET LDS #$0080 ; INITIALIZE STACK TO SOMEWHERE IN HERE LDX #REGBAS LDAA #$B0 ; !!!!! THIS REGISTER TIME PROTECTED STAA OPTION,X ; SET UP IRQ FOR FALLING EDGES JSR CW_INIT JSR TIME_INIT CLI LDY #RESET_STR ; get the standard s-comm reset string STY CW_DATA ; MOCK AN S-COMM LDY #!1666 ; 600 HZ TONE FOR STARTUP STY OC2_TONE CLR TX_INH ; MAKE SURE TX IS ENABLED UPON RESET JSR CARRIER ; TURN ON CARRIER LDY #TWO_+_HALF ; WAIT 2.5 SEC ON RESET BEFORE SENDING STRING STY MY_DELAY ; JSR TIM_DLY ; make the delay JSR SEND_CW ; send the string ; JSR ID ; NOW ID CLR ID_ACT ; MAKE SURE IT ONLY ID'S ONLY ONCE ON STARTUP CLR DTMF_FLAG ; CLEAR DTMF STUFF CLR DTMF_ERR ; LDY #DTMF_BUFR ; SET THE POINTER INITIALLY STY DTMF_PTR JMP Main ***************** ***************** * CW_INIT ***************** CW_INIT LDX #REGBAS ;INITIALIZATION LDAA #$00 STAA TMSK2,X LDAA #$40 ; SOME OUTPUT COMPARE STUFF (CW_TONE) STAA TFLG1,X RTS ********************************** ********************************** ********************************** ********************************** Main JSR COS_CHK ; SEE IF COS IS ACTIVE JSR TAIL_CHK ; CHECK THE STATUS OF THE TAIL JSR ID_CHK ; LOOK AT ID STATUS JSR TOT_CHK ; TIMEOUT STATUS JSR DTMF_CHK ; GET DTMF COMMAND STATUS BRA Main ; THIS IS IT, LOOP FOREVER ********************************** ********************************** ********************************** ********************************** * COS_CHK - TEST TO SEE IF COS IS ACTIVE ; IF SO, KEY TX ********************************** COS_CHK LDX #REGBAS BRSET PORTC,X,$01,COS_ACT ; IF THIS IS TRUE, COS IS ACTIVE JSR AUD_HALT ; STOP THE AUDIO IF NO COS JSR CLEAR ; IF NOT ACTIVE, CLEAR TOT COUNTER RTS COS_ACT JSR AUD_PASS ; LET THE AUDIO PASS IF COS JSR CARRIER ; NOW MAKE PTT ACTIVE LDAA #$FF STAA COS_ACT_F ; SET THE FLAG THAT SAYS COS IS ON PSHY LDY #$0000 STY TAILCNT ; RESET THE TAIL COUNTER SINCE COS PULY ; IS STILL ACTIVE LDAA ID_ACT ; SEE IF ID'ER NEEDS TO BE TURNED ON TSTA ; IS ID_ACT ZERO OR NOT? BNE COS_DUN ; FIRST (AND ONLY) TRIGGER FOR ID FIRST LDAA #$FF STAA ID_ACT ; SET FLAG FOR ID JSR ID ; ID SINCE IT'S BEEN INACTIVE PSHY LDY #$0000 ; INITIALIZE THE ID TIMER BY STY IDCNT ; CLEARING IT'S COUNTER PULY COS_DUN RTS ********************************** ********************************* * CLEAR - CLEARS THE TOT COUNTER ********************************* CLEAR PSHY LDY #$0000 ; STY TOTCNT PULY RTS ********************************* ********************************* * TOT_CHK - CHECKS THE STATUS OF THE TIMEOUT TIMER ********************************* TOT_CHK PSHY LDY TOTCNT ; GET THE CURRENT COUNT VALUE CPY #THREE_MINS ; LEGAL TIMEOUT DELAY PULY BHS YES_TOT ; IF GREATER THAN OR EQUAL TO, T.O. JMP TOT_DUN ; OTHERWISE, RETURN TO Main YES_TOT JSR AUD_HALT JSR ID ; IDENTIFY BEFORE DROPPING OUT JSR CARRIER PSHY ; Preserve Y LDY #TIMEOUT ; STY CW_DATA ; SEND TIMEOUT STRING PULY JSR SEND_CW JSR UNCARRIER TOT_LUP BRSET PORTC,X,$01,TOT_LUP ; LOOP HERE UNTIL COS GOES AWAY PSHY LDY #AFTR_TOT ; GET WAKEUP STRING STY CW_DATA ; ONCE AGAIN, PASS POINTER LDY #TWO_+_HALF STY MY_DELAY ; WAIT 2.5 SECS. AFTER CARRIER COMES^ PULY JSR CARRIER JSR TIM_DLY ; ACTUALLY EXECUTE THE DELAY HERE JSR SEND_CW ; SEND THE STRING JSR UNCARRIER TOT_DUN RTS ********************************* ********************************** * TAIL_CHK - CHECKS UP ON THE TAIL COUNTER TO SEE IF THE TX SHOULD DROP * OUT ********************************** TAIL_CHK PSHY LDY TAILCNT ; GET TAIL COUNTER AGAIN CPY #FIVE_SEC ; PULY BHS DROP RTS ; IF HIGHER THAN OR EQUAL, DROP PTT DROP PSHY LDY #BEEPTONE ; for the "drop" beep STY OC2_TONE PULY LDAA COS_ACT_F ; SEE IF COS HAS BEEN ACTIVE TSTA BEQ NOT ; JUMP AROUND WHEN INACTIVE JSR KEY JSR DELAY JSR UNKEY ; TAIL DROP BEEP, USE A CW "DIT" JSR DELAY NOT JSR UNCARRIER ; DROP PTT CLR COS_ACT_F RTS ********************************** ********************************** * ID_CHK - CHECKS THE ID INTERVAL TIMER TO SEE IF IT'S TIME TO ID ********************************** ID_CHK LDAA ID_ACT ; SEE IF ID TIMER IS RUNNING (THIS FLAG) TSTA ; TEST 4 ZERO BEQ ID_BYE ; IF IT IS ZERO I'M NOT WANTED PSHY ; IT IS ACTIVE :-) LDY IDCNT ; GET COUNTER VALUE CPY #NINE_MINS ; COMPARE TO REFERENCE COUNT PULY BHS ID_YES ; Joy ! RTS ID_YES PSHY LDY #$0000 ; CLEAR THE ID COUNTER + FLAG, THEN ID STY IDCNT PULY CLR ID_ACT JSR ID ID_BYE RTS ********************************** ********************************** * ID - LOADS ADDRESS OF IDENTIFIER STRING INTO THE LOCATION CW_DATA, THEN * JUMPS TO SEND_CW, TO SEND THAT STRING ********************************** ID JSR CARRIER PSHY LDY #CWTONEVAL ; SET ID TO 800 HZ STY OC2_TONE LDY #IDER STY CW_DATA ; FOR GREATEST FLEXIBILITY, USE A POINTER PULY JSR SEND_CW JSR UNCARRIER RTS ********************************** ********************************** * DTMF_CHK - CHECKS TO SEE IF THERE ARE ANY COMPLETE COMMAND STRINGS IN IT'S * BUFFER, AS WELL AS CHECKING FOR ERRORS * - THEN IF NO ERRORS, IT COMPARES THE STRING RX'D TO IT'S OWN * COMMAND STRINGS * The value "DTMF_FLAG" is nonzero if a complete DTMF string has * been recieved. ********************************** DTMF_CHK TST DTMF_FLAG ; GET THE FLAG, IF NONZERO , LOOK CLOSER BEQ DTMF_BYE ; ELSE, JUST RETURN TST DTMF_ERR ; SEE IF THE ERROR FLAG IS NONZERO BNE SEND_ERR PSHX ; PRESERVE THESE DAMMIT!!!!! PSHY LDY #CMD_1_-1 ; POINTER GETS INCREMENTED ONCE BEFORE USED STY PTR ; , SO COMPENSATE FOR THAT BY SUBTRACTING 1 LDY #C_1_ ; FIRST COMMAND STRING TO BE POINTED TO LDAA #NUM_O_CMDS STAA STR_CNT ; THIS IS THE OUTER LOOP COUNTER OUT_LUP LDX #DTMF_BUFR ; POINTER TO DTMF BUFFER TST STR_CNT BEQ CMPR_DUN DEC STR_CNT PSHY LDY PTR ; PTR POINTS TO COMMAND BYTE FLAG THINGS INY ; POINT TO THE NEXT ONE STY PTR PULY LDAA #NUM_O_DIGS INCA ; ADD ONE 'CAUSE OF FUNKY LOOP STAA DIG_CNT ; INNER LOOP COUNTER IN_LUP DEC DIG_CNT ; KNOCK ONE OFF THE LOOP TST DIG_CNT ; TEST FOR ZERO BEQ IN_DUN ; IF ZERO, GO TO THE OUTER LOOP ONCE AGAIN LDAA 0,X ; GET FIRST DIGIT OUT OF THE BUFFER LDAB 0,Y ; GET ONE FROM COMMAND STRING INX ; INCREMENT POINTERS TO BOTH STRINGS INY CBA ; COMPARE THE TWO BNE IN_LUP PSHY LDY PTR ; GET POINTER TO COMMAND BYTE N INC 0,Y ; ADD ONE TO IT ( IF A FULL MATCH OCCURS, PULY ; THE BYTE WILL READ $04 BRA IN_LUP IN_DUN BRA OUT_LUP ; D BOTTOM OF D LOOPS CMPR_DUN JMP DONE SEND_ERR PSHY ; SENDS "ERR" IN CW LDY #ERR_STRING ; GET POINTER TO STRING STY CW_DATA ; PASS IT PULY JSR SEND_CW ; SEND THE STRING CLR DTMF_ERR CLR DTMF_FLAG RTS DONE PULY ; GET THEM REGS BACK PULX CLR DTMF_ERR ; CLEAR THE ERROR FLAG CLR DTMF_FLAG ; CLEAR THE "NEW STUFF" FLAG LDAA #$FF STAA CHK_CMDS ; FOR THE CMD_EXE ROUTINE JSR CMD_EXE ; GO TO THE OTHER HALF OF THIS WHOLE ROUTINE DTMF_BYE RTS ; RETURN ********************************** ** THE REASON THESE ROUTINES ARE SPLIT IN TWO IS TO ADD FLEXIBILITY, ** THIS WHOLE SECTION IS FAIRLY COMPLEX, SO I BROKE IT DOWN FOR DEVELOPMENT/ ** DEBUGGING PURPOSES, JUST CONSITER IT ONE BIG SUBROUTINE ********************************** *CMD_EXE - LOOKS AT ALL THE COMMAND BYTES, SEES WHAT TO DO, AND EXECUTES * THE APPROPRIATE ROUTINES ********************************** CMD_EXE TST CHK_CMDS ; SEE IF I HAVE ANYTHING TO INTERPRET BEQ EXE_BYE PSHY ; AS ALWAYS, PRESERVE THESE REGISTERS PSHX LDAA #NUM_O_CMDS ; USE ACCA AS A LOOP COUNTER LDAB #NUM_O_DIGS ; COUNTERS READ # OF DIGITS THAT MATCHED LDY #SUB_TABLE ; TABLE OF "JUMP" ADDR'S FOR SUBROUTINES LDX #CMD_1_ ; ADDR OF 1ST CMD COUNTER (# OF MATCHES) CMD_LUP TSTA ; SEE IF WE'VE LOOPED ENOUGH BEQ CMD_DUN ; ACTUALLY IF THIS IS TRUE, ALL STRS BAD CMPB 0,X ; SEE IF ALL DIGITS MATCHED THIS ONE BEQ CMD_MATCH ; IF ALL MATCHED, JUMP TO ROUTINE INY ; INC THREE TIMES, IT'S A JUMP TABLE INY ; addr=2 bytes, jmp instruction is 1 byte INY ; 2 + 1 = 3 INX ; MOVE TO THE NEXT COMMAND COUNTER DECA ; LOOP COUNTER -- BRA CMD_LUP ; LOOP UNTIL WE GET A MATCH CMD_MATCH PSHY LDY #TWO_+_HALF ; WAIT 2.5 SECS TO RESPOND TO THE USER STY MY_DELAY PULY JSR SEND_RRR ; SEND RRR IN CW FOR USER RESPONSE JSR 0,Y ; USE JUMP TABLE TO GO TO COMMAND SUBR. CMD_DUN PULX PULY EXE_BYE CLR CHK_CMDS JSR CLEAR_FLGS ; CLEAR FLAGS FOR NEW DATA TO ARRIVE RTS ********************************** ********************************** * CLEAR_FLGS - CLEARS COMMAND FLAGS ( COUNTERS FOR DTMF STRING COMPARASINS) ********************************** CLEAR_FLGS PSHY PSHA LDAA #NUM_O_CMDS ; USE THIS AS A COUNTER TO CLEAR FLAG LDY #CMD_1_ ; BYTES CLR_LUP TSTA ; TEST THE LOOP COUNTER FOR 0 BEQ CLR_DUN DECA ; LOOP COUNTER -- CLR 0,Y ; CLEAR CORRESPONDING BYTE INY ; MOVE TO THE NEXT BYTE BRA CLR_LUP ; LOOP UNTIL CORRECT # OF FLAGS CLEARED CLR_DUN PULA PULY RTS ********************************** ********************************** * OK, SENDS "OK" IN MORSE - TO GIVE SOME RESPONSE TO DTMF COMMANDS ETC. ********************************** OK PSHY LDY #OK_STRING ; PASS A 16 BIT POINTER TO SEND_CW() STY CW_DATA PULY JSR CARRIER JSR SEND_CW ; RTS ********************************** ********************************** * TIME_INIT, INITIALIZES TOF TIMER, ENABLES THE TOF INTERRUPT ETC. ********************************** TIME_INIT BCLR TFLG2,X,$7F BSET TMSK2,X,$80 RTS ********************************** ********************************** * TIM_DLY, CREATE A LONG DELAY ( IN TERMS OF CLOCK CYCLES ) BY COUNTING * TIMER OVERFLOWS. WHEN USING AN 8 MHZ CRYSTAL, THIS OCCURS EVERY * 33mS ********************************** TIM_DLY PSHY ; IN CASE I EVER DECIDE TO USE Y ELSEWHERE LDY #$0000 STY TIMERVAL LOOP LDY TIMERVAL CPY MY_DELAY BNE LOOP ; LOOP UNTIL THE TIMER OVERFLOWS THE CORRECT PULY ; NUMBER OF TIMES RTS ********************************** ********************************** * SEND_RRR - JUST DOES WHAT IT SAYS, SENDS " R R R " IN CW ********************************** SEND_RRR PSHY LDY #RRR_STRING ; GET STRING POINTER STY CW_DATA JSR CARRIER ; KEY TX JSR SEND_CW ; SEND THE STRING JSR UNCARRIER ; UNKEY PULY RTS ********************************** ********************************** * TX_INHIBIT - SETS FLAG BYTE, AND DISABLES THE TRANSMITTER ********************************** TX_INHIBIT: LDAA #$FF STAA TX_INH ; MAKE THE FLAG NONZERO (CAN USE TST NOW) JSR UNCARRIER ; TAKE IT DOWN IMMEDIATELY RTS ********************************** ********************************* * TX_ON - NEGATES THE ABOVE ********************************* TX_ON CLR TX_INH ; CLEAR THE BYTE, ENABLING TX ONCE AGAIN JSR SEND_RRR ; THE USUAL RRR WON'T BE HEARD,SO DO THIS RTS ********************************* ********************************** * CARRIER /UNCARRIER JUST USED TO ACTIVATE PTT PORT B ( PB 0) *********************************** CARRIER TST TX_INH ; SEE IF THE ANTI-TX BYTE IS NONZERO BNE CAR_END ; IF SO, DON'T TX PSHX LDX #REGBAS BSET PORTB,X,$01 PULX CAR_END RTS UNCARRIER PSHX LDX #REGBAS BCLR PORTB,X,$01 PULX RTS *********************************** *********************************** * KEY/UNKEY - FOR KEYING CWID TONE *********************************** KEY PSHX LDX #REGBAS BSET TMSK1,X,$40 ;ENABLE INTERRUPT(TOC2)(FOR FM TONE KEYING) BSET TCTL1,X,$40 ; TOGGLE ON OUTPUT COMPARE PULX RTS UNKEY PSHX LDX #REGBAS ; SAME AS ABOVE BUT BASS-ACKWARDS BCLR TMSK1,X,$40 BCLR TCTL1,X,$C0 ; DISCONNECT TOC2 TIMER FROM OUTPUT PIN PULX RTS ******************************************************* ******************************************************* * AUD_PASS / AUD_HALT - TOGGLE PORT B, BIT 1 * FOR USE WITH A 4066 SWITCH TO GATE RX AUDIO * AUD_HALT IS ALSO NICE FOR BLANKING DTMF (PROGRAMMING) TONES * SO IT MAKES JAM-HACKERS WORK A BIT HARDER ******************************************************* AUD_PASS PSHX LDX #REGBAS BSET PORTB,X,$02 ; TURN THE 4066 ON PULX RTS AUD_HALT PSHX LDX #REGBAS BCLR PORTB,X,$02 ; TURN IT OFF PULX RTS ******************************************************* ****************** MAIN CW-SENDING ROUTINE************* * ADDR OF THE START OF THE STRING SHOULD BE STORED IN CW_DATA BEFORE ENTRY ******************************************************* SEND_CW PSHX PSHY PSHA PSHB LDX CW_DATA ; LOAD 16 BIT POINTER TO THE STRING TO BE SENT CW_LOOP LDAB 0,X ; LOAD CHAR BY CHAR UNTIL STRING COMPLETE INX ; INCREMENT TO NEXT CHAR FOR NEXT TIME AROUND THE LOOP CMPB #$FF BEQ SCW_BYE JSR SENDCW_CHR BRA CW_LOOP SCW_BYE PULB PULA PULY PULX SCW_DIE RTS SENDCW_CHR: LDY #CWTABLE-1 ; GET THE BEGINNING OF THE TABLE CHR_LUP INY CMPB 0,Y ; SEE IF THE CHAR IN MY STRING MATCHES WHAT WE BNE CHR_LUP INY ; NOW MOVE FROM THE ASCII CHAR TO THE CW ELEMENTS JSR DELAY ; ARE LOOKING AT IN THE TABLE (SCAN THE TABLE) JSR DELAY LOOPSCW JSR DELAY LDAA 0,Y INY DECA ; dec the entry once each step, if one... BEQ DIT ; it will now be zero etc... DECA BEQ DAH DECA BEQ WAIT RTS DELAY PSHX ; THIS DELAY LOOP HERE ACTUALLY SETS THE CW SPEED JSR COS_CHK ; CHECK COS MORE OFTEN WHEN ID'ING LDX #CW_SPEED IN_LOOP DEX BNE IN_LOOP PULX RTS WAIT JSR DELAY BRA LOOPSCW DAH JSR KEY JSR DELAY JSR DELAY JSR DELAY JSR UNKEY JMP LOOPSCW DIT JSR KEY JSR DELAY JSR UNKEY JMP LOOPSCW ; ********************************* * "COMMANDS" GO IN HERE - (YOU KNOW, THE ONES THAT GET EXECUTED BECAUSE OF * CERTAIN FEW DTMF STRINGS ********************************* THREE JSR OK PSHY LDY #ONE_MINUTE ; PRODUCE ONE MINUTE OF TONE + CARRIER FOR STY MY_DELAY ;DEVIATION ADJUSTMENTS ETC. PULY JSR CARRIER JSR KEY JSR TIM_DLY JSR UNKEY JSR UNCARRIER RTS FOUR RTS ; these all just dummies FIVE RTS SIX RTS SEVEN RTS EIGHT RTS ********************************* ********************************* ********************************** * OC2_SVC, OUTPUT COMPARE INTERRUPT SERVICE ROUTINE, TOGGLES TO PRODUCE TONE * ON PA6 ********************************** OC2_SVC LDX #REGBAS LDD OC2_TONE ; ADD ON ONE MORE HALF CYCLE DELAY ADDD TOC2,X STD TOC2,X BSET TFLG1,X,$40 ; CLEAR THE FLAGS RTI ************************************ *********************************** * TOF_SVC, TIMER OVERFLOW INTERRUPT SERVICE ROUTINE * LONG DELAY TIMES DERIVED FROM TIMER OVERFLOW, THIS OCCURS EVERY * 33mS WHEN RUNNING AN 8 MHZ CRYSTAL, GOOD ENOUGH RESOLUTION FOR IT'S * SIMPLICITY ! *********************************** TOF_SVC LDX #REGBAS ; INCREMENT ALL SYSTEM TIMERS LDY TAILCNT ; HANG TIMER VALUE INY STY TAILCNT LDY TOTCNT ; GET TIMEOUT TIMER COUNTER VALUE INY STY TOTCNT LDY IDCNT ; ID INTERVAL TIMER INY STY IDCNT LDY TIMERVAL ; THIS ONE FOR UTILITY DELAY ROUTINE INY STY TIMERVAL LDAA #$80 STAA TFLG2,X ; CLEAR THE FLAGS RTI *********************************** ************************************ * IRQ_SVC, INTERRUPT REQUEST SERVICE ROUTINE (EXTERNAL IRQ PIN TRIGGERED) * FIRES WHEN DTMF TONE IS DETECTED, THE DV LINE ON THE SSI202 * IS INVERTED THEN FED THE IRQ PIN ON THE HC11 ************************************ IRQ_SVC TST DTMF_FLAG ; MAKE SURE FLAG IS CLEAR BNE LATER ; (PREVIOUS STRING PROCESSED) LDY DTMF_PTR ; WHERE DO I STORE THE CHAR CPY #DTMF_BUFR+4 ; SEE IF WE'VE GOTTEN ALL DIGITS. BEQ LAST ; IF THIS DIGIT ISN'T A *, |ERROR| BRA NORM LAST LDAA #$FF STAA DTMF_FLAG ; MAKE IT NONZERO NORM LDAA PORTC,X ; GET THE DIGIT FROM PORTC ( HIGH 4BITS) ANDA #$F0 ; HACK OFF LOWER 4 CMPA #$B0 ; SEE IF IT'S THE STAR (*) TERMINATOR BEQ TERMINATE ; IF SO, HANDLE ACCORDINGLY CMPA #$C0 ; DTMF "CLEAR" COMMAND BEQ DTMF_CLR ; FLUSH BUFFERS ETC TST DTMF_FLAG ; SEE IF THIS IS THE LAST BNE DTMFERROR ; IF THIS IS THE "LAST", AND NOT *, ERR! STAA 0,Y ; OTHERWISE, PUT IN THE BUFFER INY ; INCREMENT POINTER STY DTMF_PTR ; GIVE BACK THE POINTER JMP DTMF_DUN ; NORMALLY JUST RETURN FROM THE INT. TERMINATE LDAA #$FF ; SET FLAG BYTE TO $FF WHEN * DETECTED STAA DTMF_FLAG LDY DTMF_PTR ; GET POINTER TO SEE WHICH DIGIT I'M ON CPY #DTMF_BUFR+4 ; SEE IF THIS SHOULD BE A TERMINATION BLO DTMFERROR ; IF NOT, SET ERROR FLAG AGAIN LDY #DTMF_BUFR ; RESET POINTER TO BASE ADDR OF BUFFER STY DTMF_PTR JMP DTMF_DUN ; JUMP TO END DTMFERROR LDAA #$FF ; MAKE ERROR FLAG $FF STAA DTMF_ERR STAA DTMF_FLAG ; SET DTMF FLAG, 'CAUSE OF ERROR LDY #DTMF_BUFR ; RESET POINTER STY DTMF_PTR DTMF_DUN RTI DTMF_CLR LDY #DTMF_BUFR STY DTMF_PTR ; RESET POINTER LDY #DTMF_BUFR ; CLEAR ALL THESE VARIABLES CLEAN CLR 0,Y INY CPY #PTR+1 ; END OF THAT STUFF BNE CLEAN ; CLEAN UNTIL ALL DONE LATER RTI ; RETURN FROM THE INTERRUPT ************************************ ********************************* * DATA AREA - CW STRINGS TO BE SENT GO HERE AS DO DTMF COMMAND STRINGS * NOTE: ALL CW STRINGS ARE TERMINATED WITH A $FF FOR SEND_CW() ********************************** ; W2SZ = Rensselaer Polytechnic inst. ; ARC. IDER FCB "DE W2SZ/R",$FF ;w2sz/r RESET_STR FCB "? RES",$FF ; S-COMM like ;-) TIMEOUT FCB "TIMEOUT",$FF ; not very creative here... AFTR_TOT FCB " GOOBER",$FF ; Scold the Longwinded OK_STRING FCB " OK",$FF ; ERR_STRING FCB " ERR",$FF ; RRR_STRING FCB " RRR",$FF ; BYE_STRING FCB "BYE",$FF ; HI_STRING FCB "HI",$FF ; #INCLUDE { c:\hc11\iasm11\includes\ASCIICW.INC } ********************************* * COMMAND STRING TABLE: * beginning address is C_1_ ********************************* C_1_ FCB $40,$40,$30,$A0 C_2_ FCB $40,$40,$30,$10 C_3_ FCB $20,$20,$20,$20 C_4_ FCB $30,$30,$30,$30 C_5_ FCB $40,$40,$40,$40 C_6_ FCB $50,$50,$50,$50 C_7_ FCB $60,$60,$60,$60 C_8_ FCB $70,$70,$70,$70 ********************************** * SUBROUTINE TABLE: * used to reference "user" commands, i.e. dtmf related functions * This length (in entries) is equal to NUM_O_COMMANDS. ********************************** SUB_TABLE JMP TX_INHIBIT ; JMP TX_ON ; JMP THREE ; JMP FOUR ; JMP FIVE JMP SIX JMP SEVEN JMP EIGHT ********************************** * DTMF TABLE - THE OUTPUT OF THE SSI202 IN THE HIGH 4 BITS OF PORTC * { FOR REFERENCE ONLY } * * 1 $10 * 2 $20 * 3 $30 * 4 $40 * 5 $50 * 6 $60 * 7 $70 * 8 $80 * 9 $90 * 0 $A0 * * $B0 ; USED TO TERMINATE DTMF STRING * # $C0 ; USED TO CLEAR DTMF BUFFERS ETC. * A $D0 * B $E0 * C $F0 * D $00 *********************************** ************************************ * INTERRUPT VECTOR JUMP TABLE ************************************ ORG $FFD6 FDB RESET FDB RESET FDB RESET FDB RESET FDB TOF_SVC FDB RESET FDB RESET FDB RESET FDB OC2_SVC FDB RESET FDB RESET FDB RESET FDB RESET FDB RESET FDB IRQ_SVC ;RESET FDB RESET FDB RESET FDB RESET FDB RESET FDB RESET FDB RESET ************************************