diff --git a/src/ce/random.src b/src/ce/random.src index 1dfb326b7..1f818de0a 100644 --- a/src/ce/random.src +++ b/src/ce/random.src @@ -75,13 +75,14 @@ _random: xor a,(iy+3*4+1) ; a = t1u ^ zh == t2u ^ s2u == t3u ld (iy+3*4+2),a ; u(state[3]) = t3u ; Calculate s1. - xor a,a ; a = 0 - add.s hl,hl - adc a,a - add.s hl,hl - adc a,a - add.s hl,hl - adc a,a ; ahl = (t1 >> 16) << 3 + ld a,h + add hl,hl + add hl,hl + add hl,hl + rlca + rlca + rlca + and a,$07 ; ahl = (t1 >> 16) << 3 ; ah = ((t1 >> 16) << 3) >> 8 == t1 >> 21 == s1hl ; a = s1h ; h = s1l @@ -95,12 +96,11 @@ _random: ld (iy+3*4+0),a ; l(state[3]) = t3l ; Calculate result. ld hl,(iy+3*4) - ld a,b ; auhl = t3 - ld de,(iy+2*4) - ld c,(iy+2*4+3) ; cude = state[2] + ld a,b ; a:uhl = t3 + ld de,(iy+2*4) ; (iy+2*4+3):ude = state[2] add hl,de - adc a,c ; auhl = t3 + state[2] = result - ld e,a ; euhl = result + adc a,(iy+2*4+3) ; a:uhl = t3 + state[2] = result + ld e,a ; e:uhl = result ret ; --- @@ -114,11 +114,11 @@ _random: _srandom: pop bc pop de - ex (sp),hl ; lude = seed + ex (sp),hl ; l:ude = seed push de push bc ex de,hl - ld a,e ; auhl = seed + ld a,e ; a:uhl = seed .global __setstate .type __setstate, @function diff --git a/test/standalone/random/autotest.json b/test/standalone/random/autotest.json new file mode 100644 index 000000000..00cb31d03 --- /dev/null +++ b/test/standalone/random/autotest.json @@ -0,0 +1,40 @@ +{ + "transfer_files": [ + "bin/DEMO.8xp" + ], + "target": { + "name": "DEMO", + "isASM": true + }, + "sequence": [ + "action|launch", + "delay|1000", + "hashWait|1", + "key|enter", + "delay|300", + "hashWait|2" + ], + "hashes": { + "1": { + "description": "All tests passed", + "timeout": 5000, + "start": "vram_start", + "size": "vram_16_size", + "expected_CRCs": [ + "38E2AD5A" + ] + }, + "2": { + "description": "Exit", + "start": "vram_start", + "size": "vram_16_size", + "expected_CRCs": [ + "FFAF89BA", + "101734A5", + "9DA19F44", + "A32840C8", + "349F4775" + ] + } + } +} diff --git a/test/standalone/random/makefile b/test/standalone/random/makefile new file mode 100644 index 000000000..0785e61ca --- /dev/null +++ b/test/standalone/random/makefile @@ -0,0 +1,19 @@ +# ---------------------------- +# Makefile Options +# ---------------------------- + +NAME = DEMO +ICON = icon.png +DESCRIPTION = "CE C Toolchain Demo" +COMPRESSED = NO +ARCHIVED = NO + +CFLAGS = -Wall -Wextra -Oz +CXXFLAGS = -Wall -Wextra -Oz + +HAS_MATH_ERRNO = YES +PREFER_OS_LIBC = NO + +# ---------------------------- + +include $(shell cedev-config --makefile) diff --git a/test/standalone/random/src/main.c b/test/standalone/random/src/main.c new file mode 100644 index 000000000..1c96c2b1d --- /dev/null +++ b/test/standalone/random/src/main.c @@ -0,0 +1,189 @@ +#include +#include +#include +#include +#include +#include + +/** + * If the algorithm/output for random/srandom or rand/srand changes, you can + * set GENERATE_TESTS to 1, and copy and paste the new lookup table values. + */ + +//------------------------------------------------------------------------------ +// Config +//------------------------------------------------------------------------------ + +/** + * define to 0 or 1 + * 0: run test cases + * 1: regenerate test cases + */ +#define GENERATE_TESTS 0 + +#define TEST_COUNT (16) + +//------------------------------------------------------------------------------ +// Test data +//------------------------------------------------------------------------------ + +const unsigned long random_0[] = { + 0x03050704, + 0x54710D87, + 0xA5BD8B69, + 0xA9F363AF, + 0xD886A9DD, + 0x7E80E185, + 0xBEE50F75, + 0xE084D90B, + 0x1ABFA826, + 0xB374C8E7, + 0x38383D5E, + 0xC4A1AACA, + 0xCB856CF1, + 0x0891BB41, + 0xA5D37384, + 0xC59A3F68, +}; + +const unsigned long random_X[] = { + 0x03050704, + 0x3A2805E1, + 0x1825044C, + 0x394804A2, + 0x1F5D0344, + 0x08800A73, + 0x5A1D0FAF, + 0x26680D98, + 0x49AD0ED1, + 0x3E280E2C, + 0x4E4D0B5A, + 0x17A01302, + 0x8EB51683, + 0x39B0165A, + 0x8A651905, + 0x4150221B, +}; + +const int rand_0[] = { + 0x050704, + 0x710D87, + 0x3D8B69, + 0x7363AF, + 0x06A9DD, + 0x00E184, + 0x650F74, + 0x04D90B, + 0x3FA825, + 0x74C8E6, + 0x383D5D, + 0x21AACA, + 0x056CF1, + 0x11BB40, + 0x537384, + 0x1A3F68, +}; + +const int rand_X[] = { + 0x050704, + 0x2805C9, + 0x6503BE, + 0x180A56, + 0x2D0FC7, + 0x180B3B, + 0x4510F9, + 0x1013C9, + 0x5D163F, + 0x281AB6, + 0x1D1B1E, + 0x701CDD, + 0x1D22ED, + 0x78295A, + 0x2D3213, + 0x38359A, +}; + +//------------------------------------------------------------------------------ +// Code +//------------------------------------------------------------------------------ + +#ifndef GENERATE_TESTS +#error "GENERATE_TESTS must be 0 or 1" +#endif /* GENERATE_TESTS */ + +#if GENERATE_TESTS + +void outchar(char ch) { + *(char*)0xFB0000 = ch; + *(char*)0xFB0001 = '\0'; +} +#define gen_printf printf +#define C(...) + +#else /* GENERATE_TESTS */ + +#define gen_printf(...) +#define C(expr) if (!(expr)) { return __LINE__; } + +#endif /* GENERATE_TESTS */ + +int run_tests() { + gen_printf("const unsigned long random_0[] = {\n"); + srandom(0); + for (int i = 0; i < TEST_COUNT; i++) { + unsigned long value = random(); + C(value == random_0[i]); + gen_printf(" 0x%08lX,\n", value); + } + gen_printf("};\n\n"); + + gen_printf("const unsigned long random_X[] = {\n"); + srandom(0); + for (int i = 0; i < TEST_COUNT; i++) { + unsigned long value = random(); + C(value == random_X[i]); + srandom(value); + gen_printf(" 0x%08lX,\n", value); + } + gen_printf("};\n\n"); + + gen_printf("const int rand_0[] = {\n"); + srand(0); + for (int i = 0; i < TEST_COUNT; i++) { + int value = rand(); + C(value == rand_0[i]); + gen_printf(" 0x%06X,\n", value); + } + gen_printf("};\n\n"); + + gen_printf("const int rand_X[] = {\n"); + srand(0); + for (int i = 0; i < TEST_COUNT; i++) { + int value = rand(); + C(value == rand_X[i]); + srand(value); + gen_printf(" 0x%06X,\n", value); + } + gen_printf("};\n\n"); + return 0; +} + +int main(void) { + os_ClrHome(); + int failed_test = run_tests(); + if (failed_test != 0) { + char buf[sizeof("Failed test L-8388608")]; + boot_sprintf(buf, "Failed test L%d", failed_test); + puts(buf); + } else { + puts("All tests passed"); + } + +#if GENERATE_TESTS + os_PutStrLine("check debug console"); +#endif /* GENERATE_TESTS */ + + while (!os_GetCSC()); + + return 0; +}