Previous 15994 Revisions Next

r9224 Sunday 26th September, 2010 at 12:18:25 UTC by Angelo Salese
Put the SH2 DMA on a timer. This is needed because Knuckles Chaotix on the 32X can't be done with 'Instant DMA' due the SH2 DMA is used to read from a FIFO port which is being filled by the 68k during the transfer. [David Haywood]
[src/emu/cpu/sh2]sh2.c sh2.h sh2comn.c sh2comn.h sh2drc.c
[src/mame/drivers]megadriv.c

src/mame/drivers/megadriv.c
r9223r9224
23432343   }
23442344}
23452345
2346/**********************************************************************************************/
2347// 68k side a15112
2348// FIFO
2349/**********************************************************************************************/
23462350
2351static UINT16 fifo_block_a[4];
2352static UINT16 fifo_block_b[4];
2353static UINT16* current_fifo_block;
2354static UINT16* current_fifo_readblock;
2355int current_fifo_write_pos;
2356int current_fifo_read_pos;
2357int fifo_block_a_full;
2358int fifo_block_b_full;
23472359
2360static READ16_HANDLER( _32x_68k_a15112_r)
2361{
2362   printf("read write-only FIFO register\n");
2363   return 0;
2364}
2365
2366static WRITE16_HANDLER( _32x_68k_a15112_w )
2367{
2368   //printf("write to FIFO %04x!\n", data);
2369
2370   if (current_fifo_block==fifo_block_a && fifo_block_a_full)
2371   {
2372      printf("attempt to write to Full Fifo block a!\n");
2373      return;
2374   }
2375
2376   if (current_fifo_block==fifo_block_b && fifo_block_b_full)
2377   {
2378      printf("attempt to write to Full Fifo block b!\n");
2379      return;
2380   }
2381
2382   current_fifo_block[current_fifo_write_pos] = data;
2383   current_fifo_write_pos++;
2384
2385   if (current_fifo_write_pos==4)
2386   {
2387      if (current_fifo_block==fifo_block_a)
2388      {
2389         fifo_block_a_full = 1;
2390         if (!fifo_block_b_full)
2391         {
2392            current_fifo_block = fifo_block_b;
2393            current_fifo_readblock = fifo_block_a;
2394         }
2395         current_fifo_write_pos = 0;
2396      }
2397      else
2398      {
2399         fifo_block_b_full = 1;
2400         
2401         if (!fifo_block_a_full)
2402         {
2403            current_fifo_block = fifo_block_a;
2404            current_fifo_readblock = fifo_block_b;
2405         }
2406         
2407         current_fifo_write_pos = 0;
2408      }
2409   }
2410}
2411
2412
2413
23482414/*
23492415
2350241615106 DREQ
r9223r9224
23672433
23682434   retval = a15106_reg;
23692435
2370   //if (fifo_full) retval |= 0x0080;
2436   if (fifo_block_a_full && fifo_block_b_full) retval |= 0x8080;
23712437
23722438   return retval;
23732439}
r9223r9224
24092475    return 0x0000;
24102476}
24112477
2478
24122479/**********************************************************************************************/
24132480// 68k side a15100
24142481// control register - used to enable 32x etc.
r9223r9224
29102977// 68k To SH2 DReq Length Register
29112978/**********************************************************************************************/
29122979
2980static READ16_HANDLER( _32x_sh2_common_4010_r )
2981{
2982//   printf("reading DReq Length!\n");
2983   return 0x0000;
2984}
2985
29132986/**********************************************************************************************/
29142987// SH2 side 4012
29152988// FIFO Register (read)
29162989/**********************************************************************************************/
29172990
2991static READ16_HANDLER( _32x_sh2_common_4012_r )
2992{
2993   UINT16 retdat = current_fifo_readblock[current_fifo_read_pos];
2994
2995   current_fifo_read_pos++;
2996
2997//   printf("reading FIFO!\n");
2998
2999   if (current_fifo_readblock == fifo_block_a && !fifo_block_a_full)
3000      printf("Fifo block a isn't filled!\n");
3001
3002   if (current_fifo_readblock == fifo_block_b && !fifo_block_b_full)
3003      printf("Fifo block b isn't filled!\n");
3004
3005
3006   if (current_fifo_read_pos==4)
3007   {
3008      if (current_fifo_readblock == fifo_block_a)
3009      {
3010         fifo_block_a_full = 0;
3011     
3012         if (fifo_block_b_full)
3013         {
3014            current_fifo_readblock = fifo_block_b;
3015            current_fifo_block = fifo_block_a;
3016         }
3017
3018         current_fifo_read_pos = 0;
3019      }
3020      else if (current_fifo_readblock == fifo_block_b)
3021      {
3022         fifo_block_b_full = 0;
3023     
3024         if (fifo_block_a_full)
3025         {
3026            current_fifo_readblock = fifo_block_a;
3027            current_fifo_block = fifo_block_b;
3028         }
3029
3030         current_fifo_read_pos = 0;
3031      }
3032   }
3033   
3034   return retdat;
3035}
3036
3037
3038
29183039/**********************************************************************************************/
29193040// SH2 side 4014
29203041// VRES (md reset button interrupt) clear
r9223r9224
31843305_32X_MAP_RAM_READHANDLERS(commsram) // _32x_sh2_commsram_r
31853306_32X_MAP_RAM_WRITEHANDLERS(commsram) // _32x_sh2_commsram_w
31863307
3308_32X_MAP_READHANDLERS(common_4010,common_4012)
3309
31873310_32X_MAP_READHANDLERS(common_4100,common_4102) // _32x_sh2_common_4100_common_4102_r
31883311_32X_MAP_WRITEHANDLERS(common_4100,common_4102) // _32x_sh2_common_4100_common_4102_w
31893312
3313
31903314_32X_MAP_READHANDLERS(common_4104,common_4106) // _32x_sh2_common_4104_common_4106_r
31913315_32X_MAP_WRITEHANDLERS(common_4104,common_4106) // _32x_sh2_common_4104_common_4106_w
31923316
r9223r9224
32133337
32143338   AM_RANGE(0x00004000, 0x00004003) AM_READWRITE( _32x_sh2_master_4000_common_4002_r, _32x_sh2_master_4000_common_4002_w )
32153339
3340   AM_RANGE(0x00004010, 0x00004013) AM_READ( _32x_sh2_common_4010_common_4012_r )
3341
32163342   AM_RANGE(0x00004014, 0x00004017) AM_WRITE( _32x_sh2_master_4014_master_4016_w ) // IRQ clear
32173343   AM_RANGE(0x00004018, 0x0000401b) AM_WRITE( _32x_sh2_master_4018_master_401a_w ) // IRQ clear
32183344   AM_RANGE(0x0000401c, 0x0000401f) AM_WRITE( _32x_sh2_master_401c_master_401e_w ) // IRQ clear
r9223r9224
32373363
32383364   AM_RANGE(0x00004000, 0x00004003) AM_READWRITE( _32x_sh2_slave_4000_common_4002_r, _32x_sh2_slave_4000_common_4002_w )
32393365
3366   AM_RANGE(0x00004010, 0x00004013) AM_READ( _32x_sh2_common_4010_common_4012_r )
3367
32403368   AM_RANGE(0x00004014, 0x00004017) AM_WRITE( _32x_sh2_slave_4014_slave_4016_w ) // IRQ clear
32413369   AM_RANGE(0x00004018, 0x0000401b) AM_WRITE( _32x_sh2_slave_4018_slave_401a_w ) // IRQ clear
32423370   AM_RANGE(0x0000401c, 0x0000401f) AM_WRITE( _32x_sh2_slave_401c_slave_401e_w ) // IRQ clear
r9223r9224
58045932      cpu_set_input_line(_segacd_68k_cpu, INPUT_LINE_HALT, ASSERT_LINE);
58055933   }
58065934
5935   current_fifo_block = fifo_block_a;
5936   current_fifo_readblock = fifo_block_b;
5937   current_fifo_write_pos = 0;
5938   current_fifo_read_pos = 0;
5939   fifo_block_a_full = 0;
5940   fifo_block_b_full = 0;
5941
58075942}
58085943
58095944void megadriv_stop_scanline_timer(void)
r9223r9224
60636198
60646199
60656200
6066static const sh2_cpu_core sh2_conf_master = { 0, NULL };
6067static const sh2_cpu_core sh2_conf_slave  = { 1, NULL };
6201static int _32x_fifo_available_callback(UINT32 src, UINT32 dst, UINT32 data, int size)
6202{
6203   if (src==0x4012)
6204   {
6205      if (current_fifo_readblock==fifo_block_a && fifo_block_a_full)
6206         return 1;
60686207
6208      if (current_fifo_readblock==fifo_block_b && fifo_block_b_full)
6209         return 1;
6210
6211      return 0;
6212   }
6213   
6214   return 1;
6215}
6216
6217
6218static const sh2_cpu_core sh2_conf_master = { 0, NULL, _32x_fifo_available_callback };
6219static const sh2_cpu_core sh2_conf_slave  = { 1, NULL, _32x_fifo_available_callback };
6220
60696221MACHINE_CONFIG_DERIVED( genesis_32x, megadriv )
60706222
60716223   MDRV_CPU_ADD("32x_master_sh2", SH2, (MASTER_CLOCK_NTSC*3)/7 )
r9223r9224
63786530   memory_install_readwrite16_handler(cputag_get_address_space(machine, "maincpu", ADDRESS_SPACE_PROGRAM), 0xa15104, 0xa15105, 0, 0, _32x_68k_a15104_r, _32x_68k_a15104_w); // 68k BANK rom set
63796531   memory_install_readwrite16_handler(cputag_get_address_space(machine, "maincpu", ADDRESS_SPACE_PROGRAM), 0xa15106, 0xa15107, 0, 0, _32x_68k_a15106_r, _32x_68k_a15106_w); // dreq stuff
63806532
6533   memory_install_readwrite16_handler(cputag_get_address_space(machine, "maincpu", ADDRESS_SPACE_PROGRAM), 0xa15112, 0xa15113, 0, 0, _32x_68k_a15112_r, _32x_68k_a15112_w); // fifo
6534
6535
63816536   memory_install_readwrite16_handler(cputag_get_address_space(machine, "maincpu", ADDRESS_SPACE_PROGRAM), 0xa15120, 0xa1512f, 0, 0, _32x_68k_commsram_r, _32x_68k_commsram_w); // comms reg 0-7
63826537
63836538   memory_install_read16_handler(cputag_get_address_space(machine, "maincpu", ADDRESS_SPACE_PROGRAM), 0x0a130ec, 0x0a130ef, 0, 0, _32x_68k_MARS_r); // system ID
src/emu/cpu/sh2/sh2comn.h
r9223r9224
132132   int            icount;
133133
134134   emu_timer *timer;
135   emu_timer *dma_timer[2];
135   emu_timer *dma_current_active_timer[2];
136136   int     dma_timer_active[2];
137137
138   int active_dma_incs[2];
139   int active_dma_incd[2];
140   int active_dma_size[2];
141   UINT32 active_dma_src[2];
142   UINT32 active_dma_dst[2];
143   UINT32 active_dma_count[2];
144
138145   int     is_slave, cpu_type;
139146   int  (*dma_callback_kludge)(UINT32 src, UINT32 dst, UINT32 data, int size);
147   int  (*dma_callback_fifo_data_available)(UINT32 src, UINT32 dst, UINT32 data, int size);
140148
141149   void   (*ftcsr_read_callback)(UINT32 data);
142150
src/emu/cpu/sh2/sh2.h
r9223r9224
6262{
6363   int is_slave;
6464   int  (*dma_callback_kludge)(UINT32 src, UINT32 dst, UINT32 data, int size);
65   int  (*dma_callback_fifo_data_available)(UINT32 src, UINT32 dst, UINT32 data, int size);
6566};
6667
6768DECLARE_LEGACY_CPU_DEVICE(SH1, sh1);
src/emu/cpu/sh2/sh2drc.c
r9223r9224
799799
800800   m = sh2->m;
801801   tsave = sh2->timer;
802   tsaved0 = sh2->dma_timer[0];
803   tsaved1 = sh2->dma_timer[1];
802   tsaved0 = sh2->dma_current_active_timer[0];
803   tsaved1 = sh2->dma_current_active_timer[1];
804804
805805   f = sh2->ftcsr_read_callback;
806806   save_irqcallback = sh2->irq_callback;
r9223r9224
822822   sh2->device = device;
823823
824824   sh2->timer = tsave;
825   sh2->dma_timer[0] = tsaved0;
826   sh2->dma_timer[1] = tsaved1;
825   sh2->dma_current_active_timer[0] = tsaved0;
826   sh2->dma_current_active_timer[1] = tsaved1;
827827   sh2->m = m;
828828   memset(sh2->m, 0, 0x200);
829829
src/emu/cpu/sh2/sh2comn.c
r9223r9224
133133   sh2_timer_activate(sh2);
134134}
135135
136static TIMER_CALLBACK( sh2_dmac_callback )
136
137
138/*
139  We have to do DMA on a timer (or at least, in chunks) due to the way some systems use it.
140  The 32x is a difficult case, they set the SOURCE of the DMA to a FIFO buffer, which at most
141  can have 8 words in it.  Attempting to do an 'instant DMA' in this scenario is impossible
142  because the game is expecting the 68k of the system to feed data into the FIFO at the same
143  time as the SH2 is transfering it out via DMA
144
145  It might be possible to avoid the timer (which causes a performance hit) by calling this
146  from the CPU_EXECUTE loop instead when there is active DMA
147*/
148
149static void sh2_do_dma(sh2_state *sh2, int dma)
137150{
151   UINT32 dmadata;
152
153   UINT32 tempsrc, tempdst;
154
155   if (sh2->active_dma_count[dma] > 0)
156   {
157      // schedule next DMA callback
158      timer_adjust_oneshot(sh2->dma_current_active_timer[dma], sh2->device->cycles_to_attotime(2), dma);
159
160      // process current DMA
161      switch(sh2->active_dma_size[dma])
162      {
163      case 0:
164         {
165            // we need to know the src / dest ahead of time without changing them
166            // to allow for the callback to check if we can process the DMA at this
167            // time (we need to know where we're reading / writing to/from)
168
169            if(sh2->active_dma_incs[dma] == 2)
170               tempsrc = sh2->active_dma_src[dma] - 1;
171            else
172               tempsrc = sh2->active_dma_src[dma];
173
174            if(sh2->active_dma_incd[dma] == 2)
175               tempdst = sh2->active_dma_dst[dma] - 1;
176            else
177               tempdst = sh2->active_dma_dst[dma];
178
179            if (sh2->dma_callback_fifo_data_available)
180            {
181               int available = sh2->dma_callback_fifo_data_available(tempsrc, tempdst, 0, sh2->active_dma_size[dma]);
182   
183               if (!available)
184                  return;
185            }
186               
187
188            dmadata = sh2->program->read_byte(tempsrc);
189            if (sh2->dma_callback_kludge) dmadata = sh2->dma_callback_kludge(tempsrc, tempdst, dmadata, sh2->active_dma_size[dma]);
190            sh2->program->write_byte(tempdst, dmadata);
191
192            if(sh2->active_dma_incs[dma] == 2)
193               sh2->active_dma_src[dma] --;
194            if(sh2->active_dma_incd[dma] == 2)
195               sh2->active_dma_dst[dma] --;
196
197
198            if(sh2->active_dma_incs[dma] == 1)
199               sh2->active_dma_src[dma] ++;
200            if(sh2->active_dma_incd[dma] == 1)
201               sh2->active_dma_dst[dma] ++;
202
203            sh2->active_dma_count[dma] --;
204         }
205         break;
206      case 1:
207         {
208            if(sh2->active_dma_incs[dma] == 2)
209               tempsrc = sh2->active_dma_src[dma] - 2;
210            else
211               tempsrc = sh2->active_dma_src[dma];
212
213            if(sh2->active_dma_incd[dma] == 2)
214               tempdst = sh2->active_dma_dst[dma] - 2;
215            else
216               tempdst = sh2->active_dma_dst[dma];
217
218            if (sh2->dma_callback_fifo_data_available)
219            {
220               int available = sh2->dma_callback_fifo_data_available(tempsrc, tempdst, 0, sh2->active_dma_size[dma]);
221   
222               if (!available)
223                  return;
224            }
225
226            // check: should this really be using read_word_32 / write_word_32?
227            dmadata   = sh2->program->read_word(tempsrc);
228            if (sh2->dma_callback_kludge) dmadata = sh2->dma_callback_kludge(tempsrc, tempdst, dmadata, sh2->active_dma_size[dma]);
229            sh2->program->write_word(tempdst, dmadata);
230
231            if(sh2->active_dma_incs[dma] == 2)
232               sh2->active_dma_src[dma] -= 2;
233            if(sh2->active_dma_incd[dma] == 2)
234               sh2->active_dma_dst[dma] -= 2;
235
236            if(sh2->active_dma_incs[dma] == 1)
237               sh2->active_dma_src[dma] += 2;
238            if(sh2->active_dma_incd[dma] == 1)
239               sh2->active_dma_dst[dma] += 2;
240         
241            sh2->active_dma_count[dma] --;
242         }
243         break;
244      case 2:
245         {
246            if(sh2->active_dma_incs[dma] == 2)
247               tempsrc = sh2->active_dma_src[dma] - 4;
248            else
249               tempsrc = sh2->active_dma_src[dma];
250
251            if(sh2->active_dma_incd[dma] == 2)
252               tempdst = sh2->active_dma_dst[dma] - 4;
253            else
254               tempdst = sh2->active_dma_dst[dma];
255
256            if (sh2->dma_callback_fifo_data_available)
257            {
258               int available = sh2->dma_callback_fifo_data_available(tempsrc, tempdst, 0, sh2->active_dma_size[dma]);
259   
260               if (!available)
261                  return;
262            }
263
264            dmadata   = sh2->program->read_dword(tempsrc);
265            if (sh2->dma_callback_kludge) dmadata = sh2->dma_callback_kludge(tempsrc, tempdst, dmadata, sh2->active_dma_size[dma]);
266            sh2->program->write_dword(tempdst, dmadata);
267
268            if(sh2->active_dma_incs[dma] == 2)
269               sh2->active_dma_src[dma] -= 4;
270            if(sh2->active_dma_incd[dma] == 2)
271               sh2->active_dma_dst[dma] -= 4;
272
273            if(sh2->active_dma_incs[dma] == 1)
274               sh2->active_dma_src[dma] += 4;
275            if(sh2->active_dma_incd[dma] == 1)
276               sh2->active_dma_dst[dma] += 4;
277
278            sh2->active_dma_count[dma] --;
279         }
280         break;
281      case 3:
282         {
283            // shouldn't this really be 4 calls here instead?
284
285            tempsrc = sh2->active_dma_src[dma];
286
287            if(sh2->active_dma_incd[dma] == 2)
288               tempdst = sh2->active_dma_dst[dma] - 16;
289            else
290               tempdst = sh2->active_dma_dst[dma];
291
292            if (sh2->dma_callback_fifo_data_available)
293            {
294               int available = sh2->dma_callback_fifo_data_available(tempsrc, tempdst, 0, sh2->active_dma_size[dma]);
295   
296               if (!available)
297                  fatalerror("SH2 dma_callback_fifo_data_available == 0 in unsupported mode");
298            }
299
300            dmadata = sh2->program->read_dword(tempsrc);
301            if (sh2->dma_callback_kludge) dmadata = sh2->dma_callback_kludge(tempsrc, tempdst, dmadata, sh2->active_dma_size[dma]);
302            sh2->program->write_dword(tempdst, dmadata);
303
304            dmadata = sh2->program->read_dword(tempsrc+4);
305            if (sh2->dma_callback_kludge) dmadata = sh2->dma_callback_kludge(tempsrc, tempdst, dmadata, sh2->active_dma_size[dma]);
306            sh2->program->write_dword(tempdst+4, dmadata);
307
308            dmadata = sh2->program->read_dword(tempsrc+8);
309            if (sh2->dma_callback_kludge) dmadata = sh2->dma_callback_kludge(tempsrc, tempdst, dmadata, sh2->active_dma_size[dma]);
310            sh2->program->write_dword(tempdst+8, dmadata);
311
312            dmadata = sh2->program->read_dword(tempsrc+12);
313            if (sh2->dma_callback_kludge) dmadata = sh2->dma_callback_kludge(tempsrc, tempdst, dmadata, sh2->active_dma_size[dma]);
314            sh2->program->write_dword(tempdst+12, dmadata);
315
316            if(sh2->active_dma_incd[dma] == 2)
317               sh2->active_dma_dst[dma] -= 16;
318
319            sh2->active_dma_src[dma] += 16;
320            if(sh2->active_dma_incd[dma] == 1)
321               sh2->active_dma_dst[dma] += 16;
322         
323            sh2->active_dma_count[dma]-=4;
324         }
325         break;
326      }
327   }
328   else // the dma is complete
329   {
330   //   int dma = param & 1;
331   //   sh2_state *sh2 = (sh2_state *)ptr;
332
333      LOG(("SH2.%s: DMA %d complete\n", sh2->device->tag(), dma));
334      sh2->m[0x63+4*dma] |= 2;
335      sh2->dma_timer_active[dma] = 0;
336      sh2_recalc_irq(sh2);
337
338   }
339}
340
341static TIMER_CALLBACK( sh2_dma_current_active_callback )
342{
138343   int dma = param & 1;
139344   sh2_state *sh2 = (sh2_state *)ptr;
140345
141   LOG(("SH2.%s: DMA %d complete\n", sh2->device->tag(), dma));
142   sh2->m[0x63+4*dma] |= 2;
143   sh2->dma_timer_active[dma] = 0;
144   sh2_recalc_irq(sh2);
346   sh2_do_dma(sh2, dma);
145347}
146348
349
147350static void sh2_dmac_check(sh2_state *sh2, int dma)
148351{
149352   if(sh2->m[0x63+4*dma] & sh2->m[0x6c] & 1)
150353   {
151354      if(!sh2->dma_timer_active[dma] && !(sh2->m[0x63+4*dma] & 2))
152355      {
153         int incs, incd, size;
154         UINT32 src, dst, count;
155         UINT32 dmadata;
156         incd = (sh2->m[0x63+4*dma] >> 14) & 3;
157         incs = (sh2->m[0x63+4*dma] >> 12) & 3;
158         size = (sh2->m[0x63+4*dma] >> 10) & 3;
159         if(incd == 3 || incs == 3)
356
357         sh2->active_dma_incd[dma] = (sh2->m[0x63+4*dma] >> 14) & 3;
358         sh2->active_dma_incs[dma] = (sh2->m[0x63+4*dma] >> 12) & 3;
359         sh2->active_dma_size[dma] = (sh2->m[0x63+4*dma] >> 10) & 3;
360         if(sh2->active_dma_incd[dma] == 3 || sh2->active_dma_incs[dma] == 3)
160361         {
161            logerror("SH2: DMA: bad increment values (%d, %d, %d, %04x)\n", incd, incs, size, sh2->m[0x63+4*dma]);
362            logerror("SH2: DMA: bad increment values (%d, %d, %d, %04x)\n", sh2->active_dma_incd[dma], sh2->active_dma_incs[dma], sh2->active_dma_size[dma], sh2->m[0x63+4*dma]);
162363            return;
163364         }
164         src   = sh2->m[0x60+4*dma];
165         dst   = sh2->m[0x61+4*dma];
166         count = sh2->m[0x62+4*dma];
167         if(!count)
168            count = 0x1000000;
365         sh2->active_dma_src[dma]   = sh2->m[0x60+4*dma];
366         sh2->active_dma_dst[dma]   = sh2->m[0x61+4*dma];
367         sh2->active_dma_count[dma] = sh2->m[0x62+4*dma];
368         if(!sh2->active_dma_count[dma])
369            sh2->active_dma_count[dma] = 0x1000000;
169370
170         LOG(("SH2: DMA %d start %x, %x, %x, %04x, %d, %d, %d\n", dma, src, dst, count, sh2->m[0x63+4*dma], incs, incd, size));
371         LOG(("SH2: DMA %d start %x, %x, %x, %04x, %d, %d, %d\n", dma, sh2->active_dma_src[dma], sh2->active_dma_dst[dma], sh2->active_dma_count[dma], sh2->m[0x63+4*dma], sh2->active_dma_incs[dma], sh2->active_dma_incd[dma], sh2->active_dma_size[dma]));
171372
172373         sh2->dma_timer_active[dma] = 1;
173         timer_adjust_oneshot(sh2->dma_timer[dma], sh2->device->cycles_to_attotime(2*count+1), dma);
174374
175         src &= AM;
176         dst &= AM;
375         sh2->active_dma_src[dma] &= AM;
376         sh2->active_dma_dst[dma] &= AM;
177377
178         switch(size)
378         switch(sh2->active_dma_size[dma])
179379         {
180380         case 0:
181            for(;count > 0; count --)
182            {
183               if(incs == 2)
184                  src --;
185               if(incd == 2)
186                  dst --;
187
188               dmadata = sh2->program->read_byte(src);
189               if (sh2->dma_callback_kludge) dmadata = sh2->dma_callback_kludge(src, dst, dmadata, size);
190               sh2->program->write_byte(dst, dmadata);
191
192               if(incs == 1)
193                  src ++;
194               if(incd == 1)
195                  dst ++;
196            }
197381            break;
198382         case 1:
199            src &= ~1;
200            dst &= ~1;
201            for(;count > 0; count --)
202            {
203
204               if(incs == 2)
205                  src -= 2;
206               if(incd == 2)
207                  dst -= 2;
208
209               // check: should this really be using read_word_32 / write_word_32?
210               dmadata   = sh2->program->read_word(src);
211               if (sh2->dma_callback_kludge) dmadata = sh2->dma_callback_kludge(src, dst, dmadata, size);
212               sh2->program->write_word(dst, dmadata);
213
214               if(incs == 1)
215                  src += 2;
216               if(incd == 1)
217                  dst += 2;
218            }
383            sh2->active_dma_src[dma] &= ~1;
384            sh2->active_dma_dst[dma] &= ~1;   
219385            break;
220386         case 2:
221            src &= ~3;
222            dst &= ~3;
223            for(;count > 0; count --)
224            {
225               if(incs == 2)
226                  src -= 4;
227               if(incd == 2)
228                  dst -= 4;
229
230               dmadata   = sh2->program->read_dword(src);
231               if (sh2->dma_callback_kludge) dmadata = sh2->dma_callback_kludge(src, dst, dmadata, size);
232               sh2->program->write_dword(dst, dmadata);
233
234               if(incs == 1)
235                  src += 4;
236               if(incd == 1)
237                  dst += 4;
238
239            }
387            sh2->active_dma_src[dma] &= ~3;
388            sh2->active_dma_dst[dma] &= ~3;
240389            break;
241390         case 3:
242            src &= ~3;
243            dst &= ~3;
244            count &= ~3;
245            for(;count > 0; count -= 4)
246            {
247               if(incd == 2)
248                  dst -= 16;
391            sh2->active_dma_src[dma] &= ~3;
392            sh2->active_dma_dst[dma] &= ~3;
393            sh2->active_dma_count[dma] &= ~3;
394            break;
395         }
249396
250               dmadata = sh2->program->read_dword(src);
251               if (sh2->dma_callback_kludge) dmadata = sh2->dma_callback_kludge(src, dst, dmadata, size);
252               sh2->program->write_dword(dst, dmadata);
397         // start DMA timer
398         timer_adjust_oneshot(sh2->dma_current_active_timer[dma], sh2->device->cycles_to_attotime(2), dma);
253399
254               dmadata = sh2->program->read_dword(src+4);
255               if (sh2->dma_callback_kludge) dmadata = sh2->dma_callback_kludge(src, dst, dmadata, size);
256               sh2->program->write_dword(dst+4, dmadata);
257400
258               dmadata = sh2->program->read_dword(src+8);
259               if (sh2->dma_callback_kludge) dmadata = sh2->dma_callback_kludge(src, dst, dmadata, size);
260               sh2->program->write_dword(dst+8, dmadata);
261
262               dmadata = sh2->program->read_dword(src+12);
263               if (sh2->dma_callback_kludge) dmadata = sh2->dma_callback_kludge(src, dst, dmadata, size);
264               sh2->program->write_dword(dst+12, dmadata);
265
266               src += 16;
267               if(incd == 1)
268                  dst += 16;
269            }
270            break;
271         }
272401      }
273402   }
274403   else
r9223r9224
276405      if(sh2->dma_timer_active[dma])
277406      {
278407         logerror("SH2: DMA %d cancelled in-flight\n", dma);
279         timer_adjust_oneshot(sh2->dma_timer[dma], attotime_never, 0);
408         //timer_adjust_oneshot(sh2->dma_complete_timer[dma], attotime_never, 0);
409         timer_adjust_oneshot(sh2->dma_current_active_timer[dma], attotime_never, 0);
410     
280411         sh2->dma_timer_active[dma] = 0;
281412      }
282413   }
r9223r9224
707838   sh2->timer = timer_alloc(device->machine, sh2_timer_callback, sh2);
708839   timer_adjust_oneshot(sh2->timer, attotime_never, 0);
709840
710   sh2->dma_timer[0] = timer_alloc(device->machine, sh2_dmac_callback, sh2);
711   timer_adjust_oneshot(sh2->dma_timer[0], attotime_never, 0);
841   sh2->dma_current_active_timer[0] = timer_alloc(device->machine, sh2_dma_current_active_callback, sh2);
842   timer_adjust_oneshot(sh2->dma_current_active_timer[0], attotime_never, 0);
712843
713   sh2->dma_timer[1] = timer_alloc(device->machine, sh2_dmac_callback, sh2);
714   timer_adjust_oneshot(sh2->dma_timer[1], attotime_never, 0);
844   sh2->dma_current_active_timer[1] = timer_alloc(device->machine, sh2_dma_current_active_callback, sh2);
845   timer_adjust_oneshot(sh2->dma_current_active_timer[1], attotime_never, 0);
715846
847
716848   sh2->m = auto_alloc_array(device->machine, UINT32, 0x200/4);
717849
718850   if(conf)
719851   {
720852      sh2->is_slave = conf->is_slave;
721853      sh2->dma_callback_kludge = conf->dma_callback_kludge;
854      sh2->dma_callback_fifo_data_available = conf->dma_callback_fifo_data_available;
722855   }
723856   else
724857   {
725858      sh2->is_slave = 0;
726859      sh2->dma_callback_kludge = NULL;
860      sh2->dma_callback_fifo_data_available = NULL;
727861
728862   }
729863   sh2->irq_callback = irqcallback;
src/emu/cpu/sh2/sh2.c
r9223r9224
21482148   emu_timer *tsave, *tsaved0, *tsaved1;
21492149   UINT32 *m;
21502150   int  (*dma_callback_kludge)(UINT32 src, UINT32 dst, UINT32 data, int size);
2151   int  (*dma_callback_fifo_data_available)(UINT32 src, UINT32 dst, UINT32 data, int size);
21512152   int save_is_slave;
21522153
21532154   void (*f)(UINT32 data);
r9223r9224
21552156
21562157   m = sh2->m;
21572158   tsave = sh2->timer;
2158   tsaved0 = sh2->dma_timer[0];
2159   tsaved1 = sh2->dma_timer[1];
2159   tsaved0 = sh2->dma_current_active_timer[0];
2160   tsaved1 = sh2->dma_current_active_timer[1];
21602161
21612162   f = sh2->ftcsr_read_callback;
21622163   save_irqcallback = sh2->irq_callback;
21632164   save_is_slave = sh2->is_slave;
21642165   dma_callback_kludge = sh2->dma_callback_kludge;
2166   dma_callback_fifo_data_available = sh2->dma_callback_fifo_data_available;
21652167
21662168   sh2->ppc = sh2->pc = sh2->pr = sh2->sr = sh2->gbr = sh2->vbr = sh2->mach = sh2->macl = 0;
21672169   sh2->evec = sh2->irqsr = 0;
r9223r9224
21762178   sh2->dma_timer_active[0] = sh2->dma_timer_active[1] = 0;
21772179
21782180   sh2->dma_callback_kludge = dma_callback_kludge;
2181   sh2->dma_callback_fifo_data_available = dma_callback_fifo_data_available;
21792182   sh2->is_slave = save_is_slave;
21802183   sh2->ftcsr_read_callback = f;
21812184   sh2->irq_callback = save_irqcallback;
21822185   sh2->device = device;
21832186
21842187   sh2->timer = tsave;
2185   sh2->dma_timer[0] = tsaved0;
2186   sh2->dma_timer[1] = tsaved1;
2188   sh2->dma_current_active_timer[0] = tsaved0;
2189   sh2->dma_current_active_timer[1] = tsaved1;
21872190   sh2->m = m;
21882191   memset(sh2->m, 0, 0x200);
21892192

Previous 15994 Revisions Next


© 1998-2018 The MESS Team