diff --git a/Makefile.libretro b/Makefile.libretro index 39c5647c2..2ad815f91 100755 --- a/Makefile.libretro +++ b/Makefile.libretro @@ -1,8 +1,17 @@ CORE_DIR := . LIBRETRO_DIR = $(CORE_DIR)/libretro ZLIB_DIR = $(LIBRETRO_DIR)/utils/zlib -STATIC_LINKING=0 -STATIC_LINKING_LINK=0 + +IPFSUPPORT ?= 0 +IPFDIR ?= + +ifeq ($(IPFSUPPORT), 1) +CAPS_DIR = $(IPFDIR) +CAPS_LIB = -L$(CAPS_DIR) -lCAPSImg_x64 +else +CAPS_DIR = +CAPS_LIB = +endif ifeq ($(platform),) platform = unix @@ -17,93 +26,30 @@ else ifneq ($(findstring win,$(shell uname -a)),) endif endif -EXTERNAL_ZLIB ?= 0 +EXTERNAL_ZLIB = 0 TARGET_NAME := hatari -GIT_VERSION := " $(shell git rev-parse --short HEAD || echo unknown)" -ifneq ($(GIT_VERSION)," unknown") - CFLAGS += -DGIT_VERSION=\"$(GIT_VERSION)\" -endif ifeq ($(platform), unix) - TARGET := $(TARGET_NAME)_libretro.so + CC = gcc + TARGET := $(TARGET_NAME)_libretro.so fpic := -fPIC - SHARED := -lpthread -shared -Wl,--version-script=$(LIBRETRO_DIR)/link.T -Wl,--no-undefined -Wl,--as-needed - PLATFLAGS := -DLSB_FIRST -DALIGN_DWORD -ifeq ($(ARCH), arm) - CFLAGS += -mno-unaligned-access -endif + SHARED := -lz -lpthread -shared -Wl,--version-script=$(LIBRETRO_DIR)/link.T -Wl,--no-undefined + PLATFLAGS := -DLSB_FIRST -DALIGN_DWORD else ifeq ($(platform), android) CC = arm-linux-androideabi-gcc AR = @arm-linux-androideabi-ar LD = @arm-linux-androideabi-g++ - TARGET := $(TARGET_NAME)_libretro.so + TARGET := $(TARGET_NAME)_libretro.so fpic := -fPIC SHARED := -Wl,--fix-cortex-a8 -llog -lz -shared -Wl,--version-script=$(LIBRETRO_DIR)/link.T -Wl,--no-undefined PLATFLAGS := -DAND -DLSB_FIRST -DALIGN_DWORD - -# Classic Platforms #################### -# Platform affix = classic__<ÂľARCH> -# Help at https://modmyclassic.com/comp - -# (armv7 a7, hard point, neon based) ### -# NESC, SNESC, C64 mini -else ifeq ($(platform), classic_armv7_a7) - TARGET := $(TARGET_NAME)_libretro.so - fpic := -fPIC - SHARED := -lz -lpthread -shared -Wl,--version-script=$(LIBRETRO_DIR)/link.T -Wl,--no-undefined - CFLAGS += -Ofast \ - -fdata-sections -ffunction-sections -Wl,--gc-sections \ - -fno-stack-protector -fno-ident -fomit-frame-pointer \ - -falign-functions=1 -falign-jumps=1 -falign-loops=1 \ - -fno-unwind-tables -fno-asynchronous-unwind-tables -fno-unroll-loops \ - -fmerge-all-constants -fno-math-errno \ - -marm -mtune=cortex-a7 -mfpu=neon-vfpv4 -mfloat-abi=hard - HAVE_NEON = 1 - ARCH = arm - PLATFLAGS := -DLSB_FIRST -DALIGN_DWORD - ifeq ($(shell echo `$(CC) -dumpversion` "< 4.9" | bc -l), 1) - CFLAGS += -march=armv7-a - else - CFLAGS += -march=armv7ve - # If gcc is 5.0 or later - ifeq ($(shell echo `$(CC) -dumpversion` ">= 5" | bc -l), 1) - LDFLAGS += -static-libgcc -static-libstdc++ - endif - endif -####################################### - else ifeq ($(platform), osx) TARGET := $(TARGET_NAME)_libretro.dylib fpic := -fPIC SHARED := -dynamiclib PLATFLAGS := -DLSB_FIRST -DALIGN_DWORD - -# ARM -else ifneq (,$(findstring armv,$(platform))) - CC = gcc - TARGET := $(TARGET_NAME)_libretro.so - fpic := -fPIC -fsigned-char - SHARED := -lz -lpthread -shared -Wl,--version-script=$(LIBRETRO_DIR)/link.T -Wl,--no-undefined - PLATFLAGS := -DLSB_FIRST -DALIGN_DWORD - CFLAGS += -marm -ifneq (,$(findstring neon,$(platform))) - CFLAGS += -mfpu=neon - ASFLAGS += -mfpu=neon - HAVE_NEON = 1 -endif -ifneq (,$(findstring softfloat,$(platform))) - CFLAGS += -mfloat-abi=softfp - ASFLAGS += -mfloat-abi=softfp -else ifneq (,$(findstring hardfloat,$(platform))) - CFLAGS += -mfloat-abi=hard - ASFLAGS += -mfloat-abi=hard -endif - CFLAGS += -DARM - -# iOS -else ifneq (,$(findstring ios,$(platform))) - +else ifeq ($(platform), ios) TARGET := $(TARGET_NAME)_libretro_ios.dylib fpic := -fPIC SHARED := -dynamiclib @@ -111,30 +57,15 @@ else ifneq (,$(findstring ios,$(platform))) ifeq ($(IOSSDK),) IOSSDK := $(shell xcodebuild -version -sdk iphoneos Path) endif - ifeq ($(platform),ios-arm64) - CC = cc -arch arm64 -isysroot $(IOSSDK) - else - CC = cc -arch armv7 -isysroot $(IOSSDK) - endif - CFLAGS += -DIOS -marm -DHAVE_POSIX_MEMALIGN=1 -w - -ifeq ($(platform),$(filter $(platform),ios9 ios-arm64)) - CC += -miphoneos-version-min=8.0 - CFLAGS += -miphoneos-version-min=8.0 -else - CC += -miphoneos-version-min=5.0 - CFLAGS += -miphoneos-version-min=5.0 -endif - -else ifeq ($(platform), tvos-arm64) - TARGET := $(TARGET_NAME)_libretro_tvos.dylib - fpic := -fPIC - SHARED := -dynamiclib - ifeq ($(IOSSDK),) - IOSSDK := $(shell xcodebuild -version -sdk appletvos Path) - endif + CC = clang -arch armv7 -isysroot $(IOSSDK) CFLAGS += -DIOS -marm -DHAVE_POSIX_MEMALIGN=1 -w + OSXVER = `sw_vers -productVersion | cut -d. -f 2` + OSX_LT_MAVERICKS = `(( $(OSXVER) <= 9)) && echo "YES"` + ifeq ($(OSX_LT_MAVERICKS),"YES") + CC += -miphoneos-version-min=5.0 + CFLAGS += -miphoneos-version-min=5.0 + endif else ifeq ($(platform), wii) TARGET := $(TARGET_NAME)_libretro_wii.a @@ -147,58 +78,23 @@ else ifeq ($(platform), wii) SHARED := -lm -lpthread -lc PLATFLAGS := -DALIGN_DWORD EXTERNAL_ZLIB = 1 - STATIC_LINKING=1 - STATIC_LINKING_LINK=1 -# Nintendo Game Cube / Wii / WiiU -else ifeq ($(platform), wiiu) - TARGET := $(TARGET_NAME)_libretro_$(platform).a - CC = $(DEVKITPPC)/bin/powerpc-eabi-gcc$(EXE_EXT) - CXX = $(DEVKITPPC)/bin/powerpc-eabi-g++$(EXE_EXT) - AR = $(DEVKITPPC)/bin/powerpc-eabi-ar$(EXE_EXT) - PLATFORM_DEFINES += -DSDL_BYTEORDER=SDL_BIG_ENDIAN -DMSB_FIRST -DBYTE_ORDER=BIG_ENDIAN -DBYTE_ORDER=BIG_ENDIAN - PLATFORM_DEFINES += -DGEKKO -mcpu=750 -meabi -mhard-float -DHAVE_STRTOF_L -DHAVE_LOCALE - PLATFORM_DEFINES += -U__INT32_TYPE__ -U __UINT32_TYPE__ -D__INT32_TYPE__=int -D_GNU_SOURCE - PLATFORM_DEFINES += -DWIIU -DHW_RVL -mwup -DWORDS_BIGENDIAN=1 -Dpowerpc -D__POWERPC__ -D__ppc__ - STATIC_LINKING=1 - STATIC_LINKING_LINK = 1 - CFLAGS += -DALIGN_DWORD $(PLATFORM_DEFINES) -I$(ZLIB_DIR) - -# Lightweight PS3 Homebrew SDK -else ifneq (,$(filter $(platform), ps3 psl1ght)) - TARGET := $(TARGET_NAME)_libretro_$(platform).a - CC = $(PS3DEV)/ppu/bin/ppu-$(COMMONLV)gcc$(EXE_EXT) - CXX = $(PS3DEV)/ppu/bin/ppu-$(COMMONLV)g++$(EXE_EXT) - AR = $(PS3DEV)/ppu/bin/ppu-$(COMMONLV)ar$(EXE_EXT) - SHARED := -lm -lpthread -lc - CFLAGS += -DSDL_BYTEORDER=SDL_BIG_ENDIAN -DMSB_FIRST -DBYTE_ORDER=BIG_ENDIAN -DBYTE_ORDER=BIG_ENDIAN \ - -D__PS3__ -DHAVE_MEMALIGN -DHAVE_ASPRINTF -I$(ZLIB_DIR) - PLATFLAGS := -DALIGN_DWORD - EXTERNAL_ZLIB = 1 - ifeq ($(platform), psl1ght) - CFLAGS += -D__PSL1GHT__ - endif - STATIC_LINKING=1 - STATIC_LINKING_LINK=1 - -else ifeq ($(platform), vita) - TARGET := $(TARGET_NAME)_libretro_vita.a - CC = arm-vita-eabi-gcc - CXX = arm-vita-eabi-g++ - AR = arm-vita-eabi-ar - CFLAGS += -DLSB_FIRST -DSDL_BYTEORDER=SDL_LIL_ENDIAN - PLATFLAGS := -U__INT32_TYPE__ -U __UINT32_TYPE__ -D__INT32_TYPE__=int -DHAVE_STRTOUL -DVITA -I$(ZLIB_DIR) -DHAVE_ALPHASORT -DHAVE_SCANDIR - STATIC_LINKING=1 - STATIC_LINKING_LINK=1 +else ifeq ($(platform), ps3) + TARGET := $(TARGET_NAME)_libretro_ps3.a + CC = $(CELL_SDK)/host-win32/ppu/bin/ppu-lv2-gcc.exe + CXX = $(CELL_SDK)/host-win32/ppu/bin/ppu-lv2-g++.exe + AR = $(CELL_SDK)/host-win32/ppu/bin/ppu-lv2-ar.exe + SHARED := -lm -lpthread -lc + CFLAGS += -DSDL_BYTEORDER=SDL_BIG_ENDIAN -DMSB_FIRST -DBYTE_ORDER=BIG_ENDIAN -DBYTE_ORDER=BIG_ENDIAN \ + -D__CELLOS_LV2 -DHAVE_MEMALIGN -DHAVE_ASPRINTF -I$(ZLIB_DIR) + PLATFLAGS := -DALIGN_DWORD + EXTERNAL_ZLIB = 1 else + #CC = i586-mingw32msvc-gcc + CC = x86_64-w64-mingw32-gcc + #CC = i686-w64-mingw32-gcc PLATFLAGS := -DLSB_FIRST -DALIGN_DWORD -DWIN32PORT -DWIN32 TARGET := $(TARGET_NAME)_libretro.dll SHARED := -shared -static-libgcc -s -Wl,--version-script=$(LIBRETRO_DIR)/link.T -Wl,--no-undefined - EXTERNAL_ZLIB = 1 -endif - -ZLIB = -ifneq ($(EXTERNAL_ZLIB), 1) -ZLIB = -lz endif ifeq ($(capsimg), 1) @@ -206,15 +102,17 @@ PLATFLAGS += -DHAVE_CAPSIMAGE -DCAPSIMAGE_VERSION=5 -I$(capssrc)/LibIPF/ -I$(cap endif ifeq ($(DEBUG), 1) -CFLAGS += -Og -g + CFLAGS += -O0 -g else -CFLAGS += -funroll-loops -ffast-math -fomit-frame-pointer -O3 + CFLAGS += -O3 endif -CFLAGS += -fsigned-char -D__LIBRETRO__ -fno-builtin -CFLAGS += $(fpic) $(PLATFLAGS) -CXXFLAGS := $(CFLAGS) -CPPFLAGS := $(CFLAGS) +CFLAGS += \ + -std=gnu99 -finline-functions -funroll-loops -fsigned-char -D__LIBRETRO__ \ + -Wno-strict-prototypes -ffast-math -fomit-frame-pointer -fno-strength-reduce -fno-builtin -finline-functions + +CXXFLAGS += $(CFLAGS) +CPPFLAGS += $(CFLAGS) EMU = $(CORE_DIR)/src CPU = $(EMU)/uae-cpu @@ -223,25 +121,41 @@ DBG = $(EMU)/debug FLP = $(EMU) GUI = $(LIBRETRO_DIR)/gui-retro CPU_PREGEN = $(LIBRETRO_DIR)/uae-cpu-pregen +LIBCOOBJ = $(LIBRETRO_DIR)/utils/libco LIBUTILS = $(LIBRETRO_DIR)/utils include Makefile.common +ifeq ($(IPFSUPPORT), 1) +INCFLAGS += -I$(CAPS_DIR)/include +PLATFLAGS += -DHAVE_CAPSIMAGE=1 +endif + OBJECTS := $(SOURCES_C:.c=.o) all: $(TARGET) -$(TARGET): $(OBJECTS) -ifeq ($(STATIC_LINKING_LINK),1) +ifeq ($(platform), wii) +$(TARGET): $(OBJECTS) + $(AR) rcs $@ $(OBJECTS) +else ifeq ($(platform), ps3) +$(TARGET): $(OBJECTS) $(AR) rcs $@ $(OBJECTS) + +else ifeq ($(platform), win) +$(TARGET): $(OBJECTS) + $(CC) $(fpic) $(SHARED) $(INCLUDES) -o $@ $(OBJECTS) -lm -lz $(CAPS_LIB) +else ifeq ($(platform), android) +$(TARGET): $(OBJECTS) + $(CC) $(fpic) $(SHARED) $(INCLUDES) -o $@ $(OBJECTS) -lm -lz else - $(CC) $(CFLAGS) $(INCFLAGS) $(LDFLAGS) $(OBJECTS) -o $@ -lm $(ZLIB) $(SHARED) +$(TARGET): $(OBJECTS) + $(CC) $(fpic) $(SHARED) $(INCLUDES) -o $@ $(OBJECTS) -lm -lz -lpthread $(CAPS_LIB) + endif %.o: %.c - $(CC) $(CFLAGS) $(INCFLAGS) -c -o $@ $< + $(CC) $(fpic) $(CFLAGS) $(PLATFLAGS) $(INCFLAGS) -c -o $@ $< clean: rm -f $(OBJECTS) $(TARGET) - -.PHONY: clean diff --git a/src/capsimg_binary/CAPSImg.lib b/src/capsimg_binary/CAPSImg.lib new file mode 100644 index 000000000..d1eb7f1db Binary files /dev/null and b/src/capsimg_binary/CAPSImg.lib differ diff --git a/src/capsimg_binary/CapsAPI.h b/src/capsimg_binary/CapsAPI.h new file mode 100644 index 000000000..0d5bc9d66 --- /dev/null +++ b/src/capsimg_binary/CapsAPI.h @@ -0,0 +1,274 @@ +#ifndef CAPSAPI_H +#define CAPSAPI_H + +#define CAPS_FILEEXT "ipf" +#define CAPS_FILEPFX ".ipf" + +// Flags provided for locking, in order: +// 0: re-align data as index synced recording +// 1: decode track to word aligned size +// 2: generate cell density for variable density tracks +// 3: generate density for automatically sized cells +// 4: generate density for unformatted cells +// 5: generate unformatted data +// 6: generate unformatted data, that changes each revolution +// 7: directly use source memory buffer supplied with LockImageMemory +// 8: flakey/weak data is created on one revolution, updated with each lock +// 9: ...Info.type holds the expected structure type +// 10: alternate density map as fractions +// 11: overlap position is in bits +// 12: tracklen is in bits, and the track buffer is bit sized +// 13: track overlap or weak data is never updated, just initialized +// 14: set weak bit generator seed value +#define DI_LOCK_INDEX DF_0 +#define DI_LOCK_ALIGN DF_1 +#define DI_LOCK_DENVAR DF_2 +#define DI_LOCK_DENAUTO DF_3 +#define DI_LOCK_DENNOISE DF_4 +#define DI_LOCK_NOISE DF_5 +#define DI_LOCK_NOISEREV DF_6 +#define DI_LOCK_MEMREF DF_7 +#define DI_LOCK_UPDATEFD DF_8 +#define DI_LOCK_TYPE DF_9 +#define DI_LOCK_DENALT DF_10 +#define DI_LOCK_OVLBIT DF_11 +#define DI_LOCK_TRKBIT DF_12 +#define DI_LOCK_NOUPDATE DF_13 +#define DI_LOCK_SETWSEED DF_14 + +#define CAPS_MAXPLATFORM 4 +#define CAPS_MTRS 5 + +#define CTIT_FLAG_FLAKEY DF_31 +#define CTIT_MASK_TYPE 0xff + +#pragma pack(push, 1) + +// decoded caps date.time +struct CapsDateTimeExt { + UDWORD year; + UDWORD month; + UDWORD day; + UDWORD hour; + UDWORD min; + UDWORD sec; + UDWORD tick; +}; + +typedef struct CapsDateTimeExt *PCAPSDATETIMEEXT; + +// library version information block +struct CapsVersionInfo { + UDWORD type; // library type + UDWORD release; // release ID + UDWORD revision; // revision ID + UDWORD flag; // supported flags +}; + +typedef struct CapsVersionInfo *PCAPSVERSIONINFO; + +// disk image information block +struct CapsImageInfo { + UDWORD type; // image type + UDWORD release; // release ID + UDWORD revision; // release revision ID + UDWORD mincylinder; // lowest cylinder number + UDWORD maxcylinder; // highest cylinder number + UDWORD minhead; // lowest head number + UDWORD maxhead; // highest head number + struct CapsDateTimeExt crdt; // image creation date.time + UDWORD platform[CAPS_MAXPLATFORM]; // intended platform(s) +}; + +typedef struct CapsImageInfo *PCAPSIMAGEINFO; + +// disk track information block +struct CapsTrackInfo { + UDWORD type; // track type + UDWORD cylinder; // cylinder# + UDWORD head; // head# + UDWORD sectorcnt; // available sectors + UDWORD sectorsize; // sector size + UDWORD trackcnt; // track variant count + PUBYTE trackbuf; // track buffer memory + UDWORD tracklen; // track buffer memory length + PUBYTE trackdata[CAPS_MTRS]; // track data pointer if available + UDWORD tracksize[CAPS_MTRS]; // track data size + UDWORD timelen; // timing buffer length + PUDWORD timebuf; // timing buffer +}; + +typedef struct CapsTrackInfo *PCAPSTRACKINFO; + +// disk track information block +struct CapsTrackInfoT1 { + UDWORD type; // track type + UDWORD cylinder; // cylinder# + UDWORD head; // head# + UDWORD sectorcnt; // available sectors + UDWORD sectorsize; // sector size + PUBYTE trackbuf; // track buffer memory + UDWORD tracklen; // track buffer memory length + UDWORD timelen; // timing buffer length + PUDWORD timebuf; // timing buffer + SDWORD overlap; // overlap position +}; + +typedef struct CapsTrackInfoT1 *PCAPSTRACKINFOT1; + +// disk track information block +struct CapsTrackInfoT2 { + UDWORD type; // track type + UDWORD cylinder; // cylinder# + UDWORD head; // head# + UDWORD sectorcnt; // available sectors + UDWORD sectorsize; // sector size, unused + PUBYTE trackbuf; // track buffer memory + UDWORD tracklen; // track buffer memory length + UDWORD timelen; // timing buffer length + PUDWORD timebuf; // timing buffer + SDWORD overlap; // overlap position + UDWORD startbit; // start position of the decoding + UDWORD wseed; // weak bit generator data + UDWORD weakcnt; // number of weak data areas +}; + +typedef struct CapsTrackInfoT2 *PCAPSTRACKINFOT2; + +// disk sector information block +struct CapsSectorInfo { + UDWORD descdatasize; // data size in bits from IPF descriptor + UDWORD descgapsize; // gap size in bits from IPF descriptor + UDWORD datasize; // data size in bits from decoder + UDWORD gapsize; // gap size in bits from decoder + UDWORD datastart; // data start position in bits from decoder + UDWORD gapstart; // gap start position in bits from decoder + UDWORD gapsizews0; // gap size before write splice + UDWORD gapsizews1; // gap size after write splice + UDWORD gapws0mode; // gap size mode before write splice + UDWORD gapws1mode; // gap size mode after write splice + UDWORD celltype; // bitcell type + UDWORD enctype; // encoder type +}; + +typedef struct CapsSectorInfo *PCAPSSECTORINFO; + +// disk data information block +struct CapsDataInfo { + UDWORD type; // data type + UDWORD start; // start position + UDWORD size; // size in bits +}; + +typedef struct CapsDataInfo *PCAPSDATAINFO; + +// disk data information block +struct CapsRevolutionInfo { + SDWORD next; // the revolution number used by the next track lock call + SDWORD last; // the revolution number used by the lack track lock call + SDWORD real; // the real revolution number used by the last track lock call + SDWORD max; // the maximum revolution available for the selected track, <0 unlimited/randomized, 0 empty +}; + +typedef struct CapsRevolutionInfo *PCAPSREVOLUTIONINFO; + +#pragma pack(pop) + +// CapsImageInfo.image type +enum { + ciitNA=0, // invalid image type + ciitFDD // floppy disk +}; + +// CapsImageInfo.platform IDs, not about configuration, but intended use +enum { + ciipNA=0, // invalid platform (dummy entry) + ciipAmiga, + ciipAtariST, + ciipPC, + ciipAmstradCPC, + ciipSpectrum, + ciipSamCoupe, + ciipArchimedes, + ciipC64, + ciipAtari8 +}; + +// CapsTrackInfo.track type +enum { + ctitNA=0, // invalid type + ctitNoise, // cells are unformatted (random size) + ctitAuto, // automatic cell size, according to track size + ctitVar // variable density +}; + +// CapsSectorInfo.bitcell type +enum { + csicNA=0, // invalid cell type + csic2us // 2us cells +}; + +// CapsSectorInfo.encoder type +enum { + csieNA=0, // undefined encoder + csieMFM, // MFM + csieRaw // no encoder used, test data only +}; + +// CapsSectorInfo.gap size mode +enum { + csiegmFixed=0, // fixed size, can't be changed + csiegmAuto, // size can be changed, resize information calculated automatically + csiegmResize // size can be changed, resize information is scripted +}; + +// CapsDataInfo.data type +enum { + cditNA=0, // undefined + cditWeak // weak bits +}; + +// CAPSGetInfo inftype +enum { + cgiitNA=0, // illegal + cgiitSector, // CapsSectorInfo + cgiitWeak, // CapsDataInfo, weak bits + cgiitRevolution // CapsRevolutionInfo +}; + +// recognized image types +enum { + citError=0, // error preventing the type identification + citUnknown, // unknown image type + citIPF, // IPF image + citCTRaw, // CT Raw image + citKFStream, // KryoFlux stream files + citKFStreamCue, // KryoFlux stream cue file + citDraft // Draft image +}; + +// image error status +enum { + imgeOk=0, + imgeUnsupported, + imgeGeneric, + imgeOutOfRange, + imgeReadOnly, + imgeOpen, + imgeType, + imgeShort, + imgeTrackHeader, + imgeTrackStream, + imgeTrackData, + imgeDensityHeader, + imgeDensityStream, + imgeDensityData, + imgeIncompatible, + imgeUnsupportedType, + imgeBadBlockType, + imgeBadBlockSize, + imgeBadDataStart, + imgeBufferShort +}; + +#endif diff --git a/src/capsimg_binary/CapsFDC.h b/src/capsimg_binary/CapsFDC.h new file mode 100644 index 000000000..5ffe557d5 --- /dev/null +++ b/src/capsimg_binary/CapsFDC.h @@ -0,0 +1,246 @@ +#ifndef CAPSFDC_H +#define CAPSFDC_H + +// drive defaults +#define CAPSDRIVE_35DD_RPM 300 +#define CAPSDRIVE_35DD_HST 83 + +// disk & drive attributes +// 0: true disk inserted (if not inserted it is write protected) +// 1: true disk write protected +// 2: true motor on +// 3: true single sided drive +#define CAPSDRIVE_DA_IN DF_0 +#define CAPSDRIVE_DA_WP DF_1 +#define CAPSDRIVE_DA_MO DF_2 +#define CAPSDRIVE_DA_SS DF_3 + +// index pulse only available if disk is inserted and motor is running +#define CAPSDRIVE_DA_IPMASK (CAPSDRIVE_DA_IN|CAPSDRIVE_DA_MO) + +// fdc output lines +// 0: drq line state +// 1: intrq line state +// 2: forced interrupt, internal +// 3: motor line state +// 4: direction line state +// 5: interrupt on index pulse +// 6: set drq, internal +#define CAPSFDC_LO_DRQ DF_0 +#define CAPSFDC_LO_INTRQ DF_1 +#define CAPSFDC_LO_INTFRC DF_2 +#define CAPSFDC_LO_MO DF_3 +#define CAPSFDC_LO_DIRC DF_4 +#define CAPSFDC_LO_INTIP DF_5 +#define CAPSFDC_LO_DRQSET DF_6 + +// fdc status lines +// 0: busy +// 1: index pulse/drq +// 2: track0/lost data +// 3: crc error +// 4: record not found +// 5: spin-up/record type +// 6: write protect +// 7: motor on +#define CAPSFDC_SR_BUSY DF_0 +#define CAPSFDC_SR_IP_DRQ DF_1 +#define CAPSFDC_SR_TR0_LD DF_2 +#define CAPSFDC_SR_CRCERR DF_3 +#define CAPSFDC_SR_RNF DF_4 +#define CAPSFDC_SR_SU_RT DF_5 +#define CAPSFDC_SR_WP DF_6 +#define CAPSFDC_SR_MO DF_7 + +// flags to clear before new command +#define CAPSFDC_SR_NCCLR (CAPSFDC_SR_SU_RT|CAPSFDC_SR_RNF|CAPSFDC_SR_CRCERR|CAPSFDC_SR_BUSY) + +// flags to set before new command +#define CAPSFDC_SR_NCSET CAPSFDC_SR_BUSY + +// type1 mask, index/track0/spin-up +// type2 read mask, drq/lost data/record type/wp=0 +// type2 write mask, drq/lost data/record type +#define CAPSFDC_SM_TYPE1 0x00 +#define CAPSFDC_SM_TYPE2R (CAPSFDC_SR_IP_DRQ|CAPSFDC_SR_TR0_LD|CAPSFDC_SR_SU_RT|CAPSFDC_SR_WP) +#define CAPSFDC_SM_TYPE2W (CAPSFDC_SR_IP_DRQ|CAPSFDC_SR_TR0_LD|CAPSFDC_SR_SU_RT) + +// end request flags +// 0: command complete +// 1: request to stop execution at current cycle; can be bitwise set in a callback +#define CAPSFDC_ER_COMEND DF_0 +#define CAPSFDC_ER_REQEND DF_1 + +// am info flags +// 0: AM detector enabled +// 1: CRC logic enabled +// 2: CRC logic active after first mark found +// 3: data being assembled in DSR is the last byte of AM +// 4: data being assembled in DSR is an A1 mark +// 5: AM in decoder, valid for 1 cell +// 6: A1 mark in decoder, valid for 1 cell +// 7: C2 mark in decoder, valid for 1 cell +// 8: DSR holds a complete byte, valid until DSR has been changed +// 9: DSR synced to AM, valid until DSR has been changed, next DSRREADY is a data byte +// 10: DSR synced to A1 mark +#define CAPSFDC_AI_AMDETENABLE DF_0 +#define CAPSFDC_AI_CRCENABLE DF_1 +#define CAPSFDC_AI_CRCACTIVE DF_2 +#define CAPSFDC_AI_AMACTIVE DF_3 +#define CAPSFDC_AI_MA1ACTIVE DF_4 +#define CAPSFDC_AI_AMFOUND DF_5 +#define CAPSFDC_AI_MARKA1 DF_6 +#define CAPSFDC_AI_MARKC2 DF_7 +#define CAPSFDC_AI_DSRREADY DF_8 +#define CAPSFDC_AI_DSRAM DF_9 +#define CAPSFDC_AI_DSRMA1 DF_10 + +#pragma pack(push, 1) + +// drive state +struct CapsDrive { + UDWORD type; // structure size + UDWORD rpm; // drive rpm + SDWORD maxtrack; // track with hard stop (head can't move) + SDWORD track; // actual track + SDWORD buftrack; // track# in buffer + SDWORD side; // actual side used for processing + SDWORD bufside; // side# in buffer + SDWORD newside; // side to select after processing + UDWORD diskattr; // disk attributes + UDWORD idistance; // distance from index in clock cycles + UDWORD clockrev; // clock cycles per revolution + SDWORD clockip; // clock cycles for index pulse hold + SDWORD ipcnt; // index pulse clock counter, <0 init, 0 stopped + UDWORD ttype; // track type + PUBYTE trackbuf; // track buffer memory + PUDWORD timebuf; // timing buffer + UDWORD tracklen; // track buffer memory length + SDWORD overlap; // overlap position + SDWORD trackbits; // used track size + SDWORD ovlmin; // overlap first bit position + SDWORD ovlmax; // overlap last bit position + SDWORD ovlcnt; // overlay bit count + SDWORD ovlact; // active overlay phase + SDWORD nact; // active noise phase + UDWORD nseed; // noise generator seed + PVOID userptr; // free to use pointer for the host application + UDWORD userdata; // free to use data for the host application +}; + +typedef struct CapsDrive *PCAPSDRIVE; + +typedef struct CapsFdc *PCAPSFDC; +typedef void (__cdecl *CAPSFDCHOOK)(PCAPSFDC pfdc, UDWORD state); + +// fdc state +struct CapsFdc { + UDWORD type; // structure size + UDWORD model; // fdc type + UDWORD endrequest; // non-zero value ends command + UDWORD clockact; // clock cycles completed + UDWORD clockreq; // requested clock cycles to complete + UDWORD clockfrq; // clock frequency + UDWORD addressmask; // valid address lines + UDWORD dataline; // data bus + UDWORD datamask; // valid data lines + UDWORD lineout; // output lines + UDWORD runmode; // run mode + UDWORD runstate; // local run state in a command + UDWORD r_st0; // status0 register + UDWORD r_st1; // status1 register + UDWORD r_stm; // status mask register (1 bits select st1) + UDWORD r_command; // command register + UDWORD r_track; // track register + UDWORD r_sector; // sector register + UDWORD r_data; // data register + UDWORD seclenmask; // sector length mask + UDWORD seclen; // sector length + UDWORD crc; // crc holder + UDWORD crccnt; // crc bit counter + UDWORD amdecode; // am detector decoder/shifter + UDWORD aminfo; // am info + UDWORD amisigmask; // enabled am info signal bits + SDWORD amdatadelay; // am data delay clock + SDWORD amdataskip; // am data skip clock + SDWORD ammarkdist; // am invalid distance from last mark in bitcells or 0 if valid + SDWORD ammarktype; // am last mark type + UDWORD dsr; // data shift register + SDWORD dsrcnt; // dsr bit counter + SDWORD datalock; // data lock bit position, <0 not locked + UDWORD datamode; // data access mode + UDWORD datacycle; // clock cycle remainder of actual bit + UDWORD dataphase; // data access phase + UDWORD datapcnt; // data phase counter + SDWORD indexcount; // index pulse counter + SDWORD indexlimit; // index pulse abort point + SDWORD readlimit; // read abort point + SDWORD verifylimit; // verify abort point + SDWORD spinupcnt; // counter for spin-up status + SDWORD spinuplimit; // spin-up point + SDWORD idlecnt; // counter for idle + SDWORD idlelimit; // idle point + UDWORD clockcnt; // clock counter + UDWORD steptime[4]; // stepping rates us + UDWORD clockstep[4]; // clock cycles for stepping rates + UDWORD hstime; // head settling delay us + UDWORD clockhs; // clock cycles for head settling + UDWORD iptime; // index pulse hold us + UDWORD updatetime; // update delay between short operations us + UDWORD clockupdate; // clock cycles for update delay + SDWORD drivecnt; // number of drives, 0: no drive attached + SDWORD drivemax; // number of active drives, 0: no drive attached + SDWORD drivenew; // drive to select after processing, <0 invalid + SDWORD drivesel; // drive selected for processing, <0 invalid + SDWORD driveact; // drive used for processing, <0 invalid + PCAPSDRIVE driveprc; // drive processed, helper + PCAPSDRIVE drive; // available drives + CAPSFDCHOOK cbirq; // irq line change callback + CAPSFDCHOOK cbdrq; // drq line change callback + CAPSFDCHOOK cbtrk; // track change callback + PVOID userptr; // free to use pointer for the host application + UDWORD userdata; // free to use data for the host application +}; + +#pragma pack(pop) + +// emulator info +enum { + cfdciNA=0, // invalid + cfdciSize_Fdc, // size required for FDC structure + cfdciSize_Drive, // size required for Drive structure + cfdciR_Command, // command register + cfdciR_ST, // status register + cfdciR_Track, // track register + cfdciR_Sector, // sector register + cfdciR_Data, // data register +}; + +// fdc models +enum { + cfdcmNA=0, // invalid fdc model + cfdcmWD1772 // WD1772 +}; + +// run modes +enum { + cfdcrmNop=0, // no-operation + cfdcrmIdle, // idle/wait loop + cfdcrmType1, // type 1 loop + cfdcrmType2R, // type 2 read loop + cfdcrmType2W, // type 2 write loop + cfdcrmType3R, // type 3 read loop + cfdcrmType3W, // type 3 write loop + cfdcrmType3A, // type 3 address loop + cfdcrmType4 // type 4 loop +}; + +// data modes +enum { + cfdcdmNoline=0, // no line input + cfdcdmNoise, // noise input + cfdcdmData, // data input + cfdcdmDMap // data with density map +}; + +#endif diff --git a/src/capsimg_binary/CapsForm.h b/src/capsimg_binary/CapsForm.h new file mode 100644 index 000000000..c74d23b30 --- /dev/null +++ b/src/capsimg_binary/CapsForm.h @@ -0,0 +1,54 @@ +#ifndef CAPSFORM_H +#define CAPSFORM_H + +#pragma pack(push, 1) + +// block data descriptor for converter +struct CapsFormatBlock { + UDWORD gapacnt; // gap before first am count + UDWORD gapavalue; // gap before first am value + UDWORD gapbcnt; // gap after first am count + UDWORD gapbvalue; // gap after first am value + UDWORD gapccnt; // gap before second am count + UDWORD gapcvalue; // gap before second am value + UDWORD gapdcnt; // gap after second am count + UDWORD gapdvalue; // gap after second am value + UDWORD blocktype; // type of block + UDWORD track; // track# + UDWORD side; // side# + UDWORD sector; // sector# + SDWORD sectorlen; // sector length in bytes + PUBYTE databuf; // source data buffer + UDWORD datavalue; // source data value if buffer is NULL +}; + +typedef struct CapsFormatBlock *PCAPSFORMATBLOCK; + +// track data descriptor for converter +struct CapsFormatTrack { + UDWORD type; // structure type + UDWORD gapacnt; // gap after index count + UDWORD gapavalue; // gap after index value + UDWORD gapbvalue; // gap before index value + PUBYTE trackbuf; // track buffer memory + UDWORD tracklen; // track buffer memory length + UDWORD buflen; // track buffer allocation size + UDWORD bufreq; // track buffer requested size + UDWORD startpos; // start position in buffer + SDWORD blockcnt; // number of blocks + PCAPSFORMATBLOCK block; // block data + UDWORD size; // internal counter +}; + +typedef struct CapsFormatTrack *PCAPSFORMATTRACK; + +#pragma pack(pop) + +// block types +enum { + cfrmbtNA=0, // invalid type + cfrmbtIndex, // index + cfrmbtData // data +}; + +#endif diff --git a/src/capsimg_binary/CapsLib.h b/src/capsimg_binary/CapsLib.h new file mode 100644 index 000000000..b75cad213 --- /dev/null +++ b/src/capsimg_binary/CapsLib.h @@ -0,0 +1,38 @@ +#ifndef CAPSLIB_H +#define CAPSLIB_H + +#undef LIB_USER +#ifdef CAPS_USER +#define LIB_USER +#endif +#include "ComLib.h" + +ExtSub SDWORD __cdecl CAPSInit(); +ExtSub SDWORD __cdecl CAPSExit(); +ExtSub SDWORD __cdecl CAPSAddImage(); +ExtSub SDWORD __cdecl CAPSRemImage(SDWORD id); +ExtSub SDWORD __cdecl CAPSLockImage(SDWORD id, PCHAR name); +ExtSub SDWORD __cdecl CAPSLockImageMemory(SDWORD id, PUBYTE buffer, UDWORD length, UDWORD flag); +ExtSub SDWORD __cdecl CAPSUnlockImage(SDWORD id); +ExtSub SDWORD __cdecl CAPSLoadImage(SDWORD id, UDWORD flag); +ExtSub SDWORD __cdecl CAPSGetImageInfo(PCAPSIMAGEINFO pi, SDWORD id); +ExtSub SDWORD __cdecl CAPSLockTrack(PVOID ptrackinfo, SDWORD id, UDWORD cylinder, UDWORD head, UDWORD flag); +ExtSub SDWORD __cdecl CAPSUnlockTrack(SDWORD id, UDWORD cylinder, UDWORD head); +ExtSub SDWORD __cdecl CAPSUnlockAllTracks(SDWORD id); +ExtSub PCHAR __cdecl CAPSGetPlatformName(UDWORD pid); +ExtSub SDWORD __cdecl CAPSGetVersionInfo(PVOID pversioninfo, UDWORD flag); +ExtSub UDWORD __cdecl CAPSFdcGetInfo(SDWORD iid, PCAPSFDC pc, SDWORD ext); +ExtSub SDWORD __cdecl CAPSFdcInit(PCAPSFDC pc); +ExtSub void __cdecl CAPSFdcReset(PCAPSFDC pc); +ExtSub void __cdecl CAPSFdcEmulate(PCAPSFDC pc, UDWORD cyclecnt); +ExtSub UDWORD __cdecl CAPSFdcRead(PCAPSFDC pc, UDWORD address); +ExtSub void __cdecl CAPSFdcWrite(PCAPSFDC pc, UDWORD address, UDWORD data); +ExtSub SDWORD __cdecl CAPSFdcInvalidateTrack(PCAPSFDC pc, SDWORD drive); +ExtSub SDWORD __cdecl CAPSFormatDataToMFM(PVOID pformattrack, UDWORD flag); +ExtSub SDWORD __cdecl CAPSGetInfo(PVOID pinfo, SDWORD id, UDWORD cylinder, UDWORD head, UDWORD inftype, UDWORD infid); +ExtSub SDWORD __cdecl CAPSSetRevolution(SDWORD id, UDWORD value); +ExtSub SDWORD __cdecl CAPSGetImageType(PCHAR name); +ExtSub SDWORD __cdecl CAPSGetImageTypeMemory(PUBYTE buffer, UDWORD length); +ExtSub SDWORD __cdecl CAPSGetDebugRequest(); + +#endif diff --git a/src/capsimg_binary/CapsLibAll.h b/src/capsimg_binary/CapsLibAll.h new file mode 100644 index 000000000..8a87bcfc8 --- /dev/null +++ b/src/capsimg_binary/CapsLibAll.h @@ -0,0 +1,11 @@ +#ifndef CAPSLIBALL_H +#define CAPSLIBALL_H + +#include "CapsLibVersion.h" +#include "CommonTypes.h" +#include "CapsAPI.h" +#include "CapsFDC.h" +#include "CapsForm.h" +#include "CapsLib.h" + +#endif diff --git a/src/capsimg_binary/CapsLibVersion.h b/src/capsimg_binary/CapsLibVersion.h new file mode 100644 index 000000000..16b96043f --- /dev/null +++ b/src/capsimg_binary/CapsLibVersion.h @@ -0,0 +1,7 @@ +#ifndef CAPSLIBVERSION_H +#define CAPSLIBVERSION_H + +#define CAPS_LIB_RELEASE 5 +#define CAPS_LIB_REVISION 1 + +#endif diff --git a/src/capsimg_binary/ComLib.h b/src/capsimg_binary/ComLib.h new file mode 100644 index 000000000..cab19ca17 --- /dev/null +++ b/src/capsimg_binary/ComLib.h @@ -0,0 +1,20 @@ +#undef DllSub +#undef DllVar +#undef ExtSub +#undef ExtVar + +#ifdef LIB_USER + +#define DllSub DllImport +#define DllVar DllImport + +#else + +#define DllSub DllExport +#define DllVar extern DllExport + +#endif + +#define ExtSub extern "C" DllSub +#define ExtVar extern "C" DllVar + diff --git a/src/capsimg_binary/CommonTypes.h b/src/capsimg_binary/CommonTypes.h new file mode 100644 index 000000000..85f56eee2 --- /dev/null +++ b/src/capsimg_binary/CommonTypes.h @@ -0,0 +1,104 @@ +#ifndef COMMONTYPES_H +#define COMMONTYPES_H + +typedef void *PVOID; +typedef char *PCHAR; + +typedef uint8_t UBYTE; +typedef uint16_t UWORD; +typedef uint32_t UDWORD; +typedef uint64_t UQUAD; +typedef int8_t SBYTE; +typedef int16_t SWORD; +typedef int32_t SDWORD; +typedef int64_t SQUAD; + +typedef UBYTE *PUBYTE; +typedef UWORD *PUWORD; +typedef UDWORD *PUDWORD; +typedef UQUAD *PUQUAD; +typedef SBYTE *PSBYTE; +typedef SWORD *PSWORD; +typedef SDWORD *PSDWORD; +typedef SQUAD *PSQUAD; + +enum { + DB_0 = 0, + DB_1, + DB_2, + DB_3, + DB_4, + DB_5, + DB_6, + DB_7, + DB_8, + DB_9, + DB_10, + DB_11, + DB_12, + DB_13, + DB_14, + DB_15, + DB_16, + DB_17, + DB_18, + DB_19, + DB_20, + DB_21, + DB_22, + DB_23, + DB_24, + DB_25, + DB_26, + DB_27, + DB_28, + DB_29, + DB_30, + DB_31 +}; + +#define DF_0 (1UL<