reduce amount of code space

Go To Last Post
49 posts / 0 new
Author
Message
#1
  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

I am looking to reduce the amount of repetitive typing. My application displays a lot of messages on a 16x2 lcd. I use the following to load the z register and output the data to the lcd

ldi zh,high(line1*2)
ldi zl,low(line1*2)
rcall out;send line 1 to lcd
ldi zh,high(line2*2)
ldi zl,low(line2*2)
rcall line2;first call line 2 to set lcd for second line

I have all my messages at the end of the code as .db

This all works well, but I have to rewrite the above for every message I want to send. (the line1 and line2 are actually the name of the lines i want to display so the change with each message)

What I would like to do is take the above code and turn it into a subroutine where first I load 'line1' and 'line2' with the message and then call the above to display it. I thought the .set directive would do the trick, but no good.

Any ideas?

Jim

I would rather attempt something great and fail, than attempt nothing and succeed - Fortune Cookie

 

"The critical shortage here is not stuff, but time." - Johan Ekdahl

 

"Step N is required before you can do step N+1!" - ka7ehk

 

"If you want a career with a known path - become an undertaker. Dead people don't sue!" - Kartman

"Why is there a "Highway to Hell" and only a "Stairway to Heaven"? A prediction of the expected traffic load?"  - Lee "theusch"

 

Speak sweetly. It makes your words easier to digest when at a later date you have to eat them ;-)  - Source Unknown

Please Read: Code-of-Conduct

Atmel Studio6.2/AS7, DipTrace, Quartus, MPLAB, RSLogix user

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

But .set only sets a constant. You want variables. You will need to send in the address in preset registers. But in this case it would probably increase the size of your code, not decrease it.

Regards,
Steve A.

The Board helps those that help themselves.

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

Why not use a macro?

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

Quote:

set only sets a constant

According to the assembler, .equ creates a non changable constant, .set allows you to change it on the fly. That is what I was hoping for. Using preset registers does not work either as I exchanged the ldi with a mov and it did not work either.

Quote:

Why not use a macro?

Thought of that too, I forgot to mention that I would like to reduce the code size as well. It seems wasteful to me to repeat the same lines with just the variable that changes. I know this is simple, but the answer is eluding me.

Thanks for the ideas....KEEP THEM COMING

Jim

I would rather attempt something great and fail, than attempt nothing and succeed - Fortune Cookie

 

"The critical shortage here is not stuff, but time." - Johan Ekdahl

 

"Step N is required before you can do step N+1!" - ka7ehk

 

"If you want a career with a known path - become an undertaker. Dead people don't sue!" - Kartman

"Why is there a "Highway to Hell" and only a "Stairway to Heaven"? A prediction of the expected traffic load?"  - Lee "theusch"

 

Speak sweetly. It makes your words easier to digest when at a later date you have to eat them ;-)  - Source Unknown

Please Read: Code-of-Conduct

Atmel Studio6.2/AS7, DipTrace, Quartus, MPLAB, RSLogix user

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

How much time do you have to display a message ?

If you have some time (and usually LCDs are not
that fast) two ideas come to my mind, but
both are only ok if space-saving is an absolute must.

Idea 1:
(I assume you have less than 256 messages)
Define an array which contains all the pointers
to line1 and line2. Write a subroutine that
uses a 1-byte index to access this array and then get the text adresses.

Idea 2:
(again assuming you have less than 256 messges)
In your text-definition area preceede each
message with a unique one-byte identifier and
end each message with a specific character (e.g. 0).
Then write a subroutine that, given the unique
identifier, linearly searches the text array for the
corresponding lines.

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

Are the text lines in sequence or is line 1 in 1 location and line 2 in another? I don't really see another way. Perhaps you could have different routines that display specific messages but that will move the loading of the pointer somewhere else, so no real code saving.
A macro would definetely save typing.

ps of course SOME people just use copy and paste to save typing, just edit the pointer name :)

John Samperi

Ampertronics Pty. Ltd.

https://www.ampertronics.com.au

* Electronic Design * Custom Products * Contract Assembly

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

I suspect that the subroutines that write to Line1 and line2 only differs in LCD adress (like 0x80, 0xC0). If you use a register for this adress you only need one subroutine to write LCD. You can also probably organize your characters so you don't need to write high adress byte more than one time.

ldi   zh,0x20   ;msb Char
ldi   zl,0x00   ;lsb Line1 Char
ldi   adr,0x80   ;LCD adress Line1
rcall write_lcd   ;write Line1
ldi   zl,0x10   ;lsb Line2 Char
ldi   adr,0xC0   ;LCD adress Line2
rcall write_lcd   ;write Line2
  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

