27 #include <sys/types.h>
34 #define EXOS_USER_SEGMAP_P (0X3FFFFC + memory)
35 #define HOST_OS_STR "Host OS "
36 #define FILE_TOO_LARGE "Too large file"
38 #define FILEIO_MAX_FILE_SIZE 67108864L
40 #define SET_CHANNEL(v) channel = ((v) - 1) & 0xFF
43 static int channel = 0;
45 static int fio_fd [0x100];
46 static int fio_off [0x100];
47 static char *fio_name[0x100];
48 static int fio_size[0x100];
49 static Uint8 fio_prot[0x100];
56 for (a = 0; a < 0x100; a++)
62 if (subdir[strlen(subdir) - 1] !=
DIRSEP[0])
76 static void fileio_host_errstr (
void )
85 static int host_file_check (
int fd,
int *file_size,
char **filename_store,
const char *filename_in )
98 *file_size =
st.st_size;
99 *filename_store = strdup(filename_in);
100 if (!*filename_store) {
115 static int open_host_file (
const char *dirname,
const char *filename,
int create,
char **used_filename,
int *file_size )
118 struct dirent *entry;
119 int mode = create ? (O_TRUNC | O_CREAT | O_RDWR) : O_RDWR;
120 dir = opendir(dirname);
125 while ((entry = readdir(
dir))) {
126 if (!strcasecmp(entry->d_name, filename)) {
128 char buffer[PATH_MAX + 1];
130 if (CHECK_SNPRINTF(snprintf(buffer,
sizeof buffer,
"%s%s%s", dirname,
DIRSEP, entry->d_name),
sizeof buffer))
133 ret = open(buffer, mode |
O_BINARY, 0666);
134 if (ret < 0 && !create)
135 ret = open(buffer, O_RDONLY |
O_BINARY);
137 fileio_host_errstr();
140 ret = host_file_check(ret, file_size, used_filename, buffer);
147 char buffer[PATH_MAX + 1];
148 if (CHECK_SNPRINTF(snprintf(buffer,
sizeof buffer,
"%s%s%s", dirname,
DIRSEP, filename),
sizeof buffer))
150 ret = open(buffer, mode |
O_BINARY, 0666);
152 fileio_host_errstr();
155 ret = host_file_check(ret, file_size, used_filename, buffer);
159 DEBUGPRINT(
"FILEIO: No file found matching the open request" NL);
164 static void get_file_name (
char *p )
184 char fnbuf[PATH_MAX + 1];
187 DEBUGPRINT(
"FILEIO: channel RAM allocation EXOS call in XEP ROM failed (A = %02Xh)? Return!" NL,
Z80_A);
191 if (fio_fd[channel] >= 0) {
192 DEBUGPRINT(
"FILEIO: open/create channel, already used channel for %d, fd is %d" NL, channel, fio_fd[channel]);
196 get_file_name(fnbuf);
199 DEBUGPRINT(
"FILEIO: file name was empty \"%s\" ..." NL, fnbuf);
205 WINDOW_TITLE " - Select file for opening via FILE: device",
218 r = open_host_file(
fileio_cwd, fnbuf, create, &fio_name[channel], &fio_size[channel]);
220 DEBUGPRINT(
"FILEIO: %s channel #%d result = %d filename = \"%s\" as %s with size of %d" NL, create ?
"create" :
"open", channel,
r, fnbuf, fio_name[channel], fio_size[channel]);
226 fio_off[channel] = 0;
227 fio_prot[channel] = 0;
236 if (fio_fd[channel] < 0) {
237 DEBUGPRINT(
"FILEIO: close, invalid channel for %d, fd is %d" NL, channel, fio_fd[channel]);
240 DEBUGPRINT(
"FILEIO: close, closing channel %d (fd = %d)" NL, channel, fio_fd[channel]);
241 close(fio_fd[channel]);
242 fio_fd[channel] = -1;
243 free(fio_name[channel]);
244 fio_name[channel] = NULL;
251 static int increment_offset (
int inc )
253 fio_off[channel] +=
inc;
254 if ( fio_off[channel] > fio_size[channel])
255 fio_size[channel] = fio_off[channel];
265 static int host_reseek (
void )
267 off_t ret = lseek(fio_fd[channel], fio_off[channel], SEEK_SET);
268 if (ret != fio_off[channel]) {
271 fileio_host_errstr();
281 DEBUG(
"FILEIO: internal host seek %d for channel %d" NL, fio_off[channel], channel);
289 Uint8 buffer[0xFFFF], *p;
291 DEBUGPRINT(
"FILEIO: read block on channel %d (fd = %d) BC=%04Xh DE=%04Xh" NL, channel, fio_fd[channel],
Z80_BC,
Z80_DE);
292 if (fio_fd[channel] < 0) {
293 DEBUGPRINT(
"FILEIO: read block problem = invalid channel" NL);
303 r = read(fio_fd[channel], buffer + rb,
Z80_BC);
304 DEBUGPRINT(
"FILEIO: read block on channel %d (fd = %d), %d byte(s) requested at offset %d (file size = %d), result is %d (got so far: %d)" NL,
305 channel, fio_fd[channel],
Z80_BC,
306 fio_off[channel], fio_size[channel],
312 if (increment_offset(
r))
318 fileio_host_errstr();
332 if (fio_fd[channel] < 0) {
333 DEBUGPRINT(
"FILEIO: read character, invalid channel for %d, fd is %d" NL, channel, fio_fd[channel]);
339 r = read(fio_fd[channel], &
Z80_B, 1);
346 fileio_host_errstr();
357 Uint8 buffer[0xFFFF], *p;
359 if (fio_fd[channel] < 0) {
373 int r = write(fio_fd[channel], p,
Z80_BC);
377 if (increment_offset(
r))
384 fileio_host_errstr();
395 if (fio_fd[channel] < 0)
401 r = write(fio_fd[channel], &
Z80_B, 1);
409 fileio_host_errstr();
426 if (fio_fd[channel] < 0) {
431 for (a = 0, de =
Z80_DE; a < 16; a++)
434 fio_off[channel] = stat[0] | (stat[1] << 8) | (stat[2] << 16) | (stat[3] << 24);
436 stat[0] = fio_off[channel] & 0xFF;
437 stat[1] = (fio_off[channel] >> 8) & 0xFF;
438 stat[2] = (fio_off[channel] >> 16) & 0xFF;
439 stat[3] = (fio_off[channel] >> 24) & 0xFF;
442 fio_prot[channel] = stat[8];
444 stat[8] = fio_prot[channel];
445 stat[4] = fio_size[channel] & 0xFF;
446 stat[5] = (fio_size[channel] >> 8) & 0xFF;
447 stat[6] = (fio_size[channel] >> 16) & 0xFF;
448 stat[7] = (fio_size[channel] >> 24) & 0xFF;
449 for (a = 0, de =
Z80_DE; a < 16; a++)
469 for (a = 0; a < 0x100; a++)
470 if (fio_fd[a] != -1) {