PDA

View Full Version : While we're on the subject of optimization...



skimask
- 4th January 2007, 03:22
I know there's a way to make this better...
I'm doing characters on a graphic LCD. Everything works well, it's just that the code below is clumsy at best. I know there's a better looking way to do it, I just cannot think of it....
What is it! Anyone? 'cause I'm out of ideas at the moment...(and it'll probably hit me at about 2am while I'm sleeping of course)...

if menu = 1 then
gosub clearalllines
lcdchardata[0] = "R" : lcdpx = 0 : lcdpy = 0 : gosub puttext : lcdchardata[0] = "E" : lcdpx = 1 : lcdpy = 0 : gosub puttext
lcdchardata[0] = "S" : lcdpx = 2 : lcdpy = 0 : gosub puttext : lcdchardata[0] = "E" : lcdpx = 3 : lcdpy = 0 : gosub puttext
lcdchardata[0] = "T" : lcdpx = 4 : lcdpy = 0 : gosub puttext : lcdchardata[0] = " " : lcdpx = 5 : lcdpy = 0 : gosub puttext
lcdchardata[0] = "E" : lcdpx = 6 : lcdpy = 0 : gosub puttext : lcdchardata[0] = "L" : lcdpx = 7 : lcdpy = 0 : gosub puttext
lcdchardata[0] = "M" : lcdpx = 8 : lcdpy = 0 : gosub puttext : lcdchardata[0] = "3" : lcdpx = 9 : lcdpy = 0 : gosub puttext
lcdchardata[0] = "2" : lcdpx = 10 : lcdpy = 0 : gosub puttext : lcdchardata[0] = "7" : lcdpx = 11 : lcdpy = 0 : gosub puttext
lcdchardata[0] = "." : lcdpx = 12 : lcdpy = 0 : gosub puttext : lcdchardata[0] = "." : lcdpx = 13 : lcdpy = 0 : gosub puttext
lcdchardata[0] = "." : lcdpx = 14 : lcdpy = 0 : gosub puttext
gosub clearserialbuffer

Darrel Taylor
- 4th January 2007, 04:17
16F or 18F ?
<br>

skimask
- 4th January 2007, 04:46
16F or 18F ?
<br>

18F4620...
Trying some asm at the moment...but I still know there's something easier and yet more compact than what I've got... just... what... is... it...
Spock...help... me ... here...

Darrel Taylor
- 4th January 2007, 06:46
Here's a slight modification of the old Embedded String thread...
lcdpx VAR byte
lcdpy VAR BYTE
Addr VAR WORD

ASM
PrintStr macro x, y, Str
local TheString, OverStr
goto OverStr
TheString
data Str, 0
OverStr
MOVE?CB x, _lcdpx
MOVE?CB y, _lcdpy
MOVE?CW TheString, _Addr
L?CALL _StringOut
endm
ENDASM

Char VAR lcdchardata[0]
StringOut:
Readcode Addr, Char ' Get a character
if Char = 0 then StringDone ' Look for Null char, Stop if found
gosub puttext
Addr = Addr + 1 ' Point to next character
lcdpx = lcdpx + 1
goto StringOut ' Continue with rest of the string
StringDone:
return
;-----------------------------------------------------------------------------Then you can do this...
@ PrintStr 0,0, "RESET ELM327..."
@ PrintStr 0,1, "Hello World!"

HTH,

skimask
- 4th January 2007, 06:55
Here's a slight modification of the old Embedded String thread...
lcdpx VAR byte
lcdpy VAR BYTE
Addr VAR WORD

ASM
PrintStr macro x, y, Str
local TheString, OverStr
goto OverStr
TheString
data Str, 0
OverStr
MOVE?CB x, _lcdpx
MOVE?CB y, _lcdpy
MOVE?CW TheString, _Addr
L?CALL _StringOut
endm
ENDASM

Char VAR lcdchardata[0]
StringOut:
Readcode Addr, Char ' Get a character
if Char = 0 then StringDone ' Look for Null char, Stop if found
gosub puttext
Addr = Addr + 1 ' Point to next character
lcdpx = lcdpx + 1
goto StringOut ' Continue with rest of the string
StringDone:
return
;-----------------------------------------------------------------------------Then you can do this...
@ PrintStr 0,0, "RESET ELM327..."
@ PrintStr 0,1, "Hello World!"

HTH,