You could embed an escape sequence or special character to select the lcd line and even address the cursor in your strings. This makes your write_lcd a little more complex but it should save a few bytes overall.

A macro would make the assembler code a bit easier to read:
write_lcd hello_str
write_lcd test_str
and so on....
failing that, write in 'c' and have it do it for you!!!

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0
write in 'c' and have it do it for you!!!

remember that he also want to SAVE space not go to the next size or 2 up processor :lol:

John Samperi

Ampertronics Pty. Ltd.

https://www.ampertronics.com.au

* Electronic Design * Custom Products * Contract Assembly

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

Quote:
Idea 2:
(again assuming you have less than 256 messges)
In your text-definition area preceed each
message with a unique one-byte identifier and
end each message with a specific character (e.g. 0).
Then write a subroutine that, given the unique
identifier, linearly searches the text array for the
corresponding lines.

I do something like this---but really just separate messages by "|" (ex .db "EAT HAM|BUY INTEL|REV 22A|UNCLE JOKER|SORRY BOUT THAT|" Then my tx routine just counts messages by counting the "|" separator. You could have 2 or 2000 messages limited by your counter bits. Though it takes a bit of time to scan a huge block! But far faster than I can read anyhow. You may use this idea without charge.

When in the dark remember-the future looks brighter than ever.   I look forward to being able to predict the future!

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

Some very good points!

I am using a common routine to send the lcd the data, but i have to write over and over the same stuff to load the z register with the message pointer. THis is why I thought the .set directive would solve my problems. my other problem is that after I display the message i am looking for a specific kepay press which branches to another location. problem there is that I exceede the branch limit That's another story though.

my initial part of the code allows you to scroll between functions, there are 7 of them to pick. based on key presses dictated the scroll direction, but also selects the function displayed. I want to be able to have two labels 'line1' and 'line2' which I can load with the line text i want, rather than repeating the same lines over and over, but with different messages called.

Here is a snip of what I currently have:

rcall lcdclear
ldi ZH,high(csy_1*2) ;
ldi ZL,low(csy_1*2) ;
rcall lcdout ;
ldi ZH,high(csy_2*2) ;
ldi ZL,low(csy_2*2)
rcall line2

;##########LCD MESSAGES##1##############X
;general messages
csy_1: .db " Casey Systems ",0
csy_2: .db " ATCT V1.0.0 ",0
mfunc1: .db "Use INC for DMM ",0
mfunc2: .db "Use DEC for SPC ",0
pr_sel: .db "Press SELECT ",0
go_tst: .db "Then press TST ",0
per_tst: .db "Performing..... ",0

The way it is written the z is loaded with the address of the first line of the message, and then the second.
A routine is called to send it to the lcd

this is fine but if i want to display a different message i must rewrite the same lines to load the z register. I would rather not have to do this and save code space by putting a static name in the () and assing them the message name in the main body where/when needed

Jim

I would rather attempt something great and fail, than attempt nothing and succeed - Fortune Cookie

 

"The critical shortage here is not stuff, but time." - Johan Ekdahl

 

"Step N is required before you can do step N+1!" - ka7ehk

 

"If you want a career with a known path - become an undertaker. Dead people don't sue!" - Kartman

"Why is there a "Highway to Hell" and only a "Stairway to Heaven"? A prediction of the expected traffic load?"  - Lee "theusch"

 

Speak sweetly. It makes your words easier to digest when at a later date you have to eat them ;-)  - Source Unknown

Please Read: Code-of-Conduct

Atmel Studio6.2/AS7, DipTrace, Quartus, MPLAB, RSLogix user

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

Have you examined the excellent string display routine Design Note 43 by dksmall?

Stan

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

At some point you need a pointer to the string as your strings are variable length. Whether you pass a 16 bit pointer for each string or whether you pass a 8bit index for the required string you need some way of identifying the string. As said previously, you can write a macro to fill in the pointer values to save typing and decrease potential errors.

Another thought to save code space is to compress your strings - I seem to recall you can get your chars into 6 bits.

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0
csy_1: .db " Casey Systems ",0 
csy_2: .db " ATCT V1.0.0 ",0 

This could be considered 1 string therefore loading Z with just a pointer to line 1. Then you would need something that counts the nuls (which COULD create a problem, see below) and switch printing to line 2 and skip over the end of string termination.

The problem WILL arise when the assembler fills the gap with a null (for odd number of bytes strings) and you could end up with 2 0 in sequence messing up the code.
I use the EOT (0x04) character to terminate my messages. As a suggestion you could use ETX (0x03) to terminate line 1 and switch to line 2 and EOT (0x04) to terminate the string.

Trickier still :) I use DC1 as a command to print to line 1 and DC2 to print to line 2 (my lcd routine has simple control characters decoding) so I would just insert a DC2 to terminate line 1 and printing to line 1 and switch to line 2, and would not have to do ANYTHING. :wink:

