Added diagonals directions keys, fix rom path, ability to load focal/basic games using alias, ColorMode toggle hotkey, other fixes and additions. (#23)

* Added BK 0010 diagonal directions keys

* Fixed retrieving rom path on windows

* Searching for filename.bin when a game try to load a file without extension (or with its own extension)

* Restore indentation (oops)

* Support for loading focal games using alias "GAME" (type "L G GAME" in focal prompt, then "G" to start)

* Support for loading focal games using alias "GAME" (type "L G GAME" in focal prompt, then "G" to start)

* Fix BK model override

* Alias "GAME" can also be lower case

* Added RUS/LAT keys (binded to insert/pageup)

* focal/basic detection substring is now case insensitive

* Configurable keys

* Restore const declarations where it was not really needed to remove them.

* Fix warnings

* Libretro Options V2

* Change color mode hotkey

* ColorMode hotkey is now configurable

* Removed comment

* Fix Peripheral option

* Change refresh rate from 25 to 50. RA menu now smooth. Need test.

* Restart support

* Fix sending trash keycodes to emulated computer when pressing unbinded keys

* Fix refresh screen after savestate loading

* Better default for color mode change hotkey

* Configurable soft reset key

* Added Hard reset hotkey

* Added ability to left hotkeys unbinded

* Hotkeys now working in callback mode

* Better key mappings default to avoid collision
This commit is contained in:
xttx 2024-06-29 02:00:36 +03:00 committed by GitHub
parent ea37046ca1
commit 31af5ca5f3
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
8 changed files with 585 additions and 81 deletions

1
.gitignore vendored
View File

@ -7,3 +7,4 @@ readtape
pngtorba
irps.log
everything
/bk_libretro.dll

4
boot.c
View File

@ -81,11 +81,11 @@ static int load_rom11(d_word * rombuf, int byte_off, const char * rompath, int b
}
int
boot_init()
boot_init(int force)
{
int ok = 1;
static unsigned char boot_done = 0;
if (boot_done) return 1;
if (force == 0 && boot_done) return 1;
boot_done = 1;

View File

@ -158,7 +158,7 @@ int load_src(register pdp_regs *p, d_word *data);
extern void line_init(void);
void bk_scr_init(void);
int boot_init(void);
int boot_init(int force);
void timer_init(void);
void printer_init(void);
void covox_init(void);
@ -571,6 +571,7 @@ static inline enum joystick_state JOYSTICK_BUTTON(int idx) {
void platform_disk_init(disk_t *disks);
extern char * tape_prefix;
extern char * tape_suffix;
void load_and_run_bin(const void *data, size_t sz);
void *load_rom_file(const char * rompath, size_t *sz, size_t min_sz, size_t max_sz);

View File

@ -11,4 +11,5 @@ void libretro_vfs_read(struct libretro_handle *h, void *s, uint64_t len);
void scr_mark_dirty (void);
void tty_set_keymap (void);
void tty_poll();
char* strtoupper(const char* str);

View File

@ -111,7 +111,7 @@ void retro_get_system_info(struct retro_system_info *info)
info->valid_extensions = "bin|img|dsk|bkd";
}
#define FPS 25
#define FPS 50
#define SAMPLE_RATE io_sound_freq
void retro_get_system_av_info(struct retro_system_av_info *info)
@ -132,6 +132,290 @@ enum {
SUBSYSTEM_4_FLOPPIES,
};
void set_options_v1(retro_environment_t cb) {
static struct retro_variable variables[] =
{
{
"bk_model",
"Model (restart); BK-0010|BK-0010.01|BK-0010.01 + FDD|BK-0011M + FDD|Terak 8510/a|Slow BK-0011M",
},
{
"bk_peripheral",
"Peripheral (UP port, restart); none|covox|ay_3_8910|mouse_high|mouse_low|joystick",
},
{
"bk_layout",
"Keyboard layout; qwerty|jcuken",
},
{
"bk_doublespeed",
"Double CPU speed; disabled|enabled",
},
{
"bk_color",
"Use color display; enabled|disabled",
},
{
"bk_keyboard_type",
"Keyboard type (restart); poll|callback",
},
{
"bk_aspect_ratio",
"Aspect ratio; 1:1|4:3",
},
{ "input_repeat", "", },
{ "input_kt", "", },
{ "input_r2", "", },
{ "input_l1", "", },
{ "input_r1", "", },
{ "input_indsu", "", },
{ "input_block", "", },
{ "input_step", "", },
{ "input_reset", "", },
{ "input_tab", "", },
{ "input_vs", "", },
{ "input_rus", "", },
{ "input_lat", "", },
{ "input_colormode", "", },
{ "input_softreset", "", },
{ "input_hardreset", "", },
{ NULL, NULL },
};
char buf[20][1024];
char* inp_opt = "---|Tilde|Insert|Delete|Home|End|PageUP|PageDown|Tab|LShift|RShift|LAlt|RAlt|LCtrl|RCtrl|Keypad_0|Keypad_1|Keypad_2|Keypad_3|Keypad_4|Keypad_5|Keypad_6|Keypad_7|Keypad_8|Keypad_9|Keypad_Divide|Keypad_Multiply|Keypad_Add|Keypad_Substract|Keypad_Dot|Keypad_Enter|F1|F2|F3|F4|F5|F6|F7|F8|F9|F10|F11|F12";
//Defaults
snprintf(buf[0], sizeof(buf[0]), "Input -> Repeat; F1|%s", inp_opt); variables[7].value = buf[0];
snprintf(buf[1], sizeof(buf[1]), "Input -> KT; F2|%s", inp_opt); variables[8].value = buf[1];
snprintf(buf[2], sizeof(buf[2]), "Input -> |--->; F5|%s", inp_opt); variables[9].value = buf[2];
snprintf(buf[3], sizeof(buf[3]), "Input -> |<---; F4|%s", inp_opt); variables[10].value = buf[3];
snprintf(buf[4], sizeof(buf[4]), "Input -> -|-->; F3|%s", inp_opt); variables[11].value = buf[4];
snprintf(buf[5], sizeof(buf[5]), "Input -> Ind Su; F6|%s", inp_opt); variables[12].value = buf[5];
snprintf(buf[6], sizeof(buf[6]), "Input -> Block; F7|%s", inp_opt); variables[13].value = buf[6];
snprintf(buf[7], sizeof(buf[7]), "Input -> Step; F8|%s", inp_opt); variables[14].value = buf[7];
snprintf(buf[8], sizeof(buf[8]), "Input -> Reset; F9|%s", inp_opt); variables[15].value = buf[8];
snprintf(buf[9], sizeof(buf[9]), "Input -> Tab; Tab|%s", inp_opt); variables[16].value = buf[9];
snprintf(buf[10], sizeof(buf[10]), "Input -> Vs; Home|%s", inp_opt); variables[17].value = buf[10];
snprintf(buf[11], sizeof(buf[11]), "Input -> Rus; Delete|%s", inp_opt); variables[18].value = buf[11];
snprintf(buf[12], sizeof(buf[12]), "Input -> Lat; PageDown|%s", inp_opt); variables[19].value = buf[12];
snprintf(buf[13], sizeof(buf[13]), "Key -> Hotkey -> Color Mode; Keypad_Multiply|%s", inp_opt); variables[20].value = buf[13];
snprintf(buf[14], sizeof(buf[14]), "Key -> Hotkey -> Soft Reset; F11|%s", inp_opt); variables[21].value = buf[14];
snprintf(buf[15], sizeof(buf[15]), "Key -> Hotkey -> Hard Reset; F12|%s", inp_opt); variables[22].value = buf[15];
cb(RETRO_ENVIRONMENT_SET_VARIABLES, variables);
//Real options
snprintf(buf[0], sizeof(buf[0]), "Input -> Repeat; %s", inp_opt); variables[7].value = buf[0];
snprintf(buf[1], sizeof(buf[1]), "Input -> KT; %s", inp_opt); variables[8].value = buf[1];
snprintf(buf[2], sizeof(buf[2]), "Input -> |--->; %s", inp_opt); variables[9].value = buf[2];
snprintf(buf[3], sizeof(buf[3]), "Input -> |<---; %s", inp_opt); variables[10].value = buf[3];
snprintf(buf[4], sizeof(buf[4]), "Input -> -|-->; %s", inp_opt); variables[11].value = buf[4];
snprintf(buf[5], sizeof(buf[5]), "Input -> Ind Su; %s", inp_opt); variables[12].value = buf[5];
snprintf(buf[6], sizeof(buf[6]), "Input -> Block; %s", inp_opt); variables[13].value = buf[6];
snprintf(buf[7], sizeof(buf[7]), "Input -> Step; %s", inp_opt); variables[14].value = buf[7];
snprintf(buf[8], sizeof(buf[8]), "Input -> Reset; %s", inp_opt); variables[15].value = buf[8];
snprintf(buf[9], sizeof(buf[9]), "Input -> Tab; %s", inp_opt); variables[16].value = buf[9];
snprintf(buf[10], sizeof(buf[10]), "Input -> Vs; %s", inp_opt); variables[17].value = buf[10];
snprintf(buf[11], sizeof(buf[11]), "Input -> Rus; %s", inp_opt); variables[18].value = buf[11];
snprintf(buf[12], sizeof(buf[12]), "Input -> Lat; %s", inp_opt); variables[19].value = buf[12];
snprintf(buf[13], sizeof(buf[13]), "Key -> Hotkey -> Color Mode; %s", inp_opt); variables[20].value = buf[13];
snprintf(buf[14], sizeof(buf[14]), "Key -> Hotkey -> Soft Reset; %s", inp_opt); variables[21].value = buf[14];
snprintf(buf[15], sizeof(buf[15]), "Key -> Hotkey -> Hard Reset; %s", inp_opt); variables[22].value = buf[15];
cb(RETRO_ENVIRONMENT_SET_VARIABLES, variables);
}
void set_options_v2(retro_environment_t cb) {
struct retro_core_option_v2_category option_cats[] = {
{
"system",
"System",
"Configure system parameters."
},
{
"input",
"Input",
"Remap keyboard system keys."
},
{ NULL, NULL, NULL },
};
struct retro_core_option_v2_definition option_defs[] = {
{
"bk_model", //Key
"Model (restart)", //Description
NULL, //descr_categorized
"Model of the emulated computer.",
NULL, //info categorized
"system", //category_key
{
{ "BK-0010", "BK-0010" },
{ "BK-0010.01", "BK-0010.01" },
{ "BK-0010.01 + FDD", "BK-0010.01 + FDD" },
{ "BK-0011M + FDD", "BK-0011M + FDD" },
{ "Terak 8510/a", "Terak 8510/a" },
{ "Slow BK-0011M", "Slow BK-0011M" },
{ NULL, NULL },
},
"BK-0010", //default_value
},
{
"bk_peripheral",
"Peripheral (UP port, restart)",
NULL,
NULL,
NULL,
"system",
{
{ "none", "None" },
{ "covox", "Covox" },
{ "ay_3_8910", "AY 3 8910" },
{ "mouse_high", "Mouse (high)" },
{ "mouse_low", "Mouse (low)" },
{ "joystick", "Joystick" },
{ NULL, NULL },
},
"none"
},
{
"bk_doublespeed",
"Double CPU speed",
NULL,
NULL,
NULL,
"system",
{
{ "disabled", NULL },
{ "enabled", NULL },
{ NULL, NULL },
},
"disabled"
},
{
"bk_color",
"Use color display",
NULL,
NULL,
NULL,
"system",
{
{ "enabled", NULL },
{ "disabled", NULL },
{ NULL, NULL },
},
"enabled"
},
{
"bk_aspect_ratio",
"Aspect ratio",
NULL,
NULL,
NULL,
"system",
{
{ "1:1", NULL },
{ "4:3", NULL },
{ NULL, NULL },
},
"1:1"
},
{
"bk_layout",
"Keyboard Layout",
NULL,
NULL,
NULL,
"input",
{
{ "qwerty", NULL },
{ "jcuken", NULL },
{ NULL, NULL },
},
"qwerty"
},
{
"bk_keyboard_type",
"Keyboard type (restart)",
NULL,
NULL,
NULL,
"input",
{
{ "poll", NULL },
{ "callback", NULL },
{ NULL, NULL },
},
"poll"
},
{ "input_repeat", "Key -> Repeat", NULL, NULL, NULL, "input", {{NULL,NULL}}, "F1" },
{ "input_kt", "Key -> KT", NULL, NULL, NULL, "input", {{NULL,NULL}}, "F2" },
{ "input_r2", "Key -> |--->", NULL, NULL, NULL, "input", {{NULL,NULL}}, "F5" },
{ "input_l1", "Key -> |<---", NULL, NULL, NULL, "input", {{NULL,NULL}}, "F4" },
{ "input_r1", "Key -> -|-->", NULL, NULL, NULL, "input", {{NULL,NULL}}, "F3" },
{ "input_indsu", "Key -> Ind Su", NULL, NULL, NULL, "input", {{NULL,NULL}}, "F6" },
{ "input_block", "Key -> Block", NULL, NULL, NULL, "input", {{NULL,NULL}}, "F7" },
{ "input_step", "Key -> Step", NULL, NULL, NULL, "input", {{NULL,NULL}}, "F8" },
{ "input_reset", "Key -> Reset", NULL, NULL, NULL, "input", {{NULL,NULL}}, "F9" },
{ "input_tab", "Key -> Tab", NULL, NULL, NULL, "input", {{NULL,NULL}}, "Tab" },
{ "input_vs", "Key -> Vs", NULL, NULL, NULL, "input", {{NULL,NULL}}, "Home" },
{ "input_rus", "Key -> Rus", NULL, NULL, NULL, "input", {{NULL,NULL}}, "Delete" },
{ "input_lat", "Key -> Lat", NULL, NULL, NULL, "input", {{NULL,NULL}}, "PageDown" },
{ "input_colormode", "Key -> Hotkey -> Color Mode", NULL, NULL, NULL, "input", {{NULL,NULL}}, "Keypad_Multiply" },
{ "input_softreset", "Key -> Hotkey -> Soft Reset", NULL, NULL, NULL, "input", {{NULL,NULL}}, "F11" },
{ "input_hardreset", "Key -> Hotkey -> Hard Reset", NULL, NULL, NULL, "input", {{NULL,NULL}}, "F12" },
{ NULL, NULL, NULL, NULL, NULL, NULL, {{0}}, NULL },
};
static const struct retro_core_option_value input_keys_values[RETRO_NUM_CORE_OPTION_VALUES_MAX] = {
{ "---", NULL },
{ "Tilde", NULL },
{ "Insert", NULL },
{ "Delete", NULL },
{ "Home", NULL },
{ "End", NULL },
{ "PageUP", NULL },
{ "PageDown", NULL },
{ "Tab", NULL },
{ "LShift", NULL },
{ "RShift", NULL },
{ "LAlt", NULL },
{ "RAlt", NULL },
{ "LCtrl", NULL },
{ "RCtrl", NULL },
{ "Keypad_0", NULL },
{ "Keypad_1", NULL },
{ "Keypad_2", NULL },
{ "Keypad_3", NULL },
{ "Keypad_4", NULL },
{ "Keypad_5", NULL },
{ "Keypad_6", NULL },
{ "Keypad_7", NULL },
{ "Keypad_8", NULL },
{ "Keypad_9", NULL },
{ "Keypad_Divide", NULL },
{ "Keypad_Multiply", NULL },
{ "Keypad_Add", NULL },
{ "Keypad_Substract", NULL },
{ "Keypad_Dot", NULL },
{ "Keypad_Enter", NULL },
{ "F1", NULL },
{ "F2", NULL },
{ "F3", NULL },
{ "F4", NULL },
{ "F5", NULL },
{ "F6", NULL },
{ "F7", NULL },
{ "F8", NULL },
{ "F9", NULL },
{ "F10", NULL },
{ "F11", NULL },
{ "F12", NULL },
{ NULL, NULL },
};
for (int n = 7; n <= 22; n++)
memcpy(&option_defs[n].values, &input_keys_values, sizeof input_keys_values);
struct retro_core_options_v2 options_v2 = { option_cats, option_defs };
cb(RETRO_ENVIRONMENT_SET_CORE_OPTIONS_V2, &options_v2);
}
void retro_set_environment(retro_environment_t cb)
{
struct retro_log_callback logging;
@ -146,40 +430,12 @@ void retro_set_environment(retro_environment_t cb)
else
log_cb = fallback_log;
static struct retro_variable variables[] =
{
{
"bk_model",
"Model (restart); BK-0010|BK-0010.01|BK-0010.01 + FDD|BK-0011M + FDD|Terak 8510/a|Slow BK-0011M",
},
{
"bk_peripheral",
"Peripheral (UP port, restart); none|covox|ay_3_8910|mouse_high|mouse_low|joystick",
},
{
"bk_layout",
"Keyboard layout; qwerty|jcuken",
},
{
"bk_doublespeed",
"Double CPU speed; disabled|enabled",
},
{
"bk_color",
"Use color display; enabled|disabled",
},
{
"bk_keyboard_type",
"Keyboard type (restart); poll|callback",
},
{
"bk_aspect_ratio",
"Aspect ratio; 1:1|4:3",
},
{ NULL, NULL },
};
cb(RETRO_ENVIRONMENT_SET_VARIABLES, variables);
unsigned version = 0;
if (!cb(RETRO_ENVIRONMENT_GET_CORE_OPTIONS_VERSION, &version)) version = 0;
if (version >= 2)
set_options_v2(cb);
else
set_options_v1(cb);
struct retro_vfs_interface_info vfs_interface_info;
vfs_interface_info.required_interface_version = 1;
@ -261,10 +517,6 @@ void retro_set_video_refresh(retro_video_refresh_t cb)
video_cb = cb;
}
void retro_reset(void)
{
}
#define MAX_SAMPLES_PER_FRAME 5000
static const int16_t zero_samples[MAX_SAMPLES_PER_FRAME * 2];
@ -416,15 +668,22 @@ static bool load_game_real(const char *image_path,
const char *dir;
int i;
bool is_basic = false;
bool is_focal = false;
if (image_path) {
char *slash = strrchr(image_path, '/');
if (!slash) slash = strrchr(image_path, '\\');
if (slash) {
tape_prefix = strdup(image_path);
tape_prefix[slash - image_path + 1] = '\0';
tape_suffix = slash + 1;
//fprintf(stderr, "Tape suffix is: <%s>\n", tape_suffix);
}
is_basic = strstr(strtoupper(image_path), "BASIC") != NULL;
is_focal = strstr(strtoupper(image_path), "FOCAL") != NULL;
}
if (bin) {
if (bin && !is_basic && !is_focal) {
void *gd = malloc(bin_size);
if (!gd)
return false;
@ -468,6 +727,9 @@ static bool load_game_real(const char *image_path,
}
update_variables(true);
if (is_basic) bkmodel = 1;
else if (is_focal) bkmodel = 0;
switch( bkmodel ) {
case 0: /* BK0010 */
@ -506,7 +768,7 @@ static bool load_game_real(const char *image_path,
sim_init(); /* ...the simulated cpu */
mem_init(); /* ...main memory */
bk_scr_init(); /* video display */
if (!boot_init())
if (!boot_init(1))
return false; /* ROM blocks */
q_reset(); /* ...any devices */
@ -588,6 +850,11 @@ void retro_unload_game(void)
{
}
void retro_reset(void)
{
load_game_real(NULL, NULL, 0, NULL, 0);
}
unsigned retro_get_region(void)
{
return RETRO_REGION_NTSC;
@ -610,7 +877,7 @@ bool retro_unserialize(const void *data_, size_t size)
return false;
memcpy(&current_state, data_, sizeof (current_state));
scr_dirty = 1;
scr_mark_dirty();
return true;
}

View File

@ -187,7 +187,7 @@ by the environment variable BK_PATH.\n"), romdir );
sim_init(); /* ...the simulated cpu */
mem_init(); /* ...main memory */
bk_scr_init(); /* video display */
boot_init(); /* ROM blocks */
boot_init(0); /* ROM blocks */
if (terak) {
// setup_terak();
} else {

81
tape.c
View File

@ -25,6 +25,7 @@ unsigned char tape_read_val = 1, tape_write_val = 0;
FILE * tape_read_file = NULL;
FILE * tape_write_file = NULL;
char * tape_prefix = NULL;
char * tape_suffix = NULL;
unsigned char tape_status = 1; /* 0 = tape moving, 1 = tape stopped */
flag_t fake_tape = 1; /* Default */
@ -35,6 +36,23 @@ static enum { Idle, Addr, Len, Name, Data, Checksum } fake_state = Idle;
#define TAPE_RELAY_DELAY 10000
char* strtoupper(const char* str) {
int len = strlen(str);
//Allocate space for new string
char* upper = (char*)malloc(sizeof(char) * (len + 1));
//Add null terminator to string
upper[len] = '\0';
//Convert characters to uppercase one by one
for (int i = 0; i < len; i++) {
upper[i] = toupper(str[i]);
}
return upper;
}
void tape_init() {
if (tape_read_file) {
if (fake_tape) {
@ -149,8 +167,25 @@ get_emt36_filename() {
bk_filename[2*i+1] = d >> 8;
}
bk_filename[16] = '\0';
for (i = 15; i >= 0 && bk_filename[i] == ' '; unix_filename[i--]='\0');
bool append_ext = false;
int name_end_index = 15;
char ext[5]; ext[4] = '\0';
memcpy(ext, &bk_filename[6], 4);
if (strcmp(ext, ".BIN") == 0) { name_end_index = 5; append_ext = true; }
if (strcmp(ext, ".COD") == 0) { name_end_index = 5; append_ext = true; }
if (strcmp(ext, ".ASC") == 0) { name_end_index = 5; append_ext = true; }
//fprintf(stderr, _("Bk_filename: <%s>\n"), bk_filename);
//fprintf(stderr, _("append_ext: <%s>\n"), append_ext);
//fprintf(stderr, _("name_end_index: <%s>\n"), name_end_index);
for (i = name_end_index; i >= 0 && bk_filename[i] == ' '; unix_filename[i--]='\0');
int trimmed_name_end_index = i;
for (; i >= 0; i--) unix_filename[i] = bk_filename[i];
if (append_ext) { memcpy(&unix_filename[trimmed_name_end_index + 1], &ext[0], 5); }
fprintf(stderr, _("Unix filename: <%s>\n"), unix_filename);
}
/*
@ -212,13 +247,35 @@ void fake_read_strobe() {
if (fake_state == Idle && !tape_read_file) {
/* First time here, find which file to open */
get_emt36_filename();
//fprintf(stderr, _("Unix file: <%s>\n"), unix_filename);
//char* fname = rtrim(unix_filename);
//fprintf(stderr, _("Unix file trimmed: <%s>\n"), fname);
//char* snum[5];
//itoa((int)unix_filename[5], snum, 10);
//fprintf(stderr, _("6th fname char: <%s>\n"), snum);
char *alloc_fullpath = NULL;
const char * fullpath = unix_filename;
if (tape_prefix != NULL) {
int al = strlen(unix_filename) + strlen(tape_prefix) + 7;
char* unix_filename_upper = strtoupper(unix_filename);
if (tape_suffix != NULL) {
if (strcmp(unix_filename_upper, "GAME") == 0) { fullpath = tape_suffix; }
else if (strcmp(unix_filename_upper, "GAME.BIN") == 0) { fullpath = tape_suffix; }
else if (strcmp(unix_filename_upper, "GAME.COD") == 0) { fullpath = tape_suffix; }
else if (strcmp(unix_filename_upper, "GAME.ASC") == 0) { fullpath = tape_suffix; }
}
//fprintf(stderr, _("UNIX FILENAME: <%s>\n"), unix_filename);
//fprintf(stderr, _("UNIX FILENAME UPPER: <%s>\n"), unix_filename_upper);
//fprintf(stderr, _("TAPE SUFFIX: <%s>\n"), tape_suffix);
//fprintf(stderr, _("FULLPATH: <%s>\n"), fullpath);
if (tape_prefix != NULL) {
int al = strlen(fullpath) + strlen(tape_prefix) + 7;
alloc_fullpath = malloc (al+1);
strncpy(alloc_fullpath, tape_prefix, al);
strncat(alloc_fullpath, unix_filename, al);
strncat(alloc_fullpath, fullpath, al);
fullpath = alloc_fullpath;
}
tape_read_file = fopen(fullpath, "r");
@ -227,12 +284,26 @@ void fake_read_strobe() {
if (alloc_fullpath)
ptr = alloc_fullpath + strlen(tape_prefix);
else
ptr = alloc_fullpath = strdup(unix_filename);
ptr = alloc_fullpath = strdup(fullpath);
for (; *ptr; ptr++) {
*ptr = tolower(*ptr);
}
fullpath = alloc_fullpath;
tape_read_file = fopen(fullpath, "r");
if (!tape_read_file) {
//Game can ask for file with or without extension (filename / filename.ext),
//which should be resolved to filename.bin and filename.ext.bin respectively
char* dot = strrchr(fullpath, '.');
if (!dot || !strcmp(dot, ".bin")) {
int al2 = strlen(fullpath) + 4;
char* alloc_fullpath2 = malloc(al2 + 1);
strncpy(alloc_fullpath2, fullpath, al2);
strncat(alloc_fullpath2, ".bin", al2);
fullpath = alloc_fullpath2;
tape_read_file = fopen(fullpath, "r");
}
}
}
fprintf(stderr, _("Will read unix file <%s> under BK name <%s>\n"),
fullpath, bk_filename);

View File

@ -13,22 +13,26 @@ struct keymap {
int shifted[RETROK_LAST];
};
//BK Keycodes here: https://bk0010.pdp-11.ru/docs/out.html (check 8.3)
static const struct keymap qwerty = {
.normal = {
[RETROK_ESCAPE] = TTY_STOP,
[RETROK_F1] = 0201, /* Repeat. */
[RETROK_F2] = 003, /* KT */
[RETROK_F3] = 0231, /* -|--> */
[RETROK_F4] = 026, /* |<--- */
[RETROK_F5] = 027, /* |---> */
[RETROK_F6] = 0202, /* ind su */
[RETROK_F7] = 0204, /* block edit */
[RETROK_F8] = 0220, /* step */
[RETROK_F9] = 014, /* clear */
//[RETROK_F1] = 0201, /* Repeat. */
//[RETROK_F2] = 003, /* KT */
//[RETROK_F3] = 0231, /* -|--> */
//[RETROK_F4] = 026, /* |<--- */
//[RETROK_F5] = 027, /* |---> */
//[RETROK_F6] = 0202, /* ind su */
//[RETROK_F7] = 0204, /* block edit */
//[RETROK_F8] = 0220, /* step */
//[RETROK_F9] = 014, /* clear */
[RETROK_F10] = TTY_STOP, /* Stop (red button)*/
[RETROK_F11] = 016,
[RETROK_F12] = 017,
//[RETROK_F11] = 016, /* RUS */
//[RETROK_F12] = 017, /* LAT */
[RETROK_BREAK] = TTY_STOP,
//[RETROK_INSERT] = 016, /* RUS */
//[RETROK_PAGEUP] = 017, /* LAT */
[RETROK_BACKQUOTE] = '`',
[RETROK_1] = '1',
@ -45,7 +49,7 @@ static const struct keymap qwerty = {
[RETROK_EQUALS] = '=',
[RETROK_BACKSPACE] = 0x18,
[RETROK_TAB] = 0x89,
//[RETROK_TAB] = 0x89,
[RETROK_q] = 'q',
[RETROK_w] = 'w',
[RETROK_e] = 'e',
@ -91,7 +95,12 @@ static const struct keymap qwerty = {
[RETROK_RIGHT] = 031,
[RETROK_DOWN] = 033,
[RETROK_HOME] = 023, /* vs */
[RETROK_KP7] = 034,
[RETROK_KP9] = 035,
[RETROK_KP1] = 036,
[RETROK_KP3] = 037,
//[RETROK_HOME] = 023, /* vs */
},
.shifted = {
[RETROK_BACKQUOTE] = '~',
@ -150,21 +159,21 @@ static const struct keymap qwerty = {
static const struct keymap jcuken = {
.normal = {
[RETROK_ESCAPE] = TTY_STOP,
[RETROK_F1] = 0201, /* Repeat. */
[RETROK_F2] = 003, /* KT */
[RETROK_F3] = 0231, /* -|--> */
[RETROK_F4] = 026, /* |<--- */
[RETROK_F5] = 027, /* |---> */
[RETROK_F6] = 0202, /* ind su */
[RETROK_F7] = 0204, /* block edit */
[RETROK_F8] = 0220, /* step */
[RETROK_F9] = 014, /* clear */
//[RETROK_F1] = 0201, /* Repeat. */
//[RETROK_F2] = 003, /* KT */
//[RETROK_F3] = 0231, /* -|--> */
//[RETROK_F4] = 026, /* |<--- */
//[RETROK_F5] = 027, /* |---> */
//[RETROK_F6] = 0202, /* ind su */
//[RETROK_F7] = 0204, /* block edit */
//[RETROK_F8] = 0220, /* step */
//[RETROK_F9] = 014, /* clear */
[RETROK_F10] = TTY_STOP, /* Stop (red button)*/
// Those 3 don't completely match original as there are no additional keys in bottom row
// on modern keyboard
[RETROK_F11] = 016,
[RETROK_F12] = 017,
//[RETROK_F11] = 016,
//[RETROK_F12] = 017,
[RETROK_BREAK] = TTY_STOP,
[RETROK_BACKQUOTE] = ';',
@ -182,7 +191,7 @@ static const struct keymap jcuken = {
[RETROK_EQUALS] = '/',
[RETROK_BACKSPACE] = 0x18,
[RETROK_TAB] = 0x89,
//[RETROK_TAB] = 0x89,
[RETROK_q] = 'J',
[RETROK_w] = 'C',
[RETROK_e] = 'U',
@ -230,7 +239,7 @@ static const struct keymap jcuken = {
[RETROK_RIGHT] = 031,
[RETROK_DOWN] = 033,
[RETROK_HOME] = 023, /* vs */
//[RETROK_HOME] = 023, /* vs */
},
.shifted = {
[RETROK_BACKQUOTE] = '+',
@ -291,6 +300,22 @@ static const struct keymap jcuken = {
static const struct keymap *current_keymap = &qwerty;
static bool curstate[RETROK_LAST];
void toggle_color_mode() {
struct retro_variable var = { 0 };
var.key = "bk_color";
var.value = NULL;
if (environ_cb(RETRO_ENVIRONMENT_GET_VARIABLE, &var) && var.value) {
if (strcmp(var.value, "enabled") == 0)
var.value = "disabled";
else
var.value = "enabled";
}
else {
var.value = "disabled";
}
environ_cb(RETRO_ENVIRONMENT_SET_VARIABLE, &var);
}
static RETRO_CALLCONV void keyboard_cb(bool down, unsigned keycode,
uint32_t character, uint16_t mod)
{
@ -328,6 +353,11 @@ static RETRO_CALLCONV void keyboard_cb(bool down, unsigned keycode,
if (c == 0) {
return;
}
if (c == 10000 && down) { toggle_color_mode(); return; }
if (c == 10001 && down) { c = TTY_RESET; }
if (c == 10002 && down) { retro_reset(); return; }
/* TODO: caps lock. */
if (ctrl && (c & 0100))
c &= 037;
@ -337,6 +367,111 @@ static RETRO_CALLCONV void keyboard_cb(bool down, unsigned keycode,
c |= 0200;
}
tty_keyevent(c);
//fprintf(stderr, "Send keycode: <%d>\n", c);
}
int get_libretro_key(const char* key_name) {
if (strcmp(key_name, "---") == 0)
return 0;
else if (strcmp(key_name, "Tilde") == 0)
return RETROK_TILDE;
else if (strcmp(key_name, "Insert") == 0)
return RETROK_INSERT;
else if (strcmp(key_name, "Delete") == 0)
return RETROK_DELETE;
else if (strcmp(key_name, "Home") == 0)
return RETROK_HOME;
else if (strcmp(key_name, "End") == 0)
return RETROK_END;
else if (strcmp(key_name, "PageUP") == 0)
return RETROK_PAGEUP;
else if (strcmp(key_name, "PageDown") == 0)
return RETROK_PAGEDOWN;
else if (strcmp(key_name, "Tab") == 0)
return RETROK_TAB;
else if (strcmp(key_name, "LShift") == 0)
return RETROK_LSHIFT;
else if (strcmp(key_name, "RShift") == 0)
return RETROK_RSHIFT;
else if (strcmp(key_name, "LAlt") == 0)
return RETROK_LALT;
else if (strcmp(key_name, "RAlt") == 0)
return RETROK_RALT;
else if (strcmp(key_name, "LCtrl") == 0)
return RETROK_LCTRL;
else if (strcmp(key_name, "RCtrl") == 0)
return RETROK_RCTRL;
else if (strcmp(key_name, "Keypad_0") == 0)
return RETROK_KP0;
else if (strcmp(key_name, "Keypad_1") == 0)
return RETROK_KP1;
else if (strcmp(key_name, "Keypad_2") == 0)
return RETROK_KP2;
else if (strcmp(key_name, "Keypad_3") == 0)
return RETROK_KP3;
else if (strcmp(key_name, "Keypad_4") == 0)
return RETROK_KP4;
else if (strcmp(key_name, "Keypad_5") == 0)
return RETROK_KP5;
else if (strcmp(key_name, "Keypad_6") == 0)
return RETROK_KP6;
else if (strcmp(key_name, "Keypad_7") == 0)
return RETROK_KP7;
else if (strcmp(key_name, "Keypad_8") == 0)
return RETROK_KP8;
else if (strcmp(key_name, "Keypad_9") == 0)
return RETROK_KP9;
else if (strcmp(key_name, "Keypad_Divide") == 0)
return RETROK_KP_DIVIDE;
else if (strcmp(key_name, "Keypad_Multiply") == 0)
return RETROK_KP_MULTIPLY;
else if (strcmp(key_name, "Keypad_Add") == 0)
return RETROK_KP_MINUS;
else if (strcmp(key_name, "Keypad_Substract") == 0)
return RETROK_KP_PLUS;
else if (strcmp(key_name, "Keypad_Dot") == 0)
return RETROK_KP_PERIOD;
else if (strcmp(key_name, "Keypad_Enter") == 0)
return RETROK_KP_ENTER;
else if (strcmp(key_name, "F1") == 0)
return RETROK_F1;
else if (strcmp(key_name, "F2") == 0)
return RETROK_F2;
else if (strcmp(key_name, "F3") == 0)
return RETROK_F3;
else if (strcmp(key_name, "F4") == 0)
return RETROK_F4;
else if (strcmp(key_name, "F5") == 0)
return RETROK_F5;
else if (strcmp(key_name, "F6") == 0)
return RETROK_F6;
else if (strcmp(key_name, "F7") == 0)
return RETROK_F7;
else if (strcmp(key_name, "F8") == 0)
return RETROK_F8;
else if (strcmp(key_name, "F9") == 0)
return RETROK_F9;
else if (strcmp(key_name, "F10") == 0)
return RETROK_F10;
else if (strcmp(key_name, "F11") == 0)
return RETROK_F11;
else if (strcmp(key_name, "F12") == 0)
return RETROK_F12;
else
return 0;
}
void set_bk_key(const char* key_name, int bk_key_code, struct keymap* keycodes) {
int k = 0;
struct retro_variable var;
var.key = key_name; var.value = NULL;
if (environ_cb(RETRO_ENVIRONMENT_GET_VARIABLE, &var) && var.value) {
k = get_libretro_key(var.value);
//current_keymap->normal[k] = bk_key_code;
keycodes->normal[k] = bk_key_code;
}
}
void
@ -347,11 +482,33 @@ tty_set_keymap()
var.key = "bk_layout";
var.value = NULL;
static struct keymap current_keymap_vals;
if (environ_cb(RETRO_ENVIRONMENT_GET_VARIABLE, &var) && var.value && strcmp(var.value, "jcuken") == 0) {
current_keymap = &jcuken;
//current_keymap = &jcuken;
memcpy(&current_keymap_vals, &jcuken, sizeof(jcuken));
} else {
current_keymap = &qwerty;
//current_keymap = &qwerty;
memcpy(&current_keymap_vals, &qwerty, sizeof(qwerty));
}
set_bk_key("input_repeat", 0201, &current_keymap_vals);
set_bk_key("input_kt", 003, &current_keymap_vals);
set_bk_key("input_r2", 027, &current_keymap_vals);
set_bk_key("input_l1", 026, &current_keymap_vals);
set_bk_key("input_r1", 0231, &current_keymap_vals);
set_bk_key("input_indsu", 0202, &current_keymap_vals);
set_bk_key("input_block", 0204, &current_keymap_vals);
set_bk_key("input_step", 0220, &current_keymap_vals);
set_bk_key("input_reset", 014, &current_keymap_vals);
set_bk_key("input_tab", 0x89, &current_keymap_vals);
set_bk_key("input_vs", 023, &current_keymap_vals);
set_bk_key("input_rus", 016, &current_keymap_vals);
set_bk_key("input_lat", 017, &current_keymap_vals);
set_bk_key("input_colormode", 10000, &current_keymap_vals);
set_bk_key("input_softreset", 10001, &current_keymap_vals);
set_bk_key("input_hardreset", 10002, &current_keymap_vals);
current_keymap = &current_keymap_vals;
}
void
@ -368,20 +525,26 @@ tty_poll() {
for (int keycode = 0; keycode < RETROK_LAST; keycode++) {
int newstate = input_state_cb(0, RETRO_DEVICE_KEYBOARD, 0, keycode);
if (curstate[keycode] != newstate) {
int curc;
int curc = 0;
curstate[keycode] = newstate;
if (shift && current_keymap->shifted[keycode]) {
curc = current_keymap->shifted[keycode];
} else if (current_keymap->normal[keycode]) {
curc = current_keymap->normal[keycode];
}
if (keycode == RETROK_F11)
if (curc && curc == 10002 && newstate) {
retro_reset(); return;
}
if (curc && curc == 10001 && newstate)
curc = TTY_RESET;
if (curc) {
change = 1;
if (newstate)
c = curc;
}
if (curc && curc == 10000 && newstate)
toggle_color_mode();
}
}