Search
lxdream.org :: lxdream/src/aica/aica.c
lxdream 0.9.1
released Jun 29
Download Now
filename src/aica/aica.c
changeset 44:8da2cbcffe24
prev43:0cf3e339cc59
next61:eb7a73c9bcae
author nkeynes
date Mon Jan 02 14:49:29 2006 +0000 (18 years ago)
permissions -rw-r--r--
last change Change LDM in accordance with the second part of 5.4.6
Fix arm_raise_exception to actually work
file annotate diff log raw
nkeynes@11
     1
/**
nkeynes@44
     2
 * $Id: aica.c,v 1.9 2005-12-26 11:52:56 nkeynes Exp $
nkeynes@11
     3
 * 
nkeynes@11
     4
 * This is the core sound system (ie the bit which does the actual work)
nkeynes@11
     5
 *
nkeynes@11
     6
 * Copyright (c) 2005 Nathan Keynes.
nkeynes@11
     7
 *
nkeynes@11
     8
 * This program is free software; you can redistribute it and/or modify
nkeynes@11
     9
 * it under the terms of the GNU General Public License as published by
nkeynes@11
    10
 * the Free Software Foundation; either version 2 of the License, or
nkeynes@11
    11
 * (at your option) any later version.
nkeynes@11
    12
 *
nkeynes@11
    13
 * This program is distributed in the hope that it will be useful,
nkeynes@11
    14
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
nkeynes@11
    15
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
nkeynes@11
    16
 * GNU General Public License for more details.
nkeynes@11
    17
 */
nkeynes@11
    18
nkeynes@35
    19
#define MODULE aica_module
nkeynes@35
    20
nkeynes@11
    21
#include "dream.h"
nkeynes@15
    22
#include "mem.h"
nkeynes@11
    23
#include "aica.h"
nkeynes@11
    24
#define MMIO_IMPL
nkeynes@11
    25
#include "aica.h"
nkeynes@11
    26
nkeynes@11
    27
MMIO_REGION_READ_DEFFN( AICA0 )
nkeynes@11
    28
MMIO_REGION_READ_DEFFN( AICA1 )
nkeynes@11
    29
MMIO_REGION_READ_DEFFN( AICA2 )
nkeynes@11
    30
nkeynes@23
    31
void aica_init( void );
nkeynes@23
    32
void aica_reset( void );
nkeynes@23
    33
void aica_start( void );
nkeynes@23
    34
void aica_stop( void );
nkeynes@35
    35
void aica_save_state( FILE *f );
nkeynes@35
    36
int aica_load_state( FILE *f );
nkeynes@30
    37
uint32_t aica_run_slice( uint32_t );
nkeynes@23
    38
nkeynes@23
    39
nkeynes@23
    40
struct dreamcast_module aica_module = { "AICA", aica_init, aica_reset, 
nkeynes@23
    41
					aica_start, aica_run_slice, aica_stop,
nkeynes@35
    42
					aica_save_state, aica_load_state };
nkeynes@15
    43
nkeynes@11
    44
/**
nkeynes@11
    45
 * Initialize the AICA subsystem. Note requires that 
nkeynes@11
    46
 */
nkeynes@11
    47
void aica_init( void )
nkeynes@11
    48
{
nkeynes@11
    49
    register_io_regions( mmio_list_spu );
nkeynes@11
    50
    MMIO_NOTRACE(AICA0);
nkeynes@11
    51
    MMIO_NOTRACE(AICA1);
nkeynes@11
    52
    arm_mem_init();
nkeynes@37
    53
    arm_reset();
nkeynes@11
    54
}
nkeynes@11
    55
nkeynes@11
    56
void aica_reset( void )
nkeynes@11
    57
{
nkeynes@35
    58
    arm_reset();
nkeynes@11
    59
}
nkeynes@11
    60
nkeynes@23
    61
void aica_start( void )
nkeynes@23
    62
{
nkeynes@23
    63
nkeynes@23
    64
}
nkeynes@23
    65
nkeynes@30
    66
uint32_t aica_run_slice( uint32_t nanosecs )
nkeynes@23
    67
{
nkeynes@23
    68
    /* Run arm instructions */
nkeynes@35
    69
    int reset = MMIO_READ( AICA2, AICA_RESET );
nkeynes@44
    70
    if( (reset & 1) == 0 ) { 
nkeynes@35
    71
	/* Running */
nkeynes@43
    72
        nanosecs = arm_run_slice( nanosecs );
nkeynes@35
    73
    }
nkeynes@23
    74
    /* Generate audio buffer */
nkeynes@43
    75
    return nanosecs;
nkeynes@23
    76
}
nkeynes@23
    77
