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 "dbgtrace.h"
7
#include "dbglabls.h"
8
#include "dbgpaint.h"
9
#include "dbgcmd.h"
10
#include "memory.h"
11
#include "z80asm.h"
12
#include "z80/op_system.h"
13
#include "util.h"
14
 
15
int disasm_line(unsigned addr, char *line)
16
{
17
   Z80 &cpu = CpuMgr.Cpu();
18
   unsigned char dbuf[16+129/*Alone Code 0.36.7*/];
19
   int i; //Alone Coder 0.36.7
20
   for (/*int*/ i = 0; i < 16; i++) dbuf[i] = cpu.DirectRm(addr+i);
21
   sprintf(line, "%04X ", addr); int ptr = 5;
22
   int len = disasm(dbuf, addr, trace_labels) - dbuf;
23
   //8000 ..DDCB0106 rr (ix+1)
24
   if (trace_labels)
25
   {
26
      char *lbl = mon_labels.find(am_r(addr));
27
//      if (lbl) for (int k = 0; k < 10 && lbl[k]; line[ptr++] = lbl[k++]); //Alone Coder
28
      if (lbl) for (int k = 0; (k < 10) && lbl[k]; )line[ptr++] = lbl[k++]; //Alone Coder
29
   }
30
   else
31
   {
32
      int len1 = len;
33
      if (len > 4) len1 = 4, *(short*)(line+ptr) = WORD2('.','.'), ptr+=2;
34
      for (i = len-len1; i < len; i++)
35
         sprintf(line+ptr, "%02X", dbuf[i]), ptr += 2;
36
   }
37
 
38
   while (ptr < 16) line[ptr++] = ' ';
39
   strcpy(line+ptr, asmbuf);
40
   return len;
41
}
42
 
43
#define TWF_BRANCH  0x010000
44
#define TWF_BRADDR  0x020000
45
#define TWF_LOOPCMD 0x040000
46
#define TWF_CALLCMD 0x080000
47
#define TWF_BLKCMD  0x100000
48
#define TWF_HALTCMD 0x200000
49
// Ìëàäøèå 16áèò - àäðåñ z80
50
// ñòàðøèå 16áèò - ôëàãè TWF_xxxx
51
unsigned tracewndflags()
52
{
53
   Z80 &cpu = CpuMgr.Cpu();
54
   unsigned readptr = cpu.pc, base = cpu.hl;
55
   unsigned char opcode = 0; unsigned char ed = 0;
56
   for (;;)
57
   {
58
      opcode = cpu.DirectRm(readptr++);
59
      if (opcode == 0xDD)
60
          base = cpu.ix;
61
      else if (opcode == 0xFD)
62
          base = cpu.iy;
63
      else if (opcode == 0xED)
64
          ed = 1;
65
      else
66
          break;
67
   }
68
 
69
   unsigned fl = 0;
70
   if(opcode == 0x76) // halt
71
   {
72
       u32 addr;
73
       if(cpu.im < 2)
74
       {
75
           addr = 0x38;
76
       }
77
       else // im2
78
       {
79
           unsigned vec = (cpu.i << 8U) | cpu.IntVec();
80
           addr = (cpu.DirectRm(vec+1) << 8U) | cpu.DirectRm(vec);
81
       }
82
       return TWF_HALTCMD | addr;
83
   }
84
 
85
   if (ed)
86
   {
87
      if((opcode & 0xF4) == 0xB0) // ldir/lddr | cpir/cpdr | inir/indr | otir/otdr
88
          return TWF_BLKCMD;
89
 
90
      if ((opcode & 0xC7) != 0x45)
91
          return 0; // reti/retn
92
 
93
 ret:
94
      return (cpu.DirectRm(cpu.sp) | (cpu.DirectRm(cpu.sp+1) << 8U)) | TWF_BRANCH | TWF_BRADDR;
95
   }
96
 
97
   if (opcode == 0xC9) // ret
98
       goto ret;
99
   if (opcode == 0xC3) // jp
100
   {
101
       jp: return (cpu.DirectRm(readptr) | (cpu.DirectRm(readptr+1) << 8U)) | TWF_BRANCH | fl;
102
   }
103
   if (opcode == 0xCD) // call
104
   {
105
       fl = TWF_CALLCMD;
106
       goto jp;
107
   }
108
 
109
   static const unsigned char flags[] = { ZF,CF,PV,SF };
110
 
111
   if ((opcode & 0xC1) == 0xC0)
112
   {
113
      unsigned char flag = flags[(opcode >> 4) & 3];
114
      unsigned char res = cpu.f & flag;
115
      if (!(opcode & 0x08))
116
          res ^= flag;
117
      if (!res)
118
          return 0;
119
      if ((opcode & 0xC7) == 0xC0) // ret cc
120
          goto ret;
121
      if ((opcode & 0xC7) == 0xC4) // call cc
122
      {
123
          fl = TWF_CALLCMD;
124
          goto jp;
125
      }
126
      if ((opcode & 0xC7) == 0xC2) // jp cc
127
      {
128
          fl = TWF_LOOPCMD;
129
          goto jp;
130
      }
131
   }
132
 
133
   if (opcode == 0xE9)
134
       return base | TWF_BRANCH | TWF_BRADDR; // jp (hl/ix/iy)
135
 
136
   if ((opcode & 0xC7) == 0xC7)
137
       return (opcode & 0x38) | TWF_CALLCMD | TWF_BRANCH; // rst #xx
138
 
139
   if ((opcode & 0xC7) == 0x00)
140
   {
141
      if (!opcode || opcode == 0x08)
142
          return 0;
143
      int offs = (signed char)cpu.DirectRm(readptr++);
144
      unsigned addr = (offs + readptr) | TWF_BRANCH;
145
      if (opcode == 0x18)
146
          return addr; // jr
147
      if (opcode == 0x10)
148
          return (cpu.b==1)? 0 : addr | TWF_LOOPCMD; // djnz
149
 
150
      unsigned char flag = flags[(opcode >> 4) & 1]; // jr cc
151
      unsigned char res = cpu.f & flag;
152
      if (!(opcode & 0x08))
153
          res ^= flag;
154
      return res? addr | TWF_LOOPCMD : 0;
155
   }
156
   return 0;
157
}
158
 
