185 lines
3.9 KiB
C++
185 lines
3.9 KiB
C++
/*****************************************************************************
|
|
** 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;
|
|
}
|