Actually, I just found what I was looking for a couple of minutes ago...and I think I'll kick myself now... how about a little LOOKUP !
But....I think I like your solution much better...
As soon as I figure out why my '4620 started double-resetting itself and locking up on initial powerup (without changing the code!!! left the room, came back, sat down, did a verify and it started!), I'll give it a whirl and see what happens. I see nothing but good stuff ('cept for that resetting bit. time to throw another chip I think).

Darrel Taylor
- 4th January 2007, 07:21
Storing it as data in program memory uses about 1/4th the code space compared to LOOKUP.

If you'll have a lot of strings to display, it could save a big chunk of space.
Not that you need to worry about it with the 4620. (64kb)
<br>

skimask
- 7th January 2007, 08:51
Storing it as data in program memory uses about 1/4th the code space compared to LOOKUP.

If you'll have a lot of strings to display, it could save a big chunk of space.
Not that you need to worry about it with the 4620. (64kb)
<br>

I just converted a few of my strings over to your format....
And after fighting with it for about an hour, I figured out that the thing is case sensitive...jeeze...what next...
I'm up to 40K used out of 64K on the '4620, might have to go to a 4685 (or maybe even an '8722 with my little 40 pin adapter I built awhile back). Hopefully this little routine helps me save a LOAD of space. I'm not even halfway done with my program yet.

mister_e
- 7th January 2007, 08:58
Well, using an external EEPROM have it's advantages as well. If you Strings are LCD dedicated, you can also format them the right way in a HEX Editor.

I use bpsoft Hex WorkShop.

skimask
- 7th January 2007, 09:10
Well, using an external EEPROM have it's advantages as well. If you Strings are LCD dedicated, you can also format them the right way in a HEX Editor.

I use bpsoft Hex WorkShop.

I'm using a graphic LCD with a whole set of subroutines to display the characters. I suppose I could probably stored the lines in the eeprom as hard coded characters (1 byte per line, 6 lines per character) and pull them out serially (actually 5x7 character font, could probably do some compression on those to save the extra byte here and there).
When I run out of room on the '4620, I'll plug an eeprom in and see what happens...or just go with a '4685 (or '8722).
Nothing like extra space to cover for sloppy programming!

uh-hum...Windows :) Hate it, but what do we all use?

Darrel Taylor
- 7th January 2007, 09:48
Just keep in mind that no matter how much Flash the PIC has, PBP can only use the first 64kb of it. Same as your 4620.

The additional space can be used to store data, but not PBP program code.
<br>

skimask
- 7th January 2007, 09:57
Just keep in mind that no matter how much Flash the PIC has, PBP can only use the first 64kb of it. Same as your 4620.

The additional space can be used to store data, but not PBP program code.
<br>

Really? I made a program awhile back for my '8722 (with my adapter, plugged into a slot originally for a '4620). I copied/pasted a load of code (a load of LCDOUT statements) back to back just to fill it all up (I wanted to see what would happen)...and it programmed...the full 128K and it ran, all the way to the end.
It looked something like this:
LCDOUT "START"
LCDOUT "SAME" a whole bunch of these lines
LCDOUT "END" : STOP a line like this at the end, verified in the .lst file as being at the end of programmable space

I could've been wrong, but the programmer software (Warp13a) showed it being full up. And the same code wouldn't fit into a '4620. And if you think about it, the '8722 only has 64K-words, the '4620 32K-words, so maybe PBP can still take it.

skimask
- 7th January 2007, 10:37
Storing it as data in program memory uses about 1/4th the code space compared to LOOKUP.

If you'll have a lot of strings to display, it could save a big chunk of space.
Not that you need to worry about it with the 4620. (64kb)
<br>

Kudos to you and all that. I just went thru and converted all of my major string routines to your embedded routine example.
So far, I've saved 7,486 in code space (started with $9C22, now I'm only using $7EE4 of space).
And I've still got to optimize the rest of the code... :)

Darrel Taylor
- 7th January 2007, 11:05
Sweet!

Let me know how it is after optimizing the rest. Just for curiosity sake.
<br>

skimask
- 7th January 2007, 11:35
Down from $9CC4 to $7688, saved 9,788 so far, and I think I'm about done, getting to that point of diminishing returns. That and it's 5:30am....I'm just about spent...

BigWumpus
- 7th January 2007, 12:55
Try to replace the "goto" inside the macro by a "bra".

