#ifndef _KEYMATRIX_H_
#define _KEYMATRIX_H_

//      key, shift, code, code+shift
uint8_t keyMatrix[] = {
        0x09, 0xC9, 0x89, 0x8B, // TAB
        0xFF, 0xFF, 0xFF, 0xFF,
        0xFF, 0xFF, 0xFF, 0xFF,
        0xFF, 0xFF, 0xFF, 0xFF,
        0xFF, 0xFF, 0xFF, 0xFF,
        0xFF, 0xFF, 0xFF, 0xFF,
        0xFF, 0xFF, 0xFF, 0xFF,
        0x1B, 0x1B, 0x9B, 0xFE, // ESC, 0xFE - strange result for Shift+Code+ESC (documentation say: 0x9B)

        0x31, 0x21, 0xB1, 0xA1, // 1
        0x39, 0x28, 0xB9, 0xA8, // 9
        0x69, 0x49, 0xE9, 0xE9, // i
        0x2D, 0x5F, 0xAD, 0x7F, // -
        0x6C, 0xD0, 0xD4, 0xD8, // LEFT
        0x27, 0x22, 0x60, 0x5C, // '
        0x0D, 0xCD, 0x8D, 0x8C, // RETURN
        0x2F, 0x3F, 0xBF, 0xBF, // /

        0xFF, 0xFF, 0xFF, 0xFF,
        0x38, 0x2A, 0xB8, 0xAA, // 8
        0x75, 0x55, 0xF5, 0xF5, // U
        0x70, 0x50, 0xF0, 0xF0, // P
        0x3B, 0x2A, 0x7E, 0x7C, // ;
        0x2C, 0x3C, 0x5B, 0x7B, // ,
        0x2E, 0x3E, 0x5D, 0x7D, // .
        0x6D, 0x4D, 0xED, 0xED, // m

        0xFF, 0xFF, 0xFF, 0xFF,
        0x37, 0x26, 0xB7, 0xA6, // 7
        0x79, 0x59, 0xF9, 0xF9, // Y
        0x6B, 0x4B, 0xEB, 0xEB, // K
        0x6C, 0x4C, 0xEC, 0xEC, // L
        0x62, 0x42, 0xE2, 0xE2, // B
        0x6E, 0x4E, 0xEE, 0xEE, // N
        0x76, 0x56, 0xF6, 0xF6, // V

        0xFF, 0xFF, 0xFF, 0xFF,
        0x36, 0x5E, 0xB6, 0xDE, // 6
        0x74, 0x54, 0xF4, 0xF4, // T
        0x68, 0x48, 0xE8, 0xE8, // H
        0x6A, 0x4A, 0xEA, 0xEA, // J
        0x78, 0x58, 0xF8, 0xF8, // X
        0x63, 0x43, 0xE3, 0xE3, // C
        0x71, 0x51, 0xF1, 0xF1, // Q

        0xFF, 0xFF, 0xFF, 0xFF,
        0x35, 0x25, 0xB5, 0xA5, // 5
        0x72, 0x52, 0xF2, 0xF2, // R
        0x66, 0x46, 0xE6, 0xE6, // F
        0x67, 0x47, 0xE7, 0xE7, // G
        0x73, 0x53, 0xF3, 0xF3, // S
        0x61, 0x41, 0xE1, 0xE1, // A
        0x7A, 0x5A, 0xFA, 0xFA, // Z

        0xFF, 0xFF, 0xFF, 0xFF,
        0x34, 0x24, 0xB4, 0xA4, // 4
        0x33, 0x23, 0xB3, 0xA3, // 3
        0x65, 0x45, 0xE5, 0xE5, // E
        0x64, 0x44, 0xE4, 0xE4, // D
        0x77, 0x57, 0xF7, 0xF7, // W
        0x32, 0x40, 0xB2, 0xC0, // 2
        0xFF, 0xFF, 0xFF, 0xFF,

        0x20, 0x20, 0x20, 0x20, // SPACE
        0x30, 0x29, 0xB0, 0xA9, // 0
        0x6F, 0x4F, 0xEF, 0xEF, // O
        0x3D, 0x2B, 0xBD, 0xAB, // =
        0xC5, 0xCF, 0xD3, 0xD7, // UP
        0xC7, 0xD1, 0xD5, 0xD9, // RIGHT
        0xC4, 0xCE, 0xD2, 0xD6, // DOWN
        0x08, 0xC8, 0x88, 0x8A  // BACKSPACE
};
#endif

