home *** CD-ROM | disk | FTP | other *** search
- /*****************************************************************************/
- /* */
- /* */
- /* CP/M emulator version 0.1 */
- /* */
- /* written by Michael Bischoff (mbi@mo.math.nat.tu-bs.de) */
- /* June-1994 */
- /* */
- /* This file is distributed under the GNU COPYRIGHT */
- /* see COPYRIGHT.GNU for Copyright details */
- /* */
- /* */
- /*****************************************************************************/
- #include "cpmemu.h"
-
- #define HAVE_RAW_IO
-
- /* magic for character I/O */
- #include <unistd.h>
- #include <fcntl.h>
- #include <termios.h>
- #include <sys/types.h>
-
- #ifdef HAVE_RAW_IO
- #include <sys/ioctl.h>
- #include <linux/kd.h>
- static int rawmode = 0;
- #endif
-
- #define SWITCHMODES /* switch between polled & sleeping */
- #define POLLING 1 /* conin() loops */
- #define SLEEPING 2 /* conin() sleeps until character found */
-
- static int currentmode = POLLING;
- static int ifd, ofd;
-
- static struct termios iold, iraw;
- static struct termios oold, oraw;
-
- static void restore_modes(void) {
- tcsetattr(ifd,TCSAFLUSH,&iold);
- if (ifd != ofd)
- tcsetattr(ofd,TCSAFLUSH,&oold);
- }
-
- int setup_io(const char *tty) {
- if (tty) {
- ofd = ifd = open(tty, O_RDWR);
- if (ofd < 0) {
- fprintf(stderr, "cpm: cannot open tty %s\n", tty);
- exit(1);
- }
- } else {
- ifd = STDIN_FILENO;
- ofd = STDOUT_FILENO;
- }
- if (tcgetattr(ifd, &iold))
- return 0; /* no chance */
- iraw = iold;
- iraw.c_lflag &= ~ECHO & ~ECHONL & ~ICANON & ~ISIG;
- iraw.c_iflag &= ~(ICRNL | IGNCR | IXON | IXOFF);
- iraw.c_cc[VMIN] = 0; /* input: return without waiting */
- iraw.c_cc[VTIME] = 0;
-
- if (ifd != ofd) {
- if (tcgetattr(ofd, &oold))
- return 0; /* no chance */
- oraw = oold;
- oraw.c_oflag &= ~OPOST;
- if (tcsetattr(ofd,TCSADRAIN,&oraw))
- return 0;
- } else
- iraw.c_oflag &= ~OPOST;
- /* now, register atexit function */
- atexit(restore_modes);
- if (tcsetattr(ifd,TCSADRAIN,&iraw))
- return 0;
- return 1;
- }
-
- int waiting = -1;
-
- static void poll(void) {
- waiting = 0;
- #ifdef HAVE_RAW_IO
- /* nasty undocumented stuff to prepare for tandy I memory mapped
- keyboard emulation (need key release events) */
- if (z80mem[4] == 0x5f && !rawmode) {
- ioctl(ifd, KDSKBMODE, K_RAW);
- rawmode = 1;
- } else if (z80mem[4] != 0x5f && rawmode) {
- ioctl(ifd, KDSKBMODE, K_XLATE);
- rawmode = 0;
- }
- #endif
- if (read(ifd, &waiting, 1) < 1)
- waiting = -1;
- }
-
- void putch(int c) { /* output character without postprocessing */
- write(ofd, &c, 1);
- }
-
- void putmes(const char *s) {
- write(ofd, s, strlen(s));
- }
- void vt52(int c) { /* simple vt52,adm3a => ANSI conversion */
- static int state = 0, x, y;
- char buff[32];
- #if 0
- static FILE *log = NULL;
- if (!log)
- log = fopen("cpm.out", "w");
- fputc(c, log);
- #endif
- switch (state) {
- case 0:
- switch (c) {
- case 0x7f: /* DEL: echo BS, space, BS */
- putmes("\b \b");
- break;
- case 0x1a: /* adm3a clear screen */
- case 0x0c: /* vt52 clear screen */
- putmes("\033[H\033[2J");
- break;
- case 0x1e: /* adm3a cursor home */
- putmes("\033[H");
- break;
- case 0x1b:
- state = 1; /* esc-prefix */
- break;
- case 1:
- state = 2; /* cursor motion prefix */
- break;
- case 2: /* insert line */
- putmes("\033[L");
- break;
- case 3: /* delete line */
- putmes("\033[M");
- break;
- case 5: /* clear to eol */
- putmes("\033[K");
- break;
- case 18: case 19:
- break;
- default:
- putch(c);
- }
- break;
- case 1: /* esc was sent */
- switch (c) {
- case '=':
- case 'Y':
- state = 2;
- break;
- default: /* some true ANSI sequence? */
- state = 0;
- putch(0x1b);
- putch(c);
- }
- break;
- case 2:
- y = c - ' '+1;
- state = 3;
- break;
- case 3:
- x = c - ' '+1;
- state = 0;
- sprintf(buff, "\033[%d;%dH", y, x);
- putmes(buff);
- break;
- }
- }
-
- int getch(void) { /* return a character, or -1 if none ready */
- if (waiting < 0) {
- /* must read character from keyboard */
- /* this part switches to sleeping mode */
- if (currentmode == POLLING) {
- iraw.c_cc[VMIN] = 1;
- currentmode = SLEEPING;
- tcsetattr(ifd,TCSADRAIN,&iraw);
- }
- poll();
- }
- if (waiting >= 0) {
- int c;
- c = waiting & 0xff;
- waiting = -1;
- return c;
- }
- return -1;
- }
-
- int kbhit(void) {
- if (waiting < 0) {
- /* really ask keyboard */
- /* this part switches to polling mode */
- if (currentmode != POLLING) {
- iraw.c_cc[VMIN] = 0;
- currentmode = POLLING;
- tcsetattr(ifd,TCSADRAIN,&iraw);
- }
- poll();
- }
- return waiting >= 0;
- }
-
-