Jump to content
IGNORED

cc65: Graphics 8 pixel plotters...


Recommended Posts

Attached is a link to a graphics mode 8 pixel plotting test harness.  It includes all sorts of ways to plot a single pixel on a graphics 8 screen from the slowest (~13 pixels / jiffy)  to the fastest I've managed (~332 pixels / jiffy) on an NTSC machine (on a PAL machine the counts are ~17 / ~427 pixels per jiffy).

 

The various methods are all general purpose routines meant to plot a pixel at a given location.  There are two "cheat" tests that are optimized for the use case of filling a screen.  The project also serves as an example of interfacing CC65 with external assembly code, how to pass variables using the zeropage, and how (in some cases) not to plot pixels.  It also includes a routine to plot text on a gr8 screen.

 

This little project was made possible by all the code folks have published over the years as well as the conversations I've had on AtariAge.

 

Next step is to add sprites...

 

https://github.com/damosan314/gr8

gfx.xex

Edited by damosan
Added binary.
  • Like 2
Link to comment
Share on other sites

$ cl65 -Osir -C gfx.cfg -t atari gfx.c gr8sprite.s -o gfx.xex
gr8.h(4): Error: Include file `common.h' not found
gfx.c(122): Error: Undefined symbol: `OS'
gfx.c(122): Error: Struct expected
gfx.c(122): Error: Struct/union has no field named `rtclok'
gfx.c(122): Error: Subscripted value is neither array nor pointer
gfx.c(122): Error: Struct expected
gfx.c(122): Error: Struct/union has no field named `rtclok'
gfx.c(122): Error: Subscripted value is neither array nor pointer
gfx.c(152): Error: Undefined symbol: `OS'
gfx.c(152): Error: Struct expected
gfx.c(152): Error: Struct/union has no field named `rtclok'
gfx.c(152): Fatal: Too many errors

Am I missing something?

Link to comment
Share on other sites

1 hour ago, atarixle said:

