- ✅ 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
return flg;
} else if (reg == SYSFLG1) {
uint32_t flg = sysFlg1;
+ flg |= 2; // external power present
flg |= (rtcDiv << 16);
// maybe set more stuff?
return flg;
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) {
tc2.load(value);
} else if (reg == RTCDR) {
rtc = value;
+ } else if (reg == SYNCIO) {
+ lastSyncioRequest = value & 0xFFFF;
} else if (reg == PALLSW) {
lcdPalette &= 0xFFFFFFFF00000000;
lcdPalette |= value;
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) {
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;
}
}
+
+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;
+}
+
}
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;
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;
};
}
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; }
}
-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];
}
}
+void Emulator::updateTouchInput(int32_t x, int32_t y, bool down) {
+}
+
}
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;
};
}
SOURCES += \
main.cpp \
- mainwindow.cpp
+ mainwindow.cpp \
+ pdascreenwindow.cpp
HEADERS += \
- mainwindow.h
+ mainwindow.h \
+ pdascreenwindow.h
FORMS += \
mainwindow.ui
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;
#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);
timer->setInterval(1000/64);
connect(timer, SIGNAL(timeout()), SLOT(execTimer()));
+ pdaScreen.show();
+
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()
{
#include <QMainWindow>
#include "../WindCore/emubase.h"
+#include "pdascreenwindow.h"
namespace Ui {
class MainWindow;
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
<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">
--- /dev/null
+#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);
+}
--- /dev/null
+#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