ZL1HIT Hellschreiber / PIC Beacon


hellpic1.gif (64625 bytes)This is a simple circuit that does a fair bit of work. The core of the circuit is my favourite IC - the Microchip PIC 16F84 Microcontroller / RISC Microprocessor.

This project was inspired by my new friend Murray, ZL1BPU. Murray is very interested in H.F. band "digital" modes. He and a group of others are responbile for resurrecting the 1927 Hellschreiber visually received "fuzzy" digital mode of communication. More information about Hellschreiber can be read here. I highly recommend you take a look. It's fascinating stuff to be sure.

This project produces base band Hellschreiber "digital" output which directly keys an HF radio transmitter. In my case I simply connect the output transistor to the CW Key input on my ICOM IC-706 Mk II transceiver. Since this rig is electronically keyed it works very well for this task.

Here is a sample of the Hellschrieber sent by this project:
hell1.gif (5908 bytes)

Following is the PIC MPASM Source Code for Version 0.03 of the Beacon:

;*************************************************************************
; Feld Hellschreiber / CW Beacon Base Band Beacon
; Author: Bryan J. Rentoul
; Date: 10-April-1999
;
; All rights reserved
; 
; Description: This project was inspired, yeh "specced" even, by Murray, 
; ZL1BPU. It purpose is to send a mixture of CW and Hellschreiber via
; a simple CW transmitter based around a 3.58 MHz Xtal oscillator in the
; classic style. This is an early version and lacks any "user friendly"
; interface for loading new messages etc.
;
; This version uses the 5x5 pixel all upper case font set provided
; by ZL1BPU. (Letters 'C', 'V' an 'O' slighly modified for clarity. 
;
;
;*************************************************************************
        include "p16c84.inc"
        include "bits.inc"	; Bit processing Macros

;*** SET CONFIG FUSES ***

	__CONFIG _CP_OFF & _WDT_OFF & _HS_OSC

;For Assembler PORTAbility

W       EQU     0               ;For file,W
w       EQU     0               ;For file,W
F       EQU     1               ;For file,F
f       EQU     1               ;For file,F

;*******************************************************************
;* REGISTER DECLARATIONS
;*******************************************************************

ind     equ     0               ;0=pseudo-reg 0 for indirect (FSR)
RTCC    equ     1               ;1=Real Time Clock/Counter
TMR0	equ	1		;1=Timer0 (same as above)
PC      equ     2               ;2=PC
STATUS  equ     3               ;3=Status Reg
INTCON	equ	0Bh
PCLATH	equ	0Ah

;* Status reg bits
	BIT	B_C,0,STATUS	;Carry
	BIT	B_DC,1,STATUS	;Half carry
	BIT	B_Z,2,STATUS	;Zero
	BIT	B_PD,3,STATUS	;Power down
	BIT	B_TO,4,STATUS	;Timeout
	BIT	B_PA0,5,STATUS	;Page select (56/57 only)
	BIT	B_PA1,6,STATUS	;Page select (56/57 only)
	BIT	B_PA2,7,STATUS	;GP flag
;----
;* OPTION reg bits
	BIT	B_RBPU,7,1
;----
;* INTCON reg bits (defined in p16c84.inc)
	BIT 	I_GIE,7,INTCON
	BIT	I_EEIE,6,INTCON	
	BIT	I_T0IE,5,INTCON	
	BIT	I_INTE,4,INTCON	
	BIT	I_RBIE,3,INTCON	
	BIT	I_T0IF,2,INTCON	
	BIT	I_INTF,1,INTCON	
	BIT	I_RBIF,0,INTCON	

;--------------------------------
	
FSR     equ     4               ;4=file select reg 0-4=indirect address
fsr     equ     4               ;4=file select reg 0-4=indirect address
PORTA   equ     5               ;5=port A I/O register (4 bits)
PORTB   equ     6               ;6=port B I/O register
porta   equ     5               ;5=port A I/O register (4 bits)
portb   equ     6               ;6=port B I/O register

;--------
	BIT	RA0,0,PORTA
	BIT	RA1,1,PORTA
	BIT	RA2,2,PORTA
	BIT	RA3,3,PORTA
	BIT	RA4,4,PORTA

	BIT	RB0,0,PORTB
	BIT	RB1,1,PORTB
	BIT	RB2,2,PORTB
	BIT	RB3,3,PORTB
	BIT	RB4,4,PORTB
	BIT	RB5,5,PORTB
	BIT	RB6,6,PORTB
	BIT	RB7,7,PORTB

	BIT	PTT,0,PORTA	; PTT Output
	BIT	SPAREA1,1,PORTA
	BIT	SIDETONE,2,PORTA
	BIT	TIMECAP,3,PORTA	; Timer capacitor output
	BIT	TIMEIN,4,PORTA	; Timer cap. input
	
	BIT	TXOUT,0,PORTB
	BIT	FSK0,1,PORTB
	BIT	FSK1,2,PORTB
	BIT	FSK2,3,PORTB
	BIT	DXMODE,4,PORTB	; DX Mode input. Jumper to GND for DX mode enable

;--------
SAVEW	equ	0Ch	; Used in INT routine to save W and STATUS register
SAVES	equ	0Dh
FLAGS	equ	0Eh	; Inputs status register
DL1	equ	0Fh	; Delay routine counters
DL2	equ	10h	;    "	   "	   "
DL3	equ	11h	;    "	   "	   " 
INTCNT	equ	12h	; Interrupt call counter to count 64 calls then reset
TONECNT equ	13h	; Tone counter using to toggle output every 8 int calls
COLCNT	equ	14h	; Column counter
ROWCNT	equ	15h	; Row counter
CURCOL	equ	16h	; Current column data for rotating each bit into carry flag
CHAR	equ	17h	; Character code to send (ASCII values from 32 to 95 OK)
TEMP	equ	18h
TEMP1	equ	19h
TIMER	equ	20h	; We use this as a free running timer incremented 
			; by the Int routine. It is for CW dot / dash timing etc
SAVE1	equ	21h	; Just another TEMP variable
SAVE2	equ	22h	; 
OUTBUF	equ	23h	; CW Output buffer

; 24h to 2B  free

	; Define some status bits (flags)
	BIT	BUSY,0,FLAGS	        ; 0 = Buffer awaits new character to send (1 = busy)
	BIT	F_SIDETONE,1,FLAGS
	BIT	F_TABLE,2,FLAGS		; 0 = Font Table 1, 1 = Font Table 2
	BIT	F_CW,3,FLAGS		; In CW mode (1) the Int does not toggle TXOUT

;*** Reset Vector ********************************************************

	ORG     0000
reset
	GOTO    INIT

; =========================
; == INTERRUPT PROCEDURE ==
; =========================
	ORG	0004
TIMERINT   ; Interrupt routine called (17.5 * 5 * 60) times per second providing
	   ; pixel timing (5 pixels/rows  per column)

	; Save W and Status
	CLB	I_T0IE		; Disable this interrupt
	CLB	I_T0IF		; clear the interrupt
        movwf   SAVEW		; save w reg in Buffer
        swapf   SAVEW, f	; swap it
        swapf   STATUS,w	; get status (swapped)
        movwf   SAVES		; and save it

	movlw	18		; Reset Counter to 18 (instead of around zero or so)
	movwf	TMR0		;   /

	; Interrupt procedure propper starts here

	decfsz	TONECNT, f	; Time for side tone click?
	goto	INEXT1		

	movlw	4		; Toggle the Sidetone output every 6 calls		
	movwf	TONECNT		;   /
	SKBC	F_SIDETONE	; ...but only if the F_SIDETONE flag is set
	TBIT	SIDETONE	;

INEXT1
	decfsz	INTCNT, f	; Time to send a dot pixel?
	goto	IEND		; Nope...

	;-------
	decf	TIMER, f	; decrement out free runing timer used in DELAY function
	;-------

	movlw	60		; Yes...
	movwf	INTCNT		; Reset INTCNT to 60	

	; Check the BUSY FLAG. If zero do nothing
	BBC	BUSY, IEND

	movfw	ROWCNT
	BBS	B_Z, IENDCOL 	; If ROWCNT is zero then we are done

	; Other wise send next bit

	movfw	CURCOL	
	rrf	CURCOL, f	; Rotate bit into carry flag for testing
	BBS	B_C, ITONEON

	BBS	F_CW, INEXT2	; Dont touch TXOUT or F_SIDETONE if in CW mode
	CLB	TXOUT		; Turn TX carrier OFF
	CLB	F_SIDETONE	; flag side tone to OFF
	goto	INEXT2

ITONEON
	BBS	F_CW, INEXT2	; Dont touch TXOUT or F_SIDETONE if in CW mode
	SEB	TXOUT		; Turn TX carrier ON
	SEB	F_SIDETONE	; flag side tone to ON

INEXT2
	decf	ROWCNT, f	; Decrement row counter
	goto	IEND		; Exit the int routine

IENDCOL
	CLB	BUSY		; Clear the BUSY flag to indicate column sent

IEND
        swapf   SAVES,w		; get status (swapped back)
        movwf   STATUS		; and restore it
        swapf   SAVEW,w		; restore W reg (swapped back to restore Z,C,DC flags)
	SEB	I_T0IE		; Re-enable the interrupt
	retfie

;---- END OF INTERRUPT ROUTINE ------	
;------------------------------------

;*************************************************************************
;** INIT
;** Hardware reset entry point
;**
;*************************************************************************

INIT    ;Power-on entry

;*************************************************************************
;** RESET
;** software reset entry point
;**
;*************************************************************************
RESET   ;Soft reset

        ;Init ports
	movlw   10h	; All Port A bits to outputs except RA4 (Timer Cap input)
	tris    PORTA

	movlw	0F0h	; Initialize Port B I/O pins
	movwf   PORTB	
	movlw	0F0h	; Port B<0-3> Output, Port B<4-7> Input
	tris    PORTB

	movlw	b'00011001' ; 0 Turn ON Port B pullups
			    ; 0 External Int triggers on falling edge	
			    ; 0 TOCS low (timer run from internal clock)
			    ; 1 TOSE - Counter timer/counter triggers on rising edge
			    ; 1 Prescaler switched OUT (to WDT) ...
			    ; 110  ...with div. 64 (WDT) or 128 (TMR0)

	option	; Store W in the Option register.


	CLB	BUSY		; Clear busy flag
	CLB	F_SIDETONE
	CLB	F_CW		; Start in Hell' mode
	
	clrf	COLCNT
	clrf	ROWCNT

	; Set up the timer interrupt to give us the required 122.5 dots per second
	; (17.5 columns per second with 7 pixel rows)
	; We reset the counter to 18 each time to yield 240 counts per 
	; interrupt = (7.3728 / 4 / 240) = 7680 ints. per second.
	; 7680 / (17.5 x 7 row pixels) = 62.69. So every 63rd call to the int. should
	; send one pixel.
	;
	; NOTE: In practice it was found tat every 60th call produced the right timing!

	movlw	6
	movwf	TONECNT	; Init tone counter reg. Toggle TXOUT every 6 calls to int.
	movlw	60
	movwf	INTCNT	; Initialize the INTCNT counter reg.
	SEB	I_T0IE	; enable timer overflow interrupt
	SEB	I_GIE	; global interrupt enable
			; The TIMERINT interrupt routine is now running

	goto	MAIN_LOOP

;====================

DELAY	; Arbitary delay routine for CW dash/dot timing or whatever

	; Make a delay send one blank column
	clrf	CURCOL
	call	TXCOL
	return
;-----------------------------------

;================================================
; Subroutines for various things shall go here..
;================================================

TXCOL	; Sets the Int routine up to send a column - 5 rows 
	; (bits stretched over usual 14 rows)
	; The CURCOL variable hold the column dat to send

	movfw	CURCOL		; Save column data (the Int routine destroys it)
	movwf	SAVE1

	movlw	6		
	movwf	ROWCNT		; ROWCNT will process 5 rows (0 not processed)
	SEB	BUSY		; Setting this bit signals Int routine to send a column
	LOOPBS	BUSY		; sit in loop waiting for BUSY to clear

	movfw	SAVE1		; Restore column data (in case we want to send it again)
	movwf	CURCOL

	return
;----------------------

TXCHAR	; Send character in "W" using Hellscheiber
	movwf	TEMP
	movlw	32		; make the char code zero based
	subwf	TEMP,f		; and store in TEMP

	; The FONT table is split into two parts. Characters 0 to 31 are in part 1
	; The rest are in part 2 (FONTTAB2)

	movlw	32		; Is the character to send less than 32?
	subwf	TEMP, w		; Subtract W (32) from TEMP
	BBS	B_C, USETABLE2	; Carry Flag is SET for a positive result (TEMP > 32)
USETABLE1
	movlw	HIGH FONTTAB1	; Get the jump page right and stick
	movwf	PCLATH		; it in PCLATH as per the book :)
	CLB	F_TABLE		; Clear the F_TABLE flag to indicate FONTTAB1 below
	goto	SENDCHAR	; --> go lookup and send this character

