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