-
Notifications
You must be signed in to change notification settings - Fork 2
/
tzxblock12.inc
136 lines (111 loc) · 2.86 KB
/
tzxblock12.inc
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
// Copyright 2022-2024 Zoran Vučenović
// SPDX-License-Identifier: Apache-2.0
{$ifdef tzx_header_section}
{ TTzxBlock12 }
TTzxBlock12 = class (TTzxBlock)
private
FLen: Integer;
PulseLen: Integer; // ticks needed
NumOfPulses: Integer; // pulses needed
TicksNeeded: Int64;
TicksNeeded0: Int64;
PulsesNeeded: Integer;
protected
function GetTicksNextEdge: Int64; override;
function IsReallyPlayableBlock: Boolean; override;
public
constructor Create(ATapePlayer: TTapePlayer); override;
class function GetBlockId: DWord; override;
{returns whole block length, without id byte}
function GetBlockLength: Integer; override;
function LoadBlock(const Stream: TStream): Boolean; override;
class function GetBlockDescription: String; override;
function GetNextPulse(): Boolean; override;
procedure Start; override;
procedure Details(out S: String); override;
end;
{$else}
function TTzxBlock12.GetTicksNextEdge: Int64;
begin
Result := TicksNeeded;
end;
function TTzxBlock12.IsReallyPlayableBlock: Boolean;
begin
Result := True;
end;
constructor TTzxBlock12.Create(ATapePlayer: TTapePlayer);
begin
inherited Create(ATapePlayer);
FLen := 0;
end;
class function TTzxBlock12.GetBlockId: DWord;
begin
Result := $12;
end;
function TTzxBlock12.GetBlockLength: Integer;
begin
Result := FLen;
end;
function TTzxBlock12.LoadBlock(const Stream: TStream): Boolean;
var
W: Word;
begin
Result := False;
if Stream.Size >= Stream.Position + 4 then begin
if Stream.Read(W{%H-}, 2) = 2 then begin
W := LEtoN(W);
PulseLen := W;
if Stream.Read(W, 2) = 2 then begin
Result := True;
FLen := 4;
W := LEtoN(W);
NumOfPulses := W;
end;
end;
end;
end;
class function TTzxBlock12.GetBlockDescription: String;
begin
Result := 'Pure Tone';
end;
function TTzxBlock12.GetNextPulse: Boolean;
var
ProcTicks: Int64;
begin
if State = TPlayState.psFinished then
Exit(False);
ProcTicks := GetCurrentTotalSpectrumTicks;
if ProcTicks >= TicksNeeded then begin
if State <> TPlayState.psStart then
FTapePlayer.ActiveBit := FTapePlayer.ActiveBit xor %01000000;
Dec(PulsesNeeded);
if PulsesNeeded = 0 then begin
case State of
TPlayState.psStart:
begin
State := TPlayState.psData;
PulsesNeeded := NumOfPulses;
end;
otherwise
State := TPlayState.psFinished;
end;
end;
TicksNeeded := ProcTicks + TicksNeeded0;
end;
Result := True;
end;
procedure TTzxBlock12.Start;
begin
inherited Start;
State := TPlayState.psStart;
TicksNeeded := TicksNeeded.MinValue;
PulsesNeeded := 1;
TicksNeeded0 := PulseLen;
AdjustTicksIfNeeded(TicksNeeded0);
end;
procedure TTzxBlock12.Details(out S: String);
begin
S := 'Number of pulses: ' + NumOfPulses.ToString
+ #13 + 'Pulse length: ' + PulseLen.ToString;
end;
{$endif}