Search
lxdream.org :: lxdream/src/asic.c
lxdream 0.9.1
released Jun 29
Download Now
filename src/asic.c
changeset 25:fa2d21d57942
prev23:1ec3acd0594d
next31:495e480360d7
author nkeynes
date Sun Dec 25 04:54:40 2005 +0000 (18 years ago)
permissions -rw-r--r--
last change Set disasm PC on startup
view annotate diff log raw
     1 #include <assert.h>
     2 #include "dream.h"
     3 #include "mem.h"
     4 #include "sh4/intc.h"
     5 #include "dreamcast.h"
     6 #include "modules.h"
     7 #include "maple/maple.h"
     8 #include "gdrom/ide.h"
     9 #include "asic.h"
    10 #define MMIO_IMPL
    11 #include "asic.h"
    12 /*
    13  * Open questions:
    14  *   1) Does changing the mask after event occurance result in the
    15  *      interrupt being delivered immediately?
    16  * TODO: Logic diagram of ASIC event/interrupt logic.
    17  *
    18  * ... don't even get me started on the "EXTDMA" page, about which, apparently,
    19  * practically nothing is publicly known...
    20  */
    22 struct dreamcast_module asic_module = { "ASIC", asic_init, NULL, NULL, NULL,
    23 					NULL, NULL, NULL };
    25 void asic_check_cleared_events( void );
    27 void asic_init( void )
    28 {
    29     register_io_region( &mmio_region_ASIC );
    30     register_io_region( &mmio_region_EXTDMA );
    31     mmio_region_ASIC.trace_flag = 0; /* Because this is called so often */
    32     asic_event( EVENT_GDROM_CMD );
    33 }
    35 void mmio_region_ASIC_write( uint32_t reg, uint32_t val )
    36 {
    37     switch( reg ) {
    38         case PIRQ0:
    39         case PIRQ1:
    40         case PIRQ2:
    41             /* Clear any interrupts */
    42             MMIO_WRITE( ASIC, reg, MMIO_READ(ASIC, reg)&~val );
    43 	    DEBUG( "ASIC Write %08X => %08X", val, reg );
    44 	    asic_check_cleared_events();
    45             break;
    46         case MAPLE_STATE:
    47             MMIO_WRITE( ASIC, reg, val );
    48             if( val & 1 ) {
    49                 uint32_t maple_addr = MMIO_READ( ASIC, MAPLE_DMA) &0x1FFFFFE0;
    50 		WARN( "Maple request initiated at %08X, halting", maple_addr );
    51                 maple_handle_buffer( maple_addr );
    52                 MMIO_WRITE( ASIC, reg, 0 );
    53 //                dreamcast_stop();
    54             }
    55             break;
    56         default:
    57             MMIO_WRITE( ASIC, reg, val );
    58             WARN( "Write to ASIC (%03X <= %08X) [%s: %s]",
    59                   reg, val, MMIO_REGID(ASIC,reg), MMIO_REGDESC(ASIC,reg) );
    60     }
    61 }
    63 int32_t mmio_region_ASIC_read( uint32_t reg )
    64 {
    65     int32_t val;
    66     switch( reg ) {
    67         /*
    68         case 0x89C:
    69             sh4_stop();
    70             return 0x000000B;
    71         */     
    72         case PIRQ0:
    73         case PIRQ1:
    74         case PIRQ2:
    75             val = MMIO_READ(ASIC, reg);
    76 //            WARN( "Read from ASIC (%03X => %08X) [%s: %s]",
    77 //                  reg, val, MMIO_REGID(ASIC,reg), MMIO_REGDESC(ASIC,reg) );
    78             return val;            
    79         case G2STATUS:
    80             return 0; /* find out later if there's any cases we actually need to care about */
    81         default:
    82             val = MMIO_READ(ASIC, reg);
    83             WARN( "Read from ASIC (%03X => %08X) [%s: %s]",
    84                   reg, val, MMIO_REGID(ASIC,reg), MMIO_REGDESC(ASIC,reg) );
    85             return val;
    86     }
    88 }
    90 void asic_event( int event )
    91 {
    92     int offset = ((event&0x60)>>3);
    93     int result = (MMIO_READ(ASIC, PIRQ0 + offset))  |=  (1<<(event&0x1F));
    95     if( result & MMIO_READ(ASIC, IRQA0 + offset) )
    96         intc_raise_interrupt( INT_IRQ13 );
    97     if( result & MMIO_READ(ASIC, IRQB0 + offset) )
    98         intc_raise_interrupt( INT_IRQ11 );
    99     if( result & MMIO_READ(ASIC, IRQC0 + offset) )
   100         intc_raise_interrupt( INT_IRQ9 );
   101 }
   103 void asic_check_cleared_events( )
   104 {
   105     int i, setA = 0, setB = 0, setC = 0;
   106     uint32_t bits;
   107     for( i=0; i<3; i++ ) {
   108 	bits = MMIO_READ( ASIC, PIRQ0 + i );
   109 	setA |= (bits & MMIO_READ(ASIC, IRQA0 + i ));
   110 	setB |= (bits & MMIO_READ(ASIC, IRQB0 + i ));
   111 	setC |= (bits & MMIO_READ(ASIC, IRQC0 + i ));
   112     }
   113     if( setA == 0 )
   114 	intc_clear_interrupt( INT_IRQ13 );
   115     if( setB == 0 )
   116 	intc_clear_interrupt( INT_IRQ11 );
   117     if( setC == 0 )
   118 	intc_clear_interrupt( INT_IRQ9 );
   119 }
   122 MMIO_REGION_WRITE_FN( EXTDMA, reg, val )
   123 {
   124     switch( reg ) {
   125         case IDEALTSTATUS: /* Device control */
   126             ide_write_control( val );
   127             break;
   128         case IDEDATA:
   129             ide_write_data_pio( val );
   130             break;
   131         case IDEFEAT:
   132             if( ide_can_write_regs() )
   133                 idereg.feature = (uint8_t)val;
   134             break;
   135         case IDECOUNT:
   136             if( ide_can_write_regs() )
   137                 idereg.count = (uint8_t)val;
   138             break;
   139         case IDELBA0:
   140             if( ide_can_write_regs() )
   141                 idereg.lba0 = (uint8_t)val;
   142             break;
   143         case IDELBA1:
   144             if( ide_can_write_regs() )
   145                 idereg.lba1 = (uint8_t)val;
   146             break;
   147         case IDELBA2:
   148             if( ide_can_write_regs() )
   149                 idereg.lba2 = (uint8_t)val;
   150             break;
   151         case IDEDEV:
   152             if( ide_can_write_regs() )
   153                 idereg.device = (uint8_t)val;
   154             break;
   155         case IDECMD:
   156             if( ide_can_write_regs() ) {
   157                 ide_clear_interrupt();
   158                 ide_write_command( (uint8_t)val );
   159             }
   160             break;
   162         default:
   163             MMIO_WRITE( EXTDMA, reg, val );
   164     }
   165 }
   167 MMIO_REGION_READ_FN( EXTDMA, reg )
   168 {
   169     switch( reg ) {
   170         case IDEALTSTATUS: return idereg.status;
   171         case IDEDATA: return ide_read_data_pio( );
   172         case IDEFEAT: return idereg.error;
   173         case IDECOUNT:return idereg.count;
   174         case IDELBA0: return idereg.disc;
   175         case IDELBA1: return idereg.lba1;
   176         case IDELBA2: return idereg.lba2;
   177         case IDEDEV: return idereg.device;
   178         case IDECMD:
   179             ide_clear_interrupt();
   180             return idereg.status;
   181         default:
   182             return MMIO_READ( EXTDMA, reg );
   183     }
   184 }
.