filename | src/asic.c |
changeset | 15:5194dd0fdb60 |
prev | 2:42349f6ea216 |
next | 20: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 }
.