summaryrefslogtreecommitdiffstatshomepage
path: root/src/mess/machine/amigacd.c
diff options
context:
space:
mode:
Diffstat (limited to 'src/mess/machine/amigacd.c')
-rw-r--r--src/mess/machine/amigacd.c547
1 files changed, 0 insertions, 547 deletions
diff --git a/src/mess/machine/amigacd.c b/src/mess/machine/amigacd.c
deleted file mode 100644
index 165ecc60c60..00000000000
--- a/src/mess/machine/amigacd.c
+++ /dev/null
@@ -1,547 +0,0 @@
-/***************************************************************************
-
- Amiga CD-ROM controller emulation
-
-Notes:
-Many thanks to Toni Wilen for all the help and information about the
-DMAC controller.
-
-***************************************************************************/
-
-
-#include "emu.h"
-#include "includes/amiga.h"
-#include "amigacd.h"
-#include "machine/6525tpi.h"
-#include "imagedev/chd_cd.h"
-#include "machine/matsucd.h"
-
-
-#define VERBOSE_DMAC 0
-
-#define LOG(x) do { if (VERBOSE_DMAC) logerror x; } while (0)
-
-/* constants */
-#define CD_SECTOR_TIME (1000/((300*1024)/2048)) /* 2X CDROM sector time in msec (300KBps) */
-
-/***************************************************************************
-
- DMAC
-
-***************************************************************************/
-
-/*
- * value to go into DAWR
- */
-#define DAWR_ATZSC 3 /* according to A3000T service-manual */
-
-/*
- * bits defined for CNTR
- */
-#define CNTR_TCEN (1<<7) /* Terminal Count Enable */
-#define CNTR_PREST (1<<6) /* Perp Reset (not implemented :-((( ) */
-#define CNTR_PDMD (1<<5) /* Perp Device Mode Select (1=SCSI,0=XT/AT) */
-#define CNTR_INTEN (1<<4) /* Interrupt Enable */
-#define CNTR_DDIR (1<<3) /* Device Direction. 1==rd host, wr to perp */
-
-/*
- * bits defined for ISTR
- */
-#define ISTR_INTX (1<<8) /* XT/AT Interrupt pending */
-#define ISTR_INT_F (1<<7) /* Interrupt Follow */
-#define ISTR_INTS (1<<6) /* SCSI Peripheral Interrupt */
-#define ISTR_E_INT (1<<5) /* End-Of-Process Interrupt */
-#define ISTR_INT_P (1<<4) /* Interrupt Pending */
-#define ISTR_UE_INT (1<<3) /* Under-Run FIFO Error Interrupt */
-#define ISTR_OE_INT (1<<2) /* Over-Run FIFO Error Interrupt */
-#define ISTR_FF_FLG (1<<1) /* FIFO-Full Flag */
-#define ISTR_FE_FLG (1<<0) /* FIFO-Empty Flag */
-
-struct dmac_data_t
-{
- UINT16 istr; /* Interrupt Status Register (R) */
- UINT16 cntr; /* Control Register (RW) */
- UINT32 wtc; /* Word Transfer Count Register (RW) */
- UINT32 acr; /* Address Count Register (RW) */
- UINT16 dawr; /* DACK Width Register (W) */
- emu_timer *dma_timer;
-};
-
-static dmac_data_t dmac_data;
-
-static void check_interrupts( running_machine &machine )
-{
- amiga_state *state = machine.driver_data<amiga_state>();
-
- /* if interrupts are disabled, bail */
- if ( (dmac_data.cntr & CNTR_INTEN) == 0 )
- return;
-
- /* if no interrupts are pending, bail */
- if ( (dmac_data.istr & ISTR_INT_P) == 0 )
- return;
-
- /* otherwise, generate the IRQ */
- state->amiga_custom_w(*state->m_maincpu_program_space, REG_INTREQ, 0x8000 | INTENA_PORTS, 0xffff);
-}
-
-static TIMER_CALLBACK(dmac_dma_proc)
-{
- amiga_state *state = machine.driver_data<amiga_state>();
- while( dmac_data.wtc > 0 )
- {
- UINT16 dat16;
- UINT8 dat8;
-
- if ( matsucd_get_next_byte( &dat8 ) < 0 )
- break;
-
- dat16 = dat8;
-
- if ( matsucd_get_next_byte( &dat8 ) < 0 )
- break;
-
- dat16 <<= 8;
- dat16 |= dat8;
-
- (*state->m_chip_ram_w)(state, dmac_data.acr, dat16);
-
- dmac_data.acr += 2;
- dmac_data.wtc--;
- }
-
- if ( dmac_data.wtc > 0 )
- {
- matsucd_read_next_block();
- dmac_data.dma_timer->adjust(attotime::from_msec( CD_SECTOR_TIME ));
- }
- else
- {
- dmac_data.istr |= ISTR_INT_P | ISTR_E_INT;
- check_interrupts( machine );
- }
-}
-
-READ16_MEMBER( amiga_state::amiga_dmac_r )
-{
- offset &= 0xff;
-
- switch( offset )
- {
- case 0x20:
- {
- UINT8 v = dmac_data.istr;
- LOG(( "DMAC: PC=%08x - ISTR Read(%04x)\n", space.device().safe_pc(), dmac_data.istr ));
-
- dmac_data.istr &= ~0x0f;
- return v;
- }
- break;
-
- case 0x21:
- {
- LOG(( "DMAC: PC=%08x - CNTR Read(%04x)\n", space.device().safe_pc(), dmac_data.cntr ));
- return dmac_data.cntr;
- }
- break;
-
- case 0x40: /* wtc hi */
- {
- LOG(( "DMAC: PC=%08x - WTC HI Read\n", space.device().safe_pc() ));
- return (dmac_data.wtc >> 16);
- }
- break;
-
- case 0x41: /* wtc lo */
- {
- LOG(( "DMAC: PC=%08x - WTC LO Read\n", space.device().safe_pc() ));
- return dmac_data.wtc;
- }
- break;
-
- case 0x42: /* acr hi */
- {
- LOG(( "DMAC: PC=%08x - ACR HI Read\n", space.device().safe_pc() ));
- return (dmac_data.acr >> 16);
- }
- break;
-
- case 0x43: /* acr lo */
- {
- LOG(( "DMAC: PC=%08x - ACR LO Read\n", space.device().safe_pc() ));
- return dmac_data.acr;
- }
- break;
-
- case 0x48: /* wd33c93 SCSI expansion */
- case 0x49:
- {
- LOG(( "DMAC: PC=%08x - WD33C93 Read(%d)\n", space.device().safe_pc(), offset & 1 ));
- return 0x00; /* Not available without SCSI expansion */
- }
- break;
-
- case 0x50:
- {
- LOG(( "DMAC: PC=%08x - CDROM RESP Read\n", space.device().safe_pc() ));
- return matsucd_response_r(space.machine());
- }
- break;
-
- case 0x51: /* XT IO */
- case 0x52:
- case 0x53:
- {
- LOG(( "DMAC: PC=%08x - XT IO Read(%d)\n", space.device().safe_pc(), (offset & 3)-1 ));
- return 0xff;
- }
- break;
-
- case 0x58: /* TPI6525 */
- case 0x59:
- case 0x5A:
- case 0x5B:
- case 0x5C:
- case 0x5D:
- case 0x5E:
- case 0x5F:
- case 0x60:
- case 0x61:
- case 0x62:
- case 0x63:
- case 0x64:
- case 0x65:
- case 0x66:
- case 0x67:
- {
- tpi6525_device *tpi = space.machine().device<tpi6525_device>("tpi6525");
- LOG(( "DMAC: PC=%08x - TPI6525 Read(%d)\n", space.device().safe_pc(), (offset - 0x58) ));
- return tpi->read(space, offset - 0x58);
- }
- break;
-
- case 0x70: /* DMA start strobe */
- {
- LOG(( "DMAC: PC=%08x - DMA Start Strobe\n", space.device().safe_pc() ));
- dmac_data.dma_timer->adjust(attotime::from_msec( CD_SECTOR_TIME ));
- }
- break;
-
- case 0x71: /* DMA stop strobe */
- {
- LOG(( "DMAC: PC=%08x - DMA Stop Strobe\n", space.device().safe_pc() ));
- dmac_data.dma_timer->reset( );
- }
- break;
-
- case 0x72: /* Clear IRQ strobe */
- {
- LOG(( "DMAC: PC=%08x - IRQ Clear Strobe\n", space.device().safe_pc() ));
- dmac_data.istr &= ~ISTR_INT_P;
- }
- break;
-
- case 0x74: /* Flush strobe */
- {
- LOG(( "DMAC: PC=%08x - Flush Strobe\n", space.device().safe_pc() ));
- dmac_data.istr |= ISTR_FE_FLG;
- }
- break;
-
- default:
- logerror( "DMAC-READ: PC=%08x, offset = %02x\n", space.device().safe_pc(), offset );
- break;
- }
-
- return 0;
-}
-
-WRITE16_MEMBER( amiga_state::amiga_dmac_w )
-{
- offset &= 0xff;
-
- switch( offset )
- {
- case 0x21: /* control write */
- {
- LOG(( "DMAC: PC=%08x - CNTR Write(%04x)\n", space.device().safe_pc(), data ));
- dmac_data.cntr = data;
- check_interrupts(space.machine());
- }
- break;
-
- case 0x40: /* wtc hi */
- {
- LOG(( "DMAC: PC=%08x - WTC HI Write - data = %04x\n", space.device().safe_pc(), data ));
- dmac_data.wtc &= 0x0000ffff;
- dmac_data.wtc |= ((UINT32)data) << 16;
- }
- break;
-
- case 0x41: /* wtc lo */
- {
- LOG(( "DMAC: PC=%08x - WTC LO Write - data = %04x\n", space.device().safe_pc(), data ));
- dmac_data.wtc &= 0xffff0000;
- dmac_data.wtc |= data;
- }
- break;
-
- case 0x42: /* acr hi */
- {
- LOG(( "DMAC: PC=%08x - ACR HI Write - data = %04x\n", space.device().safe_pc(), data ));
- dmac_data.acr &= 0x0000ffff;
- dmac_data.acr |= ((UINT32)data) << 16;
- }
- break;
-
- case 0x43: /* acr lo */
- {
- LOG(( "DMAC: PC=%08x - ACR LO Write - data = %04x\n", space.device().safe_pc(), data ));
- dmac_data.acr &= 0xffff0000;
- dmac_data.acr |= data;
- }
- break;
-
- case 0x47: /* dawr */
- {
- LOG(( "DMAC: PC=%08x - DAWR Write - data = %04x\n", space.device().safe_pc(), data ));
- dmac_data.dawr = data;
- }
- break;
-
- case 0x48: /* wd33c93 SCSI expansion */
- case 0x49:
- {
- LOG(( "DMAC: PC=%08x - WD33C93 Write(%d) - data = %04x\n", space.device().safe_pc(), offset & 1, data ));
- /* Not available without SCSI expansion */
- }
- break;
-
- case 0x50:
- {
- LOG(( "DMAC: PC=%08x - CDROM CMD Write - data = %04x\n", space.device().safe_pc(), data ));
- matsucd_command_w(space.machine(), data );
- }
- break;
-
- case 0x58: /* TPI6525 */
- case 0x59:
- case 0x5A:
- case 0x5B:
- case 0x5C:
- case 0x5D:
- case 0x5E:
- case 0x5F:
- case 0x60:
- case 0x61:
- case 0x62:
- case 0x63:
- case 0x64:
- case 0x65:
- case 0x66:
- case 0x67:
- {
- tpi6525_device *tpi = space.machine().device<tpi6525_device>("tpi6525");
- LOG(( "DMAC: PC=%08x - TPI6525 Write(%d) - data = %04x\n", space.device().safe_pc(), (offset - 0x58), data ));
- tpi->write(space, offset - 0x58, data);
- }
- break;
-
- case 0x70: /* DMA start strobe */
- {
- LOG(( "DMAC: PC=%08x - DMA Start Strobe\n", space.device().safe_pc() ));
- dmac_data.dma_timer->adjust(attotime::from_msec( CD_SECTOR_TIME ));
- }
- break;
-
- case 0x71: /* DMA stop strobe */
- {
- LOG(( "DMAC: PC=%08x - DMA Stop Strobe\n", space.device().safe_pc() ));
- dmac_data.dma_timer->reset( );
- }
- break;
-
- case 0x72: /* Clear IRQ strobe */
- {
- LOG(( "DMAC: PC=%08x - IRQ Clear Strobe\n", space.device().safe_pc() ));
- dmac_data.istr &= ~ISTR_INT_P;
- }
- break;
-
- case 0x74: /* Flush Strobe */
- {
- LOG(( "DMAC: PC=%08x - Flush Strobe\n", space.device().safe_pc() ));
- dmac_data.istr |= ISTR_FE_FLG;
- }
- break;
-
- default:
- logerror( "DMAC-WRITE: PC=%08x, offset = %02x, data = %04x\n", space.device().safe_pc(), offset, data );
- break;
- }
-}
-
-/***************************************************************************
-
- Autoconfig
-
-***************************************************************************/
-
-static void dmac_install(running_machine &machine, offs_t base)
-{
- amiga_state *state = machine.driver_data<amiga_state>();
- address_space &space = *state->m_maincpu_program_space;
- space.install_read_handler(base, base + 0xFFFF, read16_delegate(FUNC(amiga_state::amiga_dmac_r),state));
- space.install_write_handler(base, base + 0xFFFF, write16_delegate(FUNC(amiga_state::amiga_dmac_w),state));
-}
-
-static void dmac_uninstall(running_machine &machine, offs_t base)
-{
- amiga_state *state = machine.driver_data<amiga_state>();
- address_space &space = *state->m_maincpu_program_space;
- space.unmap_readwrite(base, base + 0xFFFF);
-}
-
-static const amiga_autoconfig_device dmac_device =
-{
- 0, /* link into free memory list */
- 0, /* ROM vector offset valid */
- 0, /* multiple devices on card */
- 1, /* number of 64k pages */
- 3, /* product number (DMAC) */
- 0, /* prefer 8MB address space */
- 0, /* can be shut up */
- 0x0202, /* manufacturers number (Commodore) */
- 0, /* serial number */
- 0, /* ROM vector offset */
- NULL, /* interrupt control read */
- NULL, /* interrupt control write */
- dmac_install, /* memory installation */
- dmac_uninstall /* memory uninstallation */
-};
-
-/***************************************************************************
-
- TPI6525
-
-***************************************************************************/
-
-READ8_MEMBER( amiga_state::amigacd_tpi6525_portc_r )
-{
- int ret = 0;
-
- tpi6525_device *tpi = space.machine().device<tpi6525_device>("tpi6525");
-
- if ( (tpi->get_ddr_c() & 0x04) == 0 ) /* if pin 2 is set to input */
- {
- ret |= matsucd_stch_r() ? 0x00 : 0x04; /* read status change signal */
- }
-
- if ( (tpi->get_ddr_c() & 0x08) == 0 ) /* if pin 3 is set to input */
- ret |= matsucd_sten_r() ? 0x08 : 0x00; /* read enable signal */
-
- return ret;
-}
-
-WRITE8_MEMBER( amiga_state::amigacd_tpi6525_portb_w )
-{
- tpi6525_device *tpi = space.machine().device<tpi6525_device>("tpi6525");
-
- if ( tpi->get_ddr_b() & 0x01 ) /* if pin 0 is set to output */
- matsucd_cmd_w( data & 1 ); /* write to the /CMD signal */
-
- if ( tpi->get_ddr_b() & 0x02 ) /* if pin 1 is set to output */
- matsucd_enable_w( data & 2 ); /* write to the /ENABLE signal */
-}
-
-static emu_timer *tp6525_delayed_timer;
-
-static TIMER_CALLBACK(tp6525_delayed_irq)
-{
- amiga_state *state = machine.driver_data<amiga_state>();
- (void)param;
-
- if ( (CUSTOM_REG(REG_INTREQ) & INTENA_PORTS) == 0 )
- {
- state->amiga_custom_w(*state->m_maincpu_program_space, REG_INTREQ, 0x8000 | INTENA_PORTS, 0xffff);
- }
- else
- {
- tp6525_delayed_timer->adjust(attotime::from_msec(1));
- }
-}
-
-static void amigacd_tpi6525_irq_trampoline(device_t *device, int level)
-{
- amiga_state *state = device->machine().driver_data<amiga_state>();
- LOG(( "TPI6525 Interrupt: level = %d\n", level ));
-
- if ( level )
- {
- if ( (CUSTOM_REG(REG_INTREQ) & INTENA_PORTS) == 0 )
- {
- state->amiga_custom_w(*state->m_maincpu_program_space, REG_INTREQ, 0x8000 | INTENA_PORTS, 0xffff);
- }
- else
- {
- /* we *have to* deliver the irq, so if we can't, delay it and try again later */
- tp6525_delayed_timer->adjust(attotime::from_msec(1));
- }
- }
-}
-
-WRITE_LINE_MEMBER( amiga_state::amigacd_tpi6525_irq )
-{
- tpi6525_device *tpi = machine().device<tpi6525_device>("tpi6525");
-
- amigacd_tpi6525_irq_trampoline(tpi, state);
-}
-
-static void cdrom_status_enabled( running_machine &machine, int level )
-{
- tpi6525_device *tpi = machine.device<tpi6525_device>("tpi6525");
-
- /* PC3 on the 6525 */
- tpi->i3_w(level);
-}
-
-static void cdrom_status_change( running_machine &machine, int level )
-{
- tpi6525_device *tpi = machine.device<tpi6525_device>("tpi6525");
-
- /* invert */
- level = level ? 0 : 1;
-
- /* PC2 on the 6525 */
- tpi->i2_w(level);
-}
-
-static void cdrom_subcode_ready( running_machine &machine, int level )
-{
- tpi6525_device *tpi = machine.device<tpi6525_device>("tpi6525");
-
- /* PC1 on the 6525 */
- tpi->i1_w(level);
-}
-
-void amigacd_start(running_machine &machine)
-{
- /* initialize the dmac */
- memset( &dmac_data, 0, sizeof( dmac_data ) );
-
- dmac_data.dma_timer = machine.scheduler().timer_alloc(FUNC(dmac_dma_proc));
- tp6525_delayed_timer = machine.scheduler().timer_alloc(FUNC(tp6525_delayed_irq));
-
- /* set up DMAC with autoconfig */
- amiga_add_autoconfig( machine, &dmac_device );
-
- matsucd_init( machine.device<cdrom_image_device>("cdrom"), "cdda" );
-}
-
-void amigacd_reset(running_machine &machine)
-{
- /* initialize the cdrom */
- matsucd_set_status_enabled_callback( cdrom_status_enabled );
- matsucd_set_status_changed_callback( cdrom_status_change );
- matsucd_set_subcode_ready_callback( cdrom_subcode_ready );
-}