1 /*
2 * natfeat.c - NatFeats API examples
3 *
4 * Copyright (c) 2014 by Eero Tamminen
5 *
6 * NF initialization & calling is based on EmuTOS code,
7 * Copyright (c) 2001-2003 The EmuTOS development team
8 *
9 * This file is distributed under the GPL, version 2 or at your
10 * option any later version. See doc/license.txt for details.
11 */
12
13 #if __GNUC__
14 # include <mint/osbind.h>
15 #else /* VBCC/AHCC/Pure-C */
16 # include <tos.h>
17 #endif
18 #include "natfeats.h"
19
20
21 /* NatFeats available & initialized */
22 static int nf_ok;
23
24 /* handles for NF features that may be used more frequently */
25 static long nfid_print, nfid_debugger, nfid_fastforward;
26
27
28 /* API documentation is in natfeats.h header */
29
nf_init(void)30 int nf_init(void)
31 {
32 void *sup = (void*)Super(0);
33 nf_ok = detect_nf();
34 Super(sup);
35
36 if (nf_ok) {
37 /* initialize commonly used handles */
38 nfid_print = nf_id("NF_STDERR");
39 nfid_debugger = nf_id("NF_DEBUGGER");
40 nfid_fastforward = nf_id("NF_FASTFORWARD");
41 } else {
42 Cconws("Native Features initialization failed!\r\n");
43 }
44 return nf_ok;
45 }
46
nf_print(const char * text)47 long nf_print(const char *text)
48 {
49 if (nfid_print) {
50 return nf_call(nfid_print, text);
51 } else {
52 Cconws("NF_STDERR unavailable!\r\n");
53 return 0;
54 }
55 }
56
nf_debugger(void)57 long nf_debugger(void)
58 {
59 if (nfid_debugger) {
60 return nf_call(nfid_debugger);
61 } else {
62 Cconws("NF_DEBUGGER unavailable!\r\n");
63 return 0;
64 }
65 }
66
nf_fastforward(long enabled)67 long nf_fastforward(long enabled)
68 {
69 if (nfid_fastforward) {
70 return nf_call(nfid_fastforward, enabled);
71 } else {
72 Cconws("NF_FASTFORWARD unavailable!\r\n");
73 return 0;
74 }
75 }
76
nf_shutdown(void)77 void nf_shutdown(void)
78 {
79 long id;
80 if(nf_ok && (id = nf_id("NF_SHUTDOWN"))) {
81 void *sup = (void*)Super(0);
82 /* needs to be called in supervisor mode */
83 nf_call(id);
84 Super(sup);
85 } else {
86 Cconws("NF_SHUTDOWN unavailable!\r\n");
87 }
88 }
89
nf_exit(long exitval)90 void nf_exit(long exitval)
91 {
92 long id;
93 if(nf_ok && (id = nf_id("NF_EXIT"))) {
94 nf_call(id, exitval);
95 } else {
96 /* NF_EXIT is Hatari specific, NF_SHUTDOWN isn't */
97 Cconws("NF_EXIT unavailable, trying NF_SHUTDOWN...\r\n");
98 nf_shutdown();
99 }
100 }
101
102 #ifdef TEST
103
104 /* show emulator name */
nf_showname(void)105 static void nf_showname(void)
106 {
107 long id;
108 if (nf_ok && (id = nf_id("NF_NAME"))) {
109 long chars;
110 char buffer[64];
111 id |= 0x0001; /* name + version */
112 chars = nf_call(id, buffer, sizeof(buffer)-2);
113 buffer[chars++] = '\n';
114 buffer[chars++] = '\0';
115 nf_print(buffer);
116 } else {
117 Cconws("NF_NAME unavailable!\r\n");
118 }
119 }
120
wait_key(void)121 static int wait_key(void)
122 {
123 while (Cconis()) {
124 Cconin();
125 }
126 Cconws("\r\n<press key>\r\n");
127 return Cconin();
128 }
129
main()130 int main()
131 {
132 long old_ff;
133 if (!nf_init()) {
134 wait_key();
135 return 1;
136 }
137 old_ff = nf_fastforward(1);
138 nf_print("Emulator name:\n");
139 nf_showname();
140 nf_print("Shutting down...\n");
141 nf_fastforward(old_ff);
142 nf_exit(0);
143 wait_key();
144 return 0;
145 }
146
147 #endif
148