]> localhost Git - WindEmu.git/commitdiff
rewrite keyboard code
authorAsh Wolf <ninji@wuffs.org>
Wed, 25 Dec 2019 01:53:54 +0000 (01:53 +0000)
committerAsh Wolf <ninji@wuffs.org>
Wed, 25 Dec 2019 01:53:54 +0000 (01:53 +0000)
WindCore/clps7111.cpp
WindCore/clps7111.h
WindCore/emubase.cpp
WindCore/emubase.h
WindCore/windermere.cpp
WindCore/windermere.h
WindQt/mainwindow.cpp

index a007ad895ebadea676ea001a3288eb6ea4f4b2fb..487d1b5b93efb51b9841a97e0caf801e2ae631cb 100644 (file)
@@ -15,11 +15,12 @@ uint32_t Emulator::getRTC() {
 }
 
 
+
 uint32_t Emulator::readReg8(uint32_t reg) {
        if (reg == PADR) {
-               return readKeyboard(kScan);
+               return ((portValues >> 24) & 0x80) | (readKeyboard() & 0x7F);
        } else if (reg == PBDR) {
-               return (portValues >> 16) & 0xFF;
+               return ((portValues >> 16) & 0x0F) | (keyboardExtra << 4);
        } else if (reg == PDDR) {
                return (portValues >> 8) & 0xFF;
        } else if (reg == PEDR) {
@@ -467,4 +468,104 @@ void Emulator::diffPorts(uint32_t oldval, uint32_t newval) {
        if (changes & 0x400000) log("PRT B6: %d", newval&0x400000);
        if (changes & 0x800000) log("PRT B7: %d", newval&0x800000);
 }
+
+
+uint32_t Emulator::readKeyboard() const {
+       if (kScan & 8) {
+               // Select one keyboard
+               if ((kScan & 7) < 7)
+                       return keyboardColumns[kScan & 7];
+               else
+                       return 0;
+       } else if (kScan == 0) {
+               // Report all columns combined
+               uint8_t val = 0;
+               for (int i = 0; i < 7; i++)
+                       val |= keyboardColumns[i];
+               return val;
+       } else {
+               return 0;
+       }
+}
+
+void Emulator::setKeyboardKey(EpocKey key, bool value) {
+       int idx = -1;
+#define KEY(column, bit) idx = (column << 8) | (1 << bit); break
+
+       switch ((int)key) {
+       case '1':                KEY(0, 0);
+       case '2':                KEY(1, 0);
+       case '3':                KEY(2, 0);
+       case '4':                KEY(3, 0);
+       case '5':                KEY(4, 0);
+       case '6':                KEY(5, 0);
+       case '7':                KEY(6, 0);
+
+       case '8':                KEY(0, 1);
+       case '9':                KEY(1, 1);
+       case '0':                KEY(2, 1);
+       case 'P':                KEY(3, 1);
+       case EStdKeySingleQuote: KEY(4, 1);
+       case EStdKeyEnter:       KEY(5, 1);
+       case EStdKeyBackspace:   KEY(6, 1);
+
+       case EStdKeyEscape:      KEY(0, 2);
+       case 'Q':                KEY(1, 2);
+       case 'W':                KEY(2, 2);
+       case 'E':                KEY(3, 2);
+       case 'R':                KEY(4, 2);
+       case 'T':                KEY(5, 2);
+       case 'Y':                KEY(6, 2);
+
+       case 'U':                KEY(0, 3);
+       case 'J':                KEY(1, 3);
+       case 'I':                KEY(2, 3);
+       case 'K':                KEY(3, 3);
+       case 'O':                KEY(4, 3);
+       case 'L':                KEY(5, 3);
+       case EStdKeyUpArrow:     KEY(6, 3);
+
+       case EStdKeyTab:         KEY(0, 4);
+       case 'A':                KEY(1, 4);
+       case 'S':                KEY(2, 4);
+       case 'D':                KEY(3, 4);
+       case 'F':                KEY(4, 4);
+       case 'G':                KEY(5, 4);
+       case 'H':                KEY(6, 4);
+
+       case EStdKeySpace:       KEY(0, 5);
+       case EStdKeyComma:       KEY(1, 5);
+       case 'M':                KEY(2, 5);
+       case EStdKeyFullStop:    KEY(3, 5);
+       case EStdKeyLeftArrow:   KEY(4, 5);
+       case EStdKeyDownArrow:   KEY(5, 5);
+       case EStdKeyRightArrow:  KEY(6, 5);
+
+       case 'Z':                KEY(0, 6);
+       case 'X':                KEY(1, 6);
+       case EStdKeyMenu:        KEY(2, 6);
+       case 'C':                KEY(3, 6);
+       case 'V':                KEY(4, 6);
+       case 'B':                KEY(5, 6);
+       case 'N':                KEY(6, 6);
+
+       case EStdKeyLeftShift:   KEY(8, 0);
+       case EStdKeyRightShift:  KEY(8, 1);
+       case EStdKeyLeftCtrl:    KEY(8, 2);
+       case EStdKeyLeftFunc:    KEY(8, 3);
+       }
+
+       if (idx >= 0x800) {
+               if (value)
+                       keyboardExtra |= (idx & 0xFF);
+               else
+                       keyboardExtra &= ~(idx & 0xFF);
+       } else if (idx >= 0) {
+               if (value)
+                       keyboardColumns[idx >> 8] |= (idx & 0xFF);
+               else
+                       keyboardColumns[idx >> 8] &= ~(idx & 0xFF);
+       }
+}
+
 }
index 925b405dc19671411d7556610c7acbf3ca88e740..906806230588f53d84187589fbc6b33696e14307 100644 (file)
@@ -21,11 +21,14 @@ private:
        uint32_t sysFlg1 = 0x20008000; // constant CL-PS7111 flag and cold start flag
        uint32_t lcdControl = 0;
        uint32_t lcdAddress = 0xC0000000;
-       uint32_t kScan = 0;
        uint32_t rtc = 0;
        uint32_t rtcDiv = 0;
        uint64_t lcdPalette = 0;
 
+       uint32_t kScan = 0;
+       uint8_t keyboardColumns[7] = {0,0,0,0,0,0,0};
+       uint8_t keyboardExtra = 0;
+
        Timer tc1, tc2;
        CLPS7600 pcCardController;
        bool halted = false, asleep = false;
@@ -52,6 +55,7 @@ private:
        void fetchProcessFilename(uint32_t obj, char *buf);
        void debugPC(uint32_t pc);
        void diffPorts(uint32_t oldval, uint32_t newval);
+       uint32_t readKeyboard() const;
 
 public:
        Emulator();
@@ -61,5 +65,6 @@ public:
        int getLCDWidth() const override;
        int getLCDHeight() const override;
        void readLCDIntoBuffer(uint8_t **lines) const override;
+       void setKeyboardKey(EpocKey key, bool value) override;
 };
 }
