Xemu [doxygen]
hyppo 0a42be3a057156924bc1b626a687bd6e27349c45 @ Sat 19 Mar 02:15:11 CET 2022
xemu
via65c22.c
Go to the documentation of this file.
1
/* Part of the Xemu project, please visit: https://github.com/lgblgblgb/xemu
2
Copyright (C)2016,2020 LGB (Gábor Lénárt) <lgblgblgb@gmail.com>
3
4
This program is free software; you can redistribute it and/or modify
5
it under the terms of the GNU General Public License as published by
6
the Free Software Foundation; either version 2 of the License, or
7
(at your option) any later version.
8
9
This program is distributed in the hope that it will be useful,
10
but WITHOUT ANY WARRANTY; without even the implied warranty of
11
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12
GNU General Public License for more details.
13
14
You should have received a copy of the GNU General Public License
15
along with this program; if not, write to the Free Software
16
Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */
17
18
/* Commodore LCD emulator, C version.
19
* (C)2013,2014 LGB Gabor Lenart
20
* Visit my site (the better, JavaScript version of the emu is here too): http://commodore-lcd.lgb.hu/
21
* Can be distributed/used/modified under the terms of GNU/GPL 3 (or later), please see file COPYING
22
* or visit this page: http://www.gnu.org/licenses/gpl-3.0.html
23
*/
24
25
#include "
xemu/emutools_basicdefs.h
"
26
#include "
xemu/via65c22.h
"
27
28
#define INA(via) (via->ina)(0xFF)
29
#define INB(via) ((via->ORB & via->DDRB) | ((via->inb)(255 - via->DDRB) & (255 - via->DDRB)))
30
#define OUTA(via, data) (via->outa)(via->DDRA, data)
31
#define OUTB(via, data) (via->outb)(via->DDRB, data)
32
#define INT(via, level) (via->setint)(via->irqLevel = level)
33
#define alert(via, msg) DEBUG("%s: ALERT: %s" NL, via->name, msg)
34
#define INSR(via) (via->insr)()
35
#define OUTSR(via, data) (via->outsr)(data)
36
37
static
inline
void
ifr_check(
struct
Via65c22
*via)
38
{
39
if
(via->
IFR
& via->
IER
& 127) {
40
via->
IFR
|= 128;
41
if
(!via->
irqLevel
)
INT
(via, 1);
42
}
else
{
43
via->
IFR
&= 127;
44
if
( via->
irqLevel
)
INT
(via, 0);
45
}
46
}
47
48
static
inline
void
ifr_clear (
struct
Via65c22
*via,
Uint8
mask
) { via->
IFR
&= 255 -
mask
; ifr_check(via); }
49
static
inline
void
ifr_set (
struct
Via65c22
*via,
Uint8
mask
) { via->
IFR
|=
mask
; ifr_check(via); }
50
static
inline
void
ifr_on_pa (
struct
Via65c22
*via) { ifr_clear(via, ((via->
PCR
& 0x0E) == 0x02 || (via->
PCR
& 0x0E) == 0x06) ? 2 : 3); }
51
static
inline
void
ifr_on_pb (
struct
Via65c22
*via) { ifr_clear(via, ((via->
PCR
& 0xE0) == 0x20 || (via->
PCR
& 0xE0) == 0x60) ? 0x10 : 0x18); }
52
53
54
55
56
void
via_reset
(
struct
Via65c22
*via)
57
{
58
//via->ACR = via->PCR = via->DDRA = via->DDRB = via->ORA = via->ORB = 0;
59
via->
ORA
= via->
ORB
= via->
DDRA
= via->
DDRB
= 0;
60
via->
SR
= via->
SRcount
= via->
SRmode
= via->
IER
= via->
IFR
= via->
ACR
= via->
PCR
= 0;
61
via->
T1C
= via->
T2C
= via->
T1LL
= via->
T1LH
= via->
T2LL
= via->
T2LH
= 0;
62
via->
T1run
= via->
T2run
= 0;
// false
63
INT
(via, 0);
64
DEBUG
(
"%s: RESET"
NL
, via->
name
);
65
}
66
67
68
static
void
def_outa (
Uint8
mask
,
Uint8
data
) {}
69
static
void
def_outb (
Uint8
mask
,
Uint8
data
) {}
70
static
void
def_outsr (
Uint8
data
) {}
71
static
Uint8
def_ina (
Uint8
mask
) {
return
0xFF; }
72
static
Uint8
def_inb (
Uint8
mask
) {
return
0xFF; }
73
static
Uint8
def_insr (
void
) {
return
0xFF; }
74
static
void
def_setint(
int
level) {}
75
76
77
void
via_init
(
78
struct
Via65c22
*via,
const
char
*
name
,
79
void
(*outa)(
Uint8
mask
,
Uint8
data
),
80
void
(*outb)(
Uint8
mask
,
Uint8
data
),
81
void
(*outsr)(
Uint8
data
),
82
Uint8
(*ina)(
Uint8
mask
),
83
Uint8
(*inb)(
Uint8
mask
),
84
Uint8
(*insr)(
void
),
85
void
(*setint)(
int
level)
86
) {
87
via->
name
=
name
;
88
via->
outa
= outa ? outa : def_outa;
89
via->
outb
= outb ? outb : def_outb;
90
via->
outsr
= outsr ? outsr : def_outsr;
91
via->
ina
= ina ? ina : def_ina;
92
via->
inb
= inb ? inb : def_inb;
93
via->
insr
= insr ? insr : def_insr;
94
via->
setint
= setint ? setint : def_setint;
95
via_reset
(via);
96
}
97
98
99
void
via_write
(
struct
Via65c22
*via,
int
addr
,
Uint8
data
)
100
{
101
//DEBUG("%s: write reg %02X with data %02X" NL, via->name, addr, data);
102
switch
(
addr
) {
103
case
0x0:
// port B data
104
via->
ORB
=
data
;
// FIXED BUG
105
OUTB
(via,
data
);
106
ifr_on_pb(via);
107
break
;
108
case
0x1:
// port A data
109
via->
ORA
=
data
;
// FIXED BUG
110
OUTA
(via,
data
);
111
ifr_on_pa(via);
112
break
;
113
case
0x2:
// port B DDR
114
if
(
data
!= via->
DDRB
) {
115
via->
DDRB
=
data
;
116
OUTB
(via, via->
ORB
);
117
}
118
break
;
119
case
0x3:
// port A DDR
120
if
(
data
!= via->
DDRA
) {
121
via->
DDRA
=
data
;
122
OUTA
(via, via->
ORA
);
123
}
124
break
;
125
case
0x4:
//
126
via->
T1LL
=
data
;
127
break
;
128
case
0x5:
129
via->
T1LH
=
data
;
130
ifr_clear(via, 64);
131
via->
T1run
= 1;
132
via->
T1C
= via->
T1LL
| (via->
T1LH
<< 8);
133
break
;
134
case
0x6:
135
via->
T1LL
=
data
;
136
break
;
137
case
0x7:
138
via->
T1LH
=
data
;
139
ifr_clear(via, 64);
140
break
;
141
case
0x8:
142
via->
T2LL
=
data
;
143
break
;
144
case
0x9:
145
via->
T2LH
=
data
;
146
ifr_clear(via, 32);
147
via->
T2run
= 1;
148
via->
T2C
= via->
T2LL
| (via->
T2LH
<< 8);
149
break
;
150
case
0xA:
// SR
151
ifr_clear(via, 4);
152
via->
SR
=
data
;
153
if
(via->
SRmode
) via->
SRcount
= 8;
154
break
;
155
case
0xB:
// ACR
156
via->
SRmode
= (
data
>> 2) & 7;
157
via->
ACR
=
data
;
158
if
(
data
& 32)
alert
(via,
"pulse counting T2 mode is not supported!"
);
159
break
;
160
case
0xC:
// PCR
161
via->
PCR
=
data
;
162
break
;
163
case
0xD:
// IFR
164
ifr_clear(via,
data
);
165
break
;
166
case
0xE:
// IER
167
if
(
data
& 128) via->
IER
|=
data
;
else
via->
IER
&= (255 -
data
);
168
ifr_check(via);
169
break
;
170
case
0xF:
// port A data (no handshake)
171
OUTA
(via,
data
);
172
ifr_on_pa(via);
173
break
;
174
}
175
}
176
177
Uint8
via_read
(
struct
Via65c22
*via,
int
addr
)
178
{
179
//DEBUG("%s: read reg %02X" NL, via->name, addr);
180
switch
(
addr
) {
181
case
0x0:
// port B data
182
ifr_on_pb(via);
183
return
INB
(via);
184
case
0x1:
// port A data
185
ifr_on_pa(via);
186
return
INA
(via);
187
case
0x2:
// port B DDR
188
return
via->
DDRB
;
189
case
0x3:
// port A DDR
190
return
via->
DDRA
;
191
case
0x4:
//
192
ifr_clear(via, 64);
193
return
via->
T1C
& 0xFF;
194
case
0x5:
195
return
via->
T1C
>> 8;
196
case
0x6:
197
return
via->
T1LL
;
198
case
0x7:
199
return
via->
T1C
>> 8;
200
case
0x8:
201
ifr_clear(via, 32);
202
return
via->
T2C
& 0xFF;
203
case
0x9:
204
return
via->
T2C
>> 8;
205
case
0xA:
// SR
206
ifr_clear(via, 4);
207
if
(via->
SRmode
) via->
SRcount
= 8;
208
return
via->
SR
;
209
case
0xB:
// ACR
210
return
via->
ACR
;
211
case
0xC:
// PCR
212
return
via->
PCR
;
213
case
0xD:
// IFR
214
return
via->
IFR
;
215
case
0xE:
// IER
216
return
via->
IER
| 128;
217
case
0xF:
// port A data (no handshake)
218
ifr_on_pa(via);
219
return
INA
(via);
220
}
221
return
0;
// make gcc happy :)
222
}
223
224
void
via_tick
(
struct
Via65c22
*via,
int
ticks)
225
{
226
/* T1 */
227
if
(via->
T1run
) {
228
via->
T1C
-= ticks;
229
if
(via->
T1C
<= 0) {
230
//console.log("Expired T1");
231
ifr_set(via, 64);
232
if
(via->
ACR
& 64) via->
T1C
= via->
T1LL
| (via->
T1LH
<< 8);
else
via->
T1run
= 0;
233
}
234
}
235
/* T2 */
236
via->
T2C
-= ticks;
237
if
(via->
T2run
) {
238
if
(via->
T2C
<= 0) {
239
ifr_set(via, 32);
240
via->
T2run
= 0;
241
}
242
}
243
via->
T2C
&= 0xFFFF;
244
/* shift register */
245
if
(via->
SRcount
) {
246
via->
SRcount
-= ticks;
247
if
(via->
SRcount
<= 0) {
248
switch
(via->
SRmode
) {
249
case
0: via->
SRcount
= 0; ifr_clear(via, 4);
break
;
// disabled
250
case
2: via->
SR
=
INSR
(via); via->
SRcount
= 0; ifr_set(via, 4);
break
;
// PHI2-in
251
case
4:
OUTSR
(via, via->
SR
); via->
SRcount
= via->
T2LL
+ 2; ifr_clear(via, 4);
break
;
// free-T2-out, VIA2 seems to use this mode!
252
default
: via->
SRcount
= 0 ; ifr_clear(via, 4);
alert
(via,
"SRmode is not supported!"
);
break
;
253
}
254
}
255
}
256
}
via_tick
void via_tick(struct Via65c22 *via, int ticks)
Definition:
via65c22.c:224
Via65c22::DDRA
Uint8 DDRA
Definition:
via65c22.h:30
Via65c22::ORB
Uint8 ORB
Definition:
via65c22.h:30
Via65c22::T2C
int T2C
Definition:
via65c22.h:31
Via65c22::T1run
int T1run
Definition:
via65c22.h:32
OUTB
#define OUTB(via, data)
Definition:
via65c22.c:31
Via65c22::name
const char * name
Definition:
via65c22.h:29
Via65c22::PCR
Uint8 PCR
Definition:
via65c22.h:30
Via65c22::ina
Uint8(* ina)(Uint8 mask)
Definition:
via65c22.h:25
via65c22.h
Via65c22::ACR
Uint8 ACR
Definition:
via65c22.h:30
Via65c22::T2LL
Uint8 T2LL
Definition:
via65c22.h:30
Via65c22::T1LH
Uint8 T1LH
Definition:
via65c22.h:30
addr
int addr
Definition:
dma65.c:81
Via65c22::T1LL
Uint8 T1LL
Definition:
via65c22.h:30
Via65c22::ORA
Uint8 ORA
Definition:
via65c22.h:30
OUTSR
#define OUTSR(via, data)
Definition:
via65c22.c:35
m65-memcontent-generator.data
data
Definition:
m65-memcontent-generator.py:119
alert
#define alert(via, msg)
Definition:
via65c22.c:33
INSR
#define INSR(via)
Definition:
via65c22.c:34
Via65c22
Definition:
via65c22.h:21
Uint8
uint8_t Uint8
Definition:
fat32.c:51
Via65c22::outa
void(* outa)(Uint8 mask, Uint8 data)
Definition:
via65c22.h:22
Via65c22::IFR
Uint8 IFR
Definition:
via65c22.h:30
emutools_basicdefs.h
Via65c22::irqLevel
int irqLevel
Definition:
via65c22.h:32
via_init
void via_init(struct Via65c22 *via, const char *name, void(*outa)(Uint8 mask, Uint8 data), void(*outb)(Uint8 mask, Uint8 data), void(*outsr)(Uint8 data), Uint8(*ina)(Uint8 mask), Uint8(*inb)(Uint8 mask), Uint8(*insr)(void), void(*setint)(int level))
Definition:
via65c22.c:77
Via65c22::IER
Uint8 IER
Definition:
via65c22.h:30
OUTA
#define OUTA(via, data)
Definition:
via65c22.c:30
Via65c22::DDRB
Uint8 DDRB
Definition:
via65c22.h:30
NL
#define NL
Definition:
fat32.c:37
Via65c22::outsr
void(* outsr)(Uint8 data)
Definition:
via65c22.h:24
Via65c22::inb
Uint8(* inb)(Uint8 mask)
Definition:
via65c22.h:26
Via65c22::setint
void(* setint)(int level)
Definition:
via65c22.h:28
via_read
Uint8 via_read(struct Via65c22 *via, int addr)
Definition:
via65c22.c:177
via_reset
void via_reset(struct Via65c22 *via)
Definition:
via65c22.c:56
Via65c22::SRmode
int SRmode
Definition:
via65c22.h:32
INT
#define INT(via, level)
Definition:
via65c22.c:32
Via65c22::outb
void(* outb)(Uint8 mask, Uint8 data)
Definition:
via65c22.h:23
INB
#define INB(via)
Definition:
via65c22.c:29
Via65c22::SR
Uint8 SR
Definition:
via65c22.h:30
mask
int mask
Definition:
dma65.c:83
via_write
void via_write(struct Via65c22 *via, int addr, Uint8 data)
Definition:
via65c22.c:99
name
const char * name
Definition:
joystick.c:46
DEBUG
#define DEBUG(...)
Definition:
emutools_basicdefs.h:167
Via65c22::T1C
int T1C
Definition:
via65c22.h:31
Via65c22::T2LH
Uint8 T2LH
Definition:
via65c22.h:30
Via65c22::insr
Uint8(* insr)(void)
Definition:
via65c22.h:27
Via65c22::SRcount
int SRcount
Definition:
via65c22.h:32
INA
#define INA(via)
Definition:
via65c22.c:28
Via65c22::T2run
int T2run
Definition:
via65c22.h:32
Generated by
1.8.17