Subversion Repositories svn.mios

Rev

Rev 52 | Details | Compare with Previous | Last modification | View Log | RSS feed

Rev Author Line No. Line
53 tk 1
; $Id: mios_hlp.inc 53 2008-01-30 22:52:41Z tk $
1 tk 2
;
3
; Misc Help Routines
4
;
5
; ==========================================================================
6
;
7
;  Copyright 1998-2006 Thorsten Klose (tk@midibox.org)
8
;  Licensed for personal non-commercial use only.
9
;  All other rights reserved.
10
;
11
; ==========================================================================
12
 
13
;; --------------------------------------------------------------------------
14
;;  FUNCTION: MIOS_HLP_GetIndex_2bytes
15
;;  C_DECLARATION: not available in C
16
;;  DESCRIPTION: this help function can be used for jumptables which
17
;;  contain 2-byte instructions (-> rgoto).
18
;;  Note that the JUMPTABLE_2BYTES macro allows to use this function
19
;;  securely without the danger that the code behind the table will
20
;;  be executed if the index number in WREG is greater than the number
21
;;  of entries
22
;;  IN: index in WREG
23
;;  OUT: jump to indexed entry
24
;;  USES: -
25
;;  EXAMPLE:
26
;;	;; index is already in WREG
27
;;	JUMPTABLE_2BYTES 4	; (4 entries)
28
;;	rgoto	Function_for_WREG_00
29
;;	rgoto	Function_for_WREG_01
30
;;	rgoto	Function_for_WREG_02
31
;;	rgoto	Function_for_WREG_03
32
;;
33
;;Function_for_WREG_00
34
;;	;; ...
35
;;Function_for_WREG_01
36
;;	;; ...
37
;;Function_for_WREG_02
38
;;	;; ...
39
;;Function_for_WREG_03
40
;;	;; ...
41
;;
42
;; --------------------------------------------------------------------------
43
MIOS_HLP_GetIndex_2bytes
44
	clrc
45
        rlf	WREG, W
46
        addwf   TOSL, F
47
	skpnc
48
        incf    TOSH, F
49
#if PIC_DERIVATIVE_CODE_SIZE > 0x10000
50
	skpnc
51
        incf    TOSU, F
52
#endif
53
        return
54
 
55
;; --------------------------------------------------------------------------
56
;;  FUNCTION: MIOS_HLP_GetIndex_4bytes
57
;;  C_DECLARATION: not available in C
58
;;  DESCRIPTION: this help function can be used for jumptables which
59
;;  contain 4-byte instructions (-> goto).
60
;;  Note that the JUMPTABLE_4BYTES macro allows to use this function
61
;;  securely without the danger that the code behind the table will
62
;;  be executed if the index number in WREG is greater than the number
63
;;  of entries
64
;;  IN: index in WREG
65
;;  OUT: jump to indexed entry
66
;;  USES: -
67
;;  EXAMPLE:
68
;;	;; index is already in WREG
69
;;	JUMPTABLE_4BYTES 4	; (4 entries)
70
;;	goto	Function_for_WREG_00
71
;;	goto	Function_for_WREG_01
72
;;	goto	Function_for_WREG_02
73
;;	goto	Function_for_WREG_03
74
;;
75
;;	;; far away from this jumptable (so that rgoto cannot be used...)
76
;;
77
;;Function_for_WREG_00
78
;;	;; ...
79
;;Function_for_WREG_01
80
;;	;; ...
81
;;Function_for_WREG_02
82
;;	;; ...
83
;;Function_for_WREG_03
84
;;	;; ...
85
;;
86
;; --------------------------------------------------------------------------
87
MIOS_HLP_GetIndex_4bytes
88
	clrc
89
        rlf	WREG, F
90
	clrc
91
        rlf	WREG, W
92
        addwf   TOSL, F
93
	skpnc
94
        incf    TOSH, F
95
#if PIC_DERIVATIVE_CODE_SIZE > 0x10000
96
	skpnc
97
        incf    TOSU, F
98
#endif
99
        return
100
 
101
 
102
;; --------------------------------------------------------------------------
103
;;  FUNCTION: MIOS_HLP_AddressFromTable
104
;;  C_DECLARATION: not available in C
105
;;  DESCRIPTION: this help function reads a pointer from a table and
106
;;  moves it to TBLPTR. On this way linked lists can be realized
107
;;  NOTE: TBLPTRU not read or changed. Table should be located within a 64k segment!
108
;;  IN: pointer to entry in TBLPTR[LH]
109
;;  OUT: new pointer in TBLPTR[LH]
110
;;  USES: -
111
;; --------------------------------------------------------------------------
112
MIOS_HLP_AddressFromTable
113
	tblrd*+
