Initial commit
This commit is contained in:
commit
446fc018f2
57
About.cpp
Normal file
57
About.cpp
Normal file
@ -0,0 +1,57 @@
|
|||||||
|
/*****************************************************************************
|
||||||
|
** About.cpp - Source file of About DialogBox containing info about program
|
||||||
|
** Author: Kraku
|
||||||
|
*****************************************************************************/
|
||||||
|
#include "About.h"
|
||||||
|
#include "about.xpm"
|
||||||
|
#include "const.h"
|
||||||
|
|
||||||
|
About::About (QWidget * parent): QDialog(parent)
|
||||||
|
{
|
||||||
|
|
||||||
|
all = new QVBoxLayout (this);
|
||||||
|
|
||||||
|
this->setWindowTitle (tr ("About"));
|
||||||
|
|
||||||
|
QPixmap
|
||||||
|
logo (about_xpm);
|
||||||
|
image = new QLabel (this);
|
||||||
|
image->setFixedSize (501, 218);
|
||||||
|
image->setPixmap (logo);
|
||||||
|
|
||||||
|
all->addWidget (image);
|
||||||
|
box = new QGroupBox (tr ("GB Cart Flasher Project"), this);
|
||||||
|
box->setFixedWidth (501);
|
||||||
|
labels = new QVBoxLayout (box);
|
||||||
|
name =
|
||||||
|
new QLabel (tr ("GB Cart Flasher for Linux by m0rph3us1987 v") +
|
||||||
|
VER, box);
|
||||||
|
labels->addWidget (name);
|
||||||
|
copy = new QLabel ("Based on GB Cart Flasher by Kraku & Chroost", box);
|
||||||
|
labels->addWidget (copy);
|
||||||
|
email =
|
||||||
|
new
|
||||||
|
QLabel (tr
|
||||||
|
("e-mail: <a href=mailto:gbflasher@interia.pl>gbflasher@interia.pl</a>"),
|
||||||
|
box);
|
||||||
|
labels->addWidget (email);
|
||||||
|
translator = new QLabel(tr("Translation by: Chroost"),box);
|
||||||
|
labels->addWidget(translator);
|
||||||
|
desc1 = new QLabel (tr ("This program and device, called set, enables to:\n"
|
||||||
|
"- make game backups from owned cartridges and play them on PC,\n"
|
||||||
|
"- transfer game saves between cartridge and PC, save and modify them,\n"
|
||||||
|
"- test written by yourself games directly on console (rewritable cartridge required)."),
|
||||||
|
box);
|
||||||
|
labels->addWidget (desc1);
|
||||||
|
warning = new QLabel (tr ("<b>WARNING!</b>"), box);
|
||||||
|
labels->addWidget (warning);
|
||||||
|
desc2 =
|
||||||
|
new
|
||||||
|
QLabel (tr("Using this set for purposes other than previously listed,\n"
|
||||||
|
"especially for making illegal copies of copyrighted games is strictly prohibited!"), box);
|
||||||
|
labels->addWidget (desc2);
|
||||||
|
all->addWidget (box);
|
||||||
|
ok_btn = new QPushButton (tr ("Close"), this);
|
||||||
|
all->addWidget (ok_btn);
|
||||||
|
connect (ok_btn, SIGNAL (clicked ()), this, SLOT (close ()));
|
||||||
|
}
|
25
About.h
Normal file
25
About.h
Normal file
@ -0,0 +1,25 @@
|
|||||||
|
/*****************************************************************************
|
||||||
|
** About.h
|
||||||
|
** Author: Kraku
|
||||||
|
*****************************************************************************/
|
||||||
|
#ifndef _ABOUT_H_
|
||||||
|
#define _ABOUT_H_
|
||||||
|
#include <QDialog>
|
||||||
|
#include <QPushButton>
|
||||||
|
#include <QPixmap>
|
||||||
|
#include <QLabel>
|
||||||
|
#include <QBoxLayout>
|
||||||
|
#include <QGroupBox>
|
||||||
|
class About:public QDialog
|
||||||
|
{
|
||||||
|
Q_OBJECT QPushButton * ok_btn;
|
||||||
|
QLabel *image;
|
||||||
|
QVBoxLayout *all;
|
||||||
|
QGroupBox *box;
|
||||||
|
QLabel *name, *copy, *desc1, *desc2, *email, *warning, *translator;
|
||||||
|
QVBoxLayout *labels;
|
||||||
|
public:
|
||||||
|
About (QWidget * parent = 0);
|
||||||
|
};
|
||||||
|
|
||||||
|
#endif
|
28
AbstractPort.h
Normal file
28
AbstractPort.h
Normal file
@ -0,0 +1,28 @@
|
|||||||
|
/*****************************************************************************
|
||||||
|
** AbstractPort.h
|
||||||
|
** Author: Kraku
|
||||||
|
*****************************************************************************/
|
||||||
|
#ifndef _ABSTRACTPORT_H_
|
||||||
|
#define _ABSTRACTPORT_H_
|
||||||
|
#include <QObject>
|
||||||
|
#include <QString>
|
||||||
|
|
||||||
|
class AbstractPort:public QObject
|
||||||
|
{
|
||||||
|
Q_OBJECT public:
|
||||||
|
virtual bool open_port (QString port_name) = 0;
|
||||||
|
virtual bool close_port () = 0;
|
||||||
|
virtual int receive_char () = 0;
|
||||||
|
virtual bool send_char (unsigned char character) = 0;
|
||||||
|
virtual int receive_packet (unsigned char *packet) = 0;
|
||||||
|
virtual int send_packet (unsigned char *packet) = 0;
|
||||||
|
virtual ~AbstractPort ()
|
||||||
|
{
|
||||||
|
};
|
||||||
|
virtual bool isOpen () = 0;
|
||||||
|
signals:
|
||||||
|
void error (int err);
|
||||||
|
|
||||||
|
};
|
||||||
|
|
||||||
|
#endif
|
44
Console.h
Normal file
44
Console.h
Normal file
@ -0,0 +1,44 @@
|
|||||||
|
/*****************************************************************************
|
||||||
|
** Console.h - header of Console used to print infos from other
|
||||||
|
** modules
|
||||||
|
** Author: Kraku
|
||||||
|
*****************************************************************************/
|
||||||
|
#ifndef _CONSOLE_H_
|
||||||
|
#define _CONSOLE_H_
|
||||||
|
|
||||||
|
#include <QTextEdit>
|
||||||
|
#include <QString>
|
||||||
|
#include <QPalette>
|
||||||
|
#include <QColor>
|
||||||
|
|
||||||
|
class Console:public QTextEdit
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
Console (QWidget * parent):QTextEdit (parent)
|
||||||
|
{
|
||||||
|
this->setMinimumWidth (400);
|
||||||
|
this->setReadOnly (TRUE);
|
||||||
|
QPalette palette;
|
||||||
|
palette.setColor (QPalette::Base, QColor (0, 255, 0));
|
||||||
|
this->setPalette (palette);
|
||||||
|
QFont font ("Courier");
|
||||||
|
font.setPointSize (8);
|
||||||
|
this->setFont (font);
|
||||||
|
}
|
||||||
|
|
||||||
|
void print (QString string)
|
||||||
|
{
|
||||||
|
append (string);
|
||||||
|
}
|
||||||
|
|
||||||
|
void line ()
|
||||||
|
{
|
||||||
|
#ifdef Q_WS_X11
|
||||||
|
print ("<br>");
|
||||||
|
#else
|
||||||
|
print ("<hr><br>");
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
#endif
|
66
EraseThread.cpp
Normal file
66
EraseThread.cpp
Normal file
@ -0,0 +1,66 @@
|
|||||||
|
/*****************************************************************************
|
||||||
|
** EraseThread.cpp
|
||||||
|
** Author: Kraku
|
||||||
|
*****************************************************************************/
|
||||||
|
#include "EraseThread.h"
|
||||||
|
#include "Logic.h"
|
||||||
|
#include "const.h"
|
||||||
|
#include "Settings.h"
|
||||||
|
|
||||||
|
void
|
||||||
|
EraseThread::run ()
|
||||||
|
{
|
||||||
|
time_t tp, t0; /* time for erase */
|
||||||
|
unsigned short crc16;
|
||||||
|
unsigned char packet[PACKETSIZE];
|
||||||
|
/* filling single erase packet */
|
||||||
|
memset (packet, 0x00, PACKETSIZE);
|
||||||
|
packet[0] = DATA;
|
||||||
|
packet[1] = ERASE;
|
||||||
|
packet[2] = mem;
|
||||||
|
packet[3] = mbc;
|
||||||
|
packet[4] = par;
|
||||||
|
packet[5] = Settings::dap;
|
||||||
|
crc16 = Logic::generate_crc16 (packet);
|
||||||
|
packet[PACKETSIZE - 2] = crc16 / 256;
|
||||||
|
packet[PACKETSIZE - 1] = crc16 % 256;
|
||||||
|
end = FALSE;
|
||||||
|
|
||||||
|
/* send erase packet */
|
||||||
|
if (port->send_packet (packet) < PACKETSIZE)
|
||||||
|
{
|
||||||
|
port->close_port ();
|
||||||
|
emit error (SEND_ERROR);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
t0 = tp = time (NULL);
|
||||||
|
do
|
||||||
|
{
|
||||||
|
/* end of thread - operation canceled */
|
||||||
|
if(end) {
|
||||||
|
port->close_port();
|
||||||
|
emit error (END);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
/* erase done */
|
||||||
|
if (port->receive_char () == ACK)
|
||||||
|
{
|
||||||
|
port->close_port ();
|
||||||
|
emit set_progress (1, 1);
|
||||||
|
emit error (TRUE);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
if (time (NULL) != tp)
|
||||||
|
emit set_progress (time (NULL) - tp, DELTIME);
|
||||||
|
}
|
||||||
|
while (time (NULL) - tp < DELTIME);
|
||||||
|
/* wait for erase DELTIME sec.
|
||||||
|
* hardware independent!
|
||||||
|
*/
|
||||||
|
|
||||||
|
emit set_progress (1, 1); //100%
|
||||||
|
port->close_port ();
|
||||||
|
emit error (TIMEOUT);
|
||||||
|
return;
|
||||||
|
}
|
31
EraseThread.h
Normal file
31
EraseThread.h
Normal file
@ -0,0 +1,31 @@
|
|||||||
|
/*****************************************************************************
|
||||||
|
** EraseThread.h - Header file of thread responsible for process of
|
||||||
|
** FLASH and RAM erase
|
||||||
|
** Author: Kraku
|
||||||
|
*****************************************************************************/
|
||||||
|
#ifndef _ERASETHREAD_H_
|
||||||
|
#define _ERASETHREAD_H_
|
||||||
|
#include <QThread>
|
||||||
|
#include "AbstractPort.h"
|
||||||
|
#include "Logic.h"
|
||||||
|
|
||||||
|
class EraseThread:public QThread
|
||||||
|
{
|
||||||
|
Q_OBJECT
|
||||||
|
public:
|
||||||
|
char mem; /* memory type for erase */
|
||||||
|
char mbc; /* Memory Bank Controler type */
|
||||||
|
char par;
|
||||||
|
char dap;
|
||||||
|
bool end; /* end of thread marker */
|
||||||
|
AbstractPort *port;
|
||||||
|
/* main point of thread */
|
||||||
|
virtual void run ();
|
||||||
|
public slots:
|
||||||
|
void canceled (void) { end = TRUE; }
|
||||||
|
signals:
|
||||||
|
void set_progress (int ile, int max);
|
||||||
|
void error (int err);
|
||||||
|
};
|
||||||
|
|
||||||
|
#endif
|
646
Gui.cpp
Normal file
646
Gui.cpp
Normal file
@ -0,0 +1,646 @@
|
|||||||
|
/*****************************************************************************
|
||||||
|
** Gui.cpp - main class of GUI (Main Window)
|
||||||
|
** Author: Kraku
|
||||||
|
*****************************************************************************/
|
||||||
|
#include <QFileDialog>
|
||||||
|
#include <QPixmap>
|
||||||
|
#include <QMessageBox>
|
||||||
|
#include <QThread>
|
||||||
|
#include "Gui.h"
|
||||||
|
#include "Settings.h"
|
||||||
|
#include "Logic.h"
|
||||||
|
#include "About.h"
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
#ifdef Q_WS_X11
|
||||||
|
#include "SerialPort.h"
|
||||||
|
#include "USBPort.h"
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#ifdef Q_WS_WIN
|
||||||
|
#include "USBPortWin.h"
|
||||||
|
#include "SerialPortWin.h"
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#include "const.h"
|
||||||
|
#include "flasher.xpm"
|
||||||
|
#include "icon.xpm"
|
||||||
|
|
||||||
|
int
|
||||||
|
Gui::port_type = SERIAL;
|
||||||
|
|
||||||
|
Gui::Gui (QWidget * parent):QWidget (parent)
|
||||||
|
{
|
||||||
|
QThread::currentThread ()->setPriority (QThread::NormalPriority);
|
||||||
|
path = "."; //current startup dir
|
||||||
|
this->setWindowIcon (QIcon (QPixmap (icon)));
|
||||||
|
this->setWindowTitle (tr ("GB Cart Flasher version ") + VER + tr(" ported by m0rph3us1987"));
|
||||||
|
grid = new QGridLayout (this);
|
||||||
|
left = new QVBoxLayout ();
|
||||||
|
right = new QVBoxLayout ();
|
||||||
|
center = new QVBoxLayout ();
|
||||||
|
down = new QHBoxLayout ();
|
||||||
|
|
||||||
|
image = new QLabel (this);
|
||||||
|
|
||||||
|
image->setFixedSize (200, 162);
|
||||||
|
settings = new Settings (this);
|
||||||
|
left->addWidget (settings);
|
||||||
|
left->addWidget (image);
|
||||||
|
left->addStretch (1);
|
||||||
|
grid->addLayout (left, 0, 0);
|
||||||
|
console = new Console (this);
|
||||||
|
|
||||||
|
QPixmap Logo (gameboy);
|
||||||
|
|
||||||
|
image->setPixmap (Logo);
|
||||||
|
|
||||||
|
right->addWidget (console);
|
||||||
|
progress = new QProgressBar (this);
|
||||||
|
down->addWidget (progress);
|
||||||
|
cancel_btn = new QPushButton (tr ("Cancel"), this);
|
||||||
|
cancel_btn->setEnabled (FALSE);
|
||||||
|
down->addWidget (cancel_btn);
|
||||||
|
right->addLayout (down);
|
||||||
|
grid->addLayout (right, 0, 2);
|
||||||
|
status_btn = new QPushButton (tr ("Cart Info"), this);
|
||||||
|
rflash_btn = new QPushButton (tr ("Read FLASH"), this);
|
||||||
|
wflash_btn = new QPushButton (tr ("Write FLASH"), this);
|
||||||
|
rram_btn = new QPushButton (tr ("Read RAM"), this);
|
||||||
|
wram_btn = new QPushButton (tr ("Write RAM"), this);
|
||||||
|
eflash_btn = new QPushButton (tr ("Erase FLASH"), this);
|
||||||
|
eram_btn = new QPushButton (tr ("Erase RAM"), this);
|
||||||
|
about_btn = new QPushButton (tr ("About"), this);
|
||||||
|
|
||||||
|
center->addWidget (status_btn, Qt::AlignTop);
|
||||||
|
center->addWidget (rflash_btn);
|
||||||
|
center->addWidget (wflash_btn);
|
||||||
|
center->addWidget (rram_btn);
|
||||||
|
center->addWidget (wram_btn);
|
||||||
|
center->addWidget (eflash_btn);
|
||||||
|
center->addWidget (eram_btn);
|
||||||
|
center->addSpacing (20);
|
||||||
|
center->addWidget (about_btn);
|
||||||
|
center->addStretch (1);
|
||||||
|
grid->addLayout (center, 0, 1);
|
||||||
|
|
||||||
|
thread_WFLA = new WriteFlashThread;
|
||||||
|
thread_RFLA = new ReadFlashThread;
|
||||||
|
thread_E = new EraseThread;
|
||||||
|
thread_RRAM = new ReadRamThread;
|
||||||
|
thread_WRAM = new WriteRamThread;
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
connect (cancel_btn, SIGNAL (clicked ()), thread_RFLA, SLOT (canceled ()));
|
||||||
|
connect (cancel_btn, SIGNAL (clicked ()), thread_WFLA, SLOT (canceled ()));
|
||||||
|
connect (cancel_btn, SIGNAL (clicked ()), thread_RRAM, SLOT (canceled ()));
|
||||||
|
connect (cancel_btn, SIGNAL (clicked ()), thread_WRAM, SLOT (canceled ()));
|
||||||
|
|
||||||
|
connect (cancel_btn, SIGNAL (clicked ()), thread_E, SLOT (canceled ()));
|
||||||
|
connect (wflash_btn, SIGNAL (clicked ()), this, SLOT (write_flash ()));
|
||||||
|
connect (rflash_btn, SIGNAL (clicked ()), this, SLOT (read_flash ()));
|
||||||
|
connect (status_btn, SIGNAL (clicked ()), this, SLOT (show_info ()));
|
||||||
|
connect (eflash_btn, SIGNAL (clicked ()), this, SLOT (erase_flash ()));
|
||||||
|
connect (rram_btn, SIGNAL (clicked ()), this, SLOT (read_ram ()));
|
||||||
|
connect (wram_btn, SIGNAL (clicked ()), this, SLOT (write_ram ()));
|
||||||
|
connect (eram_btn, SIGNAL (clicked ()), this, SLOT (erase_ram ()));
|
||||||
|
connect (about_btn, SIGNAL (clicked ()), this, SLOT (about ()));
|
||||||
|
|
||||||
|
connect (thread_WFLA, SIGNAL (set_progress (int, int)), this,
|
||||||
|
SLOT (setProgress (int, int)));
|
||||||
|
connect (thread_RFLA, SIGNAL (set_progress (int, int)), this,
|
||||||
|
SLOT (setProgress (int, int)));
|
||||||
|
connect (thread_E, SIGNAL (set_progress (int, int)), this,
|
||||||
|
SLOT (setProgress (int, int)));
|
||||||
|
connect (thread_RRAM, SIGNAL (set_progress (int, int)), this,
|
||||||
|
SLOT (setProgress (int, int)));
|
||||||
|
connect (thread_WRAM, SIGNAL (set_progress (int, int)), this,
|
||||||
|
SLOT (setProgress (int, int)));
|
||||||
|
|
||||||
|
|
||||||
|
connect (thread_RFLA, SIGNAL (error (int)), this, SLOT (print_error (int)));
|
||||||
|
connect (thread_WFLA, SIGNAL (error (int)), this, SLOT (print_error (int)));
|
||||||
|
connect (thread_RRAM, SIGNAL (error (int)), this, SLOT (print_error (int)));
|
||||||
|
connect (thread_WRAM, SIGNAL (error (int)), this, SLOT (print_error (int)));
|
||||||
|
connect (thread_E, SIGNAL (error (int)), this, SLOT (print_error (int)));
|
||||||
|
|
||||||
|
connect (settings, SIGNAL (refresh_ram_buttons (void)), this,
|
||||||
|
SLOT (setRamButtons (void)));
|
||||||
|
setProgress (0, 1);
|
||||||
|
console->print (tr ("GB Cart Flasher version ") + VER + tr (" started."));
|
||||||
|
#ifdef Q_WS_WIN
|
||||||
|
/* device detection is avilable only on Windows */
|
||||||
|
if (Settings::commanual == FALSE)
|
||||||
|
{
|
||||||
|
console->print (tr ("Detecting device..."));
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
|
||||||
|
AbstractPort *
|
||||||
|
Gui::create_port (void)
|
||||||
|
{
|
||||||
|
switch (port_type)
|
||||||
|
{
|
||||||
|
case USB:
|
||||||
|
#ifdef Q_WS_WIN
|
||||||
|
return new USBPortWin;
|
||||||
|
#endif
|
||||||
|
#ifdef Q_WS_X11
|
||||||
|
return new USBPort;
|
||||||
|
#endif
|
||||||
|
case SERIAL:
|
||||||
|
#ifdef Q_WS_WIN
|
||||||
|
return new SerialPortWin;
|
||||||
|
#endif
|
||||||
|
#ifdef Q_WS_X11
|
||||||
|
return new SerialPort;
|
||||||
|
#endif
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
Gui::startup_info (void)
|
||||||
|
{
|
||||||
|
status_t status;
|
||||||
|
int which_port = -1; //none at beggining
|
||||||
|
|
||||||
|
|
||||||
|
if (Settings::commanual == FALSE)
|
||||||
|
{
|
||||||
|
port_type = USB;
|
||||||
|
AbstractPort *port = create_port ();
|
||||||
|
if (Logic::read_status (port, "USB", NREAD_ID, 0x00, 0x00, &status) ==
|
||||||
|
TRUE)
|
||||||
|
{
|
||||||
|
QString tmp;
|
||||||
|
console->print (tr ("Device connected to: USB"));
|
||||||
|
settings->setCom (4); //4 is index of usb in combobox
|
||||||
|
tmp =
|
||||||
|
tmp.sprintf (" %d%d.%d%d", status.ver_11, status.ver_12,
|
||||||
|
status.ver_21, status.ver_22);
|
||||||
|
console->print (tr ("Device firmware version:") + tmp);
|
||||||
|
console->line ();
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
port_type = SERIAL;
|
||||||
|
port = create_port ();
|
||||||
|
for (int i = 0; i < PORTS_COUNT; i++)
|
||||||
|
{
|
||||||
|
if (Logic::
|
||||||
|
read_status (port, settings->getCom(i).toUtf8(), NREAD_ID, 0x00, 0x00,
|
||||||
|
&status) == TRUE)
|
||||||
|
{
|
||||||
|
which_port = i;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (which_port == -1)
|
||||||
|
{
|
||||||
|
console->print (tr ("Device not found!"));
|
||||||
|
console->print (tr ("Check COM port connection."));
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
QString tmp;
|
||||||
|
console->print (tr ("Device connected to: ") +
|
||||||
|
settings->getCom (which_port));
|
||||||
|
settings->setCom (which_port);
|
||||||
|
tmp =
|
||||||
|
tmp.sprintf (" %d%d.%d%d", status.ver_11, status.ver_12,
|
||||||
|
status.ver_21, status.ver_22);
|
||||||
|
console->print (tr ("Device firmware version:") + tmp);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
console->line ();
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
Gui::show_info ()
|
||||||
|
{
|
||||||
|
status_t status;
|
||||||
|
QString tmp;
|
||||||
|
AbstractPort *port = create_port ();
|
||||||
|
int return_code = Logic::read_status (port, settings->getCom().toUtf8(), READ_ID,
|
||||||
|
settings->getMbc (),
|
||||||
|
Settings::algorythm, &status);
|
||||||
|
|
||||||
|
if (return_code == TRUE) /* no error */
|
||||||
|
{
|
||||||
|
|
||||||
|
console->print (tr ("--Device information--"));
|
||||||
|
tmp =
|
||||||
|
tmp.sprintf (" %d%d.%d%d", status.ver_11, status.ver_12,
|
||||||
|
status.ver_21, status.ver_22);
|
||||||
|
console->print (tr ("Device firmware version:") + tmp);
|
||||||
|
console->print ("\n" + tr ("--Cartridge information--"));
|
||||||
|
tmp = tmp.sprintf (" 0x%x", status.manufacturer_id);
|
||||||
|
console->print (tr ("FLASH memory manufacturer ID:") + tmp);
|
||||||
|
tmp = tmp.sprintf (" %s", status.manufacturer);
|
||||||
|
console->print (tr ("FLASH memory manufacturer name:") + tmp);
|
||||||
|
tmp = tmp.sprintf (" 0x%x", status.chip_id);
|
||||||
|
console->print (tr ("FLASH memory chip ID:") + tmp);
|
||||||
|
|
||||||
|
if (Settings::showbbl == TRUE)
|
||||||
|
{
|
||||||
|
if (status.bbl == 1)
|
||||||
|
tmp = tr ("Locked!");
|
||||||
|
else
|
||||||
|
tmp = tr ("Unlocked");
|
||||||
|
console->print (tr ("Boot Block Status: ") + tmp);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (status.logo_correct == 1)
|
||||||
|
{
|
||||||
|
console->print ("\n" + tr ("--ROM/FLASH content information--"));
|
||||||
|
console->print (tr ("Game logo signature is correct."));
|
||||||
|
tmp = tmp.sprintf (" %s", status.game_name);
|
||||||
|
console->print (tr ("Game title:") + tmp);
|
||||||
|
if (status.cgb == 1)
|
||||||
|
tmp = tr ("YES");
|
||||||
|
else
|
||||||
|
tmp = tr ("NO");
|
||||||
|
console->print (tr ("Designed for Color GB: ") + tmp);
|
||||||
|
if (status.sgb == 1)
|
||||||
|
tmp = tr ("YES");
|
||||||
|
else
|
||||||
|
tmp = tr ("NO");
|
||||||
|
console->print (tr ("Designed for Super GB: ") + tmp);
|
||||||
|
tmp = tmp.sprintf (" %s", status.typ);
|
||||||
|
console->print (tr ("Cartridge type:") + tmp);
|
||||||
|
tmp = tmp.sprintf (" %s", status.rom_size);
|
||||||
|
console->print (tr ("ROM size:") + tmp);
|
||||||
|
tmp = tmp.sprintf (" %s", status.ram_size);
|
||||||
|
console->print (tr ("RAM size:") + tmp);
|
||||||
|
tmp = tmp.sprintf (" 0x%x", status.crc16);
|
||||||
|
console->print (tr ("Checksum:") + tmp);
|
||||||
|
console->line ();
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
console->print (tr ("Game logo signature is incorrect."));
|
||||||
|
console->
|
||||||
|
print (tr ("Cartridge is blank, damaged or not connected."));
|
||||||
|
console->line ();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else
|
||||||
|
print_error (return_code);
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void
|
||||||
|
Gui::read_flash (void)
|
||||||
|
{
|
||||||
|
file_name =
|
||||||
|
QFileDialog::getSaveFileName (this, tr ("Write FLASH to..."), path,
|
||||||
|
tr ("GB Rom Dumps (*.gb *.gbc *.sgb)"));
|
||||||
|
path = Logic::get_path (file_name);
|
||||||
|
if (file_name != "")
|
||||||
|
{
|
||||||
|
thread_RFLA->port = create_port ();
|
||||||
|
if (thread_RFLA->port->open_port (settings->getCom().toUtf8()) == FALSE)
|
||||||
|
{
|
||||||
|
print_error (PORT_ERROR);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
if (!file_name.contains (".gb", Qt::CaseInsensitive)
|
||||||
|
&& !file_name.contains (".gbc", Qt::CaseInsensitive)
|
||||||
|
&& !file_name.contains (".sgb", Qt::CaseInsensitive))
|
||||||
|
file_name = file_name + ".gb";
|
||||||
|
|
||||||
|
thread_RFLA->file = fopen (file_name.toUtf8 (), "wb");
|
||||||
|
thread_RFLA->mbc = settings->getMbc ();
|
||||||
|
thread_RFLA->page_count = settings->getFlash () / 16;
|
||||||
|
thread_RFLA->dap = Settings::dap;
|
||||||
|
thread_RFLA->algorythm = Settings::algorythm;
|
||||||
|
|
||||||
|
setEnabledButtons (FALSE);
|
||||||
|
thread_RFLA->start (Settings::priority);
|
||||||
|
|
||||||
|
console->print (tr ("Reading data from FLASH to file:") + "\n" +
|
||||||
|
file_name);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
Gui::write_flash (void)
|
||||||
|
{
|
||||||
|
|
||||||
|
file_name =
|
||||||
|
QFileDialog::getOpenFileName (this, tr ("Read FLASH from..."), path,
|
||||||
|
tr ("GB Rom Dumps (*.gb *.gbc *.sgb)"));
|
||||||
|
path = Logic::get_path (file_name);
|
||||||
|
if (file_name != "")
|
||||||
|
{
|
||||||
|
long bytes_count;
|
||||||
|
short kilobytes_count;
|
||||||
|
thread_WFLA->port = create_port ();
|
||||||
|
if (thread_WFLA->port->open_port (settings->getCom().toUtf8()) == FALSE)
|
||||||
|
{
|
||||||
|
print_error (PORT_ERROR);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
thread_WFLA->file = fopen (file_name.toUtf8 (), "rb");
|
||||||
|
thread_WFLA->mbc = settings->getMbc ();
|
||||||
|
thread_WFLA->algorythm = Settings::algorythm;
|
||||||
|
thread_WFLA->dap = Settings::dap;
|
||||||
|
|
||||||
|
if (settings->isAuto () == FALSE)
|
||||||
|
{
|
||||||
|
bytes_count = Logic::file_size (thread_WFLA->file);
|
||||||
|
thread_WFLA->page_count =
|
||||||
|
(short) ((bytes_count % 16384L) ? (bytes_count / 16384 +
|
||||||
|
1) : (bytes_count / 16384L));
|
||||||
|
kilobytes_count =
|
||||||
|
(short) ((bytes_count % 1024L) ? (bytes_count / 1024 +
|
||||||
|
1) : (bytes_count / 1024L));
|
||||||
|
|
||||||
|
}
|
||||||
|
else if ((kilobytes_count = Logic::flash_file_size (thread_WFLA->file))
|
||||||
|
!= FALSE)
|
||||||
|
thread_WFLA->page_count = kilobytes_count / 16;
|
||||||
|
else
|
||||||
|
{
|
||||||
|
print_error (WRONG_SIZE);
|
||||||
|
thread_WFLA->port->close_port ();
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
setEnabledButtons (FALSE);
|
||||||
|
|
||||||
|
thread_WFLA->start (Settings::priority);
|
||||||
|
console->print (tr ("Writing data to FLASH from file:") + "\n" +
|
||||||
|
file_name);
|
||||||
|
console->print (tr ("File size: ") + QString::number (kilobytes_count) +
|
||||||
|
"KB");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void
|
||||||
|
Gui::read_ram (void)
|
||||||
|
{
|
||||||
|
|
||||||
|
|
||||||
|
file_name =
|
||||||
|
QFileDialog::getSaveFileName (this, tr ("Write RAM to..."), path,
|
||||||
|
tr ("GB Save (*.sav)"));
|
||||||
|
path = Logic::get_path (file_name);
|
||||||
|
if (file_name != "")
|
||||||
|
{
|
||||||
|
thread_RRAM->port = create_port ();
|
||||||
|
if (thread_RRAM->port->open_port (settings->getCom().toUtf8()) == FALSE)
|
||||||
|
{
|
||||||
|
print_error (PORT_ERROR);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
if (!file_name.contains (".sav", Qt::CaseInsensitive))
|
||||||
|
file_name = file_name + ".sav";
|
||||||
|
thread_RRAM->file = fopen (file_name.toUtf8 (), "wb");
|
||||||
|
thread_RRAM->mbc = settings->getMbc ();
|
||||||
|
thread_RRAM->algorythm = Settings::algorythm;
|
||||||
|
thread_RRAM->dap = Settings::dap;
|
||||||
|
if (settings->getRam () == 2)
|
||||||
|
{
|
||||||
|
thread_RRAM->_2k = 1;
|
||||||
|
thread_RRAM->page_count = 1;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
thread_RRAM->_2k = 0;
|
||||||
|
thread_RRAM->page_count = settings->getRam () / 8;
|
||||||
|
}
|
||||||
|
setEnabledButtons (FALSE);
|
||||||
|
thread_RRAM->start (Settings::priority);
|
||||||
|
|
||||||
|
console->print (tr ("Reading data from RAM to file:") + "\n" +
|
||||||
|
file_name);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
Gui::write_ram (void)
|
||||||
|
{
|
||||||
|
|
||||||
|
file_name =
|
||||||
|
QFileDialog::getOpenFileName (this, tr ("Read RAM from..."), path,
|
||||||
|
tr ("GB Save (*.sav)"));
|
||||||
|
path = Logic::get_path (file_name);
|
||||||
|
if (file_name != "")
|
||||||
|
{
|
||||||
|
long bytes_count;
|
||||||
|
short kilobytes_count;
|
||||||
|
thread_WRAM->port = create_port ();;
|
||||||
|
if (thread_WRAM->port->open_port (settings->getCom().toUtf8()) == FALSE)
|
||||||
|
{
|
||||||
|
print_error (PORT_ERROR);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
thread_WRAM->file = fopen (file_name.toUtf8 (), "rb");
|
||||||
|
thread_WRAM->mbc = settings->getMbc ();
|
||||||
|
thread_WRAM->algorythm = Settings::algorythm;
|
||||||
|
thread_WRAM->dap = Settings::dap;
|
||||||
|
|
||||||
|
if (settings->isAuto () == FALSE)
|
||||||
|
{
|
||||||
|
bytes_count = Logic::file_size (thread_WRAM->file);
|
||||||
|
if (bytes_count == 2048)
|
||||||
|
{
|
||||||
|
thread_WRAM->_2k = 1;
|
||||||
|
thread_WRAM->page_count = 1;
|
||||||
|
kilobytes_count = 2;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
thread_WRAM->_2k = 0;
|
||||||
|
thread_WRAM->page_count =
|
||||||
|
(short) ((bytes_count % 8192L) ? (bytes_count / 8192L +
|
||||||
|
1) : bytes_count / 8192L);
|
||||||
|
kilobytes_count =
|
||||||
|
(short) ((bytes_count % 1024L) ? (bytes_count / 1024 +
|
||||||
|
1) : (bytes_count / 1024L));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else if ((kilobytes_count = Logic::ram_file_size (thread_WRAM->file)) !=
|
||||||
|
FALSE)
|
||||||
|
if (kilobytes_count == 2)
|
||||||
|
{
|
||||||
|
thread_WRAM->_2k = 1;
|
||||||
|
thread_WRAM->page_count = 1;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
thread_WRAM->_2k = 0;
|
||||||
|
thread_WRAM->page_count = kilobytes_count / 8;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
print_error (WRONG_SIZE);
|
||||||
|
thread_WRAM->port->close_port ();
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
setEnabledButtons (FALSE);
|
||||||
|
|
||||||
|
thread_WRAM->start (Settings::priority);
|
||||||
|
console->print (tr ("Writing data to RAM from file:") + "\n" +
|
||||||
|
file_name);
|
||||||
|
console->print (tr ("File size: ") + QString::number (kilobytes_count) +
|
||||||
|
"KB");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
void
|
||||||
|
Gui::erase_flash (void)
|
||||||
|
{
|
||||||
|
thread_E->port = create_port ();
|
||||||
|
if (thread_E->port->open_port (settings->getCom().toUtf8()) == FALSE)
|
||||||
|
{
|
||||||
|
print_error (PORT_ERROR);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
thread_E->mbc = settings->getMbc ();
|
||||||
|
thread_E->mem = EFLA; //FLASH
|
||||||
|
thread_E->par = Settings::algorythm;
|
||||||
|
thread_E->dap = Settings::dap;
|
||||||
|
setEnabledButtons (FALSE);
|
||||||
|
console->print (tr ("Erasing FLASH memory..."));
|
||||||
|
thread_E->start (Settings::priority);
|
||||||
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
Gui::erase_ram (void)
|
||||||
|
{
|
||||||
|
thread_E->port = create_port ();
|
||||||
|
if (thread_E->port->open_port (settings->getCom().toUtf8()) == FALSE)
|
||||||
|
{
|
||||||
|
print_error (PORT_ERROR);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
int window_count;
|
||||||
|
thread_E->mbc = settings->getMbc ();
|
||||||
|
thread_E->mem = ERAM;
|
||||||
|
switch (settings->getRam ())
|
||||||
|
{
|
||||||
|
case 2:
|
||||||
|
case 8:
|
||||||
|
window_count = 0;
|
||||||
|
break;
|
||||||
|
case 32:
|
||||||
|
window_count = 3;
|
||||||
|
break;
|
||||||
|
case 128:
|
||||||
|
window_count = 15;
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
window_count = 15;
|
||||||
|
}
|
||||||
|
|
||||||
|
thread_E->par = window_count;
|
||||||
|
thread_E->dap = Settings::dap;
|
||||||
|
setEnabledButtons (FALSE);
|
||||||
|
console->print (tr ("Erasing RAM memory..."));
|
||||||
|
thread_E->start (Settings::priority);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
void
|
||||||
|
Gui::setProgress (int ile, int max)
|
||||||
|
{
|
||||||
|
progress->setMinimum (0);
|
||||||
|
progress->setMaximum (max);
|
||||||
|
progress->setValue (ile);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void
|
||||||
|
Gui::setEnabledButtons (bool state)
|
||||||
|
{
|
||||||
|
status_btn->setEnabled (state);
|
||||||
|
rflash_btn->setEnabled (state);
|
||||||
|
wflash_btn->setEnabled (state);
|
||||||
|
eflash_btn->setEnabled (state);
|
||||||
|
cancel_btn->setEnabled (!state);
|
||||||
|
//this buttons needs to be dissabled
|
||||||
|
//if no ram is avilable
|
||||||
|
if (settings->isRamDisabled ())
|
||||||
|
state = FALSE;
|
||||||
|
rram_btn->setEnabled (state);
|
||||||
|
wram_btn->setEnabled (state);
|
||||||
|
eram_btn->setEnabled (state);
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
Gui::setRamButtons ()
|
||||||
|
{
|
||||||
|
if (status_btn->isEnabled ())
|
||||||
|
setEnabledButtons (TRUE);
|
||||||
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
Gui::print_error (int err)
|
||||||
|
{
|
||||||
|
switch (err)
|
||||||
|
{
|
||||||
|
case FILEERROR_O:
|
||||||
|
console->print (tr (">Error opening file."));
|
||||||
|
break;
|
||||||
|
|
||||||
|
case FILEERROR_W:
|
||||||
|
console->print (tr (">File write error."));
|
||||||
|
break;
|
||||||
|
|
||||||
|
case FILEERROR_R:
|
||||||
|
console->print (tr (">File read error."));
|
||||||
|
break;
|
||||||
|
|
||||||
|
case SEND_ERROR:
|
||||||
|
console->print (tr (">Error sending data to device."));
|
||||||
|
break;
|
||||||
|
|
||||||
|
case TIMEOUT:
|
||||||
|
console->print (tr (">Timeout!"));
|
||||||
|
break;
|
||||||
|
|
||||||
|
case END:
|
||||||
|
console->print (tr (">Canceled."));
|
||||||
|
break;
|
||||||
|
|
||||||
|
case PORT_ERROR:
|
||||||
|
console->print (tr (">Error opening COM port."));
|
||||||
|
break;
|
||||||
|
|
||||||
|
case WRONG_SIZE:
|
||||||
|
console->print (tr (">Bad file size."));
|
||||||
|
break;
|
||||||
|
|
||||||
|
case FALSE:
|
||||||
|
console->print (tr (">Operation failure."));
|
||||||
|
break;
|
||||||
|
|
||||||
|
case TRUE:
|
||||||
|
console->print (tr (">Success!")); /* succes is not a error code */
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
console->line ();
|
||||||
|
setProgress (0, 1);
|
||||||
|
setEnabledButtons (TRUE);
|
||||||
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
Gui::about ()
|
||||||
|
{
|
||||||
|
About about (this);
|
||||||
|
about.exec ();
|
||||||
|
}
|
71
Gui.h
Normal file
71
Gui.h
Normal file
@ -0,0 +1,71 @@
|
|||||||
|
/*****************************************************************************
|
||||||
|
** Gui.h - class of main dialog window
|
||||||
|
** Author: Kraku
|
||||||
|
*****************************************************************************/
|
||||||
|
#include <QWidget>
|
||||||
|
#include <QLayout>
|
||||||
|
#include <QLabel>
|
||||||
|
#include <QProgressBar>
|
||||||
|
#include <QPushButton>
|
||||||
|
#include <QString>
|
||||||
|
#include "Settings.h"
|
||||||
|
#include "Console.h"
|
||||||
|
#include "Logic.h"
|
||||||
|
#include "About.h"
|
||||||
|
|
||||||
|
#include "ReadFlashThread.h"
|
||||||
|
#include "WriteFlashThread.h"
|
||||||
|
#include "EraseThread.h"
|
||||||
|
#include "ReadRamThread.h"
|
||||||
|
#include "WriteRamThread.h"
|
||||||
|
|
||||||
|
class Gui:public QWidget
|
||||||
|
{
|
||||||
|
Q_OBJECT Settings * settings;
|
||||||
|
Console *console;
|
||||||
|
QGridLayout *grid;
|
||||||
|
QVBoxLayout *left;
|
||||||
|
QVBoxLayout *right;
|
||||||
|
QVBoxLayout *center;
|
||||||
|
QHBoxLayout *down;
|
||||||
|
QProgressBar *progress;
|
||||||
|
QLabel *image;
|
||||||
|
QPixmap *logo;
|
||||||
|
QPushButton *cancel_btn;
|
||||||
|
QPushButton *status_btn;
|
||||||
|
QPushButton *rflash_btn;
|
||||||
|
QPushButton *wflash_btn;
|
||||||
|
QPushButton *rram_btn;
|
||||||
|
QPushButton *wram_btn;
|
||||||
|
QPushButton *eflash_btn;
|
||||||
|
QPushButton *eram_btn;
|
||||||
|
QPushButton *about_btn;
|
||||||
|
QString file_name;
|
||||||
|
QString path;
|
||||||
|
About about_dlg;
|
||||||
|
WriteFlashThread *thread_WFLA;
|
||||||
|
ReadFlashThread *thread_RFLA;
|
||||||
|
EraseThread *thread_E;
|
||||||
|
ReadRamThread *thread_RRAM;
|
||||||
|
WriteRamThread * thread_WRAM;
|
||||||
|
|
||||||
|
public:
|
||||||
|
Gui (QWidget * parent = 0);
|
||||||
|
static int port_type;
|
||||||
|
|
||||||
|
|
||||||
|
public slots:void startup_info (void);
|
||||||
|
void setEnabledButtons (bool stan);
|
||||||
|
void setRamButtons ();
|
||||||
|
void print_error (int err);
|
||||||
|
void write_flash (void);
|
||||||
|
void read_flash (void);
|
||||||
|
void read_ram (void);
|
||||||
|
void write_ram (void);
|
||||||
|
void show_info (void);
|
||||||
|
void erase_flash (void);
|
||||||
|
void erase_ram (void);
|
||||||
|
void about ();
|
||||||
|
void setProgress (int ile, int max);
|
||||||
|
AbstractPort *create_port ();
|
||||||
|
};
|
320
Logic.cpp
Normal file
320
Logic.cpp
Normal file
@ -0,0 +1,320 @@
|
|||||||
|
/*****************************************************************************
|
||||||
|
** Logic.cpp - Source file containing all utility functions used in
|
||||||
|
** communication process by Threads and Gui
|
||||||
|
** Author: Kraku
|
||||||
|
*****************************************************************************/
|
||||||
|
#include "Logic.h"
|
||||||
|
#include "const.h"
|
||||||
|
#include "AbstractPort.h"
|
||||||
|
#include <ctype.h>
|
||||||
|
#include <cassert>
|
||||||
|
|
||||||
|
/* array used to generate crc16 */
|
||||||
|
unsigned short crc16_tab[256] = {
|
||||||
|
0x0000, 0x1021, 0x2042, 0x3063, 0x4084, 0x50A5, 0x60C6, 0x70E7, 0x8108,
|
||||||
|
0x9129, 0xA14A, 0xB16B, 0xC18C, 0xD1AD, 0xE1CE, 0xF1EF, 0x1231, 0x0210,
|
||||||
|
0x3273, 0x2252, 0x52B5, 0x4294, 0x72F7, 0x62D6, 0x9339, 0x8318, 0xB37B,
|
||||||
|
0xA35A, 0xD3BD, 0xC39C, 0xF3FF, 0xE3DE, 0x2462, 0x3443, 0x0420, 0x1401,
|
||||||
|
0x64E6, 0x74C7, 0x44A4, 0x5485, 0xA56A, 0xB54B, 0x8528, 0x9509, 0xE5EE,
|
||||||
|
0xF5CF, 0xC5AC, 0xD58D, 0x3653, 0x2672, 0x1611, 0x0630, 0x76D7, 0x66F6,
|
||||||
|
0x5695, 0x46B4, 0xB75B, 0xA77A, 0x9719, 0x8738, 0xF7DF, 0xE7FE, 0xD79D,
|
||||||
|
0xC7BC, 0x48C4, 0x58E5, 0x6886, 0x78A7, 0x0840, 0x1861, 0x2802, 0x3823,
|
||||||
|
0xC9CC, 0xD9ED, 0xE98E, 0xF9AF, 0x8948, 0x9969, 0xA90A, 0xB92B, 0x5AF5,
|
||||||
|
0x4AD4, 0x7AB7, 0x6A96, 0x1A71, 0x0A50, 0x3A33, 0x2A12, 0xDBFD, 0xCBDC,
|
||||||
|
0xFBBF, 0xEB9E, 0x9B79, 0x8B58, 0xBB3B, 0xAB1A, 0x6CA6, 0x7C87, 0x4CE4,
|
||||||
|
0x5CC5, 0x2C22, 0x3C03, 0x0C60, 0x1C41, 0xEDAE, 0xFD8F, 0xCDEC, 0xDDCD,
|
||||||
|
0xAD2A, 0xBD0B, 0x8D68, 0x9D49, 0x7E97, 0x6EB6, 0x5ED5, 0x4EF4, 0x3E13,
|
||||||
|
0x2E32, 0x1E51, 0x0E70, 0xFF9F, 0xEFBE, 0xDFDD, 0xCFFC, 0xBF1B, 0xAF3A,
|
||||||
|
0x9F59, 0x8F78, 0x9188, 0x81A9, 0xB1CA, 0xA1EB, 0xD10C, 0xC12D, 0xF14E,
|
||||||
|
0xE16F, 0x1080, 0x00A1, 0x30C2, 0x20E3, 0x5004, 0x4025, 0x7046, 0x6067,
|
||||||
|
0x83B9, 0x9398, 0xA3FB, 0xB3DA, 0xC33D, 0xD31C, 0xE37F, 0xF35E, 0x02B1,
|
||||||
|
0x1290, 0x22F3, 0x32D2, 0x4235, 0x5214, 0x6277, 0x7256, 0xB5EA, 0xA5CB,
|
||||||
|
0x95A8, 0x8589, 0xF56E, 0xE54F, 0xD52C, 0xC50D, 0x34E2, 0x24C3, 0x14A0,
|
||||||
|
0x0481, 0x7466, 0x6447, 0x5424, 0x4405, 0xA7DB, 0xB7FA, 0x8799, 0x97B8,
|
||||||
|
0xE75F, 0xF77E, 0xC71D, 0xD73C, 0x26D3, 0x36F2, 0x0691, 0x16B0, 0x6657,
|
||||||
|
0x7676, 0x4615, 0x5634, 0xD94C, 0xC96D, 0xF90E, 0xE92F, 0x99C8, 0x89E9,
|
||||||
|
0xB98A, 0xA9AB, 0x5844, 0x4865, 0x7806, 0x6827, 0x18C0, 0x08E1, 0x3882,
|
||||||
|
0x28A3, 0xCB7D, 0xDB5C, 0xEB3F, 0xFB1E, 0x8BF9, 0x9BD8, 0xABBB, 0xBB9A,
|
||||||
|
0x4A75, 0x5A54, 0x6A37, 0x7A16, 0x0AF1, 0x1AD0, 0x2AB3, 0x3A92, 0xFD2E,
|
||||||
|
0xED0F, 0xDD6C, 0xCD4D, 0xBDAA, 0xAD8B, 0x9DE8, 0x8DC9, 0x7C26, 0x6C07,
|
||||||
|
0x5C64, 0x4C45, 0x3CA2, 0x2C83, 0x1CE0, 0x0CC1, 0xEF1F, 0xFF3E, 0xCF5D,
|
||||||
|
0xDF7C, 0xAF9B, 0xBFBA, 0x8FD9, 0x9FF8, 0x6E17, 0x7E36, 0x4E55, 0x5E74,
|
||||||
|
0x2E93, 0x3EB2, 0x0ED1, 0x1EF0
|
||||||
|
};
|
||||||
|
|
||||||
|
/* array of producers names and codes */
|
||||||
|
desc_t producers[] = {
|
||||||
|
{0x01, "AMD"}, {0x02, "AMI"}, {0xe5, "Analog Devices"},
|
||||||
|
{0x1f, "Atmel"}, {0x31, "Catalyst"}, {0x34, "Cypress"},
|
||||||
|
{0x04, "Fujitsu"}, {0xE0, "Goldstar"}, {0x07, "Hitachi"},
|
||||||
|
{0xad, "Hyundai"}, {0xc1, "Infineon"}, {0x89, "Intel"},
|
||||||
|
{0xd5, "Intg. Silicon Systems"}, {0xc2, "Macronix"}, {0x29, "Microchip"},
|
||||||
|
{0x2c, "Micron"}, {0x1c, "Mitsubishi"}, {0x10, "Nec"},
|
||||||
|
{0x15, "Philips Semiconductors"}, {0xce, "Samsung"}, {0x62, "Sanyo"},
|
||||||
|
{0x20, "SGS Thomson"}, {0xb0, "Sharp"}, {0xbf, "SST"},
|
||||||
|
{0x97, "Texas Instruments"}, {0x98, "Toshiba"}, {0xda, "Winbond"},
|
||||||
|
{0x19, "Xicor"}, {0xc9, "Xilinx"}
|
||||||
|
};
|
||||||
|
|
||||||
|
/* array of cart types - source GB CPU Manual */
|
||||||
|
desc_t carts[] = {
|
||||||
|
{0x00, "ROM ONLY"}, {0x01, "ROM+MBC1"},
|
||||||
|
{0x02, "ROM+MBC1+RAM"}, {0x03, "ROM+MBC1+RAM+BATT"},
|
||||||
|
{0x05, "ROM+MBC2"}, {0x06, "ROM+MBC2+BATTERY"},
|
||||||
|
{0x08, "ROM+RAM"}, {0x09, "ROM+RAM+BATTERY"},
|
||||||
|
{0x11, "ROM+MBC3"},
|
||||||
|
{0x0b, "ROM+MMMO1"}, {0x0c, "ROM+MMMO1+SRAM"},
|
||||||
|
{0x0d, "ROM+MMMO1+SRAM+BATT"}, {0x0f, "ROM+MBC3+TIMER+BATT"},
|
||||||
|
{0x10, "ROM+MBC3+TIMER+RAM+BAT"}, {0x12, "ROM+MBC3+RAM"},
|
||||||
|
{0x13, "ROM+MBC3+RAM+BATT"}, {0x19, "ROM+MBC5"},
|
||||||
|
{0x1a, "ROM+MBC5+RAM"}, {0x1b, "ROM+MBC5+RAM+BATT"},
|
||||||
|
{0x1c, "ROM+MBC5+RUMBLE"}, {0x1d, "ROM+MBC5+RUMBLE+SRAM"},
|
||||||
|
{0x1e, "ROM+MBC5+RUMBLE+SRAM+BATT"}, {0x1f, "Pocket Camera"},
|
||||||
|
{0xfd, "Bandai TAMA5"}, {0xfe, "Hudson HuC-3"}
|
||||||
|
};
|
||||||
|
|
||||||
|
desc_t rom_sizes[] = {
|
||||||
|
{0x00, "32KB"}, {0x01, "64KB"}, {0x02, "128KB"}, {0x03, "256KB"},
|
||||||
|
{0x04, "512KB"}, {0x05, "1MB"}, {0x06, "2MB"}, {0x52, "1.1MB"},
|
||||||
|
{0x53, "1.2MB"}, {0x54, "1.5MB"}
|
||||||
|
};
|
||||||
|
|
||||||
|
desc_t ram_sizes[] = {
|
||||||
|
{0x00, "0KB"}, {0x01, "2KB"}, {0x02, "8KB"}, {0x03, "32KB"}, {0x04, "128KB"}
|
||||||
|
};
|
||||||
|
|
||||||
|
Logic::Logic (QObject * parent):QObject (parent)
|
||||||
|
{
|
||||||
|
|
||||||
|
//version with threads
|
||||||
|
//TODO: move it
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
int
|
||||||
|
Logic::read_status (AbstractPort * port, const char *port_name, char id, char mbc,
|
||||||
|
char algorythm, status_t * flasher_stat)
|
||||||
|
{
|
||||||
|
assert (port != NULL);
|
||||||
|
if (port->open_port (port_name) == FALSE)
|
||||||
|
return PORT_ERROR;
|
||||||
|
|
||||||
|
unsigned short crc16;
|
||||||
|
unsigned char packet[PACKETSIZE];
|
||||||
|
memset (packet, 0x00, PACKETSIZE);
|
||||||
|
packet[0] = DATA;
|
||||||
|
packet[1] = STATUS;
|
||||||
|
packet[2] = id;
|
||||||
|
packet[3] = mbc;
|
||||||
|
packet[4] = algorythm;
|
||||||
|
crc16 = generate_crc16 (packet);
|
||||||
|
packet[PACKETSIZE - 2] = crc16 / 256;
|
||||||
|
packet[PACKETSIZE - 1] = crc16 % 256;
|
||||||
|
|
||||||
|
if (port->send_packet (packet) < PACKETSIZE)
|
||||||
|
{
|
||||||
|
port->close_port ();
|
||||||
|
return SEND_ERROR;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
if (port->receive_packet (packet) == DATA)
|
||||||
|
{
|
||||||
|
int i, producers_count = sizeof producers / sizeof producers[0];
|
||||||
|
int types_count = sizeof carts / sizeof carts[0];
|
||||||
|
int types_count_rom = sizeof rom_sizes / sizeof rom_sizes[0];
|
||||||
|
int types_count_ram = sizeof ram_sizes / sizeof ram_sizes[0];
|
||||||
|
|
||||||
|
/* filling struct with data from packet */
|
||||||
|
flasher_stat->ver_11 = packet[2] / 16;
|
||||||
|
flasher_stat->ver_12 = packet[2] % 16;
|
||||||
|
flasher_stat->ver_21 = packet[3] / 16;
|
||||||
|
flasher_stat->ver_22 = packet[3] % 16;
|
||||||
|
flasher_stat->manufacturer_id = packet[4];
|
||||||
|
/* if code if not found - it remains unknown */
|
||||||
|
strcpy (flasher_stat->manufacturer,
|
||||||
|
tr ("Unknown manufacturer").toLocal8Bit ());
|
||||||
|
for (i = 0; i < producers_count; i++)
|
||||||
|
if (flasher_stat->manufacturer_id == producers[i].index)
|
||||||
|
{
|
||||||
|
memset (flasher_stat->manufacturer, 0x00, 30);
|
||||||
|
strcpy (flasher_stat->manufacturer, producers[i].name);
|
||||||
|
}
|
||||||
|
flasher_stat->chip_id = packet[5];
|
||||||
|
flasher_stat->bbl = packet[6] & 0x01;
|
||||||
|
|
||||||
|
flasher_stat->logo_correct = packet[8];
|
||||||
|
memcpy (flasher_stat->game_name, &packet[9], 16);
|
||||||
|
for (int i = 0; i < 16; i++)
|
||||||
|
if (!isalnum (flasher_stat->game_name[i])
|
||||||
|
|| flasher_stat->game_name[i] == '\n')
|
||||||
|
flasher_stat->game_name[i] = ' ';
|
||||||
|
flasher_stat->game_name[16] = '\0';
|
||||||
|
flasher_stat->cgb = (packet[24] == 0x80) ? 1 : 0;
|
||||||
|
flasher_stat->sgb = (packet[27] == 0x03) ? 1 : 0;
|
||||||
|
strcpy (flasher_stat->typ, tr ("Unknown type").toLocal8Bit ());
|
||||||
|
for (i = 0; i < types_count; i++)
|
||||||
|
if (packet[28] == carts[i].index)
|
||||||
|
{
|
||||||
|
memset (flasher_stat->typ, 0x00, 30);
|
||||||
|
strcpy (flasher_stat->typ, carts[i].name);
|
||||||
|
}
|
||||||
|
|
||||||
|
for (i = 0; i < types_count_rom; i++)
|
||||||
|
if (packet[29] == rom_sizes[i].index)
|
||||||
|
{
|
||||||
|
memset (flasher_stat->rom_size, 0x00,
|
||||||
|
sizeof flasher_stat->rom_size);
|
||||||
|
strcpy (flasher_stat->rom_size, rom_sizes[i].name);
|
||||||
|
}
|
||||||
|
|
||||||
|
for (i = 0; i < types_count_ram; i++)
|
||||||
|
if (packet[30] == ram_sizes[i].index)
|
||||||
|
{
|
||||||
|
memset (flasher_stat->ram_size, 0x00,
|
||||||
|
sizeof flasher_stat->ram_size);
|
||||||
|
strcpy (flasher_stat->ram_size, ram_sizes[i].name);
|
||||||
|
}
|
||||||
|
flasher_stat->crc16 = 256 * packet[35] + packet[36];
|
||||||
|
|
||||||
|
port->close_port ();
|
||||||
|
return TRUE;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
port->close_port ();
|
||||||
|
return FALSE;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
unsigned short
|
||||||
|
Logic::generate_crc16 (unsigned char packet[PACKETSIZE])
|
||||||
|
{
|
||||||
|
int i;
|
||||||
|
unsigned short crc16 = 0x0000;
|
||||||
|
/* generate for whole packet, except for two last bytes */
|
||||||
|
for (i = 0; i < PACKETSIZE - 2; i++)
|
||||||
|
crc16 = (crc16 << 8) ^ crc16_tab[((crc16 >> 8) ^ packet[i]) & 0xFF];
|
||||||
|
return crc16;
|
||||||
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
Logic::fill_data_packet (unsigned char packet[PACKETSIZE],
|
||||||
|
unsigned char data[FRAMESIZE], char packet_type,
|
||||||
|
unsigned char packet_index, int page_index)
|
||||||
|
{
|
||||||
|
unsigned short crc16;
|
||||||
|
memset (packet, 0x00, PACKETSIZE);
|
||||||
|
packet[0] = DATA;
|
||||||
|
packet[1] = packet_type;
|
||||||
|
packet[2] = RESERVED;
|
||||||
|
packet[3] = packet_index;
|
||||||
|
packet[4] = page_index / 256;
|
||||||
|
packet[5] = page_index % 256;
|
||||||
|
/* copy data to packet */
|
||||||
|
memcpy (&packet[6], data, FRAMESIZE);
|
||||||
|
|
||||||
|
/* generate and set crc */
|
||||||
|
crc16 = generate_crc16 (packet);
|
||||||
|
packet[PACKETSIZE - 2] = crc16 / 256;
|
||||||
|
packet[PACKETSIZE - 1] = crc16 % 256;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
int
|
||||||
|
Logic::check_packet (unsigned char packet[PACKETSIZE])
|
||||||
|
{
|
||||||
|
unsigned short crc16 = generate_crc16 (packet);
|
||||||
|
/* data packet with correct crc */
|
||||||
|
if (packet[0] == DATA && packet[PACKETSIZE - 2] == crc16 / 256
|
||||||
|
&& packet[PACKETSIZE - 1] == crc16 % 256)
|
||||||
|
return packet[1]; /* return packet type */
|
||||||
|
else
|
||||||
|
return BAD_PACKET;
|
||||||
|
}
|
||||||
|
|
||||||
|
long
|
||||||
|
Logic::file_size (FILE * file)
|
||||||
|
{
|
||||||
|
long size = 0;
|
||||||
|
fseek (file, 0x00, SEEK_END);
|
||||||
|
size = ftell (file);
|
||||||
|
fseek (file, 0x00, SEEK_SET);
|
||||||
|
return size;
|
||||||
|
}
|
||||||
|
|
||||||
|
short
|
||||||
|
Logic::flash_file_size (FILE * file)
|
||||||
|
{
|
||||||
|
long mem_size = Logic::file_size (file);
|
||||||
|
/* file_size w kB */
|
||||||
|
switch (mem_size)
|
||||||
|
{
|
||||||
|
case 32 * 1024:
|
||||||
|
case 64 * 1024:
|
||||||
|
case 128 * 1024:
|
||||||
|
case 256 * 1024:
|
||||||
|
case 512 * 1024:
|
||||||
|
case 1024 * 1024:
|
||||||
|
case 2048 * 1024:
|
||||||
|
case 4096 * 1024:
|
||||||
|
case 8192 * 1024:
|
||||||
|
return (short) (mem_size / 1024L);
|
||||||
|
default:
|
||||||
|
return FALSE;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
short
|
||||||
|
Logic::ram_file_size (FILE * file)
|
||||||
|
{
|
||||||
|
long mem_size = Logic::file_size (file);
|
||||||
|
switch (mem_size)
|
||||||
|
{
|
||||||
|
case 2 * 1024:
|
||||||
|
case 8 * 1024:
|
||||||
|
case 32 * 1024:
|
||||||
|
case 128 * 1024:
|
||||||
|
return (short) (mem_size / 1024L);
|
||||||
|
default:
|
||||||
|
return FALSE;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
bool
|
||||||
|
Logic::send_start_packet (AbstractPort * port, config_t cfg)
|
||||||
|
{
|
||||||
|
unsigned short crc16;
|
||||||
|
unsigned char packet[PACKETSIZE];
|
||||||
|
memset (packet, 0x00, PACKETSIZE);
|
||||||
|
packet[0] = DATA;
|
||||||
|
packet[1] = CONFIG;
|
||||||
|
packet[2] = cfg.operation;
|
||||||
|
packet[3] = cfg.mbc;
|
||||||
|
packet[4] = cfg.algorythm;
|
||||||
|
packet[5] = cfg.dap;
|
||||||
|
packet[6] = (cfg.page_count - 1) / 256;
|
||||||
|
packet[7] = (cfg.page_count - 1) % 256;
|
||||||
|
crc16 = Logic::generate_crc16 (packet);
|
||||||
|
packet[PACKETSIZE - 2] = crc16 / 256;
|
||||||
|
packet[PACKETSIZE - 1] = crc16 % 256;
|
||||||
|
if (port->send_packet (packet) < PACKETSIZE)
|
||||||
|
return FALSE;
|
||||||
|
else
|
||||||
|
return TRUE;
|
||||||
|
}
|
||||||
|
|
||||||
|
QString
|
||||||
|
Logic::get_path (QString name)
|
||||||
|
{
|
||||||
|
int end;
|
||||||
|
|
||||||
|
if ((end = name.lastIndexOf ("/")) != -1)
|
||||||
|
{
|
||||||
|
return name.left (end);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
return QString (".");
|
||||||
|
}
|
92
Logic.h
Normal file
92
Logic.h
Normal file
@ -0,0 +1,92 @@
|
|||||||
|
/*****************************************************************************
|
||||||
|
** Logic.h - Header file for utility functions used in communication proces
|
||||||
|
** Author: Kraku
|
||||||
|
*****************************************************************************/
|
||||||
|
#ifndef _LOGIC_H_
|
||||||
|
#define _LOGIC_H_
|
||||||
|
#include <QObject>
|
||||||
|
#include "const.h"
|
||||||
|
#include "AbstractPort.h"
|
||||||
|
|
||||||
|
/*
|
||||||
|
* structure consist of key/value pairs for any kind of descriptions
|
||||||
|
* most of those codes/descriptions are taken from GB CPU Manual
|
||||||
|
*/
|
||||||
|
typedef struct
|
||||||
|
{
|
||||||
|
unsigned char index;
|
||||||
|
char name[30];
|
||||||
|
} desc_t;
|
||||||
|
|
||||||
|
/* struct being used to fill packet header */
|
||||||
|
typedef struct
|
||||||
|
{
|
||||||
|
unsigned char operation;
|
||||||
|
unsigned char mbc;
|
||||||
|
unsigned char algorythm;
|
||||||
|
unsigned char dap;
|
||||||
|
int page_count;
|
||||||
|
} config_t;
|
||||||
|
|
||||||
|
/* struct filled by status */
|
||||||
|
typedef struct
|
||||||
|
{
|
||||||
|
/* digits describing version of device soft */
|
||||||
|
unsigned char ver_11;
|
||||||
|
unsigned char ver_12;
|
||||||
|
unsigned char ver_21;
|
||||||
|
unsigned char ver_22;
|
||||||
|
/* flash chip date */
|
||||||
|
unsigned char manufacturer_id;
|
||||||
|
char manufacturer[30];
|
||||||
|
unsigned char chip_id;
|
||||||
|
unsigned char bbl;
|
||||||
|
/* info about loaded game */
|
||||||
|
unsigned char logo_correct;
|
||||||
|
unsigned char cgb;
|
||||||
|
unsigned char sgb;
|
||||||
|
char rom_size[6];
|
||||||
|
char ram_size[6];
|
||||||
|
unsigned short crc16;
|
||||||
|
char typ[30];
|
||||||
|
char game_name[17];
|
||||||
|
} status_t;
|
||||||
|
|
||||||
|
/* Logic has to inherit from QObject in order to send signals */
|
||||||
|
class Logic:public QObject
|
||||||
|
{
|
||||||
|
Q_OBJECT public:
|
||||||
|
|
||||||
|
/* generate crc16 checksum stored in last two bytes of packet */
|
||||||
|
static unsigned short generate_crc16 (unsigned char packet[PACKETSIZE]);
|
||||||
|
/* both function calculate file size, and check if it's correct ROM/RAM size
|
||||||
|
* if it's OK it returns file size in kB else return FALSE
|
||||||
|
*/
|
||||||
|
static short flash_file_size (FILE * file);
|
||||||
|
static short ram_file_size (FILE * file);
|
||||||
|
/* additional function returning exact file size in B */
|
||||||
|
static long file_size (FILE * file);
|
||||||
|
/* function extracting path from fully qualified filename */
|
||||||
|
static QString get_path (QString name);
|
||||||
|
/* check packet type and crc
|
||||||
|
* return packet type if ok or BAD_PACKET otherwise
|
||||||
|
*/
|
||||||
|
static int check_packet (unsigned char packet[PACKETSIZE]);
|
||||||
|
/* create data packet from data, and set packet/page number and crc */
|
||||||
|
static void fill_data_packet (unsigned char packet[PACKETSIZE],
|
||||||
|
unsigned char data[FRAMESIZE],
|
||||||
|
char packet_type, unsigned char packet_number,
|
||||||
|
int page_number);
|
||||||
|
Logic (QObject * parent = 0);
|
||||||
|
/* query device for status of itself and cart, fills status_t struct */
|
||||||
|
static int read_status (AbstractPort * port, const char *name_portu, char id,
|
||||||
|
char mbc, char alg, status_t * flasher_stat);
|
||||||
|
/* sends start packet generateg from given configuration */
|
||||||
|
static bool send_start_packet (AbstractPort * port, config_t cfg);
|
||||||
|
|
||||||
|
signals:
|
||||||
|
void set_progress (int procent, int max);
|
||||||
|
void refresh (void);
|
||||||
|
};
|
||||||
|
|
||||||
|
#endif
|
177
ReadFlashThread.cpp
Normal file
177
ReadFlashThread.cpp
Normal file
@ -0,0 +1,177 @@
|
|||||||
|
/*****************************************************************************
|
||||||
|
** ReadFlashThread.cpp
|
||||||
|
** Author: Kraku
|
||||||
|
*****************************************************************************/
|
||||||
|
#include "ReadFlashThread.h"
|
||||||
|
#include "Settings.h"
|
||||||
|
#include "Logic.h"
|
||||||
|
#include "const.h"
|
||||||
|
|
||||||
|
|
||||||
|
void
|
||||||
|
ReadFlashThread::run ()
|
||||||
|
{
|
||||||
|
end = FALSE;
|
||||||
|
unsigned char packet[72], data[16384];
|
||||||
|
int character, data_type = 0x00, recived = 0, retries =
|
||||||
|
0, page_number, packet_number, prv_count = 0;
|
||||||
|
config_t cfg;
|
||||||
|
cfg.operation = RROM;
|
||||||
|
cfg.mbc = mbc;
|
||||||
|
cfg.algorythm = algorythm;
|
||||||
|
cfg.dap = Settings::dap;
|
||||||
|
cfg.page_count = page_count;
|
||||||
|
|
||||||
|
if (file == NULL)
|
||||||
|
{
|
||||||
|
port->close_port ();
|
||||||
|
emit error (FILEERROR_O);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
do
|
||||||
|
{ /* send start packet and wait for first one of response */
|
||||||
|
if (Logic::send_start_packet (port, cfg) == FALSE)
|
||||||
|
{
|
||||||
|
port->close_port ();
|
||||||
|
fclose (file);
|
||||||
|
emit error (SEND_ERROR);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
character = port->receive_packet (packet);
|
||||||
|
|
||||||
|
if (character == END || character == TIMEOUT)
|
||||||
|
{
|
||||||
|
port->close_port ();
|
||||||
|
fclose (file);
|
||||||
|
emit error (character);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (character == DATA) /* if packet received - check it */
|
||||||
|
data_type = Logic::check_packet (packet);
|
||||||
|
}
|
||||||
|
while (data_type != NORMAL_DATA && ++retries < 10);
|
||||||
|
|
||||||
|
if (retries == 10)
|
||||||
|
{
|
||||||
|
port->close_port ();
|
||||||
|
fclose (file);
|
||||||
|
emit error (TIMEOUT);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
retries = 0;
|
||||||
|
/* work until LAST_DATA */
|
||||||
|
do
|
||||||
|
{
|
||||||
|
if (recived != 0) /* if first packet, don't need to get it */
|
||||||
|
character = port->receive_packet (packet);
|
||||||
|
|
||||||
|
if (character == TIMEOUT || character == END)
|
||||||
|
{
|
||||||
|
port->close_port ();
|
||||||
|
fclose (file);
|
||||||
|
emit error (character);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
//end of thread!!!!
|
||||||
|
if (end)
|
||||||
|
{
|
||||||
|
port->send_char (END);
|
||||||
|
port->close_port ();
|
||||||
|
fclose (file);
|
||||||
|
emit error (END);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
data_type = Logic::check_packet (packet);
|
||||||
|
|
||||||
|
if (data_type == NORMAL_DATA || data_type == LAST_DATA)
|
||||||
|
{ /* valid data packet */
|
||||||
|
page_number = recived / 256; /* 256 packets = page */
|
||||||
|
packet_number = recived % 256;
|
||||||
|
retries = 0;
|
||||||
|
|
||||||
|
/* current packet */
|
||||||
|
if (packet_number == packet[3]
|
||||||
|
&& page_number == packet[4] * 256 + packet[5])
|
||||||
|
{
|
||||||
|
memcpy (&data[packet_number * 64], &packet[6], FRAMESIZE);
|
||||||
|
if (packet_number == 255) /* if entire page - save it to file */
|
||||||
|
if (fwrite (data, 1, sizeof data, file) < sizeof data)
|
||||||
|
{
|
||||||
|
port->close_port ();
|
||||||
|
fclose (file);
|
||||||
|
emit error (FILEERROR_W);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
port->send_char (ACK); /* send confirmation */
|
||||||
|
recived++;
|
||||||
|
prv_count = 0;
|
||||||
|
/* set progress bar status */
|
||||||
|
emit set_progress (recived, page_count * 256 - 1);
|
||||||
|
}
|
||||||
|
/* last packet received- packet is lost */
|
||||||
|
else if (((packet_number - 1) % 255) == packet[3])
|
||||||
|
{
|
||||||
|
/* device is sending last packets - end of transmision */
|
||||||
|
if (++prv_count == 10)
|
||||||
|
{
|
||||||
|
port->send_char (END);
|
||||||
|
port->close_port ();
|
||||||
|
fclose (file);
|
||||||
|
emit error (END);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
port->send_char (ACK);
|
||||||
|
/* confirm receivment, force device to send current packet */
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{ /* valid packet, but not current nor last */
|
||||||
|
port->send_char (END);
|
||||||
|
port->close_port ();
|
||||||
|
fclose (file);
|
||||||
|
emit error (END);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{ /* bad data or NAK */
|
||||||
|
if (++retries < 10)
|
||||||
|
port->send_char (NAK);
|
||||||
|
else
|
||||||
|
{
|
||||||
|
port->send_char (END);
|
||||||
|
port->close_port ();
|
||||||
|
fclose (file);
|
||||||
|
emit error (END);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
while (data_type != LAST_DATA);
|
||||||
|
|
||||||
|
/* if correct data size received - end */
|
||||||
|
if (recived * 64 == page_count * 16384)
|
||||||
|
{
|
||||||
|
port->close_port ();
|
||||||
|
fclose (file);
|
||||||
|
emit error (TRUE);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
port->close_port ();
|
||||||
|
fclose (file);
|
||||||
|
emit error (END);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
ReadFlashThread::canceled (void)
|
||||||
|
{
|
||||||
|
end = TRUE;
|
||||||
|
}
|
33
ReadFlashThread.h
Normal file
33
ReadFlashThread.h
Normal file
@ -0,0 +1,33 @@
|
|||||||
|
/*****************************************************************************
|
||||||
|
** ReadFlashThread.h
|
||||||
|
** Author: Kraku
|
||||||
|
*****************************************************************************/
|
||||||
|
#ifndef _READFLASHTHREAD_H_
|
||||||
|
#define _READFLASHTHREAD_H_
|
||||||
|
#include <QThread>
|
||||||
|
#include "AbstractPort.h"
|
||||||
|
#include "Logic.h"
|
||||||
|
|
||||||
|
class ReadFlashThread:public QThread
|
||||||
|
{
|
||||||
|
Q_OBJECT public:
|
||||||
|
ReadFlashThread ()
|
||||||
|
{
|
||||||
|
}
|
||||||
|
virtual void run ();
|
||||||
|
bool end;
|
||||||
|
FILE *file;
|
||||||
|
char mbc;
|
||||||
|
char algorythm;
|
||||||
|
char dap;
|
||||||
|
int page_count;
|
||||||
|
AbstractPort *port;
|
||||||
|
|
||||||
|
public slots:void canceled (void);
|
||||||
|
|
||||||
|
signals:
|
||||||
|
void set_progress (int ile, int max);
|
||||||
|
void error (int err);
|
||||||
|
};
|
||||||
|
|
||||||
|
#endif
|
184
ReadRamThread.cpp
Normal file
184
ReadRamThread.cpp
Normal file
@ -0,0 +1,184 @@
|
|||||||
|
/*****************************************************************************
|
||||||
|
** ReadRamThread.cpp
|
||||||
|
** Author: Kraku
|
||||||
|
*****************************************************************************/
|
||||||
|
#include "ReadRamThread.h"
|
||||||
|
#include "Settings.h"
|
||||||
|
#include "Logic.h"
|
||||||
|
#include "const.h"
|
||||||
|
|
||||||
|
|
||||||
|
void
|
||||||
|
ReadRamThread::run ()
|
||||||
|
{
|
||||||
|
|
||||||
|
end = FALSE;
|
||||||
|
unsigned char packet[72], data[2048]; /* 2kB cart is avilable */
|
||||||
|
int n, data_type = 0x00, recived = 0, retries =
|
||||||
|
0, page_number, packet_number, prv_count = 0;
|
||||||
|
config_t cfg;
|
||||||
|
cfg.operation = RRAM;
|
||||||
|
cfg.mbc = mbc;
|
||||||
|
cfg.algorythm = algorythm;
|
||||||
|
cfg.dap = Settings::dap;
|
||||||
|
cfg.page_count = page_count;
|
||||||
|
if (_2k) /* if only 2kB to process */
|
||||||
|
page_count = 1; /* treat as 8kB - one page of RAM */
|
||||||
|
|
||||||
|
if (file == NULL)
|
||||||
|
{
|
||||||
|
port->close_port ();
|
||||||
|
emit error (FILEERROR_O);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
do
|
||||||
|
{
|
||||||
|
if (Logic::send_start_packet (port, cfg) == FALSE)
|
||||||
|
{
|
||||||
|
port->close_port ();
|
||||||
|
fclose (file);
|
||||||
|
emit error (SEND_ERROR);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
n = port->receive_packet (packet);
|
||||||
|
if (n == END || n == TIMEOUT)
|
||||||
|
{
|
||||||
|
port->close_port ();
|
||||||
|
fclose (file);
|
||||||
|
emit error (n);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
if (n == DATA)
|
||||||
|
data_type = Logic::check_packet (packet);
|
||||||
|
}
|
||||||
|
while (data_type != NORMAL_DATA && ++retries < 10);
|
||||||
|
|
||||||
|
if (retries == 10)
|
||||||
|
{
|
||||||
|
port->close_port ();
|
||||||
|
fclose (file);
|
||||||
|
emit error (TIMEOUT);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
retries = 0;
|
||||||
|
|
||||||
|
do
|
||||||
|
{
|
||||||
|
if (recived != 0)
|
||||||
|
n = port->receive_packet (packet);
|
||||||
|
if (n == TIMEOUT || n == END)
|
||||||
|
{
|
||||||
|
port->close_port ();
|
||||||
|
fclose (file);
|
||||||
|
emit error (n);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
//end of thread!!!!
|
||||||
|
if (end)
|
||||||
|
{
|
||||||
|
port->send_char (END);
|
||||||
|
port->close_port ();
|
||||||
|
fclose (file);
|
||||||
|
emit error (END);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
data_type = Logic::check_packet (packet);
|
||||||
|
|
||||||
|
if (data_type == NORMAL_DATA || data_type == LAST_DATA)
|
||||||
|
{ /* good packet */
|
||||||
|
page_number = recived / 128; /* each ram page consist of 128 packets */
|
||||||
|
packet_number = recived % 128;
|
||||||
|
retries = 0;
|
||||||
|
|
||||||
|
/* current packet */
|
||||||
|
if (packet_number == packet[3]
|
||||||
|
&& page_number == packet[4] * 256 + packet[5])
|
||||||
|
{
|
||||||
|
memcpy (&data[(packet_number % 32) * 64], &packet[6],
|
||||||
|
FRAMESIZE);
|
||||||
|
if (packet_number % 32 == 31)
|
||||||
|
if (fwrite (data, 1, sizeof data, file) < sizeof data)
|
||||||
|
{
|
||||||
|
port->close_port ();
|
||||||
|
fclose (file);
|
||||||
|
emit error (FILEERROR_W);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
/* if only 2kB RAM, then force end of transmision (send END),
|
||||||
|
* device try to process whole page - 8kB*/
|
||||||
|
if (_2k && recived == 31)
|
||||||
|
{ /*_2k => page_count = 1 */
|
||||||
|
port->send_char (END);
|
||||||
|
port->close_port ();
|
||||||
|
fclose (file);
|
||||||
|
emit error (TRUE);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
port->send_char (ACK);
|
||||||
|
recived++;
|
||||||
|
prv_count = 0;
|
||||||
|
/* set amount of data with _2k flag */
|
||||||
|
emit set_progress (recived + 1, _2k ? 32 : page_count * 128);
|
||||||
|
}
|
||||||
|
else if (((packet_number - 1) % 127) == packet[3])
|
||||||
|
{ /* last packet */
|
||||||
|
if (++prv_count == 10)
|
||||||
|
{
|
||||||
|
port->send_char (END);
|
||||||
|
port->close_port ();
|
||||||
|
fclose (file);
|
||||||
|
emit error (END);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
port->send_char (ACK);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{ /* packet valid but not current */
|
||||||
|
port->send_char (END);
|
||||||
|
port->close_port ();
|
||||||
|
fclose (file);
|
||||||
|
emit error (END);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{ /* bad data or NAK */
|
||||||
|
if (++retries < 10)
|
||||||
|
port->send_char (NAK);
|
||||||
|
else
|
||||||
|
{
|
||||||
|
port->send_char (END);
|
||||||
|
port->close_port ();
|
||||||
|
fclose (file);
|
||||||
|
emit error (END);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
while (data_type != LAST_DATA);
|
||||||
|
|
||||||
|
if (recived * 64 == page_count * 8192)
|
||||||
|
{
|
||||||
|
port->close_port ();
|
||||||
|
fclose (file);
|
||||||
|
emit error (TRUE);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
port->close_port ();
|
||||||
|
fclose (file);
|
||||||
|
emit error (END);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
ReadRamThread::canceled (void)
|
||||||
|
{
|
||||||
|
end = TRUE;
|
||||||
|
}
|
33
ReadRamThread.h
Normal file
33
ReadRamThread.h
Normal file
@ -0,0 +1,33 @@
|
|||||||
|
/*****************************************************************************
|
||||||
|
** ReadRamThread.h
|
||||||
|
** Author: Kraku
|
||||||
|
*****************************************************************************/
|
||||||
|
#ifndef _READRAMTHREAD_H_
|
||||||
|
#define _READRAMTHREAD_H_
|
||||||
|
#include <QThread>
|
||||||
|
#include "AbstractPort.h"
|
||||||
|
#include "Logic.h"
|
||||||
|
|
||||||
|
class ReadRamThread:public QThread
|
||||||
|
{
|
||||||
|
Q_OBJECT public:
|
||||||
|
virtual void run ();
|
||||||
|
ReadRamThread ()
|
||||||
|
{
|
||||||
|
}
|
||||||
|
bool end;
|
||||||
|
FILE *file;
|
||||||
|
char _2k;
|
||||||
|
char mbc;
|
||||||
|
char algorythm;
|
||||||
|
char dap;
|
||||||
|
int page_count;
|
||||||
|
AbstractPort *port;
|
||||||
|
public slots:void canceled (void);
|
||||||
|
|
||||||
|
signals:
|
||||||
|
void set_progress (int ile, int max);
|
||||||
|
void error (int err);
|
||||||
|
};
|
||||||
|
|
||||||
|
#endif
|
173
SerialPort.cpp
Normal file
173
SerialPort.cpp
Normal file
@ -0,0 +1,173 @@
|
|||||||
|
/*****************************************************************************
|
||||||
|
** SerialPort.cpp
|
||||||
|
** Author: Kraku
|
||||||
|
*****************************************************************************/
|
||||||
|
#include "const.h"
|
||||||
|
#include "SerialPort.h"
|
||||||
|
|
||||||
|
extern "C"{
|
||||||
|
#include <time.h>
|
||||||
|
#include <stdio.h>
|
||||||
|
#include <stdlib.h>
|
||||||
|
/*
|
||||||
|
* Header files for RS232C support under Linux
|
||||||
|
*/
|
||||||
|
#include <unistd.h>
|
||||||
|
#include <termios.h>
|
||||||
|
#include <fcntl.h>
|
||||||
|
}
|
||||||
|
|
||||||
|
SerialPort::SerialPort()
|
||||||
|
:AbstractPort()
|
||||||
|
|
||||||
|
{
|
||||||
|
descriptor = -1;
|
||||||
|
/* Descriptor -1 is invalid - something like NULL */
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
bool SerialPort::open_port(QString port_name)
|
||||||
|
{
|
||||||
|
/* Open port in RW mode, don't check DCD line */
|
||||||
|
descriptor = open (port_name.toUtf8(), O_RDWR | O_NOCTTY | O_NDELAY);
|
||||||
|
if (descriptor != -1) /* is port opened */
|
||||||
|
{
|
||||||
|
opened = TRUE;
|
||||||
|
struct termios ts; /* structure describing port */
|
||||||
|
tcgetattr (descriptor, &ts); /* get actual state of port */
|
||||||
|
|
||||||
|
/*
|
||||||
|
* set line settings
|
||||||
|
*/
|
||||||
|
cfsetispeed (&ts, (speed_t)B115200);
|
||||||
|
cfsetospeed (&ts, (speed_t)B115200);
|
||||||
|
ts.c_cflag |= (CLOCAL | CREAD); /* important */
|
||||||
|
ts.c_cflag &= ~PARENB; /* no parity */
|
||||||
|
ts.c_cflag &= ~CSTOPB; /* 1 stop bit */
|
||||||
|
ts.c_cflag &= ~CSIZE;
|
||||||
|
ts.c_cflag |= CS8; /* 8 data bits */
|
||||||
|
|
||||||
|
/*
|
||||||
|
* raw input/output
|
||||||
|
*/
|
||||||
|
ts.c_lflag &= ~(ICANON | ECHO | ECHOE | ISIG);
|
||||||
|
ts.c_iflag &= ~(IXON | IXOFF | IXANY);
|
||||||
|
ts.c_oflag &= ~OPOST;
|
||||||
|
ts.c_iflag &= ~(INLCR | IGNCR | ICRNL);
|
||||||
|
|
||||||
|
/*
|
||||||
|
* set all info
|
||||||
|
*/
|
||||||
|
tcsetattr (descriptor, TCSANOW, &ts);
|
||||||
|
fcntl (descriptor, F_SETFL, FNDELAY); /* don't wait for data while reading */
|
||||||
|
return TRUE;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
return FALSE;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool SerialPort::close_port ()
|
||||||
|
{
|
||||||
|
if (descriptor == -1)
|
||||||
|
return FALSE;
|
||||||
|
else
|
||||||
|
{
|
||||||
|
close (descriptor);
|
||||||
|
opened = FALSE;
|
||||||
|
return TRUE;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
int SerialPort::send_packet(unsigned char packet[PACKETSIZE])
|
||||||
|
{
|
||||||
|
return write (descriptor, packet, PACKETSIZE);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
bool SerialPort::send_char (unsigned char character)
|
||||||
|
{
|
||||||
|
if (write (descriptor, &character, 1))
|
||||||
|
return TRUE;
|
||||||
|
else
|
||||||
|
return FALSE;
|
||||||
|
}
|
||||||
|
|
||||||
|
int SerialPort::receive_char (void)
|
||||||
|
{
|
||||||
|
time_t tp = time (NULL); /* save current time */
|
||||||
|
unsigned char character;
|
||||||
|
int read_count = 0;
|
||||||
|
|
||||||
|
do
|
||||||
|
{
|
||||||
|
read_count = read (descriptor, &character, 1); /* try to read char... */
|
||||||
|
}
|
||||||
|
while (read_count <= 0 && time (NULL) - tp < SLEEPTIME);
|
||||||
|
|
||||||
|
/*
|
||||||
|
* ...until done or SLEEPTIME is over
|
||||||
|
*/
|
||||||
|
if (read_count == 0)
|
||||||
|
return TIMEOUT;
|
||||||
|
|
||||||
|
/* ACK and END are only accepted chars */
|
||||||
|
if (character == ACK || character == END)
|
||||||
|
return character;
|
||||||
|
else
|
||||||
|
return NAK;
|
||||||
|
}
|
||||||
|
|
||||||
|
int SerialPort::receive_packet (unsigned char *packet)
|
||||||
|
{
|
||||||
|
time_t tp = time (NULL);
|
||||||
|
int read_count;
|
||||||
|
|
||||||
|
do
|
||||||
|
{
|
||||||
|
read_count = read (descriptor, packet, 1);
|
||||||
|
}
|
||||||
|
while (read_count <= 0 && time (NULL) - tp < SLEEPTIME);
|
||||||
|
|
||||||
|
if (read_count <= 0)
|
||||||
|
return TIMEOUT;
|
||||||
|
else
|
||||||
|
{
|
||||||
|
if (packet[0] != DATA) /* if it's not a packet, then treat it as char */
|
||||||
|
{
|
||||||
|
if (packet[0] == ACK)
|
||||||
|
return ACK;
|
||||||
|
else if (packet[0] == END)
|
||||||
|
return END;
|
||||||
|
else
|
||||||
|
return NAK;
|
||||||
|
}
|
||||||
|
else /* if packet, read rest of it */
|
||||||
|
{
|
||||||
|
int data_left = PACKETSIZE - 1;
|
||||||
|
tp = time (NULL);
|
||||||
|
|
||||||
|
do
|
||||||
|
{
|
||||||
|
|
||||||
|
/*
|
||||||
|
* read rest of data and put it in packet
|
||||||
|
*/
|
||||||
|
read_count =
|
||||||
|
read (descriptor, &packet[PACKETSIZE - data_left], data_left);
|
||||||
|
if (read_count > 0)
|
||||||
|
{
|
||||||
|
data_left -= read_count;
|
||||||
|
tp = time (NULL); /* reset wait timer */
|
||||||
|
}
|
||||||
|
}
|
||||||
|
while (data_left != 0 && time (NULL) - tp < SLEEPTIME);
|
||||||
|
/*
|
||||||
|
* read until packet is full or time ends
|
||||||
|
*/
|
||||||
|
if (data_left > 0)
|
||||||
|
return TIMEOUT;
|
||||||
|
else
|
||||||
|
return DATA; /* DATA signals read of full packet */
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
30
SerialPort.h
Normal file
30
SerialPort.h
Normal file
@ -0,0 +1,30 @@
|
|||||||
|
/*****************************************************************************
|
||||||
|
** SerialPort.h - SerialPort driver for Linux/Posix based systems
|
||||||
|
** Author: Kraku
|
||||||
|
*****************************************************************************/
|
||||||
|
#ifndef _SERIALPORT_H_
|
||||||
|
#define _SERIALPORT_H_
|
||||||
|
#include "AbstractPort.h"
|
||||||
|
|
||||||
|
class SerialPort:public AbstractPort
|
||||||
|
{
|
||||||
|
Q_OBJECT
|
||||||
|
int descriptor;
|
||||||
|
bool opened;
|
||||||
|
public:
|
||||||
|
SerialPort ();
|
||||||
|
bool open_port (QString port_name);
|
||||||
|
bool close_port ();
|
||||||
|
int receive_char ();
|
||||||
|
bool send_char (unsigned char character);
|
||||||
|
int receive_packet (unsigned char *packet);
|
||||||
|
int send_packet (unsigned char *packet);
|
||||||
|
bool isOpen ()
|
||||||
|
{
|
||||||
|
return opened;
|
||||||
|
}
|
||||||
|
signals:
|
||||||
|
void error (int err);
|
||||||
|
};
|
||||||
|
|
||||||
|
#endif
|
61
SerialPortWin.cpp
Normal file
61
SerialPortWin.cpp
Normal file
@ -0,0 +1,61 @@
|
|||||||
|
/*
|
||||||
|
#include "const.h"
|
||||||
|
#include "AbstractPort.h"
|
||||||
|
#include "SerialPortWin.h"
|
||||||
|
#include "Settings.h"
|
||||||
|
|
||||||
|
extern "C"{
|
||||||
|
#include <time.h>
|
||||||
|
#include <stdio.h>
|
||||||
|
#include <stdlib.h>
|
||||||
|
}
|
||||||
|
|
||||||
|
SerialPortWin::SerialPortWin()
|
||||||
|
:AbstractPort()
|
||||||
|
|
||||||
|
{
|
||||||
|
//hCommDev=NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
bool SerialPortWin::open_port(QString port_name)
|
||||||
|
{
|
||||||
|
|
||||||
|
return FALSE;
|
||||||
|
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
bool SerialPortWin::close_port ()
|
||||||
|
{
|
||||||
|
|
||||||
|
return TRUE;
|
||||||
|
}
|
||||||
|
|
||||||
|
int SerialPortWin::send_packet (unsigned char packet[PACKETSIZE])
|
||||||
|
{
|
||||||
|
return 0;
|
||||||
|
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
bool SerialPortWin::send_char (unsigned char character)
|
||||||
|
{
|
||||||
|
return FALSE;
|
||||||
|
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
int SerialPortWin::receive_char (void)
|
||||||
|
{
|
||||||
|
return 0;
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
int SerialPortWin::receive_packet (unsigned char *packet)
|
||||||
|
{
|
||||||
|
return 0;
|
||||||
|
|
||||||
|
}
|
||||||
|
*/
|
37
SerialPortWin.h
Normal file
37
SerialPortWin.h
Normal file
@ -0,0 +1,37 @@
|
|||||||
|
/*
|
||||||
|
#ifndef _SERIALPORTWIN_H_
|
||||||
|
#define _SERIALPORTWIN_H_
|
||||||
|
#include <windows.h>
|
||||||
|
#include "AbstractPort.h"
|
||||||
|
#include <time.h>
|
||||||
|
|
||||||
|
|
||||||
|
class SerialPortWin : public AbstractPort
|
||||||
|
{
|
||||||
|
Q_OBJECT
|
||||||
|
HANDLE hCommDev;
|
||||||
|
DCB dcb;
|
||||||
|
COMSTAT Stat;
|
||||||
|
DWORD Errors;
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
bool opened;
|
||||||
|
public:
|
||||||
|
SerialPortWin();
|
||||||
|
bool open_port (QString port_name);
|
||||||
|
bool close_port ();
|
||||||
|
int receive_char ();
|
||||||
|
bool send_char (unsigned char character);
|
||||||
|
int receive_packet (unsigned char *packet);
|
||||||
|
int send_packet (unsigned char *packet);
|
||||||
|
bool isOpen()
|
||||||
|
{
|
||||||
|
return opened;
|
||||||
|
}
|
||||||
|
signals:
|
||||||
|
void error(int err);
|
||||||
|
};
|
||||||
|
|
||||||
|
#endif
|
||||||
|
*/
|
320
Settings.cpp
Normal file
320
Settings.cpp
Normal file
@ -0,0 +1,320 @@
|
|||||||
|
/*****************************************************************************
|
||||||
|
** Settings.cpp
|
||||||
|
** Author: Kraku
|
||||||
|
*****************************************************************************/
|
||||||
|
#include <QLabel>
|
||||||
|
#include <QLayout>
|
||||||
|
#include <QComboBox>
|
||||||
|
#include <QMessageBox>
|
||||||
|
#include <QSettings>
|
||||||
|
#include "Settings.h"
|
||||||
|
#include "Gui.h"
|
||||||
|
#include <math.h>
|
||||||
|
|
||||||
|
bool
|
||||||
|
Settings::commanual = FALSE;
|
||||||
|
alg_t
|
||||||
|
Settings::algorythm = ALG16;
|
||||||
|
dap_t
|
||||||
|
Settings::dap = TOGGLE;
|
||||||
|
bool
|
||||||
|
Settings::showbbl = FALSE;
|
||||||
|
speed_type
|
||||||
|
Settings::speed = STANDARD;
|
||||||
|
QThread::Priority Settings::priority = QThread::NormalPriority;
|
||||||
|
|
||||||
|
Settings::Settings (QWidget * parent):QGroupBox (tr ("Settings"), parent)
|
||||||
|
{
|
||||||
|
QSettings
|
||||||
|
set;
|
||||||
|
|
||||||
|
labels = new QVBoxLayout ();
|
||||||
|
combo_boxes = new QVBoxLayout ();
|
||||||
|
down = new QHBoxLayout ();
|
||||||
|
north = new QHBoxLayout ();
|
||||||
|
all = new QVBoxLayout ();
|
||||||
|
|
||||||
|
|
||||||
|
com_label = new QLabel ("PORT:", this);
|
||||||
|
labels->addWidget (com_label);
|
||||||
|
com_combo = new QComboBox (this);
|
||||||
|
combo_boxes->addWidget (com_combo);
|
||||||
|
|
||||||
|
#ifdef Q_WS_X11
|
||||||
|
com_combo->insertItem (0, "/dev/ttyS0");
|
||||||
|
com_combo->insertItem (1, "/dev/ttyS1");
|
||||||
|
com_combo->insertItem (2, "/dev/ttyS2");
|
||||||
|
if (set.contains ("user_com"))
|
||||||
|
{
|
||||||
|
com_combo->insertItem (3, set.value ("user_com").toString ());
|
||||||
|
com_combo->setCurrentIndex (3);
|
||||||
|
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
// /dev/flasher can be symbolic link to device,
|
||||||
|
// if it's connected to some strange port
|
||||||
|
com_combo->insertItem (3, "/dev/flasher");
|
||||||
|
}
|
||||||
|
com_combo->insertItem (4, "USB");
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#ifdef Q_WS_WIN
|
||||||
|
com_combo->insertItem (0, "COM1");
|
||||||
|
com_combo->insertItem (1, "COM2");
|
||||||
|
com_combo->insertItem (2, "COM3");
|
||||||
|
if (set.contains ("user_com"))
|
||||||
|
{
|
||||||
|
com_combo->insertItem (3, set.value ("user_com").toString ());
|
||||||
|
com_combo->setCurrentIndex (3);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
com_combo->insertItem (3, "COM4");
|
||||||
|
}
|
||||||
|
com_combo->insertItem (4, "USB");
|
||||||
|
#endif
|
||||||
|
|
||||||
|
|
||||||
|
mbc_label = new QLabel ("MBC:", this);
|
||||||
|
|
||||||
|
labels->addWidget (mbc_label);
|
||||||
|
mbc_combo = new QComboBox (this);
|
||||||
|
combo_boxes->addWidget (mbc_combo);
|
||||||
|
mbc_combo->insertItem (0, "MBC AUTO");
|
||||||
|
mbc_combo->insertItem (1, "MBC1");
|
||||||
|
mbc_combo->insertItem (2, "MBC2");
|
||||||
|
mbc_combo->insertItem (3, "MBC3");
|
||||||
|
mbc_combo->insertItem (4, "ROM ONLY");
|
||||||
|
mbc_combo->insertItem (5, "MBC5");
|
||||||
|
mbc_combo->insertItem (6, "RUMBLE");
|
||||||
|
|
||||||
|
flash_label = new QLabel ("FLASH:", this);
|
||||||
|
labels->addWidget (flash_label);
|
||||||
|
flash_combo = new QComboBox (this);
|
||||||
|
combo_boxes->addWidget (flash_combo);
|
||||||
|
flash_combo->insertItem (0, "32 KB");
|
||||||
|
flash_combo->insertItem (1, "64 KB");
|
||||||
|
flash_combo->insertItem (2, "128 KB");
|
||||||
|
flash_combo->insertItem (3, "256 KB");
|
||||||
|
flash_combo->insertItem (4, "512 KB");
|
||||||
|
flash_combo->insertItem (5, "1024 KB");
|
||||||
|
flash_combo->insertItem (6, "2048 KB");
|
||||||
|
flash_combo->insertItem (7, "4096 KB");
|
||||||
|
flash_combo->insertItem (8, "8192 KB");
|
||||||
|
flash_combo->setCurrentIndex (4);
|
||||||
|
|
||||||
|
ram_label = new QLabel ("RAM:", this);
|
||||||
|
labels->addWidget (ram_label);
|
||||||
|
ram_combo = new QComboBox (this);
|
||||||
|
combo_boxes->addWidget (ram_combo);
|
||||||
|
ram_combo->insertItem (0, "2 KB");
|
||||||
|
ram_combo->insertItem (1, "8 KB");
|
||||||
|
ram_combo->insertItem (2, "32 KB");
|
||||||
|
ram_combo->insertItem (3, "128 KB");
|
||||||
|
ram_combo->setCurrentIndex (1);
|
||||||
|
|
||||||
|
lang_label = new QLabel (tr ("LANGUAGE:"), this);
|
||||||
|
labels->addWidget (lang_label);
|
||||||
|
lang_combo = new QComboBox (this);
|
||||||
|
combo_boxes->addWidget (lang_combo);
|
||||||
|
get_langs();
|
||||||
|
|
||||||
|
|
||||||
|
auto_check = new QCheckBox (tr ("Check file size"), this);
|
||||||
|
auto_check->setCheckState (Qt::Checked);
|
||||||
|
down->addWidget (auto_check);
|
||||||
|
|
||||||
|
|
||||||
|
north->addLayout (labels);
|
||||||
|
north->addLayout (combo_boxes);
|
||||||
|
all->addLayout (north);
|
||||||
|
all->addLayout (down);
|
||||||
|
setLayout (all);
|
||||||
|
|
||||||
|
auto_size = TRUE;
|
||||||
|
mbc = MBCAUTO;
|
||||||
|
ram_size = 8;
|
||||||
|
flash_size = 512;
|
||||||
|
com_name = com_combo->currentText ();
|
||||||
|
Gui::port_type = SERIAL;
|
||||||
|
|
||||||
|
|
||||||
|
connect (com_combo, SIGNAL (activated (int)), this, SLOT (setCom (int)));
|
||||||
|
connect (mbc_combo, SIGNAL (activated (int)), this, SLOT (setMbc (int)));
|
||||||
|
connect (flash_combo, SIGNAL (activated (int)), this,
|
||||||
|
SLOT (setFlash (int)));
|
||||||
|
connect (ram_combo, SIGNAL (activated (int)), this, SLOT (setRam (int)));
|
||||||
|
connect (lang_combo, SIGNAL (activated (const QString &)), this,
|
||||||
|
SLOT (setLang (const QString &)));
|
||||||
|
connect (auto_check, SIGNAL (stateChanged (int)), this,
|
||||||
|
SLOT (setAuto (int)));
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void
|
||||||
|
Settings::setCom (int index)
|
||||||
|
{
|
||||||
|
com_name = getCom (index);
|
||||||
|
com_combo->setCurrentIndex (index);
|
||||||
|
if (index < PORTS_COUNT)
|
||||||
|
Gui::port_type = SERIAL;
|
||||||
|
else
|
||||||
|
Gui::port_type = USB;
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
Settings::setFlash (int index)
|
||||||
|
{
|
||||||
|
/* size = 32 * 2 ^ index */
|
||||||
|
flash_size = 32 * (int) pow (2.0, (double) index);
|
||||||
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
Settings::setRam (int index)
|
||||||
|
{
|
||||||
|
switch (index)
|
||||||
|
{
|
||||||
|
case 0:
|
||||||
|
ram_size = 2;
|
||||||
|
break;
|
||||||
|
case 1:
|
||||||
|
ram_size = 8;
|
||||||
|
break;
|
||||||
|
case 2:
|
||||||
|
ram_size = 32;
|
||||||
|
break;
|
||||||
|
case 3:
|
||||||
|
ram_size = 128;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
Settings::setMbc (int mbc_nr)
|
||||||
|
{
|
||||||
|
mbc = (mbc_t) mbc_nr;
|
||||||
|
switch (mbc)
|
||||||
|
{
|
||||||
|
case MBCAUTO:
|
||||||
|
ram_types (4);
|
||||||
|
flash_types (8);
|
||||||
|
break;
|
||||||
|
case MBC1:
|
||||||
|
ram_types (3);
|
||||||
|
flash_types (6);
|
||||||
|
break;
|
||||||
|
case MBC2:
|
||||||
|
ram_types (0);
|
||||||
|
flash_types (3);
|
||||||
|
break;
|
||||||
|
case MBC3:
|
||||||
|
ram_types (3);
|
||||||
|
flash_types (6);
|
||||||
|
break;
|
||||||
|
case ROMONLY:
|
||||||
|
ram_types (0);
|
||||||
|
flash_types (0);
|
||||||
|
break;
|
||||||
|
case MBC5:
|
||||||
|
ram_types (4);
|
||||||
|
flash_types (8);
|
||||||
|
break;
|
||||||
|
case RUMBLE:
|
||||||
|
ram_types (3);
|
||||||
|
flash_types (8);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
setFlash (flash_combo->currentIndex ());
|
||||||
|
setRam (ram_combo->currentIndex ());
|
||||||
|
emit refresh_ram_buttons ();
|
||||||
|
}
|
||||||
|
|
||||||
|
//fill ram_combo depending on cart type
|
||||||
|
void
|
||||||
|
Settings::ram_types (int type)
|
||||||
|
{
|
||||||
|
int ile = ram_combo->count ();
|
||||||
|
for (int i = ile - 1; i >= 0; i--)
|
||||||
|
ram_combo->removeItem (i);
|
||||||
|
switch (type)
|
||||||
|
{
|
||||||
|
case 0:
|
||||||
|
break;
|
||||||
|
case 3:
|
||||||
|
ram_combo->insertItem (0, "2 KB");
|
||||||
|
ram_combo->insertItem (1, "8 KB");
|
||||||
|
ram_combo->insertItem (2, "32 KB");
|
||||||
|
break;
|
||||||
|
case 4:
|
||||||
|
ram_combo->insertItem (0, "2 KB");
|
||||||
|
ram_combo->insertItem (1, "8 KB");
|
||||||
|
ram_combo->insertItem (2, "32 KB");
|
||||||
|
ram_combo->insertItem (3, "128 KB");
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
Settings::flash_types (int type)
|
||||||
|
{
|
||||||
|
int ile = flash_combo->count ();
|
||||||
|
for (int i = ile - 1; i >= 0; i--)
|
||||||
|
flash_combo->removeItem (i);
|
||||||
|
|
||||||
|
for (int i = 0; i <= type; i++)
|
||||||
|
{
|
||||||
|
int pojemnosc = 32 * (int) pow (2.0, (double) i);
|
||||||
|
flash_combo->insertItem (i, QString::number (pojemnosc) + " KB");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
Settings::get_langs() {
|
||||||
|
QSettings settings;
|
||||||
|
int selectedIndex = 0;
|
||||||
|
QString selectedLang = settings.value("selected_lang").toString();
|
||||||
|
settings.beginGroup("lang");
|
||||||
|
QStringList keys = settings.childKeys();
|
||||||
|
|
||||||
|
for (int i = 0; i < keys.size(); ++i) {
|
||||||
|
lang_combo->insertItem(i,settings.value(keys.at(i)).toString());
|
||||||
|
if(selectedLang == keys.at(i))
|
||||||
|
selectedIndex = i;
|
||||||
|
}
|
||||||
|
settings.endGroup();
|
||||||
|
lang_combo->setCurrentIndex(selectedIndex);
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
Settings::setLang (const QString & lang)
|
||||||
|
{
|
||||||
|
QSettings settings;
|
||||||
|
settings.beginGroup("lang");
|
||||||
|
QString langFileName = settings.value("selected_lang").toString();
|
||||||
|
QStringList keys = settings.childKeys();
|
||||||
|
for (int i = 0; i < keys.size(); ++i) {
|
||||||
|
if(lang == settings.value(keys.at(i)).toString())
|
||||||
|
langFileName = keys.at(i);
|
||||||
|
}
|
||||||
|
settings.endGroup();
|
||||||
|
settings.setValue ("selected_lang", langFileName);
|
||||||
|
|
||||||
|
QMessageBox::information (this, tr ("Change language"),
|
||||||
|
tr
|
||||||
|
("After program restart language will be changed to: ")
|
||||||
|
+ lang, QMessageBox::Ok);
|
||||||
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
Settings::setAuto (int state)
|
||||||
|
{
|
||||||
|
if (state == Qt::Checked)
|
||||||
|
auto_size = TRUE;
|
||||||
|
else
|
||||||
|
auto_size = FALSE;
|
||||||
|
}
|
107
Settings.h
Normal file
107
Settings.h
Normal file
@ -0,0 +1,107 @@
|
|||||||
|
/*****************************************************************************
|
||||||
|
** Settings.h - configuration widget
|
||||||
|
** Author: Kraku
|
||||||
|
*****************************************************************************/
|
||||||
|
#ifndef _SETTINGS_H_
|
||||||
|
#define _SETTINGS_H_
|
||||||
|
|
||||||
|
#include <QGroupBox>
|
||||||
|
#include <QComboBox>
|
||||||
|
#include <QLabel>
|
||||||
|
#include <QLayout>
|
||||||
|
#include <QString>
|
||||||
|
#include <QCheckBox>
|
||||||
|
#include <QThread>
|
||||||
|
#include "const.h"
|
||||||
|
|
||||||
|
class Settings:public QGroupBox
|
||||||
|
{
|
||||||
|
Q_OBJECT mbc_t mbc;
|
||||||
|
QString com_name;
|
||||||
|
int flash_size;
|
||||||
|
int ram_size;
|
||||||
|
bool auto_size;
|
||||||
|
QComboBox *com_combo;
|
||||||
|
QComboBox *mbc_combo;
|
||||||
|
QComboBox *flash_combo;
|
||||||
|
QComboBox *ram_combo;
|
||||||
|
QComboBox *lang_combo;
|
||||||
|
QLabel *com_label;
|
||||||
|
QLabel *mbc_label;
|
||||||
|
QLabel *flash_label;
|
||||||
|
QLabel *ram_label;
|
||||||
|
QLabel *lang_label;
|
||||||
|
QCheckBox *auto_check;
|
||||||
|
QVBoxLayout *labels, *combo_boxes;
|
||||||
|
QHBoxLayout *north, *down;
|
||||||
|
QVBoxLayout *all;
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
public:
|
||||||
|
static bool commanual;
|
||||||
|
static alg_t algorythm;
|
||||||
|
static dap_t dap;
|
||||||
|
static bool showbbl;
|
||||||
|
static speed_type speed;
|
||||||
|
static QThread::Priority priority;
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
Settings (QWidget * parent = 0);
|
||||||
|
|
||||||
|
int getFlash ()
|
||||||
|
{
|
||||||
|
return flash_size;
|
||||||
|
}
|
||||||
|
|
||||||
|
int getRam ()
|
||||||
|
{
|
||||||
|
return ram_size;
|
||||||
|
}
|
||||||
|
|
||||||
|
QString getCom (void)
|
||||||
|
{
|
||||||
|
return com_name;
|
||||||
|
}
|
||||||
|
|
||||||
|
QString getCom (int index)
|
||||||
|
{
|
||||||
|
return com_combo->itemText (index);
|
||||||
|
}
|
||||||
|
|
||||||
|
mbc_t getMbc ()
|
||||||
|
{
|
||||||
|
if (mbc == MBC5 || mbc == RUMBLE)
|
||||||
|
return MBC5;
|
||||||
|
else
|
||||||
|
return mbc;
|
||||||
|
}
|
||||||
|
bool isAuto ()
|
||||||
|
{
|
||||||
|
return auto_size;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool isRamDisabled ()
|
||||||
|
{
|
||||||
|
|
||||||
|
return (ram_combo->currentText () == "");
|
||||||
|
}
|
||||||
|
|
||||||
|
void ram_types (int type);
|
||||||
|
void flash_types (int type);
|
||||||
|
void get_langs();
|
||||||
|
|
||||||
|
public slots:
|
||||||
|
void setCom (int index);
|
||||||
|
void setMbc (int mbc_nr);
|
||||||
|
void setFlash (int index);
|
||||||
|
void setRam (int index);
|
||||||
|
void setLang (const QString & lang);
|
||||||
|
void setAuto (int state);
|
||||||
|
signals:
|
||||||
|
void refresh_ram_buttons ();
|
||||||
|
|
||||||
|
};
|
||||||
|
|
||||||
|
#endif
|
161
USBPort.cpp
Normal file
161
USBPort.cpp
Normal file
@ -0,0 +1,161 @@
|
|||||||
|
/*****************************************************************************
|
||||||
|
** USBPort.cpp
|
||||||
|
** Author: Kraku
|
||||||
|
*****************************************************************************/
|
||||||
|
#include "const.h"
|
||||||
|
#include "USBPort.h"
|
||||||
|
#include "Settings.h"
|
||||||
|
#include <ftdi.h>
|
||||||
|
#include <iostream>
|
||||||
|
extern "C"
|
||||||
|
{
|
||||||
|
#include <time.h>
|
||||||
|
#include <stdio.h>
|
||||||
|
#include <stdlib.h>
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
USBPort::USBPort ():
|
||||||
|
AbstractPort ()
|
||||||
|
{
|
||||||
|
ftdi_init (&ftdic);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
bool
|
||||||
|
USBPort::open_port (QString /*port_name*/)
|
||||||
|
{
|
||||||
|
if (ftdi_usb_open (&ftdic, 0x0403, 0x6001) < 0)
|
||||||
|
return FALSE;
|
||||||
|
/* choose speed */
|
||||||
|
if (Settings::speed == STANDARD)
|
||||||
|
{
|
||||||
|
if (ftdi_set_baudrate (&ftdic, 185000) < 0)
|
||||||
|
return FALSE;
|
||||||
|
}
|
||||||
|
else if (Settings::speed == LOW)
|
||||||
|
{
|
||||||
|
if (ftdi_set_baudrate (&ftdic, 125000) < 0)
|
||||||
|
return FALSE;
|
||||||
|
}
|
||||||
|
else if (Settings::speed == HIGH)
|
||||||
|
{
|
||||||
|
if (ftdi_set_baudrate (&ftdic, 375000) < 0)
|
||||||
|
return FALSE;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (ftdi_set_latency_timer (&ftdic, 2) < 0)
|
||||||
|
return FALSE;
|
||||||
|
if (ftdi_set_line_property (&ftdic, BITS_8, STOP_BIT_1, NONE) < 0)
|
||||||
|
return FALSE;
|
||||||
|
//if(FT_SetTimeouts(ftHandle,5000,0) != FT_OK)
|
||||||
|
// return FALSE;
|
||||||
|
//if(ftdi_enable_bitbang(&ftdic,0xFF) < 0)
|
||||||
|
// return FALSE;
|
||||||
|
|
||||||
|
return TRUE; /* all ok */
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
bool
|
||||||
|
USBPort::close_port ()
|
||||||
|
{
|
||||||
|
ftdi_usb_close (&ftdic);
|
||||||
|
return TRUE;
|
||||||
|
}
|
||||||
|
|
||||||
|
int
|
||||||
|
USBPort::send_packet (unsigned char packet[PACKETSIZE])
|
||||||
|
{
|
||||||
|
int bytesSent;
|
||||||
|
bytesSent = ftdi_write_data (&ftdic, packet, PACKETSIZE);
|
||||||
|
return bytesSent;
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
bool
|
||||||
|
USBPort::send_char (unsigned char character)
|
||||||
|
{
|
||||||
|
int bytesSent;
|
||||||
|
|
||||||
|
bytesSent = ftdi_write_data (&ftdic, &character, 1);
|
||||||
|
return bytesSent == 1;
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
int
|
||||||
|
USBPort::receive_char (void)
|
||||||
|
{
|
||||||
|
time_t tp = time (NULL);
|
||||||
|
unsigned char character;
|
||||||
|
int bytesReceived = 0;
|
||||||
|
do
|
||||||
|
{
|
||||||
|
bytesReceived = ftdi_read_data (&ftdic, &character, 1);
|
||||||
|
if (bytesReceived != 0)
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
while (time (NULL) - tp < SLEEPTIME);
|
||||||
|
|
||||||
|
if (bytesReceived == 0)
|
||||||
|
return TIMEOUT;
|
||||||
|
if (character == ACK || character == END)
|
||||||
|
return character;
|
||||||
|
else
|
||||||
|
return NAK;
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
int
|
||||||
|
USBPort::receive_packet (unsigned char *packet)
|
||||||
|
{
|
||||||
|
time_t tp = time (NULL);
|
||||||
|
int bytesReceived = 0, bytesLeft;
|
||||||
|
do
|
||||||
|
{
|
||||||
|
bytesReceived = ftdi_read_data (&ftdic, packet, 1);
|
||||||
|
}
|
||||||
|
while (time (NULL) - tp < SLEEPTIME && bytesReceived == 0);
|
||||||
|
if (bytesReceived == 0)
|
||||||
|
return TIMEOUT;
|
||||||
|
else
|
||||||
|
{
|
||||||
|
if (packet[0] != DATA)
|
||||||
|
{
|
||||||
|
if (packet[0] == ACK)
|
||||||
|
return ACK;
|
||||||
|
else if (packet[0] == END)
|
||||||
|
return END;
|
||||||
|
else
|
||||||
|
return NAK;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
unsigned int remaining = PACKETSIZE - 1;
|
||||||
|
tp = time (NULL);
|
||||||
|
bytesReceived = 0;
|
||||||
|
do
|
||||||
|
{
|
||||||
|
bytesLeft = remaining;
|
||||||
|
|
||||||
|
bytesReceived =
|
||||||
|
ftdi_read_data (&ftdic, &packet[PACKETSIZE - remaining],
|
||||||
|
bytesLeft);
|
||||||
|
remaining -= bytesReceived;
|
||||||
|
tp = time (NULL);
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
}
|
||||||
|
while (time (NULL) - tp < SLEEPTIME && remaining != 0);
|
||||||
|
if (remaining > 0)
|
||||||
|
return TIMEOUT;
|
||||||
|
else
|
||||||
|
return DATA;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
35
USBPort.h
Normal file
35
USBPort.h
Normal file
@ -0,0 +1,35 @@
|
|||||||
|
/*****************************************************************************
|
||||||
|
** USBPort.h - USB driver for Linux based on libftdi
|
||||||
|
** Author: Kraku
|
||||||
|
*****************************************************************************/
|
||||||
|
#ifndef _USBPORT_H_
|
||||||
|
#define _USBPORT_H_
|
||||||
|
#include "AbstractPort.h"
|
||||||
|
#include <ftdi.h>
|
||||||
|
#include <time.h>
|
||||||
|
|
||||||
|
|
||||||
|
class USBPort:public AbstractPort
|
||||||
|
{
|
||||||
|
Q_OBJECT
|
||||||
|
struct ftdi_context ftdic;
|
||||||
|
FILE *file;
|
||||||
|
|
||||||
|
bool opened;
|
||||||
|
public:
|
||||||
|
USBPort ();
|
||||||
|
bool open_port (QString port_name);
|
||||||
|
bool close_port ();
|
||||||
|
int receive_char ();
|
||||||
|
bool send_char (unsigned char character);
|
||||||
|
int receive_packet (unsigned char *packet);
|
||||||
|
int send_packet (unsigned char *packet);
|
||||||
|
bool isOpen ()
|
||||||
|
{
|
||||||
|
return opened;
|
||||||
|
}
|
||||||
|
signals:
|
||||||
|
void error (int err);
|
||||||
|
};
|
||||||
|
|
||||||
|
#endif
|
158
USBPortWin.cpp
Normal file
158
USBPortWin.cpp
Normal file
@ -0,0 +1,158 @@
|
|||||||
|
/*
|
||||||
|
#include "const.h"
|
||||||
|
#include "USBPortWin.h"
|
||||||
|
#include "Settings.h"
|
||||||
|
|
||||||
|
extern "C"{
|
||||||
|
#include <time.h>
|
||||||
|
#include <stdio.h>
|
||||||
|
#include <stdlib.h>
|
||||||
|
|
||||||
|
#include <windows.h>
|
||||||
|
}
|
||||||
|
|
||||||
|
USBPortWin::USBPortWin()
|
||||||
|
:AbstractPort()
|
||||||
|
|
||||||
|
{
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
bool USBPortWin::open_port (QString port_name)
|
||||||
|
{
|
||||||
|
if(FT_Open(0,&ftHandle) != FT_OK)
|
||||||
|
return FALSE;
|
||||||
|
|
||||||
|
if(Settings::speed == STANDARD){
|
||||||
|
if(FT_SetBaudRate(ftHandle,185000) != FT_OK)
|
||||||
|
return FALSE;
|
||||||
|
}
|
||||||
|
else if(Settings::speed == LOW){
|
||||||
|
if(FT_SetBaudRate(ftHandle,125000) != FT_OK)
|
||||||
|
return FALSE;
|
||||||
|
}
|
||||||
|
else if(Settings::speed == HIGH){
|
||||||
|
if(FT_SetBaudRate(ftHandle,375000) != FT_OK)
|
||||||
|
return FALSE;
|
||||||
|
}
|
||||||
|
|
||||||
|
if(FT_SetLatencyTimer(ftHandle, 2) != FT_OK)
|
||||||
|
return FALSE;
|
||||||
|
if(FT_SetDataCharacteristics(ftHandle,FT_BITS_8,FT_STOP_BITS_1,FT_PARITY_NONE) != FT_OK)
|
||||||
|
return FALSE;
|
||||||
|
if(FT_SetDataCharacteristics(ftHandle,FT_BITS_8,FT_STOP_BITS_1,FT_PARITY_NONE) != FT_OK)
|
||||||
|
return FALSE;
|
||||||
|
if(FT_SetTimeouts(ftHandle,5000,0) != FT_OK)
|
||||||
|
return FALSE;
|
||||||
|
return TRUE;
|
||||||
|
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
bool USBPortWin::close_port ()
|
||||||
|
{
|
||||||
|
FT_Close(ftHandle);
|
||||||
|
return TRUE;
|
||||||
|
}
|
||||||
|
|
||||||
|
int USBPortWin::send_packet (unsigned char packet[PACKETSIZE])
|
||||||
|
{
|
||||||
|
DWORD sendCount;
|
||||||
|
FT_Write(ftHandle, packet, PACKETSIZE, &sendCount);
|
||||||
|
return sendCount;
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
bool USBPortWin::send_char (unsigned char character)
|
||||||
|
{
|
||||||
|
DWORD sendCount;
|
||||||
|
|
||||||
|
FT_Write(ftHandle, &character, 1, &sendCount);
|
||||||
|
return sendCount;
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
int USBPortWin::receive_char (void)
|
||||||
|
{
|
||||||
|
time_t tp = time(NULL);
|
||||||
|
unsigned char character;
|
||||||
|
DWORD cbInQue = 0;
|
||||||
|
DWORD recivedCount=0;
|
||||||
|
FT_GetQueueStatus(ftHandle,&cbInQue);
|
||||||
|
do
|
||||||
|
{
|
||||||
|
if (cbInQue > 0)
|
||||||
|
FT_Read(ftHandle, &character, 1, &recivedCount);
|
||||||
|
if(recivedCount != 0)
|
||||||
|
break;
|
||||||
|
FT_GetQueueStatus(ftHandle,&cbInQue);
|
||||||
|
}while(time(NULL) - tp < SLEEPTIME);
|
||||||
|
|
||||||
|
if (recivedCount == 0)
|
||||||
|
return TIMEOUT;
|
||||||
|
if(character == ACK || character == END)
|
||||||
|
return character;
|
||||||
|
else
|
||||||
|
return NAK;
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
int USBPortWin::receive_packet (unsigned char *packet)
|
||||||
|
{
|
||||||
|
time_t tp = time(NULL);
|
||||||
|
DWORD recivedCount=0, bytesToReceive;
|
||||||
|
DWORD cbInQue = 0;
|
||||||
|
FT_GetQueueStatus(ftHandle,&cbInQue);
|
||||||
|
do
|
||||||
|
{
|
||||||
|
if (cbInQue > 0)
|
||||||
|
FT_Read(ftHandle, packet, 1, &recivedCount);
|
||||||
|
FT_GetQueueStatus(ftHandle,&cbInQue);
|
||||||
|
} while(time(NULL) - tp < SLEEPTIME && recivedCount == 0);
|
||||||
|
if (recivedCount == 0)
|
||||||
|
return TIMEOUT;
|
||||||
|
else
|
||||||
|
{
|
||||||
|
if(packet[0] != DATA)
|
||||||
|
{
|
||||||
|
if(packet[0] == ACK)
|
||||||
|
return ACK;
|
||||||
|
else if(packet[0] == END)
|
||||||
|
return END;
|
||||||
|
else
|
||||||
|
return NAK;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
unsigned int bytesLeft = PACKETSIZE-1;
|
||||||
|
tp = time(NULL);
|
||||||
|
recivedCount = 0;
|
||||||
|
FT_GetQueueStatus(ftHandle,&cbInQue);
|
||||||
|
do
|
||||||
|
{
|
||||||
|
if (cbInQue > 0)
|
||||||
|
{
|
||||||
|
if (cbInQue > bytesLeft)
|
||||||
|
bytesToReceive = bytesLeft;
|
||||||
|
else
|
||||||
|
bytesToReceive = cbInQue;
|
||||||
|
|
||||||
|
FT_Read(ftHandle, &packet[PACKETSIZE-bytesLeft], bytesToReceive, &recivedCount);
|
||||||
|
bytesLeft -= recivedCount;
|
||||||
|
tp = time(NULL);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
FT_GetQueueStatus(ftHandle,&cbInQue);
|
||||||
|
}while(time(NULL) - tp < SLEEPTIME && bytesLeft != 0);
|
||||||
|
|
||||||
|
if(bytesLeft > 0)
|
||||||
|
return TIMEOUT;
|
||||||
|
else
|
||||||
|
return DATA;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
*/
|
34
USBPortWin.h
Normal file
34
USBPortWin.h
Normal file
@ -0,0 +1,34 @@
|
|||||||
|
/*
|
||||||
|
|
||||||
|
#ifndef _USBPORTWIN_H_
|
||||||
|
#define _USBPORTWIN_H_
|
||||||
|
#include <windows.h>
|
||||||
|
#include "AbstractPort.h"
|
||||||
|
#include <ftd2xx.h>
|
||||||
|
#include <time.h>
|
||||||
|
|
||||||
|
|
||||||
|
class USBPortWin : public AbstractPort
|
||||||
|
{
|
||||||
|
Q_OBJECT
|
||||||
|
FT_HANDLE ftHandle;
|
||||||
|
FT_STATUS ftStatus;
|
||||||
|
bool opened;
|
||||||
|
public:
|
||||||
|
USBPortWin();
|
||||||
|
bool open_port (QString port_name);
|
||||||
|
bool close_port ();
|
||||||
|
int receive_char ();
|
||||||
|
bool send_char (unsigned char character);
|
||||||
|
int receive_packet (unsigned char *packet);
|
||||||
|
int send_packet (unsigned char *packet);
|
||||||
|
bool isOpen()
|
||||||
|
{
|
||||||
|
return opened;
|
||||||
|
}
|
||||||
|
signals:
|
||||||
|
void error(int err);
|
||||||
|
};
|
||||||
|
|
||||||
|
#endif
|
||||||
|
*/
|
149
WriteFlashThread.cpp
Normal file
149
WriteFlashThread.cpp
Normal file
@ -0,0 +1,149 @@
|
|||||||
|
/*****************************************************************************
|
||||||
|
** WriteFlashThread.cpp
|
||||||
|
** Author: Kraku
|
||||||
|
*****************************************************************************/
|
||||||
|
#include "WriteFlashThread.h"
|
||||||
|
#include "Settings.h"
|
||||||
|
#include "Logic.h"
|
||||||
|
#include "const.h"
|
||||||
|
|
||||||
|
|
||||||
|
void
|
||||||
|
WriteFlashThread::run ()
|
||||||
|
{
|
||||||
|
end = FALSE;
|
||||||
|
bool zamykanie = FALSE;
|
||||||
|
|
||||||
|
int character, page_number, packet_number, retries = 0;
|
||||||
|
unsigned char packet[72], data[16384]; /* 16 kB is one page */
|
||||||
|
config_t cfg;
|
||||||
|
cfg.operation = WROM;
|
||||||
|
cfg.mbc = mbc;
|
||||||
|
cfg.algorythm = algorythm;
|
||||||
|
cfg.dap = Settings::dap;
|
||||||
|
cfg.page_count = page_count;
|
||||||
|
|
||||||
|
if (file == NULL)
|
||||||
|
{
|
||||||
|
port->close_port ();
|
||||||
|
emit error (FILEERROR_O);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
do
|
||||||
|
{ /* send start and wait for ACK */
|
||||||
|
if (Logic::send_start_packet (port, cfg) == FALSE)
|
||||||
|
{
|
||||||
|
port->close_port ();
|
||||||
|
fclose (file);
|
||||||
|
emit error (SEND_ERROR);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
character = port->receive_char ();
|
||||||
|
if (character == END || character == TIMEOUT)
|
||||||
|
{
|
||||||
|
port->close_port ();
|
||||||
|
fclose (file);
|
||||||
|
emit error (character);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
while (character != ACK && ++retries < 10); /* repeat 10 times */
|
||||||
|
|
||||||
|
if (retries == 10)
|
||||||
|
{ /* wait time passed */
|
||||||
|
port->close_port ();
|
||||||
|
fclose (file);
|
||||||
|
emit error (TIMEOUT);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
retries = 0;
|
||||||
|
|
||||||
|
/* send rest of data - page after page*/
|
||||||
|
for (page_number = 0; page_number < page_count; page_number++)
|
||||||
|
{
|
||||||
|
packet_number = 0;
|
||||||
|
/* read another page of data */
|
||||||
|
memset (data, 0xff, sizeof data);
|
||||||
|
fread (data, sizeof (char), sizeof (data), file);
|
||||||
|
/* first packet on page */
|
||||||
|
Logic::fill_data_packet (packet, &data[packet_number * 64], NORMAL_DATA,
|
||||||
|
packet_number, page_number);
|
||||||
|
|
||||||
|
do
|
||||||
|
{ /* send packet and wait for ACK */
|
||||||
|
|
||||||
|
//end of thread!!!!
|
||||||
|
if (end)
|
||||||
|
{
|
||||||
|
Logic::fill_data_packet (packet, &data[packet_number * 64],
|
||||||
|
LAST_DATA, packet_number, page_number);
|
||||||
|
zamykanie = TRUE;
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
if (port->send_packet (packet) < PACKETSIZE)
|
||||||
|
{
|
||||||
|
port->close_port ();
|
||||||
|
fclose (file);
|
||||||
|
emit error (SEND_ERROR);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
character = port->receive_char ();
|
||||||
|
if (character == END || character == TIMEOUT)
|
||||||
|
{
|
||||||
|
port->close_port ();
|
||||||
|
fclose (file);
|
||||||
|
emit error (character);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
if (character == ACK)
|
||||||
|
{ /* ACK of packet recive */
|
||||||
|
if (zamykanie)
|
||||||
|
{
|
||||||
|
port->close_port ();
|
||||||
|
fclose (file);
|
||||||
|
emit error (END);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (++packet_number == 256) /* last packet on page */
|
||||||
|
break;
|
||||||
|
retries = 0;
|
||||||
|
/* is it last packet of transmision ? */
|
||||||
|
if (packet_number == 255 && page_number == page_count - 1)
|
||||||
|
Logic::fill_data_packet (packet, &data[packet_number * 64],
|
||||||
|
LAST_DATA, packet_number,
|
||||||
|
page_number);
|
||||||
|
else /* nope, it it ordinary packet */
|
||||||
|
Logic::fill_data_packet (packet, &data[packet_number * 64],
|
||||||
|
NORMAL_DATA, packet_number,
|
||||||
|
page_number);
|
||||||
|
/* update progress */
|
||||||
|
emit set_progress (page_number * 256 + packet_number,
|
||||||
|
page_count * 256 - 1);
|
||||||
|
}
|
||||||
|
/* NAK - bad packet */
|
||||||
|
else if (++retries == 10)
|
||||||
|
{
|
||||||
|
port->close_port ();
|
||||||
|
fclose (file);
|
||||||
|
emit error (END);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
while (1); /* until all page is send and all ACK recived */
|
||||||
|
}
|
||||||
|
|
||||||
|
port->close_port ();
|
||||||
|
fclose (file);
|
||||||
|
emit error (TRUE);
|
||||||
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
WriteFlashThread::canceled (void)
|
||||||
|
{
|
||||||
|
end = TRUE;
|
||||||
|
}
|
32
WriteFlashThread.h
Normal file
32
WriteFlashThread.h
Normal file
@ -0,0 +1,32 @@
|
|||||||
|
/*****************************************************************************
|
||||||
|
** WriteFlashThread.h
|
||||||
|
** Author: Kraku
|
||||||
|
*****************************************************************************/
|
||||||
|
#ifndef _WRITEFLASHTHREAD_H_
|
||||||
|
#define _WRITEFLASHTHREAD_H_
|
||||||
|
#include <QThread>
|
||||||
|
#include "AbstractPort.h"
|
||||||
|
#include "Logic.h"
|
||||||
|
|
||||||
|
class WriteFlashThread:public QThread
|
||||||
|
{
|
||||||
|
Q_OBJECT public:
|
||||||
|
WriteFlashThread ()
|
||||||
|
{
|
||||||
|
}
|
||||||
|
virtual void run ();
|
||||||
|
FILE *file;
|
||||||
|
char mbc;
|
||||||
|
char algorythm;
|
||||||
|
char dap;
|
||||||
|
int page_count;
|
||||||
|
bool end;
|
||||||
|
AbstractPort *port;
|
||||||
|
|
||||||
|
public slots:void canceled (void);
|
||||||
|
signals:
|
||||||
|
void set_progress (int ile, int max);
|
||||||
|
void error (int err);
|
||||||
|
};
|
||||||
|
|
||||||
|
#endif
|
154
WriteRamThread.cpp
Normal file
154
WriteRamThread.cpp
Normal file
@ -0,0 +1,154 @@
|
|||||||
|
/*****************************************************************************
|
||||||
|
** WriteRamThread.cpp
|
||||||
|
** Author: Kraku
|
||||||
|
*****************************************************************************/
|
||||||
|
#include "WriteRamThread.h"
|
||||||
|
#include "Settings.h"
|
||||||
|
#include "Logic.h"
|
||||||
|
#include "const.h"
|
||||||
|
|
||||||
|
|
||||||
|
void
|
||||||
|
WriteRamThread::run ()
|
||||||
|
{
|
||||||
|
end = FALSE;
|
||||||
|
bool closing = FALSE;
|
||||||
|
/* function similar to write_flash */
|
||||||
|
int character, page_number, packet_number, retries = 0;
|
||||||
|
unsigned char packet[72], data[8192];
|
||||||
|
config_t cfg;
|
||||||
|
cfg.operation = WRAM;
|
||||||
|
cfg.mbc = mbc;
|
||||||
|
cfg.algorythm = 0x00;
|
||||||
|
cfg.dap = Settings::dap;
|
||||||
|
if (_2k)
|
||||||
|
page_count = 1;
|
||||||
|
cfg.page_count = page_count;
|
||||||
|
|
||||||
|
|
||||||
|
if (file == NULL)
|
||||||
|
{
|
||||||
|
port->close_port ();
|
||||||
|
emit error (FILEERROR_O);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
do
|
||||||
|
{
|
||||||
|
if (Logic::send_start_packet (port, cfg) == FALSE)
|
||||||
|
{
|
||||||
|
port->close_port ();
|
||||||
|
fclose (file);
|
||||||
|
emit error (SEND_ERROR);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
character = port->receive_char ();
|
||||||
|
if (character == END || character == TIMEOUT)
|
||||||
|
{
|
||||||
|
port->close_port ();
|
||||||
|
fclose (file);
|
||||||
|
emit error (character);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
while (character != ACK && ++retries < 10);
|
||||||
|
|
||||||
|
if (retries == 10)
|
||||||
|
{
|
||||||
|
port->close_port ();
|
||||||
|
emit error (TIMEOUT);
|
||||||
|
fclose (file);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
retries = 0;
|
||||||
|
for (page_number = 0; page_number < page_count; page_number++)
|
||||||
|
{
|
||||||
|
packet_number = 0;
|
||||||
|
memset (data, 0x00, sizeof data);
|
||||||
|
if (_2k) /* if set, read only 2kB - some carts */
|
||||||
|
fread (data, sizeof (char), 2048, file);
|
||||||
|
else
|
||||||
|
fread (data, sizeof (char), sizeof (data), file);
|
||||||
|
|
||||||
|
/* send first packet */
|
||||||
|
Logic::fill_data_packet (packet, &data[packet_number * 64], NORMAL_DATA,
|
||||||
|
packet_number, page_number);
|
||||||
|
|
||||||
|
do
|
||||||
|
{ /* send packet and wait for ack */
|
||||||
|
if (end)
|
||||||
|
{
|
||||||
|
Logic::fill_data_packet (packet, &data[packet_number * 64],
|
||||||
|
LAST_DATA, packet_number, page_number);
|
||||||
|
closing = TRUE;
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
if (port->send_packet (packet) < PACKETSIZE)
|
||||||
|
{
|
||||||
|
port->close_port ();
|
||||||
|
fclose (file);
|
||||||
|
emit error (SEND_ERROR);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
character = port->receive_char ();
|
||||||
|
if (character == END || character == TIMEOUT)
|
||||||
|
{
|
||||||
|
port->close_port ();
|
||||||
|
fclose (file);
|
||||||
|
emit error (character);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
if (character == ACK)
|
||||||
|
{
|
||||||
|
if (closing)
|
||||||
|
{
|
||||||
|
port->close_port ();
|
||||||
|
fclose (file);
|
||||||
|
emit error (END);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
if (_2k == 1 && packet_number == 31)
|
||||||
|
{
|
||||||
|
port->close_port ();
|
||||||
|
fclose (file);
|
||||||
|
emit error (TRUE);
|
||||||
|
return; /* end of 2kB page */
|
||||||
|
}
|
||||||
|
if (++packet_number == 128)
|
||||||
|
break;
|
||||||
|
retries = 0;
|
||||||
|
if ((packet_number == 127 && page_number == page_count - 1)
|
||||||
|
|| (_2k && packet_number == 31))
|
||||||
|
Logic::fill_data_packet (packet, &data[packet_number * 64],
|
||||||
|
LAST_DATA, packet_number,
|
||||||
|
page_number);
|
||||||
|
else
|
||||||
|
Logic::fill_data_packet (packet, &data[packet_number * 64],
|
||||||
|
NORMAL_DATA, packet_number,
|
||||||
|
page_number);
|
||||||
|
emit set_progress (page_number * 128 + packet_number + 1,
|
||||||
|
_2k ? 32 : page_count * 128);
|
||||||
|
}
|
||||||
|
else if (++retries == 10)
|
||||||
|
{
|
||||||
|
port->close_port ();
|
||||||
|
fclose (file);
|
||||||
|
emit error (END);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
while (1);
|
||||||
|
}
|
||||||
|
|
||||||
|
port->close_port ();
|
||||||
|
fclose (file);
|
||||||
|
emit error (TRUE);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
WriteRamThread::canceled (void)
|
||||||
|
{
|
||||||
|
end = TRUE;
|
||||||
|
}
|
32
WriteRamThread.h
Normal file
32
WriteRamThread.h
Normal file
@ -0,0 +1,32 @@
|
|||||||
|
/*****************************************************************************
|
||||||
|
** WriteRamThread.h
|
||||||
|
** Author: Kraku
|
||||||
|
*****************************************************************************/
|
||||||
|
#ifndef _WRITERAMTHREAD_H_
|
||||||
|
#define _WRITERAMTHREAD_H_
|
||||||
|
#include <QThread>
|
||||||
|
#include "AbstractPort.h"
|
||||||
|
#include "Logic.h"
|
||||||
|
|
||||||
|
class WriteRamThread:public QThread
|
||||||
|
{
|
||||||
|
Q_OBJECT public:
|
||||||
|
WriteRamThread ()
|
||||||
|
{
|
||||||
|
}
|
||||||
|
virtual void run ();
|
||||||
|
FILE *file;
|
||||||
|
char mbc;
|
||||||
|
char algorythm;
|
||||||
|
char dap;
|
||||||
|
int page_count;
|
||||||
|
bool end;
|
||||||
|
AbstractPort *port;
|
||||||
|
char _2k;
|
||||||
|
public slots:void canceled (void);
|
||||||
|
signals:
|
||||||
|
void set_progress (int ile, int max);
|
||||||
|
void error (int err);
|
||||||
|
};
|
||||||
|
|
||||||
|
#endif
|
79
const.h
Normal file
79
const.h
Normal file
@ -0,0 +1,79 @@
|
|||||||
|
/*****************************************************************************
|
||||||
|
** const.h - definitions of constants used in program
|
||||||
|
** Author: Kraku
|
||||||
|
*****************************************************************************/
|
||||||
|
#ifndef _CONST_H_
|
||||||
|
#define _CONST_H_
|
||||||
|
|
||||||
|
/* control characters */
|
||||||
|
enum cchars
|
||||||
|
{ ACK = 0xAA, NAK = 0xF0, END = 0x0F, DATA = 0x55 };
|
||||||
|
|
||||||
|
#define SLEEPTIME 3 /* time to wait for connection in sec. */
|
||||||
|
#define DELTIME 60 /* time to wait for delete in sec. */
|
||||||
|
#define PACKETSIZE 72
|
||||||
|
#define FRAMESIZE 64
|
||||||
|
#define AUTOSIZE -1
|
||||||
|
#define PORTS_COUNT 4
|
||||||
|
#define VER "1.1"
|
||||||
|
|
||||||
|
#define USB 0
|
||||||
|
#define SERIAL 1
|
||||||
|
|
||||||
|
|
||||||
|
#define TRUE 1
|
||||||
|
#define FALSE 0
|
||||||
|
|
||||||
|
/* strings for version information */
|
||||||
|
#ifdef Q_WS_X11
|
||||||
|
#define SYSTEM "LINUX"
|
||||||
|
#define DEVELOPED "GCC 11.4.1 + QT 5.15.3"
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#ifdef Q_WS_WIN
|
||||||
|
#define SYSTEM "WINDOWS"
|
||||||
|
#define DEVELOPED "Dev-C++ 4.9.9.2 + QT 4.3.2"
|
||||||
|
#endif
|
||||||
|
|
||||||
|
/* return values and errors */
|
||||||
|
enum error_tt
|
||||||
|
{ TIMEOUT = -1, FILEERROR_O = -2, FILEERROR_W = -3, FILEERROR_R =
|
||||||
|
-4, SEND_ERROR = -5,
|
||||||
|
BAD_PACKET = -6, BAD_PARAMS = -7, PORT_ERROR = -8, WRONG_SIZE = -9
|
||||||
|
};
|
||||||
|
|
||||||
|
/* packet types */
|
||||||
|
#define CONFIG 0x00
|
||||||
|
#define NORMAL_DATA 0x01
|
||||||
|
#define LAST_DATA 0x02
|
||||||
|
#define ERASE 0x03
|
||||||
|
#define STATUS 0x04
|
||||||
|
|
||||||
|
#define RESERVED 0x00
|
||||||
|
#define NREAD_ID 0x00
|
||||||
|
#define READ_ID 0x01
|
||||||
|
|
||||||
|
/* operations */
|
||||||
|
#define RROM 0x00
|
||||||
|
#define RRAM 0x01
|
||||||
|
#define WROM 0x02
|
||||||
|
#define WRAM 0x03
|
||||||
|
#define EFLA 0x00
|
||||||
|
#define ERAM 0x01
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
enum alg_t
|
||||||
|
{ ALG16 = 0x00, ALG12 = 0x01 };
|
||||||
|
enum dap_t
|
||||||
|
{ LONGER = 0x00, DEFAULT = 0x01, DATAPOLL = 0x02, TOGGLE = 0x03 };
|
||||||
|
enum speed_type
|
||||||
|
{ LOW = 0x00, STANDARD = 0x01, HIGH = 0x02 };
|
||||||
|
|
||||||
|
/* MBC types */
|
||||||
|
enum mbc_t
|
||||||
|
{ MBCAUTO = 0x00, MBC1 = 0x01, MBC2 = 0x02, MBC3 = 0x03,
|
||||||
|
ROMONLY = 0x04, MBC5 = 0x05, RUMBLE = 0x06
|
||||||
|
};
|
||||||
|
|
||||||
|
#endif
|
10600
flasher.xpm
Normal file
10600
flasher.xpm
Normal file
File diff suppressed because it is too large
Load Diff
123
gbcflsh.cpp
Normal file
123
gbcflsh.cpp
Normal file
@ -0,0 +1,123 @@
|
|||||||
|
/*****************************************************************************
|
||||||
|
** gbcflsh.cpp - Main source file, starts application, parse args
|
||||||
|
** and load translation files
|
||||||
|
** Author: Kraku
|
||||||
|
*****************************************************************************/
|
||||||
|
#include <QApplication>
|
||||||
|
#include <QTranslator>
|
||||||
|
#include <QSettings>
|
||||||
|
#include <QTimer>
|
||||||
|
#include <QTextCodec>
|
||||||
|
#include <QMessageBox>
|
||||||
|
#include "Gui.h"
|
||||||
|
#include "const.h"
|
||||||
|
#include "Settings.h"
|
||||||
|
#include <stdio.h>
|
||||||
|
#include <iostream>
|
||||||
|
|
||||||
|
void
|
||||||
|
parse_params (int /*argc*/, char *argv[])
|
||||||
|
{
|
||||||
|
while (*++argv)
|
||||||
|
{
|
||||||
|
/* disable auto com search in windows */
|
||||||
|
if (strcmp (*argv, "-commanual") == 0)
|
||||||
|
Settings::commanual = TRUE;
|
||||||
|
/* additional communication params */
|
||||||
|
if (strcmp (*argv, "-12bit") == 0)
|
||||||
|
Settings::algorythm = ALG12;
|
||||||
|
if (strcmp (*argv, "-longer") == 0)
|
||||||
|
Settings::dap = LONGER;
|
||||||
|
if (strcmp (*argv, "-default") == 0)
|
||||||
|
Settings::dap = DEFAULT;
|
||||||
|
if (strcmp (*argv, "-datapoll") == 0)
|
||||||
|
Settings::dap = DATAPOLL;
|
||||||
|
if (strcmp (*argv, "-showbbl") == 0)
|
||||||
|
Settings::showbbl = TRUE;
|
||||||
|
/*
|
||||||
|
* USB speed LOW 125000bps HI 375000
|
||||||
|
*/
|
||||||
|
if (strcmp (*argv, "-lowspeed") == 0)
|
||||||
|
Settings::speed = LOW;
|
||||||
|
if (strcmp (*argv, "-highspeed") == 0)
|
||||||
|
Settings::speed = HIGH;
|
||||||
|
/*
|
||||||
|
* communication threads prioryty are used when communication
|
||||||
|
* or gui is freezing
|
||||||
|
*/
|
||||||
|
if ((*argv)[0] == '-' && isdigit ((*argv)[1]) && (*argv)[1] >= '0'
|
||||||
|
&& (*argv)[1] <= '7')
|
||||||
|
{
|
||||||
|
switch ((*argv)[1] - '0')
|
||||||
|
{
|
||||||
|
case 0:
|
||||||
|
Settings::priority = QThread::IdlePriority;
|
||||||
|
break;
|
||||||
|
case 1:
|
||||||
|
Settings::priority = QThread::LowestPriority;
|
||||||
|
break;
|
||||||
|
case 2:
|
||||||
|
Settings::priority = QThread::LowPriority;
|
||||||
|
break;
|
||||||
|
case 3:
|
||||||
|
Settings::priority = QThread::NormalPriority;
|
||||||
|
break;
|
||||||
|
case 4:
|
||||||
|
Settings::priority = QThread::HighPriority;
|
||||||
|
break;
|
||||||
|
case 5:
|
||||||
|
Settings::priority = QThread::HighestPriority;
|
||||||
|
break;
|
||||||
|
case 6:
|
||||||
|
Settings::priority = QThread::TimeCriticalPriority;
|
||||||
|
break;
|
||||||
|
case 7:
|
||||||
|
Settings::priority = QThread::InheritPriority;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
int
|
||||||
|
main (int argc, char *argv[])
|
||||||
|
{
|
||||||
|
parse_params (argc, argv);
|
||||||
|
QApplication app (argc, argv);
|
||||||
|
/*
|
||||||
|
* Organization and aplication names are used for naming settings
|
||||||
|
* file/directory in Linux def. ~/.config/GBCFProject/GameBoyCartFlasher.conf
|
||||||
|
* registry keys in Windows
|
||||||
|
* def. HKEY_CURRENT_USER\Software\GBCFProject/GameBoyCartFlasher.conf
|
||||||
|
*/
|
||||||
|
QCoreApplication::setOrganizationName ("GBCFProject");
|
||||||
|
QCoreApplication::setApplicationName ("GameBoyCartFlasher");
|
||||||
|
QSettings settings;
|
||||||
|
/*
|
||||||
|
* Default language for application is English. It can be canged with
|
||||||
|
* files containing compiled QT translations. All files have same naming
|
||||||
|
* convention gbcflsh_langname.qm i.e. gbcflsh_polish.qm. Program knows
|
||||||
|
* about them, thanks to [lang] group in settings file/registry. Every lang
|
||||||
|
* is represented as single setting i.e. polish=Polski. This record contains
|
||||||
|
* pair of key=value, where value is name of lang shown in ComboBox and key
|
||||||
|
* is langname in filename. Lang selected with ComboBox is saved in
|
||||||
|
* selected_lang record as langname.
|
||||||
|
*/
|
||||||
|
//QTextCodec::setCodecForTr (QTextCodec::codecForName ("UTF-8"));
|
||||||
|
QString langName = settings.value("selected_lang").toString ();
|
||||||
|
QString langPath = settings.value("lang_path").toString();
|
||||||
|
if(langPath == "")
|
||||||
|
langPath = "./";
|
||||||
|
QTranslator translator;
|
||||||
|
translator.load ( "gbcflsh_" + langName,langPath);
|
||||||
|
app.installTranslator (&translator);
|
||||||
|
|
||||||
|
Gui window;
|
||||||
|
window.show ();
|
||||||
|
#ifdef Q_WS_WIN
|
||||||
|
window.startup_info();
|
||||||
|
#endif
|
||||||
|
return app.exec ();
|
||||||
|
}
|
54
gbcflsh_1.1.pro
Normal file
54
gbcflsh_1.1.pro
Normal file
@ -0,0 +1,54 @@
|
|||||||
|
QT += core gui
|
||||||
|
|
||||||
|
greaterThan(QT_MAJOR_VERSION, 4): QT += widgets
|
||||||
|
|
||||||
|
CONFIG += c++11
|
||||||
|
|
||||||
|
# You can make your code fail to compile if it uses deprecated APIs.
|
||||||
|
# In order to do so, uncomment the following line.
|
||||||
|
#DEFINES += QT_DISABLE_DEPRECATED_BEFORE=0x060000 # disables all the APIs deprecated before Qt 6.0.0
|
||||||
|
|
||||||
|
SOURCES += \
|
||||||
|
About.cpp \
|
||||||
|
EraseThread.cpp \
|
||||||
|
Gui.cpp \
|
||||||
|
Logic.cpp \
|
||||||
|
ReadFlashThread.cpp \
|
||||||
|
ReadRamThread.cpp \
|
||||||
|
SerialPort.cpp \
|
||||||
|
SerialPortWin.cpp \
|
||||||
|
Settings.cpp \
|
||||||
|
USBPort.cpp \
|
||||||
|
USBPortWin.cpp \
|
||||||
|
WriteFlashThread.cpp \
|
||||||
|
WriteRamThread.cpp \
|
||||||
|
gbcflsh.cpp
|
||||||
|
|
||||||
|
HEADERS += \
|
||||||
|
About.h \
|
||||||
|
AbstractPort.h \
|
||||||
|
Console.h \
|
||||||
|
EraseThread.h \
|
||||||
|
Gui.h \
|
||||||
|
Logic.h \
|
||||||
|
ReadFlashThread.h \
|
||||||
|
ReadRamThread.h \
|
||||||
|
SerialPort.h \
|
||||||
|
SerialPortWin.h \
|
||||||
|
Settings.h \
|
||||||
|
USBPort.h \
|
||||||
|
USBPortWin.h \
|
||||||
|
WriteFlashThread.h \
|
||||||
|
WriteRamThread.h \
|
||||||
|
const.h
|
||||||
|
|
||||||
|
FORMS +=
|
||||||
|
|
||||||
|
LIBS += -lftdi
|
||||||
|
|
||||||
|
DEFINES += Q_WS_X11=1
|
||||||
|
# Default rules for deployment.
|
||||||
|
qnx: target.path = /tmp/$${TARGET}/bin
|
||||||
|
else: unix:!android: target.path = /opt/$${TARGET}/bin
|
||||||
|
!isEmpty(target.path): INSTALLS += target
|
||||||
|
|
263
gbcflsh_1.1.pro.user
Normal file
263
gbcflsh_1.1.pro.user
Normal file
@ -0,0 +1,263 @@
|
|||||||
|
<?xml version="1.0" encoding="UTF-8"?>
|
||||||
|
<!DOCTYPE QtCreatorProject>
|
||||||
|
<!-- Written by QtCreator 6.0.2, 2023-12-28T13:34:34. -->
|
||||||
|
<qtcreator>
|
||||||
|
<data>
|
||||||
|
<variable>EnvironmentId</variable>
|
||||||
|
<value type="QByteArray">{fe6a0c16-8c7a-4d97-8241-f89b2320f9ae}</value>
|
||||||
|
</data>
|
||||||
|
<data>
|
||||||
|
<variable>ProjectExplorer.Project.ActiveTarget</variable>
|
||||||
|
<value type="int">0</value>
|
||||||
|
</data>
|
||||||
|
<data>
|
||||||
|
<variable>ProjectExplorer.Project.EditorSettings</variable>
|
||||||
|
<valuemap type="QVariantMap">
|
||||||
|
<value type="bool" key="EditorConfiguration.AutoIndent">true</value>
|
||||||
|
<value type="bool" key="EditorConfiguration.AutoSpacesForTabs">false</value>
|
||||||
|
<value type="bool" key="EditorConfiguration.CamelCaseNavigation">true</value>
|
||||||
|
<valuemap type="QVariantMap" key="EditorConfiguration.CodeStyle.0">
|
||||||
|
<value type="QString" key="language">Cpp</value>
|
||||||
|
<valuemap type="QVariantMap" key="value">
|
||||||
|
<value type="QByteArray" key="CurrentPreferences">CppGlobal</value>
|
||||||
|
</valuemap>
|
||||||
|
</valuemap>
|
||||||
|
<valuemap type="QVariantMap" key="EditorConfiguration.CodeStyle.1">
|
||||||
|
<value type="QString" key="language">QmlJS</value>
|
||||||
|
<valuemap type="QVariantMap" key="value">
|
||||||
|
<value type="QByteArray" key="CurrentPreferences">QmlJSGlobal</value>
|
||||||
|
</valuemap>
|
||||||
|
</valuemap>
|
||||||
|
<value type="int" key="EditorConfiguration.CodeStyle.Count">2</value>
|
||||||
|
<value type="QByteArray" key="EditorConfiguration.Codec">UTF-8</value>
|
||||||
|
<value type="bool" key="EditorConfiguration.ConstrainTooltips">false</value>
|
||||||
|
<value type="int" key="EditorConfiguration.IndentSize">4</value>
|
||||||
|
<value type="bool" key="EditorConfiguration.KeyboardTooltips">false</value>
|
||||||
|
<value type="int" key="EditorConfiguration.MarginColumn">80</value>
|
||||||
|
<value type="bool" key="EditorConfiguration.MouseHiding">true</value>
|
||||||
|
<value type="bool" key="EditorConfiguration.MouseNavigation">true</value>
|
||||||
|
<value type="int" key="EditorConfiguration.PaddingMode">1</value>
|
||||||
|
<value type="bool" key="EditorConfiguration.PreferSingleLineComments">false</value>
|
||||||
|
<value type="bool" key="EditorConfiguration.ScrollWheelZooming">true</value>
|
||||||
|
<value type="bool" key="EditorConfiguration.ShowMargin">false</value>
|
||||||
|
<value type="int" key="EditorConfiguration.SmartBackspaceBehavior">0</value>
|
||||||
|
<value type="bool" key="EditorConfiguration.SmartSelectionChanging">true</value>
|
||||||
|
<value type="bool" key="EditorConfiguration.SpacesForTabs">true</value>
|
||||||
|
<value type="int" key="EditorConfiguration.TabKeyBehavior">0</value>
|
||||||
|
<value type="int" key="EditorConfiguration.TabSize">8</value>
|
||||||
|
<value type="bool" key="EditorConfiguration.UseGlobal">true</value>
|
||||||
|
<value type="bool" key="EditorConfiguration.UseIndenter">false</value>
|
||||||
|
<value type="int" key="EditorConfiguration.Utf8BomBehavior">1</value>
|
||||||
|
<value type="bool" key="EditorConfiguration.addFinalNewLine">true</value>
|
||||||
|
<value type="bool" key="EditorConfiguration.cleanIndentation">true</value>
|
||||||
|
<value type="bool" key="EditorConfiguration.cleanWhitespace">true</value>
|
||||||
|
<value type="QString" key="EditorConfiguration.ignoreFileTypes">*.md, *.MD, Makefile</value>
|
||||||
|
<value type="bool" key="EditorConfiguration.inEntireDocument">false</value>
|
||||||
|
<value type="bool" key="EditorConfiguration.skipTrailingWhitespace">true</value>
|
||||||
|
</valuemap>
|
||||||
|
</data>
|
||||||
|
<data>
|
||||||
|
<variable>ProjectExplorer.Project.PluginSettings</variable>
|
||||||
|
<valuemap type="QVariantMap">
|
||||||
|
<valuemap type="QVariantMap" key="AutoTest.ActiveFrameworks">
|
||||||
|
<value type="bool" key="AutoTest.Framework.Boost">true</value>
|
||||||
|
<value type="bool" key="AutoTest.Framework.CTest">false</value>
|
||||||
|
<value type="bool" key="AutoTest.Framework.Catch">true</value>
|
||||||
|
<value type="bool" key="AutoTest.Framework.GTest">true</value>
|
||||||
|
<value type="bool" key="AutoTest.Framework.QtQuickTest">true</value>
|
||||||
|
<value type="bool" key="AutoTest.Framework.QtTest">true</value>
|
||||||
|
</valuemap>
|
||||||
|
<valuemap type="QVariantMap" key="AutoTest.CheckStates"/>
|
||||||
|
<value type="int" key="AutoTest.RunAfterBuild">0</value>
|
||||||
|
<value type="bool" key="AutoTest.UseGlobal">true</value>
|
||||||
|
<valuelist type="QVariantList" key="ClangCodeModel.CustomCommandLineKey"/>
|
||||||
|
<value type="bool" key="ClangCodeModel.UseGlobalConfig">true</value>
|
||||||
|
<value type="QString" key="ClangCodeModel.WarningConfigId">Builtin.BuildSystem</value>
|
||||||
|
<valuemap type="QVariantMap" key="ClangTools">
|
||||||
|
<value type="bool" key="ClangTools.AnalyzeOpenFiles">true</value>
|
||||||
|
<value type="bool" key="ClangTools.BuildBeforeAnalysis">true</value>
|
||||||
|
<value type="QString" key="ClangTools.DiagnosticConfig">Builtin.DefaultTidyAndClazy</value>
|
||||||
|
<value type="int" key="ClangTools.ParallelJobs">6</value>
|
||||||
|
<valuelist type="QVariantList" key="ClangTools.SelectedDirs"/>
|
||||||
|
<valuelist type="QVariantList" key="ClangTools.SelectedFiles"/>
|
||||||
|
<valuelist type="QVariantList" key="ClangTools.SuppressedDiagnostics"/>
|
||||||
|
<value type="bool" key="ClangTools.UseGlobalSettings">true</value>
|
||||||
|
</valuemap>
|
||||||
|
</valuemap>
|
||||||
|
</data>
|
||||||
|
<data>
|
||||||
|
<variable>ProjectExplorer.Project.Target.0</variable>
|
||||||
|
<valuemap type="QVariantMap">
|
||||||
|
<value type="QString" key="DeviceType">Desktop</value>
|
||||||
|
<value type="QString" key="ProjectExplorer.ProjectConfiguration.DefaultDisplayName">Desktop</value>
|
||||||
|
<value type="QString" key="ProjectExplorer.ProjectConfiguration.DisplayName">Desktop</value>
|
||||||
|
<value type="QString" key="ProjectExplorer.ProjectConfiguration.Id">{8c52ab2b-8dea-4a85-a5bb-94aecabf912c}</value>
|
||||||
|
<value type="int" key="ProjectExplorer.Target.ActiveBuildConfiguration">0</value>
|
||||||
|
<value type="int" key="ProjectExplorer.Target.ActiveDeployConfiguration">0</value>
|
||||||
|
<value type="int" key="ProjectExplorer.Target.ActiveRunConfiguration">0</value>
|
||||||
|
<valuemap type="QVariantMap" key="ProjectExplorer.Target.BuildConfiguration.0">
|
||||||
|
<value type="int" key="EnableQmlDebugging">0</value>
|
||||||
|
<value type="QString" key="ProjectExplorer.BuildConfiguration.BuildDirectory">/home/m0rph3us1987/build-QTDemo-Desktop-Debug</value>
|
||||||
|
<value type="QString" key="ProjectExplorer.BuildConfiguration.BuildDirectory.shadowDir">/home/m0rph3us1987/build-QTDemo-Desktop-Debug</value>
|
||||||
|
<valuemap type="QVariantMap" key="ProjectExplorer.BuildConfiguration.BuildStepList.0">
|
||||||
|
<valuemap type="QVariantMap" key="ProjectExplorer.BuildStepList.Step.0">
|
||||||
|
<value type="bool" key="ProjectExplorer.BuildStep.Enabled">true</value>
|
||||||
|
<value type="QString" key="ProjectExplorer.ProjectConfiguration.Id">QtProjectManager.QMakeBuildStep</value>
|
||||||
|
<value type="bool" key="QtProjectManager.QMakeBuildStep.QMakeForced">false</value>
|
||||||
|
<valuelist type="QVariantList" key="QtProjectManager.QMakeBuildStep.SelectedAbis"/>
|
||||||
|
</valuemap>
|
||||||
|
<valuemap type="QVariantMap" key="ProjectExplorer.BuildStepList.Step.1">
|
||||||
|
<value type="bool" key="ProjectExplorer.BuildStep.Enabled">true</value>
|
||||||
|
<value type="QString" key="ProjectExplorer.ProjectConfiguration.Id">Qt4ProjectManager.MakeStep</value>
|
||||||
|
</valuemap>
|
||||||
|
<value type="int" key="ProjectExplorer.BuildStepList.StepsCount">2</value>
|
||||||
|
<value type="QString" key="ProjectExplorer.ProjectConfiguration.DefaultDisplayName">Build</value>
|
||||||
|
<value type="QString" key="ProjectExplorer.ProjectConfiguration.DisplayName">Build</value>
|
||||||
|
<value type="QString" key="ProjectExplorer.ProjectConfiguration.Id">ProjectExplorer.BuildSteps.Build</value>
|
||||||
|
</valuemap>
|
||||||
|
<valuemap type="QVariantMap" key="ProjectExplorer.BuildConfiguration.BuildStepList.1">
|
||||||
|
<valuemap type="QVariantMap" key="ProjectExplorer.BuildStepList.Step.0">
|
||||||
|
<value type="bool" key="ProjectExplorer.BuildStep.Enabled">true</value>
|
||||||
|
<value type="QString" key="ProjectExplorer.ProjectConfiguration.Id">Qt4ProjectManager.MakeStep</value>
|
||||||
|
<value type="QString" key="Qt4ProjectManager.MakeStep.MakeArguments">clean</value>
|
||||||
|
</valuemap>
|
||||||
|
<value type="int" key="ProjectExplorer.BuildStepList.StepsCount">1</value>
|
||||||
|
<value type="QString" key="ProjectExplorer.ProjectConfiguration.DefaultDisplayName">Clean</value>
|
||||||
|
<value type="QString" key="ProjectExplorer.ProjectConfiguration.DisplayName">Clean</value>
|
||||||
|
<value type="QString" key="ProjectExplorer.ProjectConfiguration.Id">ProjectExplorer.BuildSteps.Clean</value>
|
||||||
|
</valuemap>
|
||||||
|
<value type="int" key="ProjectExplorer.BuildConfiguration.BuildStepListCount">2</value>
|
||||||
|
<value type="bool" key="ProjectExplorer.BuildConfiguration.ClearSystemEnvironment">false</value>
|
||||||
|
<valuelist type="QVariantList" key="ProjectExplorer.BuildConfiguration.CustomParsers"/>
|
||||||
|
<value type="bool" key="ProjectExplorer.BuildConfiguration.ParseStandardOutput">false</value>
|
||||||
|
<valuelist type="QVariantList" key="ProjectExplorer.BuildConfiguration.UserEnvironmentChanges"/>
|
||||||
|
<value type="QString" key="ProjectExplorer.ProjectConfiguration.DisplayName">Debug</value>
|
||||||
|
<value type="QString" key="ProjectExplorer.ProjectConfiguration.Id">Qt4ProjectManager.Qt4BuildConfiguration</value>
|
||||||
|
<value type="int" key="Qt4ProjectManager.Qt4BuildConfiguration.BuildConfiguration">2</value>
|
||||||
|
</valuemap>
|
||||||
|
<valuemap type="QVariantMap" key="ProjectExplorer.Target.BuildConfiguration.1">
|
||||||
|
<value type="QString" key="ProjectExplorer.BuildConfiguration.BuildDirectory">/home/m0rph3us1987/build-QTDemo-Desktop-Release</value>
|
||||||
|
<value type="QString" key="ProjectExplorer.BuildConfiguration.BuildDirectory.shadowDir">/home/m0rph3us1987/build-QTDemo-Desktop-Release</value>
|
||||||
|
<valuemap type="QVariantMap" key="ProjectExplorer.BuildConfiguration.BuildStepList.0">
|
||||||
|
<valuemap type="QVariantMap" key="ProjectExplorer.BuildStepList.Step.0">
|
||||||
|
<value type="bool" key="ProjectExplorer.BuildStep.Enabled">true</value>
|
||||||
|
<value type="QString" key="ProjectExplorer.ProjectConfiguration.Id">QtProjectManager.QMakeBuildStep</value>
|
||||||
|
<value type="bool" key="QtProjectManager.QMakeBuildStep.QMakeForced">false</value>
|
||||||
|
<valuelist type="QVariantList" key="QtProjectManager.QMakeBuildStep.SelectedAbis"/>
|
||||||
|
</valuemap>
|
||||||
|
<valuemap type="QVariantMap" key="ProjectExplorer.BuildStepList.Step.1">
|
||||||
|
<value type="bool" key="ProjectExplorer.BuildStep.Enabled">true</value>
|
||||||
|
<value type="QString" key="ProjectExplorer.ProjectConfiguration.Id">Qt4ProjectManager.MakeStep</value>
|
||||||
|
</valuemap>
|
||||||
|
<value type="int" key="ProjectExplorer.BuildStepList.StepsCount">2</value>
|
||||||
|
<value type="QString" key="ProjectExplorer.ProjectConfiguration.DefaultDisplayName">Build</value>
|
||||||
|
<value type="QString" key="ProjectExplorer.ProjectConfiguration.DisplayName">Build</value>
|
||||||
|
<value type="QString" key="ProjectExplorer.ProjectConfiguration.Id">ProjectExplorer.BuildSteps.Build</value>
|
||||||
|
</valuemap>
|
||||||
|
<valuemap type="QVariantMap" key="ProjectExplorer.BuildConfiguration.BuildStepList.1">
|
||||||
|
<valuemap type="QVariantMap" key="ProjectExplorer.BuildStepList.Step.0">
|
||||||
|
<value type="bool" key="ProjectExplorer.BuildStep.Enabled">true</value>
|
||||||
|
<value type="QString" key="ProjectExplorer.ProjectConfiguration.Id">Qt4ProjectManager.MakeStep</value>
|
||||||
|
<value type="QString" key="Qt4ProjectManager.MakeStep.MakeArguments">clean</value>
|
||||||
|
</valuemap>
|
||||||
|
<value type="int" key="ProjectExplorer.BuildStepList.StepsCount">1</value>
|
||||||
|
<value type="QString" key="ProjectExplorer.ProjectConfiguration.DefaultDisplayName">Clean</value>
|
||||||
|
<value type="QString" key="ProjectExplorer.ProjectConfiguration.DisplayName">Clean</value>
|
||||||
|
<value type="QString" key="ProjectExplorer.ProjectConfiguration.Id">ProjectExplorer.BuildSteps.Clean</value>
|
||||||
|
</valuemap>
|
||||||
|
<value type="int" key="ProjectExplorer.BuildConfiguration.BuildStepListCount">2</value>
|
||||||
|
<value type="bool" key="ProjectExplorer.BuildConfiguration.ClearSystemEnvironment">false</value>
|
||||||
|
<valuelist type="QVariantList" key="ProjectExplorer.BuildConfiguration.CustomParsers"/>
|
||||||
|
<value type="bool" key="ProjectExplorer.BuildConfiguration.ParseStandardOutput">false</value>
|
||||||
|
<valuelist type="QVariantList" key="ProjectExplorer.BuildConfiguration.UserEnvironmentChanges"/>
|
||||||
|
<value type="QString" key="ProjectExplorer.ProjectConfiguration.DisplayName">Release</value>
|
||||||
|
<value type="QString" key="ProjectExplorer.ProjectConfiguration.Id">Qt4ProjectManager.Qt4BuildConfiguration</value>
|
||||||
|
<value type="int" key="Qt4ProjectManager.Qt4BuildConfiguration.BuildConfiguration">0</value>
|
||||||
|
</valuemap>
|
||||||
|
<valuemap type="QVariantMap" key="ProjectExplorer.Target.BuildConfiguration.2">
|
||||||
|
<value type="int" key="EnableQmlDebugging">0</value>
|
||||||
|
<value type="QString" key="ProjectExplorer.BuildConfiguration.BuildDirectory">/home/m0rph3us1987/build-QTDemo-Desktop-Profile</value>
|
||||||
|
<value type="QString" key="ProjectExplorer.BuildConfiguration.BuildDirectory.shadowDir">/home/m0rph3us1987/build-QTDemo-Desktop-Profile</value>
|
||||||
|
<valuemap type="QVariantMap" key="ProjectExplorer.BuildConfiguration.BuildStepList.0">
|
||||||
|
<valuemap type="QVariantMap" key="ProjectExplorer.BuildStepList.Step.0">
|
||||||
|
<value type="bool" key="ProjectExplorer.BuildStep.Enabled">true</value>
|
||||||
|
<value type="QString" key="ProjectExplorer.ProjectConfiguration.Id">QtProjectManager.QMakeBuildStep</value>
|
||||||
|
<value type="bool" key="QtProjectManager.QMakeBuildStep.QMakeForced">false</value>
|
||||||
|
<valuelist type="QVariantList" key="QtProjectManager.QMakeBuildStep.SelectedAbis"/>
|
||||||
|
</valuemap>
|
||||||
|
<valuemap type="QVariantMap" key="ProjectExplorer.BuildStepList.Step.1">
|
||||||
|
<value type="bool" key="ProjectExplorer.BuildStep.Enabled">true</value>
|
||||||
|
<value type="QString" key="ProjectExplorer.ProjectConfiguration.Id">Qt4ProjectManager.MakeStep</value>
|
||||||
|
</valuemap>
|
||||||
|
<value type="int" key="ProjectExplorer.BuildStepList.StepsCount">2</value>
|
||||||
|
<value type="QString" key="ProjectExplorer.ProjectConfiguration.DefaultDisplayName">Build</value>
|
||||||
|
<value type="QString" key="ProjectExplorer.ProjectConfiguration.DisplayName">Build</value>
|
||||||
|
<value type="QString" key="ProjectExplorer.ProjectConfiguration.Id">ProjectExplorer.BuildSteps.Build</value>
|
||||||
|
</valuemap>
|
||||||
|
<valuemap type="QVariantMap" key="ProjectExplorer.BuildConfiguration.BuildStepList.1">
|
||||||
|
<valuemap type="QVariantMap" key="ProjectExplorer.BuildStepList.Step.0">
|
||||||
|
<value type="bool" key="ProjectExplorer.BuildStep.Enabled">true</value>
|
||||||
|
<value type="QString" key="ProjectExplorer.ProjectConfiguration.Id">Qt4ProjectManager.MakeStep</value>
|
||||||
|
<value type="QString" key="Qt4ProjectManager.MakeStep.MakeArguments">clean</value>
|
||||||
|
</valuemap>
|
||||||
|
<value type="int" key="ProjectExplorer.BuildStepList.StepsCount">1</value>
|
||||||
|
<value type="QString" key="ProjectExplorer.ProjectConfiguration.DefaultDisplayName">Clean</value>
|
||||||
|
<value type="QString" key="ProjectExplorer.ProjectConfiguration.DisplayName">Clean</value>
|
||||||
|
<value type="QString" key="ProjectExplorer.ProjectConfiguration.Id">ProjectExplorer.BuildSteps.Clean</value>
|
||||||
|
</valuemap>
|
||||||
|
<value type="int" key="ProjectExplorer.BuildConfiguration.BuildStepListCount">2</value>
|
||||||
|
<value type="bool" key="ProjectExplorer.BuildConfiguration.ClearSystemEnvironment">false</value>
|
||||||
|
<valuelist type="QVariantList" key="ProjectExplorer.BuildConfiguration.CustomParsers"/>
|
||||||
|
<value type="bool" key="ProjectExplorer.BuildConfiguration.ParseStandardOutput">false</value>
|
||||||
|
<valuelist type="QVariantList" key="ProjectExplorer.BuildConfiguration.UserEnvironmentChanges"/>
|
||||||
|
<value type="QString" key="ProjectExplorer.ProjectConfiguration.DisplayName">Profile</value>
|
||||||
|
<value type="QString" key="ProjectExplorer.ProjectConfiguration.Id">Qt4ProjectManager.Qt4BuildConfiguration</value>
|
||||||
|
<value type="int" key="Qt4ProjectManager.Qt4BuildConfiguration.BuildConfiguration">0</value>
|
||||||
|
<value type="int" key="SeparateDebugInfo">0</value>
|
||||||
|
</valuemap>
|
||||||
|
<value type="int" key="ProjectExplorer.Target.BuildConfigurationCount">3</value>
|
||||||
|
<valuemap type="QVariantMap" key="ProjectExplorer.Target.DeployConfiguration.0">
|
||||||
|
<valuemap type="QVariantMap" key="ProjectExplorer.BuildConfiguration.BuildStepList.0">
|
||||||
|
<value type="int" key="ProjectExplorer.BuildStepList.StepsCount">0</value>
|
||||||
|
<value type="QString" key="ProjectExplorer.ProjectConfiguration.DefaultDisplayName">Deploy</value>
|
||||||
|
<value type="QString" key="ProjectExplorer.ProjectConfiguration.DisplayName">Deploy</value>
|
||||||
|
<value type="QString" key="ProjectExplorer.ProjectConfiguration.Id">ProjectExplorer.BuildSteps.Deploy</value>
|
||||||
|
</valuemap>
|
||||||
|
<value type="int" key="ProjectExplorer.BuildConfiguration.BuildStepListCount">1</value>
|
||||||
|
<valuemap type="QVariantMap" key="ProjectExplorer.DeployConfiguration.CustomData"/>
|
||||||
|
<value type="bool" key="ProjectExplorer.DeployConfiguration.CustomDataEnabled">false</value>
|
||||||
|
<value type="QString" key="ProjectExplorer.ProjectConfiguration.Id">ProjectExplorer.DefaultDeployConfiguration</value>
|
||||||
|
</valuemap>
|
||||||
|
<value type="int" key="ProjectExplorer.Target.DeployConfigurationCount">1</value>
|
||||||
|
<valuemap type="QVariantMap" key="ProjectExplorer.Target.RunConfiguration.0">
|
||||||
|
<value type="bool" key="Analyzer.Perf.Settings.UseGlobalSettings">true</value>
|
||||||
|
<value type="bool" key="Analyzer.QmlProfiler.Settings.UseGlobalSettings">true</value>
|
||||||
|
<value type="bool" key="Analyzer.Valgrind.Settings.UseGlobalSettings">true</value>
|
||||||
|
<valuelist type="QVariantList" key="CustomOutputParsers"/>
|
||||||
|
<value type="int" key="PE.EnvironmentAspect.Base">2</value>
|
||||||
|
<valuelist type="QVariantList" key="PE.EnvironmentAspect.Changes"/>
|
||||||
|
<value type="QString" key="ProjectExplorer.ProjectConfiguration.Id">Qt4ProjectManager.Qt4RunConfiguration:/home/m0rph3us1987/gbcflsh_1.1/gbcflsh_1.1.pro</value>
|
||||||
|
<value type="QString" key="ProjectExplorer.RunConfiguration.BuildKey">/home/m0rph3us1987/gbcflsh_1.1/gbcflsh_1.1.pro</value>
|
||||||
|
<value type="bool" key="RunConfiguration.UseCppDebugger">false</value>
|
||||||
|
<value type="bool" key="RunConfiguration.UseCppDebuggerAuto">true</value>
|
||||||
|
<value type="bool" key="RunConfiguration.UseLibrarySearchPath">true</value>
|
||||||
|
<value type="bool" key="RunConfiguration.UseQmlDebugger">false</value>
|
||||||
|
<value type="bool" key="RunConfiguration.UseQmlDebuggerAuto">true</value>
|
||||||
|
<value type="QString" key="RunConfiguration.WorkingDirectory.default">/home/m0rph3us1987/build-QTDemo-Desktop-Debug</value>
|
||||||
|
</valuemap>
|
||||||
|
<value type="int" key="ProjectExplorer.Target.RunConfigurationCount">1</value>
|
||||||
|
</valuemap>
|
||||||
|
</data>
|
||||||
|
<data>
|
||||||
|
<variable>ProjectExplorer.Project.TargetCount</variable>
|
||||||
|
<value type="int">1</value>
|
||||||
|
</data>
|
||||||
|
<data>
|
||||||
|
<variable>ProjectExplorer.Project.Updater.FileVersion</variable>
|
||||||
|
<value type="int">22</value>
|
||||||
|
</data>
|
||||||
|
<data>
|
||||||
|
<variable>Version</variable>
|
||||||
|
<value type="int">22</value>
|
||||||
|
</data>
|
||||||
|
</qtcreator>
|
437
icon.xpm
Normal file
437
icon.xpm
Normal file
@ -0,0 +1,437 @@
|
|||||||
|
/* XPM - program icon */
|
||||||
|
static const char * icon[] = {
|
||||||
|
"27 35 399 2",
|
||||||
|
" c #6F6F6F",
|
||||||
|
". c #000000",
|
||||||
|
"+ c #5C5C5C",
|
||||||
|
"@ c #F9FAFC",
|
||||||
|
"# c #DAE4EE",
|
||||||
|
"$ c #DAE4ED",
|
||||||
|
"% c #D9E3ED",
|
||||||
|
"& c #D9E3EC",
|
||||||
|
"* c #D8E2EC",
|
||||||
|
"= c #D7E1EB",
|
||||||
|
"- c #D6E1EA",
|
||||||
|
"; c #D6E0EA",
|
||||||
|
"> c #D5E0E9",
|
||||||
|
", c #D4DFE9",
|
||||||
|
"' c #D4DEE8",
|
||||||
|
") c #D3DEE7",
|
||||||
|
"! c #D3DDE7",
|
||||||
|
"~ c #D2DCE6",
|
||||||
|
"{ c #D1DCE6",
|
||||||
|
"] c #D1DBE5",
|
||||||
|
"^ c #D0DAE4",
|
||||||
|
"/ c #A0AFBD",
|
||||||
|
"( c #DEE7EF",
|
||||||
|
"_ c #9DB8D2",
|
||||||
|
": c #C2D2DF",
|
||||||
|
"< c #8299AE",
|
||||||
|
"[ c #88A0B6",
|
||||||
|
"} c #B5C8D9",
|
||||||
|
"| c #859DB4",
|
||||||
|
"1 c #98B3CD",
|
||||||
|
"2 c #96B2CC",
|
||||||
|
"3 c #95B0CA",
|
||||||
|
"4 c #93AEC8",
|
||||||
|
"5 c #91ADC7",
|
||||||
|
"6 c #8FABC5",
|
||||||
|
"7 c #8EA9C3",
|
||||||
|
"8 c #8CA8C2",
|
||||||
|
"9 c #8AA6C0",
|
||||||
|
"0 c #89A4BE",
|
||||||
|
"a c #87A3BD",
|
||||||
|
"b c #85A1BB",
|
||||||
|
"c c #849FB9",
|
||||||
|
"d c #829EB8",
|
||||||
|
"e c #809CB6",
|
||||||
|
"f c #7E9BB5",
|
||||||
|
"g c #6F889F",
|
||||||
|
"h c #9BB6D0",
|
||||||
|
"i c #99B4CE",
|
||||||
|
"j c #97B3CD",
|
||||||
|
"k c #96B1CB",
|
||||||
|
"l c #94AFC9",
|
||||||
|
"m c #92AEC8",
|
||||||
|
"n c #91ACC6",
|
||||||
|
"o c #8FAAC4",
|
||||||
|
"p c #8DA9C3",
|
||||||
|
"q c #8BA7C1",
|
||||||
|
"r c #8AA5BF",
|
||||||
|
"s c #88A4BE",
|
||||||
|
"t c #86A2BC",
|
||||||
|
"u c #839FB9",
|
||||||
|
"v c #819DB7",
|
||||||
|
"w c #7E9AB4",
|
||||||
|
"x c #7C98B2",
|
||||||
|
"y c #6C869D",
|
||||||
|
"z c #88A1B8",
|
||||||
|
"A c #6A839A",
|
||||||
|
"B c #96ACBF",
|
||||||
|
"C c #698199",
|
||||||
|
"D c #DDE6EF",
|
||||||
|
"E c #5F7F50",
|
||||||
|
"F c #6C8860",
|
||||||
|
"G c #748E69",
|
||||||
|
"H c #78916C",
|
||||||
|
"I c #7B946F",
|
||||||
|
"J c #7E9772",
|
||||||
|
"K c #839C77",
|
||||||
|
"L c #879F7A",
|
||||||
|
"M c #8DA480",
|
||||||
|
"N c #8BA37E",
|
||||||
|
"O c #8AA17E",
|
||||||
|
"P c #859D78",
|
||||||
|
"Q c #809874",
|
||||||
|
"R c #93AABE",
|
||||||
|
"S c #678097",
|
||||||
|
"T c #DDE6EE",
|
||||||
|
"U c #98B4CE",
|
||||||
|
"V c #628154",
|
||||||
|
"W c #6D8962",
|
||||||
|
"X c #77916C",
|
||||||
|
"Y c #7A936E",
|
||||||
|
"Z c #7C9570",
|
||||||
|
"` c #7F9772",
|
||||||
|
" . c #829A75",
|
||||||
|
".. c #849C77",
|
||||||
|
"+. c #819A75",
|
||||||
|
"@. c #7E9773",
|
||||||
|
"#. c #92A8BC",
|
||||||
|
"$. c #647E95",
|
||||||
|
"%. c #DCE5EE",
|
||||||
|
"&. c #5C8054",
|
||||||
|
"*. c #6E8963",
|
||||||
|
"=. c #738E67",
|
||||||
|
"-. c #77906B",
|
||||||
|
";. c #79926D",
|
||||||
|
">. c #7C946F",
|
||||||
|
",. c #7E9671",
|
||||||
|
"'. c #7F9773",
|
||||||
|
"). c #7F9873",
|
||||||
|
"!. c #7D9671",
|
||||||
|
"~. c #7A946F",
|
||||||
|
"{. c #91A6BA",
|
||||||
|
"]. c #627C93",
|
||||||
|
"^. c #DBE4ED",
|
||||||
|
"/. c #637585",
|
||||||
|
"(. c #3C454F",
|
||||||
|
"_. c #5D8055",
|
||||||
|
":. c #6D8963",
|
||||||
|
"<. c #738D68",
|
||||||
|
"[. c #768F6A",
|
||||||
|
"}. c #79936E",
|
||||||
|
"|. c #8EA5B8",
|
||||||
|
"1. c #617991",
|
||||||
|
"2. c #DAE4EC",
|
||||||
|
"3. c #597D51",
|
||||||
|
"4. c #678459",
|
||||||
|
"5. c #708B65",
|
||||||
|
"6. c #758E69",
|
||||||
|
"7. c #76906A",
|
||||||
|
"8. c #78926D",
|
||||||
|
"9. c #758F69",
|
||||||
|
"0. c #8CA3B7",
|
||||||
|
"a. c #5E788F",
|
||||||
|
"b. c #DAE3EC",
|
||||||
|
"c. c #54784D",
|
||||||
|
"d. c #5D8155",
|
||||||
|
"e. c #69875C",
|
||||||
|
"f. c #718C66",
|
||||||
|
"g. c #758F6A",
|
||||||
|
"h. c #738D67",
|
||||||
|
"i. c #8BA1B6",
|
||||||
|
"j. c #5C768D",
|
||||||
|
"k. c #D9E2EB",
|
||||||
|
"l. c #8DA8C2",
|
||||||
|
"m. c #4E7248",
|
||||||
|
"n. c #577B50",
|
||||||
|
"o. c #608258",
|
||||||
|
"p. c #6A875D",
|
||||||
|
"q. c #748E68",
|
||||||
|
"r. c #708B64",
|
||||||
|
"s. c #899FB3",
|
||||||
|
"t. c #5A748B",
|
||||||
|
"u. c #D8E1EA",
|
||||||
|
"v. c #8BA6C0",
|
||||||
|
"w. c #44683F",
|
||||||
|
"x. c #4F7449",
|
||||||
|
"y. c #577C50",
|
||||||
|
"z. c #5E8156",
|
||||||
|
"A. c #68855B",
|
||||||
|
"B. c #6F8A64",
|
||||||
|
"C. c #718C65",
|
||||||
|
"D. c #728D67",
|
||||||
|
"E. c #728D66",
|
||||||
|
"F. c #728C66",
|
||||||
|
"G. c #68865B",
|
||||||
|
"H. c #879EB2",
|
||||||
|
"I. c #587189",
|
||||||
|
"J. c #D7E1E9",
|
||||||
|
"K. c #395E36",
|
||||||
|
"L. c #456940",
|
||||||
|
"M. c #5A7E52",
|
||||||
|
"N. c #5F8257",
|
||||||
|
"O. c #62845A",
|
||||||
|
"P. c #6A875C",
|
||||||
|
"Q. c #65865C",
|
||||||
|
"R. c #63845A",
|
||||||
|
"S. c #5F8157",
|
||||||
|
"T. c #859CB0",
|
||||||
|
"U. c #567087",
|
||||||
|
"V. c #D7E0E9",
|
||||||
|
"W. c #31572F",
|
||||||
|
"X. c #385C34",
|
||||||
|
"Y. c #41663C",
|
||||||
|
"Z. c #4A6D44",
|
||||||
|
"`. c #50754A",
|
||||||
|
" + c #54794E",
|
||||||
|
".+ c #5C7F54",
|
||||||
|
"++ c #5B7E53",
|
||||||
|
"@+ c #5A7D53",
|
||||||
|
"#+ c #577A50",
|
||||||
|
"$+ c #849AAF",
|
||||||
|
"%+ c #546E85",
|
||||||
|
"&+ c #D6DFE8",
|
||||||
|
"*+ c #84A0BA",
|
||||||
|
"=+ c #284F26",
|
||||||
|
"-+ c #2E542C",
|
||||||
|
";+ c #345931",
|
||||||
|
">+ c #3B5F38",
|
||||||
|
",+ c #42673D",
|
||||||
|
"'+ c #486C43",
|
||||||
|
")+ c #4D7247",
|
||||||
|
"!+ c #4F7349",
|
||||||
|
"~+ c #50744A",
|
||||||
|
"{+ c #51754B",
|
||||||
|
"]+ c #4E7148",
|
||||||
|
"^+ c #4C6F46",
|
||||||
|
"/+ c #8299AC",
|
||||||
|
"(+ c #516C83",
|
||||||
|
"_+ c #D5DEE7",
|
||||||
|
":+ c #444E56",
|
||||||
|
"<+ c #879BAE",
|
||||||
|
"[+ c #506A81",
|
||||||
|
"}+ c #D4DEE6",
|
||||||
|
"|+ c #7F9BB5",
|
||||||
|
"1+ c #242B31",
|
||||||
|
"2+ c #2D353C",
|
||||||
|
"3+ c #282E35",
|
||||||
|
"4+ c #2F373F",
|
||||||
|
"5+ c #2C333B",
|
||||||
|
"6+ c #0E1113",
|
||||||
|
"7+ c #465058",
|
||||||
|
"8+ c #9CACBC",
|
||||||
|
"9+ c #5A7791",
|
||||||
|
"0+ c #4E687F",
|
||||||
|
"a+ c #D4DDE6",
|
||||||
|
"b+ c #7D99B3",
|
||||||
|
"c+ c #94AABF",
|
||||||
|
"d+ c #97ADC1",
|
||||||
|
"e+ c #94AABE",
|
||||||
|
"f+ c #92A9BD",
|
||||||
|
"g+ c #8FA5B9",
|
||||||
|
"h+ c #8DA4B8",
|
||||||
|
"i+ c #8CA2B6",
|
||||||
|
"j+ c #8DA3B6",
|
||||||
|
"k+ c #8AA0B4",
|
||||||
|
"l+ c #849BAF",
|
||||||
|
"m+ c #8499AE",
|
||||||
|
"n+ c #879DAF",
|
||||||
|
"o+ c #9AADBC",
|
||||||
|
"p+ c #90A3B4",
|
||||||
|
"q+ c #597690",
|
||||||
|
"r+ c #57758F",
|
||||||
|
"s+ c #4C667D",
|
||||||
|
"t+ c #D3DCE5",
|
||||||
|
"u+ c #7A97B1",
|
||||||
|
"v+ c #7995AF",
|
||||||
|
"w+ c #7793AD",
|
||||||
|
"x+ c #7592AC",
|
||||||
|
"y+ c #7490AA",
|
||||||
|
"z+ c #728EA8",
|
||||||
|
"A+ c #708DA7",
|
||||||
|
"B+ c #6E8BA5",
|
||||||
|
"C+ c #6D8AA4",
|
||||||
|
"D+ c #728CA4",
|
||||||
|
"E+ c #68849D",
|
||||||
|
"F+ c #63809A",
|
||||||
|
"G+ c #617E98",
|
||||||
|
"H+ c #5F7C96",
|
||||||
|
"I+ c #5D7B95",
|
||||||
|
"J+ c #5C7993",
|
||||||
|
"K+ c #587690",
|
||||||
|
"L+ c #57748E",
|
||||||
|
"M+ c #55738D",
|
||||||
|
"N+ c #49647B",
|
||||||
|
"O+ c #D2DBE4",
|
||||||
|
"P+ c #7894AE",
|
||||||
|
"Q+ c #7693AD",
|
||||||
|
"R+ c #7591AB",
|
||||||
|
"S+ c #7390AA",
|
||||||
|
"T+ c #718EA8",
|
||||||
|
"U+ c #708CA6",
|
||||||
|
"V+ c #6C89A3",
|
||||||
|
"W+ c #6A87A1",
|
||||||
|
"X+ c #BEC9D4",
|
||||||
|
"Y+ c #97AABC",
|
||||||
|
"Z+ c #95A9BB",
|
||||||
|
"`+ c #96AABC",
|
||||||
|
" @ c #95A8B9",
|
||||||
|
".@ c #8FA3B4",
|
||||||
|
"+@ c #5D7A94",
|
||||||
|
"@@ c #5B7993",
|
||||||
|
"#@ c #597791",
|
||||||
|
"$@ c #58758F",
|
||||||
|
"%@ c #56748E",
|
||||||
|
"&@ c #54728C",
|
||||||
|
"*@ c #53708A",
|
||||||
|
"=@ c #486279",
|
||||||
|
"-@ c #D1DBE3",
|
||||||
|
";@ c #7692AC",
|
||||||
|
">@ c #7491AB",
|
||||||
|
",@ c #728FA9",
|
||||||
|
"'@ c #5B7287",
|
||||||
|
")@ c #485C6D",
|
||||||
|
"!@ c #4C6174",
|
||||||
|
"~@ c #5F788F",
|
||||||
|
"{@ c #68859F",
|
||||||
|
"]@ c #66839D",
|
||||||
|
"^@ c #65829C",
|
||||||
|
"/@ c #617F99",
|
||||||
|
"(@ c #607D97",
|
||||||
|
"_@ c #5E7B95",
|
||||||
|
":@ c #5C7A94",
|
||||||
|
"<@ c #5B7892",
|
||||||
|
"[@ c #54718B",
|
||||||
|
"}@ c #52708A",
|
||||||
|
"|@ c #506E88",
|
||||||
|
"1@ c #466077",
|
||||||
|
"2@ c #D1DAE3",
|
||||||
|
"3@ c #566C82",
|
||||||
|
"4@ c #B5B5B5",
|
||||||
|
"5@ c #8B8B8B",
|
||||||
|
"6@ c #93A8BA",
|
||||||
|
"7@ c #64819B",
|
||||||
|
"8@ c #62809A",
|
||||||
|
"9@ c #4C657C",
|
||||||
|
"0@ c #496278",
|
||||||
|
"a@ c #42596D",
|
||||||
|
"b@ c #41586C",
|
||||||
|
"c@ c #516F89",
|
||||||
|
"d@ c #4E6C86",
|
||||||
|
"e@ c #435E75",
|
||||||
|
"f@ c #D0D9E2",
|
||||||
|
"g@ c #4D6274",
|
||||||
|
"h@ c #4D5F70",
|
||||||
|
"i@ c #4F6577",
|
||||||
|
"j@ c #707070",
|
||||||
|
"k@ c #94A8BA",
|
||||||
|
"l@ c #627F99",
|
||||||
|
"m@ c #5E7C96",
|
||||||
|
"n@ c #465F74",
|
||||||
|
"o@ c #A5A6A9",
|
||||||
|
"p@ c #727878",
|
||||||
|
"q@ c #788999",
|
||||||
|
"r@ c #9EA0A3",
|
||||||
|
"s@ c #6C6F73",
|
||||||
|
"t@ c #778DA1",
|
||||||
|
"u@ c #4D6B85",
|
||||||
|
"v@ c #4C6A84",
|
||||||
|
"w@ c #425D74",
|
||||||
|
"x@ c #CFD9E1",
|
||||||
|
"y@ c #6F8CA6",
|
||||||
|
"z@ c #485B6C",
|
||||||
|
"A@ c #AFAFAF",
|
||||||
|
"B@ c #494949",
|
||||||
|
"C@ c #4A5E71",
|
||||||
|
"D@ c #27323C",
|
||||||
|
"E@ c #676767",
|
||||||
|
"F@ c #585858",
|
||||||
|
"G@ c #8EA2B5",
|
||||||
|
"H@ c #5A7892",
|
||||||
|
"I@ c #486176",
|
||||||
|
"J@ c #74787D",
|
||||||
|
"K@ c #10161B",
|
||||||
|
"L@ c #798997",
|
||||||
|
"M@ c #5A5E62",
|
||||||
|
"N@ c #0F151A",
|
||||||
|
"O@ c #71899D",
|
||||||
|
"P@ c #4B6983",
|
||||||
|
"Q@ c #CED8E0",
|
||||||
|
"R@ c #6D89A3",
|
||||||
|
"S@ c #4F6578",
|
||||||
|
"T@ c #949494",
|
||||||
|
"U@ c #1E262E",
|
||||||
|
"V@ c #51697E",
|
||||||
|
"W@ c #9BADBD",
|
||||||
|
"X@ c #55728C",
|
||||||
|
"Y@ c #758DA2",
|
||||||
|
"Z@ c #8599AC",
|
||||||
|
"`@ c #5E7990",
|
||||||
|
" # c #8397A9",
|
||||||
|
".# c #7B92A4",
|
||||||
|
"+# c #CED7E0",
|
||||||
|
"@# c #778B9C",
|
||||||
|
"## c #92A7B9",
|
||||||
|
"$# c #696969",
|
||||||
|
"%# c #2F2F2F",
|
||||||
|
"&# c #A1B2C1",
|
||||||
|
"*# c #9FB0C0",
|
||||||
|
"=# c #94A7B8",
|
||||||
|
"-# c #506D87",
|
||||||
|
";# c #4F6C86",
|
||||||
|
"># c #CDD7DF",
|
||||||
|
",# c #526F89",
|
||||||
|
"'# c #4F6D87",
|
||||||
|
")# c #CCD6DE",
|
||||||
|
"!# c #56738D",
|
||||||
|
"~# c #53718B",
|
||||||
|
"{# c #CBD5DD",
|
||||||
|
"]# c #516E88",
|
||||||
|
"^# c #CBD4DD",
|
||||||
|
"/# c #5F7D97",
|
||||||
|
"(# c #CAD4DC",
|
||||||
|
"_# c #C7CED3",
|
||||||
|
":# c #486074",
|
||||||
|
"<# c #485E72",
|
||||||
|
"[# c #465D72",
|
||||||
|
"}# c #445C71",
|
||||||
|
"|# c #445D72",
|
||||||
|
"1# c #455D73",
|
||||||
|
"2# c #565656",
|
||||||
|
" . . . . . . . . . . . . . . . . . . . . . . . . . + ",
|
||||||
|
". @ # # # # # # $ % & * = - ; > , ' ) ! ~ { ] ^ ^ / . ",
|
||||||
|
". ( _ : < : [ } | 1 2 3 4 5 6 7 8 9 0 a b c d e f g . ",
|
||||||
|
". ( _ _ _ _ h i j k l m n o p q r s t b u v e w x y . ",
|
||||||
|
". ( _ . . . . . . . . . . . . . . . . . . . . . z A . ",
|
||||||
|
". ( _ . . . . . . . . . . . . . . . . . . . . . B C . ",
|
||||||
|
". D h . . . . E F G H I J K L M N O P Q . . . . R S . ",
|
||||||
|
". T U . . . . V W G X Y Z ` .P P ..+.@.. . . . #.$.. ",
|
||||||
|
". %.k . . . . &.*.=.-.;.Y >.,.'.).J !.~.. . . . {.].. ",
|
||||||
|
". ^.l . /.(.. _.:.<.[.H H Y Y I I I }.H . . . . |.1.. ",
|
||||||
|
". 2.5 . . . . 3.4.5.6.7.H 8.;.;.;.;.H 9.. . . . 0.a.. ",
|
||||||
|
". b.6 . . . . c.d.e.f.6.7.-.X H X -.g.h.. . . . i.j.. ",
|
||||||
|
". k.l.. . . . m.n.o.p.f.q.9.[.7.[.9.<.r.. . . . s.t.. ",
|
||||||
|
". u.v.. . . . w.x.y.z.A.B.C.h.D.E.F.5.G.. . . . H.I.. ",
|
||||||
|
". J.s . . . . K.L.m.c.M.N.O.p.P.p.Q.R.S.. . . . T.U.. ",
|
||||||
|
". V.t . . . . W.X.Y.Z.`. +n..+.+_.++@+#+. . . . $+%+. ",
|
||||||
|
". &+*+. . . . =+-+;+>+,+'+)+!+~+{+{+]+^+. . . . /+(+. ",
|
||||||
|
". _+v . . . . . . . . . . . . . . . . . . . . :+<+[+. ",
|
||||||
|
". }+|+. . . . . 1+2+3+. . 4+5+6+. . . . . . 7+8+9+0+. ",
|
||||||
|
". a+b+c+d+B e+f+#.{.g+h+i+j+k+s.H.T.l+m+n+o+p+q+r+s+. ",
|
||||||
|
". t+u+v+w+x+y+z+A+B+C+D+E+E+E+E+F+G+H+I+J+9+K+L+M+N+. ",
|
||||||
|
". O+P+Q+R+S+T+U+B+V+W+X+Y+Z+`+ @.@H++@@@#@$@%@&@*@=@. ",
|
||||||
|
". -@;@>@,@'@)@!@~@W+{@]@^@F+/@(@_@:@<@q+r+M+[@}@|@1@. ",
|
||||||
|
". 2@y+z+A+3@4@5@6@{@]@7@8@G+H+I+J+9@0@L+a@b@c@|@d@e@. ",
|
||||||
|
". f@T+g@h@i@j@. k@^@7@l@(@m@+@<@n@o@p@q@r@s@t@u@v@w@. ",
|
||||||
|
". x@y@z@A@B@C@D@E@F@G@(@_@J+H@q+I@J@K@L@M@N@O@P@P@w@. ",
|
||||||
|
". Q@R@S@T@. U@V@F@. W@I+J+9+K+%@X@Y@Z@`@ #.#P@P@P@w@. ",
|
||||||
|
". +#W+@#k@##$#%#&#*#=#<@#@$@X@[@*@|@-#;#v@P@P@P@v@w@. ",
|
||||||
|
". >#{@]@^@F+F@. W@J+H@q+L+[@,#|@|@'#|@|@u@u@d@'#'#w@. ",
|
||||||
|
". )#]@7@l@G+G+G+G+G+G+#@%@&@M+!#[@*@~#[@c@|@'#;#u@w@. ",
|
||||||
|
". {#F+l@(@m@m@m@m@m@m@@@r+M+M+%@M+!#]#]#|@}@|@|@v@w@. ",
|
||||||
|
". ^#G+/#_@J+J+J+J+J+J+J+r+r+r+r+~#|@'#'#|@]#}@c@P@w@. ",
|
||||||
|
". (#H++@@@9+9+9+9+9+9+9+9+9+M+c@c@c@c@c@}@}@'#*@u@w@. ",
|
||||||
|
". _#:#<#[#}#}#}#}#}#}#}#}#}#}#}#}#}#}#}#|#|#1#}#}#}#}#",
|
||||||
|
"2#. . . . . . . . . . . . . . . . . . . . . . . . . . "};
|
Loading…
Reference in New Issue
Block a user