Commit fd167dc

Nick Faro committed on
WIP table-enabled preview... again
commit fd167dc5e8fd1d62e2efb7aa771997f027ad0f35 parent c86fc07
5 changed files +174−64
Modifiedconstants.pas +0−4
@@ -28,10 +28,6 @@ const
28 SYM_TICKS_PER_ROW = 'ticks_per_row'; 28 SYM_TICKS_PER_ROW = 'ticks_per_row';
29 SYM_ORDER_COUNT = 'order_cnt'; 29 SYM_ORDER_COUNT = 'order_cnt';
30 30
31 SYM_HALT_NOTE = 'note';
32 SYM_HALT_INSTR = 'instr';
33 SYM_HALT_MACRO_INDEX = 'macro_index';
34
35 // Sound controller registers 31 // Sound controller registers
36 NR10 = $FF10; 32 NR10 = $FF10;
37 NR11 = $FF11; 33 NR11 = $FF11;
Modifiedhalt.asm +115−17
@@ -17,6 +17,17 @@ add_a_to_de: MACRO
17 add_a_to_r16 d, e 17 add_a_to_r16 d, e
18 ENDM 18 ENDM
19 19
20
21 SECTION "LCD controller status interrupt", ROM0[$0048]
22 ;; HACK!!!!!!!!!!!!!
23 ;; there's some sort of bug in the emulator which needs to be fixed,
24 ;; which screws up the program counter immediately after it exits a halt.
25 ;; this nop protects against that for now.
26 nop
27 nop
28 nop
29 reti
30
20 SECTION "init", ROM0[$0100] 31 SECTION "init", ROM0[$0100]
21 jp init 32 jp init
22 33
@@ -32,11 +43,6 @@ DB "NF"
32 43
33 SECTION "Vars", WRAM0 44 SECTION "Vars", WRAM0
34 45
35 note1: ds 3
36 note2: ds 3
37 note3: ds 3
38 note4: ds 4
39
40 instrument1: ds 6 46 instrument1: ds 6
41 instrument2: ds 6 47 instrument2: ds 6
42 instrument3: ds 6 48 instrument3: ds 6
@@ -64,35 +70,101 @@ end_zero:
64 SECTION "code", ROM0[$400] 70 SECTION "code", ROM0[$400]
65 71
66 init_note1: 72 init_note1:
67 ld bc, note1 73 ld hl, instrument1
68 call get_current_row
69 call get_note_period
70 ld a, l
71 ld [channel_period1], a
72 ld a, h
73 ld [channel_period1+1], a
74
75 ld a, [hl+] 74 ld a, [hl+]
76 ldh [rAUD1SWEEP], a 75 ldh [rAUD1SWEEP], a
77 ld a, [hl+] 76 ld a, [hl+]
78 ldh [rAUD1LEN], a 77 ldh [rAUD1LEN], a
79 ld a, [hl+] 78 ld a, [hl+]
80 ldh [rAUD1ENV], a 79 ldh [rAUD1ENV], a
80 ld a, [hl]
81 ; ld a, 0
82 ld [highmask1], a
81 83
82 xor a 84 xor a
83 ld [table_row1], a 85 ld [table_row1], a
84 ld [start_ch1], a 86 ld [start_ch1], a
85 inc a 87 inc a
86 ld [highmask1], a
87 ld [running_ch1], a 88 ld [running_ch1], a
88 89
89 jp play_ch1_note 90 jp play_ch1_note
90 91
92 init_note2:
93 ld hl, instrument2
94 inc hl
95 ld a, [hl+]
96 ldh [rAUD2LEN], a
97 ld a, [hl+]
98 ldh [rAUD2ENV], a
99 ld a, [hl]
100 ld [highmask2], a
101
102 xor a
103 ld [table_row2], a
104 ld [start_ch2], a
105 inc a
106 ld [running_ch2], a
107
108 jp play_ch2_note
109
110 init_note3:
111 ld hl, instrument3
112 ld a, [hl+]
113 ldh [rAUD3LEN], a
114 ld a, [hl+]
115 ldh [rAUD3LEVEL], a
116 ld a, [hl+]
117 ld [current_wave], a
118 ld a, [hl]
119 ld [highmask3], a
120
121 xor a
122 ld [table_row3], a
123 ld [start_ch3], a
124 inc a
125 ld [running_ch3], a
126
127 jp play_ch3_note
128
91 run_table1: 129 run_table1:
92 ld bc, subpattern1 130 ld bc, subpattern1
93 ld hl, table_row1 131 ld hl, table_row1
94 ld e, 0 132 ld e, 0
95 jp do_table 133
134 ld a, b
135 or c
136 jp nz, do_table
137 ret
138
139 run_table2:
140 ld bc, subpattern2
141 ld hl, table_row2
142 ld e, 1
143
144 ld a, b
145 or c
146 jp nz, do_table
147 ret
148
149 run_table3:
150 ld bc, subpattern3
151 ld hl, table_row3
152 ld e, 0
153
154 ld a, b
155 or c
156 jp nz, do_table
157 ret
158
159 run_table4:
160 ld bc, subpattern4
161 ld hl, table_row4
162 ld e, 0
163
164 ld a, b
165 or c
166 jp nz, do_table
167 ret
96 168
97 init: 169 init:
98 _addr = _AUD3WAVERAM 170 _addr = _AUD3WAVERAM
@@ -142,12 +214,38 @@ _halt:
142 halt 214 halt
143 nop 215 nop
144 216
217 ld a, [start_ch1]
218 and $FF
219 call nz, init_note1
220
221 ld a, [start_ch2]
222 and $FF
223 call nz, init_note2
224
225 ld a, [start_ch3]
226 and $FF
227 call nz, init_note3
228
229 ; ld a, [start_ch4]
230 ; and $FF
231 ; call nz, init_note4
232
233 ;;;;;;;;;;;;;;;;;;;;;
234
145 ld a, [running_ch1] 235 ld a, [running_ch1]
146 and $FF 236 and $FF
147 call nz, run_table1 237 call nz, run_table1
148 238
149 ld a, [start_ch1] 239 ; ld a, [running_ch2]
240 ; and $FF
241 ; call nz, run_table2
242
243 ld a, [running_ch3]
150 and $FF 244 and $FF
151 call nz, init_note1 245 call nz, run_table3
246
247 ld a, [running_ch4]
248 and $FF
249 call nz, run_table4
152 250
153 jr _halt 251 jr _halt
Modifiedsymparser.pas +15−7
@@ -15,6 +15,7 @@ function WordPeekSymbol(Symbol: String): Integer;
15 procedure WordPokeSymbol(Symbol: String; Value: Word); 15 procedure WordPokeSymbol(Symbol: String; Value: Word);
16 function PeekSymbol(Symbol: String): Integer; 16 function PeekSymbol(Symbol: String): Integer;
17 procedure PokeSymbol(Symbol: String; Value: Byte); 17 procedure PokeSymbol(Symbol: String; Value: Byte);
18 procedure WriteBufferToSymbol(Symbol: String; const Buffer; Count: Integer);
18 19
19 procedure ParseSymFile(F: String); 20 procedure ParseSymFile(F: String);
20 21
@@ -25,16 +26,25 @@ uses machine;
25 var 26 var
26 SymbolTable: TSymbolMap; 27 SymbolTable: TSymbolMap;
27 28
29 procedure WriteBufferToSymbol(Symbol: String; const Buffer; Count: Integer);
30 var
31 I: Integer;
32 Addr: Integer;
33 begin
34 Addr := SymbolAddress(Symbol);
35
36 for I := 0 to Count-1 do
37 spokeb(Addr+I, PByte(@Buffer)[I]);
38 end;
39
28 procedure ParseSymFile(F: String); 40 procedure ParseSymFile(F: String);
29 var 41 var
30 SL: TStringList; 42 SL: TStringList;
31 SA: TStringArray; 43 SA: TStringArray;
32 S: String; 44 S: String;
33 begin 45 begin
34 if Assigned(SymbolTable) then 46 SymbolTable.Clear;
35 SymbolTable.Free;
36 47
37 SymbolTable := TSymbolMap.Create;
38 SL := TStringList.Create; 48 SL := TStringList.Create;
39 try 49 try
40 SL.LoadFromFile(F); 50 SL.LoadFromFile(F);
@@ -62,7 +72,6 @@ end;
62 72
63 function PeekSymbol(Symbol: String): Integer; 73 function PeekSymbol(Symbol: String): Integer;
64 begin 74 begin
65 if SymbolTable = nil then exit(0);
66 if SymbolTable.IndexOf(Symbol) = -1 then begin 75 if SymbolTable.IndexOf(Symbol) = -1 then begin
67 WriteLn(StdErr, '[WARNING] Attempting to peek unloaded symbol: ', symbol); 76 WriteLn(StdErr, '[WARNING] Attempting to peek unloaded symbol: ', symbol);
68 Exit(0); 77 Exit(0);
@@ -73,7 +82,6 @@ end;
73 82
74 procedure PokeSymbol(Symbol: String; Value: Byte); 83 procedure PokeSymbol(Symbol: String; Value: Byte);
75 begin 84 begin
76 if SymbolTable = nil then exit;
77 if SymbolTable.IndexOf(Symbol) = -1 then begin 85 if SymbolTable.IndexOf(Symbol) = -1 then begin
78 WriteLn(StdErr, '[WARNING] Attempting to poke unloaded symbol: ', symbol); 86 WriteLn(StdErr, '[WARNING] Attempting to poke unloaded symbol: ', symbol);
79 Exit; 87 Exit;
@@ -83,7 +91,6 @@ end;
83 91
84 function WordPeekSymbol(Symbol: String): Integer; 92 function WordPeekSymbol(Symbol: String): Integer;
85 begin 93 begin
86 if SymbolTable = nil then exit(0);
87 if SymbolTable.IndexOf(Symbol) = -1 then begin 94 if SymbolTable.IndexOf(Symbol) = -1 then begin
88 WriteLn(StdErr, '[WARNING] Attempting to wordpeek unloaded symbol: ', symbol); 95 WriteLn(StdErr, '[WARNING] Attempting to wordpeek unloaded symbol: ', symbol);
89 Exit(0); 96 Exit(0);
@@ -94,7 +101,6 @@ end;
94 101
95 procedure WordPokeSymbol(Symbol: String; Value: Word); 102 procedure WordPokeSymbol(Symbol: String; Value: Word);
96 begin 103 begin
97 if SymbolTable = nil then exit;
98 if SymbolTable.IndexOf(Symbol) = -1 then begin 104 if SymbolTable.IndexOf(Symbol) = -1 then begin
99 WriteLn(StdErr, '[WARNING] Attempting to wordpoke unloaded symbol: ', symbol); 105 WriteLn(StdErr, '[WARNING] Attempting to wordpoke unloaded symbol: ', symbol);
100 Exit; 106 Exit;
@@ -102,5 +108,7 @@ begin
102 wordpoke(SymbolTable.KeyData[Symbol], Value); 108 wordpoke(SymbolTable.KeyData[Symbol], Value);
103 end; 109 end;
104 110
111 begin
112 SymbolTable := TSymbolMap.Create;
105 end. 113 end.
106 114
Modifiedtracker.pas +16−36
@@ -842,57 +842,37 @@ procedure TfrmTracker.PreviewInstrument(Note: Integer; Instr: TInstrument;
842 SquareOnCh2: Boolean = False); 842 SquareOnCh2: Boolean = False);
843 var 843 var
844 Regs: TRegisters; 844 Regs: TRegisters;
845 AsmInstrument: TAsmInstrument;
845 I, Addr, Freq: Integer; 846 I, Addr, Freq: Integer;
846 begin 847 begin
847 Freq := NotesToFreqs.KeyData[Note]; 848 Freq := NotesToFreqs.KeyData[Note];
849 AsmInstrument := InstrumentToBytes(Instr);
848 850
849 LockPlayback; 851 LockPlayback;
852
850 with Instr do 853 with Instr do
851 begin 854 begin
852 case Type_ of 855 case Type_ of
853 itSquare: begin 856 itSquare: begin
854 Regs := SquareInstrumentToRegisters(Freq, True, Instr); 857 WriteBufferToSymbol('instrument1', AsmInstrument, SizeOf(TAsmInstrument));
855 if SquareOnCh2 then begin 858 WordPokeSymbol('channel_period1', NotesToFreqs.KeyData[Note]);
856 Spokeb(NR21, Regs.NR11); 859 PokeSymbol('channel_note1', Note);
857 Spokeb(NR22, Regs.NR12); 860 WriteBufferToSymbol('subpattern1', SubpatternToBytes(Instr.Subpattern), SizeOf(TSubpatternBytes));
858 Spokeb(NR23, Regs.NR13); 861
859 Spokeb(NR24, Regs.NR14); 862 PokeSymbol('start_ch1', 1);
860 end
861 else begin
862 Spokeb(NR10, Regs.NR10);
863 Spokeb(NR11, Regs.NR11);
864 Spokeb(NR12, Regs.NR12);
865 Spokeb(NR13, Regs.NR13);
866 Spokeb(NR14, Regs.NR14);
867 end;
868 end; 863 end;
869 itWave: begin 864 itWave: begin
870 CopyWaveIntoWaveRam(Waveform); 865 CopyWaveIntoWaveRam(Waveform);
871 Regs := WaveInstrumentToRegisters(Freq, True, Instr);
872 866
873 Spokeb(NR30, Regs.NR30); 867 WriteBufferToSymbol('instrument3', AsmInstrument, SizeOf(TAsmInstrument));
874 Spokeb(NR31, Regs.NR31); 868 WordPokeSymbol('channel_period3', NotesToFreqs.KeyData[Note]);
875 Spokeb(NR32, Regs.NR32); 869 PokeSymbol('channel_note3', Note);
876 Spokeb(NR33, Regs.NR33); 870 WriteBufferToSymbol('subpattern3', SubpatternToBytes(Instr.Subpattern), SizeOf(TSubpatternBytes));
877 Spokeb(NR34, Regs.NR34) 871
872 PokeSymbol('start_ch3', 1);
878 end; 873 end;
879 itNoise: begin 874 itNoise: begin
880 Regs := NoiseInstrumentToRegisters(Freq, True, Instr);
881 if Instr.LengthEnabled then
882 Regs.NR41 := Regs.NR41 or %01000000;
883 if Instr.CounterStep = swSeven then
884 Regs.NR41 := Regs.NR41 or %10000000;
885
886 Addr := SymbolAddress(SYM_HALT_INSTR);
887 Spokeb(Addr, Regs.NR42);
888 Spokeb(Addr+1, Regs.NR41);
889
890 for I := 0 to 5 do begin
891 Spokeb(Addr+2+I, Byte(0));
892 end;
893 875
894 PokeSymbol(SYM_HALT_MACRO_INDEX, 1);
895 PokeSymbol(SYM_HALT_NOTE, Note);
896 end; 876 end;
897 end; 877 end;
898 end; 878 end;
@@ -1377,7 +1357,7 @@ begin
1377 MessageDlg('Error', 1357 MessageDlg('Error',
1378 'An exception in hUGETracker has occured.' + LineEnding + 1358 'An exception in hUGETracker has occured.' + LineEnding +
1379 'Your song has been backed up to the hUGETracker folder, so don''t worry!' + LineEnding+LineEnding+ 1359 'Your song has been backed up to the hUGETracker folder, so don''t worry!' + LineEnding+LineEnding+
1380 'Please report this issue on GitHub, or contact me directly via Discord or Email.'+LineEnding+LineEnding+ 1360 'Please report this issue on GitHub, or contact the maintainer directly via Discord or Email.'+LineEnding+LineEnding+
1381 'Email: '+MaintainerEmail+LineEnding+ 1361 'Email: '+MaintainerEmail+LineEnding+
1382 'Discord: '+MaintainerDiscord+LineEnding+LineEnding+ 1362 'Discord: '+MaintainerDiscord+LineEnding+LineEnding+
1383 'The error is: '+E.ClassName+' with message '+E.Message, 1363 'The error is: '+E.ClassName+' with message '+E.Message,
Modifiedutils.pas +28−0
@@ -7,6 +7,9 @@ interface
7 uses 7 uses
8 Classes, SysUtils, Song, HugeDatatypes, Constants, gHashSet, fgl, instruments, math; 8 Classes, SysUtils, Song, HugeDatatypes, Constants, gHashSet, fgl, instruments, math;
9 9
10 type
11 TSubpatternBytes = array[0..((3*32)-1)] of Byte;
12
10 function Lerp(v0, v1, t: Double): Double; 13 function Lerp(v0, v1, t: Double): Double;
11 function Snap(Value, Every: Integer): Integer; 14 function Snap(Value, Every: Integer): Integer;
12 function ReMap(Value, Istart, Istop, Ostart, Ostop: Double): Double; 15 function ReMap(Value, Istart, Istop, Ostart, Ostop: Double): Double;
@@ -18,6 +21,9 @@ procedure BlankCell(var Cell: TCell);
18 function EffectCodeToStr(Code: Integer; Params: TEffectParams): String; 21 function EffectCodeToStr(Code: Integer; Params: TEffectParams): String;
19 function EffectToExplanation(Code: Integer; Params: TEffectParams): String; 22 function EffectToExplanation(Code: Integer; Params: TEffectParams): String;
20 23
24 procedure DN(Note: Integer; Instrument: Integer; Effect: Integer; out B1, B2, B3: Byte);
25 function SubpatternToBytes(Pat: TPattern): TSubpatternBytes;
26
21 function ModInst(Inst: Integer): Integer; 27 function ModInst(Inst: Integer): Integer;
22 function UnmodInst(Bank: TInstrumentType; Inst: Integer): Integer; 28 function UnmodInst(Bank: TInstrumentType; Inst: Integer): Integer;
23 function InstBankName(Bank: TInstrumentType): String; 29 function InstBankName(Bank: TInstrumentType): String;
@@ -114,6 +120,28 @@ begin
114 end; 120 end;
115 end; 121 end;
116 122
123 procedure DN(Note: Integer; Instrument: Integer; Effect: Integer; out B1, B2, B3: Byte);
124 begin
125 B1 := Byte(Note or ((Instrument and $10) shl 3));
126 B2 := Byte((((Instrument shl 4) and $FF) or (Effect shr 8)));
127 B3 := Byte(Effect and $FF);
128 end;
129
130 function SubpatternToBytes(Pat: TPattern): TSubpatternBytes;
131 var
132 I: Integer;
133 B1, B2, B3: Byte;
134 begin
135 for I := 0 to 31 do begin
136 with Pat[I] do begin
137 DN(Note, IfThen(I = 31, 1, Volume), (EffectCode shl 8) or EffectParams.Value, B1, B2, B3);
138 Result[(I*3) + 0] := B1;
139 Result[(I*3) + 1] := B2;
140 Result[(I*3) + 2] := B3;
141 end;
142 end;
143 end;
144
117 function ModInst(Inst: Integer): Integer; 145 function ModInst(Inst: Integer): Integer;
118 begin 146 begin
119 Result := ((Inst-1) mod 15)+1; 147 Result := ((Inst-1) mod 15)+1;