]> localhost Git - WindEmu.git/commitdiff
implement touch panel for Osaris
authorAsh Wolf <ninji@wuffs.org>
Wed, 25 Dec 2019 14:46:08 +0000 (14:46 +0000)
committerAsh Wolf <ninji@wuffs.org>
Wed, 25 Dec 2019 14:46:08 +0000 (14:46 +0000)
13 files changed:
README.md
WindCore/clps7111.cpp
WindCore/clps7111.h
WindCore/emubase.h
WindCore/windermere.cpp
WindCore/windermere.h
WindQt/WindQt.pro
WindQt/main.cpp
WindQt/mainwindow.cpp
WindQt/mainwindow.h
WindQt/mainwindow.ui
WindQt/pdascreenwindow.cpp [new file with mode: 0644]
WindQt/pdascreenwindow.h [new file with mode: 0644]

index 926c6db3a1d530fc4bc04c2b842ee53fc3a81f7a..6efb1ad47501cf1493f7afa967c67c38170424d2 100644 (file)
--- a/README.md
+++ b/README.md
@@ -21,7 +21,7 @@ Oregon Scientific Osaris (EPOC R4) features:
 
 - ✅ LCD: implemented
 - ✅ Keyboard: mostly implemented (key mappings wrong)
-- â\9d\8c Touch panel: not implemented
+- â\9c\85 Touch panel: implemented
 - ❌ Audio: not implemented
 - ❌ Serial/UART support: stubbed out
 - ❌ PCMCIA: mostly stubbed out
index 487d1b5b93efb51b9841a97e0caf801e2ae631cb..c764e9d65b7874add93c5c92231c3204c63a604a 100644 (file)
@@ -49,6 +49,7 @@ uint32_t Emulator::readReg32(uint32_t reg) {
                return flg;
        } else if (reg == SYSFLG1) {
                uint32_t flg = sysFlg1;
+               flg |= 2; // external power present
                flg |= (rtcDiv << 16);
                // maybe set more stuff?
                return flg;
@@ -64,6 +65,21 @@ uint32_t Emulator::readReg32(uint32_t reg) {
                return tc2.value;
        } else if (reg == RTCDR) {
                return rtc;
+       } else if (reg == SYNCIO) {
+               switch (lastSyncioRequest & 0xFF) {
+               case 0xC1: // DigitiserX
+                       return (touchX * 8) + 305;
+               case 0x81: // DigitiserY
+                       return (touchY * 13.53) + 680;
+               case 0x91: // MainBattery
+                       return 3000;
+               case 0xD1: // BackupBattery
+                       return 3100;
+               case 0xA1: // Reference
+                       return 1000;
+               }
+               log("SYNCIO read unknown:: req=%08x", lastSyncioRequest);
+               return 0xFFFFFFFF;
        } else if (reg == PALLSW) {
                return lcdPalette & 0xFFFFFFFF;
        } else if (reg == PALMSW) {
@@ -149,6 +165,8 @@ void Emulator::writeReg32(uint32_t reg, uint32_t value) {
                tc2.load(value);
        } else if (reg == RTCDR) {
                rtc = value;
+       } else if (reg == SYNCIO) {
+               lastSyncioRequest = value & 0xFFFF;
        } else if (reg == PALLSW) {
                lcdPalette &= 0xFFFFFFFF00000000;
                lcdPalette |= value;
@@ -337,7 +355,7 @@ const char *Emulator::identifyObjectCon(uint32_t ptr) {
        if (ptr == readVirtualDebug(0x800008AC, V32).value()) return "library";
 //     if (ptr == readVirtualDebug(0x800008B0, V32).value()) return "unk8B0"; // name always null
 //     if (ptr == readVirtualDebug(0x800008B4, V32).value()) return "unk8B4"; // name always null
-       return "???";
+       return nullptr;
 }
 
 void Emulator::fetchStr(uint32_t str, char *buf) {
@@ -405,15 +423,46 @@ void Emulator::debugPC(uint32_t pc) {
                log("DPlatChunkHw MAPPING: v:%08x p:%08x size:%08x arg:%08x",
                        virtAddr, physAddr, regionSize, a);
        }
+
+       if (pc == 0x16198) {
+               uint32_t rawEvent = getGPR(0);
+               uint32_t evtType = readVirtualDebug(rawEvent, V32).value_or(0);
+               uint32_t evtTick = readVirtualDebug(rawEvent + 4, V32).value_or(0);
+               uint32_t evtParamA = readVirtualDebug(rawEvent + 8, V32).value_or(0);
+               uint32_t evtParamB = readVirtualDebug(rawEvent + 0xC, V32).value_or(0);
+               const char *n = "???";
+               switch (evtType) {
+               case 0: n = "ENone"; break;
+               case 1: n = "EPointerMove"; break;
+               case 2: n = "EPointerSwitchOn"; break;
+               case 3: n = "EKeyDown"; break;
+               case 4: n = "EKeyUp"; break;
+               case 5: n = "ERedraw"; break;
+               case 6: n = "ESwitchOn"; break;
+               case 7: n = "EActive"; break;
+               case 8: n = "EInactive"; break;
+               case 9: n = "EUpdateModifiers"; break;
+               case 10: n = "EButton1Down"; break;
+               case 11: n = "EButton1Up"; break;
+               case 12: n = "EButton2Down"; break;
+               case 13: n = "EButton2Up"; break;
+               case 14: n = "EButton3Down"; break;
+               case 15: n = "EButton3Up"; break;
+               case 16: n = "ESwitchOff"; break;
+               }
+               log("EVENT %s: tick=%d params=%08x,%08x", n, evtTick, evtParamA, evtParamB);
+       }
 }
 
 
-int Emulator::getLCDWidth() const {
-       return 320;
-}
-int Emulator::getLCDHeight() const {
-       return 200;
-}
+const char *Emulator::getDeviceName() const { return "Osaris"; }
+int Emulator::getDigitiserWidth()  const { return 440; }
+int Emulator::getDigitiserHeight() const { return 200; }
+int Emulator::getLCDOffsetX()      const { return 60; }
+int Emulator::getLCDOffsetY()      const { return 0; }
+int Emulator::getLCDWidth()        const { return 320; }
+int Emulator::getLCDHeight()       const { return 200; }
+
 void Emulator::readLCDIntoBuffer(uint8_t **lines) const {
        if (lcdAddress == 0xC0000000) {
                int width = 320, height = 200;
@@ -568,4 +617,14 @@ void Emulator::setKeyboardKey(EpocKey key, bool value) {
        }
 }
 
+
+void Emulator::updateTouchInput(int32_t x, int32_t y, bool down) {
+       pendingInterrupts &= ~(1 << EINT2);
+       if (down)
+               pendingInterrupts |= (1 << EINT2);
+       log("Touch: x=%d y=%d down=%s", x, y, down ? "yes" : "no");
+       touchX = x;
+       touchY = y;
+}
+
 }
index 906806230588f53d84187589fbc6b33696e14307..f49452571bd806d341b8453a2eb60265a97ca845 100644 (file)
@@ -24,10 +24,12 @@ private:
        uint32_t rtc = 0;
        uint32_t rtcDiv = 0;
        uint64_t lcdPalette = 0;
+       uint16_t lastSyncioRequest = 0;
 
        uint32_t kScan = 0;
        uint8_t keyboardColumns[7] = {0,0,0,0,0,0,0};
        uint8_t keyboardExtra = 0;
+       int32_t touchX = 0, touchY = 0;
 
        Timer tc1, tc2;
        CLPS7600 pcCardController;
@@ -62,9 +64,15 @@ public:
        void loadROM(uint8_t *buffer, size_t size) override;
        void executeUntil(int64_t cycles) override;
        int32_t getClockSpeed() const override { return CLOCK_SPEED; }
+       const char *getDeviceName() const override;
+       int getDigitiserWidth() const override;
+       int getDigitiserHeight() const override;
+       int getLCDOffsetX() const override;
+       int getLCDOffsetY() const override;
        int getLCDWidth() const override;
        int getLCDHeight() const override;
        void readLCDIntoBuffer(uint8_t **lines) const override;
        void setKeyboardKey(EpocKey key, bool value) override;
+       void updateTouchInput(int32_t x, int32_t y, bool down) override;
 };
 }
index a1653f0d8a0f1e94b7e486c99ec18c5ec0fa5813..0fbf70fc36d79429c5f6dc29dc0bae7f0b0afbe7 100644 (file)
@@ -114,10 +114,16 @@ public:
        virtual void loadROM(uint8_t *buffer, size_t size) = 0;
        virtual void executeUntil(int64_t cycles) = 0;
        virtual int32_t getClockSpeed() const = 0;
+       virtual const char *getDeviceName() const = 0;
+       virtual int getDigitiserWidth() const = 0;
+       virtual int getDigitiserHeight() const = 0;
+       virtual int getLCDOffsetX() const = 0;
+       virtual int getLCDOffsetY() const = 0;
        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;
+       virtual void updateTouchInput(int32_t x, int32_t y, bool down) = 0;
 
        std::unordered_set<uint32_t> &breakpoints() { return _breakpoints; }
        uint64_t currentCycles() const { return passedCycles; }
index f7810582570e0c7f8e3b4220f328936cead6f8c1..a6623becfb8cafe1346b5cd5d441711d03c73675 100644 (file)
@@ -478,12 +478,14 @@ void Emulator::debugPC(uint32_t pc) {
 }
 
 
-int Emulator::getLCDWidth() const {
-       return 640;
-}
-int Emulator::getLCDHeight() const {
-       return 240;
-}
+const char *Emulator::getDeviceName() const { return "Series 5mx"; }
+int Emulator::getDigitiserWidth()  const { return 695; }
+int Emulator::getDigitiserHeight() const { return 280; }
+int Emulator::getLCDOffsetX()      const { return 45; }
+int Emulator::getLCDOffsetY()      const { return 5; }
+int Emulator::getLCDWidth()        const { return 640; }
+int Emulator::getLCDHeight()       const { return 240; }
+
 void Emulator::readLCDIntoBuffer(uint8_t **lines) const {
        if ((lcdAddress >> 24) == 0xC0) {
                const uint8_t *lcdBuf = &MemoryBlockC0[lcdAddress & MemoryBlockMask];
@@ -657,4 +659,7 @@ void Emulator::setKeyboardKey(EpocKey key, bool value) {
        }
 }
 
+void Emulator::updateTouchInput(int32_t x, int32_t y, bool down) {
+}
+
 }
index 469a9293d5b4899fdcd6610cf3f50273b35d46f5..36a335923fa084b3ed75c2ce551149db5564d652 100644 (file)
@@ -62,9 +62,15 @@ public:
        void loadROM(uint8_t *buffer, size_t size) override;
        void executeUntil(int64_t cycles) override;
        int32_t getClockSpeed() const override { return CLOCK_SPEED; }
+       const char *getDeviceName() const override;
+       int getDigitiserWidth() const override;
+       int getDigitiserHeight() const override;
+       int getLCDOffsetX() const override;
+       int getLCDOffsetY() const override;
        int getLCDWidth() const override;
        int getLCDHeight() const override;
        void readLCDIntoBuffer(uint8_t **lines) const override;
        void setKeyboardKey(EpocKey key, bool value) override;
+       void updateTouchInput(int32_t x, int32_t y, bool down) override;
 };
 }
index aae565c92b41a8bd572f4d513c84a501616bf1aa..9bab13161d84dacf17d5872830f575265776ecc0 100644 (file)
@@ -25,10 +25,12 @@ QMAKE_MACOSX_DEPLOYMENT_TARGET = 10.14
 
 SOURCES += \
         main.cpp \
-        mainwindow.cpp
+        mainwindow.cpp \
+        pdascreenwindow.cpp
 
 HEADERS += \
-        mainwindow.h
+        mainwindow.h \
+        pdascreenwindow.h
 
 FORMS += \
         mainwindow.ui
index b0012bc31ec9774866c19d5c562292c34ea1c1ed..3d9b87d27f74e44791c1fa4092f0fe25c25bb394 100644 (file)
@@ -12,7 +12,7 @@ int main(int argc, char *argv[])
 
        QString romFile;
        if (args.length() > 1)
-               romFile = args.first();
+               romFile = args.last();
        else
                romFile = QFileDialog::getOpenFileName(nullptr, "Select a ROM");
        if (romFile.isNull()) return 0;
index e1883d9f2be6da040fd83649d9be7de1f8fe643a..ef610d985132e3691706665a4a59083ef40c3cdc 100644 (file)
@@ -1,12 +1,13 @@
 #include "mainwindow.h"
 #include "ui_mainwindow.h"
 #include <QTimer>
-#include <QKeyEvent>
 #include "../WindCore/decoder.h"
+#include "clps7111.h"
 
 MainWindow::MainWindow(EmuBase *emu, QWidget *parent) :
     QMainWindow(parent),
        ui(new Ui::MainWindow),
+       pdaScreen(emu),
        emu(emu)
 {
     ui->setupUi(this);
@@ -20,6 +21,8 @@ MainWindow::MainWindow(EmuBase *emu, QWidget *parent) :
     timer->setInterval(1000/64);
     connect(timer, SIGNAL(timeout()), SLOT(execTimer()));
 
+       pdaScreen.show();
+
        updateScreen();
 }
 
@@ -100,67 +103,10 @@ void MainWindow::updateScreen()
        ui->codeLabel->setText(codeLines.join('\n'));
 
     // now, the actual screen
-       uint8_t *lines[1024];
-       QImage img(emu->getLCDWidth(), emu->getLCDHeight(), QImage::Format_Grayscale8);
-       for (int y = 0; y < img.height(); y++)
-               lines[y] = img.scanLine(y);
-       emu->readLCDIntoBuffer(lines);
-
-       ui->screen->setPixmap(QPixmap::fromImage(std::move(img)));
-}
-
-
-static EpocKey resolveKey(int key) {
-    switch (key) {
-       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 EStdKeyLeftCtrl;
-#else
-       case Qt::Key_Control: return EStdKeyLeftCtrl;
-#endif
-       case Qt::Key_Down: return EStdKeyDownArrow;
-       case Qt::Key_Period: return EStdKeyFullStop;
-#ifdef Q_OS_MAC
-       case Qt::Key_Control: return EStdKeyLeftFunc;
-#else
-       case Qt::Key_Meta: return EStdKeyLeftFunc;
-#endif
-       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;
-    }
-
-       if (key >= '0' && key <= '9') return (EpocKey)key;
-       if (key >= 'A' && key <= 'Z') return (EpocKey)key;
-       return EStdKeyNull;
+       pdaScreen.updateScreen();
 }
 
 
