For developers wanting to explore FCM (full-colour mode), it can be quite a daunting journey initially, so here’s some pointers along with an ‘experimentation’ walkthrough that will let you peek and poke your way to a better understanding of FCM
The gist of FCM/NCM modes
For FCM, each character on the screen is represented by 4 bytes (32-bits worth of information)
Two of those bytes are in screen memory (where we'd traditionally put our characters. e.g. at
$0800
)Two of those bytes are in colour memory (e.g. at
$ff80000
)
For NCM (nibble colour mode), each two screen characters are defined by these 32-bits)
From here-on in, I’ll refer to the concept of “two of those bytes” as “byte-pairs”.
Where to read about it in the docs?
The section of interest is in "Appendix M >> New Modes >> Displaying more than 256 unique characters via "Super-Extended Attribute Mode"
Of particular interest is these two tables. They describe how the bit-fields within the screen byte-pair and the colour byte-pair are defined.
The major gotchya that trips up newcomers is that the definition of these bit-fields varies depending on whether a certain bit within the colour byte-pair is set or cleared, the GOTOX bit.
That’s why there are two tables:
one table for when this GOTOX bit is cleared
the other table for when this GOTOX bit is set
Common Tripping points
Where is character data located?
Newcomers usually get muddled up at the location where FCM characters get defined, assuming that is from some offset in memory from where all character data is defined.
In reality though, it turns out that that the entire address-space can be used to define character (i.e., think of character data starting at a memory offset of zero!).
This of-course feels a bit silly, as no doubt we don’t want to define characters in the zero-page, and if we want to play nice with BASIC 65’s ram usage, we probably don’t want define characters anywhere within bank 0 or bank 1 either.
Bank 3+4 are locked as read-only for the kernal, but for keen assembly coders that don’t need the kernal, you could potentially unlock this memory and make it writable, and put character data there.
For BASIC coders, that won’t be an option though, so you might instead want to settle for a location within BANK 4 or 5 (or possibly a bank attic ram).
Example:
So let’s say I want to use BANK4, i.e., $4,0000.
I need to divide this by 64 bytes ($40) to get the char index
(since each pixel within the 8x8 character needs one byte in FCM mode)I.e., $4,0000 / $40 = $1000
So you need to set:
Screen RAM byte 0 to $00
Screen RAM byte 1 to $10
What’s all this about 16-bit character numbers?!
I feel another tripping point that causes initial confusion is the term used for the bitfield “CHR16”:
The docs for CHR16 say it enables "16-bit character numbers", when in reality, it enables “12-bit character numbers”.
Whether it's worth changing at this stage, I'd lean towards yes, it ought to change to reflect the reality and not mislead, but maybe others might feel the name is locked in now that it has gone to print 😄
Then again, the mega65-book didn't go to print yet, just the user-guide, so maybe there's hope.
FCM Experimentation via the UART monitor
In this section, I share my experimentation notes, all of my past attempts to peek and poke various registers in order to learn how these byte-pairs (and the bit-fields within them worked).
My notes feature a lot of screenshots, and follow this approach:
Try this, observe that…
Try this, observe that…
rinse/repeat
…so I feel it will be relatively easy for someone to simply repeat the steps I tried and gain similar understanding and insights.
How to access the UART monitor on a real MEGA65
If you’re working on real hardware, you have two options:
“OK OPTION”
- You can press MEGA+TAB keys to reveal the matrix debugger and type monitor commands within therePROS: in-built option all owners have available to them from the get-go
CONS: The monitor is shown as an overlay over the original screen, so you will be jumping in-and-out after each command you type, and this may limit your ability to view the impact of the change in real-time.
“BETTER OPTION”
- If you have a JTAG/serial adapter connected to your MEGA65, you then debug via USB-serial on your PC using either a serial terminal program like putty, or you could use a fully-fledged debugging tool like m65dbg.
How to access the UART monitor in XEMU
In xemu:
right click for context menu
Go to "Debug/Advanced >> Start umon on :4510"
Then in a console (or in a tool like putty), telnet to localhost on port 4510. E.g.:
telnet localhost 4510
You can then type monitor commands within this telnet session
How to use the UART monitor
For ‘peek’ing, you can use the 'm' command:
m<addr>
For ‘poke’ing, you can use the 's' command (it can take multiple values if you want to write several bytes to successive addresses):
s<addr> <val1> [<val2> <val3> ...]
So, where can I find your FCM experimentation notes then?
My notes are available as a google doc here: