mirror of
https://github.com/Treeki/WindEmu.git
synced 2025-07-04 13:32:45 +00:00
make Osaris and 5mx emulator classes inherit from a shared base
This commit is contained in:
@ -1,10 +1,58 @@
|
||||
#include "mainwindow.h"
|
||||
#include <QApplication>
|
||||
#include <QFileDialog>
|
||||
#include <QMessageBox>
|
||||
#include "../WindCore/clps7111.h"
|
||||
#include "../WindCore/windermere.h"
|
||||
|
||||
int main(int argc, char *argv[])
|
||||
{
|
||||
QApplication a(argc, argv);
|
||||
MainWindow w;
|
||||
auto args = a.arguments();
|
||||
|
||||
QString romFile;
|
||||
if (args.length() > 1)
|
||||
romFile = args.first();
|
||||
else
|
||||
romFile = QFileDialog::getOpenFileName(nullptr, "Select a ROM");
|
||||
if (romFile.isNull()) return 0;
|
||||
|
||||
// what do we have?
|
||||
QFile f(romFile);
|
||||
f.open(QFile::ReadOnly);
|
||||
auto buffer = f.readAll();
|
||||
f.close();
|
||||
|
||||
if (buffer.size() < 0x400000) {
|
||||
QMessageBox::critical(nullptr, "WindEmu", "Invalid ROM file!");
|
||||
return 0;
|
||||
}
|
||||
|
||||
EmuBase *emu = nullptr;
|
||||
uint8_t *romData = (uint8_t *)buffer.data();
|
||||
|
||||
// parse this ROM to learn what hardware it's for
|
||||
int variantFile = *((uint32_t *)&romData[0x80 + 0x4C]) & 0xFFFFFFF;
|
||||
if (variantFile < (buffer.size() - 8)) {
|
||||
int variantImg = *((uint32_t *)&romData[variantFile + 4]) & 0xFFFFFFF;
|
||||
if (variantImg < (buffer.size() - 0x70)) {
|
||||
int variant = *((uint32_t *)&romData[variantImg + 0x60]);
|
||||
|
||||
if (variant == 0x7060001) {
|
||||
// 5mx ROM
|
||||
emu = new Windermere::Emulator;
|
||||
} else if (variant == 0x5040001) {
|
||||
// Osaris ROM
|
||||
emu = new CLPS7111::Emulator;
|
||||
} else {
|
||||
QMessageBox::critical(nullptr, "WindEmu", "Unrecognised ROM file!");
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
emu->loadROM(romData, buffer.size());
|
||||
MainWindow w(emu);
|
||||
w.show();
|
||||
|
||||
return a.exec();
|
||||
|
@ -1,19 +1,17 @@
|
||||
#include "mainwindow.h"
|
||||
#include "ui_mainwindow.h"
|
||||
#include "../WindCore/clps7111_defs.h"
|
||||
#include <QTimer>
|
||||
#include <QKeyEvent>
|
||||
#include "../WindCore/decoder.h"
|
||||
|
||||
MainWindow::MainWindow(QWidget *parent) :
|
||||
MainWindow::MainWindow(EmuBase *emu, QWidget *parent) :
|
||||
QMainWindow(parent),
|
||||
ui(new Ui::MainWindow)
|
||||
ui(new Ui::MainWindow),
|
||||
emu(emu)
|
||||
{
|
||||
ui->setupUi(this);
|
||||
ui->logView->setMaximumBlockCount(1000);
|
||||
|
||||
emu = new CLPS7111;
|
||||
emu->loadROM("/Users/ash/src/psion/Osaris.bin");
|
||||
emu->setLogger([&](const char *str) {
|
||||
ui->logView->appendPlainText(str);
|
||||
});
|
||||
@ -102,68 +100,13 @@ void MainWindow::updateScreen()
|
||||
ui->codeLabel->setText(codeLines.join('\n'));
|
||||
|
||||
// now, the actual screen
|
||||
const uint8_t *lcdBuf = emu->getLCDBuffer();
|
||||
if (lcdBuf) {
|
||||
#if 0
|
||||
QImage img(640, 240, QImage::Format_Grayscale8);
|
||||
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);
|
||||
|
||||
// fetch palette
|
||||
int bpp = 1 << (lcdBuf[1] >> 4);
|
||||
int ppb = 8 / bpp;
|
||||
uint16_t palette[16];
|
||||
for (int i = 0; i < 16; i++)
|
||||
palette[i] = lcdBuf[i*2] | ((lcdBuf[i*2+1] << 8) & 0xF00);
|
||||
|
||||
// build our image out
|
||||
int lineWidth = (img.width() * bpp) / 8;
|
||||
for (int y = 0; y < img.height(); y++) {
|
||||
uint8_t *scanline = img.scanLine(y);
|
||||
int lineOffs = 0x20 + (lineWidth * y);
|
||||
for (int x = 0; x < img.width(); x++) {
|
||||
uint8_t byte = lcdBuf[lineOffs + (x / ppb)];
|
||||
int shift = (x & (ppb - 1)) * bpp;
|
||||
int mask = (1 << bpp) - 1;
|
||||
int palIdx = (byte >> shift) & mask;
|
||||
int palValue = palette[palIdx];
|
||||
|
||||
palValue |= (palValue << 4);
|
||||
scanline[x] = palValue ^ 0xFF;
|
||||
}
|
||||
}
|
||||
#else
|
||||
QImage img(320, 200, QImage::Format_Grayscale8);
|
||||
|
||||
uint32_t lcdControl = emu->getLCDControl();
|
||||
uint64_t lcdPalette = emu->getLCDPalette();
|
||||
int bpp = 1;
|
||||
if (lcdControl & 0x40000000) bpp = 2;
|
||||
if (lcdControl & 0x80000000) bpp = 4;
|
||||
int ppb = 8 / bpp;
|
||||
|
||||
// build our image out
|
||||
int lineWidth = (img.width() * bpp) / 8;
|
||||
for (int y = 0; y < img.height(); y++) {
|
||||
uint8_t *scanline = img.scanLine(y);
|
||||
int lineOffs = lineWidth * y;
|
||||
for (int x = 0; x < img.width(); x++) {
|
||||
uint8_t byte = lcdBuf[lineOffs + (x / ppb)];
|
||||
int shift = (x & (ppb - 1)) * bpp;
|
||||
int mask = (1 << bpp) - 1;
|
||||
int palIdx = (byte >> shift) & mask;
|
||||
int palValue;
|
||||
if (bpp == 1)
|
||||
palValue = palIdx * 255;
|
||||
else
|
||||
palValue = (lcdPalette >> (palIdx * 4)) & 0xF;
|
||||
|
||||
palValue |= (palValue << 4);
|
||||
scanline[x] = palValue ^ 0xFF;
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
ui->screen->setPixmap(QPixmap::fromImage(std::move(img)));
|
||||
}
|
||||
ui->screen->setPixmap(QPixmap::fromImage(std::move(img)));
|
||||
}
|
||||
|
||||
|
||||
@ -296,8 +239,10 @@ void MainWindow::on_stepInsnButton_clicked()
|
||||
|
||||
void MainWindow::execTimer()
|
||||
{
|
||||
emu->executeUntil(emu->currentCycles() + (CLOCK_SPEED / 64));
|
||||
updateScreen();
|
||||
if (emu) {
|
||||
emu->executeUntil(emu->currentCycles() + (emu->getClockSpeed() / 64));
|
||||
updateScreen();
|
||||
}
|
||||
}
|
||||
|
||||
void MainWindow::on_addBreakButton_clicked()
|
||||
@ -332,7 +277,7 @@ void MainWindow::updateMemory()
|
||||
uint32_t virtBase = ui->memoryViewAddress->text().toUInt(nullptr, 16) & ~0xFF;
|
||||
auto physBaseOpt = emu->virtToPhys(virtBase);
|
||||
auto physBase = physBaseOpt.value_or(0xFFFFFFFF);
|
||||
bool ok = physBaseOpt.has_value() && emu->isPhysAddressValid(physBase);
|
||||
bool ok = physBaseOpt.has_value();
|
||||
if (ok && (virtBase != physBase))
|
||||
ui->physicalAddressLabel->setText(QStringLiteral("Physical: %1").arg(physBase, 8, 16, QLatin1Char('0')));
|
||||
|
||||
|
@ -2,7 +2,7 @@
|
||||
#define MAINWINDOW_H
|
||||
|
||||
#include <QMainWindow>
|
||||
#include "../WindCore/clps7111.h"
|
||||
#include "../WindCore/emubase.h"
|
||||
|
||||
namespace Ui {
|
||||
class MainWindow;
|
||||
@ -13,7 +13,7 @@ class MainWindow : public QMainWindow
|
||||
Q_OBJECT
|
||||
|
||||
public:
|
||||
explicit MainWindow(QWidget *parent = nullptr);
|
||||
explicit MainWindow(EmuBase *emu, QWidget *parent = nullptr);
|
||||
~MainWindow() override;
|
||||
|
||||
private slots:
|
||||
@ -44,7 +44,7 @@ private slots:
|
||||
|
||||
private:
|
||||
Ui::MainWindow *ui;
|
||||
CLPS7111 *emu;
|
||||
EmuBase *emu;
|
||||
QTimer *timer;
|
||||
void updateScreen();
|
||||
void updateBreakpointsList();
|
||||
|
Reference in New Issue
Block a user