How MD201602 works

The majority of this post will be on MD201602‘s DYCP scrollers since the logo movement relies on what is a technique which requires very little processing time; there are multiple copies of the bitmap in memory generated when the code starts, with each stored at a different character offset horizontally so the routine swinging the logos can take a value from the curve, strip the lower seven bits off for the hardware scroll register and use what’s left to select which version of the logo to use. No data is moved in realtime so this takes a couple of scanlines at most, have a look at lines 379 to 398 of the source code since that sets up the top logo, writing directly to the registers.

The DYCP scrollers themselves are… well, just traditional DYCPs really and I’ve tried to optimise things as much as possible without losing that “spirit” too, which is why the routine isn’t going to set a record! The character set is five pixels high and, similarly to the logos, converted on start up by a routine called font_xvert so the top pixel row of each character is in a contiguous table, then the second row and so on; this format allows any of the characters to be accessed quickly, with the renderer for the first scroll drawn looking like this:

ldy dycp_cosinus,x
ldx dycp_buffer_1+$00
beq dd1_char_01
lda dycp_xfont+$000,x
sta dycp_workspace+$008,y
lda dycp_xfont+$100,x
sta dycp_workspace+$009,y
lda dycp_xfont+$200,x
sta dycp_workspace+$00a,y
lda dycp_xfont+$300,x
sta dycp_workspace+$00b,y
lda dycp_xfont+$400,x
sta dycp_workspace+$00c,y

The Y register is, appropriately enough, being used to designate the height that the character will be written into dycp_workspace (a standard character set arranged in columns of six characters on screen) whilst X is selecting which character to draw – the first line of every character is stored at dycp_xfont, the second line kept one 256 byte page on from that original position and the third, fourth and fifth are each a page further into memory than the one before them. The BEQ in the source fragment above means that if the content of the scrolling message in dycp_buffer_1 at that point is zero, the character is empty and the rendering can be skipped entirely. (And with that in mind, it probably isn’t difficult to understand why the greetings scroller is spaced out!)

Finally, there’s the colour bar in the middle of the screen using the same kind of vertical splitting that MD201509 employs and, to make the scrollers look like they’re passing behind it, the screen RAM on that central line of the five being used by the DYCPs is constantly being manipulated; if the character in the second scroller is using the first half of the cosine curve then the value written to that column on the central line of the screen is taken from line_cache (which is a copy of what’s initially generated at that point on the screen) but if the position is 128 to 255 then the routine writes a zero there instead which is always a blank character. Filling the first eight bytes of dycp_workspace which starts at $5000 with $FF from the VICE monitor or using an Action Replay cartridge once the code is executing will make that blank space visible and shows how this works more clearly, the solid blocks move across the screen and it looks like this:

So… that’s the basics at least and the source code is available to prod around too, but if anyone has a question please get in touch through the “usual channels”. I might also be persuaded to post source code for a more generic DYCP routine if enough people want it?

2 thoughts on “How MD201602 works

  1. Would like to see a more ‘generic’ DYCP routine if it’s well commented so I can make sense of it!

  2. Okay, a few other people have asked as well so i’ll get it done over the next couple of days. =-)

Leave a Reply

Your email address will not be published. Required fields are marked *