summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorNao Pross <naopross@thearcway.org>2018-10-31 20:34:10 +0100
committerNao Pross <naopross@thearcway.org>2018-10-31 20:34:10 +0100
commit044a4181fb2f6730714489e06a9127240e21595c (patch)
tree14310f175376272b302267b59c67c618e89876bf
parentUpdate gitignore (diff)
downloadz80uPC-044a4181fb2f6730714489e06a9127240e21595c.tar.gz
z80uPC-044a4181fb2f6730714489e06a9127240e21595c.zip
[linux] Add initial implementation of rom-loader
-rw-r--r--sw-linux/rom-loader/CMakeLists.txt5
-rw-r--r--sw-linux/rom-loader/Makefile208
-rw-r--r--sw-linux/rom-loader/main.cpp139
-rwxr-xr-xsw-linux/rom-loader/rom-loaderbin0 -> 27208 bytes
-rw-r--r--sw-linux/rom-loader/serial.cpp89
-rw-r--r--sw-linux/rom-loader/serial.hpp24
6 files changed, 465 insertions, 0 deletions
diff --git a/sw-linux/rom-loader/CMakeLists.txt b/sw-linux/rom-loader/CMakeLists.txt
new file mode 100644
index 0000000..6e1ad02
--- /dev/null
+++ b/sw-linux/rom-loader/CMakeLists.txt
@@ -0,0 +1,5 @@
+cmake_minimum_required(VERSION 3.7)
+
+project(rom-loader LANGUAGES CXX)
+
+add_executable(rom-loader main.cpp serial.cpp)
diff --git a/sw-linux/rom-loader/Makefile b/sw-linux/rom-loader/Makefile
new file mode 100644
index 0000000..c07b827
--- /dev/null
+++ b/sw-linux/rom-loader/Makefile
@@ -0,0 +1,208 @@
+# CMAKE generated file: DO NOT EDIT!
+# Generated by "Unix Makefiles" Generator, CMake Version 3.7
+
+# Default target executed when no arguments are given to make.
+default_target: all
+
+.PHONY : default_target
+
+# Allow only one "make -f Makefile2" at a time, but pass parallelism.
+.NOTPARALLEL:
+
+
+#=============================================================================
+# Special targets provided by cmake.
+
+# Disable implicit rules so canonical targets will work.
+.SUFFIXES:
+
+
+# Remove some rules from gmake that .SUFFIXES does not remove.
+SUFFIXES =
+
+.SUFFIXES: .hpux_make_needs_suffix_list
+
+
+# Suppress display of executed commands.
+$(VERBOSE).SILENT:
+
+
+# A target that is always out of date.
+cmake_force:
+
+.PHONY : cmake_force
+
+#=============================================================================
+# Set environment variables for the build.
+
+# The shell in which to execute make rules.
+SHELL = /bin/sh
+
+# The CMake executable.
+CMAKE_COMMAND = /usr/bin/cmake
+
+# The command to remove a file.
+RM = /usr/bin/cmake -E remove -f
+
+# Escaping for special characters.
+EQUALS = =
+
+# The top-level source directory on which CMake was run.
+CMAKE_SOURCE_DIR = /home/naopross/docs/projects/z80uPC/sw-linux/rom-loader
+
+# The top-level build directory on which CMake was run.
+CMAKE_BINARY_DIR = /home/naopross/docs/projects/z80uPC/sw-linux/rom-loader
+
+#=============================================================================
+# Targets provided globally by CMake.
+
+# Special rule for the target rebuild_cache
+rebuild_cache:
+ @$(CMAKE_COMMAND) -E cmake_echo_color --switch=$(COLOR) --cyan "Running CMake to regenerate build system..."
+ /usr/bin/cmake -H$(CMAKE_SOURCE_DIR) -B$(CMAKE_BINARY_DIR)
+.PHONY : rebuild_cache
+
+# Special rule for the target rebuild_cache
+rebuild_cache/fast: rebuild_cache
+
+.PHONY : rebuild_cache/fast
+
+# Special rule for the target edit_cache
+edit_cache:
+ @$(CMAKE_COMMAND) -E cmake_echo_color --switch=$(COLOR) --cyan "Running CMake cache editor..."
+ /usr/bin/ccmake -H$(CMAKE_SOURCE_DIR) -B$(CMAKE_BINARY_DIR)
+.PHONY : edit_cache
+
+# Special rule for the target edit_cache
+edit_cache/fast: edit_cache
+
+.PHONY : edit_cache/fast
+
+# The main all target
+all: cmake_check_build_system
+ $(CMAKE_COMMAND) -E cmake_progress_start /home/naopross/docs/projects/z80uPC/sw-linux/rom-loader/CMakeFiles /home/naopross/docs/projects/z80uPC/sw-linux/rom-loader/CMakeFiles/progress.marks
+ $(MAKE) -f CMakeFiles/Makefile2 all
+ $(CMAKE_COMMAND) -E cmake_progress_start /home/naopross/docs/projects/z80uPC/sw-linux/rom-loader/CMakeFiles 0
+.PHONY : all
+
+# The main clean target
+clean:
+ $(MAKE) -f CMakeFiles/Makefile2 clean
+.PHONY : clean
+
+# The main clean target
+clean/fast: clean
+
+.PHONY : clean/fast
+
+# Prepare targets for installation.
+preinstall: all
+ $(MAKE) -f CMakeFiles/Makefile2 preinstall
+.PHONY : preinstall
+
+# Prepare targets for installation.
+preinstall/fast:
+ $(MAKE) -f CMakeFiles/Makefile2 preinstall
+.PHONY : preinstall/fast
+
+# clear depends
+depend:
+ $(CMAKE_COMMAND) -H$(CMAKE_SOURCE_DIR) -B$(CMAKE_BINARY_DIR) --check-build-system CMakeFiles/Makefile.cmake 1
+.PHONY : depend
+
+#=============================================================================
+# Target rules for targets named rom-loader
+
+# Build rule for target.
+rom-loader: cmake_check_build_system
+ $(MAKE) -f CMakeFiles/Makefile2 rom-loader
+.PHONY : rom-loader
+
+# fast build rule for target.
+rom-loader/fast:
+ $(MAKE) -f CMakeFiles/rom-loader.dir/build.make CMakeFiles/rom-loader.dir/build
+.PHONY : rom-loader/fast
+
+main.o: main.cpp.o
+
+.PHONY : main.o
+
+# target to build an object file
+main.cpp.o:
+ $(MAKE) -f CMakeFiles/rom-loader.dir/build.make CMakeFiles/rom-loader.dir/main.cpp.o
+.PHONY : main.cpp.o
+
+main.i: main.cpp.i
+
+.PHONY : main.i
+
+# target to preprocess a source file
+main.cpp.i:
+ $(MAKE) -f CMakeFiles/rom-loader.dir/build.make CMakeFiles/rom-loader.dir/main.cpp.i
+.PHONY : main.cpp.i
+
+main.s: main.cpp.s
+
+.PHONY : main.s
+
+# target to generate assembly for a file
+main.cpp.s:
+ $(MAKE) -f CMakeFiles/rom-loader.dir/build.make CMakeFiles/rom-loader.dir/main.cpp.s
+.PHONY : main.cpp.s
+
+serial.o: serial.cpp.o
+
+.PHONY : serial.o
+
+# target to build an object file
+serial.cpp.o:
+ $(MAKE) -f CMakeFiles/rom-loader.dir/build.make CMakeFiles/rom-loader.dir/serial.cpp.o
+.PHONY : serial.cpp.o
+
+serial.i: serial.cpp.i
+
+.PHONY : serial.i
+
+# target to preprocess a source file
+serial.cpp.i:
+ $(MAKE) -f CMakeFiles/rom-loader.dir/build.make CMakeFiles/rom-loader.dir/serial.cpp.i
+.PHONY : serial.cpp.i
+
+serial.s: serial.cpp.s
+
+.PHONY : serial.s
+
+# target to generate assembly for a file
+serial.cpp.s:
+ $(MAKE) -f CMakeFiles/rom-loader.dir/build.make CMakeFiles/rom-loader.dir/serial.cpp.s
+.PHONY : serial.cpp.s
+
+# Help Target
+help:
+ @echo "The following are some of the valid targets for this Makefile:"
+ @echo "... all (the default if no target is provided)"
+ @echo "... clean"
+ @echo "... depend"
+ @echo "... rebuild_cache"
+ @echo "... edit_cache"
+ @echo "... rom-loader"
+ @echo "... main.o"
+ @echo "... main.i"
+ @echo "... main.s"
+ @echo "... serial.o"
+ @echo "... serial.i"
+ @echo "... serial.s"
+.PHONY : help
+
+
+
+#=============================================================================
+# Special targets to cleanup operation of make.
+
+# Special rule to run CMake to check the build system integrity.
+# No rule that depends on this can have commands that come from listfiles
+# because they might be regenerated.
+cmake_check_build_system:
+ $(CMAKE_COMMAND) -H$(CMAKE_SOURCE_DIR) -B$(CMAKE_BINARY_DIR) --check-build-system CMakeFiles/Makefile.cmake 0
+.PHONY : cmake_check_build_system
+
diff --git a/sw-linux/rom-loader/main.cpp b/sw-linux/rom-loader/main.cpp
new file mode 100644
index 0000000..3c845ba
--- /dev/null
+++ b/sw-linux/rom-loader/main.cpp
@@ -0,0 +1,139 @@
+#include <iostream>
+#include <string>
+#include <vector>
+
+#include <cstdio>
+#include <cstdlib>
+
+#include "serial.hpp"
+
+struct args_t
+{
+ std::string file_name;
+ bool file_name_set;
+ std::string port_name;
+ bool port_name_set;
+ long baudrate;
+ bool baudrate_set;
+};
+
+void usage(void)
+{
+ std::cout << "rom-loader -p [PORT] -f [FILE]" << std::endl
+ << std::endl
+ << "Nao Pross <naopross@thearcway.org>" << std::endl;
+}
+
+bool parse_arguments(const int argc, const char * const argv[], args_t& args)
+{
+ if (argc < 2) {
+ usage();
+ return false;
+ }
+
+ args.file_name_set = false;
+ args.port_name_set = false;
+ args.baudrate_set = false;
+
+ for (int i = 1; i < argc; i++) {
+ const std::string arg(argv[i]);
+
+ bool next = false;
+ std::string next_arg = "";
+
+ // check that is an option
+ if (arg.front() != '-') {
+ usage();
+ return false;
+ }
+
+ // help option
+ if (arg[1] == 'h') {
+ usage();
+ return false;
+ }
+
+ // check that threre is an argument
+ if (i+1 < argc) {
+ next_arg = std::string(argv[i+1]);
+ i++;
+ } else {
+ std::cerr << "Missing option argument" << std::endl;
+ return false;
+ }
+
+ switch (arg[1]) {
+ case 'p':
+ args.port_name = next_arg;
+ args.port_name_set = true;
+ break;
+
+ case 'f':
+ args.file_name = next_arg;
+ args.file_name_set = true;
+ break;
+
+ case 'b':
+ args.baudrate = std::stol(next_arg);
+ args.baudrate_set = true;
+ break;
+
+ default:
+ std::cerr << "Invalid option " << arg << std::endl;
+ return false;
+ }
+ }
+
+ if (!args.file_name_set || !args.port_name_set) {
+ std::cerr << "Missing required options: ";
+
+ if (!args.file_name_set)
+ std::cerr << "-f [FILE] ";
+
+ if (!args.port_name_set)
+ std::cerr << "-p [PORT] ";
+
+ std::cerr << std::endl;
+
+ return false;
+ }
+
+ return true;
+}
+
+int main(int argc, char *argv[])
+{
+ args_t args;
+
+ if (!parse_arguments(argc, argv, args)) {
+ return -1;
+ }
+
+ FILE *fileptr = std::fopen(args.file_name.c_str(), "rb");
+
+ if (!fileptr) {
+ std::cerr << "Failed to open file " << args.file_name << std::endl;
+ return -2;
+ }
+
+ serial s_dev(args.port_name, B9600);
+
+ int chr;
+ while ((chr = std::fgetc(fileptr)) != EOF) {
+ const char byte = static_cast<char>(chr);
+
+ // std::cout << std::hex << byte << std::endl;
+ s_dev.write(&byte, 1);
+ }
+
+ if (std::ferror(fileptr))
+ std::cerr << "I/O error when reading file "
+ << args.file_name << std::endl;
+
+ if (!std::feof(fileptr))
+ std::cerr << "The reading ended before reaching EOF" << std::endl;
+
+ std::fclose(fileptr);
+
+ return 0;
+}
diff --git a/sw-linux/rom-loader/rom-loader b/sw-linux/rom-loader/rom-loader
new file mode 100755
index 0000000..6652ef5
--- /dev/null
+++ b/sw-linux/rom-loader/rom-loader
Binary files differ
diff --git a/sw-linux/rom-loader/serial.cpp b/sw-linux/rom-loader/serial.cpp
new file mode 100644
index 0000000..7d25f02
--- /dev/null
+++ b/sw-linux/rom-loader/serial.cpp
@@ -0,0 +1,89 @@
+#include "serial.hpp"
+
+#include <ios>
+
+extern "C" {
+#include <fcntl.h>
+#include <termios.h>
+#include <unistd.h>
+}
+
+serial::serial(const std::string& port, speed_t baud)
+{
+ m_fd = open(port.c_str(), O_RDWR | O_NOCTTY | O_NDELAY);
+
+ if (m_fd < 0) {
+ throw std::ios_base::failure("Failed to open serial port " + port);
+ }
+
+ tcgetattr(m_fd, &m_settings);
+
+ // set input and output baudrate
+ cfsetispeed(&m_settings, baud);
+ cfsetospeed(&m_settings, baud);
+
+ // disable parity, 1 stop bit, clear data size
+ m_settings.c_cflag &= ~(PARENB | CSTOPB | CSIZE);
+ // set data size to 8
+ m_settings.c_cflag |= CS8;
+
+ // disable hw flow control
+ m_settings.c_cflag &= ~CRTSCTS;
+ // enable receiver and ignore modem lines
+ m_settings.c_cflag |= CREAD | CLOCAL;
+
+ // disable XON / XOFF flow control
+ m_settings.c_iflag &= ~(IXON | IXOFF | IXANY);
+ // non canonical mode
+ m_settings.c_iflag &= ~(ICANON | ECHO | ECHOE | ISIG);
+
+ // no output processing
+ m_settings.c_oflag &= ~OPOST;
+
+ // input buffer of 8 bytes
+ m_settings.c_cc[VMIN] = 8;
+ // set indefinite timeout
+ m_settings.c_cc[VTIME] = 0;
+
+ if ((tcsetattr(m_fd, TCSANOW, &m_settings)) != 0)
+ throw std::ios_base::failure("Failed to set attributes");
+
+ // clean rx buffer
+ tcflush(m_fd, TCIFLUSH);
+}
+
+serial::~serial()
+{
+ if (m_fd > 0)
+ close(m_fd);
+}
+
+int serial::write(const std::string& data) const
+{
+ write(data.c_str(), data.length());
+}
+
+int serial::write(const char * const data, size_t len) const
+{
+ return ::write(m_fd, data, len);
+}
+
+char serial::read() const
+{
+ char ch;
+
+ if (::read(m_fd, &ch, 1) < 0)
+ throw std::ios_base::failure("Failed to read");
+
+ return ch;
+}
+
+std::string serial::read(size_t howmany) const
+{
+ char data[howmany] = {};
+
+ if (::read(m_fd, data, howmany) < 0)
+ throw std::ios_base::failure("Failed to read");
+
+ return std::string(data);
+}
diff --git a/sw-linux/rom-loader/serial.hpp b/sw-linux/rom-loader/serial.hpp
new file mode 100644
index 0000000..35b35be
--- /dev/null
+++ b/sw-linux/rom-loader/serial.hpp
@@ -0,0 +1,24 @@
+#pragma once
+
+#include <string>
+
+extern "C" {
+#include <termios.h>
+}
+
+class serial
+{
+public:
+ serial(const std::string& port, speed_t baud);
+ ~serial();
+
+ int write(const std::string& data) const;
+ int write(const char * const data, size_t len) const;
+
+ char read() const;
+ std::string read(size_t howmany) const;
+
+private:
+ int m_fd;
+ struct termios m_settings;
+};