#define VERSINFO 0x0E #define VERSION "0.E 970824" BASE = 0 !---------------------------------------------------------------------- #ifdef RD58 #define MACHINE "RD58 128/86.5125" #define PRESCALER 128 #define DIVMAX 0x1FFFF #define RX_SUB 86512 #define DEF_BSTEP 1024 #define RPTR_SUB 1600 #define DEF_STEP 25 #define FLOOR 400000 #define DEF_10MHZ 430000 #define BAND_START 432000 #define DEF_1MHZ 433000 #define CALL_FREQ 433500 #define SIMPLEX_START 433400 #define SIMPLEX_END 433600 #define DUPLEX_START 434600 #define DUPLEX_END 435000 #define BAND_END 438000 #define SCAN99_START 453000 #define SCAN99_END 458000 #define SCAN9_START 463000 #define SCAN9_END 468000 #define CEIL 500000 #endif !---------------------------------------------------------------------- #ifdef RC58 #define MACHINE "RC58 64/21.4" #define PRESCALER 64 #define DIVMAX 0x0FFFF #define RX_SUB 21400 #define DEF_BSTEP 1024 #define RPTR_SUB 600 #define DEF_STEP 25 #define FLOOR 100000 #define BAND_START 144000 #define DEF_10MHZ 140000 #define DEF_1MHZ 145000 #define CALL_FREQ 145500 #define SIMPLEX_START 145200 #define SIMPLEX_END 145600 #define DUPLEX_START 145600 #define DUPLEX_END 145800 #define BAND_END 146000 #define SCAN99_START 165125 #define SCAN99_END 165750 #define SCAN9_START 169875 #define SCAN9_END 170350 #define CEIL 200000 #endif !---------------------------------------------------------------------- #ifdef RB58 #define MACHINE "RB58 64/45.0" #define PRESCALER 64 #define DIVMAX 0x0FFFF #define RX_SUB 45000 #define DEF_BSTEP 1280 #define RPTR_SUB 600 #define DEF_STEP 20 #define FLOOR 0 #define DEF_10MHZ 50000 #define BAND_START 50000 #define DEF_1MHZ 51000 #define CALL_FREQ 51510 #define SIMPLEX_START 51490 #define SIMPLEX_END 51610 #define DUPLEX_START 51810 #define DUPLEX_END 51970 #define BAND_END 52000 #define SCAN99_START 50000 #define SCAN99_END 60000 #define SCAN9_START 60000 #define SCAN9_END 70000 #define CEIL 100000 #endif !---------------------------------------------------------------------- VIP_COUNT = 10 !---------------------------------------------------------------------- ! ! crc = crchi ^ crc16_table[crclo ^ c] ! #define INIT_CRC(pkt) \ ld b, 0xFF ;\ ld a, 0xFF ;\ ld d, 0 ;\ ld ix, pkt ; #define ADD_CRC(n) \ xor [ix + (n)] ;\ ld hl, crctbl + 1 ;\ ld e, a ;\ add hl, de ;\ add hl, de ;\ ld a, b ;\ ld b, [hl] ;\ dec hl ;\ xor [hl] ; !---------------------------------------------------------------------- ! ! Convenience macros ! #define BUF(n) : .rs n #define BYTE : .rs 1 #define WORD : .rs 2 #define MKWORD(lo,hi) ((lo) | ((hi) << 8)) #define MASK(bit) (1 << (bit)) #define srl4 srl a ; srl a ; srl a ; srl a #define sla4 sla a ; sla a ; sla a ; sla a #define imm_ahl(I) ld hl, (I) % 65536 ; ld a, (I) / 65536 #define load_ahl(A) ld hl, [A] ; ld a, [(A) + 2] #define save_ahl(A) ld [A], hl ; ld [(A) + 2], a #define load_abc(A) ld bc, [A] ; ld a, [(A) + 2] !---------------------------------------------------------------------- ! ! I/O map ! #define PIO 0x00 #define SIO 0x10 #define TMR 0x20 #define DA0 0x30 #define DA1 0x40 #define AD 0x50 #define OUT0 0x60 #define OUT1 0x70 #define OUT2 0x80 #define WD 0x90 #define MDM 0xA0 #define CSMEM 0xB0 /* P8E SMEM flipflop */ #define ADATA 0 #define BDATA 1 #define ACTRL 2 #define BCTRL 3 #define TMRCTRL 3 #define AD_RSSI (AD + 0) #define AD_BATT (AD + 2) #define DA_RFC DA0 #define DA_TXPWR DA1 !---------------------------------------------------------------------- ! ! FX429 ! #define MDMDATA 2 #define MDMCTRL 3 #define MDM_TXENB 0x01 #define MDM_TXPAR 0x02 #define MDM_RXENB 0x04 #define MDM_RXFMT 0x08 #define MDM_TIMER 0xF0 #define MDM_XXX 0x00 /* Nothing enabled */ #define MDM_RXRDY 0x01 #define MDM_RXTRUE 0x02 #define MDM_DCD 0x04 #define MDM_TXRDY 0x08 #define MDM_TXIDL 0x10 #define MDM_TMRINT 0x20 #define MDM_SYNC 0x40 #define MDM_SYNT 0x80 !---------------------------------------------------------------------- ! ! 8254 timer ! #define TMR_0 0x00 #define TMR_1 0x40 #define TMR_2 0x80 #define TMR_INTTC 0x00 /* mode 0, intr on terminal cnt */ #define TMR_ONESHOT 0x02 /* mode 1, one shot */ #define TMR_RATEGEN 0x04 /* mode 2, rate generator */ #define TMR_SQWAVE 0x06 /* mode 3, square wave */ #define TMR_SWTRIGG 0x08 /* mode 4, s/w triggered strobe */ #define TMR_LSB 0x10 /* r/w counter LSB */ #define TMR_MSB 0x20 /* r/w counter MSB */ #define TMR_BOTH 0x30 /* r/w counter 16 bits, LSB first */ !---------------------------------------------------------------------- ! ! SIO defs ! #define WR0_SEND_ABORT 0x08 #define WR0_RESET_ESCINT 0x10 #define WR0_CHANNEL_RESET 0x18 #define WR0_REARM_1STC 0x20 #define WR0_RESET_TXINT 0x28 #define WR0_ERROR_RESET 0x30 #define WR0_RETINT 0x38 #define WR0_RESET_RXCRC 0x40 #define WR0_RESET_TXCRC 0x80 #define WR0_RESET_UNDERRUN 0xc0 #define WR1_ESCINT_ENB 0x01 #define WR1_TXINT_ENB 0x02 #define WR1_STATUS_VECTOR 0x04 #define WR1_RXINT_DISABLE 0x00 #define WR1_INT_1STC 0x08 #define WR1_INT_ALLC 0x10 #define WR1_INT_ALLC_PNS 0x18 #define WR1_WAITREADY_RT 0x20 #define WR1_WAITREADY_FN 0x40 #define WR1_WAITREADY_ENB 0x80 #define WR3_RX_ENB 0x01 #define WR3_SYNCLOAD_INHIBIT 0x02 #define WR3_ADDRESS_SEARCH_MODE 0x04 #define WR3_RXCRC_ENB 0x08 #define WR3_ENTER_HUNT 0x10 #define WR3_AUTO_ENABLES 0x20 #define WR3_5BIT_RX 0x00 #define WR3_6BIT_RX 0x40 #define WR3_7BIT_RX 0x80 #define WR3_8BIT_RX 0xc0 #define WR4_PARITY_ENB 0x01 #define WR4_PARITY_ODD 0x00 #define WR4_PARITY_EVEN 0x02 #define WR4_SYNC_MODES 0x00 #define WR4_1STOPBIT 0x04 #define WR4_15STOPBIT 0x08 #define WR4_2STOPBIT 0x0c #define WR4_8BITSYNC 0x00 #define WR4_16BITSYNC 0x10 #define WR4_SDLC_MODE 0x20 #define WR4_EXTSYNC 0x30 #define WR4_X1_CLK 0x00 /* 153600 bd, but... */ #define WR4_X16_CLK 0x40 /* 9600 bd */ #define WR4_X32_CLK 0x80 /* 4800 bd */ #define WR4_X64_CLK 0xc0 /* 2400 bd */ #define WR5_TXCRC_ENB 0x01 #define WR5_RTS 0x02 #define WR5_CCITT_CRC 0x00 #define WR5_CRC16_CRC 0x04 #define WR5_TX_ENB 0x08 #define WR5_SEND_BREAK 0x10 #define WR5_5BIT_TX 0x00 #define WR5_7BIT_TX 0x20 #define WR5_6BIT_TX 0x40 #define WR5_8BIT_TX 0x60 #define WR5_DTR 0x80 #define RR0_RCA 0x01 #define RR0_INT_PENDING 0x02 #define RR0_TBE 0x04 #define RR0_DCD 0x08 #define RR0_SYNC 0x10 #define RR0_CTS 0x20 #define RR0_UNDERRUN 0x40 #define RR0_BREAK_ABORT 0x80 #define RR1_ALL_SENT 0x01 #define RR1_PARER 0x10 #define RR1_ROVER 0x20 #define RR1_FRMERR 0x40 #define RR1_CRCERR 0x40 #define RR1_ENDFRAME 0x80 !---------------------------------------------------------------------- ! ! Output latch bits ! #define O0_VOLUME 0x07 #define O0_INH 0x08 #define O0_AUDIOC 0x10 #define O0_CCIRC 0x20 #define O0_MTC 0x40 #define O0_MICM 0x80 #define O0_MTCBIT 6 #define O1_SRE 0x01 #define O1_SCE 0x02 #define O1_STE 0x04 #define O1_CLK 0x08 #define O1_SD 0x10 #define O1_RAS 0x20 #define O1_TPS 0x40 #define O1_TXOFF 0x80 ! ! Changes only by mainline. ! #define O2_RA14 0x01 #define O2_RA15 0x02 #define O2_RS 0x04 #define O2_SMEM 0x08 #define O2_CS1 0x10 #define O2_CS2 0x20 #define O2_CLK 0x40 #define O2_DP 0x80 #define O2_XXX O2_SMEM #define O2_KEYPAD (O2_XXX | 0) #define O2_LATCH (O2_XXX | O2_CS1) #define O2_LCD1 (O2_XXX | O2_CS2) #define O2_LCD2 (O2_XXX | O2_CS2 | O2_CS1) !---------------------------------------------------------------------- ! ! PIO and SIO controls ! #define PA_CLK2 0x01 #define PA_HOOK 0x02 #define PA_WDR 0x04 #define PA_PWR 0x08 #define PA_CCIR 0xf0 /* all inputs */ #define PB_RAMA12 0x01 /* out */ #define PB_EXIN1 0x02 #define PB_EXIN2 0x04 #define PB_DCU 0x08 #define PB_RXOFF 0x10 #define PB_TMR0 0x20 #define PB_EXAL 0x40 /* out */ #define PB_PWROFF 0x80 /* out 3eh are inputs */ #define SA_KKINT RR0_DCD #define SA_DA RR0_CTS #define SB_PTT RR0_CTS #define SB_LOCAL RR0_SYNC #define SB_DMIDLE RR0_DCD /* No MBUS activity */ #define SB_MON WR5_DTR /* Master ON pulse */ ! LATCH bits #define BIT_AVAIL 0 /* not connected */ #define BIT_CALL 1 #define BIT_ROAM 2 #define BIT_KEYLIGHT 3 #define BIT_SERV 4 #define BIT_ON 5 #define BIT_LCDLIGHT 6 #define BIT_BRIGHT 7 ! Special LCD segments #define SEG_V_U 0x43 #define SEG_V_D 0x53 #define SEG_PHONE 0x47 #define SEG_CLOCK 0x4b #define SEG_COLON_UR 0x4f #define SEG_COLON_UL 0x63 #define SEG_COLON_D 0x57 #define SEG_PHONE_NO 0x5b #define SEG_MAST 0x5f #define SEG_BAR_L 0x67 #define SEG_BAR_R 0x6f #define SEG_STAR 0x6b #define SEG_KEY 0x73 #define SEG_BOOK 0x77 #define SEG_CAR_D 0x7b #define SEG_CAR_U 0x7f !---------------------------------------------------------------------- ! ! realstart ! .text .org BASE di ! 1st op has to be 'di' for ram-loaded #if 0 in a, [PIO+ADATA] and PA_WDR jp nz, . ! Not watchdog reset ?!? #endif ld hl, 0x0FFF ! Depends on clock freq... XXX shit 1: dec hl ld a, h or l jr nz, 1b ! Wait but not too long for defined wd state out [WD], a ! ok, now start jp start #ifdef PROM !---------------------------------------------------------------------- .org 0x0038 di ! 1st op has to be 'di' for ram-loaded out [WD], a jp start !---------------------------------------------------------------------- ! ! NMI ! .org 0x0066 di ! IFF1 and IFF2 cleared out [WD], a #ifdef P8N ld c, OUT2 ld d, O2_LCD1 & ~O2_SMEM ld e, O2_LCD1 ld b, nvend - nvmisc ld hl, nvmisc 1: ld a, [hl] out [c], d ld [hl], a out [c], e inc hl djnz 1b #endif out [WD], a ld sp, 1f retn ! restart to (IFF1 still clear) 1: .word start ! start in prom #endif !---------------------------------------------------------------------- banner: .ascii "@(#)" .ascii MACHINE .ascii " " #ifdef P8N .ascii "P8N " #endif #ifdef P8E .ascii "P8E " #endif #ifdef PROM .ascii "PROM " #endif .asciz VERSION versinfo: .byte VERSINFO !---------------------------------------------------------------------- ! ! Interrupt table, short-aligned, on one page. ! .align 4 intvec: sio_base: .word siob_tbe .word siob_esc .word siob_rca .word siob_src .word sioa_tbe .word sioa_esc .word sioa_rca .word sioa_src pioa_base: .word pioa_int piob_base: .word piob_int !---------------------------------------------------------------------- ! ! Initialization commands for PIO, SIO and 8254 ! In that order, A/B, A/B, 0/1/2 ! ! init_chips: 1: .byte LO(pioa_base) ! load interrupt vector .byte 0xcf ! set operating mode 3 .byte 0xff ! i/o selection, 1 for input, 0 for output .byte 0x97 ! set interrupt control, IE, OR, LOW, MASK .byte 0xfe ! input bit monitoring mask, A0. PIOA_INIT = . - 1b 1: .byte LO(piob_base) ! load interrupt vector .byte 0xcf ! set operating mode 3 .byte 0x3e ! i/o selection, 1 for input, 0 for output .byte 0x97 ! set interrupt control, IE, OR, LOW, MASK !.byte 0xdf ! input bit monitoring mask, only B5 (TMR0) .byte 0xff ! input bit monitoring mask, nothing PIOB_INIT = . - 1b 1: .byte WR0_CHANNEL_RESET .byte 4, WR4_1STOPBIT | WR4_X16_CLK .byte 3, WR3_8BIT_RX .byte 5, WR5_8BIT_TX | WR5_RTS | WR5_DTR .byte 1, WR1_STATUS_VECTOR | WR1_ESCINT_ENB SIOA_INIT = . - 1b 1: .byte WR0_CHANNEL_RESET .byte 4, WR4_1STOPBIT | WR4_X16_CLK .byte 3, WR3_8BIT_RX | WR3_RX_ENB .byte 5, WR5_8BIT_TX | WR5_RTS | WR5_DTR | WR5_TX_ENB .byte 1, WR1_STATUS_VECTOR | WR1_ESCINT_ENB | WR1_TXINT_ENB | WR1_INT_ALLC .byte 2, LO(sio_base) SIOB_INIT = . - 1b ! ! All timer-gates are fixed on. ! timer-clocks 0 and 1 are 4.032 MHz, 2 is 1968.75 Hz ! ! System hz is 100, from PIO B5 and TMR0_2 ! MT_300HZ = 4032000 / 300 MT_600HZ = 4032000 / 600 MT_1000HZ = 4032000 / 1000 MT_1200HZ = 4032000 / 1200 MT_1400HZ = 4032000 / 1400 MT_1750HZ = 4032000 / 1750 LP_3600HZ = 4032000 / 3600 / 100 ! Control words, then initial counts. 1: .byte TMR_0 | TMR_BOTH | TMR_SQWAVE .byte TMR_1 | TMR_BOTH | TMR_SQWAVE .byte TMR_2 | TMR_BOTH | TMR_RATEGEN TMR_INIT = . - 1b .word LP_3600HZ ! LP Filter .word 4 ! TX- and audible tones !.word 20 ! 100 Hz clock interrupt to PIO B5 .word -1 ! Slowest possible. unused. !---------------------------------------------------------------------- ! ! Initialization before main ! start: di out [WD], a ld sp, 0 ! stack down from end of ram (last 16kB) ld a, HI(intvec) ld iv, a im2 ! ! Output latches ! ld a, 0x00 ! volume setting at lowest level ld [output_0], a out [OUT0], a ld a, O1_TXOFF ! no tx, idle all ld [output_1], a out [OUT1], a out [WD], a ! ! Prep RAM selects for max workspace ! ld a, O2_XXX ! select ram 0, i hope, on P8N out [OUT2], a ld a, 1 out [CSMEM], a ! select full 16k page of ram on P8E, nop on P8N ld a, 0 ld [txon], a out [WD], a ! ! Disable NMT modem ! ld a, MDM_XXX out [MDM + MDMCTRL], a ! ! PIO, SIO and 8254 ! ld a, 0 out [PIO+BDATA], a ! B0, EXAL, OFF all zero ld hl, init_chips ld bc, MKWORD(PIO + ACTRL, PIOA_INIT) otir out [WD], a ld bc, MKWORD(PIO + BCTRL, PIOB_INIT) otir out [WD], a ! Set output bits, and check if restarted from powerdown nmi. ld a, 0 out [PIO+BDATA], a ! B0, EXAL, OFF all zero, again ? in a, [PIO+ADATA] and PA_PWR jp nz, powerdown ld bc, MKWORD(SIO + ACTRL, SIOA_INIT) in a, [c] otir out [WD], a ld bc, MKWORD(SIO + BCTRL, SIOB_INIT) in a, [c] otir out [WD], a ld bc, MKWORD(TMR + TMRCTRL, TMR_INIT) otir ld bc, MKWORD(TMR + 0, 2) otir ld bc, MKWORD(TMR + 1, 2) otir ld bc, MKWORD(TMR + 2, 2) otir out [WD], a ld hl, mbusrx_buf ld [mbusrx_rp], hl ld [mbusrx_wp], hl ld hl, mbustx_buf ld [mbustx_rp], hl ld [mbustx_wp], hl out [WD], a ld de, _bss ld a, 0 1: out [WD], a ld hl, _end and a sbc hl, de jr z, 1f ld [de], a inc de jr 1b 1: ! ! Initialize variables after bss clear ! ld hl, packet ld [pkt_ptr], hl ! rewind packet pointer call blip call load_nvdata ld a, [sec100] cp 100 jr nc, 1f ld a, [seconds] cp 60 jr nc, 1f ld a, [minutes] cp 60 jr c, 2f 1: ld a, 0 ld [sec100], a ld [seconds], a ld [minutes], a ld [hours], a 2: ld hl, 1 ld [energy_unit_per_second], hl ld a, -1 ld [key], a ld [lastkey], a ld [lastdigit], a out [WD], a #if 1 ! ! Initialize NMT modem ! ld a, 0x04 out [MDM + MDMCTRL], a ! Write 04 to control register ld hl, 10000 1: out [WD], a dec hl ld a, h or l jr nz, 1b ! Wait at least 1 bit. ld a, 0x00 out [MDM + MDMCTRL], a ! Write zeros to control register #endif ld hl, 10000 1: out [WD], a dec hl ld a, h or l jr nz, 1b ! Give time for LCD to reset itself ! in a, [TMR+TMRCTRL] ! dummy read to raise PIO B5 (remove int) ei ld a, [currmem] call getmemflags ld [memflags], a ld a, VIP_COUNT ld de, vip_list ! destination 1: ld hl, currmem ld bc, 4 ldir ! one record dec a jr nz, 1b ! VIP_COUNT times jp main !---------------------------------------------------------------------- doreti: pop af ei reti !---------------------------------------------------------------------- ! ! SIO interrupts ! siob_tbe: push af ld a, [mbustx_cnt] dec a ld [mbustx_cnt], a jr z, siob_tbe_close push hl ld hl, [mbustx_rp] ld a, [hl] inc l ld [mbustx_rp], hl pop hl out [SIO+BDATA], a ld a, 25 ld [mbus_timer], a ! keep transmit timer on jp doreti siob_tbe_close: ld a, WR0_RESET_TXINT out [SIO+BCTRL], a jp doreti siob_rca_drop: call bleep siob_rca_ignore: in a, [SIO+BDATA] jp doreti siob_rca: push af ld a, [mbus_timer] or a jr nz, siob_rca_ignore ld a, [mbusrx_cnt] inc a jr z, siob_rca_drop ! no room ld [mbusrx_cnt], a push hl ld hl, [mbusrx_wp] in a, [SIO+BDATA] ld [hl], a inc l ld [mbusrx_wp], hl pop hl jp doreti ! ! SIO B ext/status change ! siob_esc: push af in a, [SIO+BCTRL] and SB_PTT ld [pttdn], a ld a, WR0_RESET_ESCINT out [SIO+BCTRL], a jp doreti ! ! SIO B special receive condition ! siob_src: push af in a, [SIO+BDATA] ld a, WR0_ERROR_RESET out [SIO+BCTRL], a call bleep jp doreti sioa_tbe: push af ld a, WR0_RESET_TXINT out [SIO+ACTRL], a jp doreti sioa_rca: push af in a, [SIO+ADATA] jp doreti ! ! SIO A ext/status change ! sioa_esc: push af in a, [SIO+ACTRL] and SA_DA ld a, 0 jp nz, 1f ld a, [keydown] or a jr nz, 2f ld a, 1 ld [keydown], a jr 2f 1: ld a, 0 ld [key_timer], a ld [keydown], a ld a, [lastdigit] cp -1 jr z, 2f ld a, [lastdigit] ld [key], a ! Quick press of digit. ld a, -1 ld [lastdigit], a 2: #if 1 ld a, [txon] or a jr nz, 1f ! ignore during xmit in a, [MDM + MDMCTRL] and MDM_SYNC | MDM_RXRDY jr z, 1f ! no sync nor data push hl cp MDM_SYNC jr nz, 3f ! not sync only (never both simultaneously ?!?!?) ld hl, packet ld [pkt_ptr], hl ! rewind packet pointer jr 2f 3: and MDM_RXRDY jr z, 2f in a, [MDM + MDMDATA] ld hl, [pkt_ptr] ld [hl], a inc hl ld [pkt_ptr], hl ld a, l cp LO(packet + SIZE(packet)) jr nz, 2f ld hl, packet ld [pkt_ptr], hl ! rewind packet pointer push bc push de push ix call check_packet pop ix pop de pop bc 2: pop hl 1: #endif in a, [TMR+TMRCTRL] ! dummy read to raise PIO B5 (remove int) ld a, WR0_RESET_ESCINT out [SIO+ACTRL], a jp doreti ! ! SIO A special receive condition ! sioa_src: push af in a, [SIO+ADATA] ld a, WR0_ERROR_RESET out [SIO+ACTRL], a jp doreti !---------------------------------------------------------------------- ! ! PIO interrupts ! ! Change in B5 ! Should not get this now, as monitormask is empty... piob_int: push af jp doreti ! Change in A0, 1968.75 Hz square pioa_int: ex af exx dec c jr z, 1f ex af exx ei reti 1: out [WD], a ! keep watchdog happy. ! ! Hook interest ! ld a, [pioa_data] ld l, a ! old bits in a, [PIO+ADATA] ld [pioa_data], a and PA_HOOK jr z, 9f ! on hook xor l ! extract change and PA_HOOK jr z, 9f ! not changed ld hl, indicators set BIT_LCDLIGHT, [hl] ! lit the lights. set BIT_KEYLIGHT, [hl] ld hl, 100 * 5 ld [light_ltimer], hl ! for 5 seconds. ld hl, sir set DPYSIR, [hl] ! Update CU later 9: ld a, [scan_mode] or a jr z, 9f ld a, [scan_timer] or a jr z, 1f dec a ld [scan_timer], a 1: ld hl, [scan_ltimer] ld a, h or l jr z, 1f dec hl ld [scan_ltimer], hl 1: 9: ld a, [mt_timer] or a jr z, 1f ld a, [output_0] out [OUT0], a ld a, [mt_timer] dec a ld [mt_timer], a call z, stop_marker_tone 1: ! ! Decrement timer for handset lights ! ld a, [keydown] or a jr nz, 1f ! not if button still pressed ld hl, [light_ltimer] ld a, h or l jr z, 1f ! not if timer not running dec hl ld [light_ltimer], hl ld a, h or l jr nz, 1f ld hl, indicators res BIT_LCDLIGHT, [hl] ! Time to dim the lights. res BIT_KEYLIGHT, [hl] 1: ! ! Decrement MBUS activity timer ! ld a, [mbus_timer] or a jr z, 1f dec a ld [mbus_timer], a 1: ! ! Alert timer ! ld hl, [alert_ltimer] ld a, h or l jr z, 1f dec hl ld [alert_ltimer], hl 1: ! ! One second trail after end of xmit ! ld a, [txtail_timer] or a jr z, 1f ! Not counting anymore ld a, [txon] or a jr nz, 1f ! Still xmit ld a, [txtail_timer] dec a ld [txtail_timer], a ! One 10msec less of tail 1: ! ! See if keypad has data coming and debouncing ! allows it to be fetched ! ld a, [keydown] or a jr z, 1f ! not key down inc a jr z, 1f ! been a long time, 256 softicks ld [keydown], a cp 10 jr nz, 1f ! not at debounce-position ld a, [sir] set KEYSIR, a ld [sir], a ! go get it. 1: ! ! Which A/D was running ? ! ld a, [ad_select] cp 2 jp z, did_ad_batt ! S meter and squelch control in a, [AD] ld b, a ! current rssi ld [rssi], a ld a, 2 ld [ad_select], a ! next time battery voltage out [AD_BATT], a ! value not important out [AD_BATT], a ! twice to settle analog mux in case it changed ld a, [txtail_timer] cp 90 jp nc, 9f ! Skip if tx during last 100 msec ld a, [mton] or a jp nz, 9f ! Skip if tone on. #if 0 ld a, [squelch_open] or a jr z, 1f ! go if closed #endif ld a, [squelch_forced] or a jr nz, 2f ld a, [squelch_limit_close] cp b ! close_limit - rssi jr c, 1f ld hl, indicators res BIT_SERV, [hl] ld a, 0 ld [squelch_open], a ld a, [output_0] and ~O0_AUDIOC ld [output_0], a out [OUT0], a 1: ld a, [squelch_limit_open] cp b ! open_limit - rssi jr nc, 1f 2: ld hl, indicators set BIT_SERV, [hl] ld a, 1 ld [squelch_open], a ld a, [output_0] or O0_AUDIOC ld [output_0], a out [OUT0], a 1: ! smoothing rssi display ld a, [srssi] cp b ! smoothed - rssi jr c, 1f ! go if raising ld a, [rssi_timer] dec a jr nz, 2f ! go if still timing 1: ld a, 1 ld [redraw_req], a ld a, b ld [srssi], a ld a, 50 ! one second 2: ld [rssi_timer], a jp 9f did_ad_batt: ld a, [batt] ld b, a in a, [AD] ! current battery voltage ld [batt], a ld a, 0 ld [ad_select], a ! next time rssi out [AD_RSSI], a ! value not important out [AD_RSSI], a ! twice to settle analog mux in case it changed 9: ! Typematic ld a, [key_timer] or a jr z, 9f dec a ld [key_timer], a jr nz, 9f ld a, [key_speed] ld [key_timer], a ld a, [key_time] inc a jr z, 1f ld [key_time], a 1: ld a, [key_blips] or a jr z, 1f dec a ld [key_blips], a call blip 1: ld a, [lastkey] cp 10 jr nc, 1f or 0x80 ! Repeating digit is a function. 1: ld [key], a ld a, -1 ld [lastdigit], a 9: ld a, [sec100] inc a cp 100 jr c, 1f ! less than full second. ld hl, [energy] ld bc, [energy_unit_per_second] and a sbc hl, bc ld [energy], hl ! keep track how much energy is used ld a, [seconds] inc a cp 60 jr c, 2f ! less than full minute ld a, [minutes] inc a cp 60 jr c, 3f ld a, [hours] add 1 ! overflows to 0... ld [hours], a ld a, 0 3: ld [minutes], a ld a, 0 2: ld [seconds], a ld a, 0 1: ld [sec100], a ld c, 1969 / 100 ! hard ticks to next exx ! softlevel ld a, [nosir] or a jr nz, 1f ! Cannot do it now. ld a, [sir] or a jr nz, 2f ! there are sirs 1: ex af 8: ei reti 2: bit INSIR, a jr nz, 1b ! already here set INSIR, a ld [sir], a ! note sir starting ex af push af push bc push de push hl push ix push iy ! sir runs with normal regset call 8b call dosir di ld a, [sir] res INSIR, a ld [sir], a pop iy pop ix pop hl pop de pop bc pop af ei ret dosir: ld a, [sir] bit KEYSIR, a jr z, 1f res KEYSIR, a ld [sir], a call keypad 1: ld a, [sir] bit DPYSIR, a jr z, 1f res DPYSIR, a ld [sir], a call display 1: ret !---------------------------------------------------------------------- ! ! Mainline ! main: ! ! XXX ! #if 0 ld a, 0 ld [volume], a ld a, 0x40 ld [squelch_limit_open], a #endif ld a, [squelch_limit_open] sub 8 ld [squelch_limit_close], a ld hl, DEF_BSTEP ! 12.5 step ld [bstep_R], hl #if 1 ! Enable modem receiver ld a, MDM_RXENB out [MDM + MDMCTRL], a #endif ld a, 0xFF ld [dark], a ld [batt], a ! ! End XXX ! call set_vola ld a, 0 ld [rssi], a call reset_synth 1: ld a, [keydown] or a jp nz, 1b ! wait release #if 0 ld c, 0xa call putchar imm_ahl(CALL_FREQ) call freq2div save_ahl(tx_divisor) #endif call lookup_rfc call change_synth ld hl, segments + (SEG_COLON_UL / 8) set SEG_COLON_UL % 8, [hl] ld hl, segments + (SEG_COLON_UR / 8) set SEG_COLON_UR % 8, [hl] ld hl, indicators set BIT_ON, [hl] call redraw mainloop: call battcheck call pttcheck call keycheck call redrawcheck ld a, [packet_rdy] or a jr z, 1f call packet_for_whom ld a, 0 ld [packet_rdy], a ! Ignores quick successive packets 1: ld a, [scan_mode] or a jr z, 1f ld hl, [scanner_state] push hl ret scanner_ret: pop hl ld [scanner_state], hl 1: jp mainloop packet_for_whom: ld iy, packet_good ld ix, mycall ld a, [iy + 3]; srl4; cp [ix + 0]; ret nz ld a, [iy + 3]; and 0xF; cp [ix + 1]; ret nz ld a, [iy + 4]; srl4; cp [ix + 2]; ret nz ld a, [iy + 4]; and 0xF; cp [ix + 3]; ret nz ld a, [iy + 5]; srl4; cp [ix + 4]; ret nz ld hl, indicators set BIT_CALL, [hl] call ding ld a, 1 ld [call_dpyed], a ld hl, 100 * 3 ld [light_ltimer], hl ld hl, indicators set BIT_LCDLIGHT, [hl] call redraw ret battcheck: ld a, [txtail_timer] ! did xmit lately ? or a jr z, 2f ld a, [batt] cp 90 * 256 / 156 ! 9V jp c, powerdown cp 100 * 256 / 156 ! 10V, was 11.2V, 184 jr c, 1f jr 3f 2: ld a, [batt] cp 100 * 256 / 156 ! 10V, was 10.2V, 167 jp c, powerdown cp 110 * 256 / 156 ! 11V, was 11.2V, 184 jr c, 1f 3: ld hl, segments + (SEG_CLOCK / 8) res SEG_CLOCK % 8, [hl] ret 1: ld hl, segments + (SEG_CLOCK / 8) set SEG_CLOCK % 8, [hl] ld hl, [alert_ltimer] ld a, h or l ret nz ld hl, 6000 ld [alert_ltimer], hl ! every 60 sec ld hl, MT_300HZ ld d, 100 ! one second alert tone call start_marker_tone ret keycheck: ld a, [key] cp -1 ret z ld c, a ld a, -1 ld [key], a ld a, c call dokey call redraw ret redrawcheck: ld a, [redraw_req] cp 0 ret z ld a, 0 ld [redraw_req], a call redraw ret dokey: ! whatever we call will do ret cp 10 jp c, insdig cp 'C' jp z, backspace cp 'E' jp z, execute cp '#' jp z, command cp 'R' jp z, toggle_rptr cp '*' jp z, beep1750 cp '+' jp z, up_vola cp '-' jp z, dn_vola cp 'B' jp z, monitor_audio cp 0x81 jp z, up_sqlv cp 0x84 jp z, dn_sqlv cp 0x87 jp z, def_sqlv cp 0x82 jp z, up_memo cp 0x85 jp z, dn_memo cp 0x88 jp z, def_memo cp 0x83 jp z, up_freq cp 0x86 jp z, dn_freq cp 0x89 jp z, def_freq cp 0x80 jp z, def_vola cp 'S' jp z, scanner_start ret clear_rejects: ld a, 2 ld [adj_feedback], a call redraw 1: ld a, [keydown] or a jp nz, 1b ld a, -1 ld [key], a ld a, 0 ld [adj_feedback], a ld b, 10 * 3 ld a, 0 ld hl, rejects 1: ld [hl], a inc hl djnz 1b ret add_reject: ld a, 1 ld [adj_feedback], a call redraw 1: ld a, [key_time] cp 2 jp nc, clear_rejects ld a, [keydown] or a jp nz, 1b ld a, -1 ld [key], a ld a, 0 ld [adj_feedback], a ld a, [reject_idx] inc a cp 10 jr c, 1f ld a, 0 1: ld [reject_idx], a ld c, a ld b, 0 ld ix, rejects add ix, bc add ix, bc add ix, bc ld a, [currfreq + 0] ld [ix + 0], a ld a, [currfreq + 1] ld [ix + 1], a ld a, [currfreq + 2] ld [ix + 2], a ld hl, scan_do_step ld [scanner_state], hl ret scanner_start: call redraw 1: ld a, [key_time] cp 1 jp nc, add_reject ld a, [keydown] or a jr nz, 1b ld a, -1 ld [key], a ld hl, scan_do_step ld [scanner_state], hl ld hl, segments + (SEG_PHONE / 8) set SEG_PHONE % 8, [hl] ld a, [digidx] or a jr z, 1f call a2i ld a, l or a jr z, 2f ld [scan_mode], a ld [defscan], a ret 1: ld a, [scan_mode] or a ret nz 2: ld a, [defscan] or a jr nz, 1f ld a, 1 1: ld [scan_mode], a ld [defscan], a ret scanner_stop: ld a, [scan_mode] or a ret z ld a, 0 ld [scan_mode], a ld hl, segments + (SEG_PHONE / 8) res SEG_PHONE % 8, [hl] ld a, 0 ld [vip_idx], a call next_vip ret scan_bad: call scanner_stop call scanner_ret scan_do_step: ld a, 0 ld [scan_oops], a scan_do_step_again: ld a, [scan_oops] dec a ld [scan_oops], a jp z, scan_bad ld a, [scan_mode] cp 2 jp z, scan_next_simplex cp 3 jp z, scan_next_rptr cp 4 jp z, scan_next_memory cp 7 jp z, scan_next_everything cp 77 jp z, scan_next_everything_down cp 8 jp z, scan_next_9xmemory cp 9 jp z, scan_next_nmt cp 99 jp z, scan_next_nmt_mobile jp scan_next_fm scan_next_fm: load_ahl(currfreq) ld de, DEF_STEP add hl, de adc 0 save_ahl(currfreq) load_ahl(currfreq) ld de, SIMPLEX_END % 65536 and a sbc hl, de sbc SIMPLEX_END / 65536 jp c, scan_currfreq ! < 433600 ! >= 433600 load_ahl(currfreq) ld de, DUPLEX_START % 65536 and a sbc hl, de sbc DUPLEX_START / 65536 jr nc, 1f ! >= 433600 and < 434600 imm_ahl(DUPLEX_START) save_ahl(currfreq) jp scan_currfreq 1: ! >= 434600 load_ahl(currfreq) ld de, DUPLEX_END % 65536 and a sbc hl, de sbc DUPLEX_END / 65536 jp c, scan_currfreq ! >= 434600 and < 435000 ! >= 435000 imm_ahl(SIMPLEX_START) save_ahl(currfreq) jp scan_currfreq scan_next_simplex: load_ahl(currfreq) ld de, DEF_STEP add hl, de adc 0 save_ahl(currfreq) ld de, SIMPLEX_END % 65536 and a sbc hl, de sbc SIMPLEX_END / 65536 jr c, 1f imm_ahl(SIMPLEX_START) save_ahl(currfreq) 1: jp scan_currfreq scan_next_rptr: load_ahl(currfreq) ld de, DEF_STEP add hl, de adc 0 save_ahl(currfreq) ld de, DUPLEX_END % 65536 and a sbc hl, de sbc DUPLEX_END / 65536 jr c, 1f imm_ahl(DUPLEX_START) save_ahl(currfreq) 1: jp scan_currfreq scan_next_nmt_mobile: load_ahl(currfreq) ld de, DEF_STEP add hl, de adc 0 save_ahl(currfreq) ld de, SCAN99_START % 65536 and a sbc hl, de sbc SCAN99_START / 65536 jr c, 1f imm_ahl(SCAN99_START) save_ahl(currfreq) 1: jp scan_currfreq scan_next_nmt: load_ahl(currfreq) ld de, DEF_STEP add hl, de adc 0 save_ahl(currfreq) ld de, SCAN9_END % 65536 and a sbc hl, de sbc SCAN9_END / 65536 jr c, 1f imm_ahl(SCAN9_START) save_ahl(currfreq) 1: jp scan_currfreq scan_next_everything_down: load_ahl(currfreq) ld de, DEF_STEP and a sbc hl, de sbc 0 save_ahl(currfreq) #if FLOOR == 0 ld de, CEIL % 65536 and a sbc hl, de sbc CEIL / 65536 jr c, 1f ! currfreq above ceil ? imm_ahl(CEIL) #else ld de, FLOOR % 65536 and a sbc hl, de sbc FLOOR / 65536 jr nc, 1f ! currfreq below floor ? imm_ahl(CEIL) #endif save_ahl(currfreq) 1: jp scan_currfreq scan_next_everything: load_ahl(currfreq) ld de, DEF_STEP add hl, de adc 0 save_ahl(currfreq) ld de, CEIL % 65536 and a sbc hl, de sbc CEIL / 65536 jr c, 1f imm_ahl(FLOOR) save_ahl(currfreq) 1: jp scan_currfreq scan_currfreq: ld a, -1 ld [currmem], a load_ahl(currfreq) call freq2div save_ahl(tx_divisor) call default_rptr call lookup_rfc call change_synth jp scan_do_wait scan_next_9xmemory: ld e, 101 ld a, [currmem] 2: dec e jp z, scan_bad inc a cp 100 jr c, 1f ld a, 90 1: cp 90 jr nc, 1f ld a, 90 1: ld d, a call getmemflags and MEM_EMPTY ld a, d jr nz, 2b call gomem_a ! Next memory jp scan_do_wait scan_next_memory: ld e, 101 ld a, [currmem] 2: dec e jp z, scan_bad inc a cp 100 jr c, 1f ld a, 0 1: ld d, a call getmemflags and MEM_EMPTY | MEM_NOSCAN ld a, d jr nz, 2b call gomem_a ! Next memory jp scan_do_wait scan_do_wait: ld ix, rejects ld b, 10 2: ld a, [currfreq + 0] cp [ix + 0] jr nz, 1f ld a, [currfreq + 1] cp [ix + 1] jr nz, 1f ld a, [currfreq + 2] cp [ix + 2] jr nz, 1f jp scan_do_step_again 1: inc ix inc ix inc ix djnz 2b ld a, [squelch_open] or a ld a, 5 ! Wait 50 ms jr z, 1f ld a, 20 ! but make it longer if channel is busy. 1: ld [scan_timer], a call redraw 1: call scanner_ret ld a, [scan_timer] or a jr nz, 1b ! The wait. ld a, [squelch_open] or a jp z, scan_do_step ! No signal. Next. call remember_vip ld hl, 15 * 100 ld [scan_ltimer], hl ! 15 seconds max. 1: #if 1 ld a, [scan_mode] cp 9 jr z, 8f cp 99 jr z, 8f jr 7f 8: in a, [MDM + MDMCTRL] and MDM_DCD jp nz, scan_do_step 7: #endif call scanner_ret ld hl, [scan_ltimer] ld a, h or l jp z, scan_do_step ! Lost patience. Next. ld a, [squelch_open] or a jr nz, 1b ! There is signal. Stay. ld a, 100 ld [scan_timer], a ! Stay 1 sec without signal. 2: call scanner_ret ld a, [squelch_open] or a jr nz, 1b ! Again signal. Keep listening. ld a, [scan_timer] or a jr nz, 2b ! No signal for 1 sec... jp scan_do_step ! ... so Next. send_call_packet: call tx_on jp c, tx_error di ld a, [output_0] and ~O0_CCIRC or O0_MICM ld [output_0], a out [OUT0], a ei 1: call redraw ld a, [keydown] or a jp nz, 1b ld a, -1 ld [key], a call build_packet_buffer call append_packet_crc call send_packet_buffer call mdm_delay call send_packet_buffer call mdm_delay call send_packet_buffer call tx_off call clear_buffer ret build_packet_buffer: ld hl, digbuf ld a, [digidx] ld b, a cp 1 jr nz, 1f ld a, [hl] cp 0 ret z ! 0* = send it again 1: ld de, outpacket ld ix, mycall ld a, 0xC0; or [ix + 0]; ld [de], a; inc de ld a, [ix + 1]; sla4; or [ix + 2]; ld [de], a; inc de ld a, [ix + 3]; sla4; or [ix + 4]; ld [de], a; inc de ld c, 3 1: inc c ld a, [hl] inc hl sla a; sla a; sla a; sla a or 0xF ld [de], a inc de dec b jr z, 1f and 0xF0 or [hl] inc hl dec de ld [de], a inc de dec b jr z, 1f ld a, c cp SIZE(outpacket) - 2 jr nz, 1b 1: ld a, c cp SIZE(outpacket) - 2 jr z, 1f ld a, 0xFF ld [de], a inc de inc c jr 1b 1: ret append_packet_crc: INIT_CRC(outpacket) ADD_CRC(0) ADD_CRC(1) ADD_CRC(2) ADD_CRC(3) ADD_CRC(4) ADD_CRC(5) cpl ld [ix + 7], a ld a, b cpl ld [ix + 6], a ret check_packet: INIT_CRC(packet) ADD_CRC(0) ADD_CRC(1) ADD_CRC(2) ADD_CRC(3) ADD_CRC(4) ADD_CRC(5) cpl cp [ix + 7] jr nz, 1f ld a, b cpl cp [ix + 6] jr nz, 1f ld a, [packet + 0]; ld [packet_good + 0], a ld a, [packet + 1]; ld [packet_good + 1], a ld a, [packet + 2]; ld [packet_good + 2], a ld a, [packet + 3]; ld [packet_good + 3], a ld a, [packet + 4]; ld [packet_good + 4], a ld a, [packet + 5]; ld [packet_good + 5], a ld a, 1 ld [packet_rdy], a 1: ret send_packet_buffer: ld a, MDM_TXENB out [MDM + MDMCTRL], a ld a, 1 ld [nosir], a ld hl, packet_header ld b, packet_header_size call send_some_data ld hl, outpacket ld b, SIZE(outpacket) call send_some_data ld a, 0 ld [nosir], a call mdm_delay 1: in a, [MDM + MDMCTRL] and MDM_TXIDL jr z, 1b ld a, MDM_RXENB out [MDM + MDMCTRL], a ret packet_header: .byte 0b10101010 .byte 0b10101010 .byte 0b10101010 .byte 0b10101010 .byte 0b10101010 .byte 0b11000100 .byte 0b11010111 packet_header_size = . - packet_header send_some_data: 1: call mdm_delay in a, [MDM + MDMCTRL] and MDM_TXRDY jr z, 1b ld a, [hl] inc hl out [MDM + MDMDATA], a djnz 1b ret mdm_delay: nop; nop; nop; nop; nop nop; nop; nop; nop; nop nop; nop; nop; nop; nop nop; nop; nop; nop; nop nop; nop; nop; nop; nop ret beep1750: ld a, [digidx] or a jp nz, send_call_packet call tx_on jp c, tx_error call battcheck di ! No digits, repeater beep ld a, 0 ld [mt_timer], a ld a, LO(MT_1750HZ) out [TMR + 1], a ld a, HI(MT_1750HZ) out [TMR + 1], a ld a, [output_0] or O0_CCIRC | O0_MICM ld [output_0], a out [OUT0], a ei 1: call redraw ld a, [keydown] or a jp nz, 1b ld a, -1 ld [key], a di ld a, [output_0] and ~(O0_CCIRC | O0_MICM) ld [output_0], a out [OUT0], a call stop_marker_tone ei call tx_off ret tx_error: ld hl, MT_300HZ ld d, 100 call start_marker_tone 1: call redraw ld a, [keydown] or a jr nz, 1b ld a, [pttdn] or a jr nz, 1b ld a, -1 ld [key], a ret default_rptr: load_ahl(currfreq) and a ld de, DUPLEX_START % 65536 sbc hl, de sbc DUPLEX_START / 65536 jr c, 1f ! if below 434600 load_ahl(currfreq) and a ld de, DUPLEX_END % 65536 sbc hl, de sbc DUPLEX_END / 65536 jr nc, 1f ! if at or above 435000 imm_ahl(RPTR_SUB) call freq2div save_ahl(tx_sub) ret 1: imm_ahl(0) save_ahl(tx_sub) ret toggle_rptr: load_ahl(tx_sub) ! current offset or h or l imm_ahl(0) ! assume back to simplex jr nz, 1f imm_ahl(RPTR_SUB) call freq2div 1: save_ahl(tx_sub) ret command: call scanner_stop call 1f call save_nvdata ret 1: ld a, [digidx] or a jr nz, 1f ld a, [dpymode] or a ret z inc a cp NUM_INFOS jr c, 2f ld a, 1 2: ld [dpymode], a ! Plain #, next dpy mode ret 1: cp 1 jr nz, 2f call a2i ld a, l cp 8 jp z, set_all_defaults cp 9 jr nz, 1f ld a, 1 ld [dpymode], a ret 1: and 3 ! 0 1 2 3 sla a ! 0 2 4 6 sla a ! 0 4 8 C sla a ! 0 8 10 18 sla a ! 0 10 20 30 sla a ! 0 20 40 60 sla a ! 0 40 80 C0 or 0x3F ! 3F 7F BF FF ld [txpwr], a ret 2: cp 2 jr nz, 3f call a2i ! txpwr 0..99 ld a, l srl a add l add l add 8 ! 2.5 * x + 8 ld [txpwr], a ! 8, 10, 13, 15 ... 250, 253, 255 ret 3: cp 3 jr nz, 4f call a2i or h ! AH nonzero ? jr z, 1f jp go_mhz ! HL 1: ld a, l ld [rfc], a out [DA_RFC], a call save_rfc ret 4: cp 4 jr nz, 5f call a2i ld [bstep_R], hl call reset_synth ret 5: ld a, [dpymode] or a jr nz, 1f call a2i save_ahl(tx_divisor) ret 1: ld a, [digbuf + 0]; ld [mycall + 0], a ld a, [digbuf + 1]; ld [mycall + 1], a ld a, [digbuf + 2]; ld [mycall + 2], a ld a, [digbuf + 3]; ld [mycall + 3], a ld a, [digbuf + 4]; ld [mycall + 4], a call clear_buffer ret set_all_defaults: call def_sqlv call def_vola call def_memo ret execute: ld a, [scan_mode] or a jp nz, scanner_stop ! Just stop it, nothing else call 1f call save_nvdata ret 1: ld a, [dpymode] or a jr z, 1f ld a, 0 ld [dpymode], a ret 1: ld a, [digidx] cp 3 jp c, gomem ! 1...2 digits cp 5 jr nc, gofreq ! 5... digits cp 3 jr z, 1f call a2i ld de, DEF_10MHZ % 65536 ld b, DEF_10MHZ / 65536 jr 2f 1: call a2i ld de, DEF_1MHZ % 65536 ld b, DEF_1MHZ / 65536 2: add hl, de adc b jr 2f gofreq: call a2i 2: save_ahl(currfreq) call freq2div save_ahl(tx_divisor) call default_rptr call lookup_rfc call change_synth call remember_vip ret go_mhz: ld d, h ld e, l ld hl, 0 ld a, 0 ! HL has MHz, AHL gets freq ld c, 10 3: ld b, 100 1: add hl, de ! AHL * 1000 adc 0 djnz 1b dec c jr nz, 3b jp 2b ! ! Push current memory/frequency ! into vip_list, forgetting oldest record. ! Duplicates raise into head of list. ! remember_vip: #define one_vip_swap(x) \ push bc; pop ix; \ push de; pop iy; \ ld bc, [vip_list + 4 * x + 0]; \ ld de, [vip_list + 4 * x + 2]; \ ld [vip_list + 4 * x + 0], ix; \ ld [vip_list + 4 * x + 2], iy; \ ld hl, [currmem + 0]; and a; sbc hl, bc; jr nz, 1f; \ ld hl, [currmem + 2]; and a; sbc hl, de; jr nz, 1f; ret; 1: ld bc, [currmem + 0] ld de, [currmem + 2] one_vip_swap( 0) one_vip_swap( 1) one_vip_swap( 2) one_vip_swap( 3) one_vip_swap( 4) one_vip_swap( 5) one_vip_swap( 6) one_vip_swap( 7) one_vip_swap( 8) one_vip_swap( 9) #if 0 one_vip_swap(10) one_vip_swap(11) one_vip_swap(12) one_vip_swap(13) one_vip_swap(14) one_vip_swap(15) one_vip_swap(16) one_vip_swap(17) one_vip_swap(18) one_vip_swap(19) one_vip_swap(20) one_vip_swap(21) one_vip_swap(22) one_vip_swap(23) one_vip_swap(24) one_vip_swap(25) one_vip_swap(26) one_vip_swap(27) one_vip_swap(28) one_vip_swap(29) one_vip_swap(30) one_vip_swap(31) one_vip_swap(32) one_vip_swap(33) one_vip_swap(34) one_vip_swap(35) one_vip_swap(36) one_vip_swap(37) one_vip_swap(38) one_vip_swap(39) one_vip_swap(40) one_vip_swap(41) one_vip_swap(42) one_vip_swap(43) one_vip_swap(44) one_vip_swap(45) one_vip_swap(46) one_vip_swap(47) one_vip_swap(48) one_vip_swap(49) #endif ASSERT(VIP_COUNT == 10) ret next_vip: ld a, [vip_idx] ld c, a inc a cp VIP_COUNT jr c, 1f ld a, 0 1: ld [vip_idx], a ld hl, vip_list ld b, 0 add hl, bc add hl, bc add hl, bc add hl, bc push hl pop ix ld a, [ix + 0] ld [currmem], a ld l, [ix + 1] ld h, [ix + 2] ld a, [ix + 3] save_ahl(currfreq) call freq2div save_ahl(tx_divisor) call default_rptr call lookup_rfc call change_synth ret save: ld a, [digidx] or a jr nz, 1f ld a, [currmem] jr 2f 1: call a2i ld a, l 2: cp 100 jr c, 1f ld a, 0 1: ld [currmem], a ld b, 0 load_ahl(tx_sub) or h or l jr z, 1f set BIT_RPTR, b 1: ld a, b ld [memflags], a call redraw 7: ld a, [memflags] ld b, a ld a, [key_time] cp 2 jr c, 1f set BIT_NOSCAN, b 1: ld a, [key_time] cp 3 jr c, 1f set BIT_EMPTY, b 1: ld a, [memflags] cp b jr z, 1f ld a, b ld [memflags], a call redraw 1: ld a, [keydown] or a jr nz, 7b ld a, -1 ld [key], a ld a, [currmem] ld b, 0 ld c, a ld hl, memories add hl, bc add hl, bc add hl, bc add hl, bc push hl pop ix ld a, [memflags] ld [ix + 0], a load_ahl(currfreq) ld [ix + 1], l ld [ix + 2], h ld [ix + 3], a call save_nvdata ret def_memo: call clear_buffer call scanner_stop ld a, 3 ld [adj_feedback], a call redraw 1: ld a, [key_time] cp 2 jr nc, 1f ! set default ld a, [keydown] or a jr nz, 1b ld a, -1 ld [key], a ld a, 0 ld [adj_feedback], a ld a, [defmem] jp gomem_a 1: ld a, [currmem] ld [defmem], a ld a, 4 ld [adj_feedback], a call redraw 1: ld a, [keydown] or a jr nz, 1b ld a, 0 ld [adj_feedback], a ret up_memo: call clear_buffer call scanner_stop ld e, 102 2: dec e jr z, 8f ld a, [currmem] inc a cp 100 jr c, 1f ld a, 0 1: ld [currmem], a call getmemflags and MEM_EMPTY jr nz, 2b ld a, [currmem] jp gomem_a 8: ld a, -1 ld [currmem], a ret dn_memo: call clear_buffer call scanner_stop ld e, 102 2: dec e jr z, 8f ld a, [currmem] dec a cp 100 jr c, 1f ld a, 99 1: ld [currmem], a call getmemflags and MEM_EMPTY jr nz, 2b ld a, [currmem] jp gomem_a 8: ld a, -1 ld [currmem], a ret getmemflags: ld b, 0 ld c, a ld hl, memories add hl, bc add hl, bc add hl, bc add hl, bc ! 4 bytes per memory push hl pop ix ! ! First byte misc info ! ld a, [ix + 0] ret gomem: 1: ld a, [key_time] or a jp nz, save ld a, [keydown] or a jr nz, 1b ld a, -1 ld [key], a ld a, [digidx] cp 0 jp z, next_vip call a2i ld a, l cp 100 jr c, 1f ld a, 0 1: call gomem_a call remember_vip ret gomem_a: ld [currmem], a ld b, 0 ld c, a ld hl, memories add hl, bc add hl, bc add hl, bc add hl, bc ! 4 bytes per memory push hl pop ix ! ! First byte misc info ! ld a, [ix + 0] ld [memflags], a and MEM_RPTR imm_ahl(0) jr z, 1f imm_ahl(RPTR_SUB) call freq2div 1: save_ahl(tx_sub) ! ! Next 3 bytes frequency in binary Hz ! ld l, [ix + 1] ld h, [ix + 2] ld a, [ix + 3] save_ahl(currfreq) call freq2div save_ahl(tx_divisor) call lookup_rfc call change_synth ret insdig: ld e, a ld a, [digidx] cp 16 jr nc, 1f ld hl, digbuf ld b, 0 ld c, a add hl, bc inc a ld [hl], e ld [digidx], a 1: call scanner_stop ret backspace: ld a, 0 ld [vip_idx], a call scanner_stop ld a, [digidx] or a jr z, 1f #if 0 sub 1 adc 0 #else ld a, 0 ! Brute force clear all #endif ld [digidx], a ret 1: ld a, [dpymode] or a jp nz, clear_setting ret monitor_audio: ld a, [squelch_forced] xor 1 ld [squelch_forced], a ld hl, segments + (SEG_STAR / 8) and 1 jr z, 1f set SEG_STAR % 8, [hl] jr 2f 1: res SEG_STAR % 8, [hl] 2: load_ahl(tx_sub) or h or l jr z, 1f ! Simplex. No channel change load_abc(tx_sub) ld e, a load_ahl(tx_divisor) and a sbc hl, bc sbc e save_ahl(tx_divisor) call lookup_rfc call change_synth ! Duplex, peek repeater input 1: call redraw ld a, [keydown] or a jr nz, 1b ld a, -1 ld [key], a load_ahl(tx_sub) or h or l jr z, 1f load_abc(tx_sub) ! Back to repeater output. ld e, a load_ahl(tx_divisor) add hl, bc adc e save_ahl(tx_divisor) call lookup_rfc call change_synth call redraw 1: ret restart_prom: 1: ld a, [keydown] or a jp nz, 1b ! wait release jp 0x0000 def_sqlv: call clear_buffer ld a, 3 ld [adj_feedback], a call redraw 1: ld a, [key_time] cp 2 jr nc, 1f ! set default ld a, [keydown] or a jr nz, 1b ld a, -1 ld [key], a ld a, [defsq] ld [squelch_limit_open], a sub 8 ld [squelch_limit_close], a ld a, 0 ld [adj_feedback], a ld a, 0 ld [squelch_forced], a ! Adjusting opened sq removes hard open. ld hl, segments + (SEG_STAR / 8) res SEG_STAR % 8, [hl] ret 1: ld a, [squelch_limit_open] ld [defsq], a ld a, 4 ld [adj_feedback], a call redraw 1: ld a, [keydown] or a jr nz, 1b ld a, 0 ld [adj_feedback], a ret up_sqlv: call clear_buffer ld a, 1 jr 1f dn_sqlv: call clear_buffer ld a, -1 1: push af ld hl, squelch_limit_open add [hl] ld [hl], a pop af ld hl, squelch_limit_close add [hl] ld [hl], a ld a, 0 ld [squelch_forced], a ! Adjusting opened sq removes hard open. ld hl, segments + (SEG_STAR / 8) res SEG_STAR % 8, [hl] ret up_rfc: ld a, 1 jr 1f dn_rfc: ld a, -1 1: ld hl, rfc add [hl] ld [hl], a call save_rfc ret def_vola: call clear_buffer ld a, 3 ld [adj_feedback], a call redraw 1: ld a, [key_time] cp 2 jr nc, 1f ! set default ld a, [keydown] or a jr nz, 1b ld a, -1 ld [key], a ld a, 0 ld [adj_feedback], a ld a, [defvola] jp set_vola_default 1: ld a, [volume] ld [defvola], a ld a, 4 ld [adj_feedback], a call redraw 1: ld a, [keydown] or a jr nz, 1b ld a, 0 ld [adj_feedback], a ret set_vola: ld a, 0 jr 1f up_vola: ld a, [dpymode] cp 1 jp z, up_rfc ld a, 1 jr 1f dn_vola: ld a, [dpymode] cp 1 jp z, dn_rfc ld a, -1 1: ld hl, volume add [hl] set_vola_default: cp 10 jr z, 1f ! 9 -> 10 jr c, 2f ! 0 -> -1 ld a, 0 jr 2f 1: ld a, 9 2: ld [volume], a cp 0 jr z, 1f cp 1 jr z, 2f sub 2 ! 9 - 2 -> 7 and 7 ld b, a di ld a, [output_0] and ~O0_VOLUME and ~O0_INH or b ld [output_0], a out [OUT0], a ei ret 1: di ld a, [output_0] and ~O0_VOLUME or O0_INH ld [output_0], a out [OUT0], a ei ret 2: di ld a, [output_0] and ~O0_VOLUME and ~O0_INH ld [output_0], a out [OUT0], a ei ret def_freq: call clear_buffer call scanner_stop ld a, 3 ld [adj_feedback], a call redraw 1: ld a, [key_time] cp 2 jr nc, 1f ! set default ld a, [keydown] or a jr nz, 1b ld a, -1 ld [key], a ld a, 0 ld [adj_feedback], a ld a, -1 ld [currmem], a load_ahl(deffreq) save_ahl(currfreq) call freq2div save_ahl(tx_divisor) call default_rptr call lookup_rfc call change_synth ret 1: load_ahl(currfreq) save_ahl(deffreq) ld a, 4 ld [adj_feedback], a call redraw 1: ld a, [keydown] or a jr nz, 1b ld a, 0 ld [adj_feedback], a ret up_freq: call clear_buffer call scanner_stop ld bc, 1 up_freq_bc: load_ahl(tx_divisor) add hl, bc adc 0 and 1 ! only 17-bit divisor save_ahl(tx_divisor) call div2freq save_ahl(currfreq) call default_rptr call lookup_rfc call change_synth ret dn_freq: call clear_buffer call scanner_stop load_ahl(tx_divisor) ld bc, 0 scf sbc hl, bc sbc 0 and 1 ! only 17-bit divisor save_ahl(tx_divisor) call div2freq save_ahl(currfreq) call default_rptr call lookup_rfc call change_synth ret clear_buffer: ld a, 0 ld [digidx], a ret pttcheck: ld a, [pttdn] or a ret z ld hl, indicators res BIT_CALL, [hl] ld a, 0 ld [call_dpyed], a call tx_on jp c, tx_error di ld a, [output_0] and ~(O0_CCIRC | O0_MICM) ! No tones, no mic mute ld [output_0], a out [OUT0], a ei call battcheck ld a, [seconds] ld e, a dec e 1: ld a, [seconds] cp e jr z, 2f ld e, a push de call battcheck call redraw pop de 2: ld a, [pttdn] or a jp nz, 1b call tx_off call redraw call remember_vip ret !---------------------------------------------------------------------- ! ! Powerdown ! powerdown: di ld a, O1_TXOFF out [OUT1], a ld a, PB_PWROFF out [PIO+BDATA], a halt jp powerdown !---------------------------------------------------------------------- ! ! MBUS putchar, character in c ! putchar: ld hl, mbustx_cnt putchar_1: ld a, [hl] inc a jr z, putchar_1 ! wait until not full di ld a, [hl] inc [hl] or a jr z, putchar_start ! tx not active, go start it ld hl, [mbustx_wp] ld [hl], c inc l ld [mbustx_wp], hl ei ret putchar_start: ld a, c out [SIO+BDATA], a ld a, 25 ld [mbus_timer], a putchar_out: ei ret iputc: push af ld a, [mbustx_cnt] inc a jr z, 1f ! full ld [mbustx_cnt], a dec a jr z, 2f ! tx not active, go start it pop af push hl ld hl, [mbustx_wp] ld [hl], a inc l ld [mbustx_wp], hl pop hl ret 1: pop af ret 2: pop af out [SIO+BDATA], a ld a, 25 ld [mbus_timer], a ret getchar: ld hl, mbusrx_cnt ld a, [hl] or a jr z, getchar di dec [hl] ld hl, [mbusrx_rp] ld a, [hl] inc l ld [mbusrx_rp], hl ei ret .align 8 keytbl: .byte 'Z','Z','Z','Z','Z','Z','Z','Z' .byte 'Z','Z','Z','Z','+','-','?','B' .byte 'E','*', 0 ,'#','R', 7 , 8 , 9 .byte 'S', 4 , 5 , 6 ,'C', 1 , 2 , 3 keypad: ld hl, indicators res BIT_CALL, [hl] ld a, 0 ld [key_timer], a ld [key_time], a ld [call_dpyed], a call blip ld hl, 100 * 5 ld [light_ltimer], hl ld hl, indicators set BIT_LCDLIGHT, [hl] set BIT_KEYLIGHT, [hl] ! ! strobe the data into shifter ! ld a, O2_KEYPAD out [OUT2], a ld a, O2_KEYPAD | O2_CLK out [OUT2], a ld a, O2_KEYPAD out [OUT2], a ld a, O2_LCD1 out [OUT2], a in a, [PIO+BDATA] ! from LDR and PB_DCU ld [dark], a ! ! shift 5 keycode bits to l ! ld l, 0 ! collect bits here ld h, 5 ! this many 1: ld a, O2_LCD1 | O2_CLK out [OUT2], a ld a, O2_LCD1 out [OUT2], a in a, [PIO+BDATA] and PB_DCU sub 1 rl l dec h jr nz, 1b ld h, HI(keytbl) ld a, [hl] ! map code to character ld [lastkey], a cp 'B' jr z, 1f cp '*' jr z, 1f cp '#' jr z, 1f jr 2f 1: ld [key], a ! little button, * and # dont repeat ret 2: cp 10 ! digit ? jr nc, 1f ! Yes, downtime determines 0..9 or function. ld [lastdigit], a cp 1 jr z, 2f cp 4 jr z, 2f cp 7 jr z, 3f cp 8 jr z, 3f cp 9 jr z, 3f cp 0 jr z, 3f ld a, 255 ! 2356 memory/freq adjust ld [key_blips], a ld a, 50 ld [key_timer], a ld a, 33 ld [key_speed], a ret 3: ld a, 2 ! 7890 default buttons ld [key_blips], a ld a, 50 ld [key_timer], a ld a, 100 ld [key_speed], a ret 2: ld a, 8 ! 14 squelch adjust ld [key_speed], a ld a, 50 ld [key_timer], a ld a, 1 ld [key_blips], a ret 1: ld [key], a cp '+' jr z, 1f cp '-' jr z, 1f cp 'S' jr z, 2f ld a, 100 ld [key_timer], a ld a, 100 ld [key_speed], a ld a, 4 ld [key_blips], a ret ! Not digit nor +/- 2: ld a, 100 ld [key_timer], a ld a, 100 ld [key_speed], a ld a, 2 ld [key_blips], a ret 1: ld a, 50 ld [key_timer], a ld a, 20 ld [key_speed], a ld a, 255 ld [key_blips], a ret blip: push hl ld hl, MT_600HZ ld d, 3 call start_marker_tone pop hl ret bleep: push hl ld hl, MT_300HZ ld d, 100 call start_marker_tone pop hl ret ding: push bc di call stop_marker_tone ld a, [output_0] push af and ~O0_AUDIOC out [OUT0], a and ~O0_INH out [OUT0], a or O0_VOLUME out [OUT0], a ld [output_0], a ld a, 1 ld [mton], a ei ld b, 5 2: push hl ld hl, MT_1200HZ ld d, 5 call start_marker_tone pop hl 1: ld a, [mt_timer] or a jr nz, 1b push hl ld hl, MT_1400HZ ld d, 5 call start_marker_tone pop hl 1: ld a, [mt_timer] or a jr nz, 1b djnz 2b di pop af ld [output_0], a out [OUT0], a ld a, 0 ld [mton], a ei pop bc ret ! ! Duration in 10ms in d, pitch in hl ! start_marker_tone: ld a, 0 ld [mt_timer], a ld a, l out [TMR + 1], a ld a, h out [TMR + 1], a ! pitch ld hl, output_0 set O0_MTCBIT, [hl] ld a, d ld [mt_timer], a ! duration in 10ms units ret stop_marker_tone: ld a, 0 ld [mt_timer], a ld a, [output_0] and ~O0_MTC ld [output_0], a out [OUT0], a ! Cut tone from local audio ld a, 0x04 out [TMR + 1], a ! But it leaks anyway, highest possible ld a, 0x00 out [TMR + 1], a ! tone causes the least harm... brrh. ret ! 0 -> 8 -> 0 ! 1 -> 9 -> 0 ! 2 -> 10 -> 0 ! 7 -> 15 -> 0 ! 8 -> 16 -> 1 ! 9 -> 17 -> 1 dpysig: add 8 jr nc, 1f ld a, 0xff 1: srl4 jp dpydig dpyval255: push bc ld b, -1 1: inc b ! hundreds sub 100 jr nc, 1b add 100 ld c, -1 1: inc c sub 10 ! tens jr nc, 1b add 10 + '0' push af ! ones ld a, 0 or b jr nz, 1f ld b, ' ' or c jr nz, 1f ld c, ' ' 1: ld a, b call dpydig ld a, c call dpydig pop af call dpydig pop bc ret dpyval99: ld c, -1 1: inc c sub 10 jr nc, 1b add 10 push af ld a, c or a jr nz, 1f ld a, ' ' 1: call dpydig pop af call dpydig ret dpyval99nzb: ld c, -1 1: inc c sub 10 jr nc, 1b add 10 push af ld a, c call dpydig pop af call dpydig ret dpyhex: push af srl4 call 1f pop af 1: and 0xf cp 10 jr c, 1f add 'A' - 10 - '0' 1: add '0' call dpydig ret dpyhex_blankF: push af srl4 call 1f pop af 1: and 0xf cp 0xf jr nz, 1f ld a, ' ' jp dpydig 1: cp 10 jr c, 1f add 'A' - 10 - '0' 1: add '0' jp dpydig !---------------------------------------------------------------------- ! ! Build up display buffer ! redraw: ! Icons, repeater, power, battery load_ahl(tx_sub) or h or l sub 1 ccf ld a, SEG_MAST call segment_onoff ld a, [txpwr] rla push af ld a, SEG_CAR_U call segment_onoff pop af rla ld a, SEG_CAR_D call segment_onoff ! Upper row, volume squelch srssi ld de, segs_u_digit_4 ld a, [volume] call dpydig ! volume ld a, [squelch_limit_open] call dpydiv99 ! squelch setting ld a, [txon] or a ld a, [srssi] jr z, 1f ld a, [txpwr] 1: call dpydiv99 ! srssi or txpwr ! Lower left, 2 digits, lower right, 8 digits ld de, segs_dl_digit_1 ld a, [call_dpyed] or a jp nz, call2dpy ld a, [digidx] ! how many digits or a jp nz, 9f ld a, [dpymode] or a jr z, 1f call stat2dpy ! show stuff jp 8f 1: ld a, [currmem] cp 100 jr c, 1f ld a, '-' call dpydig ld a, '-' call dpydig ld b, ' ' jr 2f 1: call dpyval99 ld b, '=' ld a, [memflags] and MEM_EMPTY jr nz, 2f ld b, '-' ld a, [memflags] and MEM_NOSCAN jr nz, 2f ld b, ' ' 2: ld a, b call dpydig ld a, [adj_feedback] or a jr nz, 2f call div2dpy ! show frequency jr 8f 2: cp 1 jr nz, 2f call sput ; .asciz " rEJECt" jr 8f 2: cp 2 jr nz, 2f call sput ; .asciz "CLEArEd" jr 8f 2: cp 3 jr nz, 2f call sput ; .asciz "dEFAULt" jr 8f 2: ! 4 call sput ; .asciz " StorEd" jr 8f 9: ld ix, digbuf ld a, [digidx] cp 10 ! positions max jr c, 1f ld a, 10 1: ld b, a ! to show neg add 10 ld c, a ! to blank 1: ld a, [ix] inc ix call dpydig djnz 1b ld a, c or a jr z, 8f ld b, a 1: ld a, ' ' call dpydig djnz 1b 8: ld hl, sir set DPYSIR, [hl] ret call2dpy: call sput ; .asciz "CALL " ld a, [packet_good + 0]; and 0xF; call dpydig ld a, [packet_good + 1]; srl4; call dpydig ld a, [packet_good + 1]; and 0xF; call dpydig ld a, [packet_good + 2]; srl4; call dpydig ld a, [packet_good + 2]; and 0xF; call dpydig jp 8b display: ld hl, segments ld a, O2_LCD2 out [OUT2], a ld a, O2_LCD1 ! start 1st half of LCD1 call display_group call display_bit_zero ld a, O2_LCD2 ! start 1st half of LCD2 call display_group call display_bit_zero ld a, O2_LCD1 ! start 2nd half of LCD1 call display_group call display_bit_one ld a, O2_LCD2 ! start 2nd half of LCD2 call display_group call display_bit_one ld a, O2_LCD1 ! unselect LATCH out [OUT2], a call display_byte ld a, O2_LATCH ! select LATCH out [OUT2], a ld a, O2_LCD1 ! unselect LATCH out [OUT2], a ret display_group: out [OUT2], a call display_bit_zero call display_byte call display_byte call display_byte call display_byte ret ! ! 4032000 Hz pclk ! 0.24 us T-state ! display_byte: ld c, [hl] inc hl ld b, 8 1: srl c call display_bit djnz 1b ret display_bit: jr nc, display_bit_zero display_bit_one: or O2_DP display_bit_zero: or O2_CLK out [OUT2], a ! data & clock set 11 T 2.7 us and ~O2_CLK out [OUT2], a ! clock edge 2.7 us and ~O2_DP out [OUT2], a ! clear data 2.7 us ret puthex: push bc ld a, c srl4 call 1f pop bc ld a, c 1: and 0xf cp 10 jr c, 1f add 'A' - 10 - '0' 1: add '0' ld c, a call putchar ret bitmasks: .byte 1, 2, 4, 8, 0x10, 0x20, 0x40, 0x80 segment_onoff: jr nc, segment_off segment_on: ld h, HI(segments) ; ASSERT(LO(segments) == 0) ld l, a srl l srl l srl l ! byte ptr ok ! Uhhuh. Maybe not so bad as it looks :) and 7 ! bit number cp 4; jr nc, 4f ! >= 4 cp 2; jr nc, 2f ! >= 2, < 4 cp 1; jr nc, 1f ! >= 1, < 2 set 0, [hl] ; ret 1: set 1, [hl] ; ret 2: cp 3; jr nc, 3f ! >= 3, < 4 set 2, [hl] ; ret 3: set 3, [hl] ; ret 4: cp 6; jr nc, 6f ! >= 6 cp 5; jr nc, 5f ! >= 5, < 6 set 4, [hl] ; ret 5: set 5, [hl] ; ret 6: cp 7; jr nc, 7f ! >= 7 set 6, [hl] ; ret 7: set 7, [hl] ; ret segment_off: ld h, HI(segments) ; ASSERT(LO(segments) == 0) ld l, a srl l srl l srl l ! byte ptr ok ! Uhhuh. Maybe not so bad as it looks :) and 7 ! bit number cp 4; jr nc, 4f ! >= 4 cp 2; jr nc, 2f ! >= 2, < 4 cp 1; jr nc, 1f ! >= 1, < 2 res 0, [hl] ; ret 1: res 1, [hl] ; ret 2: cp 3; jr nc, 3f ! >= 3, < 4 res 2, [hl] ; ret 3: res 3, [hl] ; ret 4: cp 6; jr nc, 6f ! >= 6 cp 5; jr nc, 5f ! >= 5, < 6 res 4, [hl] ; ret 5: res 5, [hl] ; ret 6: cp 7; jr nc, 7f ! >= 7 res 6, [hl] ; ret 7: res 7, [hl] ; ret ! ! Calculate R and misc stuff ! ! 25 kHz ! 512, 12800 / 512 quot 25 rem 0, /= 25 shift 0 ! ! 12.5 kHz ! 1024, 12800 / 1024 quot 12 rem 512 ! 12800 / 512 quot 25 rem 0, /= 25 shift 1 ! ! 6.25 kHz ! 2048, 12800 / 2048 quot 6 rem 512 ! 12800 / 1024 quot 12 rem 512 ! 12800 / 512 quot 25 rem 0, /= 25 shift 2 ! ! 3.125 kHz ! 4096, 12800 / 4096 quot 3 rem 512 ! 12800 / 2048 quot 6 rem 512 ! 12800 / 1024 quot 12 rem 512 ! 12800 / 512 quot 25 rem 0, /= 25 shift 3 ! ! 10 kHz ! 1280, 12800 / 1280 quot 10 rem 0, /= 10 shift 0 ! ! 5 kHz ! 2560, 12800 / 2560 quot 5 rem 0, 5 too small, use /= 10 shift 1 ! ! reset_synth_oops: ld de, DEF_BSTEP ld [bstep_R], de reset_synth: ld de, [bstep_R] ld b, 0 ! try with no shift, will be 0..7 2: ld hl, 12800 ! Reference XO ld c, 0 1: inc c ! increment x2y-divider, will be from 1.. jr z, reset_synth_oops and a sbc hl, de jr z, 1f ! exact ! jr nc, 1b ! division not complete inc b ! try with more shift. jr z, reset_synth_oops srl d rr e ! try divide with smaller value ld a, e or d jr z, reset_synth_oops jr 2b 1: ld a, c cp 10 jr nc, 2f inc b ! hack in 5kHz on 70cm by changing 5/0 to 10/1 sla c jr nz, 1b jp reset_synth_oops 2: ld [bstep_cfg], bc load_ahl(currfreq) call freq2div save_ahl(tx_divisor) imm_ahl(BAND_START) call freq2div save_ahl(tx_divisor_lo) imm_ahl(BAND_END) call freq2div save_ahl(tx_divisor_hi) imm_ahl(RX_SUB) call freq2div save_ahl(rx_sub) load_ahl(tx_sub) ! current offset or h or l imm_ahl(0) ! assume was simplex jr z, 1f imm_ahl(RPTR_SUB) ! no, calc changed NA offset call freq2div 1: save_ahl(tx_sub) call rxmode_synth call lookup_rfc call change_synth ret ! ! Configure RX and TX synths ! txmode_synth: ld c, 0xf8 ! Max deviation (b7..b4), TX synth operational (b3,b2) jp 9f rxmode_synth: ld c, 0xf4 ! Max deviation (b7..b4), TX synth OFF (b3,b2) 9: ld a, O1_TXOFF out [OUT1], a ld b, 8 call send_to_synth or O1_SCE call strobe_to_synth ld hl, [bstep_R] ! channel spacing ld c, h ld b, 8 ! has excess bits... they overflow ok call send_to_synth ld c, l ld b, 8 call send_to_synth call one_to_synth ! single "1" bit - to R register or O1_SRE | O1_STE call strobe_to_synth ! both R same ret change_synth: load_ahl(tx_divisor) ld e, a ld d, O1_STE call send_NA_to_synth load_abc(rx_sub) add hl, bc adc e ! EHL + ABC -> EHL ld e, a ld d, O1_SRE call send_NA_to_synth ret ! ! 10 bits of N, 7 bits of A, single zerobit to selector ! ! RD58 NNNNNNNNNNAAAAAAA ! GFEDCBA9876543210 effective bit numbers ! EHHHHHHHHLLLLLLLL ! ! RB58S ! RC58 NNNNNNNNNN0AAAAAA ! FEDCBA9876 543210 effective bit numbers ! HHHHHHHHLL LLLLLL ! ! NA in EHL register triple send_NA_to_synth: ld a, O1_TXOFF out [OUT1], a #if PRESCALER == 128 ld c, e rrc c ! Align lowest bit for MSb first shifting just 1 bit ld b, 1 call send_to_synth ! send MSb (lowest of e) #endif ld c, h ld b, 8 call send_to_synth ld c, l #if PRESCALER == 128 ld b, 8 call send_to_synth #else ld b, 2 call send_to_synth call zero_to_synth ! pad for 64/65 prescaler, instead of linear 128/129 ld b, 6 call send_to_synth #endif call zero_to_synth ! single "0" bit - to A/N registers or d call strobe_to_synth ! which synth ret strobe_to_synth: out [OUT1], a and ~(O1_SCE | O1_STE | O1_SRE | O1_SD) out [OUT1], a ret send_to_synth: 2: rl c jr c, 1f call zero_to_synth djnz 2b ret 1: call one_to_synth djnz 2b ret zero_to_synth: and ~O1_SD out [OUT1], a or O1_CLK out [OUT1], a and ~(O1_CLK) out [OUT1], a ret one_to_synth: or O1_SD out [OUT1], a or O1_CLK out [OUT1], a and ~(O1_CLK) out [OUT1], a ret !---------------------------------------------------------------------- ! ! XXYYZZ ! 9876543210 ! ! V P S vola pwr srssi ! CH 433500 channel frequency ! ! down left digit-area segs_dl_digit_1: .byte 56, 57, 58, 59, 120, 121, 122 segs_dl_digit_0: .byte 60, 61, 62, 63, 124, 125, 126 ! down right digit-area segs_dr_digit_7: .byte 0, 1, 2, 3, 64, 65, 66 segs_dr_digit_6: .byte 4, 5, 6, 7, 68, 69, 70 segs_dr_digit_5: .byte 8, 9, 10, 11, 72, 73, 74 segs_dr_digit_4: .byte 12, 13, 14, 15, 76, 77, 78 segs_dr_digit_3: .byte 16, 17, 18, 19, 80, 81, 82 segs_dr_digit_2: .byte 20, 21, 22, 23, 84, 85, 86 segs_dr_digit_1: .byte 24, 25, 26, 27, 88, 89, 90 segs_dr_digit_0: .byte 28, 29, 30, 31, 92, 93, 94 ! upper digit-area segs_u_digit_5: .byte 32, 33, 34, 35, 96, 97, 98 segs_u_digit_4: .byte 36, 37, 38, 39, 100, 101, 102 segs_u_digit_3: .byte 40, 41, 42, 43, 104, 105, 106 segs_u_digit_2: .byte 44, 45, 46, 47, 108, 109, 110 segs_u_digit_1: .byte 48, 49, 50, 51, 112, 113, 114 segs_u_digit_0: .byte 52, 53, 54, 55, 116, 117, 118 ! ! - 4 ! | | 0 3 ! - 5 ! | | 1 2 ! - 6 .align 8 font: .byte 0x5f ! 0 0 1 2 3 4 - 6 .byte 0x0c ! 1 - - 2 3 - - - .byte 0x7a ! 2 - 1 - 3 4 5 6 .byte 0x7c ! 3 - - 2 3 4 5 6 .byte 0x2d ! 4 0 - 2 3 - 5 - .byte 0x75 ! 5 0 - 2 - 4 5 6 .byte 0x77 ! 6 0 1 2 - 4 5 6 .byte 0x1c ! 7 - - 2 3 4 - - .byte 0x7f ! 8 0 1 2 3 4 5 6 .byte 0x7d ! 9 0 - 2 3 4 5 6 .byte 0x3f ! A 0 1 2 3 4 5 - .byte 0x67 ! b 0 1 2 - - 5 6 .byte 0x53 ! C 0 1 - - 4 - 6 .byte 0x6e ! d - 1 2 3 - 5 6 .byte 0x73 ! E 0 1 - - 4 5 6 .byte 0x33 ! F 0 1 - - 4 5 - .byte 0x57 ! G 0 1 2 - 4 - 6 .org font + ' ' .byte 0x00 ! - - - - - - - .byte 0x0c ! ! - - 2 3 - - - .byte 0x09 ! " 0 - - 3 - - - .byte 0x66 ! # - 1 2 - - 5 6 .byte 0x25 ! $ 0 - 2 - - 5 - .byte 0x05 ! % 0 - 2 - - - - .byte 0x6a ! & - 1 - 3 - 5 6 .byte 0x08 ! ' - - - 3 - - - .byte 0x0c ! ( - - 2 3 - - - .byte 0x03 ! ) 0 1 - - - - - .byte 0x70 ! * - - - - 4 5 6 .byte 0x23 ! + 0 1 - - - 5 - .byte 0x02 ! , - 1 - - - - - .byte 0x20 ! - - - - - - 5 - .byte 0x02 ! . - 1 - - - - - .byte 0x2a ! / - 1 - 3 - 5 - .byte 0x5f ! 0 0 1 2 3 4 - 6 .byte 0x0c ! 1 - - 2 3 - - - .byte 0x7a ! 2 - 1 - 3 4 5 6 .byte 0x7c ! 3 - - 2 3 4 5 6 .byte 0x2d ! 4 0 - 2 3 - 5 - .byte 0x75 ! 5 0 - 2 - 4 5 6 .byte 0x77 ! 6 0 1 2 - 4 5 6 .byte 0x1c ! 7 - - 2 3 4 - - .byte 0x7f ! 8 0 1 2 3 4 5 6 .byte 0x7d ! 9 0 - 2 3 4 5 6 .byte 0x50 ! : - - - - 4 - 6 .byte 0x48 ! ; - - - 3 - - 6 .byte 0x2c ! < - - 2 3 - 5 - .byte 0x60 ! = - - - - - 5 6 .byte 0x23 ! > 0 1 - - - 5 - .byte 0x3a ! ? - 1 - 3 4 5 - .byte 0x7e ! @ - 1 2 3 4 5 6 .byte 0x3f ! A 0 1 2 3 4 5 - .byte 0x67 ! b 0 1 2 - - 5 6 .byte 0x53 ! C 0 1 - - 4 - 6 .byte 0x6e ! d - 1 2 3 - 5 6 .byte 0x73 ! E 0 1 - - 4 5 6 .byte 0x33 ! F 0 1 - - 4 5 - .byte 0x57 ! G 0 1 2 - 4 - 6 .byte 0x2f ! H 0 1 2 3 - 5 - .byte 0x0c ! I - - 2 3 - - - .byte 0x4e ! J - 1 2 3 - - 6 .byte 0x2f ! K - 1 2 3 - - 6 .byte 0x43 ! L 0 1 - - - - 6 .byte 0x1f ! M 0 1 2 3 4 - - .byte 0x26 ! N - 1 2 - - 5 - .byte 0x5f ! O 0 1 2 3 4 - 6 .byte 0x3b ! P 0 1 - 3 4 5 - .byte 0x3d ! Q 0 - 2 3 4 5 - .byte 0x1b ! R 0 1 - 3 4 - - .byte 0x75 ! S 0 - 2 - 4 5 6 .byte 0x13 ! T 0 1 - - 4 - - .byte 0x4f ! U 0 1 2 3 - - 6 .byte 0x4f ! V 0 1 2 3 - - 6 .byte 0x4f ! W 0 1 2 3 - - 6 .byte 0x70 ! X - - - - 4 5 6 .byte 0x6d ! Y 0 - 2 3 - 5 6 .byte 0x7a ! Z - 1 - 3 4 5 6 .byte 0x53 ! [ 0 1 - - 4 - 6 .byte 0x25 ! \ 0 - 2 - - 5 - .byte 0x5c ! ] - - 2 3 4 - 6 .byte 0x10 ! ^ - - - - 4 - - .byte 0x40 ! _ - - - - - - 6 .byte 0x01 ! ` 0 - - - - - - .byte 0x26 ! a - 1 2 - - 5 - .byte 0x67 ! b 0 1 2 - - 5 6 .byte 0x62 ! c - 1 - - - 5 6 .byte 0x6e ! d - 1 2 3 - 5 6 .byte 0x62 ! e - 1 - - - 5 6 .byte 0x33 ! f 0 1 - - 4 5 - .byte 0x7d ! g 0 - 2 3 4 5 6 .byte 0x27 ! h 0 1 2 - - 5 - .byte 0x04 ! i - - 2 - - - - .byte 0x44 ! j - - 2 - - - 6 .byte 0x27 ! k .byte 0x42 ! l - 1 - - - - 6 .byte 0x26 ! m - 1 2 - - 5 - .byte 0x26 ! n - 1 2 - - 5 - .byte 0x66 ! o - 1 2 - - 5 6 .byte 0x3b ! p 0 1 - 3 4 5 - .byte 0x3d ! q 0 - 2 3 4 5 - .byte 0x22 ! r - 1 - - - 5 - .byte 0x75 ! s 0 - 2 - 4 5 6 .byte 0x63 ! t 0 1 - - - 5 6 .byte 0x46 ! u - 1 2 - - - 6 .byte 0x46 ! v - 1 2 - - - 6 .byte 0x46 ! w - 1 2 - - - 6 .byte 0x06 ! x - 1 2 - - - - .byte 0x2d ! y 0 - 2 3 - 5 - .byte 0x60 ! z - - - - - 5 6 .byte 0x62 ! { - 1 - - - 5 6 .byte 0x02 ! | - 1 - - - - - .byte 0x64 ! } - - 2 - - 5 6 .byte 0x10 ! ~ - - - - 4 - - .byte 0x00 ! ^? - 1 - 3 4 5 6 fontsize = . - font 1: .byte 0x00, 0x00, 0x01, 0x01, 0x02, 0x02, 0x02, 0x03, 0x03, 0x04 .byte 0x04, 0x04, 0x05, 0x05, 0x05, 0x06, 0x06, 0x07, 0x07, 0x07 .byte 0x08, 0x08, 0x09, 0x09, 0x09, 0x10, 0x10, 0x11, 0x11, 0x11 .byte 0x12, 0x12, 0x12, 0x13, 0x13, 0x14, 0x14, 0x14, 0x15, 0x15 .byte 0x16, 0x16, 0x16, 0x17, 0x17, 0x18, 0x18, 0x18, 0x19, 0x19 .byte 0x20, 0x20, 0x20, 0x21, 0x21, 0x21, 0x22, 0x22, 0x23, 0x23 .byte 0x23, 0x24, 0x24, 0x25, 0x25, 0x25, 0x26, 0x26, 0x27, 0x27 .byte 0x27, 0x28, 0x28, 0x29, 0x29, 0x29, 0x30, 0x30, 0x30, 0x31 .byte 0x31, 0x32, 0x32, 0x32, 0x33, 0x33, 0x34, 0x34, 0x34, 0x35 .byte 0x35, 0x36, 0x36, 0x36, 0x37, 0x37, 0x37, 0x38, 0x38, 0x39 .byte 0x39, 0x39, 0x40, 0x40, 0x41, 0x41, 0x41, 0x42, 0x42, 0x43 .byte 0x43, 0x43, 0x44, 0x44, 0x45, 0x45, 0x45, 0x46, 0x46, 0x46 .byte 0x47, 0x47, 0x48, 0x48, 0x48, 0x49, 0x49, 0x50, 0x50, 0x50 .byte 0x51, 0x51, 0x52, 0x52, 0x52, 0x53, 0x53, 0x54, 0x54, 0x54 .byte 0x55, 0x55, 0x55, 0x56, 0x56, 0x57, 0x57, 0x57, 0x58, 0x58 .byte 0x59, 0x59, 0x59, 0x60, 0x60, 0x61, 0x61, 0x61, 0x62, 0x62 .byte 0x62, 0x63, 0x63, 0x64, 0x64, 0x64, 0x65, 0x65, 0x66, 0x66 .byte 0x66, 0x67, 0x67, 0x68, 0x68, 0x68, 0x69, 0x69, 0x70, 0x70 .byte 0x70, 0x71, 0x71, 0x71, 0x72, 0x72, 0x73, 0x73, 0x73, 0x74 .byte 0x74, 0x75, 0x75, 0x75, 0x76, 0x76, 0x77, 0x77, 0x77, 0x78 .byte 0x78, 0x79, 0x79, 0x79, 0x80, 0x80, 0x80, 0x81, 0x81, 0x82 .byte 0x82, 0x82, 0x83, 0x83, 0x84, 0x84, 0x84, 0x85, 0x85, 0x86 .byte 0x86, 0x86, 0x87, 0x87, 0x87, 0x88, 0x88, 0x89, 0x89, 0x89 .byte 0x90, 0x90, 0x91, 0x91, 0x91, 0x92, 0x92, 0x93, 0x93, 0x93 .byte 0x94, 0x94, 0x95, 0x95, 0x95, 0x96, 0x96, 0x96, 0x97, 0x97 .byte 0x98, 0x98, 0x98, 0x99, 0x99, 0x99 dpydiv99: ld hl, 1b ld b, 0 ld c, a add hl, bc ld a, [hl] jp dpyhex ! digit or character in a ! location table in de ! de incremented to next position, ! hl & a destroyed dpydig: push bc ld h, HI(font) ; ASSERT(LO(font) == 0) ld l, a ld c, [hl] ! what segments (0..6) are lit, what are dim ld a, [de]; inc de; rr c; call segment_onoff ld a, [de]; inc de; rr c; call segment_onoff ld a, [de]; inc de; rr c; call segment_onoff ld a, [de]; inc de; rr c; call segment_onoff ld a, [de]; inc de; rr c; call segment_onoff ld a, [de]; inc de; rr c; call segment_onoff ld a, [de]; inc de; rr c; call segment_onoff pop bc ret tx_on: call scanner_stop load_abc(tx_sub) ld e, a load_ahl(tx_divisor) and a sbc hl, bc sbc e push hl ld d, a load_abc(tx_divisor_lo) ld e, a ld a, d and a sbc hl, bc sbc e ! tx-freq - low-limit pop bc ! DBC has now tx-freq ret c ! if below limit load_ahl(tx_divisor_hi) and a sbc hl, bc sbc d ! high-limit - tx-freq ret c ! if above limit di ld a, 1 ld [txon], a ld a, 100 ld [txtail_timer], a ! shall count 1 second after tx ends call stop_marker_tone ld a, [output_0] and ~ O0_AUDIOC and ~ O0_CCIRC ld [output_0], a out [OUT0], a ei #if 1 load_abc(tx_sub) ld e, a load_ahl(tx_divisor) and a ! clear carry sbc hl, bc sbc e save_ahl(tx_divisor) #endif ld a, O1_TXOFF out [OUT1], a ld a, 0 out [DA_TXPWR], a call txmode_synth call change_synth ld a, 0 out [OUT1], a ld a, [txpwr] out [DA_TXPWR], a ld hl, 1 ld [energy_unit_per_second], hl ld hl, indicators set BIT_ROAM, [hl] and a ! return carry clear ret tx_off: ld a, O1_TXOFF out [OUT1], a ld a, 0 out [DA_TXPWR], a ld hl, 1 ld [energy_unit_per_second], hl #if 1 load_abc(tx_sub) ld e, a load_ahl(tx_divisor) add hl, bc adc e save_ahl(tx_divisor) #endif call rxmode_synth call lookup_rfc call change_synth ld a, 0 ld [txon], a #if 0 ld hl, 0 ld [alert_ltimer], hl #endif ld hl, indicators res BIT_ROAM, [hl] ret ! ! Calculate binary value from unpacked string ! Return in CY AHL ! a2i: push ix push bc push de ld ix, digbuf ld a, [digidx] ld c, a ld a, 0 ! AHL starts from 0x000000 ld h, a ld l, a ld [digidx], a dec c jp z, a2i1 dec c jp z, a2i2 dec c jp z, a2i3 dec c jp z, a2i4 dec c jp z, a2i5 dec c jp z, a2i6 dec c jp z, a2i7 jp a2i0 ! more than 7, give 0 a2iOV: imm_ahl(0xFFFFFF) jp a2i0 a2i7: ld de, 0x4240 ld b, [ix] ! x 000 000 inc ix inc b jr 1f 2: add hl, de adc 0x0F ! 1 000 000 equals 0x 0F 4240 jp c, a2iOV 1: djnz 2b a2i6: ld de, 0x86a0 ! 100 000 equals 0x186a0, thus the adc 1... ld b, [ix] ! 0 x00 000 inc ix inc b jr 1f 2: add hl, de adc 1 jp c, a2iOV 1: djnz 2b a2i5: ld de, 10000 ld b, [ix] ! 0x0 000 inc ix inc b jr 1f 2: add hl, de adc 0 jp c, a2iOV 1: djnz 2b a2i4: ld de, 1000 ld b, [ix] ! 00x 000 inc ix inc b jr 1f 2: add hl, de adc 0 jp c, a2iOV 1: djnz 2b a2i3: ld de, 100 ld b, [ix] ! 000 x00 inc ix inc b jr 1f 2: add hl, de adc 0 jp c, a2iOV 1: djnz 2b a2i2: ld de, 10 ld b, [ix] ! 000 0x0 inc ix inc b jr 1f 2: add hl, de adc 0 jp c, a2iOV 1: djnz 2b a2i1: ld de, 1 ld b, [ix] ! 000 00x inc ix inc b jr 1f 2: add hl, de adc 0 jp c, a2iOV 1: djnz 2b a2i0: pop de pop bc pop ix ret ! AHL contains frequency in binary ! Multiply AHL by C, 1.. ! Result to CY AHL mul248: push bc push de ld e, l ld d, h ld b, a and a ! clear carry 1: dec c jr z, 1f adc hl, de adc b jr nc, 1b imm_ahl(0xFFFFFF) 1: pop de pop bc ret !---------------------------------------------------------------------- ! ! Divide AHL by C, result left in HL, remainder in A. ! ! Origin: Trash-80 Assembly Language Subroutines, William Barden 1982. ! div248: push bc ld b, 16 ! do this 16 times. 2: add hl, hl ! rotate AHL one bit adc a ! position to the left. sub c jr c, 1f inc hl ! set lsb of hl, a bit into quotient. djnz 2b jr 3f 1: add c ! oops, should not have subtracted. djnz 2b 3: pop bc ret ! ! freq / 25 * 2 = xxx ! AHL has freq in Hz ! freq2div: push bc push de ld bc, [bstep_cfg] call div248 ld e, 0 ! MSb inc b jr 2f 1: scf ! remainder * 2 + 1 rl a ! cp c ! compare with divider jr c, 3f sub c 3: ccf rl l ! and shift in rl h rl e 2: djnz 1b ld a, e cp (DIVMAX / 65536) + 1 ! 0 or 1 only possible jr c, 1f imm_ahl(DIVMAX) 1: pop de pop bc ret sput: 1: pop hl ld a, [hl] inc hl push hl or a jr z, 1f call dpydig jr 1b 1: ret clear_setting: ld a, [dpymode] ld b, 0 ld c, a sla c; rl b ! 2 sla c; rl b ! 4 sla c; rl b ! 8 sla c; rl b ! 16 ld ix, settings add ix, bc 1: ld a, [ix] inc ix or a jr nz, 1b ld l, [ix + 2] ld h, [ix + 3] ld a, 0 ld [hl], a ld a, h cp HI(hours) jr nz, 1f ld a, l cp LO(hours) jr nz, 1f ld a, 0 di ld [hours], a ld [minutes], a ld [seconds], a ld [sec100], a ei 1: call save_nvdata ret ret ! ! rfc rssi batt ! 123456 78 .align 4; settings: .asciz "???? " ; .word 0, 0 .align 4; .asciz "rFc" ; .word do_tunedpy, 0 .align 4; .asciz "SqL " ; .word do_bytedpy, squelch_limit_open .align 4; .asciz "tPc " ; .word do_bytedpy, txpwr .align 4; .asciz "bAtt " ; .word do_bytedpy, batt .align 4; .asciz "AGE " ; .word do_timedpy, hours .align 4; .asciz "id " ; .word do_iddpy, mycall .align 4; .asciz "SoFt "; .word do_hexdpy, versinfo .align 4; .asciz "Ph " ; .word do_pktdpy, packet_good .align 4; .asciz "Pt " ; .word do_pktdpy, packet_good + 3 .align 4; NUM_INFOS = (. - settings) / 16 stat2dpy: ld a, [dpymode] ld b, 0 ld c, a sla c; rl b ! 2 sla c; rl b ! 4 sla c; rl b ! 8 sla c; rl b ! 16 ld ix, settings add ix, bc 1: ld a, [ix] inc ix or a jr z, 1f call dpydig jr 1b 1: ld l, [ix + 0] ld h, [ix + 1] push hl ld l, [ix + 2] ld h, [ix + 3] ret ! 9876543210 ! rFc 84 121 do_tunedpy: ld a, [rfc] call dpyval255 ld a, ' ' call dpydig ld a, [rssi] call dpyval255 ret do_bytedpy: ld a, [hl] call dpyval255 ret do_hexdpy: ld a, [hl] call dpyhex ret do_pktdpy: ld a, [hl]; inc hl; push hl; call dpyhex_blankF; pop hl ld a, [hl]; inc hl; push hl; call dpyhex_blankF; pop hl ld a, [hl]; inc hl; push hl; call dpyhex_blankF; pop hl ret do_iddpy: ld a, [hl]; inc hl; push hl; call dpydig; pop hl ld a, [hl]; inc hl; push hl; call dpydig; pop hl ld a, [hl]; inc hl; push hl; call dpydig; pop hl ld a, [hl]; inc hl; push hl; call dpydig; pop hl ld a, [hl]; inc hl; push hl; call dpydig; pop hl ret do_timedpy: ld a, [hl] inc hl push hl call dpyval255 ld a, 'h' call dpydig pop hl ld a, [hl] call dpyval99nzb ! 11h32 ret ! Print tx_divisor as Hz, 7 digits, at de ! ! xxx * 25 / 2 = freq ! div2dpy: push bc push de ld a, ' ' ld [zeroblank], a load_ahl(tx_divisor) ld bc, [bstep_cfg] call mul248 inc b jr 2f 1: rr a rr h rr l and a 2: djnz 1b ld de, 10000 call divide ! result to c pop de ! get cursor push af ld a, c ! 10 MHz and up digits ld c, -1 1: inc c ! count GHz digit sub 100 jr nc, 1b add 100 call nextdig ! insert GHz ld c, -1 1: inc c ! count 100 MHz digit sub 10 jr nc, 1b add 10 call nextdig ! insert 100 MHz ld c, a call nextdig ! insert 10 MHz pop af push de ! display cursor ld de, 1000 call divide pop de call nextdig push de ld de, 100 call divide pop de call nextdig push de ld de, 10 call divide pop de call nextdig ld a, 0 ld [zeroblank], a ld c, l call nextdig pop bc ret divide: ld c, -1 1: inc c and a sbc hl, de sbc 0 jr nc, 1b add hl, de adc 0 ret nextdig: push hl push af ld a, c or a jr z, 1f call dpydig ld a, 0 ld [zeroblank], a pop af pop hl ret 1: ld a, [zeroblank] call dpydig pop af pop hl ret div2freq: push bc ld bc, [bstep_cfg] call mul248 inc b jr 2f 1: rr a rr h rr l and a 2: djnz 1b pop bc ret lookup_rfc: call get_rfc_hl ld a, [hl] or a jr nz, 1f ld a, 85 1: ld [rfc], a out [DA_RFC], a ret save_rfc: call get_rfc_hl ld a, [rfc] ld [hl], a out [DA_RFC], a call save_nvdata ret get_rfc_hl: load_ahl(currfreq) ld de, FLOOR % 65536 and a sbc hl, de sbc FLOOR / 65536 jr nc, 1f ld hl, rfctab ret ! below 400000 1: ld de, 1000 ld c, 0 1: and a sbc hl, de sbc 0 jr c, 1f inc c jr nz, 1b ld hl, rfctab + 255 ! above 499999 ret 1: ld hl, rfctab ld b, 0 add hl, bc ret load_nvdata: #ifdef P8N ld hl, nvstart ld d, O2_LCD1 & ~O2_SMEM ld e, O2_LCD1 ld c, OUT2 1: out [WD], a out [c], d ld a, [hl] out [c], e ld [hl], a inc hl ld a, h cp HI(nvend) jr nz, 1b ld a, l cp LO(nvend) jr nz, 1b #endif ret save_nvdata: #ifdef P8N ld hl, nvstart ld d, O2_LCD1 & ~O2_SMEM ld e, O2_LCD1 ld c, OUT2 1: ld a, [hl] di out [c], d ld [hl], a out [c], e ei inc hl ld a, h cp HI(nvend) jr nz, 1b ld a, l cp LO(nvend) jr nz, 1b #endif ret !====================================================================== .align 8 ! Necessary crctbl: .word 0 .word 4489 .word 8978 .word 12955 .word 17956 .word 22445 .word 25910 .word 29887 .word 35912 .word 40385 .word 44890 .word 48851 .word 51820 .word 56293 .word 59774 .word 63735 .word 4225 .word 264 .word 13203 .word 8730 .word 22181 .word 18220 .word 30135 .word 25662 .word 40137 .word 36160 .word 49115 .word 44626 .word 56045 .word 52068 .word 63999 .word 59510 .word 8450 .word 12427 .word 528 .word 5017 .word 26406 .word 30383 .word 17460 .word 21949 .word 44362 .word 48323 .word 36440 .word 40913 .word 60270 .word 64231 .word 51324 .word 55797 .word 12675 .word 8202 .word 4753 .word 792 .word 30631 .word 26158 .word 21685 .word 17724 .word 48587 .word 44098 .word 40665 .word 36688 .word 64495 .word 60006 .word 55549 .word 51572 .word 16900 .word 21389 .word 24854 .word 28831 .word 1056 .word 5545 .word 10034 .word 14011 .word 52812 .word 57285 .word 60766 .word 64727 .word 34920 .word 39393 .word 43898 .word 47859 .word 21125 .word 17164 .word 29079 .word 24606 .word 5281 .word 1320 .word 14259 .word 9786 .word 57037 .word 53060 .word 64991 .word 60502 .word 39145 .word 35168 .word 48123 .word 43634 .word 25350 .word 29327 .word 16404 .word 20893 .word 9506 .word 13483 .word 1584 .word 6073 .word 61262 .word 65223 .word 52316 .word 56789 .word 43370 .word 47331 .word 35448 .word 39921 .word 29575 .word 25102 .word 20629 .word 16668 .word 13731 .word 9258 .word 5809 .word 1848 .word 65487 .word 60998 .word 56541 .word 52564 .word 47595 .word 43106 .word 39673 .word 35696 .word 33800 .word 38273 .word 42778 .word 46739 .word 49708 .word 54181 .word 57662 .word 61623 .word 2112 .word 6601 .word 11090 .word 15067 .word 20068 .word 24557 .word 28022 .word 31999 .word 38025 .word 34048 .word 47003 .word 42514 .word 53933 .word 49956 .word 61887 .word 57398 .word 6337 .word 2376 .word 15315 .word 10842 .word 24293 .word 20332 .word 32247 .word 27774 .word 42250 .word 46211 .word 34328 .word 38801 .word 58158 .word 62119 .word 49212 .word 53685 .word 10562 .word 14539 .word 2640 .word 7129 .word 28518 .word 32495 .word 19572 .word 24061 .word 46475 .word 41986 .word 38553 .word 34576 .word 62383 .word 57894 .word 53437 .word 49460 .word 14787 .word 10314 .word 6865 .word 2904 .word 32743 .word 28270 .word 23797 .word 19836 .word 50700 .word 55173 .word 58654 .word 62615 .word 32808 .word 37281 .word 41786 .word 45747 .word 19012 .word 23501 .word 26966 .word 30943 .word 3168 .word 7657 .word 12146 .word 16123 .word 54925 .word 50948 .word 62879 .word 58390 .word 37033 .word 33056 .word 46011 .word 41522 .word 23237 .word 19276 .word 31191 .word 26718 .word 7393 .word 3432 .word 16371 .word 11898 .word 59150 .word 63111 .word 50204 .word 54677 .word 41258 .word 45219 .word 33336 .word 37809 .word 27462 .word 31439 .word 18516 .word 23005 .word 11618 .word 15595 .word 3696 .word 8185 .word 63375 .word 58886 .word 54429 .word 50452 .word 45483 .word 40994 .word 37561 .word 33584 .word 31687 .word 27214 .word 22741 .word 18780 .word 15843 .word 11370 .word 7921 .word 3960 !====================================================================== !====================================================================== .ascii "TheEnd" .byte .cksum(0, .) 1: .data #ifdef PROM .org 0xC000 ! start of RAM #else .org 1b ! Trailing RAM-based code #endif !====================================================================== ! ! Variables ! nvstart: !------------------------------------------ ! ! 4 bytes per memory ! First one byte for misc info, ! then 3 bytes for frequency ! MEM_RPTR = 0x01 ! 0 MEM_NOSCAN = 0x04 ! 2 MEM_EMPTY = 0x80 ! 7 BIT_RPTR = 0 BIT_NOSCAN = 2 BIT_EMPTY = 7 memories: .rs 100 * 4 rfctab: .rs 100 nvmisc: !------------------------------------------ hours BYTE ! Uptime minutes BYTE seconds BYTE sec100 BYTE volume BYTE txpwr BYTE currmem BYTE currfreq BUF(3) ! current frequency in kHz. THESE TWO ADJACENT ! tx_sub BUF(3) ! repeater difference as NA rx_sub BUF(3) ! for the 1st IF as NA tx_divisor BUF(3) ! 17 bits NA squelch_limit_close BYTE squelch_limit_open BYTE energy WORD deffreq BUF(3) ! 17 bits NA defmem BYTE defsq BYTE defvola BYTE defscan BYTE def_xxx1 BYTE def_xxx2 BYTE mycall BUF(5) nvend: !------------------------------------------ output_1 BYTE mbusrx_rp WORD mbusrx_wp WORD mbustx_rp WORD mbustx_wp WORD output_0 BYTE txon BYTE rfc BYTE rssi BYTE srssi BYTE batt BYTE !====================================================================== .align 8 ! zeroed variables ASSERT(LO(.) == 0) _bss: mbusrx_buf BUF(256) ! page aligned mbustx_buf BUF(256) ! page aligned segments BUF(16) ! 32 bits 4 times, page aligned indicators BYTE ! trails segments ! mbustx_cnt BYTE mbusrx_cnt BYTE mbus_timer BYTE ! timer for MBUS transmit rssi_timer BYTE mt_timer BYTE key_timer BYTE key_speed BYTE key_blips BYTE alert_ltimer WORD light_ltimer WORD txtail_timer BYTE ! to delay squelch pop after tx and ! battery check wrt voltage drop on tx scan_timer BYTE scan_ltimer WORD scan_mode BYTE scanner_state WORD scan_oops BYTE rejects BUF(3 * 10) reject_idx BYTE adj_feedback BYTE key_time BYTE memflags BYTE sir BYTE KEYSIR = 0 DPYSIR = 1 INSIR = 7 nosir BYTE ! Mainline needs full attention bstep_cfg BUF(2) ! 2 and 25 bstep_R WORD ! 1024 lastdigit BYTE lastkey BYTE key BYTE dark BYTE pttdn BYTE keydown BYTE digidx BYTE digbuf BUF(16) zeroblank BYTE ad_select BYTE squelch_open BYTE squelch_forced BYTE mton BYTE tx_divisor_lo BUF(3) ! TX limits tx_divisor_hi BUF(3) ! as NA redraw_req BYTE dpymode BYTE call_dpyed BYTE energy_unit_per_second WORD vip_idx BYTE vip_list BUF(4 * VIP_COUNT) outpacket BUF(8) packet BUF(8) packet_good BUF(8) packet_rdy BYTE pkt_ptr WORD pioa_data BYTE _end: