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:
parent
952fe7ae89
commit
1bee24316c
13
core/coff.c
13
core/coff.c
|
@ -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;
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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);
|
||||
|
||||
|
|
|
@ -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__);
|
||||
}
|
||||
|
||||
|
|
10
core/mem.c
10
core/mem.c
|
@ -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
|
||||
|
||||
|
|
|
@ -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)
|
||||
{
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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();
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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);
|
||||
|
|
|
@ -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);
|
||||
|
|
|
@ -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);
|
||||
|
||||
|
|
|
@ -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);
|
||||
}
|
||||
|
|
|
@ -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
|
Loading…
Reference in New Issue