mirror of
https://github.com/vsariola/sointu.git
synced 2025-12-02 07:23:24 -05:00
Change the C-API to roughly match the new Go-API.
The parameter order is now so that all the in/out int parameters are in the end of the signature.
This commit is contained in:
118
src/sointu.asm
118
src/sointu.asm
@ -33,44 +33,53 @@ struc su_synth_state
|
||||
.polyphony resd 1
|
||||
.numvoices resd 1
|
||||
.randseed resd 1
|
||||
.globaltime resd 1
|
||||
.rowtick resd 1
|
||||
.rowlen resd 1
|
||||
.globaltime resd 1
|
||||
endstruc
|
||||
|
||||
SECT_TEXT(sursampl)
|
||||
|
||||
EXPORT MANGLE_FUNC(su_render_samples,12)
|
||||
EXPORT MANGLE_FUNC(su_render_time,16)
|
||||
%if BITS == 32 ; stdcall
|
||||
pushad ; push registers
|
||||
mov ecx, [esp + 4 + 32] ; ecx = &synthState
|
||||
mov esi, [esp + 8 + 32] ; esi = bufsize
|
||||
mov edx, [esp + 12 + 32] ; edx = &buffer
|
||||
mov ecx, [esp + 4 + 32] ; ecx = &synthState
|
||||
mov edx, [esp + 8 + 32] ; edx = &buffer
|
||||
mov esi, [esp + 12 + 32] ; esi = &samples
|
||||
mov ebx, [esp + 16 + 32] ; ebx = &time
|
||||
%else
|
||||
%ifidn __OUTPUT_FORMAT__,win64 ; win64 ABI: rdx = bufsize, r8 = &buffer, rcx = &synthstate
|
||||
%ifidn __OUTPUT_FORMAT__,win64 ; win64 ABI: rcx = &synthstate, rdx = &buffer, r8 = &bufsize, r9 = &time
|
||||
push_registers rdi, rsi, rbx, rbp ; win64 ABI: these registers are non-volatile
|
||||
mov rsi, rdx ; rsi = bufsize
|
||||
mov rdx, r8 ; rdx = &buffer
|
||||
%else ; System V ABI: rsi = bufsize, rdx = &buffer, rdi = &synthstate
|
||||
mov rsi, r8 ; rsi = &samples
|
||||
mov rbx, r9 ; rbx = &time
|
||||
%else ; System V ABI: rdi = &synthstate, rsi = &buffer, rdx = &samples, rcx = &time
|
||||
push_registers rbx, rbp ; System V ABI: these registers are non-volatile
|
||||
mov rbx, rcx ; rbx points to time
|
||||
xchg rsi, rdx ; rdx points to buffer, rsi points to samples
|
||||
mov rcx, rdi ; rcx = &Synthstate
|
||||
%endif
|
||||
%endif
|
||||
push _SI ; push bufsize
|
||||
push _DX ; push bufptr
|
||||
push _CX ; this takes place of the voicetrack
|
||||
push _SI ; push the pointer to samples
|
||||
push _BX ; push the pointer to time
|
||||
xor eax, eax ; samplenumber starts at 0
|
||||
push _AX ; push samplenumber to stack
|
||||
mov esi, [_SI] ; zero extend dereferenced pointer
|
||||
push _SI ; push bufsize
|
||||
push _DX ; push bufptr
|
||||
push _CX ; this takes place of the voicetrack
|
||||
mov eax, [_CX + su_synth_state.randseed]
|
||||
push _AX ; randseed
|
||||
mov eax, [_CX + su_synth_state.globaltime]
|
||||
push _AX ; global tick time
|
||||
mov eax, [_CX + su_synth_state.rowlen]
|
||||
push _AX ; push the rowlength to stack so we can easily compare to it, normally this would be row
|
||||
mov eax, [_CX + su_synth_state.rowtick]
|
||||
push _AX ; global tick time
|
||||
mov ebx, dword [_BX] ; zero extend dereferenced pointer
|
||||
push _BX ; the nominal rowlength should be time_in
|
||||
xor eax, eax ; rowtick starts at 0
|
||||
su_render_samples_loop:
|
||||
cmp eax, [_SP] ; compare current tick to rowlength
|
||||
jge su_render_samples_row_advance
|
||||
sub dword [_SP + PTRSIZE*5], 1 ; compare current tick to rowlength
|
||||
jb su_render_samples_buffer_full
|
||||
cmp eax, [_SP] ; if rowtick >= maxtime
|
||||
jge su_render_samples_time_finish ; goto finish
|
||||
mov ecx, [_SP + PTRSIZE*5] ; ecx = buffer length in samples
|
||||
cmp [_SP + PTRSIZE*6], ecx ; if samples >= maxsamples
|
||||
jge su_render_samples_time_finish ; goto finish
|
||||
inc eax ; time++
|
||||
inc dword [_SP + PTRSIZE*6] ; samples++
|
||||
mov _CX, [_SP + PTRSIZE*3]
|
||||
push _AX ; push rowtick
|
||||
mov eax, [_CX + su_synth_state.polyphony]
|
||||
@ -97,24 +106,26 @@ su_render_samples_loop:
|
||||
stosd ; clear right channel so the VM is ready to write them again
|
||||
pop _AX
|
||||
inc dword [_SP + PTRSIZE] ; increment global time, used by delays
|
||||
inc eax
|
||||
jmp su_render_samples_loop
|
||||
su_render_samples_row_advance:
|
||||
xor eax, eax ; row has finished, so clear the rowtick for next round
|
||||
su_render_samples_buffer_full:
|
||||
su_render_samples_time_finish:
|
||||
pop _CX
|
||||
pop _BX
|
||||
pop _DX
|
||||
pop _CX
|
||||
mov [_CX + su_synth_state.randseed], edx
|
||||
mov [_CX + su_synth_state.globaltime], ebx
|
||||
mov [_CX + su_synth_state.rowtick], eax
|
||||
pop _AX
|
||||
pop _AX
|
||||
mov [_CX + su_synth_state.globaltime], ebx
|
||||
pop _BX
|
||||
pop _BX
|
||||
pop _DX
|
||||
pop _BX ; pop the pointer to time
|
||||
pop _SI ; pop the pointer to samples
|
||||
mov dword [_SI], edx ; *samples = samples rendered
|
||||
mov dword [_BX], eax ; *time = time ticks rendered
|
||||
xor eax, eax ; TODO: set eax to possible error code, now just 0
|
||||
%if BITS == 32 ; stdcall
|
||||
mov [_SP + 28],eax ; we want to return eax, but popad pops everything, so put eax to stack for popad to pop
|
||||
popad
|
||||
ret 12
|
||||
ret 16
|
||||
%else
|
||||
%ifidn __OUTPUT_FORMAT__,win64
|
||||
pop_registers rdi, rsi, rbx, rbp ; win64 ABI: these registers are non-volatile
|
||||
@ -123,3 +134,48 @@ su_render_samples_buffer_full:
|
||||
%endif
|
||||
ret
|
||||
%endif
|
||||
|
||||
EXPORT MANGLE_FUNC(su_render,12)
|
||||
%if BITS == 32 ; stdcall
|
||||
mov eax, 0x7FFFFFFF ; don't care about time, just try to fill the buffer
|
||||
push eax
|
||||
mov eax, [esp + 8] ; eax = &synthState
|
||||
mov ecx, [esp + 12] ; ecx = &buffer
|
||||
mov edx, [esp + 16] ; edx = samples
|
||||
push edx
|
||||
lea edx, [esp + 4]
|
||||
push edx
|
||||
lea edx, [esp + 4]
|
||||
push edx
|
||||
push ecx
|
||||
push eax
|
||||
%else
|
||||
%ifidn __OUTPUT_FORMAT__,win64 ; win64 ABI: rdx = bufsize, r8 = &buffer, rcx = &synthstate
|
||||
push r8
|
||||
mov r8, _SP
|
||||
mov r9, 0x7FFFFFFF ; don't care about time, just try to fill the buffer
|
||||
push r9
|
||||
mov r9, _SP ; still, we have to pass a pointer to time, so pointer to stack
|
||||
%else ; System V ABI: rdi = &synthstate, rsi = &buffer, rdx = samples
|
||||
push rdx
|
||||
mov rdx, _SP
|
||||
mov rcx, 0x7FFFFFFF ; don't care about time, just try to fill the buffer
|
||||
push rcx
|
||||
mov rcx, _SP ; still, we have to pass a pointer to time, so pointer to stack
|
||||
%endif
|
||||
%endif
|
||||
call MANGLE_FUNC(su_render_time,16)
|
||||
%if BITS == 32 ; stdcall
|
||||
pop ecx
|
||||
pop ecx
|
||||
ret 12
|
||||
%else
|
||||
%ifidn __OUTPUT_FORMAT__,win64 ; win64 ABI: rdx = bufsize, r8 = &buffer, rcx = &synthstate
|
||||
pop r9
|
||||
pop r8
|
||||
%else
|
||||
pop rcx
|
||||
pop rdx
|
||||
%endif
|
||||
ret
|
||||
%endif
|
||||
|
||||
@ -331,15 +331,15 @@ EXPORT MANGLE_FUNC(su_power,0)
|
||||
%endmacro
|
||||
|
||||
;-------------------------------------------------------------------------------
|
||||
; su_render function: the entry point for the synth
|
||||
; su_render_song function: the entry point for the synth
|
||||
;-------------------------------------------------------------------------------
|
||||
; Has the signature su_render(void *ptr), where ptr is a pointer to
|
||||
; the output buffer
|
||||
; Has the signature su_render_song(void *ptr), where ptr is a pointer to
|
||||
; the output buffer. Renders the compile time hard-coded song to the buffer.
|
||||
; Stack: output_ptr
|
||||
;-------------------------------------------------------------------------------
|
||||
SECT_TEXT(surender)
|
||||
SECT_TEXT(surensng)
|
||||
|
||||
EXPORT MANGLE_FUNC(su_render,PTRSIZE) ; Stack: ptr
|
||||
EXPORT MANGLE_FUNC(su_render_song,PTRSIZE) ; Stack: ptr
|
||||
render_prologue
|
||||
xor eax, eax
|
||||
%ifdef INCLUDE_MULTIVOICE_TRACKS
|
||||
|
||||
Reference in New Issue
Block a user