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