blob: 7619fe2698d6c74c9fda5f2e43c0a309b995a147 [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>
swissChilic6b4f7e2020-08-09 16:36:36 -07009#include <errno.h>
swissChili6c61a792020-07-28 16:29:20 -070010#include <stdio.h>
11#include <stdlib.h>
12#include <unistd.h>
swissChilib71e0272020-08-08 15:56:14 -070013#include <pthread.h>
swissChilic6b4f7e2020-08-09 16:36:36 -070014#include <mqueue.h>
15#include <sys/stat.h>
swissChilib71e0272020-08-08 15:56:14 -070016
17
18void cleanup_screen_thread(pthread_t thread)
19{
swissChilib71e0272020-08-08 15:56:14 -070020 puts("Cleaning up screen...");
swissChilic6b4f7e2020-08-09 16:36:36 -070021 pthread_cancel(thread);
swissChilib71e0272020-08-08 15:56:14 -070022}
swissChilic6b4f7e2020-08-09 16:36:36 -070023
24void cleanup_debug_prompt_thread(pthread_t thread)
25{
26 puts("Cleaning up debug prompt...");
27 pthread_cancel(thread);
28}
swissChilib71e0272020-08-08 15:56:14 -070029
swissChili6c61a792020-07-28 16:29:20 -070030int main(int argc, char **argv)
31{
swissChilida4803e2020-08-06 20:06:04 -070032 bool disflag = false,
33 runflag = false,
34 helpflag = false,
35 debugflag = false,
swissChilidbbd5402020-08-07 15:07:39 -070036 should_read = false,
swissChili94ba1f52020-08-08 11:39:10 -070037 guiflag = false,
swissChilib71e0272020-08-08 15:56:14 -070038 scrflag = false,
39 nohaltflag = false;
swissChilida4803e2020-08-06 20:06:04 -070040
41 int disasm_len = 0;
swissChili62d6d5d2020-07-30 20:12:47 -070042
43 FILE *input = stdin;
swissChili6c61a792020-07-28 16:29:20 -070044
45 char c;
46
swissChilib71e0272020-08-08 15:56:14 -070047 while ((c = getopt(argc, argv, "HDsdrhgi:n:")) != -1)
swissChili6c61a792020-07-28 16:29:20 -070048 {
49 switch (c)
50 {
swissChilib71e0272020-08-08 15:56:14 -070051 case 'H':
52 nohaltflag = true;
53 break;
swissChili62d6d5d2020-07-30 20:12:47 -070054 case 'd':
55 disflag = true;
56 should_read = true;
57 break;
58 case 'r':
59 runflag = true;
60 should_read = true;
61 break;
62 case 'D':
63 debugflag = true;
64 should_read = true;
65 break;
swissChilidbbd5402020-08-07 15:07:39 -070066 case 'g':
67 guiflag = true;
68 should_read = true;
69 break;
swissChili62d6d5d2020-07-30 20:12:47 -070070 case 'i':
71 input = fopen(optarg, "r");
72 break;
swissChilida4803e2020-08-06 20:06:04 -070073 case 'n':
74 disasm_len = atoi(optarg);
75 break;
swissChili94ba1f52020-08-08 11:39:10 -070076 case 's':
77 scrflag = true;
78 break;
swissChili62d6d5d2020-07-30 20:12:47 -070079 case 'h':
80 case '?':
81 helpflag = 1;
82 break;
swissChili6c61a792020-07-28 16:29:20 -070083 }
84 }
85
86 if (helpflag)
87 {
swissChili62d6d5d2020-07-30 20:12:47 -070088 printf("6502 emulator, disassembler and debugger\n"
89 "Usage:\n"
swissChilibb478f12020-08-07 20:45:07 -070090 " -g use GUI\n"
swissChilib71e0272020-08-08 15:56:14 -070091 " -s use SDL screen (faster than GUI debugger)\n"
92 " -H keep running after CPU halts (useful on windows and to look at screen)\n"
swissChili62d6d5d2020-07-30 20:12:47 -070093 " -d disassemble input\n"
94 " -r run input\n"
swissChilibb478f12020-08-07 20:45:07 -070095 " -D open CLI debug prompt (like gdb)\n"
swissChili62d6d5d2020-07-30 20:12:47 -070096 " -i <input> set input file, defaults to standard input\n"
swissChilida4803e2020-08-06 20:06:04 -070097 " -n <number> number of instructions to disassemble, 0 for all\n"
swissChili62d6d5d2020-07-30 20:12:47 -070098 " -h, -? show this help page\n");
swissChili6c61a792020-07-28 16:29:20 -070099 return 0;
100 }
101
swissChili62d6d5d2020-07-30 20:12:47 -0700102 cpu_t cpu;
swissChilic6b4f7e2020-08-09 16:36:36 -0700103 mqd_t mq_to_cpu;
104
105 struct mq_attr attrs;
106 attrs.mq_maxmsg = 10;
107 attrs.mq_msgsize = MQ_BUF_LEN;
swissChili62d6d5d2020-07-30 20:12:47 -0700108
109 if (should_read)
110 {
111 cpu = new_cpu();
swissChilibb478f12020-08-07 20:45:07 -0700112 fread(cpu.mem + 0x600, 0xFFFF - 0x600, 1, input);
swissChilic6b4f7e2020-08-09 16:36:36 -0700113
114 int unlink = mq_unlink(MQ_NAME);
115 if (unlink < 0 && errno != ENOENT)
116 {
117 printf("Warning: mq_unlink() error: %d %s\n", errno, strerror(errno));
118 }
119
120 mq_to_cpu = mq_open(MQ_NAME, O_RDWR | O_CREAT | O_NONBLOCK, S_IWUSR|S_IRUSR, &attrs);
121 printf("error after mq_open (%ld) = %d %s\n", attrs.mq_msgsize, errno, strerror(errno));
122 ASSERT("Open message queue for emulator", mq_to_cpu > 0)
123
124 mq_send(mq_to_cpu, "init", 5, 2);
swissChili62d6d5d2020-07-30 20:12:47 -0700125 }
swissChilida4803e2020-08-06 20:06:04 -0700126 else
127 {
128 puts("6502 toolchain by swissChili <swisschili.sh>");
129 printf("%s -h for help\n", argv[0]);
130 }
swissChili6c61a792020-07-28 16:29:20 -0700131
swissChili94ba1f52020-08-08 11:39:10 -0700132 if (scrflag)
133 {
swissChilib71e0272020-08-08 15:56:14 -0700134 CATCH(&cleanup_screen_thread, start_screen_thread(cpu.mem + CPU_FB_ADDR));
swissChili94ba1f52020-08-08 11:39:10 -0700135 }
136
swissChilib71e0272020-08-08 15:56:14 -0700137 if (guiflag && scrflag)
138 {
139 THROW("-g and -s cannot be used together");
140 }
141
swissChilidbbd5402020-08-07 15:07:39 -0700142 if (guiflag)
143 {
swissChilic6b4f7e2020-08-09 16:36:36 -0700144 start_gui(mq_to_cpu, &cpu);
145 run_mq(&cpu, mq_to_cpu);
swissChilidbbd5402020-08-07 15:07:39 -0700146 }
147 else if (disflag)
swissChili6c61a792020-07-28 16:29:20 -0700148 {
swissChilic6b4f7e2020-08-09 16:36:36 -0700149 disas_num(&cpu, 64);
swissChili6c61a792020-07-28 16:29:20 -0700150 }
swissChilida4803e2020-08-06 20:06:04 -0700151 else if (runflag)
152 {
153 run(&cpu);
swissChilib71e0272020-08-08 15:56:14 -0700154 if (nohaltflag)
155 {
156 puts("Press any key to exit");
157 getchar();
158 }
swissChilida4803e2020-08-06 20:06:04 -0700159 }
swissChili62d6d5d2020-07-30 20:12:47 -0700160 else if (debugflag)
161 {
swissChilic6b4f7e2020-08-09 16:36:36 -0700162 CATCH(&cleanup_debug_prompt_thread, start_debug_prompt(mq_to_cpu, &cpu));
163 run_mq(&cpu, mq_to_cpu);
swissChili62d6d5d2020-07-30 20:12:47 -0700164 }
swissChilicc27cfe2020-08-08 12:57:57 -0700165
swissChili4bccd442020-08-11 13:55:10 -0700166 unwind();
167
swissChili62d6d5d2020-07-30 20:12:47 -0700168 if (should_read)
swissChilic6b4f7e2020-08-09 16:36:36 -0700169 {
swissChili62d6d5d2020-07-30 20:12:47 -0700170 free_cpu(&cpu);
swissChilic6b4f7e2020-08-09 16:36:36 -0700171 mq_close(mq_to_cpu);
172 }
swissChili6c61a792020-07-28 16:29:20 -0700173}