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 | } |