|
Post by spiff on Mar 10, 2008 16:53:44 GMT -5
Hello All,
I'm working on fixing another game for the DTV. This one is Up'n'Down. It turns out this game uses the TOD to measure the time spent on each level. Of course running this on the DTV (or in VicePlus) does not produce the desired result. Actually the only thing that happens is that you are never awarded a bonus for fast completion of a level.
But I want to fix it, so I think I need to look into switching the application from the TOD timer to one of the regular timers.
Does anyone have some thoughts about the easiest way to accomplish this?
What I was thinking was setting up one of the timers to generate interrupts on a 1-sec basis, then making the interrupt-handler filter out those interrupts and increment a counter. The way the TOD-timer is used in this game is that 0:00 is written to it when starting the game, and whenever you die, the values are copied to RAM. When starting again (next life) they are written back to the TOD timer. And finally, when the level is completed, the total time is read from the TOD-timer. Looks pretty simple, although having a working TOD-timer would of course be easier than having to implement the counting myself in software.
|
|
|
Post by 1570 on Mar 11, 2008 4:45:51 GMT -5
What about using a raster IRQ for this? This might work with other games that possibly use all CIA timers by default, too. Just increment some counter, if == 5 increment "tenths of second" counter.
If you write the TOD replacement code so that you can substitute LDA $DC09 by something like JSR ReadDC09 reusing this for other games should be simple. TOD IRQs are a headache though...
|
|
|
Post by spiff on Mar 11, 2008 8:45:23 GMT -5
What about using a raster IRQ for this? This might work with other games that possibly use all CIA timers by default, too. Just increment some counter, if == 5 increment "tenths of second" counter. If you write the TOD replacement code so that you can substitute LDA $DC09 by something like JSR ReadDC09 reusing this for other games should be simple. TOD IRQs are a headache though... Yes, this is possible AFAIK. Up'n'Down uses no interrupts on the TOD, only writes a value to the first TOD, and reads back from it. Also the tenths are not used, only the full second count (and minutes).
|
|
|
Post by spiff on Mar 15, 2008 20:04:34 GMT -5
I have been playing a bit with this. Still have some problems with the timer not being correct, but it mostly works. Regarding the possibility of using raster or timer interrupts, I think the difference is minimal: The interrupt handler could easily be the same, and it is just a matter of getting the other parts right. What is a bit annoying with this game is that it uses two different interrupts (both scan-line I think), but it actually changes the vector at $0314 back and forth all the time, instead of having a single ISR, that branches to the different handlers. This means I have more difficulty patching into the vector.
Playing with the timer, I have also found out that you cannot get the maximum bonus (for less than 30 seconds) when playing on a PAL machine. I have always played on a PAL machine, but this time I managed to get it perfect, and it is still 34 seconds for the first level. Switching Vice to run NTSC I was able to complete level 1 in 29 seconds. Now, the big question is: should I try to fix this as well?
Another funny thing: When playing on PAL, the speed of the music is slower during the game, but runs twice as fast in the menu, and during bonus etc. Looks like this game was never released in a version for PAL, and the timing was made in a lousy way.
|
|
|
Post by 1570 on Aug 31, 2008 6:52:44 GMT -5
Any news? I just looked at Raid over Moscov; that game also uses TOD timers and does not run on the DTV properly, so the TOD "emulation" code would be handy.
|
|
|
Post by spiff on Sept 1, 2008 2:44:54 GMT -5
Any news? I just looked at Raid over Moscov; that game also uses TOD timers and does not run on the DTV properly, so the TOD "emulation" code would be handy. I never got around to debugging the timing code. Perhaps all that is needed is some extra disabling of interrupts when reading the timer, to avoid concurrency problems. If I remember correctly, the timer seems to work fine in 4 out of 5 plays. In the remaining cases the time returned is way of. Also, the time seems to be a few seconds of compared to the TOD timer in Vice. I have a hard time figuring out whether a particular interrupt should be used for my TOD timer or not. Of course there is also the possibility of a "real" bug, honestly I think the problem is related to missing interrupts. I guess one possibility is that the first raster interrupt does not complete before the second one should trigger. This would lead to delaying this interrupt until the next frame. This could also explain why the game runs slower in PAL-mode. If you want, I can share the code I currently have. Would be nice to test it in a different environment (i.e. one where it is easier to figure out how often interrupts are generated).
|
|
|
Post by 1570 on Sept 1, 2008 11:23:24 GMT -5
In the original TOD, registers freeze if you read hours (register 11) until 10ths (register 8) are read. This is probably a bit nasty to implement properly (as in the original the actual timer continues to run while the visible registers are freezed) but simply freezing the TOD completely until register 8 is read is probably okay, too. Same happens when writing to TOD; it stops on write to reg 11 until reg 8 is written.
Perhaps this is the problem in Up'n'Down?
|
|
|
Post by spiff on Sept 2, 2008 9:30:22 GMT -5
Perhaps this is the problem in Up'n'Down? I remember reading this, but I found out that up'n'down never reads the hours register. It only uses seconds and minutes. I would think this could lead to a race condition where reading the timer while it is running could return the wrong value. But then the time is only used for bonus, and for >=60s there is no bonus.
|
|