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