index 86574b564017ba31920c59b28e833ee41b83da9f..33a7a3b68031dad202a5a502b633b8e962653f49 100644 (file)
@@ -1,19 +1 @@
 #include "emubase.h"
-
-uint8_t EmuBase::readKeyboard(int kScan) {
-       uint8_t val = 0;
-       if (kScan & 8) {
-               // Select one keyboard
-               int whichColumn = kScan & 7;
-               for (int i = 0; i < 7; i++)
-                       if (keyboardKeys[whichColumn * 7 + i])
-                               val |= (1 << i);
-       } else if (kScan == 0) {
-               // Report all columns combined
-               // EPOC's keyboard driver relies on this...
-               for (int i = 0; i < 8*7; i++)
-                       if (keyboardKeys[i])
-                               val |= (1 << (i % 7));
-       }
-       return val;
-}
index dba54058458df74398571215dbe292e46f84e158..a1653f0d8a0f1e94b7e486c99ec18c5ec0fa5813 100644 (file)
@@ -2,6 +2,104 @@
 #include "arm710.h"
 #include <unordered_set>
 
+enum EpocKey {
+       EStdKeyDial = 161,
+       EStdKeyOff = 160,
+       EStdKeyHelp = 159,
+       EStdKeyDictaphoneRecord = 158,
+       EStdKeyDictaphoneStop = 157,
+       EStdKeyDictaphonePlay = 156,
+       EStdKeySliderUp = 155,
+       EStdKeySliderDown = 154,
+       EStdKeyDecContrast = 153,
+       EStdKeyIncContrast = 152,
+       EStdKeyBacklightToggle = 151,
+       EStdKeyBacklightOff = 150,
+       EStdKeyBacklightOn = 149,
+       EStdKeyMenu = 148,
+       EStdKeyNkpFullStop = 147,
+       EStdKeyNkp0 = 146,
+       EStdKeyNkp9 = 145,
+       EStdKeyNkp8 = 144,
+       EStdKeyNkp7 = 143,
+       EStdKeyNkp6 = 142,
+       EStdKeyNkp5 = 141,
+       EStdKeyNkp4 = 140,
+       EStdKeyNkp3 = 139,
+       EStdKeyNkp2 = 138,
+       EStdKeyNkp1 = 137,
+       EStdKeyNkpEnter = 136,
+       EStdKeyNkpPlus = 135,
+       EStdKeyNkpMinus = 134,
+       EStdKeyNkpAsterisk = 133,
+       EStdKeyNkpForwardSlash = 132,
+       EStdKeyEquals = 131,
+       EStdKeyMinus = 130,
+       EStdKeySquareBracketRight = 129,
+       EStdKeySquareBracketLeft = 128,
+       EStdKeyHash = 127,
+       EStdKeySingleQuote = 126,
+       EStdKeySemiColon = 125,
+       EStdKeyBackSlash = 124,
+       EStdKeyForwardSlash = 123,
+       EStdKeyFullStop = 122,
+       EStdKeyComma = 121,
+       EStdKeyXXX = 120,
+       EStdKeyF24 = 119,
+       EStdKeyF23 = 118,
+       EStdKeyF22 = 117,
+       EStdKeyF21 = 116,
+       EStdKeyF20 = 115,
+       EStdKeyF19 = 114,
+       EStdKeyF18 = 113,
+       EStdKeyF17 = 112,
+       EStdKeyF16 = 111,
+       EStdKeyF15 = 110,
+       EStdKeyF14 = 109,
+       EStdKeyF13 = 108,
+       EStdKeyF12 = 107,
+       EStdKeyF11 = 106,
+       EStdKeyF10 = 105,
+       EStdKeyF9 = 104,
+       EStdKeyF8 = 103,
+       EStdKeyF7 = 102,
+       EStdKeyF6 = 101,
+       EStdKeyF5 = 100,
+       EStdKeyF4 = 99,
+       EStdKeyF3 = 98,
+       EStdKeyF2 = 97,
+       EStdKeyF1 = 96,
+       EStdKeyScrollLock = 28,
+       EStdKeyNumLock = 27,
+       EStdKeyCapsLock = 26,
+       EStdKeyRightFunc = 25,
+       EStdKeyLeftFunc = 24,
+       EStdKeyRightCtrl = 23,
+       EStdKeyLeftCtrl = 22,
+       EStdKeyRightAlt = 21,
+       EStdKeyLeftAlt = 20,
+       EStdKeyRightShift = 19,
+       EStdKeyLeftShift = 18,
+       EStdKeyDownArrow = 17,
+       EStdKeyUpArrow = 16,
+       EStdKeyRightArrow = 15,
+       EStdKeyLeftArrow = 14,
+       EStdKeyDelete = 13,
+       EStdKeyInsert = 12,
+       EStdKeyPageDown = 11,
+       EStdKeyPageUp = 10,
+       EStdKeyEnd = 9,
+       EStdKeyHome = 8,
+       EStdKeyPause = 7,
+       EStdKeyPrintScreen = 6,
+       EStdKeySpace = 5,
+       EStdKeyEscape = 4,
+       EStdKeyEnter = 3,
+       EStdKeyTab = 2,
+       EStdKeyBackspace = 1,
+       EStdKeyNull = 0
+};
+
 class EmuBase : public ARM710
 {
 protected:
@@ -19,10 +117,9 @@ public:
        virtual int getLCDWidth() const = 0;
        virtual int getLCDHeight() const = 0;
        virtual void readLCDIntoBuffer(uint8_t **lines) const = 0;
+       virtual void setKeyboardKey(EpocKey key, bool value) = 0;
 
        std::unordered_set<uint32_t> &breakpoints() { return _breakpoints; }
        uint64_t currentCycles() const { return passedCycles; }
-
-       bool keyboardKeys[8*7] = {0};
 };
 