These are commands interpreted by my LCD code:

CC_LKUP:
.db	SOH,0							;^A Cursor off
        rjmp     CURS_OFF
.db	STX,0							;^B Cursor blink
        rjmp     CURS_BLK
.db	ETX,0							;^C Cursor on
        rjmp     CURS_ON
.db	BS,0							;^H Backspace
        rjmp     BACKSP
.db	LF,0							;^J Line feed
        rjmp     LIN_FEED
.db	FF,0							;^L Form feed
        rjmp     L_CLS				;Clear screen
.db	CR,0							;^M Carriage return
        rjmp     SETCUR     		;Reset cursor position
.db	DC1,0							;^Q Device control 1
        rjmp     PR_LIN1
.db	DC2,0							;^R Device control 2
        rjmp     PR_LIN2
END_CCLP:

John Samperi

Ampertronics Pty. Ltd.

https://www.ampertronics.com.au

* Electronic Design * Custom Products * Contract Assembly

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

the messages are not different in size. something changed how my reply looked. I actually use 16bytes for each line. I use spaces to fill in the empties.

I have a couple lines of code that look for the '0' as end-of message

Will look at all the info in the morning

Thanks

Jim

I would rather attempt something great and fail, than attempt nothing and succeed - Fortune Cookie

 

"The critical shortage here is not stuff, but time." - Johan Ekdahl

 

"Step N is required before you can do step N+1!" - ka7ehk

 

"If you want a career with a known path - become an undertaker. Dead people don't sue!" - Kartman

"Why is there a "Highway to Hell" and only a "Stairway to Heaven"? A prediction of the expected traffic load?"  - Lee "theusch"

 

Speak sweetly. It makes your words easier to digest when at a later date you have to eat them ;-)  - Source Unknown

Please Read: Code-of-Conduct

Atmel Studio6.2/AS7, DipTrace, Quartus, MPLAB, RSLogix user

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

Quote:
string display routine Design Note 43 by dksmall?

part of the routine.

ldi zl,low(Message1) ;point the Z register to a null
ldi zh,hi(Message1) ;terminated string in memory

This would NOT normally work for flash based messages as the pointer needs to be multiplied by 2 for LPM, however DKSMALL has done a tricky thing and multiplied the pointer by 2 within the printing routine therefore saving the *2 in every pointer loading, very clever. :)

....just in case someone picks that up.. so you could have a universal pointer setup for flash, eeprom or RAM and the respective printing code would multiply the pointer by 2 (or not).

John Samperi

Ampertronics Pty. Ltd.

https://www.ampertronics.com.au

* Electronic Design * Custom Products * Contract Assembly

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

Quote:
I actually use 16bytes for each line.
EASIER STILL!! just count 16 characters and switch to line 2.

...sometimes later... :oops: this is not so good as you have a terminating null and the assembler will add another to make word alignment, so you either leave out the terminating null and count 16 chars as above or skip over the 2 nuls when you start printing on line 2.

John Samperi

Ampertronics Pty. Ltd.

https://www.ampertronics.com.au

* Electronic Design * Custom Products * Contract Assembly

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

What I do is the following to sense the "",0:

lmp
tst r0
brne output
ret
output:
;start sending display data here

I have used this lcd scheme many times before. why i am having so much trouble now sucks. all I am looking to do is reduce the amount of code that is essentially doing the same thing, just with different messages.

Incidentally I did get part of it to work with the .set last night, but I could not duplicate it. that's when I said good night to the damn thing and went to bed.

THis should be simple, maybe that is why it is so hard :wink:

Jim

I would rather attempt something great and fail, than attempt nothing and succeed - Fortune Cookie

 

"The critical shortage here is not stuff, but time." - Johan Ekdahl

 

"Step N is required before you can do step N+1!" - ka7ehk

 

"If you want a career with a known path - become an undertaker. Dead people don't sue!" - Kartman

"Why is there a "Highway to Hell" and only a "Stairway to Heaven"? A prediction of the expected traffic load?"  - Lee "theusch"

 

Speak sweetly. It makes your words easier to digest when at a later date you have to eat them ;-)  - Source Unknown

Please Read: Code-of-Conduct

Atmel Studio6.2/AS7, DipTrace, Quartus, MPLAB, RSLogix user

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

My interpretation of your problem is that you would like to write some concise code:

You can call a subroutine with a message number, so each call involves a "load reg,number; call outline1;"
or you write a macro that you invoke with "OUTLINE1 msg_address"

The subroutine counts for the n'th message but you will have to keep track of which .db string is at which index. Or you create a table of addresses.