159
unsigned trcurs_y;
160
unsigned asmii;
161
char asmpc[64], dumppc[12];
162
const unsigned cs[3][2] = { {0,4}, {5,10}, {16,16} };
163
 
164
void showtrace()
165
{
166
   Z80 &cpu = CpuMgr.Cpu();
167
//   char line[40]; //Alone Coder 0.36.7
168
   char line[16+129]; //Alone Coder 0.36.7
169
 
170
   cpu.trace_curs &= 0xFFFF;
171
   cpu.trace_top &= 0xFFFF;
172
   cpu.pc &= 0xFFFF;
173
   cpu.trace_mode = (cpu.trace_mode+3) % 3;
174
 
175
   cpu.pc_trflags = tracewndflags();
176
   cpu.nextpc = (cpu.pc_trflags & TWF_HALTCMD) ? (cpu.pc_trflags & 0xFFFF): ((cpu.pc + disasm_line(cpu.pc, line)) & 0xFFFF);
177
   unsigned pc = cpu.trace_top;
178
   asmii = -1;
179
   unsigned char atr0 = (activedbg == WNDTRACE) ? W_SEL : W_NORM;
180
   unsigned ii; //Alone Coder 0.36.7
181
   for (/*unsigned*/ ii = 0; ii < trace_size; ii++)
182
   {
183
      pc &= 0xFFFF; cpu.trpc[ii] = pc;
184
      int len = disasm_line(pc, line);
185
      char *ptr = line+strlen(line);
186
      while (ptr < line+32) *ptr++ = ' '; line[32] = 0;
187
 
188
      unsigned char atr = (pc == cpu.pc)? W_TRACEPOS : atr0;
189
      if (cpu.membits[pc] & MEMBITS_BPX) atr = (atr&~7)|2;
190
      tprint(trace_x, trace_y+ii, line, atr);
191
 
192
      if (pc == cpu.trace_curs)
193
      {
194
         asmii = ii;
195
         if (activedbg == WNDTRACE)
196
            for (unsigned q = 0; q < cs[cpu.trace_mode][1]; q++)
197
               txtscr[80*30 + (trace_y+ii)*80 + trace_x + cs[cpu.trace_mode][0] + q] = W_CURS;
198
      }
199
 
200
      if (cpu.pc_trflags & TWF_BRANCH)
201
      {
202
         if (pc == cpu.pc)
203
         {
204
            unsigned addr = cpu.pc_trflags & 0xFFFF;
205
            unsigned arr = (addr <= cpu.pc)? 0x18 : 0x19; // up/down arrow
206
            unsigned char color = (pc == cpu.trace_curs && activedbg == WNDTRACE && cpu.trace_mode == 2)? W_TRACE_JINFO_CURS_FG : W_TRACE_JINFO_NOCURS_FG;
207
            if (cpu.pc_trflags & TWF_BRADDR) sprintf(line, "%04X%c", addr, arr), tprint_fg(trace_x+32-5, trace_y+ii, line, color);
208
            else tprint_fg(trace_x+32-1, trace_y+ii, (char*)&arr, color);
209
         }
210
 
211
         if (pc == (cpu.pc_trflags & 0xFFFF))
212
         {
213
            unsigned arr = 0x11; // left arrow
214
            tprint_fg(trace_x+32-1, trace_y+ii, (char*)&arr, W_TRACE_JARROW_FOREGR);
215
         }
216
      }
217
 
218
      pc += len;
219
   }
220
   cpu.trpc[ii] = pc;
221
 
222
   unsigned char dbuf[16];
223
   int i; //Alone Coder
224
   for (/*int*/ i = 0; i < 16; i++) dbuf[i] = cpu.DirectRm(cpu.trace_curs+i);
225
   int len = disasm(dbuf, cpu.trace_curs, 0) - dbuf; strcpy(asmpc, asmbuf);
226
   for (/*int*/ i = 0; i < len && i < 5; i++)
227
      sprintf(dumppc + i*2, "%02X", cpu.DirectRm(cpu.trace_curs+i));
228
 
229
   char cpu_num[10];
230
   _snprintf(cpu_num, sizeof(cpu_num), "Z80(%d)", CpuMgr.GetCurrentCpu());
231
   tprint(trace_x, trace_y-1, cpu_num, W_TITLE);
232
 
233
   char lbr[5];
234
   _snprintf(lbr, sizeof(lbr), "%04hX", cpu.last_branch);
235
   tprint(trace_x+8, trace_y-1, lbr,  W_TITLE);
236
   frame(trace_x,trace_y,32,trace_size,FRAME);
237
}
238
 
