ADIW error in atmega88

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

I want to use atmega88 fo replace atmge8, so I want to convert assembler code for it. But i get error on sintax

 

adiw XH:XL,Charbuf/2

 

error: Operand 2 out of range: 0x80

 

it's not error on atmega 8 with Avr Studio 4 compiler

avr lovers

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

Charbuf is in RAM I guess, RAM starts at 0x60 in the M8 but at 0x100 in the M88.

 

ADIW can only "Adds an immediate value (0 - 63)" ie it worked by accident before.

John Samperi

Ampertronics Pty. Ltd.

www.ampertronics.com.au

* Electronic Design * Custom Products * Contract Assembly

Last Edited: Fri. Sep 15, 2017 - 12:42 AM
  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

can i replace with

 

        ldi XH,Charbuf/2
        ldi XL,Charbuf/2

 

 

 

avr lovers

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

Will need to use ldi XH,high (Charbuf/2) and  ldi XL, low (Charbuf/2) but this is NOT adding the value to X.

John Samperi

Ampertronics Pty. Ltd.

www.ampertronics.com.au

* Electronic Design * Custom Products * Contract Assembly

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

it can store to X ?

 

        ldi XH,Charbuf/2
        ldi XL,Charbuf/2
        ldi     r16,fillchr
        st      X+,r16 

 

avr lovers

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

.equ    fillchr = 0x55

 

....

        ldi XH,Charbuf/2
        ldi XL,Charbuf/2
        ldi     r16,fillchr
        st      X+,r16 

 

like this?

avr lovers

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

        ldi XH,low(Charbuf/2)
        ldi XL,high(Charbuf/2)
        ldi     r16,fillchr
fill_lp:
        st      X+,r16            ; Store a fill pattern, advance X pointer
        cpi     XL,low(Charbuf/2)  ; Repeat until XL = low(Charbuf/2)
        brne    fill_lp           ;

        cpi     XH,high(Charbuf/2) ; Repeat until XH = high(Charbuf/2)
        brne    fill_lp           ; (executed only on every 256th loop cycle)

 

 

It's true?

avr lovers

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

Could you explain in words what the code is expected to do?

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

original code in atmega8

.DEF mpa      = R16  ;     A

.DEF mpb      = R17  ;     B
.DEF mpc      = R18  ;     C

 

        add mpc,mpa           
        adc mpb,zero
        mov XH,mpb
        mov XL,mpc

 

        adiw XH:XL,Charbuf/2

 

and convert to

 

        add mpc,mpa           
        adc mpb,zero
        mov XH,mpb
        mov XL,mpc

 
        ldi  mpb,high(Charbuf/2)
        ldi  mpc,low(Charbuf/2)
         
        add XL,mpc
        adc XH,mpb

 

and

        sbiw XH:XL,Charbuf/2 ;  also ohne Mem-Offset

 

convert to

 

 

        ldi  mpb,high(Charbuf/2)
        ldi  mpc,low(Charbuf/2)         
        sub XL,mpc
        sbc XH,mpb

 

it's true?

 

 

 

avr lovers

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

listing code as attachments

Attachment(s): 

avr lovers

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

You didn't answer the question Visovian wrote:
Could you explain in words what the code is expected to do?

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0
charYPb: sbiw XH: XL, cpl, and again the simple division
        brcc charYPb; because it works so well
        subi XL, 0-cpl
        clr XH
        ldi mpb, cpl; number of characters per line
        mul mpa, mpb; times new Zeilennr.
        add XL, r0; plus column no.
        adc XH, r1
        adiw XH: XL, Charbuf / 2, and still the MEM offset
        adiw XH: XL, Charbuf / 2
        rjmp charwc; set new cursorpos.
        brcc charYPb; because it works so well
        subi XL, 0-cpl
        clr XH
        ldi mpb, cpl; number of characters per line
        mul mpa, mpb; times new Zeilennr.
        add XL, r0; plus column no.
        adc XH, r1
        adiw XH: XL, Charbuf / 2, and still the MEM offset
        adiw XH: XL, Charbuf / 2
        rjmp charwc; set new cursorpos.

avr lovers

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

It might be useful for OP to look at how C compilers deal with arrays/pointers with an offset.

 

The first example may not be directly applicable.  It is an array of character pointers to flash (screen prompts) and then the "right one" needs to be pointed to.  ("scratch" is a register variable that lives in R17)

flash	char	fres_dontcare[]		=	"      ";
flash	char	fres_flow[]			=	"FLOW  ";
flash	char	fres_prb10[]		=	"PRB10 ";
flash	char	fres_prb30[]		=	"PRB30 ";
flash	char	fres_probe[]		=	"PROBE ";
flash	char	fres_adc[]			=	"ADC   ";
flash	char	fres_dac[]			=	"DAC   ";
flash	char	fres_digital[]		=	"DIGITL";

flash	char *	fres[] =
{
fres_dontcare,
fres_flow,
fres_prb10,
fres_prb30,
fres_probe,
fres_adc,
fres_dac,
fres_digital,
NULL
};
... then the access is as a parameter for sprintf()
					sprintf (line1, "%2u) %5.5p Md/Ch:%2u/%1u",
									item+1,
									fres[scratch],
									retval + 1,	// make 1-relative
									looper);

...and the address build code

0091dc 2fe1      	MOV  R30,R17
0091dd e8a7      	LDI  R26,LOW(_fres)
0091de e1be      	LDI  R27,HIGH(_fres)
0091df e0f0      	LDI  R31,0
0091e0 0fee      	LSL  R30
0091e1 1fff      	ROL  R31
0091e2 0fae      	ADD  R26,R30
0091e3 1fbf      	ADC  R27,R31

I'll see if I have an SRAM array in this app.

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.

Last Edited: Fri. Sep 15, 2017 - 03:38 PM
  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

This one is an array of structures (98 bytes each) in SRAM.  "looper" is a register variable living in R19.  The code sets a pointer "tptr".

                 ;0000 14FE 				tptr = &data_thread[looper];
001c3c e6a2      	LDI  R26,LOW(98)
001c3d 9f3a      	MUL  R19,R26
001c3e 01f0      	MOVW R30,R0
001c3f 5be1      	SUBI R30,LOW(-_data_thread)
001c40 4ff3      	SBCI R31,HIGH(-_data_thread)
001c41 93e0 1d4d 	STS  _tptr,R30
001c43 93f0 1d4e 	STS  _tptr+1,R31

That is probably pretty close to what OP needs.  Build the offset in the pointer register pair.  Then use SUBI/SBCI to add the base address.  Unlike ADIW with the limited parameter range, SUBI and SBCI parameters are each the full 8 bits, 255 max, giving the instruction pair a full 64K range.

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.

Last Edited: Fri. Sep 15, 2017 - 03:46 PM