dev_dreamcast_asic.cc Source File
Back to the index.
src
devices
dev_dreamcast_asic.cc
Go to the documentation of this file.
1
/*
2
* Copyright (C) 2006-2011 Anders Gavare. All rights reserved.
3
*
4
* Redistribution and use in source and binary forms, with or without
5
* modification, are permitted provided that the following conditions are met:
6
*
7
* 1. Redistributions of source code must retain the above copyright
8
* notice, this list of conditions and the following disclaimer.
9
* 2. Redistributions in binary form must reproduce the above copyright
10
* notice, this list of conditions and the following disclaimer in the
11
* documentation and/or other materials provided with the distribution.
12
* 3. The name of the author may not be used to endorse or promote products
13
* derived from this software without specific prior written permission.
14
*
15
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
16
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
17
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
18
* ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
19
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
20
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
21
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
22
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
23
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
24
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
25
* SUCH DAMAGE.
26
*
27
*
28
* COMMENT: Dreamcast-specific ASIC
29
*
30
* A simple device which forwards various Dreamcast device events as
31
* interrupts 13, 11, or 9, to the CPU.
32
*/
33
34
#include <stdio.h>
35
#include <stdlib.h>
36
#include <string.h>
37
#include <sys/time.h>
38
39
#include "
cpu.h
"
40
#include "
device.h
"
41
#include "
machine.h
"
42
#include "
memory.h
"
43
#include "
misc.h
"
44
45
#include "
thirdparty/dreamcast_sysasicvar.h
"
46
#include "
thirdparty/sh4_exception.h
"
47
48
49
// #define debug fatal
50
51
#define DREAMCAST_ASIC_TICK_SHIFT 15
52
53
struct
dreamcast_asic_data
{
54
uint32_t
pending_irq
[3];
55
uint32_t
mask_13
[3];
56
uint32_t
mask_11
[3];
57
uint32_t
mask_9
[3];
58
59
int
asserted_13
;
60
int
asserted_11
;
61
int
asserted_9
;
62
63
struct
interrupt
irq_13
;
64
struct
interrupt
irq_11
;
65
struct
interrupt
irq_9
;
66
};
67
68
69
DEVICE_TICK
(dreamcast_asic)
70
{
71
struct
dreamcast_asic_data
*d = (
struct
dreamcast_asic_data
*) extra;
72
int
i, old_asserted_13 = d->
asserted_13
, old_asserted_11 =
73
d->
asserted_11
, old_asserted_9 = d->
asserted_9
;
74
75
d->
asserted_13
= d->
asserted_11
= d->
asserted_9
= 0;
76
77
for
(i=0; i<3; i++) {
78
if
(d->
pending_irq
[i] & d->
mask_13
[i])
79
d->
asserted_13
= 1;
80
81
if
(d->
pending_irq
[i] & d->
mask_11
[i])
82
d->
asserted_11
= 1;
83
84
if
(d->
pending_irq
[i] & d->
mask_9
[i])
85
d->
asserted_9
= 1;
86
}
87
88
if
(d->
asserted_13
!= old_asserted_13) {
89
if
(d->
asserted_13
)
90
INTERRUPT_ASSERT
(d->
irq_13
);
91
else
92
INTERRUPT_DEASSERT
(d->
irq_13
);
93
}
94
if
(d->
asserted_11
!= old_asserted_11) {
95
if
(d->
asserted_11
)
96
INTERRUPT_ASSERT
(d->
irq_11
);
97
else
98
INTERRUPT_DEASSERT
(d->
irq_11
);
99
}
100
if
(d->
asserted_9
!= old_asserted_9) {
101
if
(d->
asserted_9
)
102
INTERRUPT_ASSERT
(d->
irq_9
);
103
else
104
INTERRUPT_DEASSERT
(d->
irq_9
);
105
}
106
}
107
108
109
DEVICE_ACCESS
(dreamcast_asic)
110
{
111
struct
dreamcast_asic_data
*d = (
struct
dreamcast_asic_data
*) extra;
112
uint64_t idata = 0, odata = 0;
113
int
r;
114
115
if
(writeflag ==
MEM_WRITE
)
116
idata =
memory_readmax64
(
cpu
,
data
, len);
117
118
r = (relative_addr / 4) & 3;
119
if
(r == 3) {
120
fatal
(
"[ dreamcast_asic: Bad address ]\n"
);
121
r = 0;
122
exit(1);
// TODO?
123
}
124
125
switch
(relative_addr) {
126
127
case
0:
128
case
4:
129
case
8:
if
(writeflag ==
MEM_READ
) {
130
odata = d->
pending_irq
[r];
131
}
else
{
132
/* Should only be used interally by GXemul: */
133
if
(idata & 0x100000000ULL) {
134
/* Set specific bits: */
135
d->
pending_irq
[r] |= idata;
136
}
else
{
137
/* Clear interrupt assertions: */
138
d->
pending_irq
[r] &= ~idata;
139
}
140
dev_dreamcast_asic_tick(
cpu
, d);
141
}
142
break
;
143
144
case
0x10:
145
case
0x14:
146
case
0x18:
147
if
(writeflag ==
MEM_WRITE
) {
148
d->
mask_13
[r] = idata;
149
dev_dreamcast_asic_tick(
cpu
, d);
150
}
else
{
151
odata = d->
mask_13
[r];
152
}
153
break
;
154
155
case
0x20:
156
case
0x24:
157
case
0x28:
158
if
(writeflag ==
MEM_WRITE
) {
159
d->
mask_11
[r] = idata;
160
dev_dreamcast_asic_tick(
cpu
, d);
161
}
else
{
162
odata = d->
mask_11
[r];
163
}
164
break
;
165
166
case
0x30:
167
case
0x34:
168
case
0x38:
169
if
(writeflag ==
MEM_WRITE
) {
170
d->
mask_9
[r] = idata;
171
dev_dreamcast_asic_tick(
cpu
, d);
172
}
else
{
173
odata = d->
mask_9
[r];
174
}
175
break
;
176
177
default
:
if
(writeflag ==
MEM_READ
) {
178
debug
(
"[ dreamcast_asic: read from addr 0x%x ]\n"
,
179
(
int
)relative_addr);
180
}
else
{
181
debug
(
"[ dreamcast_asic: write to addr 0x%x: 0x%x ]\n"
,
182
(
int
)relative_addr, (
int
)idata);
183
}
184
}
185
186
if
(writeflag ==
MEM_READ
)
187
memory_writemax64
(
cpu
,
data
, len, odata);
188
189
return
1;
190
}
191
192
193
DEVINIT
(dreamcast_asic)
194
{
195
char
tmpstr[300];
196
struct
machine
*
machine
=
devinit
->
machine
;
197
struct
dreamcast_asic_data
*d;
198
199
CHECK_ALLOCATION
(d = (
struct
dreamcast_asic_data
*) malloc(
sizeof
(
struct
dreamcast_asic_data
)));
200
memset(d, 0,
sizeof
(
struct
dreamcast_asic_data
));
201
202
/* Connect to SH4 interrupt levels 13, 11, and 9: */
203
snprintf(tmpstr,
sizeof
(tmpstr),
"%s.irq[0x%x]"
,
204
devinit
->
interrupt_path
,
SH_INTEVT_IRL13
);
205
INTERRUPT_CONNECT
(tmpstr, d->
irq_13
);
206
snprintf(tmpstr,
sizeof
(tmpstr),
"%s.irq[0x%x]"
,
207
devinit
->
interrupt_path
,
SH_INTEVT_IRL11
);
208
INTERRUPT_CONNECT
(tmpstr, d->
irq_11
);
209
snprintf(tmpstr,
sizeof
(tmpstr),
"%s.irq[0x%x]"
,
210
devinit
->
interrupt_path
,
SH_INTEVT_IRL9
);
211
INTERRUPT_CONNECT
(tmpstr, d->
irq_9
);
212
213
memory_device_register
(
machine
->
memory
,
devinit
->
name
,
SYSASIC_BASE
,
214
SYSASIC_SIZE
, dev_dreamcast_asic_access, d,
DM_DEFAULT
, NULL);
215
216
machine_add_tickfunction
(
devinit
->
machine
, dev_dreamcast_asic_tick, d,
217
DREAMCAST_ASIC_TICK_SHIFT
);
218
219
return
1;
220
}
221
data
u_short data
Definition:
siireg.h:79
dreamcast_sysasicvar.h
INTERRUPT_CONNECT
#define INTERRUPT_CONNECT(name, istruct)
Definition:
interrupt.h:77
dreamcast_asic_data::irq_11
struct interrupt irq_11
Definition:
dev_dreamcast_asic.cc:64
INTERRUPT_ASSERT
#define INTERRUPT_ASSERT(istruct)
Definition:
interrupt.h:74
dreamcast_asic_data::irq_13
struct interrupt irq_13
Definition:
dev_dreamcast_asic.cc:63
debug
#define debug
Definition:
dev_adb.cc:57
SYSASIC_SIZE
#define SYSASIC_SIZE
Definition:
dreamcast_sysasicvar.h:50
DEVICE_TICK
DEVICE_TICK(dreamcast_asic)
Definition:
dev_dreamcast_asic.cc:69
memory_device_register
void memory_device_register(struct memory *mem, const char *, uint64_t baseaddr, uint64_t len, int(*f)(struct cpu *, struct memory *, uint64_t, unsigned char *, size_t, int, void *), void *extra, int flags, unsigned char *dyntrans_data)
Definition:
memory.cc:339
MEM_READ
#define MEM_READ
Definition:
memory.h:116
DM_DEFAULT
#define DM_DEFAULT
Definition:
memory.h:130
devinit::machine
struct machine * machine
Definition:
device.h:41
dreamcast_asic_data::asserted_11
int asserted_11
Definition:
dev_dreamcast_asic.cc:60
dreamcast_asic_data::mask_9
uint32_t mask_9[3]
Definition:
dev_dreamcast_asic.cc:57
device.h
dreamcast_asic_data
Definition:
dev_dreamcast_asic.cc:53
MEM_WRITE
#define MEM_WRITE
Definition:
memory.h:117
machine_add_tickfunction
void machine_add_tickfunction(struct machine *machine, void(*func)(struct cpu *, void *), void *extra, int clockshift)
Definition:
machine.cc:280
devinit::interrupt_path
char * interrupt_path
Definition:
device.h:50
fatal
void fatal(const char *fmt,...)
Definition:
main.cc:152
SH_INTEVT_IRL13
#define SH_INTEVT_IRL13
Definition:
sh4_exception.h:102
misc.h
memory_readmax64
uint64_t memory_readmax64(struct cpu *cpu, unsigned char *buf, int len)
Definition:
memory.cc:55
machine.h
machine
Definition:
machine.h:97
devinit::name
char * name
Definition:
device.h:43
DEVINIT
DEVINIT(dreamcast_asic)
Definition:
dev_dreamcast_asic.cc:193
SYSASIC_BASE
#define SYSASIC_BASE
Definition:
dreamcast_sysasicvar.h:49
devinit
Definition:
device.h:40
DEVICE_ACCESS
DEVICE_ACCESS(dreamcast_asic)
Definition:
dev_dreamcast_asic.cc:109
cpu.h
sh4_exception.h
dreamcast_asic_data::asserted_13
int asserted_13
Definition:
dev_dreamcast_asic.cc:59
machine::memory
struct memory * memory
Definition:
machine.h:126
dreamcast_asic_data::irq_9
struct interrupt irq_9
Definition:
dev_dreamcast_asic.cc:65
DREAMCAST_ASIC_TICK_SHIFT
#define DREAMCAST_ASIC_TICK_SHIFT
Definition:
dev_dreamcast_asic.cc:51
dreamcast_asic_data::mask_13
uint32_t mask_13[3]
Definition:
dev_dreamcast_asic.cc:55
INTERRUPT_DEASSERT
#define INTERRUPT_DEASSERT(istruct)
Definition:
interrupt.h:75
SH_INTEVT_IRL9
#define SH_INTEVT_IRL9
Definition:
sh4_exception.h:100
interrupt
Definition:
interrupt.h:36
memory_writemax64
void memory_writemax64(struct cpu *cpu, unsigned char *buf, int len, uint64_t data)
Definition:
memory.cc:89
dreamcast_asic_data::mask_11
uint32_t mask_11[3]
Definition:
dev_dreamcast_asic.cc:56
dreamcast_asic_data::pending_irq
uint32_t pending_irq[3]
Definition:
dev_dreamcast_asic.cc:54
dreamcast_asic_data::asserted_9
int asserted_9
Definition:
dev_dreamcast_asic.cc:61
SH_INTEVT_IRL11
#define SH_INTEVT_IRL11
Definition:
sh4_exception.h:101
cpu
Definition:
cpu.h:326
memory.h
CHECK_ALLOCATION
#define CHECK_ALLOCATION(ptr)
Definition:
misc.h:239
Generated on Tue Aug 25 2020 19:25:06 for GXemul by
1.8.18