index 7ada0c66988c5605ebdcf8da8887972da955b647..f7810582570e0c7f8e3b4220f328936cead6f8c1 100644 (file)
@@ -28,7 +28,7 @@ uint32_t Emulator::readReg8(uint32_t reg) {
        } else if (reg == TC2CTRL) {
                return tc2.config;
        } else if (reg == PADR) {
-               return readKeyboard(kScan);
+               return readKeyboard();
        } else if (reg == PBDR) {
                return (portValues >> 16) & 0xFF;
        } else if (reg == PCDR) {
@@ -562,4 +562,99 @@ void Emulator::diffInterrupts(uint16_t oldval, uint16_t newval) {
        if (changes & 0x4000) log("INTCHG lcd=%d", newval & 0x4000);
        if (changes & 0x8000) log("INTCHG spi=%d", newval & 0x8000);
 }
+
+
+uint32_t Emulator::readKeyboard() {
+       if (kScan & 8) {
+               // Select one keyboard
+               return keyboardColumns[kScan & 7];
+       } else if (kScan == 0) {
+               // Report all columns combined
+               uint8_t val = 0;
+               for (int i = 0; i < 8; i++)
+                       val |= keyboardColumns[i];
+               return val;
+       } else {
+               return 0;
+       }
+}
+
+void Emulator::setKeyboardKey(EpocKey key, bool value) {
+       int idx = -1;
+#define KEY(column, bit) idx = (column << 8) | (1 << bit); break
+
+       switch ((int)key) {
+       case EStdKeyDictaphoneRecord: KEY(0, 6);
+       case '1':                     KEY(0, 5);
+       case '2':                     KEY(0, 4);
+       case '3':                     KEY(0, 3);
+       case '4':                     KEY(0, 2);
+       case '5':                     KEY(0, 1);
+       case '6':                     KEY(0, 0);
+
+       case EStdKeyDictaphonePlay:   KEY(1, 6);
+       case '7':                     KEY(1, 5);
+       case '8':                     KEY(1, 4);
+       case '9':                     KEY(1, 3);
+       case '0':                     KEY(1, 2);
+       case EStdKeyBackspace:        KEY(1, 1);
+       case EStdKeySingleQuote:      KEY(1, 0);
+
+       case EStdKeyEscape:           KEY(2, 6);
+       case 'Q':                     KEY(2, 5);
+       case 'W':                     KEY(2, 4);
+       case 'E':                     KEY(2, 3);
+       case 'R':                     KEY(2, 2);
+       case 'T':                     KEY(2, 1);
+       case 'Y':                     KEY(2, 0);
+
+       case EStdKeyMenu:             KEY(3, 6);
+       case 'U':                     KEY(3, 5);
+       case 'I':                     KEY(3, 4);
+       case 'O':                     KEY(3, 3);
+       case 'P':                     KEY(3, 2);
+       case 'L':                     KEY(3, 1);
+       case EStdKeyEnter:            KEY(3, 0);
+
+       case EStdKeyLeftCtrl:         KEY(4, 6);
+       case EStdKeyTab:              KEY(4, 5);
+       case 'A':                     KEY(4, 4);
+       case 'S':                     KEY(4, 3);
+       case 'D':                     KEY(4, 2);
+       case 'F':                     KEY(4, 1);
+       case 'G':                     KEY(4, 0);
+
+       case EStdKeyLeftFunc:         KEY(5, 6);
+       case 'H':                     KEY(5, 5);
+       case 'J':                     KEY(5, 4);
+       case 'K':                     KEY(5, 3);
+       case 'M':                     KEY(5, 2);
+       case EStdKeyFullStop:         KEY(5, 1);
+       case EStdKeyDownArrow:        KEY(5, 0);
+
+       case EStdKeyRightShift:       KEY(6, 6);
+       case 'Z':                     KEY(6, 5);
+       case 'X':                     KEY(6, 4);
+       case 'C':                     KEY(6, 3);
+       case 'V':                     KEY(6, 2);
+       case 'B':                     KEY(6, 1);
+       case 'N':                     KEY(6, 0);
+
+       case EStdKeyLeftShift:        KEY(7, 6);
+       case EStdKeyDictaphoneStop:   KEY(7, 5);
+       case EStdKeySpace:            KEY(7, 4);
+       case EStdKeyUpArrow:          KEY(7, 3);
+       case EStdKeyComma:            KEY(7, 2);
+       case EStdKeyLeftArrow:        KEY(7, 1);
+       case EStdKeyRightArrow:       KEY(7, 0);
+       }
+
+       if (idx >= 0) {
+               if (value)
+                       keyboardColumns[idx >> 8] |= (idx & 0xFF);
+               else
+                       keyboardColumns[idx >> 8] &= ~(idx & 0xFF);
+       }
+}
+
 }
