45gs02 Tutorials VIC-IV

VIC-IV graphics, setting up FCM and NCM

NOTE this doc is in progress and images will be added

Refresher on C64 background graphics

Due to the Mega65’s graphics being an extension of previous hardware, let’s have a little refresher on how background graphics works on the C64.

The VIC-II can only access 16KB and so we must select which bank of memory it’s data is residing in by modifying bits 0&1 of $dd00, this will select either (%11) $0000, (%10) $4000, (%01) $8000 or (%00) $c000. The screen and character ram locations are offsets within the selected bank.

The C64 screen is a fixed size of 40×25 characters (1000 bytes) and is split into screen RAM (offset from VIC-II bank using bits 4-7 of $d018) and color RAM (fixed location of $d800). Each element of the screen data is an index into a character set made up of 256 small images. Each of these characters take up 8 bytes so a total of 2048 bytes (offset from VIC-II bank using bits 0-3 of $d018).

The screen memory indicates which character graphics to display (8 bits) and the color memory indicates the color to use (lower 4 bits only).

With enough fancy footwork, you can achieve stunning screens like this BoozeDesign screen. https://csdb.dk/release/?id=240696

Mega65 screen using SEAM (Super Extended Attribute Mode)

As we saw above, the VIC-II could reference 256 different characters per screen, the VIC-IV however can reference an impressive 8192 but clearly this can’t be done from a single byte.

In order to use the VIC-IV’s more advanced graphics modes we will use a feature called Super Extended Attribute Mode or SEAM for short, enabled with CHR16 (bit 0 of $d054)

        // Enable Super Extended Attributes
        // Set bit0=16 bit char indices (SEAM)
        lda #%00000001
        tsb $d054

This expands all screen and color data to be 2 bytes per tile but in doing this it adds the following features.

  • Reference a character anywhere in the bottom 512KB (at a 64 byte granularity).
  • Per character we can select between Full color (FCM), Nibble color (NCM) and Mono.
  • Use the special GOTOX flag to jump the write position in the Raster Rewrite Buffer allowing for fancy multi-layered effects.
  • Vertical and Horizontal flipping of characters.
  • Right hand trimming of character pixels.
  • NCM palette selection per characters (choosing 1 of the available 16 color palettes).
  • Vertical shifting when the character data is read from RAM (I’ll go into all of the uses of this later).
  • Row masking allow you to select which rows of the character are drawn to the screen.
  • Foreground / Background priority compared to sprites.
  • Opaque / Transparent specifies if color index 0 writes to the screen or not allowing characters to be overlayed on top of each other.

When SEAM is enabled, remember that LINECOUNT ($d058,9) must now take into account that each character is 2 bytes so it’s typically set as LINECOUNT = CHRCOUNT * 2.

Following images from mega65-chipset-reference.pdf

Palettes

The VIC-IV has 4 palettes of 256 colors each, to enable editing of the palettes you must first enable the PAL flag (bit 2 of $d030).

        // Enable RAM palettes
        // Set bit2=PAL
        lda #%00000100
        tsb $d030

In order to access a palette for reading/writing you must select which is currently mapped by setting MAPEDPAL (bit 6&7 of $d070). Once a palette is selected you can read / write the Red bytes from $d100-d1ff, Green bytes from $d200-d2ff and Blue bytes from $d300-d3ff.

NOTE that for each value in palette RAM, the nibbles are flipped and so you must swap the lo and hi nibble to get a true 0 – 255 value. For example, a color of $37 should be stored as $73.

NOTE even though it looks like there should be 24 bits of colors displayable, the bottom bit of Red (bit 0) is reserved for genlock (not yet implemented) and so we can only display 2^23 colors (about 8 million).

You must lastly select which of the 4 palettes are to be used for Text, Alternate Text and Sprites. You do this by writing you selection to Text (BTPALSEL bit 4&5 $d070), Sprites (SPRPALSEL bit 2&3 $d070) and AlternateText (ABTPALSEL bit 0&1 $d070).

        // Example Palette selection and choosing which to edit.
        // this chooses to edit pal 0, text and sprite are pal 0 and alt is pal 2
        //
        // MAPEDPAL, BTPALSEL,   SPRPALSEL,    ABTPALSEL
        // Edit=%00, Text = %00, Sprite = %00, Alt = %10
        lda #%00000010
        sta $d070 

Enabling FCM / NCM

In order to use either FCM or NCM we must first enable 8 bit color, this is done by clearing ATTR (bit 5 of $d031). We also want to enable FCM chars > 255, this means that any character index < 256 will show as Mono and any above 255 will show as FCM/NCM, this is enabled with FCLRHI (bit 2 of $d054).

        // Disable VIC3 ATTR register to enable 8bit color
        // Clear bit5=ATTR
        lda #%00100000
        trb $d031

        // Enable Mono chars < $ff
        // Set bit2=FCM for chars >$ff
        lda #%00000100
        tsb $d054

Full Color Mode (FCM)

FCM characters are 8 x 8 pixels and 256 colors per character.

When characters are rendering in FCM they use the full 256 colors per pixel which means the character data will use a byte per pixel, each byte selecting a color in the selected palette. FCM characters will consume 64 bytes of memory each and must be on a 64 byte alignment.

In FCM mode, color index 255 is handled specially, index 255 will not select the last palette color, instead it will select the color index specified by what’s in color RAM (byte1).

Nibble Color Mode (NCM)

NCM characters are 16 x 8 pixels and 16 colors per character.

When characters are rendering in NCM they use 16 colors per pixel and each byte of character data represents 2 pixels, the left in the high nibble and the right in the low nibble. Each nibble is an index into a sub-palette that is selected with color RAM.

NCM characters also consume 64 bytes of memory each and must be on a 64 byte alignment.

In NCM mode, color index 15 is handled specially, index 15 will not select the last palette color, instead it will select the color index specified by what’s in color RAM (byte1 lo nibble). The sub-palette is selected using the value in color RAM (byte 1 hi nibble) so a color RAM value of $4f specifies that palette 4 is selected and color index 15 will use sub-palette color index 15.

Related Posts

VIC-IV graphics, using RRB for pixies

Raster Rewrite Buffer The Raster Rewrite Buffer is a new feature introduced in the Mega65, you can think of it as a 2048 pixel wide single line buffer….

Scrolling the VIC-IV Screen

Unless all the action on your game is going to take place on a single screen you are going to want to scroll the screen. Using the VIC-IV…

The VIC-IV Screen Layout

With the addition of the VIC-IV, the Mega65 is not limited to a fixed sized screen anymore, the application can set the screen to any size up to…

Welcome to a very Mega65 centric blog!

I’m currently working on a shmup for the Mega65 called FirstShot and while I’m procrastinating on the various challenges of making a game with 4 registers and limited…

Leave a Reply

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