File: morse.asm

package info (click to toggle)
picasm 1.14-1
  • links: PTS
  • area: main
  • in suites: etch, etch-m68k
  • size: 528 kB
  • ctags: 378
  • sloc: ansic: 4,481; asm: 150; makefile: 72
file content (224 lines) | stat: -rw-r--r-- 3,302 bytes parent folder | download | duplicates (4)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
;
; morse.asm -- send morse code...
;
; also includes some local labels (for testing...)
;

;
; example source code for picasm by Timo Rossi
;

;
; define PIC device type
;
	device	pic16f84

;
; define config fuses
;
	config	CP=off,WDT=off,PWRT=off,OSC=hs

;
; include PIC register definitions, and some macros
;
	include "pic16f84.i"
	include "picmac.i"

;
; include file with morse code definition macros
;
	include "morse.i"

;
; bit definitions for port A
;
A_MOUT	equ	0	;morse code output (buzzer)
A_LED2	equ	1	;led (not really used in this program)


DOT_DELAY	equ	15
DASH_DELAY	equ	3*DOT_DELAY

;
; define some register file variables
;

	org	$0C

delay_cnt	ds	1	;200hz delay counter

d_cnt		ds	1	;internal delay counter

morsebyte	ds	1
bitcnt		ds	1

pa_xor_val	ds	1

temp_w		ds	1
temp_s		ds	1

;
; define a morse code message in data EEPROM
;
	org	0

	morsedata edata,"hello world "

	edata	0	;end marker
;
; code start
;
	org	0
	goto	reset_entry


	org	4
;
; interrupt entry point
;
; 4MHz crystal --> 1MHz instruction clock
; TMR0 free-running, prescaler divides by 4 -->
;
; timer interrupt occurs 976 times per second
;
	save_w_stat

	decf	d_cnt,F
	bnz	int_a

	movlw	5
	movwf	d_cnt

;
; delay_cnt is decremenmented every 6's interrupt
; --> 195 times per second (delay approx 5 ms)
;
	decf	delay_cnt,F

int_a
;
; sound is generated by toggling the buzzer output once per interrupt,
; so the fundamental frequency is 488 Hz.
;
	movf	pa_xor_val,W
	xorwf	PORTA,F

	bcf	INTCON,T0IF
	restore_w_stat
	retfie

reset_entry:
	movlw	0xff
	movwf	PORTA	;initialize port A so that LED and buzzer are off

	bsf	STATUS,RP0			;register page 1
	movlw	~((1<<A_MOUT)|(1<<A_LED2))	;LEDs as outputs,
	movwf	TRISA^80h			;other PORTA pins as inputs

; timer counts instruction cycles, assign prescaler to timer, divide by 4
; (and disable port B weak pull-ups)
	movlw	(1<<RBPU)|(1<<PS0)
	movwf	OPTION_REG^80h

	bcf	STATUS,RP0			;register page 0

	movlw	1
	movwf	d_cnt

	clrf	pa_xor_val

	movlw	(1<<T0IE)|(1<<GIE)	;enable timer interrupt
	movwf	INTCON

restart_string
	clrf	EEADR

loop
	bsf	STATUS,RP0	;reg. page 1
	bsf	EECON1^80h,ERD	;read EEPROM
	bcf	STATUS,RP0	;reg. page 0
	movf	EEDATA,W
	bz	restart_string

	call	send_morse_char
	incf	EEADR,F
	goto	loop

;
; send one morse code character
; character code (generated by the morsechar macro) in W
;
send_morse_char
	movwf	morsebyte
	comf	morsebyte,W
	bz	send_space

	movlw	7
	movwf	bitcnt

	local

skip_pad_loop
	brset	morsebyte,7,=skipped
	decf	bitcnt,F
; we don't care if carry is set or not, the bits shifed in
; by the following instruction are not used anyway
	rlf	morsebyte,F
	goto	skip_pad_loop

=skipped
	rlf	morsebyte,F

	endlocal

	local
=loop
	btfss	morsebyte,7
	call	dot
	btfsc	morsebyte,7
	call	dash
	rlf	morsebyte,F

	movlw	DOT_DELAY
	call	delay

	decfsz	bitcnt,F
	goto	=loop

	endlocal

	movlw	2*DOT_DELAY	;inter-character gap
	call	delay
	return

send_space
	movlw	2*DOT_DELAY
	call	delay
	movlw	3*DOT_DELAY
	call	delay
	return

dash	movlw	DASH_DELAY
	goto	dot_dash

dot	movlw	DOT_DELAY

dot_dash
	bsf	pa_xor_val,A_MOUT	;start sound
	call	delay
	bcf	pa_xor_val,A_MOUT	;end sound
	bsf	PORTA,A_MOUT		;make sure the buzzer is off
	return

	local
;
; delay approx. W*5ms
;
delay	movwf	delay_cnt
=loop
	bpos	delay_cnt,=loop
	return

	endlocal

	end