blob: 3b1da4668eec0f74c39ddb61e22ef342bfff5e72 [file] [log] [blame]
swissChilib71e0272020-08-08 15:56:14 -07001#include "common.h"
swissChili6c61a792020-07-28 16:29:20 -07002#include "cpu.h"
swissChili62d6d5d2020-07-30 20:12:47 -07003#include "dbg.h"
swissChilidbbd5402020-08-07 15:07:39 -07004#include "gui.h"
swissChili94ba1f52020-08-08 11:39:10 -07005#include "screen.h"
swissChili6c61a792020-07-28 16:29:20 -07006
swissChili62d6d5d2020-07-30 20:12:47 -07007#include <bits/getopt_core.h>
swissChili6c61a792020-07-28 16:29:20 -07008#include <ctype.h>
9#include <stdio.h>
10#include <stdlib.h>
11#include <unistd.h>
12
swissChili94ba1f52020-08-08 11:39:10 -070013extern sdl_screen_t *g_scr;
14
swissChilib71e0272020-08-08 15:56:14 -070015#ifndef NO_PTHREAD
16#include <pthread.h>
17
18
19void cleanup_screen_thread(pthread_t thread)
20{
21 g_screen_thread_halt = true;
22 puts("Cleaning up screen...");
23 pthread_join(thread, NULL);
24}
25#endif
26
swissChili6c61a792020-07-28 16:29:20 -070027int main(int argc, char **argv)
28{
swissChilida4803e2020-08-06 20:06:04 -070029 bool disflag = false,
30 runflag = false,
31 helpflag = false,
32 debugflag = false,
swissChilidbbd5402020-08-07 15:07:39 -070033 should_read = false,
swissChili94ba1f52020-08-08 11:39:10 -070034 guiflag = false,
swissChilib71e0272020-08-08 15:56:14 -070035 scrflag = false,
36 nohaltflag = false;
swissChilida4803e2020-08-06 20:06:04 -070037
38 int disasm_len = 0;
swissChili62d6d5d2020-07-30 20:12:47 -070039
40 FILE *input = stdin;
swissChili6c61a792020-07-28 16:29:20 -070041
42 char c;
43
swissChilib71e0272020-08-08 15:56:14 -070044 while ((c = getopt(argc, argv, "HDsdrhgi:n:")) != -1)
swissChili6c61a792020-07-28 16:29:20 -070045 {
46 switch (c)
47 {
swissChilib71e0272020-08-08 15:56:14 -070048 case 'H':
49 nohaltflag = true;
50 break;
swissChili62d6d5d2020-07-30 20:12:47 -070051 case 'd':
52 disflag = true;
53 should_read = true;
54 break;
55 case 'r':
56 runflag = true;
57 should_read = true;
58 break;
59 case 'D':
60 debugflag = true;
61 should_read = true;
62 break;
swissChilidbbd5402020-08-07 15:07:39 -070063 case 'g':
64 guiflag = true;
65 should_read = true;
66 break;
swissChili62d6d5d2020-07-30 20:12:47 -070067 case 'i':
68 input = fopen(optarg, "r");
69 break;
swissChilida4803e2020-08-06 20:06:04 -070070 case 'n':
71 disasm_len = atoi(optarg);
72 break;
swissChili94ba1f52020-08-08 11:39:10 -070073 case 's':
74 scrflag = true;
75 break;
swissChili62d6d5d2020-07-30 20:12:47 -070076 case 'h':
77 case '?':
78 helpflag = 1;
79 break;
swissChili6c61a792020-07-28 16:29:20 -070080 }
81 }
82
83 if (helpflag)
84 {
swissChili62d6d5d2020-07-30 20:12:47 -070085 printf("6502 emulator, disassembler and debugger\n"
86 "Usage:\n"
swissChilibb478f12020-08-07 20:45:07 -070087 " -g use GUI\n"
swissChilib71e0272020-08-08 15:56:14 -070088 " -s use SDL screen (faster than GUI debugger)\n"
89 " -H keep running after CPU halts (useful on windows and to look at screen)\n"
swissChili62d6d5d2020-07-30 20:12:47 -070090 " -d disassemble input\n"
91 " -r run input\n"
swissChilibb478f12020-08-07 20:45:07 -070092 " -D open CLI debug prompt (like gdb)\n"
swissChili62d6d5d2020-07-30 20:12:47 -070093 " -i <input> set input file, defaults to standard input\n"
swissChilida4803e2020-08-06 20:06:04 -070094 " -n <number> number of instructions to disassemble, 0 for all\n"
swissChili62d6d5d2020-07-30 20:12:47 -070095 " -h, -? show this help page\n");
swissChili6c61a792020-07-28 16:29:20 -070096 return 0;
97 }
98
swissChili62d6d5d2020-07-30 20:12:47 -070099 cpu_t cpu;
100
101 if (should_read)
102 {
103 cpu = new_cpu();
swissChilibb478f12020-08-07 20:45:07 -0700104 fread(cpu.mem + 0x600, 0xFFFF - 0x600, 1, input);
swissChili62d6d5d2020-07-30 20:12:47 -0700105 }
swissChilida4803e2020-08-06 20:06:04 -0700106 else
107 {
108 puts("6502 toolchain by swissChili <swisschili.sh>");
109 printf("%s -h for help\n", argv[0]);
110 }
swissChili6c61a792020-07-28 16:29:20 -0700111
swissChili94ba1f52020-08-08 11:39:10 -0700112 if (scrflag)
113 {
swissChilicc27cfe2020-08-08 12:57:57 -0700114#ifndef NO_PTHREAD
swissChilib71e0272020-08-08 15:56:14 -0700115 CATCH(&cleanup_screen_thread, start_screen_thread(cpu.mem + CPU_FB_ADDR));
swissChilicc27cfe2020-08-08 12:57:57 -0700116#else
swissChili94ba1f52020-08-08 11:39:10 -0700117 sdl_screen_t scr = new_sdl_screen(8);
118 g_scr = &scr;
swissChilicc27cfe2020-08-08 12:57:57 -0700119#endif
swissChili94ba1f52020-08-08 11:39:10 -0700120 }
121
swissChilib71e0272020-08-08 15:56:14 -0700122 if (guiflag && scrflag)
123 {
124 THROW("-g and -s cannot be used together");
125 }
126
swissChilidbbd5402020-08-07 15:07:39 -0700127 if (guiflag)
128 {
129 gui(&cpu);
130 }
131 else if (disflag)
swissChili6c61a792020-07-28 16:29:20 -0700132 {
swissChilic51e9222020-08-07 16:09:14 -0700133 disas_num(&cpu, 12);
swissChili6c61a792020-07-28 16:29:20 -0700134 }
swissChilida4803e2020-08-06 20:06:04 -0700135 else if (runflag)
136 {
137 run(&cpu);
swissChilib71e0272020-08-08 15:56:14 -0700138 if (nohaltflag)
139 {
140 puts("Press any key to exit");
141 getchar();
142 }
swissChilida4803e2020-08-06 20:06:04 -0700143 }
swissChili62d6d5d2020-07-30 20:12:47 -0700144 else if (debugflag)
145 {
146 debug(&cpu);
147 }
148
swissChilib71e0272020-08-08 15:56:14 -0700149#ifdef NO_PTHREAD
swissChilicc27cfe2020-08-08 12:57:57 -0700150 if (scrflag)
151 free_sdl_screen(g_scr);
swissChilib71e0272020-08-08 15:56:14 -0700152#endif
swissChilicc27cfe2020-08-08 12:57:57 -0700153
swissChili62d6d5d2020-07-30 20:12:47 -0700154 if (should_read)
155 free_cpu(&cpu);
swissChili6c61a792020-07-28 16:29:20 -0700156}