summaryrefslogtreecommitdiffstats
path: root/sw-linux/rom-loader/main.cpp
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 /sw-linux/rom-loader/main.cpp
parentUpdate gitignore (diff)
downloadz80uPC-044a4181fb2f6730714489e06a9127240e21595c.tar.gz
z80uPC-044a4181fb2f6730714489e06a9127240e21595c.zip
[linux] Add initial implementation of rom-loader
Diffstat (limited to 'sw-linux/rom-loader/main.cpp')
-rw-r--r--sw-linux/rom-loader/main.cpp139
1 files changed, 139 insertions, 0 deletions
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;
+}