USETABLE2
	movlw	32		; Subtract addition 32 to correct char offset for table 2
	subwf	TEMP, f		;   /
	movlw	HIGH  FONTTAB2	; Load PCLATH to correct memory page is used
	movwf	PCLATH		;   /
	SEB	F_TABLE		; Set the F_TABLE flag to indicate FONTTAB2 below

SENDCHAR
	movfw	TEMP		; Retrive char offset
	addwf	TEMP, f		; multiply by 5 to get to start of 
	addwf	TEMP, f		; char in font table
	addwf	TEMP, f		;   /
	addwf	TEMP, f		;   /

	clrf	COLCNT		; Reset COLCNT (column counter)
TAB1LOOP
	movfw	TEMP		; Retrieve char font table offset
	addwf	COLCNT, w	; Add the column number
	CBC	F_TABLE, FONTTAB1	; Call the right table based on F_TABLE flag ...
	CBS	F_TABLE, FONTTAB2	; ...set above to get the column data
	movwf	CURCOL

	call	TXCOL		; Flag the Interrupt routine to send this column
	SKBS	DXMODE		; If no jumper on for DX mode then exit
	call	TXCOL		; otherwise send the column a 2nd time

	incf	COLCNT, f	; Increment COLCNT
	movfw	COLCNT		; Last column (5) ?
	sublw	5
	BBC	B_Z, TAB1LOOP	; If not then send next column

	clrf	CURCOL		; Send one blank column
	call	TXCOL		;    /

	return

