Subversion Repositories pentevo

Rev

Rev 716 | Blame | 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 "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. }
  381.