Multiplication bug

General discussion on mikroPascal PRO for AVR.
Post Reply
Author
Message
greg.b
Posts: 11
Joined: 21 Sep 2017 21:37

Multiplication bug

#1 Post by greg.b » 08 Dec 2018 21:34

Hi
I have a question.
Why in interrupt handling you do not put r0 and r1 registers on the stack, especially when multiplication occurs in the main program and in the interrupt. The multiplication result is placed in R1 (high byte) and R0 (low byte).
I had a lot of problems before I found this error.
Please check it and fix.

Best regards
G.B.

User avatar
filip
mikroElektronika team
Posts: 11874
Joined: 25 Jan 2008 09:56

Re: Multiplication bug

#2 Post by filip » 13 Dec 2018 10:07

Hi,

Could you please attach the minimal project that demonstrates this issue ?

Regards,
Filip.

greg.b
Posts: 11
Joined: 21 Sep 2017 21:37

Re: Multiplication bug

#3 Post by greg.b » 13 Dec 2018 12:14

Hi
For example, my last project led rgb 32x16 panel + ATMega64.
When I push r0 and r1 registers on stack in interrupt handling everything is ok.

Code: Select all

program panel32x16rgb;

{ Declarations section }

var
R1_pin: sbit at portc5_bit;
G1_pin: sbit at portc6_bit;
B1_pin: sbit at portc7_bit;
R2_pin: sbit at portg2_bit;
G2_pin: sbit at porta7_bit;
B2_pin: sbit at porta6_bit;
A_pin : sbit at porta5_bit;
B_pin : sbit at porta4_bit;
C_pin : sbit at porta3_bit;
D_pin : sbit at portc4_bit;
CLK_pin: sbit at porta2_bit;
LAT_pin: sbit at porta1_bit;
OE_pin : sbit at porta0_bit;

R1_pin_direction: sbit at ddc5_bit;
G1_pin_direction: sbit at ddc6_bit;
B1_pin_direction: sbit at ddc7_bit;
R2_pin_direction: sbit at ddg2_bit;
G2_pin_direction: sbit at dda7_bit;
B2_pin_direction: sbit at dda6_bit;
A_pin_direction : sbit at dda5_bit;
B_pin_direction : sbit at dda4_bit;
C_pin_direction : sbit at dda3_bit;
D_pin_direction : sbit at ddc4_bit;
CLK_pin_direction: sbit at dda2_bit;
LAT_pin_direction: sbit at dda1_bit;
OE_pin_direction : sbit at dda0_bit;




scan: byte;
screen: array [0..191] of byte;



Procedure Reset();
begin
R1_pin_direction:=1;
G1_pin_direction:=1;
B1_pin_direction:=1;
R2_pin_direction:=1;
G2_pin_direction:=1;
B2_pin_direction:=1;
A_pin_direction :=1;
B_pin_direction :=1;
C_pin_direction :=1;
D_pin_direction :=1;
CLK_pin_direction:=1;
LAT_pin_direction:=1;
OE_pin_direction :=1;
R1_pin:=0;
G1_pin:=0;
B1_pin:=0;
R2_pin:=0;
G2_pin:=0;
B2_pin:=0;
A_pin :=0;
B_pin :=0;
C_pin :=0;
D_pin :=0;
CLK_pin:=0;
LAT_pin:=0;
OE_pin :=1;

   tccr0:= %00000101; //clk/8//32/64/128/256/1024
   tcnt0:=0;
   toie0_bit:=1;

   sreg_i_bit:=1;


end;


procedure T0_Int(); iv IVT_ADDR_TIMER0_OVF; ics ICS_AUTO;
var _n,_i,tmp_scan,tmp_n: byte;

begin
asm
 push r0;
 push r1;
end;


 if scan<1 then    /// 1/2
 begin
  inc (scan);
  tmp_scan:=3;
 end
   else
 begin
  scan:=0;
  tmp_scan:=0;
 end;


   for _n:=0 to 7 do   //3
   begin
     tmp_n:=(_n*12)+tmp_scan;
        for _i:=0 to 7 do
        begin

         B1_pin:= (screen[tmp_n +0] shr _i) and 1;
         G1_pin:= (screen[tmp_n +1] shr _i) and 1;
         R1_pin:= (screen[tmp_n +2] shr _i) and 1;
         B2_pin:= (screen[tmp_n +96] shr _i) and 1;
         G2_pin:= (screen[tmp_n +97] shr _i) and 1;
         R2_pin:= (screen[tmp_n +98] shr _i) and 1;

         CLK_pin:=1;
         CLK_pin:=0;
        end;
         for _i:=7 downto 0 do
        begin 
         B1_pin:= (screen[tmp_n +6] shr _i) and 1;
         G1_pin:= (screen[tmp_n +7] shr _i) and 1;
         R1_pin:= (screen[tmp_n +8] shr _i) and 1;
         B2_pin:= (screen[tmp_n +102] shr _i) and 1;
         G2_pin:= (screen[tmp_n+103] shr _i) and 1;
         R2_pin:= (screen[tmp_n+104] shr _i) and 1;

         CLK_pin:=1;
         CLK_pin:=0;
        end;
   end;
   
   
       OE_pin:=1;
       A_pin:=1;
       B_pin:=1;
       C_pin:=1;
       D_pin:=1;
       
       case scan of
        0:A_pin:=0;
        1:B_pin:=0;
        2:C_pin:=0;
        3:D_pin:=0;
       end;
       LAT_pin:=1;
       LAT_pin:=0;
       OE_pin:=0;
 asm
 pop r1;
 pop r0;
 end;

