I have legacy code written in Visual Basic 6. It uses Rnd and Randomize to produce an output given an initial random seed. These are the rtcRandomNext and rtcRandomize functions in the MSVBM60.DLL, respectively.
How are they implemented?
Here's a C implementation that gives the same results as the functions in MSVBM60.DLL when called directly, or when calling Rnd and Randomize in twinBASIC beta 908.
The code is based on the disassembly of MSVBM60.DLL.
// SPDX-Unlicense
#include <math.h>
#include <stdint.h>
#include <stdio.h>
#include <string.h>
#include <windows.h>
uint32_t rndState = 0;
float rtcGetTimer(void) // as in MSVBM60.DLL
{
struct _SYSTEMTIME time;
GetLocalTime(&time);
return (((uint32_t)time.wHour * 60 + (uint32_t)time.wMinute) * 60 + (uint32_t)time.wSecond)
- time.wMilliseconds * -0.001;
}
void implRandomizeTimer(void)
{
float f = rtcGetTimer();
uint32_t i;
memcpy(&i, &f, sizeof(i));
rndState = (((i & 0xffff) << 8) ^ ((i >> 8) & 0xffff00)) | (rndState & 0xff0000ff);
}
void implRandomizeNumber(double number)
{
struct
{
uint32_t low;
uint32_t high;
} inumber;
memcpy(&inumber, &number, 8);
rndState = ((inumber.high & 0xffff) << 8 ^ (inumber.high >> 8 & 0xffff00)) | (rndState & 0xff0000ff);
}
void rtcRandomize(double number) // as in MSVBM60.DLL
{
if (isnan(number))
implRandomizeTimer();
else
implRandomizeNumber(number);
}
double rtcRandomNext(float number) // as in MSVBM60.DLL
{
uint32_t inumber;
memcpy(&inumber, &number, sizeof(inumber));
uint32_t value = rndState;
if (number != 0.0) {
if (number < 0.0) {
value = ((inumber >> 0x18) + (int)inumber) & 0xffffff;
}
value = (0xffc39ec3 - (value * 0x2bc03)) & 0xffffff;
}
rndState = value;
return (uint64_t)value * 5.9604645e-08f;
}
float Rnd(void) { return rtcRandomNext(1.0f); }
float Rnd1(float number) { return rtcRandomNext(number); }
void Randomize(void) { rtcRandomize(NAN); }
void Randomize1(float number) { rtcRandomize(number); }
int main(int argc, char *argv[])
{
printf("%f\n", Rnd1(-1));
Randomize1(12345);
printf("%f\n", Rnd());
printf("%f\n", Rnd());
}
Output:
0.224007
0.376422
0.814624