fork of PCE focusing on macplus, supporting DaynaPort SCSI network emulation
1/*****************************************************************************
2 * pce *
3 *****************************************************************************/
4
5/*****************************************************************************
6 * File name: src/lib/sysdep.c *
7 * Created: 2006-06-19 by Hampa Hug <hampa@hampa.ch> *
8 * Copyright: (C) 2006-2025 Hampa Hug <hampa@hampa.ch> *
9 *****************************************************************************/
10
11/*****************************************************************************
12 * This program is free software. You can redistribute it and / or modify it *
13 * under the terms of the GNU General Public License version 2 as published *
14 * by the Free Software Foundation. *
15 * *
16 * This program is distributed in the hope that it will be useful, but *
17 * WITHOUT ANY WARRANTY, without even the implied warranty of *
18 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General *
19 * Public License for more details. *
20 *****************************************************************************/
21
22
23#include <config.h>
24
25#include <stdlib.h>
26#include <stdio.h>
27#include <string.h>
28#include <time.h>
29
30#ifdef HAVE_UNISTD_H
31#include <unistd.h>
32#endif
33
34#ifdef HAVE_SYS_TIME_H
35#include <sys/time.h>
36#endif
37
38#ifdef HAVE_SYS_POLL_H
39#include <sys/poll.h>
40#endif
41
42#ifdef HAVE_SYS_STAT_H
43#include <sys/stat.h>
44#endif
45
46#ifdef HAVE_TERMIOS_H
47#include <termios.h>
48#endif
49
50#include "sysdep.h"
51
52
53int pce_usleep (unsigned long usec)
54{
55#if defined(HAVE_NANOSLEEP)
56 struct timespec t;
57
58 t.tv_sec = usec / 1000000;
59 t.tv_nsec = 1000 * (usec % 1000000);
60
61 return (nanosleep (&t, NULL));
62#elif defined(HAVE_USLEEP)
63 unsigned long n;
64
65 while (usec > 0) {
66 n = (usec < 500000) ? usec : 500000;
67 usleep (n);
68 usec -= n;
69 }
70
71 return (0);
72#else
73 return (-1);
74#endif
75}
76
77unsigned long pce_get_interval_us (unsigned long *val)
78{
79#ifdef HAVE_GETTIMEOFDAY
80 unsigned long clk0, clk1;
81 struct timeval tv;
82
83 if (gettimeofday (&tv, NULL)) {
84 return (0);
85 }
86
87 clk1 = (1000000UL * (unsigned long) tv.tv_sec + tv.tv_usec) & 0xffffffff;
88 clk0 = (clk1 - *val) & 0xffffffff;
89
90 *val = clk1;
91
92 return (clk0);
93#else
94 return (0);
95#endif
96}
97
98void pce_srand (unsigned val)
99{
100#ifdef HAVE_GETTIMEOFDAY
101 struct timeval tv;
102
103 if (gettimeofday (&tv, NULL) == 0) {
104 val ^= (unsigned) tv.tv_sec;
105 val ^= (unsigned) tv.tv_usec;
106 }
107 else {
108 val ^= (unsigned) time (NULL);
109 }
110#else
111 val ^= (unsigned) time (NULL);
112#endif
113
114 srand (val);
115}
116
117int pce_fd_readable (int fd, int t)
118{
119#ifdef HAVE_SYS_POLL_H
120 int r;
121 struct pollfd pfd[1];
122
123 pfd[0].fd = fd;
124 pfd[0].events = POLLIN;
125
126 r = poll (pfd, 1, t);
127 if (r < 0) {
128 return (0);
129 }
130
131 if ((pfd[0].revents & POLLIN) == 0) {
132 return (0);
133 }
134
135 return (1);
136#else
137 return (0);
138#endif
139}
140
141int pce_fd_writeable (int fd, int t)
142{
143#ifdef HAVE_SYS_POLL_H
144 int r;
145 struct pollfd pfd[1];
146
147 pfd[0].fd = fd;
148 pfd[0].events = POLLOUT;
149
150 r = poll (pfd, 1, t);
151 if (r < 0) {
152 return (0);
153 }
154
155 if ((pfd[0].revents & POLLOUT) == 0) {
156 return (0);
157 }
158
159 return (1);
160#else
161 return (0);
162#endif
163}
164
165void pce_set_fd_interactive (int fd, int interactive)
166{
167#ifdef HAVE_TERMIOS_H
168 static int sios_ok = 0;
169 static struct termios sios;
170 struct termios tios;
171
172 if (sios_ok == 0) {
173 tcgetattr (fd, &sios);
174 sios_ok = 1;
175 }
176
177 if (interactive) {
178 tcsetattr (fd, TCSANOW, &sios);
179 }
180 else {
181 tios = sios;
182
183 tios.c_iflag &= ~(IXON | IXOFF);
184 tios.c_lflag &= ~(ICANON | ECHO | ISIG);
185 tios.c_cc[VMIN] = 1;
186 tios.c_cc[VTIME] = 0;
187
188 tcsetattr (fd, TCSANOW, &tios);
189 }
190#endif
191}
192
193int pce_file_exists (const char *name)
194{
195#ifdef HAVE_SYS_STAT_H
196 struct stat st;
197
198 if (stat (name, &st) != 0) {
199 return (0);
200 }
201#else
202 FILE *fp;
203
204 if ((fp = fopen (name, "rb")) == NULL) {
205 return (0);
206 }
207
208 fclose (fp);
209#endif
210 return (1);
211}
212
213void pce_start (unsigned *brk)
214{
215 if (brk != NULL) {
216 *brk = 0;
217 }
218
219 pce_set_fd_interactive (0, 0);
220}
221
222void pce_stop (void)
223{
224 pce_set_fd_interactive (0, 1);
225}