;  PIC 16C84 compiler [V1.00 18 September 1999]
;  Source file - E:\Elektronica\pic programmer\cave\tonecoder.psf
;  File compiled - Saturday 29-9-01 16:34:48
;
;                     16C84
;           RA2  1  | i   o | 18  OUT         
;           RA3  2  | i   o | 17  RELAIS      
;           RA4  3  | i   i | 16  osc2        
;          mclr  4  | i   i | 15  osc1        
;           Vss  5  | p   p | 14  Vdd         
;           RB0  6  | i   i | 13  RB7         
;        BEACON  7  | i   o | 12  LEDPLAY     
;       COMMAND  8  | i   o | 11  LEDREC      
;           PTT  9  | i   o | 10  LEDCALL     
;
;  PIC clock frequency = 8000 kHz
;
;  No compiler errors.

_PCL	EQU H'02'
_STATUS	EQU H'03'
_C	EQU H'00'
_Z	EQU H'02'
_RP0	EQU H'05'
PORTA	EQU H'05'
PORTB	EQU H'06'
_EEDATA	EQU H'08'
_EEADR	EQU H'09'
_PCLATH	EQU H'0A'
_INTCON	EQU H'0B'
IRQ_ENABLE	EQU H'07'
_EECON1	EQU H'08'
_EECON2	EQU H'09'
_RD	EQU H'00'
_WR	EQU H'01'
_WREN	EQU H'02'
_STACK0	EQU H'0C'
_STACK1	EQU H'0D'
_STACK2	EQU H'0E'
_STACK3	EQU H'0F'
_STACK4	EQU H'10'
_STACK5	EQU H'11'
_STACK6	EQU H'12'
_STACK7	EQU H'13'
_STACK8	EQU H'14'
_STACK9	EQU H'15'
A	EQU H'16'
AH	EQU H'17'
C	EQU H'18'
CH	EQU H'19'
F	EQU H'1A'
G	EQU H'1B'
V	EQU H'1C'
X	EQU H'1D'
Y	EQU H'1E'
Z	EQU H'1F'
RELAIS	EQU H'00'
OUT	EQU H'01'
BEACON	EQU H'01'
COMMAND	EQU H'02'
PTT	EQU H'03'
LEDCALL	EQU H'04'
LEDREC	EQU H'05'
LEDPLAY	EQU H'06'

	ORG 0

	goto MAIN

;  Tonecoder version 1 (aug-2001)
;  Written by Erwin Lokhorst (erwin.lokhorst@Vollok.nl)


; var a : word	;calc-variable in relation with c
; var c : word	;number of pulses for a 0,5 sec tone(output)
; var f : byte	;frequency variable
; var g : byte	;calc-variable in relation with f (pulse lengt)
; var v : byte	;RECord-flash (counter / delay)
; var x : byte	;Command-button register variable
; var y : byte	;registers if PTT was already pressed at the first loop
; var z : byte	;While TX = every 10 seconds a PTT


;lookup table for (optional) frequency output at (f)

; for f=41	tone= 2040 Hz
; for f=42	tone= 1990 Hz
; for f=43	tone= 1950 Hz (EOT)
; for f=44	tone= 1910 Hz
; 
; for f=55	tone= 1550 Hz
; for f=56	tone= 1530 Hz
; for f=57	tone= 1500 Hz (COMM)
;
; for f=69	tone= 1250 Hz
; for f=70	tone= 1240 Hz
; for f=71	tone= 1220 Hz
; for f=72	tone= 1200 Hz (SOT)
;
; for f=87	tone= 1000 Hz
;
; for f=97	tone=  904 Hz
;
; for f=110	tone=  801 Hz
;
; for f=126	tone=  702 Hz
;
; for f=148	tone=  600 Hz
;
; for f=178	tone=  501 Hz
;
; for f=224	tone=  400 Hz
;
; for f=298	tone=  300 Hz
;
; for f=381	tone=  200 Hz
;
; for f=465	tone=  100 Hz


