FreeCalypso > hg > freecalypso-tools
diff loadtools/simatr.c @ 790:0bbe0213812d
fc-simint put together, compiles
author | Mychaela Falconia <falcon@freecalypso.org> |
---|---|
date | Fri, 19 Mar 2021 04:40:05 +0000 |
parents | |
children | a31ae776de6e |
line wrap: on
line diff
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/loadtools/simatr.c Fri Mar 19 04:40:05 2021 +0000 @@ -0,0 +1,92 @@ +/* + * This module implements the stage in fc-simint where ATR bytes + * received from simagent are validated. + */ + +#include <sys/types.h> +#include <stdio.h> +#include <stdlib.h> + +extern int sim_allow_spenh; + +extern u_char sim_atr[]; +extern unsigned sim_atr_len; + +void +sim_atr_validate() +{ + unsigned b, p, y, nhist, have_tck; + + if (sim_atr_len < 2) { +too_short: fprintf(stderr, "error: ATR from simagent is too short\n"); + exit(1); + } + b = sim_atr[1]; + p = 2; + nhist = b & 0xF; + y = b & 0xF0; + have_tck = 0; + while (y) { + if (y & 0x10) { + if (p >= sim_atr_len) + goto too_short; + p++; + } + if (y & 0x20) { + if (p >= sim_atr_len) + goto too_short; + p++; + } + if (y & 0x40) { + if (p >= sim_atr_len) + goto too_short; + p++; + } + if (y & 0x80) { + if (p >= sim_atr_len) + goto too_short; + b = sim_atr[p++]; + y = b & 0xF0; + if (b & 0x0F) + have_tck = 1; + } else + y = 0; + } + p += nhist + have_tck; + if (p > sim_atr_len) + goto too_short; + if (p < sim_atr_len) { + fprintf(stderr, "error: ATR from simagent is too long\n"); + exit(1); + } + if (!have_tck) + return; + /* validate TCK */ + b = 0; + for (p = 1; p < sim_atr_len; p++) + b ^= sim_atr[p]; + if (b) { + fprintf(stderr, "error: ATR checksum is bad\n"); + exit(1); + } +} + +void +sim_spenh_logic() +{ + static char *targv[2] = {"spenh", 0}; + + if (sim_atr_len < 3 || !(sim_atr[1] & 0x10) || (sim_atr[2] < 0x94)) { + printf("ATR indicates no support for speed enhancement\n"); + return; + } + if (!sim_allow_spenh) { + printf("Speed enhancement disabled with -n option\n"); + return; + } + tpinterf_make_cmd(targv); + if (tpinterf_send_cmd() < 0) + exit(1); + if (tpinterf_pass_output(10)) + exit(1); +}