Subversion Repositories pentevo

Rev

Blame | 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. //=============================================================================
  14.  
  15. #ifdef MOD_GSZ80
  16.  
  17. //=============================================================================
  18. namespace z80gs
  19. {
  20.     unsigned __int64 gs_t_states;                       // inc'ed with GSCPUINT every gs int
  21.     static unsigned __int64 gscpu_t_at_frame_start;     // gs_t_states+gscpu.t when spectrum frame begins
  22.  
  23.     Z80INLINE unsigned char rm(unsigned addr);
  24.     u8 __fastcall dbgrm(u32 addr);
  25.     Z80INLINE void      wm(     unsigned addr,
  26.                                 unsigned char val
  27.                            );
  28.     void __fastcall     dbgwm(  u32 addr,
  29.                                 u8 val
  30.                               );
  31.     Z80INLINE u8 *am_r(u32 addr);
  32.     Z80INLINE unsigned char m1_cycle(Z80 *cpu);
  33.     unsigned char in(unsigned port);
  34.     void        out(    unsigned port,
  35.                         unsigned char val
  36.                     );
  37.                    
  38. // FIXME: ╤фхырЄ№ яхЁхъы■ўрхь√щ шэЄхЁЇхщё т чртшёшьюёЄш юЄ Їырур gscpu.dbgchk
  39. //      ю ўхь, сыфцф, Ёхў№ ???? ю_╬
  40.     //-------------------------------------------------------------------------
  41.     namespace z80fast
  42.     {
  43.         Z80INLINE unsigned char xm(unsigned addr);
  44.         Z80INLINE unsigned char rm(unsigned addr);
  45.         Z80INLINE void  wm(     unsigned addr,
  46.                                 unsigned char val
  47.                            );
  48.     }
  49.     //-------------------------------------------------------------------------
  50.     namespace z80dbg
  51.     {
  52.         Z80INLINE unsigned char xm(unsigned addr);
  53.         Z80INLINE unsigned char rm(unsigned addr);
  54.         Z80INLINE void  wm(     unsigned addr,
  55.                                 unsigned char val
  56.                            );
  57.     }
  58.     //-------------------------------------------------------------------------
  59.     u8 __fastcall Xm(u32 addr)
  60.     {
  61.         return z80gs::z80fast::xm(addr);
  62.     }
  63.     //-------------------------------------------------------------------------
  64.     u8 __fastcall Rm(u32 addr)
  65.     {
  66.         return z80gs::z80fast::rm(addr);
  67.     }
  68.     //-------------------------------------------------------------------------
  69.     void __fastcall Wm(u32 addr, u8 val)
  70.     {
  71.         z80gs::z80fast::wm(     addr,
  72.                                 val
  73.                            );
  74.     }
  75.     //-------------------------------------------------------------------------
  76.     u8 __fastcall DbgXm(u32 addr)
  77.     {
  78.         return z80gs::z80dbg::xm(addr);
  79.     }
  80.     //-------------------------------------------------------------------------
  81.     u8 __fastcall DbgRm(u32 addr)
  82.     {
  83.         return z80gs::z80dbg::rm(addr);
  84.     }
  85.     //-------------------------------------------------------------------------
  86.     void __fastcall DbgWm(u32 addr, u8 val)
  87.     {
  88.         z80gs::z80dbg::wm(      addr,
  89.                                 val
  90.                           );
  91.     }
  92.     //-------------------------------------------------------------------------
  93. }
  94. //=============================================================================
  95.  
  96.  
  97.  
  98. //=============================================================================
  99. u8 *TGsZ80::DirectMem(unsigned addr) const
  100. {
  101.     return z80gs::am_r(addr);
  102. }
  103. //=============================================================================
  104. unsigned char TGsZ80::m1_cycle()
  105. {
  106.     return z80gs::m1_cycle(this);
  107. }
  108. //=============================================================================
  109. unsigned char TGsZ80::in(unsigned port)
  110. {
  111.     return z80gs::in(port);
  112. }
  113. //=============================================================================
  114. void TGsZ80::out(unsigned port, unsigned char val)
  115. {
  116.     z80gs::out(port, val);
  117. }
  118. //=============================================================================
  119. void TGsZ80::retn()
  120. {
  121.     nmi_in_progress = false;
  122. }
  123. //=============================================================================
  124.  
  125.  
  126. //=============================================================================
  127. namespace z80gs
  128. {
  129.  
  130. #include "z80/op_system.h"
  131.  
  132. const u8 MPAG   = 0x00;
  133. const u8 MPAGEX = 0x10;
  134.  
  135. // gs
  136. const u8 VOL1 = 0x06;
  137. const u8 VOL2 = 0x07;
  138. const u8 VOL3 = 0x08;
  139. const u8 VOL4 = 0x09;
  140.  
  141. // nsg
  142. const u8 VOL5 = 0x16;
  143. const u8 VOL6 = 0x17;
  144. const u8 VOL7 = 0x18;
  145. const u8 VOL8 = 0x19;
  146.  
  147. const u8 DMA_MOD = 0x1B;
  148. const u8 DMA_HAD = 0x1C;
  149. const u8 DMA_MAD = 0x1D;
  150. const u8 DMA_LAD = 0x1E;
  151. const u8 DMA_CST = 0x1F;
  152.  
  153. const u8 GSCFG0 = 0x0F;
  154.  
  155. const u8 M_NOROM = 1;
  156. const u8 M_RAMRO = 2;
  157. const u8 M_EXPAG = 8;
  158.  
  159. const u8 M_8CHANS = 0x04;
  160. const u8 M_PAN4CH = 0x40;
  161.  
  162. static u8 *gsbankr[4] = {       ROM_GS_M,
  163.                                 GSRAM_M + 3 * PAGE,
  164.                                 ROM_GS_M,
  165.                                 ROM_GS_M + PAGE
  166.                          };     // bank pointers for read
  167.                          
  168. static u8 *gsbankw[4] = {       TRASH_M,
  169.                                 GSRAM_M + 3 * PAGE,
  170.                                 TRASH_M,
  171.                                 TRASH_M
  172.                          };     // bank pointers for write
  173.  
  174. static unsigned gs_v[8];
  175.  
  176. static unsigned char gsvol[8], gsbyte[8]{       0x80,
  177.                                                 0x80,
  178.                                                 0x80,
  179.                                                 0x80,
  180.                                                 0x80,
  181.                                                 0x80,
  182.                                                 0x80,
  183.                                                 0x80
  184.                                          };
  185.                                          
  186. static unsigned char gsdata_in, gsdata_out, gspage = 0;
  187. static unsigned char gscmd, gsstat;
  188.  
  189. static bool GsSilent = false;   // ╧Ёшчэръ эєыхтющ уЁюьъюёЄш тю тёхї ърэрырї
  190.  
  191. static unsigned long long mult_gs, mult_gs2;
  192.  
  193. // ngs
  194. static u8 ngs_mode_pg1;         // page ex number
  195. static u8 ngs_cfg0;
  196. static u8 ngs_s_ctrl;
  197. static u8 ngs_s_stat;
  198. static u8 SdRdVal, SdRdValNew;
  199. static u8 ngs_dmamod;
  200.  
  201. static u8 ngs_chn_mask = 3;
  202. static int vol_div = 256;
  203.  
  204. static bool SdDataAvail = false;
  205.  
  206.  
  207.  
  208. // эхъюЄюЁ√х юс· тыхэ√ т gsz80.h
  209.  
  210. const unsigned GSINTFQ = 37500;                 // Hz
  211. static unsigned GSCPUFQI;                       // 489795 = 24000000 / 49
  212. const unsigned GSCPUINT = GSCPUFQ/GSINTFQ;      // 640 = 24000000 / 37500
  213. const int MULT_GS_SHIFT = 12;                   // cpu tick -> gscpu tick precision
  214.                                                 // яюўхьє 12 ????????
  215. void flush_gs_z80();
  216. void reset();
  217. void nmi();
  218.  
  219. //-----------------------------------------------------------------------------
  220. void apply_gs()
  221. {
  222.     GSCPUFQI = GSCPUFQ / conf.intfq;
  223.     mult_gs = (temp.snd_frame_ticks << MULT_C) / GSCPUFQI;
  224.     mult_gs2 = (GSCPUFQI<<MULT_GS_SHIFT) / conf.frame;
  225.  
  226.     make_gs_volume();
  227. }
  228. //-----------------------------------------------------------------------------
  229.  
  230.  
  231. //-----------------------------------------------------------------------------
  232. static inline void flush_gs_sound()
  233. {
  234.     if (temp.sndblock)
  235.         return;
  236.  
  237.     unsigned l,r;               //!psb
  238.     l = gs_v[0] + gs_v[1];      //!psb
  239.     r = gs_v[2] + gs_v[3];      //!psb
  240.  
  241.     // ngs 8ch
  242.     if(ngs_cfg0 & M_8CHANS)
  243.     {
  244.         l += gs_v[4] + gs_v[5];
  245.         r += gs_v[6] + gs_v[7];
  246.     }
  247.  
  248.     unsigned lv, rv;
  249.     lv = (l + r/2) / 2;
  250.     rv = (r + l/2) / 2;
  251.  
  252. /*
  253.     if (gs_t_states < gscpu_t_at_frame_start)
  254.     {
  255.         printf("err: gs_t_states = %lld, gscpu_t_at_frame_start=%lld, gscpu.t = %u, t = %lld\n",
  256.             gs_t_states, gscpu_t_at_frame_start, gscpu.t, ((gs_t_states + gscpu.t)  - gscpu_t_at_frame_start));
  257.         fflush(stdout);
  258.     }
  259. */
  260.  
  261. //   assert(gs_t_states >= gscpu_t_at_frame_start);
  262.  
  263.    sound.update( unsigned(      (gs_t_states + gscpu.t) - gscpu_t_at_frame_start),
  264.                                 lv,
  265.                                 rv
  266.                 );     //!psb
  267. }
  268. //-----------------------------------------------------------------------------
  269.  
  270.  
  271. //-----------------------------------------------------------------------------
  272. void init_gs_frame()
  273. {
  274. //   printf("%s, gs_t_states = %lld, gscpu.t = %u\n", __FUNCTION__, gs_t_states, gscpu.t);
  275.     assert(gscpu.t < LONG_MAX);
  276.     gscpu_t_at_frame_start = gs_t_states + gscpu.t;
  277.     sound.start_frame();
  278. }
  279. //-----------------------------------------------------------------------------
  280.  
  281.  
  282. //-----------------------------------------------------------------------------
  283. void flush_gs_frame()
  284. {
  285.     flush_gs_z80();
  286.  
  287. /*   printf("%s, gs_t_states = %lld, gscpu_t_at_frame_start = %lld, gscpu.t = %u, t = %lld\n",
  288.        __FUNCTION__, gs_t_states, gscpu_t_at_frame_start, gscpu.t,
  289.        ((gs_t_states + gscpu.t)  - gscpu_t_at_frame_start));
  290. */
  291.     sound.end_frame(unsigned((gs_t_states + gscpu.t) - gscpu_t_at_frame_start));
  292.  
  293.     for(int ch = 0; ch < 8; ch++)
  294.     {
  295.         gsleds[ch].level = abs(int(gsbyte[ch] - 0x80) * gsvol[ch]) / ((128 * 63) / 15);
  296.         gsleds[ch].attrib = 0x0F;
  297.     }
  298. }
  299. //-----------------------------------------------------------------------------
  300.  
  301.  
  302. //-----------------------------------------------------------------------------
  303. void out_gs( unsigned port, u8 val )
  304. {
  305.     port &= 0xFF;
  306.  
  307.     switch (port)
  308.     {
  309.     case 0x33:                  // GSCTR
  310.         if (val & 0x80)         // reset
  311.         {
  312.             reset();
  313.             flush_gs_z80();
  314.             return;
  315.         }
  316.         if(val & 0x40)          // nmi
  317.         {
  318.             nmi();
  319.             flush_gs_z80();
  320.             return;
  321.         }
  322.         return;
  323.     }
  324.  
  325.     flush_gs_z80();
  326.    
  327.     switch (port)
  328.     {
  329.     case 0xB3:                  // GSDAT
  330.         gsdata_out = val;
  331.         gsstat |= 0x80;
  332.     break;
  333.     case 0xBB:                  // GSCOM
  334.         gscmd = val;
  335.         gsstat |= 0x01;
  336.     break;
  337.     }
  338. }
  339. //-----------------------------------------------------------------------------
  340.  
  341.  
  342. //-----------------------------------------------------------------------------
  343. u8 in_gs(unsigned port)
  344. {
  345.     flush_gs_z80();
  346.     port &= 0xFF;
  347.     switch(port)
  348.     {
  349.     case 0xB3:
  350.         gsstat &= 0x7F;
  351.         return gsdata_in;
  352.     case 0xBB:
  353.         return gsstat | 0x7E;
  354.     }
  355.     return 0xFF;
  356. }
  357. //-----------------------------------------------------------------------------
  358.  
  359.  
  360. //-----------------------------------------------------------------------------
  361. static void gs_byte_to_dac( unsigned addr, unsigned char byte )
  362. {
  363.     if(GsSilent)
  364.     {
  365.         return;
  366.     }
  367.  
  368.     flush_gs_sound();
  369.     unsigned chan = (addr >> 8) & ngs_chn_mask;
  370.     gsbyte[chan] = byte;
  371. //   gs_v[chan] = (gsbyte[chan] * gs_vfx[gsvol[chan]]) >> 8;
  372.     gs_v[chan] = unsigned(      ( (signed char) (gsbyte[chan]-0x80) * (signed)gs_vfx[gsvol[chan]] )
  373.                                 /
  374.                                 vol_div
  375.                                 +
  376.                                 int(gs_vfx[33])
  377.                           ); //!psb
  378. }
  379. //-----------------------------------------------------------------------------
  380.  
  381.  
  382. //-----------------------------------------------------------------------------
  383. static inline void stepi();
  384. //-----------------------------------------------------------------------------
  385.  
  386.  
  387. //-----------------------------------------------------------------------------
  388. Z80INLINE u8 *am_r(u32 addr)
  389. {
  390.     return &gsbankr[(addr >> 14U) & 3][addr & (PAGE-1)];
  391. }
  392. //-----------------------------------------------------------------------------
  393.  
  394.  
  395. //-----------------------------------------------------------------------------
  396. namespace z80fast
  397. {
  398.     #include "gsz80.inl"
  399. }
  400. //-----------------------------------------------------------------------------
  401.  
  402.  
  403. //-----------------------------------------------------------------------------
  404. namespace z80dbg
  405. {
  406.     #define Z80_DBG
  407.     #include "gsz80.inl"
  408.     #undef Z80_DBG
  409. }
  410. //-----------------------------------------------------------------------------
  411.  
  412.  
  413. //-----------------------------------------------------------------------------
  414. u8 *__fastcall MemDbg(u32 addr);
  415. //-----------------------------------------------------------------------------
  416. u8 *__fastcall MemDbg(u32 addr)
  417. {
  418.     return am_r(addr);
  419. }
  420. //-----------------------------------------------------------------------------
  421. u8 __fastcall dbgrm(u32 addr)
  422. {
  423.     return z80dbg::rm(addr);
  424. }
  425. //-----------------------------------------------------------------------------
  426. void __fastcall dbgwm(u32 addr, u8 val)
  427. {
  428.     *am_r(addr) = val;
  429. }
  430. //-----------------------------------------------------------------------------
  431.  
  432.  
  433. //-----------------------------------------------------------------------------
  434. void __cdecl BankNames(int i, char *Name)
  435. {
  436.     if ( gsbankr[i] < GSRAM_M + MAX_GSRAM_PAGES * PAGE )
  437.         sprintf(        Name,
  438.                         "RAM%2lX",
  439.                         ULONG((gsbankr[i] - GSRAM_M) / PAGE)
  440.                 );
  441.                
  442.     if ( (gsbankr[i] - ROM_GS_M) < PAGE * MAX_GSROM_PAGES )
  443.         sprintf(        Name,
  444.                         "ROM%2lX",
  445.                         ULONG((gsbankr[i] - ROM_GS_M) / PAGE)
  446.                 );
  447. }
  448. //-----------------------------------------------------------------------------
  449.  
  450.  
  451. //-----------------------------------------------------------------------------
  452. Z80INLINE unsigned char m1_cycle(Z80 *cpu)
  453. {
  454.     cpu->r_low++; cpu->t += 4;
  455.     return cpu->MemIf->xm(cpu->pc++);
  456. }
  457. //-----------------------------------------------------------------------------
  458.  
  459.  
  460. //-----------------------------------------------------------------------------
  461. static inline void UpdateMemMapping()
  462. {
  463.     bool RamRo = (ngs_cfg0 & M_RAMRO) != 0;
  464.     bool NoRom = (ngs_cfg0 & M_NOROM) != 0;
  465.    
  466.     if (NoRom)
  467.     {
  468.         gsbankr[0] = gsbankw[0] = GSRAM_M;
  469.         gsbankr[1] = gsbankw[1] = GSRAM_M + 3 * PAGE;
  470.         gsbankr[2] = gsbankw[2] = GSRAM_M + gspage * PAGE;
  471.         gsbankr[3] = gsbankw[3] = GSRAM_M + ngs_mode_pg1 * PAGE;
  472.  
  473.         if (RamRo)
  474.         {
  475.             if ( gspage == 0 || gspage == 1 )                   // RAM0 or RAM1 in PG2
  476.                 gsbankw[2] = TRASH_M;
  477.                
  478.             if ( ngs_mode_pg1 == 0 || ngs_mode_pg1 == 1 )       // RAM0 or RAM1 in PG3
  479.                 gsbankw[3] = TRASH_M;
  480.         }
  481.     }
  482.     else
  483.     {
  484.         gsbankw[0] = gsbankw[2] = gsbankw[3] = TRASH_M;
  485.         gsbankr[0] = ROM_GS_M;                                  // ROM0
  486.         gsbankr[1] = gsbankw[1] = GSRAM_M + 3 * PAGE;           // RAM3
  487.         gsbankr[2] = ROM_GS_M +  (gspage & 0x1F) * PAGE;        // ROMn
  488.         gsbankr[3] = ROM_GS_M +  (ngs_mode_pg1 & 0x1F) * PAGE;  // ROMm
  489.     }
  490. }
  491. //-----------------------------------------------------------------------------
  492.  
  493.  
  494. //-----------------------------------------------------------------------------
  495. void out( unsigned port, unsigned char val )
  496. {
  497. //   printf(__FUNCTION__" port=0x%X, val=0x%X\n", (port & 0xFF), val);
  498.  
  499.     //-------------------------------------------------------------------------
  500.     switch (port & 0xFF)
  501.     {
  502.         //---------------------------------------------------------------------
  503.         case MPAG:
  504.         {
  505.             bool ExtMem = (ngs_cfg0 & M_EXPAG) != 0;
  506.  
  507.             gspage =    rol8(val, 1)
  508.                         &
  509.                         temp.gs_ram_mask
  510.                         &
  511.                         ( ExtMem    ?   0xFF :
  512.                                         0xFE );
  513.                                        
  514.             if (!ExtMem)
  515.                 ngs_mode_pg1 = ( rol8(val, 1)   &   temp.gs_ram_mask ) | 1;
  516.                
  517. //         printf(__FUNCTION__"->GSPG, %X, Ro=%d, NoRom=%d, Ext=%d\n", gspage, RamRo, NoRom, ExtMem);
  518.             UpdateMemMapping();
  519.             return;
  520.         }
  521.         //---------------------------------------------------------------------
  522.         case 0x02:
  523.             gsstat &= 0x7F;
  524.             return;
  525.         //---------------------------------------------------------------------
  526.         case 0x03:
  527.             gsstat |= 0x80;
  528.             gsdata_in = val;
  529.             return;
  530.         //---------------------------------------------------------------------
  531.         case 0x05:
  532.             gsstat &= 0xFE;
  533.             return;
  534.         //---------------------------------------------------------------------
  535.         case VOL1:
  536.         case VOL2:
  537.         case VOL3:
  538.         case VOL4:
  539.         case VOL5:
  540.         case VOL6:
  541.         case VOL7:
  542.         case VOL8:
  543.         {
  544.             if (    (port & 0x10)
  545.                         &&
  546.                     !( ngs_cfg0 & (M_8CHANS | M_PAN4CH) )
  547.               )
  548.             {
  549.                 return;
  550.             }
  551.  
  552.             val &= 0x3F;
  553.  
  554.             if(GsSilent && val == 0)
  555.             {
  556.                 return;
  557.             }
  558.  
  559.             flush_gs_sound();
  560.            
  561.             unsigned chan = ( (port & 0x10) >> 2U ) + (port & 0x0F) - 6;
  562.             gsvol[chan] = val;
  563.  
  564.             auto Chans = (ngs_cfg0 & M_8CHANS) ? 8 : 4;
  565.  
  566.             auto Silent = true;
  567.            
  568.             for (auto Ch = 0; Ch < Chans; Ch++)
  569.             {
  570.                 if (gsvol[Ch] != 0)
  571.                 {
  572.                     Silent = false;
  573.                     break;
  574.                 }
  575.             }
  576.  
  577.             GsSilent = Silent;
  578.  
  579. //          gs_v[chan] = (gsbyte[chan] * gs_vfx[gsvol[chan]]) >> 8;
  580.             gs_v[chan] = unsigned(      ((signed char) (gsbyte[chan]-0x80) * (signed)gs_vfx[gsvol[chan]])
  581.                                         /
  582.                                         vol_div + int(gs_vfx[33])
  583.                                   ); //!psb
  584.             return;
  585.         } //case VOL1...VOL8:
  586.         //---------------------------------------------------------------------
  587.         case 0x0A:
  588.             gsstat = u8((gsstat & 0x7F) | (gspage << 7));
  589.             return;
  590.         //---------------------------------------------------------------------
  591.         case 0x0B:
  592.             gsstat = u8((gsstat & 0xFE) | ((gsvol[0] >> 5) & 1));
  593.             return;
  594.         //---------------------------------------------------------------------
  595.     }
  596.     //-------------------------------------------------------------------------
  597.  
  598. //   printf(__FUNCTION__" port=0x%X, val=0x%X\n", (port & 0xFF), val);
  599.  
  600.     //-------------------------------------------------------------------------
  601.     // ngs
  602.     switch (port & 0xFF)
  603.     {
  604.         //---------------------------------------------------------------------
  605.         case GSCFG0:
  606.         {
  607.             ngs_cfg0 = val & 0x3F;
  608. //          printf(__FUNCTION__"->GSCFG0, %X, Ro=%d, NoRom=%d, Ext=%d\n", ngs_cfg0, RamRo, NoRom, ExtMem);
  609.  
  610.             if (ngs_cfg0 & M_8CHANS)
  611.             {
  612.                 ngs_chn_mask = 0x7;
  613.                 vol_div = 512;
  614.             }
  615.             else
  616.             {
  617.                 ngs_chn_mask = 0x3;
  618.                 vol_div = 256;
  619.             }
  620.             UpdateMemMapping();
  621.         }
  622.         break;
  623.         //---------------------------------------------------------------------
  624.         case MPAGEX:
  625.         {
  626. //          assert((ngs_cfg0 & M_EXPAG) != 0);
  627.             ngs_mode_pg1 = rol8(val, 1) & temp.gs_ram_mask;
  628.             UpdateMemMapping();
  629.         }
  630.         break;
  631.         //---------------------------------------------------------------------
  632.         case S_CTRL:
  633. //          printf(__FUNCTION__"->S_CTRL\n");
  634.             if (val & 0x80)
  635.                 ngs_s_ctrl |= (val & 0xF);
  636.             else
  637.                 ngs_s_ctrl &= ~(val & 0xF);
  638.  
  639.             if ( !(ngs_s_ctrl & _MPXRS) )
  640.                 Vs1001.Reset();
  641.  
  642.             Vs1001.SetNcs((ngs_s_ctrl & _MPNCS) != false);
  643.             break;
  644.         //---------------------------------------------------------------------
  645.         case MC_SEND:
  646.             Vs1001.WrCmd(val);
  647.             break;
  648.         //---------------------------------------------------------------------
  649.         case MD_SEND:
  650.             Vs1001.Wr(val);
  651.             break;
  652.         //---------------------------------------------------------------------
  653.         case SD_SEND:
  654.             SdCard.Wr(val);
  655.             SdRdValNew = SdCard.Rd();
  656.             SdDataAvail = true;
  657.             break;
  658.         //---------------------------------------------------------------------
  659.         case DMA_MOD:
  660.             ngs_dmamod = val;
  661.             break;
  662.         //---------------------------------------------------------------------
  663.         case DMA_HAD:
  664.             if (ngs_dmamod == 1)
  665.                 temp.gsdmaaddr = (temp.gsdmaaddr & 0x0000ffff) | (unsigned(val & 0x1F) << 16); // 5bit only
  666.             break;
  667.         //---------------------------------------------------------------------
  668.         case DMA_MAD:   //!!! ёЄЁрээ√х ьрёъш !!!???
  669.             if (ngs_dmamod == 1)
  670.                 temp.gsdmaaddr = (temp.gsdmaaddr & 0x001f00ff) | (unsigned(val) << 8);
  671.             break;
  672.         //---------------------------------------------------------------------
  673.         case DMA_LAD:   //!!! ёЄЁрээ√х ьрёъш !!!???
  674.             if (ngs_dmamod == 1)
  675.                 temp.gsdmaaddr = (temp.gsdmaaddr & 0x001fff00) | val;
  676.             break;
  677.         //---------------------------------------------------------------------
  678.         case DMA_CST:
  679.             if (ngs_dmamod == 1)
  680.                 temp.gsdmaon = val;
  681.             break;
  682.         //---------------------------------------------------------------------
  683.     }
  684.     //-------------------------------------------------------------------------
  685. }
  686. //-----------------------------------------------------------------------------
  687.  
  688.  
  689. //-----------------------------------------------------------------------------
  690. unsigned char in(unsigned port)
  691. {
  692.     //-------------------------------------------------------------------------
  693.     switch (port & 0xFF)
  694.     {
  695.         //---------------------------------------------------------------------
  696.         case 0x01:
  697.             return gscmd;
  698.         //---------------------------------------------------------------------
  699.         case 0x02:
  700.             gsstat &= 0x7F;
  701.             return gsdata_out;
  702.         //---------------------------------------------------------------------
  703.         case 0x03:
  704.             gsstat |= 0x80;
  705.             gsdata_in = 0xFF;
  706.             return 0xFF;
  707.         //---------------------------------------------------------------------
  708.         case 0x04:
  709.             return gsstat;
  710.         //---------------------------------------------------------------------
  711.         case 0x05:
  712.             gsstat &= 0xFE;
  713.             return 0xFF;
  714.         //---------------------------------------------------------------------
  715.         case 0x0A:
  716.             gsstat = u8( (gsstat & 0x7F) | (gspage << 7) );
  717.             return 0xFF;
  718.         //---------------------------------------------------------------------
  719.         case 0x0B:
  720.             gsstat = u8( (gsstat & 0xFE) | (gsvol[0] >> 5) );
  721.             return 0xFF;
  722.         //---------------------------------------------------------------------
  723.         // ngs
  724.         //---------------------------------------------------------------------
  725.         case GSCFG0:
  726.             return ngs_cfg0;
  727.         //---------------------------------------------------------------------
  728.         case S_CTRL:
  729.             return ngs_s_ctrl;
  730.         //---------------------------------------------------------------------
  731.         case S_STAT:
  732.             if (Vs1001.GetDreq())
  733.                 ngs_s_stat |= _MPDRQ;
  734.             else
  735.                 ngs_s_stat &= ~_MPDRQ;
  736.             return ngs_s_stat;
  737.         //---------------------------------------------------------------------
  738.         case MC_READ:
  739.             return Vs1001.Rd();
  740.         //---------------------------------------------------------------------
  741.         case SD_READ:
  742.         {
  743.             u8 Tmp = SdRdVal;
  744.             SdRdVal = SdRdValNew;
  745.             return Tmp;
  746.         }
  747.         //---------------------------------------------------------------------
  748.         case SD_RSTR:
  749.             if (SdDataAvail)
  750.             {
  751.                 SdDataAvail = false;
  752.                 return SdRdValNew;
  753.             }
  754.             return SdCard.Rd();
  755.         //---------------------------------------------------------------------
  756.         case DMA_MOD:
  757.             return ngs_dmamod;
  758.         //---------------------------------------------------------------------
  759.         case DMA_HAD:
  760.             if (ngs_dmamod == 1)
  761.                 return (temp.gsdmaaddr>>16) & 0x1F;     // 5bit only
  762.             break;
  763.         //---------------------------------------------------------------------
  764.         case DMA_MAD:
  765.             if (ngs_dmamod == 1)
  766.                 return (temp.gsdmaaddr>>8) & 0xFF;
  767.             break;
  768.         //---------------------------------------------------------------------
  769.         case DMA_LAD:
  770.             if (ngs_dmamod == 1)
  771.                 return temp.gsdmaaddr & 0xFF;
  772.             break;
  773.         //---------------------------------------------------------------------
  774.         case DMA_CST:
  775.             if (ngs_dmamod == 1)
  776.                 return temp.gsdmaon;
  777.             break;
  778.         //---------------------------------------------------------------------    
  779.     }
  780.     //-------------------------------------------------------------------------
  781.  
  782.     return 0xFF;
  783. }
  784. //-----------------------------------------------------------------------------
  785.  
  786. //#include "z80/cmd.cpp"
  787.  
  788. //-----------------------------------------------------------------------------
  789. static inline void stepi()
  790. {
  791.     u8 opcode = m1_cycle( &gscpu);
  792.     (::normal_opcode[ opcode])( &gscpu);
  793.    
  794.             //printf ("GSINTFQ %d\n",GSINTFQ);
  795.             //printf ("GSCPUFQI %d\n",GSCPUFQI);
  796.             //printf ("GSCPUFQ %d\n",GSCPUFQ);
  797.             //printf ("GSCPUINT %d\n",GSCPUINT);
  798. }
  799. //-----------------------------------------------------------------------------
  800.  
  801.  
  802. //-----------------------------------------------------------------------------
  803. void Z80FAST step();
  804. //-----------------------------------------------------------------------------
  805.  
  806.  
  807. //-----------------------------------------------------------------------------
  808. void Z80FAST step()
  809. {
  810.     stepi();
  811. }
  812. //-----------------------------------------------------------------------------
  813.  
  814.  
  815. //-----------------------------------------------------------------------------
  816. void flush_gs_z80()
  817. {
  818.     if (gscpu.dbgchk)
  819.     {
  820.         gscpu.SetDbgMemIf();
  821.         z80gs::z80dbg::z80loop();
  822.     }
  823.     else
  824.     {
  825.         gscpu.SetFastMemIf();
  826.         z80gs::z80fast::z80loop();
  827.     }
  828. }
  829. //-----------------------------------------------------------------------------
  830.  
  831.  
  832. //-----------------------------------------------------------------------------
  833. __int64 __cdecl delta()
  834. {
  835.     return i64(gs_t_states) + gscpu.t - gscpu.debug_last_t;
  836. }
  837. //-----------------------------------------------------------------------------
  838.  
  839.  
  840. //-----------------------------------------------------------------------------
  841. void __cdecl SetLastT()
  842. {
  843.     gscpu.debug_last_t = i64(gs_t_states + gscpu.t);
  844. }
  845. //-----------------------------------------------------------------------------
  846.  
  847.  
  848. //-----------------------------------------------------------------------------
  849. void nmi()
  850. {
  851.     gscpu.sp -= 2;
  852.     z80fast::wm(gscpu.sp, gscpu.pcl);
  853.     z80fast::wm(gscpu.sp+1, gscpu.pch);
  854.     gscpu.pc = 0x66;
  855.     gscpu.iff1 = gscpu.halted = 0;
  856. }
  857. //-----------------------------------------------------------------------------
  858.  
  859.  
  860. //-----------------------------------------------------------------------------
  861. void reset()
  862. {
  863.     gscpu.reset();
  864.     gsbankr[0] = ROM_GS_M; gsbankr[1] = GSRAM_M + 3 * PAGE; gsbankr[2] = ROM_GS_M; gsbankr[3] = ROM_GS_M + PAGE;
  865.     gsbankw[0] = TRASH_M; gsbankw[1] = GSRAM_M + 3 * PAGE; gsbankw[2] = TRASH_M; gsbankw[3] = TRASH_M;
  866.  
  867.     gscpu.t = 0;
  868.     gs_t_states = 0;
  869.     gscpu_t_at_frame_start = 0;
  870.     ngs_cfg0 = 0;
  871.     ngs_s_stat = u8( u8(rdtsc() & ~7U) | _SDDET | _MPDRQ );
  872.     ngs_s_ctrl = u8( u8(rdtsc() & ~0xFU) | _SDNCS );
  873.     SdRdVal = SdRdValNew = 0xFF;
  874.     SdDataAvail = false;
  875.     Vs1001.Reset();
  876.  
  877.     for (unsigned i = 0;    i < 8;    i++)
  878.     {
  879.         gsbyte[i] = 0x80;
  880.         gsvol[i] = 0;
  881.         gs_v[i] = 0;
  882.     }
  883.  
  884.     ngs_mode_pg1 = 1;
  885.     ngs_dmamod = 0;
  886.     temp.gsdmaaddr = 0;
  887.     temp.gsdmaon = 0;
  888.     SdCard.Reset();
  889. }
  890. //-----------------------------------------------------------------------------
  891.  
  892. } // end of z80gs namespace
  893.  
  894. //=============================================================================
  895.  
  896. #endif  //#ifdef MOD_GSZ80
  897.  
  898. //=============================================================================
  899.  
  900.