diff --git a/sys/atari/tos.c b/sys/atari/tos.c new file mode 100644 index 000000000..e1f003ea2 --- /dev/null +++ b/sys/atari/tos.c @@ -0,0 +1,372 @@ +/* SCCS Id: @(#)tos.c 3.1 90/14/08 +/* NetHack may be freely redistributed. See license for details. */ + +/* + * TOS system functions. + */ + +#define NEED_VARARGS +#include "hack.h" + +#ifdef TTY_GRAPHICS +# include "tcap.h" +#else +/* To avoid error for tos.c; will be removed later */ +static char *nh_HE="\033q"; +#endif + +#ifdef TOS + +# include +# ifndef WORD +# define WORD short /* 16 bits -- redefine if necessary */ +# endif + +#include + +static char NDECL(DOSgetch); +static char NDECL(BIOSgetch); +static void NDECL(init_aline); +char *_a_line; /* for Line A variables */ +# ifdef TEXTCOLOR +boolean colors_changed = FALSE; +# endif + +int +tgetch() +{ + char ch; + + /* BIOSgetch can use the numeric key pad on IBM compatibles. */ + if (iflags.BIOS) + ch = BIOSgetch(); + else + ch = DOSgetch(); + return ((ch == '\r') ? '\n' : ch); +} + +/* + * Keyboard translation tables. + */ +#define KEYPADLO 0x61 +#define KEYPADHI 0x71 + +#define PADKEYS (KEYPADHI - KEYPADLO + 1) +#define iskeypad(x) (KEYPADLO <= (x) && (x) <= KEYPADHI) + +/* + * Keypad keys are translated to the normal values below. + * When iflags.BIOS is active, shifted keypad keys are translated to the + * shift values below. + */ +static const struct pad { + char normal, shift, cntrl; +} keypad[PADKEYS] = { + {C('['), 'Q', C('[')}, /* UNDO */ + {'?', '/', '?'}, /* HELP */ + {'(', 'a', '('}, /* ( */ + {')', 'w', ')'}, /* ) */ + {'/', '/', '/'}, /* / */ + {C('p'), '$', C('p')}, /* * */ + {'y', 'Y', C('y')}, /* 7 */ + {'k', 'K', C('k')}, /* 8 */ + {'u', 'U', C('u')}, /* 9 */ + {'h', 'H', C('h')}, /* 4 */ + {'.', '.', '.'}, + {'l', 'L', C('l')}, /* 6 */ + {'b', 'B', C('b')}, /* 1 */ + {'j', 'J', C('j')}, /* 2 */ + {'n', 'N', C('n')}, /* 3 */ + {'i', 'I', C('i')}, /* Ins */ + {'.', ':', ':'} /* Del */ +}, numpad[PADKEYS] = { + {C('['), 'Q', C('[')} , /* UNDO */ + {'?', '/', '?'}, /* HELP */ + {'(', 'a', '('}, /* ( */ + {')', 'w', ')'}, /* ) */ + {'/', '/', '/'}, /* / */ + {C('p'), '$', C('p')}, /* * */ + {'7', M('7'), '7'}, /* 7 */ + {'8', M('8'), '8'}, /* 8 */ + {'9', M('9'), '9'}, /* 9 */ + {'4', M('4'), '4'}, /* 4 */ + {'.', '.', '.'}, /* 5 */ + {'6', M('6'), '6'}, /* 6 */ + {'1', M('1'), '1'}, /* 1 */ + {'2', M('2'), '2'}, /* 2 */ + {'3', M('3'), '3'}, /* 3 */ + {'i', 'I', C('i')}, /* Ins */ + {'.', ':', ':'} /* Del */ +}; + +/* + * Unlike Ctrl-letter, the Alt-letter keystrokes have no specific ASCII + * meaning unless assigned one by a keyboard conversion table, so the + * keyboard BIOS normally does not return a character code when Alt-letter + * is pressed. So, to interpret unassigned Alt-letters, we must use a + * scan code table to translate the scan code into a letter, then set the + * "meta" bit for it. -3. + */ +#define SCANLO 0x10 + +static const char scanmap[] = { /* ... */ + 'q','w','e','r','t','y','u','i','o','p','[',']', '\n', + 0, 'a','s','d','f','g','h','j','k','l',';','\'', '`', + 0, '\\', 'z','x','c','v','b','N','m',',','.','?' /* ... */ +}; + +#define inmap(x) (SCANLO <= (x) && (x) < SCANLO + SIZE(scanmap)) + +/* + * BIOSgetch gets keys directly with a BIOS call. + */ +#define SHIFT (0x1 | 0x2) +#define CTRL 0x4 +#define ALT 0x8 + +static char +BIOSgetch() +{ + unsigned char scan, shift, ch; + const struct pad *kpad; + + long x; + + /* Get scan code. + */ + x = Crawcin(); + ch = x & 0x0ff; + scan = (x & 0x00ff0000L) >> 16; + /* Get shift status. + */ + shift = Kbshift(-1); + + /* Translate keypad keys */ + if (iskeypad(scan)) { + kpad = iflags.num_pad ? numpad : keypad; + if (shift & SHIFT) + ch = kpad[scan - KEYPADLO].shift; + else if (shift & CTRL) + ch = kpad[scan - KEYPADLO].cntrl; + else + ch = kpad[scan - KEYPADLO].normal; + } + /* Translate unassigned Alt-letters */ + if ((shift & ALT) && !ch) { + if (inmap(scan)) + ch = scanmap[scan - SCANLO]; + return (isprint(ch) ? M(ch) : ch); + } + return ch; +} + +static char +DOSgetch() +{ + return (Crawcin() & 0x007f); +} + + +long +freediskspace(path) +char *path; +{ + int drive = 0; + struct { + long freal; /*free allocation units*/ + long total; /*total number of allocation units*/ + long bps; /*bytes per sector*/ + long pspal; /*physical sectors per allocation unit*/ + } freespace; + if (path[0] && path[1] == ':') + drive = (toupper(path[0]) - 'A') + 1; + if (Dfree(&freespace,drive)<0) return -1; + return freespace.freal*freespace.bps*freespace.pspal; +} + +/* + * Functions to get filenames using wildcards + */ +int +findfirst(path) +char *path; +{ + return (Fsfirst(path, 0) == 0); +} + +int +findnext() +{ + return (Fsnext() == 0); +} + +char * +foundfile_buffer() +{ + return (char *)Fgetdta() + 30; +} + +long +filesize(file) +char *file; +{ + if (findfirst(file)) + return (* (long *) ((char *)Fgetdta() + 26)); + else + return -1L; +} + +/* + * Chdrive() changes the default drive. + */ +void +chdrive(str) +char *str; +{ + char *ptr; + char drive; + + if ((ptr = index(str, ':')) != (char *)0) { + drive = toupper(*(ptr - 1)); + (void)Dsetdrv(drive - 'A'); + } + return; +} + + +void +get_scr_size() +{ +# ifdef MINT +# include + struct winsize win; + char *tmp; + + if((tmp=nh_getenv("LINES"))) + LI = atoi(tmp); + else if((tmp=nh_getenv("ROWS"))) + LI = atoi(tmp); + if(tmp && (tmp=nh_getenv("COLUMNS"))) + CO = atoi(tmp); + else { + ioctl(0,TIOCGWINSZ, &win); + LI = win.ws_row; + CO = win.ws_col; + } +# else + init_aline(); + LI = (*((WORD *)(_a_line + -42L))) + 1; + CO = (*((WORD *)(_a_line + -44L))) + 1; +# endif +} + +# define BIGBUF 8192 + +int +_copyfile(from, to) +char *from, *to; +{ + int fromfd, tofd, r; + char *buf; + + if ((fromfd = open(from, O_RDONLY|O_BINARY, 0)) < 0) + return -1; + if ((tofd = open(to, O_WRONLY|O_CREAT|O_TRUNC|O_BINARY, FCMASK)) < 0) + return -1; + buf = (char *)alloc((size_t)BIGBUF); + while ( (r = read(fromfd, buf, BIGBUF)) > 0) + write(tofd, buf, r); + close(fromfd); + close(tofd); + free(buf); + return 0; /* successful */ +} + +int kbhit() +{ + return Cconis(); +} + +static void +init_aline() +{ +# ifdef __GNUC__ +/* line A calls nuke registers d0-d2,a0-a2; not all compilers regard these + as scratch registers, though, so we save them + */ + asm(" moveml d0-d2/a0-a2, sp@-"); + asm(" .word 0xa000; movel d0, __a_line"); + asm(" moveml sp@+, d0-d2/a0-a2"); +# else + asm(" movem.l d0-d2/a0-a2, -(sp)"); + asm(" .dc.w 0xa000"); /* tweak as necessary for your compiler */ + asm(" move.l d0, __a_line"); + asm(" movem.l (sp)+, d0-d2/a0-a2"); +# endif +} + +# ifdef TEXTCOLOR +/* used in termcap.c to decide how to set up the hilites */ +unsigned long tos_numcolors = 2; + +void +set_colors() +{ + static char colorHE[] = "\033q\033b0"; + + if (!iflags.BIOS) + return; + init_aline(); + tos_numcolors = 1 << (((unsigned char *) _a_line)[1]); + if (tos_numcolors <= 2) { /* mono */ + iflags.use_color = FALSE; + return; + } else { + colors_changed = TRUE; + nh_HE = colorHE; + } +} + +void +restore_colors() +{ + static char plainHE[] = "\033q"; + + if (colors_changed) + nh_HE = plainHE; + colors_changed = FALSE; +} +# endif /* TEXTCOLOR */ + +# ifdef SUSPEND + +#include + +# ifdef MINT +extern int __mint; +# endif + +int +dosuspend() { +# ifdef MINT + extern int kill(); + if (__mint == 0) { +# endif + pline("Sorry, it seems we have no SIGTSTP here. Try ! or S."); +# ifdef MINT + } + else if(signal(SIGTSTP, SIG_IGN) == SIG_DFL) { + suspend_nhwindows((char *)0); + (void) signal(SIGTSTP, SIG_DFL); + (void) kill(0, SIGTSTP); + get_scr_size(); + resume_nhwindows(); + } else { + pline("I don't think your shell has job control."); + } +# endif /* MINT */ + return(0); +} +# endif /* SUSPEND */ + +#endif /* TOS */