filename | src/asic.c |
changeset | 23:1ec3acd0594d |
prev | 20:3ffb66aa25c7 |
next | 25:fa2d21d57942 |
author | nkeynes |
date | Sat Dec 24 03:27:55 2005 +0000 (18 years ago) |
permissions | -rw-r--r-- |
last change | Rearrange directory structure to be a little neater remove tst & tst1 |
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 * 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 }
.