Jump to content
IGNORED

C or Assembler for game development


zzip

Recommended Posts

When I was learning programming on my Atari back in the day, we "knew" that real games/apps were written in assembly language, not basic. So I learned assembly language from a library book. But I was a kid and couldn't justify buying a package like MAC65 or Atari Assembler. So I was using an assember written in basic that I typed in from that book. Needless to say it didn't do me any favors :)

 

So now I'm thinking about trying my hand at creating some homebrew atari projects. I've since become proficient in C, and I see that there's a cc65 compiler. Does this have a lot of overhead? For instance, if I write a very simple "hello" program on Linux, it compiles to a 6K binary. 6K would be a lot on an Atari, same program could be written in assembly for 30 bytes or less. Hopefully CC65 could produce something more compact.

 

It would be awesome if I could write my games in C on the Atari, I could churn them out in no time.

Edited by zzip
Link to comment
Share on other sites

Not an expert by any means. These are just casual observations/opinions.

 

Most classic game system targets for cc65 seem to have neglected or incomplete libraries. My guess is that the 5200 is in that category.

 

Most action is on the assembly side so everyone will point out assembly always wins on performance. It really comes down to how comfortable you are with the tools.

Link to comment
Share on other sites

You can mix C and assembly if you want for time critical procedures. Just an opinion of course, it depends on the type of game you want to write. There are lots of games like RPGs, puzzles, text adventures, and sims that would be easier to do in C. There are a few ~contests where code density is the goal, but other then that you can assume memory won't be a problem.

Link to comment
Share on other sites

I'd expect that even if you used C, you'd still have to hand-inspect and vet the assembly. A lot of stuff on the 5200/8-bit is extremely time sensitive and you'd just end up doing it in assembly anyway.

 

For me personally, working in assembly is a huge part of doing homebrew. If I want to do something in C (and I do!) I can write a PC game or something. I prefer to "choose the right job for the tool" rather than the reverse. I decide I'd like to do something in language X, and then come up with a project that allows me to do so.

  • Like 1
Link to comment
Share on other sites

Not an expert by any means. These are just casual observations/opinions.

 

Most classic game system targets for cc65 seem to have neglected or incomplete libraries. My guess is that the 5200 is in that category.

 

Most action is on the assembly side so everyone will point out assembly always wins on performance. It really comes down to how comfortable you are with the tools.

 

yes, assembly will always win on performance, but I'm hoping cc65 might be 'good enough', since I haven't touched 6502 assembly in about 30 years, and would be rusty.

 

Incomplete libraries doesn't bother me, I'm comfortable coding my own low-level functions if needed.

Link to comment
Share on other sites

I'd expect that even if you used C, you'd still have to hand-inspect and vet the assembly. A lot of stuff on the 5200/8-bit is extremely time sensitive and you'd just end up doing it in assembly anyway.

 

For me personally, working in assembly is a huge part of doing homebrew. If I want to do something in C (and I do!) I can write a PC game or something. I prefer to "choose the right job for the tool" rather than the reverse. I decide I'd like to do something in language X, and then come up with a project that allows me to do so.

 

I'm fine mixing ASM and C, That might be the refresher course I need to give me the confidence to go full assembly on another project.

Link to comment
Share on other sites

 

I'm fine mixing ASM and C, That might be the refresher course I need to give me the confidence to go full assembly on another project.

 

That would be a great intermediate step. It might be the most practical too. I can't imagine writing things like HBLANK interrupts in C and actually having it work out, but maybe I'm underestimating C compilers.

Link to comment
Share on other sites

 

That would be a great intermediate step. It might be the most practical too. I can't imagine writing things like HBLANK interrupts in C and actually having it work out, but maybe I'm underestimating C compilers.

 

lol yeah, there's only so much code that can be executed during a DLI/HBLANK, and I wouldn't trust any compiler to produce it. Fortunately I've always found writing ASM for DLIs pretty easy because I am only changing a handful of memory register for new colors, different P/M positions, etc.

Link to comment
Share on other sites

 

yes, assembly will always win on performance, but I'm hoping cc65 might be 'good enough', since I haven't touched 6502 assembly in about 30 years, and would be rusty.

 

Incomplete libraries doesn't bother me, I'm comfortable coding my own low-level functions if needed.

 

 