; PROCEDURE(MAIN)
MAIN

; alias(RA0,relais)	;Renaming ports
; alias(RA1,out)
; alias(RB1,beacon)
; alias(RB2,command)
; alias(RB3,PTT)
; alias(RB4,LEDcall)
; alias(RB5,LEDrec)
; alias(RB6,LEDplay)

; output(relais)		;Sets as output(s)
	BSF	_STATUS,_RP0
	BCF	PORTA,RELAIS
; output(out)
	BCF	PORTA,OUT
; output(LEDcall)
	BCF	PORTB,LEDCALL
; output(LEDrec)
	BCF	PORTB,LEDREC
; output(LEDplay)
	BCF	PORTB,LEDPLAY

; input(beacon)		;Sets as input(s)
	BSF	PORTB,BEACON
; input(command)
	BSF	PORTB,COMMAND
; input(PTT)
	BSF	PORTB,PTT

; clr(relais) 		;Sets TX-relais to inative
	BCF	_STATUS,_RP0
	BCF	PORTA,RELAIS
; clr(out)		;sets (tone)out(put) at low
	BCF	PORTA,OUT
; clr(a)			;from here clears rest of the variables
	CLRF	A
	CLRF	AH
; clr(c)			
	CLRF	C
	CLRF	CH
; clr(f)
	CLRF	F
; clr(g)
	CLRF	G
; clr(v)
	CLRF	V
; clr(x)
	CLRF	X
; clr(y)
	CLRF	Y
; clr(z)
	CLRF	Z

; Startup			;Goto procedure(Startup)
	CALL	STARTUP

; while true		;Main loop
_WHILE0

; if command = 0 then	;detects command-button
_IF1
	BTFSC	PORTB,COMMAND
	GOTO	_ELSE1
; begin
;  inc(x)			;counts number of times comm-button is pressed
	INCF	X,F
;  wait(500)		;500ms button-delay
	MOVLW	H'F4'
	MOVWF	_STACK0
	MOVLW	H'01'
	MOVWF	_STACK1
	CALL	_WAIT
;  if x = 4 then		;When comm-button is pressed for more then 3 times all clears 
_IF2
	MOVF	X,W
	SUBLW	H'04'
	MOVLW	H'00'
	BTFSC	_STATUS,_Z
	ADDLW	H'FF'
	ANDLW	H'FF'
	BTFSC	_STATUS,_Z
	GOTO	_ELSE2
;  begin
;   clr(x)
	CLRF	X
;   LEDrec = 0
	BCF	PORTB,LEDREC
;  end
; end
_ELSE2


; if x = 1 then		;a Call will be TX-ed
_ELSE1
_IF3
	MOVF	X,W
	SUBLW	H'01'
	MOVLW	H'00'
	BTFSC	_STATUS,_Z
	ADDLW	H'FF'
	ANDLW	H'FF'
	BTFSC	_STATUS,_Z
	GOTO	_ELSE3
; begin
;  LEDcall = 1		;indication of Call-command
	BSF	PORTB,LEDCALL
;  clr(LEDplay)
	BCF	PORTB,LEDPLAY
;  clr(LEDrec)
	BCF	PORTB,LEDREC
; end

; if x = 2 then		;Playback-command will be TX-ed
_ELSE3
_IF4
	MOVF	X,W
	SUBLW	H'02'
	MOVLW	H'00'
	BTFSC	_STATUS,_Z
	ADDLW	H'FF'
	ANDLW	H'FF'
	BTFSC	_STATUS,_Z
	GOTO	_ELSE4
; begin
;  LEDplay = 1		;indication of Play-command
	BSF	PORTB,LEDPLAY
;  clr(LEDcall)
	BCF	PORTB,LEDCALL
;  clr(LEDrec)
	BCF	PORTB,LEDREC
; end

