Subversion Repositories pentevo

Rev

Rev 796 | Go to most recent revision | Blame | Compare with Previous | Last modification | View Log | Download | RSS feed

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