|
|
1.1 ! root 1: /* ! 2: * Hatari - natfeats.c ! 3: * ! 4: * Copyright (C) 2012 by Eero Tamminen ! 5: * ! 6: * This file is distributed under the GNU General Public License, version 2 ! 7: * or at your option any later version. Read the file gpl.txt for details. ! 8: * ! 9: * natfeats.c - Hatari Native features identification and call forwarding, ! 10: * modeleted after similar code in Aranym (written by Petr Stehlik), ! 11: * specified here: ! 12: * http://wiki.aranym.org/natfeats/proposal ! 13: */ ! 14: const char Natfeats_fileid[] = "Hatari natfeats.c : " __DATE__ " " __TIME__; ! 15: ! 16: #include <stdio.h> ! 17: #include "main.h" ! 18: #include "version.h" ! 19: #include "configuration.h" ! 20: #include "stMemory.h" ! 21: #include "m68000.h" ! 22: #include "natfeats.h" ! 23: ! 24: #define NF_DEBUG 1 ! 25: #if NF_DEBUG ! 26: # define Dprintf(a) printf a ! 27: #else ! 28: # define Dprintf(a) ! 29: #endif ! 30: ! 31: /* TODO: ! 32: * - supervisor vs. user stack handling? ! 33: * - clipboard and hostfs native features? ! 34: */ ! 35: ! 36: ! 37: static bool nf_name(Uint32 stack, Uint32 subid, Uint32 *retval) ! 38: { ! 39: Uint32 ptr, len; ! 40: const char *str; ! 41: char *buf; ! 42: ! 43: ptr = STMemory_ReadLong(stack); ! 44: len = STMemory_ReadLong(stack + SIZE_LONG); ! 45: Dprintf(("NF name[%d](0x%x, %d)\n", subid, ptr, len)); ! 46: ! 47: if (!STMemory_ValidArea(ptr, len)) { ! 48: M68000_BusError(ptr, BUS_ERROR_WRITE); ! 49: return false; ! 50: } ! 51: if (subid) { ! 52: str = PROG_NAME; ! 53: } else { ! 54: str = "Hatari"; ! 55: } ! 56: buf = (char *)STRAM_ADDR(ptr); ! 57: *retval = snprintf(buf, len, "%s", str); ! 58: return true; ! 59: } ! 60: ! 61: static bool nf_version(Uint32 stack, Uint32 subid, Uint32 *retval) ! 62: { ! 63: Dprintf(("NF version() -> 0x00010000\n")); ! 64: *retval = 0x00010000; ! 65: return true; ! 66: } ! 67: ! 68: static bool nf_stderr(Uint32 stack, Uint32 subid, Uint32 *retval) ! 69: { ! 70: const char *str; ! 71: Uint32 ptr; ! 72: ! 73: ptr = STMemory_ReadLong(stack); ! 74: //Dprintf(("NF stderr(0x%x)\n", ptr)); ! 75: ! 76: if (!STMemory_ValidArea(ptr, 1)) { ! 77: M68000_BusError(ptr, BUS_ERROR_READ); ! 78: return false; ! 79: } ! 80: str = (const char *)STRAM_ADDR(ptr); ! 81: *retval = fprintf(stderr, "%s", str); ! 82: fflush(stderr); ! 83: return true; ! 84: } ! 85: ! 86: static bool nf_shutdown(Uint32 stack, Uint32 subid, Uint32 *retval) ! 87: { ! 88: Dprintf(("NF shutdown()\n")); ! 89: ConfigureParams.Log.bConfirmQuit = false; ! 90: Main_RequestQuit(); ! 91: return true; ! 92: } ! 93: ! 94: /* ---------------------------- */ ! 95: ! 96: #define FEATNAME_MAX 16 ! 97: ! 98: static const struct { ! 99: const char *name; /* feature name */ ! 100: bool super; /* should be called only in supervisor mode */ ! 101: bool (*cb)(Uint32 stack, Uint32 subid, Uint32 *retval); ! 102: } features[] = { ! 103: { "NF_NAME", false, nf_name }, ! 104: { "NF_VERSION", false, nf_version }, ! 105: { "NF_STDERR", false, nf_stderr }, ! 106: { "NF_SHUTDOWN", true, nf_shutdown } ! 107: }; ! 108: ! 109: /* macros from Aranym */ ! 110: #define ID_SHIFT 20 ! 111: #define IDX2MASTERID(idx) (((idx)+1) << ID_SHIFT) ! 112: #define MASTERID2IDX(id) (((id) >> ID_SHIFT)-1) ! 113: #define MASKOUTMASTERID(id) ((id) & ((1L << ID_SHIFT)-1)) ! 114: ! 115: ! 116: /** ! 117: * Set retval to internal ID for requested Native Feature, ! 118: * or zero if feature is unknown/unsupported. ! 119: * ! 120: * Return true if caller is to proceed normally, ! 121: * false if there was an exception. ! 122: */ ! 123: bool NatFeat_ID(Uint32 stack, Uint32 *retval) ! 124: { ! 125: const char *name; ! 126: Uint32 ptr; ! 127: int i; ! 128: ! 129: ptr = STMemory_ReadLong(stack); ! 130: if (!STMemory_ValidArea(ptr, FEATNAME_MAX)) { ! 131: M68000_BusError(ptr, BUS_ERROR_READ); ! 132: return false; ! 133: } ! 134: ! 135: name = (const char *)STRAM_ADDR(ptr); ! 136: Dprintf(("NF ID(0x%x)\n", ptr)); ! 137: Dprintf((" \"%s\"\n", name)); ! 138: ! 139: for (i = 0; i < ARRAYSIZE(features); i++) { ! 140: if (strcmp(features[i].name, name) == 0) { ! 141: *retval = IDX2MASTERID(i); ! 142: return true; ! 143: } ! 144: } ! 145: /* unknown feature */ ! 146: *retval = 0; ! 147: return true; ! 148: } ! 149: ! 150: /** ! 151: * Do given Native Feature, if it is supported ! 152: * and set 'retval' accordingly. ! 153: * ! 154: * Return true if caller is to proceed normally, ! 155: * false if there was an exception. ! 156: */ ! 157: bool NatFeat_Call(Uint32 stack, bool super, Uint32 *retval) ! 158: { ! 159: Uint32 subid = STMemory_ReadLong(stack); ! 160: unsigned int idx = MASTERID2IDX(subid); ! 161: subid = MASKOUTMASTERID(subid); ! 162: ! 163: if (idx >= ARRAYSIZE(features)) { ! 164: Dprintf(("ERROR: invalid NF ID %d requested\n", idx)); ! 165: return true; /* undefined */ ! 166: } ! 167: if (features[idx].super && !super) { ! 168: Dprintf(("ERROR: NF function %d called without supervisor mode\n", idx)); ! 169: Exception(8, 0, M68000_EXC_SRC_CPU); ! 170: return false; ! 171: } ! 172: stack += SIZE_LONG; ! 173: return features[idx].cb(stack, subid, retval); ! 174: }
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.