Ensure big-endian data in A2V2 save-file format

- Also sanity-check buffer read overflow during loading
This commit is contained in:
Aaron Culliney 2016-10-16 12:52:27 -07:00
parent f6e2ebc028
commit d2e61e5091
10 changed files with 14270 additions and 718 deletions

View File

@ -1029,99 +1029,98 @@ void SetCLK(double CLK)
#define SS_YAML_VALUE_CHANGE_FORMAT "%d, %d, 0x%1X, 0x%02X"
#if 1 // APPLE2IX
static bool _saveStateData32(StateHelper_s *helper, uint32_t data) {
int fd = helper->fd;
uint8_t serialized[sizeof(uint32_t)] = { 0 };
serialized[0] = (uint8_t)((data & 0xFF000000) >> 24);
serialized[1] = (uint8_t)((data & 0xFF0000 ) >> 16);
serialized[2] = (uint8_t)((data & 0xFF00 ) >> 8);
serialized[3] = (uint8_t)((data & 0xFF ) >> 0);
return helper->save(fd, serialized, sizeof(serialized));
}
static bool _loadStateData32(StateHelper_s *helper, uint32_t *data) {
int fd = helper->fd;
uint8_t serialized[sizeof(uint32_t)] = { 0 };
if (!helper->load(fd, serialized, sizeof(uint32_t))) {
return false;
}
*data = (uint32_t)(serialized[0] << 24) |
(uint32_t)(serialized[1] << 16) |
(uint32_t)(serialized[2] << 8) |
(uint32_t)(serialized[3] << 0);
return true;
}
static bool _saveState(StateHelper_s *helper, struct CAY8910 *_this) {
int fd = helper->fd;
bool saved = false;
do {
unsigned int data = 0;
data = _this->ay_tone_tick[0];
if (!helper->save(fd, (uint8_t *)&data, sizeof(data))) {
if (!_saveStateData32(helper, _this->ay_tone_tick[0])) {
break;
}
data = _this->ay_tone_tick[1];
if (!helper->save(fd, (uint8_t *)&data, sizeof(data))) {
if (!_saveStateData32(helper, _this->ay_tone_tick[1])) {
break;
}
data = _this->ay_tone_tick[2];
if (!helper->save(fd, (uint8_t *)&data, sizeof(data))) {
if (!_saveStateData32(helper, _this->ay_tone_tick[2])) {
break;
}
data = _this->ay_tone_high[0];
if (!helper->save(fd, (uint8_t *)&data, sizeof(data))) {
if (!_saveStateData32(helper, _this->ay_tone_high[0])) {
break;
}
data = _this->ay_tone_high[1];
if (!helper->save(fd, (uint8_t *)&data, sizeof(data))) {
if (!_saveStateData32(helper, _this->ay_tone_high[1])) {
break;
}
data = _this->ay_tone_high[2];
if (!helper->save(fd, (uint8_t *)&data, sizeof(data))) {
if (!_saveStateData32(helper, _this->ay_tone_high[2])) {
break;
}
data = _this->ay_noise_tick;
if (!helper->save(fd, (uint8_t *)&data, sizeof(data))) {
if (!_saveStateData32(helper, _this->ay_noise_tick)) {
break;
}
data = _this->ay_tone_subcycles;
if (!helper->save(fd, (uint8_t *)&data, sizeof(data))) {
if (!_saveStateData32(helper, _this->ay_tone_subcycles)) {
break;
}
data = _this->ay_env_subcycles;
if (!helper->save(fd, (uint8_t *)&data, sizeof(data))) {
if (!_saveStateData32(helper, _this->ay_env_subcycles)) {
break;
}
data = _this->ay_env_internal_tick;
if (!helper->save(fd, (uint8_t *)&data, sizeof(data))) {
if (!_saveStateData32(helper, _this->ay_env_internal_tick)) {
break;
}
data = _this->ay_env_tick;
if (!helper->save(fd, (uint8_t *)&data, sizeof(data))) {
if (!_saveStateData32(helper, _this->ay_env_tick)) {
break;
}
data = _this->ay_tick_incr;
if (!helper->save(fd, (uint8_t *)&data, sizeof(data))) {
if (!_saveStateData32(helper, _this->ay_tick_incr)) {
break;
}
data = _this->ay_tone_period[0];
if (!helper->save(fd, (uint8_t *)&data, sizeof(data))) {
if (!_saveStateData32(helper, _this->ay_tone_period[0])) {
break;
}
data = _this->ay_tone_period[1];
if (!helper->save(fd, (uint8_t *)&data, sizeof(data))) {
if (!_saveStateData32(helper, _this->ay_tone_period[1])) {
break;
}
data = _this->ay_tone_period[2];
if (!helper->save(fd, (uint8_t *)&data, sizeof(data))) {
if (!_saveStateData32(helper, _this->ay_tone_period[2])) {
break;
}
data = _this->ay_noise_period;
if (!helper->save(fd, (uint8_t *)&data, sizeof(data))) {
if (!_saveStateData32(helper, _this->ay_noise_period)) {
break;
}
data = _this->ay_env_period;
if (!helper->save(fd, (uint8_t *)&data, sizeof(data))) {
if (!_saveStateData32(helper, _this->ay_env_period)) {
break;
}
data = _this->rng;
if (!helper->save(fd, (uint8_t *)&data, sizeof(data))) {
if (!_saveStateData32(helper, _this->rng)) {
break;
}
data = _this->noise_toggle;
if (!helper->save(fd, (uint8_t *)&data, sizeof(data))) {
if (!_saveStateData32(helper, _this->noise_toggle)) {
break;
}
data = _this->env_first;
if (!helper->save(fd, (uint8_t *)&data, sizeof(data))) {
if (!_saveStateData32(helper, _this->env_first)) {
break;
}
data = _this->env_rev;
if (!helper->save(fd, (uint8_t *)&data, sizeof(data))) {
if (!_saveStateData32(helper, _this->env_rev)) {
break;
}
data = _this->env_counter;
if (!helper->save(fd, (uint8_t *)&data, sizeof(data))) {
if (!_saveStateData32(helper, _this->env_counter)) {
break;
}
@ -1142,30 +1141,28 @@ static bool _saveState(StateHelper_s *helper, struct CAY8910 *_this) {
// Queued changes
assert(_this->ay_change_count >= 0);
if (!helper->save(fd, (uint8_t *)&(_this->ay_change_count), sizeof(_this->ay_change_count))) {
if (!_saveStateData32(helper, _this->ay_change_count)) {
break;
}
if (_this->ay_change_count)
{
bool success = true;
for (int i=0; i<_this->ay_change_count; i++) {
unsigned long tstates = (_this->ay_change[i]).tstates;
if (!helper->save(fd, (uint8_t *)&tstates, sizeof(tstates))) {
if (!_saveStateData32(helper, (uint32_t)_this->ay_change[i].tstates)) {
success = false;
break;
}
unsigned short ofs = (_this->ay_change[i]).ofs;
if (!helper->save(fd, (uint8_t *)&ofs, sizeof(ofs))) {
if (!_saveStateData32(helper, (uint32_t)(_this->ay_change[i].ofs))) {
success = false;
break;
}
unsigned char reg = (_this->ay_change[i]).reg;
if (!helper->save(fd, (uint8_t *)&reg, sizeof(reg))) {
uint8_t reg = _this->ay_change[i].reg;
if (!helper->save(fd, &reg, sizeof(reg))) {
success = false;
break;
}
unsigned char val = (_this->ay_change[i]).val;
if (!helper->save(fd, (uint8_t *)&val, sizeof(val))) {
uint8_t val = _this->ay_change[i].val;
if (!helper->save(fd, &val, sizeof(val))) {
success = false;
break;
}
@ -1187,70 +1184,70 @@ static bool _loadState(StateHelper_s *helper, struct CAY8910 *_this) {
bool loaded = false;
do {
if (!helper->load(fd, (uint8_t *)&(_this->ay_tone_tick[0]), sizeof(unsigned int))) {
if (!_loadStateData32(helper, &(_this->ay_tone_tick[0]))) {
break;
}
if (!helper->load(fd, (uint8_t *)&(_this->ay_tone_tick[1]), sizeof(unsigned int))) {
if (!_loadStateData32(helper, &(_this->ay_tone_tick[1]))) {
break;
}
if (!helper->load(fd, (uint8_t *)&(_this->ay_tone_tick[2]), sizeof(unsigned int))) {
if (!_loadStateData32(helper, &(_this->ay_tone_tick[2]))) {
break;
}
if (!helper->load(fd, (uint8_t *)&(_this->ay_tone_high[0]), sizeof(unsigned int))) {
if (!_loadStateData32(helper, &(_this->ay_tone_high[0]))) {
break;
}
if (!helper->load(fd, (uint8_t *)&(_this->ay_tone_high[1]), sizeof(unsigned int))) {
if (!_loadStateData32(helper, &(_this->ay_tone_high[1]))) {
break;
}
if (!helper->load(fd, (uint8_t *)&(_this->ay_tone_high[2]), sizeof(unsigned int))) {
if (!_loadStateData32(helper, &(_this->ay_tone_high[2]))) {
break;
}
if (!helper->load(fd, (uint8_t *)&(_this->ay_noise_tick), sizeof(unsigned int))) {
if (!_loadStateData32(helper, &(_this->ay_noise_tick))) {
break;
}
if (!helper->load(fd, (uint8_t *)&(_this->ay_tone_subcycles), sizeof(unsigned int))) {
if (!_loadStateData32(helper, &(_this->ay_tone_subcycles))) {
break;
}
if (!helper->load(fd, (uint8_t *)&(_this->ay_env_subcycles), sizeof(unsigned int))) {
if (!_loadStateData32(helper, &(_this->ay_env_subcycles))) {
break;
}
if (!helper->load(fd, (uint8_t *)&(_this->ay_env_internal_tick), sizeof(unsigned int))) {
if (!_loadStateData32(helper, &(_this->ay_env_internal_tick))) {
break;
}
if (!helper->load(fd, (uint8_t *)&(_this->ay_env_tick), sizeof(unsigned int))) {
if (!_loadStateData32(helper, &(_this->ay_env_tick))) {
break;
}
if (!helper->load(fd, (uint8_t *)&(_this->ay_tick_incr), sizeof(unsigned int))) {
if (!_loadStateData32(helper, &(_this->ay_tick_incr))) {
break;
}
if (!helper->load(fd, (uint8_t *)&(_this->ay_tone_period[0]), sizeof(unsigned int))) {
if (!_loadStateData32(helper, &(_this->ay_tone_period[0]))) {
break;
}
if (!helper->load(fd, (uint8_t *)&(_this->ay_tone_period[1]), sizeof(unsigned int))) {
if (!_loadStateData32(helper, &(_this->ay_tone_period[1]))) {
break;
}
if (!helper->load(fd, (uint8_t *)&(_this->ay_tone_period[2]), sizeof(unsigned int))) {
if (!_loadStateData32(helper, &(_this->ay_tone_period[2]))) {
break;
}
if (!helper->load(fd, (uint8_t *)&(_this->ay_noise_period), sizeof(unsigned int))) {
if (!_loadStateData32(helper, &(_this->ay_noise_period))) {
break;
}
if (!helper->load(fd, (uint8_t *)&(_this->ay_env_period), sizeof(unsigned int))) {
if (!_loadStateData32(helper, &(_this->ay_env_period))) {
break;
}
if (!helper->load(fd, (uint8_t *)&(_this->rng), sizeof(unsigned int))) {
if (!_loadStateData32(helper, (uint32_t *)&(_this->rng))) {
break;
}
if (!helper->load(fd, (uint8_t *)&(_this->noise_toggle), sizeof(unsigned int))) {
if (!_loadStateData32(helper, (uint32_t *)&(_this->noise_toggle))) {
break;
}
if (!helper->load(fd, (uint8_t *)&(_this->env_first), sizeof(unsigned int))) {
if (!_loadStateData32(helper, (uint32_t *)&(_this->env_first))) {
break;
}
if (!helper->load(fd, (uint8_t *)&(_this->env_rev), sizeof(unsigned int))) {
if (!_loadStateData32(helper, (uint32_t *)&(_this->env_rev))) {
break;
}
if (!helper->load(fd, (uint8_t *)&(_this->env_counter), sizeof(unsigned int))) {
if (!_loadStateData32(helper, (uint32_t *)&(_this->env_counter))) {
break;
}
@ -1269,7 +1266,7 @@ static bool _loadState(StateHelper_s *helper, struct CAY8910 *_this) {
}
// Queued changes
if (!helper->load(fd, (uint8_t *)&(_this->ay_change_count), sizeof(_this->ay_change_count))) {
if (!_loadStateData32(helper, (uint32_t *)&(_this->ay_change_count))) {
break;
}
assert(_this->ay_change_count >= 0);
@ -1277,14 +1274,18 @@ static bool _loadState(StateHelper_s *helper, struct CAY8910 *_this) {
{
bool success = true;
for (int i=0; i<_this->ay_change_count; i++) {
if (!helper->load(fd, (uint8_t *)&(_this->ay_change[i].tstates), sizeof(_this->ay_change[i].tstates))) {
if (!_loadStateData32(helper, (uint32_t *)&(_this->ay_change[i].tstates))) {
success = false;
break;
}
if (!helper->load(fd, (uint8_t *)&(_this->ay_change[i].ofs), sizeof(_this->ay_change[i].ofs))) {
uint32_t ofs = 0;
if (!_loadStateData32(helper, &ofs)) {
success = false;
break;
}
assert(ofs <= 65535);
_this->ay_change[i].ofs = (uint16_t)ofs;
if (!helper->load(fd, (uint8_t *)&(_this->ay_change[i].reg), sizeof(_this->ay_change[i].reg))) {
success = false;
break;
@ -1307,60 +1308,62 @@ static bool _loadState(StateHelper_s *helper, struct CAY8910 *_this) {
}
# if TESTING
static int _assert_testData32(const uint32_t data32, uint8_t **exData) {
uint8_t *expected = *exData;
uint32_t d32 = (uint32_t)(expected[0] << 24) |
(uint32_t)(expected[1] << 16) |
(uint32_t)(expected[2] << 8) |
(uint32_t)(expected[3] << 0);
ASSERT(d32 == data32);
*exData += 4;
PASS();
}
int _testStateA2V2(struct CAY8910 *_this, uint8_t **exData) {
unsigned int *p32 = (unsigned int *)(*exData);
uint8_t *p8 = *exData;
ASSERT(_this->ay_tone_tick[0] == *p32++);
ASSERT(_this->ay_tone_tick[1] == *p32++);
ASSERT(_this->ay_tone_tick[2] == *p32++);
ASSERT(_this->ay_tone_high[0] == *p32++);
ASSERT(_this->ay_tone_high[1] == *p32++);
ASSERT(_this->ay_tone_high[2] == *p32++);
_assert_testData32(_this->ay_tone_tick[0], &p8);
_assert_testData32(_this->ay_tone_tick[1], &p8);
_assert_testData32(_this->ay_tone_tick[2], &p8);
_assert_testData32(_this->ay_tone_high[0], &p8);
_assert_testData32(_this->ay_tone_high[1], &p8);
_assert_testData32(_this->ay_tone_high[2], &p8);
ASSERT(_this->ay_noise_tick == *p32++);
ASSERT(_this->ay_tone_subcycles == *p32++);
ASSERT(_this->ay_env_subcycles == *p32++);
ASSERT(_this->ay_env_internal_tick == *p32++);
ASSERT(_this->ay_env_tick == *p32++);
ASSERT(_this->ay_tick_incr == *p32++);
_assert_testData32(_this->ay_noise_tick, &p8);
_assert_testData32(_this->ay_tone_subcycles, &p8);
_assert_testData32(_this->ay_env_subcycles, &p8);
_assert_testData32(_this->ay_env_internal_tick, &p8);
_assert_testData32(_this->ay_env_tick, &p8);
ASSERT(_this->ay_tone_period[0] == *p32++);
ASSERT(_this->ay_tone_period[1] == *p32++);
ASSERT(_this->ay_tone_period[2] == *p32++);
//_assert_testData32(_this->ay_tick_incr, &p8); -- IGNORE... this will change depending on sample rate
p8 += 4;
ASSERT(_this->ay_noise_period == *p32++);
ASSERT(_this->ay_env_period == *p32++);
ASSERT(_this->rng == *p32++);
ASSERT(_this->noise_toggle == *p32++);
ASSERT(_this->env_first == *p32++);
ASSERT(_this->env_rev == *p32++);
ASSERT(_this->env_counter == *p32++);
_assert_testData32(_this->ay_tone_period[0], &p8);
_assert_testData32(_this->ay_tone_period[1], &p8);
_assert_testData32(_this->ay_tone_period[2], &p8);
_assert_testData32(_this->ay_noise_period, &p8);
_assert_testData32(_this->ay_env_period, &p8);
_assert_testData32(_this->rng, &p8);
_assert_testData32(_this->noise_toggle, &p8);
_assert_testData32(_this->env_first, &p8);
_assert_testData32(_this->env_rev, &p8);
_assert_testData32(_this->env_counter, &p8);
// Registers
uint8_t *p8 = (uint8_t *)p32;
for (unsigned int i=0; i<16; i++) {
ASSERT(_this->sound_ay_registers[i] == *p8++);
}
p32 = (unsigned int *)p8;
int changeCount = _this->ay_change_count;
ASSERT(changeCount == *p32++);
_assert_testData32(changeCount, &p8);
ASSERT(changeCount >= 0);
p8 = (uint8_t *)p32;
if (changeCount) {
for (int i=0; i<changeCount; i++) {
unsigned long *pL = (unsigned long *)p8;
ASSERT(_this->ay_change[i].tstates == *pL++);
p8 = (uint8_t *)pL;
unsigned short *pS = (unsigned short *)p8;
ASSERT(_this->ay_change[i].ofs == *pS++);
p8 = (uint8_t *)pS;
_assert_testData32(_this->ay_change[i].tstates, &p8);
_assert_testData32(_this->ay_change[i].ofs, &p8);
ASSERT(_this->ay_change[i].reg == *p8++);
ASSERT(_this->ay_change[i].val == *p8++);
}

View File

@ -2628,21 +2628,25 @@ static bool _sy6522_saveState(StateHelper_s *helper, SY6522 *sy6522) {
break;
}
uint16_t state16 = 0x0;
state16 = sy6522->TIMER1_COUNTER.w;
if (!helper->save(fd, (uint8_t *)&state16, 2)) {
uint8_t serialized[2] = { 0 };
serialized[0] = (uint8_t)((sy6522->TIMER1_COUNTER.w & 0xFF00) >> 8);
serialized[1] = (uint8_t)((sy6522->TIMER1_COUNTER.w & 0xFF ) >> 0);
if (!helper->save(fd, serialized, 2)) {
break;
}
state16 = sy6522->TIMER1_LATCH.w;
if (!helper->save(fd, (uint8_t *)&state16, 2)) {
serialized[0] = (uint8_t)((sy6522->TIMER1_LATCH.w & 0xFF00) >> 8);
serialized[1] = (uint8_t)((sy6522->TIMER1_LATCH.w & 0xFF ) >> 0);
if (!helper->save(fd, serialized, 2)) {
break;
}
state16 = sy6522->TIMER2_COUNTER.w;
if (!helper->save(fd, (uint8_t *)&state16, 2)) {
serialized[0] = (uint8_t)((sy6522->TIMER2_COUNTER.w & 0xFF00) >> 8);
serialized[1] = (uint8_t)((sy6522->TIMER2_COUNTER.w & 0xFF ) >> 0);
if (!helper->save(fd, serialized, 2)) {
break;
}
state16 = sy6522->TIMER2_LATCH.w;
if (!helper->save(fd, (uint8_t *)&state16, 2)) {
serialized[0] = (uint8_t)((sy6522->TIMER2_LATCH.w & 0xFF00) >> 8);
serialized[1] = (uint8_t)((sy6522->TIMER2_LATCH.w & 0xFF ) >> 0);
if (!helper->save(fd, serialized, 2)) {
break;
}
@ -2693,18 +2697,31 @@ static bool _sy6522_loadState(StateHelper_s *helper, SY6522 *sy6522) {
break;
}
if (!helper->load(fd, (uint8_t *)&(sy6522->TIMER1_COUNTER.w), 2)) {
uint8_t serialized[2] = { 0 };
if (!helper->load(fd, serialized, 2)) {
break;
}
if (!helper->load(fd, (uint8_t *)&(sy6522->TIMER1_LATCH.w), 2)) {
sy6522->TIMER1_COUNTER.h = serialized[0];
sy6522->TIMER1_COUNTER.l = serialized[1];
if (!helper->load(fd, serialized, 2)) {
break;
}
if (!helper->load(fd, (uint8_t *)&(sy6522->TIMER2_COUNTER.w), 2)) {
sy6522->TIMER1_LATCH.h = serialized[0];
sy6522->TIMER1_LATCH.l = serialized[1];
if (!helper->load(fd, serialized, 2)) {
break;
}
if (!helper->load(fd, (uint8_t *)&(sy6522->TIMER2_LATCH.w), 2)) {
sy6522->TIMER2_COUNTER.h = serialized[0];
sy6522->TIMER2_COUNTER.l = serialized[1];
if (!helper->load(fd, serialized, 2)) {
break;
}
sy6522->TIMER2_LATCH.h = serialized[0];
sy6522->TIMER2_LATCH.l = serialized[1];
if (!helper->load(fd, &(sy6522->SERIAL_SHIFT), 1)) {
break;
@ -2853,16 +2870,20 @@ bool mb_loadState(StateHelper_s *helper) {
SY6522_AY8910 *mb = &g_MB[idx];
if (!_sy6522_loadState(helper, &(mb->sy6522))) {
LOG("could not load SY6522 %u %u", i, j);
goto exit_load;
}
if (!_ay8910_loadState(helper, idx)) {
LOG("could not load AY8910 %u %u", i, j);
goto exit_load;
}
if (!_ssi263_loadState(helper, &(mb->SpeechChip))) {
LOG("could not load SSI263 %u %u", i, j);
goto exit_load;
}
if (!helper->load(fd, &(mb->nAYCurrentRegister), 1)) {
LOG("could not load nAYCurrentRegister %u %u", i, j);
goto exit_load;
}
@ -2889,6 +2910,15 @@ exit_load:
}
# if TESTING
static int _assert_testData16(const uint16_t data16, uint8_t **exData) {
uint8_t *expected = *exData;
uint16_t d16 = (uint16_t)(expected[0] << 8) |
(uint16_t)(expected[1] << 0);
ASSERT(d16 == data16);
*exData += 2;
PASS();
}
static int _sy6522_testAssertA2V2(SY6522 *sy6522, uint8_t **exData) {
uint8_t *expected = *exData;
@ -2898,14 +2928,10 @@ static int _sy6522_testAssertA2V2(SY6522 *sy6522, uint8_t **exData) {
ASSERT(sy6522->DDRA == *expected++);
ASSERT(sy6522->DDRB == *expected++);
uint16_t *expected16 = (uint16_t *)expected;
ASSERT(sy6522->TIMER1_COUNTER.w == *expected16++);
ASSERT(sy6522->TIMER1_LATCH.w == *expected16++);
ASSERT(sy6522->TIMER2_COUNTER.w == *expected16++);
ASSERT(sy6522->TIMER2_LATCH.w == *expected16++);
expected = (uint8_t *)expected16;
_assert_testData16(sy6522->TIMER1_COUNTER.w, &expected);
_assert_testData16(sy6522->TIMER1_LATCH.w, &expected);
_assert_testData16(sy6522->TIMER2_COUNTER.w, &expected);
_assert_testData16(sy6522->TIMER2_LATCH.w, &expected);
ASSERT(sy6522->SERIAL_SHIFT == *expected++);
ASSERT(sy6522->ACR == *expected++);

View File

@ -1172,8 +1172,9 @@ bool disk6_loadState(StateHelper_s *helper) {
namebuf[namelen+gzlen] = '\0';
LOG("LOAD disk[%lu] : (%u) %s", i, namelen, namebuf);
if (disk6_insert(i, namebuf, is_protected)) {
FREE(namebuf);
break;
LOG("OOPS loadState : proceeding despite cannot load disk : %s", namebuf);
//FREE(namebuf);
//break; -- ignore error with inserting disk and proceed
}
}

View File

@ -55,7 +55,7 @@ static bool _save_state(int fd, const uint8_t * outbuf, ssize_t outmax) {
ssize_t outlen = 0;
do {
if (TEMP_FAILURE_RETRY(outlen = write(fd, outbuf, outmax)) == -1) {
ERRLOG("error writing emulator save state file");
ERRLOG("OOPS, error writing emulator save-state file");
break;
}
outbuf += outlen;
@ -67,13 +67,33 @@ static bool _save_state(int fd, const uint8_t * outbuf, ssize_t outmax) {
static bool _load_state(int fd, uint8_t * inbuf, ssize_t inmax) {
ssize_t inlen = 0;
assert(inmax > 0);
struct stat stat_buf;
if (UNLIKELY(fstat(fd, &stat_buf) < 0)) {
ERRLOG("OOPS, could not stat FD");
return false;
}
off_t fileSiz = stat_buf.st_size;
off_t filePos = lseek(fd, 0, SEEK_CUR);
if (UNLIKELY(filePos < 0)) {
ERRLOG("OOPS, could not lseek FD");
return false;
}
if (UNLIKELY(filePos + inmax > fileSiz)) {
LOG("OOPS, encountered truncated save-state file");
return false;
}
do {
if (TEMP_FAILURE_RETRY(inlen = read(fd, inbuf, inmax)) == -1) {
ERRLOG("error reading emulator save state file");
ERRLOG("error reading emulator save-state file");
break;
}
if (inlen == 0) {
ERRLOG("error reading emulator save state file (truncated)");
ERRLOG("error reading emulator save-state file (truncated)");
break;
}
inbuf += inlen;
@ -143,7 +163,7 @@ bool emulator_saveState(const char * const path) {
}
if (!saved) {
ERRLOG("could not write to the emulator save state file");
ERRLOG("OOPS, could not write to the emulator save-state file");
unlink(path);
}
@ -204,8 +224,10 @@ bool emulator_loadState(const char * const path) {
break;
}
if (!timing_loadState(&helper)) {
break;
if (version >= 2) {
if (!timing_loadState(&helper)) {
break;
}
}
if (!video_loadState(&helper)) {
@ -218,6 +240,22 @@ bool emulator_loadState(const char * const path) {
}
}
// sanity-check whole file was read
struct stat stat_buf;
if (fstat(fd, &stat_buf) < 0) {
ERRLOG("OOPS, could not stat FD");
}
off_t fileSiz = stat_buf.st_size;
off_t filePos = lseek(fd, 0, SEEK_CUR);
if (filePos < 0) {
ERRLOG("OOPS, could not lseek FD");
}
if (UNLIKELY(filePos != fileSiz)) {
LOG("OOPS, state file read: %lu total: %lu", filePos, fileSiz);
}
loaded = true;
} while (0);
@ -226,7 +264,7 @@ bool emulator_loadState(const char * const path) {
}
if (!loaded) {
ERRLOG("could not load emulator save state file");
LOG("OOPS, problem(s) encountered loading emulator save-state file");
}
return loaded;

57
src/test/a2v2-good1-mb.h Normal file
View File

@ -0,0 +1,57 @@
unsigned char mbData[] = {
0x00, 0x04, 0xff, 0x07, 0x39, 0xcb, 0x4f, 0xba, 0xcf, 0x7d, 0x00, 0x00,
0x00, 0x40, 0x00, 0x00, 0x40, 0x00, 0x00, 0x00, 0x88, 0x00, 0x00, 0x04,
0x13, 0x00, 0x00, 0x00, 0x06, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x06, 0x28,
0xd9, 0x00, 0x0e, 0x28, 0xd9, 0x00, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00,
0x08, 0x00, 0x2e, 0x47, 0xcb, 0x00, 0x00, 0x00, 0xcd, 0x00, 0x00, 0x07,
0x9e, 0x00, 0x00, 0x00, 0x3c, 0x00, 0x00, 0x00, 0x05, 0x00, 0x00, 0x00,
0x0f, 0x00, 0x01, 0x76, 0x6a, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xcd, 0x00, 0x9e,
0x07, 0x3c, 0x00, 0x05, 0xf8, 0x0b, 0x00, 0x02, 0x0f, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x0d, 0x00, 0x00, 0x00, 0x66, 0x00, 0x00, 0x00,
0x02, 0x00, 0xcd, 0x00, 0x00, 0x00, 0x9f, 0x00, 0x00, 0x00, 0x03, 0x01,
0x00, 0x00, 0x00, 0x00, 0xd8, 0x00, 0x00, 0x00, 0x04, 0x02, 0x9e, 0x00,
0x00, 0x01, 0x11, 0x00, 0x00, 0x00, 0x05, 0x03, 0x07, 0x00, 0x00, 0x01,
0x4a, 0x00, 0x00, 0x00, 0x07, 0x04, 0x3c, 0x00, 0x00, 0x01, 0x83, 0x00,
0x00, 0x00, 0x08, 0x05, 0x00, 0x00, 0x00, 0x01, 0xbc, 0x00, 0x00, 0x00,
0x09, 0x06, 0x05, 0x00, 0x00, 0x01, 0xf5, 0x00, 0x00, 0x00, 0x0a, 0x07,
0xfa, 0x00, 0x00, 0x02, 0x33, 0x00, 0x00, 0x00, 0x0c, 0x08, 0x0c, 0x00,
0x00, 0x02, 0x6d, 0x00, 0x00, 0x00, 0x0d, 0x09, 0x10, 0x00, 0x00, 0x02,
0xa7, 0x00, 0x00, 0x00, 0x0e, 0x0a, 0x02, 0x00, 0x00, 0x02, 0xdb, 0x00,
0x00, 0x00, 0x0f, 0x0b, 0x3c, 0x00, 0x00, 0x03, 0x14, 0x00, 0x00, 0x00,
0x11, 0x0c, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0c, 0x00, 0x04,
0xff, 0x07, 0xcf, 0x7d, 0x00, 0x00, 0xcf, 0x7d, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xb8, 0x00, 0x00, 0x01, 0x56, 0x00,
0x00, 0x00, 0x34, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0x00, 0x06, 0x28, 0xd9, 0x00,
0x0e, 0x28, 0xd9, 0x00, 0x00, 0x00, 0x0e, 0x00, 0x00, 0x00, 0x39, 0x00,
0x2e, 0x47, 0xcb, 0x00, 0x00, 0x00, 0xf3, 0x00, 0x00, 0x07, 0x9e, 0x00,
0x00, 0x00, 0x3c, 0x00, 0x00, 0x00, 0x05, 0x00, 0x00, 0x00, 0x3c, 0x00,
0x01, 0x57, 0xf3, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xf3, 0x00, 0x9e, 0x07, 0x3c,
0x00, 0x05, 0xfa, 0x0c, 0x10, 0x02, 0x3c, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0c, 0x00, 0x00,
0x00, 0x00, 0xcf, 0x7d, 0x00, 0x00, 0xcf, 0x7d, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x24, 0x81, 0x45, 0x00, 0x05, 0x05, 0xe7, 0x00,
0x05, 0x05, 0xe7, 0x00, 0x00, 0x00, 0x05, 0x00, 0x24, 0x81, 0x45, 0x00,
0x2e, 0x47, 0xcb, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x01, 0x00,
0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x66, 0xb5, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0xcf, 0x7d, 0x00, 0x00, 0xcf, 0x7d, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x24, 0x81, 0x45, 0x00, 0x05, 0x05, 0xe7, 0x00,
0x05, 0x05, 0xe7, 0x00, 0x00, 0x00, 0x05, 0x00, 0x24, 0x81, 0x45, 0x00,
0x2e, 0x47, 0xcb, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x01, 0x00,
0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x66, 0xb5, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
};

View File

@ -8,7 +8,7 @@ unsigned char data[] = {
0x6b, 0x04, 0x00, 0x1a, 0x15, 0xba, 0x00, 0x00, 0x00, 0x00, 0x00, 0x04,
0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x40, 0xf5, 0x00, 0xc6, 0x00, 0x00,
0xff, 0xff, 0x00, 0x00, 0xff, 0xff, 0x00, 0x02, 0xff, 0xff, 0x00, 0x00,
0x29, 0x07, 0x01, 0x09, 0x05, 0xff, 0x00, 0x00, 0x06, 0x06, 0x01, 0x00,
0x24, 0x07, 0x01, 0x09, 0x05, 0xff, 0x00, 0x00, 0x05, 0x00, 0x01, 0x00,
0xff, 0xff, 0x00, 0x00, 0x01, 0xc4, 0x00, 0xc4, 0x00, 0x01, 0x00, 0xf2,
0x00, 0x04, 0x00, 0x60, 0xff, 0xff, 0x00, 0x00, 0xff, 0xff, 0xff, 0x00,
0xff, 0x00, 0xf0, 0xfd, 0x1b, 0xfd, 0x00, 0x00, 0xff, 0x0e, 0x00, 0x00,
@ -27,7 +27,7 @@ unsigned char data[] = {
0x44, 0x00, 0x00, 0xcc, 0xcc, 0x0c, 0x08, 0xc4, 0xc8, 0xa4, 0x60, 0x00,
0x30, 0x10, 0x90, 0x2c, 0x7c, 0x2c, 0xfc, 0xc8, 0x84, 0x40, 0x18, 0x3c,
0x24, 0x10, 0x1c, 0x10, 0x2c, 0x20, 0x14, 0x74, 0xa0, 0x1c, 0x1c, 0xa8,
0x74, 0xac, 0x80, 0xa8, 0x07, 0x0f, 0x01, 0x01, 0x01, 0x3d, 0x0a, 0x00,
0x74, 0xac, 0x80, 0xa8, 0x07, 0x0e, 0x01, 0x01, 0x01, 0x42, 0x0a, 0x00,
0xff, 0xff, 0x00, 0x00, 0xff, 0xff, 0x00, 0x00, 0xff, 0xff, 0x00, 0x00,
0xff, 0xff, 0x00, 0x00, 0xff, 0xff, 0x00, 0x00, 0xff, 0xff, 0x00, 0x00,
0xff, 0xff, 0x00, 0x00, 0xff, 0xff, 0x00, 0x00, 0xff, 0xff, 0x00, 0x00,
@ -48,7 +48,7 @@ unsigned char data[] = {
0xff, 0xff, 0x00, 0x00, 0xff, 0xff, 0x00, 0x00, 0xff, 0xff, 0x00, 0x00,
0xff, 0xff, 0x00, 0x00, 0xff, 0xff, 0x00, 0x00, 0xff, 0xff, 0x00, 0x00,
0xff, 0xff, 0x00, 0x00, 0xff, 0xff, 0x00, 0x00, 0xff, 0xff, 0x00, 0x00,
0x17, 0x05, 0x17, 0x05, 0x04, 0x0e, 0x03, 0x0e, 0x0d, 0x34, 0x30, 0x44,
0x17, 0x05, 0x17, 0x05, 0x02, 0x10, 0x02, 0x07, 0x15, 0x34, 0x30, 0x44,
0xf3, 0xff, 0x00, 0x00, 0xff, 0xff, 0x00, 0x00, 0xff, 0xff, 0x00, 0x00,
0xff, 0xff, 0x00, 0x00, 0xff, 0xff, 0x00, 0x00, 0xff, 0xff, 0x00, 0x00,
0xff, 0xff, 0x00, 0x00, 0xff, 0xff, 0x00, 0x00, 0xff, 0xff, 0x00, 0x00,
@ -106,9 +106,9 @@ unsigned char data[] = {
0x20, 0x20, 0x20, 0x20, 0x20, 0x28, 0x0e, 0x0f, 0x14, 0x20, 0x13, 0x0f,
0x29, 0x20, 0x03, 0x08, 0x05, 0x01, 0x10, 0x20, 0x14, 0x15, 0x0e, 0x05,
0x13, 0x20, 0x09, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0xa0,
0xa0, 0xa0, 0xa0, 0xa0, 0x20, 0xa0, 0xa0, 0xa0, 0xa0, 0x20, 0xa0, 0xa0,
0xa0, 0xa0, 0xa0, 0xa0, 0xa0, 0xa0, 0xa0, 0xa0, 0xa0, 0xa0, 0xa0, 0xa0,
0xa0, 0x20, 0xa0, 0xa0, 0xa0, 0xa0, 0x20, 0xa0, 0xa0, 0xa0, 0xa0, 0xa0,
0xa0, 0xa0, 0xa0, 0xa0, 0xa0, 0xa0, 0xa0, 0xa0, 0xa0, 0xa0, 0xa0, 0xa0,
0xa0, 0xa0, 0xa0, 0xa0, 0xa0, 0xa0, 0xa0, 0xa0, 0xa0, 0xa0, 0xa0, 0xa0,
0xa0, 0xa0, 0xa0, 0xa0, 0xa0, 0xa0, 0xa0, 0x20, 0x01, 0x20, 0x20, 0x20,
0x20, 0x02, 0x20, 0x20, 0x20, 0x20, 0x03, 0x20, 0xa0, 0xa0, 0xa0, 0xa0,
0xa0, 0xa0, 0xa0, 0xa0, 0x20, 0x01, 0x20, 0x20, 0x20, 0x20, 0x02, 0x20,
@ -117,9 +117,9 @@ unsigned char data[] = {
0xdf, 0xdf, 0xdf, 0xdf, 0xdf, 0xdf, 0xdf, 0xdf, 0xdf, 0xdf, 0xdf, 0xdf,
0xdf, 0xdf, 0xdf, 0xdf, 0xdf, 0xdf, 0xdf, 0xdf, 0xdf, 0xdf, 0xdf, 0xdf,
0xdf, 0xdf, 0xdf, 0xdf, 0xdf, 0xdf, 0xdf, 0xdf, 0xa0, 0xa0, 0xa0, 0xa0,
0x29, 0xa0, 0xa0, 0xa0, 0xa0, 0x29, 0xa0, 0xa0, 0xa0, 0xa0, 0xa0, 0xa0,
0xa0, 0xa0, 0xa0, 0xa0, 0xa0, 0xa0, 0xa0, 0xa0, 0xa0, 0x29, 0xa0, 0xa0,
0xa0, 0xa0, 0x29, 0xa0, 0xa0, 0xa0, 0xa0, 0xa0, 0xa0, 0xa0, 0xa0, 0xa0,
0x20, 0xa0, 0xa0, 0xa0, 0xa0, 0xa0, 0xa0, 0xa0, 0xa0, 0xa0, 0xa0, 0xa0,
0xa0, 0xa0, 0xa0, 0xa0, 0xa0, 0xa0, 0xa0, 0xa0, 0xa0, 0x20, 0xa0, 0xa0,
0xa0, 0xa0, 0xa0, 0xa0, 0xa0, 0xa0, 0xa0, 0xa0, 0xa0, 0xa0, 0xa0, 0xa0,
0xa0, 0xa0, 0xa0, 0xa0, 0xa0, 0xa0, 0xa0, 0xa0, 0xa0, 0xa0, 0xa0, 0xa0,
0xa0, 0xa0, 0xa0, 0xa0, 0xa0, 0xa0, 0xa0, 0xa0, 0xa0, 0xa0, 0xa0, 0xa0,
0xa0, 0xa0, 0xa0, 0xa0, 0xa0, 0xa0, 0xa0, 0xa0, 0xa0, 0xa0, 0xa0, 0xa0,
@ -127,9 +127,9 @@ unsigned char data[] = {
0xa0, 0xa0, 0x20, 0x01, 0x20, 0x14, 0x12, 0x09, 0x02, 0x15, 0x14, 0x05,
0x20, 0x14, 0x0f, 0x20, 0x14, 0x08, 0x05, 0x20, 0x13, 0x14, 0x20, 0x03,
0x08, 0x09, 0x10, 0x14, 0x15, 0x0e, 0x05, 0x20, 0x13, 0x03, 0x05, 0x0e,
0x05, 0x20, 0xa0, 0xa0, 0xa0, 0xa0, 0xa0, 0xa0, 0x28, 0xa0, 0xa0, 0xa0,
0xa0, 0x28, 0xa0, 0xa0, 0xa0, 0xa0, 0xa0, 0xa0, 0xa0, 0xa0, 0xa0, 0xa0,
0xa0, 0xa0, 0xa0, 0xa0, 0xa0, 0x28, 0xa0, 0xa0, 0xa0, 0xa0, 0x28, 0xa0,
0x05, 0x20, 0xa0, 0xa0, 0xa0, 0xa0, 0xa0, 0xa0, 0x29, 0xa0, 0xa0, 0xa0,
0xa0, 0xa0, 0xa0, 0xa0, 0xa0, 0xa0, 0xa0, 0xa0, 0xa0, 0xa0, 0xa0, 0xa0,
0xa0, 0xa0, 0xa0, 0xa0, 0xa0, 0x29, 0xa0, 0xa0, 0xa0, 0xa0, 0xa0, 0xa0,
0xa0, 0xa0, 0xa0, 0xa0, 0xa0, 0xa0, 0xa0, 0xa0, 0xdf, 0xdf, 0xdf, 0xdf,
0xdf, 0xdf, 0xdf, 0xdf, 0xdf, 0xdf, 0xdf, 0xdf, 0xdf, 0xdf, 0xdf, 0xdf,
0xdf, 0xdf, 0xdf, 0xdf, 0xdf, 0xdf, 0xdf, 0xdf, 0xdf, 0xdf, 0xdf, 0xdf,
@ -138,9 +138,9 @@ unsigned char data[] = {
0xa0, 0xa0, 0xa0, 0xa0, 0xa0, 0xa0, 0xa0, 0xa0, 0xa0, 0xa0, 0xa0, 0xa0,
0xa0, 0xa0, 0xa0, 0xa0, 0xa0, 0xa0, 0xa0, 0xa0, 0xa0, 0xa0, 0xa0, 0xa0,
0xa0, 0xa0, 0xa0, 0xa0, 0xa0, 0xa0, 0xa0, 0xa0, 0xa0, 0xa0, 0xa0, 0xa0,
0xa0, 0xa0, 0xa0, 0xa0, 0x29, 0xa0, 0xa0, 0xa0, 0xa0, 0x29, 0xa0, 0xa0,
0xa0, 0xa0, 0xa0, 0xa0, 0x28, 0xa0, 0xa0, 0xa0, 0xa0, 0xa0, 0xa0, 0xa0,
0xa0, 0xa0, 0xa0, 0xa0, 0xa0, 0xa0, 0xa0, 0xa0, 0xa0, 0xa0, 0xa0, 0xa0,
0xa0, 0x29, 0xa0, 0xa0, 0xa0, 0xa0, 0x29, 0xa0, 0xa0, 0xa0, 0xa0, 0xa0,
0xa0, 0x28, 0xa0, 0xa0, 0xa0, 0xa0, 0xa0, 0xa0, 0xa0, 0xa0, 0xa0, 0xa0,
0xa0, 0xa0, 0xa0, 0xa0, 0x0d, 0x0b, 0x02, 0x23, 0x34, 0x20, 0x20, 0x20,
0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x06, 0x12, 0x05, 0x0e, 0x03, 0x08,
0x20, 0x14, 0x0f, 0x15, 0x03, 0x08, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
@ -149,9 +149,9 @@ unsigned char data[] = {
0xa0, 0xa0, 0xa0, 0xa0, 0xa0, 0xa0, 0xa0, 0xa0, 0xa0, 0xa0, 0xa0, 0xa0,
0xa0, 0xa0, 0xa0, 0xa0, 0xa0, 0xa0, 0xa0, 0xa0, 0xa0, 0xa0, 0xa0, 0xa0,
0xa0, 0xa0, 0xa0, 0xa0, 0xa0, 0xa0, 0xa0, 0xa0, 0xa0, 0xa0, 0xa0, 0xa0,
0x28, 0xa0, 0xa0, 0xa0, 0xa0, 0x28, 0xa0, 0xa0, 0xa0, 0xa0, 0xa0, 0xa0,
0xa0, 0xa0, 0xa0, 0xa0, 0xa0, 0xa0, 0xa0, 0xa0, 0xa0, 0x28, 0xa0, 0xa0,
0xa0, 0xa0, 0x28, 0xa0, 0xa0, 0xa0, 0xa0, 0xa0, 0xa0, 0xa0, 0xa0, 0xa0,
0x29, 0xa0, 0xa0, 0xa0, 0xa0, 0xa0, 0xa0, 0xa0, 0xa0, 0xa0, 0xa0, 0xa0,
0xa0, 0xa0, 0xa0, 0xa0, 0xa0, 0xa0, 0xa0, 0xa0, 0xa0, 0x29, 0xa0, 0xa0,
0xa0, 0xa0, 0xa0, 0xa0, 0xa0, 0xa0, 0xa0, 0xa0, 0xa0, 0xa0, 0xa0, 0xa0,
0xa0, 0xa0, 0xa0, 0xa0, 0xa0, 0xa0, 0xa0, 0xa0, 0xa0, 0xa0, 0xa0, 0xa0,
0xa0, 0xa0, 0xa0, 0xa0, 0xa0, 0xa0, 0xa0, 0xa0, 0xa0, 0xa0, 0xa0, 0xa0,
0xa0, 0xa0, 0xa0, 0xa0, 0xa0, 0xa0, 0xa0, 0xa0, 0xa0, 0xa0, 0xa0, 0xa0,
@ -159,9 +159,9 @@ unsigned char data[] = {
0xa0, 0xa0, 0xa0, 0xa0, 0xa0, 0xa0, 0xa0, 0xa0, 0xa0, 0xa0, 0xa0, 0xa0,
0xa0, 0xa0, 0xa0, 0xa0, 0xa0, 0xa0, 0xa0, 0xa0, 0xa0, 0xa0, 0xa0, 0xa0,
0xa0, 0xa0, 0xa0, 0xa0, 0xa0, 0xa0, 0xa0, 0xa0, 0xa0, 0xa0, 0xa0, 0xa0,
0xa0, 0xa0, 0xa0, 0xa0, 0xa0, 0xa0, 0xa0, 0xa0, 0x29, 0xa0, 0xa0, 0xa0,
0xa0, 0x29, 0xa0, 0xa0, 0xa0, 0xa0, 0x20, 0xa0, 0xa0, 0xa0, 0xa0, 0xa0,
0xa0, 0xa0, 0xa0, 0xa0, 0xa0, 0x29, 0xa0, 0xa0, 0xa0, 0xa0, 0x29, 0xa0,
0xa0, 0xa0, 0xa0, 0xa0, 0xa0, 0xa0, 0xa0, 0xa0, 0x28, 0xa0, 0xa0, 0xa0,
0xa0, 0xa0, 0xa0, 0xa0, 0xa0, 0xa0, 0x20, 0xa0, 0xa0, 0xa0, 0xa0, 0xa0,
0xa0, 0xa0, 0xa0, 0xa0, 0xa0, 0x28, 0xa0, 0xa0, 0xa0, 0xa0, 0xa0, 0xa0,
0xa0, 0xa0, 0xa0, 0x20, 0xa0, 0xa0, 0xa0, 0xa0, 0xc9, 0xe6, 0xa0, 0xd0,
0xe9, 0xe7, 0xf3, 0xa0, 0xc3, 0xef, 0xf5, 0xec, 0xe4, 0xa0, 0xc6, 0xec,
0xf9, 0xa0, 0xa8, 0xc5, 0xee, 0xe4, 0xa0, 0xd4, 0xf5, 0xee, 0xe5, 0xa9,
@ -170,9 +170,9 @@ unsigned char data[] = {
0xa0, 0xa0, 0xa0, 0xa0, 0xa0, 0xa0, 0xa0, 0xa0, 0xa0, 0xa0, 0xa0, 0xa0,
0xa0, 0xa0, 0xa0, 0xa0, 0xa0, 0xa0, 0xa0, 0xa0, 0xa0, 0xa0, 0xa0, 0xa0,
0xa0, 0xa0, 0xa0, 0xa0, 0xa0, 0xa0, 0xa0, 0xa0, 0xa0, 0xa0, 0xa0, 0xa0,
0xa0, 0xa0, 0xa0, 0xa0, 0x28, 0xa0, 0xa0, 0xa0, 0xa0, 0x28, 0xa0, 0xa0,
0xa0, 0xa0, 0xa0, 0xa0, 0x29, 0xa0, 0xa0, 0xa0, 0xa0, 0x20, 0xa0, 0xa0,
0xa0, 0xa0, 0x29, 0xa0, 0xa0, 0xa0, 0xa0, 0xa0, 0xa0, 0xa0, 0xa0, 0xa0,
0xa0, 0x28, 0xa0, 0xa0, 0xa0, 0xa0, 0x28, 0xa0, 0xa0, 0xa0, 0xa0, 0x29,
0xa0, 0x29, 0xa0, 0xa0, 0xa0, 0xa0, 0x20, 0xa0, 0xa0, 0xa0, 0xa0, 0x29,
0xa0, 0xa0, 0xa0, 0xa0, 0xc6, 0xf2, 0xe1, 0xfa, 0xe5, 0xf2, 0xa0, 0xa8,
0xc6, 0xf2, 0xe1, 0xee, 0xfa, 0xe5, 0xee, 0xa0, 0xc1, 0xee, 0xe4, 0xf2,
0xe5, 0xe1, 0xf3, 0xa9, 0xa0, 0xa0, 0xa0, 0xa0, 0xa0, 0xa0, 0xa0, 0xa0,
@ -11417,16 +11417,16 @@ unsigned char data[] = {
0x69, 0x01, 0x9d, 0x49, 0xf9, 0xbd, 0x73, 0xf9, 0x85, 0xfe, 0x69, 0x00,
0x9d, 0x57, 0xf9, 0xa0, 0x00, 0xb1, 0xfd, 0x9d, 0x8f, 0xf9, 0x4c, 0xa5,
0xf6, 0x8d, 0xe4, 0xf6, 0x8e, 0x1a, 0xf7, 0x8c, 0x50, 0xf7, 0xa5, 0xfa,
0xd0, 0x05, 0xa9, 0x00, 0x4c, 0xec, 0xf6, 0xa9, 0x0c, 0x29, 0x0f, 0x4a,
0xd0, 0x05, 0xa9, 0x00, 0x4c, 0xec, 0xf6, 0xa9, 0x0b, 0x29, 0x0f, 0x4a,
0xc5, 0x18, 0xf0, 0x24, 0x85, 0x18, 0x85, 0xf9, 0xa2, 0x00, 0xbd, 0xc3,
0xf9, 0x85, 0xf7, 0xbd, 0xdb, 0xf9, 0x85, 0xf8, 0xa4, 0xf9, 0xb9, 0xab,
0xf9, 0xe6, 0xf9, 0xa0, 0x04, 0x91, 0xf7, 0xa0, 0x19, 0x91, 0xf7, 0xe8,
0xe0, 0x09, 0xd0, 0xe2, 0xa5, 0xfb, 0xd0, 0x05, 0xa9, 0x00, 0x4c, 0x22,
0xf7, 0xa9, 0x0d, 0x29, 0x0f, 0x4a, 0xc5, 0x19, 0xf0, 0x24, 0x85, 0x19,
0xf7, 0xa9, 0x10, 0x29, 0x0f, 0x4a, 0xc5, 0x19, 0xf0, 0x24, 0x85, 0x19,
0x85, 0xf9, 0xa2, 0x00, 0xbd, 0xc3, 0xf9, 0x85, 0xf7, 0xbd, 0xdb, 0xf9,
0x85, 0xf8, 0xa4, 0xf9, 0xb9, 0xab, 0xf9, 0xe6, 0xf9, 0xa0, 0x09, 0x91,
0xf7, 0xa0, 0x1e, 0x91, 0xf7, 0xe8, 0xe0, 0x09, 0xd0, 0xe2, 0xa5, 0xfc,
0xd0, 0x05, 0xa9, 0x00, 0x4c, 0x58, 0xf7, 0xa9, 0x03, 0x29, 0x0f, 0x4a,
0xd0, 0x05, 0xa9, 0x00, 0x4c, 0x58, 0xf7, 0xa9, 0x02, 0x29, 0x0f, 0x4a,
0xc5, 0x1a, 0xf0, 0x24, 0x85, 0x1a, 0x85, 0xf9, 0xa2, 0x00, 0xbd, 0xc3,
0xf9, 0x85, 0xf7, 0xbd, 0xdb, 0xf9, 0x85, 0xf8, 0xa4, 0xf9, 0xb9, 0xab,
0xf9, 0xe6, 0xf9, 0xa0, 0x0e, 0x91, 0xf7, 0xa0, 0x23, 0x91, 0xf7, 0xe8,
@ -11468,14 +11468,14 @@ unsigned char data[] = {
0xb3, 0xb4, 0xb5, 0xb6, 0xb7, 0xb8, 0xb9, 0xba, 0xbb, 0xbc, 0xbd, 0xbe,
0xbf, 0xd0, 0xd1, 0xd2, 0xd3, 0xd4, 0xd5, 0xd6, 0xd7, 0xd8, 0xd9, 0xda,
0xdb, 0xdc, 0xdd, 0xde, 0xdf, 0xe0, 0xe1, 0xe2, 0xe3, 0xe4, 0xe5, 0xe6,
0xe7, 0xe8, 0xe9, 0xea, 0xeb, 0xec, 0xed, 0xee, 0xef, 0x3e, 0x1c, 0x2f,
0x42, 0xd1, 0x7e, 0x09, 0x6a, 0xaf, 0xc8, 0x89, 0x4e, 0x9b, 0xe6, 0x0a,
0xe7, 0xe8, 0xe9, 0xea, 0xeb, 0xec, 0xed, 0xee, 0xef, 0x43, 0x1c, 0x33,
0x46, 0xd1, 0x7e, 0x09, 0x6c, 0xb5, 0xcc, 0x8b, 0x50, 0x9b, 0xe6, 0x0a,
0x26, 0x28, 0x3d, 0x48, 0x58, 0x5a, 0x5e, 0x73, 0x8a, 0x9a, 0xa9, 0xab,
0xab, 0xcf, 0xd4, 0x6f, 0xa6, 0x33, 0x6e, 0xf3, 0x28, 0xed, 0x8c, 0x1f,
0xca, 0x8d, 0xd8, 0x03, 0x25, 0x27, 0x3c, 0x48, 0x58, 0x59, 0x5e, 0x6d,
0x8a, 0x99, 0xa8, 0xab, 0xab, 0x00, 0xc1, 0x01, 0x01, 0x33, 0xbe, 0x0a,
0x03, 0x02, 0x01, 0x02, 0x03, 0x8b, 0x8b, 0x51, 0x00, 0xb1, 0x02, 0x3c,
0x00, 0x05, 0xf8, 0x0c, 0x0d, 0x03, 0x0f, 0x00, 0xff, 0x01, 0x00, 0x00,
0x8a, 0x99, 0xa8, 0xab, 0xab, 0x00, 0xbc, 0x0e, 0x0e, 0x2e, 0xb9, 0x05,
0x05, 0x03, 0x15, 0x04, 0x0e, 0x86, 0x86, 0xa2, 0x00, 0x9e, 0x07, 0x3c,
0x00, 0x05, 0xfa, 0x0b, 0x10, 0x02, 0x3c, 0x00, 0xff, 0x01, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xa0,
0xa0, 0xa0, 0xa0, 0xa0, 0xa0, 0xa0, 0xa0, 0x20, 0x29, 0x28, 0x29, 0x28,
0x29, 0x28, 0x29, 0x28, 0x00, 0x80, 0x00, 0x80, 0x00, 0x80, 0x00, 0x80,
@ -13661,64 +13661,61 @@ unsigned char data[] = {
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x02, 0x02, 0x02,
0x02, 0xf3, 0x0f, 0xf3, 0x0e, 0x01, 0x30, 0x0d, 0x03, 0xfc, 0x64, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xc8, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x01, 0x00, 0x00, 0x04, 0xff, 0x07, 0xec, 0x02, 0xba, 0x4f,
0xdf, 0xdf, 0x00, 0x00, 0x00, 0x40, 0x00, 0x00, 0x40, 0x69, 0x00, 0x00,
0x00, 0x23, 0x00, 0x00, 0x00, 0x2b, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00,
0x00, 0xb4, 0x54, 0x02, 0x00, 0xb4, 0x54, 0x0a, 0x00, 0x05, 0x00, 0x00,
0x00, 0x0c, 0x00, 0x00, 0x00, 0xcb, 0x47, 0x2e, 0x00, 0xa2, 0x00, 0x00,
0x00, 0xcc, 0x01, 0x00, 0x00, 0x3c, 0x00, 0x00, 0x00, 0x05, 0x00, 0x00,
0x00, 0x0f, 0x00, 0x00, 0x00, 0xfa, 0x17, 0x01, 0x00, 0x01, 0x00, 0x00,
0x02, 0xf6, 0xea, 0x00, 0x18, 0x05, 0x33, 0x10, 0x02, 0xfa, 0x00, 0x00,
0x00, 0x64, 0x00, 0x00, 0x00, 0xc8, 0x01, 0x00, 0x00, 0x04, 0xff, 0x07,
0x39, 0xcb, 0x4f, 0xba, 0xcf, 0x7d, 0x00, 0x00, 0x00, 0x40, 0x00, 0x00,
0x40, 0x00, 0x00, 0x00, 0x88, 0x00, 0x00, 0x04, 0x13, 0x00, 0x00, 0x00,
0x06, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x06, 0x28, 0xd9, 0x00, 0x0e, 0x28,
0xd9, 0x00, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00, 0x08, 0x00, 0x2e, 0x47,
0xcb, 0x00, 0x00, 0x00, 0xcd, 0x00, 0x00, 0x07, 0x9e, 0x00, 0x00, 0x00,
0x3c, 0x00, 0x00, 0x00, 0x05, 0x00, 0x00, 0x00, 0x0f, 0x00, 0x01, 0x76,
0x6a, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0xcd, 0x00, 0x9e, 0x07, 0x3c, 0x00, 0x05,
0xf8, 0x0b, 0x00, 0x02, 0x0f, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x0d, 0x00, 0x00, 0x00, 0x66, 0x00, 0x00, 0x00, 0x02, 0x00, 0xcd, 0x00,
0x00, 0x00, 0x9f, 0x00, 0x00, 0x00, 0x03, 0x01, 0x00, 0x00, 0x00, 0x00,
0xd8, 0x00, 0x00, 0x00, 0x04, 0x02, 0x9e, 0x00, 0x00, 0x01, 0x11, 0x00,
0x00, 0x00, 0x05, 0x03, 0x07, 0x00, 0x00, 0x01, 0x4a, 0x00, 0x00, 0x00,
0x07, 0x04, 0x3c, 0x00, 0x00, 0x01, 0x83, 0x00, 0x00, 0x00, 0x08, 0x05,
0x00, 0x00, 0x00, 0x01, 0xbc, 0x00, 0x00, 0x00, 0x09, 0x06, 0x05, 0x00,
0x00, 0x01, 0xf5, 0x00, 0x00, 0x00, 0x0a, 0x07, 0xfa, 0x00, 0x00, 0x02,
0x33, 0x00, 0x00, 0x00, 0x0c, 0x08, 0x0c, 0x00, 0x00, 0x02, 0x6d, 0x00,
0x00, 0x00, 0x0d, 0x09, 0x10, 0x00, 0x00, 0x02, 0xa7, 0x00, 0x00, 0x00,
0x0e, 0x0a, 0x02, 0x00, 0x00, 0x02, 0xdb, 0x00, 0x00, 0x00, 0x0f, 0x0b,
0x3c, 0x00, 0x00, 0x03, 0x14, 0x00, 0x00, 0x00, 0x11, 0x0c, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x0c, 0x00, 0x04, 0xff, 0x07, 0xcf, 0x7d,
0x00, 0x00, 0xcf, 0x7d, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0xb8, 0x00, 0x00, 0x01, 0x56, 0x00, 0x00, 0x00, 0x34, 0x00,
0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x02, 0x00, 0x06, 0x28, 0xd9, 0x00, 0x0e, 0x28, 0xd9, 0x00,
0x00, 0x00, 0x0e, 0x00, 0x00, 0x00, 0x39, 0x00, 0x2e, 0x47, 0xcb, 0x00,
0x00, 0x00, 0xf3, 0x00, 0x00, 0x07, 0x9e, 0x00, 0x00, 0x00, 0x3c, 0x00,
0x00, 0x00, 0x05, 0x00, 0x00, 0x00, 0x3c, 0x00, 0x01, 0x57, 0xf3, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0xa2, 0x00, 0xcc, 0x01, 0x3c, 0x00, 0x05, 0xf8, 0x0d, 0x0e, 0x04,
0x0f, 0x00, 0x00, 0x00, 0x00, 0x0d, 0x00, 0x00, 0x00, 0x66, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x66, 0x9f, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x03, 0x00, 0x01, 0x00, 0xd8, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x04, 0x00, 0x02, 0x66, 0x11, 0x01, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x05, 0x00, 0x03, 0x02, 0x4a, 0x01, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x07, 0x00, 0x04, 0x3c, 0x83, 0x01, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x08, 0x00, 0x05, 0x00, 0xbc, 0x01, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x09, 0x00, 0x06, 0x05, 0xf5, 0x01, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x0a, 0x00, 0x07, 0xf8, 0x33, 0x02, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x0c, 0x00, 0x08, 0x0d, 0x6d, 0x02, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x0d, 0x00, 0x09, 0x0e, 0xa7, 0x02, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x0e, 0x00, 0x0a, 0x03, 0xdb, 0x02, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x0f, 0x00, 0x0b, 0x0f, 0x14, 0x03, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x11, 0x00, 0x0c, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x0c, 0x00, 0x04, 0xff, 0x07, 0xdf, 0xdf, 0x00, 0x00,
0xdf, 0xdf, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x11, 0x00, 0x00,
0x00, 0xa0, 0x01, 0x00, 0x00, 0x1b, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00,
0x00, 0x00, 0x00, 0xf3, 0x00, 0x9e, 0x07, 0x3c, 0x00, 0x05, 0xfa, 0x0c,
0x10, 0x02, 0x3c, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x0c, 0x00, 0x00, 0x00, 0x00, 0xcf, 0x7d,
0x00, 0x00, 0xcf, 0x7d, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0xb4, 0x54, 0x02, 0x00, 0xb4, 0x54, 0x0a, 0x00, 0x0a, 0x00, 0x00,
0x00, 0x0d, 0x00, 0x00, 0x00, 0xcb, 0x47, 0x2e, 0x00, 0x79, 0x00, 0x00,
0x00, 0x23, 0x02, 0x00, 0x00, 0x3c, 0x00, 0x00, 0x00, 0x05, 0x00, 0x00,
0x00, 0x0f, 0x00, 0x00, 0x00, 0xf9, 0xd7, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x79, 0x00, 0x23, 0x02, 0x3c, 0x00, 0x05, 0xf8, 0x0d, 0x0e, 0x04,
0x0f, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x0c, 0x00, 0x00, 0x00, 0x00, 0xdf, 0xdf, 0x00, 0x00,
0xdf, 0xdf, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00,
0x00, 0x01, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x01, 0xdb, 0x35,
0x00, 0xa4, 0x93, 0x03, 0x00, 0xa4, 0x93, 0x0b, 0x00, 0x01, 0x00, 0x00,
0x00, 0x01, 0xdb, 0x35, 0x00, 0xcb, 0x47, 0x2e, 0x00, 0x01, 0x00, 0x00,
0x00, 0x01, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0xd0, 0x16, 0x01, 0x00, 0x01, 0x00, 0x00,
0x24, 0x81, 0x45, 0x00, 0x05, 0x05, 0xe7, 0x00, 0x05, 0x05, 0xe7, 0x00,
0x00, 0x00, 0x05, 0x00, 0x24, 0x81, 0x45, 0x00, 0x2e, 0x47, 0xcb, 0x00,
0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x01, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x66, 0xb5, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xdf, 0xdf, 0x00, 0x00,
0xdf, 0xdf, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00,
0x00, 0x01, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x01, 0xdb, 0x35,
0x00, 0xa4, 0x93, 0x03, 0x00, 0xa4, 0x93, 0x0b, 0x00, 0x01, 0x00, 0x00,
0x00, 0x01, 0xdb, 0x35, 0x00, 0xcb, 0x47, 0x2e, 0x00, 0x01, 0x00, 0x00,
0x00, 0x01, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0xd0, 0x16, 0x01, 0x00, 0x01, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xcf, 0x7d,
0x00, 0x00, 0xcf, 0x7d, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x24, 0x81, 0x45, 0x00, 0x05, 0x05, 0xe7, 0x00, 0x05, 0x05, 0xe7, 0x00,
0x00, 0x00, 0x05, 0x00, 0x24, 0x81, 0x45, 0x00, 0x2e, 0x47, 0xcb, 0x00,
0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x01, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x66, 0xb5, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00
0x00, 0x00, 0x00, 0x00, 0x00, 0x00
};

51
src/test/a2v2-good2-mb.h Normal file
View File

@ -0,0 +1,51 @@
unsigned char mbData[] = {
0x0c, 0x1c, 0xff, 0x1f, 0xc3, 0xe2, 0x00, 0x00, 0xc3, 0xe2, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x4d, 0x00, 0x00, 0x00,
0x2f, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x26, 0xc8, 0xfc, 0x00, 0x07, 0xce,
0x82, 0x00, 0x0f, 0xce, 0x82, 0x00, 0x00, 0x00, 0x01, 0x00, 0x30, 0xe4,
0xc1, 0x00, 0x2e, 0x47, 0xcb, 0x00, 0x00, 0x00, 0x51, 0x00, 0x00, 0x00,
0x7a, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0xfc, 0x1c, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x51, 0x00, 0x7a,
0x00, 0x00, 0x00, 0x00, 0x3c, 0x0d, 0x0b, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x0d, 0x76, 0x00, 0x00, 0x00,
0x88, 0x09, 0x0a, 0x00, 0x00, 0x0d, 0xf3, 0x00, 0x00, 0x00, 0x8b, 0x08,
0x0c, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x08, 0x0a, 0x1c, 0xff, 0x1f,
0xc3, 0xe2, 0x00, 0x00, 0xc3, 0xe2, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x30, 0x00, 0x00, 0x00, 0x18, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x08, 0xad, 0x44, 0x00, 0x07, 0xce, 0x82, 0x00, 0x0f, 0xce,
0x82, 0x00, 0x00, 0x00, 0x01, 0x00, 0x30, 0xe4, 0xc1, 0x00, 0x2e, 0x47,
0xcb, 0x00, 0x00, 0x00, 0xb6, 0x00, 0x00, 0x00, 0xa2, 0x00, 0x00, 0x00,
0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x39,
0xfb, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0xb6, 0x00, 0xa2, 0x00, 0x00, 0x00, 0x00,
0x3c, 0x0b, 0x0d, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x02, 0x00, 0x00, 0x0b, 0x60, 0x00, 0x00, 0x00, 0x7a, 0x09, 0x0c, 0x00,
0x00, 0x0b, 0xdd, 0x00, 0x00, 0x00, 0x7d, 0x08, 0x0a, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x08, 0x0b, 0x1c, 0xff, 0x1f, 0x0e, 0x12, 0x4f, 0xb9,
0xc3, 0xe2, 0x00, 0x00, 0x00, 0x40, 0x00, 0x00, 0x40, 0x00, 0x00, 0x00,
0x5b, 0x00, 0x00, 0x03, 0x20, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x30, 0xe0,
0x7f, 0x00, 0x07, 0xce, 0x82, 0x00, 0x0f, 0xce, 0x82, 0x00, 0x00, 0x00,
0x01, 0x00, 0x30, 0xe4, 0xc1, 0x00, 0x2e, 0x47, 0xcb, 0x00, 0x00, 0x00,
0xf4, 0x00, 0x00, 0x03, 0xcf, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0e, 0x83, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0xf4, 0x00, 0xcf, 0x03, 0x00, 0x00, 0x00, 0x3c, 0x0c, 0x0c, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x09,
0xaf, 0x00, 0x00, 0x00, 0x66, 0x09, 0x0b, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x09, 0x0c, 0x1c, 0xff, 0x1f, 0xc3, 0xe2, 0x00, 0x00, 0xc3, 0xe2,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xa6, 0x00,
0x00, 0x00, 0x16, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x30, 0xe0, 0xf9, 0x00,
0x07, 0xce, 0x82, 0x00, 0x0f, 0xce, 0x82, 0x00, 0x00, 0x00, 0x01, 0x00,
0x30, 0xe4, 0xc1, 0x00, 0x2e, 0x47, 0xcb, 0x00, 0x00, 0x00, 0xf4, 0x00,
0x00, 0x00, 0x60, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x0e, 0x83, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xf4,
0x00, 0x60, 0x00, 0x00, 0x00, 0x00, 0x3c, 0x0d, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x08, 0x16, 0x00,
0x00, 0x00, 0x5b, 0x08, 0x0c, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x08
};

13717
src/test/a2v2-good2.h Normal file

File diff suppressed because it is too large Load Diff

View File

@ -178,6 +178,9 @@ TEST test_load_A2VM_good1() {
// ASSERT framebuffer matches expected
ASSERT_SHA("9C654FEF2A672E16D89ED2FB80C593CD2005A026");
#if MOBILE_DEVICE
// TODO FIXME ... this is a fragile test due to the fact that the disk path [on Desktop] is hardcoded here
#else
// Disk6 ...
ASSERT(disk6.motor_off == 1);
ASSERT(disk6.drive == 0);
@ -200,6 +203,7 @@ TEST test_load_A2VM_good1() {
ASSERT(!disk6.disk[0].track_dirty);
extern int skew_table_6_do[16];
ASSERT(disk6.disk[0].skew_table == skew_table_6_do);
#endif
// VM ...
ASSERT(softswitches == 0x000343d1);
@ -269,8 +273,11 @@ TEST test_load_A2V2_good1() {
ASSERT(ret);
// ASSERT framebuffer matches expected
ASSERT_SHA("EE8AF0ADB3AF477A713B9E5FD02D655CF8371F7B");
ASSERT_SHA("B1CB1C5811B9C629BB077F857CC41DFA8A283E96");
#if MOBILE_DEVICE
// TODO FIXME ... this is a fragile test due to the fact that the disk path [on Desktop] is hardcoded here
#else
// Disk6 ...
ASSERT(disk6.motor_off == 1);
ASSERT(disk6.drive == 0);
@ -293,11 +300,12 @@ TEST test_load_A2V2_good1() {
ASSERT(!disk6.disk[0].track_dirty);
extern int skew_table_6_do[16];
ASSERT(disk6.disk[0].skew_table == skew_table_6_do);
#endif
// VM ...
ASSERT(softswitches == 0x000140f5);
ASSERT_SHA_BIN("0AEA333FBDAE26959719E3BDD6AEFA408784F614", apple_ii_64k[0], /*len:*/sizeof(apple_ii_64k));
ASSERT_SHA_BIN("6D54FC0A19EC396113863C15D607EAE55F369C0D", language_card[0], /*len:*/sizeof(language_card));
ASSERT_SHA_BIN("3B41CCC86A7FCE2A95F1D7A5C4BF7E2AC7A11323", apple_ii_64k[0], /*len:*/sizeof(apple_ii_64k));
ASSERT_SHA_BIN("54C8611AA3FD1813B1BEE45EF7F4B2303C51C679", language_card[0], /*len:*/sizeof(language_card));
ASSERT_SHA_BIN("36F1699537024EC6017A22641FF0EC277AFFD49D", language_banks[0], /*len:*/sizeof(language_banks));
ASSERT(base_ramrd == apple_ii_64k[0]);
ASSERT(base_ramwrt == apple_ii_64k[0]);
@ -314,503 +322,135 @@ TEST test_load_A2V2_good1() {
ASSERT(base_e000_wrt == language_card[0]-0xE000);
// CPU ...
ASSERT(cpu65_pc == 0xF30F);
ASSERT(cpu65_ea == 0xF30E);
ASSERT(cpu65_a == 0x01);
ASSERT(cpu65_f == 0x30);
ASSERT(cpu65_x == 0x0D);
ASSERT(cpu65_y == 0x03);
ASSERT(cpu65_sp == 0xFC);
ASSERT(cpu65_pc == 0xF6EA);
ASSERT(cpu65_ea == 0x0018);
ASSERT(cpu65_a == 0x05);
ASSERT(cpu65_f == 0x33);
ASSERT(cpu65_x == 0x10);
ASSERT(cpu65_y == 0x02);
ASSERT(cpu65_sp == 0xFA);
// Timing ...
long scaleFactor = (long)(cpu_scale_factor * 100.);
ASSERT(scaleFactor = 100);
ASSERT(scaleFactor == 100);
long altScaleFactor = (long)(cpu_altscale_factor * 100.);
ASSERT(altScaleFactor = 200);
ASSERT(altScaleFactor == 200);
ASSERT(alt_speed_enabled);
// Mockingboard ...
{
uint8_t *exData = MALLOC(1024);
uint8_t *p8 = exData;
uint16_t *p16 = 0;
unsigned int *p32 = 0;
unsigned int changeCount = 0;
unsigned long *pL = 0;
unsigned short *pS = 0;
#include "test/a2v2-good1-mb.h"
size_t mbSiz = sizeof(mbData);
mb_testAssertA2V2(mbData, mbSiz);
// ----------------------------------------------------------------- 00
unlink(savData);
FREE(savData);
// --------------- SY6522
PASS();
}
*p8++ = 0x00; // ORA
*p8++ = 0x04; // ORB
*p8++ = 0xFF; // DDRA
*p8++ = 0x07; // DDRB
TEST test_load_A2V2_good2() {
p16 = (uint16_t *)p8;
// ensure stable test
disk6_eject(0);
c_debugger_set_timeout(1);
c_debugger_clear_watchpoints();
c_debugger_go();
c_debugger_set_timeout(0);
*p16++ = 0x02EC; // TIMER1_COUNTER
*p16++ = 0x4FBA; // TIMER1_LATCH
*p16++ = 0xDFDF; // TIMER2_COUNTER
*p16++ = 0x0000; // TIMER2_LATCH
// write saved state to disk
p8 = (uint8_t *)p16;
#include "test/a2v2-good2.h"
*p8++ = 0x00; // SERIAL_SHIFT
*p8++ = 0x40; // ACR
*p8++ = 0x00; // PCR
*p8++ = 0x00; // IFR
*p8++ = 0x40; // IER
// --------------- AY8910
p32 = (unsigned int *)p8;
*p32++ = (unsigned int)105; // ay_tone_tick[0]
*p32++ = (unsigned int)35; // ay_tone_tick[1]
*p32++ = (unsigned int)43; // ay_tone_tick[2]
*p32++ = (unsigned int)1; // ay_tone_high[0]
*p32++ = (unsigned int)0; // ay_tone_high[1]
*p32++ = (unsigned int)0; // ay_tone_high[2]
*p32++ = (unsigned int)1; // ay_noise_tick
*p32++ = (unsigned int)152756; // ay_tone_subcycles
*p32++ = (unsigned int)677044; // ay_env_subcycles
*p32++ = (unsigned int)5; // ay_env_internal_tick
*p32++ = (unsigned int)12; // ay_env_tick
*p32++ = (unsigned int)3033035; // ay_tick_incr
*p32++ = (unsigned int)162; // ay_tone_period[0]
*p32++ = (unsigned int)460; // ay_tone_period[1]
*p32++ = (unsigned int)60; // ay_tone_period[2]
*p32++ = (unsigned int)5; // ay_noise_period
*p32++ = (unsigned int)15; // ay_env_period
*p32++ = (unsigned int)71674; // rng
*p32++ = (unsigned int)1; // noise_toggle
*p32++ = (unsigned int)0; // env_first
*p32++ = (unsigned int)0; // env_rev
*p32++ = (unsigned int)0; // env_counter
p8 = (uint8_t *)p32;
*p8++ = 0xA2; // sound_ay_registers[0]
*p8++ = 0x00; // sound_ay_registers[1]
*p8++ = 0xCC; // sound_ay_registers[2]
*p8++ = 0x01; // sound_ay_registers[3]
*p8++ = 0x3C; // sound_ay_registers[4]
*p8++ = 0x00; // sound_ay_registers[5]
*p8++ = 0x05; // sound_ay_registers[6]
*p8++ = 0xF8; // sound_ay_registers[7]
*p8++ = 0x0D; // sound_ay_registers[8]
*p8++ = 0x0E; // sound_ay_registers[9]
*p8++ = 0x04; // sound_ay_registers[10]
*p8++ = 0x0F; // sound_ay_registers[11]
*p8++ = 0x00; // sound_ay_registers[12]
*p8++ = 0x00; // sound_ay_registers[13]
*p8++ = 0x00; // sound_ay_registers[14]
*p8++ = 0x00; // sound_ay_registers[15]
p32 = (unsigned int *)p8;
changeCount = 13;
*p32++ = changeCount; // ay_change_count
pL = (unsigned long *)p32;
*pL++ = 102; // ay_change[0].tstates
pS = (uint16_t *)pL;
*pS++ = 2; // ay_change[0].ofs
p8 = (uint8_t *)pS;
*p8++ = 0; // ay_change[0].reg
*p8++ = 102; // ay_change[0].val
pL = (unsigned long *)p8;
*pL++ = 159; // ay_change[1].tstates
pS = (uint16_t *)pL;
*pS++ = 3; // ay_change[1].ofs
p8 = (uint8_t *)pS;
*p8++ = 1; // ay_change[1].reg
*p8++ = 0; // ay_change[1].val
pL = (unsigned long *)p8;
*pL++ = 216; // ay_change[2].tstates
pS = (uint16_t *)pL;
*pS++ = 4; // ay_change[2].ofs
p8 = (uint8_t *)pS;
*p8++ = 2; // ay_change[2].reg
*p8++ = 102; // ay_change[2].val
pL = (unsigned long *)p8;
*pL++ = 273; // ay_change[3].tstates
pS = (uint16_t *)pL;
*pS++ = 5; // ay_change[3].ofs
p8 = (uint8_t *)pS;
*p8++ = 3; // ay_change[3].reg
*p8++ = 2; // ay_change[3].val
pL = (unsigned long *)p8;
*pL++ = 330; // ay_change[4].tstates
pS = (uint16_t *)pL;
*pS++ = 7; // ay_change[4].ofs
p8 = (uint8_t *)pS;
*p8++ = 4; // ay_change[4].reg
*p8++ = 60; // ay_change[4].val
pL = (unsigned long *)p8;
*pL++ = 387; // ay_change[5].tstates
pS = (uint16_t *)pL;
*pS++ = 8; // ay_change[5].ofs
p8 = (uint8_t *)pS;
*p8++ = 5; // ay_change[5].reg
*p8++ = 0; // ay_change[5].val
pL = (unsigned long *)p8;
*pL++ = 444; // ay_change[6].tstates
pS = (uint16_t *)pL;
*pS++ = 9; // ay_change[6].ofs
p8 = (uint8_t *)pS;
*p8++ = 6; // ay_change[6].reg
*p8++ = 5; // ay_change[6].val
pL = (unsigned long *)p8;
*pL++ = 501; // ay_change[7].tstates
pS = (uint16_t *)pL;
*pS++ = 10; // ay_change[7].ofs
p8 = (uint8_t *)pS;
*p8++ = 7; // ay_change[7].reg
*p8++ = 248; // ay_change[7].val
pL = (unsigned long *)p8;
*pL++ = 563; // ay_change[8].tstates
pS = (uint16_t *)pL;
*pS++ = 12; // ay_change[8].ofs
p8 = (uint8_t *)pS;
*p8++ = 8; // ay_change[8].reg
*p8++ = 13; // ay_change[8].val
pL = (unsigned long *)p8;
*pL++ = 621; // ay_change[9].tstates
pS = (uint16_t *)pL;
*pS++ = 13; // ay_change[9].ofs
p8 = (uint8_t *)pS;
*p8++ = 9; // ay_change[9].reg
*p8++ = 14; // ay_change[9].val
pL = (unsigned long *)p8;
*pL++ = 679; // ay_change[10].tstates
pS = (uint16_t *)pL;
*pS++ = 14; // ay_change[10].ofs
p8 = (uint8_t *)pS;
*p8++ = 10; // ay_change[10].reg
*p8++ = 3; // ay_change[10].val
pL = (unsigned long *)p8;
*pL++ = 731; // ay_change[11].tstates
pS = (uint16_t *)pL;
*pS++ = 15; // ay_change[11].ofs
p8 = (uint8_t *)pS;
*p8++ = 11; // ay_change[11].reg
*p8++ = 15; // ay_change[11].val
pL = (unsigned long *)p8;
*pL++ = 788; // ay_change[12].tstates
pS = (uint16_t *)pL;
*pS++ = 17; // ay_change[12].ofs
p8 = (uint8_t *)pS;
*p8++ = 12; // ay_change[12].reg
*p8++ = 0; // ay_change[12].val
// --------------- SSI263
*p8++ = 0x00; // DurationPhoneme
*p8++ = 0x00; // Inflection
*p8++ = 0x00; // RateInflection
*p8++ = 0x00; // CtrlArtAmp
*p8++ = 0x00; // FilterFreq
*p8++ = 0x00; // CurrentMode
// ---------------
*p8++ = 0x0C; // nAYCurrentRegister
// ----------------------------------------------------------------- 01
// --------------- SY6522
*p8++ = 0x00; // ORA
*p8++ = 0x04; // ORB
*p8++ = 0xFF; // DDRA
*p8++ = 0x07; // DDRB
p16 = (uint16_t *)p8;
*p16++ = 0xDFDF; // TIMER1_COUNTER
*p16++ = 0x0000; // TIMER1_LATCH
*p16++ = 0xDFDF; // TIMER2_COUNTER
*p16++ = 0x0000; // TIMER2_LATCH
p8 = (uint8_t *)p16;
*p8++ = 0x00; // SERIAL_SHIFT
*p8++ = 0x00; // ACR
*p8++ = 0x00; // PCR
*p8++ = 0x00; // IFR
*p8++ = 0x00; // IER
// --------------- AY8910
p32 = (unsigned int *)p8;
*p32++ = (unsigned int)17; // ay_tone_tick[0]
*p32++ = (unsigned int)416; // ay_tone_tick[1]
*p32++ = (unsigned int)27; // ay_tone_tick[2]
*p32++ = (unsigned int)1; // ay_tone_high[0]
*p32++ = (unsigned int)0; // ay_tone_high[1]
*p32++ = (unsigned int)0; // ay_tone_high[2]
*p32++ = (unsigned int)0; // ay_noise_tick
*p32++ = (unsigned int)152756; // ay_tone_subcycles
*p32++ = (unsigned int)677044; // ay_env_subcycles
*p32++ = (unsigned int)10; // ay_env_internal_tick
*p32++ = (unsigned int)13; // ay_env_tick
*p32++ = (unsigned int)3033035; // ay_tick_incr
*p32++ = (unsigned int)121; // ay_tone_period[0]
*p32++ = (unsigned int)547; // ay_tone_period[1]
*p32++ = (unsigned int)60; // ay_tone_period[2]
*p32++ = (unsigned int)5; // ay_noise_period
*p32++ = (unsigned int)15; // ay_env_period
*p32++ = (unsigned int)55289; // rng
*p32++ = (unsigned int)0; // noise_toggle
*p32++ = (unsigned int)0; // env_first
*p32++ = (unsigned int)0; // env_rev
*p32++ = (unsigned int)0; // env_counter
p8 = (uint8_t *)p32;
*p8++ = 0x79; // sound_ay_registers[0]
*p8++ = 0x00; // sound_ay_registers[1]
*p8++ = 0x23; // sound_ay_registers[2]
*p8++ = 0x02; // sound_ay_registers[3]
*p8++ = 0x3C; // sound_ay_registers[4]
*p8++ = 0x00; // sound_ay_registers[5]
*p8++ = 0x05; // sound_ay_registers[6]
*p8++ = 0xF8; // sound_ay_registers[7]
*p8++ = 0x0D; // sound_ay_registers[8]
*p8++ = 0x0E; // sound_ay_registers[9]
*p8++ = 0x04; // sound_ay_registers[10]
*p8++ = 0x0F; // sound_ay_registers[11]
*p8++ = 0x00; // sound_ay_registers[12]
*p8++ = 0x00; // sound_ay_registers[13]
*p8++ = 0x00; // sound_ay_registers[14]
*p8++ = 0x00; // sound_ay_registers[15]
p32 = (unsigned int *)p8;
changeCount = 0;
*p32++ = changeCount; // ay_change_count
p8 = (uint8_t *)p32;
// --------------- SSI263
*p8++ = 0x00; // DurationPhoneme
*p8++ = 0x00; // Inflection
*p8++ = 0x00; // RateInflection
*p8++ = 0x00; // CtrlArtAmp
*p8++ = 0x00; // FilterFreq
*p8++ = 0x00; // CurrentMode
// ---------------
*p8++ = 0x0C; // nAYCurrentRegister
// ----------------------------------------------------------------- 02
// --------------- SY6522
*p8++ = 0x00; // ORA
*p8++ = 0x00; // ORB
*p8++ = 0x00; // DDRA
*p8++ = 0x00; // DDRB
p16 = (uint16_t *)p8;
*p16++ = 0xDFDF; // TIMER1_COUNTER
*p16++ = 0x0000; // TIMER1_LATCH
*p16++ = 0xDFDF; // TIMER2_COUNTER
*p16++ = 0x0000; // TIMER2_LATCH
p8 = (uint8_t *)p16;
*p8++ = 0x00; // SERIAL_SHIFT
*p8++ = 0x00; // ACR
*p8++ = 0x00; // PCR
*p8++ = 0x00; // IFR
*p8++ = 0x00; // IER
// --------------- AY8910
p32 = (unsigned int *)p8;
*p32++ = (unsigned int)0; // ay_tone_tick[0]
*p32++ = (unsigned int)0; // ay_tone_tick[1]
*p32++ = (unsigned int)0; // ay_tone_tick[2]
*p32++ = (unsigned int)1; // ay_tone_high[0]
*p32++ = (unsigned int)1; // ay_tone_high[1]
*p32++ = (unsigned int)1; // ay_tone_high[2]
*p32++ = (unsigned int)3529473; // ay_noise_tick
*p32++ = (unsigned int)234404; // ay_tone_subcycles
*p32++ = (unsigned int)758692; // ay_env_subcycles
*p32++ = (unsigned int)1; // ay_env_internal_tick
*p32++ = (unsigned int)3529473; // ay_env_tick
*p32++ = (unsigned int)3033035; // ay_tick_incr
*p32++ = (unsigned int)1; // ay_tone_period[0]
*p32++ = (unsigned int)1; // ay_tone_period[1]
*p32++ = (unsigned int)1; // ay_tone_period[2]
*p32++ = (unsigned int)0; // ay_noise_period
*p32++ = (unsigned int)0; // ay_env_period
*p32++ = (unsigned int)71376; // rng
*p32++ = (unsigned int)1; // noise_toggle
*p32++ = (unsigned int)0; // env_first
*p32++ = (unsigned int)0; // env_rev
*p32++ = (unsigned int)0; // env_counter
p8 = (uint8_t *)p32;
*p8++ = 0x00; // sound_ay_registers[0]
*p8++ = 0x00; // sound_ay_registers[1]
*p8++ = 0x00; // sound_ay_registers[2]
*p8++ = 0x00; // sound_ay_registers[3]
*p8++ = 0x00; // sound_ay_registers[4]
*p8++ = 0x00; // sound_ay_registers[5]
*p8++ = 0x00; // sound_ay_registers[6]
*p8++ = 0x00; // sound_ay_registers[7]
*p8++ = 0x00; // sound_ay_registers[8]
*p8++ = 0x00; // sound_ay_registers[9]
*p8++ = 0x00; // sound_ay_registers[10]
*p8++ = 0x00; // sound_ay_registers[11]
*p8++ = 0x00; // sound_ay_registers[12]
*p8++ = 0x00; // sound_ay_registers[13]
*p8++ = 0x00; // sound_ay_registers[14]
*p8++ = 0x00; // sound_ay_registers[15]
p32 = (unsigned int *)p8;
changeCount = 0;
*p32++ = changeCount; // ay_change_count
p8 = (uint8_t *)p32;
// --------------- SSI263
*p8++ = 0x00; // DurationPhoneme
*p8++ = 0x00; // Inflection
*p8++ = 0x00; // RateInflection
*p8++ = 0x00; // CtrlArtAmp
*p8++ = 0x00; // FilterFreq
*p8++ = 0x00; // CurrentMode
// ---------------
*p8++ = 0x00; // nAYCurrentRegister
// ----------------------------------------------------------------- 03
// --------------- SY6522
*p8++ = 0x00; // ORA
*p8++ = 0x00; // ORB
*p8++ = 0x00; // DDRA
*p8++ = 0x00; // DDRB
p16 = (uint16_t *)p8;
*p16++ = 0xDFDF; // TIMER1_COUNTER
*p16++ = 0x0000; // TIMER1_LATCH
*p16++ = 0xDFDF; // TIMER2_COUNTER
*p16++ = 0x0000; // TIMER2_LATCH
p8 = (uint8_t *)p16;
*p8++ = 0x00; // SERIAL_SHIFT
*p8++ = 0x00; // ACR
*p8++ = 0x00; // PCR
*p8++ = 0x00; // IFR
*p8++ = 0x00; // IER
// --------------- AY8910
p32 = (unsigned int *)p8;
*p32++ = (unsigned int)0; // ay_tone_tick[0]
*p32++ = (unsigned int)0; // ay_tone_tick[1]
*p32++ = (unsigned int)0; // ay_tone_tick[2]
*p32++ = (unsigned int)1; // ay_tone_high[0]
*p32++ = (unsigned int)1; // ay_tone_high[1]
*p32++ = (unsigned int)1; // ay_tone_high[2]
*p32++ = (unsigned int)3529473; // ay_noise_tick
*p32++ = (unsigned int)234404; // ay_tone_subcycles
*p32++ = (unsigned int)758692; // ay_env_subcycles
*p32++ = (unsigned int)1; // ay_env_internal_tick
*p32++ = (unsigned int)3529473; // ay_env_tick
*p32++ = (unsigned int)3033035; // ay_tick_incr
*p32++ = (unsigned int)1; // ay_tone_period[0]
*p32++ = (unsigned int)1; // ay_tone_period[1]
*p32++ = (unsigned int)1; // ay_tone_period[2]
*p32++ = (unsigned int)0; // ay_noise_period
*p32++ = (unsigned int)0; // ay_env_period
*p32++ = (unsigned int)71376; // rng
*p32++ = (unsigned int)1; // noise_toggle
*p32++ = (unsigned int)0; // env_first
*p32++ = (unsigned int)0; // env_rev
*p32++ = (unsigned int)0; // env_counter
p8 = (uint8_t *)p32;
*p8++ = 0x00; // sound_ay_registers[0]
*p8++ = 0x00; // sound_ay_registers[1]
*p8++ = 0x00; // sound_ay_registers[2]
*p8++ = 0x00; // sound_ay_registers[3]
*p8++ = 0x00; // sound_ay_registers[4]
*p8++ = 0x00; // sound_ay_registers[5]
*p8++ = 0x00; // sound_ay_registers[6]
*p8++ = 0x00; // sound_ay_registers[7]
*p8++ = 0x00; // sound_ay_registers[8]
*p8++ = 0x00; // sound_ay_registers[9]
*p8++ = 0x00; // sound_ay_registers[10]
*p8++ = 0x00; // sound_ay_registers[11]
*p8++ = 0x00; // sound_ay_registers[12]
*p8++ = 0x00; // sound_ay_registers[13]
*p8++ = 0x00; // sound_ay_registers[14]
*p8++ = 0x00; // sound_ay_registers[15]
p32 = (unsigned int *)p8;
changeCount = 0;
*p32++ = changeCount; // ay_change_count
p8 = (uint8_t *)p32;
// --------------- SSI263
*p8++ = 0x00; // DurationPhoneme
*p8++ = 0x00; // Inflection
*p8++ = 0x00; // RateInflection
*p8++ = 0x00; // CtrlArtAmp
*p8++ = 0x00; // FilterFreq
*p8++ = 0x00; // CurrentMode
// ---------------
*p8++ = 0x00; // nAYCurrentRegister
// --------------------------------------------------------------------
size_t exSiz = p8 - exData;
ASSERT(exSiz <= 1024);
mb_testAssertA2V2(exData, exSiz);
FREE(exData);
const char *homedir = HOMEDIR;
char *savData = NULL;
ASPRINTF(&savData, "%s/a2_emul_a2v2.dat", homedir);
if (savData) {
unlink(savData);
}
FILE *fp = fopen(savData, "w");
ASSERT(fp);
size_t dataSiz = sizeof(data);
if (fwrite(data, 1, dataSiz, fp) != dataSiz) {
ASSERT(false);
}
fflush(fp); fclose(fp); fp = NULL;
// load state and assert
bool ret = emulator_loadState(savData);
ASSERT(ret);
// ASSERT framebuffer matches expected
ASSERT_SHA("7A60972EF2E95956249454402A42C12E7C8FBF7A");
#if MOBILE_DEVICE
// TODO FIXME ... this is a fragile test due to the fact that the disk path [on Desktop] is hardcoded here
#else
// Disk6 ...
ASSERT(disk6.motor_off == 1);
ASSERT(disk6.drive == 0);
ASSERT(disk6.ddrw == 0);
ASSERT(disk6.disk_byte == 0xAA);
extern int stepper_phases;
ASSERT(stepper_phases == 0x0);
ASSERT(disk6.disk[0].is_protected);
const char *file_name = strrchr(disk6.disk[0].file_name, '/');
ASSERT(strcmp(file_name, "/u5boot.do") == 0);
ASSERT(disk6.disk[0].phase == 58);
ASSERT(disk6.disk[0].run_byte == 1208);
ASSERT(disk6.disk[0].fd > 0);
ASSERT(disk6.disk[0].mmap_image != 0);
ASSERT(disk6.disk[0].mmap_image != MAP_FAILED);
ASSERT(disk6.disk[0].whole_len == 143360);
ASSERT(disk6.disk[0].whole_image != NULL);
ASSERT(disk6.disk[0].track_width == BLANK_TRACK_WIDTH);
ASSERT(!disk6.disk[0].nibblized);
ASSERT(!disk6.disk[0].track_dirty);
extern int skew_table_6_do[16];
ASSERT(disk6.disk[0].skew_table == skew_table_6_do);
#endif
// VM ...
ASSERT(softswitches == 0x000140f4);
ASSERT_SHA_BIN("CAD59B53F04DE501A76E0C04750155C838EADAE2", apple_ii_64k[0], /*len:*/sizeof(apple_ii_64k));
ASSERT_SHA_BIN("B3268356F9F4F4ACAE2F4FF49D4FED1D36535DDA", language_card[0], /*len:*/sizeof(language_card));
ASSERT_SHA_BIN("0B6E45306506F92554102485CE9B500C6779D145", language_banks[0], /*len:*/sizeof(language_banks));
ASSERT(base_ramrd == apple_ii_64k[0]);
ASSERT(base_ramwrt == apple_ii_64k[0]);
ASSERT(base_textrd == apple_ii_64k[0]);
ASSERT(base_textwrt == apple_ii_64k[0]);
ASSERT(base_hgrrd == apple_ii_64k[0]);
ASSERT(base_hgrwrt == apple_ii_64k[0]);
ASSERT(base_stackzp == apple_ii_64k[0]);
ASSERT(base_c3rom == apple_ii_64k[1]);
ASSERT(base_cxrom == (void *)&iie_read_peripheral_card);
ASSERT(base_d000_rd == language_banks[0]-0xD000);
ASSERT(base_d000_wrt == language_banks[0]-0xD000);
ASSERT(base_e000_rd == language_card[0]-0xE000);
ASSERT(base_e000_wrt == language_card[0]-0xE000);
// CPU ...
ASSERT(cpu65_pc == 0x8474);
ASSERT(cpu65_ea == 0x8474);
ASSERT(cpu65_a == 0x00);
ASSERT(cpu65_f == 0x73);
ASSERT(cpu65_x == 0x04);
ASSERT(cpu65_y == 0x21);
ASSERT(cpu65_sp == 0xF1);
// Timing ...
long scaleFactor = (long)(cpu_scale_factor * 100.);
ASSERT(scaleFactor == 100);
long altScaleFactor = (long)(cpu_altscale_factor * 100.);
ASSERT(altScaleFactor == 75);
ASSERT(alt_speed_enabled);
// Mockingboard ...
#include "test/a2v2-good2-mb.h"
size_t mbSiz = sizeof(mbData);
mb_testAssertA2V2(mbData, mbSiz);
unlink(savData);
FREE(savData);
@ -837,6 +477,7 @@ GREATEST_SUITE(test_suite_ui) {
RUN_TESTp(test_load_A2VM_good1);
RUN_TESTp(test_load_A2V2_good1);
RUN_TESTp(test_load_A2V2_good2);
#if INTERFACE_TOUCH
# warning TODO : touch joystick(s), keyboard, mouse, menu

View File

@ -575,15 +575,27 @@ bool timing_saveState(StateHelper_s *helper) {
int fd = helper->fd;
do {
long lVal = 0;
uint32_t lVal = 0;
uint8_t serialized[4] = { 0 };
lVal = (long)(cpu_scale_factor * 100.);
if (!helper->save(fd, (uint8_t *)&lVal, sizeof(lVal))) {
assert(cpu_scale_factor >= 0);
assert(cpu_altscale_factor >= 0);
lVal = (uint32_t)(cpu_scale_factor * 100.);
serialized[0] = (uint8_t)((lVal & 0xFF000000) >> 24);
serialized[1] = (uint8_t)((lVal & 0xFF0000 ) >> 16);
serialized[2] = (uint8_t)((lVal & 0xFF00 ) >> 8);
serialized[3] = (uint8_t)((lVal & 0xFF ) >> 0);
if (!helper->save(fd, serialized, sizeof(serialized))) {
break;
}
lVal = (long)(cpu_altscale_factor * 100.);
if (!helper->save(fd, (uint8_t *)&lVal, sizeof(lVal))) {
serialized[0] = (uint8_t)((lVal & 0xFF000000) >> 24);
serialized[1] = (uint8_t)((lVal & 0xFF0000 ) >> 16);
serialized[2] = (uint8_t)((lVal & 0xFF00 ) >> 8);
serialized[3] = (uint8_t)((lVal & 0xFF ) >> 0);
if (!helper->save(fd, serialized, sizeof(serialized))) {
break;
}
@ -603,16 +615,25 @@ bool timing_loadState(StateHelper_s *helper) {
int fd = helper->fd;
do {
long lVal = 0;
uint32_t lVal = 0;
uint8_t serialized[4] = { 0 };
if (!helper->load(fd, (uint8_t *)&lVal, sizeof(lVal))) {
if (!helper->load(fd, serialized, sizeof(uint32_t))) {
break;
}
lVal = (uint32_t)(serialized[0] << 24);
lVal |= (uint32_t)(serialized[1] << 16);
lVal |= (uint32_t)(serialized[2] << 8);
lVal |= (uint32_t)(serialized[3] << 0);
cpu_scale_factor = lVal / 100.;
if (!helper->load(fd, (uint8_t *)&lVal, sizeof(lVal))) {
if (!helper->load(fd, serialized, sizeof(uint32_t))) {
break;
}
lVal = (uint32_t)(serialized[0] << 24);
lVal |= (uint32_t)(serialized[1] << 16);
lVal |= (uint32_t)(serialized[2] << 8);
lVal |= (uint32_t)(serialized[3] << 0);
cpu_altscale_factor = lVal / 100.;
uint8_t bVal = 0;