basic setup
This commit is contained in:
parent
3c8456cab0
commit
a982a3c9d9
5 changed files with 126 additions and 5 deletions
1
ESP32/dc11.cpp
Symbolic link
1
ESP32/dc11.cpp
Symbolic link
|
@ -0,0 +1 @@
|
|||
../dc11.cpp
|
1
ESP32/dc11.h
Symbolic link
1
ESP32/dc11.h
Symbolic link
|
@ -0,0 +1 @@
|
|||
../dc11.h
|
106
dc11.cpp
106
dc11.cpp
|
@ -1,17 +1,121 @@
|
|||
// (C) 2024 by Folkert van Heusden
|
||||
// Released under MIT license
|
||||
|
||||
#include <cstring>
|
||||
#include <poll.h>
|
||||
#include <unistd.h>
|
||||
#include <arpa/inet.h>
|
||||
#include <sys/socket.h>
|
||||
|
||||
#include "bus.h"
|
||||
#include "cpu.h"
|
||||
#include "dc11.h"
|
||||
#include "log.h"
|
||||
|
||||
|
||||
dc11::dc11(bus *const b): b(b)
|
||||
dc11::dc11(const int base_port, bus *const b):
|
||||
base_port(base_port),
|
||||
b(b)
|
||||
{
|
||||
th = new std::thread(std::ref(*this));
|
||||
}
|
||||
|
||||
dc11::~dc11()
|
||||
{
|
||||
stop_flag = true;
|
||||
|
||||
if (th) {
|
||||
th->join();
|
||||
delete th;
|
||||
}
|
||||
}
|
||||
|
||||
void dc11::operator()()
|
||||
{
|
||||
int fds[dc11_n_lines] = { };
|
||||
|
||||
pollfd pfds[8] = { };
|
||||
|
||||
for(int i=0; i<dc11_n_lines; i++) {
|
||||
// listen on port
|
||||
pfds[i].fd = socket(AF_INET, SOCK_STREAM, 0);
|
||||
|
||||
int port = base_port + i + 1;
|
||||
|
||||
sockaddr_in listen_addr;
|
||||
memset(&listen_addr, 0, sizeof(listen_addr));
|
||||
listen_addr.sin_family = AF_INET;
|
||||
listen_addr.sin_addr.s_addr = htonl(INADDR_ANY);
|
||||
listen_addr.sin_port = htons(port);
|
||||
|
||||
if (bind(pfds[i].fd, reinterpret_cast<struct sockaddr *>(&listen_addr), sizeof(listen_addr)) == -1) {
|
||||
close(pfds[i].fd);
|
||||
fds[i] = -1;
|
||||
|
||||
DOLOG(warning, true, "Cannot bind to port %d (DC11)", port);
|
||||
}
|
||||
|
||||
pfds[i].events = POLLIN;
|
||||
|
||||
// client session
|
||||
pfds[dc11_n_lines + i].fd = socket(AF_INET, SOCK_STREAM, 0);
|
||||
pfds[dc11_n_lines + i].events = POLLIN;
|
||||
}
|
||||
|
||||
while(!stop_flag) {
|
||||
int rc = poll(pfds, dc11_n_lines * 2, 100);
|
||||
if (rc == 0)
|
||||
continue;
|
||||
|
||||
// accept any new session
|
||||
for(int i=0; i<dc11_n_lines; i++) {
|
||||
if (pfds[i].revents != POLLIN)
|
||||
continue;
|
||||
|
||||
int client_i = dc11_n_lines + i;
|
||||
|
||||
// disconnect any existing client session
|
||||
// yes, one can ddos with this
|
||||
if (pfds[client_i].fd != -1) {
|
||||
close(pfds[client_i].fd);
|
||||
DOLOG(info, false, "Restarting session for port %d", base_port + i + 1);
|
||||
}
|
||||
|
||||
pfds[client_i].fd = accept(pfds[i].fd, nullptr, nullptr);
|
||||
}
|
||||
|
||||
// receive data
|
||||
for(int i=dc11_n_lines; i<dc11_n_lines * 2; i++) {
|
||||
if (pfds[i].revents != POLLIN)
|
||||
continue;
|
||||
|
||||
char buffer[32] { };
|
||||
int rc = read(pfds[i].fd, buffer, sizeof buffer);
|
||||
if (rc <= 0) { // closed or error?
|
||||
DOLOG(info, false, "Failed reading on port %d", base_port + i + 1);
|
||||
close(pfds[i].fd);
|
||||
pfds[i].fd = -1;
|
||||
}
|
||||
else {
|
||||
int line_nr = i - dc11_n_lines;
|
||||
|
||||
std::unique_lock<std::mutex> lck(input_lock[line_nr]);
|
||||
|
||||
for(int k=0; k<rc; k++)
|
||||
recv_buffers[line_nr].push_back(buffer[k]);
|
||||
|
||||
have_data[line_nr].notify_all();
|
||||
|
||||
if (registers[line_nr * 4] & 64) // interrupts enabled?
|
||||
b->getCpu()->queue_interrupt(4, 0320 + line_nr * 4);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
for(int i=0; i<dc11_n_lines * 2; i++) {
|
||||
if (fds[i] != -1)
|
||||
close(fds[i]);
|
||||
}
|
||||
}
|
||||
|
||||
void dc11::reset()
|
||||
|
|
21
dc11.h
21
dc11.h
|
@ -3,7 +3,11 @@
|
|||
|
||||
#pragma once
|
||||
#include <atomic>
|
||||
#include <condition_variable>
|
||||
#include <cstdint>
|
||||
#include <mutex>
|
||||
#include <thread>
|
||||
#include <vector>
|
||||
|
||||
#include "gen.h"
|
||||
#include "bus.h"
|
||||
|
@ -15,16 +19,25 @@
|
|||
|
||||
class bus;
|
||||
|
||||
// 4 interfaces
|
||||
constexpr const int dc11_n_lines = 4;
|
||||
|
||||
class dc11
|
||||
{
|
||||
private:
|
||||
int base_port { 1100 };
|
||||
bus *const b { nullptr };
|
||||
// 4 interfaces
|
||||
uint16_t registers[4 * 4] { };
|
||||
uint16_t registers[4 * dc11_n_lines] { };
|
||||
std::atomic_bool stop_flag { false };
|
||||
std::thread *th { nullptr };
|
||||
|
||||
std::vector<char> recv_buffers[dc11_n_lines];
|
||||
std::condition_variable have_data[dc11_n_lines];
|
||||
std::mutex input_lock[dc11_n_lines];
|
||||
|
||||
|
||||
public:
|
||||
dc11(bus *const b);
|
||||
dc11(const int base_port, bus *const b);
|
||||
virtual ~dc11();
|
||||
|
||||
#if IS_POSIX
|
||||
|
@ -39,4 +52,6 @@ public:
|
|||
|
||||
void write_byte(const uint16_t addr, const uint8_t v);
|
||||
void write_word(const uint16_t addr, uint16_t v);
|
||||
|
||||
void operator()();
|
||||
};
|
||||
|
|
2
main.cpp
2
main.cpp
|
@ -582,7 +582,7 @@ int main(int argc, char *argv[])
|
|||
cnsl->begin();
|
||||
|
||||
// TODO
|
||||
dc11 *dc11_ = new dc11(b);
|
||||
dc11 *dc11_ = new dc11(1100, b);
|
||||
b->add_DC11(dc11_);
|
||||
|
||||
running = cnsl->get_running_flag();
|
||||
|
|
Loading…
Add table
Reference in a new issue