From e8cc5155d9fb86a5e14717cc138f3b39314c821e Mon Sep 17 00:00:00 2001
From: Pavel Pisa <pisa@cmp.felk.cvut.cz>
Date: Mon, 27 Apr 2020 10:23:23 +0200
Subject: [PATCH] seminaries/qtmips/qtmips/uart-calc-add: task to receive two
 decimal numbers from UART and send sum in decimal to the UART.

Implement receive, add and print functions and place C language source
file on path

  work/uart-calc-add/uart-calc-add.c

To run the code in qtmips_cli, the serial port to file redirection
is required. Commit

      qtmips_cli: add option to connect serial port input and output to file.
      https://github.com/cvut/QtMips/commit/597c9271608c3d30ce193b96be3fe82966e4cc1d

qtmips_gui implement required functionality for lonag time already.

Signed-off-by: Pavel Pisa <pisa@cmp.felk.cvut.cz>
---
 seminaries/qtmips/uart-calc-add/.gitignore    |   6 +
 seminaries/qtmips/uart-calc-add/Makefile      |  92 ++++++++++++
 seminaries/qtmips/uart-calc-add/crt0local.S   |  38 +++++
 .../uart-calc-add/uart-calc-add-template.c    | 138 ++++++++++++++++++
 4 files changed, 274 insertions(+)
 create mode 100644 seminaries/qtmips/uart-calc-add/.gitignore
 create mode 100644 seminaries/qtmips/uart-calc-add/Makefile
 create mode 100644 seminaries/qtmips/uart-calc-add/crt0local.S
 create mode 100644 seminaries/qtmips/uart-calc-add/uart-calc-add-template.c