Darrel Taylor
- 7th January 2007, 18:05
Just keep in mind that no matter how much Flash the PIC has, PBP can only use the first 64kb of it. Same as your 4620.

The additional space can be used to store data, but not PBP program code.
<br>


Really?

No, not really. That didn't come out right at all.

The space above 64K can't be accessed by the READCODE statement. So your string data has to be in the first 64K. The space above 64k can store data, but READCODE can't use it. It's possible to write an ASM routine that does the same thing as readcode and uses the upper space, but it's not built in to PBP.

Hope that clarifies it a bit.
<br>

Darrel Taylor
- 7th January 2007, 18:14
Try to replace the "goto" inside the macro by a "bra".

Sure, good idea. It'll save another word for each instance of PrintStr.
And it only takes one edit. :)
<br>

skimask
- 8th January 2007, 03:04
No, not really. That didn't come out right at all.

The space above 64K can't be accessed by the READCODE statement. So your string data has to be in the first 64K. The space above 64k can store data, but READCODE can't use it. It's possible to write an ASM routine that does the same thing as readcode and uses the upper space, but it's not built in to PBP.

Hope that clarifies it a bit.
<br>

That sounds about right, and makes quite a bit more sense.
So noted for the next project....

skimask
- 8th January 2007, 03:07
Sure, good idea. It'll save another word for each instance of PrintStr.
And it only takes one edit. :)
<br>

And another 129 words saved, brings me up to 9,917 saved so far.
At this rate, I'll be able to fit the program into a 10F202 soon ! :)

skimask
- 11th January 2007, 04:34
And another 129 words saved, brings me up to 9,917 saved so far.
At this rate, I'll be able to fit the program into a 10F202 soon ! :)

And another 3,000-ish saved...from $9CC4 to $6A40... 12,932 words saved so far...

skimask
- 4th January 2008, 03:11
Got a modification of the PRINTSTR macro for my nokia lcd...


ASM
PrintStr macro x, y, Str
local TheString, OverStr
goto OverStr
TheString
data Str, 0
OverStr
MOVE?CB x, _lcdpx
MOVE?CB y, _lcdpy
MOVE?CW TheString, _Addr
L?CALL _StringOut
endm
ENDASM
StringOut:
Readcode Addr, Char : if Char = 0 then StringDone ' Look for Null char, Stop if found
gosub puttext : Addr = Addr + 1 : lcdpx = lcdpx + 1 : goto StringOut
StringDone: return


Is there a conditional directive that'll "overload" (I suppose like C++) the PRINTSTR macro to either accept or ignore 2 extra parameters?
In my case, I want to add foreground color and background color, but not neccessarily one or both at the same time...like this


PrintStr macro x, y, Str , forecolor , backcolor

If both are there, great, process them as normal.
If the background color value isn't there, ignore it and don't change it.
If the foreground color value isn't there, ignore both of them and don't change either.
Sure, it's easy enough to make 3 different versions of the same thing, and use 3 different names, i.e. printstr, printstrf (set foreground only ), printstrfb (set both foreground/background), printstrb (set background only).
If I assumed null-zero's would work, that would be fine except that I'm dealing with 8 bits of color (soon to be 16) and a zero-null is a valid color.

mister_e
- 4th January 2008, 14:27
Well, as far as i'm aware of, MPASM don't provide any features like that. If you don't fill all arguments, it will prompt you. That's one downside.

So you'll probably need to build some different version of you macro, one calling the other or variant of.

skimask
- 5th January 2008, 07:51
Well, as far as i'm aware of, MPASM don't provide any features like that. If you don't fill all arguments, it will prompt you. That's one downside.

It'll prompt me all-right...prompt me with an error message! :D


So you'll probably need to build some different version of you macro, one calling the other or variant of.

I've been pouring over the MPASM documentation looking for some insight into 'overloading' macros like I want to do and not finding anything interesting. I guess it's back to multiple versions of the same thing, but different. It's either that or I'm going to try a version with a 'mode number' in the front, sort like that multiple LCD mod on another thread...
@ printstr 1 , 5 , 5 , "works here" - mode 1 - no color modify
@ printstr 2 , 5 , 5 , 1 , "works here" - mode 2 - foreground color change...
...and so on...
Let the code in the macro do the choosing based on the mode number.
But if I go that way, I may as well have different versions.
More thought required...

