293 lines
5.7 KiB
PHP
293 lines
5.7 KiB
PHP
|
SYS equ meos
|
|||
|
midi_parse:
|
|||
|
and [max_note],0
|
|||
|
and [cur_track],0
|
|||
|
mov [min_note],0xff
|
|||
|
mov edi,[midi_limit]
|
|||
|
cmp dword[workarea],'MThd'
|
|||
|
je .head_ok
|
|||
|
mov edx,sHeadInv
|
|||
|
call debug_outstr
|
|||
|
jmp clearpath
|
|||
|
.head_ok:
|
|||
|
cmp dword[workarea+4],0x6000000
|
|||
|
je .heads_ok
|
|||
|
mov edx,sHSizeInv
|
|||
|
call debug_outstr
|
|||
|
jmp clearpath
|
|||
|
.heads_ok:
|
|||
|
cmp dword[workarea+8],0x1000000
|
|||
|
jmp .headt_ok
|
|||
|
mov edx,sTypeUnsup
|
|||
|
call debug_outstr
|
|||
|
jmp clearpath
|
|||
|
.headt_ok:
|
|||
|
movzx eax,word[workarea+12]
|
|||
|
rol ax,8
|
|||
|
mov [quarter],eax
|
|||
|
mov [tempo],50
|
|||
|
mov esi,workarea+0xe
|
|||
|
skip_sections:
|
|||
|
lodsd
|
|||
|
cmp eax,'MTrk'
|
|||
|
je track_found
|
|||
|
if SYS eq meos
|
|||
|
; dps <'What?',13,10>
|
|||
|
end if
|
|||
|
lodsd
|
|||
|
add esi,eax
|
|||
|
cmp esi,[midi_limit]
|
|||
|
jbe skip_sections
|
|||
|
if NONCRITICAL_MSG eq 1
|
|||
|
dps 'No more tracks'
|
|||
|
end if
|
|||
|
and word[edi],0
|
|||
|
; ud2
|
|||
|
jmp decode_end
|
|||
|
track_found:
|
|||
|
if SYS eq meos1
|
|||
|
dps <13,10,'Track '>
|
|||
|
push esi
|
|||
|
sub esi,workarea
|
|||
|
; dpd esi
|
|||
|
pop esi
|
|||
|
end if
|
|||
|
lodsd
|
|||
|
bswap eax
|
|||
|
mov bl,[cur_track]
|
|||
|
cmp bl,[sel_track]
|
|||
|
je .trk_fnd
|
|||
|
add esi,eax
|
|||
|
jmp next_event.eot
|
|||
|
.trk_fnd:
|
|||
|
mov [track_len],eax
|
|||
|
dps 'TRK'
|
|||
|
next_event:
|
|||
|
call readvar
|
|||
|
; dpd eax
|
|||
|
add [delta],eax
|
|||
|
lodsw ; al -event, ah - next byte
|
|||
|
if SYS eq meos1
|
|||
|
dph eax
|
|||
|
dps <' ',13,10>
|
|||
|
newline
|
|||
|
end if
|
|||
|
test al,0x80 ; check if a valid event
|
|||
|
jnz .valid_evt2
|
|||
|
dec esi
|
|||
|
shl ax,8
|
|||
|
mov al,[prev_cmd]
|
|||
|
jmp .valid_evt
|
|||
|
.valid_evt2:
|
|||
|
mov [prev_cmd],al
|
|||
|
.valid_evt:
|
|||
|
cmp al,0xf0
|
|||
|
jne .nosysex
|
|||
|
dec esi
|
|||
|
call readvar
|
|||
|
add esi,eax
|
|||
|
jmp next_event
|
|||
|
.nosysex:
|
|||
|
cmp al,0xff
|
|||
|
jne .no_meta
|
|||
|
|
|||
|
; meta events
|
|||
|
cmp ah,0x51
|
|||
|
jne .notempo
|
|||
|
push eax edx
|
|||
|
mov eax,[esi]
|
|||
|
xor al,al
|
|||
|
bswap eax
|
|||
|
xor edx,edx
|
|||
|
mov ebx,10000
|
|||
|
div ebx
|
|||
|
pop edx eax
|
|||
|
jmp .no_eot
|
|||
|
.notempo:
|
|||
|
cmp ah,0x2f ; end of track
|
|||
|
jne .no_eot
|
|||
|
inc esi
|
|||
|
if SYS eq meos1
|
|||
|
dps <13,10,'EOT'>
|
|||
|
push esi
|
|||
|
sub esi,workarea
|
|||
|
dpd esi
|
|||
|
pop esi
|
|||
|
; mcall 5,200
|
|||
|
; dph eax
|
|||
|
; ud2
|
|||
|
end if
|
|||
|
.eot:
|
|||
|
; dps 'EOT '
|
|||
|
inc [cur_track]
|
|||
|
jmp skip_sections;decode_end
|
|||
|
.no_eot:
|
|||
|
lodsb
|
|||
|
movzx ecx,al ; ecx - length of metadata
|
|||
|
add esi,ecx
|
|||
|
jmp next_event
|
|||
|
.no_meta:
|
|||
|
cmp al,0xfa ; system ctl events
|
|||
|
jb .no_sys
|
|||
|
.dec_esi:
|
|||
|
dec esi
|
|||
|
jmp next_event
|
|||
|
.no_sys:
|
|||
|
cmp al,0xf8
|
|||
|
je .dec_esi
|
|||
|
movzx ecx,al ; ecx - MIDI Event Command
|
|||
|
and ecx,0xf ; cl - channel
|
|||
|
and al,0xf0 ; al - event code
|
|||
|
|
|||
|
cmp al,0xe0 ; Pitch wheel change
|
|||
|
je .inc_esi
|
|||
|
cmp al,0xb0
|
|||
|
ja .no_inc
|
|||
|
.inc_esi:
|
|||
|
inc esi
|
|||
|
.no_inc:
|
|||
|
cmp ecx,[channel] ; Channel must be 0 !!!
|
|||
|
jz .chan_ok
|
|||
|
if NONCRITICAL_MSG eq 1
|
|||
|
dps 'C' ; Reference to unsupported channel !!!
|
|||
|
dpd ecx
|
|||
|
mov ecx,esi
|
|||
|
dps '-'
|
|||
|
sub ecx,workarea+1
|
|||
|
dpd ecx
|
|||
|
end if
|
|||
|
jmp next_event
|
|||
|
.chan_ok:
|
|||
|
cmp al,0x90 ; Note On
|
|||
|
jne .no_noon
|
|||
|
add al,[octave]
|
|||
|
cmp [curnote],0x80
|
|||
|
je .note_ok
|
|||
|
if NONCRITICAL_MSG eq 1
|
|||
|
dps 'N!' ; Note On without Off !!!
|
|||
|
end if
|
|||
|
.note_ok:
|
|||
|
; dps 'N+'
|
|||
|
; movzx ecx,ah
|
|||
|
; dpd ecx
|
|||
|
call insert_pause
|
|||
|
mov [curnote],ah ; [curnote]=note number
|
|||
|
jmp next_event
|
|||
|
.no_noon:
|
|||
|
cmp al,0x80 ; Note Off
|
|||
|
jne .no_nooff
|
|||
|
add ah,[octave]
|
|||
|
cmp ah,[curnote]
|
|||
|
je .off_ok
|
|||
|
if NONCRITICAL_MSG eq 1
|
|||
|
dps 'n!' ; Note Off mismatch !!!
|
|||
|
end if
|
|||
|
.off_ok:
|
|||
|
; dps 'N-'
|
|||
|
cmp ah,[max_note]
|
|||
|
jbe .nomax
|
|||
|
mov [max_note],ah
|
|||
|
.nomax:
|
|||
|
cmp ah,[min_note]
|
|||
|
jae .ins
|
|||
|
mov [min_note],ah
|
|||
|
.ins:
|
|||
|
call insert_note
|
|||
|
mov [curnote],al
|
|||
|
|
|||
|
.no_nooff: ; No more supported events
|
|||
|
jmp next_event
|
|||
|
prev_cmd db ?
|
|||
|
max_note db ?
|
|||
|
min_note db ?
|
|||
|
; *********************************************
|
|||
|
; ******* READ VARIABLE BYTES ****************
|
|||
|
; *********************************************
|
|||
|
|
|||
|
readvar:
|
|||
|
; in: esi - pointer;
|
|||
|
; out: esi - new pointer; eax - value;
|
|||
|
push ebx ecx
|
|||
|
movzx ebx,byte[esi]
|
|||
|
inc esi
|
|||
|
btr ebx,7
|
|||
|
jnc .exit
|
|||
|
.next:
|
|||
|
shl ebx,7
|
|||
|
lodsb
|
|||
|
mov ecx,eax
|
|||
|
and eax,0x7f
|
|||
|
add ebx,eax
|
|||
|
cmp cl,0x7f
|
|||
|
ja .next
|
|||
|
.exit:
|
|||
|
mov eax,ebx
|
|||
|
pop ecx ebx
|
|||
|
ret
|
|||
|
|
|||
|
; *********************************************
|
|||
|
; ******* INSERT PAUSE ***********************
|
|||
|
; *********************************************
|
|||
|
|
|||
|
insert_pause:
|
|||
|
cmp [delta],0
|
|||
|
jz return
|
|||
|
push eax ebx ecx
|
|||
|
mov ah,0xff
|
|||
|
jmp write_note
|
|||
|
|
|||
|
; *********************************************
|
|||
|
; ******* INSERT NOTE ************************
|
|||
|
; *********************************************
|
|||
|
|
|||
|
insert_note: ; ah - note code
|
|||
|
push eax ebx ecx
|
|||
|
movzx eax,ah
|
|||
|
mov ebx,12
|
|||
|
div bl
|
|||
|
shl al,4
|
|||
|
add ah,al
|
|||
|
sub ah,0x1f
|
|||
|
write_note:
|
|||
|
push eax
|
|||
|
mov eax,[delta]
|
|||
|
mov edx,[tempo]
|
|||
|
mul edx
|
|||
|
mov ecx,[quarter]
|
|||
|
div ecx ; ax - note delay
|
|||
|
cmp eax,0x7f
|
|||
|
jb .ok
|
|||
|
mov eax,0x7f
|
|||
|
.ok:
|
|||
|
movzx ecx,al
|
|||
|
or ecx,0x80
|
|||
|
pop eax
|
|||
|
mov al,cl
|
|||
|
stosw
|
|||
|
xor eax,eax
|
|||
|
mov [delta],eax
|
|||
|
pop ecx ebx eax
|
|||
|
return:
|
|||
|
ret
|
|||
|
|
|||
|
sHeadInv:
|
|||
|
if lang eq ru
|
|||
|
db "<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>",0
|
|||
|
else
|
|||
|
db "Header invalid",0
|
|||
|
end if
|
|||
|
|
|||
|
sHSizeInv:
|
|||
|
if lang eq ru
|
|||
|
db '<27><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> ࠧ<><E0A0A7><EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>',0
|
|||
|
else
|
|||
|
db 'Header size invalid',0
|
|||
|
end if
|
|||
|
|
|||
|
sTypeUnsup:
|
|||
|
if lang eq ru
|
|||
|
db '<27><><EFBFBD> MIDI <20><> <20><><EFBFBD><EFBFBD><EFBFBD>ন<EFBFBD><E0A6A8><EFBFBD><EFBFBD><EFBFBD><EFBFBD>',0
|
|||
|
else
|
|||
|
db 'MIDI type not supported',0
|
|||
|
end if
|