Jump to content
IGNORED

Ramless Pong - 1K Project


Recommended Posts

You need to be some sort of masochist to code for the VCS, because the system is so limiting. One of its most well-known limitations is the mere 128 bytes of RAM on board. Programmers have spent ages seeing what is possible using these 1024 bits of information.

So, I thought, why not limit myself to the extreme? I challenged myself to make a complete game using absolutely NONE of the on-board RAM.

And I did it! It took a lot longer to actually finish than I had anticipated, but I have a fully-functional 2-player pong clone using none of the RAM, namely without addressing anything within $80-$FF or any of its mirrors, neither reading nor writing. This should work perfectly on a system with the RAM disabled or otherwise re-routed.

 

Since I am not using RAM, I am only using the CPU registers for storing information. I can only use X and the stack pointer for storage, though, while A and Y take on more temporary roles. I used T1024T and INTIM to temporarily store data while swapping X with the SP, which is neccessary twice per frame.

The SP normally holds the scores (both values from 0-10) encrypted into 7 bits, with the high bit controlling the vertical speed of the ball. The X register normally holds the vertical position of the ball (0-95), with the high bit controlling the vertical direction of the ball. X is also used to trigger "score mode", where a sound is played for about half a second before switching to "serve mode". These are simply special X values that cannot occur during a rally.

The Interrupt flag is used to control the horizontal direction of the ball. Since there is no way to test the value of this flag, I am using the stack to push the CPU state to NUSIZ0. GRP0 is used for the score graphics, and since it never moves, I can use a simple collision detection against the playfield to determine what the Interrupt flag is.

The ball's horizontal position is not stored, as it is moved with HMOVE. All other game mechanics are done with either checking the bounds of the data, or checking collisions between objects. If you disable different graphics objects, strange things will happen!

In attract mode, the screen color cycles, and if you have the BW/COLOR switch set to COLOR, it keeps the color on game reset, otherwise it resets to black and white.

 

This also just happens to fit within 1K of space. I could probably squeeze a few more bytes out to maybe add changeable paddle sizes using the difficulty switches, but I like it as it is.

ramless_pong.bin

ramless_pong.asm

  • Like 18
Link to comment
Share on other sites

Thanks guys! I was hoping the game would be under 512 bytes, but it would have to be drastically stripped down. Doing simple things without RAM takes a lot more ROM...

I would like to do a 128-byte RAM game someday. Probably as a 256-byte cart that does initialization, pushes the code to RAM, and jumps into it.

 

The inspiration for the gameplay was taken from this video:

  • Like 1
Link to comment
Share on other sites

Awesome program Jeremiah! :)

 

This is really interesting - you are indeed not using any of the 128 bytes, but the registers T1024T and INTIM could count as register RAM; the Fairchild Channel F has 64 bytes of register RAM used like the direct page on the VCS.

 

I think the hardware acceleration makes this code possible since the TIA can transparently access additional RAM; here there is another parallel with the Fairchild Channel F having 2K of video RAM and no way to read it back but with the VCS this is not so; our 20 bits of playfield video RAM and 19 bits of sprites are write only but the bits can be read back by other registers and calculated anywhere within a 40*n scanline matrix for the playfield or a 160*n matrix for the bit sprites.

 

  • Like 2
Link to comment
Share on other sites

Just wondering, are there any officially-released games that don't use RAM? Because they would make good troubleshooting tools for the typical black screen issues by ruling out at least one chip.

 

Not that I know of, but I had wondered that as well.

I know there was a color-test cart made that I thought simply rendered a typical test screen. After looking up the video, though, it looks a bit more complex than that.

 

WARNING: Mute the sound!

Edited by JeremiahK
Link to comment
Share on other sites

Neat! I've too made ramless programs, but never thought about making a game before. Pong is good choice for that.

 

I remember at least one discussion that was had about methods of extra storage. This post captures most of that.

 

