Merge pull request #29 from joevt/master

Add socket option for serial backend
This commit is contained in:
dingusdev 2022-08-14 16:59:08 -07:00 committed by GitHub
commit 7f57e96335
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
20 changed files with 361 additions and 77 deletions

View File

@ -191,7 +191,7 @@ void ppc_opcode19() {
#ifdef EXHAUSTIVE_DEBUG
uint32_t regrab = (uint32_t)subop_grab;
LOG_F(INFO, "Executing Opcode 19 table subopcode entry \n", regrab);
LOG_F(INFO, "Executing Opcode 19 table subopcode entry", regrab);
#endif // EXHAUSTIVE_DEBUG
if (subop_grab == 32) {
@ -251,7 +251,7 @@ void ppc_opcode31() {
oe_flag = ppc_cur_instruction & 0x400;
#ifdef EXHAUSTIVE_DEBUG
LOG_F(INFO, "Executing Opcode 31 table subopcode entry %n \n", (uint32_t)subop_grab);
LOG_F(INFO, "Executing Opcode 31 table subopcode entry %n", (uint32_t)subop_grab);
#endif // EXHAUSTIVE_DEBUG
SubOpcode31Grabber[subop_grab]();
@ -261,7 +261,7 @@ void ppc_opcode59() {
uint16_t subop_grab = (ppc_cur_instruction >> 1) & 0x1F;
rc_flag = ppc_cur_instruction & 1;
#ifdef EXHAUSTIVE_DEBUG
LOG_F(INFO, "Executing Opcode 59 table subopcode entry %n \n", (uint32_t)subop_grab);
LOG_F(INFO, "Executing Opcode 59 table subopcode entry %n", (uint32_t)subop_grab);
#endif // EXHAUSTIVE_DEBUG
SubOpcode59Grabber[subop_grab]();
}
@ -270,7 +270,7 @@ void ppc_opcode63() {
uint16_t subop_grab = (ppc_cur_instruction >> 1) & 0x3FF;
rc_flag = ppc_cur_instruction & 1;
#ifdef EXHAUSTIVE_DEBUG
LOG_F(INFO, "Executing Opcode 63 table subopcode entry %n \n", (uint32_t)subop_grab);
LOG_F(INFO, "Executing Opcode 63 table subopcode entry %n", (uint32_t)subop_grab);
#endif // EXHAUSTIVE_DEBUG
SubOpcode63Grabber[subop_grab]();
}

View File

@ -615,7 +615,7 @@ static TLBEntry* dtlb2_refill(uint32_t guest_va, int is_write)
}
return tlb_entry;
} else {
LOG_F(WARNING, "Access to unmapped physical memory, phys_addr=0x%08X\n", phys_addr);
LOG_F(WARNING, "Access to unmapped physical memory, phys_addr=0x%08X", phys_addr);
return &UnmappedMem;
}
}
@ -947,7 +947,7 @@ void mmu_pat_ctx_changed()
void mmu_print_regs()
{
LOG_SCOPE_FUNCTION(INFO);
LOG_F(INFO, "MSR = 0x%X\n", ppc_state.msr);
LOG_F(INFO, "MSR = 0x%X", ppc_state.msr);
LOG_F(INFO, "BAT registers:");
@ -966,7 +966,7 @@ void mmu_print_regs()
}
LOG_F(INFO, "");
LOG_F(INFO, "SDR1 = 0x%X\n", ppc_state.spr[SPR::SDR1]);
LOG_F(INFO, "SDR1 = 0x%X", ppc_state.spr[SPR::SDR1]);
LOG_F(INFO, "Segment registers:");
for (int i = 0; i < 16; i++) {
@ -1372,7 +1372,7 @@ static inline T read_phys_mem(AddressMapEntry *mru_rgn, uint32_t addr)
if (entry) {
*mru_rgn = *entry;
} else {
LOG_F(ERROR, "Read from unmapped memory at 0x%08X!\n", addr);
LOG_F(ERROR, "Read from unmapped memory at 0x%08X!", addr);
return (-1ULL ? sizeof(T) == 8 : -1UL);
}
}
@ -1402,7 +1402,7 @@ static inline T read_phys_mem(AddressMapEntry *mru_rgn, uint32_t addr)
return READ_QWORD_BE_A(mru_rgn->mem_ptr + (addr - mru_rgn->start));
}
default:
LOG_F(ERROR, "READ_PHYS: invalid size %lu passed\n", sizeof(T));
LOG_F(ERROR, "READ_PHYS: invalid size %lu passed", sizeof(T));
return (-1ULL ? sizeof(T) == 8 : -1UL);
}
} else if (mru_rgn->type & RT_MMIO) {
@ -1413,7 +1413,7 @@ static inline T read_phys_mem(AddressMapEntry *mru_rgn, uint32_t addr)
return (mru_rgn->devobj->read(mru_rgn->start,
addr - mru_rgn->start, sizeof(T)));
} else {
LOG_F(ERROR, "READ_PHYS: invalid region type!\n");
LOG_F(ERROR, "READ_PHYS: invalid region type!");
return (-1ULL ? sizeof(T) == 8 : -1UL);
}
}
@ -1426,7 +1426,7 @@ static inline void write_phys_mem(AddressMapEntry *mru_rgn, uint32_t addr, T val
if (entry) {
*mru_rgn = *entry;
} else {
LOG_F(ERROR, "Write to unmapped memory at 0x%08X!\n", addr);
LOG_F(ERROR, "Write to unmapped memory at 0x%08X!", addr);
return;
}
}
@ -1460,7 +1460,7 @@ static inline void write_phys_mem(AddressMapEntry *mru_rgn, uint32_t addr, T val
}
break;
default:
LOG_F(ERROR, "WRITE_PHYS: invalid size %lu passed\n", sizeof(T));
LOG_F(ERROR, "WRITE_PHYS: invalid size %lu passed", sizeof(T));
return;
}
} else if (mru_rgn->type & RT_MMIO) {
@ -1471,7 +1471,7 @@ static inline void write_phys_mem(AddressMapEntry *mru_rgn, uint32_t addr, T val
mru_rgn->devobj->write(mru_rgn->start, addr - mru_rgn->start, value,
sizeof(T));
} else {
LOG_F(ERROR, "WRITE_PHYS: invalid region type!\n");
LOG_F(ERROR, "WRITE_PHYS: invalid region type!");
}
}
@ -1525,7 +1525,7 @@ static uint32_t ppc_mmu_addr_translate(uint32_t la, int is_write)
static void mem_write_unaligned(uint32_t addr, uint32_t value, uint32_t size) {
#ifdef MMU_DEBUG
LOG_F(WARNING, "Attempt to write unaligned %d bytes to 0x%08X\n", size, addr);
LOG_F(WARNING, "Attempt to write unaligned %d bytes to 0x%08X", size, addr);
#endif
if (((addr & 0xFFF) + size) > 0x1000) {
@ -1627,7 +1627,7 @@ static uint32_t mem_grab_unaligned(uint32_t addr, uint32_t size) {
uint32_t ret = 0;
#ifdef MMU_DEBUG
LOG_F(WARNING, "Attempt to read unaligned %d bytes from 0x%08X\n", size, addr);
LOG_F(WARNING, "Attempt to read unaligned %d bytes from 0x%08X", size, addr);
#endif
if (((addr & 0xFFF) + size) > 0x1000) {

View File

@ -1199,7 +1199,7 @@ void dppc_interpreter::ppc_bclrl() {
void dppc_interpreter::ppc_cmp() {
#ifdef CHECK_INVALID
if (ppc_cur_instruction & 0x200000) {
LOG_F(WARNING, "Invalid CMP instruction form (L=1)!\n");
LOG_F(WARNING, "Invalid CMP instruction form (L=1)!");
return;
}
#endif
@ -1216,7 +1216,7 @@ void dppc_interpreter::ppc_cmp() {
void dppc_interpreter::ppc_cmpi() {
#ifdef CHECK_INVALID
if (ppc_cur_instruction & 0x200000) {
LOG_F(WARNING, "Invalid CMPI instruction form (L=1)!\n");
LOG_F(WARNING, "Invalid CMPI instruction form (L=1)!");
return;
}
#endif
@ -1233,7 +1233,7 @@ void dppc_interpreter::ppc_cmpi() {
void dppc_interpreter::ppc_cmpl() {
#ifdef CHECK_INVALID
if (ppc_cur_instruction & 0x200000) {
LOG_F(WARNING, "Invalid CMPL instruction form (L=1)!\n");
LOG_F(WARNING, "Invalid CMPL instruction form (L=1)!");
return;
}
#endif
@ -1250,7 +1250,7 @@ void dppc_interpreter::ppc_cmpl() {
void dppc_interpreter::ppc_cmpli() {
#ifdef CHECK_INVALID
if (ppc_cur_instruction & 0x200000) {
LOG_F(WARNING, "Invalid CMPLI instruction form (L=1)!\n");
LOG_F(WARNING, "Invalid CMPLI instruction form (L=1)!");
return;
}
#endif

View File

@ -75,7 +75,7 @@ void NVram::init() {
!f.read((char*)&data_size, sizeof(data_size)) ||
memcmp(sig, NVRAM_FILE_ID, sizeof(NVRAM_FILE_ID)) || data_size != this->ram_size ||
!f.read((char*)this->storage, this->ram_size)) {
LOG_F(WARNING, "Could not restore NVRAM content from the given file. \n");
LOG_F(WARNING, "Could not restore NVRAM content from the given file.");
memset(this->storage, 0, sizeof(this->ram_size));
}

View File

@ -131,7 +131,7 @@ uint32_t Bandit::read(uint32_t reg_start, uint32_t offset, int size)
} else {
LOG_F(
ERROR,
"%s err: read attempt from non-existing PCI device %d \n",
"%s err: read attempt from non-existing PCI device %d",
this->name.c_str(),
idsel);
result = 0;
@ -187,7 +187,7 @@ void Bandit::write(uint32_t reg_start, uint32_t offset, uint32_t value, int size
} else {
LOG_F(
ERROR,
"%s err: write attempt to non-existing PCI device %d \n",
"%s err: write attempt to non-existing PCI device %d",
this->name.c_str(),
idsel);
}
@ -269,7 +269,7 @@ uint32_t Chaos::read(uint32_t reg_start, uint32_t offset, int size)
} else {
LOG_F(
ERROR,
"%s err: read attempt from non-existing VCI device %d \n",
"%s err: read attempt from non-existing VCI device %d",
this->name.c_str(),
idsel);
result = 0;
@ -312,7 +312,7 @@ void Chaos::write(uint32_t reg_start, uint32_t offset, uint32_t value, int size)
} else {
LOG_F(
ERROR,
"%s err: write attempt to non-existing VCI device %d \n",
"%s err: write attempt to non-existing VCI device %d",
this->name.c_str(),
idsel);
}

View File

@ -435,7 +435,7 @@ void ViaCuda::process_packet() {
switch (this->in_buf[0]) {
case CUDA_PKT_ADB:
LOG_F(9, "Cuda: ADB packet received \n");
LOG_F(9, "Cuda: ADB packet received");
process_adb_command(this->in_buf[1], this->in_count - 2);
break;
case CUDA_PKT_PSEUDO:
@ -624,7 +624,7 @@ void ViaCuda::pseudo_command(int cmd, int data_count) {
case CUDA_MONO_STABLE_RESET:
case CUDA_RESTART_SYSTEM:
/* really kludge temp code */
LOG_F(INFO, "Cuda: Restart/Shutdown signal sent with command 0x%x! \n", cmd);
LOG_F(INFO, "Cuda: Restart/Shutdown signal sent with command 0x%x!", cmd);
//exit(0);
break;
default:

View File

@ -242,7 +242,7 @@ FloppyImgConverter* open_floppy_image(std::string& img_path)
break;
case FlopImgType::WOZ1:
case FlopImgType::WOZ2:
LOG_F(INFO, "WOZ v%s image\n", (itype == FlopImgType::WOZ2) ? "2" : "1");
LOG_F(INFO, "WOZ v%s image", (itype == FlopImgType::WOZ2) ? "2" : "1");
break;
default:
LOG_F(ERROR, "Unknown/unsupported image format!");

View File

@ -131,7 +131,7 @@ void HeathrowIC::dma_write(uint32_t offset, uint32_t value, int size) {
uint32_t HeathrowIC::read(uint32_t reg_start, uint32_t offset, int size) {
uint32_t res = 0;
LOG_F(9, "%s: reading from offset %x \n", this->name.c_str(), offset);
LOG_F(9, "%s: reading from offset %x", this->name.c_str(), offset);
unsigned sub_addr = (offset >> 12) & 0x7F;
@ -165,7 +165,7 @@ uint32_t HeathrowIC::read(uint32_t reg_start, uint32_t offset, int size) {
if (sub_addr >= 0x60) {
res = this->nvram->read_byte((offset - 0x60000) >> 4);
} else {
LOG_F(WARNING, "Attempting to read unmapped I/O space: %x \n", offset);
LOG_F(WARNING, "Attempting to read unmapped I/O space: %x", offset);
}
}
@ -173,7 +173,7 @@ uint32_t HeathrowIC::read(uint32_t reg_start, uint32_t offset, int size) {
}
void HeathrowIC::write(uint32_t reg_start, uint32_t offset, uint32_t value, int size) {
LOG_F(9, "%s: writing to offset %x \n", this->name.c_str(), offset);
LOG_F(9, "%s: writing to offset %x", this->name.c_str(), offset);
unsigned sub_addr = (offset >> 12) & 0x7F;
@ -210,7 +210,7 @@ void HeathrowIC::write(uint32_t reg_start, uint32_t offset, uint32_t value, int
if (sub_addr >= 0x60) {
this->nvram->write_byte((offset - 0x60000) >> 4, value);
} else {
LOG_F(WARNING, "Attempting to write to unmapped I/O space: %x \n", offset);
LOG_F(WARNING, "Attempting to write to unmapped I/O space: %x", offset);
}
}
}
@ -238,16 +238,16 @@ uint32_t HeathrowIC::mio_ctrl_read(uint32_t offset, int size) {
res = this->int_levels1;
break;
case MIO_HEAT_ID:
LOG_F(9, "read from MIO:ID register at Address %x \n", ppc_state.pc);
LOG_F(9, "read from MIO:ID register at Address %x", ppc_state.pc);
res = (this->fp_id << 24) | (this->mon_id << 16) | (this->mb_id << 8) |
(this->cpu_id | (this->emmo_pin << 4));
break;
case MIO_HEAT_FEAT_CTRL:
LOG_F(9, "read from MIO:Feat_Ctrl register \n");
LOG_F(9, "read from MIO:Feat_Ctrl register");
res = this->feat_ctrl;
break;
default:
LOG_F(WARNING, "read from unknown MIO register at %x \n", offset);
LOG_F(WARNING, "read from unknown MIO register at %x", offset);
break;
}
@ -279,24 +279,24 @@ void HeathrowIC::mio_ctrl_write(uint32_t offset, uint32_t value, int size) {
}
break;
case MIO_HEAT_ID:
LOG_F(WARNING, "Attempted to write %x to MIO:ID at %x; Address : %x \n", value, offset, ppc_state.pc);
LOG_F(WARNING, "Attempted to write %x to MIO:ID at %x; Address : %x", value, offset, ppc_state.pc);
break;
case MIO_HEAT_FEAT_CTRL:
this->feature_control(BYTESWAP_32(value));
break;
case 0x3C:
LOG_F(9, "write %x to MIO:Aux_Ctrl register \n", value);
LOG_F(9, "write %x to MIO:Aux_Ctrl register", value);
this->aux_ctrl = value;
break;
default:
LOG_F(WARNING, "write %x to unknown MIO register at %x \n", value, offset);
LOG_F(WARNING, "write %x to unknown MIO register at %x", value, offset);
break;
}
}
void HeathrowIC::feature_control(const uint32_t value)
{
LOG_F(9, "write %x to MIO:Feat_Ctrl register \n", value);
LOG_F(9, "write %x to MIO:Feat_Ctrl register", value);
this->feat_ctrl = value;

View File

@ -107,7 +107,7 @@ uint32_t MPC106::pci_read(uint32_t size) {
if (bus_num) {
LOG_F(
ERROR,
"%s err: read attempt from non-local PCI bus, config_addr = %x \n",
"%s err: read attempt from non-local PCI bus, config_addr = %x",
this->name.c_str(),
this->config_addr);
return 0;
@ -125,7 +125,7 @@ uint32_t MPC106::pci_read(uint32_t size) {
} else {
LOG_F(
ERROR,
"%s err: read attempt from non-existing PCI device %d \n",
"%s err: read attempt from non-existing PCI device %d",
this->name.c_str(),
dev_num);
return 0;
@ -142,7 +142,7 @@ void MPC106::pci_write(uint32_t value, uint32_t size) {
if (bus_num) {
LOG_F(
ERROR,
"%s err: write attempt to non-local PCI bus, config_addr = %x \n",
"%s err: write attempt to non-local PCI bus, config_addr = %x",
this->name.c_str(),
this->config_addr);
return;
@ -160,7 +160,7 @@ void MPC106::pci_write(uint32_t value, uint32_t size) {
} else {
LOG_F(
ERROR,
"%s err: write attempt to non-existing PCI device %d \n",
"%s err: write attempt to non-existing PCI device %d",
this->name.c_str(),
dev_num);
}
@ -169,7 +169,7 @@ void MPC106::pci_write(uint32_t value, uint32_t size) {
uint32_t MPC106::pci_cfg_read(uint32_t reg_offs, uint32_t size) {
#ifdef MPC106_DEBUG
LOG_F(9, "read from Grackle register %08X\n", reg_offs);
LOG_F(9, "read from Grackle register %08X", reg_offs);
#endif
if (reg_offs < 64) {
@ -181,7 +181,7 @@ uint32_t MPC106::pci_cfg_read(uint32_t reg_offs, uint32_t size) {
void MPC106::pci_cfg_write(uint32_t reg_offs, uint32_t value, uint32_t size) {
#ifdef MPC106_DEBUG
LOG_F(9, "write %08X to Grackle register %08X\n", value, reg_offs);
LOG_F(9, "write %08X to Grackle register %08X", value, reg_offs);
#endif
if (reg_offs < 64) {
@ -195,7 +195,7 @@ void MPC106::pci_cfg_write(uint32_t reg_offs, uint32_t value, uint32_t size) {
if (this->my_pci_cfg_hdr[0xF2] & 8) {
#ifdef MPC106_DEBUG
LOG_F(9, "MPC106: MCCR1[MEMGO] was set! \n");
LOG_F(9, "MPC106: MCCR1[MEMGO] was set!");
#endif
setup_ram();
}
@ -225,13 +225,13 @@ void MPC106::setup_ram() {
bank_end = (((ext_mem_end >> bank * 8) & 3) << 30) |
(((mem_end >> bank * 8) & 0xFF) << 20) | 0xFFFFFUL;
if (bank && bank_start != ram_size)
LOG_F(WARNING, "MPC106: RAM not contiguous! \n");
LOG_F(WARNING, "MPC106: RAM not contiguous!");
ram_size += bank_end - bank_start + 1;
}
}
if (!this->add_ram_region(0, ram_size)) {
LOG_F(ERROR, "MPC106 RAM allocation failed! \n");
LOG_F(ERROR, "MPC106 RAM allocation failed!");
}
}

View File

@ -56,7 +56,7 @@ HANDLE hOutput = GetStdHandle(STD_OUTPUT_HANDLE);
DWORD old_in_mode, old_out_mode;
int old_stdin_trans_mode;
void mysig_handler(int signum) {
void CharIoStdin::mysig_handler(int signum) {
SetStdHandle(signum, hInput);
SetStdHandle(signum, hOutput);
}
@ -127,24 +127,24 @@ int CharIoStdin::rcv_char(uint8_t* c) {
#else // non-Windows OS (Linux, mac OS etc.)
#include <signal.h>
#include <stdio.h>
#include <sys/time.h>
#include <sys/types.h>
#include <sys/select.h>
#include <termios.h>
#include <unistd.h>
struct sigaction old_act, new_act;
struct sigaction old_act_sigint, new_act_sigint;
struct sigaction old_act_sigterm, new_act_sigterm;
struct termios orig_termios;
void mysig_handler(int signum)
void CharIoStdin::mysig_handler(int signum)
{
// restore original terminal state
tcsetattr(STDIN_FILENO, TCSANOW, &orig_termios);
// restore original signal handler for SIGINT
signal(SIGINT, old_act.sa_handler);
signal(SIGINT, old_act_sigint.sa_handler);
signal(SIGTERM, old_act_sigterm.sa_handler);
LOG_F(INFO, "Old terminal state restored, SIG#=%d", signum);
@ -171,9 +171,15 @@ int CharIoStdin::rcv_enable()
// save original signal handler for SIGINT
// then redirect SIGINT to new handler
memset(&new_act, 0, sizeof(new_act));
new_act.sa_handler = mysig_handler;
sigaction(SIGINT, &new_act, &old_act);
memset(&new_act_sigint, 0, sizeof(new_act_sigint));
new_act_sigint.sa_handler = mysig_handler;
sigaction(SIGINT, &new_act_sigint, &old_act_sigint);
// save original signal handler for SIGTERM
// then redirect SIGTERM to new handler
memset(&new_act_sigterm, 0, sizeof(new_act_sigterm));
new_act_sigterm.sa_handler = mysig_handler;
sigaction(SIGTERM, &new_act_sigterm, &old_act_sigterm);
this->stdio_inited = true;
@ -189,25 +195,38 @@ void CharIoStdin::rcv_disable()
tcsetattr(STDIN_FILENO, TCSANOW, &orig_termios);
// restore original signal handler for SIGINT
signal(SIGINT, old_act.sa_handler);
signal(SIGINT, old_act_sigint.sa_handler);
// restore original signal handler for SIGTERM
signal(SIGTERM, old_act_sigterm.sa_handler);
this->stdio_inited = false;
}
bool CharIoStdin::rcv_char_available()
{
static int consecutivechars = 0;
if (consecutivechars >= 15) {
consecutivechars++;
if (consecutivechars >= 400)
consecutivechars = 0;
return 0;
}
fd_set readfds;
FD_ZERO(&readfds);
FD_SET(STDIN_FILENO, &readfds);
fd_set savefds = readfds;
struct timeval timeout;
timeout.tv_sec = 0;
timeout.tv_usec = 0;
int chr;
int sel_rv = select(1, &readfds, NULL, NULL, &timeout);
if (sel_rv > 0)
consecutivechars++;
else
consecutivechars = 0;
return sel_rv > 0;
}
@ -224,3 +243,233 @@ int CharIoStdin::rcv_char(uint8_t *c)
}
#endif
//======================== SOCKET character I/O backend ========================
#ifdef _WIN32
#else // non-Windows OS (Linux, mac OS etc.)
#include <sys/socket.h>
#include <sys/un.h>
#include <sys/errno.h>
CharIoSocket::CharIoSocket()
{
int rc;
path = "dingussocket";
do {
rc = unlink(path);
if (rc == 0) {
LOG_F(INFO, "socket unlinked %s", path);
}
else if (errno != ENOENT) {
LOG_F(INFO, "socket unlink err: %s", strerror(errno));
break;
}
sockaddr_un address;
memset(&address, 0, sizeof(address));
address.sun_family = AF_UNIX;
strcpy(address.sun_path, path);
sockfd = socket(AF_UNIX, SOCK_STREAM, 0);
if (sockfd == -1) {
LOG_F(INFO, "socket create err: %s", strerror(errno));
break;
}
rc = bind(sockfd, (sockaddr*)(&address), sizeof(address));
if (rc == -1) {
LOG_F(INFO, "socket bind err: %s", strerror(errno));
close(sockfd);
sockfd = -1;
break;
}
rc = listen(sockfd, 100);
if (rc == -1) {
LOG_F(INFO, "socket listen err: %s", strerror(errno));
close(sockfd);
sockfd = -1;
break;
}
LOG_F(INFO, "socket listen %d", sockfd);
} while (0);
};
CharIoSocket::~CharIoSocket() {
unlink(path);
if (errno != ENOENT) {
LOG_F(INFO, "socket unlink err: %s", strerror(errno));
}
if (sockfd != -1) {
close(sockfd);
sockfd = -1;
}
}
int CharIoSocket::rcv_enable()
{
if (this->socket_inited)
return 0;
this->socket_inited = true;
return 0;
}
void CharIoSocket::rcv_disable()
{
if (!this->socket_inited)
return;
this->socket_inited = false;
}
bool CharIoSocket::rcv_char_available()
{
static int consecutivechars = 0;
static int count = 0;
if (consecutivechars >= 15) {
consecutivechars++;
if (consecutivechars >= 400)
consecutivechars = 0;
return 0;
}
int sel_rv = 0;
bool havechars = false;
fd_set readfds;
fd_set writefds;
fd_set errorfds;
int sockmax = 0;
if (sockfd != -1) {
FD_ZERO(&readfds);
FD_SET(sockfd, &readfds);
if (sockfd > sockmax) sockmax = sockfd;
if (acceptfd != -1) {
FD_SET(acceptfd, &readfds);
if (acceptfd > sockmax) sockmax = acceptfd;
}
writefds = readfds;
errorfds = readfds;
struct timeval timeout;
timeout.tv_sec = 0;
timeout.tv_usec = 0;
sel_rv = select(sockmax + 1, &readfds, &writefds, &errorfds, &timeout);
if (sel_rv == -1) {
LOG_F(INFO, "socket select err: %s", strerror(errno));
}
}
if (sel_rv > 0) {
if (sockfd != -1) {
if (FD_ISSET(sockfd, &readfds)) {
uint8_t c;
int received = recv(sockfd, &c, 1, 0);
if (received == -1 && acceptfd != -1) {
LOG_F(INFO, "socket sock read err: %s", strerror(errno));
}
else if (received == 1) {
LOG_F(INFO, "socket sock read '%c'", c);
}
else {
LOG_F(INFO, "socket sock read %d", received);
}
if (acceptfd == -1) {
sockaddr_un acceptfdaddr;
memset(&acceptfdaddr, 0, sizeof(acceptfdaddr));
socklen_t len = sizeof(acceptfdaddr);
acceptfd = accept(sockfd, (struct sockaddr *) &acceptfdaddr, &len);
if (acceptfd == -1){
LOG_F(INFO, "socket accept err: %s", strerror(errno));
}
else {
LOG_F(INFO, "socket accept %d", acceptfd);
}
}
} // if read
if (FD_ISSET(sockfd, &writefds)) {
LOG_F(INFO, "socket sock write");
}
if (FD_ISSET(sockfd, &errorfds)) {
LOG_F(INFO, "socket sock error");
}
} // if sockfd
if (acceptfd != -1) {
if (FD_ISSET(acceptfd, &readfds)) {
// LOG_F(INFO, "socket accept read havechars");
havechars = true;
consecutivechars++;
} // if read
if (FD_ISSET(acceptfd, &writefds)) {
// LOG_F(INFO, "socket accept write"); // this is usually always true
}
if (FD_ISSET(acceptfd, &errorfds)) {
LOG_F(INFO, "socket accept error");
}
} // if acceptfd
}
else
consecutivechars = 0;
return havechars;
}
int CharIoSocket::xmit_char(uint8_t c)
{
if (acceptfd == -1)
CharIoSocket::rcv_char_available();
if (acceptfd != -1) {
int sent = send(acceptfd, &c, 1, 0);
if (sent == -1) {
LOG_F(INFO, "socket accept write err: %s", strerror(errno));
}
if (sent == 1) {
// LOG_F(INFO, "socket accept write '%c'", c);
}
else {
LOG_F(INFO, "socket accept write %d", sent);
}
}
return 0;
}
int CharIoSocket::rcv_char(uint8_t *c)
{
if (acceptfd == -1)
CharIoSocket::rcv_char_available();
if (acceptfd != -1) {
int received = recv(acceptfd, c, 1, 0);
if (received == -1) {
LOG_F(INFO, "socket accept read err: %s", strerror(errno));
}
else if (received == 1) {
// LOG_F(INFO, "socket accept read '%c'", c ? *c : 0);
}
else {
LOG_F(INFO, "socket accept read %d", received);
}
}
return 0;
}
#endif

View File

@ -26,13 +26,16 @@ along with this program. If not, see <https://www.gnu.org/licenses/>.
#include <cinttypes>
#ifndef _WIN32
#ifdef _WIN32
#else
#include <termios.h>
#include <signal.h>
#endif
enum {
CHARIO_BE_NULL = 0, // NULL backend: swallows everything, receives nothing
CHARIO_BE_STDIO = 1, // STDIO backend: uses STDIN for input and STDOUT for output
CHARIO_BE_SOCKET = 2, // socket backend: uses a socket for input and output
};
/** Interface for character I/O backends. */
@ -72,7 +75,27 @@ public:
int rcv_char(uint8_t *c);
private:
static void mysig_handler(int signum);
bool stdio_inited;
};
/** Socket character I/O backend. */
class CharIoSocket : public CharIoBackEnd {
public:
CharIoSocket();
~CharIoSocket();
int rcv_enable();
void rcv_disable();
bool rcv_char_available();
int xmit_char(uint8_t c);
int rcv_char(uint8_t *c);
private:
bool socket_inited = false;
int sockfd = -1;
int acceptfd = -1;
const char* path = 0;
};
#endif // CHAR_IO_H

View File

@ -49,7 +49,13 @@ EsccController::EsccController()
std::string backend_name = GET_STR_PROP("serial_backend");
this->ch_a->attach_backend(
(backend_name == "stdio") ? CHARIO_BE_STDIO : CHARIO_BE_NULL);
(backend_name == "stdio") ? CHARIO_BE_STDIO :
#ifdef _WIN32
#else
(backend_name == "socket") ? CHARIO_BE_SOCKET :
#endif
CHARIO_BE_NULL
);
this->ch_b->attach_backend(CHARIO_BE_NULL);
this->reg_ptr = 0;
@ -166,6 +172,12 @@ void EsccChannel::attach_backend(int id)
case CHARIO_BE_STDIO:
this->chario = std::unique_ptr<CharIoBackEnd> (new CharIoStdin);
break;
#ifdef _WIN32
#else
case CHARIO_BE_SOCKET:
this->chario = std::unique_ptr<CharIoBackEnd> (new CharIoSocket);
break;
#endif
default:
LOG_F(ERROR, "ESCC: unknown backend ID %d, using NULL instead", id);
this->chario = std::unique_ptr<CharIoBackEnd> (new CharIoNull);
@ -309,7 +321,7 @@ uint8_t EsccChannel::receive_byte()
return c;
}
static const vector<string> CharIoBackends = {"null", "stdio"};
static const vector<string> CharIoBackends = {"null", "stdio", "socket"};
static const PropMap Escc_Properties = {
{"serial_backend", new StrProperty("null", CharIoBackends)},

View File

@ -156,7 +156,7 @@ void AwacsScreamer::snd_ctrl_write(uint32_t offset, uint32_t value, int size)
subframe = (value >> 14) & 3;
reg_num = (value >> 20) & 7;
data = ((value >> 8) & 0xF00) | ((value >> 24) & 0xFF);
LOG_F(9, "Screamer subframe = %d, reg = %d, data = %08X\n",
LOG_F(9, "Screamer subframe = %d, reg = %d, data = %08X",
subframe, reg_num, data);
if (!subframe)
this->control_regs[reg_num] = data;

View File

@ -46,12 +46,12 @@ VideoCtrlBase::VideoCtrlBase(int width, int height)
);
if (this->display_wnd == NULL) {
LOG_F(ERROR, "Display: SDL_CreateWindow failed with %s\n", SDL_GetError());
LOG_F(ERROR, "Display: SDL_CreateWindow failed with %s", SDL_GetError());
}
this->renderer = SDL_CreateRenderer(this->display_wnd, -1, SDL_RENDERER_ACCELERATED);
if (this->renderer == NULL) {
LOG_F(ERROR, "Display: SDL_CreateRenderer failed with %s\n", SDL_GetError());
LOG_F(ERROR, "Display: SDL_CreateRenderer failed with %s", SDL_GetError());
}
SDL_SetRenderDrawColor(this->renderer, 0, 0, 0, 255);
@ -73,7 +73,7 @@ VideoCtrlBase::VideoCtrlBase(int width, int height)
);
if (this->disp_texture == NULL) {
LOG_F(ERROR, "Display: SDL_CreateTexture failed with %s\n", SDL_GetError());
LOG_F(ERROR, "Display: SDL_CreateTexture failed with %s", SDL_GetError());
}
}

View File

@ -49,7 +49,7 @@ int initialize_catalyst(std::string& id)
// allocate ROM region
if (!platinum_obj->add_rom_region(0xFFC00000, 0x400000)) {
LOG_F(ERROR, "Could not allocate ROM region!\n");
LOG_F(ERROR, "Could not allocate ROM region!");
return -1;
}

View File

@ -141,11 +141,11 @@ int MachineFactory::create(string& mach_id)
// post-initialize all devices
if (gMachineObj->postinit_devices()) {
LOG_F(ERROR, "Could not post-initialize devices!\n");
LOG_F(ERROR, "Could not post-initialize devices!");
return -1;
}
LOG_F(INFO, "Initialization completed.\n");
LOG_F(INFO, "Initialization completed.");
return 0;
}
@ -302,7 +302,7 @@ string MachineFactory::machine_name_from_rom(string& rom_filepath) {
rom_id = (rom_id_str[5] << 24) | (rom_id_str[6] << 16) |
(rom_id_str[7] << 8) | rom_id_str[8];
LOG_F(INFO, "The machine is identified as... %s\n",
LOG_F(INFO, "The machine is identified as... %s",
std::get<1>(rom_identity.at(rom_id)));
machine_name = std::get<0>(rom_identity.at(rom_id));

View File

@ -78,7 +78,7 @@ int initialize_gossamer(std::string& id)
// allocate ROM region
if (!grackle_obj->add_rom_region(0xFFC00000, 0x400000)) {
LOG_F(ERROR, "Could not allocate ROM region!\n");
LOG_F(ERROR, "Could not allocate ROM region!");
return -1;
}

View File

@ -62,19 +62,19 @@ int initialize_pdm(std::string& id)
// allocate ROM region
if (!hmc_obj->add_rom_region(0x40000000, 0x400000)) {
LOG_F(ERROR, "Could not allocate ROM region!\n");
LOG_F(ERROR, "Could not allocate ROM region!");
return -1;
}
// mirror ROM to 0xFFC00000 for a PowerPC CPU to start
if (!hmc_obj->add_mem_mirror(0xFFC00000, 0x40000000)) {
LOG_F(ERROR, "Could not create ROM mirror!\n");
LOG_F(ERROR, "Could not create ROM mirror!");
return -1;
}
// add 8MB of soldered on-board RAM
if (!hmc_obj->add_ram_region(0x00000000, 0x800000)) {
LOG_F(ERROR, "Could not allocate built-in RAM region!\n");
LOG_F(ERROR, "Could not allocate built-in RAM region!");
return -1;
}

View File

@ -56,7 +56,7 @@ int initialize_tnt(std::string& id)
// allocate ROM region
if (!memctrl_obj->add_rom_region(0xFFC00000, 0x400000)) {
LOG_F(ERROR, "Could not allocate ROM region!\n");
LOG_F(ERROR, "Could not allocate ROM region!");
return -1;
}

View File

@ -1248,7 +1248,7 @@ namespace loguru
if (message.verbosity == Verbosity_FATAL) {
auto st = loguru::stacktrace(stack_trace_skip + 2);
if (!st.empty()) {
RAW_LOG_F(ERROR, "Stack trace:\n" LOGURU_FMT(s) "", st.c_str());
RAW_LOG_F(ERROR, "Stack trace:" LOGURU_FMT(s) "", st.c_str());
}
auto ec = loguru::get_error_context();