Initial support for Atari ST.

This commit is contained in:
sorgelig
2020-04-17 23:44:05 +08:00
parent 07d965102d
commit 4e96473a1a
14 changed files with 767 additions and 2359 deletions

View File

@@ -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

View File

@@ -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" />

View File

@@ -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>

View File

@@ -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
View File

@@ -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;

View File

@@ -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
View File

@@ -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;

View File

@@ -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

View File

@@ -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;
}
}
}

View File

@@ -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

View File

@@ -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

View File

@@ -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;

View File

@@ -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();