;--------------------------------
;--- CW ROUTINES START HERE -----
;--------------------------------
SENDDASH
	SEB	F_SIDETONE
	SEB	TXOUT		; PTT on
	call	DELAY		; Dash delay
	call	DELAY	
	call	DELAY	
	call	DELAY	
	call	DELAY	
	CLB	TXOUT		; PTT off
	CLB	F_SIDETONE
	call	DELAY
	return
;-----------------------------------
SENDDOT
	SEB	F_SIDETONE
	SEB	TXOUT		; PTT on
	call	DELAY		; Dot delay
	call	DELAY	
	CLB	TXOUT		; PTT off
	CLB	F_SIDETONE
	call	DELAY		; "space between" delay
	return
;-----------------------------------

SENDCW	; Sends CW character held in W. RRF's each bit out until W = 1
	; 00h in W means send space between words

	SEB	F_CW		; Tell the Int routine we are in CW mode

	movwf	OUTBUF
	xorlw	0		; Trigger Z flag (maybe) 
	BBS	B_Z, SSPACE	; Its zero so just send a space
SILOOP
	movfw	OUTBUF
	sublw	1
	BBS	B_Z, SIEND	; If just one then we are done

	CLB	B_C
	rrf	OUTBUF, f	; Get next bit to send

	BBC	B_C, SDOT	; Branch to DOT if Carry clear. Otherwise its a DASH
	call	SENDDASH
	goto	SILOOP		; loop back
