FreeCalypso > hg > fc-sim-sniff
changeset 45:b0524d1dc6ef
simtrace3-sniff-dec: implement command decoding
author | Mychaela Falconia <falcon@freecalypso.org> |
---|---|
date | Thu, 31 Aug 2023 09:32:48 +0000 |
parents | 74330513121e |
children | 43f678895a3a |
files | sw/sniff-dec/command.c sw/sniff-dec/dispatch.c sw/sniff-dec/state.h |
diffstat | 3 files changed, 158 insertions(+), 3 deletions(-) [+] |
line wrap: on
line diff
--- a/sw/sniff-dec/command.c Thu Aug 31 08:55:34 2023 +0000 +++ b/sw/sniff-dec/command.c Thu Aug 31 09:32:48 2023 +0000 @@ -14,10 +14,138 @@ extern unsigned rx_byte; extern int state; +static char cmd_start_timestamp[18]; +static int cmd_start_line; +static char data_start_timestamp[18]; +static int data_start_line; +static char sw1_timestamp[18]; +static int sw1_line; + +static u_char cmd_hdr[5]; +static unsigned hdr_byte_count; +static unsigned data_total, data_sofar, data_thistime; +static u_char data_buf[256], sw1; + void start_cmd_header() { - printf("input line %d: command header, end of implementation so far\n", - lineno); - exit(0); + strcpy(cmd_start_timestamp, linebuf); + cmd_start_line = lineno; + cmd_hdr[0] = rx_byte; + hdr_byte_count = 1; + state = STATE_CMD_HDR; +} + +static void +print_cmd_hdr() +{ + unsigned n; + + printf("%s line %d: CMD", cmd_start_timestamp, cmd_start_line); + for (n = 0; n < 5; n++) + printf(" %02X", cmd_hdr[n]); + putchar('\n'); +} + +void +cmd_hdr_byte_in() +{ + cmd_hdr[hdr_byte_count++] = rx_byte; + if (hdr_byte_count < 5) + return; + print_cmd_hdr(); + if ((cmd_hdr[1] & 0xF0) == 0x60 || (cmd_hdr[1] & 0xF0) == 0x90) { + printf(" ERROR: INS byte is invalid!\n"); + state = STATE_ERROR; + return; + } + if (cmd_hdr[4]) + data_total = cmd_hdr[4]; + else + data_total = 256; + data_sofar = 0; + state = STATE_CMD_PROC; +} + +static void +print_data() +{ + unsigned n; + + printf("%s line %d: DATA\n", data_start_timestamp, data_start_line); + for (n = 0; n < data_sofar; n++) { + printf(" %02X", data_buf[n]); + if ((n & 15) == 15 || n == data_sofar - 1) + putchar('\n'); + } } + +static void +handle_sw1() +{ + strcpy(sw1_timestamp, linebuf); + sw1_line = lineno; + sw1 = rx_byte; + if (data_sofar) + print_data(); + state = STATE_CMD_SW; +} + +void +handle_ack(single) +{ + if (data_sofar >= data_total) { + printf("%s line %d: ERROR: ACK for more data than possible\n", + linebuf, lineno); + state = STATE_ERROR; + return; + } + if (!data_sofar) { + strcpy(data_start_timestamp, linebuf); + data_start_line = lineno; + } + if (single) + data_thistime = 1; + else + data_thistime = data_total - data_sofar; + state = STATE_CMD_DATA; +} + +void +cmd_proc_byte_in() +{ + if (rx_byte == 0x60) + return; + if ((rx_byte & 0xF0) == 0x60 || (rx_byte & 0xF0) == 0x90) { + handle_sw1(); + return; + } + if (rx_byte == cmd_hdr[1]) { + handle_ack(0); + return; + } + if (rx_byte == (cmd_hdr[1] ^ 0xFF)) { + handle_ack(1); + return; + } + printf("%s line %d: ERROR: invalid procedure byte\n", linebuf, lineno); + state = STATE_ERROR; +} + +void +cmd_data_byte_in() +{ + data_buf[data_sofar++] = rx_byte; + data_thistime--; + if (data_thistime) + return; + state = STATE_CMD_PROC; +} + +void +cmd_sw2_byte_in() +{ + printf("%s line %d: SW %02X %02X\n", sw1_timestamp, sw1_line, sw1, + rx_byte); + state = STATE_READY_FOR_CMD; +}
--- a/sw/sniff-dec/dispatch.c Thu Aug 31 08:55:34 2023 +0000 +++ b/sw/sniff-dec/dispatch.c Thu Aug 31 09:32:48 2023 +0000 @@ -143,6 +143,30 @@ extract_rx_byte(); pps_byte_in(); return; + case STATE_CMD_HDR: + if (check_parity()) + return; + extract_rx_byte(); + cmd_hdr_byte_in(); + return; + case STATE_CMD_PROC: + if (check_parity()) + return; + extract_rx_byte(); + cmd_proc_byte_in(); + return; + case STATE_CMD_DATA: + if (check_parity()) + return; + extract_rx_byte(); + cmd_data_byte_in(); + return; + case STATE_CMD_SW: + if (check_parity()) + return; + extract_rx_byte(); + cmd_sw2_byte_in(); + return; default: fprintf(stderr, "BUG in top state machine: invalid state\n"); abort();