1//============================================================================
2//
3// SSSS tt lll lll
4// SS SS tt ll ll
5// SS tttttt eeee ll ll aaaa
6// SSSS tt ee ee ll ll aa
7// SS tt eeeeee ll ll aaaaa -- "An Atari 2600 VCS Emulator"
8// SS SS tt ee ll ll aa aa
9// SSSS ttt eeeee llll llll aaaaa
10//
11// Copyright (c) 1995-2019 by Bradford W. Mott, Stephen Anthony
12// and the Stella Team
13//
14// See the file "License.txt" for information on usage and redistribution of
15// this file, and for a DISCLAIMER OF ALL WARRANTIES.
16//============================================================================
17
18#include <cmath>
19
20#include "PaddleReader.hxx"
21
22// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
23PaddleReader::PaddleReader()
24{
25 reset(0);
26}
27
28// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
29void PaddleReader::reset(uInt64 timestamp)
30{
31 myU = 0;
32 myIsDumped = false;
33
34 myValue = 0;
35 myTimestamp = timestamp;
36
37 setConsoleTiming(ConsoleTiming::ntsc);
38}
39
40// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
41void PaddleReader::vblank(uInt8 value, uInt64 timestamp)
42{
43 bool oldIsDumped = myIsDumped;
44
45 if (value & 0x80) {
46 myIsDumped = true;
47 myU = 0;
48 myTimestamp = timestamp;
49 } else if (oldIsDumped) {
50 myIsDumped = false;
51 myTimestamp = timestamp;
52 }
53}
54
55// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
56uInt8 PaddleReader::inpt(uInt64 timestamp)
57{
58 updateCharge(timestamp);
59
60 bool state = myIsDumped ? false : myU > myUThresh;
61
62 return state ? 0x80 : 0;
63}
64
65// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
66void PaddleReader::update(double value, uInt64 timestamp, ConsoleTiming consoleTiming)
67{
68 if (consoleTiming != myConsoleTiming) {
69 setConsoleTiming(consoleTiming);
70 }
71
72 if (value != myValue) {
73 myValue = value;
74
75 if (myValue < 0) {
76 // value < 0 signifies either maximum resistance OR analog input connected to
77 // ground (keyboard controllers). As we have no way to tell these apart we just
78 // assume ground and discharge.
79 myU = 0;
80 myTimestamp = timestamp;
81 } else {
82 updateCharge(timestamp);
83 }
84 }
85}
86
87// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
88void PaddleReader::setConsoleTiming(ConsoleTiming consoleTiming)
89{
90 myConsoleTiming = consoleTiming;
91
92 myClockFreq = myConsoleTiming == ConsoleTiming::ntsc ? 60 * 228 * 262 : 50 * 228 * 312;
93 myUThresh = USUPP * (1. - exp(-TRIPPOINT_LINES * 228 / myClockFreq / (RPOT + R0) / C));
94}
95
96// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
97void PaddleReader::updateCharge(uInt64 timestamp)
98{
99 if (myIsDumped) return;
100
101 if (myValue >= 0)
102 myU = USUPP * (1 - (1 - myU / USUPP) *
103 exp(-static_cast<double>(timestamp - myTimestamp) / (myValue * RPOT + R0) / C / myClockFreq));
104
105 myTimestamp = timestamp;
106}
107
108// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
109bool PaddleReader::save(Serializer& out) const
110{
111 try
112 {
113 out.putDouble(myUThresh);
114 out.putDouble(myU);
115
116 out.putDouble(myValue);
117 out.putLong(myTimestamp);
118
119 out.putInt(int(myConsoleTiming));
120 out.putDouble(myClockFreq);
121
122 out.putBool(myIsDumped);
123 }
124 catch(...)
125 {
126 cerr << "ERROR: TIA_PaddleReader::save" << endl;
127 return false;
128 }
129
130 return true;
131}
132
133// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
134bool PaddleReader::load(Serializer& in)
135{
136 try
137 {
138 myUThresh = in.getDouble();
139 myU = in.getDouble();
140
141 myValue = in.getDouble();
142 myTimestamp = in.getLong();
143
144 myConsoleTiming = ConsoleTiming(in.getInt());
145 myClockFreq = in.getDouble();
146
147 myIsDumped = in.getBool();
148 }
149 catch(...)
150 {
151 cerr << "ERROR: TIA_PaddleReader::load" << endl;
152 return false;
153 }
154
155 return true;
156}
157