114
	movff	TABLAT, MIOS_AFT_PTRL
115
	tblrd*+
116
	movff	MIOS_AFT_PTRL, TBLPTRL
117
	movff	TABLAT, TBLPTRH
118
	return
119
 
120
;; --------------------------------------------------------------------------
121
;;  FUNCTION: MIOS_HLP_IndirectJump
122
;;  C_DECLARATION: not available in C
123
;;  DESCRIPTION: this help function reads a pointer from a table and
124
;;  jumps to this pointer
125
;;  NOTE: TBLPTRU not read or changed. Table and target address should be located within a 64k segment!
126
;;  IN: pointer to entry in TBLPTR[LH]
127
;;  OUT: jumps indirectly to [TBLPTR[LH]]
128
;;  USES: WREG
129
;; --------------------------------------------------------------------------
130
MIOS_HLP_IndirectJump
131
	IRQ_DISABLE
132
	push
133
	tblrd*+
134
	movf	TABLAT, W
135
	movwf	TOSL
136
	tblrd*+
137
	movf	TABLAT, W
138
	movwf	TOSH
139
	IRQ_ENABLE
140
	return
141
 
142
 
143
;; ==========================================================================
144
 
145
;; --------------------------------------------------------------------------
146
;;  FUNCTION: MIOS_HLP_GetBitANDMask
147
;;  C_DECLARATION: unsigned char MIOS_HLP_GetBitANDMask(unsigned char value)
148
;;  DESCRIPTION: this help function is usefull for bit manipulations
149
;;  IN:	see map below
150
;;  C_IN: see map below
151
;;  OUT: 0x00 -> b'11111110'
152
;;       0x01 -> b'11111101'
153
;;       0x02 -> b'11111011'
154
;;       0x03 -> b'11110111'
155
;;       0x04 -> b'11101111'
156
;;       0x05 -> b'11011111'
157
;;       0x06 -> b'10111111'
158
;;       0x07 -> b'01111111'
159
;;  C_OUT: 0x00 -> 0b11111110
160
;;       0x01 -> 0b11111101
161
;;       0x02 -> 0b11111011
162
;;       0x03 -> 0b11110111
163
;;       0x04 -> 0b11101111
164
;;       0x05 -> 0b11011111
165
;;       0x06 -> 0b10111111
166
;;       0x07 -> 0b01111111
167
;;  USES: -
168
;; --------------------------------------------------------------------------
169
MIOS_HLP_GetBitANDMask
170
	BRA_IFSET WREG, 2, ACCESS, MIOS_HLP_GetBitANDMask_4567
171
MIOS_HLP_GetBitANDMask_0123
172
	BRA_IFSET WREG, 1, ACCESS, MIOS_HLP_GetBitANDMask_23
173
MIOS_HLP_GetBitANDMask_01
174
	btfss	WREG, 0
175
	retlw	b'11111110'
176
	retlw	b'11111101'
177
MIOS_HLP_GetBitANDMask_23
178
	btfss	WREG, 0
179
	retlw	b'11111011'
180
	retlw	b'11110111'
181
 
182
MIOS_HLP_GetBitANDMask_4567
183
	BRA_IFSET WREG, 1, ACCESS, MIOS_HLP_GetBitANDMask_67
184
MIOS_HLP_GetBitANDMask_45
185
	btfss	WREG, 0
186
	retlw	b'11101111'
187
	retlw	b'11011111'
188
MIOS_HLP_GetBitANDMask_67
189
	btfss	WREG, 0
190
	retlw	b'10111111'
191
	retlw	b'01111111'
192
 
193
;; --------------------------------------------------------------------------
194
;;  FUNCTION: MIOS_HLP_GetBitORMask
195
;;  C_DECLARATION: unsigned char MIOS_HLP_GetBitORMask(unsigned char value);
196
;;  DESCRIPTION: this help function is usefull for bit manipulations
197
;;  IN:	see map below
198
;;  C_IN: see map below
199
;;  OUT: 0x00 -> b'00000001'
200
;;       0x01 -> b'00000010'
201
;;       0x02 -> b'00000100'
202
;;       0x03 -> b'00001000'
203
;;       0x04 -> b'00010000'
204
;;       0x05 -> b'00100000'
205
;;       0x06 -> b'01000000'
206
;;       0x07 -> b'10000000'
207
;;  C_OUT: 0x00 -> 0b00000001
208
;;       0x01 -> 0b00000010
209
;;       0x02 -> 0b00000100
210
;;       0x03 -> 0b00001000
211
;;       0x04 -> 0b00010000
212
;;       0x05 -> 0b00100000
213
;;       0x06 -> 0b01000000
214
;;       0x07 -> 0b10000000
215
;;  USES: -
216
;; --------------------------------------------------------------------------
217
MIOS_HLP_GetBitORMask
218
	BRA_IFSET WREG, 2, ACCESS, MIOS_HLP_GetBitORMask_4567
