amiga_boottest
changeset 3:555b986cc420
IFS
author | John Tsiombikas <nuclear@member.fsf.org> |
---|---|
date | Thu, 22 Feb 2018 14:46:32 +0200 |
parents | 58ebd84822e7 |
children | 995d42b33974 |
files | src/copper.h src/main.c src/rng.c src/rng.h |
diffstat | 4 files changed, 225 insertions(+), 8 deletions(-) [+] |
line diff
1.1 --- a/src/copper.h Thu Feb 22 12:44:20 2018 +0200 1.2 +++ b/src/copper.h Thu Feb 22 14:46:32 2018 +0200 1.3 @@ -11,6 +11,7 @@ 1.4 #define COPPER_VWAIT(s) (0x0001ff00 | ((uint32_t)((s) + 0x2c) << 24)) 1.5 #define COPPER_VWAIT_OVERSCAN(s) \ 1.6 (0x0001ff00 | ((uint32_t)(s) << 24)) 1.7 +#define COPPER_OVERFLOW 0xffdffffe 1.8 #define COPPER_END 0xfffffffe 1.9 1.10 extern uint32_t *copperlist, *copperlist_end;
2.1 --- a/src/main.c Thu Feb 22 12:44:20 2018 +0200 2.2 +++ b/src/main.c Thu Feb 22 14:46:32 2018 +0200 2.3 @@ -1,6 +1,7 @@ 2.4 #include "hwregs.h" 2.5 #include "intr.h" 2.6 #include "copper.h" 2.7 +#include "rng.h" 2.8 2.9 #define BPLSZ (320 / 8 * 256) 2.10 static unsigned char fb0[BPLSZ]; 2.11 @@ -30,15 +31,27 @@ 2.12 static uint32_t coplist[] = { 2.13 COPPER_MOVE(REGN_BPL1PTH, 0), 2.14 COPPER_MOVE(REGN_BPL1PTL, 0), 2.15 - COPPER_VWAIT(50), 2.16 - COPPER_MOVE(REGN_COLOR0, 0x00a), 2.17 - COPPER_VWAIT(60), 2.18 - COPPER_MOVE(REGN_COLOR0, 0x008), 2.19 + 2.20 + COPPER_MOVE(REGN_COLOR0, 0x234), 2.21 + COPPER_VWAIT(15), 2.22 + COPPER_MOVE(REGN_COLOR0, 0x012), 2.23 + COPPER_VWAIT(20), 2.24 + COPPER_MOVE(REGN_COLOR0, 0x235), 2.25 + 2.26 + COPPER_OVERFLOW, 2.27 + 2.28 + COPPER_VWAIT(220), 2.29 + COPPER_MOVE(REGN_COLOR0, 0x346), 2.30 + COPPER_VWAIT(225), 2.31 + COPPER_MOVE(REGN_COLOR0, 0x234), 2.32 + 2.33 COPPER_END 2.34 }; 2.35 2.36 int main(void) 2.37 { 2.38 + int32_t x = 0, y = 0; 2.39 + 2.40 REG_INTENA = SETBITS(INTEN_VERTB | INTEN_MASTER); 2.41 2.42 REG_DMACON = CLRBITS(DMA_ALL); 2.43 @@ -49,8 +62,8 @@ 2.44 REG_DDFSTART = 0x38; 2.45 REG_DDFSTOP = 0xd0; 2.46 2.47 - REG_COLOR0 = 0x008; 2.48 - REG_COLOR1 = 0xaaa; 2.49 + REG_COLOR0 = 0x235; 2.50 + REG_COLOR1 = 0x2f5; 2.51 2.52 wait_vblank(); 2.53 coplist[0] = COPPER_MOVE(REGN_BPL1PTH, (uint32_t)fb0 >> 16); 2.54 @@ -58,11 +71,44 @@ 2.55 REG32_COP1LC = (uint32_t)coplist; 2.56 REG_COPJMP1 = 0; 2.57 2.58 - fb0[128 * 320 / 8 + 160 / 8] = 8; 2.59 - 2.60 REG_DMACON = SETBITS(DMA_BPL | DMA_COPPER | DMA_MASTER); 2.61 2.62 + srand(0); 2.63 + 2.64 +#define CDF0 655 2.65 +#define CDF1 56361 2.66 +#define CDF2 60948 2.67 + 2.68 for(;;) { 2.69 + int sel = rand() & 0xffff; 2.70 + int32_t px, py; 2.71 + unsigned char *pptr; 2.72 + 2.73 + if(sel < CDF0) { 2.74 + x = 0; 2.75 + y = (y >> 8) * (10486 >> 8); 2.76 + } else if(sel < CDF1) { 2.77 + int32_t nx = (x >> 8) * (55705 >> 8) + (y >> 8) * (2621 >> 8); 2.78 + y = (y >> 8) * (55705 >> 8) - (x >> 8) * (2621 >> 8) + 104857; 2.79 + x = nx; 2.80 + } else if(sel < CDF2) { 2.81 + int32_t nx = (x >> 8) * (13107 >> 8) - (y >> 8) * (17039 >> 8); 2.82 + y = (x >> 8) * (15073 >> 8) + (y >> 8) * (14417 >> 8) + 104857; 2.83 + x = nx; 2.84 + } else { 2.85 + int32_t nx = (y >> 8) * (18350 >> 8) - (x >> 8) * (9830 >> 8); 2.86 + y = (x >> 8) * (17039 >> 8) + (y >> 8) * (15728 >> 8) + 28835; 2.87 + x = nx; 2.88 + } 2.89 + 2.90 + px = (y >> 11); 2.91 + py = 128 - (x >> 11); 2.92 + 2.93 + if(py >= 0) { 2.94 + pptr = fb0 + (py * 320 + px) / 8; 2.95 + *pptr = *pptr | (0x80 >> (px & 7)); 2.96 + } 2.97 + 2.98 wait_vblank(); 2.99 } 2.100
3.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000 3.2 +++ b/src/rng.c Thu Feb 22 14:46:32 2018 +0200 3.3 @@ -0,0 +1,159 @@ 3.4 +#include "rng.h" 3.5 + 3.6 +/** 3.7 + * tinymt32 internal state vector and parameters 3.8 + */ 3.9 +typedef struct tinymt32 { 3.10 + uint32_t status[4]; 3.11 + uint32_t mat1; 3.12 + uint32_t mat2; 3.13 + uint32_t tmat; 3.14 +} tinymt32_t; 3.15 + 3.16 +static tinymt32_t st; 3.17 + 3.18 +static void tinymt32_init(tinymt32_t * random, uint32_t seed); 3.19 +inline static uint32_t tinymt32_generate_uint32(tinymt32_t * random); 3.20 +/*inline static float tinymt32_generate_float(tinymt32_t * random);*/ 3.21 + 3.22 +void srand(unsigned int s) 3.23 +{ 3.24 + tinymt32_init(&st, s); 3.25 +} 3.26 + 3.27 +int32_t rand(void) 3.28 +{ 3.29 + return tinymt32_generate_uint32(&st) & RAND_MAX; 3.30 +} 3.31 + 3.32 +/** 3.33 + * @file tinymt32.h 3.34 + * 3.35 + * @brief Tiny Mersenne Twister only 127 bit internal state 3.36 + * 3.37 + * @author Mutsuo Saito (Hiroshima University) 3.38 + * @author Makoto Matsumoto (University of Tokyo) 3.39 + * 3.40 + * Copyright (C) 2011 Mutsuo Saito, Makoto Matsumoto, 3.41 + * Hiroshima University and The University of Tokyo. 3.42 + * All rights reserved. 3.43 + * 3.44 + * The 3-clause BSD License is applied to this software, see 3.45 + * LICENSE.txt 3.46 + */ 3.47 +#define TINYMT32_MEXP 127 3.48 +#define TINYMT32_SH0 1 3.49 +#define TINYMT32_SH1 10 3.50 +#define TINYMT32_SH8 8 3.51 +#define TINYMT32_MASK 0x7fffffffu 3.52 +/*#define TINYMT32_MUL (1.0f / 4294967296.0f)*/ 3.53 + 3.54 +/** 3.55 + * This function changes internal state of tinymt32. 3.56 + * Users should not call this function directly. 3.57 + * @param random tinymt internal status 3.58 + */ 3.59 +inline static void tinymt32_next_state(tinymt32_t * random) { 3.60 + uint32_t x; 3.61 + uint32_t y; 3.62 + 3.63 + y = random->status[3]; 3.64 + x = (random->status[0] & TINYMT32_MASK) 3.65 + ^ random->status[1] 3.66 + ^ random->status[2]; 3.67 + x ^= (x << TINYMT32_SH0); 3.68 + y ^= (y >> TINYMT32_SH0) ^ x; 3.69 + random->status[0] = random->status[1]; 3.70 + random->status[1] = random->status[2]; 3.71 + random->status[2] = x ^ (y << TINYMT32_SH1); 3.72 + random->status[3] = y; 3.73 + random->status[1] ^= -((int32_t)(y & 1)) & random->mat1; 3.74 + random->status[2] ^= -((int32_t)(y & 1)) & random->mat2; 3.75 +} 3.76 + 3.77 +/** 3.78 + * This function outputs 32-bit unsigned integer from internal state. 3.79 + * Users should not call this function directly. 3.80 + * @param random tinymt internal status 3.81 + * @return 32-bit unsigned pseudorandom number 3.82 + */ 3.83 +inline static uint32_t tinymt32_temper(tinymt32_t * random) { 3.84 + uint32_t t0, t1; 3.85 + t0 = random->status[3]; 3.86 +#if defined(LINEARITY_CHECK) 3.87 + t1 = random->status[0] 3.88 + ^ (random->status[2] >> TINYMT32_SH8); 3.89 +#else 3.90 + t1 = random->status[0] 3.91 + + (random->status[2] >> TINYMT32_SH8); 3.92 +#endif 3.93 + t0 ^= t1; 3.94 + t0 ^= -((int32_t)(t1 & 1)) & random->tmat; 3.95 + return t0; 3.96 +} 3.97 + 3.98 +/** 3.99 + * This function outputs 32-bit unsigned integer from internal state. 3.100 + * @param random tinymt internal status 3.101 + * @return 32-bit unsigned integer r (0 <= r < 2^32) 3.102 + */ 3.103 +inline static uint32_t tinymt32_generate_uint32(tinymt32_t * random) { 3.104 + tinymt32_next_state(random); 3.105 + return tinymt32_temper(random); 3.106 +} 3.107 + 3.108 +#if 0 3.109 +/** 3.110 + * This function outputs floating point number from internal state. 3.111 + * This function is implemented using multiplying by 1 / 2^32. 3.112 + * floating point multiplication is faster than using union trick in 3.113 + * my Intel CPU. 3.114 + * @param random tinymt internal status 3.115 + * @return floating point number r (0.0 <= r < 1.0) 3.116 + */ 3.117 +inline static float tinymt32_generate_float(tinymt32_t * random) { 3.118 + tinymt32_next_state(random); 3.119 + return tinymt32_temper(random) * TINYMT32_MUL; 3.120 +} 3.121 +#endif 3.122 + 3.123 +#define MIN_LOOP 8 3.124 +#define PRE_LOOP 8 3.125 + 3.126 +/** 3.127 + * This function certificate the period of 2^127-1. 3.128 + * @param random tinymt state vector. 3.129 + */ 3.130 +static void period_certification(tinymt32_t * random) { 3.131 + if ((random->status[0] & TINYMT32_MASK) == 0 && 3.132 + random->status[1] == 0 && 3.133 + random->status[2] == 0 && 3.134 + random->status[3] == 0) { 3.135 + random->status[0] = 'T'; 3.136 + random->status[1] = 'I'; 3.137 + random->status[2] = 'N'; 3.138 + random->status[3] = 'Y'; 3.139 + } 3.140 +} 3.141 + 3.142 +/** 3.143 + * This function initializes the internal state array with a 32-bit 3.144 + * unsigned integer seed. 3.145 + * @param random tinymt state vector. 3.146 + * @param seed a 32-bit unsigned integer used as a seed. 3.147 + */ 3.148 +static void tinymt32_init(tinymt32_t * random, uint32_t seed) { 3.149 + random->status[0] = seed; 3.150 + random->status[1] = random->mat1; 3.151 + random->status[2] = random->mat2; 3.152 + random->status[3] = random->tmat; 3.153 + for (int i = 1; i < MIN_LOOP; i++) { 3.154 + random->status[i & 3] ^= i + 1812433253u 3.155 + * (random->status[(i - 1) & 3] 3.156 + ^ (random->status[(i - 1) & 3] >> 30)); 3.157 + } 3.158 + period_certification(random); 3.159 + for (int i = 0; i < PRE_LOOP; i++) { 3.160 + tinymt32_next_state(random); 3.161 + } 3.162 +}
4.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000 4.2 +++ b/src/rng.h Thu Feb 22 14:46:32 2018 +0200 4.3 @@ -0,0 +1,11 @@ 4.4 +#ifndef RNG_H_ 4.5 +#define RNG_H_ 4.6 + 4.7 +#include "inttypes.h" 4.8 + 4.9 +#define RAND_MAX 0x7fffffff 4.10 + 4.11 +void srand(unsigned int s); 4.12 +int32_t rand(void); 4.13 + 4.14 +#endif /* RNG_H_ */