162 lines
3.8 KiB
D
162 lines
3.8 KiB
D
|
/+
|
||
|
+ device/paddle.d
|
||
|
+
|
||
|
+ Copyright: 2007 Gerald Stocker
|
||
|
+
|
||
|
+ This file is part of Twoapple.
|
||
|
+
|
||
|
+ Twoapple is free software; you can redistribute it and/or modify
|
||
|
+ it under the terms of the GNU General Public License as published by
|
||
|
+ the Free Software Foundation; either version 2 of the License, or
|
||
|
+ (at your option) any later version.
|
||
|
+
|
||
|
+ Twoapple is distributed in the hope that it will be useful,
|
||
|
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||
|
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||
|
+ GNU General Public License for more details.
|
||
|
+
|
||
|
+ You should have received a copy of the GNU General Public License
|
||
|
+ along with Twoapple; if not, write to the Free Software
|
||
|
+ Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
|
||
|
+/
|
||
|
|
||
|
module device.paddle;
|
||
|
|
||
|
import device.base;
|
||
|
import timer;
|
||
|
import memory;
|
||
|
|
||
|
class Paddles
|
||
|
{
|
||
|
Timer timer;
|
||
|
|
||
|
int numPaddles;
|
||
|
int[4] onTrigger;
|
||
|
bool[4] stillTiming;
|
||
|
ubyte[4] switchVal;
|
||
|
|
||
|
this()
|
||
|
{
|
||
|
numPaddles = 4;
|
||
|
}
|
||
|
|
||
|
void reboot()
|
||
|
{
|
||
|
onTrigger[0..4] = 1380; // XXX only if no real joystick ??
|
||
|
stillTiming[0..4] = false;
|
||
|
switchVal[0..4] = 0;
|
||
|
}
|
||
|
|
||
|
// XXX II: C07X | IIe Orig: C07X | IIe Enh: C070-C07E
|
||
|
// (IOU gets C07F)
|
||
|
// IIc: as IIe Enh, plus VBLINT?
|
||
|
|
||
|
mixin(InitSwitches("", [
|
||
|
mixin(MakeSwitch(
|
||
|
[0xC070, 0xC071, 0xC072, 0xC073, 0xC074, 0xC075, 0xC076, 0xC077,
|
||
|
0xC078, 0xC079, 0xC07A, 0xC07B, 0xC07C, 0xC07D, 0xC07E],
|
||
|
"R0W", "trigger")),
|
||
|
mixin(MakeSwitch([0xC064, 0xC06C], "R7", "check_pdl_0")),
|
||
|
mixin(MakeSwitch([0xC065, 0xC06D], "R7", "check_pdl_1")),
|
||
|
mixin(MakeSwitch([0xC066, 0xC06E], "R7", "check_pdl_2")),
|
||
|
mixin(MakeSwitch([0xC067, 0xC06F], "R7", "check_pdl_3"))
|
||
|
]));
|
||
|
|
||
|
void update(int pdl, int value)
|
||
|
{
|
||
|
onTrigger[pdl] = value ? value : 1;
|
||
|
}
|
||
|
|
||
|
ubyte check_pdl_0()
|
||
|
{
|
||
|
return switchVal[0];
|
||
|
}
|
||
|
|
||
|
ubyte check_pdl_1()
|
||
|
{
|
||
|
return switchVal[1];
|
||
|
}
|
||
|
ubyte check_pdl_2()
|
||
|
{
|
||
|
return switchVal[2];
|
||
|
}
|
||
|
ubyte check_pdl_3()
|
||
|
{
|
||
|
return switchVal[3];
|
||
|
}
|
||
|
|
||
|
void trigger()
|
||
|
{
|
||
|
for (int i = 0; i < numPaddles; ++i)
|
||
|
{
|
||
|
if (stillTiming[i]) return;
|
||
|
}
|
||
|
for (int i = 0; i < numPaddles; ++i)
|
||
|
{
|
||
|
if (onTrigger[i] == 0) onTrigger[i] = 1;
|
||
|
switchVal[i] = 0x80;
|
||
|
}
|
||
|
timer.new Counter(onTrigger[0], &pdl_0_expired);
|
||
|
timer.new Counter(onTrigger[1], &pdl_1_expired);
|
||
|
if (numPaddles > 2)
|
||
|
{
|
||
|
timer.new Counter(onTrigger[2], &pdl_2_expired);
|
||
|
timer.new Counter(onTrigger[3], &pdl_3_expired);
|
||
|
}
|
||
|
}
|
||
|
|
||
|
bool pdl_0_expired()
|
||
|
{
|
||
|
stillTiming[0] = false;
|
||
|
switchVal[0] = 0x00;
|
||
|
return false;
|
||
|
}
|
||
|
|
||
|
bool pdl_1_expired()
|
||
|
{
|
||
|
stillTiming[1] = false;
|
||
|
switchVal[1] = 0x00;
|
||
|
return false;
|
||
|
}
|
||
|
|
||
|
bool pdl_2_expired()
|
||
|
{
|
||
|
stillTiming[2] = false;
|
||
|
switchVal[2] = 0x00;
|
||
|
return false;
|
||
|
}
|
||
|
|
||
|
bool pdl_3_expired()
|
||
|
{
|
||
|
stillTiming[3] = false;
|
||
|
switchVal[3] = 0x00;
|
||
|
return false;
|
||
|
}
|
||
|
}
|
||
|
|
||
|
// NOTE: IIe Unenhanced uses Paddles_II; IIe enhanced uses Paddles
|
||
|
// (because C07F is handled first by IOU)
|
||
|
|
||
|
class Paddles_II : Paddles
|
||
|
{
|
||
|
mixin(InitSwitches("super", [
|
||
|
mixin(MakeSwitch([0xC07F], "R0W", "trigger"))
|
||
|
]));
|
||
|
}
|
||
|
|
||
|
// XXX IIc: 0xC07X resets VBLINT along with triggering timers,
|
||
|
// C07E/C07F as IIe enhanced, maybe more? (and there
|
||
|
// are only two paddles, so no C066/C067/C06E/C06F)
|
||
|
|
||
|
class Paddles_IIc : Paddles
|
||
|
{
|
||
|
// XXX add the switches
|
||
|
mixin(EmptyInitSwitches());
|
||
|
|
||
|
this()
|
||
|
{
|
||
|
super();
|
||
|
numPaddles = 2;
|
||
|
}
|
||
|
}
|