Flatpak VICE, Sublime Text and Kick Assembler

The Linux Mint VICE version listed in the software manager is an older version and had issues with opening modal windows (I could, for insta...

Friday, 19 April 2019

Flatpak VICE, Sublime Text and Kick Assembler

The Linux Mint VICE version listed in the software manager is an older version and had issues with opening modal windows (I could, for instance, not open the monitor) on my Linux installation.

VICE is not released as a compiled version for Linux anymore and I just do not want to compile the emulator each time a new version is released. It turns out that the VICE version distributed in Flatpak is version 3.3, the most recent. So lets use that one. After removing the old version via Software Manager and installing the Flatpak version I noticed that the build systems for Kick Assembler in Sublime Text did not work anymore: compiling works, but the emulator is not started afterwards: the command x64 is not found.

This is because Flatpak is an abstraction layer around your application allowing for applications to run without being installed 'inside' your OS. Flatpak is started first, and then your application. Inspecting the icons for VICE which were created by the Flatpak installation made it clear that VICE is now started like this:

/usr/bin/flatpak run --branch=stable --arch=x86_64 --command=x64 net.sf.VICE

So we need to modify the build scripts supplied by the Kick Assembler package for Sublime Text. Luckily, these use the new way of defining parameters. The package preferences (Preferences > Package Settings > SublimeKickAssemblerC64 > Preferences) showed me these two relevant settings:

"kickass_run_path": "x64"

"kickass_run_command_x64": "\"${kickass_run_path}\" -logfile \"${kickass_output_path}/${build_file_base_name}_ViceLog.txt\" -moncommands \"${kickass_output_path}/${build_file_base_name}.vs\" ${kickass_run_args} \"${kickass_output_path}/${start_filename}\""

So the solution comes in two steps.

1) modify the kickass_run_path variable to:

"kickass_run_path": "flatpak run --branch=stable --arch=x86_64 --command=x64 net.sf.VICE"

2) modify the run command itself slightly; it currently adds quotes around the executable command, which will not work with Flatpak, so let's remove those. They are preceded by an escape character and show up as \" . We only need to remove the quotes around the kickass_run_path part:

"kickass_run_command_x64": "${kickass_run_path} -logfile \"${kickass_output_path}/${build_file_base_name}_ViceLog.txt\" -moncommands \"${kickass_output_path}/${build_file_base_name}.vs\" ${kickass_run_args} \"${kickass_output_path}/${start_filename}\"",

After saving this in the User settings (this will override the package defaults) compiling and running the emulator works again. Afterwards, I did the same for the debug path.

I am currently extending the Kick Assembler package with more snippets and build systems for the C128. I will create a pull request for the official repo for the package in the near future.

Happy coding!

Thursday, 21 February 2019

Ultimate64 RGB video - RECOMMENDED

Ultimate 64 RGB video

The Ultimate64 can output RGB video from the 'normal' analog video port which normally produces component and s-video signal.

Some time ago I received an Ultimate64 to RGB scart video cable. It was made for me by an nice fellow from Belgium (much thanks!), as I suck at making small solder points. The pin connection diagram can be found on the U64 documentation page.

Connecting the U64 to an RGB capable monitor really shows gives new life to this old machine. I'm loving it.

The PVM monitor I own can now be used to connect my Ultimate64 (analog RGB), C128D (s-video and digital RGB) and Amiga (analog RGB)

Here are some closeups of games and demos showing the color and picture clarity.

First some Wizball to show the nice scan lines that are produced, the contrast and deep blacks.

Then, a new demo called "Unboxed." Check out the nice color selections on the top left and left side of the image and how the image displays these next to each other with no blending or interference.

The Ghosts 'n Goblins remake really looks amazing. I can watch the attract mode all day long.

Finally, a close up of the game "Rescuing Orc." I love how this game looks, the graphics have great personality.

If you have an RGB monitor and use the Ultimate 64, I really recommend you to go get that RGB video cable made and hook it up. You'll get a whole new C64 experience.

Saturday, 31 March 2018

Commodore 128 Assembly - Part 3 : The 80-column (8563) Chip

Welcome to a new part of this series. We are going to look at the basic functions of the VDC, which enables 80 column support. It is foremost a chip designed to do nice stuff with text. It can do interlaced modes and bit-mapped graphics though, and we might take a look at that later on.

