OSDN Git Service

upgrade to 3.6.1
[jnethack/source.git] / sys / atari / tos.c
1 /* NetHack 3.6  tos.c   $NHDT-Date: 1501979358 2017/08/06 00:29:18 $  $NHDT-Branch: NetHack-3.6.0 $:$NHDT-Revision: 1.8 $ */
2 /* NetHack may be freely redistributed.  See license for details. */
3
4 /*
5  *  TOS system functions.
6  */
7
8 #define NEED_VARARGS
9 #include "hack.h"
10
11 #ifdef TTY_GRAPHICS
12 #include "tcap.h"
13 #else
14 /* To avoid error for tos.c; will be removed later */
15 static char *nh_HE = "\033q";
16 #endif
17
18 #ifdef TOS
19
20 #include <osbind.h>
21 #ifndef WORD
22 #define WORD short /* 16 bits -- redefine if necessary */
23 #endif
24
25 #include <ctype.h>
26
27 static char NDECL(DOSgetch);
28 static char NDECL(BIOSgetch);
29 static void NDECL(init_aline);
30 char *_a_line; /* for Line A variables */
31 #ifdef TEXTCOLOR
32 boolean colors_changed = FALSE;
33 #endif
34
35 int
36 tgetch()
37 {
38     char ch;
39
40     /* BIOSgetch can use the numeric key pad on IBM compatibles. */
41     if (iflags.BIOS)
42         ch = BIOSgetch();
43     else
44         ch = DOSgetch();
45     return ((ch == '\r') ? '\n' : ch);
46 }
47
48 /*
49  *  Keyboard translation tables.
50  */
51 #define KEYPADLO 0x61
52 #define KEYPADHI 0x71
53
54 #define PADKEYS (KEYPADHI - KEYPADLO + 1)
55 #define iskeypad(x) (KEYPADLO <= (x) && (x) <= KEYPADHI)
56
57 /*
58  * Keypad keys are translated to the normal values below.
59  * When iflags.BIOS is active, shifted keypad keys are translated to the
60  *    shift values below.
61  */
62 static const struct pad {
63     char normal, shift, cntrl;
64 } keypad[PADKEYS] =
65     {
66       { C('['), 'Q', C('[') }, /* UNDO */
67       { '?', '/', '?' },       /* HELP */
68       { '(', 'a', '(' },       /* ( */
69       { ')', 'w', ')' },       /* ) */
70       { '/', '/', '/' },       /* / */
71       { C('p'), '$', C('p') }, /* * */
72       { 'y', 'Y', C('y') },    /* 7 */
73       { 'k', 'K', C('k') },    /* 8 */
74       { 'u', 'U', C('u') },    /* 9 */
75       { 'h', 'H', C('h') },    /* 4 */
76       { '.', '.', '.' },
77       { 'l', 'L', C('l') }, /* 6 */
78       { 'b', 'B', C('b') }, /* 1 */
79       { 'j', 'J', C('j') }, /* 2 */
80       { 'n', 'N', C('n') }, /* 3 */
81       { 'i', 'I', C('i') }, /* Ins */
82       { '.', ':', ':' }     /* Del */
83     },
84   numpad[PADKEYS] = {
85       { C('['), 'Q', C('[') }, /* UNDO */
86       { '?', '/', '?' },       /* HELP */
87       { '(', 'a', '(' },       /* ( */
88       { ')', 'w', ')' },       /* ) */
89       { '/', '/', '/' },       /* / */
90       { C('p'), '$', C('p') }, /* * */
91       { '7', M('7'), '7' },    /* 7 */
92       { '8', M('8'), '8' },    /* 8 */
93       { '9', M('9'), '9' },    /* 9 */
94       { '4', M('4'), '4' },    /* 4 */
95       { '.', '.', '.' },       /* 5 */
96       { '6', M('6'), '6' },    /* 6 */
97       { '1', M('1'), '1' },    /* 1 */
98       { '2', M('2'), '2' },    /* 2 */
99       { '3', M('3'), '3' },    /* 3 */
100       { 'i', 'I', C('i') },    /* Ins */
101       { '.', ':', ':' }        /* Del */
102   };
103
104 /*
105  * Unlike Ctrl-letter, the Alt-letter keystrokes have no specific ASCII
106  * meaning unless assigned one by a keyboard conversion table, so the
107  * keyboard BIOS normally does not return a character code when Alt-letter
108  * is pressed.  So, to interpret unassigned Alt-letters, we must use a
109  * scan code table to translate the scan code into a letter, then set the
110  * "meta" bit for it.  -3.
111  */
112 #define SCANLO 0x10
113
114 static const char scanmap[] = {
115     /* ... */
116     'q', 'w', 'e', 'r', 't', 'y', 'u', 'i', 'o', 'p', '[', ']', '\n', 0, 'a',
117     's', 'd', 'f', 'g', 'h', 'j', 'k', 'l', ';', '\'', '`', 0, '\\', 'z', 'x',
118     'c', 'v', 'b', 'N', 'm', ',', '.', '?' /* ... */
119 };
120
121 #define inmap(x) (SCANLO <= (x) && (x) < SCANLO + SIZE(scanmap))
122
123 /*
124  * BIOSgetch gets keys directly with a BIOS call.
125  */
126 #define SHIFT (0x1 | 0x2)
127 #define CTRL 0x4
128 #define ALT 0x8
129
130 static char
131 BIOSgetch()
132 {
133     unsigned char scan, shift, ch;
134     const struct pad *kpad;
135
136     long x;
137
138     /* Get scan code.
139      */
140     x = Crawcin();
141     ch = x & 0x0ff;
142     scan = (x & 0x00ff0000L) >> 16;
143     /* Get shift status.
144      */
145     shift = Kbshift(-1);
146
147     /* Translate keypad keys */
148     if (iskeypad(scan)) {
149         kpad = iflags.num_pad ? numpad : keypad;
150         if (shift & SHIFT)
151             ch = kpad[scan - KEYPADLO].shift;
152         else if (shift & CTRL)
153             ch = kpad[scan - KEYPADLO].cntrl;
154         else
155             ch = kpad[scan - KEYPADLO].normal;
156     }
157     /* Translate unassigned Alt-letters */
158     if ((shift & ALT) && !ch) {
159         if (inmap(scan))
160             ch = scanmap[scan - SCANLO];
161         return (isprint(ch) ? M(ch) : ch);
162     }
163     return ch;
164 }
165
166 static char
167 DOSgetch()
168 {
169     return (Crawcin() & 0x007f);
170 }
171
172 long
173 freediskspace(path)
174 char *path;
175 {
176     int drive = 0;
177     struct {
178         long freal; /*free allocation units*/
179         long total; /*total number of allocation units*/
180         long bps;   /*bytes per sector*/
181         long pspal; /*physical sectors per allocation unit*/
182     } freespace;
183     if (path[0] && path[1] == ':')
184         drive = (toupper(path[0]) - 'A') + 1;
185     if (Dfree(&freespace, drive) < 0)
186         return -1;
187     return freespace.freal * freespace.bps * freespace.pspal;
188 }
189
190 /*
191  * Functions to get filenames using wildcards
192  */
193 int
194 findfirst(path)
195 char *path;
196 {
197     return (Fsfirst(path, 0) == 0);
198 }
199
200 int
201 findnext()
202 {
203     return (Fsnext() == 0);
204 }
205
206 char *
207 foundfile_buffer()
208 {
209     return (char *) Fgetdta() + 30;
210 }
211
212 long
213 filesize(file)
214 char *file;
215 {
216     if (findfirst(file))
217         return (*(long *) ((char *) Fgetdta() + 26));
218     else
219         return -1L;
220 }
221
222 /*
223  * Chdrive() changes the default drive.
224  */
225 void
226 chdrive(str)
227 char *str;
228 {
229     char *ptr;
230     char drive;
231
232     if ((ptr = index(str, ':')) != (char *) 0) {
233         drive = toupper(*(ptr - 1));
234         (void) Dsetdrv(drive - 'A');
235     }
236     return;
237 }
238
239 void
240 get_scr_size()
241 {
242 #ifdef MINT
243 #include <ioctl.h>
244     struct winsize win;
245     char *tmp;
246
247     if ((tmp = nh_getenv("LINES")))
248         LI = atoi(tmp);
249     else if ((tmp = nh_getenv("ROWS")))
250         LI = atoi(tmp);
251     if (tmp && (tmp = nh_getenv("COLUMNS")))
252         CO = atoi(tmp);
253     else {
254         ioctl(0, TIOCGWINSZ, &win);
255         LI = win.ws_row;
256         CO = win.ws_col;
257     }
258 #else
259     init_aline();
260     LI = (*((WORD *) (_a_line + -42L))) + 1;
261     CO = (*((WORD *) (_a_line + -44L))) + 1;
262 #endif
263 }
264
265 #define BIGBUF 8192
266
267 int
268 _copyfile(from, to)
269 char *from, *to;
270 {
271     int fromfd, tofd, r;
272     char *buf;
273
274     fromfd = open(from, O_RDONLY | O_BINARY, 0);
275     if (fromfd < 0)
276         return -1;
277     tofd = open(to, O_WRONLY | O_CREAT | O_TRUNC | O_BINARY, FCMASK);
278     if (tofd < 0) {
279         close(fromfd);
280         return -1;
281     }
282     buf = (char *) alloc((unsigned) BIGBUF);
283     while ((r = read(fromfd, buf, BIGBUF)) > 0)
284         write(tofd, buf, r);
285     close(fromfd);
286     close(tofd);
287     free((genericptr_t) buf);
288     return 0; /* successful */
289 }
290
291 int
292 kbhit()
293 {
294     return Cconis();
295 }
296
297 static void
298 init_aline()
299 {
300 #ifdef __GNUC__
301     /* line A calls nuke registers d0-d2,a0-a2; not all compilers regard these
302        as scratch registers, though, so we save them
303      */
304     asm(" moveml d0-d2/a0-a2, sp@-");
305     asm(" .word 0xa000; movel d0, __a_line");
306     asm(" moveml sp@+, d0-d2/a0-a2");
307 #else
308     asm(" movem.l d0-d2/a0-a2, -(sp)");
309     asm(" .dc.w 0xa000"); /* tweak as necessary for your compiler */
310     asm(" move.l d0, __a_line");
311     asm(" movem.l (sp)+, d0-d2/a0-a2");
312 #endif
313 }
314
315 #ifdef TEXTCOLOR
316 /* used in termcap.c to decide how to set up the hilites */
317 unsigned long tos_numcolors = 2;
318
319 void
320 set_colors()
321 {
322     static char colorHE[] = "\033q\033b0";
323
324     if (!iflags.BIOS)
325         return;
326     init_aline();
327     tos_numcolors = 1 << (((unsigned char *) _a_line)[1]);
328     if (tos_numcolors <= 2) { /* mono */
329         iflags.use_color = FALSE;
330         return;
331     } else {
332         colors_changed = TRUE;
333         nh_HE = colorHE;
334     }
335 }
336
337 void
338 restore_colors()
339 {
340     static char plainHE[] = "\033q";
341
342     if (colors_changed)
343         nh_HE = plainHE;
344     colors_changed = FALSE;
345 }
346 #endif /* TEXTCOLOR */
347
348 #ifdef SUSPEND
349
350 #include <signal.h>
351
352 #ifdef MINT
353 extern int __mint;
354 #endif
355
356 int
357 dosuspend()
358 {
359 #ifdef MINT
360     extern int kill();
361     if (__mint == 0) {
362 #endif
363         pline("Sorry, it seems we have no SIGTSTP here.  Try ! or S.");
364 #ifdef MINT
365     } else if (signal(SIGTSTP, SIG_IGN) == SIG_DFL) {
366         suspend_nhwindows((char *) 0);
367         (void) signal(SIGTSTP, SIG_DFL);
368         (void) kill(0, SIGTSTP);
369         get_scr_size();
370         resume_nhwindows();
371     } else {
372         pline("I don't think your shell has job control.");
373     }
374 #endif /* MINT */
375     return (0);
376 }
377 #endif /* SUSPEND */
378
379 #endif /* TOS */