239
void c_lbl_import()
240
{
241
   mon_labels.import_menu();
242
}
243
 
244
      /* ------------------------------------------------------------- */
245
unsigned save_pos[8] = { -1U,-1U,-1U,-1U,-1U,-1U,-1U,-1U };
246
unsigned save_cur[8] = { -1U,-1U,-1U,-1U,-1U,-1U,-1U,-1U };
247
unsigned stack_pos[32] = { -1U }, stack_cur[32] = { -1U };
248
 
249
void push_pos()
250
{
251
   Z80 &cpu = CpuMgr.Cpu();
252
   memmove(&stack_pos[1], &stack_pos[0], sizeof stack_pos - sizeof *stack_pos);
253
   memmove(&stack_cur[1], &stack_cur[0], sizeof stack_cur - sizeof *stack_cur);
254
   stack_pos[0] = cpu.trace_top; stack_cur[0] = cpu.trace_curs;
255
}
256
 
257
unsigned cpu_up(unsigned ip)
258
{
259
   Z80 &cpu = CpuMgr.Cpu();
260
   unsigned char buf1[0x10];
261
   unsigned p1 = (ip > sizeof buf1) ? ip - sizeof buf1 : 0;
262
   for (unsigned i = 0; i < sizeof buf1; i++) buf1[i] = cpu.DirectRm(p1+i);
263
   unsigned char *dispos = buf1, *prev;
264
   do {
265
      prev = dispos;
266
      dispos = disasm(dispos, 0, 0);
267
   } while ((unsigned)(dispos-buf1+p1) < ip);
268
   return prev-buf1+p1;
269
}
270
 
