comparison sw/sniff-dec/atr.c @ 41:118a12e9483b

simtrace3-sniff-dec started
author Mychaela Falconia <falcon@freecalypso.org>
date Thu, 31 Aug 2023 08:46:23 +0000
parents
children 74330513121e
comparison
equal deleted inserted replaced
40:510bef2b2000 41:118a12e9483b
1 /*
2 * Here we implement ATR decoding.
3 */
4
5 #include <sys/types.h>
6 #include <stdio.h>
7 #include <stdlib.h>
8 #include <string.h>
9 #include <strings.h>
10 #include "state.h"
11
12 extern char linebuf[];
13 extern int lineno;
14 extern unsigned rx_byte;
15 extern int state;
16
17 #define MAX_ATR_BYTES 33
18
19 #define SUBST_TS 0
20 #define SUBST_T0 1
21 #define SUBST_TAn 2
22 #define SUBST_TBn 3
23 #define SUBST_TCn 4
24 #define SUBST_TDn 5
25 #define SUBST_HIST 6
26 #define SUBST_TCK 7
27
28 static char atr_start_timestamp[18];
29 static int atr_start_line;
30 static int substate;
31 static u_char atr_bytes[MAX_ATR_BYTES];
32 static unsigned byte_count;
33 static u_char latch_y, latch_k, have_tck;
34
35 void
36 atr_begin()
37 {
38 strcpy(atr_start_timestamp, linebuf);
39 atr_start_line = lineno;
40 substate = SUBST_TS;
41 byte_count = 0;
42 }
43
44 static int
45 advance_state()
46 {
47 if (substate == SUBST_TAn) {
48 if (latch_y & 0x10)
49 return 0;
50 substate = SUBST_TBn;
51 }
52 if (substate == SUBST_TBn) {
53 if (latch_y & 0x20)
54 return 0;
55 substate = SUBST_TCn;
56 }
57 if (substate == SUBST_TCn) {
58 if (latch_y & 0x40)
59 return 0;
60 substate = SUBST_TDn;
61 }
62 if (substate == SUBST_TDn) {
63 if (latch_y & 0x80)
64 return 0;
65 substate = SUBST_HIST;
66 }
67 if (substate == SUBST_HIST) {
68 if (latch_k)
69 return 0;
70 substate = SUBST_TCK;
71 }
72 if (substate == SUBST_TCK) {
73 if (have_tck)
74 return 0;
75 return 1;
76 }
77 fprintf(stderr, "BUG in ATR decoder: bad state in advance_state()\n");
78 abort();
79 }
80
81 static void
82 check_tck()
83 {
84 unsigned n, xor;
85
86 xor = 0;
87 for (n = 1; n < byte_count; n++)
88 xor ^= atr_bytes[n];
89 printf(" TCK is %s\n", xor ? "bad!" : "correct");
90 }
91
92 static void
93 atr_finish()
94 {
95 unsigned n;
96
97 printf("%s line %d: ATR\n", atr_start_timestamp, atr_start_line);
98 for (n = 0; n < byte_count; n++)
99 printf(" %02X", atr_bytes[n]);
100 putchar('\n');
101 if (have_tck)
102 check_tck();
103 state = STATE_READY_FOR_CMD;
104 }
105
106 void
107 atr_byte_in()
108 {
109 atr_bytes[byte_count++] = rx_byte;
110 switch (substate) {
111 case SUBST_TS:
112 substate = SUBST_T0;
113 return;
114 case SUBST_T0:
115 latch_y = rx_byte & 0xF0;
116 latch_k = rx_byte & 0x0F;
117 have_tck = 0;
118 substate = SUBST_TAn;
119 if (advance_state()) {
120 atr_finish();
121 return;
122 }
123 return;
124 case SUBST_TAn:
125 substate = SUBST_TBn;
126 if (advance_state()) {
127 atr_finish();
128 return;
129 }
130 break;
131 case SUBST_TBn:
132 substate = SUBST_TCn;
133 if (advance_state()) {
134 atr_finish();
135 return;
136 }
137 break;
138 case SUBST_TCn:
139 substate = SUBST_TDn;
140 if (advance_state()) {
141 atr_finish();
142 return;
143 }
144 break;
145 case SUBST_TDn:
146 latch_y = rx_byte & 0xF0;
147 if (rx_byte & 0x0F)
148 have_tck = 1;
149 substate = SUBST_TAn;
150 if (advance_state()) {
151 atr_finish();
152 return;
153 }
154 break;
155 case SUBST_HIST:
156 latch_k--;
157 if (advance_state()) {
158 atr_finish();
159 return;
160 }
161 break;
162 case SUBST_TCK:
163 atr_finish();
164 return;
165 default:
166 fprintf(stderr,
167 "BUG in ATR decoder: bad state in atr_byte_in()\n");
168 abort();
169 }
170 if (byte_count < MAX_ATR_BYTES)
171 return;
172 printf("%s line %d: ERROR: ATR is too long\n", atr_start_timestamp,
173 atr_start_line);
174 state = STATE_ERROR;
175 }