Jump to content
IGNORED

My first test... on the TMS9918


F-Cycles

Recommended Posts

I was waiting for a ColecoVision hardware for few weeks, but strangely I got 2 hardware last week. First, a ColecoVision (last Saturday) was let to me in order to experiment and test my stuff. Then, at work.. I was asked to do something on a new piece of hardware which will be considered the 8th generation of video game console. It's a strange feeling to have to discover things on nearly the two extremes of gaming console within a week. ^_^

 

In the picture below, you will see 3 of the 4 software I wrote which run on the real hardware (NTSC) and BlueMSX emulator. The 4th one is a simulated extended color for later study.

 

post-36389-0-28025400-1378163170_thumb.jpg

 

So far, there seem to be a wrong timing in BlueMSX. I believe the emulator is coded with 60 FPS instead of 60/1.001 = 59.94... FPS. Which cause different synchronization behavior between the software simulation and hardware. But I have not made test to confirm this just notice that the timing is different. I did wrote an email on their forum.. but no reply yet.

 

 

  • Like 5
Link to comment
Share on other sites

48 sprites on one screen! Incredible! I think the Collusion and the 5th Sprite flag video register won't work with sprites above 32 since it is only 5-bit. Not really a necessary feature and can use box collusion and sprite flickering routine get around the flags. Also the multicolor extended mode is cool.

Link to comment
Share on other sites

48 sprites on one screen! Incredible! I think the Collusion and the 5th Sprite flag video register won't work with sprites above 32 since it is only 5-bit.

In fact, by reading these information before doing the transition of the first 16 sprites to the last one (while keeping the 16 sprites in middle intact), the information of the 48 sprites could be kept.

 

For the multicolor extended mode, as you can see I did not bother to create a software to convert existing image, so I just write a routine to have different color patterns which I could check visually to ensure that I display what I expect. This multicolor mode is using only768 bytes for names and 4 x 1536 bytes for colors. So a total of 6912 bytes. But because of the alignment of memory, 4x2Kb + 1Kb = 9 Kb. I was thinking to explore a way to store 2 images and make them flicker in that mode which take less memory than vmode 2. Also, sprites could be use in overlay to improve some part of the image. Well, as you can see more work could be done but probably something interesting could appear all of that work.

 

As for more than 4 sprites per line... I think this cannot be done because the information of the 4 sprites to display are copied from the VRAM to internal register and then use during the drawing of a line. I try to work with the X position of 1 sprite, hoping to see a copy of it further on the same line... tried on the real hardware and each pictures I took with my camera show only 16 lines on screen (while if I would have 17 or more, that would have reveal that the hardware did update it's x position during a scanline).

Link to comment
Share on other sites

  • 4 weeks later...
  • 4 weeks later...

I mentioned this possibility months ago on an adam chat. I seen the same technique done with a tandy 1000. Which has similar specs, 16 colours 320 x 200 res and using 2 images flipping back and forth to mix the colours. He came up with an 84 colour pallete I believe. Look real good. I though this might work as well here and a coleco. I was curious if the flipping between 2 images would be fast enough to fool the eye on a colecovision.

Link to comment
Share on other sites

you can have 105 colors on colecovisionand msx using this kind of technics.

 

If you search the forum , you can also find a demo rom done by newcoleco that display a very nice picture of the earth in 105 colors.

Did you mean techniques?

 

The same thing has been done on the Tandy Color Computer and Sinclair Spectrum with pretty good results.

The demo I saw on the CoCo3 looked a lot like the Amiga's 4096 color HAM mode... but then the CoCo3 has a 64 color palette to begin with.

 

Edited by JamesD
Link to comment
Share on other sites

  • 2 months later...

Hi, i am from the TI-99/4a community, our computer also uses the TMS9918(a) as VDP. Your tests look very promising. I wasn't quite able to follow/see, how you achieve more than 16 colors.

Are you using some some special video hardware, or is the Atarimax Ultimate SD cartridge solely used as ROM storage here to execute your prog?

If you do it in software: Are you flipping two color tables in VRam for every frame update? Or are you changing the color table somehow while the frame is drawn?
The download package only contains png and text files in the _Colors Folder, so I wasn't able to verify or understand the test.

I need to study the 48 sprite example.

Link to comment
Share on other sites

Hi, i am from the TI-99/4a community, our computer also uses the TMS9918(a) as VDP. Your tests look very promising. I wasn't quite able to follow/see, how you achieve more than 16 colors.

Are you using some some special video hardware, or is the Atarimax Ultimate SD cartridge solely used as ROM storage here to execute your prog?

 

If you do it in software: Are you flipping two color tables in VRam for every frame update? Or are you changing the color table somehow while the frame is drawn?

The download package only contains png and text files in the _Colors Folder, so I wasn't able to verify or understand the test.

 

I need to study the 48 sprite example.

 

Hi kl99,

 

Currently, the extended colors are simulation with 2 combined colors out of the 15 available. I have not program anything yet on the Coleco for that test but the best render would probably consist of drawing a pattern of color 1 & color 2 where each adjacent pixel is the other color. Have these two color swap at each frame and check it on a CRT.

 

This trick can work with the vertical interrupt, unlike the other stuff I code which need to be in sync with each scan line. I tested the other first in order to verify when the video chip is reading the VRAM and that there are no shadow registers. :) The hardware I have show that no... the registers are not shadowed and that a bit change on them will have immediate effect on the circuit.

