Back to the main page

Note and apology: if you downloaded the very first version of 0.2 (28th and 29th of December 2006), please download this new version which is a rapid post-release fix. If you have the corrected version, it will say "0.2a" when the emulator starts up after the music. This applies to the .d64 and .prg versions. My apologies for the inconvenience.

The Incredible KIMplement

The Incredible KIMplement is a KIM-1 emulator for the Commodore 64 (yes, this is not a joke -- see the screenshot to the right). It is a true, partial emulation of the original KIM-1 hardware featuring:

Why did I write this, instead of a (better) MESS driver, say? The KIMplement was written as a demonstration application of a software 6502 emulation I wrote for the 6502. Besides being an entertaining academic pursuit, having a software 6502 on the 6502 allows us to add features that the original didn't have, such as true virtual and protected memory models, exception processing, additional instructions, and other features needed by modern operating systems. The KIMplement shows some of this capability with its ability to trap ROM and I/O access, trap illegal instructions, and remap memory access. Plus, it was a lot of fun :-)

In the future, more hardware support will be added to the KIMplement to make it as comprehensive an emulator of the KIM-1 as possible within the constraints of the host system.

Only a stock Commodore 64 or compatible emulator is required. Simply LOAD and RUN the program to start. After the title screen, the emulated KIM will auto-reset, the LEDs will appear, and the time machine will transport you to the year 1975!

If you're an impatient little so-and-so, you can jump to the goodies, but I recommend reading the below first (especially if you have only used version 0.1, which had some significant differences).

Using the KIMplement

A complete primer on using the KIM-1 is beyond the scope of this document and it is assumed you have some familiarity. If you don't, look at the manuals on the Links and Archives page. Nevertheless, here are the basics.

The KIM-1 has six seven-segment LEDs, displayed at the top of the screen as the rightmost six LEDs of seven (the seventh LED on the far left is the KIMplement mode indicator). In the rudimentary KIM monitor, the address is displayed on the four left digits in hexadecimal, and its current contents on the rightmost two.

The KIM-1 also has a small hexadecimal keypad along with several special keys: AD to set the current address, DA to enter data, + to advance one byte, PC to see the last program counter, GO to start execution from the current address, ST to trigger an NMI (stop execution), and RS to send a reset to the machine (the contents of memory are not altered).

On startup, KIMplement displays a 'P' for 'keyPad' in the mode indicator (leftmost LED) indicating that the keyboard sends the emulated KIM presses on the keypad. Keys 0-9 and A-F send the appropriate hex digit. + sends the plus sign key. R (for 'addRess') sends an AD keypress, G sends a GO keypress, and T (for 'daTa') sends a DA keypress. The keys to send ST and RS are special and will be discussed presently.