I was in the same boat as you when I decided I wanted to write something for the Lynx a month ago. I had done some stuff for the 2600 a few years back, but my real 6502 coding dates back to the mid '80s. Don't worry, you will pick back up the 8-bit instruction set and that old knowledge/tricks you've store away from year's past.

 

I would recommend staying with assembly as the macro assemblers are so much better these days, can be used to cross-compile to the 8-bit targets and will give the best utilization of CPU cycles/memory footprint (at the cost of implementation speed). You can also use one of the 6502 C compilers too, and have it output the assembly so you can see what it would generate. I used to use that when I was doing Nintendo 64 and Saturn work to see how much I would need to actually code in MIPS and SH2 assembly.

  • Like 2
Link to comment
Share on other sites

When I was learning programming on my Atari back in the day, we "knew" that real games/apps were written in assembly language, not basic. So I learned assembly language from a library book. But I was a kid and couldn't justify buying a package like MAC65 or Atari Assembler. So I was using an assember written in basic that I typed in from that book. Needless to say it didn't do me any favors :)

 

So now I'm thinking about trying my hand at creating some homebrew atari projects. I've since become proficient in C, and I see that there's a cc65 compiler. Does this have a lot of overhead? For instance, if I write a very simple "hello" program on Linux, it compiles to a 6K binary. 6K would be a lot on an Atari, same program could be written in assembly for 30 bytes or less. Hopefully CC65 could produce something more compact.

 

It would be awesome if I could write my games in C on the Atari, I could churn them out in no time.

 

I believe that you are aware of this thread. You can find some games written in C with full source code there.

And do not judge by the size of "Hello world" program. There can be huge differences. In CC65, cputs("Hello world"); will result in much smaller binary than printf("Hello world\n");

Also CC65 is very well suited for mixing C and Assembler and also has amazing linker that allows you to store game data (graphics, character sets, display lists) in the resulting binary file.

  • Like 2
Link to comment
Share on other sites

Using C is going to have overhead but try writing a game and see if you're satisfied with the result. If you expect to push the hardware to its limits, then C is going to be a poor choice.

 

It might also be relevant to keep in mind that you'll want to understand the low-level systems of the Atari (e.g. display lists, ANTIC, GTIA), regardless of language choice.

Link to comment
Share on other sites

Given the choice of either C or assembly, I'd do a mix of both as well. Assembly for cycle-exact stuff, or where you need the tightest code, and C for long and tedious game logic. I've found off-by-one bugs in a number of commercial 6502 games, and C would help with that sort of thing.

 

I'm thinking for the 6502 you should be doing your C coding in a style that would normally be considered bad form otherwise - ie. lots of globals, and very few function arguments, if any.

Link to comment
Share on other sites

Given the choice of either C or assembly, I'd do a mix of both as well. Assembly for cycle-exact stuff, or where you need the tightest code, and C for long and tedious game logic. I've found off-by-one bugs in a number of commercial 6502 games, and C would help with that sort of thing.

 

I'm thinking for the 6502 you should be doing your C coding in a style that would normally be considered bad form otherwise - ie. lots of globals, and very few function arguments, if any.

 

I remember programming in Java ME for mobile phones (times when there was no Android, iOS, or Windows Phone). The computational power of the phones was very limited, so it was basically programming in Java while breaking most of the "Best Java programming practices" at the same time.

 

With CC65 and Atari, it is similar. One has to carefully check what programming constructs are too "expensive". With CC65, accessing members of structures and automatic variables is more "expensive" than one could expect. All because of the way a linkage stack must be implemented on 6502 CPU. Just observe the assembly generated by CC65 and you will see.

  • Like 2
Link to comment
Share on other sites

Btw,

 

is there any good CC65 example for a typical Atari game "software architecture"?

 

So to say:

* DL for screen / gfx mode setup

* DLI for nice colors / pmg repositioning

* VBI for music / pmg movement / joystick updates

* main game logic / loop outside of VBI

 

Especially the VBI / game logic is something I can not yet imagine how the corresponding cc65 code would look like. My typical 6502 code is almost completely hammered into the VBI part after the music update (RMT). That way things are nicely synced with the screen updates and everything looks smooth as pal/ntsc can be..

 