gfx.c(122): Error: Undefined symbol: `OS' gfx.c(122): Error: Struct expected

 

@damosan already added the missing header.

The problems with the missing "OS"-symbol are reasoned by a more than 3 year old cc65 version.

See also here:

 

  • Like 1
Link to comment
Share on other sites

10 hours ago, damosan said:

The various methods are all general purpose routines meant to plot a pixel at a given location. 

Looking good, the only thing to optimize would be rewriting to ASM function plot_pixel_lookups_zp4 (with 2 lookup tables for X under and over 256).

Btw, the tables you can generate shorter:

.align  256

yindexlo:    .res 256
yindexhi:    .res 256

bitmask_table:
.repeat 32
    .byte $80, $40, $20, $10, $08, $04, $02, $01
.endrep

byteoffset_table:
.repeat 256,i
    .byte i/8
.endrep

byteoffset256_table:
.repeat 256,i
    .byte 4+i/8
.endrep

also instead of using hardcoded addresses on ZP you could define them with pragmas https://cc65.github.io/doc/cc65.html#ss7.20

Edited by ilmenit
Link to comment
Share on other sites

Yeah - I had aligns in there initially but the linker would complain about the code segment not being aligned.  It'd still work of course - I need to modify the linker config to align the data segment to a page.  I made some changes to the assembly (using res) but kept the other tables as they were as someone new to 6502 assembly and ca65 may be confused with the repeat/endrep stuff.

 

I'm thinking of new ways to plot pixels where the LDA/ORA/STA sequence will work with absolute addresses instead of lookups.  It's going to take a lot of space of course.

 

 

 

Link to comment
Share on other sites

2 minutes ago, damosan said:

I'm thinking of new ways to plot pixels where the LDA/ORA/STA sequence will work with absolute addresses instead of lookups.  It's going to take a lot of space of course.

You can also place screen memory at selected/aligned locations to squeeze some cycles with the code. If speed is the most critical then even place each screen line at the beginning of a page (like in some demoscene effects).

Link to comment
Share on other sites

Well, now if you get these errors (like I did):

 

$ cl65 -Osir -C gfx.cfg -t atari gfx.c gr8sprite.s -o gfx.xex
common.h(4): Error: Multiple definition for 'word'
common.h(7): Error: Multiple definition for 'byte'

just remove the definition in common.h which now looks like this:

#ifndef __COMMON_H
#define __COMMON_H

//typedef unsigned int  word;
typedef unsigned int  u16;
typedef int           s16;
//typedef unsigned char byte;
typedef unsigned char u8;
typedef signed char   sbyte;
typedef signed char   s8;

#endif

... and wow that is going freaking fast at the end!

Link to comment
Share on other sites

5 hours ago, atarixle said:

Well, now if you get these errors (like I did):

 


$ cl65 -Osir -C gfx.cfg -t atari gfx.c gr8sprite.s -o gfx.xex
common.h(4): Error: Multiple definition for 'word'
common.h(7): Error: Multiple definition for 'byte'

 

 

What version of the compiler are you using?  I'm running 2.19.

Link to comment
Share on other sites

ok, one last try (I mean it just worked with my modifications, but it's worth the try that late in the evening). I downloaded the cc65-master.zip and am compiling it right now.

Let's see what version it attempts to produce and if it works like your versions do.

 

(Hell, I love it! Compiling without ./configure, without errors, even without warnings, on every system from PowerPC Leopard, over 32 bit Intel Linux, up to 64 bit macOS Monterey. But it needs a PREFIX to be added manually - something is always as we say in german.)

 

ok, now it reported the 2.19 as the current version.

 

....aaaaaaaand:

it compiles, no matter if I comment out the definition for word and byte. strange.

 

$ vim common.h 
removing the definitions of word and byte
$ cl65 -Osir -C gfx.cfg -t atari gfx.c gr8sprite.s -o gfx.xex
$ vim common.h 
adding the definitions of word and byte 
$ cl65 -Osir -C gfx.cfg -t atari gfx.c gr8sprite.s -o gfx.xex
$ 

No errors on both compiles. Do they both work? ...

(let pass some time ...)

Both compiles work.

Link to comment
Share on other sites

Well may be I over-reacted.

I more meant that as a funny, more a sarcastic statement.

I really guess I either write bad styled C code, or I write C style of an older ISO standard of code.

Actually only one - the largest project - is breaking. All others compile with warnings that never appeared before, but run even faster at the end ???

cc65 2.18 lets me use text as an unsigned char, and it casts it without any error or warning. 2.19 now brings tons of warnings that casting between char* and unsigned char* does something with the signess. But it still works somehow.

The project that breaks uses a struct with self referencing pointers (e.g. *next, *prev for chains). This compiles in 2.18 but horrorbly breaks in errors in 2.19-master.

 

Edited by atarixle
Link to comment
Share on other sites

1 hour ago, atarixle said:

The project that breaks uses a struct with self referencing pointers (e.g. *next, *prev for chains). This compiles in 2.18 but horrorbly breaks in errors in 2.19-master.

 

show here a minimal example of the code and we will try to help.

Link to comment
Share on other sites

Yeah I was thinking that too, but now it compiles without errors, because a closer look at this time of day revealed that this wasn't causing the error.

Beside a typo (which strangely did not throw and error on 2.18) I also had an invalid lvalue, which I fixed with a pair of brackets.

 

Now it compiles the whole project but the outcome results in errors while runtime.

 

Time now to remove all warnings I guess.

Edited by atarixle
Link to comment
Share on other sites

ok this is even weirder to me:

The project now works, as I removed the cast in 

memset((unsigned char*)PST, 170, SCREEN_WIDTH);
 
originally, I added this cast to avoid the Warning: Converting integer to pointer without a cast
 
Most of my projects run way faster than before: a per-pixel-scroller in GR.8 feels like 3x the speed as before, and my prime-number-generator speed up from 22 seconds down to 17 seconds for the very same task (calculating primes from 2 to 32000).
Edited by atarixle
SPEED
Link to comment
Share on other sites

29 minutes ago, atarixle said:

The project now works, as I removed the cast in 

You shouldn't need the cast as long as PST has been defined as char *PST

Also all pointers are unsigned, they are purely 16 bit addresses so "unsigned" is also not needed.

I think that definition may have somehow confused the compiler

Link to comment
Share on other sites

Join the conversation

You can post now and register later. If you have an account, sign in now to post with your account.
Note: Your post will require moderator approval before it will be visible.

Guest
Reply to this topic...

×   Pasted as rich text.   Paste as plain text instead

  Only 75 emoji are allowed.

×   Your link has been automatically embedded.   Display as a link instead

×   Your previous content has been restored.   Clear editor

×   You cannot paste images directly. Upload or insert images from URL.

Loading...
  • Recently Browsing   0 members

    • No registered users viewing this page.
×
×
  • Create New...