Another way to write the macro would be:
PRINTMSG "message text"

The macro stores the text directly preferably in a different section and invokes the output routine with the address of the text.

If you are feeling clever then you can make the macro create a message address to the string with:

PRINTFUNCADS .MACRO function,address
    ldi  ZH,high(address*2)
    ldi  ZL,low(address*2)
    rcall function
    .ENDM

PRINTMSGADS .MACRO string,address
    .SECTION TXTSEG
address: .db string
    .SECTION CODSEG
    PRINTFUNCADS lcdout,address
    .ENDM
;
; and then invoke with:
 PRINTMSGADS "hello world", hello_msg
; or later with:
 PRINTFUNCADS    lcdout_line2, hello_msg

It all comes down to your personal style. You could use the n'th message style if you make the macro place the addresses into an index table and you .set a unique value for hello_num that indexes the hello_ads.

David.

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

Quote:
PRINTMSG "message text"

David don't disclose too many asm secrets in public, the "C people" may read them.
The "asm secret society" to which we made a sworn oath of allegiance will not be happy.
:lol: :lol:

John Samperi

Ampertronics Pty. Ltd.

https://www.ampertronics.com.au

* Electronic Design * Custom Products * Contract Assembly

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

Speed don't seem to be a problem, so make all the text a 0 in between.(normal c string's).
The write routine can then start at string 0 and count the needed number of strings (counting 0's) . and print the correct one.(yes slow but so is a LCD). And the code is small.
If you need to save more space think about how many letters you use! and only store 5 or 6 bit for each letter. But if it's less than 200 letters you will not save anything because the code get's bigger.

Jens

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

JS
I spoke with four F.A.E.'s from Atmel today All four wanted to know why I do not use 'c', three would not help me, and the one that is helping me cannot understand why what I want to do does not work!!

WAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA!!!!!!!! :roll:

Jim

I would rather attempt something great and fail, than attempt nothing and succeed - Fortune Cookie

 

"The critical shortage here is not stuff, but time." - Johan Ekdahl

 

"Step N is required before you can do step N+1!" - ka7ehk

 

"If you want a career with a known path - become an undertaker. Dead people don't sue!" - Kartman

"Why is there a "Highway to Hell" and only a "Stairway to Heaven"? A prediction of the expected traffic load?"  - Lee "theusch"

 

Speak sweetly. It makes your words easier to digest when at a later date you have to eat them ;-)  - Source Unknown

Please Read: Code-of-Conduct

Atmel Studio6.2/AS7, DipTrace, Quartus, MPLAB, RSLogix user

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

Quote:
I spoke with four F.A.E.'s from Atmel today All four wanted to know why I do not use 'c', three would not help me, and the one that is helping me cannot understand why what I want to do does not work!!

My guess is they're not familiar with assembler...

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

The one who is helping IS familliar, he just need some more info from me first.

I cannot complain, normally they want nothing to do with you unless you are buying a $1000000 a year

Jim

I would rather attempt something great and fail, than attempt nothing and succeed - Fortune Cookie

 

"The critical shortage here is not stuff, but time." - Johan Ekdahl

 

"Step N is required before you can do step N+1!" - ka7ehk

 

"If you want a career with a known path - become an undertaker. Dead people don't sue!" - Kartman

"Why is there a "Highway to Hell" and only a "Stairway to Heaven"? A prediction of the expected traffic load?"  - Lee "theusch"

 

Speak sweetly. It makes your words easier to digest when at a later date you have to eat them ;-)  - Source Unknown

Please Read: Code-of-Conduct

Atmel Studio6.2/AS7, DipTrace, Quartus, MPLAB, RSLogix user

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

C has been around since the '70s.... lets see... use a 30 year old tool or a new tool.... slide rule or scientific calculator... Friden mechanical calculator with gears or a scientific calculator... IBM 7094 mainframe with germanium pnp transistors in the flip flops, one flip flop on a pc board the size of a paperback book, several racks full of these cards in a room with a raised floor and tons of airconditioning, or even an apple ii or a trs80 vs a desktop pc. Good tool analogy? Bridgeport milling machine with cranks or a CNC machine? jqm doesnt care beans about code space till he runs out of it. He wants less typing... he'll get that from either c or macros. Here's another outside the box idea... hire someone that can really type like a batouttahell and dictate to em...

Imagecraft compiler user

Last Edited: Tue. Aug 7, 2007 - 01:20 AM
  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

Quote:
cannot understand why what I want to do does not work!!
Quote:
I thought the .set directive would do the trick, but no good.
Quote:
.set allows you to change it on the fly.

Is this the FAE does not understand why it doesn't work? Let's try to go back to basic. Are you trying to load the pointer (Z) by changing the value of the .set directive?