KIMplement can also emulate a TTY connected to the emulated KIM-1 (there's a screenshot of this to the right); this emulation is modeled on an old-school ASR-33 teletype. The TTY emulation mode is triggered by pressing RUBOUT, which is mapped to the INST/DEL key. Press the INST/DEL key firmly and hold it briefly, as there is a race condition in the KIM-1 ROM accentuated by the slower system speed. The mode indicator will change to 'b' for 'keyBoard' indicating TTY mode. In this mode, KIM types out the current address and contents to the console and waits for input. There is no punch tape reader function, although you can try to save to punched tape (the data stream is simply echoed to the console). Use the same keys indicated in the KIM-1 User Manual for sending TTY commands. Special ASR-33 keys and control sequences are mostly supported; here are the ones in this version:

In addition, most control sequences are active, such as CTRL-G for BEL (which will ring an emulated bell). And, of course, the Commodore keyboard already has the ASR-33's backarrow (now you know where PETSCII came from). Graphic characters are ignored, as is any character code over 127. There are no shifted letters because ASCII-1963 and the ASR-33 didn't have them.

If the TTY isn't responding to commands, the race condition probably got triggered. Press INST/DEL, repeatedly if needed, until the TTY responds. Remember to press it firmly. This symptom is a lot less frequent now than in previous versions because the CPU emulation is faster, but still possible to trigger.

You may freely switch between keyPad and keyBoard modes at any time (many programs will only take input from the keypad, for example). To silently enter keyBoard mode from keyPad without sending RUBOUT, press SHIFT (the screen will turn white) and release it. Note that since SHIFT is obviously an active TTY key, to shift back to keyPad mode, hold down SHIFT and press the Commodore key (the screen will turn cyan), and then release both keys. The mode indicator will always show what type of input method KIMplement is facilitating, but note that this will not change where the KIM monitor or the currently running program is expecting input from -- if you were in keyPad mode, you must return to keyPad mode to get the monitor to respond to your commands, for example. Similarly, programs hardcoded to accept information from the emulated TTY must be in keyBoard mode, such as TinyBASIC. Remember that to get the KIM monitor to acknowledge the TTY, you must press rubout (INST/DEL) to switch the KIM-1 to TTY mode as described above, and to once again get the KIM monitor to accept keypad input, the emulated KIM must be reset (see the entry on the RS key below).

To stop the currently executing program on a KIM-1, an NMI (Non-Maskable Interrupt) is sent by pressing the ST key on the keypad. In keyPad mode, the CTRL key is mapped to ST; press CTRL (the screen will turn purple) and release it. Since CTRL is also an active key in TTY mode, hold down CTRL and press the Commodore key (the screen will turn purple), and then release both keys, to trigger NMI in keyBoard mode. The emulator will automatically switch to keyPad mode on an NMI. For the ST key to properly operate on a KIM, as well as in the KIMplement, the NMI vector at locations $17fa-b must have bytes $00 and $1c in them respectively. To enter this in keyPad mode, use the following sequence:

[AD] 1 7 F A [DA] 0 0 [+] 1 C [+]

In keyBoard mode, use the following sequence:

1 7 F A [space] 0 0 . 1 C .

If this vector is not set, the emulated KIM-1 may crash or lock up in an endless loop on NMI! If that happens, you will need to reset the KIM with the Commodore key; see below.

During operation, the emulated CPU may return error or information conditions to the KIM emulator. When a CPU condition occurs, the border will flash and the emulator will report the condition and the current emulated 6502 state. BRK is handled "transparently" since many KIM applications use it as a software interrupt; it will flash the border white-and-black, then automatically trigger the IRQ, load up the stack, set the emulated B-flag and continue execution through the 6502's IRQ vector as usual. However, nothing is printed on the screen otherwise to avoid interference with normal operations. The other messages are fatal errors and the emulator will force you to non-destructively reset the emulated CPU (illegal instruction, memory fault, consistency error [bug in the CPU emulation! ack!], etc.). This will restart the KIM, but memory should remain intact (assuming the errant program hasn't trashed it). Do note that for BRK instructions to properly function, the vector at $17fe should be properly set (or set to $1c00, as in the example above for $17fa). If you get an endless loop of BRKs, you will need to reset the machine (see below).

The main menu, along with the reset command, is accessed with the Commodore key in both keyPad and keyBoard modes. Press the Commodore key (the screen will turn red) and release it; the emulator will pause, display the current state of the emulated CPU, and present options. From here, you can:

The toggle menu lists several user-configurable options for the emulator. In this version, two are supported: toggling ROM SCANDS support (see Technical and compatiblity notes), and toggling the SST "Single-STep" switch. To toggle the appropriate option, press the number listed to toggle the value (0=off, 1=on). When finished setting toggle switches, press T to return to the main menu. Toggle switch settings are not saved when you leave the emulator.

The SST mode is important and deserves additional explanation. When SST mode is activated, for any code that is not in ROM (at locations $1800-$1fff), an NMI is triggered immediately after each instruction executes, thus allowing single stepping through code (press GO or type 'g' depending on keyPad/keyBoard mode to keep stepping). Because SST mode uses NMIs to single-step, the NMI vector must be set at $17fa-b as described above, or the emulated CPU may crash! The emulator automatically switches back to keyPad mode on each step.