Darrel Taylor
- 5th January 2008, 09:11
That's one of only 2 circumstances in which I would prefer PM.EXE

With PM, you are not limited to a specific number of parameters supplied to a macro.

If paramaters are ommited, they show up as "undefined".
Then you can just do a IFNDEF to see if a parameter was included or not.

The second circumstance is IRPC, which can split up each character of a string and repeat the macro for each one.

However, since PM can't "Nest" macro's. It doesn't help a bit.
Not to mention the 18F problem.

And like you've both already pointed out...
MPASM can't do either one of them. :(
<br>

skimask
- 7th January 2008, 19:39
If paramaters are ommited, they show up as "undefined".
Then you can just do a IFNDEF to see if a parameter was included or not.
However, since PM can't "Nest" macro's. It doesn't help a bit.
Not to mention the 18F problem.
And like you've both already pointed out...
MPASM can't do either one of them. :(
<br>
I've come up with a half-way solution to what I want.
I just take the standard @printstr macro, keep all of my parameters inside of the quotes, and count the number of comma's inside the quotes and act accordingly:
4 comma's, all parameters, x, y, string, forecolor, backcolor
3 comma's, all but backcolor
2 comma's, all but colors.
Only limitation is that I can't use a comma (or double-quote, or single-quote) in the string.
Basic string parsing code at work...
Not the optimal solution, not my preferred solution, but it'll work.

mister_e
- 7th January 2008, 20:28
mmpff, to me it doesn't make sense at all to do so, this will just suck juice where it shouldn't need to. I would just prefer to use a macro for the color stuff, and one for the print... or filling the whole thing with all parameter in. but, yeah, that's me :D

skimask
- 7th January 2008, 21:41
mmpff, to me it doesn't make sense at all to do so, this will just suck juice where it shouldn't need to.

I guess my main thing is that I can put the whole thing into one command.
Instead of this:
lcdpx = 10
lcdpy = 10
string = "assuming PBP could handle strings anyways"
forecolor = 5
backcolor = 0

I get this:
@ printstr "10,10,printstr can handle this string after all,5,0"

Might not save any code space, but I can see it saving some sanity...

Mike, K8LH
- 13th January 2008, 10:05
I've used the following method in assembly language programs to reduce LCD string "overhead" by pulling the string address from the stack but I'm not sure how you might implement it in PBP (or if it might save memory compared to how you're doin' it now).

Food for thought. Regards, Mike


;
; example macro usage
;
PutStr "Azimuth:\n\r "
PutStr "Elevation:\n\r"
;


;
; PutStr macro
;
PutStr macro str ; print in-line string
call PutString ;
db str,0
ENDM
;

;************************************************* *****************
;
; PutString - print in-line string via Stack and TBLPTR
;
; string must be terminated with a 00 byte and does not need
; to be word aligned
;
PutString
movff TOSL,TBLPTRL ; copy return address into TBLPTR
movff TOSH,TBLPTRH ;
clrf TBLPTRU ; assume PIC with < 64-KB
PutNext
tblrd *+ ; get in-line string character
movf TABLAT,W ; last character (00)?
bz PutExit ; yes, exit, else
rcall PutLCD ; print character to LCD
bra PutNext ; and do another
PutExit
btfsc TBLPTRL,0 ; odd address?
tblrd *+ ; yes, make it even (fix PC)
movf TBLPTRH,W ; setup new return address
movwf TOSH ;
movf TBLPTRL,W ;
movwf TOSL ;
return ;

skimask
- 11th March 2008, 00:06
Might not save any code space, but I can see it saving some sanity...

How's this for losing some sanity? :D

Darrel Taylor
- 11th March 2008, 01:17
In case someone opens that file, and is running a little short...
Here's an extra roll for ya.

<img src="http://www.picbasic.co.uk/forum/attachment.php?attachmentid=2403&stc=1&d=1205198017" />
<br>

Ioannis
- 11th March 2008, 09:16
Thanks Darrel. I sure needed the extra roll!

Hey Skimask, are you really able to follow the program? I got dizzy... Congrats anyway!

Ioannis

skimask
- 11th March 2008, 12:51
Thanks Darrel. I sure needed the extra roll!
Hey Skimask, are you really able to follow the program? I got dizzy... Congrats anyway!
Ioannis

I suppose it's like anything else when programming...the guy that wrote it can follow it, practically nobody else can...