Subversion Repositories pentevo

Rev

Details | Last modification | View Log | RSS feed

Rev Author Line No. Line
716 lvd 1
#include "std.h"
2
 
3
#include "emul.h"
4
#include "vars.h"
5
#include "debug.h"
6
#include "dbgpaint.h"
7
#include "dbgtrace.h"
8
#include "util.h"
9
 
10
/*
11
     dialogs design
12
 
13
ÚÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ¿
14
³Read from TR-DOS file  ³
15
ÃÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ´
16
³drive: A               ³
17
³file:  12345678 C      ³
18
³start: E000 end: FFFF  ³
19
ÀÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÙ
20
 
21
ÚÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ¿
22
³Read from TR-DOS sector³
23
ÃÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ´
24
³drive: A               ³
25
³trk (00-9F): 00        ³
26
³sec (00-0F): 08        ³
27
³start: E000 end: FFFF  ³
28
ÀÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÙ
29
 
30
ÚÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ¿
31
³Read RAW sectors       ³
32
ÃÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ´
33
³drive: A               ³
34
³cyl (00-4F): 00 side: 0³
35
³sec (00-0F): 08 num: 01³
36
³start: E000            ³
37
ÀÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÙ
38
 
39
ÚÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ¿
40
³Read from host file    ³
41
ÃÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ´
42
³file: 12345678.bin     ³
43
³start: C000 end: FFFF  ³
44
ÀÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÙ
45
 
46
*/
47
 
48
enum FILEDLG_MODE { FDM_LOAD = 0, FDM_SAVE, FDM_DISASM };
49
 
50
unsigned addr = 0, end = 0xFFFF;
51
unsigned char *memdata;
52
unsigned rw_drive, rw_trk, rw_cyl, rw_tsec, rw_rsec, rw_side;
53
char fname[20] = "", trdname[9] = "12345678", trdext[2] = "C";
54
 
55
const int FILEDLG_X = 6;
56
const int FILEDLG_Y = 10;
57
const int FILEDLG_DX = 25;
58
 
59
static void rw_err(const char *msg)
60
{
61
   MessageBox(wnd, msg, "Error", MB_OK | MB_ICONERROR);
62
}
63
 
64
char query_file_addr(FILEDLG_MODE mode)
65
{
66
   filledframe(FILEDLG_X, FILEDLG_Y, FILEDLG_DX, 5);
67
   char ln[64];
68
   static const char *titles[] = { " Read from binary file   ",
69
                                   " Write to binary file    ",
70
                                   " Disasm to text file     " };
71
   tprint(FILEDLG_X, FILEDLG_Y, titles[mode], FRM_HEADER);
72
   tprint(FILEDLG_X+1, FILEDLG_Y+2, "file:", FFRAME_INSIDE);
73
   sprintf(ln, (mode != FDM_LOAD)? "start: %04X end: %04X" : "start: %04X", addr, end);
74
   tprint(FILEDLG_X+1, FILEDLG_Y+3, ln, FFRAME_INSIDE);
75
   strcpy(str, fname);
76
   for (;;)
77
   {
78
      if (!inputhex(FILEDLG_X+7,FILEDLG_Y+2,16, false))
79
          return 0;
80
      if (mode != FDM_LOAD)
81
          break;
82
      if (GetFileAttributes(str) != INVALID_FILE_ATTRIBUTES)
83
          break;
84
   }
85
   strcpy(fname, str);
86
   sprintf(ln, "%-16s", fname);
87
   fillattr(FILEDLG_X+7,FILEDLG_Y+2,16);
88
   unsigned a1 = input4(FILEDLG_X+8,FILEDLG_Y+3,addr);
89
   if (a1 == -1)
90
       return 0;
91
   addr = a1;
92
   fillattr(FILEDLG_X+8,FILEDLG_Y+3,4);
93
   if (mode == FDM_LOAD)
94
       return 1;
95
   for (;;)
96
   {
97
      unsigned e1 = input4(FILEDLG_X+18,FILEDLG_Y+3,end);
98
      if (e1 == -1)
99
          return 0;
100
      if (e1 < addr)
101
          continue;
102
      end = e1;
103
          return 1;
104
   }
105
}
106
 
