This commit is contained in:
bbond007
2019-01-08 18:42:57 -05:00
37 changed files with 1734 additions and 298 deletions

View File

@@ -1,4 +1,3 @@
# makefile to fail if any command in pipe is failed.
SHELL = /bin/bash -o pipefail
@@ -9,8 +8,15 @@ CC = $(BASE)-gcc
LD = $(CC)
STRIP = $(BASE)-strip
ifeq ($(V),1)
Q :=
else
Q := @
endif
INCLUDE = -I./
INCLUDE = -I./support/minimig
INCLUDE += -I./support/minimig
INCLUDE += -I./lib/libco
PRJ = MiSTer
SRC = $(wildcard *.c)
@@ -21,46 +27,48 @@ ARCHIE_SRC = $(wildcard ./support/archie/*.cpp)
ST_SRC = $(wildcard ./support/st/*.cpp)
X86_SRC = $(wildcard ./support/x86/*.cpp)
SNES_SRC = $(wildcard ./support/snes/*.cpp)
LIBCO_SRC = lib/libco/arm.c
VPATH = ./:./support/minimig:./support/sharpmz:./support/archie:./support/st:./support/x86:./support/snes
OBJ = $(SRC:.c=.o) $(SRC2:.cpp=.o) $(MINIMIG_SRC:.cpp=.o) $(SHARPMZ_SRC:.cpp=.o) $(ARCHIE_SRC:.cpp=.o) $(ST_SRC:.cpp=.o) $(X86_SRC:.cpp=.o) $(SNES_SRC:.cpp=.o)
DEP = $(SRC:.c=.d) $(SRC2:.cpp=.d) $(MINIMIG_SRC:.cpp=.d) $(SHARPMZ_SRC:.cpp=.d) $(ARCHIE_SRC:.cpp=.d) $(ST_SRC:.cpp=.d) $(X86_SRC:.cpp=.d) $(SNES_SRC:.cpp=.d)
OBJ = $(SRC:.c=.c.o) $(SRC2:.cpp=.cpp.o) $(MINIMIG_SRC:.cpp=.cpp.o) $(SHARPMZ_SRC:.cpp=.cpp.o) $(ARCHIE_SRC:.cpp=.cpp.o) $(ST_SRC:.cpp=.cpp.o) $(X86_SRC:.cpp=.cpp.o) $(SNES_SRC:.cpp=.cpp.o) $(LIBCO_SRC:.c=.c.o)
DEP = $(SRC:.c=.cpp.d) $(SRC2:.cpp=.cpp.d) $(MINIMIG_SRC:.cpp=.cpp.d) $(SHARPMZ_SRC:.cpp=.cpp.d) $(ARCHIE_SRC:.cpp=.cpp.d) $(ST_SRC:.cpp=.cpp.d) $(X86_SRC:.cpp=.cpp.d) $(SNES_SRC:.cpp=.cpp.d) $(LIBCO_SRC:.c=.c.d)
DFLAGS = $(INCLUDE)
CFLAGS = $(DFLAGS) -Wall -Wextra -c -O3 -D_FILE_OFFSET_BITS=64 -D_LARGEFILE64_SOURCE -DVDATE=\"`date +"%y%m%d"`\"
DFLAGS = $(INCLUDE) -D_FILE_OFFSET_BITS=64 -D_LARGEFILE64_SOURCE -DVDATE=\"`date +"%y%m%d"`\"
CFLAGS = $(DFLAGS) -Wall -Wextra -Wno-strict-aliasing -c -O3
LFLAGS = -lc -lstdc++ -lrt
$(PRJ): $(OBJ)
@$(info $@)
@$(LD) -o $@ $+ $(LFLAGS)
@cp $@ $@.elf
@$(STRIP) $@
$(Q)$(info $@)
$(Q)$(LD) -o $@ $+ $(LFLAGS)
$(Q)cp $@ $@.elf
$(Q)$(STRIP) $@
clean:
rm -f *.d *.o *.elf *.map *.lst *.bak *.rej *.org *.user *~ $(PRJ)
rm -rf obj .vs DTAR* x64
$(Q)rm -f *.elf *.map *.lst *.user *~ $(PRJ)
$(Q)rm -rf obj .vs DTAR* x64
$(Q)find . \( -name '*.o' -o -name '*.d' -o -name '*.bak' -o -name '*.rej' -o -name '*.org' \) -exec rm -f {} \;
cleanall:
rm -rf *.d *.o *.elf *.map *.lst *.bak *.rej *.org *.user *~ $(PRJ)
rm -rf obj .vs DTAR* x64
find . -name '*.o' -delete
find . -name '*.d' -delete
$(Q)rm -rf $(OBJ) $(DEP) *.elf *.map *.lst *.bak *.rej *.org *.user *~ $(PRJ)
$(Q)rm -rf obj .vs DTAR* x64
$(Q)find . -name '*.o' -delete
$(Q)find . -name '*.d' -delete
%.o: %.c
@$(info $<)
@$(CC) $(CFLAGS) -std=gnu99 -o $@ -c $< 2>&1 | sed -e 's/\(.[a-zA-Z]\+\):\([0-9]\+\):\([0-9]\+\):/\1(\2,\ \3):/g'
%.c.o: %.c
$(Q)$(info $<)
$(Q)$(CC) $(CFLAGS) -std=gnu99 -o $@ -c $< 2>&1 | sed -e 's/\(.[a-zA-Z]\+\):\([0-9]\+\):\([0-9]\+\):/\1(\2,\ \3):/g'
%.o: %.cpp
@$(info $<)
@$(CC) $(CFLAGS) -std=gnu++14 -o $@ -c $< 2>&1 | sed -e 's/\(.[a-zA-Z]\+\):\([0-9]\+\):\([0-9]\+\):/\1(\2,\ \3):/g'
%.cpp.o: %.cpp
$(Q)$(info $<)
$(Q)$(CC) $(CFLAGS) -std=gnu++14 -o $@ -c $< 2>&1 | sed -e 's/\(.[a-zA-Z]\+\):\([0-9]\+\):\([0-9]\+\):/\1(\2,\ \3):/g'
-include $(DEP)
%.d: %.c
@$(CC) $(DFLAGS) -MM $< -MT $@ -MT $*.o -MF $@ 2>&1 | sed -e 's/\(.[a-zA-Z]\+\):\([0-9]\+\):\([0-9]\+\):/\1(\2,\ \3):/g'
%.c.d: %.c
$(Q)$(CC) $(DFLAGS) -MM $< -MT $@ -MT $*.c.o -MF $@ 2>&1 | sed -e 's/\(.[a-zA-Z]\+\):\([0-9]\+\):\([0-9]\+\):/\1(\2,\ \3):/g'
%.d: %.cpp
@$(CC) $(DFLAGS) -MM $< -MT $@ -MT $*.o -MF $@ 2>&1 | sed -e 's/\(.[a-zA-Z]\+\):\([0-9]\+\):\([0-9]\+\):/\1(\2,\ \3):/g'
%.cpp.d: %.cpp
$(Q)$(CC) $(DFLAGS) -MM $< -MT $@ -MT $*.cpp.o -MF $@ 2>&1 | sed -e 's/\(.[a-zA-Z]\+\):\([0-9]\+\):\([0-9]\+\):/\1(\2,\ \3):/g'
# Ensure correct time stamp
main.o: $(filter-out main.o, $(OBJ))
main.cpp.o: $(filter-out main.cpp.o, $(OBJ))

View File

@@ -29,12 +29,16 @@
<NMakeBuildCommandLine>git.lnk ./build.sh</NMakeBuildCommandLine>
<NMakeOutput>MiSTer</NMakeOutput>
<NMakeCleanCommandLine>git.lnk ./clean.sh</NMakeCleanCommandLine>
<NMakePreprocessorDefinitions>WIN32;VDATE="000000";_FILE_OFFSET_BITS=64;_LARGEFILE64_SOURCE;$(NMakePreprocessorDefinitions)</NMakePreprocessorDefinitions>
<NMakeIncludeSearchPath>c:\Work\Git\opt\gcc54\arm-linux-gnueabihf\libc\usr\include;$(NMakeIncludeSearchPath)</NMakeIncludeSearchPath>
<NMakePreprocessorDefinitions>__arm__;__GNUC__;__USE_GNU ;_GNU_SOURCE;VDATE="000000";_FILE_OFFSET_BITS=64;_LARGEFILE64_SOURCE;$(NMakePreprocessorDefinitions)</NMakePreprocessorDefinitions>
<NMakeIncludeSearchPath>c:\Work\Git\opt\gcc54\arm-linux-gnueabihf\libc\usr\include;c:\Work\Git\opt\gcc54\lib\gcc\arm-linux-gnueabihf\5.4.1\include;c:\Work\Git\opt\gcc54\arm-linux-gnueabihf\include\c++\5.4.1;$(NMakeIncludeSearchPath);lib\libco</NMakeIncludeSearchPath>
<OutDir>$(TEMP)</OutDir>
<IntDir>$(TEMP)</IntDir>
<AdditionalOptions>
</AdditionalOptions>
<IncludePath />
<ReferencePath />
<LibraryPath />
<LibraryWPath />
</PropertyGroup>
<ItemDefinitionGroup>
</ItemDefinitionGroup>
@@ -53,9 +57,12 @@
<ClCompile Include="hardware.cpp" />
<ClCompile Include="ini_parser.cpp" />
<ClCompile Include="input.cpp" />
<ClCompile Include="lib\libco\arm.c" />
<ClCompile Include="lib\libco\libco.c" />
<ClCompile Include="main.cpp" />
<ClCompile Include="menu.cpp" />
<ClCompile Include="osd.cpp" />
<ClCompile Include="scheduler.cpp" />
<ClCompile Include="spi.cpp" />
<ClCompile Include="support\archie\archie.cpp" />
<ClCompile Include="support\minimig\minimig_boot.cpp" />
@@ -88,9 +95,12 @@
<ClInclude Include="hardware.h" />
<ClInclude Include="ini_parser.h" />
<ClInclude Include="input.h" />
<ClInclude Include="lib\libco\libco.h" />
<ClInclude Include="lib\libco\settings.h" />
<ClInclude Include="logo.h" />
<ClInclude Include="menu.h" />
<ClInclude Include="osd.h" />
<ClInclude Include="scheduler.h" />
<ClInclude Include="spi.h" />
<ClInclude Include="support.h" />
<ClInclude Include="support\archie\archie.h" />

View File

@@ -9,6 +9,12 @@
<UniqueIdentifier>{93995380-89BD-4b04-88EB-625FBE52EBFB}</UniqueIdentifier>
<Extensions>h;hh;hpp;hxx;hm;inl;inc;xsd</Extensions>
</Filter>
<Filter Include="Header Files\lib">
<UniqueIdentifier>{0c4bf53d-7986-4434-bbd2-734da3553be9}</UniqueIdentifier>
</Filter>
<Filter Include="Source Files\lib">
<UniqueIdentifier>{da657dc9-d7b4-417e-b916-6543cf17b67e}</UniqueIdentifier>
</Filter>
</ItemGroup>
<ItemGroup>
<None Include="build.sh" />
@@ -94,6 +100,15 @@
<ClCompile Include="support\snes\snes.cpp">
<Filter>Source Files</Filter>
</ClCompile>
<ClCompile Include="lib\libco\arm.c">
<Filter>Source Files\lib</Filter>
</ClCompile>
<ClCompile Include="lib\libco\libco.c">
<Filter>Source Files\lib</Filter>
</ClCompile>
<ClCompile Include="scheduler.cpp">
<Filter>Source Files</Filter>
</ClCompile>
</ItemGroup>
<ItemGroup>
<ClInclude Include="battery.h">
@@ -201,5 +216,14 @@
<ClInclude Include="support\snes\snes.h">
<Filter>Header Files</Filter>
</ClInclude>
<ClInclude Include="lib\libco\libco.h">
<Filter>Header Files\lib</Filter>
</ClInclude>
<ClInclude Include="lib\libco\settings.h">
<Filter>Header Files\lib</Filter>
</ClInclude>
<ClInclude Include="scheduler.h">
<Filter>Header Files</Filter>
</ClInclude>
</ItemGroup>
</Project>

View File

@@ -22,9 +22,12 @@
#include "user_io.h"
#include "cfg.h"
#include "input.h"
#include "scheduler.h"
typedef std::vector<dirent> DirentVector;
static const size_t YieldIterations = 128;
DirentVector DirItem;
int iSelectedEntry = 0; // selected entry index
int iFirstEntry = 0;
@@ -520,6 +523,11 @@ struct DirentComp
{
bool operator()(const dirent& de1, const dirent& de2)
{
if (++iterations % YieldIterations == 0)
{
scheduler_yield();
}
if ((de1.d_type == DT_DIR) && !strcmp(de1.d_name, "..")) return true;
if ((de2.d_type == DT_DIR) && !strcmp(de2.d_name, "..")) return false;
@@ -545,6 +553,8 @@ struct DirentComp
return strcasecmp(de1.d_name, de2.d_name) < 0;
}
size_t iterations = 0;
};
static int get_stmode(const char *path)
@@ -635,8 +645,13 @@ int ScanDirectory(char* path, int mode, const char *extension, int options, cons
}
struct dirent *de;
while((de = readdir(d)))
for (size_t i = 0; (de = readdir(d)); i++)
{
if (0 < i && i % YieldIterations == 0)
{
scheduler_yield();
}
if (de->d_type == DT_DIR)
{
if (!strcmp(de->d_name, ".")) continue;

244
input.cpp
View File

@@ -17,6 +17,7 @@
#include "errno.h"
#define NUMDEV 10
#define NUMPLAYERS 6
static int ev2amiga[] =
{
@@ -970,24 +971,24 @@ uint32_t get_key_mod()
typedef struct
{
uint16_t vid, pid;
char led;
char last_x, last_y; // last x & y axis bitmasks for each alternative directional control scheme (DPAD, Analog pad etc.)
uint8_t led;
uint8_t last_x, last_y; // last x & y axis bitmasks for each alternative directional control scheme (DPAD, Analog pad etc.)
char has_map;
uint8_t num;
uint8_t has_map;
uint32_t map[32];
char has_mmap;
uint8_t has_mmap;
uint32_t mmap[32];
uint16_t jkmap[1024];
char has_kbdmap;
uint8_t has_kbdmap;
uint8_t kbdmap[256];
int accx, accy;
} devInput;
static devInput input[NUMDEV] = {};
static int first_joystick = -1;
int mfd = -1;
int mwd = -1;
@@ -1190,8 +1191,8 @@ void finish_map_setting(int dismiss)
}
else
{
if (dismiss) input[mapping_dev].has_map = 0;
else FileSaveConfig(get_map_name(mapping_dev, 0), &input[mapping_dev].map, sizeof(input[mapping_dev].map));
for (int i = 0; i < NUMDEV; i++) input[i].has_map = 0;
if (!dismiss) FileSaveConfig(get_map_name(mapping_dev, 0), &input[mapping_dev].map, sizeof(input[mapping_dev].map));
if (is_menu_core()) input[mapping_dev].has_mmap = 0;
}
}
@@ -1281,10 +1282,10 @@ static int keyrah_trans(int key, int press)
static void input_cb(struct input_event *ev, struct input_absinfo *absinfo, int dev);
static int kbd_toggle = 0;
static uint16_t joy[2] = { 0 }, joy_prev[2] = { 0 };
static uint16_t autofire[2] = { 0 };
static uint16_t autofirecodes[2][16] = { 0 };
static int af_delay[2] = { 50, 50 };
static uint16_t joy[NUMPLAYERS] = {}, joy_prev[NUMPLAYERS] = {};
static uint16_t autofire[NUMPLAYERS] = {};
static uint16_t autofirecodes[NUMPLAYERS][16] = {};
static int af_delay[NUMPLAYERS] = {};
static unsigned char mouse_btn = 0;
static int mouse_emu = 0;
@@ -1295,88 +1296,92 @@ static int mouse_emu_y = 0;
static uint32_t mouse_timer = 0;
static void joy_digital(int num, uint16_t mask, uint16_t code, char press, int bnum)
static void joy_digital(int jnum, uint16_t mask, uint16_t code, char press, int bnum)
{
static char str[128];
static uint16_t lastcode[2], lastmask[2];
static uint16_t lastcode[NUMPLAYERS], lastmask[NUMPLAYERS];
int num = jnum - 1;
if (num < 2)
if (num < NUMPLAYERS)
{
if (bnum != 17 && bnum != 16)
if (jnum)
{
if (press)
{
lastcode[num] = code;
lastmask[num] = mask;
}
else
{
lastcode[num] = 0;
lastmask[num] = 0;
}
}
else if (!user_io_osd_is_visible())
{
if (lastcode[num])
if (bnum != 17 && bnum != 16)
{
if (press)
{
int found = 0;
int zero = -1;
for (int i = 0; i < 16; i++)
lastcode[num] = code;
lastmask[num] = mask;
}
else
{
lastcode[num] = 0;
lastmask[num] = 0;
}
}
else if (!user_io_osd_is_visible())
{
if (lastcode[num])
{
if (press)
{
if (!autofirecodes[num][i]) zero = i;
if (autofirecodes[num][i] == lastcode[num])
int found = 0;
int zero = -1;
for (int i = 0; i < 16; i++)
{
found = 1;
autofirecodes[num][i] = 0;
break;
if (!autofirecodes[num][i]) zero = i;
if (autofirecodes[num][i] == lastcode[num])
{
found = 1;
autofirecodes[num][i] = 0;
break;
}
}
if (!found && zero >= 0) autofirecodes[num][zero] = lastcode[num];
autofire[num] = !found ? autofire[num] | lastmask[num] : autofire[num] & ~lastmask[num];
if (hasAPI1_5())
{
if (!found) sprintf(str, "Auto fire: %d ms", af_delay[num] * 2);
else sprintf(str, "Auto fire: OFF");
Info(str);
}
else InfoMessage((!found) ? "\n\n Auto fire\n ON" :
"\n\n Auto fire\n OFF");
}
return;
}
else if (joy[num] & 0xF)
{
if (press)
{
if (joy[num] & 9)
{
af_delay[num] += 25 << ((joy[num] & 1) ? 1 : 0);
if (af_delay[num] > 500) af_delay[num] = 500;
}
else
{
af_delay[num] -= 25 << ((joy[num] & 2) ? 1 : 0);
if (af_delay[num] < 25) af_delay[num] = 25;
}
static char str[256];
if (hasAPI1_5())
{
sprintf(str, "Auto fire period: %d ms", af_delay[num] * 2);
Info(str);
}
else
{
sprintf(str, "\n\n Auto fire period\n %dms", af_delay[num] * 2);
InfoMessage(str);
}
}
if (!found && zero >= 0) autofirecodes[num][zero] = lastcode[num];
autofire[num] = !found ? autofire[num] | lastmask[num] : autofire[num] & ~lastmask[num];
if (hasAPI1_5())
{
if (!found) sprintf(str, "Auto fire: %d ms", af_delay[num] * 2);
else sprintf(str, "Auto fire: OFF");
Info(str);
}
else InfoMessage((!found) ? "\n\n Auto fire\n ON" :
"\n\n Auto fire\n OFF");
return;
}
return;
}
else if(joy[num] &0xF)
{
if (press)
{
if (joy[num] & 9)
{
af_delay[num] += 25 << ((joy[num] & 1) ? 1 : 0);
if (af_delay[num] > 500) af_delay[num] = 500;
}
else
{
af_delay[num] -= 25 << ((joy[num] & 2) ? 1 : 0);
if (af_delay[num] < 25) af_delay[num] = 25;
}
static char str[256];
if (hasAPI1_5())
{
sprintf(str, "Auto fire period: %d ms", af_delay[num] * 2);
Info(str);
}
else
{
sprintf(str, "\n\n Auto fire period\n %dms", af_delay[num] * 2);
InfoMessage(str);
}
}
return;
}
}
@@ -1447,7 +1452,7 @@ static void joy_digital(int num, uint16_t mask, uint16_t code, char press, int b
input_cb(&ev, 0, 0);
}
else
else if(jnum)
{
if (press) joy[num] |= mask;
else joy[num] &= ~mask;
@@ -1465,10 +1470,11 @@ static void joy_digital(int num, uint16_t mask, uint16_t code, char press, int b
static void joy_analog(int num, int axis, int offset)
{
static int pos[2][2] = { 0 };
static int pos[NUMPLAYERS][2] = {};
if (num < 2)
if (num > 0 && num < NUMPLAYERS+1)
{
num--;
pos[num][axis] = offset;
user_io_analog_joystick(num, (char)(pos[num][0]), (char)(pos[num][1]));
}
@@ -1545,8 +1551,9 @@ static void input_cb(struct input_event *ev, struct input_absinfo *absinfo, int
input[dev].map[13] = 0;
input[dev].map[14] = 0;
input[dev].map[15] = 0;
input[dev].has_map++;
}
input[dev].has_map = 1;
input[dev].has_map++;
}
if (!input[dev].has_mmap)
@@ -1651,7 +1658,24 @@ static void input_cb(struct input_event *ev, struct input_absinfo *absinfo, int
//joystick buttons, digital directions
if (ev->code >= 256)
{
if (first_joystick < 0) first_joystick = dev;
if (!input[dev].num)
{
for (uint8_t num = 1; num < NUMDEV + 1; num++)
{
int found = 0;
for (int i = 0; i < NUMDEV; i++)
{
found = (input[i].num == num);
if (found) break;
}
if (!found)
{
input[dev].num = num;
break;
}
}
}
if (user_io_osd_is_visible())
{
@@ -1711,11 +1735,16 @@ static void input_cb(struct input_event *ev, struct input_absinfo *absinfo, int
{
if (ev->code == input[dev].map[i])
{
if (ev->value <= 1) joy_digital((first_joystick == dev) ? 0 : 1, 1 << i, 0, ev->value, i);
if (ev->value <= 1) joy_digital(input[dev].num, 1 << i, 0, ev->value, i);
return;
}
}
}
else if (input[dev].has_map == 2)
{
if (ev->value == 1) joy_digital(0, 0, 0, 3, 17);
return;
}
else
{
for (int i = 0; i <= 15; i++)
@@ -1723,7 +1752,7 @@ static void input_cb(struct input_event *ev, struct input_absinfo *absinfo, int
if (ev->code == input[dev].map[i])
{
if (i <= 3 && origcode == ev->code) origcode = 0; // prevent autofire for original dpad
if (ev->value <= 1) joy_digital((first_joystick == dev) ? 0 : 1, 1 << i, origcode, ev->value, i);
if (ev->value <= 1) joy_digital(input[dev].num, 1 << i, origcode, ev->value, i);
return;
}
}
@@ -1733,7 +1762,7 @@ static void input_cb(struct input_event *ev, struct input_absinfo *absinfo, int
if (ev->code == input[dev].mmap[i])
{
if (origcode == ev->code) origcode = 0; // prevent autofire for original dpad
if (ev->value <= 1) joy_digital((first_joystick == dev) ? 0 : 1, 1 << (i - 8), origcode, ev->value, i - 8);
if (ev->value <= 1) joy_digital(input[dev].num, 1 << (i - 8), origcode, ev->value, i - 8);
return;
}
}
@@ -1741,7 +1770,7 @@ static void input_cb(struct input_event *ev, struct input_absinfo *absinfo, int
if (ev->code == input[dev].mmap[17])
{
if (ev->value <= 1) joy_digital((first_joystick == dev) ? 0 : 1, 0, 0, ev->value, 17);
if (ev->value <= 1) joy_digital(input[dev].num, 0, 0, ev->value, 17);
return;
}
@@ -1805,7 +1834,7 @@ static void input_cb(struct input_event *ev, struct input_absinfo *absinfo, int
if (ev->code == input[dev].map[i])
{
if (i <= 3 && origcode == ev->code) origcode = 0; // prevent autofire for original dpad
if (ev->value <= 1) joy_digital((user_io_get_kbdemu() == EMU_JOY0) ? 0 : 1, 1 << i, origcode, ev->value, i);
if (ev->value <= 1) joy_digital((user_io_get_kbdemu() == EMU_JOY0) ? 1 : 2, 1 << i, origcode, ev->value, i);
return;
}
}
@@ -1813,7 +1842,7 @@ static void input_cb(struct input_event *ev, struct input_absinfo *absinfo, int
if (ev->code == input[dev].mmap[16])
{
if (ev->value <= 1) joy_digital((user_io_get_kbdemu() == EMU_JOY0) ? 0 : 1, 0, 0, ev->value, 16);
if (ev->value <= 1) joy_digital((user_io_get_kbdemu() == EMU_JOY0) ? 1 : 2, 0, 0, ev->value, 16);
return;
}
}
@@ -1914,7 +1943,7 @@ static void input_cb(struct input_event *ev, struct input_absinfo *absinfo, int
else
{
// skip if first joystick is not defined.
if (first_joystick < 0) break;
if (!input[dev].num) break;
// TODO:
// 1) add analog axis mapping
@@ -1925,7 +1954,7 @@ static void input_cb(struct input_event *ev, struct input_absinfo *absinfo, int
int offset = 0;
if (value < 127 || value>129) offset = value - 128;
//printf("analog_x = %d\n", offset);
joy_analog((first_joystick == dev) ? 0 : 1, 0, offset);
joy_analog(input[dev].num, 0, offset);
return;
}
@@ -1934,7 +1963,7 @@ static void input_cb(struct input_event *ev, struct input_absinfo *absinfo, int
int offset = 0;
if (value < 127 || value>129) offset = value - 128;
//printf("analog_y = %d\n", offset);
joy_analog((first_joystick == dev) ? 0 : 1, 1, offset);
joy_analog(input[dev].num, 1, offset);
return;
}
}
@@ -2095,12 +2124,12 @@ int input_test(int getchar)
{
//keyboard, buttons
case EV_KEY:
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, jnum=%d, ID:%04x:%04x\n", ev.code, ev.code, ev.value, input[i].num, input[i].vid, input[i].pid);
break;
//mouse
case EV_REL:
printf("Input event: type=EV_REL, Axis=%d, Offset:=%d\n", ev.code, ev.value);
printf("Input event: type=EV_REL, Axis=%d, Offset:=%d, jnum=%d, ID:%04x:%04x\n", ev.code, ev.value, input[i].num, input[i].vid, input[i].pid);
break;
case EV_SYN:
@@ -2122,7 +2151,7 @@ int input_test(int getchar)
if (input[i].vid == 0x0079 && input[i].pid == 0x0006)
{ if (ev.code == 2) break; }
printf("Input event: type=EV_ABS, Axis=%d, Offset:=%d.", ev.code, ev.value);
printf("Input event: type=EV_ABS, Axis=%d, Offset:=%d, jnum=%d, ID:%04x:%04x.", ev.code, ev.value, input[i].num, input[i].vid, input[i].pid);
printf(" ABS_INFO: min = %d max = %d", absinfo.minimum, absinfo.maximum);
if (absinfo.fuzz) printf(" fuzz = %d", absinfo.fuzz);
if (absinfo.resolution) printf(" res = %d", absinfo.resolution);
@@ -2130,7 +2159,7 @@ int input_test(int getchar)
break;
default:
printf("Input event: type=%d, code=%d(0x%x), value=%d(0x%x)\n", ev.type, ev.code, ev.code, ev.value, ev.value);
printf("Input event: type=%d, code=%d(0x%x), value=%d(0x%x), jnum=%d, ID:%04x:%04x\n", ev.type, ev.code, ev.code, ev.value, ev.value, input[i].num, input[i].vid, input[i].pid);
}
}
@@ -2159,8 +2188,9 @@ int input_test(int getchar)
uint16_t base_axis = !user_io_get_joy_transl() ? 0 : ~ev.code;
uint16_t extra_axis = 2;
if (input[i].vid == 0x0079 && input[i].pid == 0x0006) extra_axis = 0; // AliExpress USB encoder PCB floods axis 2
if (input[i].vid == 0x045e && input[i].pid == 0x028e) extra_axis = 3; // 8BitDo Retro Receiver
if (input[i].vid == 0x046d && input[i].pid == 0xc21f) extra_axis = 3; // Logitech F710
if (input[i].vid == 0x0079 && input[i].pid == 0x0006) extra_axis = 0; // AliExpress USB encoder PCB floods axis 2
if(ev.code == base_axis || ev.code == extra_axis || ev.code == 16) // x
{
@@ -2178,10 +2208,11 @@ int input_test(int getchar)
}
base_axis = !user_io_get_joy_transl() ? 1 : ~ev.code;
if (input[i].vid == 0x0079 && input[i].pid == 0x0006) base_axis = 3; // AliExpress USB encoder PCB
extra_axis = 5;
if (input[i].vid == 0x045e && input[i].pid == 0x028e) extra_axis = 4; // 8BitDo Retro Receiver
if (input[i].vid == 0x046d && input[i].pid == 0xc21f) extra_axis = 4; // Logitech F710
if (input[i].vid == 0x0079 && input[i].pid == 0x0006) extra_axis = 3; // AliExpress USB encoder PCB
if (ev.code == base_axis || ev.code == extra_axis || ev.code == 17) // y
{
@@ -2201,7 +2232,8 @@ int input_test(int getchar)
}
}
if (input[i].vid == 0x045e && input[i].pid == 0x028e) // 8BitDo Retro Receiver
if ((input[i].vid == 0x045e && input[i].pid == 0x028e) || // 8BitDo Retro Receiver
(input[i].vid == 0x046d && input[i].pid == 0xc21f)) // Logitech F710
{
ev.type = EV_KEY;
if (ev.code == 2)
@@ -2265,8 +2297,8 @@ int input_test(int getchar)
int input_poll(int getchar)
{
static int af[2] = { 0 };
static uint32_t time[2] = { 0 };
static int af[NUMPLAYERS] = {};
static uint32_t time[NUMPLAYERS] = {};
int ret = input_test(getchar);
if (getchar) return ret;
@@ -2298,8 +2330,10 @@ int input_poll(int getchar)
if (!mouse_emu_x && !mouse_emu_y) mouse_timer = 0;
for (int i = 0; i < 2; i++)
for (int i = 0; i < NUMPLAYERS; i++)
{
if (!af_delay[i]) af_delay[i] = 50;
if (!time[i]) time[i] = GetTimer(af_delay[i]);
int send = 0;

160
lib/libco/amd64.c Normal file
View File

@@ -0,0 +1,160 @@
/*
libco.amd64 (2016-09-14)
author: byuu
license: public domain
*/
#define LIBCO_C
#include "libco.h"
#include "settings.h"
#include <assert.h>
#include <stdlib.h>
#ifdef __cplusplus
extern "C" {
#endif
static thread_local long long co_active_buffer[64];
static thread_local cothread_t co_active_handle = 0;
static void (*co_swap)(cothread_t, cothread_t) = 0;
#ifdef LIBCO_MPROTECT
alignas(4096)
#else
section(text)
#endif
#ifdef _WIN32
/* ABI: Win64 */
static const unsigned char co_swap_function[4096] = {
0x48, 0x89, 0x22, /* mov [rdx],rsp */
0x48, 0x8b, 0x21, /* mov rsp,[rcx] */
0x58, /* pop rax */
0x48, 0x89, 0x6a, 0x08, /* mov [rdx+ 8],rbp */
0x48, 0x89, 0x72, 0x10, /* mov [rdx+16],rsi */
0x48, 0x89, 0x7a, 0x18, /* mov [rdx+24],rdi */
0x48, 0x89, 0x5a, 0x20, /* mov [rdx+32],rbx */
0x4c, 0x89, 0x62, 0x28, /* mov [rdx+40],r12 */
0x4c, 0x89, 0x6a, 0x30, /* mov [rdx+48],r13 */
0x4c, 0x89, 0x72, 0x38, /* mov [rdx+56],r14 */
0x4c, 0x89, 0x7a, 0x40, /* mov [rdx+64],r15 */
#if !defined(LIBCO_NO_SSE)
0x0f, 0x29, 0x72, 0x50, /* movaps [rdx+ 80],xmm6 */
0x0f, 0x29, 0x7a, 0x60, /* movaps [rdx+ 96],xmm7 */
0x44, 0x0f, 0x29, 0x42, 0x70, /* movaps [rdx+112],xmm8 */
0x48, 0x83, 0xc2, 0x70, /* add rdx,112 */
0x44, 0x0f, 0x29, 0x4a, 0x10, /* movaps [rdx+ 16],xmm9 */
0x44, 0x0f, 0x29, 0x52, 0x20, /* movaps [rdx+ 32],xmm10 */
0x44, 0x0f, 0x29, 0x5a, 0x30, /* movaps [rdx+ 48],xmm11 */
0x44, 0x0f, 0x29, 0x62, 0x40, /* movaps [rdx+ 64],xmm12 */
0x44, 0x0f, 0x29, 0x6a, 0x50, /* movaps [rdx+ 80],xmm13 */
0x44, 0x0f, 0x29, 0x72, 0x60, /* movaps [rdx+ 96],xmm14 */
0x44, 0x0f, 0x29, 0x7a, 0x70, /* movaps [rdx+112],xmm15 */
#endif
0x48, 0x8b, 0x69, 0x08, /* mov rbp,[rcx+ 8] */
0x48, 0x8b, 0x71, 0x10, /* mov rsi,[rcx+16] */
0x48, 0x8b, 0x79, 0x18, /* mov rdi,[rcx+24] */
0x48, 0x8b, 0x59, 0x20, /* mov rbx,[rcx+32] */
0x4c, 0x8b, 0x61, 0x28, /* mov r12,[rcx+40] */
0x4c, 0x8b, 0x69, 0x30, /* mov r13,[rcx+48] */
0x4c, 0x8b, 0x71, 0x38, /* mov r14,[rcx+56] */
0x4c, 0x8b, 0x79, 0x40, /* mov r15,[rcx+64] */
#if !defined(LIBCO_NO_SSE)
0x0f, 0x28, 0x71, 0x50, /* movaps xmm6, [rcx+ 80] */
0x0f, 0x28, 0x79, 0x60, /* movaps xmm7, [rcx+ 96] */
0x44, 0x0f, 0x28, 0x41, 0x70, /* movaps xmm8, [rcx+112] */
0x48, 0x83, 0xc1, 0x70, /* add rcx,112 */
0x44, 0x0f, 0x28, 0x49, 0x10, /* movaps xmm9, [rcx+ 16] */
0x44, 0x0f, 0x28, 0x51, 0x20, /* movaps xmm10,[rcx+ 32] */
0x44, 0x0f, 0x28, 0x59, 0x30, /* movaps xmm11,[rcx+ 48] */
0x44, 0x0f, 0x28, 0x61, 0x40, /* movaps xmm12,[rcx+ 64] */
0x44, 0x0f, 0x28, 0x69, 0x50, /* movaps xmm13,[rcx+ 80] */
0x44, 0x0f, 0x28, 0x71, 0x60, /* movaps xmm14,[rcx+ 96] */
0x44, 0x0f, 0x28, 0x79, 0x70, /* movaps xmm15,[rcx+112] */
#endif
0xff, 0xe0, /* jmp rax */
};
#include <windows.h>
static void co_init() {
#ifdef LIBCO_MPROTECT
DWORD old_privileges;
VirtualProtect((void*)co_swap_function, sizeof co_swap_function, PAGE_EXECUTE_READ, &old_privileges);
#endif
}
#else
/* ABI: SystemV */
static const unsigned char co_swap_function[4096] = {
0x48, 0x89, 0x26, /* mov [rsi],rsp */
0x48, 0x8b, 0x27, /* mov rsp,[rdi] */
0x58, /* pop rax */
0x48, 0x89, 0x6e, 0x08, /* mov [rsi+ 8],rbp */
0x48, 0x89, 0x5e, 0x10, /* mov [rsi+16],rbx */
0x4c, 0x89, 0x66, 0x18, /* mov [rsi+24],r12 */
0x4c, 0x89, 0x6e, 0x20, /* mov [rsi+32],r13 */
0x4c, 0x89, 0x76, 0x28, /* mov [rsi+40],r14 */
0x4c, 0x89, 0x7e, 0x30, /* mov [rsi+48],r15 */
0x48, 0x8b, 0x6f, 0x08, /* mov rbp,[rdi+ 8] */
0x48, 0x8b, 0x5f, 0x10, /* mov rbx,[rdi+16] */
0x4c, 0x8b, 0x67, 0x18, /* mov r12,[rdi+24] */
0x4c, 0x8b, 0x6f, 0x20, /* mov r13,[rdi+32] */
0x4c, 0x8b, 0x77, 0x28, /* mov r14,[rdi+40] */
0x4c, 0x8b, 0x7f, 0x30, /* mov r15,[rdi+48] */
0xff, 0xe0, /* jmp rax */
};
#include <unistd.h>
#include <sys/mman.h>
static void co_init() {
#ifdef LIBCO_MPROTECT
unsigned long long addr = (unsigned long long)co_swap_function;
unsigned long long base = addr - (addr % sysconf(_SC_PAGESIZE));
unsigned long long size = (addr - base) + sizeof co_swap_function;
mprotect((void*)base, size, PROT_READ | PROT_EXEC);
#endif
}
#endif
static void crash() {
assert(0); /* called only if cothread_t entrypoint returns */
}
cothread_t co_active() {
if(!co_active_handle) co_active_handle = &co_active_buffer;
return co_active_handle;
}
cothread_t co_create(unsigned int size, void (*entrypoint)(void)) {
cothread_t handle;
if(!co_swap) {
co_init();
co_swap = (void (*)(cothread_t, cothread_t))co_swap_function;
}
if(!co_active_handle) co_active_handle = &co_active_buffer;
size += 512; /* allocate additional space for storage */
size &= ~15; /* align stack to 16-byte boundary */
if(handle = (cothread_t)malloc(size)) {
long long *p = (long long*)((char*)handle + size); /* seek to top of stack */
*--p = (long long)crash; /* crash if entrypoint returns */
*--p = (long long)entrypoint; /* start of function */
*(long long*)handle = (long long)p; /* stack pointer */
}
return handle;
}
void co_delete(cothread_t handle) {
free(handle);
}
void co_switch(cothread_t handle) {
register cothread_t co_previous_handle = co_active_handle;
co_swap(co_active_handle = handle, co_previous_handle);
}
#ifdef __cplusplus
}
#endif

79
lib/libco/arm.c Normal file
View File

@@ -0,0 +1,79 @@
/*
libco.arm (2016-09-14)
author: byuu
license: public domain
*/
#define LIBCO_C
#include "libco.h"
#include "settings.h"
#include <assert.h>
#include <stdlib.h>
#include <unistd.h>
#include <sys/mman.h>
#ifdef __cplusplus
extern "C" {
#endif
static thread_local unsigned long co_active_buffer[64];
static thread_local cothread_t co_active_handle = 0;
static void (*co_swap)(cothread_t, cothread_t) = 0;
#ifdef LIBCO_MPROTECT
alignas(4096)
#else
section(text)
#endif
static const unsigned long co_swap_function[1024] = {
0xe8a16ff0, /* stmia r1!, {r4-r11,sp,lr} */
0xe8b0aff0, /* ldmia r0!, {r4-r11,sp,pc} */
0xe12fff1e, /* bx lr */
};
static void co_init() {
#ifdef LIBCO_MPROTECT
unsigned long addr = (unsigned long)co_swap_function;
unsigned long base = addr - (addr % sysconf(_SC_PAGESIZE));
unsigned long size = (addr - base) + sizeof co_swap_function;
mprotect((void*)base, size, PROT_READ | PROT_EXEC);
#endif
}
cothread_t co_active() {
if(!co_active_handle) co_active_handle = &co_active_buffer;
return co_active_handle;
}
cothread_t co_create(unsigned int size, void (*entrypoint)(void)) {
unsigned long* handle = 0;
if(!co_swap) {
co_init();
co_swap = (void (*)(cothread_t, cothread_t))co_swap_function;
}
if(!co_active_handle) co_active_handle = &co_active_buffer;
size += 256;
size &= ~15;
if((handle = (unsigned long*)malloc(size))) {
unsigned long* p = (unsigned long*)((unsigned char*)handle + size);
handle[8] = (unsigned long)p;
handle[9] = (unsigned long)entrypoint;
}
return handle;
}
void co_delete(cothread_t handle) {
free(handle);
}
void co_switch(cothread_t handle) {
cothread_t co_previous_handle = co_active_handle;
co_swap(co_active_handle = handle, co_previous_handle);
}
#ifdef __cplusplus
}
#endif

8
lib/libco/doc/style.css Normal file
View File

@@ -0,0 +1,8 @@
body {
background: #333;
color: #fff;
}
code {
background: #444;
}

View File

@@ -0,0 +1,89 @@
<html>
<head>
<title></title>
<link href="style.css" rel="stylesheet" type="text/css">
</head>
<body>
<b>Supported targets:</b><br/><br/>
Note that supported targets are only those that have been tested and confirmed
working. It is quite possible that libco will work on more processors, compilers
and operating systems than those listed below.
<hr/>
<b>libco.x86</b><br/>
Overhead: ~5x<br/>
Supported processor(s): 32-bit x86<br/>
Supported compiler(s): any<br/>
Supported operating system(s):<ul>
<li>Windows</li>
<li>Mac OS X</li>
<li>Linux</li>
<li>BSD</li>
</ul>
<hr/>
<b>libco.amd64</b><br/>
Overhead: ~10x (Windows), ~6x (all other platforms)<br/>
Supported processor(s): 64-bit amd64<br/>
Supported compiler(s): any<br/>
Supported operating system(s):<ul>
<li>Windows</li>
<li>Mac OS X</li>
<li>Linux</li>
<li>BSD</li>
</ul>
<hr/>
<b>libco.ppc</b><br/>
Overhead: ~20x<br/>
Supported processor(s): 32-bit PowerPC, 64-bit PowerPC<br/>
Supported compiler(s): GNU GCC<br/>
Supported operating system(s):<ul>
</ul>
<li>Mac OS X</li>
<li>Linux</li>
<li>BSD</li>
<li>Playstation 3</li>
</ul>
<br/>
Note: this module contains compiler flags to enable/disable FPU and Altivec
support.
<hr/>
<b>libco.fiber</b><br/>
Overhead: ~15x<br/>
Supported processor(s): Processor independent<br/>
Supported compiler(s): any<br/>
Supported operating system(s):<ul>
<li>Windows</li>
</ul>
<hr/>
<b>libco.sjlj</b><br/>
Overhead: ~30x<br/>
Supported processor(s): Processor independent<br/>
Supported compiler(s): any<br/>
Supported operating system(s):<ul>
<li>Mac OS X</li>
<li>Linux</li>
<li>BSD</li>
<li>Solaris</li>
</ul>
<hr/>
<b>libco.ucontext</b><br/>
Overhead: <b><font color="#ff0000">~300x</font></b><br/>
Supported processor(s): Processor independent<br/>
Supported compiler(s): any<br/>
Supported operating system(s):<ul>
<li>Linux</li>
<li>BSD</li>
</ul>
<hr/>
</body>
</html>

107
lib/libco/doc/usage.html Normal file
View File

@@ -0,0 +1,107 @@
<html>
<head>
<title></title>
<link href="style.css" rel="stylesheet" type="text/css">
</head>
<body>
<b>License:</b><br/><br/>
libco is released to the public domain.
<hr/>
<b>Contact:</b><br/><br/>
At present, you may contact me at setsunakun0 at hotmail dot com.<br/>
I am interested in knowing of any projects that make use of this library,
though this is only a courtesy.
<hr/>
<b>Foreword:</b><br/><br/>
libco is a cross-platform, public domain implementation of
cooperative-multithreading; a feature that is sorely lacking
from the ISO C/C++ standard.<br/>
The library is designed for maximum speed and portability, and
not for safety or features. If safety or extra functionality is desired,
a wrapper API can easily be written to encapsulate all library functions.<br/>
Behavior of executing operations that are listed as not permitted
below result in undefined behavior. They may work anyway, they
may cause undesired / unknown behavior, or they may crash the
program entirely.<br/>
The goal of this library was to simplify the base API as much as possible,
implementing only that which cannot be implemented using pure C. Additional
functionality after this would only complicate ports of this library to new
platforms.
<hr/>
<b>Porting:</b><br/><br/>
This document is included as a reference for porting libco. Please submit any
ports you create to me, so that libco can become more useful. Please note that
since libco is public domain, you must submit your code as a work of the
public domain in order for it to be included in the official distribution.
Full credit will be given in the source code of the official release. Please
do not bother submitting code to me under any other license -- including GPL,
LGPL, BSD or CC -- I am not interested in creating a library with multiple
different licenses depending on which targets are used.
<hr/>
<b>Synopsis:</b><br/><br/>
<code>
typedef void* cothread_t;<br/>
<br/>
cothread_t co_active();<br/>
cothread_t co_create(unsigned int heapsize, void (*coentry)(void));<br/>
void &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;co_delete(cothread_t cothread);<br/>
void &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;co_switch(cothread_t cothread);<br/>
</code>
<hr/>
<b>Usage:</b>
<hr/>
<code>typedef void* cothread_t;</code><br/><br/>
Handle to cothread.<br/>
Handle must be of type void*.<br/>
A value of null (0) indicates an uninitialized or invalid
handle, whereas a non-zero value indicates a valid handle.
<hr/>
<code>cothread_t co_active();</code><br/><br/>
Return handle to current cothread. Always returns a valid handle, even when
called from the main program thread.
<hr/>
<code>cothread_t co_create(unsigned int heapsize, void (*coentry)(void));</code><br/><br/>
Create new cothread.<br/>
Heapsize is the amount of memory allocated for the cothread stack, specified
in bytes. This is unfortunately impossible to make fully portable. It is
recommended to specify sizes using `n * sizeof(void*)'. It is better to err
on the side of caution and allocate more memory than will be needed to ensure
compatibility with other platforms, within reason. A typical heapsize for a
32-bit architecture is ~1MB.<br/>
When the new cothread is first called, program execution jumps to coentry.
This function does not take any arguments, due to portability issues with
passing function arguments. However, arguments can be simulated by the use
of global variables, which can be set before the first call to each cothread.<br/>
coentry() must not return, and should end with an appropriate co_switch()
statement. Behavior is undefined if entry point returns normally.<br/>
Library is responsible for allocating cothread stack memory, to free
the user from needing to allocate special memory capable of being used
as program stack memory on platforms where this is required.<br/>
User is always responsible for deleting cothreads with co_delete().<br/>
Return value of null (0) indicates cothread creation failed.
<hr/>
<code>void co_delete(cothread_t cothread);</code><br/><br/>
Delete specified cothread.<br/>
Null (0) or invalid cothread handle is not allowed.<br/>
Passing handle of active cothread to this function is not allowed.<br/>
Passing handle of primary cothread is not allowed.
<hr/>
<code>void co_switch(cothread_t cothread);</code><br/><br/>
Switch to specified cothread.<br/>
Null (0) or invalid cothread handle is not allowed.<br/>
Passing handle of active cothread to this function is not allowed.
<hr/>
</body>
</html>

51
lib/libco/fiber.c Normal file
View File

@@ -0,0 +1,51 @@
/*
libco.win (2008-01-28)
authors: Nach, byuu
license: public domain
*/
#define LIBCO_C
#include "libco.h"
#define WINVER 0x0400
#define _WIN32_WINNT 0x0400
#include <windows.h>
#ifdef __cplusplus
extern "C" {
#endif
static thread_local cothread_t co_active_ = 0;
static void __stdcall co_thunk(void* coentry) {
((void (*)(void))coentry)();
}
cothread_t co_active() {
if(!co_active_) {
ConvertThreadToFiber(0);
co_active_ = GetCurrentFiber();
}
return co_active_;
}
cothread_t co_create(unsigned int heapsize, void (*coentry)(void)) {
if(!co_active_) {
ConvertThreadToFiber(0);
co_active_ = GetCurrentFiber();
}
return (cothread_t)CreateFiber(heapsize, co_thunk, (void*)coentry);
}
void co_delete(cothread_t cothread) {
DeleteFiber(cothread);
}
void co_switch(cothread_t cothread) {
co_active_ = cothread;
SwitchToFiber(cothread);
}
#ifdef __cplusplus
}
#endif

34
lib/libco/libco.c Normal file
View File

@@ -0,0 +1,34 @@
/*
libco
license: public domain
*/
#if defined(__clang__)
#pragma clang diagnostic ignored "-Wparentheses"
#endif
#if defined(__clang__) || defined(__GNUC__)
#if defined(__i386__)
#include "x86.c"
#elif defined(__amd64__)
#include "amd64.c"
#elif defined(__arm__)
#include "arm.c"
#elif defined(_ARCH_PPC)
#include "ppc.c"
#elif defined(_WIN32)
#include "fiber.c"
#else
#include "sjlj.c"
#endif
#elif defined(_MSC_VER)
#if defined(_M_IX86)
#include "x86.c"
#elif defined(_M_AMD64)
#include "amd64.c"
#else
#include "fiber.c"
#endif
#else
#error "libco: unsupported processor, compiler or operating system"
#endif

26
lib/libco/libco.h Normal file
View File

@@ -0,0 +1,26 @@
/*
libco v18 (2016-09-14)
author: byuu
license: public domain
*/
#ifndef LIBCO_H
#define LIBCO_H
#ifdef __cplusplus
extern "C" {
#endif
typedef void* cothread_t;
cothread_t co_active();
cothread_t co_create(unsigned int, void (*)(void));
void co_delete(cothread_t);
void co_switch(cothread_t);
#ifdef __cplusplus
}
#endif
/* ifndef LIBCO_H */
#endif

367
lib/libco/ppc.c Normal file
View File

@@ -0,0 +1,367 @@
/*
libco.ppc (2016-09-14)
author: blargg
license: public domain
*/
#define LIBCO_C
#include "libco.h"
#include "settings.h"
#include <stdlib.h>
#include <stdint.h>
#include <string.h>
#if LIBCO_MPROTECT
#include <unistd.h>
#include <sys/mman.h>
#endif
/* state format (offsets in 32-bit words)
+0 pointer to swap code
rest of function descriptor for entry function
+8 PC
+10 SP
special registers
GPRs
FPRs
VRs
stack
*/
enum { state_size = 1024 };
enum { above_stack = 2048 };
enum { stack_align = 256 };
static thread_local cothread_t co_active_handle = 0;
/* determine environment */
#define LIBCO_PPC64 (_ARCH_PPC64 || __PPC64__ || __ppc64__ || __powerpc64__)
/* whether function calls are indirect through a descriptor, or are directly to function */
#ifndef LIBCO_PPCDESC
#if !_CALL_SYSV && (_CALL_AIX || _CALL_AIXDESC || LIBCO_PPC64)
#define LIBCO_PPCDESC 1
#endif
#endif
#ifdef LIBCO_MPROTECT
alignas(4096)
#else
section(text)
#endif
static const uint32_t libco_ppc_code[1024] = {
#if LIBCO_PPC64
0x7d000026, /* mfcr r8 */
0xf8240028, /* std r1,40(r4) */
0x7d2802a6, /* mflr r9 */
0xf9c40048, /* std r14,72(r4) */
0xf9e40050, /* std r15,80(r4) */
0xfa040058, /* std r16,88(r4) */
0xfa240060, /* std r17,96(r4) */
0xfa440068, /* std r18,104(r4) */
0xfa640070, /* std r19,112(r4) */
0xfa840078, /* std r20,120(r4) */
0xfaa40080, /* std r21,128(r4) */
0xfac40088, /* std r22,136(r4) */
0xfae40090, /* std r23,144(r4) */
0xfb040098, /* std r24,152(r4) */
0xfb2400a0, /* std r25,160(r4) */
0xfb4400a8, /* std r26,168(r4) */
0xfb6400b0, /* std r27,176(r4) */
0xfb8400b8, /* std r28,184(r4) */
0xfba400c0, /* std r29,192(r4) */
0xfbc400c8, /* std r30,200(r4) */
0xfbe400d0, /* std r31,208(r4) */
0xf9240020, /* std r9,32(r4) */
0xe8e30020, /* ld r7,32(r3) */
0xe8230028, /* ld r1,40(r3) */
0x48000009, /* bl 1 */
0x7fe00008, /* trap */
0x91040030, /*1:stw r8,48(r4) */
0x80c30030, /* lwz r6,48(r3) */
0x7ce903a6, /* mtctr r7 */
0xe9c30048, /* ld r14,72(r3) */
0xe9e30050, /* ld r15,80(r3) */
0xea030058, /* ld r16,88(r3) */
0xea230060, /* ld r17,96(r3) */
0xea430068, /* ld r18,104(r3) */
0xea630070, /* ld r19,112(r3) */
0xea830078, /* ld r20,120(r3) */
0xeaa30080, /* ld r21,128(r3) */
0xeac30088, /* ld r22,136(r3) */
0xeae30090, /* ld r23,144(r3) */
0xeb030098, /* ld r24,152(r3) */
0xeb2300a0, /* ld r25,160(r3) */
0xeb4300a8, /* ld r26,168(r3) */
0xeb6300b0, /* ld r27,176(r3) */
0xeb8300b8, /* ld r28,184(r3) */
0xeba300c0, /* ld r29,192(r3) */
0xebc300c8, /* ld r30,200(r3) */
0xebe300d0, /* ld r31,208(r3) */
0x7ccff120, /* mtcr r6 */
#else
0x7d000026, /* mfcr r8 */
0x90240028, /* stw r1,40(r4) */
0x7d2802a6, /* mflr r9 */
0x91a4003c, /* stw r13,60(r4) */
0x91c40040, /* stw r14,64(r4) */
0x91e40044, /* stw r15,68(r4) */
0x92040048, /* stw r16,72(r4) */
0x9224004c, /* stw r17,76(r4) */
0x92440050, /* stw r18,80(r4) */
0x92640054, /* stw r19,84(r4) */
0x92840058, /* stw r20,88(r4) */
0x92a4005c, /* stw r21,92(r4) */
0x92c40060, /* stw r22,96(r4) */
0x92e40064, /* stw r23,100(r4) */
0x93040068, /* stw r24,104(r4) */
0x9324006c, /* stw r25,108(r4) */
0x93440070, /* stw r26,112(r4) */
0x93640074, /* stw r27,116(r4) */
0x93840078, /* stw r28,120(r4) */
0x93a4007c, /* stw r29,124(r4) */
0x93c40080, /* stw r30,128(r4) */
0x93e40084, /* stw r31,132(r4) */
0x91240020, /* stw r9,32(r4) */
0x80e30020, /* lwz r7,32(r3) */
0x80230028, /* lwz r1,40(r3) */
0x48000009, /* bl 1 */
0x7fe00008, /* trap */
0x91040030, /*1:stw r8,48(r4) */
0x80c30030, /* lwz r6,48(r3) */
0x7ce903a6, /* mtctr r7 */
0x81a3003c, /* lwz r13,60(r3) */
0x81c30040, /* lwz r14,64(r3) */
0x81e30044, /* lwz r15,68(r3) */
0x82030048, /* lwz r16,72(r3) */
0x8223004c, /* lwz r17,76(r3) */
0x82430050, /* lwz r18,80(r3) */
0x82630054, /* lwz r19,84(r3) */
0x82830058, /* lwz r20,88(r3) */
0x82a3005c, /* lwz r21,92(r3) */
0x82c30060, /* lwz r22,96(r3) */
0x82e30064, /* lwz r23,100(r3) */
0x83030068, /* lwz r24,104(r3) */
0x8323006c, /* lwz r25,108(r3) */
0x83430070, /* lwz r26,112(r3) */
0x83630074, /* lwz r27,116(r3) */
0x83830078, /* lwz r28,120(r3) */
0x83a3007c, /* lwz r29,124(r3) */
0x83c30080, /* lwz r30,128(r3) */
0x83e30084, /* lwz r31,132(r3) */
0x7ccff120, /* mtcr r6 */
#endif
#ifndef LIBCO_PPC_NOFP
0xd9c400e0, /* stfd f14,224(r4) */
0xd9e400e8, /* stfd f15,232(r4) */
0xda0400f0, /* stfd f16,240(r4) */
0xda2400f8, /* stfd f17,248(r4) */
0xda440100, /* stfd f18,256(r4) */
0xda640108, /* stfd f19,264(r4) */
0xda840110, /* stfd f20,272(r4) */
0xdaa40118, /* stfd f21,280(r4) */
0xdac40120, /* stfd f22,288(r4) */
0xdae40128, /* stfd f23,296(r4) */
0xdb040130, /* stfd f24,304(r4) */
0xdb240138, /* stfd f25,312(r4) */
0xdb440140, /* stfd f26,320(r4) */
0xdb640148, /* stfd f27,328(r4) */
0xdb840150, /* stfd f28,336(r4) */
0xdba40158, /* stfd f29,344(r4) */
0xdbc40160, /* stfd f30,352(r4) */
0xdbe40168, /* stfd f31,360(r4) */
0xc9c300e0, /* lfd f14,224(r3) */
0xc9e300e8, /* lfd f15,232(r3) */
0xca0300f0, /* lfd f16,240(r3) */
0xca2300f8, /* lfd f17,248(r3) */
0xca430100, /* lfd f18,256(r3) */
0xca630108, /* lfd f19,264(r3) */
0xca830110, /* lfd f20,272(r3) */
0xcaa30118, /* lfd f21,280(r3) */
0xcac30120, /* lfd f22,288(r3) */
0xcae30128, /* lfd f23,296(r3) */
0xcb030130, /* lfd f24,304(r3) */
0xcb230138, /* lfd f25,312(r3) */
0xcb430140, /* lfd f26,320(r3) */
0xcb630148, /* lfd f27,328(r3) */
0xcb830150, /* lfd f28,336(r3) */
0xcba30158, /* lfd f29,344(r3) */
0xcbc30160, /* lfd f30,352(r3) */
0xcbe30168, /* lfd f31,360(r3) */
#endif
#ifdef __ALTIVEC__
0x7ca042a6, /* mfvrsave r5 */
0x39040180, /* addi r8,r4,384 */
0x39240190, /* addi r9,r4,400 */
0x70a00fff, /* andi. r0,r5,4095 */
0x90a40034, /* stw r5,52(r4) */
0x4182005c, /* beq- 2 */
0x7e8041ce, /* stvx v20,r0,r8 */
0x39080020, /* addi r8,r8,32 */
0x7ea049ce, /* stvx v21,r0,r9 */
0x39290020, /* addi r9,r9,32 */
0x7ec041ce, /* stvx v22,r0,r8 */
0x39080020, /* addi r8,r8,32 */
0x7ee049ce, /* stvx v23,r0,r9 */
0x39290020, /* addi r9,r9,32 */
0x7f0041ce, /* stvx v24,r0,r8 */
0x39080020, /* addi r8,r8,32 */
0x7f2049ce, /* stvx v25,r0,r9 */
0x39290020, /* addi r9,r9,32 */
0x7f4041ce, /* stvx v26,r0,r8 */
0x39080020, /* addi r8,r8,32 */
0x7f6049ce, /* stvx v27,r0,r9 */
0x39290020, /* addi r9,r9,32 */
0x7f8041ce, /* stvx v28,r0,r8 */
0x39080020, /* addi r8,r8,32 */
0x7fa049ce, /* stvx v29,r0,r9 */
0x39290020, /* addi r9,r9,32 */
0x7fc041ce, /* stvx v30,r0,r8 */
0x7fe049ce, /* stvx v31,r0,r9 */
0x80a30034, /*2:lwz r5,52(r3) */
0x39030180, /* addi r8,r3,384 */
0x39230190, /* addi r9,r3,400 */
0x70a00fff, /* andi. r0,r5,4095 */
0x7ca043a6, /* mtvrsave r5 */
0x4d820420, /* beqctr */
0x7e8040ce, /* lvx v20,r0,r8 */
0x39080020, /* addi r8,r8,32 */
0x7ea048ce, /* lvx v21,r0,r9 */
0x39290020, /* addi r9,r9,32 */
0x7ec040ce, /* lvx v22,r0,r8 */
0x39080020, /* addi r8,r8,32 */
0x7ee048ce, /* lvx v23,r0,r9 */
0x39290020, /* addi r9,r9,32 */
0x7f0040ce, /* lvx v24,r0,r8 */
0x39080020, /* addi r8,r8,32 */
0x7f2048ce, /* lvx v25,r0,r9 */
0x39290020, /* addi r9,r9,32 */
0x7f4040ce, /* lvx v26,r0,r8 */
0x39080020, /* addi r8,r8,32 */
0x7f6048ce, /* lvx v27,r0,r9 */
0x39290020, /* addi r9,r9,32 */
0x7f8040ce, /* lvx v28,r0,r8 */
0x39080020, /* addi r8,r8,32 */
0x7fa048ce, /* lvx v29,r0,r9 */
0x39290020, /* addi r9,r9,32 */
0x7fc040ce, /* lvx v30,r0,r8 */
0x7fe048ce, /* lvx v31,r0,r9 */
#endif
0x4e800420, /* bctr */
};
#if LIBCO_PPCDESC
/* function call goes through indirect descriptor */
#define CO_SWAP_ASM(x, y) ((void (*)(cothread_t, cothread_t))(uintptr_t)x)(x, y)
#else
/* function call goes directly to code */
#define CO_SWAP_ASM(x, y) ((void (*)(cothread_t, cothread_t))(uintptr_t)libco_ppc_code)(x, y)
#endif
static uint32_t* co_create_(unsigned size, uintptr_t entry) {
(void)entry;
uint32_t* t = (uint32_t*)malloc(size);
#if LIBCO_PPCDESC
if(t) {
memcpy(t, (void*)entry, sizeof(void*) * 3); /* copy entry's descriptor */
*(const void**)t = libco_ppc_code; /* set function pointer to swap routine */
}
#endif
return t;
}
cothread_t co_create(unsigned int size, void (*entry_)(void)) {
uintptr_t entry = (uintptr_t)entry_;
uint32_t* t = 0;
/* be sure main thread was successfully allocated */
if(co_active()) {
size += state_size + above_stack + stack_align;
t = co_create_(size, entry);
}
if(t) {
uintptr_t sp;
int shift;
/* save current registers into new thread, so that any special ones will have proper values when thread is begun */
CO_SWAP_ASM(t, t);
#if LIBCO_PPCDESC
entry = (uintptr_t)*(void**)entry; /* get real address */
#endif
/* put stack near end of block, and align */
sp = (uintptr_t)t + size - above_stack;
sp -= sp % stack_align;
/* on PPC32, we save and restore GPRs as 32 bits. for PPC64, we
save and restore them as 64 bits, regardless of the size the ABI
uses. so, we manually write pointers at the proper size. we always
save and restore at the same address, and since PPC is big-endian,
we must put the low byte first on PPC32. */
/* if uintptr_t is 32 bits, >>32 is undefined behavior,
so we do two shifts and don't have to care how many bits uintptr_t is. */
#if LIBCO_PPC64
shift = 16;
#else
shift = 0;
#endif
/* set up so entry will be called on next swap */
t[ 8] = (uint32_t)(entry >> shift >> shift);
t[ 9] = (uint32_t)entry;
t[10] = (uint32_t)(sp >> shift >> shift);
t[11] = (uint32_t)sp;
}
return t;
}
void co_delete(cothread_t t) {
free(t);
}
static void co_init_(void) {
#if LIBCO_MPROTECT
long page_size = sysconf(_SC_PAGESIZE);
if(page_size > 0) {
uintptr_t align = page_size;
uintptr_t begin = (uintptr_t)libco_ppc_code;
uintptr_t end = begin + sizeof libco_ppc_code;
/* align beginning and end */
end += align - 1;
end -= end % align;
begin -= begin % align;
mprotect((void*)begin, end - begin, PROT_READ | PROT_EXEC);
}
#endif
co_active_handle = co_create_(state_size, (uintptr_t)&co_switch);
}
cothread_t co_active() {
if(!co_active_handle) co_init_();
return co_active_handle;
}
void co_switch(cothread_t t) {
cothread_t old = co_active_handle;
co_active_handle = t;
CO_SWAP_ASM(t, old);
}

36
lib/libco/settings.h Normal file
View File

@@ -0,0 +1,36 @@
#ifdef LIBCO_C
/*[amd64, arm, ppc, x86]:
by default, co_swap_function is marked as a text (code) section
if not supported, uncomment the below line to use mprotect instead */
/* #define LIBCO_MPROTECT */
/*[amd64]:
Win64 only: provides a substantial speed-up, but will thrash XMM regs
do not use this unless you are certain your application won't use SSE */
/* #define LIBCO_NO_SSE */
#ifdef LIBCO_C
#ifdef LIBCO_MP
#define thread_local __thread
#else
#define thread_local
#endif
#endif
#if __STDC_VERSION__ >= 201112L
#ifndef _MSC_VER
#include <stdalign.h>
#endif
#else
#define alignas(bytes)
#endif
#ifndef _MSC_VER
#define section(name) __attribute__((section("." #name "#")))
#else
#define section(name) __declspec(allocate("." #name))
#endif
/* ifdef LIBCO_C */
#endif

102
lib/libco/sjlj.c Normal file
View File

@@ -0,0 +1,102 @@
/*
libco.sjlj (2008-01-28)
author: Nach
license: public domain
*/
/*
note this was designed for UNIX systems. Based on ideas expressed in a paper by Ralf Engelschall.
for SJLJ on other systems, one would want to rewrite springboard() and co_create() and hack the jmb_buf stack pointer.
*/
#define LIBCO_C
#include "libco.h"
#include <stdlib.h>
#include <signal.h>
#include <setjmp.h>
#ifdef __cplusplus
extern "C" {
#endif
typedef struct {
sigjmp_buf context;
void (*coentry)(void);
void* stack;
} cothread_struct;
static thread_local cothread_struct co_primary;
static thread_local cothread_struct* creating;
static thread_local cothread_struct* co_running = 0;
static void springboard(int ignored) {
if(sigsetjmp(creating->context, 0)) {
co_running->coentry();
}
}
cothread_t co_active() {
if(!co_running) co_running = &co_primary;
return (cothread_t)co_running;
}
cothread_t co_create(unsigned int size, void (*coentry)(void)) {
if(!co_running) co_running = &co_primary;
cothread_struct *thread = (cothread_struct*)malloc(sizeof(cothread_struct));
if(thread) {
struct sigaction handler;
struct sigaction old_handler;
stack_t stack;
stack_t old_stack;
thread->coentry = thread->stack = 0;
stack.ss_flags = 0;
stack.ss_size = size;
thread->stack = stack.ss_sp = malloc(size);
if(stack.ss_sp && !sigaltstack(&stack, &old_stack)) {
handler.sa_handler = springboard;
handler.sa_flags = SA_ONSTACK;
sigemptyset(&handler.sa_mask);
creating = thread;
if(!sigaction(SIGUSR1, &handler, &old_handler)) {
if(!raise(SIGUSR1)) {
thread->coentry = coentry;
}
sigaltstack(&old_stack, 0);
sigaction(SIGUSR1, &old_handler, 0);
}
}
if(thread->coentry != coentry) {
co_delete(thread);
thread = 0;
}
}
return (cothread_t)thread;
}
void co_delete(cothread_t cothread) {
if(cothread) {
if(((cothread_struct*)cothread)->stack) {
free(((cothread_struct*)cothread)->stack);
}
free(cothread);
}
}
void co_switch(cothread_t cothread) {
if(!sigsetjmp(co_running->context, 0)) {
co_running = (cothread_struct*)cothread;
siglongjmp(co_running->context, 1);
}
}
#ifdef __cplusplus
}
#endif

69
lib/libco/ucontext.c Normal file
View File

@@ -0,0 +1,69 @@
/*
libco.ucontext (2008-01-28)
author: Nach
license: public domain
*/
/*
WARNING: the overhead of POSIX ucontext is very high,
assembly versions of libco or libco_sjlj should be much faster
this library only exists for two reasons:
1: as an initial test for the viability of a ucontext implementation
2: to demonstrate the power and speed of libco over existing implementations,
such as pth (which defaults to wrapping ucontext on unix targets)
use this library only as a *last resort*
*/
#define LIBCO_C
#include "libco.h"
#define _BSD_SOURCE
#include <stdlib.h>
#include <ucontext.h>
#ifdef __cplusplus
extern "C" {
#endif
static thread_local ucontext_t co_primary;
static thread_local ucontext_t* co_running = 0;
cothread_t co_active() {
if(!co_running) co_running = &co_primary;
return (cothread_t)co_running;
}
cothread_t co_create(unsigned int heapsize, void (*coentry)(void)) {
if(!co_running) co_running = &co_primary;
ucontext_t* thread = (ucontext_t*)malloc(sizeof(ucontext_t));
if(thread) {
if((!getcontext(thread) && !(thread->uc_stack.ss_sp = 0)) && (thread->uc_stack.ss_sp = malloc(heapsize))) {
thread->uc_link = co_running;
thread->uc_stack.ss_size = heapsize;
makecontext(thread, coentry, 0);
} else {
co_delete((cothread_t)thread);
thread = 0;
}
}
return (cothread_t)thread;
}
void co_delete(cothread_t cothread) {
if(cothread) {
if(((ucontext_t*)cothread)->uc_stack.ss_sp) { free(((ucontext_t*)cothread)->uc_stack.ss_sp); }
free(cothread);
}
}
void co_switch(cothread_t cothread) {
ucontext_t* old_thread = co_running;
co_running = (ucontext_t*)cothread;
swapcontext(old_thread, co_running);
}
#ifdef __cplusplus
}
#endif

114
lib/libco/x86.c Normal file
View File

@@ -0,0 +1,114 @@
/*
libco.x86 (2016-09-14)
author: byuu
license: public domain
*/
#define LIBCO_C
#include "libco.h"
#include "settings.h"
#include <assert.h>
#include <stdlib.h>
#ifdef __cplusplus
extern "C" {
#endif
#if defined(__clang__) || defined(__GNUC__)
#define fastcall __attribute__((fastcall))
#elif defined(_MSC_VER)
#define fastcall __fastcall
#else
#error "libco: please define fastcall macro"
#endif
static thread_local long co_active_buffer[64];
static thread_local cothread_t co_active_handle = 0;
static void (fastcall *co_swap)(cothread_t, cothread_t) = 0;
#ifdef LIBCO_MPROTECT
alignas(4096)
#else
section(text)
#endif
/* ABI: fastcall */
static const unsigned char co_swap_function[4096] = {
0x89, 0x22, /* mov [edx],esp */
0x8b, 0x21, /* mov esp,[ecx] */
0x58, /* pop eax */
0x89, 0x6a, 0x04, /* mov [edx+ 4],ebp */
0x89, 0x72, 0x08, /* mov [edx+ 8],esi */
0x89, 0x7a, 0x0c, /* mov [edx+12],edi */
0x89, 0x5a, 0x10, /* mov [edx+16],ebx */
0x8b, 0x69, 0x04, /* mov ebp,[ecx+ 4] */
0x8b, 0x71, 0x08, /* mov esi,[ecx+ 8] */
0x8b, 0x79, 0x0c, /* mov edi,[ecx+12] */
0x8b, 0x59, 0x10, /* mov ebx,[ecx+16] */
0xff, 0xe0, /* jmp eax */
};
#ifdef _WIN32
#include <windows.h>
static void co_init() {
#ifdef LIBCO_MPROTECT
DWORD old_privileges;
VirtualProtect((void*)co_swap_function, sizeof co_swap_function, PAGE_EXECUTE_READ, &old_privileges);
#endif
}
#else
#include <unistd.h>
#include <sys/mman.h>
static void co_init() {
#ifdef LIBCO_MPROTECT
unsigned long addr = (unsigned long)co_swap_function;
unsigned long base = addr - (addr % sysconf(_SC_PAGESIZE));
unsigned long size = (addr - base) + sizeof co_swap_function;
mprotect((void*)base, size, PROT_READ | PROT_EXEC);
#endif
}
#endif
static void crash() {
assert(0); /* called only if cothread_t entrypoint returns */
}
cothread_t co_active() {
if(!co_active_handle) co_active_handle = &co_active_buffer;
return co_active_handle;
}
cothread_t co_create(unsigned int size, void (*entrypoint)(void)) {
cothread_t handle;
if(!co_swap) {
co_init();
co_swap = (void (fastcall*)(cothread_t, cothread_t))co_swap_function;
}
if(!co_active_handle) co_active_handle = &co_active_buffer;
size += 256; /* allocate additional space for storage */
size &= ~15; /* align stack to 16-byte boundary */
if(handle = (cothread_t)malloc(size)) {
long *p = (long*)((char*)handle + size); /* seek to top of stack */
*--p = (long)crash; /* crash if entrypoint returns */
*--p = (long)entrypoint; /* start of function */
*(long*)handle = (long)p; /* stack pointer */
}
return handle;
}
void co_delete(cothread_t handle) {
free(handle);
}
void co_switch(cothread_t handle) {
register cothread_t co_previous_handle = co_active_handle;
co_swap(co_active_handle = handle, co_previous_handle);
}
#ifdef __cplusplus
}
#endif

View File

@@ -30,27 +30,19 @@ along with this program. If not, see <http://www.gnu.org/licenses/>.
#include "user_io.h"
#include "input.h"
#include "fpga_io.h"
#include "scheduler.h"
const char *version = "$VER:HPS" VDATE;
int main(int argc, char *argv[])
{
/*
//placeholder for CPU1 dedicated process
if (!fork())
{
cpu_set_t set;
CPU_ZERO(&set);
CPU_SET(1, &set);
sched_setaffinity(0, sizeof(set), &set);
while (1)
{
sleep(2);
printf("Tick\n");
}
}
*/
// Always pin main worker process to core #1 as core #0 is the
// hardware interrupt handler in Linux. This reduces idle latency
// in the main loop by about 6-7x.
cpu_set_t set;
CPU_ZERO(&set);
CPU_SET(1, &set);
sched_setaffinity(0, sizeof(set), &set);
fpga_io_init();
fpga_gpo_write(0);
@@ -75,26 +67,8 @@ int main(int argc, char *argv[])
FindStorage();
user_io_init((argc > 1) ? argv[1] : "");
while(1)
{
if(!is_fpga_ready(1))
{
printf("FPGA is not ready. JTAG uploading?\n");
printf("Waiting for FPGA to be ready...\n");
scheduler_init();
scheduler_run();
//enable reset in advance
fpga_core_reset(1);
while (!is_fpga_ready(0))
{
sleep(1);
}
reboot(0);
}
user_io_poll();
input_poll(0);
HandleUI();
}
return 0;
}

View File

@@ -1624,11 +1624,11 @@ void HandleUI(void)
case MENU_JOYDIGMAP:
helptext = 0;
menumask = 1;
OsdSetTitle("Joystick", 0);
OsdSetTitle("Define buttons", 0);
menustate = MENU_JOYDIGMAP1;
parentstate = MENU_JOYDIGMAP;
for (int i = 0; i < OsdGetSize() - 1; i++) OsdWrite(i, "", 0, 0);
OsdWrite(OsdGetSize() - 1, " Cancel", menusub == 0, 0);
OsdWrite(OsdGetSize() - 1, " ESC \x16 Cancel", menusub == 0, 0);
break;
case MENU_JOYDIGMAP1:
@@ -1660,7 +1660,7 @@ void HandleUI(void)
OsdWrite(3, s, 0, 0);
if (get_map_button())
{
if (get_map_type()) OsdWrite(OsdGetSize() - 1, " finish (SPACE - skip)", menusub == 0, 0);
if (get_map_type()) OsdWrite(OsdGetSize() - 1, " Enter \x16 Finish, Space \x16 Skip", menusub == 0, 0);
else OsdWrite(OsdGetSize() - 1, "", 0, 0);
sprintf(s, " %s ID: %04x:%04x", get_map_type() ? "Joystick" : "Keyboard", get_map_vid(), get_map_pid());
@@ -3450,6 +3450,16 @@ void HandleUI(void)
}
}
void open_joystick_setup()
{
OsdSetSize(16);
menusub = 0;
OsdClear();
OsdEnable(DISABLE_KEYBOARD);
start_map_setting(joy_bcount ? joy_bcount + 4 : 8);
menustate = MENU_JOYDIGMAP;
}
void ScrollLongName(void)
{
// this function is called periodically when file selection window is displayed

4
menu.h
View File

@@ -1,6 +1,8 @@
#ifndef MENU_H
#define MENU_H
#include <inttypes.h>
// UI strings, used by boot messages
extern const char *config_memory_chip_msg[];
extern const char *config_memory_slow_msg[];
@@ -24,4 +26,6 @@ void substrcpy(char *d, char *s, char idx);
extern char joy_bnames[12][32];
extern int joy_bcount;
void open_joystick_setup();
#endif

BIN
releases/MiSTer_20190108 Normal file

Binary file not shown.

94
scheduler.cpp Normal file
View File

@@ -0,0 +1,94 @@
#include "scheduler.h"
#include <stdio.h>
#include "libco.h"
#include "menu.h"
#include "user_io.h"
#include "input.h"
#include "fpga_io.h"
static cothread_t co_scheduler = nullptr;
static cothread_t co_poll = nullptr;
static cothread_t co_ui = nullptr;
static cothread_t co_last = nullptr;
static void scheduler_wait_fpga_ready(void)
{
while (!is_fpga_ready(1))
{
printf("FPGA is not ready. JTAG uploading?\n");
printf("Waiting for FPGA to be ready...\n");
//enable reset in advance
fpga_core_reset(1);
while (!is_fpga_ready(0))
{
sleep(1);
}
reboot(0);
}
}
static void scheduler_co_poll(void)
{
for (;;)
{
scheduler_wait_fpga_ready();
user_io_poll();
input_poll(0);
scheduler_yield();
}
}
static void scheduler_co_ui(void)
{
for (;;)
{
HandleUI();
scheduler_yield();
}
}
static void scheduler_schedule(void)
{
if (co_last == co_poll)
{
co_last = co_ui;
co_switch(co_ui);
}
else
{
co_last = co_poll;
co_switch(co_poll);
}
}
void scheduler_init(void)
{
const unsigned int co_stack_size = 262144 * sizeof(void*);
co_poll = co_create(co_stack_size, scheduler_co_poll);
co_ui = co_create(co_stack_size, scheduler_co_ui);
}
void scheduler_run(void)
{
co_scheduler = co_active();
for (;;)
{
scheduler_schedule();
}
co_delete(co_ui);
co_delete(co_poll);
co_delete(co_scheduler);
}
void scheduler_yield(void)
{
co_switch(co_scheduler);
}

8
scheduler.h Normal file
View File

@@ -0,0 +1,8 @@
#ifndef SCHEDULER_H
#define SCHEDULER_H
void scheduler_init(void);
void scheduler_run(void);
void scheduler_yield(void);
#endif

View File

@@ -19,7 +19,7 @@ typedef struct
static archie_config_t config;
fileTYPE floppy[MAX_FLOPPY] = { 0 };
fileTYPE floppy[MAX_FLOPPY] = {};
#define ARCHIE_FILE_TX 0x53
#define ARCHIE_FILE_TX_DAT 0x54
@@ -83,7 +83,7 @@ const char *archie_get_rom_name(void)
return p;
}
const char *archie_get_floppy_name(char i)
const char *archie_get_floppy_name(int i)
{
if (!floppy[i].size) return "* no disk *";
@@ -125,7 +125,7 @@ void archie_send_file(unsigned char id, char *name)
{
archie_debugf("Sending file with id %d", id);
fileTYPE file = { 0 };
fileTYPE file = {};
if (!FileOpen(&file, name)) return;
// prepare transmission of new file
@@ -184,7 +184,7 @@ void archie_fdc_set_status(void)
DisableFpga();
}
void archie_set_floppy(char i, char *name)
void archie_set_floppy(int i, char *name)
{
if (!name)
{
@@ -202,7 +202,7 @@ void archie_set_floppy(char i, char *name)
archie_fdc_set_status();
}
char archie_floppy_is_inserted(char i)
char archie_floppy_is_inserted(int i)
{
return(floppy[i].size != 0);
}
@@ -264,7 +264,7 @@ static void archie_kbd_reset(void)
void archie_init(void)
{
char i;
int i;
archie_debugf("init");
@@ -301,7 +301,7 @@ void archie_init(void)
char fdc_name[] = "Archie/FLOPPY0.ADF";
fdc_name[13] = '0' + i;
if (FileOpen(&floppy[i], fdc_name))
archie_debugf("Inserted floppy %d with %d bytes", i, floppy[i].size);
archie_debugf("Inserted floppy %d with %llu bytes", i, floppy[i].size);
else
floppy[i].size = 0;
}

View File

@@ -8,10 +8,10 @@ void archie_poll(void);
void archie_kbd(unsigned short code);
void archie_mouse(unsigned char b, int16_t x, int16_t y);
const char *archie_get_rom_name(void);
const char *archie_get_floppy_name(char b);
const char *archie_get_floppy_name(int b);
void archie_set_rom(char *);
void archie_set_floppy(char i, char *);
char archie_floppy_is_inserted(char i);
void archie_set_floppy(int i, char *);
char archie_floppy_is_inserted(int i);
void archie_save_config(void);
void archie_set_ar(char i);

View File

@@ -169,7 +169,7 @@ static void BootClearScreen(int adr, int size)
static void BootUploadLogo()
{
fileTYPE file = { 0 };
fileTYPE file = {};
int x, y;
int i = 0;
int adr;
@@ -228,7 +228,7 @@ static void BootUploadLogo()
static void BootUploadBall()
{
fileTYPE file = { 0 };
fileTYPE file = {};
int x;
int i = 0;
int adr;
@@ -258,7 +258,7 @@ static void BootUploadBall()
static void BootUploadCopper()
{
fileTYPE file = { 0 };
fileTYPE file = {};
int x;
int i = 0;
int adr;

View File

@@ -35,7 +35,7 @@ typedef struct
unsigned char autofire;
} configTYPE_old;
configTYPE config = { 0 };
configTYPE config = { };
unsigned char romkey[3072];
static void SendFileV2(fileTYPE* file, unsigned char* key, int keysize, int address, int size)
@@ -61,7 +61,7 @@ static void SendFileV2(fileTYPE* file, unsigned char* key, int keysize, int addr
for (int j = 0; j<512; j++)
{
buf[j] ^= key[keyidx++];
if (keyidx >= keysize) keyidx -= keysize;
if ((int)keyidx >= keysize) keyidx -= keysize;
}
}
EnableOsd();
@@ -86,7 +86,7 @@ static void SendFileV2(fileTYPE* file, unsigned char* key, int keysize, int addr
static char UploadKickstart(char *name)
{
fileTYPE file = { 0 };
fileTYPE file = {};
int keysize = 0;
BootPrint("Checking for Amiga Forever key file:");
@@ -168,7 +168,7 @@ static char UploadKickstart(char *name)
static char UploadActionReplay()
{
fileTYPE file = { 0 };
fileTYPE file = {};
if(FileOpen(&file, "Amiga/HRTMON.ROM") || FileOpen(&file, "HRTMON.ROM"))
{
int adr, data;
@@ -378,7 +378,6 @@ unsigned char LoadConfiguration(int num)
static const char config_id[] = "MNMGCFG0";
char updatekickstart = 0;
char result = 0;
unsigned char key, i;
const char *filename = GetConfigurationName(num);
@@ -387,7 +386,7 @@ unsigned char LoadConfiguration(int num)
if(filename && (size = FileLoadConfig(filename, 0, 0))>0)
{
BootPrint("Opened configuration file\n");
printf("Configuration file size: %s, %lu\n", filename, size);
printf("Configuration file size: %s, %d\n", filename, size);
if (size == sizeof(config))
{
static configTYPE tmpconf;
@@ -439,7 +438,7 @@ unsigned char LoadConfiguration(int num)
}
else printf("Cannot load configuration file\n");
}
else printf("Wrong configuration file size: %lu (expected: %lu)\n", size, sizeof(config));
else printf("Wrong configuration file size: %d (expected: %u)\n", size, sizeof(config));
}
if (!result) {
BootPrint("Can not open configuration file!\n");
@@ -502,7 +501,7 @@ void MinimigReset()
void SetKickstart(char *name)
{
int len = strlen(name);
uint len = strlen(name);
if (len > (sizeof(config.kickstart) - 1)) len = sizeof(config.kickstart) - 1;
memcpy(config.kickstart, name, len);
config.kickstart[len] = 0;

View File

@@ -35,7 +35,7 @@ along with this program. If not, see <http://www.gnu.org/licenses/>.
unsigned char drives = 0; // number of active drives reported by FPGA (may change only during reset)
adfTYPE *pdfx; // drive select pointer
adfTYPE df[4] = { 0 }; // drive information structure
adfTYPE df[4] = {}; // drive information structure
static uint8_t sector_buffer[512];
@@ -71,13 +71,13 @@ void SendSector(unsigned char *pData, unsigned char sector, unsigned char track,
// odd bits of header
x = 0x55;
checksum[0] = x;
y = track >> 1 & 0x55;
y = (track >> 1) & 0x55;
checksum[1] = y;
spi_w(B2W(x,y));
x = sector >> 1 & 0x55;
x = (sector >> 1) & 0x55;
checksum[2] = x;
y = 11 - sector >> 1 & 0x55;
y = ((11 - sector) >> 1) & 0x55;
checksum[3] = y;
spi_w(B2W(x, y));
@@ -90,7 +90,7 @@ void SendSector(unsigned char *pData, unsigned char sector, unsigned char track,
x = sector & 0x55;
checksum[2] ^= x;
y = 11 - sector & 0x55;
y = (11 - sector) & 0x55;
checksum[3] ^= y;
spi_w(B2W(x, y));
@@ -135,8 +135,8 @@ void SendSector(unsigned char *pData, unsigned char sector, unsigned char track,
p = pData;
while (i--)
{
x = *p++ >> 1 | 0xAA;
y = *p++ >> 1 | 0xAA;
x = (*p++ >> 1) | 0xAA;
y = (*p++ >> 1) | 0xAA;
spi_w(B2W(x, y));
}
@@ -166,7 +166,7 @@ void ReadTrack(adfTYPE *drive)
unsigned char status;
unsigned char track;
unsigned short dsksync;
unsigned short dsklen;
//unsigned short dsklen;
uint16_t tmp;
//unsigned short n;
@@ -201,7 +201,7 @@ void ReadTrack(adfTYPE *drive)
status = (uint8_t)(tmp>>8); // read request signal
track = (uint8_t)tmp; // track number (cylinder & head)
dsksync = spi_w(0); // disk sync
dsklen = spi_w(0) & 0x3FFF; // mfm words to transfer
//dsklen = spi_w(0) & 0x3FFF; // mfm words to transfer
DisableFpga();
if (track >= drive->tracks)
@@ -218,7 +218,7 @@ void ReadTrack(adfTYPE *drive)
status = (uint8_t)(tmp >> 8); // read request signal
track = (uint8_t)tmp; // track number (cylinder & head)
dsksync = spi_w(0); // disk sync
dsklen = spi_w(0) & 0x3FFF; // mfm words to transfer
//dsklen = spi_w(0) & 0x3FFF; // mfm words to transfer
if (track >= drive->tracks)
track = drive->tracks - 1;
@@ -281,7 +281,7 @@ void ReadTrack(adfTYPE *drive)
unsigned char FindSync(adfTYPE *drive)
// reads data from fifo till it finds sync word or fifo is empty and dma inactive (so no more data is expected)
{
unsigned char c1, c2, c3, c4;
unsigned char c1, c2;
unsigned short n;
uint16_t tmp;
@@ -641,7 +641,6 @@ void InsertFloppy(adfTYPE *drive, char* path)
return;
}
unsigned char i, j;
unsigned long tracks;
// calculate number of tracks in the ADF image file

View File

@@ -81,12 +81,12 @@ typedef struct
uint16_t sector_count;
} hdfTYPE;
static hdfTYPE HDF[4] = { 0 };
static hdfTYPE HDF[4] = {};
static uint8_t sector_buffer[512];
static void CalcGeometry(hdfTYPE *hdf)
{
uint32_t head, cyl, spt;
uint32_t head = 0, cyl = 0, spt = 0;
uint32_t sptt[] = { 63, 127, 255, 0 };
uint32_t total = hdf->file.size / 512;
for (int i = 0; sptt[i] != 0; i++)
@@ -205,7 +205,6 @@ static uint32_t RDBChecksum(uint32_t *p, int set)
// if the HDF file doesn't have a RigidDiskBlock, we synthesize one
static void FakeRDB(hdfTYPE *hdf)
{
int i;
// start by clearing the sector buffer
memset(sector_buffer, 0, 512);
@@ -285,7 +284,8 @@ static void FakeRDB(hdfTYPE *hdf)
// builds Identify Device struct
static void IdentifyDevice(uint16_t *pBuffer, hdfTYPE *hdf)
{
char *p, i, x;
char *p, x;
int i;
uint32_t total_sectors = hdf->cylinders * hdf->heads * hdf->sectors;
memset(pBuffer, 0, 512);
@@ -368,6 +368,7 @@ static void WriteStatus(uint8_t status)
static void ATA_Recalibrate(uint8_t* tfr, hdfTYPE *hdf)
{
// Recalibrate 0x10-0x1F (class 3 command: no data)
(void)hdf;
hdd_debugf("IDE%d: Recalibrate", hdf->unit);
WriteTaskFile(0, 0, tfr[6] & 0x40 ? 0 : 1, 0, 0, tfr[6] & 0xF0);
WriteStatus(IDE_STATUS_END | IDE_STATUS_IRQ);
@@ -376,6 +377,8 @@ static void ATA_Recalibrate(uint8_t* tfr, hdfTYPE *hdf)
static void ATA_Diagnostic(uint8_t* tfr, hdfTYPE *hdf)
{
// Execute Drive Diagnostic (0x90)
(void)hdf;
(void)tfr;
hdd_debugf("IDE: Drive Diagnostic");
WriteTaskFile(1, 0, 0, 0, 0, 0);
WriteStatus(IDE_STATUS_END | IDE_STATUS_IRQ);
@@ -383,7 +386,6 @@ static void ATA_Diagnostic(uint8_t* tfr, hdfTYPE *hdf)
static void ATA_IdentifyDevice(uint8_t* tfr, hdfTYPE *hdf)
{
int i;
// Identify Device (0xec)
hdd_debugf("IDE%d: Identify Device", hdf->unit);
IdentifyDevice((uint16_t*)sector_buffer, hdf);
@@ -401,6 +403,7 @@ static void ATA_IdentifyDevice(uint8_t* tfr, hdfTYPE *hdf)
static void ATA_Initialize(uint8_t* tfr, hdfTYPE *hdf)
{
// Initialize Device Parameters (0x91)
(void)hdf;
hdd_debugf("Initialize Device Parameters");
hdd_debugf("IDE%d: %02X.%02X.%02X.%02X.%02X.%02X.%02X.%02X", hdf->unit, tfr[0], tfr[1], tfr[2], tfr[3], tfr[4], tfr[5], tfr[6], tfr[7]);
WriteTaskFile(0, tfr[2], tfr[3], tfr[4], tfr[5], tfr[6]);
@@ -535,7 +538,7 @@ static void WriteSector(hdfTYPE *hdf)
else
{
GetRDBGeometry(hdf);
printf("Using new CHS: %u/%u/%u (%lu MB)\n", hdf->cylinders, hdf->heads, hdf->sectors, ((((uint32_t)hdf->cylinders) * hdf->heads * hdf->sectors) >> 11));
printf("Using new CHS: %u/%u/%u (%llu MB)\n", hdf->cylinders, hdf->heads, hdf->sectors, ((((uint64_t)hdf->cylinders) * hdf->heads * hdf->sectors) >> 11));
}
}
FileWriteSec(&hdf->file, sector_buffer);
@@ -660,6 +663,8 @@ static void ATA_WriteMultiple(uint8_t* tfr, hdfTYPE *hdf)
void HandleHDD(uint8_t c1, uint8_t c2)
{
(void)c2;
if (c1 & CMD_IDECMD)
{
uint8_t unit = 0;
@@ -727,7 +732,7 @@ uint8_t OpenHardfile(uint8_t unit)
SetHardfileGeometry(hdf, !strcasecmp(".hdf", config.hardfile[unit].filename + strlen(config.hardfile[unit].filename) - 4));
printf("size: %llu (%llu MB)\n", hdf->file.size, hdf->file.size >> 20);
printf("CHS: %u/%u/%u", hdf->cylinders, hdf->heads, hdf->sectors);
printf(" (%lu MB), ", ((((uint32_t)hdf->cylinders) * hdf->heads * hdf->sectors) >> 11));
printf(" (%llu MB), ", ((((uint64_t)hdf->cylinders) * hdf->heads * hdf->sectors) >> 11));
printf("Offset: %d\n", hdf->offset);
return 1;
}
@@ -742,7 +747,7 @@ uint8_t OpenHardfile(uint8_t unit)
int checkHDF(const char* name, struct RigidDiskBlock **rdb)
{
fileTYPE file = { 0 };
fileTYPE file = {};
*rdb = NULL;
if (FileOpenEx(&file, name, O_RDONLY))

View File

@@ -253,7 +253,7 @@ int sharpmz_reload_config(short setStatus)
//
void sharpmz_init(void)
{
char i;
int i;
sharpmz_debugf("Sharp MZ Series Initialisation");
@@ -1253,7 +1253,7 @@ void sharpmz_set_fdc_rom_enabled(short machineModel, short on, short setStatus)
//
short sharpmz_get_custom_rom_enabled(short machineModel, short romType)
{
short romEnabled;
short romEnabled = 0;
machineModel &= 0x07;
romType &= 0x07;
@@ -1492,7 +1492,7 @@ void sharpmz_send_file(romData_t &image, char *dirPrefix)
unsigned int actualReadSize;
unsigned long time = GetTimer(0);
unsigned short i;
fileTYPE file = { 0 };
fileTYPE file = {};
// If a prefix is given (ie. core directory), prepend it before use.
//
@@ -1528,7 +1528,7 @@ void sharpmz_send_file(romData_t &image, char *dirPrefix)
sharpmz_debugf("[");
for (i = 0; i < image.loadSize; i += actualReadSize)
{
if (!(i & 127)) sharpmz_debugf("*");
if (!(i & 127)) { sharpmz_debugf("*"); }
// Work out size of data block to read.
int readSize = (image.loadSize - i >= 512 ? 512 : image.loadSize - i);
@@ -1574,7 +1574,7 @@ void sharpmz_send_file(romData_t &image, char *dirPrefix)
short sharpmz_read_ram(const char *memDumpFile, short bank)
{
unsigned int actualWriteSize;
fileTYPE file = { 0 };
fileTYPE file = {};
// Open the memory image debug file for writing.
if (!sharpmz_file_write(&file, memDumpFile))
@@ -1585,7 +1585,7 @@ short sharpmz_read_ram(const char *memDumpFile, short bank)
// Depending on the bank, or all banks, loop until request is complete.
//
for(unsigned int mb=(bank == SHARPMZ_MEMBANK_ALL ? 0 : bank); mb <= (bank == SHARPMZ_MEMBANK_ALL ? SHARPMZ_MEMBANK_MAXBANKS-1 : bank); mb++)
for(unsigned int mb=(bank == SHARPMZ_MEMBANK_ALL ? 0 : bank); mb <= (uint)(bank == SHARPMZ_MEMBANK_ALL ? SHARPMZ_MEMBANK_MAXBANKS-1 : bank); mb++)
{
// Skip bank 1, as SYSROM spans two physical banks 0 and 1.
if(mb == 1) mb = SHARPMZ_MEMBANK_SYSRAM;
@@ -1603,7 +1603,7 @@ short sharpmz_read_ram(const char *memDumpFile, short bank)
sharpmz_debugf("[");
for (unsigned long j = 0; j < MZBANKSIZE[mb] or actualWriteSize == 0; j += actualWriteSize)
{
if (!(j & 127)) sharpmz_debugf("*");
if (!(j & 127)) { sharpmz_debugf("*"); }
spi_read(sector_buffer, 512, 0);
@@ -1637,7 +1637,7 @@ short sharpmz_read_tape_header(const char *tapeFile)
// Handle for the MZF file to be processed.
//
fileTYPE file = { 0 };
fileTYPE file = {};
// Try and open the tape file, exit if it cannot be opened.
//
@@ -1668,13 +1668,13 @@ short sharpmz_load_tape_to_ram(const char *tapeFile, unsigned char dstCMT)
{
unsigned int actualReadSize;
unsigned long time = GetTimer(0);
char fileName[17];
//char fileName[17];
//sharpmz_debugf("Sending tape file:%s to emulator ram", tapeFile);
// Handle for the MZF file to be processed.
//
fileTYPE file = { 0 };
fileTYPE file = {};
// Try and open the tape file, exit if it cannot be opened.
//
@@ -1692,10 +1692,12 @@ short sharpmz_load_tape_to_ram(const char *tapeFile, unsigned char dstCMT)
// Some sanity checks.
//
if(tapeHeader.dataType == 0 || tapeHeader.dataType > 5) return(4);
/*
for(int i=0; i < 17; i++)
{
fileName[i] = tapeHeader.fileName[i] == 0x0d ? 0x00 : tapeHeader.fileName[i];
}
*/
// Debug output to indicate the file loaded and information about the tape image.
//
@@ -1756,7 +1758,7 @@ short sharpmz_load_tape_to_ram(const char *tapeFile, unsigned char dstCMT)
sharpmz_debugf("[");
for (unsigned short i = 0; i < tapeHeader.fileSize; i += actualReadSize)
{
if (!(i & 127)) sharpmz_debugf("*");
if (!(i & 127)) { sharpmz_debugf("*"); }
DISKLED_ON;
actualReadSize = sharpmz_file_read(&file, sector_buffer, 512);
@@ -1865,7 +1867,7 @@ short sharpmz_save_tape_from_cmt(const char *tapeFile)
// Handle for the MZF file to be written.
//
fileTYPE file = { 0 };
fileTYPE file = {};
// Read the header, then data, but limit data size to the 'file size' stored in the header.
//
@@ -1946,6 +1948,7 @@ short sharpmz_save_tape_from_cmt(const char *tapeFile)
void sharpmz_select_file(const char* pFileExt, unsigned char Options, char *fs_pFileExt, char chdir, char *SelectedPath)
{
sharpmz_debugf("pFileExt = %s\n", pFileExt);
(void)chdir;
if (strncasecmp(SHARPMZ_CORE_NAME, SelectedPath, strlen(SHARPMZ_CORE_NAME))) strcpy(SelectedPath, SHARPMZ_CORE_NAME);
@@ -1991,17 +1994,19 @@ void sharpmz_ui(int idleState, int idle2State, int system
static short scrollPos = 0;
static short volumeDir = 0;
int menuItem;
int subItem;
uint32_t subItem;
short romEnabled;
short itemCount;
char sBuf[40];
char *fileName;
(void)plus;
(void)minus;
// Idle2 state (MENU_NONE2) is our main hook, when the HandleUI state machine reaches this state, if the menu key is pressed,
// we takeover control in this method.
//
if(*menustate == idle2State && menu)
if(*menustate == (uint32_t)idle2State && menu)
{
OsdSetSize(16);
*menusub = 0;

View File

@@ -375,10 +375,11 @@ void ikbd_reset(void) {
// process inout from atari core into ikbd
void ikbd_handle_input(unsigned char cmd) {
// store byte in buffer
ikbd.buffer.byte[ikbd.buffer.size++] = cmd;
unsigned char *byte = ikbd.buffer.byte;
byte[(int)(ikbd.buffer.size++)] = cmd;
// check if there's a known command in the buffer
char c;
int c;
for (c = 0; ikbd_command_handler[c].length &&
(ikbd_command_handler[c].code != ikbd.buffer.command.code); c++);
@@ -445,7 +446,7 @@ static void ikbd_update_time()
void ikbd_poll(void) {
#ifdef IKBD_DEBUG
static unsigned long xtimer = 0;
static int last_cnt = 0;
static unsigned int last_cnt = 0;
if (CheckTimer(xtimer)) {
xtimer = GetTimer(2000);
if (ikbd.tx_cnt != last_cnt) {
@@ -469,7 +470,7 @@ void ikbd_poll(void) {
/* --------- joystick ---------- */
if (ikbd.state & IKBD_STATE_JOYSTICK_EVENT_REPORTING) {
char i;
int i;
for (i = 0; i<2; i++) {
unsigned char state = ikbd.joy[i].state;
@@ -599,7 +600,7 @@ void ikbd_keyboard(unsigned char code) {
enqueue(code);
}
void ikbd_mouse(unsigned char b, char x, char y) {
void ikbd_mouse(unsigned char b, signed char x, signed char y) {
// honour reversal of y axis
if (ikbd.state & IKBD_STATE_MOUSE_Y_BOTTOM)

View File

@@ -5,7 +5,7 @@ void ikbd_init(void);
void ikbd_poll(void);
void ikbd_reset(void);
void ikbd_joystick(unsigned char joy, unsigned char map);
void ikbd_mouse(unsigned char buttons, char x, char y);
void ikbd_mouse(unsigned char buttons, signed char x, signed char y);
void ikbd_keyboard(unsigned char code);
#endif // IKBD_H

View File

@@ -36,10 +36,10 @@ static struct {
fileTYPE file;
unsigned char sides;
unsigned char spt;
} fdd_image[2] = { 0 };
} fdd_image[2] = {};
// one harddisk
fileTYPE hdd_image[2] = { 0 };
fileTYPE hdd_image[2] = {};
unsigned long hdd_direct = 0;
static unsigned char dma_buffer[512];
@@ -66,7 +66,7 @@ static const char *acsi_cmd_name(int cmd) {
return cmdname[cmd];
}
void tos_set_video_adjust(char axis, char value) {
void tos_set_video_adjust(int axis, char value) {
config.video_adjust[axis] += value;
EnableFpga();
@@ -76,7 +76,7 @@ void tos_set_video_adjust(char axis, char value) {
DisableFpga();
}
char tos_get_video_adjust(char axis) {
char tos_get_video_adjust(int axis) {
return config.video_adjust[axis];
}
@@ -105,6 +105,7 @@ static void mist_set_control(unsigned long ctrl) {
DisableFpga();
}
/*
static void mist_memory_read(char *data, unsigned long words) {
EnableFpga();
spi8(MIST_READ_MEMORY);
@@ -117,6 +118,7 @@ static void mist_memory_read(char *data, unsigned long words) {
DisableFpga();
}
*/
static void mist_memory_write(unsigned char *data, unsigned long words) {
EnableFpga();
@@ -162,6 +164,7 @@ void mist_memory_set(char data, unsigned long words) {
// enable direct sd card access on acsi0
void tos_set_direct_hdd(char on) {
(void)on;
config.sd_direct = 0;
tos_debugf("ACSI: disable direct sd access");
@@ -208,12 +211,12 @@ static void handle_acsi(unsigned char *buffer) {
if (length == 0) length = 256;
if (user_io_dip_switch1()) {
tos_debugf("ACSI: target %d.%d, \"%s\" (%02x)", target, device, acsi_cmd_name(cmd), cmd);
tos_debugf("ACSI: target %u.%u, \"%s\" (%02x)", target, device, acsi_cmd_name(cmd), cmd);
tos_debugf("ACSI: lba %lu (%lx), length %u", lba, lba, length);
tos_debugf("DMA: scnt %u, addr %p", scnt, dma_address);
tos_debugf("DMA: scnt %u, addr %X", scnt, dma_address);
if (buffer[20] == 0xa5) {
tos_debugf("DMA: fifo %d/%d %x %s",
tos_debugf("DMA: fifo %u/%u %x %s",
(buffer[21] >> 4) & 0x0f, buffer[21] & 0x0f,
buffer[22], (buffer[2] & 1) ? "OUT" : "IN");
tos_debugf("DMA stat=%x, mode=%x, fdc_irq=%d, acsi_irq=%d",
@@ -308,7 +311,7 @@ static void handle_acsi(unsigned char *buffer) {
asc[target] = 0x00;
}
else {
tos_debugf("ACSI: read (%d+%d) exceeds device limits (%d)",
tos_debugf("ACSI: read (%lu+%u) exceeds device limits (%lu)",
lba, length, blocks);
dma_ack(0x02);
asc[target] = 0x21;
@@ -348,7 +351,7 @@ static void handle_acsi(unsigned char *buffer) {
asc[target] = 0x00;
}
else {
tos_debugf("ACSI: write (%d+%d) exceeds device limits (%d)",
tos_debugf("ACSI: write (%lu+%u) exceeds device limits (%lu)",
lba, length, blocks);
dma_ack(0x02);
asc[target] = 0x21;
@@ -380,7 +383,7 @@ static void handle_acsi(unsigned char *buffer) {
case 0x1a: // mode sense
if (device == 0) {
tos_debugf("ACSI: mode sense, blocks = %u", blocks);
tos_debugf("ACSI: mode sense, blocks = %lu", blocks);
bzero(dma_buffer, 512);
dma_buffer[3] = 8; // size of extent descriptor list
dma_buffer[5] = blocks >> 16;
@@ -430,7 +433,7 @@ static void handle_fdc(unsigned char *buffer) {
unsigned char fdc_cmd = buffer[4];
unsigned char fdc_track = buffer[5];
unsigned char fdc_sector = buffer[6];
unsigned char fdc_data = buffer[7];
//unsigned char fdc_data = buffer[7];
unsigned char drv_sel = 3 - ((buffer[8] >> 2) & 3);
unsigned char drv_side = 1 - ((buffer[8] >> 1) & 1);
@@ -450,7 +453,7 @@ static void handle_fdc(unsigned char *buffer) {
offset += fdc_sector - 1;
if (user_io_dip_switch1()) {
tos_debugf("FDC %s req %d sec (%c, SD:%d, T:%d, S:%d = %d) -> %p",
tos_debugf("FDC %s req %d sec (%c, SD:%d, T:%d, S:%d = %d) -> %X",
(fdc_cmd & 0x10) ? "multi" : "single", scnt,
'A' + drv_sel - 1, drv_side, fdc_track, fdc_sector, offset,
dma_address);
@@ -534,6 +537,7 @@ static void mist_get_dmastate() {
#define PLANES 4
static void tos_write(const char *str);
/*
static void tos_color_test() {
unsigned short buffer[COLORS][PLANES];
@@ -569,6 +573,7 @@ static void tos_color_test() {
// for(;;);
#endif
}
*/
static void tos_write(const char *str) {
static int y = 0;
@@ -614,7 +619,7 @@ static void tos_clr() {
extern unsigned char charfont[256][8];
static void tos_font_load() {
fileTYPE file = { 0 };
fileTYPE file = {};
if (FileOpen(&file, "SYSTEM.FNT")) {
if (file.size == 4096) {
int i;
@@ -648,7 +653,7 @@ static void tos_font_load() {
void tos_load_cartridge(const char *name)
{
fileTYPE file = { 0 };
fileTYPE file = {};
if (name)
strncpy(config.cart_img, name, 11);
@@ -658,7 +663,7 @@ void tos_load_cartridge(const char *name)
int i;
unsigned char buffer[512];
tos_debugf("%s:\n size = %d", config.cart_img, file.size);
tos_debugf("%s:\n size = %llu", config.cart_img, file.size);
int blocks = file.size / 512;
tos_debugf(" blocks = %d", blocks);
@@ -697,7 +702,7 @@ char tos_cartridge_is_inserted() {
void tos_upload(const char *name)
{
fileTYPE file = { 0 };
fileTYPE file = {};
// set video offset in fpga
tos_set_video_adjust(0, 0);
@@ -727,7 +732,7 @@ void tos_upload(const char *name)
unsigned long time;
unsigned long tos_base = TOS_BASE_ADDRESS_192k;
tos_debugf("TOS.IMG:\n size = %d", file.size);
tos_debugf("TOS.IMG:\n size = %llu", file.size);
if (file.size >= 256 * 1024)
tos_base = TOS_BASE_ADDRESS_256k;
@@ -737,7 +742,7 @@ void tos_upload(const char *name)
int blocks = file.size / 512;
tos_debugf(" blocks = %d", blocks);
tos_debugf(" address = $%08x", tos_base);
tos_debugf(" address = $%08lx", tos_base);
// clear first 16k
mist_memory_set_address(0, 16384 / 512, 0);
@@ -828,7 +833,7 @@ void tos_upload(const char *name)
#endif
time = GetTimer(0) - time;
tos_debugf("TOS.IMG uploaded in %lu ms (%d kB/s / %d kBit/s)",
tos_debugf("TOS.IMG uploaded in %lu ms (%llu kB/s / %llu kBit/s)",
time >> 20, file.size / (time >> 20), 8 * file.size / (time >> 20));
}
@@ -851,9 +856,9 @@ void tos_upload(const char *name)
// try to open both floppies
int i;
for (i = 0; i<2; i++) {
char msg[] = "Found floppy disk image for drive X: ";
//char msg[] = "Found floppy disk image for drive X: ";
char name[] = "DISK_A.ST";
msg[34] = name[5] = 'A' + i;
//msg[34] = name[5] = 'A' + i;
tos_insert_disk(i, name);
}
@@ -889,6 +894,7 @@ void tos_upload(const char *name)
mist_set_control(config.system_ctrl);
}
/*
static unsigned long get_long(char *buffer, int offset) {
unsigned long retval = 0;
int i;
@@ -898,6 +904,7 @@ static unsigned long get_long(char *buffer, int offset) {
return retval;
}
*/
void tos_poll() {
// 1 == button not pressed, 2 = 1 sec exceeded, else timer running
@@ -950,9 +957,8 @@ static void nice_name(char *dest, char *src) {
static char buffer[17]; // local buffer to assemble file name (8+3+2)
char *tos_get_disk_name(char index) {
char *tos_get_disk_name(int index) {
fileTYPE file;
char *c;
if (index <= 1)
file = fdd_image[index].file;
@@ -983,14 +989,14 @@ char *tos_get_cartridge_name() {
return buffer;
}
char tos_disk_is_inserted(char index) {
char tos_disk_is_inserted(int index) {
if (index <= 1)
return (fdd_image[index].file.size != 0);
return hdd_image[index - 2].size != 0;
}
void tos_select_hdd_image(char i, const char *name)
void tos_select_hdd_image(int i, const char *name)
{
tos_debugf("Select ACSI%c image %s", '0' + i, name);
@@ -1015,7 +1021,7 @@ void tos_select_hdd_image(char i, const char *name)
mist_set_control(config.system_ctrl);
}
void tos_insert_disk(char i, const char *name)
void tos_insert_disk(int i, const char *name)
{
if (i > 1)
{
@@ -1136,7 +1142,7 @@ void tos_config_init(void)
int size = FileLoadConfig(CONFIG_FILENAME, 0, 0);
if (size>0)
{
tos_debugf("Configuration file size: %lu (should be %lu)", size, sizeof(tos_config_t));
tos_debugf("Configuration file size: %u (should be %u)", size, sizeof(tos_config_t));
if (size == sizeof(tos_config_t))
{
FileLoadConfig(CONFIG_FILENAME, &config, size);

View File

@@ -85,11 +85,11 @@ unsigned long tos_system_ctrl(void);
void tos_upload(const char *);
void tos_poll();
void tos_update_sysctrl(unsigned long);
char *tos_get_disk_name(char);
char tos_disk_is_inserted(char index);
void tos_insert_disk(char i, const char *name);
char *tos_get_disk_name(int);
char tos_disk_is_inserted(int index);
void tos_insert_disk(int i, const char *name);
void tos_eject_all();
void tos_select_hdd_image(char i, const char *name);
void tos_select_hdd_image(int i, const char *name);
void tos_set_direct_hdd(char on);
char tos_get_direct_hdd();
void tos_reset(char cold);
@@ -98,8 +98,8 @@ char *tos_get_cartridge_name();
char tos_cartridge_is_inserted();
void tos_load_cartridge(const char *);
void tos_set_video_adjust(char axis, char value);
char tos_get_video_adjust(char axis);
void tos_set_video_adjust(int axis, char value);
char tos_get_video_adjust(int axis);
void tos_config_init(void);
void tos_config_save(void);

View File

@@ -72,6 +72,7 @@ static uint8_t dma_sdio(int status)
return res;
}
/*
static uint32_t dma_get(uint32_t address)
{
EnableFpga();
@@ -81,6 +82,7 @@ static uint32_t dma_get(uint32_t address)
DisableFpga();
return res;
}
*/
static void dma_set(uint32_t address, uint32_t data)
{
@@ -111,7 +113,7 @@ static void dma_rcvbuf(uint32_t address, uint32_t length, uint32_t *data)
static int load_bios(const char* name, uint8_t index)
{
fileTYPE f = { 0 };
fileTYPE f = {};
static uint32_t buf[128];
if (!FileOpen(&f, name)) return 0;
@@ -155,10 +157,10 @@ 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_image0 = { 0 };
static fileTYPE fdd_image1 = { 0 };
static fileTYPE hdd_image0 = { 0 };
static fileTYPE hdd_image1 = { 0 };
static fileTYPE fdd_image0 = {};
static fileTYPE fdd_image1 = {};
static fileTYPE hdd_image0 = {};
static fileTYPE hdd_image1 = {};
static bool boot_from_floppy = 1;
#define IMG_TYPE_FDD0 0x0800
@@ -210,8 +212,8 @@ static int img_write(uint32_t type, uint32_t lba, void *buf, uint32_t 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)
/*
static void cmos_set(uint addr, uint8_t val)
{
if (addr >= sizeof(cmos)) return;
@@ -229,6 +231,7 @@ void cmos_set(int addr, uint8_t val)
IOWR(RTC_BASE, 0x2E, cmos[0x2E]);
IOWR(RTC_BASE, 0x2F, cmos[0x2F]);
}
*/
static int fdd_set(char* filename)
{
@@ -661,7 +664,7 @@ struct sd_param_t
uint32_t bl_cnt;
};
static struct sd_param_t sd_params = { 0 };
static struct sd_param_t sd_params = {};
void x86_poll()
{

View File

@@ -609,7 +609,7 @@ int user_io_get_joyswap()
void user_io_analog_joystick(unsigned char joystick, char valueX, char valueY)
{
uint8_t joy = (!joyswap) ? joystick : joystick ? 0 : 1;
uint8_t joy = (joystick>1 || !joyswap) ? joystick : joystick^1;
if (core_type == CORE_TYPE_8BIT)
{
@@ -626,13 +626,7 @@ void user_io_analog_joystick(unsigned char joystick, char valueX, char valueY)
void user_io_digital_joystick(unsigned char joystick, uint16_t map, int newdir)
{
uint8_t joy = (!joyswap) ? joystick : joystick ? 0 : 1;
if (is_minimig())
{
spi_uio_cmd16(UIO_JOYSTICK0 + joy, map);
return;
}
uint8_t joy = (joystick>1 || !joyswap) ? joystick : joystick ^ 1;
// atari ST handles joystick 0 and 1 through the ikbd emulated by the io controller
// but only for joystick 1 and 2
@@ -642,8 +636,9 @@ void user_io_digital_joystick(unsigned char joystick, uint16_t map, int newdir)
return;
}
spi_uio_cmd16(UIO_JOYSTICK0 + joy, map);
if (joy_transl == 1 && newdir)
spi_uio_cmd16((joy < 2) ? (UIO_JOYSTICK0 + joy) : (UIO_JOYSTICK2 + joy - 2), map);
if (!is_minimig() && joy_transl == 1 && newdir)
{
user_io_analog_joystick(joystick, (map & 2) ? 128 : (map & 1) ? 127 : 0, (map & 8) ? 128 : (map & 4) ? 127 : 0);
}
@@ -2473,8 +2468,8 @@ void user_io_kbd(uint16_t key, int press)
else
{
if (is_menu_core()) printf("PS2 code(make)%s for core: %d(0x%X)\n", (code & EXT) ? "(ext)" : "", code & 255, code & 255);
if ((has_menu() || osd_is_visible || (get_key_mod() & (LALT | RALT | RGUI | LGUI))) && (((key == KEY_F12) && ((!is_x86_core() && !is_archie()) || (get_key_mod() & (RGUI | LGUI)))) || key == KEY_MENU)) menu_key_set(KEY_F12);
if (!osd_is_visible && !is_menu_core() && key == KEY_MENU && press == 3) open_joystick_setup();
else if ((has_menu() || osd_is_visible || (get_key_mod() & (LALT | RALT | RGUI | LGUI))) && (((key == KEY_F12) && ((!is_x86_core() && !is_archie()) || (get_key_mod() & (RGUI | LGUI)))) || key == KEY_MENU)) menu_key_set(KEY_F12);
else if (osd_is_visible)
{
if (press == 1) menu_key_set(key);
@@ -2943,10 +2938,10 @@ static void adjust_vsize(char force)
if ((res & 0x8000) && (nres != res || force))
{
nres = res;
uint16_t scr_hsize = spi_w(0);
uint16_t scr_vsize = spi_w(0);
uint16_t scr_hsize = spi_w(0);
uint16_t scr_vsize = spi_w(0);
DisableIO();
printf("\033[1;37mVMODE: resolution: %u x %u, mode: %u\033[0m\n", scr_hsize, scr_vsize, res & 255);
static int loaded = 0;
@@ -2991,14 +2986,14 @@ static void store_vsize()
spi_uio_cmd_cont(UIO_GET_VMODE);
uint16_t res = spi_w(0);
uint16_t scr_hsize = spi_w(0);
uint16_t scr_vsize = spi_w(0);
uint16_t scr_hbl_l = spi_w(0);
uint16_t scr_hbl_r = spi_w(0);
uint16_t scr_vbl_t = spi_w(0);
uint16_t scr_vbl_b = spi_w(0);
uint16_t scr_hsize = spi_w(0);
uint16_t scr_vsize = spi_w(0);
uint16_t scr_hbl_l = spi_w(0);
uint16_t scr_hbl_r = spi_w(0);
uint16_t scr_vbl_t = spi_w(0);
uint16_t scr_vbl_b = spi_w(0);
DisableIO();
printf("\033[1;37mVMODE: store position: [%u-%u, %u-%u]\033[0m\n", scr_hbl_l, scr_hbl_r, scr_vbl_t, scr_vbl_b);
uint32_t mode = scr_hsize | (scr_vsize << 12) | ((res & 0xFF) << 24);