mirror of
https://git.code.sf.net/p/newrpl/sources
synced 2024-09-29 17:36:57 +02:00
Fixed memory corruption bug in drawing routines + started backup framework.
This commit is contained in:
parent
ba1b2b2d59
commit
194dc29a78
11 changed files with 200 additions and 35 deletions
|
@ -53,3 +53,50 @@ if( (left<srf->addr)||(right>srf->addr+2048)) {
|
|||
|
||||
}
|
||||
|
||||
|
||||
|
||||
void ggl_cliphline(gglsurface *srf,int y,int xl,int xr, int color)
|
||||
{
|
||||
// PAINTS A HORIZONTAL LINE FROM xl TO xr BOTH INCLUSIVE
|
||||
// color=COLORED PATTERN TO USE, 8 PIXELS - 1 NIBBLE PER PIXEL
|
||||
// PATTERN IS ALWAYS WORD ALIGNED
|
||||
|
||||
// RESTRICTIONS: xr>=xl
|
||||
// y MUST BE VALID
|
||||
|
||||
|
||||
if(y<srf->clipy) return;
|
||||
if(y>srf->clipy2) return;
|
||||
if(xr<srf->clipx) return;
|
||||
if(xl>srf->clipx2) return;
|
||||
|
||||
if(xl<srf->clipx) xl=srf->clipx;
|
||||
if(xr>srf->clipx2) xr=srf->clipx2;
|
||||
|
||||
|
||||
|
||||
int loff=(y*srf->width+xl);
|
||||
int roff=(y*srf->width+xr);
|
||||
register int *left=(int *)srf->addr+ (loff>>3);
|
||||
register int *right=(int *)srf->addr+ (roff>>3);
|
||||
int ml=ggl_leftmask(loff),mr=ggl_rightmask(roff);
|
||||
|
||||
|
||||
if(left==right) {
|
||||
// single word operation
|
||||
ml|=mr;
|
||||
*left= (*left & ml) | (color & (~ml));
|
||||
return;
|
||||
}
|
||||
|
||||
*left= (*left & ml) | (color & (~ml));
|
||||
++left;
|
||||
while(left!=right)
|
||||
{
|
||||
*left=color;
|
||||
++left;
|
||||
}
|
||||
|
||||
*right= (*right & mr) | (color & (~mr));
|
||||
|
||||
}
|
||||
|
|
|
@ -14,3 +14,25 @@ void ggl_vline(gglsurface *srf,int x,int yt,int yb, int color)
|
|||
|
||||
}
|
||||
|
||||
// SAME AS VLINE BU WITH CLIPPING
|
||||
void ggl_clipvline(gglsurface *srf,int x,int yt,int yb, int color)
|
||||
{
|
||||
// PAINTS A VERTICAL LINE FROM yt TO yb BOTH INCLUSIVE
|
||||
// color=number from 0 to 15
|
||||
// RESTRICTIONS: yb>=yt
|
||||
|
||||
if(yt>srf->clipy2) return;
|
||||
if(yb<srf->clipy) return;
|
||||
|
||||
if(yt<srf->clipy) yt=srf->clipy;
|
||||
if(yb>srf->clipy2) yb=srf->clipy2;
|
||||
|
||||
if(x<srf->clipx) return;
|
||||
if(x>srf->clipx2) return;
|
||||
|
||||
|
||||
int offset=srf->width*yt+x;
|
||||
|
||||
while(yt<=yb) { ggl_pltnib(srf->addr,offset,color>>((yt&7)<<2)); offset+=srf->width; ++yt; }
|
||||
|
||||
}
|
||||
|
|
|
@ -233,7 +233,7 @@ void halRedrawStack(DRAWSURFACE *scr)
|
|||
xright=numwidth>12? numwidth:12;
|
||||
ggl_cliprect(scr,scr->clipx,ytop,scr->clipx2,y-1,0); // CLEAR RECTANGLE
|
||||
DrawText(xright-numwidth,ytop,num,levelfnt,0xf,scr);
|
||||
ggl_vline(scr,xright,ytop,y-1,ggl_mkcolor(0x8));
|
||||
ggl_clipvline(scr,xright,ytop,y-1,ggl_mkcolor(0x8));
|
||||
|
||||
if(level<=depth) {
|
||||
// DRAW THE OBJECT
|
||||
|
@ -310,13 +310,13 @@ void halRedrawMenu1(DRAWSURFACE *scr)
|
|||
ytop=halScreen.Form+halScreen.Stack+halScreen.CmdLine;
|
||||
ybottom=ytop+halScreen.Menu1-1;
|
||||
// DRAW BACKGROUND
|
||||
ggl_rect(scr,0,ytop,SCREEN_WIDTH-1,ybottom-1,ggl_mkcolor(0xf));
|
||||
ggl_hline(scr,ybottom,0,SCREEN_WIDTH-1,0);
|
||||
ggl_vline(scr,21,ytop,ybottom,0);
|
||||
ggl_vline(scr,43,ytop,ybottom,0);
|
||||
ggl_vline(scr,65,ytop,ybottom,0);
|
||||
ggl_vline(scr,87,ytop,ybottom,0);
|
||||
ggl_vline(scr,109,ytop,ybottom,0);
|
||||
ggl_cliprect(scr,0,ytop,SCREEN_WIDTH-1,ybottom-1,ggl_mkcolor(0xf));
|
||||
ggl_cliphline(scr,ybottom,0,SCREEN_WIDTH-1,0);
|
||||
ggl_clipvline(scr,21,ytop,ybottom,0);
|
||||
ggl_clipvline(scr,43,ytop,ybottom,0);
|
||||
ggl_clipvline(scr,65,ytop,ybottom,0);
|
||||
ggl_clipvline(scr,87,ytop,ybottom,0);
|
||||
ggl_clipvline(scr,109,ytop,ybottom,0);
|
||||
|
||||
halScreen.DirtyFlag&=~MENU1_DIRTY;
|
||||
}
|
||||
|
@ -333,13 +333,13 @@ void halRedrawMenu2(DRAWSURFACE *scr)
|
|||
ytop=halScreen.Form+halScreen.Stack+halScreen.CmdLine+halScreen.Menu1;
|
||||
ybottom=ytop+halScreen.Menu2-1;
|
||||
// DRAW BACKGROUND
|
||||
ggl_rect(scr,0,ytop,64,ybottom,ggl_mkcolor(0x8));
|
||||
ggl_vline(scr,21,ytop,ybottom,0);
|
||||
ggl_vline(scr,43,ytop,ybottom,0);
|
||||
ggl_vline(scr,65,ytop,ybottom,0);
|
||||
// ggl_vline(scr,87,ytop,ybottom,0);
|
||||
// ggl_vline(scr,109,ytop,ybottom,0);
|
||||
ggl_hline(scr,ytop+6,0,64,0);
|
||||
ggl_cliprect(scr,0,ytop,64,ybottom,ggl_mkcolor(0x8));
|
||||
ggl_clipvline(scr,21,ytop,ybottom,0);
|
||||
ggl_clipvline(scr,43,ytop,ybottom,0);
|
||||
ggl_clipvline(scr,65,ytop,ybottom,0);
|
||||
// ggl_clipvline(scr,87,ytop,ybottom,0);
|
||||
// ggl_clipvline(scr,109,ytop,ybottom,0);
|
||||
ggl_cliphline(scr,ytop+6,0,64,0);
|
||||
|
||||
halScreen.DirtyFlag&=~MENU2_DIRTY;
|
||||
}
|
||||
|
@ -348,7 +348,7 @@ void halRedrawStatus(DRAWSURFACE *scr)
|
|||
{
|
||||
if(halScreen.Menu2) {
|
||||
int ytop=halScreen.Form+halScreen.Stack+halScreen.CmdLine+halScreen.Menu1;
|
||||
ggl_rect(scr,STATUSAREA_X,ytop,SCREEN_WIDTH-1,ytop+halScreen.Menu2-1,0);
|
||||
ggl_cliprect(scr,STATUSAREA_X,ytop,SCREEN_WIDTH-1,ytop+halScreen.Menu2-1,0);
|
||||
|
||||
}
|
||||
// TODO: SHOW THE CURRENT DIR, ETC. HERE
|
||||
|
@ -362,8 +362,8 @@ void halRedrawCmdLine(DRAWSURFACE *scr)
|
|||
if(halScreen.CmdLine) {
|
||||
int ytop=halScreen.Form+halScreen.Stack;
|
||||
if((halScreen.DirtyFlag&CMDLINE_ALLDIRTY)==CMDLINE_ALLDIRTY) {
|
||||
ggl_rect(scr,0,ytop,SCREEN_WIDTH-1,ytop+halScreen.CmdLine-1,0);
|
||||
ggl_hline(scr,ytop,0,SCREEN_WIDTH-1,0xf0f0f0f0);
|
||||
ggl_cliprect(scr,0,ytop,SCREEN_WIDTH-1,ytop+halScreen.CmdLine-1,0);
|
||||
ggl_cliphline(scr,ytop,0,SCREEN_WIDTH-1,0xf0f0f0f0);
|
||||
}
|
||||
|
||||
BINT y=(halScreen.LineCurrent-halScreen.LineVisible)*halScreen.CmdLineFont->BitmapHeight;
|
||||
|
@ -530,12 +530,12 @@ void halShowErrorMsg()
|
|||
ggl_initscr(&scr);
|
||||
BINT ytop=halScreen.Form+halScreen.Stack+halScreen.CmdLine+halScreen.Menu1;
|
||||
// CLEAR MENU2 AND STATUS AREA
|
||||
ggl_rect(&scr,0,ytop,SCREEN_WIDTH-1,ytop+halScreen.Menu2-1,0);
|
||||
ggl_cliprect(&scr,0,ytop,SCREEN_WIDTH-1,ytop+halScreen.Menu2-1,0);
|
||||
// DO SOME DECORATIVE ELEMENTS
|
||||
ggl_hline(&scr,ytop+1,1,SCREEN_WIDTH-2,ggl_mkcolor(8));
|
||||
ggl_hline(&scr,ytop+halScreen.Menu2-1,1,SCREEN_WIDTH-2,ggl_mkcolor(8));
|
||||
ggl_vline(&scr,1,ytop+2,ytop+halScreen.Menu2-2,ggl_mkcolor(8));
|
||||
ggl_vline(&scr,SCREEN_WIDTH-2,ytop+2,ytop+halScreen.Menu2-2,ggl_mkcolor(8));
|
||||
ggl_cliphline(&scr,ytop+1,1,SCREEN_WIDTH-2,ggl_mkcolor(8));
|
||||
ggl_cliphline(&scr,ytop+halScreen.Menu2-1,1,SCREEN_WIDTH-2,ggl_mkcolor(8));
|
||||
ggl_clipvline(&scr,1,ytop+2,ytop+halScreen.Menu2-2,ggl_mkcolor(8));
|
||||
ggl_clipvline(&scr,SCREEN_WIDTH-2,ytop+2,ytop+halScreen.Menu2-2,ggl_mkcolor(8));
|
||||
|
||||
// SHOW ERROR MESSAGE
|
||||
|
||||
|
@ -557,12 +557,12 @@ void halShowMsgN(char *Text,char *End)
|
|||
ggl_initscr(&scr);
|
||||
BINT ytop=halScreen.Form+halScreen.Stack+halScreen.CmdLine+halScreen.Menu1;
|
||||
// CLEAR MENU2 AND STATUS AREA
|
||||
ggl_rect(&scr,0,ytop,SCREEN_WIDTH-1,ytop+halScreen.Menu2-1,0);
|
||||
ggl_cliprect(&scr,0,ytop,SCREEN_WIDTH-1,ytop+halScreen.Menu2-1,0);
|
||||
// DO SOME DECORATIVE ELEMENTS
|
||||
ggl_hline(&scr,ytop+1,1,SCREEN_WIDTH-2,ggl_mkcolor(8));
|
||||
ggl_hline(&scr,ytop+halScreen.Menu2-1,1,SCREEN_WIDTH-2,ggl_mkcolor(8));
|
||||
ggl_vline(&scr,1,ytop+2,ytop+halScreen.Menu2-2,ggl_mkcolor(8));
|
||||
ggl_vline(&scr,SCREEN_WIDTH-2,ytop+2,ytop+halScreen.Menu2-2,ggl_mkcolor(8));
|
||||
ggl_cliphline(&scr,ytop+1,1,SCREEN_WIDTH-2,ggl_mkcolor(8));
|
||||
ggl_cliphline(&scr,ytop+halScreen.Menu2-1,1,SCREEN_WIDTH-2,ggl_mkcolor(8));
|
||||
ggl_clipvline(&scr,1,ytop+2,ytop+halScreen.Menu2-2,ggl_mkcolor(8));
|
||||
ggl_clipvline(&scr,SCREEN_WIDTH-2,ytop+2,ytop+halScreen.Menu2-2,ggl_mkcolor(8));
|
||||
|
||||
// SHOW MESSAGE
|
||||
|
||||
|
|
|
@ -71,6 +71,7 @@ int ggl_getmonopix(char *buf,int off); // peek a pixel in monochrome
|
|||
|
||||
void ggl_hline(gglsurface *srf,int y,int xl,int xr, int color); // fast low-level horizontal line
|
||||
void ggl_vline(gglsurface *srf,int x,int yt,int yb, int color); // fast low-level vertical line
|
||||
void ggl_clipvline(gglsurface *srf,int x,int yt,int yb, int color);
|
||||
void ggl_rect(gglsurface *srf,int x1,int y1,int x2,int y2,int color); // low-level rectangle
|
||||
void ggl_cliprect(gglsurface *srf,int x1,int y1,int x2,int y2,int color); // low-level rectangle
|
||||
|
||||
|
|
|
@ -55,7 +55,7 @@ void main_virtual()
|
|||
|
||||
tmr_eventkill(event);
|
||||
// CLEAR SCREEN
|
||||
ggl_rect(&scr,0,0,131,80,0x12345678);
|
||||
ggl_rect(&scr,0,0,SCREEN_WIDTH-1,SCREEN_HEIGHT-1,0x12345678);
|
||||
|
||||
}
|
||||
|
||||
|
|
|
@ -1,9 +1,11 @@
|
|||
#include <QtGui>
|
||||
#include <QtCore>
|
||||
#include <QFileDialog>
|
||||
#include <QFile>
|
||||
#include <QMessageBox>
|
||||
#include "mainwindow.h"
|
||||
#include "ui_mainwindow.h"
|
||||
|
||||
#include "newrpl.h"
|
||||
MainWindow *myMainWindow;
|
||||
|
||||
|
||||
|
@ -294,12 +296,58 @@ void MainWindow::on_actionExit_triggered()
|
|||
|
||||
}
|
||||
|
||||
void MainWindow::WriteWord(unsigned int word)
|
||||
{
|
||||
myMainWindow->fileptr->write((const char *)&word,4);
|
||||
}
|
||||
|
||||
extern "C" void write_data(unsigned int word)
|
||||
{
|
||||
MainWindow::WriteWord(word);
|
||||
}
|
||||
|
||||
void MainWindow::on_actionSave_triggered()
|
||||
{
|
||||
// STOP THE RPL ENGINE AND SAVE ITS CONTENTS
|
||||
|
||||
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";
|
||||
|
||||
QFile file(fname);
|
||||
|
||||
if(!file.open(QIODevice::WriteOnly)) {
|
||||
QMessageBox a(QMessageBox::Warning,"Error while saving","Cannot write to file "+ fname,QMessageBox::Ok,this);
|
||||
a.exec();
|
||||
return;
|
||||
}
|
||||
|
||||
// FILE IS OPEN AND READY FOR WRITING
|
||||
|
||||
// STOP RPL ENGINE
|
||||
maintmr->stop();
|
||||
screentmr->stop();
|
||||
if(rpl.isRunning()) {
|
||||
__pc_terminate=1;
|
||||
__pckeymatrix^=(1ULL<<63);
|
||||
__keyb_update();
|
||||
while(rpl.isRunning());
|
||||
}
|
||||
|
||||
// PERFORM BACKUP
|
||||
myMainWindow=this;
|
||||
fileptr=&file;
|
||||
rplBackup(&write_data);
|
||||
|
||||
// RESTART RPL ENGINE
|
||||
__pc_terminate=0;
|
||||
__pckeymatrix=0;
|
||||
rpl.start();
|
||||
maintmr->start(1);
|
||||
screentmr->start(50);
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
@ -2,6 +2,7 @@
|
|||
#define MAINWINDOW_H
|
||||
|
||||
#include <QMainWindow>
|
||||
#include <QFile>
|
||||
#include "rplthread.h"
|
||||
namespace Ui {
|
||||
class MainWindow;
|
||||
|
@ -13,7 +14,12 @@ class MainWindow : public QMainWindow
|
|||
|
||||
QTimer *screentmr,*maintmr;
|
||||
RPLThread rpl;
|
||||
|
||||
public:
|
||||
QFile *fileptr;
|
||||
|
||||
static void WriteWord(unsigned int word);
|
||||
|
||||
explicit MainWindow(QWidget *parent = 0);
|
||||
~MainWindow();
|
||||
protected:
|
||||
|
|
|
@ -125,10 +125,10 @@ HEADERS += \
|
|||
newrpl/decimal.h
|
||||
|
||||
# This might need to be adapted to each cross-compiler installation
|
||||
GCC_LIBDIR = /usr/local/lib/gcc/arm-none-eabi/4.9.2
|
||||
GCC_LIBDIR = /usr/local/lib/gcc/arm-none-eabi/5.2.0
|
||||
|
||||
INCLUDEPATH += $$GCC_LIBDIR/include
|
||||
QMAKE_LIBDIR += $$GCC_LIBDIR/4.9.2
|
||||
QMAKE_LIBDIR += $$GCC_LIBDIR
|
||||
|
||||
# End of cross-compiler dependent
|
||||
|
||||
|
@ -140,8 +140,7 @@ LIBS += -lgcc
|
|||
FORMS +=
|
||||
|
||||
DISTFILES += \
|
||||
firmware/ld.script \
|
||||
firmware/sys/target_50g/bootrom.txt
|
||||
firmware/ld.script
|
||||
|
||||
RESOURCES +=
|
||||
|
||||
|
|
|
@ -111,7 +111,8 @@ SOURCES += main.cpp\
|
|||
newrpl/cordic_K_8_comp.c \
|
||||
newrpl/cordic_Kh_8_comp.c \
|
||||
newrpl/decimal.c \
|
||||
newrpl/dectranscen.c
|
||||
newrpl/dectranscen.c \
|
||||
newrpl/backup.c
|
||||
|
||||
HEADERS += mainwindow.h \
|
||||
qemuscreen.h \
|
||||
|
|
38
newrpl/backup.c
Normal file
38
newrpl/backup.c
Normal file
|
@ -0,0 +1,38 @@
|
|||
/*
|
||||
* Copyright (c) 2014, Claudio Lapilli and the newRPL Team
|
||||
* All rights reserved.
|
||||
* This file is released under the 3-clause BSD license.
|
||||
* See the file LICENSE.txt that shipped with this distribution.
|
||||
*/
|
||||
|
||||
#include "newrpl.h"
|
||||
#include "libraries.h"
|
||||
#include "hal.h"
|
||||
|
||||
|
||||
// BACKUP TEMPOB AND DIRECTORIES (NO STACK) TO EXTERNAL DEVICE
|
||||
|
||||
void rplBackup(void (*writefunc)(unsigned int))
|
||||
{
|
||||
// COMPACT TEMPOB AS MUCH AS POSSIBLE
|
||||
rplGCollect();
|
||||
|
||||
// DUMP SYSTEM VARIABLES TO THE FILE
|
||||
// DUMP TEMPBLOCKS TO THE FILE
|
||||
// DUMP TEMPOB TO THE FILE
|
||||
// DUMP DIRECTORIES TO THE FILE
|
||||
|
||||
// TODO: JUST WRITE A WORD FOR NOW
|
||||
writefunc(0X12345678);
|
||||
|
||||
return;
|
||||
|
||||
}
|
||||
|
||||
|
||||
// FULLY RESTORE TEMPOB AND DIRECTORIES FROM BACKUP
|
||||
|
||||
void rplRestoreBackup(void (*readfunc)(unsigned int))
|
||||
{
|
||||
|
||||
}
|
|
@ -222,6 +222,9 @@ extern void rplSetSystemFlagByName(BYTEPTR name,BINT len);
|
|||
// GARBAGE COLLECTION
|
||||
extern void rplGCollect();
|
||||
|
||||
// BACKUP/RESTORE
|
||||
void rplBackup(void (*writefunc)(unsigned int));
|
||||
void rplRestoreBackup(void (*readfunc)(unsigned int));
|
||||
|
||||
|
||||
|
||||
|
|
Loading…
Reference in a new issue