view loadtools/simatr.c @ 893:85091e14be9c

fc-buzplay: PWT refactoring, first step
author Mychaela Falconia <falcon@freecalypso.org>
date Sun, 03 Apr 2022 08:00:50 +0000
parents a31ae776de6e
children
line wrap: on
line source

/*
 * 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;
	}
	printf("Requesting SIM speed enhancement\n");
	tpinterf_make_cmd(targv);
	if (tpinterf_send_cmd() < 0)
		exit(1);
	if (tpinterf_pass_output(10))
		exit(1);
}