Initial support for Atari ST.
This commit is contained in:
2
Makefile
2
Makefile
@@ -35,7 +35,7 @@ CPP_SRC = $(wildcard *.cpp) \
|
||||
$(wildcard ./support/snes/*.cpp) \
|
||||
$(wildcard ./support/neogeo/*.cpp) \
|
||||
$(wildcard ./support/arcade/*.cpp) \
|
||||
$(wildcard ./support/megacd/*.cpp) \
|
||||
$(wildcard ./support/megacd/*.cpp) \
|
||||
$(wildcard ./support/c64/*.cpp) \
|
||||
lib/lodepng/lodepng.cpp
|
||||
|
||||
|
||||
@@ -88,7 +88,6 @@
|
||||
<ClCompile Include="support\neogeo\loader.cpp" />
|
||||
<ClCompile Include="support\sharpmz\sharpmz.cpp" />
|
||||
<ClCompile Include="support\snes\snes.cpp" />
|
||||
<ClCompile Include="support\st\st_ikbd.cpp" />
|
||||
<ClCompile Include="support\st\st_tos.cpp" />
|
||||
<ClCompile Include="support\x86\x86.cpp" />
|
||||
<ClCompile Include="sxmlc.c" />
|
||||
@@ -145,7 +144,6 @@
|
||||
<ClInclude Include="support\neogeo\loader.h" />
|
||||
<ClInclude Include="support\sharpmz\sharpmz.h" />
|
||||
<ClInclude Include="support\snes\snes.h" />
|
||||
<ClInclude Include="support\st\st_ikbd.h" />
|
||||
<ClInclude Include="support\st\st_tos.h" />
|
||||
<ClInclude Include="support\x86\x86.h" />
|
||||
<ClInclude Include="sxmlc.h" />
|
||||
|
||||
@@ -166,9 +166,6 @@
|
||||
<ClCompile Include="support\snes\snes.cpp">
|
||||
<Filter>Source Files\support</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="support\st\st_ikbd.cpp">
|
||||
<Filter>Source Files\support</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="support\st\st_tos.cpp">
|
||||
<Filter>Source Files\support</Filter>
|
||||
</ClCompile>
|
||||
@@ -303,9 +300,6 @@
|
||||
<ClInclude Include="support\neogeo\loader.h">
|
||||
<Filter>Header Files\support</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="support\st\st_ikbd.h">
|
||||
<Filter>Header Files\support</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="support\st\st_tos.h">
|
||||
<Filter>Header Files\support</Filter>
|
||||
</ClInclude>
|
||||
|
||||
@@ -235,6 +235,7 @@ void FileClose(fileTYPE *file)
|
||||
|
||||
file->zip = nullptr;
|
||||
file->filp = nullptr;
|
||||
file->size = 0;
|
||||
}
|
||||
|
||||
static int zip_search_by_crc(mz_zip_archive *zipArchive, uint32_t crc32)
|
||||
|
||||
143
input.cpp
143
input.cpp
@@ -816,143 +816,6 @@ static int ev2archie[] =
|
||||
NONE //255 ???
|
||||
};
|
||||
|
||||
/*
|
||||
|
||||
// unmapped atari keys:
|
||||
// 0x63 KP (
|
||||
// 0x64 KP )
|
||||
|
||||
// keycode translation table for atari
|
||||
const unsigned short usb2atari[] = {
|
||||
MISS, // 00: NoEvent
|
||||
MISS, // 01: Overrun Error
|
||||
MISS, // 02: POST fail
|
||||
MISS, // 03: ErrorUndefined
|
||||
0x1e, // 04: a
|
||||
0x30, // 05: b
|
||||
0x2e, // 06: c
|
||||
0x20, // 07: d
|
||||
0x12, // 08: e
|
||||
0x21, // 09: f
|
||||
0x22, // 0a: g
|
||||
0x23, // 0b: h
|
||||
0x17, // 0c: i
|
||||
0x24, // 0d: j
|
||||
0x25, // 0e: k
|
||||
0x26, // 0f: l
|
||||
0x32, // 10: m
|
||||
0x31, // 11: n
|
||||
0x18, // 12: o
|
||||
0x19, // 13: p
|
||||
0x10, // 14: q
|
||||
0x13, // 15: r
|
||||
0x1f, // 16: s
|
||||
0x14, // 17: t
|
||||
0x16, // 18: u
|
||||
0x2f, // 19: v
|
||||
0x11, // 1a: w
|
||||
0x2d, // 1b: x
|
||||
0x15, // 1c: y
|
||||
0x2c, // 1d: z
|
||||
0x02, // 1e: 1
|
||||
0x03, // 1f: 2
|
||||
0x04, // 20: 3
|
||||
0x05, // 21: 4
|
||||
0x06, // 22: 5
|
||||
0x07, // 23: 6
|
||||
0x08, // 24: 7
|
||||
0x09, // 25: 8
|
||||
0x0a, // 26: 9
|
||||
0x0b, // 27: 0
|
||||
0x1c, // 28: Return
|
||||
0x01, // 29: Escape
|
||||
0x0e, // 2a: Backspace
|
||||
0x0f, // 2b: Tab
|
||||
0x39, // 2c: Space
|
||||
0x0c, // 2d: -
|
||||
0x0d, // 2e: =
|
||||
0x1a, // 2f: [
|
||||
0x1b, // 30: ]
|
||||
0x29, // 31: backslash, only on us keyboard
|
||||
0x29, // 32: Europe 1, only on int. keyboard
|
||||
0x27, // 33: ;
|
||||
0x28, // 34: '
|
||||
0x2b, // 35: `
|
||||
0x33, // 36: ,
|
||||
0x34, // 37: .
|
||||
0x35, // 38: /
|
||||
0x3a | CAPS_LOCK_TOGGLE, // 39: Caps Lock
|
||||
0x3b, // 3a: F1
|
||||
0x3c, // 3b: F2
|
||||
0x3d, // 3c: F3
|
||||
0x3e, // 3d: F4
|
||||
0x3f, // 3e: F5
|
||||
0x40, // 3f: F6
|
||||
0x41, // 40: F7
|
||||
0x42, // 41: F8
|
||||
0x43, // 42: F9
|
||||
0x44, // 43: F10
|
||||
MISS, // 44: F11
|
||||
OSD_OPEN, // 45: F12
|
||||
MISS, // 46: Print Screen
|
||||
NUM_LOCK_TOGGLE, // 47: Scroll Lock
|
||||
MISS, // 48: Pause
|
||||
0x52, // 49: Insert
|
||||
0x47, // 4a: Home
|
||||
0x62, // 4b: Page Up
|
||||
0x53, // 4c: Delete
|
||||
MISS, // 4d: End
|
||||
0x61, // 4e: Page Down
|
||||
0x4d, // 4f: Right Arrow
|
||||
0x4b, // 50: Left Arrow
|
||||
0x50, // 51: Down Arrow
|
||||
0x48, // 52: Up Arrow
|
||||
NUM_LOCK_TOGGLE, // 53: Num Lock
|
||||
0x65, // 54: KP /
|
||||
0x66, // 55: KP *
|
||||
0x4a, // 56: KP -
|
||||
0x4e, // 57: KP +
|
||||
0x72, // 58: KP Enter
|
||||
0x6d, // 59: KP 1
|
||||
0x6e, // 5a: KP 2
|
||||
0x6f, // 5b: KP 3
|
||||
0x6a, // 5c: KP 4
|
||||
0x6b, // 5d: KP 5
|
||||
0x6c, // 5e: KP 6
|
||||
0x67, // 5f: KP 7
|
||||
0x68, // 60: KP 8
|
||||
0x69, // 61: KP 9
|
||||
0x70, // 62: KP 0
|
||||
0x71, // 63: KP .
|
||||
0x60, // 64: Europe 2
|
||||
OSD_OPEN, // 65: App
|
||||
MISS, // 66: Power
|
||||
MISS, // 67: KP =
|
||||
MISS, // 68: F13
|
||||
MISS, // 69: F14
|
||||
MISS, // 6a: F15
|
||||
0x52, // 6b: insert (for keyrah)
|
||||
NUM_LOCK_TOGGLE | 1, // 6c: F17
|
||||
NUM_LOCK_TOGGLE | 2, // 6d: F18
|
||||
NUM_LOCK_TOGGLE | 3, // 6e: F19
|
||||
NUM_LOCK_TOGGLE | 4 // 6f: F20
|
||||
};
|
||||
|
||||
unsigned short modifier_keycode(unsigned char index)
|
||||
{
|
||||
// usb modifer bits:
|
||||
//0 1 2 3 4 5 6 7
|
||||
//LCTRL LSHIFT LALT LGUI RCTRL RSHIFT RALT RGUI
|
||||
|
||||
if (core_type == CORE_TYPE_MIST)
|
||||
{
|
||||
static const unsigned short atari_modifier[] = { 0x1d, 0x2a, 0x38, MISS, 0x1d, 0x36, 0x38, MISS };
|
||||
return atari_modifier[index];
|
||||
}
|
||||
}
|
||||
*/
|
||||
|
||||
|
||||
uint32_t get_ps2_code(uint16_t key)
|
||||
{
|
||||
if (key > 255) return NONE;
|
||||
@@ -965,12 +828,6 @@ uint32_t get_amiga_code(uint16_t key)
|
||||
return ev2amiga[key];
|
||||
}
|
||||
|
||||
uint32_t get_atari_code(uint16_t key)
|
||||
{
|
||||
if (key > 255) return NONE;
|
||||
return 0; // ev2atari[key];
|
||||
}
|
||||
|
||||
uint32_t get_archie_code(uint16_t key)
|
||||
{
|
||||
if (key > 255) return NONE;
|
||||
|
||||
1
input.h
1
input.h
@@ -93,7 +93,6 @@ void send_map_cmd(int key);
|
||||
uint32_t get_key_mod();
|
||||
uint32_t get_ps2_code(uint16_t key);
|
||||
uint32_t get_amiga_code(uint16_t key);
|
||||
uint32_t get_atari_code(uint16_t key);
|
||||
uint32_t get_archie_code(uint16_t key);
|
||||
|
||||
int input_has_lightgun();
|
||||
|
||||
833
menu.cpp
833
menu.cpp
@@ -131,20 +131,18 @@ enum MENU
|
||||
MENU_RECENT1,
|
||||
MENU_RECENT2,
|
||||
|
||||
// Mist/atari specific pages
|
||||
MENU_MIST_MAIN1,
|
||||
MENU_MIST_MAIN2,
|
||||
MENU_MIST_MAIN_FILE_SELECTED,
|
||||
MENU_MIST_STORAGE1,
|
||||
MENU_MIST_STORAGE2,
|
||||
MENU_MIST_STORAGE_FILE_SELECTED,
|
||||
MENU_MIST_SYSTEM1,
|
||||
MENU_MIST_SYSTEM2,
|
||||
MENU_MIST_SYSTEM_FILE_SELECTED,
|
||||
MENU_MIST_VIDEO1,
|
||||
MENU_MIST_VIDEO2,
|
||||
MENU_MIST_VIDEO_ADJUST1,
|
||||
MENU_MIST_VIDEO_ADJUST2,
|
||||
// Atari ST specific pages
|
||||
MENU_ST_MAIN1,
|
||||
MENU_ST_MAIN2,
|
||||
MENU_ST_SYSTEM1,
|
||||
MENU_ST_SYSTEM2,
|
||||
MENU_ST_FDD_FILE_SELECTED,
|
||||
MENU_ST_HDD_FILE_SELECTED,
|
||||
MENU_ST_SYSTEM_FILE_SELECTED,
|
||||
MENU_ST_LOAD_CONFIG1,
|
||||
MENU_ST_LOAD_CONFIG2,
|
||||
MENU_ST_SAVE_CONFIG1,
|
||||
MENU_ST_SAVE_CONFIG2,
|
||||
|
||||
// archimedes menu entries
|
||||
MENU_ARCHIE_MAIN1,
|
||||
@@ -182,7 +180,7 @@ static uint32_t menu_timer = 0;
|
||||
extern const char *version;
|
||||
|
||||
const char *config_tos_mem[] = { "512 kB", "1 MB", "2 MB", "4 MB", "8 MB", "14 MB", "--", "--" };
|
||||
const char *config_tos_wrprot[] = { "none", "A:", "B:", "A: and B:" };
|
||||
const char *config_tos_wrprot[] = { "None", "A:", "B:", "A: and B:" };
|
||||
const char *config_tos_usb[] = { "none", "control", "debug", "serial", "parallel", "midi" };
|
||||
|
||||
const char *config_scanlines_msg[] = { "Off", "HQ2x", "CRT 25%" , "CRT 50%" , "CRT 75%" };
|
||||
@@ -841,7 +839,6 @@ void HandleUI(void)
|
||||
{
|
||||
switch (user_io_core_type())
|
||||
{
|
||||
case CORE_TYPE_MIST:
|
||||
case CORE_TYPE_8BIT:
|
||||
case CORE_TYPE_SHARPMZ:
|
||||
case CORE_TYPE_ARCHIE:
|
||||
@@ -874,6 +871,7 @@ void HandleUI(void)
|
||||
static unsigned long flash_timer = 0;
|
||||
static int flash_state = 0;
|
||||
static uint32_t dip_submenu;
|
||||
static int need_reset = 0;
|
||||
|
||||
static char cp_MenuCancel;
|
||||
|
||||
@@ -1143,7 +1141,7 @@ void HandleUI(void)
|
||||
{
|
||||
SelectFile(0, SCANO_CORES, MENU_CORE_FILE_SELECTED1, MENU_NONE1);
|
||||
}
|
||||
else if (user_io_core_type() == CORE_TYPE_MIST) menustate = MENU_MIST_MAIN1;
|
||||
else if (is_st()) menustate = MENU_ST_MAIN1;
|
||||
else if (is_archie()) menustate = MENU_ARCHIE_MAIN1;
|
||||
else {
|
||||
if (is_menu())
|
||||
@@ -1845,7 +1843,7 @@ void HandleUI(void)
|
||||
MenuWrite(n++, s, menusub == 8, !video_get_gamma_en() || !S_ISDIR(getFileType(GAMMA_DIR)));
|
||||
}
|
||||
|
||||
if (is_minimig())
|
||||
if (is_minimig() || is_st())
|
||||
{
|
||||
menumask &= ~0x600;
|
||||
}
|
||||
@@ -2033,15 +2031,13 @@ void HandleUI(void)
|
||||
else if (left)
|
||||
{
|
||||
// go back to core requesting this menu
|
||||
switch (user_io_core_type()) {
|
||||
case CORE_TYPE_MIST:
|
||||
menusub = 5;
|
||||
menustate = MENU_MIST_MAIN1;
|
||||
break;
|
||||
switch (user_io_core_type())
|
||||
{
|
||||
case CORE_TYPE_ARCHIE:
|
||||
menusub = 0;
|
||||
menustate = MENU_ARCHIE_MAIN1;
|
||||
break;
|
||||
|
||||
case CORE_TYPE_8BIT:
|
||||
if (is_minimig())
|
||||
{
|
||||
@@ -2053,6 +2049,11 @@ void HandleUI(void)
|
||||
menusub = 0;
|
||||
menustate = MENU_ARCHIE_MAIN1;
|
||||
}
|
||||
else if (is_st())
|
||||
{
|
||||
menusub = 0;
|
||||
menustate = MENU_ST_MAIN1;
|
||||
}
|
||||
else
|
||||
{
|
||||
menusub = 0;
|
||||
@@ -2348,10 +2349,6 @@ void HandleUI(void)
|
||||
// go back to core requesting this menu
|
||||
switch (user_io_core_type())
|
||||
{
|
||||
case CORE_TYPE_MIST:
|
||||
menusub = 5;
|
||||
menustate = MENU_MIST_MAIN1;
|
||||
break;
|
||||
case CORE_TYPE_ARCHIE:
|
||||
menusub = 0;
|
||||
menustate = MENU_ARCHIE_MAIN1;
|
||||
@@ -2367,6 +2364,11 @@ void HandleUI(void)
|
||||
menusub = 0;
|
||||
menustate = MENU_ARCHIE_MAIN1;
|
||||
}
|
||||
else if (is_st())
|
||||
{
|
||||
menusub = 0;
|
||||
menustate = MENU_ST_MAIN1;
|
||||
}
|
||||
else
|
||||
{
|
||||
menusub = 0;
|
||||
@@ -2748,456 +2750,433 @@ void HandleUI(void)
|
||||
|
||||
|
||||
/******************************************************************/
|
||||
/* mist main menu */
|
||||
/* st main menu */
|
||||
/******************************************************************/
|
||||
|
||||
case MENU_MIST_MAIN1:
|
||||
OsdSetSize(8);
|
||||
menumask = 0xff;
|
||||
OsdSetTitle("Mist", 0);
|
||||
case MENU_ST_MAIN1:
|
||||
OsdSetSize(16);
|
||||
menumask = 0x3ff;
|
||||
OsdSetTitle("AtariST", 0);
|
||||
m = 0;
|
||||
|
||||
// most important: main page has setup for floppy A: and screen
|
||||
strcpy(s, " A: ");
|
||||
strcat(s, tos_get_disk_name(0));
|
||||
if (tos_system_ctrl() & TOS_CONTROL_FDC_WR_PROT_A) strcat(s, " \x17");
|
||||
OsdWrite(0, s, menusub == 0, 0);
|
||||
OsdWrite(m++);
|
||||
for (uint32_t i = 0; i < 2; i++)
|
||||
{
|
||||
snprintf(s, 29, " %c: %s%s", 'A' + i, (tos_system_ctrl() & (TOS_CONTROL_FDC_WR_PROT_A << i)) ? "\x17" : "", tos_get_disk_name(i));
|
||||
OsdWrite(m++, s, menusub == i, 0);
|
||||
}
|
||||
strcpy(s, " Write protect: ");
|
||||
strcat(s, config_tos_wrprot[(tos_system_ctrl() >> 6) & 3]);
|
||||
OsdWrite(m++, s, menusub == 2, 0);
|
||||
OsdWrite(m++);
|
||||
|
||||
strcpy(s, " Screen: ");
|
||||
if (tos_system_ctrl() & TOS_CONTROL_VIDEO_COLOR) strcat(s, "Color");
|
||||
else strcat(s, "Mono");
|
||||
OsdWrite(1, s, menusub == 1, 0);
|
||||
snprintf(s, 29, " Joysticks swap: %s", user_io_get_joyswap() ? "Yes" : "No");
|
||||
OsdWrite(m++, s, menusub == 3);
|
||||
OsdWrite(m++);
|
||||
|
||||
/* everything else is in submenus */
|
||||
OsdWrite(2, " Storage \x16", menusub == 2, 0);
|
||||
OsdWrite(3, " System \x16", menusub == 3, 0);
|
||||
OsdWrite(4, " Audio / Video \x16", menusub == 4, 0);
|
||||
OsdWrite(5, " Firmware & Core \x16", menusub == 5, 0);
|
||||
OsdWrite(m++, " Modify config \x16", menusub == 4);
|
||||
OsdWrite(m++, " Load config \x16", menusub == 5);
|
||||
OsdWrite(m++, " Save config \x16", menusub == 6);
|
||||
OsdWrite(m++);
|
||||
|
||||
OsdWrite(6, " Save config ", menusub == 6, 0);
|
||||
OsdWrite(m++, " Reset", menusub == 7);
|
||||
OsdWrite(m++, " Cold Boot", menusub == 8);
|
||||
|
||||
OsdWrite(7, STD_EXIT, menusub == 7, 0);
|
||||
for (; m < OsdGetSize()-1; m++) OsdWrite(m);
|
||||
MenuWrite(15, STD_EXIT, menusub == 9, 0, OSD_ARROW_RIGHT | OSD_ARROW_LEFT);
|
||||
|
||||
menustate = MENU_MIST_MAIN2;
|
||||
parentstate = MENU_MIST_MAIN1;
|
||||
menustate = MENU_ST_MAIN2;
|
||||
parentstate = MENU_ST_MAIN1;
|
||||
break;
|
||||
|
||||
case MENU_MIST_MAIN2:
|
||||
case MENU_ST_MAIN2:
|
||||
// menu key closes menu
|
||||
if (menu)
|
||||
{
|
||||
menustate = MENU_NONE1;
|
||||
if (select) {
|
||||
switch (menusub) {
|
||||
}
|
||||
else if (right)
|
||||
{
|
||||
menustate = MENU_8BIT_SYSTEM1;
|
||||
menusub = 0;
|
||||
}
|
||||
else if (left)
|
||||
{
|
||||
menustate = MENU_8BIT_INFO;
|
||||
menusub = 1;
|
||||
}
|
||||
else if (select)
|
||||
{
|
||||
switch (menusub)
|
||||
{
|
||||
case 0:
|
||||
if (tos_disk_is_inserted(0)) {
|
||||
tos_insert_disk(0, NULL);
|
||||
menustate = MENU_MIST_MAIN1;
|
||||
case 1:
|
||||
if (tos_disk_is_inserted(menusub))
|
||||
{
|
||||
tos_insert_disk(menusub, "");
|
||||
menustate = MENU_ST_MAIN1;
|
||||
}
|
||||
else
|
||||
SelectFile("ST ", SCANO_DIR, MENU_MIST_MAIN_FILE_SELECTED, MENU_MIST_MAIN1);
|
||||
{
|
||||
SelectFile("ST ", SCANO_DIR, MENU_ST_FDD_FILE_SELECTED, MENU_ST_MAIN1);
|
||||
}
|
||||
break;
|
||||
|
||||
case 1:
|
||||
tos_update_sysctrl(tos_system_ctrl() ^ TOS_CONTROL_VIDEO_COLOR);
|
||||
menustate = MENU_MIST_MAIN1;
|
||||
case 2:
|
||||
// remove current write protect bits and increase by one
|
||||
tos_update_sysctrl((tos_system_ctrl() & ~(TOS_CONTROL_FDC_WR_PROT_A | TOS_CONTROL_FDC_WR_PROT_B))
|
||||
| (((((tos_system_ctrl() >> 6) & 3) + 1) & 3) << 6));
|
||||
menustate = MENU_ST_MAIN1;
|
||||
break;
|
||||
|
||||
case 2: // Storage submenu
|
||||
menustate = MENU_MIST_STORAGE1;
|
||||
case 3:
|
||||
user_io_set_joyswap(!user_io_get_joyswap());
|
||||
menustate = MENU_ST_MAIN1;
|
||||
break;
|
||||
|
||||
case 4: // System submenu
|
||||
menustate = MENU_ST_SYSTEM1;
|
||||
need_reset = 0;
|
||||
menusub = 0;
|
||||
break;
|
||||
|
||||
case 3: // System submenu
|
||||
menustate = MENU_MIST_SYSTEM1;
|
||||
menusub = 0;
|
||||
break;
|
||||
|
||||
case 4: // Video submenu
|
||||
menustate = MENU_MIST_VIDEO1;
|
||||
menusub = 0;
|
||||
break;
|
||||
|
||||
case 5: // Firmware submenu
|
||||
//menustate = MENU_FIRMWARE1;
|
||||
case 5: // Load config
|
||||
menustate = MENU_ST_LOAD_CONFIG1;
|
||||
menusub = 0;
|
||||
break;
|
||||
|
||||
case 6: // Save config
|
||||
menustate = MENU_NONE1;
|
||||
tos_config_save();
|
||||
break;
|
||||
|
||||
case 7: // Exit
|
||||
menustate = MENU_NONE1;
|
||||
break;
|
||||
}
|
||||
}
|
||||
break;
|
||||
|
||||
case MENU_MIST_MAIN_FILE_SELECTED: // file successfully selected
|
||||
tos_insert_disk(0, SelectedPath);
|
||||
menustate = MENU_MIST_MAIN1;
|
||||
break;
|
||||
|
||||
case MENU_MIST_STORAGE1:
|
||||
menumask = tos_get_direct_hdd() ? 0x3f : 0x7f;
|
||||
OsdSetTitle("Storage", 0);
|
||||
// entries for both floppies
|
||||
for (uint32_t i = 0; i<2; i++) {
|
||||
strcpy(s, " A: ");
|
||||
strcat(s, tos_get_disk_name(i));
|
||||
s[1] = 'A' + i;
|
||||
if (tos_system_ctrl() & (TOS_CONTROL_FDC_WR_PROT_A << i))
|
||||
strcat(s, " \x17");
|
||||
OsdWrite(i, s, menusub == i, 0);
|
||||
}
|
||||
strcpy(s, " Write protect: ");
|
||||
strcat(s, config_tos_wrprot[(tos_system_ctrl() >> 6) & 3]);
|
||||
OsdWrite(2, s, menusub == 2, 0);
|
||||
OsdWrite(3, "", 0, 0);
|
||||
strcpy(s, " ACSI0 direct SD: ");
|
||||
strcat(s, tos_get_direct_hdd() ? "on" : "off");
|
||||
OsdWrite(4, s, menusub == 3, 0);
|
||||
for (uint32_t i = 0; i<2; i++) {
|
||||
strcpy(s, " ACSI0: ");
|
||||
s[5] = '0' + i;
|
||||
|
||||
strcat(s, tos_get_disk_name(2 + i));
|
||||
OsdWrite(5 + i, s, ((i == 1) || !tos_get_direct_hdd()) ? (menusub == (!tos_get_direct_hdd() ? 4 : 3) + i) : 0,
|
||||
(i == 0) && tos_get_direct_hdd());
|
||||
}
|
||||
OsdWrite(7, STD_EXIT, !tos_get_direct_hdd() ? (menusub == 6) : (menusub == 5), 0);
|
||||
parentstate = menustate;
|
||||
menustate = MENU_MIST_STORAGE2;
|
||||
break;
|
||||
|
||||
|
||||
case MENU_MIST_STORAGE2:
|
||||
if (menu) {
|
||||
menustate = MENU_MIST_MAIN1;
|
||||
menusub = 2;
|
||||
}
|
||||
if (select) {
|
||||
if (menusub <= 1) {
|
||||
if (tos_disk_is_inserted(menusub)) {
|
||||
tos_insert_disk(menusub, NULL);
|
||||
menustate = MENU_MIST_STORAGE1;
|
||||
}
|
||||
else
|
||||
SelectFile("ST ", SCANO_DIR, MENU_MIST_STORAGE_FILE_SELECTED, MENU_MIST_STORAGE1);
|
||||
}
|
||||
else if (menusub == 2) {
|
||||
// remove current write protect bits and increase by one
|
||||
tos_update_sysctrl((tos_system_ctrl() & ~(TOS_CONTROL_FDC_WR_PROT_A | TOS_CONTROL_FDC_WR_PROT_B))
|
||||
| (((((tos_system_ctrl() >> 6) & 3) + 1) & 3) << 6));
|
||||
menustate = MENU_MIST_STORAGE1;
|
||||
|
||||
}
|
||||
else if (menusub == 3) {
|
||||
tos_set_direct_hdd(!tos_get_direct_hdd());
|
||||
menustate = MENU_MIST_STORAGE1;
|
||||
|
||||
// no direct hhd emulation: Both ACSI entries are enabled
|
||||
// or direct hhd emulation for ACSI0: Only second ACSI entry is enabled
|
||||
}
|
||||
else if ((menusub == 4) || (!tos_get_direct_hdd() && (menusub == 5))) {
|
||||
char disk_idx = menusub - (tos_get_direct_hdd() ? 1 : 2);
|
||||
printf("Select image for disk %d\n", disk_idx);
|
||||
|
||||
if (tos_disk_is_inserted(disk_idx)) {
|
||||
tos_insert_disk(disk_idx, NULL);
|
||||
menustate = MENU_MIST_STORAGE1;
|
||||
}
|
||||
else
|
||||
SelectFile("HD ", 0, MENU_MIST_STORAGE_FILE_SELECTED, MENU_MIST_STORAGE1);
|
||||
|
||||
}
|
||||
else if (tos_get_direct_hdd() ? (menusub == 5) : (menusub == 6)) {
|
||||
menustate = MENU_MIST_MAIN1;
|
||||
menusub = 2;
|
||||
}
|
||||
}
|
||||
break;
|
||||
|
||||
case MENU_MIST_STORAGE_FILE_SELECTED: // file successfully selected
|
||||
// floppy/hdd
|
||||
if (menusub < 2)
|
||||
tos_insert_disk(menusub, SelectedPath);
|
||||
else {
|
||||
char disk_idx = menusub - (tos_get_direct_hdd() ? 1 : 2);
|
||||
printf("Insert image for disk %d\n", disk_idx);
|
||||
tos_insert_disk(disk_idx, SelectedPath);
|
||||
}
|
||||
menustate = MENU_MIST_STORAGE1;
|
||||
break;
|
||||
|
||||
case MENU_MIST_SYSTEM1:
|
||||
menumask = 0xff;
|
||||
OsdSetTitle("System", 0);
|
||||
|
||||
strcpy(s, " Memory: ");
|
||||
strcat(s, config_tos_mem[(tos_system_ctrl() >> 1) & 7]);
|
||||
OsdWrite(0, s, menusub == 0, 0);
|
||||
|
||||
strcpy(s, " CPU: ");
|
||||
strcat(s, config_cpu_msg[(tos_system_ctrl() >> 4) & 3]);
|
||||
OsdWrite(1, s, menusub == 1, 0);
|
||||
|
||||
strcpy(s, " TOS: ");
|
||||
strcat(s, tos_get_image_name());
|
||||
OsdWrite(2, s, menusub == 2, 0);
|
||||
|
||||
strcpy(s, " Cartridge: ");
|
||||
strcat(s, tos_get_cartridge_name());
|
||||
OsdWrite(3, s, menusub == 3, 0);
|
||||
|
||||
strcpy(s, " USB I/O: ");
|
||||
strcat(s, "NONE"); //config_tos_usb[tos_get_cdc_control_redirect()]);
|
||||
OsdWrite(4, s, menusub == 4, 0);
|
||||
|
||||
OsdWrite(5, " Reset", menusub == 5, 0);
|
||||
OsdWrite(6, " Cold boot", menusub == 6, 0);
|
||||
|
||||
OsdWrite(7, STD_EXIT, menusub == 7, 0);
|
||||
|
||||
parentstate = menustate;
|
||||
menustate = MENU_MIST_SYSTEM2;
|
||||
break;
|
||||
|
||||
case MENU_MIST_SYSTEM2:
|
||||
if (menu) {
|
||||
menustate = MENU_MIST_MAIN1;
|
||||
menusub = 3;
|
||||
}
|
||||
if (select) {
|
||||
switch (menusub) {
|
||||
case 0: { // RAM
|
||||
int mem = (tos_system_ctrl() >> 1) & 7; // current memory config
|
||||
mem++;
|
||||
if (mem > 5) mem = 3; // cycle 4MB/8MB/14MB
|
||||
tos_update_sysctrl((tos_system_ctrl() & ~0x0e) | (mem << 1));
|
||||
tos_reset(1);
|
||||
menustate = MENU_MIST_SYSTEM1;
|
||||
} break;
|
||||
|
||||
case 1: { // CPU
|
||||
int cpu = (tos_system_ctrl() >> 4) & 3; // current cpu config
|
||||
cpu = (cpu + 1) & 3;
|
||||
if (cpu == 2) cpu = 3; // skip unused config
|
||||
tos_update_sysctrl((tos_system_ctrl() & ~0x30) | (cpu << 4));
|
||||
tos_reset(0);
|
||||
menustate = MENU_MIST_SYSTEM1;
|
||||
} break;
|
||||
|
||||
case 2: // TOS
|
||||
SelectFile("IMG", 0, MENU_MIST_SYSTEM_FILE_SELECTED, MENU_MIST_SYSTEM1);
|
||||
break;
|
||||
|
||||
case 3: // Cart
|
||||
// if a cart name is set, then remove it
|
||||
if (tos_cartridge_is_inserted()) {
|
||||
tos_load_cartridge("");
|
||||
menustate = MENU_MIST_SYSTEM1;
|
||||
}
|
||||
else
|
||||
{
|
||||
SelectFile("IMG", 0, MENU_MIST_SYSTEM_FILE_SELECTED, MENU_MIST_SYSTEM1);
|
||||
}
|
||||
break;
|
||||
|
||||
case 4:
|
||||
menustate = MENU_MIST_SYSTEM1;
|
||||
break;
|
||||
|
||||
case 5: // Reset
|
||||
tos_reset(0);
|
||||
menustate = MENU_NONE1;
|
||||
break;
|
||||
|
||||
case 6: // Cold Boot
|
||||
tos_reset(1);
|
||||
menustate = MENU_NONE1;
|
||||
break;
|
||||
|
||||
case 7:
|
||||
menustate = MENU_MIST_MAIN1;
|
||||
menusub = 3;
|
||||
break;
|
||||
}
|
||||
}
|
||||
break;
|
||||
|
||||
case MENU_MIST_SYSTEM_FILE_SELECTED: // file successfully selected
|
||||
if (menusub == 2) {
|
||||
tos_upload(SelectedPath);
|
||||
menustate = MENU_MIST_SYSTEM1;
|
||||
}
|
||||
if (menusub == 3) {
|
||||
tos_load_cartridge(SelectedPath);
|
||||
menustate = MENU_MIST_SYSTEM1;
|
||||
}
|
||||
break;
|
||||
|
||||
|
||||
case MENU_MIST_VIDEO1:
|
||||
menumask = 0x7f;
|
||||
OsdSetTitle("A/V", 0);
|
||||
|
||||
strcpy(s, " Screen: ");
|
||||
if (tos_system_ctrl() & TOS_CONTROL_VIDEO_COLOR) strcat(s, "Color");
|
||||
else strcat(s, "Mono");
|
||||
OsdWrite(0, s, menusub == 0, 0);
|
||||
|
||||
// Viking card can only be enabled with max 8MB RAM
|
||||
enable = (tos_system_ctrl() & 0xe) <= TOS_MEMCONFIG_8M;
|
||||
strcpy(s, " Viking/SM194: ");
|
||||
strcat(s, ((tos_system_ctrl() & TOS_CONTROL_VIKING) && enable) ? "on" : "off");
|
||||
OsdWrite(1, s, menusub == 1, enable ? 0 : 1);
|
||||
|
||||
// Blitter is always present in >= STE
|
||||
enable = (tos_system_ctrl() & (TOS_CONTROL_STE | TOS_CONTROL_MSTE)) ? 1 : 0;
|
||||
strcpy(s, " Blitter: ");
|
||||
strcat(s, ((tos_system_ctrl() & TOS_CONTROL_BLITTER) || enable) ? "on" : "off");
|
||||
OsdWrite(2, s, menusub == 2, enable);
|
||||
|
||||
strcpy(s, " Chipset: ");
|
||||
// extract TOS_CONTROL_STE and TOS_CONTROL_MSTE bits
|
||||
strcat(s, atari_chipset[(tos_system_ctrl() >> 23) & 3]);
|
||||
OsdWrite(3, s, menusub == 3, 0);
|
||||
|
||||
OsdWrite(4, " Video adjust \x16", menusub == 4, 0);
|
||||
|
||||
strcpy(s, " YM-Audio: ");
|
||||
strcat(s, stereo[(tos_system_ctrl() & TOS_CONTROL_STEREO) ? 1 : 0]);
|
||||
OsdWrite(5, s, menusub == 5, 0);
|
||||
OsdWrite(6, "", 0, 0);
|
||||
|
||||
OsdWrite(7, STD_EXIT, menusub == 6, 0);
|
||||
|
||||
parentstate = menustate;
|
||||
menustate = MENU_MIST_VIDEO2;
|
||||
break;
|
||||
|
||||
case MENU_MIST_VIDEO2:
|
||||
if (menu) {
|
||||
menustate = MENU_MIST_MAIN1;
|
||||
menusub = 4;
|
||||
}
|
||||
|
||||
if (select) {
|
||||
switch (menusub) {
|
||||
case 0:
|
||||
tos_update_sysctrl(tos_system_ctrl() ^ TOS_CONTROL_VIDEO_COLOR);
|
||||
menustate = MENU_MIST_VIDEO1;
|
||||
break;
|
||||
|
||||
case 1:
|
||||
// viking/sm194
|
||||
tos_update_sysctrl(tos_system_ctrl() ^ TOS_CONTROL_VIKING);
|
||||
menustate = MENU_MIST_VIDEO1;
|
||||
break;
|
||||
|
||||
case 2:
|
||||
if (!(tos_system_ctrl() & TOS_CONTROL_STE)) {
|
||||
tos_update_sysctrl(tos_system_ctrl() ^ TOS_CONTROL_BLITTER);
|
||||
menustate = MENU_MIST_VIDEO1;
|
||||
}
|
||||
break;
|
||||
|
||||
case 3: {
|
||||
unsigned long chipset = (tos_system_ctrl() >> 23) + 1;
|
||||
if (chipset == 4) chipset = 0;
|
||||
tos_update_sysctrl((tos_system_ctrl() & ~(TOS_CONTROL_STE | TOS_CONTROL_MSTE)) | (chipset << 23));
|
||||
menustate = MENU_MIST_VIDEO1;
|
||||
} break;
|
||||
|
||||
case 4:
|
||||
menustate = MENU_MIST_VIDEO_ADJUST1;
|
||||
menustate = MENU_ST_SAVE_CONFIG1;
|
||||
menusub = 0;
|
||||
break;
|
||||
|
||||
case 7: // Reset
|
||||
tos_reset(0);
|
||||
menustate = MENU_NONE1;
|
||||
break;
|
||||
|
||||
case 8: // Cold Boot
|
||||
tos_reset(1);
|
||||
menustate = MENU_NONE1;
|
||||
break;
|
||||
|
||||
case 9: // Exit
|
||||
menustate = MENU_NONE1;
|
||||
break;
|
||||
}
|
||||
}
|
||||
break;
|
||||
|
||||
case MENU_ST_FDD_FILE_SELECTED:
|
||||
tos_insert_disk(menusub, SelectedPath);
|
||||
menustate = MENU_ST_MAIN1;
|
||||
break;
|
||||
|
||||
case MENU_ST_SYSTEM1:
|
||||
menumask = 0x1fff;
|
||||
OsdSetTitle("Config", 0);
|
||||
m = 0;
|
||||
|
||||
for (uint32_t i = 0; i < 2; i++)
|
||||
{
|
||||
snprintf(s, 29, " HDD%d: %s", i, tos_get_disk_name(2 + i));
|
||||
OsdWrite(m++, s, menusub == i);
|
||||
}
|
||||
|
||||
snprintf(s, 29, " Cart: %s", tos_get_cartridge_name());
|
||||
OsdWrite(m++, s, menusub == 2);
|
||||
|
||||
OsdWrite(m++);
|
||||
strcpy(s, " Memory: ");
|
||||
strcat(s, config_tos_mem[(tos_system_ctrl() >> 1) & 7]);
|
||||
OsdWrite(m++, s, menusub == 3);
|
||||
|
||||
snprintf(s, 29, " TOS: %s", tos_get_image_name());
|
||||
OsdWrite(m++, s, menusub == 4);
|
||||
|
||||
// Blitter is always present in >= STE
|
||||
enable = (tos_system_ctrl() & (TOS_CONTROL_STE | TOS_CONTROL_MSTE)) ? 1 : 0;
|
||||
strcpy(s, " Blitter: ");
|
||||
strcat(s, ((tos_system_ctrl() & TOS_CONTROL_BLITTER) || enable) ? "On" : "Off");
|
||||
OsdWrite(m++, s, menusub == 5, enable);
|
||||
|
||||
strcpy(s, " Chipset: ");
|
||||
// extract TOS_CONTROL_STE and TOS_CONTROL_MSTE bits
|
||||
strcat(s, atari_chipset[(tos_system_ctrl() >> 23) & 3]);
|
||||
OsdWrite(m++, s, menusub == 6, 0);
|
||||
|
||||
// Viking card can only be enabled with max 8MB RAM
|
||||
enable = (tos_system_ctrl() & 0xe) <= TOS_MEMCONFIG_8M;
|
||||
strcpy(s, " Viking: ");
|
||||
strcat(s, ((tos_system_ctrl() & TOS_CONTROL_VIKING) && enable) ? "On" : "Off");
|
||||
OsdWrite(m++, s, menusub == 7, enable ? 0 : 1);
|
||||
|
||||
/*
|
||||
strcpy(s, " CDC I/O: ");
|
||||
strcat(s, config_tos_usb[tos_get_cdc_control_redirect()]);
|
||||
OsdWrite(m++, s, menusub == 3, 0);
|
||||
*/
|
||||
|
||||
OsdWrite(m++);
|
||||
strcpy(s, " Screen: ");
|
||||
if (tos_system_ctrl() & TOS_CONTROL_VIDEO_COLOR) strcat(s, "Color");
|
||||
else strcat(s, "Mono");
|
||||
OsdWrite(m++, s, menusub == 8, 0);
|
||||
|
||||
strcpy(s, " Border: ");
|
||||
if (tos_system_ctrl() & TOS_CONTROL_BORDER) strcat(s, "Visible");
|
||||
else strcat(s, "Full");
|
||||
OsdWrite(m++, s, menusub == 9, 0);
|
||||
|
||||
strcpy(s, " Scanlines: ");
|
||||
strcat(s, scanlines[(tos_system_ctrl() >> 20) & 3]);
|
||||
OsdWrite(m++, s, menusub == 10, 0);
|
||||
|
||||
strcpy(s, " YM-Audio: ");
|
||||
strcat(s, stereo[(tos_system_ctrl() & TOS_CONTROL_STEREO) ? 1 : 0]);
|
||||
OsdWrite(m++, s, menusub == 11, 0);
|
||||
|
||||
for (; m < OsdGetSize() - 1; m++) OsdWrite(m);
|
||||
OsdWrite(15, STD_EXIT, menusub == 12, 0);
|
||||
|
||||
parentstate = menustate;
|
||||
menustate = MENU_ST_SYSTEM2;
|
||||
break;
|
||||
|
||||
case MENU_ST_SYSTEM2:
|
||||
if (menu)
|
||||
{
|
||||
menustate = MENU_ST_MAIN1;
|
||||
menusub = 3;
|
||||
if(need_reset) tos_reset(1);
|
||||
}
|
||||
|
||||
if (select)
|
||||
{
|
||||
switch (menusub)
|
||||
{
|
||||
case 0:
|
||||
case 1:
|
||||
SelectFile("VHD", SCANO_DIR | SCANO_UMOUNT, MENU_ST_HDD_FILE_SELECTED, MENU_ST_SYSTEM1);
|
||||
break;
|
||||
|
||||
case 2:
|
||||
// Cart
|
||||
if (tos_cartridge_is_inserted())
|
||||
{
|
||||
tos_load_cartridge("");
|
||||
menustate = MENU_ST_SYSTEM1;
|
||||
}
|
||||
else
|
||||
{
|
||||
SelectFile("IMG", SCANO_DIR, MENU_ST_SYSTEM_FILE_SELECTED, MENU_ST_SYSTEM1);
|
||||
}
|
||||
break;
|
||||
|
||||
case 3:
|
||||
{
|
||||
// RAM
|
||||
int mem = (tos_system_ctrl() >> 1) & 7; // current memory config
|
||||
mem++;
|
||||
if (mem > 5) mem = 0; // cycle 4MB/8MB/14MB
|
||||
tos_update_sysctrl((tos_system_ctrl() & ~0x0e) | (mem << 1));
|
||||
need_reset = 1;
|
||||
menustate = MENU_ST_SYSTEM1;
|
||||
}
|
||||
break;
|
||||
|
||||
case 4: // TOS
|
||||
SelectFile("IMG", SCANO_DIR, MENU_ST_SYSTEM_FILE_SELECTED, MENU_ST_SYSTEM1);
|
||||
break;
|
||||
|
||||
/*
|
||||
case 3:
|
||||
if (tos_get_cdc_control_redirect() == CDC_REDIRECT_MIDI)
|
||||
{
|
||||
tos_set_cdc_control_redirect(CDC_REDIRECT_NONE);
|
||||
}
|
||||
else
|
||||
{
|
||||
tos_set_cdc_control_redirect(tos_get_cdc_control_redirect() + 1);
|
||||
}
|
||||
menustate = MENU_ST_SYSTEM1;
|
||||
break;
|
||||
*/
|
||||
|
||||
case 5:
|
||||
tos_update_sysctrl(tos_system_ctrl() ^ TOS_CONTROL_STEREO);
|
||||
menustate = MENU_MIST_VIDEO1;
|
||||
if (!(tos_system_ctrl() & TOS_CONTROL_STE))
|
||||
{
|
||||
tos_update_sysctrl(tos_system_ctrl() ^ TOS_CONTROL_BLITTER);
|
||||
menustate = MENU_ST_SYSTEM1;
|
||||
}
|
||||
break;
|
||||
|
||||
case 6:
|
||||
menustate = MENU_MIST_MAIN1;
|
||||
menusub = 4;
|
||||
{
|
||||
unsigned long chipset = (tos_system_ctrl() >> 23) + 1;
|
||||
if (chipset == 4) chipset = 0;
|
||||
tos_update_sysctrl((tos_system_ctrl() & ~(TOS_CONTROL_STE | TOS_CONTROL_MSTE)) | (chipset << 23));
|
||||
menustate = MENU_ST_SYSTEM1;
|
||||
}
|
||||
break;
|
||||
|
||||
case 7:
|
||||
// viking/sm194
|
||||
tos_update_sysctrl(tos_system_ctrl() ^ TOS_CONTROL_VIKING);
|
||||
menustate = MENU_ST_SYSTEM1;
|
||||
break;
|
||||
|
||||
case 8:
|
||||
tos_update_sysctrl(tos_system_ctrl() ^ TOS_CONTROL_VIDEO_COLOR);
|
||||
menustate = MENU_ST_SYSTEM1;
|
||||
break;
|
||||
|
||||
case 9:
|
||||
tos_update_sysctrl(tos_system_ctrl() ^ TOS_CONTROL_BORDER);
|
||||
menustate = MENU_ST_SYSTEM1;
|
||||
break;
|
||||
|
||||
case 10:
|
||||
{
|
||||
// next scanline state
|
||||
int scan = ((tos_system_ctrl() >> 20) + 1) & 3;
|
||||
tos_update_sysctrl((tos_system_ctrl() & ~TOS_CONTROL_SCANLINES) | (scan << 20));
|
||||
menustate = MENU_ST_SYSTEM1;
|
||||
}
|
||||
break;
|
||||
|
||||
case 11:
|
||||
tos_update_sysctrl(tos_system_ctrl() ^ TOS_CONTROL_STEREO);
|
||||
menustate = MENU_ST_SYSTEM1;
|
||||
break;
|
||||
|
||||
|
||||
case 12:
|
||||
menustate = MENU_ST_MAIN1;
|
||||
menusub = 3;
|
||||
if (need_reset) tos_reset(1);
|
||||
break;
|
||||
}
|
||||
}
|
||||
break;
|
||||
|
||||
case MENU_MIST_VIDEO_ADJUST1:
|
||||
menumask = 0x1f;
|
||||
OsdSetTitle("V-adjust", 0);
|
||||
|
||||
OsdWrite(0, "", 0, 0);
|
||||
|
||||
strcpy(s, " PAL mode: ");
|
||||
if (tos_system_ctrl() & TOS_CONTROL_PAL50HZ) strcat(s, "50Hz");
|
||||
else strcat(s, "56Hz");
|
||||
OsdWrite(1, s, menusub == 0, 0);
|
||||
|
||||
strcpy(s, " Scanlines: ");
|
||||
strcat(s, scanlines[(tos_system_ctrl() >> 20) & 3]);
|
||||
OsdWrite(2, s, menusub == 1, 0);
|
||||
|
||||
OsdWrite(3, "", 0, 0);
|
||||
|
||||
sprintf(s, " Horizontal: %d", tos_get_video_adjust(0));
|
||||
OsdWrite(4, s, menusub == 2, 0);
|
||||
|
||||
sprintf(s, " Vertical: %d", tos_get_video_adjust(1));
|
||||
OsdWrite(5, s, menusub == 3, 0);
|
||||
|
||||
OsdWrite(6, "", 0, 0);
|
||||
|
||||
OsdWrite(7, STD_EXIT, menusub == 4, 0);
|
||||
|
||||
parentstate = menustate;
|
||||
menustate = MENU_MIST_VIDEO_ADJUST2;
|
||||
case MENU_ST_HDD_FILE_SELECTED:
|
||||
printf("Insert image for disk %d\n", menusub);
|
||||
tos_insert_disk(menusub+2, SelectedPath);
|
||||
menustate = MENU_ST_SYSTEM1;
|
||||
break;
|
||||
|
||||
case MENU_MIST_VIDEO_ADJUST2:
|
||||
if (menu) {
|
||||
menustate = MENU_MIST_VIDEO1;
|
||||
case MENU_ST_SYSTEM_FILE_SELECTED: // file successfully selected
|
||||
if (menusub == 4)
|
||||
{
|
||||
tos_upload(SelectedPath);
|
||||
menustate = MENU_ST_SYSTEM1;
|
||||
}
|
||||
|
||||
if (menusub == 2)
|
||||
{
|
||||
tos_load_cartridge(SelectedPath);
|
||||
menustate = MENU_ST_SYSTEM1;
|
||||
}
|
||||
break;
|
||||
|
||||
case MENU_ST_LOAD_CONFIG1:
|
||||
helptext = helptexts[HELPTEXT_NONE];
|
||||
m = 0;
|
||||
if (parentstate != menustate) // First run?
|
||||
{
|
||||
menumask = 0x21;
|
||||
if (tos_config_exists(1)) menumask |= 0x02;
|
||||
if (tos_config_exists(2)) menumask |= 0x04;
|
||||
if (tos_config_exists(3)) menumask |= 0x08;
|
||||
if (tos_config_exists(4)) menumask |= 0x10;
|
||||
}
|
||||
parentstate = menustate;
|
||||
parentstate = menustate;
|
||||
OsdSetTitle("Load Config", 0);
|
||||
|
||||
OsdWrite(m++);
|
||||
OsdWrite(m++);
|
||||
OsdWrite(m++);
|
||||
OsdWrite(m++);
|
||||
OsdWrite(m++, " Default", menusub == 0);
|
||||
OsdWrite(m++);
|
||||
OsdWrite(m++, " 1", menusub == 1, !(menumask & 0x02));
|
||||
OsdWrite(m++, " 2", menusub == 2, !(menumask & 0x04));
|
||||
OsdWrite(m++, " 3", menusub == 3, !(menumask & 0x08));
|
||||
OsdWrite(m++, " 4", menusub == 4, !(menumask & 0x10));
|
||||
|
||||
for (; m < OsdGetSize() - 1; m++) OsdWrite(m);
|
||||
OsdWrite(15, STD_EXIT, menusub == 5, 0);
|
||||
|
||||
menustate = MENU_ST_LOAD_CONFIG2;
|
||||
break;
|
||||
|
||||
case MENU_ST_LOAD_CONFIG2:
|
||||
if (menu)
|
||||
{
|
||||
menustate = MENU_ST_MAIN1;
|
||||
menusub = 4;
|
||||
}
|
||||
|
||||
// use left/right to adjust video position
|
||||
if (left || right) {
|
||||
if ((menusub == 2) || (menusub == 3)) {
|
||||
if (left && ((signed char)(tos_get_video_adjust(menusub - 2)) > -100))
|
||||
tos_set_video_adjust(menusub - 2, -1);
|
||||
|
||||
if (right && ((signed char)(tos_get_video_adjust(menusub - 2)) < 100))
|
||||
tos_set_video_adjust(menusub - 2, +1);
|
||||
|
||||
menustate = MENU_MIST_VIDEO_ADJUST1;
|
||||
if (select)
|
||||
{
|
||||
if (menusub < 5)
|
||||
{
|
||||
tos_config_load(menusub);
|
||||
tos_upload(NULL);
|
||||
menustate = MENU_NONE1;
|
||||
}
|
||||
else
|
||||
{
|
||||
menustate = MENU_ST_MAIN1;
|
||||
menusub = 4;
|
||||
}
|
||||
}
|
||||
break;
|
||||
|
||||
if (select) {
|
||||
switch (menusub) {
|
||||
case 0:
|
||||
tos_update_sysctrl(tos_system_ctrl() ^ TOS_CONTROL_PAL50HZ);
|
||||
menustate = MENU_MIST_VIDEO_ADJUST1;
|
||||
break;
|
||||
case MENU_ST_SAVE_CONFIG1:
|
||||
helptext = helptexts[HELPTEXT_NONE];
|
||||
menumask = 0x3f;
|
||||
m = 0;
|
||||
parentstate = menustate;
|
||||
OsdSetTitle("Save Config", 0);
|
||||
|
||||
case 1: {
|
||||
// next scanline state
|
||||
int scan = ((tos_system_ctrl() >> 20) + 1) & 3;
|
||||
tos_update_sysctrl((tos_system_ctrl() & ~TOS_CONTROL_SCANLINES) | (scan << 20));
|
||||
menustate = MENU_MIST_VIDEO_ADJUST1;
|
||||
} break;
|
||||
OsdWrite(m++);
|
||||
OsdWrite(m++);
|
||||
OsdWrite(m++);
|
||||
OsdWrite(m++);
|
||||
OsdWrite(m++, " Default", menusub == 0, 0);
|
||||
OsdWrite(m++);
|
||||
OsdWrite(m++, " 1", menusub == 1, 0);
|
||||
OsdWrite(m++, " 2", menusub == 2, 0);
|
||||
OsdWrite(m++, " 3", menusub == 3, 0);
|
||||
OsdWrite(m++, " 4", menusub == 4, 0);
|
||||
|
||||
// entries 2 and 3 use left/right
|
||||
for (; m < OsdGetSize() - 1; m++) OsdWrite(m);
|
||||
OsdWrite(15, STD_EXIT, menusub == 5, 0);
|
||||
|
||||
case 4:
|
||||
menustate = MENU_MIST_VIDEO1;
|
||||
menusub = 4;
|
||||
break;
|
||||
menustate = MENU_ST_SAVE_CONFIG2;
|
||||
break;
|
||||
|
||||
case MENU_ST_SAVE_CONFIG2:
|
||||
if (menu)
|
||||
{
|
||||
menustate = MENU_ST_MAIN1;
|
||||
menusub = 5;
|
||||
}
|
||||
|
||||
if (select)
|
||||
{
|
||||
if (menusub < 5)
|
||||
{
|
||||
tos_config_save(menusub);
|
||||
menustate = MENU_NONE1;
|
||||
}
|
||||
else
|
||||
{
|
||||
menustate = MENU_ST_MAIN1;
|
||||
menusub = 5;
|
||||
}
|
||||
}
|
||||
break;
|
||||
|
||||
@@ -11,7 +11,6 @@
|
||||
#include "support/archie/archie.h"
|
||||
|
||||
// ST (Atari) support
|
||||
#include "support/st/st_ikbd.h"
|
||||
#include "support/st/st_tos.h"
|
||||
|
||||
// X86 support
|
||||
|
||||
@@ -1,656 +0,0 @@
|
||||
/*
|
||||
|
||||
http://removers.free.fr/wikipendium/wakka.php?wiki=IntelligentKeyboardBible
|
||||
https://www.kernel.org/doc/Documentation/input/atarikbd.txt
|
||||
|
||||
ikbd ToDo:
|
||||
|
||||
Feature Example using/needing it impl. tested
|
||||
---------------------------------------------------------------------
|
||||
mouse y at bottom Bolo X X
|
||||
mouse button key events Goldrunner/A_008 X X
|
||||
joystick interrogation mode Xevious/A_004 X X
|
||||
Absolute mouse mode Addicataball/A_050 X X
|
||||
disable mouse ? X
|
||||
disable joystick ? X
|
||||
Joysticks also generate Goldrunner X -X
|
||||
mouse button events!
|
||||
Pause/Resume PACMANIA_STE/Gembench X
|
||||
mouse keycode mode Goldrunner X X
|
||||
|
||||
Games that have ikbd problems:
|
||||
PowerMonger/PP_106 fixed
|
||||
Stardust fixed
|
||||
M1 tank platoon/A_385 fixed
|
||||
*/
|
||||
|
||||
#include <stdio.h>
|
||||
#include <string.h>
|
||||
|
||||
#include "../../user_io.h"
|
||||
#include "../../spi.h"
|
||||
#include "st_ikbd.h"
|
||||
#include "../../debug.h"
|
||||
|
||||
#define IKBD_AUTO_MS 20
|
||||
|
||||
// atari ikbd stuff
|
||||
#define IKBD_STATE_JOYSTICK_EVENT_REPORTING 0x01
|
||||
#define IKBD_STATE_MOUSE_Y_BOTTOM 0x02
|
||||
#define IKBD_STATE_MOUSE_BUTTON_AS_KEY 0x04 // mouse buttons act like keys
|
||||
#define IKBD_STATE_MOUSE_DISABLED 0x08
|
||||
#define IKBD_STATE_MOUSE_ABSOLUTE 0x10
|
||||
#define IKBD_STATE_MOUSE_ABSOLUTE_IN_PROGRESS 0x20
|
||||
#define IKBD_STATE_WAIT4RESET 0x40
|
||||
#define IKBD_STATE_PAUSED 0x80
|
||||
|
||||
#define IKBD_DEFAULT IKBD_STATE_JOYSTICK_EVENT_REPORTING
|
||||
|
||||
/* ------------------- transmit queue ------------------- */
|
||||
#define QUEUE_LEN 16 // power of 2!
|
||||
static unsigned short tx_queue[QUEUE_LEN];
|
||||
static unsigned char wptr = 0, rptr = 0;
|
||||
static unsigned long ikbd_timer = 0;
|
||||
|
||||
/* -------- main structure to keep track of ikbd state -------- */
|
||||
static struct {
|
||||
unsigned char state;
|
||||
unsigned long auto_timer; // auto report timer (50hz/20ms)
|
||||
unsigned long rtc_timer;
|
||||
// ----- joystick state -------
|
||||
struct {
|
||||
unsigned char state; // current state
|
||||
unsigned char prev; // last reported state
|
||||
} joy[2];
|
||||
|
||||
// ----- mouse state -------
|
||||
struct {
|
||||
// current state
|
||||
unsigned char but, but_prev;
|
||||
short x, y;
|
||||
|
||||
struct {
|
||||
// absolute mouse state
|
||||
unsigned char buttons;
|
||||
struct { unsigned short x, y; } max;
|
||||
struct { unsigned char x, y; } scale;
|
||||
struct { unsigned short x, y; } pos;
|
||||
} abs;
|
||||
} mouse;
|
||||
|
||||
// ----- clock state ------
|
||||
unsigned char date[6];
|
||||
|
||||
unsigned int tx_cnt; // tx byte counter for debugging
|
||||
|
||||
// ----- buffer tp hold incoming commands ------
|
||||
struct {
|
||||
char size;
|
||||
|
||||
union {
|
||||
struct {
|
||||
unsigned char code; // cmd code
|
||||
|
||||
// command specific structures
|
||||
union {
|
||||
unsigned char mouse_button_action;
|
||||
unsigned char reset;
|
||||
struct { unsigned short max_x, max_y; } __attribute__((packed)) abs_mouse_pos;
|
||||
struct { unsigned char dist_x, dist_y; } __attribute__((packed)) mouse_keycode;
|
||||
struct { unsigned char x, y; } __attribute__((packed)) mouse_threshold;
|
||||
struct { unsigned char x, y; } __attribute__((packed)) mouse_scale;
|
||||
struct { unsigned char f; unsigned short x, y; } __attribute__((packed)) load_mouse_pos;
|
||||
unsigned char date[6];
|
||||
};
|
||||
} __attribute__((packed)) command;
|
||||
|
||||
unsigned char byte[0];
|
||||
};
|
||||
} buffer;
|
||||
|
||||
} ikbd;
|
||||
|
||||
// read a 16 bit word in big endian
|
||||
unsigned short be16(unsigned short in) {
|
||||
return ((in & 0xff) << 8) + ((in & 0xff00) >> 8);
|
||||
}
|
||||
|
||||
static void enqueue(unsigned short b) {
|
||||
if (((wptr + 1)&(QUEUE_LEN - 1)) == rptr)
|
||||
return;
|
||||
|
||||
tx_queue[wptr] = b;
|
||||
wptr = (wptr + 1)&(QUEUE_LEN - 1);
|
||||
}
|
||||
|
||||
unsigned char bcd2bin(unsigned char in) {
|
||||
return 10 * (in >> 4) + (in & 0x0f);
|
||||
}
|
||||
|
||||
unsigned char bin2bcd(unsigned char in) {
|
||||
return 16 * (in / 10) + (in % 10);
|
||||
}
|
||||
|
||||
// convert internal joystick format into atari ikbd format
|
||||
static unsigned char joystick_map2ikbd(unsigned char in) {
|
||||
unsigned char out = 0;
|
||||
|
||||
if (in & JOY_UP) out |= 0x01;
|
||||
if (in & JOY_DOWN) out |= 0x02;
|
||||
if (in & JOY_LEFT) out |= 0x04;
|
||||
if (in & JOY_RIGHT) out |= 0x08;
|
||||
if (in & JOY_BTN1) out |= 0x80;
|
||||
|
||||
return out;
|
||||
}
|
||||
|
||||
void ikbd_handler_mouse_button_action(void) {
|
||||
unsigned char action = ikbd.buffer.command.mouse_button_action;
|
||||
ikbd_debugf("mouse button action = %d", action);
|
||||
|
||||
// bit 2: Mouse buttons act like keys (LEFT=0x74 & RIGHT=0x75)
|
||||
if (action & 0x04) ikbd.state |= IKBD_STATE_MOUSE_BUTTON_AS_KEY;
|
||||
else ikbd.state &= ~IKBD_STATE_MOUSE_BUTTON_AS_KEY;
|
||||
}
|
||||
|
||||
void ikbd_handler_set_relative_mouse_pos(void) {
|
||||
ikbd_debugf("Set relative mouse positioning");
|
||||
ikbd.state &= ~IKBD_STATE_MOUSE_DISABLED;
|
||||
ikbd.state &= ~IKBD_STATE_MOUSE_ABSOLUTE;
|
||||
}
|
||||
|
||||
void ikbd_handler_set_abs_mouse_pos(void) {
|
||||
ikbd.mouse.abs.max.x = be16(ikbd.buffer.command.abs_mouse_pos.max_x);
|
||||
ikbd.mouse.abs.max.y = be16(ikbd.buffer.command.abs_mouse_pos.max_y);
|
||||
|
||||
ikbd_debugf("Set absolute mouse positioning, max = %u/%u",
|
||||
ikbd.mouse.abs.max.x, ikbd.mouse.abs.max.y);
|
||||
|
||||
ikbd.state &= ~IKBD_STATE_MOUSE_DISABLED;
|
||||
ikbd.state |= IKBD_STATE_MOUSE_ABSOLUTE;
|
||||
ikbd.mouse.abs.buttons = 2 | 8;
|
||||
}
|
||||
|
||||
void ikbd_handler_set_mouse_keycode_mode(void) {
|
||||
ikbd_debugf("Set mouse keycode mode dist %u/%u",
|
||||
ikbd.buffer.command.mouse_keycode.dist_x,
|
||||
ikbd.buffer.command.mouse_keycode.dist_y);
|
||||
}
|
||||
|
||||
void ikbd_handler_set_mouse_threshold(void) {
|
||||
ikbd_debugf("Set mouse threshold %u/%u",
|
||||
ikbd.buffer.command.mouse_threshold.x,
|
||||
ikbd.buffer.command.mouse_threshold.y);
|
||||
}
|
||||
|
||||
void ikbd_handler_set_mouse_scale(void) {
|
||||
ikbd_debugf("Set mouse scale %u/%u",
|
||||
ikbd.buffer.command.mouse_scale.x,
|
||||
ikbd.buffer.command.mouse_scale.y);
|
||||
|
||||
ikbd.mouse.abs.scale.x = ikbd.buffer.command.mouse_scale.x;
|
||||
ikbd.mouse.abs.scale.y = ikbd.buffer.command.mouse_scale.y;
|
||||
}
|
||||
|
||||
void ikbd_handler_interrogate_mouse_pos(void) {
|
||||
// ikbd_debugf("Interrogate Mouse Position");
|
||||
if (ikbd.state & IKBD_STATE_MOUSE_ABSOLUTE) {
|
||||
|
||||
enqueue(0x8000 + 3); // 3ms delay, hatari uses 18000 cycles (~2.25ms)
|
||||
enqueue(0xf7);
|
||||
enqueue(ikbd.mouse.abs.buttons);
|
||||
enqueue(ikbd.mouse.abs.pos.x >> 8);
|
||||
enqueue(ikbd.mouse.abs.pos.x & 0xff);
|
||||
enqueue(ikbd.mouse.abs.pos.y >> 8);
|
||||
enqueue(ikbd.mouse.abs.pos.y & 0xff);
|
||||
|
||||
ikbd.mouse.abs.buttons = 0;
|
||||
}
|
||||
}
|
||||
|
||||
void ikbd_handler_load_mouse_pos(void) {
|
||||
ikbd.mouse.abs.pos.x = be16(ikbd.buffer.command.load_mouse_pos.x);
|
||||
ikbd.mouse.abs.pos.y = be16(ikbd.buffer.command.load_mouse_pos.y);
|
||||
|
||||
ikbd_debugf("Load mouse position %u/%u", ikbd.mouse.abs.pos.x, ikbd.mouse.abs.pos.y);
|
||||
}
|
||||
|
||||
void ikbd_handler_set_y_bottom(void) {
|
||||
ikbd_debugf("Set Y at bottom");
|
||||
ikbd.state |= IKBD_STATE_MOUSE_Y_BOTTOM;
|
||||
}
|
||||
|
||||
void ikbd_handler_set_y_top(void) {
|
||||
ikbd_debugf("Set Y at top");
|
||||
ikbd.state &= ~IKBD_STATE_MOUSE_Y_BOTTOM;
|
||||
}
|
||||
|
||||
void ikbd_handler_resume(void) {
|
||||
ikbd.state &= ~IKBD_STATE_PAUSED;
|
||||
}
|
||||
|
||||
void ikbd_handler_disable_mouse(void) {
|
||||
ikbd_debugf("Disable mouse");
|
||||
ikbd.state |= IKBD_STATE_MOUSE_DISABLED;
|
||||
}
|
||||
|
||||
void ikbd_handler_pause(void) {
|
||||
ikbd.state |= IKBD_STATE_PAUSED;
|
||||
}
|
||||
|
||||
void ikbd_handler_set_joystick_event_reporting(void) {
|
||||
ikbd_debugf("Set Joystick event reporting");
|
||||
ikbd.state |= IKBD_STATE_JOYSTICK_EVENT_REPORTING;
|
||||
ikbd.state &= ~IKBD_STATE_PAUSED;
|
||||
}
|
||||
|
||||
void ikbd_handler_set_joystick_interrogation_mode(void) {
|
||||
ikbd_debugf("Set Joystick interrogation mode");
|
||||
ikbd.state &= ~IKBD_STATE_JOYSTICK_EVENT_REPORTING;
|
||||
ikbd.state &= ~IKBD_STATE_PAUSED;
|
||||
}
|
||||
|
||||
void ikbd_handler_interrogate_joystick(void) {
|
||||
// send reply
|
||||
enqueue(0xfd);
|
||||
enqueue(ikbd.joy[0].state | ((ikbd.mouse.but & (1 << 0)) ? 0x80 : 0x00));
|
||||
enqueue(ikbd.joy[1].state | ((ikbd.mouse.but & (1 << 1)) ? 0x80 : 0x00));
|
||||
}
|
||||
|
||||
void ikbd_handler_disable_joysticks(void) {
|
||||
ikbd_debugf("Disable joysticks");
|
||||
ikbd.state &= ~IKBD_STATE_JOYSTICK_EVENT_REPORTING;
|
||||
}
|
||||
|
||||
void ikbd_handler_time_set(void) {
|
||||
unsigned char c;
|
||||
for (c = 0; c<6; c++)
|
||||
ikbd.date[c] = bcd2bin(ikbd.buffer.command.date[c]);
|
||||
|
||||
// release SPI since it will be used by usb when
|
||||
// reading the time from the rtc
|
||||
DisableIO();
|
||||
|
||||
// try to set time on rtc if present
|
||||
//usb_rtc_set_time(ikbd.date);
|
||||
|
||||
spi_uio_cmd_cont(UIO_IKBD_IN);
|
||||
|
||||
ikbd_debugf("Time of day clock set: %u:%02u:%02u %u.%u.%u",
|
||||
ikbd.date[3], ikbd.date[4], ikbd.date[5],
|
||||
ikbd.date[2], ikbd.date[1], 1900 + ikbd.date[0]);
|
||||
}
|
||||
|
||||
void ikbd_handler_interrogate_time(void) {
|
||||
unsigned char i;
|
||||
|
||||
// release SPI since it will be used by usb when
|
||||
// reading the time from the rtc
|
||||
DisableIO();
|
||||
|
||||
// try to fetch time from rtc if present
|
||||
//usb_rtc_get_time(ikbd.date);
|
||||
|
||||
spi_uio_cmd_cont(UIO_IKBD_IN);
|
||||
|
||||
ikbd_debugf("Interrogate time of day %u:%02u:%02u %u.%u.%u",
|
||||
ikbd.date[3], ikbd.date[4], ikbd.date[5],
|
||||
ikbd.date[2], ikbd.date[1], 1900 + ikbd.date[0]);
|
||||
|
||||
enqueue(0x8000 + 64); // wait 64ms
|
||||
enqueue(0xfc);
|
||||
for (i = 0; i<6; i++) enqueue(bin2bcd(ikbd.date[i]));
|
||||
}
|
||||
|
||||
void ikbd_handler_reset(void) {
|
||||
ikbd_debugf("Reset %x", ikbd.buffer.command.reset);
|
||||
|
||||
if (ikbd.buffer.command.reset == 1) {
|
||||
ikbd.state = IKBD_DEFAULT;
|
||||
|
||||
enqueue(0x8000 + 300); // wait 300ms
|
||||
enqueue(0xf0);
|
||||
}
|
||||
}
|
||||
|
||||
// ---- list of supported ikbd commands ----
|
||||
struct ikbd_command_handler_t {
|
||||
unsigned char code;
|
||||
unsigned char length;
|
||||
void(*handler)(void);
|
||||
};
|
||||
|
||||
ikbd_command_handler_t ikbd_command_handler[] =
|
||||
{
|
||||
{ 0x07, 2, ikbd_handler_mouse_button_action },
|
||||
{ 0x08, 1, ikbd_handler_set_relative_mouse_pos },
|
||||
{ 0x09, 5, ikbd_handler_set_abs_mouse_pos },
|
||||
{ 0x0a, 3, ikbd_handler_set_mouse_keycode_mode },
|
||||
{ 0x0b, 3, ikbd_handler_set_mouse_threshold },
|
||||
{ 0x0c, 3, ikbd_handler_set_mouse_scale },
|
||||
{ 0x0d, 1, ikbd_handler_interrogate_mouse_pos },
|
||||
{ 0x0e, 6, ikbd_handler_load_mouse_pos },
|
||||
{ 0x0f, 1, ikbd_handler_set_y_bottom },
|
||||
{ 0x10, 1, ikbd_handler_set_y_top },
|
||||
{ 0x11, 1, ikbd_handler_resume },
|
||||
{ 0x12, 1, ikbd_handler_disable_mouse },
|
||||
{ 0x13, 1, ikbd_handler_pause },
|
||||
{ 0x14, 1, ikbd_handler_set_joystick_event_reporting },
|
||||
{ 0x15, 1, ikbd_handler_set_joystick_interrogation_mode },
|
||||
{ 0x16, 1, ikbd_handler_interrogate_joystick },
|
||||
{ 0x1a, 1, ikbd_handler_disable_joysticks },
|
||||
{ 0x1c, 1, ikbd_handler_interrogate_time },
|
||||
{ 0x1b, 7, ikbd_handler_time_set },
|
||||
{ 0x80, 2, ikbd_handler_reset },
|
||||
{ 0, 0, NULL } // end of list
|
||||
};
|
||||
|
||||
void ikbd_init() {
|
||||
// reset ikbd state
|
||||
memset(&ikbd, 0, sizeof(ikbd));
|
||||
ikbd.state = IKBD_DEFAULT | IKBD_STATE_WAIT4RESET;
|
||||
|
||||
ikbd.mouse.abs.max.x = ikbd.mouse.abs.max.y = 65535;
|
||||
ikbd.mouse.abs.scale.x = ikbd.mouse.abs.scale.y = 1;
|
||||
|
||||
ikbd_debugf("Init");
|
||||
|
||||
// init ikbd date to some default
|
||||
ikbd.date[0] = 113;
|
||||
ikbd.date[1] = 7;
|
||||
ikbd.date[2] = 20;
|
||||
ikbd.date[3] = 20;
|
||||
ikbd.date[4] = 58;
|
||||
|
||||
// handle auto events
|
||||
ikbd.auto_timer = GetTimer(0);
|
||||
ikbd.rtc_timer = GetTimer(1000);
|
||||
}
|
||||
|
||||
void ikbd_reset(void) {
|
||||
ikbd.tx_cnt = 0;
|
||||
ikbd.state |= IKBD_STATE_WAIT4RESET;
|
||||
}
|
||||
|
||||
// process inout from atari core into ikbd
|
||||
void ikbd_handle_input(unsigned char cmd) {
|
||||
// store byte in buffer
|
||||
unsigned char *byte = ikbd.buffer.byte;
|
||||
byte[(int)(ikbd.buffer.size++)] = cmd;
|
||||
|
||||
// check if there's a known command in the buffer
|
||||
int c;
|
||||
for (c = 0; ikbd_command_handler[c].length &&
|
||||
(ikbd_command_handler[c].code != ikbd.buffer.command.code); c++);
|
||||
|
||||
// not a valid command? -> flush buffer
|
||||
if (!ikbd_command_handler[c].length)
|
||||
ikbd.buffer.size = 0;
|
||||
else {
|
||||
// valid command and enough bytes?
|
||||
if (ikbd_command_handler[c].length == ikbd.buffer.size) {
|
||||
ikbd_command_handler[c].handler();
|
||||
ikbd.buffer.size = 0;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// advance the ikbd time by one second
|
||||
static void ikbd_update_time()
|
||||
{
|
||||
static const char mdays[] = { 31, 29, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31 };
|
||||
|
||||
short year = 1900 + ikbd.date[0];
|
||||
char is_leap = (!(year % 4) && (year % 100)) || !(year % 400);
|
||||
|
||||
// advance seconds
|
||||
ikbd.date[5]++;
|
||||
if (ikbd.date[5] == 60)
|
||||
{
|
||||
ikbd.date[5] = 0;
|
||||
|
||||
// advance minutes
|
||||
ikbd.date[4]++;
|
||||
if (ikbd.date[4] == 60)
|
||||
{
|
||||
ikbd.date[4] = 0;
|
||||
|
||||
// advance hours
|
||||
ikbd.date[3]++;
|
||||
if (ikbd.date[3] == 24)
|
||||
{
|
||||
ikbd.date[3] = 0;
|
||||
|
||||
// advance days
|
||||
ikbd.date[2]++;
|
||||
if ((ikbd.date[2] == mdays[ikbd.date[1] - 1] + 1) ||
|
||||
(is_leap && (ikbd.date[1] == 2) && (ikbd.date[2] == 29)))
|
||||
{
|
||||
ikbd.date[2] = 1;
|
||||
|
||||
// advance month
|
||||
ikbd.date[1]++;
|
||||
if (ikbd.date[1] == 13)
|
||||
{
|
||||
ikbd.date[1] = 0;
|
||||
|
||||
// advance year
|
||||
ikbd.date[0]++;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void ikbd_poll(void) {
|
||||
#ifdef IKBD_DEBUG
|
||||
static unsigned long xtimer = 0;
|
||||
static unsigned int last_cnt = 0;
|
||||
if (CheckTimer(xtimer)) {
|
||||
xtimer = GetTimer(2000);
|
||||
if (ikbd.tx_cnt != last_cnt) {
|
||||
ikbd_debugf("sent bytes: %d", ikbd.tx_cnt);
|
||||
last_cnt = ikbd.tx_cnt;
|
||||
}
|
||||
}
|
||||
#endif
|
||||
if (CheckTimer(ikbd.rtc_timer))
|
||||
{
|
||||
ikbd.rtc_timer = GetTimer(1000);
|
||||
ikbd_update_time();
|
||||
}
|
||||
|
||||
// do auto events every 20ms
|
||||
if (CheckTimer(ikbd.auto_timer)) {
|
||||
ikbd.auto_timer = GetTimer(IKBD_AUTO_MS);
|
||||
|
||||
if (!(ikbd.state & IKBD_STATE_WAIT4RESET) &&
|
||||
!(ikbd.state & IKBD_STATE_PAUSED)) {
|
||||
|
||||
/* --------- joystick ---------- */
|
||||
if (ikbd.state & IKBD_STATE_JOYSTICK_EVENT_REPORTING) {
|
||||
int i;
|
||||
for (i = 0; i<2; i++) {
|
||||
unsigned char state = ikbd.joy[i].state;
|
||||
|
||||
// left mouse button 1 is also joystick 0 fire button
|
||||
// right mouse button 0 is also joystick 1 fire button
|
||||
if (ikbd.mouse.but & (2 >> i)) state |= 0x80;
|
||||
|
||||
if (state != ikbd.joy[i].prev) {
|
||||
// printf("JOY%d: %x\n", i, state);
|
||||
enqueue(0xfe + i);
|
||||
enqueue(state);
|
||||
ikbd.joy[i].prev = state;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/* ----------- relative mouse ---------- */
|
||||
if (!(ikbd.state & IKBD_STATE_MOUSE_DISABLED) &&
|
||||
!(ikbd.state & IKBD_STATE_MOUSE_ABSOLUTE)) {
|
||||
unsigned char b = ikbd.mouse.but;
|
||||
|
||||
// include joystick buttons into mouse state
|
||||
if (ikbd.joy[0].state & 0x80) b |= 2;
|
||||
if (ikbd.joy[1].state & 0x80) b |= 1;
|
||||
|
||||
if (ikbd.mouse.x || ikbd.mouse.y || (b != ikbd.mouse.but_prev)) {
|
||||
do {
|
||||
char x, y;
|
||||
if (ikbd.mouse.x < -128) x = -128;
|
||||
else if (ikbd.mouse.x > 127) x = 127;
|
||||
else x = ikbd.mouse.x;
|
||||
|
||||
if (ikbd.mouse.y < -128) y = -128;
|
||||
else if (ikbd.mouse.y > 127) y = 127;
|
||||
else y = ikbd.mouse.y;
|
||||
|
||||
// printf("RMOUSE: %x %x %x\n", b, x&0xff, y&0xff);
|
||||
enqueue(0xf8 | b);
|
||||
enqueue(x & 0xff);
|
||||
enqueue(y & 0xff);
|
||||
|
||||
ikbd.mouse.x -= x;
|
||||
ikbd.mouse.y -= y;
|
||||
|
||||
} while (ikbd.mouse.x || ikbd.mouse.y);
|
||||
|
||||
// check if mouse buttons are supposed to be treated like keys
|
||||
if (ikbd.state & IKBD_STATE_MOUSE_BUTTON_AS_KEY) {
|
||||
|
||||
// check if mouse button state has changed
|
||||
if (b != ikbd.mouse.but_prev) {
|
||||
// Mouse buttons act like keys (LEFT=0x74 & RIGHT=0x75)
|
||||
|
||||
// handle left mouse button
|
||||
if ((b ^ ikbd.mouse.but_prev) & 2) ikbd_keyboard(0x74 | ((b & 2) ? 0x00 : 0x80));
|
||||
// handle right mouse button
|
||||
if ((b ^ ikbd.mouse.but_prev) & 1) ikbd_keyboard(0x75 | ((b & 1) ? 0x00 : 0x80));
|
||||
}
|
||||
}
|
||||
|
||||
ikbd.mouse.but_prev = b;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
static unsigned long mtimer = 0;
|
||||
if (CheckTimer(mtimer)) {
|
||||
mtimer = GetTimer(10);
|
||||
|
||||
// check for incoming ikbd data
|
||||
spi_uio_cmd_cont(UIO_IKBD_IN);
|
||||
|
||||
while (spi_in())
|
||||
ikbd_handle_input(spi_in());
|
||||
|
||||
DisableIO();
|
||||
}
|
||||
|
||||
// everything below must not happen faster than 1khz
|
||||
static unsigned long rtimer = 0;
|
||||
if (!CheckTimer(rtimer))
|
||||
return;
|
||||
|
||||
// next event 1 ms later
|
||||
rtimer = GetTimer(1);
|
||||
|
||||
// timer active?
|
||||
if (ikbd_timer) {
|
||||
if (!CheckTimer(ikbd_timer))
|
||||
return;
|
||||
|
||||
ikbd_timer = 0;
|
||||
}
|
||||
|
||||
if (rptr == wptr) return;
|
||||
|
||||
if (tx_queue[rptr] & 0x8000) {
|
||||
|
||||
// request to start timer?
|
||||
if (tx_queue[rptr] & 0x8000)
|
||||
ikbd_timer = GetTimer(tx_queue[rptr] & 0x3fff);
|
||||
|
||||
rptr = (rptr + 1)&(QUEUE_LEN - 1);
|
||||
return;
|
||||
}
|
||||
|
||||
// transmit data from queue
|
||||
spi_uio_cmd_cont(UIO_IKBD_OUT);
|
||||
spi8(tx_queue[rptr]);
|
||||
DisableIO();
|
||||
|
||||
ikbd.tx_cnt++;
|
||||
|
||||
rptr = (rptr + 1)&(QUEUE_LEN - 1);
|
||||
}
|
||||
|
||||
// called from external parts to report joystick states
|
||||
void ikbd_joystick(unsigned char joystick, unsigned char map) {
|
||||
ikbd.joy[joystick].state = joystick_map2ikbd(map);
|
||||
}
|
||||
|
||||
void ikbd_keyboard(unsigned char code) {
|
||||
#ifdef IKBD_DEBUG
|
||||
ikbd_debugf("send keycode %x%s", code & 0x7f, (code & 0x80) ? " BREAK" : "");
|
||||
#endif
|
||||
enqueue(code);
|
||||
}
|
||||
|
||||
void ikbd_mouse(unsigned char b, signed char x, signed char y) {
|
||||
|
||||
// honour reversal of y axis
|
||||
if (ikbd.state & IKBD_STATE_MOUSE_Y_BOTTOM)
|
||||
y = -y;
|
||||
|
||||
// update relative mouse state
|
||||
ikbd.mouse.but = ((b & 1) ? 2 : 0) | ((b & 2) ? 1 : 0);
|
||||
ikbd.mouse.x += x;
|
||||
ikbd.mouse.y += y;
|
||||
|
||||
// save button state for absolute mouse reports
|
||||
|
||||
if (ikbd.state & IKBD_STATE_MOUSE_ABSOLUTE) {
|
||||
// include joystick buttons into mouse state
|
||||
if (ikbd.joy[0].state & 0x80) b |= 2;
|
||||
if (ikbd.joy[1].state & 0x80) b |= 1;
|
||||
|
||||
if (b & 2) ikbd.mouse.abs.buttons |= 1;
|
||||
else ikbd.mouse.abs.buttons |= 2;
|
||||
if (b & 1) ikbd.mouse.abs.buttons |= 4;
|
||||
else ikbd.mouse.abs.buttons |= 8;
|
||||
|
||||
if (ikbd.mouse.abs.scale.x > 1) x *= ikbd.mouse.abs.scale.x;
|
||||
if (ikbd.mouse.abs.scale.y > 1) y *= ikbd.mouse.abs.scale.y;
|
||||
|
||||
// ikbd_debugf("abs inc %d %d -> ", x, y);
|
||||
|
||||
if (x < 0) {
|
||||
x = -x;
|
||||
|
||||
if (ikbd.mouse.abs.pos.x > x) ikbd.mouse.abs.pos.x -= x;
|
||||
else ikbd.mouse.abs.pos.x = 0;
|
||||
}
|
||||
else if (x > 0) {
|
||||
if (ikbd.mouse.abs.pos.x < ikbd.mouse.abs.max.x - x)
|
||||
ikbd.mouse.abs.pos.x += x;
|
||||
else
|
||||
ikbd.mouse.abs.pos.x = ikbd.mouse.abs.max.x;
|
||||
}
|
||||
|
||||
if (y < 0) {
|
||||
y = -y;
|
||||
if (ikbd.mouse.abs.pos.y > y) ikbd.mouse.abs.pos.y -= y;
|
||||
else ikbd.mouse.abs.pos.y = 0;
|
||||
}
|
||||
else if (y > 0) {
|
||||
if (ikbd.mouse.abs.pos.y < ikbd.mouse.abs.max.y - y)
|
||||
ikbd.mouse.abs.pos.y += y;
|
||||
else
|
||||
ikbd.mouse.abs.pos.y = ikbd.mouse.abs.max.y;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1,11 +0,0 @@
|
||||
#ifndef __ST_IKBD_H__
|
||||
#define __ST_IKBD_H__
|
||||
|
||||
void ikbd_init(void);
|
||||
void ikbd_poll(void);
|
||||
void ikbd_reset(void);
|
||||
void ikbd_joystick(unsigned char joy, unsigned char map);
|
||||
void ikbd_mouse(unsigned char buttons, signed char x, signed char y);
|
||||
void ikbd_keyboard(unsigned char code);
|
||||
|
||||
#endif // IKBD_H
|
||||
File diff suppressed because it is too large
Load Diff
@@ -3,21 +3,6 @@
|
||||
|
||||
#include "../../file_io.h"
|
||||
|
||||
// FPGA spi cmommands
|
||||
#define MIST_INVALID 0x00
|
||||
|
||||
// memory interface
|
||||
#define MIST_SET_ADDRESS 0x01
|
||||
#define MIST_WRITE_MEMORY 0x02
|
||||
#define MIST_READ_MEMORY 0x03
|
||||
#define MIST_SET_CONTROL 0x04
|
||||
#define MIST_GET_DMASTATE 0x05 // reads state of dma and floppy controller
|
||||
#define MIST_ACK_DMA 0x06 // acknowledge a dma command
|
||||
#define MIST_BUS_REQ 0x07 // request bus
|
||||
#define MIST_BUS_REL 0x08 // release bus
|
||||
#define MIST_SET_VADJ 0x09
|
||||
#define MIST_NAK_DMA 0x0a // reject a dma command
|
||||
|
||||
// tos sysconfig bits:
|
||||
// 0 - RESET
|
||||
// 1-3 - Memory configuration
|
||||
@@ -80,28 +65,28 @@
|
||||
|
||||
#define TOS_CONTROL_VIKING 0x10000000 // Viking graphics card
|
||||
|
||||
#define TOS_CONTROL_BORDER 0x20000000
|
||||
|
||||
unsigned long tos_system_ctrl(void);
|
||||
|
||||
void tos_upload(const char *);
|
||||
void tos_poll();
|
||||
void tos_update_sysctrl(unsigned long);
|
||||
char *tos_get_disk_name(int);
|
||||
char tos_disk_is_inserted(int index);
|
||||
void tos_insert_disk(int i, const char *name);
|
||||
void tos_insert_disk(int index, const char *name);
|
||||
void tos_eject_all();
|
||||
void tos_select_hdd_image(int i, const char *name);
|
||||
void tos_set_direct_hdd(char on);
|
||||
char tos_get_direct_hdd();
|
||||
void tos_reset(char cold);
|
||||
char *tos_get_image_name();
|
||||
char *tos_get_cartridge_name();
|
||||
const char *tos_get_disk_name(int);
|
||||
const char *tos_get_image_name();
|
||||
const char *tos_get_cartridge_name();
|
||||
char tos_cartridge_is_inserted();
|
||||
void tos_load_cartridge(const char *);
|
||||
|
||||
void tos_set_video_adjust(int axis, char value);
|
||||
char tos_get_video_adjust(int axis);
|
||||
int tos_get_cdc_control_redirect(void);
|
||||
void tos_set_cdc_control_redirect(char mode);
|
||||
|
||||
void tos_config_init(void);
|
||||
void tos_config_save(void);
|
||||
void tos_config_load(int slot); // slot -1 == last config
|
||||
void tos_config_save(int slot);
|
||||
int tos_config_exists(int slot);
|
||||
|
||||
#endif
|
||||
|
||||
273
user_io.cpp
273
user_io.cpp
@@ -170,9 +170,6 @@ const char *user_io_get_core_name_ex()
|
||||
{
|
||||
switch (user_io_core_type())
|
||||
{
|
||||
case CORE_TYPE_MIST:
|
||||
return "ST";
|
||||
|
||||
case CORE_TYPE_ARCHIE:
|
||||
return "ARCHIE";
|
||||
|
||||
@@ -700,9 +697,7 @@ void user_io_init(const char *path, const char *xml)
|
||||
core_type = CORE_TYPE_8BIT;
|
||||
}
|
||||
|
||||
if ((core_type != CORE_TYPE_DUMB) &&
|
||||
(core_type != CORE_TYPE_MIST) &&
|
||||
(core_type != CORE_TYPE_ARCHIE) &&
|
||||
if ((core_type != CORE_TYPE_ARCHIE) &&
|
||||
(core_type != CORE_TYPE_8BIT) &&
|
||||
(core_type != CORE_TYPE_SHARPMZ))
|
||||
{
|
||||
@@ -746,17 +741,6 @@ void user_io_init(const char *path, const char *xml)
|
||||
printf("Unable to identify core (%x)!\n", core_type);
|
||||
break;
|
||||
|
||||
case CORE_TYPE_DUMB:
|
||||
puts("Identified core without user interface");
|
||||
break;
|
||||
|
||||
case CORE_TYPE_MIST:
|
||||
puts("Identified MiST core");
|
||||
ikbd_init();
|
||||
tos_config_init();
|
||||
tos_upload(NULL);
|
||||
break;
|
||||
|
||||
case CORE_TYPE_ARCHIE:
|
||||
puts("Identified Archimedes core");
|
||||
spi_uio_cmd16(UIO_SET_MEMSZ, sdram_sz(-1));
|
||||
@@ -784,18 +768,26 @@ void user_io_init(const char *path, const char *xml)
|
||||
{
|
||||
OsdCoreNameSet(user_io_get_core_name());
|
||||
|
||||
printf("Loading config %s\n", name);
|
||||
uint32_t status[2] = { 0, 0 };
|
||||
if (FileLoadConfig(name, status, 8))
|
||||
if (!is_st())
|
||||
{
|
||||
printf("Found config: %08X-%08X\n", status[0], status[1]);
|
||||
status[0] &= ~UIO_STATUS_RESET;
|
||||
user_io_8bit_set_status(status[0], ~UIO_STATUS_RESET, 0);
|
||||
user_io_8bit_set_status(status[1], 0xffffffff, 1);
|
||||
printf("Loading config %s\n", name);
|
||||
if (FileLoadConfig(name, status, 8))
|
||||
{
|
||||
printf("Found config: %08X-%08X\n", status[0], status[1]);
|
||||
status[0] &= ~UIO_STATUS_RESET;
|
||||
user_io_8bit_set_status(status[0], ~UIO_STATUS_RESET, 0);
|
||||
user_io_8bit_set_status(status[1], 0xffffffff, 1);
|
||||
}
|
||||
parse_config();
|
||||
}
|
||||
parse_config();
|
||||
|
||||
if (is_menu())
|
||||
if (is_st())
|
||||
{
|
||||
tos_config_load(0);
|
||||
tos_upload(NULL);
|
||||
}
|
||||
else if (is_menu())
|
||||
{
|
||||
user_io_8bit_set_status((cfg.menu_pal) ? 0x10 : 0, 0x10);
|
||||
if (cfg.fb_terminal) video_menu_bg((status[0] >> 1) & 7);
|
||||
@@ -972,14 +964,6 @@ void user_io_digital_joystick(unsigned char joystick, uint32_t map, int newdir)
|
||||
{
|
||||
uint8_t joy = (joystick>1 || !joyswap) ? joystick : joystick ^ 1;
|
||||
|
||||
// atari ST handles joystick 0 and 1 through the ikbd emulated by the io controller
|
||||
// but only for joystick 1 and 2
|
||||
if (core_type == CORE_TYPE_MIST)
|
||||
{
|
||||
ikbd_joystick(joy, (uint8_t)map);
|
||||
return;
|
||||
}
|
||||
|
||||
static int use32 = 0;
|
||||
use32 |= map >> 16;
|
||||
|
||||
@@ -994,51 +978,6 @@ void user_io_digital_joystick(unsigned char joystick, uint32_t map, int newdir)
|
||||
}
|
||||
}
|
||||
|
||||
// transmit serial/rs232 data into core
|
||||
void user_io_serial_tx(char *chr, uint16_t cnt)
|
||||
{
|
||||
spi_uio_cmd_cont(UIO_SERIAL_OUT);
|
||||
while (cnt--) spi8(*chr++);
|
||||
DisableIO();
|
||||
}
|
||||
|
||||
char user_io_serial_status(serial_status_t *status_in, uint8_t status_out)
|
||||
{
|
||||
uint8_t i, *p = (uint8_t*)status_in;
|
||||
|
||||
spi_uio_cmd_cont(UIO_SERIAL_STAT);
|
||||
|
||||
// first byte returned by core must be "magic". otherwise the
|
||||
// core doesn't support this request
|
||||
if (spi_b(status_out) != 0xa5)
|
||||
{
|
||||
DisableIO();
|
||||
return 0;
|
||||
}
|
||||
|
||||
// read the whole structure
|
||||
for (i = 0; i<sizeof(serial_status_t); i++) *p++ = spi_in();
|
||||
|
||||
DisableIO();
|
||||
return 1;
|
||||
}
|
||||
|
||||
// transmit midi data into core
|
||||
void user_io_midi_tx(char chr)
|
||||
{
|
||||
spi_uio_cmd8(UIO_MIDI_OUT, chr);
|
||||
}
|
||||
|
||||
// send ethernet mac address into FPGA
|
||||
void user_io_eth_send_mac(uint8_t *mac)
|
||||
{
|
||||
uint8_t i;
|
||||
|
||||
spi_uio_cmd_cont(UIO_ETH_MAC);
|
||||
for (i = 0; i<6; i++) spi8(*mac++);
|
||||
DisableIO();
|
||||
}
|
||||
|
||||
static uint8_t CSD[16] = { 0xf1, 0x40, 0x40, 0x0a, 0x80, 0x7f, 0xe5, 0xe9, 0x00, 0x00, 0x59, 0x5b, 0x32, 0x00, 0x0e, 0x40 };
|
||||
static uint8_t CID[16] = { 0x3e, 0x00, 0x00, 0x34, 0x38, 0x32, 0x44, 0x00, 0x00, 0x73, 0x2f, 0x6f, 0x93, 0x00, 0xc7, 0xcd };
|
||||
|
||||
@@ -1131,38 +1070,6 @@ uint8_t user_io_ps2_ctl(uint8_t *kbd_ctl, uint8_t *mouse_ctl)
|
||||
return res;
|
||||
}
|
||||
|
||||
// read 32 bit ethernet status word from FPGA
|
||||
uint32_t user_io_eth_get_status(void)
|
||||
{
|
||||
uint32_t s;
|
||||
|
||||
spi_uio_cmd_cont(UIO_ETH_STATUS);
|
||||
s = spi_in();
|
||||
s = (s << 8) | spi_in();
|
||||
s = (s << 8) | spi_in();
|
||||
s = (s << 8) | spi_in();
|
||||
DisableIO();
|
||||
|
||||
return s;
|
||||
}
|
||||
|
||||
// read ethernet frame from FPGAs ethernet tx buffer
|
||||
void user_io_eth_receive_tx_frame(uint8_t *d, uint16_t len)
|
||||
{
|
||||
spi_uio_cmd_cont(UIO_ETH_FRM_IN);
|
||||
while (len--) *d++ = spi_in();
|
||||
DisableIO();
|
||||
}
|
||||
|
||||
// write ethernet frame to FPGAs rx buffer
|
||||
void user_io_eth_send_rx_frame(uint8_t *s, uint16_t len)
|
||||
{
|
||||
spi_uio_cmd_cont(UIO_ETH_FRM_OUT);
|
||||
spi_write(s, len, 0);
|
||||
spi8(0); // one additional byte to allow fpga to store the previous one
|
||||
DisableIO();
|
||||
}
|
||||
|
||||
// 16 byte fifo for amiga key codes to limit max key rate sent into the core
|
||||
#define KBD_FIFO_SIZE 16 // must be power of 2
|
||||
static unsigned short kbd_fifo[KBD_FIFO_SIZE];
|
||||
@@ -1218,33 +1125,45 @@ void user_io_set_download(unsigned char enable)
|
||||
DisableFpga();
|
||||
}
|
||||
|
||||
int user_io_file_mount(char *name, unsigned char index, char pre)
|
||||
int user_io_file_mount(const char *name, unsigned char index, char pre)
|
||||
{
|
||||
int writable = 0;
|
||||
int ret = 0;
|
||||
int len = strlen(name);
|
||||
|
||||
if (!strcasecmp(user_io_get_core_name_ex(), "apple-ii"))
|
||||
if (len)
|
||||
{
|
||||
ret = dsk2nib(name, sd_image + index);
|
||||
}
|
||||
if (!strcasecmp(user_io_get_core_name_ex(), "apple-ii"))
|
||||
{
|
||||
ret = dsk2nib(name, sd_image + index);
|
||||
}
|
||||
|
||||
if (!ret)
|
||||
if (!ret)
|
||||
{
|
||||
if (x2trd_ext_supp(name))
|
||||
{
|
||||
ret = x2trd(name, sd_image + index);
|
||||
}
|
||||
else if (is_c64() && len > 4 && !strcasecmp(name + len - 4, ".t64"))
|
||||
{
|
||||
writable = 0;
|
||||
ret = c64_openT64(name, sd_image + index);
|
||||
}
|
||||
else
|
||||
{
|
||||
writable = FileCanWrite(name);
|
||||
ret = FileOpenEx(&sd_image[index], name, writable ? (O_RDWR | O_SYNC) : O_RDONLY);
|
||||
}
|
||||
}
|
||||
|
||||
if (!ret)
|
||||
{
|
||||
printf("Failed to open file %s\n", name);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
if (x2trd_ext_supp(name))
|
||||
{
|
||||
ret = x2trd(name, sd_image + index);
|
||||
}
|
||||
else if (is_c64() && len > 4 && !strcasecmp(name + len - 4, ".t64"))
|
||||
{
|
||||
writable = 0;
|
||||
ret = c64_openT64(name, sd_image + index);
|
||||
}
|
||||
else
|
||||
{
|
||||
writable = FileCanWrite(name);
|
||||
ret = FileOpenEx(&sd_image[index], name, writable ? (O_RDWR | O_SYNC) : O_RDONLY);
|
||||
}
|
||||
FileClose(&sd_image[index]);
|
||||
}
|
||||
|
||||
buffer_lba[index] = ULLONG_MAX;
|
||||
@@ -1252,7 +1171,6 @@ int user_io_file_mount(char *name, unsigned char index, char pre)
|
||||
if (!ret)
|
||||
{
|
||||
sd_image[index].size = 0;
|
||||
printf("Failed to open file %s\n", name);
|
||||
if (pre)
|
||||
{
|
||||
writable = 1;
|
||||
@@ -1982,17 +1900,20 @@ uint32_t user_io_8bit_set_status(uint32_t new_status, uint32_t mask, int ex)
|
||||
// updated masked bits
|
||||
status[ex] |= new_status & mask;
|
||||
|
||||
if (!io_ver)
|
||||
if (!is_st())
|
||||
{
|
||||
spi_uio_cmd8(UIO_SET_STATUS, status[0]);
|
||||
spi_uio_cmd32(UIO_SET_STATUS2, status[0], 0);
|
||||
}
|
||||
else
|
||||
{
|
||||
spi_uio_cmd_cont(UIO_SET_STATUS2);
|
||||
spi32w(status[0]);
|
||||
spi32w(status[1]);
|
||||
DisableIO();
|
||||
if (!io_ver)
|
||||
{
|
||||
spi_uio_cmd8(UIO_SET_STATUS, status[0]);
|
||||
spi_uio_cmd32(UIO_SET_STATUS2, status[0], 0);
|
||||
}
|
||||
else
|
||||
{
|
||||
spi_uio_cmd_cont(UIO_SET_STATUS2);
|
||||
spi32w(status[0]);
|
||||
spi32w(status[1]);
|
||||
DisableIO();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -2128,32 +2049,13 @@ static uint32_t res_timer = 0;
|
||||
|
||||
void user_io_poll()
|
||||
{
|
||||
if ((core_type != CORE_TYPE_MIST) &&
|
||||
(core_type != CORE_TYPE_ARCHIE) &&
|
||||
if ((core_type != CORE_TYPE_ARCHIE) &&
|
||||
(core_type != CORE_TYPE_SHARPMZ) &&
|
||||
(core_type != CORE_TYPE_8BIT))
|
||||
{
|
||||
return; // no user io for the installed core
|
||||
}
|
||||
|
||||
if (core_type == CORE_TYPE_MIST)
|
||||
{
|
||||
ikbd_poll();
|
||||
|
||||
unsigned char c = 0;
|
||||
|
||||
// check for incoming serial data. this is directly forwarded to the
|
||||
// arm rs232 and mixes with debug output. Useful for debugging only of
|
||||
// e.g. the diagnostic cartridge
|
||||
spi_uio_cmd_cont(UIO_SERIAL_IN);
|
||||
while (spi_in())
|
||||
{
|
||||
c = spi_in();
|
||||
if (c != 0xff) putchar(c);
|
||||
}
|
||||
DisableIO();
|
||||
}
|
||||
|
||||
user_io_send_buttons(0);
|
||||
|
||||
if (is_minimig())
|
||||
@@ -2242,40 +2144,8 @@ void user_io_poll()
|
||||
}
|
||||
}
|
||||
|
||||
if (core_type == CORE_TYPE_MIST)
|
||||
{
|
||||
// do some tos specific monitoring here
|
||||
tos_poll();
|
||||
}
|
||||
|
||||
if (core_type == CORE_TYPE_8BIT && !is_menu())
|
||||
{
|
||||
/*
|
||||
unsigned char c = 1, f, p = 0;
|
||||
|
||||
// check for serial data to be sent
|
||||
// check for incoming serial data. this is directly forwarded to the
|
||||
// arm rs232 and mixes with debug output.
|
||||
spi_uio_cmd_cont(UIO_SIO_IN);
|
||||
// status byte is 1000000A with A=1 if data is available
|
||||
if ((f = spi_in(0)) == 0x81)
|
||||
{
|
||||
printf("\033[1;36m");
|
||||
|
||||
// character 0xff is returned if FPGA isn't configured
|
||||
while ((f == 0x81) && (c != 0xff) && (c != 0x00) && (p < 8))
|
||||
{
|
||||
c = spi_in();
|
||||
if (c != 0xff && c != 0x00) printf("%c", c);
|
||||
|
||||
f = spi_in();
|
||||
p++;
|
||||
}
|
||||
printf("\033[0m");
|
||||
}
|
||||
DisableIO();
|
||||
*/
|
||||
|
||||
check_status_change();
|
||||
}
|
||||
|
||||
@@ -2286,6 +2156,8 @@ void user_io_poll()
|
||||
}
|
||||
else if ((core_type == CORE_TYPE_8BIT || core_type == CORE_TYPE_ARCHIE) && !is_menu() && !is_minimig())
|
||||
{
|
||||
if (is_st()) tos_poll();
|
||||
|
||||
static uint8_t buffer[4][512];
|
||||
uint32_t lba;
|
||||
uint16_t req_type = 0;
|
||||
@@ -2839,19 +2711,6 @@ static void send_keycode(unsigned short key, int press)
|
||||
return;
|
||||
}
|
||||
|
||||
if (core_type == CORE_TYPE_MIST)
|
||||
{
|
||||
if (press > 1) return;
|
||||
|
||||
uint32_t code = get_atari_code(key);
|
||||
if (code == NONE) return;
|
||||
|
||||
// atari has "break" marker in msb
|
||||
if (!press) code = (code & 0xff) | 0x80;
|
||||
ikbd_keyboard(code);
|
||||
return;
|
||||
}
|
||||
|
||||
if (core_type == CORE_TYPE_ARCHIE || is_archie())
|
||||
{
|
||||
if (press > 1) return;
|
||||
@@ -3007,10 +2866,6 @@ void user_io_mouse(unsigned char b, int16_t x, int16_t y, int16_t w)
|
||||
}
|
||||
return;
|
||||
|
||||
case CORE_TYPE_MIST:
|
||||
ikbd_mouse(b, x, y);
|
||||
return;
|
||||
|
||||
case CORE_TYPE_ARCHIE:
|
||||
archie_mouse(b, x, y);
|
||||
return;
|
||||
|
||||
47
user_io.h
47
user_io.h
@@ -19,20 +19,12 @@
|
||||
#define UIO_KEYBOARD 0x05 // -"-
|
||||
#define UIO_KBD_OSD 0x06 // keycodes used by OSD only
|
||||
|
||||
// codes as used by MiST (atari)
|
||||
// directions (in/out) are from an io controller view
|
||||
#define UIO_IKBD_OUT 0x02
|
||||
#define UIO_IKBD_IN 0x03
|
||||
#define UIO_SERIAL_OUT 0x04
|
||||
#define UIO_SERIAL_IN 0x05
|
||||
#define UIO_PARALLEL_IN 0x06
|
||||
#define UIO_MIDI_OUT 0x07
|
||||
#define UIO_MIDI_IN 0x08
|
||||
#define UIO_ETH_MAC 0x09
|
||||
#define UIO_ETH_STATUS 0x0a
|
||||
#define UIO_ETH_FRM_IN 0x0b
|
||||
#define UIO_ETH_FRM_OUT 0x0c
|
||||
#define UIO_SERIAL_STAT 0x0d
|
||||
// 0x08 - 0x0F - core specific
|
||||
#define ST_WRITE_MEMORY 0x08
|
||||
#define ST_READ_MEMORY 0x09
|
||||
#define ST_ACK_DMA 0x0a
|
||||
#define ST_NAK_DMA 0x0b
|
||||
#define ST_GET_DMASTATE 0x0c
|
||||
|
||||
#define UIO_JOYSTICK2 0x10 // also used by minimig and 8 bit
|
||||
#define UIO_JOYSTICK3 0x11 // -"-
|
||||
@@ -77,11 +69,6 @@
|
||||
#define UIO_INFO_GET 0x36
|
||||
#define UIO_SETWIDTH 0x37 // Set max scaled horizontal resolution
|
||||
#define UIO_SETSYNC 0x38
|
||||
#define ST_WRITE_MEMORY 0x3A
|
||||
#define ST_READ_MEMORY 0x3B
|
||||
#define ST_ACK_DMA 0x3C
|
||||
#define ST_NAK_DMA 0x3D
|
||||
#define ST_GET_DMASTATE 0x3E
|
||||
|
||||
// codes as used by 8bit for file loading from OSD
|
||||
#define UIO_FILE_TX 0x53
|
||||
@@ -160,8 +147,6 @@
|
||||
|
||||
// core type value should be unlikely to be returned by broken cores
|
||||
#define CORE_TYPE_UNKNOWN 0x55
|
||||
#define CORE_TYPE_DUMB 0xa0 // core without any io controller interaction
|
||||
#define CORE_TYPE_MIST 0xa3 // mist atari st core
|
||||
#define CORE_TYPE_8BIT 0xa4 // generic core
|
||||
#define CORE_TYPE_ARCHIE 0xa6 // Acorn Archimedes
|
||||
#define CORE_TYPE_SHARPMZ 0xa7 // Sharp MZ Series
|
||||
@@ -199,22 +184,12 @@
|
||||
#define EMU_JOY0 2
|
||||
#define EMU_JOY1 3
|
||||
|
||||
// serial status data type returned from the core
|
||||
typedef struct {
|
||||
uint32_t bitrate; // 300, 600 ... 115200
|
||||
uint8_t datasize; // 5,6,7,8 ...
|
||||
uint8_t parity;
|
||||
uint8_t stopbits;
|
||||
uint8_t fifo_stat; // space in cores input fifo
|
||||
} __attribute__((packed)) serial_status_t;
|
||||
|
||||
void user_io_init(const char *path, const char *xml);
|
||||
unsigned char user_io_core_type();
|
||||
void user_io_poll();
|
||||
char user_io_menu_button();
|
||||
char user_io_user_button();
|
||||
void user_io_osd_key_enable(char);
|
||||
void user_io_serial_tx(char *, uint16_t);
|
||||
void user_io_read_confstr();
|
||||
char *user_io_get_confstr(int index);
|
||||
uint32_t user_io_8bit_set_status(uint32_t, uint32_t, int ex = 0);
|
||||
@@ -223,8 +198,7 @@ void user_io_file_tx_write(const uint8_t *addr, uint16_t len);
|
||||
int user_io_get_width();
|
||||
|
||||
uint32_t user_io_get_file_crc();
|
||||
int user_io_file_mount(char *name, unsigned char index = 0, char pre = 0);
|
||||
char user_io_serial_status(serial_status_t *, uint8_t);
|
||||
int user_io_file_mount(const char *name, unsigned char index = 0, char pre = 0);
|
||||
char *user_io_make_filepath(const char *path, const char *filename);
|
||||
char *user_io_get_core_name();
|
||||
char *user_io_get_core_path();
|
||||
@@ -237,13 +211,6 @@ const char *get_image_name(int i);
|
||||
int user_io_get_kbdemu();
|
||||
uint32_t user_io_get_uart_mode();
|
||||
|
||||
// io controllers interface for FPGA ethernet emulation using usb ethernet
|
||||
// devices attached to the io controller (ethernec emulation)
|
||||
void user_io_eth_send_mac(uint8_t *);
|
||||
uint32_t user_io_eth_get_status(void);
|
||||
void user_io_eth_send_rx_frame(uint8_t *, uint16_t);
|
||||
void user_io_eth_receive_tx_frame(uint8_t *, uint16_t);
|
||||
|
||||
void user_io_mouse(unsigned char b, int16_t x, int16_t y, int16_t w);
|
||||
void user_io_kbd(uint16_t key, int press);
|
||||
char* user_io_create_config_name();
|
||||
|
||||
Reference in New Issue
Block a user