# HG changeset patch # User Mychaela Falconia # Date 1615585929 0 # Node ID 130c46b8376055d557fa61ba8305cfa9a21f1877 # Parent 6d1b22d4926fb2559c07d426f2b3f2ab2ee6beb1 simagent: sim-up command fully implemented diff -r 6d1b22d4926f -r 130c46b83760 target-utils/simagent/cmdtab.c --- a/target-utils/simagent/cmdtab.c Fri Mar 12 21:20:56 2021 +0000 +++ b/target-utils/simagent/cmdtab.c Fri Mar 12 21:52:09 2021 +0000 @@ -16,12 +16,14 @@ extern void abb_init(); extern void abb_power_off(); extern void abb_unlock_page2(); +extern void print_atr(); const struct cmdtab cmdtab[] = { {"abbinit", abb_init}, {"abbpage2", abb_unlock_page2}, {"abbr", cmd_abbr}, {"abbw", cmd_abbw}, + {"atr", print_atr}, {"baud", cmd_baud_switch}, {"jump", cmd_jump}, {"poweroff", abb_power_off}, diff -r 6d1b22d4926f -r 130c46b83760 target-utils/simagent/simup.c --- a/target-utils/simagent/simup.c Fri Mar 12 21:20:56 2021 +0000 +++ b/target-utils/simagent/simup.c Fri Mar 12 21:52:09 2021 +0000 @@ -3,14 +3,50 @@ #include "types.h" #include "abbdefs.h" #include "simregs.h" +#include "timeout.h" + +#define MAX_ATR_BYTES 33 #define WAIT_ONE_TDMA 60000 extern u16 abb_reg_read(); extern void abb_reg_write(); +extern const u8 inverse_coding_table[256]; + int sim_if_state; u16 conf1_reg; +u8 atr_buf[MAX_ATR_BYTES]; +unsigned atr_length; +int inverse_coding; + +void +print_atr() +{ + unsigned n; + + printf("ATR:"); + for (n = 0; n < atr_length; n++) + printf(" %02X", atr_buf[n]); + putchar('\n'); +} + +static +rx_atr_byte() +{ + int rc; + + rc = rx_sim_byte(SIM_WAIT_TIMEOUT); + if (rc < 0) { + printf("ERROR: timeout waiting for subsequent byte of ATR\n"); + return(-1); + } + rc &= 0xFF; + if (inverse_coding) + rc = inverse_coding_table[rc]; + atr_buf[atr_length++] = rc; + return rc; +} void cmd_sim_up(argbulk) @@ -18,7 +54,8 @@ { char *argv[2]; u16 abb_sim_reg; - unsigned count; + unsigned count, y, nhist, have_tck; + int rc; if (sim_if_state) { printf("ERROR: SIM interface is already up\n"); @@ -89,9 +126,84 @@ return; } } - -#if 0 /* lift the card out of reset! */ SIMREGS.conf1 = conf1_reg |= SIM_CONF1_SRSTLEV; -#endif + + /* first byte of ATR */ + rc = rx_sim_byte(SIM_WAIT_TIMEOUT); + if (rc < 0) { + printf("ERROR: timeout waiting for first byte of ATR\n"); + return; + } + rc &= 0xFF; + if (rc == 0x3B) { + /* direct convention */ + inverse_coding = 0; + atr_buf[0] = 0x3B; + } else if (rc == 0x03) { + /* inverse convention */ + inverse_coding = 1; + atr_buf[0] = 0x3F; + } else { + printf( + "ERROR: received TS=0x%02X, matches neither convention\n", + rc); + return; + } + atr_length = 1; + + /* remainder of ATR, starting with T0 */ + rc = rx_atr_byte(); + if (rc < 0) + return; + nhist = rc & 0xF; + y = rc & 0xF0; + have_tck = 0; + while (y) { + if (y & 0x10) { + if (atr_length >= MAX_ATR_BYTES) { +atr_too_long: printf("ERROR: ATR exceeds 33 byte limit\n"); + return; + } + rc = rx_atr_byte(); + if (rc < 0) + return; + } + if (y & 0x20) { + if (atr_length >= MAX_ATR_BYTES) + goto atr_too_long; + rc = rx_atr_byte(); + if (rc < 0) + return; + } + if (y & 0x40) { + if (atr_length >= MAX_ATR_BYTES) + goto atr_too_long; + rc = rx_atr_byte(); + if (rc < 0) + return; + } + if (y & 0x80) { + if (atr_length >= MAX_ATR_BYTES) + goto atr_too_long; + rc = rx_atr_byte(); + if (rc < 0) + return; + y = rc & 0xF0; + if (rc & 0x0F) + have_tck = 1; + } else + y = 0; + } + for (count = 0; count < nhist + have_tck; count++) { + if (atr_length >= MAX_ATR_BYTES) + goto atr_too_long; + rc = rx_atr_byte(); + if (rc < 0) + return; + } + + /* all good! */ + sim_if_state = 2; + print_atr(); }