Has anyone suggested using bankswitching as memory? If you had 8 banks, that would provide 3 bits of state. Each bank would have mostly duplicate code, but coded with an identifier between 0 and 7. Storing the value of 5 would be done by jumping to bank 5.

  • Like 1
Link to comment
Share on other sites

Neat! I've too made ramless programs, but never thought about making a game before. Pong is good choice for that.

 

I remember at least one discussion that was had about methods of extra storage. This post captures most of that.

I believe that post was the original inspiration for me, then one day in the shower I figured out how to put it all together, haha.

 

 

 

Has anyone suggested using bankswitching as memory? If you had 8 banks, that would provide 3 bits of state. Each bank would have mostly duplicate code, but coded with an identifier between 0 and 7. Storing the value of 5 would be done by jumping to bank 5.

That would be interesting, although it would require a bit of ROM.

Link to comment
Share on other sites

  • 1 month later...
On 6/5/2019 at 5:15 PM, JeremiahK said:

 

Not that I know of, but I had wondered that as well.

I know there was a color-test cart made that I thought simply rendered a typical test screen. After looking up the video, though, it looks a bit more complex than that.

 

WARNING: Mute the sound!

 

Do you have a link to this rom?  I'm trying to get my TV squared away and I was looking for something like this, but I couldn't find it.

Link to comment
Share on other sites

  • 10 months later...
On 5/30/2020 at 7:12 AM, Hai Nguyen said:

Out of curiousity, anyone know what 128 Bytes in Atari game consist of? I am trying to use RAM to train an agent to play the game so some clues might help.

 

Hai.

 

I believe this question has been asked before.

The 128 bytes "consists of" whatever the programmer decides. It is different for every game.

 

Link to comment
Share on other sites

On 6/1/2019 at 9:53 PM, JeremiahK said:

You need to be some sort of masochist to code for the VCS, because the system is so limiting. One of its most well-known limitations is the mere 128 bytes of RAM on board. Programmers have spent ages seeing what is possible using these 1024 bits of information.

So, I thought, why not limit myself to the extreme? I challenged myself to make a complete game using absolutely NONE of the on-board RAM.

And I did it! It took a lot longer to actually finish than I had anticipated, but I have a fully-functional 2-player pong clone using none of the RAM, namely without addressing anything within $80-$FF or any of its mirrors, neither reading nor writing. This should work perfectly on a system with the RAM disabled or otherwise re-routed.

 

Since I am not using RAM, I am only using the CPU registers for storing information. I can only use X and the stack pointer for storage, though, while A and Y take on more temporary roles. I used T1024T and INTIM to temporarily store data while swapping X with the SP, which is neccessary twice per frame.

The SP normally holds the scores (both values from 0-10) encrypted into 7 bits, with the high bit controlling the vertical speed of the ball. The X register normally holds the vertical position of the ball (0-95), with the high bit controlling the vertical direction of the ball. X is also used to trigger "score mode", where a sound is played for about half a second before switching to "serve mode". These are simply special X values that cannot occur during a rally.

The Interrupt flag is used to control the horizontal direction of the ball. Since there is no way to test the value of this flag, I am using the stack to push the CPU state to NUSIZ0. GRP0 is used for the score graphics, and since it never moves, I can use a simple collision detection against the playfield to determine what the Interrupt flag is.

The ball's horizontal position is not stored, as it is moved with HMOVE. All other game mechanics are done with either checking the bounds of the data, or checking collisions between objects. If you disable different graphics objects, strange things will happen!

In attract mode, the screen color cycles, and if you have the BW/COLOR switch set to COLOR, it keeps the color on game reset, otherwise it resets to black and white.

 

This also just happens to fit within 1K of space. I could probably squeeze a few more bytes out to maybe add changeable paddle sizes using the difficulty switches, but I like it as it is.

ramless_pong.bin 1 kB · 265 downloads

ramless_pong.asm 11.06 kB · 149 downloads

 

 

Exploding-Head.jpg

Edited by Halycon275
  • Like 1
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...