|
|
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.