Help: CC65 Compiled Code Locking Up??

You need an actual VIC.

Moderator: Moderators

SparkyNZ
Vic 20 Enthusiast
Posts: 153
Joined: Tue Jan 18, 2011 2:23 am

Post by SparkyNZ »

Kweepa wrote:Ok, I managed to get cc65 to compile a single prg that reserves space for UDGs at $1400-$1C00. Just change your cfg file to read as follows:
Thanks Kweepa. I'm just playing around with screen and character memory layouts under 16k right this very minute but in BASIC with CBMPrgStudio 1.6.1 at the moment.. (then I thought I'd try the same with CC65 :) )

I'm using the exact same UDG location $1400 and $1000 for the screen so its good to see I'm doing something the same.. Of course I'm now getting .PRG generation problems with CBMPrgStudio. It either doesn't like my comments or something. :) Perhaps I'll jump back to CC65 soon - I may have more luck with that now. :)

Update: Yeah, I had comments of more than 40 characters that were going into the Vic listings. Just found out that I can use "Smart Comments" so my comments don't get generated in the .PRG files.. Now that I have my little test program working, I'll go see if I can get it working with CC65...
SparkyNZ
Vic 20 Enthusiast
Posts: 153
Joined: Tue Jan 18, 2011 2:23 am

Post by SparkyNZ »

Kweepa wrote:Ok, I managed to get cc65 to compile a single prg that reserves space for UDGs at $1400-$1C00.
Hi Kweepa. I've tried modifying the .CFG file but I reckon I haven't a clue what I'm doing. :)

I am using $1000 for the screen data and $1400 for character data. I don't understand why the "RAM" definition in the .CFG file starts at $11FF. I tried $1000 and that wouldn't work at all. I also tried moving the program code to $4000 but that seems to have the same effect.

Can you help me please? Please don't be too critical of the C code - I cut and pasted the BASIC from CBMPrgStdio and changed it into C.

Code: Select all

MEMORY {
    ZP: start =  $0002, size = $001A, type = rw, define = yes;
    RAM: start = $11FF, size = $A01, define = yes, fill = yes, file = %O;
    URAM: start = $4000, size = $2000, define = yes, file = %O;
}
Here's my test program:

Code: Select all

#include <stdio.h>

#define BYTE unsigned char

#undef POKE
#define POKE(x,y) *(BYTE*)(x)=y
#define PEEK(x)   *((BYTE*)(x))

void main( void )
{
  int   c, o;

  POKE( 36879, 8 );

  printf( "\x8e\x13\x40\n" );
  printf( "\x05hello paul\n" );
  
  // 0xCD - Screen @ $1000, Char @ $1400 
  POKE( 36869, 0xCD );
  POKE( 36866, PEEK( 36866 ) & 254 );

  // Go into double height mode..
  POKE( 36867, PEEK( 36867 ) | 1 );

  // 5120 = $1400

  // Copy ROM characters over and make double height
  for( c = 0; c < 2048; c ++ )
  {
    o = c * 2;
    POKE( 5120 + o,     PEEK( 32768 + c ) );
    POKE( 5120 + o + 1, PEEK( 32768 + c ) );
  }

  // Fill screen with red characters
  for( c = 0; c < 256; c ++ )
  {
    POKE( 4096  + c, c );
    POKE( 37888 + c, 2 );
  }

  for( ;; ) ;
}
User avatar
Kweepa
Vic 20 Scientist
Posts: 1315
Joined: Fri Jan 04, 2008 5:11 pm
Location: Austin, Texas
Occupation: Game maker

Post by Kweepa »

You have to put the URAM (upper RAM) memory next to the RAM section, so put that back to $1C00 - this is so there's no gap between RAM and URAM. The linker isn't smart and just glues the two segments together, so it will be compiled as if the upper memory is separated but linked as if there's no gap, and the memory addresses won't line up.

You also have to make sure that all the segments except STARTUP, LOWCODE and INIT are changed to load = URAM, as in the cfg snippet I posted.

I'm using this cfg and it's working for me.
SparkyNZ
Vic 20 Enthusiast
Posts: 153
Joined: Tue Jan 18, 2011 2:23 am

Post by SparkyNZ »

Kweepa wrote:You have to put the URAM (upper RAM) memory next to the RAM section, so put that back to $1C00 - this is so there's no gap between RAM and URAM. The linker isn't smart and just glues the two segments together, so it will be compiled as if the upper memory is separated but linked as if there's no gap, and the memory addresses won't line up.

You also have to make sure that all the segments except STARTUP, LOWCODE and INIT are changed to load = URAM, as in the cfg snippet I posted.

