mirror of
https://github.com/samstyle/Xpeccy.git
synced 2025-04-19 00:04:05 +03:00
build 20170426
[+] Virtual keyboard: LMB = press+release, RMB = trigger, MMB = release all keys [+] Virtual keyboard: indicate all ZX keys state [+] CMakeLists.txt fixes for MacOSX. Bundle icon is now available! [+] internal: cpu->exec makes a decision: to exec opcode or to handle interrupt. no more cpu->intr there
This commit is contained in:
parent
fa83c135eb
commit
0914907c84
@ -87,11 +87,17 @@ elseif(${CMAKE_SYSTEM_NAME} MATCHES "Darwin")
|
||||
set(CPACK_DMG_NAME ${PROJECT_NAME})
|
||||
set(CPACK_DMG_FORMAT UDZO)
|
||||
|
||||
set(CPACK_BUNDLE_NAME ${PROJECT_NAME}.app)
|
||||
set(CPACK_BUNDLE_ICON ${CMAKE_SOURCE_DIR}/images/xpeccy.icns)
|
||||
set(MACOSX_BUNDLE_BUNDLE_NAME ${PROJECT_NAME}.app)
|
||||
set(MACOSX_BUNDLE_ICON_FILE ${PROJECT_NAME}.icns)
|
||||
set(MACOSX_BUNDLE_INFO_PLIST ${CMAKE_SOURCE_DIR}/Info.plist)
|
||||
set(MACOSX_BUNDLE_BUNDLE_VERSION ${XVER})
|
||||
|
||||
set_source_files_properties(${CMAKE_BINARY_DIR}/${PROJECT_NAME} PROPERTIES MACOS_PACKAGE_LOCATION MacOSX)
|
||||
set_source_files_properties(${CPACK_BUNDLE_ICON} PROPERTIES MACOS_PACKAGE_LOCATION Resources)
|
||||
set(BUNDLE_ICON_PATH ${CMAKE_SOURCE_DIR}/images/${MACOSX_BUNDLE_ICON_FILE})
|
||||
set(BUNDLE_PATH ${CMAKE_BINARY_DIR}/${MACOSX_BUNDLE_BUNDLE_NAME})
|
||||
|
||||
|
||||
set_source_files_properties(${CMAKE_BINARY_DIR}/${PROJECT_NAME} PROPERTIES MACOSX_PACKAGE_LOCATION MacOSX)
|
||||
set_source_files_properties(${BUNDLE_ICON_PATH} PROPERTIES MACOSX_PACKAGE_LOCATION Resources)
|
||||
|
||||
elseif(${CMAKE_SYSTEM_NAME} MATCHES "Windows")
|
||||
|
||||
@ -143,6 +149,7 @@ set(MOCFILES
|
||||
./src/dbg_finder.h
|
||||
./src/watcher.h
|
||||
./src/setupwin.h
|
||||
./src/vkeyboard.h
|
||||
./src/xgui/xgui.h
|
||||
)
|
||||
|
||||
@ -232,14 +239,20 @@ include_directories(${INCLUDIRS})
|
||||
if(${CMAKE_SYSTEM_NAME} MATCHES "Linux")
|
||||
add_executable(${PROJECT_NAME} ${SOURCES} ${HEADERS} ${UIHEADERS} ${RESOURCES} ${MOCHEADERS})
|
||||
elseif(${CMAKE_SYSTEM_NAME} MATCHES "Darwin")
|
||||
add_executable(${PROJECT_NAME} MACOSX_BUNDLE ${SOURCES} ${HEADERS} ${UIHEADERS} ${RESOURCES} ${MOCHEADERS})
|
||||
add_executable(${PROJECT_NAME} MACOSX_BUNDLE ${SOURCES} ${HEADERS} ${UIHEADERS} ${RESOURCES} ${MOCHEADERS} ${BUNDLE_ICON_PATH})
|
||||
find_program(MACDEPLOYQTEXE macdeployqt)
|
||||
add_custom_command(TARGET ${PROJECT_NAME} POST_BUILD
|
||||
COMMAND mkdir ARGS -p ${CMAKE_BINARY_DIR}/${CPACK_BUNDLE_NAME}/Contents/Frameworks
|
||||
COMMAND cp ARGS -R /Library/Frameworks/SDL.framework ${CMAKE_BINARY_DIR}/${CPACK_BUNDLE_NAME}/Contents/Frameworks
|
||||
COMMAND ${MACDEPLOYQTEXE} ARGS ${CMAKE_BINARY_DIR}/${CPACK_BUNDLE_NAME} -always-overwrite
|
||||
COMMAND ${MACDEPLOYQTEXE} ARGS ${BUNDLE_PATH} -always-overwrite
|
||||
# COMMAND mkdir ARGS -p ${BUNDLE_PATH}/Contents/Frameworks
|
||||
COMMAND cp ARGS -R /Library/Frameworks/SDL.framework ${BUNDLE_PATH}/Contents/Frameworks
|
||||
)
|
||||
set(CMAKE_INSTALL_PREFIX "/Applications")
|
||||
# install(CODE "
|
||||
# include(BundleUtilities)
|
||||
# fixup_bundle(${BUNDLE_PATH} \"\" ${LIBDIRS})
|
||||
# find_program(MACDEPLOYQTEXE macdeployqt)
|
||||
# execute_process(COMMAND ${MACDEPLOYQTEXE} ARGS ${BUNDLE_PATH} -always-overwrite)
|
||||
# " COMPONENT Runtime)
|
||||
install(TARGETS ${PROJECT_NAME} BUNDLE DESTINATION .)
|
||||
elseif(${CMAKE_SYSTEM_NAME} MATCHES "Windows")
|
||||
add_executable(${PROJECT_NAME} WIN32 ${SOURCES} ${HEADERS} ${UIHEADERS} ${RESOURCES} ${MOCHEADERS})
|
||||
|
30
Info.plist
Normal file
30
Info.plist
Normal file
@ -0,0 +1,30 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
|
||||
<plist version="1.0">
|
||||
<dict>
|
||||
<key>CFBundleDevelopmentRegion</key>
|
||||
<string>Russian</string>
|
||||
<key>CFBundleDisplayName</key>
|
||||
<string>xpeccy</string>
|
||||
<key>CFBundleExecutable</key>
|
||||
<string>xpeccy</string>
|
||||
<key>CFBundleIconFile</key>
|
||||
<string>xpeccy.icns</string>
|
||||
<key>CFBundleIdentifier</key>
|
||||
<string>ru.samstyle.xpeccy</string>
|
||||
<key>CFBundleInfoDictionaryVersion</key>
|
||||
<string>6.0</string>
|
||||
<key>CFBundleName</key>
|
||||
<string>xpeccy</string>
|
||||
<key>CFBundlePackageType</key>
|
||||
<string>APPL</string>
|
||||
<key>CFBundleShortVersionString</key>
|
||||
<string>0.6</string>
|
||||
<key>CFBundleSignature</key>
|
||||
<string>iddqd</string>
|
||||
<key>NSPrincipalClass</key>
|
||||
<string>NSApplication</string>
|
||||
<key>LSApplicationCategoryType</key>
|
||||
<string>public.app-category.productivity</string>
|
||||
</dict>
|
||||
</plist>
|
BIN
images/cartrige.png
Normal file
BIN
images/cartrige.png
Normal file
Binary file not shown.
After Width: | Height: | Size: 852 B |
BIN
images/eye.png
BIN
images/eye.png
Binary file not shown.
Before Width: | Height: | Size: 659 B |
BIN
images/keyboardzx.png
Normal file
BIN
images/keyboardzx.png
Normal file
Binary file not shown.
After Width: | Height: | Size: 388 B |
BIN
images/objective.png
Normal file
BIN
images/objective.png
Normal file
Binary file not shown.
After Width: | Height: | Size: 954 B |
BIN
images/pixels.png
Normal file
BIN
images/pixels.png
Normal file
Binary file not shown.
After Width: | Height: | Size: 1.3 KiB |
@ -41,7 +41,7 @@ void DebugWin::start(Computer* c) {
|
||||
updateScreen();
|
||||
if (!comp->vid->tail)
|
||||
vidDarkTail(comp->vid);
|
||||
ui.tabsPanel->setTabEnabled(ui.tabsPanel->indexOf(ui.gbTab), comp->hw->type == HW_GBC);
|
||||
ui.tabsPanel->setTabEnabled(ui.tabsPanel->indexOf(ui.gbTab), comp->hw->id == HW_GBC);
|
||||
|
||||
ui.dasmTable->comp = comp;
|
||||
move(winPos);
|
||||
@ -369,7 +369,7 @@ void DebugWin::doStep() {
|
||||
disasmAdr = comp->cpu->pc;
|
||||
fillDisasm();
|
||||
}
|
||||
if ((traceType == DBG_TRACE_INT) && (comp->cpu->inth))
|
||||
if ((traceType == DBG_TRACE_INT) && (comp->cpu->intrq & comp->cpu->inten))
|
||||
trace = 0;
|
||||
if ((traceType == DBG_TRACE_HERE) && (comp->cpu->pc == traceAdr))
|
||||
trace = 0;
|
||||
@ -646,7 +646,7 @@ bool DebugWin::fillAll() {
|
||||
setSignal(ui.labCPM, comp->cpm);
|
||||
//setSignal(ui.labHBlank, comp->vid->hblank);
|
||||
//setSignal(ui.labVBlank, comp->vid->vblank);
|
||||
setSignal(ui.labINT, comp->cpu->inth);
|
||||
setSignal(ui.labINT, comp->cpu->intrq & comp->cpu->inten);
|
||||
if (memViewer->isVisible())
|
||||
memViewer->fillImage();
|
||||
return fillDisasm();
|
||||
|
@ -33,83 +33,13 @@
|
||||
|
||||
// main
|
||||
|
||||
unsigned char screen[2048 * 2048 * 3]; // scaled image (up to fullscreen)
|
||||
unsigned char screen[4096 * 2048 * 3]; // scaled image (up to fullscreen)
|
||||
unsigned char scrn[1024 * 512 * 3]; // 2:1 image
|
||||
unsigned char prvScr[1024 * 512 * 3]; // copy of last 2:1 image (for noflic)
|
||||
|
||||
// temp emulation
|
||||
unsigned short pc,af,de,ix;
|
||||
|
||||
// onscreen keyboard
|
||||
|
||||
unsigned char kwMap[4][10] = {
|
||||
{'1','2','3','4','5','6','7','8','9','0'},
|
||||
{'q','w','e','r','t','y','u','i','o','p'},
|
||||
{'a','s','d','f','g','h','j','k','l','E'},
|
||||
{'C','z','x','c','v','b','n','m','S',' '}
|
||||
};
|
||||
|
||||
keyWindow::keyWindow(QWidget* p):QLabel(p) {
|
||||
kb = NULL;
|
||||
xk.key1 = 0;
|
||||
xk.key2 = 0;
|
||||
}
|
||||
|
||||
void keyWindow::paintEvent(QPaintEvent*) {
|
||||
QPainter pnt;
|
||||
int wid = width() / 10 + 1;
|
||||
int hig = height() / 4;
|
||||
pnt.begin(this);
|
||||
pnt.fillRect(QRectF(0,0,1,1), qRgba(0,0,0,0));
|
||||
if (~kb->map[0] & 2) { // SS
|
||||
pnt.fillRect(8 * wid, 3 * hig, wid, hig, qRgba(64, 160, 160, 100));
|
||||
}
|
||||
if (~kb->map[7] & 1) { // CS
|
||||
pnt.fillRect(0, 3 * hig, wid, hig, qRgba(64, 160, 160, 100));
|
||||
}
|
||||
pnt.drawPixmap(0, 0, QPixmap(":/images/keymap.png"));
|
||||
pnt.end();
|
||||
}
|
||||
|
||||
void keyWindow::mousePressEvent(QMouseEvent* ev) {
|
||||
if (!kb) return;
|
||||
int row;
|
||||
int col;
|
||||
if (ev->button() == Qt::RightButton) {
|
||||
keyReleaseAll(kb);
|
||||
xk.key1 = 0;
|
||||
} else {
|
||||
row = ev->y() * 4 / height();
|
||||
col = ev->x() * 10 / width();
|
||||
xk.key1 = kwMap[row][col];
|
||||
if ((xk.key1 == 'S') || (xk.key1 == 'C')) {
|
||||
keyTrigger(kb, xk, 0);
|
||||
update();
|
||||
} else {
|
||||
keyPress(kb, xk, 0);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void keyWindow::mouseReleaseEvent(QMouseEvent* ev) {
|
||||
if (!kb) return;
|
||||
switch(xk.key1) {
|
||||
case 'C':
|
||||
if (kb->map[0] & 2) break;
|
||||
keyRelease(kb, xk, 0);
|
||||
update();
|
||||
break;
|
||||
case 'S':
|
||||
if (kb->map[7] & 1) break;
|
||||
keyRelease(kb, xk, 0);
|
||||
update();
|
||||
break;
|
||||
default:
|
||||
keyRelease(kb, xk, 0);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
// mainwin
|
||||
|
||||
void MainWin::updateHead() {
|
||||
@ -236,8 +166,6 @@ MainWin::MainWin() {
|
||||
rzxWin = new RZXWin(this);
|
||||
connect(rzxWin,SIGNAL(stateChanged(int)),this,SLOT(rzxStateChanged(int)));
|
||||
|
||||
initUserMenu();
|
||||
|
||||
keywin = new keyWindow();
|
||||
QPixmap pxm(":/images/keymap.png");
|
||||
keywin->setPixmap(pxm);
|
||||
@ -245,6 +173,8 @@ MainWin::MainWin() {
|
||||
keywin->setWindowIcon(QIcon(":/images/keyboard.png"));
|
||||
keywin->setWindowTitle("ZX Keyboard");
|
||||
|
||||
initUserMenu();
|
||||
|
||||
cmosTimer.start(1000);
|
||||
timer.setInterval(20);
|
||||
connect(&cmosTimer,SIGNAL(timeout()),this,SLOT(cmosTick()));
|
||||
@ -554,8 +484,8 @@ void MainWin::keyPressEvent(QKeyEvent *ev) {
|
||||
keywin->close();
|
||||
} else {
|
||||
keywin->show();
|
||||
activateWindow();
|
||||
raise();
|
||||
// activateWindow();
|
||||
// raise();
|
||||
}
|
||||
break;
|
||||
case Qt::Key_N:
|
||||
@ -572,7 +502,7 @@ void MainWin::keyPressEvent(QKeyEvent *ev) {
|
||||
break;
|
||||
}
|
||||
} else {
|
||||
if (comp->hw->type == HW_GBC)
|
||||
if (comp->hw->id == HW_GBC)
|
||||
gbPress(comp, kent.name);
|
||||
keyPress(comp->keyb, kent.zxKey, 0);
|
||||
if (kent.msxKey.key1) keyPress(comp->keyb,kent.msxKey,2);
|
||||
@ -664,6 +594,7 @@ void MainWin::keyPressEvent(QKeyEvent *ev) {
|
||||
break;
|
||||
}
|
||||
}
|
||||
if (keywin->isVisible()) keywin->update();
|
||||
}
|
||||
|
||||
void MainWin::keyReleaseEvent(QKeyEvent *ev) {
|
||||
@ -680,6 +611,7 @@ void MainWin::keyReleaseEvent(QKeyEvent *ev) {
|
||||
keyRelease(comp->keyb, kent.zxKey, 0);
|
||||
if (kent.msxKey.key1) keyRelease(comp->keyb,kent.msxKey,2);
|
||||
}
|
||||
if (keywin->isVisible()) keywin->update();
|
||||
}
|
||||
|
||||
void MainWin::mousePressEvent(QMouseEvent *ev){
|
||||
@ -1031,7 +963,8 @@ void MainWin::initUserMenu() {
|
||||
userMenu->addSeparator();
|
||||
pckAct = userMenu->addAction(QIcon(":/images/keyboard.png"),"PC keyboard");
|
||||
pckAct->setCheckable(true);
|
||||
userMenu->addAction(QIcon(),"Watcher",watcher,SLOT(show()));
|
||||
userMenu->addAction(QIcon(":/images/keyboardzx.png"),"ZX Keyboard",keywin,SLOT(show()));
|
||||
userMenu->addAction(QIcon(":/images/objective.png"),"Watcher",watcher,SLOT(show()));
|
||||
userMenu->addAction(QIcon(":/images/other.png"),"Options",this,SLOT(doOptions()));
|
||||
|
||||
connect(bookmarkMenu,SIGNAL(triggered(QAction*)),this,SLOT(bookmarkSelected(QAction*)));
|
||||
@ -1044,7 +977,7 @@ void MainWin::initUserMenu() {
|
||||
fileMenu->addAction(QIcon(":/images/memory.png"),"Snapshot")->setData(FT_SNAP | FT_SPG);
|
||||
fileMenu->addAction(QIcon(":/images/tape.png"),"Tape")->setData(FT_TAPE);
|
||||
fileMenu->addAction(QIcon(":/images/floppy.png"),"Floppy")->setData(FT_DISK);
|
||||
fileMenu->addAction(QIcon(),"Slot")->setData(FT_SLOT);
|
||||
fileMenu->addAction(QIcon(":/images/cartrige.png"),"Slot")->setData(FT_SLOT);
|
||||
|
||||
nsAct = vmodeMenu->addAction("No screen");
|
||||
nsAct->setData(-1);
|
||||
|
@ -11,6 +11,7 @@
|
||||
#include "setupwin.h"
|
||||
#include "debuger.h"
|
||||
#include "watcher.h"
|
||||
#include "vkeyboard.h"
|
||||
#include "xcore/xcore.h"
|
||||
#include "xgui/xgui.h"
|
||||
#include "ethread.h"
|
||||
@ -35,19 +36,6 @@ typedef struct {
|
||||
QString imgName;
|
||||
} xLed;
|
||||
|
||||
class keyWindow : public QLabel {
|
||||
Q_OBJECT
|
||||
public:
|
||||
keyWindow(QWidget* = NULL);
|
||||
Keyboard* kb;
|
||||
private:
|
||||
xKey xk;
|
||||
protected:
|
||||
void paintEvent(QPaintEvent*);
|
||||
void mousePressEvent(QMouseEvent*);
|
||||
void mouseReleaseEvent(QMouseEvent*);
|
||||
};
|
||||
|
||||
class MainWin : public QWidget {
|
||||
Q_OBJECT
|
||||
public:
|
||||
|
@ -4,7 +4,7 @@
|
||||
#include "xgui/xgui.h"
|
||||
#include "xcore/sound.h"
|
||||
|
||||
std::mutex emutex;
|
||||
QMutex emutex;
|
||||
|
||||
unsigned char* blkData = NULL;
|
||||
extern unsigned char scrn[1024 * 512 * 3];
|
||||
|
@ -2,7 +2,7 @@
|
||||
#define _ETHREAD_H
|
||||
|
||||
#include <QThread>
|
||||
#include <mutex>
|
||||
#include <QMutex>
|
||||
|
||||
#include "xcore/xcore.h"
|
||||
|
||||
@ -29,6 +29,6 @@ class xThread : public QThread {
|
||||
void tapeSignal(int,int);
|
||||
};
|
||||
|
||||
extern std::mutex emutex;
|
||||
extern QMutex emutex;
|
||||
|
||||
#endif
|
||||
|
@ -93,7 +93,7 @@ int getFileType(QString path) {
|
||||
|
||||
int testSlotOn(Computer* comp) {
|
||||
int res = 0;
|
||||
switch (comp->hw->type) {
|
||||
switch (comp->hw->id) {
|
||||
case HW_MSX:
|
||||
case HW_MSX2:
|
||||
case HW_GBC:
|
||||
|
@ -27,23 +27,6 @@ void lr_reset(CPU* cpu) {
|
||||
cpu->i = cpu->r = cpu->r7 = 0xff;
|
||||
}
|
||||
|
||||
int lr_exec(CPU* cpu) {
|
||||
if (cpu->lock) return 1;
|
||||
cpu->t = 0;
|
||||
cpu->opTab = lrTab;
|
||||
do {
|
||||
cpu->tmp = cpu->mrd(cpu->pc++, 1, cpu->data);
|
||||
cpu->op = &cpu->opTab[cpu->tmp];
|
||||
cpu->t += cpu->op->t;
|
||||
cpu->op->exec(cpu);
|
||||
} while (cpu->op->prefix);
|
||||
if (cpu->dihalt) { // LR35902 bug (?) : repeat opcode after HALT with disabled interrupts (DI)
|
||||
cpu->dihalt = 0;
|
||||
cpu->pc = cpu->tmpw;
|
||||
}
|
||||
return cpu->t;
|
||||
}
|
||||
|
||||
typedef struct {
|
||||
unsigned char mask;
|
||||
unsigned short inta;
|
||||
@ -77,6 +60,30 @@ int lr_int(CPU* cpu) {
|
||||
return res;
|
||||
}
|
||||
|
||||
int lr_exec(CPU* cpu) {
|
||||
int res = 0;
|
||||
if ((cpu->intrq & cpu->inten) && cpu->iff1) {
|
||||
res = lr_int(cpu);
|
||||
} else if (cpu->lock) {
|
||||
res = 1;
|
||||
} else {
|
||||
cpu->t = 0;
|
||||
cpu->opTab = lrTab;
|
||||
do {
|
||||
cpu->tmp = cpu->mrd(cpu->pc++, 1, cpu->data);
|
||||
cpu->op = &cpu->opTab[cpu->tmp];
|
||||
cpu->t += cpu->op->t;
|
||||
cpu->op->exec(cpu);
|
||||
} while (cpu->op->prefix);
|
||||
if (cpu->dihalt) { // LR35902 bug (?) : repeat opcode after HALT with disabled interrupts (DI)
|
||||
cpu->dihalt = 0;
|
||||
cpu->pc = cpu->tmpw;
|
||||
}
|
||||
res = cpu->t;
|
||||
}
|
||||
return res;
|
||||
}
|
||||
|
||||
// disasm
|
||||
|
||||
xAsmScan lr_asm(const char* cbuf, char* buf) {
|
||||
|
@ -26,16 +26,23 @@ int m6502_int(CPU* cpu) {
|
||||
m6502_push_int(cpu);
|
||||
cpu->pc = 0xfffe;
|
||||
}
|
||||
cpu->inth = cpu->intrq ? 1 : 0; // if both INT happened in one time
|
||||
// cpu->inth = cpu->intrq ? 1 : 0; // if both INT happened in one time
|
||||
return 7;
|
||||
}
|
||||
|
||||
int m6502_exec(CPU* cpu) {
|
||||
unsigned char com = cpu->mrd(cpu->pc++, 1, cpu->data);
|
||||
opCode* op = &mosTab[com];
|
||||
cpu->t = op->t; // 2T fetch
|
||||
op->exec(cpu);
|
||||
return cpu->t;
|
||||
int res = 0;
|
||||
unsigned char com;
|
||||
if (cpu->intrq & cpu->inten) {
|
||||
res = m6502_int(cpu);
|
||||
} else {
|
||||
com = cpu->mrd(cpu->pc++, 1, cpu->data);
|
||||
opCode* op = &mosTab[com];
|
||||
cpu->t = op->t; // 2T fetch
|
||||
op->exec(cpu);
|
||||
res = cpu->t;
|
||||
}
|
||||
return res;
|
||||
}
|
||||
|
||||
xMnem m6502_mnem(CPU* cpu, unsigned short adr, cbdmr mrd, void* data) {
|
||||
|
@ -92,7 +92,7 @@ void mosGetINDY(CPU* cpu) {
|
||||
// brk : 7T
|
||||
void mosop00(CPU* cpu) {
|
||||
cpu->intrq |= 1; // request for user interrupt
|
||||
cpu->inth = 1;
|
||||
// cpu->inth = 1;
|
||||
}
|
||||
|
||||
// 01:ora indx n : 6T
|
||||
|
@ -26,24 +26,10 @@ void z80_reset(CPU* cpu) {
|
||||
cpu->i = cpu->r = cpu->r7 = 0;
|
||||
cpu->halt = 0;
|
||||
cpu->intrq = 0;
|
||||
cpu->inten = 2; // NMI allways enabled, INT is controlled by ei/di
|
||||
cpu->wait = 0;
|
||||
}
|
||||
|
||||
int z80_exec(CPU* cpu) {
|
||||
if (cpu->wait) return 1;
|
||||
cpu->t = 0;
|
||||
cpu->noint = 0;
|
||||
cpu->opTab = npTab;
|
||||
do {
|
||||
cpu->com = cpu->mrd(cpu->pc++,1,cpu->data);
|
||||
cpu->op = &cpu->opTab[cpu->com];
|
||||
cpu->r++;
|
||||
cpu->t += cpu->op->t;
|
||||
cpu->op->exec(cpu);
|
||||
} while (cpu->op->prefix);
|
||||
return cpu->t;
|
||||
}
|
||||
|
||||
int z80_int(CPU* cpu) {
|
||||
int res = 0;
|
||||
if (cpu->wait) return 0;
|
||||
@ -108,6 +94,28 @@ int z80_int(CPU* cpu) {
|
||||
return res;
|
||||
}
|
||||
|
||||
int z80_exec(CPU* cpu) {
|
||||
int res = 0;
|
||||
if (cpu->wait) {
|
||||
res = 1;
|
||||
} else if (cpu->intrq & cpu->inten) {
|
||||
res = z80_int(cpu);
|
||||
} else {
|
||||
cpu->t = 0;
|
||||
cpu->noint = 0;
|
||||
cpu->opTab = npTab;
|
||||
do {
|
||||
cpu->com = cpu->mrd(cpu->pc++,1,cpu->data);
|
||||
cpu->op = &cpu->opTab[cpu->com];
|
||||
cpu->r++;
|
||||
cpu->t += cpu->op->t;
|
||||
cpu->op->exec(cpu);
|
||||
} while (cpu->op->prefix);
|
||||
res = cpu->t;
|
||||
}
|
||||
return res;
|
||||
}
|
||||
|
||||
// disasm
|
||||
|
||||
unsigned char z80_cnd[4] = {FZ, FC, FP, FS};
|
||||
|
@ -845,6 +845,7 @@ void nprF2(CPU* cpu) {
|
||||
void nprF3(CPU* cpu) {
|
||||
cpu->iff1 = 0;
|
||||
cpu->iff2 = 0;
|
||||
cpu->inten &= ~1;
|
||||
}
|
||||
|
||||
// f4 call p,nn 4 3rd 3rd[+1] [3wr 3wr] memptr = nn
|
||||
@ -897,6 +898,7 @@ void nprFB(CPU* cpu) {
|
||||
cpu->iff1 = 1;
|
||||
cpu->iff2 = 1;
|
||||
cpu->noint = 1;
|
||||
cpu->inten |= 1;
|
||||
}
|
||||
|
||||
// fc call m,nn 4 3rd 3rd[+1] [3wr 3wr] mptr = nn
|
||||
|
@ -28,9 +28,9 @@ extern opCode npTab[256];
|
||||
extern opCode lrTab[256];
|
||||
|
||||
cpuCore cpuTab[] = {
|
||||
{CPU_Z80, "Z80", npTab, z80_reset, z80_exec, z80_int, z80_asm, z80_mnem},
|
||||
{CPU_LR35902, "LR35902", lrTab, lr_reset, lr_exec, lr_int, lr_asm, lr_mnem},
|
||||
{CPU_NONE, "none", NULL, nil_reset, nil_exec, nil_int, nil_asm, nil_mnem}
|
||||
{CPU_Z80, "Z80", npTab, z80_reset, z80_exec, /*z80_int,*/ z80_asm, z80_mnem},
|
||||
{CPU_LR35902, "LR35902", lrTab, lr_reset, lr_exec, /*lr_int,*/ lr_asm, lr_mnem},
|
||||
{CPU_NONE, "none", NULL, nil_reset, nil_exec, /*nil_int,*/ nil_asm, nil_mnem}
|
||||
};
|
||||
|
||||
cpuCore* findCore(int type) {
|
||||
@ -59,7 +59,7 @@ void cpuSetType(CPU* cpu, int type) {
|
||||
cpu->type = core->type;
|
||||
cpu->reset = core->reset;
|
||||
cpu->exec = core->exec;
|
||||
cpu->intr = core->intr;
|
||||
// cpu->intr = core->intr;
|
||||
cpu->asmbl = core->asmbl;
|
||||
cpu->mnem = core->mnem;
|
||||
cpu->tab = core->tab;
|
||||
|
@ -10,11 +10,17 @@ typedef struct {
|
||||
const char* mnem;
|
||||
} xMnem;
|
||||
|
||||
// memrq rd
|
||||
typedef unsigned char(*cbmr)(unsigned short,int,void*);
|
||||
// memrq wr
|
||||
typedef void(*cbmw)(unsigned short,unsigned char,void*);
|
||||
// iorq rd
|
||||
typedef unsigned char(*cbir)(unsigned short,void*);
|
||||
// iorq wr
|
||||
typedef void(*cbiw)(unsigned short,unsigned char,void*);
|
||||
// iorq int : interrupt vector request
|
||||
typedef unsigned char(*cbirq)(void*);
|
||||
// memrd external
|
||||
typedef unsigned char(*cbdmr)(unsigned short,void*);
|
||||
|
||||
#ifdef WORDS_BIG_ENDIAN
|
||||
@ -55,7 +61,7 @@ enum {
|
||||
|
||||
struct CPU {
|
||||
unsigned halt:1; // cpu halted, undo on interrput
|
||||
unsigned inth:1; // next step is 1:handle interrupt, 0: exec opcode
|
||||
// unsigned inth:1; // next step is 1:handle interrupt, 0: exec opcode
|
||||
unsigned resPV:1; // Z80: reset PV flag on INT
|
||||
unsigned noint:1; // Z80: don't handle INT after EI
|
||||
unsigned wait:1; // Z80: WAIT signal
|
||||
@ -106,7 +112,7 @@ struct CPU {
|
||||
|
||||
void (*reset)(CPU*);
|
||||
int (*exec)(CPU*);
|
||||
int (*intr)(CPU*); // handle interrupt. intrq = requested INT types
|
||||
// int (*intr)(CPU*); // handle interrupt. intrq = requested INT types
|
||||
xAsmScan (*asmbl)(const char*, char*);
|
||||
xMnem (*mnem)(CPU*, unsigned short, cbdmr, void*);
|
||||
|
||||
@ -123,7 +129,7 @@ typedef struct {
|
||||
opCode* tab; // start opcode tab;
|
||||
void (*reset)(CPU*); // reset
|
||||
int (*exec)(CPU*); // exec opcode, return T
|
||||
int (*intr)(CPU*); // handle interrupt, return T
|
||||
// int (*intr)(CPU*); // handle interrupt, return T
|
||||
xAsmScan (*asmbl)(const char*, char*); // compile mnemonic
|
||||
xMnem (*mnem)(CPU*, unsigned short, cbdmr, void*);
|
||||
} cpuCore;
|
||||
|
@ -30,17 +30,17 @@ void zx_sync(Computer* comp, long ns) {
|
||||
if (!comp->cpu->iff1 || comp->cpu->noint) return;
|
||||
if (comp->vid->intFRAME && (comp->vid->intMask & 1)) {
|
||||
comp->intVector = 0xff;
|
||||
comp->cpu->inth = 1;
|
||||
// comp->cpu->inth = 1;
|
||||
comp->cpu->intrq |= 1;
|
||||
comp->vid->intFRAME = 0;
|
||||
} else if (comp->vid->intLINE) {
|
||||
comp->intVector = 0xfd;
|
||||
comp->cpu->inth = 1;
|
||||
// comp->cpu->inth = 1;
|
||||
comp->cpu->intrq |= 1;
|
||||
comp->vid->intLINE = 0;
|
||||
} else if (comp->vid->intDMA) {
|
||||
comp->intVector = 0xfb;
|
||||
comp->cpu->inth = 1;
|
||||
// comp->cpu->inth = 1;
|
||||
comp->cpu->intrq |= 1;
|
||||
comp->vid->intDMA = 0;
|
||||
}
|
||||
|
@ -732,8 +732,8 @@ void gbc_sync(Computer* comp, long ns) {
|
||||
req |= 16;
|
||||
}
|
||||
comp->cpu->intrq |= req; // cpu int req
|
||||
if (comp->cpu->iff1 && (comp->cpu->intrq & 0x1f)) //comp->cpu->inten))
|
||||
comp->cpu->inth = 1;
|
||||
// if (comp->cpu->iff1 && (comp->cpu->intrq & 0x1f)) //comp->cpu->inten))
|
||||
// comp->cpu->inth = 1;
|
||||
}
|
||||
|
||||
// keypress
|
||||
|
@ -4,55 +4,55 @@
|
||||
|
||||
HardWare hwTab[] = {
|
||||
{
|
||||
"ZX48K","ZX 48K",HW_ZX48,50,MEM_48,
|
||||
HW_ZX48,"ZX48K","ZX 48K",50,MEM_48,
|
||||
&speMapMem,&speOut,&speIn,&stdMRd,&stdMWr,&speReset,&zx_sync
|
||||
},{
|
||||
"Pentagon","Pentagon",HW_PENT,50,MEM_128 | MEM_512,
|
||||
HW_PENT,"Pentagon","Pentagon",50,MEM_128 | MEM_512,
|
||||
&penMapMem,&penOut,&penIn,&stdMRd,&stdMWr,NULL,&zx_sync
|
||||
},{
|
||||
"Pentagon1024SL","Pentagon 1024 SL",HW_P1024,50,MEM_1M,
|
||||
HW_P1024,"Pentagon1024SL","Pentagon 1024 SL",50,MEM_1M,
|
||||
&p1mMapMem,&p1mOut,&p1mIn,&stdMRd,&stdMWr,NULL,&zx_sync
|
||||
},{
|
||||
"Scorpion","ZS Scorpion",HW_SCORP,50,MEM_256 | MEM_1M,
|
||||
HW_SCORP,"Scorpion","ZS Scorpion",50,MEM_256 | MEM_1M,
|
||||
&scoMapMem,&scoOut,&scoIn,&scoMRd,&stdMWr,NULL,&zx_sync
|
||||
},{
|
||||
"ATM2","ATM Turbo 2+",HW_ATM2,50,MEM_128 | MEM_256 | MEM_512 | MEM_1M,
|
||||
HW_ATM2,"ATM2","ATM Turbo 2+",50,MEM_128 | MEM_256 | MEM_512 | MEM_1M,
|
||||
&atm2MapMem,&atm2Out,&atm2In,&stdMRd,&stdMWr,&atm2Reset,&zx_sync
|
||||
},{
|
||||
"Profi","Profi",HW_PROFI,50,MEM_512 | MEM_1M,
|
||||
HW_PROFI,"Profi","Profi",50,MEM_512 | MEM_1M,
|
||||
&prfMapMem,&prfOut,&prfIn,&stdMRd,&stdMWr,&prfReset,&zx_sync
|
||||
},{
|
||||
"Phoenix","ZXM Phoenix",HW_PHOENIX,50,MEM_2M,
|
||||
HW_PHOENIX,"Phoenix","ZXM Phoenix",50,MEM_2M,
|
||||
&phxMapMem,&phxOut,&phxIn,&stdMRd,&stdMWr,&phxReset,&zx_sync
|
||||
},{
|
||||
"PentEvo","Evo Baseconf",HW_PENTEVO,50,MEM_4M,
|
||||
HW_PENTEVO,"PentEvo","Evo Baseconf",50,MEM_4M,
|
||||
&evoMapMem,&evoOut,&evoIn,&evoMRd,&evoMWr,&evoReset,&zx_sync
|
||||
},{
|
||||
"TSLab","Evo TSConf",HW_TSLAB,50,MEM_4M,
|
||||
HW_TSLAB,"TSLab","Evo TSConf",50,MEM_4M,
|
||||
&tslMapMem,&tslOut,&tslIn,&tslMRd,&tslMWr,&tslReset,&zx_sync
|
||||
},{
|
||||
"","",HW_NULL,50,0,NULL,NULL,NULL,NULL,NULL,NULL // separator
|
||||
HW_NULL,"","",50,0,NULL,NULL,NULL,NULL,NULL,NULL // separator
|
||||
},{
|
||||
"Spectrum +2","Spectrum +2",HW_PLUS2,50,MEM_128,
|
||||
HW_PLUS2,"Spectrum +2","Spectrum +2",50,MEM_128,
|
||||
&pl2MapMem,&pl2Out,&pl2In,&stdMRd,&stdMWr,NULL,&zx_sync
|
||||
},{
|
||||
"Spectrum +3","Spectrum +3",HW_PLUS3,50,MEM_128,
|
||||
HW_PLUS3,"Spectrum +3","Spectrum +3",50,MEM_128,
|
||||
&pl2MapMem,&pl3Out,&pl3In,&stdMRd,&stdMWr,NULL,&zx_sync
|
||||
},{
|
||||
"","",HW_NULL,50,0,NULL,NULL,NULL,NULL,NULL,NULL // separator
|
||||
HW_NULL,"","",50,0,NULL,NULL,NULL,NULL,NULL,NULL // separator
|
||||
},{
|
||||
"MSX","MSX-1",HW_MSX,60,MEM_128,
|
||||
HW_MSX,"MSX","MSX-1",60,MEM_128,
|
||||
&msxMapMem,&msxOut,&msxIn,&stdMRd,&stdMWr,&msxReset,&msx_sync
|
||||
},{
|
||||
"MSX2","MSX-2 (alfa)",HW_MSX2,60,MEM_128,
|
||||
HW_MSX2,"MSX2","MSX-2 (alfa)",60,MEM_128,
|
||||
&msx2mapper,&msx2Out,&msx2In,&msx2mrd,&msx2mwr,&msx2Reset,&msx_sync
|
||||
},{
|
||||
"","",HW_NULL,50,0,NULL,NULL,NULL,NULL,NULL,NULL // separator
|
||||
HW_NULL,"","",50,0,NULL,NULL,NULL,NULL,NULL,NULL // separator
|
||||
},{
|
||||
"GameBoy", "Game Boy", HW_GBC, 60, MEM_48,
|
||||
&gbMaper, NULL, NULL, &gbMemRd, &gbMemWr, &gbReset, &gbc_sync
|
||||
HW_GBC,"GameBoy","Game Boy",60,MEM_48,
|
||||
&gbMaper,NULL,NULL,&gbMemRd,&gbMemWr,&gbReset,&gbc_sync
|
||||
},{
|
||||
NULL,NULL,HW_NULL,50,0,NULL,NULL,NULL,NULL,NULL,NULL // eot
|
||||
HW_NULL,NULL,NULL,50,0,NULL,NULL,NULL,NULL,NULL,NULL // eot
|
||||
}
|
||||
};
|
||||
|
||||
@ -60,7 +60,7 @@ HardWare* findHardware(const char* name) {
|
||||
HardWare* hw = NULL;
|
||||
int idx = 0;
|
||||
while (hwTab[idx].name != NULL) {
|
||||
if ((hwTab[idx].type != HW_NULL) && !strcmp(hwTab[idx].name,name)) {
|
||||
if ((hwTab[idx].id != HW_NULL) && !strcmp(hwTab[idx].name,name)) {
|
||||
hw = &hwTab[idx];
|
||||
break;
|
||||
}
|
||||
|
@ -37,12 +37,37 @@ enum {
|
||||
#define MEM_2M (1<<4)
|
||||
#define MEM_4M (1<<5)
|
||||
|
||||
// Hardware callbacks
|
||||
|
||||
// reset
|
||||
typedef void(*cbHwRes)(Computer*);
|
||||
// map memory
|
||||
typedef void(*cbHwMap)(Computer*);
|
||||
// sync: calls after every CPU command
|
||||
typedef void(*cbHwSnc)(Computer*, long);
|
||||
// memory read
|
||||
typedef unsigned char(*cbHwMrd)(Computer*, unsigned short, int);
|
||||
// memory write
|
||||
typedef void(*cbHwMwr)(Computer*, unsigned short, unsigned char);
|
||||
// io read; TODO:remove last argument (bdi activity)
|
||||
typedef unsigned char(*cbHwIrd)(Computer*, unsigned short, int);
|
||||
// io write
|
||||
typedef void(*cbHwIwr)(Computer*, unsigned short, unsigned char, int);
|
||||
|
||||
struct HardWare {
|
||||
int id; // id
|
||||
const char* name; // name used for conf file
|
||||
const char* optName; // name used for setup window
|
||||
int type; // id
|
||||
int fps;
|
||||
int mask; // mem size bits (b0:128, b1:256, b2:512, b3:1M, b4:2M, b5:4M); =0 for 48K
|
||||
cbHwMap mapMem;
|
||||
cbHwIwr out;
|
||||
cbHwIrd in;
|
||||
cbHwMrd mrd;
|
||||
cbHwMwr mwr;
|
||||
cbHwRes reset;
|
||||
cbHwSnc sync;
|
||||
/*
|
||||
void (*mapMem)(Computer*);
|
||||
void (*out)(Computer*,unsigned short,unsigned char,int);
|
||||
unsigned char (*in)(Computer*,unsigned short,int);
|
||||
@ -50,6 +75,7 @@ struct HardWare {
|
||||
void (*mwr)(Computer*,unsigned short,unsigned char);
|
||||
void (*reset)(Computer*);
|
||||
void (*sync)(Computer*, long); // callback after each command. control request/handle interrupt bit
|
||||
*/
|
||||
};
|
||||
|
||||
typedef struct {
|
||||
|
@ -249,7 +249,8 @@ void msxOut(Computer* comp, unsigned short port, unsigned char val, int dos) {
|
||||
// int zxINT(Computer*, unsigned char);
|
||||
void msx_sync(Computer* comp, long ns) {
|
||||
if ((comp->vid->v9938.reg[1] & 0x40) && comp->vid->newFrame && comp->cpu->iff1) {
|
||||
comp->cpu->inth = 1;
|
||||
// comp->cpu->inth = 1;
|
||||
comp->cpu->intrq |= 1;
|
||||
comp->intVector = 0xff;
|
||||
}
|
||||
}
|
||||
|
@ -1,7 +1,7 @@
|
||||
#include "../spectrum.h"
|
||||
|
||||
void speReset(Computer* comp) {
|
||||
comp->p7FFD = 0x10;
|
||||
|
||||
}
|
||||
|
||||
void speMapMem(Computer* comp) {
|
||||
|
@ -130,18 +130,12 @@ void gsSync(GSound* gs) {
|
||||
int res;
|
||||
gs->counter += gs->sync * GS_FRQ / 980; // ticks to emulate
|
||||
while (gs->counter > 0) {
|
||||
if (gs->cpu->inth) {
|
||||
gs->cpu->inth = 0;
|
||||
gs->cpu->intrq = 1;
|
||||
res = gs->cpu->intr(gs->cpu);
|
||||
} else {
|
||||
res = gs->cpu->exec(gs->cpu);
|
||||
}
|
||||
res = gs->cpu->exec(gs->cpu);
|
||||
gs->counter -= res;
|
||||
gs->cnt += res;
|
||||
if (gs->cnt > 320) { // 12MHz CLK, 37.5KHz INT -> int in each 320 ticks
|
||||
gs->cnt -= 320;
|
||||
gs->cpu->inth = 1;
|
||||
gs->cpu->intrq |= 1;
|
||||
}
|
||||
}
|
||||
gs->sync = 0;
|
||||
|
@ -246,7 +246,6 @@ void compReset(Computer* comp,int res) {
|
||||
if (comp->rzx.play) rzxStop(comp);
|
||||
zxInitPalete(comp);
|
||||
comp->vid->ula->active = 0;
|
||||
comp->rzx.play = 0;
|
||||
comp->prt2 = 0;
|
||||
comp->p1FFD = 0;
|
||||
comp->pEFF7 = 0;
|
||||
@ -285,7 +284,7 @@ void compUpdateTimings(Computer* comp) {
|
||||
long perNoTurbo = 1e3 / comp->cpuFrq;
|
||||
if (perNoTurbo & 1) perNoTurbo++;
|
||||
comp->nsPerTick = perNoTurbo / comp->frqMul;
|
||||
int type = comp->hw ? comp->hw->type : HW_NULL;
|
||||
int type = comp->hw ? comp->hw->id : HW_NULL;
|
||||
switch (type) {
|
||||
case HW_MSX:
|
||||
case HW_MSX2:
|
||||
@ -324,25 +323,23 @@ void compSetHardware(Computer* comp, const char* name) {
|
||||
HardWare* hw = findHardware(name);
|
||||
if (hw == NULL) return;
|
||||
comp->hw = hw;
|
||||
comp->vid->istsconf = (hw->type == HW_TSLAB) ? 1 : 0;
|
||||
comp->vid->ismsx = ((hw->type == HW_MSX) || (hw->type == HW_MSX2)) ? 1 : 0;
|
||||
comp->vid->isgb = (hw->type == HW_GBC) ? 1 : 0;
|
||||
comp->vid->istsconf = (hw->id == HW_TSLAB) ? 1 : 0;
|
||||
comp->vid->ismsx = ((hw->id == HW_MSX) || (hw->id == HW_MSX2)) ? 1 : 0;
|
||||
comp->vid->isgb = (hw->id == HW_GBC) ? 1 : 0;
|
||||
compUpdateTimings(comp);
|
||||
}
|
||||
|
||||
// interrupts
|
||||
// exec 1 opcode, sync devices, return eated ns
|
||||
|
||||
// IDEA : let video system to accumulate TIME value, not like (cpu->t * comp->nsPerTick);
|
||||
|
||||
void vidTSRender(Video*, unsigned char*);
|
||||
int compExec(Computer* comp) {
|
||||
res4 = 0;
|
||||
res2 = 0;
|
||||
if (comp->cpu->inth) { // 1:handle interrupt
|
||||
comp->cpu->inth = 0;
|
||||
res2 = comp->cpu->intr(comp->cpu);
|
||||
}
|
||||
if (res2 == 0)
|
||||
res2 = comp->cpu->exec(comp->cpu);
|
||||
// exec cpu opcode OR handle interrupt. get T states back
|
||||
res2 = comp->cpu->exec(comp->cpu);
|
||||
// scorpion WAIT: add 1T to odd-T command
|
||||
if (comp->evenM1 && (res2 & 1))
|
||||
res2++;
|
||||
@ -368,10 +365,9 @@ int compExec(Computer* comp) {
|
||||
// ...
|
||||
res1 = res2;
|
||||
pcreg = comp->cpu->pc;
|
||||
// NMI TODO: remake as another INT
|
||||
// NMI
|
||||
if ((pcreg > 0x3fff) && comp->nmiRequest && !comp->rzx.play) {
|
||||
comp->cpu->intrq |= 2; // request nmi
|
||||
comp->cpu->inth = 1;
|
||||
comp->dos = 1; // set dos page
|
||||
comp->rom = 1;
|
||||
comp->hw->mapMem(comp);
|
||||
@ -383,7 +379,7 @@ int compExec(Computer* comp) {
|
||||
if (comp->rzx.play) {
|
||||
if (comp->rzx.frm.fetches < 1) {
|
||||
comp->intVector = 0xff;
|
||||
comp->cpu->inth = 1;
|
||||
comp->cpu->intrq |= 1;
|
||||
comp->rzx.fCurrent++;
|
||||
comp->rzx.fCount--;
|
||||
rzxGetFrame(comp);
|
||||
@ -399,7 +395,6 @@ int compExec(Computer* comp) {
|
||||
// TSConf : update 'next-line' registers TODO:move to TSConf hw->sync
|
||||
if (comp->vid->nextrow && comp->vid->istsconf) {
|
||||
tslUpdatePorts(comp);
|
||||
// vidTSRender(comp->vid, comp->vid->linptr);
|
||||
comp->vid->nextrow = 0;
|
||||
}
|
||||
// breakpoints
|
||||
@ -419,7 +414,7 @@ int compExec(Computer* comp) {
|
||||
difSync(comp->dif, nsTime);
|
||||
// tsSync(comp->ts, nsTime);
|
||||
|
||||
if (comp->hw->type == HW_GBC) {
|
||||
if (comp->hw->id == HW_GBC) {
|
||||
// sound
|
||||
gbsSync(comp->gbsnd, nsTime);
|
||||
// timer
|
||||
|
@ -59,7 +59,7 @@ SetupWin::SetupWin(QWidget* par):QDialog(par) {
|
||||
// machine
|
||||
i = 0;
|
||||
while (hwTab[i].name != NULL) {
|
||||
if (hwTab[i].type != HW_NULL) {
|
||||
if (hwTab[i].id != HW_NULL) {
|
||||
ui.machbox->addItem(trUtf8(hwTab[i].optName),QString::fromLocal8Bit(hwTab[i].name));
|
||||
} else {
|
||||
ui.machbox->insertSeparator(i);
|
||||
|
@ -1 +1 @@
|
||||
#define VERSION 0.6.20170419
|
||||
#define VERSION 0.6.20170426
|
||||
|
103
src/vkeyboard.cpp
Normal file
103
src/vkeyboard.cpp
Normal file
@ -0,0 +1,103 @@
|
||||
// virtual keyboard
|
||||
|
||||
#include "vkeyboard.h"
|
||||
#include "xcore/xcore.h"
|
||||
|
||||
#include <QPainter>
|
||||
|
||||
unsigned char kwMap[4][10] = {
|
||||
{'1','2','3','4','5','6','7','8','9','0'},
|
||||
{'q','w','e','r','t','y','u','i','o','p'},
|
||||
{'a','s','d','f','g','h','j','k','l','E'},
|
||||
{'C','z','x','c','v','b','n','m','S',' '}
|
||||
};
|
||||
|
||||
keyWindow::keyWindow(QWidget* p):QLabel(p) {
|
||||
kb = NULL;
|
||||
xk.key1 = 0;
|
||||
xk.key2 = 0;
|
||||
// setWindowModality(Qt::WindowModal);
|
||||
}
|
||||
|
||||
void keyWindow::paintEvent(QPaintEvent*) {
|
||||
QPainter pnt;
|
||||
int wid = width() / 10 + 1;
|
||||
int hig = (height() - 10) / 4;
|
||||
unsigned char val;
|
||||
int row, pos;
|
||||
pnt.begin(this);
|
||||
pnt.fillRect(QRectF(0,0,1,1), qRgba(0,0,0,0));
|
||||
// pnt.setPen(qRgb(0, 200, 255));
|
||||
// pnt.setBrush(QBrush(qRgb(0, 180, 235)));
|
||||
for(int i = 0; i < 8; i++) {
|
||||
pos = (i & 4) ? 0 : 9;
|
||||
row = (i & 4) ? (i & 3) : (~i & 3);
|
||||
val = ~kb->map[i] & 0x1f;
|
||||
while(val) {
|
||||
if (val & 1) {
|
||||
pnt.fillRect(pos * wid, 10 + row * hig, wid, hig, qRgb(0, 200, 255));
|
||||
//pnt.drawRoundRect(pos * wid, row * hig, wid, hig);
|
||||
}
|
||||
val >>= 1;
|
||||
pos += (i & 4) ? 1 : -1;
|
||||
}
|
||||
}
|
||||
pnt.drawPixmap(0, 0, QPixmap(":/images/keymap.png"));
|
||||
pnt.end();
|
||||
}
|
||||
|
||||
void keyWindow::mousePressEvent(QMouseEvent* ev) {
|
||||
if (!kb) return;
|
||||
int row;
|
||||
int col;
|
||||
row = ev->y() * 4 / height();
|
||||
col = ev->x() * 10 / width();
|
||||
xk.key1 = kwMap[row][col];
|
||||
switch(ev->button()) {
|
||||
case Qt::LeftButton:
|
||||
keyPress(kb, xk, 0);
|
||||
update();
|
||||
break;
|
||||
case Qt::RightButton:
|
||||
keyTrigger(kb, xk, 0);
|
||||
update();
|
||||
break;
|
||||
case Qt::MiddleButton:
|
||||
keyReleaseAll(kb);
|
||||
xk.key1 = 0;
|
||||
update();
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
void keyWindow::mouseReleaseEvent(QMouseEvent* ev) {
|
||||
if (!kb) return;
|
||||
if (ev->button() == Qt::LeftButton) {
|
||||
keyRelease(kb, xk, 0);
|
||||
}
|
||||
update();
|
||||
}
|
||||
|
||||
void keyWindow::keyPressEvent(QKeyEvent* ev) {
|
||||
int keyid = qKey2id(ev->key());
|
||||
keyEntry kent = getKeyEntry(keyid);
|
||||
if (ev->modifiers() & Qt::AltModifier) {
|
||||
if (ev->key() == Qt::Key_K)
|
||||
close();
|
||||
} else {
|
||||
keyPress(kb, kent.zxKey, 0);
|
||||
if (kent.msxKey.key1)
|
||||
keyPress(kb,kent.msxKey,2);
|
||||
update();
|
||||
}
|
||||
}
|
||||
|
||||
void keyWindow::keyReleaseEvent(QKeyEvent* ev) {
|
||||
int keyid = qKey2id(ev->key());
|
||||
keyEntry kent = getKeyEntry(keyid);
|
||||
keyRelease(kb, kent.zxKey, 0);
|
||||
if (kent.msxKey.key1) keyRelease(kb,kent.msxKey,2);
|
||||
update();
|
||||
}
|
27
src/vkeyboard.h
Normal file
27
src/vkeyboard.h
Normal file
@ -0,0 +1,27 @@
|
||||
#ifndef _VKEYBOARD_H
|
||||
#define _VKEYBOARD_H
|
||||
|
||||
#include <QWidget>
|
||||
#include <QLabel>
|
||||
#include <QPaintEvent>
|
||||
#include <QMouseEvent>
|
||||
#include <QKeyEvent>
|
||||
|
||||
#include "libxpeccy/input.h"
|
||||
|
||||
class keyWindow : public QLabel {
|
||||
Q_OBJECT
|
||||
public:
|
||||
keyWindow(QWidget* = NULL);
|
||||
Keyboard* kb;
|
||||
private:
|
||||
xKey xk;
|
||||
protected:
|
||||
void paintEvent(QPaintEvent*);
|
||||
void mousePressEvent(QMouseEvent*);
|
||||
void mouseReleaseEvent(QMouseEvent*);
|
||||
void keyPressEvent(QKeyEvent*);
|
||||
void keyReleaseEvent(QKeyEvent*);
|
||||
};
|
||||
|
||||
#endif
|
@ -2,8 +2,6 @@
|
||||
|
||||
#include "xcore.h"
|
||||
|
||||
// #if __linux
|
||||
|
||||
#define XKEY_1 10
|
||||
#define XKEY_2 11
|
||||
#define XKEY_3 12
|
||||
@ -90,94 +88,6 @@
|
||||
#define XKEY_RBRACK 257 // }
|
||||
#define XKEY_QUEST 258
|
||||
|
||||
/*
|
||||
#elif _WIN32
|
||||
|
||||
#define XKEY_1 2
|
||||
#define XKEY_2 3
|
||||
#define XKEY_3 4
|
||||
#define XKEY_4 5
|
||||
#define XKEY_5 6
|
||||
#define XKEY_6 7
|
||||
#define XKEY_7 8
|
||||
#define XKEY_8 9
|
||||
#define XKEY_9 10
|
||||
#define XKEY_0 11
|
||||
#define XKEY_MINUS 12
|
||||
#define XKEY_PLUS 13
|
||||
#define XKEY_BSP 14
|
||||
#define XKEY_TAB 15
|
||||
#define XKEY_Q 16
|
||||
#define XKEY_W 17
|
||||
#define XKEY_E 18
|
||||
#define XKEY_R 19
|
||||
#define XKEY_T 20
|
||||
#define XKEY_Y 21
|
||||
#define XKEY_U 22
|
||||
#define XKEY_I 23
|
||||
#define XKEY_O 24
|
||||
#define XKEY_P 25
|
||||
#define XKEY_LBRACE 26
|
||||
#define XKEY_RBRACE 27
|
||||
#define XKEY_ENTER 28
|
||||
#define XKEY_LCTRL 29
|
||||
#define XKEY_A 30
|
||||
#define XKEY_S 31
|
||||
#define XKEY_D 32
|
||||
#define XKEY_F 33
|
||||
#define XKEY_G 34
|
||||
#define XKEY_H 35
|
||||
#define XKEY_J 36
|
||||
#define XKEY_K 37
|
||||
#define XKEY_L 38
|
||||
#define XKEY_DOTCOM 39 // ;
|
||||
#define XKEY_QUOTE 40 // "
|
||||
#define XKEY_TILDA 41 // ~
|
||||
#define XKEY_LSHIFT 42
|
||||
#define XKEY_SLASH 43
|
||||
#define XKEY_Z 44
|
||||
#define XKEY_X 45
|
||||
#define XKEY_C 46
|
||||
#define XKEY_V 47
|
||||
#define XKEY_B 48
|
||||
#define XKEY_N 49
|
||||
#define XKEY_M 50
|
||||
#define XKEY_PERIOD 51
|
||||
#define XKEY_COMMA 52
|
||||
#define XKEY_BSLASH 53 // /
|
||||
#define XKEY_RSHIFT 54
|
||||
#define XKEY_SPACE 57
|
||||
#define XKEY_CAPS 58
|
||||
#define XKEY_RCTRL XKEY_LCTRL
|
||||
#define XKEY_RALT 312
|
||||
#define XKEY_LALT 56
|
||||
#define XKEY_HOME 327
|
||||
#define XKEY_UP 328
|
||||
#define XKEY_PGUP 329
|
||||
#define XKEY_LEFT 331
|
||||
#define XKEY_RIGHT 333
|
||||
#define XKEY_END 335
|
||||
#define XKEY_DOWN 336
|
||||
#define XKEY_PGDN 337
|
||||
#define XKEY_INS 338
|
||||
#define XKEY_DEL 339
|
||||
#define XKEY_MENU 349
|
||||
#define XKEY_ESC 1
|
||||
#define XKEY_F1 59
|
||||
#define XKEY_F2 60
|
||||
#define XKEY_F3 61
|
||||
#define XKEY_F4 62
|
||||
#define XKEY_F5 63
|
||||
#define XKEY_F6 64
|
||||
#define XKEY_F7 65
|
||||
#define XKEY_F8 66
|
||||
#define XKEY_F9 67
|
||||
#define XKEY_F10 68
|
||||
#define XKEY_F11 87
|
||||
|
||||
#endif
|
||||
*/
|
||||
|
||||
#define ENDKEY 0
|
||||
|
||||
// KEYMAPS
|
||||
@ -240,7 +150,7 @@ keyEntry keyMapInit[] = {
|
||||
{"[",XKEY_LBRACK,{'S','8'},{'S','y'},{'[',0},0x54},
|
||||
{"]",XKEY_RBRACK,{'S','9'},{'S','u'},{']',0},0x5b},
|
||||
{"`",XKEY_TILDA,{'C','S'},{'S','x'},{'`',0},0x0e},
|
||||
{"\\",XKEY_SLASH,{'S','c'},{'S','d'},{'\\',0},0x5d},
|
||||
{"\\",XKEY_SLASH,{'S','C'},{0,0},{'\\',0},0x5d},
|
||||
|
||||
{"PGDN",XKEY_PGUP,{'C','3'},{'m'|0x80,0},{MSXK_CODE,0},0x7de0},
|
||||
{"PGUP",XKEY_PGDN,{'C','4'},{'n'|0x80,0},{MSXK_SEL,0},0x7ae0},
|
||||
@ -354,7 +264,7 @@ keyTrans ktTab[] = {
|
||||
{Qt::Key_BracketRight, 1066, XKEY_RBRACK}, // ]
|
||||
// {Qt::Key_BraceLeft, 1061, XKEY_LBRACE}, // { == Shift + [
|
||||
// {Qt::Key_BraceRight, 1066, XKEY_LBRACE}, // } == Shift + ]
|
||||
{Qt::Key_Slash, Qt::Key_Slash, XKEY_BSLASH}, // ?
|
||||
{Qt::Key_Backslash, Qt::Key_Backslash, XKEY_SLASH}, // |
|
||||
|
||||
{Qt::Key_CapsLock, Qt::Key_CapsLock, XKEY_CAPS},
|
||||
{Qt::Key_A, 1060, XKEY_A},
|
||||
@ -380,6 +290,7 @@ keyTrans ktTab[] = {
|
||||
{Qt::Key_M, 1068, XKEY_M},
|
||||
{Qt::Key_Period, 1041, XKEY_PERIOD},
|
||||
{Qt::Key_Comma, Qt::Key_Comma, XKEY_COMMA},
|
||||
{Qt::Key_Slash, Qt::Key_Slash, XKEY_BSLASH}, // ?
|
||||
|
||||
{Qt::Key_Control, Qt::Key_Control, XKEY_LCTRL},
|
||||
{Qt::Key_Alt, Qt::Key_Alt, XKEY_LALT},
|
||||
|
@ -4,12 +4,12 @@
|
||||
#include "xcore.h"
|
||||
|
||||
#include <iostream>
|
||||
#include <mutex>
|
||||
#include <QMutex>
|
||||
|
||||
#include <SDL.h>
|
||||
#undef main
|
||||
|
||||
extern std::mutex emutex; // unlock to start emulation cycle
|
||||
extern QMutex emutex; // unlock to start emulation cycle
|
||||
|
||||
typedef struct {
|
||||
unsigned char data[0x1000];
|
||||
|
@ -2220,7 +2220,7 @@
|
||||
<action name="actSprScan">
|
||||
<property name="icon">
|
||||
<iconset resource="../xpeccy.qrc">
|
||||
<normaloff>:/images/eye.png</normaloff>:/images/eye.png</iconset>
|
||||
<normaloff>:/images/pixels.png</normaloff>:/images/pixels.png</iconset>
|
||||
</property>
|
||||
<property name="text">
|
||||
<string>Sprite scanner</string>
|
||||
|
@ -48,7 +48,6 @@
|
||||
<file>images/msx.png</file>
|
||||
<file>images/stop.png</file>
|
||||
<file>images/floppyRed.png</file>
|
||||
<file>images/eye.png</file>
|
||||
<file>images/gameboy.png</file>
|
||||
<file>font.bin</file>
|
||||
<file>images/label.png</file>
|
||||
@ -61,5 +60,9 @@
|
||||
<file>images/search.png</file>
|
||||
<file>DejaVuSansMono.ttf</file>
|
||||
<file>images/note.png</file>
|
||||
<file>images/keyboardzx.png</file>
|
||||
<file>images/objective.png</file>
|
||||
<file>images/pixels.png</file>
|
||||
<file>images/cartrige.png</file>
|
||||
</qresource>
|
||||
</RCC>
|
||||
|
Loading…
x
Reference in New Issue
Block a user