Jump to content
IGNORED

Pong 256 Bytes (2600)


Wickeycolumbus

Recommended Posts

After compleating Pong 512 Bytes, I decided I would attempt to cut the ROM size in half to a measly 256 Bytes. It is not down to 256 bytes yet, but it is getting there at only 343 Bytes. Some features had to be cut to slim it down like scoring and sound. This version was tested (and works) on real hardware. Here is the latest binary/source code.

Pong256Bytes.bin

Pong256Bytes.asm.zip

Link to comment
Share on other sites

You really should give both players the ability to move. As it stands, if the first player is moving up it negates all other checks. How about...

 

;NOTE: RAM must have P0_Y immediately followed by
;P1_Y and P0_End immediately followed by P1_End.

;29 bytes...handles all movement
  lda SWCHA	  ;get both sticks
  ldx #2		 ;# players to check
.check_stick_loop:
  ldy P0_Y-1,x   ;get current Y
  lsr			;slide off up bit
  bcs .not_up	;skip if set
  iny			;...or, bump Y
.not_up:
  lsr			;slide off down bit
  bcs .not_down  ;skip if set
  dey			;...or, bump y
.not_down:
  lsr			;slide off right/left
  lsr			; (invalid movement)
  sty P0_Y-1,x   ;Store updated Y
  pha			;push sticks to stack
  tya			;do addition now...
  clc			;
  adc #24		;
  sta P0_End,x   ;...to get the ending
  pla			;get back stick value
  dex			;bump to next player
  bne .check_stick_loop

;ends w / x=0, a=0

Link to comment
Share on other sites

You really should give both players the ability to move. As it stands, if the first player is moving up it negates all other checks. How about...

 

;NOTE: RAM must have P0_Y immediately followed by
;P1_Y and P0_End immediately followed by P1_End.

;29 bytes...handles all movement
  lda SWCHA	 ;get both sticks
  ldx #2		;# players to check
.check_stick_loop:
  ldy P0_Y-1,x  ;get current Y
  lsr		;slide off up bit
  bcs .not_up;skip if set
  iny		;...or, bump Y
.not_up:
  lsr		;slide off down bit
  bcs .not_down ;skip if set
  dey		;...or, bump y
.not_down:
  lsr		;slide off right/left
  lsr		; (invalid movement)
  sty P0_Y-1,x  ;Store updated Y
  pha		;push sticks to stack
  tya		;do addition now...
  clc		;
  adc #24	;
  sta P0_End,x  ;...to get the ending
  pla		;get back stick value
  dex		;bump to next player
  bne .check_stick_loop

;ends w / x=0, a=0

 

Good Point :P Now its down to 327 bytes.

Pong256Bytes.bin

Pong256Bytes.asm_2.zip

Link to comment
Share on other sites

Don't forget to erase the ADC's up top. The additions are already done in the loop.

 

 

I suppose that it's a pipe dream to get Pong the smallest game on the console. You could do a "Simon"-ish game less space...no GFX are even needed - just flash a color that corresponds to the direction the stick needs to be moved. By setting up a pseudo-ram cache of stick values, let the game cycle through an increased number of them. If incorrect, the game flashes the correct color with a buzzer. If correct, the index is bumped and the process repeated until the entire cache is used.

 

 

A "game" of stopwatch would be smaller than that.

Link to comment
Share on other sites

Don't forget to erase the ADC's up top. The additions are already done in the loop.

 

That routine you wrote is magic :) I also saved around 6 bytes optimizing the kernel for a total of 305 Bytes.

 

I suppose that it's a pipe dream to get Pong the smallest game on the console. You could do a "Simon"-ish game less space...no GFX are even needed - just flash a color that corresponds to the direction the stick needs to be moved. By setting up a pseudo-ram cache of stick values, let the game cycle through an increased number of them. If incorrect, the game flashes the correct color with a buzzer. If correct, the index is bumped and the process repeated until the entire cache is used.

 

 

A "game" of stopwatch would be smaller than that.

 

Well its the smallest so far ;) I'll have to try a 128 byte Simon game later.

Pong256Bytes.bin

Pong256Bytes.asm_3.zip

Edited by Wickeycolumbus
Link to comment
Share on other sites

You can save two bytes by doing this:

 

	lda	#$87				 ; 2
sta	VBLANK			   ; 3
asl						 ; 2
.loopVsync:
sta	WSYNC				; 3
;-------------------------------------
sta	VSYNC				; 3
lsr						 ; 2
bne	.loopVsync		   ; 2³

 

Basically it takes the routine in Macro.h and adds a little more to it.

 

