28 #include <sys/types.h>
36 #define EXOS_USER_SEGMAP_P (0X3FFFFC + memory)
37 #define HOST_OS_STR "Host OS "
38 #define FILE_TOO_LARGE "Too large file"
40 #define FILEIO_MAX_FILE_SIZE 67108864L
42 #define SET_CHANNEL(v) channel = ((v) - 1) & 0xFF
45 static int channel = 0;
47 static int fio_fd [0x100];
48 static int fio_off [0x100];
49 static char *fio_name[0x100];
50 static int fio_size[0x100];
51 static Uint8 fio_prot[0x100];
58 for (a = 0; a < 0x100; a++)
78 static void fileio_host_errstr (
void )
87 static int host_file_check (
int fd,
int *file_size,
char **filename_store,
const char *filename_in )
100 *file_size =
st.st_size;
101 *filename_store = strdup(filename_in);
102 if (!*filename_store) {
117 static int open_host_file (
const char *dirname,
const char *filename,
int create,
char **used_filename,
int *file_size )
120 struct dirent *entry;
121 int mode = create ? (O_TRUNC | O_CREAT | O_RDWR) : O_RDWR;
122 dir = opendir(dirname);
127 while ((entry = readdir(
dir))) {
128 if (!strcasecmp(entry->d_name, filename)) {
130 char buffer[PATH_MAX + 1];
132 if (CHECK_SNPRINTF(snprintf(buffer,
sizeof buffer,
"%s%s%s", dirname,
DIRSEP_STR, entry->d_name),
sizeof buffer))
135 ret = open(buffer, mode |
O_BINARY, 0666);
136 if (ret < 0 && !create)
137 ret = open(buffer, O_RDONLY |
O_BINARY);
139 fileio_host_errstr();
142 ret = host_file_check(ret, file_size, used_filename, buffer);
149 char buffer[PATH_MAX + 1];
150 if (CHECK_SNPRINTF(snprintf(buffer,
sizeof buffer,
"%s%s%s", dirname,
DIRSEP_STR, filename),
sizeof buffer))
152 ret = open(buffer, mode |
O_BINARY, 0666);
154 fileio_host_errstr();
157 ret = host_file_check(ret, file_size, used_filename, buffer);
161 DEBUGPRINT(
"FILEIO: No file found matching the open request" NL);
166 static void get_file_name (
char *p )
186 char fnbuf[PATH_MAX + 1];
189 DEBUGPRINT(
"FILEIO: channel RAM allocation EXOS call in XEP ROM failed (A = %02Xh)? Return!" NL,
Z80_A);
193 if (fio_fd[channel] >= 0) {
194 DEBUGPRINT(
"FILEIO: open/create channel, already used channel for %d, fd is %d" NL, channel, fio_fd[channel]);
198 get_file_name(fnbuf);
201 DEBUGPRINT(
"FILEIO: file name was empty \"%s\" ..." NL, fnbuf);
207 "Select file for opening via FILE: device",
220 r = open_host_file(
fileio_cwd, fnbuf, create, &fio_name[channel], &fio_size[channel]);
222 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]);
228 fio_off[channel] = 0;
229 fio_prot[channel] = 0;
238 if (fio_fd[channel] < 0) {
239 DEBUGPRINT(
"FILEIO: close, invalid channel for %d, fd is %d" NL, channel, fio_fd[channel]);
242 DEBUGPRINT(
"FILEIO: close, closing channel %d (fd = %d)" NL, channel, fio_fd[channel]);
243 close(fio_fd[channel]);
244 fio_fd[channel] = -1;
245 free(fio_name[channel]);
246 fio_name[channel] = NULL;
253 static int increment_offset (
int inc )
255 fio_off[channel] +=
inc;
256 if ( fio_off[channel] > fio_size[channel])
257 fio_size[channel] = fio_off[channel];
267 static int host_reseek (
void )
269 off_t ret = lseek(fio_fd[channel], fio_off[channel], SEEK_SET);
270 if (ret != fio_off[channel]) {
273 fileio_host_errstr();
283 DEBUG(
"FILEIO: internal host seek %d for channel %d" NL, fio_off[channel], channel);
291 Uint8 buffer[0xFFFF], *p;
293 DEBUGPRINT(
"FILEIO: read block on channel %d (fd = %d) BC=%04Xh DE=%04Xh" NL, channel, fio_fd[channel],
Z80_BC,
Z80_DE);
294 if (fio_fd[channel] < 0) {
295 DEBUGPRINT(
"FILEIO: read block problem = invalid channel" NL);
305 r = read(fio_fd[channel], buffer + rb,
Z80_BC);
306 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,
307 channel, fio_fd[channel],
Z80_BC,
308 fio_off[channel], fio_size[channel],
314 if (increment_offset(
r))
320 fileio_host_errstr();
334 if (fio_fd[channel] < 0) {
335 DEBUGPRINT(
"FILEIO: read character, invalid channel for %d, fd is %d" NL, channel, fio_fd[channel]);
341 r = read(fio_fd[channel], &
Z80_B, 1);
348 fileio_host_errstr();
359 Uint8 buffer[0xFFFF], *p;
361 if (fio_fd[channel] < 0) {
375 int r = write(fio_fd[channel], p,
Z80_BC);
379 if (increment_offset(
r))
386 fileio_host_errstr();
397 if (fio_fd[channel] < 0)
403 r = write(fio_fd[channel], &
Z80_B, 1);
411 fileio_host_errstr();
428 if (fio_fd[channel] < 0) {
433 for (a = 0, de =
Z80_DE; a < 16; a++)
436 fio_off[channel] = stat[0] | (stat[1] << 8) | (stat[2] << 16) | (stat[3] << 24);
438 stat[0] = fio_off[channel] & 0xFF;
439 stat[1] = (fio_off[channel] >> 8) & 0xFF;
440 stat[2] = (fio_off[channel] >> 16) & 0xFF;
441 stat[3] = (fio_off[channel] >> 24) & 0xFF;
444 fio_prot[channel] = stat[8];
446 stat[8] = fio_prot[channel];
447 stat[4] = fio_size[channel] & 0xFF;
448 stat[5] = (fio_size[channel] >> 8) & 0xFF;
449 stat[6] = (fio_size[channel] >> 16) & 0xFF;
450 stat[7] = (fio_size[channel] >> 24) & 0xFF;
451 for (a = 0, de =
Z80_DE; a < 16; a++)
471 for (a = 0; a < 0x100; a++)
472 if (fio_fd[a] != -1) {