-void MainWindow::keyPressEvent(QKeyEvent *event)
-{
-       EpocKey k = resolveKey(event->key());
-       if (k != EStdKeyNull)
-               emu->setKeyboardKey(k, true);
-}
-
-void MainWindow::keyReleaseEvent(QKeyEvent *event)
-{
-       EpocKey k = resolveKey(event->key());
-       if (k != EStdKeyNull)
-               emu->setKeyboardKey(k, false);
-}
-
-
-
 
 void MainWindow::on_startButton_clicked()
 {
index 781caadb6ac05b7d4102aeb38b3711fcdada02d7..5c11efb9169ebfa14da61f56a7649fc47d7eaaa5 100644 (file)
@@ -3,6 +3,7 @@
 
 #include <QMainWindow>
 #include "../WindCore/emubase.h"
+#include "pdascreenwindow.h"
 
 namespace Ui {
 class MainWindow;
@@ -44,16 +45,13 @@ private slots:
 
 private:
     Ui::MainWindow *ui;
+       PDAScreenWindow pdaScreen;
        EmuBase *emu;
     QTimer *timer;
     void updateScreen();
     void updateBreakpointsList();
     void updateMemory();
     void adjustMemoryAddress(int offset);
-
-protected:
-    void keyPressEvent(QKeyEvent *event) override;
-    void keyReleaseEvent(QKeyEvent *event) override;
 };
 
 #endif // MAINWINDOW_H
index c2250b661d91b4ce972cdd0e99f549dd805b4554..d176e06a791d1e6a7742b0b0f0e168840bd48460 100644 (file)
@@ -25,7 +25,7 @@
     <item row="4" column="0" colspan="5">
      <widget class="QTabWidget" name="tabWidget">
       <property name="currentIndex">
-       <number>0</number>
+       <number>2</number>
       </property>
       <widget class="QWidget" name="tab">
        <attribute name="title">
diff --git a/WindQt/pdascreenwindow.cpp b/WindQt/pdascreenwindow.cpp
new file mode 100644 (file)
index 0000000..8cea790
--- /dev/null
@@ -0,0 +1,107 @@
+#include "pdascreenwindow.h"
+#include <QKeyEvent>
+
+PDAScreenWindow::PDAScreenWindow(EmuBase *emu, QWidget *parent) :
+       QWidget(parent),
+       emu(emu),
+       lcd(new QLabel(this))
+{
+       setWindowTitle("WindEmu");
+       setFixedSize(emu->getDigitiserWidth(), emu->getDigitiserHeight());
+       lcd->setGeometry(emu->getLCDOffsetX(), emu->getLCDOffsetY(), emu->getLCDWidth(), emu->getLCDHeight());
+
+       const char *who = emu->getDeviceName();
+       if (strcmp(who, "Osaris") == 0) {
+               // some cheap and cheerful placeholders
+               int bitW = (emu->getDigitiserWidth() - emu->getLCDWidth()) / 2;
+               int bitH = emu->getDigitiserHeight() / 5;
+               int leftX = 0;
+               int rightX = bitW + emu->getLCDWidth();
+               (new QLabel("Word",       this))->setGeometry(leftX, bitH * 0, bitW, bitH);
+               (new QLabel("Sheet",      this))->setGeometry(leftX, bitH * 1, bitW, bitH);
+               (new QLabel("Data",       this))->setGeometry(leftX, bitH * 2, bitW, bitH);
+               (new QLabel("Agenda",     this))->setGeometry(leftX, bitH * 3, bitW, bitH);
+               (new QLabel("Extras",     this))->setGeometry(leftX, bitH * 4, bitW, bitH);
+               (new QLabel("EPOC",       this))->setGeometry(rightX, bitH * 0, bitW, bitH);
+               (new QLabel("Menu",       this))->setGeometry(rightX, bitH * 1, bitW, bitH);
+               (new QLabel("Copy/Paste", this))->setGeometry(rightX, bitH * 2, bitW, bitH);
+               (new QLabel("Zoom In",    this))->setGeometry(rightX, bitH * 3, bitW, bitH);
+               (new QLabel("Zoom Out",   this))->setGeometry(rightX, bitH * 4, bitW, bitH);
+       }
+}
+
+void PDAScreenWindow::updateScreen() {
+       uint8_t *lines[1024];
+       QImage img(emu->getLCDWidth(), emu->getLCDHeight(), QImage::Format_Grayscale8);
+       for (int y = 0; y < img.height(); y++)
+               lines[y] = img.scanLine(y);
+       emu->readLCDIntoBuffer(lines);
+
+       lcd->setPixmap(QPixmap::fromImage(std::move(img)));
+}
+
+static EpocKey resolveKey(int key) {
+       switch (key) {
+       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 EStdKeyLeftCtrl;
+#else
+       case Qt::Key_Control: return EStdKeyLeftCtrl;
+#endif
+       case Qt::Key_Down: return EStdKeyDownArrow;
+       case Qt::Key_Period: return EStdKeyFullStop;
+#ifdef Q_OS_MAC
+       case Qt::Key_Control: return EStdKeyLeftFunc;
+#else
+       case Qt::Key_Meta: return EStdKeyLeftFunc;
+#endif
+       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;
+       }
+
+       if (key >= '0' && key <= '9') return (EpocKey)key;
+       if (key >= 'A' && key <= 'Z') return (EpocKey)key;
+       return EStdKeyNull;
+}
+
+
+void PDAScreenWindow::keyPressEvent(QKeyEvent *event)
+{
+       EpocKey k = resolveKey(event->key());
+       if (k != EStdKeyNull)
+               emu->setKeyboardKey(k, true);
+}
+
+void PDAScreenWindow::keyReleaseEvent(QKeyEvent *event)
+{
+       EpocKey k = resolveKey(event->key());
+       if (k != EStdKeyNull)
+               emu->setKeyboardKey(k, false);
+}
+
+
+void PDAScreenWindow::mousePressEvent(QMouseEvent *event)
+{
+       emu->updateTouchInput(event->x(), event->y(), true);
+}
+
+void PDAScreenWindow::mouseReleaseEvent(QMouseEvent *event)
+{
+       emu->updateTouchInput(event->x(), event->y(), false);
+}
+
+void PDAScreenWindow::mouseMoveEvent(QMouseEvent *event)
+{
+       if (event->buttons() & Qt::LeftButton)
+               emu->updateTouchInput(event->x(), event->y(), true);
+}
diff --git a/WindQt/pdascreenwindow.h b/WindQt/pdascreenwindow.h
new file mode 100644 (file)
index 0000000..e18ca78
--- /dev/null
@@ -0,0 +1,29 @@
+#ifndef PDASCREENWINDOW_H
+#define PDASCREENWINDOW_H
+
+#include <QWidget>
+#include <QLabel>
+#include "emubase.h"
+
+class PDAScreenWindow : public QWidget
+{
+       Q_OBJECT
+private:
+       EmuBase *emu;
+       QLabel *lcd;
+
+public:
+       explicit PDAScreenWindow(EmuBase *emu, QWidget *parent = nullptr);
+
+public slots:
+       void updateScreen();
+
+protected:
+       void keyPressEvent(QKeyEvent *event) override;
+       void keyReleaseEvent(QKeyEvent *event) override;
+       void mousePressEvent(QMouseEvent *event) override;
+       void mouseReleaseEvent(QMouseEvent *event) override;
+       void mouseMoveEvent(QMouseEvent *event) override;
+};
+
+#endif // PDASCREENWINDOW_H