; THIS PROGRAM IS THE CONTROL FOR THE ; 6 LINE CALL PROCESSOR. IT IS TARGETED ; FOR AN 8749 RUNNING AT 10.00 MHZ. ; TMS6.ASM BY BILL HEIDEMAN ; VERSION 1.6 SEPTEMBER 1,1987 ;***************************************** ; ; TEST FIXTURE HAS EXTERNAL ; RECORD ON LINE 1, PRODUCTION ; HAS IT ON LINE 4. FIND ***** ; ;COMCHN EQU 33 ;FOR TEST FIXTURE COMCHN EQU 36 ;FOR PRODUCT ;***************************************** ; DECLARED DATA TMCT0 EQU 32 ;TIMER COUNTER 0 MATRIX EQU 33 ;CROSS POINT MATRIX (6) DSPOT EQU 39 ;DISPLAY OUTPUT (4) FRSTMR EQU 43 ;FIRST RECORD TIMER BCD (2) SWITCH EQU 45 ;RAW SWITCH DATA DSPCNT EQU 46 ;DISPLAY BYTE CNTR HVAL EQU 47 ;RAW H LINE VALUE HPHAS EQU 48 ;H LINE DEBOUNE CNTR (6) RPHAS EQU 54 ;RING PHASE CNTR (6) RNGCTR EQU 60 ;RING COUNTERS (6) VOCTMS EQU 66 ;VOICE RECORDED TIME DUM32 EQU 67 ;DUMMY 32 SEC DISPLAY (2) TONOT EQU 69 ;TONE OUTPUT WORD STKPTR EQU 70 ;STACK POINTER MATPTR EQU 71 ;MATRIX POINTER DISBLK EQU 72 ;DISPLAY BLANK WORD ; D0=202P READING ; D1=VOICE CODSWT EQU 73 ;CODE SWITCH TONEIN EQU 74 ;INCOMING KEY FROM 202P'S LNSTUS EQU 75 ;LINE STATUS (6) ; 0=IDLE ; D0=RING ; D1=IN USE HLDEB EQU 81 ;DEBOUNCED H LINES HANGUP EQU 82 ;HANG-UP REQUEST FLGS RECDAT EQU 83 ;VOICE SET-UP DATA ; D1-D0=PHASE ; D3-D2=PHRASE NUMBER ; D5-D4=SPEED ; D6=STOP FLAG ; D7=RECORD FLAG SWTCHG EQU 84 ;SWITCH CHANGED BITS TMCT1 EQU 85 ;.5 SECOND TIMER SWTLST EQU 86 ;LAST SWITCH READ VALUE SWTDEB EQU 87 ;DEBOUNCED SWITCH VALUE SWTDCD EQU 88 ;DECODED SWITCH VALUE ; D0=OFF ; D1=RECORD ; D2=ANSWER ; D3=(SPARE) ; D4=DAY 5 ; D5=DAY 3 ; D6=NIGHT MSG1ST EQU 89 ;FIRST MESSAGE FLGS ; D0=FIRST REOCRD ; D1=REDO FIRST MESSAGE HLD30 EQU 90 ;30 SECOND TIMER ANSPHS EQU 91 ;ANSWER PHASE TONPHS EQU 92 ;TONE PHASE HLDPHS EQU 93 ;HOLD PHASE ;******************************************** ; THESE VALUES MUST STAY TOGETHER NUMINB EQU 94 ;IN BOUND CALLS (2) NUMANS EQU 96 ;CALLS ANSWERED (2) NUMABN EQU 98 ;CALLS ABANDONED (2) ;******************************************** RECTIM EQU 100 ;RECORDING TIME BCD (2) VCRCTM EQU 102 ;VOICE RECORD TIMER DSPFLS EQU 103 ;DISPLAY FLASH FLAG VCPLTM EQU 104 ;PLAY BACK TIMER VOCMD EQU 105 ;VOICE MONITOR COMMAND ; D0=PLAY LAST ; D1=DAY 5 MSG ; D2=DAY 3 MSG ; D3=NIGHT MSG ; D4=PLAY ALL ; D5=STOP ; D6=PLAY/REC ; D7=REMOTE RPLTMR EQU 106 ;RECORD TIMER RECLST EQU 107 ;LAST CHANNEL RECORDED ;******************************************* ; THESE VALUES MUST STAY TOGETHER ANSDLY EQU 108 ;ANSWER MONITOR DELAY TONDLY EQU 109 ;TONE MONITOR DELAY HLDDLY EQU 110 ;HOLD MONITOR DELAY RESTMR EQU 111 ;STAT RESET TIMER ;******************************************* FRSDNC EQU 112 ;FIRST MSG DOWN TIMER FRSREC EQU 113 ;FIRST MESSAGE RECORDED SWTOLD EQU 114 ;OLD SWITCH COMMAND STACK EQU 115 ;CALL PROGRESS STACK (6) REMOTE EQU 121 ;REMOTE MODE FLAG RESCNT EQU 122 ;STAT RESET COUNT RPLPHS EQU 123 ;REPLAY ALL PHASING ; D3-D0=PHASE ; SEND MSG,WAIT FOR BUSY ; WAIT FOR DONE,PAUSE ; D5-D4=MSG NUMBER TONFLG EQU 124 ;SINGLE TONE PHASE ANSERD EQU 125 ;LINES ANSWERED FRSTIM EQU 126 ;FIRST MESSAGE TIME (2 BCD) ;F0 READ FLAG ;F1 DISPLAY ONE'S ;R7 RECDED RECORDED MESSAGES ;R7' ACC SAVE ;R6' TONE DELAY ;THIS IS THE MAIN RESTART FROM POWER-UP ORG 000H MAIN: MOV R2,#112 CLR A MOV R0,#10H ;CLEAR ALL RAM JMP MAIN1 ;THIS ROUTINE IS THE REAL TIME CLOCK. ;IT IS CALLED EVERY 2 MSEC FROM AN ;INTERNAL TIMER. ORG 007H TMR: SEL RB1 MOV R7,A ;SAVE STATUS MOV A,#0D8H ;RESET TIMER TO 2 MSEC MOV T,A STRT T CALL HLRD ;DO H LINE FILTER MOV R0,#TMCT0 INC @R0 ;INCR TIMER MOV A,@R0 ANL A,#0FH JNZ TMR2 ;IF NOT 32 MSEC CALL TONE ;DO TONE OUTPUT CALL DLYS ;DO MONITOR DELAYS CALL SWDB ;DO SWITCH DEBN MOV R0,#TMCT0 MOV A,@R0 ANL A,#3FH JNZ TMR2 ;IF NOT 128 MSEC CALL RGDT CALL VCTM ;DO VOICE TIMER TMR2: MOV R0,#TMCT0 MOV A,@R0 JNZ TMR4 ;IF NOT .5 SEC MOV R0,#TMCT1 INC @R0 ;INCR .5 TIMER MOV A,R6 JZ TMR3 ;IF DELAY UP DEC R6 TMR3: MOV R0,#HLD30 MOV A,@R0 JZ TMR4 ;IF 30 SEC NOT UP DEC A MOV @R0,A TMR4: MOV A,R7 RETR ;THIS ROUTINE FORMS THE RING TONE. IT IS ;CALLED EVERY 32 MSEC. TONE: MOV R1,#TONOT MOV R0,#TONFLG MOV A,@R0 JNZ TONE7 ;IF SINGLE TONE SET MOV R0,#SWTDCD MOV A,@R0 ANL A,#43H JZ TONE2 ;IF ON AND NO RECORD TONE1: MOV @R1,#0 ;TURN TONE OFF RET TONE2: CALL CLCK ;DO MATRIX CHECK JNZ TONE6 ;IF MACHINE HAS LINE MOV R2,#0 MOV R0,#LNSTUS TONE3: MOV A,@R0 XRL A,#1 JZ TONE4 ;IF LINE RINGING INC R0 INC R2 MOV A,R2 XRL A,#6 JNZ TONE3 ;IF NOT ALL JMP TONE1 TONE4: MOV A,R2 ADD A,#RPHAS MOV R0,A MOV A,@R0 ;READ H LINE JB7 TONE1 ;IF RING OFF MOV R0,#TMCT0 MOV A,@R0 JB4 TONE5 ;IF WARBLE TIME MOV @R1,#10H ;SET TONE ON RET TONE5: MOV @R1,#30H ;SET WARBLE RET TONE6: MOV A,R6 JNZ TONE1 ;IF TONE DELAY ON MOV R0,#TMCT1 ;DUAL TONE BURST MOV A,@R0 ANL A,#0DH XRL A,#0DH JNZ TONE1 ;IF LULL TIME MOV R0,#TMCT0 MOV A,@R0 JB4 TONE5 ;IF WARBLE TIME MOV @R1,#10H RET TONE7: DEC A MOV @R0,A ;DECR SINGLE TONE TIME JZ TONE1 ;IF JUST UP JMP TONE5 ;DO SINGLE TONE ;THIS ROUTINE CHECKS TO SEE IF THE START ;BUTTON HAS BEEN PRESSED 3 TIMES WITHIN ;A SHORT TIME TO RESET STATS. IT IS CALLED ;FROM SWMN (MAIN). RSCK: MOV A,R6 JB0 RSCK1 ;IF S3 IS OFF CLR F1 ;CLEAR DUMMY 1'S MOV R0,#RESCNT MOV A,@R0 ;GET COUNT INC @R0 ;INCR COUNTER MOV R0,#RESTMR JNZ RSCK2 ;IF COUNTER ON MOV @R0,#50 ;SET TIMER RSCK1: RET RSCK2: MOV R2,A ;SAVE COUNT MOV A,@R0 JZ RSCK4 ;IF TIME IS UP MOV A,R2 XRL A,#2 JNZ RSCK1 ;IF COUNTER NOT UP MOV R0,#NUMINB CLR A MOV R2,#6 RSCK3: MOV @R0,A ;CLEAR ALL STATS INC R0 DJNZ R2,RSCK3 MOV R0,#TONFLG MOV @R0,#4 ;SET TONE RET RSCK4: MOV R0,#RESCNT MOV @R0,#0 ;CLEAR COUNTER RET ;THIS IS THE MAIN LINE ROUTINE FROM WHICH ALL ;NON TIME CRITICAL ROUTINES ARE CALLED. NOP MAIN1: MOV @R0,A ;CLEAR DATA INC R0 DJNZ R2,MAIN1 OUTL BUS,A ;TURN OFF DISPLAY MOV A,#3CH OUTL P2,A ;INITIALIZE P2 CALL VCRES ;DO VOICE RESET MOV A,#0C0H OUTL P1,A ;INITIALIZE P1 MOV R0,#VCRCTM MOV @R0,#0FFH ;STOP TIMER MOV R0,#NUMINB MOV @R0,#35H ;PRE-SET STATS MOV R0,#NUMANS MOV @R0,#32H MOV R0,#NUMABN MOV @R0,#6 MOV R7,#0EH ;SET ALL RECORDED MOV R0,#FRSREC MOV @R0,#2 ;SET FIRST REC CLR F1 CPL F1 ;SET DISPLAY 1'S MOV R0,#DUM32 MOV @R0,#32H ;SET DUMMY DISP STRT T EN TCNTI MAIN2: CALL DSOT ;DO DISPLAY OUTPUT CALL HLIN ;DO H LINE INPUT CALL HLMN ;DO H LINE MONITOR CALL DGRD ;DO 202P READ CALL VCCT ;DO VOICE CONTROL CALL SWMN ;DO SWITCH MONITOR CALL DSMN ;DO DISPLAY MONITOR CALL ANSW ;DO ANSWER MONITOR CALL VCMN ;DO VOICE MONITOR CALL TNDC ;DO REMOTE TONE DECODE CALL HNGP ;DO HANG-UP MOV A,T ADD A,#5 JC MAIN3 ;IF TIMER ALMOST UP CALL MXCN ;DO MATRIX CONNECT MAIN3: JMP MAIN2 ;THIS ROUTINE READS THE RAW H LINES AND ;DEBOUNCES THEM FOR RING DETECTION. IT ;INCLUDES FAST RING DETECT AND IN USE ;DETECT. ITI IS CALLED EVERY 2 MSEC FROM ;THE REAL TIME CLOCK. HLRD: MOV R5,#1 ;BIT MASK MOV R4,#0 ;LOOP CNTR MOV R1,#HPHAS HLRD0: MOV R0,#HVAL MOV A,@R0 ;GET RAW H LINES ANL A,R5 JZ HLRD5 ;IF HL=0 MOV A,@R1 JB7 HLRD3 ;IF HL WAS 1 HLRD1: MOV @R1,#80H ;SET UP UP HLRD2: CALL SETUP ;DO LOOP CHECK JB6 HLRD0 ;IF NOT DONE RET HLRD3: XRL A,#0A8H JZ HLRD4 ;UPCNT=80 MSEC MOV A,@R1 INC A JZ HLRD2 ;IF OVERFLOW MOV @R1,A XRL A,#0FFH JNZ HLRD2 ;IF NOT MAX READS UP MOV R0,#STACK MOV A,@R0 DEC A XRL A,R4 JNZ HLRD2 ;IF LINE<>TOP OF STACK CALL INUSE ;IN USE CHECK JNZ HLRD2 ;IF LINE NOT IN USE MOV R6,#28 ;SET TONE OFF TO 16 SEC JMP HLRD9 HLRD4: MOV R0,#HLDEB ;SET H VALUE MOV A,@R0 ORL A,R5 MOV @R0,A INC @R1 ;INCR PHASE JMP HLRD2 HLRD5: MOV A,@R1 JB7 HLRD7 ;IF LINE WAS UP INC A JB7 HLRD2 ;IF OVERFLOW MOV @R1,A MOV R0,#HLDEB MOV A,R5 ;CLEAR H VALUE CPL A ANL A,@R0 MOV @R0,A JMP HLRD2 HLRD7: MOV @R1,#0 ;SET UP DOWN MOV R2,A ;SAVE OLD UP TIME ADD A,#102 JNC HLRD2 ;IF < 50 MSEC MOV A,R2 ADD A,#28 JC HLRD2 ;IF > 200 MSEC HLRD8: CALL INUSE ;CHECK IF LINE IN USE JNZ HLRD2 ;IF LINE NOT IN USE MOV R0,#NUMABN CALL INCB ;INCR ABN HLRD9: MOV R0,#HANGUP MOV A,@R0 ORL A,R5 ;SET HANG-UP MOV @R0,A JMP HLRD2 ;THIS ROUTINE DETERMINES IF A LINE IS ;RINGING FROM THE DEBOUNCED H LINE VALUES. ;IT ALSO COUNTS THE RINGS. IT IS CALLED ;EVERY 128 MSEC FROM THE REAL TIME CLOCK. RGDT: MOV R5,#1 ;BIT MASK MOV R4,#0 ;LOOP CNTR MOV R1,#RPHAS RGDT1: MOV R0,#HLDEB MOV A,@R0 ANL A,R5 JZ RGDT5 ;IF H VAL=0 MOV A,@R1 JB7 RGDT3 ;IF H VAL WAS 1 MOV @R1,#80H ;SET UP UP RGDT2: CALL SETUP ;FORM LOOP JB6 RGDT1 ;IF NOT DONE RET RGDT3: INC A JZ RGDT2 ;IF OVER FLOW MOV @R1,A XRL A,#0A8H MOV R0,#ANSERD JZ RGDT8 ;IF UP=5 SEC MOV A,@R0 ANL A,R5 JZ RGDT2 ;IF LINE NOT ANSWERED MOV A,@R1 XRL A,#82H JNZ RGDT2 ;IF NOT 2 READS UP MOV R0,#STACK MOV A,@R0 DEC A XRL A,R4 JNZ RGDT2 ;IF NOT TOP OF STACK RGDT4: MOV R0,#HANGUP MOV A,@R0 ORL A,R5 ;SET HANG-UP MOV @R0,A JMP RGDT2 RGDT5: MOV A,@R1 JB7 RGDT6 ;IF H VAL WAS 1 INC A JB7 RGDT2 ;IF DOWN=MAX MOV @R1,A XRL A,#4 JNZ RGDTZ ;IF NOT .5 SEC CALL INUSE ;CHECK IF LINE IN USE JZ RGDT2 ;IF LINE IN USE MOV @R0,#1 ;SET RING CALL CLCK JNZ RGDTA ;IF LINES ON UNIT CALL RGCK RGDTA: MOV A,#RNGCTR ADD A,R4 MOV R0,A MOV A,@R0 INC @R0 ;INCR RING CNTR JNZ RGDT2 ;IF NOT FIRST RING JMP RGDT7 RGDTZ: MOV A,@R1 XRL A,#24 JNZ RGDT2 ;IF NOT 2.5 SEC MOV A,#RNGCTR CALL DATCL ;CLEAR RING CNTR MOV A,#LNSTUS ADD A,R4 MOV R0,A MOV @R0,#2 ;SET IN USE JMP RGDT2 RGDT6: MOV @R1,#0 ;SET UP DOWN JMP RGDT2 RGDT7: MOV R0,#NUMINB CALL INCB ;INCR INBOUND MOV R0,#STKPTR MOV A,@R0 INC @R0 ;INCR STACK PTR ADD A,#STACK MOV R0,A MOV A,R4 INC A MOV @R0,A ;WRITE LINE TO STACK JMP RGDT2 RGDT8: MOV A,@R0 ANL A,R5 JNZ RGDT2 ;IF LINE ANSWERED JMP RGDT4 ;THIS ROUTINE CHECKS TO SEE IF A LINE IS IN ;USE. IT IS CALLED FROM HLRD (2 MSEC). INUSE: MOV A,#LNSTUS ADD A,R4 MOV R0,A MOV A,@R0 ;READ STATUS XRL A,#2 INUS1: RET ;THIS ROUTINE OUTPUTS THE DISPLAY DATA TO ;THE 4 DIGIT DISPLAY. IT IS CALLED FROM ;MAIN. DSOT: MOV R0,#DISBLK MOV A,@R0 JNZ INUS1 ;IF DISP BLANK MOV R1,#DSPCNT MOV A,@R1 ADD A,#DSPOT MOV R0,A ;FORM DATA PNTR MOV A,@R0 ;GET DISP DATA MOV R2,A MOV A,@R1 INC A ;FORM DIGIT SELECT MOV R3,A MOV A,#8 DSOT2: RL A DJNZ R3,DSOT2 ;FORM BIT MOV R3,A ;SAVE SELECT ORL A,R2 ;OR IN DATA OUTL BUS,A ;WRITE TO DISPLAY MOV R0,#TMCT0 MOV A,@R0 ;SYNC DISP TO TIME RR A ANL A,#3 MOV @R1,A ;WRITE DIGIT SELECT MOV R0,#SWITCH MOV A,R3 SWAP A ;GET SELECT JNT1 DSOT3 ;IF SWITCH SET CPL A ANL A,@R0 ;CLEAR BIT MOV @R0,A ;WRITE RESULT RET DSOT3: ORL A,@R0 ;SET BIT MOV @R0,A DSOT4: RET ;THIS ROUTINE TAKES CARE OF THE MONITOR ;DELAY TIMERS. IF THEY ARE NOT 0, THEY ;ARE DECR TO 0. IT IS CALLED EVERY 32 MSEC. DLYS: MOV R0,#ANSDLY MOV R2,#4 DLYS1: MOV A,@R0 JZ DLYS2 ;IF TIMER=0 DEC A MOV @R0,A ;DECR TIMER DLYS2: INC R0 DJNZ R2,DLYS1 ;DO REST MOV R0,#RESTMR MOV A,@R0 JNZ DLYS3 ;IF TIMER ON MOV R0,#RESCNT MOV @R0,A ;RESET COUNT DLYS3: RET ;THIS ROUTINE READS THE DATA FROM THE 202P'S. ;IT IS CALLED FROM MAIN. DGRD: IN A,P1 MOV R1,#DISBLK CPL A JB7 DGRD2 ;IF NO DATA VALID JF0 DGRD1 ;IF DATA READ CPL F0 ;SET DATA READ MOV A,@R1 ORL A,#1 ;SET DIAPLAY BLANK MOV @R1,A MOVX A,@R0 ;SET BUS TO IN INS A,BUS ;READ DATA MOV R0,#CODSWT ANL A,#0FH MOV @R0,A ;STORE CODE SWITCH ORL P2,#40H ;SET ENA HIGH INS A,BUS ;READ 202'S MOV R0,#TONEIN ANL A,#0FH MOV @R0,A ANL P2,#0BFH ;CLEAR ENA'S DGRD1: RET DGRD2: CLR F0 ;CLEAR DATA READ MOV A,@R1 JB0 DGRD3 ;IF DIS BLANK RET DGRD3: ANL A,#0FEH ;CLEAR DIS BLANK MOV @R1,A RET ;THIS ROUTINE WRITE THE DATA OUT TO THE CROSS ;POINT MATRIX. IT IS CALLED FROM MAIN. MXCN: MOV R1,#MATPTR MOV A,@R1 RR A RR A ANL A,#7 ;MASK BYTE ADD A,#MATRIX MOV R0,A MOV A,@R0 ;READ MATRIX MOV R5,A ;SAVE MOV A,@R1 ;READ CNTR ANL A,#0FH MOV R3,A MOV R4,#4 MXCN1: ANL P2,#7FH ;CLEAR DATA MOV A,R5 RRC A MOV R5,A JNC MXCN2 ;IF DATA=0 ORL P2,#80H ;SET DATA MXCN2: MOV R0,#TONOT MOV A,@R0 ;GET TONES ORL A,R3 ;SET ADDR ORL A,#0C0H ;SET INPUTS OUTL P1,A MOV A,@R1 JB4 MXCN5 ;IF UPPER MATRIX ORL P2,#1 ANL P2,#0FEH ;PULSE LOWER MXCN3: INC @R1 ;INCR BIT CNTR INC R3 ;INCR ADDR DJNZ R4,MXCN1 ;IF NOT ALL BITS MOV A,@R1 XRL A,#24 JZ MXCN4 ;LIMIT POINTER RET MXCN4: MOV @R1,A RET MXCN5: ORL P2,#2 ;PULSE UPPER ANL P2,#0FDH JMP MXCN3 ;THIS ROUTINE READS IN THE RAW H LINE DATA ;TO HVAL. IT IS CALLED FROM MAIN. HLIN: MOV R2,#20H ;SET BIT MASK MOV R3,#0 ;CLEAR RESULT MOV R4,#6 ;SET LOOP CNTR MOV R1,#TONOT HLIN1: DEC R4 MOV A,@R1 ;GET TONE ORL A,R4 ;OR IN NEW ORL A,#0C0H ;SET INPUTS OUTL P1,A ;WRITE OUT INC R4 JNT0 HLIN2 ;IF T0=0 MOV A,R2 ;SET BIT ORL A,R3 MOV R3,A ;SAVE RESULT HLIN2: MOV A,R2 RR A MOV R2,A ;ROTATE MASK DJNZ R4,HLIN1 ;LOOP IF NOT DONE MOV R0,#HVAL MOV A,R3 MOV @R0,A ;UPDATE HVAL RET ;THIS ROUTINE IS THE HOLD MONITOR WHICH ;SEQUENCES THE LINES ON AND OFF THE ;VOICE PATH WHEN ON HOLD. IT IS CALLED FROM ;MAIN. HLMN: MOV R1,#HLDPHS MOV A,@R1 JZ HLMN3 ;IF PHASE=0 MOV R0,#HLDDLY ;PHASE=1 MOV A,@R0 JNZ HLMN1 ;IF DELAY STILL ON IN A,P1 JB6 HLMN2 ;IF END OF SPEECH CALL CLCK JB0 HLMN1 ;IF LINES STILL ACTIVE MOV R0,#VOCMD MOV @R0,#20H ;SET STOP HLMN0: MOV @R1,#0 ;RESET PHASE HLMN1: RET HLMN2: CALL XFER ;DO C2 TRANSFER MOV R0,#HLD30 MOV @R0,#60 ;SET 30 SECONDS JMP HLMN0 HLMN3: MOV R0,#HLD30 MOV A,@R0 JNZ HLMN1 ;IF TIMER NOT UP CALL CLCK CPL A JB1 HLMN1 ;IF NO LINES LEFT MOV R0,#ANSPHS MOV A,@R0 MOV R0,#TONPHS ORL A,@R0 JNZ HLMN1 ;IF VOICE ACTIVE CALL C1TR ;DO C1 TRANSFER MOV R0,#VOCMD MOV @R0,#2 ;SET PACIFIER MOV R0,#HLDDLY MOV @R0,#1 ;SET HOLD DELAY INC @R1 ;INCR PHASE RET ;THIS ROUTINE WRITES THE VALUE IN THE ACC ;TO ALL THE DISPLAY DIGITS. IT IS CALLED ;FROM DSMN (MAIN). DSWR: MOV R2,#4 MOV R0,#DSPOT DSWR1: MOV @R0,A INC R0 DJNZ R2,DSWR1 RET ;THIS IS THE TABLE FOR DE-SCRAMBLING THE ;CODE SWITCH INPUT. IT IS USED BY TNDC (MAIN). ORG 300H CODTBL: DB 0 DB 2 DB 1 DB 3 DB 8 ;4 DB 0AH DB 9 DB 0BH DB 4 ;8 DB 6 DB 5 DB 7 ;THIS TABLE IS THE DECODING FOR THE FRONT ;PANEL SWITCHES. SWTTBL: DB 01H ;OLD 3 DB 01H ;3 DB 14H ;5 DB 12H ;7 DB 44H ;9 DB 42H ;B DB 24H ;D DB 22H ;F ;THIS ROTUINE IS USED TO CLEAR DATA AT AN ;INDEXED LOCATION (R5). IT IS CALLED FROM ;REAL TIME ROUTINES. DATCL: ADD A,R4 MOV R0,A MOV @R0,#0 ;CLEAR DATA RET ;THIS ROUTINE IS THE INTERFACE TO THE VOICE ;CHIP. IT IS CALLED FROM MAIN. VCCT: MOV R1,#RECDAT MOV R2,#0 ;SET SELECT MOV A,@R1 ANL A,#3 JZ VCCT4 ;IF VOICE ON DEC A JZ VCCT7 ;IF=1 PHRASE DEC A JZ VCCT6 ;IF=2 SPEED MOV R0,#DISBLK MOV A,@R0 ORL A,#2 ;SET DISPLAY BLANK MOV @R0,A MOV A,@R1 JB6 VCCT8 ;IF STOP SET ANL A,#80H ;GET REC/PLAY VCCT2: OUTL BUS,A ;WRITE DATA ANL P2,#0FBH ;STROBE /WR NOP NOP NOP ;WAIT FOR COMMAND ORL P2,#0CH ;RESET /WR'S MOV A,@R1 ;INCR PHASE DEC A MOV @R1,A ;DECR PHASE ANL A,#3 JNZ VCCT4 ;IF NOT OVER FLOW MOV A,#0FCH ANL A,@R1 ;RESET PHASE MOV @R1,A MOV R0,#DISBLK MOV A,@R0 ANL A,#0FDH MOV @R0,A ;RESET DISP BLANK VCCT4: RET VCCT6: MOV A,#53H ;SET SPEED JMP VCCT2 VCCT7: MOV A,@R1 RR A RR A ANL A,#3 ;GET PHRASE NUM ORL A,#60H ;SET CODE JMP VCCT2 VCCT8: MOV A,@R1 ANL A,#0FDH ;SET PHASE 1 MOV @R1,A MOV A,#20H ;SET STOP JMP VCCT2 ;THIS ROUTINE DEBOUNCES THE FRONT PANEL ;SWITCHES. IT IS CALLED EVERY 32 MSEC ;FROM THE REAL TIME CLOCK. SWDB: MOV R0,#SWITCH MOV R1,#SWTLST MOV A,@R0 MOV R2,A ;SAVE PRESENT XRL A,@R1 JZ SWDB1 ;IF OLD=NEW MOV A,R2 MOV @R1,A ;UPDATE OLD RET SWDB1: MOV R0,#SWTDEB MOV A,R2 MOV @R0,A ;UPDATE VALUE RET ;THIS ROUTINE INCREMENTS A 2 BYTE BCD NUMBER ;AS SET IN R0. IT IS RE