COMBO4:	;87C750 KEYER and ID
	;5jul00
;xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
ORG	000H
	AJMP	TOPGM	; to select pgm to run based on P3.5
;XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX
	;Int0 is dash  paddle is sent pin 18 P1.5
	ORG	0003H
	SETB 	DASHB
	CLR	SLEPB	;in case going to sleep
	CLR	EX0
	RETI
;XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX
	;T0 is the clock interrupt
	ORG	000BH	;timer clock
	CALL	TEN
	RETI
;XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX
	;Int1 is a dot paddle pin 19 P1.6
	ORG	0013H
	SETB	DOTB
	CLR	SLEPB	;incase going to sleep
	CLR	EX1
INT0A:	RETI
;XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX
; ram data
;bit addressable

DASHB	EQU	022H	;a dash is to be sent--K
CHAR	EQU	023H	;bit addressable cw of SCHAR-T/R
DOTB	EQU	024H	;a dot is to be sent--K
WAITB	EQU	025H	;to wait for clock interrupt--Both
CALLB	EQU	026H	;sending call sign when = 1-T/R
SLEPB	EQU	027H	;put in sleep mode--K
SBCB	EQU	028H	;to output dot or a space--K
TENB	EQU	029H	;time to ID-T/R
;byte addressable variables

SEC1	EQU	031H	;delay timer-T/R
SEC2	EQU	032H	;delay timer-T/R
RCTR1	EQU	033H	;for 10 min delay--Both
RCTR2	EQU	034H	;for 10 min delay--Both
DOTS	EQU	035H	;dot or dash indicator--K
CTR2	EQU	036H	;for 750 hz-Both

SCHAR	EQU	038H	;the call sign char-T/R
CTR	EQU	039H	;--T/R
;XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX
TEN:	; clock interrupt
	JB	SLEPB,TEN1	;time to enter sleep mode in 14 mins idle
	JNB	P3.5,KEYCK	;P3.5=0 is keyer mode
;	timer for T/R and ID routine
	JNB	CALLB, TEN1	;10 min timer else sending cw
	DJNZ	DOTS,TEN2	;loop for dash
	CLR	WAITB		;clr flag to continue with operation
	JMP	TEN2
TEN1:	DJNZ	RCTR1,TEN2
	MOV	RCTR1,#0FFH	;reload RCT1
	DJNZ	RCTR2,TEN2
	SETB	TENB		;show 10 mins is up
	CLR	TR		;stop clock
TEN2:	RET
;	timer for keyer routine
KEYCK:	CLR	SLEPB		;to show a clock intrpt for sleep mode
	DJNZ	DOTS,T0A	;loop for dash
	CLR	WAITB		;clr flag to send sbc
T0A:	RET

;XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX
;XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX
TOPGM:	;select pgm to run based on P3.5 value
	JNB	P3.5,KEYER	;do keyer program if =0
	AJMP	IDPGM		;else do ID
;##################################################

; this is the keyer code below

;###############################################
;       P1.0 to 1.4 sets the speed
;       P1.5 dash paddle
;       P1.6 dot paddle
;       P3.2 non oscillating output hi when send an element
;       P3.0 modulated CW hi is on.
;	P3.1 turns off rcvr to speaker
;	P3.6 puts keyer to sleep manually
;	P3.5 tied to ground runs keyer pgm
;	P3.7 goes to 0 when keyer goes to sleep. Allows external shutdowns.  
;XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX
KEYER:	;main prog. set speed and send cw.
	;can change speed and next intrupt will run at new speed
	;initialize
	CLR	P3.2	;use high as on to turn on xmtr
	CLR	P3.0	;low is OFF
	CLR	P3.1	;low is rcvr input turned off
	CLR	SLEPB
	SETB	EA
	SETB	ET0
	SETB	EX1
	SETB	EX0
	CLR	DOTB
	CLR	DASHB
KEYER1:	CALL	SETSPD	;determine keying speed
	JNB	DOTB,KEY20	;dotb set when dot paddle pressed
	ACALL	ADOT
	CLR 	DOTB
	SETB	EX1		;allow dot intrpt again
KEY20:	JNB	DASHB,IDLE
	ACALL	ADASH
	CLR	DASHB
	SETB	EX0		;allow dash intrpt
	AJMP	KEYER1
IDLE:	JB	DOTB,KEYER1
	JB	DASHB,KEY20
	SETB	P3.1		;allow rcvr to spkr
; sleep option after 14 mins not used
SLEP0:	MOV	RTL,#01H	;take full 'FFFF' count of clock
	MOV	RTH,#00H
	MOV	TH,RTH
	MOV	TL,RTL
	MOV	RCTR1,#0FFH
	MOV	RCTR2,#0fH	;this makes it 14 mins
	CLR	TENB		;so ten min timer will put to sleep
	SETB	SLEPB
	SETB	TR		;start sleep clock