Link to comment
Share on other sites

Hi F-Cycles

Greetings for your findings! How do you get 48 sprites ? I code on msx, so I've not clear what the colecovision HW can offer.

 

Usually on msx this is done by having an interrupt in the middle of the screen that changes the sprite allocation table, so the VDP starts again to plot extra sprites.

 

The fact is that you need a line interrupt or you will end to poll the vblank bit in the status register and to count the raster lines with cycle accurate delays, and this makes the technique barely usable is not in demos.

 

PS

I think you could interested in the fact that the TMS 9918 supports in graphic mode two screen pages that can be used for double buffering

The restriction is that you can use only the lower two 3dr's of the screen and the 512 tiles share the same color table.

 

Each page needs 2K+2K for patters +2K for colors = 6K, so both pages need 12K

 

Try this on bluemsx to see how it looks like

https://sites.google.com/site/testmsx/Home/double-buffer-in-screen-2-on-msx/URIDx2.rom?attredirects=0&d=1

Edited by artrag
Link to comment
Share on other sites

So the 9928a VDP is similar to the one in the original MSX as I understand it. So that means there is a frame interrupt that can be turned on, but there is no scan line interrupt available. So the only option for doing multiple sprites is to either switch sprite tables at the end of the frame, or have an idle loop that delays until it is time, and have the CPU switch the sprite table. As you observed it isn't that reliable, as there can be various things that can delay the timing.

 

Ages ago (maybe 1987) I did the rainbow edge demo, where you change the background colour every few scanlines. And I found when I ran it on the Coleco Adam, the AdamNET devices which do NMIs can affect the timing. Also the roller controller/super action controller/turbo steering wheel spinner interrupt of course takes CPU cycles to service. If you are on a ColecoVision without those things, most likely it would be consistent from frame to frame.

 

Unless there is something I missed, I think that is the only way to get 48 sprites.

Edited by hardhat
Link to comment
Share on other sites

Hi F-Cycles

Greetings for your findings! How do you get 48 sprites ?

 

PS

I think you could interested in the fact that the TMS 9918 supports in graphic mode two screen pages that can be used for double buffering

The restriction is that you can use only the lower two 3dr's of the screen and the 512 tiles share the same color table.

 

Each page needs 2K+2K for patters +2K for colors = 6K, so both pages need 12K

 

The Coleco has no interrupt setup elsewhere than at the bottom of the display area. For this test, I setup a delay to reach the area where the sprites 17 to 32 are display and change the sprite attribute address. (see my reply below to hardhat for more info. :) ).

 

About the two screen pages in graphic mode 2. Hum, I did a test with graphic mode 2. At first I got hard time to setup the screen. I am not sure anymore if I have test more than one screen page, but I count on it for what I want to do... Now that you are telling me that, I should double check my stuff when I have time.

 

 

Ages ago (maybe 1987) I did the rainbow edge demo, where you change the background colour every few scanlines. And I found when I ran it on the Coleco Adam, the AdamNET devices which do NMIs can affect the timing. Also the roller controller/super action controller/turbo steering wheel spinner interrupt of course takes CPU cycles to service. If you are on a ColecoVision without those things, most likely it would be consistent from frame to frame.

 

Unless there is something I missed, I think that is the only way to get 48 sprites.

 

Yes... hardhat that's how I do it in my test. Ahh.. interesting to know that some controller trigger additional interrupt which cause unpredictable delay to be introduce. I thought that I could measure the time I spend in my code... can does interrupt caused by other type of controller be handle in software (like can we have it call our code or it's fix to some address in the ROM of the machine?).

 

For the 48 sprites, there is a big gap of 64 scanlines so it might be manageable to have it while having those interrupt. If you use 8x8 sprites, you can go for a 96 sprites, but then you need to change things every 32 scan line.

Link to comment
Share on other sites

So I see that I misspoke a little. The AdamNET actually does DMA, which causes wait states on the z80 CPU while the DMA is happening. So if there are more active AdamNET devices, there will be more wait state cycles that delay the CPU in ways that aren't as predictable as you might like. While playing a cartridge game, most of the RAM that the AdamNET controller is accessing is not visible and should cause minimal side effects on timing loops.

 

