fork of PCE focusing on macplus, supporting DaynaPort SCSI network emulation
1/*****************************************************************************
2 * pce *
3 *****************************************************************************/
4
5/*****************************************************************************
6 * File name: src/lib/msgdsk.c *
7 * Created: 2019-06-22 by Hampa Hug <hampa@hampa.ch> *
8 * Copyright: (C) 2019 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 <stdio.h>
24#include <stdlib.h>
25
26#include <drivers/block/block.h>
27#include <drivers/block/blkpbi.h>
28#include <drivers/block/blkqed.h>
29
30#include <lib/console.h>
31#include <lib/log.h>
32#include <lib/msg.h>
33#include <lib/msgdsk.h>
34#include <lib/path.h>
35
36
37void msg_dsk_print_help (void)
38{
39 pce_puts (
40 "disk.commit [<id>]\n"
41 "disk.eject [<id>]\n"
42 "disk.id [<id>]\n"
43 "disk.insert <filename>\n"
44 "disk.ro [<id>]\n"
45 "disk.rw [<id>]\n"
46 );
47}
48
49void dsk_print_info (disk_t *dsk)
50{
51 unsigned p;
52
53 pce_printf ("ID=%-3u T=%-2u BLK=%-8lu",
54 dsk->drive, dsk->type, dsk_get_block_cnt (dsk)
55 );
56
57 p = pce_printf ("CHS=%u/%u/%u",
58 (unsigned long) dsk->c,
59 (unsigned long) dsk->h,
60 (unsigned long) dsk->s
61 );
62
63 while (p++ < 15) {
64 pce_putc (' ');
65 }
66
67 pce_printf ("%-2s FILE=%s\n",
68 dsk_get_readonly (dsk) ? "RO" : "RW",
69 dsk_get_fname (dsk)
70 );
71}
72
73void dsks_print_info (disks_t *dsks)
74{
75 unsigned i;
76 disk_t *dsk;
77 disk_pbi_t *pbi;
78 disk_qed_t *qed;
79
80 for (i = 0; i < dsks->cnt; i++) {
81 dsk = dsks->dsk[i];
82
83 while (dsk != NULL) {
84 dsk_print_info (dsk);
85
86 if (dsk->type == PCE_DISK_PBI) {
87 pbi = dsk->ext;
88 dsk = pbi->next;
89 }
90 else if (dsk->type == PCE_DISK_QED) {
91 qed = dsk->ext;
92 dsk = qed->next;
93 }
94 else {
95 dsk = NULL;
96 }
97 }
98 }
99}
100
101int msg_dsk_get_disk_id (const char *val, unsigned *id)
102{
103 unsigned tmp;
104
105 if ((val == NULL) || (*val == 0)) {
106 return (0);
107 }
108
109 if (msg_get_uint (val, &tmp)) {
110 pce_log (MSG_ERR, "*** bad disk id (%s)\n", val);
111 return (1);
112 }
113
114 *id = tmp;
115
116 return (0);
117}
118
119int msg_dsk_emu_disk_commit (const char *val, disks_t *dsks, unsigned *id)
120{
121 if (msg_dsk_get_disk_id (val, id)) {
122 return (1);
123 }
124
125 pce_log (MSG_INF, "commiting disk %u\n", *id);
126
127 if (dsks_set_msg (dsks, *id, "commit", NULL)) {
128 pce_log (MSG_ERR, "*** disk %u commit error\n", *id);
129 return (1);
130 }
131
132 return (0);
133}
134
135int msg_dsk_emu_disk_eject (const char *val, disks_t *dsks, unsigned *id)
136{
137 disk_t *dsk;
138
139 if (msg_dsk_get_disk_id (val, id)) {
140 return (1);
141 }
142
143 dsk = dsks_get_disk (dsks, *id);
144
145 if (dsk == NULL) {
146 pce_log (MSG_ERR,
147 "*** disk %u eject error: no such disk\n", *id
148 );
149 }
150 else {
151 pce_log (MSG_INF, "ejecting disk %u\n", *id);
152
153 dsks_rmv_disk (dsks, dsk);
154 dsk_del (dsk);
155 }
156
157 return (0);
158}
159
160int msg_dsk_emu_disk_id (const char *val, unsigned *id)
161{
162 if ((val == NULL) || (*val == 0)) {
163 pce_log (MSG_INF, "current disk id is %u\n", *id);
164 return (0);
165 }
166
167 if (msg_dsk_get_disk_id (val, id)) {
168 return (1);
169 }
170
171 return (0);
172}
173
174int msg_dsk_emu_disk_insert (const char *val, disks_t *dsks, unsigned id)
175{
176 disk_t *dsk, *old;
177 char *path;
178
179 if ((old = dsks_get_disk (dsks, id)) != NULL) {
180 pce_log (MSG_INF, "ejecting disk %u\n", id);
181 dsks_rmv_disk (dsks, old);
182 dsk_del (old);
183 }
184
185 path = pce_path_get (val);
186
187 pce_log (MSG_INF, "inserting disk %u (%s)\n", id, path);
188
189 if ((dsk = dsk_auto_open (path, 0, 0)) == NULL) {
190 pce_log (MSG_ERR,
191 "*** disk %u insert error: failed to open image (%s)\n",
192 id, path
193 );
194 free (path);
195 return (1);
196 }
197
198 dsk_set_drive (dsk, id);
199
200 free (path);
201
202 if (dsks_add_disk (dsks, dsk)) {
203 dsk_del (dsk);
204 return (1);
205 }
206
207 return (0);
208}
209
210int msg_dsk_emu_disk_ro (const char *val, disks_t *dsks, unsigned *id)
211{
212 disk_t *dsk;
213
214 if (msg_dsk_get_disk_id (val, id)) {
215 return (1);
216 }
217
218 dsk = dsks_get_disk (dsks, *id);
219
220 if (dsk != NULL) {
221 pce_log (MSG_INF, "setting disk %u to read-only\n", *id);
222
223 dsk_set_readonly (dsk, 1);
224 }
225
226 return (0);
227}
228
229int msg_dsk_emu_disk_rw (const char *val, disks_t *dsks, unsigned *id)
230{
231 disk_t *dsk;
232
233 if (msg_dsk_get_disk_id (val, id)) {
234 return (1);
235 }
236
237 dsk = dsks_get_disk (dsks, *id);
238
239 if (dsk != NULL) {
240 pce_log (MSG_INF, "setting disk %u to read/write\n", *id);
241
242 dsk_set_readonly (dsk, 0);
243 }
244
245 return (0);
246}
247
248int msg_dsk_set_msg (const char *msg, const char *val, disks_t *dsks, unsigned *id)
249{
250 if (msg_is_message ("disk.commit", msg)) {
251 return (msg_dsk_emu_disk_commit (val, dsks, id));
252 }
253 else if (msg_is_message ("disk.eject", msg)) {
254 return (msg_dsk_emu_disk_eject (val, dsks, id));
255 }
256 else if (msg_is_message ("disk.id", msg)) {
257 return (msg_dsk_emu_disk_id (val, id));
258 }
259 else if (msg_is_message ("disk.insert", msg)) {
260 return (msg_dsk_emu_disk_insert (val, dsks, *id));
261 }
262 else if (msg_is_message ("disk.ro", msg)) {
263 return (msg_dsk_emu_disk_ro (val, dsks, id));
264 }
265 else if (msg_is_message ("disk.rw", msg)) {
266 return (msg_dsk_emu_disk_rw (val, dsks, id));
267 }
268
269 return (-1);
270}