fork of PCE focusing on macplus, supporting DaynaPort SCSI network emulation
1/*****************************************************************************
2 * pce *
3 *****************************************************************************/
4
5/*****************************************************************************
6 * File name: src/arch/cpm80/msg.c *
7 * Created: 2012-11-30 by Hampa Hug <hampa@hampa.ch> *
8 * Copyright: (C) 2012-2021 Hampa Hug <hampa@hampa.ch> *
9 *****************************************************************************/
10
11/*****************************************************************************
12 * This program is free software. You can redistribute it and / or modify it *
13 * under the terms of the GNU General Public License version 2 as published *
14 * by the Free Software Foundation. *
15 * *
16 * This program is distributed in the hope that it will be useful, but *
17 * WITHOUT ANY WARRANTY, without even the implied warranty of *
18 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General *
19 * Public License for more details. *
20 *****************************************************************************/
21
22
23#include "main.h"
24#include "cpm80.h"
25#include "msg.h"
26
27#include <string.h>
28
29#include <drivers/block/block.h>
30
31#include <lib/console.h>
32#include <lib/inidsk.h>
33#include <lib/log.h>
34#include <lib/monitor.h>
35#include <lib/msg.h>
36
37
38typedef struct {
39 const char *msg;
40
41 int (*set_msg) (cpm80_t *sim, const char *msg, const char *val);
42} c80_msg_list_t;
43
44
45extern monitor_t par_mon;
46extern cpm80_t *par_sim;
47
48
49static
50int c80_set_msg_emu_aux_read (cpm80_t *sim, const char *msg, const char *val)
51{
52 if (c80_set_aux_read (sim, (*val == 0) ? NULL : val)) {
53 pce_log (MSG_ERR, "*** can't open file (%s)\n", val);
54 }
55
56 return (0);
57}
58
59static
60int c80_set_msg_emu_aux_write (cpm80_t *sim, const char *msg, const char *val)
61{
62 if (c80_set_aux_write (sim, (*val == 0) ? NULL : val, 1)) {
63 pce_log (MSG_ERR, "*** can't open file (%s)\n", val);
64 }
65
66 return (0);
67}
68
69static
70int c80_set_msg_emu_con_read (cpm80_t *sim, const char *msg, const char *val)
71{
72 if (c80_set_con_read (sim, (*val == 0) ? NULL : val)) {
73 pce_log (MSG_ERR, "*** can't open file (%s)\n", val);
74 }
75
76 return (0);
77}
78
79static
80int c80_set_msg_emu_con_write (cpm80_t *sim, const char *msg, const char *val)
81{
82 if (c80_set_con_write (sim, (*val == 0) ? NULL : val, 1)) {
83 pce_log (MSG_ERR, "*** can't open file (%s)\n", val);
84 }
85
86 return (0);
87}
88
89static
90int c80_set_msg_emu_cpu_model (cpm80_t *sim, const char *msg, const char *val)
91{
92 if (c80_set_cpu_model (sim, val)) {
93 pce_log (MSG_ERR, "*** failed to set CPU model (%s)\n", val);
94 }
95
96 return (0);
97}
98
99static
100int c80_set_msg_emu_cpu_speed (cpm80_t *sim, const char *msg, const char *val)
101{
102 unsigned v;
103
104 if (msg_get_uint (val, &v)) {
105 return (1);
106 }
107
108 if (v > 4) {
109 v = 8 * (v - 4);
110 }
111
112 c80_set_speed (sim, v);
113
114 return (0);
115}
116
117static
118int c80_set_msg_emu_cpu_speed_double (cpm80_t *sim, const char *msg, const char *val)
119{
120 c80_set_speed (sim, 2 * sim->speed);
121
122 return (0);
123}
124
125static
126int c80_set_msg_emu_cpu_speed_half (cpm80_t *sim, const char *msg, const char *val)
127{
128 if (sim->speed > 1) {
129 c80_set_speed (sim, sim->speed / 2);
130 }
131
132 return (0);
133}
134
135static
136int c80_set_msg_emu_cpu_speed_step (cpm80_t *sim, const char *msg, const char *val)
137{
138 int v;
139
140 if (msg_get_sint (val, &v)) {
141 return (1);
142 }
143
144 v += (int) sim->speed;
145
146 if (v <= 0) {
147 v = 1;
148 }
149
150 c80_set_speed (sim, v);
151
152 return (0);
153}
154
155static
156int c80_set_msg_emu_disk_commit (cpm80_t *sim, const char *msg, const char *val)
157{
158 int r;
159 unsigned drv;
160
161 if (strcmp (val, "all") == 0) {
162 pce_log (MSG_INF, "commiting all drives\n");
163
164 if (dsks_commit (sim->dsks)) {
165 pce_log (MSG_ERR,
166 "*** commit failed for at least one disk\n"
167 );
168 return (1);
169 }
170
171 return (0);
172 }
173
174 r = 0;
175
176 while (*val != 0) {
177 if (msg_get_prefix_uint (&val, &drv, ":", " \t")) {
178 pce_log (MSG_ERR, "*** commit error: bad drive (%s)\n",
179 val
180 );
181
182 return (1);
183 }
184
185 pce_log (MSG_INF, "commiting drive %u\n", drv);
186
187 if (dsks_set_msg (sim->dsks, drv, "commit", NULL)) {
188 pce_log (MSG_ERR, "*** commit error for drive %u\n",
189 drv
190 );
191
192 r = 1;
193 }
194 }
195
196 return (r);
197}
198
199static
200int c80_set_msg_emu_disk_eject (cpm80_t *sim, const char *msg, const char *val)
201{
202 unsigned drv;
203 disk_t *dsk;
204
205 while (*val != 0) {
206 if (msg_get_prefix_uint (&val, &drv, ":", " \t")) {
207 pce_log (MSG_ERR,
208 "*** disk eject error: bad drive (%s)\n",
209 val
210 );
211
212 return (1);
213 }
214
215 dsk = dsks_get_disk (sim->dsks, drv);
216
217 if (dsk == NULL) {
218 pce_log (MSG_ERR,
219 "*** disk eject error: no such disk (%lu)\n", drv
220 );
221 }
222 else {
223 pce_log (MSG_INF, "ejecting drive %lu\n", drv);
224
225 dsks_rmv_disk (sim->dsks, dsk);
226
227 dsk_del (dsk);
228 }
229 }
230
231 return (0);
232}
233
234static
235int c80_set_msg_emu_disk_insert (cpm80_t *sim, const char *msg, const char *val)
236{
237 if (dsk_insert (sim->dsks, val, 1)) {
238 return (1);
239 }
240
241 return (0);
242}
243
244static
245int c80_set_msg_emu_exit (cpm80_t *sim, const char *msg, const char *val)
246{
247 sim->brk = PCE_BRK_ABORT;
248
249 mon_set_terminate (&par_mon, 1);
250
251 return (0);
252}
253
254static
255int c80_set_msg_emu_reset (cpm80_t *sim, const char *msg, const char *val)
256{
257 c80_reset (sim);
258
259 return (0);
260}
261
262static
263int c80_set_msg_emu_stop (cpm80_t *sim, const char *msg, const char *val)
264{
265 sim->brk = PCE_BRK_STOP;
266
267 return (0);
268}
269
270static c80_msg_list_t set_msg_list[] = {
271 { "emu.aux.read", c80_set_msg_emu_aux_read },
272 { "emu.aux.write", c80_set_msg_emu_aux_write },
273 { "emu.con.read", c80_set_msg_emu_con_read },
274 { "emu.con.write", c80_set_msg_emu_con_write },
275 { "emu.cpu.model", c80_set_msg_emu_cpu_model },
276 { "emu.cpu.speed", c80_set_msg_emu_cpu_speed },
277 { "emu.cpu.speed.double", c80_set_msg_emu_cpu_speed_double },
278 { "emu.cpu.speed.half", c80_set_msg_emu_cpu_speed_half },
279 { "emu.cpu.speed.step", c80_set_msg_emu_cpu_speed_step },
280 { "emu.disk.commit", c80_set_msg_emu_disk_commit },
281 { "emu.disk.eject", c80_set_msg_emu_disk_eject },
282 { "emu.disk.insert", c80_set_msg_emu_disk_insert },
283 { "emu.exit", c80_set_msg_emu_exit },
284 { "emu.reset", c80_set_msg_emu_reset },
285 { "emu.stop", c80_set_msg_emu_stop },
286 { NULL, NULL }
287};
288
289
290int c80_set_msg (cpm80_t *sim, const char *msg, const char *val)
291{
292 c80_msg_list_t *lst;
293
294 /* a hack, for debugging only */
295 if (sim == NULL) {
296 sim = par_sim;
297 }
298
299 if (msg == NULL) {
300 return (1);
301 }
302
303 if (val == NULL) {
304 val = "";
305 }
306
307 lst = set_msg_list;
308
309 while (lst->msg != NULL) {
310 if (msg_is_message (lst->msg, msg)) {
311 return (lst->set_msg (sim, msg, val));
312 }
313
314 lst += 1;
315 }
316
317 if (msg_is_prefix ("term", msg)) {
318 return (1);
319 }
320
321 pce_log (MSG_INF, "unhandled message (\"%s\", \"%s\")\n", msg, val);
322
323 return (1);
324}