drmortalwombat / oscar64

Optimizing Small memory C Compiler Assembler and Runtime for C64
GNU General Public License v3.0
273 stars 24 forks source link

Error referencing a variable in assembly inline #63

Closed AGPX closed 5 months ago

AGPX commented 5 months ago

Hi,

I've reproduced an issue (with latest commited version, using -O2 or -O0, no matter) where the address of a local variable is translated to a random address:

class Player
{
public:
    unsigned char  sprN[4], ns;
    unsigned short x;
    unsigned char  y;
    unsigned char *sprites;

    void setupFrame();
};

void Player::setupFrame()
{
    // Assembly implementation...

    unsigned char n;
    unsigned char vi, temp;

    const auto _sprN    = sprN;
    const auto _sprites = sprites;
    const auto _px      = x;
    const auto _py      = y;
          auto nsAlias  = &ns;
          auto _ns      = ns;

    __asm {

                ldy #0
                lda #2
        sta (nsAlias),y

        lda #0
        sta vi

        ldy #1

        lda vi
        cmp _ns
        bcc sets01
        jmp exit201

sets01:
        sty temp
        ldy vi

        lda (_sprN),y
        sta n

        ldy temp

        lda (_sprites),y
        iny
        tax
        lda #1
        ldx n
        sta 2040,x

        txa
        asl
        tax

        lda (_sprites),y
        bmi exit201
        clc
        adc _px      // <--- This is translated to "ADC $00" or "ADC $1f" or "ADC WORK + 6", looks randomly. Why?
        beq sets01
        cmp _py     // <--- This is translated correctly to CMP T6 + 0 

exit201:
    };

}

int main()
{
    Player p;
    p.x = 1;
    p.y = 2;
    p.setupFrame();
    return 0;
}

If I replace the __asm statement with only the following one:

__asm {
        lda (_sprites),y
        bmi exit201
        clc
        adc _px                     // <--- This is translated ADC T1 + 0 
        beq exit201
        cmp _py                     // <--- This is translated CMP T2 + 0 
exit201:
    };

it works as expected.

drmortalwombat commented 5 months ago

There is a limit of seven variables to be passed into an assembler block. I extended this to eleven now and added an error, when this limit is exceeded.