/* Because all defines did not work */ /* some lines were edited - no functions changed */ /* by oh3nwq 25.8.98 (having a flue & nothing else to do) */ /* 990405 v. 3.4 corrected the compilation on WITHSERSEND - OH3NWQ */ /* 991010 v. 3.5 added with serial send to the image also */ #ifndef STEP_kHz #define STEP_kHz 25 #endif /* fix mainloop, ccirint, btnproc */ #define VERSION_MAJOR 3 #define VERSION_MINOR 0x5 #ifdef EEPROM #define BANNER " EE 3n5 " #define VERSION "@(#)MC25PTL/TVL 3.5 VT 991010 EEPROM" #else #define BANNER " 3n5 " #define VERSION "@(#)MC25PTL/TVL 3.5 VT 991010 PROM" #endif #define EDITED "OH3NWQ19990405" /* 12345678901234 */ #define EEPROMSTART (16 * 1024) #define EEPROMEND (24 * 1024) ASSERT(LO(EEPROMSTART) == 0) ASSERT(LO(EEPROMEND) == 0) /* * XXX fill this space * * With apologies, * OH5NXO, Juha Nurmela * * Unconventional stack usage (for 1802), * where Rstk is kept pointing to the valid byte at the top of stack. */ #define BYTE :.rs 1 #define WORD :.rs 2 #define BUF(x) :.rs x #define shr4 shr; shr; shr; shr #define shl4 shl; shl; shl; shl #define LDREG(r,a) ldi LO(a); plo r; ldi HI(a); phi r #define ADJUST(r,a) ldi LO(a); plo r #define PUSH dec Rstk; str Rstk #define POP lda Rstk #define ALIGN_PAGE .fill (0x100 - (. % 0x100)) & 0xFF, 0xFF #define Rdma 0 #define Rint 1 #define Rstk 2 #define Rcal 3 #define Rret 4 #define Rpgm 5 Rflags = 6 # misc flags Rtmp = 7 # general scratch Rtbl = 8 # rom tables Reeprom = 9 # eeprom variables Rram = 0xA # 1st ram page, variables. Rptr = 0xB # another 1st ram page Rvar = 0xC # third Rbeeps = 0xD # lo for audible and hi for TX beeps Rscan = 0xE # lo for counter, hi for scan mode Rdpyproc= 0xF # display bitbang /* * dma is not used, nor is SCRT. */ Rkeyproc = Rdma # keypad bitbang Rin4 = Rcal # lo Rupd = Rcal # hi Rtmp2 = Rret # #define get_in4 ghi Rin4 #define put_in4 phi Rin4 #define get_upd glo Rupd #define put_upd plo Rupd FLAG_HIGH_TIMERSQ = 0x40 FLAG_HIGH_MUTE = 0x20 FLAG_HIGH_MUTE_ACT = 0x10 FLAG_HIGH_CODESQ = 0x08 FLAG_HIGH_RPTR_DIR = 0x04 FLAG_HIGH_RPTR_REV = 0x02 FLAG_HIGH_RPTR = 0x01 FLAG_HIGH_RPTR_ALL = 0x07 FLAG_LOW_SCANX = 0xC0 FLAG_LOW_LISTEN = 0x80 FLAG_LOW_SQWAIT = 0x40 FLAG_LOW_SCANGO = 0x20 FLAG_LOW_CBROWSE = 0x10 FLAG_LOW_SETUP = 0x08 FLAG_LOW_PEPA_TXT = 0x04 FLAG_LOW_EXAL = 0x02 FLAG_LOW_SYNTH_P0 = 0x01 /* * output 1 * * modified at interrupt time. */ O1_SDO = 0x01 # idle low, dpy O1_KEYCLK = 0x02 # idle high, keypad. O1_DPYCLK = 0x04 # idle low, dpy O1_DPY_ON = 0x08 # normally set, /RST O1_TXLEDxxx = 0x10 # led added to out1/4, no more O1_SYNTH_P0 = 0x20 # optionally wired to synth P0, the lsb. O1_EXTERN_ALARM = 0x40 INIT_1 = 0x0A # idle all, dpy on # TVL 0x0A /* * output 2 */ INIT_2 = 0x80 # synth rewritten from eeprom on init. /* * output 3 * * modifications from mainline thru volabits. */ O3_VOLUME = 0x0F O3_TXON = 0x10 O3_EARPHONE_ON = 0x20 O3_SQUELCH_ENB = 0x40 O3_DO_TONE = 0x80 INIT_3 = 0x61 # low volume; squelch mute; TX off, tone off. # TVL 0x40 O3_VOLABITS = 0x6F # mainline changes /* * input 4 */ I4_HOOK = 0x01 # active low I4_SQUELCH = 0x02 I4_LOCK = 0x04 # active low I4_PROGRAM = 0x08 # active low I4_OFFICE = 0x10 # active low I4_DETECT_1800 = 0x20 # active low I4_DETECT_EV = 0x40 I4_DETECT_ARP = 0x80 # Idle state (off-hook) 0xFC /* * output 5 * * Only at interrupt. */ O5_ACK_CCIR_EV = 0x02 O5_ACK_CCIR_ARP = 0x04 O5_MIC_ON = 0x08 O5_CCIR_OFF_MASK= 0xF0 # when all set, no output. INIT_5 = 0xF0 # no CCIR, no acks, mic off-line # TVL 0xF0 O5_CCIR_BEEP_MASK= 0x8F # 1747 Hz for repeater, drop bits 0x70 /* * input 6 * This is not cached in ram, inp 6 used when ccir detected. */ I6_CCIR_EV = 0x0F I6_CCIR_ARP = 0xF0 # Idle state ??? /* * output 7 * * bits changed only by mainline. */ O7_TONE_3112 = 0x01 O7_SIMPLEX_1 = 0x02 # active-low O7_SIMPLEX_2 = 0x04 # active-low O7_SIMPLEX_3 = 0x08 # active-low O7_TX_HI_POWER = 0x10 O7_SIMPLEX_RX = 0x40 O7_TONE_2000 = 0x80 INIT_7 = 0x0E # no tones, simplex off, low-power. # TVL 0x0E O7_SIMPLEXES = 0x0E /* * /EF1 PTT * /EF2 unassigned * /EF3 keypad SDI, idle low, but triple inverted when reaches /EF3 * /EF4 LOCAL */ IDLETICKS = 100 # times 32 ms, about 3 seconds. BLIPTICKS = 10 # keyblip millisecs. BLEEPTICKS = 150 BEEPTICKS = 100 # time of repeater beep in 1 ms ticks BEEP0TICK = 255 BEEP0TICK_SMALL = 1 SYNTH_LOCK_TICKS = 50 # ms to wait until tx after synth change .data /* * There is 0x100 or 256 nibbles of eeprom available. * Each memory consumes two nibbles per divisor, * and additional bytes for repeater and no-scan information. * 40 memories (0 unnamed) needs 80 halfbytes plus 2*40 bits, * 80 + 10 halfbytes, totaling 90 halfbytes. */ .org 0xC000 eeprom: ee_synth: .rs 2 ee_volume: .rs 1 ee_misc: .rs 1 EE_MISC_P0 = 0x8 EE_MISC_MUTEMASK= 0x6 EE_MISC_TIMERSQ = 0x6 EE_MISC_CODESQ = 0x4 EE_MISC_MUTE = 0x2 EE_MISC_RPTR = 0x1 ee_simplexes: .rs 1 # state of simplex controls and tx power EE_TXHI = 0x8 # the layout of the latch is used in advantage ee_rptr_low: .rs 2 ee_rptr_high: .rs 2 ee_scan_low: .rs 2 ee_scan_high: .rs 2 ee_step_ticks: .rs 2 # could use 1/100 sec here, free 4bits eeprom ee_listen_time: .rs 2 ee_sqwait_time: .rs 2 # 0..15 units of 1/4 would suffice ee_silence_time: .rs 1 ee_scan_chstep: .rs 1 ee_alert_time: .rs 2 ee_blipvolume: .rs 1 ee_alertvolume: .rs 1 ee_pri_1: .rs 2 ee_pri_2: .rs 2 ee_pri_3: .rs 2 ee_pri_4: .rs 2 # XXX ee_reject_1: .rs 2 ee_reject_2: .rs 2 ee_reject_3: .rs 2 ee_reject_4: .rs 2 ee_reject_5: .rs 2 ee_reject_6: .rs 2 ee_scan_A: .rs 1 ee_scan_B: .rs 1 ee_act_U: .rs 2 MEMORY_NOT = 0x80 MEMORY_NOSCAN = 0x40 MEMORY_MASK = 0x3F MEMORY_CNT = 40 memory_divisors: .rs 80 # 40 divisors, 2 bytes per memory, 80 bytes memory_rptrbits: .rs 10 # 40 repeater bits, 4 per byte memory_noscanbits:.rs 10 # 40 no-scan bits, 4 per byte EECCIRLEN = 7 DOBELL = 1 # act bits for ccirs DOLISTEN = 2 DOFIXED = 4 DOEXAL = 8 ee_ccir_e1: .rs EECCIRLEN ; .rs 1 # 1 ee_ccir_e2: .rs EECCIRLEN ; .rs 1 # 2 ee_ccir_e3: .rs EECCIRLEN ; .rs 1 # 3 ee_ccir_a1: .rs EECCIRLEN ; .rs 1 # 4 ee_ccir_a2: .rs EECCIRLEN ; .rs 1 # 5 ee_ccir_a3: .rs EECCIRLEN ; .rs 1 # 6 ee_ccir_pepa: .rs EECCIRLEN ; .rs 1 # 7 # 8 special and can be sent "8" ee_ccir_csq: .rs EECCIRLEN # 9 ee_scanmode: .rs 1 EE_MISC2_SQ = 0x8 # scanmode 0..7, this last ee_ptlmode: .rs 1 # 3 unused bits ee_sec1800: .rs 1 BASE_FREQ: .rs 8 # 14150045, base and default for 10/1 MHz ee_trx_diff: .rs 2 ee_trlo: .rs 2 ee_trhi: .rs 2 ee_rptr_diff: .rs 2 ee_scan_4_1: .rs 2 ee_scan_4_2: .rs 2 ee_scan_4_3: .rs 2 ee_scan_4_4: .rs 2 ee_scan_4_5: .rs 2 ee_scan_4_6: .rs 2 ee_scan_4_7: .rs 2 ee_scan_4_8: .rs 2 ee_ccir_tx_0: .rs EECCIRLEN ee_act_H: .rs 2 eeprom_used = . - eeprom ASSERT(eeprom_used == 256) .org eeprom + 0x100 # end of eeprom end_eeprom: .org 0x8000 ram: ram_p0: keyqueue BUF(32) # page-aligned, length power of two !!! keyinp BYTE keyoutp BYTE # pointers, also indexes :) trx_diff BYTE # rptr_diff BYTE # trlo BYTE trhi BYTE ptlmode BYTE # 0x1: simplex-controls not mutually exclusive sec1800 BYTE # minimum length of 1800 tone "squelch" length1800 BYTE # length counter for 1800 tone setuprec BYTE # current setup index ptr. setuptype BYTE setupxaddr BYTE setupeaddr BYTE /* * "cached" values at io-ports. * updated at interrupt. */ cksum BYTE junk BYTE prev_4 BYTE out_ports: /* contiguous ! */ output_1 BYTE output_2 BYTE output_3 BYTE output_5 BYTE output_7 BYTE btnpc BYTE btnticker BYTE btntime BYTE btnmask BYTE # which button pressed 1st keyticker BYTE keytime BYTE keybits BYTE # currently under reception. VIP_idx BYTE VIP_list BUF(5) # interesting frequencies VIP_listend: synth BYTE synthwas BYTE synthlock BYTE # timer for xmit after synth change. key BYTE # code being handled by mainline digval BYTE digidx BYTE digbuf BUF(16) # last digits entered digbufend: ccirtxbuf BUF(18) # F series FF ccirtxptr BYTE ccircwbuf BUF(2) # 8, FF scan_chstep BYTE rptr_low BYTE rptr_high BYTE scan_low BYTE scan_high BYTE scan_idx BYTE scan_tmp BYTE scan_A BYTE # alg. to start from short 'A' scan_B BYTE # alg. to start from long 'A' act_U BYTE act_H BYTE step_ticks BYTE steptimer BYTE # 1 ms between scanning steps scantimer BYTE # 1/4 s between listen/sqwait states listen_time BYTE sqwait_time BYTE godeaf BYTE alerttimer BYTE silencetimer BYTE silence_time BYTE alert_time BYTE NOTMEM = 0xFF curmem BYTE # NOTMEM if not on memory volume BYTE volabits BYTE blipvolume BYTE alertvolume BYTE idletimer BYTE rejectidx BYTE rejects BUF(4) # volatile rejects reject_1 BYTE # non-volatile rejects reject_2 BYTE reject_3 BYTE reject_4 BYTE reject_5 BYTE reject_6 BYTE end_rejects: pri_1 BYTE pri_2 BYTE pri_3 BYTE pri_4 BYTE CCIRMAX = 16 ev_prev BYTE ev_ccirlen BYTE ev_ccirbuf BUF(CCIRMAX) arp_prev BYTE arp_ccirlen BYTE arp_ccirbuf BUF(CCIRMAX) ccirhist_wp BYTE ccirhist_rp BYTE CCIR_R = 0xE # REPEAT code. tmpfreq BUF(6) CUSTOM_SCAN_LIST: scan_4_1 BYTE scan_4_2 BYTE scan_4_3 BYTE scan_4_4 BYTE scan_4_5 BYTE scan_4_6 BYTE scan_4_7 BYTE scan_4_8 BYTE dpyptr BYTE # pointer withing dpy array dpybuf BYTE # currently transmitting. dpybits BYTE # so many bits left in current byte. /* * 14 digits: * EDCBA987654321 * 9L 10 r145500 * * 0..9 audio volume setting * Hi/Lo power * memory channel * repeater * frequency */ dpyleds: # led0 BYTE # led1 BYTE # any these must not touch page boundaries. dpychars: # dpyvolume BYTE # '0'..'9' value of speaker audio dpytxpower BYTE # 'H'/'L' high/low TX power dpyblank0 BYTE # dpymemory BUF(2) # dpymisc BYTE # dpyreverse: dpystrings: dpydigbuf BYTE dpyrepeater BYTE # 'r' for repeater or blank dpyfreq BUF(6) # "145500" dpybufend: pttdown BYTE serc BYTE sermask BYTE timersquelch BYTE ASSERT(. < ram + 0x100) .org ram + 0x100; ram_p1: .org ram + 0x200; ram_p2: stack: /* XXX end of p3 */ scanner_page: .org ram + 0x300; ram_p3: ccir_history: .org ram + 0x400; ram_p4: .text /* * From reset, P/X both 0 */ ASSERT(Rint != 0) ASSERT(Rpgm != 0) ASSERT(Rtmp != 0) #ifdef EEPROM .org EEPROMSTART start: .asciz "moppe" # ident .word TheEnd # end address #else /* prom code */ .org 0 start: .byte 0x71, 0x00 # disable interrupts before they get a change. out 1 .byte INIT_1 out 2 .byte INIT_2 out 3 .byte INIT_3 out 5 .byte INIT_5 out 7 .byte INIT_7 # sane defaults for outputs. seq # TXD idling lbr promstart # from start to here exactly 16 bytes ! #endif /* not eeprom code */ .org start + 16 # (in eeprom) room for cksums and others start16: /* * Now either ROM or EEPROM executing with R0 */ LDREG(Rint, 1f) sep Rint haltit: seq seq # make it 50% duty req br haltit # until watchdog. 1: /* * Checksum ourselves and halt if not 0 */ ldi 0 plo Rtbl # cksum plo 0 phi 0 # for watchdog, ROM ok to write LDREG(Rtmp, TheEnd) # just one past last byte 1: dec Rtmp sex 0 inp 4 sex Rtmp glo Rtbl add plo Rtbl glo Rtmp smi LO(start) bnz 1b ghi Rtmp smi HI(start) bnz 1b glo Rtbl bnz haltit /* * Code looks ok. Setup pointers and flags */ ldi 0 plo Rram plo Rflags # zero int-flags phi Rflags # zero mainline-flags phi Rbeeps # not transmitting tones plo Rscan # starting value for step-counter phi Rscan # not scanning put_upd # nonzero is repaint cmd. ldi BLIPTICKS plo Rbeeps # beep after 1st interrupt ldi HI(tables) phi Rtbl ldi HI(eeprom) phi Reeprom ldi 0xFF # plo Rstk # ldi HI(ram_p1) phi Rstk # page 1 for stack ldi HI(ram_p0) phi Rvar # page 0 for variables phi Rptr ldi HI(ram_p4) phi Rram # check/clear from here, lo already 0 sex Rram # Rram generally kept X /* * Zero ram, 1024 bytes * check good ram, and again halt if not ok. * Tickle port 4 to keep watchdog happy. */ 1: dec Rram inp 4 # reset watchdog glo Rstk str Rram # check 0xFF sm bnz haltit ldi 0xAA # check 0xAA str Rram sm bnz haltit ldi 0x55 # check 0x55 str Rram sm bnz haltit str Rram # check 0 and leave it there sm bnz haltit glo Rram bnz 1b # until exactly at 1st ram page. leave Rram there. ghi Rram smi HI(ram) bnz 1b /* * Some variables need nonzero initial values * Prep outputs/inputs at ram-images and latches again. * Contiguous layout of the output_x variables ! */ LDREG(Rtmp, raminit) 1: lda Rtmp # offset bz 1f plo Rram inp 4 # reset watchdog lda Rtmp # value str Rram br 1b 1: /* * Empty key/event queue. */ ldi SIZE(keyqueue) plo Rram 1: dec Rram glo Rstk # still FF str Rram glo Rram bnz 1b ADJUST(Rram, out_ports) out 1 out 2 out 3 out 5 out 7 /* * Display initialization. * Reset for 1 ms, then send banner. * Watchdog not patted during 1 ms. */ ldi 35 plo Rtmp sex Rint out 1 .byte INIT_1 & ~O1_DPY_ON 1: dec Rtmp glo Rtmp bnz 1b # 35 * 8 == 280 == 1 ms out 1 .byte INIT_1 sex Rram /* * Setup and send initial seq */ ADJUST(Rvar, dpychars) ADJUST(Rram, output_1) LDREG(Rtmp, dpyinit) 3: lda Rtmp # next byte bz 9f plo Rptr # shift from here ldi 8 plo Rtbl # 8 bits glo Rtmp smi LO(banner+1) # still doing temporary bytes ? bnf 1f glo Rptr smi 'n' bz 1f # A '.' and cannot go into our fixed length buffer glo Rptr str Rvar inc Rvar 1: 2: glo Rptr shl plo Rptr 4: ldn Rram ani ~O1_SDO lsnf; ori O1_SDO xri O1_DPYCLK | O1_KEYCLK str Rram out 1 dec Rram ldi 50 plo Rtmp2 1: sex Rstk; inp 4; sex Rram; dec Rtmp2; glo Rtmp2; bnz 1b ldn Rram ani O1_DPYCLK bnz 4b # go drop it dec Rtbl glo Rtbl bnz 2b br 3b 9: LDREG(Rkeyproc, keyproc) LDREG(Rdpyproc, dpyproc) LDREG(Rpgm, over_pure_stuff) sep Rpgm ALIGN_PAGE tables: #if STEP_kHz == 25 /* * divisor -> frequency readout * * ls_chan[] gives 100 kc and 10 kc of divisor & 0x0F * ms_chan[] gives 10 and 1 Mc and 100 kc of divisor >> 4 * last digit (kc) is depending on divisor & 3 * base frequency is removed from these. */ kc_P0: .byte 0x00, 0x12 # 10 and 1 kc add for halfstep (P0) kc_chan: .byte 0, 5, 0, 5 ls_chan: .byte 0,0, 0,2, 0,5, 0,7 .byte 1,0, 1,2, 1,5, 1,7 .byte 2,0, 2,2, 2,5, 2,7 .byte 3,0, 3,2, 3,5, 3,7 ms_chan: .byte 0,0,0, 0,4,0, 0,8,0, 1,2,0 .byte 1,6,0, 2,0,0, 2,4,0, 2,8,0 .byte 3,2,0, 3,6,0, 4,0,0, 4,4,0 .byte 4,8,0, 5,2,0, 5,6,0, 6,0,0 /* * frequency input -> divisor * * each table is used to lookup a corresponding value * and resulting divisor is the sum. * again, base frequency is not included in here. */ # 0 1 2 3 4 5 6 7 8 9 kc_1000: .byte 0, 40, 80,120,160,200,240,255,255,255 kc_100: .byte 0, 4, 8, 12, 16, 20, 24, 28, 32, 36 kc_10: .byte 0, 1, 2, 3, 4, 4, 5, 6, 7, 8 # (n << 1) | lsb #endif #if STEP_kHz == 10 #ifdef CB kc_chan: .byte 5, 5, 5, 5 # 1 kc #else kc_chan: .byte 0, 0, 0, 0 # 1 kc #endif kc_P0: .byte 0x00, 0x05 # 10 and 1 kc add for halfstep (P0) ls_chan: .byte 0,0, 0,1, 0,2, 0,3 # 100 and 10 kc .byte 0,4, 0,5, 0,6, 0,7 .byte 0,8, 0,9, 1,0, 1,1 .byte 1,2, 1,3, 1,4, 1,5 ms_chan: .byte 0,0,0, 0,1,6, 0,3,2, 0,4,8 # 10 and 1 Mc and 100 kc .byte 0,6,4, 0,8,0, 0,9,6, 1,1,2 .byte 1,2,8, 1,4,4, 1,6,0, 1,7,6 .byte 1,9,2, 2,0,8, 2,2,4, 2,4,0 # 0 1 2 3 4 5 6 7 8 9 kc_1000: .byte 0,100,200,255,255,255,255,255,255,255 kc_100: .byte 0, 10, 20, 30, 40, 50, 60, 70, 80, 90 kc_10: .byte 0, 2, 4, 6, 8, 10, 12, 14, 16, 18 # (n << 1) | lsb #endif #if STEP_kHz == 20 kc_P0: .byte 0x00, 0x10 # 10 and 1 kc add for halfstep (P0) kc_chan: .byte 0, 0, 0, 0 # 1 kc ls_chan: .byte 0,0, 0,2, 0,4, 0,6 # 100 and 10 kc .byte 0,8, 1,0, 1,2, 1,4 .byte 1,6, 1,8, 2,0, 2,2 .byte 2,4, 2,6, 2,8, 3,0 ms_chan: # 10 and 1 Mc and 100 kc .byte 0,0,0, 0,3,2, 0,6,4, 0,9,6 .byte 1,2,8, 1,6,0, 1,9,2, 2,2,4 .byte 2,5,6, 2,8,8, 3,2,0, 3,5,2 .byte 3,8,4, 4,1,6, 4,4,8, 4,8,0 # 0 1 2 3 4 5 6 7 8 9 kc_1000: .byte 0, 50,100,150,200,250,255,255,255,255 kc_100: .byte 0, 5, 10, 15, 20, 25, 30, 35, 40, 45 kc_10: .byte 0, 0, 1, 1, 2, 2, 3, 3, 4, 4 #endif #if STEP_kHz == 12 kc_P0: .byte 0x00, 0x06 # 10 and 1 kc add for halfstep (P0) kc_chan: .byte 0, 2, 5, 7 ls_chan: .byte 0,0, 0,1, 0,2, 0,3 .byte 0,5, 0,6, 0,7, 0,8 .byte 1,0, 1,1, 1,2, 1,3 .byte 1,5, 1,6, 1,7, 1,8 ms_chan: .byte 0,0,0, 0,2,0, 0,4,0, 0,6,0 .byte 0,8,0, 1,0,0, 1,2,0, 1,4,0 .byte 1,6,0, 1,8,0, 2,0,0, 2,2,0 .byte 2,4,0, 2,6,0, 2,8,0, 3,0,0 # 0 1 2 3 4 5 6 7 8 9 kc_1000: .byte 0, 80,160,240,255,255,255,255,255,255 kc_100: .byte 0, 8, 16, 24, 32, 40, 48, 56, 64, 72 kc_10: .byte 0, 1, 2, 3, 3, 4, 5, 6, 7, 7 #endif /* * speaker volume bits for different settings 0...9 * bit 0x20 activates earphone. */ voltbl: # 0 1 2 3 4 5 6 7 8 9 .byte 0,0x20,0x21,0x23,0x25,0x27,0x29,0x2B,0x2D,0x2F /* * mask from bit number 0..3 */ bitmasks: .byte 0x01, 0x02, 0x04, 0x08 BAND_SCAN = 1 MEMORY_SCAN = 2 PRIONLY_SCAN = 3 CUSTOM_SCAN = 4 NEXT_SCAN = 5 /* * ledbits into displayable codes * LED1_S cannot be used. */ ledtbl: .byte 20 # 0 .byte 39 # 1 rqa man .byte 43 # 2 rqe e .byte 63 # 3 rqe rqa e man .byte 31 # 4 bsy a .byte 4 # 5 bsy rqa a man .byte 61 # 6 bsy rqe a e .byte 2 # 7 bsy rqe rqa a e man .byte 27 # 8 on aut .byte 13 # 9 on rqa aut man .byte 6 # A on rqe aut e .byte 1 # B on rqe rqa aut e man .byte 3 # C on bsy aut a .byte 15 # D on bsy rqa aut a man .byte 5 # E on bsy rqe aut a e .byte 22 # F on bsy rqe rqa aut a e man LED0_REQA = 0x01 LED0_REQE = 0x02 LED0_BUSY = 0x04 LED0_ON = 0x08 LED1_MAN = 0x01 # simplex 1 LED1_E = 0x02 # simplex 2 LED1_A = 0x04 # simplex 3 LED1_AUT = 0x08 xLED1_S = 0x10 # problematic to lit with others. /* * digits into displayable codes. */ chrtbl: # 0 1 2 3 4 5 6 7 # 8 9 A B C D E F .byte 0x4F, 0x28, 0x32, 0x33, 0x34, 0x35, 0x36, 0x37 .byte 0x38, 0x39, 0x41, 0x1E, 0x43, 0x23, 0x45, 0x46 /* already displayable stuff */ DPY_HEAD0 = 0xAF DPY_HEAD1 = 0xC0 DPY_TRAIL = 0xFE C_P = 0x50 C_E = 0x45 C_H = 0x48 C_L = 0x4C C_r = 0x2B C_o = 0x26 C_r_rev = 0x7E # _| C_t = 0x7B C_n = 0x4D C_y = 0x6F /* * internal codes <-> serial ascii, * characters at the tail of sermap (starting from C currently) * cannot be sent without additional delay, * finding them overflows stopbittime. */ sermap: .byte '#', '*', '+', '-', 'A', 'T', 'N', 'C', 0 .byte KEY_HASH,KEY_STAR,KEY_PLUS,KEY_MINUS,KEY_A,KEY_T,KEY_N,KEY_C, 0 SERMAPX = (. - sermap) / 2 chrmap: .byte '0', '1', '2', '3', '4', '5', '6', '7' .byte '8', '9', 'A', 'B', 'C', 'D', 'E', 'F' arp_ccirs: .byte LO(ee_ccir_a1), LO(ee_ccir_a2), LO(ee_ccir_a3) .byte LO(ee_ccir_pepa), 0 ev_ccirs: .byte LO(ee_ccir_csq) .byte LO(ee_ccir_e1), LO(ee_ccir_e2), LO(ee_ccir_e3) .byte LO(ee_ccir_pepa), 0 tx_ccirs: .byte LO(ee_ccir_tx_0) .byte LO(ee_ccir_e1), LO(ee_ccir_e2), LO(ee_ccir_e3) .byte LO(ee_ccir_a1), LO(ee_ccir_a2), LO(ee_ccir_a3) .byte LO(ee_ccir_pepa), 0, LO(ee_ccir_csq) rr_tbl:.byte ' ', ' ' .byte ' ', C_r .byte C_r, C_r .byte C_r, C_r strings: .byte 'A', C_r, 'E', 'A' # 0 .byte C_r, 'E', 'C', 'L' # 1 .byte 'P', C_r, '1', C_o # 2 .byte 'L', 1 , 'S', C_t # 3 .byte 'S', 'E', 'A', C_r # 4 .ascii "EH ?" ; Eh = 5 .ascii "PEPA" ; Pepa = 6 ASSERT(HI(.) == HI(tables)) ALIGN_PAGE /* * scancode from keypad into enumerated keycode * some commands are also enumerated. */ keytbl: .byte 1,4,7,0xD,2,5,8,0,3,6,9,0xC,0xA,0xB,0xE,0xF,0x10,0x11,0x12,0x13 # 1,4,7,'*',2,5,8,0,3,6,9,'#','-','+','A','T', 'N', 'C', 'D', 'U' SIZE_keytbl = . - keytbl KEY_MINUS = 0xA KEY_PLUS = 0xB KEY_HASH = 0xC KEY_STAR = 0xD KEY_A = 0xE KEY_T = 0xF KEY_N = 0x10 KEY_C = 0x11 KEY_UP = 0x12 KEY_DOWN = 0x13 CMD_1800 = 0x17 # 1800 Hz detected over configured minimum CMD_UP = 0x18 CMD_DOWN = 0x19 CMD_SETUP = 0x1A CMD_PTT = 0x1B CMD_SCAN_A = 0x1C CMD_SCAN_B = 0x1D CMD_ACT_H = 0x1E CMD_ACT_U = 0x1F CHR_CCIR_E = 0x40 # mask 0 10 0 dddd CHR_CCIR_A = 0x60 # mask 0 11 0 dddd serint: ADJUST(Rvar, sermask) serint_next: ADJUST(Rram, junk) ADJUST(Rptr, serc) ldi 0 str Rvar # long mask serint_long_next: sex Rram 1: inp 4 # input 4 bn2 1b # await end of NUL 9: ldi 0 plo Rtmp phi Rtmp 1: bn2 1f # 2 startbit ! inp 4 dec Rtmp glo Rtmp bnz 1b ghi Rtmp bnz 1b lbr interrupt_return # timeout 1: ldi 0 # 2 plo Reeprom # 4 counts onebits nop # 7 ++++ ldi 0x80 # 4 str Rptr # 6 DF after 8 databits ldi 10 # 8 The n plo Rtmp # 10 ++++ 1: inp 4 # 2 inp 4 # 4 dec Rtmp # 6 glo Rtmp # 8 not yet half of startbit ? bnz 1b # 10 ++++ 10 + 7 + n * 10 == 233/2 == 117 b2 9b # only if startbit still 0 /* * At half of startbit. * Do full bittimes */ 8: ldi 26 # 2 plo Rtmp # 4 1: inp 4 # 2 dec Rtmp # 4 glo Rtmp # 6 bnz 1b # 8 +++ n * 8 inp 4 # 2 inp 4 # 4 nop # 7 ++++ 7 ldn Rptr # 6 shr # 8 b2 1f # 10 ori 0x00 # 12 br 2f # 14 1: ori 0x80 inc Reeprom # branches timed same, onebits++ 2: str Rptr # 16 save bnf 8b # 18 ==== not yet 8 bits # ++++ 18 + 7 + n * 8 == 233 /* * See parity. */ ldi 28 # 2 plo Rtmp # 4 nop # 7 1: inp 4 # 2 dec Rtmp # 4 glo Rtmp # 6 bnz 1b # 8 +++ n * 8 bn2 1f # 9 inc Reeprom # not counted 1: # ++++ 9 + 28 * 8 == 233 glo Reeprom # 2 shr # 4 DF used few lines below ! ADJUST(Rtbl, sermap) # 8 look below. /* * See stopbit. */ ldi 20 # 10 XXX on the short side to get more time. plo Rtmp # 12 1: inp 4 # 2 dec Rtmp # 4 glo Rtmp # 6 bnz 1b # 8 +++ n * 8 # ++++ 14 + 27 * 8 == 230 sex Rptr # 14 used below bn2 serint # framing error bdf serint # parity error, here the DF /* character in *Rptr, long mask in *Rvar */ ldn Rptr smi '0' bnf 2f # < '0' plo Rtmp smi 10 bnf 9f # <= '9', digit, ok in Rtmp.LO smi 'L' - 10 - '0' bnz 2f ldi 0x80 str Rvar br serint_long_next 6: ldn Rptr smi 4 # EOT lbz interrupt_return smi 1 # ENQ bz sertell br serint ; nop 2: lda Rtbl bz 6b sm bnz 2b glo Rtbl adi SERMAPX - 1 plo Rtbl ldn Rtbl plo Rtmp 9: ADJUST(Rram, keyinp) ldn Rram # get insertion point plo Rptr ldn Rptr smi 0xFF bnz serint_next # no space glo Rtmp # code sex Rvar # mask or str Rptr # *keyinp++ = code inc Rptr glo Rptr ani SIZE(keyqueue) - 1 str Rram br serint_next sertell: sex Rram ADJUST(Rram, junk) LDREG(Rtmp, dpyleds - 1) 9: inc Rtmp glo Rtmp # where we are smi LO(dpybufend) # just past ? bnf 1f # go to translation if below end. lbnz interrupt_return # all sent. outta here. ldi 0x0A # at end. append newline br 3f 1: ldn Rtmp plo Rvar # assume already ascii ani ~0xF bnz 2f # needs no translation ldn Rtmp adi LO(chrmap) plo Rtbl ldn Rtbl 3: plo Rvar # binary to serial character 2: ldi 1 + 8 # start plus 8 databits plo Rptr ldi 0 plo Reeprom # parity counter req # 2 startbit br 2f # 4 go to delay for start 3: glo Rvar # 2 shrc # 4 plo Rvar # 6 save rest bdf 1f # 8 ==== 8 cycles additional to prev bit req # br 2f # branches same time 1: seq # 2 inc Reeprom # 4 2: ldi 26 # 6 plo Rtbl # 8 1: inp 4 # 2 dec Rtbl # 4 glo Rtbl # 6 bnz 1b # 8 ==== 8 * 26 = 208 ldi 0 # ++ 2 dec Rptr # 10 glo Rptr # 12 lbnz 3b # 15 ==== # ++++++++ 8 + 208 + 2 + 15, 233 cycles glo Reeprom # 2 shr # 4 look parity bnf 1f # 6 even already seq # 8 last bit got the required few cycles br 2f # 1: req br 2f # 2 2: ldi 28 # 4 plo Rtbl # 6 nop # 9 1: inp 4 # 2 dec Rtbl # 4 glo Rtbl # 6 bnz 1b # 8 === # +++++ 9 + 28 * 8 == 233 seq # 2 stop bit ldi 90 # 4 generous stopbit, about 2 bits plo Rptr # 6 1: inp 4 # 2 dec Rptr # 4 glo Rptr # 6 bnz 1b # 8 ==== 8 * n lbr 9b # next byte /*-------------------------------------------- * Timer interrupt. * */ interrupt_return: sex Rstk # prepare for ret from stack. ldxa # pop DF and shr # shift it into place ldxa plo Rvar ldxa plo Rptr ldxa plo Rram ldxa plo Reeprom ldxa plo Rtbl ldxa plo Rtmp ldxa phi Rtmp ldxa # pop D. ret # pop X,P. increments stack as a side effect interrupt: dec Rstk sav # T (old X,P) dec Rstk stxd # D ghi Rtmp stxd glo Rtmp stxd glo Rtbl stxd glo Reeprom stxd glo Rram stxd glo Rptr stxd glo Rvar stxd shlc # lastly, shift DF into D stxd # and save it. /* * Refresh input values in ram, also keep watchdog happy. */ inp 4 # Input 4 to scratch at TOS. lda Rstk # TOS left pointing to last valid byte. put_in4 sex Rram /* * Input routines. * Keypad and separate buttons. * Buttons are looked at only every 32 ms, for debouncing. * CCIR decoders are also looked at here. */ RRET = Rint sep Rkeyproc get_upd bz 1f sep Rdpyproc 1: glo Rscan ani 31 # 32 msec elapsed ? (LOW, NOT THE SCAN MODE) bnz 9f lbr check_ccirs # ccirs and buttons ret_check_buttons: glo Rscan # 1/4 seconds elapsed ? bnz 9f ADJUST(Rram, alerttimer) ldn Rram bz 1f # decrement only if running smi 1 str Rram bnz 1f ldi 1 dec Rram ; ASSERT(godeaf == (alerttimer - 1)) str Rram inc Rram 1: inc Rram ; ASSERT(silencetimer == (alerttimer + 1)) ldn Rram bz 1f # decrement or restart only if running. get_in4 ani I4_SQUELCH bnz 2f ldn Rram # no carrier, see if long enough to close audio smi 1 str Rram bnz 1f ldi 2 dec Rram dec Rram str Rram br 1f 2: inc Rram ; ASSERT(silence_time == (silencetimer + 1)) ldn Rram dec Rram str Rram # got again carrier and restarted silencetimer 1: 9: ghi Rscan # this does a lot. dec Rscan # decrement only LSB of Rscan and check for NZ MSB phi Rscan bz 9f # skip if not scanning ADJUST(Rram, steptimer) ldn Rram bz 1f smi 1 str Rram 1: glo Rscan bnz 9f # not yet 1/4 s down. inc Rram ; ASSERT(scantimer == (steptimer + 1)) ldn Rram lsz; smi 1 str Rram 1: 9: /* * Update outputs. */ /* * Copy synth to output_2 and output_1 (LSb) * Also set the other general bits in output_1 */ sex Rram ADJUST(Rvar, synth) ADJUST(Rram, output_1) glo Rflags shr ; ASSERT(FLAG_LOW_SYNTH_P0 == 1) plo Rtbl # keep shifting ldn Rram ani ~(O1_SYNTH_P0 | O1_EXTERN_ALARM) bnf 1f ori O1_SYNTH_P0 1: str Rram glo Rtbl # here shr ; ASSERT(FLAG_LOW_EXAL == 2) bnf 1f ldn Rram ori O1_EXTERN_ALARM str Rram 1: inc Rram ; ASSERT(output_2 == (output_1 + 1)) ldn Rvar str Rram # output_2 ok if RX ghi Rbeeps bz check_ptt # b if not beeping. smi 1 phi Rbeeps lbnz tx_is_on ADJUST(Rram, output_5) ADJUST(Rvar, ccirtxptr) ldn Rvar # get ccir-pointer bz end_beeps plo Rptr # aim. ldn Rptr # get tone ani 0xF0 bnz end_beeps # b if above 0xF (0...9 and R legal) ldn Rram ani 0x07 # clear tone bits and mic. str Rram ldn Rptr # get tone again. shl4 or str Rram # out5 updated inc Rptr glo Rptr str Rvar # save incremented pointer. ldi BEEPTICKS phi Rbeeps lbr tx_is_on # keep beeping. end_beeps: ldi 0 str Rvar # zero pointer. ldi BLIPTICKS plo Rbeeps # tell user signalling ended. ldn Rram ori O5_CCIR_OFF_MASK # ccir generator off, mic online str Rram check_ptt: # look at PTT ADJUST(Rram, output_5) ldn Rram bn1 1f # if PTT pressed. ani ~O5_MIC_ON str Rram lbr rx_mode 1: ori O5_MIC_ON # activate mic only with PTT str Rram tx_is_on: ASSERT(FLAG_HIGH_RPTR_REV == 0x02) ASSERT(FLAG_HIGH_RPTR == 0x01) ADJUST(Rram, output_2) ghi Rflags ani FLAG_HIGH_RPTR | FLAG_HIGH_RPTR_REV bz 3f shr bnf 2f 1: ADJUST(Rvar, rptr_diff) # prepare to adjust divisor ldn Rvar # get difference sd # (RX) - D str Rram # difference ok. br 3f 2: ADJUST(Rvar, rptr_diff) # prepare to adjust divisor ldn Rvar add # (RX) + D str Rram # difference ok. 3: ADJUST(Rvar, trx_diff) # prepare to adjust divisor ldn Rvar add str Rram # tx correction saved. ADJUST(Rvar, synthwas) lda Rvar # get previous synth value, inc over lock. sm # previous - current bz 1f # skip if same freq ldn Rram dec Rvar ; ASSERT(synthlock == (synthwas + 1)) str Rvar # save changed previous inc Rvar ldi SYNTH_LOCK_TICKS str Rvar 1: ldn Rvar bz 1f # not deferring smi 1 str Rvar # decrement timer and save for next time br rx_mode # No tx just yet. 1: ADJUST(Rvar, trlo) lda Rvar ; ASSERT(trhi == (trlo + 1)) sm # lower bound - divisor, below band ? bdf 2f # branch if illegal ldn Rvar sd # divisor - upper bound bdf 2f # note inverted sense of DF when subbing. /* * Mute audio during TX */ inc Rram ; ASSERT(output_3 == (output_2 + 1)) ldn Rram ori O3_TXON # sending a beep or PTT pressed. ani ~(O3_VOLABITS | O3_DO_TONE) str Rram #if 1 glo Rbeeps bz fix_outputs_ret dec Rbeeps # beeping case. ADJUST(Rvar, blipvolume) ldn Rvar ori O3_DO_TONE | O3_EARPHONE_ON or str Rram #endif br fix_outputs_ret # TX setup done. #if 0 2: ADJUST(Rvar, dpyfreq) ADJUST(Rtbl, Error) 1: lda Rtbl bz 1f str Rvar inc Rvar br 1b 1: #else 2: ldi 1 plo Rbeeps #endif rx_mode: /* * Keyclick. * Cases: * doing keyclick * muted * scanning * normal */ ADJUST(Rram, output_3) ADJUST(Rvar, volabits) ldn Rram # clear previous volume setting ani ~(O3_TXON | O3_DO_TONE | O3_VOLABITS) str Rram # assumption, no audio at all. glo Rbeeps bnz 2f # keyclick active. ghi Rflags # not beeping, muted ? ani FLAG_HIGH_MUTE_ACT bnz 1f # leave audio off if mute active. ldn Rvar ani O3_VOLABITS # just the volabits or str Rram ghi Rscan # scanning ? bz fix_outputs_ret # not. glo Rflags ani FLAG_LOW_SCANX # scanner stopped ? bnz fix_outputs_ret # leave audio on if scanner stopped. ldn Rram ani ~O3_VOLUME str Rram # silence during channel change. br fix_outputs_ret 1: ldi O3_SQUELCH_ENB # mute case. keep squelch working. or str Rram br fix_outputs_ret 2: dec Rbeeps # beeping case. ADJUST(Rvar, blipvolume) ldn Rvar ani O3_VOLABITS # just the volabits ori O3_DO_TONE | O3_EARPHONE_ON # audible clicks even when muted. or str Rram fix_outputs_ret: ADJUST(Rram, out_ports) sex Rram out 1 out 2 out 3 out 5 out 7 bn2 1f # character on serial line ! lbr interrupt_return 1: lbr serint /*-------------------------------------------------------------- * Send the display characters into vacuum display. */ sep RRET dpyproc: get_upd adi 1 # 1=request, 2=processing started bz 1f put_upd 1: ADJUST(Rram, dpyptr) ldi LO(dpyleds) str Rram # set starting point. send_next_byte: ADJUST(Rram, dpyptr) ldn Rram plo Rvar # set pointer ADJUST(Rram, dpybuf) # destination for shifter bits glo Rvar smi LO(dpychars) bdf 1f # go if above led-bytes. ldn Rvar # led1 adi LO(ledtbl) # number to display code. plo Rtbl ldn Rtbl # xlate from table. br 2f 1: ldn Rvar # load next number/character. ani ~0xF # exceeds table ? bnz 1f ldn Rvar # load next number/character again adi LO(chrtbl) # number to display code. plo Rtbl ldn Rtbl # xlate from table. br 2f 1: ldn Rvar # load next number/character again 2: str Rram # put code into shifter buffer. inc Rram ; ASSERT(dpybits == (dpybuf + 1)) ldi 8 send_next_bit: str Rram # # bits in buffer. ADJUST(Rram, dpybuf) ldn Rram # load buffer. shl # get next bit. str Rram # save rest into buffer. ADJUST(Rram, output_1) ldn Rram # assume bit (in DF) is "1" ori O1_SDO | O1_DPYCLK # also raise clock. bdf 1f ani ~O1_SDO # no, was "0" 1: str Rram # store changed output-word. sep RRET # now wait ... ADJUST(Rram, output_1) ldn Rram ani ~O1_DPYCLK str Rram sep RRET # ... trailing edge. ADJUST(Rram, dpybits) # what to do at raising edge ? ldn Rram smi 1 # just sent one bit. more bits ? bnz send_next_bit # yes. count saved at jump destination. ADJUST(Rram, dpyptr) ldn Rram adi 1 str Rram # remember place smi LO(dpybufend) # done past the whole array ? lbz 2f /* * More bytes to go. * prevent crosstalk to transmit audio by halting if TXON. * MIC is only set during voice-xmit, so it suffices to * check for activated mic. */ 1: ADJUST(Rram, output_5) ldn Rram ani O5_MIC_ON lbz send_next_byte # continue sending, no problem wth crosstalk. sep RRET lbr 1b # check again. 2: /* * back in initial state, dpyclk low. * * upd is 1 if another repaint needed. * otherwise processing ends for now. */ get_upd smi 1 lbz dpyproc - 1 # send the array again. ldi 0 put_upd # mark idle. lbr dpyproc - 1 # ready for next train. /*-------------------------------------------- * keypad input handler. * Called from interrupt every millisecond. * Shifts in the key in and puts it into key queue. * * Note that SDI is inverted 3 times between * the shifter and /EF3, so the ops b3 and bn3 * are used to detect active and non-active SDI. * * A blip-tone is emitted every XXX ms the key is held down. */ sep RRET keyproc: bn3 keyproc - 1 # SDI ? keep waiting if not. ADJUST(Rram, keyticker) ldi 0 # 0 both ticker and quarter-counter str Rram inc Rram ; ASSERT(keytime == (keyticker + 1)) str Rram ldi BLIPTICKS # blip for so many ms. plo Rbeeps ADJUST(Rram, output_1) ldn Rram ani ~O1_KEYCLK # mask CLK1 off, creating first trailing edge. str Rram 1: sep RRET # come back later. ADJUST(Rram, keyticker) ldn Rram adi 1 str Rram # bump keytime counter with 768 ms intervals bnz 2f # but dont overflow. inc Rram ; ASSERT(keytime == (keyticker + 1)) ldn Rram adi 1 bz 2f # dont overflow quarter-counter str Rram ani 3 # blip every 4th overflow. about 1 sec. bnz 2f ldi BLEEPTICKS # again blip, now longer plo Rbeeps 2: ADJUST(Rram, output_1) ldn Rram xri O1_KEYCLK str Rram # flip clock. ani O1_KEYCLK bnz 1b # if raising edge, wait trailing. bn3 1f # SDI still high ? wait startbit, giving pulses. br 1b 1: ADJUST(Rram, keybits) ldi 0x80 # this will give DF after 8 shifts. str Rram # store shifter. 1: sep RRET # back later for bit. ADJUST(Rram, output_1) ldn Rram xri O1_KEYCLK # flip clock. str Rram ani O1_KEYCLK bnz 1b # if raising edge, wait trailing. ADJUST(Rram, keybits) ldn Rram shr # shift previous bits. DF after all eight here. bn3 2f ori 0x80 # add current bit, was "1" 2: str Rram # save keycode shifter. bnf 1b # more to come, if no DF. /* * Good key received ? Translate into number/character. */ smi SIZE_keytbl bdf 9f # ignore invalid keys (over keycode table) adi SIZE_keytbl + LO(keytbl) plo Rtmp ldi HI(keytbl) phi Rtmp ADJUST(Rram, keytime) ldn Rram shr # divide by 4 to get "seconds" shr lsz # quick press, zero hibit flag ok. ldi 0x80 str Rram # long press, change into hibit flag ldn Rtmp # now number/character from table. sex Rram or # get possible hibit mask. plo Rtbl # save code for a while ADJUST(Rram, keyinp) ldn Rram # get insertion point plo Rvar ldn Rvar smi 0xFF bnz 9f # not empty slot. glo Rtbl # now get the keycode. str Rvar # *keyinx = code inc Rvar glo Rvar ani SIZE(keyqueue) - 1 str Rram br 1f 9: ldi 0xFF # longer than BLEEPTICKS plo Rbeeps 1: sep RRET # one more wait for the last raise of CLK1. ADJUST(Rram, output_1) ldn Rram ori O1_KEYCLK # set CLK1 high. str Rram sep RRET # and another wait maybe unnecessary. br keyproc - 1 # key stuff now handled. ready for next. /* * Finally can set interrupt reg too. */ over_pure_stuff: sex Rram LDREG(Rint, interrupt) /* * Copy some stuff into RAM from EEPROM. * CCIR strings are not copied. */ LDREG(Rtmp, setup_table) 9: ADJUST(Rram, prev_4) inp 4 # watchdog. lda Rtmp plo Rvar # type smi 0xFF lbz 9f # 0xFF ends table, break. lda Rtmp plo Rram # RAM address lda Rtmp plo Reeprom # EEPROM address lda Rtmp plo Rtbl # ROM address glo Rtmp adi 16 - 4 - 1 plo Rtmp # over last byte of record. inc Rtmp # bump into next. page might change. glo Rram bz 9b # no RAM address, next glo Rvar smi SETUP_NIBB bz 1f glo Rvar smi SETUP_T ; ASSERT(SETUP_S == (SETUP_T)) bz 1f glo Rvar smi SETUP_F bz 1f br 9b # not interesting this time, next 1: glo Reeprom bnz 1f # EEPROM address glo Rtbl bnz 2f # ROM address br 9b # next. 1: lda Reeprom ani 0xF str Rram glo Rvar smi SETUP_NIBB bz 9b # only the lower nibble. ldn Reeprom shl4 or str Rram br 9b # next. 2: ldn Rtbl str Rram 7: lbr 9b # next. 9: /* * Some stuff needs more shuffling about. */ /* * Frequency and #-list. */ ADJUST(Reeprom, ee_synth) ADJUST(Rram, synth) ADJUST(Rptr, VIP_list) ADJUST(Rvar, output_2) lda Reeprom ani 0xF str Rram lda Reeprom shl4 or str Rram # synth mirror str Rvar # real synth output. 1: ldn Rram str Rptr # VIP-list inc Rptr glo Rptr smi LO(VIP_listend) bnz 1b ADJUST(Rram, prev_4) inp 4 /* * Volume. */ ADJUST(Reeprom, ee_volume) ADJUST(Rvar, volume) ADJUST(Rptr, volabits) ADJUST(Rram, output_3) ldn Reeprom ani 0xF str Rvar # volume setting ramified. adi LO(voltbl) plo Rtbl ldn Rram ani ~O3_VOLABITS str Rram # all volume bits off. ldn Rtbl # translated volume bits. str Rptr # save volabits for later. or str Rram # volume bits ok. /* * Miscellaneous. */ ADJUST(Reeprom, ee_misc) ldn Reeprom ani EE_MISC_MUTEMASK plo Rtmp smi EE_MISC_TIMERSQ bnz 1f ghi Rflags ori FLAG_HIGH_TIMERSQ | FLAG_HIGH_MUTE | FLAG_HIGH_MUTE_ACT phi Rflags 1: glo Rtmp smi EE_MISC_CODESQ bnz 1f ghi Rflags ori FLAG_HIGH_CODESQ | FLAG_HIGH_MUTE | FLAG_HIGH_MUTE_ACT phi Rflags 1: glo Rtmp smi EE_MISC_MUTE bnz 1f ghi Rflags ori FLAG_HIGH_MUTE | FLAG_HIGH_MUTE_ACT phi Rflags 1: ldn Reeprom ani EE_MISC_RPTR bz 1f ghi Rflags ori FLAG_HIGH_RPTR phi Rflags 1: lda Reeprom ; ASSERT(ee_simplexes == (ee_misc + 1)) ani EE_MISC_P0 bz 1f inc Rflags ; ASSERT(FLAG_LOW_SYNTH_P0 == 1) 1: /* * Simplex controls and TX power. Enlighten 'Virta' too. */ ADJUST(Rram, output_7) ldn Reeprom # xxxx P321 in eeprom ani 0xF # 0000 P321 shl # 000P 3210 in latch str Rram ADJUST(Rram, led0) ldi LED0_ON str Rram inc Rram ; ASSERT(led1 == (led0 + 1)) ; ASSERT(LED1_MAN == 1) ; ASSERT(LED1_E == 2) ; ASSERT(LED1_A == 4) ldn Reeprom # xxxxP321 xri 7 ani 7 # 00000321 inverted str Rram /* * Shut down when scanning ? * bit3 is squelch setting. */ ADJUST(Reeprom, ee_scanmode) ldn Reeprom ani 0x7 phi Rscan ldn Reeprom ani EE_MISC2_SQ str Reeprom # clear scanmode, keep SQ-bit bz 1f ADJUST(Rvar, volabits) ldn Rvar ori O3_SQUELCH_ENB str Rvar inc Rvar ; ASSERT(blipvolume == (volabits + 1)) ldn Rvar ori O3_SQUELCH_ENB str Rvar 1: /* * Clear ccir history. */ LDREG(Rtmp, ccir_history) sex Rtmp 1: inp 4 # watchdog ldi ' ' str Rtmp inc Rtmp glo Rtmp bnz 1b dec Rtmp # Last dec Rtmp # 2nd last ldi '-' str Rtmp # 'empty marker' sex Rram /* * Dont continue until PTT released * Emit tone too */ ADJUST(Rram, prev_4) ADJUST(Rvar, output_3) 1: sex Rram inp 4 b1 1f # wait until PTT released. ldi 0 phi Rscan # dont continue scanner if PTT-start ldn Rvar plo Rtmp ori O3_DO_TONE | 1 str Rvar sex Rvar out 3 dec Rvar # undo ++ from out glo Rtmp str Rvar # no beep when next updated br 1b 1: init_complete: /*-------------------------------------------- * Now all set for interrupts. * Fake a "return from interrupt" * keeping Rpgm in current value, and setting Rram as RX. * * Start mainloop. */ sex Rpgm ret .byte (Rram << 4) | Rpgm # X,P for ret-instruction ldi 100 1: idl smi 1 bnz 1b ghi Rscan lbnz maybe_restart_scanner lbr mainloop very_decrease_audio: ADJUST(Rvar, volume) ldi 1 br 3f very_increase_audio: ADJUST(Rvar, volume) ldi 9 br 3f decrease_audio: ADJUST(Rvar, volume) ldn Rvar lbz 2f # already setting 0 smi 1 3: str Rvar # update volume lbr 2f increase_audio: ADJUST(Rvar, volume) ldn Rvar # PLUS; increase audio smi 9 # "kaakossa" ? bz 2f adi 10 # ++, but also correct above smi str Rvar 2: ADJUST(Rram, volabits) ldn Rram ani ~(O3_VOLUME | O3_EARPHONE_ON) str Rram ldn Rvar adi LO(voltbl) plo Rtbl ldn Rtbl sex Rram or str Rram # save bits lbr update_display send_beep: ADJUST(Rram, ccirtxbuf + 5) ldi 0xFF # terminate series stxd ldi 8 # 500 ms '8' stxd stxd stxd stxd stxd lbr send_ccir_again /* * If given string is just one digit, * replace string in digbuf with one from eeprom. */ send_ccir: ADJUST(Rram, ccirtxbuf) ADJUST(Rvar, digidx) ldn Rvar bz 9f # length 0, cannot happen. plo Rtmp # length of string to send. smi 1 bnz 8f # not length 1, not preset. ADJUST(Rptr, digbuf) ldn Rptr # the digit, 0..9 adi LO(tx_ccirs) plo Rtbl ldn Rtbl # map digit to one of preset ones. plo Reeprom bz 8f # '8' has no preset ccir, send "8" ldi 0 plo Rtmp # count length. 1: lda Reeprom ani 0xF smi 0xF bz 1f # shorter than EECCIRLEN adi 0xF str Rptr inc Rptr inc Rtmp glo Rtmp smi EECCIRLEN # max length in eeprom bnz 1b 1: glo Rtmp # was it configured ? bnz 8f # digbuf was touched only when length != 0 ldn Rvar # digidx. plo Rtmp # send "n" originally in digbuf. 8: ldi 0xF phi Rtmp # no prev code. str Rram inc Rram # start with silence. ADJUST(Rptr, digbuf) # back to start, in case string was replaced. 1: lda Rptr str Rram ghi Rtmp # prev code. sex Rram sm # same code as previous ? bnz 2f ldi CCIR_R str Rram 2: lda Rram phi Rtmp dec Rtmp glo Rtmp bnz 1b 9: ldi 0xFF str Rram # terminator for string. send_ccir_again: ADJUST(Rram, led0) ldn Rram ori LED0_BUSY str Rram ldi 1 put_upd # request repaint ldi 0 phi Rscan # stop scanning. ADJUST(Rram, ccirtxptr) ldi LO(ccirtxbuf) str Rram # set pointer. /* * Push current frequency into VIP-list */ ADJUST(Rvar, VIP_list) ADJUST(Rram, synth) sex Rram ldn Rram phi Rtmp # synth pushed to list 1: ldn Rvar # get current in list plo Rtmp # save for insertion down the list ghi Rtmp # get previous str Rvar # replace current in list glo Rtmp # see what was just overwritten phi Rtmp # will be inserted in next round sm bz 1f # leave rest of list intact, if overwrote synth inc Rvar # step down the list glo Rvar smi LO(VIP_listend) bnz 1b # until all over 1: ldi BEEP0TICK phi Rbeeps # start ! lbr update_display toggle_mute: glo Rflags ani ~FLAG_LOW_EXAL plo Rflags ghi Rflags ani FLAG_HIGH_MUTE # was enabled ? bnz 1f ghi Rflags ori FLAG_HIGH_MUTE | FLAG_HIGH_MUTE_ACT br 2f 1: ghi Rflags ani ~(FLAG_HIGH_CODESQ | FLAG_HIGH_TIMERSQ | FLAG_HIGH_MUTE | FLAG_HIGH_MUTE_ACT) 2: phi Rflags lbr update_display toggle_timersq: glo Rflags ani ~FLAG_LOW_EXAL plo Rflags ghi Rflags ani FLAG_HIGH_TIMERSQ # was enabled ? bnz 1f ghi Rflags ori FLAG_HIGH_TIMERSQ | FLAG_HIGH_MUTE | FLAG_HIGH_MUTE_ACT br 2f 1: ghi Rflags ani ~(FLAG_HIGH_TIMERSQ | FLAG_HIGH_MUTE | FLAG_HIGH_MUTE_ACT) 2: ani ~(FLAG_HIGH_CODESQ) phi Rflags lbr update_display toggle_squelch: ghi Rflags ani FLAG_HIGH_CODESQ bz 1f ghi Rflags xri FLAG_HIGH_MUTE_ACT phi Rflags ani FLAG_HIGH_MUTE_ACT bnz 1f ADJUST(Rram, silencetimer) ldi 4 str Rram dec Rram dec Rram ; ASSERT(silencetimer == (godeaf + 2)) ldi 0 str Rram lbr update_display 1: ghi Rflags ani FLAG_HIGH_MUTE lbnz toggle_mute # end mute instead. ADJUST(Rram, volabits) ldn Rram xri O3_SQUELCH_ENB # flip squelch. str Rram inc Rram ; ASSERT(blipvolume == (volabits + 1)) ldn Rram xri O3_SQUELCH_ENB # flip squelch. str Rram lbr update_display set_lo_tx: ADJUST(Rram, output_7) ldn Rram ani ~O7_TX_HI_POWER lbr 1f set_hi_tx: ADJUST(Rram, output_7) ldn Rram ori O7_TX_HI_POWER lbr 1f toggle_tx_power: ADJUST(Rram, output_7) ldn Rram xri O7_TX_HI_POWER 1: str Rram lbr update_display cbrowse_very_back: ldi -12 lskp cbrowse_very_forw: ldi 12 lskp cbrowse_back: ldi -1 lskp cbrowse_forw: ldi 1 plo Rtmp ADJUST(Rram, ccirhist_rp) glo Rtmp sex Rram add str Rram lbr update_with_ccirhist cbrowse_next: ldi -1 lskp cbrowse_prev: ldi 1 dec Rstk str Rstk ADJUST(Rram, ccirhist_rp) ldn Rram plo Rtmp sex Rstk 1: glo Rtmp add plo Rtmp bz 1f ldi HI(ccir_history) phi Rtmp ldn Rtmp smi ' ' lbnz 1b # not yet next 1: inc Rstk sex Rram glo Rtmp str Rram lbr update_with_ccirhist show_ccir_history: ADJUST(Rram, ccirhist_wp) lda Rram smi 1 # last ' ' str Rram ; ASSERT(ccirhist_rp == (ccirhist_wp + 1)) glo Rflags ori FLAG_LOW_CBROWSE plo Rflags lbr update_with_ccirhist leave_ccir_history: glo Rflags ani ~FLAG_LOW_CBROWSE plo Rflags lbr update_display_no_eeprom /* * simplex -> duplex rarely used * duplex -> reverse * reverse -> duplex * duplex -> simplex rarely used */ repeater_toggle: ADJUST(Rvar, rptr_diff) ADJUST(Rram, synth) ghi Rflags ani FLAG_HIGH_RPTR | FLAG_HIGH_RPTR_REV bnz 1f ghi Rflags # was simplex. ori FLAG_HIGH_RPTR ani ~FLAG_HIGH_RPTR_DIR # to duplex from simplex. br 9f 1: ghi Rflags ani FLAG_HIGH_RPTR_REV bz 1f ldn Rvar # was reverse. sex Rram add str Rram # now duplex. ghi Rflags xri FLAG_HIGH_RPTR | FLAG_HIGH_RPTR_REV ori FLAG_HIGH_RPTR_DIR # to duplex from reverse. br 9f 1: ghi Rflags ani FLAG_HIGH_RPTR_DIR # was duplex. from where ? bz 1f ghi Rflags # was duplex from reverse. ani ~FLAG_HIGH_RPTR_ALL # go simplex. br 9f 1: ldn Rvar # was duplex from simplex. sex Rram # go reverse. sd str Rram ghi Rflags xri FLAG_HIGH_RPTR | FLAG_HIGH_RPTR_REV 9: phi Rflags lbr update_display call_recall: ldi 0 phi Rscan ADJUST(Rvar, curmem) ldi NOTMEM str Rvar ADJUST(Rram, synth) ADJUST(Rptr, pri_1) ADJUST(Rvar, VIP_idx) ldn Rptr str Rram ldi 0 str Rvar glo Rflags ani ~FLAG_LOW_SYNTH_P0 plo Rflags lbr update_display_and_modes VIP_recall: ADJUST(Rram, synth) ADJUST(Rvar, VIP_idx) ldn Rvar adi LO(VIP_list) plo Rptr smi LO(VIP_listend) bnf 1f ADJUST(Rptr, pri_1) # over last -> priority 1 ldi -1 str Rvar # and restart from 0 1: ldn Rptr str Rram # update synth ldn Rvar adi 1 str Rvar bnz 1f ldi 2 * BLIPTICKS plo Rbeeps # blip when passed end of list 1: ldi 0 phi Rscan ADJUST(Rvar, curmem) ldi NOTMEM str Rvar lbr update_display_and_modes memory_store: ADJUST(Rvar, curmem) ADJUST(Rram, digval) ldn Rram smi MEMORY_CNT lbdf hmm_eh_what ldn Rram # get memory number str Rvar # set as current, no noscan bit, nor nomem bit. shl # multiply by two to get index into nibbletable adi LO(memory_divisors) plo Reeprom # 2 bytes per memory. ADJUST(Rram, synth) ldn Rram shr4 # eeprom only 4bit wide... str Reeprom # bits 7...4 inc Reeprom ldn Rram str Reeprom # bits 3...0 ldn Rvar # memory number ani 3 # get bit-mask adi LO(bitmasks) plo Rtbl # bitmask pointer ldn Rvar # memory number shr # 4 memories per byte. shr # convert to byte offset into eeprom adi LO(memory_rptrbits) plo Reeprom # positioned over the byte containing rptr bit sex Reeprom ghi Rflags ani FLAG_HIGH_RPTR bz 1f ldn Rtbl or # set repeater info for memory br 2f 1: ldn Rtbl xri 0xFF # invert mask and # clear repeater info for memory 2: str Reeprom ldn Rvar shr # get nibble number shr # 4 memories per byte. adi LO(memory_noscanbits) plo Reeprom # positioned over the byte containing noscan bit ldn Rtbl # load mask xri 0xFF # invert mask and # clear scan info for memory str Reeprom sex Rram lbr update_display set_memory_noscan: ADJUST(Rvar, curmem) ldn Rvar smi MEMORY_CNT lbdf hmm_eh_what # if no carry ldn Rvar ani 3 # get bit-mask adi LO(bitmasks) plo Rtbl ldn Rvar shr shr # get nibble number adi LO(memory_noscanbits) plo Reeprom # positioned over the byte containing noscan bit sex Reeprom ldn Rtbl # load mask or # set scan info for memory str Reeprom sex Rram ldn Rvar ori MEMORY_NOSCAN str Rvar lbr update_display to_next_memory: ADJUST(Rram, curmem) ldn Rram # 0 -> 1, NOTMEM -> 0, 39 -> 40 ani MEMORY_MASK adi 1 smi MEMORY_CNT lsnf; ldi - MEMORY_CNT adi MEMORY_CNT lbr memory_recall_D memory_recall: ADJUST(Rvar, digval) ldn Rvar smi MEMORY_CNT lbdf hmm_eh_what ldn Rvar memory_recall_D: smi MEMORY_CNT lsnf; ldi -1 adi MEMORY_CNT plo Rtmp # remember memory number ADJUST(Rvar, curmem) glo Rtmp # has no noscan bit str Rvar shl # nibble-number to byte offset adi LO(memory_divisors) plo Reeprom ADJUST(Rram, synth) ldn Reeprom shl4 str Rram inc Reeprom ldn Reeprom ani 0xF sex Rram or str Rram # synth ok glo Rflags ani ~FLAG_LOW_SYNTH_P0 plo Rflags ldn Rvar ani 3 # get bit-mask adi LO(bitmasks) plo Rtbl # bitmask pointer ldn Rvar shr shr # get nibble number adi LO(memory_rptrbits) plo Reeprom # positioned over the byte containing rptr bit sex Reeprom ldn Rtbl # have now the bitmask for memory. and # mask out the bit bz 1f ghi Rflags ori FLAG_HIGH_RPTR br 2f 1: ghi Rflags ani ~FLAG_HIGH_RPTR 2: ani ~(FLAG_HIGH_RPTR_REV | FLAG_HIGH_RPTR_DIR) phi Rflags ldn Rvar shr shr # get nibble number adi LO(memory_noscanbits) plo Reeprom # positioned over the byte containing noscan bit ldn Rtbl # load mask and # get noscan info for memory bz 1f ldn Rvar ori MEMORY_NOSCAN str Rvar 1: lbr update_display do_command: smi 0xA lbdf hmm_eh_what adi 0xA shl shl # *= 4 adi LO(1f) plo Rpgm # go! 1: lbr set_lo_tx ;nop # 90# lbr set_memory_noscan ;nop # 91# lbr flipto_setup ;nop # 92# #ifdef EEPROM lbr hmm_eh_what ;nop # 93# #else #ifdef WITHSERSEND lbr sersend_test ;nop # 93# #else lbr hmm_eh_what ;nop # 93# #endif #endif lbr reject_channel ;nop # 94# lbr clear_rejects ;nop # 95# lbr start_scanning_band ;nop # 96# lbr start_scanning_memories ;nop # 97# #ifdef EEPROM lbr hmm_eh_what ;nop # 98# #else lbr serrecv_test ;nop # 98# #endif lbr set_hi_tx ;nop # 99# ASSERT(HI(.) == HI(do_command)) execute: ldi 0 phi Rscan ADJUST(Rram, digidx) ldn Rram lbz VIP_recall # b if 0 digits. smi 2 lbnf memory_recall # b if 1 digit lbnz go_frequency # b if 3 or more. ADJUST(Rvar, digbuf) lda Rvar smi 4 lbnf memory_recall # b if 2 digits, 00 .. 39 smi 5 lbnz go_frequency # b if 2 digits, not 9x ldn Rvar lbr do_command go_frequency: ADJUST(Rram, curmem) ldi NOTMEM str Rram ldi HI(freq2div) phi Rtmp ldi LO(freq2div) plo Rtmp sep Rtmp # "call" ADJUST(Rptr, synth) lda Rstk # pop result str Rptr # P1...P8 ok ldn Rtbl # Rtbl points to byte having 0x01 set if synth P0 shr # synth P0 now in carry glo Rflags ani ~FLAG_LOW_SYNTH_P0 # assume even 12.5 kHz lsnf; ori FLAG_LOW_SYNTH_P0 plo Rflags # P0 ok lbr update_display_and_modes reject_channel: ADJUST(Rvar, synth) ADJUST(Rram, rejectidx) ldn Rram adi 1 ani 3 str Rram adi LO(rejects) plo Rram ldn Rvar br 2f clear_rejects: ADJUST(Rram, rejects + 3) ldi 0 stxd stxd stxd 2: str Rram lbr maybe_restart_scanner hmm_eh_what: ADJUST(Rram, digidx) ldi 0 stxd ; ASSERT(digval == (digidx - 1)) str Rram ADJUST(Rvar, idletimer) ldi IDLETICKS str Rvar ADJUST(Rram, dpystrings) ldi Eh lbr update_with_string reenter_setup: ADJUST(Rram, setuprec) ldi 0 br 2f enter_setup: ADJUST(Rram, setuprec) ADJUST(Rvar, digval) ldn Rvar 2: str Rram flipto_setup: glo Rflags ani ~FLAG_LOW_CBROWSE ori FLAG_LOW_SETUP plo Rflags lbr setup_display_update leave_setup: glo Rflags ani ~FLAG_LOW_SETUP plo Rflags lbr update_display next_setup_field: ldi 1 lskp previous_setup_field: ldi -1 plo Rtmp ADJUST(Rram, setuprec) glo Rtmp add str Rram lbr setup_display_update reboot: sex Rpgm dis .byte Rpgm # X 0 and P pgm ldi 0 plo 0 phi 0 sep 0 # X and P R0, R0 0000 reset_setup: ADJUST(Rram, setuptype) ldn Rram smi SETUP_banner # SETUP ? lbnz reset_setup_field ADJUST(Reeprom, end_eeprom - 1) 1: ldi 0 str Reeprom glo Reeprom bz 1f dec Reeprom br 1b 1: LDREG(Rtmp, setup_table) 9: lda Rtmp # type plo Rvar smi 0xFF lbz reboot # 0xFF ends table, break. lda Rtmp # RAM address lda Rtmp # EEPROM address plo Reeprom lda Rtmp # default value plo Rtbl glo Rtmp adi 16 - 4 - 1 plo Rtmp # over last byte of record. inc Rtmp # bump into next. page might change. glo Reeprom bz 9b # no eeprom address. glo Rtbl bz 9b # default value 0 already glo Rvar smi SETUP_CCIR bz 2f glo Rtbl str Reeprom glo Rvar smi SETUP_NIBB bz 9b glo Rtbl shr4 inc Reeprom str Reeprom br 9b # next. 2: ldi EECCIRLEN plo Rvar 1: ldi 0xF str Reeprom dec Rvar glo Rvar bz 9b inc Reeprom br 1b setup_execute: ADJUST(Rram, setuptype) ldn Rram smi SETUP_banner # SETUP ? lbnz 9f ADJUST(Rvar, setuprec) ADJUST(Rram, digval) # record number given ? ldn Rram str Rvar lbz leave_setup lbr setup_display_update 9: ADJUST(Rram, digidx) # other exec has to have value. ldn Rram lbz setup_display_update /* * Not a special setup-entry. Copy value. */ reset_setup_field: ADJUST(Rram, setuptype) ldn Rram smi SETUP_CCIR lbz setup_save_ccir # digit string 7 ? smi SETUP_BF - SETUP_CCIR lbz setup_save_bf ldn Rram smi SETUP_F lbnz 1f # some kind of frequency ? ldi HI(freq2div) phi Rtmp ldi LO(freq2div) plo Rtmp sep Rtmp # convert frequency -> divisor. ADJUST(Rptr, digval) lda Rstk str Rptr 1: ADJUST(Rvar, setupxaddr) ldn Rvar plo Rram ADJUST(Rvar, setupeaddr) ldn Rvar plo Reeprom ADJUST(Rvar, digval) ADJUST(Rptr, setuptype) ldn Rptr smi SETUP_NIBB lbz setup_save_nibb # 4 bits wide value glo Rram # ram address for variable ? lsz ldn Rvar str Rram # XXX - NIBBLE save only to lower nibble. glo Reeprom # eeprom address for variable ? bz 1f ldn Rvar str Reeprom # lower nibble ldn Rvar inc Reeprom shr4 str Reeprom # upper nibble 1: setup_did_it: ldi BLIPTICKS plo Rbeeps lbr setup_display_update setup_save_nibb: ldn Rvar ani 0xF0 # over max value ? bz 1f ldi 0x0F # make it 15 str Rvar 1: glo Rram # ram address for variable ? bz 1f ldn Rram ani 0xF0 # clear nibble from ram str Rram sex Rram ldn Rvar or str Rram # or only to lower nibble. 1: glo Reeprom # eeprom address for variable ? bz 1f ldn Rvar str Reeprom # lower nibble 1: lbr setup_did_it setup_save_bf: ldi 8 lskp setup_save_ccir: ldi EECCIRLEN plo Rtbl ADJUST(Rvar, setupeaddr) ldn Rvar bz 4f plo Reeprom ADJUST(Rvar, digidx) ldn Rvar plo Rtmp ADJUST(Rvar, digbuf) 1: glo Rtmp bz 2f dec Rtmp lda Rvar br 3f 2: ldi 0xF 3: str Reeprom inc Reeprom dec Rtbl glo Rtbl bnz 1b 4: lbr setup_did_it update_with_scan_mode: ghi Rscan smi 1 lbr update_with_string update_with_pepa_text: ldi Pepa lbr update_with_string update_display_and_modes: ADJUST(Rvar, rptr_low) lda Rvar ; ASSERT(rptr_high == (rptr_low + 1)) bz 1f ldn Rvar bz 1f ghi Rflags ani ~FLAG_HIGH_RPTR_ALL phi Rflags ADJUST(Rram, synth) ldn Rvar sex Rram sm # upper bound - synth bnf 1f # b if borrow dec Rvar ldn Rvar sd # synth - rptr_low bnf 1f # b if borrow ghi Rflags ori FLAG_HIGH_RPTR phi Rflags 1: update_display: /* * Update nonvolative data in eeprom */ ADJUST(Reeprom, eeprom) ADJUST(Rram, synth) ldn Rram str Reeprom ; ASSERT(ee_synth == (eeprom + 0)) inc Reeprom shr4 str Reeprom inc Reeprom ADJUST(Rram, volume) ldn Rram str Reeprom ; ASSERT(ee_volume == (eeprom + 2)) inc Reeprom ldi 0 str Reeprom ; ASSERT(ee_misc == (eeprom + 3)) glo Rflags ani FLAG_LOW_SYNTH_P0 bz 1f ldn Reeprom ori EE_MISC_P0 str Reeprom 1: ghi Rflags ani FLAG_HIGH_RPTR bz 1f ldn Reeprom ori EE_MISC_RPTR str Reeprom 1: ghi Rflags ani FLAG_HIGH_CODESQ bz 1f ldn Reeprom ori EE_MISC_CODESQ lbr 2f 1: ghi Rflags ani FLAG_HIGH_TIMERSQ lbz 1f ldn Reeprom ori EE_MISC_TIMERSQ lbr 2f 1: ghi Rflags ani FLAG_HIGH_MUTE bz 1f ldn Reeprom ori EE_MISC_MUTE 2: str Reeprom 1: inc Reeprom ; ASSERT(ee_simplexes == (ee_misc + 1)) ADJUST(Rram, output_7) # power and simplexes ldn Rram shr ; ASSERT(O7_SIMPLEX_1 == 2) str Reeprom ; ASSERT(O7_TX_HI_POWER == 0x10) ADJUST(Rram, volabits) ldn Rram shl shl ; ASSERT(O3_SQUELCH_ENB == 0x40) ADJUST(Reeprom, ee_scanmode) ghi Rscan ani 7 bnf 1f ori EE_MISC2_SQ 1: str Reeprom update_display_no_eeprom: ADJUST(Rram, digval) ldi 0 str Rram inc Rram ; ASSERT(digidx == (digval + 1)) str Rram update_display_keep_idx: /* * Common fields in display */ ASSERT(dpyvolume == (dpychars + 0)) ASSERT(dpytxpower == (dpychars + 1)) ASSERT(dpyblank0 == (dpychars + 2)) ASSERT(dpymemory == (dpychars + 3)) ASSERT(dpyreverse == (dpychars + 6)) ASSERT(dpyrepeater == (dpychars + 7)) ASSERT(dpyfreq == (dpychars + 8)) ADJUST(Rram, dpychars) ADJUST(Rptr, volume) ldn Rptr str Rram # "9" inc Rram ADJUST(Rptr, output_7) ldn Rptr ani O7_TX_HI_POWER lsz; ldi 'H' - 'L' adi 'L' str Rram # "9L" inc Rram ldi ' ' plo Rvar # no no-scan dash plo Rtbl plo Rtmp ghi Rflags ani FLAG_HIGH_MUTE_ACT | FLAG_HIGH_CODESQ | FLAG_HIGH_MUTE | FLAG_HIGH_TIMERSQ lbz 1f LDREG(Rtmp, modepairs) ghi Rflags ani FLAG_HIGH_MUTE_ACT lsz inc Rtmp inc Rtmp ghi Rflags ani FLAG_HIGH_CODESQ lsz inc Rtmp inc Rtmp lsz inc Rtmp inc Rtmp ghi Rflags ani FLAG_HIGH_TIMERSQ lsz inc Rtmp inc Rtmp lsz inc Rtmp inc Rtmp lsz inc Rtmp inc Rtmp lsz inc Rtmp inc Rtmp lda Rtmp plo Rtbl ldn Rtmp plo Rtmp br 9f 1: ghi Rscan # scanning ? bz 1f glo Rflags ani FLAG_LOW_SCANX # paused scanner ? bz 9f # not paused, blank memory area 1: ADJUST(Rptr, curmem) ldn Rptr shl bdf 9f # not on memory 0x80 shl bnf 1f # no noscan, 0x40 ldi '-' plo Rvar # no-scan dash. 1: ldi 0 plo Rtbl # count tens. ldn Rptr ani MEMORY_MASK 1: inc Rtbl smi 10 bdf 1b # keep counting tens. adi 10 plo Rtmp # remember ones. dec Rtbl glo Rtbl bnz 9f glo Rvar plo Rtbl ldi ' ' plo Rvar 9: glo Rvar str Rram # "9L-1" inc Rram glo Rtbl str Rram # "9L-1" inc Rram glo Rtmp str Rram # "9L-12" inc Rram ldi ' ' str Rram inc Rram # "9L-12 " glo Rflags ani FLAG_LOW_PEPA_TXT lbnz update_with_pepa_text ADJUST(Rptr, digidx) ldn Rptr lbnz update_with_digits ghi Rscan # scanning ? bz 1f glo Rflags # scanner paused ? ani FLAG_LOW_SCANX lbz update_with_scan_mode 1: ghi Rflags ani FLAG_HIGH_RPTR | FLAG_HIGH_RPTR_REV shl adi LO(rr_tbl) plo Rtbl lda Rtbl str Rram # "9L-12 r" inc Rram ldn Rtbl str Rram # "9L-12 rr" inc Rram ADJUST(Rptr, synth) ldn Rptr lbr div2freq # divisor to display. /* Rram somewhere to dpybuf, D index to string[][4] */ update_with_string: shl # 2 shl # 4 adi LO(strings) plo Rtbl ldi ' ' str Rram ; inc Rram str Rram ; inc Rram str Rram ; inc Rram lda Rtbl str Rram ; inc Rram lda Rtbl str Rram ; inc Rram lda Rtbl str Rram ; inc Rram ldn Rtbl str Rram ; inc Rram ldi 0 plo Rtmp # blank to end of area lbr 1f update_with_digits: plo Rtmp # digidx ADJUST(Rptr, digbuf) 1: glo Rram smi LO(dpybufend) lbz 4f # end of space glo Rtmp bz 2f # end of digits dec Rtmp lda Rptr br 3f 2: ldi ' ' 3: str Rram inc Rram lbr 1b 4: lbr send_display next_memory: ADJUST(Rptr, scan_idx) ldn Rptr plo Rtmp ldi HI(scanner_page) phi Rtmp ldn Rtmp smi MEMORY_CNT bnf 1f ldi 0 str Rptr plo Rtmp 1: ldn Rptr adi 1 str Rptr # index ++ for next time ADJUST(Rvar, curmem) ldn Rtmp str Rvar # new memory number ldn Rvar shl adi LO(memory_divisors) plo Reeprom ADJUST(Rram, synth) lda Reeprom shl4 str Rram ldn Reeprom ani 0xF sex Rram or str Rram # synth ok glo Rflags ani ~FLAG_LOW_SYNTH_P0 plo Rflags ldn Rvar # memory number again shr shr # get nibble number adi LO(memory_rptrbits) plo Reeprom # positioned over the byte containing rptr bit ldn Rvar ani 3 # get bit-mask adi LO(bitmasks) plo Rtbl ldn Rtbl # have now the bitmask for memory. sex Reeprom and # mask out the bit sex Rram lbz 1f ghi Rflags ori FLAG_HIGH_RPTR lbr 2f 1: ghi Rflags ani ~FLAG_HIGH_RPTR 2: ani ~(FLAG_HIGH_RPTR_REV | FLAG_HIGH_RPTR_DIR) phi Rflags lbr check_scanner_ret /* * CCIR mainline */ do_ccir_chr: sex Rram ADJUST(Rram, ev_prev) ADJUST(Rvar, key) ldn Rvar ani 0x20 # from where the 'key' came ? bz 1f ADJUST(Rram, arp_prev) 1: ldn Rram # phi Rtmp # remember previous ldn Rvar ani 0xF plo Rtmp # this char str Rram # replace previous inc Rram ; ASSERT(ev_ccirlen == (ev_prev + 1)) smi 0xF lbz do_ccir_complete smi CCIR_R - 0xF bnz 1f # go if not Repeat ghi Rtmp plo Rtmp # Repeat. use previous instead 1: ldn Rram # get length adi 1 bz 1f # no overflow of length. str Rram # length + 1 smi CCIRMAX + 1 bdf 1f # no room in buffer if no carry glo Rram # &length == base - 1 add # += length + 1 plo Rram glo Rtmp str Rram # appended 1: lbr mainloop do_ccir_complete: ldn Rram # how long it was ? smi 3 lbnf ccir_no_match # 0, 1 or 2 gave carry ldn Rvar # key ani 0x20 lsz; ldi 'A' - 'E' adi 'E' plo Reeprom # source indicator /* * Show in display. * If digits in buffer, dont show. * Also if peeking into history, no display. */ ADJUST(Rptr, digidx) ldn Rptr bnz 8f # pending command, be quiet glo Rflags ani FLAG_LOW_CBROWSE | FLAG_LOW_SETUP bnz 8f # browsing prev strings or in setup, be quiet ADJUST(Rptr, dpybufend - 8) glo Reeprom # get receiver indicator. str Rptr inc Rptr glo Rram plo Rvar inc Rvar # pointer to string ldn Rram plo Rtbl # length 1: lda Rvar str Rptr inc Rptr glo Rptr smi LO(dpybufend) bz 2f # end of space dec Rtbl glo Rtbl bnz 1b 1: ldi ' ' str Rptr inc Rptr glo Rptr smi LO(dpybufend) bnz 1b # not end of space 2: /* displayed, restart idle timer */ ADJUST(Rptr, idletimer) ldi IDLETICKS str Rptr ldi 1 put_upd 8: /* * Then copy to history, * copy at most 255 chars, and * then clear at most 128 digits from fouled oldest string. */ ADJUST(Rptr, ccirhist_wp) ldn Rptr plo Rtmp # write pointer offset ldi HI(ccir_history) phi Rtmp # keep in page. glo Reeprom str Rtmp inc Rtmp # put indicator into history. glo Rram plo Rvar inc Rvar # pointer to string ldn Rram plo Rtbl # real length (lest longer than 256) smi CCIRMAX bnf 1f ldi CCIRMAX # we saved only this much. plo Rtbl 1: ldi HI(ccir_history) phi Rtmp # keep in page. lda Rvar str Rtmp # into history inc Rtmp dec Rtbl glo Rtbl lbnz 1b # keep copying to history. glo Rtmp adi 1 # for ' ' str Rptr # index for next string. ldi 128 # max clearing plo Rtbl 1: ldi HI(ccir_history) phi Rtmp # keep in page. ldn Rtmp smi ' ' # overwrite oldest completely bz 1f ldi ' ' str Rtmp # end history inc Rtmp dec Rtbl glo Rtbl bnz 1b 1: /* * display and history ok. * Compare. */ ldn Rram # get length smi EECCIRLEN + 1 lbdf ccir_no_match # >= 9 ? too long to compare glo Reeprom phi Rtmp # eeprom used for other smi 'E' lsz; ldi arp_ccirs - ev_ccirs adi LO(ev_ccirs) - 1 plo Rtbl # list of strings to compare. 9: sex Rram inc Rtbl ldn Rtbl lbz ccir_no_match plo Reeprom # next string to compare glo Rram plo Rvar inc Rvar # start of received string. ldn Rram plo Rptr # length of received string. sex Rvar 1: lda Reeprom ani 0xF plo Rtmp # save smi 0xF bz 9b # end of configured string, if F ldn Rvar smi 0xA lbz 2f # wildcard A matches all glo Rtmp sm # compare with received string @var lbnz 9b # mismatch. 2: inc Rvar dec Rptr glo Rptr # end of received string ? lbnz 1b # more. sex Rram /* * Check case where received length less than EECCIRLEN, * received a prefix of a configured string. */ ldn Rram smi EECCIRLEN lbz ccir_match # both max digits long. ldn Reeprom ani 0xF smi 0xF # continues with 0..E ? lbnz 9b ccir_match: ldi 0 str Rram # zero length ldn Rtbl smi LO(ee_ccir_csq) lbnz 1f ghi Rflags ani FLAG_HIGH_CODESQ lbz mainloop # only used during active codesquelch ADJUST(Rram, godeaf) ldi 0 str Rram inc Rram inc Rram ; ASSERT(silencetimer == (godeaf + 2)) ldi 4 str Rram ghi Rflags ani ~FLAG_HIGH_MUTE_ACT phi Rflags lbr update_display_any_mode 1: ldn Rtbl # was it the 'pepa' string ? smi LO(ee_ccir_pepa) bnz 1f glo Rflags ori FLAG_LOW_PEPA_TXT plo Rflags 1: ADJUST(Rram, led0) ghi Rtmp smi 'E' lsz; ldi LED0_REQA - LED0_REQE adi LED0_REQE sex Rram or str Rram ldn Rtbl # get start of setup adi EECCIRLEN plo Reeprom ldn Reeprom # act bits here lskp do_alert_1800: ldi DOFIXED # hardcoded for 1800 detects plo Rtbl # keep here for a while ani DOEXAL bz 8f # no exalarm glo Rflags ori FLAG_LOW_EXAL plo Rflags 8: glo Rtbl ani DOBELL bz 8f # no bell ADJUST(Rvar, blipvolume) lda Rvar ; ASSERT(alertvolume == (blipvolume + 1)) phi Rtmp # save blipvolume ldn Rvar bz 8f # zero alertvolume -> skip tones /* * Make noises. */ dec Rvar str Rvar # blipvolume changed to alertvolume ldi 20 plo Rtmp 2: ldi 32 1: idl smi 1 bnz 1b ldi 32 plo Rbeeps 1: glo Rbeeps bnz 1b b3 1f # key ? stop noise bn1 1f # ptt ? stop noise dec Rtmp glo Rtmp bnz 2b 1: ghi Rtmp str Rvar # restore blipvolume 8: glo Rtbl ani DOFIXED bz 8f ADJUST(Rram, alert_time) ldn Rram dec Rram dec Rram dec Rram ; ASSERT(alerttimer == (alert_time - 3)) str Rram ghi Rflags ani ~FLAG_HIGH_MUTE_ACT # in case mute was on. phi Rflags 8: glo Rtbl ani DOLISTEN bz 8f ADJUST(Rram, silence_time) ldn Rram dec Rram ; ASSERT(silencetimer == (silence_time - 1)) str Rram ghi Rflags ani ~FLAG_HIGH_MUTE_ACT # in case mute was on. phi Rflags 8: get_upd bnz 8b # wait until the string shows up on display. lbr send_display # lit the leds. ccir_no_match: ldi 0 str Rram lbr mainloop check_scanner: glo Rflags ani FLAG_LOW_SCANGO lbnz scanner_go_now glo Rflags ani FLAG_LOW_SCANX lbz scanner_search # not listening nor waiting, thus searching ani FLAG_LOW_SQWAIT lbnz scanner_sqwait # waiting. scanner_listen: /* * Was listening. */ get_in4 ani I4_SQUELCH lbnz 1f /* * Listener lost carrier, to waiting. */ glo Rflags xri FLAG_LOW_LISTEN | FLAG_LOW_SQWAIT plo Rflags ADJUST(Rram, sqwait_time) ldn Rram dec Rram dec Rram ; ASSERT(scantimer == (sqwait_time - 2)) str Rram lbr check_scanner_ret 1: /* * Listener still has carrier * Push current frequency into VIP-list */ ADJUST(Rvar, VIP_list) ADJUST(Rram, synth) sex Rram ldn Rram phi Rtmp # synth pushed to list 1: ldn Rvar # get current in list plo Rtmp # save for insertion down the list ghi Rtmp # get previous str Rvar # replace current in list glo Rtmp # see what was just overwritten phi Rtmp # will be inserted in next round sm bz 1f # leave rest of list intact, if overwrote synth inc Rvar # step down the list glo Rvar smi LO(VIP_listend) bnz 1b # until all over 1: ADJUST(Rram, scantimer) ; ASSERT(scantimer == (listen_time - 1)) lda Rram lbnz check_scanner_ret # timer still running ldn Rram lbz check_scanner_ret # listening not limited. scanner_go_now: /* * Lost patience */ glo Rflags ani ~(FLAG_LOW_SCANX | FLAG_LOW_SCANGO) plo Rflags ADJUST(Rram, steptimer) ldi 0xFF str Rram # longer wait to allow squelch to close. lbr scanner_jog scanner_sqwait: /* * Was waiting */ get_in4 ani I4_SQUELCH lbz 1f /* * Waiter got carrier, to listening. */ glo Rflags xri FLAG_LOW_LISTEN | FLAG_LOW_SQWAIT plo Rflags ADJUST(Rram, listen_time) ldn Rram dec Rram ; ASSERT(scantimer == (listen_time - 1)) str Rram lbr check_scanner_ret 1: /* * Waiter times out ? */ ADJUST(Rram, scantimer) ldn Rram lbnz check_scanner_ret # not yet. glo Rflags ani ~FLAG_LOW_SCANX plo Rflags ADJUST(Rram, step_ticks) lda Rram ; ASSERT(steptimer == (step_ticks + 1)) str Rram scanner_jog: ADJUST(Rram, idletimer) ldi 0 str Rram # force repaint lbr scanner_step scanner_search: /* * Was searching */ ADJUST(Rram, steptimer) ldn Rram lbnz check_scanner_ret # not yet stepping. get_in4 ani I4_SQUELCH bz 1f /* * Now have carrier */ glo Rflags ori FLAG_LOW_LISTEN plo Rflags ADJUST(Rram, listen_time) ldn Rram dec Rram ; ASSERT(scantimer == (listen_time - 1)) str Rram ADJUST(Rram, idletimer) ldi 0 str Rram # force repaint ghi Rscan smi NEXT_SCAN bnz 2f phi Rscan # search mode. stop. 2: lbr check_scanner_ret /* * No carrier. step on to next freq. */ 1: dec Rram lda Rram ; ASSERT(steptimer == (step_ticks + 1)) str Rram scanner_step: ghi Rscan smi MEMORY_SCAN lbz next_memory # returns from check_scanner totally. ADJUST(Rram, synth) ldi HI(scanner_page) phi Rtmp # sclist page ADJUST(Rvar, scan_idx) ldn Rvar # get index plo Rtmp ldn Rtmp # get from list bnz 1f plo Rtmp # at end. reset pointer ... str Rvar # to index 0. ldn Rtmp 1: str Rram glo Rtmp adi 1 str Rvar # increment index. ADJUST(Rvar, rptr_low) lda Rvar bz 1f ldn Rvar bz 1f ghi Rflags ani ~FLAG_HIGH_RPTR_ALL phi Rflags sex Rram ldn Rvar sm bnf 1f dec Rvar ldn Rvar sd bnf 1f ghi Rflags ori FLAG_HIGH_RPTR phi Rflags 1: lbr check_scanner_ret step_channels_up: ADJUST(Rram, digval) ldn Rram lbnz do_channel_step # nonzero +, do full step plo Rtmp glo Rflags xri FLAG_LOW_SYNTH_P0 plo Rflags ani FLAG_LOW_SYNTH_P0 lbz step_one_up # was middle-channel, now full step. lbr 1f # middle-ch ok in flags, do housekeeping step_channels_down: ADJUST(Rram, digval) ldi 0 sex Rram sm # negated lbnz do_channel_step plo Rtmp # assume no P1..8 change glo Rflags xri FLAG_LOW_SYNTH_P0 plo Rflags ani FLAG_LOW_SYNTH_P0 lbz 1f # 487 -> 475, 0 ok in Rtmp.lo dec Rtmp 1: lbr do_micro_step # 500 -> 487, P1..8 decrement step_one_up: ldi 1 br do_channel_step step_one_down: ldi -1 do_channel_step: plo Rtmp glo Rflags shr # Get LSb bnf 1f dec Rflags # Clear LSb glo Rtmp shl bnf 1f # skip if positive step inc Rtmp # - steps from middle-channel, one less to get "25" 1: do_micro_step: ghi Rscan lbz 1f ldi 0 phi Rscan # stop scanning lbr update_display 1: ADJUST(Rram, synth) glo Rtmp sex Rram add str Rram ADJUST(Rram, curmem) ldi NOTMEM str Rram lbr update_display_and_modes /* * Toggle or reset all simplex controls */ extbit1_toggle: ldi O7_SIMPLEX_1 lskp extbit2_toggle: ldi O7_SIMPLEX_2 lskp extbit3_toggle: ldi O7_SIMPLEX_3 lskp extbits_clear: ldi 0 plo Rtmp # remember bit ADJUST(Reeprom, ee_simplexes) ADJUST(Rram, output_7) ADJUST(Rvar, ptlmode) ldn Rvar ani 1 bz 1f # zero ptlmode, do all clear first. glo Rtmp bnz 2f # nonzero bit, skip clear. 1: ldn Rram ori O7_SIMPLEX_1 | O7_SIMPLEX_2 | O7_SIMPLEX_3 str Rram # tvlmode or zerobit. all cleared. 2: glo Rtmp # the bitmask again sex Rram xor # flip the bit in question, if any. str Rram # latch mirror updated shr str Reeprom # eeprom nibble is like the latch, but LSb dropped ADJUST(Rram, led1) ldn Rram ani ~7 ; ASSERT(LED1_AUT == 8) str Rram # Simplex leds cleared ldn Reeprom xri 7 # 0 in latch is active, 1 in leds is lit. ani 7 # 3 LSbits or str Rram lbr update_display nop # ALIGN nop # ALIGN nop # ALIGN nop # ALIGN maybe_restart_scanner: ghi Rscan smi 1 lbz start_scanning_band smi 1 lbz start_scanning_memories smi 1 lbz start_scanning_priorities smi 1 lbz start_scanning_rom smi 1 lbz start_search_scan lbr update_display ptt_down: glo Rflags ani ~FLAG_LOW_EXAL plo Rflags ghi Rflags ani FLAG_HIGH_CODESQ bz 9f sex Rram ADJUST(Rram, ccirtxbuf) ADJUST(Reeprom, ee_ccir_csq) ldi EECCIRLEN plo Rtmp # max length ldi 0xF phi Rtmp # no prev code. str Rram inc Rram # start with silence. 1: lda Reeprom ani 0xF str Rram smi 0xF bz 1f ghi Rtmp # prev code. sm # same code as previous ? bnz 2f ldi CCIR_R str Rram 2: lda Rram phi Rtmp dec Rtmp glo Rtmp bnz 1b 1: ldi 0xFF str Rram # terminator for string. ADJUST(Rram, ccirtxptr) ldi LO(ccirtxbuf) str Rram # set pointer. ldi BEEP0TICK_SMALL # minimal initial delay phi Rbeeps # start ! ghi Rflags ori FLAG_HIGH_MUTE | FLAG_HIGH_MUTE_ACT phi Rflags br 2f 9: ghi Rflags ani ~(FLAG_HIGH_MUTE | FLAG_HIGH_TIMERSQ | FLAG_HIGH_MUTE_ACT) phi Rflags 2: /* * Push current frequency into VIP-list */ ADJUST(Rvar, VIP_list) ADJUST(Rram, synth) sex Rram ghi Rscan bz 1f ldi 0 phi Rscan # stop scanning ldn Rvar str Rram # go back to found channel. lbr update_display_and_modes 1: ldn Rram phi Rtmp # synth pushed to list 1: ldn Rvar # get current in list plo Rtmp # save for insertion down the list ghi Rtmp # get previous str Rvar # replace current in list glo Rtmp # see what was just overwritten phi Rtmp # will be inserted in next round sm bz 1f # leave rest of list intact, if overwrote synth inc Rvar # step down the list glo Rvar smi LO(VIP_listend) bnz 1b # until all over 1: lbr update_display_no_eeprom /*----------------------------------------------------------------- * Display routine used in setup-mode */ setup_display_update: ADJUST(Rram, digval) ldi 0 str Rram inc Rram ; ASSERT(digidx == (digval + 1)) str Rram setup_display_update_keep_idx: ADJUST(Rram, setuprec) # record ptr ldn Rram phi Rtmp # index smi SETUP_COUNT bnf 9f # in range -> stay lsz # one past -> 0 ldi SETUP_COUNT - 1 # go to last. str Rram phi Rtmp # change index 9: ghi Rtmp shl4 # index * 16 plo Rtmp # offset ghi Rtmp shr4 adi HI(setup_table) # base + index / 16 phi Rtmp # page # record: type ramoff eepromoff romoff "MSG" ADJUST(Rram, setuptype) lda Rtmp # type of field for digit insertion elsewhere str Rram plo Rtbl inc Rram ; ASSERT(setupxaddr == (setuptype + 1)) lda Rtmp # address of ram-variable str Rram plo Rvar inc Rram ; ASSERT(setupeaddr == (setuptype + 2)) lda Rtmp # address of eeprom-variable str Rram plo Reeprom lda Rtmp # default value, XXX unused ADJUST(Rram, dpychars) 1: lda Rtmp bz 1f str Rram inc Rram br 1b 1: /* * Initial string, the name, copied. * Determine what to show as value. * Rram pointing to display location. */ ADJUST(Rptr, digidx) # determine character-count to display lda Rptr lbz 9f # nothing entered ? go display current value. ; ASSERT(digbuf == (digidx + 1)) /* * Show what is in the input-buffer, * dont exceed available space. */ plo Rtmp # count index backwards. 1: glo Rram smi LO(dpybufend) lbz send_display lda Rptr # must not cross page and nudge Rram out of page 0 !!! str Rram inc Rram dec Rtmp glo Rtmp lbnz 1b /* * Pad with blanks upto end of 7segments. */ setup_display_finish_blanks: ldi ' ' setup_display_finish: plo Rtmp 1: glo Rram smi LO(dpybufend) lbz send_display glo Rtmp str Rram inc Rram br 1b 9: /*---------------------------------------------- * Input-buffer is empty. * Show the current value of the variable in question. * Rvar pointing to variable. */ glo Rtbl # setuptype smi SETUP_CCIR lbz setup_display_ccir smi SETUP_BF - SETUP_CCIR lbz setup_display_bf glo Rvar # setupxaddr, field has a value ? lbz setup_display_finish_blanks glo Rtbl # setuptype smi SETUP_F lbz setup_display_freq smi SETUP_NIBB - SETUP_F lbz setup_display_nibb /* * 0...255 ranged variable. * We enter here also for boolean variables. * Ok as long as setuptype is used elsewhere. XXX */ setup_display_byte: ldn Rvar setup_display_byte_or_nibble: phi Rtmp # x ldi 0 plo Rtmp # 100 counter 1: ghi Rtmp # x smi 100 bnf 1f phi Rtmp # x >= 100 --> x -= 100 inc Rtmp # ++100 lbr 1b 1: glo Rtmp lsnz; ldi ' ' # zeroblanking, " 12" or "123" str Rram ldi 0 plo Rtmp # 10 counter 1: ghi Rtmp smi 10 lbnf 1f phi Rtmp inc Rtmp lbr 1b 1: lda Rram # ++, stored 100 smi ' ' bnz 1f # 100 was not blank glo Rtmp lsnz; ldi ' ' # replace 0 with ' ' plo Rtmp 1: glo Rtmp # 10 again str Rram inc Rram ghi Rtmp # 1 str Rram # store residue from 100 and 10 loops inc Rram lbr setup_display_finish_blanks setup_display_nibb: ldn Reeprom ani 0x0F lbr setup_display_byte_or_nibble /* * divisor byte @Rvar, shown as a frequency string. */ setup_display_freq: ldn Rvar lbnz div2freq # divisor to display ldi '-' # zero divisor is shown as ------ lbr setup_display_finish /* * CCIR-string @Rvar */ setup_display_bf: ldi 8 lskp setup_display_ccir: ldi EECCIRLEN plo Rtmp # assumed padding length glo Reeprom phi Rtmp # remember start ldi 0 plo Rvar # count length 1: lda Reeprom ani 0xF smi 0xF bz 1f inc Rvar dec Rtmp # not F, one less blank padding glo Rtmp bnz 1b 1: glo Rtmp bz 1f dec Rtmp ldi ' ' str Rram inc Rram br 1b 1: ghi Rtmp plo Reeprom # restart 1: glo Rvar bz 1f dec Rvar lda Reeprom ani 0xF str Rram inc Rram br 1b 1: lbr send_display update_with_ccirhist: ADJUST(Rptr, dpybufend) ADJUST(Rvar, ccirhist_rp) ldn Rvar plo Rtmp 1: dec Rtmp ldi HI(ccir_history) phi Rtmp ldn Rtmp dec Rptr str Rptr glo Rptr smi LO(dpychars) lbnz 1b lbr send_display continue_scanner: glo Rflags ori FLAG_LOW_SCANGO plo Rflags lbr update_display finish_scanner_start: glo Rtmp smi LO(scanner_page) lbz hmm_eh_what ghi Rflags ani ~FLAG_HIGH_RPTR_ALL phi Rflags glo Rflags ani ~(FLAG_LOW_SQWAIT | FLAG_LOW_SYNTH_P0) ori FLAG_LOW_LISTEN | FLAG_LOW_SCANGO plo Rflags ADJUST(Rram, scan_idx) ADJUST(Rvar, steptimer) ldi 0 str Rram str Rvar inc Rvar ; ASSERT(scantimer == (steptimer + 1)) str Rvar ADJUST(Rram, curmem) ldi NOTMEM str Rram ADJUST(Rram, volabits) ldn Rram ori O3_SQUELCH_ENB str Rram inc Rram ; ASSERT(blipvolume == (volabits + 1)) ldn Rram ori O3_SQUELCH_ENB str Rram glo Rtbl phi Rscan ADJUST(Rram, led1) ldn Rram ori LED1_AUT str Rram lbr update_display /*----------------------------------------------------------- * Build up frequency-string from divisor byte. * * Input: * D the divisor * * Continues to send_display * * BASE_FREQ is the base frequency in unpacked BCD. * * divisor 0xFF * "141500" base * "60" ms_chan[0xF] * "5"/"0" depending on (divisor&1) * "37" ls_chan[0xF] * "147875" result to display * * First, copy the base frequency as a string. */ div2freq: dec Rstk str Rstk # save divisor ADJUST(Reeprom, BASE_FREQ) ADJUST(Rram, tmpfreq) ADJUST(Rvar, dpyfreq) lda Reeprom; ani 0xF ; str Rram ; inc Rram lda Reeprom; ani 0xF ; str Rram ; inc Rram lda Reeprom; ani 0xF ; str Rram ; inc Rram lda Reeprom; ani 0xF ; str Rram ; inc Rram lda Reeprom; ani 0xF ; str Rram ; inc Rram ldn Reeprom; ani 0xF ; str Rram /* * Add 00xyz0 resulting from upper nibble of divisor. */ dec Rram # over 10 kc ADJUST(Rptr, junk) ldn Rstk # get divisor shr4 # upper nibble first. str Rptr sex Rptr add add # *= 3 index into ms_chan[] adi LO(ms_chan) + 2 plo Rtbl # over 10 kc of ms_chan[] triple sex Rram ldn Rtbl # 0 of 600 add # add to 0 of 141500 str Rram # store 10 kc digit smi 10 bnf 1f str Rram # correct with % 10 1: # carry set if result >= 10 dec Rram # over 100 kc dec Rtbl ldn Rtbl # 0 of 600 adc # add to 5 of 141500 str Rram # store 100 kc digit smi 10 bnf 1f str Rram 1: dec Rram # over 1 Mc dec Rtbl ldn Rtbl # 6 of 600 adc # add to 2nd 1 of 141500 str Rram # store 1 Mc digit smi 10 bnf 1f str Rram 1: dec Rram # over 10 Mc ldi 0 adc # add to 4 of 141500 str Rram # store 10 Mc digit, cannot carry as 200 Mc is impossible /* * Now, add 000xy0 from lower nibble of divisor. */ inc Rram # over 1 Mc inc Rram # over 100 kc inc Rram # over 10 kc inc Rram # over 1 kc ldn Rstk # divisor ani 3 # divisor & 3 adi LO(kc_chan) plo Rtbl ldn Rtbl str Rram # no effect to other digits dec Rram # over 10 kc ldn Rstk # get divisor ani 0xF # lower nibble. shl # *= 2 index into ls_chan[] adi LO(ls_chan) + 1 plo Rtbl # over 10 kc ldn Rtbl # 7 of 375 adc # add 7 to 1st 0 of 141500 str Rram smi 10 bnf 1f str Rram 1: dec Rram # over 100 kc dec Rtbl ldn Rtbl adc # add 3 to 5 of 141500 str Rram smi 10 bnf 1f str Rram 1: dec Rram # over 1 Mc ldi 0 adc str Rram smi 10 bnf 1f str Rram 1: dec Rram # over 10 Mc ldi 0 adc str Rram dec Rram # over 100 Mc, cannot carry, 200 Mc impossible ADJUST(Rtbl, kc_P0) glo Rflags shr ; ASSERT(FLAG_LOW_SYNTH_P0 == 1) bnf 1f inc Rtbl 1: lda Rram ; lsnz ; ldi ' ' ; str Rvar ; inc Rvar lda Rram ; str Rvar ; inc Rvar lda Rram ; str Rvar ; inc Rvar lda Rram ; str Rvar ; inc Rvar ldn Rtbl ; shr4 ; add ; inc Rram ; str Rvar ; inc Rvar ldn Rtbl ; ani 0xF ; add ; str Rvar inc Rstk # dispose scratch lbr send_display /*----------------------------------------------------------- * Main loop * Execute stuff as requested from keypad or buttons. */ goswitch: glo Rflags ani FLAG_LOW_SETUP lbz 1f LDREG(Rpgm, setup_jump_table) lbr switcher 1: glo Rflags ani FLAG_LOW_CBROWSE lbz 1f LDREG(Rpgm, cbrowse_jump_table) lbr switcher 1: ADJUST(Rvar, digidx) ldn Rvar lbz 1f LDREG(Rpgm, digits_jump_table) lbr switcher 1: LDREG(Rpgm, normal_jump_table) lbr switcher switcher: 1: lda Rpgm bz 1f # no match in table, default action sm # compare with above saved key bz 1f # matches inc Rpgm # over ... inc Rpgm # ... the address. br 1b 1: lda Rpgm plo Rtbl ldn Rpgm plo Rpgm glo Rtbl phi Rpgm sep Rpgm # GO ! send_display: ldi 1 put_upd mainloop: sex Rram ADJUST(Rram, keyoutp) ldn Rram plo Rvar ldn Rvar phi Rtmp # get character and save. smi 0xFF lbz no_events ldi 0xFF str Rvar # mark slot empty inc Rvar glo Rvar ani SIZE(keyqueue) - 1 str Rram do_key: ghi Rtmp smi 10 # key - 10 lbdf do_non_digit # 0..9 digit if carry (No DF) do_digit: /* * Normal digit pressed. * Insert digit into buffer. * Keep also track of the value as decimal byte. */ ADJUST(Rram, idletimer) ldi IDLETICKS str Rram glo Rflags ani ~(FLAG_LOW_PEPA_TXT | FLAG_LOW_CBROWSE) plo Rflags ldi 0 phi Rscan # stop scanning on digit. ADJUST(Rram, digidx) ldn Rram # index smi SIZE(digbuf) lbz 9f # no room ldn Rram # again adi LO(digbuf) # base plo Rvar # buf ptr now complete ldn Rram # index again adi 1 str Rram # ++ for next ghi Rtmp # new digit (maybe with 0xF0 junk) ani 0xF str Rvar # insert digit into digbuf dec Rram ; ASSERT(digval == (digidx - 1)) sex Rram ldn Rram # old digval ... add; bdf 1f # 2 times add; bdf 1f # 3 times add; bdf 1f # 4 times add; bdf 1f # 5 times add; bdf 1f # 6 times add; bdf 1f # 7 times add; bdf 1f # 8 times add; bdf 1f # 9 times add; bdf 1f # and 10, digval *= 10 str Rram ldn Rvar # new digit add; bdf 1f lskp # skip ldi if no carryover 1: ldi 0xFF # overflowed str Rram # digval += key 9: glo Rflags ani FLAG_LOW_SETUP lbz update_display_keep_idx lbr setup_display_update_keep_idx do_non_digit: ADJUST(Rram, key) ghi Rtmp str Rram # save for further inspection sex Rram # Used below. /* * CCIR-digits have 0x40 set */ shl shl lbdf do_ccir_chr ghi Rtmp smi CMD_1800 lbz do_alert_1800 /* * Not a CCIR-digit, dim possibly lit CCIR-leds * and remove "PEPA" indication. */ ADJUST(Rvar, led0) ldn Rvar ani ~(LED0_REQA | LED0_REQE) str Rvar glo Rflags ani ~FLAG_LOW_PEPA_TXT plo Rflags /* * 123AA* for sending group-calls. */ ghi Rtmp smi KEY_A lbnz 1f ADJUST(Rvar, digidx) ldn Rvar smi 2 lbnf 1f ldi 0xA phi Rtmp lbr do_digit # 'A' is a "digit" after 2 real digits. 1: /* * #-list ugliness */ ghi Rtmp smi KEY_HASH lbz 1f ghi Rtmp smi CMD_ACT_H lbz 1f smi 1 ; ASSERT(CMD_ACT_U == (CMD_ACT_H + 1)) lbz 1f ADJUST(Rvar, VIP_idx) ldi 0 str Rvar # not # nor hook/unhook, restart #-list 1: /* * Select table, P temporarily Rtmp ! */ LDREG(Rtmp, goswitch) sep Rtmp nop # ALIGN nop # ALIGN no_events: ADJUST(Rram, led0) bn1 1f # go if PTT pressed ghi Rbeeps bnz 1f # go if signalling. get_in4 ani I4_SQUELCH bnz 1f # go if squelch open. ldn Rram ani LED0_BUSY lbz 3f # BUSY already dim. ldn Rram ani ~LED0_BUSY br 2f 1: ldn Rram ani LED0_BUSY lbnz 3f # BUSY already lit. ldn Rram ori LED0_BUSY 2: str Rram ldi 1 put_upd 3: b1 1f # skip this if no ptt get_in4 ani I4_PROGRAM | I4_OFFICE xri I4_PROGRAM | I4_OFFICE bz 1f ani I4_OFFICE lbz set_lo_tx lbr set_hi_tx # hmm, return to otherplace 1: ghi Rscan lbnz check_scanner ADJUST(Rram, led1) ldn Rram ani ~LED1_AUT str Rram # dim AUT-led if someone stopped scanner. check_scanner_ret: ADJUST(Rram, godeaf) ldn Rram lbz 1f # no flag to go mute again. ldi 0 str Rram # clear flag glo Rflags ani ~FLAG_LOW_EXAL plo Rflags # stop Ext alarm ghi Rflags ani FLAG_HIGH_MUTE | FLAG_HIGH_CODESQ | FLAG_HIGH_TIMERSQ bz 1f ghi Rflags # was muted/codesq, close audio. ori FLAG_HIGH_MUTE_ACT phi Rflags lbr 2f # skip idlecheck and go to repaint 1: ADJUST(Rram, idletimer) ldn Rram lbnz mainloop ldi IDLETICKS # restart idletimer always str Rram ghi Rflags ani ~FLAG_HIGH_RPTR_DIR phi Rflags 2: glo Rflags ani FLAG_LOW_CBROWSE | FLAG_LOW_SETUP lbz update_display_no_eeprom ani FLAG_LOW_CBROWSE lbz setup_display_update lbr update_with_ccirhist start_scan_A_or_continue: ghi Rscan smi NEXT_SCAN lbnz 1f phi Rscan lbr update_display # stop. was searching for next. 1: ghi Rscan lbnz continue_scanner start_scan_A: ldi LO(scan_A) lskp start_scan_B: ldi LO(scan_B) lskp start_given_scan: ldi LO(digval) plo Rram start_scan_at_ram: ghi Rscan # already scanning ? bz 1f ldi 0 # yes, stop. phi Rscan lbr update_display 1: ldn Rram smi 1 lbz start_scanning_band smi 1 lbz start_scanning_memories smi 1 lbz start_scanning_priorities smi 1 lbz start_scanning_rom smi 1 lbz start_search_scan lbr start_scanning_band /*---------------------------------------------------------------- * Calculate divisor from input string * Callable from Rpgm, requires RP init every time. * * Output: result pushed to stack :} * * 145775 6 * 45775 6 * 5775 4 * 775 3 * 77 2, taken as 770 * * 0, 1 digits : no good */ freq2div: dec Rstk # result space sex Rram ADJUST(Rram, tmpfreq + 5) # over 1 kc ldi 0 str Rstk # result sum initialize stxd stxd stxd # xxx000 over last x ADJUST(Reeprom, BASE_FREQ + 7) ldn Reeprom ani 0xF stxd dec Reeprom ldn Reeprom ani 0xF stxd # x45xxx x51xxx ADJUST(Reeprom, BASE_FREQ) ldn Reeprom ani 0xF str Rram # 145000 051000 over 100 Mc ADJUST(Rvar, digidx) lda Rvar ; ASSERT(digbuf == (digidx + 1)) plo Rtmp2 # counter for loop below smi 2 lbnf 8f # less than 2. no good. smi 2 bnf 3f # less than 4. bz 4f # 4 digits smi 2 bnf 5f # less than 6, thus 5 bz 6f lbr 9f # more than 6, no good. 3: inc Rram 4: inc Rram 5: inc Rram 6: 1: lda Rvar str Rram inc Rram dec Rtmp2 glo Rtmp2 bnz 1b /* * Remove base frequency from digitstring. * Rram and Reeprom pointing to 10 kc. */ ADJUST(Reeprom, BASE_FREQ + 4) # 10 kc ADJUST(Rram, tmpfreq + 4) ldn Reeprom ani 0xF sd # 10 kc lbdf 1f adi 10 adi 0 # set "carry" 1: stxd # decrements Rram dec Reeprom ldn Reeprom ani 0xF sdb # 100 kc bdf 1f adi 10 adi 0 1: stxd dec Reeprom ldn Reeprom ani 0xF sdb # 1000 kc bdf 1f adi 10 adi 0 1: stxd dec Reeprom ldn Reeprom ani 0xF sdb # 10000 kc bdf 1f br 8f # underflow 1: str Rram sex Rstk # result, already zeroed. inc Rram # to 1000 kc lda Rram # 1000 kc adi LO(kc_1000) # XXX config plo Rtbl ldn Rtbl add bdf 9f str Rstk lda Rram # 100 kc adi LO(kc_100) # XXX config plo Rtbl ldn Rtbl add bdf 9f str Rstk lda Rram # 10 kc adi LO(kc_10) # XXX config plo Rtbl ldn Rtbl shr # LSb contains synth bit 0, the lowest add bdf 9f 1: str Rstk # finished result. sex Rram sep Rpgm # "return" 9: ldi 0xFF # upper limit for overflows br 1b 8: ldi 0 # lower for underflows br 1b /*----------------------------------------------------------- */ action_H: ldi LO(act_H) lskp action_U: ldi LO(act_U) plo Rram ldn Rram lbz mainloop # 0 smi 6 lbz VIP_recall # 6 ADJUST(Rvar, VIP_idx) ldi 0 str Rvar # not vip-fcn, restart #-list ldn Rram smi 5 lbnf start_scan_at_ram # 1...4 if carry lbz start_scan_A_or_continue # 5 smi 2 lbz to_next_memory # 7 ldi 0 phi Rscan ldn Rram smi 100 lbr memory_recall_D # 100..., memories 0... start_scanning_rom: ldi CUSTOM_SCAN plo Rtbl ADJUST(Rram, CUSTOM_SCAN_LIST) ldi 8 br 9f start_scanning_priorities: ldi PRIONLY_SCAN plo Rtbl ADJUST(Rram, pri_1) ldi 4 9: plo Reeprom ldi 0 phi Rscan LDREG(Rtmp, scanner_page) sex Rram 2: ldn Rram bz 1f ADJUST(Rptr, rejects) lda Rptr ; sm ; bz 1f lda Rptr ; sm ; bz 1f lda Rptr ; sm ; bz 1f lda Rptr ; sm ; bz 1f ldn Rram str Rtmp inc Rtmp 1: inc Rram dec Reeprom glo Reeprom bnz 2b ldi 0 str Rtmp # end list with 0 lbr finish_scanner_start start_search_scan: ldi NEXT_SCAN plo Rtbl br 2f start_scanning_band: ldi BAND_SCAN plo Rtbl 2: ldi 0 phi Rscan ADJUST(Rvar, scan_low) LDREG(Rtmp, scanner_page) ADJUST(Rram, scan_tmp) sex Rram lda Rvar ; ASSERT(scan_high == (scan_low + 1)) str Rram 2: ADJUST(Rptr, rejects) lda Rptr ; sm ; bz 9f lda Rptr ; sm ; bz 9f lda Rptr ; sm ; bz 9f lda Rptr ; sm ; bz 9f lda Rptr ; sm ; bz 9f lda Rptr ; sm ; bz 9f lda Rptr ; sm ; 9: lbz 1f lda Rptr ; sm ; bz 1f lda Rptr ; sm ; bz 1f lda Rptr ; sm ; bz 1f ldn Rram bz 1f str Rtmp inc Rtmp 1: ldn Rvar sm # at upper limit of bandscan ? bz 1f ADJUST(Rptr, scan_chstep) ldn Rptr lsnz ; adi 1 add str Rram # next frequency = prev freq + scstep lbnz 2b 1: ldi 0 str Rtmp # end list with 0 lbr finish_scanner_start code_mute_start: ADJUST(Rvar, digval) ldn Rvar smi 1 lbz toggle_mute # 1N smi 1 lbz toggle_codesq # 2N smi 3 lbz toggle_timersq # 5N lbr toggle_squelch # 0N toggle_codesq: ghi Rflags xri FLAG_HIGH_CODESQ phi Rflags ani FLAG_HIGH_CODESQ bnz 1f ghi Rflags ani ~(FLAG_HIGH_MUTE | FLAG_HIGH_MUTE_ACT | FLAG_HIGH_TIMERSQ) br 2f 1: ghi Rflags ori FLAG_HIGH_MUTE | FLAG_HIGH_MUTE_ACT ani ~(FLAG_HIGH_TIMERSQ) 2: phi Rflags lbr update_display prev_setup_group: ldi -1 lskp next_setup_group: ldi 1 plo Rtbl ADJUST(Rram, dpychars) # pointing to 1st character of "title" 4: ADJUST(Rptr, setuprec) # record ptr glo Rtbl sex Rptr add # *Rptr + Rtbl, +- 1 sex Rram str Rptr phi Rtmp # index smi SETUP_COUNT bz 1f # one past -> 0 bnf 9f # in range -> stay ldi SETUP_COUNT - 1 # go to last. 1: str Rptr phi Rtmp # change index 9: ghi Rtmp # record: type ramoff eepromoff romoff "MSG" shl4 # index * 16 adi 4 # skip directly to title plo Rtmp # offset ghi Rtmp shr4 adi HI(setup_table) # base + index / 16 phi Rtmp # page ldn Rtmp sex Rram sm # compare 1st char of titles lbz 4b # keep looking for differing lbr setup_display_update start_scanning_memories: ldi 0 phi Rscan ghi Rflags ani ~(FLAG_HIGH_RPTR|FLAG_HIGH_RPTR_REV|FLAG_HIGH_RPTR_DIR) phi Rflags LDREG(Rtmp, scanner_page) ADJUST(Rram, scan_tmp) ADJUST(Rvar, scan_idx) ldi 0 str Rvar plo Rvar # memory number counter, 0..max 2: glo Rvar # memory number shr shr # get nibble number adi LO(memory_noscanbits) plo Reeprom # positioned over the byte containing noscan bit glo Rvar ani 3 # get bit-mask adi LO(bitmasks) plo Rtbl ldn Rtbl # have now the bitmask for memory. sex Reeprom and # mask out the bit sex Rram bnz 1f # nonzero - not scannable glo Rvar shl adi LO(memory_divisors) plo Reeprom lda Reeprom shl4 str Rram ldn Reeprom ani 0xF or str Rram # divisor complete bz 1f ADJUST(Rptr, rejects) lda Rptr ; sm ; bz 1f lda Rptr ; sm ; bz 1f lda Rptr ; sm ; bz 1f lda Rptr ; sm ; bz 1f glo Rvar # memory number again str Rtmp inc Rtmp 1: inc Rvar glo Rvar smi MEMORY_CNT bnf 2b ldi NOTMEM str Rtmp # end with impossible memory number ldi MEMORY_SCAN plo Rtbl lbr finish_scanner_start /* * Check for and queue up detected CCIR codes. */ check_ccirs: /* * Not when xmitting */ ADJUST(Rptr, output_3) ldn Rptr ani O3_TXON lbnz ret_check_ccirs sex Rram /* * Count length of 1800Hz */ get_in4 ani I4_DETECT_1800 lbnz 1f glo Rscan # receiving 1800 Hz lbnz 9f # count only each 256 ms ADJUST(Rvar, length1800) ldn Rvar adi 1 # increment tone length lbz 9f # dont overflow str Rvar lbr 9f 1: # end of 1800 Hz, see how long it was. ADJUST(Rram, length1800) ldn Rram lbz 9f # very short. plo Rvar # remember for a while ldi 0 str Rram # zero counter for next. dec Rram ; ASSERT(sec1800 == (length1800 - 1)) ldn Rram lbz 9f # minimum not configured glo Rvar # get length of this tone sm # this - minimum lbnf 9f # go if carry, shorter tone ADJUST(Rram, keyinp) ldn Rram # get insertion index plo Rvar ldn Rvar smi 0xFF lbnz 9f # no room ldi CMD_1800 # event str Rvar # keyqueue[keyinx] = code inc Rvar glo Rvar ani SIZE(keyqueue) - 1 str Rram 9: /* * Now do CCIRs. */ ADJUST(Rvar, output_5) ldn Rvar ani O5_ACK_CCIR_ARP # acking ? bz 1f # stop acking and then continue to check ev. ldn Rvar ani ~O5_ACK_CCIR_ARP # stop acking. str Rvar lbr 9f 1: get_in4 # Input 4 shl lbnf 9f ; ASSERT(I4_DETECT_ARP == 0x80) ldn Rvar ori O5_ACK_CCIR_ARP str Rvar # set acknowledge for this character. /* * New code from ARP detector. */ ADJUST(Rvar, keyinp) ldn Rvar # get insertion index plo Rram ldn Rram smi 0xFF lbnz 9f inp 6 shr4 ; ASSERT(I6_CCIR_ARP == 0xF0) ori CHR_CCIR_A # add source-indicator. str Rram # keyqueue[keyinx] = code inc Rram glo Rram ani SIZE(keyqueue) - 1 str Rvar 9: ADJUST(Rvar, output_5) ldn Rvar ani O5_ACK_CCIR_EV # acking ? bz 1f ldn Rvar # stop acking and then leave. ani ~O5_ACK_CCIR_EV # stop acking. str Rvar lbr 9f 1: get_in4 # Input 4 shl shl lbnf 9f ; ASSERT(I4_DETECT_EV == 0x40) ldn Rvar ori O5_ACK_CCIR_EV str Rvar # set acknowledge for this character. /* * New code from EV detector. */ ADJUST(Rvar, keyinp) ldn Rvar # get insertion point plo Rram ldn Rram smi 0xFF # space ? bnz 9f inp 6 ani 0x0F ; ASSERT(I6_CCIR_EV == 0x0F) ori CHR_CCIR_E # add source-indicator. str Rram # keyqueue[keyinx] = code inc Rram glo Rram ani SIZE(keyqueue) - 1 str Rvar 9: lbr ret_check_ccirs /*----------------------------------------------------------- * LOCK/SETUP/UP/DOWN button stuff. */ do_updown: ADJUST(Rvar, btnmask) glo Rtmp str Rvar # which was pressed... dec Rvar ; ASSERT(btntime == (btnmask - 1)) ldi 0 str Rvar # count moments button kept down. 9: ADJUST(Rvar, btnticker) ldi 20 # number of 32 ms periods giving 1 moment. str Rvar ldi BLIPTICKS plo Rbeeps # blip. 1: ADJUST(Rvar, btnpc) ldi LO(go_button_is_down) str Rvar lbr ret_check_buttons button_is_down: get_in4 # current status ani I4_OFFICE | I4_PROGRAM lbz btn_both # both down smi I4_OFFICE | I4_PROGRAM bz 9f # both up. ADJUST(Rram, btnticker) ldn Rram smi 1 str Rram lbnz 1b # not yet 1 moment down. inc Rram ; ASSERT(btntime == (btnticker + 1)) ldn Rram adi 1 # another moment down. enqueue command. bz 1f str Rram 1: ADJUST(Rram, keyinp) ldn Rram # get insertion point plo Rptr ldn Rptr smi 0xFF bnz 8f # not empty slot. get_in4 ani I4_OFFICE lsz; ldi CMD_DOWN - CMD_UP adi CMD_UP # the code. str Rptr # keyqueue[keyinx] = code inc Rptr glo Rptr ani SIZE(keyqueue) - 1 str Rram 8: lbr 9b # keep waiting 9: /* * Button was released. */ ADJUST(Rvar, btntime) # a short press ? lda Rvar ; ASSERT(btnmask == (btntime + 1)) lbnz btn_idle ldn Rvar ani I4_OFFICE lsz; ldi CMD_UP - CMD_DOWN adi CMD_DOWN lbr btnproc_enqueue btn_both: /* * Both buttons down. */ ldi BLEEPTICKS plo Rbeeps # blip. 1: ADJUST(Rvar, btnpc) ldi LO(go_buttons_are_down) str Rvar lbr ret_check_buttons buttons_are_down: get_in4 xri I4_PROGRAM | I4_OFFICE ani I4_PROGRAM | I4_OFFICE lbnz 1b # one or another still down. ADJUST(Rvar, btnmask) ldn Rvar # which was initial button down. ani I4_OFFICE lsz; ldi CMD_SCAN_B - CMD_SCAN_A adi CMD_SCAN_A lbr btnproc_enqueue btnproc_enqueue: plo Rtmp ADJUST(Rram, keyinp) ldn Rram # get insertion point plo Rptr ldn Rptr smi 0xFF bnz 1f # not empty slot. glo Rtmp str Rptr # keyqueue[keyinx] = code inc Rptr glo Rptr ani SIZE(keyqueue) - 1 str Rram 1: btn_idle: ADJUST(Rram, btnpc) ldi 0 str Rram lbr ret_check_buttons ret_check_ccirs: check_buttons: ADJUST(Rvar, idletimer) ldn Rvar bz 1f smi 1 str Rvar 1: ADJUST(Rram, prev_4) ldn Rram plo Rtmp # old bits get_in4 str Rram # copy current bits for next old ADJUST(Rvar, btnpc) ldn Rvar bz 1f # also catches cross-page with RP ! plo Rint # jump ! go_button_is_down: lbr button_is_down go_buttons_are_down: lbr buttons_are_down 1: /* * PTT down and Hook pressed ? * send '8' for 32 ms and emit sidetone too. */ ADJUST(Rvar, pttdown) ldn Rvar bn1 1f lbr 2f 1: lbnz 1f # was down already. ldi 1 str Rvar ldi CMD_PTT lbr btnproc_enqueue 1: get_in4 ani I4_HOOK lbz btn_idle ADJUST(Rptr, ccirtxptr) ldi LO(ccircwbuf) str Rptr ldi 32 plo Rbeeps phi Rbeeps lbr ret_check_buttons 2: ldi 0 str Rvar # not PTT pressed. glo Rtmp # prev sex Rram # curr xor ani I4_HOOK | I4_LOCK | I4_OFFICE | I4_PROGRAM | I4_SQUELCH lbz ret_check_buttons # no changes plo Rtmp # remember changed ones shr lbdf do_hook ; ASSERT(I4_HOOK == 0x01) shr shr bdf do_lock ; ASSERT(I4_LOCK == 0x04) glo Rtmp ani I4_OFFICE | I4_PROGRAM lbnz do_updown /* * squelch has opened or closed. */ ldn Rram ani I4_SQUELCH lbz btn_idle # squelch closed. ghi Rflags ani FLAG_HIGH_TIMERSQ lbz btn_idle # no timer-squelch active ldi CMD_1800 # squelch opened during timer-squelch. lbr btnproc_enqueue do_lock: get_in4 ani I4_LOCK lbnz btn_idle # ignore release ldi BLIPTICKS plo Rbeeps # blip. ldi CMD_SETUP lbr btnproc_enqueue # and leave. do_hook: get_in4 ani I4_HOOK lsz; ldi CMD_ACT_H - CMD_ACT_U adi CMD_ACT_U lbr btnproc_enqueue update_display_any_mode: glo Rflags ani FLAG_LOW_CBROWSE | FLAG_LOW_SETUP lbz update_display_keep_idx ani FLAG_LOW_CBROWSE lbz setup_display_update_keep_idx lbr update_with_ccirhist #ifndef EEPROM /* * Testing. * Dump 8kB eprom to the "serial port". */ #ifdef WITHSERSEND .align 8 sersend_test: LDREG(Rtmp, EEPROMSTART - 1) 9: inc Rtmp ghi Rtmp smi HI(EEPROMEND) lbz update_display # outta here sex Rram glo Rtmp bnz 2f ADJUST(Rram, dpybufend - 1) ghi Rtmp ani 0xF stxd ghi Rtmp shr4 stxd ldi ' ' stxd # " 2F" ldi 1 put_upd 1: get_upd bnz 1b 2: ADJUST(Rram, junk) ldn Rtmp plo Rvar ldi 1 + 8 # start plus 8 databits plo Rptr ldi 0 plo Reeprom # parity counter /* * Disable interrupts for timing. */ sex Rpgm dis .byte (Rram << 4) | Rpgm # X,P for ret-instruction /* * 1200 bd one bit takes 233 cycles * 2.240 MHz clock * 1/280000 s per cycle * 233.3 cycles per bit */ req # 2 startbit br 2f # 4 go to delay for start 3: glo Rvar # 2 shrc # 4 plo Rvar # 6 save rest bdf 1f # 8 ==== 8 cycles additional to prev bit req # 10 br 2f # 12 branches same time 1: seq # 10 inc Reeprom # 12 count onebits 2: ldi 26 # 14 plo Rtbl # 16 1: inp 4 # 2 dec Rtbl # 4 glo Rtbl # 6 bnz 1b # 8 ==== 8 * 26 = 208 nop # 19 dec Rptr # 21 glo Rptr # 23 bnz 3b # 25 ==== # ++++++++ 233 cycles glo Reeprom # 2 shr # 4 look parity bnf 1f # 6 even already seq # 8 last bit got the required few cycles br 2f # 1: req br 2f # 2 2: ldi 28 # 4 plo Rtbl # 6 nop # 9 1: inp 4 # 2 dec Rtbl # 4 glo Rtbl # 6 bnz 1b # 8 === # +++++ 9 + 28 * 8 == 233 seq # 2 stop bit ldi 45 # 4 generous stopbit plo Rptr # 6 nop # 9 1: inp 4 # 2 dec Rptr # 4 glo Rptr # 6 bnz 1b # 8 ==== 8 * n /* * Enable interrupts between characters. */ sex Rpgm ret .byte (Rram << 4) | Rpgm # X,P for ret-instruction lbr 9b # next byte #endif /* WITHSERSEND */ /* ALIGN_PAGE * Receive a new program into eeprom. */ serrecv_test: sex Rram ADJUST(Rram, dpybufend - 1) ldi 0xd stxd ldi 0xA stxd ldi 'O' stxd ldi 'L' stxd ldi ' ' stxd stxd # " LOAd" ADJUST(Rram, cksum) ldi 1 put_upd 1: get_upd lbnz 1b # wait until visible. get 0 to D. str Rram # cksum zeroed inc Rram ; ASSERT(junk == (cksum + 1)) /* * Disable interrupts for timing. */ sex Rpgm dis .byte (Rram << 4) | Rpgm # X,P for ret-instruction /* * Unlock EEPROM */ LDREG(Rtmp, EEPROMSTART + 0x1555); LDREG(Rscan, EEPROMSTART + 0x0AAA); ldi 0xAA; str Rtmp ldi 0x55; str Rscan ldi 0x80; str Rtmp ldi 0xAA; str Rtmp ldi 0x55; str Rscan ldi 0x20; str Rtmp LDREG(Rtmp, EEPROMSTART) 1: bn2 9f # 2 startbit coming inp 4 br 1b # wait. 1st startbit waited forever. serrecv_wait: ldi 0 plo Rscan phi Rscan # timeout for wait 1: bn2 9f # 2 startbit coming inp 4 dec Rscan glo Rscan bnz 1b ghi Rscan bnz 1b lbr serrecv_out # timed out waiting. 9: /* * 1200 bd one bit takes 233.33 cycles * 2.240 MHz clock * 1/280000 s per cycle * 233.33 cycles per bit * * First wait in the middle of startbit */ ldi 0x80 # 4 plo Rvar # 6 DF after 8 databits ldi 0 # 8 plo Rtbl # 10 onebit counter ldi 10 # 12 The loop-n plo Rptr # 14 nop # 17 ++++ 1: inp 4 # 2 inp 4 # 4 dec Rptr # 6 glo Rptr # 8 not yet half of startbit ? bnz 1b # 10 ++++ 17 + n * 10 == 233/2 == 117 b2 serrecv_wait # false start /* * At half of startbit. * Do full bittimes */ 8: ldi 26 # 2 plo Rptr # 4 1: inp 4 # 2 dec Rptr # 4 glo Rptr # 6 bnz 1b # 8 +++ n * 8 inp 4 # 2 inp 4 # 4 inp 4 # 6 ++++ 6 glo Rvar # 6 shr # 8 b2 1f # 10 ori 0 # 12 for timing br 2f # 14 1: ori 0x80 # count onebits. inc Rtbl # branches timed same 2: plo Rvar # 16 save bnf 8b # 18 ==== not yet 8 bits # ++++ 18 + 7 + n * 8 == 233 /* * See paritybit, following is no longer exact with timing */ ldi 28 # 2 plo Rptr # 4 nop # 7 1: inp 4 # 2 dec Rptr # 4 glo Rptr # 6 lbnz 1b # 8 +++ n * 8 < OH3NWQ bn2 1f # 9 ++++ 9 + 28 * 8 == 233 inc Rtbl 1: glo Rtbl # 2 shr # 4 get parity bit lbdf serrecv_out # 7 /* * See stopbit. */ ldi 28 # 9 plo Rptr # 11 1: inp 4 # 2 dec Rptr # 4 glo Rptr # 6 bnz 1b # 8 +++ n * 8 b2 1f # ++++ 11 + 28 * 8 == 235 lbr serrecv_out # framing error or end of load 1: dec Rram ; ASSERT(cksum == (junk - 1)) glo Rvar add str Rram # cksum updated. inc Rram ; ASSERT(junk == (cksum + 1)) glo Rvar # last received byte. str Rtmp # store to eeprom inc Rtmp # to next byte lbr serrecv_wait nop # ALIGN nop # ALIGN serrecv_out: /* * This also waits last byte to sunk. */ ADJUST(Rptr, dpybufend - 1) ADJUST(Rvar, cksum) sex Rptr glo Rtmp ani 0xF stxd glo Rtmp shr4 stxd ghi Rtmp ani 0xF stxd ghi Rtmp shr4 stxd ldi ' ' stxd ldn Rvar ani 0xF stxd ldn Rvar shr4 stxd ldi ' ' stxd ldi 0 str Rvar # restart checksum 1: sex Rram inp 4 glo Rtmp # smi LO(EEPROMSTART) unnecessary bnz 2f ghi Rtmp smi HI(EEPROMSTART) bnz 2f lbr 1f 2: dec Rtmp ldn Rtmp sex Rvar add str Rvar lbr 1b 1: sex Rptr ldn Rvar ani 0xF stxd ldn Rvar shr4 stxd ldi ' ' stxd sex Rram #if 0 /* * Lock EEPROM, fix fouled bytes immediately. */ LDREG(Rtmp, EEPROMSTART + 0x1555); ldn Rtmp; plo Rptr; LDREG(Rscan, EEPROMSTART + 0x0AAA); ldn Rscan; plo Rvar; ldi 0xAA; str Rtmp ldi 0x55; str Rscan ldi 0xA0; str Rtmp glo Rptr # fix 1 str Rtmp shl bdf 1f # stored 1xxxyyyy ? 2: ldn Rpgm inp 4 ldn Rtmp shl bdf 2b # wait until it sticks br 2f 1: ldn Rpgm inp 4 ldn Rtmp shl bnf 1b 2: ldi 0xAA; str Rtmp ldi 0x55; str Rscan ldi 0xA0; str Rtmp glo Rvar # fix 2 str Rscan shl bdf 1f # stored 1xxxyyyy ? 2: ldn Rpgm inp 4 ldn Rscan shl bdf 2b # wait until it sticks br 2f 1: ldn Rpgm inp 4 ldn Rscan shl bnf 1b 2: #endif ldi 0 plo Rscan phi Rscan # was used as counter/pointer /* * Enable interrupts */ sex Rpgm ret .byte (Rram << 4) | Rpgm # X,P for ret-instruction ldi 1 put_upd ldi 4 * 5 # diddling here for a while plo Rtmp 2: ldi BLIPTICKS plo Rbeeps ldi 0 1: idl smi 1 bnz 1b dec Rtmp glo Rtmp bnz 2b # couple of seconds to wait lbr mainloop ALIGN_PAGE promstart: bn1 1f # PTT on ? dont go to eeprom then LDREG(Rtmp, EEPROMSTART) lda Rtmp smi 'm' bnz 1f lda Rtmp smi 'o' bnz 1f lda Rtmp smi 'p' bnz 1f lda Rtmp smi 'p' lda Rtmp smi 'e' bnz 1f lda Rtmp bnz 1f # "moppe\0" lda Rtmp # end hi phi Rptr lda Rtmp # end lo plo Rtmp ghi Rptr phi Rtmp /* * X 0, ROM write no harm. */ ldi 0 plo Rtbl 2: sex 0 inp 4 sex Rtmp dec Rtmp glo Rtbl add plo Rtbl glo Rtmp # smi LO(EEPROMSTART) unnecessary bnz 2b ghi Rtmp smi HI(EEPROMSTART) bnz 2b glo Rtbl lbz EEPROMSTART + 16 # if cksum ok. 1: lbr start16 #endif /* not EEPROM */ modepairs: .byte C_o, C_o .byte 'N', 'N' .byte 'C', C_o .byte 'C', 'S' .byte C_t, C_o .byte C_t, 'S' .byte ' ', ' ' to_prev_memory: ADJUST(Rram, curmem) ldn Rram # 0 -> 39, NOTMEM -> 0, 39 -> 40 ani MEMORY_MASK smi 1 smi MEMORY_CNT lsnf; ldi - MEMORY_CNT adi MEMORY_CNT lbr memory_recall_D ALIGN_PAGE setup_table: SETUP_banner = 0x10 SETUP_NIBB = 1 SETUP_S = 2 SETUP_T = 2 SETUP_F = 6 SETUP_CCIR = 7 SETUP_BF = 8 /* * Each record need to be exactly 16 bytes long * Type RAM_address EEPROM_address clear_value prompt_string */ #define X(x,a,e,dflt) ASSERT((. & 15) == 0); .byte x, LO(a), LO(e), dflt, X(SETUP_banner,0,0,0) 'S','E',C_t,'U',C_P,' ',0,0,0,0,0,0 X(SETUP_F,scan_low,ee_scan_low,0) 'S','C',' ','L',C_o,' ',' ',' ',0,0,0,0 X(SETUP_F,scan_high,ee_scan_high,0) 'S','C',' ','H','1',' ',' ',' ',0,0,0,0 X(SETUP_F,pri_1,ee_pri_1,0) 'P',C_r,'1',' ',1,' ',' ',' ',0,0,0,0 X(SETUP_F,pri_2,ee_pri_2,0) 'P',C_r,'1',' ',2,' ',' ',' ',0,0,0,0 X(SETUP_F,pri_3,ee_pri_3,0) 'P',C_r,'1',' ',3,' ',' ',' ',0,0,0,0 X(SETUP_F,pri_4,ee_pri_4,0) 'P',C_r,'1',' ',4,' ',' ',' ',0,0,0,0 X(SETUP_T,step_ticks,ee_step_ticks,50) 'S','C',' ',C_r,'A',C_t,'E',' ',' ',' ',' ',0 X(SETUP_S,sqwait_time,ee_sqwait_time,3) 'S','C',' ',0xd,'E','L','A',C_y,' ',' ',' ',0 X(SETUP_S,listen_time,ee_listen_time,60) 'S','C',' ','L',1,'S',C_t,'E',C_n,' ',' ',0 X(SETUP_NIBB,scan_A,ee_scan_A,1) 'S','C',' ',C_t,C_y,'P','E',' ',0xA,' ',' ',0 X(SETUP_NIBB,scan_B,ee_scan_B,2) 'S','C',' ',C_t,C_y,'P','E',' ',0xB,' ',' ',0 X(SETUP_T,act_H,ee_act_H,0) 'A','C',C_t,' ','H',' ',' ',' ',' ',' ',' ',0 X(SETUP_T,act_U,ee_act_U,0) 'A','C',C_t,' ','U',' ',' ',' ',' ',' ',' ',0 X(SETUP_F,reject_1,ee_reject_1,0) C_r,'E','J','E','C',C_t,1,' ',0,0,0,0 X(SETUP_F,reject_2,ee_reject_2,0) C_r,'E','J','E','C',C_t,2,' ',0,0,0,0 X(SETUP_F,reject_3,ee_reject_3,0) C_r,'E','J','E','C',C_t,3,' ',0,0,0,0 X(SETUP_F,reject_4,ee_reject_4,0) C_r,'E','J','E','C',C_t,4,' ',0,0,0,0 X(SETUP_F,reject_5,ee_reject_5,0) C_r,'E','J','E','C',C_t,5,' ',0,0,0,0 X(SETUP_F,reject_6,ee_reject_6,0) C_r,'E','J','E','C',C_t,6,' ',0,0,0,0 X(SETUP_CCIR,0,ee_ccir_e1,0xF) 'C','C',1,C_r, 1 ,' ',' ',0,0,0,0,0 X(SETUP_NIBB,junk,ee_ccir_e1+EECCIRLEN,0) 'C','C',1,C_r,1,' ','A','C',C_t,' ',' ',0 X(SETUP_CCIR,0,ee_ccir_e2,0xF) 'C','C',1,C_r, 2 ,' ',' ',0,0,0,0,0 X(SETUP_NIBB,junk,ee_ccir_e2+EECCIRLEN,0) 'C','C',1,C_r,2,' ','A','C',C_t,' ',' ',0 X(SETUP_CCIR,0,ee_ccir_e3,0xF) 'C','C',1,C_r, 3 ,' ',' ',0,0,0,0,0 X(SETUP_NIBB,junk,ee_ccir_e3+EECCIRLEN,0) 'C','C',1,C_r,3,' ','A','C',C_t,' ',' ',0 X(SETUP_CCIR,0,ee_ccir_a1,0xF) 'C','C',1,C_r,'A',' ',' ',0,0,0,0,0 X(SETUP_NIBB,junk,ee_ccir_a1+EECCIRLEN,0) 'C','C',1,C_r,'A',' ','A','C',C_t,' ',' ',0 X(SETUP_CCIR,0,ee_ccir_a2,0xF) 'C','C',1,C_r,0xb,' ',' ',0,0,0,0,0 X(SETUP_NIBB,junk,ee_ccir_a2+EECCIRLEN,0) 'C','C',1,C_r,0xb,' ','A','C',C_t,' ',' ',0 X(SETUP_CCIR,0,ee_ccir_a3,0xF) 'C','C',1,C_r,'C',' ',' ',0,0,0,0,0 X(SETUP_NIBB,junk,ee_ccir_a3+EECCIRLEN,0) 'C','C',1,C_r,'C',' ','A','C',C_t,' ',' ',0 X(SETUP_CCIR,0,ee_ccir_pepa,0xF) 'C','C',1,C_r,'P',' ',' ',0,0,0,0,0 X(SETUP_NIBB,junk,ee_ccir_pepa+EECCIRLEN,0) 'C','C',1,C_r,'P',' ','A','C',C_t,' ',' ',0 #if 0 X(SETUP_CCIR,0,ee_ccir_yyy,0xF) 'C','C',1,C_r,C_r,' ',' ',0,0,0,0,0 X(SETUP_NIBB,junk,ee_ccir_yyy+EECCIRLEN,0) 'C','C',1,C_r,C_r,' ','A','C',C_t,' ',' ',0 #endif X(SETUP_CCIR,0,ee_ccir_tx_0,0xF) C_t,'C','C',1,C_r,'O',' ',0,0,0,0,0 X(SETUP_CCIR,0,ee_ccir_csq,0xF) 'C','S','C','C',1,C_r,' ',0,0,0,0,0 X(SETUP_S,alert_time,ee_alert_time,0) 'A','L','E',C_r,C_t,' ',0xd,'U',C_r,' ',' ',0 X(SETUP_NIBB,silence_time,ee_silence_time,0) 'S',1,'L','E',C_t,' ',0xd,'U',C_r,' ',' ',0 X(SETUP_NIBB,sec1800,ee_sec1800,0) 1,8,'O','O',' ',0xd,'E',C_t,'E','C',C_t,0 X(SETUP_NIBB,blipvolume,ee_blipvolume,1) 0xb,'E','L','L',' ',' ',' ',' ',' ',' ',' ',0 X(SETUP_NIBB,alertvolume,ee_alertvolume,7) 'A','L','E',C_r,C_t,' ',0xb,'E','L','L',' ',0 X(SETUP_F,rptr_low,ee_rptr_low,0) C_r,'P',C_t,C_r,' ','L',C_o,' ',0,0,0,0 X(SETUP_F,rptr_high,ee_rptr_high,0) C_r,'P',C_t,C_r,' ','H','1',' ',0,0,0,0 X(SETUP_NIBB,ptlmode,ee_ptlmode,0) 'P',C_t,'L',' ','S',1,2,3,' ',' ',' ',0 X(SETUP_F,scan_4_1,ee_scan_4_1,0) 'S','C','4',' ',1,' ',' ',' ',0,0,0,0 X(SETUP_F,scan_4_2,ee_scan_4_2,0) 'S','C','4',' ',2,' ',' ',' ',0,0,0,0 X(SETUP_F,scan_4_3,ee_scan_4_3,0) 'S','C','4',' ',3,' ',' ',' ',0,0,0,0 X(SETUP_F,scan_4_4,ee_scan_4_4,0) 'S','C','4',' ',4,' ',' ',' ',0,0,0,0 X(SETUP_F,scan_4_5,ee_scan_4_5,0) 'S','C','4',' ',5,' ',' ',' ',0,0,0,0 X(SETUP_F,scan_4_6,ee_scan_4_6,0) 'S','C','4',' ',6,' ',' ',' ',0,0,0,0 X(SETUP_F,scan_4_7,ee_scan_4_7,0) 'S','C','4',' ',7,' ',' ',' ',0,0,0,0 X(SETUP_F,scan_4_8,ee_scan_4_8,0) 'S','C','4',' ',8,' ',' ',' ',0,0,0,0 X(SETUP_BF,0,BASE_FREQ,0) 0xb,'A','S','E','F',' ',0,0,0,0,0,0 X(SETUP_T,trx_diff,ee_trx_diff,0) C_t,C_r,' ',0xd,'1','F','F',' ',' ',' ',' ',0 X(SETUP_F,trlo,ee_trlo,0) C_t,C_r,' ','L',C_o,' ',' ',' ',0,0,0,0 X(SETUP_F,trhi,ee_trhi,0) C_t,C_r,' ','H','1',' ',' ',' ',0,0,0,0 X(SETUP_T,rptr_diff,ee_rptr_diff,24) C_r,'P',C_t,C_r,' ',0xd,'1','F','F',' ','-',0 #if 0 X(SETUP_s2,0,DEF_MHZ,0) 0xd,'E','F',' ',1,'O','O','O','O',' ',' ',0 X(SETUP_T,chan_step,0,25) 'C','H',' ','S',C_t,'E','P',' ',' ',' ',' ',0 X(SETUP_S,prichk_time,ee_prichk_time,0) 'P',C_r,'1',' ',C_r,'A',C_t,'E',' ',' ',' ',0 #endif X(SETUP_NIBB,scan_chstep,ee_scan_chstep,0) 'S','C',' ','C','H','S',C_t,'E','P',' ',' ',0 X(SETUP_T,synth,0,0) 0xd,'1','U','1','S',C_o,C_r,' ',' ',' ',' ',0 #undef X ASSERT((. & 0xF) == 0) SETUP_COUNT = (. - setup_table) / 16 .byte 0xFF # type FF as terminator raminit: .byte LO(ccircwbuf), 8 .byte LO(ccircwbuf + 1), 0xFF .byte LO(output_1), INIT_1 .byte LO(output_2), INIT_2 .byte LO(output_3), INIT_3 .byte LO(output_5), INIT_5 .byte LO(output_7), INIT_7 .byte LO(curmem), NOTMEM .byte LO(arp_prev), 0xF .byte LO(ev_prev), 0xF .byte LO(idletimer), IDLETICKS .byte 0 dpyinit: .byte DPY_HEAD0, DPY_HEAD1, DPY_TRAIL # unknown seq .ascii "88888888888888" # tube .byte 22, 22 # leds banner: .asciz BANNER .ascii VERSION .ascii " STEP " .byte STEP_kHz / 10 + '0' .byte STEP_kHz % 10 + '0' .ascii "kHz" #ifdef CB .ascii " for CB/PR40" #endif #ifdef WITHSERSEND .ascii " with serial send" #endif #define SHORT(c, handler) .byte (0x00 | (c)), HI(handler), LO(handler) #define LONG(c, handler) .byte (0x80 | (c)), HI(handler), LO(handler) normal_jump_table: SHORT(KEY_MINUS, decrease_audio) SHORT(KEY_PLUS, increase_audio) SHORT(KEY_A, start_scan_A_or_continue) SHORT(KEY_T, repeater_toggle) SHORT(KEY_N, toggle_squelch) SHORT(KEY_C, flipto_setup) SHORT(KEY_STAR, send_beep) SHORT(KEY_HASH, VIP_recall) SHORT(CMD_DOWN, step_one_down) SHORT(KEY_DOWN, step_one_down) SHORT(CMD_UP, step_one_up) SHORT(KEY_UP, step_one_up) SHORT(CMD_SETUP, flipto_setup) SHORT(CMD_SCAN_A,start_scan_A) SHORT(CMD_SCAN_B,start_scan_B) SHORT(CMD_ACT_H, action_H) SHORT(CMD_ACT_U, action_U) SHORT(CMD_PTT, ptt_down) LONG(KEY_DOWN, to_prev_memory) LONG(KEY_UP, to_next_memory) LONG(KEY_MINUS, very_decrease_audio) LONG(KEY_PLUS, very_increase_audio) LONG(KEY_A, start_scan_B) LONG(KEY_T, toggle_tx_power) LONG(KEY_N, toggle_mute) LONG(KEY_HASH, call_recall) LONG(KEY_STAR, send_ccir_again) LONG( 0 , extbits_clear) LONG( 1 , extbit1_toggle) LONG( 2 , extbit2_toggle) LONG( 3 , extbit3_toggle) LONG( 4 , reject_channel) LONG( 5 , clear_rejects) LONG( 7 , show_ccir_history) LONG(KEY_C, show_ccir_history) SHORT(0, mainloop) cbrowse_jump_table: SHORT(KEY_MINUS, cbrowse_back) SHORT(KEY_PLUS, cbrowse_forw) SHORT(KEY_N, cbrowse_next) SHORT(KEY_A, cbrowse_prev) SHORT(KEY_T, show_ccir_history) SHORT(KEY_HASH, leave_ccir_history) SHORT(CMD_SETUP, leave_ccir_history) SHORT(CMD_DOWN, step_one_down) SHORT(CMD_UP, step_one_up) SHORT(CMD_PTT, ptt_down) LONG(KEY_MINUS, cbrowse_very_back) LONG(KEY_PLUS, cbrowse_very_forw) SHORT(KEY_C, leave_ccir_history) SHORT(0, mainloop) digits_jump_table: SHORT(KEY_MINUS, step_channels_down) SHORT(KEY_PLUS, step_channels_up) SHORT(KEY_A, start_given_scan) SHORT(KEY_HASH, execute) SHORT(KEY_STAR, send_ccir) SHORT(KEY_C, enter_setup) SHORT(KEY_N, code_mute_start) LONG(KEY_HASH, memory_store) SHORT(0, mainloop) setup_jump_table: SHORT(KEY_MINUS, previous_setup_field) SHORT(CMD_DOWN, previous_setup_field) SHORT(KEY_PLUS, next_setup_field) SHORT(CMD_UP, next_setup_field) SHORT(KEY_HASH, setup_execute) SHORT(KEY_T, reenter_setup) SHORT(KEY_STAR, reset_setup) SHORT(CMD_SETUP, leave_setup) SHORT(KEY_C, leave_setup) SHORT(KEY_A, next_setup_group) SHORT(KEY_N, prev_setup_group) LONG(KEY_HASH, reenter_setup) SHORT(0, mainloop) /*----------------------------------------------------------- * End of code */ .ascii "End" .cksum # zero sum TheEnd: # keep this last