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:
Veikko Sariola
2020-10-27 20:15:06 +02:00
parent 5f4b85b0a4
commit 64afa9fb48
7 changed files with 217 additions and 135 deletions

View File

@ -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

View File

@ -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