SLEP1:	MOV	PCON,#001H	;idle mode
	JNB	P3.6,SLEP2	;this puts keyer in sleep mode
	JNB	SLEPB,SLEP3	;it is a paddle interrupt if slepb is 0
	JNB	TENB,SLEP1
SLEP2:	MOV	P1,#06FH	;minimize power useage
	CLR	P3.7		;allows external shutdown
	MOV	PCON,#002H	;enter sleep mod
	;must reset to restart now
SLEP3:	CLR	P3.1
	AJMP	KEYER1
;xXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX
SETSPD:	;put speed value in clock based on 4 DIPs
	MOV	A,P1	;p1.0 to 1.4 have speed
	ANL	A,#01FH
	RL	A
	MOV	DPTR,#SPDTBL
	MOVC	A,@A+DPTR
	MOV	RTH,A
	MOV	A,P1
	ANL	A,#01FH
	RL	A
	INC	A
	MOVC	A,@A+DPTR
	MOV	RTL,A
	MOV	TH,RTH
	MOV	TL,RTL
	RET
;XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX
SPDTBL:	;16 speeds from 18  wpm to 44 wpm based on 5 psn DIP
	; using a color burst crystal
	DW	09475H	;13  WPM
	DW	09C24H	;14
	DW	0A2CCH	;15
	DW	0A89FH	;16
	DW	0ADC3H	;17
	DW	0B254H	;18
	DW	0B66BH	;19
	DW	0BA19H	;20
	DW	0BD6DH	;21
	DW	0C073H	;22
	DW	0C337H	;23
	DW	0C5BFH	;24
	DW	0C813H	;25
	DW	0CA3AH	;26
	DW	0CC38H	;27
	DW	0CE11H	;28
	DW	0CFCAH	;29
	DW	0D165H	;30
	DW	0D2E6H	;31
	DW	0D44FH	;32
	DW	0D5A2H	;33
	DW	0D6E1H	;34
	DW	0D80EH	;35
	DW	0D92AH	;36
	DW	0DA36H	;37
	DW	0DB35H	;38
	DW	0DC26H	;39
	DW	0DD0CH	;40
	DW	0DDE6H	;41
	DW	0DEB6H	;42
	DW	0DF7CH	;43
	DW	0E039H	;44
;XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX
CWOUT:	;used by both programs
	;outputs the dot or dash and sbc for the cw of the letter
	JC	ADASH		;ID has a dash to output
ADOT:	MOV	DOTS,#001H	;a dot has only one clock cycle
CWOUT6:	NOP
	SETB	TR		;start clock
;___________________________________________________
	;makes 750 hz output
	SETB	WAITB 		;looop till end element
	SETB	P3.2		;this one does not oscillate
HZ750:	SETB	P3.0		;start element hi turns on xmtr
	MOV	CTR2,#02CH
HZ05:	DJNZ	CTR2,HZ10	;loop till count down
	CLR	P3.0		;turn off output
	MOV	CTR2,#02CH
HZ07:	DJNZ	CTR2,HZ15	;loop till count down
	JMP	HZ750
HZ10:	JNB	WAITB,CWOUT20
	JMP	HZ05
HZ15:	JB	WAITB,HZ07
;_________________________________________________________
CWOUT20:CLR	P3.0		;end element
	CLR	P3.2
	;output an sbc. clock automatically reloads itself
	MOV	DOTS,#001H	;SBC is one dot
	SETB	WAITB
	JB	WAITB,$	;wait until sbc done
	CLR	TR		;stop clock
	RET
ADASH:	MOV	DOTS,#003H	;dash is 3 dots long
	JMP	CWOUT6
;###########################################

; this is the T/R and ID code below

;#######################################################
;	P3.5=1 for ID set
;	p1.0 is remote key input=1
;	P1.1 is hf input=1
;	P1.2 controls the T/R switch and the input to hf rig
;	P1.3 control input to VHF transmitter
;	P3.0 is 750 hz CW
;	P3.2 is unmodulated CW
;	there is no sleep mode for this program
;XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX
;((((((((((((((((((((((((((((((((((((((((

CALLSN:	DB	'N4UAU*'
; change this for your call sign
;star shows last character. I made this more complex than necessary by
;allowing the input to be letters. Could make much smaller if Callsn were
;the CW pattern in the CHRS table
;)))))))))))))))))))))))))))))))))))))))))))
CHRS:	;list of characters and cw elements with a 1 to indicate first element 
since
	; cw can be 1,2,3,4,5,6 elements in length. thus a is 0000 0101 for dot 
dash.
	DB	'A',5,'B',24,'C',26,'D',12,'E',2,'F',18
	DB	'G',14,'H',16,'I',4,'J',23,'K',13
	DB	'L',20,'M',7,'N',6,'O',15,'P',22,'Q',29
	DB	'R',10,'S',8,'T',3,'U',9,'V',17,'W',11,'X',25
	DB	'Y',27,'Z',28,'0',63,'1',47,'2',39,'3',35
	DB	'4',33,'5',32,'6',48,'7',56,'8',60,'9',62,'/',50
;XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX
	;initialize
IDPGM:	CLR	P3.0		;750 hz cw, low is off
	CLR	P3.2
	SETB	P1.2		;mute input to hf, T/R to transmitter
	SETB	P1.3		;mute vhf xmit
	CLR	TENB
	CLR	CALLB	;not sending call- for timer intr
	;initialize for 10 min clock for
	MOV	RCTR1,#0FFH
	MOV	RCTR2,#0AH
	MOV	RTL,#01H	;take full 'FFFF' count of clock
	MOV	RTH,#00H
	SETB	EA
	SETB	ET0	;enable clock
	ACALL	ID	;ID at start
;XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX
	;look for an input
MAIN:	JNB	P1.0,M21	;input from remote key?
	ACALL	RKIN
M21:	JNB	TENB,M23	;time for ID?
	ACALL	ID		;yes
M23:	JNB	P1.1,MAIN	;input from hf rig
	ACALL	HFIN
	JMP	MAIN
	;loop until something happens
;XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX
HFIN:	;input from the hf rig
	SETB	TR		;start 10 min clock
	SETB	P1.2		;mute input to hf, T/R to transmitter
	CLR	P1.3		;unmute vhf xmtr
	;load 10 second delay constants
	MOV	SEC2,#0FFH
M25:	MOV	SEC1,#0FFH
M30:	JNB	P1.1,M35	;space from hf rig
	NOP
	DJNZ	SEC1,M30
	DJNZ	SEC2,M25
	;10 secs are up with no pause from hf rig
M35:	;look for remote key input
	SETB	P1.3		;mute vhf xmit
	MOV	SEC1,#016H	;200 usec delay
M40:	NOP
	DJNZ	SEC1,M40
	CLR	P1.2		;T/R switch to receive
	RET			;look for inputs
;XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX
RKIN:	; an input from the remote key, after remote input wait 1 sec
;before return to main loop
	CLR	P1.2		;unmute key input to rig
	SETB	P1.3		;mute hf input to xmtr
M110:	JNB	P1.0,M115	;if space pause 1 sec for next hi
	JMP	M110
M115:	MOV	SEC2,#0FFH	;1 sec delay
M120:	MOV	SEC1,#0FFH
M150:	JB	P1.0,M115	;reset 1 sec
	DJNZ	SEC1,M150
	DJNZ	SEC2,M120	;wait 1 sec of no input before go to main loop
	RET
;XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX
ID:	;do ID
	SETB	P1.3		;mute hf into vhf xmtr- input ID
	SETB	P1.2		;mute key input to hf rig- ant to xmit
	ACALL	SCALL
	;re-initialize for 10 min clock do not start it
	MOV	RCTR1,#0FFH
	MOV	RCTR2,#0BH
	MOV	RTL,#01H	;take full 'FFFF' count of clock
	MOV	RTH,#00H
	CLR	TENB
	RET
;XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX
SCALL: 	;find which letter or number in the call sign
	SETB	CALLB
	CLR	P3.1		;this inhibits other inputs while IDing
	MOV	R1,#00H
S400:	MOV	DPTR,#CALLSN	;address of callsign
	MOV	A,R1
	MOVC	A,@A+DPTR
	CJNE	A,#02AH,S404	;if a * then done
	CLR	CALLB
	SETB	P3.1		;allow other inputs when done IDing
	RET
S404:	MOV	SCHAR,A		;holds a call sign char
	MOV	DPTR,#CHRS	;adr of list of all characters,numbers
	MOV	R0,#00H
S405:	MOV	A,R0
	MOVC	A,@A+DPTR	;A has a character
	; get match of character
	;put chr in A for compare
	CJNE	A,SCHAR,S300	;no match get next letter
S350:	INC 	R0		;this is cw for the char
	MOV	A,R0
	MOVC	A,@A+DPTR	;put cw into Acc
	ACALL	DOCW		;output cwAAAAA
S303:	INC	R1		;next char in call sign
	JMP	S400		;if not asterisk get next char
S300:	INC	R0		;look at next char
	INC	R0		;2 incrs cuz cw in table
	JMP	S405
;XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX
DOCW:	;output the dots and dashes of the letter
	MOV	CTR,#007h
DOCW1:	RLC	A
	JC	DOCW2		;first 1 is just before the cw starts
	DEC	CTR
	JMP	DOCW1
DOCW2:	RLC	A		;this is cw
	MOV	RTL,#019H	;load clock for 20 wpm code w/3.58Mhz xtl
	MOV	RTH,#0BAH
	MOV	TH,RTH
	MOV	TL,RTL
	ACALL	CWOUT		;output dot or dash plus an SBC
	DJNZ	CTR,DOCW2	;continue for rest cw elements
	SETB	TR		;after last element need 2 more SBC
DOCW3:	MOV	DOTS,#002H
	SETB	WAITB
	JB	WAITB,$
	CLR	TR
	RET
;XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX
END
