2017-07-02 20:55:56 +01:00
|
|
|
#include "qapple.h"
|
|
|
|
|
|
|
|
#include "StdAfx.h"
|
|
|
|
#include "Common.h"
|
|
|
|
#include "Applewin.h"
|
|
|
|
#include "Disk.h"
|
|
|
|
#include "Harddisk.h"
|
|
|
|
#include "Log.h"
|
|
|
|
#include "CPU.h"
|
|
|
|
#include "Frame.h"
|
|
|
|
#include "Memory.h"
|
|
|
|
#include "ParallelPrinter.h"
|
|
|
|
#include "Video.h"
|
|
|
|
#include "SaveState.h"
|
|
|
|
|
|
|
|
#include "linux/data.h"
|
|
|
|
#include "linux/configuration.h"
|
2017-07-07 21:04:21 +01:00
|
|
|
#include "linux/benchmark.h"
|
2017-07-10 19:44:52 +01:00
|
|
|
#include "linux/joy_input.h"
|
2017-07-02 20:55:56 +01:00
|
|
|
|
2017-07-03 21:00:42 +01:00
|
|
|
#include "emulator.h"
|
|
|
|
|
2017-07-04 14:05:06 +01:00
|
|
|
#include <QMdiSubWindow>
|
2017-07-07 21:13:17 +01:00
|
|
|
#include <QMessageBox>
|
2017-07-04 14:05:06 +01:00
|
|
|
|
2017-07-02 20:55:56 +01:00
|
|
|
namespace
|
|
|
|
{
|
|
|
|
|
|
|
|
void initialiseEmulator()
|
|
|
|
{
|
|
|
|
g_fh = fopen("/tmp/applewin.txt", "w");
|
|
|
|
setbuf(g_fh, NULL);
|
|
|
|
|
2017-07-03 21:00:42 +01:00
|
|
|
InitializeRegistry("../qapple/applen.conf");
|
2017-07-10 19:44:52 +01:00
|
|
|
Input::initialise("/dev/input/by-id/usb-©Microsoft_Corporation_Controller_1BBE3DB-event-joystick");
|
2017-07-02 20:55:56 +01:00
|
|
|
|
|
|
|
LogFileOutput("Initialisation\n");
|
|
|
|
|
|
|
|
ImageInitialize();
|
|
|
|
DiskInitialize();
|
|
|
|
}
|
|
|
|
|
|
|
|
void startEmulator()
|
|
|
|
{
|
|
|
|
LoadConfiguration();
|
|
|
|
|
|
|
|
CheckCpu();
|
|
|
|
|
2017-07-04 14:05:06 +01:00
|
|
|
SetWindowTitle();
|
|
|
|
|
2017-07-02 20:55:56 +01:00
|
|
|
FrameRefreshStatus(DRAW_LEDS | DRAW_BUTTON_DRIVES);
|
|
|
|
|
|
|
|
MemInitialize();
|
|
|
|
VideoInitialize();
|
|
|
|
}
|
|
|
|
|
|
|
|
void uninitialiseEmulator()
|
|
|
|
{
|
|
|
|
HD_Destroy();
|
|
|
|
PrintDestroy();
|
|
|
|
CpuDestroy();
|
|
|
|
MemDestroy();
|
|
|
|
|
|
|
|
DiskDestroy();
|
|
|
|
}
|
|
|
|
|
|
|
|
}
|
|
|
|
|
2017-07-04 12:14:04 +01:00
|
|
|
void FrameDrawDiskLEDS(HDC)
|
|
|
|
{
|
|
|
|
}
|
|
|
|
|
|
|
|
void FrameDrawDiskStatus(HDC)
|
|
|
|
{
|
2017-07-02 20:55:56 +01:00
|
|
|
|
2017-07-04 12:14:04 +01:00
|
|
|
}
|
|
|
|
|
|
|
|
void FrameRefreshStatus(int, bool)
|
|
|
|
{
|
2017-07-02 20:55:56 +01:00
|
|
|
|
2017-07-04 12:14:04 +01:00
|
|
|
}
|
2017-07-02 20:55:56 +01:00
|
|
|
|
|
|
|
// Speaker
|
|
|
|
|
2017-07-04 12:14:04 +01:00
|
|
|
BYTE __stdcall SpkrToggle (WORD pc, WORD addr, BYTE bWrite, BYTE d, ULONG nCyclesLeft)
|
|
|
|
{
|
|
|
|
Q_UNUSED(pc)
|
|
|
|
Q_UNUSED(addr)
|
|
|
|
Q_UNUSED(bWrite)
|
|
|
|
Q_UNUSED(d)
|
|
|
|
Q_UNUSED(nCyclesLeft)
|
|
|
|
return 0;
|
|
|
|
}
|
2017-07-02 20:55:56 +01:00
|
|
|
|
|
|
|
void VideoInitialize() {}
|
|
|
|
|
|
|
|
QApple::QApple(QWidget *parent) :
|
2017-07-07 21:04:21 +01:00
|
|
|
QMainWindow(parent), myDiskFileDialog(this), myTimerID(0)
|
2017-07-02 20:55:56 +01:00
|
|
|
{
|
|
|
|
setupUi(this);
|
|
|
|
|
2017-07-04 19:25:10 +01:00
|
|
|
myDiskFileDialog.setFileMode(QFileDialog::AnyFile);
|
|
|
|
|
2017-07-03 21:00:42 +01:00
|
|
|
myEmulator = new Emulator(mdiArea);
|
2017-07-04 12:14:04 +01:00
|
|
|
myEmulatorWindow = mdiArea->addSubWindow(myEmulator, Qt::CustomizeWindowHint | Qt::WindowTitleHint | Qt::WindowMinMaxButtonsHint);
|
2017-07-04 21:17:40 +01:00
|
|
|
myEmulatorWindow->setWindowTitle(g_pAppTitle);
|
2017-07-02 20:55:56 +01:00
|
|
|
|
2017-07-09 16:49:11 +01:00
|
|
|
myMSGap = 5;
|
2017-07-02 20:55:56 +01:00
|
|
|
|
|
|
|
initialiseEmulator();
|
2017-07-04 14:05:06 +01:00
|
|
|
|
2017-07-04 21:17:40 +01:00
|
|
|
startEmulator();
|
2017-07-04 14:05:06 +01:00
|
|
|
}
|
|
|
|
|
|
|
|
void QApple::closeEvent(QCloseEvent *)
|
|
|
|
{
|
2017-07-07 21:04:21 +01:00
|
|
|
stopTimer();
|
2017-07-04 14:05:06 +01:00
|
|
|
uninitialiseEmulator();
|
2017-07-02 20:55:56 +01:00
|
|
|
}
|
|
|
|
|
2017-07-09 16:49:11 +01:00
|
|
|
void QApple::on_timer()
|
2017-07-02 20:55:56 +01:00
|
|
|
{
|
2017-07-09 16:49:11 +01:00
|
|
|
const qint64 elapsed = myElapsedTimer.restart();
|
2017-07-02 20:55:56 +01:00
|
|
|
const double fUsecPerSec = 1.e6;
|
2017-07-09 16:49:11 +01:00
|
|
|
const UINT nExecutionPeriodUsec = 1000 * elapsed;
|
2017-07-02 20:55:56 +01:00
|
|
|
|
|
|
|
const double fExecutionPeriodClks = g_fCurrentCLK6502 * ((double)nExecutionPeriodUsec / fUsecPerSec);
|
|
|
|
const DWORD uCyclesToExecute = fExecutionPeriodClks;
|
|
|
|
|
|
|
|
const bool bVideoUpdate = false;
|
|
|
|
|
2017-07-09 16:49:11 +01:00
|
|
|
do
|
2017-07-02 20:55:56 +01:00
|
|
|
{
|
2017-07-09 16:49:11 +01:00
|
|
|
const DWORD uActualCyclesExecuted = CpuExecute(uCyclesToExecute, bVideoUpdate);
|
|
|
|
g_dwCyclesThisFrame += uActualCyclesExecuted;
|
|
|
|
if (g_dwCyclesThisFrame >= dwClksPerFrame)
|
|
|
|
{
|
|
|
|
g_dwCyclesThisFrame -= dwClksPerFrame;
|
|
|
|
myEmulator->redrawScreen();
|
|
|
|
}
|
2017-07-10 19:44:52 +01:00
|
|
|
Input::instance().poll();
|
2017-07-02 20:55:56 +01:00
|
|
|
}
|
2017-07-09 16:49:11 +01:00
|
|
|
while (DiskIsSpinning());
|
2017-07-04 14:05:06 +01:00
|
|
|
}
|
|
|
|
|
2017-07-07 21:04:21 +01:00
|
|
|
void QApple::stopTimer()
|
|
|
|
{
|
|
|
|
if (myTimerID)
|
|
|
|
{
|
|
|
|
killTimer(myTimerID);
|
|
|
|
myTimerID = 0;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2017-07-02 20:55:56 +01:00
|
|
|
void QApple::on_actionStart_triggered()
|
|
|
|
{
|
2017-07-04 14:05:06 +01:00
|
|
|
// always restart with the same timer gap that was last used
|
2017-07-09 16:49:11 +01:00
|
|
|
myTimerID = startTimer(myMSGap, Qt::PreciseTimer);
|
|
|
|
myElapsedTimer.start();
|
2017-07-02 20:55:56 +01:00
|
|
|
actionPause->setEnabled(true);
|
|
|
|
actionStart->setEnabled(false);
|
|
|
|
}
|
|
|
|
|
|
|
|
void QApple::on_actionPause_triggered()
|
|
|
|
{
|
2017-07-07 21:04:21 +01:00
|
|
|
stopTimer();
|
2017-07-02 20:55:56 +01:00
|
|
|
actionPause->setEnabled(false);
|
|
|
|
actionStart->setEnabled(true);
|
|
|
|
}
|
2017-07-04 12:14:04 +01:00
|
|
|
|
|
|
|
void QApple::on_actionX1_triggered()
|
|
|
|
{
|
|
|
|
myEmulator->setZoom(myEmulatorWindow, 1);
|
|
|
|
}
|
|
|
|
|
|
|
|
void QApple::on_actionX2_triggered()
|
|
|
|
{
|
|
|
|
myEmulator->setZoom(myEmulatorWindow, 2);
|
|
|
|
}
|
|
|
|
|
|
|
|
void QApple::on_action4_3_triggered()
|
|
|
|
{
|
|
|
|
myEmulator->set43AspectRatio(myEmulatorWindow);
|
|
|
|
}
|
2017-07-04 19:25:10 +01:00
|
|
|
|
|
|
|
void QApple::insertDisk(const int disk)
|
|
|
|
{
|
|
|
|
if (myDiskFileDialog.exec())
|
|
|
|
{
|
|
|
|
QStringList files = myDiskFileDialog.selectedFiles();
|
|
|
|
if (files.size() == 1)
|
|
|
|
{
|
|
|
|
const std::string filename = files[0].toStdString();
|
|
|
|
const bool createMissingDisk = true;
|
2017-07-07 21:13:17 +01:00
|
|
|
const ImageError_e result = DiskInsert(disk, filename.c_str(), IMAGE_USE_FILES_WRITE_PROTECT_STATUS, createMissingDisk);
|
|
|
|
if (result != eIMAGE_ERROR_NONE)
|
|
|
|
{
|
|
|
|
const QString message = QString("Error [%1] inserting '%2'").arg(QString::number(result), files[0]);
|
|
|
|
QMessageBox::warning(NULL, "Disk error", message);
|
|
|
|
}
|
2017-07-04 19:25:10 +01:00
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
void QApple::on_actionDisk_1_triggered()
|
|
|
|
{
|
|
|
|
insertDisk(DRIVE_1);
|
|
|
|
}
|
|
|
|
|
|
|
|
void QApple::on_actionDisk_2_triggered()
|
|
|
|
{
|
|
|
|
insertDisk(DRIVE_2);
|
|
|
|
}
|
2017-07-04 21:17:40 +01:00
|
|
|
|
|
|
|
void QApple::on_actionReboot_triggered()
|
|
|
|
{
|
|
|
|
startEmulator();
|
|
|
|
}
|
2017-07-07 21:04:21 +01:00
|
|
|
|
|
|
|
void QApple::on_actionBenchmark_triggered()
|
|
|
|
{
|
|
|
|
VideoBenchmark([this]() { myEmulator->redrawScreen(); });
|
|
|
|
on_actionReboot_triggered();
|
|
|
|
}
|
2017-07-09 16:49:11 +01:00
|
|
|
|
|
|
|
void QApple::timerEvent(QTimerEvent *)
|
|
|
|
{
|
|
|
|
on_timer();
|
|
|
|
}
|