I'm using this cfg and it's working for me.
I've just cut and pasted your .cfg snippet in and it ain't working.. The double height characters get created, no problem there, but the below bit of code doesn't seem to be happening:

Code: Select all

  for( c = 0; c < 256; c ++ )
  {
    POKE( 4096  + c, c );
    POKE( 37888 + c, 2 );
  }
The problem seems similar to my original problem of code overwriting:

Code: Select all

  // Copy ROM characters over and make double height
//  for( c = 0; c < 2048; c ++ ) - DOES NOT WORK
//for( c = 0; c < 512; c ++ ) - WORKS OK
for( c = 0; c < 1024; c ++ ) - DOES NOT WORK
{
  o = c * 2;
  POKE( 5120 + o,     PEEK( 32768 + c ) );
  POKE( 5120 + o + 1, PEEK( 32768 + c ) );
}
Cheers
Paul
User avatar
Kweepa
Vic 20 Scientist
Posts: 1315
Joined: Fri Jan 04, 2008 5:11 pm
Location: Austin, Texas
Occupation: Game maker

Post by Kweepa »

Ah yes, I see.
256 16-byte characters is 4k, which extends from $1400 to $2400.
So you'll have to use:

Code: Select all

    RAM: start = $11FF, size = $1201, define = yes, fill = yes, file = %O;
    URAM: start = $2400, size = $3C00, define = yes, file = %O;
SparkyNZ
Vic 20 Enthusiast
Posts: 153
Joined: Tue Jan 18, 2011 2:23 am

Post by SparkyNZ »

Kweepa wrote:Ah yes, I see.
256 16-byte characters is 4k, which extends from $1400 to $2400.
So you'll have to use:

Code: Select all

    RAM: start = $11FF, size = $1201, define = yes, fill = yes, file = %O;
    URAM: start = $2400, size = $3C00, define = yes, file = %O;
Excellent - that worked.. So why didn't this work below?

Code: Select all

    RAM: start = $11FF, size = $A01, define = yes, fill = yes, file = %O;
    URAM: start = $4000, size = $2000, define = yes, file = %O; 
I realise the size I had was only $A01, not $1201.. Does that mean that the linker has ignored the URAM definition and just put the program code at $11FF + $A01 ?

I still don't understand why the RAM section starts at $11FF and not $1000. $1FF is nearly 2 lots of 256 (511) so does this have some implicit connection to the screen RAM requirements? (i.e. is the linker not allowed to 'map over' the screen RAM that I'm using?)

I admit I'm hazy concerning the screen RAM and colour "RAM" usage in the Vic. My understanding with the color RAM (38400/37888) was that this area was mapped to the Vic chip directly (I/O address lines rather than actual RAM, or "RAM within the Vic chip" if you like), but I thought the screen RAM was actual RAM. Am I making any sense? :)
User avatar
Mike
Herr VC
Posts: 4840
Joined: Wed Dec 01, 2004 1:57 pm
Location: Munich, Germany
Occupation: electrical engineer

Post by Mike »

From the view of the VIC chip, the colour RAM is everywhere.

The colour RAM is connected over an extra 4-bit data bus to the VIC chip, and shares the lower 10 address pins with the 14-bit VIC address bus.

That is the reason the colour RAM changes its base address along with the screen RAM base address. Take a look at the lower 10 address bits:

Code: Select all

4096 = %000100|0000000000    37888 = %100101|0000000000
7680 = %000111|1000000000    38400 = %100101|1000000000
In the first line, the lower 10 bits are both %0000000000, in the second line %1000000000. That pattern still holds, when the screen memory is shifted to another address, the colour RAM has always the same base address MOD 1024.

Furthermore, the following correspondence holds:

Code: Select all

VIC address range    CPU address range

 $0000 ... $1FFF      $8000 ... $9FFF, i.e. BLK4
 $2000 ... $3FFF      $0000 ... $1FFF, i.e. BLK0
Anything outside BLK0 or BLK4 is not accessible to VIC.

It is also not able to access the colour RAM as text or character generator data, as an analog switch separates the normal data bus and the colour RAM bus during VIC access.

Even though an external +3K RAM expansion maps into BLK0, it is not accessible by VIC either, as it is on the 'wrong' side of the data bus and address bus buffers, which also separate the VIC and CPU side of both busses during VIC access. They're necessary, because the 6502 cannot tri-state its address bus.

An internal +3K expansion, as done in parts 1 and 2 of my VFLI mod, fills the hole between $0400 and $0FFF on the VIC side, making the complete BLK0 available for graphics data.
Post Reply