index dead6602e185752bf0081b7a93f71f35758fb8aa..469a9293d5b4899fdcd6610cf3f50273b35d46f5 100644 (file)
@@ -23,9 +23,11 @@ private:
     uint32_t pwrsr = 0x00002000; // cold start flag
     uint32_t lcdControl = 0;
     uint32_t lcdAddress = 0;
-    uint32_t kScan = 0;
     uint32_t rtc = 0;
 
+       uint32_t kScan = 0;
+       uint8_t keyboardColumns[8] = {0,0,0,0,0,0,0};
+
     Timer tc1, tc2;
     UART uart1, uart2;
        Etna etna;
@@ -53,6 +55,7 @@ private:
     void debugPC(uint32_t pc);
        void diffPorts(uint32_t oldval, uint32_t newval);
        void diffInterrupts(uint16_t oldval, uint16_t newval);
+       uint32_t readKeyboard();
 
 public:
        Emulator();
@@ -62,5 +65,6 @@ public:
        int getLCDWidth() const override;
        int getLCDHeight() const override;
        void readLCDIntoBuffer(uint8_t **lines) const override;
+       void setKeyboardKey(EpocKey key, bool value) override;
 };
 }
index 01e07a0753b701261a93aac4f84bc6375cd16f0a..e1883d9f2be6da040fd83649d9be7de1f8fe643a 100644 (file)
@@ -110,97 +110,53 @@ void MainWindow::updateScreen()
 }
 
 
