Previous 15994 Revisions Next

r855 Monday 20th August, 2007 at 23:00:32 UTC by Nathan Woods
1. [3DO] Protection fixes. [Ernesto Corvi]

2. [AMIGA] Added cdrom support, marked as working but with imperfect graphics,
added CDDA audio. Bug fix to FDC. [Ernesto Corvi]
[docs]messnew.txt
[src/mess]mess.mak
[src/mess/drivers]3do.c amiga.c
[src/mess/machine]3do.c amigacd.c* amigacd.h* amigafdc.c matsucd.c* matsucd.h*

src/mess/machine/3do.c
r854r855
22#include "driver.h"
33#include "includes/3do.h"
44
5/*
6registers to be located:
7- SCOBCTL0 - Spryte engine control word
8- REGCTL0  - Modulo for reading source frame buffer data and writing spryte image data
9   bit0   G1 = 32 for CFBD read buffer
10   bit1   Undefined, set to 0.
11   bit2   G1 = 256 for CFBD read buffer
12   bit3   G1 = 1024 for CFBD read buffer
13   bit4   G2 = 64 for CFBD read buffer
14   bit5   G2 = 128 for CFBD read buffer
15   bit6   G2 = 256 for CFBD read buffer
16   bit7   Undefined, set to 0.
17   bit8   G1 = 32 for destination buffer
18   bit9   Undefined, set to 0.
19   bit10   G1 = 256 for destination buffer
20   bit11   G1 = 1024 for destination buffer
21   bit12   G2 = 64 for destination buffer
22   bit13   G2 = 128 for destination buffer
23   bit14   G2 = 256 for destination buffer
24   bit15   Undefined, set to 0
25- REGCTL1   - X and Y clip values
26   bit26-16   - max Y
27   bit10-0      - max x
28- REGCTL2   - Read base address. Address of the upper left corner pixel of the source frame buffer.
29- REGCTL3   - Write base address. Address of the upper left corner pixel of the destination buffer.
30- XYPOSH
31- XYPOSL
32- DXYH
33- DXYL
34- DDXYH
35- DDXYL
36- PPMPC
37- pixel count register
38
39Spryte engine uses 8 DMA registers:
40- 0 = current scob address
41- 1 = next scob address
42- 2 = pip address
43- 3 = spryte base address
44- 4 = engine a fetch address
45- 5 = engine a length
46- 6 = engine b fetch address
47- 7 = engine b length
48
49Sprite engine registers:
50- SPRSTRT   - Start spryte engine (sets Spryte-ON flipflop)
51- SPRSTOP   - Stop spryte engine, everything gets reset.
52- SPRPAUS   - Pause spryte engine when it's done with the current spryte (sets pause flipflop).
53- SPRCNTU   - Continue after pause of spryte engine.
54When interrupt is present, pause flipflop is set
55*/
56
575typedef struct {
586   UINT32   revision;
597   UINT32   memory_configuration;
r854r855
6311   UINT32   dummy;
6412} CLIO;
6513
66static UINT32   unk_318_data_0 = 0;
14//static UINT32   unk_318_data_0 = 0;
6715static MADAM   madam;
6816static CLIO      clio;
6917
r854r855
12270*/
12371READ32_HANDLER( unk_318_r ) {
12472   logerror( "%08X: UNK_318 read offset = %08X\n", activecpu_get_pc(), offset );
73#if 0
12574   switch( offset ) {
12675   case 0:      /* Boot ROM checks here and expects to read 1, 0, 1, 0 in the lowest bit */
12776      unk_318_data_0 ^= 1;
12877      return unk_318_data_0;
12978   }
79#endif
13080   return 0;
13181}
13282
133WRITE32_HANDLER( unk_318_w ) {
83WRITE32_HANDLER( unk_318_w )
84{
13485   logerror( "%08X: UNK_318 write offset = %08X, data = %08X, mask = %08X\n", activecpu_get_pc(), offset, data, mem_mask );
135   switch( offset ) {
136   case 0:      /* Boot ROM writes 03180000 here and then starts reading some things */
86
87   switch( offset )
88   {
89      case 0:      /* Boot ROM writes 03180000 here and then starts reading some things */
90      {
91         /* disable ROM overlay */
92         memory_set_bank(1, 0);
93      }
13794      break;
13895   }
13996}
14097
14198
142/*
143  I think this is the spryte engine - WP
144 */
99
145100READ32_HANDLER( vram_sport_r ) {
146101   logerror( "%08X: VRAM SPORT read offset = %08X\n", activecpu_get_pc(), offset );
147102   switch( offset ) {
r854r855
189144   }
190145}
191146
192void madam_init( void ) {
147void madam_init( void )
148{
193149   memset( &madam, 0, sizeof(MADAM) );
194150   madam.revision = 0x00000001;
195151}
196152
197153
198READ32_HANDLER( clio_r ) {
154READ32_HANDLER( clio_r )
155{
199156   logerror( "%08X: CLIO read offset = %08X\n", activecpu_get_pc(), offset );
157   
158   switch( offset )
159   {
160      case 0x0a: return 0x40; break;
161      case 0x0d:
162      {
163         static UINT32 irq_sequence[3] = { 0, 4, 12 };
164         static int counter = 0;
165         
166         return irq_sequence[(counter++)%3];
167      }
168      break;
169   }
200170   return 0;
201171}
202172
203WRITE32_HANDLER( clio_w ) {
173WRITE32_HANDLER( clio_w )
174{
204175   logerror( "%08X: CLIO write offset = %08X, data = %08X, mask = %08X\n", activecpu_get_pc(), offset, data, mem_mask );
205   switch( offset ) {
206   case 0x0A:   /* 03400028 - bits 0,1, and 6 are tested (irq sources?) */
176   
177   switch( offset )
178   {
179      case 0x0A:   /* 03400028 - bits 0,1, and 6 are tested (irq sources?) */
207180      break;
208   case 0x0B:   /* 0340002C - ?? during boot 0000000B is written here counter reload related?? */
181     
182      case 0x0B:   /* 0340002C - ?? during boot 0000000B is written here counter reload related?? */
209183      break;
184     
185      case 0x88:   /* set timer frequency */
186         
187      break;
210188   }
211189}
212190
213void clio_init( void ) {
191void clio_init( void )
192{
214193   memset( &clio, 0, sizeof(CLIO) );
215194}
216195
src/mess/machine/amigacd.c
r0r855
1/***************************************************************************
2 
3   Amiga cdrom controller emulation
4   
5Notes:
6Many thanks to Toni Willem for all the help and information about the
7DMAC controller.
8 
9***************************************************************************/
10 
11#include "mame.h"
12#include "driver.h"
13#include "amiga.h"
14#include "amigacd.h"
15#include "machine/6526cia.h"
16#include "machine/wd33c93.h"
17#include "tpi6525.h"
18#include "matsucd.h"
19 
20#define VERBOSE_DMAC 0
21 
22#if VERBOSE_DMAC
23#define LOG logerror
24#else
25INLINE void dummy_log( const char *a, ... ) {}
26#define LOG dummy_log
27#endif
28 
29/* constants */
30#define CD_SECTOR_TIME      (1000/((300*1024)/2048))   /* 2X CDROM sector time in msec (300KBps) */
31 
32/***************************************************************************
33 
34   DMAC
35   
36***************************************************************************/
37 
38/*
39 * value to go into DAWR
40 */
41#define DAWR_ATZSC      3       /* according to A3000T service-manual */
42 
43/*
44 * bits defined for CNTR
45 */
46#define CNTR_TCEN       (1<<7)  /* Terminal Count Enable */
47#define CNTR_PREST      (1<<6)  /* Perp Reset (not implemented :-((( ) */
48#define CNTR_PDMD       (1<<5)  /* Perp Device Mode Select (1=SCSI,0=XT/AT) */
49#define CNTR_INTEN      (1<<4)  /* Interrupt Enable */
50#define CNTR_DDIR       (1<<3)  /* Device Direction. 1==rd host, wr to perp */
51 
52/*
53 * bits defined for ISTR
54 */
55#define ISTR_INTX       (1<<8)  /* XT/AT Interrupt pending */
56#define ISTR_INT_F      (1<<7)  /* Interrupt Follow */
57#define ISTR_INTS       (1<<6)  /* SCSI Peripheral Interrupt */
58#define ISTR_E_INT      (1<<5)  /* End-Of-Process Interrupt */
59#define ISTR_INT_P      (1<<4)  /* Interrupt Pending */
60#define ISTR_UE_INT     (1<<3)  /* Under-Run FIFO Error Interrupt */
61#define ISTR_OE_INT     (1<<2)  /* Over-Run FIFO Error Interrupt */
62#define ISTR_FF_FLG     (1<<1)  /* FIFO-Full Flag */
63#define ISTR_FE_FLG     (1<<0)  /* FIFO-Empty Flag */
64 
65typedef struct
66{
67   UINT16      istr;      /* Interrupt Status Register (R) */
68    UINT16      cntr;      /* Control Register (RW) */
69   UINT32      wtc;      /* Word Transfer Count Register (RW) */
70   UINT32      acr;      /* Address Count Register (RW) */
71   UINT16      dawr;      /* DACK Width Register (W) */
72   mame_timer *dma_timer;
73} _dmac_data;
74 
75static _dmac_data dmac_data;
76 
77static void check_interrupts( void )
78{
79   /* if interrupts are disabled, bail */
80   if ( (dmac_data.cntr & CNTR_INTEN) == 0 )
81      return;
82   
83   /* if no interrupts are pending, bail */
84   if ( (dmac_data.istr & ISTR_INT_P) == 0 )
85      return;
86   
87   /* otherwise, generate the IRQ */
88   amiga_custom_w(REG_INTREQ, 0x8000 | INTENA_PORTS, 0);
89}
90 
91static TIMER_CALLBACK(dmac_dma_proc)
92{
93   while( dmac_data.wtc > 0 )
94   {
95      UINT16   dat16;
96      UINT8   dat8;
97       
98      if ( matsucd_get_next_byte( &dat8 ) < 0 )
99         break;
100       
101      dat16 = dat8;
102               
103      if ( matsucd_get_next_byte( &dat8 ) < 0 )
104         break;
105       
106      dat16 <<= 8;
107      dat16 |= dat8;
108       
109      amiga_chip_ram_w(dmac_data.acr, dat16);
110       
111      dmac_data.acr += 2;
112      dmac_data.wtc--;
113   }
114   
115   if ( dmac_data.wtc > 0 )
116   {
117      matsucd_read_next_block();
118      mame_timer_adjust( dmac_data.dma_timer, MAME_TIME_IN_MSEC( CD_SECTOR_TIME ), 0, time_zero );
119   }
120   else
121   {
122      dmac_data.istr |= ISTR_INT_P | ISTR_E_INT;
123      check_interrupts();
124   }
125}
126 
127static READ16_HANDLER( amiga_dmac_r )
128{
129   offset &= 0xff;
130 
131   switch( offset )
132   {
133      case 0x20:
134      {
135         UINT8   v = dmac_data.istr;
136         LOG( "DMAC: PC=%08x - ISTR Read(%04x)\n", activecpu_get_pc(), dmac_data.istr );
137         
138         dmac_data.istr &= ~0x0f;
139         return v;
140      }
141      break;
142       
143      case 0x21:
144      {
145         LOG( "DMAC: PC=%08x - CNTR Read(%04x)\n", activecpu_get_pc(), dmac_data.cntr );
146         return dmac_data.cntr;
147      }
148      break;
149       
150      case 0x40:   /* wtc hi */
151      {
152         LOG( "DMAC: PC=%08x - WTC HI Read\n", activecpu_get_pc() );
153         return (dmac_data.wtc >> 16);
154      }
155      break;
156         
157      case 0x41:   /* wtc lo */
158      {
159         LOG( "DMAC: PC=%08x - WTC LO Read\n", activecpu_get_pc() );
160         return dmac_data.wtc;
161      }
162      break;
163       
164      case 0x42:   /* acr hi */
165      {
166         LOG( "DMAC: PC=%08x - ACR HI Read\n", activecpu_get_pc() );
167         return (dmac_data.acr >> 16);
168      }
169      break;
170         
171      case 0x43:   /* acr lo */
172      {
173         LOG( "DMAC: PC=%08x - ACR LO Read\n", activecpu_get_pc() );
174         return dmac_data.acr;
175      }
176      break;
177 
178      case 0x48:   /* wd33c93 SCSI expansion */
179      case 0x49:
180      {
181         LOG( "DMAC: PC=%08x - WD33C93 Read(%d)\n", activecpu_get_pc(), offset & 1 );
182         return 0x00;   /* Not available without SCSI expansion */
183      }
184      break;
185       
186      case 0x50:
187      {
188         LOG( "DMAC: PC=%08x - CDROM RESP Read\n", activecpu_get_pc() );
189         return matsucd_response_r();
190      }
191      break;
192       
193      case 0x51:   /* XT IO */
194      case 0x52:
195      case 0x53:
196      {
197         LOG( "DMAC: PC=%08x - XT IO Read(%d)\n", activecpu_get_pc(), (offset & 3)-1 );
198         return 0xff;
199      }
200      break;
201       
202      case 0x58:   /* TPI6525 */
203      case 0x59:
204      case 0x5A:
205      case 0x5B:
206      case 0x5C:
207      case 0x5D:
208      case 0x5E:
209      case 0x5F:
210      case 0x60:
211      case 0x61:
212      case 0x62:
213      case 0x63:
214      case 0x64:
215      case 0x65:
216      case 0x66:
217      case 0x67:
218      {
219         LOG( "DMAC: PC=%08x - TPI6525 Read(%d)\n", activecpu_get_pc(), (offset - 0x58) );
220         return tpi6525_0_port_r(offset - 0x58);
221      }
222      break;
223       
224      case 0x70:   /* DMA start strobe */
225      {
226         LOG( "DMAC: PC=%08x - DMA Start Strobe\n", activecpu_get_pc() );
227         mame_timer_adjust( dmac_data.dma_timer, MAME_TIME_IN_MSEC( CD_SECTOR_TIME ), 0, time_zero );
228      }
229      break;
230       
231      case 0x71:   /* DMA stop strobe */
232      {
233         LOG( "DMAC: PC=%08x - DMA Stop Strobe\n", activecpu_get_pc() );
234         mame_timer_reset( dmac_data.dma_timer, time_never );
235      }
236      break;
237       
238      case 0x72:   /* Clear IRQ strobe */
239      {
240         LOG( "DMAC: PC=%08x - IRQ Clear Strobe\n", activecpu_get_pc() );
241         dmac_data.istr &= ~ISTR_INT_P;
242      }
243      break;
244       
245      case 0x74:   /* Flush strobe */
246      {
247         LOG( "DMAC: PC=%08x - Flush Strobe\n", activecpu_get_pc() );
248         dmac_data.istr |= ISTR_FE_FLG;
249      }
250      break;
251             
252      default:
253         logerror( "DMAC-READ: PC=%08x, offset = %02x\n", activecpu_get_pc(), offset );
254      break;
255   }
256   
257   return 0;
258}
259 
260static WRITE16_HANDLER( amiga_dmac_w )
261{
262   offset &= 0xff;
263 
264   switch( offset )
265   {
266      case 0x21:   /* control write */
267      {
268         LOG( "DMAC: PC=%08x - CNTR Write(%04x)\n", activecpu_get_pc(), data );
269         dmac_data.cntr = data;
270         check_interrupts();
271      }
272      break;
273       
274      case 0x40:   /* wtc hi */
275      {
276         LOG( "DMAC: PC=%08x - WTC HI Write - data = %04x\n", activecpu_get_pc(), data );
277         dmac_data.wtc &= 0x0000ffff;
278         dmac_data.wtc |= ((UINT32)data) << 16;
279      }
280      break;
281         
282      case 0x41:   /* wtc lo */
283      {
284         LOG( "DMAC: PC=%08x - WTC LO Write - data = %04x\n", activecpu_get_pc(), data );
285         dmac_data.wtc &= 0xffff0000;
286         dmac_data.wtc |= data;
287      }
288      break;
289       
290      case 0x42:   /* acr hi */
291      {
292         LOG( "DMAC: PC=%08x - ACR HI Write - data = %04x\n", activecpu_get_pc(), data );
293         dmac_data.acr &= 0x0000ffff;
294         dmac_data.acr |= ((UINT32)data) << 16;
295      }
296      break;
297         
298      case 0x43:   /* acr lo */
299      {
300         LOG( "DMAC: PC=%08x - ACR LO Write - data = %04x\n", activecpu_get_pc(), data );
301         dmac_data.acr &= 0xffff0000;
302         dmac_data.acr |= data;
303      }
304      break;
305       
306      case 0x47:   /* dawr */
307      {
308         LOG( "DMAC: PC=%08x - DAWR Write - data = %04x\n", activecpu_get_pc(), data );
309         dmac_data.dawr = data;
310      }
311      break;
312       
313      case 0x48:   /* wd33c93 SCSI expansion */
314      case 0x49:
315      {
316         LOG( "DMAC: PC=%08x - WD33C93 Write(%d) - data = %04x\n", activecpu_get_pc(), offset & 1, data );
317         /* Not available without SCSI expansion */
318      }
319      break;
320       
321      case 0x50:
322      {
323         LOG( "DMAC: PC=%08x - CDROM CMD Write - data = %04x\n", activecpu_get_pc(), data );
324         matsucd_command_w( data );
325      }
326      break;
327       
328      case 0x58:   /* TPI6525 */
329      case 0x59:
330      case 0x5A:
331      case 0x5B:
332      case 0x5C:
333      case 0x5D:
334      case 0x5E:
335      case 0x5F:
336      case 0x60:
337      case 0x61:
338      case 0x62:
339      case 0x63:
340      case 0x64:
341      case 0x65:
342      case 0x66:
343      case 0x67:
344      {
345         LOG( "DMAC: PC=%08x - TPI6525 Write(%d) - data = %04x\n", activecpu_get_pc(), (offset - 0x58), data );
346         tpi6525_0_port_w(offset - 0x58, data);
347      }
348      break;
349       
350      case 0x70:   /* DMA start strobe */
351      {
352         LOG( "DMAC: PC=%08x - DMA Start Strobe\n", activecpu_get_pc() );
353         mame_timer_adjust( dmac_data.dma_timer, MAME_TIME_IN_MSEC( CD_SECTOR_TIME ), 0, time_zero );
354      }
355      break;
356       
357      case 0x71:   /* DMA stop strobe */
358      {
359         LOG( "DMAC: PC=%08x - DMA Stop Strobe\n", activecpu_get_pc() );
360         mame_timer_reset( dmac_data.dma_timer, time_never );
361      }
362      break;
363       
364      case 0x72:   /* Clear IRQ strobe */
365      {
366         LOG( "DMAC: PC=%08x - IRQ Clear Strobe\n", activecpu_get_pc() );
367         dmac_data.istr &= ~ISTR_INT_P;
368      }
369      break;
370       
371      case 0x74:   /* Flush Strobe */
372      {
373         LOG( "DMAC: PC=%08x - Flush Strobe\n", activecpu_get_pc() );
374         dmac_data.istr |= ISTR_FE_FLG;
375      }
376      break;
377       
378      default:
379         logerror( "DMAC-WRITE: PC=%08x, offset = %02x, data = %04x\n", activecpu_get_pc(), offset, data );
380      break;
381   }
382}
383 
384/***************************************************************************
385 
386   Autoconfig
387   
388***************************************************************************/
389 
390static void   dmac_install(offs_t base)
391{
392   memory_install_read16_handler(0, ADDRESS_SPACE_PROGRAM, base, base + 0xFFFF, 0, 0, amiga_dmac_r);
393   memory_install_write16_handler(0, ADDRESS_SPACE_PROGRAM, base, base + 0xFFFF, 0, 0, amiga_dmac_w);
394}
395 
396static void   dmac_uninstall(offs_t base)
397{
398   memory_install_read16_handler(0, ADDRESS_SPACE_PROGRAM, base, base + 0xFFFF, 0, 0, MRA16_UNMAP);
399   memory_install_write16_handler(0, ADDRESS_SPACE_PROGRAM, base, base + 0xFFFF, 0, 0, MWA16_UNMAP);
400}
401 
402static amiga_autoconfig_device dmac_device =
403{
404   0,            /* link into free memory list */
405   0,            /* ROM vector offset valid */
406   0,            /* multiple devices on card */
407   1,            /* number of 64k pages */
408   3,            /* product number (DMAC) */
409   0,            /* prefer 8MB address space */
410   0,            /* can be shut up */
411   0x0202,         /* manufacturers number (Commodore) */
412   0,            /* serial number */
413   0,            /* ROM vector offset */
414   NULL,         /* interrupt control read */
415   NULL,         /* interrupt control write */
416   dmac_install,   /* memory installation */
417   dmac_uninstall   /* memory uninstallation */
418};
419 
420/***************************************************************************
421 
422   TPI6525
423   
424***************************************************************************/
425 
426static int tp6525_portc_r( void )
427{
428   int   ret = 0;
429   
430   if ( (tpi6525[0].c.ddr & 0x04) == 0 ) /* if pin 2 is set to input */
431   {
432      ret |= matsucd_stch_r() ? 0x00 : 0x04;   /* read status change signal */
433   }
434   
435   if ( (tpi6525[0].c.ddr & 0x08) == 0 ) /* if pin 3 is set to input */
436      ret |= matsucd_sten_r() ? 0x08 : 0x00;   /* read enable signal */
437   
438   return ret;
439}
440 
441static void tp6525_portb_w( int data )
442{
443   if ( tpi6525[0].b.ddr & 0x01 ) /* if pin 0 is set to output */
444      matsucd_cmd_w( data & 1 ); /* write to the /CMD signal */
445   
446   if ( tpi6525[0].b.ddr & 0x02 ) /* if pin 1 is set to output */
447      matsucd_enable_w( data & 2 ); /* write to the /ENABLE signal */
448}
449 
450static mame_timer *tp6525_delayed_timer;
451 
452static TIMER_CALLBACK(tp6525_delayed_irq)
453{
454   (void)param;
455   
456   if ( (CUSTOM_REG(REG_INTREQ) & INTENA_PORTS) == 0 )
457   {
458      amiga_custom_w(REG_INTREQ, 0x8000 | INTENA_PORTS, 0);
459   }
460   else
461   {
462      mame_timer_adjust( tp6525_delayed_timer, MAME_TIME_IN_MSEC(1), 0, time_zero );
463   }
464}
465 
466static void tp6525_irq( int level )
467{
468   LOG( "TPI6525 Interrupt: level = %d\n", level);
469   
470   if ( level )
471   {
472      if ( (CUSTOM_REG(REG_INTREQ) & INTENA_PORTS) == 0 )
473      {
474         amiga_custom_w(REG_INTREQ, 0x8000 | INTENA_PORTS, 0);
475      }
476      else
477      {
478         /* we *have to* deliver the irq, so if we can't, delay it and try again later */
479         mame_timer_adjust( tp6525_delayed_timer, MAME_TIME_IN_MSEC(1), 0, time_zero );
480      }
481   }
482}
483 
484static void cdrom_status_enabled( int level )
485{
486   /* PC3 on the 6525 */
487   tpi6525_0_irq3_level( level );
488}
489 
490static void cdrom_status_change( int level )
491{
492   /* invert */
493   level = level ? 0 : 1;
494   
495   /* PC2 on the 6525 */
496   tpi6525_0_irq2_level( level );
497}
498 
499static void cdrom_subcode_ready( int level )
500{
501   /* PC1 on the 6525 */
502   tpi6525_0_irq1_level( level );
503}
504 
505void amigacd_init( void )
506{
507   /* initialize the dmac */
508   memset( &dmac_data, 0, sizeof( dmac_data ) );
509   
510   dmac_data.dma_timer = mame_timer_alloc(dmac_dma_proc);
511   tp6525_delayed_timer = mame_timer_alloc(tp6525_delayed_irq);
512   
513   /* initialize the 6525 TPI */
514   tpi6525_0_reset();
515   
516   tpi6525[0].a.read = NULL;
517   tpi6525[0].b.read = NULL;
518   tpi6525[0].c.read = tp6525_portc_r;
519   
520   tpi6525[0].a.output = NULL;
521   tpi6525[0].b.output = tp6525_portb_w;
522   tpi6525[0].c.output = NULL;
523   
524   tpi6525[0].interrupt.output = tp6525_irq;
525   tpi6525[0].ca.output = NULL;
526   tpi6525[0].cb.output = NULL;
527   
528   /* initialize the cdrom */
529   matsucd_init();
530   matsucd_set_status_enabled_callback( cdrom_status_enabled );
531   matsucd_set_status_changed_callback( cdrom_status_change );
532   matsucd_set_subcode_ready_callback( cdrom_subcode_ready );
533   
534   /* set up DMAC with autoconfig */
535   amiga_add_autoconfig( &dmac_device );
536}
src/mess/machine/amigacd.h
r0r855
1#ifndef AMIGACD_H
2#define AMIGACD_H
3 
4void amigacd_init( void );
5 
6#endif /* AMIGACD_H */
src/mess/machine/amigafdc.c
r854r855
370370
371371   if ( drive == -1 ) {
372372      logerror("Disk DMA started with no drive selected!\n" );
373      amiga_custom_w(REG_INTREQ, 0x8000 | INTENA_DSKBLK, 0);
373374      return;
374375   }
375376   
src/mess/machine/matsucd.c
r0r855
1/***************************************************************************
2 
3   Matsushita/Panasonic CDR521/522 type CDROM drive emulation
4   
5Notes:
6This version implements the drive found in Amiga CDTV. There are
7different drives supporting this command-set (look in the sbpcd driver
8in Linux for examples). Most drives support the exact same command
9structure, but the command numbers differ. Eventually this driver
10can be expanded with support for the other drives as needed.
11 
12***************************************************************************/
13 
14#include "mame.h"
15#include "driver.h"
16#include "devices/chd_cd.h"
17#include "sound/cdda.h"
18 
19 
20#define MATSU_STATUS_READY      ( 1 << 0 )   /* driver ready */
21#define MATSU_STATUS_DOORLOCKED   ( 1 << 1 )   /* door locked */
22#define MATSU_STATUS_PLAYING   ( 1 << 2 )   /* drive playing */
23#define MATSU_STATUS_SUCCESS   ( 1 << 3 )   /* last command was succesful */
24#define MATSU_STATUS_ERROR      ( 1 << 4 )   /* last command failed */
25#define MATSU_STATUS_MOTOR      ( 1 << 5 )   /* spinning */
26#define MATSU_STATUS_MEDIA      ( 1 << 6 )   /* media present (in caddy or tray) */
27#define MATSU_STATUS_DOORCLOSED   ( 1 << 7 )   /* tray status */
28 
29typedef struct
30{
31   UINT8   enabled;      /* /ENABLE - Unit enabled */
32   UINT8   cmd_signal;      /* /CMD - Command mode    */
33   UINT8   stch_signal;   /* /STCH - Status Changed */
34   UINT8   sten_signal;   /* /STEN - Status Enabled */
35   UINT8   scor_signal;   /* /STEN - Subcode Ready */
36   UINT8   input[16];
37   UINT8   input_pos;
38   UINT8   output[16];
39   UINT8   output_pos;
40   UINT8   output_len;
41   UINT8   status;
42   UINT8   motor;
43   UINT16   sector_size;
44   UINT32   lba;
45   UINT16   num_blocks;
46   UINT16   xfer_offset;
47   UINT8   sector_buffer[CD_MAX_SECTOR_DATA];
48   UINT8   cdda_set;
49   void (*sten_cb)( int level );   /* Status enabled callback */
50   void (*stch_cb)( int level );   /* Status changed callback */
51   void (*scor_cb)( int level );   /* Subcode ready callback */
52   cdrom_file *cdrom;
53   mame_timer *frame_timer;
54} matsucd;
55 
56static matsucd cd;
57 
58#define MSF2LBA(msf) (((msf >> 16) & 0xff) * 60 * 75 + ((msf >> 8) & 0xff) * 75 + ((msf >> 0) & 0xff))
59#define LBA2MSF(lba) (((lba / (75 * 60)) << 16) | (((lba / 75) % 60) << 8) | (lba % 75))
60 
61static TIMER_CALLBACK(matsu_subcode_proc);
62 
63void matsucd_init( void )
64{
65   memset(&cd, 0, sizeof( matsucd ) );
66   
67   cd.cdrom = mess_cd_get_cdrom_file_by_number(0);
68   
69   cd.frame_timer = mame_timer_alloc(matsu_subcode_proc);
70   
71   cd.stch_signal = 1;
72}
73 
74void matsucd_set_status_enabled_callback( void (*sten_cb)( int level ) )
75{
76   /* add the callback for status enabled signal */
77   cd.sten_cb = sten_cb;
78}
79 
80void matsucd_set_status_changed_callback( void (*stch_cb)( int level ) )
81{
82   /* add the callback for status changed signal */
83   cd.stch_cb = stch_cb;
84}
85 
86void matsucd_set_subcode_ready_callback( void (*scor_cb)( int level ) )
87{
88   /* add the callback for subcode ready signal */
89   cd.scor_cb = scor_cb;
90}
91 
92static int matsucd_getsector_type( void )
93{
94   switch( cd.sector_size )
95   {
96      case 2048: return CD_TRACK_MODE1; break;
97      case 2324: return CD_TRACK_MODE2_FORM2; break;
98      case 2336: return CD_TRACK_MODE2; break;
99      case 2352: return CD_TRACK_MODE2_RAW; break;
100       
101      default: logerror( "MATSUCD: Sector size %d unsupported!\n", cd.sector_size ); break;
102   }
103   
104   return CD_TRACK_RAW_DONTCARE;
105}
106 
107void matsucd_read_next_block( void )
108{
109   cd.xfer_offset = 0;
110   
111   if ( cd.num_blocks )
112   {
113      cd.lba++;
114      cd.num_blocks--;
115       
116      if (!cdrom_read_data(cd.cdrom, cd.lba, cd.sector_buffer, matsucd_getsector_type()))
117      {
118         logerror( "MATSUCD - Warning: Read error on CD!\n" );
119      }
120   }
121}
122 
123int matsucd_get_next_byte( UINT8 *data )
124{
125   /* no more data to read on this sector */
126   if ( cd.xfer_offset >= cd.sector_size )
127      return -1;
128   
129   if ( data )
130      *data = cd.sector_buffer[cd.xfer_offset++];
131   
132   return 0;   
133}
134 
135static void matsucd_cdda_stop( void )
136{
137   int cddanum = cdda_num_from_cdrom(cd.cdrom);
138   
139   if (cddanum != -1)
140   {
141      cdda_stop_audio(cddanum);
142      mame_timer_reset( cd.frame_timer, time_never );
143   }
144}
145 
146static void matsucd_cdda_play( UINT32 lba, UINT32 num_blocks )
147{
148   int cddanum = cdda_num_from_cdrom(cd.cdrom);
149   if (cddanum != -1)
150   {
151      cdda_start_audio(cddanum, lba, num_blocks);
152      mame_timer_adjust( cd.frame_timer, MAME_TIME_IN_HZ( 75 ), 0, time_zero );
153   }
154}
155 
156static void matsucd_cdda_pause( int pause )
157{
158   int cddanum = cdda_num_from_cdrom(cd.cdrom);
159   if (cddanum != -1)
160   {
161      cdda_pause_audio(cddanum, pause);
162       
163      if ( pause )
164      {
165         mame_timer_reset( cd.frame_timer, time_never );
166      }
167      else
168      {
169         mame_timer_adjust( cd.frame_timer, MAME_TIME_IN_HZ( 75 ), 0, time_zero );
170      }
171   }
172}
173 
174static UINT8 matsucd_cdda_getstatus( UINT32 *lba )
175{
176   int cddanum = cdda_num_from_cdrom(cd.cdrom);
177   
178   if ( lba ) *lba = 0;
179   
180   if (cddanum != -1)
181   {
182      if (cdda_audio_active(cddanum))
183      {
184         if ( lba ) *lba = cdda_get_audio_lba(cddanum);
185             
186         if (cdda_audio_paused(cddanum))
187         {
188            return 0x12;   /* audio paused */
189         }
190         else
191         {
192            return 0x11;   /* audio in progress */
193         }
194      }
195      else if (cdda_audio_ended(cddanum))
196      {
197         return 0x13;   /* audio ended */
198      }
199   }
200   
201   return 0x15;   /* no audio status */
202}
203 
204void matsucd_enable_w( int level )
205{
206   cd.enabled = ( level ) ? 0 : 1;
207}
208 
209void matsucd_cmd_w( int level )
210{
211   cd.cmd_signal = ( level ) ? 0 : 1;
212}
213 
214int matsucd_stch_r( void )
215{
216   return cd.stch_signal ? 0 : 1;
217}
218 
219int matsucd_sten_r( void )
220{
221   return cd.sten_signal ? 0 : 1;
222}
223 
224int matsucd_scor_r( void )
225{
226   return cd.scor_signal ? 0 : 1;
227}
228 
229static void update_status_enable( int level )
230{
231   cd.sten_signal = level;
232   
233   if ( cd.sten_cb )
234   {
235      (*cd.sten_cb)(cd.sten_signal);
236   }
237}
238 
239static void update_status_changed( int level )
240{
241   cd.stch_signal = level;
242   
243   if ( cd.stch_cb )
244   {
245      (*cd.stch_cb)(cd.stch_signal);
246   }
247}
248 
249static void update_subcode_ready( int level )
250{
251   cd.scor_signal = level;
252   
253   if ( cd.scor_cb )
254   {
255      (*cd.scor_cb)(cd.scor_signal);
256   }
257}
258 
259static TIMER_CALLBACK(matsucd_set_status_end)
260{
261   update_status_changed( 1 );
262}
263 
264static void matsucd_set_status( UINT8 status )
265{
266   if ( status != cd.status )
267   {
268      cd.status = status;
269       
270      if ( cd.stch_signal != 0 )
271      {
272         update_status_changed( 0 );
273         mame_timer_set( MAME_TIME_IN_MSEC(1), 0, matsucd_set_status_end );
274      }
275   }
276}
277 
278static TIMER_CALLBACK(matsu_subcode_proc)
279{
280   int cddanum = cdda_num_from_cdrom(cd.cdrom);
281   
282   (void)param;
283   
284   if (cddanum != -1)
285   {
286      UINT8   s = matsucd_cdda_getstatus(NULL);
287      UINT8   newstatus = cd.status;
288       
289      if ( s == 0x11 || s == 0x12 )
290      {
291         if ( s == 0x11 )
292         {
293            update_subcode_ready( 1 );
294            update_subcode_ready( 0 );
295         }
296         
297         newstatus |= MATSU_STATUS_PLAYING;
298         
299         mame_timer_adjust( cd.frame_timer, MAME_TIME_IN_HZ( 75 ), 0, time_zero );
300      }
301      else
302      {
303         newstatus &= ~MATSU_STATUS_PLAYING;
304      }
305       
306      matsucd_set_status( newstatus );
307   }
308}
309 
310static void matsucd_command_error( void )
311{
312   UINT8   newstatus = cd.status;
313       
314   newstatus &= ~MATSU_STATUS_SUCCESS;
315   newstatus |= MATSU_STATUS_ERROR;
316   
317   matsucd_set_status( newstatus );
318}
319 
320static void matsucd_complete_cmd( UINT8 len )
321{
322   UINT8   newstatus = cd.status;
323   
324   cd.input_pos = 0;
325   cd.output_pos = 0;
326   cd.output_len = len;
327   
328   newstatus &= ~MATSU_STATUS_ERROR;
329   newstatus |= MATSU_STATUS_SUCCESS;
330   
331   matsucd_set_status( newstatus );
332   
333   update_status_enable( 1 );
334   update_status_enable( 0 );
335}
336 
337UINT8 matsucd_response_r( void )
338{
339   UINT8   v = cd.output[cd.output_pos++];
340   
341   if ( cd.output_pos < cd.output_len )
342   {
343      update_status_enable( 1 );
344      update_status_enable( 0 );
345   }
346   
347   return v;
348}
349 
350void matsucd_command_w( UINT8 data )
351{
352   UINT8   cmd;
353   
354   /* make sure we're enabled */
355   if ( cd.enabled == 0 )
356      return;
357   
358   /* make sure /CMD is asserted */
359   if ( cd.cmd_signal == 0 )
360      return;
361   
362   if ( cd.cdda_set == 0 )
363   {
364      if ( cd.cdrom )
365         cdda_set_cdrom(0, cd.cdrom);
366       
367      cd.cdda_set = 1;
368   }
369   
370   cd.input[cd.input_pos++] = data;
371 
372   cmd = cd.input[0];
373   
374   switch( cmd )
375   {
376      case 0x01:   /* seek */
377      {
378         if ( cd.input_pos < 7 )
379            return;
380             
381         /* stop CDDA audio if necessary */
382         matsucd_cdda_stop();
383         
384         cd.motor = 1;
385                   
386         memset( cd.output, 0, 6 );
387         matsucd_complete_cmd( 0 );
388      }
389      break;
390       
391      case 0x02:   /* read sectors */
392      {
393         if ( cd.input_pos < 7 )
394            return;
395         
396         /* stop CDDA audio if necessary */
397         matsucd_cdda_stop();
398             
399         /* LBA */
400         cd.lba = cd.input[1];
401         cd.lba <<= 8;
402         cd.lba |= cd.input[2];
403         cd.lba <<= 8;
404         cd.lba |= cd.input[3];
405         
406         /* Number of blocks */
407         cd.num_blocks = cd.input[4];
408         cd.num_blocks <<= 8;
409         cd.num_blocks |= cd.input[5];
410         
411         /* Reset transfer count */
412         cd.xfer_offset = 0;
413         
414         /* go ahead and cache the first block */
415         if (!cdrom_read_data(cd.cdrom, cd.lba, cd.sector_buffer, matsucd_getsector_type()))
416         {
417            logerror( "MATSUCD - Warning: Read error on CD!\n" );
418            matsucd_command_error();
419            return;
420         }
421         
422         cd.motor = 1;
423                   
424         memset( cd.output, 0, 6 );
425         matsucd_complete_cmd( 0 );
426      }
427      break;
428       
429      case 0x04:   /* motor on */
430      {
431         if ( cd.input_pos < 7 )
432            return;
433             
434         cd.motor = 1;
435                   
436         memset( cd.output, 0, 6 );
437         matsucd_complete_cmd( 0 );
438      }
439      break;
440       
441      case 0x05:   /* motor off */
442      {
443         if ( cd.input_pos < 7 )
444            return;
445             
446         /* stop CDDA audio if necessary */
447         matsucd_cdda_stop();
448         
449         cd.motor = 0;
450                   
451         memset( cd.output, 0, 6 );
452         matsucd_complete_cmd( 0 );
453      }
454      break;
455       
456      case 0x09:   /* play audio cd, LBA mode */
457      {
458         UINT32   lba, numblocks;
459         
460         if ( cd.input_pos < 7 )
461            return;
462         
463         lba = cd.input[1];
464         lba <<= 8;
465         lba |= cd.input[2];
466         lba <<= 8;
467         lba |= cd.input[3];
468         
469         numblocks = cd.input[4];
470         numblocks <<= 8;
471         numblocks |= cd.input[5];
472         numblocks <<= 8;
473         numblocks |= cd.input[6];
474         
475         matsucd_cdda_play( lba, numblocks );
476         
477         cd.motor = 1;
478                   
479         memset( cd.output, 0, 6 );
480         matsucd_complete_cmd( 0 );
481      }
482      break;
483       
484      case 0x0a:   /* play audio cd, MSF mode */
485      {
486         UINT32   start, end, lba_start, lba_end;
487         
488         if ( cd.input_pos < 7 )
489            return;
490         
491         start = cd.input[1];
492         start <<= 8;
493         start |= cd.input[2];
494         start <<= 8;
495         start |= cd.input[3];
496         
497         end = cd.input[4];
498         end <<= 8;
499         end |= cd.input[5];
500         end <<= 8;
501         end |= cd.input[6];
502         
503         lba_start = MSF2LBA( start );
504         lba_end = MSF2LBA( end );
505         
506         if ( end == 0xffffff )
507         {
508            lba_end = cdrom_get_track_start(cd.cdrom,cdrom_get_last_track(cd.cdrom)-1);
509            lba_end += cdrom_get_toc(cd.cdrom)->tracks[cdrom_get_last_track(cd.cdrom)-1].frames;
510         }
511         
512         if ( lba_end <= lba_start )
513         {
514            matsucd_cdda_stop();
515         }
516         else
517         {
518            matsucd_cdda_play( lba_start, lba_end - lba_start );
519            cd.motor = 1;
520         }
521         
522         memset( cd.output, 0, 6 );
523         matsucd_complete_cmd( 0 );
524      }
525      break;
526       
527      case 0x0b:   /* play audio track and index */
528      {
529         UINT8   track_start = cd.input[1];
530         UINT8   index_start = cd.input[2];
531         UINT8   track_end = cd.input[3];
532         UINT8   index_end = cd.input[4];
533         UINT32   lba_start, lba_end;
534         
535         /* TODO: Add index support once the CDDA engine supports it */
536         (void)index_start;
537         (void)index_end;
538         
539         /* sanitize values */
540         if ( track_start == 0 ) track_start++;
541         if ( track_end > cdrom_get_last_track(cd.cdrom) )
542            track_end = cdrom_get_last_track(cd.cdrom);
543 
544         /* find the start and stop positions */
545         lba_start = cdrom_get_track_start(cd.cdrom,track_start-1);
546         lba_end = cdrom_get_track_start(cd.cdrom,track_end-1);
547         
548         lba_end += cdrom_get_toc(cd.cdrom)->tracks[track_end-1].frames;
549         
550         if ( lba_end <= lba_start )
551         {
552            matsucd_cdda_stop();
553         }
554         else
555         {
556            matsucd_cdda_play( lba_start, lba_end - lba_start );
557            cd.motor = 1;
558         }
559         
560         memset( cd.output, 0, 6 );
561         matsucd_complete_cmd( 0 );
562      }
563      break;
564       
565      case 0x81:   /* status read */
566      {
567         UINT8   newstatus = cd.status;
568         
569         newstatus &= MATSU_STATUS_SUCCESS | MATSU_STATUS_ERROR | MATSU_STATUS_PLAYING;
570         newstatus |= MATSU_STATUS_READY;
571         
572         if (cd.cdrom)
573         {
574            newstatus |= MATSU_STATUS_MEDIA;
575         }
576         
577         if (cd.motor)
578            newstatus |= MATSU_STATUS_MOTOR;
579         
580         cd.output[0] = newstatus;
581         
582         matsucd_set_status( newstatus );
583         
584         matsucd_complete_cmd( 1 );
585      }
586      break;
587       
588      case 0x82:   /* error read */
589      {
590         if ( cd.input_pos < 7 )
591            return;
592         
593         memset( cd.output, 0, 6 );
594         matsucd_complete_cmd( 6 );
595      }
596      break;
597       
598      case 0x84:   /* set mode */
599      {
600         if ( cd.input_pos < 7 )
601            return;
602             
603         cd.sector_size = cd.input[2];
604         cd.sector_size <<= 8;
605         cd.sector_size |= cd.input[3];
606         
607         memset( cd.output, 0, 6 );
608         matsucd_complete_cmd( 0 );
609      }
610      break;
611       
612      case 0x87:   /* read SUBQ */
613      {
614         int      msfmode;
615         UINT32   lba;
616         UINT8   track;
617                   
618         if ( cd.input_pos < 7 )
619            return;
620         
621         msfmode = (cd.input[1] & 0x02) ? 1 : 0;
622             
623         memset( cd.output, 0, 13 );
624         
625         cd.output[0] = matsucd_cdda_getstatus( &lba );
626         
627         if ( lba > 0 )
628         {
629            UINT32   disk_pos;
630            UINT32   track_pos;
631             
632            track = cdrom_get_track(cd.cdrom, lba);
633                   
634            cd.output[1] = cdrom_get_adr_control(cd.cdrom, track);
635            cd.output[2] = track+1;
636            cd.output[3] = 0; /* index */
637         
638            disk_pos = lba;
639            if ( msfmode ) disk_pos = LBA2MSF(disk_pos);
640               
641            cd.output[4] = (disk_pos >> 24) & 0xff;
642            cd.output[5] = (disk_pos >> 16) & 0xff;
643            cd.output[6] = (disk_pos >> 8) & 0xff;
644            cd.output[7] = (disk_pos) & 0xff;
645         
646            track_pos = lba - cdrom_get_track_start(cd.cdrom, track);
647            if ( msfmode ) track_pos = LBA2MSF(track_pos);
648         
649            cd.output[8] = (track_pos >> 24) & 0xff;
650            cd.output[9] = (track_pos >> 16) & 0xff;
651            cd.output[10] = (track_pos >> 8) & 0xff;
652            cd.output[11] = (track_pos) & 0xff;
653         
654            /* TODO: UPC flag at offset 12 */
655            cd.output[12] = 0;
656         }
657         
658         matsucd_complete_cmd( 13 );
659      }
660      break;
661       
662      case 0x89:   /* read disk info */
663      {
664         UINT32   end;
665         
666         if ( cd.input_pos < 7 )
667            return;
668         
669         memset( cd.output, 0, 5 );
670         
671         cd.output[0] = cdrom_get_last_track(cd.cdrom) ? 1 : 0;
672         cd.output[1] = cdrom_get_last_track(cd.cdrom);
673         end = cdrom_get_track_start(cd.cdrom,cd.output[1]-1);
674         end += cdrom_get_toc(cd.cdrom)->tracks[cd.output[1]-1].frames;
675         end = LBA2MSF(end);
676         cd.output[2] = (end >> 16) & 0xff;
677         cd.output[3] = (end >> 8) & 0xff;
678         cd.output[4] = (end) & 0xff;
679         
680         matsucd_complete_cmd( 5 );
681      }
682      break;
683       
684      case 0x8a:   /* read toc */
685      {
686         UINT8   track;
687         int      msfmode;
688         UINT32   track_start;
689         
690         if ( cd.input_pos < 7 )
691            return;
692         
693         /* stop CDDA audio if necessary */
694         matsucd_cdda_stop();
695                   
696         track = cd.input[2];
697         msfmode = (cd.input[1] & 0x02) ? 1 : 0;
698             
699         if ( cd.cdrom == NULL )
700         {
701            logerror( "MATSUCD - Warning: Reading TOC without a CD!\n" );
702            matsucd_command_error();
703            return;
704         }
705         
706         if ( track > cdrom_get_last_track(cd.cdrom) )
707         {
708            logerror( "MATSUCD - Warning: Reading invalid track entry from TOC!\n" );
709            matsucd_command_error();
710            return;
711         }
712         
713         memset( cd.output, 0, 7 );
714   
715         track_start = cdrom_get_track_start(cd.cdrom, track > 0 ? (track-1) : track );
716         if ( msfmode ) track_start = LBA2MSF( track_start );
717 
718         cd.output[1] = cdrom_get_adr_control(cd.cdrom, track > 0 ? (track-1) : track);
719         cd.output[2] = track;
720         cd.output[3] = (track == 0 ) ? cdrom_get_last_track(cd.cdrom) : 0;
721         cd.output[4] = (track_start >> 24) & 0xff;
722         cd.output[5] = (track_start >> 16) & 0xff;
723         cd.output[6] = (track_start >> 8) & 0xff;
724         cd.output[7] = (track_start) & 0xff;
725         
726         cd.motor = 1;
727         
728         matsucd_complete_cmd( 8 );
729      }
730      break;
731       
732      case 0x8b:   /* pause audio */
733      {
734         if ( cd.input_pos < 7 )
735            return;
736         
737         matsucd_cdda_pause( (cd.input[1] == 0) ? 1 : 0 );
738         memset( cd.output, 0, 7 );
739         matsucd_complete_cmd( 0 );
740      }
741      break;
742       
743      case 0xa3:   /* front panel */
744      {
745         if ( cd.input_pos < 7 )
746            return;
747         
748         /* TODO: ??? */
749             
750         memset( cd.output, 0, 7 );
751         matsucd_complete_cmd( 0 );
752      }
753      break;
754       
755      default:
756         logerror( "MATSUCD: Unknown/inimplemented command %08x\n", cmd );
757      break;
758   }
759}
src/mess/machine/matsucd.h
r0r855
1/***************************************************************************
2 
3   Matsushita/Panasonic CDR521/522 type CDROM drive emulation
4 
5***************************************************************************/
6 
7/* initialization */
8extern void matsucd_init( void );
9 
10/* signaling */
11extern void matsucd_enable_w( int level );   /* /ENABLE pin */
12extern void matsucd_cmd_w( int level );      /* /CMD pin */
13extern int matsucd_stch_r( void );         /* /STCH pin */
14extern int matsucd_sten_r( void );         /* /STEN pin */
15extern int matsucd_scor_r( void );         /* /SCOR pin */
16 
17/* callback for signal changes */
18extern void matsucd_set_status_enabled_callback( void (*sten_cb)( int level ) );
19extern void matsucd_set_status_changed_callback( void (*stch_cb)( int level ) );
20extern void matsucd_set_subcode_ready_callback( void (*scor_cb)( int level ) );
21 
22/* data transfer routines */
23extern void matsucd_read_next_block( void );
24extern int matsucd_get_next_byte( UINT8 *data );
25 
26/* main command interface */
27extern void matsucd_command_w( UINT8 data );
28extern UINT8 matsucd_response_r( void );
src/mess/mess.mak
r854r855
566566   $(MAME_MACHINE)/amiga.o         \
567567   $(MAME_AUDIO)/amiga.o         \
568568   $(MESS_MACHINE)/amigafdc.o   \
569   $(MESS_MACHINE)/amigacd.o   \
570   $(MESS_MACHINE)/matsucd.o   \
569571   $(MESS_MACHINE)/amigakbd.o   \
570572   $(MAME_MACHINE)/msm6242.o   \
571573   $(MESS_DRIVERS)/amiga.o      \
src/mess/drivers/3do.c
r854r855
9999/* The 3DO has an ARM6 core which is a bit different from the current
100100   ARM cpu cores. This define 'hack' can be removed once the ARM6 core
101101   is fully supported. */
102#define CPU_ARM6   CPU_ARM
102#define CPU_ARM6   CPU_ARM7
103103
104104#define X1_CLOCK      50000000
105105#define X2_CLOCK_PAL   59000000
r854r855
110110UINT32   *vram;
111111
112112static ADDRESS_MAP_START( 3do_mem, ADDRESS_SPACE_PROGRAM, 32)
113   AM_RANGE(0x00000000, 0x001FFFFF) AM_RAM AM_BASE(&dram)                     /* DRAM */
113   AM_RANGE(0x00000000, 0x001FFFFF) AM_RAMBANK(1) AM_BASE(&dram)               /* DRAM */
114114   AM_RANGE(0x00200000, 0x002FFFFF) AM_RAM   AM_BASE(&vram)                     /* VRAM */
115   AM_RANGE(0x03000000, 0x030FFFFF) AM_ROMBANK(1)                           /* BIOS */
115   AM_RANGE(0x03000000, 0x030FFFFF) AM_ROMBANK(2)                           /* BIOS */
116116   AM_RANGE(0x03140000, 0x0315FFFF) AM_READWRITE(nvarea_r, nvarea_w)            /* NVRAM */
117117   AM_RANGE(0x03180000, 0x031FFFFF) AM_READWRITE(unk_318_r, unk_318_w)            /* ???? */
118   AM_RANGE(0x03200000, 0x032FFFFF) AM_READWRITE(vram_sport_r, vram_sport_w)      /* special vram access1/spryte engine? */
118   AM_RANGE(0x03200000, 0x032FFFFF) AM_READWRITE(vram_sport_r, vram_sport_w)      /* special vram access1 */
119119   AM_RANGE(0x03300000, 0x033FFFFF) AM_READWRITE(madam_r, madam_w)               /* address decoder */
120120   AM_RANGE(0x03400000, 0x034FFFFF) AM_READWRITE(clio_r, clio_w)               /* io controller */
121121ADDRESS_MAP_END
r854r855
123123INPUT_PORTS_START( 3do )
124124INPUT_PORTS_END
125125
126MACHINE_RESET( 3do ) {
127   memory_set_bankptr( 1, memory_region( REGION_USER1 ) );
128   /* Copy BIOS ROM data to DRAM */
129   memcpy( dram, memory_region( REGION_USER1 ), memory_region_length( REGION_USER1 ) );
126MACHINE_RESET( 3do )
127{
128   memory_set_bankptr(2,memory_region(REGION_USER1));
129   
130   /* configure overlay */
131   memory_configure_bank(1, 0, 1, dram, 0);
132   memory_configure_bank(1, 1, 1, memory_region(REGION_USER1), 0);
133   
134   /* start with overlay enabled */
135   memory_set_bank(1, 1);
136
130137   madam_init();
131138   clio_init();
132139}
r854r855
166173MACHINE_DRIVER_END
167174
168175ROM_START(3do)
169   ROM_REGION( 0x100000, REGION_USER1, 0 )
176   ROM_REGION32_BE( 0x100000, REGION_USER1, 0 )
170177   ROM_SYSTEM_BIOS( 0, "panafz10", "Panasonic FZ-10 R.E.A.L. 3DO Interactive Multiplayer" )
171178   ROMX_LOAD( "panafz10.bin", 0x000000, 0x100000, CRC(58242cee) SHA1(3c912300775d1ad730dc35757e279c274c0acaad), ROM_BIOS(1) )
172179   ROM_SYSTEM_BIOS( 1, "goldstar", "Goldstar 3DO Interactive Multiplayer v1.01m" )
r854r855
180187ROM_END
181188
182189ROM_START(3do_pal)
183    ROM_REGION( 0x100000, REGION_USER1, 0 )
190    ROM_REGION32_BE( 0x100000, REGION_USER1, 0 )
184191    ROM_SYSTEM_BIOS( 0, "panafz10", "Panasonic FZ-10 R.E.A.L. 3DO Interactive Multiplayer" )
185192    ROMX_LOAD( "panafz10.bin", 0x000000, 0x100000, CRC(58242cee) SHA1(3c912300775d1ad730dc35757e279c274c0acaad), ROM_BIOS(1) )
186193    ROM_SYSTEM_BIOS( 1, "goldstar", "Goldstar 3DO Interactive Multiplayer v1.01m" )
src/mess/drivers/amiga.c
r854r855
1414If we didn't map any, then we still put a mirror, but where fast-mem
1515would commence ($C00000).
1616
17
18TODO:
19- Reverse and add the DMAC DMA/CD-ROM controller for CDTV
20
2117***************************************************************************/
2218
2319#include "driver.h"
r854r855
2622#include "includes/amiga.h"
2723#include "machine/amigafdc.h"
2824#include "machine/amigakbd.h"
25#include "machine/amigacd.h"
2926#include "machine/msm6242.h"
3027#include "devices/chd_cd.h"
3128#include "inputx.h"
r854r855
8784
8885static ADDRESS_MAP_START(cdtv_mem, ADDRESS_SPACE_PROGRAM, 16)
8986   AM_RANGE(0x000000, 0x0fffff) AM_RAMBANK(1) AM_BASE(&amiga_chip_ram) AM_SIZE(&amiga_chip_ram_size)
90   AM_RANGE(0x100000, 0x9fffff) AM_NOP
9187   AM_RANGE(0xbfd000, 0xbfefff) AM_READWRITE(amiga_cia_r, amiga_cia_w)
9288   AM_RANGE(0xdc0000, 0xdc003f) AM_READWRITE(amiga_clock_r, amiga_clock_w);
9389   AM_RANGE(0xdc8000, 0xdc87ff) AM_RAM AM_BASE(&generic_nvram16) AM_SIZE(&generic_nvram_size)
r854r855
216212   MDRV_CPU_PROGRAM_MAP(cdtv_mem, 0)
217213   
218214   MDRV_NVRAM_HANDLER(generic_0fill)
215   
216   MDRV_SOUND_ADD( CDDA, 0 )
217   MDRV_SOUND_ROUTE( 0, "left", 1.0 )
218   MDRV_SOUND_ROUTE( 1, "right", 1.0 )
219219MACHINE_DRIVER_END
220220
221221static MACHINE_DRIVER_START( a1000n )
r854r855
352352{
353353   static const amiga_machine_interface amiga_intf =
354354   {
355      FAT_ANGUS_CHIP_RAM_MASK,
355      ECS_CHIP_RAM_MASK,
356356      amiga_cia_0_portA_r, NULL,               /* CIA0 port A & B read */
357357      amiga_cia_0_portA_w, NULL,               /* CIA0 port A & B write */
358358      NULL, NULL,                              /* CIA1 port A & B read */
r854r855
370370   /* set up memory */
371371   memory_configure_bank(1, 0, 1, amiga_chip_ram, 0);
372372   memory_configure_bank(1, 1, 1, memory_region(REGION_USER1), 0);
373   
374   /* initialize the cdrom controller */
375   amigacd_init();
373376}
374377
375378/***************************************************************************
r854r855
464467COMP(  1985, a1000p,   a1000n,           0,       a1000p,  amiga,   amiga,   amiga,   "Commodore Business Machines Co.",  "Commodore Amiga 1000 (PAL-OCS)", GAME_COMPUTER | GAME_IMPERFECT_GRAPHICS )
465468COMPB( 1987, a500n,    0,       amiga,   0,       ntsc,    amiga,   amiga,   amiga,   "Commodore Business Machines Co.",  "Commodore Amiga 500 (NTSC-OCS)", GAME_COMPUTER | GAME_IMPERFECT_GRAPHICS )
466469COMPB( 1987, a500p,    a500n,   amiga,   0,       pal,     amiga,   amiga,   amiga,   "Commodore Business Machines Co.",  "Commodore Amiga 500 (PAL-OCS)", GAME_COMPUTER | GAME_IMPERFECT_GRAPHICS )
467COMP(  1991, cdtv,     0,                0,       cdtv,    amiga,   cdtv,    cdtv,    "Commodore Business Machines Co.",  "Commodore Amiga CDTV (NTSC)", GAME_NOT_WORKING )
470COMP(  1991, cdtv,     0,                0,       cdtv,    amiga,   cdtv,    cdtv,    "Commodore Business Machines Co.",  "Commodore Amiga CDTV 1.0 (NTSC)", GAME_COMPUTER | GAME_IMPERFECT_GRAPHICS )
docs/messnew.txt
r854r855
88
99System Driver Changes:
1010----------------------
11- [3DO] Protection fixes.  [Ernesto Corvi]
12
13- [AMIGA] Added cdrom support, marked as working but with imperfect graphics,
14  added CDDA audio.  Bug fix to FDC.  [Ernesto Corvi]
15 
1116- [MK1] Fixed interrupt issues and re-enabled driver.  [Wilbert Pol]
1217
1318- [X68000] Sprite fixes, made SRAM executable and added an hsync timer.  [Barry

Previous 15994 Revisions Next


© 1998-2018 The MESS Team