Frame timing 2

Technical discussion for those interested in Supermodel development and Model 3 reverse engineering. Prospective contributors welcome.
Forum rules
Keep it classy!

  • No ROM requests or links.
  • Do not ask to be a play tester.
  • Do not ask about release dates.
  • No drama!

Re: Frame timing 2

Postby Ian » Wed Oct 19, 2016 5:08 am

I did some more debugging today with a bunch of step 1 and 1.5 games

If I was to guess, I'd say that status register read might actually be the swap buffer command. It seems to get called exactly once per frame, normally after all the data has been sent to the GPU for that frame. (Either that or its at the start which seems unlikely.)

Games also seem to sync with it at the very beginning. Ie they will flood read the register until it returns 0, and then continue rendering normally. This seems to be the only time we ever return 0 for the register read.

Here is a quick log from scud

Code: Select all
WritePolygonRAM
WriteHighCullingRAM
flush
swapbuffers
status 2
WritePolygonRAM
WriteHighCullingRAM
swapbuffers
flush
status 2
WritePolygonRAM
WriteHighCullingRAM
flush
swapbuffers
status 2
WritePolygonRAM
WriteHighCullingRAM
flush
swapbuffers
status 2
WritePolygonRAM
swapbuffers
WriteHighCullingRAM
flush
status 2
WritePolygonRAM
WriteHighCullingRAM
flush
create format 0 x: 384 y: 0 width: 128 height: 256
swapbuffers
status 2
WritePolygonRAM
WriteHighCullingRAM
flush
swapbuffers
status 2
WritePolygonRAM
WriteHighCullingRAM
flush
swapbuffers
status 2
WritePolygonRAM
WriteHighCullingRAM
flush
swapbuffers
status 2
WritePolygonRAM
WriteHighCullingRAM
flush
swapbuffers
status 2
WritePolygonRAM
WriteHighCullingRAM
flush
swapbuffers
status 2
WritePolygonRAM
swapbuffers
WriteHighCullingRAM
flush
status 2
swapbuffers
WritePolygonRAM
WriteHighCullingRAM
flush
status 2
swapbuffers
WritePolygonRAM
WriteHighCullingRAM
flush
status 2
WritePolygonRAM
WriteHighCullingRAM
flush
swapbuffers
status 2
WritePolygonRAM
WriteHighCullingRAM
flush
swapbuffers
status 2


Scud seems to write data as per the SDK we have. Ie poly ram -> culling ram -> flush -> swap buffers()

Sega bass fishing does the updates totally differently
ie

Code: Select all
-----> deleting 0 1536 256 128 128
WriteHighCullingRAM
flush
create format 0 x: 1536 y: 256 width: 128 height: 128
WritePolygonRAM
swapbuffers
flush
WritePolygonRAM
flush
WritePolygonRAM
flush
WritePolygonRAM
flush
WritePolygonRAM
flush
WritePolygonRAM
flush
WritePolygonRAM
flush
WriteTexturePort
flush
status 2
-----> deleting 0 1536 256 128 128
WriteHighCullingRAM
flush
WritePolygonRAM
flush
WritePolygonRAM
flush
WritePolygonRAM
flush
WritePolygonRAM
flush
WritePolygonRAM
flush
WritePolygonRAM
flush
WritePolygonRAM
flush
WriteTexturePort
create format 0 x: 1536 y: 256 width: 128 height: 128
flush
swapbuffers
status 2
-----> deleting 0 1536 256 128 128
WriteHighCullingRAM
flush
create format 0 x: 1536 y: 256 width: 128 height: 128
WritePolygonRAM
flush
WritePolygonRAM
flush
WritePolygonRAM
flush
WritePolygonRAM
flush
WritePolygonRAM
flush
WritePolygonRAM
flush
WritePolygonRAM
flush
swapbuffers
WriteTexturePort
flush
status 2
-----> deleting 0 1536 256 128 128
WriteHighCullingRAM
flush
create format 0 x: 1536 y: 256 width: 128 height: 128
WritePolygonRAM
swapbuffers
flush
WritePolygonRAM
flush
WritePolygonRAM
flush
WritePolygonRAM
flush
WritePolygonRAM
flush
WritePolygonRAM
flush
WritePolygonRAM
flush
WriteTexturePort
flush
status 2
-----> deleting 0 1536 256 128 128
WriteHighCullingRAM
flush
WritePolygonRAM
flush
WritePolygonRAM
flush
WritePolygonRAM
flush
WritePolygonRAM
flush
WritePolygonRAM
flush
WritePolygonRAM
flush
WritePolygonRAM
flush
create format 0 x: 1536 y: 256 width: 128 height: 128
swapbuffers
WriteTexturePort
flush
status 2
-----> deleting 0 1536 256 128 128
WriteHighCullingRAM
flush
WritePolygonRAM
flush
WritePolygonRAM
flush
WritePolygonRAM
flush
WritePolygonRAM
flush
WritePolygonRAM
flush
WritePolygonRAM
flush
WritePolygonRAM
flush
create format 0 x: 1536 y: 256 width: 128 height: 128
WriteTexturePort
swapbuffers
flush
status 2
-----> deleting 0 1536 256 128 128
WriteHighCullingRAM
flush
WritePolygonRAM
flush
WritePolygonRAM
flush
WritePolygonRAM
flush
WritePolygonRAM
flush
WritePolygonRAM
flush
WritePolygonRAM
flush
WritePolygonRAM
flush
WriteTexturePort
create format 0 x: 1536 y: 256 width: 128 height: 128
flush
swapbuffers
-----> deleting 0 1536 256 128 128
status 2
WriteHighCullingRAM
flush
WritePolygonRAM
flush
WritePolygonRAM
flush
WritePolygonRAM
flush
WritePolygonRAM
flush
WritePolygonRAM
flush
create format 0 x: 1536 y: 256 width: 128 height: 128
WritePolygonRAM
flush
WritePolygonRAM
flush
swapbuffers
WriteTexturePort
flush
-----> deleting 0 1536 256 128 128
status 2
WriteHighCullingRAM
create format 0 x: 1536 y: 256 width: 128 height: 128
flush
swapbuffers
WritePolygonRAM
flush
WritePolygonRAM
flush
WritePolygonRAM
flush
WritePolygonRAM
flush
WritePolygonRAM
flush
WritePolygonRAM
flush
WritePolygonRAM
flush
WriteTexturePort
flush
status 2
-----> deleting 0 1536 256 128 128
WriteHighCullingRAM
flush
WritePolygonRAM
flush
WritePolygonRAM
flush
WritePolygonRAM
flush
WritePolygonRAM
flush
WritePolygonRAM
flush
WritePolygonRAM
flush
WritePolygonRAM
flush
WriteTexturePort
create format 0 x: 1536 y: 256 width: 128 height: 128
flush
swapbuffers
-----> deleting 0 1536 256 128 128
status 2
WriteHighCullingRAM
flush
WritePolygonRAM
flush
WritePolygonRAM
flush
WritePolygonRAM
flush
WritePolygonRAM
flush
WritePolygonRAM
flush
WritePolygonRAM
flush
WritePolygonRAM
flush
WriteTexturePort
create format 0 x: 1536 y: 256 width: 128 height: 128
flush
swapbuffers
status 2
-----> deleting 0 1536 256 128 128
WriteHighCullingRAM
flush
WritePolygonRAM
flush
WritePolygonRAM
flush
WritePolygonRAM
flush
WritePolygonRAM
flush
WritePolygonRAM
flush
WritePolygonRAM
flush
WritePolygonRAM
flush


