t-edson / P65Pas

CPU 6502 Pascal Compiler/IDE/Debugger
GNU General Public License v3.0
125 stars 27 forks source link

About basic compiler optimizations #11

Closed odflor closed 5 years ago

odflor commented 5 years ago

Hi Mr.:

I see that the compiler is growing very good. I think there is a moment to test to do some kind of library for upload images, sprites, play music, read joystick and things like that.

My concern is about compiler optimizations. And some overlay of executable files.

Wath is the best organization to make the routines, one per file or I can group routines by kind? For example graphics.pas, sound.pas, serial.pas, and so on?.

If a program use one routine of this library files, the final executable will have the routine and its requirements or will have all the other unused rutine of the library?

Also is good to staring thinking on implementing overlay files when the program grows up to do some kind of complex program.

Thanks and Best Regards Good Work!

mvdhoning commented 5 years ago

according to my usage it already does a nice job of optimizing things, collecting only used variables and procedure that are used from units

mvdhoning commented 5 years ago

sprite test

add uses sprite1 to the main and call initSprite1 and it shows a green commodore balloon

i cannot find a nice way to poke the sprite1data to $2000 so that has to wait either for byte array with data initalized at a certain adres (there is an issue for that) or allow assigning to a position in an array (there is an issue for that also) or a way i could not think of at the moment


unit sprite1;

interface

var 
  sprite1data: [64]byte = [0,127,0,1,255,192,3,255,224,3,231,224,
                             7,217,240,7,223,240,7,217,240,3,231,224,
                             3,255,224,3,255,224,2,255,160,1,127,64,
                             1,62,64,0,156,128,0,156,128,0,73,0,0,73,0,
                           0,62,0,0,62,0,0,62,0,0,28,0];
  sprite1pointer: byte absolute $07F8;
  spritesEnable: byte absolute $D015;
  sprite1xpos: byte absolute $D000;
  sprite1ypos: byte absolute $D001;
  sprite1color: byte absolute $D027;
  sprite1adres: byte absolute $2000;

procedure initSprite1;

implementation

procedure initSprite1;
var
  i,t: byte;
  pos: word;
begin

  for i:=0 to 63 do
    t := sprite1data[i];
    asm
      ldx i
      lda t
      sta sprite1adres,x
    end
  end; 

  sprite1pointer:=$80; //128*64=$2000
  spritesEnable:=1;
  sprite1xpos:=128;
  sprite1ypos:=128;
  sprite1color:=5; //green
end;  

end.
t-edson commented 5 years ago

Hi.

I see that the compiler is growing very good. I think there is a moment to test to do some kind of library for upload images, sprites, play music, read joystick and things like that.

Yes, the compiler has been improved a lot in these days. Several features has been added, specially in working with assembler, arrays, pointers, function parameters and units. Code generation is a bit incomplete, by now.

Wath is the best organization to make the routines, one per file or I can group routines by kind? For example graphics.pas, sound.pas, serial.pas, and so on?.

We have a unit Commodore.pas. It's intended to set the compiler to work in Commodore 64 mode. I guess we can create other units like you propose., grouped by function.

If a program use one routine of this library files, the final executable will have the routine and its requirements or will have all the other unused rutine of the library?

P65Pas use some algorithms to identify what variables and functions are really used. And only compiles what is used. Even has the capability to detect variables that can be reused sharing the same memory, but this is features seems not working by now in the compiler.

P65Pas pretend to be a high optimized compiler, and some optimizations, disabled by now, will be reviewed in the future.

t-edson commented 5 years ago

The sprite program runs excellent. The new advances in the compiler allows now to assign items indexing:

  for i:=0 to 63 do
    sprite1adres[i] := sprite1data[i];
  end; 

Or even assign the complete array:

  sprite1adres: [64]byte absolute $2000;
  sprite1adres := sprite1data;

Also you can initialize arrays with constant, so you can just do:

unit sprite1;

interface

var 
  sprite1data: [64]byte  absolute $2000;
  sprite1pointer: byte absolute $07F8;
  spritesEnable: byte absolute $D015;
  sprite1xpos: byte absolute $D000;
  sprite1ypos: byte absolute $D001;
  sprite1color: byte absolute $D027;

procedure initSprite1;

implementation

procedure initSprite1;
begin
  sprite1data := [0,127,0,1,255,192,3,255,224,3,231,224,
                    7,217,240,7,223,240,7,217,240,3,231,224,
                    3,255,224,3,255,224,2,255,160,1,127,64,
                    1,62,64,0,156,128,0,156,128,0,73,0,0,73,0,
                  0,62,0,0,62,0,0,62,0,0,28,0,0];

  sprite1pointer:=$80; //128*64=$2000
  spritesEnable:=1;
  sprite1xpos:=128;
  sprite1ypos:=128;
  sprite1color:=5; //green
end;  

end.
t-edson commented 5 years ago

@mvdhoning I would like to include your code in the examples section of the distribution if you don't have any problem of course. P65Pas hasn't example with sprites.

mvdhoning commented 5 years ago

its fine by me, but i am not the designer of the sprite as the sprite is from the c64 programmers manual: http://www.devili.iki.fi/Computers/Commodore/C64/Programmers_Reference/Chapter_3/page_146.html going to try out the new features as they open a lot of possibilties :-)

i prefer keeping sprite data in the var declaration and assiging it with sprite1adres := sprite1data; also nice optimisation in the assignment there at first i thought it was wrong, but i was

    ;sprite1adres:=sprite1data;
      $090C A2 40    LDX #$40 
      $090E BD 1B 08 LDA $081B,X 
      $0911 9D FF 1F STA $1FFF,X 
      $0914 CA       DEX  
      $0915 D0 F7    BNE $090E

as it exits when 0 is reached if starting with $3F and the 'correct' memory adresses the last byte would not have been written. Clever. Away with the for loop :-)