mirror of
https://github.com/ringtailsoftware/uvm32.git
synced 2026-06-05 22:43:39 +00:00
Lissajous, showing floating point arithmetic
This commit is contained in:
parent
de689bdeaf
commit
ebb6518ec3
5 changed files with 148 additions and 0 deletions
|
|
@ -21,6 +21,7 @@ Although based on a fully fledged CPU emulator, uvm32 is intended for executing
|
||||||
* [host-arduino](host-arduino) vm host as Arduino sketch (tested on Arduino Uno ATmega328P, uses 9950 bytes of flash/1254 bytes RAM)
|
* [host-arduino](host-arduino) vm host as Arduino sketch (tested on Arduino Uno ATmega328P, uses 9950 bytes of flash/1254 bytes RAM)
|
||||||
* [apps/helloworld](apps/helloworld) C hello world program
|
* [apps/helloworld](apps/helloworld) C hello world program
|
||||||
* [apps/conio](apps/conio) C console IO demo
|
* [apps/conio](apps/conio) C console IO demo
|
||||||
|
* [apps/lissajous](apps/lissajour) C console lissajous curve (showing softfp, floating point)
|
||||||
* [apps/hello-asm](apps/hello-asm) Minimal hello world assembly
|
* [apps/hello-asm](apps/hello-asm) Minimal hello world assembly
|
||||||
* [apps/fib](apps/fib) C fibonacci series program (iterative and recursive)
|
* [apps/fib](apps/fib) C fibonacci series program (iterative and recursive)
|
||||||
* [apps/sketch](apps/sketch) C Arduino/Wiring/Processing type program in `setup()` and `loop()` style
|
* [apps/sketch](apps/sketch) C Arduino/Wiring/Processing type program in `setup()` and `loop()` style
|
||||||
|
|
|
||||||
|
|
@ -4,6 +4,7 @@ all:
|
||||||
docker build -t ${DOCKER_IMAGE} .
|
docker build -t ${DOCKER_IMAGE} .
|
||||||
(cd sketch && make)
|
(cd sketch && make)
|
||||||
(cd helloworld && make)
|
(cd helloworld && make)
|
||||||
|
(cd lissajous && make)
|
||||||
(cd conio && make)
|
(cd conio && make)
|
||||||
(cd zig-mandel && make)
|
(cd zig-mandel && make)
|
||||||
(cd zigtris && make)
|
(cd zigtris && make)
|
||||||
|
|
@ -13,6 +14,7 @@ all:
|
||||||
clean:
|
clean:
|
||||||
(cd sketch && make clean)
|
(cd sketch && make clean)
|
||||||
(cd helloworld && make clean)
|
(cd helloworld && make clean)
|
||||||
|
(cd lissajous && make clean)
|
||||||
(cd conio && make clean)
|
(cd conio && make clean)
|
||||||
(cd zig-mandel && make clean)
|
(cd zig-mandel && make clean)
|
||||||
(cd zigtris && make clean)
|
(cd zigtris && make clean)
|
||||||
|
|
|
||||||
27
apps/lissajous/Makefile
Normal file
27
apps/lissajous/Makefile
Normal file
|
|
@ -0,0 +1,27 @@
|
||||||
|
PROJECT:=lissajous
|
||||||
|
|
||||||
|
DOCKER_IMAGE=riscv-dev
|
||||||
|
DOCKER_CMD:=docker run --rm -v ${PWD}../../../:/data -w /data/apps/${PROJECT} ${DOCKER_IMAGE}
|
||||||
|
PREFIX:=${DOCKER_CMD} riscv64-unknown-elf-
|
||||||
|
CFLAGS+=-I../../common
|
||||||
|
CFLAGS+=-fno-stack-protector
|
||||||
|
CFLAGS+=-static-libgcc -fdata-sections -ffunction-sections
|
||||||
|
CFLAGS+=-g -Os -march=rv32ima_zicsr -mabi=ilp32 -static
|
||||||
|
LDFLAGS:= -T ../linker.ld -nostdlib -Wl,--gc-sections
|
||||||
|
LIBS:= -lgcc # needed for softfp
|
||||||
|
|
||||||
|
SRCS=${PROJECT}.c ../crt0.S
|
||||||
|
|
||||||
|
all:
|
||||||
|
${PREFIX}gcc -o ${PROJECT}.elf ${CFLAGS} ${LDFLAGS} ${SRCS} ${LIBS}
|
||||||
|
$(PREFIX)objcopy ${PROJECT}.elf -O binary ${PROJECT}.bin
|
||||||
|
|
||||||
|
disasm: all
|
||||||
|
$(PREFIX)objdump -S -d -f ${PROJECT}.elf
|
||||||
|
|
||||||
|
test: all
|
||||||
|
../../host/host ${PWD}/${PROJECT}.bin
|
||||||
|
|
||||||
|
clean:
|
||||||
|
rm -f ${PROJECT}.o ${PROJECT}.elf ${PROJECT}.bin
|
||||||
|
|
||||||
118
apps/lissajous/lissajous.c
Normal file
118
apps/lissajous/lissajous.c
Normal file
|
|
@ -0,0 +1,118 @@
|
||||||
|
#define USE_MAIN
|
||||||
|
#include "uvm32_target.h"
|
||||||
|
|
||||||
|
// https://github.com/shastro/CodeGolf-Lissajous/blob/master/lissa.c
|
||||||
|
// https://github.com/nicbk/donut-embedded/blob/ad8061ece9a2c156694c39af12f109ea6778da52/donut.c#L57
|
||||||
|
|
||||||
|
#define PI 3.14159265358979323846 // First 21 digits of pi
|
||||||
|
|
||||||
|
void movecursor(int x, int y) {
|
||||||
|
print("\033[");
|
||||||
|
printdec(y);
|
||||||
|
print(";");
|
||||||
|
printdec(x);
|
||||||
|
print("f");
|
||||||
|
}
|
||||||
|
|
||||||
|
void sleep(uint32_t ms) {
|
||||||
|
uint32_t start = millis();
|
||||||
|
while (millis() < start + ms) {
|
||||||
|
yield();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Absolute value function for doubles
|
||||||
|
double abs_c(double x) {
|
||||||
|
if (x < 0) {
|
||||||
|
return -x;
|
||||||
|
} else {
|
||||||
|
return x;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Recursive factorial capable of calculating a max of approximately 10^18 in size
|
||||||
|
unsigned long long fac(unsigned char x) {
|
||||||
|
if (x == 0) {
|
||||||
|
return 1;
|
||||||
|
} else {
|
||||||
|
return x * fac(x - 1);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Exponential function
|
||||||
|
// Ignores edge cases such as indeterminate forms for simplicity
|
||||||
|
double pow_c(double x, unsigned char n) {
|
||||||
|
if (n == 0) {
|
||||||
|
return 1;
|
||||||
|
} else {
|
||||||
|
double product = x;
|
||||||
|
|
||||||
|
for (int i = 1; i < n; ++i) {
|
||||||
|
product *= x;
|
||||||
|
}
|
||||||
|
|
||||||
|
return product;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// MacLaurin series approximation of sin(x) from -PI/2 to PI/2
|
||||||
|
// with eight terms, and extended to the domain of all
|
||||||
|
// real numbers with modular arithmetic.
|
||||||
|
double sin(double x) {
|
||||||
|
double translation = 0;
|
||||||
|
if (x > -PI / 2) {
|
||||||
|
translation = (int)((x + PI / 2) / PI);
|
||||||
|
} else {
|
||||||
|
translation = (int)((x - PI / 2) / PI);
|
||||||
|
}
|
||||||
|
|
||||||
|
x -= PI * translation;
|
||||||
|
if ((int)abs_c(translation) % 2 == 1) {
|
||||||
|
x = -x;
|
||||||
|
}
|
||||||
|
|
||||||
|
double sum = 0;
|
||||||
|
|
||||||
|
for (int i = 0; i < 9; ++i) {
|
||||||
|
sum += pow_c(-1, i) * pow_c(x, 2 * i + 1) / fac(2 * i + 1);
|
||||||
|
}
|
||||||
|
|
||||||
|
return sum;
|
||||||
|
}
|
||||||
|
|
||||||
|
// cos(x) function derived from sin(x)
|
||||||
|
double cos(double x) {
|
||||||
|
return sin(PI / 2 - x);
|
||||||
|
}
|
||||||
|
|
||||||
|
void main(void) {
|
||||||
|
int freq1 = 45;
|
||||||
|
int freq2 = 90;
|
||||||
|
|
||||||
|
for (int i = 0; i < 300; i++) {
|
||||||
|
putc('\n');
|
||||||
|
}
|
||||||
|
print("\033[H"); // Cursor at Corner of Screen
|
||||||
|
|
||||||
|
float x = 0;
|
||||||
|
float y = 0;
|
||||||
|
float angle = 0;
|
||||||
|
float beta = 0.0;
|
||||||
|
|
||||||
|
while (1) {
|
||||||
|
uint32_t framestart = millis();
|
||||||
|
for (angle = 0; angle < 2 * PI; angle += 0.15) {
|
||||||
|
movecursor(x, y);
|
||||||
|
x = 40 * cos(freq1 * angle + beta) + 60;
|
||||||
|
y = 20 * sin(freq2 * angle) + 30;
|
||||||
|
print("#");
|
||||||
|
}
|
||||||
|
// wait for next frame
|
||||||
|
while (millis() < framestart + 20) {
|
||||||
|
yield();
|
||||||
|
}
|
||||||
|
beta += 0.05;
|
||||||
|
|
||||||
|
print("\033[2J");
|
||||||
|
}
|
||||||
|
}
|
||||||
BIN
precompiled/lissajous.bin
Executable file
BIN
precompiled/lissajous.bin
Executable file
Binary file not shown.
Loading…
Add table
Add a link
Reference in a new issue