Skip to content

Commit

Permalink
Calculate variable versions when needed, set product ID field of expo…
Browse files Browse the repository at this point in the history
…rted files. Fixes #334.
  • Loading branch information
calc84maniac committed Jul 9, 2024
1 parent 7d1788f commit 25ff8e8
Show file tree
Hide file tree
Showing 3 changed files with 133 additions and 29 deletions.
18 changes: 16 additions & 2 deletions core/link.c
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,7 @@
#define ADDR_ERRNO 0xD008DF
#define ADDR_PRGM_SIZE 0xD0118C

#define FILE_PRODUCT_ID 0x0A
#define FILE_DATA 0x35
#define FILE_DATA_START 0x37

Expand Down Expand Up @@ -74,6 +75,7 @@ int emu_receive_variable(const char *file, const calc_var_t *vars, int count) {
FILE *fd;
calc_var_t var;
uint16_t header_size = 13, size = 0, checksum = 0;
uint8_t max_version = 0, product_id;
int byte;

fd = fopen_utf8(file, "w+b");
Expand All @@ -94,15 +96,27 @@ int emu_receive_variable(const char *file, const calc_var_t *vars, int count) {
if (write_le16(var.size, fd) != 1) goto w_err;
if (fwrite(var.data, var.size, 1, fd) != 1) goto w_err;
size += 17 + var.size;
if ((var.version & ~0x20) > max_version) {
max_version = var.version & ~0x20;
}
}
if (max_version > 0x0A) {
product_id = 0x13;
} else if (max_version == 0x0A) {
product_id = 0x0F;
} else {
product_id = 0x0A;
}
if (fseek(fd, FILE_PRODUCT_ID, SEEK_SET)) goto w_err;
if (fputc(product_id, fd) == EOF) goto w_err;
if (fseek(fd, FILE_DATA, SEEK_SET)) goto w_err;
if (write_le16(size, fd) != 1) goto w_err;
if (write_le16(size, fd) != 1) goto w_err;
if (fflush(fd)) goto w_err;
while (size--) {
if ((byte = fgetc(fd)) == EOF) goto w_err;
checksum += byte;
}
if (write_le16(checksum, fd) != 1) goto w_err;
if (write_le16(checksum, fd) != 1) goto w_err;
(void)fclose(fd);

return LINK_GOOD;
Expand Down
112 changes: 112 additions & 0 deletions core/vat.c
Original file line number Diff line number Diff line change
Expand Up @@ -211,6 +211,54 @@ const char *calc_var_name_to_utf8(uint8_t name[8], bool named) {
return buffer;
}

static uint8_t calc_tokenized_var_version(const calc_var_t *var) {
static const uint8_t twoByteTokens[] = {0x5C, 0x5D, 0x5E, 0x60, 0x61, 0x62, 0x63, 0x7E, 0xBB, 0xAA, 0xEF};
bool usesRTC = false;
int maxBB = -1;
int maxEF = -1;
uint16_t offset = 2;
while (offset < var->size) {
uint8_t firstByte = var->data[offset++];
if (memchr(twoByteTokens, firstByte, sizeof(twoByteTokens)) != NULL) {
if (offset >= var->size) {
break;
}
uint8_t secondByte = var->data[offset++];
if (firstByte == 0xBB) {
if (secondByte > maxBB) maxBB = secondByte;
} else if (firstByte == 0xEF) {
if (secondByte <= 0x10) usesRTC = true;
if (secondByte > maxEF) maxEF = secondByte;
}
}
}
uint8_t version = usesRTC ? 0x20 : 0x00;
if (maxBB > 0xF5 || maxEF > 0xA6) {
version = 0xFF;
} else if (maxEF > 0x98) {
version |= 0x0C;
} else if (maxEF > 0x75) {
version |= 0x0B;
} else if (maxEF > 0x40) {
version |= 0x0A;
} else if (maxEF > 0x3E) {
version |= 0x07;
} else if (maxEF > 0x16) {
version |= 0x06;
} else if (maxEF > 0x12) {
version |= 0x05;
} else if (maxEF > -1) {
version |= 0x04;
} else if (maxBB > 0xDA) {
version |= 0x03;
} else if (maxBB > 0xCE) {
version |= 0x02;
} else if (maxBB > 0x67) {
version |= 0x01;
}
return version;
}

void vat_search_init(calc_var_t *var) {
memset(var, 0, sizeof *var);
var->vat = 0xD3FFFF;
Expand Down Expand Up @@ -250,6 +298,7 @@ bool vat_search_next(calc_var_t *var) {
switch (var->type) {
case CALC_VAR_TYPE_REAL:
case CALC_VAR_TYPE_REAL_FRAC:
case CALC_VAR_TYPE_MIXED_FRAC:
case CALC_VAR_TYPE_REAL_RADICAL:
case CALC_VAR_TYPE_REAL_PI:
case CALC_VAR_TYPE_REAL_PI_FRAC:
Expand Down Expand Up @@ -277,11 +326,74 @@ bool vat_search_next(calc_var_t *var) {
break;
}
var->data = phys_mem_ptr(var->address, var->size);
if (var->data == NULL) {
return false;
}
for (i = 0; i != var->namelen; i++) {
var->name[i] = mem_peek_byte(var->vat--);
}
memset(&var->name[i], 0, sizeof var->name - i);

if (!var->archived) {
switch (var->type) {
case CALC_VAR_TYPE_REAL:
case CALC_VAR_TYPE_REAL_FRAC:
case CALC_VAR_TYPE_MIXED_FRAC:
var->type = CALC_VAR_TYPE_REAL;
i = var->data[0] & 0x3F;
if (i == CALC_VAR_TYPE_REAL) {
var->version = 0x00;
} else {
var->version = 0x06;
}
break;

case CALC_VAR_TYPE_CPLX:
case CALC_VAR_TYPE_CPLX_FRAC:
case CALC_VAR_TYPE_CPLX_RADICAL:
case CALC_VAR_TYPE_CPLX_PI:
case CALC_VAR_TYPE_CPLX_PI_FRAC:
i = var->data[0] & 0x3F;
if (i == CALC_VAR_TYPE_CPLX) {
var->version = 0x00;
} else if (i == CALC_VAR_TYPE_CPLX_FRAC) {
var->version = 0x0B;
} else {
var->version = 0x10;
}
break;

case CALC_VAR_TYPE_REAL_LIST:
case CALC_VAR_TYPE_MATRIX:
case CALC_VAR_TYPE_CPLX_LIST:
var->version = 0x00;
for (uint16_t offset = 2; offset < var->size; offset += 9) {
i = var->data[offset] & 0x3F;
if (i > CALC_VAR_TYPE_CPLX_FRAC) {
var->version = 0x10;
break;
} else if (i == CALC_VAR_TYPE_CPLX_FRAC) {
if (var->version < 0x0B) var->version = 0x0B;
} else if (i == CALC_VAR_TYPE_REAL_FRAC || i == CALC_VAR_TYPE_MIXED_FRAC) {
if (var->version < 0x06) var->version = 0x06;
}
}
break;

case CALC_VAR_TYPE_EQU:
case CALC_VAR_TYPE_STRING:
case CALC_VAR_TYPE_NEW_EQU:
var->version = calc_tokenized_var_version(var);
break;

default:
if (var->type > CALC_VAR_TYPE_CPLX_FRAC) {
var->version = 0x10;
}
break;
}
}

return true;
}

Expand Down
32 changes: 5 additions & 27 deletions core/vat.h
Original file line number Diff line number Diff line change
Expand Up @@ -34,7 +34,7 @@ typedef enum calc_var_type {
CALC_VAR_TYPE_TEMP_PROG,
CALC_VAR_TYPE_GROUP,
CALC_VAR_TYPE_REAL_FRAC,
CALC_VAR_TYPE_UNKNOWN1,
CALC_VAR_TYPE_MIXED_FRAC,
CALC_VAR_TYPE_IMAGE,
CALC_VAR_TYPE_CPLX_FRAC,
CALC_VAR_TYPE_REAL_RADICAL,
Expand All @@ -43,36 +43,14 @@ typedef enum calc_var_type {
CALC_VAR_TYPE_CPLX_PI_FRAC,
CALC_VAR_TYPE_REAL_PI,
CALC_VAR_TYPE_REAL_PI_FRAC,
CALC_VAR_TYPE_UNKNOWN2,
CALC_VAR_TYPE_OPERATING_SYSTEM,
CALC_VAR_TYPE_OPERATING_SYSTEM = 0x23,
CALC_VAR_TYPE_FLASH_APP,
CALC_VAR_TYPE_CERTIFICATE,
CALC_VAR_TYPE_UNKNOWN3,
CALC_VAR_TYPE_APPID_LIST,
CALC_VAR_TYPE_CERTIFICATE_MEMORY,
CALC_VAR_TYPE_UNKNOWN4,
CALC_VAR_TYPE_UNIT_CERTIFICATE,
CALC_VAR_TYPE_CLOCK,
CALC_VAR_TYPE_UNKNOWN5,
CALC_VAR_TYPE_UNKNOWN6,
CALC_VAR_TYPE_UNKNOWN7,
CALC_VAR_TYPE_UNKNOWN8,
CALC_VAR_TYPE_UNKNOWN9,
CALC_VAR_TYPE_UNKNOWN10,
CALC_VAR_TYPE_UNKNOWN11,
CALC_VAR_TYPE_UNKNOWN12,
CALC_VAR_TYPE_UNKNOWN13,
CALC_VAR_TYPE_UNKNOWN14,
CALC_VAR_TYPE_UNKNOWN15,
CALC_VAR_TYPE_UNKNOWN16,
CALC_VAR_TYPE_UNKNOWN17,
CALC_VAR_TYPE_UNKNOWN18,
CALC_VAR_TYPE_UNKNOWN19,
CALC_VAR_TYPE_UNKNOWN20,
CALC_VAR_TYPE_UNKNOWN21,
CALC_VAR_TYPE_UNKNOWN22,
CALC_VAR_TYPE_UNKNOWN23,
CALC_VAR_TYPE_UNKNOWN24,
CALC_VAR_TYPE_FLASH_LICENSE,
CALC_VAR_TYPE_UNKNOWN25
CALC_VAR_TYPE_FLASH_LICENSE = 0x3E
} calc_var_type_t;

extern const char *calc_var_type_names[0x40];
Expand Down

0 comments on commit 25ff8e8

Please sign in to comment.