Fixed memory corruption bug in drawing routines + started backup framework.

This commit is contained in:
claudiol 2015-08-19 15:58:24 -04:00
parent ba1b2b2d59
commit 194dc29a78
11 changed files with 200 additions and 35 deletions

View file

@ -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));
}

View file

@ -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; }
}

View file

@ -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

View file

@ -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

View file

@ -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);
}

View file

@ -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);
}
}

View file

@ -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:

View file

@ -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 +=

View file

@ -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
View 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))
{
}

View file

@ -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));