Otherwise there have been some good suggestions on various ways of reducing code space and typing time above.

By the way, WHY do we need to ask FAEs anything? :lol:
I have had so called FAEs to which I had to explain how their product works!! Quite a lot of them are unemployable in the real world...well except Atmel FAEs of course :lol:

John Samperi

Ampertronics Pty. Ltd.

https://www.ampertronics.com.au

* Electronic Design * Custom Products * Contract Assembly

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

Quote:

All four wanted to know why I do not use 'c',

Hear that, js? Right from the horse's mouth.

Duh--this isn't Programming 101, but it >>is<< Programming 202. I don't call the Atmel FAE every time I have a sticky programming problem. Figure out what you need to do with some diagrams on paper or such. If you can't figure out how to do a pointer in ASM, then use a language with built-in pointers, like C.

Geez, I have tricky programming problems every day. What do macros and typing time have to do with it?

Lee

You can put lipstick on a pig, but it is still a pig.

I've never met a pig I didn't like, as long as you have some salt and pepper.

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

js wrote:
...The "asm secret society" to which we made a sworn oath of allegiance will not be happy.
:lol: :lol:
Ah ha!!!
Busted,
John

Resistance is futile…… You will be compiled!

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

Oh christ, now I've done it. Pissed the entire world off.

I only called the local FAE because I know him, and I also though there might be a problem with the AVRStudio and wanted to get some info. By the way that is one of the reasons they get paid.

Bob G. I do care about space as well. I am looking to simplify things for myself, and streamline the code at the same time. I was not aware that 'c' has been around since the 70's. Thanks for the history lesson!!

JS:
Yes load the z pointer with .set. I thought that was what my original post mentioned. My bad, ans yes there have been some great ideas posted too.

To all
Sorry I pissed off the secret society by asking the creator of the product I am using for a little assistance, rather than stare at a screen going bonkers

Jeeeeeeeeezzz Tough crowd :evil:

Jim 8)

I would rather attempt something great and fail, than attempt nothing and succeed - Fortune Cookie

 

"The critical shortage here is not stuff, but time." - Johan Ekdahl

 

"Step N is required before you can do step N+1!" - ka7ehk

 

"If you want a career with a known path - become an undertaker. Dead people don't sue!" - Kartman

"Why is there a "Highway to Hell" and only a "Stairway to Heaven"? A prediction of the expected traffic load?"  - Lee "theusch"

 

Speak sweetly. It makes your words easier to digest when at a later date you have to eat them ;-)  - Source Unknown

Please Read: Code-of-Conduct

Atmel Studio6.2/AS7, DipTrace, Quartus, MPLAB, RSLogix user

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

Quote:

Pissed the entire world off.

Mostly the Surly Curmudgeon. (tm)

Quote:

and I also though there might be a problem with the AVRStudio

Quote:

but i have to write over and over the same stuff to load the z register with the message pointer. THis is why I thought the .set directive would solve my problems.

Quote:

By the way that is one of the reasons they get paid.

??? From the documentation on the .SET directive,

Quote:
SET - Set a symbol equal to an expression
The SET directive assigns a value to a label. This label can then be used in later expressions. A label assigned to a value by the SET directive can be changed later in the program.

Syntax:
.SET label = expression

Example:
.SET io_offset = 0x23
.SET porta = io_offset + 2

.CSEG ; Start code segment
clr r2 ; Clear register 2
out porta,r2 ; Write to Port A


Quote:

problem there is that I exceede the branch limit

From the AVRStudio documentation on BRxxx:
Quote:
This instruction branches relatively to PC in either direction (PC - 63 ≤ destination ≤ PC + 64).

But
Quote:

By the way that is one of the reasons they get paid.

You can put lipstick on a pig, but it is still a pig.

I've never met a pig I didn't like, as long as you have some salt and pepper.

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

jgmdesign wrote:
Oh christ, now I've done it. Pissed the entire world off.
...
Jeeeeeeeeezzz Tough crowd :evil:

Jim 8)

The real problem; we think we're funny!

Resistance is futile…… You will be compiled!

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

Quote:
Yes load the z pointer with .set.
Don't know if that would work. If the assembler assigns values to labels ect. in the first pass, then the last instance of .set would be remembered and assigned to the label.

I'm not really sure how this would work at runtime.

Can you please show us how you are laying out the code using the set directive in relation with loading the Z pointer?

Quote:
Right from the horse's mouth.
OK show me an example of a horse using C and I will believe that :)

John Samperi

Ampertronics Pty. Ltd.

https://www.ampertronics.com.au

* Electronic Design * Custom Products * Contract Assembly

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

Quote:

OK show me an example of a horse using C and I will believe that

