How about this bit of optimized code? I believe the following properly
emulates your original code.
push R30
push R31 ; push Z
clr R17 ; R17:16 = character offset
mov R30, R16 ; R17:16 -> Z
mov R31, R17
add R30, R30 ; Z + Z = 2x
adc R31, R31
add R30, R16 ; Z + R17:16 = 3x
adc R31, R17
add R30, R30 ; Z + Z = 6x
adc R31, R31
add R30, R16 ; Z + R17:16 = 7x
adc R31, R17
add R30, rownum ; Add in row offset
adc R31, R17 ; this has 0x00 in it.
; Add in char gen base offset adjusted for the lack of
; data below character 32
subi R30, low(-((CHAR_GEN*2) - (' '*7)))
sbci R31, high(-((CHAR_GEN*2) - (' '*7)))
lpm
pop R31
pop R30
ret
-----Original Message-----
From: John Samperi [mailto:samperi@ampertronics.com.au]
Sent: Friday, December 03, 2004 4:17 PM
To: AVR-Chat@yahoogroups.com
Subject: Re: [AVR-Chat] Reading from flash in Assembly
At 06:48 PM 3/12/04 -0500, you wrote:
OK this is what I do to get the data from a character generator
look up table (an array of 224 rows x 7 bytes wide).
;r16 has the character we want to get the data for 0x20-0xff
good_char:
subi r16,' ' ;Multiplier LSB (this just deducts 32 (0x20) from the number)
clr r17 ;Multiplier MSB (as there is no data for char 0-31 or control
chars)
ldi r18,7 ;Multiplicand LSB, 7 bytes each char
clr r19 ;Multiplicand MSB
rcall mpy16u ;Find offset in CHAR_GEN table
;of first row results in r18 and r19
push zl ;push z as this routine happens during ints
push zh
clr zh
mov zl,rownum ;Load z with row_num
add zl,r18 ;Add offset results
adc zh,r19
ldi r16,low(CHAR_GEN*2)
ldi r17,high(CHAR_GEN*2)
add zl,r16 ;Add char gen start address
adc zh,r17
lpm ;Go and get CG char into r0
pop zh ;restore z
pop zl
ret
As you can see it's a LOT longer that what you have but it has been working
for many years, if anyone can shorten it I would be grateful :-))
Regards
John SamperiMessage
RE: [AVR-Chat] Reading from flash in Assembly
2004-12-04 by Larry Barello
Attachments
- No local attachments were found for this message.