VirtualC64 v5.0 beta
Commodore 64 Emulator
Loading...
Searching...
No Matches
Datasette.h
1// -----------------------------------------------------------------------------
2// This file is part of VirtualC64
3//
4// Copyright (C) Dirk W. Hoffmann. www.dirkwhoffmann.de
5// This FILE is dual-licensed. You are free to choose between:
6//
7// - The GNU General Public License v3 (or any later version)
8// - The Mozilla Public License v2
9//
10// SPDX-License-Identifier: GPL-3.0-or-later OR MPL-2.0
11// -----------------------------------------------------------------------------
12
13#pragma once
14
15#include "DatasetteTypes.h"
16#include "C64Types.h"
17#include "CmdQueue.h"
18#include "SubComponent.h"
19#include "Constants.h"
20#include "Chrono.h"
21
22namespace vc64 {
23
24class Pulse {
25
26public:
27
28 i32 cycles;
29
30public:
31
32 Pulse() : cycles(0) { };
33 Pulse(i32 value) : cycles(value) { };
34
35 util::Time delay() const;
36};
37
38class Datasette final : public SubComponent, public Inspectable<DatasetteInfo> {
39
40 Descriptions descriptions = {{
41
42 .name = "Datasette",
43 .description = "Datasette"
44 }};
45
46 ConfigOptions options = {
47
50 };
51
52 // Current configuration
53 DatasetteConfig config = { };
54
55 //
56 // Tape
57 //
58
59 /* Data format (as specified in the TAP file)
60 *
61 * - In TAP format 0, data byte 0 signals a long pulse without stating
62 * its length precisely.
63 *
64 * - In TAP format 1, each 0 is followed by three bytes stating the
65 * precise length in LO_LO_HI_00 format.
66 */
67 u8 type = 0;
68
69 // The pulse buffer
70 Pulse *pulses = nullptr;
71
72 // Number of pulses stored in the pulse buffer
73 isize numPulses = 0;
74
75
76 //
77 // Tape drive
78 //
79
80 // The position of the read/write head inside the pulse buffer (0 ... size)
81 isize head = 0;
82
83 // The tape counter (time between start and the current head position)
84 util::Time counter;
85
86 // State of the play key
87 bool playKey = false;
88
89 // State of the drive motor
90 bool motor = false;
91
92 // Next scheduled rising edge on data line
93 i64 nextRisingEdge = 0;
94
95 // Next scheduled falling edge on data line
96 i64 nextFallingEdge = 0;
97
98
99 //
100 // Methods
101 //
102
103public:
104
105 Datasette(C64 &ref) : SubComponent(ref) { };
106 ~Datasette();
107
108 void alloc(isize capacity);
109 void dealloc();
110
111 Datasette& operator= (const Datasette& other);
112
113
114 //
115 // Methods from Serializable
116 //
117
118public:
119
120 template <class T>
121 void serialize(T& worker)
122 {
123 worker
124
125 << head
126 << counter.ticks
127 << playKey
128 << motor
129 << nextRisingEdge
130 << nextFallingEdge;
131
132 if (isResetter(worker)) return;
133
134 worker
135
136 << type;
137 }
138
139 void operator << (SerChecker &worker) override { serialize(worker); }
140 void operator << (SerCounter &worker) override;
141 void operator << (SerResetter &worker) override { serialize(worker); }
142 void operator << (SerReader &worker) override;
143 void operator << (SerWriter &worker) override;
144
145
146 //
147 // Methods from CoreComponent
148 //
149
150public:
151
152 const Descriptions &getDescriptions() const override { return descriptions; }
153
154private:
155
156 void _dump(Category category, std::ostream& os) const override;
157
158
159 //
160 // Methods from Inspectable
161 //
162
163public:
164
165 void cacheInfo(DatasetteInfo &result) const override;
166
167
168 //
169 // Methods from Configurable
170 //
171
172public:
173
174 const DatasetteConfig &getConfig() const { return config; }
175 const ConfigOptions &getOptions() const override { return options; }
176 i64 getOption(Option opt) const override;
177 void checkOption(Option opt, i64 value) override;
178 void setOption(Option opt, i64 value) override;
179
180
181 //
182 // Handling tapes
183 //
184
185public:
186
187 // Returns true if a tape is inserted
188 bool hasTape() const { return numPulses != 0; }
189
190 // Returns the duration from the tape start and the specified position
191 util::Time tapeDuration(isize pos);
192
193 // Returns the duration of the entire tape
194 util::Time tapeDuration() { return tapeDuration(numPulses); }
195
196 // Returns the current tape counter in (truncated) seconds
197 isize getCounter() const { return (isize)counter.asSeconds(); }
198
199 //Inserts a TAP archive as a virtual tape
200 void insertTape(class MediaFile &file);
201
202 // Ejects the tape (if any)
203 void ejectTape();
204
205 // Returns the tape type (TAP format, 0 or 1)
206 u8 getType() const { return type; }
207
208
209 //
210 // Operating the device
211 //
212
213public:
214
215 // Returns true if the play key is pressed
216 bool getPlayKey() const { return playKey; }
217
218 // Presses the play key
219 void pressPlay();
220
221 // Presses the stop key
222 void pressStop();
223
224private:
225
226 // Performs the pressPlay action
227 void play();
228
229 // Performs the pressStop action
230 void stop();
231
232
233 //
234 // Emulating the device
235 //
236
237public:
238
239 // Puts the read/write head at the beginning of the tape
240 void rewind(isize seconds = 0);
241
242 // Returns true if the datasette motor is switched on
243 bool getMotor() const { return motor; }
244
245 // Switches the motor on or off
246 void setMotor(bool value);
247
248private:
249
250 // Advances the read/write head one pulse
251 void advanceHead();
252
253
254
255 //
256 // Processing commands and events
257 //
258
259public:
260
261 // Processes a datasette command
262 void processCommand(const Cmd &cmd);
263
264 // Processes a datesette event
265 void processMotEvent(EventID event);
266 void processDatEvent(EventID event, i64 cycles);
267
268private:
269
270 // Updates the event in the DAT slot
271 void updateDatEvent();
272
273 // Schedules the next event in the DAT slot
274 void scheduleNextDatEvent();
275
276 // Schedules the rising and falling edge of the next pulse
277 void schedulePulse(isize nr);
278};
279
280}
VirtualC64 project namespace.
Definition CmdQueue.cpp:16
@ OPT_DAT_CONNECT
Connection status.
Definition OptionTypes.h:153
@ OPT_DAT_MODEL
Datasette model.
Definition OptionTypes.h:152