end;

Procedure set_pix(x_pos,y_pos,_red,_green,_blue:byte);
var _bit_nr:byte;
_byte_nr:byte;
begin
 _bit_nr:= 7- (x_pos mod 8);


 if y_pos >=8 then
  begin
   y_pos:=y_pos-8;
   _byte_nr:=((x_pos div 8) *24) + (y_pos*3)+96;
  end
   else
   _byte_nr:=((x_pos div 8) *24) + (y_pos*3);


 if _red=0 then
   clearbit(screen[_byte_nr+0],_bit_nr)
  else
   setbit(screen[_byte_nr+0],_bit_nr);

   
 if _green=0 then
   clearbit(screen[_byte_nr+1],_bit_nr)
  else
   setbit(screen[_byte_nr+1],_bit_nr);
   
 if _blue=0 then
   clearbit(screen[_byte_nr+2],_bit_nr)
  else
   setbit(screen[_byte_nr+2],_bit_nr);


end;


Procedure set_screen(_red: byte;_green:byte;_blue:byte);
var
_n,tmp_r,tmp_g,tmp_b: byte;
begin
  tmp_r:=0;
  tmp_g:=0;
  tmp_b:=0;

 if _red=1 then
  tmp_r:=0xff;
 if _green=1 then
  tmp_g:=0xff;
 if _blue=1 then
  tmp_b:=0xff;

 
 for _n:=0 to 63 do
 begin
   screen[(_n*3)+0]:=tmp_r;
   screen[(_n*3)+1]:=tmp_g;
   screen[(_n*3)+2]:=tmp_b;

 end;

end;


begin
  { Main program }

Reset;

 set_screen(0,0,0);


while true do
 begin

 set_pix(5,5,1,1,1);
 set_pix(6,6,1,0,0);
 set_pix(7,7,0,1,0);
 set_pix(8,8,0,0,1);
 set_pix(9,9,1,1,0);
 set_pix(10,10,1,0,1);
 set_pix(11,11,0,1,1);


 end;
end.
ASM FILE

Code: Select all

_T0_Int:
	PUSH       R30
	PUSH       R31
	PUSH       R27
	IN         R27, SREG+0
	PUSH       R27
	PUSH       R28
	PUSH       R29
	IN         R28, SPL+0
	IN         R29, SPL+1
	SBIW       R28, 2
	OUT        SPL+0, R28
	OUT        SPL+1, R29
	ADIW       R28, 1

;panel32x16rgb.mpas,84 :: 		begin
;panel32x16rgb.mpas,86 :: 		push r0;
	PUSH       R0
;panel32x16rgb.mpas,87 :: 		push r1;
	PUSH       R1
;panel32x16rgb.mpas,91 :: 		if scan<1 then    /// 1/2
	LDS        R16, _scan+0
	CPI        R16, 1
	BRLO       L__T0_Int72
	JMP        L__T0_Int3
L__T0_Int72:
;panel32x16rgb.mpas,93 :: 		inc (scan);
	LDS        R16, _scan+0
	SUBI       R16, 255
	STS        _scan+0, R16
;panel32x16rgb.mpas,94 :: 		tmp_scan:=3;
; tmp_scan start address is: 20 (R20)
	LDI        R20, 3
;panel32x16rgb.mpas,95 :: 		end
; tmp_scan end address is: 20 (R20)
	JMP        L__T0_Int4
;panel32x16rgb.mpas,96 :: 		else
L__T0_Int3:
;panel32x16rgb.mpas,98 :: 		scan:=0;
	LDI        R27, 0
	STS        _scan+0, R27
;panel32x16rgb.mpas,99 :: 		tmp_scan:=0;
; tmp_scan start address is: 20 (R20)
	LDI        R20, 0
; tmp_scan end address is: 20 (R20)
;panel32x16rgb.mpas,100 :: 		end;
L__T0_Int4:
;panel32x16rgb.mpas,103 :: 		for _n:=0 to 7 do   //3
; tmp_scan start address is: 20 (R20)
; _n start address is: 21 (R21)
	LDI        R21, 0
; tmp_scan end address is: 20 (R20)
; _n end address is: 21 (R21)
L__T0_Int6:
;panel32x16rgb.mpas,105 :: 		tmp_n:=(_n*12)+tmp_scan;
; _n start address is: 21 (R21)
; tmp_scan start address is: 20 (R20)
	LDI        R16, 12
	MUL        R21, R16
	MOV        R16, R0
	ADD        R16, R20
	STD        Y+1, R16
;panel32x16rgb.mpas,106 :: 		for _i:=0 to 7 do
	LDI        R27, 0
	STD        Y+0, R27
Best regards
G.B.
Attachments
R0,R1 on the stack
R0,R1 on the stack
rgbpanel2.jpg (81.14 KiB) Viewed 1830 times
No R0,R1 on the stack
No R0,R1 on the stack
rgbpanel1.jpg (140.47 KiB) Viewed 1830 times

Post Reply

Return to “mikroPascal PRO for AVR General”