271
void cgoto()
272
{
273
   Z80 &cpu = CpuMgr.Cpu();
274
   unsigned v = input4(trace_x, trace_y, cpu.trace_top);
275
   if (v != -1)
276
       cpu.trace_top = cpu.trace_curs = v;
277
}
278
 
279
void csetpc()
280
{
281
    Z80 &cpu = CpuMgr.Cpu();
282
    cpu.pc = cpu.trace_curs;
283
}
284
 
285
void center()
286
{
287
   Z80 &cpu = CpuMgr.Cpu();
288
   if (!cpu.trace_mode)
289
       sprintf(str, "%04X", cpu.trace_curs);
290
   else if (cpu.trace_mode == 1)
291
       strcpy(str, dumppc);
292
   else
293
       strcpy(str, asmpc);
294
 
295
   if (input.lastkey != VK_RETURN)
296
   {
297
       *str = 0;
298
        PostThreadMessage(GetCurrentThreadId(), WM_KEYDOWN, input.lastkey, 1);
299
   }
300
 
301
   for (;;)
302
   {
303
      if (!inputhex(trace_x+cs[cpu.trace_mode][0], trace_y + trcurs_y + asmii, cs[cpu.trace_mode][1], cpu.trace_mode < 2))
304
          break;
305
      if (!cpu.trace_mode)
306
      {
307
         push_pos();
308
         sscanf(str, "%X", &cpu.trace_top);
309
         cpu.trace_curs = cpu.trace_top;
310
         for (unsigned i = 0; i < asmii; i++)
311
             cpu.trace_top = cpu_up(cpu.trace_top);
312
         break;
313
      }
314
      else if (cpu.trace_mode == 1)
315
      {
316
         char *p; //Alone Coder 0.36.7
317
         for (/*char * */p = str+strlen(str)-1; p >= str && *p == ' '; *p-- = 0);
318
         unsigned char dump[8]; unsigned i;
319
         for (p = str, i = 0; ishex(*p) && ishex(p[1]); p+=2)
320
            dump[i++] = hex(p);
321
         if (*p) continue;
322
         for (unsigned j = 0; j < i; j++)
323
            cpu.DirectWm(cpu.trace_curs+j, dump[j]);
324
         break;
325
      }
326
      else
327
      {
328
         unsigned sz = assemble_cmd((unsigned char*)str, cpu.trace_curs);
329
         if (sz)
330
         {
331
            for (unsigned i = 0; i < sz; i++)
332
                cpu.DirectWm(cpu.trace_curs+i, asmresult[i]);
333
            showtrace();
334
            void cdown();
335
            cdown();
336
            break;
337
         }
338
      }
339
   }
340
}
341
 
342
char dispatch_trace()
343
{
344
   if (input.lastkey >= 'A' && input.lastkey < 'Z')
345
   {
346
       center();
347
       return 1;
348
   }
349
   return 0;
350
}
351
 
352
void cfindtext()
353
{
354
   Z80 &cpu = CpuMgr.Cpu();
355
   unsigned char oldmode = editor; editor = ED_MEM;
356
   unsigned rs = find1dlg(cpu.trace_curs);
357
   editor = oldmode;
358
   if (rs != -1)
359
       cpu.trace_top = cpu.trace_curs = rs;
360
}
361
void cfindcode()
362
{
363
   Z80 &cpu = CpuMgr.Cpu();
364
   unsigned char oldmode = editor; editor = ED_MEM;
365
   unsigned rs = find2dlg(cpu.trace_curs);
366
   editor = oldmode;
367
   if (rs != -1)
368
       cpu.trace_top = cpu.trace_curs = rs;
369
}
370
 
371
void cbpx()
372
{
373
   Z80 &cpu = CpuMgr.Cpu();
374
   cpu.membits[cpu.trace_curs] ^= MEMBITS_BPX;
375
}
376
 
377
void cfindpc()
378
{
379
    Z80 &cpu = CpuMgr.Cpu();
380
    cpu.trace_top = cpu.trace_curs = cpu.pc;
381
}
382
 
