Subversion Repositories pentevo

Rev

Rev 1134 | 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 "gs.h"
  6. #include "gsz80.h"
  7. #include "vs1001.h"
  8. #include "sdcard.h"
  9. #include "debug.h"
  10.  
  11. #include "z80/op_noprefix.h"
  12.  
  13. #ifdef MOD_GSZ80
  14. namespace z80gs
  15. {
  16. unsigned __int64 gs_t_states; // inc'ed with GSCPUINT every gs int
  17. static unsigned __int64 gscpu_t_at_frame_start; // gs_t_states+gscpu.t when spectrum frame begins
  18.  
  19. Z80INLINE unsigned char rm(unsigned addr);
  20. u8 __fastcall dbgrm(u32 addr);
  21. Z80INLINE void wm(unsigned addr, unsigned char val);
  22. void __fastcall dbgwm(u32 addr, u8 val);
  23. Z80INLINE u8 *am_r(u32 addr);
  24. Z80INLINE unsigned char m1_cycle(Z80 *cpu);
  25. unsigned char in(unsigned port);
  26. void out(unsigned port, unsigned char val);
  27. // FIXME: Сделать переключаемый интерфейс в зависимости от флага gscpu.dbgchk
  28. namespace z80fast
  29. {
  30. Z80INLINE unsigned char xm(unsigned addr);
  31. Z80INLINE unsigned char rm(unsigned addr);
  32. Z80INLINE void wm(unsigned addr, unsigned char val);
  33. }
  34.  
  35. namespace z80dbg
  36. {
  37. Z80INLINE unsigned char xm(unsigned addr);
  38. Z80INLINE unsigned char rm(unsigned addr);
  39. Z80INLINE void wm(unsigned addr, unsigned char val);
  40. }
  41.  
  42. u8 __fastcall Xm(u32 addr)
  43. {
  44.     return z80gs::z80fast::xm(addr);
  45. }
  46.  
  47. u8 __fastcall Rm(u32 addr)
  48. {
  49.     return z80gs::z80fast::rm(addr);
  50. }
  51.  
  52. void __fastcall Wm(u32 addr, u8 val)
  53. {
  54.     z80gs::z80fast::wm(addr, val);
  55. }
  56.  
  57. u8 __fastcall DbgXm(u32 addr)
  58. {
  59.     return z80gs::z80dbg::xm(addr);
  60. }
  61.  
  62. u8 __fastcall DbgRm(u32 addr)
  63. {
  64.     return z80gs::z80dbg::rm(addr);
  65. }
  66.  
  67. void __fastcall DbgWm(u32 addr, u8 val)
  68. {
  69.     z80gs::z80dbg::wm(addr, val);
  70. }
  71. }
  72.  
  73. u8 *TGsZ80::DirectMem(unsigned addr) const
  74. {
  75.     return z80gs::am_r(addr);
  76. }
  77.  
  78. unsigned char TGsZ80::m1_cycle()
  79. {
  80.     return z80gs::m1_cycle(this);
  81. }
  82.  
  83. unsigned char TGsZ80::in(unsigned port)
  84. {
  85.     return z80gs::in(port);
  86. }
  87.  
  88. void TGsZ80::out(unsigned port, unsigned char val)
  89. {
  90.     z80gs::out(port, val);
  91. }
  92.  
  93. void TGsZ80::retn()
  94. {
  95.     nmi_in_progress = false;
  96. }
  97.  
  98. namespace z80gs
  99. {
  100. #include "z80/op_system.h"
  101.  
  102. const u8 MPAG   = 0x00;
  103. const u8 MPAGEX = 0x10;
  104.  
  105. // gs
  106. const u8 VOL1 = 0x06;
  107. const u8 VOL2 = 0x07;
  108. const u8 VOL3 = 0x08;
  109. const u8 VOL4 = 0x09;
  110.  
  111. // nsg
  112. const u8 VOL5 = 0x16;
  113. const u8 VOL6 = 0x17;
  114. const u8 VOL7 = 0x18;
  115. const u8 VOL8 = 0x19;
  116.  
  117. const u8 DMA_MOD= 0x1b;
  118. const u8 DMA_HAD= 0x1c;
  119. const u8 DMA_MAD= 0x1d;
  120. const u8 DMA_LAD= 0x1e;
  121. const u8 DMA_CST= 0x1f;
  122.  
  123. const u8 GSCFG0 = 0x0F;
  124.  
  125. const u8 M_NOROM = 1;
  126. const u8 M_RAMRO = 2;
  127. const u8 M_EXPAG = 8;
  128.  
  129. const u8 M_8CHANS = 0x04;
  130. const u8 M_PAN4CH = 0x40;
  131.  
  132. static u8 *gsbankr[4] = { ROM_GS_M, GSRAM_M + 3 * PAGE, ROM_GS_M, ROM_GS_M + PAGE }; // bank pointers for read
  133. static u8 *gsbankw[4] = { TRASH_M, GSRAM_M + 3 * PAGE, TRASH_M, TRASH_M }; // bank pointers for write
  134.  
  135. static unsigned gs_v[8];
  136. static unsigned char gsvol[8], gsbyte[8]{ 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80 };
  137. static unsigned char gsdata_in, gsdata_out, gspage = 0;
  138. static unsigned char gscmd, gsstat;
  139.  
  140. static bool GsSilent = false; // Признак нулевой громкости во всех каналах
  141.  
  142. static unsigned long long mult_gs, mult_gs2;
  143.  
  144. // ngs
  145. static u8 ngs_mode_pg1; // page ex number
  146. static u8 ngs_cfg0;
  147. static u8 ngs_s_ctrl;
  148. static u8 ngs_s_stat;
  149. static u8 SdRdVal, SdRdValNew;
  150. static u8 ngs_dmamod;
  151.  
  152. static u8 ngs_chn_mask = 3;
  153. static int vol_div = 256;
  154.  
  155. static bool SdDataAvail = false;
  156.  
  157. const unsigned GSINTFQ = 37500; // hz
  158. static unsigned GSCPUFQI;
  159. const unsigned GSCPUINT = GSCPUFQ/GSINTFQ;
  160. const int MULT_GS_SHIFT = 12; // cpu tick -> gscpu tick precision
  161. void flush_gs_z80();
  162. void reset();
  163. void nmi();
  164.  
  165. void apply_gs()
  166. {
  167.    GSCPUFQI = GSCPUFQ / conf.intfq;
  168.    mult_gs = (temp.snd_frame_ticks << MULT_C)/GSCPUFQI;
  169.    mult_gs2 = (GSCPUFQI<<MULT_GS_SHIFT)/conf.frame;
  170.  
  171.    make_gs_volume();
  172. }
  173.  
  174. static inline void flush_gs_sound()
  175. {
  176.    if (temp.sndblock)
  177.        return;
  178.  
  179.   unsigned l,r;         //!psb
  180.   l = gs_v[0] + gs_v[1];    //!psb
  181.   r = gs_v[2] + gs_v[3];    //!psb
  182.  
  183.   // ngs 8ch
  184.   if(ngs_cfg0 & M_8CHANS)
  185.   {
  186.       l += gs_v[4] + gs_v[5];
  187.       r += gs_v[6] + gs_v[7];
  188.   }
  189.  
  190.    unsigned lv, rv;
  191.    lv = (l + r/2) / 2;
  192.    rv = (r + l/2) / 2;
  193.  
  194. /*
  195.    if(gs_t_states < gscpu_t_at_frame_start)
  196.    {
  197.        printf("err: gs_t_states = %lld, gscpu_t_at_frame_start=%lld, gscpu.t = %u, t = %lld\n",
  198.            gs_t_states, gscpu_t_at_frame_start, gscpu.t, ((gs_t_states + gscpu.t)  - gscpu_t_at_frame_start));
  199.        fflush(stdout);
  200.    }
  201. */
  202.  
  203. //   assert(gs_t_states >= gscpu_t_at_frame_start);
  204.  
  205.    sound.update(unsigned((gs_t_states + gscpu.t) - gscpu_t_at_frame_start), lv, rv);     //!psb
  206. }
  207.  
  208. void init_gs_frame()
  209. {
  210. //   printf("%s, gs_t_states = %lld, gscpu.t = %u\n", __FUNCTION__, gs_t_states, gscpu.t);
  211.    assert(gscpu.t < LONG_MAX);
  212.    gscpu_t_at_frame_start = gs_t_states + gscpu.t;
  213.    sound.start_frame();
  214. }
  215.  
  216. void flush_gs_frame()
  217. {
  218.    flush_gs_z80();
  219.  
  220. /*   printf("%s, gs_t_states = %lld, gscpu_t_at_frame_start = %lld, gscpu.t = %u, t = %lld\n",
  221.        __FUNCTION__, gs_t_states, gscpu_t_at_frame_start, gscpu.t,
  222.        ((gs_t_states + gscpu.t)  - gscpu_t_at_frame_start));
  223. */
  224.    sound.end_frame(unsigned((gs_t_states + gscpu.t) - gscpu_t_at_frame_start));
  225.  
  226.    for(int ch = 0; ch < 8; ch++)
  227.    {
  228.        gsleds[ch].level = abs(int(gsbyte[ch] - 0x80) * gsvol[ch]) / ((128 * 63) / 15);
  229.        gsleds[ch].attrib = 0x0F;
  230.    }
  231. }
  232.  
  233. void out_gs(unsigned port, u8 val)
  234. {
  235.    port &= 0xFF;
  236.  
  237.    switch(port)
  238.    {
  239.    case 0x33: // GSCTR
  240.        if(val & 0x80) // reset
  241.        {
  242.            reset();
  243.            flush_gs_z80();
  244.            return;
  245.        }
  246.        if(val & 0x40) // nmi
  247.        {
  248.            nmi();
  249.            flush_gs_z80();
  250.            return;
  251.        }
  252.        return;
  253.    }
  254.  
  255.    flush_gs_z80();
  256.    switch(port)
  257.    {
  258.    case 0xB3: // GSDAT
  259.         gsdata_out = val;
  260.         gsstat |= 0x80;
  261.    break;
  262.    case 0xBB: // GSCOM
  263.        gscmd = val;
  264.        gsstat |= 0x01;
  265.    break;
  266.    }
  267. }
  268.  
  269. u8 in_gs(unsigned port)
  270. {
  271.    flush_gs_z80();
  272.    port &= 0xFF;
  273.    switch(port)
  274.    {
  275.    case 0xB3: gsstat &= 0x7F; return gsdata_in;
  276.    case 0xBB: return gsstat | 0x7E;
  277.    }
  278.    return 0xFF;
  279. }
  280.  
  281. static void gs_byte_to_dac(unsigned addr, unsigned char byte)
  282. {
  283.     if(GsSilent)
  284.     {
  285.         return;
  286.     }
  287.  
  288.    flush_gs_sound();
  289.    unsigned chan = (addr>>8) & ngs_chn_mask;
  290.    gsbyte[chan] = byte;
  291. //   gs_v[chan] = (gsbyte[chan] * gs_vfx[gsvol[chan]]) >> 8;
  292.    gs_v[chan] = unsigned(((signed char)(gsbyte[chan]-0x80) * (signed)gs_vfx[gsvol[chan]]) / vol_div + int(gs_vfx[33])); //!psb
  293. }
  294.  
  295. static inline void stepi();
  296.  
  297. Z80INLINE u8 *am_r(u32 addr)
  298. {
  299.    return &gsbankr[(addr >> 14U) & 3][addr & (PAGE-1)];
  300. }
  301.  
  302. namespace z80fast
  303. {
  304.    #include "gsz80.inl"
  305. }
  306. namespace z80dbg
  307. {
  308.    #define Z80_DBG
  309.    #include "gsz80.inl"
  310.    #undef Z80_DBG
  311. }
  312.  
  313. u8 *__fastcall MemDbg(u32 addr);
  314.  
  315. u8 *__fastcall MemDbg(u32 addr)
  316. {
  317.     return am_r(addr);
  318. }
  319.  
  320. u8 __fastcall dbgrm(u32 addr)
  321. {
  322.     return z80dbg::rm(addr);
  323. }
  324.  
  325. void __fastcall dbgwm(u32 addr, u8 val)
  326. {
  327.     *am_r(addr) = val;
  328. }
  329.  
  330. void __cdecl BankNames(int i, char *Name)
  331. {
  332.     if(gsbankr[i] < GSRAM_M + MAX_GSRAM_PAGES*PAGE)
  333.         sprintf(Name, "RAM%2lX", ULONG((gsbankr[i] - GSRAM_M) / PAGE));
  334.     if((gsbankr[i] - ROM_GS_M) < PAGE*MAX_GSROM_PAGES)
  335.         sprintf(Name, "ROM%2lX", ULONG((gsbankr[i] - ROM_GS_M) / PAGE));
  336. }
  337.  
  338.  
  339. Z80INLINE unsigned char m1_cycle(Z80 *cpu)
  340. {
  341.    cpu->r_low++; cpu->t += 4;
  342.    return cpu->MemIf->xm(cpu->pc++);
  343. }
  344.  
  345. static inline void UpdateMemMapping()
  346. {
  347.     bool RamRo = (ngs_cfg0 & M_RAMRO) != 0;
  348.     bool NoRom = (ngs_cfg0 & M_NOROM) != 0;
  349.     if(NoRom)
  350.     {
  351.         gsbankr[0] = gsbankw[0] = GSRAM_M;
  352.         gsbankr[1] = gsbankw[1] = GSRAM_M + 3 * PAGE;
  353.         gsbankr[2] = gsbankw[2] = GSRAM_M + gspage * PAGE;
  354.         gsbankr[3] = gsbankw[3] = GSRAM_M + ngs_mode_pg1 * PAGE;
  355.  
  356.         if(RamRo)
  357.         {
  358.             gsbankw[0] = TRASH_M;
  359.             if(gspage == 0 || gspage == 1) // RAM0 or RAM1 in PG2
  360.                gsbankw[2] = TRASH_M;
  361.             if(ngs_mode_pg1 == 0 || ngs_mode_pg1 == 1) // RAM0 or RAM1 in PG3
  362.                gsbankw[3] = TRASH_M;
  363.         }
  364.     }
  365.     else
  366.     {
  367.         gsbankw[0] = gsbankw[2] = gsbankw[3] = TRASH_M;
  368.         gsbankr[0] = ROM_GS_M;                                  // ROM0
  369.         gsbankr[1] = gsbankw[1] = GSRAM_M + 3 * PAGE;           // RAM3
  370.         gsbankr[2] = ROM_GS_M +  (gspage & 0x1F) * PAGE;        // ROMn
  371.         gsbankr[3] = ROM_GS_M +  (ngs_mode_pg1 & 0x1F) * PAGE;  // ROMm
  372.     }
  373. }
  374.  
  375. void out(unsigned port, unsigned char val)
  376. {
  377. //   printf(__FUNCTION__" port=0x%X, val=0x%X\n", (port & 0xFF), val);
  378.    switch (port & 0xFF)
  379.    {
  380.       case MPAG:
  381.       {
  382.          bool ExtMem = (ngs_cfg0 & M_EXPAG) != 0;
  383.  
  384.          gspage = rol8(val, 1) & temp.gs_ram_mask & (ExtMem ? 0xFF : 0xFE);
  385.  
  386.          if(!ExtMem)
  387.              ngs_mode_pg1 = (rol8(val, 1) & temp.gs_ram_mask) | 1;
  388. //         printf(__FUNCTION__"->GSPG, %X, Ro=%d, NoRom=%d, Ext=%d\n", gspage, RamRo, NoRom, ExtMem);
  389.          UpdateMemMapping();
  390.          return;
  391.       }
  392.       case 0x02: gsstat &= 0x7F; return;
  393.       case 0x03: gsstat |= 0x80; gsdata_in = val; return;
  394.       case 0x05: gsstat &= 0xFE; return;
  395.  
  396.       case VOL1: case VOL2: case VOL3: case VOL4:
  397.       case VOL5: case VOL6: case VOL7: case VOL8:
  398.       {
  399.          if((port & 0x10) && !(ngs_cfg0 & (M_8CHANS | M_PAN4CH)))
  400.          {
  401.              return;
  402.          }
  403.  
  404.          val &= 0x3F;
  405.  
  406.          if(GsSilent && val == 0)
  407.          {
  408.              return;
  409.          }
  410.  
  411.          flush_gs_sound();
  412.          unsigned chan = ((port & 0x10) >> 2U) + (port & 0x0F)-6;
  413.          gsvol[chan] = val;
  414.  
  415.          auto Chans = (ngs_cfg0 & M_8CHANS) ? 8 : 4;
  416.  
  417.          auto Silent = true;
  418.          for(auto Ch = 0; Ch < Chans; Ch++)
  419.          {
  420.              if(gsvol[Ch] != 0)
  421.              {
  422.                  Silent = false;
  423.                  break;
  424.              }
  425.          }
  426.  
  427.          GsSilent = Silent;
  428.  
  429. //         gs_v[chan] = (gsbyte[chan] * gs_vfx[gsvol[chan]]) >> 8;
  430.          gs_v[chan] = unsigned(((signed char)(gsbyte[chan]-0x80) * (signed)gs_vfx[gsvol[chan]]) /vol_div + int(gs_vfx[33])); //!psb
  431.          return;
  432.       }
  433.       case 0x0A: gsstat = u8((gsstat & 0x7F) | (gspage << 7)); return;
  434.       case 0x0B: gsstat = u8((gsstat & 0xFE) | ((gsvol[0] >> 5) & 1)); return;
  435.  
  436.    }
  437.  
  438. //   printf(__FUNCTION__" port=0x%X, val=0x%X\n", (port & 0xFF), val);
  439.    // ngs
  440.    switch (port & 0xFF)
  441.    {
  442.       case GSCFG0:
  443.       {
  444.           ngs_cfg0 = val & 0x3F;
  445. //          printf(__FUNCTION__"->GSCFG0, %X, Ro=%d, NoRom=%d, Ext=%d\n", ngs_cfg0, RamRo, NoRom, ExtMem);
  446.  
  447.           if(ngs_cfg0 & M_8CHANS)
  448.           {
  449.               ngs_chn_mask = 0x7;
  450.               vol_div = 512;
  451.           }
  452.           else
  453.           {
  454.               ngs_chn_mask = 0x3;
  455.               vol_div = 256;
  456.           }
  457.           UpdateMemMapping();
  458.       }
  459.       break;
  460.  
  461.       case MPAGEX:
  462.       {
  463. //          assert((ngs_cfg0 & M_EXPAG) != 0);
  464.           ngs_mode_pg1 = rol8(val, 1) & temp.gs_ram_mask;
  465.           UpdateMemMapping();
  466.       }
  467.       break;
  468.  
  469.       case S_CTRL:
  470. //          printf(__FUNCTION__"->S_CTRL\n");
  471.           if(val & 0x80)
  472.               ngs_s_ctrl |= (val & 0xF);
  473.           else
  474.               ngs_s_ctrl &= ~(val & 0xF);
  475.  
  476.           if(!(ngs_s_ctrl & _MPXRS))
  477.               Vs1001.Reset();
  478.  
  479.           Vs1001.SetNcs((ngs_s_ctrl & _MPNCS) != false);
  480.       break;
  481.  
  482.       case MC_SEND:
  483.           Vs1001.WrCmd(val);
  484.       break;
  485.  
  486.       case MD_SEND:
  487.           Vs1001.Wr(val);
  488.       break;
  489.  
  490.       case SD_SEND:
  491.           SdCard.Wr(val);
  492.           SdRdValNew = SdCard.Rd();
  493.           SdDataAvail = true;
  494.       break;
  495.  
  496.       case DMA_MOD:
  497.           ngs_dmamod = val;
  498.       break;
  499.  
  500.       case DMA_HAD:
  501.           if (ngs_dmamod == 1)
  502.               temp.gsdmaaddr = (temp.gsdmaaddr&0x0000ffff)|(unsigned(val & 0x1F)<<16); // 5bit only
  503.       break;
  504.  
  505.       case DMA_MAD:
  506.           if (ngs_dmamod == 1)
  507.               temp.gsdmaaddr = (temp.gsdmaaddr&0x001f00ff)|(unsigned(val)<<8);
  508.       break;
  509.  
  510.       case DMA_LAD:
  511.           if (ngs_dmamod == 1)
  512.               temp.gsdmaaddr = (temp.gsdmaaddr&0x001fff00)|val;
  513.       break;
  514.  
  515.       case DMA_CST:
  516.           if (ngs_dmamod == 1)
  517.               temp.gsdmaon = val;
  518.       break;
  519.    }
  520. }
  521.  
  522. unsigned char in(unsigned port)
  523. {
  524.    switch (port & 0xFF)
  525.    {
  526.       case 0x01: return gscmd;
  527.       case 0x02: gsstat &= 0x7F; return gsdata_out;
  528.       case 0x03: gsstat |= 0x80; gsdata_in = 0xFF; return 0xFF;
  529.       case 0x04: return gsstat;
  530.       case 0x05: gsstat &= 0xFE; return 0xFF;
  531.       case 0x0A: gsstat = u8((gsstat & 0x7F) | (gspage << 7)); return 0xFF;
  532.       case 0x0B: gsstat = u8((gsstat & 0xFE) | (gsvol[0] >> 5)); return 0xFF;
  533.  
  534.  
  535.       // ngs
  536.       case GSCFG0:
  537.           return ngs_cfg0;
  538.       case S_CTRL:
  539.           return ngs_s_ctrl;
  540.  
  541.       case S_STAT:
  542.           if(Vs1001.GetDreq())
  543.               ngs_s_stat |= _MPDRQ;
  544.           else
  545.               ngs_s_stat &= ~_MPDRQ;
  546.           return ngs_s_stat;
  547.  
  548.       case MC_READ:
  549.           return Vs1001.Rd();
  550.  
  551.       case SD_READ:
  552.       {
  553.           u8 Tmp = SdRdVal;
  554.           SdRdVal = SdRdValNew;
  555.           return Tmp;
  556.       }
  557.       case SD_RSTR:
  558.           if(SdDataAvail)
  559.           {
  560.               SdDataAvail = false;
  561.               return SdRdValNew;
  562.           }
  563.           return SdCard.Rd();
  564.  
  565.       case DMA_MOD:
  566.           return ngs_dmamod;
  567.  
  568.       case DMA_HAD:
  569.           if (ngs_dmamod == 1)
  570.               return (temp.gsdmaaddr>>16) & 0x1F; // 5bit only
  571.       break;
  572.  
  573.       case DMA_MAD:
  574.           if (ngs_dmamod == 1)
  575.               return (temp.gsdmaaddr>>8) & 0xFF;
  576.       break;
  577.  
  578.       case DMA_LAD:
  579.           if (ngs_dmamod == 1)
  580.               return temp.gsdmaaddr & 0xFF;
  581.       break;
  582.  
  583.       case DMA_CST:
  584.           if (ngs_dmamod == 1)
  585.               return temp.gsdmaon;
  586.       break;
  587.    }
  588.    return 0xFF;
  589. }
  590.  
  591. //#include "z80/cmd.cpp"
  592.  
  593. static inline void stepi()
  594. {
  595.    u8 opcode = m1_cycle(&gscpu);
  596.    (::normal_opcode[opcode])(&gscpu);
  597. }
  598.  
  599. void Z80FAST step();
  600.  
  601. void Z80FAST step()
  602. {
  603.     stepi();
  604. }
  605.  
  606. void flush_gs_z80()
  607. {
  608.    if(gscpu.dbgchk)
  609.    {
  610.        gscpu.SetDbgMemIf();
  611.        z80gs::z80dbg::z80loop();
  612.    }
  613.    else
  614.    {
  615.        gscpu.SetFastMemIf();
  616.        z80gs::z80fast::z80loop();
  617.    }
  618. }
  619.  
  620. __int64 __cdecl delta()
  621. {
  622.     return i64(gs_t_states) + gscpu.t - gscpu.debug_last_t;
  623. }
  624.  
  625. void __cdecl SetLastT()
  626. {
  627.    gscpu.debug_last_t = i64(gs_t_states + gscpu.t);
  628. }
  629.  
  630. void nmi()
  631. {
  632.    gscpu.sp -= 2;
  633.    z80fast::wm(gscpu.sp, gscpu.pcl);
  634.    z80fast::wm(gscpu.sp+1, gscpu.pch);
  635.    gscpu.pc = 0x66;
  636.    gscpu.iff1 = gscpu.halted = 0;
  637. }
  638.  
  639. void reset()
  640. {
  641.    gscpu.reset();
  642.    gsbankr[0] = ROM_GS_M; gsbankr[1] = GSRAM_M + 3 * PAGE; gsbankr[2] = ROM_GS_M; gsbankr[3] = ROM_GS_M + PAGE;
  643.    gsbankw[0] = TRASH_M; gsbankw[1] = GSRAM_M + 3 * PAGE; gsbankw[2] = TRASH_M; gsbankw[3] = TRASH_M;
  644.  
  645.    gscpu.t = 0;
  646.    gs_t_states = 0;
  647.    gscpu_t_at_frame_start = 0;
  648.    ngs_cfg0 = 0;
  649.    ngs_s_stat = u8(u8(rdtsc() & ~7U) | _SDDET | _MPDRQ);
  650.    ngs_s_ctrl = u8(u8(rdtsc() & ~0xFU) | _SDNCS);
  651.    SdRdVal = SdRdValNew = 0xFF;
  652.    SdDataAvail = false;
  653.    Vs1001.Reset();
  654.  
  655.    for(unsigned i = 0; i < 8; i++)
  656.    {
  657.        gsbyte[i] = 0x80;
  658.        gsvol[i] = 0;
  659.        gs_v[i] = 0;
  660.    }
  661.  
  662.    ngs_mode_pg1 = 1;
  663.    ngs_dmamod = 0;
  664.    temp.gsdmaaddr = 0;
  665.    temp.gsdmaon = 0;
  666.    SdCard.Reset();
  667. }
  668.  
  669. } // end of z80gs namespace
  670. #endif
  671.