/*
// original translation from ASM and minor bug fixes. no optimisation and no unwinding
//======================================================================
void _007_vect_timer_irq_and_sub() {    // timer interrupt
    stopTimer();
// switch to bank 1
    R3b1 = a;
if (OBF == true) goto label_010;
    PORT2 = PORT2 & 0xF7
    _2CA_sub_send_data_to_CPU();

label_010:
    a = 0xAD;
    timer = a;
if (timerOverflowFlag == true) goto label_015;

label_015:
    startTimer();
    a = R7b1;
    a = ~a;
if (bitRead(a, bit2) == 1) goto label_028;
    R6b1--;
if (R6b1 > 0) goto label_028;
    R0b1 = 0x20;
    a = readRAM(R0b1);
    R6b1 = a;
    R0b1 = 0x29;
    a = readRAM(R0b1);
    R5b1 = a;
    a = 0xFF;
    _2A7_sub();

label_028:
    R2b1--;
if (R2b1 > 0) goto irq_exit_030;
    R2b1 = 0x02;
    a = R7b1;
    a = a | 0x80;
    R7b1 = a;


irq_exit_030:
    a = R3;
    return;                     // return from timer interrupt
}
//======================================================================
void _032_sub_main_loop() {     // Main loop
                                // jump from 09E (entry boot)
_032_sub_main_loop:
    enableExternalInterrupt();
// switch to bank 1
    disableExternalInterrupt();
    a = R7b1;
    a = ~a;
if (bitRead(a, bit7) == 1) goto _032_sub_main_loop;
    a = ~a;
    a = a & 0x7F;
    R7b1 = a;
    enableExternalInterrupt();
    a = ~a;
if (bitRead(a, bit1) == 1) goto label_052;
    R1b1 = 0x39;
    a = readRAM(R1b1);
    a--;
    writeRAM(a, R1b1);
if (a == 0) goto label_04A;
goto label_052;

label_04A:
    PORT2 = PORT2 & 0xEF;
    R5b1 = 000;
    a = 0xFD;
    _2A7_sub();

label_052:
// switch to bank 1
    a = R7b1;
    a = ~a;
// switch to bank 0
if (bitRead(a, bit0) == 1) goto _032_sub_main_loop;
    _11A_sub();
    _0DB_sub();
    a = 0x03;
    a = ~a;
    a++;
    a = a + R5;                 // uses carry, fixme
    carry = !carry;
if (carry == false) goto _032_sub_main_loop;
    _146_sub();
goto _032_sub_main_loop;
}
//======================================================================
void _068_boot_entry() {         // cold boot
    PORT2 = PORT2 & 0x7F;
    PORT2 = PORT2 & 0xB7;
// bank 1
    R7b1 = 0;
    R2b1 = 2;   // overflow counter
    R6b1 = 1;
//bank 0
    R0 = 0x20
    writeRAM(0x01, R0);
    R0++
    writeRAM(0x0F, R0);
    R0++
    writeRAM(0x02, R0);
    R0++;
    writeRAM(0x32, R0);
    R0 = 0x39;
    writeRAM(0x32, R0);
    R0 = 0x27;
    a = 0;
    writeRAM(a, R0);
    R0++;
    writeRAM(a, R0);
    R0++;
    writeRAM(a, R0);
    R4 = 0x14;
    R0 = 0x2B;

label_092:
    writeRAM(0x00, R0);
    R4--;
if (R4 > 0) goto label_092;
    a = 0xAD;
    timer = a;
    PORT2 = PORT2 | 0x80;
    startTimer();
    enableExternalInterrupt();
    enableTimerInterrupt();

//goto _032_sub_main_loop;
}
//======================================================================
void _0A0_sub_ext_irq() {       // external interrupt
// use bank1
    R3b1 = a;
    R1B1 = 0x38;
    a = readRAM(R1b1);
    R1b1 = a;
if (F1 == true) goto label_0B2;
    a = dataIn;
    writeRAM(a, R1b1);

label_0AA:
    R1b1 = 0x23;
    a = readRAM(R1b1);
    R1b1 = 0x39;
    writeRAM(a, R1b1)
    a = R3b1;
    return;                     // return from IRQ

label_0B2:
    a = dataIn;
if (a != 0 ) goto label_0C3;
    a = 0x6A;
    R0b1 = 0x08;
    writeRAM(a, R0b1);
    a = 0;
    R0++;
    writeRAM(a, R0b1);
    a = 0x01;
    PSW = a;
    disableExternalInterrupt();
    return;                     // return from IRQ

label_0C3:
if (bitRead(a, bit7) == 1) goto label_0D0;
    R7b1 = a;
    a = a & 0x010;
    R1b1 = a;
    a = PORT2
    a = a & 0xEF;
    a = a | R1b1;
    PORT2 = a;

goto label_0AA;

label_0D0:
if (bitRead(a, bit6) == 1) goto label_0AA;
    R1b1 = 0x38
    a = a & 0x03;
    a = a + 0x20;               // uses carry. fixme
    writeRAM(a, R1b1);
goto label_0AA
}
//======================================================================
void _0DB_sub() {                // call from
                                // 005a (main loop)
                                // read keyboard matrix
    R1 = 0x24;
    R5 = 0;
    R4 = 0x08;

label_0E1:
    R3 = 0x08;
    a = R4;
    a = a & 0x07;
    R0 = a;
    a = PORT2;
    a = a & 0xF8;
    a = a | R0;
    PORT2 = a;
    a = PORT1;
    carry = false;
    a = ~a;

label_0EF:
if (a == 0) goto label_0F6;
    a = a >> 1;                 // use carry fix it!
if (carry == true) goto label_0FD;

label_0F4:
    R3--;
if (R3 > 0) goto label_0EF;

label_0F6:
    R4--;
if (R4 > 0) goto label_0E1;
    R0 = 0x37;
    a= R5;
    writeRAM(a, R0);
    return;

label_0FD:
    R2 = a;
    R5++;
    a = 0x03;
    a = ~a;
    a++;
    a = a + R5;                 // use carry fixme
    c = !c;
if (carry == true) goto label_109;
goto label_0F4;

label_109:
    a = R4;
    a = a << 1;
    a = a << 1;
    a = a << 1;
    a = a & 0x38;
    R0 = a;
    a = R3;
    a = a & 0x07;
    a = a | R0;
    writeRAM(a, R1);
    R1++;
    a = R2;
    carry = false;
goto label_0F4;
}
//======================================================================
void _11A_sub() {               // call from
                                // 058 (main loop)
    a = 0;
if (TEST1 == true) goto label_120;
    a = a | 0x40;

label_120:
if (TEST0 == true) goto label_124;
    a = a | 0x20;
    R0 = a;

label_124:
    a = PORT2
    a = a & 0xF8;
    a = a | 0x02;
    PORT2 = a;
    a = PORT1;
    a = ~a;
    a = a & 0x01;
if (a == 0) goto label_135;
    a = R0;
    a = a | 0x80;
    R0 = a;

label_135:
    R1 = 0x2A;
    a = readRAM(R1);
    a = ~a;
    a++;
    a = a + R0;                 // check for carry
    carry = !carry;
if (a == 0) goto label_141;
    a = R0;
    writeRAM(R1, a);
    return;

label_141:
    a = R0;
    R1 = 0x29;
    writeRAM(a, R1);
    return;
}
//======================================================================
void _28A_sub_translate_scan_code() {   //call from
                                        // 216 (sub_146)
                                        // 26a (sub_146)
                                        // unknown parameter in accumulator
    a = a << 1;
    a = a << 1;
    a = a & 0xFC;
    R5 = a;
    R0 = 0x29;
    a = readRAM(R0);
    a = a >> 1;
    a = a >> 1;
    a = a >> 1;
    a = a >> 1;
    a = a >> 1;
    a = a & 0x03;
    a = a | R5
    a = keyMatrix(a);
    R5 = a;
    a = readRAM(R0);
    a = a & 0x80;
if (a == 0) goto label_2A5;
    a = 0x9F;
    a = a & R5;
    R5 = a;

label_2A5:
    a = R5;
    return;
}
//======================================================================
void _2A7_sub() {               // call from
                                // 026 (timer irq)
                                // 050 (main loop)
                                // 21e (sub_146)
                                // 274 (sub_146)
                                // unknown parameter in accumulator and R5
    R0 = a;
    a = a ^ 0xFE;
if (a != 0 ) goto label_2AF;
    PORT2 = PORT2 | 0x40;
    return;

label_2AF:
    a = R0;
    R0 = 0x28;

if (OBF == true) goto label_2BC;
    PORT2 = PORT2 & 0xF7;
    busOut = a;
    a = R5;
    busStatus = a;
    PORT2 = PORT2 | 0x08;
    return;

label_2BC:
    tmp = readRAM(R0);      // xch  a,@r0
    writeRAM(a, R0);
    a = tmp;

if (a == 0 ) goto label_2C3;
    R0--;
    writeRAM(0xFe, R0);
    return;

label_2C3:
    tmp = readRAM(R0);      // xch  a,@r0
    writeRAM(a, R0);
    a = tmp;

    R0--;
    writeRAM(a, R0);
    R0++;
    a = R5;
    writeRAM(a, R0);
    return;
}
//=======================================================================
void _2CA_sub_send_data_to_CPU() {
                                    //call from
                                    // 00e (timer irq)
    R0 = 0x28;
    a = readRAM(R0);
if (a == 0 ) goto label_2DA;
    R0--;
    a = readRAM(R0);
    busOut = a;
    R0++;
    a = readRAM(R0);
    writeRAM(0x00, R0);
    busStatus = a;
    PORT2 = PORT2 | 0x08
    return;

label_2DA:
    R0 = 0x29;
    a = readRAM(R0);
    busStatus = a;
    return;
}
//=======================================================================
// start with bank 0
// shitty long background function
void _146_sub() {             // call from 0x064 (main loop)

    uint8_t a, tmp8;
    uint16_t tmp16;
    bool carry;

    R0 = 0x02C;
    R4 = 0x04;

label_14A:
    a = 0xEF;
    a = a & readRAM(R0);
    writeRAM(a, R0);
    R0 +=3;
    R4--;
if (R4 > 0 ) goto label_14A;

    R1= 0x37;
    a = readRAM(R1);
if (a == 0) goto label_175;
    R7 = a;
    R1 = 0x24;

label_15B:
    a = readRAM(R1);
    R2 = a;
    R4 = 0x04;
    R0 = 0x2C;

label_161:
    a = readRAM(R0);
if (a == 0) goto label_16D;
    R0--;
    a = readRAM(R0);
    a = ~a;
    a++;

    tmp16 = (uint16_t)a + (uint16_t)R2;
    carry = tmp16 > 0xFF ? true : false;
    a = tmp16 & 0xFF;

    carry = !carry;
if (a == 0 ) goto label_1EF;
    R0++;

label_16D:
    R0 += 3;
    R4--;
if (R4 > 0) goto label_161;

label_172:
    R1++;
    R7--;
if (R7 > 0) goto label_15B;

label_175:
    R0 = 0x2C;
    R4 = 0x4;

label_179:
    a = readRAM(R0);
if (a == 0) goto label_17F;
    a = ~a;
if (bitRead(a, bit4) == 1 ) goto label_1D3;

label_17F:
    R0++;

label_180:
    R0 += 2;
    R4--;
if (R4 > 0) goto label_179;

    R1 = 0x37;
    a = readRAM(R1);
    R1 = 0x24;
if (a == 0 ) goto label_193;

    R7 = a;

label_18C:
    a = readRAM(R1);
    a++;
if ( a !=0 ) goto label_194;

label_190:
    R1++;
    R7--;
if (R7 > 0) goto label_18C;

label_193:
    return;

label_194:
    a = readRAM(R1);
    a = a ^ 0x10;
if (a == 0) goto label_190;
    R0 = 0x2C;

label_19B:
    a = readRAM(R0);
if (a == 0) goto label_1A3;
    R0 += 3;
goto label_19B;

label_1A3:
    R0--;
    a = readRAM(R1);
    writeRAM(a, R0);
    R0++;
    a = R1;
    R2 = a;
    R1 = 0x29;
    a = readRAM(R1);
    a = a & 0xE0;
    a = a | 0x08;
    writeRAM(a, R0);
    R0++;
    ramWrite(0x01, R0);
    R6 = 0x04;
    R0 = 0x2C;

label_1B8:
    a = readRAM(R0);
if (a == 0 ) goto label_1CA;
if (bitRead(a, bit3) == 1) goto label_1CA;
if (bitRead(a, bit0) == 1) goto label_1CA;
    a = a & 0xF0;
    a = a | 0x04;
    writeRAM(a, R0);
    R0++;
    R1 = 0x21;
    a = readRAM(R1);
    writeRAM(a, R0);
    R0--;

label_1CA:
    R0 +=3;
    R6--;
if (R6 > 0) goto label_1B8;
    a = R2;
    R1 = a;
goto label_190;

label_1D3:
    a = ~a;
if (bitRead(a, bit0) == 1) goto label_1E1;
    a = a & 0xF0;
    a = a | 0x01;
    writeRAM(a, R0);
    R0++;
    a = 0x02;
    writeRAM(a, R0);
goto label_180;

label_1E1:
    R0++;
    a = readRAM(R0);
    a--;
if (a == 0 ) goto label_1E9;
    writeRAM(a, R0);
goto label_180;

label_1E9:
    R0--;
    writeRAM(a, R0);
    PORT2 = PORT2 & 0xBF;
goto label_17F;

label_1EF:
    R0++;
    a = readRAM(R0);
    R3 = a;
    R0++;
    a = readRAM(R0);
    R6 = a;
    a = R0;
    R4b1 = a;                       // BANK1 used
    a = R3;
if (bitRead(a, bit3) == 1) goto label_20F;
if (bitRead(a, bit2) == 1) goto label_22B;
if (bitRead(a, bit1) == 1) goto label_249;
    a = a & 0xE0;
    a = a | 0x08;
    R3 = a;
    a = 0x01;
goto label_279;

label_20F:
    a = R6;
    a--;
if (a == 0 ) goto label_215;
goto label_279;

label_215:
    a = R2;
    a = _28A_sub_translate_scan_code(a);
    R2 = a;
    a = R3;
    a = a & 0xE0;
    R5 = a;
    a = R2;
    _2A7_sub(a, R5);
    a = R5;
    a = a & 0xF0;
    a = a | 0x04;
    R3 = a;
    R0 = 0x21;
    a = readRAM(R0);
goto label_279;

label_22B:
    a = R6;
    a--;
if (a == 0 ) goto label_231;
goto label_279;

label_231:
    a = R7b1;                   // BANK1 in use
    a = ~a;

if (bitRead(a, bit3) == 1) goto label_239;
goto label_23E;

label_239:
    R0 = 0x21;
    a = readRAM(R0);
goto label_279;

label_23E:
    a = R3;
    a = a & 0xF0;
    a = a | 0x02;
    R3 = a;
    R0 = 0x22;
    a = readRAM(R0);
goto label_279;

label_249:
    a = R6;
    a--;
if (a == 0) goto label_24F;
goto label_279;

label_24F:
    a = R3;
    a = a & 0xE0;
    R0 = 0x29;
    a = ~a;
    a++;

    tmp16 = (uint16_t)a + (uint16_t)readRAM(R0);
    carry = tmp16 > 0xFF ? true : false;
    a = tmp16 & 0xFF;

    carry = !carry;
if (a == 0) goto label_269;
    a = readRAM(R0);
    a = a & 0xE0;
    a = a | 0x04;
    R3 = a;
    R0 = 0x21;
    readRAM(R0);
goto label_279;

label_269:
    a = R2;
    a = _28A_sub_translate_scan_code(a);
    R2 = a;
    a = R3;
    a = a & 0xE0;
    a = a | 0x10;
    R5 = a;
    a = R2;
    _2A7_sub(a, R5);
    R0 = 0x022;
    a = readRAM(R0);

label_279:

    tmp8 = R4b1;                // BANK1 in use
    R4b1 = a;                   // BANK1 in use
    a = tmp8;                   // exchange R4b1 and accumulator

    R0 = a;
    a = R4b1;                   // BANK1 in use
    writeRAM(a, R0);
    R0--;
    a = R3;
    a = a | 0x10;
    writeRAM(a, R0);
    writeRAM(0xFF, R1);
goto label_172;

}
*/