Edit: It also leaves A = 0, and you can save another byte a little later with TAY before you load the value for your timer. A little farther down from that #$80 is loaded for VBLANK, after that you can use ASL to have #$00 again instead of loading. When you're testing INPT4 I believe Y=0 at that point and you might be able to do TYA after the BMI.

 

You can a few bytes too with your jumps. When you:

 

ora #%00000010

jmp Store_LR_Status

 

I believe you can:

 

ora #%00000010

bne Store_LR_Status

 

And you should be able to save three more bytes here:

 

 

lda Ball_X

cmp #$FE ;1

bne .Check_Other_X

jmp Start_New_Round

 

.Check_Other_X

 

lda Ball_X

cmp #160 ;156

bne Done_Update_Score

 

Start_New_Round

 

 

 

By going like this:

 

lda Ball_X

cmp #$FE ;1

beq .Start_New_Round

 

Check_Other_X

 

lda Ball_X

cmp #160 ;156

bne Done_Update_Score

 

.Start_New_Round

 

 

 

 

I look forward to seeing you do this Wickey. It's cool stuff. :)

Edited by Omegamatrix
Link to comment
Share on other sites

I got it down to 259 Bytes :) Only 4 more bytes to go!

 

ora #%00000010

jmp Store_LR_Status

 

I believe you can:

 

ora #%00000010

bne Store_LR_Status

 

I cant do that anymore, because I changed the way the ball logic works (see attached source)

 

 

And you should be able to save three more bytes here:

 

 

lda Ball_X

cmp #$FE ;1

bne .Check_Other_X

jmp Start_New_Round

 

.Check_Other_X

 

lda Ball_X

cmp #160 ;156

bne Done_Update_Score

 

Start_New_Round

 

 

 

By going like this:

 

lda Ball_X

cmp #$FE ;1

beq .Start_New_Round

 

Check_Other_X

 

lda Ball_X

cmp #160 ;156

bne Done_Update_Score

 

.Start_New_Round

 

I shortened my routine down to:

 

	lda Ball_X
   bne Check_Other_X




jmp Start_New_Round

Check_Other_X

lda Ball_X
cmp #160;156
bne Done_Update_Score

 

Then yours saved me 1 byte, but I was able to shorten yours down to:

 

	lda Ball_X
cmp #$FE
beq Start_New_Round

Check_Other_X
cmp #160
bne Done_Update_Score

 

Which saved 2 more bytes :cool:

Edit: Saved 2 more bytes by cutting out the 'cmp #$FE'

 

 

I look forward to seeing you do this Wickey. It's cool stuff. :)

 

Thanks :)

Pong256Bytes.bin

Pong256Bytes.asm_5.zip

Edited by Wickeycolumbus
Link to comment
Share on other sites

I cant do that anymore, because I changed the way the ball logic works (see attached source)

 

What he meant was that you can use an unconditional branch instead of a JMP when the status register is known. After an ORA involving a non-zero value, the Z flag would be clear...so you can BNE.

 

In that source, you changed it to load a zero directly...but an unconditional branch can still be used there. Instead of BNE, use it's opposite BEQ. You just loaded a zero, so the flag is set.

Link to comment
Share on other sites

Yup...Simon is the smallest example I can think of (aside from Stopwatch which really isn't a game). No gfx needed at all. Maybe not even a display kernel...tho I dunno how real hardware would like it. Just set 1 of six background colors...4 for the directions you need to move, and 2 for a game over/game win indicator.

 

Paddles move faster now :)

Great, thanks! Now can you add an AI so I can play against the computer? :D

 

..Al

 

No :P

 

Maybe in the 512 Byte version...

 

Actually, you could if the "AI" is incredibly dim.

Link to comment
Share on other sites

Done :)

This is very cool, but...

 

You really really really need more than 1 angle for the ball.

 

Not going to be possible with only 256 bytes. There is only 1 byte free right now, and is pretty much optimized to the core. I may be able to free at most 4 more bytes.

 

Also: you shouldn't allow the 1st player to serve the ball towards the 2nd player.

Why not?

 

And the ball wraps around the screen when you miss.

 

:P

 

Not done yet!

 

This can be fixed, but requires some tinkering, and is not too much of a problem. If I have time later this week, I will fix that.

 

Thanks for the feedback :)

 

-Rick

Link to comment
Share on other sites

Also: you shouldn't allow the 1st player to serve the ball towards the 2nd player.

Why not?

It allows for cheap points. You miss a shot and, before you are able to get ready (i.e., reposition your paddle near the center) your opponent serves the ball way out of reach and gets a free score.

 

And while I'm being the resident naysayer, why not use paddles instead of joysticks? It probably wouldn't take more code.

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...