My DTV mod: C64 DTV in the original C64 case |
When I first heard about the C64DTV, I knew this is what I have been waiting for.
I always wanted a clone which is compatible with the original Commodore 64, but more powerful and has
extra resources like other resolutions, more memory, etc. Fortunately the C64DTV (I own a European PAL version V2)
can be hacked many ways, and you can find a lot of
information about it on the Internet. See my references below!
I checked many hacking pages, so I knew that it is possible to attach an original disk drive via the IEC bus, and it is possible to attach PS2 keyboard to the unit. But as far as I know, no one tried to put the DTV back into an original C64 box (I can be wrong though). Then I found Lars Pontoppidan's MMC2IEC project which uses MMC/SD card for the storage and it acts like a 1541 drive (sure a little bit better). As I am experienced with microcontrollers as well as C/C++ and the assembly language, I knew that there is a way to handle the original C64 keyboard matrix with a microcontroller. Unfortunately the DTV does not have the keyboard rows/cols pinouts, so there is no perfect solution, but the PS2 implementation might be good enough for my purposes. I thought, the same microcontroller - in this case it's the Atmel ATMEGA32 with 32 I/O pins - could scan the keyboard matrix and send the necessary press and release codes on the PS2 bus to the DTV. The PS2 port on the DTV is unidirectional, it means the host never sends data to the keyboard. Great. Thanks to the other researches that cool guys have done before, I had enough knowledge about everything. I knew how to generate PS2 codes, I knew how to scan the keyboard matrix, and thanks to Lars Pontoppidan, I had a solution for the IEC interface. All I had to do is just modify the original MMC2IEC design a little bit, and implement the keyboard scanner function. I have spent about 3 weekends with this. Unfortunately the PS2 interface for the DTV has some odds. It also has some remappings, therefore my implementation had to do some workaround for special keys. For example on the C64 keyboard the key 2 has the " sign when it's shifted, the PC keyboard has the sign @. There are some other mismatches, which make my life difficult. Anyway, what you see here is the first version. I know it's not perfect, but it works. I do not want to write about the other obvious hacks for the DTV, you can find out yourselves these ones (like joy port, video fix, updating the flash, etc), just google them. I am not really concerned about the IEC and MMC stuff either, Lars did a great job. I am only writing about the keyboard matrix here.
Theory: the IEC bus has higher priority than the keyboard matrix. Whenever the IEC works - which means you load or save something - there is no keyboard scanning at all. When there is no disk handling, the microcontroller has an idle time, in this case I scan the keyboard matrix as fast as I can. Every time I compare the last scanned values with the new ones, so in case of one key there is four different states (0-pressed, 1-released) if we have the bit #1 as the old bit, and the bit #0 is the new bit:
Let me highlight some points about the schematic.
Some points about the software: The main loop in the mmc2iec.c is pretty simple. It scans the keyboard if there is nothing else to do, otherwise the IEC handler works. Obviously I initialized the keyboard handler with the InitKeyMatrix() function before I use the UpdateKeyMatrix(). While (TRUE) { // scan the keyboard normally (IDLE time) UpdateKeyMatrix(); // IEC-MMC handler (LOAD/SAVE) Interface_handler(); }Ps2.c: this is the one that sends a byte on the PS2 bus to the DTV. Simple as hell, as the PS2 port is only output for the microcontroller. I am not even sure that the parity bit generation is correct. If not, that means the DTV does not care about the parity bit. Good. C64keymtx.c: the keyboard handler module. There is an array called "r" (unsigned char r[64] PROGMEM) which contains the PS2 codes. The only one exception is the colon ":" key, which is handled differently and I used 0xff for this key. Obviously, the table contains the keys based on the schematic - as you can see, the rows and cols are mixed, but it was the easiest way to solder and I did not mind to change the bits in the software. It does not matter anyway. How it works? Read the source. It tells everything. One more thing to mention. You will find out that I used the goto statement inside the UpdateKeyMatrix() to break up the loops some cases. I know that every book says you should never use gotos. Bullshit. I use what I want to use. And besides, this is a microcontroller application where speed and space are factors. I tried some different ways. Anything else generates more code. BTW the WINAVR is just perfect, the best compiler I've ever seen. Still, some bytes matter to me. So for those who are against the goto: try to write an assembly code without braches and jumps. Good luck for that. Gotos don't mix up your code. If they do for you, you should find another job to do. Selling postcards for example. :-)
Downloads
Links and references
Things to do for the next release (just some ideas in my mind)
Addendum:
19th of Oct, 2007 |
Pictures
|