nkeynes@23
    78
void aica_stop( void )
nkeynes@23
    79
{
nkeynes@23
    80
nkeynes@23
    81
}
nkeynes@23
    82
nkeynes@35
    83
void aica_save_state( FILE *f )
nkeynes@35
    84
{
nkeynes@35
    85
    arm_save_state( f );
nkeynes@35
    86
}
nkeynes@35
    87
nkeynes@35
    88
int aica_load_state( FILE *f )
nkeynes@35
    89
{
nkeynes@35
    90
    return arm_load_state( f );
nkeynes@35
    91
}
nkeynes@35
    92
nkeynes@11
    93
/** Channel register structure:
nkeynes@43
    94
 * 00  4  Channel config
nkeynes@43
    95
 * 04  4  Waveform address lo (16 bits)
nkeynes@11
    96
 * 08  4  Loop start address
nkeynes@11
    97
 * 0C  4  Loop end address
nkeynes@11
    98
 * 10  4  Volume envelope
nkeynes@43
    99
 * 14  4  Init to 0x1F
nkeynes@43
   100
 * 18  4  Frequency (floating point)
nkeynes@43
   101
 * 1C  4  ?? 
nkeynes@43
   102
 * 20  4  ??
nkeynes@11
   103
 * 24  1  Pan
nkeynes@11
   104
 * 25  1  ??
nkeynes@11
   105
 * 26  
nkeynes@11
   106
 * 27  
nkeynes@11
   107
 * 28  1  ??
nkeynes@11
   108
 * 29  1  Volume
nkeynes@11
   109
 * 2C
nkeynes@11
   110
 * 30
nkeynes@11
   111
 * 
nkeynes@11
   112
nkeynes@11
   113
/* Write to channels 0-31 */
nkeynes@11
   114
void mmio_region_AICA0_write( uint32_t reg, uint32_t val )
nkeynes@11
   115
{
nkeynes@11
   116
    //    aica_write_channel( reg >> 7, reg % 128, val );
nkeynes@35
   117
    MMIO_WRITE( AICA0, reg, val );
nkeynes@37
   118
    //    DEBUG( "AICA0 Write %08X => %08X", val, reg );
nkeynes@11
   119
}
nkeynes@11
   120
nkeynes@11
   121
/* Write to channels 32-64 */
nkeynes@11
   122
void mmio_region_AICA1_write( uint32_t reg, uint32_t val )
nkeynes@11
   123
{
nkeynes@11
   124
    //    aica_write_channel( (reg >> 7) + 32, reg % 128, val );
nkeynes@35
   125
    MMIO_WRITE( AICA1, reg, val );
nkeynes@37
   126
    // DEBUG( "AICA1 Write %08X => %08X", val, reg );
nkeynes@11
   127
}
nkeynes@11
   128
nkeynes@11
   129
/* General registers */
nkeynes@11
   130
void mmio_region_AICA2_write( uint32_t reg, uint32_t val )
nkeynes@11
   131
{
nkeynes@35
   132
    uint32_t tmp;
nkeynes@35
   133
    switch( reg ) {
nkeynes@35
   134
    case AICA_RESET:
nkeynes@35
   135
	tmp = MMIO_READ( AICA2, AICA_RESET );
nkeynes@37
   136
	if( (tmp & 1) == 1 && (val & 1) == 0 ) {
nkeynes@35
   137
	    /* ARM enabled - execute a core reset */
nkeynes@37
   138
	    DEBUG( "ARM enabled" );
nkeynes@35
   139
	    arm_reset();
nkeynes@37
   140
	} else if( (tmp&1) == 0 && (val&1) == 1 ) {
nkeynes@37
   141
	    DEBUG( "ARM disabled" );
nkeynes@35
   142
	}
nkeynes@35
   143
	MMIO_WRITE( AICA2, AICA_RESET, val );
nkeynes@35
   144
	break;
nkeynes@35
   145
    default:
nkeynes@35
   146
	MMIO_WRITE( AICA2, reg, val );
nkeynes@35
   147
	break;
nkeynes@35
   148
    }
nkeynes@11
   149
}
.