The spinner is on the maskable interrupt in interrupt mode 1, which uses the RST 38h vector. That vector is forwarded to the cartridge ROM, without doing any handling in the OS7 ROM.

Link to comment
Share on other sites

A side note about the 48 sprites.

On msx1 the sole interrupt is at vertical blank as well, so if you want to swap the sprite allocation tables (SATs) in the middle of the screen you need to wait the right scan line with some delay system.

A good solution for this problem is to place two colliding sprites (eventually transparent) on the line where the SATs have to swap and poll the status register on the collision bit.

This guaranties you to swapp at the exact line.

The back off is that if sprites collide in the upper side of the screen you get a false line interrupt...

Another solution is to place 5 transparent sprites at the line you like and poll for the 5h sprite flag

Also this solution guaranties you to swap at the exact line, but wastes 5 SAT positions

On the other side, this time if in the upper part of the screen there is a genuine 5h sprite condition you can "filter" it testing the number of sprite plane. As you know witch planes are used as placeholder you can distinguish between genuine 5h sprite situations and line where you need to swap the SAT's
My two cents
Edited by artrag
  • Like 1
Link to comment
Share on other sites

 

A good solution for this problem is to place two colliding sprites (eventually transparent) on the line where the SATs have to swap and poll the status register on the collision bit.

This guaranties you to swapp at the exact line.

The back off is that if sprites collide in the upper side of the screen you get a false line interrupt...

Another solution is to place 5 transparent sprites at the line you like and poll for the 5h sprite flag

Also this solution guaranties you to swap at the exact line, but wastes 5 SAT positions

On the other side, this time if in the upper part of the screen there is a genuine 5h sprite condition you can "filter" it testing the number of sprite plane. As you know witch planes are used as placeholder you can distinguish between genuine 5h sprite situations and line where you need to swap the SAT's
My two cents

 

 

 

This idea of querying the 5th sprite flag is very interesting. I guess we can even determine the exact scanline by doing a binary search on screen (as long we make sure we are in the visible area).

 

 

The first idea I was having...

 

One article I read about security was mentioning that time spent in a function to decrypt could be use to analyze which path of the code was used. According to the article, that was a security failure in an early version of Internet Explorer. And that today, writing code to decrypt or encrypt something also involve to make sure that any path of the code give the exact same CPU cycles.

 

That could also be a way to solve it... if the main loop of a game is coded in order to always produce the same number of clock cycle for each function (like: play_music, update_screen, update_ai, ...). Then, you can divide the screen based on each function.

 

The additional delay in the CPU introduced by other components could not be control, but if the resulting jitter is inside the tolerance, we can still cope with that.

 

One other feature that can be done when you have precise control over what happen on screen. The music will sound better as the update will be periodic. We can also start to call update_music a few time per interrupt and start modifying the audio structure instead of being modifying the rhythm structure. (interesting video about it: http://www.youtube.com/watch?v=aEjcK5JFEFE)!

 

 

For me, all ideas are interesting and depending of what we need to do, one method will be more suitable than another one else. :)

I will try to keep in mind this 5-th bit... and collision bit.

Link to comment
Share on other sites

As the 5th sprite plane is reported by the status register, and you know in advance which placeholder sprite is the 5th, you can discriminate between actual 5th sprites and you placeholders on the screen split line by simply reading the lower 5 bits of the status register. No need of doing binary search.

The idea is that once you get the vblank interrupt, you execute your interrupt service routine (ISR) with your useful code (music, game engine, whatever you like) provided that the time lenght of your useful tasks is limited to about half screen (or to the approximate position of the raster where you want to do the SAT swap).

 

You do not need to do cycle accurate code, but only consider the worst case with respect to the raster position in the active area while the ISR is served.

The useful code has to finish before the reaster has reached the line where placeholders sprites are.

 

Than you start polling the status register waiting for 5th sprite or collision, do your trick on SAT, and return executing useful code or terminate the interrupt service routine giving control to the main loop

 

IMHO it is by far simpler, more accurate and reliable than computing cycles...

 

Actually If you are able - with you code - to discriminate in few raster lines (but here you need cycle accurate code) if the sprite collision reported by the status register concerns useful sprites or not, you could even try to use two colliding transparent sprites as paceholders, and poll the collision flag for finding the right raster line where to split the screen.

 

In this case, if the collision concerns useful sprites, you store the info about the "real collision" for later use, otherwise you swap the SAT.

The difference with the 5th sprite solution, is that the split will fall few lines later as discriminating among sprites for collision check takes more time.

 

But as you said it depends on what you want to do, usually the cost of doing a large section of cycle accurate code is by far bigger than wasting 5 sprite planes instead of 2.

Edited by artrag
  • Like 1
Link to comment
Share on other sites

  • 2 months later...
  • 3 months later...

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