Previous 15994 Revisions Next

r11530 Thursday 12th May, 2011 at 19:46:18 UTC by Angelo Salese
Forgot this
[src/mame/machine]dccons.c

src/mame/machine/dccons.c
r11529r11530
1/*
2
3    dc.c - Sega Dreamcast hardware
4
5    MESS (DC home console) hardware overrides (GD-ROM drive etc)
6
7    c230048 - 5 is written, want 6
8    c0d9d9e - where bad happens, from routine @ c0da260
9
10    c0d9d8e - R0 on return is the value to put in
11
12    cfffee0 - stack location when bad happens
13
14*/
15
16#include "emu.h"
17#include "cdrom.h"
18#include "debugger.h"
19#include "includes/dc.h"
20#include "cpu/sh4/sh4.h"
21#include "sound/aica.h"
22#include "includes/naomi.h"
23#include "machine/gdrom.h"
24#include "imagedev/chd_cd.h"
25
26#define ATAPI_CYCLES_PER_SECTOR (5000)   // TBD for Dreamcast
27
28#define ATAPI_STAT_BSY      0x80
29#define ATAPI_STAT_DRDY    0x40
30#define ATAPI_STAT_DMARDDF 0x20
31#define ATAPI_STAT_SERVDSC 0x10
32#define ATAPI_STAT_DRQ     0x08
33#define ATAPI_STAT_CORR    0x04
34#define ATAPI_STAT_CHECK   0x01
35
36#define ATAPI_INTREASON_COMMAND 0x01
37#define ATAPI_INTREASON_IO      0x02
38#define ATAPI_INTREASON_RELEASE 0x04
39
40#define ATAPI_REG_DATA      0
41#define ATAPI_REG_FEATURES   1
42#define ATAPI_REG_INTREASON   2
43#define ATAPI_REG_SAMTAG   3
44#define ATAPI_REG_COUNTLOW   4
45#define ATAPI_REG_COUNTHIGH   5
46#define ATAPI_REG_DRIVESEL   6
47#define ATAPI_REG_CMDSTATUS   7
48#define ATAPI_REG_ERROR      16   // read-only ERROR (write is FEATURES)
49
50#define ATAPI_REG_MAX 24
51
52#define ATAPI_XFER_PIO      0x00
53#define ATAPI_XFER_PIO_FLOW   0x08
54#define ATAPI_XFER_MULTI_DMA   0x20
55#define ATAPI_XFER_ULTRA_DMA   0x40
56
57#define ATAPI_DATA_SIZE ( 64 * 1024 )
58
59static UINT8 *atapi_regs;
60static emu_timer *atapi_timer;
61static SCSIInstance *gdrom_device;
62static UINT8 *atapi_data;
63static int atapi_data_ptr, atapi_data_len, atapi_xferlen, atapi_xferbase, atapi_cdata_wait, atapi_xfermod;
64static UINT32 gdrom_alt_status;
65static UINT8 xfer_mode = ATAPI_XFER_PIO;
66
67#define MAX_TRANSFER_SIZE ( 63488 )
68
69extern UINT32 dc_sysctrl_regs[0x200/4];
70
71extern UINT32 g1bus_regs[0x100/4];
72
73static void gdrom_raise_irq(running_machine &machine)
74{
75   dc_sysctrl_regs[SB_ISTEXT] |= IST_EXT_GDROM;
76   dc_update_interrupt_status(machine);
77}
78
79static TIMER_CALLBACK( atapi_xfer_end )
80{
81   UINT8 sector_buffer[ 4096 ];
82
83   atapi_timer->adjust(attotime::never);
84
85   printf("atapi_xfer_end atapi_xferlen = %d, atapi_xfermod=%d\n", atapi_xfermod, atapi_xferlen );
86
87   mame_printf_debug("ATAPI: xfer_end.  xferlen = %d, atapi_xfermod = %d\n", atapi_xferlen, atapi_xfermod);
88
89   while (atapi_xferlen > 0 )
90   {
91      struct sh4_ddt_dma ddtdata;
92
93      // get a sector from the SCSI device
94      SCSIReadData( gdrom_device, sector_buffer, 2048 );
95
96      atapi_xferlen -= 2048;
97
98      // perform the DMA
99      ddtdata.destination = atapi_xferbase;   // destination address
100      ddtdata.length = 2048/4;
101      ddtdata.size = 4;
102      ddtdata.buffer = sector_buffer;
103      ddtdata.direction=1;   // 0 source to buffer, 1 buffer to destination
104      ddtdata.channel= -1;   // not used
105      ddtdata.mode= -1;      // copy from/to buffer
106      printf("ATAPI: DMA one sector to %x, %x remaining\n", atapi_xferbase, atapi_xferlen);
107      sh4_dma_ddt(machine.device("maincpu"), &ddtdata);
108
109      atapi_xferbase += 2048;
110   }
111
112   if (atapi_xfermod > MAX_TRANSFER_SIZE)
113   {
114      atapi_xferlen = MAX_TRANSFER_SIZE;
115      atapi_xfermod = atapi_xfermod - MAX_TRANSFER_SIZE;
116   }
117   else
118   {
119      atapi_xferlen = atapi_xfermod;
120      atapi_xfermod = 0;
121   }
122
123   if (atapi_xferlen > 0)
124   {
125      printf("ATAPI: starting next piece of multi-part transfer\n");
126      atapi_regs[ATAPI_REG_COUNTLOW] = atapi_xferlen & 0xff;
127      atapi_regs[ATAPI_REG_COUNTHIGH] = (atapi_xferlen>>8)&0xff;
128
129      atapi_timer->adjust(machine.device<cpu_device>("maincpu")->cycles_to_attotime((ATAPI_CYCLES_PER_SECTOR * (atapi_xferlen/2048))));
130   }
131   else
132   {
133      printf("ATAPI: Transfer completed, dropping DRQ\n");
134      atapi_regs[ATAPI_REG_CMDSTATUS] = ATAPI_STAT_DRDY;
135      gdrom_alt_status = ATAPI_STAT_DRDY;
136      atapi_regs[ATAPI_REG_INTREASON] = ATAPI_INTREASON_IO | ATAPI_INTREASON_COMMAND;
137
138      g1bus_regs[SB_GDST]=0;
139      dc_sysctrl_regs[SB_ISTNRM] |= IST_DMA_GDROM;
140      dc_update_interrupt_status(machine);
141   }
142
143   gdrom_raise_irq(machine);
144
145   printf( "atapi_xfer_end: %d %d\n", atapi_xferlen, atapi_xfermod );
146}
147
148static READ32_HANDLER( atapi_r )
149{
150   running_machine &machine = space->machine();
151   int reg, data;
152
153   if (mem_mask == 0x0000ffff)   // word-wide command read
154   {
155//      mame_printf_debug("ATAPI: packet read = %04x\n", atapi_data[atapi_data_ptr]);
156
157      // assert IRQ and drop DRQ
158      if (atapi_data_ptr == 0 && atapi_data_len == 0)
159      {
160         // get the data from the device
161         if( atapi_xferlen > 0 )
162         {
163            SCSIReadData( gdrom_device, atapi_data, atapi_xferlen );
164            atapi_data_len = atapi_xferlen;
165         }
166
167         if (atapi_xfermod > MAX_TRANSFER_SIZE)
168         {
169            atapi_xferlen = MAX_TRANSFER_SIZE;
170            atapi_xfermod = atapi_xfermod - MAX_TRANSFER_SIZE;
171         }
172         else
173         {
174            atapi_xferlen = atapi_xfermod;
175            atapi_xfermod = 0;
176         }
177
178//          printf( "atapi_r: atapi_xferlen=%d\n", atapi_xferlen );
179         if( atapi_xferlen != 0 )
180         {
181            atapi_regs[ATAPI_REG_CMDSTATUS] = ATAPI_STAT_DRQ | ATAPI_STAT_SERVDSC;
182            gdrom_alt_status = ATAPI_STAT_DRQ | ATAPI_STAT_SERVDSC;
183            atapi_regs[ATAPI_REG_INTREASON] = ATAPI_INTREASON_IO;
184         }
185         else
186         {
187            //mame_printf_debug("ATAPI: dropping DRQ\n");
188            atapi_regs[ATAPI_REG_CMDSTATUS] = 0;
189            gdrom_alt_status = 0;
190            atapi_regs[ATAPI_REG_INTREASON] = ATAPI_INTREASON_IO;
191         }
192
193         atapi_regs[ATAPI_REG_COUNTLOW] = atapi_xferlen & 0xff;
194         atapi_regs[ATAPI_REG_COUNTHIGH] = (atapi_xferlen>>8)&0xff;
195
196         gdrom_raise_irq(machine);
197      }
198
199      if( atapi_data_ptr < atapi_data_len )
200      {
201         data = atapi_data[atapi_data_ptr++];
202         data |= ( atapi_data[atapi_data_ptr++] << 8 );
203         if( atapi_data_ptr >= atapi_data_len )
204         {
205//              printf( "atapi_r: read all bytes\n" );
206            atapi_data_ptr = 0;
207            atapi_data_len = 0;
208
209            if( atapi_xferlen == 0 )
210            {
211               atapi_regs[ATAPI_REG_CMDSTATUS] = 0;
212               gdrom_alt_status = 0;
213               atapi_regs[ATAPI_REG_INTREASON] = ATAPI_INTREASON_IO;
214               gdrom_raise_irq(machine);
215            }
216         }
217      }
218      else
219      {
220         data = 0;
221      }
222   }
223   else
224   {
225      reg = offset;
226
227      // get read-only side of read-only/write-only registers from elsewhere
228      if (reg == ATAPI_REG_FEATURES)
229      {
230         reg = ATAPI_REG_ERROR;
231      }
232      data = atapi_regs[reg];
233
234      #if 0
235      switch( reg )
236      {
237      case ATAPI_REG_DATA:
238         printf( "atapi_r: data=%02x\n", data );
239         break;
240      case ATAPI_REG_ERROR:
241         printf( "atapi_r: error=%02x\n", data );
242         break;
243      case ATAPI_REG_INTREASON:
244         printf( "atapi_r: intreason=%02x\n", data );
245         break;
246      case ATAPI_REG_SAMTAG:
247         printf( "atapi_r: samtag=%02x\n", data );
248         break;
249      case ATAPI_REG_COUNTLOW:
250         printf( "atapi_r: countlow=%02x\n", data );
251         break;
252      case ATAPI_REG_COUNTHIGH:
253         printf( "atapi_r: counthigh=%02x\n", data );
254         break;
255      case ATAPI_REG_DRIVESEL:
256         printf( "atapi_r: drivesel=%02x\n", data );
257         break;
258      case ATAPI_REG_CMDSTATUS:
259         printf( "atapi_r: cmdstatus=%02x\n", data );
260         break;
261      }
262      #endif
263
264      mame_printf_debug("ATAPI: read reg %d = %x (PC=%x)\n", reg, data, cpu_get_pc(&space->device()));
265   }
266
267//  printf( "atapi_r( %08x, %08x ) %08x\n", offset, mem_mask, data );
268   return data;
269}
270
271static WRITE32_HANDLER( atapi_w )
272{
273   running_machine &machine = space->machine();
274   int reg;
275
276//  printf( "atapi_w( %08x, %08x, %08x )\n", offset, mem_mask, data );
277
278   if (mem_mask == 0x0000ffff)   // word-wide command write
279   {
280//      printf("atapi_w: data=%04x\n", data );
281
282//      printf("ATAPI: packet write %04x\n", data);
283      atapi_data[atapi_data_ptr++] = data & 0xff;
284      atapi_data[atapi_data_ptr++] = data >> 8;
285
286      if (atapi_cdata_wait)
287      {
288//                  printf("ATAPI: waiting, ptr %d wait %d\n", atapi_data_ptr, atapi_cdata_wait);
289         if (atapi_data_ptr == atapi_cdata_wait)
290         {
291            // send it to the device
292            SCSIWriteData( gdrom_device, atapi_data, atapi_cdata_wait );
293
294            // assert IRQ
295            gdrom_raise_irq(machine);
296
297            // not sure here, but clear DRQ at least?
298            atapi_regs[ATAPI_REG_CMDSTATUS] = 0;
299         }
300      }
301
302      else if ( atapi_data_ptr == 12 )
303      {
304         int phase;
305
306//          printf("atapi_w: command %02x\n", atapi_data[0]&0xff );
307
308         // reset data pointer for reading SCSI results
309         atapi_data_ptr = 0;
310         atapi_data_len = 0;
311
312         // send it to the SCSI device
313         SCSISetCommand( gdrom_device, atapi_data, 12 );
314         SCSIExecCommand( gdrom_device, &atapi_xferlen );
315         SCSIGetPhase( gdrom_device, &phase );
316
317         if (atapi_xferlen != -1)
318         {
319            printf("ATAPI: SCSI command %02x returned %d bytes from the device\n", atapi_data[0]&0xff, atapi_xferlen);
320
321            // store the returned command length in the ATAPI regs, splitting into
322            // multiple transfers if necessary
323            atapi_xfermod = 0;
324            if (atapi_xferlen > MAX_TRANSFER_SIZE)
325            {
326               atapi_xfermod = atapi_xferlen - MAX_TRANSFER_SIZE;
327               atapi_xferlen = MAX_TRANSFER_SIZE;
328            }
329
330            atapi_regs[ATAPI_REG_COUNTLOW] = atapi_xferlen & 0xff;
331            atapi_regs[ATAPI_REG_COUNTHIGH] = (atapi_xferlen>>8)&0xff;
332
333            gdrom_alt_status = 0;   // (I guess?)
334
335            if (atapi_xferlen == 0)
336            {
337               // if no data to return, set the registers properly
338               atapi_regs[ATAPI_REG_CMDSTATUS] = ATAPI_STAT_DRDY;
339               atapi_regs[ATAPI_REG_INTREASON] = ATAPI_INTREASON_IO|ATAPI_INTREASON_COMMAND;
340            }
341            else
342            {
343               // indicate data ready: set DRQ and DMA ready, and IO in INTREASON
344               if (atapi_regs[ATAPI_REG_FEATURES] & 0x01)   // DMA feature
345               {
346                  atapi_regs[ATAPI_REG_CMDSTATUS] = ATAPI_STAT_BSY | ATAPI_STAT_DRDY | ATAPI_STAT_SERVDSC;
347               }
348               else
349               {
350                  atapi_regs[ATAPI_REG_CMDSTATUS] = ATAPI_STAT_DRQ | ATAPI_STAT_SERVDSC | ATAPI_STAT_DRQ;
351               }
352               atapi_regs[ATAPI_REG_INTREASON] = ATAPI_INTREASON_IO;
353            }
354
355            switch( phase )
356            {
357            case SCSI_PHASE_DATAOUT:
358               atapi_cdata_wait = atapi_xferlen;
359               break;
360            }
361
362            // perform special ATAPI processing of certain commands
363            switch (atapi_data[0]&0xff)
364            {
365               case 0x00: // BUS RESET / TEST UNIT READY
366               case 0xbb: // SET CDROM SPEED
367                  atapi_regs[ATAPI_REG_CMDSTATUS] = 0;
368                  break;
369
370               case 0x45: // PLAY
371                  atapi_regs[ATAPI_REG_CMDSTATUS] = ATAPI_STAT_BSY;
372                  atapi_timer->adjust( downcast<cpu_device *>(&space->device())->cycles_to_attotime(ATAPI_CYCLES_PER_SECTOR ) );
373                  break;
374            }
375
376            // assert IRQ
377            gdrom_raise_irq(machine);
378         }
379         else
380         {
381                     printf("ATAPI: SCSI device returned error!\n");
382
383            atapi_regs[ATAPI_REG_CMDSTATUS] = ATAPI_STAT_DRQ | ATAPI_STAT_CHECK;
384            atapi_regs[ATAPI_REG_ERROR] = 0x50;   // sense key = ILLEGAL REQUEST
385            atapi_regs[ATAPI_REG_COUNTLOW] = 0;
386            atapi_regs[ATAPI_REG_COUNTHIGH] = 0;
387         }
388      }
389   }
390   else
391   {
392      reg = offset;
393#if 0
394      switch( reg )
395      {
396      case ATAPI_REG_DATA:
397         printf( "atapi_w: data=%02x\n", data );
398             break;
399          case ATAPI_REG_FEATURES:
400         printf( "atapi_w: features=%02x\n", data );
401             break;
402          case ATAPI_REG_INTREASON:
403         printf( "atapi_w: intreason=%02x\n", data );
404             break;
405          case ATAPI_REG_SAMTAG:
406         printf( "atapi_w: samtag=%02x\n", data );
407             break;
408          case ATAPI_REG_COUNTLOW:
409         printf( "atapi_w: countlow=%02x\n", data );
410             break;
411          case ATAPI_REG_COUNTHIGH:
412         printf( "atapi_w: counthigh=%02x\n", data );
413             break;
414          case ATAPI_REG_DRIVESEL:
415         printf( "atapi_w: drivesel=%02x\n", data );
416             break;
417          case ATAPI_REG_CMDSTATUS:
418         printf( "atapi_w: cmdstatus=%02x\n", data );
419         break;
420      }
421#endif
422      atapi_regs[reg] = data;
423//      mame_printf_debug("ATAPI: reg %d = %x (offset %x mask %x PC=%x)\n", reg, data, offset, mem_mask, cpu_get_pc(&space->device()));
424
425      if (reg == ATAPI_REG_CMDSTATUS)
426      {
427         printf("ATAPI command %x issued! (PC=%x)\n", data, cpu_get_pc(&space->device()));
428
429         switch (data)
430         {
431            case 0xa0:   // PACKET
432               atapi_regs[ATAPI_REG_CMDSTATUS] = ATAPI_STAT_DRQ;
433               gdrom_alt_status = ATAPI_STAT_DRQ;
434               atapi_regs[ATAPI_REG_INTREASON] = ATAPI_INTREASON_COMMAND;
435
436               atapi_data_ptr = 0;
437               atapi_data_len = 0;
438
439               /* we have no data */
440               atapi_xferlen = 0;
441               atapi_xfermod = 0;
442
443               atapi_cdata_wait = 0;
444               break;
445
446            case 0xa1:   // IDENTIFY PACKET DEVICE
447               atapi_regs[ATAPI_REG_CMDSTATUS] = ATAPI_STAT_DRQ;
448               gdrom_alt_status = ATAPI_STAT_DRQ;
449
450               atapi_data_ptr = 0;
451               atapi_data_len = 512;
452
453               /* we have no data */
454               atapi_xferlen = 0;
455               atapi_xfermod = 0;
456
457               memset( atapi_data, 0, atapi_data_len );
458
459               atapi_data[ 0 ^ 1 ] = 0x86;   // ATAPI device, cmd set 6 compliant, DRQ within 3 ms of PACKET command
460               atapi_data[ 1 ^ 1 ] = 0x00;
461
462               memset( &atapi_data[ 46 ], ' ', 8 );
463               atapi_data[ 46 ^ 1 ] = 'S';
464               atapi_data[ 47 ^ 1 ] = 'E';
465
466               memset( &atapi_data[ 54 ], ' ', 40 );
467               atapi_data[ 54 ^ 1 ] = 'C';
468               atapi_data[ 55 ^ 1 ] = 'D';
469               atapi_data[ 56 ^ 1 ] = '-';
470               atapi_data[ 57 ^ 1 ] = 'R';
471               atapi_data[ 58 ^ 1 ] = 'O';
472               atapi_data[ 59 ^ 1 ] = 'M';
473               atapi_data[ 60 ^ 1 ] = ' ';
474               atapi_data[ 61 ^ 1 ] = 'D';
475               atapi_data[ 62 ^ 1 ] = 'R';
476               atapi_data[ 63 ^ 1 ] = 'I';
477               atapi_data[ 64 ^ 1 ] = 'V';
478               atapi_data[ 65 ^ 1 ] = 'E';
479               atapi_data[ 66 ^ 1 ] = ' ';
480               atapi_data[ 67 ^ 1 ] = ' ';
481               atapi_data[ 68 ^ 1 ] = ' ';
482               atapi_data[ 69 ^ 1 ] = ' ';
483               atapi_data[ 70 ^ 1 ] = '6';
484               atapi_data[ 71 ^ 1 ] = '.';
485               atapi_data[ 72 ^ 1 ] = '4';
486               atapi_data[ 73 ^ 1 ] = '2';
487
488               atapi_data[ 98 ^ 1 ] = 0x04; // IORDY may be disabled
489               atapi_data[ 99 ^ 1 ] = 0x00;
490
491               atapi_regs[ATAPI_REG_COUNTLOW] = 0;
492               atapi_regs[ATAPI_REG_COUNTHIGH] = 2;
493
494               gdrom_raise_irq(space->machine());
495               break;
496
497            case 0xef:   // SET FEATURES
498               // set xfer mode?
499               if (atapi_regs[ATAPI_REG_FEATURES] == 0x03)
500               {
501                  printf("Set transfer mode to %x\n", atapi_regs[ATAPI_REG_COUNTLOW] & 0xf8);
502                  xfer_mode = atapi_regs[ATAPI_REG_COUNTLOW] & 0xf8;
503               }
504               else
505               {
506                  printf("ATAPI: Unknown set features %x\n", atapi_regs[ATAPI_REG_FEATURES]);
507               }
508
509               atapi_regs[ATAPI_REG_CMDSTATUS] = 0;
510               gdrom_alt_status = 0;   // is this correct?
511
512               atapi_data_ptr = 0;
513               atapi_data_len = 0;
514
515               gdrom_raise_irq(space->machine());
516               break;
517
518            default:
519               mame_printf_debug("ATAPI: Unknown IDE command %x\n", data);
520               break;
521         }
522      }
523   }
524}
525
526static void dreamcast_atapi_exit(running_machine& machine)
527{
528   if (gdrom_device != NULL)
529   {
530      SCSIDeleteInstance( gdrom_device );
531   }
532}
533
534void dreamcast_atapi_init(running_machine &machine)
535{
536   atapi_regs = auto_alloc_array(machine, UINT8,  ATAPI_REG_MAX );
537   memset(atapi_regs, 0, sizeof(atapi_regs));
538
539   atapi_regs[ATAPI_REG_CMDSTATUS] = 0;
540   atapi_regs[ATAPI_REG_ERROR] = 1;
541   atapi_regs[ATAPI_REG_COUNTLOW] = 0x14;
542   atapi_regs[ATAPI_REG_COUNTHIGH] = 0xeb;
543
544   atapi_data_ptr = 0;
545   atapi_data_len = 0;
546   atapi_cdata_wait = 0;
547
548   atapi_timer = machine.scheduler().timer_alloc(FUNC(atapi_xfer_end));
549   atapi_timer->adjust(attotime::never);
550
551   gdrom_device = NULL;
552
553   machine.add_notifier(MACHINE_NOTIFY_EXIT, machine_notify_delegate(FUNC(dreamcast_atapi_exit),&machine));
554
555   atapi_data = auto_alloc_array(machine, UINT8,  ATAPI_DATA_SIZE );
556
557   state_save_register_global_pointer(machine,  atapi_regs, ATAPI_REG_MAX );
558   state_save_register_global_pointer(machine,  atapi_data, ATAPI_DATA_SIZE / 2 );
559   state_save_register_global(machine,  atapi_data_ptr );
560   state_save_register_global(machine,  atapi_data_len );
561   state_save_register_global(machine,  atapi_xferlen );
562   state_save_register_global(machine,  atapi_xferbase );
563   state_save_register_global(machine,  atapi_cdata_wait );
564   state_save_register_global(machine,  atapi_xfermod );
565}
566
567void dreamcast_atapi_reset(running_machine &machine)
568{
569   atapi_regs[ATAPI_REG_CMDSTATUS] = 0;
570   atapi_regs[ATAPI_REG_ERROR] = 1;
571   atapi_regs[ATAPI_REG_COUNTLOW] = 0x14;
572   atapi_regs[ATAPI_REG_COUNTHIGH] = 0xeb;
573
574   atapi_data_ptr = 0;
575   atapi_data_len = 0;
576   atapi_cdata_wait = 0;
577
578   atapi_xferlen = 0;
579   atapi_xfermod = 0;
580
581   if ( cd_get_cdrom_file(machine.device( "cdrom" )) != NULL )
582   {
583      SCSIAllocInstance( machine, &SCSIClassGDROM, &gdrom_device, "cdrom" );
584   }
585   else
586   {
587      gdrom_device = NULL;
588   }
589}
590
591/*
592
593 GDROM regsters:
594
595 5f7018: alternate status/device control
596 5f7080: data
597 5f7084: error/features
598 5f7088: interrupt reason/sector count
599 5f708c: sector number
600 5f7090: byte control low
601 5f7094: byte control high
602 5f7098: drive select
603 5f709c: status/command
604
605c002910 - ATAPI packet writes
606c002796 - aux status read after that
607c000776 - DMA triggered to c008000
608
609*/
610
611READ64_HANDLER( dc_mess_gdrom_r )
612{
613   UINT32 off;
614
615   if ((int)~mem_mask & 1)
616   {
617      off=(offset << 1) | 1;
618   }
619   else
620   {
621      off=offset << 1;
622   }
623
624//  printf("gdrom_r: @ %x (off %x), mask %llx (PC %x)\n", offset, off, mem_mask, cpu_get_pc(&space->device()));
625
626   if (offset == 3)
627   {
628      return gdrom_alt_status;
629   }
630   else if (off >= 0x20)
631   {
632      return atapi_r(space, off-0x20, 0xff);
633   }
634
635   return 0;
636}
637
638WRITE64_HANDLER( dc_mess_gdrom_w )
639{
640   UINT32 dat,off;
641
642   if ((int)~mem_mask & 1)
643   {
644      dat=(UINT32)(data >> 32);
645      off=(offset << 1) | 1;
646   }
647   else
648   {
649      dat=(UINT32)data;
650      off=offset << 1;
651   }
652
653//  printf("GDROM: [%08x=%x]write %llx to %x, mask %llx (PC %x)\n", 0x5f7000+off*4, dat, data, offset, mem_mask, cpu_get_pc(&space->device()));
654
655   if (off >= 0x20)
656   {
657      atapi_w(space, off-0x20, dat, (UINT32)mem_mask);
658   }
659}
660
661// register decode helpers
662
663// this accepts only 32-bit accesses
664INLINE int decode_reg32_64(running_machine &machine, UINT32 offset, UINT64 mem_mask, UINT64 *shift)
665{
666   int reg = offset * 2;
667
668   *shift = 0;
669
670   // non 32-bit accesses have not yet been seen here, we need to know when they are
671   if ((mem_mask != U64(0xffffffff00000000)) && (mem_mask != U64(0x00000000ffffffff)))
672   {
673      mame_printf_verbose("%s:Wrong mask!\n", machine.describe_context());
674//      debugger_break(machine);
675   }
676
677   if (mem_mask == U64(0xffffffff00000000))
678   {
679      reg++;
680      *shift = 32;
681   }
682
683   return reg;
684}
685
686READ64_HANDLER( dc_mess_g1_ctrl_r )
687{
688   int reg;
689   UINT64 shift;
690
691   reg = decode_reg32_64(space->machine(), offset, mem_mask, &shift);
692   mame_printf_verbose("G1CTRL:  Unmapped read %08x\n", 0x5f7400+reg*4);
693   return (UINT64)g1bus_regs[reg] << shift;
694}
695
696WRITE64_HANDLER( dc_mess_g1_ctrl_w )
697{
698   int reg;
699   UINT64 shift;
700   UINT32 old,dat;
701
702   reg = decode_reg32_64(space->machine(), offset, mem_mask, &shift);
703   dat = (UINT32)(data >> shift);
704   old = g1bus_regs[reg];
705
706   g1bus_regs[reg] = dat; // 5f7400+reg*4=dat
707   mame_printf_verbose("G1CTRL: [%08x=%x] write %" I64FMT "x to %x, mask %" I64FMT "x\n", 0x5f7400+reg*4, dat, data, offset, mem_mask);
708   switch (reg)
709   {
710   case SB_GDST:
711      if (dat & 1 && g1bus_regs[SB_GDEN] == 1) // 0 -> 1
712      {
713         if (g1bus_regs[SB_GDDIR] == 0)
714         {
715            printf("G1CTRL: unsupported transfer\n");
716            return;
717         }
718
719         atapi_xferbase = g1bus_regs[SB_GDSTAR];
720         atapi_timer->adjust(space->machine().device<cpu_device>("maincpu")->cycles_to_attotime((ATAPI_CYCLES_PER_SECTOR * (atapi_xferlen/2048))));
721      }
722      break;
723   }
724}
725

Previous 15994 Revisions Next


© 1998-2018 The MESS Team