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