Author Topic: Vic-20 Saga Reboot - Assistance Requested  (Read 2005 times)

0 Members and 1 Guest are viewing this topic.

Offline BlueNalgene

  • Thread Starter
  • Posts: 739
  • Location: Oklahoma, USA
Vic-20 Saga Reboot - Assistance Requested
« on: Mon, 02 March 2015, 20:06:16 »
I'm going to use this thread as a build thread for my Vic 20 project.  Previous recount of the pitfalls of the project can be found here.




I've had a little bit of time recently, so I decided to take another crack at getting the Vic-20 working again.  In that time I've acquired a Teensy2.0++.  My goal is to get the Teensy to (oh ****, we just had a decent sized earthquake, it's still going - I saw a flash outside... transformer damage?...just aftershock tremors now, carrying on) work on the Commodore keyboard interface.  I soldered some crap together to wire the input into a DIP socket. 

The real challenge is getting some programming to work with it.  I started out using the C64Key project by Mikkel Holm Olsen.  The programming was honestly a bit daunting for me, since I have never taken a good stab at C and my programming skill is lackluster.  I decided to take a stab at adapting the TRS-80 Model 100 Project by Karl Lunt to the Commodore.  I had a little bit more luck with this, but I still had trouble figuring out how to assign pins to the columns and rows of the matrix.  I decided to look at Soarer's controller, which is very popular here.  Unfortunately I only found hex files with modification macros.  This would be great if I wanted something standard and I wanted it to work without thinking.  My plan for this is a bit farther reaching with well meaning intentions to use it to teach myself coding.  I decided to look at Hasu/TMK's firmware.  This was what I was looking for.  The code is modular, with examples.  The code had enough commenting that I finally understood how pins are assigned to rows and columns.  So all this afternoon I plugged and modified and got a working first try at some code.

The layout I designed is this:
Code: [Select]
static const uint8_t PROGMEM keymaps[][MATRIX_ROWS][MATRIX_COLS] = {
    /* Layer 0: Default Layer
     *  ,---------------------------------------------------------------.  ,-----,
     *  |ESC|  1|  2|  3|  4|  5|  6|  7|  8|  9|  0|  +|  -|  £|Hom|Del|  | F 1 |
     *  |---------------------------------------------------------------|  |-----|
     *  |Ctrl |  Q|  W|  E|  R|  T|  Y|  U|  I|  O|  P|  @|  *|Fn2|Back |  | F 3 |
     * ,----------------------------------------------------------------'  |-----|
     * |Fn1|CpL|  A|  S|  D|  F|  G|  H|  J|  K|  L|  :|  ;|  =|   Rtrn|   | F 5 |
     * |---------------------------------------------------------------|   |-----|
     * | C=|Shft |  Z|  X|  C|  V|  B|  N|  M|  ,|  .|  /|Shft |UP |LFT|   | F 7 |
     * `---------------------------------------------------------------'   `-----'
     *             |      Space                       |           
     *             `----------------------------------'
     */
    KEYMAP(ESC, 1,  2,  3,  4,  5,  6,  7,  8,  9,  0, PPLS, MINS, CURRENCY_UNIT, HOME, DEL, F1, \
           LCTL, Q,   W,   E,   R,   T,   Y,   U,   I,   O,   P,   KP_ATMARK,KP_ASTERISK,FN2,BSPC, F3, \
           FN1,CLCK,A,   S,   D,   F,   G,   H,   J,   K,   L,   KP_COLON, SCOLON,KP_EQUAL_AS400,ENT, F5, \
           LGUI,LSFT,Z,   X,   C,   V,   B,   N,   M,   COMM,DOT, SLSH, RSFT,UP,LEFT, F7, \
           SPACE),

A few things on this should be noted.  As per the Vic-20 native layout, several keys are denoted with some exotic commands.  A simple example is the use of KC_KP_ASTERISK (the asterisk found on the keypad) is used on the mainboard instead of relying on shift keys.  Three keys were pulled from a list of unused keys in the TMK code: KC_CURRENCY_UNIT, KC_ATMARK, and KC_EQUAL_AS400.  I'm not sure what the reaction will be when I try using these keys.  Windows programs may not always support these character codes.  And the currency unit may default to dollars.  Also note that two keys were marked as Fn keys to use for advanced overlays later on. 

This code is based on the code for the Macway keyboard (now defunct).  For things that weren't explained, I cross referenced with the Phantom keyboard code within the same set of files. 

(pause while I submit a Did You Feel It? report to the GIS for the previously mentioned earthquake)

So I loaded everything up and strapped the Teensy to the poorly soldered converter and typed.  The keys were not registering correctly.  I decided to make a table of the keys expected vs. the keys that were actually input to the computer.

Code: [Select]
1 3 5 7 9 + £ Del

←(esc) W R Y I P * Rtrn
(return) Uarr
Lctrl a d G J L ; Larr
W S
run (fn1) Lsft X V N , / uarr
R F X
Spc Z C B M . Rsft F1
Y H V
Lgui S F H K : = F3
i K N
Q E T U O @ ↑(fn2) F5
P ,
2 4 6 8 0 - Home F7
* /
Restore(backspace) no input


The layout you see is based on the Commodore matrix, examples of which can be found here and here.  As you can plainly see.  What you type is not what you get (WYTINWYG - you'd think I typed it all in LaTeX).  I think there are some serious problems with the matrix or the diodes that I have not diagnosed yet.  More will come in the future, but this is what is currently completed.
« Last Edit: Thu, 12 March 2015, 16:08:38 by BlueNalgene »

Offline BlueNalgene

  • Thread Starter
  • Posts: 739
  • Location: Oklahoma, USA
Re: Vic-20 Saga Reboot
« Reply #1 on: Tue, 03 March 2015, 18:47:21 »
I have a bit less time to work on this project today, but I was going over the wiring, and I noticed that I had made a mistake with the wiring of my soldered converter.  I had inadvertently connected the Commodore Row0 pin to the AREF on the Teensy.  Not a huge surprise that it didn't work.  I performed the same test as before, typing in the keystrokes entered to the computer on a copy of the Commodore matrix.  This time I got:

Code: [Select]
1 3 5 7 9 + £ Del

←(esc) W R Y I P * Rtrn
(return) larr Uarr
Lctrl a d G J L ; Larr
w a s
run (fn1) Lsft X V N , / uarr
r d f x
Spc Z C B M . Rsft F1

Lgui S F H K : = F3
i j k n
Q E T U O @ ↑(fn2) F5
p l ,
2 4 6 8 0 - Home F7
* ; /
Restore(backspace) no input

We have gained some characters and lost a few others.  By doing a diff comparison with the results from yesterday (always save your data kids), we observe that we now have characters appear in the W, A, Lshift, S, E, and 4 positions - all in the same column of the matrix.  We lost characters entered by the spacebar, M, and Rshift keys.  These omissions all occur on the same row.  This is all interesting enough, but remember: the only changes made since the experiment yesterday have been to remove Row0 from AREF and placing it in its proper position (PE1).  And yet the changes we observe occur on our column 1 and row 4. 

The characters added to column 1 seem to be the characters we would expect from row 2.  Similarly, what we see in row 1 is what appears to be a jumbled up column 7.  My early prognosis is that the columns and rows are mixed up - not on the correct axes of the matrix, and in addition, some lines are missing a connection somewhere.


Based on the massive influx of comments on this project *crickets*, I'm sure that all of you were very concerned about the earthquake I reported.  I believe that this was the seismic event in question based on the time and severity.  The event is listed as magnitude 3.2, but has an intensity rating of V.  For those of you who are unaware, this is common with central plains earthquakes.  Oklahoma has had a HUGE influx of quakes lately.  It is almost surely due to the hydraulic fracturing of the large numbers of emptied wells in the region.  For those of you who have experience with earthquakes, you might think that 3.2 is kinda ****.  I hear stuff like that from people who comment on the our geology from the comfort of some other region.  The reason that the intensity is so disparate with the magnitude is due to the geological makeup of the region.  Whereas many places with common earthquakes such as California, Chile, and the rest of the ring of fire have more powerful earthquakes - the perceived intensity is much greater per magnitude unit in the plains.  The ground in most of the these ring of fire locations is much softer in deep areas that lie between the quake and the victim/user.  In the plains, there is mostly very hard rock such as granite and limestone.  This harder material transfers energy much more efficiently than soft earth.  While Oklahoma isn't likely to have mudslides or tsunamis with their quakes, we ALL feel these short sharp shocks.

So now that you have been educated about why my keyboard isn't working and how central US earthquakes differ from coastal ones, I hope you have a lovely evening.

Offline BlueNalgene

  • Thread Starter
  • Posts: 739
  • Location: Oklahoma, USA
Re: Vic-20 Saga Reboot
« Reply #2 on: Sat, 07 March 2015, 17:24:01 »
I've been messing around and having no luck figuring out how I might improve this.  Anyone feel like giving me a hand here?


Relevant code:
More
Code: [Select]
#ifndef DEBOUNCE
#   define DEBOUNCE 5
#endif
static uint8_t debouncing = DEBOUNCE;

/* matrix state(1:on, 0:off) */
static matrix_row_t matrix[MATRIX_ROWS];
static matrix_row_t matrix_debouncing[MATRIX_ROWS];

#ifdef MATRIX_HAS_GHOST
static bool matrix_has_ghost_in_row(uint8_t row);
#endif
static matrix_row_t read_cols(void);
static void unselect_rows(void);
static void select_row(uint8_t row);
static void init_cols(void);


inline
uint8_t matrix_rows(void)
{
    return MATRIX_ROWS;
}

inline
uint8_t matrix_cols(void)
{
    return MATRIX_COLS;
}

void matrix_init(void)
{
    // initialize row and col
    unselect_rows();
init_cols();
    // Input with pull-up(DDR:0, PORT:1)
    DDRF = 0x00;
    PORTF = 0xFF;

    // initialize matrix state: all keys off
    for (uint8_t i=0; i < MATRIX_ROWS; i++) {
        matrix[i] = 0;
        matrix_debouncing[i] = 0;
    }
}

uint8_t matrix_scan(void)
{
    for (uint8_t i = 0; i < MATRIX_ROWS; i++) {
        select_row(i);
        _delay_us(30);  // without this wait read unstable value.
        matrix_row_t cols = read_cols();
        if (matrix_debouncing[i] != cols) {
            matrix_debouncing[i] = cols;
            if (debouncing) {
                debug("bounce!: "); debug_hex(debouncing); debug("\n");
            }
            debouncing = DEBOUNCE;
        }
        unselect_rows();
    }

    if (debouncing) {
        if (--debouncing) {
            _delay_ms(1);
        } else {
            for (uint8_t i = 0; i < MATRIX_ROWS; i++) {
                matrix[i] = matrix_debouncing[i];
            }
        }

    }

    return 1;
}

bool matrix_is_modified(void)
{
    if (debouncing) return false;
    return true;
}

inline
bool matrix_is_on(uint8_t row, uint8_t col)
{
    return (matrix[row] & ((matrix_row_t)1<<col));
}

inline
matrix_row_t matrix_get_row(uint8_t row)
{
    return matrix[row];
}

void matrix_print(void)
{
    print("\nr/c 01234567\n");
    for (uint8_t row = 0; row < matrix_rows(); row++) {
        phex(row); print(": ");
        pbin_reverse(matrix_get_row(row));
#ifdef MATRIX_HAS_GHOST
        if (matrix_has_ghost_in_row(row)) {
            print(" <ghost");
        }
#endif
        print("\n");
    }
}

#ifdef MATRIX_HAS_GHOST
inline
static bool matrix_has_ghost_in_row(uint8_t row)
{
    // no ghost exists in case less than 2 keys on
    if (((matrix[row] - 1) & matrix[row]) == 0)
        return false;

    // ghost exists in case same state as other row
    for (uint8_t i=0; i < MATRIX_ROWS; i++) {
        if (i != row && (matrix[i] & matrix[row]))
            return true;
    }
    return false;
}
#endif

/* Col pin configuration
 * col: 0   1   2   3   4   5   6   7
 * pin: F0  F6  F5  F4  F3  F2  F1  F7
 */
inline
static void init_cols(void)
{
    // Input with pull-up(DDR:0, PORT:1)
    DDRF  &= ~0b11111111;
    PORTF |= 0b11111111;
}

static uint8_t read_cols(void)
{
    return (PINF&(1<<0) ? 0 : (1<<0)) |
           (PINF&(1<<6) ? 0 : (1<<1)) |
           (PINF&(1<<5) ? 0 : (1<<2)) |
           (PINF&(1<<4) ? 0 : (1<<3)) |
           (PINF&(1<<3) ? 0 : (1<<4)) |
   (PINF&(1<<2) ? 0 : (1<<5)) |
           (PINF&(1<<1) ? 0 : (1<<6)) | 
           (PINF&(1<<7) ? 0 : (1<<7));
}

inline
static void unselect_rows(void)
{
    // Hi-Z(DDR:0, PORT:0) to unselect
    DDRC  &= ~0b11111111; // PC: 7,6,5,4,3,2,1,0
    PORTC &= ~0b11111111;
    DDRE  &= ~0b00000010; // PE: 1
    PORTE &= ~0b00000010;
}

inline
static void select_row(uint8_t row)
{
    // Output low(DDR:1, PORT:0) to select
    // row: 0    1    2    3    4    5    6    7    8
    // pin: PE1, PC7, PC6, PC1, PC4, PC3, PC2, PC5, PC0
    switch (row) {
        case 0:
            DDRE  |= (1<<1);
            PORTE &= ~(1<<1);
            break;
        case 1:
            DDRC  |= (1<<7);
            PORTC &= ~(1<<7);
            break;
        case 2:
            DDRC  |= (1<<6);
            PORTC &= ~(1<<6);
            break;
        case 3:
            DDRC  |= (1<<1);
            PORTC &= ~(1<<1);
            break;
        case 4:
            DDRC  |= (1<<4);
            PORTC &= ~(1<<4);
            break;
        case 5:
            DDRC  |= (1<<3);
            PORTC &= ~(1<<3);
            break;
        case 6:
            DDRC  |= (1<<2);
            PORTC &= ~(1<<2);
            break;
        case 7:
            DDRC  |= (1<<5);
            PORTC &= ~(1<<5);
            break;
        case 8:
            DDRC  |= (1<<0);
            PORTC &= ~(1<<0);
            break;
    }
}










Offline BlueNalgene

  • Thread Starter
  • Posts: 739
  • Location: Oklahoma, USA
Re: Vic-20 Saga Reboot
« Reply #3 on: Thu, 12 March 2015, 16:08:24 »
I had a moment to mess around with the hardware today, so I partially disassembled the keyboard. 



I used a jumper and used it to "type" on the pads of the pcb.  I did this to check if the error was hardware related.  It went the same as before.  The same keys worked in the same strange way.  The problem is definitely software related.  I'm still hoping someone has some input here.