If Mr. Ed were still alive, he'd be using C and not ASM. Right, Wilbur? [Well, maybe it wasn't from the horse's >>mouth<< ...]

Lee

You can put lipstick on a pig, but it is still a pig.

I've never met a pig I didn't like, as long as you have some salt and pepper.

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

Quote:
I'm not really sure how this would work at runtime.

The point is, it is not a runtime directive. As I said previously, .set sets the value of a constant. Yes, what the value of that label is can change within the file, but at the time of its use it is a fixed value based on where it is used within the file. For instance:

.set foo = 0x10
...
	ldi r16, foo ;loads the value 0x10 into r16
	rcall func
...
.set foo = 0x20
...
func:
	ldi r17, foo ;loads the value 0x20 into r17
	ret

With the first use of foo, its value is 0x10 because the statement using it is after the first definition of foo but before the second. With the second use of foo, its value is 0x20 since it is after the second definition of foo. That func is called between the first and second definitions is inconsequential. It is where the line of code that uses foo is within the file that matters, not where it is in relation to program flow.

Aside from that, the second parameter of ldi is a constant anyways. There is no way to change that value at runtime no matter what tricks you try to do.

There are certainly ways that you might make the code more readable or more versatile as other have mentioned, but none of them would make the code any shorter since

ldi zh,high(line1*2) 
ldi zl,low(line1*2)

is the shortest code possible to load a value into the Z registers (two words/two clocks).

Regards,
Steve A.

The Board helps those that help themselves.

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

Quote:
Right, Wilbur?

Shouldn't that be:
Right, Willllllber?

Regards,
Steve A.

The Board helps those that help themselves.

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

According to Wikipedia, it is Wilbur. But you were right with the lllllllllll. ;)
http://en.wikipedia.org/wiki/Mr._Ed

Lee

You can put lipstick on a pig, but it is still a pig.

I've never met a pig I didn't like, as long as you have some salt and pepper.

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

Quote:
According to Wikipedia, it is Wilbur.

The horse can talk. No one said it could spell (or me either, for that matter) :D

Regards,
Steve A.

The Board helps those that help themselves.

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

Quote:
Jeeeeeeeeezzz Tough crowd

I am sorry that you are having difficulties with assembler. There are as many tricks that can be used with assembler macros as can be used with 'C'. And if you pre-process with cpp first before you even start with assembler macros you can work wonders.

I presume that your main aim is to write code that is clear to read, reasonably concise and possibly efficient in code space. The code space generally only becomes an issue when you do not want to move to the next bigger AVR.

Why don't you post a chunk of your present code? By the current response I predict that you will get several practical alternatives in programming style.

Select the styles that suit you, and incorporate them into your own style.

I no longer use assembler but always wished that someone would write a book promoting assembler style. Instead you just have to trawl through other people's code to get ideas. I can guarantee that no two programmers will agree on everything.

David.

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

DAvid,

Quote:

I can guarantee that no two programmers will agree on everything.

If you sift through all the responses, you will see the vast styles you mentioned!

At this point I am about to scratch most of the code off and start over. Before I do that I am going to post it for everyones amusement/perusement.

From what I read before from JS and others, the .set might work, it might not. I have tried it in simpler programs and it seems to work. The code i am going to trash has gotten so surly that at this point it seems better to start over.

Maybe I can get back into some of these guys good graces if I do as well :wink: I doubt it though

Jim

I would rather attempt something great and fail, than attempt nothing and succeed - Fortune Cookie

 

"The critical shortage here is not stuff, but time." - Johan Ekdahl

 

"Step N is required before you can do step N+1!" - ka7ehk

 

"If you want a career with a known path - become an undertaker. Dead people don't sue!" - Kartman

"Why is there a "Highway to Hell" and only a "Stairway to Heaven"? A prediction of the expected traffic load?"  - Lee "theusch"

 

Speak sweetly. It makes your words easier to digest when at a later date you have to eat them ;-)  - Source Unknown

Please Read: Code-of-Conduct

Atmel Studio6.2/AS7, DipTrace, Quartus, MPLAB, RSLogix user

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

If all your strings are 16 bytes long, then you can write your own display function which doesn't need terminators, it can just ouput 16 characters.
Each string can be assigned an 8 bit number, and the display routine can multiply by 16 to find the right string.
If you start your table of strings on an even byte boundary, and pad them with spaces, the assembler should not need to do any alignment.
You can assign names to the 8 bit identifiers with EQU.
I'm afraid that it's really very trivial, and I'm not suprised that some of the people at Atmel declined to help.

Four legs good, two legs bad, three legs stable.

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

OK, I have the definitive answer for y'all. And also kills once and for all the right-wing rhetoric ....errr, ASM advocacy ... by js & Jim.

Quote:

I am looking to reduce the amount of repetitive typing. My application displays a lot of messages ...

Ok, now we know the app. Various people have tried to put lipstick on the pig with various macros (no, Jim, .SET won't work). And advice such as

Quote:

All four wanted to know why I do not use 'c',

Was dismissed out-of-hand. But remember your stated objective:

Quote:

I am looking to reduce the amount of repetitive typing.

Let's use an example. You need to print out the lyrics of The Twelve Days of Christmas on your LCD display. Lots of repetition there, eh? How can we reduce that? The wise Wizards at Atmel suggested C 'cause you can't do this with nearly the same number of typed characters in ASM:

#include 
main(t,_,a)char *a;{return!0

QED [quod erat demonstrandum (which was to be demonstrated)]

Lee

You can put lipstick on a pig, but it is still a pig.

I've never met a pig I didn't like, as long as you have some salt and pepper.

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

Oh Leeeeeeeeeeeeeeeeeeeeeee; now you've done it!!!!!
John

PS: Look over your shoulder, often,
my friend!
John

Resistance is futile…… You will be compiled!

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

Lee,

Quote:

Code:

#include
main(t,_,a)char *a;{return!0 main(-86,0,a+1)+a)):1,t<_?main(t+1,_,a):3,main(-94,-27+t,a)&&t==2?_<13?
main(2,_+1,"%s %d %d\n"):9:16:t<0?t<-72?main(_,t,
"@n'+,#'/*{}w+/w#cdnr/+,{}r/*de}+,/*{*+,/w{%+,/w#q#n+,/#{l,+,/n{n+,/+#n+,/#\
;#q#n+,/+k#;*+,/'r :'d*'3,}{w+K w'K:'+}e#';dq#'l \
q#'+d'K#!/+k#;q#'r}eKK#}w'r}eKK{nl]'/#;#q#n'){)#}w'){){nl]'/+#n';d}rw' i;# \
){nl]!/n{n#'; r{#w'r nc{nl]'/#{l,+'K {rw' iK{;[{nl]'/w#q#n'wk nw' \
iwk{KK{nl]!/w{%'l##w#' i; :{nl]'/*{q#'ld;r'}{nlwb!/*de}'c \
;;{nl'-{}rw]'/+,}##'*}#nc,',#nw]'/+kd'+e}+;#'rdq#w! nr'/ ') }+}{rl#'{n' ')# \
}'+}##(!!/")
:t<-50?_==*a?putchar(31[a]):main(-65,_,a+1):main((*a=='/')+t,_,a+1)
:0 "!ek;dc i@bK'(q)-[w]*%n+r3#l,{}:\nuwloca-O;m .vpbks,fxntdCeghiry"),a+1);}

Now I understand!! :roll:

I am most likely going to rewrite the code. I'll try to do it tonight. At this point the rewrite seems easier than annoying the entire free world. I was just looking for someone with a possible quick fix. As usual, my mistake

Jim

I would rather attempt something great and fail, than attempt nothing and succeed - Fortune Cookie

 

"The critical shortage here is not stuff, but time." - Johan Ekdahl

 

"Step N is required before you can do step N+1!" - ka7ehk

 

"If you want a career with a known path - become an undertaker. Dead people don't sue!" - Kartman

"Why is there a "Highway to Hell" and only a "Stairway to Heaven"? A prediction of the expected traffic load?"  - Lee "theusch"

 

Speak sweetly. It makes your words easier to digest when at a later date you have to eat them ;-)  - Source Unknown

Please Read: Code-of-Conduct

Atmel Studio6.2/AS7, DipTrace, Quartus, MPLAB, RSLogix user

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

Just in case we are all barking up the wrong tree ........ arf arf arf (this will scare off "bad old puttycats" with sunglasses) :)
How are you switching from printing from line 1 to line 2 on the lcd? You seem to have a rcall line2, does this change the cursor to the line 2 address?

When you post some of your code I may understand WHAT does not work, still unsure, isn't Z being loaded correctly or nothing gets printed? Or line 2 is not being printed.

By the way do you have a Dragon or JTAG ICE? What chip are you using? (it may be lost somewhere in the 3 pages)

By the way Lee, thanks for sharing an example of your C code :lol:

John Samperi

Ampertronics Pty. Ltd.

https://www.ampertronics.com.au

* Electronic Design * Custom Products * Contract Assembly

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

js:
Yes, I am configuring the lcd for the second line. I am using a dragon for debugging as well.

Here is a section of my lcd code. Nothing fancy:

;***************************************************
line1:
ldi zl,low(lcd1*2)
ldi zh,high(lcd1*2)
rcall lcdout
ret
;***************************************************
linex:
ldi zh,high(lcd2*2)
ldi zl,low(lcd2*2)
;***************************************************
line2: cbi control,1
ldi temp,0xc0
out port,temp
rcall strobe
sbi control,1
rcall lcdout
ret
;***************************************************