SDOT
	call	SENDDOT
	goto	SILOOP		; loop back

SSPACE
	call	DELAY	; Send word space (just wait)
	call	DELAY
	call	DELAY
SIEND
	call	DELAY	; Inter char delay
	call	DELAY
	call	DELAY

	CLB	F_CW		; Tat's enough CW for now thanks :)
	return
;------------------------------------

;********************************
;****** M A I N   L O O P  ******
;********************************

MAIN_LOOP

	; Send the beacon string from the "T_BEACON" table
	clrf	TEMP1
BEACONL1
	movlw	HIGH  T_BEACON	; Stick the MSByte of T_BEACON in PCLATH
	movwf	PCLATH
	movfw	TEMP1		; Retrieve the beacon character offset
	call	T_BEACON	; Go get the character
	xorlw	0		; To update the Z flag
	BBS	B_Z, MLEND1	; Zero? If so we are done so jump out to MLEND1
	call	TXCHAR		; Otherwise send this character
	incf	TEMP1, f	; Increment to next character
	goto	BEACONL1	; Loopy de loop

MLEND1
	call	DELAY
	call	DELAY

;-----

	; Same again but this time CW
	clrf	TEMP1
BEACONL2
	movlw	HIGH  T_CALLSIGN	; Stick the MSByte of T_BEACON in PCLATH
	movwf	PCLATH
	movfw	TEMP1		; Retrieve the beacon character offset
	call	T_CALLSIGN	; Go get the character
	xorlw	0		; To update the Z flag
	BBS	B_Z, MLEND2	; Zero? If so we are done so jump out to MLEND1
	movwf	TEMP		; Save W
	movlw	HIGH CWT	; Get the dot and dashes from the CWT
	movwf	PCLATH		; /
	movfw	TEMP		; Restore W
	call	CWT		; /
	call	SENDCW		; Send this character
	incf	TEMP1, f	; Increment to next character
	goto	BEACONL2	; Loopy de loop

