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
|
unit InstrumentPreview;
{$mode ObjFPC}{$H+}
interface
uses
Classes, SysUtils, instruments, constants, hugedatatypes, symparser, machine, utils;
procedure StartInstrumentPreview(Instr: TInstrument; Note: Integer; SquareOnCh2: Boolean = False);
procedure StopInstrumentPreview(Channel: Integer);
implementation
function GetLabel(Constant: String; Number: Integer): String;
begin
Result := Constant+IntToStr(Number);
end;
procedure StartInstrumentPreview(Instr: TInstrument; Note: Integer; SquareOnCh2: Boolean);
var
Addr: Integer;
AsmInstrument: TAsmInstrument;
HighMask: Integer;
Channel: Integer;
begin
AsmInstrument := InstrumentToBytes(Instr);
case Instr.Type_ of
itSquare: if SquareOnCh2 then Channel := 2 else Channel := 1;
itWave: Channel := 3;
itNoise: Channel := 4;
end;
if Instr.Type_ = itNoise then begin
Addr := SymbolAddress(GetLabel(SYM_HALT_INSTR, Channel));
spokeb(Addr, AsmInstrument[1]);
HighMask := AsmInstrument[0];
if Instr.LengthEnabled then
HighMask := HighMask or %01000000;
if Instr.CounterStep = swSeven then
HighMask := HighMask or %10000000;
spokeb(Addr+3, HighMask);
end else begin
WriteBufferToSymbol(GetLabel(SYM_HALT_INSTR, Channel), AsmInstrument, SizeOf(TAsmInstrument));
end;
WriteBufferToSymbol(GetLabel(SYM_HALT_SUBPATTERN, Channel),
SubpatternToBytes(Instr.Subpattern),
SizeOf(TSubpatternBytes));
WordPokeSymbol(GetLabel(SYM_HALT_PERIOD, Channel), NotesToFreqs.KeyData[Note]);
PokeSymbol(GetLabel(SYM_HALT_NOTE, Channel), Note);
PokeSymbol(GetLabel(SYM_HALT_START, Channel), 1);
if Instr.SubpatternEnabled then
PokeSymbol(GetLabel(SYM_HALT_RUNNING, Channel), 1);
end;
procedure StopInstrumentPreview(Channel: Integer);
begin
PokeSymbol(GetLabel(SYM_HALT_RUNNING, Channel), 0);
end;
end.
|