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