Top secrets sources NedoPC pentevo

Rev

Rev 883 | Blame | Compare with Previous | Last modification | View Log | Download | RSS feed | ?url?

#include "std.h"

#include "emul.h"
#include "vars.h"
#include "debug.h"
#include "dbgtrace.h"
#include "dbglabls.h"
#include "dbgpaint.h"
#include "dbgcmd.h"
#include "memory.h"
#include "z80asm.h"
#include "z80/op_system.h"
#include "util.h"

int disasm_line(unsigned addr, char *line)
{
   Z80 &cpu = CpuMgr.Cpu();
   unsigned char dbuf[16+129/*Alone Code 0.36.7*/];
   ptrdiff_t i; //Alone Coder 0.36.7
   for (/*int*/ i = 0; i < 16; i++) dbuf[i] = cpu.DirectRm(addr+unsigned(i));
   sprintf(line, "%04X ", addr); int ptr = 5;
   ptrdiff_t len = disasm(dbuf, addr, char(trace_labels)) - dbuf;
   //8000 ..DDCB0106 rr (ix+1)
   if (trace_labels)
   {
      char *virtlbl = mon_labels.find(((unsigned char *)NULL)+addr);
      char *lbl = mon_labels.find(am_r(addr));
      if (virtlbl) lbl=virtlbl;
      if (lbl) for (int k = 0; (k < 10) && lbl[k]; )line[ptr++] = lbl[k++];
   }
   else
   {
      ptrdiff_t len1 = len;
      if(len > 4)
      {
          len1 = 4;
          *(short*)(line + ptr) = WORD2('.', '.');
          ptr += 2;
      }
      for(i = len - len1; i < len; i++)
      {
          sprintf(line + ptr, "%02X", dbuf[i]);
          ptr += 2;
      }
   }

   while (ptr < 16) line[ptr++] = ' ';
   strcpy(line+ptr, asmbuf);
   return int(len);
}

#define TWF_BRANCH  0x010000U
#define TWF_BRADDR  0x020000U
#define TWF_LOOPCMD 0x040000U
#define TWF_CALLCMD 0x080000U
#define TWF_BLKCMD  0x100000U
#define TWF_HALTCMD 0x200000U
// Ìëàäøèå 16áèò - àäðåñ z80
// ñòàðøèå 16áèò - ôëàãè TWF_xxxx
static unsigned tracewndflags()
{
   Z80 &cpu = CpuMgr.Cpu();
   unsigned readptr = cpu.pc, base = cpu.hl;
   unsigned char opcode = 0; unsigned char ed = 0;
   for (;;)
   {
      opcode = cpu.DirectRm(readptr++);
      if (opcode == 0xDD)
          base = cpu.ix;
      else if (opcode == 0xFD)
          base = cpu.iy;
      else if (opcode == 0xED)
          ed = 1;
      else
          break;
   }

   unsigned fl = 0;
   if(opcode == 0x76) // halt
   {
       u32 addr;
       if(cpu.im < 2)
       {
           addr = 0x38;
       }
       else // im2
       {
           unsigned vec = unsigned(cpu.i << 8U) | cpu.IntVec();
           addr = u32((cpu.DirectRm(vec+1) << 8U) | cpu.DirectRm(vec));
       }
       return TWF_HALTCMD | addr;
   }

   if (ed)
   {
      if((opcode & 0xF4) == 0xB0) // ldir/lddr | cpir/cpdr | inir/indr | otir/otdr
          return TWF_BLKCMD;

      if ((opcode & 0xC7) != 0x45)
          return 0; // reti/retn

 ret:
      return (cpu.DirectRm(cpu.sp) | unsigned(cpu.DirectRm(cpu.sp+1) << 8U)) | TWF_BRANCH | TWF_BRADDR;
   }

   if (opcode == 0xC9) // ret
       goto ret;
   if (opcode == 0xC3) // jp
   {
       jp: return (cpu.DirectRm(readptr) | unsigned(cpu.DirectRm(readptr+1) << 8U)) | TWF_BRANCH | fl;
   }
   if (opcode == 0xCD) // call
   {
       fl = TWF_CALLCMD;
       goto jp;
   }

   static const unsigned char flags[] = { ZF,CF,PV,SF };

   if ((opcode & 0xC1) == 0xC0)
   {
      unsigned char flag = flags[(opcode >> 4) & 3];
      unsigned char res = cpu.f & flag;
      if (!(opcode & 0x08))
          res ^= flag;
      if (!res)
          return 0;
      if ((opcode & 0xC7) == 0xC0) // ret cc
          goto ret;
      if ((opcode & 0xC7) == 0xC4) // call cc
      {
          fl = TWF_CALLCMD;
          goto jp;
      }
      if ((opcode & 0xC7) == 0xC2) // jp cc
      {
          fl = TWF_LOOPCMD;
          goto jp;
      }
   }

   if (opcode == 0xE9)
       return base | TWF_BRANCH | TWF_BRADDR; // jp (hl/ix/iy)

   if ((opcode & 0xC7) == 0xC7)
       return (opcode & 0x38) | TWF_CALLCMD | TWF_BRANCH; // rst #xx

   if ((opcode & 0xC7) == 0x00)
   {
      if (!opcode || opcode == 0x08)
          return 0;
      int offs = (signed char)cpu.DirectRm(readptr++);
      unsigned addr = unsigned(offs + int(readptr)) | TWF_BRANCH;
      if (opcode == 0x18)
          return addr; // jr
      if (opcode == 0x10)
          return (cpu.b==1)? 0 : addr | TWF_LOOPCMD; // djnz

      unsigned char flag = flags[(opcode >> 4) & 1]; // jr cc
      unsigned char res = cpu.f & flag;
      if (!(opcode & 0x08))
          res ^= flag;
      return res? addr | TWF_LOOPCMD : 0;
   }
   return 0;
}