219
MIOS_HLP_GetBitORMask_0123
220
	BRA_IFSET WREG, 1, ACCESS, MIOS_HLP_GetBitORMask_23
221
MIOS_HLP_GetBitORMask_01
222
	btfss	WREG, 0
223
	retlw	b'00000001'
224
	retlw	b'00000010'
225
MIOS_HLP_GetBitORMask_23
226
	btfss	WREG, 0
227
	retlw	b'00000100'
228
	retlw	b'00001000'
229
 
230
MIOS_HLP_GetBitORMask_4567
231
	BRA_IFSET WREG, 1, ACCESS, MIOS_HLP_GetBitORMask_67
232
MIOS_HLP_GetBitORMask_45
233
	btfss	WREG, 0
234
	retlw	b'00010000'
235
	retlw	b'00100000'
236
MIOS_HLP_GetBitORMask_67
237
	btfss	WREG, 0
238
	retlw	b'01000000'
239
	retlw	b'10000000'
240
 
241
;; ==========================================================================
242
 
243
;; --------------------------------------------------------------------------
244
;;  FUNCTION: MIOS_HLP_16bitAddSaturate
245
;;  C_DECLARATION: unsigned char MIOS_HLP_16bitAddSaturate(unsigned char add_value, unsigned int *ptr, unsigned int max_value)
246
;;  DESCRIPTION: adds a signed 8-bit value to a 16 bit value and saturates<BR>
247
;;  That means: if the resulting value is greater than the given max value,
248
;;  the result will be saturated to the max value. If the resulting value
249
;;  is less than 0, the result will be saturated to 0<BR>
250
;;  Important: the 16-bit value must be aligned to an even word address
251
;;  (0x10, 0x12, 0x14, ...). First address contains the low-byte and
252
;;  the second address contains the high-byte
253
;;  IN:	  8-bit signed value in WREG
254
;;	  pointer to low/high byte which should be modified in FSR1
255
;;        low-byte of max value in MIOS_PARAMETER1
256
;;        high-byte of max value in MIOS_PARAMETER2
257
;;  C_IN: 8-bit signed value in <add_value>
258
;;	  pointer to variable which should be modified in <ptr>
259
;;        max value in <max_value>
260
;;  OUT:  returns new absolute value in FSR1
261
;;        WREG and MIOS_PARAMETER1[0] is 1, if the value has been changed, 0 if it
262
;;           is equal to the old value
263
;;  C_OUT: writes new absolute value into *ptr
264
;;        returns 1, if the value has been changed, 0 if it
265
;;           is equal to the old value
266
;;  USES: BSR, INDF1 (FSR1 untouched), MIOS_PARAMETER[123]
267
;;  EXAMPLE:
268
;;
269
;;	;; subtract -5 from the 16-bit value
270
;;      ;; [FSR1] == INDF1 is 0x0002
271
;;      ;; max-value is 0x0fff
272
;;      movlw   0xff			; low-byte of max value
273
;;      movwf   MIOS_PARAMETER1
274
;;      movlw   0x0f			; high-byte of max value
275
;;      movwf   MIOS_PARAMETER2
276
;;	movlw	-5			; incrementer is -5
277
;;	call	MIOS_HLP_16bitAddSaturate
278
;;      ;; now INDF1 contains 0x0000 due to saturation
279
;;      ;; MIOS_PARAMETER1[0] is 1 since the value has been changed
280
;;
281
;;      ;; subtract -5 again
282
;;      ;; [FSR1] == INDF1 is 0x0000
283
;;      movlw   0xff			; low-byte of max value
284
;;      movwf   MIOS_PARAMETER1
285
;;      movlw   0x0f			; high-byte of max value
286
;;      movwf   MIOS_PARAMETER2
287
;;	movlw	-5			; incrementer is -5
288
;;	call	MIOS_HLP_16bitAddSaturate
289
;;      ;; now INDF1 contains 0x0000 due to saturation
290
;;      ;; MIOS_PARAMETER1[0] is 0 since the value has NOT been changed
291
;;
292
;;
293
;;
294
;;	;; add 30 to the 16-bit value
295
;;      ;; [FSR1] == INDF1 is 0x0ffe
296
;;      ;; max-value is 0x0fff
297
;;      movlw   0xff			; low-byte of max value
298
;;      movwf   MIOS_PARAMETER1
299
;;      movlw   0x0f			; high-byte of max value
300
;;      movwf   MIOS_PARAMETER2
301
;;	movlw	30			; incrementer is 30
302
;;	call	MIOS_HLP_16bitAddSaturate
303
;;      ;; now INDF1 contains 0x0fff due to saturation
304
;;      ;; MIOS_PARAMETER1[0] is 1 since the value has been changed
305
;;
306
;;  C_EXAMPLE:
307
;;
308
;;	// subtract -5 from the 16-bit value (unsigned int)
309
;;	MIOS_HLP_16bitAddSaturate(-5, &value, 0x0fff);
310
;;
311
;; --------------------------------------------------------------------------
312
MIOS_HLP_16bitAddSaturate
313
	movwf	MIOS_PARAMETER3			; save incrementer in MIOS_PARAMETER3
