* Disassembled AWA RT85A UHF FM radio firmware * (this version with HD6305Y2 daughter board and 64K EPROM) * * As used by the Royal District Nursing Service. * * Original disassembly work by John Kent, VK3BIZ, December 2001 * * Additional comments by Mark Harrison, VK3BYY, Jan 2002. * Notes: * * RDNS radios have an emergency button that sends SELCALL messages * every 10 seconds while power is applied. This condition can only * be reset by removing the radio from backup power for several minutes. * The Emergency button is connected to AUXPTT line. This line goes * low while button is pressed. * * W2 & W4 link is fitted in head so STATUS/SEND switch is scanned. * W1 & W3 is not fitted - would ground /SEND line going to radio directly. * * Depower output of micro doubles as /SILENT output to SELCALL option * connector and Voting option (presumably only used during RX). * * Depower function has been disabled by changing opcodes: * Z060D BSET DEPWR,PORTB * to: * Z060D BCLR DEPWR,PORTB * Also code to reset power level to default level (to 0 I guess) on * exit from TX PTT is missing (overwritten by other changes???). * * Keys: (standard functions - may not work in this version) * * SCAN: Enable Scan / Disable Scan. * * SILENT: Disable / Enable CTCSS or CTCSS squelch on RX. * Reset SELCALL (alarm??). * Enable Priority during Scan Mode. * * SEND: (Hold 1 sec) Send SELCALL, ANI with Status * or Car-to-car call. * (Momentary) Flashing 2-digit display to select Car-to-Car * address (using UP/DOWN). * (Momentary) Flashing 1-digit display to select Status * code (using UP/DOWN). * Add another channel to self prog group during Scan Mode * (with UP/DOWN), also displays current channel list. * Select Scan Group during Scan Mode (with UP/DOWN) * * Link P302/3 Low Power (Depower) switch or Mic. Hangup Switch * Hangup switch either exits Scan Mode or disables * Silent Mode when Microphone is lifted. * * The original dissasembled code may not re-assemble correctly. Some * assemblers optimise the dissassembled instructions in the form: * opcode 0,X * to the short form: * opcode ,X * To match the original binary, uses two byte opcodes for 0,X instructions, * which can be forced with the short address '<': * opcode <0,X * * * Re-Assembly: * * Use Motorola's Freeware ASx assembler (AS5.exe) * Run: * AS5 rt85a_64.a05 * or, * AS5 rt85a_64.a05 -l -cse -s * * where options are: * l = listing (to con:), use redirect * cse = cross ref listing * s = symbol listing * ( cross-ref and symbol listings may crash - too many symbols...) * ORG $000 * * Processor registers * PORTA EQU $0000 PORTB EQU $0001 PORTC EQU $0002 PORTD EQU $0003 ; read only register DDIRA EQU $0004 ; write only reg DDIRB EQU $0005 ; "" DDIRC EQU $0006 ; "" TIMREG EQU $0008 TIMCTL EQU $0009 ISCRG EQU $000A ; Misc Register (HD6305) (/INT2 masks) * * PORT A BITS (Input/Outputs) * (CTCSS & SELCALL) * DATA0 EQU 0 ;PA.0 Tone data0 (PL1/7-Data0) DATA1 EQU 1 ;PA.1 Tone data1 (PL1/6-Data1) DATA2 EQU 2 ;PA.2 Tone data2 (PL1/5-Data2) DATA3 EQU 3 ;PA.3 Tone data3 (PL1/4-Data3) DATA4 EQU 4 ;PA.4 Tone data4 (PL1/3-Data4) & No Tone NOTONE EQU 4 ;PA.4 No Tone DATA5 EQU 5 ;PA.5 Tone data5 (PL1/2-Data5) & Tone set SEC TONSET EQU 5 ;PA.5 Tone set SEC TSQENC EQU 6 ;PA.6 CTCSS /ENC (input) SCENC EQU 7 ;PA.7 SELCALL /ENC (out) * * PORT B BITS (Outputs) * DSP3 EQU 0 ;PB.0 DSP3 SK901/7 DSP2 EQU 1 ;PB.1 DSP2 SK901/6 DSP1 EQU 2 ;PB.2 DSP1 SK901/5 BUSY EQU 3 ;PB.3 BUSY LED SK901/2 (0 to turn ON LED) DEPWR EQU 4 ;PB.4 DEPOWER SK900/1 (also Voting strobe) * ; Low for low power TSQRST EQU 5 ;PB.5 CTCSS /RES PL1/11 (0=Reset,1=latch data) SCRST EQU 6 ;PB.6 SELCALL /RES PL1/10 (0=Reset,1=latch data) ALERT EQU 7 ;PB.7 ALERT PL1/7 via Q1 * * PORT C BITS (Outputs) * SYNDAT EQU 0 ;PC.0 SER DATA SK901/4 + SK902/7 DSP0 EQU 0 ;" " DSP 0 SPMUTE EQU 1 ;PC.1 SPKR MUTE SK902/10 SYNCLK EQU 2 ;PC.2 SER CLK SK902/8 DSPSTH EQU 3 ;PC.3 DSPSTH SK902/6 DSPSTL EQU 4 ;PC.4 DSPSTL SK902/5 AUDOUT EQU 5 ;PC.5 ALARM SK902/2 SYNLOD EQU 6 ;PC.6 SER STROBE SK902/1 TXON EQU 7 ;PC.7 TX ON low to TX SK901/9 * * PORT D BITS (Inputs) * ;PD.0 (not bonded) (?) OUTLOCK EQU 1 ;PD.1 OUT OF LOCK SK902/4 SQUELCH EQU 2 ;PD.2 SQUELCH SK902/3 SCDEC EQU 3 ;PD.3 SELCALL /DEC PL1/12 TSQDEC EQU 4 ;PD.4 CTCSS DEC PL1/13 * ;xxxx EQU 5 ;PD.5 (not connected) (?) SWRET EQU 6 ;PD.6 SWITCH RETURN SK901/3 AUXPTT EQU 7 ;PD.7 /AUX PTT (Emergency button) SK901/1 * ------------------------------------------ * * RAM starts here... * * Address space 000B-000F, & 0013-001F not used in HD6305 * Address space 0020-003F is external memory only * RAM is $0040-$013F in HD6305 * ORG $0040 * Personality Data * * $0040 - $004C are the configuration bytes * copied from EPROM $13F0 - $13FC at startup. * Z0040 MAXCHAN RMB 1 ; Maximum Channel number * Z0041 RMB 1 TXLIMIT EQU $0F ; TX Timeout value DSPBLNK EQU 4 ; Enable Display Blanking after 20 seconds TXIBUSY EQU 5 ; Enable Transmit Inhibit on BUSY TXIOPEN EQU 6 ; Enable Transmit Inhibit on OPEN DPWRENB EQU 7 ; Enable Depower Link on back of head * Z0042 RMB 1 SCANENB EQU 0 ; Enable Scanning SCANTSQ EQU 1 ; Enable Scan Stop with CTCSS ?? SCANDEL EQU 2 ; Enable Chan DOWN key Deletes Scan Channel SCANHUR EQU 3 ; Enable Hangup up Resets Scan ???? SCANPROG EQU 4 ; Enable Self-Programming Scan SCANHLD EQU $E0 ; Scan old time ( 0 - 7 seconds) * Z0043 RMB 1 OPENHU EQU 0 ; Enable Silent switch TSQENB EQU 1 ; Enable Tone Squelch ??? SELCENB EQU 2 ; Enable SELCALL STATENB EQU 3 ; Enable SELCALL Status call ANILEAD EQU 4 ; Enable SELCALL Leading ANI ANITRAIL EQU 5 ; Enable SELCALL Trailing ANI ANIBEEP EQU 6 ; Enable Send ANI with beep CAR2CAR EQU 7 ; Enable SELCALL Car to Car call * Z0044 RMB 1 TIMER44 EQU $0F ; ANI SELCALL lead-in time (1=short, 15,0=long) BSYDLY5 EQU 4 ; Enable Busy LED 5 second delay SILSWEN EQU 5 ; Enable Silent switch ?? SNDIBUSY EQU 6 ; Enable SEND Inhibit on BUSY SNDIOPEN EQU 7 ; Enable SEND Inhibit on OPEN * Z0045 RMB 1 VOTENB EQU 0 ; Enable Voting * ;xxxx EQU 1 ; an option with timers, SELCALL, and beeps ?? ?? SCANLED EQU 2 ; Enable SCAN LED as Power Indicator OPENLED EQU 3 ; Enable OPEN LED (disabled if 0) TONEPER EQU $F0 ; Scan Hold time (in seconds) * Z0046 RMB 1 SCTXDEC EQU 0 ; Bypass TX code initialisation of SELCALL ; xxxx EQU 1 ; another CTCSS option ?? ; xxxx EQU $FC ; unused bits... * Z0047 RMB 1 *; xxxx EQU 0 ; unused *; xxxx EQU 1 ; unused *; xxxx EQU 2 ; unused ALARMRST EQU 3 ; Enable ALERT reset enable via Depower/Hangup link *; xxxx EQU 4 ; unused *; xxxx EQU 5 ; Enable Depower link as DOWN key in user scan ??JMH *; xxxx EQU 6 ; unused *; xxxx EQU 7 ; unused * SELCALL ID - 5 digits, RX and TX digits combined into one byte. * Buffer Z0048-Z004C. * Z0048 RMB 5 RXTONES EQU $0F ; RX digit tones in the LSN TXTONES EQU $F0 ; TX digit tones in the MSN * -------------------------------------- * End of personality data * -------------------------------------- * Working memory from here on.... * All RAM from Z0040-Z0079 cleared at cold start, otherwise retained. * SELCALL & ANI buffer * 5 digit SELCALL ID buffer is used for status and car-to-car call * messages. Status & Car codes are entered using UP/DOWN & SEND keys. * * Initialised with SELCALL digits from Z0048-4C into Z004D-51 * Retained during warm start... * Z004D RMB 4 ; SELCALL digit buffer Z0051 RMB 1 ; Last digit of SELCALL * Retained during warm start... Z0052 RMB 1 ; Status tone * Retained during warm start... Z0053 RMB 1 UPDNFLG EQU 0 ; Channel Up/Down Flag (1 for UP, 0 for DOWN key) *;xxxx EQU 2 ; ?? used near 022F & in PTT IRQ OPENFLG EQU 3 ; OPEN LED status (set to request OPEN LED on) STATFLG EQU 4 ; Status call flag DISPTIM EQU 5 ; TIMER1 Timer flag *; xxx EQU 7 ; AUXPTT flag * This byte cleared on cold and warm starts... Z0054 RMB 1 *; xxxx EQU 0 ; ?? (tested in PTT IRQ) DPWRFLG EQU 1 ; Depower link status, 0=open (set in key scan loop) SENDFLG EQU 2 ; SEND Vehicle Ident flag ALERTFLG EQU 4 ; ALERT flag TIMOUT77 EQU 5 ; Time out flag for Z0077 * ; Key repeat timer?? for UP/DOWN select?? * Retained during warm start... * Z0055 RMB 1 CARFLG EQU 0 ; Car to car call in progress *; xxx EQU 1 ; another Car to car option or flag?? *; xxx EQU 2 ; ?? to do with Car to Car ?? *; xxx EQU 3 ; ?? used near Z0252 (voting on) * ; also set on CTCSS tone received ?? SILFLG EQU 4 ; Set when SILENT key pressed *; xxxx EQU 7 ; Emergency flag (set when Emergency key pressed) * This byte cleared on cold and warm starts... Z0056 RMB 1 TXFLAG EQU 0 ; Radio transmitting * Retained during warm start... CHANUM RMB 1 ; Channel number Z0058 RMB 1 ; Car to Car Ident SWSTROB RMB 1 ; Switch strobe select (DSP data) * * This byte is set to $5A on power-up * To indicate RAM is valid * * Retained during warm start... RAMCHK RMB 1 Z005B RMB 1 ; holds CHANUM for PTT IRQ Z005C RMB 1 ;Scan list pointer Z005D RMB 1 Z005E RMB 1 * * RAM from Z005F to Z0066 scrubbed occasionally and * during cold start on (invalid RAM check) * Z005F RMB 4 * $0063 - $0066 are channels deleted from the scan group Z0063 RMB 3 ;scan delete channels Z0066 RMB 1 Z0067 RMB 1 Z0068 RMB 1 ; Scan hold time converted from MSN of $0045 * * $0069 - $006C = Synthesiser data copied from channel tables. * (written at Z04DF) * Also used as scratch buffer * Z0069 RMB 1 ; Scan sequence/Power select byte Z006A RMB 1 ; CTCSS Byte - bits 1 to 6, TX Limit Timer Z006B RMB 1 ; PLL data MSBs; also MAXCHAN temp $006B Z006C RMB 1 ; PLL data LSBs * Z006D RMB 3 * * $0070 - $0073 = Code buffer * For self writing code * Z0070 RMB 1 ; LDA ,X Z0071 RMB 1 ; high byte addr Z0072 RMB 1 ; low byte addr Z0073 RMB 1 ; RTS Z0074 RMB 1 ; Bit counter for synth serial bus (exclusive use) * Timers Z0075 RMB 1 ; Slow timer pre-scaler Z0076 RMB 1 ; A SLOW Timer for Bit 5 on Z0053 Z0077 RMB 1 ; A FAST timer ( for Up/Down key repeats??) * ; decremented on every timer IRQ Z0078 RMB 1 ; A SLOW Timer for Bit 3 on PortB Z0079 RMB 1 ; some sort of counter for SCAN mode (decremented during Squelch) * * Typically the stack runs from $007F -> $0040 * Z007F EQU $007F * ======================================== * * Start of code * ORG $0100 * * EPROM overlaps HD6305 internal RAM - not used * Z0100 FCB $FF,$FF,$FF,$FF,$FF,$FF,$FF,$FF FCB $FF,$FF,$FF,$FF,$FF,$FF,$FF,$FF FCB $FF,$FF,$FF,$FF,$FF,$FF,$FF,$FF FCB $FF,$FF,$FF,$FF,$FF,$FF,$FF,$FF FCB $FF,$FF,$FF,$FF,$FF,$FF,$FF,$FF FCB $FF,$FF,$FF,$FF,$FF,$FF,$FF,$FF FCB $FF,$FF,$FF,$FF,$FF,$FF,$FF,$FF FCB $FF,$FF,$FF,$FF,$FF,$FF,$FF,$FF * ORG $0140 * Start of External ROM space in HD6305 * * Initial Configuration Data * for IO ports A-D * Z0140 FCB $C0 ;Port A Data Reg FCB $60 ;Port B Data Reg FCB $BC ;Port C Data Reg FCB $00 ;Port D Data Reg FCB $FF ;Data Direction Port A FCB $FF ;Data Direction Port B FCB $FF ;Data Direction Port C FCB $00 ;Data Direction Port D * * Test control head Switch state. * * Switch to test in 4 LSBs of X * Returns A=0 if open, $FF if closed * TESTSW STX SWSTROB TESTSW2 LDX SWSTROB BSR OUTDIGX ;set DSP bits from 4 LSBs of X CLRA BRCLR SWRET,PORTD,Z0153 ;test head switches DECA Z0153 RTS ;return with A=0 if switch open * --------------- * * Output data to remote head. * * Output 4 LSBs of X to DSP bus (No strobes) * DSP bits are scrambled across Port B & C. * Bit 0 on PortC * OUTDIGX BCLR DSP3,PORTB ;reset DSPx data bits BCLR DSP0,PORTC BCLR DSP2,PORTB BCLR DSP1,PORTB TXA AND #$0F STA Z0069 ;temp BRCLR 0,Z0069,Z0166 ; set port bits from data bits... BSET DSP0,PORTC Z0166 BRCLR 1,Z0069,Z016B BSET DSP1,PORTB Z016B BRCLR 2,Z0069,Z0170 BSET DSP2,PORTB Z0170 BRCLR 3,Z0069,Z0175 BSET DSP3,PORTB Z0175 RTS * --------------- * * Display Digits & start the TIMER1 * Z0176 JSR DSP2DIG LDA #$28 * Start Timer... (time is Acc.A) Z017B JSR Z01AF ; Start Interrupt timer BSET 5,Z0053 ; Set TIMER1 flag RTS * --------------- * * Wait for key release * * Delay a while, then retest key state for current switch * Return when key released. * WAITSW BSR Z018A ; Delay JSR TESTSW2 ; Test pressed key (existing switch code) Z0186 BRCLR SWRET,PORTD,Z0186 ; Loop till released RTS * --------------- * * Delay loop while waiting on key release * Z018A LDA #$06 STA Z0069 Z018E DECA BNE Z018E DEC Z0069 BNE Z018E RTS * --------------- * * Display Digits in X on LED display * * LSBs of X go to right hand digit, MSBs to Left digit. * DSP2DIG JSR OUTDIGX ;output 1st (LSB) digit to head BCLR DSPSTL,PORTC ;strobe data to head JSR Z01AE ;time waster?? BSET DSPSTL,PORTC ASRX ASRX ASRX ASRX JSR OUTDIGX ;output 2nd (MSB) digit to head BCLR DSPSTH,PORTC JSR Z01AE BSET DSPSTH,PORTC Z01AE RTS * --------------- * * Start Interrupt timer * Z01AF STA Z0076 Z01B1 LDA #$7D STA Z0075 Z01B5 LDX #$0D ; start hardware timer STX TIMCTL ; LDA #$70 STA TIMREG CLI RTS * --------------- * * Start timer in Z0077 * * Timer Z0077 used for various purposes including UP/DOWN key repeats, * and SELCALL timing. * * Enter at Z01BF to set timer to 11 * 256 timer IRQs * Enter at Z01C1 with period in Acc A. * Z01BF LDA #$0B Z01C1 STA Z0077 ; set timer Z0077 period BSET 5,Z0054 ; set timer running flag BRA Z01B5 * --------------- * * Software Delay Loop * SWDELAY1 LDA #$01 ;loop once * enter here to loop Acc.A times... SWDELAYA STA Z0076 ;outer loop count Z01CB LDA #$DE ; inner loop count Z01CD TST ,X ; waste time... TST ,X TST ,X DECA BNE Z01CD DEC Z0076 BNE Z01CB RTS * --------------- * * Turn off OPEN and SCAN LEDs, then * set OPEN LED from status bit in Z0053.3 * if enabled in Z0045.3 * Z01D8 LDX #$0E ; clear OPEN & SCAN LEDs JSR OUTDIGX BRSET 3,Z0053,Z01E3 ; check OPEN status BRCLR 3,Z0045,Z01E8 ; skip if OPEN LED disabled Z01E3 LDX #$0C ; Turn On OPEN LED JSR OUTDIGX Z01E8 RTS * --------------- * =========================================================== * * Reset entry point * RESET SEI CLRX ; Initialise ports Z01EB LDA Z0140,X ; copy init. data from ROM to Ports A-D STA ,X INCX CPX #$08 BNE Z01EB LDA #$5A ; Test if RAM still alive since last RESET CMP RAMCHK BEQ Z0207 ; do warm start if OK, else... * LDX #MAXCHAN ; clear RAM from Z0040-Z0079 (config, scratch, etc) Z01FC CLR ,X INCX CPX #$7A BNE Z01FC STA RAMCHK ; set RAM check byte JSR CLRRAM ; clear scratch RAM Z005F-Z0066 Z0207 CLR Z0054 ; clear flags CLR Z0056 ; clear TX flag * * Load personality configuration bytes from EPROM * at 13F0-$13FC into RAM at $0040-$004C * LDX #MAXCHAN ;copy to config data RAM LDA #Z004D STA Z0069 Z0211 LDA Z13B0,X ;from ROM Z13F0 to Z13FC STA <0,X ;into RAM Z0040 to Z004C INCX CPX #Z004D BCS Z0211 ; ..loop till done Z021B RSP ;set stack to $7F BSET 5,Z0054 ; Set key repeat timer flag CLR SWSTROB ; clear switch strobe byte BSET UPDNFLG,Z0053 ; branch if UP key was pressed JSR Z03FB ; prog synth if channel OK BSR Z01D8 ; turn off SCAN LED, update OPEN LED BRCLR 2,Z0045,Z022F ; skip if SCAN as Power LED disabled LDX #$0A ; turn on SCAN LED (as power indicator) JSR OUTDIGX Z022F NOP NOP NOP BRSET 2,Z0053,Z028A ; long jump to Z02A3 BCLR 4,Z0055 ; clear SILENT Flag Z0237 JMP Z0AB0 ; restart key scan, etc * --------------- * * Main loop: * Scan the Head Buttons * * Keys numbers (DSP data): * 0 = UP * 1 = DOWN (+aliases 3,5,7) * 2 = SILENT * 4 = STATUS/SEND * 6 = Depower link (for Low power or Hangup switch) * 8 = SCAN * A = Set SCAN LED * C = set OPEN LED * E = clear SCAN & OPEN LEDs * Z023A CLRX ; start with key #0 (UP key) CLI * Scan the Head key # in X Z023C BSR Z02A6 ; Test Button pointed to by X, * ; returns with state in A, * ; Carry is set if need to ignore this key (alias key) BCC Z029A ; if valid key pressed, go execute key's function * ; via JMP ,X ,... else no key pressed... CPX #$06 ; is this a Depower/Hangup Link scan? (and link is O/C) BNE Z0252 ; if not, back to main loop & cont. key scan * This is a Depower/Hangup link scan, but no link was detected... * - clear the PA depower flag * - clear ALERT output and flag if Z0047.3 == 1 * BRCLR 1,Z0054,Z0252 ; Skip if depower flag already clear BCLR 1,Z0054 ; link just opened, so clear flag BRCLR 3,Z0047,Z0298 ; ALERT Reset on Depower Link disabled? * ; - continue key scan if 0 BSR Z02C5 ; mess with LEDs (clear OPEN LED ??) Z024E BCLR ALERT,PORTB ; clear ALERT output BCLR 4,Z0054 ; clear ALERT flag * Scan Next key... * Most key functions come here when finished and loop back to test next key. * Falls through if last key just tested, to do other housekeeping... * Z0252 INCX ; inc to next key number to scan CPX #$0A ; scanned all keys yet? BCS Z023C ; Nope, loop back to scan next key * Do this when last key has been scanned... BRSET SQUELCH,PORTD,Z0279 ;squelch open? go check CTCSS tone (??) BRCLR 4,Z0044,Z0286 ;BUSY led 5 sec delay disabled? BRSET BUSY,PORTB,Z0286 ; jmp if BUSY LED off LDA Z0076 CMP #$27 BCC Z0282 BRSET 3,Z0055,Z0282 ;?? * TST Z0078 BNE Z0271 LDA #$0A STA Z0078 * Z0271 BRSET 5,Z0053,Z0277 ; TIMER1 JSR Z0549 Z0277 BRA Z0237 ; (goes to Z0AB0 - restart key scan, etc) * --------------- * Come here after last key scanned & if squelch is open (signal received) * Z0279 BCLR BUSY,PORTB ;Turn On BUSY LED BRCLR TSQDEC,PORTD,Z0280 ;Tone squelch detected? BSET 3,Z0055 ;set tone squelch flag ?? Z0280 BRA Z0271 ; go and handle TIMER1, etc * --------------- * Z0282 BCLR 3,Z0055 CLR Z0078 Z0286 BSET BUSY,PORTB ; turn Off BUSY LED BRA Z0271 * --------------- * Z028A BRA Z02A3 ; go to SCAN key function * --------------- * Here on key scan finds Depower link shorted... * Z028C BRSET 1,Z0054,Z0252 ; test if depower flag already set * ; if set, quit and scan next key. BSET 1,Z0054 ; else set set depower flag now BRCLR 3,Z0047,Z0298 ; Reset ALERT on Depower Lnk disabled? BSR Z02EE ; Set the OPEN LED & Flag Z0296 BRA Z024E ; jump to clear ALERT output & ALERT flag * ; and continue key scans Z0298 BRA Z0252 ; back to main loop, cont. key scan * --------------- * * Execute key functions for scanned key. * * UP and DOWN keys never come here. * Keys 3, 5 & 7 never reach here as they are aliases of key 1 and * are headed off earlier. * Warning: Never enter with X == 0 (loops forever) * Z029B EQU *+1 Z029A JMP Z029B,X ; X holds key code BRA Z02DD ; X = 2 => SILENT key BRA Z02FE ; X = 4 => SEND key BRA Z028C ; X = 6 => DEPOWER Link Z02A3 JMP Z066B ; X = 8 => SCAN key * --------------- * * Test key number, excluding invalid (aliased) key codes. * * Skips testing alias of the DOWN key (numbers 3,5,7), returning Carry set. * Valid keys, returns key state in Acc A (0 or $FF) * * Returns Carry=1 if invalid key code or key was up. * Z02A6 CPX #$03 BEQ Z02B7 ;don't test switch 3 CPX #$05 BEQ Z02B7 ;don't test switch 5 CPX #$07 BEQ Z02B7 ;don't test switch 7 JSR TESTSW ; test switch state BPL Z02B9 ; jmp if switch pressed Z02B7 SEC ; set error flag RTS Z02B9 NOP NOP NOP CPX #$01 ; Channel Down ? BEQ Z02D7 ; jmp if yes TSTX ; Channel Up ? BEQ Z02D5 ; jmp if yes CLC ; clear error flag RTS * --------------- * Z02C5 BCLR 3,Z0053 ; Clear OPEN flag LDX #$0E ; Turn Off SCAN & OPEN LEDs JSR OUTDIGX BRSET 2,Z0045,Z02D2 ; skip if SCAN LED as Power indicator BRCLR 2,Z0053,Z02D4 ; Test SCAN LED request Flag Z02D2 BCLR DSP2,PORTB ; Output $0A = Set SCAN LED Z02D4 RTS * --------------- * * CHAN UP/DOWN keys * Increment or decrement channel number and program synth to new frequency. * Z02D5 BSET UPDNFLG,Z0053 ; Set UP key flag Z02D7 JSR Z03DC ; Step Up/Down one channel and program synth SEC ; set error flag (don't execute UP or DOWN keys) CLRX ; reset key number RTS * --------------- * * Here on SILENT/HANGUP key * Z02DD BRCLR 0,Z0043,Z02E5 ; SILENT Switch Enable or open from hangup?? BRCLR 3,Z0053,Z02EA ; if OPEN LED Flag not set, set it BSR Z02C5 Z02E5 JSR WAITSW ; Wait for key release Z02E8 BRA Z0296 Z02EA BSR Z02EE ; Set the OPEN LED & Flag BRA Z02E5 * --------------- * * Turn On OPEN LED & Flag * Z02EE BSET 3,Z0053 ; Set OPEN LED Flag LDX #$0C ; Turn On OPEN LED JSR OUTDIGX RTS * * * Z02F6 BCLR 6,Z0053 LDX #$BB JSR DSP2DIG RTS * --------------- * * Here on SEND Key scanned * Z02FE JSR Z018A ; Software delay LDA #$02 JSR Z017B ; start switch debounce timer Z0306 BRCLR 5,Z0053,Z0338 ; TIMER1, SEND Function BRCLR SWRET,PORTD,Z0306 ; loop till key release Z030C BRCLR 2,Z0055,Z031F BCLR 2,Z0055 BSET 4,Z0053 ; Status call BRCLR 3,Z0043,Z030C ; jmp if SELCALL Status call disabled LDA Z0052 ; get status code ADD #$B0 * * Common status / Car to car * Z031A JSR Z0452 Z031D BRA Z02E8 * --------------- * * * Z031F BRCLR 4,Z0053,Z032F ;status call flag BCLR 4,Z0053 ; Not Status call BRCLR 7,Z0043,Z031F ; jmp if car to car disabled Z0327 BSET 0,Z0055 ; Flag car to car call. LDA Z0058 ; Car to car Ident BRA Z031A * --------------- * * * Z032D BSR Z03A7 ; Beep once Z032F BCLR 0,Z0055 ; Clear Car to car call BSET 2,Z0055 JSR Z0410 BRA Z031D * --------------- * * Here on SEND key, go send SELCALL message if enabled * Z0338 BRCLR 2,Z0043,Z032F ; skip if SELCALL disabled BRCLR 6,Z0044,Z0341 ; Send Inhibit on BUSY? BRCLR BUSY,PORTB,Z032D ; jmp if BUSY LED On Z0341 BRCLR 7,Z0044,Z0347 ; Send Inhibit on OPEN BRCLR 3,Z0053,Z032D ; Branch if OPEN Flag not set Z0347 BSET 2,Z0054 ; send vehicle ident JMP Z0AC5 ; go send SELCALL with status code * --------------- * * Stuff from here to Z0375 is dead code and is never called... * Z034C EQU * ; never called? * BRCLR 0,Z0055,Z0352 ; If not car to car call, send BRSET 1,Z0046,Z0358 ; SELCALL TX code option ?? Z0352 JSR SETSCTX ; set up radio's SELCALL Tx digits BRCLR 0,Z0055,Z0375 ; send SELCALL status if not car to car call * Send car to car SELCALL message... * changes digits 4 & 5 to car to car code in SELCALL digit buffer * This code never used... Z0358 LDX #$51 ; point to SELCALL digit buffer LDA <0,X BNE Z035F ; search for a digit == 0 DECX Z035F LDA Z0058 ; Load car ident digit COMA ; invert it AND #$0F ; extract 2nd digit of car code STA <0,X ; save it in place of '0' digit LDA Z0058 ; get car ident again COMA LSRA ; extract 1st digit of car code LSRA LSRA LSRA DECX STA <0,X ; save car code too. LDX #Z004D JSR SCRPTCHK ; check duplicates in tone digit buffer * send SELCALL message * used when SEND key pressed... Z0375 JSR Z0901 ; send SELCALL message BRCLR 1,Z0045,Z0398 ; option with timers, SELCALL, and beeps?? LDA #$04 JSR Z017B ; Start Interrupt timer Z0380 BRCLR 5,Z0053,Z039E ; TIMER1 expired? BRCLR 4,Z0054,Z0380 ; loop until ALERT BCLR 4,Z0054 ; reset ALERT flag LDA #$02 ; emit 2 beeps JSR BEEPA JSR Z02F6 LDA #$02 JSR Z017B ; start interrupt timer Z0395 BRCLR 5,Z0053,Z0395 ; wait for TIMER1 Z0398 BCLR 2,Z0054 ; Clear SEND flag BCLR 4,Z0053 ; Clear Status call flag BRA Z032F * --------------- * * TIMER1 expired while waiting for ALERT flag to set * Z039E BRCLR 0,Z0055,Z0398 ; Branch if not car to car call BCLR 2,Z0055 ; ?? BCLR 2,Z0054 ; Clear SEND Flag BRA Z0327 * --------------- * * Emit one beep * Z03A7 LDA #$01 JSR BEEPA JSR Z01B5 RTS * --------------- * * Increment/Decrement to Next channel * NXTCHAN BRSET UPDNFLG,Z0053,Z03BC ; key pressed was UP or DOWN.. TSTA BNE Z03B9 LDA Z006B INCA Z03B9 DECA BRA Z03C3 * --------------- * * This looks like it is incrementing * the channel number by one * Z03BC CMP Z006B BNE Z03C2 LDA #$FF Z03C2 INCA Z03C3 TAX AND #$0F ;Mask the units digits CMP #$0A BNE Z03D0 TXA ;Reached 10, so increment 10s digit AND #$F0 ADD #$10 TAX Z03D0 CMP #$0F ;has units overflowed ? BNE Z03DA TXA ;Yes, limit units to x9 AND #$F0 ADD #$09 TAX Z03DA TXA RTS * --------------- * * Select next Up or Down channel and Program synthesiser * with new selected channel. * * Z03DC JSR Z018A ; delay loop.. BRSET 4,Z0053,Z0419 ; Status call BRSET 0,Z0055,Z0428 ; Car to car call BRCLR 4,Z0041,Z03EB ; Display blanking after 20secs BRCLR 5,Z0053,Z0410 ; TIMER1 * Z03EB LDA #$96 ; Set up initial key delay Z03ED STA Z0077 ; set timer Z0077 BSET 5,Z0054 ; set timer running flag for Key repeat timer * Z03F1 LDA MAXCHAN ; get max. chan number STA Z006B LDA CHANUM BSR NXTCHAN ; go Up/Down 1 channel. STX CHANUM * * Test for valid channel & program the synthesiser * Z03FB JSR LDCHANST ; get channel's enable bit BMI Z03F1 ; If MSB set, it is not a valid channel, skip to next LDX CHANUM ; display channel number on head LEDs JSR DSP2DIG Z0405 BRCLR 5,Z0054,Z0464 ; test key repeat timer JSR TESTSW2 ; test last pressed key state BPL Z0405 JSR PROGSYN * Z0410 BCLR 6,Z0053 LDX CHANUM BRCLR 4,Z0041,Z0455 ; Display balnking after 20secs BRA Z0453 * --------------- * * Increment Car to Car status ID * Z0419 LDA #$09 STA Z006B LDA Z0052 ; get the car number JSR NXTCHAN ; increment using channel up/down STA Z0052 ; save it again ADD #$B0 BRA Z0452 * --------------- * Z0428 LDA #$99 ; Max Channel (or Car# ??) = 99 STA Z006B * LDA #$96 ; repeat key time?? Z042E STA Z0077 ; set timer Z0077 BSET 5,Z0054 ; set timer running flag * LDA Z0058 ; Get car identity JSR NXTCHAN ; increment with channel up/down STA Z0058 ; save it again TAX JSR DSP2DIG ; and display it * Z043D BRCLR 5,Z0054,Z044A ; Up/Down key repeat flag?? JSR TESTSW2 ; test key state BPL Z043D JSR PROGSYN BRA Z044E * --------------- * Z044A LDA #$20 BRA Z042E * --------------- * * Send car to car using RX codes * Z044E LDA Z0058 ; get car to car ident BCLR 1,Z0055 Z0452 TAX * Z0453 BSET 6,Z0053 * Z0455 JSR Z0176 ; Display digits and start TIMER1 BCLR UPDNFLG,Z0053 ; clr UP/DOWN flag JSR WAITSW JSR SETSCRX JSR Z01B1 RTS * --------------- * * Load Key repeat Timer * Z0464 LDA #$25 BRA Z03ED * --------------- ******************************************** * * Interrupt Service Routine - TIMER IRQ * * Called when timer overflows * * ******************************************** IRQTIM BCLR 7,TIMCTL ; reset timer overflow flag LDA #$7D ; reload timer STA TIMREG DEC Z0077 ; countdown timer Z0077 BNE Z047A BCLR 5,Z0054 ; clear timer flag * ; ( for Up/Down key repeats, etc??) BRCLR 2,Z0043,Z047A ; skip if SELCALL disabled JSR Z082C ; Do SELCALL stuff Z047A BRCLR 1,Z0043,Z04C4 ; RX CTCSS disabled? BRCLR TSQDEC,PORTD,Z04C7 ; CTCSS tone detected? BRSET 5,Z0044,Z04CA ; SILENT switch enabled?? Z0483 BCLR SPMUTE,PORTC ; Mute the Audio Z0485 DEC Z0075 BNE Z04BB BRCLR 4,Z0054,Z0491 ; branch if no ALERT flag?? timer on SELCALL enabled ?? BRSET ALERT,PORTB,Z04BD ; ALERT already set? BSET ALERT,PORTB ; not already set, so set ALERT now Z0491 BRCLR 0,Z0055,Z04A3 ; Skip if not car to car BRSET 1,Z0055,Z04D1 BSET 1,Z0055 ; set the flag now LDX Z0058 ; get car to car ident digits Z049B JSR DSP2DIG ; Display digits on head LEDs LDX SWSTROB ; get last head scan select JSR OUTDIGX ; select next switch to scan * * Not car to car... Z04A3 LDA #$7D STA Z0075 TST Z0078 BEQ Z04B1 DEC Z0078 BNE Z04B1 BSET BUSY,PORTB ; turn Off BUSY LED * Z04B1 TST Z0076 BEQ Z04B9 DEC Z0076 BNE Z04BB Z04B9 BCLR 5,Z0053 ; TIMER1 * Z04BB CLI RTI ; end TIMER interrupt * * * Z04BD BCLR ALERT,PORTB ; turn Off ALERT JSR Z03A7 BRA Z0491 * --------------- * * * Z04C4 BRCLR 2,Z0043,Z0483 ; Skip if SELCALL disabled Z04C7 BRSET 5,Z0044,Z04CD ; Silent Switch enabled ? Z04CA BRSET 3,Z0053,Z0483 ; Test Silent flag Z04CD BSET SPMUTE,PORTC ; Enable speaker audio BRA Z0485 * --------------- * * * Z04D1 BCLR 1,Z0055 LDX #$BB BRA Z049B * --------------- * * Loop Lock Time out - keep trying to program the synthesiser * LOCKERR LDA #$01 ; beep once JSR BEEPA PROGSYN BSR SETLOAD ; set lookup for channel in CHANUM * Shift 8 bits of the channel data into the synthesiser * CLRX Z04DF LDA #$08 ; Count 8 bits STA Z0074 JSR Z0070 ; Self modifying code at Z0070-73 * ; LDA ,X * ; SETLOAD writes long address @71+72 * ; - loads the channel byte data STA Z0069,X ; into Z0069-Z006C Z04E7 LSLA BCS Z04EE BCLR SYNDAT,PORTC ; PLL data Low BRA Z04F0 Z04EE BSET SYNDAT,PORTC ; PLL data High Z04F0 BCLR SYNCLK,PORTC ; Pulse PLL data clock Low briefly... DEC Z0074 BSET SYNCLK,PORTC BNE Z04E7 INCX CPX #$04 ; shift all 4 bytes. BNE Z04DF * * Byte No 1 of the channel data * contains the CTCSS tone in bits 1 to 6. * * Latch channel tone data to CTCSS module, * and send final clock to synth to latch new frequency for transmit. * LDA Z006A ; get byte 2 of channel data LSRA ORA #$C0 STA PORTA ; output data to CTCSS module BCLR TSQRST,PORTB ; Reset CTCSS module BSET SYNLOD,PORTC ; pulse Synth Load TST <0,X ; delay BCLR SYNLOD,PORTC BSET TSQRST,PORTB ; latch data to CTCSS module LDX #$4F ; start hardware timer STX TIMCTL LDA #$96 STA TIMREG Z0516 BRSET 7,TIMCTL,LOCKERR ; Timer overflowed BRSET OUTLOCK,PORTD,Z0516 ; Loop while PLL out of lock RTS * --------------- * * Set up self modifying code in RAM to index the Channel table. * * Sets up a long indexed address for accessing channel tables. * Enter at SETLOAD to set address to channel in CHANUM. * Enter at SETLOADA to set address to channel in Acc.A * SETLOAD LDA #$D6 ; Opcode for LDA ,X STA Z0070 LDA #$10 ; Offset to RX channel table BRCLR TXFLAG,Z0056,Z0528 LDA #$14 ; Offset to TX channel table Z0528 STA Z0071 LDA #$00 ; LSB of addr. = $00 STA Z0072 LDA #$81 ; Opcode for RTS STA Z0073 * LDA CHANUM ; get channel number * enter here with A=channel number: SETLOADA CMP #$80 ; calculate table offsets.. BCS Z053C INC Z0071 ; adjust SUB #$40 Z053C CMP #$40 BCS Z0544 INC Z0071 SUB #$40 Z0544 LSLA ; x4 for 4 bytes/chan LSLA STA Z0072 RTS * --------------- * * * Z0549 BRCLR 6,Z0053,Z0554 BRCLR 2,Z0055,Z0555 JSR Z02F6 BCLR 6,Z0053 Z0554 RTS * --------------- * Z0555 BRSET 4,Z0041,Z055A ;Display Blanking 20 secs BCLR 6,Z0053 Z055A LDX CHANUM JSR Z0176 ; Display channel and start the TIMER1 Z055F BCLR 0,Z0055 ; clear car to car call BSET 2,Z0055 BCLR 4,Z0053 RTS * --------------- * =============================================== * * EXTERNAL IRQ * - used by the PTT line * * =============================================== IRQEXT BIL Z0569 ;quit if IRQ line high RTI * Z0569 NOP NOP NOP RSP BRCLR 2,Z0053,Z057E BRSET 0,Z0054,Z057E LDA Z005B STA CHANUM ; change channel?? BRSET 0,Z0045,Z057E ; Voting enabled?? LDA #$01 BRA Z05E5 * Voting enabled, or various other flags (??) * Z057E LDA #$02 BRCLR AUXPTT,PORTD,Z059C ; jmp if Emergency button pressed BRCLR 5,Z0041,Z0589 ; TX Inhibit on BUSY BRCLR BUSY,PORTB,Z05E5 ; jmp if BUSY LED On Z0589 BRCLR 6,Z0041,Z058F ; TX Inhibit on OPEN BRCLR 3,Z0053,Z05E5 * Z058F LDX CHANUM JSR DSP2DIG BCLR ALERT,PORTB ; clear ALERT output BCLR DSP3,PORTB ; Clear DSP3, but why ? BCLR 4,Z0054 ; update ALERT status flag BRA Z059E * --------------- * AUXPTT (Emergency button) low... * send emergency SELCALL status message ?? send SELCALL every 10 secs. * Z059C BSET 7,Z0053 ; set AUXPTT flag active Z059E BSET BUSY,PORTB ; turn Off BUSY LED BSR Z05FA ; Turn TX ON BRCLR 4,Z0043,Z05BB ; Leading ANI ? JSR Z0963 ; get ANI leadin time from Z0044 BRCLR 6,Z0043,Z05B6 ; Send ANI with Beep disabled?? SUB #$32 STA Z0069 ; save ANI leadin - $32 LDA #$01 ; Beep once JSR BEEPA LDA Z0069 Z05B6 JSR SWDELAYA ; do lead-in delay (Delay loop x A) BSR Z0618 Z05BB JSR Z018A NOP * Get TX timeout value LDX #$5F ; Timer div by 128, Enable Timer output, Mask Timer IRQ LDA Z0041 ; Get TX Limit Timer AND #$0F LSLA STA Z006A BEQ Z05D0 * Do TX timeout timer while PTT down... Z05CA LDX #$4F ; Timer div by 128, Mask Timer IRQ LDA #$E5 STA Z0069 Z05D0 STX TIMCTL ; start hardware timer STA TIMREG Z05D4 BIH Z05ED ; Wait for PTT release BRCLR 7,TIMCTL,Z05D4 ; Test for timer rollover DEC Z0069 ; counter timer rollovers BNE Z05D0 * BSR Z0612 DEC Z006A BNE Z05CA * * Transmitter time out - emit 3 beeps. * LDA #$03 Z05E5 JSR BEEPA Z05E8 BSR Z0628 ; turn TX OFF JMP Z021B ; restart key scan * --------------- * * I assume this is where PTT goes Hi (PTT Released) * Z05ED BSR Z0615 JSR Z0B20 ; clear emergency flag BSET TSQENC,PORTA ; disable CTCSS output tone BRSET 7,Z0053,Z05E8 ; test AUXPTT flag and ignore ! NOP ; nobbled code?? BRA Z05E8 * --------------- * Turn TX ON, after checking flags for power level, etc. * * TX Power depends on flags in Z0041.7, Z0069 (==0?), Z0054.1 * Z05FA BSET TXFLAG,Z0056 JSR PROGSYN BCLR TSQENC,PORTA ; Enable CTCSS output tone if req'd BRSET 7,Z0041,Z060A ; Depower link on head enabled? LDA Z0069 ; based on Z00679....(per channel) BEQ Z060D ; go turn TX ON (low power) BRA Z060F ; or, go turn TX ON (high power) * Z060A test Z0054.1 and turn TX ON with high or low power (B1=0 == High) * Z060D sets TX to low power and turns TX ON. * Z060F turns TX ON (low or high power?). * Z060A BRCLR 1,Z0054,Z060F ; Test depower link status flag *** The following instruction should be BSET to work!!! *** Also DEPWR must be cleared at TX OFF (but code is missing!!!) Z060D BCLR DEPWR,PORTB ; Set Low output power Z060F BCLR TXON,PORTC ; turn ON TX RTS * --------------- * * * Z0612 BRSET 4,Z0043,Z0618 ; Leading ANI ? Z0615 BRCLR 5,Z0043,Z0627 ; Trailing ANI disabled?? Z0618 JSR Z095A ; Reset SELCALL module BRCLR 0,Z0046,Z0621 ; Bypass SELCALL TX code init.?? JSR SETSCTX ; set up radio's SELCALL Tx digits Z0621 JSR Z0917 ; Send Trailing ANI JSR Z084C Z0627 RTS * --------------- * * Turn TX OFF * Z0628 BSET TSQENC,PORTA ; disable CTCSS tone output BCLR 7,Z0053 ; clear AUXPTT flag BSET TXON,PORTC ; turn TX OFF Z062E BIL Z062E ; wait while PTT low BCLR 2,Z0053 ; clear flag ?? BCLR TXFLAG,Z0056 ; clear TX flag RTS * --------------- * * Emit a beep to loudspeaker. * Beep for 4 timer periods * and wait for 4 timer periods. * * Repeat Acc.A times * * Pulse width (ampilutude & timbre) determined by software delay. * Tone frequency determined by hardware timer. * BEEPA STA Z006A ; save beep count Z0637 LDA #$04 Z0639 BSR Z065E ; set hardware timer period * output 4 pulses at hardware timer period Z063B BCLR AUDOUT,PORTC ; toggle warning tone output LDX #$4B ; software delay Z063F DECX BNE Z063F BSET AUDOUT,PORTC ; toggle warning tone output LDX #$4B ; software delay Z0646 DECX BNE Z0646 BRCLR 7,TIMCTL,Z063B ; loop till Timer overflows DECA BNE Z0639 * silence between beeps for 4 timer periods LDA #$04 Z0651 BSR Z065E ; set hardware timer period Z0653 BRCLR 7,TIMCTL,Z0653 ; wait for timer overflow DECA BNE Z0651 ; Time up ? DEC Z006A ; more beeps to output? BNE Z0637 RTS * --------------- * * Set hardware timer period to beep tone period * Z065E LDX #$4F ; set hardware timer STX TIMCTL LDX #$AE STX TIMREG RTS * --------------- * * User prog scan ?? * Z0667 LDA CHANUM STA Z005F * * Here on SCAN key decode * Z066B JSR WAITSW ; Wait for key release BRSET 0,Z0042,Z0683 ; Branch if Scanning enabled BRCLR 0,Z0045,Z06E0 ; Branch if Voting disabled JMP Z096A * --------------- * * Get address of item in self program list into X. * Z0677 LDX #Z005F ; check Z005F LDA ,X INCA ; Is it a $FF ? BEQ Z0667 ; yep, invalid channel TXA ; X = $5F+Z005C ADD Z005C TAX BRA Z0699 * --------------- * SCAN key pressed with scan option enabled * Z0683 JSR Z09C4 ;turn on SCAN LED ? LDA #$1E ; set counter (decermented during squelch???) STA Z0079 Z068A CLR Z005C ;reset scan list pointer Z068C BRSET 4,Z0042,Z0677 ;user self programming scan? LDA Z005C ;set lookup address of channel in Z005C JSR SETLOADA CLRX JSR Z0070 ; Get Channel byte 0 (Scan list) * ; Self modifying code at Z0070-73 * ; LDA ,X * ; SETLOAD writes long address @71+72 * ; - loads the channel byte data BRA Z069A * --------------- * Scanning... * Check if current scan channel is in Deleted list (??) * If it is then skip this channel and go to next scan channel in list. * $0063 - $0066 deleted scan channels list. * Z0699 LDA ,X ; get scan channel # in self prog list. Z069A CMP #$FF ; if $FF then reached end of scan list BEQ Z068A ; go restart scan list BRSET 4,Z0042,Z06AB ;skip if user self prog enabled ; otherwise check DOWN delete list... LDX #Z0063 ;check for A in list Z0063-Z0066 Z06A3 CMP ,X BEQ Z06C7 ;channel in list? (go to next item) INCX ; test next entry in delete list CPX #Z0067 BNE Z06A3 Z06AB JSR Z09D2 ; set radio to channel in A * Enter here on BUSY hang * Z06AE JSR Z09DC ; Delay using Z0077 timer NOP NOP NOP Z06B4 BRSET SQUELCH,PORTD,Z06F3 ; When Squelch goes high, clear BUSY BSET BUSY,PORTB ; turn Off BUSY LED JSR Z075A ; Test for key press BRSET 5,Z0054,Z06B4 ; loop if set BRSET 6,Z0054,Z06D9 BRSET 5,Z0053,Z06AE ; TIMER1 BCLR 0,Z0054 Z06C7 INC Z005C ;increment scan list pointer (next chan) Z06C9 BRA Z068C * --------------- * * * Z06CB LDA #$1E ; set counter STA Z0079 LDA Z005B STA CHANUM ; change channel ?? BSET 6,Z0054 BSET SPMUTE,PORTC ; enable speaker audio BRA Z06AB * --------------- * * * Z06D9 BRSET 5,Z0053,Z06AE ; TIMER1 BCLR 6,Z0054 BRA Z06C9 * --------------- * * Here on SCAN key pressed, but no scan option or voting option enabled ?? * Z06E0 JMP Z0252 ; back to main loop, cont. key scan * --------------- Z06E3 BRA Z06C7 ;long jump * --------------- * * Here on Squelch going LOW (open I assume) * Z06E5 BSET BUSY,PORTB ; turn Off BUSY LED LDA Z0042 ; get scan hold time & user prog. enable LSRA LSRA LSRA LSRA STA Z0076 ; put scan hold time in timer BSET 5,Z0053 ; TIMER1 BRA Z06AE * --------------- * * Squelch is HI (Signal present) * Z06F3 BCLR BUSY,PORTB ; turn On BUSY LED BRSET 1,Z0042,Z0724 ; Scan Stop with CTCSS? * Re-enter here from Tone squelch detect Z06F8 BCLR SPMUTE,PORTC ; Mute speaker BSET 0,Z0054 Z06FC BRCLR SQUELCH,PORTD,Z06E5 * CLR SWSTROB ; Test for channel UP key JSR TESTSW2 BPL Z073A ; jump to 'UP' INC SWSTROB ; Test for channel DOWN key JSR TESTSW2 BMI Z0710 ; jump if NOT 'DOWN' BRSET 2,Z0042,Z0743 ; DOWN key deletes scan Channel Z0710 BRCLR 4,Z0055,Z0720 ; Hangup resets scan BRSET 6,Z0054,Z0755 BRSET 5,Z0054,Z0720 DEC Z0079 ; decrement count BEQ Z06CB JSR Z01BF ; Start Timer Z0077 Z0720 BSR Z075A BRA Z06FC * --------------- * * Stop scan on CTCSS... * Squelch HI and option bit Z0042.1 set * Test for RX CTCSS * Z0724 BRSET 3,Z0053,Z06F8 ; OPEN Flag set ? LDA #$07 STA Z006A Z072B JSR Z01BF ; Start Timer Z0077 Z072E BRSET TSQDEC,PORTD,Z06F8 BRSET 5,Z0054,Z072E DEC Z006A BNE Z072B Z0738 BRA Z06E3 ; long jump to Z06C7 * --------------- * * Here on Channel UP * Z073A JSR WAITSW Z073D BCLR 0,Z0054 BSET BUSY,PORTB ; turn Off BUSY LED BRA Z0738 ; long jump to Z06C7 * --------------- * * DOWN key deletes scan channel - * Insert current channel in scan delete list. * Z0743 LDX #Z0066-1 ;push old channels down on list Z0745 CPX #Z0063-1 BEQ Z074F LDA ,X STA 1,X DECX BRA Z0745 Z074F LDA CHANUM ;add current channel to top of list STA 1,X BRA Z073D * --------------- * * * Z0755 NOP NOP NOP BRA Z0720 * --------------- * * Test for key entry * Z075A BRCLR 3,Z0042,Z0766 ; Hangup resets scan disabled? LDX #$02 ; check SILENT key JSR TESTSW ; get key state BMI Z0766 BSET 4,Z0055 ; Set Hangup flag * Z0766 LDX #$04 ; check SEND key JSR TESTSW BPL Z0770 JMP Z07FC ; next test for depower link Z0770 BRA Z0787 ; go handle SEND key pressed... * --------------- * Z0772 LDX #$01 ; CHANNEL DOWN key JSR TESTSW BRCLR 5,Z0054,Z078E BMI Z0772 * * Channel DOWN key pressed... * LDX Z006A Z077E LDA PORTB ;copy PORTB into Z006A-Z0068 ?? STA <0,X INCX CPX #Z0067 BNE Z077E ;exit with X = 0067 * * SEND key pressed... * Z0787 JSR WAITSW ; clear SCAN & OPEN LEDs using key state routine LDX #Z005E STX Z006A Z078E INC Z006A LDX Z006A CPX #Z0067 BEQ Z07A7 LDA <0,X CMP #$FF BEQ Z07A7 TAX JSR DSP2DIG LDA #$FA ; set timer Z0077 to $FA JSR Z01C1 BRA Z0772 * Z07A7 LDX CHANUM JSR Z0176 BCLR 4,Z0053 BCLR 0,Z0055 ; Clear car to car call Z07B0 CLRX Z07B1 JSR Z02A6 ; test key pointed to by X BCS Z07BE ; not a valid key ? CPX #$04 BEQ Z07CC ; branch if SEND CPX #$08 BEQ Z07C1 ; Branch if SCAN Z07BE BRSET 5,Z0053,Z07C5 ; TIMER1 Z07C1 RSP JMP Z066B * --------------- * Z07C5 INCX CPX #$09 BNE Z07B1 BRA Z07B0 * --------------- * * * Z07CC NOP LDX #Z005F ;check Z005F Z07CF LDA <0,X CMP CHANUM BEQ Z07F6 BCS Z07ED STX Z006A * ;part of SEND key.... LDX #Z0066 ;send data out PORTB (?) Z07DB DECX LDA <0,X STA PORTB ;output bytes in Z0065-Z006A to PORTB ???? CPX Z006A BNE Z07DB * LDA CHANUM ;save CHANUM in Z006A STA <0,X JSR WAITSW BRA Z0770 ; go handle SEND key.... * --------------- * * * Z07ED INCX CPX #Z0066 BNE Z07CF ; Test Depower link & DOWN key LDA CHANUM STA <0,X Z07F6 JSR WAITSW JMP Z0770 * --------------- * * Test for Depower Link and DOWN key. * If DOWN pressed or Depower link is in (and link option 2 is enabled), * goto Z080D. * Z07FC LDX #$06 BRCLR 5,Z0047,Z0806 ;just test DOWN key if Depower link * ; option 2 isdisabled? Z0801 JSR TESTSW ;test Depower link state BPL Z080D ; jmp if pressed (or linked) Z0806 INCX ; also test DOWN key INCX CPX #$08 ; Scan key == #8? BEQ Z0801 RTS * --------------- * * Depower Link in (& option 2 enabled), and/or Scan Button is pressed * Z080D BRSET 4,Z0042,Z0812 ;user self programming scan? BSR CLRRAM ;clear scratch RAM Z005F-Z0066 Z0812 LDA Z005B STA CHANUM ; change channel?? BCLR 2,Z0053 Z0818 BCLR SPMUTE,PORTC ; Mute speaker JSR WAITSW BCLR 4,Z0055 JMP Z021B * --------------- * * Clear RAM Z005F-Z0066 (user programmable scans, etc?) * CLRRAM LDX #Z0066 ;Clear scratch RAM Z005F-Z0066 Z0824 CLR ,X DEC ,X DECX CPX #Z005F-1 BNE Z0824 RTS * --------------- * * Handle SELCALL stuff. * Enter here when Z0077 timer reaches zero inside timer ISR. * Z082C LDA Z005D BRCLR SCENC,PORTA,Z0870 ; jmp if CTCSS output is On BRSET SCDEC,PORTD,Z0865 ; jmp if CTCSS tone detected CMP #$04 BEQ Z0890 CMP #$03 BNE Z0840 TST Z0051 ; BEQ Z0890 Z0840 BSET 3,Z0054 INC Z005D LDA #$04 JSR Z08CD ; Get SELCALL tone period Z0849 JSR Z01C1 ; set timer Z0077 to tone period Z084C CLR Z005E LDA #Z004D ADD Z005D TAX LDA ,X Z0854 ORA #$F0 ; mask SELCALL control lines STA PORTA ; set SELCALL data BCLR SCRST,PORTB ; Reset SELCALL chip JSR Z0864 ; to RST, immediate return BSET SCRST,PORTB ; Latch tone data into SELCALL chip LDA #$17 ; delay briefly... Z0861 DECA BNE Z0861 Z0864 RTS * --------------- * * Here on SELCALL decode * Z0865 TSTA BEQ Z0870 LDA Z005E CMP #$05 BEQ Z0875 INC Z005E * * Here on SELCALL encode * Get the tone period and set up time Z0077 * Z0870 BSR Z08CB STA Z0077 ; set timer Z0077 RTS * --------------- * Z0875 BRSET 7,Z0054,SETSCRX BSET 7,Z0054 LDA #Z004D ADD Z005D TAX Z087F LDA #$03 Z0881 INCA CMP #$06 BEQ Z087F STA ,X INCX CPX #Z0052 BNE Z0881 Z088C BSR Z08CB BRA Z0849 * --------------- * Z0890 BCLR 3,Z0054 JMP Z0AD3 ; go clear emergency flag, etc... * --------------- * Label missing here !!!! * * This is dead code, never called... Z0895 EQU * BRSET 7,Z0054,Z089F BSET 4,Z0054 ; set ALERT flag?? * but this code is used... Z089A BRSET 2,Z0054,Z08C3 ; Branch if sending BSR Z0901 ; send SELCALL message Z089F LDA #$04 ; Emit 4 beeps JSR BEEPA BSET 3,Z0053 ; Set OPEN LED Flag LDX #$0C ; Turn On OPEN LED JSR OUTDIGX JSR Z055F JMP Z0818 * --------------- * * Program SELCALL Receive Tones * SETSCRX BRSET 2,Z0054,Z08C3 ; Branch if SENDing LDX #Z0048 ;point to radios SELCALL ID CODE Z08B6 LDA ,X ;get code digits COMA AND #$0F STA 5,X ;store digits offset by 5 into Z004D-51 INCX CPX #Z004D BNE Z08B6 ;for all 5 digits... BSR SCRPTCHK ; check duplicates in tone digit buffer * * Enter here on sending * Z08C3 BCLR 7,Z0054 CLR Z005D BCLR 3,Z0054 BRA Z088C * --------------- * * Get SELCALL Tone period multiplied by ACCA * Z08CB LDA #$01 Z08CD STA Z0068 LDA Z0045 ;extract timer value from personality byte LSRA LSRA LSRA LSRA STA Z006C CLRA Z08D8 ADD Z0068 DEC Z006C BNE Z08D8 LSRA RTS * --------------- * * Copy this radios SELCALL Tx Tones into buffer Z004D-Z0051, * and check for duplicate digits. (does not send ELCALL). * SETSCTX LDX #Z0048 ;point to radios SELCALL ID CODE Z08E2 LDA ,X ; get code digits COMA LSRA LSRA LSRA LSRA STA 5,X ; save digits offset by 5 into Z004D-51 INCX CPX #Z004D ; for all 5 digits... BNE Z08E2 BSR SCRPTCHK ; check duplicates in tone digit buffer RTS * --------------- * * Check for repeat CTCSS/SELCALL tones received in Z004D-51 buffer. * Override duplicates with $05. * SCRPTCHK LDX #Z004D Z08F4 LDA ,X ; get digit 'n' INCX CMP ,X ; same as digit 'n+1' ? BNE Z08FC LDA #$05 STA ,X ; overwrite digit with $05 Z08FC CPX #Z0051 BNE Z08F4 RTS * --------------- * * Send a SELCALL message ?? * Z0901 SEI JSR Z05FA ; turn TX ON BSR Z095A ; Reset secall module BSR Z0963 ; get ANI leadin time from Z0044 JSR SWDELAYA ; do lead-in delay (Delay Loop x A) BSR Z0917 JSR Z0628 ; turn TX OFF BSET 5,Z0054 JSR Z03FB RTS * --------------- * * * Z0917 LDX #Z004D Z0919 BSR Z0945 INCX CPX #Z0052 BNE Z0919 BRCLR 3,Z0043,Z0944 ; SELCALL Status call disabled?? BRCLR 0,Z0055,Z0929 ; branch if not car to car call BRSET 2,Z0054,Z0944 ; Exit if SENDing Z0929 DECX LDA ,X BEQ Z0936 BCLR NOTONE,PORTA ; disable SELCALL tone output LDA #$0A BSR Z08CD ; Get SELCALL tone delay JSR SWDELAYA ; Delay loop x A Z0936 LDA Z0052 COMA AND #$0F BSR Z0948 LDA #$05 BSR Z08CD ; Get S/C Tone Delay JSR SWDELAYA ; Delay Loop x A Z0944 RTS * --------------- * * Send an ANI or status call * Z0945 LDA ,X ; skip tone out if data == 0 BEQ Z0959 Z0948 ORA #$10 ; data = $10 BRCLR TSQENC,PORTA,Z094F ; jmp if CTCSS output enabled ORA #$4D ; else data = $4D Z094F STA PORTA ; data to module LDA #$05 JSR Z08CD ; Get SELCALL Tone Period JSR SWDELAYA ; Delay Loop x A Z0959 RTS * --------------- * * Reset SELCALL module. Disable tone output. * Z095A BCLR SCRST,PORTB ; Reset SELCALL module BCLR SCENC,PORTA ; Enable SELCALL tone gen. BCLR NOTONE,PORTA ; Disable tone output BSET SCRST,PORTB ; Enable SELCALL module RTS * --------------- * * Get ANI lead-in time from personality byte Z0044 * Z0963 LDA Z0044 ; get ANI leadin time from Z0044 LSLA LSLA LSLA LSLA RTS * --------------- * * Come here if SCAN key pressed but * Scan option disabled, but Voting * option is enabled ?? * Z096A BCLR 5,Z0055 BCLR 0,Z0054 BSR Z09C4 LDX #$5F ;clear RAM Z005F-Z0068 Z0972 CLR ,X INCX CPX #$69 BNE Z0972 BRA Z098C * --------------- Z097A LDA CHANUM BRA Z0982 * --------------- * * * Z097E LDA CHANUM AND #$F0 Z0982 INCA STA CHANUM JSR LDCHANST ; get channel's CTCSS/OK byte BMI Z097E ; Loop until valid channel found BRA Z0995 * --------------- * * * Z098C JSR Z055F NOP NOP NOP NOP BRA Z097E * --------------- * * * Z0995 LDA CHANUM BSR Z09D2 ; set radio to channel in A BSR Z09DC ; Delay using Z0077 Timer NOP NOP LDA CHANUM BRSET 5,Z0055,Z09AF AND #$0F ADD #$5E STA Z006B TAX TST ,X BEQ Z09AF JMP Z09FF * --------------- * * * Z09AF BRSET SQUELCH,PORTD,Z09C1 ;play TX depower or Voting ??JMH BRCLR 5,Z0054,Z09EE BSR Z09E6 ; Test for SCAN key BPL Z09BE LDA Z006B TAX BRA Z09AF * --------------- Z09BE JMP Z0812 ; Scan key pressed * --------------- Z09C1 JMP Z0A40 ; play TX depower or Voting ??JMH * --------------- * called during SCAN mode (to turn on SCAN LED ??) * Z09C4 BSET 2,Z0053 LDA CHANUM ; put CHANUM into Z005B for PTT IRQ?? STA Z005B CLR Z0076 LDX #$0A ; turn On SCAN LED JSR OUTDIGX RTS * --------------- * Set radio to channel in A and program synthesiser. * Z09D2 TAX STA CHANUM JSR DSP2DIG ;display new channel number JSR PROGSYN ;set synth to receive channel RTS * --------------- * * Start timer and wait until almost finished, and return. * Z09DC JSR Z01BF ; Start Z0077 timer Z09DF LDA Z0077 ; wait for Z0077 timer CMP #$03 BNE Z09DF RTS * --------------- * * Test SCAN key * Z09E6 LDX #$08 JSR TESTSW RTS * --------------- * * * Z09EC BCLR DSP3,PORTB Z09EE BSET BUSY,PORTB ;Turn Off BUSY LED BRSET 5,Z0055,Z09FC BRCLR 0,Z0054,Z09F9 LDX Z006B INC ,X Z09F9 JMP Z097A * --------------- * Z09FC JMP Z096A ; long jump * --------------- * Z09FF BCLR 5,Z0044 ; SILENT switch enabled?? CLR Z006A LDX #$5E Z0A05 INCX LDA ,X BEQ Z0A13 CMP Z006A BCS Z0A05 STA Z006A STX Z0069 BRA Z0A05 * --------------- * * * Z0A13 LDA Z0069 SUB #$5E STA Z006A LDA CHANUM AND #$F0 ADD Z006A STA Z005B STA CHANUM JSR Z09D2 ; Set radio to channel in A JSR Z09DC ; Delay using Z0077 timer JSR SETSCRX RSP NOP NOP BCLR BUSY,PORTB ; turn On BUSY LED Z0A31 BRCLR SQUELCH,PORTD,Z0A3B JSR Z09E6 ; Test SCAN key BMI Z0A31 BCLR 2,Z0053 Z0A3B BSET BUSY,PORTB ; turn Off BUSY LED JMP Z0818 * --------------- * * Play with TX depower or Voting ??JMH * Called when SQUELCH active * Z0A40 BRSET 5,Z0055,Z0A57 BSET 0,Z0054 LDA #$5C ; set hardware timer STA TIMCTL CLR TIMREG BSET DEPWR,PORTB ;set HIGH output power JSR SWDELAY1 ; software delay LDA TIMREG ; record time STA ,X BCLR DEPWR,PORTB ;set LOW output power BRA Z0A6F ;lomg jump to Z0F9 * --------------- * * * Z0A57 LDA #$46 JSR Z01C1 ; set timer Z0077 to $46 Z0A5C BRCLR 5,Z0054,Z0A72 BRSET SPMUTE,PORTC,Z0A5C ; jmp if speaker audio enabled BCLR BUSY,PORTB ; turn On BUSY LED Z0A64 BRCLR SQUELCH,PORTD,Z0A75 JSR Z09E6 ; Test SCAN key BMI Z0A64 JMP Z0812 * --------------- Z0A6F JMP Z09F9 ; long jump * --------------- Z0A72 JMP Z09FF ; long jump * --------------- Z0A75 JMP Z09EC ; long jump * --------------- * * Get byte #2 of channel data (RX or TX CTCSS tone data) * LDCHANST BSET 2,Z0055 ;set flag ?? JSR SETLOAD LDX #$01 JSR Z0070 ; Load CTCSS tone * ; Self modifying code at Z0070-73 * ; LDA ,X * ; SETLOAD writes long address @71+72 * ; - loads the channel byte data RTS * --------------- * * 46 bytes from here (Z0A82) to Z0AAF is filled with $FF's... * * --------------- * * Called at startup and after main loop restart. * Check for existing emergency flag or new emergency key press. * Either condition, do emergency stuff, else return to scan keys. * * ORG $0AB0 Z0AB0 BRSET 7,Z0055,Z0ABA ; Emergency flag already set? BRCLR AUXPTT,PORTD,Z0AC0 ; Emergency switch pressed now? Z0AB6 RSP ; reset stack pointer JMP Z023A ; go back, start scanning keys at #0 * Z0ABA BRSET 5,Z0053,Z0AB6 ; Check TIMER1 and * ; return to key scan JMP Z0B00 ; else do emergency stuff Z0AC0 BSET 7,Z0055 ; set emergency flag JMP Z0B00 ; and do emergency stuff * --------------- * * Here on pressing the SEND key * * Go send a SELCALL message with current Status digit as last digit * Z0AC5 LDA Z0052 ; Status digit for SELCALL send COMA AND #$0F STA Z0051 ; save as last SELCALL digit JSR SCRPTCHK ; check duplicates in tone digit buffer RSP ; reset stack JMP Z0375 * --------------- * * * Z0AD3 BCLR 7,Z0055 ; clear emergency flag LDA #$0D JSR SWDELAYA ; Delay Loop x A LDA #$05 ; set CTCSS tone JSR Z0854 ; set up CTCSS chip LDA #$05 JSR SWDELAYA ; Delay Loop x A BRCLR SCDEC,PORTD,Z0AFE ; CTCSS tone decode? BRSET 7,Z0054,Z0AFA BSET 4,Z0054 ; set ALERT flag?? * LDA Z0052 COMA AND #$0F STA Z0051 JSR SCRPTCHK ; check duplicates in tone digit buffer RSP JMP Z089A * --------------- * Z0AFA RSP JMP Z089F ;long jump * --------------- * * * Z0AFE BSET 7,Z0055 ; set emergency flag * ;come here to send emergency stuff Z0B00 LDA Z0052 STA Z006D COMA AND #$0F STA Z0051 LDA #$0A STA Z0052 JSR SCRPTCHK ; check duplicates in tone digit buffer JSR Z0901 ; send SELCALL message LDA Z006D STA Z0052 LDA #$14 JSR Z017B ; Start interrupt timer RSP JMP Z023A * --------------- * * Clear the emergency flag Z0055.7 and return * Z0B20 BRCLR 7,Z0055,Z0B25 ; return if no emergency flag BCLR 7,Z0055 ; else clear the emergency flag Z0B25 RTS * ================================================ * * Receive Channel Table * This radio only has 6 channels * Channel 0 has all $FF's and is not displayed * table at $1000 is for RX and * table at $1400 is for TX * * First Byte is used for scanning (and low power??) * Second Byte Bit 7 is 0 for valid channel * Second Byte Bits 6..1 are for RX Tone squelch * Second Byte Bit 0 is MSBit of synthesiser data * Third Byte Synth data * Fourth Byte Synth Data LSBits * ORG $1000 *; Note: 70cm frequencies substituted here... FCB $FF,$FF,$FF,$FF FCB $FF,$01,$02,$80 ;TX ch 1 435MHz FCB $FF,$00,$FF,$30 ;TX ch 2 430MHz FCB $04,$01,$05,$90 ;TX ch 3 440MHz FCB $05,$01,$02,$80 ;TX ch 4 435MHz FCB $06,$00,$FF,$30 ;TX ch 5 430MHz FCB $FF,$01,$05,$90 ;TX ch 6 440MHz *; original RDNS channels: *;; FCB $FF,$FF,$FF,$FF *;; FCB $FF,$40,$F4,$9C ;RX ch 1 *;; FCB $FF,$00,$F4,$9E ;RX ch 2 *;; FCB $FF,$40,$F4,$A0 ; *;; FCB $FF,$40,$F4,$B4 *;; FCB $FF,$00,$F5,$00 *;; FCB $FF,$40,$F5,$04 ;RX ch 6 * ORG $13E8 ; unknown data?? FCB $00,$00,$00,$72 FCB $FF,$56,$FF,$03 ORG $13F0 Z13B0 EQU *-MAXCHAN * Initialisation data for personaity data in RAM. * for memory locations $40 -> $4D Z13F0 FCB $06 ; $40: 6 channels total. FCB $84 ; $41: Tx timeout, Depower from head enabled FCB $00 ; $42: No scanning FCB $00 ; $43: FCB $07 ; $44: FCB $00 ; $45: FCB $00 ; $46: FCB $00 ; $47: FCB $11 ; $48: SELCALL ID TX/RX = 15070 FCB $55 ; $49: FCB $00 ; $4A: FCB $77 ; $4B: FCB $00 ; $4C: FCB $00 ; $4D: FCB $00 ; not copied... FCB $00 ; not copied... *;; Original RDNS personality data: *;;Z13F0 FCB $06 ; 6 channels total. *;; FCB $04 ; Tx timeout *;; FCB $00 ; No scanning *;; FCB $0D ; Silent Switch, SELCALL enable, Leading ANI *;; FCB $07 ; ANI timer ? *;; FCB $22 ; Scan hold time? + ? *;; FCB $00 ; *;; FCB $00 ; *;; FCB $11 ; SELCALL ID TX/RX = 15070 *;; FCB $55 ; *;; FCB $00 ; *;; FCB $77 ; *;; FCB $00 ; *;; FCB $00 ; *;; FCB $00 ; *;; FCB $00 ; * * Transmit Channel Table * * First Byte is used for scanning ???? * Second Byte Bit 7 is 0 for valid channel * Second Byte Bits 6..1 are for TX Tone squelch Encode * Second Byte Bit 0 is MSBit of synthesiser data * Third Byte Synth data * Fourth Byte Synth Data * ORG $1400 *; Note: 70cm frequencies substituted here... FCB $FF,$FF,$FF,$FF ; FCB $FF,$01,$03,$B0 ;TX ch 1 435MHz FCB $FF,$01,$00,$A0 ;TX ch 2 430MHz FCB $FF,$01,$07,$00 ;TX ch 3 440MHz FCB $00,$01,$03,$B0 ;TX ch 1 435MHz FCB $00,$01,$00,$A0 ;TX ch 2 430MHz FCB $00,$01,$07,$00 ;TX ch 3 440MHz *; original RDNS channels: *;; FCB $FF,$FF,$FF,$FF ; *;; FCB $FF,$6C,$F0,$18 ;TX ch 1 *;; FCB $FF,$2C,$F0,$1A ;TX ch 2 *;; FCB $FF,$2C,$F0,$1C ; *;; FCB $FF,$6C,$F0,$30 *;; FCB $FF,$6C,$F0,$3C *;; FCB $FF,$2C,$F0,$80 ;TX ch 6 * =============================== * * Interrupt Vectors * ORG $1FF6 FDB $0000 ;Timer Interrupt for Wait State Only FDB IRQTIM ;Timer Interrupt FDB IRQEXT ;External Interrupt FDB $FFFF ;Software Interrupt FDB RESET ;Reset Interrupt END