mirror of
https://github.com/vsariola/sointu.git
synced 2025-06-04 01:28:45 -04:00
feat(libsointu): make su_render return some error codes, typically due to FPU stack errors.
This commit is contained in:
parent
83937bb2ee
commit
7bb60de74e
@ -83,9 +83,13 @@ void CALLCONV su_load_gmdls(void);
|
|||||||
// time_out > time_in, as it is modulated and the time could advance by 2 or more, so the loop
|
// time_out > time_in, as it is modulated and the time could advance by 2 or more, so the loop
|
||||||
// exit condition would fire when the current time is already past time_in
|
// exit condition would fire when the current time is already past time_in
|
||||||
//
|
//
|
||||||
// Returns error code:
|
// Returns an error code, which is actually just masked version of the FPU Status Word
|
||||||
// 0 everything ok
|
// On a succesful run, the return value should be 0
|
||||||
// (no actual errors implemented yet)
|
// Error code bits:
|
||||||
|
// bit 0 FPU invalid operation (stack over/underflow OR invalid arithmetic e.g. NaNs)
|
||||||
|
// bit 2 Divide by zero occurred
|
||||||
|
// bit 6 Stack overflow or underflow occurred
|
||||||
|
// bits 11-13 The top pointer of the fpu stack. Any other value than 0 indicates that some values were left on the stack.
|
||||||
int CALLCONV su_render(Synth* synth, float* buffer, int* samples, int* time);
|
int CALLCONV su_render(Synth* synth, float* buffer, int* samples, int* time);
|
||||||
|
|
||||||
// Arithmetic opcode ids
|
// Arithmetic opcode ids
|
||||||
|
@ -209,7 +209,9 @@ su_render_samples_time_finish:
|
|||||||
pop _SI ; pop the pointer to samples
|
pop _SI ; pop the pointer to samples
|
||||||
mov dword [_SI], edx ; *samples = samples rendered
|
mov dword [_SI], edx ; *samples = samples rendered
|
||||||
mov dword [_BX], eax ; *time = time ticks rendered
|
mov dword [_BX], eax ; *time = time ticks rendered
|
||||||
xor eax, eax ; TODO: set eax to possible error code, now just 0
|
xor eax, eax
|
||||||
|
fnstsw ax ; store the FPU status flag in ax.
|
||||||
|
and ax, 0011100001000101b ; mask TOP pointer, stack error, zero divide and invalid operation
|
||||||
frstor [_SP] ; restore fpu state
|
frstor [_SP] ; restore fpu state
|
||||||
add _SP,108 ; rewind the stack allocate for FPU state
|
add _SP,108 ; rewind the stack allocate for FPU state
|
||||||
%if BITS == 32 ; stdcall
|
%if BITS == 32 ; stdcall
|
||||||
|
@ -43,18 +43,15 @@ int main(int argc, char* argv[]) {
|
|||||||
time = 0;
|
time = 0;
|
||||||
errcode = su_render(synth, buffer, &samples, &time);
|
errcode = su_render(synth, buffer, &samples, &time);
|
||||||
if (errcode != 0)
|
if (errcode != 0)
|
||||||
{
|
|
||||||
printf("su_render returned error");
|
|
||||||
goto fail;
|
goto fail;
|
||||||
}
|
|
||||||
if (samples > 0)
|
if (samples > 0)
|
||||||
{
|
{
|
||||||
printf("su_render rendered samples, despite it should not");
|
printf("su_render rendered samples, despite it should not\n");
|
||||||
goto fail;
|
goto fail;
|
||||||
}
|
}
|
||||||
if (time > 0)
|
if (time > 0)
|
||||||
{
|
{
|
||||||
printf("su_render advanced time, despite it should not");
|
printf("su_render advanced time, despite it should not\n");
|
||||||
goto fail;
|
goto fail;
|
||||||
}
|
}
|
||||||
// Then check that when we render using su_render with 0 samples,
|
// Then check that when we render using su_render with 0 samples,
|
||||||
@ -63,18 +60,15 @@ int main(int argc, char* argv[]) {
|
|||||||
time = INT32_MAX;
|
time = INT32_MAX;
|
||||||
errcode = su_render(synth, buffer, &samples, &time);
|
errcode = su_render(synth, buffer, &samples, &time);
|
||||||
if (errcode != 0)
|
if (errcode != 0)
|
||||||
{
|
|
||||||
printf("su_render returned error");
|
|
||||||
goto fail;
|
goto fail;
|
||||||
}
|
|
||||||
if (samples > 0)
|
if (samples > 0)
|
||||||
{
|
{
|
||||||
printf("su_render rendered samples, despite it should not");
|
printf("su_render rendered samples, despite it should not\n");
|
||||||
goto fail;
|
goto fail;
|
||||||
}
|
}
|
||||||
if (time > 0)
|
if (time > 0)
|
||||||
{
|
{
|
||||||
printf("su_render advanced time, despite it should not");
|
printf("su_render advanced time, despite it should not\n");
|
||||||
goto fail;
|
goto fail;
|
||||||
}
|
}
|
||||||
// Then check that each time we call render, only SAMPLES_PER_ROW
|
// Then check that each time we call render, only SAMPLES_PER_ROW
|
||||||
@ -84,7 +78,9 @@ int main(int argc, char* argv[]) {
|
|||||||
// check that buffer full
|
// check that buffer full
|
||||||
samples = 1;
|
samples = 1;
|
||||||
time = INT32_MAX;
|
time = INT32_MAX;
|
||||||
su_render(synth, &buffer[totalrendered*2], &samples, &time);
|
errcode = su_render(synth, &buffer[totalrendered*2], &samples, &time);
|
||||||
|
if (errcode != 0)
|
||||||
|
goto fail;
|
||||||
totalrendered += samples;
|
totalrendered += samples;
|
||||||
if (samples != 1)
|
if (samples != 1)
|
||||||
{
|
{
|
||||||
@ -98,7 +94,9 @@ int main(int argc, char* argv[]) {
|
|||||||
}
|
}
|
||||||
samples = SAMPLES_PER_ROW - 1;
|
samples = SAMPLES_PER_ROW - 1;
|
||||||
time = INT32_MAX;
|
time = INT32_MAX;
|
||||||
su_render(synth, &buffer[totalrendered * 2], &samples, &time);
|
errcode = su_render(synth, &buffer[totalrendered * 2], &samples, &time);
|
||||||
|
if (errcode != 0)
|
||||||
|
goto fail;
|
||||||
totalrendered += samples;
|
totalrendered += samples;
|
||||||
if (samples != SAMPLES_PER_ROW - 1)
|
if (samples != SAMPLES_PER_ROW - 1)
|
||||||
{
|
{
|
||||||
@ -124,6 +122,16 @@ finish:
|
|||||||
free(buffer);
|
free(buffer);
|
||||||
return retval;
|
return retval;
|
||||||
fail:
|
fail:
|
||||||
|
if (errcode > 0) {
|
||||||
|
if ((errcode & 0xFF00) != 0)
|
||||||
|
printf("FPU stack was not empty on exit\n");
|
||||||
|
if ((errcode & 0x04) != 0)
|
||||||
|
printf("FPU zero divide\n");
|
||||||
|
if ((errcode & 0x01) != 0)
|
||||||
|
printf("FPU invalid operation\n");
|
||||||
|
if ((errcode & 0x40) != 0)
|
||||||
|
printf("FPU stack error\n");
|
||||||
|
}
|
||||||
retval = 1;
|
retval = 1;
|
||||||
goto finish;
|
goto finish;
|
||||||
}
|
}
|
||||||
|
Loading…
x
Reference in New Issue
Block a user