WIN32 build

This commit is contained in:
folkert van heusden 2023-03-27 12:51:20 +02:00
parent 00b4214ea0
commit 08bc5f890a
Signed by untrusted user who does not match committer: folkert
GPG key ID: 6B6455EDFEED3BD1
14 changed files with 184 additions and 8 deletions

View file

@ -34,6 +34,30 @@ add_executable(
utils.cpp utils.cpp
) )
add_executable(
kek-win32
bus.cpp
console.cpp
console_posix.cpp
cpu.cpp
debugger.cpp
disk_backend.cpp
disk_backend_file.cpp
disk_backend_nbd.cpp
error.cpp
kw11-l.cpp
loaders.cpp
log.cpp
main.cpp
memory.cpp
rk05.cpp
rl02.cpp
tm-11.cpp
tty.cpp
utils.cpp
windows/win32.cpp
)
include(CheckIPOSupported) include(CheckIPOSupported)
check_ipo_supported(RESULT supported) check_ipo_supported(RESULT supported)
@ -45,6 +69,9 @@ set(CMAKE_THREAD_PREFER_PTHREAD TRUE)
set(THREADS_PREFER_PTHREAD_FLAG TRUE) set(THREADS_PREFER_PTHREAD_FLAG TRUE)
find_package(Threads) find_package(Threads)
target_link_libraries(kek Threads::Threads) target_link_libraries(kek Threads::Threads)
target_link_libraries(kek-win32 Threads::Threads)
target_link_libraries(kek-win32 ws2_32)
include(FindPkgConfig) include(FindPkgConfig)

View file

@ -10,6 +10,10 @@
#include "bus.h" #include "bus.h"
#if defined(_WIN32)
#include "windows/win32.h"
#endif
constexpr const int t_width { 80 }; constexpr const int t_width { 80 };
constexpr const int t_height { 25 }; constexpr const int t_height { 25 };

View file