Bass fishing appears to be doing
Culling Ram -> Flush() -> PolyRam -> Flush() -> PolyRam -> Flush() -> TexturePort -> Flush() -> Swap Buffers

This is also the reason why MAME runs sega bass fishing at like 1fps, because it's drawing a frame after each flush command. But you can see the frame is only complete after it does a texture port write. But given what I know, it seems that the database must be complete enough for a frame render after a flush command.
Ian
 
Posts: 874
Joined: Tue Feb 23, 2016 9:23 am

Re: Frame timing 2

Postby Ian » Sun Oct 23, 2016 4:17 pm

Well i tried drawing on the status bit read, and it did not work. In scud it was getting called in the middle of the frame leading to tearing in the video.

I'm pretty sure the 0x88 says the database is complete and can be rendered. I think every time 0x88 is called just need to check enough time has passed to decide to draw or not.

The status bit seems to be used to sync rendering. Some of the games seem to wait for the bit to change. Hi or low doesn't seem to matter. If I was to guess maybe the status bit should be flipped every time a frame is drawn. Currently the status only changes if more than the current frame time has elapsed, then is reset on the next frame which doesn't make a lot of sense to me.
Ian
 
Posts: 874
Joined: Tue Feb 23, 2016 9:23 am

Re: Frame timing 2

Postby Ian » Fri Dec 16, 2016 6:12 pm

OVERLOAD CONTROL
The PRO-1000 supports three overload modes; frame lock mode, overload protect
mode and extended overload mode. Frame lock mode will reset and start another
update period if the processing time runs over the specified update period (16.7ms/60
Hz update or 33.3ms/30 Hz update). Any polygons that have been processed will be
loaded into the frame buffer and the picture will be incomplete. Overload protect mode
will allow another update period to finish processing. In this case, the system will
automatically drop to one-half the update rate (e.g., from 60 Hz to 30 Hz). No hysteresis
is in effect for this mode. Extended overload will drop the frame rate as far as necessary
to process all the polygons. The host computer may read these signals for
synchronization purposes.


What mode did the model3 use? Mode 1 kinda sounds like no vsync at all. Just draw every 16.7ms.

The host computer may read these signals for
synchronization purposes.


I am guessing this is where it's reading the real3d registers. The step 1-1.5 games look like they are syncing with the status register when booting. They will repeatedly read register 0 until it changes state. The actual state doesn't seem to matter. After they are done syncing they don't seem to be used again, at least for the step 1 and 1.5 games.
Ian
 
Posts: 874
Joined: Tue Feb 23, 2016 9:23 am

Re: Frame timing 2

Postby Bart » Wed Dec 21, 2016 12:55 am

This is interesting. I was going to suggest that perhaps these modes are actually implemented in software by the PowerPC program running on the Pro-1000 but then I'm not sure how a frame could be canceled after running over its allotted time (unless some register can be written to force the Real3D to abort and reset). It's hard to say how much of this functionality is implemented in the Real3D chipset itself and how much was implemented by the PowerPC firmware.
User avatar
Bart
Site Admin
 
Posts: 1838
Joined: Thu Sep 01, 2011 2:13 pm
Location: New York City

Previous

Return to The Dark Room

Who is online

Users browsing this forum: No registered users and 3 guests