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 "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.             if(gspage == 0 || gspage == 1) // RAM0 or RAM1 in PG2
  359.                gsbankw[2] = TRASH_M;
  360.             if(ngs_mode_pg1 == 0 || ngs_mode_pg1 == 1) // RAM0 or RAM1 in PG3
  361.                gsbankw[3] = TRASH_M;
  362.         }
  363.     }
  364.     else
  365.     {
  366.         gsbankw[0] = gsbankw[2] = gsbankw[3] = TRASH_M;
  367.         gsbankr[0] = ROM_GS_M;                                  // ROM0
  368.         gsbankr[1] = gsbankw[1] = GSRAM_M + 3 * PAGE;           // RAM3
  369.         gsbankr[2] = ROM_GS_M +  (gspage & 0x1F) * PAGE;        // ROMn
  370.         gsbankr[3] = ROM_GS_M +  (ngs_mode_pg1 & 0x1F) * PAGE;  // ROMm
  371.     }
  372. }
  373.  
  374. void out(unsigned port, unsigned char val)
  375. {
  376. //   printf(__FUNCTION__" port=0x%X, val=0x%X\n", (port & 0xFF), val);
  377.    switch (port & 0xFF)
  378.    {
  379.       case MPAG:
  380.       {
  381.          bool ExtMem = (ngs_cfg0 & M_EXPAG) != 0;
  382.  
  383.          gspage = rol8(val, 1) & temp.gs_ram_mask & (ExtMem ? 0xFF : 0xFE);
  384.  
  385.          if(!ExtMem)
  386.              ngs_mode_pg1 = (rol8(val, 1) & temp.gs_ram_mask) | 1;
  387. //         printf(__FUNCTION__"->GSPG, %X, Ro=%d, NoRom=%d, Ext=%d\n", gspage, RamRo, NoRom, ExtMem);
  388.          UpdateMemMapping();
  389.          return;
  390.       }
  391.       case 0x02: gsstat &= 0x7F; return;
  392.       case 0x03: gsstat |= 0x80; gsdata_in = val; return;
  393.       case 0x05: gsstat &= 0xFE; return;
  394.  
  395.       case VOL1: case VOL2: case VOL3: case VOL4:
  396.       case VOL5: case VOL6: case VOL7: case VOL8:
  397.       {
  398.          if((port & 0x10) && !(ngs_cfg0 & (M_8CHANS | M_PAN4CH)))
  399.          {
  400.              return;
  401.          }
  402.  
  403.          val &= 0x3F;
  404.  
  405.          if(GsSilent && val == 0)
  406.          {
  407.              return;
  408.          }
  409.  
  410.          flush_gs_sound();
  411.          unsigned chan = ((port & 0x10) >> 2U) + (port & 0x0F)-6;
  412.          gsvol[chan] = val;
  413.  
  414.          auto Chans = (ngs_cfg0 & M_8CHANS) ? 8 : 4;
  415.  
  416.          auto Silent = true;
  417.          for(auto Ch = 0; Ch < Chans; Ch++)
  418.          {
  419.              if(gsvol[Ch] != 0)
  420.              {
  421.                  Silent = false;
  422.                  break;
  423.              }
  424.          }
  425.  
  426.          GsSilent = Silent;
  427.  
  428. //         gs_v[chan] = (gsbyte[chan] * gs_vfx[gsvol[chan]]) >> 8;
  429.          gs_v[chan] = unsigned(((signed char)(gsbyte[chan]-0x80) * (signed)gs_vfx[gsvol[chan]]) /vol_div + int(gs_vfx[33])); //!psb
  430.          return;
  431.       }
  432.       case 0x0A: gsstat = u8((gsstat & 0x7F) | (gspage << 7)); return;
  433.       case 0x0B: gsstat = u8((gsstat & 0xFE) | ((gsvol[0] >> 5) & 1)); return;
  434.  
  435.    }
  436.  
  437. //   printf(__FUNCTION__" port=0x%X, val=0x%X\n", (port & 0xFF), val);
  438.    // ngs
  439.    switch (port & 0xFF)
  440.    {
  441.       case GSCFG0:
  442.       {
  443.           ngs_cfg0 = val & 0x3F;
  444. //          printf(__FUNCTION__"->GSCFG0, %X, Ro=%d, NoRom=%d, Ext=%d\n", ngs_cfg0, RamRo, NoRom, ExtMem);
  445.  
  446.           if(ngs_cfg0 & M_8CHANS)
  447.           {
  448.               ngs_chn_mask = 0x7;
  449.               vol_div = 512;
  450.           }
  451.           else
  452.           {
  453.               ngs_chn_mask = 0x3;
  454.               vol_div = 256;
  455.           }
  456.           UpdateMemMapping();
  457.       }
  458.       break;
  459.  
  460.       case MPAGEX:
  461.       {
  462. //          assert((ngs_cfg0 & M_EXPAG) != 0);
  463.           ngs_mode_pg1 = rol8(val, 1) & temp.gs_ram_mask;
  464.           UpdateMemMapping();
  465.       }
  466.       break;
  467.  
  468.       case S_CTRL:
  469. //          printf(__FUNCTION__"->S_CTRL\n");
  470.           if(val & 0x80)
  471.               ngs_s_ctrl |= (val & 0xF);
  472.           else
  473.               ngs_s_ctrl &= ~(val & 0xF);
  474.  
  475.           if(!(ngs_s_ctrl & _MPXRS))
  476.               Vs1001.Reset();
  477.  
  478.           Vs1001.SetNcs((ngs_s_ctrl & _MPNCS) != false);
  479.       break;
  480.  
  481.       case MC_SEND:
  482.           Vs1001.WrCmd(val);
  483.       break;
  484.  
  485.       case MD_SEND:
  486.           Vs1001.Wr(val);
  487.       break;
  488.  
  489.       case SD_SEND:
  490.           SdCard.Wr(val);
  491.           SdRdValNew = SdCard.Rd();
  492.           SdDataAvail = true;
  493.       break;
  494.  
  495.       case DMA_MOD:
  496.           ngs_dmamod = val;
  497.       break;
  498.  
  499.       case DMA_HAD:
  500.           if (ngs_dmamod == 1)
  501.               temp.gsdmaaddr = (temp.gsdmaaddr&0x0000ffff)|(unsigned(val & 0x1F)<<16); // 5bit only
  502.       break;
  503.  
  504.       case DMA_MAD:
  505.           if (ngs_dmamod == 1)
  506.               temp.gsdmaaddr = (temp.gsdmaaddr&0x001f00ff)|(unsigned(val)<<8);
  507.       break;
  508.  
  509.       case DMA_LAD:
  510.           if (ngs_dmamod == 1)
  511.               temp.gsdmaaddr = (temp.gsdmaaddr&0x001fff00)|val;
  512.       break;
  513.  
  514.       case DMA_CST:
  515.           if (ngs_dmamod == 1)
  516.               temp.gsdmaon = val;
  517.       break;
  518.    }
  519. }
  520.  
  521. unsigned char in(unsigned port)
  522. {
  523.    switch (port & 0xFF)
  524.    {
  525.       case 0x01: return gscmd;
  526.       case 0x02: gsstat &= 0x7F; return gsdata_out;
  527.       case 0x03: gsstat |= 0x80; gsdata_in = 0xFF; return 0xFF;
  528.       case 0x04: return gsstat;
  529.       case 0x05: gsstat &= 0xFE; return 0xFF;
  530.       case 0x0A: gsstat = u8((gsstat & 0x7F) | (gspage << 7)); return 0xFF;
  531.       case 0x0B: gsstat = u8((gsstat & 0xFE) | (gsvol[0] >> 5)); return 0xFF;
  532.  
  533.  
  534.       // ngs
  535.       case GSCFG0:
  536.           return ngs_cfg0;
  537.       case S_CTRL:
  538.           return ngs_s_ctrl;
  539.  
  540.       case S_STAT:
  541.           if(Vs1001.GetDreq())
  542.               ngs_s_stat |= _MPDRQ;
  543.           else
  544.               ngs_s_stat &= ~_MPDRQ;
  545.           return ngs_s_stat;
  546.  
  547.       case MC_READ:
  548.           return Vs1001.Rd();
  549.  
  550.       case SD_READ:
  551.       {
  552.           u8 Tmp = SdRdVal;
  553.           SdRdVal = SdRdValNew;
  554.           return Tmp;
  555.       }
  556.       case SD_RSTR:
  557.           if(SdDataAvail)
  558.           {
  559.               SdDataAvail = false;
  560.               return SdRdValNew;
  561.           }
  562.           return SdCard.Rd();
  563.  
  564.       case DMA_MOD:
  565.           return ngs_dmamod;
  566.  
  567.       case DMA_HAD:
  568.           if (ngs_dmamod == 1)
  569.               return (temp.gsdmaaddr>>16) & 0x1F; // 5bit only
  570.       break;
  571.  
  572.       case DMA_MAD:
  573.           if (ngs_dmamod == 1)
  574.               return (temp.gsdmaaddr>>8) & 0xFF;
  575.       break;
  576.  
  577.       case DMA_LAD:
  578.           if (ngs_dmamod == 1)
  579.               return temp.gsdmaaddr & 0xFF;
  580.       break;
  581.  
  582.       case DMA_CST:
  583.           if (ngs_dmamod == 1)
  584.               return temp.gsdmaon;
  585.       break;
  586.    }
  587.    return 0xFF;
  588. }
  589.  
  590. //#include "z80/cmd.cpp"
  591.  
  592. static inline void stepi()
  593. {
  594.    u8 opcode = m1_cycle(&gscpu);
  595.    (::normal_opcode[opcode])(&gscpu);
  596. }
  597.  
  598. void Z80FAST step();
  599.  
  600. void Z80FAST step()
  601. {
  602.     stepi();
  603. }
  604.  
  605. void flush_gs_z80()
  606. {
  607.    if(gscpu.dbgchk)
  608.    {
  609.        gscpu.SetDbgMemIf();
  610.        z80gs::z80dbg::z80loop();
  611.    }
  612.    else
  613.    {
  614.        gscpu.SetFastMemIf();
  615.        z80gs::z80fast::z80loop();
  616.    }
  617. }
  618.  
  619. __int64 __cdecl delta()
  620. {
  621.     return i64(gs_t_states) + gscpu.t - gscpu.debug_last_t;
  622. }
  623.  
  624. void __cdecl SetLastT()
  625. {
  626.    gscpu.debug_last_t = i64(gs_t_states + gscpu.t);
  627. }
  628.  
  629. void nmi()
  630. {
  631.    gscpu.sp -= 2;
  632.    z80fast::wm(gscpu.sp, gscpu.pcl);
  633.    z80fast::wm(gscpu.sp+1, gscpu.pch);
  634.    gscpu.pc = 0x66;
  635.    gscpu.iff1 = gscpu.halted = 0;
  636. }
  637.  
  638. void reset()
  639. {
  640.    gscpu.reset();
  641.    gsbankr[0] = ROM_GS_M; gsbankr[1] = GSRAM_M + 3 * PAGE; gsbankr[2] = ROM_GS_M; gsbankr[3] = ROM_GS_M + PAGE;
  642.    gsbankw[0] = TRASH_M; gsbankw[1] = GSRAM_M + 3 * PAGE; gsbankw[2] = TRASH_M; gsbankw[3] = TRASH_M;
  643.  
  644.    gscpu.t = 0;
  645.    gs_t_states = 0;
  646.    gscpu_t_at_frame_start = 0;
  647.    ngs_cfg0 = 0;
  648.    ngs_s_stat = u8(u8(rdtsc() & ~7U) | _SDDET | _MPDRQ);
  649.    ngs_s_ctrl = u8(u8(rdtsc() & ~0xFU) | _SDNCS);
  650.    SdRdVal = SdRdValNew = 0xFF;
  651.    SdDataAvail = false;
  652.    Vs1001.Reset();
  653.  
  654.    for(unsigned i = 0; i < 8; i++)
  655.    {
  656.        gsbyte[i] = 0x80;
  657.        gsvol[i] = 0;
  658.        gs_v[i] = 0;
  659.    }
  660.  
  661.    ngs_mode_pg1 = 1;
  662.    ngs_dmamod = 0;
  663.    temp.gsdmaaddr = 0;
  664.    temp.gsdmaon = 0;
  665.    SdCard.Reset();
  666. }
  667.  
  668. } // end of z80gs namespace
  669. #endif
  670.