KIM-64

INTRODUCTION

Many years ago, in 1976, MOS Technologies designed the KIM-1 microcomputer system to promote their 6502 CPU. This single-boad computer offered 2KB ROM, 1KB RAM, hex keypad, 7-segment LED display and little I/O (serial and tape interface).

Let’s build a modern 6502 based single-boad computer with a more convenient user interface – the KIM-64. It is based on the well documented 6502 CPU, VIA 6522 and C64 firmware.

Features

  • USB powered 5V/200mA
  • C64 BASIC V2 (unpatched)
  • C64 KERNEL (patched)
  • C64 keyboard
  • 64KB RAM
  • Monochrome analog 40 x 25 character PAL CVBS video output
  • Onboard Supermon64 machine-language monitor
  • Onboard SD2IEC for file storage and PC transfer
  • Full screen editor with transparent video memory
  • IEC serial bus support (disk drives, printers, etc.)
  • PEEK & POKE access to Mega 2560 resources (Ports, Timers, UARTs, TWI, etc.)
  • NMOS & CMOS compatible (65xx, 65Cxx)
  • Easy memory transfer from Mega 2560 FLASH to KIM-64 RAM
  • Progammable PHI0 and Interrupt Timers

Block diagram

Block diagram of the KIM-64

Theory of operation

After reset of the Mega 2560 it copies the C64 firmware from Flash to RAM. Its timers for interrupt and clock PHI0 are started and finally RESET is set high to start 6502 CPU execution at vector $FFFC/$FFFD.

In addition to the address decoding the Main Logic halts the CPU when it’s accessing screen memory ($400-$7FF) or Mega I/O ($D000-$D0FF). The Mega 2560 processes the interrupt request and asserts ACK after finishing.

The Nano is the video controller which provides video timing and pixel data. Writing to screen memory interrupts the Mega 2560 and the address is latched during the write cycle. Now, the screen character byte is being copied from RAM to SRAM in the Mega 2560. During vertical sync the transfer of screen data from Mega to Nano takes place via SPI for the period of approximately 3 ms.
Thus there are three identical sets of the screen data: RAM, Mega SRAM, Nano SRAM
Note: Interrupts for Vertical sync and CPU halt state may interfere with each other, resulting in a delayed access on Mega I/O.

A falling edge on VIA 6522 CA1 input generates the interrupt for the 6502 CPU. Pin CA1 is driven by Timer 4 at 60 Hz. Both 8-bit ports of the VIA are used to scan the 8×8 keyboard matrix, in a similar manner to the C64.

For the connection of IEC devices like 1541, 1571, 1581, SD2IEC, etc. an IEC interface is realized by I/O logic, reduced to the bare minimum, in an ATF22V10 PLD.

Main Logic Write Timing diagram

Main Logic Read Timing diagram

KIM-64 Memory map

AddressKIM-64C64
0000, 0001RAM6510 Processor Port
$0002-$9FFFRAMRAM
$A000-$BFFFBASIC (RAM resident)BASIC ROM
$C000-$CFFFRAMRAM
$D000-$D03FRAMVIC
$D040-$D0FFMega 2560 IOVIC
$D100-$DBFFSupermon64VIC, SID, Color RAM
$DC00-$DCFFVIA 6522 (Keyboard, IRQ)CIA 6526
$DD00-$DDFFIEC InterfaceCIA 6526 IEC & User Port
$DE00-$DEFFI/O #1I/O #1
$DF00-$DFFFI/O #2I/O #2
$E000-$FFFFKERNEL (RAM resident)KERNEL ROM

Supermon64

Due to non-existend C64 VIC, SID and Color RAM the address range $D000-$DBFF became available for other purposes. The machine-language monitor Supermon64 is now occupying $D100-$DBFF. It was programmed in the 1980s by Jim Butterfield and others. Reformatted by J.B. Langston to be conform with 64tass.

To start Supermon64

  • press and hold RUN/STOP and hit RESTORE
  • during system RESET press and hold RUN/STOP
  • SYS 53504

Supermon64 command summary

CommandDescription
$ , + , & , %number conversion
Ggo (run)
Jjump (subroutine)
Lload from SD card or disk
Mmemory display
Rregister display
Ssave to SD card or disk
Xexit to basic
Asimple assembler
Ddisassembler
Ffill memory
Hhunt memory
Ttransfer memory
Ccompare memory
@disk status/command