107
void write_mem()
108
{
109
   Z80 &cpu = CpuMgr.Cpu();
110
   u8 *ptr = memdata;
111
   for(unsigned a1 = addr; a1 <= end; a1++)
112
      *cpu.DirectMem(a1) = *ptr++;
113
}
114
 
115
void read_mem()
116
{
117
   Z80 &cpu = CpuMgr.Cpu();
118
   unsigned char *ptr = memdata;
119
   for (unsigned a1 = addr; a1 <= end; a1++)
120
     *ptr++ = cpu.DirectRm(a1);
121
}
122
 
123
char rw_select_drive()
124
{
125
   tprint(FILEDLG_X+1, FILEDLG_Y+2, "drive:", FFRAME_INSIDE);
126
   for (;;) {
127
      *(unsigned*)str = 'A' + rw_drive;
128
      if (!inputhex(FILEDLG_X+8, FILEDLG_Y+2, 1, true)) return 0;
129
      fillattr(FILEDLG_X+8, FILEDLG_Y+2, 1);
130
      unsigned disk = *str - 'A';
131
      if (disk > 3) continue;
132
      if (!comp.wd.fdd[disk].rawdata) continue;
133
      rw_drive = disk; return 1;
134
   }
135
}
136
 
137
char rw_trdos_sectors(FILEDLG_MODE mode)
138
{
139
   filledframe(FILEDLG_X, FILEDLG_Y, FILEDLG_DX, 7);
140
   const char *title = (mode == FDM_LOAD)? " Read from TR-DOS sectors" :
141
                                     " Write to TR-DOS sectors ";
142
   tprint(FILEDLG_X, FILEDLG_Y, title, FRM_HEADER);
143
 
144
   char ln[64]; unsigned t;
145
 
146
   sprintf(ln, "trk (00-9F): %02X", rw_trk);
147
   tprint(FILEDLG_X+1, FILEDLG_Y+3, ln, FFRAME_INSIDE);
148
 
149
   sprintf(ln, "sec (00-0F): %02X", rw_tsec);
150
   tprint(FILEDLG_X+1, FILEDLG_Y+4, ln, FFRAME_INSIDE);
151
 
152
   sprintf(ln, "start: %04X end: %04X", addr, end);
153
   tprint(FILEDLG_X+1, FILEDLG_Y+5, ln, FFRAME_INSIDE);
154
 
155
   if (!rw_select_drive()) return 0;
156
   FDD *fdd = &comp.wd.fdd[rw_drive];
157
   // if (fdd->sides != 2) { rw_err("single-side TR-DOS disks are not supported"); return 0; }
158
 
159
   t = input2(FILEDLG_X+14, FILEDLG_Y+3, rw_trk);
160
   if (t == -1) return 0; else rw_trk = t;
161
   fillattr(FILEDLG_X+14, FILEDLG_Y+3, 2);
162
 
163
   t = input2(FILEDLG_X+14, FILEDLG_Y+4, rw_tsec);
164
   if (t == -1) return 0; else rw_tsec = t;
165
   fillattr(FILEDLG_X+14, FILEDLG_Y+4, 2);
166
 
167
   t = input4(FILEDLG_X+8,FILEDLG_Y+5,addr);
168
   if (t == -1) return 0; else addr = t;
169
   fillattr(FILEDLG_X+8,FILEDLG_Y+5,4);
170
 
171
   for (;;) {
172
      t = input4(FILEDLG_X+18,FILEDLG_Y+5,end);
173
      fillattr(FILEDLG_X+18,FILEDLG_Y+5,4);
174
      if (t == -1) return 0;
175
      if (t < addr) continue;
176
      end = t; break;
177
   }
178
 
179
   unsigned offset = 0;
180
   if (mode == FDM_SAVE) read_mem();
181
 
182
   unsigned trk = rw_trk, sec = rw_tsec;
183
 
184
   TRKCACHE tc; tc.clear();
185
   for (;;) {
186
      int left = end+1 - (addr+offset);
187
      if (left <= 0) break;
188
      if (left > 0x100) left = 0x100;
189
 
190
      tc.seek(fdd, trk/2, trk & 1, LOAD_SECTORS);
191
      if (!tc.trkd) { sprintf(ln, "track #%02X not found", trk); rw_err(ln); break; }
192
      const SECHDR *hdr = tc.get_sector(sec+1);
193
      if (!hdr || !hdr->data) { sprintf(ln, "track #%02X, sector #%02X not found", trk, sec); rw_err(ln); break; }
194
      if (hdr->l != 1) { sprintf(ln, "track #%02X, sector #%02X is not 256 bytes", trk, sec); rw_err(ln); break; }
195
 
196
      if (mode == FDM_LOAD) {
197
         memcpy(memdata+offset, hdr->data, left);
198
      } else {
199
         tc.write_sector(sec+1, memdata+offset);
200
         fdd->optype |= 1;
201
      }
202
 
203
      offset += left;
204
      if (++sec == 0x10) trk++, sec = 0;
205
   }
206
 
207
   end = addr + offset - 1;
208
   if (mode == FDM_LOAD) write_mem();
209
   return 1;
210
}
211
 
