Re: [cc65] Hello, and a memory corruption (?) issue when optimizing

From: Greg King <greg.king51verizon.net>
Date: 2013-06-11 07:23:01
From: "Maik Merten"; on Monday, June 10, 2013; at 1:00 PM -0400
>
> This is interesting to toy around with. From the looks of the
> corruption, I'd guess that either the video-RAM or color-RAM ends up
> with wrong values.

That is correct.  It is an optimizer bug.
Before I explain, I will show the function that has the problem:

void showPicture(int imgdata) {
    int i = 0;
    int vicconf[3];
    int base;

    vicconf[0] = VIC.addr;
    vicconf[1] = VIC.ctrl1;
    vicconf[2] = VIC.ctrl2;
    VIC.spr_ena = 0;
    base = 16384;

    // 8000 bytes bitmap
    memcpy((int*)(base + 8192), (int*)imgdata, 8000);
    // 1000 bytes char mem
    memcpy((int*)(base + 0x0400), (int*)(imgdata + 8000), 1000);
    // 1000 bytes color mem
    memcpy((int*)(0xD800), (int*)(imgdata + 9000), 1000);
    // 1 byte background color
    bgcolor(*((int*)(imgdata + 10000)));
    switchBank(1);
    // multicolor on
    // POKE 53265,PEEK(53265) OR 32 : POKE 53270,PEEK(53270) OR 16
    VIC.addr = VIC.addr | 8; // bitmap at 8192
    VIC.ctrl1 = VIC.ctrl1 | 32;
    VIC.ctrl2 = VIC.ctrl2 | 16;
    while(1){
        if(!(PEEK(JOY2) & 0x1f & JOYFIRE)) break;
    }
    // multicolor off
    VIC.addr = vicconf[0];
    VIC.ctrl1 = vicconf[1];
    VIC.ctrl2 = vicconf[2];
    switchBank(0);
    clrscr();
    bgcolor(0);
}

When the optimizer gets to "base = 16384", it removes a "LDX #$40" from the
output assembly code.  Therefore, the statement becomes "base = 0".  But,
the optimizer remembers what "base" is supposed to hold!!  It converts the
expression "(base + 8192)" into "(16384 + 8192)".  So, the first memcpy()
puts the bitmap where it should go.  The optimizer doesn't remember "base"
in the next memcpy() -- the variable is read; so, that function call puts
the text-RAM palette into the normal screen area, instead of where the
VIC-II will look for it.  The video chip sees garbage for that color
palette.

If I double the assignment line:

    base = 16384;
    base = 16384;

then the optimizer doesn't drop the "LDX #$40".  (A macro would be even
better:
#define BASE 0x4000
)

After that fix, the palette will be copied on top of another part of the
program.  So, you need to add an option to the cl65 command line.
"-m nuclear.map" will give you a text file that will show you where the
program sits in RAM.  Look for the section of that file that is entitled
"Segment list".  Then, you must change the destination of the memcpy().
(A good place for the text-RAM palette is just below the bitmap.)

----------------------------------------------------------------------
To unsubscribe from the list send mail to majordomo@musoftware.de with
the string "unsubscribe cc65" in the body(!) of the mail.
Received on Tue Jun 11 08:23:28 2013

This archive was generated by hypermail 2.1.8 : 2013-06-15 17:37:38 CEST