1 /*
2 * SEGA Dreamcast support using KallistiOS (http://cadcdev.sourceforge.net)
3 * (c) 2002-2014 Christian Groessler (chris@groessler.org)
4 */
5
6 #include <stdarg.h>
7 #include <stdlib.h>
8 #include <dirent.h>
9 #include <errno.h>
10 #include <kos.h>
11 #include <sys/types.h>
12 #include "atari.h"
13 #include "config.h"
14 #include "sio.h"
15 #include "binload.h"
16 #include "afile.h"
17 #include "input.h"
18 #include "akey.h"
19 #include "colours.h"
20 #include "colours_ntsc.h"
21 #include "colours_pal.h"
22 #include "colours_external.h"
23 #include "ui.h"
24 #include "ui_basic.h"
25 #include "time.h"
26 #include "screen.h"
27 #include <dc/g2bus.h>
28 #include <arm/aica_cmd_iface.h>
29 #include <dc/sound/sound.h>
30 #include "statesav.h"
31 #include "sound.h"
32 #define _TYPEDEF_H /* to prevent pokeysnd.h to create uint32 type #defines */
33 #include "pokeysnd.h"
34 #include "version.h"
35
36 #define REPEAT_DELAY 5000
37 #define REPEAT_INI_DELAY (5 * REPEAT_DELAY)
38 /*#define DEBUG*/
39 #ifndef DIRTYRECT
40 #error need DIRTYRECT
41 #endif
42
43 void PLATFORM_DisplayScreen(void);
44 int stat(const char *, struct stat *);
45 static void calc_palette(void);
46 static int check_tray_open(void);
47 static void autostart(void);
48 static void controller_update(void);
49 /*static void dc_atari_sync(void);*/
50 static void dc_sound_init(void);
51 static void dc_snd_stream_stop(void);
52
53 static unsigned char *atari_screen_backup;
54 static unsigned char *atari_screen_backup2;
55 static maple_device_t *mcont_dev[MAPLE_PORT_COUNT * MAPLE_UNIT_COUNT];
56 static cont_state_t *mcont_state[MAPLE_PORT_COUNT * MAPLE_UNIT_COUNT];
57 static maple_device_t *mkeyb_dev;
58 static int num_cont; /* # of controllers found */
59 static int su_first_call = TRUE;
60 static int b_ui_leave = FALSE;
61 static int in_kbui = FALSE;
62 static int open_tray = FALSE;
63 static int tray_closed = TRUE;
64 static int reverse_x_axis = FALSE, reverse_y_axis = FALSE;
65 static unsigned int cont_dpad_up = CONT_DPAD_UP;
66 static unsigned int cont_dpad_down = CONT_DPAD_DOWN;
67 static unsigned int cont_dpad_left = CONT_DPAD_LEFT;
68 static unsigned int cont_dpad_right = CONT_DPAD_RIGHT;
69 #ifdef ASSEMBLER_SCREENUPDATE
70 int vid_mode_width;
71 #endif
72 #ifndef ASSEMBLER_SCREENUPDATE
73 static
74 #endif
75 uint16 *screen_vram;
76 static char x_str[16], y_str[16]; /* used by ScreenPositionConfiguration */
77 int x_adj, y_adj; /* screen position adjustment */
78 int emulate_paddles = FALSE;
79 int glob_snd_ena = TRUE;
80 int db_mode = FALSE;
81 int screen_tv_mode; /* mode of connected tv set */
82
83 int x_ovr = FALSE, y_ovr = FALSE, b_ovr = FALSE;
84 int disable_js = FALSE, disable_dpad = FALSE;
85 int ovr_inject_key = AKEY_NONE;
86 int x_key = AKEY_NONE;
87 int y_key = AKEY_NONE;
88 int b_key = AKEY_NONE;
89
90 extern char curr_disk_dir[];
91 extern char curr_cart_dir[];
92 extern char curr_exe_dir[];
93 extern char curr_tape_dir[];
94
95 static vid_mode_t mymode_pal = {
96 DM_320x240,
97 320, 240,
98 VID_PIXELDOUBLE|VID_LINEDOUBLE|VID_PAL,
99 CT_ANY,
100 PM_RGB565,
101 313, 857,
102 0xAE, 0x2D,
103 0x15, 312,
104 141, 843,
105 24, 313*2,
106 0, 1,
107 { 0, 0, 0, 0 }
108 };
109 static vid_mode_t mymode_ntsc = {
110 DM_320x240,
111 320, 240, /* width, height in pixels */
112 VID_PIXELDOUBLE|VID_LINEDOUBLE, /* flags */
113 CT_ANY, /* cable type */
114 PM_RGB565, /* pixel mode */
115 262, 857, /* scanlines/frame, clocks/scanline */
116 0xAE, 0x10, /* bitmap window position x, y */
117 0x15, 261, /* scanline interrupt positions */
118 141, 843, /* border x start + stop */
119 24, 263*2, /* border y start + stop */
120 0, 1,
121 { 0, 0, 0, 0 }
122 };
123
update_vidmode(void)124 void update_vidmode(void)
125 {
126 vid_mode_t mymode;
127
128 /* we need to copy it since vid_set_mode_ex() modifies it */
129 switch(screen_tv_mode) {
130 case Atari800_TV_NTSC:
131 memcpy(&mymode, &mymode_ntsc, sizeof(vid_mode_t));
132 break;
133 case Atari800_TV_PAL:
134 default:
135 memcpy(&mymode, &mymode_pal, sizeof(vid_mode_t));
136 break;
137 }
138 mymode.cable_type = vid_check_cable();
139 mymode.bitmapx += x_adj;
140 mymode.bitmapy += y_adj;
141 vid_set_mode_ex(&mymode);
142
143 screen_vram = (uint16*)0xA5000000;
144 /* point to current line of atari screen in display memory */
145 screen_vram += (vid_mode->height - Screen_HEIGHT) / 2 * vid_mode->width;
146 /* adjust left column to screen resolution */
147 screen_vram += (vid_mode->width - 320) / 2 - (Screen_WIDTH - 320) / 2 ;
148
149 #ifdef ASSEMBLER_SCREENUPDATE
150 vid_mode_width = vid_mode->width; /* for the assembler routines... */
151 #endif
152 }
153
154 #ifndef ASSEMBLER_SCREENUPDATE
155 static
156 #endif
157 uint16 mypal[256];
158
calc_palette(void)159 static void calc_palette(void)
160 {
161 int i;
162
163 for (i = 0; i < 256; i++) {
164 mypal[i] = ((Colours_GetR(i) >> 3) << 11) |
165 ((Colours_GetG(i) >> 2) << 5) |
166 (Colours_GetB(i) >> 3);
167 }
168 }
169
170 #ifndef ASSEMBLER_SCREENUPDATE
171 static
172 #endif
vbl_wait(void)173 void vbl_wait(void)
174 {
175 static int last_cntr = 0;
176
177 while (maple_state.vbl_cntr == last_cntr) ;
178 last_cntr = maple_state.vbl_cntr;
179 }
180
181 #define START_VAL ((Screen_WIDTH - 320) / 2) /* shortcut, used in screen update routines */
182
183 #ifndef ASSEMBLER_SCREENUPDATE
184 static
185 #endif
186 UBYTE old_sd[2][Screen_HEIGHT * Screen_WIDTH / 8];
187
188 #ifdef ASSEMBLER_SCREENUPDATE
189 extern void PLATFORM_DisplayScreen_doubleb(UBYTE *screen);
190 #else
PLATFORM_DisplayScreen_doubleb(UBYTE * screen)191 static void PLATFORM_DisplayScreen_doubleb(UBYTE *screen)
192 {
193 static unsigned int sbase = 0; /* screen base of current frame */
194 unsigned int x, m, j;
195 uint16 *vram;
196 UBYTE *osd, *nsd; /* old screen-dirty, new screen-dirty */
197
198 #ifdef SPEED_CHECK
199 vid_border_color(0, 0, 0);
200 #endif
201 if (sbase) {
202 sbase = 0;
203 vram = screen_vram;
204 osd = old_sd[0];
205 nsd = old_sd[1];
206 }
207 else {
208 sbase = 1024 * 768 * 4;
209 vram = screen_vram + sbase / 2; /* "/ 2" since screen_vram is (uint16 *) */
210 osd = old_sd[1];
211 nsd = old_sd[0];
212 }
213
214 for (m=START_VAL/8, x=START_VAL; m < Screen_HEIGHT * Screen_WIDTH / 8; m++) {
215 nsd[m] = Screen_dirty[m]; /* remember for other page */
216 if (Screen_dirty[m] || osd[m]) {
217 /* Draw eight pixels (x,y), (x+1,y),...,(x+7,y) here */
218 for (j=0; j<8; j++) {
219 *(vram + x + j) = mypal[*(screen + x + j)];
220 }
221 Screen_dirty[m] = 0;
222 }
223 x += 8;
224 if (x >= 320 + (Screen_WIDTH - 320) / 2) { /* end of visible part of line */
225 vram += vid_mode->width;
226 screen += Screen_WIDTH;
227 m += (Screen_WIDTH - 320) / 8;
228 x = START_VAL;
229 }
230 }
231
232 #ifdef SPEED_CHECK
233 vid_border_color(127, 127, 127);
234 #endif
235 vbl_wait();
236 vid_set_start(sbase);
237 #ifdef SPEED_CHECK
238 vid_border_color(255, 255, 255);
239 #endif
240 }
241 #endif /* not defined ASSEMBLER_SCREENUPDATE */
242
243 #ifdef ASSEMBLER_SCREENUPDATE
244 extern void PLATFORM_DisplayScreen_singleb(UBYTE *screen);
245 #else
PLATFORM_DisplayScreen_singleb(UBYTE * screen)246 static void PLATFORM_DisplayScreen_singleb(UBYTE *screen)
247 {
248 unsigned int x, m, j;
249 uint16 *vram = screen_vram;
250
251 #ifdef SPEED_CHECK
252 vid_border_color(0, 0, 0);
253 #endif
254 for (m=START_VAL/8, x=START_VAL; m < Screen_HEIGHT * Screen_WIDTH / 8; m++) {
255 if (Screen_dirty[m]) {
256 /* Draw eight pixels (x,y), (x+1,y),...,(x+7,y) here */
257 for (j=0; j<8; j++) {
258 *(vram + x + j) = mypal[*(screen + x + j)];
259 }
260 Screen_dirty[m] = 0;
261 }
262 x += 8;
263 if (x >= 320 + (Screen_WIDTH - 320) / 2) { /* end of visible part of line */
264 vram += vid_mode->width;
265 screen += Screen_WIDTH;
266 m += (Screen_WIDTH - 320) / 8;
267 x = START_VAL;
268 }
269 }
270 #ifdef SPEED_CHECK
271 vid_border_color(127, 127, 127);
272 #endif
273 vbl_wait();
274 #ifdef SPEED_CHECK
275 vid_border_color(255, 255, 255);
276 #endif
277 }
278 #endif /* not defined ASSEMBLER_SCREENUPDATE */
279
280 static void (*screen_updater)(UBYTE *screen);
281
PLATFORM_DisplayScreen(void)282 void PLATFORM_DisplayScreen(void)
283 {
284 screen_updater((UBYTE *)Screen_atari);
285 }
286
update_screen_updater(void)287 void update_screen_updater(void)
288 {
289 if (db_mode) {
290 screen_updater = PLATFORM_DisplayScreen_doubleb;
291 }
292 else {
293 screen_updater = PLATFORM_DisplayScreen_singleb;
294 }
295 }
296
PLATFORM_Initialise(int * argc,char * argv[])297 int PLATFORM_Initialise(int *argc, char *argv[])
298 {
299 static int fc = TRUE;
300
301 if (! fc) return TRUE; else fc = FALSE;
302
303 screen_tv_mode = Atari800_tv_mode;
304
305 #ifndef DEBUG
306 /* Bother us with output only if something died */
307 dbglog_set_level(DBG_DEAD);
308 #endif
309
310 /* Set the video mode */
311 update_vidmode();
312 calc_palette();
313
314 return TRUE;
315 }
316
PLATFORM_Exit(int run_monitor)317 int PLATFORM_Exit(int run_monitor)
318 {
319 arch_reboot();
320 return(0); /* not reached */
321 }
322
323 /*
324 * update num_cont, mkeyb_dev, and mcont_dev[]
325 */
dc_controller_init(void)326 static void dc_controller_init(void)
327 {
328 int p, u;
329 maple_device_t *dev;
330
331 mkeyb_dev = NULL;
332 num_cont = 0;
333 for (p = 0; p < MAPLE_PORT_COUNT; p++) {
334 for (u = 0; u < MAPLE_UNIT_COUNT; u++) {
335 if ((dev = maple_enum_type(p * MAPLE_PORT_COUNT + u, MAPLE_FUNC_CONTROLLER))) {
336 mcont_dev[num_cont++] = dev;
337 }
338 else if (!mkeyb_dev && (dev = maple_enum_type(p * MAPLE_PORT_COUNT + u, MAPLE_FUNC_KEYBOARD))) {
339 mkeyb_dev = dev;
340 }
341 }
342 }
343 return;
344 }
345
346 /*
347 * update the in-core status of the controller buttons/settings
348 */
controller_update(void)349 static void controller_update(void)
350 {
351 int i;
352
353 dc_controller_init(); /* update dis-/reconnections */
354 for (i = 0; i < num_cont; i++) {
355 if (! (mcont_state[i] = (cont_state_t *)maple_dev_status(mcont_dev[i]))) {
356 #ifdef DEBUG
357 printf("controller_update: error getting controller status\n");
358 #endif
359 }
360 }
361 }
362
consol_keys(void)363 static int consol_keys(void)
364 {
365 cont_state_t *state = mcont_state[0];
366
367 if (state->buttons & CONT_START) {
368 if (UI_is_active)
369 arch_reboot();
370 else {
371 if (state->buttons & CONT_X)
372 return(AKEY_COLDSTART);
373 else
374 return(AKEY_WARMSTART);
375 }
376 }
377
378 if (Atari800_machine_type != Atari800_MACHINE_5200) {
379 if (b_ovr && !UI_is_active && !b_ui_leave) {
380 /* !UI_is_active and !b_ui_leave because B is also the esc key
381 (with rtrig) to leave the ui */
382 if (b_key != AKEY_NONE && (state->buttons & CONT_B))
383 ovr_inject_key = b_key;
384 }
385 else {
386 if (state->buttons & CONT_B) {
387 if (! b_ui_leave) {
388 INPUT_key_consol &= ~INPUT_CONSOL_START;
389 }
390 else {
391 INPUT_key_consol |= INPUT_CONSOL_START;
392 }
393 }
394 else {
395 b_ui_leave = FALSE;
396 INPUT_key_consol |= INPUT_CONSOL_START;
397 }
398 }
399
400 if (y_ovr) {
401 if (y_key != AKEY_NONE && (state->buttons & CONT_Y))
402 ovr_inject_key = y_key;
403 }
404 else {
405 if (state->buttons & CONT_Y) {
406 INPUT_key_consol &= ~INPUT_CONSOL_SELECT;
407 }
408 else {
409 INPUT_key_consol |= INPUT_CONSOL_SELECT;
410 }
411 }
412
413 if (x_ovr) {
414 if (x_key != AKEY_NONE && (state->buttons & CONT_X))
415 ovr_inject_key = x_key;
416 }
417 else {
418 if (state->buttons & CONT_X) {
419 INPUT_key_consol &= ~INPUT_CONSOL_OPTION;
420 }
421 else {
422 INPUT_key_consol |= INPUT_CONSOL_OPTION;
423 }
424 }
425 }
426 else {
427 /* @@@ *_ovr TODO @@@ */
428
429 if (state->buttons & CONT_X) { /* 2nd action button */
430 INPUT_key_shift = 1;
431 }
432 else {
433 INPUT_key_shift = 0;
434 }
435 if (! UI_is_active) {
436 if (state->buttons & CONT_B) { /* testtest */
437 if (! b_ui_leave) {
438 return(AKEY_4); /* ??? at least on the dc kb "4" starts some games?? */
439 }
440 }
441 else {
442 b_ui_leave = FALSE;
443 }
444 if (state->buttons & CONT_Y) { /* testtest */
445 return(AKEY_5200_START);
446 }
447 }
448 }
449 return(AKEY_NONE);
450 }
451
get_emkey(UBYTE * title)452 int get_emkey(UBYTE *title)
453 {
454 int keycode;
455
456 controller_update();
457 in_kbui = TRUE;
458 memcpy(atari_screen_backup, Screen_atari, Screen_HEIGHT * Screen_WIDTH);
459 keycode = UI_BASIC_OnScreenKeyboard(title, -1);
460 memcpy(Screen_atari, atari_screen_backup, Screen_HEIGHT * Screen_WIDTH);
461 Screen_EntireDirty();
462 PLATFORM_DisplayScreen();
463 in_kbui = FALSE;
464 return keycode;
465
466 #if 0 /* @@@ 26-Mar-2013, chris: check this */
467 if (inject_key != AKEY_NONE) {
468 keycode = inject_key;
469 inject_key = AKEY_NONE;
470 return(keycode);
471 }
472 else {
473 return(AKEY_NONE);
474 }
475 #endif
476 }
477
478 /*
479 * do some basic keyboard emulation for the controller,
480 * so that the emulator menu can be used without keyboard
481 * (basically for selecting bin files/disk images)
482 */
controller_kb(void)483 static int controller_kb(void)
484 {
485 static int prev_up = FALSE, prev_down = FALSE, prev_a = FALSE,
486 prev_r = FALSE, prev_left = FALSE, prev_right = FALSE,
487 prev_b = FALSE, prev_l = FALSE;
488 static int repdelay = REPEAT_DELAY;
489 cont_state_t *state = mcont_state[0];
490
491 if (! num_cont) return(AKEY_NONE); /* no controller present */
492
493 repdelay--;
494 if (repdelay < 0) repdelay = REPEAT_DELAY;
495
496 if (!UI_is_active && (state->ltrig > 250 || (state->buttons & CONT_Z))) {
497 return(AKEY_UI);
498 }
499 #ifdef KB_UI
500 if (!UI_is_active && (state->rtrig > 250 || (state->buttons & CONT_C))) {
501 controller_update();
502 return(AKEY_KEYB);
503 }
504 /* provide keyboard emulation to enter file name */
505 if (UI_is_active && !in_kbui && (state->rtrig > 250 || (state->buttons & CONT_C))) {
506 controller_update();
507 in_kbui = TRUE;
508 memcpy(atari_screen_backup, Screen_atari, Screen_HEIGHT * Screen_WIDTH);
509 keycode = UI_BASIC_OnScreenKeyboard(NULL, -1);
510 memcpy(Screen_atari, atari_screen_backup, Screen_HEIGHT * Screen_WIDTH);
511 Screen_EntireDirty();
512 PLATFORM_DisplayScreen();
513 in_kbui = FALSE;
514 return keycode;
515 #if 0 /* @@@ 26-Mar-2013, chris: check this */
516 if (inject_key != AKEY_NONE) {
517 int keycode;
518 keycode = inject_key;
519 inject_key = AKEY_NONE;
520 return(keycode);
521 }
522 else {
523 return(AKEY_NONE);
524 }
525 #endif
526 }
527 #endif
528
529 if (UI_is_active) {
530 if ((state->buttons & cont_dpad_up)) {
531 prev_down = FALSE;
532 if (! prev_up) {
533 repdelay = REPEAT_INI_DELAY;
534 prev_up = 1;
535 return(AKEY_UP);
536 }
537 else {
538 if (! repdelay) {
539 return(AKEY_UP);
540 }
541 }
542 }
543 else {
544 prev_up = FALSE;
545 }
546
547 if ((state->buttons & cont_dpad_down)) {
548 prev_up = FALSE;
549 if (! prev_down) {
550 repdelay = REPEAT_INI_DELAY;
551 prev_down = TRUE;
552 return(AKEY_DOWN);
553 }
554 else {
555 if (! repdelay) {
556 return(AKEY_DOWN);
557 }
558 }
559 }
560 else {
561 prev_down = FALSE;
562 }
563
564 if ((state->buttons & cont_dpad_left)) {
565 prev_right = FALSE;
566 if (! prev_left) {
567 repdelay = REPEAT_INI_DELAY;
568 prev_left = TRUE;
569 return(AKEY_LEFT);
570 }
571 else {
572 if (! repdelay) {
573 return(AKEY_LEFT);
574 }
575 }
576 }
577 else {
578 prev_left = FALSE;
579 }
580
581 if ((state->buttons & cont_dpad_right)) {
582 prev_left = FALSE;
583 if (! prev_right) {
584 repdelay = REPEAT_INI_DELAY;
585 prev_right = TRUE;
586 return(AKEY_RIGHT);
587 }
588 else {
589 if (! repdelay) {
590 return(AKEY_RIGHT);
591 }
592 }
593 }
594 else {
595 prev_right = FALSE;
596 }
597
598 if ((state->buttons & CONT_A)) {
599 if (! prev_a) {
600 prev_a = TRUE;
601 return(AKEY_RETURN);
602 }
603 }
604 else {
605 prev_a = FALSE;
606 }
607
608 if ((state->buttons & CONT_B)) {
609 if (! prev_b) {
610 prev_b = TRUE;
611 b_ui_leave = TRUE; /* B must be released again */
612 return(AKEY_ESCAPE);
613 }
614 }
615 else {
616 prev_b = FALSE;
617 }
618
619 if (state->ltrig > 250 || (state->buttons & CONT_Z)) {
620 if (! prev_l && in_kbui) {
621 prev_l = TRUE;
622 return(AKEY_ESCAPE);
623 }
624 }
625 else {
626 prev_l = FALSE;
627 }
628
629 if (state->rtrig > 250 || (state->buttons & CONT_C)) {
630 if (! prev_r) {
631 prev_r = TRUE;
632 return(AKEY_ESCAPE);
633 }
634 }
635 else {
636 prev_r = FALSE;
637 }
638 }
639 return(AKEY_NONE);
640 }
641
PLATFORM_Keyboard(void)642 int PLATFORM_Keyboard(void)
643 {
644 static int old_open_tray = FALSE;
645 int open_tray;
646 int keycode;
647 int i;
648
649 /* let's do this here... */
650 open_tray = check_tray_open();
651 if (open_tray != old_open_tray) {
652 old_open_tray = open_tray;
653 if (open_tray == TRUE) {
654 #ifdef DEBUG
655 printf("XXX TRAY OPEN!\n");
656 #endif
657 tray_closed = FALSE;
658 return(AKEY_UI);
659 }
660 else {
661 #ifdef DEBUG
662 printf("XXX TRAY CLOSE!\n");
663 #endif
664 tray_closed = TRUE;
665 cdrom_init();
666 iso_reset();
667 chdir("/");
668 for (i=0; i<UI_n_atari_files_dir; i++)
669 strcpy(UI_atari_files_dir[i], "/");
670 }
671 }
672
673 if (UI_is_active) controller_update();
674
675 if (num_cont && (keycode = consol_keys()) != AKEY_NONE) return(keycode);
676
677 #ifdef KB_UI
678 if (inject_key != AKEY_NONE) {
679 keycode = inject_key;
680 inject_key = AKEY_NONE;
681 switch(keycode) {
682 case AKEY_OPTION:
683 INPUT_key_consol &= (~INPUT_CONSOL_OPTION);
684 keycode = AKEY_NONE;
685 break;
686 case AKEY_SELECT:
687 INPUT_key_consol &= (~INPUT_CONSOL_SELECT);
688 keycode = AKEY_NONE;
689 break;
690 case AKEY_START:
691 INPUT_key_consol &= (~INPUT_CONSOL_START);
692 keycode = AKEY_NONE;
693 break;
694 }
695 return(keycode);
696 }
697 #endif
698 if (ovr_inject_key != AKEY_NONE) {
699 keycode = ovr_inject_key;
700 ovr_inject_key = AKEY_NONE;
701 return(keycode);
702 }
703
704 keycode = controller_kb();
705 if (keycode != AKEY_NONE) return(keycode);
706
707 if (mkeyb_dev)
708 keycode = kbd_queue_pop(mkeyb_dev, 1);
709 else
710 keycode = -1;
711 if (keycode == -1) return(AKEY_NONE);
712
713 #ifdef DEBUG
714 printf("DC key: %04X (%c)\n", keycode, keycode > 32 && keycode < 127 ? keycode : '.');
715 #endif
716
717 switch (keycode) {
718
719 /* OPTION / SELECT / START keys */
720 /*INPUT_key_consol = INPUT_CONSOL_NONE; -- already set in consol_keys... */
721 case 0x3b00:
722 INPUT_key_consol &= (~INPUT_CONSOL_OPTION);
723 return(AKEY_NONE);
724 case 0x3c00:
725 INPUT_key_consol &= (~INPUT_CONSOL_SELECT);
726 return(AKEY_NONE);
727 case 0x3d00:
728 INPUT_key_consol &= (~INPUT_CONSOL_START);
729 return(AKEY_NONE);
730
731 case 0x1b: /* ESC */
732 keycode = AKEY_ESCAPE;
733 break;
734 case 9: /* TAB */
735 keycode = AKEY_TAB;
736 break;
737 case '`':
738 keycode = AKEY_CAPSTOGGLE;
739 break;
740 case '!':
741 keycode = AKEY_EXCLAMATION;
742 break;
743 case '"':
744 keycode = AKEY_DBLQUOTE;
745 break;
746 case '#':
747 keycode = AKEY_HASH;
748 break;
749 case '$':
750 keycode = AKEY_DOLLAR;
751 break;
752 case '%':
753 keycode = AKEY_PERCENT;
754 break;
755 case '&':
756 keycode = AKEY_AMPERSAND;
757 break;
758 case '\'':
759 keycode = AKEY_QUOTE;
760 break;
761 case '@':
762 keycode = AKEY_AT;
763 break;
764 case '(':
765 keycode = AKEY_PARENLEFT;
766 break;
767 case ')':
768 keycode = AKEY_PARENRIGHT;
769 break;
770 case '[':
771 keycode = AKEY_BRACKETLEFT;
772 break;
773 case ']':
774 keycode = AKEY_BRACKETRIGHT;
775 break;
776 case '<':
777 keycode = AKEY_LESS;
778 break;
779 case '>':
780 keycode = AKEY_GREATER;
781 break;
782 case '=':
783 keycode = AKEY_EQUAL;
784 break;
785 case '?':
786 keycode = AKEY_QUESTION;
787 break;
788 case '-':
789 keycode = AKEY_MINUS;
790 break;
791 case '+':
792 keycode = AKEY_PLUS;
793 break;
794 case '*':
795 keycode = AKEY_ASTERISK;
796 break;
797 case '/':
798 keycode = AKEY_SLASH;
799 break;
800 case ':':
801 keycode = AKEY_COLON;
802 break;
803 case ';':
804 keycode = AKEY_SEMICOLON;
805 break;
806 case ',':
807 keycode = AKEY_COMMA;
808 break;
809 case '.':
810 keycode = AKEY_FULLSTOP;
811 break;
812 case '_':
813 keycode = AKEY_UNDERSCORE;
814 break;
815 case '^':
816 keycode = AKEY_CIRCUMFLEX;
817 break;
818 case '\\':
819 keycode = AKEY_BACKSLASH;
820 break;
821 case '|':
822 keycode = AKEY_BAR;
823 break;
824 case ' ':
825 keycode = AKEY_SPACE;
826 break;
827 case '0':
828 keycode = AKEY_0;
829 break;
830 case '1':
831 keycode = AKEY_1;
832 break;
833 case '2':
834 keycode = AKEY_2;
835 break;
836 case '3':
837 keycode = AKEY_3;
838 break;
839 case '4':
840 keycode = AKEY_4;
841 break;
842 case '5':
843 keycode = AKEY_5;
844 break;
845 case '6':
846 keycode = AKEY_6;
847 break;
848 case '7':
849 keycode = AKEY_7;
850 break;
851 case '8':
852 keycode = AKEY_8;
853 break;
854 case '9':
855 keycode = AKEY_9;
856 break;
857 case 'a':
858 keycode = AKEY_a;
859 break;
860 case 'b':
861 keycode = AKEY_b;
862 break;
863 case 'c':
864 keycode = AKEY_c;
865 break;
866 case 'd':
867 keycode = AKEY_d;
868 break;
869 case 'e':
870 keycode = AKEY_e;
871 break;
872 case 'f':
873 keycode = AKEY_f;
874 break;
875 case 'g':
876 keycode = AKEY_g;
877 break;
878 case 'h':
879 keycode = AKEY_h;
880 break;
881 case 'i':
882 keycode = AKEY_i;
883 break;
884 case 'j':
885 keycode = AKEY_j;
886 break;
887 case 'k':
888 keycode = AKEY_k;
889 break;
890 case 'l':
891 keycode = AKEY_l;
892 break;
893 case 'm':
894 keycode = AKEY_m;
895 break;
896 case 'n':
897 keycode = AKEY_n;
898 break;
899 case 'o':
900 keycode = AKEY_o;
901 break;
902 case 'p':
903 keycode = AKEY_p;
904 break;
905 case 'q':
906 keycode = AKEY_q;
907 break;
908 case 'r':
909 keycode = AKEY_r;
910 break;
911 case 's':
912 keycode = AKEY_s;
913 break;
914 case 't':
915 keycode = AKEY_t;
916 break;
917 case 'u':
918 keycode = AKEY_u;
919 break;
920 case 'v':
921 keycode = AKEY_v;
922 break;
923 case 'w':
924 keycode = AKEY_w;
925 break;
926 case 'x':
927 keycode = AKEY_x;
928 break;
929 case 'y':
930 keycode = AKEY_y;
931 break;
932 case 'z':
933 keycode = AKEY_z;
934 break;
935 case 'A':
936 keycode = AKEY_A;
937 break;
938 case 'B':
939 keycode = AKEY_B;
940 break;
941 case 'C':
942 keycode = AKEY_C;
943 break;
944 case 'D':
945 keycode = AKEY_D;
946 break;
947 case 'E':
948 keycode = AKEY_E;
949 break;
950 case 'F':
951 keycode = AKEY_F;
952 break;
953 case 'G':
954 keycode = AKEY_G;
955 break;
956 case 'H':
957 keycode = AKEY_H;
958 break;
959 case 'I':
960 keycode = AKEY_I;
961 break;
962 case 'J':
963 keycode = AKEY_J;
964 break;
965 case 'K':
966 keycode = AKEY_K;
967 break;
968 case 'L':
969 keycode = AKEY_L;
970 break;
971 case 'M':
972 keycode = AKEY_M;
973 break;
974 case 'N':
975 keycode = AKEY_N;
976 break;
977 case 'O':
978 keycode = AKEY_O;
979 break;
980 case 'P':
981 keycode = AKEY_P;
982 break;
983 case 'Q':
984 keycode = AKEY_Q;
985 break;
986 case 'R':
987 keycode = AKEY_R;
988 break;
989 case 'S':
990 keycode = AKEY_S;
991 break;
992 case 'T':
993 keycode = AKEY_T;
994 break;
995 case 'U':
996 keycode = AKEY_U;
997 break;
998 case 'V':
999 keycode = AKEY_V;
1000 break;
1001 case 'W':
1002 keycode = AKEY_W;
1003 break;
1004 case 'X':
1005 keycode = AKEY_X;
1006 break;
1007 case 'Y':
1008 keycode = AKEY_Y;
1009 break;
1010 case 'Z':
1011 keycode = AKEY_Z;
1012 break;
1013
1014 case 0x3a00: /* F1 */
1015 keycode = AKEY_UI;
1016 break;
1017
1018 case 0x3e00: /* F5 */
1019 keycode = AKEY_COLDSTART;
1020 break;
1021
1022 case 0x4500: /* F12 */
1023 arch_reboot();
1024
1025 /* cursor keys */
1026 case 0x5200:
1027 keycode = AKEY_UP;
1028 break;
1029 case 0x5100:
1030 keycode = AKEY_DOWN;
1031 break;
1032 case 0x5000:
1033 keycode = AKEY_LEFT;
1034 break;
1035 case 0x4f00:
1036 keycode = AKEY_RIGHT;
1037 break;
1038
1039 case 0x6500: /* S3 */
1040 keycode = AKEY_ATARI;
1041 break;
1042
1043 case 0x4a00: /* Home */
1044 keycode = AKEY_CLEAR;
1045 break;
1046 case 0x4d00: /* End */
1047 keycode = AKEY_HELP;
1048 break;
1049 case 0x4800: /* Break/Pause */
1050 keycode = AKEY_BREAK;
1051 break;
1052
1053 case 0x4c00: /* Del */
1054 if (INPUT_key_shift)
1055 keycode = AKEY_DELETE_LINE;
1056 else
1057 keycode |= AKEY_DELETE_CHAR;
1058 break;
1059 case 0x4900: /* Ins */
1060 if (INPUT_key_shift)
1061 keycode = AKEY_INSERT_LINE;
1062 else
1063 keycode |= AKEY_INSERT_CHAR;
1064 break;
1065
1066 case 127:
1067 case 8:
1068 keycode = AKEY_BACKSPACE;
1069 break;
1070 case 13:
1071 case 10:
1072 keycode = AKEY_RETURN;
1073 break;
1074 default:
1075 keycode = AKEY_NONE;
1076 break;
1077 }
1078 return keycode;
1079 }
1080
PLATFORM_PORT(int num)1081 int PLATFORM_PORT(int num)
1082 {
1083 cont_state_t *state;
1084 int retval = 0xff;
1085 int cix = 0;
1086
1087 if (num) {
1088 if (Atari800_machine_type != Atari800_MACHINE_800) return(retval);
1089 cix = 2; /* js #2 and #3 */
1090 }
1091
1092 if (num_cont < 1 + cix) return(retval); /* no controller present */
1093
1094 state = mcont_state[cix];
1095 if (! emulate_paddles) {
1096 if (! disable_dpad) {
1097 if (state->buttons & cont_dpad_up) {
1098 retval &= 0xfe;
1099 }
1100 if (state->buttons & cont_dpad_down) {
1101 retval &= 0xfd;
1102 }
1103 if (state->buttons & cont_dpad_left) {
1104 retval &= 0xfb;
1105 }
1106 if (state->buttons & cont_dpad_right) {
1107 retval &= 0xf7;
1108 }
1109 }
1110 /* if joypad not used, try the joystick instead */
1111 if (retval == 0xff && !disable_js) {
1112 if (reverse_x_axis) {
1113 if (state->joyx < -10) { // @@@ new kos new values
1114 retval &= 0xf7;
1115 }
1116 if (state->joyx > 10) { // @@@ ditto, and following lines
1117 retval &= 0xfb;
1118 }
1119 }
1120 else {
1121 if (state->joyx > 10) { /* right */
1122 retval &= 0xf7;
1123 }
1124 if (state->joyx < -10) { /* left */
1125 retval &= 0xfb;
1126 }
1127 }
1128 if (reverse_y_axis) {
1129 if (state->joyy < -10) {
1130 retval &= 0xfd;
1131 }
1132 if (state->joyy > 10) {
1133 retval &= 0xfe;
1134 }
1135 }
1136 else {
1137 if (state->joyy < -10) { /* down */
1138 retval &= 0xfd;
1139 }
1140 if (state->joyy > 10) { /* up */
1141 retval &= 0xfe;
1142 }
1143 }
1144 }
1145 if (num_cont > 1 + cix) {
1146 state = mcont_state[cix+1];
1147 if (! disable_dpad) {
1148 if (state->buttons & cont_dpad_up) {
1149 retval &= 0xef;
1150 }
1151 if (state->buttons & cont_dpad_down) {
1152 retval &= 0xdf;
1153 }
1154 if (state->buttons & cont_dpad_left) {
1155 retval &= 0xbf;
1156 }
1157 if (state->buttons & cont_dpad_right) {
1158 retval &= 0x7f;
1159 }
1160 }
1161 /* if joypad not used, try the joystick instead */
1162 if ((retval & 0xf0) == 0xf0 && !disable_js) {
1163 if (reverse_x_axis) {
1164 if (state->joyx < -10) {
1165 retval &= 0x7f;
1166 }
1167 if (state->joyx > 10) {
1168 retval &= 0xbf;
1169 }
1170 }
1171 else {
1172 if (state->joyx > 10) { /* right */
1173 retval &= 0x7f;
1174 }
1175 if (state->joyx < -10) { /* left */
1176 retval &= 0xbf;
1177 }
1178 }
1179 if (reverse_y_axis) {
1180 if (state->joyy < -10) {
1181 retval &= 0xdf;
1182 }
1183 if (state->joyy > 10) {
1184 retval &= 0xef;
1185 }
1186 }
1187 else {
1188 if (state->joyy > 10) { /* down */
1189 retval &= 0xdf;
1190 }
1191 if (state->joyy < -10) { /* up */
1192 retval &= 0xef;
1193 }
1194 }
1195 }
1196 }
1197 }
1198 else { /* emulate paddles */
1199 /* 1st paddle trigger */
1200 if (state->buttons & CONT_A) {
1201 retval &= (cix > 1) ? 0xbf : 0xfb;
1202 }
1203 if (num_cont > 1 + cix) {
1204 state = mcont_state[cix+1];
1205
1206 /* 2nd paddle trigger */
1207 if (state->buttons & CONT_A) {
1208 retval &= (cix > 1) ? 0x7f : 0xf7;
1209 }
1210 }
1211 }
1212
1213 return(retval);
1214 }
1215
Atari_POT(int num)1216 int Atari_POT(int num)
1217 {
1218 int val;
1219 cont_state_t *state;
1220
1221 if (Atari800_machine_type != Atari800_MACHINE_5200) {
1222 if (emulate_paddles && !disable_js) {
1223 if (num + 1 > num_cont) return(228);
1224 if (Atari800_machine_type != Atari800_MACHINE_800 && num > 3) return(228);
1225
1226 state = mcont_state[num];
1227 val = state->joyx;
1228 if (reverse_x_axis) val = 255 - val;
1229 val = val * 228 / 255;
1230 if (val > 227) return(1);
1231 return(228 - val);
1232 }
1233 else {
1234 return(228);
1235 }
1236 }
1237 else { /* 5200 version:
1238 *
1239 * num / 2: which controller
1240 * num & 1 == 0: x axis
1241 * num & 1 == 1: y axis
1242 */
1243
1244 if (num / 2 + 1 > num_cont || disable_js) return(INPUT_joy_5200_center);
1245
1246 state = mcont_state[num / 2];
1247 if (num & 1) {
1248 if (reverse_y_axis)
1249 val = -state->joyy;
1250 else
1251 val = state->joyy;
1252 }
1253 else {
1254 if (reverse_x_axis)
1255 val = -state->joyx;
1256 else
1257 val = state->joyx;
1258 }
1259
1260 /* normalize into 5200 range */
1261 if (! val) return(INPUT_joy_5200_center);
1262 if (val < 0) {
1263 /*val -= joy_5200_min;*/
1264 val = val * (INPUT_joy_5200_center - INPUT_joy_5200_min) / 127; // @@@ new kos values
1265 return(val + INPUT_joy_5200_min);
1266 }
1267 else {
1268 val = val * INPUT_joy_5200_max / 255;
1269 if (val < INPUT_joy_5200_center)
1270 val = INPUT_joy_5200_center;
1271 return(val);
1272 }
1273 }
1274 }
1275
PLATFORM_TRIG(int num)1276 int PLATFORM_TRIG(int num)
1277 {
1278 cont_state_t *state;
1279
1280 if (num + 1 > num_cont) return(1); /* no controller present */
1281 if (Atari800_machine_type != Atari800_MACHINE_800 && num > 1) return(1);
1282
1283 state = mcont_state[num];
1284 if (state->buttons & CONT_A) {
1285 return(0);
1286 }
1287
1288 return(1);
1289 }
1290
do_reverse_x_axis(void)1291 void do_reverse_x_axis(void)
1292 {
1293 if (reverse_x_axis) {
1294 cont_dpad_left = CONT_DPAD_RIGHT;
1295 cont_dpad_right = CONT_DPAD_LEFT;
1296 }
1297 else {
1298 cont_dpad_left = CONT_DPAD_LEFT;
1299 cont_dpad_right = CONT_DPAD_RIGHT;
1300 }
1301 }
1302
do_reverse_y_axis(void)1303 void do_reverse_y_axis(void)
1304 {
1305 if (reverse_y_axis) {
1306 cont_dpad_up = CONT_DPAD_DOWN;
1307 cont_dpad_down = CONT_DPAD_UP;
1308 }
1309 else {
1310 cont_dpad_up = CONT_DPAD_UP;
1311 cont_dpad_down = CONT_DPAD_DOWN;
1312 }
1313 }
1314
1315 #if 0
1316 /*
1317 * fill up unused (no entry in atari800.cfg) saved_files_dir
1318 * entries with the available VMUs
1319 */
1320 static void setup_saved_files_dirs(void)
1321 {
1322 int p, u;
1323
1324 /* loop over VMUs */
1325 for (p=0; p<MAPLE_PORT_COUNT; p++) {
1326 for (u=0; u<MAPLE_UNIT_COUNT; u++) {
1327 if (maple_device_func(p, u) & MAPLE_FUNC_MEMCARD) {
1328 if (n_saved_files_dir < MAX_DIRECTORIES) {
1329 sprintf(saved_files_dir[n_saved_files_dir], "/vmu/%c%c",
1330 'a' + p, '0' + u);
1331 n_saved_files_dir++;
1332 }
1333 else
1334 return;
1335 }
1336 }
1337 }
1338 }
1339 #endif
1340
1341 #ifdef HZ_TEST
cls(int xres,int yres)1342 static void cls(int xres, int yres)
1343 {
1344 int x, y;
1345 for(x = 0; x < xres; x++)
1346 for(y = 0; y < yres; y++)
1347 vram_s[xres*y + x] = 0;
1348 }
1349
wait_a(void)1350 static void wait_a(void)
1351 {
1352 cont_state_t *state;
1353
1354 while (!mcont_dev[0])
1355 dc_controller_init();
1356
1357 do {
1358 if (!(state = (cont_state_t *)maple_dev_status(mcont_dev[0]))) {
1359 return;
1360 }
1361
1362 } while (state && !(state->buttons & CONT_A));
1363 }
1364 #endif
1365
1366 #ifdef HZ_TEST
do_hz_test(void)1367 void do_hz_test(void)
1368 {
1369 uint32 s, ms, s2, ms2, z;
1370 char buffer[80];
1371
1372 cls(320,240);
1373 bfont_draw_str(vram_s+64*320+5, 320, 0, "chk dsply hz.. 500 vbls");
1374 timer_ms_gettime(&s, &ms);
1375 for (z=0; z<500; z++) {
1376 vbl_wait();
1377 }
1378 timer_ms_gettime(&s2, &ms2);
1379 sprintf(buffer, "start time: %lu.%03lu\n", s, ms);
1380 bfont_draw_str(vram_s+89*320+5, 320, 0, buffer);
1381 sprintf(buffer, "end time: %lu.%03lu\n", s2, ms2);
1382 bfont_draw_str(vram_s+114*320+5, 320, 0, buffer);
1383 sprintf(buffer, "diff(ms) = %ld\n", s2*1000 + ms2 - s * 1000 - ms);
1384 bfont_draw_str(vram_s+139*320+5, 320, 0, buffer);
1385 sprintf(buffer, "hz = %f\n", 500.0 / ((s2*1000 + ms2 - s * 1000 - ms) / 1000.0));
1386 bfont_draw_str(vram_s+164*320+5, 320, 0, buffer);
1387 wait_a();
1388 cls(320,240);
1389 }
1390 #endif /* ifdef HZ_TEST */
1391
1392 KOS_INIT_FLAGS(INIT_IRQ | INIT_THD_PREEMPT);
1393 #ifdef ROMDISK
1394 extern uint8 romdisk[];
1395 KOS_INIT_ROMDISK(romdisk);
1396 #endif
1397
1398 #ifndef DEBUG
1399 int scif_dbgio_enabled = 1; /* 1 = disable serial debug output */
1400 #endif
1401
dc_init_serial(void)1402 void dc_init_serial(void)
1403 {
1404 dbgio_disable();
1405 scif_set_parameters(9600, 1);
1406 scif_init();
1407 scif_set_irq_usage(1);
1408 }
1409
dc_set_baud(int baud)1410 void dc_set_baud(int baud)
1411 {
1412 scif_set_parameters(baud, 1);
1413 scif_init();
1414 scif_set_irq_usage(1);
1415 #ifdef DEBUG
1416 printf("setting baud rate: %d\n", baud);
1417 #endif
1418 }
1419
dc_write_serial(unsigned char byte)1420 int dc_write_serial(unsigned char byte)
1421 {
1422 if (scif_write_buffer(&byte, 1, 0) == 1)
1423 return 1;
1424 return 0;
1425 }
1426
dc_read_serial(unsigned char * byte)1427 int dc_read_serial(unsigned char *byte)
1428 {
1429 int c = scif_read();
1430 if (c == -1) return 0;
1431 *byte = c;
1432 return 1;
1433 }
1434
main(int argc,char ** argv)1435 int main(int argc, char **argv)
1436 {
1437 printf("Atari800DC main() starting\n"); /* workaound for fopen-before-printf kos bug */
1438 printf("--------------------------\n"); /* �$%&!:-grr! */
1439
1440 /* initialize screen updater */
1441 update_screen_updater();
1442
1443 /* initialize Atari800 core */
1444 Atari800_Initialise(&argc, argv);
1445
1446 /* initialize dc controllers for the first time */
1447 dc_controller_init();
1448
1449 /* initialize sound */
1450 dc_sound_init();
1451
1452 /*
1453 ser_console_init();
1454 dbgio_init();
1455 */
1456
1457 #ifdef DEBUG
1458 printf("\nFor Tobias & Dominik\n");
1459 printf("--------------------\n");
1460 #endif
1461
1462 #ifdef HZ_TEST
1463 do_hz_test();
1464 #endif
1465
1466 #if 0
1467 gdb_init();
1468 asm("mov #7,r12");
1469 asm("trapa #0x20");
1470 asm("nop");
1471 asm("nop");
1472 asm("nop");
1473 asm("nop");
1474 asm("nop");
1475 asm("nop");
1476 //gdb_breakpoint();
1477 #endif
1478
1479 atari_screen_backup = malloc(Screen_HEIGHT * Screen_WIDTH);
1480 atari_screen_backup2 = malloc(Screen_HEIGHT * Screen_WIDTH);
1481
1482 chdir("/"); /* initialize cwd in dc_chdir.c */
1483 autostart();
1484
1485 /* main loop */
1486 while(TRUE)
1487 {
1488 int keycode;
1489
1490 keycode = PLATFORM_Keyboard();
1491
1492 switch (keycode) {
1493 case AKEY_5200_RESET:
1494 if (Atari800_machine_type == Atari800_MACHINE_5200) {
1495 Atari800_Coldstart();
1496 }
1497 break;
1498 #ifdef KB_UI
1499 case AKEY_KEYB:
1500 if (Atari800_machine_type != Atari800_MACHINE_5200) {
1501 Sound_Pause();
1502 in_kbui = TRUE;
1503 if (x_ovr || y_ovr || b_ovr) {
1504 kb_ui((UBYTE *)Screen_atari, NULL, KB_CONSOL);
1505 }
1506 else {
1507 kb_ui((UBYTE *)Screen_atari, NULL, 0);
1508 }
1509 in_kbui = FALSE;
1510 INPUT_key_consol |= INPUT_CONSOL_START;
1511 /*b_ui_leave = TRUE; crashes when included!! why?? */
1512 Sound_Continue();
1513 controller_update();
1514 }
1515 else {
1516 Sound_Pause();
1517 in_kbui = TRUE;
1518 kb_ui_5200((UBYTE *)Screen_atari);
1519 in_kbui = FALSE;
1520 Sound_Continue();
1521 controller_update();
1522 }
1523 break;
1524 #endif /* #ifdef KB_UI */
1525 case AKEY_BREAK:
1526 INPUT_key_code = AKEY_BREAK;
1527 break;
1528 default:
1529 INPUT_key_code = keycode;
1530 break;
1531 }
1532
1533 Atari800_Frame();
1534 PLATFORM_DisplayScreen();
1535 controller_update(); /* get new values from the controllers */
1536 }
1537 }
1538
1539 /*
1540 * autostart: check for autorun.xxx files on the
1541 * CD root directory and start the first one found
1542 */
autostart(void)1543 static void autostart(void)
1544 {
1545 struct stat sb;
1546
1547 if (! stat("/cd/autorun.com", &sb)) {
1548 if (S_ISREG(sb.st_mode)) {
1549 if (BINLOAD_Loader("/cd/autorun.com")) {
1550 Atari800_Coldstart();
1551 return;
1552 }
1553 }
1554 }
1555 if (! stat("/cd/autorun.exe", &sb)) {
1556 if (S_ISREG(sb.st_mode)) {
1557 if (BINLOAD_Loader("/cd/autorun.exe")) {
1558 Atari800_Coldstart();
1559 return;
1560 }
1561 }
1562 }
1563 if (! stat("/cd/autorun.atr", &sb)) {
1564 if (S_ISREG(sb.st_mode)) {
1565 SIO_Mount(1, "/cd/autorun.atr", TRUE);
1566 return;
1567 }
1568 }
1569 }
1570
1571 #if 0 /* not stable, KOS crashes sometimes with files on the ramdisk */
1572 static char mytmpnam[] = "/ram/tmpf";
1573 char *tmpnam(char *space)
1574 {
1575 static int inc = 0;
1576 char b[16];
1577 if (space) {
1578 strcpy(space, mytmpnam);
1579 sprintf(b, ".%d\n", inc++);
1580 strcat(space, b);
1581 return(space);
1582 }
1583 else {
1584 return(mytmpnam);
1585 }
1586 }
1587 char *_tmpnam_r (struct reent *r, char *s)
1588 {
1589 return tmpnam(s);
1590 }
1591 #endif
1592
1593 /* parts taken from KOS' kernel/libc/koslib/opendir.c */
1594 static int odc;
opendir(const char * name)1595 DIR *opendir(const char *name)
1596 {
1597 file_t handle;
1598 DIR *newd;
1599 #ifdef DEBUG
1600 printf("opendir...(%s)\n", name);
1601 #endif
1602 if (open_tray) return(NULL);
1603 /*if (tray_closed)*/ tray_closed = FALSE;
1604
1605 if (! strcmp(name, "/cd")) {
1606 /* hack */
1607 cdrom_init();
1608 iso_reset();
1609 }
1610 if (strcmp(name, "/")
1611 && strcmp(name, "/cd") && strcmp(name, "/pc") && strcmp(name, "/ram")
1612 && strcmp(name, "/vmu") && strcmp(name, "/pty") && strcmp(name, "/rd")
1613 && strncmp(name, "/cd/", 4) && strncmp(name, "/pc/", 4) && strncmp(name, "/ram/", 5)
1614 && strncmp(name, "/vmu/", 5) && strncmp(name, "/pty/", 5) && strncmp(name, "/rd/", 4)) {
1615 #ifdef DEBUG
1616 printf("opendir: punt!\n");
1617 #endif
1618 return(NULL);
1619 }
1620 handle = fs_open(name, O_DIR | O_RDONLY);
1621 if (handle < 0) return(NULL);
1622
1623 newd = malloc(sizeof(DIR));
1624 if (!newd) {
1625 errno = ENOMEM;
1626 return(NULL);
1627 }
1628
1629 newd->fd = handle;
1630 memset(&newd->d_ent, 0, sizeof(struct dirent));
1631
1632 if (strcmp(name, "/") && strcmp(name, "/pc") /* no ".." in the root directory */
1633 && strncmp(name, "/pc/", 4)) /* and in /pc and subdirectories */
1634 odc = 1; /* (/pc provides ".." by itself) */
1635 return(newd);
1636 }
1637
1638 static struct dirent myd;
1639
1640 /* parts taken from KOS' kernel/libc/koslib/readdir.c */
readdir(DIR * dir)1641 struct dirent *readdir(DIR *dir)
1642 {
1643 dirent_t *d;
1644
1645 if (open_tray) return(NULL);
1646 if (tray_closed) {
1647 tray_closed = FALSE;
1648 return(NULL);
1649 }
1650 if (odc) {
1651 odc = 0;
1652 memset(&myd, 0, sizeof(struct dirent));
1653 strcpy(myd.d_name, "..");
1654 myd.d_type = 4; // DT_DIR
1655 return(&myd);
1656 }
1657
1658 if (!dir) {
1659 errno = EBADF;
1660 return(NULL);
1661 }
1662 d = fs_readdir(dir->fd);
1663 if (!d) return(NULL);
1664
1665 dir->d_ent.d_ino = 0;
1666 dir->d_ent.d_off = 0;
1667 dir->d_ent.d_reclen = 0;
1668 if (d->size < 0)
1669 dir->d_ent.d_type = 4; // DT_DIR
1670 else
1671 dir->d_ent.d_type = 8; // DT_REG
1672 strncpy(dir->d_ent.d_name, d->name, 255);
1673
1674 return(&dir->d_ent);
1675 }
1676
1677 /* our super-duper stat */
1678 /* only check, whether the S_IFDIR bit has to be set */
stat(const char * path,struct stat * sb)1679 int stat(const char *path, struct stat *sb)
1680 {
1681 file_t handle;
1682
1683 memset(sb, 0, sizeof(struct stat)); /* preinitialize result */
1684
1685 if (open_tray) return(-1);
1686 if (tray_closed) tray_closed = FALSE;
1687
1688 /* special ".." case */
1689 if (strlen(path) > 3 &&
1690 ! strcmp(path + strlen(path) - 3, "/..")) {
1691 sb->st_mode = _IFDIR;
1692 return(0); /* success */
1693 }
1694
1695 /* check if dir */
1696 if ((handle = fs_open(path, O_DIR | O_RDONLY)) != -1) { /* is dir */
1697 sb->st_mode = _IFDIR;
1698 }
1699 else if ((handle = fs_open(path, O_RDONLY)) != -1) { /* is file */
1700 sb->st_mode = _IFREG;
1701 }
1702 else { /* is not here */
1703 #ifdef DEBUG
1704 printf("stat: error with '%s'\n", path);
1705 #endif
1706 return(-1);
1707 }
1708 fs_close(handle);
1709 return(0); /* success */
1710 }
1711
1712 #if 0
1713 static void dc_atari_sync(void)
1714 {
1715 static unsigned long long nextclock = 0;
1716 unsigned long long curclock;
1717 uint32 s, ms;
1718
1719 do {
1720 timer_ms_gettime(&s, &ms);
1721 curclock = ((unsigned long long)s << 32) + ms;
1722 } while (curclock < nextclock);
1723
1724 nextclock = curclock + CLK_TCK / ((Atari800_tv_mode == Atari800_TV_PAL ? 50 : 60));
1725 }
1726 #endif
1727
check_tray_open(void)1728 static int check_tray_open(void)
1729 {
1730 int status, disk_type, retval;
1731
1732 retval = cdrom_get_status(&status, &disk_type);
1733 if (retval == ERR_OK) {
1734 if ((status & 15) == 6) return(TRUE);
1735 return(FALSE);
1736 }
1737 else {
1738 return(FALSE); /* error case: assume tray not open */
1739 }
1740 }
1741
dc_printbox(char * string)1742 void dc_printbox(char *string)
1743 {
1744 int l = strlen(string);
1745
1746 Box(0x9a, 0x94, 20-l/2-1, 11, 20-l/2-1+l+1, 13);
1747 Print(0x94, 0x9a, string, 20-l/2, 12, 40);
1748 }
1749
dc_please_wait(void)1750 void dc_please_wait(void)
1751 {
1752 dc_printbox(" Please wait... ");
1753 entire_Screen_dirty();
1754 PLATFORM_DisplayScreen();
1755 }
1756
dc_error_msg(void)1757 void dc_error_msg(void)
1758 {
1759 dc_printbox(" Error!! ");
1760 entire_Screen_dirty();
1761 PLATFORM_DisplayScreen();
1762 GetKeyPress();
1763 }
1764
DCStateSave(void)1765 void DCStateSave(void)
1766 {
1767 unsigned int i;
1768 int f = 0;
1769
1770 StateSav_SaveINT(&screen_tv_mode, 1);
1771 StateSav_SaveINT(&Atari800_tv_mode, 1);
1772 StateSav_SaveINT(&x_ovr, 1);
1773 StateSav_SaveINT(&x_key, 1);
1774 StateSav_SaveINT(&y_ovr, 1);
1775 StateSav_SaveINT(&y_key, 1);
1776 StateSav_SaveINT(&b_ovr, 1);
1777 StateSav_SaveINT(&b_key, 1);
1778 StateSav_SaveINT(&emulate_paddles, 1);
1779 StateSav_SaveINT(&glob_snd_ena, 1);
1780 StateSav_SaveINT(&db_mode, 1);
1781 StateSav_SaveINT(&INPUT_joy_autofire[0], 1);
1782 StateSav_SaveINT(&disable_js, 1);
1783 StateSav_SaveINT(&disable_dpad, 1);
1784 StateSav_SaveINT(&reverse_x_axis, 1);
1785 StateSav_SaveINT(&reverse_y_axis, 1);
1786 StateSav_SaveINT(&x_adj, 1);
1787 StateSav_SaveINT(&y_adj, 1);
1788 for (i=0; i<16; i++) StateSav_SaveINT(&f, 1); /* future stuff */
1789
1790 #ifdef DEBUG
1791 printf("DCStateSave: tv_mode = %d, screen_tv_mode = %d, db_mode = %d\n",
1792 Atari800_tv_mode, screen_tv_mode, db_mode);
1793 #endif
1794 }
1795
DCStateRead(void)1796 void DCStateRead(void)
1797 {
1798 StateSav_ReadINT(&screen_tv_mode, 1);
1799 StateSav_ReadINT(&Atari800_tv_mode, 1);
1800 StateSav_ReadINT(&x_ovr, 1);
1801 StateSav_ReadINT(&x_key, 1);
1802 StateSav_ReadINT(&y_ovr, 1);
1803 StateSav_ReadINT(&y_key, 1);
1804 StateSav_ReadINT(&b_ovr, 1);
1805 StateSav_ReadINT(&b_key, 1);
1806 StateSav_ReadINT(&emulate_paddles, 1);
1807 StateSav_ReadINT(&glob_snd_ena, 1);
1808 StateSav_ReadINT(&db_mode, 1);
1809 StateSav_ReadINT(&INPUT_joy_autofire[0], 1);
1810 StateSav_ReadINT(&disable_js, 1);
1811 StateSav_ReadINT(&disable_dpad, 1);
1812 StateSav_ReadINT(&reverse_x_axis, 1);
1813 StateSav_ReadINT(&reverse_y_axis, 1);
1814 StateSav_ReadINT(&x_adj, 1);
1815 StateSav_ReadINT(&y_adj, 1);
1816
1817 #ifdef DEBUG
1818 printf("DCStateRead: tv_mode = %d, screen_tv_mode = %d, db_mode = %d\n",
1819 Atari800_tv_mode, screen_tv_mode, db_mode);
1820 #endif
1821
1822 /* sanity check */
1823 if (Atari800_tv_mode != screen_tv_mode) db_mode = FALSE;
1824
1825 update_vidmode();
1826 update_screen_updater();
1827 }
1828
AboutAtariDC(void)1829 void AboutAtariDC(void)
1830 {
1831 UI_driver->fInfoScreen("About AtariDC",
1832 "AtariDC v" A800DCVERASC " ("__DATE__")\0"
1833 "(c) 2002-2013 Christian Groessler\0"
1834 "http://www.groessler.org/a800dc\0"
1835 "\0"
1836 "Please report all problems\0"
1837 "to chris@groessler.org\0"
1838 "\0"
1839 "This port is based on\0"
1840 Atari800_TITLE "\0"
1841 "http://atari800.atari.org\0"
1842 "\0"
1843 "It uses the KallistiOS library\0"
1844 "http://cadcdev.sourceforge.net\0"
1845 "\0"
1846 #if 1
1847 "THIS IS A *BETA* VERSION!\0"
1848 "PLEASE DO NOT DISTRIBUTE\0\0"
1849 #endif
1850 "Dedicated to Tobias & Dominik\0\n");
1851 }
1852
1853
ovr2str(int keycode,char * keystr)1854 static void ovr2str(int keycode, char *keystr)
1855 {
1856 sprintf(keystr, "\"%c\" ($%02X)", UI_BASIC_key_to_ascii[keycode], keycode);
1857 }
1858
1859 /* "Button configuration" submenu of "Controller Configuration" */
ButtonConfiguration(void)1860 void ButtonConfiguration(void)
1861 {
1862 char keystr[3][10];
1863 int option = 0;
1864 static UI_tMenuItem menu_array[] = {
1865 UI_MENU_ACTION(0, "Override X key: "),
1866 UI_MENU_ACTION(1, "Override Y key: "),
1867 UI_MENU_ACTION(2, "Override B key: "),
1868 UI_MENU_END
1869 };
1870
1871
1872 do {
1873 if (x_ovr) {
1874 ovr2str(x_key, keystr[0]);
1875 menu_array[0].suffix = keystr[0];
1876 }
1877 else {
1878 menu_array[0].suffix = "OFF ";
1879 }
1880
1881 if (y_ovr) {
1882 ovr2str(y_key, keystr[1]);
1883 menu_array[1].suffix = keystr[1];
1884 }
1885 else {
1886 menu_array[1].suffix = "OFF ";
1887 }
1888
1889 if (b_ovr) {
1890 ovr2str(b_key, keystr[2]);
1891 menu_array[2].suffix = keystr[2];
1892 }
1893 else {
1894 menu_array[2].suffix = "OFF ";
1895 }
1896
1897 option = UI_driver->fSelect(NULL, TRUE, option, menu_array, NULL);
1898
1899 switch(option) {
1900 case 0:
1901 if (x_ovr) x_ovr = FALSE;
1902 else {
1903 x_key = get_emkey("Select X button definition");
1904 if (x_key != AKEY_NONE) {
1905 x_ovr = TRUE;
1906 }
1907 else {
1908 x_ovr = FALSE;
1909 }
1910 }
1911 break;
1912 case 1:
1913 if (y_ovr) y_ovr = FALSE;
1914 else {
1915 y_key = get_emkey("Select Y button definition");
1916 if (y_key != AKEY_NONE) {
1917 y_ovr = TRUE;
1918 }
1919 else {
1920 y_ovr = FALSE;
1921 }
1922 }
1923 break;
1924 case 2:
1925 if (b_ovr) b_ovr = FALSE;
1926 else {
1927 b_key = get_emkey("Select B button definition");
1928 if (b_key != AKEY_NONE) {
1929 b_ovr = TRUE;
1930 }
1931 else {
1932 b_ovr = FALSE;
1933 }
1934 }
1935 break;
1936 }
1937 } while (option >= 0);
1938 }
1939
1940 /* "Joystick/D-Pad configuration" submenu of "Controller Configuration" */
JoystickConfiguration(void)1941 void JoystickConfiguration(void)
1942 {
1943 int option = 0;
1944 static UI_tMenuItem menu_array[] = {
1945 UI_MENU_ACTION(0, "Disable Joystick: "),
1946 UI_MENU_ACTION(1, "Disable D-Pad:"),
1947 UI_MENU_ACTION(2, "Reverse X axis:"),
1948 UI_MENU_ACTION(3, "Reverse Y axis:"),
1949 UI_MENU_END
1950 };
1951
1952
1953 do {
1954 if (disable_js)
1955 menu_array[0].suffix = "ON ";
1956 else
1957 menu_array[0].suffix = "OFF";
1958
1959 if (disable_dpad)
1960 menu_array[1].suffix = "ON ";
1961 else
1962 menu_array[1].suffix = "OFF";
1963
1964 if (reverse_x_axis)
1965 menu_array[2].suffix = "ON ";
1966 else
1967 menu_array[2].suffix = "OFF";
1968
1969 if (reverse_y_axis)
1970 menu_array[3].suffix = "ON ";
1971 else
1972 menu_array[3].suffix = "OFF";
1973
1974 option = UI_driver->fSelect(NULL, TRUE, option, menu_array, NULL);
1975
1976 switch(option) {
1977 case 0:
1978 disable_js = !disable_js;
1979 break;
1980 case 1:
1981 disable_dpad = !disable_dpad;
1982 break;
1983 case 2:
1984 reverse_x_axis = !reverse_x_axis;
1985 do_reverse_x_axis();
1986 break;
1987 case 3:
1988 reverse_y_axis = !reverse_y_axis;
1989 do_reverse_y_axis();
1990 break;
1991 }
1992 #if 0
1993 if (disable_js && disable_dpad) /* don't allow both to be disabled */
1994 disable_js = disable_dpad = FALSE;
1995 #endif
1996 } while (option >= 0);
1997 }
1998
1999
2000 /* "Screen position configuration" submenu of "Display Settings" */
ScreenPositionConfiguration(void)2001 void ScreenPositionConfiguration(void)
2002 {
2003 int keycode;
2004
2005 ClearScreen();
2006
2007 Box(0x9a, 0x94, 0, 0, 39, 24);
2008 CenterPrint(0x9a, 0x94,"Screen position configuration", 2);
2009
2010 CenterPrint(0x9a, 0x94, "Use up/down/left/right to adjust", 20);
2011 CenterPrint(0x9a, 0x94, "Use ESC to exit", 21);
2012
2013 Print(0x9a, 0x94, "X adjustment:", 8, 9, 40);
2014 Print(0x9a, 0x94, "Y adjustment:", 8, 11, 40);
2015
2016 do {
2017
2018 sprintf(x_str, "%d", x_adj);
2019 sprintf(y_str, "%d", y_adj);
2020
2021 Print(0x9a, 0x94, " ", 31 - 6, 9, 40);
2022 Print(0x9a, 0x94, " ", 31 - 6, 11, 40);
2023
2024 Print(0x9a, 0x94, x_str, 31 - strlen(x_str), 9, 40);
2025 Print(0x9a, 0x94, y_str, 31 - strlen(y_str), 11, 40);
2026
2027 while ((keycode = GetKeyPress()) == AKEY_NONE)
2028 ;
2029
2030 if (keycode == 0x1e) { /* left */
2031 x_adj--;
2032 if (x_adj < -63) x_adj = -63;
2033 }
2034 else if (keycode == 0x1f) { /* right */
2035 x_adj++;
2036 if (x_adj > 63) x_adj = 63;
2037 }
2038 else if (keycode == 0x1c) { /* up */
2039 y_adj--;
2040 if (y_adj < -63) y_adj = -63;
2041 }
2042 else if (keycode == 0x1d) { /* down */
2043 y_adj++;
2044 if (y_adj > 63) y_adj = 63;
2045 }
2046 else
2047 continue;
2048
2049 update_vidmode();
2050 entire_Screen_dirty();
2051 } while (keycode != 0x1b); /* ESC */
2052 }
2053
2054
2055 static int sound_enabled = TRUE; /* sound: on or off */
2056
2057 #define DSPRATE 22050
2058
dc_sound_init(void)2059 void dc_sound_init(void)
2060 {
2061 snd_init();
2062 #ifdef STEREO
2063 POKEYSND_Init(POKEYSND_FREQ_17_EXACT, DSPRATE, 2, 0);
2064 #else
2065 POKEYSND_Init(POKEYSND_FREQ_17_EXACT, DSPRATE, 1, 0);
2066 #endif
2067 }
2068
Sound_Pause(void)2069 void Sound_Pause(void)
2070 {
2071 if (sound_enabled) {
2072 sound_enabled = FALSE;
2073 dc_snd_stream_stop();
2074 }
2075 }
2076
Sound_Continue(void)2077 void Sound_Continue(void)
2078 {
2079 if (! sound_enabled && glob_snd_ena) {
2080 sound_enabled = TRUE;
2081 su_first_call = TRUE;
2082 }
2083 }
2084
Sound_Exit(void)2085 void Sound_Exit(void)
2086 {
2087 #ifdef DEBUG
2088 printf("Sound_Exit called\n");
2089 #endif
2090 }
2091
2092 /* taken from KOS' snd_stream.c */
2093 #define SPU_RAM_BASE 0xa0800000
2094
2095 #define FRAG_SIZE 0x80 /* size of one fragment */
2096 #define FRAG_NUM 16 /* max. # of fragments in the buffer */
2097 #define FRAG_BUFSZ (FRAG_NUM * FRAG_SIZE)
2098
2099 static unsigned char fragbuf[FRAG_BUFSZ]; /* scratch buffer to generate sound data for a fragment */
2100 static uint32 spu_ram_sch1 = 0;
2101
2102 /* ripped from KOS */
dc_snd_stream_stop(void)2103 static void dc_snd_stream_stop(void)
2104 {
2105 AICA_CMDSTR_CHANNEL(tmp, cmd, chan);
2106
2107 /* Stop stream */
2108 /* Channel 0 */
2109 cmd->cmd = AICA_CMD_CHAN;
2110 cmd->timestamp = 0;
2111 cmd->size = AICA_CMDSTR_CHANNEL_SIZE;
2112 cmd->cmd_id = 0;
2113 chan->cmd = AICA_CH_CMD_STOP;
2114 snd_sh4_to_aica(tmp, cmd->size);
2115 }
2116
2117 /* ripped from KOS */
aica_getpos(int chan)2118 static inline unsigned int aica_getpos(int chan)
2119 {
2120 return(g2_read_32(SPU_RAM_BASE + AICA_CHANNEL(chan) + offsetof(aica_channel_t, pos)));
2121 }
2122
2123 /* some parts taken from KOS' snd_stream.c */
Sound_Update(void)2124 void Sound_Update(void)
2125 {
2126 static int last_frag;
2127 int cur_pos, cur_frag, fill_frag, first_frag_to_fill, last_frag_to_fill;
2128 int n, k;
2129
2130 if (! sound_enabled) return;
2131
2132 if (su_first_call) {
2133 AICA_CMDSTR_CHANNEL(tmp, cmd, chan);
2134
2135 su_first_call = FALSE;
2136
2137 if (! spu_ram_sch1)
2138 spu_ram_sch1 = snd_mem_malloc(FRAG_BUFSZ);
2139
2140 /* prefill buffers */
2141 POKEYSND_Process(fragbuf, FRAG_BUFSZ);
2142 spu_memload(spu_ram_sch1, fragbuf, FRAG_SIZE);
2143
2144 last_frag = 0;
2145
2146 #ifdef STEREO
2147 #error STEREO not implemented!
2148 #endif
2149 /* start streaming */
2150 /* use channel 0 */
2151 cmd->cmd = AICA_CMD_CHAN;
2152 cmd->timestamp = 0;
2153 cmd->size = AICA_CMDSTR_CHANNEL_SIZE;
2154 cmd->cmd_id = 0;
2155 chan->cmd = AICA_CH_CMD_START;
2156 chan->base = spu_ram_sch1;
2157 chan->type = AICA_SM_8BIT;
2158 chan->length = FRAG_BUFSZ;
2159 chan->loop = 1;
2160 chan->loopstart = 0;
2161 chan->loopend = FRAG_BUFSZ - 1;
2162 chan->freq = DSPRATE;
2163 chan->vol = 240;
2164 chan->pan = 127;
2165 snd_sh4_to_aica(tmp, cmd->size);
2166 }
2167
2168 /* get current playing position */
2169 cur_pos = aica_getpos(0);
2170 cur_frag = cur_pos / FRAG_SIZE;
2171
2172 #if 0 /* new */
2173 if (cur_frag > last_frag) {
2174 n = cur_frag - last_frag - 1;
2175 Pokey_process(fragbuf, n * FRAG_SIZE);
2176 spu_memload(spu_ram_sch1 + FRAG_SIZE * (last_frag + 1),
2177 fragbuf, FRAG_SIZE * n);
2178 }
2179 else {
2180 n = cur_frag - last_frag - 1 + FRAG_NUM;
2181 Pokey_process(fragbuf, n * FRAG_SIZE);
2182 k = FRAG_NUM - last_frag - 1;
2183 if (k) {
2184 spu_memload(spu_ram_sch1 + FRAG_SIZE * (last_frag + 1),
2185 fragbuf, FRAG_SIZE * k);
2186 }
2187 n = n - k;
2188 if (n) {
2189 spu_memload(spu_ram_sch1,
2190 fragbuf + FRAG_SIZE * k, FRAG_SIZE * n);
2191 }
2192 }
2193 last_frag = cur_frag - 1;
2194 if (last_frag < 0) last_frag = 0;
2195 #else
2196 /* calc # of new fragments needed to fill sound buffer */
2197 first_frag_to_fill = last_frag + 1;
2198 first_frag_to_fill %= FRAG_NUM;
2199 last_frag_to_fill = cur_frag;
2200
2201 fill_frag = first_frag_to_fill;
2202
2203 n = last_frag_to_fill - first_frag_to_fill;
2204 if (n < 0) n += FRAG_NUM;
2205 POKEYSND_Process(fragbuf, n * FRAG_SIZE);
2206 k = 0;
2207 while (fill_frag != last_frag_to_fill) {
2208 spu_memload(spu_ram_sch1 + FRAG_SIZE * fill_frag, fragbuf + k * FRAG_SIZE, FRAG_SIZE);
2209 last_frag = fill_frag;
2210 fill_frag++;
2211 fill_frag %= FRAG_NUM;
2212 k++;
2213 }
2214 #endif
2215
2216 #if 0 /* some arm debug stuff */
2217 printf("cur_pos was %x (%x) (%x)\n", cur_pos,
2218 g2_read_32(SPU_RAM_BASE + 0x1f800),
2219 g2_read_32(SPU_RAM_BASE + 0x1f804));
2220 #endif
2221 }
2222