diff --git a/MiSTer.vcxproj b/MiSTer.vcxproj index 61ec713..46bb6d8 100644 --- a/MiSTer.vcxproj +++ b/MiSTer.vcxproj @@ -57,6 +57,7 @@ + @@ -78,7 +79,6 @@ - @@ -86,6 +86,7 @@ + diff --git a/MiSTer.vcxproj.filters b/MiSTer.vcxproj.filters index f2d1745..a5a7241 100644 --- a/MiSTer.vcxproj.filters +++ b/MiSTer.vcxproj.filters @@ -65,6 +65,9 @@ Source Files + + Source Files + @@ -121,9 +124,6 @@ Header Files - - Header Files - Header Files @@ -148,6 +148,9 @@ Header Files + + Header Files + diff --git a/file_io.c b/file_io.c index f2631a3..4f52d7b 100644 --- a/file_io.c +++ b/file_io.c @@ -478,7 +478,7 @@ int de_cmp(const void *e1, const void *e2) const struct dirent *de2 = e2; if ((de1->d_type == DT_DIR) && !strcmp(de1->d_name, "..")) return -1; - if ((de2->d_type == DT_DIR) && !strcmp(de1->d_name, "..")) return 1; + if ((de2->d_type == DT_DIR) && !strcmp(de2->d_name, "..")) return 1; if ((de1->d_type == DT_DIR) && (de2->d_type == DT_REG)) return -1; if ((de1->d_type == DT_REG) && (de2->d_type == DT_DIR)) return 1; @@ -723,7 +723,7 @@ int ScanDirectory(char* path, int mode, char *extension, int options) if (found >= 0) { iSelectedEntry = found; - if (iSelectedEntry + (OsdGetSize() / 2) - 1 >= nDirEntries) iFirstEntry = nDirEntries - OsdGetSize(); + if (iSelectedEntry + (OsdGetSize() / 2) >= nDirEntries) iFirstEntry = nDirEntries - OsdGetSize(); else iFirstEntry = iSelectedEntry - (OsdGetSize()/2) + 1; if (iFirstEntry < 0) iFirstEntry = 0; } diff --git a/file_io.h b/file_io.h index 6020fd2..3949f99 100644 --- a/file_io.h +++ b/file_io.h @@ -29,7 +29,8 @@ extern int iFirstEntry; #define SCAN_SET_ITEM 3 // find exact item // options flags -#define SCAN_DIR 1 // include subdirectories +#define SCAN_DIR 1 // include subdirectories +#define SCAN_UMOUNT 2 // include subdirectories void FindStorage(); int getStorage(int from_setting); diff --git a/input.c b/input.c index c0aebb9..aaff9c8 100644 --- a/input.c +++ b/input.c @@ -1,6 +1,5 @@ #include #include -#include #include #include #include @@ -18,129 +17,97 @@ #define NUMDEV 10 -typedef struct -{ - uint16_t vid, pid; - char led; - char last_l, last_r, last_u, last_d; - - char has_map; - uint32_t map[32]; - - char has_mmap; - uint32_t mmap[32]; - - char has_kbdmap; - uint8_t kbdmap[256]; -} devInput; - -static devInput input[NUMDEV] = {0}; -static int first_joystick = -1; - -#define FN 0x10000 - -#define LCTRL 0x0100 -#define LSHIFT 0x0200 -#define LALT 0x0400 -#define LGUI 0x0800 -#define RCTRL 0x1000 -#define RSHIFT 0x2000 -#define RALT 0x4000 -#define RGUI 0x8000 -#define MODMASK 0xFF00 -#define NONE 0 - -static int ev2usb[] = +static int ev2amiga[] = { NONE, //0 KEY_RESERVED - 0x29, //1 KEY_ESC - 0x1e, //2 KEY_1 - 0x1f, //3 KEY_2 - 0x20, //4 KEY_3 - 0x21, //5 KEY_4 - 0x22, //6 KEY_5 - 0x23, //7 KEY_6 - 0x24, //8 KEY_7 - 0x25, //9 KEY_8 - 0x26, //10 KEY_9 - 0x27, //11 KEY_0 - 0x2D, //12 KEY_MINUS - 0x2E, //13 KEY_EQUAL - 0x2A, //14 KEY_BACKSPACE - 0x2B, //15 KEY_TAB - 0x14, //16 KEY_Q - 0x1a, //17 KEY_W - 0x08, //18 KEY_E - 0x15, //19 KEY_R - 0x17, //20 KEY_T - 0x1c, //21 KEY_Y - 0x18, //22 KEY_U - 0x0c, //23 KEY_I - 0x12, //24 KEY_O - 0x13, //25 KEY_P - 0x2F, //26 KEY_LEFTBRACE - 0x30, //27 KEY_RIGHTBRACE - 0x28, //28 KEY_ENTER - LCTRL, //29 KEY_LEFTCTRL - 0x04, //30 KEY_A - 0x16, //31 KEY_S - 0x07, //32 KEY_D - 0x09, //33 KEY_F - 0x0a, //34 KEY_G - 0x0b, //35 KEY_H - 0x0d, //36 KEY_J - 0x0e, //37 KEY_K - 0x0f, //38 KEY_L - 0x33, //39 KEY_SEMICOLON - 0x34, //40 KEY_APOSTROPHE - 0x35, //41 KEY_GRAVE - LSHIFT, //42 KEY_LEFTSHIFT - 0x31, //43 KEY_BACKSLASH - 0x1d, //44 KEY_Z - 0x1b, //45 KEY_X - 0x06, //46 KEY_C - 0x19, //47 KEY_V - 0x05, //48 KEY_B - 0x11, //49 KEY_N - 0x10, //50 KEY_M - 0x36, //51 KEY_COMMA - 0x37, //52 KEY_DOT - 0x38, //53 KEY_SLASH - RSHIFT, //54 KEY_RIGHTSHIFT - 0x55, //55 KEY_KPASTERISK - LALT, //56 KEY_LEFTALT - 0x2C, //57 KEY_SPACE - 0x39, //58 KEY_CAPSLOCK - 0x3a, //59 KEY_F1 - 0x3b, //60 KEY_F2 - 0x3c, //61 KEY_F3 - 0x3d, //62 KEY_F4 - 0x3e, //63 KEY_F5 - 0x3f, //64 KEY_F6 - 0x40, //65 KEY_F7 - 0x41, //66 KEY_F8 - 0x42, //67 KEY_F9 - 0x43, //68 KEY_F10 - 0x53, //69 KEY_NUMLOCK - 0x47, //70 KEY_SCROLLLOCK - 0x5F, //71 KEY_KP7 - 0x60, //72 KEY_KP8 - 0x61, //73 KEY_KP9 - 0x56, //74 KEY_KPMINUS - 0x5C, //75 KEY_KP4 - 0x5D, //76 KEY_KP5 - 0x5E, //77 KEY_KP6 - 0x57, //78 KEY_KPPLUS - 0x59, //79 KEY_KP1 - 0x5A, //80 KEY_KP2 - 0x5B, //81 KEY_KP3 - 0x62, //82 KEY_KP0 - 0x63, //83 KEY_KPDOT + 0x45, //1 KEY_ESC + 0x01, //2 KEY_1 + 0x02, //3 KEY_2 + 0x03, //4 KEY_3 + 0x04, //5 KEY_4 + 0x05, //6 KEY_5 + 0x06, //7 KEY_6 + 0x07, //8 KEY_7 + 0x08, //9 KEY_8 + 0x09, //10 KEY_9 + 0x0a, //11 KEY_0 + 0x0b, //12 KEY_MINUS + 0x0c, //13 KEY_EQUAL + 0x41, //14 KEY_BACKSPACE + 0x42, //15 KEY_TAB + 0x10, //16 KEY_Q + 0x11, //17 KEY_W + 0x12, //18 KEY_E + 0x13, //19 KEY_R + 0x14, //20 KEY_T + 0x15, //21 KEY_Y + 0x16, //22 KEY_U + 0x17, //23 KEY_I + 0x18, //24 KEY_O + 0x19, //25 KEY_P + 0x1a, //26 KEY_LEFTBRACE + 0x1b, //27 KEY_RIGHTBRACE + 0x44, //28 KEY_ENTER + 0x63, //29 KEY_LEFTCTRL + 0x20, //30 KEY_A + 0x21, //31 KEY_S + 0x22, //32 KEY_D + 0x23, //33 KEY_F + 0x24, //34 KEY_G + 0x25, //35 KEY_H + 0x26, //36 KEY_J + 0x27, //37 KEY_K + 0x28, //38 KEY_L + 0x29, //39 KEY_SEMICOLON + 0x2a, //40 KEY_APOSTROPHE + 0x00, //41 KEY_GRAVE + 0x60, //42 KEY_LEFTSHIFT + 0x0d, //43 KEY_BACKSLASH + 0x31, //44 KEY_Z + 0x32, //45 KEY_X + 0x33, //46 KEY_C + 0x34, //47 KEY_V + 0x35, //48 KEY_B + 0x36, //49 KEY_N + 0x37, //50 KEY_M + 0x38, //51 KEY_COMMA + 0x39, //52 KEY_DOT + 0x3a, //53 KEY_SLASH + 0x61, //54 KEY_RIGHTSHIFT + 0x5d, //55 KEY_KPASTERISK + 0x64, //56 KEY_LEFTALT + 0x40, //57 KEY_SPACE + 0x62 | CAPS_TOGGLE, //58 KEY_CAPSLOCK + 0x50, //59 KEY_F1 + 0x51, //60 KEY_F2 + 0x52, //61 KEY_F3 + 0x53, //62 KEY_F4 + 0x54, //63 KEY_F5 + 0x55, //64 KEY_F6 + 0x56, //65 KEY_F7 + 0x57, //66 KEY_F8 + 0x58, //67 KEY_F9 + 0x59, //68 KEY_F10 + NONE, //69 KEY_NUMLOCK + NONE, //70 KEY_SCROLLLOCK + 0x3d, //71 KEY_KP7 + 0x3e, //72 KEY_KP8 + 0x3f, //73 KEY_KP9 + 0x4a, //74 KEY_KPMINUS + 0x2d, //75 KEY_KP4 + 0x2e, //76 KEY_KP5 + 0x2f, //77 KEY_KP6 + 0x5e, //78 KEY_KPPLUS + 0x1d, //79 KEY_KP1 + 0x1e, //80 KEY_KP2 + 0x1f, //81 KEY_KP3 + 0x0f, //82 KEY_KP0 + 0x3c, //83 KEY_KPDOT NONE, //84 ??? NONE, //85 KEY_ZENKAKU - FN, //86 KEY_102ND - 0x44, //87 KEY_F11 - 0x45, //88 KEY_F12 + NONE, //86 KEY_102ND + 0x5f, //87 KEY_F11 + NONE, //88 KEY_F12 NONE, //89 KEY_RO NONE, //90 KEY_KATAKANA NONE, //91 KEY_HIRAGANA @@ -148,38 +115,299 @@ static int ev2usb[] = NONE, //93 KEY_KATAKANA NONE, //94 KEY_MUHENKAN NONE, //95 KEY_KPJPCOMMA - 0x28, //96 KEY_KPENTER - RCTRL, //97 KEY_RIGHTCTRL - 0x54, //98 KEY_KPSLASH + 0x43, //96 KEY_KPENTER + 0x63, //97 KEY_RIGHTCTRL + 0x5c, //98 KEY_KPSLASH NONE, //99 KEY_SYSRQ - RALT, //100 KEY_RIGHTALT + 0x65, //100 KEY_RIGHTALT NONE, //101 KEY_LINEFEED - 0x4A, //102 KEY_HOME - 0x52, //103 KEY_UP - 0x4B, //104 KEY_PAGEUP - 0x50, //105 KEY_LEFT - 0x4F, //106 KEY_RIGHT - 0x4D, //107 KEY_END - 0x51, //108 KEY_DOWN - 0x4E, //109 KEY_PAGEDOWN - 0x49, //110 KEY_INSERT - 0x4C, //111 KEY_DELETE + 0x6a, //102 KEY_HOME + 0x4c, //103 KEY_UP + NONE, //104 KEY_PAGEUP + 0x4f, //105 KEY_LEFT + 0x4e, //106 KEY_RIGHT + NONE, //107 KEY_END + 0x4d, //108 KEY_DOWN + NONE, //109 KEY_PAGEDOWN + 0x0d, //110 KEY_INSERT + 0x46, //111 KEY_DELETE NONE, //112 KEY_MACRO NONE, //113 KEY_MUTE NONE, //114 KEY_VOLUMEDOWN NONE, //115 KEY_VOLUMEUP NONE, //116 KEY_POWER - 0x67, //117 KEY_KPEQUAL + NONE, //117 KEY_KPEQUAL NONE, //118 KEY_KPPLUSMINUS - 0x48, //119 KEY_PAUSE + NONE, //119 KEY_PAUSE NONE, //120 KEY_SCALE NONE, //121 KEY_KPCOMMA NONE, //122 KEY_HANGEUL NONE, //123 KEY_HANJA NONE, //124 KEY_YEN - LGUI, //125 KEY_LEFTMETA - RGUI, //126 KEY_RIGHTMETA - 0x65, //127 KEY_COMPOSE + 0x66, //125 KEY_LEFTMETA + 0x67, //126 KEY_RIGHTMETA + NONE, //127 KEY_COMPOSE + NONE, //128 KEY_STOP + NONE, //129 KEY_AGAIN + NONE, //130 KEY_PROPS + NONE, //131 KEY_UNDO + NONE, //132 KEY_FRONT + NONE, //133 KEY_COPY + NONE, //134 KEY_OPEN + NONE, //135 KEY_PASTE + NONE, //136 KEY_FIND + NONE, //137 KEY_CUT + NONE, //138 KEY_HELP + NONE, //139 KEY_MENU + NONE, //140 KEY_CALC + NONE, //141 KEY_SETUP + NONE, //142 KEY_SLEEP + NONE, //143 KEY_WAKEUP + NONE, //144 KEY_FILE + NONE, //145 KEY_SENDFILE + NONE, //146 KEY_DELETEFILE + NONE, //147 KEY_XFER + NONE, //148 KEY_PROG1 + NONE, //149 KEY_PROG2 + NONE, //150 KEY_WWW + NONE, //151 KEY_MSDOS + NONE, //152 KEY_SCREENLOCK + NONE, //153 KEY_DIRECTION + NONE, //154 KEY_CYCLEWINDOWS + NONE, //155 KEY_MAIL + NONE, //156 KEY_BOOKMARKS + NONE, //157 KEY_COMPUTER + NONE, //158 KEY_BACK + NONE, //159 KEY_FORWARD + NONE, //160 KEY_CLOSECD + NONE, //161 KEY_EJECTCD + NONE, //162 KEY_EJECTCLOSECD + NONE, //163 KEY_NEXTSONG + NONE, //164 KEY_PLAYPAUSE + NONE, //165 KEY_PREVIOUSSONG + NONE, //166 KEY_STOPCD + NONE, //167 KEY_RECORD + NONE, //168 KEY_REWIND + NONE, //169 KEY_PHONE + NONE, //170 KEY_ISO + NONE, //171 KEY_CONFIG + NONE, //172 KEY_HOMEPAGE + NONE, //173 KEY_REFRESH + NONE, //174 KEY_EXIT + NONE, //175 KEY_MOVE + NONE, //176 KEY_EDIT + NONE, //177 KEY_SCROLLUP + NONE, //178 KEY_SCROLLDOWN + NONE, //179 KEY_KPLEFTPAREN + NONE, //180 KEY_KPRIGHTPAREN + NONE, //181 KEY_NEW + NONE, //182 KEY_REDO + 0x5a, //183 KEY_F13 + 0x5b, //184 KEY_F14 + NONE, //185 KEY_F15 + 0x5f, //186 KEY_F16 + NONE, //187 KEY_F17 + NONE, //188 KEY_F18 + NONE, //189 KEY_F19 + NONE, //190 KEY_F20 + NONE, //191 KEY_F21 + NONE, //192 KEY_F22 + NONE, //193 KEY_F23 + 0x63, //194 KEY_F24 + NONE, //195 ??? + NONE, //196 ??? + NONE, //197 ??? + NONE, //198 ??? + NONE, //199 ??? + NONE, //200 KEY_PLAYCD + NONE, //201 KEY_PAUSECD + NONE, //202 KEY_PROG3 + NONE, //203 KEY_PROG4 + NONE, //204 KEY_DASHBOARD + NONE, //205 KEY_SUSPEND + NONE, //206 KEY_CLOSE + NONE, //207 KEY_PLAY + NONE, //208 KEY_FASTFORWARD + NONE, //209 KEY_BASSBOOST + NONE, //210 KEY_PRINT + NONE, //211 KEY_HP + NONE, //212 KEY_CAMERA + NONE, //213 KEY_SOUND + NONE, //214 KEY_QUESTION + NONE, //215 KEY_EMAIL + NONE, //216 KEY_CHAT + NONE, //217 KEY_SEARCH + NONE, //218 KEY_CONNECT + NONE, //219 KEY_FINANCE + NONE, //220 KEY_SPORT + NONE, //221 KEY_SHOP + NONE, //222 KEY_ALTERASE + NONE, //223 KEY_CANCEL + NONE, //224 KEY_BRIGHT_DOWN + NONE, //225 KEY_BRIGHT_UP + NONE, //226 KEY_MEDIA + NONE, //227 KEY_SWITCHVIDEO + NONE, //228 KEY_DILLUMTOGGLE + NONE, //229 KEY_DILLUMDOWN + NONE, //230 KEY_DILLUMUP + NONE, //231 KEY_SEND + NONE, //232 KEY_REPLY + NONE, //233 KEY_FORWARDMAIL + NONE, //234 KEY_SAVE + NONE, //235 KEY_DOCUMENTS + NONE, //236 KEY_BATTERY + NONE, //237 KEY_BLUETOOTH + NONE, //238 KEY_WLAN + NONE, //239 KEY_UWB + NONE, //240 KEY_UNKNOWN + NONE, //241 KEY_VIDEO_NEXT + NONE, //242 KEY_VIDEO_PREV + NONE, //243 KEY_BRIGHT_CYCLE + NONE, //244 KEY_BRIGHT_AUTO + NONE, //245 KEY_DISPLAY_OFF + NONE, //246 KEY_WWAN + NONE, //247 KEY_RFKILL + NONE, //248 KEY_MICMUTE + NONE, //249 ??? + NONE, //250 ??? + NONE, //251 ??? + NONE, //252 ??? + NONE, //253 ??? + NONE, //254 ??? + NONE //255 ??? +}; + + +static const int ev2ps2[] = +{ + NONE, //0 KEY_RESERVED + 0x76, //1 KEY_ESC + 0x16, //2 KEY_1 + 0x1e, //3 KEY_2 + 0x26, //4 KEY_3 + 0x25, //5 KEY_4 + 0x2e, //6 KEY_5 + 0x36, //7 KEY_6 + 0x3d, //8 KEY_7 + 0x3e, //9 KEY_8 + 0x46, //10 KEY_9 + 0x45, //11 KEY_0 + 0x4e, //12 KEY_MINUS + 0x55, //13 KEY_EQUAL + 0x66, //14 KEY_BACKSPACE + 0x0d, //15 KEY_TAB + 0x15, //16 KEY_Q + 0x1d, //17 KEY_W + 0x24, //18 KEY_E + 0x2d, //19 KEY_R + 0x2c, //20 KEY_T + 0x35, //21 KEY_Y + 0x3c, //22 KEY_U + 0x43, //23 KEY_I + 0x44, //24 KEY_O + 0x4d, //25 KEY_P + 0x54, //26 KEY_LEFTBRACE + 0x5b, //27 KEY_RIGHTBRACE + 0x5a, //28 KEY_ENTER + LCTRL | 0x14, //29 KEY_LEFTCTRL + 0x1c, //30 KEY_A + 0x1b, //31 KEY_S + 0x23, //32 KEY_D + 0x2b, //33 KEY_F + 0x34, //34 KEY_G + 0x33, //35 KEY_H + 0x3b, //36 KEY_J + 0x42, //37 KEY_K + 0x4b, //38 KEY_L + 0x4c, //39 KEY_SEMICOLON + 0x52, //40 KEY_APOSTROPHE + 0x0e, //41 KEY_GRAVE + LSHIFT | 0x12, //42 KEY_LEFTSHIFT + 0x5d, //43 KEY_BACKSLASH + 0x1a, //44 KEY_Z + 0x22, //45 KEY_X + 0x21, //46 KEY_C + 0x2a, //47 KEY_V + 0x32, //48 KEY_B + 0x31, //49 KEY_N + 0x3a, //50 KEY_M + 0x41, //51 KEY_COMMA + 0x49, //52 KEY_DOT + 0x4a, //53 KEY_SLASH + RSHIFT | 0x59, //54 KEY_RIGHTSHIFT + 0x7c, //55 KEY_KPASTERISK + LALT | 0x11, //56 KEY_LEFTALT + 0x29, //57 KEY_SPACE + 0x58, //58 KEY_CAPSLOCK + 0x05, //59 KEY_F1 + 0x06, //60 KEY_F2 + 0x04, //61 KEY_F3 + 0x0c, //62 KEY_F4 + 0x03, //63 KEY_F5 + 0x0b, //64 KEY_F6 + 0x83, //65 KEY_F7 + 0x0a, //66 KEY_F8 + 0x01, //67 KEY_F9 + 0x09, //68 KEY_F10 + EMU_SWITCH_2 | 0x77, //69 KEY_NUMLOCK + EMU_SWITCH_1 | 0x7E, //70 KEY_SCROLLLOCK + 0x6c, //71 KEY_KP7 + 0x75, //72 KEY_KP8 + 0x7d, //73 KEY_KP9 + 0x7b, //74 KEY_KPMINUS + 0x6b, //75 KEY_KP4 + 0x73, //76 KEY_KP5 + 0x74, //77 KEY_KP6 + 0x79, //78 KEY_KPPLUS + 0x69, //79 KEY_KP1 + 0x72, //80 KEY_KP2 + 0x7a, //81 KEY_KP3 + 0x70, //82 KEY_KP0 + 0x71, //83 KEY_KPDOT + NONE, //84 ??? + NONE, //85 KEY_ZENKAKU + NONE, //86 KEY_102ND + 0x78, //87 KEY_F11 + OSD_OPEN, //88 KEY_F12 + NONE, //89 KEY_RO + NONE, //90 KEY_KATAKANA + NONE, //91 KEY_HIRAGANA + NONE, //92 KEY_HENKAN + NONE, //93 KEY_KATAKANA + NONE, //94 KEY_MUHENKAN + NONE, //95 KEY_KPJPCOMMA + EXT | 0x5a, //96 KEY_KPENTER + RCTRL | EXT | 0x14, //97 KEY_RIGHTCTRL + EXT | 0x4a, //98 KEY_KPSLASH + NONE, //99 KEY_SYSRQ + RALT | EXT | 0x11, //100 KEY_RIGHTALT + NONE, //101 KEY_LINEFEED + EXT | 0x6c, //102 KEY_HOME + EXT | 0x75, //103 KEY_UP + EXT | 0x7d, //104 KEY_PAGEUP + EXT | 0x6b, //105 KEY_LEFT + EXT | 0x74, //106 KEY_RIGHT + EXT | 0x69, //107 KEY_END + EXT | 0x72, //108 KEY_DOWN + EXT | 0x7a, //109 KEY_PAGEDOWN + EXT | 0x70, //110 KEY_INSERT + EXT | 0x71, //111 KEY_DELETE + NONE, //112 KEY_MACRO + NONE, //113 KEY_MUTE + NONE, //114 KEY_VOLUMEDOWN + NONE, //115 KEY_VOLUMEUP + NONE, //116 KEY_POWER + NONE, //117 KEY_KPEQUAL + NONE, //118 KEY_KPPLUSMINUS + 0xE1, //119 KEY_PAUSE + NONE, //120 KEY_SCALE + NONE, //121 KEY_KPCOMMA + NONE, //122 KEY_HANGEUL + NONE, //123 KEY_HANJA + NONE, //124 KEY_YEN + LGUI | EXT | 0x1f, //125 KEY_LEFTMETA + RGUI | EXT | 0x27, //126 KEY_RIGHTMETA + NONE, //127 KEY_COMPOSE NONE, //128 KEY_STOP NONE, //129 KEY_AGAIN NONE, //130 KEY_PROPS @@ -239,14 +467,14 @@ static int ev2usb[] = NONE, //184 KEY_F14 NONE, //185 KEY_F15 NONE, //186 KEY_F16 - NONE, //187 KEY_F17 - NONE, //188 KEY_F18 - NONE, //189 KEY_F19 - NONE, //190 KEY_F20 + EMU_SWITCH_1 | 1, //187 KEY_F17 + EMU_SWITCH_1 | 2, //188 KEY_F18 + EMU_SWITCH_1 | 3, //189 KEY_F19 + EMU_SWITCH_1 | 4, //190 KEY_F20 NONE, //191 KEY_F21 NONE, //192 KEY_F22 NONE, //193 KEY_F23 - RCTRL, //194 KEY_F24 + RCTRL | EXT | 0x14, //194 KEY_F24 NONE, //195 ??? NONE, //196 ??? NONE, //197 ??? @@ -262,7 +490,7 @@ static int ev2usb[] = NONE, //207 KEY_PLAY NONE, //208 KEY_FASTFORWARD NONE, //209 KEY_BASSBOOST - 0x46, //210 KEY_PRINT + 0xE2, //210 KEY_PRINT NONE, //211 KEY_HP NONE, //212 KEY_CAMERA NONE, //213 KEY_SOUND @@ -310,6 +538,344 @@ static int ev2usb[] = 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 +}; +*/ + +/* + +// Archimedes unmapped keys +// Missing sterling +// Missing kp_hash +// Missing button_1 +// Missing button_2 +// Missing button_3 +// Missing button_4 +// Missing button_5 + +// keycode translation table +const unsigned short usb2archie[] = { +MISS, // 00: NoEvent +MISS, // 01: Overrun Error +MISS, // 02: POST fail +MISS, // 03: ErrorUndefined +0x3c, // 04: a +0x52, // 05: b +0x50, // 06: c +0x3e, // 07: d +0x29, // 08: e +0x3f, // 09: f +0x40, // 0a: g +0x41, // 0b: h +0x2e, // 0c: i +0x42, // 0d: j +0x43, // 0e: k +0x44, // 0f: l +0x54, // 10: m +0x53, // 11: n +0x2f, // 12: o +0x30, // 13: p +0x27, // 14: q +0x2a, // 15: r +0x3d, // 16: s +0x2b, // 17: t +0x2d, // 18: u +0x51, // 19: v +0x28, // 1a: w +0x4f, // 1b: x +0x2c, // 1c: y +0x4e, // 1d: z +0x11, // 1e: 1 +0x12, // 1f: 2 +0x13, // 20: 3 +0x14, // 21: 4 +0x15, // 22: 5 +0x16, // 23: 6 +0x17, // 24: 7 +0x18, // 25: 8 +0x19, // 26: 9 +0x1a, // 27: 0 +0x47, // 28: Return +0x00, // 29: Escape +0x1e, // 2a: Backspace +0x26, // 2b: Tab +0x5f, // 2c: Space +0x1b, // 2d: - +0x1c, // 2e: = +0x31, // 2f: [ +0x32, // 30: ] +0x33, // 31: backslash (only on us keyboards) +0x33, // 32: Europe 1 (only on international kbds) +0x45, // 33: ; +0x46, // 34: ' +0x10, // 35: ` +0x55, // 36: , +0x56, // 37: . +0x57, // 38: / +0x5d, // 39: Caps Lock +0x01, // 3a: F1 +0x02, // 3b: F2 +0x03, // 3c: F3 +0x04, // 3d: F4 +0x05, // 3e: F5 +0x06, // 3f: F6 +0x07, // 40: F7 +0x08, // 41: F8 +0x09, // 42: F9 +0x0a, // 43: F10 +0x0b, // 44: F11 +0x0c, // 45: F12 - Used heavily by the archie... OSD moved to printscreen. +// 0x0d, // 46: Print Screen +OSD_OPEN, // 46: Print Screen +0x0e, // 47: Scroll Lock +0x0f, // 48: Pause +0x1f, // 49: Insert +0x20, // 4a: Home +0x21, // 4b: Page Up +0x34, // 4c: Delete +0x35, // 4d: End +0x36, // 4e: Page Down +0x64, // 4f: Right Arrow +0x62, // 50: Left Arrow +0x63, // 51: Down Arrow +0x59, // 52: Up Arrow +0x22, // 53: Num Lock +0x23, // 54: KP / +0x24, // 55: KP * +0x3a, // 56: KP - +0x4b, // 57: KP + +0x67, // 58: KP Enter +0x5a, // 59: KP 1 +0x5b, // 5a: KP 2 +0x5c, // 5b: KP 3 +0x48, // 5c: KP 4 +0x49, // 5d: KP 5 +0x4a, // 5e: KP 6 +0x37, // 5f: KP 7 +0x38, // 60: KP 8 +0x39, // 61: KP 9 +0x65, // 62: KP 0 +0x66, // 63: KP decimal +MISS, // 64: Europe 2 +0x72, // 65: App (maps to middle mouse button) +MISS, // 66: Power +MISS, // 67: KP = +MISS, // 68: F13 +MISS, // 69: F14 +MISS, // 6a: F15 +0x1f, // 6b: insert (for keyrah) +MISS, // 6c: F17 +MISS, // 6d: F18 +MISS, // 6e: F19 +MISS, // 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_MINIMIG2) +{ +static const unsigned short amiga_modifier[] = { 0x63, 0x60, 0x64, 0x66, 0x63, 0x61, 0x65, 0x67 }; +return amiga_modifier[index]; +} + +if (core_type == CORE_TYPE_MIST) +{ +static const unsigned short atari_modifier[] = { 0x1d, 0x2a, 0x38, MISS, 0x1d, 0x36, 0x38, MISS }; +return atari_modifier[index]; +} + +if (core_type == CORE_TYPE_8BIT) +{ +static const unsigned short ps2_modifier[] = { 0x14, 0x12, 0x11, EXT | 0x1f, EXT | 0x14, 0x59, EXT | 0x11, EXT | 0x27 }; +return ps2_modifier[index]; +} + +if (core_type == CORE_TYPE_ARCHIE) +{ +static const unsigned short archie_modifier[] = { 0x36, 0x4c, 0x5e, MISS, 0x61, 0x58, 0x60, MISS }; +return archie_modifier[index]; +} + +return MISS; +} +*/ + + +uint32_t get_ps2_code(uint16_t key) +{ + if (key > 255) return NONE; + return ev2ps2[key]; +} + +uint32_t get_amiga_code(uint16_t key) +{ + if (key > 255) return NONE; + 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; + return 0; // ev2archie[key]; +} + +static uint32_t modifier = 0; + +uint32_t get_key_mod() +{ + return modifier & MODMASK; +} + +typedef struct +{ + uint16_t vid, pid; + char led; + char last_l, last_r, last_u, last_d; + + char has_map; + uint32_t map[32]; + + char has_mmap; + uint32_t mmap[32]; + + char has_kbdmap; + uint8_t kbdmap[256]; +} devInput; + +static devInput input[NUMDEV] = { 0 }; +static int first_joystick = -1; + int mfd = -1; int mwd = -1; @@ -523,51 +1089,51 @@ uint16_t get_map_pid() static char kr_fn_table[] = { - 0x54, 0x48, // pause/break - 0x55, 0x46, // prnscr - 0x50, 0x4a, // home - 0x4f, 0x4d, // end - 0x52, 0x4b, // pgup - 0x51, 0x4e, // pgdown - 0x3a, 0x44, // f11 - 0x3b, 0x45, // f12 + KEY_KPSLASH, KEY_PAUSE, + KEY_KPASTERISK, KEY_PRINT, + KEY_LEFT, KEY_HOME, + KEY_RIGHT, KEY_END, + KEY_UP, KEY_PAGEUP, + KEY_DOWN, KEY_PAGEDOWN, + KEY_F1, KEY_F11, + KEY_F2, KEY_F12, - 0x3c, 0x6c, // EMU_MOUSE - 0x3d, 0x6d, // EMU_JOY0 - 0x3e, 0x6e, // EMU_JOY1 - 0x3f, 0x6f, // EMU_NONE + KEY_F3, KEY_F17, // EMU_MOUSE + KEY_F4, KEY_F18, // EMU_JOY0 + KEY_F5, KEY_F19, // EMU_JOY1 + KEY_F6, KEY_F20, // EMU_NONE - //Emulate keypad for A600 - 0x1E, 0x59, //KP1 - 0x1F, 0x5A, //KP2 - 0x20, 0x5B, //KP3 - 0x21, 0x5C, //KP4 - 0x22, 0x5D, //KP5 - 0x23, 0x5E, //KP6 - 0x24, 0x5F, //KP7 - 0x25, 0x60, //KP8 - 0x26, 0x61, //KP9 - 0x27, 0x62, //KP0 - 0x2D, 0x56, //KP- - 0x2E, 0x57, //KP+ - 0x31, 0x55, //KP* - 0x2F, 0x68, //KP( - 0x30, 0x69, //KP) - 0x37, 0x63, //KP. - 0x28, 0x58 //KP Enter + //Emulate keypad for A600 + KEY_1, KEY_KP1, + KEY_2, KEY_KP2, + KEY_3, KEY_KP3, + KEY_4, KEY_KP4, + KEY_5, KEY_KP5, + KEY_6, KEY_KP6, + KEY_7, KEY_KP7, + KEY_8, KEY_KP8, + KEY_9, KEY_KP9, + KEY_0, KEY_KP0, + KEY_MINUS, KEY_KPMINUS, + KEY_EQUAL, KEY_KPPLUS, + KEY_BACKSLASH, KEY_KPASTERISK, + KEY_LEFTBRACE, KEY_F13, //KP( + KEY_RIGHTBRACE, KEY_F14, //KP) + KEY_DOT, KEY_KPDOT, + KEY_ENTER, KEY_KPENTER }; static int keyrah_trans(int key, int press) { static int fn = 0; - if (key == 0x53) return 0x68; - if (key == 0x47) return 0x69; - if (key == 0x49) return 0x6b; // workaround! + if (key == KEY_NUMLOCK) return KEY_F13; // numlock -> f13 + if (key == KEY_SCROLLLOCK) return KEY_F14; // scrlock -> f14 + if (key == KEY_INSERT) return KEY_F16; // insert -> f16. workaround! - if (key == FN) + if (key == KEY_102ND) { - if (!press && fn == 1) menu_key_set(KEY_AMI_MENU); + if (!press && fn == 1) menu_key_set(KEY_F12); fn = press ? 1 : 0; return 0; } @@ -727,9 +1293,6 @@ static void input_cb(struct input_event *ev, int dev) static uint8_t modifiers = 0; static char keys[6] = { 0,0,0,0,0,0 }; - // repeat events won't be processed - if (ev->type == EV_KEY && ev->value > 1) return; - int map_skip = (ev->type == EV_KEY && ev->code == 57 && mapping_dev >= 0 && mapping_type==1); int cancel = (ev->type == EV_KEY && ev->code == 1); int enter = (ev->type == EV_KEY && ev->code == 28); @@ -740,9 +1303,12 @@ static void input_cb(struct input_event *ev, int dev) case EV_KEY: if (ev->code >= 272 && ev->code <= 279) { - unsigned char mask = 1 << (ev->code - 272); - mouse_btn = (ev->value) ? mouse_btn | mask : mouse_btn & ~mask; - user_io_mouse(mouse_btn, 0, 0); + if (ev->value <= 1) + { + unsigned char mask = 1 << (ev->code - 272); + mouse_btn = (ev->value) ? mouse_btn | mask : mouse_btn & ~mask; + user_io_mouse(mouse_btn, 0, 0); + } return; } break; @@ -802,7 +1368,7 @@ static void input_cb(struct input_event *ev, int dev) { if (mapping_type == 2) { - if (ev->value && ev->code < 256) + if (ev->value == 1 && ev->code < 256) { if(mapping_dev < 0) { @@ -829,7 +1395,7 @@ static void input_cb(struct input_event *ev, int dev) if (mapping_dev == dev && mapping_button < mapping_count) { - if (ev->value) + if (ev->value == 1) { if (!mapping_button) memset(input[dev].map, 0, sizeof(input[dev].map)); @@ -842,7 +1408,7 @@ static void input_cb(struct input_event *ev, int dev) key_mapped = 1; } } - else + else if(ev->value == 0) { if (key_mapped) mapping_button++; key_mapped = 0; @@ -904,7 +1470,7 @@ static void input_cb(struct input_event *ev, int dev) { if (ev->code == input[dev].map[i]) { - joy_digital((first_joystick == dev) ? 0 : 1, 1 << i, ev->value, i); + if(ev->value <= 1) joy_digital((first_joystick == dev) ? 0 : 1, 1 << i, ev->value, i); return; } } @@ -915,7 +1481,7 @@ static void input_cb(struct input_event *ev, int dev) { if (ev->code == input[dev].map[i]) { - joy_digital((first_joystick == dev) ? 0 : 1, 1 << i, ev->value, i); + if (ev->value <= 1) joy_digital((first_joystick == dev) ? 0 : 1, 1 << i, ev->value, i); return; } } @@ -924,7 +1490,7 @@ static void input_cb(struct input_event *ev, int dev) { if (ev->code == input[dev].mmap[i]) { - joy_digital((first_joystick == dev) ? 0 : 1, 1 << (i - 8), ev->value, i - 8); + if (ev->value <= 1) joy_digital((first_joystick == dev) ? 0 : 1, 1 << (i - 8), ev->value, i - 8); return; } } @@ -932,11 +1498,11 @@ static void input_cb(struct input_event *ev, int dev) if (ev->code == input[dev].map[17]) { - joy_digital((first_joystick == dev) ? 0 : 1, 0, ev->value, 17); + if (ev->value <= 1) joy_digital((first_joystick == dev) ? 0 : 1, 0, ev->value, 17); return; } - if (ev->code == input[dev].mmap[15]) + if (ev->code == input[dev].mmap[15] && (ev->value <= 1)) { mouse_emu = ev->value ? mouse_emu | 1 : mouse_emu & ~1; printf("mouse_emu = %d\n", mouse_emu); @@ -966,7 +1532,7 @@ static void input_cb(struct input_event *ev, int dev) { if (ev->code == input[dev].map[i]) { - joy_digital((user_io_get_kbdemu() == EMU_JOY0) ? 0 : 1, 1 << i, ev->value, i); + if (ev->value <= 1) joy_digital((user_io_get_kbdemu() == EMU_JOY0) ? 0 : 1, 1 << i, ev->value, i); return; } } @@ -974,7 +1540,7 @@ static void input_cb(struct input_event *ev, int dev) if (ev->code == input[dev].map[16]) { - joy_digital((user_io_get_kbdemu() == EMU_JOY0) ? 0 : 1, 0, ev->value, 16); + if (ev->value <= 1) joy_digital((user_io_get_kbdemu() == EMU_JOY0) ? 0 : 1, 0, ev->value, 16); return; } } @@ -1017,14 +1583,14 @@ static void input_cb(struct input_event *ev, int dev) if (ev->code == input[dev].mmap[15]) { - mouse_sniper = ev->value; + if (ev->value <= 1) mouse_sniper = ev->value; return; } } if (ev->code == input[dev].map[16]) { - if (ev->value) + if (ev->value == 1) { kbd_mouse_emu = !kbd_mouse_emu; printf("kbd_mouse_emu = %d\n", kbd_mouse_emu); @@ -1048,34 +1614,27 @@ static void input_cb(struct input_event *ev, int dev) input[dev].has_kbdmap = 1; } - int key = input[dev].kbdmap[ev->code] ? input[dev].kbdmap[ev->code] : ev->code; - key = (key < (sizeof(ev2usb) / sizeof(ev2usb[0]))) ? ev2usb[key] : NONE; - if(key != NONE) - { - static uint16_t mod = 0; + static uint16_t mod = 0; - //Keyrah v2: USB\VID_18D8&PID_0002\A600/A1200_MULTIMEDIA_EXTENSION_VERSION - int keyrah = (mist_cfg.keyrah_mode && (((((uint32_t)input[dev].vid) << 16) | input[dev].pid) == mist_cfg.keyrah_mode)); + // replace MENU key by RGUI to allow using Right Amiga on reduced keyboards + // (it also disables the use of Menu for OSD) + uint16_t code = ev->code; + if (mist_cfg.key_menu_as_rgui && code == 139) code = 126; - if (keyrah) key = keyrah_trans(key, ev->value); - if (key & 0xffff) - { - unsigned short reset_m = mod >> 8; - if (key == 0x4c) reset_m |= 0x100; - user_io_check_reset(reset_m, (keyrah && !mist_cfg.reset_combo) ? 1 : mist_cfg.reset_combo); + //Keyrah v2: USB\VID_18D8&PID_0002\A600/A1200_MULTIMEDIA_EXTENSION_VERSION + int keyrah = (mist_cfg.keyrah_mode && (((((uint32_t)input[dev].vid) << 16) | input[dev].pid) == mist_cfg.keyrah_mode)); + if (keyrah) code = keyrah_trans(code, ev->value); - if (key & MODMASK) - { - if (ev->value) mod |= key; - else mod &= ~key; - } - key = (mod & MODMASK) | (key & ~MODMASK); + uint32_t ps2code = get_ps2_code(code); + if (ev->value) modifier |= ps2code; + else modifier &= ~ps2code; - menu_mod_set(mod >> 8); - user_io_kbd((uint16_t)key, ev->value); - } - return; - } + uint16_t reset_m = (modifier & MODMASK) >> 8; + if (code == 111) reset_m |= 0x100; + user_io_check_reset(reset_m, (keyrah && !mist_cfg.reset_combo) ? 1 : mist_cfg.reset_combo); + + user_io_kbd(code, ev->value); + return; } break; @@ -1236,7 +1795,7 @@ int input_test(int getchar) { //keyboard, buttons case EV_KEY: - if(ev.value<=1) printf("Input event: type=EV_KEY, code=%d(0x%x), value=%d\n", ev.code, ev.code, ev.value); + printf("Input event: type=EV_KEY, code=%d(0x%x), value=%d\n", ev.code, ev.code, ev.value); break; //mouse diff --git a/input.h b/input.h index c73bdaa..77061f6 100644 --- a/input.h +++ b/input.h @@ -2,11 +2,33 @@ #ifndef EVINPUT_H #define EVINPUT_H +#include + #define HID_LED_NUM_LOCK 1 #define HID_LED_CAPS_LOCK 2 #define HID_LED_SCROLL_LOCK 4 #define HID_LED_MASK 7 +#define NONE 0xFF +#define LCTRL 0x000100 +#define LSHIFT 0x000200 +#define LALT 0x000400 +#define LGUI 0x000800 +#define RCTRL 0x001000 +#define RSHIFT 0x002000 +#define RALT 0x004000 +#define RGUI 0x008000 +#define MODMASK 0x00FF00 + +#define OSD 0x010000 // to be used by OSD, not the core itself +#define OSD_OPEN 0x020000 // OSD key not forwarded to core, but queued in arm controller +#define CAPS_TOGGLE 0x040000 // caps lock toggle behaviour +#define EXT 0x080000 +#define EMU_SWITCH_1 0x100000 +#define EMU_SWITCH_2 0x200000 + +#define UPSTROKE 0x400000 + void set_kbdled(int mask, int state); int get_kbdled(int mask); int toggle_kbdled(int mask); @@ -22,4 +44,10 @@ void finish_map_setting(int dismiss); uint16_t get_map_vid(); uint16_t get_map_pid(); +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); + #endif diff --git a/keycodes.h b/keycodes.h deleted file mode 100644 index e41f558..0000000 --- a/keycodes.h +++ /dev/null @@ -1,509 +0,0 @@ -// http://wiki.amigaos.net/index.php/Keymap_Library -// http://www.win.tue.nl/~aeb/linux/kbd/scancodes-14.html - -#include "osd.h" - -#ifndef KEYCODES_H -#define KEYCODES_H - -#define MISS 0xff -#define KEYCODE_MAX (0x6f) - -// The original minimig had the keyboard connected to the FPGA. Thus all key events (even for OSD) -// came from the FPGA core. The MIST has the keyboard attached to the arm controller. To be compatible -// with the minimig core all keys (incl. OSD!) are forwarded to the FPGA and the OSD keys are returned. -// These keys are tagged with the "OSD" flag -// The atari/mist core does not forwards keys through the FPGA but queues them inside the arm controller. -// Keys flagged with "OSD_OPEN" are used to open the OSD in non-minimig. They can have a keycode which -// will be sent into the core - -#define OSD 0x0100 // to be used by OSD, not the core itself -#define OSD_OPEN 0x0200 // OSD key not forwarded to core, but queued in arm controller -#define CAPS_LOCK_TOGGLE 0x0400 // caps lock toggle behaviour -#define NUM_LOCK_TOGGLE 0x0800 -#define EXT 0x1000 // extended PS/2 keycode - -// amiga unmapped: -// 0x5a KP-( (mapped on Keyrah) -// 0x5b KP-) (mapped on Keyrah) -// codes >= 0x69 are for OSD only and are not sent to the amiga itself - -// keycode translation table -const unsigned short usb2ami[] = { - MISS, // 00: NoEvent - MISS, // 01: Overrun Error - MISS, // 02: POST fail - MISS, // 03: ErrorUndefined - 0x20, // 04: a - 0x35, // 05: b - 0x33, // 06: c - 0x22, // 07: d - 0x12, // 08: e - 0x23, // 09: f - 0x24, // 0a: g - 0x25, // 0b: h - 0x17, // 0c: i - 0x26, // 0d: j - 0x27, // 0e: k - 0x28, // 0f: l - 0x37, // 10: m - 0x36, // 11: n - 0x18, // 12: o - 0x19, // 13: p - 0x10, // 14: q - 0x13, // 15: r - 0x21, // 16: s - 0x14, // 17: t - 0x16, // 18: u - 0x34, // 19: v - 0x11, // 1a: w - 0x32, // 1b: x - 0x15, // 1c: y - 0x31, // 1d: z - 0x01, // 1e: 1 - 0x02, // 1f: 2 - 0x03, // 20: 3 - 0x04, // 21: 4 - 0x05, // 22: 5 - 0x06, // 23: 6 - 0x07, // 24: 7 - 0x08, // 25: 8 - 0x09, // 26: 9 - 0x0a, // 27: 0 - 0x44, // 28: Return - 0x45, // 29: Escape - 0x41, // 2a: Backspace - 0x42, // 2b: Tab - 0x40, // 2c: Space - 0x0b, // 2d: - - 0x0c, // 2e: = - 0x1a, // 2f: [ - 0x1b, // 30: ] - 0x0d, // 31: backslash (only on us keyboards) - 0x2b, // 32: Europe 1 (only on international keyboards) - 0x29, // 33: ; - 0x2a, // 34: ' - 0x00, // 35: ` - 0x38, // 36: , - 0x39, // 37: . - 0x3a, // 38: / - 0x62 | CAPS_LOCK_TOGGLE, // 39: Caps Lock - 0x50, // 3a: F1 - 0x51, // 3b: F2 - 0x52, // 3c: F3 - 0x53, // 3d: F4 - 0x54, // 3e: F5 - 0x55, // 3f: F6 - 0x56, // 40: F7 - 0x57, // 41: F8 - 0x58, // 42: F9 - 0x59, // 43: F10 - 0x5f, // 44: F11 - OSD_OPEN, // 45: F12 (OSD) - 0x6e | OSD, // 46: Print Screen (OSD) - NUM_LOCK_TOGGLE, // 47: Scroll Lock (OSD) - 0x6f | OSD, // 48: Pause - 0x0d, // 49: backslash to avoid panic in Germany ;) - 0x6a, // 4a: Home - 0x6c | OSD, // 4b: Page Up (OSD) - 0x46, // 4c: Delete - MISS, // 4d: End - 0x6d | OSD, // 4e: Page Down (OSD) - 0x4e, // 4f: Right Arrow - 0x4f, // 50: Left Arrow - 0x4d, // 51: Down Arrow - 0x4c, // 52: Up Arrow - NUM_LOCK_TOGGLE, // 53: Num Lock - 0x5c, // 54: KP / - 0x5d, // 55: KP * - 0x4a, // 56: KP - - 0x5e, // 57: KP + - 0x43, // 58: KP Enter - 0x1d, // 59: KP 1 - 0x1e, // 5a: KP 2 - 0x1f, // 5b: KP 3 - 0x2d, // 5c: KP 4 - 0x2e, // 5d: KP 5 - 0x2f, // 5e: KP 6 - 0x3d, // 5f: KP 7 - 0x3e, // 60: KP 8 - 0x3f, // 61: KP 9 - 0x0f, // 62: KP 0 - 0x3c, // 63: KP . - 0x30, // 64: Europe 2 - 0x69 | OSD, // 65: App - MISS, // 66: Power - MISS, // 67: KP = - 0x5a, // 68: KP ( - 0x5b, // 69: KP ) - MISS, // 6a: F15 - 0x5f, // 6b: help (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 -}; - -// 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 -}; - -// keycode translation table for ps2 emulation -const unsigned short usb2ps2[] = { - MISS, // 00: NoEvent - MISS, // 01: Overrun Error - MISS, // 02: POST fail - MISS, // 03: ErrorUndefined - 0x1c, // 04: a - 0x32, // 05: b - 0x21, // 06: c - 0x23, // 07: d - 0x24, // 08: e - 0x2b, // 09: f - 0x34, // 0a: g - 0x33, // 0b: h - 0x43, // 0c: i - 0x3b, // 0d: j - 0x42, // 0e: k - 0x4b, // 0f: l - 0x3a, // 10: m - 0x31, // 11: n - 0x44, // 12: o - 0x4d, // 13: p - 0x15, // 14: q - 0x2d, // 15: r - 0x1b, // 16: s - 0x2c, // 17: t - 0x3c, // 18: u - 0x2a, // 19: v - 0x1d, // 1a: w - 0x22, // 1b: x - 0x35, // 1c: y - 0x1a, // 1d: z - 0x16, // 1e: 1 - 0x1e, // 1f: 2 - 0x26, // 20: 3 - 0x25, // 21: 4 - 0x2e, // 22: 5 - 0x36, // 23: 6 - 0x3d, // 24: 7 - 0x3e, // 25: 8 - 0x46, // 26: 9 - 0x45, // 27: 0 - 0x5a, // 28: Return - 0x76, // 29: Escape - 0x66, // 2a: Backspace - 0x0d, // 2b: Tab - 0x29, // 2c: Space - 0x4e, // 2d: - - 0x55, // 2e: = - 0x54, // 2f: [ - 0x5b, // 30: ] - 0x5d, // 31: backslash - 0x5d, // 32: Europe 1 - 0x4c, // 33: ; - 0x52, // 34: ' - 0x0e, // 35: ` - 0x41, // 36: , - 0x49, // 37: . - 0x4a, // 38: / - 0x58, // 39: Caps Lock - 0x05, // 3a: F1 - 0x06, // 3b: F2 - 0x04, // 3c: F3 - 0x0c, // 3d: F4 - 0x03, // 3e: F5 - 0x0b, // 3f: F6 - 0x83, // 40: F7 - 0x0a, // 41: F8 - 0x01, // 42: F9 - 0x09, // 43: F10 - 0x78, // 44: F11 - OSD_OPEN | 0x07, // 45: F12 (OSD) - EXT | 0x7c, // 46: Print Screen - NUM_LOCK_TOGGLE, // 47: Scroll Lock - 0x77, // 48: Pause (special key handled inside user_io) - EXT | 0x70, // 49: Insert - EXT | 0x6c, // 4a: Home - EXT | 0x7d, // 4b: Page Up - EXT | 0x71, // 4c: Delete - EXT | 0x69, // 4d: End - EXT | 0x7a, // 4e: Page Down - EXT | 0x74, // 4f: Right Arrow - EXT | 0x6b, // 50: Left Arrow - EXT | 0x72, // 51: Down Arrow - EXT | 0x75, // 52: Up Arrow - NUM_LOCK_TOGGLE, // 53: Num Lock - EXT | 0x4a, // 54: KP / - 0x7c, // 55: KP * - 0x7b, // 56: KP - - 0x79, // 57: KP + - EXT | 0x5a, // 58: KP Enter - 0x69, // 59: KP 1 - 0x72, // 5a: KP 2 - 0x7a, // 5b: KP 3 - 0x6b, // 5c: KP 4 - 0x73, // 5d: KP 5 - 0x74, // 5e: KP 6 - 0x6c, // 5f: KP 7 - 0x75, // 60: KP 8 - 0x7d, // 61: KP 9 - 0x70, // 62: KP 0 - 0x71, // 63: KP . - 0x61, // 64: Europe 2 - OSD_OPEN | EXT | 0x2f, // 65: App - EXT | 0x37, // 66: Power - 0x0f, // 67: KP = - 0x77, // 68: Num Lock - 0x7e, // 69: Scroll Lock - 0x18, // 6a: F15 - EXT | 0x70, // 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 -}; - -// Archimedes unmapped keys -// Missing sterling -// Missing kp_hash -// Missing button_1 -// Missing button_2 -// Missing button_3 -// Missing button_4 -// Missing button_5 - -// keycode translation table -const unsigned short usb2archie[] = { - MISS, // 00: NoEvent - MISS, // 01: Overrun Error - MISS, // 02: POST fail - MISS, // 03: ErrorUndefined - 0x3c, // 04: a - 0x52, // 05: b - 0x50, // 06: c - 0x3e, // 07: d - 0x29, // 08: e - 0x3f, // 09: f - 0x40, // 0a: g - 0x41, // 0b: h - 0x2e, // 0c: i - 0x42, // 0d: j - 0x43, // 0e: k - 0x44, // 0f: l - 0x54, // 10: m - 0x53, // 11: n - 0x2f, // 12: o - 0x30, // 13: p - 0x27, // 14: q - 0x2a, // 15: r - 0x3d, // 16: s - 0x2b, // 17: t - 0x2d, // 18: u - 0x51, // 19: v - 0x28, // 1a: w - 0x4f, // 1b: x - 0x2c, // 1c: y - 0x4e, // 1d: z - 0x11, // 1e: 1 - 0x12, // 1f: 2 - 0x13, // 20: 3 - 0x14, // 21: 4 - 0x15, // 22: 5 - 0x16, // 23: 6 - 0x17, // 24: 7 - 0x18, // 25: 8 - 0x19, // 26: 9 - 0x1a, // 27: 0 - 0x47, // 28: Return - 0x00, // 29: Escape - 0x1e, // 2a: Backspace - 0x26, // 2b: Tab - 0x5f, // 2c: Space - 0x1b, // 2d: - - 0x1c, // 2e: = - 0x31, // 2f: [ - 0x32, // 30: ] - 0x33, // 31: backslash (only on us keyboards) - 0x33, // 32: Europe 1 (only on international kbds) - 0x45, // 33: ; - 0x46, // 34: ' - 0x10, // 35: ` - 0x55, // 36: , - 0x56, // 37: . - 0x57, // 38: / - 0x5d, // 39: Caps Lock - 0x01, // 3a: F1 - 0x02, // 3b: F2 - 0x03, // 3c: F3 - 0x04, // 3d: F4 - 0x05, // 3e: F5 - 0x06, // 3f: F6 - 0x07, // 40: F7 - 0x08, // 41: F8 - 0x09, // 42: F9 - 0x0a, // 43: F10 - 0x0b, // 44: F11 - 0x0c, // 45: F12 - Used heavily by the archie... OSD moved to printscreen. - // 0x0d, // 46: Print Screen - OSD_OPEN, // 46: Print Screen - 0x0e, // 47: Scroll Lock - 0x0f, // 48: Pause - 0x1f, // 49: Insert - 0x20, // 4a: Home - 0x21, // 4b: Page Up - 0x34, // 4c: Delete - 0x35, // 4d: End - 0x36, // 4e: Page Down - 0x64, // 4f: Right Arrow - 0x62, // 50: Left Arrow - 0x63, // 51: Down Arrow - 0x59, // 52: Up Arrow - 0x22, // 53: Num Lock - 0x23, // 54: KP / - 0x24, // 55: KP * - 0x3a, // 56: KP - - 0x4b, // 57: KP + - 0x67, // 58: KP Enter - 0x5a, // 59: KP 1 - 0x5b, // 5a: KP 2 - 0x5c, // 5b: KP 3 - 0x48, // 5c: KP 4 - 0x49, // 5d: KP 5 - 0x4a, // 5e: KP 6 - 0x37, // 5f: KP 7 - 0x38, // 60: KP 8 - 0x39, // 61: KP 9 - 0x65, // 62: KP 0 - 0x66, // 63: KP decimal - MISS, // 64: Europe 2 - 0x72, // 65: App (maps to middle mouse button) - MISS, // 66: Power - MISS, // 67: KP = - MISS, // 68: F13 - MISS, // 69: F14 - MISS, // 6a: F15 - 0x1f, // 6b: insert (for keyrah) - MISS, // 6c: F17 - MISS, // 6d: F18 - MISS, // 6e: F19 - MISS, // 6f: F20 -}; - -#endif diff --git a/main.c b/main.c index 756edfe..f63020c 100644 --- a/main.c +++ b/main.c @@ -86,8 +86,6 @@ void core_init() int main(int argc, char *argv[]) { - uint8_t mmc_ok = 0; - fpga_io_init(); fpga_gpo_write(0); diff --git a/menu.c b/menu.c index f742bdc..421a42d 100644 --- a/menu.c +++ b/menu.c @@ -46,6 +46,7 @@ along with this program. If not, see . #include #include "mist_cfg.h" #include "input.h" +#include "x86.h" /*menu states*/ enum MENU @@ -269,7 +270,7 @@ static void SelectFile(char* pFileExt, unsigned char Options, unsigned char Menu iprintf("%s - %s\n", pFileExt, fs_pFileExt); AdjustDirectory(SelectedPath); - if (strncmp(pFileExt, fs_pFileExt, 12) != 0) // check desired file extension + if (strncmp(pFileExt, fs_pFileExt, 12) != 0 || !strlen(SelectedPath)) // check desired file extension { // if different from the current one go to the root directory and init entry buffer SelectedPath[0] = 0; @@ -415,52 +416,42 @@ const uint8_t keycode_table[128] = 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }; -static uint8_t GetASCIIKey(unsigned char keycode) +static uint8_t GetASCIIKey(uint32_t keycode) { - if (keycode & KEY_AMI_UPSTROKE) + if (keycode & UPSTROKE) return 0; - return keycode_table[keycode & 0x7F]; + return keycode_table[get_amiga_code(keycode & 0xFFFF) & 0x7F]; } /* the Atari core handles OSD keys competely inside the core */ -static unsigned char menu_key = 0; -static unsigned char menu_mod = 0; +static uint32_t menu_key = 0; -void menu_key_set(unsigned char c) +void menu_key_set(uint32_t c) { - //iprintf("OSD enqueue: %x\n", c); + //printf("OSD enqueue: %x\n", c); menu_key = c; } -void menu_mod_set(uint8_t m) -{ - menu_mod = m; -} - // get key status -static uint8_t menu_key_get(void) +static uint32_t menu_key_get(void) { - static unsigned char c2; + static uint32_t c2; static unsigned long delay; static unsigned long repeat; static unsigned char repeat2; - unsigned char c1, c; + uint32_t c1, c; c1 = menu_key; - - // OsdKeyGet permanently returns the last key event. - - // generate normal "key-pressed" event c = 0; if (c1 != c2) c = c1; c2 = c1; // inject a fake "MENU_KEY" if no menu is visible and the menu key is loaded - if (!user_io_osd_is_visible() && is_menu_core()) c = KEY_AMI_MENU; + if (!user_io_osd_is_visible() && is_menu_core()) c = KEY_F12; // generate repeat "key-pressed" events - if ((c1 & KEY_AMI_UPSTROKE) || (!c1)) + if ((c1 & UPSTROKE) || (!c1)) { repeat = GetTimer(REPEATDELAY); } @@ -475,10 +466,9 @@ static uint8_t menu_key_get(void) { static unsigned char last_but = 0; unsigned char but = user_io_menu_button(); - if (!but && last_but) c = KEY_AMI_MENU; + if (!but && last_but) c = KEY_F12; last_but = but; } - return(c); } @@ -486,7 +476,7 @@ void HandleUI(void) { char *p; char s[40]; - unsigned char i, c, m, up, down, select, menu, right, left, plus, minus; + unsigned char i, m, up, down, select, menu, right, left, plus, minus; uint8_t mod; unsigned long len; static hardfileTYPE t_hardfile[2]; // temporary copy of former hardfile configuration @@ -502,7 +492,7 @@ void HandleUI(void) char usb_id[64]; // get user control codes - c = menu_key_get(); + uint32_t c = menu_key_get(); // decode and set events menu = false; @@ -516,9 +506,9 @@ void HandleUI(void) switch (c) { - case KEY_AMI_MENU: + case KEY_F12: menu = true; - menu_key_set(KEY_AMI_MENU | KEY_AMI_UPSTROKE); + menu_key_set(KEY_F12 | UPSTROKE); break; // Within the menu the esc key acts as the menu key. problem: @@ -526,35 +516,35 @@ void HandleUI(void) // break code for the ESC key when the key is released will // reach the core which never saw the make code. Simple solution: // react on break code instead of make code - case KEY_AMI_ESC | KEY_AMI_UPSTROKE: + case KEY_ESC | UPSTROKE: if (menustate != MENU_NONE2) menu = true; break; - case KEY_AMI_ENTER: - case KEY_AMI_SPACE: + case KEY_ENTER: + case KEY_SPACE: select = true; break; - case KEY_AMI_UP: + case KEY_UP: up = true; break; - case KEY_AMI_DOWN: + case KEY_DOWN: down = true; break; - case KEY_AMI_LEFT: + case KEY_LEFT: left = true; break; - case KEY_AMI_RIGHT: + case KEY_RIGHT: right = true; break; - case KEY_AMI_KPPLUS: - case 0x0c: // =/+ + case KEY_KPPLUS: + case KEY_EQUAL: // =/+ plus = true; break; - case KEY_AMI_KPMINUS: - case 0x0b: // -/_ + case KEY_KPMINUS: + case KEY_MINUS: // -/_ minus = true; break; - +/* case 0x01: // 1: 1280x720 mode if (user_io_osd_is_visible) mist_cfg.video_mode = 0; break; @@ -562,6 +552,7 @@ void HandleUI(void) case 0x02: // 2: 1280x1024 mode if (user_io_osd_is_visible) mist_cfg.video_mode = 1; break; +*/ } if (menu || select || up || down || left || right) @@ -633,7 +624,7 @@ void HandleUI(void) case MENU_NONE2: if (menu) { - if (menu_mod & 0x44) //Alt+Menu + if (get_key_mod() & (LALT|RALT)) //Alt+Menu { OsdSetSize(16); SelectFile("RBF", 0, MENU_FIRMWARE_CORE_FILE_SELECTED, MENU_NONE1, 0); @@ -818,7 +809,11 @@ void HandleUI(void) } // check for 'O'ption strings - if (p && (p[0] == 'O')) { + if (p && (p[0] == 'O')) + { + //option handled by ARM + if (p[1] == 'X') p++; + unsigned long x = getStatus(p, status); // get currently active option @@ -955,15 +950,26 @@ void HandleUI(void) static char ext[13]; substrcpy(ext, p, 1); while (strlen(ext) < 3) strcat(ext, " "); - SelectFile(ext, SCAN_DIR, + SelectFile(ext, SCAN_DIR | ((p[0] == 'S') ? SCAN_UMOUNT : 0), (p[0] == 'F') ? MENU_8BIT_MAIN_FILE_SELECTED : MENU_8BIT_MAIN_IMAGE_SELECTED, MENU_8BIT_MAIN1, 1); } else if (p[0] == 'O') { + int byarm = 0; + if (p[1] == 'X') + { + byarm = 1; + p++; + } + unsigned long status = user_io_8bit_set_status(0, 0); // 0,0 gets status unsigned long x = getStatus(p, status) + 1; + if (byarm && is_x86_core()) + { + if (p[1] == '2') x86_set_fdd_boot(!(x&1)); + } // check if next value available substrcpy(s, p, 2 + x); if (!strlen(s)) x = 0; @@ -976,12 +982,20 @@ void HandleUI(void) { // determine which status bit is affected unsigned long mask = 1 << getIdx(p); - unsigned long status = user_io_8bit_set_status(0, 0); + if (mask == 1 && is_x86_core()) + { + x86_init(); + menustate = MENU_NONE1; + } + else + { + unsigned long status = user_io_8bit_set_status(0, 0); - user_io_8bit_set_status(status ^ mask, mask); - user_io_8bit_set_status(status, mask); + user_io_8bit_set_status(status ^ mask, mask); + user_io_8bit_set_status(status, mask); + menustate = MENU_8BIT_MAIN1; + } - menustate = MENU_8BIT_MAIN1; } } } @@ -1000,9 +1014,16 @@ void HandleUI(void) case MENU_8BIT_MAIN_IMAGE_SELECTED: iprintf("Image selected: %s\n", SelectedPath); - user_io_set_index(user_io_ext_idx(SelectedPath, fs_pFileExt) << 6 | (menusub + 1)); - user_io_file_mount(drive_num, SelectedPath); - menustate = MENU_NONE1; + if (is_x86_core()) + { + x86_set_image(drive_num, SelectedPath); + } + else + { + user_io_set_index(user_io_ext_idx(SelectedPath, fs_pFileExt) << 6 | (menusub + 1)); + user_io_file_mount(drive_num, SelectedPath); + } + menustate = SelectedPath[0] ? MENU_NONE1 : MENU_8BIT_MAIN1; break; case MENU_8BIT_SYSTEM1: @@ -1079,6 +1100,7 @@ void HandleUI(void) unsigned long status = user_io_8bit_set_status(0, 0); iprintf("Saving config to %s\n", filename); FileSaveConfig(filename, &status, 4); + if (is_x86_core()) x86_config_save(); menustate = MENU_8BIT_MAIN1; menusub = 0; } @@ -1832,7 +1854,7 @@ void HandleUI(void) else if (menusub == 11) menustate = MENU_NONE1; } - else if (c == KEY_AMI_BACK) // eject all floppies + else if (c == KEY_BACKSPACE) // eject all floppies { for (i = 0; i <= drives; i++) df[i].status = 0; @@ -1934,25 +1956,31 @@ void HandleUI(void) ScrollLongName(); // scrolls file name if longer than display line - if (c == KEY_AMI_HOME) + if (c == KEY_HOME) { ScanDirectory(SelectedPath, SCAN_INIT, fs_pFileExt, fs_Options); menustate = MENU_FILE_SELECT1; } - if (c == KEY_AMI_BACK) + if (c == KEY_BACKSPACE) { - changeDir(".."); - menustate = MENU_FILE_SELECT1; + if (fs_Options & SCAN_UMOUNT) + { + for (int i = 0; i < OsdGetSize() - 1; i++) OsdWrite(i, "", 0, 0); + OsdWrite(OsdGetSize() / 2, " Unmounting the image", 0, 0); + usleep(1500000); + SelectedPath[0] = 0; + menustate = fs_MenuSelect; + } } - if ((c == KEY_AMI_PGUP) || (c == KEY_AMI_LEFT)) + if ((c == KEY_PAGEUP) || (c == KEY_LEFT)) { ScanDirectory(SelectedPath, SCAN_PREV_PAGE, fs_pFileExt, fs_Options); menustate = MENU_FILE_SELECT1; } - if ((c == KEY_AMI_PGDN) || (c == KEY_AMI_RIGHT)) + if ((c == KEY_PAGEDOWN) || (c == KEY_RIGHT)) { ScanDirectory(SelectedPath, SCAN_NEXT_PAGE, fs_pFileExt, fs_Options); menustate = MENU_FILE_SELECT1; diff --git a/menu.h b/menu.h index 0493542..82ccf09 100644 --- a/menu.h +++ b/menu.h @@ -3,23 +3,6 @@ #include "fdd.h" // for adfTYPE definition -#define KEY_AMI_UPSTROKE 0x80 -#define KEY_AMI_MENU 0x69 -#define KEY_AMI_PGUP 0x6C -#define KEY_AMI_PGDN 0x6D -#define KEY_AMI_HOME 0x6A -#define KEY_AMI_ESC 0x45 -#define KEY_AMI_KPENTER 0x43 -#define KEY_AMI_ENTER 0x44 -#define KEY_AMI_BACK 0x41 -#define KEY_AMI_SPACE 0x40 -#define KEY_AMI_UP 0x4C -#define KEY_AMI_DOWN 0x4D -#define KEY_AMI_LEFT 0x4F -#define KEY_AMI_RIGHT 0x4E -#define KEY_AMI_KPPLUS 0x5E -#define KEY_AMI_KPMINUS 0x4A - // UI strings, used by boot messages extern const char *config_filter_msg[]; extern const char *config_memory_chip_msg[]; @@ -40,7 +23,9 @@ void ShowSplash(); void HideSplash(); void EjectAllFloppies(); -void menu_key_set(unsigned char c); -void menu_mod_set(uint8_t m); +unsigned long getStatus(char *opt, unsigned long status); + +void menu_key_set(uint32_t c); +void menu_mod_set(uint32_t m); #endif diff --git a/releases/MiSTer_20170803 b/releases/MiSTer_20170803 new file mode 100644 index 0000000..9e3ec1d Binary files /dev/null and b/releases/MiSTer_20170803 differ diff --git a/releases/MiSTer_20170805 b/releases/MiSTer_20170805 new file mode 100644 index 0000000..4695002 Binary files /dev/null and b/releases/MiSTer_20170805 differ diff --git a/releases/MiSTer_20170806 b/releases/MiSTer_20170806 new file mode 100644 index 0000000..5bc7479 Binary files /dev/null and b/releases/MiSTer_20170806 differ diff --git a/spi.c b/spi.c index d2e831a..ed2d166 100644 --- a/spi.c +++ b/spi.c @@ -132,6 +132,14 @@ void spi32(uint32_t parm) spi8(parm >> 0); } +uint32_t spi32w(uint32_t parm) +{ + uint32_t res; + res = spi_w(parm); + res |= (spi_w(parm>>16))<<16; + return res; +} + // little endian: lsb first void spi32le(uint32_t parm) { diff --git a/spi.h b/spi.h index 35414a7..26ff901 100644 --- a/spi.h +++ b/spi.h @@ -29,6 +29,7 @@ void spi24(uint32_t parm); void spi32(uint32_t parm); void spi32le(uint32_t parm); void spi_n(uint8_t value, uint16_t cnt); +uint32_t spi32w(uint32_t parm); /* block transfer functions */ void spi_block_read(uint8_t *addr, int wide); diff --git a/user_io.c b/user_io.c index 80b36a4..ea64742 100644 --- a/user_io.c +++ b/user_io.c @@ -10,7 +10,6 @@ #include "user_io.h" #include "archie.h" #include "debug.h" -#include "keycodes.h" #include "ikbd.h" #include "spi.h" #include "mist_cfg.h" @@ -20,6 +19,7 @@ #include "file_io.h" #include "config.h" #include "menu.h" +#include "x86.h" #define BREAK 0x8000 @@ -133,9 +133,17 @@ char is_menu_core() return (is_menu_type == 1); } +static int is_x86_type = 0; +char is_x86_core() +{ + if (!is_x86_type) is_x86_type = strcasecmp(core_name, "AO486") ? 2 : 1; + return (is_x86_type == 1); +} + static void user_io_read_core_name() { is_menu_type = 0; + is_x86_type = 0; core_name[0] = 0; if (user_io_is_8bit_with_config_string()) @@ -172,12 +180,6 @@ static int joy_force = 0; static void parse_config() { - // check if core has a config string - core_type_8bit_with_config_string = (user_io_8bit_get_string(0) != NULL); - - // set core name. This currently only sets a name for the 8 bit cores - user_io_read_core_name(); - joy_force = 0; if (core_type_8bit_with_config_string) { @@ -194,6 +196,19 @@ static void parse_config() input_notify_mode(); set_kbd_led(HID_LED_NUM_LOCK, true); } + + if (p[0] == 'O' && p[1] == 'X') + { + unsigned long status = user_io_8bit_set_status(0, 0); + printf("found OX option: %s, 0x%08X\n", p, status); + + unsigned long x = getStatus(p+1, status); + + if (is_x86_core()) + { + if (p[2] == '2') x86_set_fdd_boot(!(x&1)); + } + } } i++; } while (p); @@ -258,8 +273,11 @@ void user_io_detect_core_type() // forward SD card config to core in case it uses the local // SD card implementation user_io_sd_set_config(); + // check if core has a config string + core_type_8bit_with_config_string = (user_io_8bit_get_string(0) != NULL); - parse_config(); + // set core name. This currently only sets a name for the 8 bit cores + user_io_read_core_name(); // send a reset user_io_8bit_set_status(UIO_STATUS_RESET, UIO_STATUS_RESET); @@ -275,22 +293,49 @@ void user_io_detect_core_type() iprintf("Found config\n"); user_io_8bit_set_status(status, 0xffffffff); } + parse_config(); - // check if there's a .rom present - sprintf(mainpath, "%s/boot.rom", user_io_get_core_name()); - if (!user_io_file_tx(mainpath, 0)) + if (is_x86_core()) { - strcpy(name + strlen(name) - 3, "ROM"); - user_io_file_tx(name, 0); + x86_config_load(); + x86_init(); } - - // check if there's a .vhd present - sprintf(mainpath, "%s/boot.vhd", user_io_get_core_name()); - user_io_set_index(0); - if (!user_io_file_mount(0, mainpath)) + else { - strcpy(name + strlen(name) - 3, "VHD"); - user_io_file_mount(0, name); + // check for multipart rom + sprintf(mainpath, "%s/boot0.rom", user_io_get_core_name()); + if (user_io_file_tx(mainpath, 0)) + { + sprintf(mainpath, "%s/boot1.rom", user_io_get_core_name()); + if (user_io_file_tx(mainpath, 0x40)) + { + sprintf(mainpath, "%s/boot2.rom", user_io_get_core_name()); + if (user_io_file_tx(mainpath, 0x80)) + { + sprintf(mainpath, "%s/boot3.rom", user_io_get_core_name()); + user_io_file_tx(mainpath, 0xC0); + } + } + } + else + { + // legacy style of rom + sprintf(mainpath, "%s/boot.rom", user_io_get_core_name()); + if (!user_io_file_tx(mainpath, 0)) + { + strcpy(name + strlen(name) - 3, "ROM"); + user_io_file_tx(name, 0); + } + } + + // check if there's a .vhd present + sprintf(mainpath, "%s/boot.vhd", user_io_get_core_name()); + user_io_set_index(0); + if (!user_io_file_mount(0, mainpath)) + { + strcpy(name + strlen(name) - 3, "VHD"); + user_io_file_mount(0, name); + } } } @@ -300,28 +345,6 @@ void user_io_detect_core_type() } } -unsigned short usb2amiga(unsigned char k) -{ - // replace MENU key by RGUI to allow using Right Amiga on reduced keyboards - // (it also disables the use of Menu for OSD) - if (mist_cfg.key_menu_as_rgui && k == 0x65) - { - return 0x67; - } - return usb2ami[k]; -} - -unsigned short usb2ps2code(unsigned char k) -{ - // replace MENU key by RGUI e.g. to allow using RGUI on reduced keyboards without physical key - // (it also disables the use of Menu for OSD) - if (mist_cfg.key_menu_as_rgui && k == 0x65) - { - return EXT | 0x27; - } - return usb2ps2[k]; -} - void user_io_analog_joystick(unsigned char joystick, char valueX, char valueY) { if (core_type == CORE_TYPE_8BIT) @@ -456,17 +479,36 @@ uint16_t user_io_sd_get_status(uint32_t *lba) } // read 8 bit keyboard LEDs status from FPGA -uint8_t user_io_kbdled_get_status(void) +uint16_t user_io_kbdled_get_status(void) { - uint8_t c; + uint16_t c; spi_uio_cmd_cont(UIO_GET_KBD_LED); - c = spi_in(); + c = spi_w(0); DisableIO(); return c; } +uint8_t user_io_ps2_ctl(uint8_t *kbd_ctl, uint8_t *mouse_ctl) +{ + uint16_t c; + uint8_t res = 0; + + spi_uio_cmd_cont(UIO_PS2_CTL); + + c = spi_w(0); + if (kbd_ctl) *kbd_ctl = (uint8_t)c; + res |= ((c >> 8) & 1); + + c = spi_w(0); + if (mouse_ctl) *mouse_ctl = (uint8_t)c; + res |= ((c >> 7) & 2); + + DisableIO(); + return res; +} + // read 32 bit ethernet status word from FPGA uint32_t user_io_eth_get_status(void) { @@ -635,7 +677,7 @@ int user_io_file_tx(char* name, unsigned char index) spi8(0x00); DisableFpga(); - iprintf("\n"); + printf("\n"); return 1; } @@ -731,6 +773,7 @@ void user_io_send_buttons(char force) key_map = map; spi_uio_cmd8(UIO_BUT_SW, map); printf("sending keymap: %X\n", map); + if ((key_map & BUTTON2) && is_x86_core) x86_init(); } if (old_video_mode != mist_cfg.video_mode) @@ -749,6 +792,20 @@ void __inline diskled_on() diskled_is_on = 1; } +void kbd_reply(char code) +{ + printf("kbd_reply = 0x%02X\n", code); + spi_uio_cmd8(UIO_KEYBOARD, code); +} + +void mouse_reply(char code) +{ + printf("mouse_reply = 0x%02X\n", code); + spi_uio_cmd8(UIO_MOUSE, code); +} + +static uint8_t use_ps2ctl = 0; + void user_io_poll() { if ((core_type != CORE_TYPE_MINIMIG2) && @@ -845,10 +902,10 @@ void user_io_poll() if (core_type == CORE_TYPE_8BIT) { + /* 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); @@ -869,8 +926,14 @@ void user_io_poll() iprintf("\033[0m"); } DisableIO(); + */ // sd card emulation + if (is_x86_core()) + { + x86_poll(); + } + else { static char buffer[4][512]; static uint64_t buffer_lba[4] = { -1,-1,-1,-1 }; @@ -1141,10 +1204,140 @@ void user_io_poll() if (core_type == CORE_TYPE_ARCHIE) archie_poll(); + static uint8_t leds = 0; + if(use_ps2ctl) + { + leds |= (KBD_LED_FLAG_STATUS | KBD_LED_CAPS_CONTROL); + + uint8_t kbd_ctl, mouse_ctl; + uint8_t ps2ctl = user_io_ps2_ctl(&kbd_ctl, &mouse_ctl); + + if (ps2ctl & 1) + { + static uint8_t cmd = 0; + static uint8_t byte = 0; + + printf("kbd_ctl = 0x%02X\n", kbd_ctl); + if (!byte) + { + cmd = kbd_ctl; + switch (cmd) + { + case 0xff: + kbd_reply(0xFA); + kbd_reply(0xAA); + break; + + case 0xf4: + case 0xf5: + case 0xfa: + kbd_reply(0xFA); + break; + + case 0xed: + kbd_reply(0xFA); + byte++; + break; + + default: + kbd_reply(0xFE); + break; + } + } + else + { + switch (cmd) + { + case 0xed: + kbd_reply(0xFA); + byte = 0; + + if (kbd_ctl & 4) leds |= KBD_LED_CAPS_STATUS; + else leds &= ~KBD_LED_CAPS_STATUS; + + break; + + default: + byte = 0; + break; + } + } + } + + if (ps2ctl & 2) + { + static uint8_t cmd = 0; + static uint8_t byte = 0; + + printf("mouse_ctl = 0x%02X\n", mouse_ctl); + if (!byte) + { + cmd = mouse_ctl; + switch (cmd) + { + case 0xe8: + case 0xf3: + mouse_reply(0xFA); + byte++; + break; + + case 0xf2: + mouse_reply(0xFA); + mouse_reply(0x00); + break; + + case 0xe6: + case 0xf4: + case 0xf5: + mouse_reply(0xFA); + break; + + case 0xe9: + mouse_reply(0xFA); + mouse_reply(0x00); + mouse_reply(0x00); + mouse_reply(0x00); + break; + + case 0xff: + mouse_reply(0xFA); + mouse_reply(0xAA); + mouse_reply(0x00); + break; + + default: + mouse_reply(0xFE); + break; + } + } + else + { + switch (cmd) + { + case 0xf3: + case 0xe8: + mouse_reply(0xFA); + byte = 0; + break; + + default: + byte = 0; + break; + } + } + } + } + if (CheckTimer(led_timer)) { led_timer = GetTimer(LED_FREQ); - uint8_t leds = user_io_kbdled_get_status(); + if (!use_ps2ctl) + { + uint16_t s = user_io_kbdled_get_status(); + if(s & 0x100) use_ps2ctl = 1; + if (!use_ps2ctl) leds = (uint8_t)s; + } + if ((leds & KBD_LED_FLAG_MASK) != KBD_LED_FLAG_STATUS) leds = 0; if ((keyboard_leds & KBD_LED_CAPS_MASK) != (leds & KBD_LED_CAPS_MASK)) @@ -1175,12 +1368,36 @@ char user_io_user_button() return((!user_io_menu_button() && (fpga_get_buttons() & BUTTON_USR)) ? 1 : 0); } -static void send_keycode(unsigned short code) +static void send_keycode(unsigned short key, int press) { if (core_type == CORE_TYPE_MINIMIG2) { - // amiga has "break" marker in msb - if (code & BREAK) code = (code & 0xff) | 0x80; + if (press > 1) return; + + uint32_t code = get_amiga_code(key); + if (code == NONE) return; + + if (code & CAPS_TOGGLE) + { + if (press = 1) + { + // send alternating make and break codes for caps lock + if(caps_lock_toggle) code |= 0x80; + caps_lock_toggle = !caps_lock_toggle; + set_kbd_led(HID_LED_CAPS_LOCK, caps_lock_toggle); + } + else + { + return; + } + } + else + { + // amiga has "break" marker in msb + if (!press) code |= 0x80; + } + + code &= 0xff; // send immediately if possible if (CheckTimer(kbd_timer) && (kbd_fifo_w == kbd_fifo_r)) @@ -1191,67 +1408,109 @@ static void send_keycode(unsigned short code) { kbd_fifo_enqueue(code); } + 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 (code & BREAK) code = (code & 0xff) | 0x80; + if (!press) code = (code & 0xff) | 0x80; ikbd_keyboard(code); + return; } if (core_type == CORE_TYPE_8BIT) { - // send ps2 keycodes for those cores that prefer ps2 - spi_uio_cmd_cont(UIO_KEYBOARD); + uint32_t code = get_ps2_code(key); + if (code == NONE) return; - // "pause" has a complex code - if ((code & 0xff) == 0x77) + //pause + if ((code & 0xff) == 0xE1) { // pause does not have a break code - if (!(code & BREAK)) + if (press != 1) { // Pause key sends E11477E1F014E077 - static const unsigned char c[] = { - 0xe1, 0x14, 0x77, 0xe1, 0xf0, 0x14, 0xf0, 0x77, 0x00 }; + static const unsigned char c[] = { 0xe1, 0x14, 0x77, 0xe1, 0xf0, 0x14, 0xf0, 0x77, 0x00 }; const unsigned char *p = c; - iprintf("PS2 KBD "); + spi_uio_cmd_cont(UIO_KEYBOARD); + + printf("PS2 PAUSE CODE: "); while (*p) { - iprintf("%x ", *p); + printf("%x ", *p); spi8(*p++); } - iprintf("\n"); + printf("\n"); + + DisableIO(); + } + } + // print screen + else if ((code & 0xff) == 0xE2) + { + if (press <= 1) + { + static const unsigned char c[2][8] = { + { 0xE0, 0xF0, 0x7C, 0xE0, 0xF0, 0x12, 0x00, 0x00 }, + { 0xE0, 0x12, 0xE0, 0x7C, 0x00, 0x00, 0x00, 0x00 } + }; + + const unsigned char *p = c[press]; + + spi_uio_cmd_cont(UIO_KEYBOARD); + + printf("PS2 PRINT CODE: "); + while (*p) + { + printf("%x ", *p); + spi8(*p++); + } + printf("\n"); + + DisableIO(); } } else { - /* - iprintf("PS2 KBD "); - if (code & EXT) iprintf("e0 "); - if (code & BREAK) iprintf("f0 "); - iprintf("%x\n", code & 0xff); - */ + if (press > 1 && !use_ps2ctl) return; + + spi_uio_cmd_cont(UIO_KEYBOARD); // prepend extended code flag if required if (code & EXT) spi8(0xe0); // prepend break code if required - if (code & BREAK) spi8(0xf0); + if (!press) spi8(0xf0); // send code itself spi8(code & 0xff); - } - DisableIO(); + DisableIO(); + } } - if (core_type == CORE_TYPE_ARCHIE) archie_kbd(code); + if (core_type == CORE_TYPE_ARCHIE) + { + if (press > 1) return; + + uint32_t code = get_archie_code(key); + if (code == NONE) return; + + archie_kbd(code); + } } void user_io_mouse(unsigned char b, int16_t x, int16_t y) { + if (osd_is_visible) return; + // send mouse data as minimig expects it if (core_type == CORE_TYPE_MINIMIG2) { @@ -1282,19 +1541,6 @@ LCTRL LSHIFT LALT LGUI RCTRL RSHIFT RALT RGUI #define EMU_BTN3 (2+(keyrah*4)) // left alt #define EMU_BTN4 (3+(keyrah*4)) // left gui (usually windows key) -unsigned short keycode(unsigned char in) -{ - if (core_type == CORE_TYPE_MINIMIG2) return usb2amiga(in); - - // atari st and the 8 bit core (currently only used for atari 800) - // use the same key codes - if (core_type == CORE_TYPE_MIST) return usb2atari[in]; - if (core_type == CORE_TYPE_ARCHIE) return usb2archie[in]; - if (core_type == CORE_TYPE_8BIT) return usb2ps2code(in); - - return MISS; -} - extern configTYPE config; void user_io_check_reset(unsigned short modifiers, char useKeys) @@ -1332,58 +1578,19 @@ void user_io_check_reset(unsigned short modifiers, char useKeys) } } -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_MINIMIG2) - { - static const unsigned short amiga_modifier[] = { 0x63, 0x60, 0x64, 0x66, 0x63, 0x61, 0x65, 0x67 }; - return amiga_modifier[index]; - } - - if (core_type == CORE_TYPE_MIST) - { - static const unsigned short atari_modifier[] = { 0x1d, 0x2a, 0x38, MISS, 0x1d, 0x36, 0x38, MISS }; - return atari_modifier[index]; - } - - if (core_type == CORE_TYPE_8BIT) - { - static const unsigned short ps2_modifier[] = { 0x14, 0x12, 0x11, EXT | 0x1f, EXT | 0x14, 0x59, EXT | 0x11, EXT | 0x27 }; - return ps2_modifier[index]; - } - - if (core_type == CORE_TYPE_ARCHIE) - { - static const unsigned short archie_modifier[] = { 0x36, 0x4c, 0x5e, MISS, 0x61, 0x58, 0x60, MISS }; - return archie_modifier[index]; - } - - return MISS; -} - void user_io_osd_key_enable(char on) { iprintf("OSD is now %s\n", on ? "visible" : "invisible"); osd_is_visible = on; } -static char key_used_by_osd(unsigned short s) +static char key_used_by_osd(uint32_t s) { // this key is only used to open the OSD and has no keycode - if ((s & OSD_OPEN) && !(s & 0xff)) return true; + if (s & OSD_OPEN) return 1; // no keys are suppressed if the OSD is inactive - if (!osd_is_visible) return false; - - // in atari mode eat all keys if the OSD is online, - // else none as it's up to the core to forward keys - // to the OSD - return((core_type == CORE_TYPE_MIST) || (core_type == CORE_TYPE_ARCHIE) || (core_type == CORE_TYPE_8BIT)); + return osd_is_visible; } void user_io_kbd(uint16_t key, int press) @@ -1393,105 +1600,37 @@ void user_io_kbd(uint16_t key, int press) (core_type == CORE_TYPE_ARCHIE) || (core_type == CORE_TYPE_8BIT)) { - uint8_t m = key >> 8; - uint8_t k = key & 0xFF; - - static unsigned char modifier = 0; - - // handle modifier keys - if (m != modifier) + if (key) { - for (int i = 0; i<8; i++) - { - uint16_t code = modifier_keycode(i); - - // Do we have a downstroke on a modifier key? - if ((m & (1 << i)) && !(modifier & (1 << i))) - { - if (code != MISS) - { - if (is_menu_core()) printf("keycode(make)%s for core: %d(0x%X)\n", (code & EXT) ? "(ext)" : "", code & 255, code & 255); - if(!osd_is_visible) send_keycode(code); - } - } - - if (!(m & (1 << i)) && (modifier & (1 << i))) - { - if (code != MISS) - { - if (is_menu_core()) printf("keycode(break)%s for core: %d(0x%X)\n", (code & EXT) ? "(ext)" : "", code & 255, code & 255); - if (!osd_is_visible) send_keycode(BREAK | code); - } - } - } - - modifier = m; - } - - // check if there are keys in the pressed list which aren't - // reported anymore - if (k) - { - uint16_t code = keycode(k); + uint32_t code = get_ps2_code(key); if (!press) { - if (is_menu_core()) printf("keycode(break)%s for core: %d(0x%X)\n", (code & EXT) ? "(ext)" : "", code & 255, code & 255); + if (is_menu_core()) printf("PS2 code(break)%s for core: %d(0x%X)\n", (code & EXT) ? "(ext)" : "", code & 255, code & 255); - if (code != MISS) + if (code & OSD_OPEN) menu_key_set(UPSTROKE | KEY_F12); + else if (osd_is_visible) menu_key_set(UPSTROKE | key); + else { - if (code & OSD_OPEN) - { - menu_key_set(KEY_AMI_UPSTROKE | KEY_AMI_MENU); - } - else - { - // special OSD key handled internally - if (osd_is_visible) menu_key_set(KEY_AMI_UPSTROKE | usb2amiga(k)); - } - - if (!key_used_by_osd(code) && !(code & CAPS_LOCK_TOGGLE) && !(code & NUM_LOCK_TOGGLE)) - { - send_keycode(BREAK | code); - } + send_keycode(key, press); } } else { - if (is_menu_core()) printf("keycode(make)%s for core: %d(0x%X)\n", (code & EXT) ? "(ext)" : "", code & 255, code & 255); + if (is_menu_core()) printf("PS2 code(make)%s for core: %d(0x%X)\n", (code & EXT) ? "(ext)" : "", code & 255, code & 255); - if ((k <= KEYCODE_MAX) && code != MISS) + if (code & OSD_OPEN) { - // If OSD is visible, then all keys are sent into the OSD - // using Amiga key codes since the OSD itself uses Amiga key codes - // for historical reasons. If the OSD is invisble then only - // those keys marked for OSD in the core specific table are - // sent for OSD handling. - if (code & OSD_OPEN) + if (press == 1) menu_key_set(KEY_F12); + } + else if (osd_is_visible) + { + if (press == 1) menu_key_set(key); + } + else + { + if ((code & EMU_SWITCH_1) || ((code & EMU_SWITCH_2) && !use_ps2ctl)) { - menu_key_set(KEY_AMI_MENU); - } - else - { - // special OSD key handled internally - if (osd_is_visible) - { - menu_key_set(usb2amiga(k)); - } - } - - // no further processing of any key that is currently - // redirected to the OSD - if (!key_used_by_osd(code)) - { - if (code & CAPS_LOCK_TOGGLE) - { - // send alternating make and break codes for caps lock - send_keycode((code & 0xff) | (caps_lock_toggle ? BREAK : 0)); - caps_lock_toggle = !caps_lock_toggle; - - set_kbd_led(HID_LED_CAPS_LOCK, caps_lock_toggle); - } - else if (code & NUM_LOCK_TOGGLE) + if (press == 1) { // num lock has four states indicated by leds: // all off: normal @@ -1499,7 +1638,7 @@ void user_io_kbd(uint16_t key, int press) // num lock on, scroll lock off: joy0 emu // num lock off, scroll lock on: joy1 emu - switch (code ^ NUM_LOCK_TOGGLE) + switch (code & 0xff) { case 1: if (!joy_force) emu_mode = EMU_MOUSE; @@ -1529,10 +1668,10 @@ void user_io_kbd(uint16_t key, int press) if (emu_mode == EMU_MOUSE || emu_mode == EMU_JOY1) set_kbd_led(HID_LED_SCROLL_LOCK, true); else set_kbd_led(HID_LED_SCROLL_LOCK, false); } - else - { - send_keycode(code); - } + } + else + { + send_keycode(key, press); } } } diff --git a/user_io.h b/user_io.h index 8c3e400..ef38875 100644 --- a/user_io.h +++ b/user_io.h @@ -53,6 +53,7 @@ #define UIO_SET_STATUS2 0x1e // 32bit status #define UIO_GET_KBD_LED 0x1f // keyboard LEDs control #define UIO_SET_VIDEO 0x20 // set HDMI video mode 0: 1280x720p60(TV), 1: 1280x1024p60(PC), 2-255: reserved +#define UIO_PS2_CTL 0x21 // get PS2 control from supported cores // codes as used by 8bit (atari 800, zx81) via SS2 #define UIO_GET_STATUS 0x50 @@ -63,6 +64,11 @@ #define UIO_FILE_INDEX 0x55 #define UIO_FILE_INFO 0x56 +// ao486 direct memory access +#define UIO_DMA_WRITE 0x61 +#define UIO_DMA_READ 0x62 +#define UIO_DMA_SDIO 0x63 + #define JOY_RIGHT 0x01 #define JOY_LEFT 0x02 #define JOY_DOWN 0x04 @@ -167,6 +173,7 @@ int user_io_file_mount(int num, char *name); char *user_io_get_core_name(); char *user_io_get_core_name_ex(); char is_menu_core(); +char is_x86_core(); emu_mode_t user_io_get_kbdemu(); @@ -192,5 +199,5 @@ void user_io_set_index(unsigned char index); unsigned char user_io_ext_idx(char *, char*); void user_io_check_reset(unsigned short modifiers, char useKeys); - + #endif // USER_IO_H diff --git a/x86.c b/x86.c new file mode 100644 index 0000000..89d447e --- /dev/null +++ b/x86.c @@ -0,0 +1,790 @@ +/* + * Copyright (c) 2014, Aleksander Osman + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * + * * Redistributions of source code must retain the above copyright notice, this + * list of conditions and the following disclaimer. + * + * * Redistributions in binary form must reproduce the above copyright notice, + * this list of conditions and the following disclaimer in the documentation + * and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" + * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR + * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER + * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, + * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE + * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +#include +#include +#include +#include +#include +#include +#include + +#include "spi.h" +#include "user_io.h" +#include "file_io.h" +#include "fpga_io.h" + +#define ALT_CPU_CPU_FREQ 90000000u + +#define FLOPPY_BASE 0x8800 +#define HDD_BASE 0x8840 +#define PC_BUS_BASE 0x88a0 +#define PIO_OUTPUT_BASE 0x8860 +#define SOUND_BASE 0x9000 +#define PIT_BASE 0x8880 +#define RTC_BASE 0x8c00 +#define SD_BASE 0x0A00 + +#define CFG_VER 1 + +typedef struct +{ + uint32_t ver; + char fdd_name[1024]; + char hdd_name[1024]; +} x86_config; + +static x86_config config; + +static uint8_t dma_sdio(int status) +{ + uint8_t res; + EnableFpga(); + spi8(UIO_DMA_SDIO); + res = spi_w((uint16_t)status); + DisableFpga(); + return res; +} + +static uint32_t dma_get(uint32_t address) +{ + EnableFpga(); + spi8(UIO_DMA_READ); + spi32w(address); + uint32_t res = spi32w(0); + DisableFpga(); + return res; +} + +static void dma_set(uint32_t address, uint32_t data) +{ + EnableFpga(); + spi8(UIO_DMA_WRITE); + spi32w(address); + spi32w(data); + DisableFpga(); +} + +static void dma_sendbuf(uint32_t address, uint32_t length, uint32_t *data) +{ + EnableFpga(); + spi8(UIO_DMA_WRITE); + spi32w(address); + while (length--) spi32w(*data++); + DisableFpga(); +} + +static void dma_rcvbuf(uint32_t address, uint32_t length, uint32_t *data) +{ + EnableFpga(); + spi8(UIO_DMA_READ); + spi32w(address); + while (length--) *data++ = spi32w(0); + DisableFpga(); +} + +static int load_bios(char* name, uint8_t index) +{ + fileTYPE f = { 0 }; + static uint32_t buf[128]; + + if (!FileOpen(&f, name)) return 0; + + unsigned long bytes2send = f.size; + printf("BIOS %s, %lu bytes.\n", name, bytes2send); + + EnableFpga(); + spi8(UIO_DMA_WRITE); + spi32w( index ? 0x80C0000 : 0x80F0000 ); + + while (bytes2send) + { + printf("."); + + uint16_t chunk = (bytes2send>512) ? 512 : bytes2send; + bytes2send -= chunk; + + FileReadSec(&f, buf); + + chunk = (chunk + 3) >> 2; + uint32_t* p = buf; + while(chunk--) spi32w(*p++); + } + DisableFpga(); + FileClose(&f); + + printf("\n"); + return 1; +} + +static void crc32(uint8_t *ptr, uint32_t *crc_output) +{ + static uint8_t crc[32]; + + //do nothing + if(ptr != NULL && crc_output != NULL) return; + + //initialize + if(ptr == NULL && crc_output == NULL) + { + for(int i=0; i<32; i++) crc[i] = 1; + return; + } + + //output + if(ptr == NULL && crc_output != NULL) + { + *crc_output = 0; + for(int i=0; i<32; i++) + { + (*crc_output) |= crc[i] << (31-i); + } + (*crc_output) = ~(*crc_output); + return; + } + + uint8_t in[8]; + for(int j=0; j<8; j++) in[j] = ((*ptr) >> j) & 1; + + uint8_t new_crc[32]; + + new_crc[31] = in[2] ^ crc[23] ^ crc[29]; + new_crc[30] = in[0] ^ in[3] ^ crc[22] ^ crc[28] ^ crc[31]; + new_crc[29] = in[0] ^ in[1] ^ in[4] ^ crc[21] ^ crc[27] ^ crc[30] ^ crc[31]; + new_crc[28] = in[1] ^ in[2] ^ in[5] ^ crc[20] ^ crc[26] ^ crc[29] ^ crc[30]; + new_crc[27] = in[0] ^ in[2] ^ in[3] ^ in[6] ^ crc[19] ^ crc[25] ^ crc[28] ^ crc[29] ^ crc[31]; + new_crc[26] = in[1] ^ in[3] ^ in[4] ^ in[7] ^ crc[18] ^ crc[24] ^ crc[27] ^ crc[28] ^ crc[30]; + new_crc[25] = in[4] ^ in[5] ^ crc[17] ^ crc[26] ^ crc[27]; + new_crc[24] = in[0] ^ in[5] ^ in[6] ^ crc[16] ^ crc[25] ^ crc[26] ^ crc[31]; + new_crc[23] = in[1] ^ in[6] ^ in[7] ^ crc[15] ^ crc[24] ^ crc[25] ^ crc[30]; + new_crc[22] = in[7] ^ crc[14] ^ crc[24]; + new_crc[21] = in[2] ^ crc[13] ^ crc[29]; + new_crc[20] = in[3] ^ crc[12] ^ crc[28]; + new_crc[19] = in[0] ^ in[4] ^ crc[11] ^ crc[27] ^ crc[31]; + new_crc[18] = in[0] ^ in[1] ^ in[5] ^ crc[10] ^ crc[26] ^ crc[30] ^ crc[31]; + new_crc[17] = in[1] ^ in[2] ^ in[6] ^ crc[9] ^ crc[25] ^ crc[29] ^ crc[30]; + new_crc[16] = in[2] ^ in[3] ^ in[7] ^ crc[8] ^ crc[24] ^ crc[28] ^ crc[29]; + new_crc[15] = in[0] ^ in[2] ^ in[3] ^ in[4] ^ crc[7] ^ crc[27] ^ crc[28] ^ crc[29] ^ crc[31]; + new_crc[14] = in[0] ^ in[1] ^ in[3] ^ in[4] ^ in[5] ^ crc[6] ^ crc[26] ^ crc[27] ^ crc[28] ^ crc[30] ^ crc[31]; + new_crc[13] = in[0] ^ in[1] ^ in[2] ^ in[4] ^ in[5] ^ in[6] ^ crc[5] ^ crc[25] ^ crc[26] ^ crc[27] ^ crc[29] ^ crc[30] ^ crc[31]; + new_crc[12] = in[1] ^ in[2] ^ in[3] ^ in[5] ^ in[6] ^ in[7] ^ crc[4] ^ crc[24] ^ crc[25] ^ crc[26] ^ crc[28] ^ crc[29] ^ crc[30]; + new_crc[11] = in[3] ^ in[4] ^ in[6] ^ in[7] ^ crc[3] ^ crc[24] ^ crc[25] ^ crc[27] ^ crc[28]; + new_crc[10] = in[2] ^ in[4] ^ in[5] ^ in[7] ^ crc[2] ^ crc[24] ^ crc[26] ^ crc[27] ^ crc[29]; + new_crc[9] = in[2] ^ in[3] ^ in[5] ^ in[6] ^ crc[1] ^ crc[25] ^ crc[26] ^ crc[28] ^ crc[29]; + new_crc[8] = in[3] ^ in[4] ^ in[6] ^ in[7] ^ crc[0] ^ crc[24] ^ crc[25] ^ crc[27] ^ crc[28]; + new_crc[7] = in[0] ^ in[2] ^ in[4] ^ in[5] ^ in[7] ^ crc[24] ^ crc[26] ^ crc[27] ^ crc[29] ^ crc[31]; + new_crc[6] = in[0] ^ in[1] ^ in[2] ^ in[3] ^ in[5] ^ in[6] ^ crc[25] ^ crc[26] ^ crc[28] ^ crc[29] ^ crc[30] ^ crc[31]; + new_crc[5] = in[0] ^ in[1] ^ in[2] ^ in[3] ^ in[4] ^ in[6] ^ in[7] ^ crc[24] ^ crc[25] ^ crc[27] ^ crc[28] ^ crc[29] ^ crc[30] ^ crc[31]; + new_crc[4] = in[1] ^ in[3] ^ in[4] ^ in[5] ^ in[7] ^ crc[24] ^ crc[26] ^ crc[27] ^ crc[28] ^ crc[30]; + new_crc[3] = in[0] ^ in[4] ^ in[5] ^ in[6] ^ crc[25] ^ crc[26] ^ crc[27] ^ crc[31]; + new_crc[2] = in[0] ^ in[1] ^ in[5] ^ in[6] ^ in[7] ^ crc[24] ^ crc[25] ^ crc[26] ^ crc[30] ^ crc[31]; + new_crc[1] = in[0] ^ in[1] ^ in[6] ^ in[7] ^ crc[24] ^ crc[25] ^ crc[30] ^ crc[31]; + new_crc[0] = in[1] ^ in[7] ^ crc[24] ^ crc[30]; + + memcpy(crc, new_crc, sizeof(crc)); +} + +static bool floppy_is_160k = false; +static bool floppy_is_180k = false; +static bool floppy_is_320k = false; +static bool floppy_is_360k = false; +static bool floppy_is_720k = false; +static bool floppy_is_1_2m = false; +static bool floppy_is_1_44m= false; +static bool floppy_is_1_68m= false; +static bool floppy_is_2_88m= false; + +#define CMOS_FDD_TYPE ((floppy_is_2_88m) ? 0x50 : (floppy_is_1_44m || floppy_is_1_68m) ? 0x40 : (floppy_is_720k) ? 0x30 : (floppy_is_1_2m) ? 0x20 : 0x10) + +static fileTYPE fdd_image = { 0 }; +static fileTYPE hdd_image = { 0 }; +static bool boot_from_floppy = 1; + +#define IMG_TYPE_FDD 0x800 +#define IMG_TYPE_HDD 0x000 + +static __inline fileTYPE *get_image(uint32_t type) +{ + return (type == IMG_TYPE_FDD) ? &fdd_image : &hdd_image; +} + +static int img_mount(uint32_t type, char *name) +{ + FileClose(get_image(type)); + + int writable = FileCanWrite(name); + int ret = FileOpenEx(get_image(type), name, writable ? (O_RDWR | O_SYNC) : O_RDONLY); + if (!ret) + { + get_image(type)->size = 0; + printf("Failed to open file %s\n", name); + return 0; + } + + printf("Mount %s as %s\n", name, writable ? "read-write" : "read-only"); + return 1; +} + +static int img_read(uint32_t type, uint32_t lba, void *buf, uint32_t len) +{ + if (!FileSeekLBA(get_image(type), lba)) return 0; + return FileReadAdv(get_image(type), buf, len); +} + +static int img_write(uint32_t type, uint32_t lba, void *buf, uint32_t len) +{ + if (!FileSeekLBA(get_image(type), lba)) return 0; + return FileWriteAdv(get_image(type), buf, len); +} + +#define IOWR(base, reg, value) dma_set(base+(reg<<2), value) + +static uint32_t cmos[128]; + +void cmos_set(int addr, uint8_t val) +{ + if (addr >= sizeof(cmos)) return; + + cmos[addr] = val; + return; + + uint16_t sum = 0; + for (int i = 0x10; i <= 0x2D; i++) sum += cmos[i]; + + cmos[0x2E] = sum >> 8; + cmos[0x2F] = sum & 0xFF; + + IOWR(RTC_BASE, addr, cmos[addr]); + + IOWR(RTC_BASE, 0x2E, cmos[0x2E]); + IOWR(RTC_BASE, 0x2F, cmos[0x2F]); +} + +static int fdd_set(char* filename) +{ + floppy_is_160k = false; + floppy_is_180k = false; + floppy_is_320k = false; + floppy_is_360k = false; + floppy_is_720k = false; + floppy_is_1_2m = false; + floppy_is_1_44m = false; + floppy_is_1_68m = false; + floppy_is_2_88m = false; + + int floppy = img_mount(IMG_TYPE_FDD, filename); + uint32_t size = get_image(IMG_TYPE_FDD)->size/512; + if (floppy && size) + { + if (size >= 5760) floppy_is_2_88m = true; + else if (size >= 3360) floppy_is_1_68m = true; + else if (size >= 2880) floppy_is_1_44m = true; + else if (size >= 2400) floppy_is_1_2m = true; + else if (size >= 1440) floppy_is_720k = true; + else if (size >= 720) floppy_is_360k = true; + else if (size >= 640) floppy_is_320k = true; + else if (size >= 360) floppy_is_180k = true; + else floppy_is_160k = true; + } + else + { + floppy = 0; + floppy_is_1_44m = true; + } + + /* + 0x00.[0]: media present + 0x01.[0]: media writeprotect + 0x02.[7:0]: media cylinders + 0x03.[7:0]: media sectors per track + 0x04.[31:0]: media total sector count + 0x05.[1:0]: media heads + 0x06.[31:0]: media sd base + 0x07.[15:0]: media wait cycles: 200000 us / spt + 0x08.[15:0]: media wait rate 0: 1000 us + 0x09.[15:0]: media wait rate 1: 1666 us + 0x0A.[15:0]: media wait rate 2: 2000 us + 0x0B.[15:0]: media wait rate 3: 500 us + 0x0C.[7:0]: media type: 8'h20 none; 8'h00 old; 8'hC0 720k; 8'h80 1_44M; 8'h40 2_88M + */ + + int floppy_spt = + (floppy_is_160k) ? 8 : + (floppy_is_180k) ? 9 : + (floppy_is_320k) ? 8 : + (floppy_is_360k) ? 9 : + (floppy_is_720k) ? 9 : + (floppy_is_1_2m) ? 15 : + (floppy_is_1_44m) ? 18 : + (floppy_is_1_68m) ? 21 : + (floppy_is_2_88m) ? 36 : + 0; + + int floppy_cylinders = (floppy_is_2_88m || floppy_is_1_68m || floppy_is_1_44m || floppy_is_1_2m || floppy_is_720k) ? 80 : 40; + int floppy_heads = (floppy_is_160k || floppy_is_180k) ? 1 : 2; + int floppy_total_sectors = floppy_spt * floppy_heads * floppy_cylinders; + int floppy_wait_cycles = 200000000 / floppy_spt; + + int floppy_media = + (!floppy) ? 0x20 : + (floppy_is_160k) ? 0x00 : + (floppy_is_180k) ? 0x00 : + (floppy_is_320k) ? 0x00 : + (floppy_is_360k) ? 0x00 : + (floppy_is_720k) ? 0xC0 : + (floppy_is_1_2m) ? 0x00 : + (floppy_is_1_44m) ? 0x80 : + (floppy_is_2_88m) ? 0x40 : + 0x20; + + IOWR(FLOPPY_BASE, 0x0, floppy ? 1 : 0); + IOWR(FLOPPY_BASE, 0x1, (floppy && (get_image(IMG_TYPE_FDD)->mode & O_RDWR)) ? 0 : 1); + IOWR(FLOPPY_BASE, 0x2, floppy_cylinders); + IOWR(FLOPPY_BASE, 0x3, floppy_spt); + IOWR(FLOPPY_BASE, 0x4, floppy_total_sectors); + IOWR(FLOPPY_BASE, 0x5, floppy_heads); + IOWR(FLOPPY_BASE, 0x6, 0); // base LBA + IOWR(FLOPPY_BASE, 0x7, (int)(floppy_wait_cycles / (1000000000.0 / ALT_CPU_CPU_FREQ))); + IOWR(FLOPPY_BASE, 0x8, (int)(1000000.0 / (1000000000.0 / ALT_CPU_CPU_FREQ))); + IOWR(FLOPPY_BASE, 0x9, (int)(1666666.0 / (1000000000.0 / ALT_CPU_CPU_FREQ))); + IOWR(FLOPPY_BASE, 0xA, (int)(2000000.0 / (1000000000.0 / ALT_CPU_CPU_FREQ))); + IOWR(FLOPPY_BASE, 0xB, (int)(500000.0 / (1000000000.0 / ALT_CPU_CPU_FREQ))); + IOWR(FLOPPY_BASE, 0xC, floppy_media); + + //cmos_set(0x10, CMOS_FDD_TYPE); + return floppy; +} + +static uint8_t bin2bcd(unsigned val) +{ + return ((val / 10) << 4) + (val % 10); +} + +void x86_init() +{ + user_io_8bit_set_status(UIO_STATUS_RESET, UIO_STATUS_RESET); + + load_bios("ao486/boot0.rom", 0); + load_bios("ao486/boot1.rom", 1); + + IOWR(PC_BUS_BASE, 0, 0x00FFF0EA); + IOWR(PC_BUS_BASE, 1, 0x000000F0); + + //-------------------------------------------------------------------------- sound + /* + 0-255.[15:0]: cycles in period + 256.[12:0]: cycles in 80us + 257.[9:0]: cycles in 1 sample: 96000 Hz + */ + + double cycle_in_ns = (1000000000.0 / ALT_CPU_CPU_FREQ); //33.333333; + for(int i=0; i<256; i++) + { + double f = 1000000.0 / (256.0-i); + + double cycles_in_period = 1000000000.0 / (f * cycle_in_ns); + IOWR(SOUND_BASE, i, (int)cycles_in_period); + } + + IOWR(SOUND_BASE, 256, (int)(80000.0 / (1000000000.0 / ALT_CPU_CPU_FREQ))); + IOWR(SOUND_BASE, 257, (int)((1000000000.0/96000.0) / (1000000000.0 / ALT_CPU_CPU_FREQ))); + + //-------------------------------------------------------------------------- pit + /* + 0.[7:0]: cycles in sysclock 1193181 Hz + */ + + IOWR(PIT_BASE, 0, (int)((1000000000.0/1193181.0) / (1000000000.0 / ALT_CPU_CPU_FREQ))); + + //-------------------------------------------------------------------------- floppy + + fdd_set(config.fdd_name); + + //-------------------------------------------------------------------------- hdd + + unsigned int hd_cylinders = 0; + unsigned int hd_heads = 0; + unsigned int hd_spt = 0; + unsigned int hd_total_sectors = 0; + unsigned int hdd_sd_base = 0; + + int hdd = img_mount(IMG_TYPE_HDD, config.hdd_name); + if (hdd) + { + hd_cylinders = 1024; + hd_heads = 16; + hd_spt = 63; + + hd_total_sectors = get_image(IMG_TYPE_HDD)->size / 512; + } + + /* + 0x00.[31:0]: identify write + 0x01.[16:0]: media cylinders + 0x02.[4:0]: media heads + 0x03.[8:0]: media spt + 0x04.[13:0]: media sectors per cylinder = spt * heads + 0x05.[31:0]: media sectors total + 0x06.[31:0]: media sd base + */ + + uint32_t identify[256] = + { + 0x0040, //word 0 + (hd_cylinders > 16383)? 16383 : hd_cylinders, //word 1 + 0x0000, //word 2 reserved + hd_heads, //word 3 + (uint16_t)(512 * hd_spt), //word 4 + 512, //word 5 + hd_spt, //word 6 + 0x0000, //word 7 vendor specific + 0x0000, //word 8 vendor specific + 0x0000, //word 9 vendor specific + ('A' << 8) | 'O', //word 10 + ('H' << 8) | 'D', //word 11 + ('0' << 8) | '0', //word 12 + ('0' << 8) | '0', //word 13 + ('0' << 8) | ' ', //word 14 + (' ' << 8) | ' ', //word 15 + (' ' << 8) | ' ', //word 16 + (' ' << 8) | ' ', //word 17 + (' ' << 8) | ' ', //word 18 + (' ' << 8) | ' ', //word 19 + 3, //word 20 buffer type + 512, //word 21 cache size + 4, //word 22 number of ecc bytes + 0,0,0,0, //words 23..26 firmware revision + ('A' << 8) | 'O', //words 27..46 model number + (' ' << 8) | 'H', + ('a' << 8) | 'r', + ('d' << 8) | 'd', + ('r' << 8) | 'i', + ('v' << 8) | 'e', + (' ' << 8) | ' ', + (' ' << 8) | ' ', + (' ' << 8) | ' ', + (' ' << 8) | ' ', + (' ' << 8) | ' ', + (' ' << 8) | ' ', + (' ' << 8) | ' ', + (' ' << 8) | ' ', + (' ' << 8) | ' ', + (' ' << 8) | ' ', + (' ' << 8) | ' ', + (' ' << 8) | ' ', + (' ' << 8) | ' ', + (' ' << 8) | ' ', + 16, //word 47 max multiple sectors + 1, //word 48 dword io + 1<<9, //word 49 lba supported + 0x0000, //word 50 reserved + 0x0200, //word 51 pio timing + 0x0200, //word 52 pio timing + 0x0007, //word 53 valid fields + (hd_cylinders > 16383)? 16383 : hd_cylinders, //word 54 + hd_heads, //word 55 + hd_spt, //word 56 + hd_total_sectors & 0xFFFF, //word 57 + hd_total_sectors >> 16, //word 58 + 0x0000, //word 59 multiple sectors + hd_total_sectors & 0xFFFF, //word 60 + hd_total_sectors >> 16, //word 61 + 0x0000, //word 62 single word dma modes + 0x0000, //word 63 multiple word dma modes + 0x0000, //word 64 pio modes + 120,120,120,120, //word 65..68 + 0,0,0,0,0,0,0,0,0,0,0, //word 69..79 + 0x007E, //word 80 ata modes + 0x0000, //word 81 minor version number + 1<<14, //word 82 supported commands + (1<<14) | (1<<13) | (1<<12) | (1<<10), //word 83 + 1<<14, //word 84 + 1<<14, //word 85 + (1<<14) | (1<<13) | (1<<12) | (1<<10), //word 86 + 1<<14, //word 87 + 0x0000, //word 88 + 0,0,0,0, //word 89..92 + 1 | (1<<14) | 0x2000, //word 93 + 0,0,0,0,0,0, //word 94..99 + hd_total_sectors & 0xFFFF, //word 100 + hd_total_sectors >> 16, //word 101 + 0, //word 102 + 0, //word 103 + + 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,//word 104..127 + + 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, //word 128..255 + 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0 + }; + + for(int i=0; i<128; i++) IOWR(HDD_BASE, 0, hdd ? ((unsigned int)identify[2*i+1] << 16) | (unsigned int)identify[2*i+0] : 0); + + IOWR(HDD_BASE, 1, hd_cylinders); + IOWR(HDD_BASE, 2, hd_heads); + IOWR(HDD_BASE, 3, hd_spt); + IOWR(HDD_BASE, 4, hd_spt * hd_heads); + IOWR(HDD_BASE, 5, hd_spt * hd_heads * hd_cylinders); + IOWR(HDD_BASE, 6, 0); // base LBA + + printf("HDD:\n hd_cylinders %d\n hd_heads %d\n hd_spt %d\n hd_total_sectors %d\n\n", hd_cylinders, hd_heads, hd_spt, hd_total_sectors); + + //-------------------------------------------------------------------------- rtc + + /* + 128.[26:0]: cycles in second + 129.[12:0]: cycles in 122.07031 us + */ + + IOWR(RTC_BASE, 128, (int)(1000000000.0 / (1000000000.0 / ALT_CPU_CPU_FREQ))); + IOWR(RTC_BASE, 129, (int)(122070.0 / (1000000000.0 / ALT_CPU_CPU_FREQ))); + + bool translate_none = hd_cylinders <= 1024 && hd_heads <= 16 && hd_spt <= 63; + bool translate_large= !translate_none && (hd_cylinders * hd_heads) <= 131072; + bool translate_lba = !translate_none && !translate_large; + + unsigned char translate_byte = 1; //(translate_large) ? 1 : (translate_lba) ? 2 : 0; + + time_t t = time(NULL); + struct tm tm = *localtime(&t); + + //rtc contents 0-127 + uint32_t tmp[128] = { + bin2bcd(tm.tm_sec), //0x00: SEC BCD + 0x00, //0x01: ALARM SEC BCD + bin2bcd(tm.tm_min), //0x02: MIN BCD + 0x00, //0x03: ALARM MIN BCD + bin2bcd(tm.tm_hour), //0x04: HOUR BCD 24h + 0x12, //0x05: ALARM HOUR BCD 24h + tm.tm_wday+1, //0x06: DAY OF WEEK Sunday=1 + bin2bcd(tm.tm_mday), //0x07: DAY OF MONTH BCD from 1 + bin2bcd(tm.tm_mon+1), //0x08: MONTH BCD from 1 + bin2bcd((tm.tm_year<117) ? 17 : tm.tm_year-100), //0x09: YEAR BCD + 0x26, //0x0A: REG A + 0x02, //0x0B: REG B + 0x00, //0x0C: REG C + 0x80, //0x0D: REG D + 0x00, //0x0E: REG E - POST status + 0x00, //0x0F: REG F - shutdown status + + CMOS_FDD_TYPE, //0x10: floppy drive type; 0-none, 1-360K, 2-1.2M, 3-720K, 4-1.44M, 5-2.88M + 0x00, //0x11: configuration bits; not used + 0xF0, //0x12: hard disk types; 0-none, 1:E-type, F-type 16+ + 0x00, //0x13: advanced configuration bits; not used + 0x0D, //0x14: equipment bits + 0x80, //0x15: base memory in 1k LSB + 0x02, //0x16: base memory in 1k MSB + 0x00, //0x17: memory size above 1m in 1k LSB + 0xFC, //0x18: memory size above 1m in 1k MSB + 0x2F, //0x19: extended hd types 1/2; type 47d + 0x00, //0x1A: extended hd types 2/2 + + hdd ? hd_cylinders & 0xFF : 0, //0x1B: hd 0 configuration 1/9; cylinders low + hdd ? (hd_cylinders >> 8) & 0xFF : 0, //0x1C: hd 0 configuration 2/9; cylinders high + hdd ? hd_heads : 0, //0x1D: hd 0 configuration 3/9; heads + hdd ? 0xFF : 0, //0x1E: hd 0 configuration 4/9; write pre-comp low + hdd ? 0xFF : 0, //0x1F: hd 0 configuration 5/9; write pre-comp high + hdd ? 0xC8 : 0, //0x20: hd 0 configuration 6/9; retries/bad map/heads>8 + hdd ? hd_cylinders & 0xFF : 0, //0x21: hd 0 configuration 7/9; landing zone low + hdd ? (hd_cylinders >> 8) & 0xFF : 0, //0x22: hd 0 configuration 8/9; landing zone high + hdd ? hd_spt : 0, //0x23: hd 0 configuration 9/9; sectors/track + + 0x00, //0x24: hd 1 configuration 1/9 + 0x00, //0x25: hd 1 configuration 2/9 + 0x00, //0x26: hd 1 configuration 3/9 + 0x00, //0x27: hd 1 configuration 4/9 + 0x00, //0x28: hd 1 configuration 5/9 + 0x00, //0x29: hd 1 configuration 6/9 + 0x00, //0x2A: hd 1 configuration 7/9 + 0x00, //0x2B: hd 1 configuration 8/9 + 0x00, //0x2C: hd 1 configuration 9/9 + + (boot_from_floppy)? 0x20u : 0x00u, //0x2D: boot sequence + + 0x00, //0x2E: checksum MSB + 0x00, //0x2F: checksum LSB + + 0x00, //0x30: memory size above 1m in 1k LSB + 0xFC, //0x31: memory size above 1m in 1k MSB + + 0x20, //0x32: IBM century + 0x00, //0x33: ? + + 0x00, //0x34: memory size above 16m in 64k LSB + 0x07, //0x35: memory size above 16m in 64k MSB; 128 MB + + 0x00, //0x36: ? + 0x20, //0x37: IBM PS/2 century + + 0x00, //0x38: eltorito boot sequence; not used + translate_byte, //0x39: ata translation policy 1/2 + 0x00, //0x3A: ata translation policy 2/2 + + 0x00, //0x3B: ? + 0x00, //0x3C: ? + + 0x00, //0x3D: eltorito boot sequence; not used + + 0x00, //0x3E: ? + 0x00, //0x3F: ? + + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 + }; + + memcpy(cmos, tmp, sizeof(cmos)); + + //count checksum + unsigned short sum = 0; + for(int i=0x10; i<=0x2D; i++) sum += cmos[i]; + + cmos[0x2E] = sum >> 8; + cmos[0x2F] = sum & 0xFF; + + for(unsigned int i=0; i> 2, (uint32_t*)&sd_params); + //printf("Read: 0x%08x, 0x%08x, %d\n", sd_params.addr, sd_params.lba, sd_params.bl_cnt); + + if (get_image(sd_params.addr)->size) + { + if (sd_params.bl_cnt>0 && sd_params.bl_cnt<=4) + { + if (img_read(sd_params.addr, sd_params.lba, secbuf, sd_params.bl_cnt * 512)) + { + dma_sendbuf(sd_params.addr, sd_params.bl_cnt * 128, secbuf); + res = 1; + } + } + else + { + printf("Error: Block count %d is out of range 1..4.\n", sd_params.bl_cnt); + } + } + else + { + printf("Error: image is not ready.\n"); + } + + dma_sdio(res ? 1 : 2); + } + else if (sd_req == 2) + { + dma_rcvbuf(SD_BASE + (4 << 2), sizeof(sd_params) >> 2, (uint32_t*)&sd_params); + //printf("Write: 0x%08x, 0x%08x, %d\n", sd_params.addr, sd_params.lba, sd_params.bl_cnt); + + if (get_image(sd_params.addr)->size) + { + if (sd_params.bl_cnt>0 && sd_params.bl_cnt <= 4) + { + if (get_image(sd_params.addr)->mode & O_RDWR) + { + dma_rcvbuf(sd_params.addr, sd_params.bl_cnt * 128, secbuf); + if (img_write(sd_params.addr, sd_params.lba, secbuf, sd_params.bl_cnt * 512)) + { + res = 1; + } + } + else + { + printf("Error: image is read-only.\n"); + } + } + else + { + printf("Error: Block count %d is out of range 1..4.\n", sd_params.bl_cnt); + } + } + else + { + printf("Error: image is not ready.\n"); + } + + dma_sdio(res ? 1 : 2); + } +} + +void x86_set_image(int num, char *filename) +{ + if (num == 2) + { + strcpy(config.hdd_name, filename); + } + + if (num == 0) + { + strcpy(config.fdd_name, filename); + fdd_set(filename); + } +} + +void x86_config_save() +{ + config.ver = CFG_VER; + FileSaveConfig("ao486sys.cfg", &config, sizeof(config)); +} + +void x86_config_load() +{ + static x86_config tmp; + memset(&config, 0, sizeof(config)); + if (FileLoadConfig("ao486sys.cfg", &tmp, sizeof(tmp)) && (tmp.ver == CFG_VER)) + { + memcpy(&config, &tmp, sizeof(config)); + } +} + +void x86_set_fdd_boot(uint32_t boot) +{ + boot_from_floppy = (boot != 0); +} diff --git a/x86.h b/x86.h new file mode 100644 index 0000000..8bb15f7 --- /dev/null +++ b/x86.h @@ -0,0 +1,13 @@ +#ifndef X86_H +#define X86_H + +void x86_init(); +void x86_poll(); + +void x86_set_image(int num, char *filename); + +void x86_config_load(); +void x86_config_save(); +void x86_set_fdd_boot(uint32_t boot); + +#endif