Search
lxdream.org :: lxdream/src/asic.c
lxdream 0.9.1
released Jun 29
Download Now
filename src/asic.c
changeset 2:42349f6ea216
prev1:eea311cfd33e
next15:5194dd0fdb60
author nkeynes
date Thu Dec 08 13:38:00 2005 +0000 (18 years ago)
permissions -rw-r--r--
last change Generalise the core debug window to allow multiple instances.
Add cpu description structure to define different cpus for use by the
debug window, in preparation for ARM implementation
file annotate diff log raw
nkeynes@1
     1
#include <assert.h>
nkeynes@1
     2
#include "dream.h"
nkeynes@1
     3
#include "mem.h"
nkeynes@1
     4
#include "sh4/intc.h"
nkeynes@1
     5
#include "asic.h"
nkeynes@2
     6
#include "dreamcast.h"
nkeynes@1
     7
#include "maple.h"
nkeynes@2
     8
#include "ide.h"
nkeynes@1
     9
#define MMIO_IMPL
nkeynes@1
    10
#include "asic.h"
nkeynes@1
    11
/*
nkeynes@1
    12
 * Open questions:
nkeynes@1
    13
 *   1) Does changing the mask after event occurance result in the
nkeynes@1
    14
 *      interrupt being delivered immediately?
nkeynes@1
    15
 *   2) If the pending register is not cleared after an interrupt, does
nkeynes@1
    16
 *      the interrupt line remain high? (ie does the IRQ reoccur?)
nkeynes@1
    17
 * TODO: Logic diagram of ASIC event/interrupt logic.
nkeynes@1
    18
 *
nkeynes@1
    19
 * ... don't even get me started on the "EXTDMA" page, about which, apparently,
nkeynes@1
    20
 * practically nothing is publicly known...
nkeynes@1
    21
 */
nkeynes@1
    22
nkeynes@1
    23
void asic_init( void )
nkeynes@1
    24
{
nkeynes@1
    25
    register_io_region( &mmio_region_ASIC );
nkeynes@1
    26
    register_io_region( &mmio_region_EXTDMA );
nkeynes@1
    27
    mmio_region_ASIC.trace_flag = 0; /* Because this is called so often */
nkeynes@1
    28
    asic_event( EVENT_GDROM_CMD );
nkeynes@1
    29
}
nkeynes@1
    30
nkeynes@1
    31
void mmio_region_ASIC_write( uint32_t reg, uint32_t val )
nkeynes@1
    32
{
nkeynes@1
    33
    switch( reg ) {
nkeynes@1
    34
        case PIRQ0:
nkeynes@1
    35
        case PIRQ1:
nkeynes@1
    36
        case PIRQ2:
nkeynes@1
    37
            /* Clear any interrupts */
nkeynes@1
    38
            MMIO_WRITE( ASIC, reg, MMIO_READ(ASIC, reg)&~val );
nkeynes@1
    39
            break;
nkeynes@1
    40
        case MAPLE_STATE:
nkeynes@1
    41
            MMIO_WRITE( ASIC, reg, val );
nkeynes@1
    42
            if( val & 1 ) {
nkeynes@1
    43
                uint32_t maple_addr = MMIO_READ( ASIC, MAPLE_DMA) &0x1FFFFFE0;
nkeynes@2
    44
		WARN( "Maple request initiated at %08X, halting", maple_addr );
nkeynes@2
    45
                maple_handle_buffer( maple_addr );
nkeynes@1
    46
                MMIO_WRITE( ASIC, reg, 0 );
nkeynes@2
    47
//                dreamcast_stop();
nkeynes@1
    48
            }
nkeynes@1
    49
            break;
nkeynes@1
    50
        default:
nkeynes@1
    51
            MMIO_WRITE( ASIC, reg, val );
nkeynes@1
    52
            WARN( "Write to ASIC (%03X <= %08X) [%s: %s]",
nkeynes@1
    53
                  reg, val, MMIO_REGID(ASIC,reg), MMIO_REGDESC(ASIC,reg) );
nkeynes@1
    54
    }
nkeynes@1
    55
}
nkeynes@1
    56
nkeynes@1
    57
int32_t mmio_region_ASIC_read( uint32_t reg )
nkeynes@1
    58
{
nkeynes@1
    59
    int32_t val;
nkeynes@1
    60
    switch( reg ) {
nkeynes@2
    61
        /*
nkeynes@2
    62
        case 0x89C:
nkeynes@2
    63
            sh4_stop();
nkeynes@2
    64
            return 0x000000B;
nkeynes@2
    65
        */     
nkeynes@1
    66
        case PIRQ0:
nkeynes@1
    67
        case PIRQ1:
nkeynes@1
    68
        case PIRQ2:
nkeynes@1
    69
            val = MMIO_READ(ASIC, reg);
nkeynes@1
    70
//            WARN( "Read from ASIC (%03X => %08X) [%s: %s]",
nkeynes@1
    71
//                  reg, val, MMIO_REGID(ASIC,reg), MMIO_REGDESC(ASIC,reg) );
nkeynes@1
    72
            return val;            
nkeynes@1
    73
        case G2STATUS:
nkeynes@1
    74
            return 0; /* find out later if there's any cases we actually need to care about */
nkeynes@1
    75
        default:
nkeynes@1
    76
            val = MMIO_READ(ASIC, reg);
nkeynes@1
    77
            WARN( "Read from ASIC (%03X => %08X) [%s: %s]",
nkeynes@1
    78
                  reg, val, MMIO_REGID(ASIC,reg), MMIO_REGDESC(ASIC,reg) );
nkeynes@1
    79
            return val;
nkeynes@1
    80
    }
nkeynes@1
    81
           
nkeynes@1
    82
}
nkeynes@1
    83
nkeynes@1
    84
void asic_event( int event )
nkeynes@1
    85
{
nkeynes@1
    86
    int offset = ((event&0x60)>>3);
nkeynes@1
    87
    int result = (MMIO_READ(ASIC, PIRQ0 + offset))  |=  (1<<(event&0x1F));
nkeynes@1
    88
nkeynes@1
    89
    if( result & MMIO_READ(ASIC, IRQA0 + offset) )
nkeynes@1
    90
        intc_raise_interrupt( INT_IRQ13 );
nkeynes@1
    91
    if( result & MMIO_READ(ASIC, IRQB0 + offset) )
nkeynes@1
    92
        intc_raise_interrupt( INT_IRQ11 );
nkeynes@1
    93
    if( result & MMIO_READ(ASIC, IRQC0 + offset) )
nkeynes@1
    94
        intc_raise_interrupt( INT_IRQ9 );
nkeynes@1
    95
}
nkeynes@1
    96
nkeynes@1
    97
nkeynes@1
    98
nkeynes@1
    99
MMIO_REGION_WRITE_FN( EXTDMA, reg, val )
nkeynes@1
   100
{
nkeynes@2
   101
    switch( reg ) {
nkeynes@2
   102
        case IDEALTSTATUS: /* Device control */
nkeynes@2
   103
            ide_write_control( val );
nkeynes@2
   104
            break;
nkeynes@2
   105
        case IDEDATA:
nkeynes@2
   106
            ide_write_data_pio( val );
nkeynes@2
   107
            break;
nkeynes@2
   108
        case IDEFEAT:
nkeynes@2
   109
            if( ide_can_write_regs() )
nkeynes@2
   110
                idereg.feature = (uint8_t)val;
nkeynes@2
   111
            break;
nkeynes@2
   112
        case IDECOUNT:
nkeynes@2
   113
            if( ide_can_write_regs() )
nkeynes@2
   114
                idereg.count = (uint8_t)val;
nkeynes@2
   115
            break;
nkeynes@2
   116
        case IDELBA0:
nkeynes@2
   117
            if( ide_can_write_regs() )
nkeynes@2
   118
                idereg.lba0 = (uint8_t)val;
nkeynes@2
   119
            break;
nkeynes@2
   120
        case IDELBA1:
nkeynes@2
   121
            if( ide_can_write_regs() )
nkeynes@2
   122
                idereg.lba1 = (uint8_t)val;
nkeynes@2
   123
            break;
nkeynes@2
   124
        case IDELBA2:
nkeynes@2
   125
            if( ide_can_write_regs() )
nkeynes@2
   126
                idereg.lba2 = (uint8_t)val;
nkeynes@2
   127
            break;
nkeynes@2
   128
        case IDEDEV:
nkeynes@2
   129
            if( ide_can_write_regs() )
nkeynes@2
   130
                idereg.device = (uint8_t)val;
nkeynes@2
   131
            break;
nkeynes@2
   132
        case IDECMD:
nkeynes@2
   133
            if( ide_can_write_regs() ) {
nkeynes@2
   134
                ide_clear_interrupt();
nkeynes@2
   135
                ide_write_command( (uint8_t)val );
nkeynes@2
   136
            }
nkeynes@2
   137
            break;
nkeynes@2
   138
            
nkeynes@2
   139
        default:
nkeynes@2
   140
            MMIO_WRITE( EXTDMA, reg, val );
nkeynes@2
   141
    }
nkeynes@1
   142
}
nkeynes@1
   143
nkeynes@1
   144
MMIO_REGION_READ_FN( EXTDMA, reg )
nkeynes@1
   145
{
nkeynes@1
   146
    switch( reg ) {
nkeynes@2
   147
        case IDEALTSTATUS: return idereg.status;
nkeynes@2
   148
        case IDEDATA: return ide_read_data_pio( );
nkeynes@2
   149
        case IDEFEAT: return idereg.error;
nkeynes@2
   150
        case IDECOUNT:return idereg.count;
nkeynes@2
   151
        case IDELBA0: return idereg.disc;
nkeynes@2
   152
        case IDELBA1: return idereg.lba1;
nkeynes@2
   153
        case IDELBA2: return idereg.lba2;
nkeynes@2
   154
        case IDEDEV: return idereg.device;
nkeynes@2
   155
        case IDECMD:
nkeynes@2
   156
            ide_clear_interrupt();
nkeynes@2
   157
            return idereg.status;
nkeynes@1
   158
        default:
nkeynes@1
   159
            return MMIO_READ( EXTDMA, reg );
nkeynes@1
   160
    }
nkeynes@1
   161
}
nkeynes@1
   162
.