314
 
315
	bcf	FSR1L, 0			; switch to low-byte
316
	movff	INDF1, MIOS_TMP1		; store low-byte in TMP_L
317
	bsf	FSR1L, 0			; switch to high-byte
318
	movff	INDF1, MIOS_TMP2		; store low-byte in TMP_H
319
	bcf	FSR1L, 0			; switch to low-byte
320
 
321
	addwf	INDF1, F			; add (or subtract if negative) to low-byte
322
	bsf	FSR1L, 0			; switch to high-byte
323
	movlw	0x00				; if positive add 0 to high-byte
324
	btfsc	MIOS_PARAMETER3, 7		; if negative add 0xff to high-byte
325
	movlw	0xff
326
	addwfc	INDF1, F			; add to high-byte
327
 
328
	;; now saturate the absolute value, depending on addition or subtraction
329
	BRA_IFSET MIOS_PARAMETER3, 7, ACCESS, MIOS_HLP_16bitAddSaturate_Dec
330
MIOS_HLP_16bitAddSaturate_Inc
331
	;; if positive: saturate with max-value
332
	;; check if max value has been reached: max - current < 0
333
 
334
	bcf	FSR1L, 0	; switch to low-byte
335
 
336
	;; absolute value (low-byte) now in INDF1
337
	;; max value (low-byte) in MIOS_PARAMETER[12]
338
	;; calc MIOS_PARAMETER[12] - INDF1 (LH)
339
	movf	INDF1, W
340
	subwf	MIOS_PARAMETER1, W
341
	bsf	FSR1L, 0	; switch to high-byte
342
	movf	INDF1, W
343
	subwfb	MIOS_PARAMETER2, W
344
 
345
	;; skip saturation if result is not negative
346
	bnn	MIOS_HLP_16bitAddSaturate_Cont
347
 
348
	;; else copy max value to absolute value
349
	movff	MIOS_PARAMETER2, INDF1
350
	bcf	FSR1L, 0	; switch to low-byte
351
	movff	MIOS_PARAMETER1, INDF1
352
 
353
	rgoto	MIOS_HLP_16bitAddSaturate_Cont
354
 
355
MIOS_HLP_16bitAddSaturate_Dec
356
	;; if negative (counter clockwise turn): saturate with zero
357
	BRA_IFCLR INDF1, 7, ACCESS, MIOS_HLP_16bitAddSaturate_Cont; (result not negative)
358
	clrf	INDF1		; clear high-byte
359
	bcf	FSR1L, 0	; switch to low-byte
360
	clrf	INDF1		; clear low-byte
361
	;; 	rgoto	HN_ENC_SendVPot_Cont	; continue
362
MIOS_HLP_16bitAddSaturate_Cont
363
 
364
	;; set MIOS_PARAMETER[1] if value has been changed
365
	clrf	MIOS_PARAMETER1
366
	SET_BSR	MIOS_TMP1
367
 
368
	bcf	FSR1L, 0			; switch to low-byte
369
	movf	INDF1, W
370
	xorwf	MIOS_TMP1, W, BANKED
371
	skpz
372
	bsf	MIOS_PARAMETER1, 0
373
 
374
	bsf	FSR1L, 0			; switch to high-byte
375
	movf	INDF1, W
376
	xorwf	MIOS_TMP2, W, BANKED
377
	skpz
378
	bsf	MIOS_PARAMETER1, 0
379
 
380
	bcf	FSR1L, 0			; switch to low-byte
381
	movf	MIOS_PARAMETER1, W		; get parameter
382
 
383
	return
384
 
385
;; ==========================================================================
386
 
