Jump to content
IGNORED

SpinBall


Nicam_Shilova

Recommended Posts

Development started five years ago and recently I decided to resume the programming of this Jezzball clone.

Honestly, in advanced levels, this game drive Colecovision into a corner however, it still playable.

 

Have fun.

 

Another news : Burning Disc is not dead: since these years I continued to programming this Windjammers clones and recently I added majors features. Burning Disc was a codename and the final name of this game is: Wind Edge.

I plan to post in the near future a gameplay video which include sounds.SpinBall.rar

SpinBall.rar

  • Like 4
Link to comment
Share on other sites

13 hours ago, Nicam_Shilova said:

Development started five years ago and recently I decided to resume the programming of this Jezzball clone.

Honestly, in advanced levels, this game drive Colecovision into a corner however, it still playable.

 

Have fun.

 

Another news : Burning Disc is not dead: since these years I continued to programming this Windjammers clones and recently I added majors features. Burning Disc was a codename and the final name of this game is: Wind Edge.

I plan to post in the near future a gameplay video which include sounds.SpinBall.rar

SpinBall.rar 6.7 kB · 18 downloads

Thank you for the free ROM.  

 

Just one quick question.   What are the system requirements?    I can't seem to get the ROM to work on my Adam

 

 

Link to comment
Share on other sites

47 minutes ago, Ikrananka said:

Fun game, but still quite buggy.  I got to Level 5 when this happened.  The balls are still moving around as if the walls that were there before are still there.

The joy of VRAM corruption.  The game gets laggy at level 3 with 4 balls. Then half speed at level 4 and does that or write into the color portion of VRAM disabling the balls.  When this system is at half the speed than the normal speed, more likely these glitches will show up.  Knightmare for example, stack overflow happened, thus resetting the game.

Only writes I can see on screen is the time and your player position.  I'm not sure if it is writing something else like the score, lives, or the entire name table every frame.  I suggest only update the name table what it needs on screen right after delay(1); or whenever the finish drawing screen flag is raised. So it's not writing something right before or running into NMI task. 

One way to minimize VRAM corruption is either split up the tasks to run at a frame like update timer would run at frame==1 update player can update at frame==2.  The other way do 2 delay(1); loop.  Challenger one of my game uses 3 delay(1); loop due to the amount of collision detection it required to compare 6 shots vs 16 objects.  I tried 6 shots vs 23 objects, didn't work so well and it was glitchy.  Vanguard is at 2 delay(1); One focus on drawing on the 2nd unseen screen(which is split up to draw 1/3 of it a frame), the 2nd runs the enemy routines etc.  If 2nd delay overruns, then 1st delay play catch up since requires less tasks before it hit NMI.

EDIT: Think the VDP starts to ignore commands if it receives too many request from the CPU.

Edited by Kiwi
Link to comment
Share on other sites

3 minutes ago, Kiwi said:

The joy of VRAM corruption.  The game gets laggy at level 3 with 4 balls. Then half speed at level 4 and does that or write into the color portion of VRAM disabling the balls.  When this system is at half the speed than the normal speed, more likely these glitches will show up.  Knightmare for example, stack overflow happened, thus resetting the game.

Only writes I can see on screen is the time and your player position.  I'm not sure if it is writing something else like the score, lives, or the entire name table every frame.  I suggest only update the name table what it needs on screen right after delay(1); or whenever the finish drawing screen flag is raised. So it's not writing something right before or running into NMI task. 

One way to minimize VRAM corruption is either split up the tasks to run at a frame like update timer would run at frame==1 update player can update at frame==2.  The other way do 2 delay(1); loop.  Challenger one of my game uses 3 delay(1); loop due to the amount of collision detection it required to compare 6 shots vs 16 objects.  I tried 6 shots vs 23 objects, didn't work so well and it was glitchy.  Vanguard is at 2 delay(1); One focus on drawing on the 2nd unseen screen(which is split up to draw 1/3 of it a frame), the 2nd runs the enemy routines etc.  If 2nd delay overruns, then 1st delay play catch up since requires less tasks before it hit NMI.

EDIT: Think the VDP starts to ignore commands if it receives too many request from the CPU.

 

I suspected this corruption because I detected it in a previous version when code inclued an complicated method which manipulate VRAM. I'd better to check it.

Link to comment
Share on other sites

Inadvertent VRAM corruption on the Coleco is caused by two things (assuming it's not actually a real bug in the original code):

 

- writing to the VDP too quickly. The CPU is faster than the VDP and reading or writing bytes during the active display portion without a delay between them will cause the VDP to randomly drop some of them. (It's not really random, but from the CPU's point of view you can't really predict it). It is okay to go full speed (I believe) during vblank or when the display blank bit is set. In addition, it appears it's okay (?) to set the registers without a delay between the two writes, but there MUST be a delay after setting a read address before reading. I haven't tested between setting a write address and the first write.

 

- having a VDP read or write interrupted by the NMI. Most NMI handlers in most people's games at least clear the VDP interrupt by reading the VDP status register. This has the side effect of changing the internal VDP address. When the NMI returns, the caller doesn't know that an NMI occurred, and continues to process at the newly corrupted address. This is the most insidious one because unless the software is very aware of the VDP frame state, it can appear to happen at random, and to go away and come back every time you change any little thing in your code. There are a number of ways to deal with it:

1 - wait for the NMI to finish and do all your VDP access immediately afterwards. You'll have to take into account how much time the NMI itself needs to finish to know how long you have.

2 - do all your VDP access /inside/ the NMI (before clearing the status register, it can't trigger again)

3 - disable the VDP interrupt in the VDP itself (note you need to use one of the previous methods to time your configuration of the register, else THAT can also be interrupted randomly). You'll have to poll the status register for end of frame, though, and there are hardware race conditions with doing so, so not recommended.

4 - do /NO/ VDP access inside the NMI, including clearing the status register. Rather, just set a flag and let the main code loop deal with it.

 

The safest options are 2 and 4, there is NO WAY for the NMI to break your access with those methods. It just takes a little planning to make it work. 

 

 

  • Like 1
Link to comment
Share on other sites

5 minutes ago, Tursi said:

having a VDP read or write interrupted by the NMI. Most NMI handlers in most people's games at least clear the VDP interrupt by reading the VDP status register. This has the side effect of changing the internal VDP address. When the NMI returns, the caller doesn't know that an NMI occurred, and continues to process at the newly corrupted address.

My assumption is correct.  I had the thought that the address have been altered because it would write somewhere else in VRAM either on screen or part of the pattern/color/sprite/attribute table.

I used a visual aid to see where the beam is at by using, paper(15);delay(1);(paper(12); to show me how much cpu time I have left between paper(15) to delay(1).  If the border's flashing meaning that the task done in a frame haven't finish before the screen finished drawing.

Link to comment
Share on other sites

22 hours ago, Kiwi said:

I used a visual aid to see where the beam is at by using, paper(15);delay(1);(paper(12); to show me how much cpu time I have left between paper(15) to delay(1).  If the border's flashing meaning that the task done in a frame haven't finish before the screen finished drawing.

It's a good technique - but go one further! Set the background color at every major part of your code. That way, you can use the border color bars to see how much (relative) time each part of your code takes. As long as you are basing your timing off the blank, of course, then you can lose the delay.

 

I also have to correct myself, it's an error I make often. Reading the status register doesn't corrupt the active VDP address, but it does reset the byte flipflop - meaning that if an NMI causes a status register read while writing a register or setting a new address, THEN the address will be corrupted. (Also, most probably know this, but setting a register changes the address too ;) ). I stand by my recommendation of safe practices though.

 

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