212
char wr_trdos_file()
213
{
214
   filledframe(FILEDLG_X, FILEDLG_Y, FILEDLG_DX, 6);
215
   const char *title = " Write to TR-DOS file    ";
216
   tprint(FILEDLG_X, FILEDLG_Y, title, FRM_HEADER);
217
 
218
   char ln[64]; unsigned t;
219
 
220
   sprintf(ln, "file:  %-8s %s", trdname, trdext);
221
   tprint(FILEDLG_X+1, FILEDLG_Y+3, ln, FFRAME_INSIDE);
222
 
223
   sprintf(ln, "start: %04X end: %04X", addr, end);
224
   tprint(FILEDLG_X+1, FILEDLG_Y+4, ln, FFRAME_INSIDE);
225
 
226
   if (!rw_select_drive()) return 0;
227
   FDD *fdd = &comp.wd.fdd[rw_drive];
228
   // if (fdd->sides != 2) { rw_err("single-side TR-DOS disks are not supported"); return 0; }
229
 
230
   strcpy(str, trdname);
231
   if (!inputhex(FILEDLG_X+8,FILEDLG_Y+3,8,false)) return 0;
232
   fillattr(FILEDLG_X+8,FILEDLG_Y+3,8);
233
   strcpy(trdname, str);
234
   for (int ptr = strlen(trdname); ptr < 8; trdname[ptr++] = ' ');
235
   trdname[8] = 0;
236
 
237
   strcpy(str, trdext);
238
   if (!inputhex(FILEDLG_X+17,FILEDLG_Y+3,1,false)) return 0;
239
   fillattr(FILEDLG_X+17,FILEDLG_Y+3,1);
240
   trdext[0] = str[0]; trdext[1] = 0;
241
 
242
   t = input4(FILEDLG_X+8,FILEDLG_Y+4,addr);
243
   if (t == -1) return 0; else addr = t;
244
   fillattr(FILEDLG_X+8,FILEDLG_Y+4,4);
245
 
246
   for (;;) {
247
      t = input4(FILEDLG_X+18,FILEDLG_Y+4,end);
248
      fillattr(FILEDLG_X+18,FILEDLG_Y+4,4);
249
      if (t == -1) return 0;
250
      if (t < addr) continue;
251
      end = t; break;
252
   }
253
 
254
   read_mem();
255
 
256
   unsigned char hdr[16];
257
   memcpy(hdr, trdname, 8);
258
   hdr[8] = *trdext;
259
 
260
   unsigned sz = end-addr+1;
261
   *(unsigned short*)(hdr+9) = addr;
262
   *(unsigned short*)(hdr+11) = sz;
263
   hdr[13] = u8(align_by(sz, 0x100) / 0x100); // sector size
264
 
265
   fdd->optype |= 1;
266
   if (!fdd->addfile(hdr, memdata)) { rw_err("write error"); return 0; }
267
   return 1;
268
}
269
 
