diff --git a/.ci/Jenkinsfile b/.ci/Jenkinsfile index fbcb51c04..fbb7fd081 100644 --- a/.ci/Jenkinsfile +++ b/.ci/Jenkinsfile @@ -194,7 +194,7 @@ pipeline { /* Adding to the above, run a git clone as soon as possible on any node to further avoid race conditions caused by busy node executor delays. */ retry(10) { - node('citadel && !Windows') { + node('!Windows') { /* Run git clone. */ gitClone(repository[buildBranch], branch[buildBranch]) diff --git a/src/cpu/x86_ops_flag.h b/src/cpu/x86_ops_flag.h index 24c97339e..ce0cb4cd6 100644 --- a/src/cpu/x86_ops_flag.h +++ b/src/cpu/x86_ops_flag.h @@ -266,11 +266,11 @@ static int opPOPFD(uint32_t fetchdat) else if (IOPLp) cpu_state.flags = (cpu_state.flags & 0x3000) | (templ & 0x4fd5) | 2; else cpu_state.flags = (cpu_state.flags & 0x3200) | (templ & 0x4dd5) | 2; - templ &= (is486 || isibm486) ? 0x3c0000 : 0; + templ &= (is486) ? 0x3c0000 : 0; templ |= ((cpu_state.eflags&3) << 16); if (cpu_CR4_mask & CR4_VME) cpu_state.eflags = (templ >> 16) & 0x3f; else if (CPUID) cpu_state.eflags = (templ >> 16) & 0x27; - else if (is486 || isibm486) cpu_state.eflags = (templ >> 16) & 7; + else if (is486) cpu_state.eflags = (templ >> 16) & 7; else cpu_state.eflags = (templ >> 16) & 3; flags_extract(); diff --git a/src/discord.c b/src/discord.c index 27b8c6fdf..d1966a93d 100644 --- a/src/discord.c +++ b/src/discord.c @@ -15,69 +15,68 @@ * Copyright 2019 David Hrdlička. */ #include -#include #include +#include #include #include #include #define HAVE_STDARG_H -#include <86box/86box.h> #include "cpu/cpu.h" +#include <86box/86box.h> +#include <86box/discord.h> #include <86box/machine.h> #include <86box/plat.h> #include <86box/plat_dynld.h> -#include <86box/discord.h> #include #ifdef _WIN32 -#define PATH_DISCORD_DLL "discord_game_sdk.dll" +# define PATH_DISCORD_DLL "discord_game_sdk.dll" #elif defined __APPLE__ -#define PATH_DISCORD_DLL "discord_game_sdk.dylib" +# define PATH_DISCORD_DLL "discord_game_sdk.dylib" #else -#define PATH_DISCORD_DLL "discord_game_sdk.so" +# define PATH_DISCORD_DLL "discord_game_sdk.so" #endif -int discord_loaded = 0; +int discord_loaded = 0; -static void *discord_handle = NULL; -static struct IDiscordCore *discord_core = NULL; -static struct IDiscordActivityManager *discord_activities = NULL; +static void *discord_handle = NULL; +static struct IDiscordCore *discord_core = NULL; +static struct IDiscordActivityManager *discord_activities = NULL; -static enum EDiscordResult (*discord_create)(DiscordVersion version, struct DiscordCreateParams* params, struct IDiscordCore** result); +static enum EDiscordResult(DISCORD_API *discord_create)(DiscordVersion version, struct DiscordCreateParams *params, struct IDiscordCore **result); static dllimp_t discord_imports[] = { - { "DiscordCreate", &discord_create }, - { NULL, NULL } + {"DiscordCreate", &discord_create}, + { NULL, NULL } }; #ifdef ENABLE_DISCORD_LOG int discord_do_log = 1; - static void discord_log(const char *fmt, ...) { va_list ap; if (discord_do_log) { - va_start(ap, fmt); - pclog_ex(fmt, ap); - va_end(ap); + va_start(ap, fmt); + pclog_ex(fmt, ap); + va_end(ap); } } #else -#define discord_log(fmt, ...) +# define discord_log(fmt, ...) #endif void discord_update_activity(int paused) { struct DiscordActivity activity; - char cpufamily[1024]; - char *paren; + char cpufamily[1024]; + char *paren; - if(discord_activities == NULL) - return; + if (discord_activities == NULL) + return; discord_log("discord: discord_update_activity(paused=%d)\n", paused); @@ -86,53 +85,47 @@ discord_update_activity(int paused) strncpy(cpufamily, cpu_f->name, sizeof(cpufamily) - 1); paren = strchr(cpufamily, '('); if (paren) - *(paren - 1) = '\0'; + *(paren - 1) = '\0'; #pragma GCC diagnostic push #if defined(__GNUC__) -#pragma GCC diagnostic ignored "-Wformat-truncation" +# pragma GCC diagnostic ignored "-Wformat-truncation" #endif - if (strlen(vm_name) < 100) - { - snprintf(activity.details, sizeof(activity.details), "Running \"%s\"", vm_name); - snprintf(activity.state, sizeof(activity.state), "%s (%s/%s)", strchr(machine_getname(), ']') + 2, cpufamily, cpu_s->name); - } - else - { - strncpy(activity.details, strchr(machine_getname(), ']') + 2, sizeof(activity.details) - 1); - snprintf(activity.state, sizeof(activity.state), "%s/%s", cpufamily, cpu_s->name); + if (strlen(vm_name) < 100) { + snprintf(activity.details, sizeof(activity.details), "Running \"%s\"", vm_name); + snprintf(activity.state, sizeof(activity.state), "%s (%s/%s)", strchr(machine_getname(), ']') + 2, cpufamily, cpu_s->name); + } else { + strncpy(activity.details, strchr(machine_getname(), ']') + 2, sizeof(activity.details) - 1); + snprintf(activity.state, sizeof(activity.state), "%s/%s", cpufamily, cpu_s->name); } #pragma GCC diagnostic pop activity.timestamps.start = time(NULL); -/* Icon choosing for Discord based on 86Box.rc */ + /* Icon choosing for Discord based on 86Box.rc */ #ifdef RELEASE_BUILD -/* Icon by OBattler and laciba96 (green for release builds)*/ + /* Icon by OBattler and laciba96 (green for release builds)*/ strcpy(activity.assets.large_image, "86box-green"); #elif BETA_BUILD -/* Icon by OBattler and laciba96 (yellow for beta builds done by Jenkins)*/ + /* Icon by OBattler and laciba96 (yellow for beta builds done by Jenkins)*/ strcpy(activity.assets.large_image, "86box-yellow"); #elif ALPHA_BUILD -/* Icon by OBattler and laciba96 (red for alpha builds done by Jenkins)*/ + /* Icon by OBattler and laciba96 (red for alpha builds done by Jenkins)*/ strcpy(activity.assets.large_image, "86box-red"); #else -/* Icon by OBattler and laciba96 (gray for builds of branches and from the git master)*/ + /* Icon by OBattler and laciba96 (gray for builds of branches and from the git master)*/ strcpy(activity.assets.large_image, "86box"); #endif -/* End of icon choosing */ + /* End of icon choosing */ - if (paused) - { - strcpy(activity.assets.small_image, "status-paused"); - strcpy(activity.assets.small_text, "Paused"); - } - else - { - strcpy(activity.assets.small_image, "status-running"); - strcpy(activity.assets.small_text, "Running"); + if (paused) { + strcpy(activity.assets.small_image, "status-paused"); + strcpy(activity.assets.small_text, "Paused"); + } else { + strcpy(activity.assets.small_image, "status-running"); + strcpy(activity.assets.small_text, "Running"); } discord_activities->update_activity(discord_activities, &activity, NULL, NULL); @@ -142,42 +135,40 @@ int discord_load() { if (discord_handle != NULL) - return(1); + return (1); // Try to load the DLL discord_handle = dynld_module(PATH_DISCORD_DLL, discord_imports); - if (discord_handle == NULL) - { - discord_log("discord: couldn't load " PATH_DISCORD_DLL "\n"); - discord_close(); + if (discord_handle == NULL) { + discord_log("discord: couldn't load " PATH_DISCORD_DLL "\n"); + discord_close(); - return(0); + return (0); } discord_loaded = 1; - return(1); + return (1); } void discord_init() { - enum EDiscordResult result; + enum EDiscordResult result; struct DiscordCreateParams params; - if(discord_handle == NULL) - return; + if (discord_handle == NULL) + return; DiscordCreateParamsSetDefault(¶ms); params.client_id = 906956844956782613; - params.flags = DiscordCreateFlags_NoRequireDiscord; + params.flags = DiscordCreateFlags_NoRequireDiscord; result = discord_create(DISCORD_VERSION, ¶ms, &discord_core); - if (result != DiscordResult_Ok) - { - discord_log("discord: DiscordCreate returned %d\n", result); - discord_close(); - return; + if (result != DiscordResult_Ok) { + discord_log("discord: DiscordCreate returned %d\n", result); + discord_close(); + return; } discord_activities = discord_core->get_activity_manager(discord_core); @@ -189,17 +180,17 @@ void discord_close() { if (discord_core != NULL) - discord_core->destroy(discord_core); + discord_core->destroy(discord_core); - discord_core = NULL; + discord_core = NULL; discord_activities = NULL; } void discord_run_callbacks() { - if(discord_core == NULL) - return; + if (discord_core == NULL) + return; discord_core->run_callbacks(discord_core); } diff --git a/src/disk/hdc_esdi_mca.c b/src/disk/hdc_esdi_mca.c index 9d2881294..e0859697f 100644 --- a/src/disk/hdc_esdi_mca.c +++ b/src/disk/hdc_esdi_mca.c @@ -86,8 +86,8 @@ #define ESDI_IOADDR_SEC 0x3518 #define ESDI_IRQCHAN 14 -#define BIOS_FILE_L "roms/hdd/esdi/62-000193-036.BIN" -#define BIOS_FILE_H "roms/hdd/esdi/62-000194-036.BIN" +#define BIOS_FILE_L "roms/hdd/esdi/90x8969.bin" +#define BIOS_FILE_H "roms/hdd/esdi/90x8970.bin" #define ESDI_TIME 512 @@ -133,7 +133,7 @@ typedef struct esdi_t { int command; int cmd_state; - int in_reset, in_reset2; + int in_reset; uint64_t callback; pc_timer_t timer; @@ -825,13 +825,6 @@ esdi_read(uint16_t port, void *priv) switch (port & 7) { case 2: /*Basic status register*/ - if (!dev->status) { - if (((dev->command == CMD_WRITE) || dev->in_reset2) && !dev->cmd_dev) { - dev->in_reset2 = 0; - dev->status |= STATUS_STATUS_OUT_FULL; - } else if (dev->command && (dev->cmd_dev == ATTN_HOST_ADAPTER)) - dev->status |= STATUS_STATUS_OUT_FULL; - } ret = dev->status; break; @@ -859,7 +852,6 @@ esdi_write(uint16_t port, uint8_t val, void *priv) case 2: /*Basic control register*/ if ((dev->basic_ctrl & CTRL_RESET) && !(val & CTRL_RESET)) { dev->in_reset = 1; - dev->in_reset2 = 1; esdi_mca_set_callback(dev, ESDI_TIME * 50); dev->status = STATUS_BUSY; } @@ -891,7 +883,6 @@ esdi_write(uint16_t port, uint8_t val, void *priv) case ATTN_RESET: dev->in_reset = 1; - dev->in_reset2 = 1; esdi_mca_set_callback(dev, ESDI_TIME * 50); dev->status = STATUS_BUSY; break; @@ -1152,7 +1143,6 @@ esdi_init(const device_t *info) /* Mark for a reset. */ dev->in_reset = 1; - dev->in_reset2 = 1; esdi_mca_set_callback(dev, ESDI_TIME * 50); dev->status = STATUS_BUSY; diff --git a/src/include/86box/vid_ega_render_remap.h b/src/include/86box/vid_ega_render_remap.h index 4ad64466c..b21233fbd 100644 --- a/src/include/86box/vid_ega_render_remap.h +++ b/src/include/86box/vid_ega_render_remap.h @@ -88,24 +88,24 @@ static uint32_t (*address_remap_funcs[16])(ega_t *ega, uint32_t in_addr) = void ega_recalc_remap_func(ega_t *ega) { - int func_nr; + int func_nr; - if (ega->crtc[0x14] & 0x40) - func_nr = VAR_DWORD_MODE; - else if (ega->crtc[0x17] & 0x40) - func_nr = VAR_BYTE_MODE; - else if (ega->crtc[0x17] & 0x20) - func_nr = VAR_WORD_MODE_MA15; - else - func_nr = VAR_WORD_MODE_MA13; + if (ega->crtc[0x14] & 0x40) + func_nr = VAR_DWORD_MODE; + else if (ega->crtc[0x17] & 0x40) + func_nr = VAR_BYTE_MODE; + else if (ega->crtc[0x17] & 0x20) + func_nr = VAR_WORD_MODE_MA15; + else + func_nr = VAR_WORD_MODE_MA13; - if (!(ega->crtc[0x17] & 0x01)) - func_nr |= VAR_ROW0_MA13; - if (!(ega->crtc[0x17] & 0x02)) - func_nr |= VAR_ROW1_MA14; + if (!(ega->crtc[0x17] & 0x01)) + func_nr |= VAR_ROW0_MA13; + if (!(ega->crtc[0x17] & 0x02)) + func_nr |= VAR_ROW1_MA14; - ega->remap_required = (func_nr != 0); - ega->remap_func = address_remap_funcs[func_nr]; + ega->remap_required = (func_nr != 0); + ega->remap_func = address_remap_funcs[func_nr]; } #endif /*VIDEO_RENDER_REMAP_H*/ diff --git a/src/include/discord_game_sdk.h b/src/include/discord_game_sdk.h index e3779a7cc..62ea8418e 100644 --- a/src/include/discord_game_sdk.h +++ b/src/include/discord_game_sdk.h @@ -8,6 +8,23 @@ #ifndef _DISCORD_GAME_SDK_H_ #define _DISCORD_GAME_SDK_H_ +#ifdef _WIN32 +#include +#include +#endif + +#ifdef _WIN32 +# ifdef _WIN64 +# define DISCORD_API +# else +# define DISCORD_API __stdcall +# endif +#else +# define DISCORD_API +#endif + +#define DISCORD_CALLBACK DISCORD_API + #ifdef __cplusplus extern "C" { #endif @@ -18,7 +35,7 @@ extern "C" { #include #endif -#define DISCORD_VERSION 2 +#define DISCORD_VERSION 3 #define DISCORD_APPLICATION_MANAGER_VERSION 1 #define DISCORD_USER_MANAGER_VERSION 1 #define DISCORD_IMAGE_MANAGER_VERSION 1 @@ -26,7 +43,7 @@ extern "C" { #define DISCORD_RELATIONSHIP_MANAGER_VERSION 1 #define DISCORD_LOBBY_MANAGER_VERSION 1 #define DISCORD_NETWORK_MANAGER_VERSION 1 -#define DISCORD_OVERLAY_MANAGER_VERSION 1 +#define DISCORD_OVERLAY_MANAGER_VERSION 2 #define DISCORD_STORAGE_MANAGER_VERSION 1 #define DISCORD_STORE_MANAGER_VERSION 1 #define DISCORD_VOICE_MANAGER_VERSION 1 @@ -77,6 +94,7 @@ enum EDiscordResult { DiscordResult_InvalidGiftCode = 41, DiscordResult_PurchaseError = 42, DiscordResult_TransactionAborted = 43, + DiscordResult_DrawingInitFailed = 44, }; enum EDiscordCreateFlags { @@ -109,6 +127,11 @@ enum EDiscordImageType { DiscordImageType_User, }; +enum EDiscordActivityPartyPrivacy { + DiscordActivityPartyPrivacy_Private = 0, + DiscordActivityPartyPrivacy_Public = 1, +}; + enum EDiscordActivityType { DiscordActivityType_Playing, DiscordActivityType_Streaming, @@ -121,6 +144,12 @@ enum EDiscordActivityActionType { DiscordActivityActionType_Spectate, }; +enum EDiscordActivitySupportedPlatformFlags { + DiscordActivitySupportedPlatformFlags_Desktop = 1, + DiscordActivitySupportedPlatformFlags_Android = 2, + DiscordActivitySupportedPlatformFlags_iOS = 4, +}; + enum EDiscordActivityJoinRequestReply { DiscordActivityJoinRequestReply_No, DiscordActivityJoinRequestReply_Yes, @@ -169,6 +198,18 @@ enum EDiscordLobbySearchDistance { DiscordLobbySearchDistance_Global, }; +enum EDiscordKeyVariant { + DiscordKeyVariant_Normal, + DiscordKeyVariant_Right, + DiscordKeyVariant_Left, +}; + +enum EDiscordMouseButton { + DiscordMouseButton_Left, + DiscordMouseButton_Middle, + DiscordMouseButton_Right, +}; + enum EDiscordEntitlementType { DiscordEntitlementType_Purchase = 1, DiscordEntitlementType_PremiumSubscription, @@ -204,6 +245,18 @@ typedef char DiscordMetadataKey[256]; typedef char DiscordMetadataValue[4096]; typedef uint64_t DiscordNetworkPeerId; typedef uint8_t DiscordNetworkChannelId; +#ifdef __APPLE__ +typedef void IDXGISwapChain; +#endif +#ifdef __linux__ +typedef void IDXGISwapChain; +#endif +#ifdef __APPLE__ +typedef void MSG; +#endif +#ifdef __linux__ +typedef void MSG; +#endif typedef char DiscordPath[4096]; typedef char DiscordDateTime[64]; @@ -252,6 +305,7 @@ struct DiscordPartySize { struct DiscordActivityParty { char id[128]; struct DiscordPartySize size; + enum EDiscordActivityPartyPrivacy privacy; }; struct DiscordActivitySecrets { @@ -271,6 +325,7 @@ struct DiscordActivity { struct DiscordActivityParty party; struct DiscordActivitySecrets secrets; bool instance; + uint32_t supported_platforms; }; struct DiscordPresence { @@ -293,6 +348,21 @@ struct DiscordLobby { bool locked; }; +struct DiscordImeUnderline { + int32_t from; + int32_t to; + uint32_t color; + uint32_t background_color; + bool thick; +}; + +struct DiscordRect { + int32_t left; + int32_t top; + int32_t right; + int32_t bottom; +}; + struct DiscordFileStat { char filename[260]; uint64_t size; @@ -330,265 +400,278 @@ struct DiscordUserAchievement { }; struct IDiscordLobbyTransaction { - enum EDiscordResult (*set_type)(struct IDiscordLobbyTransaction* lobby_transaction, enum EDiscordLobbyType type); - enum EDiscordResult (*set_owner)(struct IDiscordLobbyTransaction* lobby_transaction, DiscordUserId owner_id); - enum EDiscordResult (*set_capacity)(struct IDiscordLobbyTransaction* lobby_transaction, uint32_t capacity); - enum EDiscordResult (*set_metadata)(struct IDiscordLobbyTransaction* lobby_transaction, DiscordMetadataKey key, DiscordMetadataValue value); - enum EDiscordResult (*delete_metadata)(struct IDiscordLobbyTransaction* lobby_transaction, DiscordMetadataKey key); - enum EDiscordResult (*set_locked)(struct IDiscordLobbyTransaction* lobby_transaction, bool locked); + enum EDiscordResult (DISCORD_API *set_type)(struct IDiscordLobbyTransaction* lobby_transaction, enum EDiscordLobbyType type); + enum EDiscordResult (DISCORD_API *set_owner)(struct IDiscordLobbyTransaction* lobby_transaction, DiscordUserId owner_id); + enum EDiscordResult (DISCORD_API *set_capacity)(struct IDiscordLobbyTransaction* lobby_transaction, uint32_t capacity); + enum EDiscordResult (DISCORD_API *set_metadata)(struct IDiscordLobbyTransaction* lobby_transaction, DiscordMetadataKey key, DiscordMetadataValue value); + enum EDiscordResult (DISCORD_API *delete_metadata)(struct IDiscordLobbyTransaction* lobby_transaction, DiscordMetadataKey key); + enum EDiscordResult (DISCORD_API *set_locked)(struct IDiscordLobbyTransaction* lobby_transaction, bool locked); }; struct IDiscordLobbyMemberTransaction { - enum EDiscordResult (*set_metadata)(struct IDiscordLobbyMemberTransaction* lobby_member_transaction, DiscordMetadataKey key, DiscordMetadataValue value); - enum EDiscordResult (*delete_metadata)(struct IDiscordLobbyMemberTransaction* lobby_member_transaction, DiscordMetadataKey key); + enum EDiscordResult (DISCORD_API *set_metadata)(struct IDiscordLobbyMemberTransaction* lobby_member_transaction, DiscordMetadataKey key, DiscordMetadataValue value); + enum EDiscordResult (DISCORD_API *delete_metadata)(struct IDiscordLobbyMemberTransaction* lobby_member_transaction, DiscordMetadataKey key); }; struct IDiscordLobbySearchQuery { - enum EDiscordResult (*filter)(struct IDiscordLobbySearchQuery* lobby_search_query, DiscordMetadataKey key, enum EDiscordLobbySearchComparison comparison, enum EDiscordLobbySearchCast cast, DiscordMetadataValue value); - enum EDiscordResult (*sort)(struct IDiscordLobbySearchQuery* lobby_search_query, DiscordMetadataKey key, enum EDiscordLobbySearchCast cast, DiscordMetadataValue value); - enum EDiscordResult (*limit)(struct IDiscordLobbySearchQuery* lobby_search_query, uint32_t limit); - enum EDiscordResult (*distance)(struct IDiscordLobbySearchQuery* lobby_search_query, enum EDiscordLobbySearchDistance distance); + enum EDiscordResult (DISCORD_API *filter)(struct IDiscordLobbySearchQuery* lobby_search_query, DiscordMetadataKey key, enum EDiscordLobbySearchComparison comparison, enum EDiscordLobbySearchCast cast, DiscordMetadataValue value); + enum EDiscordResult (DISCORD_API *sort)(struct IDiscordLobbySearchQuery* lobby_search_query, DiscordMetadataKey key, enum EDiscordLobbySearchCast cast, DiscordMetadataValue value); + enum EDiscordResult (DISCORD_API *limit)(struct IDiscordLobbySearchQuery* lobby_search_query, uint32_t limit); + enum EDiscordResult (DISCORD_API *distance)(struct IDiscordLobbySearchQuery* lobby_search_query, enum EDiscordLobbySearchDistance distance); }; typedef void* IDiscordApplicationEvents; struct IDiscordApplicationManager { - void (*validate_or_exit)(struct IDiscordApplicationManager* manager, void* callback_data, void (*callback)(void* callback_data, enum EDiscordResult result)); - void (*get_current_locale)(struct IDiscordApplicationManager* manager, DiscordLocale* locale); - void (*get_current_branch)(struct IDiscordApplicationManager* manager, DiscordBranch* branch); - void (*get_oauth2_token)(struct IDiscordApplicationManager* manager, void* callback_data, void (*callback)(void* callback_data, enum EDiscordResult result, struct DiscordOAuth2Token* oauth2_token)); - void (*get_ticket)(struct IDiscordApplicationManager* manager, void* callback_data, void (*callback)(void* callback_data, enum EDiscordResult result, const char* data)); + void (DISCORD_API *validate_or_exit)(struct IDiscordApplicationManager* manager, void* callback_data, void (DISCORD_API *callback)(void* callback_data, enum EDiscordResult result)); + void (DISCORD_API *get_current_locale)(struct IDiscordApplicationManager* manager, DiscordLocale* locale); + void (DISCORD_API *get_current_branch)(struct IDiscordApplicationManager* manager, DiscordBranch* branch); + void (DISCORD_API *get_oauth2_token)(struct IDiscordApplicationManager* manager, void* callback_data, void (DISCORD_API *callback)(void* callback_data, enum EDiscordResult result, struct DiscordOAuth2Token* oauth2_token)); + void (DISCORD_API *get_ticket)(struct IDiscordApplicationManager* manager, void* callback_data, void (DISCORD_API *callback)(void* callback_data, enum EDiscordResult result, const char* data)); }; struct IDiscordUserEvents { - void (*on_current_user_update)(void* event_data); + void (DISCORD_API *on_current_user_update)(void* event_data); }; struct IDiscordUserManager { - enum EDiscordResult (*get_current_user)(struct IDiscordUserManager* manager, struct DiscordUser* current_user); - void (*get_user)(struct IDiscordUserManager* manager, DiscordUserId user_id, void* callback_data, void (*callback)(void* callback_data, enum EDiscordResult result, struct DiscordUser* user)); - enum EDiscordResult (*get_current_user_premium_type)(struct IDiscordUserManager* manager, enum EDiscordPremiumType* premium_type); - enum EDiscordResult (*current_user_has_flag)(struct IDiscordUserManager* manager, enum EDiscordUserFlag flag, bool* has_flag); + enum EDiscordResult (DISCORD_API *get_current_user)(struct IDiscordUserManager* manager, struct DiscordUser* current_user); + void (DISCORD_API *get_user)(struct IDiscordUserManager* manager, DiscordUserId user_id, void* callback_data, void (DISCORD_API *callback)(void* callback_data, enum EDiscordResult result, struct DiscordUser* user)); + enum EDiscordResult (DISCORD_API *get_current_user_premium_type)(struct IDiscordUserManager* manager, enum EDiscordPremiumType* premium_type); + enum EDiscordResult (DISCORD_API *current_user_has_flag)(struct IDiscordUserManager* manager, enum EDiscordUserFlag flag, bool* has_flag); }; typedef void* IDiscordImageEvents; struct IDiscordImageManager { - void (*fetch)(struct IDiscordImageManager* manager, struct DiscordImageHandle handle, bool refresh, void* callback_data, void (*callback)(void* callback_data, enum EDiscordResult result, struct DiscordImageHandle handle_result)); - enum EDiscordResult (*get_dimensions)(struct IDiscordImageManager* manager, struct DiscordImageHandle handle, struct DiscordImageDimensions* dimensions); - enum EDiscordResult (*get_data)(struct IDiscordImageManager* manager, struct DiscordImageHandle handle, uint8_t* data, uint32_t data_length); + void (DISCORD_API *fetch)(struct IDiscordImageManager* manager, struct DiscordImageHandle handle, bool refresh, void* callback_data, void (DISCORD_API *callback)(void* callback_data, enum EDiscordResult result, struct DiscordImageHandle handle_result)); + enum EDiscordResult (DISCORD_API *get_dimensions)(struct IDiscordImageManager* manager, struct DiscordImageHandle handle, struct DiscordImageDimensions* dimensions); + enum EDiscordResult (DISCORD_API *get_data)(struct IDiscordImageManager* manager, struct DiscordImageHandle handle, uint8_t* data, uint32_t data_length); }; struct IDiscordActivityEvents { - void (*on_activity_join)(void* event_data, const char* secret); - void (*on_activity_spectate)(void* event_data, const char* secret); - void (*on_activity_join_request)(void* event_data, struct DiscordUser* user); - void (*on_activity_invite)(void* event_data, enum EDiscordActivityActionType type, struct DiscordUser* user, struct DiscordActivity* activity); + void (DISCORD_API *on_activity_join)(void* event_data, const char* secret); + void (DISCORD_API *on_activity_spectate)(void* event_data, const char* secret); + void (DISCORD_API *on_activity_join_request)(void* event_data, struct DiscordUser* user); + void (DISCORD_API *on_activity_invite)(void* event_data, enum EDiscordActivityActionType type, struct DiscordUser* user, struct DiscordActivity* activity); }; struct IDiscordActivityManager { - enum EDiscordResult (*register_command)(struct IDiscordActivityManager* manager, const char* command); - enum EDiscordResult (*register_steam)(struct IDiscordActivityManager* manager, uint32_t steam_id); - void (*update_activity)(struct IDiscordActivityManager* manager, struct DiscordActivity* activity, void* callback_data, void (*callback)(void* callback_data, enum EDiscordResult result)); - void (*clear_activity)(struct IDiscordActivityManager* manager, void* callback_data, void (*callback)(void* callback_data, enum EDiscordResult result)); - void (*send_request_reply)(struct IDiscordActivityManager* manager, DiscordUserId user_id, enum EDiscordActivityJoinRequestReply reply, void* callback_data, void (*callback)(void* callback_data, enum EDiscordResult result)); - void (*send_invite)(struct IDiscordActivityManager* manager, DiscordUserId user_id, enum EDiscordActivityActionType type, const char* content, void* callback_data, void (*callback)(void* callback_data, enum EDiscordResult result)); - void (*accept_invite)(struct IDiscordActivityManager* manager, DiscordUserId user_id, void* callback_data, void (*callback)(void* callback_data, enum EDiscordResult result)); + enum EDiscordResult (DISCORD_API *register_command)(struct IDiscordActivityManager* manager, const char* command); + enum EDiscordResult (DISCORD_API *register_steam)(struct IDiscordActivityManager* manager, uint32_t steam_id); + void (DISCORD_API *update_activity)(struct IDiscordActivityManager* manager, struct DiscordActivity* activity, void* callback_data, void (DISCORD_API *callback)(void* callback_data, enum EDiscordResult result)); + void (DISCORD_API *clear_activity)(struct IDiscordActivityManager* manager, void* callback_data, void (DISCORD_API *callback)(void* callback_data, enum EDiscordResult result)); + void (DISCORD_API *send_request_reply)(struct IDiscordActivityManager* manager, DiscordUserId user_id, enum EDiscordActivityJoinRequestReply reply, void* callback_data, void (DISCORD_API *callback)(void* callback_data, enum EDiscordResult result)); + void (DISCORD_API *send_invite)(struct IDiscordActivityManager* manager, DiscordUserId user_id, enum EDiscordActivityActionType type, const char* content, void* callback_data, void (DISCORD_API *callback)(void* callback_data, enum EDiscordResult result)); + void (DISCORD_API *accept_invite)(struct IDiscordActivityManager* manager, DiscordUserId user_id, void* callback_data, void (DISCORD_API *callback)(void* callback_data, enum EDiscordResult result)); }; struct IDiscordRelationshipEvents { - void (*on_refresh)(void* event_data); - void (*on_relationship_update)(void* event_data, struct DiscordRelationship* relationship); + void (DISCORD_API *on_refresh)(void* event_data); + void (DISCORD_API *on_relationship_update)(void* event_data, struct DiscordRelationship* relationship); }; struct IDiscordRelationshipManager { - void (*filter)(struct IDiscordRelationshipManager* manager, void* filter_data, bool (*filter)(void* filter_data, struct DiscordRelationship* relationship)); - enum EDiscordResult (*count)(struct IDiscordRelationshipManager* manager, int32_t* count); - enum EDiscordResult (*get)(struct IDiscordRelationshipManager* manager, DiscordUserId user_id, struct DiscordRelationship* relationship); - enum EDiscordResult (*get_at)(struct IDiscordRelationshipManager* manager, uint32_t index, struct DiscordRelationship* relationship); + void (DISCORD_API *filter)(struct IDiscordRelationshipManager* manager, void* filter_data, bool (DISCORD_API *filter)(void* filter_data, struct DiscordRelationship* relationship)); + enum EDiscordResult (DISCORD_API *count)(struct IDiscordRelationshipManager* manager, int32_t* count); + enum EDiscordResult (DISCORD_API *get)(struct IDiscordRelationshipManager* manager, DiscordUserId user_id, struct DiscordRelationship* relationship); + enum EDiscordResult (DISCORD_API *get_at)(struct IDiscordRelationshipManager* manager, uint32_t index, struct DiscordRelationship* relationship); }; struct IDiscordLobbyEvents { - void (*on_lobby_update)(void* event_data, int64_t lobby_id); - void (*on_lobby_delete)(void* event_data, int64_t lobby_id, uint32_t reason); - void (*on_member_connect)(void* event_data, int64_t lobby_id, int64_t user_id); - void (*on_member_update)(void* event_data, int64_t lobby_id, int64_t user_id); - void (*on_member_disconnect)(void* event_data, int64_t lobby_id, int64_t user_id); - void (*on_lobby_message)(void* event_data, int64_t lobby_id, int64_t user_id, uint8_t* data, uint32_t data_length); - void (*on_speaking)(void* event_data, int64_t lobby_id, int64_t user_id, bool speaking); - void (*on_network_message)(void* event_data, int64_t lobby_id, int64_t user_id, uint8_t channel_id, uint8_t* data, uint32_t data_length); + void (DISCORD_API *on_lobby_update)(void* event_data, int64_t lobby_id); + void (DISCORD_API *on_lobby_delete)(void* event_data, int64_t lobby_id, uint32_t reason); + void (DISCORD_API *on_member_connect)(void* event_data, int64_t lobby_id, int64_t user_id); + void (DISCORD_API *on_member_update)(void* event_data, int64_t lobby_id, int64_t user_id); + void (DISCORD_API *on_member_disconnect)(void* event_data, int64_t lobby_id, int64_t user_id); + void (DISCORD_API *on_lobby_message)(void* event_data, int64_t lobby_id, int64_t user_id, uint8_t* data, uint32_t data_length); + void (DISCORD_API *on_speaking)(void* event_data, int64_t lobby_id, int64_t user_id, bool speaking); + void (DISCORD_API *on_network_message)(void* event_data, int64_t lobby_id, int64_t user_id, uint8_t channel_id, uint8_t* data, uint32_t data_length); }; struct IDiscordLobbyManager { - enum EDiscordResult (*get_lobby_create_transaction)(struct IDiscordLobbyManager* manager, struct IDiscordLobbyTransaction** transaction); - enum EDiscordResult (*get_lobby_update_transaction)(struct IDiscordLobbyManager* manager, DiscordLobbyId lobby_id, struct IDiscordLobbyTransaction** transaction); - enum EDiscordResult (*get_member_update_transaction)(struct IDiscordLobbyManager* manager, DiscordLobbyId lobby_id, DiscordUserId user_id, struct IDiscordLobbyMemberTransaction** transaction); - void (*create_lobby)(struct IDiscordLobbyManager* manager, struct IDiscordLobbyTransaction* transaction, void* callback_data, void (*callback)(void* callback_data, enum EDiscordResult result, struct DiscordLobby* lobby)); - void (*update_lobby)(struct IDiscordLobbyManager* manager, DiscordLobbyId lobby_id, struct IDiscordLobbyTransaction* transaction, void* callback_data, void (*callback)(void* callback_data, enum EDiscordResult result)); - void (*delete_lobby)(struct IDiscordLobbyManager* manager, DiscordLobbyId lobby_id, void* callback_data, void (*callback)(void* callback_data, enum EDiscordResult result)); - void (*connect_lobby)(struct IDiscordLobbyManager* manager, DiscordLobbyId lobby_id, DiscordLobbySecret secret, void* callback_data, void (*callback)(void* callback_data, enum EDiscordResult result, struct DiscordLobby* lobby)); - void (*connect_lobby_with_activity_secret)(struct IDiscordLobbyManager* manager, DiscordLobbySecret activity_secret, void* callback_data, void (*callback)(void* callback_data, enum EDiscordResult result, struct DiscordLobby* lobby)); - void (*disconnect_lobby)(struct IDiscordLobbyManager* manager, DiscordLobbyId lobby_id, void* callback_data, void (*callback)(void* callback_data, enum EDiscordResult result)); - enum EDiscordResult (*get_lobby)(struct IDiscordLobbyManager* manager, DiscordLobbyId lobby_id, struct DiscordLobby* lobby); - enum EDiscordResult (*get_lobby_activity_secret)(struct IDiscordLobbyManager* manager, DiscordLobbyId lobby_id, DiscordLobbySecret* secret); - enum EDiscordResult (*get_lobby_metadata_value)(struct IDiscordLobbyManager* manager, DiscordLobbyId lobby_id, DiscordMetadataKey key, DiscordMetadataValue* value); - enum EDiscordResult (*get_lobby_metadata_key)(struct IDiscordLobbyManager* manager, DiscordLobbyId lobby_id, int32_t index, DiscordMetadataKey* key); - enum EDiscordResult (*lobby_metadata_count)(struct IDiscordLobbyManager* manager, DiscordLobbyId lobby_id, int32_t* count); - enum EDiscordResult (*member_count)(struct IDiscordLobbyManager* manager, DiscordLobbyId lobby_id, int32_t* count); - enum EDiscordResult (*get_member_user_id)(struct IDiscordLobbyManager* manager, DiscordLobbyId lobby_id, int32_t index, DiscordUserId* user_id); - enum EDiscordResult (*get_member_user)(struct IDiscordLobbyManager* manager, DiscordLobbyId lobby_id, DiscordUserId user_id, struct DiscordUser* user); - enum EDiscordResult (*get_member_metadata_value)(struct IDiscordLobbyManager* manager, DiscordLobbyId lobby_id, DiscordUserId user_id, DiscordMetadataKey key, DiscordMetadataValue* value); - enum EDiscordResult (*get_member_metadata_key)(struct IDiscordLobbyManager* manager, DiscordLobbyId lobby_id, DiscordUserId user_id, int32_t index, DiscordMetadataKey* key); - enum EDiscordResult (*member_metadata_count)(struct IDiscordLobbyManager* manager, DiscordLobbyId lobby_id, DiscordUserId user_id, int32_t* count); - void (*update_member)(struct IDiscordLobbyManager* manager, DiscordLobbyId lobby_id, DiscordUserId user_id, struct IDiscordLobbyMemberTransaction* transaction, void* callback_data, void (*callback)(void* callback_data, enum EDiscordResult result)); - void (*send_lobby_message)(struct IDiscordLobbyManager* manager, DiscordLobbyId lobby_id, uint8_t* data, uint32_t data_length, void* callback_data, void (*callback)(void* callback_data, enum EDiscordResult result)); - enum EDiscordResult (*get_search_query)(struct IDiscordLobbyManager* manager, struct IDiscordLobbySearchQuery** query); - void (*search)(struct IDiscordLobbyManager* manager, struct IDiscordLobbySearchQuery* query, void* callback_data, void (*callback)(void* callback_data, enum EDiscordResult result)); - void (*lobby_count)(struct IDiscordLobbyManager* manager, int32_t* count); - enum EDiscordResult (*get_lobby_id)(struct IDiscordLobbyManager* manager, int32_t index, DiscordLobbyId* lobby_id); - void (*connect_voice)(struct IDiscordLobbyManager* manager, DiscordLobbyId lobby_id, void* callback_data, void (*callback)(void* callback_data, enum EDiscordResult result)); - void (*disconnect_voice)(struct IDiscordLobbyManager* manager, DiscordLobbyId lobby_id, void* callback_data, void (*callback)(void* callback_data, enum EDiscordResult result)); - enum EDiscordResult (*connect_network)(struct IDiscordLobbyManager* manager, DiscordLobbyId lobby_id); - enum EDiscordResult (*disconnect_network)(struct IDiscordLobbyManager* manager, DiscordLobbyId lobby_id); - enum EDiscordResult (*flush_network)(struct IDiscordLobbyManager* manager); - enum EDiscordResult (*open_network_channel)(struct IDiscordLobbyManager* manager, DiscordLobbyId lobby_id, uint8_t channel_id, bool reliable); - enum EDiscordResult (*send_network_message)(struct IDiscordLobbyManager* manager, DiscordLobbyId lobby_id, DiscordUserId user_id, uint8_t channel_id, uint8_t* data, uint32_t data_length); + enum EDiscordResult (DISCORD_API *get_lobby_create_transaction)(struct IDiscordLobbyManager* manager, struct IDiscordLobbyTransaction** transaction); + enum EDiscordResult (DISCORD_API *get_lobby_update_transaction)(struct IDiscordLobbyManager* manager, DiscordLobbyId lobby_id, struct IDiscordLobbyTransaction** transaction); + enum EDiscordResult (DISCORD_API *get_member_update_transaction)(struct IDiscordLobbyManager* manager, DiscordLobbyId lobby_id, DiscordUserId user_id, struct IDiscordLobbyMemberTransaction** transaction); + void (DISCORD_API *create_lobby)(struct IDiscordLobbyManager* manager, struct IDiscordLobbyTransaction* transaction, void* callback_data, void (DISCORD_API *callback)(void* callback_data, enum EDiscordResult result, struct DiscordLobby* lobby)); + void (DISCORD_API *update_lobby)(struct IDiscordLobbyManager* manager, DiscordLobbyId lobby_id, struct IDiscordLobbyTransaction* transaction, void* callback_data, void (DISCORD_API *callback)(void* callback_data, enum EDiscordResult result)); + void (DISCORD_API *delete_lobby)(struct IDiscordLobbyManager* manager, DiscordLobbyId lobby_id, void* callback_data, void (DISCORD_API *callback)(void* callback_data, enum EDiscordResult result)); + void (DISCORD_API *connect_lobby)(struct IDiscordLobbyManager* manager, DiscordLobbyId lobby_id, DiscordLobbySecret secret, void* callback_data, void (DISCORD_API *callback)(void* callback_data, enum EDiscordResult result, struct DiscordLobby* lobby)); + void (DISCORD_API *connect_lobby_with_activity_secret)(struct IDiscordLobbyManager* manager, DiscordLobbySecret activity_secret, void* callback_data, void (DISCORD_API *callback)(void* callback_data, enum EDiscordResult result, struct DiscordLobby* lobby)); + void (DISCORD_API *disconnect_lobby)(struct IDiscordLobbyManager* manager, DiscordLobbyId lobby_id, void* callback_data, void (DISCORD_API *callback)(void* callback_data, enum EDiscordResult result)); + enum EDiscordResult (DISCORD_API *get_lobby)(struct IDiscordLobbyManager* manager, DiscordLobbyId lobby_id, struct DiscordLobby* lobby); + enum EDiscordResult (DISCORD_API *get_lobby_activity_secret)(struct IDiscordLobbyManager* manager, DiscordLobbyId lobby_id, DiscordLobbySecret* secret); + enum EDiscordResult (DISCORD_API *get_lobby_metadata_value)(struct IDiscordLobbyManager* manager, DiscordLobbyId lobby_id, DiscordMetadataKey key, DiscordMetadataValue* value); + enum EDiscordResult (DISCORD_API *get_lobby_metadata_key)(struct IDiscordLobbyManager* manager, DiscordLobbyId lobby_id, int32_t index, DiscordMetadataKey* key); + enum EDiscordResult (DISCORD_API *lobby_metadata_count)(struct IDiscordLobbyManager* manager, DiscordLobbyId lobby_id, int32_t* count); + enum EDiscordResult (DISCORD_API *member_count)(struct IDiscordLobbyManager* manager, DiscordLobbyId lobby_id, int32_t* count); + enum EDiscordResult (DISCORD_API *get_member_user_id)(struct IDiscordLobbyManager* manager, DiscordLobbyId lobby_id, int32_t index, DiscordUserId* user_id); + enum EDiscordResult (DISCORD_API *get_member_user)(struct IDiscordLobbyManager* manager, DiscordLobbyId lobby_id, DiscordUserId user_id, struct DiscordUser* user); + enum EDiscordResult (DISCORD_API *get_member_metadata_value)(struct IDiscordLobbyManager* manager, DiscordLobbyId lobby_id, DiscordUserId user_id, DiscordMetadataKey key, DiscordMetadataValue* value); + enum EDiscordResult (DISCORD_API *get_member_metadata_key)(struct IDiscordLobbyManager* manager, DiscordLobbyId lobby_id, DiscordUserId user_id, int32_t index, DiscordMetadataKey* key); + enum EDiscordResult (DISCORD_API *member_metadata_count)(struct IDiscordLobbyManager* manager, DiscordLobbyId lobby_id, DiscordUserId user_id, int32_t* count); + void (DISCORD_API *update_member)(struct IDiscordLobbyManager* manager, DiscordLobbyId lobby_id, DiscordUserId user_id, struct IDiscordLobbyMemberTransaction* transaction, void* callback_data, void (DISCORD_API *callback)(void* callback_data, enum EDiscordResult result)); + void (DISCORD_API *send_lobby_message)(struct IDiscordLobbyManager* manager, DiscordLobbyId lobby_id, uint8_t* data, uint32_t data_length, void* callback_data, void (DISCORD_API *callback)(void* callback_data, enum EDiscordResult result)); + enum EDiscordResult (DISCORD_API *get_search_query)(struct IDiscordLobbyManager* manager, struct IDiscordLobbySearchQuery** query); + void (DISCORD_API *search)(struct IDiscordLobbyManager* manager, struct IDiscordLobbySearchQuery* query, void* callback_data, void (DISCORD_API *callback)(void* callback_data, enum EDiscordResult result)); + void (DISCORD_API *lobby_count)(struct IDiscordLobbyManager* manager, int32_t* count); + enum EDiscordResult (DISCORD_API *get_lobby_id)(struct IDiscordLobbyManager* manager, int32_t index, DiscordLobbyId* lobby_id); + void (DISCORD_API *connect_voice)(struct IDiscordLobbyManager* manager, DiscordLobbyId lobby_id, void* callback_data, void (DISCORD_API *callback)(void* callback_data, enum EDiscordResult result)); + void (DISCORD_API *disconnect_voice)(struct IDiscordLobbyManager* manager, DiscordLobbyId lobby_id, void* callback_data, void (DISCORD_API *callback)(void* callback_data, enum EDiscordResult result)); + enum EDiscordResult (DISCORD_API *connect_network)(struct IDiscordLobbyManager* manager, DiscordLobbyId lobby_id); + enum EDiscordResult (DISCORD_API *disconnect_network)(struct IDiscordLobbyManager* manager, DiscordLobbyId lobby_id); + enum EDiscordResult (DISCORD_API *flush_network)(struct IDiscordLobbyManager* manager); + enum EDiscordResult (DISCORD_API *open_network_channel)(struct IDiscordLobbyManager* manager, DiscordLobbyId lobby_id, uint8_t channel_id, bool reliable); + enum EDiscordResult (DISCORD_API *send_network_message)(struct IDiscordLobbyManager* manager, DiscordLobbyId lobby_id, DiscordUserId user_id, uint8_t channel_id, uint8_t* data, uint32_t data_length); }; struct IDiscordNetworkEvents { - void (*on_message)(void* event_data, DiscordNetworkPeerId peer_id, DiscordNetworkChannelId channel_id, uint8_t* data, uint32_t data_length); - void (*on_route_update)(void* event_data, const char* route_data); + void (DISCORD_API *on_message)(void* event_data, DiscordNetworkPeerId peer_id, DiscordNetworkChannelId channel_id, uint8_t* data, uint32_t data_length); + void (DISCORD_API *on_route_update)(void* event_data, const char* route_data); }; struct IDiscordNetworkManager { /** * Get the local peer ID for this process. */ - void (*get_peer_id)(struct IDiscordNetworkManager* manager, DiscordNetworkPeerId* peer_id); + void (DISCORD_API *get_peer_id)(struct IDiscordNetworkManager* manager, DiscordNetworkPeerId* peer_id); /** * Send pending network messages. */ - enum EDiscordResult (*flush)(struct IDiscordNetworkManager* manager); + enum EDiscordResult (DISCORD_API *flush)(struct IDiscordNetworkManager* manager); /** * Open a connection to a remote peer. */ - enum EDiscordResult (*open_peer)(struct IDiscordNetworkManager* manager, DiscordNetworkPeerId peer_id, const char* route_data); + enum EDiscordResult (DISCORD_API *open_peer)(struct IDiscordNetworkManager* manager, DiscordNetworkPeerId peer_id, const char* route_data); /** * Update the route data for a connected peer. */ - enum EDiscordResult (*update_peer)(struct IDiscordNetworkManager* manager, DiscordNetworkPeerId peer_id, const char* route_data); + enum EDiscordResult (DISCORD_API *update_peer)(struct IDiscordNetworkManager* manager, DiscordNetworkPeerId peer_id, const char* route_data); /** * Close the connection to a remote peer. */ - enum EDiscordResult (*close_peer)(struct IDiscordNetworkManager* manager, DiscordNetworkPeerId peer_id); + enum EDiscordResult (DISCORD_API *close_peer)(struct IDiscordNetworkManager* manager, DiscordNetworkPeerId peer_id); /** * Open a message channel to a connected peer. */ - enum EDiscordResult (*open_channel)(struct IDiscordNetworkManager* manager, DiscordNetworkPeerId peer_id, DiscordNetworkChannelId channel_id, bool reliable); + enum EDiscordResult (DISCORD_API *open_channel)(struct IDiscordNetworkManager* manager, DiscordNetworkPeerId peer_id, DiscordNetworkChannelId channel_id, bool reliable); /** * Close a message channel to a connected peer. */ - enum EDiscordResult (*close_channel)(struct IDiscordNetworkManager* manager, DiscordNetworkPeerId peer_id, DiscordNetworkChannelId channel_id); + enum EDiscordResult (DISCORD_API *close_channel)(struct IDiscordNetworkManager* manager, DiscordNetworkPeerId peer_id, DiscordNetworkChannelId channel_id); /** * Send a message to a connected peer over an opened message channel. */ - enum EDiscordResult (*send_message)(struct IDiscordNetworkManager* manager, DiscordNetworkPeerId peer_id, DiscordNetworkChannelId channel_id, uint8_t* data, uint32_t data_length); + enum EDiscordResult (DISCORD_API *send_message)(struct IDiscordNetworkManager* manager, DiscordNetworkPeerId peer_id, DiscordNetworkChannelId channel_id, uint8_t* data, uint32_t data_length); }; struct IDiscordOverlayEvents { - void (*on_toggle)(void* event_data, bool locked); + void (DISCORD_API *on_toggle)(void* event_data, bool locked); }; struct IDiscordOverlayManager { - void (*is_enabled)(struct IDiscordOverlayManager* manager, bool* enabled); - void (*is_locked)(struct IDiscordOverlayManager* manager, bool* locked); - void (*set_locked)(struct IDiscordOverlayManager* manager, bool locked, void* callback_data, void (*callback)(void* callback_data, enum EDiscordResult result)); - void (*open_activity_invite)(struct IDiscordOverlayManager* manager, enum EDiscordActivityActionType type, void* callback_data, void (*callback)(void* callback_data, enum EDiscordResult result)); - void (*open_guild_invite)(struct IDiscordOverlayManager* manager, const char* code, void* callback_data, void (*callback)(void* callback_data, enum EDiscordResult result)); - void (*open_voice_settings)(struct IDiscordOverlayManager* manager, void* callback_data, void (*callback)(void* callback_data, enum EDiscordResult result)); + void (DISCORD_API *is_enabled)(struct IDiscordOverlayManager* manager, bool* enabled); + void (DISCORD_API *is_locked)(struct IDiscordOverlayManager* manager, bool* locked); + void (DISCORD_API *set_locked)(struct IDiscordOverlayManager* manager, bool locked, void* callback_data, void (DISCORD_API *callback)(void* callback_data, enum EDiscordResult result)); + void (DISCORD_API *open_activity_invite)(struct IDiscordOverlayManager* manager, enum EDiscordActivityActionType type, void* callback_data, void (DISCORD_API *callback)(void* callback_data, enum EDiscordResult result)); + void (DISCORD_API *open_guild_invite)(struct IDiscordOverlayManager* manager, const char* code, void* callback_data, void (DISCORD_API *callback)(void* callback_data, enum EDiscordResult result)); + void (DISCORD_API *open_voice_settings)(struct IDiscordOverlayManager* manager, void* callback_data, void (DISCORD_API *callback)(void* callback_data, enum EDiscordResult result)); + enum EDiscordResult (DISCORD_API *init_drawing_dxgi)(struct IDiscordOverlayManager* manager, IDXGISwapChain* swapchain, bool use_message_forwarding); + void (DISCORD_API *on_present)(struct IDiscordOverlayManager* manager); + void (DISCORD_API *forward_message)(struct IDiscordOverlayManager* manager, MSG* message); + void (DISCORD_API *key_event)(struct IDiscordOverlayManager* manager, bool down, const char* key_code, enum EDiscordKeyVariant variant); + void (DISCORD_API *char_event)(struct IDiscordOverlayManager* manager, const char* character); + void (DISCORD_API *mouse_button_event)(struct IDiscordOverlayManager* manager, uint8_t down, int32_t click_count, enum EDiscordMouseButton which, int32_t x, int32_t y); + void (DISCORD_API *mouse_motion_event)(struct IDiscordOverlayManager* manager, int32_t x, int32_t y); + void (DISCORD_API *ime_commit_text)(struct IDiscordOverlayManager* manager, const char* text); + void (DISCORD_API *ime_set_composition)(struct IDiscordOverlayManager* manager, const char* text, struct DiscordImeUnderline* underlines, uint32_t underlines_length, int32_t from, int32_t to); + void (DISCORD_API *ime_cancel_composition)(struct IDiscordOverlayManager* manager); + void (DISCORD_API *set_ime_composition_range_callback)(struct IDiscordOverlayManager* manager, void* on_ime_composition_range_changed_data, void (DISCORD_API *on_ime_composition_range_changed)(void* on_ime_composition_range_changed_data, int32_t from, int32_t to, struct DiscordRect* bounds, uint32_t bounds_length)); + void (DISCORD_API *set_ime_selection_bounds_callback)(struct IDiscordOverlayManager* manager, void* on_ime_selection_bounds_changed_data, void (DISCORD_API *on_ime_selection_bounds_changed)(void* on_ime_selection_bounds_changed_data, struct DiscordRect anchor, struct DiscordRect focus, bool is_anchor_first)); + bool (DISCORD_API *is_point_inside_click_zone)(struct IDiscordOverlayManager* manager, int32_t x, int32_t y); }; typedef void* IDiscordStorageEvents; struct IDiscordStorageManager { - enum EDiscordResult (*read)(struct IDiscordStorageManager* manager, const char* name, uint8_t* data, uint32_t data_length, uint32_t* read); - void (*read_async)(struct IDiscordStorageManager* manager, const char* name, void* callback_data, void (*callback)(void* callback_data, enum EDiscordResult result, uint8_t* data, uint32_t data_length)); - void (*read_async_partial)(struct IDiscordStorageManager* manager, const char* name, uint64_t offset, uint64_t length, void* callback_data, void (*callback)(void* callback_data, enum EDiscordResult result, uint8_t* data, uint32_t data_length)); - enum EDiscordResult (*write)(struct IDiscordStorageManager* manager, const char* name, uint8_t* data, uint32_t data_length); - void (*write_async)(struct IDiscordStorageManager* manager, const char* name, uint8_t* data, uint32_t data_length, void* callback_data, void (*callback)(void* callback_data, enum EDiscordResult result)); - enum EDiscordResult (*delete_)(struct IDiscordStorageManager* manager, const char* name); - enum EDiscordResult (*exists)(struct IDiscordStorageManager* manager, const char* name, bool* exists); - void (*count)(struct IDiscordStorageManager* manager, int32_t* count); - enum EDiscordResult (*stat)(struct IDiscordStorageManager* manager, const char* name, struct DiscordFileStat* stat); - enum EDiscordResult (*stat_at)(struct IDiscordStorageManager* manager, int32_t index, struct DiscordFileStat* stat); - enum EDiscordResult (*get_path)(struct IDiscordStorageManager* manager, DiscordPath* path); + enum EDiscordResult (DISCORD_API *read)(struct IDiscordStorageManager* manager, const char* name, uint8_t* data, uint32_t data_length, uint32_t* read); + void (DISCORD_API *read_async)(struct IDiscordStorageManager* manager, const char* name, void* callback_data, void (DISCORD_API *callback)(void* callback_data, enum EDiscordResult result, uint8_t* data, uint32_t data_length)); + void (DISCORD_API *read_async_partial)(struct IDiscordStorageManager* manager, const char* name, uint64_t offset, uint64_t length, void* callback_data, void (DISCORD_API *callback)(void* callback_data, enum EDiscordResult result, uint8_t* data, uint32_t data_length)); + enum EDiscordResult (DISCORD_API *write)(struct IDiscordStorageManager* manager, const char* name, uint8_t* data, uint32_t data_length); + void (DISCORD_API *write_async)(struct IDiscordStorageManager* manager, const char* name, uint8_t* data, uint32_t data_length, void* callback_data, void (DISCORD_API *callback)(void* callback_data, enum EDiscordResult result)); + enum EDiscordResult (DISCORD_API *delete_)(struct IDiscordStorageManager* manager, const char* name); + enum EDiscordResult (DISCORD_API *exists)(struct IDiscordStorageManager* manager, const char* name, bool* exists); + void (DISCORD_API *count)(struct IDiscordStorageManager* manager, int32_t* count); + enum EDiscordResult (DISCORD_API *stat)(struct IDiscordStorageManager* manager, const char* name, struct DiscordFileStat* stat); + enum EDiscordResult (DISCORD_API *stat_at)(struct IDiscordStorageManager* manager, int32_t index, struct DiscordFileStat* stat); + enum EDiscordResult (DISCORD_API *get_path)(struct IDiscordStorageManager* manager, DiscordPath* path); }; struct IDiscordStoreEvents { - void (*on_entitlement_create)(void* event_data, struct DiscordEntitlement* entitlement); - void (*on_entitlement_delete)(void* event_data, struct DiscordEntitlement* entitlement); + void (DISCORD_API *on_entitlement_create)(void* event_data, struct DiscordEntitlement* entitlement); + void (DISCORD_API *on_entitlement_delete)(void* event_data, struct DiscordEntitlement* entitlement); }; struct IDiscordStoreManager { - void (*fetch_skus)(struct IDiscordStoreManager* manager, void* callback_data, void (*callback)(void* callback_data, enum EDiscordResult result)); - void (*count_skus)(struct IDiscordStoreManager* manager, int32_t* count); - enum EDiscordResult (*get_sku)(struct IDiscordStoreManager* manager, DiscordSnowflake sku_id, struct DiscordSku* sku); - enum EDiscordResult (*get_sku_at)(struct IDiscordStoreManager* manager, int32_t index, struct DiscordSku* sku); - void (*fetch_entitlements)(struct IDiscordStoreManager* manager, void* callback_data, void (*callback)(void* callback_data, enum EDiscordResult result)); - void (*count_entitlements)(struct IDiscordStoreManager* manager, int32_t* count); - enum EDiscordResult (*get_entitlement)(struct IDiscordStoreManager* manager, DiscordSnowflake entitlement_id, struct DiscordEntitlement* entitlement); - enum EDiscordResult (*get_entitlement_at)(struct IDiscordStoreManager* manager, int32_t index, struct DiscordEntitlement* entitlement); - enum EDiscordResult (*has_sku_entitlement)(struct IDiscordStoreManager* manager, DiscordSnowflake sku_id, bool* has_entitlement); - void (*start_purchase)(struct IDiscordStoreManager* manager, DiscordSnowflake sku_id, void* callback_data, void (*callback)(void* callback_data, enum EDiscordResult result)); + void (DISCORD_API *fetch_skus)(struct IDiscordStoreManager* manager, void* callback_data, void (DISCORD_API *callback)(void* callback_data, enum EDiscordResult result)); + void (DISCORD_API *count_skus)(struct IDiscordStoreManager* manager, int32_t* count); + enum EDiscordResult (DISCORD_API *get_sku)(struct IDiscordStoreManager* manager, DiscordSnowflake sku_id, struct DiscordSku* sku); + enum EDiscordResult (DISCORD_API *get_sku_at)(struct IDiscordStoreManager* manager, int32_t index, struct DiscordSku* sku); + void (DISCORD_API *fetch_entitlements)(struct IDiscordStoreManager* manager, void* callback_data, void (DISCORD_API *callback)(void* callback_data, enum EDiscordResult result)); + void (DISCORD_API *count_entitlements)(struct IDiscordStoreManager* manager, int32_t* count); + enum EDiscordResult (DISCORD_API *get_entitlement)(struct IDiscordStoreManager* manager, DiscordSnowflake entitlement_id, struct DiscordEntitlement* entitlement); + enum EDiscordResult (DISCORD_API *get_entitlement_at)(struct IDiscordStoreManager* manager, int32_t index, struct DiscordEntitlement* entitlement); + enum EDiscordResult (DISCORD_API *has_sku_entitlement)(struct IDiscordStoreManager* manager, DiscordSnowflake sku_id, bool* has_entitlement); + void (DISCORD_API *start_purchase)(struct IDiscordStoreManager* manager, DiscordSnowflake sku_id, void* callback_data, void (DISCORD_API *callback)(void* callback_data, enum EDiscordResult result)); }; struct IDiscordVoiceEvents { - void (*on_settings_update)(void* event_data); + void (DISCORD_API *on_settings_update)(void* event_data); }; struct IDiscordVoiceManager { - enum EDiscordResult (*get_input_mode)(struct IDiscordVoiceManager* manager, struct DiscordInputMode* input_mode); - void (*set_input_mode)(struct IDiscordVoiceManager* manager, struct DiscordInputMode input_mode, void* callback_data, void (*callback)(void* callback_data, enum EDiscordResult result)); - enum EDiscordResult (*is_self_mute)(struct IDiscordVoiceManager* manager, bool* mute); - enum EDiscordResult (*set_self_mute)(struct IDiscordVoiceManager* manager, bool mute); - enum EDiscordResult (*is_self_deaf)(struct IDiscordVoiceManager* manager, bool* deaf); - enum EDiscordResult (*set_self_deaf)(struct IDiscordVoiceManager* manager, bool deaf); - enum EDiscordResult (*is_local_mute)(struct IDiscordVoiceManager* manager, DiscordSnowflake user_id, bool* mute); - enum EDiscordResult (*set_local_mute)(struct IDiscordVoiceManager* manager, DiscordSnowflake user_id, bool mute); - enum EDiscordResult (*get_local_volume)(struct IDiscordVoiceManager* manager, DiscordSnowflake user_id, uint8_t* volume); - enum EDiscordResult (*set_local_volume)(struct IDiscordVoiceManager* manager, DiscordSnowflake user_id, uint8_t volume); + enum EDiscordResult (DISCORD_API *get_input_mode)(struct IDiscordVoiceManager* manager, struct DiscordInputMode* input_mode); + void (DISCORD_API *set_input_mode)(struct IDiscordVoiceManager* manager, struct DiscordInputMode input_mode, void* callback_data, void (DISCORD_API *callback)(void* callback_data, enum EDiscordResult result)); + enum EDiscordResult (DISCORD_API *is_self_mute)(struct IDiscordVoiceManager* manager, bool* mute); + enum EDiscordResult (DISCORD_API *set_self_mute)(struct IDiscordVoiceManager* manager, bool mute); + enum EDiscordResult (DISCORD_API *is_self_deaf)(struct IDiscordVoiceManager* manager, bool* deaf); + enum EDiscordResult (DISCORD_API *set_self_deaf)(struct IDiscordVoiceManager* manager, bool deaf); + enum EDiscordResult (DISCORD_API *is_local_mute)(struct IDiscordVoiceManager* manager, DiscordSnowflake user_id, bool* mute); + enum EDiscordResult (DISCORD_API *set_local_mute)(struct IDiscordVoiceManager* manager, DiscordSnowflake user_id, bool mute); + enum EDiscordResult (DISCORD_API *get_local_volume)(struct IDiscordVoiceManager* manager, DiscordSnowflake user_id, uint8_t* volume); + enum EDiscordResult (DISCORD_API *set_local_volume)(struct IDiscordVoiceManager* manager, DiscordSnowflake user_id, uint8_t volume); }; struct IDiscordAchievementEvents { - void (*on_user_achievement_update)(void* event_data, struct DiscordUserAchievement* user_achievement); + void (DISCORD_API *on_user_achievement_update)(void* event_data, struct DiscordUserAchievement* user_achievement); }; struct IDiscordAchievementManager { - void (*set_user_achievement)(struct IDiscordAchievementManager* manager, DiscordSnowflake achievement_id, uint8_t percent_complete, void* callback_data, void (*callback)(void* callback_data, enum EDiscordResult result)); - void (*fetch_user_achievements)(struct IDiscordAchievementManager* manager, void* callback_data, void (*callback)(void* callback_data, enum EDiscordResult result)); - void (*count_user_achievements)(struct IDiscordAchievementManager* manager, int32_t* count); - enum EDiscordResult (*get_user_achievement)(struct IDiscordAchievementManager* manager, DiscordSnowflake user_achievement_id, struct DiscordUserAchievement* user_achievement); - enum EDiscordResult (*get_user_achievement_at)(struct IDiscordAchievementManager* manager, int32_t index, struct DiscordUserAchievement* user_achievement); + void (DISCORD_API *set_user_achievement)(struct IDiscordAchievementManager* manager, DiscordSnowflake achievement_id, uint8_t percent_complete, void* callback_data, void (DISCORD_API *callback)(void* callback_data, enum EDiscordResult result)); + void (DISCORD_API *fetch_user_achievements)(struct IDiscordAchievementManager* manager, void* callback_data, void (DISCORD_API *callback)(void* callback_data, enum EDiscordResult result)); + void (DISCORD_API *count_user_achievements)(struct IDiscordAchievementManager* manager, int32_t* count); + enum EDiscordResult (DISCORD_API *get_user_achievement)(struct IDiscordAchievementManager* manager, DiscordSnowflake user_achievement_id, struct DiscordUserAchievement* user_achievement); + enum EDiscordResult (DISCORD_API *get_user_achievement_at)(struct IDiscordAchievementManager* manager, int32_t index, struct DiscordUserAchievement* user_achievement); }; typedef void* IDiscordCoreEvents; struct IDiscordCore { - void (*destroy)(struct IDiscordCore* core); - enum EDiscordResult (*run_callbacks)(struct IDiscordCore* core); - void (*set_log_hook)(struct IDiscordCore* core, enum EDiscordLogLevel min_level, void* hook_data, void (*hook)(void* hook_data, enum EDiscordLogLevel level, const char* message)); - struct IDiscordApplicationManager* (*get_application_manager)(struct IDiscordCore* core); - struct IDiscordUserManager* (*get_user_manager)(struct IDiscordCore* core); - struct IDiscordImageManager* (*get_image_manager)(struct IDiscordCore* core); - struct IDiscordActivityManager* (*get_activity_manager)(struct IDiscordCore* core); - struct IDiscordRelationshipManager* (*get_relationship_manager)(struct IDiscordCore* core); - struct IDiscordLobbyManager* (*get_lobby_manager)(struct IDiscordCore* core); - struct IDiscordNetworkManager* (*get_network_manager)(struct IDiscordCore* core); - struct IDiscordOverlayManager* (*get_overlay_manager)(struct IDiscordCore* core); - struct IDiscordStorageManager* (*get_storage_manager)(struct IDiscordCore* core); - struct IDiscordStoreManager* (*get_store_manager)(struct IDiscordCore* core); - struct IDiscordVoiceManager* (*get_voice_manager)(struct IDiscordCore* core); - struct IDiscordAchievementManager* (*get_achievement_manager)(struct IDiscordCore* core); + void (DISCORD_API *destroy)(struct IDiscordCore* core); + enum EDiscordResult (DISCORD_API *run_callbacks)(struct IDiscordCore* core); + void (DISCORD_API *set_log_hook)(struct IDiscordCore* core, enum EDiscordLogLevel min_level, void* hook_data, void (DISCORD_API *hook)(void* hook_data, enum EDiscordLogLevel level, const char* message)); + struct IDiscordApplicationManager* (DISCORD_API *get_application_manager)(struct IDiscordCore* core); + struct IDiscordUserManager* (DISCORD_API *get_user_manager)(struct IDiscordCore* core); + struct IDiscordImageManager* (DISCORD_API *get_image_manager)(struct IDiscordCore* core); + struct IDiscordActivityManager* (DISCORD_API *get_activity_manager)(struct IDiscordCore* core); + struct IDiscordRelationshipManager* (DISCORD_API *get_relationship_manager)(struct IDiscordCore* core); + struct IDiscordLobbyManager* (DISCORD_API *get_lobby_manager)(struct IDiscordCore* core); + struct IDiscordNetworkManager* (DISCORD_API *get_network_manager)(struct IDiscordCore* core); + struct IDiscordOverlayManager* (DISCORD_API *get_overlay_manager)(struct IDiscordCore* core); + struct IDiscordStorageManager* (DISCORD_API *get_storage_manager)(struct IDiscordCore* core); + struct IDiscordStoreManager* (DISCORD_API *get_store_manager)(struct IDiscordCore* core); + struct IDiscordVoiceManager* (DISCORD_API *get_voice_manager)(struct IDiscordCore* core); + struct IDiscordAchievementManager* (DISCORD_API *get_achievement_manager)(struct IDiscordCore* core); }; struct DiscordCreateParams { @@ -644,7 +727,7 @@ void DiscordCreateParamsSetDefault(struct DiscordCreateParams* params) params->achievement_version = DISCORD_ACHIEVEMENT_MANAGER_VERSION; } -enum EDiscordResult DiscordCreate(DiscordVersion version, struct DiscordCreateParams* params, struct IDiscordCore** result); +enum EDiscordResult DISCORD_API DiscordCreate(DiscordVersion version, struct DiscordCreateParams* params, struct IDiscordCore** result); #ifdef __cplusplus } diff --git a/src/qt/qt_rendererstack.cpp b/src/qt/qt_rendererstack.cpp index ae451db6c..795c31fe7 100644 --- a/src/qt/qt_rendererstack.cpp +++ b/src/qt/qt_rendererstack.cpp @@ -447,7 +447,11 @@ RendererStack::blitCommon(int x, int y, int w, int h) void RendererStack::closeEvent(QCloseEvent* event) { - if (cpu_thread_run == 0 || is_quit == 1) { event->accept(); return; } + if (cpu_thread_run == 0 || is_quit == 0) { + event->accept(); + show_second_monitors = 0; // TODO: This isn't actually the right fix, so fix this properly. + return; + } event->ignore(); main_window->close(); } diff --git a/src/upi42.c b/src/upi42.c index e98af5496..8b8e4b72e 100644 --- a/src/upi42.c +++ b/src/upi42.c @@ -18,40 +18,89 @@ #include #include #include -#define fatal printf -#define pclog printf -enum { - UPI42_8042 = 0, - UPI42_80C42 -}; +#ifdef UPI42_STANDALONE +# define fatal(...) \ + { \ + upi42_log(__VA_ARGS__); \ + abort(); \ + } +# define upi42_log(...) \ + { \ + printf(__VA_ARGS__); \ + fflush(stdout); \ + } +#else +#include +#define HAVE_STDARG_H +#include <86box/86box.h> +#include <86box/device.h> +#include <86box/io.h> +#include <86box/timer.h> + + +#ifdef ENABLE_UPI42_LOG +int upi42_do_log = ENABLE_UPI42_LOG; + + +void +upi42_log(const char *fmt, ...) +{ + va_list ap; + + if (upi42_do_log) { + va_start(ap, fmt); + pclog_ex(fmt, ap); + va_end(ap); + } +} +#else +#define upi42_log(fmt, ...) +#endif +#endif + +#define UPI42_REG(upi42, r, op) ((upi42->psw & 0x10) ? (upi42->ram[24 + ((r) &7)] op) : (upi42->ram[(r) &7] op)) + +#define UPI42_ROM_SHIFT 0 /* actually the mask */ +#define UPI42_RAM_SHIFT 16 /* actually the mask */ +#define UPI42_TYPE_MCS (0 << 24) +#define UPI42_TYPE_UPI (1 << 24) +#define UPI42_EXT_C42 (1 << 25) + +#define UPI42_8048 ((1023 << UPI42_ROM_SHIFT) | (63 << UPI42_RAM_SHIFT) | UPI42_TYPE_MCS) +#define UPI42_8049 ((2047 << UPI42_ROM_SHIFT) | (127 << UPI42_RAM_SHIFT) | UPI42_TYPE_MCS) +#define UPI42_8041 ((1023 << UPI42_ROM_SHIFT) | (127 << UPI42_RAM_SHIFT) | UPI42_TYPE_UPI) +#define UPI42_8042 ((2047 << UPI42_ROM_SHIFT) | (255 << UPI42_RAM_SHIFT) | UPI42_TYPE_UPI) +#define UPI42_80C42 ((4095 << UPI42_ROM_SHIFT) | (255 << UPI42_RAM_SHIFT) | UPI42_TYPE_UPI | UPI42_EXT_C42) typedef struct _upi42_ { int (*ops[256])(struct _upi42_ *upi42, uint32_t fetchdat); - uint8_t ram[256], rom[4096], /* memory */ - ports[7], /* I/O ports */ - dbb_in, dbb_out; /* UPI-42 data buffer */ + uint32_t type; + uint8_t ram[256], *rom, /* memory */ + ports_in[8], ports_out[8], /* I/O ports */ + dbb_in, dbb_out; /* UPI-42 data buffer */ - uint8_t rammask, - a, /* accumulator */ - t, /* timer counter */ - psw, /* program status word */ - sts; /* UPI-42 status */ + uint8_t rammask, /* RAM mask */ + a, /* accumulator */ + t, /* timer counter */ + psw, /* program status word */ + sts; /* UPI-42 status */ - uint16_t pc; /* program counter */ + uint16_t pc, rommask; /* program counter and ROM mask */ - unsigned int prescaler : 5, tf : 1, tcnti : 1, run_timer : 1, run_counter : 1, skip_timer_inc : 1, /* timer/counter */ - i : 1, i_asserted : 1, tcnti_asserted : 1, irq_mask : 1, /* interrupts */ - dbf : 1, /* ROM bank */ - t0 : 1, t1 : 1, /* T0/T1 signals */ - flags : 1, /* buffer flag pins */ - suspend : 1; /* 80C42 suspend flag */ + unsigned int prescaler : 5, tf : 1, skip_timer_inc : 1, /* timer/counter */ + run_timer : 1, run_counter : 1, tcnti : 1, /* timer/counter enables */ + i : 1, i_raise : 1, tcnti_raise : 1, irq_mask : 1, /* interrupts */ + t0 : 1, t1 : 1, /* T0/T1 signals */ + flags : 1, dbf : 1, suspend : 1; /* UPI-42 flags */ int cycs; /* cycle counter */ -} upi42_t; -#define UPI42_REG_READ(upi42, r) ((upi42->psw & 0x10) ? (upi42->ram[24 + ((r) &7)]) : (upi42->ram[(r) &7])) -#define UPI42_REG_WRITE(upi42, r, op) ((upi42->psw & 0x10) ? (upi42->ram[24 + ((r) &7)] op) : (upi42->ram[(r) &7] op)) +#ifndef UPI42_STANDALONE + uint8_t ram_index; + uint16_t rom_index; +#endif +} upi42_t; static inline void upi42_mirror_f0(upi42_t *upi42) @@ -63,14 +112,14 @@ upi42_mirror_f0(upi42_t *upi42) static int upi42_op_MOV_A_Rr(upi42_t *upi42, uint32_t fetchdat) { - upi42->a = UPI42_REG_READ(upi42, fetchdat); + upi42->a = UPI42_REG(upi42, fetchdat, ); return 1; } static int upi42_op_MOV_Rr_A(upi42_t *upi42, uint32_t fetchdat) { - UPI42_REG_WRITE(upi42, fetchdat, = upi42->a); + UPI42_REG(upi42, fetchdat, = upi42->a); return 1; } @@ -91,7 +140,7 @@ upi42_op_MOV_indRr_A(upi42_t *upi42, uint32_t fetchdat) static int upi42_op_MOV_Rr_imm(upi42_t *upi42, uint32_t fetchdat) { - UPI42_REG_WRITE(upi42, fetchdat, = fetchdat >> 8); + UPI42_REG(upi42, fetchdat, = fetchdat >> 8); upi42->cycs--; return 2; } @@ -169,8 +218,8 @@ static int upi42_op_XCH_A_Rr(upi42_t *upi42, uint32_t fetchdat) { uint8_t temp = upi42->a; - upi42->a = UPI42_REG_READ(upi42, fetchdat); - UPI42_REG_WRITE(upi42, fetchdat, = temp); + upi42->a = UPI42_REG(upi42, fetchdat, ); + UPI42_REG(upi42, fetchdat, = temp); return 1; } @@ -202,7 +251,8 @@ upi42_op_SWAP_A(upi42_t *upi42, uint32_t fetchdat) static int upi42_op_IN_A_Pp(upi42_t *upi42, uint32_t fetchdat) { - upi42->a = upi42->ports[fetchdat & 3]; + int port = fetchdat & 3; + upi42->a = upi42->ports_in[port] & upi42->ports_out[port]; upi42->cycs--; return 1; } @@ -211,13 +261,14 @@ static int upi42_op_IN_A_DBB(upi42_t *upi42, uint32_t fetchdat) { upi42->a = upi42->dbb_in; + upi42->sts &= ~0x02; /* clear IBF */ return 1; } static int upi42_op_OUTL_Pp_A(upi42_t *upi42, uint32_t fetchdat) { - upi42->ports[fetchdat & 3] = upi42->a; + upi42->ports_out[fetchdat & 3] = upi42->a; upi42->cycs--; return 1; } @@ -226,14 +277,15 @@ static int upi42_op_OUT_DBB_A(upi42_t *upi42, uint32_t fetchdat) { upi42->dbb_out = upi42->a; - upi42->sts |= 0x01; + upi42->sts |= 0x01; /* set OBF */ return 1; } static int upi42_op_MOVD_A_Pp(upi42_t *upi42, uint32_t fetchdat) { - upi42->a = upi42->ports[4 | (fetchdat & 3)] & 0x0f; + int port = 4 | (fetchdat & 3); + upi42->a = (upi42->ports_in[port] & upi42->ports_out[port]) & 0x0f; upi42->cycs--; return 1; } @@ -241,7 +293,7 @@ upi42_op_MOVD_A_Pp(upi42_t *upi42, uint32_t fetchdat) static int upi42_op_MOVD_Pp_A(upi42_t *upi42, uint32_t fetchdat) { - upi42->ports[4 | (fetchdat & 3)] = upi42->a & 0x0f; + upi42->ports_out[4 | (fetchdat & 3)] = upi42->a & 0x0f; upi42->cycs--; return 1; } @@ -249,21 +301,21 @@ upi42_op_MOVD_Pp_A(upi42_t *upi42, uint32_t fetchdat) static int upi42_op_ANL_A_Rr(upi42_t *upi42, uint32_t fetchdat) { - upi42->a &= UPI42_REG_READ(upi42, fetchdat); + upi42->a &= UPI42_REG(upi42, fetchdat, ); return 1; } static int upi42_op_ORL_A_Rr(upi42_t *upi42, uint32_t fetchdat) { - upi42->a |= UPI42_REG_READ(upi42, fetchdat); + upi42->a |= UPI42_REG(upi42, fetchdat, ); return 1; } static int upi42_op_XRL_A_Rr(upi42_t *upi42, uint32_t fetchdat) { - upi42->a ^= UPI42_REG_READ(upi42, fetchdat); + upi42->a ^= UPI42_REG(upi42, fetchdat, ); return 1; } @@ -315,7 +367,7 @@ upi42_op_XRL_A_imm(upi42_t *upi42, uint32_t fetchdat) static int upi42_op_ANL_Pp_imm(upi42_t *upi42, uint32_t fetchdat) { - upi42->ports[fetchdat & 3] &= fetchdat >> 8; + upi42->ports_out[fetchdat & 3] &= fetchdat >> 8; upi42->cycs--; return 2; } @@ -323,7 +375,7 @@ upi42_op_ANL_Pp_imm(upi42_t *upi42, uint32_t fetchdat) static int upi42_op_ORL_Pp_imm(upi42_t *upi42, uint32_t fetchdat) { - upi42->ports[fetchdat & 3] |= fetchdat >> 8; + upi42->ports_out[fetchdat & 3] |= fetchdat >> 8; upi42->cycs--; return 2; } @@ -331,7 +383,7 @@ upi42_op_ORL_Pp_imm(upi42_t *upi42, uint32_t fetchdat) static int upi42_op_ANLD_Pp_A(upi42_t *upi42, uint32_t fetchdat) { - upi42->ports[4 | (fetchdat & 3)] &= upi42->a; + upi42->ports_out[4 | (fetchdat & 3)] &= upi42->a; upi42->cycs--; return 1; } @@ -339,7 +391,7 @@ upi42_op_ANLD_Pp_A(upi42_t *upi42, uint32_t fetchdat) static int upi42_op_ORLD_Pp_A(upi42_t *upi42, uint32_t fetchdat) { - upi42->ports[4 | (fetchdat & 3)] |= upi42->a; + upi42->ports_out[4 | (fetchdat & 3)] |= upi42->a; upi42->cycs--; return 1; } @@ -386,7 +438,7 @@ upi42_op_INC_A(upi42_t *upi42, uint32_t fetchdat) static int upi42_op_INC_Rr(upi42_t *upi42, uint32_t fetchdat) { - UPI42_REG_WRITE(upi42, fetchdat, ++); + UPI42_REG(upi42, fetchdat, ++); return 1; } @@ -407,15 +459,16 @@ upi42_op_DEC_A(upi42_t *upi42, uint32_t fetchdat) static int upi42_op_DEC_Rr(upi42_t *upi42, uint32_t fetchdat) { - UPI42_REG_WRITE(upi42, fetchdat, --); + UPI42_REG(upi42, fetchdat, --); return 1; } static int upi42_op_DJNZ_Rr_imm(upi42_t *upi42, uint32_t fetchdat) { - UPI42_REG_WRITE(upi42, fetchdat, --); - if (UPI42_REG_READ(upi42, fetchdat)) { + upi42->cycs--; + UPI42_REG(upi42, fetchdat, --); + if (UPI42_REG(upi42, fetchdat, )) { upi42->pc = (upi42->pc & 0xff00) | ((fetchdat >> 8) & 0xff); return 0; } else { @@ -426,7 +479,7 @@ upi42_op_DJNZ_Rr_imm(upi42_t *upi42, uint32_t fetchdat) static int upi42_op_ADD_A_Rr(upi42_t *upi42, uint32_t fetchdat) { - int res = upi42->a + UPI42_REG_READ(upi42, fetchdat); + int res = upi42->a + UPI42_REG(upi42, fetchdat, ); upi42->a = res; upi42->psw = ((res >> 1) & 0x80) | (upi42->psw & ~0x80); return 1; @@ -435,7 +488,7 @@ upi42_op_ADD_A_Rr(upi42_t *upi42, uint32_t fetchdat) static int upi42_op_ADDC_A_Rr(upi42_t *upi42, uint32_t fetchdat) { - int res = upi42->a + (upi42->psw >> 7) + UPI42_REG_READ(upi42, fetchdat); + int res = upi42->a + (upi42->psw >> 7) + UPI42_REG(upi42, fetchdat, ); upi42->a = res; upi42->psw = ((res >> 1) & 0x80) | (upi42->psw & ~0x80); return 1; @@ -444,7 +497,7 @@ upi42_op_ADDC_A_Rr(upi42_t *upi42, uint32_t fetchdat) static int upi42_op_ADD_A_indRr(upi42_t *upi42, uint32_t fetchdat) { - int res = upi42->a + upi42->ram[UPI42_REG_READ(upi42, fetchdat) & upi42->rammask]; + int res = upi42->a + upi42->ram[UPI42_REG(upi42, fetchdat, ) & upi42->rammask]; upi42->a = res; upi42->psw = ((res >> 1) & 0x80) | (upi42->psw & ~0x80); return 1; @@ -453,7 +506,7 @@ upi42_op_ADD_A_indRr(upi42_t *upi42, uint32_t fetchdat) static int upi42_op_ADDC_A_indRr(upi42_t *upi42, uint32_t fetchdat) { - int res = upi42->a + (upi42->psw >> 7) + upi42->ram[UPI42_REG_READ(upi42, fetchdat) & upi42->rammask]; + int res = upi42->a + (upi42->psw >> 7) + upi42->ram[UPI42_REG(upi42, fetchdat, ) & upi42->rammask]; upi42->a = res; upi42->psw = ((res >> 1) & 0x80) | (upi42->psw & ~0x80); return 1; @@ -576,7 +629,7 @@ upi42_op_EN_TCNTI(upi42_t *upi42, uint32_t fetchdat) static int upi42_op_DIS_TCNTI(upi42_t *upi42, uint32_t fetchdat) { - upi42->tcnti = upi42->tcnti_asserted = 0; + upi42->tcnti = upi42->tcnti_raise = 0; return 1; } @@ -644,16 +697,14 @@ upi42_op_CALL_imm(upi42_t *upi42, uint32_t fetchdat) { /* Push new frame onto stack. */ uint8_t sp = (upi42->psw & 0x07) << 1; - upi42->ram[8 + sp++] = upi42->pc; /* stack frame format is undocumented! */ + upi42->ram[8 + sp++] = upi42->pc + 2; /* stack frame format is undocumented! */ upi42->ram[8 + sp++] = (upi42->psw & 0xf0) | ((upi42->pc >> 8) & 0x07); upi42->psw = (upi42->psw & 0xf8) | (sp >> 1); /* Load new program counter. */ upi42->pc = (upi42->dbf << 11) | ((fetchdat << 3) & 0x0700) | ((fetchdat >> 8) & 0x00ff); - /* Don't decrease cycle counter if this is an interrupt call. */ - if (fetchdat & 0xff) - upi42->cycs--; + upi42->cycs--; return 0; } @@ -703,24 +754,24 @@ upi42_op_JMPP_indA(upi42_t *upi42, uint32_t fetchdat) { \ if (cond) \ upi42->pc = (upi42->pc & 0xff00) | ((fetchdat >> 8) & 0x00ff); \ - post \ - upi42->cycs--; \ + post; \ + upi42->cycs--; \ return 2 * !(cond); \ } -UPI42_COND_JMP_IMM(JC, upi42->psw & 0x80, ;) -UPI42_COND_JMP_IMM(JNC, !(upi42->psw & 0x80), ;) -UPI42_COND_JMP_IMM(JZ, !upi42->a, ;) -UPI42_COND_JMP_IMM(JNZ, upi42->a, ;) -UPI42_COND_JMP_IMM(JT0, upi42->t0, ;) -UPI42_COND_JMP_IMM(JNT0, !upi42->t0, ;) -UPI42_COND_JMP_IMM(JT1, upi42->t1, ;) -UPI42_COND_JMP_IMM(JNT1, !upi42->t1, ;) -UPI42_COND_JMP_IMM(JF0, upi42->psw & 0x20, ;) -UPI42_COND_JMP_IMM(JF1, upi42->sts & 0x08, ;) -UPI42_COND_JMP_IMM(JTF, !upi42->tf, upi42->tf = 0;) -UPI42_COND_JMP_IMM(JBb, upi42->a &(1 << ((fetchdat >> 5) & 7)), ;) -UPI42_COND_JMP_IMM(JNIBF, !(upi42->sts & 0x02), ;) -UPI42_COND_JMP_IMM(JOBF, upi42->sts & 0x01, ;) +UPI42_COND_JMP_IMM(JC, upi42->psw & 0x80, ) +UPI42_COND_JMP_IMM(JNC, !(upi42->psw & 0x80), ) +UPI42_COND_JMP_IMM(JZ, !upi42->a, ) +UPI42_COND_JMP_IMM(JNZ, upi42->a, ) +UPI42_COND_JMP_IMM(JT0, upi42->t0, ) +UPI42_COND_JMP_IMM(JNT0, !upi42->t0, ) +UPI42_COND_JMP_IMM(JT1, upi42->t1, ) +UPI42_COND_JMP_IMM(JNT1, !upi42->t1, ) +UPI42_COND_JMP_IMM(JF0, upi42->psw & 0x20, ) +UPI42_COND_JMP_IMM(JF1, upi42->sts & 0x08, ) +UPI42_COND_JMP_IMM(JTF, !upi42->tf, upi42->tf = 0) +UPI42_COND_JMP_IMM(JBb, upi42->a &(1 << ((fetchdat >> 5) & 7)), ) +UPI42_COND_JMP_IMM(JNIBF, !(upi42->sts & 0x02), ) +UPI42_COND_JMP_IMM(JOBF, upi42->sts & 0x01, ) static int upi42_op_EN_A20(upi42_t *upi42, uint32_t fetchdat) @@ -738,6 +789,7 @@ upi42_op_EN_DMA(upi42_t *upi42, uint32_t fetchdat) static int upi42_op_EN_FLAGS(upi42_t *upi42, uint32_t fetchdat) { + upi42->flags = 1; return 1; } @@ -749,65 +801,6 @@ upi42_op_SUSPEND(upi42_t *upi42, uint32_t fetchdatr) return 1; } -static void -upi42_exec(void *priv) -{ - upi42_t *upi42 = (upi42_t *) priv; - - /* Skip interrupt handling and code execution if we're suspended or in a multi-cycle instruction. */ - if (upi42->suspend || ++upi42->cycs < 0) - return; - - /* Trigger interrupt if requested. */ - if (upi42->irq_mask) { - /* Masked, we're currently in an ISR. */ - } else if (upi42->i_asserted) { - /* External interrupt. Higher priority than the timer interrupt. */ - upi42->irq_mask = 1; - upi42->i_asserted = 0; - upi42_op_CALL_imm(upi42, 3 << 8); - return; - } else if (upi42->tcnti_asserted) { - /* Timer interrupt. */ - upi42->irq_mask = 1; - upi42->tcnti_asserted = 0; - upi42_op_CALL_imm(upi42, 7 << 8); - return; - } - - /* Fetch instruction. */ - uint32_t fetchdat = *((uint32_t *) &upi42->rom[upi42->pc]); - pclog("%04X @ %04X R0=%02X", fetchdat & 0xffff, upi42->pc, upi42->ram[0]); - - /* Decode instruction. */ - uint8_t insn = fetchdat & 0xff; - if (upi42->ops[insn]) { - /* Execute instruction and increment program counter. */ - upi42->pc += upi42->ops[insn](upi42, fetchdat); - - /* Decrement cycle counter. Multi-cycle instructions also decrement within their code. */ - upi42->cycs--; - } else { - fatal("UPI42: Unknown opcode %02X (%08X)\n", insn, fetchdat); - return; - } - - /* Some instructions don't increment the timer. */ - if (upi42->skip_timer_inc) { - upi42->skip_timer_inc = 0; - } else { - /* Increment counter once the prescaler overflows, - and set timer flag once the main value overflows. */ - if ((++upi42->prescaler == 0) && (++upi42->t == 0)) { - upi42->tf = 1; - - /* Fire counter interrupt if enabled. */ - if (upi42->tcnti) - upi42->tcnti_asserted = 1; - } - } -} - static const int (*ops_80c42[256])(upi42_t *upi42, uint32_t fetchdat) = { // clang-format off /* 0 / 8 */ /* 1 / 9 */ /* 2 / a */ /* 3 / b */ /* 4 / c */ /* 5 / d */ /* 6 / e */ /* 7 / f */ @@ -823,9 +816,9 @@ static const int (*ops_80c42[256])(upi42_t *upi42, uint32_t fetchdat) = { /* 48 */ upi42_op_ORL_A_Rr, upi42_op_ORL_A_Rr, upi42_op_ORL_A_Rr, upi42_op_ORL_A_Rr, upi42_op_ORL_A_Rr, upi42_op_ORL_A_Rr, upi42_op_ORL_A_Rr, upi42_op_ORL_A_Rr, /* 50 */ upi42_op_ANL_A_indRr, upi42_op_ANL_A_indRr, upi42_op_JBb_imm, upi42_op_ANL_A_imm, upi42_op_CALL_imm, upi42_op_STRT_T, upi42_op_JT1_imm, upi42_op_DA_A, /* 58 */ upi42_op_ANL_A_Rr, upi42_op_ANL_A_Rr, upi42_op_ANL_A_Rr, upi42_op_ANL_A_Rr, upi42_op_ANL_A_Rr, upi42_op_ANL_A_Rr, upi42_op_ANL_A_Rr, upi42_op_ANL_A_Rr, - /* 60 */ upi42_op_ADD_A_indRr, upi42_op_ADD_A_indRr, upi42_op_MOV_T_A, NULL, upi42_op_JMP_imm, upi42_op_STOP_TCNT, NULL, upi42_op_RRC_A, + /* 60 */ upi42_op_ADD_A_indRr, upi42_op_ADD_A_indRr, upi42_op_MOV_T_A, upi42_op_SEL_PMB0, upi42_op_JMP_imm, upi42_op_STOP_TCNT, NULL, upi42_op_RRC_A, /* 68 */ upi42_op_ADD_A_Rr, upi42_op_ADD_A_Rr, upi42_op_ADD_A_Rr, upi42_op_ADD_A_Rr, upi42_op_ADD_A_Rr, upi42_op_ADD_A_Rr, upi42_op_ADD_A_Rr, upi42_op_ADD_A_Rr, - /* 70 */ upi42_op_ADDC_A_indRr, upi42_op_ADDC_A_indRr, upi42_op_JBb_imm, NULL, upi42_op_CALL_imm, NULL, upi42_op_JF1_imm, upi42_op_RR_A, + /* 70 */ upi42_op_ADDC_A_indRr, upi42_op_ADDC_A_indRr, upi42_op_JBb_imm, upi42_op_SEL_PMB1, upi42_op_CALL_imm, NULL, upi42_op_JF1_imm, upi42_op_RR_A, /* 78 */ upi42_op_ADDC_A_Rr, upi42_op_ADDC_A_Rr, upi42_op_ADDC_A_Rr, upi42_op_ADDC_A_Rr, upi42_op_ADDC_A_Rr, upi42_op_ADDC_A_Rr, upi42_op_ADDC_A_Rr, upi42_op_ADDC_A_Rr, /* 80 */ NULL, NULL, upi42_op_SUSPEND, upi42_op_RET, upi42_op_JMP_imm, upi42_op_CLR_F0, upi42_op_JOBF_imm, NULL, /* 88 */ upi42_op_ORL_Pp_imm, upi42_op_ORL_Pp_imm, upi42_op_ORL_Pp_imm, upi42_op_ORL_Pp_imm, upi42_op_ORLD_Pp_A, upi42_op_ORLD_Pp_A, upi42_op_ORLD_Pp_A, upi42_op_ORLD_Pp_A, @@ -847,27 +840,182 @@ static const int (*ops_80c42[256])(upi42_t *upi42, uint32_t fetchdat) = { }; static void -upi42_reset(upi42_t *upi42) +upi42_exec(void *priv) { - upi42->pc = 0; /* program counter */ - upi42->psw = 0; /* stack pointer, register bank and F0 */ - upi42->dbf = 0; /* memory bank */ - upi42->i = upi42->tcnti = 0; /* both interrupts */ - upi42->tf = 0; /* timer flag */ - upi42->sts = 0; /* F1 */ - upi42->suspend = 0; /* 80C42 suspend flag */ + upi42_t *upi42 = (upi42_t *) priv; + + /* Skip everything if we're suspended, or just process timer if we're in a multi-cycle instruction. */ + if (upi42->suspend) + return; + else if (++upi42->cycs < 0) + goto timer; + + /* Trigger interrupt if requested. */ + if (upi42->irq_mask) { + /* Masked, we're currently in an ISR. */ + } else if (upi42->i_raise) { + /* External interrupt. Higher priority than the timer interrupt. */ + upi42->irq_mask = 1; + upi42->i_raise = 0; + + upi42->pc -= 2; + upi42->cycs++; + upi42_op_CALL_imm(upi42, 3 << 8); + return; + } else if (upi42->tcnti_raise) { + /* Timer interrupt. */ + upi42->irq_mask = 1; + upi42->tcnti_raise = 0; + + upi42->pc -= 2; + upi42->cycs++; + upi42_op_CALL_imm(upi42, 7 << 8); + return; + } + + /* Fetch instruction. */ + uint32_t fetchdat = *((uint32_t *) &upi42->rom[upi42->pc]); + + /* Decode instruction. */ + uint8_t insn = fetchdat & 0xff; + if (upi42->ops[insn]) { + /* Execute instruction. */ + int pc_inc = upi42->ops[insn](upi42, fetchdat); + + /* Increment lower 11 bits of the program counter. */ + upi42->pc = (upi42->pc & 0xf800) | ((upi42->pc + pc_inc) & 0x07ff); + + /* Decrement cycle counter. Multi-cycle instructions also decrement within their code. */ + upi42->cycs--; + } else { + fatal("UPI42: Unknown opcode %02X (%08X)\n", insn, fetchdat); + return; + } + +timer: + /* Process timer. */ + if (!upi42->run_timer) { + /* Timer disabled. */ + } else if (upi42->skip_timer_inc) { + /* Some instructions don't increment the timer. */ + upi42->skip_timer_inc = 0; + } else { + /* Increment counter once the prescaler overflows, + and set timer flag once the main value overflows. */ + if ((++upi42->prescaler == 0) && (++upi42->t == 0)) { + upi42->tf = 1; + + /* Fire counter interrupt if enabled. */ + if (upi42->tcnti) + upi42->tcnti_raise = 1; + } + } } -static upi42_t * -upi42_init(int type) +uint8_t +upi42_port_read(void *priv, int port) +{ + upi42_t *upi42 = (upi42_t *) priv; + + /* Read base port value. */ + port &= 7; + uint8_t ret = upi42->ports_in[port] & upi42->ports_out[port]; + + /* Apply special meanings. */ + switch (port) { + } + + upi42_log("UPI42: port_read(%d) = %02X\n", port, ret); + return ret; +} + +void +upi42_port_write(void *priv, int port, uint8_t val) +{ + upi42_t *upi42 = (upi42_t *) priv; + + port &= 7; + upi42_log("UPI42: port_write(%d, %02X)\n", port, val); + + /* Set input level. */ + upi42->ports_in[port] = val; +} + +/* NOTE: The dbb/sts/cmd functions use I/O handler signatures; port is ignored. */ + +uint8_t +upi42_dbb_read(uint16_t port, void *priv) +{ + upi42_t *upi42 = (upi42_t *) priv; + + uint8_t ret = upi42->dbb_out; + upi42_log("UPI42: dbb_read(%04X) = %02X\n", port, ret); + upi42->sts &= ~0x01; /* clear OBF */ + return ret; +} + +void +upi42_dbb_write(uint16_t port, uint8_t val, void *priv) +{ + upi42_t *upi42 = (upi42_t *) priv; + + upi42_log("UPI42: dbb_write(%04X, %02X)\n", port, val); + upi42->dbb_in = val; + upi42->sts = (upi42->sts & ~0x08) | 0x02; /* clear F1 and set IBF */ + if (upi42->i) /* fire IBF interrupt if enabled */ + upi42->i_raise = 1; +} + +uint8_t +upi42_sts_read(uint16_t port, void *priv) +{ + upi42_t *upi42 = (upi42_t *) priv; + + uint8_t ret = upi42->sts; + upi42_log("UPI42: sts_read(%04X) = %02X\n", port, ret); + return ret; +} + +void +upi42_cmd_write(uint16_t port, uint8_t val, void *priv) +{ + upi42_t *upi42 = (upi42_t *) priv; + + upi42_log("UPI42: cmd_write(%04X, %02X)\n", port, val); + upi42->dbb_in = val; + upi42->sts |= 0x0a; /* set F1 and IBF */ + if (upi42->i) /* fire IBF interrupt if enabled */ + upi42->i_raise = 1; +} + +void +upi42_reset(upi42_t *upi42) +{ + upi42->pc = 0; /* program counter */ + upi42->psw = 0; /* stack pointer, register bank and F0 */ + upi42->dbf = 0; /* ROM bank */ + upi42->i = 0; /* external interrupt */ + upi42->tcnti = 0; /* timer/counter interrupt */ + upi42->tf = 0; /* timer flag */ + upi42->sts = 0; /* F1 */ + upi42->flags = 0; /* UPI-42 buffer interrupts */ + upi42->suspend = 0; /* 80C42 suspend flag */ +} + +void +upi42_do_init(upi32_t type, uint8_t *rom) { - /* Allocate state structure. */ - upi42_t *upi42 = (upi42_t *) malloc(sizeof(upi42_t)); memset(upi42, 0, sizeof(upi42_t)); + upi42->rom = rom; + + /* Set chip type. */ + upi42->type = type; + upi42->rommask = type >> UPI42_ROM_SHIFT; + upi42->rammask = type >> UPI42_RAM_SHIFT; /* Build instruction table. */ memcpy(upi42->ops, ops_80c42, sizeof(ops_80c42)); - if (type < UPI42_80C42) { + if (!(type & UPI42_EXT_C42)) { /* Remove 80C42-only instructions. */ upi42->ops[0x33] = NULL; /* EN A20 */ upi42->ops[0x63] = NULL; /* SEL PMB0 */ @@ -876,28 +1024,431 @@ upi42_init(int type) upi42->ops[0xe2] = NULL; /* SUSPEND */ } + memset(upi42_t->ports_in, 0xff, 0x08); + upi42_t->t0 = 1; + upi42_t->t1 = 1; +} + +void * +upi42_init(uint32_t type, uint8_t *rom) +{ + /* Allocate state structure. */ + upi42_t *upi42 = (upi42_t *) malloc(sizeof(upi42_t)); + upi42_do_init(type, rom); + return upi42; } +#ifdef UPI42_STANDALONE +static const char *flags_8042[] = { "OBF", "IBF", "F0", "F1", "ST4", "ST5", "ST6", "ST7" }; + int main(int argc, char **argv) { - upi42_t *upi42 = upi42_init(UPI42_8042); + /* Check arguments. */ + if (argc < 2) { + upi42_log("Specify a ROM file to execute.\n"); + return 1; + } /* Load ROM. */ - FILE *f = fopen("1503033.bin", "rb"); - fread(upi42->rom, 1, sizeof(upi42->rom), f); + uint8_t rom[4096] = { 0 }; + FILE *f = fopen(argv[1], "rb"); + if (!f) { + upi42_log("Could not read ROM file.\n"); + return 2; + } + size_t rom_size = fread(rom, sizeof(rom[0]), sizeof(rom), f); fclose(f); - /* Start execution. */ - char buf[256]; - while (1) { - upi42->sts |= 0x02; - upi42->sts |= 0x08; - upi42->dbb_in = 0xaa; - upi42->cycs = 0; + /* Determine chip type from ROM. */ + upi42_log("%d-byte ROM, ", rom_size); + uint32_t type; + switch (rom_size) { + case 0 ... 1024: + upi42_log("emulating 8041"); + type = UPI42_8041; + break; + case 1025 ... 2048: + upi42_log("emulating 8042"); + type = UPI42_8042; + break; + + case 2049 ... 4096: + upi42_log("emulating 80C42"); + type = UPI42_80C42; + break; + + default: + upi42_log("unknown!\n"); + return 3; + } + upi42_log(".\n"); + + /* Initialize emulator. */ + upi42_t *upi42 = (upi42_t *) upi42_init(type, rom); + + /* Start execution. */ + char cmd, cmd_buf[256]; + int val, go_until = -1; + while (1) { + /* Output status. */ + upi42_log("PC=%04X I=%02X(%02X) A=%02X", upi42->pc, upi42->rom[upi42->pc], upi42->rom[upi42->pc + 1], upi42->a); + for (val = 0; val < 8; val++) + upi42_log(" R%d=%02X", val, UPI42_REG(upi42, val, )); + upi42_log(" T=%02X PSW=%02X TF=%d I=%d TCNTI=%d", upi42->t, upi42->psw, upi42->tf, upi42->i, upi42->tcnti); + if (type & UPI42_TYPE_UPI) { + upi42_log(" STS=%02X", upi42->sts); + for (val = 0; val < 8; val++) { + if (upi42->sts & (1 << val)) { + upi42_log(" [%s]", flags_8042[val]); + } else { + upi42_log(" %s ", flags_8042[val]); + } + } + } + upi42_log("\n"); + + /* Break for command only if stepping. */ + if ((go_until < 0) || (upi42->pc == go_until)) { +retry: + go_until = -1; + upi42_log("> "); + + /* Read command. */ + cmd = '\0'; + scanf("%c", &cmd); + + /* Execute command. */ + switch (cmd) { + case 'c': /* write command */ + if (scanf("%X%*c", &val, &cmd_buf)) + upi42_cmd_write(0, val, upi42); + goto retry; + + case 'd': /* write data */ + if (scanf("%X%*c", &val, &cmd_buf)) + upi42_dbb_write(0, val, upi42); + goto retry; + + case 'g': /* go until */ + if (!scanf("%X%*c", &go_until, &cmd_buf)) + go_until = -1; + break; + + case 'r': /* read data */ + upi42_dbb_read(0, upi42); /* return value will be logged */ + goto skip_and_retry; + + case 'q': /* exit */ + return 0; + + case '\r': /* step */ + case '\n': + case '\0': + break; + + default: + upi42_log("Monitor commands:\n"); + upi42_log("- Return (no command) - Step execution\n"); + upi42_log("- q (or Ctrl+C) - Exit\n"); + upi42_log("- gXXXX - Execute until PC is hex value XXXX\n"); + upi42_log("- dXX - Write hex value XX to data port\n"); + upi42_log("- cXX - Write hex value XX to command port\n"); + upi42_log("- r - Read from data port and reset OBF\n"); +skip_and_retry: + scanf("%*c", &cmd_buf); + goto retry; + } + } + + /* Execute a cycle. */ upi42_exec(upi42); - fgets(buf, 256, stdin); + } + + return 0; +} +#else +static void +upi42_write(uint16_t port, uint8_t val, void *priv) +{ + upi42_t *upi42 = (upi42_t *) priv; + uint32_t temp_type, uint8_t *temp_rom; + int i; + + switch (port) { + /* Write to data port. */ + case 0x0060: + case 0x0160: + upi42_dbb_write(0, val, upi42); + break; + + /* RAM Index. */ + case 0x0162: + upi42->ram_index = val & upi42->rammask; + break; + + /* RAM. */ + case 0x0163: + upi42->ram[upi42->ram_index & upi42->rammask] = val; + break; + + /* Write to command port. */ + case 0x0064: + case 0x0164: + upi42_cmd_write(0, val, upi42); + break; + + /* Input ports. */ + case 0x0180 ... 0x0187: + upi42->ports_in[addr & 0x0007] = val; + break; + + /* Output ports. */ + case 0x0188 ... 0x018f: + upi42->ports_out[addr & 0x0007] = val; + break; + + /* 4 = T0, 5 = T1. */ + case 0x0194: + upi42->t0 = (val >> 4) & 0x01; + upi42->t1 = (val >> 5) & 0x01; + break; + + /* Program counter. */ + case 0x0196: + upi42->pc = (upi42->pc & 0xff00) | val; + break; + case 0x0197: + upi42->pc = (upi42->pc & 0x00ff) | (val << 8); + break; + + /* Input data buffer. */ + case 0x019a: + upi42->dbb_in = val; + break; + + /* Output data buffer. */ + case 0x019b: + upi42->dbb_out = val; + break; + + /* ROM Index. */ + case 0x01a0: + upi42->rom_index = (upi42->rom_index & 0xff00) | val; + break; + case 0x01a1: + upi42->rom_index = (upi42->rom_index & 0x00ff) | (val << 8); + break; + + /* Hard reset. */ + case 0x01a2: + temp_type = upi42->type; + temp_rom = upi42->rom; + upi42_do_init(temp_type, temp_rom); + break; + + /* Soft reset. */ + case 0x01a3: + upi42_reset(upi42); + break; + + /* ROM. */ + case 0x01a4: + upi42->rom[upi42->rom_index & upi42->rommask] = val; + break; + case 0x01a5: + upi42->rom[(upi42->rom_index + 1) & upi42->rommask] = val; + break; + case 0x01a6: + upi42->rom[(upi42->rom_index + 2) & upi42->rommask] = val; + break; + case 0x01a7: + upi42->rom[(upi42->rom_index + 3) & upi42->rommask] = val; + break; + + /* Pause. */ + case 0x01a8: + break; + + /* Resume. */ + case 0x01a9: + break; + + /* Bus master ROM: 0 = direction (0 = to memory, 1 = from memory). */ + case 0x01aa: + if (val & 0x01) { + for (i = 0; i <= upi42->rommask; i += 4) + *(uint32_t *) &(upi42->rom[i]) = mem_readl_phys(upi42->ram_addr + i); + } else { + for (i = 0; i <= upi42->rommask; i += 4) + mem_writel_phys(upi42->ram_addr + i, *(uint32_t *) &(upi42->rom[i])); + } + upi42->bm_stat = (val & 0x01) | 0x02; + break; } } + + +static uint8_t +upi42_read(uint16_t port, void *priv) +{ + upi42_t *upi42 = (upi42_t *) priv; + uint8_t ret = 0xff; + + switch (port) { + /* Type. */ + case 0x015c: + ret = upi42->type & 0xff; + break; + case 0x015d: + ret = upi42->type >> 8; + break; + case 0x015e: + ret = upi42->type >> 16; + break; + case 0x015f: + ret = upi42->type >> 24; + break; + + /* Read from data port and reset OBF. */ + case 0x0060: + case 0x0160: + ret = upi42->dbb_out; + upi42->sts &= ~0x01; /* clear OBF */ + break; + + /* RAM Mask. */ + case 0x0161: + ret = upi42->rammask; + break; + + /* RAM Index. */ + case 0x0162: + ret = upi42->ram_index; + break; + + /* RAM. */ + case 0x0163: + ret = upi42->ram[upi42->ram_index & upi42->rammask]; + break; + + /* Read status. */ + case 0x0064: + case 0x0164: + ret = upi42->sts; + break; + + /* Input ports. */ + case 0x0180 ... 0x0187: + ret = upi42->ports_in[addr & 0x0007]; + break; + + /* Output ports. */ + case 0x0188 ... 0x018f: + ret = upi42->ports_out[addr & 0x0007]; + break; + + /* Accumulator. */ + case 0x0190: + ret = upi42->a; + break; + + /* Timer counter. */ + case 0x0191: + ret = upi42->t; + break; + + /* Program status word. */ + case 0x0192: + ret = upi42->psw; + break; + + /* 0-4 = Prescaler, 5 = TF, 6 = Skip Timer Inc, 7 = Run Timer. */ + case 0x0193: + ret = (upi42->prescaler & 0x1f) || ((upi42->tf & 0x01) << 5) || ((upi42->skip_timer_inc & 0x01) << 6) || ((upi42->run_timer & 0x01) << 7); + break; + + /* 0 = I, 1 = I Raise, 2 = TCNTI Raise, 3 = IRQ Mask, 4 = T0, 5 = T1, 6 = Flags, 7 = DBF. */ + case 0x0194: + ret = (upi42->i & 0x01) || ((upi42->i_raise & 0x01) << 1) || ((upi42->tcnti_raise & 0x01) << 2) || ((upi42->irq_mask & 0x01) << 3) || + ((upi42->t0 & 0x01) << 4) || ((upi42->t1 & 0x01) << 5) || ((upi42->flags & 0x01) << 6) || ((upi42->dbf & 0x01) << 7); + break; + + /* 0 = Suspend. */ + case 0x0195: + ret = (upi42->suspend & 0x01); + break; + + /* Program counter. */ + case 0x0196: + ret = upi42->pc & 0xff; + break; + case 0x0197: + ret = upi42->pc >> 8; + break; + + /* ROM Mask. */ + case 0x0198: + ret = upi42->rommask & 0xff; + break; + case 0x0199: + ret = upi42->rommask >> 8; + break; + + /* Input data buffer. */ + case 0x019a: + ret = upi42->dbb_in; + break; + + /* Output data buffer. */ + case 0x019b: + ret = upi42->dbb_out; + break; + + /* Cycle counter. */ + case 0x019c: + ret = upi42->cycs & 0xff; + break; + case 0x019d: + ret = upi42->cycs >> 8; + break; + case 0x019e: + ret = upi42->cycs >> 16; + break; + case 0x019f: + ret = upi42->cycs >> 24; + break; + + /* ROM Index. */ + case 0x01a0: + ret = upi42->rom_index & 0xff; + break; + case 0x01a1: + ret = upi42->rom_index >> 8; + break; + + /* ROM. */ + case 0x01a4: + ret = upi42->rom[upi42->rom_index & upi42->rommask]; + break; + case 0x01a5: + ret = upi42->rom[(upi42->rom_index + 1) & upi42->rommask]; + break; + case 0x01a6: + ret = upi42->rom[(upi42->rom_index + 2) & upi42->rommask]; + break; + case 0x01a7: + ret = upi42->rom[(upi42->rom_index + 3) & upi42->rommask]; + break; + + /* Bus master status: 0 = direction, 1 = finished. */ + case 0x01ab: + ret = upi42->bm_stat; + break; + } + + return ret; +} +#endif diff --git a/src/video/vid_8514a.c b/src/video/vid_8514a.c index 7f1c7d770..1cb0a5407 100644 --- a/src/video/vid_8514a.c +++ b/src/video/vid_8514a.c @@ -37,22 +37,6 @@ #include <86box/vid_svga_render.h> #include "cpu.h" -#define INT_VSY (1 << 0) -#define INT_GE_BSY (1 << 1) -#define INT_FIFO_OVR (1 << 2) -#define INT_FIFO_EMP (1 << 3) -#define INT_MASK 0xf - -#define FIFO_MASK (FIFO_SIZE - 1) -#define FIFO_ENTRY_SIZE (1 << 31) - -#define FIFO_ENTRIES_8514 (dev->fifo_write_idx - dev->fifo_read_idx) -#define FIFO_FULL_8514 ((dev->fifo_write_idx - dev->fifo_read_idx) >= FIFO_SIZE) -#define FIFO_EMPTY_8514 (dev->fifo_read_idx == dev->fifo_write_idx) - -#define FIFO_TYPE_8514 0xff000000 -#define FIFO_ADDR_8514 0x00ffffff - static void ibm8514_accel_out_fifo(ibm8514_t *dev, uint16_t port, uint32_t val, int len); static void ibm8514_accel_outb(uint16_t port, uint8_t val, void *p); static void ibm8514_accel_outw(uint16_t port, uint16_t val, void *p); @@ -368,17 +352,14 @@ ibm8514_accel_out_fifo(ibm8514_t *dev, uint16_t port, uint32_t val, int len) case 0x82e8: case 0xc2e8: if (len == 1) { - dev->accel.cur_y_bit12 = (dev->accel.cur_y_bit12 & 0xf00) | val; dev->accel.cur_y = (dev->accel.cur_y & 0x700) | val; } else { - dev->accel.cur_y_bit12 = val & 0xfff; dev->accel.cur_y = val & 0x7ff; } break; case 0x82e9: case 0xc2e9: if (len == 1) { - dev->accel.cur_y_bit12 = (dev->accel.cur_y_bit12 & 0xff) | ((val & 0x0f) << 8); dev->accel.cur_y = (dev->accel.cur_y & 0xff) | ((val & 0x07) << 8); } break; @@ -386,17 +367,14 @@ ibm8514_accel_out_fifo(ibm8514_t *dev, uint16_t port, uint32_t val, int len) case 0x86e8: case 0xc6e8: if (len == 1) { - dev->accel.cur_x_bit12 = (dev->accel.cur_x_bit12 & 0xf00) | val; dev->accel.cur_x = (dev->accel.cur_x & 0x700) | val; } else { - dev->accel.cur_x_bit12 = val & 0xfff; dev->accel.cur_x = val & 0x7ff; } break; case 0x86e9: case 0xc6e9: if (len == 1) { - dev->accel.cur_x_bit12 = (dev->accel.cur_x_bit12 & 0xff) | ((val & 0x0f) << 8); dev->accel.cur_x = (dev->accel.cur_x & 0xff) | ((val & 0x07) << 8); } break; @@ -448,7 +426,7 @@ ibm8514_accel_out_fifo(ibm8514_t *dev, uint16_t port, uint32_t val, int len) else { dev->accel.err_term = val & 0x3fff; if (val & 0x2000) - dev->accel.err_term |= ~0x3fff; + dev->accel.err_term |= ~0x1fff; } break; case 0x92e9: @@ -456,7 +434,7 @@ ibm8514_accel_out_fifo(ibm8514_t *dev, uint16_t port, uint32_t val, int len) if (len == 1) { dev->accel.err_term = (dev->accel.err_term & 0xff) | ((val & 0x3f) << 8); if (val & 0x20) - dev->accel.err_term |= ~0x3fff; + dev->accel.err_term |= ~0x1fff; } break; @@ -684,7 +662,6 @@ static void ibm8514_ramdac_out(uint16_t port, uint8_t val, void *p) { svga_t *svga = (svga_t *)p; - uint8_t index; switch (port) { case 0x2ea: @@ -707,7 +684,6 @@ ibm8514_ramdac_in(uint16_t port, void *p) { svga_t *svga = (svga_t *)p; uint8_t ret = 0xff; - uint8_t index; switch (port) { case 0x2ea: @@ -727,62 +703,6 @@ ibm8514_ramdac_in(uint16_t port, void *p) return ret; } -static void -ibm8514_io_remove(svga_t *svga) -{ - io_removehandler(0x2e8, 0x0002, ibm8514_accel_inb, ibm8514_accel_inw, NULL, ibm8514_accel_outb, ibm8514_accel_outw, NULL, svga); - io_removehandler(0x2ea, 0x0004, ibm8514_ramdac_in, NULL, NULL, ibm8514_ramdac_out, NULL, NULL, svga); - io_removehandler(0x6e8, 0x0002, ibm8514_accel_inb, ibm8514_accel_inw, NULL, ibm8514_accel_outb, ibm8514_accel_outw, NULL, svga); - io_removehandler(0xae8, 0x0002, ibm8514_accel_inb, ibm8514_accel_inw, NULL, ibm8514_accel_outb, ibm8514_accel_outw, NULL, svga); - io_removehandler(0xee8, 0x0002, ibm8514_accel_inb, ibm8514_accel_inw, NULL, ibm8514_accel_outb, ibm8514_accel_outw, NULL, svga); - io_removehandler(0x12e8, 0x0002, ibm8514_accel_inb, ibm8514_accel_inw, NULL, ibm8514_accel_outb, ibm8514_accel_outw, NULL, svga); - io_removehandler(0x16e8, 0x0002, ibm8514_accel_inb, ibm8514_accel_inw, NULL, ibm8514_accel_outb, ibm8514_accel_outw, NULL, svga); - io_removehandler(0x1ae8, 0x0002, ibm8514_accel_inb, ibm8514_accel_inw, NULL, ibm8514_accel_outb, ibm8514_accel_outw, NULL, svga); - io_removehandler(0x1ee8, 0x0002, ibm8514_accel_inb, ibm8514_accel_inw, NULL, ibm8514_accel_outb, ibm8514_accel_outw, NULL, svga); - io_removehandler(0x22e8, 0x0002, ibm8514_accel_inb, ibm8514_accel_inw, NULL, ibm8514_accel_outb, ibm8514_accel_outw, NULL, svga); - io_removehandler(0x26e8, 0x0002, ibm8514_accel_inb, ibm8514_accel_inw, NULL, ibm8514_accel_outb, ibm8514_accel_outw, NULL, svga); - io_removehandler(0x2ee8, 0x0002, ibm8514_accel_inb, ibm8514_accel_inw, NULL, ibm8514_accel_outb, ibm8514_accel_outw, NULL, svga); - io_removehandler(0x42e8, 0x0002, ibm8514_accel_inb, ibm8514_accel_inw, NULL, ibm8514_accel_outb, ibm8514_accel_outw, NULL, svga); - io_removehandler(0x4ae8, 0x0002, ibm8514_accel_inb, ibm8514_accel_inw, NULL, ibm8514_accel_outb, ibm8514_accel_outw, NULL, svga); - io_removehandler(0x52e8, 0x0002, ibm8514_accel_inb, ibm8514_accel_inw, NULL, ibm8514_accel_outb, ibm8514_accel_outw, NULL, svga); - io_removehandler(0x56e8, 0x0002, ibm8514_accel_inb, ibm8514_accel_inw, NULL, ibm8514_accel_outb, ibm8514_accel_outw, NULL, svga); - io_removehandler(0x5ae8, 0x0002, ibm8514_accel_inb, ibm8514_accel_inw, NULL, ibm8514_accel_outb, ibm8514_accel_outw, NULL, svga); - io_removehandler(0x5ee8, 0x0002, ibm8514_accel_inb, ibm8514_accel_inw, NULL, ibm8514_accel_outb, ibm8514_accel_outw, NULL, svga); - io_removehandler(0x82e8, 0x0002, ibm8514_accel_inb, ibm8514_accel_inw, NULL, ibm8514_accel_outb, ibm8514_accel_outw, NULL, svga); - io_removehandler(0x86e8, 0x0002, ibm8514_accel_inb, ibm8514_accel_inw, NULL, ibm8514_accel_outb, ibm8514_accel_outw, NULL, svga); - io_removehandler(0x8ae8, 0x0002, ibm8514_accel_inb, ibm8514_accel_inw, NULL, ibm8514_accel_outb, ibm8514_accel_outw, NULL, svga); - io_removehandler(0x8ee8, 0x0002, ibm8514_accel_inb, ibm8514_accel_inw, NULL, ibm8514_accel_outb, ibm8514_accel_outw, NULL, svga); - io_removehandler(0x92e8, 0x0002, ibm8514_accel_inb, ibm8514_accel_inw, NULL, ibm8514_accel_outb, ibm8514_accel_outw, NULL, svga); - io_removehandler(0x96e8, 0x0002, ibm8514_accel_inb, ibm8514_accel_inw, NULL, ibm8514_accel_outb, ibm8514_accel_outw, NULL, svga); - io_removehandler(0x9ae8, 0x0002, ibm8514_accel_inb, ibm8514_accel_inw, NULL, ibm8514_accel_outb, ibm8514_accel_outw, NULL, svga); - io_removehandler(0x9ee8, 0x0002, ibm8514_accel_inb, ibm8514_accel_inw, NULL, ibm8514_accel_outb, ibm8514_accel_outw, NULL, svga); - io_removehandler(0xa2e8, 0x0002, ibm8514_accel_inb, ibm8514_accel_inw, NULL, ibm8514_accel_outb, ibm8514_accel_outw, NULL, svga); - io_removehandler(0xa6e8, 0x0002, ibm8514_accel_inb, ibm8514_accel_inw, NULL, ibm8514_accel_outb, ibm8514_accel_outw, NULL, svga); - io_removehandler(0xaae8, 0x0002, ibm8514_accel_inb, ibm8514_accel_inw, NULL, ibm8514_accel_outb, ibm8514_accel_outw, NULL, svga); - io_removehandler(0xaee8, 0x0002, ibm8514_accel_inb, ibm8514_accel_inw, NULL, ibm8514_accel_outb, ibm8514_accel_outw, NULL, svga); - io_removehandler(0xb2e8, 0x0002, ibm8514_accel_inb, ibm8514_accel_inw, NULL, ibm8514_accel_outb, ibm8514_accel_outw, NULL, svga); - io_removehandler(0xb6e8, 0x0002, ibm8514_accel_inb, ibm8514_accel_inw, NULL, ibm8514_accel_outb, ibm8514_accel_outw, NULL, svga); - io_removehandler(0xbae8, 0x0002, ibm8514_accel_inb, ibm8514_accel_inw, NULL, ibm8514_accel_outb, ibm8514_accel_outw, NULL, svga); - io_removehandler(0xbee8, 0x0002, ibm8514_accel_inb, ibm8514_accel_inw, NULL, ibm8514_accel_outb, ibm8514_accel_outw, NULL, svga); - io_removehandler(0xe2e8, 0x0002, ibm8514_accel_inb, ibm8514_accel_inw, NULL, ibm8514_accel_outb, ibm8514_accel_outw, NULL, svga); - - io_removehandler(0xc2e8, 0x0002, ibm8514_accel_inb, ibm8514_accel_inw, NULL, ibm8514_accel_outb, ibm8514_accel_outw, NULL, svga); - io_removehandler(0xc6e8, 0x0002, ibm8514_accel_inb, ibm8514_accel_inw, NULL, ibm8514_accel_outb, ibm8514_accel_outw, NULL, svga); - io_removehandler(0xcae8, 0x0002, ibm8514_accel_inb, ibm8514_accel_inw, NULL, ibm8514_accel_outb, ibm8514_accel_outw, NULL, svga); - io_removehandler(0xcee8, 0x0002, ibm8514_accel_inb, ibm8514_accel_inw, NULL, ibm8514_accel_outb, ibm8514_accel_outw, NULL, svga); - io_removehandler(0xd2e8, 0x0002, ibm8514_accel_inb, ibm8514_accel_inw, NULL, ibm8514_accel_outb, ibm8514_accel_outw, NULL, svga); - io_removehandler(0xd6e8, 0x0002, ibm8514_accel_inb, ibm8514_accel_inw, NULL, ibm8514_accel_outb, ibm8514_accel_outw, NULL, svga); - io_removehandler(0xdae8, 0x0002, ibm8514_accel_inb, ibm8514_accel_inw, NULL, ibm8514_accel_outb, ibm8514_accel_outw, NULL, svga); - io_removehandler(0xdee8, 0x0002, ibm8514_accel_inb, ibm8514_accel_inw, NULL, ibm8514_accel_outb, ibm8514_accel_outw, NULL, svga); - io_removehandler(0xe6e8, 0x0002, ibm8514_accel_inb, ibm8514_accel_inw, NULL, ibm8514_accel_outb, ibm8514_accel_outw, NULL, svga); - io_removehandler(0xeae8, 0x0002, ibm8514_accel_inb, ibm8514_accel_inw, NULL, ibm8514_accel_outb, ibm8514_accel_outw, NULL, svga); - io_removehandler(0xeee8, 0x0002, ibm8514_accel_inb, ibm8514_accel_inw, NULL, ibm8514_accel_outb, ibm8514_accel_outw, NULL, svga); - io_removehandler(0xf2e8, 0x0002, ibm8514_accel_inb, ibm8514_accel_inw, NULL, ibm8514_accel_outb, ibm8514_accel_outw, NULL, svga); - io_removehandler(0xf6e8, 0x0002, ibm8514_accel_inb, ibm8514_accel_inw, NULL, ibm8514_accel_outb, ibm8514_accel_outw, NULL, svga); - io_removehandler(0xfae8, 0x0002, ibm8514_accel_inb, ibm8514_accel_inw, NULL, ibm8514_accel_outb, ibm8514_accel_outw, NULL, svga); - io_removehandler(0xfee8, 0x0002, ibm8514_accel_inb, ibm8514_accel_inw, NULL, ibm8514_accel_outb, ibm8514_accel_outw, NULL, svga); -} - static void ibm8514_io_set(svga_t *svga) { @@ -1117,8 +1037,6 @@ ibm8514_short_stroke_start(int count, int cpu_input, uint32_t mix_dat, uint32_t ibm8514_accel_start(count, cpu_input, mix_dat, cpu_dat, dev, len); } -#define SWAP(a,b) { tmpswap = a; a = b; b = tmpswap; } - static void ibm8514_accel_start(int count, int cpu_input, uint32_t mix_dat, uint32_t cpu_dat, ibm8514_t *dev, int len) { @@ -1139,7 +1057,6 @@ ibm8514_accel_start(int count, int cpu_input, uint32_t mix_dat, uint32_t cpu_dat uint32_t old_mix_dat; int and3 = dev->accel.cur_x & 3; uint8_t poly_src = 0; - int16_t tmpswap; if (dev->accel.cmd & 0x100) { dev->force_busy = 1; @@ -2717,7 +2634,7 @@ bitblt_pix: break; } - READ(dev->accel.dest + dev->accel.cx, dest_dat); + READ(dev->accel.dest + dev->accel.dx, dest_dat); if ((compare_mode == 0) || ((compare_mode == 0x10) && (dest_dat >= compare)) || @@ -2729,7 +2646,7 @@ bitblt_pix: old_dest_dat = dest_dat; MIX(mix_dat & mix_mask, dest_dat, src_dat); dest_dat = (dest_dat & wrt_mask) | (old_dest_dat & ~wrt_mask); - WRITE(dev->accel.dest + dev->accel.cx, dest_dat); + WRITE(dev->accel.dest + dev->accel.dx, dest_dat); } } diff --git a/src/video/vid_xga.c b/src/video/vid_xga.c index 60e6f3d67..40f0aa6aa 100644 --- a/src/video/vid_xga.c +++ b/src/video/vid_xga.c @@ -445,7 +445,6 @@ xga_ext_inb(uint16_t addr, void *p) svga_t *svga = (svga_t *)p; xga_t *xga = &svga->xga; uint8_t ret, index; - uint16_t sprite_idx; switch (addr & 0x0f) { case 0: @@ -898,7 +897,7 @@ xga_short_stroke(svga_t *svga, uint8_t ssv) uint32_t srcbase = xga->accel.px_map_base[xga->accel.src_map]; int y = ssv & 0x0f; int x = 0; - int dx, dy, dirx, diry; + int dx, dy, dirx = 0, diry = 0; dx = xga->accel.dst_map_x & 0x1fff; if (xga->accel.dst_map_x & 0x1800) @@ -1916,7 +1915,7 @@ xga_memio_writel(uint32_t addr, uint32_t val, void *p) static uint8_t xga_mem_read(uint32_t addr, xga_t *xga, svga_t *svga) { - uint8_t temp; + uint8_t temp = 0xff; addr &= 0x1fff; @@ -2031,19 +2030,16 @@ static void xga_hwcursor_draw(svga_t *svga, int displine) { xga_t *xga = &svga->xga; - uint8_t dat; + uint8_t dat = 0; int offset = xga->hwcursor_latch.x - xga->hwcursor_latch.xoff; int x, x_pos, y_pos; - int comb; + int comb = 0; uint32_t *p; - uint8_t *cd; int idx = (xga->cursor_data_on) ? 32 : 0; if (xga->interlace && xga->hwcursor_oddeven) xga->hwcursor_latch.addr += 16; - cd = (uint8_t *) xga->sprite_data; - y_pos = displine; x_pos = offset + svga->x_add; p = buffer32->line[y_pos]; @@ -2155,7 +2151,6 @@ xga_render_16bpp(xga_t *xga, svga_t *svga) int x; uint32_t *p; uint32_t dat; - uint32_t addr; if ((xga->displine + svga->y_add) < 0) return; @@ -2169,7 +2164,7 @@ xga_render_16bpp(xga_t *xga, svga_t *svga) for (x = 0; x <= (xga->h_disp); x += 8) { dat = *(uint32_t *)(&xga->vram[(xga->ma + (x << 1)) & xga->vram_mask]); - p[x] = video_16to32[dat & 0xffff]; + p[x] = video_16to32[dat & 0xffff]; p[x + 1] = video_16to32[dat >> 16]; dat = *(uint32_t *)(&xga->vram[(xga->ma + (x << 1) + 4) & xga->vram_mask]); @@ -2215,9 +2210,6 @@ xga_write(uint32_t addr, uint8_t val, void *p) static void xga_writeb(uint32_t addr, uint8_t val, void *p) { - svga_t *svga = (svga_t *)p; - xga_t *xga = &svga->xga; - //pclog("[%04X:%08X]: WriteB\n", CS, cpu_state.pc); xga_write(addr, val, p); } @@ -2225,9 +2217,6 @@ xga_writeb(uint32_t addr, uint8_t val, void *p) static void xga_writew(uint32_t addr, uint16_t val, void *p) { - svga_t *svga = (svga_t *)p; - xga_t *xga = &svga->xga; - //pclog("[%04X:%08X]: WriteW\n", CS, cpu_state.pc); xga_write(addr, val, p); xga_write(addr + 1, val >> 8, p); @@ -2236,9 +2225,6 @@ xga_writew(uint32_t addr, uint16_t val, void *p) static void xga_writel(uint32_t addr, uint32_t val, void *p) { - svga_t *svga = (svga_t *)p; - xga_t *xga = &svga->xga; - //pclog("[%04X:%08X]: WriteL\n", CS, cpu_state.pc); xga_write(addr, val, p); xga_write(addr + 1, val >> 8, p); @@ -2344,8 +2330,6 @@ xga_read(uint32_t addr, void *p) static uint8_t xga_readb(uint32_t addr, void *p) { - svga_t *svga = (svga_t *)p; - xga_t *xga = &svga->xga; uint8_t ret; ret = xga_read(addr, p); @@ -2356,8 +2340,6 @@ xga_readb(uint32_t addr, void *p) static uint16_t xga_readw(uint32_t addr, void *p) { - svga_t *svga = (svga_t *)p; - xga_t *xga = &svga->xga; uint16_t ret; ret = xga_read(addr, p); @@ -2369,8 +2351,6 @@ xga_readw(uint32_t addr, void *p) static uint32_t xga_readl(uint32_t addr, void *p) { - svga_t *svga = (svga_t *)p; - xga_t *xga = &svga->xga; uint32_t ret; ret = xga_read(addr, p); @@ -2665,16 +2645,11 @@ xga_mca_feedb(void *priv) } static void -xga_pos_out(uint16_t addr, uint8_t val, void *priv) +xga_mca_reset(void *p) { - svga_t *svga = (svga_t *)priv; - xga_t *xga = &svga->xga; + svga_t *svga = (svga_t *)p; - mem_mapping_disable(&svga->mapping); - if (val & 0x08) { - mem_mapping_enable(&svga->mapping); - xga_updatemapping(svga); - } + xga_mca_write(0x102, 0, svga); } static uint8_t @@ -2692,6 +2667,7 @@ static void xga_t *xga = &svga->xga; FILE *f; uint32_t temp; + uint32_t initial_bios_addr = device_get_config_hex20("init_bios_addr"); uint8_t *rom = NULL; xga->type = device_get_config_int("type"); @@ -2704,7 +2680,7 @@ static void xga->on = 0; xga->hwcursor.cur_xsize = 64; xga->hwcursor.cur_ysize = 64; - xga->bios_rom.sz = 0x8000; + xga->bios_rom.sz = 0x2000; f = rom_fopen(xga->type ? XGA2_BIOS_PATH : XGA_BIOS_PATH, "rb"); (void)fseek(f, 0L, SEEK_END); @@ -2729,7 +2705,7 @@ static void xga->instance = 0; xga->rom_addr = 0; mem_mapping_add(&xga->bios_rom.mapping, - 0xd8000, xga->bios_rom.sz, + initial_bios_addr, xga->bios_rom.sz, rom_read, rom_readw, rom_readl, NULL, NULL, NULL, xga->bios_rom.rom, MEM_MAPPING_EXTERNAL, &xga->bios_rom); @@ -2759,7 +2735,7 @@ static void xga->pos_regs[1] = 0x8f; if (xga->bus & DEVICE_MCA) { - mca_add(xga_mca_read, xga_mca_write, xga_mca_feedb, NULL, svga); + mca_add(xga_mca_read, xga_mca_write, xga_mca_feedb, xga_mca_reset, svga); } else { io_sethandler(0x0100, 0x0008, xga_pos_in, NULL, NULL, NULL, NULL, NULL, svga); io_sethandler(0x2100 + (xga->instance << 4), 0x0010, xga_ext_inb, NULL, NULL, xga_ext_outb, NULL, NULL, svga); @@ -2805,6 +2781,25 @@ xga_force_redraw(void *p) static const device_config_t xga_configuration[] = { // clang-format off + { + .name = "init_bios_addr", + .description = "Initial MCA BIOS Address (before POS configuration)", + .type = CONFIG_HEX20, + .default_string = "", + .default_int = 0xc0000, + .file_filter = "", + .spinner = { 0 }, + .selection = { + { .description = "C000H", .value = 0xc0000 }, + { .description = "C800H", .value = 0xc8000 }, + { .description = "CC00H", .value = 0xcc000 }, + { .description = "D000H", .value = 0xd0000 }, + { .description = "D400H", .value = 0xd4000 }, + { .description = "D800H", .value = 0xd8000 }, + { .description = "DC00H", .value = 0xdc000 }, + { .description = "" } + }, + }, { .name = "type", .description = "XGA type",