Files
libretro-atari800/atari800/src/atari_falcon.c
T
2015-12-14 14:00:35 +01:00

1242 lines
26 KiB
C

/*
* atari_falcon.c - Atari Falcon specific port code
*
* Copyright (c) 1997-1998 Petr Stehlik and Karel Rous
* Copyright (c) 1998-2014 Atari800 development team (see DOC/CREDITS)
*
* This file is part of the Atari800 emulator project which emulates
* the Atari 400, 800, 800XL, 130XE, and 5200 8-bit computers.
*
* Atari800 is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2 of the License, or
* (at your option) any later version.
*
* Atari800 is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with Atari800; if not, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
*/
#include "config.h"
#include <mint/osbind.h>
#include <string.h>
#include <stdio.h>
#include <stdlib.h> /* for free */
#include <mint/falcon.h> /* for VsetRGB */
#include "falcon/xcb.h" /* for NOVA screensaver */
#include "atari.h"
#include "binload.h"
#include "cpu.h"
#include "colours.h"
#include "ui.h" /* for UI_is_active */
#include "input.h"
#include "akey.h"
#include "screen.h"
#include "antic.h" /* for BITPL_SCR */
#include "platform.h"
#include "monitor.h"
#include "sound.h"
#include "log.h"
#include "util.h"
#include "gem.h"
/* -------------------------------------------------------------------------- */
int get_cookie(long cookie, long *value)
{
long *cookiejar = (long *) Setexc(0x168, -1L);
if (cookiejar) {
while (*cookiejar) {
if (*cookiejar == cookie) {
if (value)
*value = *++cookiejar;
return (1);
}
cookiejar += 2;
}
}
return (0);
}
/* -------------------------------------------------------------------------- */
#ifdef SCREENSAVER
#include "falcon/jclkcook.h"
int Clocky_SS(int on)
{
long adr;
JCLKSTRUCT *jclk;
int oldval;
/* CHECK_CLOCKY_STRUCT; */
if (!get_cookie(CLOCKY_IDENT_NUM, &adr))
return 0;
jclk = (JCLKSTRUCT *) adr;
if (jclk->name != CLOCKY_IDENT) {
return 0;
}
if ((jclk->version / 0x100) != (CLOCKY_VERSION / 0x100)) {
return 0;
}
oldval = jclk->switches.par.SaverOn;
jclk->switches.par.SaverOn = on; /* turn the Clocky's screen saver on/off */
return oldval;
}
static int Clocky_SSval; /* original value */
static int NOVA_SSval;
#endif /* SCREENSAVER */
/* -------------------------------------------------------------------------- */
typedef enum {
UNKNOWN,
TT030,
F030,
Milan,
} Video_HW;
static Video_HW video_hw = UNKNOWN;
static int bitplanes = TRUE; /* Atari 256 colour mode uses 8 bit planes */
static int gl_vdi_handle;
XCB *NOVA_xcb = NULL;
static int NOVA_double_size = FALSE;
static int HOST_WIDTH, HOST_HEIGHT, HOST_PLANES;
#define EMUL_WIDTH (NOVA_double_size ? 2*336 : 336)
#define EMUL_HEIGHT (NOVA_double_size ? 2*240 : 240)
#undef QUAD
#define CENTER_X ((HOST_WIDTH - EMUL_WIDTH) / 2)
#define CENTER_Y ((HOST_HEIGHT - EMUL_HEIGHT) / 2)
#define CENTER (CENTER_X + CENTER_Y * HOST_WIDTH)
#ifdef SHOW_DISK_LED
static int LED_timeout = 0;
#endif
/* -------------------------------------------------------------------------- */
// static int consol;
static int trig0;
static int stick0;
static int joyswap = FALSE;
/* parameters for c2p_uni */
UWORD screenw, screenh, vramw, vramh;
UBYTE *odkud, *kam;
static int delta_screen = FALSE;
UBYTE *oldscreen = NULL; /* pointer to previous screen if double buffering is turned on */
/* parameters for DisplayScreen */
static int skip_N_frames = 0;
extern void init_kb(void);
extern void rem_kb(void);
extern char key_buf[128];
extern UBYTE joy0, joy1, buttons;
_KEYTAB *key_tab;
#define KEYBUF_SIZE 256
unsigned char keybuf[KEYBUF_SIZE];
int kbhead = 0;
UBYTE *Original_Log_base, *Original_Phys_base;
UWORD original_videl_settings[25];
UWORD mode336x240_videl_settings[25]=
{0x0133, 0x0001, 0x3b00, 0x0150, 0x00f0, 0x0008, 0x0002, 0x0010, \
0x00a8, 0x0186, 0x0005, 0x00c6, 0x0095, 0x000d, 0x0292, 0x0083, \
0x0096, 0x0000, 0x0000, 0x0419, 0x03ff, 0x003f, 0x003f, 0x03ff, 0x0415};
static int force_videl = FALSE; /* force Atari800 to switch VIDEL into new resolution by direct HW programming */
static int reprogram_VIDEL = FALSE;
static int new_videl_mode_valid = FALSE;
UBYTE *new_videoram = NULL;
extern void rplanes(void);
extern void rplanes_delta(void);
extern void load_r(void);
extern void save_r(void);
extern ULONG *p_str_p;
ULONG f030coltable[256];
ULONG f030coltable_backup[256];
ULONG *f030_coltable_ptr;
long RGBcoltable[256], RGBcoltable_backup[256];
int coltable[256][3], coltable_backup[256][3];
void get_colors_on_f030(void)
{
int i;
ULONG *x = (ULONG *) 0xff9800;
for (i = 0; i < 256; i++)
f030_coltable_ptr[i] = x[i];
}
void set_colors_on_f030(void)
{
int i;
ULONG *x = (ULONG *) 0xff9800;
for (i = 0; i < 256; i++)
x[i] = f030_coltable_ptr[i];
}
void set_colors(int new)
{
int i;
if (reprogram_VIDEL) {
if (new)
f030_coltable_ptr = f030coltable;
else
f030_coltable_ptr = f030coltable_backup;
Supexec(set_colors_on_f030);
/* VsetRGB(0, 256, new ? RGBcoltable : RGBcoltable_backup); */
}
else {
for(i=0; i<256; i++)
vs_color(gl_vdi_handle, i, new ? coltable[i] : coltable_backup[i]);
}
}
void save_original_colors(void)
{
int i;
if (reprogram_VIDEL) {
f030_coltable_ptr = f030coltable_backup;
Supexec(get_colors_on_f030);
/* VgetRGB(0, 256, RGBcoltable_backup); */
}
else {
for(i=0; i<256; i++)
vq_color(gl_vdi_handle, i, 1, coltable_backup[i]);
}
}
void set_new_colors(void) { set_colors(1); }
void restore_original_colors(void) { set_colors(0); }
/* -------------------------------------------------------------------------- */
void SetupEmulatedEnvironment(void)
{
if (reprogram_VIDEL) {
/* set new video resolution by direct VIDEL programming */
(void)VsetScreen(new_videoram, new_videoram, -1, -1);
p_str_p = (ULONG *)mode336x240_videl_settings;
Supexec(load_r);
new_videl_mode_valid = 1;
}
set_new_colors(); /* setup new color palette */
Supexec(init_kb); /* our keyboard routine */
Bconout(4, 0x14); /* joystick init */
#ifdef BITPL_SCR
if (delta_screen) {
if (Screen_atari_b != NULL) {
memset(Screen_atari_b, 0, (Screen_HEIGHT * Screen_WIDTH));
}
}
#endif
}
void ShutdownEmulatedEnvironment(void)
{
if (new_videl_mode_valid) {
/* restore original VIDEL mode */
p_str_p = (ULONG *) original_videl_settings;
Supexec(load_r);
new_videl_mode_valid = 0;
(void)VsetScreen(Original_Log_base, Original_Phys_base, -1, -1);
}
restore_original_colors();
Supexec(rem_kb); /* original keyboard routine */
Bconout(4, 8); /* joystick disable */
}
int PLATFORM_Initialise(int *argc, char *argv[])
{
int i;
int j;
int work_in[11], work_out[57];
int maxx, maxy, maxw, maxh, wcell, hcell, wbox, hbox;
int video_hardware;
for (i = j = 1; i < *argc; i++) {
int i_a = (i + 1 < *argc); /* is argument available? */
int a_m = FALSE; /* error, argument missing! */
if (strcmp(argv[i], "-interlace") == 0) {
if (i_a)
skip_N_frames = Util_sscandec(argv[++i]);
else a_m = TRUE;
}
else if (strcmp(argv[i], "-joyswap") == 0)
joyswap = TRUE;
else if (strcmp(argv[i], "-videl") == 0)
force_videl = TRUE;
else if (strcmp(argv[i], "-double") == 0)
NOVA_double_size = TRUE;
else if (strcmp(argv[i], "-delta") == 0)
delta_screen = TRUE;
else {
if (strcmp(argv[i], "-help") == 0) {
Log_print("\t-interlace x Generate Falcon screen only every X frame\n");
Log_print("\t-joyswap Exchange joysticks\n");
Log_print("\t-videl direct VIDEL programming (Falcon/VGA only)\n");
Log_print("\t-delta delta screen output (differences only)\n");
}
argv[j++] = argv[i];
}
if (a_m) {
Log_print("Missing argument for '%s'", argv[i]);
return FALSE;
}
}
*argc = j;
/* recalculate color tables */
for (i = 0; i < 256; i++) {
int r = (Colours_table[i] >> 18) & 0x3f;
int g = (Colours_table[i] >> 10) & 0x3f;
int b = (Colours_table[i] >> 2) & 0x3f;
f030coltable[i] = (r << 26) | (g << 18) | (b << 2);
RGBcoltable[i] = (r << 16) | (g << 8) | b;
coltable[i][0] = r * 1000 / 64;
coltable[i][1] = g * 1000 / 64;
coltable[i][2] = b * 1000 / 64;
}
/* check for VIDEL hardware */
if (!get_cookie('_VDO', &video_hardware))
video_hardware = 0;
switch(video_hardware >> 16) {
case 2:
video_hw = TT030;
break;
case 3:
video_hw = F030;
break;
case 4:
video_hw = Milan;
bitplanes = FALSE;
break;
default:
video_hw = UNKNOWN;
bitplanes = FALSE;
}
/* check for NOVA graphics card */
if (get_cookie('NOVA', &NOVA_xcb))
bitplanes = FALSE;
else if (get_cookie('fVDI', NULL))
bitplanes = FALSE;
/* GEM init */
appl_init();
graf_mouse(M_OFF, NULL);
wind_get(0, WF_WORKXYWH, &maxx, &maxy, &maxw, &maxh);
gl_vdi_handle = graf_handle(&wcell, &hcell, &wbox, &hbox);
work_in[0] = Getrez() + 2;
for(i = 1;i < 10;work_in[i++] = 1);
work_in[10] = 2;
v_opnvwk(work_in, &gl_vdi_handle, work_out);
/* get current screen size and color depth */
HOST_WIDTH = work_out[0] + 1;
HOST_HEIGHT = work_out[1] + 1;
vq_extnd(gl_vdi_handle, 1, work_out);
HOST_PLANES = work_out[4];
if (force_videl && video_hw == F030) { /* we may switch VIDEL directly */
bitplanes = TRUE;
/* save original VIDEL settings */
p_str_p = (ULONG *) original_videl_settings;
Supexec(save_r);
if ((new_videoram = (UBYTE *)Mxalloc((336UL*Screen_HEIGHT), 0)) == NULL) {
form_alert(1, "[1][Error allocating video memory ][ OK ]");
exit(-1);
}
/* create new graphics mode 336x240 in 256 colors */
reprogram_VIDEL = 1;
vramw = screenw = 336;
vramh = screenh = Screen_HEIGHT;
}
else if (HOST_PLANES == 8 && HOST_WIDTH >= 320 && HOST_HEIGHT >= Screen_HEIGHT) {
/* current resolution is OK */
vramw = HOST_WIDTH;
vramh = HOST_HEIGHT;
/*
if (vramw > 336)
screenw = 336;
else
*/
screenw = 320;
screenh = Screen_HEIGHT;
}
else {
/* we may also try to switch into proper resolution using XBios call and then
reinitialize VDI - we've been told it would work OK */
if (video_hw == F030)
form_alert(1, "[1][Atari800 emulator needs 320x240|or higher res. in 256 colors.|Or use the -videl switch.][ OK ]");
else
form_alert(1, "[1][Atari800 emulator needs 320x240|or higher res. in 256 colors.][ OK ]");
exit(-1);
}
/* lock GEM */
v_clrwk(gl_vdi_handle); /* clear whole screen */
wind_update(BEG_UPDATE);
save_original_colors();
#ifdef SCREENSAVER
Clocky_SSval = Clocky_SS(0); /* turn off Clocky's screen saver */
if (NOVA_xcb) {
NOVA_SSval = NOVA_xcb->blnk_time;
NOVA_xcb->blnk_time = 0;
}
#endif
Original_Log_base = Logbase();
Original_Phys_base = Physbase();
key_tab = Keytbl(-1, -1, -1);
// consol = 7;
CPU_Initialise();
#ifdef SOUND
if (!Sound_Initialise(argc, argv))
return FALSE;
#endif
SetupEmulatedEnvironment();
return TRUE;
}
/* -------------------------------------------------------------------------- */
int PLATFORM_Exit(int run_monitor)
{
ShutdownEmulatedEnvironment();
#ifdef BUFFERED_LOG
Log_flushlog();
#endif
if (run_monitor) {
if (MONITOR_Run()) {
SetupEmulatedEnvironment();
return 1; /* go back to emulation */
}
}
if (new_videoram)
free(new_videoram);
/* unlock GEM */
wind_update(END_UPDATE);
form_dial(FMD_FINISH, 0, 0, 0, 0, 0, 0, HOST_WIDTH, HOST_HEIGHT); /* redraw screen */
graf_mouse(M_ON, NULL);
/* GEM exit */
appl_exit();
#ifdef SCREENSAVER
Clocky_SS(Clocky_SSval);
if (NOVA_xcb)
NOVA_xcb->blnk_time = NOVA_SSval;
#endif
return 0;
}
/* -------------------------------------------------------------------------- */
inline long DoubleSizeIt(short data)
{
long result;
__asm__ __volatile__("\n\t\
movew %1,%0\n\t\
swap %0\n\t\
movew %1,%0\n\t\
rorw #8,%0\n\t\
rorl #8,%0"
: "=d" (result)
: "d" (data)
);
return result;
}
void PLATFORM_DisplayScreen(void)
{
UBYTE *screen = (UBYTE *) Screen_atari;
static int i = 0;
/*
if (! draw_display)
return;
*/
#ifdef SHOW_DISK_LED
if (LED_timeout)
if (--LED_timeout == 0)
Atari_Set_LED(0);
#endif
if (i < skip_N_frames) {
i++;
return;
}
i = 0;
odkud = screen;
kam = Logbase();
#ifdef BITPL_SCR
oldscreen = Screen_atari_b;
if (delta_screen) {
/* switch between screens to enable delta output */
if (Screen_atari==Screen_atari1) {
Screen_atari = Screen_atari2;
Screen_atari_b = Screen_atari1;
}
else {
Screen_atari = Screen_atari1;
Screen_atari_b = Screen_atari2;
}
}
#endif
if (bitplanes) {
#ifdef BITPL_SCR
if (delta_screen && !UI_is_active)
rplanes_delta();
else
#endif
rplanes();
}
else {
UBYTE *ptr_from = screen + 24;
UBYTE *ptr_mirror = oldscreen + 24;
UBYTE *ptr_dest = kam + CENTER;
int j;
for (j = 0; j < Screen_HEIGHT; j++) {
short cycles;
long *long_ptr_from = ptr_from;
long *long_ptr_mirror = ptr_mirror;
long *long_ptr_dest = ptr_dest;
if (NOVA_double_size) {
cycles = 83;
if (delta_screen && !UI_is_active) {
do {
long data = *long_ptr_from++;
if (data == *long_ptr_mirror++)
long_ptr_dest+=2;
else {
long data2 = DoubleSizeIt((short) data);
long data1 = DoubleSizeIt((short) (data >> 16));
*(long_ptr_dest + HOST_WIDTH / 4) = data1;
*long_ptr_dest++ = data1;
*(long_ptr_dest + HOST_WIDTH / 4) = data2;
*long_ptr_dest++ = data2;
}
} while (cycles--);
}
else {
do {
long data = *long_ptr_from++;
long data2 = DoubleSizeIt((short) data);
long data1 = DoubleSizeIt((short) (data >> 16));
*(long_ptr_dest + HOST_WIDTH / 4) = data1;
*long_ptr_dest++ = data1;
*(long_ptr_dest + HOST_WIDTH / 4) = data2;
*long_ptr_dest++ = data2;
} while (cycles--);
}
ptr_dest += HOST_WIDTH;
}
else {
cycles = 20;
if (delta_screen && !UI_is_active) {
do {
long data;
#define CHECK_AND_WRITE \
data = *long_ptr_from++; \
if (data == *long_ptr_mirror++) \
long_ptr_dest++; \
else \
*long_ptr_dest++ = data;
CHECK_AND_WRITE
CHECK_AND_WRITE
CHECK_AND_WRITE
CHECK_AND_WRITE
} while (cycles--);
}
else {
do {
*long_ptr_dest++ = *long_ptr_from++;
*long_ptr_dest++ = *long_ptr_from++;
*long_ptr_dest++ = *long_ptr_from++;
*long_ptr_dest++ = *long_ptr_from++;
} while (cycles--);
}
}
ptr_from += Screen_WIDTH;
ptr_mirror += Screen_WIDTH;
ptr_dest += HOST_WIDTH;
}
}
}
#ifdef SHOW_DISK_LED
void Atari_Set_LED(int how)
{
if (how) {
Offgibit(~0x02);
LED_timeout = 8;
}
else {
Ongibit(0x02);
LED_timeout = 0;
}
}
#endif
/* -------------------------------------------------------------------------- */
// extern int KEYPRESSED;
extern int UI_alt_function;
int PLATFORM_Keyboard(void)
{
UBYTE shift_key, control_key;
int scancode, keycode;
int i;
trig0 = 1;
stick0 = INPUT_STICK_CENTRE;
shift_key = (key_buf[0x2a] || key_buf[0x36]);
control_key = key_buf[0x1d];
if (!shift_key && !control_key) {
if (key_buf[0x70])
trig0 = 0;
if (key_buf[0x6d] || key_buf[0x6e] || key_buf[0x6f])
stick0 -= (INPUT_STICK_CENTRE - INPUT_STICK_BACK);
if (key_buf[0x6f] || key_buf[0x6c] || key_buf[0x69])
stick0 -= (INPUT_STICK_CENTRE - INPUT_STICK_RIGHT);
if (key_buf[0x6d] || key_buf[0x6a] || key_buf[0x67])
stick0 -= (INPUT_STICK_CENTRE - INPUT_STICK_LEFT);
if (key_buf[0x67] || key_buf[0x68] || key_buf[0x69])
stick0 -= (INPUT_STICK_CENTRE - INPUT_STICK_FORWARD);
}
scancode = 0;
if (stick0 == INPUT_STICK_CENTRE && trig0 == 1) {
for (i = 1; i <= 0x72; i++) { /* search for pressed key */
if (key_buf[i]) {
if (i == 0x1d || i == 0x2a || i == 0x36 /* Shift, Control skip */
|| i == 0x3c || i == 0x3d || i == 0x3e) /* F2, F3, F4 skip */
continue;
scancode = i;
break;
}
}
}
#define SCANCODE_TAB 0x0f
#define SCANCODE_CONTROL 0x1d
#define SCANCODE_LSHIFT 0x2a
#define SCANCODE_RSHIFT 0x36
#define SCANCODE_ALT 0x38
#define SCANCODE_R 0x13
#define SCANCODE_Y 0x2c
#define SCANCODE_O 0x18
#define SCANCODE_A 0x1e
#define SCANCODE_S 0x1f
#define SCANCODE_D 0x20
#define SCANCODE_L 0x26
#define SCANCODE_C 0x2e
#define SCANCODE_T 0x14
UI_alt_function = -1; /* no alt function */
if (key_buf[0x38]) { /* left Alt key is pressed */
if (scancode == SCANCODE_R)
UI_alt_function = UI_MENU_RUN; /* ALT+R .. Run file */
else if (scancode == SCANCODE_Y)
UI_alt_function = UI_MENU_SYSTEM; /* ALT+Y .. Select system */
else if (scancode == SCANCODE_O)
UI_alt_function = UI_MENU_SOUND; /* ALT+O .. mono/stereo sound */
else if (scancode == SCANCODE_A)
UI_alt_function = UI_MENU_ABOUT; /* ALT+A .. About */
else if (scancode == SCANCODE_S)
UI_alt_function = UI_MENU_SAVESTATE; /* ALT+S .. Save state */
else if (scancode == SCANCODE_D)
UI_alt_function = UI_MENU_DISK; /* ALT+D .. Disk management */
else if (scancode == SCANCODE_L)
UI_alt_function = UI_MENU_LOADSTATE; /* ALT+L .. Load state */
else if (scancode == SCANCODE_C)
UI_alt_function = UI_MENU_CARTRIDGE; /* ALT+C .. Cartridge management */
else if (scancode == SCANCODE_T)
UI_alt_function = UI_MENU_CASSETTE; /* ALT+T .. Tape management */
}
if (UI_alt_function != -1)
return AKEY_UI;
BINLOAD_pause_loading = FALSE;
if (key_buf[0x3c]) /* F2 */
INPUT_key_consol &= ~INPUT_CONSOL_OPTION; /* OPTION key ON */
else
INPUT_key_consol |= INPUT_CONSOL_OPTION; /* OPTION key OFF */
if (key_buf[0x3d]) /* F3 */
INPUT_key_consol &= ~INPUT_CONSOL_SELECT; /* SELECT key ON */
else
INPUT_key_consol |= INPUT_CONSOL_SELECT; /* SELECT key OFF */
if (key_buf[0x3e]) /* F4 */
INPUT_key_consol &= ~INPUT_CONSOL_START; /* START key ON */
else
INPUT_key_consol |= INPUT_CONSOL_START; /* START key OFF */
if (scancode) {
/* read ASCII code of pressed key */
if (shift_key)
keycode = *(UBYTE *) (key_tab->shift + scancode);
else
keycode = *(UBYTE *) (key_tab->unshift + scancode);
if (control_key)
keycode -= 64;
switch (keycode) {
case 0x01:
keycode = AKEY_CTRL_a;
break;
case 0x02:
keycode = AKEY_CTRL_b;
break;
case 0x03:
keycode = AKEY_CTRL_c;
break;
case 0x04:
keycode = AKEY_CTRL_d;
break;
case 0x05:
keycode = AKEY_CTRL_e;
break;
case 0x06:
keycode = AKEY_CTRL_f;
break;
case 0x07:
keycode = AKEY_CTRL_g;
break;
case 0x08:
if (scancode == 0x0e)
keycode = AKEY_BACKSPACE;
else
keycode = AKEY_CTRL_h;
break;
case 0x09:
if (scancode == 0x0f) {
if (shift_key)
keycode = AKEY_SETTAB;
else if (control_key)
keycode = AKEY_CLRTAB;
else
keycode = AKEY_TAB;
}
else
keycode = AKEY_CTRL_i;
break;
case 0x0a:
keycode = AKEY_CTRL_j;
break;
case 0x0b:
keycode = AKEY_CTRL_k;
break;
case 0x0c:
keycode = AKEY_CTRL_l;
break;
case 0x0d:
if (scancode == 0x1c || scancode == 0x72)
keycode = AKEY_RETURN;
else
keycode = AKEY_CTRL_m;
break;
case 0x0e:
keycode = AKEY_CTRL_n;
break;
case 0x0f:
keycode = AKEY_CTRL_o;
break;
case 0x10:
keycode = AKEY_CTRL_p;
break;
case 0x11:
keycode = AKEY_CTRL_q;
break;
case 0x12:
keycode = AKEY_CTRL_r;
break;
case 0x13:
keycode = AKEY_CTRL_s;
break;
case 0x14:
keycode = AKEY_CTRL_t;
break;
case 0x15:
keycode = AKEY_CTRL_u;
break;
case 0x16:
keycode = AKEY_CTRL_v;
break;
case 0x17:
keycode = AKEY_CTRL_w;
break;
case 0x18:
keycode = AKEY_CTRL_x;
break;
case 0x19:
keycode = AKEY_CTRL_y;
break;
case 0x1a:
keycode = AKEY_CTRL_z;
break;
case ' ':
keycode = AKEY_SPACE;
break;
case '`':
keycode = AKEY_CAPSTOGGLE;
break;
case '!':
keycode = AKEY_EXCLAMATION;
break;
case '"':
keycode = AKEY_DBLQUOTE;
break;
case '#':
keycode = AKEY_HASH;
break;
case '$':
keycode = AKEY_DOLLAR;
break;
case '%':
keycode = AKEY_PERCENT;
break;
case '&':
keycode = AKEY_AMPERSAND;
break;
case '\'':
keycode = AKEY_QUOTE;
break;
case '@':
keycode = AKEY_AT;
break;
case '(':
keycode = AKEY_PARENLEFT;
break;
case ')':
keycode = AKEY_PARENRIGHT;
break;
case '[':
keycode = AKEY_BRACKETLEFT;
break;
case ']':
keycode = AKEY_BRACKETRIGHT;
break;
case '<':
keycode = AKEY_LESS;
break;
case '>':
keycode = AKEY_GREATER;
break;
case '=':
keycode = AKEY_EQUAL;
break;
case '?':
keycode = AKEY_QUESTION;
break;
case '-':
keycode = AKEY_MINUS;
break;
case '+':
keycode = AKEY_PLUS;
break;
case '*':
keycode = AKEY_ASTERISK;
break;
case '/':
keycode = AKEY_SLASH;
break;
case ':':
keycode = AKEY_COLON;
break;
case ';':
keycode = AKEY_SEMICOLON;
break;
case ',':
keycode = AKEY_COMMA;
break;
case '.':
keycode = AKEY_FULLSTOP;
break;
case '_':
keycode = AKEY_UNDERSCORE;
break;
case '^':
keycode = AKEY_CIRCUMFLEX;
break;
case '\\':
keycode = AKEY_BACKSLASH;
break;
case '|':
keycode = AKEY_BAR;
break;
case '0':
keycode = AKEY_0;
break;
case '1':
keycode = AKEY_1;
break;
case '2':
keycode = AKEY_2;
break;
case '3':
keycode = AKEY_3;
break;
case '4':
keycode = AKEY_4;
break;
case '5':
keycode = AKEY_5;
break;
case '6':
keycode = AKEY_6;
break;
case '7':
keycode = AKEY_7;
break;
case '8':
keycode = AKEY_8;
break;
case '9':
keycode = AKEY_9;
break;
case 'a':
keycode = AKEY_a;
break;
case 'b':
keycode = AKEY_b;
break;
case 'c':
keycode = AKEY_c;
break;
case 'd':
keycode = AKEY_d;
break;
case 'e':
keycode = AKEY_e;
break;
case 'f':
keycode = AKEY_f;
break;
case 'g':
keycode = AKEY_g;
break;
case 'h':
keycode = AKEY_h;
break;
case 'i':
keycode = AKEY_i;
break;
case 'j':
keycode = AKEY_j;
break;
case 'k':
keycode = AKEY_k;
break;
case 'l':
keycode = AKEY_l;
break;
case 'm':
keycode = AKEY_m;
break;
case 'n':
keycode = AKEY_n;
break;
case 'o':
keycode = AKEY_o;
break;
case 'p':
keycode = AKEY_p;
break;
case 'q':
keycode = AKEY_q;
break;
case 'r':
keycode = AKEY_r;
break;
case 's':
keycode = AKEY_s;
break;
case 't':
keycode = AKEY_t;
break;
case 'u':
keycode = AKEY_u;
break;
case 'v':
keycode = AKEY_v;
break;
case 'w':
keycode = AKEY_w;
break;
case 'x':
keycode = AKEY_x;
break;
case 'y':
keycode = AKEY_y;
break;
case 'z':
keycode = AKEY_z;
break;
case 'A':
keycode = AKEY_A;
break;
case 'B':
keycode = AKEY_B;
break;
case 'C':
keycode = AKEY_C;
break;
case 'D':
keycode = AKEY_D;
break;
case 'E':
keycode = AKEY_E;
break;
case 'F':
keycode = AKEY_F;
break;
case 'G':
keycode = AKEY_G;
break;
case 'H':
keycode = AKEY_H;
break;
case 'I':
keycode = AKEY_I;
break;
case 'J':
keycode = AKEY_J;
break;
case 'K':
keycode = AKEY_K;
break;
case 'L':
keycode = AKEY_L;
break;
case 'M':
keycode = AKEY_M;
break;
case 'N':
keycode = AKEY_N;
break;
case 'O':
keycode = AKEY_O;
break;
case 'P':
keycode = AKEY_P;
break;
case 'Q':
keycode = AKEY_Q;
break;
case 'R':
keycode = AKEY_R;
break;
case 'S':
keycode = AKEY_S;
break;
case 'T':
keycode = AKEY_T;
break;
case 'U':
keycode = AKEY_U;
break;
case 'V':
keycode = AKEY_V;
break;
case 'W':
keycode = AKEY_W;
break;
case 'X':
keycode = AKEY_X;
break;
case 'Y':
keycode = AKEY_Y;
break;
case 'Z':
keycode = AKEY_Z;
break;
case 0x1b:
keycode = AKEY_ESCAPE;
break;
case 0x00:
switch (scancode) {
case 0x3b: /* F1 */
case 0x61: /* Undo */
keycode = AKEY_UI;
break;
case 0x62: /* Help */
keycode = AKEY_HELP;
break;
case 0x3f: /* F5 */
keycode = shift_key ? AKEY_COLDSTART : AKEY_WARMSTART;
break;
case 0x40: /* F6 */
keycode = AKEY_HELP;
break;
case 0x41: /* F7 */
if (BINLOAD_wait_active) {
BINLOAD_pause_loading = TRUE;
keycode = AKEY_NONE;
}
else
keycode = AKEY_BREAK;
break;
case 0x42: /* F8 */
keycode = PLATFORM_Exit(1) ? AKEY_NONE : AKEY_EXIT; /* invoke monitor */
break;
case 0x43: /* F9 */
keycode = AKEY_EXIT;
break;
case 0x44: /* F10*/
keycode = shift_key ? AKEY_SCREENSHOT_INTERLACE : AKEY_SCREENSHOT;
break;
case 0x50:
keycode = AKEY_DOWN;
break;
case 0x4b:
keycode = AKEY_LEFT;
break;
case 0x4d:
keycode = AKEY_RIGHT;
break;
case 0x48:
keycode = AKEY_UP;
break;
default:
keycode = AKEY_NONE;
break;
}
break;
default:
keycode = AKEY_NONE;
break;
}
}
else
keycode = AKEY_NONE;
// KEYPRESSED = (keycode != AKEY_NONE);
return keycode;
}
/* -------------------------------------------------------------------------- */
int PLATFORM_PORT(int num)
{
if (num == 0) {
if (stick0 == INPUT_STICK_CENTRE && trig0 == 1)
return (((~joy1 << 4) & 0xf0) | ((~joy0) & 0x0f));
else {
if (joyswap)
return ((stick0 << 4) | ((~joy0) & 0x0f));
else
return (((~joy0 << 4) & 0xf0) | stick0);
}
}
else
return 0xff;
}
/* -------------------------------------------------------------------------- */
int PLATFORM_TRIG(int num)
{
switch (num) {
case 0:
return (joy0 > 0x0f) ? 0 : joyswap ? 1 : trig0;
case 1:
return (joy1 > 0x0f) ? 0 : joyswap ? trig0 : 1;
case 2:
case 3:
default:
return 1;
}
}
/* -------------------------------------------------------------------------- */
int main(int argc, char **argv)
{
/* initialise Atari800 core */
if (!Atari800_Initialise(&argc, argv))
return 3;
/* main loop */
for (;;) {
INPUT_key_code = PLATFORM_Keyboard();
Atari800_Frame();
if (Atari800_display_screen)
PLATFORM_DisplayScreen();
}
}