Subversion Repositories pentevo

Rev

Rev 883 | 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 "memory.h"
  7. #include "gsz80.h"
  8. #include "z80.h"
  9. #include "util.h"
  10. #include "sndrender/sndcounter.h"
  11. #include "sound.h"
  12.  
  13. namespace z80fast
  14. {
  15. #include "z80_main.h"
  16. }
  17.  
  18. int fmsoundon0=4; //Alone Coder
  19. int tfmstatuson0=2; //Alone Coder
  20. char pressedit = 0; //Alone Coder
  21.  
  22. void __fastcall wmdbg(u32 addr, u8 val);
  23. u8 __fastcall rmdbg(u32 addr);
  24. u8 *__fastcall MemDbg(u32 addr);
  25. void __cdecl BankNames(int i, char *Name);
  26. namespace z80dbg
  27. {
  28. void Z80FAST step();
  29. __int64 __cdecl delta();
  30. void __cdecl SetLastT();
  31. }
  32.  
  33. #pragma pack(8)
  34.  
  35. void out(unsigned port, unsigned char val);
  36. unsigned char in(unsigned port);
  37.  
  38. Z80INLINE unsigned char m1_cycle(Z80 *cpu)
  39. {
  40.    unsigned char temp_op_code;
  41.    cpu->r_low++; cpu->t += 4;
  42.    temp_op_code = cpu->MemIf->xm(cpu->pc++);
  43.    if((conf.mem_model==MM_ATM3)&&(comp.pBE)&&cpu->nmi_in_progress)
  44.       {
  45.           if(comp.pBE == 1)
  46.           {
  47.                           if(trdos_in_nmi)
  48.                               comp.flags |= CF_SETDOSROM|CF_TRDOS;
  49.               cpu->nmi_in_progress = false;
  50.               set_banks();
  51.           }
  52.           comp.pBE--;
  53.       }
  54.    return temp_op_code;
  55. }
  56.  
  57. /*
  58. unsigned char TMainZ80::rm(unsigned addr) { return z80fast::rm(addr); }
  59.  
  60. unsigned char TMainZ80::dbgrm(unsigned addr) { return ::rmdbg(addr); }
  61.  
  62. void TMainZ80::wm(unsigned addr, unsigned char val) { z80fast::wm(addr, val); }
  63.  
  64. void TMainZ80::dbgwm(unsigned addr, unsigned char val) { ::wmdbg(addr, val); }
  65. */
  66. u8 *TMainZ80::DirectMem(unsigned addr) const
  67. {
  68.     return am_r(addr);
  69. }
  70.  
  71. unsigned char TMainZ80::m1_cycle() { return ::m1_cycle(this); }
  72.  
  73. unsigned char TMainZ80::in(unsigned port) { return ::in(port); }
  74.  
  75. void TMainZ80::out(unsigned port, unsigned char val) { ::out(port, val); }
  76.  
  77. u8 TMainZ80::IntVec()
  78. {
  79.     return (comp.flags & CF_Z80FBUS)? u8(rdtsc() & 0xFF) : 0xFF;
  80. }
  81.  
  82. void TMainZ80::CheckNextFrame()
  83. {
  84.    if(t >= conf.frame)
  85.    {
  86.        comp.t_states += conf.frame;
  87.        t -= conf.frame;
  88.        eipos -= conf.frame;
  89.        comp.frame_counter++;
  90.        int_pend = true;
  91.    }
  92. }
  93.  
  94. void TMainZ80::retn()
  95. {
  96.     //nmi_in_progress = false;
  97.     //set_banks();
  98. }
  99.  
  100. static const TMemIf FastMemIf = { Xm, Rm, Wm };
  101. static const TMemIf DbgMemIf = { DbgXm, DbgRm, DbgWm };
  102.  
  103.  
  104. TMainZ80 cpu(0, BankNames, z80dbg::step, z80dbg::delta, z80dbg::SetLastT, membits, &FastMemIf, &DbgMemIf);
  105.  
  106.  
  107. #ifdef MOD_GSZ80
  108. namespace z80gs
  109. {
  110.     u8 __fastcall dbgrm(u32 addr);
  111.     void __fastcall dbgwm(u32 addr, u8 val);
  112.     u8 *__fastcall MemDbg(u32 addr);
  113.     void __cdecl BankNames(int i, char *Name);
  114.     void Z80FAST step();
  115.     __int64 __cdecl delta();
  116.     void __cdecl SetLastT();
  117.     u8 membits[0x10000];
  118.  
  119.     SNDRENDER sound;
  120.     static const TMemIf FastMemIf = { z80gs::Xm, z80gs::Rm, z80gs::Wm };
  121.     static const TMemIf DbgMemIf = { z80gs::DbgXm, z80gs::DbgRm, z80gs::DbgWm };
  122.  
  123. }
  124.  
  125. u8 TGsZ80::IntVec()
  126. {
  127.     return 0xFF;
  128. }
  129.  
  130. void TGsZ80::CheckNextFrame()
  131. {
  132.    if(t >= z80gs::GSCPUINT)
  133.    {
  134.       t -= z80gs::GSCPUINT;
  135.       eipos -= z80gs::GSCPUINT;
  136.       z80gs::gs_t_states += z80gs::GSCPUINT;
  137.       int_pend = true;
  138.    }
  139. }
  140.  
  141. TGsZ80 gscpu(1, z80gs::BankNames, z80gs::step, z80gs::delta,
  142.     z80gs::SetLastT, z80gs::membits, &z80gs::FastMemIf, &z80gs::DbgMemIf);
  143. #endif
  144.  
  145. TCpuMgr CpuMgr;
  146.  
  147. void TCpuMgr::SwitchCpu()
  148. {
  149.     CurrentCpu++;
  150.     CurrentCpu %= Count;
  151. }
  152.  
  153. Z80 *TCpuMgr::Cpus[] =
  154. {
  155.   &cpu,
  156. #ifdef MOD_GSZ80
  157.   &gscpu
  158. #endif
  159. };
  160.  
  161.  
  162. const unsigned TCpuMgr::Count = _countof(Cpus);
  163. TZ80State TCpuMgr::PrevCpus[TCpuMgr::Count];
  164. unsigned TCpuMgr::CurrentCpu = 0;
  165.  
  166. #ifdef MOD_GSBASS
  167. GSHLE gs;
  168. #endif
  169.  
  170. unsigned char dbgbreak = 0;
  171.  
  172.  
  173. CONFIG conf;
  174. COMPUTER comp;
  175. TEMP temp;
  176. ATA_PORT hdd;   // not in `comp' - not cleared in reset()
  177. K_INPUT input;
  178. ISA_MODEM modem;
  179.  
  180. SNDRENDER sound;
  181. SNDCHIP ay[2];
  182. SNDCOUNTER sndcounter;
  183.  
  184.  
  185. unsigned char *base_sos_rom, *base_dos_rom, *base_128_rom, *base_sys_rom;
  186.  
  187. #ifdef CACHE_ALIGNED
  188. ATTR_ALIGN(4096)
  189. unsigned char memory[PAGE*MAX_PAGES];
  190. #else // __declspec(align) not available, force QWORD align with old method
  191. __int64 memory__[PAGE*MAX_PAGES/sizeof(__int64)];
  192. unsigned char * const memory = (unsigned char*)memory__;
  193. #endif
  194.  
  195. #ifdef MOD_VID_VD
  196. CACHE_ALIGNED unsigned char vdmem[4][0x2000];
  197. #endif
  198.  
  199. unsigned char membits[0x10000];
  200. unsigned char *bankr[4];
  201. unsigned char *bankw[4];
  202. unsigned char cmos[0x100];
  203. unsigned char nvram[0x800];
  204.  
  205. unsigned sndplaybuf[PLAYBUFSIZE];
  206. unsigned spbsize;
  207.  
  208. FILE *savesnd;
  209. unsigned char savesndtype; // 0-none,1-wave,2-vtx
  210. unsigned char *vtxbuf; unsigned vtxbufsize, vtxbuffilled;
  211.  
  212. unsigned char trdos_load, trdos_save, trdos_format, trdos_seek; // for leds
  213. unsigned char needclr; // clear screenbuffer before rendering
  214.  
  215. HWND wnd; HINSTANCE hIn;
  216.  
  217. char droppedFile[512];
  218.  
  219. const TMemModel mem_model[N_MM_MODELS] =
  220. {
  221.     { "PENTAGON", "PENTAGON",                MM_PENTAGON, 128,  RAM_128 | RAM_256 | RAM_512 | RAM_1024 },
  222.     { "ZS SCORPION", "SCORPION",             MM_SCORP, 256,  RAM_256 | RAM_1024 },
  223.     { "ZS SCORPION + PROF ROM", "PROFSCORP", MM_PROFSCORP, 256,  RAM_256 | RAM_1024 },
  224.     { "PROFI", "PROFI",                      MM_PROFI, 1024, RAM_1024 },
  225.     { "ATM-TURBO v4.50", "ATM450",           MM_ATM450, 512,  RAM_512 | RAM_1024 },
  226.     { "ATM-TURBO 2+ v7.10", "ATM710",        MM_ATM710, 1024, RAM_128 | RAM_256 | RAM_512 | RAM_1024 },
  227.     { "ZX-EVO", "ATM3",                     MM_ATM3, 4096, RAM_4096 },
  228.     { "Nemo's KAY", "KAY",                   MM_KAY, 256,  RAM_256 | RAM_1024 },
  229.     { "ZX-Spectrum +3", "PLUS3",             MM_PLUS3, 128,  RAM_128 },
  230.     { "QUORUM", "QUORUM",                    MM_QUORUM, 1024, RAM_128 | RAM_1024 },
  231. };
  232.  
  233. unsigned char kbdpc[VK_MAX]; // add cells for mouse & joystick
  234. unsigned char kbdpcEX[6]; //Dexus
  235. keyports inports[VK_MAX];
  236.  
  237. char statusline[128];
  238. unsigned statcnt;
  239.  
  240. char arcbuffer[0x2000]; // extensions and command lines for archivers
  241. char skiparc[0x400]; // ignore this files in archive
  242.  
  243. unsigned char exitflag = 0; // avoid call exit() twice
  244.  
  245. // beta128 vars
  246. unsigned trd_toload = 0; // drive to load
  247. unsigned DefaultDrive = -1U; // ─шёъютюф яю єьюыўрэш■ т ъюЄюЁ√щ уЁєч Єё  юсЁрч√ фшёъют яЁш ёЄрЁЄх
  248.  
  249. char trd_loaded[4]; // used to get first free drive with no account of autoloaded images
  250. char ininame[0x200];
  251. char helpname[0x200];
  252. unsigned snapsize;
  253.  
  254. // conditional breakpoints support
  255. unsigned brk_port_in, brk_port_out;
  256. unsigned char brk_port_val;
  257.  
  258. virtkeyt pckeys[] =
  259. {
  260.    { "ESC", DIK_ESCAPE },
  261.    { "F1", DIK_F1 }, { "F2", DIK_F2 }, { "F3", DIK_F3 },
  262.    { "F4", DIK_F4 }, { "F5", DIK_F5 }, { "F6", DIK_F6 },
  263.    { "F7", DIK_F7 }, { "F8", DIK_F8 }, { "F9", DIK_F9 },
  264.    { "F10", DIK_F10 }, { "F11", DIK_F11 }, { "F12", DIK_F12 },
  265.    { "PRSCR", DIK_SYSRQ }, { "SCLOCK", DIK_SCROLL }, { "PAUSE", DIK_PAUSE },
  266.  
  267.    { "1", DIK_1 }, { "2", DIK_2 }, { "3", DIK_3 }, { "4", DIK_4 }, { "5", DIK_5 },
  268.    { "6", DIK_6 }, { "7", DIK_7 }, { "8", DIK_8 }, { "9", DIK_9 }, { "0", DIK_0 },
  269.  
  270.    { "Q", DIK_Q }, { "W", DIK_W }, { "E", DIK_E }, { "R", DIK_R }, { "T", DIK_T },
  271.    { "Y", DIK_Y }, { "U", DIK_U }, { "I", DIK_I }, { "O", DIK_O }, { "P", DIK_P },
  272.    { "A", DIK_A }, { "S", DIK_S }, { "D", DIK_D }, { "F", DIK_F }, { "G", DIK_G },
  273.    { "H", DIK_H }, { "J", DIK_J }, { "K", DIK_K }, { "L", DIK_L },
  274.    { "Z", DIK_Z }, { "X", DIK_X }, { "C", DIK_C }, { "V", DIK_V }, { "B", DIK_B },
  275.    { "N", DIK_N }, { "M", DIK_M },
  276.  
  277.    { "MINUS", DIK_MINUS }, { "PLUS", DIK_EQUALS }, { "BACK", DIK_BACK },
  278.    { "TAB", DIK_TAB }, { "LB", DIK_LBRACKET }, { "RB", DIK_RBRACKET },
  279.    { "CAPS", DIK_CAPITAL }, { "TIL", DIK_GRAVE }, { "SPACE", DIK_SPACE },
  280.    { "COL", DIK_SEMICOLON }, { "QUOTE", DIK_APOSTROPHE }, { "ENTER", DIK_RETURN },
  281.    { "COMMA", DIK_COMMA }, { "POINT", DIK_PERIOD }, { "SLASH", DIK_SLASH }, { "BACKSL", DIK_BACKSLASH },
  282.    { "SHIFT", DIK_SHIFT }, { "ALT", DIK_MENU }, { "CONTROL", DIK_CONTROL },
  283.    { "LSHIFT", DIK_LSHIFT }, { "LALT", DIK_LMENU }, { "LCONTROL", DIK_LCONTROL },
  284.    { "RSHIFT", DIK_RSHIFT }, { "RALT", DIK_RMENU }, { "RCONTROL", DIK_RCONTROL },
  285.  
  286.    { "INS", DIK_INSERT }, { "HOME", DIK_HOME }, { "PGUP", DIK_PRIOR },
  287.    { "DEL", DIK_DELETE }, { "END", DIK_END },   { "PGDN", DIK_NEXT },
  288.  
  289.    { "UP", DIK_UP }, { "DOWN", DIK_DOWN }, { "LEFT", DIK_LEFT }, { "RIGHT", DIK_RIGHT },
  290.  
  291.    { "NUMLOCK", DIK_NUMLOCK }, { "GRDIV", DIK_DIVIDE },
  292.    { "GRMUL", DIK_MULTIPLY }, { "GRSUB", DIK_SUBTRACT }, { "GRADD", DIK_ADD },
  293.    { "GRENTER", DIK_NUMPADENTER },
  294.  
  295.    { "N0", DIK_NUMPAD0 }, { "N1", DIK_NUMPAD1 }, { "N2", DIK_NUMPAD2 },
  296.    { "N3", DIK_NUMPAD3 }, { "N4", DIK_NUMPAD4 }, { "N5", DIK_NUMPAD5 },
  297.    { "N6", DIK_NUMPAD6 }, { "N7", DIK_NUMPAD7 }, { "N8", DIK_NUMPAD8 },
  298.    { "N9", DIK_NUMPAD9 }, { "NP", DIK_DECIMAL },
  299.  
  300.    { "LMB", VK_LMB }, { "RMB", VK_RMB }, { "MMB", VK_MMB },
  301.    { "MWU", VK_MWU }, { "MWD", VK_MWD },
  302.  
  303.    { "JLEFT", VK_JLEFT }, { "JRIGHT", VK_JRIGHT },
  304.    { "JUP", VK_JUP }, { "JDOWN", VK_JDOWN }, { "JFIRE", VK_JFIRE },
  305.    { "JB0", VK_JB0 },
  306.    { "JB1", VK_JB1 },
  307.    { "JB2", VK_JB2 },
  308.    { "JB3", VK_JB3 },
  309.    { "JB4", VK_JB4 },
  310.    { "JB5", VK_JB5 },
  311.    { "JB6", VK_JB6 },
  312.    { "JB7", VK_JB7 },
  313.    { "JB8", VK_JB8 },
  314.    { "JB9", VK_JB9 },
  315.    { "JB10", VK_JB10 },
  316.    { "JB11", VK_JB11 },
  317.    { "JB12", VK_JB12 },
  318.    { "JB13", VK_JB13 },
  319.    { "JB14", VK_JB14 },
  320.    { "JB15", VK_JB15 },
  321.    { "JB16", VK_JB16 },
  322.    { "JB17", VK_JB17 },
  323.    { "JB18", VK_JB18 },
  324.    { "JB19", VK_JB19 },
  325.    { "JB20", VK_JB20 },
  326.    { "JB21", VK_JB21 },
  327.    { "JB22", VK_JB22 },
  328.    { "JB23", VK_JB23 },
  329.    { "JB24", VK_JB24 },
  330.    { "JB25", VK_JB25 },
  331.    { "JB26", VK_JB26 },
  332.    { "JB27", VK_JB27 },
  333.    { "JB28", VK_JB28 },
  334.    { "JB29", VK_JB29 },
  335.    { "JB30", VK_JB30 },
  336.    { "JB31", VK_JB31 },
  337. };
  338. const size_t pckeys_count = _countof(pckeys);
  339.  
  340. static zxkey zxk_default[] =
  341. {
  342.    { "KRIGHT", &input.kjoy, u8(~1U) },
  343.    { "KLEFT",  &input.kjoy, u8(~2U) },
  344.    { "KDOWN",  &input.kjoy, u8(~4U) },
  345.    { "KUP",    &input.kjoy, u8(~8U) },
  346.    { "KFIRE",  &input.kjoy, u8(~16U)},
  347.    { "KFIRE1", &input.kjoy, u8(~16U) },
  348.    { "KFIRE2", &input.kjoy, u8(~32U) },
  349.    { "KFIRE3", &input.kjoy, u8(~64U) },
  350.  
  351.    // fuller joystick
  352.    { "FRIGHT", &input.fjoy, u8(~8U) },
  353.    { "FLEFT",  &input.fjoy, u8(~4U) },
  354.    { "FDOWN",  &input.fjoy, u8(~2U) },
  355.    { "FUP",    &input.fjoy, u8(~1U) },
  356.    { "FFIRE",  &input.fjoy, u8(~128U)},
  357.    { "FFIRE1", &input.fjoy, u8(~128U) },
  358.    { "FFIRE2", &input.fjoy, u8(~64U) },
  359.    { "FFIRE3", &input.fjoy, u8(~32U) },
  360.  
  361.    { "ENT", input.kbd+6, u8(~0x01U) },
  362.    { "SPC", input.kbd+7, u8(~0x01U) },
  363.    { "SYM", input.kbd+7, u8(~0x02U) },
  364.  
  365.    { "CAP", input.kbd+0, u8(~0x01U) },
  366.    { "Z",   input.kbd+0, u8(~0x02U) },
  367.    { "X",   input.kbd+0, u8(~0x04U) },
  368.    { "C",   input.kbd+0, u8(~0x08U) },
  369.    { "V",   input.kbd+0, u8(~0x10U) },
  370.  
  371.    { "A",   input.kbd+1, u8(~0x01U) },
  372.    { "S",   input.kbd+1, u8(~0x02U) },
  373.    { "D",   input.kbd+1, u8(~0x04U) },
  374.    { "F",   input.kbd+1, u8(~0x08U) },
  375.    { "G",   input.kbd+1, u8(~0x10U) },
  376.  
  377.    { "Q",   input.kbd+2, u8(~0x01U) },
  378.    { "W",   input.kbd+2, u8(~0x02U) },
  379.    { "E",   input.kbd+2, u8(~0x04U) },
  380.    { "R",   input.kbd+2, u8(~0x08U) },
  381.    { "T",   input.kbd+2, u8(~0x10U) },
  382.  
  383.    { "1",   input.kbd+3, u8(~0x01U) },
  384.    { "2",   input.kbd+3, u8(~0x02U) },
  385.    { "3",   input.kbd+3, u8(~0x04U) },
  386.    { "4",   input.kbd+3, u8(~0x08U) },
  387.    { "5",   input.kbd+3, u8(~0x10U) },
  388.  
  389.    { "0",   input.kbd+4, u8(~0x01U) },
  390.    { "9",   input.kbd+4, u8(~0x02U) },
  391.    { "8",   input.kbd+4, u8(~0x04U) },
  392.    { "7",   input.kbd+4, u8(~0x08U) },
  393.    { "6",   input.kbd+4, u8(~0x10U) },
  394.  
  395.    { "P",   input.kbd+5, u8(~0x01U) },
  396.    { "O",   input.kbd+5, u8(~0x02U) },
  397.    { "I",   input.kbd+5, u8(~0x04U) },
  398.    { "U",   input.kbd+5, u8(~0x08U) },
  399.    { "Y",   input.kbd+5, u8(~0x10U) },
  400.  
  401.    { "L",   input.kbd+6, u8(~0x02U) },
  402.    { "K",   input.kbd+6, u8(~0x04U) },
  403.    { "J",   input.kbd+6, u8(~0x08U) },
  404.    { "H",   input.kbd+6, u8(~0x10U) },
  405.  
  406.    { "M",   input.kbd+7, u8(~0x04U) },
  407.    { "N",   input.kbd+7, u8(~0x08U) },
  408.    { "B",   input.kbd+7, u8(~0x10U) },
  409. };
  410.  
  411. static zxkey zxk_bk08[] =
  412. {
  413.    { "KRIGHT", &input.kjoy, u8(~1U) },
  414.    { "KLEFT",  &input.kjoy, u8(~2U) },
  415.    { "KDOWN",  &input.kjoy, u8(~4U) },
  416.    { "KUP",    &input.kjoy, u8(~8U) },
  417.    { "KFIRE",  &input.kjoy, u8(~16U)},
  418.    { "KFIRE1", &input.kjoy, u8(~16U) },
  419.    { "KFIRE2", &input.kjoy, u8(~32U) },
  420.    { "KFIRE3", &input.kjoy, u8(~64U) },
  421.  
  422.    // fuller joystick
  423.    { "FRIGHT", &input.fjoy, u8(~8U) },
  424.    { "FLEFT",  &input.fjoy, u8(~4U) },
  425.    { "FDOWN",  &input.fjoy, u8(~2U) },
  426.    { "FUP",    &input.fjoy, u8(~1U) },
  427.    { "FFIRE",  &input.fjoy, u8(~128U)},
  428.    { "FFIRE1", &input.fjoy, u8(~128U) },
  429.    { "FFIRE2", &input.fjoy, u8(~64U) },
  430.    { "FFIRE3", &input.fjoy, u8(~32U) },
  431.  
  432.    { "ALT", input.kbd+0, u8(~0x01U) },
  433.    { "Z",   input.kbd+0, u8(~0x02U) },
  434.    { "X",   input.kbd+0, u8(~0x04U) },
  435.    { "C",   input.kbd+0, u8(~0x08U) },
  436.    { "V",   input.kbd+0, u8(~0x10U) },
  437.    { "RUS", input.kbd+0, u8(~0x20U) },
  438.    { "SHF", input.kbd+0, u8( 0x7FU) },
  439.  
  440.    { "A",   input.kbd+1, u8(~0x01U) },
  441.    { "S",   input.kbd+1, u8(~0x02U) },
  442.    { "D",   input.kbd+1, u8(~0x04U) },
  443.    { "F",   input.kbd+1, u8(~0x08U) },
  444.    { "G",   input.kbd+1, u8(~0x10U) },
  445.    { "BSL", input.kbd+1, u8(~0x20U) },
  446.    { "SL",  input.kbd+1, u8( 0x7FU) },
  447.  
  448.    { "Q",   input.kbd+2, u8(~0x01U) },
  449.    { "W",   input.kbd+2, u8(~0x02U) },
  450.    { "E",   input.kbd+2, u8(~0x04U) },
  451.    { "R",   input.kbd+2, u8(~0x08U) },
  452.    { "T",   input.kbd+2, u8(~0x10U) },
  453.    { "CMA", input.kbd+2, u8(~0x20U) },
  454.    { "PNT", input.kbd+2, u8( 0x7FU) },
  455.  
  456.    { "1",   input.kbd+3, u8(~0x01U) },
  457.    { "2",   input.kbd+3, u8(~0x02U) },
  458.    { "3",   input.kbd+3, u8(~0x04U) },
  459.    { "4",   input.kbd+3, u8(~0x08U) },
  460.    { "5",   input.kbd+3, u8(~0x10U) },
  461.    { "TIL", input.kbd+3, u8(~0x20U) },
  462.    { "TAB", input.kbd+3, u8( 0x7FU) },
  463.  
  464.    { "0",   input.kbd+4, u8(~0x01U) },
  465.    { "9",   input.kbd+4, u8(~0x02U) },
  466.    { "8",   input.kbd+4, u8(~0x04U) },
  467.    { "7",   input.kbd+4, u8(~0x08U) },
  468.    { "6",   input.kbd+4, u8(~0x10U) },
  469.    { "MNS", input.kbd+4, u8(~0x20U) },
  470.    { "PLS", input.kbd+4, u8( 0x7FU) },
  471.  
  472.    { "P",   input.kbd+5, u8(~0x01U) },
  473.    { "O",   input.kbd+5, u8(~0x02U) },
  474.    { "I",   input.kbd+5, u8(~0x04U) },
  475.    { "U",   input.kbd+5, u8(~0x08U) },
  476.    { "Y",   input.kbd+5, u8(~0x10U) },
  477.    { "LB",  input.kbd+5, u8(~0x20U) },
  478.    { "RB",  input.kbd+5, u8( 0x7FU) },
  479.  
  480.    { "ENT", input.kbd+6, u8(~0x01U) },
  481.    { "L",   input.kbd+6, u8(~0x02U) },
  482.    { "K",   input.kbd+6, u8(~0x04U) },
  483.    { "J",   input.kbd+6, u8(~0x08U) },
  484.    { "H",   input.kbd+6, u8(~0x10U) },
  485.    { "COL", input.kbd+6, u8(~0x20U) },
  486.    { "QUO", input.kbd+6, u8( 0x7FU) },
  487.  
  488.    { "SPC", input.kbd+7, u8(~0x01U) },
  489.    { "CTL", input.kbd+7, u8(~0x02U) },
  490.    { "M",   input.kbd+7, u8(~0x04U) },
  491.    { "N",   input.kbd+7, u8(~0x08U) },
  492.    { "B",   input.kbd+7, u8(~0x10U) },
  493.    { "R/A", input.kbd+7, u8(~0x20U) },
  494.    { "CPS", input.kbd+7, u8( 0x7FU) }
  495. };
  496.  
  497. static zxkey zxk_quorum[] =
  498. {
  499.    { "KRIGHT", &input.kjoy, u8(~1U) },
  500.    { "KLEFT",  &input.kjoy, u8(~2U) },
  501.    { "KDOWN",  &input.kjoy, u8(~4U) },
  502.    { "KUP",    &input.kjoy, u8(~8U) },
  503.    { "KFIRE",  &input.kjoy, u8(~16U)},
  504.    { "KFIRE1", &input.kjoy, u8(~16U) },
  505.    { "KFIRE2", &input.kjoy, u8(~32U) },
  506.    { "KFIRE3", &input.kjoy, u8(~64U) },
  507.  
  508.    // fuller joystick
  509.    { "FRIGHT", &input.fjoy, u8(~8U) },
  510.    { "FLEFT",  &input.fjoy, u8(~4U) },
  511.    { "FDOWN",  &input.fjoy, u8(~2U) },
  512.    { "FUP",    &input.fjoy, u8(~1U) },
  513.    { "FFIRE",  &input.fjoy, u8(~128U)},
  514.    { "FFIRE1", &input.fjoy, u8(~128U) },
  515.    { "FFIRE2", &input.fjoy, u8(~64U) },
  516.    { "FFIRE3", &input.fjoy, u8(~32U) },
  517.  
  518.  
  519.    { "ENT", input.kbd+6, u8(~0x01U) },
  520.    { "SPC", input.kbd+7, u8(~0x01U) },
  521.    { "SYM", input.kbd+7, u8(~0x02U) },
  522.  
  523.    { "CAP", input.kbd+0, u8(~0x01U) },
  524.    { "Z",   input.kbd+0, u8(~0x02U) },
  525.    { "X",   input.kbd+0, u8(~0x04U) },
  526.    { "C",   input.kbd+0, u8(~0x08U) },
  527.    { "V",   input.kbd+0, u8(~0x10U) },
  528.  
  529.    { "A",   input.kbd+1, u8(~0x01U) },
  530.    { "S",   input.kbd+1, u8(~0x02U) },
  531.    { "D",   input.kbd+1, u8(~0x04U) },
  532.    { "F",   input.kbd+1, u8(~0x08U) },
  533.    { "G",   input.kbd+1, u8(~0x10U) },
  534.  
  535.    { "Q",   input.kbd+2, u8(~0x01U) },
  536.    { "W",   input.kbd+2, u8(~0x02U) },
  537.    { "E",   input.kbd+2, u8(~0x04U) },
  538.    { "R",   input.kbd+2, u8(~0x08U) },
  539.    { "T",   input.kbd+2, u8(~0x10U) },
  540.  
  541.    { "1",   input.kbd+3, u8(~0x01U) },
  542.    { "2",   input.kbd+3, u8(~0x02U) },
  543.    { "3",   input.kbd+3, u8(~0x04U) },
  544.    { "4",   input.kbd+3, u8(~0x08U) },
  545.    { "5",   input.kbd+3, u8(~0x10U) },
  546.  
  547.    { "0",   input.kbd+4, u8(~0x01U) },
  548.    { "9",   input.kbd+4, u8(~0x02U) },
  549.    { "8",   input.kbd+4, u8(~0x04U) },
  550.    { "7",   input.kbd+4, u8(~0x08U) },
  551.    { "6",   input.kbd+4, u8(~0x10U) },
  552.  
  553.    { "P",   input.kbd+5, u8(~0x01U) },
  554.    { "O",   input.kbd+5, u8(~0x02U) },
  555.    { "I",   input.kbd+5, u8(~0x04U) },
  556.    { "U",   input.kbd+5, u8(~0x08U) },
  557.    { "Y",   input.kbd+5, u8(~0x10U) },
  558.  
  559.    { "L",   input.kbd+6, u8(~0x02U) },
  560.    { "K",   input.kbd+6, u8(~0x04U) },
  561.    { "J",   input.kbd+6, u8(~0x08U) },
  562.    { "H",   input.kbd+6, u8(~0x10U) },
  563.  
  564.    { "M",   input.kbd+7, u8(~0x04U) },
  565.    { "N",   input.kbd+7, u8(~0x08U) },
  566.    { "B",   input.kbd+7, u8(~0x10U) },
  567.  
  568.    // quorum additional keys
  569.    { "RUS",    input.kbd+8, u8(~0x01U) },
  570.    { "LAT",    input.kbd+8, u8(~0x02U) },
  571.    { "N1",     input.kbd+8, u8(~0x08U) },
  572.    { "N2",     input.kbd+8, u8(~0x10U) },
  573.    { ".",      input.kbd+8, u8(~0x20U) },
  574.  
  575.    { "CAPS",   input.kbd+9, u8(~0x01U) },
  576.    { "F2",     input.kbd+9, u8(~0x02U) },
  577.    { "TILDA",  input.kbd+9, u8(~0x04U) },
  578.    { "N4",     input.kbd+9, u8(~0x08U) },
  579.    { "QUOTE",  input.kbd+9, u8(~0x10U) },
  580.    { "N6",     input.kbd+9, u8(~0x20U) },
  581.  
  582.    { "TAB",    input.kbd+10, u8(~0x01U) },
  583.    { "F4",     input.kbd+10, u8(~0x02U) },
  584.    { "N7",     input.kbd+10, u8(~0x08U) },
  585.    { "N5",     input.kbd+10, u8(~0x10U) },
  586.    { "N9",     input.kbd+10, u8(~0x20U) },
  587.  
  588.    { "EBOX",   input.kbd+11, u8(~0x01U) },
  589.    { "F5",     input.kbd+11, u8(~0x02U) },
  590.    { "BS",     input.kbd+11, u8(~0x04U) },
  591.    { "NSLASH", input.kbd+11, u8(~0x08U) },
  592.    { "N8",     input.kbd+11, u8(~0x10U) },
  593.    { "NMINUS", input.kbd+11, u8(~0x20U) },
  594.  
  595.    { "-",      input.kbd+12, u8(~0x01U) },
  596.    { "+",      input.kbd+12, u8(~0x04U) },
  597.    { "DEL",    input.kbd+12, u8(~0x08U) },
  598.    { "NSTAR",  input.kbd+12, u8(~0x10U) },
  599.    { "GBOX",   input.kbd+12, u8(~0x20U) },
  600.  
  601.    { "COLON",  input.kbd+13, u8(~0x01U) },
  602.    { "F3",     input.kbd+13, u8(~0x02U) },
  603.    { "\\",     input.kbd+13, u8(~0x04U) },
  604.    { "]",      input.kbd+13, u8(~0x10U) },
  605.    { "[",      input.kbd+13, u8(~0x20U) },
  606.  
  607.    { ",",      input.kbd+14, u8(~0x01U) },
  608.    { "/",      input.kbd+14, u8(~0x10U) },
  609.    { "N3",     input.kbd+14, u8(~0x20U) },
  610.  
  611.    { "F1",     input.kbd+15, u8(~0x02U) },
  612.    { "N0",     input.kbd+15, u8(~0x08U) },
  613.    { "NPOINT", input.kbd+15, u8(~0x10U) },
  614.    { "NPLUS",  input.kbd+15, u8(~0x20U) },
  615. };
  616.  
  617. zxkeymap zxk_maps[] =
  618. {
  619.    { "default", zxk_default, _countof(zxk_default) },
  620.    { "BK08", zxk_bk08, _countof(zxk_bk08) },
  621.    { "quorum", zxk_quorum, _countof(zxk_quorum) },
  622. };
  623.  
  624. const size_t zxk_maps_count = _countof(zxk_maps);
  625.  
  626. PALETTEENTRY syspalette[0x100];
  627.  
  628. GDIBMP gdibmp = { { { sizeof(BITMAPINFOHEADER), 320, -240, 1, 8, BI_RGB, 0 } } };
  629.  
  630. PALETTE_OPTIONS pals[32] = {{"default",0x00,0x80,0xC0,0xE0,0xFF,0xC8,0xFF,0x00,0x00,0x00,0xFF,0x00,0x00,0x00,0xFF}};
  631.  
  632. #pragma pack()
  633.  
  634. unsigned char snbuf[4*1048576]; // large temporary buffer (for reading snapshots)
  635. unsigned char gdibuf[2*1048576];
  636.  
  637. // on-screen watches block
  638. uintptr_t watch_script[4][64];
  639. unsigned char watch_enabled[4];
  640. unsigned char used_banks[MAX_PAGES];
  641. unsigned char trace_rom=1, trace_ram=1;
  642.  
  643. DWORD WinVerMajor;
  644. DWORD WinVerMinor;
  645. HWND dlg; // used in setcheck/getcheck: gui settings, monitor dialogs
  646.  
  647. HBITMAP hbm;  // bitmap for repaint background
  648. DWORD bm_dx, bm_dy;
  649. DWORD mousepos;  // left-clicked point in monitor
  650. unsigned nowait; // don't close console window after error if started from GUI
  651. bool normal_exit = false; // true on correct exit, false on failure exit
  652.  
  653. char *ayvols[64]; unsigned num_ayvols;
  654. char *aystereo[64]; unsigned num_aystereo;
  655. char *ulapreset[64]; unsigned num_ula;
  656. static char presetbuf[0x4000];
  657. char *setptr = presetbuf;
  658.  
  659. /*
  660. #include "fontdata.cpp"
  661. #include "font8.cpp"
  662. #include "font14.cpp"
  663. #include "font16.cpp"
  664. #include "fontatm2.cpp"
  665. */
  666.  
  667. // ╧юЁ фюъ ёЄЁюъ т ¤Єюь ьрёёштх фюыцхэ ёююЄтхЄёЄтютрЄ№ enum AY_SCHEME
  668. const char * const ay_schemes[] =
  669. {
  670.     "no soundchip",
  671.     "fuller box",
  672.     "single chip",
  673.     "pseudo-turbo",
  674.     "quadro-AY",
  675.     "turbo-AY // POS",
  676.     "turbo-sound // NedoPC"
  677. };
  678.  
  679. int trdos_in_nmi = 0;
  680.