22#define CAP_MIN_SCATTER_PREFIX_CARDS 4
23#define CAP_MIN_ISOLATION_CARDS 8
49 int newcap = d->
cap ? d->
cap * 2 : 16;
51 (
size_t)newcap *
sizeof(
struct cap_card));
68 int newcap = c->
cap ? c->
cap * 2 : 80;
69 uint16_t *tmp = realloc(c->
cols, (
size_t)newcap *
sizeof(uint16_t));
85 if (!s || strlen(s) != 4)
87 return isxdigit((
unsigned char)s[0]) &&
88 isxdigit((
unsigned char)s[1]) &&
89 isxdigit((
unsigned char)s[2]) &&
90 isxdigit((
unsigned char)s[3]);
99 const char prefix[] =
"Card n. ";
100 const size_t plen =
sizeof(prefix) - 1;
101 if (strncmp(line, prefix, plen) != 0)
103 const char *p = line + plen;
105 if (!isdigit((
unsigned char)*p))
108 long n = strtol(p, &end, 10);
112 while (*end && (isspace((
unsigned char)*end) || *end ==
'\r'))
129 FILE *fp = fopen(path,
"r");
142 while (fgets(line,
sizeof(line), fp)) {
144 size_t len = strlen(line);
145 while (len > 0 && (line[len-1] ==
'\n' || line[len-1] ==
'\r'))
170 strncpy(linecopy, line,
sizeof(linecopy) - 1);
171 linecopy[
sizeof(linecopy) - 1] =
'\0';
173 tok = strtok(linecopy,
" \t\r\n");
176 uint16_t val = (uint16_t)strtoul(tok, NULL, 16);
181 tok = strtok(NULL,
" \t\r\n");
197 return calloc(1,
sizeof(
struct cap_deck));
209 if (!d || i < 0 || i >= d->
ncards)
216 if (!d || i < 0 || i >= d->
ncards)
231 for (
int i = 0; i <
ncols; i++) {
245 fp = fopen(path,
"w");
249 fprintf(fp,
"Generated by gemu cap_save\n");
250 for (
int i = 0; i < d->
ncards; i++) {
252 fprintf(fp,
"Card n. %d\n", i + 1);
253 for (
int j = 0; j < c->
ncols; j++)
254 fprintf(fp,
"%04X%c", c->
cols[j] & 0x1FFFu, (j + 1 == c->
ncols) ?
'\n' :
' ');
267 for (
int i = 0; i < d->
ncards; i++)
282 for (
int i = 0; i < n; i++)
293 for (
int r = 0; r <= 12; r++) {
299 if (n == 1 && rows[0] >= 0 && rows[0] <= 9)
300 return (
char)(
'0' + rows[0]);
301 if (n == 2 && rows[0] == 1 && rows[1] == 12)
303 if (n == 2 && rows[0] == 2 && rows[1] == 12)
305 if (n == 2 && rows[0] == 3 && rows[1] == 12)
313 char id[3] = { a, b, c };
315 for (
int i = 0; i < 3; i++) {
316 if (
id[i] >=
'0' &&
id[i] <=
'9')
318 else if (
id[i] >=
'A' &&
id[i] <=
'C')
319 v[i] = 10 + (
id[i] -
'A');
324 return (v[0] << 8) | (v[1] << 4) | v[2];
330 uint8_t out[8],
int *eligible_cards)
333 struct { uint8_t p[8];
int cnt; } tab[1024];
334 int ntab = 0, best = -1;
337 for (
int i = 0; i < nc; i++) {
340 if (ncols < 11 || !cols)
348 for (j = 0; j < ntab; j++) {
349 if (memcmp(tab[j].p, b, 8) == 0) {
354 if (j == ntab && ntab < 1024) {
355 memcpy(tab[ntab].p, b, 8);
361 for (
int j = 0; j < ntab; j++) {
362 if (best < 0 || tab[j].cnt > tab[best].cnt)
369 *eligible_cards = eligible;
370 memcpy(out, tab[best].p, 8);
371 return tab[best].cnt;
398 int have_prev_iso = 0;
407 if (ncols < 80 || !cols)
416 if (have_prev_iso && idv == prev_iso + 1)
443 unsigned *lo,
unsigned *hi)
459 int loose = !have_prefix;
463 long min_a = -1, max_a = -1;
465 for (
int i = 0; i < nc; i++) {
468 if (ncols < 11 || !cols)
474 int match = (have_prefix && n >= 8 && memcmp(b, want, 8) == 0);
476 long addr = ((long)b[9] << 8) | b[10];
478 int fits = (11 + ll < n) && (addr + ll <= 0xFFFF);
480 if (!(loose ? fits : (match && fits)))
483 for (
int k = 0; k < paylen; k++)
484 image[addr + k] = b[11 + k];
486 if (min_a < 0 || addr < min_a)
488 if (addr + ll > max_a)
495 if (loaded == 0 || min_a < 0)
499 *lo = (unsigned)min_a;
501 *hi = (unsigned)max_a;
506 unsigned org,
unsigned *lo,
unsigned *hi)
528 if (ncols < 80 || !cols)
535 if (off + 75 > 0xFFFF) {
540 for (
int k = 0; k < 76; k++)
552 if (loaded == 0 || min_a < 0)
556 *lo = (unsigned)min_a;
558 *hi = (unsigned)max_a;
const uint16_t * cap_card_columns(const struct cap_deck *d, int i)
static int is_hex4(const char *s)
static int parse_card_header(const char *line, int *card_num)
int cap_append_card(struct cap_deck *d, const uint16_t *cols, int ncols)
const char * cap_family_name(enum cap_deck_family family)
#define CAP_MIN_SCATTER_PREFIX_CARDS
static int card_add_col(struct cap_card *c, uint16_t val)
static int isolation_ident_value(char a, char b, char c)
static int scat_decode_card(const uint16_t *cols, int ncols, int mode, uint8_t out[80])
int cap_card_ncols(const struct cap_deck *d, int i)
struct cap_deck * cap_create(void)
static char isolation_ident_char(uint16_t col)
int cap_num_cards(const struct cap_deck *d)
void cap_free(struct cap_deck *d)
struct cap_deck * cap_load(const char *path)
int cap_load_scattered(const char *path, int mode, unsigned char *image, unsigned *lo, unsigned *hi)
#define CAP_MIN_ISOLATION_CARDS
int cap_save(const struct cap_deck *d, const char *path)
int cap_load_isolation_stream(const char *path, unsigned char *image, unsigned org, unsigned *lo, unsigned *hi)
static int scat_detect_prefix(const struct cap_deck *d, int mode, uint8_t out[8], int *eligible_cards)
static int deck_add_card(struct cap_deck *d)
enum cap_deck_family cap_detect_family(const struct cap_deck *d, int mode, struct cap_deck_info *info)
uint8_t scatter_prefix[8]
int eligible_scatter_cards
enum cap_deck_family family
uint8_t transcode_column(uint16_t column, enum transcode_mode mode)