src/platform/commandline.c (view raw)
1#include "commandline.h"
2
3#ifdef USE_CLI_DEBUGGER
4#include "debugger/cli-debugger.h"
5#endif
6
7#ifdef USE_GDB_STUB
8#include "debugger/gdb-stub.h"
9#endif
10
11#include <fcntl.h>
12#include <getopt.h>
13
14static const char* _defaultFilename = "test.rom";
15
16static const struct option _options[] = {
17 { "bios", 1, 0, 'b' },
18#ifdef USE_CLI_DEBUGGER
19 { "debug", 1, 0, 'd' },
20#endif
21#ifdef USE_GDB_STUB
22 { "gdb", 1, 0, 'g' },
23#endif
24 { 0, 0, 0, 0 }
25};
26
27int parseCommandArgs(struct StartupOptions* opts, int argc, char* const* argv, const char* extraOptions) {
28 memset(opts, 0, sizeof(*opts));
29 opts->fd = -1;
30 opts->biosFd = -1;
31 opts->width = 240;
32 opts->height = 160;
33 opts->fullscreen = 0;
34
35 int multiplier = 1;
36 int ch;
37 char options[64] =
38 "b:"
39#ifdef USE_CLI_DEBUGGER
40 "d"
41#endif
42#ifdef USE_GDB_STUB
43 "g"
44#endif
45 ;
46 if (extraOptions) {
47 strncat(options, extraOptions, sizeof(options) - strlen(options) - 1);
48 }
49 while ((ch = getopt_long(argc, argv, options, _options, 0)) != -1) {
50 switch (ch) {
51 case 'b':
52 opts->biosFd = open(optarg, O_RDONLY);
53 break;
54#ifdef USE_CLI_DEBUGGER
55 case 'd':
56 if (opts->debuggerType != DEBUGGER_NONE) {
57 return 0;
58 }
59 opts->debuggerType = DEBUGGER_CLI;
60 break;
61#endif
62 case 'f':
63 opts->fullscreen = 1;
64 break;
65#ifdef USE_GDB_STUB
66 case 'g':
67 if (opts->debuggerType != DEBUGGER_NONE) {
68 return 0;
69 }
70 opts->debuggerType = DEBUGGER_GDB;
71 break;
72#endif
73 case '2':
74 if (multiplier != 1) {
75 return 0;
76 }
77 multiplier = 2;
78 break;
79 case '3':
80 if (multiplier != 1) {
81 return 0;
82 }
83 multiplier = 3;
84 break;
85 case '4':
86 if (multiplier != 1) {
87 return 0;
88 }
89 multiplier = 4;
90 break;
91 default:
92 return 0;
93 }
94 }
95 argc -= optind;
96 argv += optind;
97 if (argc == 1) {
98 opts->fname = argv[0];
99 } else if (argc == 0) {
100 opts->fname = _defaultFilename;
101 } else {
102 return 0;
103 }
104 opts->fd = open(opts->fname, O_RDONLY);
105 opts->width *= multiplier;
106 opts->height *= multiplier;
107 return 1;
108}
109
110struct ARMDebugger* createDebugger(struct StartupOptions* opts) {
111 union DebugUnion {
112 struct ARMDebugger d;
113#ifdef USE_CLI_DEBUGGER
114 struct CLIDebugger cli;
115#endif
116#ifdef USE_GDB_STUB
117 struct GDBStub gdb;
118#endif
119 };
120
121 union DebugUnion* debugger = malloc(sizeof(union DebugUnion));
122
123 switch (opts->debuggerType) {
124#ifdef USE_CLI_DEBUGGER
125 case DEBUGGER_CLI:
126 CLIDebuggerCreate(&debugger->cli);
127 break;
128#endif
129#ifdef USE_GDB_STUB
130 case DEBUGGER_GDB:
131 GDBStubCreate(&debugger->gdb);
132 GDBStubListen(&debugger->gdb, 2345, 0);
133 break;
134#endif
135 case DEBUGGER_NONE:
136 case DEBUGGER_MAX:
137 free(debugger);
138 return 0;
139 break;
140 }
141
142 return &debugger->d;
143}
144
145void usage(const char* arg0, const char* extraOptions) {
146 printf("usage: %s [option ...] file\n", arg0);
147 puts("\nGeneric options:");
148 puts(" -b, --bios FILE GBA BIOS file to use");
149#ifdef USE_CLI_DEBUGGER
150 puts(" -d, --debug Use command-line debugger");
151#endif
152#ifdef USE_GDB_STUB
153 puts(" -g, --gdb Start GDB session (default port 2345)");
154#endif
155 if (extraOptions) {
156 puts(extraOptions);
157 }
158}