-static int resolveKey(int key) {
+static EpocKey resolveKey(int key) {
     switch (key) {
-    case Qt::Key_6: return 0;
-    case Qt::Key_5: return 1;
-    case Qt::Key_4: return 2;
-    case Qt::Key_3: return 3;
-    case Qt::Key_2: return 4;
-    case Qt::Key_1: return 5;
-    // missing 6: F13/rec
-
-    case Qt::Key_Apostrophe: return 7;
-    case Qt::Key_Backspace: return 8;
-    case Qt::Key_0: return 9;
-    case Qt::Key_9: return 10;
-    case Qt::Key_8: return 11;
-    case Qt::Key_7: return 12;
-    // missing 13: F15/play
-
-    case Qt::Key_Y: return 14;
-    case Qt::Key_T: return 15;
-    case Qt::Key_R: return 16;
-    case Qt::Key_E: return 17;
-    case Qt::Key_W: return 18;
-    case Qt::Key_Q: return 19;
-    case Qt::Key_Escape: return 20;
-
-    case Qt::Key_Enter: return 21;
-    case Qt::Key_Return: return 21;
-    case Qt::Key_L: return 22;
-    case Qt::Key_P: return 23;
-    case Qt::Key_O: return 24;
-    case Qt::Key_I: return 25;
-    case Qt::Key_U: return 26;
-    case Qt::Key_Alt: return 27; // actually Menu
-
-    case Qt::Key_G: return 28;
-    case Qt::Key_F: return 29;
-    case Qt::Key_D: return 30;
-    case Qt::Key_S: return 31;
-    case Qt::Key_A: return 32;
-    case Qt::Key_Tab: return 33;
+       case Qt::Key_Apostrophe: return EStdKeySingleQuote;
+       case Qt::Key_Backspace: return EStdKeyBackspace;
+       case Qt::Key_Escape: return EStdKeyEscape;
+       case Qt::Key_Enter: return EStdKeyEnter;
+       case Qt::Key_Return: return EStdKeyEnter;
+       case Qt::Key_Alt: return EStdKeyMenu;
+       case Qt::Key_Tab: return EStdKeyTab;
 #ifdef Q_OS_MAC
-    case Qt::Key_Meta: return 34; // Control -> Control
+       case Qt::Key_Meta: return EStdKeyLeftCtrl;
 #else
-    case Qt::Key_Control: return 34; // Control -> Control
+       case Qt::Key_Control: return EStdKeyLeftCtrl;
 #endif
-
-    case Qt::Key_Down: return 35;
-    case Qt::Key_Period: return 36;
-    case Qt::Key_M: return 37;
-    case Qt::Key_K: return 38;
-    case Qt::Key_J: return 39;
-    case Qt::Key_H: return 40;
+       case Qt::Key_Down: return EStdKeyDownArrow;
+       case Qt::Key_Period: return EStdKeyFullStop;
 #ifdef Q_OS_MAC
-    case Qt::Key_Control: return 41; // Command -> Fn
+       case Qt::Key_Control: return EStdKeyLeftFunc;
 #else
-    case Qt::Key_Meta: return 41; // Super -> Fn
+       case Qt::Key_Meta: return EStdKeyLeftFunc;
 #endif
-
-    case Qt::Key_N: return 42;
-    case Qt::Key_B: return 43;
-    case Qt::Key_V: return 44;
-    case Qt::Key_C: return 45;
-    case Qt::Key_X: return 46;
-    case Qt::Key_Z: return 47;
-    case Qt::Key_Shift: return 48;
-
-    case Qt::Key_Right: return 49;
-    case Qt::Key_Left: return 50;
-    case Qt::Key_Comma: return 51;
-    case Qt::Key_Up: return 52;
-    case Qt::Key_Space: return 53;
-    // missing 54: F14/stop
-    // missing 55: another Shift
+       case Qt::Key_Shift: return EStdKeyLeftShift;
+       case Qt::Key_Right: return EStdKeyRightArrow;
+       case Qt::Key_Left: return EStdKeyLeftArrow;
+       case Qt::Key_Comma: return EStdKeyComma;
+       case Qt::Key_Up: return EStdKeyUpArrow;
+       case Qt::Key_Space: return EStdKeySpace;
     }
-    return -1;
+
+       if (key >= '0' && key <= '9') return (EpocKey)key;
+       if (key >= 'A' && key <= 'Z') return (EpocKey)key;
+       return EStdKeyNull;
 }
 
 
 void MainWindow::keyPressEvent(QKeyEvent *event)
 {
-    int k = resolveKey(event->key());
-    if (k >= 0)
-        emu->keyboardKeys[k] = true;
+       EpocKey k = resolveKey(event->key());
+       if (k != EStdKeyNull)
+               emu->setKeyboardKey(k, true);
 }
 
 void MainWindow::keyReleaseEvent(QKeyEvent *event)
 {
-    int k = resolveKey(event->key());
-       if (k >= 0)
-        emu->keyboardKeys[k] = false;
+       EpocKey k = resolveKey(event->key());
+       if (k != EStdKeyNull)
+               emu->setKeyboardKey(k, false);
 }