1 // dc_hw.c - Hardware found on the ARM7/AICA side of the Dreamcast
2
3 #include "ao.h"
4 #include "dc_hw.h"
5 #include "aica.h"
6
7 #define DK_CORE (1)
8
9 #if DK_CORE
10 #include "arm7.h"
11 #else
12 #include "arm7core.h"
13 #endif
14
aica_irq(struct sARM7 * cpu,int irq)15 static void aica_irq(struct sARM7 *cpu, int irq)
16 {
17 if (irq > 0)
18 {
19 #if DK_CORE
20 ARM7_SetFIQ(cpu, TRUE);
21 #else
22 set_irq_line(ARM7_FIRQ_LINE, 1);
23 #endif
24 }
25 else
26 {
27 #if DK_CORE
28 ARM7_SetFIQ(cpu, FALSE);
29 #else
30 set_irq_line(ARM7_FIRQ_LINE, 0);
31 #endif
32 }
33 }
34
35 #define MIXER_PAN_LEFT 1
36 #define MIXER_PAN_RIGHT 2
37 #define MIXER(level,pan) ((level & 0xff) | ((pan & 0x03) << 8))
38 #define YM3012_VOL(LVol,LPan,RVol,RPan) (MIXER(LVol,LPan)|(MIXER(RVol,RPan) << 16))
39
dc_read8(struct sARM7 * cpu,int addr)40 uint8 dc_read8(struct sARM7 *cpu, int addr)
41 {
42 if (addr < 0x800000)
43 {
44 return cpu->dc_ram[addr];
45 }
46
47 if ((addr >= 0x800000) && (addr <= 0x807fff))
48 {
49 int foo = AICA_0_r(cpu->AICA, (addr-0x800000)/2, 0);
50
51 if (addr & 1)
52 {
53 return foo>>8;
54 }
55 else
56 {
57 return foo & 0xff;
58 }
59 }
60
61 printf("R8 @ %x\n", addr);
62 return -1;
63 }
64
dc_read16(struct sARM7 * cpu,int addr)65 uint16 dc_read16(struct sARM7 *cpu, int addr)
66 {
67 if (addr < 0x800000)
68 {
69 return cpu->dc_ram[addr] | (cpu->dc_ram[addr+1]<<8);
70 }
71
72 if ((addr >= 0x800000) && (addr <= 0x807fff))
73 {
74 return AICA_0_r(cpu->AICA, (addr-0x800000)/2, 0);
75 }
76
77 printf("R16 @ %x\n", addr);
78 return -1;
79 }
80
dc_read32(struct sARM7 * cpu,int addr)81 uint32 dc_read32(struct sARM7 *cpu, int addr)
82 {
83 if (addr < 0x800000)
84 {
85 return cpu->dc_ram[addr] | (cpu->dc_ram[addr+1]<<8) | (cpu->dc_ram[addr+2]<<16) | (cpu->dc_ram[addr+3]<<24);
86 }
87
88 if ((addr >= 0x800000) && (addr <= 0x807fff))
89 {
90 addr &= 0x7fff;
91 return AICA_0_r(cpu->AICA, addr/2, 0) & 0xffff;
92 }
93
94 // printf("R32 @ %x\n", addr);
95 return 0;
96 }
97
dc_write8(struct sARM7 * cpu,int addr,uint8 data)98 void dc_write8(struct sARM7 *cpu, int addr, uint8 data)
99 {
100 if (addr < 0x800000)
101 {
102 cpu->dc_ram[addr] = data;
103 return;
104 }
105
106 if ((addr >= 0x800000) && (addr <= 0x807fff))
107 {
108 addr -= 0x800000;
109 if ((addr & 1))
110 AICA_0_w(cpu->AICA, addr>>1, data<<8, 0x00ff);
111 else
112 AICA_0_w(cpu->AICA, addr>>1, data, 0xff00);
113 return;
114 }
115
116 printf("W8 %x @ %x\n", data, addr);
117 }
118
dc_write16(struct sARM7 * cpu,int addr,uint16 data)119 void dc_write16(struct sARM7 *cpu, int addr, uint16 data)
120 {
121 if (addr < 0x800000)
122 {
123 cpu->dc_ram[addr] = data&0xff;
124 cpu->dc_ram[addr+1] = (data>>8) & 0xff;
125 return;
126 }
127
128 if ((addr >= 0x800000) && (addr <= 0x807fff))
129 {
130 AICA_0_w(cpu->AICA, (addr-0x800000)/2, data, 0);
131 return;
132 }
133
134 printf("W16 %x @ %x\n", data, addr);
135 }
136
dc_write32(struct sARM7 * cpu,int addr,uint32 data)137 void dc_write32(struct sARM7 *cpu, int addr, uint32 data)
138 {
139 if (addr < 0x800000)
140 {
141 cpu->dc_ram[addr] = data&0xff;
142 cpu->dc_ram[addr+1] = (data>>8) & 0xff;
143 cpu->dc_ram[addr+2] = (data>>16) & 0xff;
144 cpu->dc_ram[addr+3] = (data>>24) & 0xff;
145 return;
146 }
147
148 if ((addr >= 0x800000) && (addr <= 0x807fff))
149 {
150 addr -= 0x800000;
151 AICA_0_w(cpu->AICA, (addr>>1), data&0xffff, 0x0000);
152 AICA_0_w(cpu->AICA, (addr>>1)+1, data>>16, 0x0000);
153 return;
154 }
155
156 printf("W32 %x @ %x\n", data, addr);
157 }
158
dc_hw_init(struct sARM7 * cpu)159 void dc_hw_init(struct sARM7 *cpu)
160 {
161 #if 0
162 static struct AICAinterface aica_interface =
163 {
164 1,
165 { cpu->dc_ram, },
166 { YM3012_VOL(100, MIXER_PAN_LEFT, 100, MIXER_PAN_RIGHT) },
167 { aica_irq, },
168 };
169 #endif
170
171 cpu->aica_interface.num = 1;
172 cpu->aica_interface.region[0] = cpu->dc_ram;
173 cpu->aica_interface.mixing_level[0] = YM3012_VOL(100, MIXER_PAN_LEFT, 100, MIXER_PAN_RIGHT);
174 cpu->aica_interface.irq_callback[0] = aica_irq;
175 cpu->aica_interface.cpu = cpu;
176 cpu->AICA = aica_start(&cpu->aica_interface);
177 }
178
dc_hw_free(struct sARM7 * cpu)179 void dc_hw_free (struct sARM7 *cpu) {
180 aica_stop (cpu->AICA);
181 cpu->AICA = NULL;
182 }
183