Now more Windows-friendly

- cpu_thread now stops and waits on a pthread condition variable, rather
  than sleep(1)ing and waiting to be pthread_kill()'d. Signals don't
  work well on Windows, apparently.
- fopen() now open binary files with the "b" mode
- the keymap red-black tree no longer casts pointers to ints, because
  mingw/gcc complains about it
- added a dumb batch script to compile the sdl gui on windows
- {n,h}to{h,n}{s,l,ll} is now handled better on windows
This commit is contained in:
Peter Rutenbar 2014-06-14 00:19:08 -04:00
parent 952fe7ae89
commit 1bee24316c
14 changed files with 157 additions and 98 deletions

View File

@ -32,7 +32,7 @@
#include "shoebill.h"
void symb_inorder(rb_node *cur) {
const coff_symbol *sym = (coff_symbol*)cur->value;
const coff_symbol *sym = *(coff_symbol**)&cur[1];
if (!sym)
return ;
symb_inorder(cur->left);
@ -177,7 +177,7 @@ coff_file* coff_parse(uint8_t *buf, uint32_t buflen, alloc_pool_t *parent_pool)
if (cf->num_symbols == 0) // if num_symbols==0, symtab_offset may be bogus
return cf; // just return
cf->func_tree = rb_new(cf->pool);
cf->func_tree = rb_new(cf->pool, sizeof(coff_symbol*));
//slog("func_tree = %llx, *func_tree = %llx\n", cf->func_tree, *cf->func_tree);
cf->symbols = (coff_symbol*)p_alloc(cf->pool, sizeof(coff_symbol) *cf->num_symbols);
@ -242,7 +242,8 @@ coff_file* coff_parse(uint8_t *buf, uint32_t buflen, alloc_pool_t *parent_pool)
if (cf->symbols[i].sclass == 2 || cf->symbols[i].sclass == 3) {
rb_insert(cf->func_tree, cf->symbols[i].value, &cf->symbols[i], NULL);
void *ptr = &cf->symbols[i];
rb_insert(cf->func_tree, cf->symbols[i].value, &ptr, NULL);
//slog("%s addr=0x%x\n", cf->symbols[i].name, cf->symbols[i].value);
}
// slog("%u: %s (class=%u)\n", i+1, cf->symbols[i].name, cf->symbols[i].sclass);
@ -274,7 +275,7 @@ fail:
coff_file* coff_parse_from_path(const char *path, alloc_pool_t *parent_pool)
{
FILE *f = fopen(path, "r");
FILE *f = fopen(path, "rb");
uint8_t *buf = malloc(1);
uint32_t i=0, tmp;
coff_file *coff;
@ -343,11 +344,11 @@ coff_symbol* coff_find_func(coff_file *coff, uint32_t addr)
if (addr < cur->key)
cur = cur->left;
else if (addr > cur->key) {
last = cur->value;
last = *(coff_symbol**)&cur[1];
cur = cur->right;
}
else
return cur->value;
return *(coff_symbol**)&cur[1];
}
return last;

View File

@ -32,6 +32,7 @@
#include <unistd.h>
#include <signal.h>
#include <stdarg.h>
#include <time.h>
#include "../core/shoebill.h"
@ -55,14 +56,16 @@ void shoebill_stop()
pthread_join(shoe.via_thread_pid, NULL);
pthread_mutex_destroy(&shoe.via_clock_thread_lock);
pthread_kill(shoe.cpu_thread_pid, SIGUSR2); // wake up the CPU thread if it was STOPPED
pthread_mutex_lock(&shoe.cpu_thread_lock);
pthread_mutex_unlock(&shoe.cpu_thread_lock);
unstop_cpu_thread(); // wake up the CPU thread if it was STOPPED
pthread_join(shoe.cpu_thread_pid, NULL);
pthread_mutex_destroy(&shoe.cpu_thread_lock);
pthread_mutex_destroy(&shoe.via_cpu_lock);
pthread_mutex_destroy(&shoe.cpu_stop_mutex);
pthread_cond_destroy(&shoe.cpu_stop_cond);
shoe.running = 0;
// Close all the SCSI disk images
@ -79,15 +82,30 @@ void shoebill_stop()
memset(&shoe, 0, sizeof(shoe));
}
void _sigusr2 (int p)
static void _await_interrupt (void)
{
return ;
struct timeval now;
struct timespec later;
assert(pthread_mutex_lock(&shoe.cpu_stop_mutex) == 0);
gettimeofday(&now, NULL);
later.tv_sec = now.tv_sec;
later.tv_nsec = (now.tv_usec * 1000) + (1000000000 / 60);
if (later.tv_nsec >= 1000000000) {
later.tv_nsec -= 1000000000;
later.tv_sec++;
}
/* Only wait for (1/60) seconds - an interrupt should have fired by then */
pthread_cond_timedwait(&shoe.cpu_stop_cond,
&shoe.cpu_stop_mutex,
&later);
assert(pthread_mutex_unlock(&shoe.cpu_stop_mutex) == 0);
}
void *_cpu_thread (void *arg)
{
signal(SIGUSR2, _sigusr2);
pthread_mutex_lock(&shoe.cpu_thread_lock);
while (1) {
@ -105,7 +123,7 @@ void *_cpu_thread (void *arg)
}
if (shoe.cpu_thread_notifications & SHOEBILL_STATE_STOPPED) {
sleep(1);
_await_interrupt();
continue;
}
}
@ -364,7 +382,7 @@ static uint32_t _load_rom (shoebill_config_t *config, uint8_t **_rom_data, uint3
{
uint32_t i, rom_size;
uint8_t *rom_data = (uint8_t*)p_alloc(shoe.pool, 64 * 1024);
FILE *f = fopen(config->rom_path, "r");
FILE *f = fopen(config->rom_path, "rb");
if (f == NULL) {
sprintf(config->error_msg, "Couldn't open rom path [%s]\n", config->rom_path);
@ -429,7 +447,7 @@ static uint32_t _open_disk_images (shoebill_config_t *config, scsi_device_t *dis
if (!path) continue;
FILE *f = fopen(path, "r+");
FILE *f = fopen(path, "r+b");
if (f == NULL) {
sprintf(config->error_msg, "Couldn't open scsi id #%u disk [%s]\n", i, path);
@ -757,15 +775,19 @@ uint32_t shoebill_initialize(shoebill_config_t *config)
memcpy(shoe.scsi_devices, disks, 8 * sizeof(scsi_device_t));
pthread_mutex_init(&shoe.via_cpu_lock, NULL);
pthread_mutex_init(&shoe.via_clock_thread_lock, NULL);
pthread_mutex_lock(&shoe.via_clock_thread_lock);
pthread_create(&shoe.via_thread_pid, NULL, via_clock_thread, NULL);
/*
* config->debug_mode is a hack - the debugger implements its own CPU thread
*/
pthread_cond_init(&shoe.cpu_stop_cond, NULL);
pthread_mutex_init(&shoe.cpu_stop_mutex, NULL);
pthread_mutex_init(&shoe.cpu_thread_lock, NULL);
pthread_mutex_lock(&shoe.cpu_thread_lock);
if (!config->debug_mode)
pthread_create(&shoe.cpu_thread_pid, NULL, _cpu_thread, NULL);
@ -861,7 +883,7 @@ void shoebill_restart (void)
assert(coff && "can't parse the kernel");
// Re-open the root disk image
shoe.scsi_devices[0].f = fopen(shoe.scsi_devices[0].image_path, "r+");
shoe.scsi_devices[0].f = fopen(shoe.scsi_devices[0].image_path, "r+b");
assert(shoe.scsi_devices[0].f && "couldn't reopen the disk image at scsi id #0"); // FIXME: and this
shoe.coff = coff;

View File

@ -207,7 +207,7 @@ static disk_t* open_disk (const char *disk_path, char *error_str)
disk->error_str = error_str;
disk->path = disk_path;
f = fopen(disk_path, "r");
f = fopen(disk_path, "rb");
if (f == NULL) {
sprintf(error_str, "Can't open that path");
goto fail;
@ -1306,7 +1306,7 @@ done:
if (!buf)
return 0;
FILE *f = fopen("result", "w");
FILE *f = fopen("result", "wb");
fwrite(buf, size, 1, f);
fclose(f);

View File

@ -81,15 +81,15 @@ void inst_mc68851_pflushr(uint16_t ext){
verify_supervisor();
slog("pflushr!");
// Just nuke the entire cache
bzero(shoe.pmmu_cache[0].valid_map, PMMU_CACHE_SIZE/8);
bzero(shoe.pmmu_cache[1].valid_map, PMMU_CACHE_SIZE/8);
memset(shoe.pmmu_cache[0].valid_map, 0, PMMU_CACHE_SIZE/8);
memset(shoe.pmmu_cache[1].valid_map, 0, PMMU_CACHE_SIZE/8);
}
void inst_mc68851_pflush(uint16_t ext){
verify_supervisor();
slog("pflush!");
bzero(shoe.pmmu_cache[0].valid_map, PMMU_CACHE_SIZE/8);
bzero(shoe.pmmu_cache[1].valid_map, PMMU_CACHE_SIZE/8);
memset(shoe.pmmu_cache[0].valid_map, 0, PMMU_CACHE_SIZE/8);
memset(shoe.pmmu_cache[1].valid_map, 0, PMMU_CACHE_SIZE/8);
// slog("%s: Error, not implemented!\n", __func__);
}

View File

@ -24,20 +24,10 @@
*/
#include <stdio.h>
#include <arpa/inet.h>
#include <assert.h>
#include <stdlib.h>
#include "../core/shoebill.h"
#ifdef __APPLE__
#include <machine/endian.h>
#include <libkern/OSByteOrder.h>
#define ntohll(x) OSSwapBigToHostInt64(x)
#elif (__BYTE_ORDER__ == __ORDER_LITTLE_ENDIAN__)
#define ntohll(_x) ({uint64_t x = (_x); (((uint64_t)ntohl((uint32_t)x))<<32) | ntohl(x>>32);})
#endif
/* --- Physical_get jump table --- */
#pragma mark Physical_get jump table

View File

@ -26,31 +26,33 @@
#include <stdio.h>
#include <stdlib.h>
#include <assert.h>
#include <string.h>
#include "shoebill.h"
// Create a new red-black tree
// (just return an empty black leaf pointer)
rb_tree* rb_new(alloc_pool_t *parent_pool)
// Create a new red-black tree
rb_tree* rb_new(alloc_pool_t *parent_pool, uint32_t sz)
{
alloc_pool_t *pool = p_new_pool(parent_pool);
rb_tree *tree = (rb_tree*)p_alloc(pool, sizeof(rb_tree));
tree->root = NULL;
tree->pool = pool;
tree->sz = sz;
return tree;
}
// Insert a new key/value into the tree
// Insert a new key/value into the tree
// (and return the old value if *old_value is non-null.)
// Returns true if the key already existed.
uint8_t rb_insert(rb_tree *tree, rb_key_t key, rb_value_t value, rb_value_t *old_value)
uint8_t rb_insert(rb_tree *tree, rb_key_t key, void *value, void *old_value)
{
const uint32_t alloc_size = sizeof(rb_node) + tree->sz;
rb_node **root = &tree->root;
// Special edge case: insert the root node if tree's empty
if (*root == NULL) {
*root = p_alloc(tree->pool, sizeof(rb_node));
*root = p_alloc(tree->pool, alloc_size);
(*root)->key = key;
(*root)->value = value;
memcpy(&(*root)[1], value, tree->sz);
return 0;
}
@ -63,19 +65,19 @@ uint8_t rb_insert(rb_tree *tree, rb_key_t key, rb_value_t value, rb_value_t *old
else if (key > (*cur)->key) // right
cur = &((*cur)->right);
else { // the key already exists
if (old_value)
*old_value = (*cur)->value;
(*cur)->value = value;
if (old_value)
memcpy(old_value, &(*cur)[1], tree->sz);
memcpy(&(*cur)[1], value, tree->sz);
return 1; // 1 => the key already existed
}
}
// insert
*cur = p_alloc(tree->pool, sizeof(rb_node));
*cur = p_alloc(tree->pool, alloc_size);
(*cur)->parent = parent;
(*cur)->key = key;
(*cur)->value = value;
(*cur)->is_red = 1;
memcpy(&(*cur)[1], value, tree->sz);
// resolve
@ -118,7 +120,7 @@ uint8_t rb_insert(rb_tree *tree, rb_key_t key, rb_value_t value, rb_value_t *old
uint8_t mycase = ((gparent->left==parent)?0:1);
mycase = (mycase << 1) | ((parent->left==red)?0:1);
switch (mycase) {
case 0: {// LLb
rb_node *Br = parent->right;
*gparent_ptr = parent;
@ -130,11 +132,11 @@ uint8_t rb_insert(rb_tree *tree, rb_key_t key, rb_value_t value, rb_value_t *old
parent->parent = gparent->parent;
gparent->parent = parent;
if (Br) Br->parent = gparent;
red = gparent->right; // gparent became red, gparent->left is black, check gparent->right
break ;
}
case 1: {// LRb
case 1: {// LRb
rb_node *Cl = red->left;
rb_node *Cr = red->right;
*gparent_ptr = red;
@ -170,7 +172,7 @@ uint8_t rb_insert(rb_tree *tree, rb_key_t key, rb_value_t value, rb_value_t *old
parent->parent = red;
if (Cr) Cr->parent = parent;
if (Cl) Cl->parent = gparent;
red = gparent->left;
break;
}
@ -191,24 +193,24 @@ uint8_t rb_insert(rb_tree *tree, rb_key_t key, rb_value_t value, rb_value_t *old
}
}
}
(*root)->is_red = 0; // make double-sure root is red
return 0;
}
// Find a value given a key
uint8_t rb_find (rb_tree *tree, rb_key_t key, rb_value_t *value)
uint8_t rb_find (rb_tree *tree, rb_key_t key, void *value)
{
rb_node *cur = tree->root;
while (cur) {
if (key < cur->key)
if (key < cur->key)
cur = cur->left;
else if (key > cur->key)
cur = cur->right;
else {
if (value)
*value = cur->value;
memcpy(value, &cur[1], tree->sz);
return 1;
}
}
@ -217,28 +219,30 @@ uint8_t rb_find (rb_tree *tree, rb_key_t key, rb_value_t *value)
uint8_t _rb_index (rb_node *cur, uint32_t *index, rb_node **result)
{
if (!cur)
if (!cur)
return 0;
else if (_rb_index(cur->left, index, result) == 1)
else if (_rb_index(cur->left, index, result) == 1)
return 1;
else if (0 == *index) {
*result = cur;
return 1;
}
--*index;
return _rb_index(cur->right, index, result);
}
// Do an in-order traversal, and retrieve the (index)th sorted key/value
uint8_t rb_index (rb_tree *tree, uint32_t index, rb_key_t *key, rb_value_t *value)
uint8_t rb_index (rb_tree *tree, uint32_t index, rb_key_t *key, void *value)
{
rb_node *cur = tree->root, *result;
if (_rb_index(cur, &index, &result)) {
if (key) *key = result->key;
if (value) *value = result->value;
if (key)
*key = result->key;
if (value)
memcpy(value, &result[1], tree->sz);
return 1;
}
return 0;
@ -247,7 +251,7 @@ uint8_t rb_index (rb_tree *tree, uint32_t index, rb_key_t *key, rb_value_t *valu
// Count the number of nodes in the tree
static uint32_t _rb_count (rb_node *node)
{
if (!node)
if (!node)
return 0;
return 1 + _rb_count(node->left) + _rb_count(node->right);
}
@ -256,7 +260,7 @@ uint32_t rb_count (rb_tree *tree)
{
return _rb_count(tree->root);
}
// Free all the nodes (and the rb_tree ptr itself)
void rb_free (rb_tree *tree)
{

View File

@ -33,13 +33,43 @@
#include <pthread.h>
#if (defined WIN32) || (defined _WIN64)
#ifndef ntohl
/* Assumes that all windows platforms are little endian */
#define ntohs(_v) ({const uint16_t v = (_v); (v>>8) | (v<<8);})
#define ntohl(_v) ({const uint32_t v = (_v); (v>>24) | (((v>>16)&0xff)<<8) | (((v>>8)&0xff)<<16) | ((v&0xff)<<24);})
#define ntohll(_x) ({uint64_t x = (_x); (((uint64_t)ntohl((uint32_t)x))<<32) | ntohl(x>>32);})
#define htons(_v) ntohs(_v)
#define htonl(_v) ntohl(_v)
#endif
#else /* #if (defined WIN32) || (defined _WIN64) */
#include <arpa/inet.h>
#if (defined __APPLE__)
#include <machine/endian.h>
#include <libkern/OSByteOrder.h>
#define ntohll(x) OSSwapBigToHostInt64(x)
#else /* #if (defined __APPLE__) */
#ifdef __LITTLE_ENDIAN__
#define ntohll(_x) ({uint64_t x = (_x); (((uint64_t)ntohl((uint32_t)x))<<32) | ntohl(x>>32);})
#else
#define ntohll(_x) (_x)
#endif
#endif /* #if (defined __APPLE__) */
#endif /* #if (defined WIN32) || (defined _WIN64) */
/*
* core_api.c stuff
*/
typedef void (*shoebill_pram_callback_t) (void *param, const uint8_t addr, const uint8_t byte);
typedef struct {
@ -266,27 +296,26 @@ alloc_pool_t* p_new_pool(alloc_pool_t *parent_pool);
*/
typedef uint32_t rb_key_t;
typedef void* rb_value_t;
typedef struct _rb_node {
struct _rb_node *left, *right, *parent;
rb_key_t key;
rb_value_t value;
uint8_t is_red : 1;
} rb_node;
typedef struct {
rb_node *root;
alloc_pool_t *pool;
uint32_t sz;
} rb_tree;
rb_tree* rb_new(alloc_pool_t *pool);
rb_tree* rb_new(alloc_pool_t *pool, uint32_t sz);
void rb_free (rb_tree *tree);
uint8_t rb_insert (rb_tree *root, rb_key_t key, rb_value_t value, rb_value_t *old_value);
uint8_t rb_find (rb_tree *tree, rb_key_t key, rb_value_t *value);
uint8_t rb_index (rb_tree *tree, uint32_t index, rb_key_t *key, rb_value_t *value);
uint8_t rb_insert (rb_tree *root, rb_key_t key, void *value, void *old_value);
uint8_t rb_find (rb_tree *tree, rb_key_t key, void *value);
uint8_t rb_index (rb_tree *tree, uint32_t index, rb_key_t *key, void *value);
uint32_t rb_count (rb_tree *tree);
@ -600,6 +629,12 @@ typedef struct {
} via_clock_t;
#define unstop_cpu_thread() do {\
assert(pthread_mutex_lock(&shoe.cpu_stop_mutex) == 0); \
assert(pthread_cond_signal(&shoe.cpu_stop_cond) == 0); \
assert(pthread_mutex_unlock(&shoe.cpu_stop_mutex) == 0); \
} while (0)
typedef struct {
_Bool running;
@ -614,9 +649,12 @@ typedef struct {
pthread_mutex_t cpu_thread_lock;
pthread_mutex_t via_clock_thread_lock; // synchronizes shoebill_start() and the starting of via_clock_thread()
pthread_mutex_t cpu_freeze_lock;
pthread_mutex_t via_cpu_lock; // synchronizes reads/writes of VIA registers and via_clock_thread()
// The pthread condition/mutex pair for yielding CPU on STOP, and waking up upon receiving an interrupt
pthread_mutex_t cpu_stop_mutex;
pthread_cond_t cpu_stop_cond;
// -- Assorted CPU state variables --
uint16_t op; // the first word of the instruction we're currently running
uint16_t orig_sr; // the sr before we began executing the instruction

View File

@ -71,8 +71,7 @@ void via_raise_interrupt(uint8_t vianum, uint8_t ifr_bit)
// if the CPU was stopped, wake it up
if (shoe.cpu_thread_notifications & SHOEBILL_STATE_STOPPED) {
if (!shoe.config_copy.debug_mode)
pthread_kill(shoe.cpu_thread_pid, SIGUSR2);
unstop_cpu_thread();
}
}

View File

@ -97,7 +97,7 @@ void nubus_video_init(void *_ctx, uint8_t slotnum,
// Set the depth and clut for B&W
_switch_depth(ctx, 1);
bzero(ctx->clut, 256 * 4);
memset(ctx->clut, 0, 256 * 4);
ctx->clut[0].r = 0xff;
ctx->clut[0].g = 0xff;
ctx->clut[0].b = 0xff;

View File

@ -14,7 +14,7 @@ int main (int argc, char **argv)
return 0;
}
assert(in = fopen(argv[1], "r"));
assert(in = fopen(argv[1], "rb"));
assert(out = fopen(argv[2], "w"));
assert(fread(rom, 4096, 1, in) == 1);

View File

@ -585,9 +585,8 @@ void global_passive_motion_func (int x, int y)
void global_keyboard_up_func (unsigned char c, int x, int y)
{
void *_value;
if (rb_find(keymap, c, &_value)) {
const uint16_t value = (uint16_t)_value;
uint16_t value;
if (rb_find(keymap, c, &value)) {
shoebill_key_modifier((value >> 8) | (_get_modifiers() >> 16));
shoebill_key(0, value & 0xff);
}
@ -595,9 +594,8 @@ void global_keyboard_up_func (unsigned char c, int x, int y)
void global_keyboard_down_func (unsigned char c, int x, int y)
{
void *_value;
if (rb_find(keymap, c, &_value)) {
const uint16_t value = (uint16_t)_value;
uint16_t value;
if (rb_find(keymap, c, &value)) {
shoebill_key_modifier((value >> 8) | (_get_modifiers() >> 16));
shoebill_key(1, value & 0xff);
}
@ -659,13 +657,13 @@ static void _init_keyboard_map (void)
{
#define mapkeymod(u, a, m) do { \
assert((a >> 7) == 0); \
void *value = (void*)(((m) << 8)| (a)); \
rb_insert(keymap, u, value, NULL); \
uint16_t value = ((m) << 8)| (a); \
rb_insert(keymap, u, &value, NULL); \
} while (0)
#define mapkey(_u, a) mapkeymod(_u, a, 0)
keymap = rb_new(p_new_pool(NULL));
keymap = rb_new(p_new_pool(NULL), sizeof(uint16_t));
// Letters
mapkey('a', 0x00);

View File

@ -32,15 +32,15 @@
#define mapkeymod(u, a, m) do { \
assert((a >> 7) == 0); \
void *value = (void*)(((m) << 8)| (a)); \
rb_insert(keymap, u, value, NULL); \
uint16_t value = ((m) << 8)| (a); \
rb_insert(keymap, u, &value, NULL); \
} while (0) \
#define mapkey(_u, a) mapkeymod(_u, a, 0)
- (void)initKeyboardMap
{
keymap = rb_new(p_new_pool(NULL));
keymap = rb_new(p_new_pool(NULL), sizeof(uint16_t));
// Letters
mapkey('a', 0x00);
@ -178,13 +178,12 @@
NSString *chars = [[event charactersIgnoringModifiers] lowercaseString];
NSUInteger modifierFlags = [event modifierFlags];
unichar c = [chars characterAtIndex:0];
void *_value;
uint16_t value;
if (keymap == NULL)
[self initKeyboardMap];
if (rb_find(keymap, c, &_value)) {
uint16_t value = (uint16_t)_value;
if (rb_find(keymap, c, &value)) {
shoebill_key_modifier((value >> 8) | (modifierFlags >> 16));
shoebill_key((type == NSKeyDown), value & 0xff);

View File

@ -36,13 +36,13 @@ static void _init_keyboard_map (void)
{
#define mapkeymod(u, a, m) do { \
assert((a >> 7) == 0); \
void *value = (void*)(((m) << 8)| (a)); \
rb_insert(keymap, u, value, NULL); \
uint16_t value = ((m) << 8)| (a); \
rb_insert(keymap, u, &value, NULL); \
} while (0)
#define mapkey(_u, a) mapkeymod(_u, a, 0)
keymap = rb_new(p_new_pool(NULL));
keymap = rb_new(p_new_pool(NULL), sizeof(uint16_t));
// Letters
mapkey('a', 0x00);
@ -269,7 +269,7 @@ static _Bool _setup_shoebill (void)
uint32_t i;
shoebill_config_t config;
bzero(&config, sizeof(shoebill_config_t));
memset(&config, 0, sizeof(shoebill_config_t));
config.aux_verbose = user_params.verbose;
config.ram_size = user_params.ram_megabytes * 1024 * 1024;
@ -299,7 +299,7 @@ static void _handle_key_event (SDL_Event *event)
const _Bool key_down = (event->type == SDL_KEYDOWN);
const SDL_Keymod sdl_mod = SDL_GetModState();
uint16_t adb_mod = 0;
void *_value;
uint16_t value;
if (sdl_mod & KMOD_SHIFT) adb_mod |= modShift;
if (sdl_mod & KMOD_CTRL) adb_mod |= modControl;
@ -307,8 +307,7 @@ static void _handle_key_event (SDL_Event *event)
if (sdl_mod & KMOD_GUI) adb_mod |= modCommand;
if (sdl_mod & KMOD_CAPS) adb_mod |= modCapsLock;
if (rb_find(keymap, sym, &_value)) {
const uint16_t value = (uint16_t)_value;
if (rb_find(keymap, sym, &value)) {
shoebill_key_modifier((value >> 8) | adb_mod);
shoebill_key(key_down, value & 0xff);
}

9
sdl-gui/win_build.bat Executable file
View File

@ -0,0 +1,9 @@
for %%i in (adb fpu mc68851 mem via floppy core_api cpu dis) do (
perl ..\core\macro.pl ..\core\%%i.c %%i.post.c
)
gcc -O1 ..\core\decoder_gen.c -o decoder_gen
decoder_gen inst .
decoder_gen dis .
gcc -O3 -flto -mno-ms-bitfields sdl.c adb.post.c fpu.post.c mc68851.post.c mem.post.c via.post.c floppy.post.c core_api.post.c cpu.post.c dis.post.c ..\core\atrap_tab.c ..\core\coff.c ..\core\exception.c ..\core\macii_symbols.c ..\core\redblack.c ..\core\scsi.c ..\core\video.c ..\core\filesystem.c ..\core\alloc_pool.c -lmingw32 -lopengl32 -lsdl2main -lsdl2 -o shoebill