It took me a while to convert the DYCP part from VIMM, and again I contacted Anders Carlsson for the music. He didn't disappoint me, and produced a very small music player (track player) with a test music and a little larger music player (duration player) with some tunes.
I was talking about color splits with Aleksi, so I also demonstrated how to get a lot of independent colors on screen with a routine, which later became the second routine for the unexpanded demo collection, called 19-split.
I continued converting the VIMM parts, and used all of my skills to fit everything into the 5.5kB of RAM (color memory nybbles included) available. Fortunately I always found some way to implement the effects or memory management better than in the so-called original versions. Of course sometimes sacrifices had to be made.
The following chapters goes throught the parts in order, talks about the general idea, code specifics, memory layout, how memory was saved, joystick control and other hidden bonus features, in addition to how the part actually performs and looks like.
Note that only PAL VIC20 is currently supported.
This part also starts the music for the first actual part and plays the music while the part is loaded. I first had the next part in the same file, but decided that the smaller the first part is the better.
The picture display is turned off while a new picture is being loaded. Pictures are loaded in order and when no more pictures are found, the next part is loaded. VIMMII contains 10 pictures.
The scrolling and color-changing border bars were added for release in the unexpanded demo collection. Before this addition I considered dropping this part completely from VIMMII, but now it is cool enough :-)
The VIMM part faked 8-line characters by having three 24-character patterns. One set has both halves the same, while the others have lighter and darker bottom halves. Character and border colors can be only from 0 to 7. Two sets of patterns are needed to switch colors so that character and border colors are always from 0 to 7, whatever colors are on-screen. The VIMM way thus needed 2304 bytes for the character patterns, but I found a better way. The new way only needs three 32-character patterns, 1536 bytes.
The major change is that the old version used a fixed map to which a running offset was added to cycle the colors. The size of the map was 1044 bytes. Another map was activated while the next part was loaded. I decided to use a 'real' plasma, which did not need a full map. A sine value is calculated for each row and column, each location value is the sum of the row and column values. The frequency and offset of row and columns sines are varied to morph the display. No map is needed, and the sine table only takes 256 bytes.
The scroller is implemented by clearing the multicolor bit in the color memory in the right places. Because the plasma routine always initializes the double-buffered color memory, the routine doesn't do actual scrolling, but plots the pixels anew every frame. Scrolling up emulates 8-line characters by moving the screen start location and only really scrolling every second frame. The plasma row sine calculation is properly compensated so that the plasma display does not jump around. The font is generated from the ROM font by logically oring with a right-shifted version.
The scroller actually demonstrates a dual-color plasma.
The implementation isn't magic, of course. It is simply 16 lines worth of lda #0 and sta $900f pairs with some other instructions thrown in, and each lda updated each frame with the right colors.
The display area was filled from the two source buffers, that contained the characters currently on-screen. Different effects are made by transforming the data a bit when copying it to the display area. Two buffers were needed for quarter-character scrolling speed, because horizontal scrolling precision is only one cycle, i.e. half a character. Data in the other buffer is one multicolor pixel rotated compared to the first buffer. This slow scrolling speed was the first feature to remove -- the scroll speed can easily be allowed to be twice as fast, because quarter of a character per frame was actually too slow anyway.
The source buffers are handled like ring buffers, i.e. when a new column of a character appears, only that column must be printed to the buffer, the whole buffer does not need to be scrolled. When copying to display area, only the source pointers need to be scrolled so that the target data is moved by one column while the source data remains the same. This also made it easy to use two buffers, because the same copy routine could be used, just the source pointers were changed to point to the right source buffer.
Actually, we don't even need to change the pointers at all, but scroll the video matrix contents instead. At first the columns corresponds to character codes 0/1..54/55 (two rows, 28 columns). When scrolling new data is copied to charactes 0 and 1, and the video matrix columns are set to 2/3..54/55,0/1.
But the pointers can be set to point to the font itself instead of the source buffer (there is only one now, because we eliminated the shifted one), eliminating the use of a temporary graphics buffer completely. Now we only have the 3kB font and the 896-byte graphics display area, and the pointers have the information about which column of which character corresponds to which column of display data.
This is much better than the original, but still too much. The copying routine requires that each source 'slice' is consequtive 32 bytes and the effects assume that first line of the font is empty. The character packing that is used in the 3k-vimmii part can be applied here, the unit is simply 32 bytes instead of 16 bytes, i.e. only identical columns are removed. To save enough space I had to edit the font more dramatically, I even left out WXZ that were not used in the scrolltext. The result is 1536 bytes for the font, 84 bytes for the mapping table.
The improved scroller allowed two effects and no-effect on-screen simultaneously. Each character (or in fact each column of a character) could select any of these. This required a 120-byte table and the effect code was a little more complicated than necessary. One effect (or no effect) for the whole display only needs one 40-byte table and simplified effect code. Also, I had to drop some effects. Two of the remaining ones use the same data tables and the third leaves the table to 'normal' state after finishing.
Some of the tables are located in color memory (just remember to clear the top nybble), and the loader is not used anymore, so also that 200 bytes is free for grabs. Sprinkled on top with Anders Carlsson's very tiny trackplayer and tune ($90 for music data, $d0 for player) the part is finished.