; if x = 3 then		;Record-command will be TX-ed
_ELSE4
_IF5
	MOVF	X,W
	SUBLW	H'03'
	MOVLW	H'00'
	BTFSC	_STATUS,_Z
	ADDLW	H'FF'
	ANDLW	H'FF'
	BTFSC	_STATUS,_Z
	GOTO	_ELSE5
; begin
;  LEDrec = 1		;indication of Rec-command
	BSF	PORTB,LEDREC
;  clr(LEDplay)
	BCF	PORTB,LEDPLAY
;  clr(LEDcall)
	BCF	PORTB,LEDCALL
; end

; if beacon = 0 then	;Beacon-switch is active
_ELSE5
_IF6
	BTFSC	PORTB,BEACON
	GOTO	_ELSE6
; begin
;  relais = 1		;TX-relais is active
	BSF	PORTA,RELAIS
;  wait(200)		;200ms delay
	MOVLW	H'C8'
	MOVWF	_STACK0
	MOVLW	H'00'
	MOVWF	_STACK1
	CALL	_WAIT
;  SOT			;goto procedure SOT (Start Of Transmission)
	CALL	SOT
;  wait(500)			
	MOVLW	H'F4'
	MOVWF	_STACK0
	MOVLW	H'01'
	MOVWF	_STACK1
	CALL	_WAIT
;  EOT			;goto procedure EOT (End Of Transmission)
	CALL	EOT
;  wait(200)		;200ms delay
	MOVLW	H'C8'
	MOVWF	_STACK0
	MOVLW	H'00'
	MOVWF	_STACK1
	CALL	_WAIT
;  relais = 0		;TX-relais to be inactive
	BCF	PORTA,RELAIS
;  wait(2000)		;Receiving-time of 2 seconds
	MOVLW	H'D0'
	MOVWF	_STACK0
	MOVLW	H'07'
	MOVWF	_STACK1
	CALL	_WAIT
; end

; if PTT = 0 then		;PTT(Push To Talk)-button is active
_ELSE6
_IF7
	BTFSC	PORTB,PTT
	GOTO	_ELSE7
; begin
;  relais = 1		;TX-relais is active
	BSF	PORTA,RELAIS
;  inc(z)
	INCF	Z,F
;  wait(500)
	MOVLW	H'F4'
	MOVWF	_STACK0
	MOVLW	H'01'
	MOVWF	_STACK1
	CALL	_WAIT
;  if z = 20 then		;20 x 500ms = 10 seconds
_IF8
	MOVF	Z,W
	SUBLW	H'14'
	MOVLW	H'00'
	BTFSC	_STATUS,_Z
	ADDLW	H'FF'
	ANDLW	H'FF'
	BTFSC	_STATUS,_Z
	GOTO	_ELSE8
;  begin
;   clr(z)
	CLRF	Z
;   SOT			;every 10seconds a (new)SOT will be TX-ed / goto  procedure SOT
	CALL	SOT
;  end
;  if y = 0 then		;Detects if PTT is pressed for the first time
_ELSE8
_IF9
	MOVF	Y,W
	SUBLW	H'00'
	MOVLW	H'00'
	BTFSC	_STATUS,_Z
	ADDLW	H'FF'
	ANDLW	H'FF'
	BTFSC	_STATUS,_Z
	GOTO	_ELSE9
;  begin			;or was allready pressed previously
;   y = 1
	MOVLW	H'01'
	MOVWF	Y
;   SOT			;goto procedure SOT
	CALL	SOT
;  end
;  if x = 1 then		;a Call-command is given
_ELSE9
_IF10
	MOVF	X,W
	SUBLW	H'01'
	MOVLW	H'00'
	BTFSC	_STATUS,_Z
	ADDLW	H'FF'
	ANDLW	H'FF'
	BTFSC	_STATUS,_Z
	GOTO	_ELSE10
