diff --git a/Makefile b/Makefile
index 9860708..c3f3700 100644
--- a/Makefile
+++ b/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
diff --git a/MiSTer.vcxproj b/MiSTer.vcxproj
index d3122e6..af1f2e3 100644
--- a/MiSTer.vcxproj
+++ b/MiSTer.vcxproj
@@ -88,7 +88,6 @@
-
@@ -145,7 +144,6 @@
-
diff --git a/MiSTer.vcxproj.filters b/MiSTer.vcxproj.filters
index 34b6710..42962d0 100644
--- a/MiSTer.vcxproj.filters
+++ b/MiSTer.vcxproj.filters
@@ -166,9 +166,6 @@
Source Files\support
-
- Source Files\support
-
Source Files\support
@@ -303,9 +300,6 @@
Header Files\support
-
- Header Files\support
-
Header Files\support
diff --git a/file_io.cpp b/file_io.cpp
index 3511f73..884cffa 100644
--- a/file_io.cpp
+++ b/file_io.cpp
@@ -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)
diff --git a/input.cpp b/input.cpp
index 12e028f..6ef6b05 100644
--- a/input.cpp
+++ b/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;
diff --git a/input.h b/input.h
index bb94f9c..696e22e 100644
--- a/input.h
+++ b/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();
diff --git a/menu.cpp b/menu.cpp
index e9dbcc5..62397ff 100644
--- a/menu.cpp
+++ b/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;
diff --git a/support.h b/support.h
index 553bf42..4339367 100644
--- a/support.h
+++ b/support.h
@@ -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
diff --git a/support/st/st_ikbd.cpp b/support/st/st_ikbd.cpp
deleted file mode 100644
index 8a966ec..0000000
--- a/support/st/st_ikbd.cpp
+++ /dev/null
@@ -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
-#include
-
-#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;
- }
- }
-}
diff --git a/support/st/st_ikbd.h b/support/st/st_ikbd.h
deleted file mode 100644
index 8c1391d..0000000
--- a/support/st/st_ikbd.h
+++ /dev/null
@@ -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
diff --git a/support/st/st_tos.cpp b/support/st/st_tos.cpp
index bd55179..ac8004f 100644
--- a/support/st/st_tos.cpp
+++ b/support/st/st_tos.cpp
@@ -4,14 +4,13 @@
#include "../../hardware.h"
#include "../../menu.h"
-#include "st_tos.h"
#include "../../file_io.h"
#include "../../debug.h"
#include "../../user_io.h"
-#include "st_ikbd.h"
#include "../../fpga_io.h"
+#include "st_tos.h"
-#define CONFIG_FILENAME "MIST.CFG"
+#define CONFIG_FILENAME "ATARIST0.CFG"
typedef struct {
unsigned long system_ctrl; // system control word
@@ -19,28 +18,12 @@ typedef struct {
char cart_img[1024];
char acsi_img[2][1024];
char video_adjust[2];
- char sd_direct;
+ char cdc_control_redirect;
} tos_config_t;
static tos_config_t config;
-#define TOS_BASE_ADDRESS_192k 0xfc0000
-#define TOS_BASE_ADDRESS_256k 0xe00000
-#define CART_BASE_ADDRESS 0xfa0000
-#define VIDEO_BASE_ADDRESS 0x010000
-
-static unsigned char font[2048]; // buffer for 8x16 atari font
-
- // two floppies
-static struct {
- fileTYPE file;
- unsigned char sides;
- unsigned char spt;
-} fdd_image[2] = {};
-
-// one harddisk
fileTYPE hdd_image[2] = {};
-unsigned long hdd_direct = 0;
static unsigned char dma_buffer[512];
@@ -66,179 +49,100 @@ static const char *acsi_cmd_name(int cmd) {
return cmdname[cmd];
}
-void tos_set_video_adjust(int axis, char value) {
- config.video_adjust[axis] += value;
-
- EnableFpga();
- spi8(MIST_SET_VADJ);
- spi8(config.video_adjust[0]);
- spi8(config.video_adjust[1]);
- DisableFpga();
-}
-
-char tos_get_video_adjust(int axis) {
- return config.video_adjust[axis];
-}
-
-static void mist_memory_set_address(unsigned long a, unsigned char s, char rw) {
- // printf("set addr = %x, %d, %d\n", a, s, rw);
-
- a |= rw ? 0x1000000 : 0;
- a >>= 1;
-
- EnableFpga();
- spi8(MIST_SET_ADDRESS);
- spi8(s);
- spi8((a >> 16) & 0xff);
- spi8((a >> 8) & 0xff);
- spi8((a >> 0) & 0xff);
- DisableFpga();
-}
-
-static void mist_set_control(unsigned long ctrl) {
- EnableFpga();
- spi8(MIST_SET_CONTROL);
- spi8((ctrl >> 24) & 0xff);
- spi8((ctrl >> 16) & 0xff);
- spi8((ctrl >> 8) & 0xff);
- spi8((ctrl >> 0) & 0xff);
- DisableFpga();
-}
-
/*
-static void mist_memory_read(char *data, unsigned long words) {
- EnableFpga();
- spi8(MIST_READ_MEMORY);
+int tos_get_cdc_control_redirect(void)
+{
+ return config.cdc_control_redirect;
+}
- // transmitted bytes must be multiple of 2 (-> words)
- while (words--) {
- *data++ = spi_in();
- *data++ = spi_in();
+void tos_set_cdc_control_redirect(char mode)
+{
+ if (mode <= CDC_REDIRECT_MIDI)
+ {
+ config.cdc_control_redirect = mode;
+
+ // core is only informed about redirections of rs232/par/midi
+ if (mode < CDC_REDIRECT_RS232)
+ mode = 0;
+ else
+ mode -= CDC_REDIRECT_RS232 - 1;
+
+ tos_update_sysctrl((tos_system_ctrl() & ~0x0c000000) |
+ (((unsigned long)mode) << 26));
}
-
- DisableFpga();
}
*/
-static void mist_memory_write(unsigned char *data, unsigned long words) {
- EnableFpga();
- spi8(MIST_WRITE_MEMORY);
+static void mist_set_control(uint32_t ctrl)
+{
+ spi_uio_cmd_cont(UIO_SET_STATUS2);
+ spi32w(ctrl);
+ DisableIO();
+}
- while (words--) {
- spi8(*data++);
- spi8(*data++);
- }
+static void mist_memory_read(unsigned char *data, unsigned long words)
+{
+ EnableFpga();
+ spi8(ST_READ_MEMORY);
+
+ // transmitted bytes must be multiple of 2 (-> words)
+ uint16_t *buf = (uint16_t*)data;
+ while (words--) *buf++ = spi_w(0);
DisableFpga();
}
-static void mist_memory_read_block(unsigned char *data) {
+static void mist_memory_write(unsigned char *data, unsigned long words)
+{
EnableFpga();
- spi8(MIST_READ_MEMORY);
+ spi8(ST_WRITE_MEMORY);
- spi_block_read(data,0);
+ uint16_t *buf = (uint16_t*)data;
+ while (words--) spi_w(*buf++);
DisableFpga();
}
-static void mist_memory_write_block(unsigned char *data) {
+static void dma_ack(unsigned char status)
+{
EnableFpga();
- spi8(MIST_WRITE_MEMORY);
-
- spi_block_write(data,0);
-
- DisableFpga();
-}
-
-void mist_memory_set(char data, unsigned long words) {
- EnableFpga();
- spi8(MIST_WRITE_MEMORY);
-
- while (words--) {
- spi8(data);
- spi8(data);
- }
-
- DisableFpga();
-}
-
-// enable direct sd card access on acsi0
-void tos_set_direct_hdd(char on) {
- (void)on;
- config.sd_direct = 0;
-
- tos_debugf("ACSI: disable direct sd access");
- config.system_ctrl &= ~TOS_ACSI0_ENABLE;
- hdd_direct = 0;
-
- // check if image access should be enabled instead
- if (hdd_image[0].size) {
- tos_debugf("ACSI: re-enabling image on ACSI0");
- config.system_ctrl |= TOS_ACSI0_ENABLE;
- }
-
- mist_set_control(config.system_ctrl);
-}
-
-char tos_get_direct_hdd() {
- return 0;
-}
-
-static void dma_ack(unsigned char status) {
- EnableFpga();
- spi8(MIST_ACK_DMA);
+ spi8(ST_ACK_DMA);
spi8(status);
DisableFpga();
}
-static void dma_nak(void) {
+static void dma_nak(void)
+{
EnableFpga();
- spi8(MIST_NAK_DMA);
+ spi8(ST_NAK_DMA);
DisableFpga();
}
-static char user_io_dip_switch1()
+static void handle_acsi(unsigned char *buffer)
{
- return 0;
-}
+ static uint8_t buf[65536];
-static void handle_acsi(unsigned char *buffer) {
static unsigned char asc[2] = { 0,0 };
- unsigned char target = buffer[19] >> 5;
- unsigned char device = buffer[10] >> 5;
- unsigned char cmd = buffer[9];
- unsigned int dma_address = 256 * 256 * buffer[0] +
- 256 * buffer[1] + (buffer[2] & 0xfe);
- unsigned char scnt = buffer[3];
- unsigned long lba = 256 * 256 * (buffer[10] & 0x1f) +
- 256 * buffer[11] + buffer[12];
- unsigned short length = buffer[13];
+ unsigned char target = buffer[10] >> 5;
+ unsigned char device = buffer[1] >> 5;
+ unsigned char cmd = buffer[0];
+ unsigned long lba = 256 * 256 * (buffer[1] & 0x1f) +
+ 256 * buffer[2] + buffer[3];
+ unsigned short length = buffer[4];
if (length == 0) length = 256;
- if (user_io_dip_switch1()) {
- tos_debugf("ACSI: target %u.%u, \"%s\" (%02x)", target, device, acsi_cmd_name(cmd), cmd);
+ if (0)
+ {
+ tos_debugf("ACSI: target %d.%d, \"%s\" (%02x)", target, device, acsi_cmd_name(cmd), cmd);
tos_debugf("ACSI: lba %lu (%lx), length %u", lba, lba, length);
- tos_debugf("DMA: scnt %u, addr %X", scnt, dma_address);
-
- if (buffer[20] == 0xa5) {
- tos_debugf("DMA: fifo %u/%u %x %s",
- (buffer[21] >> 4) & 0x0f, buffer[21] & 0x0f,
- buffer[22], (buffer[2] & 1) ? "OUT" : "IN");
- tos_debugf("DMA stat=%x, mode=%x, fdc_irq=%d, acsi_irq=%d",
- buffer[23], buffer[24], buffer[25], buffer[26]);
- }
}
// only a harddisk on ACSI 0/1 is supported
// ACSI 0/1 is only supported if a image is loaded
- // ACSI 0 is only supported for direct IO
- if (((target < 2) && (hdd_image[target].size != 0)) ||
- ((target == 0) && hdd_direct)) {
+ if (((target < 2) && (hdd_image[target].size != 0)))
+ {
unsigned long blocks = hdd_image[target].size / 512;
- // if in hdd direct mode then hdd_direct contains device sizee
- if (hdd_direct && target == 0) blocks = hdd_direct;
-
// only lun0 is fully supported
switch (cmd) {
case 0x25:
@@ -290,39 +194,48 @@ static void handle_acsi(unsigned char *buffer) {
case 0x08: // read sector
case 0x28: // read (10)
- if (device == 0) {
- if (cmd == 0x28) {
+ if (device == 0)
+ {
+ if (cmd == 0x28)
+ {
lba =
- 256 * 256 * 256 * buffer[11] +
- 256 * 256 * buffer[12] +
- 256 * buffer[13] +
- buffer[14];
+ 256 * 256 * 256 * buffer[2] +
+ 256 * 256 * buffer[3] +
+ 256 * buffer[4] +
+ buffer[5];
- length = 256 * buffer[16] + buffer[17];
- // printf("READ(10) %d, %d\n", lba, length);
+ length = 256 * buffer[7] + buffer[8];
+ // iprintf("READ(10) %d, %d\n", lba, length);
}
- if (lba + length <= blocks) {
+ if (lba + length <= blocks)
+ {
DISKLED_ON;
- while (length) {
- FileSeekLBA(&hdd_image[target], lba++);
- FileReadSec(&hdd_image[target], dma_buffer);
- // hexdump(dma_buffer, 32, 0);
- mist_memory_write_block(dma_buffer);
- length--;
+ FileSeekLBA(&hdd_image[target], lba);
+ while (length)
+ {
+ uint32_t len = length;
+ if (len > 128) len = 128;
+ length -= len;
+
+ len *= 512;
+ FileReadAdv(&hdd_image[target], buf, len);
+ mist_memory_write(buf, len / 2);
}
DISKLED_OFF;
+
dma_ack(0x00);
asc[target] = 0x00;
}
- else {
- tos_debugf("ACSI: read (%lu+%u) exceeds device limits (%lu)",
- lba, length, blocks);
+ else
+ {
+ tos_debugf("ACSI: read (%lu+%d) exceeds device limits (%lu)", lba, length, blocks);
dma_ack(0x02);
asc[target] = 0x21;
}
}
- else {
+ else
+ {
dma_ack(0x02);
asc[target] = 0x25;
}
@@ -330,33 +243,41 @@ static void handle_acsi(unsigned char *buffer) {
case 0x0a: // write sector
case 0x2a: // write (10)
- if (device == 0) {
- if (cmd == 0x2a) {
+ if (device == 0)
+ {
+ if (cmd == 0x2a)
+ {
lba =
- 256 * 256 * 256 * buffer[11] +
- 256 * 256 * buffer[12] +
- 256 * buffer[13] +
- buffer[14];
+ 256 * 256 * 256 * buffer[2] +
+ 256 * 256 * buffer[3] +
+ 256 * buffer[4] +
+ buffer[5];
- length = 256 * buffer[16] + buffer[17];
+ length = 256 * buffer[7] + buffer[8];
- // printf("WRITE(10) %d, %d\n", lba, length);
+ // iprintf("WRITE(10) %d, %d\n", lba, length);
}
- if (lba + length <= blocks) {
+ if (lba + length <= blocks)
+ {
DISKLED_ON;
- while (length) {
- mist_memory_read_block(dma_buffer);
- FileSeekLBA(&hdd_image[target], lba++);
- FileWriteSec(&hdd_image[target], dma_buffer);
- length--;
+ FileSeekLBA(&hdd_image[target], lba);
+ while (length)
+ {
+ uint32_t len = length;
+ if (len > 128) len = 128;
+ length -= len;
+
+ len *= 512;
+ mist_memory_read(buf, len / 2);
+ FileWriteAdv(&hdd_image[target], buf, len);
}
DISKLED_OFF;
dma_ack(0x00);
asc[target] = 0x00;
}
else {
- tos_debugf("ACSI: write (%lu+%u) exceeds device limits (%lu)",
+ tos_debugf("ACSI: write (%lu+%d) exceeds device limits (%lu)",
lba, length, blocks);
dma_ack(0x02);
asc[target] = 0x21;
@@ -369,17 +290,15 @@ static void handle_acsi(unsigned char *buffer) {
break;
case 0x12: // inquiry
- if (hdd_direct && target == 0) tos_debugf("ACSI: Inquiry DIRECT");
- else tos_debugf("ACSI: Inquiry %s", hdd_image[target].name);
+ tos_debugf("ACSI: Inquiry %.11s", hdd_image[target].name);
bzero(dma_buffer, 512);
dma_buffer[2] = 2; // SCSI-2
- dma_buffer[4] = length - 5; // len
- memcpy(dma_buffer + 8, "MIST ", 8); // Vendor
- memcpy(dma_buffer + 16, " ", 16); // Clear device entry
- if (hdd_direct && target == 0) memcpy(dma_buffer + 16, "SD DIRECT", 9);// Device
- else memcpy(dma_buffer + 16, hdd_image[target].name, 11);
- memcpy(dma_buffer + 32, "ATH ", 4); // Product revision
- memcpy(dma_buffer + 36, VDATE " ", 8); // Serial number
+ dma_buffer[4] = length - 5; // len
+ memcpy(dma_buffer + 8, "MISTer ", 8); // Vendor
+ memcpy(dma_buffer + 16, " ", 16); // Clear device entry
+ memcpy(dma_buffer + 16, hdd_image[target].name, 11); // Device
+ memcpy(dma_buffer + 32, "ATH ", 4); // Product revision
+ memcpy(dma_buffer + 36, VDATE " ", 8); // Serial number
if (device != 0) dma_buffer[0] = 0x7f;
mist_memory_write(dma_buffer, length / 2);
dma_ack(0x00);
@@ -408,7 +327,7 @@ static void handle_acsi(unsigned char *buffer) {
#if 0
case 0x1f: // ICD command?
tos_debugf("ACSI: ICD command %s ($%02x)",
- acsi_cmd_name(buffer[10] & 0x1f), buffer[10] & 0x1f);
+ acsi_cmd_name(buffer[1] & 0x1f), buffer[1] & 0x1f);
asc[target] = 0x05;
dma_ack(0x02);
break;
@@ -430,264 +349,42 @@ static void handle_acsi(unsigned char *buffer) {
}
}
-static void handle_fdc(unsigned char *buffer) {
- // extract contents
- unsigned int dma_address = 256 * 256 * buffer[0] +
- 256 * buffer[1] + (buffer[2] & 0xfe);
- unsigned char scnt = buffer[3];
- unsigned char fdc_cmd = buffer[4];
- unsigned char fdc_track = buffer[5];
- unsigned char fdc_sector = buffer[6];
- //unsigned char fdc_data = buffer[7];
- unsigned char drv_sel = 3 - ((buffer[8] >> 2) & 3);
- unsigned char drv_side = 1 - ((buffer[8] >> 1) & 1);
-
- // tos_debugf("FDC: sel %d, cmd %x", drv_sel, fdc_cmd);
-
- // check if a matching disk image has been inserted
- if (drv_sel && fdd_image[drv_sel - 1].file.size) {
- // if the fdc has been asked to write protect the disks, then
- // write sector commands should never reach the oi controller
-
- // read/write sector command
- if ((fdc_cmd & 0xc0) == 0x80) {
- // convert track/sector/side into disk offset
- unsigned int offset = drv_side;
- offset += fdc_track * fdd_image[drv_sel - 1].sides;
- offset *= fdd_image[drv_sel - 1].spt;
- offset += fdc_sector - 1;
-
- if (user_io_dip_switch1()) {
- tos_debugf("FDC %s req %d sec (%c, SD:%d, T:%d, S:%d = %d) -> %X",
- (fdc_cmd & 0x10) ? "multi" : "single", scnt,
- 'A' + drv_sel - 1, drv_side, fdc_track, fdc_sector, offset,
- dma_address);
- }
-
- while (scnt) {
- // check if requested sector is in range
- if ((fdc_sector > 0) && (fdc_sector <= fdd_image[drv_sel - 1].spt)) {
-
- DISKLED_ON;
-
- FileSeek(&fdd_image[drv_sel - 1].file, offset, SEEK_SET);
-
- if ((fdc_cmd & 0xe0) == 0x80) {
- // read from disk ...
- FileReadSec(&fdd_image[drv_sel - 1].file, dma_buffer);
- // ... and copy to ram
- mist_memory_write_block(dma_buffer);
- }
- else {
- // read from ram ...
- mist_memory_read_block(dma_buffer);
- // ... and write to disk
- FileWriteSec(&(fdd_image[drv_sel - 1].file), dma_buffer);
- }
-
- DISKLED_OFF;
- }
- else
- tos_debugf("sector out of range");
-
- scnt--;
- dma_address += 512;
- offset += 1;
- }
- dma_ack(0x00);
- }
- else if ((fdc_cmd & 0xc0) == 0xc0) {
- char msg[32];
-
- if ((fdc_cmd & 0xe0) == 0xc0) printf("READ ADDRESS\n");
-
- if ((fdc_cmd & 0xf0) == 0xe0) {
- printf("READ TRACK %d SIDE %d\n", fdc_track, drv_side);
- sprintf(msg, "RD TRK %d S %d", fdc_track, drv_side);
- InfoMessage(msg);
- }
-
- if ((fdc_cmd & 0xf0) == 0xf0) {
- printf("WRITE TRACK %d SIDE %d\n", fdc_track, drv_side);
- sprintf(msg, "WR TRK %d S %d", fdc_track, drv_side);
- InfoMessage(msg);
- }
-
- printf("scnt = %d\n", scnt);
-
- dma_ack(0x00);
- }
- }
-}
-
-static void mist_get_dmastate() {
- unsigned char buffer[32];
+static void mist_get_dmastate()
+{
+ unsigned char buffer[16];
EnableFpga();
- spi8(MIST_GET_DMASTATE);
- spi_read(buffer, 32,0);
+ spi8(ST_GET_DMASTATE);
+ spi_read(buffer, 16, 0);
DisableFpga();
- // check if acsi is busy
- if (buffer[19] & 0x01)
- handle_acsi(buffer);
-
- // check if fdc is busy
- if (buffer[8] & 0x01)
- handle_fdc(buffer);
+ if (buffer[10] & 0x01) handle_acsi(buffer);
}
-// color test, used to test the shifter without CPU/TOS
-#define COLORS 20
-#define PLANES 4
+static void fill_tx(unsigned char fill, unsigned int len, unsigned char index)
+{
+ user_io_set_index(index);
+ user_io_set_download(1);
-static void tos_write(const char *str);
-/*
-static void tos_color_test() {
- unsigned short buffer[COLORS][PLANES];
+ uint16_t wfill = (fill << 8) | fill;
- int y;
- for (y = 0; y<13; y++) {
- int i, j;
- for (i = 0; i> n;
-
- *(d + 1) = *d;
- }
- }
+ user_io_set_download(0);
}
void tos_load_cartridge(const char *name)
{
- fileTYPE file = {};
-
- if (name)
- strncpy(config.cart_img, name, 11);
+ if (name) strncpy(config.cart_img, name, 11);
// upload cartridge
- if (config.cart_img[0] && FileOpen(&file, config.cart_img)) {
- int i;
- unsigned char buffer[512];
-
- tos_debugf("%s:\n size = %llu", config.cart_img, file.size);
-
- int blocks = file.size / 512;
- tos_debugf(" blocks = %d", blocks);
-
-
- DISKLED_ON;
- for (i = 0; i= 256 * 1024)
- tos_base = TOS_BASE_ADDRESS_256k;
- else if (file.size != 192 * 1024)
- tos_debugf("WARNING: Unexpected TOS size!");
-
- int blocks = file.size / 512;
- tos_debugf(" blocks = %d", blocks);
-
- tos_debugf(" address = $%08lx", tos_base);
-
- // clear first 16k
- mist_memory_set_address(0, 16384 / 512, 0);
- mist_memory_set(0x00, 8192);
-
- time = GetTimer(0);
- tos_debugf("Uploading ...");
-
- for (i = 0; i= 0) {
- printf("Failed in block %d/%x (%x != %x)\n", i, ok, 0xff & buffer[ok], 0xff & b2[ok]);
-
- hexdump(buffer, 512, 0);
- puts("");
- hexdump(b2, 512, 0);
-
- // re-read to check whether read or write failed
- bzero(buffer, 512);
- mist_memory_set_address(tos_base + i * 512, 1, 1);
- mist_memory_read_block(buffer);
-
- ok = -1;
- for (j = 0; j<512; j++)
- if (buffer[j] != b2[j])
- if (ok < 0)
- ok = j;
-
- if (ok >= 0) {
- printf("Re-read failed in block %d/%x (%x != %x)\n", i, ok, 0xff & buffer[ok], 0xff & b2[ok]);
- hexdump(buffer, 512, 0);
- }
- else
- printf("Re-read ok!\n");
-
- for (;;);
- }
- }
- printf("Verify: %s\n", ok ? "ok" : "failed");
- }
-#endif
-
- time = GetTimer(0) - time;
- tos_debugf("TOS.IMG uploaded in %lu ms (%llu kB/s / %llu kBit/s)",
- time >> 20, file.size / (time >> 20), 8 * file.size / (time >> 20));
-
- FileClose(&file);
-
- }
- else {
- tos_debugf("Unable to find tos.img");
- tos_write("Unable to find tos.img");
-
- DISKLED_OFF;
- return;
- }
-
- DISKLED_OFF;
-
- // This is the initial boot if no name was given. Otherwise the
- // user reloaded a new os
- if (!name) {
- // load
- tos_load_cartridge(NULL);
-
- // try to open both floppies
- int i;
- for (i = 0; i<2; i++) {
- //char msg[] = "Found floppy disk image for drive X: ";
- char name[] = "DISK_A.ST";
- //msg[34] = name[5] = 'A' + i;
-
- tos_insert_disk(i, name);
- }
-
- if (config.sd_direct) {
- tos_set_direct_hdd(1);
- tos_write("Enabling direct SD card access via ACSI0");
- }
- else {
- // try to open harddisk image
- for (i = 0; i<2; i++) {
- if (FileOpen(&file, config.acsi_img[i]))
- {
- FileClose(&file);
- char msg[] = "Found hard disk image for ACSIX";
- msg[30] = '0' + i;
- tos_write(msg);
- tos_select_hdd_image(i, config.acsi_img[i]);
- }
- }
- }
- }
-
- tos_write("Booting ... ");
-
- // clear sector count register -> stop DMA
- mist_memory_set_address(0, 0, 0);
-
- ikbd_reset();
-
- // let cpu run (release reset)
- config.system_ctrl &= ~TOS_CONTROL_CPU_RESET;
- mist_set_control(config.system_ctrl);
-}
-
-/*
-static unsigned long get_long(char *buffer, int offset) {
- unsigned long retval = 0;
- int i;
-
- for (i = 0; i<4; i++)
- retval = (retval << 8) + *(unsigned char*)(buffer + offset + i);
-
- return retval;
-}
-*/
-
-void tos_poll() {
- // 1 == button not pressed, 2 = 1 sec exceeded, else timer running
- static unsigned long timer = 1;
+ static unsigned long timer = 0;
mist_get_dmastate();
// check the user button
- if (user_io_user_button()) {
- if (timer == 1)
- timer = GetTimer(1000);
- else if (timer != 2)
- if (CheckTimer(timer)) {
+ if (!user_io_osd_is_visible() && user_io_user_button())
+ {
+ if (!timer) timer = GetTimer(1000);
+ else if (timer != 1)
+ {
+ if (CheckTimer(timer))
+ {
tos_reset(1);
- timer = 2;
+ timer = 1;
}
+ }
}
- else {
- // released while still running (< 1 sec)
- if (!(timer & 3))
- tos_reset(0);
-
- timer = 1;
- }
-}
-
-void tos_update_sysctrl(unsigned long n) {
- // printf(">>>>>>>>>>>> set sys %x, eth is %s\n", n, (n&TOS_CONTROL_ETHERNET)?"on":"off");
-
- // some of the usb drivers also call this without knowing which
- // core is running. So make sure this only happens if the Atari ST (MIST)
- // core is running
- if (user_io_core_type() == CORE_TYPE_MIST) {
- config.system_ctrl = n;
- mist_set_control(config.system_ctrl);
- }
-}
-
-static void nice_name(char *dest, char *src) {
- char *c;
-
- // copy and append nul
- strncpy(dest, src, 8);
- for (c = dest + 7; *c == ' '; c--); c++;
- *c++ = '.';
- strncpy(c, src + 8, 3);
- for (c += 2; *c == ' '; c--); c++;
- *c++ = '\0';
-}
-
-static char buffer[17]; // local buffer to assemble file name (8+3+2)
-
-char *tos_get_disk_name(int index) {
- fileTYPE file;
-
- if (index <= 1)
- file = fdd_image[index].file;
else
- file = hdd_image[index - 2];
+ {
+ timer = 0;
+ }
+}
- if (!file.size) {
- strcpy(buffer, "* no disk *");
- return buffer;
+void tos_update_sysctrl(unsigned long n)
+{
+ config.system_ctrl = n;
+ mist_set_control(config.system_ctrl);
+}
+
+const char *tos_get_disk_name(int index)
+{
+ const char *name = 0;
+ if(index <= 1) name = get_image_name(index);
+ else
+ {
+ if (!hdd_image[index & 1].size) name = 0;
+ else
+ {
+ name = strrchr(hdd_image[index & 1].name, '/');
+ if (!name) name = hdd_image[index & 1].name; else name++;
+ }
}
- nice_name(buffer, file.name);
-
- return buffer;
+ return name ? name : "* no disk *";
}
-char *tos_get_image_name() {
- nice_name(buffer, config.tos_img);
- return buffer;
+const char *tos_get_image_name()
+{
+ char *p = strrchr(config.tos_img, '/');
+ return p ? p+1 : config.tos_img;
}
-char *tos_get_cartridge_name() {
- if (!config.cart_img[0]) // no cart name set
- strcpy(buffer, "* no cartridge *");
- else
- nice_name(buffer, config.cart_img);
-
- return buffer;
+const char *tos_get_cartridge_name()
+{
+ if (!config.cart_img[0]) return "* no cartridge *";
+ char *p = strrchr(config.cart_img, '/');
+ return p ? p + 1 : config.cart_img;
}
-char tos_disk_is_inserted(int index) {
- if (index <= 1)
- return (fdd_image[index].file.size != 0);
-
- return hdd_image[index - 2].size != 0;
+char tos_disk_is_inserted(int index)
+{
+ if (index <= 1) return (get_image_name(index) != NULL);
+ return hdd_image[index & 1].size != 0;
}
-void tos_select_hdd_image(int i, const char *name)
+static void tos_select_hdd_image(int i, const char *name)
{
tos_debugf("Select ACSI%c image %s", '0' + i, name);
- if(name) strcpy(config.acsi_img[i], name);
- else config.acsi_img[i][0] = 0;
-
- if (!name)
+ strcpy(config.acsi_img[i], name);
+ if (!strlen(name))
{
FileClose(&hdd_image[i]);
hdd_image[i].size = 0;
@@ -1022,106 +490,16 @@ void tos_select_hdd_image(int i, const char *name)
mist_set_control(config.system_ctrl);
}
-void tos_insert_disk(int i, const char *name)
+void tos_insert_disk(int index, const char *name)
{
- if (i > 1)
- {
- tos_select_hdd_image(i - 2, name);
- return;
- }
-
- tos_debugf("%c: eject", i + 'A');
-
- // toggle write protect bit to help tos detect a media change
- int wp_bit = (!i) ? TOS_CONTROL_FDC_WR_PROT_A : TOS_CONTROL_FDC_WR_PROT_B;
-
- // any disk ejected is "write protected" (as nothing covers the write protect mechanism)
- mist_set_control(config.system_ctrl | wp_bit);
-
- // first "eject" disk
- fdd_image[i].file.size = 0;
- fdd_image[i].sides = 1;
- fdd_image[i].spt = 0;
- FileClose(&fdd_image[i].file);
-
- // no new disk given?
- if (!name) return;
-
- // open floppy
- if (!FileOpen(&fdd_image[i].file, name)) return;
-
- tos_debugf("%c: insert %s", i + 'A', name);
-
- // check image size and parameters
-
- // check if image size suggests it's a two sided disk
- if (fdd_image[i].file.size > 85 * 11 * 512)
- fdd_image[i].sides = 2;
-
- // try common sector/track values
- int m, s, t;
- for (m = 0; m <= 2; m++) // multiplier for hd/ed disks
- for (s = 9; s <= 12; s++)
- for (t = 78; t <= 85; t++)
- if (512 * (1 << m)*s*t*fdd_image[i].sides == fdd_image[i].file.size)
- fdd_image[i].spt = s*(1 << m);
-
-
-
- if (!fdd_image[i].spt) {
- // read first sector from disk
- /*
- if (MMC_Read(0, dma_buffer)) {
- fdd_image[i].spt = dma_buffer[24] + 256 * dma_buffer[25];
- fdd_image[i].sides = dma_buffer[26] + 256 * dma_buffer[27];
- }
- else
- */
- fdd_image[i].file.size = 0;
- }
-
- if (fdd_image[i].file.size) {
- // restore state of write protect bit
- tos_update_sysctrl(config.system_ctrl);
- tos_debugf("%c: detected %d sides with %d sectors per track",
- i + 'A', fdd_image[i].sides, fdd_image[i].spt);
- }
+ if (index <= 1) user_io_file_mount(name, index);
+ else tos_select_hdd_image(index & 1, name);
}
// force ejection of all disks (SD card has been removed)
-void tos_eject_all() {
- int i;
- for (i = 0; i<2; i++)
- tos_insert_disk(i, NULL);
-
- // ejecting an SD card while a hdd image is mounted may be a bad idea
- for (i = 0; i<2; i++) {
- if (hdd_direct)
- hdd_direct = 0;
-
- if (hdd_image[i].size) {
- InfoMessage("Card removed:\nDisabling Harddisk!");
- hdd_image[i].size = 0;
- }
- }
-}
-
-void tos_reset(char cold) {
- ikbd_reset();
-
- tos_update_sysctrl(config.system_ctrl | TOS_CONTROL_CPU_RESET); // set reset
-
- if (cold) {
-#if 0 // clearing mem should be sifficient. But currently we upload TOS as it may be damaged
- // clear first 16k
- mist_memory_set_address(8);
- mist_memory_set(0x00, 8192 - 4);
-#else
- tos_upload(NULL);
-#endif
- }
-
- tos_update_sysctrl(config.system_ctrl & ~TOS_CONTROL_CPU_RESET); // release reset
+void tos_eject_all()
+{
+ for (int i = 0; i < 4; i++) tos_insert_disk(i, "");
}
unsigned long tos_system_ctrl(void)
@@ -1129,33 +507,96 @@ unsigned long tos_system_ctrl(void)
return config.system_ctrl;
}
-void tos_config_init(void)
+static void tos_upload_mist2()
{
- // set default values
- config.system_ctrl = TOS_MEMCONFIG_4M | TOS_CONTROL_BLITTER;
- strcpy(config.tos_img, "TOS.IMG");
- config.cart_img[0] = 0;
- strcpy(config.acsi_img[0], "HARDDISK.HD");
- config.acsi_img[1][0] = 0;
- config.video_adjust[0] = config.video_adjust[1] = 0;
+ // clear first 16k
+ tos_debugf("Clear first 16k");
+ fill_tx(0, 16 * 1024, 0x03);
- // try to load config
- int size = FileLoadConfig(CONFIG_FILENAME, 0, 0);
- if (size>0)
+ // upload and verify tos image
+ int len = FileLoad(config.tos_img, 0, 0);
+ if (len)
{
- tos_debugf("Configuration file size: %u (should be %u)", size, sizeof(tos_config_t));
- if (size == sizeof(tos_config_t))
+ tos_debugf("TOS.IMG:\n size = %d", len);
+
+ if (len >= 256 * 1024) user_io_file_tx(config.tos_img, 0);
+ else if (len == 192 * 1024) user_io_file_tx(config.tos_img, 0x01);
+ else tos_debugf("WARNING: Unexpected TOS size!");
+ }
+ else
+ {
+ tos_debugf("Unable to find tos.img");
+ return;
+ }
+
+ tos_load_cartridge(NULL);
+
+ for (int i = 0; i < 2; i++)
+ {
+ if (FileExists(config.acsi_img[i]))
{
- FileLoadConfig(CONFIG_FILENAME, &config, size);
+ tos_select_hdd_image(i, config.acsi_img[i]);
}
}
+}
+
+void tos_reset(char cold)
+{
+ tos_update_sysctrl(config.system_ctrl | TOS_CONTROL_CPU_RESET); // set reset
+ if (cold) tos_upload_mist2();
+ tos_update_sysctrl(config.system_ctrl & ~TOS_CONTROL_CPU_RESET); // release reset
+}
+
+void tos_upload(const char *name)
+{
+ if(name) strcpy(config.tos_img, name);
+ tos_reset(1);
+}
+
+// load/init configuration
+void tos_config_load(int slot)
+{
+ char name[64] = { CONFIG_FILENAME };
+
+ static char last_slot = 0;
+ char new_slot;
+
+ tos_eject_all();
+
+ new_slot = (slot == -1) ? last_slot : slot;
+
+ // set default values
+ config.system_ctrl = TOS_MEMCONFIG_4M | TOS_CONTROL_BLITTER | TOS_CONTROL_VIDEO_COLOR;
+ strcpy(config.tos_img, user_io_get_core_path());
+ strcat(config.tos_img, "/TOS.IMG");
+ config.cart_img[0] = 0;
+ strcpy(config.acsi_img[0], "HARDDISK.VHD");
+ config.acsi_img[1][0] = 0;
+ config.video_adjust[0] = config.video_adjust[1] = 0;
+ config.cdc_control_redirect = 0;
+
+ // try to load config
+ name[7] = '0' + new_slot;
+ int len = FileLoadConfig(name, 0, 0);
+ tos_debugf("Configuration file size: %d (should be %d)", len, sizeof(tos_config_t));
+ if (len == sizeof(tos_config_t)) FileLoadConfig(name, &config, sizeof(tos_config_t));
// ethernet is auto detected later
config.system_ctrl &= ~TOS_CONTROL_ETHERNET;
}
// save configuration
-void tos_config_save(void)
+void tos_config_save(int slot)
{
- FileSaveConfig(CONFIG_FILENAME, &config, sizeof(tos_config_t));
+ char name[64] = { CONFIG_FILENAME };
+ name[7] = '0' + slot;
+ FileSaveConfig(name, &config, sizeof(config));
+}
+
+// configuration file check
+int tos_config_exists(int slot)
+{
+ char name[64] = { CONFIG_FILENAME };
+ name[7] = '0' + slot;
+ return FileLoadConfig(name, 0, 0);
}
diff --git a/support/st/st_tos.h b/support/st/st_tos.h
index 89e4357..d6c9a7b 100644
--- a/support/st/st_tos.h
+++ b/support/st/st_tos.h
@@ -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
diff --git a/user_io.cpp b/user_io.cpp
index 0488e6a..c616db4 100644
--- a/user_io.cpp
+++ b/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 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;
diff --git a/user_io.h b/user_io.h
index 9021408..07bc2ae 100644
--- a/user_io.h
+++ b/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();