static unsigned trcurs_y;
unsigned asmii;
static char asmpc[64], dumppc[12];
const unsigned cs[3][2] = { {0,4}, {5,10}, {16,16} };

void showtrace()
{
   Z80 &cpu = CpuMgr.Cpu();
//   char line[40]; //Alone Coder 0.36.7
   char line[16+129]; //Alone Coder 0.36.7

   cpu.trace_curs &= 0xFFFF;
   cpu.trace_top &= 0xFFFF;
   cpu.pc &= 0xFFFF;
   cpu.trace_mode = (cpu.trace_mode+3) % 3;

   cpu.pc_trflags = tracewndflags();
   cpu.nextpc = (cpu.pc_trflags & TWF_HALTCMD) ? (cpu.pc_trflags & 0xFFFF): ((cpu.pc + unsigned(disasm_line(cpu.pc, line))) & 0xFFFF);
   unsigned pc = cpu.trace_top;
   asmii = -1U;
   unsigned char atr0 = (activedbg == WNDTRACE) ? W_SEL : W_NORM;
   unsigned ii; //Alone Coder 0.36.7
   for (/*unsigned*/ ii = 0; ii < trace_size; ii++)
   {
      pc &= 0xFFFF; cpu.trpc[ii] = pc;
      int len = disasm_line(pc, line);
      char *ptr = line+strlen(line);
      while (ptr < line+32) *ptr++ = ' '; line[32] = 0;

      unsigned char atr = (pc == cpu.pc)? W_TRACEPOS : atr0;
      if (cpu.membits[pc] & MEMBITS_BPX) atr = (atr&~7)|2;
      tprint(trace_x, trace_y+ii, line, atr);

      if (pc == cpu.trace_curs)
      {
         asmii = ii;
         if (activedbg == WNDTRACE)
            for (unsigned q = 0; q < cs[cpu.trace_mode][1]; q++)
               txtscr[80*30 + (trace_y+ii)*80 + trace_x + cs[cpu.trace_mode][0] + q] = W_CURS;
      }

      if (cpu.pc_trflags & TWF_BRANCH)
      {
         if (pc == cpu.pc)
         {
            unsigned addr = cpu.pc_trflags & 0xFFFF;
            unsigned arr = (addr <= cpu.pc)? 0x18 : 0x19; // up/down arrow
            unsigned char color = (pc == cpu.trace_curs && activedbg == WNDTRACE && cpu.trace_mode == 2)? W_TRACE_JINFO_CURS_FG : W_TRACE_JINFO_NOCURS_FG;
            if(cpu.pc_trflags & TWF_BRADDR)
            {
                sprintf(line, "%04X%c", addr, int(arr));
                tprint_fg(trace_x + 32 - 5, trace_y + ii, line, color);
            }
            else tprint_fg(trace_x+32-1, trace_y+ii, (char*)&arr, color);
         }

         if (pc == (cpu.pc_trflags & 0xFFFF))
         {
            unsigned arr = 0x11; // left arrow
            tprint_fg(trace_x+32-1, trace_y+ii, (char*)&arr, W_TRACE_JARROW_FOREGR);
         }
      }

      pc += unsigned(len);
   }
   cpu.trpc[ii] = pc;

   unsigned char dbuf[16];
   unsigned i; //Alone Coder
   for (/*int*/ i = 0; i < 16; i++) dbuf[i] = cpu.DirectRm(cpu.trace_curs+i);
   ptrdiff_t len = disasm(dbuf, cpu.trace_curs, 0) - dbuf; strcpy(asmpc, asmbuf);
   for (/*int*/ i = 0; i < len && i < 5; i++)
      sprintf(dumppc + i*2, "%02X", cpu.DirectRm(cpu.trace_curs+i));

   char cpu_num[10];
   _snprintf(cpu_num, sizeof(cpu_num), "Z80(%u)", CpuMgr.GetCurrentCpu());
   tprint(trace_x, trace_y-1, cpu_num, W_TITLE);

   char lbr[5];
   _snprintf(lbr, sizeof(lbr), "%04hX", cpu.last_branch);
   tprint(trace_x+8, trace_y-1, lbr,  W_TITLE);
   frame(trace_x,trace_y,32,trace_size,FRAME);
}