;  begin
;   wait(500)
	MOVLW	H'F4'
	MOVWF	_STACK0
	MOVLW	H'01'
	MOVWF	_STACK1
	CALL	_WAIT
;   Comm			;goto Comm(and) Procedure
	CALL	COMM
;   clr(x)		;reset X for next command
	CLRF	X
;   clr(LEDcall)		;clear indication-LED
	BCF	PORTB,LEDCALL
;  end
;  if x = 2 then		;a Play-command is given
_ELSE10
_IF11
	MOVF	X,W
	SUBLW	H'02'
	MOVLW	H'00'
	BTFSC	_STATUS,_Z
	ADDLW	H'FF'
	ANDLW	H'FF'
	BTFSC	_STATUS,_Z
	GOTO	_ELSE11
;  begin
;   wait(500)
	MOVLW	H'F4'
	MOVWF	_STACK0
	MOVLW	H'01'
	MOVWF	_STACK1
	CALL	_WAIT
;   comm			;goto Comm(and) Procedure
	CALL	COMM
;   wait(500)		;500ms delay
	MOVLW	H'F4'
	MOVWF	_STACK0
	MOVLW	H'01'
	MOVWF	_STACK1
	CALL	_WAIT
;   Comm			;goto Comm(and) Procedure
	CALL	COMM
;   clr(x)
	CLRF	X
;   clr(LEDplay)		;clear indication-LED
	BCF	PORTB,LEDPLAY
;  end
;  if x = 3 then
_ELSE11
_IF12
	MOVF	X,W
	SUBLW	H'03'
	MOVLW	H'00'
	BTFSC	_STATUS,_Z
	ADDLW	H'FF'
	ANDLW	H'FF'
	BTFSC	_STATUS,_Z
	GOTO	_ELSE12
;  begin
;   wait(500)
	MOVLW	H'F4'
	MOVWF	_STACK0
	MOVLW	H'01'
	MOVWF	_STACK1
	CALL	_WAIT
;   Comm			;goto Comm(and) Procedure
	CALL	COMM
;   wait(500)		;500ms delay
	MOVLW	H'F4'
	MOVWF	_STACK0
	MOVLW	H'01'
	MOVWF	_STACK1
	CALL	_WAIT
;   Comm			;goto Comm(and) Procedure
	CALL	COMM
;   wait(500)		;500ms delay
	MOVLW	H'F4'
	MOVWF	_STACK0
	MOVLW	H'01'
	MOVWF	_STACK1
	CALL	_WAIT
;   Comm			;goto Comm(and) Procedure
	CALL	COMM
;   clr(x)
	CLRF	X
;   clr(LEDrec)		;clear indication-LED
	BCF	PORTB,LEDREC
;   v = 1			;sets var(v) for RECord-flash indicator-LED
	MOVLW	H'01'
	MOVWF	V
;  end
;  if v > 0 then
_ELSE12
_IF13
	MOVF	V,W
	SUBLW	H'00'
	CLRW
	BTFSS	_STATUS,_C
	ADDLW	H'FF'
	BTFSC	_STATUS,_Z
	GOTO	_ELSE13
;  begin
;   inc(v)
	INCF	V,F
;   LEDrec = 1		
	BSF	PORTB,LEDREC
;   wait(100)		;100ms delay
	MOVLW	H'64'
	MOVWF	_STACK0
	MOVLW	H'00'
	MOVWF	_STACK1
	CALL	_WAIT
;   LEDrec = 0
	BCF	PORTB,LEDREC
;   wait(100)		;100ms delay
	MOVLW	H'64'
	MOVWF	_STACK0
	MOVLW	H'00'
	MOVWF	_STACK1
	CALL	_WAIT
;   if v = 57 then	;total recording-time is 40 seconds / communication is still possible
_IF14
	MOVF	V,W
	SUBLW	H'39'
	MOVLW	H'00'
	BTFSC	_STATUS,_Z
	ADDLW	H'FF'
	ANDLW	H'FF'
	BTFSC	_STATUS,_Z
	GOTO	_ELSE14
