Subversion Repositories pentevo

Rev

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

  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 "fdd.h"
  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;
  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";
  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.  
  66. static char query_file_addr(FILEDLG_MODE mode)
  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);
  90.    int a1 = input4(FILEDLG_X+8,FILEDLG_Y+3,addr);
  91.    if (a1 == -1)
  92.        return 0;
  93.    addr = unsigned(a1);
  94.    fillattr(FILEDLG_X+8,FILEDLG_Y+3,4);
  95.    if (mode == FDM_LOAD)
  96.        return 1;
  97.    for (;;)
  98.    {
  99.       int e1 = input4(FILEDLG_X+18,FILEDLG_Y+3,end);
  100.       if (e1 == -1)
  101.           return 0;
  102.       if (unsigned(e1) < addr)
  103.           continue;
  104.       end = unsigned(e1);
  105.           return 1;
  106.    }
  107. }
  108.  
  109. static void write_mem()
  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.  
  117. static void read_mem()
  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.  
  125. static char rw_select_drive()
  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);
  132.       unsigned disk = unsigned(*str - 'A');
  133.       if (disk > 3) continue;
  134.       if (!comp.fdd[disk].rawdata) continue;
  135.       rw_drive = disk; return 1;
  136.    }
  137. }
  138.  
  139. static char rw_trdos_sectors(FILEDLG_MODE mode)
  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.  
  146.    char ln[64]; int t;
  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;
  158.    FDD *fdd = &comp.fdd[rw_drive];
  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);
  162.    if (t == -1) return 0; else rw_trk = unsigned(t);
  163.    fillattr(FILEDLG_X+14, FILEDLG_Y+3, 2);
  164.  
  165.    t = input2(FILEDLG_X+14, FILEDLG_Y+4, rw_tsec);
  166.    if (t == -1) return 0; else rw_tsec = unsigned(t);
  167.    fillattr(FILEDLG_X+14, FILEDLG_Y+4, 2);
  168.  
  169.    t = input4(FILEDLG_X+8,FILEDLG_Y+5,addr);
  170.    if (t == -1) return 0; else addr = unsigned(t);
  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;
  177.       if (unsigned(t) < addr) continue;
  178.       end = unsigned(t); break;
  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 (;;) {
  188.       int left = int(end+1) - int(addr+offset);
  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; }
  194.       const SECHDR *hdr = tc.get_sector(sec+1, 1);
  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) {
  199.          memcpy(memdata+offset, hdr->data, size_t(left));
  200.       } else {
  201.          tc.write_sector(sec+1, 1, memdata+offset);
  202.          fdd->optype |= 1;
  203.       }
  204.  
  205.       offset += unsigned(left);
  206.       if(++sec == 0x10)
  207.       {
  208.           trk++;
  209.           sec = 0;
  210.       }
  211.    }
  212.  
  213.    end = addr + offset - 1;
  214.    if (mode == FDM_LOAD) write_mem();
  215.    return 1;
  216. }
  217.  
  218. static char wr_trdos_file()
  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.  
  224.    char ln[64]; int t;
  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;
  233.    FDD *fdd = &comp.fdd[rw_drive];
  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);
  240.    for (size_t ptr = strlen(trdname); ptr < 8; trdname[ptr++] = ' ');
  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);
  249.    if (t == -1) return 0; else addr = unsigned(t);
  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;
  256.       if (unsigned(t) < addr) continue;
  257.       end = unsigned(t); break;
  258.    }
  259.  
  260.    read_mem();
  261.  
  262.    unsigned char hdr[16];
  263.    memcpy(hdr, trdname, 8);
  264.    hdr[8] = u8(*trdext);
  265.  
  266.    unsigned sz = end-addr+1;
  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
  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;
  300.          size_t sz = fread(bf, 1, sizeof(bf), ff);
  301.          fclose(ff);
  302.          end = unsigned(addr + sz - 1);
  303.          end = min(end, 0xFFFFU);
  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
  374.             a += unsigned(disasm_line(a, line));
  375.             fprintf(ff, "%s\n", line);
  376.          }
  377.          fclose(ff);
  378.          return;
  379.       }
  380.  
  381.       case 4:
  382.       {
  383.          return;
  384.       }
  385.    }
  386. }
  387.