Search
lxdream.org :: lxdream/src/asic.c :: diff
lxdream 0.9.1
released Jun 29
Download Now
filename src/asic.c
changeset 155:be61d1a20937
prev137:41907543d890
next158:a0a82246b44e
author nkeynes
date Thu Jun 15 10:25:45 2006 +0000 (17 years ago)
permissions -rw-r--r--
last change Add P4 I/O tracing
Add ability to set I/O trace by region address
file annotate diff log raw
1.1 --- a/src/asic.c Sun Apr 30 01:50:15 2006 +0000
1.2 +++ b/src/asic.c Thu Jun 15 10:25:45 2006 +0000
1.3 @@ -1,5 +1,5 @@
1.4 /**
1.5 - * $Id: asic.c,v 1.14 2006-04-30 01:50:13 nkeynes Exp $
1.6 + * $Id: asic.c,v 1.15 2006-05-24 11:50:19 nkeynes Exp $
1.7 *
1.8 * Support for the miscellaneous ASIC functions (Primarily event multiplexing,
1.9 * and DMA).
1.10 @@ -41,8 +41,14 @@
1.11 * practically nothing is publicly known...
1.12 */
1.13
1.14 -struct dreamcast_module asic_module = { "ASIC", asic_init, NULL, NULL, NULL,
1.15 - NULL, NULL, NULL };
1.16 +static void asic_check_cleared_events( void );
1.17 +static void asic_init( void );
1.18 +static void asic_reset( void );
1.19 +static void asic_save_state( FILE *f );
1.20 +static int asic_load_state( FILE *f );
1.21 +
1.22 +struct dreamcast_module asic_module = { "ASIC", asic_init, asic_reset, NULL, NULL,
1.23 + NULL, asic_save_state, asic_load_state };
1.24
1.25 #define G2_BIT5_TICKS 8
1.26 #define G2_BIT4_TICKS 16
1.27 @@ -55,7 +61,36 @@
1.28 unsigned int bit4_off_timer;
1.29 unsigned int bit0_on_timer;
1.30 unsigned int bit0_off_timer;
1.31 -} g2_state;
1.32 +};
1.33 +
1.34 +static struct asic_g2_state g2_state;
1.35 +
1.36 +static void asic_init( void )
1.37 +{
1.38 + register_io_region( &mmio_region_ASIC );
1.39 + register_io_region( &mmio_region_EXTDMA );
1.40 + mmio_region_ASIC.trace_flag = 0; /* Because this is called so often */
1.41 + asic_reset();
1.42 +}
1.43 +
1.44 +static void asic_reset( void )
1.45 +{
1.46 + memset( &g2_state, 0, sizeof(g2_state) );
1.47 +}
1.48 +
1.49 +static void asic_save_state( FILE *f )
1.50 +{
1.51 + fwrite( &g2_state, sizeof(g2_state), 1, f );
1.52 +}
1.53 +
1.54 +static int asic_load_state( FILE *f )
1.55 +{
1.56 + if( fread( &g2_state, sizeof(g2_state), 1, f ) != 1 )
1.57 + return 1;
1.58 + else
1.59 + return 0;
1.60 +}
1.61 +
1.62
1.63 /* FIXME: Handle rollover */
1.64 void asic_g2_write_word()
1.65 @@ -89,15 +124,69 @@
1.66 return val | 0x0E;
1.67 }
1.68
1.69 -void asic_check_cleared_events( void );
1.70
1.71 -void asic_init( void )
1.72 +void asic_event( int event )
1.73 {
1.74 - register_io_region( &mmio_region_ASIC );
1.75 - register_io_region( &mmio_region_EXTDMA );
1.76 - mmio_region_ASIC.trace_flag = 0; /* Because this is called so often */
1.77 + int offset = ((event&0x60)>>3);
1.78 + int result = (MMIO_READ(ASIC, PIRQ0 + offset)) |= (1<<(event&0x1F));
1.79 +
1.80 + if( result & MMIO_READ(ASIC, IRQA0 + offset) )
1.81 + intc_raise_interrupt( INT_IRQ13 );
1.82 + if( result & MMIO_READ(ASIC, IRQB0 + offset) )
1.83 + intc_raise_interrupt( INT_IRQ11 );
1.84 + if( result & MMIO_READ(ASIC, IRQC0 + offset) )
1.85 + intc_raise_interrupt( INT_IRQ9 );
1.86 }
1.87
1.88 +void asic_clear_event( int event ) {
1.89 + int offset = ((event&0x60)>>3);
1.90 + uint32_t result = MMIO_READ(ASIC, PIRQ0 + offset) & (~(1<<(event&0x1F)));
1.91 + MMIO_WRITE( ASIC, PIRQ0 + offset, result );
1.92 +
1.93 + asic_check_cleared_events();
1.94 +}
1.95 +
1.96 +void asic_check_cleared_events( )
1.97 +{
1.98 + int i, setA = 0, setB = 0, setC = 0;
1.99 + uint32_t bits;
1.100 + for( i=0; i<3; i++ ) {
1.101 + bits = MMIO_READ( ASIC, PIRQ0 + i );
1.102 + setA |= (bits & MMIO_READ(ASIC, IRQA0 + i ));
1.103 + setB |= (bits & MMIO_READ(ASIC, IRQB0 + i ));
1.104 + setC |= (bits & MMIO_READ(ASIC, IRQC0 + i ));
1.105 + }
1.106 + if( setA == 0 )
1.107 + intc_clear_interrupt( INT_IRQ13 );
1.108 + if( setB == 0 )
1.109 + intc_clear_interrupt( INT_IRQ11 );
1.110 + if( setC == 0 )
1.111 + intc_clear_interrupt( INT_IRQ9 );
1.112 +}
1.113 +
1.114 +
1.115 +void asic_ide_dma_transfer( )
1.116 +{
1.117 + if( MMIO_READ( EXTDMA, IDEDMACTL2 ) == 1 &&
1.118 + MMIO_READ( EXTDMA, IDEDMACTL1 ) == 0 ) {
1.119 + uint32_t addr = MMIO_READ( EXTDMA, IDEDMASH4 );
1.120 + uint32_t length = MMIO_READ( EXTDMA, IDEDMASIZ );
1.121 + int dir = MMIO_READ( EXTDMA, IDEDMADIR );
1.122 +
1.123 + uint32_t xfer = ide_read_data_dma( addr, length );
1.124 + if( xfer != 0 ) {
1.125 + MMIO_WRITE( EXTDMA, IDEDMASH4, addr + xfer );
1.126 + MMIO_WRITE( EXTDMA, IDEDMASIZ, length - xfer );
1.127 + if( xfer == length ) {
1.128 + MMIO_WRITE( EXTDMA, IDEDMACTL2, 0 );
1.129 + asic_event( EVENT_IDE_DMA );
1.130 + }
1.131 + }
1.132 + }
1.133 +
1.134 +}
1.135 +
1.136 +
1.137 void mmio_region_ASIC_write( uint32_t reg, uint32_t val )
1.138 {
1.139 switch( reg ) {
1.140 @@ -114,15 +203,13 @@
1.141 MMIO_WRITE( ASIC, reg, val );
1.142 if( val & 1 ) {
1.143 uint32_t maple_addr = MMIO_READ( ASIC, MAPLE_DMA) &0x1FFFFFE0;
1.144 - WARN( "Maple request initiated at %08X, halting", maple_addr );
1.145 + // WARN( "Maple request initiated at %08X, halting", maple_addr );
1.146 maple_handle_buffer( maple_addr );
1.147 MMIO_WRITE( ASIC, reg, 0 );
1.148 }
1.149 break;
1.150 case PVRDMACTL: /* Initiate PVR DMA transfer */
1.151 MMIO_WRITE( ASIC, reg, val );
1.152 - WARN( "Write to ASIC (%03X <= %08X) [%s: %s]",
1.153 - reg, val, MMIO_REGID(ASIC,reg), MMIO_REGDESC(ASIC,reg) );
1.154 if( val & 1 ) {
1.155 uint32_t dest_addr = MMIO_READ( ASIC, PVRDMADEST) &0x1FFFFFE0;
1.156 uint32_t count = MMIO_READ( ASIC, PVRDMACNT );
1.157 @@ -177,46 +264,6 @@
1.158
1.159 }
1.160
1.161 -void asic_event( int event )
1.162 -{
1.163 - int offset = ((event&0x60)>>3);
1.164 - int result = (MMIO_READ(ASIC, PIRQ0 + offset)) |= (1<<(event&0x1F));
1.165 -
1.166 - if( result & MMIO_READ(ASIC, IRQA0 + offset) )
1.167 - intc_raise_interrupt( INT_IRQ13 );
1.168 - if( result & MMIO_READ(ASIC, IRQB0 + offset) )
1.169 - intc_raise_interrupt( INT_IRQ11 );
1.170 - if( result & MMIO_READ(ASIC, IRQC0 + offset) )
1.171 - intc_raise_interrupt( INT_IRQ9 );
1.172 -}
1.173 -
1.174 -void asic_clear_event( int event ) {
1.175 - int offset = ((event&0x60)>>3);
1.176 - uint32_t result = MMIO_READ(ASIC, PIRQ0 + offset) & (~(1<<(event&0x1F)));
1.177 - MMIO_WRITE( ASIC, PIRQ0 + offset, result );
1.178 -
1.179 - asic_check_cleared_events();
1.180 -}
1.181 -
1.182 -void asic_check_cleared_events( )
1.183 -{
1.184 - int i, setA = 0, setB = 0, setC = 0;
1.185 - uint32_t bits;
1.186 - for( i=0; i<3; i++ ) {
1.187 - bits = MMIO_READ( ASIC, PIRQ0 + i );
1.188 - setA |= (bits & MMIO_READ(ASIC, IRQA0 + i ));
1.189 - setB |= (bits & MMIO_READ(ASIC, IRQB0 + i ));
1.190 - setC |= (bits & MMIO_READ(ASIC, IRQC0 + i ));
1.191 - }
1.192 - if( setA == 0 )
1.193 - intc_clear_interrupt( INT_IRQ13 );
1.194 - if( setB == 0 )
1.195 - intc_clear_interrupt( INT_IRQ11 );
1.196 - if( setC == 0 )
1.197 - intc_clear_interrupt( INT_IRQ9 );
1.198 -}
1.199 -
1.200 -
1.201 MMIO_REGION_WRITE_FN( EXTDMA, reg, val )
1.202 {
1.203 WARN( "EXTDMA write %08X <= %08X", reg, val );
1.204 @@ -258,14 +305,10 @@
1.205 }
1.206 break;
1.207 case IDEDMACTL1:
1.208 + MMIO_WRITE( EXTDMA, reg, val );
1.209 case IDEDMACTL2:
1.210 MMIO_WRITE( EXTDMA, reg, val );
1.211 - if( MMIO_READ( EXTDMA, IDEDMACTL1 ) == 1 &&
1.212 - MMIO_READ( EXTDMA, IDEDMACTL2 ) == 1 ) {
1.213 - uint32_t target_addr = MMIO_READ( EXTDMA, IDEDMASH4 );
1.214 - uint32_t length = MMIO_READ( EXTDMA, IDEDMASIZ );
1.215 - int dir = MMIO_READ( EXTDMA, IDEDMADIR );
1.216 - }
1.217 + asic_ide_dma_transfer( );
1.218 break;
1.219 default:
1.220 MMIO_WRITE( EXTDMA, reg, val );
.