Asterix converted to run on NTSC

This is an archive of a topic from NESdev BBS, taken in mid-October 2019 before a server upgrade.
View original topic
Asterix converted to run on NTSC
by on (#232954)
My first attempt at converting Asterix to run on NTSC (and Dendy) consoles.

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.
Re: Asterix converted to run on NTSC
by on (#232955)
Cool!
Re: Asterix converted to run on NTSC
by on (#232965)
I don't know anything about the architecture of Asterix. But does it have enough room in CHR RAM to double buffer the affected character's animations? And is the next cel predictable based on the current cel, such as in a run cycle? If so, you could try what Haunted: Halloween '85 does: preload the most likely next cel, and lag only on misprediction.
Re: Asterix converted to run on NTSC
by on (#232970)
Even if you can't use the unrolled PLA+STA method, you can still achieve comparable speeds with indexed addressing. Several years ago I posted about a generic solution for transferring data to VRAM at 8 cycles per byte, but since this is just for tiles you can probably use something more specialized.

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:
TileByte0 = $0500 ;buffer starts at $0500
TileByte1 = TileByte0+14
TileByte2 = TileByte1+14
;(...)
TileByte14 = TileByte13+14
TileByte15 = TileByte14+14

With the buffer arranged this way, you can now blast tiles to VRAM like this, with very little overhead:

Code:
  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

Since this is copying the tiles backwards, you'd have to buffer the tiles in that order too, but that's easy if you know how many tiles you need to copy.

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.
Re: Asterix converted to run on NTSC
by on (#233015)
Thanks, guys --- I appreciate the suggestions. Looking at the memory log after playing through all levels, once, I can find $C3 bytes outside the $140-$1FF region that I could use to relocate the variables from there, which might keep the PLA option on the table after all. Otherwise, I will consider the suggestions offered here.

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.
Re: Asterix converted to run on NTSC
by on (#233018)
Is it possible to make frames when only the instruments (including arpeggios) are updated and nothing else?
Re: Asterix converted to run on NTSC
by on (#233019)
NewRisingSun wrote:
Is there a possibility of creating a good 50 Hz timer on an NTSC system using the DPCM interrupt?
Not exactly, but the closest three are
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
Re: Asterix converted to run on NTSC
by on (#233020)
lidnariq wrote:
Block length 1(17 bytes), rate $5 = 51.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:
Is it possible to make frames when only the instruments (including arpeggios) are updated and nothing else?
What do you mean, "make frames"?
Re: Asterix converted to run on NTSC
by on (#233022)
He means that the note events are separate from updating of arpeggios, so if you can find the separation you can tick the note events twice on every fifth frame, but don't double the arpeggio tick.