;   begin			;delays(500+200+200ms)x58=40.6seconds
;    clr(v)		;after 40 sec REC-LED stops flashing
	CLRF	V
;   end
;  end
_ELSE14
; end
_ELSE13

; if PTT = 1 then		;detects end off communication
_ELSE7
_IF15
	BTFSS	PORTB,PTT
	GOTO	_ELSE15
; begin
;  clr(z)			;resets 10 seconds SOT-pulse
	CLRF	Z
;  clr(v)			;resets record-flash-indicator-LED
	CLRF	V
;  if y = 1 then		;detects PTT was pressed until last loop
_IF16
	MOVF	Y,W
	SUBLW	H'01'
	MOVLW	H'00'
	BTFSC	_STATUS,_Z
	ADDLW	H'FF'
	ANDLW	H'FF'
	BTFSC	_STATUS,_Z
	GOTO	_ELSE16
;  begin
;   clr(y)		;resets Y for next PTT		
	CLRF	Y
;   wait(500)	
	MOVLW	H'F4'
	MOVWF	_STACK0
	MOVLW	H'01'
	MOVWF	_STACK1
	CALL	_WAIT
;   EOT			;goto EOT(End Of Transmission)Procedure
	CALL	EOT
;   wait(200)		;200ms delay
	MOVLW	H'C8'
	MOVWF	_STACK0
	MOVLW	H'00'
	MOVWF	_STACK1
	CALL	_WAIT
;  end
;  relais = 0		;TX-relais inactive
_ELSE16
	BCF	PORTA,RELAIS
; end

; loop
_ELSE15
	GOTO	_WHILE0
_LOOP0

	GOTO	MAIN

; PROCEDURE(STARTUP)
STARTUP
; clr(LEDcall)
	BCF	PORTB,LEDCALL
; clr(LEDrec)
	BCF	PORTB,LEDREC
; clr(LEDplay)
	BCF	PORTB,LEDPLAY

	RETURN

; PROCEDURE(SOT)
SOT
; clr(a)			;clears a for procedure(Count)
	CLRF	A
	CLRF	AH
; f = 72			;pulseHigh & pulseLow = 1200 Hz
	MOVLW	H'48'
	MOVWF	F
; c = 500			;number of pulses for 0,5seconds tone
	MOVLW	H'F4'
	MOVWF	_STACK0
	MOVLW	H'01'
	MOVWF	_STACK1
	MOVF	_STACK0,W
	MOVWF	C
	MOVF	_STACK1,W
	MOVWF	CH
; Count			;goto procedure(Count)
	CALL	COUNT

	RETURN

; PROCEDURE(EOT)
EOT
; clr(a)			;clears a for procedure(Count)
	CLRF	A
	CLRF	AH
; f = 43			;pulse for 1950 Hz
	MOVLW	H'2B'
	MOVWF	F
; c = 977			;number of pulses for 0,5seconds tone
	MOVLW	H'D1'
	MOVWF	_STACK0
	MOVLW	H'03'
	MOVWF	_STACK1
	MOVF	_STACK0,W
	MOVWF	C
	MOVF	_STACK1,W
	MOVWF	CH
; Count			;goto procedure(Count)
	CALL	COUNT

	RETURN

; PROCEDURE(COMM)
COMM
; clr(a)			;clears a for procedure(Count)
	CLRF	A
	CLRF	AH
; f = 57			;pulse for 1500 Hz
	MOVLW	H'39'
	MOVWF	F
; c = 771			;number of pulses for 0,5seconds tone
	MOVLW	H'03'
	MOVWF	_STACK0
	MOVLW	H'03'
	MOVWF	_STACK1
	MOVF	_STACK0,W
	MOVWF	C
	MOVF	_STACK1,W
	MOVWF	CH
; Count			;goto procedure(Count)
	CALL	COUNT

	RETURN

