Details | Last modification | View Log | RSS feed
Rev | Author | Line No. | Line |
---|---|---|---|
134 | diamond | 1 | SYS equ meos |
2 | midi_parse: |
||
3 | and [max_note],0 |
||
4 | and [cur_track],0 |
||
5 | mov [min_note],0xff |
||
6 | mov edi,[midi_limit] |
||
7 | cmp dword[workarea],'MThd' |
||
8 | je .head_ok |
||
9 | mov edx,sHeadInv |
||
10 | call debug_outstr |
||
11 | jmp clearpath |
||
12 | .head_ok: |
||
13 | cmp dword[workarea+4],0x6000000 |
||
14 | je .heads_ok |
||
15 | mov edx,sHSizeInv |
||
16 | call debug_outstr |
||
17 | jmp clearpath |
||
18 | .heads_ok: |
||
19 | cmp dword[workarea+8],0x1000000 |
||
20 | jmp .headt_ok |
||
21 | mov edx,sTypeUnsup |
||
22 | call debug_outstr |
||
23 | jmp clearpath |
||
24 | .headt_ok: |
||
25 | movzx eax,word[workarea+12] |
||
26 | rol ax,8 |
||
27 | mov [quarter],eax |
||
28 | mov [tempo],50 |
||
29 | mov esi,workarea+0xe |
||
30 | skip_sections: |
||
31 | lodsd |
||
32 | cmp eax,'MTrk' |
||
33 | je track_found |
||
34 | if SYS eq meos |
||
35 | ; dps <'What?',13,10> |
||
36 | end if |
||
37 | lodsd |
||
38 | add esi,eax |
||
39 | cmp esi,[midi_limit] |
||
40 | jbe skip_sections |
||
41 | if NONCRITICAL_MSG eq 1 |
||
42 | dps 'No more tracks' |
||
43 | end if |
||
44 | and word[edi],0 |
||
45 | ; ud2 |
||
46 | jmp decode_end |
||
47 | track_found: |
||
48 | if SYS eq meos1 |
||
49 | dps <13,10,'Track '> |
||
50 | push esi |
||
51 | sub esi,workarea |
||
52 | ; dpd esi |
||
53 | pop esi |
||
54 | end if |
||
55 | lodsd |
||
56 | bswap eax |
||
57 | mov bl,[cur_track] |
||
58 | cmp bl,[sel_track] |
||
59 | je .trk_fnd |
||
60 | add esi,eax |
||
61 | jmp next_event.eot |
||
62 | .trk_fnd: |
||
63 | mov [track_len],eax |
||
64 | dps 'TRK' |
||
65 | next_event: |
||
66 | call readvar |
||
67 | ; dpd eax |
||
68 | add [delta],eax |
||
69 | lodsw ; al -event, ah - next byte |
||
70 | if SYS eq meos1 |
||
71 | dph eax |
||
72 | dps <' ',13,10> |
||
73 | newline |
||
74 | end if |
||
75 | test al,0x80 ; check if a valid event |
||
76 | jnz .valid_evt2 |
||
77 | dec esi |
||
78 | shl ax,8 |
||
79 | mov al,[prev_cmd] |
||
80 | jmp .valid_evt |
||
81 | .valid_evt2: |
||
82 | mov [prev_cmd],al |
||
83 | .valid_evt: |
||
84 | cmp al,0xf0 |
||
85 | jne .nosysex |
||
86 | dec esi |
||
87 | call readvar |
||
88 | add esi,eax |
||
89 | jmp next_event |
||
90 | .nosysex: |
||
91 | cmp al,0xff |
||
92 | jne .no_meta |
||
93 | |||
94 | ; meta events |
||
95 | cmp ah,0x51 |
||
96 | jne .notempo |
||
97 | push eax edx |
||
98 | mov eax,[esi] |
||
99 | xor al,al |
||
100 | bswap eax |
||
101 | xor edx,edx |
||
102 | mov ebx,10000 |
||
103 | div ebx |
||
104 | pop edx eax |
||
105 | jmp .no_eot |
||
106 | .notempo: |
||
107 | cmp ah,0x2f ; end of track |
||
108 | jne .no_eot |
||
109 | inc esi |
||
110 | if SYS eq meos1 |
||
111 | dps <13,10,'EOT'> |
||
112 | push esi |
||
113 | sub esi,workarea |
||
114 | dpd esi |
||
115 | pop esi |
||
116 | ; mcall 5,200 |
||
117 | ; dph eax |
||
118 | ; ud2 |
||
119 | end if |
||
120 | .eot: |
||
121 | ; dps 'EOT ' |
||
122 | inc [cur_track] |
||
123 | jmp skip_sections;decode_end |
||
124 | .no_eot: |
||
125 | lodsb |
||
126 | movzx ecx,al ; ecx - length of metadata |
||
127 | add esi,ecx |
||
128 | jmp next_event |
||
129 | .no_meta: |
||
130 | cmp al,0xfa ; system ctl events |
||
131 | jb .no_sys |
||
132 | .dec_esi: |
||
133 | dec esi |
||
134 | jmp next_event |
||
135 | .no_sys: |
||
136 | cmp al,0xf8 |
||
137 | je .dec_esi |
||
138 | movzx ecx,al ; ecx - MIDI Event Command |
||
139 | and ecx,0xf ; cl - channel |
||
140 | and al,0xf0 ; al - event code |
||
141 | |||
142 | cmp al,0xe0 ; Pitch wheel change |
||
143 | je .inc_esi |
||
144 | cmp al,0xb0 |
||
145 | ja .no_inc |
||
146 | .inc_esi: |
||
147 | inc esi |
||
148 | .no_inc: |
||
149 | cmp ecx,[channel] ; Channel must be 0 !!! |
||
150 | jz .chan_ok |
||
151 | if NONCRITICAL_MSG eq 1 |
||
152 | dps 'C' ; Reference to unsupported channel !!! |
||
153 | dpd ecx |
||
154 | mov ecx,esi |
||
155 | dps '-' |
||
156 | sub ecx,workarea+1 |
||
157 | dpd ecx |
||
158 | end if |
||
159 | jmp next_event |
||
160 | .chan_ok: |
||
161 | cmp al,0x90 ; Note On |
||
162 | jne .no_noon |
||
163 | add al,[octave] |
||
164 | cmp [curnote],0x80 |
||
165 | je .note_ok |
||
166 | if NONCRITICAL_MSG eq 1 |
||
167 | dps 'N!' ; Note On without Off !!! |
||
168 | end if |
||
169 | .note_ok: |
||
170 | ; dps 'N+' |
||
171 | ; movzx ecx,ah |
||
172 | ; dpd ecx |
||
173 | call insert_pause |
||
174 | mov [curnote],ah ; [curnote]=note number |
||
175 | jmp next_event |
||
176 | .no_noon: |
||
177 | cmp al,0x80 ; Note Off |
||
178 | jne .no_nooff |
||
179 | add ah,[octave] |
||
180 | cmp ah,[curnote] |
||
181 | je .off_ok |
||
182 | if NONCRITICAL_MSG eq 1 |
||
183 | dps 'n!' ; Note Off mismatch !!! |
||
184 | end if |
||
185 | .off_ok: |
||
186 | ; dps 'N-' |
||
187 | cmp ah,[max_note] |
||
188 | jbe .nomax |
||
189 | mov [max_note],ah |
||
190 | .nomax: |
||
191 | cmp ah,[min_note] |
||
192 | jae .ins |
||
193 | mov [min_note],ah |
||
194 | .ins: |
||
195 | call insert_note |
||
196 | mov [curnote],al |
||
197 | |||
198 | .no_nooff: ; No more supported events |
||
199 | jmp next_event |
||
200 | prev_cmd db ? |
||
201 | max_note db ? |
||
202 | min_note db ? |
||
203 | ; ********************************************* |
||
204 | ; ******* READ VARIABLE BYTES **************** |
||
205 | ; ********************************************* |
||
206 | |||
207 | readvar: |
||
208 | ; in: esi - pointer; |
||
209 | ; out: esi - new pointer; eax - value; |
||
210 | push ebx ecx |
||
211 | movzx ebx,byte[esi] |
||
212 | inc esi |
||
213 | btr ebx,7 |
||
214 | jnc .exit |
||
215 | .next: |
||
216 | shl ebx,7 |
||
217 | lodsb |
||
218 | mov ecx,eax |
||
219 | and eax,0x7f |
||
220 | add ebx,eax |
||
221 | cmp cl,0x7f |
||
222 | ja .next |
||
223 | .exit: |
||
224 | mov eax,ebx |
||
225 | pop ecx ebx |
||
226 | ret |
||
227 | |||
228 | ; ********************************************* |
||
229 | ; ******* INSERT PAUSE *********************** |
||
230 | ; ********************************************* |
||
231 | |||
232 | insert_pause: |
||
233 | cmp [delta],0 |
||
234 | jz return |
||
235 | push eax ebx ecx |
||
236 | mov ah,0xff |
||
237 | jmp write_note |
||
238 | |||
239 | ; ********************************************* |
||
240 | ; ******* INSERT NOTE ************************ |
||
241 | ; ********************************************* |
||
242 | |||
243 | insert_note: ; ah - note code |
||
244 | push eax ebx ecx |
||
245 | movzx eax,ah |
||
246 | mov ebx,12 |
||
247 | div bl |
||
248 | shl al,4 |
||
249 | add ah,al |
||
250 | sub ah,0x1f |
||
251 | write_note: |
||
252 | push eax |
||
253 | mov eax,[delta] |
||
254 | mov edx,[tempo] |
||
255 | mul edx |
||
256 | mov ecx,[quarter] |
||
257 | div ecx ; ax - note delay |
||
258 | cmp eax,0x7f |
||
259 | jb .ok |
||
260 | mov eax,0x7f |
||
261 | .ok: |
||
262 | movzx ecx,al |
||
263 | or ecx,0x80 |
||
264 | pop eax |
||
265 | mov al,cl |
||
266 | stosw |
||
267 | xor eax,eax |
||
268 | mov [delta],eax |
||
269 | pop ecx ebx eax |
||
270 | return: |
||
271 | ret |
||
272 | |||
273 | sHeadInv: |
||
274 | if lang eq ru |
||
275 | db "Неверный заголовок",0 |
||
276 | else |
||
277 | db "Header invalid",0 |
||
278 | end if |
||
279 | |||
280 | sHSizeInv: |
||
281 | if lang eq ru |
||
282 | db 'Неверный размер заголовка',0 |
||
283 | else |
||
284 | db 'Header size invalid',0 |
||
285 | end if |
||
286 | |||
287 | sTypeUnsup: |
||
288 | if lang eq ru |
||
289 | db 'Тип MIDI не поддерживается',0 |
||
290 | else |
||
291 | db 'MIDI type not supported',0 |
||
292 | end if13,10,'EOT'>'>13,10,'Track>'What?',13,10> |