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