383
void cup()
384
{
385
   Z80 &cpu = CpuMgr.Cpu();
386
   if (cpu.trace_curs > cpu.trace_top)
387
   {
388
      for (unsigned i = 1; i < trace_size; i++)
389
         if (cpu.trpc[i] == cpu.trace_curs)
390
             cpu.trace_curs = cpu.trpc[i-1];
391
   }
392
   else
393
       cpu.trace_top = cpu.trace_curs = cpu_up(cpu.trace_curs);
394
}
395
 
396
void cdown()
397
{
398
   Z80 &cpu = CpuMgr.Cpu();
399
   for (unsigned i = 0; i < trace_size; i++)
400
      if (cpu.trpc[i] == cpu.trace_curs)
401
      {
402
         cpu.trace_curs = cpu.trpc[i+1];
403
         if (i+1 == trace_size)
404
             cpu.trace_top = cpu.trpc[1];
405
         break;
406
      }
407
}
408
void cleft()  { CpuMgr.Cpu().trace_mode--; }
409
void cright() { CpuMgr.Cpu().trace_mode++; }
410
void chere()
411
{
412
    Z80 &cpu = CpuMgr.Cpu();
413
    cpu.dbgbreak = 0;
414
    dbgbreak = 0;
415
    cpu.dbgchk = 1;
416
 
417
    cpu.dbg_stophere = cpu.trace_curs;
418
}
419
 
420
void cpgdn()
421
{
422
   Z80 &cpu = CpuMgr.Cpu();
423
   unsigned curs = 0;
424
   for (unsigned i = 0; i < trace_size; i++)
425
      if (cpu.trace_curs == cpu.trpc[i]) curs = i;
426
   cpu.trace_top = cpu.trpc[trace_size];
427
   showtrace();
428
   cpu.trace_curs = cpu.trpc[curs];
429
}
430
 
431
void cpgup()
432
{
433
   Z80 &cpu = CpuMgr.Cpu();
434
   unsigned curs = 0;
435
   unsigned i; //Alone Coder 0.36.7
436
   for (/*unsigned*/ i = 0; i < trace_size; i++)
437
      if (cpu.trace_curs == cpu.trpc[i]) curs = i;
438
   for (i = 0; i < trace_size; i++)
439
       cpu.trace_top = cpu_up(cpu.trace_top);
440
   showtrace();
441
   cpu.trace_curs = cpu.trpc[curs];
442
}
443
 
444
void pop_pos()
445
{
446
   Z80 &cpu = CpuMgr.Cpu();
447
   if (stack_pos[0] == -1)
448
       return;
449
   cpu.trace_curs = stack_cur[0];
450
   cpu.trace_top = stack_pos[0];
451
   memcpy(&stack_pos[0], &stack_pos[1], sizeof stack_pos - sizeof *stack_pos);
452
   memcpy(&stack_cur[0], &stack_cur[1], sizeof stack_cur - sizeof *stack_cur);
453
   stack_pos[(sizeof stack_pos / sizeof *stack_pos)-1] = -1;
454
}
455
 
456
void cjump()
457
{
458
   Z80 &cpu = CpuMgr.Cpu();
459
   char *ptr = 0;
460
   for (char *p = asmpc; *p; p++)
461
      if (ishex(p[0]) & ishex(p[1]) & ishex(p[2]) & ishex(p[3])) ptr = p;
462
   if (!ptr) return;
463
   push_pos();
464
   unsigned addr;
465
   sscanf(ptr, "%04X", &addr);
466
   cpu.trace_curs = cpu.trace_top = addr;
467
}
468
 
469
void cdjump()
470
{
471
   char *ptr = 0;
472
   for (char *p = asmpc; *p; p++)
473
      if (ishex(p[0]) & ishex(p[1]) & ishex(p[2]) & ishex(p[3])) ptr = p;
474
   if (!ptr) return;
475
   unsigned addr; sscanf(ptr, "%04X", &addr);
476
   Z80 &cpu = CpuMgr.Cpu();
477
   cpu.mem_curs = addr; activedbg = WNDMEM; editor = ED_MEM;
478
}
479
 
