Search
lxdream.org :: lxdream/src/asic.c
lxdream 0.9.1
released Jun 29
Download Now
filename src/asic.c
changeset 15:5194dd0fdb60
prev2:42349f6ea216
next20:3ffb66aa25c7
author nkeynes
date Tue Dec 13 14:47:59 2005 +0000 (18 years ago)
permissions -rw-r--r--
last change More work on load/save state - save state a little more structured now
Memory save now in
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.h"
     8 #include "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  *   2) If the pending register is not cleared after an interrupt, does
    17  *      the interrupt line remain high? (ie does the IRQ reoccur?)
    18  * TODO: Logic diagram of ASIC event/interrupt logic.
    19  *
    20  * ... don't even get me started on the "EXTDMA" page, about which, apparently,
    21  * practically nothing is publicly known...
    22  */
    24 struct dreamcast_module asic_module = { "ASIC", asic_init, NULL, NULL, NULL,
    25 					NULL, NULL };
    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             break;
    44         case MAPLE_STATE:
    45             MMIO_WRITE( ASIC, reg, val );
    46             if( val & 1 ) {
    47                 uint32_t maple_addr = MMIO_READ( ASIC, MAPLE_DMA) &0x1FFFFFE0;
    48 		WARN( "Maple request initiated at %08X, halting", maple_addr );
    49                 maple_handle_buffer( maple_addr );
    50                 MMIO_WRITE( ASIC, reg, 0 );
    51 //                dreamcast_stop();
    52             }
    53             break;
    54         default:
    55             MMIO_WRITE( ASIC, reg, val );
    56             WARN( "Write to ASIC (%03X <= %08X) [%s: %s]",
    57                   reg, val, MMIO_REGID(ASIC,reg), MMIO_REGDESC(ASIC,reg) );
    58     }
    59 }
    61 int32_t mmio_region_ASIC_read( uint32_t reg )
    62 {
    63     int32_t val;
    64     switch( reg ) {
    65         /*
    66         case 0x89C:
    67             sh4_stop();
    68             return 0x000000B;
    69         */     
    70         case PIRQ0:
    71         case PIRQ1:
    72         case PIRQ2:
    73             val = MMIO_READ(ASIC, reg);
    74 //            WARN( "Read from ASIC (%03X => %08X) [%s: %s]",
    75 //                  reg, val, MMIO_REGID(ASIC,reg), MMIO_REGDESC(ASIC,reg) );
    76             return val;            
    77         case G2STATUS:
    78             return 0; /* find out later if there's any cases we actually need to care about */
    79         default:
    80             val = MMIO_READ(ASIC, reg);
    81             WARN( "Read from ASIC (%03X => %08X) [%s: %s]",
    82                   reg, val, MMIO_REGID(ASIC,reg), MMIO_REGDESC(ASIC,reg) );
    83             return val;
    84     }
    86 }
    88 void asic_event( int event )
    89 {
    90     int offset = ((event&0x60)>>3);
    91     int result = (MMIO_READ(ASIC, PIRQ0 + offset))  |=  (1<<(event&0x1F));
    93     if( result & MMIO_READ(ASIC, IRQA0 + offset) )
    94         intc_raise_interrupt( INT_IRQ13 );
    95     if( result & MMIO_READ(ASIC, IRQB0 + offset) )
    96         intc_raise_interrupt( INT_IRQ11 );
    97     if( result & MMIO_READ(ASIC, IRQC0 + offset) )
    98         intc_raise_interrupt( INT_IRQ9 );
    99 }
   103 MMIO_REGION_WRITE_FN( EXTDMA, reg, val )
   104 {
   105     switch( reg ) {
   106         case IDEALTSTATUS: /* Device control */
   107             ide_write_control( val );
   108             break;
   109         case IDEDATA:
   110             ide_write_data_pio( val );
   111             break;
   112         case IDEFEAT:
   113             if( ide_can_write_regs() )
   114                 idereg.feature = (uint8_t)val;
   115             break;
   116         case IDECOUNT:
   117             if( ide_can_write_regs() )
   118                 idereg.count = (uint8_t)val;
   119             break;
   120         case IDELBA0:
   121             if( ide_can_write_regs() )
   122                 idereg.lba0 = (uint8_t)val;
   123             break;
   124         case IDELBA1:
   125             if( ide_can_write_regs() )
   126                 idereg.lba1 = (uint8_t)val;
   127             break;
   128         case IDELBA2:
   129             if( ide_can_write_regs() )
   130                 idereg.lba2 = (uint8_t)val;
   131             break;
   132         case IDEDEV:
   133             if( ide_can_write_regs() )
   134                 idereg.device = (uint8_t)val;
   135             break;
   136         case IDECMD:
   137             if( ide_can_write_regs() ) {
   138                 ide_clear_interrupt();
   139                 ide_write_command( (uint8_t)val );
   140             }
   141             break;
   143         default:
   144             MMIO_WRITE( EXTDMA, reg, val );
   145     }
   146 }
   148 MMIO_REGION_READ_FN( EXTDMA, reg )
   149 {
   150     switch( reg ) {
   151         case IDEALTSTATUS: return idereg.status;
   152         case IDEDATA: return ide_read_data_pio( );
   153         case IDEFEAT: return idereg.error;
   154         case IDECOUNT:return idereg.count;
   155         case IDELBA0: return idereg.disc;
   156         case IDELBA1: return idereg.lba1;
   157         case IDELBA2: return idereg.lba2;
   158         case IDEDEV: return idereg.device;
   159         case IDECMD:
   160             ide_clear_interrupt();
   161             return idereg.status;
   162         default:
   163             return MMIO_READ( EXTDMA, reg );
   164     }
   165 }
.