void c_lbl_import()
{
   mon_labels.import_menu();
}

      /* ------------------------------------------------------------- */
static unsigned save_pos[8] = { -1U,-1U,-1U,-1U,-1U,-1U,-1U,-1U };
static unsigned save_cur[8] = { -1U,-1U,-1U,-1U,-1U,-1U,-1U,-1U };
static unsigned stack_pos[32] = { -1U }, stack_cur[32] = { -1U };

void push_pos();

void push_pos()
{
   Z80 &cpu = CpuMgr.Cpu();
   memmove(&stack_pos[1], &stack_pos[0], sizeof stack_pos - sizeof *stack_pos);
   memmove(&stack_cur[1], &stack_cur[0], sizeof stack_cur - sizeof *stack_cur);
   stack_pos[0] = cpu.trace_top; stack_cur[0] = cpu.trace_curs;
}

static unsigned cpu_up(unsigned ip)
{
   Z80 &cpu = CpuMgr.Cpu();
   unsigned char buf1[0x10];
   unsigned p1 = (ip > sizeof buf1) ? ip - sizeof buf1 : 0;
   for (unsigned i = 0; i < sizeof buf1; i++) buf1[i] = cpu.DirectRm(p1+i);
   const unsigned char *dispos = buf1, *prev;
   do {
      prev = dispos;
      dispos = disasm(dispos, 0, 0);
   } while ((unsigned)(dispos-buf1+p1) < ip);
   return unsigned(prev-buf1+p1);
}

void cgoto()
{
   Z80 &cpu = CpuMgr.Cpu();
   int v = input4(trace_x, trace_y, cpu.trace_top);
   if (v != -1)
       cpu.trace_top = cpu.trace_curs = unsigned(v);
}

void csetpc()
{
    Z80 &cpu = CpuMgr.Cpu();
    cpu.pc = cpu.trace_curs;
}

void center()
{
   Z80 &cpu = CpuMgr.Cpu();
   if (!cpu.trace_mode)
       sprintf(str, "%04X", cpu.trace_curs);
   else if (cpu.trace_mode == 1)
       strcpy(str, dumppc);
   else
       strcpy(str, asmpc);

   if (input.lastkey != VK_RETURN)
   {
       *str = 0;
        PostThreadMessage(GetCurrentThreadId(), WM_KEYDOWN, input.lastkey, 1);
   }

   for (;;)
   {
      if (!inputhex(trace_x+cs[cpu.trace_mode][0], trace_y + trcurs_y + asmii, cs[cpu.trace_mode][1], cpu.trace_mode < 2))
          break;
      if (!cpu.trace_mode)
      {
         push_pos();
         sscanf(str, "%X", &cpu.trace_top);
         cpu.trace_curs = cpu.trace_top;
         for (unsigned i = 0; i < asmii; i++)
             cpu.trace_top = cpu_up(cpu.trace_top);
         break;
      }
      else if (cpu.trace_mode == 1)
      {
         char *p; //Alone Coder 0.36.7
         for (/*char * */p = str+strlen(str)-1; p >= str && *p == ' '; *p-- = 0);
         unsigned char dump[8]; unsigned i;
         for (p = str, i = 0; ishex(*p) && ishex(p[1]); p+=2)
            dump[i++] = hex(p);
         if (*p) continue;
         for (unsigned j = 0; j < i; j++)
            cpu.DirectWm(cpu.trace_curs+j, dump[j]);
         break;
      }
      else
      {
         unsigned sz = assemble_cmd((unsigned char*)str, cpu.trace_curs);
         if (sz)
         {
            for (unsigned i = 0; i < sz; i++)
                cpu.DirectWm(cpu.trace_curs+i, asmresult[i]);
            showtrace();
            void cdown();
            cdown();
            break;
         }
      }
   }
}