@ -1,9 +1,15 @@
// (C) 2018-2023 by Folkert van Heusden // (C) 2018-2023 by Folkert van Heusden
// Released under MIT license // Released under MIT license
#if defined(_WIN32)
#include <conio.h>
#include <winsock2.h>
#else
#include <poll.h> #include <poll.h>
#endif
#include <stdio.h> #include <stdio.h>
#include <termios.h>
#include <unistd.h> #include <unistd.h>
#include "console_posix.h" #include "console_posix.h"
@ -13,6 +19,7 @@
console_posix::console_posix(std::atomic_uint32_t *const stop_event, bus *const b) : console_posix::console_posix(std::atomic_uint32_t *const stop_event, bus *const b) :
console(stop_event, b) console(stop_event, b)
{ {
#if !defined(_WIN32)
if (tcgetattr(STDIN_FILENO, &org_tty_opts) == -1) if (tcgetattr(STDIN_FILENO, &org_tty_opts) == -1)
error_exit(true, "console_posix: tcgetattr failed"); error_exit(true, "console_posix: tcgetattr failed");
@ -21,22 +28,36 @@ console_posix::console_posix(std::atomic_uint32_t *const stop_event, bus *const
if (tcsetattr(STDIN_FILENO, TCSANOW, &tty_opts_raw) == -1) if (tcsetattr(STDIN_FILENO, TCSANOW, &tty_opts_raw) == -1)
error_exit(true, "console_posix: tcsetattr failed"); error_exit(true, "console_posix: tcsetattr failed");
#endif
} }
console_posix::~console_posix() console_posix::~console_posix()
{ {
stop_thread(); stop_thread();
#if !defined(_WIN32)
if (tcsetattr(STDIN_FILENO, TCSANOW, &org_tty_opts) == -1) if (tcsetattr(STDIN_FILENO, TCSANOW, &org_tty_opts) == -1)
error_exit(true, "~console_posix: tcsetattr failed"); error_exit(true, "~console_posix: tcsetattr failed");
#endif
} }
int console_posix::wait_for_char_ll(const short timeout) int console_posix::wait_for_char_ll(const short timeout)
{ {
#if defined(_WIN32)
fd_set rfds;
FD_ZERO(&rfds);
FD_SET(STDIN_FILENO, &rfds);
timeval to { timeout / 1000000, timeout % 1000000 };
if (select(STDIN_FILENO + 1, &rfds, nullptr, nullptr, &to) == 1 && FD_ISSET(STDIN_FILENO, &rfds))
return _getch();
#else
struct pollfd fds[] = { { STDIN_FILENO, POLLIN, timeout } }; struct pollfd fds[] = { { STDIN_FILENO, POLLIN, timeout } };
if (poll(fds, 1, timeout) == 1 && fds[0].revents) if (poll(fds, 1, timeout) == 1 && fds[0].revents)
return getchar(); return getchar();
#endif
return -1; return -1;
} }

View file

@ -1,7 +1,9 @@
// (C) 2018-2023 by Folkert van Heusden // (C) 2018-2023 by Folkert van Heusden
// Released under MIT license // Released under MIT license
#if !defined(_WIN32)
#include <termios.h> #include <termios.h>
#endif
#include "console.h" #include "console.h"
@ -9,7 +11,9 @@
class console_posix : public console class console_posix : public console
{ {
private: private:
#if !defined(_WIN32)
struct termios org_tty_opts { 0 }; struct termios org_tty_opts { 0 };
#endif
protected: protected:
int wait_for_char_ll(const short timeout) override; int wait_for_char_ll(const short timeout) override;

View file

@ -36,12 +36,26 @@ bool disk_backend_file::read(const off_t offset, const size_t n, uint8_t *const
{ {
DOLOG(debug, false, "disk_backend_file::read: read %zu bytes from offset %zu", n, offset); DOLOG(debug, false, "disk_backend_file::read: read %zu bytes from offset %zu", n, offset);
#if defined(_WIN32) // hope for the best
if (lseek(fd, offset, SEEK_SET) == -1)
return false;
return ::read(fd, target, n) == ssize_t(n);
#else
return pread(fd, target, n, offset) == ssize_t(n); return pread(fd, target, n, offset) == ssize_t(n);
#endif
} }
bool disk_backend_file::write(const off_t offset, const size_t n, const uint8_t *const from) bool disk_backend_file::write(const off_t offset, const size_t n, const uint8_t *const from)
{ {
DOLOG(debug, false, "disk_backend_file::write: write %zu bytes to offset %zu", n, offset); DOLOG(debug, false, "disk_backend_file::write: write %zu bytes to offset %zu", n, offset);
#if defined(_WIN32) // hope for the best
if (lseek(fd, offset, SEEK_SET) == -1)
return false;
return ::write(fd, from, n) == ssize_t(n);
#else
return pwrite(fd, from, n, offset) == ssize_t(n); return pwrite(fd, from, n, offset) == ssize_t(n);
#endif
} }

View file

@ -4,18 +4,31 @@
#include <fcntl.h> #include <fcntl.h>
#include <string.h> #include <string.h>
#include <unistd.h> #include <unistd.h>
#include <arpa/inet.h>
#include <sys/types.h> #include <sys/types.h>
#include "disk_backend_nbd.h" #include "disk_backend_nbd.h"
#include "log.h" #include "log.h"
#include "utils.h" #include "utils.h"
#ifdef ESP32 #if defined(ESP32)
#include <lwip/netdb.h> #include <lwip/netdb.h>
#include <lwip/sockets.h> #include <lwip/sockets.h>
#elif defined(_WIN32)
// from https://stackoverflow.com/questions/12765743/implicit-declaration-of-function-getaddrinfo-on-mingw
#define _NTDDI_VERSION_FROM_WIN32_WINNT2(ver) ver##0000
#define _NTDDI_VERSION_FROM_WIN32_WINNT(ver) _NTDDI_VERSION_FROM_WIN32_WINNT2(ver)
#ifndef _WIN32_WINNT
# define _WIN32_WINNT 0x501
#endif
#ifndef NTDDI_VERSION
# define NTDDI_VERSION _NTDDI_VERSION_FROM_WIN32_WINNT(_WIN32_WINNT)
#endif
#include <ws2tcpip.h>
#include <winsock2.h>
#else #else
#include <netdb.h> #include <netdb.h>
#include <arpa/inet.h>
#include <sys/socket.h> #include <sys/socket.h>
#endif #endif

View file

@ -8,9 +8,9 @@
#include <stdlib.h> #include <stdlib.h>
#include <sys/types.h> #include <sys/types.h>
#include <signal.h> #include <signal.h>
#include <regex.h>
#if defined(ESP32) #if defined(ESP32)
#include <Arduino.h> #include <Arduino.h>
#elif defined(_WIN32)
#else #else
#include <ncursesw/ncurses.h> #include <ncursesw/ncurses.h>
#endif #endif
@ -21,18 +21,20 @@
{ {
int e = errno; int e = errno;
#if !defined(_WIN32)
(void)endwin();
#endif
#if defined(ESP32) #if defined(ESP32)
Serial.println(format); Serial.println(format);
#else #else
(void)endwin();
va_list ap; va_list ap;
va_start(ap, format); va_start(ap, format);
(void)vfprintf(stderr, format, ap); (void)vfprintf(stderr, format, ap);
va_end(ap); va_end(ap);
if (sys_err == TRUE) if (sys_err == true)
fprintf(stderr, "error: %s (%d)\n", strerror(e), e); fprintf(stderr, "error: %s (%d)\n", strerror(e), e);
#endif #endif

View file

@ -7,10 +7,12 @@
#include <string.h> #include <string.h>
#include <time.h> #include <time.h>
#include <unistd.h> #include <unistd.h>
#include <sys/types.h>
#include "error.h" #include "error.h"
#include "log.h" #include "log.h"
#include "utils.h" #include "utils.h"
#include "windows/win32.h"
static const char *logfile = strdup("/tmp/myip.log"); static const char *logfile = strdup("/tmp/myip.log");
@ -65,11 +67,13 @@ void dolog(const log_level_t ll, const char *fmt, ...)
if (!lfh) if (!lfh)
error_exit(true, "Cannot access log-file %s", logfile); error_exit(true, "Cannot access log-file %s", logfile);
#if !defined(_WIN32)
if (lf_uid != -1 && fchown(fileno(lfh), lf_uid, lf_gid) == -1) if (lf_uid != -1 && fchown(fileno(lfh), lf_uid, lf_gid) == -1)
error_exit(true, "Cannot change logfile (%s) ownership", logfile); error_exit(true, "Cannot change logfile (%s) ownership", logfile);
if (fcntl(fileno(lfh), F_SETFD, FD_CLOEXEC) == -1) if (fcntl(fileno(lfh), F_SETFD, FD_CLOEXEC) == -1)
error_exit(true, "fcntl(FD_CLOEXEC) failed"); error_exit(true, "fcntl(FD_CLOEXEC) failed");
#endif
#endif #endif
} }
@ -77,8 +81,12 @@ void dolog(const log_level_t ll, const char *fmt, ...)
time_t t_now = now / 1000000; time_t t_now = now / 1000000;
tm tm { 0 }; tm tm { 0 };
#if defined(_WIN32)
tm = *localtime(&t_now);
#else
if (!localtime_r(&t_now, &tm)) if (!localtime_r(&t_now, &tm))
error_exit(true, "localtime_r failed"); error_exit(true, "localtime_r failed");
#endif
char *ts_str = nullptr; char *ts_str = nullptr;

View file

@ -9,7 +9,9 @@
#include <unistd.h> #include <unistd.h>
#include "error.h" #include "error.h"
#if !defined(_WIN32)
#include "console_ncurses.h" #include "console_ncurses.h"
#endif
#include "console_posix.h" #include "console_posix.h"
#include "cpu.h" #include "cpu.h"
#include "debugger.h" #include "debugger.h"
@ -21,7 +23,9 @@
#include "loaders.h" #include "loaders.h"
#include "log.h" #include "log.h"
#include "memory.h" #include "memory.h"
#if !defined(_WIN32)
#include "terminal.h" #include "terminal.h"
#endif
#include "tty.h" #include "tty.h"
#include "utils.h" #include "utils.h"
@ -32,6 +36,7 @@ std::atomic_bool *running { nullptr };
std::atomic_bool sigw_event { false }; std::atomic_bool sigw_event { false };
#if !defined(_WIN32)
void sw_handler(int s) void sw_handler(int s)
{ {
if (s == SIGWINCH) if (s == SIGWINCH)
@ -42,6 +47,7 @@ void sw_handler(int s)
event = EVENT_TERMINATE; event = EVENT_TERMINATE;
} }
} }
#endif
void help() void help()
{ {
@ -227,9 +233,12 @@ int main(int argc, char *argv[])
if (sa_set) if (sa_set)
c->setRegister(7, start_addr); c->setRegister(7, start_addr);
#if !defined(_WIN32)
if (withUI) if (withUI)
cnsl = new console_ncurses(&event, b); cnsl = new console_ncurses(&event, b);
else { else
#endif
{
DOLOG(info, true, "This PDP-11 emulator is called \"kek\" (reason for that is forgotten) and was written by Folkert van Heusden."); DOLOG(info, true, "This PDP-11 emulator is called \"kek\" (reason for that is forgotten) and was written by Folkert van Heusden.");
DOLOG(info, true, "Built on: " __DATE__ " " __TIME__); DOLOG(info, true, "Built on: " __DATE__ " " __TIME__);
@ -262,6 +271,7 @@ int main(int argc, char *argv[])
DOLOG(info, true, "Start running at %06o", c->getRegister(7)); DOLOG(info, true, "Start running at %06o", c->getRegister(7));
#if !defined(_WIN32)
struct sigaction sa { }; struct sigaction sa { };
sa.sa_handler = sw_handler; sa.sa_handler = sw_handler;
sigemptyset(&sa.sa_mask); sigemptyset(&sa.sa_mask);
@ -272,6 +282,7 @@ int main(int argc, char *argv[])
sigaction(SIGTERM, &sa, nullptr); sigaction(SIGTERM, &sa, nullptr);
sigaction(SIGINT , &sa, nullptr); sigaction(SIGINT , &sa, nullptr);
#endif
if (test.empty() == false) if (test.empty() == false)
load_p11_x11(b, test); load_p11_x11(b, test);

View file

@ -16,6 +16,9 @@
#include <vector> #include <vector>
#include <sys/time.h> #include <sys/time.h>
#include "windows/win32.h"
void setBit(uint16_t & v, const int bit, const bool vb) void setBit(uint16_t & v, const int bit, const bool vb)
{ {
const uint16_t mask = 1 << bit; const uint16_t mask = 1 << bit;

3
windows/README.txt Normal file
View file

@ -0,0 +1,3 @@
cmake -DCMAKE_TOOLCHAIN_FILE=mingw64.cmake ..
make kek-win32

14
windows/mingw64.cmake Normal file
View file

@ -0,0 +1,14 @@
# cmake -DCMAKE_TOOLCHAIN_FILE=mingw64.cmake ..
set(CMAKE_SYSTEM_NAME Windows)
set(TOOLCHAIN_PREFIX x86_64-w64-mingw32)
set(CMAKE_C_COMPILER ${TOOLCHAIN_PREFIX}-gcc-posix)
set(CMAKE_CXX_COMPILER ${TOOLCHAIN_PREFIX}-g++-posix)
set(CMAKE_RC_COMPILER ${TOOLCHAIN_PREFIX}-windres)
set(CMAKE_FIND_ROOT_PATH /usr/${TOOLCHAIN_PREFIX} /usr/lib/gcc/${TOOLCHAIN_PREFIX}/7.3-posix)
set(CMAKE_FIND_ROOT_PATH_MODE_PROGRAM NEVER)
set(CMAKE_FIND_ROOT_PATH_MODE_LIBRARY ONLY)
set(CMAKE_FIND_ROOT_PATH_MODE_INCLUDE ONLY)

48
windows/win32.cpp Normal file
View file

@ -0,0 +1,48 @@
#if defined(_WIN32)
// from https://stackoverflow.com/questions/40159892/using-asprintf-on-windows
#include <stdio.h> /* needed for vsnprintf */
#include <stdlib.h> /* needed for malloc, free */
#include <stdarg.h> /* needed for va_* */
int vscprintf(const char *format, va_list ap)
{
va_list ap_copy;
va_copy(ap_copy, ap);
int retval = vsnprintf(NULL, 0, format, ap_copy);
va_end(ap_copy);
return retval;
}
/*
* asprintf, vasprintf:
* MSVC does not implement these, thus we implement them here
* GNU-C-compatible compilers implement these with the same names, thus we
* don't have to do anything
*/
int vasprintf(char **strp, const char *format, va_list ap)
{
int len = vscprintf(format, ap);
if (len == -1)
return -1;
char *str = (char*)malloc((size_t) len + 1);
if (!str)
return -1;
int retval = vsnprintf(str, len + 1, format, ap);
if (retval == -1) {
free(str);
return -1;
}
*strp = str;
return retval;
}
int asprintf(char **strp, const char *format, ...)
{
va_list ap;
va_start(ap, format);
int retval = vasprintf(strp, format, ap);
va_end(ap);
return retval;
}
#endif

4
windows/win32.h Normal file
View file

@ -0,0 +1,4 @@
#pragma once
int vasprintf(char **strp, const char *format, va_list ap);
int asprintf(char **strp, const char *format, ...);