387
;; --------------------------------------------------------------------------
388
;;  FUNCTION: MIOS_HLP_Dec2BCD
389
;;  C_DECLARATION: void MIOS_HLP_Dec2BCD(unsigned int value)
390
;;  DESCRIPTION: converts a 16-bit decimal value to BCD
391
;;  IN:	  low-byte in WREG
392
;;	  high-byte in MIOS_PARAMETER1
393
;;  C_IN: 16bit value in <value>
394
;;  OUT:  rightmost digits (n1*10^1 and n0*10^0) in WREG and MIOS_PARAMETER1
395
;;        middle digits (n3*10^3 and n2*10^2) in MIOS_PARAMETER2
396
;;        leftmost digit (n5*10^4) in MIOS_PARAMETER3
397
;;  C_OUT:  rightmost digits (n1*10^1 and n0*10^0) in MIOS_PARAMETER1
398
;;        middle digits (n3*10^3 and n2*10^2) in MIOS_PARAMETER2
399
;;        leftmost digit (n5*10^4) in MIOS_PARAMETER3
400
;;  USES: BSR, MIOS_PARAMETER[123]
401
;;  EXAMPLE:
402
;;
403
;;	;; get the BCD code from 12345
404
;;      movlw	(12345) >> 8		; store high-byte in MIOS_PARAMETER1
405
;;	movwf	MIOS_PARAMETER1
406
;;	movlw	(12345) & 0xff		; store low-byte in WREG
407
;;	call	MIOS_HLP_Dec2BCD	; convert to BCD code
408
;;	;; now:
409
;;	;;    MIOS_PARAMETER3 contains the hex-value 0x01
410
;;	;;    MIOS_PARAMETER2 contains the hex-value 0x23
411
;;	;;    MIOS_PARAMETER1 contains the hex-value 0x45
412
;;	;;    WREG            contains also the hex-value 0x45
413
;;  C_EXAMPLE:
414
;;
415
;;	// get the BCD code from 12345
416
;;	MIOS_HLP_Dec2BCD(12345);
417
;;	// now:
418
;;	//    MIOS_PARAMETER3 contains the hex-value 0x01
419
;;	//    MIOS_PARAMETER2 contains the hex-value 0x23
420
;;	//    MIOS_PARAMETER1 contains the hex-value 0x45
421
;; --------------------------------------------------------------------------
422
MIOS_HLP_Dec2BCD
423
;; NOTE: code from AN544 of Microchip
424
;; --[ BEGIN MACRO ] --------------------------------------------------------
425
MIOS_HLP_Dec2BCD_ADJUST MACRO reg
426
	movlw   0x03
427
	addwf   reg, W, BANKED
428
	btfsc	WREG, 3		; test if result > 7
429
	movwf   reg
430
	movlw   0x30
431
	addwf   reg,W, BANKED
432
	btfsc	WREG, 7		; test if result > 7
433
	movwf   reg, BANKED     ; save as MSD
434
	ENDM
435
;; --[ END MACRO ] ----------------------------------------------------------
436
 
437
	SET_BSR	MIOS_TMP1
438
 
439
	;; copy value to MIOS_PARAMETER[12]
440
	movff	MIOS_PARAMETER1, MIOS_PARAMETER2
441
	movwf	MIOS_PARAMETER1
442
 
443
	clrc			; clear the carry bit
444
	movlw   0x10
445
	movwf   MIOS_PARAMETER3	; (used as counter)
446
	clrf    MIOS_TMP3, BANKED
447
	clrf    MIOS_TMP2, BANKED
448
	clrf    MIOS_TMP1, BANKED
449
MIOS_HLP_Dec2BCD_Loop
450
	rlf     MIOS_PARAMETER1, F
451
	rlf     MIOS_PARAMETER2, F
452
	rlf     MIOS_TMP1, F, BANKED
453
	rlf     MIOS_TMP2, F, BANKED
454
	rlf     MIOS_TMP3, F, BANKED
455
 
456
	dcfsnz  MIOS_PARAMETER3, F	; (used as counter)
457
	rgoto	MIOS_HLP_Dec2BCD_End
458
 
459
	MIOS_HLP_Dec2BCD_ADJUST	MIOS_TMP3
460
	MIOS_HLP_Dec2BCD_ADJUST	MIOS_TMP2
461
	MIOS_HLP_Dec2BCD_ADJUST	MIOS_TMP1
462
	rgoto   MIOS_HLP_Dec2BCD_Loop
463
 
464
MIOS_HLP_Dec2BCD_End
465
	movff	MIOS_TMP3, MIOS_PARAMETER3
466
	movff	MIOS_TMP2, MIOS_PARAMETER2
467
	movf	MIOS_TMP1, W, BANKED
468
	movwf	MIOS_PARAMETER1
469
	return