Allow a full make check on Travis
[microwatt.git] / sim_console_c.c
1 #include <stdint.h>
2 #include <stdio.h>
3 #include <stdlib.h>
4 #include <stdbool.h>
5 #include <string.h>
6 #include <termios.h>
7 #include <unistd.h>
8 #include <poll.h>
9
10
11 #define vhpi0 2 /* forcing 0 */
12 #define vhpi1 3 /* forcing 1 */
13
14 static uint64_t from_std_logic_vector(unsigned char *p, unsigned long len)
15 {
16 unsigned long ret = 0;
17
18 if (len > 64) {
19 fprintf(stderr, "%s: invalid length %lu\n", __func__, len);
20 exit(1);
21 }
22
23 for (unsigned long i = 0; i < len; i++) {
24 unsigned char bit;
25
26 if (*p == vhpi0) {
27 bit = 0;
28 } else if (*p == vhpi1) {
29 bit = 1;
30 } else {
31 fprintf(stderr, "%s: bad bit %d\n", __func__, *p);
32 bit = 0;
33 }
34
35 ret = (ret << 1) | bit;
36 p++;
37 }
38
39 return ret;
40 }
41
42 static void to_std_logic_vector(unsigned long val, unsigned char *p,
43 unsigned long len)
44 {
45 if (len > 64) {
46 fprintf(stderr, "%s: invalid length %lu\n", __func__, len);
47 exit(1);
48 }
49
50 for (unsigned long i = 0; i < len; i++) {
51 if ((val >> (len-1-i) & 1))
52 *p = vhpi1;
53 else
54 *p = vhpi0;
55
56 p++;
57 }
58 }
59
60 static struct termios oldt;
61
62 static void restore_termios(void)
63 {
64 tcsetattr(STDIN_FILENO, TCSANOW, &oldt);
65 }
66
67 static void nonblocking(void)
68 {
69 static bool initialized = false;
70
71 if (!initialized) {
72 static struct termios newt;
73
74 tcgetattr(STDIN_FILENO, &oldt);
75 newt = oldt;
76 newt.c_lflag &= ~(ICANON|ECHO);
77
78 newt.c_iflag &= ~(BRKINT | ICRNL | INPCK | ISTRIP | IXON);
79 newt.c_oflag &= ~(OPOST);
80 newt.c_cflag |= (CS8);
81 newt.c_lflag &= ~(ECHO | ICANON | IEXTEN | ISIG);
82
83 tcsetattr(STDIN_FILENO, TCSANOW, &newt);
84 initialized = true;
85 atexit(restore_termios);
86 }
87 }
88
89 void sim_console_read(unsigned char *__rt)
90 {
91 int ret;
92 unsigned long val = 0;
93
94 nonblocking();
95
96 ret = read(STDIN_FILENO, &val, 1);
97 if (ret != 1) {
98 fprintf(stderr, "%s: read of stdin returns %d\n", __func__, ret);
99 exit(1);
100 }
101
102 //fprintf(stderr, "read returns %c\n", val);
103
104 to_std_logic_vector(val, __rt, 64);
105 }
106
107 void sim_console_poll(unsigned char *__rt)
108 {
109 int ret;
110 struct pollfd fdset[1];
111 uint8_t val = 0;
112
113 nonblocking();
114
115 memset(fdset, 0, sizeof(fdset));
116
117 fdset[0].fd = STDIN_FILENO;
118 fdset[0].events = POLLIN;
119
120 ret = poll(fdset, 1, 0);
121 //fprintf(stderr, "poll returns %d\n", ret);
122
123 if (ret == 1)
124 val = 1;
125
126 to_std_logic_vector(val, __rt, 64);
127 }
128
129 void sim_console_write(unsigned char *__rs)
130 {
131 uint8_t val;
132
133 val = from_std_logic_vector(__rs, 64);
134
135 fprintf(stderr, "%c", val);
136 }