dingusppc/devices/serial/chario.cpp

481 lines
12 KiB
C++
Raw Normal View History

2022-05-07 19:38:27 +00:00
/*
DingusPPC - The Experimental PowerPC Macintosh emulator
Copyright (C) 2018-22 divingkatae and maximum
(theweirdo) spatium
(Contact divingkatae#1017 or powermax#2286 on Discord for more info)
This program is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with this program. If not, see <https://www.gnu.org/licenses/>.
*/
/** Character I/O backend implementations. */
#include <devices/serial/chario.h>
#include <loguru.hpp>
#include <cinttypes>
2022-05-21 13:01:50 +00:00
#include <cstring>
2022-05-07 19:38:27 +00:00
#include <memory>
bool CharIoNull::rcv_char_available()
{
return false;
}
int CharIoNull::xmit_char(uint8_t c)
{
return 0;
}
int CharIoNull::rcv_char(uint8_t *c)
{
*c = 0xFF;
return 0;
}
//======================== STDIO character I/O backend ========================
#ifdef _WIN32
#include <fcntl.h>
#include <io.h>
#include <windows.h>
HANDLE hInput = GetStdHandle(STD_INPUT_HANDLE);
HANDLE hOutput = GetStdHandle(STD_OUTPUT_HANDLE);
DWORD old_in_mode, old_out_mode;
int old_stdin_trans_mode;
Add socket type for serial_backend With the option --serial_backend=socket, input and output to a serial port will use a SOCK_STREAM type UNIX domain socket. This allows you to do Open Firmware in one window, while the first window can be used for dingusppc debugger. Other fixes: - Added SIGTERM handler so that if the user force quits dingusppc, the terminal settings are properly restored. A user needs to force quit when --serial_backend=stdio and Open Firmware is taking input from ttya. If terminal settings are not restored, then running dingusppc after a force quit will cause Control-C to not work when --serial_backend is not stdio. - Added a couple numbers to rcv_char_available - 15 is the number of consecutive characters that can processed. 400 is the total number of calls to rcv_char_available after 15 consecutive characters have been read before additional characters can be read. This delay in processing additional characters allows pasting arbitrarily large amounts of text into Open Firmware. A real serial port terminal app might have a text pacing option to limit the number of output characters per second but that is not an option since the emulator is not limiting character data to a baud rate. Related Notes: The socket file is created when dingusppc starts. The socket file is named dingusppcsocket and is created in the current working directory (usually where the executable is located and where the dingusppc.log, nvram.bin, and pram.bin files are created). The socket file is not visible in the Finder. You can see it in the terminal using the ls command. The socket file can be used with the following command in a new terminal window: socat UNIX-CLIENT:dingussocket -,cs8,parenb=0,echo=0,icanon=0,isig=0,icrnl=0 When dingusppc quits, the socat command ends. Other notes: The dingusppc --debugger option causes dingusppc to enter the debugger before Open Firmware outputs anything. You can connect to the socket while dingusppc is in the debugger. Then enter the go command to leave the debugger and start Open Firmware. However, since the startup sound takes a long time, you can probably connect to the socket before Open Firmware starts even without the --debugger option. It's like with a real Power Mac - you have a few seconds to hold Command-Option-O-F except in this case you have a few seconds to press the up arrow and press enter (for executing the last command from the terminal command history) and if you do it too late you'll still get into Open Firmware if auto-boot? was previously set to false using the dingusppc debugger which is actually the only way to get into Open Firmware since a keyboard is currently not emulated?). To set ttya as the input and output device in Open Firmware, you can use the setenv command in the dingusppc debugger. The device path needs to be longer than the current device path (because code for handling shortening of the paths is currently not implemented). For example, ttya can replace kbd for the input-device, but to replace screen for the output-device you need to add some extra characters like this: ttya,11 (I think the number is for baud but we're not using a real serial port so baud doesn't matter). Future ideas: - Have dingusppc execute the socat command for you so that it opens a terminal window before Open Firmware starts. - Add another --serial_backend for the printer port (ttyb) since now we have more than one type of serial backend. If both serial ports use socket backend, then a different name for the second socket is required. - Have an option to make dingusppc block until something connects to the socket (this means calling accept after listen instead of after select). - Test compatibility with serial port socket created by Parallels Desktop virtual machines in macOS. - Find a solution that works with Windows. - Test with Linux. - Create a serial_backend type for tty devices. I suppose maybe socat can pipe the file socket to tty but a direct connection might be easier to setup. - Allow using a socket created by some other app (for example, socat UNIX-LISTEN). This means dingusppc will assume the client role and will call connect instead of accept.
2022-08-14 13:48:16 +00:00
void CharIoStdin::mysig_handler(int signum) {
SetStdHandle(signum, hInput);
SetStdHandle(signum, hOutput);
}
int CharIoStdin::rcv_enable() {
if (this->stdio_inited)
return 0;
GetConsoleMode(hInput, &old_in_mode);
GetConsoleMode(hOutput, &old_out_mode);
DWORD new_in_mode = old_in_mode;
new_in_mode &= ~ENABLE_ECHO_INPUT;
new_in_mode &= ~ENABLE_LINE_INPUT;
new_in_mode &= ~ENABLE_PROCESSED_INPUT;
new_in_mode |= ENABLE_EXTENDED_FLAGS;
new_in_mode |= ENABLE_INSERT_MODE;
new_in_mode |= ENABLE_VIRTUAL_TERMINAL_INPUT;
SetConsoleMode(hInput, new_in_mode);
SetConsoleMode(hOutput, old_out_mode | ENABLE_VIRTUAL_TERMINAL_PROCESSING);
// disable automatic CRLF translation
old_stdin_trans_mode = _setmode(_fileno(stdin), _O_BINARY);
this->stdio_inited = true;
LOG_F(INFO, "Winterm: receiver initialized");
return 0;
}
void CharIoStdin::rcv_disable() {
if (!this->stdio_inited)
return;
// restore original console mode
SetConsoleMode(hInput, old_in_mode);
SetConsoleMode(hOutput, old_out_mode);
// restore original translation mode
_setmode(_fileno(stdin), old_stdin_trans_mode);
this->stdio_inited = false;
LOG_F(INFO, "Winterm: receiver disabled");
}
bool CharIoStdin::rcv_char_available() {
DWORD events;
INPUT_RECORD buffer;
PeekConsoleInput(hInput, &buffer, 1, &events);
return !!(events > 0);
}
int CharIoStdin::xmit_char(uint8_t c) {
_write(_fileno(stdout), &c, 1);
return 0;
}
int CharIoStdin::rcv_char(uint8_t* c) {
_read(_fileno(stdin), c, 1);
return 0;
}
#else // non-Windows OS (Linux, mac OS etc.)
2022-05-07 19:38:27 +00:00
#include <stdio.h>
2022-05-21 13:01:50 +00:00
#include <sys/time.h>
#include <sys/types.h>
#include <sys/select.h>
2022-05-07 19:38:27 +00:00
#include <unistd.h>
static struct sigaction old_act_sigint, new_act_sigint;
static struct sigaction old_act_sigterm, new_act_sigterm;
static struct termios orig_termios;
2022-05-07 19:38:27 +00:00
Add socket type for serial_backend With the option --serial_backend=socket, input and output to a serial port will use a SOCK_STREAM type UNIX domain socket. This allows you to do Open Firmware in one window, while the first window can be used for dingusppc debugger. Other fixes: - Added SIGTERM handler so that if the user force quits dingusppc, the terminal settings are properly restored. A user needs to force quit when --serial_backend=stdio and Open Firmware is taking input from ttya. If terminal settings are not restored, then running dingusppc after a force quit will cause Control-C to not work when --serial_backend is not stdio. - Added a couple numbers to rcv_char_available - 15 is the number of consecutive characters that can processed. 400 is the total number of calls to rcv_char_available after 15 consecutive characters have been read before additional characters can be read. This delay in processing additional characters allows pasting arbitrarily large amounts of text into Open Firmware. A real serial port terminal app might have a text pacing option to limit the number of output characters per second but that is not an option since the emulator is not limiting character data to a baud rate. Related Notes: The socket file is created when dingusppc starts. The socket file is named dingusppcsocket and is created in the current working directory (usually where the executable is located and where the dingusppc.log, nvram.bin, and pram.bin files are created). The socket file is not visible in the Finder. You can see it in the terminal using the ls command. The socket file can be used with the following command in a new terminal window: socat UNIX-CLIENT:dingussocket -,cs8,parenb=0,echo=0,icanon=0,isig=0,icrnl=0 When dingusppc quits, the socat command ends. Other notes: The dingusppc --debugger option causes dingusppc to enter the debugger before Open Firmware outputs anything. You can connect to the socket while dingusppc is in the debugger. Then enter the go command to leave the debugger and start Open Firmware. However, since the startup sound takes a long time, you can probably connect to the socket before Open Firmware starts even without the --debugger option. It's like with a real Power Mac - you have a few seconds to hold Command-Option-O-F except in this case you have a few seconds to press the up arrow and press enter (for executing the last command from the terminal command history) and if you do it too late you'll still get into Open Firmware if auto-boot? was previously set to false using the dingusppc debugger which is actually the only way to get into Open Firmware since a keyboard is currently not emulated?). To set ttya as the input and output device in Open Firmware, you can use the setenv command in the dingusppc debugger. The device path needs to be longer than the current device path (because code for handling shortening of the paths is currently not implemented). For example, ttya can replace kbd for the input-device, but to replace screen for the output-device you need to add some extra characters like this: ttya,11 (I think the number is for baud but we're not using a real serial port so baud doesn't matter). Future ideas: - Have dingusppc execute the socat command for you so that it opens a terminal window before Open Firmware starts. - Add another --serial_backend for the printer port (ttyb) since now we have more than one type of serial backend. If both serial ports use socket backend, then a different name for the second socket is required. - Have an option to make dingusppc block until something connects to the socket (this means calling accept after listen instead of after select). - Test compatibility with serial port socket created by Parallels Desktop virtual machines in macOS. - Find a solution that works with Windows. - Test with Linux. - Create a serial_backend type for tty devices. I suppose maybe socat can pipe the file socket to tty but a direct connection might be easier to setup. - Allow using a socket created by some other app (for example, socat UNIX-LISTEN). This means dingusppc will assume the client role and will call connect instead of accept.
2022-08-14 13:48:16 +00:00
void CharIoStdin::mysig_handler(int signum)
2022-05-07 19:38:27 +00:00
{
// restore original terminal state
tcsetattr(STDIN_FILENO, TCSANOW, &orig_termios);
// restore original signal handler for SIGINT
Add socket type for serial_backend With the option --serial_backend=socket, input and output to a serial port will use a SOCK_STREAM type UNIX domain socket. This allows you to do Open Firmware in one window, while the first window can be used for dingusppc debugger. Other fixes: - Added SIGTERM handler so that if the user force quits dingusppc, the terminal settings are properly restored. A user needs to force quit when --serial_backend=stdio and Open Firmware is taking input from ttya. If terminal settings are not restored, then running dingusppc after a force quit will cause Control-C to not work when --serial_backend is not stdio. - Added a couple numbers to rcv_char_available - 15 is the number of consecutive characters that can processed. 400 is the total number of calls to rcv_char_available after 15 consecutive characters have been read before additional characters can be read. This delay in processing additional characters allows pasting arbitrarily large amounts of text into Open Firmware. A real serial port terminal app might have a text pacing option to limit the number of output characters per second but that is not an option since the emulator is not limiting character data to a baud rate. Related Notes: The socket file is created when dingusppc starts. The socket file is named dingusppcsocket and is created in the current working directory (usually where the executable is located and where the dingusppc.log, nvram.bin, and pram.bin files are created). The socket file is not visible in the Finder. You can see it in the terminal using the ls command. The socket file can be used with the following command in a new terminal window: socat UNIX-CLIENT:dingussocket -,cs8,parenb=0,echo=0,icanon=0,isig=0,icrnl=0 When dingusppc quits, the socat command ends. Other notes: The dingusppc --debugger option causes dingusppc to enter the debugger before Open Firmware outputs anything. You can connect to the socket while dingusppc is in the debugger. Then enter the go command to leave the debugger and start Open Firmware. However, since the startup sound takes a long time, you can probably connect to the socket before Open Firmware starts even without the --debugger option. It's like with a real Power Mac - you have a few seconds to hold Command-Option-O-F except in this case you have a few seconds to press the up arrow and press enter (for executing the last command from the terminal command history) and if you do it too late you'll still get into Open Firmware if auto-boot? was previously set to false using the dingusppc debugger which is actually the only way to get into Open Firmware since a keyboard is currently not emulated?). To set ttya as the input and output device in Open Firmware, you can use the setenv command in the dingusppc debugger. The device path needs to be longer than the current device path (because code for handling shortening of the paths is currently not implemented). For example, ttya can replace kbd for the input-device, but to replace screen for the output-device you need to add some extra characters like this: ttya,11 (I think the number is for baud but we're not using a real serial port so baud doesn't matter). Future ideas: - Have dingusppc execute the socat command for you so that it opens a terminal window before Open Firmware starts. - Add another --serial_backend for the printer port (ttyb) since now we have more than one type of serial backend. If both serial ports use socket backend, then a different name for the second socket is required. - Have an option to make dingusppc block until something connects to the socket (this means calling accept after listen instead of after select). - Test compatibility with serial port socket created by Parallels Desktop virtual machines in macOS. - Find a solution that works with Windows. - Test with Linux. - Create a serial_backend type for tty devices. I suppose maybe socat can pipe the file socket to tty but a direct connection might be easier to setup. - Allow using a socket created by some other app (for example, socat UNIX-LISTEN). This means dingusppc will assume the client role and will call connect instead of accept.
2022-08-14 13:48:16 +00:00
signal(SIGINT, old_act_sigint.sa_handler);
signal(SIGTERM, old_act_sigterm.sa_handler);
2022-05-07 19:38:27 +00:00
LOG_F(INFO, "Old terminal state restored, SIG#=%d", signum);
// re-post signal
raise(signum);
}
int CharIoStdin::rcv_enable()
{
if (this->stdio_inited)
return 0;
// save original terminal state
tcgetattr(STDIN_FILENO, &orig_termios);
struct termios new_termios = orig_termios;
new_termios.c_cflag &= ~(CSIZE | PARENB);
new_termios.c_cflag |= CS8;
new_termios.c_lflag &= ~(ECHO | ICANON | ISIG);
2022-05-07 19:38:27 +00:00
new_termios.c_iflag &= ~(ICRNL);
tcsetattr(STDIN_FILENO, TCSANOW, &new_termios);
// save original signal handler for SIGINT
// then redirect SIGINT to new handler
Add socket type for serial_backend With the option --serial_backend=socket, input and output to a serial port will use a SOCK_STREAM type UNIX domain socket. This allows you to do Open Firmware in one window, while the first window can be used for dingusppc debugger. Other fixes: - Added SIGTERM handler so that if the user force quits dingusppc, the terminal settings are properly restored. A user needs to force quit when --serial_backend=stdio and Open Firmware is taking input from ttya. If terminal settings are not restored, then running dingusppc after a force quit will cause Control-C to not work when --serial_backend is not stdio. - Added a couple numbers to rcv_char_available - 15 is the number of consecutive characters that can processed. 400 is the total number of calls to rcv_char_available after 15 consecutive characters have been read before additional characters can be read. This delay in processing additional characters allows pasting arbitrarily large amounts of text into Open Firmware. A real serial port terminal app might have a text pacing option to limit the number of output characters per second but that is not an option since the emulator is not limiting character data to a baud rate. Related Notes: The socket file is created when dingusppc starts. The socket file is named dingusppcsocket and is created in the current working directory (usually where the executable is located and where the dingusppc.log, nvram.bin, and pram.bin files are created). The socket file is not visible in the Finder. You can see it in the terminal using the ls command. The socket file can be used with the following command in a new terminal window: socat UNIX-CLIENT:dingussocket -,cs8,parenb=0,echo=0,icanon=0,isig=0,icrnl=0 When dingusppc quits, the socat command ends. Other notes: The dingusppc --debugger option causes dingusppc to enter the debugger before Open Firmware outputs anything. You can connect to the socket while dingusppc is in the debugger. Then enter the go command to leave the debugger and start Open Firmware. However, since the startup sound takes a long time, you can probably connect to the socket before Open Firmware starts even without the --debugger option. It's like with a real Power Mac - you have a few seconds to hold Command-Option-O-F except in this case you have a few seconds to press the up arrow and press enter (for executing the last command from the terminal command history) and if you do it too late you'll still get into Open Firmware if auto-boot? was previously set to false using the dingusppc debugger which is actually the only way to get into Open Firmware since a keyboard is currently not emulated?). To set ttya as the input and output device in Open Firmware, you can use the setenv command in the dingusppc debugger. The device path needs to be longer than the current device path (because code for handling shortening of the paths is currently not implemented). For example, ttya can replace kbd for the input-device, but to replace screen for the output-device you need to add some extra characters like this: ttya,11 (I think the number is for baud but we're not using a real serial port so baud doesn't matter). Future ideas: - Have dingusppc execute the socat command for you so that it opens a terminal window before Open Firmware starts. - Add another --serial_backend for the printer port (ttyb) since now we have more than one type of serial backend. If both serial ports use socket backend, then a different name for the second socket is required. - Have an option to make dingusppc block until something connects to the socket (this means calling accept after listen instead of after select). - Test compatibility with serial port socket created by Parallels Desktop virtual machines in macOS. - Find a solution that works with Windows. - Test with Linux. - Create a serial_backend type for tty devices. I suppose maybe socat can pipe the file socket to tty but a direct connection might be easier to setup. - Allow using a socket created by some other app (for example, socat UNIX-LISTEN). This means dingusppc will assume the client role and will call connect instead of accept.
2022-08-14 13:48:16 +00:00
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);
2022-05-07 19:38:27 +00:00
this->stdio_inited = true;
return 0;
}
void CharIoStdin::rcv_disable()
{
if (!this->stdio_inited)
return;
// restore original terminal state
tcsetattr(STDIN_FILENO, TCSANOW, &orig_termios);
// restore original signal handler for SIGINT
Add socket type for serial_backend With the option --serial_backend=socket, input and output to a serial port will use a SOCK_STREAM type UNIX domain socket. This allows you to do Open Firmware in one window, while the first window can be used for dingusppc debugger. Other fixes: - Added SIGTERM handler so that if the user force quits dingusppc, the terminal settings are properly restored. A user needs to force quit when --serial_backend=stdio and Open Firmware is taking input from ttya. If terminal settings are not restored, then running dingusppc after a force quit will cause Control-C to not work when --serial_backend is not stdio. - Added a couple numbers to rcv_char_available - 15 is the number of consecutive characters that can processed. 400 is the total number of calls to rcv_char_available after 15 consecutive characters have been read before additional characters can be read. This delay in processing additional characters allows pasting arbitrarily large amounts of text into Open Firmware. A real serial port terminal app might have a text pacing option to limit the number of output characters per second but that is not an option since the emulator is not limiting character data to a baud rate. Related Notes: The socket file is created when dingusppc starts. The socket file is named dingusppcsocket and is created in the current working directory (usually where the executable is located and where the dingusppc.log, nvram.bin, and pram.bin files are created). The socket file is not visible in the Finder. You can see it in the terminal using the ls command. The socket file can be used with the following command in a new terminal window: socat UNIX-CLIENT:dingussocket -,cs8,parenb=0,echo=0,icanon=0,isig=0,icrnl=0 When dingusppc quits, the socat command ends. Other notes: The dingusppc --debugger option causes dingusppc to enter the debugger before Open Firmware outputs anything. You can connect to the socket while dingusppc is in the debugger. Then enter the go command to leave the debugger and start Open Firmware. However, since the startup sound takes a long time, you can probably connect to the socket before Open Firmware starts even without the --debugger option. It's like with a real Power Mac - you have a few seconds to hold Command-Option-O-F except in this case you have a few seconds to press the up arrow and press enter (for executing the last command from the terminal command history) and if you do it too late you'll still get into Open Firmware if auto-boot? was previously set to false using the dingusppc debugger which is actually the only way to get into Open Firmware since a keyboard is currently not emulated?). To set ttya as the input and output device in Open Firmware, you can use the setenv command in the dingusppc debugger. The device path needs to be longer than the current device path (because code for handling shortening of the paths is currently not implemented). For example, ttya can replace kbd for the input-device, but to replace screen for the output-device you need to add some extra characters like this: ttya,11 (I think the number is for baud but we're not using a real serial port so baud doesn't matter). Future ideas: - Have dingusppc execute the socat command for you so that it opens a terminal window before Open Firmware starts. - Add another --serial_backend for the printer port (ttyb) since now we have more than one type of serial backend. If both serial ports use socket backend, then a different name for the second socket is required. - Have an option to make dingusppc block until something connects to the socket (this means calling accept after listen instead of after select). - Test compatibility with serial port socket created by Parallels Desktop virtual machines in macOS. - Find a solution that works with Windows. - Test with Linux. - Create a serial_backend type for tty devices. I suppose maybe socat can pipe the file socket to tty but a direct connection might be easier to setup. - Allow using a socket created by some other app (for example, socat UNIX-LISTEN). This means dingusppc will assume the client role and will call connect instead of accept.
2022-08-14 13:48:16 +00:00
signal(SIGINT, old_act_sigint.sa_handler);
// restore original signal handler for SIGTERM
signal(SIGTERM, old_act_sigterm.sa_handler);
2022-05-07 19:38:27 +00:00
this->stdio_inited = false;
}
bool CharIoStdin::rcv_char_available()
{
Add socket type for serial_backend With the option --serial_backend=socket, input and output to a serial port will use a SOCK_STREAM type UNIX domain socket. This allows you to do Open Firmware in one window, while the first window can be used for dingusppc debugger. Other fixes: - Added SIGTERM handler so that if the user force quits dingusppc, the terminal settings are properly restored. A user needs to force quit when --serial_backend=stdio and Open Firmware is taking input from ttya. If terminal settings are not restored, then running dingusppc after a force quit will cause Control-C to not work when --serial_backend is not stdio. - Added a couple numbers to rcv_char_available - 15 is the number of consecutive characters that can processed. 400 is the total number of calls to rcv_char_available after 15 consecutive characters have been read before additional characters can be read. This delay in processing additional characters allows pasting arbitrarily large amounts of text into Open Firmware. A real serial port terminal app might have a text pacing option to limit the number of output characters per second but that is not an option since the emulator is not limiting character data to a baud rate. Related Notes: The socket file is created when dingusppc starts. The socket file is named dingusppcsocket and is created in the current working directory (usually where the executable is located and where the dingusppc.log, nvram.bin, and pram.bin files are created). The socket file is not visible in the Finder. You can see it in the terminal using the ls command. The socket file can be used with the following command in a new terminal window: socat UNIX-CLIENT:dingussocket -,cs8,parenb=0,echo=0,icanon=0,isig=0,icrnl=0 When dingusppc quits, the socat command ends. Other notes: The dingusppc --debugger option causes dingusppc to enter the debugger before Open Firmware outputs anything. You can connect to the socket while dingusppc is in the debugger. Then enter the go command to leave the debugger and start Open Firmware. However, since the startup sound takes a long time, you can probably connect to the socket before Open Firmware starts even without the --debugger option. It's like with a real Power Mac - you have a few seconds to hold Command-Option-O-F except in this case you have a few seconds to press the up arrow and press enter (for executing the last command from the terminal command history) and if you do it too late you'll still get into Open Firmware if auto-boot? was previously set to false using the dingusppc debugger which is actually the only way to get into Open Firmware since a keyboard is currently not emulated?). To set ttya as the input and output device in Open Firmware, you can use the setenv command in the dingusppc debugger. The device path needs to be longer than the current device path (because code for handling shortening of the paths is currently not implemented). For example, ttya can replace kbd for the input-device, but to replace screen for the output-device you need to add some extra characters like this: ttya,11 (I think the number is for baud but we're not using a real serial port so baud doesn't matter). Future ideas: - Have dingusppc execute the socat command for you so that it opens a terminal window before Open Firmware starts. - Add another --serial_backend for the printer port (ttyb) since now we have more than one type of serial backend. If both serial ports use socket backend, then a different name for the second socket is required. - Have an option to make dingusppc block until something connects to the socket (this means calling accept after listen instead of after select). - Test compatibility with serial port socket created by Parallels Desktop virtual machines in macOS. - Find a solution that works with Windows. - Test with Linux. - Create a serial_backend type for tty devices. I suppose maybe socat can pipe the file socket to tty but a direct connection might be easier to setup. - Allow using a socket created by some other app (for example, socat UNIX-LISTEN). This means dingusppc will assume the client role and will call connect instead of accept.
2022-08-14 13:48:16 +00:00
static int consecutivechars = 0;
if (consecutivechars >= 15) {
consecutivechars++;
if (consecutivechars >= 400)
consecutivechars = 0;
return 0;
}
2022-05-07 19:38:27 +00:00
fd_set readfds;
FD_ZERO(&readfds);
FD_SET(STDIN_FILENO, &readfds);
struct timeval timeout;
timeout.tv_sec = 0;
timeout.tv_usec = 0;
int sel_rv = select(1, &readfds, NULL, NULL, &timeout);
Add socket type for serial_backend With the option --serial_backend=socket, input and output to a serial port will use a SOCK_STREAM type UNIX domain socket. This allows you to do Open Firmware in one window, while the first window can be used for dingusppc debugger. Other fixes: - Added SIGTERM handler so that if the user force quits dingusppc, the terminal settings are properly restored. A user needs to force quit when --serial_backend=stdio and Open Firmware is taking input from ttya. If terminal settings are not restored, then running dingusppc after a force quit will cause Control-C to not work when --serial_backend is not stdio. - Added a couple numbers to rcv_char_available - 15 is the number of consecutive characters that can processed. 400 is the total number of calls to rcv_char_available after 15 consecutive characters have been read before additional characters can be read. This delay in processing additional characters allows pasting arbitrarily large amounts of text into Open Firmware. A real serial port terminal app might have a text pacing option to limit the number of output characters per second but that is not an option since the emulator is not limiting character data to a baud rate. Related Notes: The socket file is created when dingusppc starts. The socket file is named dingusppcsocket and is created in the current working directory (usually where the executable is located and where the dingusppc.log, nvram.bin, and pram.bin files are created). The socket file is not visible in the Finder. You can see it in the terminal using the ls command. The socket file can be used with the following command in a new terminal window: socat UNIX-CLIENT:dingussocket -,cs8,parenb=0,echo=0,icanon=0,isig=0,icrnl=0 When dingusppc quits, the socat command ends. Other notes: The dingusppc --debugger option causes dingusppc to enter the debugger before Open Firmware outputs anything. You can connect to the socket while dingusppc is in the debugger. Then enter the go command to leave the debugger and start Open Firmware. However, since the startup sound takes a long time, you can probably connect to the socket before Open Firmware starts even without the --debugger option. It's like with a real Power Mac - you have a few seconds to hold Command-Option-O-F except in this case you have a few seconds to press the up arrow and press enter (for executing the last command from the terminal command history) and if you do it too late you'll still get into Open Firmware if auto-boot? was previously set to false using the dingusppc debugger which is actually the only way to get into Open Firmware since a keyboard is currently not emulated?). To set ttya as the input and output device in Open Firmware, you can use the setenv command in the dingusppc debugger. The device path needs to be longer than the current device path (because code for handling shortening of the paths is currently not implemented). For example, ttya can replace kbd for the input-device, but to replace screen for the output-device you need to add some extra characters like this: ttya,11 (I think the number is for baud but we're not using a real serial port so baud doesn't matter). Future ideas: - Have dingusppc execute the socat command for you so that it opens a terminal window before Open Firmware starts. - Add another --serial_backend for the printer port (ttyb) since now we have more than one type of serial backend. If both serial ports use socket backend, then a different name for the second socket is required. - Have an option to make dingusppc block until something connects to the socket (this means calling accept after listen instead of after select). - Test compatibility with serial port socket created by Parallels Desktop virtual machines in macOS. - Find a solution that works with Windows. - Test with Linux. - Create a serial_backend type for tty devices. I suppose maybe socat can pipe the file socket to tty but a direct connection might be easier to setup. - Allow using a socket created by some other app (for example, socat UNIX-LISTEN). This means dingusppc will assume the client role and will call connect instead of accept.
2022-08-14 13:48:16 +00:00
if (sel_rv > 0)
consecutivechars++;
else
consecutivechars = 0;
2022-05-07 19:38:27 +00:00
return sel_rv > 0;
}
int CharIoStdin::xmit_char(uint8_t c)
{
write(STDOUT_FILENO, &c, 1);
return 0;
}
int CharIoStdin::rcv_char(uint8_t *c)
{
read(STDIN_FILENO, c, 1);
return 0;
}
#endif
Add socket type for serial_backend With the option --serial_backend=socket, input and output to a serial port will use a SOCK_STREAM type UNIX domain socket. This allows you to do Open Firmware in one window, while the first window can be used for dingusppc debugger. Other fixes: - Added SIGTERM handler so that if the user force quits dingusppc, the terminal settings are properly restored. A user needs to force quit when --serial_backend=stdio and Open Firmware is taking input from ttya. If terminal settings are not restored, then running dingusppc after a force quit will cause Control-C to not work when --serial_backend is not stdio. - Added a couple numbers to rcv_char_available - 15 is the number of consecutive characters that can processed. 400 is the total number of calls to rcv_char_available after 15 consecutive characters have been read before additional characters can be read. This delay in processing additional characters allows pasting arbitrarily large amounts of text into Open Firmware. A real serial port terminal app might have a text pacing option to limit the number of output characters per second but that is not an option since the emulator is not limiting character data to a baud rate. Related Notes: The socket file is created when dingusppc starts. The socket file is named dingusppcsocket and is created in the current working directory (usually where the executable is located and where the dingusppc.log, nvram.bin, and pram.bin files are created). The socket file is not visible in the Finder. You can see it in the terminal using the ls command. The socket file can be used with the following command in a new terminal window: socat UNIX-CLIENT:dingussocket -,cs8,parenb=0,echo=0,icanon=0,isig=0,icrnl=0 When dingusppc quits, the socat command ends. Other notes: The dingusppc --debugger option causes dingusppc to enter the debugger before Open Firmware outputs anything. You can connect to the socket while dingusppc is in the debugger. Then enter the go command to leave the debugger and start Open Firmware. However, since the startup sound takes a long time, you can probably connect to the socket before Open Firmware starts even without the --debugger option. It's like with a real Power Mac - you have a few seconds to hold Command-Option-O-F except in this case you have a few seconds to press the up arrow and press enter (for executing the last command from the terminal command history) and if you do it too late you'll still get into Open Firmware if auto-boot? was previously set to false using the dingusppc debugger which is actually the only way to get into Open Firmware since a keyboard is currently not emulated?). To set ttya as the input and output device in Open Firmware, you can use the setenv command in the dingusppc debugger. The device path needs to be longer than the current device path (because code for handling shortening of the paths is currently not implemented). For example, ttya can replace kbd for the input-device, but to replace screen for the output-device you need to add some extra characters like this: ttya,11 (I think the number is for baud but we're not using a real serial port so baud doesn't matter). Future ideas: - Have dingusppc execute the socat command for you so that it opens a terminal window before Open Firmware starts. - Add another --serial_backend for the printer port (ttyb) since now we have more than one type of serial backend. If both serial ports use socket backend, then a different name for the second socket is required. - Have an option to make dingusppc block until something connects to the socket (this means calling accept after listen instead of after select). - Test compatibility with serial port socket created by Parallels Desktop virtual machines in macOS. - Find a solution that works with Windows. - Test with Linux. - Create a serial_backend type for tty devices. I suppose maybe socat can pipe the file socket to tty but a direct connection might be easier to setup. - Allow using a socket created by some other app (for example, socat UNIX-LISTEN). This means dingusppc will assume the client role and will call connect instead of accept.
2022-08-14 13:48:16 +00:00
//======================== 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 >= 800)
Add socket type for serial_backend With the option --serial_backend=socket, input and output to a serial port will use a SOCK_STREAM type UNIX domain socket. This allows you to do Open Firmware in one window, while the first window can be used for dingusppc debugger. Other fixes: - Added SIGTERM handler so that if the user force quits dingusppc, the terminal settings are properly restored. A user needs to force quit when --serial_backend=stdio and Open Firmware is taking input from ttya. If terminal settings are not restored, then running dingusppc after a force quit will cause Control-C to not work when --serial_backend is not stdio. - Added a couple numbers to rcv_char_available - 15 is the number of consecutive characters that can processed. 400 is the total number of calls to rcv_char_available after 15 consecutive characters have been read before additional characters can be read. This delay in processing additional characters allows pasting arbitrarily large amounts of text into Open Firmware. A real serial port terminal app might have a text pacing option to limit the number of output characters per second but that is not an option since the emulator is not limiting character data to a baud rate. Related Notes: The socket file is created when dingusppc starts. The socket file is named dingusppcsocket and is created in the current working directory (usually where the executable is located and where the dingusppc.log, nvram.bin, and pram.bin files are created). The socket file is not visible in the Finder. You can see it in the terminal using the ls command. The socket file can be used with the following command in a new terminal window: socat UNIX-CLIENT:dingussocket -,cs8,parenb=0,echo=0,icanon=0,isig=0,icrnl=0 When dingusppc quits, the socat command ends. Other notes: The dingusppc --debugger option causes dingusppc to enter the debugger before Open Firmware outputs anything. You can connect to the socket while dingusppc is in the debugger. Then enter the go command to leave the debugger and start Open Firmware. However, since the startup sound takes a long time, you can probably connect to the socket before Open Firmware starts even without the --debugger option. It's like with a real Power Mac - you have a few seconds to hold Command-Option-O-F except in this case you have a few seconds to press the up arrow and press enter (for executing the last command from the terminal command history) and if you do it too late you'll still get into Open Firmware if auto-boot? was previously set to false using the dingusppc debugger which is actually the only way to get into Open Firmware since a keyboard is currently not emulated?). To set ttya as the input and output device in Open Firmware, you can use the setenv command in the dingusppc debugger. The device path needs to be longer than the current device path (because code for handling shortening of the paths is currently not implemented). For example, ttya can replace kbd for the input-device, but to replace screen for the output-device you need to add some extra characters like this: ttya,11 (I think the number is for baud but we're not using a real serial port so baud doesn't matter). Future ideas: - Have dingusppc execute the socat command for you so that it opens a terminal window before Open Firmware starts. - Add another --serial_backend for the printer port (ttyb) since now we have more than one type of serial backend. If both serial ports use socket backend, then a different name for the second socket is required. - Have an option to make dingusppc block until something connects to the socket (this means calling accept after listen instead of after select). - Test compatibility with serial port socket created by Parallels Desktop virtual machines in macOS. - Find a solution that works with Windows. - Test with Linux. - Create a serial_backend type for tty devices. I suppose maybe socat can pipe the file socket to tty but a direct connection might be easier to setup. - Allow using a socket created by some other app (for example, socat UNIX-LISTEN). This means dingusppc will assume the client role and will call connect instead of accept.
2022-08-14 13:48:16 +00:00
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 = (int)recv(sockfd, &c, 1, 0);
if (received == -1) {
if (acceptfd == -1) {
//LOG_F(INFO, "socket sock read (not accepted yet) err: %s", strerror(errno)); // this happens once before accept
}
else {
LOG_F(INFO, "socket sock read err: %s", strerror(errno)); // should never happen
}
Add socket type for serial_backend With the option --serial_backend=socket, input and output to a serial port will use a SOCK_STREAM type UNIX domain socket. This allows you to do Open Firmware in one window, while the first window can be used for dingusppc debugger. Other fixes: - Added SIGTERM handler so that if the user force quits dingusppc, the terminal settings are properly restored. A user needs to force quit when --serial_backend=stdio and Open Firmware is taking input from ttya. If terminal settings are not restored, then running dingusppc after a force quit will cause Control-C to not work when --serial_backend is not stdio. - Added a couple numbers to rcv_char_available - 15 is the number of consecutive characters that can processed. 400 is the total number of calls to rcv_char_available after 15 consecutive characters have been read before additional characters can be read. This delay in processing additional characters allows pasting arbitrarily large amounts of text into Open Firmware. A real serial port terminal app might have a text pacing option to limit the number of output characters per second but that is not an option since the emulator is not limiting character data to a baud rate. Related Notes: The socket file is created when dingusppc starts. The socket file is named dingusppcsocket and is created in the current working directory (usually where the executable is located and where the dingusppc.log, nvram.bin, and pram.bin files are created). The socket file is not visible in the Finder. You can see it in the terminal using the ls command. The socket file can be used with the following command in a new terminal window: socat UNIX-CLIENT:dingussocket -,cs8,parenb=0,echo=0,icanon=0,isig=0,icrnl=0 When dingusppc quits, the socat command ends. Other notes: The dingusppc --debugger option causes dingusppc to enter the debugger before Open Firmware outputs anything. You can connect to the socket while dingusppc is in the debugger. Then enter the go command to leave the debugger and start Open Firmware. However, since the startup sound takes a long time, you can probably connect to the socket before Open Firmware starts even without the --debugger option. It's like with a real Power Mac - you have a few seconds to hold Command-Option-O-F except in this case you have a few seconds to press the up arrow and press enter (for executing the last command from the terminal command history) and if you do it too late you'll still get into Open Firmware if auto-boot? was previously set to false using the dingusppc debugger which is actually the only way to get into Open Firmware since a keyboard is currently not emulated?). To set ttya as the input and output device in Open Firmware, you can use the setenv command in the dingusppc debugger. The device path needs to be longer than the current device path (because code for handling shortening of the paths is currently not implemented). For example, ttya can replace kbd for the input-device, but to replace screen for the output-device you need to add some extra characters like this: ttya,11 (I think the number is for baud but we're not using a real serial port so baud doesn't matter). Future ideas: - Have dingusppc execute the socat command for you so that it opens a terminal window before Open Firmware starts. - Add another --serial_backend for the printer port (ttyb) since now we have more than one type of serial backend. If both serial ports use socket backend, then a different name for the second socket is required. - Have an option to make dingusppc block until something connects to the socket (this means calling accept after listen instead of after select). - Test compatibility with serial port socket created by Parallels Desktop virtual machines in macOS. - Find a solution that works with Windows. - Test with Linux. - Create a serial_backend type for tty devices. I suppose maybe socat can pipe the file socket to tty but a direct connection might be easier to setup. - Allow using a socket created by some other app (for example, socat UNIX-LISTEN). This means dingusppc will assume the client role and will call connect instead of accept.
2022-08-14 13:48:16 +00:00
}
else if (received == 1) {
LOG_F(INFO, "socket sock read '%c'", c); // should never happen
Add socket type for serial_backend With the option --serial_backend=socket, input and output to a serial port will use a SOCK_STREAM type UNIX domain socket. This allows you to do Open Firmware in one window, while the first window can be used for dingusppc debugger. Other fixes: - Added SIGTERM handler so that if the user force quits dingusppc, the terminal settings are properly restored. A user needs to force quit when --serial_backend=stdio and Open Firmware is taking input from ttya. If terminal settings are not restored, then running dingusppc after a force quit will cause Control-C to not work when --serial_backend is not stdio. - Added a couple numbers to rcv_char_available - 15 is the number of consecutive characters that can processed. 400 is the total number of calls to rcv_char_available after 15 consecutive characters have been read before additional characters can be read. This delay in processing additional characters allows pasting arbitrarily large amounts of text into Open Firmware. A real serial port terminal app might have a text pacing option to limit the number of output characters per second but that is not an option since the emulator is not limiting character data to a baud rate. Related Notes: The socket file is created when dingusppc starts. The socket file is named dingusppcsocket and is created in the current working directory (usually where the executable is located and where the dingusppc.log, nvram.bin, and pram.bin files are created). The socket file is not visible in the Finder. You can see it in the terminal using the ls command. The socket file can be used with the following command in a new terminal window: socat UNIX-CLIENT:dingussocket -,cs8,parenb=0,echo=0,icanon=0,isig=0,icrnl=0 When dingusppc quits, the socat command ends. Other notes: The dingusppc --debugger option causes dingusppc to enter the debugger before Open Firmware outputs anything. You can connect to the socket while dingusppc is in the debugger. Then enter the go command to leave the debugger and start Open Firmware. However, since the startup sound takes a long time, you can probably connect to the socket before Open Firmware starts even without the --debugger option. It's like with a real Power Mac - you have a few seconds to hold Command-Option-O-F except in this case you have a few seconds to press the up arrow and press enter (for executing the last command from the terminal command history) and if you do it too late you'll still get into Open Firmware if auto-boot? was previously set to false using the dingusppc debugger which is actually the only way to get into Open Firmware since a keyboard is currently not emulated?). To set ttya as the input and output device in Open Firmware, you can use the setenv command in the dingusppc debugger. The device path needs to be longer than the current device path (because code for handling shortening of the paths is currently not implemented). For example, ttya can replace kbd for the input-device, but to replace screen for the output-device you need to add some extra characters like this: ttya,11 (I think the number is for baud but we're not using a real serial port so baud doesn't matter). Future ideas: - Have dingusppc execute the socat command for you so that it opens a terminal window before Open Firmware starts. - Add another --serial_backend for the printer port (ttyb) since now we have more than one type of serial backend. If both serial ports use socket backend, then a different name for the second socket is required. - Have an option to make dingusppc block until something connects to the socket (this means calling accept after listen instead of after select). - Test compatibility with serial port socket created by Parallels Desktop virtual machines in macOS. - Find a solution that works with Windows. - Test with Linux. - Create a serial_backend type for tty devices. I suppose maybe socat can pipe the file socket to tty but a direct connection might be easier to setup. - Allow using a socket created by some other app (for example, socat UNIX-LISTEN). This means dingusppc will assume the client role and will call connect instead of accept.
2022-08-14 13:48:16 +00:00
}
else {
LOG_F(INFO, "socket sock read %d", received); // should never happen
Add socket type for serial_backend With the option --serial_backend=socket, input and output to a serial port will use a SOCK_STREAM type UNIX domain socket. This allows you to do Open Firmware in one window, while the first window can be used for dingusppc debugger. Other fixes: - Added SIGTERM handler so that if the user force quits dingusppc, the terminal settings are properly restored. A user needs to force quit when --serial_backend=stdio and Open Firmware is taking input from ttya. If terminal settings are not restored, then running dingusppc after a force quit will cause Control-C to not work when --serial_backend is not stdio. - Added a couple numbers to rcv_char_available - 15 is the number of consecutive characters that can processed. 400 is the total number of calls to rcv_char_available after 15 consecutive characters have been read before additional characters can be read. This delay in processing additional characters allows pasting arbitrarily large amounts of text into Open Firmware. A real serial port terminal app might have a text pacing option to limit the number of output characters per second but that is not an option since the emulator is not limiting character data to a baud rate. Related Notes: The socket file is created when dingusppc starts. The socket file is named dingusppcsocket and is created in the current working directory (usually where the executable is located and where the dingusppc.log, nvram.bin, and pram.bin files are created). The socket file is not visible in the Finder. You can see it in the terminal using the ls command. The socket file can be used with the following command in a new terminal window: socat UNIX-CLIENT:dingussocket -,cs8,parenb=0,echo=0,icanon=0,isig=0,icrnl=0 When dingusppc quits, the socat command ends. Other notes: The dingusppc --debugger option causes dingusppc to enter the debugger before Open Firmware outputs anything. You can connect to the socket while dingusppc is in the debugger. Then enter the go command to leave the debugger and start Open Firmware. However, since the startup sound takes a long time, you can probably connect to the socket before Open Firmware starts even without the --debugger option. It's like with a real Power Mac - you have a few seconds to hold Command-Option-O-F except in this case you have a few seconds to press the up arrow and press enter (for executing the last command from the terminal command history) and if you do it too late you'll still get into Open Firmware if auto-boot? was previously set to false using the dingusppc debugger which is actually the only way to get into Open Firmware since a keyboard is currently not emulated?). To set ttya as the input and output device in Open Firmware, you can use the setenv command in the dingusppc debugger. The device path needs to be longer than the current device path (because code for handling shortening of the paths is currently not implemented). For example, ttya can replace kbd for the input-device, but to replace screen for the output-device you need to add some extra characters like this: ttya,11 (I think the number is for baud but we're not using a real serial port so baud doesn't matter). Future ideas: - Have dingusppc execute the socat command for you so that it opens a terminal window before Open Firmware starts. - Add another --serial_backend for the printer port (ttyb) since now we have more than one type of serial backend. If both serial ports use socket backend, then a different name for the second socket is required. - Have an option to make dingusppc block until something connects to the socket (this means calling accept after listen instead of after select). - Test compatibility with serial port socket created by Parallels Desktop virtual machines in macOS. - Find a solution that works with Windows. - Test with Linux. - Create a serial_backend type for tty devices. I suppose maybe socat can pipe the file socket to tty but a direct connection might be easier to setup. - Allow using a socket created by some other app (for example, socat UNIX-LISTEN). This means dingusppc will assume the client role and will call connect instead of accept.
2022-08-14 13:48:16 +00:00
}
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 = (int)send(acceptfd, &c, 1, 0);
Add socket type for serial_backend With the option --serial_backend=socket, input and output to a serial port will use a SOCK_STREAM type UNIX domain socket. This allows you to do Open Firmware in one window, while the first window can be used for dingusppc debugger. Other fixes: - Added SIGTERM handler so that if the user force quits dingusppc, the terminal settings are properly restored. A user needs to force quit when --serial_backend=stdio and Open Firmware is taking input from ttya. If terminal settings are not restored, then running dingusppc after a force quit will cause Control-C to not work when --serial_backend is not stdio. - Added a couple numbers to rcv_char_available - 15 is the number of consecutive characters that can processed. 400 is the total number of calls to rcv_char_available after 15 consecutive characters have been read before additional characters can be read. This delay in processing additional characters allows pasting arbitrarily large amounts of text into Open Firmware. A real serial port terminal app might have a text pacing option to limit the number of output characters per second but that is not an option since the emulator is not limiting character data to a baud rate. Related Notes: The socket file is created when dingusppc starts. The socket file is named dingusppcsocket and is created in the current working directory (usually where the executable is located and where the dingusppc.log, nvram.bin, and pram.bin files are created). The socket file is not visible in the Finder. You can see it in the terminal using the ls command. The socket file can be used with the following command in a new terminal window: socat UNIX-CLIENT:dingussocket -,cs8,parenb=0,echo=0,icanon=0,isig=0,icrnl=0 When dingusppc quits, the socat command ends. Other notes: The dingusppc --debugger option causes dingusppc to enter the debugger before Open Firmware outputs anything. You can connect to the socket while dingusppc is in the debugger. Then enter the go command to leave the debugger and start Open Firmware. However, since the startup sound takes a long time, you can probably connect to the socket before Open Firmware starts even without the --debugger option. It's like with a real Power Mac - you have a few seconds to hold Command-Option-O-F except in this case you have a few seconds to press the up arrow and press enter (for executing the last command from the terminal command history) and if you do it too late you'll still get into Open Firmware if auto-boot? was previously set to false using the dingusppc debugger which is actually the only way to get into Open Firmware since a keyboard is currently not emulated?). To set ttya as the input and output device in Open Firmware, you can use the setenv command in the dingusppc debugger. The device path needs to be longer than the current device path (because code for handling shortening of the paths is currently not implemented). For example, ttya can replace kbd for the input-device, but to replace screen for the output-device you need to add some extra characters like this: ttya,11 (I think the number is for baud but we're not using a real serial port so baud doesn't matter). Future ideas: - Have dingusppc execute the socat command for you so that it opens a terminal window before Open Firmware starts. - Add another --serial_backend for the printer port (ttyb) since now we have more than one type of serial backend. If both serial ports use socket backend, then a different name for the second socket is required. - Have an option to make dingusppc block until something connects to the socket (this means calling accept after listen instead of after select). - Test compatibility with serial port socket created by Parallels Desktop virtual machines in macOS. - Find a solution that works with Windows. - Test with Linux. - Create a serial_backend type for tty devices. I suppose maybe socat can pipe the file socket to tty but a direct connection might be easier to setup. - Allow using a socket created by some other app (for example, socat UNIX-LISTEN). This means dingusppc will assume the client role and will call connect instead of accept.
2022-08-14 13:48:16 +00:00
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 = (int)recv(acceptfd, c, 1, 0);
Add socket type for serial_backend With the option --serial_backend=socket, input and output to a serial port will use a SOCK_STREAM type UNIX domain socket. This allows you to do Open Firmware in one window, while the first window can be used for dingusppc debugger. Other fixes: - Added SIGTERM handler so that if the user force quits dingusppc, the terminal settings are properly restored. A user needs to force quit when --serial_backend=stdio and Open Firmware is taking input from ttya. If terminal settings are not restored, then running dingusppc after a force quit will cause Control-C to not work when --serial_backend is not stdio. - Added a couple numbers to rcv_char_available - 15 is the number of consecutive characters that can processed. 400 is the total number of calls to rcv_char_available after 15 consecutive characters have been read before additional characters can be read. This delay in processing additional characters allows pasting arbitrarily large amounts of text into Open Firmware. A real serial port terminal app might have a text pacing option to limit the number of output characters per second but that is not an option since the emulator is not limiting character data to a baud rate. Related Notes: The socket file is created when dingusppc starts. The socket file is named dingusppcsocket and is created in the current working directory (usually where the executable is located and where the dingusppc.log, nvram.bin, and pram.bin files are created). The socket file is not visible in the Finder. You can see it in the terminal using the ls command. The socket file can be used with the following command in a new terminal window: socat UNIX-CLIENT:dingussocket -,cs8,parenb=0,echo=0,icanon=0,isig=0,icrnl=0 When dingusppc quits, the socat command ends. Other notes: The dingusppc --debugger option causes dingusppc to enter the debugger before Open Firmware outputs anything. You can connect to the socket while dingusppc is in the debugger. Then enter the go command to leave the debugger and start Open Firmware. However, since the startup sound takes a long time, you can probably connect to the socket before Open Firmware starts even without the --debugger option. It's like with a real Power Mac - you have a few seconds to hold Command-Option-O-F except in this case you have a few seconds to press the up arrow and press enter (for executing the last command from the terminal command history) and if you do it too late you'll still get into Open Firmware if auto-boot? was previously set to false using the dingusppc debugger which is actually the only way to get into Open Firmware since a keyboard is currently not emulated?). To set ttya as the input and output device in Open Firmware, you can use the setenv command in the dingusppc debugger. The device path needs to be longer than the current device path (because code for handling shortening of the paths is currently not implemented). For example, ttya can replace kbd for the input-device, but to replace screen for the output-device you need to add some extra characters like this: ttya,11 (I think the number is for baud but we're not using a real serial port so baud doesn't matter). Future ideas: - Have dingusppc execute the socat command for you so that it opens a terminal window before Open Firmware starts. - Add another --serial_backend for the printer port (ttyb) since now we have more than one type of serial backend. If both serial ports use socket backend, then a different name for the second socket is required. - Have an option to make dingusppc block until something connects to the socket (this means calling accept after listen instead of after select). - Test compatibility with serial port socket created by Parallels Desktop virtual machines in macOS. - Find a solution that works with Windows. - Test with Linux. - Create a serial_backend type for tty devices. I suppose maybe socat can pipe the file socket to tty but a direct connection might be easier to setup. - Allow using a socket created by some other app (for example, socat UNIX-LISTEN). This means dingusppc will assume the client role and will call connect instead of accept.
2022-08-14 13:48:16 +00:00
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