The bitmap mode has enabled people to create games for it which are not dependent on the hardware sprites and other VIC effects. For instance, someone has ported Ultimate games to the C128 using this mode:

These games are good candidates as they use software sprites, in a bit-mapped mode.


The RAM used by the VDC is isolated from the main C128 memory map. It can only be accessed through two registers that are mapped to $D600 (address register) and $D601 (data register).

The following procedures must be used to read/write from the VDC RAM:

  1. put the required register # in the address register;
  2. wait for the ready bit in the address register to go high;
  3. store or load the value from the data register;

Here are the macros I've written for this:

.macro WriteVDC () {
!: bit VDCADR
bpl !-

.macro ReadVDC () {
!: bit VDCADR
bpl !-

Early C128 machines came with 16K of VDC RAM, expandable to 64K by added three additional 16K chips. Later models (C128, C128CR) had 64K RAM. The VDC is configured to use 16K or 64K modules, and we can check that configuration by reading bit 4 of register 28:

:SetBankConfiguration(15) // set bank 15
ldx #28
sta $fb
lda #010000
bit $fb
bne small
lda #$31
jsr $ffd2
lda #$30
jsr $ffd2

Running this program on VICE results in this, as it emulates a 64K model:

Of course, a 0 does not mean there's only 16K in your machine, only that the VCD is configured to use 16K modules. So there still might be 64K available. I have not found a way to check this, apart from trying to write something outside the 16K. :)

Writing to the VDC RAM takes two steps:

  1. Set the update address where you want to write to;
  2. Pass data through the internal data register of the VDC (register 31);

This is the macro to set the update address:

.macro SetVDCUpdateAddress (address) {
ldx #18
lda #>address
.var a1 = <address
.var a2 = >address
.if( a1 != a2) {
lda #<address // include if different from hi-byte.

Matrix Data

The Matrix data area in the VDC is located at $0000-$07FF by default.  It's function is the same as screen memory in the C128 main memory map ($0400 by default).  As we have 80 characters in a row, it takes 2000 bytes, as opposed to the 1000 bytes on the 40 column display.

The address in VDC RAM can be retrieved by reading registers 12 and 13. You can also change the address of the matrix data by writing a new value to these registers. This macro will read the current setting, and store it in $FB and $FC:

.macro GetVDCDisplayStart() {
ldx #12
sta $fb
sta $fc

Writing to this area of RAM goes like this:

ldy #0 // loop counter
ldx #31 // internal data register of the VCD.
bne !-

This puts 255 characters in screen memory. After each write, the update address in the VDC is incremented for us. Handy!

Attribute Data

Attribute data is located at $0800-$0FFF by default, and can be read or changed by modifying registers 20 and 21. Attribute data is comparable to VIC color data, but it has more features. Characters can blink, be inverse (without these being part of the character definitions as with the VIC), underlined and more. Also, these attribute effects can be modified. for instance, the underline can be moved withing the character, enabling, for instance, a strike-through effect.

Each byte in the attribute data corresponds to a screen location, and it can be written to. Attributes are enabled by setting a bit in each byte:

7 - Character set
6 - Reverse video
5 - Underline
4 - Blink
3 - Red
2 - Green
1 - Blue
0 - Intensity

Attributes can be enabled or disabled (this is a global setting, allowing you to use the RAM for something else) by using bit 6 of register 25. So let's play, by writing some bogus values to this area:

ldy #0
lda #%01110101
ldx #31
ror // crazy stuff
bne !-

ldx #25 // write to this VDC register
ora #%01000000 // enable attributes

This will be the result:

Character Definitions

As on the VIC, the character definitions can be changed on the VDC. The definitions are located, by default, at $2000-$3FFF in VDC RAM and its config can be changed or read through register 28. As the VDC cannot access the character ROM at $d000, and because it has no character definition data by itself, the definitions are copied from ROM to VDC RAM when the C128 boots. As a VDC character is defined in a 8x16 grid some padding is added to the character data each 8 bytes.

This is done by a kernal routine called DLCHR. We could utilize this routine, but it has some hard coded values, so here's the macro I've made that steals this idea and makes it more flexible:

.macro CopyDefinitionsToVDC (address, address_end) {
lda #<address
ldy #>address
sta $da // pointer to start of data
sty $db
lda #>address_end
sta $de // high byte of data end

ldx #$12  // write to $2000 in VDC ram
lda #$20
lda #$00

ldy #0
ldx #31 // VDC data register
lda ($da),y
cpy #8
bcc !-

lda #0 // add 8 bytes as padding
bne !-

lda $da
adc #8
sta $da
bcc loop
inc $db
lda $db
cmp $de // done all?
bne loop

To use this, you need to define the start and end of the definitions data. Here's how to in Kick Assembler:

.pc = $2000 "character set"
.import binary "tetris_chars2.raw"

I've imported the char set created for my Tetris clone. Spot the counterfeit logo, after I've called this:

:CopyDefinitionsToVDC(charset, charset_end)

That was easy!!

Modify Fonts and Display

The VDC can manipulate how characters are displayed.  We can do fun stuff with it.

The spacing around the character can be changed, by using registers 22 (horizontal) and 9 (vertical). Here is some example code:

ldx #22
lda #%10110110

ldx #9
lda #11  // vertical spacing of char to 12.

This will result in:

As you can see, more spacing is added vertically and horizontally. What is interesting to see is that all 80 columns are printed, but when a line wraps it is continued one pixel down, creating an overlap. The next line is started at the default position.

We can also control how MUCH of a character is displayed by modifying registers 22 and 23:

ldx #22
and #%11110000
ora #000100      // set horizontal display to 4

ldx #23
lda #3 // vertical display to 4

Resulting in:

Spacing is not effect, but by setting the register values to 4, we only see a 4x4 grid of each character.

What do do with it? We can make fun fades, like:

lda #7
sta $fb
ldx #23    // affect vertical font display
lda $fb
dec $fb
bpl !-
ldx #50
ldy #0
bne !-
bne !-

Resulting in:


The VDC is a versatile chip and it's sad to see that not much software was created to take advantage of it. The demo scene created some cool demos and games using the VDC, so all is not lost!

There is more to the VDC chip, and we'll return to it later when needed. There's scrolling, blitter functionality, bitmap mode and more.

Wednesday, 21 March 2018

Commodore 128 Assembly - Part 2 : Memory Management

Commodore 128 Memory Management


Welcome to another part in this series. We need to get the basics down of the Commodore 128, and so it is time to crack on with memory management. It is very important for the C128 machine code programmer to understand how this works, and it is more complicated as opposed to the C64, where memory address $01 controlled the ROM/RAM mapping in a relative simple way.

When programming the C128, the following two books are indispensable:

Also before we continue, a definition of terms:
  • RAM block: a single block of 64K RAM. The C128 contains two of these;
  • Bank: a configuration (combination) of RAM block selection and ROM chip mapping;
  • Common RAM: an area in RAM block 0 that is also available in RAM block 1;
  • MMU: Memory Management Unit, the "new $01";
  • VDC: Video Display Chip, the new video chip in the C128;
  • VIC II: Video Interface Chip, the video chip as known from the C64;
  • VIC Bank: an area of 16K of RAM, used by the VIC chip.

Take a look at this memory map (you can access it here on google drive), and then lets go through this, one area at a time.

When we look at the RAM0 and VICII Banks columns, we can see the C128 is much the same as the C64. There is a bigger BASIC ROM though, and some areas we know from the C64 have been moved (start of BASIC RAM, location of BASIC variables, screen editor). When we introduce the RAM1 column and the Common areas it starts to become more complicated as there are more combinations to be taken care off.

The bottom of RAM1 is used by BASIC to store variables. The rest is free to use as needed.


The chip that does all this trickery for us is the MMU. Its registers are mapped to $D500 to $D506. This is not inside the default common RAM block, so this introduces the problem that any configuration that maps out the ROM in this area will also make the MMU unavailable.

Commodore solved this by mirroring the MMU registers in the top of memory ($FF00) and force this area common. You should not use locations from $FF00 to $FFFF for code or data. We will use $FF00 and not $D500 for MMU configuration changes.

We will use the MMU in the following examples.


Banking is about two things:
  1. selecting a RAM block;
  2. determining which ROMS are available, or not
Being an 8 bit processor, the 8502 can only 'see' 64K at a time so there needs to be a mechanism to switch between the RAM blocks. This is done by selecting a bank configuration.

ROM chips can be enabled or disabled. When disabling a ROM, the RAM underneath becomes available for reading. You can always write to a RAM location 'underneath' a ROM.

The BASIC 'BANK' command will select one of 15 configurations that Commodore has prepared. Bank configuration 15 is the default setting, and it provides the configuration shown in the map above.

In machine code, we need to access the MMU directly, and set the bits of the configuration register ($FF00) that we want.  A macro helps with that:

.macro SetBankConfiguration(id) {
.if(id==0) {
lda #111111 // no roms, RAM0
.if(id==1) {
lda #%01111111 // no roms, RAM1
.if(id==12) {
lda #000110 // int.function ROM, Kernal and IO, RAM0
.if(id==14) {
lda #000001 // all roms, char ROM, RAM0
.if(id==15) {
lda #000000  // all roms, RAM0. default setting.
.if(id==99) {
lda #001110  // IO, kernal, RAM0. 48K RAM.

It generates this code when we call SetBankConfiguration(15) :

LDA #$00

This will select RAM bank configuration 15 and enable I/O, Kernal and BASIC ROMs. The macro offers the possibility to add custom configurations (see option 99). There is also a configuration (12) that enables the internal function ROM (a free socket on the motherboard can be fitted with a custom ROM chip). I intent to test some ROMs that I have real soon.

In general, try to use RAM block 0 for program code, and RAM block 1 for data.

Common RAM area

By default, common RAM is only present at the bottom of the memory map, has a size of 1K, and runs from $0000 to $03FF.  Common RAM always comes from RAM block 0. The configuration of common RAM has nothing to do with banking; choosing another bank configuration does not change the common RAM settings.

If you only need to access RAM block 0, then a good place for programs is in the range of $1300 to $1BFF. If you do not use BASIC then you can use up to $3FFF. But, any program located here making the switch to RAM block 1 cannot continue as this range is outside the common area and therefore unavailable in RAM block 1. The program will crash.

When writing programs that need to use both RAM blocks, you need to put that program (or the part that accesses both blocks) in the common area. This situation was foreseen and Commodore has provided some free space in this area and subroutines for reading and writing data to and from any RAM configuration.

We will take a look at those subroutines in another part.

If your program or data is too large to fit in the default common area, then its size can be changed. It can be 1, 4, 8 or 16K in size. The macro I created to change the size is this:

.macro SetCommonRAM(amount) {
and #%11111100 // clear bits 0 and 1. this is also option 1
.if(amount==4) {
ora #000001
.if(amount==8) {
ora #000010
.if(amount==16) {
ora #000011

Calling SetCommonRAM(8) generates:

ORA #$02

Also, we can choose to make the top of memory common, the bottom (default) or both. In total we can have 32K of common RAM. This is done by using the following macro:

.macro SetCommonEnabled(option) {
and #%11110011 // clear bits 2 and 3
ora #option*4

Calling SetCommonEnabled(1) generates:

AND #$F3
ORA #$04

This will make the bottom 8K common only.


The VIC chip in the C128 is configured exactly the same as on the C64. The VIC chip registers are mapped onto $D000 in RAM. By default, the VIC chip uses the same 16K area as the C64 ($0000 to $3FFF) and the screen and character memory offsets are also identical.

Also, as on the C64, the VIC chip does not see ROM, only RAM. No matter what your memory configuration is, you can use the RAM you selected even if a ROM image is mapped in the same location.

As you can see in the memory map above, the VIC can be pointed to 4 blocks of RAM, also called banks... The following macro accepts a number from 0 to 3:

.macro SetVICBank (bank) {
lda $dd00
and #%11111100
ora #3-bank
sta $dd00

Calling SetVICBank(0) creates:

 LDA $DD00
 ORA #$03
 STA $DD00

Which will select VIC bank 0, which is the default. Are you tired of the word 'bank' yet?

Within this 16K block of RAM, we can change the offsets to the character set data and the screen display matrix (screen memory) inside that block.

.macro SetCharacterOffset (offset) {
lda $d018
and #%11110001 // clear the 3 offset control bits
ora #offset
sta $d018

Calling SetCharacterOffset(4) assembles to:

 LDA $D018
 AND #$F1
 ORA #$04
 STA $D018

This mean that the offset for the character data is 4K. If the VIC bank is located at $0000 (the default) then the character data is read from $1000. As you can see from the map above, this is the default.

The offset voor screen memory (screen matrix) can be changed in 1K steps. The macro I created for this is:

.macro SetMatrixOffset (offset) {
lda $d018
and #001111 // clear the 4 offset control bits
.if(offset > 0) {
ora #offset*16
sta $d018

Using SetMatrixOffset(1) assembles to:

 LDA $D018
 AND #$0F
 ORA #$10
 STA $D018

Which will place the screen RAM at $0000 + $400 = $0400, which is, again, the default.

So far, nothing different from the C64. There is one new option though: you can tell the MMU that the VIC chip should use RAM block 1. Here's the macro to do that, and it accepts a 0 or a 1 as value:

.macro SetVICRAMBank(value) {
and #%10111111 // clear bit 6
.if(value==1) {
ora #%01111111 // enable bit 6

All Kernal routines etc work with RAM block 0, so why you would want to do this, I do not know.  I accept all tips regarding this subject!


The VDC registers are absent, its registers cannot be found in the C128 memory map, except for these two: $D600 and $D601. The VDC Video RAM and registers are isolated, and are accessed via these two locations. Nothing you can do with the MMU will change the way you interact with the VDC.

Programming it is kind of a hassle, so this is where macros and some handy subroutines should make this more easy. We'll get back to this later on.


When planning a program for the C128, it's wise to think about the memory layout beforehand and select or create the Bank configuration that best suits the program.  It's a good idea to draw a map like provided above, and fill in where the program and data will do. You can use the provided document I've shared (see the link at the top of this article)

If the VIC configuration needs changing because of the fixed location of data, then selecting another 16K block or tuning the location of character data and screen data will help.

This can now easily be done using a few macros that will generate the necessary code.
Getting this out of the way will make it easier to understand the machine and plan for new programs.

Next up is programming the VDC chip. It's lovely.

Saturday, 17 March 2018

Commodore 128 Assembly - Part 1

All the code and resource files in this post will be available on my Github page, because it's fun to share.  It's very W.I.P. though, so I will add it later when more stable.

I want to delve more into the Commodore 128. It's such a nice system. Some of the new and advanced features are not easy to program though. So I decided to create a system, a framework if you will, of re-useable parts once I had figured out the basics.


I use Kick Assembler, Sublime Text and VICE to develop on my PC.

Using more of Kick Assemblers power was on my to-do list and this is a start. I decided to create easy to use macro's that will generate specific object code, or make it easy to insert reusable subroutines into object code.

First thing to do was to modify the default basic startup macro to use $1c01, not $0801:

.macro BasicUpstart128(address) {
    .pc = $1c01 "C128 Basic"
    .word upstartEnd  // link address
    .word 10   // line num
    .byte $9e  // sys
    .text toIntString(address)
    .byte 0
    .word 0  // empty link signals the end of the program
    .pc = $1c0e "Basic End"

Then, some handy setup macros. For example:

.macro Go80 () {
lda MODE // are we in 80 columns mode?
bmi !+ // bit 7 set? then yes
jsr SWAPPER // swap mode to 80 columns

Isn't that nice? Entering Go80() beats remembering and typing in that code. I can now also use this macro:


Which will also switch to 80 or 40 column mode. This is the macro code for that:

.macro DoEscapeCode (code) {
lda #code

And it allows easy access to the other escape codes as well.

These are one-off calls. They accept parameters and will therefore generate specific code for specific situations, mostly during setup, and they can be added into the code when required. Some code is better added as subroutines though, for example: writing to a VDC register:

.macro WriteVDC () {
!: bit VDCADR
bpl !-

This can be added as a subroutine to object code like so:


It can then be called multiple times, like this:

ldx #26 // modify register 26, colour.
lda #010011 // left nybble is BG, right is FG

This will change the background and character colour on the 80 columns display.

Memory Management (Unit)

One of the first things to tackle when using the C128 is the use of the MMU. Especially when mixing Basic and machine code.

Check out this memory map overview. We will get back to it later:

This can be quite confusing, so I created a macro which will make selecing the proper bank configuration easier, as the values as used in the BASIC Bank command can be used, and some custom configuration when I do so choose to add them:

.macro SetBank(id) {
.if(id==0) {
lda #111111 // no roms, RAM 0
.if(id==1) {
lda #%01111111 // no roms, RAM 1
.if(id==12) {
lda #000110 // int.func. ROM, Kernal, IO, RAM 0
.if(id==14) {
lda #000001 // all roms, char ROM, RAM 0
.if(id==15) {
lda #000000  // all roms, RAM 0. default.
.if(id==99) {
lda #001110  // IO, kernal, RAM0. No basic

So, adding SetBank(15) to my source code will enable the default bank configuration.

First Test

This is the code for a first test I've made. It sets up some default stuff, and it then fills the 80 column display with a character, and changes the colour of the display.

#import "c128system.asm"
#import "c128macros.asm"

:BasicUpstart128(MAIN) // I like to use : to indicate a macro call.

:SetBank(15) // set bank 15

ldx #18 // register 18 = update address hi
lda #$00
jsr WRITE_VDC // write 0
inx // register 19 = update address lo
jsr WRITE_VDC // write 0

ldy #0 // byte counter
lda #8 // page counter
sta $fa

ldx #31 // we write to the data register
// data will be passed to address defined by 18-19
lda #$66 // we write this char to screen memory
bne !- // byte loop
dec $fa
bne !- // page loop

ldx #26 // modify register 26, colour.
lda #010011 // left nybble is BG, right is FG

// assemble sub routines.


That's it for now. I will keep trying new things and post about them.  At this time, I am not sure what I want to program on the C128, but I have a few ideas... 

Till next time!

Friday, 24 November 2017

C64 Reloaded MK2, Jiffydos, and the 1541 Ultimate II+

In a Jiffy!

Using the new Reloaded MK2 motherboard for the C64 in combination with the 1541 Ultimate II+ cartridge has made it ridiculously easy to use Jiffydos without the fuss of opening up hardware and lifting chips from sockets.

Jiffydos is great. It speeds up disk operations and adds easier to use commands to work with the disk drive and floppies. Technical details can be found here, and also instructions how to use it: https://www.c64-wiki.com/wiki/JiffyDOS

We need two kernal ROM images: the one for the C64 itself, and the ROM that needs to be used in the disk drive.  These can be acquired from various places.

Let's set those ROMs to work.

Upload kernal to the Reloaded MK2

The kernal ROM needs to be uploaded to the motherboard by using the USB file transfer method.

I use Linux Mint, with Minicom.  In order for xmodem file transfers over serial to work, and not report "failure executing protocol", an Y/Z modem needs to be installed. I do not know why this doesn't work out of the box, but entering sudo apt-get install lrzsz in a terminal window did the trick for me.  I love Google.

Sending the file to the board takes a few seconds:

NOTE: After uploading, the ROMs list does not show that an image has been uploaded to the board. So make a note on which ROM you put in which slot.

Activating the Jiffydos Kernal

Selecting M and then K gets you into the kernal ROM select menu:

Memory and ROM selection
C -   Select character ROM
E -   Select function of extra image
I -   Memory initialization pattern
K -   Select kernal ROM

X -   Exit menu
Select kernal ROM
D -   Use default kernal ROM
1 ==> Use custom kernal ROM image 1
2 -   Use custom kernal ROM image 2
3 -   Use custom kernal ROM image 3

X -   Exit menu

Select option 1 to select the kernal ROM we uploaded.

Make sure to use menu "W - Write settings" to save the settings. From now on, the MK2 will start with this kernal activated.

Now, the C64 to be restarted, or the menu item "Z - Reinitialize memory and reload ROM images from flash" needs to be executed. After restarting, my C64 shows that Jiffydos is loaded:

We can make selecting the kernal ROMs a bit easier though by changing the setting in the "K - Configure Keys (RESTORE and RESET/POWER)" menu. I changed the long press of the reset button to switch between custom image 1 and the default kernal ROM.

Configure long press RESET/POWER function
1 ==> Toggle between default kernal and custom image 1
2 -   Cycle through default kernal and custom image 1, 2
3 -   Cycle through default kernal and all custom images
C -   Toggle between default and custom character ROM
R -   Reset machine
S -   Toggle between SID-1 and SID-2 (when set to mono)

After performing this action (hold the reset button for at least 5 seconds) you need to reset the machine to activate the other kernal ROM. So hold, and then short press the reset button.

ROM upload to the 1541 Ultimate II+

Next, we need to set the 1541 Ultimate II+ to use the Jiffydos kernal ROM for its drive. This is done by first locating the ROM on the USB stick and selecting it.

This will open a menu, allowing you to use it as a drive ROM:

Selecting the ROM tells you what to do next:

Lets do what we're told: lets change the drive A ROM to Custom. This is done by going into the settings menu F2 and then selecting the drive A settings option:

Press ENTER and we're done.


We can now use Jiffydos in combination with the 1541 Ultimate II+. Really nice! Fastload without taking a cartridge slot, and handy shortcut commands when using diskettes:

Thursday, 23 November 2017

C64 Reloaded MK2 review and build

Some time ago I preordered the new motherboard for the C64: the Reloaded MK2. Let's play!

Product Overview

The C64 Reloaded MK2 board comes with a nice one-sheet giving an overview of the layout, connectors and features.

A more detailed explanation of the board can be found here:

After taking the board from the plastic wrapper, you are faced with this. I liked the coloured sockets of the MK1 board, but this is a sleek look, really nice!


I gathered a few donor machines when I ordered the MK2 board, and when I got the confirmation that the board was shipped I started desoldering the required chips:

2x CIA
1x 6510
1x SID

Having a few spare boards, I acquired a small collection of these so I could play around with them when needed. And it was needed.

The board is powered by 12V DC, at 1 or 2 amp. I had a spare power supply lying about, so no problem there.

As the case I was going to use is a C64C case, I also needed a keyboard, and the required clamps on which the keyboard rests. The clamps were pulled from a spare C64C. The keyboard came from an early C64, as I like the bright function keys.

Fitting the chips

Fitting chips is easy: lift the handle, drop in the chip, and move the handle down. The notch on the chip needs to face the handle.

Start up

When I powered up the board for the first time, I got no video, and the error led on the board was flashing.  As it does this on all errors this didn't tell me much, but the board has a great feature: USB access to a debugging and configuration menu!

I attached the cable to the USB port near the tape connector and started Minicom.

NOTE: It is important to turn off hardware flow control on the serial connection settings. If this is not done (it is enabled by default) you will not be able to send input to the board.

Pressing I to see the chip information. It shows the fitted chips. If anything is not recognised by what ever reason it can be seen here.

Two of the three SID chips I had acquired turned out to be faulty (they showed up as 'unidentified', and the one I have in there now (which works) has an issue when playing samples. They are too low in volume, and are barely audible. And yes, it is a 6581.

Also, as I got my chips from a collection of donor machines, I had to play around with the mixing of the cpu and cia chips. In the end it all turned out ok.

The chipset (menu item I) information is now:

SID 2 showing up as Unknown is because there is no chip in the second socket until I can get more replacements.

This menu does not show the CIA chips, which I think is a bad omission as I had to replace these as well. Why does it not show them? Hopefully a future update will add more chipset information.

Fitting the board

A long, long time ago I bought a transparant C64C case. The idea had always been to add a new board to this case, so now was the time to finally do it!

Adding the keyboard was a bit of an issue. After adding the keyboard I noticed that the power button was touching the underside of the hole in the case, causing the power button to stay in the on position.  You can also see that the joystick ports are almost touching the bottom case holes as well:

It turned out that the left keyboard bracket needed a little adjusting, as it was touching joystick port 2:

Some bracket parts were bent to make sure that the bracket would rest correctly on the motherboard. Your mileage may vary.

After closing everything up I had a perfect fit:

So far I am really pleased. The MK2 looks great, has nice hardware features, and has options that will enable us to do things with the C64 we could not do without hardware hacks and soldering.

I'll be posting some more when I get to play with custom ROMs, and using other hardware to see what kind of neat things we can do with this motherboard.

See you next time!