1 /*
2 sat_hw.c - Saturn sound hardware glue/emulation/whatever
3
4 supported: main RAM (512 KB)
5 SCSP + timers
6 MC68000 CPU
7
8 Copyright (c) 2007, R. Belmont and Richard Bannister.
9
10 All rights reserved.
11
12 Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met:
13
14 * Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer.
15 * Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution.
16 * Neither the names of R. Belmont and Richard Bannister nor the names of its contributors may be used to endorse or promote products derived from this software without specific prior written permission.
17
18 THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
19 "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
20 LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
21 A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR
22 CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
23 EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
24 PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
25 PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
26 LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
27 NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
28 SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
29 */
30
31 #include <stdio.h>
32
33 #include "ao.h"
34 #include "scsp.h"
35 #include "sat_hw.h"
36 #include "m68k.h"
37 #include "m68kcpu.h"
38
scsp_irq(m68ki_cpu_core * cpu,int irq)39 static void scsp_irq(m68ki_cpu_core *cpu, int irq)
40 {
41 if (irq > 0)
42 {
43 m68k_set_irq(cpu, irq);
44 }
45 }
46
47 #define MIXER_PAN_LEFT 1
48 #define MIXER_PAN_RIGHT 2
49 #define MIXER(level,pan) ((level & 0xff) | ((pan & 0x03) << 8))
50 #define YM3012_VOL(LVol,LPan,RVol,RPan) (MIXER(LVol,LPan)|(MIXER(RVol,RPan) << 16))
51
52 #if 0
53 static struct SCSPinterface scsp_interface =
54 {
55 1,
56 { sat_ram, },
57 { YM3012_VOL(100, MIXER_PAN_LEFT, 100, MIXER_PAN_RIGHT) },
58 { scsp_irq, },
59 };
60 #endif
61
sat_hw_init(m68ki_cpu_core * cpu)62 void sat_hw_init(m68ki_cpu_core *cpu)
63 {
64 // m68k_init();
65 m68k_set_cpu_type(cpu, M68K_CPU_TYPE_68000);
66 m68k_pulse_reset(cpu);
67 struct SCSPinterface scsp_interface;
68 scsp_interface.num = 1;
69 scsp_interface.region[0] = cpu->sat_ram;
70 scsp_interface.mixing_level[0] = YM3012_VOL(100, MIXER_PAN_LEFT, 100, MIXER_PAN_RIGHT);
71 scsp_interface.irq_callback[0] = scsp_irq;
72 scsp_interface.cpu = cpu;
73
74 cpu->SCSP = SCSP_Start(&scsp_interface);
75 }
76
sat_hw_free(struct m68ki_cpu_core_s * cpu)77 void sat_hw_free(struct m68ki_cpu_core_s *cpu) {
78 SCSP_Exit (cpu->SCSP);
79 }
80
81 /* M68k memory handlers */
82
m68k_read_memory_8(m68ki_cpu_core * cpu,unsigned int address)83 unsigned int m68k_read_memory_8(m68ki_cpu_core *cpu, unsigned int address)
84 {
85 if (address < (512*1024))
86 return cpu->sat_ram[address^1];
87
88 if (address >= 0x100000 && address < 0x100c00)
89 {
90 int foo = SCSP_0_r(cpu->SCSP, (address - 0x100000)/2, 0);
91
92 if (address & 1)
93 return foo & 0xff;
94 else
95 return foo>>8;
96 }
97
98 printf("R8 @ %x\n", address);
99 return 0;
100 }
101
m68k_read_memory_16(m68ki_cpu_core * cpu,unsigned int address)102 unsigned int m68k_read_memory_16(m68ki_cpu_core *cpu, unsigned int address)
103 {
104 if (address < (512*1024))
105 {
106 return mem_readword_swap((unsigned short *)(cpu->sat_ram+address));
107 }
108
109 if (address >= 0x100000 && address < 0x100c00)
110 return SCSP_0_r(cpu->SCSP, (address-0x100000)/2, 0);
111
112 printf("R16 @ %x\n", address);
113 return 0;
114 }
115
m68k_read_memory_32(m68ki_cpu_core * cpu,unsigned int address)116 unsigned int m68k_read_memory_32(m68ki_cpu_core *cpu, unsigned int address)
117 {
118 if (address < 0x80000)
119 {
120 return cpu->sat_ram[address+2] | cpu->sat_ram[address+3]<<8 | cpu->sat_ram[address]<<16 | cpu->sat_ram[address+1]<<24;
121 }
122
123 printf("R32 @ %x\n", address);
124 return 0;
125 }
126
m68k_write_memory_8(m68ki_cpu_core * cpu,unsigned int address,unsigned int data)127 void m68k_write_memory_8(m68ki_cpu_core *cpu, unsigned int address, unsigned int data)
128 {
129 if (address < 0x80000)
130 {
131 cpu->sat_ram[address^1] = data;
132 return;
133 }
134
135 if (address >= 0x100000 && address < 0x100c00)
136 {
137 address -= 0x100000;
138 if (address & 1)
139 SCSP_0_w(cpu->SCSP, address>>1, data, 0xff00);
140 else
141 SCSP_0_w(cpu->SCSP, address>>1, data<<8, 0x00ff);
142 return;
143 }
144 }
145
m68k_write_memory_16(m68ki_cpu_core * cpu,unsigned int address,unsigned int data)146 void m68k_write_memory_16(m68ki_cpu_core *cpu, unsigned int address, unsigned int data)
147 {
148 if (address < 0x80000)
149 {
150 cpu->sat_ram[address+1] = (data>>8)&0xff;
151 cpu->sat_ram[address] = data&0xff;
152 return;
153 }
154
155 if (address >= 0x100000 && address < 0x100c00)
156 {
157 SCSP_0_w(cpu->SCSP, (address-0x100000)>>1, data, 0x0000);
158 return;
159 }
160 }
161
m68k_write_memory_32(m68ki_cpu_core * cpu,unsigned int address,unsigned int data)162 void m68k_write_memory_32(m68ki_cpu_core *cpu, unsigned int address, unsigned int data)
163 {
164 if (address < 0x80000)
165 {
166 cpu->sat_ram[address+1] = (data>>24)&0xff;
167 cpu->sat_ram[address] = (data>>16)&0xff;
168 cpu->sat_ram[address+3] = (data>>8)&0xff;
169 cpu->sat_ram[address+2] = data&0xff;
170 return;
171 }
172
173 if (address >= 0x100000 && address < 0x100c00)
174 {
175 address -= 0x100000;
176 SCSP_0_w(cpu->SCSP, address>>1, data>>16, 0x0000);
177 SCSP_0_w(cpu->SCSP, (address>>1)+1, data&0xffff, 0x0000);
178 return;
179 }
180 }
181