diff --git a/seminaries/qtmips/uart-calc-add/.gitignore b/seminaries/qtmips/uart-calc-add/.gitignore
new file mode 100644
index 0000000..ae1a51c
--- /dev/null
+++ b/seminaries/qtmips/uart-calc-add/.gitignore
@@ -0,0 +1,6 @@
+*.o
+depend
+uart-calc-add
+serial_port.in
+serial_port.ref
+serial_port.out
diff --git a/seminaries/qtmips/uart-calc-add/Makefile b/seminaries/qtmips/uart-calc-add/Makefile
new file mode 100644
index 0000000..51591ef
--- /dev/null
+++ b/seminaries/qtmips/uart-calc-add/Makefile
@@ -0,0 +1,92 @@
+ARCH=mips-elf
+#ARCH=mips-linux-gnu
+
+SOURCES = uart-calc-add.c crt0local.S
+TARGET_EXE = uart-calc-add
+
+CC=$(ARCH)-gcc
+CXX=$(ARCH)-g++
+AS=$(ARCH)-as
+LD=$(ARCH)-ld
+OBJCOPY=$(ARCH)-objcopy
+
+ARCHFLAGS += -march=mips32
+#ARCHFLAGS += -fno-lto
+#ARCHFLAGS += -mno-shared
+
+CFLAGS  += -ggdb -Os -Wall
+CXXFLAGS+= -ggdb -Os -Wall
+AFLAGS  += -ggdb
+LDFLAGS += -ggdb
+LDFLAGS += -nostartfiles
+LDFLAGS += -static
+#LDFLAGS += -specs=/opt/musl/mips-linux-gnu/lib/musl-gcc.specs
+
+CFLAGS  += $(ARCHFLAGS)
+CXXFLAGS+= $(ARCHFLAGS)
+AFLAGS  += $(ARCHFLAGS)
+LDFLAGS += $(ARCHFLAGS)
+
+OBJECTS += $(filter %.o,$(SOURCES:%.S=%.o))
+OBJECTS += $(filter %.o,$(SOURCES:%.c=%.o))
+OBJECTS += $(filter %.o,$(SOURCES:%.cpp=%.o))
+
+all : default
+
+.PHONY : default clean dep all run_test
+
+%.o:%.S
+	$(CC) -D__ASSEMBLY__ $(AFLAGS) -c $< -o $@
+
+%.o:%.c
+	$(CC) $(CFLAGS) $(CPPFLAGS) -c $< -o $@
+
+%.o:%.cpp
+	$(CXX) $(CXXFLAGS) $(CPPFLAGS) -c $<
+
+%.s:%.c
+	$(CC) $(CFLAGS) $(CPPFLAGS) -S $< -o $@
+
+#default : $(TARGET_EXE)
+default : run_test
+
+$(TARGET_EXE) : $(OBJECTS)
+	$(CC) $(LDFLAGS) $^ -o $@
+
+dep: depend
+
+depend: $(SOURCES) $(glob *.h)
+	echo '# autogenerated dependencies' > depend
+ifneq ($(filter %.S,$(SOURCES)),)
+	$(CC)  -D__ASSEMBLY__ $(AFLAGS) -w -E -M $(filter %.S,$(SOURCES)) \
+	  >> depend
+endif
+ifneq ($(filter %.c,$(SOURCES)),)
+	$(CC) $(CFLAGS) $(CPPFLAGS) -w -E -M $(filter %.c,$(SOURCES)) \
+	  >> depend
+endif
+ifneq ($(filter %.cpp,$(SOURCES)),)
+	$(CXX) $(CXXFLAGS) $(CPPFLAGS) -w -E -M $(filter %.cpp,$(SOURCES)) \
+	  >> depend
+endif
+
+clean:
+	rm -f *.o *.a $(OBJECTS) $(TARGET_EXE) depend input_val.in \
+		serial_port.ref serial_port.out
+
+#mips-elf-objdump --source -M no-aliases,reg-names=numeric qtmips_binrep
+
+input_val1:=$(shell echo $$RANDOM)
+input_val2:=$(shell echo $$RANDOM)
+
+run_test: $(TARGET_EXE)
+	echo $(input_val1) >serial_port.in
+	echo $(input_val2) >>serial_port.in
+	echo "$(input_val1) + $(input_val2)" | bc >serial_port.ref 
+	qtmips_cli --pipelined \
+		--dump-cycles $< \
+		--serin serial_port.in \
+		--serout serial_port.out
+	diff -u serial_port.ref serial_port.out
+
+-include depend
diff --git a/seminaries/qtmips/uart-calc-add/crt0local.S b/seminaries/qtmips/uart-calc-add/crt0local.S
new file mode 100644
index 0000000..c0fc838
--- /dev/null
+++ b/seminaries/qtmips/uart-calc-add/crt0local.S
@@ -0,0 +1,38 @@
+/* minimal replacement of crt0.o which is else provided by C library */
+
+.globl main
+.globl _start
+.globl __start
+.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
+	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
diff --git a/seminaries/qtmips/uart-calc-add/uart-calc-add-template.c b/seminaries/qtmips/uart-calc-add/uart-calc-add-template.c
new file mode 100644
index 0000000..3713227
--- /dev/null
+++ b/seminaries/qtmips/uart-calc-add/uart-calc-add-template.c
@@ -0,0 +1,138 @@
+/*******************************************************************
+uart-calc-add.c
+
+Template for simple task of serial minimal calculator (add operation
+only for now) which receives two decimal unsigned numbers from serial
+input (each terminated by new line) and prints sum of these two to
+serial output terminated by single newline character. 
+
+The mips-elf-gcc compiler is required to build the code
+  https://cw.fel.cvut.cz/wiki/courses/b35apo/documentation/mips-elf-gnu/start
+
+The included Makefile can be used to build the project and run it
+in the qtmips_cli simulator variant. To run ELF binary in qtmips_gui
+use make to compile binary or run on command line
+  mips-elf-gcc -ggdb -nostartfiles -nostdlib -static -march=mips32 crt0local.S uart-calc-add.c -o uart-calc-add
+
+Place file on path work/uart-calc-add/uart-calc-add.c in your
+subject personal GIT repository.
+
+Licence: Public Domain
+ *******************************************************************/
+
+#define _POSIX_C_SOURCE 200112L
+
+#include <stdint.h>
+
+/*
+ * Next macros provides location of knobs and LEDs peripherals
+ * implemented on QtMips simulator.
+ *
+ * More information can be found on page
+ *   https://github.com/ppisa/QtMips
+ */
+
+
+/*
+ * Base address of the region where simple serial port (UART)
+ * implementation is mapped in emulated MIPS address space
+ */
+#define SERIAL_PORT_BASE   0xffffc000
+
+/*
+ * Byte offset of the 32-bit receive status register
+ * of the serial port
+ */
+#define SERP_RX_ST_REG_o         0x00
+/*
+ * Mask of the bit which inform that received character is ready
+ to be read by CPU.
+ */
+#define SERP_RX_ST_REG_READY_m    0x1
+/*
+ * Byte offset of the UART received data register.
+ * When the 32-bit word is read the least-significant (LSB)
+ * eight bits are represet last complete byte received from terminal.
+ */
+
+#define SERP_RX_DATA_REG_o        0x04
+/*
+ * Byte offset of the 32-bit transition status register
+ * of the serial port
+ */
+#define SERP_TX_ST_REG_o         0x08
+/*
+ * Mask of the bit which inform that peripheral is ready to accept
+ * next character to send. If it is zero, then peripheral is
+ * busy by sending of previous character.
+ */
+#define SERP_TX_ST_REG_READY_m    0x1
+
+/*
+ * Byte offset of the UART transmit register.
+ * When the 32-bit word is written the least-significant (LSB)
+ * eight bits are send to the terminal.
+ */
+#define SERP_TX_DATA_REG_o        0x0c
+
+/*
+ * Base address of the region where knobs and LEDs peripherals
+ * are mapped in the emulated MIPS physical memory address space.
+ */
+#define SPILED_REG_BASE      0xffffc100
+
+/* Valid address range for the region */
+#define SPILED_REG_SIZE      0x00000100
+
+/*
+ * Byte offset of the register which controls individual LEDs
+ * in the row of 32 yellow LEDs. When the corresponding bit
+ * is set (value 1) then the LED is lit.
+ */
+#define SPILED_REG_LED_LINE_o           0x004
+
+/*
+ * The register to control 8 bit RGB components of brightness
+ * of the first RGB LED
+ */
+#define SPILED_REG_LED_RGB1_o           0x010
+
+/*
+ * The register to control 8 bit RGB components of brightness
+ * of the second RGB LED
+ */
+#define SPILED_REG_LED_RGB2_o           0x014
+
+/*
+ * The register which combines direct write to RGB signals
+ * of the RGB LEDs, write to the keyboard scan register
+ * and control of the two additional individual LEDs.
+ * The direct write to RGB signals is orred with PWM
+ * signal generated according to the values in previous
+ * registers.
+ */
+#define SPILED_REG_LED_KBDWR_DIRECT_o   0x018
+
+/*
+ * Register providing access to unfiltered encoder channels
+ * and keyboard return signals.
+ */
+#define SPILED_REG_KBDRD_KNOBS_DIRECT_o 0x020
+
+/*
+ * The register representing knobs positions as three
+ * 8-bit values where each value is incremented
+ * and decremented by the knob relative turning.
+ */
+#define SPILED_REG_KNOBS_8BIT_o         0x024
+
+/*
+ * The main entry into example program
+ */
+int main(int argc, char *argv[])
+{
+
+  /* the space for your code */
+
+  return 0;
+}
-- 
GitLab