# HG changeset patch # User John Tsiombikas # Date 1519303592 -7200 # Node ID 555b986cc4208b1e47eeeef4de5cf13a77ba52bb # Parent 58ebd84822e733ea796844bd0362cb4509fb5f1e IFS diff -r 58ebd84822e7 -r 555b986cc420 src/copper.h --- a/src/copper.h Thu Feb 22 12:44:20 2018 +0200 +++ b/src/copper.h Thu Feb 22 14:46:32 2018 +0200 @@ -11,6 +11,7 @@ #define COPPER_VWAIT(s) (0x0001ff00 | ((uint32_t)((s) + 0x2c) << 24)) #define COPPER_VWAIT_OVERSCAN(s) \ (0x0001ff00 | ((uint32_t)(s) << 24)) +#define COPPER_OVERFLOW 0xffdffffe #define COPPER_END 0xfffffffe extern uint32_t *copperlist, *copperlist_end; diff -r 58ebd84822e7 -r 555b986cc420 src/main.c --- a/src/main.c Thu Feb 22 12:44:20 2018 +0200 +++ b/src/main.c Thu Feb 22 14:46:32 2018 +0200 @@ -1,6 +1,7 @@ #include "hwregs.h" #include "intr.h" #include "copper.h" +#include "rng.h" #define BPLSZ (320 / 8 * 256) static unsigned char fb0[BPLSZ]; @@ -30,15 +31,27 @@ static uint32_t coplist[] = { COPPER_MOVE(REGN_BPL1PTH, 0), COPPER_MOVE(REGN_BPL1PTL, 0), - COPPER_VWAIT(50), - COPPER_MOVE(REGN_COLOR0, 0x00a), - COPPER_VWAIT(60), - COPPER_MOVE(REGN_COLOR0, 0x008), + + COPPER_MOVE(REGN_COLOR0, 0x234), + COPPER_VWAIT(15), + COPPER_MOVE(REGN_COLOR0, 0x012), + COPPER_VWAIT(20), + COPPER_MOVE(REGN_COLOR0, 0x235), + + COPPER_OVERFLOW, + + COPPER_VWAIT(220), + COPPER_MOVE(REGN_COLOR0, 0x346), + COPPER_VWAIT(225), + COPPER_MOVE(REGN_COLOR0, 0x234), + COPPER_END }; int main(void) { + int32_t x = 0, y = 0; + REG_INTENA = SETBITS(INTEN_VERTB | INTEN_MASTER); REG_DMACON = CLRBITS(DMA_ALL); @@ -49,8 +62,8 @@ REG_DDFSTART = 0x38; REG_DDFSTOP = 0xd0; - REG_COLOR0 = 0x008; - REG_COLOR1 = 0xaaa; + REG_COLOR0 = 0x235; + REG_COLOR1 = 0x2f5; wait_vblank(); coplist[0] = COPPER_MOVE(REGN_BPL1PTH, (uint32_t)fb0 >> 16); @@ -58,11 +71,44 @@ REG32_COP1LC = (uint32_t)coplist; REG_COPJMP1 = 0; - fb0[128 * 320 / 8 + 160 / 8] = 8; - REG_DMACON = SETBITS(DMA_BPL | DMA_COPPER | DMA_MASTER); + srand(0); + +#define CDF0 655 +#define CDF1 56361 +#define CDF2 60948 + for(;;) { + int sel = rand() & 0xffff; + int32_t px, py; + unsigned char *pptr; + + if(sel < CDF0) { + x = 0; + y = (y >> 8) * (10486 >> 8); + } else if(sel < CDF1) { + int32_t nx = (x >> 8) * (55705 >> 8) + (y >> 8) * (2621 >> 8); + y = (y >> 8) * (55705 >> 8) - (x >> 8) * (2621 >> 8) + 104857; + x = nx; + } else if(sel < CDF2) { + int32_t nx = (x >> 8) * (13107 >> 8) - (y >> 8) * (17039 >> 8); + y = (x >> 8) * (15073 >> 8) + (y >> 8) * (14417 >> 8) + 104857; + x = nx; + } else { + int32_t nx = (y >> 8) * (18350 >> 8) - (x >> 8) * (9830 >> 8); + y = (x >> 8) * (17039 >> 8) + (y >> 8) * (15728 >> 8) + 28835; + x = nx; + } + + px = (y >> 11); + py = 128 - (x >> 11); + + if(py >= 0) { + pptr = fb0 + (py * 320 + px) / 8; + *pptr = *pptr | (0x80 >> (px & 7)); + } + wait_vblank(); } diff -r 58ebd84822e7 -r 555b986cc420 src/rng.c --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/src/rng.c Thu Feb 22 14:46:32 2018 +0200 @@ -0,0 +1,159 @@ +#include "rng.h" + +/** + * tinymt32 internal state vector and parameters + */ +typedef struct tinymt32 { + uint32_t status[4]; + uint32_t mat1; + uint32_t mat2; + uint32_t tmat; +} tinymt32_t; + +static tinymt32_t st; + +static void tinymt32_init(tinymt32_t * random, uint32_t seed); +inline static uint32_t tinymt32_generate_uint32(tinymt32_t * random); +/*inline static float tinymt32_generate_float(tinymt32_t * random);*/ + +void srand(unsigned int s) +{ + tinymt32_init(&st, s); +} + +int32_t rand(void) +{ + return tinymt32_generate_uint32(&st) & RAND_MAX; +} + +/** + * @file tinymt32.h + * + * @brief Tiny Mersenne Twister only 127 bit internal state + * + * @author Mutsuo Saito (Hiroshima University) + * @author Makoto Matsumoto (University of Tokyo) + * + * Copyright (C) 2011 Mutsuo Saito, Makoto Matsumoto, + * Hiroshima University and The University of Tokyo. + * All rights reserved. + * + * The 3-clause BSD License is applied to this software, see + * LICENSE.txt + */ +#define TINYMT32_MEXP 127 +#define TINYMT32_SH0 1 +#define TINYMT32_SH1 10 +#define TINYMT32_SH8 8 +#define TINYMT32_MASK 0x7fffffffu +/*#define TINYMT32_MUL (1.0f / 4294967296.0f)*/ + +/** + * This function changes internal state of tinymt32. + * Users should not call this function directly. + * @param random tinymt internal status + */ +inline static void tinymt32_next_state(tinymt32_t * random) { + uint32_t x; + uint32_t y; + + y = random->status[3]; + x = (random->status[0] & TINYMT32_MASK) + ^ random->status[1] + ^ random->status[2]; + x ^= (x << TINYMT32_SH0); + y ^= (y >> TINYMT32_SH0) ^ x; + random->status[0] = random->status[1]; + random->status[1] = random->status[2]; + random->status[2] = x ^ (y << TINYMT32_SH1); + random->status[3] = y; + random->status[1] ^= -((int32_t)(y & 1)) & random->mat1; + random->status[2] ^= -((int32_t)(y & 1)) & random->mat2; +} + +/** + * This function outputs 32-bit unsigned integer from internal state. + * Users should not call this function directly. + * @param random tinymt internal status + * @return 32-bit unsigned pseudorandom number + */ +inline static uint32_t tinymt32_temper(tinymt32_t * random) { + uint32_t t0, t1; + t0 = random->status[3]; +#if defined(LINEARITY_CHECK) + t1 = random->status[0] + ^ (random->status[2] >> TINYMT32_SH8); +#else + t1 = random->status[0] + + (random->status[2] >> TINYMT32_SH8); +#endif + t0 ^= t1; + t0 ^= -((int32_t)(t1 & 1)) & random->tmat; + return t0; +} + +/** + * This function outputs 32-bit unsigned integer from internal state. + * @param random tinymt internal status + * @return 32-bit unsigned integer r (0 <= r < 2^32) + */ +inline static uint32_t tinymt32_generate_uint32(tinymt32_t * random) { + tinymt32_next_state(random); + return tinymt32_temper(random); +} + +#if 0 +/** + * This function outputs floating point number from internal state. + * This function is implemented using multiplying by 1 / 2^32. + * floating point multiplication is faster than using union trick in + * my Intel CPU. + * @param random tinymt internal status + * @return floating point number r (0.0 <= r < 1.0) + */ +inline static float tinymt32_generate_float(tinymt32_t * random) { + tinymt32_next_state(random); + return tinymt32_temper(random) * TINYMT32_MUL; +} +#endif + +#define MIN_LOOP 8 +#define PRE_LOOP 8 + +/** + * This function certificate the period of 2^127-1. + * @param random tinymt state vector. + */ +static void period_certification(tinymt32_t * random) { + if ((random->status[0] & TINYMT32_MASK) == 0 && + random->status[1] == 0 && + random->status[2] == 0 && + random->status[3] == 0) { + random->status[0] = 'T'; + random->status[1] = 'I'; + random->status[2] = 'N'; + random->status[3] = 'Y'; + } +} + +/** + * This function initializes the internal state array with a 32-bit + * unsigned integer seed. + * @param random tinymt state vector. + * @param seed a 32-bit unsigned integer used as a seed. + */ +static void tinymt32_init(tinymt32_t * random, uint32_t seed) { + random->status[0] = seed; + random->status[1] = random->mat1; + random->status[2] = random->mat2; + random->status[3] = random->tmat; + for (int i = 1; i < MIN_LOOP; i++) { + random->status[i & 3] ^= i + 1812433253u + * (random->status[(i - 1) & 3] + ^ (random->status[(i - 1) & 3] >> 30)); + } + period_certification(random); + for (int i = 0; i < PRE_LOOP; i++) { + tinymt32_next_state(random); + } +} diff -r 58ebd84822e7 -r 555b986cc420 src/rng.h --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/src/rng.h Thu Feb 22 14:46:32 2018 +0200 @@ -0,0 +1,11 @@ +#ifndef RNG_H_ +#define RNG_H_ + +#include "inttypes.h" + +#define RAND_MAX 0x7fffffff + +void srand(unsigned int s); +int32_t rand(void); + +#endif /* RNG_H_ */