mirror of
https://git.code.sf.net/p/newrpl/sources
synced 2024-11-16 19:51:25 +01:00
Added Stack save/load and clipboard support to PC simulator
This commit is contained in:
parent
7b6294ae8a
commit
9b2a13dc51
9 changed files with 338 additions and 7 deletions
|
@ -10,6 +10,7 @@
|
|||
|
||||
unsigned int cpu_state;
|
||||
unsigned int __saveint;
|
||||
volatile unsigned int __cpu_idle;
|
||||
|
||||
enum {
|
||||
CPU_INTMASKED=1,
|
||||
|
@ -74,7 +75,13 @@ void cpu_waitforinterrupt()
|
|||
// BLOCK THREAD UNTIL AN INTERRUPT HAS OCCURRED
|
||||
|
||||
// ON THE PC, JUST YIELD FOR 1 MSECOND
|
||||
|
||||
// BLOCK SO OTHER THREAD CAN DO WORK ON RPL
|
||||
while(__cpu_idle==2) thread_yield();
|
||||
|
||||
__cpu_idle=1;
|
||||
thread_yield();
|
||||
if(__cpu_idle==1) __cpu_idle=0;
|
||||
}
|
||||
|
||||
// ACQUIRE A LOCK AND RETURN PREVIOUS VALUE
|
||||
|
|
123
interaction.cpp
Normal file
123
interaction.cpp
Normal file
|
@ -0,0 +1,123 @@
|
|||
#include <QtGui>
|
||||
#include <QtCore>
|
||||
#include <QClipboard>
|
||||
|
||||
|
||||
extern "C" {
|
||||
// DECLARATIONS SPLIT TO AVOID CONFLICT OF TYPES
|
||||
|
||||
uint32_t *getrplstackobject(int level,int *size);
|
||||
char *getdecompiledrplobject(int level,int *strsize);
|
||||
void pushobject(char *data,int sizebytes);
|
||||
void pushtext(char *data,int sizebytes);
|
||||
void removestackobject(int level,int nitems);
|
||||
|
||||
}
|
||||
|
||||
// COPY OBJECT FROM THE STACK INTO THE HOST CLIPBOARD
|
||||
void Stack2Clipboard(int level,int dropit)
|
||||
{
|
||||
|
||||
uint32_t *obj;
|
||||
int size;
|
||||
|
||||
obj=getrplstackobject(level,&size);
|
||||
|
||||
if(!obj) return;
|
||||
|
||||
|
||||
QClipboard *clip = qApp->clipboard();
|
||||
QMimeData *data=new QMimeData;
|
||||
QByteArray buffer;
|
||||
buffer.append((const char *)obj,size*sizeof(int32_t));
|
||||
|
||||
data->setData(QString("application/newrpl-object"),buffer);
|
||||
|
||||
char *text;
|
||||
int strsize;
|
||||
|
||||
text=getdecompiledrplobject(level,&strsize);
|
||||
|
||||
if(!text) return;
|
||||
|
||||
QByteArray decomptext((const char *)text,strsize);
|
||||
QString utf8string(decomptext);
|
||||
data->setText(utf8string);
|
||||
data->setHtml(utf8string);
|
||||
clip->setMimeData(data,QClipboard::Clipboard);
|
||||
|
||||
if(dropit) removestackobject(level,1);
|
||||
|
||||
}
|
||||
|
||||
// PUSH THE CLIPBOARD IN THE STACK
|
||||
void Clipboard2Stack()
|
||||
{
|
||||
QClipboard *clip = qApp->clipboard();
|
||||
const QMimeData *data=clip->mimeData();
|
||||
|
||||
if(data->hasFormat(QString("application/newrpl-object"))) {
|
||||
QByteArray mydata(data->data(QString("application/newrpl-object")));
|
||||
|
||||
pushobject(mydata.data(),mydata.size());
|
||||
return;
|
||||
}
|
||||
|
||||
if(data->hasText()) {
|
||||
QByteArray mydata(data->text().toUtf8());
|
||||
pushtext(mydata.data(),mydata.size());
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
int SaveRPLObject(QString& filename,int level)
|
||||
{
|
||||
uint32_t *obj;
|
||||
int size;
|
||||
|
||||
obj=getrplstackobject(level,&size);
|
||||
|
||||
if(!obj) return 0;
|
||||
|
||||
|
||||
QFile f(filename);
|
||||
|
||||
if(!f.open(QIODevice::WriteOnly|QIODevice::Truncate)) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
const char *fileprolog="NRPL";
|
||||
f.write(fileprolog,4);
|
||||
f.write((const char *)obj,size*4);
|
||||
f.close();
|
||||
|
||||
return 1;
|
||||
|
||||
}
|
||||
|
||||
|
||||
int LoadRPLObject(QString& filename)
|
||||
{
|
||||
uint32_t *obj;
|
||||
int size;
|
||||
|
||||
QFile f(filename);
|
||||
|
||||
if(!f.open(QIODevice::ReadOnly)) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
size=f.size();
|
||||
if(size&3) return 0;
|
||||
QByteArray data=f.read(f.size());
|
||||
|
||||
if( (data.at(0)!='N')||(data.at(1)!='R')||(data.at(2)!='P')||(data.at(3)!='L'))
|
||||
return 0;
|
||||
|
||||
pushobject(data.data()+4,data.size()-4);
|
||||
|
||||
f.close();
|
||||
|
||||
return 1;
|
||||
|
||||
}
|
64
interaction_rpl.c
Normal file
64
interaction_rpl.c
Normal file
|
@ -0,0 +1,64 @@
|
|||
|
||||
// THIS FILE ISOLATES THE COMPONENTS THAT INTERACT WITH NEWRPL
|
||||
// THIS IS ONLY NEEDED BECAUSE OF THE REDEFINITION OF THE TYPE WORD
|
||||
// IN NEWRPL CONFLICTING WITH QT
|
||||
|
||||
#include <newrpl.h>
|
||||
#include <ui.h>
|
||||
|
||||
// GET A POINTER TO AN OBJECT ON THE STACK, AS WELL AS ITS SIZE
|
||||
uint32_t *getrplstackobject(int level,int *size)
|
||||
{
|
||||
if(level>rplDepthData()) return 0;
|
||||
if(level<1) return 0;
|
||||
if(size) *size=rplObjSize(rplPeekData(level));
|
||||
return rplPeekData(level);
|
||||
}
|
||||
|
||||
void removestackobject(int level,int nitems)
|
||||
{
|
||||
if(rplDepthData()>=level+nitems-1) rplRemoveAtData(level,nitems);
|
||||
halScreen.DirtyFlag|=CMDLINE_ALLDIRTY|FORM_DIRTY|STACK_DIRTY|MENU1_DIRTY|MENU2_DIRTY|STAREA_DIRTY;
|
||||
|
||||
}
|
||||
|
||||
|
||||
|
||||
// DECOMPILES THE OBJECT AT THE STACK, THEN STORES THE SIZE OF THE STRING AND
|
||||
// RETURNS A POINTER TO THE TEXT
|
||||
char *getdecompiledrplobject(int level,int *strsize)
|
||||
{
|
||||
if(level>rplDepthData()) return 0;
|
||||
if(level<1) return 0;
|
||||
|
||||
WORDPTR newobj=rplDecompile(rplPeekData(level),DECOMP_MAXWIDTH(60));
|
||||
if(!newobj) return 0;
|
||||
if(strsize) *strsize=rplStrSize(newobj);
|
||||
return (char *)(newobj+1);
|
||||
}
|
||||
|
||||
// PUSH A BINARY OBJECT IN THE STACK
|
||||
// OBJECT IS GIVEN BY A STREAM OF BYTES
|
||||
void pushobject(char *data,int sizebytes)
|
||||
{
|
||||
if(sizebytes&3) return; // SIZE MUST BE MULTIPLE OF 4, OTHERWISE IT'S AN INVALID OBJECT
|
||||
|
||||
WORDPTR newobj=rplAllocTempOb((sizebytes-1)/4);
|
||||
if(!newobj) return;
|
||||
memmoveb((char *)newobj,data,sizebytes);
|
||||
rplPushData(newobj);
|
||||
halScreen.DirtyFlag|=CMDLINE_ALLDIRTY|FORM_DIRTY|STACK_DIRTY|MENU1_DIRTY|MENU2_DIRTY|STAREA_DIRTY;
|
||||
}
|
||||
|
||||
// PUSH A TEXT OBJECT IN THE STACK
|
||||
void pushtext(char *data,int sizebytes)
|
||||
{
|
||||
WORDPTR newobj=rplCreateStringBySize(sizebytes);
|
||||
if(!newobj) return;
|
||||
|
||||
memmoveb((char *)(newobj+1),data,sizebytes);
|
||||
|
||||
rplPushData(newobj);
|
||||
halScreen.DirtyFlag|=CMDLINE_ALLDIRTY|FORM_DIRTY|STACK_DIRTY|MENU1_DIRTY|MENU2_DIRTY|STAREA_DIRTY;
|
||||
|
||||
}
|
|
@ -23,6 +23,8 @@ MainWindow *myMainWindow;
|
|||
extern unsigned long long __pckeymatrix;
|
||||
extern int __pc_terminate;
|
||||
extern int __memmap_intact;
|
||||
extern volatile int __cpu_idle;
|
||||
|
||||
extern "C" void __keyb_update();
|
||||
// BACKUP/RESTORE
|
||||
extern "C" int rplBackup(void (*writefunc)(unsigned int));
|
||||
|
@ -680,3 +682,90 @@ void MainWindow::on_actionTake_Screenshot_triggered()
|
|||
image.save(fname);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
extern void Stack2Clipboard(int level,int dropit);
|
||||
extern void Clipboard2Stack();
|
||||
extern int SaveRPLObject(QString& filename,int level);
|
||||
int LoadRPLObject(QString& filename);
|
||||
|
||||
|
||||
void MainWindow::on_actionCopy_Level_1_triggered()
|
||||
{
|
||||
if(!rpl.isRunning()) return; // DO NOTHING
|
||||
|
||||
while(!__cpu_idle) QThread::msleep(1); // BLOCK UNTIL RPL IS IDLE
|
||||
|
||||
__cpu_idle=2; // BLOCK REQUEST
|
||||
|
||||
// NOW WORK ON THE RPL ENGINE WHILE THE THREAD IS BLOCKED
|
||||
Stack2Clipboard(1,0);
|
||||
|
||||
__cpu_idle=0; // LET GO THE SIMULATOR
|
||||
}
|
||||
|
||||
void MainWindow::on_actionPaste_to_Level_1_triggered()
|
||||
{
|
||||
if(!rpl.isRunning()) return; // DO NOTHING
|
||||
|
||||
while(!__cpu_idle) QThread::msleep(1); // BLOCK UNTIL RPL IS IDLE
|
||||
|
||||
__cpu_idle=2; // BLOCK REQUEST
|
||||
|
||||
// NOW WORK ON THE RPL ENGINE WHILE THE THREAD IS BLOCKED
|
||||
Clipboard2Stack();
|
||||
|
||||
__cpu_idle=0; // LET GO THE SIMULATOR
|
||||
|
||||
}
|
||||
|
||||
void MainWindow::on_actionCut_Level_1_triggered()
|
||||
{
|
||||
if(!rpl.isRunning()) return; // DO NOTHING
|
||||
|
||||
while(!__cpu_idle) QThread::msleep(1); // BLOCK UNTIL RPL IS IDLE
|
||||
|
||||
__cpu_idle=2; // BLOCK REQUEST
|
||||
|
||||
// NOW WORK ON THE RPL ENGINE WHILE THE THREAD IS BLOCKED
|
||||
Stack2Clipboard(1,1);
|
||||
|
||||
__cpu_idle=0; // LET GO THE SIMULATOR
|
||||
}
|
||||
|
||||
void MainWindow::on_actionSave_Level_1_As_triggered()
|
||||
{
|
||||
QString fname=QFileDialog::getSaveFileName(this,"Select File Name",QString(),"*.nrpl");
|
||||
|
||||
if(!fname.isEmpty()) {
|
||||
// GOT A NAME, APPEND EXTENSION IF NOT GIVEN
|
||||
|
||||
if(!fname.endsWith(".nrpl")) fname+=".nrpl";
|
||||
}
|
||||
|
||||
if(!SaveRPLObject(fname,1)) {
|
||||
QMessageBox a(QMessageBox::Warning,"Error while saving","Cannot write to file "+ fname,QMessageBox::Ok,this);
|
||||
a.exec();
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
void MainWindow::on_actionOpen_file_to_Level_1_triggered()
|
||||
{
|
||||
QString fname=QFileDialog::getOpenFileName(this,"Select File Name",QString(),"*.nrpl");
|
||||
if(!rpl.isRunning()) return; // DO NOTHING
|
||||
|
||||
while(!__cpu_idle) QThread::msleep(1); // BLOCK UNTIL RPL IS IDLE
|
||||
|
||||
__cpu_idle=2; // BLOCK REQUEST
|
||||
|
||||
// NOW WORK ON THE RPL ENGINE WHILE THE THREAD IS BLOCKED
|
||||
if(!LoadRPLObject(fname)) {
|
||||
QMessageBox a(QMessageBox::Warning,"Error while saving","Cannot write to file "+ fname,QMessageBox::Ok,this);
|
||||
a.exec();
|
||||
return;
|
||||
}
|
||||
|
||||
__cpu_idle=0; // LET GO THE SIMULATOR
|
||||
|
||||
}
|
||||
|
|
10
mainwindow.h
10
mainwindow.h
|
@ -60,6 +60,16 @@ private slots:
|
|||
|
||||
void on_actionTake_Screenshot_triggered();
|
||||
|
||||
void on_actionCopy_Level_1_triggered();
|
||||
|
||||
void on_actionPaste_to_Level_1_triggered();
|
||||
|
||||
void on_actionCut_Level_1_triggered();
|
||||
|
||||
void on_actionSave_Level_1_As_triggered();
|
||||
|
||||
void on_actionOpen_file_to_Level_1_triggered();
|
||||
|
||||
public slots:
|
||||
void domaintimer();
|
||||
private:
|
||||
|
|
|
@ -116,7 +116,7 @@ border-width: 0px;</string>
|
|||
<x>0</x>
|
||||
<y>0</y>
|
||||
<width>1016</width>
|
||||
<height>25</height>
|
||||
<height>21</height>
|
||||
</rect>
|
||||
</property>
|
||||
<widget class="QMenu" name="menuFile">
|
||||
|
@ -147,7 +147,18 @@ border-width: 0px;</string>
|
|||
<addaction name="actionSimulate_Alarm"/>
|
||||
<addaction name="actionTake_Screenshot"/>
|
||||
</widget>
|
||||
<widget class="QMenu" name="menuStack">
|
||||
<property name="title">
|
||||
<string>Stack</string>
|
||||
</property>
|
||||
<addaction name="actionCopy_Level_1"/>
|
||||
<addaction name="actionCut_Level_1"/>
|
||||
<addaction name="actionPaste_to_Level_1"/>
|
||||
<addaction name="actionSave_Level_1_As"/>
|
||||
<addaction name="actionOpen_file_to_Level_1"/>
|
||||
</widget>
|
||||
<addaction name="menuFile"/>
|
||||
<addaction name="menuStack"/>
|
||||
<addaction name="menuSD_Card"/>
|
||||
<addaction name="menuHardware"/>
|
||||
</widget>
|
||||
|
@ -254,6 +265,31 @@ border-width: 0px;</string>
|
|||
<string>Take Screenshot</string>
|
||||
</property>
|
||||
</action>
|
||||
<action name="actionCopy_Level_1">
|
||||
<property name="text">
|
||||
<string>Copy Level 1</string>
|
||||
</property>
|
||||
</action>
|
||||
<action name="actionCut_Level_1">
|
||||
<property name="text">
|
||||
<string>Cut Level 1</string>
|
||||
</property>
|
||||
</action>
|
||||
<action name="actionPaste_to_Level_1">
|
||||
<property name="text">
|
||||
<string>Paste to Level 1</string>
|
||||
</property>
|
||||
</action>
|
||||
<action name="actionSave_Level_1_As">
|
||||
<property name="text">
|
||||
<string>Save Level 1 As...</string>
|
||||
</property>
|
||||
</action>
|
||||
<action name="actionOpen_file_to_Level_1">
|
||||
<property name="text">
|
||||
<string>Open file to Level 1...</string>
|
||||
</property>
|
||||
</action>
|
||||
</widget>
|
||||
<layoutdefault spacing="6" margin="11"/>
|
||||
<customwidgets>
|
||||
|
|
|
@ -212,7 +212,9 @@ SOURCES += main.cpp\
|
|||
newrpl/lib-96-composites.c \
|
||||
newrpl/atan_ltables.c \
|
||||
newrpl/lighttranscend.c \
|
||||
newrpl/ln_ltables.c
|
||||
newrpl/ln_ltables.c \
|
||||
interaction.cpp \
|
||||
interaction_rpl.c
|
||||
|
||||
HEADERS += mainwindow.h \
|
||||
qemuscreen.h \
|
||||
|
|
|
@ -49,7 +49,7 @@ typedef uint32_t PTR2NUMBER;
|
|||
|
||||
|
||||
#ifdef __cplusplus
|
||||
"C" {
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
// CONSTANTS THAT CONTROL THE MAIN RPL ENGINE
|
||||
|
|
|
@ -36,16 +36,16 @@ STREAM
|
|||
ΔLIST
|
||||
ΣLIST
|
||||
ΠLIST
|
||||
ADD
|
||||
ADDROT
|
||||
SORT
|
||||
REVLIST
|
||||
PUT
|
||||
PUTI
|
||||
GET
|
||||
GETI
|
||||
HEAD
|
||||
TAIL
|
||||
ADD
|
||||
ADDROT
|
||||
SORT
|
||||
REVLIST
|
||||
}
|
||||
|
||||
|
||||
|
|
Loading…
Reference in a new issue