To load or save files, type 'L' or 'S' respectively from the main menu. To load a file from disk, the file should be stored as a regular .prg file on the default disk drive. KIMplement prefers that such files have (and files saved will have) an apparent starting address of 16384 ($4000) plus the starting address in the emulated KIM's addressing space; this is because the KIM-1's RAM is stored at this location in the C64, with the addressing space extending in the C64 from $4000-$7fff. However, since there are many raw binaries without a starting address, KIMplement will also allow you to specify a starting address for those types of files. To indicate that there is a valid starting address on the file, after pressing L, press K to indicate that this is a KIMplement-style .prg file. Otherwise, press B to indicate it is a raw binary and the KIMplement will ask you where you want to load it. Note that KIMplement rigidly enforces its addressing range and will refuse to load a program that doesn't have a valid starting address in this 16K block, and if the loaded file extends outside of this range KIMplement will force you to cold start the emulator from scratch to protect itself, potentially losing your work! To cancel a load, simply enter a blank filename. On a successful load, KIMplement will report the starting and ending addresses (inclusive) of any memory locations changed as a verification measure.

You will note that since the ROMs lie between $1800 and $1fff (real locations $5800 and $5fff), you can overwrite them with your own ROMs. This should be considered a feature, and is useful and even supported, but there are important emulator-specific limitations you should read first.

To save a file from disk, enter the desired filename, and then the starting and ending addresses (inclusive; do not enter ending address + 1) in hexadecimal. Give the addresses relative to KIM RAM; KIMplement will save the file to disk with the proper starting address and return the DOS error code, if any. Enter a blank entry at any time to cancel the save operation.

Technical and compatibility notes

The Incredible KIMplement emulates enough of the hardware to get the KIM-1 ROMs functional, and many applications as well. Its major disadvantage is its relatively poor execution time (relative to a native 6502).

KIMplement uses a KIM-4-style memory map for its expanded RAM emulation, with two changes: first, RAM exists in *every* location between $0000 and $1700, whereas a real KIM with most 4K low-RAM expansion boards typically only had RAM up to $1400. This is done for efficiency reasons rather than special-casing this little-used section of addressing space, but if you want your programs to be guaranteed to work on as wide a range of configurations as possible, don't take that block of RAM between $1400 and $1700 for granted. Second, above $4000, the unmapped addressing range is hardwired to return $ff on purpose; this forces an immediate illegal instruction exception if the program counter gets into this range, greatly facilitating debugging. KIMplement correctly mirrors $17f8-$17ff to $fff8-$ffff, just like a real KIM-4.

There are certain elements of the KIM hardware that KIMplement does not presently emulate. In particular, the RIOT emulation is incomplete; besides only kludgy support for terminal and keypad lines, the most important deficiency is interval timer support. A full-speed and completely cycle-accurate software emulation will never be possible on the stock ~1MHz Commodore 64 because the timers also offer a mode where every single pulse of the KIM's own 1MHz clock is counted by the timer -- impossible because the instructions merely to do the counting, let alone the 64's own IRQs and housekeeping and the rest of the emulator itself, require much more time than a single clock cycle. I am considering adding a feature where the right number of ticks are counted, but in groups based on the 60Hz Timer A IRQ, or possibly even using the 64's CIAs to count 64's own clock pulses at its similar clock speed as long as this does not greatly impact performance -- since the sorts of applications needing this support typically use it for real time triggering, it's important that the interval timers themselves run in real time, not by counting slower "emulated clock ticks." However, I haven't implemented either scheme yet and in any case either option might still not be accurate enough for certain applications. (The rest of the RIOT feature set is not so constrained and I will gradually add more accurate I/O sensing and similar features into future versions.)

A related problem is that several segments of the KIM-1 ROM were written assuming that the CPU ran at a fixed 1.000MHz -- a real trick when the 64's own 6510 is itself running at approximately that same speed as we explained above. There is no way the stock C64 can keep up with this, so for these problematic areas of ROM, the emulator actually traps calls to these routines and replaces them with native kernel-level code. In particular, the routines to flash the LEDs, read the keypad, send characters to the TTY and receive characters from the TTY have been replaced with native-mode traps, and certain startup routines are also diverted.

Because this requires the emulator to trap the emulated 6502 at certain locations in ROM, this also means that these locations must be valid for arbitrary entry. Currently, the following routines (referenced by symbol name in the KIM-1 disassembly as it appears in the User Manual) must remain at their documented entry points:

In addition, location $1fd4 must contain an RTS ($60), and locations $1f16-$1f18 and locations $1f5e-$1f62 must also be identical to their contents in the original KIM ROMs (hex 49 ff 60 and hex e8 e8 a4 fc 60 respectively), as the emulator uses these sections of code to improve native compatibility.

As previously mentioned, you can replace the built-in ROMs with your own ROMs, but because of the emulator's current architecture your custom ROMs must obey all of the entry point constraints noted above (both to enable compatibility with KIM-1 application programs, and to make sure that ROM traps do not fail or the emulator may trap routines falsely or (worse) place the PC at the wrong instruction). Be careful with the length of your code as well: if the length of your ROM file(s) cause them to expand into KIM RAM above $2000 (real C64 location $6000), then they may not properly be write-protected because the emulator does not know they are supposed to be "ROM," and if you really go overboard and cause them to expand beyond $3fff (real C64 location $7fff), then you will corrupt the emulator, be forced to coldstart, and lose your work! To replace 6530-002, your code should be 1K in length and have a starting address of $5800 (assembled with * = $1800); to replace 6530-003 (the master ROM), your code should be 1K at length, must have valid NMI, IRQ and RESET vectors in the last six bytes!, and have a starting address of $5c00 (assembled with * = $1c00).

Unfortunately, the emulator cannot do this sort of trapping for arbitrary programs in general. Programs that depend on the interval timer may not work at all (although some programs used the LSB at $1704 as a cheap source of 'random' numbers, and in this version this shameless practise is supported [weakly] by simply copying the LSB of the C64's jiffy clock there on each emulated instruction execution). Programs that use a delay loop based on a certain number of processor cycles will run on the KIMplement, but the delay loop will be considerably longer in real time. (This is the reverse of compatibility problems with the CMD SCPU, where a program that assumed the speed of the 64 was fixed ran too fast instead.) For such programs, the delay loop will have to be recalibrated, or the program rewritten to wait for a keypress or some other external signal. Eventually these routines might be rewritten for the interval timers when this support is added.

One other note is that SCANDS, the KIM-1 ROM routine that flashes the KIM data/address LEDs and refreshes them, depends on the LEDs having some kind of afterimage to make a smooth display which the sprites simulating them obviously don't have. The ROM SCANDS operates by turning all the LEDs off after briefly lighting the display, which when in a loop at the speed this emulator runs at, causes noticible flickering. Instead, the emulated SCANDS trap (enabled by default) leaves the LEDs on after setting up the display for a smoother-looking appearance, extinguishing them only when direct access is made to the LEDs, or when a program is started. Usually this works, but if the program depends on the LEDs being extinguished immediately afterwards, the display may not function correctly. For these programs, go into the toggle menu and enable ROM SCANDS to use the old version, but have your headache medicine handy when you see what happens to the LEDs.

To-do list, and known bugs

Download

Okay, now the goodies. If you're lazy and don't want to download and run these .sdas or can't be bothered to figure out Star Commander, you can download all of these together in a .gzipped .d64 which can be turned into a real 1541 disk using Pasi Ojala's gunzip.c64. However, please, please, PLEASE read the instructions below anyway. kim2d64.d64.gz (16K)

Here are some sample programs ready-to-run in KIMplement.

Other utilities:

Acknowledgements

Send all bug-reports, comments, and wads of cash to ckaiser@floodgap.com.

Thank-yous go out to: Phil Lange (who did a lot of banging on version 0.1 and offered many suggestions and requests for 0.2), Neil H. F. Meyer, Jr., Cameron Bean, Jim Butterfield, Ruud Baltissen, Peter Jennings and Tom Pittman; apologies to Wendy Carlos and, of course, Chuck Peddle.

The KIM-1 system ROMs appear for educational purposes only, as their contents are no longer considered reasonably available under the fair use/obsolescence criterion 3 of the United States Digital Millenium Copyright Act (reference: http://www.copyright.gov/1201/ and http://www.arstechnica.com/archive/news/1067440261.html). If the authorized owner of the copyrights on these ROMs would like to assert their objection and their proof of copyright on paper, please E-mail me at the address above for contact information. This currently only applies to USA domestic users of the KIMplement; other copyright or fair use laws may apply to international users depending on your home country or region.


Back to the main page