MLEND2
	call	DELAY
	call	DELAY

	goto	MAIN_LOOP	; Luckily PIC MCU's do not get bored!
;-----------------------------------

	ORG	0200h

FONTTAB1
	addwf	PC, f

	retlw	 0	;  32 -  
	retlw	 0
	retlw	 0
	retlw	 0
	retlw	 0

	retlw	 0	;  33 - !
	retlw	 0
	retlw	 29
	retlw	 0
	retlw	 0

	retlw	 0	;  34 - "
	retlw	 24
	retlw	 0
	retlw	 24
	retlw	 0

	retlw	 10	;  35 - #
	retlw	 31
	retlw	 10
	retlw	 31
	retlw	 10

	retlw	 8	;  36 - $
	retlw	 21
	retlw	 31
	retlw	 21
	retlw	 2

	retlw	 25	;  37 - %
	retlw	 26
	retlw	 4
	retlw	 11
	retlw	 19

	retlw	 10	;  38 - &
	retlw	 21
	retlw	 13
	retlw	 2
	retlw	 5

	retlw	 0	;  39 - '
	retlw	 16
	retlw	 24
	retlw	 0
	retlw	 0

	retlw	 0	;  40 - (
	retlw	 14
	retlw	 17
	retlw	 0
	retlw	 0

	retlw	 0	;  41 - )
	retlw	 0
	retlw	 17
	retlw	 14
	retlw	 0

	retlw	 21	;  42 - *
	retlw	 14
	retlw	 31
	retlw	 14
	retlw	 21

	retlw	 4	;  43 - +
	retlw	 4
	retlw	 31
	retlw	 4
	retlw	 4

	retlw	 0	;  44 - ,
	retlw	 1
	retlw	 6
	retlw	 0
	retlw	 0

	retlw	 4	;  45 - -
	retlw	 4
	retlw	 4
	retlw	 4
	retlw	 4

	retlw	 0	;  46 - .
	retlw	 3
	retlw	 3
	retlw	 0
	retlw	 0

	retlw	 1	;  47 - /
	retlw	 2
	retlw	 4
	retlw	 8
	retlw	 16

	retlw	 14	;  48 - 0
	retlw	 19
	retlw	 21
	retlw	 25
	retlw	 14

	retlw	 0	;  49 - 1
	retlw	 16
	retlw	 31
	retlw	 0
	retlw	 0

	retlw	 3	;  50 - 2
	retlw	 21
	retlw	 21
	retlw	 21
	retlw	 9

	retlw	 0	;  51 - 3
	retlw	 21
	retlw	 21
	retlw	 21
	retlw	 10

	retlw	 0	;  52 - 4
	retlw	 30
	retlw	 2
	retlw	 7
	retlw	 2

	retlw	 28	;  53 - 5
	retlw	 21
	retlw	 21
	retlw	 21
	retlw	 2

	retlw	 14	;  54 - 6
	retlw	 21
	retlw	 21
	retlw	 21
	retlw	 2

	retlw	 16	;  55 - 7
	retlw	 16
	retlw	 23
	retlw	 24
	retlw	 0

	retlw	 10	;  56 - 8
	retlw	 21
	retlw	 21
	retlw	 21
	retlw	 10

	retlw	 8	;  57 - 9
	retlw	 21
	retlw	 21
	retlw	 21
	retlw	 14

	retlw	 0	;  58 - :
	retlw	 5
	retlw	 5
	retlw	 0
	retlw	 0

	retlw	 0	;  59 - ;
	retlw	 10
	retlw	 11
	retlw	 0
	retlw	 0

	retlw	 4	;  60 - <
	retlw	 10
	retlw	 17
	retlw	 0
	retlw	 0

	retlw	 0	;  61 - =
	retlw	 10
	retlw	 10
	retlw	 10
	retlw	 0

	retlw	 0	;  62 - >
	retlw	 0
	retlw	 17
	retlw	 10
	retlw	 4

	retlw	 8	;  63 - ?
	retlw	 16
	retlw	 21
	retlw	 20
	retlw	 8
