This commit is contained in:
62
Makefile
62
Makefile
@@ -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))
|
||||
|
||||
@@ -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" />
|
||||
|
||||
@@ -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>
|
||||
17
file_io.cpp
17
file_io.cpp
@@ -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
244
input.cpp
@@ -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
160
lib/libco/amd64.c
Normal 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
79
lib/libco/arm.c
Normal 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
8
lib/libco/doc/style.css
Normal file
@@ -0,0 +1,8 @@
|
||||
body {
|
||||
background: #333;
|
||||
color: #fff;
|
||||
}
|
||||
|
||||
code {
|
||||
background: #444;
|
||||
}
|
||||
89
lib/libco/doc/targets.html
Normal file
89
lib/libco/doc/targets.html
Normal 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
107
lib/libco/doc/usage.html
Normal 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 co_delete(cothread_t cothread);<br/>
|
||||
void 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
51
lib/libco/fiber.c
Normal 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
34
lib/libco/libco.c
Normal 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
26
lib/libco/libco.h
Normal 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
367
lib/libco/ppc.c
Normal 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
36
lib/libco/settings.h
Normal 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
102
lib/libco/sjlj.c
Normal 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
69
lib/libco/ucontext.c
Normal 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
114
lib/libco/x86.c
Normal 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
|
||||
46
main.cpp
46
main.cpp
@@ -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;
|
||||
}
|
||||
|
||||
16
menu.cpp
16
menu.cpp
@@ -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
4
menu.h
@@ -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
BIN
releases/MiSTer_20190108
Normal file
Binary file not shown.
94
scheduler.cpp
Normal file
94
scheduler.cpp
Normal 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
8
scheduler.h
Normal file
@@ -0,0 +1,8 @@
|
||||
#ifndef SCHEDULER_H
|
||||
#define SCHEDULER_H
|
||||
|
||||
void scheduler_init(void);
|
||||
void scheduler_run(void);
|
||||
void scheduler_yield(void);
|
||||
|
||||
#endif
|
||||
@@ -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;
|
||||
}
|
||||
|
||||
@@ -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);
|
||||
|
||||
@@ -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;
|
||||
|
||||
@@ -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;
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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))
|
||||
|
||||
@@ -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;
|
||||
|
||||
@@ -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)
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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);
|
||||
|
||||
@@ -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);
|
||||
|
||||
@@ -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()
|
||||
{
|
||||
|
||||
39
user_io.cpp
39
user_io.cpp
@@ -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);
|
||||
|
||||
Reference in New Issue
Block a user