char dispatch_trace()
{
   if (input.lastkey >= 'A' && input.lastkey < 'Z')
   {
       center();
       return 1;
   }
   return 0;
}

void cfindtext()
{
   Z80 &cpu = CpuMgr.Cpu();
   unsigned char oldmode = editor; editor = ED_MEM;
   int rs = find1dlg(cpu.trace_curs);
   editor = oldmode;
   if (rs != -1)
       cpu.trace_top = cpu.trace_curs = unsigned(rs);
}
void cfindcode()
{
   Z80 &cpu = CpuMgr.Cpu();
   unsigned char oldmode = editor; editor = ED_MEM;
   int rs = find2dlg(cpu.trace_curs);
   editor = oldmode;
   if (rs != -1)
       cpu.trace_top = cpu.trace_curs = unsigned(rs);
}

void cbpx()
{
   Z80 &cpu = CpuMgr.Cpu();
   cpu.membits[cpu.trace_curs] ^= MEMBITS_BPX;
}

void cfindpc()
{
    Z80 &cpu = CpuMgr.Cpu();
    cpu.trace_top = cpu.trace_curs = cpu.pc;
}

void cup()
{
   Z80 &cpu = CpuMgr.Cpu();
   if (cpu.trace_curs > cpu.trace_top)
   {
      for (unsigned i = 1; i < trace_size; i++)
         if (cpu.trpc[i] == cpu.trace_curs)
             cpu.trace_curs = cpu.trpc[i-1];
   }
   else
       cpu.trace_top = cpu.trace_curs = cpu_up(cpu.trace_curs);
}

void cdown()
{
   Z80 &cpu = CpuMgr.Cpu();
   for (unsigned i = 0; i < trace_size; i++)
      if (cpu.trpc[i] == cpu.trace_curs)
      {
         cpu.trace_curs = cpu.trpc[i+1];
         if (i+1 == trace_size)
             cpu.trace_top = cpu.trpc[1];
         break;
      }
}
void cleft()  { CpuMgr.Cpu().trace_mode--; }
void cright() { CpuMgr.Cpu().trace_mode++; }
void chere()
{
    Z80 &cpu = CpuMgr.Cpu();
    cpu.dbgbreak = 0;
    dbgbreak = 0;
    cpu.dbgchk = 1;
 
    cpu.dbg_stophere = cpu.trace_curs;
}

void cpgdn()
{
   Z80 &cpu = CpuMgr.Cpu();
   unsigned curs = 0;
   for (unsigned i = 0; i < trace_size; i++)
      if (cpu.trace_curs == cpu.trpc[i]) curs = i;
   cpu.trace_top = cpu.trpc[trace_size];
   showtrace();
   cpu.trace_curs = cpu.trpc[curs];
}

void cpgup()
{
   Z80 &cpu = CpuMgr.Cpu();
   unsigned curs = 0;
   unsigned i; //Alone Coder 0.36.7
   for (/*unsigned*/ i = 0; i < trace_size; i++)
      if (cpu.trace_curs == cpu.trpc[i]) curs = i;
   for (i = 0; i < trace_size; i++)
       cpu.trace_top = cpu_up(cpu.trace_top);
   showtrace();
   cpu.trace_curs = cpu.trpc[curs];
}

void pop_pos()
{
   Z80 &cpu = CpuMgr.Cpu();
   if (stack_pos[0] == -1U)
       return;
   cpu.trace_curs = stack_cur[0];
   cpu.trace_top = stack_pos[0];
   memcpy(&stack_pos[0], &stack_pos[1], sizeof stack_pos - sizeof *stack_pos);
   memcpy(&stack_cur[0], &stack_cur[1], sizeof stack_cur - sizeof *stack_cur);
   stack_pos[(sizeof stack_pos / sizeof *stack_pos)-1] = -1U;
}

