- umem->addr = offset;
- umem->size = length;
- umem->mem = mmap(NULL, length, prot, MAP_PRIVATE|MAP_ANONYMOUS, -1, 0);
- if (umem->mem != MAP_FAILED)
- goto done;
-
- printf("upper mem @ %08x %d mmap fail, trying backing file\n", offset, length);
- sprintf(name, "m%08x", offset);
- fd = open(name, O_CREAT|O_RDWR, 0644);
- lseek(fd, length - 1, SEEK_SET);
- name[0] = 0;
- write(fd, name, 1);
-
- umem->mem = mmap(NULL, length, prot, MAP_SHARED, fd, 0);
- if (umem->mem == MAP_FAILED) {
- printf("failed, giving up\n");
- close(fd);
- free(umem);
- return MAP_FAILED;
+ return ioctl(fd, request, argp);
+}
+
+int emu_do_ioctl(int fd, int request, void *argp)
+{
+ if (fd == emu_interesting_fds[IFD_SOUND].fd)
+ return emu_sound_ioctl(fd, request, argp);
+
+ switch (fd) {
+ /* *********************** */
+ case FAKEDEV_FB0:
+ case FAKEDEV_FB1:
+ if (argp == NULL)
+ goto fail;
+
+ switch (request) {
+ case FBIOGET_FSCREENINFO: {
+ struct fb_fix_screeninfo *fix = argp;
+
+ memset(fix, 0, sizeof(*fix));
+ strcpy(fix->id, "mmsp2_RGB0");
+ fix->type = FB_TYPE_PACKED_PIXELS;
+ fix->accel = FB_ACCEL_NONE;
+ fix->visual = FB_VISUAL_TRUECOLOR;
+ fix->line_length = 320*2;
+ fix->smem_start = (fd == FAKEDEV_FB0) ? 0x03101000 : 0x03381000;
+ fix->smem_len = 320*240*2;
+ return 0;
+ }
+ case FBIOGET_VSCREENINFO: {
+ struct fb_var_screeninfo *var = argp;
+ static const struct fb_bitfield fbb_red = { offset: 11, length: 5, };
+ static const struct fb_bitfield fbb_green = { offset: 5, length: 6, };
+ static const struct fb_bitfield fbb_blue = { offset: 0, length: 5, };
+
+ memset(var, 0, sizeof(*var));
+ var->activate = FB_ACTIVATE_NOW;
+ var->xres =
+ var->xres_virtual = 320;
+ var->yres =
+ var->yres_virtual = 240;
+ var->width =
+ var->height = -1;
+ var->vmode = FB_VMODE_NONINTERLACED;
+ var->bits_per_pixel = 16;
+ var->red = fbb_red;
+ var->green = fbb_green;
+ var->blue = fbb_blue;
+ return 0;
+ }
+ case FBIOPUT_VSCREENINFO: {
+ struct fb_var_screeninfo *var = argp;
+ dbg(" put vscreen: %dx%d@%d\n", var->xres, var->yres, var->bits_per_pixel);
+ if (var->xres != 320 || var->yres != 240 || var->bits_per_pixel != 16)
+ return -1;
+ return 0;
+ }
+ }
+
+ /* *********************** */
+ case FAKEDEV_TTY0:
+ // fake tty0 to make GPH SDL happy
+ if (request == 0x4b46) // KDGKBENT
+ return -1;
+ return 0;
+ }
+
+fail:
+ err("bad/ni ioctl(%d, %08x, %p)\n", fd, request, argp);
+ errno = EINVAL;
+ return -1;
+}
+
+static const struct {
+ const char *from;
+ const char *to;
+} path_map[] = {
+ { "/mnt/tmp/", "/tmp/" },
+};
+
+static const char *wrap_path(const char *path)
+{
+ char *buff;
+ size_t size;
+ int i, len;
+
+ // do only path mapping for now
+ for (i = 0; i < ARRAY_SIZE(path_map); i++) {
+ len = strlen(path_map[i].from);
+ if (strncmp(path, path_map[i].from, len) == 0) {
+ size = strlen(path) + strlen(path_map[i].to) + 1;
+ buff = malloc(size);
+ if (buff == NULL)
+ break;
+ snprintf(buff, size, "%s%s", path_map[i].to, path + len);
+ dbg("mapped path \"%s\" -> \"%s\"\n", path, buff);
+ return buff;
+ }