480
void cfliplabels()
481
{
482
   trace_labels = !trace_labels; showtrace();
483
}
484
void csave(unsigned n)
485
{
486
   Z80 &cpu = CpuMgr.Cpu();
487
   save_pos[n] = cpu.trace_top;
488
   save_cur[n] = cpu.trace_curs;
489
}
490
void crest(unsigned n)
491
{
492
   Z80 &cpu = CpuMgr.Cpu();
493
   if (save_pos[n] == -1)
494
       return;
495
   push_pos();
496
   cpu.trace_top = save_pos[n];
497
   cpu.trace_curs = save_cur[n];
498
}
499
void csave1() { csave(0); }
500
void csave2() { csave(1); }
501
void csave3() { csave(2); }
502
void csave4() { csave(3); }
503
void csave5() { csave(4); }
504
void csave6() { csave(5); }
505
void csave7() { csave(6); }
506
void csave8() { csave(7); }
507
void crest1() { crest(0); }
508
void crest2() { crest(1); }
509
void crest3() { crest(2); }
510
void crest4() { crest(3); }
511
void crest5() { crest(4); }
512
void crest6() { crest(5); }
513
void crest7() { crest(6); }
514
void crest8() { crest(7); }
515
 
516
namespace z80dbg
517
{
518
void __cdecl SetLastT()
519
{
520
   cpu.debug_last_t = comp.t_states + cpu.t;
521
}
522
}
523
 
524
void mon_step()
525
{
526
   Z80 &cpu = CpuMgr.Cpu();
527
   TZ80State &prevcpu = CpuMgr.PrevCpu();
528
 
529
   cpu.SetLastT();
530
   prevcpu = cpu;
531
//   CpuMgr.CopyToPrev();
532
   if(cpu.t >= conf.intlen)
533
       cpu.int_pend = false;
534
   cpu.Step();
535
   if (cpu.int_pend && cpu.iff1 && cpu.t != cpu.eipos && // int enabled in CPU not issued after EI
536
       cpu.int_gate) // int enabled by ATM hardware
537
   {
538
      handle_int(&cpu, cpu.IntVec());
539
   }
540
 
541
   cpu.CheckNextFrame();
542
   cpu.trace_curs = cpu.pc;
543
}
544
 
545
void mon_stepover()
546
{
547
   Z80 &cpu = CpuMgr.Cpu();
548
   unsigned char trace = 1;
549
 
550
   // call,rst
551
   if (cpu.pc_trflags & TWF_CALLCMD)
552
   {
553
       cpu.dbg_stopsp = cpu.sp & 0xFFFF;
554
       cpu.dbg_stophere = cpu.nextpc;
555
       trace = 0;
556
   }
557
   else if (cpu.pc_trflags & (TWF_BLKCMD | TWF_HALTCMD)) // ldir/lddr|cpir/cpdr|otir/otdr|inir/indr|halt
558
   {
559
       trace = 0;
560
       cpu.dbg_stophere = cpu.nextpc;
561
   }
562
 
563
/* [vv]
564
   // jr cc,$-xx, jp cc,$-xx
565
   else if ((cpu.pc_trflags & TWF_LOOPCMD) && (cpu.pc_trflags & 0xFFFF) < (cpu.pc & 0xFFFF))
566
   {
567
      cpu.dbg_stopsp = cpu.sp & 0xFFFF;
568
      cpu.dbg_stophere = cpu.nextpc,
569
      cpu.dbg_loop_r1 = cpu.pc_trflags & 0xFFFF;
570
      cpu.dbg_loop_r2 = cpu.pc & 0xFFFF;
571
      trace = 0;
572
   }
573
*/
574
 
575
/* [vv]
576
   else if (cpu.pc_trflags & TWF_BRANCH)
577
       trace = 1;
578
   else
579
   {
580
       trace = 1;
581
       cpu.dbg_stophere = cpu.nextpc;
582
   }
583
*/
584
 
585
   if (trace)
586
   {
587
       mon_step();
588
   }
589
   else
590
   {
591
       cpu.dbgbreak = 0;
592
       dbgbreak = 0;
593
       cpu.dbgchk = 1;
594
   }
595
}