#include "ps2000_internal.h" #include #include /* ========================================================================== */ /* STREAMING MATH & RING BUFFER */ /* ========================================================================== */ /** * @brief Update ring buffer write position with wrap-around. * * Reconstructs sub_10300 / sub_10770: * add eax, 8000h; shr ax, 8; mov [rbp+40Ah], cx * * Implements aligned circular buffer indexing. */ uint32_t _ps2000_strm_update_ring_pos(uint32_t current_pos, uint32_t increment, uint32_t buf_size) { if (buf_size == 0) return 0; uint32_t new_pos = current_pos + increment; /* Apply wrap mask and alignment shift as in original asm */ uint32_t aligned = new_pos + 0x8000U; aligned >>= 8U; aligned <<= 8U; /* Modulo buffer size for true circular behavior */ return aligned % buf_size; } /** * @brief Process raw streaming samples with calibration and correction. * * Reconstructs sub_28A19 SSE block: * cvtsi2sd xmm0, [mem]; mulsd xmm0, gain; divsd xmm0, scale; * addsd xmm0, correction; cvttsd2si esi, xmm0; */ ps2000_status_t _ps2000_strm_process_raw(ps2000_context_t *ctx, const int16_t *raw_buf, uint32_t num_samples, int16_t *out_buf, uint32_t *processed_count) { if (!ctx || !raw_buf || !out_buf || !processed_count) { return PS2000_ERR_INVALID_PARAM; } if (num_samples == 0) { *processed_count = 0; return PS2000_OK; } /* Use channel 0 calibration by default for streaming */ double gain = ctx->info.cal_gain[0]; double offset = (double)ctx->info.cal_offset[0]; for (uint32_t i = 0; i < num_samples; i++) { /* Delegate to centralized math module */ out_buf[i] = _ps2000_math_adc_convert(raw_buf[i], gain, offset); } *processed_count = num_samples; return PS2000_OK; }