add SIGINFO / SIGUSR1 signal to headless driver.

On *BSD and MacOS X, typing ^T in the terminal sends a SIGINFO which will dump the text screen to stdout.
On Linux (as well as *BSD, etc) `kill -SIGUSR1 pid` will do the same.
This commit is contained in:
Kelvin Sherlock 2017-04-09 12:16:08 -04:00
parent 0e5f941cd5
commit 2554364910
1 changed files with 120 additions and 0 deletions

View File

@ -8,9 +8,129 @@
#include "defc.h"
#include "glog.h"
#include <signal.h>
extern int get_byte_at_address(int addr);
static unsigned char fix_char(unsigned char c) {
// inverse upper case
if (c >= 0x00 && c <= 0x1f) return c + 0x40;
// inverse special
if (c >= 0x20 && c <= 0x3f) return c;
// mouse text
if (c >= 0x40 && c <= 0x5f) return ' ';
// inverse lowercase
if (c >= 0x60 && c <= 0x7f) return c;
// uppercase normal
if (c >= 0x80 && c <= 0x9f) return c - 0x40;
// special characters, uppercase normal, lowercase normal.
if (c >= 0xa0 && c <= 0xff) return c - 0x80;
return ' ';
}
static void siginfo_handler(int signum) {
static unsigned table[] = {
0x0400,
0x0480,
0x0500,
0x0580,
0x0600,
0x0680,
0x0700,
0x0780,
0x0428,
0x04A8,
0x0528,
0x05A8,
0x0628,
0x06A8,
0x0728,
0x07A8,
0x0450,
0x04D0,
0x0550,
0x05D0,
0x0650,
0x06D0,
0x0750,
0x07D0,
};
extern int g_cur_a2_stat;
extern int get_byte_at_address(int addr);
if (g_cur_a2_stat & ALL_STAT_SUPER_HIRES) return; // not text...
int st80 = g_cur_a2_stat & ALL_STAT_VID80 /* ALL_STAT_ST80 */;
//if (!(g_cur_a2_stat & ALL_STAT_TEXT)) return; // text is not enabled.
char buffer[80+1];
for (int row = 0; row < 24; ++row) {
unsigned address = table[row];
int column = 0;
memset(buffer, ' ', sizeof(buffer));
for(int j = 0; j < 40; ++j, ++address) {
unsigned char c;
if (st80) {
c = get_byte_at_address(0xe10000 + address);
c = fix_char(c);
buffer[column++] = c;
}
c = get_byte_at_address(0xe00000 + address);
c = fix_char(c);
buffer[column++] = c;
}
if (st80) {
buffer[80] = '\n';
write(1, buffer, 81);
} else {
buffer[40] = '\n';
write(1, buffer, 41);
}
}
write(1, "\n\n", 2);
}
int
main(int argc, char **argv)
{
struct sigaction sa;
memset(&sa, 0, sizeof(sa));
sa.sa_flags = SA_RESTART;
sa.sa_handler = siginfo_handler;
#if defined(SIGINFO)
/* control-T by default */
sigaction(SIGINFO, &sa, NULL);
//signal(SIGINFO, siginfo_handler);
#endif
//signal(SIGUSR1, siginfo_handler);
sigaction(SIGUSR1, &sa, NULL);
return gsplusmain(argc, argv);
}