/* Borland Win16 random-number support reconstructed from Code5. */ #include "tdkpin_random.h" enum { BORLAND_RANDOM_MULTIPLIER = 0x08088405u }; uint32_t borland_next_random(void) { g_borland_random_seed = g_borland_random_seed * BORLAND_RANDOM_MULTIPLIER + 1u; return g_borland_random_seed; } uint16_t borland_random_below(uint16_t upper_bound) { uint32_t random = borland_next_random(); return (uint16_t)(((uint64_t)random * upper_bound) >> 32); } BorlandReal48 borland_random_real48_registers(void) { uint32_t random = borland_next_random(); if (random == 0) { return (BorlandReal48){{0, 0, 0, 0, 0, 0}}; } uint8_t exponent = 0x80; while ((random & 0x80000000u) == 0) { random <<= 1; exponent--; } random &= 0x7fffffffu; return (BorlandReal48){{ exponent, 0, (uint8_t)random, (uint8_t)(random >> 8), (uint8_t)(random >> 16), (uint8_t)(random >> 24), }}; } int8_t borland_random_exponent(void) { return (int8_t)borland_random_real48_registers().bytes[0]; } /* * 1020:14de — x87 Random: reinterpret the signed FILD of RandSeed as unsigned * by adding exactly 2^31, then FSCALE by -32. Binary64 represents every * uint32_t/2^32 result exactly, so this host spelling loses no target bits. */ double borland_random_unit_interval(void) { uint32_t random = borland_next_random(); return (double)random / 4294967296.0; } void borland_seed_random_from_dos_time(void) { g_borland_random_seed = win16_dos_time_words(); }