void cjump()
{
   Z80 &cpu = CpuMgr.Cpu();
   char *ptr = nullptr;
   for (char *p = asmpc; *p; p++)
      if (ishex(p[0]) & ishex(p[1]) & ishex(p[2]) & ishex(p[3])) ptr = p;
   if (!ptr) return;
   push_pos();
   unsigned addr;
   sscanf(ptr, "%04X", &addr);
   cpu.trace_curs = cpu.trace_top = addr;
}

void cdjump()
{
   char *ptr = nullptr;
   for (char *p = asmpc; *p; p++)
      if (ishex(p[0]) & ishex(p[1]) & ishex(p[2]) & ishex(p[3])) ptr = p;
   if (!ptr) return;
   unsigned addr; sscanf(ptr, "%04X", &addr);
   Z80 &cpu = CpuMgr.Cpu();
   cpu.mem_curs = addr; activedbg = WNDMEM; editor = ED_MEM;
}

void cfliplabels()
{
   trace_labels = !trace_labels; showtrace();
}
static void csave(unsigned n)
{
   Z80 &cpu = CpuMgr.Cpu();
   save_pos[n] = cpu.trace_top;
   save_cur[n] = cpu.trace_curs;
}
static void crest(unsigned n)
{
   Z80 &cpu = CpuMgr.Cpu();
   if (save_pos[n] == -1U)
       return;
   push_pos();
   cpu.trace_top = save_pos[n];
   cpu.trace_curs = save_cur[n];
}
void csave1() { csave(0); }
void csave2() { csave(1); }
void csave3() { csave(2); }
void csave4() { csave(3); }
void csave5() { csave(4); }
void csave6() { csave(5); }
void csave7() { csave(6); }
void csave8() { csave(7); }
void crest1() { crest(0); }
void crest2() { crest(1); }
void crest3() { crest(2); }
void crest4() { crest(3); }
void crest5() { crest(4); }
void crest6() { crest(5); }
void crest7() { crest(6); }
void crest8() { crest(7); }

namespace z80dbg
{
void __cdecl SetLastT()
{
   cpu.debug_last_t = comp.t_states + cpu.t;
}
}

void mon_step()
{
   Z80 &cpu = CpuMgr.Cpu();
   TZ80State &prevcpu = CpuMgr.PrevCpu();
   
   cpu.SetLastT();
   prevcpu = cpu;
//   CpuMgr.CopyToPrev();
   if(cpu.t >= conf.intlen)
       cpu.int_pend = false;
   cpu.Step();
   if (cpu.int_pend && cpu.iff1 && cpu.t != cpu.eipos && // int enabled in CPU not issued after EI
       cpu.int_gate) // int enabled by ATM hardware
   {
      handle_int(&cpu, cpu.IntVec());
   }

   cpu.CheckNextFrame();
   cpu.trace_curs = cpu.pc;
}

void mon_stepover()
{
   Z80 &cpu = CpuMgr.Cpu();
   unsigned char trace = 1;

   // call,rst
   if (cpu.pc_trflags & TWF_CALLCMD)
   {
       cpu.dbg_stopsp = cpu.sp & 0xFFFF;
       cpu.dbg_stophere = cpu.nextpc;
       trace = 0;
   }
   else if (cpu.pc_trflags & (TWF_BLKCMD | TWF_HALTCMD)) // ldir/lddr|cpir/cpdr|otir/otdr|inir/indr|halt
   {
       trace = 0;
       cpu.dbg_stophere = cpu.nextpc;
   }

/* [vv]
   // jr cc,$-xx, jp cc,$-xx
   else if ((cpu.pc_trflags & TWF_LOOPCMD) && (cpu.pc_trflags & 0xFFFF) < (cpu.pc & 0xFFFF))
   {
      cpu.dbg_stopsp = cpu.sp & 0xFFFF;
      cpu.dbg_stophere = cpu.nextpc,
      cpu.dbg_loop_r1 = cpu.pc_trflags & 0xFFFF;
      cpu.dbg_loop_r2 = cpu.pc & 0xFFFF;
      trace = 0;
   }
*/


/* [vv]
   else if (cpu.pc_trflags & TWF_BRANCH)
       trace = 1;
   else
   {
       trace = 1;
       cpu.dbg_stophere = cpu.nextpc;
   }
*/


   if (trace)
   {
       mon_step();
   }
   else
   {
       cpu.dbgbreak = 0;
       dbgbreak = 0;
       cpu.dbgchk = 1;
   }
}