270
void mon_load()
271
{
272
   static MENUITEM items[] =
273
      { { "from binary file", MENUITEM::LEFT },
274
        { "from TR-DOS file", MENUITEM::LEFT },
275
        { "from TR-DOS sectors", MENUITEM::LEFT },
276
        { "from raw sectors of FDD image", MENUITEM::LEFT } };
277
   static MENUDEF menu = { items, 3, "Load data to memory...", 0 };
278
 
279
   if(!handle_menu(&menu))
280
       return;
281
 
282
   unsigned char bf[0x10000];
283
   memdata = bf;
284
 
285
   switch (menu.pos)
286
   {
287
      case 0:
288
      {
289
         if (!query_file_addr(FDM_LOAD))
290
             return;
291
         FILE *ff = fopen(fname, "rb");
292
         if (!ff)
293
             return;
294
         unsigned sz = fread(bf, 1, sizeof(bf), ff);
295
         fclose(ff);
296
         end = addr + sz - 1;
297
         end = min(end, 0xFFFF);
298
         write_mem();
299
         return;
300
      }
301
 
302
      case 1:
303
      {
304
         rw_err("file selector\r\nis not implemented");
305
         return;
306
      }
307
 
308
      case 2:
309
      {
310
         rw_trdos_sectors(FDM_LOAD);
311
         return;
312
      }
313
 
314
      case 3:
315
      {
316
         return;
317
      }
318
   }
319
}
320
 
321
void mon_save()
322
{
323
   static MENUITEM items[] =
324
      { { "to binary file", MENUITEM::LEFT },
325
        { "to TR-DOS file", MENUITEM::LEFT },
326
        { "to TR-DOS sectors", MENUITEM::LEFT },
327
        { "as Z80 disassembly", MENUITEM::LEFT },
328
        { "to raw sectors of FDD image", (MENUITEM::FLAGS)(MENUITEM::LEFT | MENUITEM::DISABLED) } };
329
   static MENUDEF menu = { items, 4, "Save data from memory...", 0 };
330
 
331
   if (!handle_menu(&menu)) return;
332
 
333
   unsigned char bf[0x10000]; memdata = bf;
334
 
335
   switch (menu.pos)
336
   {
337
      case 0:
338
      {
339
         if (!query_file_addr(FDM_SAVE)) return;
340
         read_mem();
341
         FILE *ff = fopen(fname, "wb");
342
         if (!ff) return;
343
         fwrite(bf, 1, end+1-addr, ff);
344
         fclose(ff);
345
         return;
346
      }
347
 
348
      case 1:
349
      {
350
         wr_trdos_file();
351
         return;
352
      }
353
 
354
      case 2:
355
      {
356
         rw_trdos_sectors(FDM_SAVE);
357
         return;
358
      }
359
 
360
      case 3:
361
      {
362
         if (!query_file_addr(FDM_DISASM)) return;
363
         FILE *ff = fopen(fname, "wt");
364
         if (!ff) return;
365
         for (unsigned a = addr; a <= end; ) {
366
//            char line[64]; //Alone Coder 0.36.7
367
            char line[16+129]; //Alone Coder 0.36.7
368
            a += disasm_line(a, line);
369
            fprintf(ff, "%s\n", line);
370
         }
371
         fclose(ff);
372
         return;
373
      }
374
 
375
      case 4:
376
      {
377
         return;
378
      }
379
   }
380
}