;---------------------------------------

CWT	; CW Table	Call with W=ASC of char to send (EG. 'A' (65) for "di'dah" )
	addlw	0
	SKBC	B_Z	; Return a zero if zero received
	retlw	0

	movwf	SAVE1		; Calculate offset in table from ASCI char given
	movlw	48		; [ ASCII code for "0" ]
	subwf	SAVE1, w
	addwf	PC, f
	
	retlw	b'00111111' ; 0
	retlw	b'00111110' ; 1
	retlw	b'00111100' ; 2
	retlw	b'00111000' ; 3
	retlw	b'00110000' ; 4
	retlw	b'00100000' ; 5
	retlw	b'00100001' ; 6
	retlw	b'00100011' ; 7
	retlw	b'00100111' ; 8
	retlw	b'00101111' ; 9
	retlw	b'00000000' ; :
	retlw	b'00000000' ; ;
	retlw	b'00000000' ; <
	retlw	b'00000000' ; =
	retlw	b'00000000' ; >
	retlw	b'00000000' ; ?
	retlw	b'00000000' ; @
	retlw	b'00000110' ; A
	retlw	b'00010001' ; B
	retlw	b'00010101' ; C
	retlw	b'00001001' ; D
	retlw	b'00000010' ; E
	retlw	b'00010100' ; F
	retlw	b'00001011' ; G
	retlw	b'00010000' ; H
	retlw	b'00000100' ; I
	retlw	b'00011110' ; J
	retlw	b'00001101' ; K
	retlw	b'00010010' ; L
	retlw	b'00000111' ; M
	retlw	b'00000101' ; N
	retlw	b'00001111' ; O
	retlw	b'00010110' ; P
	retlw	b'00011011' ; Q
	retlw	b'00001010' ; R
	retlw	b'00001000' ; S
	retlw	b'00000011' ; T
	retlw	b'00001100' ; U
	retlw	b'00011000' ; V
	retlw	b'00001110' ; W
	retlw	b'00011001' ; X
	retlw	b'00011101' ; Y
	retlw	b'00010011' ; Z

;=========================

	; FONT TABLE 2 (second half)

	ORG	0300h	; start table at even multiple of 256 address

FONTTAB2		
	addwf	PC, f

	retlw	 14	;  64 - @
	retlw	 17
	retlw	 21
	retlw	 21
	retlw	 8

	retlw	 15	;  65 - A
	retlw	 20
	retlw	 20
	retlw	 20
	retlw	 15

	retlw	 31	;  66 - B
	retlw	 21
	retlw	 21
	retlw	 21
	retlw	 10

	retlw	 14	;  67 - C
	retlw	 17
	retlw	 17
	retlw	 17
	retlw	 0	;was 10

	retlw	 31	;  68 - D
	retlw	 17
	retlw	 17
	retlw	 17
	retlw	 14

	retlw	 31	;  69 - E
	retlw	 21
	retlw	 21
	retlw	 21
	retlw	 17

	retlw	 31	;  70 - F
	retlw	 20
	retlw	 20
	retlw	 20
	retlw	 16

	retlw	 14	;  71 - G
	retlw	 17
	retlw	 17
	retlw	 19
	retlw	 10

	retlw	 31	;  72 - H
	retlw	 4
	retlw	 4
	retlw	 4
	retlw	 31

	retlw	 0	;  73 - I
	retlw	 17
	retlw	 31
	retlw	 17
	retlw	 0

	retlw	 2	;  74 - J
	retlw	 17
	retlw	 31
	retlw	 16
	retlw	 0

	retlw	 31	;  75 - K
	retlw	 4
	retlw	 10
	retlw	 17
	retlw	 0

	retlw	 31	;  76 - L
	retlw	 1
	retlw	 1
	retlw	 1
	retlw	 0

	retlw	 31	;  77 - M
	retlw	 8
	retlw	 4
	retlw	 8
	retlw	 31

	retlw	 31	;  78 - N
	retlw	 8
	retlw	 4
	retlw	 2
	retlw	 31

