src/instrumentpreview.pas1.8 KB · ObjectPascal
Raw
 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.