The game updates at least fourteen tiles in every vertical blanking period, requiring copying 224 bytes from ROM to CHR-RAM, which is too much for the short vertical blanking duration on NTSC consoles when doing it like the game does, with indirect reads. The ideal solution would be to do it like Battletoads: prepare the CPU $01xx area during the frame, then an unrolled loop of 224 PLA/STA $2007 during vertical blanking. This is not directly possible here, as the game heavily uses the $01xx area for other things; changing this would require a major relocation of a great number of variables, and may not be possible at all without additional WRAM. I instead modified the game to only update one fourth of all the tiles during each vertical blanking period. This causes a slight lag in the main character's animation, that I find quite tolerable, but that I would expect others to find inacceptable.
The archive includes one patch that keeps the music speed as it is, for Dendy consoles or for people who like fast music, and another one that adjusts the music speed. The adjustment method may be a bit too crude for this arpeggio-heavy music. But the sound driver's internal tempo seems to be track-specific, and my attempts to change each track's tempo resulted in the tracks going out of sync after a while, similar to what has been observed in the PAL version of Over Horizon, so I eschewed that approach.
I played the music-adjusted version for a while on my Sharp Twin Famicom AN-505BK with an Everdrive N8 and did not notice any other glitches.
- (521 Bytes) Downloaded 338 times
If you do have the 224 bytes necessary to buffer the tiles available anywhere in RAM, you could consider storing the tiles in interleaved form (i.e. structure of arrays, rather than array of structures), and indexing them by tile rather than by byte. Something like this:
Code: Select all
TileByte0 = $0500 ;buffer starts at $0500 TileByte1 = TileByte0+14 TileByte2 = TileByte1+14 ;(...) TileByte14 = TileByte13+14 TileByte15 = TileByte14+14
Code: Select all
ldx TileIndex CopyTile: lda TileByte0, x sta $2007 lda TileByte1, x sta $2007 lda TileByte2, x sta $2007 ;(...) lda TileByte14, x sta $2007 lda TileByte15, x sta $2007 dex bpl CopyTile
Even if you don't have the RAM to spare, it's still possible to interleave the tiles in ROM and use the same technique.
There seem to be 20 CHR-RAM sprite tiles unused at any time; the character animation takes 12 tiles, of which I can update at least three in any given frame, so there is space for two different "predicted" frames, which I would assume would make the algorithm quite complicated though.
Is there a possibility of creating a good 50 Hz timer on an NTSC system using the DPCM interrupt? If so, that might provide a better means of adjusting the music speed than my current "skip every 6th call" to the music routine, which makes the arpeggios rather uneven.
Not exactly, but the closest three areNewRisingSun wrote:Is there a possibility of creating a good 50 Hz timer on an NTSC system using the DPCM interrupt?
Block length 1(17 bytes), rate $5 = 51.8Hz
Block length 5(81 bytes), rate $F = 51.1Hz
Block length 4(65 bytes), rate $E = 47.8Hz
Close enough. I suppose I can relocate what's in the $C000-C011 area to a few unused bytes at the end of the fixed back to make room for 17 bytes of silent samples.lidnariq wrote:Block length 1(17 bytes), rate $5 = 51.8Hz
What do you mean, "make frames"?lidnariq wrote:Is it possible to make frames when only the instruments (including arpeggios) are updated and nothing else?