;LCD OUT - SENDS MESSAGE DATA TO LCD
lcdout:
lpm ;load the register with charachter
tst r0 ;and check if it is the end
brne output ;if done return
ret ;equal go back
output: ldi temp,0xff
out ddra,temp
out port,r0 ;move first charachter to port b
rcall strobe ;pulse the enable line
inc ZL
rjmp lcdout ;go get the next charachter
;***************************************************

;STROBE - PULSES THE 'E' LINE ON THE LCD
strobe: sbi control,0
rcall delay
cbi control,0
ret
;***************************************************

;DELAY - ROUTINE FOR STRETCHING PULSE WIDTHS ON LCD
;PRIMARILY FOR FASTER PROGRAMS
delay: ldi dly1,0x10
ldi dly2,0xff
dly: dec dly2
brne dly
dec dly1
brne dly
ret

It really is irrelevant at this point.

From what I learned from Atmel, the .set directive uses static numbers not variables. Meaning I cannot do this:

.set lcd1 =msg1

The reason is that the location of msg1 can/will change as the code size changes.

Now, if the location of msg1 was always at say 0x2AB, and the location of msg5 was at 0x1ff then I could use:
.set lcd1 =0x2ab
then call my output subroutine

.set lcd1 =0x1ff
then call my output subroutine

As I said in the beginning, the .set directive looked to good to be true.

Thanks to all who contributed.

Jim

and use

I would rather attempt something great and fail, than attempt nothing and succeed - Fortune Cookie

 

"The critical shortage here is not stuff, but time." - Johan Ekdahl

 

"Step N is required before you can do step N+1!" - ka7ehk

 

"If you want a career with a known path - become an undertaker. Dead people don't sue!" - Kartman

"Why is there a "Highway to Hell" and only a "Stairway to Heaven"? A prediction of the expected traffic load?"  - Lee "theusch"

 

Speak sweetly. It makes your words easier to digest when at a later date you have to eat them ;-)  - Source Unknown

Please Read: Code-of-Conduct

Atmel Studio6.2/AS7, DipTrace, Quartus, MPLAB, RSLogix user

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

Since you want to avoid unnecessary typing :lol:

rcall lcdout
ret 

This sequence of instructions can be

rjmp lcdout

Also

lpm ;load the register with charachter 

can be

lpm   r0,z+ ;load any register and postincrement Z

then you don't need

inc ZL 

No big sensation, but it will save speed, codespace and typing... :wink:

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

Lennart,
Good ideas. THe rcall lcdout is needed as it is used frequently.

I would rather attempt something great and fail, than attempt nothing and succeed - Fortune Cookie

 

"The critical shortage here is not stuff, but time." - Johan Ekdahl

 

"Step N is required before you can do step N+1!" - ka7ehk

 

"If you want a career with a known path - become an undertaker. Dead people don't sue!" - Kartman

"Why is there a "Highway to Hell" and only a "Stairway to Heaven"? A prediction of the expected traffic load?"  - Lee "theusch"

 

Speak sweetly. It makes your words easier to digest when at a later date you have to eat them ;-)  - Source Unknown

Please Read: Code-of-Conduct

Atmel Studio6.2/AS7, DipTrace, Quartus, MPLAB, RSLogix user

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

Not sure you understood my point. Since this code sequence

rcall   lcdout
ret

end with RET it implies that you already made a previous RCALL and have return adress for this in your stack. So why do an extra RCALL to a routine that end with RET and then another RET?
This strategy will of course only work if you started your nested subroutines with RCALL.

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

You would like to use:

msg1: .set lcd1 = msg1ads
      rcall line1
msg2: .set lcd1 = msg2ads
      rcall line1

Each invocation is just the rcall instruction.

If you use a macro: then you have the extra two instructions for: ldi ZH and ldi ZL

If you use an index then you have one ldi reg,index instruction. A macro has generated an index label but it does not need to use code space.

For a block of functions and indexed messages:

msg1: ldi reg,1
      rjmp msg
msg2: ldi reg,2
msg:  rcall line1

Each call is only the rcall msg1 but you have the overhead of the ldi and rjmp. If you use addresses instead of an index then you have two ldi and an rjmp.

For program readability, a macro that sets ZH,ZL,func all in one line with a literal string would win every time:

       OUTMSG "message text",line1 

As mentioned earlier, the actual text can be compressed or encoded to save space. You can reduce a rcall, ret sequence to a rjmp. But in general common code elimination will be most dramatic.

The other benefit of removal of duplication is that the resulting function just needs debugging once.

David.