; PROCEDURE(COUNT)
COUNT

; while a <= c		;check of number of pulses for a pulse of 0,5 seconds
_WHILE17
	MOVF	A,W
	MOVWF	_STACK0
	MOVF	AH,W
	MOVWF	_STACK1
	MOVF	C,W
	MOVWF	_STACK2
	MOVF	CH,W
	MOVWF	_STACK3
	CALL	_LESSEQ16
	BTFSC	_STATUS,_Z
	GOTO	_LOOP17
; inc(a)			;increment a by 1
	INCF	A,F
	BTFSC	_STATUS,_Z
	INCF	AH,F
; clr(g)			;clears g for procedure(Hpulse)
	CLRF	G
; Hpulse			;goto procedure(Hpulse)
	CALL	HPULSE
; clr(g)			;clears g for procedure(Lpulse)
	CLRF	G
; Lpulse			;goto procedure(Lpulse)
	CALL	LPULSE
; loop			;loop until tone is longer then 0,5 seconds
	GOTO	_WHILE17
_LOOP17


	RETURN

; PROCEDURE(HPULSE)
HPULSE

; while g <= f		;loop-check for a 500ms block-wave
_WHILE18
	MOVF	G,W
	SUBWF	F,W
	CLRW
	BTFSC	_STATUS,_C
	ADDLW	H'FF'
	BTFSC	_STATUS,_Z
	GOTO	_LOOP18
; inc(g)			;increment g by 1
	INCF	G,F
; out = 1			;(signal)output is High
	BSF	PORTA,OUT
; loop			;loop until 1/2 of freq is reached
	GOTO	_WHILE18
_LOOP18


	RETURN

; PROCEDURE(LPULSE)
LPULSE

; while g <= f		;loop-check for a 500ms block-wave
_WHILE19
	MOVF	G,W
	SUBWF	F,W
	CLRW
	BTFSC	_STATUS,_C
	ADDLW	H'FF'
	BTFSC	_STATUS,_Z
	GOTO	_LOOP19
; inc(g)			;increment g by 1
	INCF	G,F
; out = 0			;(signal)output is Low
	BCF	PORTA,OUT
; loop			;loop until 1/2 of freq is reached
	GOTO	_WHILE19
_LOOP19

			;Hpulse & Lpulse form one total block-wave
	RETURN
; 16 bit Less than or equal to
_LESSEQ16
	MOVF	_STACK1,W
	SUBWF	_STACK3,W
	BTFSS	3,2
	GOTO	_LESSEQ161
	MOVF	_STACK0,W
	SUBWF	_STACK2,W
	BTFSC	3,2
	GOTO	_LESSEQ162
_LESSEQ161
	BTFSC	3,0
	GOTO	_LESSEQ162
	CLRF	_STACK0
	CLRF	_STACK1
	RETURN
_LESSEQ162
	IORLW	H'FF'
	MOVWF	_STACK0
	MOVWF	_STACK1
	RETURN
; Wait routine
_WAIT
	CLRF	_STACK2
	CLRF	_STACK3
_WAIT1
	MOVLW	H'13'
	MOVWF	_STACK4
_WAIT2
	MOVLW	H'1F'
	MOVWF	_STACK5
_WAIT3
	DECFSZ	_STACK5,f
	GOTO	_WAIT3
	DECFSZ	_STACK4,f
	GOTO	_WAIT2
	MOVLW	H'28'
	MOVWF	_STACK4
_WAIT4
	DECFSZ	_STACK4,f
	GOTO	_WAIT4
	INCF	_STACK2,f
	BTFSC	3,2
	INCF	_STACK3,f
	MOVF	_STACK0,W
	SUBWF	_STACK2,W
	BTFSS	3,2
	GOTO	_WAIT1
	MOVF	_STACK1,W
	SUBWF	_STACK3,W
	BTFSS	3,2
	GOTO	_WAIT1
	RETURN
	END

