diff --git a/core/pseudo-halt.c b/core/pseudo-halt.c index fcdacfc..822cac7 100644 --- a/core/pseudo-halt.c +++ b/core/pseudo-halt.c @@ -142,6 +142,7 @@ static uint32_t phDPSTTS(VB *sim) { case 3: /* 8ms - L*BSY falling edge */ case 6: /* 13ms-18ms - Display right frame buffer */ case 7: /* 18ms - R*BSY falling edge */ + case 8: /* 20ms - Display interval complete */ return sim->vip.dp.until; } /* case 1: 3ms - L*BSY rising edge */ diff --git a/core/vb.c b/core/vb.c index af8ecfe..146f016 100644 --- a/core/vb.c +++ b/core/vb.c @@ -319,9 +319,10 @@ struct VB { struct { float i1[2]; /* Previous analog input sample */ float o1[2]; /* Previous analog output sample */ - uint32_t capacity; /* Number of audio frames in samples */ - uint32_t offset; /* Position in output buffer */ - int16_t *samples; /* Output memory */ + unsigned capacity; /* Number of audio frames in output buffer */ + unsigned offset; /* Position in output buffer */ + void *samples; /* Output buffer */ + int type; /* Output data type */ } out; /* Memory */ @@ -461,19 +462,23 @@ VBAPI int vbEmulate(VB *sim, uint32_t *clocks) { } /* Process multiple simulations */ -VBAPI int vbEmulateEx(VB **sims, int count, uint32_t *clocks) { +VBAPI int vbEmulateEx(VB **sims, unsigned count, uint32_t *clocks) { int brk; /* A callback requested a break */ uint32_t until; /* Clocks guaranteed to process */ - int x; /* Iterator */ + unsigned x; /* Iterator */ + + /* Process one simulation */ + if (count == 1) + return vbEmulate(sims[0], clocks); + + /* Process multiple simulations */ while (*clocks != 0) { until = *clocks; - for (x = count - 1; x >= 0; x--) - until = sysUntil(sims[x], until); - + for (x = count; x > 0; x--) + until = sysUntil(sims[x - 1], until); brk = 0; - for (x = count - 1; x >= 0; x--) - brk |= sysEmulate(sims[x], until); - + for (x = count; x > 0; x--) + brk |= sysEmulate(sims[x - 1], until); *clocks -= until; if (brk) return brk; /* TODO: return 1 */ @@ -584,7 +589,7 @@ VBAPI uint32_t vbGetProgramCounter(VB *sim) { } /* Retrieve the value in a program register */ -VBAPI int32_t vbGetProgramRegister(VB *sim, int index) { +VBAPI int32_t vbGetProgramRegister(VB *sim, unsigned index) { return index < 1 || index > 31 ? 0 : sim->cpu.program[index]; } @@ -594,13 +599,18 @@ VBAPI vbOnRead vbGetReadCallback(VB *sim) { } /* Retrieve the audio samples buffer */ -VBAPI void* vbGetSamples(VB *sim, uint32_t *capacity, uint32_t *position) { +VBAPI void* vbGetSamples(VB *sim, int *type, + unsigned *capacity, unsigned *position) { if (sim->vsu.out.samples == NULL) { + if (type != NULL) + *type = 0; if (capacity != NULL) *capacity = 0; if (position != NULL) *position = 0; } else { + if (type != NULL) + *type = sim->vsu.out.type; if (capacity != NULL) *capacity = sim->vsu.out.capacity; if (position != NULL) @@ -615,8 +625,8 @@ VBAPI vbOnSamples vbGetSamplesCallback(VB *sim) { } /* Retrieve the value in a system register */ -VBAPI uint32_t vbGetSystemRegister(VB *sim, int index) { - return index < 0 || index > 31 ? 0 : cpuGetSystemRegister(sim, index); +VBAPI uint32_t vbGetSystemRegister(VB *sim, unsigned index) { + return index > 31 ? 0 : cpuGetSystemRegister(sim, index); } /* Retrieve a simulation's userdata pointer */ @@ -761,12 +771,15 @@ VBAPI int vbSetOption(VB *sim, int key, int value) { } /* Specify a new communication peer */ -VBAPI VB* vbSetPeer(VB *sim, VB *peer) { - VB *prev = sim->peer; +VBAPI void vbSetPeer(VB *sim, VB *peer) { + if (sim->peer == peer) + return; sim->peer = peer; - if (peer != prev && prev != NULL) - prev->peer = NULL; - return prev; + if (peer == NULL) + return; + if (peer->peer != NULL) + peer->peer->peer = NULL; + peer->peer = sim; } /* Specify a new value for the program counter */ @@ -778,7 +791,7 @@ VBAPI uint32_t vbSetProgramCounter(VB *sim, uint32_t value) { } /* Specify a new value for a program register */ -VBAPI int32_t vbSetProgramRegister(VB *sim, int index, int32_t value) { +VBAPI int32_t vbSetProgramRegister(VB *sim, unsigned index, int32_t value) { return index < 1 || index > 31 ? 0 : (sim->cpu.program[index] = value); } @@ -790,12 +803,14 @@ VBAPI vbOnRead vbSetReadCallback(VB *sim, vbOnRead callback) { } /* Specify a new audio samples buffer */ -VBAPI int vbSetSamples(VB *sim, void *samples, uint32_t capacity) { - if (samples != NULL && (capacity == 0 || capacity > 0x40000000)) +VBAPI int vbSetSamples(VB *sim, void *samples, int type, unsigned capacity) { + if (samples != NULL && + (capacity == 0 || (type != VB_S16 && type != VB_F32))) return 1; - sim->vsu.out.capacity = samples == NULL ? 0 : capacity; + sim->vsu.out.capacity = capacity; sim->vsu.out.offset = 0; sim->vsu.out.samples = samples; + sim->vsu.out.type = type; return 0; } @@ -807,9 +822,8 @@ VBAPI vbOnSamples vbSetSamplesCallback(VB *sim, vbOnSamples callback) { } /* Specify a new value for a system register */ -VBAPI uint32_t vbSetSystemRegister(VB *sim, int index, uint32_t value) { - return index < 0 || index > 31 ? 0 : - cpuSetSystemRegister(sim, index, value, 1); +VBAPI uint32_t vbSetSystemRegister(VB *sim, unsigned index, uint32_t value) { + return index > 31 ? 0 : cpuSetSystemRegister(sim, index, value, 1); } /* Specify a new write callback handler */ diff --git a/core/vb.h b/core/vb.h index 64d92d9..aebd68f 100644 --- a/core/vb.h +++ b/core/vb.h @@ -79,6 +79,7 @@ extern "C" { #define VB_S16 2 #define VB_U16 3 #define VB_S32 4 +#define VB_F32 5 /* Option keys */ #define VB_PSEUDO_HALT 0 @@ -106,7 +107,7 @@ typedef int (*vbOnWrite )(VB *sim, uint32_t address, int type, int32_t *valu /******************************* API Commands ********************************/ VBAPI int vbEmulate (VB *sim, uint32_t *clocks); -VBAPI int vbEmulateEx (VB **sims, int count, uint32_t *clocks); +VBAPI int vbEmulateEx (VB **sims, unsigned count, uint32_t *clocks); VBAPI void* vbGetCallback (VB *sim, int id); VBAPI void* vbGetCartRAM (VB *sim, uint32_t *size); VBAPI void* vbGetCartROM (VB *sim, uint32_t *size); @@ -120,11 +121,11 @@ VBAPI int vbGetOption (VB *sim, int key); VBAPI VB* vbGetPeer (VB *sim); VBAPI void vbGetPixels (VB *sim, void *left, int leftStrideX, int leftStrideY, void *right, int rightStrideX, int rightStrideY); VBAPI uint32_t vbGetProgramCounter (VB *sim); -VBAPI int32_t vbGetProgramRegister (VB *sim, int index); +VBAPI int32_t vbGetProgramRegister (VB *sim, unsigned index); VBAPI vbOnRead vbGetReadCallback (VB *sim); -VBAPI void* vbGetSamples (VB *sim, uint32_t *capacity, uint32_t *position); +VBAPI void* vbGetSamples (VB *sim, int *type, unsigned *capacity, unsigned *position); VBAPI vbOnSamples vbGetSamplesCallback (VB *sim); -VBAPI uint32_t vbGetSystemRegister (VB *sim, int index); +VBAPI uint32_t vbGetSystemRegister (VB *sim, unsigned index); VBAPI void* vbGetUserData (VB *sim); VBAPI vbOnWrite vbGetWriteCallback (VB *sim); VBAPI VB* vbInit (VB *sim); @@ -139,12 +140,13 @@ VBAPI vbOnFrame vbSetFrameCallback (VB *sim, vbOnFrame callback); VBAPI vbOnLink vbSetLinkCallback (VB *sim, vbOnLink callback); VBAPI uint16_t vbSetKeys (VB *sim, uint16_t keys); VBAPI int vbSetOption (VB *sim, int key, int value); +VBAPI void vbSetPeer (VB *sim, VB *peer); VBAPI uint32_t vbSetProgramCounter (VB *sim, uint32_t value); -VBAPI int32_t vbSetProgramRegister (VB *sim, int index, int32_t value); +VBAPI int32_t vbSetProgramRegister (VB *sim, unsigned index, int32_t value); VBAPI vbOnRead vbSetReadCallback (VB *sim, vbOnRead callback); -VBAPI int vbSetSamples (VB *sim, void *samples, uint32_t capacity); +VBAPI int vbSetSamples (VB *sim, void *samples, int type, unsigned capacity); VBAPI vbOnSamples vbSetSamplesCallback (VB *sim, vbOnSamples callback); -VBAPI uint32_t vbSetSystemRegister (VB *sim, int index, uint32_t value); +VBAPI uint32_t vbSetSystemRegister (VB *sim, unsigned index, uint32_t value); VBAPI void* vbSetUserData (VB *sim, void *tag); VBAPI vbOnWrite vbSetWriteCallback (VB *sim, vbOnWrite callback); VBAPI size_t vbSizeOf (); diff --git a/core/vip.c b/core/vip.c index e722873..1cf834b 100644 --- a/core/vip.c +++ b/core/vip.c @@ -605,14 +605,18 @@ static int vipEmulateDisplay(VB *sim, uint32_t clocks) { } sim->vip.dp.clocks = vipClocksMs(2); sim->vip.dp.enabled = 0; - sim->vip.dp.step = 0; + sim->vip.dp.step = 8; sim->vip.dp.until = vipClocksMs(2); - if (vipOnFrame(sim)) - return 1; break; /* 18ms-20ms - Idle */ + case 8: /* 20ms - Display interval complete */ + sim->vip.dp.step = 0; + if (vipOnFrame(sim)) + return 1; + break; + } } diff --git a/core/vsu.c b/core/vsu.c index 46faa10..cf4c866 100644 --- a/core/vsu.c +++ b/core/vsu.c @@ -368,8 +368,21 @@ static void vsuEmulate(VB *sim, uint32_t clocks) { sim->vsu.out.samples != NULL && sim->vsu.out.offset >> 1 < sim->vsu.out.capacity ) { - sim->vsu.out.samples[sim->vsu.out.offset++] = - (int16_t) (o0 * 32767.0f + (o0 < 0.0f ? -0.5f : +0.5f)); + + /* Processing by data type*/ + switch (sim->vsu.out.type) { + case VB_S16: + ((int16_t *) sim->vsu.out.samples) + [sim->vsu.out.offset++] = (int16_t) + (o0 * 32767.0f + (o0 < 0.0f ? -0.5f : +0.5f)); + break; + case VB_F32: + ((float *) sim->vsu.out.samples) + [sim->vsu.out.offset++] = o0; + break; + } + + /* Invoke the samples callback */ if ( e == 1 && sim->vsu.out.offset >> 1 == sim->vsu.out.capacity diff --git a/makefile b/makefile index 82de1d8..2595dcf 100644 --- a/makefile +++ b/makefile @@ -65,7 +65,8 @@ wasm: @emcc -o web/core.wasm web/wasm.c core/vb.c util/vbu.c -I core -I util \ -D VB_LITTLE_ENDIAN -D VB_SIGNED_PROPAGATE \ -D "VBAPI=__attribute__((used))" -D "VBUAPI=__attribute__((used))" \ - --no-entry -O2 -flto -s WASM=1 -s WARN_ON_UNDEFINED_SYMBOLS=0 \ + -D VB_DIRECT_FRAME=wasmOnFrame \ + --no-entry -O2 -flto -s WASM=1 \ -s EXPORTED_RUNTIME_METHODS=[] -s ALLOW_MEMORY_GROWTH \ -s MAXIMUM_MEMORY=4GB -fno-strict-aliasing @rm -f web/*.wasm.tmp*