Helpful hints

  • default for LOAD/SAVE is device #8
  • LOAD displays the directory from default device #8
  • LOAD “”,9 displays the directory from device #9
  • Tape (device #1) is not supported
  • RS232 (device #2) is not supported, use Mega 2560 UART instead
  • only capital/graphics character set is supported
  • CBM + RUN/STOP loads first file from device #8

Main Logic ABEL design

MODULE 


TITLE 'KIM-64'
"Yorck Thiele, March 2024

DEVICE  'p22V10';


"INPUTS
PHI2       pin 1; "
SYNC       pin 2; "
R_W        pin 3; "
ACK        pin 4; "
A8         pin 5; "
A9         pin 6; " 
A10        pin 7; " 
A11        pin 8; " 
A12        pin 9; " 
A13        pin 10; " 
A14        pin 11; " 
A15        pin 13; " 
RAM6502    pin 14; "

"OUTPUTS
LATCH_EN   pin 23 istype 'reg'; "
RDY        pin 22 istype 'reg'; "
!RAM_WR    pin 21 istype 'com'; "
!RAM_OE    pin 20 istype 'com'; "
!VIA1      pin 19 istype 'com'; "
!VIA2      pin 18 istype 'com'; "
!IO1       pin 17 istype 'com'; "
!IO2       pin 16 istype 'com'; "

X=.X.;

ADR_IN= [A15,A14,A13,A12,A11,A10,A9,A8, X,X,X,X,X,X,X,X];

VIDEO_ADR=((ADR_IN >= ^h0400) & (ADR_IN <= ^h07FF));
IO_ADR=   ((ADR_IN >= ^hD000) & (ADR_IN <= ^hD0FF));"MEGA2560 INTERN I/O ACCESS

EQUATIONS

LATCH_EN.CLK=PHI2;
RDY.CLK=PHI2;

RAM_WR= !(VIA1 # VIA2 #IO1 #IO2) & !R_W & PHI2;
RAM_OE= !(VIA1 # VIA2 #IO1 #IO2) & R_W;
RAM_WR.OE=RAM6502;
RAM_OE.OE=RAM6502;

when ((VIDEO_ADR # IO_ADR) & (R_W ==0) & (ACK ==0)) # ((LATCH_EN ==0) & (ACK ==0)) then LATCH_EN := 0; else LATCH_EN := 1;

when  (LATCH_EN ==0) # (IO_ADR & (R_W ==1) & (ACK ==0)) then RDY := 0; else RDY := 1;

"KIM-64 ADDRESS MAP
when (ADR_IN>= ^hDC00) & (ADR_IN<= ^hDCFF) then VIA1 = 1;
when (ADR_IN>= ^hDD00) & (ADR_IN<= ^hDDFF) then VIA2 = 1;
when (ADR_IN>= ^hDE00) & (ADR_IN<= ^hDEFF) then IO1 = 1;
when (ADR_IN>= ^hDF00) & (ADR_IN<= ^hDFFF) then IO2 = 1;

END

IEC Logic ABEL design

MODULE 

TITLE 'KIM IEC IO'
"Yorck Thiele, MAY 2024

DEVICE  'p22V10';


"INPUTS (CPU6502 SIGNALS)
R_W, CS, RESET                  PIN  13, 8, 9;

"INPUTS (INVERTED PHI2)
PHI1                            PIN  1;

"INPUTS (IEC BUS SIGNALS)
DATA_IN, CLOCK_IN               PIN  3, 4;



"OUTPUTS
IEC_RESET                       PIN 23       ISTYPE 'com';
IEC_DATA                        PIN 22       ISTYPE 'reg';
IEC_CLOCK                       PIN 21       ISTYPE 'reg';
IEC_ATN                         PIN 20       ISTYPE 'reg';

D3                              PIN 18       ISTYPE 'com';"IEC ATN OUT
D4                              PIN 17       ISTYPE 'com';"IEC CLOCK OUT
D5                              PIN 16       ISTYPE 'com';"IEC DATA OUT
D6                              PIN 15       ISTYPE 'reg';"IEC CLOCK IN
D7                              PIN 14       ISTYPE 'reg';"IEC DATA IN

EQUATIONS
IEC_DATA.clk=PHI1;
IEC_CLOCK.clk=PHI1;
IEC_ATN.clk=PHI1;
D6.clk=PHI1;
D7.clk=PHI1;

IEC_DATA.OE= !IEC_DATA & RESET;
IEC_CLOCK.OE= !IEC_CLOCK & RESET;
IEC_ATN.OE= !IEC_ATN & RESET;


IEC_RESET = 0;
IEC_RESET.OE = !RESET;

D7 := DATA_IN;
D7.OE = RESET & R_W & !CS;

D6 := CLOCK_IN;
D6.OE = RESET & R_W & !CS;

D5 = !IEC_DATA;
D5.OE = RESET & R_W & !CS;

D4 = !IEC_CLOCK;
D4.OE = RESET & R_W & !CS;

D3 = !IEC_ATN;
D3.OE = RESET & R_W & !CS;

when (RESET & !R_W & !CS) then IEC_DATA := !D5; else IEC_DATA := IEC_DATA # !RESET;

when (RESET & !R_W & !CS) then IEC_CLOCK := !D4; else IEC_CLOCK := IEC_CLOCK # !RESET;

when (RESET & !R_W & !CS) then IEC_ATN := !D3; else IEC_ATN := IEC_ATN # !RESET;

END

Download Section

KIM-64