-
Notifications
You must be signed in to change notification settings - Fork 1
/
tzxblock18.inc
142 lines (113 loc) · 2.94 KB
/
tzxblock18.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
136
137
138
139
140
141
// Copyright 2022-2024 Zoran Vučenović
// SPDX-License-Identifier: Apache-2.0
{$ifdef tzx_header_section}
TTzxBlock18 = class (TTzxBlockStandard)
strict private
type
TCswBlock18 = class(TCswBlock)
end;
strict private
Csw: TCswBlock18;
FPauseAfterBlock: Integer;
strict protected
function Load2(const Stream: TStream; L: Integer): Boolean; override;
protected
function GetTicksNextEdge: Int64; override;
function IsReallyPlayableBlock: Boolean; override;
public
constructor Create(ATapePlayer: TTapePlayer); override;
destructor Destroy; override;
procedure Start; override;
function GetNextPulse: Boolean; override;
class function GetBlockId: DWord; override;
class function GetBlockDescription: String; override;
function GetBlockLength: Integer; override;
procedure Details(out S: String); override;
end;
{$else}
constructor TTzxBlock18.Create(ATapePlayer: TTapePlayer);
begin
inherited Create(ATapePlayer);
Csw := TCswBlock18.Create(ATapePlayer);
end;
destructor TTzxBlock18.Destroy;
begin
Csw.Free;
inherited Destroy;
end;
procedure TTzxBlock18.Start;
begin
inherited Start;
Csw.Start;
if Csw.State = TCswBlock.TCswPlayState.cpsStart then begin
State := TPlayState.psStart;
end;
end;
function TTzxBlock18.GetNextPulse: Boolean;
begin
if State = psFinished then
Exit(False);
if Csw.State <> TCswBlock.TCswPlayState.cpsFinished then
Result := Csw.GetNextPulse
else begin
if FPauseAfterBlock > 0 then begin
FTapePlayer.StartPauseBlock(FPauseAfterBlock);
end;
State := psFinished;
Result := True;
end;
end;
class function TTzxBlock18.GetBlockId: DWord;
begin
Result := $18;
end;
class function TTzxBlock18.GetBlockDescription: String;
begin
Result := 'CSW Recording';
end;
function TTzxBlock18.GetBlockLength: Integer;
begin
Result := FLen;
end;
procedure TTzxBlock18.Details(out S: String);
begin
Csw.Details(S);
S := S + #13 + 'Pause after block: ' + FPauseAfterBlock.ToString + ' ms'
end;
function TTzxBlock18.Load2(const Stream: TStream; L: Integer): Boolean;
var
W: Word;
N: Int32;
B: Byte;
Dw: DWord;
begin
Result := False;
if L >= 10 then begin
if Stream.Read(W{%H-}, 2) = 2 then begin
W := LEtoN(W);
FPauseAfterBlock := W;
if ReadThreeBytes(Stream, N) and (N > 0) and (Stream.Read(B{%H-}, 1) = 1) then begin
Csw.SampleRate := N;
if B = 2 then
Csw.CompressionType := TCswBlock.TCswCompressionType.cctZRle
else
Csw.CompressionType := TCswBlock.TCswCompressionType.cctRle;
if Stream.Read(Dw{%H-}, 4) = 4 then begin
Dw := LEtoN(Dw);
Csw.TotalNumOfPulses := Dw;
Csw.CswDataLength := L - 10;
Result := Csw.LoadBlock(Stream);
end;
end;
end;
end;
end;
function TTzxBlock18.GetTicksNextEdge: Int64;
begin
Result := Csw.GetTicksNextEdge;
end;
function TTzxBlock18.IsReallyPlayableBlock: Boolean;
begin
Result := True;
end;
{$endif}