greetings,

twh

Link to comment
Share on other sites

Btw,

 

is there any good CC65 example for a typical Atari game "software architecture"?

 

So to say:

* DL for screen / gfx mode setup

* DLI for nice colors / pmg repositioning

* VBI for music / pmg movement / joystick updates

* main game logic / loop outside of VBI

 

Especially the VBI / game logic is something I can not yet imagine how the corresponding cc65 code would look like. My typical 6502 code is almost completely hammered into the VBI part after the music update (RMT). That way things are nicely synced with the screen updates and everything looks smooth as pal/ntsc can be..

 

greetings,

twh

The 8-bit doesn't have much in the way of APIs, so almost everything is done by setting the values in the same memory locations as you would for ASM or Basic. In C, that would just mean creating pointers to those specific memory locations. What I've seen from cc65 so far is it's named many of them for you already if you include the right headers.

I've always found the book "Mapping the Atari" essential. You can now find it online for free.

 

For VBI (and DLI) you need to know the memory address where your code resides, and that seems counter to typical C programming. I notice cc65 produces assembly language you can read, and I imaging you could get the addresses from that.

 

EDIT: now that I think about it, I think you would still want to write your VBI or DLI code in ASM because timing is critical. In C you could put it in inline ASM statements or put it in a char array (similar to how machine language is often stored in data statements in basic.

Edited by zzip
Link to comment
Share on other sites

Hi zzip,

 

you are absolutely right. setting the values in memory locations is actually all you can do in ASM :)

 

1) DLI code in ASM is ok.. everything else would be kind of strange. I agree.

2) But what about VBI code?

 

Like I said: the main logic would be placed in a typical ASM game into the VBI and just some basic stuff would be left over in the main loop.

I guess in CC65 it would be the other way around.

 

\twh

Link to comment
Share on other sites

Hi zzip,

 

you are absolutely right. setting the values in memory locations is actually all you can do in ASM :)

 

1) DLI code in ASM is ok.. everything else would be kind of strange. I agree.

2) But what about VBI code?

 

Like I said: the main logic would be placed in a typical ASM game into the VBI and just some basic stuff would be left over in the main loop.

I guess in CC65 it would be the other way around.

 

\twh

 

you could theoretically write VBI code in C, but my worry would be that the compiler would generate too much code and you'd have to hand-optimize the assembly anyway.

Link to comment
Share on other sites

So I have been working with ca65 assembler from the cc65 package as my macro assembler for the Lynx, but am starting to look at possibly changing to Macross. Now Macross was an assembler written by Lucasfilms back in the late '80s for their assembly language projects on the 6502 and 68k. It did share some structured programming constructs like you have in C (i.e. do-while, if-then-else, do-until, etc.) so it might be a good middle road for you to look at.

 

Last year they open-sourced the code to Macross so you can build it for whatever host you are working with currently. I was going to add 65c02 support to it, so I could use it on the Lynx, but it looks like someone already beat me to it.

Link to comment
Share on other sites

Btw,

 

is there any good CC65 example for a typical Atari game "software architecture"?

 

So to say:

* DL for screen / gfx mode setup

* DLI for nice colors / pmg repositioning

* VBI for music / pmg movement / joystick updates

* main game logic / loop outside of VBI

 

Especially the VBI / game logic is something I can not yet imagine how the corresponding cc65 code would look like. My typical 6502 code is almost completely hammered into the VBI part after the music update (RMT). That way things are nicely synced with the screen updates and everything looks smooth as pal/ntsc can be..

 

greetings,

twh

 

You can try to minimize the VBI code, be keeping the most part of the logic in the mainline code. Something like the following. Joystick input is handled in the mainline, but the movement is still smooth.

 

Mainline:

if (ship_movement_dirty == 0) {

if (PEEK(STICK0)==STICK_LEFT) {

ship_xpos++;

ship_movement_dirty=255;

}

}

 

VBI:

 

LDY _ship_movement_dirty ;Ship to be moved?

BNE PM ;No, skip

LDA _ship_xpos ;Get intended position

STA HPOSP0 ;Set GTIA P0 xpos

INY ;Clear dirty flag

STA _ship_movement_dirty ;Store the dirty flag

PM: ...

Edited by baktra
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...