diff --git a/seminaries/hello-apo/.gitingnore b/seminaries/hello-apo/.gitingnore
new file mode 100644
index 0000000000000000000000000000000000000000..2fe532e90ea841795e63cbcc4314e63e6accb079
--- /dev/null
+++ b/seminaries/hello-apo/.gitingnore
@@ -0,0 +1,9 @@
+*.o
+*.dump
+*-native
+*-x86
+*-riscv
+*-riscv64
+*-mips
+*-arm
+*-aarch64
diff --git a/seminaries/hello-apo/Makefile b/seminaries/hello-apo/Makefile
new file mode 100644
index 0000000000000000000000000000000000000000..a123f1fbfe048d437d4bb72ca92a83cdc13ac775
--- /dev/null
+++ b/seminaries/hello-apo/Makefile
@@ -0,0 +1,109 @@
+# Makefile to buidl example for different ISA targets
+# Select architecture by ARCH parameter
+#   native, x86, riscv, riscv64, mips, arm, aarch64
+
+# Specify source files of the program
+SOURCES = hello-apo.c
+
+# Specify base name of the executable - architecture
+TARGET_BASE = hello-apo
+
+# The actual target filename is unique for each architecture
+TARGET_EXE = $(TARGET_BASE)-$(ARCH)
+
+all: default
+
+.PHONY : all default build run dump clean
+
+ARCH_SUPPORTED = native x86 riscv riscv64 mips arm aarch64
+
+ifneq ($(MAKECMDGOALS),clean)
+ifeq ($(filter $(ARCH_SUPPORTED),$(ARCH)),)
+  $(error ARCH parameter has to be set accepted: x86, riscv, riscv64, mips and arm)
+endif
+endif
+
+# setting specific for riscv build for native build
+SOURCES-native +=
+LOADLIBES-native +=
+CC-native = gcc
+OBJDUMP-native = objdump
+ARCHFLAGS-native += -ggdb
+RUN-native =
+
+# setting specific for riscv build for native build
+SOURCES-x86 +=
+LOADLIBES-x86 +=
+CC-x86 = x86_64-linux-gnu-gcc
+OBJDUMP-x86 = x86_64-linux-gnu-objdump
+ARCHFLAGS-native += -static  -ggdb
+RUN-x86 = qemu-x86_64-static
+
+# setting specific for riscv build for QtRvSim simulator and or RISC-V Linux 32-bit run
+SOURCES-riscv += sys-qtrvsim/qtrvsim_sys_stub.c sys-qtrvsim/crt0local.S
+LOADLIBES-riscv += -lc -lgcc
+CC-riscv = riscv64-unknown-elf-gcc
+OBJDUMP-riscv = riscv64-unknown-elf-objdump
+ARCHFLAGS-riscv += -mabi=ilp32 -march=rv32im -fno-lto -nostartfiles -nostdlib -static -ggdb
+RUN-riscv = qemu-riscv32-static
+
+# setting specific for riscv64 build for QtRvSim simulator and or RISC-V Linux 64-bit run
+SOURCES-riscv64 += sys-qtrvsim/qtrvsim_sys_stub.c sys-qtrvsim/crt0local.S
+LOADLIBES-riscv64 += -lc -lgcc
+CC-riscv64 = riscv64-unknown-elf-gcc
+OBJDUMP-riscv64 = riscv64-unknown-elf-objdump
+ARCHFLAGS-riscv64 += -mabi=lp64 -march=rv64imac -fno-lto -nostartfiles -nostdlib -static -ggdb
+RUN-riscv64 = qemu-riscv64-static
+
+# setting specific for riscv64 build for QtMips simulator and or MIPS Linux run
+SOURCES-mips += sys-qtmips/qtmips_sys_stub.c sys-qtmips/crt0local.S
+LOADLIBES-mips += -lc -lgcc
+CC-mips = mips-elf-gcc
+OBJDUMP-mips = mips-elf-objdump
+ARCHFLAGS-mips += -march=mips32 -fno-lto -nostartfiles -nostdlib -static -ggdb
+RUN-mips = qemu-mips-static
+
+# setting specific for ARM 32-bit build
+SOURCES-arm +=
+LOADLIBES-arm +=
+CC-arm = arm-linux-gnueabihf-gcc
+OBJDUMP-arm = arm-linux-gnueabihf-objdump
+ARCHFLAGS-arm += -static -ggdb
+RUN-arm = qemu-arm-static
+
+# setting specific for ARM 64-bit build
+SOURCES-aarch64 +=
+LOADLIBES-aarch64 +=
+CC-aarch64 = aarch64-linux-gnu-gcc
+OBJDUMP-aarch64 = aarch64-linux-gnu-objdump
+ARCHFLAGS-aarch64 += -static -ggdb
+RUN-aarch64 = qemu-aarch64-static
+
+define compile_one_src
+src := $(1)
+arch := $(2)
+obj := $$(basename $$(notdir $$(src)))-$$(arch).o
+$$(obj) : $$(src)
+	$$(CC-$$(arch)) $$(ARCHFLAGS-$$(arch)) -c $$< -o $$@
+OBJS-$$(arch) := $$(OBJS-$$(arch)) $$(obj)
+#$$(warning $$(src) $$(obj) $$(arch) $$(OBJS-$$(arch)))
+endef
+
+$(foreach srci, $(SOURCES) $(SOURCES-$(ARCH)),$(eval $(call compile_one_src, $(srci), $(ARCH))))
+
+$(TARGET_EXE) : $(OBJS-$(ARCH))
+	$(CC-$(ARCH)) -o $@ $^ $(ARCHFLAGS-$(ARCH)) $(LOADLIBES-$(ARCH))
+
+build : $(TARGET_EXE)
+
+run : $(TARGET_EXE)
+	$(RUN-$(ARCH)) ./$<
+
+dump: $(TARGET_EXE)
+	$(OBJDUMP-$(ARCH)) --source $< > $<.dump
+	cat $<.dump
+
+clean :
+	rm -f $(OBJS-$(ARCH)) $(foreach arch,$(ARCH_SUPPORTED),$(TARGET_BASE)-$(arch)) *.o *.dump
+
+default : build
\ No newline at end of file
diff --git a/seminaries/hello-apo/hello-apo.c b/seminaries/hello-apo/hello-apo.c
new file mode 100644
index 0000000000000000000000000000000000000000..b6197a548067d21239bafdfe27f4b167d9bc4134
--- /dev/null
+++ b/seminaries/hello-apo/hello-apo.c
@@ -0,0 +1,25 @@
+/* Hello world example to demonstrate on multiple architectures */
+
+/*
+ * compile, run and examine for different instruction set architectures
+ * build by make command where ARCH is chisen as one of
+ *   native, x86, riscv, riscv64, mips, arm or aarch64
+ *   make ARCH=riscv
+ */
+
+#include <stdio.h>
+
+//int var_a = 40;
+//int var_b =  2;
+
+int main(int argc, char *argv[])
+{
+
+  /*
+   * modify program to compute and print answer
+   * of var_a + var_b
+   */
+  printf("Hello APO\n");
+
+  return 0;
+}
diff --git a/seminaries/hello-apo/sys-qtmips/crt0local.S b/seminaries/hello-apo/sys-qtmips/crt0local.S
new file mode 100644
index 0000000000000000000000000000000000000000..1931e765e4915b95bee4ee22ca4096795f2700e9
--- /dev/null
+++ b/seminaries/hello-apo/sys-qtmips/crt0local.S
@@ -0,0 +1,47 @@
+/* minimal replacement of crt0.o which is else provided by C library */
+
+.globl main
+.globl _start
+.globl __start
+.globl _heap_stack_start
+.globl _heap_stack_end
+.set noat
+.set noreorder
+.ent _start
+
+.text
+
+__start:
+_start:
+#if defined(__PIC__) || defined(__pic__)
+	bal     next
+	nop
+next:
+	.set    noreorder
+	.cpload $31
+	.set    reorder
+#else
+	la      $gp, _gp
+#endif
+	la      $sp, _heap_stack_end
+	addi    $a0, $zero, 0
+	addi    $a1, $zero, 0
+	jal     main
+	nop
+quit:
+	addi    $a0, $zero, 0
+	addi    $v0, $zero, 4001  /* SYS_exit */
+
+	syscall
+
+loop:	break
+	beq     $zero, $zero, loop
+	nop
+
+.end _start
+
+.bss
+
+_heap_stack_start:
+	.skip  0x800000
+_heap_stack_end:
diff --git a/seminaries/hello-apo/sys-qtmips/qtmips_sys_stub.c b/seminaries/hello-apo/sys-qtmips/qtmips_sys_stub.c
new file mode 100644
index 0000000000000000000000000000000000000000..119f5d3613816ba5783a82766f3e4a7b78e4efd8
--- /dev/null
+++ b/seminaries/hello-apo/sys-qtmips/qtmips_sys_stub.c
@@ -0,0 +1,436 @@
+/* Support files for GNU libc.  Files in the system namespace go here.
+   Files in the C namespace (ie those that do not start with an
+   underscore) go in .c.  */
+
+#include <sys/types.h>
+#include <sys/stat.h>
+#include <sys/fcntl.h>
+#include <stdio.h>
+#include <stdarg.h>
+#include <time.h>
+#include <sys/time.h>
+#include <sys/times.h>
+#include <errno.h>
+#include <reent.h>
+#include "qtmips_unistd.h"
+
+#define UNUSED_PARAM(symbol) ((void)(symbol))
+
+/* Register name - works in collusion with the linker.  */
+register char * stack_ptr asm ("sp");
+
+
+int _read(int file, char *ptr, int len);
+int
+_read (int file,
+       char * ptr,
+       int len)
+{
+	register int __v0 asm("$v0") = __NR_read;
+	register int __a0 asm("$a0") = file;
+	register char * __a1 asm("$a1") = ptr;
+	register int __a2 asm("$a2") = len;
+	register int __a3 asm("$a3");
+	__asm__ volatile (
+	".set\tnoreorder\n\t"
+	"syscall\n\t"
+	".set reorder"
+	: "=r" (__v0), "=r" (__a3)
+	: "r" (__v0), "r" (__a0), "r" (__a1), "r"(__a2)
+	: );
+	return __a3? -1: __v0;
+}
+
+int _write(int file, const char *ptr, int len);
+int
+_write (int    file,
+	const char * ptr,
+	int    len)
+{
+	register int __v0 asm("$v0") = __NR_write;
+	register int __a0 asm("$a0") = file;
+	register const char * __a1 asm("$a1") = ptr;
+	register int __a2 asm("$a2") = len;
+	register int __a3 asm("$a3");
+	__asm__ volatile (
+	".set\tnoreorder\n\t"
+	"syscall\n\t"
+	".set reorder"
+	: "=r" (__v0), "=r" (__a3)
+	: "r" (__v0), "r" (__a0), "r" (__a1), "r"(__a2)
+	: );
+	return __a3? -1: __v0;
+}
+
+
+int
+_lseek (int file,
+	int pos,
+	int dir)
+{
+	UNUSED_PARAM(file);
+	UNUSED_PARAM(pos);
+	UNUSED_PARAM(dir);
+
+	return -1;
+}
+
+int _open(const char *path, int flags,	...);
+int
+_open (const char * path,
+       int          flags,
+       ...)
+{
+	register int __v0 asm("$v0") = __NR_open;
+	register const char * __a0 asm("$a0") = path;
+	register int __a1 asm("$a1") = flags;
+	register int __a2 asm("$a2") = 0;
+	register int __a3 asm("$a3");
+
+	if (flags & O_CREAT) {
+		va_list list;
+		va_start(list, flags);
+		__a2 = va_arg(list, int);
+		va_end(list);
+	}
+
+	__asm__ volatile (
+	".set\tnoreorder\n\t"
+	"syscall\n\t"
+	".set reorder"
+	: "=r" (__v0), "=r" (__a3)
+	: "r" (__v0), "r" (__a0), "r" (__a1), "r"(__a2)
+	: );
+	return __a3? -1: __v0;
+}
+
+int _close(int file);
+int
+_close (int file)
+{
+	register int __v0 asm("$v0") = __NR_close;
+	register int __a0 asm("$a0") = file;
+	register int __a3 asm("$a3");
+	__asm__ volatile (
+	".set\tnoreorder\n\t"
+	"syscall\n\t"
+	".set reorder"
+	: "=r" (__v0), "=r" (__a3)
+	: "r" (__v0), "r" (__a0)
+	: );
+	return __a3? -1: __v0;
+}
+
+void _exit(int n);
+void
+_exit (int n)
+{
+	register int __v0 asm("$v0") = __NR_exit;
+	register int __a0 asm("$a0") = n;
+
+	while(1) __asm__ volatile (
+	".set\tnoreorder\n\t"
+	"syscall\n\t"
+	".set reorder"
+	:
+	: "r" (__v0), "r" (__a0)
+	: "a3");
+}
+
+void abort(void);
+void abort(void)
+{
+	while(1) __asm__ volatile (
+	".set\tnoreorder\n\t"
+	"break\n\t"
+	".set reorder"
+	:
+	:
+	: );
+}
+
+int _kill(int n, int m);
+int
+_kill (int n, int m)
+{
+  UNUSED_PARAM(n);
+  UNUSED_PARAM(m);
+  return -1;
+}
+
+int _getpid(void);
+int
+_getpid (void)
+{
+  return 1;
+}
+
+
+void *_sbrk(ptrdiff_t incr);
+void *
+_sbrk (ptrdiff_t incr)
+{
+  extern char    _heap_stack_start;
+  static char   *heap_end;
+  char *        prev_heap_end;
+
+  incr=(incr+3) & ~3;
+
+  if (heap_end == NULL)
+    heap_end = & _heap_stack_start;
+
+  prev_heap_end = heap_end;
+
+  if ((heap_end + incr > stack_ptr) && (&_heap_stack_start < stack_ptr))
+    {
+      /* Some of the libstdc++-v3 tests rely upon detecting
+	 out of memory errors, so do not abort here.  */
+#if 1
+      extern void abort (void);
+
+      _write (1, "_sbrk: Heap and stack collision\n", 32);
+
+      abort ();
+#else
+      errno = ENOMEM;
+      return (caddr_t) -1;
+#endif
+    }
+
+  heap_end += incr;
+
+  return /*(caddr_t)*/ prev_heap_end;
+}
+
+int _fstat(int file, struct stat *st);
+int
+_fstat (int file, struct stat * st)
+{
+  UNUSED_PARAM(file);
+  UNUSED_PARAM(st);
+  return -1;
+}
+
+int _stat (const char *fname, struct stat *st);
+int _stat (const char *fname, struct stat *st)
+{
+  UNUSED_PARAM(fname);
+  UNUSED_PARAM(st);
+  return -1;
+}
+
+int _link(const char *path1, const char *path2);
+int
+_link (const char *path1,
+       const char *path2)
+{
+  UNUSED_PARAM(path1);
+  UNUSED_PARAM(path2);
+  return -1;
+}
+
+int _unlink(const char *path);
+int
+_unlink (const char *path)
+{
+  UNUSED_PARAM(path);
+  return -1;
+}
+
+void _raise(void);
+void
+_raise (void)
+{
+  return;
+}
+
+int _gettimeofday(struct timeval *tp, struct timezone *tzp);
+int
+_gettimeofday (struct timeval *tp,
+	       struct timezone *tzp)
+{
+
+  if(tp)
+    {
+      tp->tv_sec = 0;
+      tp->tv_usec = 0;
+    }
+  /* Return fixed data for the timezone.  */
+  if (tzp)
+    {
+      tzp->tz_minuteswest = 0;
+      tzp->tz_dsttime = 0;
+    }
+
+  return 0;
+}
+
+/* Return a clock that ticks at 100Hz.  */
+clock_t _times(struct tms *tp);
+clock_t
+_times (struct tms * tp)
+{
+  clock_t timeval = 0;
+
+  if (tp)
+    {
+      tp->tms_utime  = timeval;	/* user time */
+      tp->tms_stime  = 0;	/* system time */
+      tp->tms_cutime = 0;	/* user time, children */
+      tp->tms_cstime = 0;	/* system time, children */
+    }
+
+  return timeval;
+};
+
+
+int isatty(int fd);
+int
+isatty (int fd)
+{
+  UNUSED_PARAM(fd);
+  return 1;
+}
+
+int _system(const char *s);
+int
+_system (const char *s)
+{
+  UNUSED_PARAM(s);
+  return -1;
+}
+
+int _rename(const char *oldpath, const char *newpath);
+int
+_rename (const char * oldpath, const char * newpath)
+{
+  UNUSED_PARAM(oldpath);
+  UNUSED_PARAM(newpath);
+  return -1;
+}
+
+/* extern (.*) ([^ ]*) _PARAMS \(\(struct _reent \*(,*)(.*)\)\); */
+/* \1 \2 (struct _reent *\3\4) { return \2(\4);} */
+
+struct _reent;
+
+int _close_r(struct _reent *reent, int file)
+{ UNUSED_PARAM(reent); return _close(file);}
+/*
+  int _fcntl_r(struct _reent *, int, int, int)
+  { return _fcntl( int, int, int);}
+*/
+int _fstat_r(struct _reent *reent, int file, struct stat *st);
+int _fstat_r(struct _reent *reent, int file, struct stat *st)
+{ UNUSED_PARAM(reent); return _fstat(file, st);}
+
+int _getpid_r(struct _reent *reent);
+int _getpid_r(struct _reent *reent)
+{ UNUSED_PARAM(reent); return _getpid();}
+
+int _kill_r(struct _reent *reent, int n, int m);
+int _kill_r(struct _reent *reent, int n, int m)
+{ UNUSED_PARAM(reent); return _kill(n, m);}
+
+int _link_r(struct _reent *reent, const char *path1, const char *path2);
+int _link_r(struct _reent *reent, const char *path1, const char *path2)
+{ UNUSED_PARAM(reent); return _link(path1, path2);}
+
+_off_t _lseek_r(struct _reent *reent, int file, _off_t pos, int dir);
+_off_t _lseek_r(struct _reent *reent, int file, _off_t pos, int dir)
+{ UNUSED_PARAM(reent); return _lseek(file, pos, dir);}
+
+int _open_r(struct _reent *reent, const char *path, int flags, int opts);
+int _open_r(struct _reent *reent, const char *path, int flags, int opts)
+{ UNUSED_PARAM(reent); return _open(path, flags, opts);}
+
+_ssize_t _read_r(struct _reent *reent, int file, void *ptr, size_t len);
+_ssize_t _read_r(struct _reent *reent, int file, void *ptr, size_t len)
+{ UNUSED_PARAM(reent); return _read(file, ptr, len);}
+
+void *_sbrk_r(struct _reent *reent, ptrdiff_t incr);
+void *_sbrk_r(struct _reent *reent, ptrdiff_t incr)
+{ UNUSED_PARAM(reent); return _sbrk(incr);}
+
+int _stat_r(struct _reent *reent, const char *path, struct stat *st);
+int _stat_r(struct _reent *reent, const char *path, struct stat *st)
+{ UNUSED_PARAM(reent); return _stat(path, st);}
+
+int _unlink_r(struct _reent *reent, const char *path);
+int _unlink_r(struct _reent *reent, const char *path)
+{ UNUSED_PARAM(reent); return _unlink(path);}
+
+_ssize_t _write_r(struct _reent *reent, int file, const void *ptr, size_t len);
+_ssize_t _write_r(struct _reent *reent, int file, const void *ptr, size_t len)
+{ UNUSED_PARAM(reent); return _write(file, ptr, len);}
+
+/* FIXME: TDK added dummy functions. Need to implement. */
+int _isatty(int fd);
+int _isatty(int fd)
+{
+  UNUSED_PARAM(fd);
+  return -1;
+}
+
+int _swistat(int fd, struct stat *st);
+int _swistat(int fd, struct stat *st)
+{
+  UNUSED_PARAM(fd);
+  UNUSED_PARAM(st);
+  return -1;
+}
+
+/* Return a clock that ticks at 100Hz.  */
+clock_t _clock(void);
+clock_t _clock(void)
+{
+  clock_t timeval=0;
+  return timeval;
+}
+
+int _swiclose(int fh);
+int _swiclose(int fh)
+{
+  UNUSED_PARAM(fh);
+  return -1;
+}
+
+int _swiopen(const char *path, int flags);
+int _swiopen(const char *path, int flags)
+{
+  UNUSED_PARAM(path);
+  UNUSED_PARAM(flags);
+  return -1;
+}
+
+int _swiwrite(int fh, char *ptr, int len);
+int _swiwrite(int fh, char *ptr, int len)
+{
+  UNUSED_PARAM(fh);
+  UNUSED_PARAM(ptr);
+  UNUSED_PARAM(len);
+  return -1;
+}
+
+int _swilseek(int fd, int ptr, int dir);
+int _swilseek(int fd, int ptr, int dir)
+{
+  UNUSED_PARAM(fd);
+  UNUSED_PARAM(ptr);
+  UNUSED_PARAM(dir);
+  return -1;
+}
+
+int _swiread(int fh, char *ptr,	int len);
+int _swiread(int fh, char *ptr,	int len)
+{
+  UNUSED_PARAM(fh);
+  UNUSED_PARAM(ptr);
+  UNUSED_PARAM(len);
+  return -1;
+}
+
+void initialise_monitor_handles(void);
+void initialise_monitor_handles(void)
+{
+}
diff --git a/seminaries/hello-apo/sys-qtmips/qtmips_unistd.h b/seminaries/hello-apo/sys-qtmips/qtmips_unistd.h
new file mode 100644
index 0000000000000000000000000000000000000000..e1a686967c708635189ed60a4f7bee8252a9d211
--- /dev/null
+++ b/seminaries/hello-apo/sys-qtmips/qtmips_unistd.h
@@ -0,0 +1,29 @@
+// ******************************************************************
+//  QtMips emulator https://github.com/cvut/QtMips support filees
+//
+//  qtmips_unistd.h  - definition of the QtMips syscall numbers
+//
+//  (C) Copyright 2019 - 2020 by Pavel Pisa
+//      e-mail:   pisa@cmp.felk.cvut.cz
+//      homepage: http://cmp.felk.cvut.cz/~pisa
+//      license:  any combination of GPL, LGPL, MPL or BSD licenses
+//
+// ******************************************************************
+
+#ifndef QTMIPS_UNISTD_H
+#define QTMIPS_UNISTD_H
+
+// Linux kernel compatible system calls subset
+
+#define __NR_exit     4001	// void exit(int status)
+#define __NR_read     4003	// ssize_t read(int fd, void *buf, size_t count)
+#define __NR_write    4004	// ssize_t write(int fd, const void *buf, size_t count)
+#define __NR_close    4006	// int close(int fd)
+#define __NR_open     4005	// int open(const char *pathname, int flags, mode_t mode)
+#define __NR_brk      4045	// void * brk(void *addr)
+#define __NR_truncate 4092	// int ftruncate(int fd, off_t length)
+#define __NR_readv    4145	// ssize_t readv(int fd, const struct iovec *iov, int iovcnt)
+#define __NR_writev   4146	// ssize_t writev(int fd, const struct iovec *iov, int iovcnt)
+#define __NR_set_thread_area 4283 // int set_thread_area(unsigned long addr)
+
+#endif /*QTMIPS_UNISTD_H*/
diff --git a/seminaries/hello-apo/sys-qtrvsim/crt0local.S b/seminaries/hello-apo/sys-qtrvsim/crt0local.S
new file mode 100644
index 0000000000000000000000000000000000000000..20017869ebfd71380908cd2aea560595e8d9b698
--- /dev/null
+++ b/seminaries/hello-apo/sys-qtrvsim/crt0local.S
@@ -0,0 +1,37 @@
+/* minimal replacement of crt0.o which is else provided by C library */
+
+.globl main
+.globl _start
+.globl __start
+.globl _heap_stack_start
+.globl _heap_stack_end
+
+.option norelax
+
+.text
+
+__start:
+_start:
+	.option push
+	.option norelax
+	la gp, __global_pointer$
+	.option pop
+	la      sp, _heap_stack_end
+	addi    a0, zero, 0
+	addi    a1, zero, 0
+	jal     main
+quit:
+	addi    a0, zero, 0
+	addi    a7, zero, 93  /* SYS_exit */
+	ecall
+
+loop:	ebreak
+        beq     zero, zero, loop
+
+.bss
+
+_heap_stack_start:
+	.skip   16384
+_heap_stack_end:
+
+.end _start
diff --git a/seminaries/hello-apo/sys-qtrvsim/qtrvsim_sys_stub.c b/seminaries/hello-apo/sys-qtrvsim/qtrvsim_sys_stub.c
new file mode 100644
index 0000000000000000000000000000000000000000..e56603e3a90ac37555e4c82e307ac4ffa9b749f4
--- /dev/null
+++ b/seminaries/hello-apo/sys-qtrvsim/qtrvsim_sys_stub.c
@@ -0,0 +1,502 @@
+/* Support files for GNU libc.  Files in the system namespace go here.
+   Files in the C namespace (ie those that do not start with an
+   underscore) go in .c.  */
+
+#include <sys/types.h>
+#include <sys/stat.h>
+#include <sys/fcntl.h>
+#include <stdio.h>
+#include <stdarg.h>
+#include <time.h>
+#include <sys/time.h>
+#include <sys/times.h>
+#include <errno.h>
+#include <reent.h>
+#include "qtrvsim_unistd.h"
+
+#define UNUSED_PARAM(symbol) ((void)(symbol))
+
+
+/* Open flags definition for Linux kernel copied from musl-libc */
+
+#define KERNEL_O_CREAT        0100
+#define KERNEL_O_EXCL         0200
+#define KERNEL_O_NOCTTY       0400
+#define KERNEL_O_TRUNC       01000
+#define KERNEL_O_APPEND      02000
+#define KERNEL_O_NONBLOCK    04000
+#define KERNEL_O_DSYNC      010000
+#define KERNEL_O_SYNC     04010000
+#define KERNEL_O_RSYNC    04010000
+#define KERNEL_O_DIRECTORY 0200000
+#define KERNEL_O_NOFOLLOW  0400000
+#define KERNEL_O_CLOEXEC  02000000
+
+#define KERNEL_O_PATH 010000000
+
+#define KERNEL_O_SYNC1 040000
+
+#define KERNEL_O_ACCMODE (03 | KERNEL_O_PATH)
+#define KERNEL_O_RDONLY 00
+#define KERNEL_O_WRONLY 01
+#define KERNEL_O_RDWR 02
+
+#define TARGET_AT_FDCWD -100
+
+/* Register name - works in collusion with the linker.  */
+register char * stack_ptr asm ("sp");
+
+
+int _read(int file, char *ptr, int len);
+int
+_read (int file,
+       char * ptr,
+       int len)
+{
+	register int __a7 asm("a7") = __NR_read;
+	register int __a0 asm("a0") = file;
+	register char * __a1 asm("a1") = ptr;
+	register int __a2 asm("a2") = len;
+	__asm__ volatile (
+	"ecall\n\t"
+	: "=r" (__a0)
+	: "r" (__a7), "r" (__a0), "r" (__a1), "r"(__a2)
+	: );
+	return __a0 < 0 ? -1: __a0;
+}
+
+int _write(int file, const char *ptr, int len);
+int
+_write (int    file,
+	const char * ptr,
+	int    len)
+{
+	register int __a7 asm("a7") = __NR_write;
+	register int __a0 asm("a0") = file;
+	register const char * __a1 asm("a1") = ptr;
+	register int __a2 asm("a2") = len;
+	__asm__ volatile (
+	"ecall\n\t"
+	: "=r" (__a0)
+	: "r" (__a7), "r" (__a0), "r" (__a1), "r"(__a2)
+	: );
+	return __a0 < 0 ? -1: __a0;
+}
+
+
+int
+_lseek (int file,
+	int pos,
+	int dir)
+{
+	UNUSED_PARAM(file);
+	UNUSED_PARAM(pos);
+	UNUSED_PARAM(dir);
+
+	return -1;
+}
+
+int _openat(int fd, const char *path, int flags,	...);
+int
+_openat (int fd, const char * path,
+       int          flags,
+       ...)
+{
+	register int __a7 asm("a7") = __NR_openat;
+	// use fd = -100 for normal open behaviour. Full openat not supported.
+	register int __a0 asm("a0") = fd;
+	register const char * __a1 asm("a1") = path;
+	register int __a2 asm("a2") = 0;
+	register int __a3 asm("a3");
+
+#ifdef O_CREAT
+	if (flags & O_CREAT)
+		__a2 |= KERNEL_O_CREAT;
+#endif
+#ifdef O_EXCL
+	if (flags & O_EXCL)
+		__a2 |= KERNEL_O_EXCL;
+#endif
+#ifdef O_NOCTTY
+	if (flags & O_NOCTTY)
+		__a2 |= KERNEL_O_NOCTTY;
+#endif
+#ifdef O_TRUNC
+	if (flags & O_TRUNC)
+		__a2 |= KERNEL_O_TRUNC;
+#endif
+#ifdef O_APPEND
+	if (flags & O_APPEND)
+		__a2 |= KERNEL_O_APPEND;
+#endif
+#ifdef O_NONBLOCK
+	if (flags & O_NONBLOCK)
+		__a2 |= KERNEL_O_NONBLOCK;
+#endif
+#ifdef O_DSYNC
+	if (flags & O_DSYNC)
+		__a2 |= KERNEL_O_DSYNC;
+#endif
+#ifdef O_SYNC
+	if (flags & O_SYNC)
+		__a2 |= KERNEL_O_SYNC;
+#endif
+#ifdef O_RSYNC
+	if (flags & O_RSYNC)
+		__a2 |= KERNEL_O_RSYNC;
+#endif
+#ifdef O_DIRECTORY
+	if (flags & O_DIRECTORY)
+		__a2 |= KERNEL_O_DIRECTORY;
+#endif
+#ifdef O_NOFOLLOW
+	if (flags & O_NOFOLLOW)
+		__a2 |= KERNEL_O_NOFOLLOW;
+#endif
+#ifdef O_CLOEXEC
+	if (flags & O_CLOEXEC)
+		__a2 |= KERNEL_O_CLOEXEC;
+#endif
+
+	if (flags & O_CREAT) {
+		va_list list;
+		va_start(list, flags);
+		__a3 = va_arg(list, int);
+		va_end(list);
+	}
+
+	__asm__ volatile (
+	"ecall\n\t"
+	: "=r" (__a0)
+	: "r" (__a7), "r" (__a0), "r" (__a1), "r"(__a2), "r"(__a3)
+	: );
+	return __a0 < 0 ? -1: __a0;
+}
+
+int _close(int file);
+int
+_close (int file)
+{
+	register int __a7 asm("a7") = __NR_close;
+	register int __a0 asm("a0") = file;
+	__asm__ volatile (
+	"ecall\n\t"
+	: "=r" (__a0)
+	: "r" (__a7), "r" (__a0)
+	: );
+	return __a0 < 0 ? -1: __a0;
+}
+
+void _exit(int n);
+void
+_exit (int n)
+{
+	register int __a7 asm("a7") = __NR_exit;
+	register int __a0 asm("a0") = n;
+
+	while(1) __asm__ volatile (
+	"ecall\n\t"
+	:
+	: "r" (__a7), "r" (__a0)
+	: );
+}
+
+void abort(void);
+void abort(void)
+{
+	while(1) __asm__ volatile (
+	"ebreak\n\t"
+	:
+	:
+	: );
+}
+
+int _kill(int n, int m);
+int
+_kill (int n, int m)
+{
+  UNUSED_PARAM(n);
+  UNUSED_PARAM(m);
+  return -1;
+}
+
+int _getpid(void);
+int
+_getpid (void)
+{
+  return 1;
+}
+
+
+void *_sbrk(ptrdiff_t incr);
+void *
+_sbrk (ptrdiff_t incr)
+{
+  extern char    _heap_stack_start;
+  static char   *heap_end;
+  char *        prev_heap_end;
+
+  incr=(incr+3) & ~3;
+
+  if (heap_end == NULL)
+    heap_end = & _heap_stack_start;
+
+  prev_heap_end = heap_end;
+
+  if ((heap_end + incr > stack_ptr) && (&_heap_stack_start < stack_ptr))
+    {
+      /* Some of the libstdc++-v3 tests rely upon detecting
+	 out of memory errors, so do not abort here.  */
+#if 1
+      extern void abort (void);
+
+      _write (1, "_sbrk: Heap and stack collision\n", 32);
+
+      abort ();
+#else
+      errno = ENOMEM;
+      return (caddr_t) -1;
+#endif
+    }
+
+  heap_end += incr;
+
+  return /*(caddr_t)*/ prev_heap_end;
+}
+
+int _fstat(int file, struct stat *st);
+int
+_fstat (int file, struct stat * st)
+{
+  UNUSED_PARAM(file);
+  UNUSED_PARAM(st);
+  return -1;
+}
+
+int _stat (const char *fname, struct stat *st);
+int _stat (const char *fname, struct stat *st)
+{
+  UNUSED_PARAM(fname);
+  UNUSED_PARAM(st);
+  return -1;
+}
+
+int _link(const char *path1, const char *path2);
+int
+_link (const char *path1,
+       const char *path2)
+{
+  UNUSED_PARAM(path1);
+  UNUSED_PARAM(path2);
+  return -1;
+}
+
+int _unlink(const char *path);
+int
+_unlink (const char *path)
+{
+  UNUSED_PARAM(path);
+  return -1;
+}
+
+void _raise(void);
+void
+_raise (void)
+{
+  return;
+}
+
+int _gettimeofday(struct timeval *tp, struct timezone *tzp);
+int
+_gettimeofday (struct timeval *tp,
+	       struct timezone *tzp)
+{
+
+  if(tp)
+    {
+      tp->tv_sec = 0;
+      tp->tv_usec = 0;
+    }
+  /* Return fixed data for the timezone.  */
+  if (tzp)
+    {
+      tzp->tz_minuteswest = 0;
+      tzp->tz_dsttime = 0;
+    }
+
+  return 0;
+}
+
+/* Return a clock that ticks at 100Hz.  */
+clock_t _times(struct tms *tp);
+clock_t
+_times (struct tms * tp)
+{
+  clock_t timeval = 0;
+
+  if (tp)
+    {
+      tp->tms_utime  = timeval;	/* user time */
+      tp->tms_stime  = 0;	/* system time */
+      tp->tms_cutime = 0;	/* user time, children */
+      tp->tms_cstime = 0;	/* system time, children */
+    }
+
+  return timeval;
+};
+
+
+int isatty(int fd);
+int
+isatty (int fd)
+{
+  UNUSED_PARAM(fd);
+  return 1;
+}
+
+int _system(const char *s);
+int
+_system (const char *s)
+{
+  UNUSED_PARAM(s);
+  return -1;
+}
+
+int _rename(const char *oldpath, const char *newpath);
+int
+_rename (const char * oldpath, const char * newpath)
+{
+  UNUSED_PARAM(oldpath);
+  UNUSED_PARAM(newpath);
+  return -1;
+}
+
+/* extern (.*) ([^ ]*) _PARAMS \(\(struct _reent \*(,*)(.*)\)\); */
+/* \1 \2 (struct _reent *\3\4) { return \2(\4);} */
+
+struct _reent;
+
+int _close_r(struct _reent *reent, int file)
+{ UNUSED_PARAM(reent); return _close(file);}
+/*
+  int _fcntl_r(struct _reent *, int, int, int)
+  { return _fcntl( int, int, int);}
+*/
+int _fstat_r(struct _reent *reent, int file, struct stat *st);
+int _fstat_r(struct _reent *reent, int file, struct stat *st)
+{ UNUSED_PARAM(reent); return _fstat(file, st);}
+
+int _getpid_r(struct _reent *reent);
+int _getpid_r(struct _reent *reent)
+{ UNUSED_PARAM(reent); return _getpid();}
+
+int _kill_r(struct _reent *reent, int n, int m);
+int _kill_r(struct _reent *reent, int n, int m)
+{ UNUSED_PARAM(reent); return _kill(n, m);}
+
+int _link_r(struct _reent *reent, const char *path1, const char *path2);
+int _link_r(struct _reent *reent, const char *path1, const char *path2)
+{ UNUSED_PARAM(reent); return _link(path1, path2);}
+
+_off_t _lseek_r(struct _reent *reent, int file, _off_t pos, int dir);
+_off_t _lseek_r(struct _reent *reent, int file, _off_t pos, int dir)
+{ UNUSED_PARAM(reent); return _lseek(file, pos, dir);}
+
+int _open_r(struct _reent *reent, const char *path, int flags, int opts);
+int _open_r(struct _reent *reent, const char *path, int flags, int opts)
+{ UNUSED_PARAM(reent); return _openat(TARGET_AT_FDCWD, path, flags, opts);}
+
+int _openat_r(struct _reent *reent, int fd, const char *path, int flags, int opts);
+int _openat_r(struct _reent *reent, int fd, const char *path, int flags, int opts)
+{ UNUSED_PARAM(reent); return _openat(fd, path, flags, opts);}
+
+_ssize_t _read_r(struct _reent *reent, int file, void *ptr, size_t len);
+_ssize_t _read_r(struct _reent *reent, int file, void *ptr, size_t len)
+{ UNUSED_PARAM(reent); return _read(file, ptr, len);}
+
+void *_sbrk_r(struct _reent *reent, ptrdiff_t incr);
+void *_sbrk_r(struct _reent *reent, ptrdiff_t incr)
+{ UNUSED_PARAM(reent); return _sbrk(incr);}
+
+int _stat_r(struct _reent *reent, const char *path, struct stat *st);
+int _stat_r(struct _reent *reent, const char *path, struct stat *st)
+{ UNUSED_PARAM(reent); return _stat(path, st);}
+
+int _unlink_r(struct _reent *reent, const char *path);
+int _unlink_r(struct _reent *reent, const char *path)
+{ UNUSED_PARAM(reent); return _unlink(path);}
+
+_ssize_t _write_r(struct _reent *reent, int file, const void *ptr, size_t len);
+_ssize_t _write_r(struct _reent *reent, int file, const void *ptr, size_t len)
+{ UNUSED_PARAM(reent); return _write(file, ptr, len);}
+
+/* FIXME: TDK added dummy functions. Need to implement. */
+int _isatty(int fd);
+int _isatty(int fd)
+{
+  UNUSED_PARAM(fd);
+  return -1;
+}
+
+int _swistat(int fd, struct stat *st);
+int _swistat(int fd, struct stat *st)
+{
+  UNUSED_PARAM(fd);
+  UNUSED_PARAM(st);
+  return -1;
+}
+
+/* Return a clock that ticks at 100Hz.  */
+clock_t _clock(void);
+clock_t _clock(void)
+{
+  clock_t timeval=0;
+  return timeval;
+}
+
+int _swiclose(int fh);
+int _swiclose(int fh)
+{
+  UNUSED_PARAM(fh);
+  return -1;
+}
+
+int _swiopen(const char *path, int flags);
+int _swiopen(const char *path, int flags)
+{
+  UNUSED_PARAM(path);
+  UNUSED_PARAM(flags);
+  return -1;
+}
+
+int _swiwrite(int fh, char *ptr, int len);
+int _swiwrite(int fh, char *ptr, int len)
+{
+  UNUSED_PARAM(fh);
+  UNUSED_PARAM(ptr);
+  UNUSED_PARAM(len);
+  return -1;
+}
+
+int _swilseek(int fd, int ptr, int dir);
+int _swilseek(int fd, int ptr, int dir)
+{
+  UNUSED_PARAM(fd);
+  UNUSED_PARAM(ptr);
+  UNUSED_PARAM(dir);
+  return -1;
+}
+
+int _swiread(int fh, char *ptr,	int len);
+int _swiread(int fh, char *ptr,	int len)
+{
+  UNUSED_PARAM(fh);
+  UNUSED_PARAM(ptr);
+  UNUSED_PARAM(len);
+  return -1;
+}
+
+void initialise_monitor_handles(void);
+void initialise_monitor_handles(void)
+{
+}
diff --git a/seminaries/hello-apo/sys-qtrvsim/qtrvsim_unistd.h b/seminaries/hello-apo/sys-qtrvsim/qtrvsim_unistd.h
new file mode 100644
index 0000000000000000000000000000000000000000..219d676f13d3b58ab04ddd2c005dced918a07de3
--- /dev/null
+++ b/seminaries/hello-apo/sys-qtrvsim/qtrvsim_unistd.h
@@ -0,0 +1,29 @@
+// ******************************************************************
+//  QtRvSim emulator https://github.com/cvut/qtrvsim support filees
+//
+//  qtrvsim_unistd.h  - definition of the QtRvSim syscall numbers
+//
+//  (C) Copyright 2019 - 2022 by Pavel Pisa
+//      e-mail:   pisa@cmp.felk.cvut.cz
+//      homepage: http://cmp.felk.cvut.cz/~pisa
+//      license:  any combination of GPL, LGPL, MPL or BSD licenses
+//
+// ******************************************************************
+
+#ifndef QTRVSIM_UNISTD_H
+#define QTRVSIM_UNISTD_H
+
+// Linux kernel compatible system calls subset
+
+#define __NR_exit         93  // void exit(int status)
+#define __NR_read         63  // ssize_t read(int fd, void *buf, size_t count)
+#define __NR_write        64  // ssize_t write(int fd, const void *buf, size_t count)
+#define __NR_close        57  // int close(int fd)
+#define __NR_openat       56  // int openat(int fd, const char *pathname, int flags, mode_t mode)
+        // use fd = -100 for normal open behaviour. Full openat not supported.
+#define __NR_brk         214 // void * brk(void *addr)
+#define __NR_ftruncate64  46  // int ftruncate64(int fd, off_t length)
+#define __NR_readv        65  // ssize_t readv(int fd, const struct iovec *iov, int iovcnt)
+#define __NR_writev       66  // ssize_t writev(int fd, const struct iovec *iov, int iovcnt)
+
+#endif /*QTRVSIM_UNISTD_H*/