diff --git a/README.md b/README.md index b787486..552adb4 100644 --- a/README.md +++ b/README.md @@ -22,6 +22,7 @@ Although based on a fully fledged CPU emulator, uvm32 is intended for executing * [apps/helloworld](apps/helloworld) C hello world program * [apps/conio](apps/conio) C console IO demo * [apps/lissajous](apps/lissajous) C console lissajous curve (showing softfp, floating point) + * [apps/maze](apps/maze) C ASCII art recursive maze generation * [apps/hello-asm](apps/hello-asm) Minimal hello world assembly * [apps/fib](apps/fib) C fibonacci series program (iterative and recursive) * [apps/self](apps/self) host-mini with embedded mandelbrot generation program, compiled as an app (inception!) diff --git a/apps/Makefile b/apps/Makefile index 69c99b7..40c4fb5 100644 --- a/apps/Makefile +++ b/apps/Makefile @@ -11,6 +11,7 @@ all: (cd zigtris && make) (cd rust-hello && make) (cd hello-asm && make) + (cd maze && make) clean: (cd sketch && make clean) @@ -22,4 +23,5 @@ clean: (cd zigtris && make clean) (cd rust-hello && make clean) (cd hello-asm && make clean) + (cd maze && make clean) diff --git a/apps/maze/Makefile b/apps/maze/Makefile new file mode 100644 index 0000000..d0d1359 --- /dev/null +++ b/apps/maze/Makefile @@ -0,0 +1,27 @@ +PROJECT:=maze + +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 + diff --git a/apps/maze/maze.c b/apps/maze/maze.c new file mode 100644 index 0000000..20b5d61 --- /dev/null +++ b/apps/maze/maze.c @@ -0,0 +1,85 @@ +#include "uvm32_target.h" + +// This example generates a random maze using the recursive backtracking algorithm. +// https://github.com/ccattuto/riscv-python/blob/main/tests/test_newlib_maze.c + +#define WIDTH 79 // must be odd +#define HEIGHT 31 // must be odd + +char maze[HEIGHT * WIDTH]; + +void* memcpy(void* dst, const void* src, int len) { + uint8_t* d = (uint8_t*)dst; + const uint8_t* s = (const uint8_t*)src; + while (len--) { + *(d++) = *(s++); + } + return dst; +} + +void* memset(void* buf, int c, int len) { + uint8_t* b = (uint8_t*)buf; + while (len--) { + *(b++) = c; + } + return buf; +} + +int dx[] = {0, 1, 0, -1}; +int dy[] = {-1, 0, 1, 0}; + +int seed = 123456789; + +int rand() { + uint32_t a = 1103515245; + uint32_t c = 12345; + uint32_t m = 0xFFFFFFFF; + seed = (a * seed + c) % m; + return seed; +} + +void init_maze() { + memset(maze, '#', sizeof(maze)); +} + +int in_bounds(int x, int y) { + return x > 0 && y > 0 && x < WIDTH - 1 && y < HEIGHT - 1; +} + +void carve(int x, int y) { + maze[y * WIDTH + x] = ' '; + + int dirs[] = {0, 1, 2, 3}; + // Fisher-Yates shuffle + for (int i = 3; i > 0; i--) { + int j = rand() % (i + 1); + int tmp = dirs[i]; + dirs[i] = dirs[j]; + dirs[j] = tmp; + } + + for (int i = 0; i < 4; i++) { + int nx = x + dx[dirs[i]] * 2; + int ny = y + dy[dirs[i]] * 2; + + if (in_bounds(nx, ny) && maze[ny * WIDTH + nx] == '#') { + maze[(y + dy[dirs[i]]) * WIDTH + (x + dx[dirs[i]])] = ' '; + carve(nx, ny); + } + } +} + +void print_maze() { + for (int y = 0; y < HEIGHT; y++) { + for (int x = 0; x < WIDTH; x++) { + putc(maze[y * WIDTH + x]); + } + putc('\n'); + } +} + +void main(void) { + init_maze(); + carve(1, 1); + print_maze(); +} diff --git a/host/Makefile b/host/Makefile index 9e05032..8772ac9 100644 --- a/host/Makefile +++ b/host/Makefile @@ -1,5 +1,5 @@ all: - gcc -Wall -pedantic -std=c99 -O2 -DUVM32_MEMORY_SIZE=32768 -I../uvm32 -I../common -o host ../uvm32/uvm32.c host.c + gcc -Wall -pedantic -std=c99 -O2 -DUVM32_MEMORY_SIZE=65535 -I../uvm32 -I../common -o host ../uvm32/uvm32.c host.c clean: rm -f host diff --git a/precompiled/maze.bin b/precompiled/maze.bin new file mode 100755 index 0000000..d292845 Binary files /dev/null and b/precompiled/maze.bin differ