;	retlw	 31	;  79 - O
;	retlw	 17
;	retlw	 17
;	retlw	 17
;	retlw	 31

	retlw	 14	;  79 - O
	retlw	 17
	retlw	 17
	retlw	 17
	retlw	 14

	retlw	 31	;  80 - P
	retlw	 20
	retlw	 20
	retlw	 20
	retlw	 8

	retlw	 31	;  81 - Q
	retlw	 17
	retlw	 21
	retlw	 19
	retlw	 15

	retlw	 31	;  82 - R
	retlw	 20
	retlw	 22
	retlw	 21
	retlw	 9

	retlw	 8	;  83 - S
	retlw	 21
	retlw	 21
	retlw	 21
	retlw	 2

	retlw	 16	;  84 - T
	retlw	 16
	retlw	 31
	retlw	 16
	retlw	 16

	retlw	 31	;  85 - U
	retlw	 1
	retlw	 1
	retlw	 1
	retlw	 31

;	retlw	 16	;  86 - V
;	retlw	 8
;	retlw	 4
;	retlw	 2
;	retlw	 31

	retlw	 24	;  86 - V
	retlw	 6
	retlw	 1
	retlw	 6
	retlw	 24

	retlw	 30	;  87 - W
	retlw	 1
	retlw	 6
	retlw	 1
	retlw	 30

	retlw	 17	;  88 - X
	retlw	 10
	retlw	 4
	retlw	 10
	retlw	 17

	retlw	 16	;  89 - Y
	retlw	 8
	retlw	 7
	retlw	 8
	retlw	 16

	retlw	 17	;  90 - Z
	retlw	 19
	retlw	 21
	retlw	 25
	retlw	 17

	retlw	 31	;  91 - [
	retlw	 17
	retlw	 17
	retlw	 0
	retlw	 0

	retlw	 16	;  92 - \
	retlw	 8
	retlw	 4
	retlw	 2
	retlw	 1

	retlw	 17	;  93 - ]
	retlw	 17
	retlw	 31
	retlw	 0
	retlw	 0

	retlw	 0	;  94 - ^
	retlw	 8
	retlw	 16
	retlw	 8
	retlw	 0

	retlw	 31	;  95 - _
	retlw	 31
	retlw	 31
	retlw	 31
	retlw	 31

T_BEACON
	addwf	PC, f
	retlw	' '
	retlw	'>'
	retlw	'>'
	retlw	' '
	retlw	'H'
	retlw	'E'
	retlw	'L'
	retlw	'L'
	retlw	'S'
	retlw	'C'
	retlw	'H'
	retlw	'R'
	retlw	'E'
	retlw	'I'
	retlw	'B'
	retlw	'E'
	retlw	'R'
	retlw	' '
	retlw	'B'
	retlw	'E'
	retlw	'A'
	retlw	'C'
	retlw	'O'
	retlw	'N'
	retlw	' '
	retlw	'V'
	retlw	'I'
	retlw	'A'
	retlw	' '
	retlw	'P'
	retlw	'I'
	retlw	'C'
	retlw	'1'
	retlw	'6'
	retlw	'C'
	retlw	'8'
	retlw	'4'
	retlw	' '
	retlw	'M'
	retlw	'C'
	retlw	'U'
	retlw	' '
	retlw	'D'
	retlw	'E'
	retlw	' '
	retlw	'Z'
	retlw	'L'
	retlw	'1'
	retlw	'H'
	retlw	'I'
	retlw	'T'
	retlw	' '
	retlw	'<'
	retlw	'<'
	retlw	' '
	retlw	' '
	retlw	0

T_CALLSIGN
	addwf	PC, f
	retlw	'Z'
	retlw	'L'
	retlw	'1'
	retlw	'H'
	retlw	'I'
	retlw	'T'
	retlw	0

	END