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.

RAM


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 () {
stx VDCADR
!: bit VDCADR
bpl !-
sta VDCDAT
}

.macro ReadVDC () {
stx VDCADR
!: bit VDCADR
bpl !-
lda VDCDAT
}

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
jsr READ_VDC
sta $fb
lda #010000
bit $fb
bne small
lda #$31
jsr $ffd2
rts
small:
lda #$30
jsr $ffd2
rts

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
jsr WRITE_VDC
inx
.var a1 = <address
.var a2 = >address
.if( a1 != a2) {
lda #<address // include if different from hi-byte.
}
jsr WRITE_VDC
}


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
jsr READ_VDC
sta $fb
inx
jsr READ_VDC
sta $fc
}


Writing to this area of RAM goes like this:

:SetVDCUpdateAddress($0000)
ldy #0 // loop counter
ldx #31 // internal data register of the VCD.
!:
tya
jsr WRITE_VDC
iny
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:

:SetVDCUpdateAddress($0800)
ldy #0
lda #%01110101
ldx #31
!:
jsr WRITE_VDC
ror // crazy stuff
dey
bne !-

ldx #25 // write to this VDC register
jsr READ_VDC
ora #%01000000 // enable attributes
jsr WRITE_VDC
rts

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
jsr WRITE_VDC
inx
lda #$00
jsr WRITE_VDC

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

lda #0 // add 8 bytes as padding
!:
jsr WRITE_VDC
dey
bne !-

clc
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"
charset:
.import binary "tetris_chars2.raw"
charset_end:

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

:CopyDefinitionsToVDC(charset, charset_end)
:Go80()


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
jsr WRITE_VDC

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


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
jsr READ_VDC
and #%11110000
ora #000100      // set horizontal display to 4
jsr WRITE_VDC

ldx #23
lda #3 // vertical display to 4
jsr WRITE_VDC
rts

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
jsr WRITE_VDC
jsr DELAY
dec $fb
bpl !-
rts
DELAY:
ldx #50
ldy #0
!:
dey
bne !-
dex
bne !-
rts

Resulting in:



Conclusion


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


Introduction



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.

MMU


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


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.
}
sta MMUCR
}

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

LDA #$00
STA $FF00

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) {
lda MMURCR
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
}
sta MMURCR
}

Calling SetCommonRAM(8) generates:

LDA $FF06
AND #$FC
ORA #$02
STA $FF06

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) {
lda MMURCR
and #%11110011 // clear bits 2 and 3
ora #option*4
sta MMURCR
}

Calling SetCommonEnabled(1) generates:

LDA $FF06
AND #$F3
ORA #$04
STA $FF06

This will make the bottom 8K common only.

VIC II


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
 AND #$FC
 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) {
lda MMURCR
and #%10111111 // clear bit 6
.if(value==1) {
ora #%01111111 // enable bit 6
}
sta MMURCR
}

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!

VDC


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.

Concluding


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.

Groundwork


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
upstartEnd:
    .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:

DoEscapeCode('X')

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

.macro DoEscapeCode (code) {
lda #code
jsr JESCAPE
}

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 () {
stx VDCADR
!: bit VDCADR
bpl !-
sta VDCDAT
}

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

WRITE_VDC:
:WriteVDC()
rts

It can then be called multiple times, like this:

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

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
}
sta MMUCR
}

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.


MAIN:
:SetBank(15) // set bank 15
:Go80()

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
!:
jsr WRITE_VDC
iny
bne !- // byte loop
dec $fa
bne !- // page loop

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

// assemble sub routines.

WRITE_VDC:
:WriteVDC()
rts
READ_VDC:
:ReadVDC()
rts


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.

Result!


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:
http://wiki.icomp.de/wiki/C64_reloaded_mk2

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!





Preparations


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
1x VIC II

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!

Saturday, 9 September 2017

Review 1541 Ultimate II+

Recently I bought the new version of the 1541 Ultimate II cartridge. It is the best investment you can do when you enjoy your Commodore 64 and want to play around with games, programming, music playback and hacking.

The cartridge came with the 3.1 firmware installed, which is not available for download on the official site. Also included are a serial cable and a branded USB stick. Nice.


The case is a bit bigger than the first U2, which is needed to house more USB ports, audio connectors, a network port and micro USB power connector.  The case is a really nice quality, with a big logo on top and smooth finish.



The blue USB3 port is not a USB3 port in the traditional sense, but used for the Tape connector.


Features


A lot of features have stayed the same as the Ultimate 2. For an overview of the capabilities of the earlier version of the cartridge, see my series of posts, starting here.

Cartridges


I was really happy to see the KCS Power Cartridge in the list of supported images. I (and many Dutch people with me) used this cartridge, because of the monitor and the floppy disk turbo load features.  I never used the freeze capabilities, as I found it cumbersome.

Another new cartridge is the GeoRAM. It was a memory expansion, usable with Geos. It is slower than the REU, and its use is limited. I'll probably never use it.

Amiga Mod Audio Playback


This is really fun, and it surprised me.

A new feature is the playback of Amiga mod files. All you need to do is load up the .mod file to your USB stick, and select "play MOD" from the context menu. You must connect the audio out connector to a amplifier though.  But it's good fun to play classic mod files on the C64. You can press the function keys to enable/disable voices.


Now I need to find some classics! Any pointers?

Network Features


It is now possible to operate the U2+ through the network. The network port is configured, by default, to use DHCP. When you connect a RJ45 cable to the cartridge, you will see the IP address you need to connect to in the root of the file system (the network is displayed the same as a USB stick).

Use a telnet client to do this, and it will look like this:


It's handy to be able to browse the cartridge file systems for a new file to play while the SID or MOD file keeps playing as you browse.


What I did find is that the ESC key (close a configuration screen for example) does the same as pressing RUN-STOP on the C64, but the screen does not reflect this. Pressing an arrow key afterwards does refresh the telnet screen.


I have not tried to FTP files to the cartridge using the network as this is REALLY slow.

Gideon mentions that the FPGA in the U2+ is not (yet, hopefully) running on full speed, and is even slower than the U2.

I did not get any further than this:


Stand Alone Mode


As the cartridge can be powered using a micro USB cable, it is now possible to run it without a C64.  Also connect it to the network and you can Telnet to it, but there is not much else you can do in stand alone mode as audio playback does not work (You need a C64 to run the module or SID playback programs)

Quality of Life stuff


It is now possible to select a folder on the file system and set it as a HOME directory. The cartridge can go to this folder on start up, and/or you can go to it by pressing the Home key. Really handy if you are tired of scrolling through the HSVC folders to your favourite musician :)

It is also possible to set the device ID that is used by DMA load. This can REALLY help with multi-load games.

Conclusion


Lots of new additions made this cartridge even better than the already impressive original 1541 Ultimate 2.

The hardware features promise more exciting possibilities further down the road. I really hope RR-net functionality is coming, because BBSes baby! And also using the turbo assembler cartridge with it.

If you like your C64, and you use it on a regular basis, then this cartridge is a GREAT addon to enjoy it even more. Highly recommended!!

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 foremos...