#include "custom.h"
#include "events.h"
#include "newcpu.h"
-#include "compiler.h"
#include "autoconf.h"
#include "osdep/exectasks.h"
static uae_u8 blit_cycle_diagram_line[] =
{
- 0, 4, 0,0,0,4 /* total guess.. */
+ 0, 4, 0,0,3,4 /* total guess.. */
};
void build_blitfilltable(void)
if (blt_info.hblitsize != 2)
write_log ("weird hblitsize in linemode: %d vsize=%d PC%=%x\n", blt_info.hblitsize, blt_info.vblitsize, m68k_getpc());
blit_diag = blit_cycle_diagram_line;
+ blit_singlechannel = 1;
} else {
if (con & 2) {
blitfc = !!(bltcon1 & 0x4);
#include "gfxfilter.h"
#include "savestate.h"
#include "memory.h"
+#include "gui.h"
#define CONFIG_BLEN 2560
return 1;
if (!strcmp (option, "config_host"))
return 1;
+ if (cfgfile_string (option, value, "config_hardware_path", p->config_hardware_path, 256))
+ return 1;
+ if (cfgfile_string (option, value, "config_host_path", p->config_host_path, 256))
+ return 1;
if (type == 0 || (type & CONFIG_TYPE_HARDWARE)) {
if (cfgfile_parse_hardware (p, option, value))
return 1;
break;
}
if (!path) {
- if (msg)
- gui_message ("You need any of following ROM(s)\n\n%s", tmp2);
+ if (msg) {
+ char tmp3[MAX_DPATH];
+ translate_message (NUMSG_ROMNEED, tmp3);
+ gui_message (tmp3, tmp2);
+ }
return 0;
}
switch (rd->type)
p->curses_reverse_video = 0;
- target_default_options (p);
+ target_default_options (p, type);
p->immediate_blits = 0;
p->collision_level = 2;
strcpy (p->cartfile, "");
strcpy (p->prtname, DEFPRTNAME);
strcpy (p->sername, DEFSERNAME);
+ target_default_options (p, 1);
}
static void set_68020_compa (struct uae_prefs *p, int compa)
}
}
+/* 0: cycle-exact
+ * 1: more compatible
+ * 2: no more compatible, no 100% sound
+ * 3: no more compatible, immediate blits, no 100% sound
+ */
+
static void set_68000_compa (struct uae_prefs *p, int compa)
{
- if (compa == 0) {
+ switch (compa)
+ {
+ case 0:
p->cpu_cycle_exact = p->blitter_cycle_exact = 1;
p->fast_copper = 0;
- } else if (compa == 2) {
+ break;
+ case 1:
+ break;
+ case 2:
+ p->cpu_compatible = 0;
+ break;
+ case 3:
p->immediate_blits = 1;
p->produce_sound = 2;
p->cpu_compatible = 0;
+ break;
}
}
rom[0] = rom[1] = rom[2] = rom[3] = -1;
switch (config)
{
- case 0: // KS 1.3, ECS Agnus, 0.5M Chip + 0.5M Slow
+ case 0: // KS 1.3, OCS Agnus, 0.5M Chip + 0.5M Slow
rom[0] = 6;
rom[1] = 32;
+ p->chipset_mask = 0;
break;
- case 1: // KS 1.3, OCS Agnus, 0.5M Chip
+ case 1: // KS 1.3, ECS Agnus, 0.5M Chip + 0.5M Slow
rom[0] = 6;
rom[1] = 32;
- p->bogomem_size = 0;
- p->chipset_mask = 0;
- p->dfxtype[1] = -1;
break;
case 2: // KS 1.3, ECS Agnus, 1.0M Chip
rom[0] = 6;
p->bogomem_size = 0;
p->chipmem_size = 0x100000;
break;
- case 3: // KS 1.2, OCS Agnus, 0.5M Chip
+ case 3: // KS 1.3, OCS Agnus, 0.5M Chip
+ rom[0] = 6;
+ rom[1] = 32;
+ p->bogomem_size = 0;
+ p->chipset_mask = 0;
+ p->dfxtype[1] = -1;
+ break;
+ case 4: // KS 1.2, OCS Agnus, 0.5M Chip
rom[0] = 5;
rom[1] = 4;
rom[2] = 3;
p->chipset_mask = 0;
p->dfxtype[1] = -1;
break;
- case 4: // KS 1.2, OCS Agnus, 0.5M Chip + 0.5M Slow
+ case 5: // KS 1.2, OCS Agnus, 0.5M Chip + 0.5M Slow
rom[0] = 5;
rom[1] = 4;
rom[2] = 3;
int build_in_prefs (struct uae_prefs *p, int model, int config, int compa, int romcheck)
{
- if (model > 4)
+ if (model > 6)
return 1;
buildin_default_prefs (p);
switch (model)
case 0:
return bip_a500 (p, config, compa, romcheck);
//case 1:
+ //return bip_a500p (p, config, compa, romcheck);
+ //case 2:
//return bip_a600 (p, config, compa, romcheck);
- case 1:
+ case 3:
return bip_a1000 (p, config, compa, romcheck);
- case 2:
+ case 4:
return bip_a1200 (p, config, compa, romcheck);
- case 3:
+ case 5:
return bip_cd32 (p, config, compa, romcheck);
- case 4:
+ case 6:
return bip_cdtv (p, config, compa, romcheck);
}
return 0;
ciabicr |= 0x10;
RethinkICRB();
}
+void cia_parallelack (void)
+{
+ ciaaicr |= 0x10;
+ RethinkICRA();
+}
static void ciab_checkalarm (void)
{
compute_passed_time ();
#ifdef CIA_DEBUG_R
- write_log("R_CIAA: %02.2X %08.8X\n", addr, m68k_getpc());
+ write_log("R_CIAA: bfe%x01 %08.8X\n", addr, m68k_getpc());
#endif
switch (addr & 0xf) {
unsigned int tmp;
#ifdef CIA_DEBUG_R
- write_log("R_CIAB: %02.2X %08.8X\n", addr, m68k_getpc());
+ write_log("R_CIAB: bfd%x00 %08.8X\n", addr, m68k_getpc());
#endif
compute_passed_time ();
static void WriteCIAA (uae_u16 addr,uae_u8 val)
{
#ifdef CIA_DEBUG_W
- write_log("W_CIAA: %02.2X %02.2X %08.8X\n", addr, val, m68k_getpc());
+ write_log("W_CIAA: bfe%x01 %02.2X %08.8X\n", addr, val, m68k_getpc());
#endif
switch (addr & 0xf) {
case 0:
static void WriteCIAB (uae_u16 addr,uae_u8 val)
{
#ifdef CIA_DEBUG_W
- write_log("W_CIAB: %02.2X %02.2X %08.8X\n", addr, val, m68k_getpc());
+ write_log("W_CIAB: bfd%x00 %02.2X %08.8X\n", addr, val, m68k_getpc());
#endif
switch (addr & 0xf) {
case 0:
#include "include/memory.h"
#include "custom.h"
#include "newcpu.h"
-#include "compiler.h"
#include "comptbl.h"
#include "compemu.h"
+++ /dev/null
- /*
- * UAE - The Un*x Amiga Emulator
- *
- * m68k emulation
- *
- * Copyright 1996 Bernd Schmidt
- */
-
-#include "sysconfig.h"
-#include "sysdeps.h"
-
-#include "config.h"
-#include "options.h"
-#include "events.h"
-#include "gui.h"
-#include "memory.h"
-#include "custom.h"
-#include "newcpu.h"
-#include "ersatz.h"
-#include "blitter.h"
-#include "debug.h"
-#include "autoconf.h"
-#include "compiler.h"
-
-#ifdef USE_COMPILER
-
-#include <sys/mman.h>
-
-char *address_space, *good_address_map;
-
-code_execfunc exec_me;
-uae_u8 nr_bbs_to_run = 1;
-int nr_bbs_start = 40;
-
-static int compile_failure;
-static int quiet_compile = 1;
-int i_want_to_die = 1;
-static int n_compiled = 0;
-static int n_max_comp = 99999999;
-static uaecptr call_only_me = 0;
-
-int patched_syscalls = 0;
-
-static int count_bits(uae_u16 v)
-{
- int bits = 0;
- while (v != 0) {
- if (v & 1)
- bits++;
- v >>= 1;
- }
- return bits;
-}
-
-static uae_u16 bitswap(uae_u16 v)
-{
- uae_u16 newv = 0;
- uae_u16 m1 = 1, m2 = 0x8000;
- int i;
-
- for (i = 0; i < 16; i++) {
- if (v & m1)
- newv |= m2;
- m2 >>= 1;
- m1 <<= 1;
- }
- return newv;
-}
-
-static long long compiled_hits = 0;
-
-/* 16K areas with 512 byte blocks */
-#define SUBUNIT_ORDER 9
-#define PAGE_SUBUNIT (1 << SUBUNIT_ORDER)
-#define PAGE_ALLOC_UNIT (PAGE_SUBUNIT * 32)
-
-static int zerofd;
-static int zeroff;
-static struct code_page *first_code_page;
-
-static struct code_page *new_code_page(void)
-{
- struct code_page *ncp;
-
- ncp = (struct code_page *)mmap(NULL, PAGE_ALLOC_UNIT,
- PROT_EXEC|PROT_READ|PROT_WRITE, MAP_PRIVATE,
- zerofd, zeroff);
- zeroff += PAGE_ALLOC_UNIT;
- if (ncp) {
- ncp->next = first_code_page;
- first_code_page = ncp;
- ncp->allocmask = 1; /* what a waste */
- }
- return ncp;
-}
-
-#define NUM_HASH 32768 /* larger values cause some paging on my 16MB machine */
-#define HASH_MASK (NUM_HASH-1)
-#define MAX_UNUSED_HASH 512
-
-static int SCAN_MARK = 1; /* Number of calls after which to scan a function */
-static int COMPILE_MARK = 5; /* Number of calls after which to compile a function */
-
-/* The main address -> function lookup hashtable. We use the lower bits of
- * the address as hash function. */
-static struct hash_entry cpu_hash[NUM_HASH];
-/* These aren't really LRU lists... They used to be, but keeping them in that
- * order is costly. The hash LRU list is now a two-part list: Functions that have
- * no code allocated for them are placed at the beginning. Such entries can be
- * recycled when we need a new hash entry. */
-static struct hash_block lru_first_block;
-static struct hash_entry lru_first_hash;
-static struct hash_entry *freelist_hash;
-static struct hash_block *freelist_block;
-static int num_unused_hash;
-
-static int m68k_scan_func(struct hash_entry *);
-static int m68k_compile_block(struct hash_block *);
-
-static char *alloc_code(struct hash_block *hb, int ninsns)
-{
- struct code_page *cp;
- long int allocsize = (ninsns * 32 + PAGE_SUBUNIT-1) & ~(PAGE_SUBUNIT-1);
- uae_u32 allocmask;
- int allocbits;
- int j;
- int last_bit;
-
- if (allocsize >= (PAGE_ALLOC_UNIT - (1 << SUBUNIT_ORDER)))
- return NULL;
- allocbits = (allocsize >> SUBUNIT_ORDER);
- allocmask = (1 << allocbits) - 1;
-
- for (cp = first_code_page; cp != NULL; cp = cp->next) {
- uae_u32 thispage_alloc = cp->allocmask;
- for (j = 1; j < (33 - allocbits); j++) {
- if ((cp->allocmask & (allocmask << j)) == 0) {
- goto found_page;
- }
- }
- }
-
- /* Nothing large enough free: make a new page */
- cp = new_code_page();
- if (cp == NULL)
- return NULL;
- j = 1;
-
-found_page:
- /* See whether there is in fact more space for us. If so, allocate all of
- * it. compile_block() will free everything it didn't need. */
-
- allocmask <<= j;
- last_bit = allocbits + j;
- while (last_bit < 32 && (cp->allocmask & (1 << last_bit)) == 0) {
- allocmask |= 1 << last_bit;
- allocsize += PAGE_SUBUNIT;
- last_bit++;
- }
-
- hb->page_allocmask = allocmask;
- hb->cpage = cp;
- cp->allocmask |= allocmask;
- hb->compile_start = ((char *)cp + (j << SUBUNIT_ORDER));
- hb->alloclen = allocsize;
- return hb->compile_start;
-}
-
-static void remove_hash_from_lists(struct hash_entry *h)
-{
- h->lru_next->lru_prev = h->lru_prev;
- h->lru_prev->lru_next = h->lru_next;
-
- h->next->prev = h->prev;
- h->prev->next = h->next;
-}
-
-static void lru_touch(struct hash_entry *h)
-{
- h->lru_next->lru_prev = h->lru_prev;
- h->lru_prev->lru_next = h->lru_next;
-
- h->lru_next = &lru_first_hash;
- h->lru_prev = lru_first_hash.lru_prev;
- h->lru_prev->lru_next = h;
- lru_first_hash.lru_prev = h;
-}
-
-static void lru_untouch(struct hash_entry *h)
-{
- h->lru_next->lru_prev = h->lru_prev;
- h->lru_prev->lru_next = h->lru_next;
-
- h->lru_prev = &lru_first_hash;
- h->lru_next = lru_first_hash.lru_next;
- h->lru_next->lru_prev = h;
- lru_first_hash.lru_next = h;
-}
-
-static void forget_block(struct hash_block *hb)
-{
- struct hash_entry *h = hb->he_first;
-
- hb->lru_next->lru_prev = hb->lru_prev;
- hb->lru_prev->lru_next = hb->lru_next;
-
- hb->lru_next = freelist_block;
- freelist_block = hb;
-
- if (hb->cpage != NULL)
- write_log ("Discarding block with code. Tsk.\n");
-
- do {
- struct hash_entry *next = h->next_same_block;
- h->block = NULL;
- h->execute = NULL;
- h->next_same_block = NULL;
- h = next;
- num_unused_hash++;
- lru_untouch(h);
- } while (h != hb->he_first);
- compiler_flush_jsr_stack();
-}
-
-static void lru_touch_block(struct hash_block *h)
-{
- h->lru_next->lru_prev = h->lru_prev;
- h->lru_prev->lru_next = h->lru_next;
-
- h->lru_next = &lru_first_block;
- h->lru_prev = lru_first_block.lru_prev;
- h->lru_prev->lru_next = h;
- lru_first_block.lru_prev = h;
-}
-
-STATIC_INLINE int check_block(struct hash_block *hb)
-{
-#ifndef RELY_ON_LOADSEG_DETECTION
- struct hash_entry *h = hb->he_first;
-
- do {
- struct hash_entry *next = h->next_same_block;
- if (h->matchword != *(uae_u32 *)get_real_address(h->addr))
- return 0;
- h = next;
- } while (h != hb->he_first);
-#endif
- return 1;
-}
-
-uae_u32 flush_icache(void)
-{
- struct hash_block *hb = lru_first_block.lru_next;
-
- while (hb != &lru_first_block) {
- struct hash_block *next = hb->lru_next;
- if (hb->cpage != NULL) {
- /* Address in chipmem? Then forget about block*/
- if ((hb->he_first->addr & ~0xF80000) != 0xF80000) {
- hb->cpage->allocmask &= ~hb->page_allocmask;
- hb->cpage = NULL;
- forget_block(hb);
- }
- }
- hb = next;
- }
- return m68k_dreg(regs, 0);
-}
-
-void possible_loadseg(void)
-{
- write_log ("Possible LoadSeg() detected\n");
- flush_icache();
-}
-
-static struct hash_block *new_block(void)
-{
- struct hash_block *b = freelist_block;
-
- if (b != NULL) {
- freelist_block = b->lru_next;
- } else
- b = (struct hash_block *)malloc(sizeof *b);
- b->nrefs = 0;
- b->cpage = NULL;
- b->he_first = NULL;
- b->translated = b->untranslatable = b->allocfailed = 0;
- return b;
-}
-
-static struct hash_entry *get_free_hash(void)
-{
- struct hash_entry *h;
-
- for (;;) {
- h = freelist_hash;
- if (h != NULL) {
- freelist_hash = h->next_same_block;
- break;
- }
- h = lru_first_hash.lru_next;
- if (num_unused_hash >= MAX_UNUSED_HASH && h->block == NULL
- && !h->locked)
- {
- remove_hash_from_lists(h);
- num_unused_hash--;
- break;
- }
- h = (struct hash_entry *)malloc(sizeof(struct hash_entry));
- h->next_same_block = NULL;
- h->addr = -1;
- break;
- }
- num_unused_hash++;
- h->block = NULL;
- h->ncalls = 0;
- h->locked = h->cacheflush = 0;
- h->execute = NULL;
- return h;
-}
-
-static struct hash_entry *new_hash(uaecptr addr)
-{
- struct hash_entry *h = get_free_hash();
-
- h->addr = addr;
-
- /* Chain the new node */
- h->prev = cpu_hash + ((addr >> 1) & HASH_MASK);
- h->next = h->prev->next;
- h->next->prev = h->prev->next = h;
-
- h->lru_next = &lru_first_hash;
- h->lru_prev = lru_first_hash.lru_prev;
- h->lru_prev->lru_next = h;
- lru_first_hash.lru_prev = h;
-
- h->next_same_block = NULL;
-
- return h;
-}
-static struct hash_entry *find_hash(uaecptr addr)
-{
- struct hash_entry *h;
- struct hash_entry *h1 = cpu_hash + ((addr >> 1) & HASH_MASK);
-
- if (h1->next->addr == addr)
- return h1->next;
-
- for (h = h1->next; h != h1; h = h->next) {
- if (h->addr == addr) {
- /* Put it at the head of the list so that the above shortcut
- * works the next time we come here */
- h->next->prev = h->prev; h->prev->next = h->next;
- h->prev = h1;
- h->next = h1->next;
- h->next->prev = h->prev->next = h;
- return h;
- }
- }
- return NULL;
-}
-
-static struct hash_entry *get_hash_for_func(uaecptr addr, int mark_locked)
-{
- struct hash_entry *h = find_hash(addr);
- if (h == NULL)
- h = new_hash (addr);
-#if 0 /* Too expensive */
- else
- lru_touch(h);
-#endif
- if (mark_locked)
- h->locked = 1;
- return h;
-}
-
-static struct hash_entry *get_hash(uaecptr addr)
-{
- struct hash_entry *h = get_hash_for_func(addr, 0);
-
- if (h->block == NULL) {
- if (++h->ncalls == SCAN_MARK) {
- m68k_scan_func(h);
- }
- } else
- if (!h->block->untranslatable && h->block->nrefs++ == COMPILE_MARK) {
- lru_touch_block(h->block);
- if (m68k_compile_block(h->block)) {
- h->block->untranslatable = 1;
- } else {
- h->block->translated = 1;
- }
- }
- return h;
-}
-
-void special_flush_hash(uaecptr addr)
-{
- struct hash_entry *h = get_hash_for_func(addr, 0);
-
- h->cacheflush = 1;
-}
-
-STATIC_INLINE void m68k_setpc_hash(uaecptr newpc)
-{
- struct hash_entry *h = get_hash(newpc);
-
- if (h->cacheflush)
- flush_icache();
-
- if (h->execute != NULL) {
- if ((h->addr & 0xF80000) == 0xF80000 || check_block(h->block)) {
- compiled_hits++;
- if (i_want_to_die && (call_only_me == 0 || call_only_me == newpc)) {
- exec_me = h->execute;
- nr_bbs_to_run = nr_bbs_start;
- regs.spcflags |= SPCFLAG_EXEC;
- }
- } else
- flush_icache();
- }
- regs.pc = newpc;
- regs.pc_p = regs.pc_oldp = get_real_address(newpc);
-}
-
-STATIC_INLINE void m68k_setpc_nohash(uaecptr newpc)
-{
-#if 0
- /* This is probably not too good for efficiency... FIXME */
- struct hash_entry *h = find_hash(newpc);
-
- if (h != NULL && h->cacheflush)
- flush_icache();
-#endif
- regs.pc = newpc;
- regs.pc_p = regs.pc_oldp = get_real_address(newpc);
-}
-
-void m68k_setpc(uaecptr newpc)
-{
- m68k_setpc_hash(newpc);
-}
-
-void m68k_setpc_fast(uaecptr newpc)
-{
- m68k_setpc_nohash(newpc);
-}
-
-void m68k_setpc_rte(uaecptr newpc)
-{
- m68k_setpc_nohash(newpc);
-}
-
-void m68k_setpc_bcc(uaecptr newpc)
-{
- m68k_setpc_hash(newpc);
-}
-
-static void hash_init(void)
-{
- int i;
- struct hash_entry **hepp;
-
- freelist_block = NULL;
- freelist_hash = NULL;
-
- for(i = 0; i < NUM_HASH; i++) {
- cpu_hash[i].next = cpu_hash[i].prev = cpu_hash + i;
- cpu_hash[i].lru_next = cpu_hash[i].lru_prev = NULL;
- cpu_hash[i].block = NULL;
- cpu_hash[i].locked = 0; cpu_hash[i].cacheflush = 0;
- cpu_hash[i].addr = -1;
- }
-
- lru_first_hash.lru_next = lru_first_hash.lru_prev = &lru_first_hash;
- lru_first_block.lru_next = lru_first_block.lru_prev = &lru_first_block;
-
- num_unused_hash = 0;
-}
-
-static void code_init(void)
-{
- first_code_page = NULL;
- zerofd = open("/dev/zero", O_RDWR);
- zeroff = 0;
-}
-
-#define CC68K_C 16
-#define CC68K_V 8
-#define CC68K_Z 4
-#define CC68K_N 2
-#define CC68K_X 1
-
-STATIC_INLINE int cc_flagmask_68k(const int cc)
-{
- switch(cc){
- case 0: return 0; /* T */
- case 1: return 0; /* F */
- case 2: return CC68K_C|CC68K_Z; /* HI */
- case 3: return CC68K_C|CC68K_Z; /* LS */
- case 4: return CC68K_C; /* CC */
- case 5: return CC68K_C; /* CS */
- case 6: return CC68K_Z; /* NE */
- case 7: return CC68K_Z; /* EQ */
- case 8: return CC68K_V; /* VC */
- case 9: return CC68K_V; /* VS */
- case 10:return CC68K_N; /* PL */
- case 11:return CC68K_N; /* MI */
- case 12:return CC68K_N|CC68K_V; /* GE */
- case 13:return CC68K_N|CC68K_V; /* LT */
- case 14:return CC68K_N|CC68K_V|CC68K_Z; /* GT */
- case 15:return CC68K_N|CC68K_V|CC68K_Z; /* LE */
- }
- abort();
- return 0;
-}
-
-STATIC_INLINE void translate_step_over_ea(uae_u8 **pcpp, amodes m,
- wordsizes size)
-{
- switch (m) {
- case Areg:
- case Dreg:
- case Aind:
- case Aipi:
- case Apdi:
- case immi:
- break;
-
- case imm:
- if (size == sz_long)
- goto is_long;
- /* fall through */
- case Ad16:
- case PC16:
- case imm0:
- case imm1:
- case absw:
- (*pcpp)+=2;
- break;
- case Ad8r:
- case PC8r:
- {
- uae_u16 extra = *(*pcpp)++;
- extra <<= 8;
- extra |= *(*pcpp)++;
- /* @@@ handle 68020 stuff here */
- }
- break;
- case absl:
- case imm2:
- is_long:
- (*pcpp) += 4;
- break;
- }
-}
-
-static struct instr *translate_getnextinsn(uae_u8 **pcpp)
-{
- uae_u16 opcode;
- struct instr *dp;
-
- opcode = *(*pcpp)++ << 8;
- opcode |= *(*pcpp)++;
-
- if (cpufunctbl[opcode] == op_illg) {
- opcode = 0x4AFC;
- }
- dp = table68k + opcode;
- if (dp->suse) {
- translate_step_over_ea(pcpp, dp->smode, dp->size);
- }
- if (dp->duse) {
- translate_step_over_ea(pcpp, dp->dmode, dp->size);
- }
- return dp;
-}
-
-#define CB_STACKSIZE 200
-#define BB_STACKSIZE 200
-
-static uae_u32 condbranch_stack[CB_STACKSIZE];
-static int condbranch_src_stack[CB_STACKSIZE];
-
-struct bb_info {
- struct hash_entry *h;
- uaecptr stopaddr;
- int can_compile_last;
- struct bb_info *bb_next1, *bb_next2;
- int flags_live_at_end;
- int flags_live_at_start;
- int first_iip, last_iip;
-} bb_stack[BB_STACKSIZE];
-
-static int top_bb;
-
-static uaecptr bcc_target_stack[BB_STACKSIZE];
-
-static int new_bcc_target(uaecptr addr)
-{
- int i;
-
- for (i = 0; i < top_bb; i++)
- if (bcc_target_stack[i] == addr)
- return 1;
-
- if (top_bb == BB_STACKSIZE)
- return 0;
- bcc_target_stack[top_bb++] = addr;
- return 1;
-}
-
-static int bcc_compfn(const void *a, const void *b)
-{
- uaecptr *a1 = (uaecptr *)a, *b1 = (uaecptr *)b;
-
- if (*a1 == *b1)
- printf("BUG!!\n");
-
- if (*a1 < *b1)
- return 1;
- return -1;
-}
-
-static int bb_compfn(const void *a, const void *b)
-{
- struct bb_info *a1 = (struct bb_info *)a, *b1 = (struct bb_info *)b;
-
- if (a1->h->addr == b1->h->addr)
- printf("BUG!!\n");
-
- if (a1->h->addr < b1->h->addr)
- return -1;
- return 1;
-}
-
-static int find_basic_blocks(struct hash_entry *h)
-{
- int current_bb = 0;
-
- top_bb = 0;
- bcc_target_stack[0] = h->addr;
- new_bcc_target(h->addr);
-
- while (top_bb > current_bb) {
- uaecptr addr = bcc_target_stack[current_bb];
- int ninsns = 0;
- uae_u8 *realpc = get_real_address(addr);
- uae_u8 *rpc_start = realpc;
-
- for(;;) {
- uaecptr thisinsn_addr = (realpc - rpc_start) + addr;
- uae_u8 *rpc_save = realpc;
- struct instr *dp = translate_getnextinsn(&realpc);
- uaecptr nextinsn_addr = (realpc - rpc_start) + addr;
-
- if (dp->mnemo == i_RTS || dp->mnemo == i_RTE
- || dp->mnemo == i_RTR || dp->mnemo == i_RTD
- || dp->mnemo == i_JMP || dp->mnemo == i_ILLG)
- {
- break;
- }
-
- if (dp->mnemo == i_BSR || dp->mnemo == i_JSR) {
- if (!new_bcc_target(nextinsn_addr))
- return 0;
- break;
- }
-
- if (dp->mnemo == i_DBcc) {
- uaecptr newaddr = thisinsn_addr + 2 + (uae_s16)((*(rpc_save+2) << 8) | *(rpc_save+3));
- if (!new_bcc_target(nextinsn_addr))
- return 0;
- if (!new_bcc_target(newaddr))
- return 0;
- break;
- }
-
- if (dp->mnemo == i_Bcc) {
- uaecptr newaddr;
- if (dp->smode == imm1)
- newaddr = thisinsn_addr + 2 + (uae_s16)((*(rpc_save+2) << 8) | *(rpc_save+3));
- else
- newaddr = thisinsn_addr + 2 + (uae_s8)dp->sreg;
-
- if (dp->cc != 0)
- if (!new_bcc_target(nextinsn_addr))
- return 0;
- if (!new_bcc_target(newaddr))
- return 0;
- break;
- }
- }
- current_bb++;
- }
-
- qsort(bcc_target_stack, top_bb, sizeof (uaecptr), bcc_compfn);
-
- return 1;
-}
-
-static int m68k_scan_func(struct hash_entry *h)
-{
- int i;
- struct hash_block *found_block;
- struct hash_entry **hepp;
-
- if (!find_basic_blocks(h))
- return 0;
-
- found_block = NULL;
-
- /* First, lock the hash entries we already have to prevent grief */
- for (i = 0; i < top_bb; i++) {
- struct hash_entry *h = find_hash(bcc_target_stack[i]);
- if (h != NULL)
- h->locked = 1;
- }
-
- /* Allocate new ones */
- for (i = 0; i < top_bb; i++) {
- struct hash_entry *h = get_hash_for_func(bcc_target_stack[i], 1);
- bb_stack[i].h = h;
-#if 0 /* This doesn't work in all cases */
- if (h->block != NULL && h->block != found_block) {
- if (found_block == NULL) {
- if (h->block->cpage != NULL)
- write_log ("Found compiled code\n");
- else
- found_block = h->block;
- } else {
- write_log ("Multiple blocks found.\n");
- if (h->block->cpage == NULL)
- forget_block(h->block);
- else if (found_block->cpage == NULL) {
- forget_block(found_block);
- found_block = h->block;
- } else
- write_log ("Bad case.\n");
- }
- }
-#endif
- }
- if (found_block == NULL) {
- found_block = new_block();
-
- found_block->lru_next = &lru_first_block;
- found_block->lru_prev = lru_first_block.lru_prev;
- found_block->lru_prev->lru_next = found_block;
- lru_first_block.lru_prev = found_block;
- }
-
- hepp = &found_block->he_first;
- found_block->he_first = NULL;
- for (i = 0; i < top_bb; i++) {
- struct bb_info *bb = bb_stack + i;
-
- if (bb->h->block == NULL) {
- num_unused_hash--;
- lru_touch(bb->h);
- bb->h->block = found_block;
- *hepp = bb->h;
- hepp = &bb->h->next_same_block;
- }
- }
- *hepp = found_block->he_first;
- return 1;
-}
-
-struct ea_reg_info {
- enum { eat_reg, eat_imem, eat_amem, eat_const } ea_type;
- int regs_set:16;
- int regs_used:16;
- int nr_scratch;
- uae_u32 temp1, temp2;
-};
-
-#define MAX_TRANSLATE 2048
-struct insn_info_struct {
- uaecptr address;
- struct instr *dp;
- int flags_set;
- int flags_used;
- int flags_live_at_end;
- int jump_target;
- int jumps_to;
- char *compiled_jumpaddr; /* Address to use for jumps to this insn */
- char *compiled_fillin; /* Address where to put offset if this is a Bcc */
- int regs_set:16;
- int regs_used:16;
- int stop_translation:2;
- int sync_cache:1;
- int sync_flags:1;
- int ccuser_follows:1;
-} insn_info [MAX_TRANSLATE];
-
-#define EA_NONE 0
-#define EA_LOAD 1
-#define EA_STORE 2
-#define EA_MODIFY 4
-
-#if 0
-static void analyze_ea_for_insn(amodes mode, int reg, wordsizes size,
- struct ea_reg_info *eai,
- uae_u8 **pcpp, uaecptr pca,
- int ea_purpose)
-{
- uae_u8 *p = *pcpp;
-
- switch(mode) {
- case Dreg:
- eai->ea_type = eat_reg;
- if (size != sz_long && (ea_purpose & EA_STORE))
- ea_purpose |= EA_LOAD;
- if (ea_purpose & EA_LOAD)
- eai->regs_used |= 1 << reg;
- if (ea_purpose & EA_STORE)
- eai->regs_set |= 1 << reg;
- break;
-
- case Areg:
- eai->ea_type = eat_reg;
- if (size != sz_long && (ea_purpose & EA_STORE))
- printf("Areg != long\n");
- if (ea_purpose & EA_LOAD)
- eai->regs_used |= 1 << (8+reg);
- if (ea_purpose & EA_STORE)
- eai->regs_set |= 1 << (8+reg);
- break;
-
- case Ad16:
- case Aind:
- case Apdi:
- case Aipi:
- eai->ea_type = eat_imem;
- eai->regs_used |= 1 << (8+reg);
- break;
-
- case Ad8r:
- eai->ea_type = eat_imem;
- pii->regs_used |= 1 << (8+reg);
-
- eai->temp = (uae_u16)((*p << 8) | *(p+1));
- r = (eai->temp & 0x7000) >> 12;
- (*pcpp) += 2; p += 2;
-
- if (eai->temp1 & 0x8000)
- pii->regs_used |= 1 << (8+r);
- else
- pii->regs_used |= 1 << r;
- break;
-
- case PC8r:
- eai->ea_type = eat_imem;
- eai->temp1 = (uae_u16)do_get_mem_word((uae_u16 *)p);
- eai->temp2 = pca + (uae_s8)eai->temp1;
- (*pcpp) += 2; p += 2;
- r = (eai->temp1 & 0x7000) >> 12;
-
- if (eai->temp1 & 0x8000)
- pii->regs_used |= 1 << (8+r);
- else
- pii->regs_used |= 1 << r;
- break;
-
- case PC16:
- eai->ea_type = eat_amem;
- eai->temp1 = pca + (uae_s16)do_get_mem_word((uae_u16 *)p);
- (*pcpp) += 2;
- break;
-
- case absw:
- eai->ea_type = eat_amem;
- eai->temp1 = (uae_s16)do_get_mem_word((uae_u16 *)p);
- (*pcpp) += 2;
- break;
-
- case absl:
- eai->ea_type = eat_amem;
- eai->temp1 = (uae_s32)do_get_mem_long((uae_u32 *)p);
- (*pcpp) += 4;
- break;
-
- case imm:
- if (size == sz_long)
- goto imm2_const;
- if (size == sz_word)
- goto imm1_const;
-
- /* fall through */
- case imm0:
- eai->ea_type = eat_imm;
- eai->temp1 = (uae_s8)*(p+1);
- (*pcpp) += 2;
- break;
-
- case imm1:
- imm1_const:
- eai->ea_type = eat_imm;
- eai->temp1 = (uae_s16)do_get_mem_word((uae_u16 *)p);
- (*pcpp) += 2;
- break;
-
- case imm2:
- imm2_const:
- eai->ea_type = eat_imm;
- eai->temp1 = (uae_s32)do_get_mem_long((uae_u32 *)p);
- (*pcpp) += 4;
- break;
-
- case immi:
- eai->ea_type = eat_imm;
- eai->temp1 = (uae_s8)reg;
- break;
-
- default:
- break;
- }
-}
-#endif
-static struct bb_info *find_bb(struct hash_entry *h)
-{
- int i;
-
- if (h == NULL)
- printf("Bug...\n");
-
- for (i = 0; i < top_bb; i++)
- if (bb_stack[i].h == h)
- return bb_stack + i;
- if (!quiet_compile)
- write_log ("BB not found!\n");
- return NULL;
-}
-
-static int m68k_scan_block(struct hash_block *hb, int *movem_count)
-{
- struct hash_entry *h = hb->he_first;
- int i, iip, last_iip;
- int changed, round;
-
- top_bb = 0;
-
- do {
- struct bb_info *bb = bb_stack + top_bb;
- bb->h = h;
- bb->bb_next1 = NULL;
- bb->bb_next2 = NULL;
- h = h->next_same_block;
- top_bb++;
- } while (h != hb->he_first);
-
- qsort(bb_stack, top_bb, sizeof (struct bb_info), bb_compfn);
-
- *movem_count = 0;
-
- iip = 0;
- for (i = 0; i < top_bb; i++) {
- struct bb_info *bb = bb_stack + i;
- uae_u8 *realpc = get_real_address(bb->h->addr);
- uae_u8 *rpc_start = realpc;
- uaecptr stop_addr = 0;
- int live_at_start = 31, may_clear_las = 31;
- struct insn_info_struct *prev_ii = NULL;
-
- if (i < top_bb - 1)
- stop_addr = (bb+1)->h->addr;
- bb->first_iip = iip;
-
- for (;;) {
- struct insn_info_struct *thisii = insn_info + iip;
- uaecptr thisinsn_addr = (realpc - rpc_start) + bb->h->addr;
- uae_u8 *rpc_save = realpc;
- struct instr *dp = translate_getnextinsn(&realpc);
- uaecptr nextinsn_addr = (realpc - rpc_start) + bb->h->addr;
-
- int fset = dp->flagdead == -1 ? 31 : dp->flagdead;
- int fuse = dp->flaglive == -1 ? 31 : dp->flaglive;
-
- if (thisinsn_addr == stop_addr) {
- bb->bb_next1 = find_bb (find_hash (thisinsn_addr));
- break;
- }
-
- if (dp->mnemo == i_Scc || dp->mnemo == i_Bcc || dp->mnemo == i_DBcc) {
- fset = 0, fuse = cc_flagmask_68k(dp->cc);
- if (prev_ii && dp->mnemo != i_Scc) /* Don't use Scc here: ea can cause an exit */
- prev_ii->ccuser_follows = 1;
- }
-
- may_clear_las &= ~fuse;
- live_at_start &= ~(fset & may_clear_las);
-
- thisii->dp = dp;
- thisii->address = thisinsn_addr;
- thisii->stop_translation = 0;
- thisii->ccuser_follows = 0;
-/* thisii->have_reginfo = 0;*/
- thisii->jump_target = 0;
- thisii->sync_cache = thisii->sync_flags = 0;
- thisii->flags_set = fset;
- thisii->flags_used = fuse;
- thisii->regs_set = 0;
- thisii->regs_used = 0;
- iip++;
- if (iip == MAX_TRANSLATE)
- return 0;
-
- if (dp->mnemo == i_RTS || dp->mnemo == i_RTE
- || dp->mnemo == i_RTR || dp->mnemo == i_RTD
- || dp->mnemo == i_JMP || dp->mnemo == i_ILLG)
- {
- thisii->flags_used = 31;
- thisii->regs_used = 65535;
- thisii->stop_translation = dp->mnemo == i_RTS || dp->mnemo == i_JMP ? 2 : 1;
- break;
- }
- if (dp->mnemo == i_BSR || dp->mnemo == i_JSR)
- {
- thisii->flags_used = 31;
- thisii->regs_used = 65535;
- bb->can_compile_last = 1;
- bb->bb_next1 = find_bb (get_hash_for_func (nextinsn_addr, 1));
- if (bb->bb_next1 == NULL)
- thisii->stop_translation = 1;
- break;
- }
-
- if (dp->mnemo == i_DBcc) {
- uaecptr newaddr = thisinsn_addr + 2 + (uae_s16)((*(rpc_save+2) << 8) | *(rpc_save+3));
- bb->can_compile_last = 1;
- bb->bb_next1 = find_bb (get_hash_for_func (newaddr, 1));
- if (bb->bb_next1 == NULL)
- thisii->stop_translation = 1;
- bb->bb_next2 = find_bb (get_hash_for_func (nextinsn_addr, 1));
- if (bb->bb_next2 == NULL)
- thisii->stop_translation = 1;
- thisii->regs_used = 65535;
- break;
- }
-
- if (dp->mnemo == i_Bcc) {
- uaecptr newaddr;
- if (dp->smode == imm1)
- newaddr = thisinsn_addr + 2 + (uae_s16)((*(rpc_save+2) << 8) | *(rpc_save+3));
- else
- newaddr = thisinsn_addr + 2 + (uae_s8)dp->sreg;
- bb->can_compile_last = 1;
- bb->bb_next1 = find_bb(get_hash_for_func(newaddr, 1));
- if (bb->bb_next1 == NULL)
- thisii->stop_translation = 1;
- if (dp->cc != 0) {
- bb->bb_next2 = find_bb(get_hash_for_func(nextinsn_addr, 1));
- if (bb->bb_next2 == NULL)
- thisii->stop_translation = 1;
- }
- thisii->regs_used = 65535;
- break;
- }
-
- if (dp->mnemo == i_MVMLE || dp->mnemo == i_MVMEL) {
- uae_u16 regmask = (*(rpc_save + 2) << 8) | (*(rpc_save + 3));
- *movem_count += count_bits(regmask);
- if (dp->dmode == Apdi)
- regmask = bitswap(regmask);
- if (dp->mnemo == i_MVMLE)
- thisii->regs_used = regmask;
- else
- thisii->regs_set = regmask;
- }
-
- prev_ii = thisii;
- }
- bb->last_iip = iip - 1;
- bb->flags_live_at_start = live_at_start;
- }
- last_iip = iip;
- round = 0;
- do {
- changed = 0;
- for (i = 0; i < top_bb; i++) {
- struct bb_info *bb = bb_stack + i;
- int mnemo;
- int current_live;
- struct instr *dp;
-
- iip = bb->last_iip;
- mnemo = insn_info[iip].dp->mnemo;
-
- /* Fix up branches */
- if (round == 0 && (mnemo == i_DBcc || mnemo == i_Bcc)) {
- if (bb->bb_next1 != NULL) {
- insn_info[bb->last_iip].jumps_to = bb->bb_next1->first_iip;
- insn_info[bb->bb_next1->first_iip].jump_target = 1;
- }
- }
-
- /* And take care of flag life information */
- dp = insn_info[iip].dp;
- if (insn_info[iip].stop_translation)
- current_live = 31;
- else if (dp->mnemo == i_DBcc || dp->mnemo == i_Bcc) {
- current_live = 0;
- if (bb->bb_next1 != NULL)
- current_live |= bb->bb_next1->flags_live_at_start;
- if (bb->bb_next2 != NULL)
- current_live |= bb->bb_next2->flags_live_at_start;
- } else {
- if (bb->bb_next1 == NULL && bb->bb_next2 == NULL)
- write_log ("Can't happen\n");
- current_live = 0;
- if (bb->bb_next1 != NULL)
- current_live |= bb->bb_next1->flags_live_at_start;
- if (bb->bb_next2 != NULL)
- current_live |= bb->bb_next2->flags_live_at_start;
- }
-
- do {
- insn_info[iip].flags_live_at_end = current_live;
- current_live &= ~insn_info[iip].flags_set;
- current_live |= insn_info[iip].flags_used;
- } while (iip-- != bb->first_iip);
-
- if (bb->flags_live_at_start != current_live && !quiet_compile)
- write_log ("Fascinating %d!\n", round), changed = 1;
- bb->flags_live_at_start = current_live;
- }
- round++;
- } while (changed);
- return last_iip;
-}
-
-#define MAX_JSRS 4096 /* must be a power of two */
-
-static uaecptr jsr_rets[MAX_JSRS];
-static struct hash_entry *jsr_hash[MAX_JSRS];
-static int jsr_num;
-static struct hash_entry dummy_hash; /* This is for safety purposes only */
-
-
-static void jsr_stack_init(void)
-{
- jsr_num = 0;
- dummy_hash.execute = NULL;
-}
-
-void compiler_flush_jsr_stack(void)
-{
- jsr_num = 0;
-}
-
-void m68k_do_rts(void)
-{
- m68k_setpc(get_long(m68k_areg(regs, 7)));
- m68k_areg(regs, 7) += 4;
- if (jsr_num > 0)
- jsr_num--;
-}
-
-__inline__ void m68k_do_jsr(uaecptr oldpc, uaecptr dest)
-{
- struct hash_entry *h = find_hash(oldpc);
-
- if (jsr_num == MAX_JSRS)
- compiler_flush_jsr_stack();
- if (h == NULL) {
- jsr_hash[jsr_num] = &dummy_hash;
- jsr_rets[jsr_num++] = 0xC0DEDBAD;
- } else {
- jsr_hash[jsr_num] = h;
- jsr_rets[jsr_num++] = oldpc;
- }
- m68k_areg(regs, 7) -= 4;
- put_long(m68k_areg(regs, 7), oldpc);
- m68k_setpc(dest);
-}
-
-void m68k_do_bsr(uaecptr oldpc, uae_s32 offset)
-{
- m68k_do_jsr(oldpc, m68k_getpc() + offset);
-}
-
-/* Here starts the actual compiling part */
-
-static char *compile_current_addr;
-static char *compile_last_addr;
-
-STATIC_INLINE void assemble(uae_u8 a)
-{
- if (compile_current_addr < compile_last_addr) {
- *compile_current_addr++ = a;
- } else {
- compile_failure = 1;
- }
-}
-
-STATIC_INLINE void assemble_ulong(uae_u32 a)
-{
- assemble(a);
- assemble(a >> 8);
- assemble(a >> 16);
- assemble(a >> 24);
-}
-
-STATIC_INLINE void assemble_ulong_68k(uae_u32 a)
-{
- assemble(a >> 24);
- assemble(a >> 16);
- assemble(a >> 8);
- assemble(a);
-}
-
-STATIC_INLINE void assemble_uword(uae_u16 a)
-{
- assemble(a);
- assemble(a >> 8);
-}
-
-STATIC_INLINE void assemble_long(void *a)
-{
- assemble_ulong((uae_u32)a);
-}
-
-STATIC_INLINE void compile_org(char *addr)
-{
- compile_current_addr = addr;
-}
-
-STATIC_INLINE char *compile_here(void)
-{
- return compile_current_addr;
-}
-
-#define r_EAX 0
-#define r_ECX 1
-#define r_EDX 2
-#define r_EBX 3
-#define r_ESP 4
-#define r_EBP 5
-#define r_ESI 6
-#define r_EDI 7
-
-#define r_AH 0x84
-#define r_CH 0x85
-#define r_DH 0x86
-#define r_BH 0x87
-
-#define ALL_X86_REGS 255
-#define ADDRESS_X86_REGS ((1 << r_EBP) | (1 << r_ESI) | (1 << r_EDI))
-#define DATA_X86_REGS ((1 << r_EAX) | (1 << r_EDX) | (1 << r_EBX) | (1 << r_ECX))
-
-#define BO_NORMAL 0
-#define BO_SWAPPED_LONG 1
-#define BO_SWAPPED_WORD 2
-
-struct register_mapping {
- int dreg_map[8], areg_map[8]; /* 68000 register cache */
- int x86_const_offset[8];
- int x86_dirty[8];
- int x86_cache_reg[8]; /* Regs used for the 68000 register cache */
- int x86_cr_type[8]; /* Caching data or address register? */
- int x86_locked[8]; /* Regs used for some purpose */
- int x86_users[8];
- int x86_byteorder[8];
- int x86_verified[8];
-};
-
-/*
- * First, code to compile some primitive x86 instructions
- */
-
-static void compile_lea_reg_with_offset(int dstreg, int srcreg, uae_u32 srcoffs)
-{
- assemble(0x8D);
- if (srcreg == -2) {
- assemble(0x05 + 8*dstreg);
- assemble_ulong(srcoffs);
- } else if ((uae_s32)srcoffs >= -128 && (uae_s32)srcoffs <= 127) {
- assemble(0x40 + 8*dstreg + srcreg);
- assemble(srcoffs);
- } else {
- assemble(0x80 + 8*dstreg + srcreg);
- assemble_ulong(srcoffs);
- }
-}
-
-static void compile_move_reg_reg(int dstreg, int srcreg, wordsizes size)
-{
- if (size == sz_byte
- && (((1 << dstreg) & DATA_X86_REGS) == 0
- || ((1 << srcreg) & DATA_X86_REGS) == 0))
- {
- write_log ("Moving wrong register types!\n");
- }
- if (size == sz_word)
- assemble(0x66);
- if (size == sz_byte)
- assemble(0x88);
- else
- assemble(0x89);
- assemble(0xC0 + dstreg + 8*srcreg);
-}
-
-static void compile_move_between_reg_mem_regoffs(int dstreg, int srcreg,
- uae_u32 srcoffs, wordsizes size,
- int code)
-{
- if (size == sz_byte && (dstreg & 0x80) != 0)
- dstreg &= ~0x80;
- else if ((size == sz_byte
- && ((1 << dstreg) & DATA_X86_REGS) == 0)
- || (size != sz_byte && (dstreg & 0x80) != 0))
- {
- write_log ("Moving wrong register types!\n");
- }
- if (size == sz_word)
- assemble(0x66);
- if (size == sz_byte)
- assemble(code);
- else
- assemble(code + 1);
-
- if (srcreg == -2) {
- assemble(0x05 + 8*dstreg);
- assemble_ulong(srcoffs);
- } else if ((uae_s32)srcoffs >= -128 && (uae_s32)srcoffs <= 127) {
- assemble(0x40 + 8*dstreg + srcreg);
- assemble(srcoffs);
- } else {
- assemble(0x80 + 8*dstreg + srcreg);
- assemble_ulong(srcoffs);
- }
-}
-
-static void compile_move_reg_from_mem_regoffs(int dstreg, int srcreg,
- uae_u32 srcoffs, wordsizes size)
-{
- compile_move_between_reg_mem_regoffs(dstreg, srcreg, srcoffs, size, 0x8A);
-}
-
-static void compile_move_reg_to_mem_regoffs(int dstreg, uae_u32 dstoffs,
- int srcreg, wordsizes size)
-{
- compile_move_between_reg_mem_regoffs(srcreg, dstreg, dstoffs, size, 0x88);
-}
-
-static void compile_byteswap(int x86r, wordsizes size, int save_flags)
-{
- switch(size) {
- case sz_word:
- if (save_flags)
- assemble(0x9C);
- assemble(0x66); /* rolw $8,x86r */
- assemble(0xC1);
- assemble(0xC0 + x86r);
- assemble(8);
- if (save_flags)
- assemble(0x9D);
- break;
- case sz_long:
- assemble(0x0F); /* bswapl x86r */
- assemble(0xC8+x86r);
- break;
- default:
- break;
- }
-}
-
-static void compile_force_byteorder(struct register_mapping *map, int x86r,
- int desired_bo, int save_flags)
-{
- if (x86r < 0 || map->x86_byteorder[x86r] == desired_bo)
- return;
-
- if (map->x86_byteorder[x86r] == BO_SWAPPED_LONG)
- compile_byteswap(x86r, sz_long, save_flags);
- else if (map->x86_byteorder[x86r] == BO_SWAPPED_WORD)
- compile_byteswap(x86r, sz_word, save_flags);
-
- if (desired_bo == BO_SWAPPED_LONG)
- compile_byteswap(x86r, sz_long, save_flags);
- else if (desired_bo == BO_SWAPPED_WORD)
- compile_byteswap(x86r, sz_word, save_flags);
- map->x86_byteorder[x86r] = desired_bo;
-}
-
-/* Add a constant offset to a x86 register. If it's in the cache, make sure
- * we update the const_offset value. The flags are unaffected by this */
-
-static void compile_offset_reg(struct register_mapping *map, int x86r,
- uae_u32 offset)
-{
- int cached_68k;
-
- if (offset == 0 || x86r == -1 || x86r == -2)
- return;
-
- compile_force_byteorder(map, x86r, BO_NORMAL, 1);
- cached_68k = map->x86_cache_reg[x86r];
- if (cached_68k != -1) {
- map->x86_const_offset[x86r] -= offset;
- map->x86_dirty[x86r] = 1;
- }
- compile_lea_reg_with_offset(x86r, x86r, offset);
-}
-
-static int get_unused_x86_register(struct register_mapping *map)
-{
- int x86r;
- for (x86r = 0; x86r < 24; x86r++) {
- if (map->x86_cache_reg[x86r] != -1)
- continue;
- if (map->x86_users[x86r] > 0)
- continue;
-
- map->x86_verified[x86r] = 0;
- map->x86_byteorder[x86r] = BO_NORMAL;
- return x86r;
- }
- return -1;
-}
-
-/*
- * sync_reg() may not touch the flags
- * If may_clobber is 1 and the reg had an offset, the reg will be offsetted
- * by this function
- */
-static void sync_reg(struct register_mapping *map, int x86r, void *m68kr,
- uae_u32 offset, int dirty, int may_clobber)
-{
- if (dirty || offset != 0)
- compile_force_byteorder(map, x86r, BO_NORMAL, 1);
- if (offset != 0) {
- if (may_clobber) {
- compile_lea_reg_with_offset(x86r, x86r, offset);
- dirty = 1;
- } else {
- int tmpr = get_unused_x86_register(map);
- if (tmpr != -1) {
- compile_lea_reg_with_offset(tmpr, x86r, offset);
- x86r = tmpr;
- dirty = 1;
- } else {
- compile_lea_reg_with_offset(x86r, x86r, offset);
- assemble(0x89); /* movl x86r,m68kr */
- assemble(0x05 + (x86r << 3));
- assemble_long(m68kr);
- compile_lea_reg_with_offset(x86r, x86r, -offset);
- return;
- }
- }
- }
- if (dirty) {
- assemble(0x89); /* movl x86r,m68kr */
- assemble(0x05 + (x86r << 3));
- assemble_long(m68kr);
- }
-}
-
-static void sync_reg_cache(struct register_mapping *map, int flush)
-{
- int i;
-
- for (i = 0; i < 8; i++) {
- int cr68k = map->x86_cache_reg[i];
- if (cr68k != -1) {
- if (map->x86_cr_type[i] == 1) {
- sync_reg(map, i, regs.regs + cr68k, map->x86_const_offset[i], map->x86_dirty[i], 1);
- if (flush)
- map->dreg_map[cr68k] = -1;
- } else {
- sync_reg(map, i, regs.regs + 8 + cr68k, map->x86_const_offset[i], map->x86_dirty[i], 1);
- if (flush)
- map->areg_map[cr68k] = -1;
- }
- if (flush)
- map->x86_cache_reg[i] = -1;
- map->x86_const_offset[i] = 0;
- }
- }
- memset(map->x86_dirty, 0, sizeof map->x86_dirty);
-}
-
-static void remove_x86r_from_cache(struct register_mapping *map, int x86r,
- int may_clobber)
-{
- int j;
- int reg_68k;
-
- if (x86r == -1)
- return;
-
- reg_68k = map->x86_cache_reg[x86r];
-
- if (reg_68k == -1)
- return;
-
- if (map->x86_cr_type[x86r] == 1) {
- map->dreg_map[reg_68k] = -1;
- sync_reg(map, x86r, regs.regs + reg_68k, map->x86_const_offset[x86r],
- map->x86_dirty[x86r], may_clobber);
- } else {
- map->areg_map[reg_68k] = -1;
- sync_reg(map, x86r, regs.regs + 8 + reg_68k, map->x86_const_offset[x86r],
- map->x86_dirty[x86r], may_clobber);
- }
- map->x86_dirty[x86r] = 0;
- map->x86_cache_reg[x86r] = -1;
- map->x86_const_offset[x86r] = 0;
- map->x86_verified[x86r] = 0;
- map->x86_byteorder[x86r] = BO_NORMAL;
-}
-
-static int get_free_x86_register(struct register_mapping *map,
- int preferred_mask)
-{
- int cnt;
- for (cnt = 0; cnt < 24; cnt++) {
- int x86r = cnt & 7;
- /* In the first two passes, try to get one of the preferred regs */
- if (cnt < 16 && ((1 << x86r) & preferred_mask) == 0)
- continue;
- /* In the first pass, don't discard any registers from the cache */
- if (cnt < 8 && map->x86_cache_reg[x86r] != -1)
- continue;
- /* Never use locked registers */
- if (map->x86_users[x86r] > 0)
- continue;
-
- remove_x86r_from_cache(map, x86r, 1);
- map->x86_dirty[x86r] = 0;
- map->x86_cache_reg[x86r] = -1;
- map->x86_const_offset[x86r] = 0;
- map->x86_verified[x86r] = 0;
- map->x86_byteorder[x86r] = BO_NORMAL;
- return x86r;
- }
- printf("Out of registers!\n");
- return -1;
-}
-
-static int get_typed_x86_register(struct register_mapping *map,
- int preferred_mask)
-{
- int cnt;
- for (cnt = 0; cnt < 16; cnt++) {
- int x86r = cnt & 7;
- /* Get one of the preferred regs */
- if (((1 << x86r) & preferred_mask) == 0)
- continue;
- /* In the first pass, don't discard any registers from the cache */
- if (cnt < 8 && map->x86_cache_reg[x86r] != -1)
- continue;
- /* Never use locked registers */
- if (map->x86_users[x86r] > 0)
- continue;
-
- remove_x86r_from_cache(map, x86r, 1);
- map->x86_dirty[x86r] = 0;
- map->x86_cache_reg[x86r] = -1;
- map->x86_const_offset[x86r] = 0;
- map->x86_verified[x86r] = 0;
- map->x86_byteorder[x86r] = BO_NORMAL;
- return x86r;
- }
- printf("Out of type registers!\n");
- return -1;
-}
-
-static void compile_unlock_reg(struct register_mapping *map, int reg)
-{
- if (reg >= 0) {
- if (--map->x86_users[reg] == 0)
- map->x86_locked[reg] = 0;
-
- }
-}
-
-static void lock_reg(struct register_mapping *map, int x86r, int lock_type)
-{
-#if 1
- switch (map->x86_locked[x86r]) {
- case 0:
- if (map->x86_users[x86r] != 0)
- printf("Users for an unlocked reg!\n");
- break;
- case 1:
- if (lock_type == 2)
- printf("Locking shared reg for exclusive use!\n");
- break;
- case 2:
- printf("Locking exclusive reg!\n");
- break;
- default:
- printf("Unknown lock?\n");
- break;
- }
-#endif
- map->x86_locked[x86r] = lock_type;
- map->x86_users[x86r]++;
-}
-
-static int get_and_lock_68k_reg(struct register_mapping *map, int reg, int is_dreg,
- int preferred, int no_offset, int lock_type)
-{
- int x86r;
- int *regmap;
- uae_u32 *reghome;
- uae_u32 const_off = 0;
-
- if (reg < 0 || reg > 7) {
- printf("Mad compiler disease\n");
- return 0;
- }
-
- if (is_dreg)
- regmap = map->dreg_map, reghome = regs.regs;
- else
- regmap = map->areg_map, reghome = regs.regs + 8;
-
- if (preferred == 0)
- preferred = ALL_X86_REGS;
-
- x86r = regmap[reg];
- if (x86r == -1) {
- x86r = get_free_x86_register(map, preferred);
- assemble(0x8B); assemble(0x05 + (x86r << 3)); /* movl regs.d[reg],x86r */
- assemble_long(reghome + reg);
- map->x86_cache_reg[x86r] = reg;
- map->x86_cr_type[x86r] = is_dreg;
- map->x86_const_offset[x86r] = 0;
- map->x86_dirty[x86r] = 0;
- map->x86_verified[x86r] = 0;
- map->x86_byteorder[x86r] = BO_NORMAL;
- regmap[reg] = x86r;
- } else {
- const_off = map->x86_const_offset[x86r];
-
- if (map->x86_locked[x86r] == 2
- || (map->x86_locked[x86r] == 1 && (lock_type == 2 || (const_off != 0 && no_offset))))
- {
- int newr;
- int old_dirty = 0;
- int old_verified;
- int old_bo;
-
- newr = get_free_x86_register(map, preferred);
- if (const_off == 0) {
- compile_move_reg_reg(newr, x86r, sz_long);
- } else {
- compile_force_byteorder(map, x86r, BO_NORMAL, 1);
- compile_lea_reg_with_offset(newr, x86r, const_off);
- old_dirty = 1;
- const_off = 0;
- }
- /* Remove old reg from cache... */
- map->x86_cache_reg[x86r] = -1;
- map->x86_cr_type[x86r] = is_dreg;
- map->x86_const_offset[x86r] = 0;
- old_dirty |= map->x86_dirty[x86r];
- old_verified = map->x86_verified[x86r];
- old_bo = map->x86_byteorder[x86r];
- map->x86_verified[x86r] = 0;
- map->x86_dirty[x86r] = 0;
- x86r = newr;
- /* ... and make the new one the cache register */
- map->x86_cache_reg[x86r] = reg;
- map->x86_cr_type[x86r] = is_dreg;
- map->x86_const_offset[x86r] = 0;
- map->x86_dirty[x86r] = old_dirty;
- map->x86_verified[x86r] = old_verified;
- map->x86_byteorder[x86r] = old_bo;
- regmap[reg] = x86r;
- }
- }
- if (no_offset && const_off != 0) {
- if (map->x86_locked[x86r] != 0)
- printf("modifying locked reg\n");
- compile_force_byteorder(map, x86r, BO_NORMAL, 1);
- compile_lea_reg_with_offset(x86r, x86r, map->x86_const_offset[x86r]);
- map->x86_const_offset[x86r] = 0;
- map->x86_dirty[x86r] = 1;
- }
- lock_reg(map, x86r, lock_type);
- return x86r;
-}
-
-/*
- * Move a constant to a register. Don't do anything if we already have a
- * register, even if it is offset by a constant
- */
-
-static int compile_force_const_reg(struct register_mapping *map, int x86r,
- uae_u32 *offs, int desired)
-{
- int newr = x86r;
-
- if (newr == -2) {
- if (desired == 0)
- newr = get_free_x86_register(map, ALL_X86_REGS);
- else
- newr = get_typed_x86_register(map, desired);
-
- assemble(0xB8 + newr);
- assemble_ulong(*offs);
- *offs = 0;
- }
- map->x86_users[newr]++;
- return newr;
-}
-
-static void compile_extend_long(struct register_mapping *map, int x86r,
- wordsizes size)
-{
- if (x86r < 0) {
- printf("Bad reg in extend_long\n");
- return;
- }
-
- compile_force_byteorder(map, x86r, BO_NORMAL, 1);
-
- if (size != sz_long) {
- if (x86r == r_EAX && size == sz_word) {
- assemble(0x98); /* cwtl */
- } else {
- assemble(0x0F);
- if (size == sz_byte) {
- assemble(0xBE);
- } else {
- assemble(0xBF);
- }
- assemble(0xC0 + x86r*9);
- }
- }
-}
-
-struct ea_info {
- int reg;
- amodes mode;
- wordsizes size;
- int address_reg; /* The x86 reg holding the address, or -1 if ea doesn't refer to memory
- * -2 if it refers to memory, but only with a constant address */
- uae_u32 addr_const_off; /* Constant offset to the address */
- int data_reg; /* The x86 reg that holds the data. -1 if data is not present yet.
- * -2 if data is constant */
- uae_u32 data_const_off;
- int flags; /* Extra info. Contains the dp field of d8r modes */
- int purpose;
-};
-
-static void init_eainfo(struct ea_info *eai)
-{
- eai->address_reg = -1;
- eai->addr_const_off = 0;
- eai->data_reg = -1;
- eai->data_const_off = 0;
-}
-
-struct insn_reg_needs {
- int checkpoint_no;
- int dreg_needed[8], areg_needed[8];
- int dreg_mask[8], areg_mask[8];
-};
-
-/*
- * This structure holds information about predec/postinc addressing modes.
- */
-
-struct pid_undo {
- int used;
- int x86r[2];
- int m68kr[2];
- int dirty[2];
- int offs[2];
-};
-
-static void add_undo(struct pid_undo *pud, int x86r, int m68kr, int offs,
- int dirty)
-{
- int i;
- for (i = 0; i < pud->used; i++)
- if (pud->m68kr[i] == m68kr)
- return;
- pud->m68kr[i] = m68kr;
- pud->x86r[i] = x86r;
- pud->offs[i] = offs;
- pud->dirty[i] = dirty;
- pud->used++;
-}
-
-/*
- * Lock previous contents of address registers used in predec/postinc modes
- * for generate_possible_exit().
- */
-
-static void compile_prepare_undo(struct register_mapping *map, amodes mode,
- int reg, struct pid_undo *pud)
-{
- int x86r;
-
- switch(mode){
- default:
- break;
-
- case Apdi:
- x86r = get_and_lock_68k_reg(map, reg, 0, ADDRESS_X86_REGS, 0, 1);
- /* This saves recording the byteorder in the pud structure, and we'll
- * need it in normal byteorder anyway */
- compile_force_byteorder(map, x86r, BO_NORMAL, 0);
- /*
- * Add this reg with its current offset to the undo buffer.
- * Since we have locked it, we are certain that it will not be
- * modified.
- */
- add_undo(pud, x86r, reg, map->x86_const_offset[x86r], map->x86_dirty[x86r]);
- break;
-
- case Aipi:
- x86r = get_and_lock_68k_reg(map, reg, 0, ADDRESS_X86_REGS, 0, 1);
- compile_force_byteorder(map, x86r, BO_NORMAL, 0);
- add_undo(pud, x86r, reg, map->x86_const_offset[x86r], map->x86_dirty[x86r]);
- break;
- }
-}
-
-/*
- * Load all the registers absolutely needed to calculate and verify thea
- * address. Load other registers if convenient.
- * This contains a fair amount of magic to get the register cache working right.
- */
-
-static void compile_prepareea(struct register_mapping *map, amodes mode,
- int reg, wordsizes size, uae_u8 **pcpp, uaecptr pca,
- struct ea_info *eainf, int eaino, int ea_purpose,
- int pidmult)
-{
- struct ea_info *eai = eainf + eaino;
- int pdival = size == sz_byte && reg != 7 ? 1 : size == sz_long ? 4 : 2;
- uae_u8 *p = *pcpp;
- uae_u16 dp;
- int r;
- int x86r, tmpr;
-
- pdival *= pidmult;
-
- init_eainfo(eai);
- eai->mode = mode;
- eai->size = size;
- eai->reg = reg;
-
- switch(mode){
- case Dreg:
- case Areg:
- break;
-
- case Ad16:
- eai->addr_const_off = (uae_s16)do_get_mem_word((uae_u16 *)p);
- (*pcpp) += 2; p += 2;
- x86r = eai->address_reg = get_and_lock_68k_reg(map, reg, 0, ADDRESS_X86_REGS, 0, 1);
- compile_force_byteorder(map, x86r, BO_NORMAL, 0);
- eai->addr_const_off += map->x86_const_offset[x86r];
- break;
-
- case Aind:
- x86r = eai->address_reg = get_and_lock_68k_reg(map, reg, 0, ADDRESS_X86_REGS, 0, 1);
- compile_force_byteorder(map, x86r, BO_NORMAL, 0);
- eai->addr_const_off = map->x86_const_offset[x86r];
- break;
-
- case Apdi:
- x86r = eai->address_reg = get_and_lock_68k_reg(map, reg, 0, ADDRESS_X86_REGS, 0, 1);
- compile_force_byteorder(map, x86r, BO_NORMAL, 0);
- map->x86_const_offset[x86r] -= pdival;
- eai->addr_const_off = map->x86_const_offset[x86r];
- break;
-
- case Aipi:
- x86r = eai->address_reg = get_and_lock_68k_reg(map, reg, 0, ADDRESS_X86_REGS, 0, 1);
- compile_force_byteorder(map, x86r, BO_NORMAL, 0);
- eai->addr_const_off = map->x86_const_offset[x86r];
- map->x86_const_offset[x86r] += pdival;
- break;
-
- case Ad8r:
- dp = (uae_s16)do_get_mem_word((uae_u16 *)p);
- r = (dp & 0x7000) >> 12;
- (*pcpp) += 2; p += 2;
-
- tmpr = get_and_lock_68k_reg(map, reg, 0, ADDRESS_X86_REGS, 0, 1);
- compile_force_byteorder(map, tmpr, BO_NORMAL, 0);
- eai->addr_const_off = map->x86_const_offset[tmpr] + (uae_s8)dp;
-
- if (dp & 0x800) {
- x86r = get_and_lock_68k_reg(map, r, dp & 0x8000 ? 0 : 1, ADDRESS_X86_REGS, 0, 2);
- remove_x86r_from_cache(map, x86r, 0);
- compile_force_byteorder(map, x86r, BO_NORMAL, 0);
- eai->addr_const_off += map->x86_const_offset[x86r];
- } else {
- x86r = get_and_lock_68k_reg(map, r, dp & 0x8000 ? 0 : 1, ADDRESS_X86_REGS, 1, 2);
- remove_x86r_from_cache(map, x86r, 0);
- compile_force_byteorder(map, x86r, BO_NORMAL, 0);
- }
- eai->address_reg = x86r;
-
- r = (dp & 0x7000) >> 12;
-
- if (dp & 0x800) {
- if (eai->addr_const_off == 0) {
- assemble(0x03); assemble(0xC0 + tmpr + x86r*8); /* addl basereg,addrreg */
- } else if ((uae_s32)eai->addr_const_off >= -128 && (uae_s32)eai->addr_const_off <= 127) {
- assemble(0x8D);
- assemble(0x44 + x86r*8); /* leal disp8(dispreg,basereg),dispreg */
- assemble(x86r*8 + tmpr);
- assemble(eai->addr_const_off);
- } else {
- assemble(0x8D);
- assemble(0x84 + x86r*8); /* leal disp32(dispreg,basereg),dispreg */
- assemble(x86r*8 + tmpr);
- assemble_ulong(eai->addr_const_off);
- }
- eai->addr_const_off = 0;
- } else {
- assemble(0x0F); assemble(0xBF);
- assemble(0xC0 + x86r*9); /* movswl dispreg,addrreg */
- assemble(0x03); assemble(0xC0 + tmpr + x86r*8); /* addl basereg,addrreg */
- }
- compile_unlock_reg(map, tmpr);
- break;
-
- case PC8r:
- dp = (uae_s16)do_get_mem_word((uae_u16 *)p);
- (*pcpp) += 2; p += 2;
- r = (dp & 0x7000) >> 12;
- eai->addr_const_off = pca + (uae_s8)dp;
- if (dp & 0x800) {
- x86r = get_and_lock_68k_reg(map, r, dp & 0x8000 ? 0 : 1, ADDRESS_X86_REGS, 0, 1);
- remove_x86r_from_cache(map, x86r, 0);
- compile_force_byteorder(map, x86r, BO_NORMAL, 0);
- eai->addr_const_off += map->x86_const_offset[x86r];
- } else {
- x86r = get_and_lock_68k_reg(map, r, dp & 0x8000 ? 0 : 1, ADDRESS_X86_REGS, 1, 2);
- remove_x86r_from_cache(map, x86r, 0);
- compile_force_byteorder(map, x86r, BO_NORMAL, 0);
-
- assemble(0x0F); assemble(0xBF);
- assemble(0xC0 + x86r*9); /* movswl dispreg,addrreg */
- }
- eai->address_reg = x86r;
- break;
-
- case PC16:
- eai->addr_const_off = pca + (uae_s16)do_get_mem_word((uae_u16 *)p);
- eai->address_reg = -2;
- (*pcpp) += 2; p += 2;
- break;
-
- case absw:
- eai->addr_const_off = (uae_s16)do_get_mem_word((uae_u16 *)p);
- eai->address_reg = -2;
- (*pcpp) += 2; p += 2;
- break;
-
- case absl:
- eai->addr_const_off = (uae_s32)do_get_mem_long((uae_u32 *)p);
- eai->address_reg = -2;
- (*pcpp) += 4; p += 4;
- break;
-
- case imm:
- if (size == sz_long)
- goto imm2_const;
- if (size == sz_word)
- goto imm1_const;
-
- /* fall through */
- case imm0:
- eai->data_const_off = (uae_s8)*(p+1);
- eai->data_reg = -2;
- (*pcpp) += 2; p += 2;
- break;
-
- case imm1:
- imm1_const:
- eai->data_const_off = (uae_s16)do_get_mem_word((uae_u16 *)p);
- eai->data_reg = -2;
- (*pcpp) += 2; p += 2;
- break;
-
- case imm2:
- imm2_const:
- eai->data_const_off = (uae_s32)do_get_mem_long((uae_u32 *)p);
- eai->data_reg = -2;
- (*pcpp) += 4; p += 4;
- break;
-
- case immi:
- eai->data_const_off = (uae_s8)reg;
- eai->data_reg = -2;
- break;
-
- default:
- break;
- }
- eai->purpose = ea_purpose;
-}
-
-static void compile_get_excl_lock(struct register_mapping *map, struct ea_info *eai)
-{
- int x86r = eai->data_reg;
-
- if (x86r >= 0 && map->x86_locked[x86r] == 1) {
- int newr;
- if (eai->size == sz_byte)
- newr = get_typed_x86_register(map, DATA_X86_REGS);
- else
- newr = get_free_x86_register(map, ALL_X86_REGS);
-
- compile_move_reg_reg(newr, x86r, sz_long);
- eai->data_reg = newr;
- lock_reg(map, eai->data_reg, 2);
- }
-}
-
-/*
- * Some functions to assemble some 386 opcodes which have a similar
- * structure (ADD, AND, OR, etc.). These take source and destination
- * addressing modes, check their validity and assemble a complete
- * 386 instruction.
- */
-
-STATIC_INLINE int rmop_long(struct ea_info *eai)
-{
- if (eai->data_reg == -2)
- printf("rmop for const\n");
- else if (eai->data_reg == -1) {
- if (eai->address_reg == -2)
- return 5;
- if (eai->address_reg == -1) {
- /* This must be a 68k register in its home location */
- return 5;
- }
-#if 0 /* We need to add address_space... */
- if (eai->addr_const_off == 0 && eai->address_reg != r_EBP) {
- return eai->address_reg;
- }
- else if ((uae_s32)eai->addr_const_off >= -128 && (uae_s32)eai->addr_const_off <= 127) {
- return eai->address_reg | 0x40;
- }
-#endif
- return eai->address_reg | 0x80;
- } else {
- if (eai->size == sz_byte && ((1 << eai->data_reg) & DATA_X86_REGS) == 0)
- printf("wrong type reg in rmop\n");
- if (eai->data_const_off != 0)
- printf("data_const_off in rmop\n");
- return 0xC0 + eai->data_reg;
- }
- return 0;
-}
-
-STATIC_INLINE int rmop_short(struct ea_info *eai)
-{
- if (eai->data_reg == -2)
- printf("rmop_short for const\n");
- else if (eai->data_reg == -1) {
- printf("rmop_short for mem\n");
- } else {
- if (eai->size == sz_byte && ((1 << eai->data_reg) & DATA_X86_REGS) == 0)
- printf("wrong type reg in rmop_short\n");
- if (eai->data_const_off != 0)
- printf("data_const_off in rmop_short\n");
- return eai->data_reg*8;
- }
- return 0;
-}
-
-STATIC_INLINE void rmop_finalize(struct ea_info *eai)
-{
- if (eai->data_reg == -2)
- assemble_ulong(eai->data_const_off);
- else if (eai->data_reg == -1) {
- if (eai->address_reg == -2)
- /* Constant address */
- assemble_long(address_space + (uae_s32)eai->addr_const_off);
- else if (eai->address_reg == -1) {
- /* Register in its home location */
- if (eai->mode == Areg)
- assemble_long(regs.regs + 8 + eai->reg);
- else
- assemble_long(regs.regs + eai->reg);
- } else {
-#if 0
- /* Indirect address with offset */
- if ((uae_s32)eai->addr_const_off >= -128 && (uae_s32)eai->addr_const_off <= 127) {
- }
-#endif
- assemble_long(address_space + (uae_s32)eai->addr_const_off);
- }
- }
-}
-
-static void compile_eas(struct register_mapping *map, struct ea_info *eainf, int eaino_s, int eaino_d,
- int optype)
-{
- struct ea_info *eais = eainf + eaino_s;
- struct ea_info *eaid = eainf + eaino_d;
- int szflag = eais->size == sz_byte ? 0 : 1;
- int swapflag = 0;
- int opcode;
-
- if (eais->data_reg == -1) {
- compile_force_byteorder(map, eais->address_reg, BO_NORMAL, 0);
- eais = eainf + eaino_d;
- eaid = eainf + eaino_s;
- swapflag = 1;
- }
- if (eais->data_reg == -1) {
- compile_force_byteorder(map, eais->address_reg, BO_NORMAL, 0);
- }
-
- if (eais->size == sz_word)
- assemble(0x66);
-
- if (eais->data_reg == -2) {
- assemble(0x80+szflag);
- assemble(8*optype | rmop_long(eaid));
- rmop_finalize(eaid);
- switch(eais->size) {
- case sz_byte: assemble(eais->data_const_off); break;
- case sz_word: assemble_uword(eais->data_const_off); break;
- case sz_long: assemble_ulong(eais->data_const_off); break;
- }
- } else {
- assemble(8*optype | szflag | 2*swapflag);
- assemble(rmop_long(eaid) | rmop_short(eais));
- rmop_finalize(eaid);
- }
-}
-
-static void compile_fetchmem(struct register_mapping *map, struct ea_info *eai)
-{
- int x86r;
- if (eai->size == sz_byte)
- x86r = get_typed_x86_register(map, DATA_X86_REGS);
- else
- x86r = get_free_x86_register(map, ALL_X86_REGS);
-
- lock_reg(map, x86r, 2);
- compile_force_byteorder(map, eai->address_reg, BO_NORMAL, 0);
- compile_move_reg_from_mem_regoffs(x86r, eai->address_reg,
- (uae_u32)(eai->addr_const_off + address_space),
- eai->size);
- map->x86_verified[x86r] = 0;
- switch (eai->size) {
- case sz_byte: map->x86_byteorder[x86r] = BO_NORMAL; break;
- case sz_word: map->x86_byteorder[x86r] = BO_SWAPPED_WORD; break;
- case sz_long: map->x86_byteorder[x86r] = BO_SWAPPED_LONG; break;
- }
- eai->data_reg = x86r;
- eai->data_const_off = 0;
-}
-
-static void compile_fetchimm(struct register_mapping *map, struct ea_info *eai, int byteorder)
-{
- int x86r;
- if (eai->size == sz_byte)
- x86r = get_typed_x86_register(map, DATA_X86_REGS);
- else
- x86r = get_free_x86_register(map, ALL_X86_REGS);
-
- switch (byteorder) {
- case BO_SWAPPED_LONG:
- eai->data_const_off = (((eai->data_const_off & 0xFF000000) >> 24)
- | ((eai->data_const_off & 0xFF0000) >> 8)
- | ((eai->data_const_off & 0xFF00) << 8)
- | ((eai->data_const_off & 0xFF) << 24));
- break;
- case BO_SWAPPED_WORD:
- eai->data_const_off = (((eai->data_const_off & 0xFF00) >> 8)
- | ((eai->data_const_off & 0xFF) << 8)
- | (eai->data_const_off & 0xFFFF0000));
- break;
- case BO_NORMAL:
- break;
- }
- lock_reg(map, x86r, 2);
- map->x86_byteorder[x86r] = byteorder; map->x86_verified[x86r] = 0;
-
- switch (eai->size) {
- case sz_byte: assemble(0xC6); assemble(0xC0 + x86r); assemble(eai->data_const_off); break;
- case sz_word: assemble(0x66); assemble(0xC7); assemble(0xC0 + x86r); assemble_uword(eai->data_const_off); break;
- case sz_long: assemble(0xC7); assemble(0xC0 + x86r); assemble_ulong(eai->data_const_off); break;
- }
- eai->data_reg = x86r;
- eai->data_const_off = 0;
-}
-
-/*
- * 1: reg
- * 2: mem
- * 4: imm
- */
-
-static int binop_alternatives[] = {
- 7, 1,
- 5, 3,
- 0, 0
-};
-
-static int binop_worda_alternatives[] = {
- 1, 3,
- 0, 0
-};
-
-static int regonly_alternatives[] = {
- 1, 1,
- 0, 0
-};
-
-static void compile_loadeas(struct register_mapping *map, struct ea_info *eainf,
- int eaino_s, int eaino_d, int *alternatives,
- int scramble_poss, int load_dest)
-{
- struct ea_info *eais = eainf + eaino_s;
- struct ea_info *eaid = eainf + eaino_d;
- int scrambled_bo = eaid->size == sz_long ? BO_SWAPPED_LONG : eaid->size == sz_word ? BO_SWAPPED_WORD : BO_NORMAL;
- int i, scrambled = 0;
- int best = 0;
- int bestcost = -1;
- int *ap;
- uae_u32 *sregp = NULL, *dregp = NULL;
- int screg = -1, dcreg = -1;
- int stype = -1, dtype = -1;
- int asrc, adst;
- int regprefs = eais->size == sz_byte ? DATA_X86_REGS : 0;
-
- if (eais->mode == Dreg) {
- stype = 0;
- screg = map->dreg_map[eais->reg];
- if (screg == -1)
- sregp = regs.regs + eais->reg;
- } else if (eais->mode == Areg) {
- stype = 0;
- screg = map->areg_map[eais->reg];
- if (screg == -1)
- sregp = regs.regs + 8 + eais->reg;
- } else if (eais->data_reg == -2) {
- stype = -2;
- }
-
- if (eaid->mode == Dreg) {
- dtype = 0;
- dcreg = map->dreg_map[eaid->reg];
- if (dcreg == -1)
- dregp = regs.regs + eaid->reg;
- } else if (eaid->mode == Areg) {
- dtype = 0;
- dcreg = map->areg_map[eaid->reg];
- if (dcreg == -1)
- dregp = regs.regs + 8 + eaid->reg;
- } else if (eaid->data_reg == -2) {
- dtype = -2;
- }
-
- ap = alternatives;
-
- for (i = 0;; i++) {
- int cost = 0;
-
- asrc = *ap++;
- if (asrc == 0)
- break;
- adst = *ap++;
-
- if (stype == -2 && (asrc & 4) == 0)
- cost++;
- else if (stype == -1 && ((asrc & 2) == 0 || (eais->size != sz_byte && !scramble_poss)))
- cost++;
- else if (stype == 0 && screg == -1 && (asrc & 2) == 0)
- cost++;
-
- if (dtype == -1 && ((adst & 2) == 0 || (eaid->size != sz_byte && !scramble_poss)))
- /* The !load_dest case isn't handled by the current code,
- * and it isn't desirable anyway. Use a different alternative
- */
- cost += load_dest ? 1 : 100;
- else if (dtype == 0 && dcreg == -1 && (adst & 2) == 0)
- cost++;
-
- if (bestcost == -1 || cost < bestcost) {
- bestcost = cost;
- best = i;
- }
- }
-
- asrc = alternatives[2*best];
- adst = alternatives[2*best+1];
-
- if (dtype == -1) {
- if (load_dest) {
- if ((adst & 2) == 0 || (eaid->size != sz_byte && !scramble_poss))
- compile_fetchmem(map, eaid);
- } else {
- if ((adst & 2) == 0) {
- printf("Not loading memory operand. Prepare to die.\n");
- if (eaid->size == sz_byte)
- eaid->data_reg = get_typed_x86_register(map, DATA_X86_REGS);
- else
- eaid->data_reg = get_free_x86_register(map, ALL_X86_REGS);
- }
- }
- /* Scrambled in both mem and reg cases */
- if (eaid->size != sz_byte && scramble_poss)
- scrambled = 1;
- } else {
- if (dcreg == -1 && !load_dest && (adst & 2) == 0 && eaid->size == sz_long) {
- /* We need a register, but we don't need to fetch the old data.
- * See storeea for some more code handling this case. This first
- * if statement could be eliminated, we would generate some
- * superfluous moves. This is an optimization. If it were not
- * done, the mem-mem-move warning could be commented in in
- * storeea. */
- if (eaid->size == sz_byte)
- eaid->data_reg = get_typed_x86_register(map, DATA_X86_REGS);
- else
- eaid->data_reg = get_free_x86_register(map, ALL_X86_REGS);
- eaid->data_const_off = 0;
- } else if ((dcreg == -1 && (adst & 2) == 0) || dcreg != -1) {
- int reg_bo;
- eaid->data_reg = get_and_lock_68k_reg(map, eaid->reg, eaid->mode == Dreg, regprefs, 1, 2);
- eaid->data_const_off = 0;
-
- reg_bo = map->x86_byteorder[eaid->data_reg];
-
- if (reg_bo != BO_NORMAL) {
- if (reg_bo != scrambled_bo)
- compile_force_byteorder(map, eaid->data_reg, BO_NORMAL, 0);
- else if (scramble_poss)
- scrambled = 1;
- }
- }
- }
-
- if (stype == -2) {
- /* @@@ may need to scramble imm, this is a workaround */
- if ((asrc & 4) == 0 || scrambled)
- compile_fetchimm(map, eais, scrambled ? scrambled_bo : BO_NORMAL);
- } else if (stype == -1) {
- if ((asrc & 2) == 0 || (eais->size != sz_byte && !scrambled))
- compile_fetchmem(map, eais);
- } else {
- if ((screg == -1 && (asrc & 2) == 0) || screg != -1) {
- eais->data_reg = get_and_lock_68k_reg(map, eais->reg, eais->mode == Dreg, regprefs, 1, 2);
- eais->data_const_off = 0;
- }
- }
-
- /* Optimization */
- if (scrambled && eais->data_reg >= 0 && !load_dest
- && map->x86_byteorder[eais->data_reg] == BO_NORMAL
- && eaid->size == sz_long && dtype == 0)
- scrambled = 0;
-
- if (regprefs != 0 && eais->data_reg >= 0 && ((1 << eais->data_reg) & regprefs) == 0) {
- int tmpr = get_typed_x86_register(map, regprefs);
- compile_move_reg_reg(tmpr, eais->data_reg, sz_long);
- eais->data_reg = tmpr;
- }
-
- if (regprefs != 0 && eaid->data_reg >= 0 && ((1 << eaid->data_reg) & regprefs) == 0) {
- int tmpr = get_typed_x86_register(map, regprefs);
- compile_move_reg_reg(tmpr, eaid->data_reg, sz_long);
- eaid->data_reg = tmpr;
- }
-
- /* Now set the byteorder once and for all (should already be correct for
- * most cases) */
- if (scrambled) {
- if (eaid->data_reg >= 0)
- compile_force_byteorder(map, eaid->data_reg, scrambled_bo, 0);
- if (eais->data_reg >= 0)
- compile_force_byteorder(map, eais->data_reg, scrambled_bo, 0);
- } else {
- if (eaid->data_reg >= 0)
- compile_force_byteorder(map, eaid->data_reg, BO_NORMAL, 0);
- if (eais->data_reg >= 0)
- compile_force_byteorder(map, eais->data_reg, BO_NORMAL, 0);
- }
-}
-
-static void compile_fetchea(struct register_mapping *map, struct ea_info *eainf,
- int eaino, int asrc)
-{
- struct ea_info *eais = eainf + eaino;
- int scrambled_bo = eais->size == sz_long ? BO_SWAPPED_LONG : eais->size == sz_word ? BO_SWAPPED_WORD : BO_NORMAL;
- int i, scrambled = 0;
- int best = 0;
- int bestcost = -1;
- int *ap;
- uae_u32 *sregp = NULL;
- int screg = -1, stype = -1;
- int regprefs = eais->size == sz_byte ? DATA_X86_REGS : 0;
-
- if (eais->mode == Dreg) {
- stype = 0;
- screg = map->dreg_map[eais->reg];
- if (screg == -1)
- sregp = regs.regs + eais->reg;
- } else if (eais->mode == Areg) {
- stype = 0;
- screg = map->areg_map[eais->reg];
- if (screg == -1)
- sregp = regs.regs + 8 + eais->reg;
- } else if (eais->data_reg == -2) {
- stype = -2;
- }
-
- if (stype == -2) {
- if ((asrc & 4) == 0)
- compile_fetchimm(map, eais, scrambled ? scrambled_bo : BO_NORMAL);
- } else if (stype == -1) {
- if ((asrc & 2) == 0 || eais->size != sz_byte)
- compile_fetchmem(map, eais);
- } else {
- if ((screg == -1 && (asrc & 2) == 0) || screg != -1) {
- eais->data_reg = get_and_lock_68k_reg(map, eais->reg, eais->mode == Dreg, regprefs, 1, 2);
- eais->data_const_off = 0;
- }
- }
-
- if (eais->data_reg >= 0)
- compile_force_byteorder(map, eais->data_reg, BO_NORMAL, 0);
-}
-
-/*
- * compile_note_modify() should be called on destination EAs obtained from
- * compile_loadeas(), if their value was modified (e.g. by the compile_eas()
- * function)
- */
-
-static void compile_note_modify(struct register_mapping *map, struct ea_info *eainf,
- int eaino)
-{
- struct ea_info *eai = eainf + eaino;
- int newr;
- int szflag = eai->size == sz_byte ? 0 : 1;
-
- if (eai->mode == Dreg) {
- /* We only need to do something if we have the value in a register,
- * otherwise, the home location was modified already */
- if (eai->data_reg >= 0) {
- if (eai->data_reg != map->dreg_map[eai->reg]) {
- remove_x86r_from_cache(map, eai->data_reg, 0);
- if (map->dreg_map[eai->reg] >= 0)
- remove_x86r_from_cache(map, map->dreg_map[eai->reg], 0);
- map->x86_cache_reg[eai->data_reg] = eai->reg;
- map->x86_cr_type[eai->data_reg] = 1;
- map->dreg_map[eai->reg] = eai->data_reg;
- }
- map->x86_verified[eai->data_reg] = 0;
- map->x86_const_offset[eai->data_reg] = eai->data_const_off;
- map->x86_dirty[eai->data_reg] = 1;
- }
- return;
- } else if (eai->mode == Areg) {
- if (eai->size != sz_long)
- printf("Areg put != long\n");
-
- /* We only need to do something if we have the value in a register,
- * otherwise, the home location was modified already */
- if (eai->data_reg >= 0) {
- if (eai->data_reg != map->areg_map[eai->reg]) {
- remove_x86r_from_cache(map, eai->data_reg, 0);
- if (map->areg_map[eai->reg] >= 0)
- remove_x86r_from_cache(map, map->areg_map[eai->reg], 0);
- map->x86_cache_reg[eai->data_reg] = eai->reg;
- map->x86_cr_type[eai->data_reg] = 0;
- map->areg_map[eai->reg] = eai->data_reg;
- }
- map->x86_verified[eai->data_reg] = 0;
- map->x86_const_offset[eai->data_reg] = eai->data_const_off;
- map->x86_dirty[eai->data_reg] = 1;
- }
- return;
- } else {
- /* Storing to memory from reg? */
- if (eai->data_reg >= 0) {
- compile_offset_reg(map, eai->data_reg, eai->data_const_off);
-
- switch (eai->size) {
- case sz_byte: compile_force_byteorder(map, eai->data_reg, BO_NORMAL, 1); break;
- case sz_word: compile_force_byteorder(map, eai->data_reg, BO_SWAPPED_WORD, 1); break;
- case sz_long: compile_force_byteorder(map, eai->data_reg, BO_SWAPPED_LONG, 1); break;
- }
- compile_force_byteorder(map, eai->address_reg, BO_NORMAL, 0);
- compile_move_reg_to_mem_regoffs(eai->address_reg,
- (uae_u32)(eai->addr_const_off + address_space),
- eai->data_reg, eai->size);
- }
- }
-}
-
-static void compile_storeea(struct register_mapping *map, struct ea_info *eainf,
- int eaino_s, int eaino_d)
-{
- struct ea_info *eais = eainf + eaino_s;
- struct ea_info *eaid = eainf + eaino_d;
- int newr, cacher;
- int szflag = eaid->size == sz_byte ? 0 : 1;
-
- if (eaid->mode == Dreg) {
- /* Is the reg to move from already the register cache reg for the
- * destination? */
- if (eais->data_reg >= 0 && eais->data_reg == map->dreg_map[eaid->reg]) {
- map->x86_dirty[eais->data_reg] = 1; map->x86_verified[eais->data_reg] = 0;
- map->x86_const_offset[eais->data_reg] = eais->data_const_off;
- return;
- }
- /* Is the destination register in its home location? */
- if (map->dreg_map[eaid->reg] < 0) {
- if (eais->data_reg == -2) {
- /* Move immediate to regs.regs */
- if (eaid->size == sz_word) assemble(0x66);
- assemble(0xC6 + szflag); assemble(0x05); assemble_long(regs.regs + eaid->reg);
- switch (eaid->size) {
- case sz_byte: assemble(eais->data_const_off); break;
- case sz_word: assemble_uword(eais->data_const_off); break;
- case sz_long: assemble_ulong(eais->data_const_off); break;
- }
- } else if (eais->data_reg == -1) {
-#if 0
- printf("Shouldn't happen (mem-mem-move)\n");
-#endif
- /* This _can_ happen: move.l $4,d0, if d0 isn't in the
- * cache, will come here. But a reg will be allocated for
- * dest. We use this. This _really_ shouldn't happen if
- * the size isn't long. */
- if (eaid->size != sz_long)
- printf("_Really_ shouldn't happen (Dreg case)\n");
- map->x86_cache_reg[eaid->data_reg] = eaid->reg;
- map->x86_cr_type[eaid->data_reg] = 1;
- map->x86_const_offset[eaid->data_reg] = eaid->data_const_off;
- map->dreg_map[eaid->reg] = eaid->data_reg;
- map->x86_verified[eaid->data_reg] = 0;
- goto have_cache_reg_d;
- } else {
- if (eais->size == sz_long) {
- /* Make this the new register cache reg */
- remove_x86r_from_cache(map, eais->data_reg, 0);
- map->x86_cache_reg[eais->data_reg] = eaid->reg;
- map->x86_cr_type[eais->data_reg] = 1;
- map->x86_const_offset[eais->data_reg] = eais->data_const_off;
- map->dreg_map[eaid->reg] = eais->data_reg;
- map->x86_verified[eais->data_reg] = 0;
- } else {
- /* Move from reg to regs.regs */
- compile_force_byteorder(map, eais->data_reg, BO_NORMAL, 1);
- compile_offset_reg (map, eais->data_reg, eais->data_const_off);
- if (eaid->size == sz_word) assemble(0x66);
- assemble(0x88 + szflag); assemble(0x05 + 8*eais->data_reg);
- assemble_long(regs.regs + eaid->reg);
- }
- }
- } else {
- int destr;
-
- have_cache_reg_d:
-
- destr = map->dreg_map[eaid->reg];
- if (eaid->size != sz_long)
- compile_force_byteorder(map, destr, BO_NORMAL, 1);
-
- if (eais->data_reg == -2) {
- /* Move immediate to reg */
- if (eaid->size == sz_word) assemble(0x66);
- assemble(0xC6 + szflag); assemble(0xC0 + destr);
- switch (eaid->size) {
- case sz_byte: assemble(eais->data_const_off); break;
- case sz_word: assemble_uword(eais->data_const_off); break;
- case sz_long: assemble_ulong(eais->data_const_off); break;
- }
- /* normal byteorder comes either from force above or from long
- * const move */
- map->x86_byteorder[destr] = BO_NORMAL;
- } else if (eais->data_reg == -1) {
- if (eais->mode == Dreg) {
- compile_move_reg_from_mem_regoffs(destr, -2, (uae_u32)(regs.regs + eais->reg),
- eais->size);
- map->x86_byteorder[destr] = BO_NORMAL;
- } else if (eais->mode == Areg) {
- compile_move_reg_from_mem_regoffs(destr, -2, (uae_u32)(regs.regs + 8 + eais->reg),
- eais->size);
- map->x86_byteorder[destr] = BO_NORMAL;
- } else {
- /* Move mem to reg */
- compile_force_byteorder(map, eais->address_reg, BO_NORMAL, 0);
- compile_move_reg_from_mem_regoffs(destr, eais->address_reg,
- (uae_u32)(eais->addr_const_off + address_space),
- eais->size);
-
- switch (eais->size) {
- case sz_byte: map->x86_byteorder[destr] = BO_NORMAL; break;
- case sz_word: map->x86_byteorder[destr] = BO_SWAPPED_WORD; break;
- case sz_long: map->x86_byteorder[destr] = BO_SWAPPED_LONG; break;
- }
- }
- } else {
- if (eais->size == sz_long) {
- /* Make this the new register cache reg */
- remove_x86r_from_cache(map, eais->data_reg, 0);
- remove_x86r_from_cache(map, destr, 0);
- map->x86_cache_reg[eais->data_reg] = eaid->reg;
- map->x86_cr_type[eais->data_reg] = 1;
- map->x86_const_offset[eais->data_reg] = eais->data_const_off;
- map->dreg_map[eaid->reg] = eais->data_reg;
- map->x86_verified[eais->data_reg] = 0;
- } else {
- /* Move from reg to reg */
- compile_force_byteorder(map, eais->data_reg, BO_NORMAL, 1);
- compile_offset_reg (map, eais->data_reg, eais->data_const_off);
- if (eaid->size == sz_word) assemble(0x66);
- assemble(0x88 + szflag); assemble(0xC0 + destr + 8*eais->data_reg);
- }
- }
- }
-
- if (map->dreg_map[eaid->reg] >= 0)
- map->x86_dirty[map->dreg_map[eaid->reg]] = 1;
- return;
- } else if (eaid->mode == Areg) {
- if (eaid->size != sz_long)
- printf("Areg put != long\n");
-
- /* Is the reg to move from already the register cache reg for the
- * destination? */
- if (eais->data_reg >= 0 && eais->data_reg == map->areg_map[eaid->reg]) {
- map->x86_dirty[eais->data_reg] = 1; map->x86_verified[eais->data_reg] = 0;
- map->x86_const_offset[eais->data_reg] = eais->data_const_off;
- return;
- }
- /* Is the destination register in its home location? */
- if (map->areg_map[eaid->reg] < 0) {
- if (eais->data_reg == -2) {
- /* Move immediate to regs.regs */
- assemble(0xC7); assemble(0x05); assemble_long(regs.regs + 8 + eaid->reg);
- assemble_ulong(eais->data_const_off);
- } else if (eais->data_reg == -1) {
-#if 0 /* see above... */
- printf("Shouldn't happen (mem-mem-move)\n");
-#endif
- map->x86_cache_reg[eaid->data_reg] = eaid->reg;
- map->x86_cr_type[eaid->data_reg] = 0;
- map->x86_const_offset[eaid->data_reg] = eaid->data_const_off;
- map->areg_map[eaid->reg] = eaid->data_reg;
- map->x86_verified[eaid->data_reg] = 0;
- goto have_cache_reg_a;
- } else {
- /* Make this the new register cache reg */
- remove_x86r_from_cache(map, eais->data_reg, 0);
- map->x86_cache_reg[eais->data_reg] = eaid->reg;
- map->x86_cr_type[eais->data_reg] = 0;
- map->x86_const_offset[eais->data_reg] = eais->data_const_off;
- map->areg_map[eaid->reg] = eais->data_reg;
- map->x86_verified[eais->data_reg] = 0;
- }
- } else {
- int destr;
-
- have_cache_reg_a:
-
- destr = map->areg_map[eaid->reg];
- if (eaid->size != sz_long)
- compile_force_byteorder(map, destr, BO_NORMAL, 1);
-
- if (eais->data_reg == -2) {
- /* Move immediate to reg */
- assemble(0xC7); assemble(0xC0 + destr);
- assemble_ulong(eais->data_const_off);
-
- /* normal byteorder comes either from force above or from long
- * const move */
- map->x86_byteorder[destr] = BO_NORMAL;
- } else if (eais->data_reg == -1) {
- if (eais->mode == Dreg) {
- compile_move_reg_from_mem_regoffs(destr, -2, (uae_u32)(regs.regs + eais->reg),
- eais->size);
- map->x86_byteorder[destr] = BO_NORMAL;
- } else if (eais->mode == Areg) {
- compile_move_reg_from_mem_regoffs(destr, -2, (uae_u32)(regs.regs + 8 + eais->reg),
- eais->size);
- map->x86_byteorder[destr] = BO_NORMAL;
- } else {
- /* Move mem to reg */
- compile_force_byteorder(map, eais->address_reg, BO_NORMAL, 0);
- compile_move_reg_from_mem_regoffs(destr, eais->address_reg,
- (uae_u32)(eais->addr_const_off + address_space),
- eais->size);
-
- map->x86_byteorder[destr] = BO_SWAPPED_LONG;
- }
- } else {
- /* Make this the new register cache reg */
- remove_x86r_from_cache(map, eais->data_reg, 0);
- remove_x86r_from_cache(map, destr, 0);
- map->x86_cache_reg[eais->data_reg] = eaid->reg;
- map->x86_cr_type[eais->data_reg] = 0;
- map->x86_const_offset[eais->data_reg] = eais->data_const_off;
- map->areg_map[eaid->reg] = eais->data_reg;
- map->x86_verified[eais->data_reg] = 0;
- }
- }
-
- if (map->areg_map[eaid->reg] >= 0)
- map->x86_dirty[map->areg_map[eaid->reg]] = 1;
- return;
- }
-
- if (eais->data_reg == -1)
- printf("Storing to mem, but not from reg\n");
- /* Correct the byteorder */
- if (eais->data_reg != -2) {
- compile_offset_reg(map, eais->data_reg, eais->data_const_off);
-
- switch (eaid->size) {
- case sz_byte: compile_force_byteorder(map, eais->data_reg, BO_NORMAL, 1); break;
- case sz_word: compile_force_byteorder(map, eais->data_reg, BO_SWAPPED_WORD, 1); break;
- case sz_long: compile_force_byteorder(map, eais->data_reg, BO_SWAPPED_LONG, 1); break;
- }
- compile_force_byteorder(map, eaid->address_reg, BO_NORMAL, 0);
- compile_move_reg_to_mem_regoffs(eaid->address_reg,
- (uae_u32)(eaid->addr_const_off + address_space),
- eais->data_reg, eaid->size);
- } else {
- switch (eaid->size) {
- case sz_long:
- eais->data_const_off = (((eais->data_const_off & 0xFF000000) >> 24)
- | ((eais->data_const_off & 0xFF0000) >> 8)
- | ((eais->data_const_off & 0xFF00) << 8)
- | ((eais->data_const_off & 0xFF) << 24));
- break;
- case sz_word:
- eais->data_const_off = (((eais->data_const_off & 0xFF00) >> 8)
- | ((eais->data_const_off & 0xFF) << 8));
- break;
- }
- compile_force_byteorder(map, eaid->address_reg, BO_NORMAL, 0);
- /* generate code to move valueoffset,eaoffset(eareg) */
- switch(eaid->size) {
- case sz_byte: assemble(0xC6); break;
- case sz_word: assemble(0x66); /* fall through */
- case sz_long: assemble(0xC7); break;
- }
- if (eaid->address_reg == -2) { /* absolute or PC-relative */
- assemble(0x05);
- assemble_long(eaid->addr_const_off + address_space);
- } else {
- assemble(0x80 + eaid->address_reg);
- assemble_long(eaid->addr_const_off + address_space);
- }
- switch(eaid->size) {
- case sz_byte: assemble(eais->data_const_off); break;
- case sz_word: assemble_uword(eais->data_const_off); break;
- case sz_long: assemble_ulong(eais->data_const_off); break;
- }
- }
-}
-
-#define CE_STACK_SIZE 1000
-
-static struct {
- struct register_mapping map;
- char *jmpoffs;
- uae_u32 address;
- int noflush:1;
-} compile_exit_stack[CE_STACK_SIZE];
-
-static int cesp;
-
-static struct register_mapping current_exit_regmap;
-
-static void generate_exit(struct register_mapping *map, int address)
-{
- int i;
-
- if (map != NULL)
- sync_reg_cache (map, 1);
- assemble(0xB8); /* movl $new_pc,%eax */
- assemble_ulong(address);
- assemble(0xC3); /* RET */
-}
-
-static void copy_map_with_undo(struct register_mapping *dst,
- struct register_mapping *src,
- struct pid_undo *pud)
-{
- int i;
- *dst = *src;
- for (i = 0; i < pud->used; i++) {
- int m68kr = pud->m68kr[i];
- int x86r = pud->x86r[i];
- int old_cr = dst->areg_map[m68kr];
- if (old_cr != -1) {
- dst->x86_cache_reg[old_cr] = -1;
- }
- dst->x86_cache_reg[x86r] = m68kr;
- dst->areg_map[m68kr] = x86r;
- dst->x86_cr_type[x86r] = 0;
- dst->x86_const_offset[x86r] = pud->offs[i];
- dst->x86_dirty[x86r] = pud->dirty[i];
- }
-}
-
-static void unlock_pud(struct register_mapping *map, struct pid_undo *pud)
-{
- int i;
- for (i = 0; i < pud->used; i++) {
- compile_unlock_reg(map, pud->x86r[i]);
- }
-}
-
-static int exits_necessary;
-
-static void generate_possible_exit(struct register_mapping *map,
- struct ea_info *eai, int iip,
- struct pid_undo *pud)
-{
- struct register_mapping exit_regmap;
-
- if (!exits_necessary) {
- unlock_pud(map, pud);
- return;
- }
-
- compile_force_byteorder(map, eai->address_reg, BO_NORMAL, 0);
- switch (eai->address_reg) {
- case -1:
- /* EA doesn't refer to memory */
- break;
- case -2:
- /* Only a constant offset */
- eai->addr_const_off &= (1<<24)-1;
- if (!good_address_map[eai->addr_const_off]) {
- copy_map_with_undo(&exit_regmap, map, pud);
- generate_exit(&exit_regmap, insn_info[iip].address);
- }
- break;
- default:
- if (map->x86_verified[eai->address_reg])
- break;
- map->x86_verified[eai->address_reg] = 1;
- if (cesp == CE_STACK_SIZE) {
- copy_map_with_undo(&exit_regmap, map, pud);
- generate_exit(&exit_regmap, insn_info[iip].address);
- break;
- }
- copy_map_with_undo(&compile_exit_stack[cesp].map, map, pud);
- compile_exit_stack[cesp].address = insn_info[iip].address;
- assemble(0x80); assemble(0xB8 + eai->address_reg); /* cmpb $0, good_address_map(x86r) */
- assemble_long(good_address_map + eai->addr_const_off);
- assemble(0);
- assemble(0x0F); assemble(0x84); /* JE finish */
- compile_exit_stack[cesp].jmpoffs = compile_here();
- compile_exit_stack[cesp].noflush = 0;
- assemble_ulong(0);
- cesp++;
- break;
- }
- unlock_pud(map, pud);
-}
-
-static void finish_exits(void)
-{
- int i;
- for (i = 0; i < cesp; i++) {
- char *exitpoint = compile_here();
- char *nextpoint;
-
- if (compile_exit_stack[i].noflush)
- generate_exit(NULL, compile_exit_stack[i].address);
- else
- generate_exit(&compile_exit_stack[i].map, compile_exit_stack[i].address);
- nextpoint = compile_here();
- compile_org(compile_exit_stack[i].jmpoffs);
- assemble_ulong(exitpoint - (compile_exit_stack[i].jmpoffs + 4));
- compile_org(nextpoint);
- }
-}
-
-static void finish_condjumps(int lastiip)
-{
- int iip;
- char *lastptr = compile_here();
- for (iip = 0; iip < lastiip; iip++) {
- char *fillin = insn_info[iip].compiled_fillin;
- if (fillin != NULL) {
- compile_org(insn_info[iip].compiled_fillin);
- assemble_ulong(insn_info[insn_info[iip].jumps_to].compiled_jumpaddr - (fillin + 4));
- }
- }
- compile_org(lastptr);
-}
-
-#define CC_X_FROM_86C 1
-#define CC_C_FROM_86C 2
-#define CC_Z_FROM_86Z 4
-#define CC_V_FROM_86V 8
-#define CC_N_FROM_86N 16
-#define CC_TEST_REG 32
-#define CC_Z_FROM_86C 64
-#define CC_SAHF 128
-#define CC_TEST_CONST 256
-#define CC_AFTER_RO 512
-#define CC_AFTER_ROX 1024
-
-static unsigned int cc_status;
-static int cc_reg;
-static uae_u32 cc_offset;
-static wordsizes cc_size;
-
-static void compile_do_cc_test_reg(struct register_mapping *map)
-{
- compile_force_byteorder(map, cc_reg, BO_NORMAL, 1);
- if (cc_offset != 0)
- printf("Pull my finger\n");
- if (cc_size == sz_word) /* test ccreg */
- assemble(0x66);
- if (cc_size == sz_byte)
- assemble(0x84);
- else
- assemble(0x85);
- assemble(0xC0 + 9*cc_reg);
-}
-
-static int compile_flush_cc_cache(struct register_mapping *map, int status,
- int live_at_end, int user_follows,
- int user_live_at_end, int user_ccval)
-{
- int status_for_user = 0;
-
- if (user_follows) {
- int need_for_user = 0;
- int user_flagmask = cc_flagmask_68k(user_ccval);
-
- if (user_flagmask & CC68K_C)
- need_for_user |= CC_C_FROM_86C;
- if (user_flagmask & CC68K_Z)
- need_for_user |= CC_Z_FROM_86Z;
- if (user_flagmask & CC68K_N)
- need_for_user |= CC_N_FROM_86N;
- if (user_flagmask & CC68K_V)
- need_for_user |= CC_V_FROM_86V;
-
- /* Check whether we can satisfy the user's needs in a simple way. */
- if ((need_for_user & status) == need_for_user)
- status_for_user = status;
- else if (user_flagmask == CC68K_Z && status == CC_Z_FROM_86C)
- status_for_user = status;
- else if (status == CC_TEST_REG && (user_flagmask & (CC68K_C|CC68K_V|CC68K_Z|CC68K_N)) != 0) {
- if (cc_reg == -2) {
- status_for_user = CC_TEST_CONST;
- } else {
- compile_do_cc_test_reg(map);
- status_for_user = status = (CC_C_FROM_86C | CC_Z_FROM_86Z | CC_N_FROM_86N | CC_V_FROM_86V);
- }
- } else if (status == CC_AFTER_RO) {
- /* We fake some information here... */
- if (user_flagmask == CC68K_C && (user_live_at_end & ~CC68K_C) == 0)
- status = status_for_user = CC_C_FROM_86C;
- else if (((user_flagmask | user_live_at_end) & (CC68K_C|CC68K_V)) == 0) {
- status = CC_TEST_REG; user_live_at_end = CC68K_Z|CC68K_N|CC68K_V;
- status_for_user = (CC_C_FROM_86C | CC_Z_FROM_86Z | CC_N_FROM_86N | CC_V_FROM_86V);
- } else
- status_for_user = CC_SAHF;
- } else if (status == CC_AFTER_ROX) {
- if (user_flagmask == CC68K_C && (user_live_at_end & ~(CC68K_C|CC68K_X)) == 0)
- status = status_for_user = CC_C_FROM_86C;
- else if (((user_flagmask | user_live_at_end) & (CC68K_C|CC68K_X|CC68K_V)) == 0) {
- status = CC_TEST_REG; user_live_at_end = CC68K_Z|CC68K_N|CC68K_V;
- status_for_user = (CC_C_FROM_86C | CC_Z_FROM_86Z | CC_N_FROM_86N | CC_V_FROM_86V);
- } else
- status_for_user = CC_SAHF;
- } else if (need_for_user != 0) {
- /* No way to handle it easily */
- status_for_user = CC_SAHF;
- }
- if (status_for_user != CC_SAHF)
- live_at_end = user_live_at_end;
- }
-
- /*
- * Now store the flags which are live at the end of this insn and set by
- * us into their home locations
- */
- if (status == CC_TEST_REG) {
- if ((live_at_end & (CC68K_C|CC68K_V|CC68K_Z|CC68K_N)) == 0)
- goto all_ok;
-
- if (cc_reg == -2) {
- uae_u8 f = 0;
- if (cc_size == sz_byte) {
- f |= (cc_offset & 0x80) ? 0x80 : 0;
- f |= (cc_offset & 0xFF) == 0 ? 0x40 : 0;
- } else if (cc_size == sz_byte) {
- f |= (cc_offset & 0x8000) ? 0x80 : 0;
- f |= (cc_offset & 0xFFFF) == 0 ? 0x40 : 0;
- } else {
- f |= (cc_offset & 0x80000000) ? 0x80 : 0;
- f |= (cc_offset & 0xFFFFFFFF) == 0 ? 0x40 : 0;
- }
- assemble(0xC7); assemble(0x05);
- assemble_long((char*)®flags);
- assemble_uword(f);
- } else {
- int tmpr = get_free_x86_register(map, ALL_X86_REGS);
- compile_do_cc_test_reg(map);
-
- /* pushfl; popl tmpr; movl tempr, regflags */
- assemble(0x9C); assemble(0x58+tmpr);
- compile_move_reg_to_mem_regoffs(-2, (uae_u32)®flags, tmpr, sz_long);
- }
- } else if (status == CC_Z_FROM_86C) {
- if ((live_at_end & CC68K_Z) != 0) {
- int tmpr = get_typed_x86_register(map, DATA_X86_REGS);
- assemble(0x9C);
- /* setnc tmpr; shl $6, tmpr; andb $~0x40, regflags; orb tmpr, regflags */
- assemble(0x0F); assemble(0x93); assemble(0xC0 + tmpr);
- assemble(0xC0); assemble(4*8 + 0xC0 + tmpr); assemble(6);
- assemble(0x80); assemble(0x05+0x20); assemble_long(®flags); assemble((uae_u8)~0x40);
- assemble(0x08); assemble(0x05+ tmpr*8); assemble_long(®flags);
- assemble(0x9D);
- }
- } else if (status == CC_AFTER_RO || status == CC_AFTER_ROX) {
- int tmpr = get_typed_x86_register(map, DATA_X86_REGS);
- assemble(0x9C);
- compile_do_cc_test_reg(map);
- /* pushfl; popl tmpr; andl $0xff,tmpr (mask out V flag which is cleared after rotates) */
- assemble(0x9C); assemble(0x58 + tmpr);
- assemble(0x81); assemble(0xC0 + tmpr + 8*4); assemble_ulong(0xFF);
- assemble(0x9D);
- /* adc $0, tmpr */
- assemble(0x80); assemble(0xC0 + tmpr + 8*2); assemble(0);
- compile_move_reg_to_mem_regoffs(-2, (uae_u32)®flags, tmpr, sz_long);
- if (status == CC_AFTER_ROX)
- compile_move_reg_to_mem_regoffs(-2, 4 + (uae_u32)®flags, tmpr, sz_long);
- } else if (status != 0) {
- assert((status & CC_TEST_REG) == 0);
- assert (status == (CC_C_FROM_86C | CC_Z_FROM_86Z | CC_N_FROM_86N | CC_X_FROM_86C | CC_V_FROM_86V)
- || status == (CC_C_FROM_86C | CC_Z_FROM_86Z | CC_N_FROM_86N | CC_V_FROM_86V)
- || status == CC_C_FROM_86C);
-
- if ((status & CC_X_FROM_86C) == 0)
- live_at_end &= ~CC68K_X;
-
- if (status == CC_C_FROM_86C && (live_at_end & CC68K_C) != 0)
- write_log ("Shouldn't be needing C here!\n");
- else if (live_at_end) {
- if ((live_at_end & CC68K_X) == 0)
- status &= ~CC_X_FROM_86C;
-
- if (live_at_end) {
- if ((status & CC_X_FROM_86C) != 0 && live_at_end == CC68K_X) {
- /* SETC regflags + 4 */
- assemble(0x0F); assemble(0x92);
- assemble(0x05); assemble_long(4 + (uae_u32)®flags);
- } else {
- int tmpr = get_free_x86_register(map, ALL_X86_REGS);
- /* pushfl; popl tmpr; movl tempr, regflags */
- assemble(0x9C); assemble(0x58+tmpr);
- compile_move_reg_to_mem_regoffs(-2, (uae_u32)®flags, tmpr, sz_long);
-
- if (status & CC_X_FROM_86C) {
- compile_move_reg_to_mem_regoffs(-2, 4 + (uae_u32)®flags, tmpr, sz_word);
- }
- }
- }
- }
- }
-
- all_ok:
- return status_for_user;
-}
-
-static char *compile_condbranch(struct register_mapping *map, int iip,
- int new_cc_status)
-{
- int cc = insn_info[iip].dp->cc;
- int flagsused = cc_flagmask_68k(cc);
- int flagsneeded = 0;
- char *undo_pointer = compile_here();
-
- if (flagsused & CC68K_C)
- flagsneeded |= CC_C_FROM_86C;
- if (flagsused & CC68K_Z)
- flagsneeded |= CC_Z_FROM_86Z;
- if (flagsused & CC68K_N)
- flagsneeded |= CC_N_FROM_86N;
- if (flagsused & CC68K_V)
- flagsneeded |= CC_V_FROM_86V;
-
- if (flagsneeded == 0)
- /* Fine */;
- else if (new_cc_status == CC_SAHF) {
- int tmpr = get_free_x86_register(map, ALL_X86_REGS);
- compile_move_reg_from_mem_regoffs(tmpr, -2, (uae_u32)®flags, sz_long);
- assemble(0x66); assemble(0x50+tmpr); assemble(0x66); assemble(0x9D);
- new_cc_status = CC_C_FROM_86C|CC_Z_FROM_86Z|CC_N_FROM_86N|CC_V_FROM_86V;
- } else if (new_cc_status == CC_TEST_CONST) {
- int n,z;
- switch(cc_size) {
- case sz_byte: n = ((uae_s8)cc_offset) < 0; z = ((uae_s8)cc_offset) == 0; break;
- case sz_word: n = ((uae_s16)cc_offset) < 0; z = ((uae_s16)cc_offset) == 0; break;
- case sz_long: n = ((uae_s32)cc_offset) < 0; z = ((uae_s32)cc_offset) == 0; break;
- }
-#define Bcc_TRUE 0
-#define Bcc_FALSE 1
- flagsneeded = 0;
- new_cc_status = 0;
- switch (cc) {
- case 2: cc = !z ? Bcc_TRUE : Bcc_FALSE; break; /* !CFLG && !ZFLG */
- case 3: cc = z ? Bcc_TRUE : Bcc_FALSE; break; /* CFLG || ZFLG */
- case 4: cc = Bcc_TRUE; break; /* !CFLG */
- case 5: cc = Bcc_FALSE; break; /* CFLG */
- case 6: cc = !z ? Bcc_TRUE : Bcc_FALSE; break; /* !ZFLG */
- case 7: cc = z ? Bcc_TRUE : Bcc_FALSE; break; /* ZFLG */
- case 8: cc = Bcc_TRUE; break; /* !VFLG */
- case 9: cc = Bcc_FALSE; break; /* VFLG */
- case 10:cc = !n ? Bcc_TRUE : Bcc_FALSE; break; /* !NFLG */
- case 11:cc = n ? Bcc_TRUE : Bcc_FALSE; break; /* NFLG */
- case 12:cc = !n ? Bcc_TRUE : Bcc_FALSE; break; /* NFLG == VFLG */
- case 13:cc = n ? Bcc_TRUE : Bcc_FALSE; break; /* NFLG != VFLG */
- case 14:cc = !n && !z ? Bcc_TRUE : Bcc_FALSE; break; /* !ZFLG && (NFLG == VFLG) */
- case 15:cc = n || z ? Bcc_TRUE : Bcc_FALSE; break; /* ZFLG || (NFLG != VFLG) */
- }
- } else if (new_cc_status == CC_Z_FROM_86C) {
- if (cc == 6 || cc == 7) {
- cc = (cc - 2) ^ 1;
- /* Fake... */
- flagsneeded = new_cc_status = CC_C_FROM_86C;
- } else if (cc != 0 && cc != 1)
- printf("Groan!\n");
- }
-
- if (cc == 1)
- return NULL;
-
- if ((flagsneeded & new_cc_status) == flagsneeded) {
- char *result;
- /* We can generate a simple branch */
- if (cc == 0)
- assemble(0xE9);
- else
- assemble(0x0F);
- switch(cc) {
- case 2: assemble(0x87); break; /* HI */
- case 3: assemble(0x86); break; /* LS */
- case 4: assemble(0x83); break; /* CC */
- case 5: assemble(0x82); break; /* CS */
- case 6: assemble(0x85); break; /* NE */
- case 7: assemble(0x84); break; /* EQ */
- case 8: assemble(0x81); break; /* VC */
- case 9: assemble(0x80); break; /* VS */
- case 10:assemble(0x89); break; /* PL */
- case 11:assemble(0x88); break; /* MI */
- case 12:assemble(0x8D); break; /* GE */
- case 13:assemble(0x8C); break; /* LT */
- case 14:assemble(0x8F); break; /* GT */
- case 15:assemble(0x8E); break; /* LE */
- }
- result = compile_here();
- assemble_ulong(0);
- return result;
- }
- printf("Uhhuh.\n");
- return NULL;
-}
-
-static void compile_handle_bcc(struct register_mapping *map, int iip,
- int new_cc_status)
-{
- insn_info[iip].compiled_fillin = compile_condbranch(map, iip, new_cc_status);
-}
-
-static void compile_handle_dbcc(struct register_mapping *map, int iip,
- int new_cc_status, int dreg)
-{
- char *fillin1 = compile_condbranch(map, iip, new_cc_status);
-
- /* subw $1,dreg; jnc ... */
- assemble(0x66); assemble(0x83); assemble(0x05 + 5*8);
- assemble_long(regs.regs + dreg);
- assemble(1);
- assemble(0x0F); assemble(0x83);
- insn_info[iip].compiled_fillin = compile_here();
- assemble_ulong(0);
- if (fillin1 != NULL) {
- char *oldp = compile_here();
- compile_org(fillin1);
- assemble_ulong(oldp - (fillin1+4));
- compile_org(oldp);
- }
-}
-
-static void handle_bit_insns(struct register_mapping *map, struct ea_info *eainf,
- int eaino_s, int eaino_d, instrmnem optype)
-{
- struct ea_info *srcea = eainf + eaino_s, *dstea = eainf + eaino_d;
- int code = (optype == i_BTST ? 0
- : optype == i_BSET ? 1
- : optype == i_BCLR ? 2
- : /* optype == i_BCHG */ 3);
-
- compile_fetchea(map, eainf, eaino_s, 5);
- compile_fetchea(map, eainf, eaino_d, 3);
-
- if (srcea->data_reg != -2) {
- compile_force_byteorder(map, srcea->data_reg, BO_NORMAL, 0);
- remove_x86r_from_cache(map, srcea->data_reg, 0);
- /* andl $something,srcreg */
- assemble(0x83); assemble(0xC0 + 4*8 + srcea->data_reg);
- if (dstea->size == sz_byte)
- assemble(7);
- else
- assemble(31);
- } else
- if (dstea->size == sz_byte)
- srcea->data_const_off &= 7;
- else
- srcea->data_const_off &= 31;
-
- /* Areg isn't possible here */
- if (dstea->mode == Dreg && dstea->data_reg == -1) {
- if (srcea->data_reg == -2) {
- assemble(0x0F); assemble(0xBA); assemble(5 + 8*(4 + code));
- assemble_long(regs.regs + dstea->reg);
- assemble(srcea->data_const_off);
- } else {
- assemble(0x0F); assemble(0xA3 + 8*code);
- assemble(5 + srcea->data_reg*8);
- assemble_long(regs.regs + dstea->reg);
- }
- } else if (dstea->data_reg >= 0) {
- compile_force_byteorder(map, dstea->data_reg, BO_NORMAL, 0);
- if (srcea->data_reg == -2) {
- assemble(0x0F); assemble(0xBA); assemble(0xC0 + dstea->data_reg + 8*(4 + code));
- assemble(srcea->data_const_off);
- } else {
- assemble(0x0F); assemble(0xA3 + 8*code);
- assemble(0xC0 + dstea->data_reg + srcea->data_reg*8);
- }
- if (optype != i_BTST)
- map->x86_dirty[dstea->data_reg] = 1;
- } else {
- int addr_code = dstea->address_reg == -2 ? 5 : dstea->address_reg + 0x80;
- compile_force_byteorder(map, dstea->address_reg, BO_NORMAL, 0);
- /* We have an address in memory */
- if (dstea->data_reg != -1)
- printf("Things don't look good in handle_bit_insns\n");
- if (srcea->data_reg == -2) {
- assemble(0x0F); assemble(0xBA);
- assemble(addr_code + 8*(4 + code));
- assemble_long(address_space + dstea->addr_const_off);
- assemble(srcea->data_const_off);
- } else {
- assemble(0x0F); assemble(0xA3 + 8*code);
- assemble(addr_code + srcea->data_reg*8);
- assemble_long(address_space + dstea->addr_const_off);
- }
-
- }
- cc_status = CC_Z_FROM_86C;
-}
-
-static int do_rotshi = 1;
-
-static void handle_rotshi(struct register_mapping *map, int iip,
- uae_u8 *realpc, uaecptr current_addr, struct pid_undo *pud)
-{
- struct ea_info eai;
- int amode_reg = insn_info[iip].dp->sreg;
- int amode_mode = insn_info[iip].dp->smode;
- wordsizes size = insn_info[iip].dp->size;
- int shiftcount;
- int mnemo = insn_info[iip].dp->mnemo;
- int shiftcode;
- int locked_eax_for_sahf = 0;
-
- switch(mnemo) {
- case i_ASLW: shiftcount = 1; mnemo = i_ASL; break;
- case i_ASRW: shiftcount = 1; mnemo = i_ASR; break;
- case i_LSLW: shiftcount = 1; mnemo = i_LSL; break;
- case i_LSRW: shiftcount = 1; mnemo = i_LSR; break;
- case i_ROLW: shiftcount = 1; mnemo = i_ROL; break;
- case i_RORW: shiftcount = 1; mnemo = i_ROR; break;
- case i_ROXLW:shiftcount = 1; mnemo = i_ROXL;break;
- case i_ROXRW:shiftcount = 1; mnemo = i_ROXR;break;
- default:
- amode_reg = insn_info[iip].dp->dreg;
- amode_mode = insn_info[iip].dp->dmode;
- shiftcount = insn_info[iip].dp->sreg;
- break;
- }
- if ((insn_info[iip].flags_live_at_end & CC68K_V) != 0) {
- if (mnemo == i_ASL) {
- generate_exit(map, insn_info[iip].address);
- printf("Can't handle this shift\n");
- return;
- } else if (mnemo == i_ASR || mnemo == i_LSR || mnemo == i_LSL) {
- remove_x86r_from_cache(map, r_EAX, 1);
- locked_eax_for_sahf = 1;
- lock_reg(map, r_EAX, 2);
- }
-
- }
- if (mnemo == i_ROXR || mnemo == i_ROXL) {
- remove_x86r_from_cache(map, r_EAX, 1);
- lock_reg(map, r_EAX, 2);
- compile_move_reg_from_mem_regoffs(r_AH, -2, 4 + (uae_u32)®flags, sz_byte);
- }
- compile_prepare_undo(map, amode_mode, amode_reg, pud);
- compile_prepareea(map, amode_mode, amode_reg, size,
- &realpc, current_addr,
- &eai, 0, EA_LOAD|EA_STORE|EA_MODIFY, 1);
-
- generate_possible_exit(map, &eai, iip, pud);
-
- compile_fetchea(map, &eai, 0, 1);
- compile_force_byteorder(map, eai.data_reg, BO_NORMAL, 0);
-
- switch (mnemo) {
- case i_ASL:
- shiftcode = 4; cc_status = CC_C_FROM_86C | CC_Z_FROM_86Z | CC_N_FROM_86N | CC_V_FROM_86V | CC_X_FROM_86C;
- break;
- case i_LSL:
- shiftcode = 4; cc_status = CC_C_FROM_86C | CC_Z_FROM_86Z | CC_N_FROM_86N | CC_V_FROM_86V | CC_X_FROM_86C;
- break;
- case i_LSR:
- shiftcode = 5; cc_status = CC_C_FROM_86C | CC_Z_FROM_86Z | CC_N_FROM_86N | CC_V_FROM_86V | CC_X_FROM_86C;
- break;
- case i_ASR:
- shiftcode = 7; cc_status = CC_C_FROM_86C | CC_Z_FROM_86Z | CC_N_FROM_86N | CC_V_FROM_86V | CC_X_FROM_86C;
- break;
- case i_ROR:
- shiftcode = 1; cc_status = CC_AFTER_RO;
- break;
- case i_ROL:
- shiftcode = 0; cc_status = CC_AFTER_RO;
- break;
- case i_ROXL:
- shiftcode = 2; assemble(0x9E); /* SAHF */ cc_status = CC_AFTER_ROX; compile_unlock_reg(map, r_EAX);
- break;
- case i_ROXR:
- shiftcode = 3; assemble(0x9E); /* SAHF */ cc_status = CC_AFTER_ROX; compile_unlock_reg(map, r_EAX);
- break;
- }
-
- if (size == sz_word)
- assemble(0x66);
- assemble((shiftcount == 1 ? 0xD0 : 0xC0) + (size == sz_byte ? 0 : 1));
- assemble(shiftcode*8+0xC0 + eai.data_reg);
- if (shiftcount != 1) assemble(shiftcount);
- cc_offset = 0; cc_size = size; cc_reg = eai.data_reg;
-
- if (locked_eax_for_sahf) {
- /* The trick here is that the overflow flag isn't put into AH in SAHF */
- assemble(0x9E);
- assemble(0x0B); assemble(9*1 + 0xC0);
- assemble(0x9F);
- compile_unlock_reg(map, r_EAX);
- }
- compile_note_modify(map, &eai, 0);
-}
-
-static void handle_rotshi_variable(struct register_mapping *map, int iip,
- uae_u8 *realpc, uaecptr current_addr,
- struct pid_undo *pud)
-{
- struct ea_info eais, eaid;
- int mnemo = insn_info[iip].dp->mnemo;
- int shiftcode;
- char *tmp1, *tmp2;
- int locked_eax_for_sahf = 0;
-
- remove_x86r_from_cache(map, r_ECX, 1);
- lock_reg(map, r_ECX, 2);
-
- if ((insn_info[iip].flags_live_at_end & CC68K_V) != 0) {
- if (mnemo == i_ASL) {
- generate_exit(map, insn_info[iip].address);
- printf("Can't handle this shift (var)\n");
- return;
- } else if (mnemo == i_ASR || mnemo == i_LSR || mnemo == i_LSL) {
- remove_x86r_from_cache(map, r_EAX, 1);
- locked_eax_for_sahf = 1;
- lock_reg(map, r_EAX, 2);
- }
-
- }
- if (mnemo == i_ROXR || mnemo == i_ROXL) {
- remove_x86r_from_cache(map, r_EAX, 1);
- lock_reg(map, r_EAX, 2);
- compile_move_reg_from_mem_regoffs(r_AH, -2, 4 + (uae_u32)®flags,
- sz_byte);
- }
- /* Both src and dest are Dreg modes */
- compile_prepareea(map, insn_info[iip].dp->smode, insn_info[iip].dp->sreg,
- sz_long, &realpc, current_addr,
- &eais, 0, EA_LOAD, 1);
- compile_prepareea(map, insn_info[iip].dp->dmode, insn_info[iip].dp->dreg,
- insn_info[iip].dp->size, &realpc, current_addr,
- &eaid, 0, EA_LOAD|EA_STORE|EA_MODIFY, 1);
-
- compile_fetchea(map, &eais, 0, 1);
- compile_fetchea(map, &eaid, 1, 1);
- compile_force_byteorder(map, eais.data_reg, BO_NORMAL, 0);
- compile_force_byteorder(map, eaid.data_reg, BO_NORMAL, 0);
- compile_move_reg_reg(r_ECX, eais.data_reg, sz_long);
- /* Test against zero, and test bit 6. If 1 <= count <= 31, we can do the
- * operation, otherwise, we have to exit */
- assemble(0xF6); assemble(0xC0 + r_ECX); assemble(0x1F);
- assemble(0x74); assemble(9);
- assemble(0xF6); assemble(0xC0 + r_ECX); assemble(0x20);
-
- assemble(0x0F); assemble(0x85); tmp1 = compile_here(); assemble_ulong(0);
- generate_exit(map, insn_info[iip].address);
- tmp2 = compile_here(); compile_org (tmp1); assemble_ulong((tmp2-tmp1) + 4); compile_org(tmp2);
-
- switch (mnemo) {
- case i_ASL:
- shiftcode = 4; cc_status = CC_C_FROM_86C | CC_Z_FROM_86Z | CC_N_FROM_86N | CC_V_FROM_86V | CC_X_FROM_86C;
- break;
- case i_LSL:
- shiftcode = 4; cc_status = CC_C_FROM_86C | CC_Z_FROM_86Z | CC_N_FROM_86N | CC_V_FROM_86V | CC_X_FROM_86C;
- break;
- case i_LSR:
- shiftcode = 5; cc_status = CC_C_FROM_86C | CC_Z_FROM_86Z | CC_N_FROM_86N | CC_V_FROM_86V | CC_X_FROM_86C;
- break;
- case i_ASR:
- shiftcode = 7; cc_status = CC_C_FROM_86C | CC_Z_FROM_86Z | CC_N_FROM_86N | CC_V_FROM_86V | CC_X_FROM_86C;
- break;
- case i_ROR:
- shiftcode = 1; cc_status = CC_AFTER_RO;
- break;
- case i_ROL:
- shiftcode = 0; cc_status = CC_AFTER_RO;
- break;
- case i_ROXL:
- shiftcode = 2; assemble(0x9E); /* SAHF */ cc_status = CC_AFTER_ROX; compile_unlock_reg(map, r_EAX);
- break;
- case i_ROXR:
- shiftcode = 3; assemble(0x9E); /* SAHF */ cc_status = CC_AFTER_ROX; compile_unlock_reg(map, r_EAX);
- break;
- }
-
- if (insn_info[iip].dp->size == sz_word)
- assemble(0x66);
- assemble(0xD2 + (insn_info[iip].dp->size == sz_byte ? 0 : 1));
- assemble(shiftcode*8+0xC0 + eaid.data_reg);
- cc_offset = 0; cc_size = insn_info[iip].dp->size; cc_reg = eaid.data_reg;
-
- if (locked_eax_for_sahf) {
- /* The trick here is that the overflow flag isn't put into AH in SAHF */
- assemble(0x9E);
- assemble(0x0B); assemble(9*1 + 0xC0);
- assemble(0x9F);
- compile_unlock_reg(map, r_EAX);
- }
- compile_note_modify(map, &eaid, 0);
- compile_unlock_reg(map, r_ECX);
-}
-
-static uae_u32 testmask = 0xF80000, testval = 0xF80000;
-
-static int m68k_compile_block(struct hash_block *hb)
-{
- int movem_extra = 0;
- int last_iip = m68k_scan_block(hb, &movem_extra);
- struct register_mapping map;
- int i, iip, szflag;
- uae_u8 *realpc_start = NULL;
- struct bb_info *current_bb;
- int cc_status_for_bcc = CC_SAHF;
- struct insn_reg_needs reg_needs_init;
-
- cesp = 0;
-
- if (n_compiled > n_max_comp)
- return 1;
- else if (n_compiled++ == n_max_comp)
- printf("X\n");
-
- cc_status = 0; compile_failure = 0;
-
- /* Kickstart ROM address? */
- if ((hb->he_first->addr & 0xF80000) != 0xF80000
- && 0 && !patched_syscalls)
- return 1;
-
- exits_necessary = ((hb->he_first->addr & 0xF80000) == 0xF80000 || !USER_PROGRAMS_BEHAVE);
-
- if (alloc_code (hb, last_iip + movem_extra) == NULL) {
- hb->allocfailed = 1;
- return 0;
- }
- compile_org(hb->compile_start);
- compile_last_addr = (char *)hb->compile_start + hb->alloclen;
-
- /* m68k_scan_block() will leave this all set up */
- current_bb = bb_stack;
-
- for (i = 0; i < 8; i++) {
- map.dreg_map[i] = map.areg_map[i] = -1;
- map.x86_dirty[i] = 0;
- map.x86_cache_reg[i] = -1;
- map.x86_cr_type[i] = 0;
- map.x86_const_offset[i] = 0;
- map.x86_verified[i] = 0;
- map.x86_byteorder[i] = BO_NORMAL;
- }
-
- reg_needs_init.checkpoint_no = 0;
- for (i = 0; i < 8; i++) {
- reg_needs_init.dreg_needed[i] = reg_needs_init.areg_needed[i] = -1;
- reg_needs_init.dreg_mask[i] = reg_needs_init.areg_mask[i] = ALL_X86_REGS;
- }
-
- for (iip = 0; iip < last_iip && !compile_failure; iip++) {
- uae_u8 *realpc;
- struct ea_info eainfo[8];
- uaecptr current_addr;
- struct pid_undo pub;
- struct insn_reg_needs this_reg_needs = reg_needs_init;
-
- /* Set up locks for a new insn. We don't bother to clear this
- * properly after compiling one insn. */
- for (i = 0; i < 8; i++) {
- map.x86_users[i] = i == r_ESP ? 1 : 0;
- map.x86_locked[i] = i == r_ESP ? 2 : 0;
- }
-
- pub.used = 0;
- current_addr = insn_info[iip].address + 2;
-
- if (iip == current_bb->first_iip) {
- sync_reg_cache(&map, 1);
- if (!quiet_compile)
- printf("Compiling %08lx\n", current_bb->h->addr);
-
- realpc_start = get_real_address(current_bb->h->addr);
- current_bb->h->execute = (code_execfunc)compile_here();
- current_bb->h->matchword = *(uae_u32 *)realpc_start;
- cc_status_for_bcc = CC_SAHF;
- }
-
- realpc = realpc_start + (current_addr - current_bb->h->addr);
-
- insn_info[iip].compiled_jumpaddr = compile_here();
- insn_info[iip].compiled_fillin = NULL;
-
- if (insn_info[iip].jump_target) {
- if (cesp == CE_STACK_SIZE) {
- generate_exit(NULL, insn_info[iip].address);
- compile_failure = 1;
- } else {
- assemble(0xFE); assemble(0x05 + 8*1); assemble_long(&nr_bbs_to_run);
- assemble(0x0F); assemble(0x84); /* JE finish */
- compile_exit_stack[cesp].noflush = 1;
- compile_exit_stack[cesp].address = current_bb->h;
- compile_exit_stack[cesp].jmpoffs = compile_here();
- assemble_ulong(0);
- cesp++;
- }
- }
- /*
- * This will sort out all insns we can't compile, including
- * jumps out of this block */
- if (insn_info[iip].stop_translation == 1) {
- generate_exit(&map, insn_info[iip].address);
- cc_status = 0;
- } else switch (insn_info[iip].dp->mnemo) {
- case i_NOP:
- cc_status = 0;
- if (!quiet_compile)
- printf("Compiling a NOP\n");
- break;
-
- case i_RTS:
- sync_reg_cache(&map, 1);
- lock_reg(&map, r_ECX, 2);
- lock_reg(&map, r_EBX, 2);
- {
- char *tmp1, *tmp2, *tmp3;
-
- /* fetch (A7) */
- assemble(0x8B); assemble(0x5 + r_EBX*8); assemble_long(regs.regs + 15);
- assemble(0x8B); assemble(0x80 + 9*r_EBX); assemble_long(address_space);
- assemble(0x0F); /* bswapl x86r */
- assemble(0xC8 + r_EBX);
- /* fetch jsr_num */
- assemble(0x8B); assemble(0x5 + r_ECX*8); assemble_long(&jsr_num);
- assemble(0x09); assemble(0xC0 + 9*r_ECX);
- assemble(0x0F); assemble(0x84); tmp1 = compile_here(); assemble_ulong(0);
- assemble(0xFF); assemble(1*8 + 0xC0 + r_ECX);
- /* cmpl %ebx,disp32(,%ecx,4) */
- assemble(0x39); assemble(0x04 + 8*r_EBX); assemble(0x8d);
- assemble_long(jsr_rets);
- assemble(0x0F); assemble(0x85); tmp2 = compile_here(); assemble_ulong(0);
- /* movl disp32(,%ecx,4),%ebx */
- assemble(0x8B); assemble(0x04 + 8*r_EBX); assemble(0x8d);
- assemble_long(jsr_hash);
- /* movl execute(%ebx), %ebx */
- assemble(0x8B); assemble(0x040 + 9*r_EBX); assemble((int)&((struct hash_entry *)0)->execute);
- assemble(0x09); assemble(0xC0 + 9*r_EBX);
- assemble(0x0F); assemble(0x85); tmp3 = compile_here(); assemble_ulong(0);
- compile_org(tmp1); assemble_ulong(tmp3 - tmp1);
- compile_org(tmp2); assemble_ulong(tmp3 - tmp2);
- compile_org(tmp3 + 4);
- generate_exit(&map, insn_info[iip].address);
- tmp1 = compile_here();
- compile_org(tmp3); assemble_ulong((tmp1-tmp3)-4);
- compile_org(tmp1);
- assemble(0x89); assemble(0x5 + r_ECX*8); assemble_long(&jsr_num);
- assemble(0x83); assemble(0x05 + 5*8); assemble_long(regs.regs + 15); assemble(-4);
- /* Off we go */
- assemble(0xFF); assemble(4*8 + 0xC0 + r_EBX);
- }
- break;
-
- case i_JMP:
- sync_reg_cache(&map, 1);
- compile_prepareea(&map, insn_info[iip].dp->smode,
- insn_info[iip].dp->sreg,
- insn_info[iip].dp->size, &realpc, current_addr,
- eainfo, 0, EA_LOAD, 1);
- {
- char *tmp1, *tmp2, *tmp3;
-
- struct hash_entry *tmph;
- if (eainfo[0].address_reg != -2 || (tmph = get_hash_for_func(eainfo[0].addr_const_off, 1)) == 0) {
- if (eainfo[0].address_reg != -2 && !quiet_compile)
- printf("Can't compile indirect JMP\n");
- generate_exit(&map, insn_info[iip].address);
- break;
- }
- /* check whether the destination has compiled code */
- assemble(0x8B); assemble(r_EBX*8 + 0x05); assemble_long(&(tmph->execute));
- assemble(0x09); assemble(0xC0 + 9*r_EBX);
- assemble(0x0F); assemble(0x85); tmp1 = compile_here(); assemble_ulong(0);
- generate_exit(&map, insn_info[iip].address);
- tmp2 = compile_here(); compile_org(tmp1);
- assemble_ulong((tmp2 - tmp1) - 4);
- compile_org(tmp2);
- /* Off we go */
- assemble(0xFF); assemble(4*8 + 0xC0 + r_EBX);
- }
- cc_status = 0;
- break;
-
- case i_JSR:
- sync_reg_cache(&map, 1);
- lock_reg(&map, r_ECX, 2);
- lock_reg(&map, r_EBX, 2);
- compile_prepareea(&map, insn_info[iip].dp->smode,
- insn_info[iip].dp->sreg,
- insn_info[iip].dp->size, &realpc, current_addr,
- eainfo, 0, EA_LOAD, 1);
- {
- char *tmp1, *tmp2, *tmp3;
-
- struct hash_entry *tmph;
- if (eainfo[0].address_reg != -2 || (tmph = get_hash_for_func(eainfo[0].addr_const_off, 1)) == 0) {
- if (eainfo[0].address_reg != -2 && !quiet_compile)
- printf("Can't compile indirect JSR\n");
- generate_exit(&map, insn_info[iip].address);
- break;
- }
- assert(iip + 1 < last_iip);
- assert(iip == current_bb->last_iip);
- /* check whether the destination has compiled code */
- assemble(0x8B); assemble(r_EBX*8 + 0x05); assemble_long(&(tmph->execute));
- assemble(0x09); assemble(0xC0 + 9*r_EBX);
- assemble(0x0F); assemble(0x84); tmp3 = compile_here(); assemble_ulong(0);
- /* check for stack overflow */
- assemble(0x8B); assemble(r_ECX*8 + 0x05); assemble_long(&jsr_num);
- assemble(0xF7); assemble(0xC0+r_ECX); assemble_ulong(MAX_JSRS);
- assemble(0x0F); assemble(0x84); tmp1 = compile_here(); assemble_ulong(0);
- generate_exit(&map, insn_info[iip].address);
- tmp2 = compile_here(); compile_org(tmp1); assemble_ulong((tmp2 - tmp1) - 4);
- compile_org(tmp3); assemble_ulong(tmp1-tmp3);
- compile_org(tmp2);
- /* movl $something,disp32(,%ecx,4) */
- assemble(0xC7); assemble(0x04); assemble(0x8d);
- assemble_long(jsr_rets); assemble_ulong(insn_info[iip+1].address);
- assemble(0xC7); assemble(0x04); assemble(0x8d);
- assemble_long(jsr_hash); assemble_long((current_bb + 1)->h);
- /* incl jsr_num */
- assemble(0xFF); assemble(0x05); assemble_long(&jsr_num);
- /* Put things on the 68k stack */
- assemble(0x83); assemble(0x05 + 5*8); assemble_long(regs.regs + 15); assemble(4);
- assemble(0x8B); assemble(r_ECX*8+ 0x05); assemble_long(regs.regs + 15);
- assemble(0xC7); assemble(0x80 + r_ECX); assemble_long(address_space);
- assemble_ulong_68k(insn_info[iip+1].address);
- /* Off we go */
- assemble(0xFF); assemble(4*8 + 0xC0 + r_EBX);
- }
- break;
-
- case i_BSR:
- sync_reg_cache(&map, 1);
- lock_reg(&map, r_ECX, 2);
- lock_reg(&map, r_EBX, 2);
- compile_prepareea(&map, insn_info[iip].dp->smode,
- insn_info[iip].dp->sreg,
- insn_info[iip].dp->size, &realpc, current_addr,
- eainfo, 0, EA_LOAD, 1);
- {
- char *tmp1, *tmp2, *tmp3;
- uaecptr dest = insn_info[iip].address + 2 + (uae_s32)eainfo[0].data_const_off;
- struct hash_entry *tmph;
- if ((tmph = get_hash_for_func(dest, 1)) == 0) {
- generate_exit(&map, insn_info[iip].address);
- break;
- }
- assert(iip + 1 < last_iip);
- assert(iip == current_bb->last_iip);
-
- /* check whether the destination has compiled code */
- assemble(0x8B); assemble(r_EBX*8 + 0x05); assemble_long(&(tmph->execute));
- assemble(0x09); assemble(0xC0 + 9*r_EBX);
- assemble(0x0F); assemble(0x84); tmp3 = compile_here(); assemble_ulong(0);
- /* check for stack overflow */
- assemble(0x8B); assemble(r_ECX*8 + 0x05); assemble_long(&jsr_num);
- assemble(0xF7); assemble(0xC0+r_ECX); assemble_ulong(MAX_JSRS);
- assemble(0x0F); assemble(0x84); tmp1 = compile_here(); assemble_ulong(0);
- generate_exit(&map, insn_info[iip].address);
- tmp2 = compile_here(); compile_org(tmp1); assemble_ulong((tmp2 - tmp1) - 4);
- compile_org(tmp3); assemble_ulong(tmp1-tmp3);
- compile_org(tmp2);
- /* movl $something,disp32(,%ecx,4) */
- assemble(0xC7); assemble(0x04); assemble(0x8d);
- assemble_long(jsr_rets); assemble_ulong(insn_info[iip+1].address);
- assemble(0xC7); assemble(0x04); assemble(0x8d);
- assemble_long(jsr_hash); assemble_long((current_bb + 1)->h);
- /* incl jsr_num */
- assemble(0xFF); assemble(0x05); assemble_long(&jsr_num);
- /* Put things on the 68k stack */
- assemble(0x83); assemble(0x05 + 5*8); assemble_long(regs.regs + 15); assemble(4);
- assemble(0x8B); assemble(r_ECX*8+ 0x05); assemble_long(regs.regs + 15);
- assemble(0xC7); assemble(0x80 + r_ECX); assemble_long(address_space);
- assemble_ulong_68k(insn_info[iip+1].address);
- /* Off we go */
- assemble(0xFF); assemble(4*8 + 0xC0 + r_EBX);
- }
- break;
-
- case i_Bcc:
- sync_reg_cache(&map, 0);
- compile_handle_bcc(&map, iip, cc_status_for_bcc);
- cc_status = 0;
- break;
-
- case i_DBcc:
- sync_reg_cache(&map, 0);
- remove_x86r_from_cache(&map, map.dreg_map[insn_info[iip].dp->sreg], 1);
- compile_handle_dbcc(&map, iip, cc_status_for_bcc,
- insn_info[iip].dp->sreg);
- cc_status = 0;
- break;
-#if 0
- case i_Scc:
- compile_prepare_undo(&map, insn_info[iip].dp->smode, insn_info[iip].dp->sreg, &pub);
- compile_prepareea(&map, insn_info[iip].dp->smode,
- insn_info[iip].dp->sreg,
- insn_info[iip].dp->size, &realpc, current_addr,
- eainfo, 0, EA_STORE, 1);
-
- generate_possible_exit(&map, eainfo, iip, &pub);
- srcreg2 = get_;
- compile_note_modify(&map, eainfo, 0);
-
- cc_status = 0;
- break;
-#endif
- case i_ADD:
- case i_SUB:
- case i_CMP:
- case i_CMPM:
- compile_prepare_undo(&map, insn_info[iip].dp->smode, insn_info[iip].dp->sreg, &pub);
- compile_prepare_undo(&map, insn_info[iip].dp->dmode, insn_info[iip].dp->dreg, &pub);
- compile_prepareea(&map, insn_info[iip].dp->smode,
- insn_info[iip].dp->sreg,
- insn_info[iip].dp->size, &realpc, current_addr,
- eainfo, 0, EA_LOAD, 1);
- compile_prepareea(&map, insn_info[iip].dp->dmode,
- insn_info[iip].dp->dreg,
- insn_info[iip].dp->size, &realpc, current_addr,
- eainfo, 1,
- (insn_info[iip].dp->mnemo == i_ADD || insn_info[iip].dp->mnemo == i_SUB
- ? EA_MODIFY | EA_LOAD | EA_STORE
- : EA_LOAD | EA_STORE), 1);
-
- generate_possible_exit(&map, eainfo, iip, &pub);
- generate_possible_exit(&map, eainfo+1, iip, &pub);
-
- compile_loadeas(&map, eainfo, 0, 1, binop_alternatives, 0, 1);
-
- switch (insn_info[iip].dp->mnemo) {
- case i_ADD: compile_eas(&map, eainfo, 0, 1, 0); break;
- case i_SUB: compile_eas(&map, eainfo, 0, 1, 5); break;
- case i_CMP: case i_CMPM: compile_eas(&map, eainfo, 0, 1, 7); break;
- }
-
- if (insn_info[iip].dp->mnemo != i_CMP && insn_info[iip].dp->mnemo != i_CMPM)
- compile_note_modify(&map, eainfo, 1);
- switch (insn_info[iip].dp->mnemo) {
- case i_ADD:
- case i_SUB:
- cc_status = CC_X_FROM_86C | CC_Z_FROM_86Z | CC_C_FROM_86C | CC_V_FROM_86V | CC_N_FROM_86N;
- break;
- case i_CMP:
- case i_CMPM:
- cc_status = CC_Z_FROM_86Z | CC_C_FROM_86C | CC_V_FROM_86V | CC_N_FROM_86N;
- break;
- }
- break;
-
- case i_ADDX:
- case i_SUBX:
- compile_prepare_undo(&map, insn_info[iip].dp->smode, insn_info[iip].dp->sreg, &pub);
- compile_prepare_undo(&map, insn_info[iip].dp->dmode, insn_info[iip].dp->dreg, &pub);
- compile_prepareea(&map, insn_info[iip].dp->smode,
- insn_info[iip].dp->sreg,
- insn_info[iip].dp->size, &realpc, current_addr,
- eainfo, 0, EA_LOAD, 1);
- compile_prepareea(&map, insn_info[iip].dp->dmode,
- insn_info[iip].dp->dreg,
- insn_info[iip].dp->size, &realpc, current_addr,
- eainfo, 1, EA_MODIFY | EA_LOAD | EA_STORE, 1);
-
- generate_possible_exit(&map, eainfo, iip, &pub);
- generate_possible_exit(&map, eainfo+1, iip, &pub);
-
- compile_loadeas(&map, eainfo, 0, 1, binop_alternatives, 0, 1);
-
- /* bt $0, regflags+4 ; get carry */
- assemble(0x0F); assemble(0xBA); assemble(0x5+4*8);
- assemble_ulong(4 + (uae_u32)®flags); assemble(0);
-
- switch (insn_info[iip].dp->mnemo) {
- case i_ADDX: compile_eas(&map, eainfo, 0, 1, 2); break;
- case i_SUBX: compile_eas(&map, eainfo, 0, 1, 3); break;
- }
- compile_note_modify(&map, eainfo, 1);
-
- if (insn_info[iip].flags_live_at_end & CC68K_Z) {
- /* Darn. */
- int tmpr = get_free_x86_register(&map, ALL_X86_REGS);
- /* pushfl; popl tmpr */
- assemble(0x9C); assemble(0x58+tmpr);
- /* Magic! */
- /* andl tmpr, regflags; andl $~0x40,tmpr; orl tmpr, regflags */
- assemble(0x21); assemble(0x05 + 8*tmpr); assemble_long(®flags);
- assemble(0x81); assemble(0xC0 + 8*4 + tmpr); assemble_ulong(~0x40);
- assemble(0x09); assemble(0x05 + 8*tmpr); assemble_long(®flags);
- compile_move_reg_to_mem_regoffs(-2, 4 + (uae_u32)®flags, tmpr, sz_long);
- cc_status = 0;
- } else {
- /* Lies! */
- cc_status = CC_X_FROM_86C | CC_Z_FROM_86Z |CC_C_FROM_86C |CC_V_FROM_86V |CC_N_FROM_86N;
- }
- break;
-
- case i_MULU:
- case i_MULS:
- compile_prepare_undo(&map, insn_info[iip].dp->smode, insn_info[iip].dp->sreg, &pub);
- compile_prepare_undo(&map, insn_info[iip].dp->dmode, insn_info[iip].dp->dreg, &pub);
- compile_prepareea(&map, insn_info[iip].dp->smode,
- insn_info[iip].dp->sreg,
- insn_info[iip].dp->size, &realpc, current_addr,
- eainfo, 0, EA_LOAD, 1);
- compile_prepareea(&map, insn_info[iip].dp->dmode,
- insn_info[iip].dp->dreg,
- insn_info[iip].dp->size, &realpc, current_addr,
- eainfo, 1, EA_MODIFY | EA_LOAD | EA_STORE, 1);
-
- generate_possible_exit(&map, eainfo, iip, &pub);
- generate_possible_exit(&map, eainfo+1, iip, &pub);
-
- compile_loadeas(&map, eainfo, 0, 1, regonly_alternatives, 0, 1);
-
- /* Extend the regs properly */
- remove_x86r_from_cache(&map, eainfo[0].data_reg, 0);
- switch (insn_info[iip].dp->mnemo) {
- case i_MULU:
- assemble(0x81); assemble(0xC0+4*8 + eainfo[0].data_reg); assemble_ulong(0xFFFF);
- assemble(0x81); assemble(0xC0+4*8 + eainfo[1].data_reg); assemble_ulong(0xFFFF);
- break;
- case i_MULS:
- assemble(0x0F); assemble(0xBF); assemble(0xC0 + 9*eainfo[0].data_reg);
- assemble(0x0F); assemble(0xBF); assemble(0xC0 + 9*eainfo[1].data_reg);
- break;
- }
- /* and multiply */
- assemble(0x0F); assemble(0xAF); assemble(0xC0 + 8*eainfo[1].data_reg + eainfo[0].data_reg);
- compile_note_modify(&map, eainfo, 1);
- cc_status = CC_TEST_REG;
- cc_reg = eainfo[1].data_reg;
- cc_offset = 0;
- cc_size = sz_long;
- break;
-
- case i_ADDA:
- case i_SUBA:
- case i_CMPA:
- compile_prepare_undo(&map, insn_info[iip].dp->smode, insn_info[iip].dp->sreg, &pub);
- compile_prepare_undo(&map, insn_info[iip].dp->dmode, insn_info[iip].dp->dreg, &pub);
- compile_prepareea(&map, insn_info[iip].dp->smode,
- insn_info[iip].dp->sreg,
- insn_info[iip].dp->size, &realpc, current_addr,
- eainfo, 0, EA_LOAD, 1);
- compile_prepareea(&map, insn_info[iip].dp->dmode,
- insn_info[iip].dp->dreg,
- sz_long, &realpc, current_addr,
- eainfo, 1,
- (insn_info[iip].dp->mnemo == i_ADDA || insn_info[iip].dp->mnemo == i_SUBA
- ? EA_MODIFY | EA_LOAD | EA_STORE
- : EA_LOAD | EA_STORE),
- 1);
-
- generate_possible_exit(&map, eainfo, iip, &pub);
-
- compile_loadeas(&map, eainfo, 0, 1,
- insn_info[iip].dp->size == sz_word ? binop_worda_alternatives : binop_alternatives,
- 0, 1);
-
- if (insn_info[iip].dp->size == sz_word) {
- remove_x86r_from_cache(&map, eainfo[0].data_reg, 0);
- compile_extend_long(&map, eainfo[0].data_reg, sz_word);
- }
- eainfo[0].size = sz_long;
-
- switch (insn_info[iip].dp->mnemo) {
- case i_ADDA: compile_eas(&map, eainfo, 0, 1, 0); break;
- case i_SUBA: compile_eas(&map, eainfo, 0, 1, 5); break;
- case i_CMPA: compile_eas(&map, eainfo, 0, 1, 7); break;
- }
-
- if (insn_info[iip].dp->mnemo == i_CMPA) {
- cc_status = CC_Z_FROM_86Z |CC_C_FROM_86C |CC_V_FROM_86V |CC_N_FROM_86N;
- } else {
- compile_note_modify(&map, eainfo, 1);
- cc_status = 0;
- }
- break;
-
- case i_MOVE:
- compile_prepare_undo(&map, insn_info[iip].dp->smode, insn_info[iip].dp->sreg, &pub);
- compile_prepare_undo(&map, insn_info[iip].dp->dmode, insn_info[iip].dp->dreg, &pub);
- compile_prepareea(&map, insn_info[iip].dp->smode,
- insn_info[iip].dp->sreg,
- insn_info[iip].dp->size, &realpc, current_addr,
- eainfo, 0, EA_LOAD, 1);
- compile_prepareea(&map, insn_info[iip].dp->dmode,
- insn_info[iip].dp->dreg,
- insn_info[iip].dp->size, &realpc, current_addr,
- eainfo, 1, EA_STORE, 1);
-
- generate_possible_exit(&map, eainfo, iip, &pub);
- generate_possible_exit(&map, eainfo + 1, iip, &pub);
-
- compile_loadeas(&map, eainfo, 0, 1, binop_alternatives, 1, 0);
- compile_storeea(&map, eainfo, 0, 1);
-
- if (eainfo[0].data_reg == -2) {
- cc_status = CC_TEST_REG;
- cc_reg = -2;
- cc_offset = eainfo[0].data_const_off;
- } else if (eainfo[0].data_reg == -1) {
- if (eainfo[1].data_reg == -1)
- printf("Don't know where to get flags from\n");
- cc_status = CC_TEST_REG;
- cc_offset = 0;
- cc_reg = eainfo[1].data_reg;
- } else {
- cc_status = CC_TEST_REG;
- cc_reg = eainfo[0].data_reg;
- cc_offset = 0;
- }
- cc_size = eainfo[0].size;
-
- break;
-
- case i_MOVEA:
- compile_prepare_undo(&map, insn_info[iip].dp->smode, insn_info[iip].dp->sreg, &pub);
- compile_prepare_undo(&map, insn_info[iip].dp->dmode, insn_info[iip].dp->dreg, &pub);
- compile_prepareea(&map, insn_info[iip].dp->smode,
- insn_info[iip].dp->sreg,
- insn_info[iip].dp->size, &realpc, current_addr,
- eainfo, 0, EA_LOAD, 1);
- compile_prepareea(&map, insn_info[iip].dp->dmode,
- insn_info[iip].dp->dreg,
- sz_long, &realpc, current_addr,
- eainfo, 1, EA_STORE, 1);
-
- generate_possible_exit(&map, eainfo, iip, &pub);
-
- compile_loadeas(&map, eainfo, 0, 1,
- insn_info[iip].dp->size == sz_word ? binop_worda_alternatives : binop_alternatives,
- 0, 0);
-
- if (insn_info[iip].dp->size == sz_word) {
- remove_x86r_from_cache(&map, eainfo[0].data_reg, 0);
- compile_extend_long(&map, eainfo[0].data_reg, sz_word);
- }
- eainfo[0].size = sz_long;
-
- compile_storeea(&map, eainfo, 0, 1);
-
- cc_status = 0;
- break;
-
- case i_EXG:
- if (insn_info[iip].dp->smode != insn_info[iip].dp->dmode
- || insn_info[iip].dp->sreg != insn_info[iip].dp->dreg)
- {
- compile_prepareea(&map, insn_info[iip].dp->smode,
- insn_info[iip].dp->sreg,
- sz_long, &realpc, current_addr,
- eainfo, 0, EA_LOAD|EA_STORE, 1);
- compile_prepareea(&map, insn_info[iip].dp->dmode,
- insn_info[iip].dp->dreg,
- sz_long, &realpc, current_addr,
- eainfo, 1, EA_LOAD|EA_STORE, 1);
-
- compile_loadeas(&map, eainfo, 0, 1, regonly_alternatives, 0, 1);
- compile_storeea(&map, eainfo, 1, 0);
- compile_storeea(&map, eainfo, 0, 1);
- }
-
- cc_status = 0;
- break;
-
- case i_LINK:
- compile_prepare_undo(&map, Apdi, 7, &pub);
- compile_prepareea(&map, insn_info[iip].dp->smode,
- insn_info[iip].dp->sreg,
- sz_long, &realpc, current_addr,
- eainfo, 0, EA_LOAD|EA_STORE, 1);
- compile_prepareea(&map, insn_info[iip].dp->dmode,
- insn_info[iip].dp->dreg,
- sz_long, &realpc, current_addr,
- eainfo, 1, EA_LOAD, 1);
- compile_prepareea(&map, Apdi, 7, sz_long, &realpc, current_addr,
- eainfo, 2, EA_STORE, 1);
-
- generate_possible_exit(&map, eainfo+2, iip, &pub);
-
- compile_fetchea(&map, eainfo, 0, 1);
- /* we know this is a constant - no need to fetch it*/
- /* compile_fetchea(&map, eainfo, 1); */
- compile_storeea(&map, eainfo, 0, 2); /* An -> -(A7) */
-
- compile_prepareea(&map, Areg, 7, sz_long, &realpc, current_addr,
- eainfo, 3, EA_STORE, 1);
- compile_fetchea(&map, eainfo, 3, 1);
- compile_storeea(&map, eainfo, 3, 0); /* A7 -> An */
-
- /* @@@ 020 */
- compile_prepareea(&map, Areg, 7, sz_long, &realpc, current_addr,
- eainfo, 4, EA_LOAD, 1);
- compile_prepareea(&map, Areg, 7, sz_long, &realpc, current_addr,
- eainfo, 5, EA_STORE, 1);
- compile_fetchea(&map, eainfo, 4, 1);
- eainfo[4].data_const_off += (uae_s16)eainfo[1].data_const_off;
- compile_storeea(&map, eainfo, 4, 5); /* A7+off -> A7 */
- cc_status = 0;
- break;
-
- case i_UNLK:
- compile_prepareea(&map, Areg,
- insn_info[iip].dp->sreg,
- sz_long, &realpc, current_addr,
- eainfo, 0, EA_LOAD, 1);
- compile_prepareea(&map, Areg, 7, sz_long, &realpc, current_addr,
- eainfo, 1, EA_STORE, 1);
-
- generate_possible_exit(&map, eainfo + 0, iip, &pub);
-
- compile_fetchea(&map, eainfo, 0, 1);
- compile_storeea(&map, eainfo, 0, 1);
-
- /* The Apdi could of course point to a non-memory area, but undos
- * are difficult here, and anyway: which program does evil hacks
- * with UNLK? */
- compile_prepareea(&map, Aipi, 7, sz_long, &realpc, current_addr,
- eainfo, 2, EA_LOAD, 1);
- compile_prepareea(&map, insn_info[iip].dp->smode,
- insn_info[iip].dp->sreg,
- sz_long, &realpc, current_addr,
- eainfo, 3, EA_STORE, 1);
- compile_fetchea(&map, eainfo, 2, 1);
- compile_storeea(&map, eainfo, 2, 3);
-
- cc_status = 0;
- break;
-
- case i_OR:
- case i_AND:
- case i_EOR:
- compile_prepare_undo(&map, insn_info[iip].dp->smode, insn_info[iip].dp->sreg, &pub);
- compile_prepare_undo(&map, insn_info[iip].dp->dmode, insn_info[iip].dp->dreg, &pub);
- compile_prepareea(&map, insn_info[iip].dp->smode,
- insn_info[iip].dp->sreg,
- insn_info[iip].dp->size, &realpc, current_addr,
- eainfo, 0, EA_LOAD, 1);
- compile_prepareea(&map, insn_info[iip].dp->dmode,
- insn_info[iip].dp->dreg,
- insn_info[iip].dp->size, &realpc, current_addr,
- eainfo, 1, EA_MODIFY | EA_LOAD | EA_STORE, 1);
-
- generate_possible_exit(&map, eainfo, iip, &pub);
- generate_possible_exit(&map, eainfo + 1, iip, &pub);
-
- compile_loadeas(&map, eainfo, 0, 1, binop_alternatives, 0, 1);
-
- switch (insn_info[iip].dp->mnemo) {
- case i_AND: compile_eas(&map, eainfo, 0, 1, 4); break;
- case i_EOR: compile_eas(&map, eainfo, 0, 1, 6); break;
- case i_OR: compile_eas(&map, eainfo, 0, 1, 1); break;
- }
-
- compile_note_modify(&map, eainfo, 1);
- cc_status = CC_Z_FROM_86Z | CC_C_FROM_86C | CC_V_FROM_86V | CC_N_FROM_86N;
- break;
-
- case i_TST:
- compile_prepare_undo(&map, insn_info[iip].dp->smode, insn_info[iip].dp->sreg, &pub);
- compile_prepareea(&map, insn_info[iip].dp->smode,
- insn_info[iip].dp->sreg,
- insn_info[iip].dp->size, &realpc, current_addr,
- eainfo, 0, EA_LOAD, 1);
-
- generate_possible_exit(&map, eainfo, iip, &pub);
-
- compile_fetchea(&map, eainfo, 0, 1);
- cc_status = CC_TEST_REG;
- cc_reg = eainfo[0].data_reg;
- cc_offset = 0;
- cc_size = eainfo[0].size;
- break;
-
- case i_CLR:
- compile_prepare_undo(&map, insn_info[iip].dp->smode, insn_info[iip].dp->sreg, &pub);
- compile_prepareea(&map, insn_info[iip].dp->smode,
- insn_info[iip].dp->sreg,
- insn_info[iip].dp->size, &realpc, current_addr,
- eainfo, 0, EA_STORE, 1);
- compile_prepareea(&map, immi, 0, sz_long, &realpc, current_addr,
- eainfo, 1, EA_LOAD, 1);
- generate_possible_exit(&map, eainfo + 0, iip, &pub);
- compile_loadeas(&map, eainfo, 1, 0, binop_alternatives, 1, 0);
- compile_storeea(&map, eainfo, 1, 0);
-
- cc_status = CC_TEST_REG;
- cc_reg = -2;
- cc_offset = 0;
- cc_size = eainfo[0].size;
- break;
-
- case i_EXT:
- /* No exits, no undo - this is always a Dreg; fetchea will get it in a reg
- * without offset */
- compile_prepareea(&map, insn_info[iip].dp->smode,
- insn_info[iip].dp->sreg,
- insn_info[iip].dp->size == sz_long ? sz_word : sz_byte,
- &realpc, current_addr,
- eainfo, 0, EA_LOAD|EA_STORE, 1);
- compile_fetchea(&map, eainfo, 0, 1);
- compile_force_byteorder(&map, eainfo[0].data_reg, BO_NORMAL, 0);
-
- if (insn_info[iip].dp->size == sz_word)
- assemble(0x66);
- assemble(0x0F);
- if (insn_info[iip].dp->size == sz_long)
- assemble(0xBF);
- else
- assemble(0xBE);
-
- assemble(0xC0 + 9*eainfo[0].data_reg);
- map.x86_dirty[eainfo[0].data_reg] = 1;
-
- cc_status = CC_TEST_REG;
- cc_reg = eainfo[0].data_reg;
- cc_offset = 0;
- cc_size = eainfo[0].size;
- break;
-
- case i_NOT:
- case i_NEG:
- szflag = insn_info[iip].dp->size == sz_byte ? 0 : 1;
-
- compile_prepare_undo(&map, insn_info[iip].dp->smode, insn_info[iip].dp->sreg, &pub);
- compile_prepareea(&map, insn_info[iip].dp->smode,
- insn_info[iip].dp->sreg,
- insn_info[iip].dp->size,
- &realpc, current_addr,
- eainfo, 0, EA_LOAD|EA_STORE, 1);
-
- generate_possible_exit(&map, eainfo, iip, &pub);
-
- compile_fetchea(&map, eainfo, 0, 1);
- compile_force_byteorder(&map, eainfo[0].data_reg, BO_NORMAL, 0);
-
- if (insn_info[iip].dp->size == sz_word)
- assemble(0x66);
- assemble(0xF6 + szflag);
-
- assemble(0xC0 + eainfo[0].data_reg + 8*(insn_info[iip].dp->mnemo == i_NOT ? 2 : 3));
- compile_note_modify(&map, eainfo, 0);
-
- if (insn_info[iip].dp->mnemo == i_NEG)
- cc_status = CC_Z_FROM_86Z | CC_C_FROM_86C | CC_V_FROM_86V | CC_N_FROM_86N | CC_X_FROM_86C;
- else {
- cc_status = CC_TEST_REG;
- cc_reg = eainfo[0].data_reg;
- cc_offset = 0;
- cc_size = eainfo[0].size;
- }
- break;
-
- case i_SWAP:
- /* No exits, no undo - this is always a Dreg; fetchea will get it in a reg
- * without offset */
- compile_prepareea(&map, insn_info[iip].dp->smode,
- insn_info[iip].dp->sreg, sz_long,
- &realpc, current_addr,
- eainfo, 0, EA_LOAD|EA_STORE, 1);
-
- compile_fetchea(&map, eainfo, 0, 1);
- compile_force_byteorder(&map, eainfo[0].data_reg, BO_NORMAL, 0);
-
- /* roll $16, srcreg */
- assemble(0xC1); assemble(0xC0 + eainfo[0].data_reg); assemble(16);
-
- /* @@@ un-shortcut */
- map.x86_dirty[eainfo[0].data_reg] = 1;
-
- cc_status = CC_TEST_REG;
- cc_reg = eainfo[0].data_reg;
- cc_offset = 0;
- cc_size = eainfo[0].size;
- break;
-
- case i_LEA:
- /* No exits necessary here: never touches memory */
- compile_prepareea(&map, insn_info[iip].dp->smode,
- insn_info[iip].dp->sreg,
- insn_info[iip].dp->size, &realpc, current_addr,
- eainfo, 0, 0, 1);
- eainfo[0].data_reg = eainfo[0].address_reg;
- eainfo[0].data_const_off = eainfo[0].addr_const_off;
- eainfo[0].address_reg = -1;
- compile_get_excl_lock(&map, eainfo + 0);
- compile_prepareea(&map, insn_info[iip].dp->dmode,
- insn_info[iip].dp->dreg,
- sz_long, &realpc, current_addr,
- eainfo, 1, EA_STORE, 1);
- compile_storeea(&map, eainfo, 0, 1);
- cc_status = 0;
- break;
-
- case i_PEA:
- compile_prepare_undo(&map, Apdi, 7, &pub);
- compile_prepareea(&map, insn_info[iip].dp->smode,
- insn_info[iip].dp->sreg,
- insn_info[iip].dp->size, &realpc, current_addr,
- eainfo, 0, 0, 1);
- eainfo[0].data_reg = eainfo[0].address_reg;
- eainfo[0].data_const_off = eainfo[0].addr_const_off;
- eainfo[0].address_reg = -1;
- compile_get_excl_lock(&map, eainfo + 0);
- compile_prepareea(&map, Apdi, 7, sz_long, &realpc, current_addr,
- eainfo, 1, EA_STORE, 1);
-
- generate_possible_exit(&map, eainfo+1, iip, &pub);
- compile_storeea(&map, eainfo, 0, 1);
-
- cc_status = 0;
- break;
-
- case i_MVMEL:
- compile_prepareea(&map, insn_info[iip].dp->smode,
- insn_info[iip].dp->sreg,
- sz_word, &realpc, current_addr,
- eainfo, 0, EA_LOAD, 1);
- sync_reg_cache(&map, 0);
- {
- /* Scratch 0 holds the registers while they are being moved
- * from/to memory. Scratch 1 points at regs.d. Scratch 2
- * points at the base addr in memory where to fetch data
- * from.
- */
- int scratch0, scratch1, scratch2;
- uae_u16 mask = eainfo[0].data_const_off;
- int bits = count_bits(mask);
- int size = insn_info[iip].dp->size == sz_long ? 4 : 2;
- int i;
- uae_u8 x86amode;
- uae_u32 current_offs = 0;
-
- compile_prepare_undo(&map, insn_info[iip].dp->dmode, insn_info[iip].dp->dreg, &pub);
- /* !!! Note current_addr + 2 here! */
- compile_prepareea(&map, insn_info[iip].dp->dmode,
- insn_info[iip].dp->dreg,
- insn_info[iip].dp->size, &realpc, current_addr + 2,
- eainfo, 1, EA_LOAD, bits);
-
- generate_possible_exit(&map, eainfo + 1, iip, &pub);
-
- scratch0 = get_free_x86_register(&map, ADDRESS_X86_REGS);
- lock_reg(&map, scratch0, 2);
- scratch1 = get_free_x86_register(&map, ADDRESS_X86_REGS);
- lock_reg(&map, scratch1, 2);
- scratch2 = get_free_x86_register(&map, ADDRESS_X86_REGS);
- lock_reg(&map, scratch2, 2);
- compile_force_byteorder(&map, eainfo[1].address_reg, BO_NORMAL, 0);
-
- compile_lea_reg_with_offset(scratch1, -2, (uae_u32)regs.regs);
- compile_lea_reg_with_offset(scratch2, eainfo[1].address_reg,
- (uae_u32)(address_space + eainfo[1].addr_const_off));
-
- for (i = 0; i < 16; i++) {
- int r68k = i;
- int *cache68k = i < 8 ? map.dreg_map : map.areg_map;
- if (mask & 1
- && (i < 8
- || insn_info[iip].dp->dmode != Aipi
- || (r68k & 7) != insn_info[iip].dp->dreg)) {
- int tmpr = cache68k[r68k & 7];
-
- if (tmpr != -1) {
- cache68k[r68k & 7] = -1;
- map.x86_cache_reg[tmpr] = -1;
- }
- compile_move_reg_from_mem_regoffs(scratch0, scratch2,
- current_offs, insn_info[iip].dp->size);
- if (size == 2) {
- assemble(0x66); /* rolw $8,scratch0 */
- assemble(0xC1);
- assemble(0xC0 + scratch0);
- assemble(8);
- assemble(0x0F); assemble(0xBF); /* extend */
- assemble(0xC0 + 9*scratch0);
- } else {
- assemble(0x0F); /* bswapl scratch0 */
- assemble(0xC8 + scratch0);
- }
- compile_move_reg_to_mem_regoffs(scratch1, (char *)(regs.regs + r68k) - (char *)regs.regs,
- scratch0, sz_long);
- }
- if (mask & 1)
- current_offs += size;
- mask >>= 1;
- }
- }
- cc_status = 0;
- break;
-
- case i_MVMLE:
- compile_prepareea(&map, insn_info[iip].dp->smode,
- insn_info[iip].dp->sreg,
- sz_word, &realpc, current_addr,
- eainfo, 0, EA_LOAD, 1);
- sync_reg_cache(&map, 0);
- {
- int scratch0,scratch1,scratch2;
- uae_u16 mask = eainfo[0].data_const_off;
- int bits = count_bits(mask);
- int size = insn_info[iip].dp->size == sz_long ? 4 : 2;
- int i;
- uae_u8 x86amode;
- uae_u32 current_offs = 0;
- int addrareg = -1;
- if (insn_info[iip].dp->dmode == Aind
- || insn_info[iip].dp->dmode == Apdi
- || insn_info[iip].dp->dmode == Aipi
- || insn_info[iip].dp->dmode == Ad16
- || insn_info[iip].dp->dmode == Ad8r)
- {
- addrareg = get_and_lock_68k_reg(&map, insn_info[iip].dp->dreg, 0, ADDRESS_X86_REGS, 1, 2);
- compile_force_byteorder(&map, addrareg, BO_NORMAL, 0);
- }
- if (insn_info[iip].dp->dmode == Apdi)
- mask = bitswap(mask);
- /* !!! Note current_addr + 2 here! */
- compile_prepare_undo(&map, insn_info[iip].dp->dmode, insn_info[iip].dp->dreg, &pub);
- compile_prepareea(&map, insn_info[iip].dp->dmode,
- insn_info[iip].dp->dreg,
- insn_info[iip].dp->size, &realpc, current_addr + 2,
- eainfo, 1, EA_STORE, bits);
-
- generate_possible_exit(&map, eainfo + 1, iip, &pub);
-
- scratch0 = get_free_x86_register(&map, ADDRESS_X86_REGS);
- lock_reg(&map, scratch0, 2);
- scratch1 = get_free_x86_register(&map, ADDRESS_X86_REGS);
- lock_reg(&map, scratch1, 2);
- scratch2 = get_free_x86_register(&map, ADDRESS_X86_REGS);
- lock_reg(&map, scratch2, 2);
-
- compile_force_byteorder(&map, eainfo[1].address_reg, BO_NORMAL, 0);
-
- compile_lea_reg_with_offset(scratch1, -2, (uae_u32)regs.regs);
- compile_lea_reg_with_offset(scratch2, eainfo[1].address_reg,
- (uae_u32)(address_space + eainfo[1].addr_const_off));
-
- for (i = 0; i < 16; i++) {
- int r68k = i;
- if (mask & 1) {
- /* move from 68k reg */
- if (i < 8 || (i & 7) != insn_info[iip].dp->dreg || addrareg == -1) {
- compile_move_reg_from_mem_regoffs(scratch0, scratch1, (char *)(regs.regs + r68k) - (char *)regs.regs,
- sz_long);
- } else {
- assemble(0x8B); assemble(0xC0 + 8*scratch0 + addrareg);
- }
-
- if (size == 2) {
- assemble(0x66); /* rolw $8,scratch0 */
- assemble(0xC1);
- assemble(0xC0 + scratch0); assemble(8);
- } else {
- assemble(0x0F); /* bswapl scratch0 */
- assemble(0xC8 + scratch0);
- }
- compile_move_reg_to_mem_regoffs(scratch2, current_offs,
- scratch0, insn_info[iip].dp->size);
- }
- if (mask & 1)
- current_offs += size;
- mask >>= 1;
- }
- }
- cc_status = 0;
- break;
-#if 1
- case i_BTST:
- case i_BSET:
- case i_BCLR:
- case i_BCHG:
- compile_prepare_undo(&map, insn_info[iip].dp->smode, insn_info[iip].dp->sreg, &pub);
- compile_prepare_undo(&map, insn_info[iip].dp->dmode, insn_info[iip].dp->dreg, &pub);
- compile_prepareea(&map, insn_info[iip].dp->smode,
- insn_info[iip].dp->sreg,
- insn_info[iip].dp->size, &realpc, current_addr,
- eainfo, 0, EA_LOAD, 1);
- compile_prepareea(&map, insn_info[iip].dp->dmode,
- insn_info[iip].dp->dreg,
- insn_info[iip].dp->size, &realpc, current_addr,
- eainfo, 1, 0, 1);
-
- generate_possible_exit(&map, eainfo, iip, &pub);
- generate_possible_exit(&map, eainfo + 1, iip, &pub);
-
- handle_bit_insns(&map, eainfo, 0, 1, insn_info[iip].dp->mnemo);
- break;
-
- case i_ASL: case i_ASR: case i_LSL: case i_LSR:
- case i_ROL: case i_ROR: case i_ROXL:case i_ROXR:
- if (insn_info[iip].dp->smode == Dreg && do_rotshi) {
- handle_rotshi_variable(&map, iip, realpc, current_addr, &pub);
- break;
- }
- /* fall through */
- case i_ASLW: case i_ASRW: case i_LSLW: case i_LSRW:
- case i_ROLW: case i_RORW: case i_ROXLW:case i_ROXRW:
- if (do_rotshi) {
- handle_rotshi(&map, iip, realpc, current_addr, &pub);
- break;
- }
-#endif
- default:
- generate_exit(&map, insn_info[iip].address); cc_status = 0;
- break;
- }
- if (insn_info[iip].ccuser_follows)
- cc_status_for_bcc = compile_flush_cc_cache(&map, cc_status,
- insn_info[iip].flags_live_at_end,
- 1, insn_info[iip+1].flags_live_at_end,
- insn_info[iip+1].dp->cc);
- else
- cc_status_for_bcc = compile_flush_cc_cache(&map, cc_status,
- insn_info[iip].flags_live_at_end,
- 0, 0, 0);
-
- if (iip == current_bb->last_iip) {
- current_bb++;
- }
- }
- if (compile_failure)
- goto oops;
-
- /* Compile all exits that we prepared earlier */
- finish_exits();
- if (compile_failure)
- goto oops;
- finish_condjumps(last_iip);
- {
- int needed_len = compile_here() - hb->compile_start;
- int allocsize = (needed_len + PAGE_SUBUNIT - 1) & ~(PAGE_SUBUNIT-1);
- uae_u32 allocmask;
- int allocbits;
-
- allocbits = (allocsize >> SUBUNIT_ORDER);
- allocmask = (1 << allocbits) - 1;
- while ((allocmask & hb->page_allocmask) != allocmask)
- allocmask <<= 1;
- if ((hb->page_allocmask & ~allocmask) != 0 && !quiet_compile)
- write_log ("Gaining some bits: %08lx\n", hb->page_allocmask & ~allocmask);
- hb->cpage->allocmask &= ~hb->page_allocmask;
- hb->page_allocmask = allocmask;
- hb->cpage->allocmask |= allocmask;
- }
- return 0;
-
- oops:
- if (1 || !quiet_compile)
- write_log ("Compile failed!\n");
- hb->cpage->allocmask &= ~hb->page_allocmask;
- hb->cpage = NULL;
- hb->untranslatable = 1;
- {
- struct hash_entry *h = hb->he_first;
-
- do {
- h->execute = NULL;
- h = h->next_same_block;
- } while (h != hb->he_first);
- }
- return 1;
-}
-
-void compiler_init(void)
-{
- code_init();
- hash_init();
- jsr_stack_init();
-}
-
-/*
- * Why do compilers always have to be so complicated? And I thought GCC was
- * a mess...
- */
-
-#endif /* USE_COMPILER */
STATIC_INLINE void compute_delay_offset (void)
{
- delayoffset = ((plfstrt - HARD_DDF_START) & fetchstart_mask) << 1;
- if (delayoffset & 8)
+ delayoffset = (((plfstrt - HARD_DDF_START) & fetchstart_mask) << 1) & ~7;
+ if (delayoffset == 8)
delayoffset = 8;
- else if (delayoffset & 16)
- delayoffset = 16;
- else if (delayoffset & 32)
+ else if (delayoffset == 16) /* Overkill AGA */
+ delayoffset = 48;
+ else if (delayoffset == 32)
delayoffset = 32;
+ else if (delayoffset == 48) /* Pinball Illusions AGA, ingame */
+ delayoffset = 16;
else
delayoffset = 0;
}
static int last_warned;
last_warned = (last_warned + 1) & 4095;
if (last_warned == 0)
- write_log ("WARNING! Very strange DDF values.\n");
+ write_log ("WARNING! Very strange DDF values (%x %x).\n", ddfstrt, ddfstop);
}
}
-int test_cnt = 0x80;
-
static void DDFSTOP (int hpos, uae_u16 v)
{
v &= 0xfe;
double idle = 1000 - (idletime == 0 ? 0.0 : (double)idletime * 1000.0 / (vsynctime * 32.0));
int fps = frametime2 == 0 ? 0 : syncbase * 32 / (frametime2 / 10);
if (fps > 9999)
- fps = 9999;
+ fps = 9999;
if (idle < 0)
idle = 0;
if (idle > 100 * 10)
static struct memwatch_node mwhit;
static uae_u8 *illgdebug;
+static int illgdebug_break;
extern int cdtv_enabled, cd32_enabled;
static void illg_init (void)
write_log ("RW: %08.8X=%02.2X %c PC=%08.8X\n", ad, v, rws, pc);
else
write_log ("RW: %08.8X %c PC=%08.8X\n", ad, rws, pc);
+ if (illgdebug_break)
+ activate_debugger ();
} else if ((mask & 1) && rw) {
write_log ("RO: %08.8X=%02.2X %c PC=%08.8X\n", ad, v, rws, pc);
+ if (illgdebug_break)
+ activate_debugger ();
} else if ((mask & 2) && !rw) {
write_log ("WO: %08.8X %c PC=%08.8X\n", ad, rws, pc);
+ if (illgdebug_break)
+ activate_debugger ();
}
}
}
} else {
illg_init ();
console_out ("Illegal memory access logging enabled\n");
+ ignore_ws (c);
+ illgdebug_break = 0;
+ if (more_params (c))
+ illgdebug_break = 1;
}
return;
}
#include "osemu.h"
#include "execlib.h"
#include "savestate.h"
+#include "cia.h"
#ifdef FDI2RAW
#include "fdi2raw.h"
#endif
#define DISK_WORDSYNC 2
#define DISK_REVOLUTION 4 /* 4,8,16,32 */
-/* A value of 5 works out to a guaranteed delay of 1/2 of a second
- Higher values are dangerous, e.g. a value of 8 breaks the RSI
- demo. */
-#define DSKREADY_TIME 5
+#define DSKREADY_TIME 4
#define DSKREADY_DOWN_TIME 10
#if 0
int dskready_time;
int dskready_down_time;
int steplimit;
+ int indexhack, indexhackmode;
int ddhd; /* 1=DD 2=HD */
int drive_id_scnt; /* drive id shift counter */
int idbit;
disabled |= 1 << i;
gui_data.drive_disabled[i] = 1;
}
+ /* most internal Amiga floppy drives won't enable
+ * diskready until motor is running at full speed
+ * and next indexsync has been passed
+ */
+ drv->indexhackmode = 0;
+ if (i == 0 && currprefs.dfxtype[i] == 0)
+ drv->indexhackmode = 1;
drv->dskchange_time = 0;
drv->buffered_cyl = -1;
drv->buffered_side = -1;
struct zfile *DISK_validate_filename (const char *fname, int leave_open, int *wrprot)
{
- struct zfile *f = zfile_fopen (fname, "r+b");
- if (f) {
- if (wrprot)
- *wrprot = 0;
+ if (leave_open) {
+ struct zfile *f = zfile_fopen (fname, "r+b");
+ if (f) {
+ if (wrprot)
+ *wrprot = 0;
+ } else {
+ if (wrprot)
+ *wrprot = 1;
+ f = zfile_fopen (fname, "rb");
+ }
+ return f;
} else {
- if (wrprot)
- *wrprot = 1;
- f = zfile_fopen (fname, "rb");
+ if (zfile_exists (fname)) {
+ if (wrprot)
+ *wrprot = 0;
+ return (void*)1;
+ } else {
+ if (wrprot)
+ *wrprot = 1;
+ return 0;
+ }
}
- if (!leave_open)
- zfile_fclose (f);
- return f;
}
static void updatemfmpos (drive *drv)
return 1;
}
-static char *getwritefilename (const char *name)
+char *DISK_get_saveimagepath (const char *name)
{
static char name1[MAX_DPATH];
char name2[MAX_DPATH];
static struct zfile *getwritefile (const char *name, int *wrprot)
{
- return DISK_validate_filename (getwritefilename (name), 1, wrprot);
+ return DISK_validate_filename (DISK_get_saveimagepath (name), 1, wrprot);
}
static int iswritefileempty (const char *name)
#endif
#ifdef DISK_DEBUG2
write_dlog (" ->motor on");
+ if (drv->indexhackmode > 0)
+ drv->indexhack = 1;
#endif
}
if (!drv->motoroff && off) {
} else if (drv->filetype == ADF_IPF) {
#ifdef CAPS
- caps_loadtrack (drv->bigmfmbuf, drv->tracktiming, drv - floppy, tr, &drv->tracklen, &drv->multi_revolution);
+ caps_loadtrack (drv->bigmfmbuf, drv->tracktiming, drv - floppy, tr, &drv->tracklen, &drv->multi_revolution, &drv->skipoffset);
#endif
} else if (drv->filetype == ADF_FDI) {
memset (dstmfmbuf, 0xaa, len * 2);
dstmfmoffset += FLOPPY_GAP_LEN;
- drv->skipoffset = FLOPPY_GAP_LEN / 3 * 2;
+ drv->skipoffset = (FLOPPY_GAP_LEN * 8) / 3 * 2;
drv->tracklen = len * 2 * 8;
for (sec = 0; sec < drv->num_secs; sec++) {
static void drive_write_data (drive * drv)
{
int ret;
+ static int warned;
+
if (drive_writeprotected (drv)) {
/* read original track back because we didn't really write anything */
drv->buffered_side = 2;
switch (drv->filetype) {
case ADF_NORMAL:
- drive_write_adf_amigados (drv);
+ if (drive_write_adf_amigados (drv)) {
+ if (!warned)
+ notify_user (NUMSG_NEEDEXT2);
+ warned = 1;
+ }
return;
case ADF_EXT1:
break;
drv->dskchange_time = dsktime;
}
+void DISK_reinsert (int num)
+{
+ drive_eject (&floppy[num]);
+ setdskchangetime (&floppy[num], 20);
+}
+
int disk_setwriteprotect (int num, const char *name, int protect)
{
int needwritefile, oldprotect;
if (!zf1) return 0;
if (zfile_iscompressed (zf1)) wrprot1 = 1;
zf2 = getwritefile (name, &wrprot2);
- name2 = getwritefilename (name);
+ name2 = DISK_get_saveimagepath (name);
if (needwritefile && zf2 == 0)
disk_creatediskfile (name2, 1, drvtype);
if (!needwritefile)
diskfile_readonly (name, protect);
diskfile_readonly (name2, protect);
- drive_eject (&floppy[num]);
- setdskchangetime (&floppy[num], 20);
+ DISK_reinsert (num);
return 1;
}
{
int i;
+ if (name[0] == 0)
+ return;
+ if (!zfile_exists (name))
+ return;
if (idx >= 0) {
if (idx >= MAX_PREVIOUS_FLOPPIES)
return;
strcpy (dfxhistory[idx], name);
return;
}
- if (name[0] == 0)
- return;
for (i = 0; i < MAX_PREVIOUS_FLOPPIES; i++) {
if (!strcmp (dfxhistory[i], name)) {
while (i < MAX_PREVIOUS_FLOPPIES - 1) {
{
if (idx >= MAX_PREVIOUS_FLOPPIES)
return 0;
- if (dfxhistory[idx][0] == 0)
- return 0;
return dfxhistory[idx];
}
direction = (data >> 1) & 1;
step_pulse = data & 1;
+ if ((prevdata & 0x80) != (data & 0x80)) {
+ for (dr = 0; dr < 4; dr++) {
+ if (floppy[dr].indexhackmode > 1 && !(selected & (1 << dr))) {
+ floppy[dr].indexhack = 1;
+#ifdef DISK_DEBUG2
+ write_dlog (" indexhack!");
+#endif
+ }
+ }
+ }
+
#ifdef DISK_DEBUG2
write_dlog (" %d%d%d%d% ", (selected & 1) ? 0 : 1, (selected & 2) ? 0 : 1, (selected & 4) ? 0 : 1, (selected & 8) ? 0 : 1);
if ((prevdata & 0x80) != (data & 0x80))
for (dr = 0; dr < MAX_FLOPPY_DRIVES; dr++) {
if (!(selected & (1 << dr))) {
drive_step (floppy + dr);
+ if (floppy[dr].indexhackmode > 1 && (data & 0x80))
+ floppy[dr].indexhack = 1;
}
}
}
st &= ~0x20;
#endif
} else {
- if (drv->dskready)
+ if (drv->dskready && !drv->indexhack)
st &= ~0x20;
}
} else {
}
}
-extern void cia_diskindex (void);
-
static int diskevent_flag;
static int disk_sync_cycle;
int firstcycle = startcycle;
uae_u32 tword = word;
int mfmpos = drv->mfmpos;
+ int indexhack = drv->indexhack;
diskevent_flag = 0;
while (startcycle < (maxhpos << 8) && !diskevent_flag) {
mfmpos %= drv->tracklen;
if (mfmpos == 0)
diskevent_flag |= DISK_REVOLUTION << (drv - floppy);
- if (mfmpos == drv->indexoffset)
+ if (mfmpos == drv->indexoffset) {
diskevent_flag |= DISK_INDEXSYNC;
- if (mfmpos == drv->skipoffset) {
+ indexhack = 0;
+ }
+ if (dskdmaen != 3 && mfmpos == drv->skipoffset) {
int skipcnt = disk_jitter;
while (skipcnt-- > 0) {
- if (mfmpos == drv->indexoffset)
- diskevent_flag |= DISK_INDEXSYNC;
- if (mfmpos == 0)
- diskevent_flag |= DISK_REVOLUTION << (drv - floppy);
mfmpos++;
mfmpos %= drv->tracklen;
+ if (mfmpos == 0)
+ diskevent_flag |= DISK_REVOLUTION << (drv - floppy);
+ if (mfmpos == drv->indexoffset) {
+ diskevent_flag |= DISK_INDEXSYNC;
+ indexhack = 0;
+ }
}
}
startcycle += drv->trackspeed;
drv->mfmpos += disk_jitter;
drv->mfmpos %= drv->tracklen;
}
+ if (drv->mfmpos == drv->indexoffset) {
+#ifdef DISK_DEBUG2
+ if (drv->indexhack)
+ write_log ("indexhack cleared\n");
+#endif
+ drv->indexhack = 0;
+ }
if (bitoffset == 15 && dma_enable && dskdmaen == 2 && dsklength >= 0) {
if (dsklength > 0) {
- put_word (dskpt, word);
- dskpt += 2;
+ put_word (dskpt, word);
+ dskpt += 2;
#ifdef CPUEMU_6
- cycle_line[7] |= CYCLE_DISK;
- cycle_line[9] |= CYCLE_DISK;
+ cycle_line[7] |= CYCLE_DISK;
+ cycle_line[9] |= CYCLE_DISK;
#endif
}
#if 0
dma_enable = 1;
}
}
-
bitoffset++;
bitoffset &= 15;
floppybits -= drv->trackspeed;
int cycles = (tohpos << 8) - disk_hpos;
int startcycle = disk_hpos;
- disk_jitter = (rand () >> 4) & 3;
+ disk_jitter = ((rand () >> 4) & 3) + 1;
if (disk_jitter > 2)
- disk_jitter = 0;
+ disk_jitter = 1;
if (cycles <= 0)
return;
disk_hpos += cycles;
reset_drive (i);
}
-int DISK_examine_image (struct uae_prefs *p, int num)
+int DISK_examine_image (struct uae_prefs *p, int num, uae_u32 *crc32)
{
int drvsec;
int ret, i;
drive *drv = &floppy[num];
- uae_u32 dos, crc;
+ uae_u32 dos, crc, crc2;
ret = 0;
drv->cyl = 0;
side = 0;
- drive_insert (drv, p, num, p->df[num]);
+ *crc32 = 0;
+ if (!drive_insert (drv, p, num, p->df[num]))
+ return 2;
if (!drv->diskfile)
return 1;
+ *crc32 = zfile_crc32 (drv->diskfile);
if (decode_buffer (drv->bigmfmbuf, drv->cyl, 11, drv->ddhd, drv->filetype, &drvsec)) {
ret = 2;
goto end;
}
- crc = 0;
- for (i = 0; i < 512; i += 4) {
+ crc = crc2 = 0;
+ for (i = 0; i < 1024; i += 4) {
uae_u32 v = (writebuffer[i] << 24) | (writebuffer[i + 1] << 16) | (writebuffer[i + 2] << 8) | writebuffer[i + 3];
if (i == 0)
dos = v;
- if (i == 4)
+ if (i == 4) {
+ crc2 = v;
v = 0;
+ }
if (crc + v < crc)
crc++;
crc += v;
}
crc ^= 0xffffffff;
-// if (crc != 0)
-// return 3;
+ if (crc != crc2)
+ return 3;
if (dos == 0x444f5300)
ret = 10;
else if (dos == 0x444f5301 || dos == 0x444f5302 || dos == 0x444f5303)
default:
write_log ("Only CMD_READ supported in DoIO()\n");
- abort();
+ uae_restart (-1, NULL);
}
{
uaecptr dest = get_long (request + 0x28);
if (disk_empty (0)) {
gui_message ("You need to have a diskfile in DF0 to use the Kickstart replacement!\n");
- uae_quit ();
- m68k_setpc (0xF80010);
+ uae_restart (-1, NULL);
return;
}
case EOP_NIMP:
write_log ("Unimplemented Kickstart function called\n");
- uae_quit ();
+ uae_restart (-1, NULL);
/* fall through */
case EOP_LOOP:
case EOP_OPENLIB:
default:
write_log ("Internal error. Giving up.\n");
- abort ();
+ uae_restart (-1, NULL);
}
}
#include "newcpu.h"
#include "filesys.h"
#include "autoconf.h"
-#include "compiler.h"
#include "fsusage.h"
#include "native2amiga.h"
#include "scsidev.h"
#define DUMPLOCK(u,x)
#endif
-void xfree (void *p)
-{
- free (p);
-}
-
static void aino_test (a_inode *aino)
{
#ifdef AINO_DEBUG
return strdup (newname);
}
+static void dump_partinfo (char *name, int num, uaecptr pp)
+{
+ uae_u32 dostype = get_long (pp + 80);
+ write_log ("RDB: '%s' uaehf.device:%d, dostype=%08.8X\n", name, num, dostype);
+ write_log ("BlockSize: %d, Surfaces: %d, SectorsPerBlock %d\n",
+ get_long (pp + 20) * 4, get_long (pp + 28), get_long (pp + 32));
+ write_log ("SectorsPerTrack: %d, Reserved: %d, LowCyl %d, HighCyl %d\n",
+ get_long (pp + 36), get_long (pp + 40), get_long (pp + 52), get_long (pp + 56));
+ write_log ("Buffers: %d, BufMemType: %08.8x, MaxTransfer: %08.8x, BootPri: %d\n",
+ get_long (pp + 60), get_long (pp + 64), get_long (pp + 68), get_long (pp + 76));
+}
+
static int rdb_mount (UnitInfo *uip, int unit_no, int partnum, uaecptr parmpacket)
{
int lastblock = 63, blocksize, readblocksize, badblock, driveinitblock;
put_long (parmpacket + 12, 0); /* Device flags */
for (i = 0; i < PP_MAXSIZE; i++)
put_byte (parmpacket + 16 + i, buf[128 + i]);
+ dump_partinfo (buf + 37, uip->devno, parmpacket);
dostype = get_long (parmpacket + 80);
- write_log ("RDB: '%s' uaehf.device:%d, dostype=%08.8X\n", buf + 37, uip->devno, dostype);
if (dostype == 0) {
err = -1;
#include "newcpu.h"
#include "filesys.h"
#include "autoconf.h"
-#include "compiler.h"
#include "fsusage.h"
#include "native2amiga.h"
#include "scsidev.h"
fprintf (f, "#include \"custom.h\"\n");
fprintf (f, "#include \"events.h\"\n");
fprintf (f, "#include \"newcpu.h\"\n");
- fprintf (f, "#include \"compiler.h\"\n");
fprintf (f, "#include \"comptbl.h\"\n");
}
if (extracycles > 0) {
printf("\t{\n");
fill_prefetch_next_cycles ();
- printf("\tif (%d * %d > lostcycles) do_cycles_ce (%d * %d - lostcycles);\n",
+ printf("\tif ((%d + 4) * %d > lostcycles) do_cycles_ce ((%d + 4) * %d - lostcycles);\n",
extracycles, CYCLE_UNIT / 2, extracycles, CYCLE_UNIT / 2);
printf("\t}\n");
} else {
if ((using_prefetch || using_ce) && using_exception_3 && getv != 0 && size != sz_byte) {
printf ("\tif (%sa & 1) {\n", name);
- printf ("\t\texception3 (opcode, m68k_getpc() + %d, %sa);\n", m68k_pc_offset_last, name);
+ if (using_prefetch || using_ce)
+ printf ("\t\texception3 (opcode, m68k_getpc() + %d, %sa);\n", m68k_pc_offset + 2, name);
+ else
+ printf ("\t\texception3 (opcode, m68k_getpc() + %d, %sa);\n", m68k_pc_offset_last, name);
printf ("\t\tgoto %s;\n", endlabelstr);
printf ("\t}\n");
need_endlabel = 1;
if (curi->size == sz_byte) {
printf ("\tsrc &= 0xFF;\n");
}
- fill_prefetch_next_delay (8);
+ fill_prefetch_next_delay (4);
printf ("\tregs.sr %c= src;\n", curi->mnemo == i_EORSR ? '^' : '|');
printf ("\tMakeFromSR();\n");
break;
if (curi->size == sz_byte) {
printf ("\tsrc |= 0xFF00;\n");
}
- fill_prefetch_next_delay (8);
+ fill_prefetch_next_delay (4);
printf ("\tregs.sr &= src;\n");
printf ("\tMakeFromSR();\n");
break;
fill_prefetch_full ();
break;
case i_RTD:
- printf ("\tcompiler_flush_jsr_stack();\n");
genamode (Aipi, "7", sz_long, "pc", 1, 0, 0);
genamode (curi->smode, "srcreg", curi->size, "offs", 1, 0, 0);
printf ("\tm68k_areg(regs, 7) += offs;\n");
need_endlabel = 1;
break;
case i_RTR:
- printf ("\tcompiler_flush_jsr_stack();\n");
printf ("\tMakeSR();\n");
genamode (Aipi, "7", sz_word, "sr", 1, 0, 0);
genamode (Aipi, "7", sz_long, "pc", 1, 0, 0);
}
fill_prefetch_full ();
if (using_ce)
- printf ("\treturn 0;\n");
+ printf ("\treturn;\n");
else
printf ("\treturn 10 * %d;\n", CYCLE_UNIT / 2);
} else {
-#ifdef USE_COMPILER
- printf ("\tm68k_setpc_bcc(m68k_getpc() + 2+ (uae_s32)src);\n");
-#else
printf ("\tm68k_incpc ((uae_s32)src + 2);\n");
-#endif
returncycles ("\t", 10);
}
printf ("didnt_jump:;\n");
printf ("\tuaecptr oldpc = m68k_getpc();\n");
addcycles (2);
printf ("\tif (!cctrue(%d)) {\n", curi->cc);
-#ifdef USE_COMPILER
- printf ("\t\tm68k_setpc_bcc(m68k_getpc() + (uae_s32)offs + 2);\n");
-#else
printf ("\t\tm68k_incpc((uae_s32)offs + 2);\n");
-#endif
printf ("\t"); fill_prefetch_1 (0, 0);
printf ("\t"); genastore ("(src-1)", curi->smode, "srcreg", curi->size, "src");
fill_prefetch_1 (2, 0);
returncycles ("\t\t\t", 12);
if (using_ce)
- printf ("\t\t\treturn 0;\n");
+ printf ("\t\t\treturn;\n");
printf ("\t\t}\n");
printf ("\t} else {\n");
addcycles2 ("\t\t", 2);
genamode (curi->dmode, "dstreg", sz_long, "dst", 1, 0, 0);
fill_prefetch_next_cycles ();
sync_m68k_pc ();
- /* Clear V flag when dividing by zero - Alcatraz Odyssey demo depends
- * on this (actually, it's doing a DIVS). */
+ printf ("\tCLEAR_CZNV;\n");
printf ("\tif (src == 0) {\n");
- printf ("\t\tSET_VFLG (0);\n");
+ if (cpu_level > 0) {
+ /* 68020 sets V when dividing by zero and N if dst is negative
+ * 68000 clears both
+ */
+ printf("\t\tSET_VFLG (1);\n");
+ printf("\t\tif (dst < 0) SET_NFLG (1);\n");
+ }
printf ("\t\tException (5, oldpc);\n");
printf ("\t\tgoto %s;\n", endlabelstr);
printf ("\t} else {\n");
addcycles3 ("\t\t");
}
/* The N flag appears to be set each time there is an overflow.
- * Weird. */
+ * Weird. but 68020 only sets N when dst is negative.. */
printf ("\t\tif (newv > 0xffff) {\n");
- printf ("\t\t\tSET_VFLG (1); SET_NFLG (1); SET_CFLG (0);\n");
+ printf ("\t\t\tSET_VFLG (1);\n");
+#ifdef UNDEF68020
+ if (cpu_level >= 2)
+ printf ("\t\t\tif (currprefs.cpu_level == 0 || dst < 0) SET_NFLG (1);\n");
+ else /* ??? some 68000 revisions may not set NFLG when overflow happens.. */
+#endif
+ printf ("\t\t\tSET_NFLG (1);\n");
printf ("\t\t} else {\n");
printf ("\t\t"); genflags (flag_logical, sz_word, "newv", "", "");
printf ("\t\t\tnewv = (newv & 0xffff) | ((uae_u32)rem << 16);\n");
genamode (curi->dmode, "dstreg", sz_long, "dst", 1, 0, 0);
fill_prefetch_next_cycles ();
sync_m68k_pc ();
+ printf ("\tCLEAR_CZNV;\n");
printf ("\tif (src == 0) {\n");
- printf ("\t\tSET_VFLG (0);\n");
+ if (cpu_level > 0) {
+ /* 68020 sets V when dividing by zero. Z is also set.
+ * 68000 clears both
+ */
+ printf("\t\tSET_VFLG (1);\n");
+ printf("\t\tSET_ZFLG (1);\n");
+ }
printf ("\t\tException (5, oldpc);\n");
printf ("\t\tgoto %s;\n", endlabelstr);
printf ("\t} else {\n");
addcycles3 ("\t\t");
}
printf ("\t\tif ((newv & 0xffff8000) != 0 && (newv & 0xffff8000) != 0xffff8000) {\n");
- printf ("\t\t\tSET_VFLG (1); SET_NFLG (1); SET_CFLG (0);\n");
+ printf ("\t\t\tSET_VFLG (1);\n");
+#ifdef UNDEF68020
+ if (cpu_level > 0)
+ printf ("\t\t\tif (currprefs.cpu_level == 0) SET_NFLG (1);\n");
+ else
+#endif
+ printf ("\t\t\tSET_NFLG (1);\n");
printf ("\t\t} else {\n");
printf ("\t\t\tif (((uae_s16)rem < 0) != ((uae_s32)dst < 0)) rem = -rem;\n");
genflags (flag_logical, sz_word, "newv", "", "");
fprintf (f, "#include \"events.h\"\n");
fprintf (f, "#include \"newcpu.h\"\n");
fprintf (f, "#include \"cpu_prefetch.h\"\n");
- fprintf (f, "#include \"compiler.h\"\n");
fprintf (f, "#include \"cputbl.h\"\n");
fprintf (f, "#define CPUFUNC(x) x##_ff\n"
}
if (i68000)
fprintf (stblfile, "#ifndef CPUEMU_68000_ONLY\n");
- fprintf (stblfile, "{ CPUFUNC(op_%04lx_%d), %ld }, /* %s */\n", opcode, postfix, opcode, lookuptab[i].name);
+ fprintf (stblfile, "{ %sCPUFUNC(op_%04lx_%d), %ld }, /* %s */\n",
+ using_ce ? "(cpuop_func*)" : "", opcode, postfix, opcode, lookuptab[i].name);
if (i68000)
fprintf (stblfile, "#endif\n");
- fprintf (headerfile, "extern cpuop_func op_%04lx_%d_nf;\n", opcode, postfix);
- fprintf (headerfile, "extern cpuop_func op_%04lx_%d_ff;\n", opcode, postfix);
+ fprintf (headerfile, "extern %s op_%04lx_%d_nf;\n",
+ using_ce ? "cpuop_func_ce" : "cpuop_func", opcode, postfix);
+ fprintf (headerfile, "extern %s op_%04lx_%d_ff;\n",
+ using_ce ? "cpuop_func_ce" : "cpuop_func", opcode, postfix);
printf ("/* %s */\n", outopcode (opcode));
if (i68000)
printf("#ifndef CPUEMU_68000_ONLY\n");
- printf ("unsigned long REGPARAM2 CPUFUNC(op_%04lx_%d)(uae_u32 opcode)\n{\n", opcode, postfix);
+ printf ("%s REGPARAM2 CPUFUNC(op_%04lx_%d)(uae_u32 opcode)\n{\n", using_ce ? "void" : "unsigned long", opcode, postfix);
switch (table68k[opcode].stype) {
case 0: smsk = 7; break;
if (need_endlabel)
printf ("%s: ;\n", endlabelstr);
returncycles ("", insn_n_cycles);
- if (using_ce)
- printf ("return 0;\n");
printf ("}\n");
if (i68000)
printf("#endif\n");
extern void CIA_handler (void);
extern void diskindex_handler (void);
+extern void cia_parallelack (void);
+extern void cia_diskindex (void);
extern void dumpcia (void);
extern void rethink_cias (void);
+++ /dev/null
- /*
- * UAE - The Un*x Amiga Emulator
- *
- * m68k -> i386 compiler
- *
- * (c) 1995 Bernd Schmidt
- */
-
-typedef uaecptr (*code_execfunc)(void);
-
-struct code_page {
- struct code_page *next;
- uae_u32 allocmask;
-};
-
-struct hash_block {
- struct hash_block *lru_next, *lru_prev;
- struct hash_entry *he_first;
-
- struct code_page *cpage;
- int alloclen;
- uae_u32 page_allocmask;
- char *compile_start;
-
- int nrefs;
-
- int translated:1;
- int untranslatable:1;
- int allocfailed:1;
-};
-
-struct hash_entry {
- code_execfunc execute; /* For the sake of the stubs in X86.S */
- struct hash_entry *next,*prev;
- struct hash_entry *next_same_block, *lru_next, *lru_prev;
- struct hash_block *block;
-
- uaecptr addr;
- uae_u32 matchword;
- int ncalls:8;
- int locked:1;
- int cacheflush:1;
-};
-
-extern int nr_bbs_start;
-extern uae_u8 nr_bbs_to_run;
-extern code_execfunc exec_me;
-
-#ifdef USE_COMPILER
-STATIC_INLINE void run_compiled_code(void)
-{
-
- /*if (regs.spcflags == SPCFLAG_EXEC && may_run_compiled) {*/
- while (regs.spcflags == SPCFLAG_EXEC) {
- uaecptr newpc;
- regs.spcflags = 0;
- /* newpc = (*exec_me)();*/
- __asm__ __volatile__ ("pushl %%ebp; call *%1; popl %%ebp" : "=a" (newpc) : "r" (exec_me) :
- "%eax", "%edx", "%ecx", "%ebx",
- "%edi", "%esi", "memory", "cc");
- if (nr_bbs_to_run == 0) {
- struct hash_entry *h = (struct hash_entry *)newpc;
- regs.spcflags = SPCFLAG_EXEC;
- exec_me = h->execute;
- regs.pc = h->addr;
- regs.pc_p = regs.pc_oldp = get_real_address(h->addr);
- nr_bbs_to_run = nr_bbs_start;
- } else
- m68k_setpc_fast(newpc);
- do_cycles();
- }
-/*} else */
- regs.spcflags &= ~SPCFLAG_EXEC;
-}
-
-extern void compiler_init(void);
-extern void possible_loadseg(void);
-
-extern void m68k_do_rts(void);
-extern void m68k_do_bsr(uaecptr, uae_s32);
-extern void m68k_do_jsr(uaecptr, uaecptr);
-extern void compiler_flush_jsr_stack(void);
-
-#else
-
-#define run_compiled_code() do { ; } while (0)
-#define compiler_init() do { ; } while (0)
-#define possible_loadseg() do { ; } while (0)
-#define compiler_flush_jsr_stack() do { ; } while (0)
-
-STATIC_INLINE void m68k_do_rts(void)
-{
- uaecptr pc = get_long (m68k_areg(regs, 7));
- m68k_areg(regs, 7) += 4;
- if (pc & 1)
- exception3 (0x4e75, m68k_getpc(), pc);
- else
- m68k_setpc(pc);
-}
-
-STATIC_INLINE void m68k_do_bsr(uaecptr oldpc, uae_s32 offset)
-{
- m68k_areg(regs, 7) -= 4;
- put_long(m68k_areg(regs, 7), oldpc);
- m68k_incpc(offset);
-}
-
-STATIC_INLINE void m68k_do_jsr(uaecptr oldpc, uaecptr dest)
-{
- m68k_areg(regs, 7) -= 4;
- put_long(m68k_areg(regs, 7), oldpc);
- m68k_setpc(dest);
-}
-
-#endif
extern void dumpdisk (void);
extern void DISK_history_add (const char *name, int idx);
extern char *DISK_history_get (int idx);
-extern int DISK_examine_image (struct uae_prefs *p, int drive);
+int DISK_examine_image (struct uae_prefs *p, int num, uae_u32 *crc32);
+extern char *DISK_get_saveimagepath (const char *name);
+extern void DISK_reinsert (int num);
extern void DSKLEN (uae_u16 v, int hpos);
extern uae_u16 DSKBYTR (int hpos);
#define ERROR_NO_MORE_ENTRIES 232
#define ERROR_NOT_IMPLEMENTED 236
+#define A_FIBF_HIDDEN (1<<7)
#define A_FIBF_SCRIPT (1<<6)
#define A_FIBF_PURE (1<<5)
#define A_FIBF_ARCHIVE (1<<4)
extern void S2X_refresh (void);
extern void S2X_render (void);
extern void S2X_init (int dw, int dh, int aw, int ah, int mult, int ad, int dd);
+extern void S2X_free (void);
typedef unsigned char uint8;
typedef unsigned short uint16;
/* Functions to be called when prefs are changed by non-gui code. */
extern void gui_update_gfx (void);
+
+void notify_user (int msg);
+int translate_message (int msg, char *out);
+typedef enum {
+ NUMSG_NEEDEXT2, NUMSG_NOROMKEY, NUMSG_KSROMCRCERROR, NUMSG_KSROMREADERROR, NUMSG_NOEXTROM,
+ NUMSG_MODRIP_NOTFOUND, NUMSG_MODRIP_FINISHED, NUMSG_MODRIP_SAVE,
+ NUMSG_KS68020, NUMSG_ROMNEED, NUMSG_NOZLIB, NUMSG_STATEHD,
+ NUMSG_NOCAPS, NUMSG_OLDCAPS,
+} notify_user_msg;
+
#undef DIRECT_MEMFUNCS_SUCCESSFUL
#include "machdep/maccess.h"
-#ifndef CAN_MAP_MEMORY
-#undef USE_COMPILER
-#endif
-
-#ifdef JIT
-#if defined(USE_COMPILER) && !defined(USE_MAPPED_MEMORY)
-#define USE_MAPPED_MEMORY
-#endif
-#endif
-
#define chipmem_start 0x00000000
#define bogomem_start 0x00C00000
#define a3000mem_start 0x07000000
#endif
typedef unsigned long cpuop_func (uae_u32) REGPARAM;
+typedef void cpuop_func_ce (uae_u32) REGPARAM;
struct cputbl {
cpuop_func *handler;
#define m68k_dreg(r,num) ((r).regs[(num)])
#define m68k_areg(r,num) (((r).regs + 8)[(num)])
-#if !defined USE_COMPILER
STATIC_INLINE void m68k_setpc (uaecptr newpc)
{
regs.pc_p = regs.pc_oldp = get_real_address (newpc);
regs.pc = newpc;
}
-#else
-extern void m68k_setpc (uaecptr newpc);
-#endif
STATIC_INLINE uaecptr m68k_getpc (void)
{
return r;
}
-#ifdef USE_COMPILER
-extern void m68k_setpc_fast (uaecptr newpc);
-extern void m68k_setpc_bcc (uaecptr newpc);
-extern void m68k_setpc_rte (uaecptr newpc);
-#else
+STATIC_INLINE void m68k_do_rts(void)
+{
+ m68k_setpc(get_long(m68k_areg(regs, 7)));
+ m68k_areg(regs, 7) += 4;
+}
+
+STATIC_INLINE void m68k_do_bsr(uaecptr oldpc, uae_s32 offset)
+{
+ m68k_areg(regs, 7) -= 4;
+ put_long(m68k_areg(regs, 7), oldpc);
+ m68k_incpc(offset);
+}
+
+STATIC_INLINE void m68k_do_jsr(uaecptr oldpc, uaecptr dest)
+{
+ m68k_areg(regs, 7) -= 4;
+ put_long(m68k_areg(regs, 7), oldpc);
+ m68k_setpc(dest);
+}
+
#define m68k_setpc_fast m68k_setpc
#define m68k_setpc_bcc m68k_setpc
#define m68k_setpc_rte m68k_setpc
-#endif
STATIC_INLINE void m68k_setstopped (int stop)
{
char description[256];
char info[256];
int config_version;
+ char config_hardware_path[256];
+ char config_host_path[256];
int illegal_mem;
int no_xhair;
extern int target_parse_option (struct uae_prefs *, char *option, char *value);
extern void target_save_options (FILE *, struct uae_prefs *);
-extern void target_default_options (struct uae_prefs *);
+extern void target_default_options (struct uae_prefs *, int type);
extern int target_cfgfile_load (struct uae_prefs *, char *filename, int type);
extern int cfgfile_load (struct uae_prefs *, const char *filename, int *);
extern void *xmalloc(size_t);
extern void *xcalloc(size_t, size_t);
+extern void xfree(void*);
/* We can only rely on GNU C getting enums right. Mickeysoft VSC++ is known
* to have problems, and it's likely that other compilers choke too. */
#define ASM_SYM_FOR_FUNC(a)
#endif
-#if defined USE_COMPILER
-#undef NO_PREFETCH_BUFFER
-#undef NO_EXCEPTION_3
-#define NO_EXCEPTION_3
-#define NO_PREFETCH_BUFFER
-#endif
-
#include "target.h"
#ifdef UAE_CONSOLE
struct zfile;
extern int is_zlib;
+typedef int (*zfile_callback)(struct zfile*, void*);
+
extern struct zfile *zfile_fopen (const char *, const char *);
extern struct zfile *zfile_fopen_empty (const char *name, int size);
extern int zfile_exists (const char *name);
extern int zfile_zcompress (struct zfile *dst, void *src, int size);
extern int zfile_zuncompress (void *dst, int dstsize, struct zfile *src, int srcsize);
extern int zfile_gettype (struct zfile *z);
+extern int zfile_zopen (const char *name, zfile_callback zc, void *user);
+extern char *zfile_getname (struct zfile *f);
+extern uae_u32 zfile_crc32 (struct zfile *f);
#define ZFILE_UNKNOWN 0
#define ZFILE_CONFIGURATION 1
#include "autoconf.h"
#include "osemu.h"
#include "osdep/exectasks.h"
-#include "compiler.h"
#include "picasso96.h"
#include "bsdsocket.h"
#include "uaeexe.h"
}
}
+static void parse_diskswapper (char *s)
+{
+ char *tmp = my_strdup (s);
+ char *delim = ",";
+ char *p1, *p2;
+ int num = 0;
+
+ p1 = tmp;
+ for(;;) {
+ p2 = strtok (p1, delim);
+ if (!p2)
+ break;
+ p1 = NULL;
+ if (num >= MAX_SPARE_DRIVES)
+ break;
+ strncpy (currprefs.dfxlist[num], p2, 255);
+ num++;
+ }
+ free (tmp);
+}
+
static void parse_cmdline (int argc, char **argv)
{
int i;
for (i = 1; i < argc; i++) {
- if (strcmp (argv[i], "-cfgparam") == 0) {
+ if (!strncmp (argv[i], "-diskswapper=", 13)) {
+ parse_diskswapper (argv[i] + 13);
+ } else if (strcmp (argv[i], "-cfgparam") == 0) {
if (i + 1 < argc)
i++;
} else if (strncmp (argv[i], "-config=", 8) == 0) {
reset_frame_rate_hack ();
init_m68k(); /* must come after reset_frame_rate_hack (); */
- compiler_init ();
gui_update ();
if (graphics_init ()) {
#include "savestate.h"
#include "ar.h"
#include "crc32.h"
-
-#ifdef USE_MAPPED_MEMORY
-#include <sys/mman.h>
-#endif
+#include "gui.h"
#ifdef JIT
int canbang;
{
int i;
+ if (!rd)
+ return 0;
for (i = 0; i < romlist_cnt; i++) {
if (rl[i].rd == rd)
return rl[i].path;
{ "Cloanto Amiga Forever ROM key", 0, 0, 0x869ae1b1, 2069, 0, 68000, ROMTYPE_KEY },
{ "Kickstart v1.0", 0, 0, 0x299790ff, 262144, 1, 68000, ROMTYPE_KICK },
- { "Kickstart v1.1", 31, 34, 0xd060572a, 262144, 2, 68000, ROMTYPE_KICK },
- { "Kickstart v1.2", 32, 34, 0xec86dae2, 262144, 3, 68000, ROMTYPE_KICK },
+ { "Kickstart v1.1 (NTSC)", 31, 34, 0xd060572a, 262144, 2, 68000, ROMTYPE_KICK },
+ { "Kickstart v1.1 (PAL)", 31, 34, 0xec86dae2, 262144, 3, 68000, ROMTYPE_KICK },
{ "Kickstart v1.2", 33, 166, 0x0ed783d0, 262144, 4, 68000, ROMTYPE_KICK },
{ "Kickstart v1.2", 33, 180, 0xa6ce1636, 262144, 5, 68000, ROMTYPE_KICK },
{ "Kickstart v1.3", 34, 5, 0xc4f0f55f, 262144, 6, 68000, ROMTYPE_KICK },
- { "Kickstart v1.3 (Cloanto)", 34, 5, 0xe0f37258, 262144, 32, 68000, ROMTYPE_KICK },
+ { "Kickstart v1.3", 34, 5, 0xe0f37258, 262144, 32, 68000, ROMTYPE_KICK },
{ "Kickstart v2.04", 37, 175, 0xc3bdb240, 524288, 7, 68000, ROMTYPE_KICK },
{ "Kickstart v2.05", 37, 299, 0x83028fb5, 524288, 8, 68000, ROMTYPE_KICK },
{ "Kickstart v2.05", 37, 300, 0x64466c2a, 524288, 9, 68000, ROMTYPE_KICK },
{ "Kickstart v2.05", 37, 350, 0x43b0df7b, 524288, 10, 68000, ROMTYPE_KICK },
- { "Kickstart v3.0", 39, 106, 0x6c9b07d2, 524288, 11, 68020, ROMTYPE_KICK },
+ { "Kickstart v3.0", 39, 106, 0x6c9b07d2, 524288, 11, 68000, ROMTYPE_KICK },
{ "Kickstart v3.0", 39, 106, 0x9e6ac152, 524288, 12, 68020, ROMTYPE_KICK },
{ "Kickstart v3.1", 40, 55, 0x14e93bcc, 524288, 13, 68020, ROMTYPE_KICK },
{ "Kickstart v3.1", 40, 63, 0xfc24ae0d, 524288, 14, 68000, ROMTYPE_KICK },
{ "Kickstart v3.1", 40, 68, 0x1483a091, 524288, 15, 68020, ROMTYPE_KICK },
{ "Kickstart v3.1 (Cloanto)", 40, 68, 0x43b6dd22, 524288, 31, 68020, ROMTYPE_KICK },
{ "Kickstart v3.1", 40, 68, 0xd6bae334, 524288, 16, 68020, ROMTYPE_KICK },
- { "Kickstart v3.1", 40, 70, 0x917100a0, 524288, 17, 68020, ROMTYPE_KICK },
+// { "Kickstart v3.1", 40, 70, 0x917100a0, 524288, 17, 68020, ROMTYPE_KICK },
{ "CD32 Kickstart v3.1", 40, 60, 0x1e62d4a5, 524288, 18, 68020, ROMTYPE_KICKCD32 },
{ "CD32 Extended", 40, 60, 0x87746be2, 524288, 19, 68020, ROMTYPE_EXTCD32 },
strcat (tmp, "rom.key");
f = zfile_fopen (tmp, "rb");
if (!f) {
- strcpy (tmp, p->path_rom);
- strcat (tmp, "rom.key");
- f = zfile_fopen (tmp, "rb");
+ struct romdata *rd = getromdatabyid (0);
+ char *s = romlist_get (rd);
+ if (s)
+ f = zfile_fopen (s, "rb");
if (!f) {
- f = zfile_fopen ("roms\\rom.key", "rb");
+ strcpy (tmp, p->path_rom);
+ strcat (tmp, "rom.key");
+ f = zfile_fopen (tmp, "rb");
if (!f) {
- strcpy (tmp, start_path);
- strcat (tmp, "rom.key");
- f = zfile_fopen(tmp, "rb");
+ f = zfile_fopen ("roms\\rom.key", "rb");
if (!f) {
strcpy (tmp, start_path);
- strcat (tmp, "..\\shared\\rom\\rom.key");
+ strcat (tmp, "rom.key");
f = zfile_fopen(tmp, "rb");
+ if (!f) {
+ strcpy (tmp, start_path);
+ strcat (tmp, "..\\shared\\rom\\rom.key");
+ f = zfile_fopen(tmp, "rb");
+ }
}
}
}
p = load_keyfile (&currprefs, NULL, &keysize);
if (!p) {
- #ifndef SINGLEFILE
- gui_message ("Could not find ROM key file.\n");
+#ifndef SINGLEFILE
+ notify_user (NUMSG_NOROMKEY);
#endif
return 0;
}
}
#ifndef SINGLEFILE
if (cksum != 0xFFFFFFFFul)
- gui_message("Kickstart checksum incorrect. You probably have a corrupted ROM image.\n");
+ notify_user (NUMSG_KSROMCRCERROR);
#endif
return 0;
}
cr = 1;
}
+ if (cloanto_rom)
+ *cloanto_rom = cr;
+
i = zfile_fread (mem, 1, size, f);
zfile_fclose (f);
if ((i != 8192 && i != 65536) && i != 131072 && i != 262144 && i != 524288) {
- gui_message ("Error while reading Kickstart.\n");
+ notify_user (NUMSG_KSROMREADERROR);
return 0;
}
if (i == size / 2)
memcpy (mem + size / 2, mem, size / 2);
- if (cr)
- decode_cloanto_rom (mem, size, i);
+ if (cr) {
+ if (!decode_cloanto_rom (mem, size, i))
+ return 0;
+ }
if (i == 8192 || i == 65536) {
a1000_bootrom = malloc (65536);
memcpy (a1000_bootrom, kickmemory, 65536);
}
if (dochecksum && i >= 262144)
kickstart_checksum (mem, size);
- if (cloanto_rom)
- *cloanto_rom = cr;
return i;
}
return 0;
f = zfile_fopen (currprefs.romextfile, "rb");
if (!f) {
- gui_message("No extended Kickstart ROM found");
+ notify_user (NUMSG_NOEXTROM);
return 0;
}
zfile_fseek (f, 0, SEEK_END);
static int load_kickstart (void)
{
struct zfile *f = zfile_fopen (currprefs.romfile, "rb");
- char tmprom[512];
+ char tmprom[MAX_DPATH];
strcpy (tmprom, currprefs.romfile);
if (f == NULL) {
void memory_reset (void)
{
- int custom_start;
+ int custom_start, bnk;
be_cnt = 0;
currprefs.chipmem_size = changed_prefs.chipmem_size;
if (savestate_state != STATE_RESTORE)
clearexec ();
load_extendedkickstart ();
+ kickmem_mask = 524288 - 1;
if (!load_kickstart ()) {
#ifdef AUTOCONFIG
init_ersatz_rom (kickmemory);
ersatzkickfile = 1;
+#else
+ uae_restart (-1, NULL);
#endif
}
}
map_banks (&cia_bank, 0xA0, 32, 0);
map_banks (&clock_bank, 0xDC, 1, 0);
- /* @@@ Does anyone have a clue what should be in the 0x200000 - 0xA00000
- * range on an Amiga without expansion memory? */
- custom_start = allocated_chipmem >> 16;
- if (custom_start < 0x20 + (currprefs.fastmem_size >> 16))
- custom_start = 0x20 + (currprefs.fastmem_size >> 16);
- map_banks (&dummy_bank, custom_start, 0xA0 - custom_start, 0);
+ /* map "nothing" to 0x200000 - 0xa00000 */
+ bnk = allocated_chipmem >> 16;
+ if (bnk < 0x20 + (currprefs.fastmem_size >> 16))
+ bnk = 0x20 + (currprefs.fastmem_size >> 16);
+ map_banks (&dummy_bank, bnk, 0xA0 - bnk, 0);
/*map_banks (&mbres_bank, 0xDE, 1); */
if (bogomemory != 0) {
if (dstptr)
dstbak = dst = dstptr;
else
- dstbak = dst = malloc (4 + 4 + 4 + 4 + 4 + mem_size);
+ dstbak = dst = malloc (4 + 4 + 4 + 4 + 4 + 256 + 256 + mem_size);
save_u32 (mem_start);
save_u32 (mem_size);
save_u32 (mem_type);
}
return a;
}
+
+void xfree (void *p)
+{
+ free (p);
+}
#include "memory.h"
#include "autoconf.h"
#include "moduleripper.h"
+#include "gui.h"
static int got, canceled;
}
#endif
if (!got)
- gui_message("No modules or compressed data found");
+ notify_user (NUMSG_MODRIP_NOTFOUND);
else if (!canceled)
- gui_message("Search finished");
+ notify_user (NUMSG_MODRIP_FINISHED);
free (buf);
}
FILE *moduleripper2_fopen (const char *name, const char *mode, const char *id)
{
- char msg[1000];
+ char msg[MAX_DPATH], msg2[MAX_DPATH];
int ret;
if (canceled)
return NULL;
got++;
- sprintf (msg, "Module/packer found\n%s\nDo you want to save it?", id);
- ret = gui_message_multibutton (2, msg);
+ translate_message (NUMSG_MODRIP_SAVE, msg);
+ sprintf (msg2, msg, id);
+ ret = gui_message_multibutton (2, msg2);
if (ret < 0)
canceled = 1;
if (ret < 0 || ret != 1)
#include "autoconf.h"
#include "ersatz.h"
#include "debug.h"
-#include "compiler.h"
#include "gui.h"
#include "savestate.h"
#include "blitter.h"
int sv = regs.s;
exception_debug (nr);
- compiler_flush_jsr_stack();
MakeSR();
c = 0;
int sv = regs.s;
exception_debug (nr);
- compiler_flush_jsr_stack();
MakeSR();
if (!regs.s) {
return 4;
}
- compiler_flush_jsr_stack ();
if (opcode == 0x4E7B && get_long (0x10) == 0 && in_rom (pc) && !cpu68020) {
- gui_message ("Your Kickstart requires a 68020 CPU");
+ notify_user (NUMSG_KS68020);
cpu68020 = 1;
}
do_copper ();
}
-#ifdef JIT
- run_compiled_code();
-#endif
if (regs.spcflags & SPCFLAG_DOTRACE) {
Exception (9,last_trace_ad);
}
if (unitnum >= unitcnt)
return 0;
if (log_scsi)
- write_log ("ASPI: opening %d:%d:%d\n", si[unitnum].scsibus, si[unitnum].target, si[unitnum].lun);
+ write_log ("ASPI: opening %d:%d:%d (%d)\n", si[unitnum].scsibus, si[unitnum].target, si[unitnum].lun, unitnum);
si[unitnum].handle = openscsi (si[unitnum].scsibus, si[unitnum].target, si[unitnum].lun);
if (si[unitnum].handle)
si[unitnum].mediainserted = mediacheck (unitnum);
// 6: generate unformatted data, that changes each revolution
// 7: directly use source memory buffer supplied with LockImageMemory
// 8: flakey data is created on one revolution, updated with each lock
+// 9: ...Info.type holds the expected structure type
#define DI_LOCK_INDEX DF_0
#define DI_LOCK_ALIGN DF_1
#define DI_LOCK_DENVAR DF_2
#define DI_LOCK_NOISEREV DF_6
#define DI_LOCK_MEMREF DF_7
#define DI_LOCK_UPDATEFD DF_8
+#define DI_LOCK_TYPE DF_9
#define CAPS_MAXPLATFORM 4
#define CAPS_MTRS 5
typedef struct CapsDateTimeExt *PCAPSDATETIMEEXT;
+// library version information block
+struct CapsVersionInfo {
+ UDWORD type; // library type
+ UDWORD release; // release ID
+ UDWORD revision; // revision ID
+ UDWORD flag; // supported flags
+};
+
+typedef struct CapsVersionInfo *PCAPSVERSIONINFO;
+
// disk image information block
struct CapsImageInfo {
UDWORD type; // image type
typedef struct CapsTrackInfo *PCAPSTRACKINFO;
+// disk track information block
+struct CapsTrackInfoT1 {
+ UDWORD type; // track type
+ UDWORD cylinder; // cylinder#
+ UDWORD head; // head#
+ UDWORD sectorcnt; // available sectors
+ UDWORD sectorsize; // sector size
+ PUBYTE trackbuf; // track buffer memory
+ UDWORD tracklen; // track buffer memory length
+ UDWORD timelen; // timing buffer length
+ PUDWORD timebuf; // timing buffer
+ UDWORD overlap; // overlap position
+};
+
+typedef struct CapsTrackInfoT1 *PCAPSTRACKINFOT1;
+
#pragma pack(pop)
// image type
imgeDensityHeader,
imgeDensityStream,
imgeDensityData,
- imgeIncompatible
+ imgeIncompatible,
+ imgeUnsupportedType
};
#endif
ExtSub SDWORD __cdecl CAPSUnlockTrack(SDWORD id, UDWORD cylinder, UDWORD head);
ExtSub SDWORD __cdecl CAPSUnlockAllTracks(SDWORD id);
ExtSub PCHAR __cdecl CAPSGetPlatformName(UDWORD pid);
+ExtSub SDWORD __cdecl CAPSGetVersionInfo(PCAPSVERSIONINFO pi, UDWORD flag);
#endif
#include "caps_win32.h"
#include "zfile.h"
+#include "gui.h"
#include "ComType.h"
#include "CapsAPI.h"
static SDWORD caps_cont[4]= {-1, -1, -1, -1};
static int caps_locked[4];
-static int caps_flags = DI_LOCK_DENVAR|DI_LOCK_DENNOISE|DI_LOCK_NOISE|DI_LOCK_UPDATEFD;
+static int caps_flags = DI_LOCK_DENVAR|DI_LOCK_DENNOISE|DI_LOCK_NOISE|DI_LOCK_UPDATEFD|DI_LOCK_TYPE;
+#define LIB_TYPE 1
int caps_init (void)
{
static int init, noticed;
int i;
HMODULE h;
+ struct CapsVersionInfo cvi;
if (init) return 1;
h = LoadLibrary ("CAPSImg.dll");
if (!h) {
if (noticed)
return 0;
- gui_message (
- "This disk image needs the C.A.P.S. plugin\nwhich is available from\nhttp//www.caps-project.org/download.shtml");
+ notify_user (NUMSG_NOCAPS);
noticed = 1;
return 0;
}
- if (GetProcAddress(h, "CAPSLockImageMemory") == 0) {
+ if (GetProcAddress(h, "CAPSLockImageMemory") == 0 || GetProcAddress(h, "CAPSGetVersionInfo") == 0) {
if (noticed)
return 0;
- gui_message (
- "You need updated C.A.P.S. plugin\nwhich is available from\nhttp//www.caps-project.org/download.shtml");
+ notify_user (NUMSG_OLDCAPS);
noticed = 1;
return 0;
}
FreeLibrary (h);
init = 1;
+ cvi.type = LIB_TYPE;
+ CAPSGetVersionInfo (&cvi, 0);
+ write_log ("CAPS: library version %d.%d\n", cvi.release, cvi.revision);
for (i = 0; i < 4; i++)
caps_cont[i] = CAPSAddImage();
return 1;
return 1;
}
+#if 0
+static void outdisk (void)
+{
+ struct CapsTrackInfo ci;
+ int tr;
+ FILE *f;
+ static int done;
+
+ if (done)
+ return;
+ done = 1;
+ f = fopen("c:\\out3.dat", "wb");
+ if (!f)
+ return;
+ for (tr = 0; tr < 160; tr++) {
+ CAPSLockTrack(&ci, caps_cont[0], tr / 2, tr & 1, caps_flags);
+ fwrite (ci.trackdata[0], ci.tracksize[0], 1, f);
+ fwrite ("XXXX", 4, 1, f);
+ }
+ fclose (f);
+}
+#endif
+
int caps_loadrevolution (uae_u16 *mfmbuf, int drv, int track, int *tracklength)
{
- static int revcnt;
- int rev, len, i;
+ int len, i;
uae_u16 *mfm;
- struct CapsTrackInfo ci;
+ struct CapsTrackInfoT1 ci;
- revcnt++;
- CAPSLockTrack(&ci, caps_cont[drv], track / 2, track & 1, caps_flags);
- rev = revcnt % ci.trackcnt;
- len = ci.tracksize[rev];
+ ci.type = LIB_TYPE;
+ CAPSLockTrack((PCAPSTRACKINFO)&ci, caps_cont[drv], track / 2, track & 1, caps_flags);
+ len = ci.tracklen;
*tracklength = len * 8;
mfm = mfmbuf;
for (i = 0; i < (len + 1) / 2; i++) {
- uae_u8 *data = ci.trackdata[rev]+ i * 2;
+ uae_u8 *data = ci.trackbuf + i * 2;
*mfm++ = 256 * *data + *(data + 1);
}
return 1;
}
-int caps_loadtrack (uae_u16 *mfmbuf, uae_u16 *tracktiming, int drv, int track, int *tracklength, int *multirev)
+int caps_loadtrack (uae_u16 *mfmbuf, uae_u16 *tracktiming, int drv, int track, int *tracklength, int *multirev, int *gapoffset)
{
int i, len, type;
uae_u16 *mfm;
- struct CapsTrackInfo ci;
+ struct CapsTrackInfoT1 ci;
+ ci.type = LIB_TYPE;
*tracktiming = 0;
- CAPSLockTrack(&ci, caps_cont[drv], track / 2, track & 1, caps_flags);
+ CAPSLockTrack((PCAPSTRACKINFO)&ci, caps_cont[drv], track / 2, track & 1, caps_flags);
mfm = mfmbuf;
*multirev = (ci.type & CTIT_FLAG_FLAKEY) ? 1 : 0;
- if (ci.trackcnt > 1)
- *multirev = 1;
type = ci.type & CTIT_MASK_TYPE;
- len = ci.tracksize[0];
+ len = ci.tracklen;
*tracklength = len * 8;
+ *gapoffset = ci.overlap * 8;
for (i = 0; i < (len + 1) / 2; i++) {
- uae_u8 *data = ci.trackdata[0]+ i * 2;
+ uae_u8 *data = ci.trackbuf + i * 2;
*mfm++ = 256 * *data + *(data + 1);
}
#if 0
{
FILE *f=fopen("c:\\1.txt","wb");
- fwrite (ci.trackdata[0], len, 1, f);
+ fwrite (ci.trackbuf, len, 1, f);
fclose (f);
}
#endif
tracktiming[i] = (uae_u16)ci.timebuf[i];
}
#if 0
- write_log ("caps: drive:%d track:%d flakey:%d multi:%d timing:%d type:%d\n",
- drv, track, *multirev, ci.trackcnt, ci.timelen, type);
+ write_log ("caps: drive:%d track:%d len:%d flakey:%d multi:%d timing:%d type:%d\n",
+ drv, track, len, *multirev, ci.trackcnt, ci.timelen, type);
#endif
return 1;
}
int caps_init (void);
void caps_unloadimage (int drv);
int caps_loadimage (struct zfile *zf, int drv, int *num_tracks);
-int caps_loadtrack (uae_u16 *mfmbuf, uae_u16 *tracktiming, int drv, int track, int *tracklength, int *multirev);
+int caps_loadtrack (uae_u16 *mfmbuf, uae_u16 *tracktiming, int drv, int track, int *tracklength, int *multirev, int *gapoffset);
int caps_loadrevolution (uae_u16 *mfmbuf, int drv, int track, int *tracklength);
else
{
//best is add a real keystatecheck here but it still work so
- apostrophstate=0;
+ apostrophstate = 0;
+ inputdevice_translatekeycode (num, DIK_LALT,0);
+ inputdevice_translatekeycode (num, DIK_LSHIFT,0);
+ inputdevice_translatekeycode (num, 4, 0); // release also the # key
return 13;
}
}
else
{
- inputdevice_translatekeycode (num, DIK_LALT,0);
- inputdevice_translatekeycode (num, DIK_LSHIFT,0);
+ inputdevice_translatekeycode (num, DIK_LALT, 0);
+ inputdevice_translatekeycode (num, DIK_LSHIFT, 0);
// Here is the same not nice but do the job
return 4; // the german # key
memset (&bltfx, 0, sizeof (bltfx));
bltfx.dwSize = sizeof (bltfx);
hr2 = IDirectDrawSurface7_Blt (surface, NULL, NULL, NULL, DDBLT_COLORFILL | DDBLT_WAIT, &bltfx);
- if (hr2 != DD_OK)
+ if (hr2 != DD_OK) {
+ static int crap = 0;
+ if (hr2 == 0x887601C2) {
+ if (crap)
+ return hr;
+ crap = 1;
+ write_log ("Restore succeeded but following Blt failed with lost surface. Display driver bug?\n");
+ return hr;
+ }
write_log("Surface clear failed: %s\n", DXError (hr2));
+ }
}
return hr;
}
return dderr;
}
-static struct DirectDrawSurfaceMapper DirectDrawState;
+struct DirectDrawSurfaceMapper DirectDrawState;
static int lockcnt = 0;
surface = DirectDrawState.tertiary.surface;
surfacedesc = &DirectDrawState.tertiary.desc;
break;
+ case temporary_surface:
+ surface = DirectDrawState.temporary.surface;
+ surfacedesc = &DirectDrawState.temporary.desc;
+ break;
case overlay_surface:
surface = DirectDrawState.overlay.surface;
surfacedesc = &DirectDrawState.overlay.desc;
DirectDrawState.tertiary.desc.dwSize = sizeof( DDSURFACEDESC2 );
result = LockStub( surface_type );
break;
+ case temporary_surface:
+ DirectDrawState.temporary.desc.dwSize = sizeof( DDSURFACEDESC2 );
+ result = LockStub( surface_type );
+ break;
case overlay_surface:
DirectDrawState.overlay.desc.dwSize = sizeof( DDSURFACEDESC2 );
result = LockStub( surface_type );
HRESULT DirectDraw_SetPaletteEntries( int start, int count, PALETTEENTRY *palette )
{
HRESULT ddrval = DDERR_NOPALETTEATTACHED;
- int i;
if( DirectDrawState.lpDDP )
ddrval = IDirectDrawPalette_SetEntries( DirectDrawState.lpDDP, 0, start, count, palette );
return ddrval;
{
lpDDS4_dst = DirectDrawState.primary.surface;
}
+ else if (dsttype == temporary_surface)
+ {
+ lpDDS4_dst = DirectDrawState.temporary.surface;
+ }
else
{
lpDDS4_dst = DirectDrawState.secondary.surface;
{
lpDDS4_src = DirectDrawState.primary.surface;
}
+ else if (srctype == temporary_surface)
+ {
+ lpDDS4_src = DirectDrawState.temporary.surface;
+ }
else
{
lpDDS4_src = DirectDrawState.secondary.surface;
{
lpDDS4_dst = DirectDrawState.tertiary.surface;
}
+ else if( dsttype == temporary_surface )
+ {
+ lpDDS4_dst = DirectDrawState.temporary.surface;
+ }
else
{
lpDDS4_dst = DirectDrawState.overlay.surface;
{
lpDDS4_src = DirectDrawState.tertiary.surface;
}
+ else if( srctype == temporary_surface )
+ {
+ lpDDS4_src = DirectDrawState.temporary.surface;
+ }
else if( srctype == overlay_surface )
{
lpDDS4_src = DirectDrawState.overlay.surface;
return gb;
}
-
+int DirectDraw_GetPrimaryPixelFormat (LPDDPIXELFORMAT ddpf)
+{
+ surface_type_e surface_type;
+ HRESULT ddrval;
+
+ surface_type = DirectDraw_GetLockableType ();
+ ddpf->dwSize = sizeof (DDPIXELFORMAT);
+ if (surface_type == overlay_surface)
+ ddrval = IDirectDrawSurface7_GetPixelFormat (DirectDrawState.overlay.surface, ddpf);
+ else
+ ddrval = IDirectDrawSurface7_GetPixelFormat (DirectDrawState.primary.surface, ddpf);
+ if (ddrval != DD_OK) {
+ write_log ("GetPixelFormat failed\n%s\n", DXError (ddrval));
+ return 0;
+ }
+ return 1;
+}
secondary_surface,
tertiary_surface,
overlay_surface,
- lockable_surface
+ lockable_surface,
+ temporary_surface
} surface_type_e;
typedef enum
DDSURFACEDESC2 desc;
} overlay;
struct
+ {
+ LPDIRECTDRAWSURFACE7 surface;
+ DDSURFACEDESC2 desc;
+ } temporary;
+ struct
{
DDSURFACEDESC2 desc;
} current;
DWORD DirectDraw_CurrentHeight( void );
DWORD DirectDraw_CurrentRefreshRate (void);
int DirectDraw_GetVerticalBlankStatus (void);
+extern struct DirectDrawSurfaceMapper DirectDrawState;
+extern int DirectDraw_GetPrimaryPixelFormat (LPDDPIXELFORMAT ddpf);
extern void ddraw_unlockscr (void);
#define DirectDraw_SurfaceUnlock() ddraw_unlockscr()
aino->amigaos_mode |= A_FIBF_WRITE | A_FIBF_DELETE;
if (FILE_ATTRIBUTE_SYSTEM & mode)
aino->amigaos_mode |= A_FIBF_PURE;
+ if (FILE_ATTRIBUTE_HIDDEN & mode)
+ aino->amigaos_mode |= A_FIBF_HIDDEN;
aino->amigaos_mode = filesys_parse_mask(aino->amigaos_mode);
return 1;
}
mode |= FILE_ATTRIBUTE_SYSTEM;
else
mode &= ~FILE_ATTRIBUTE_SYSTEM;
+ if (tmpmask & A_FIBF_HIDDEN)
+ mode |= FILE_ATTRIBUTE_HIDDEN;
+ else
+ mode &= ~FILE_ATTRIBUTE_HIDDEN;
SetFileAttributes(aino->nname, mode);
}
//#define IOPORT_EMU
#define io_log
-//#define io_log write_log
+#define para_log write_log
typedef int bool;
write_log ("PARAPORT: POUT can't be output\n");
ok = 0;
}
- if ((dir & 4) && (v & 4))
+ if ((dir & 4) && !(v & 4))
c[0].Control |= PARAPORT_MASK_CONTROL_SELECTIN;
if (!pp_executecycle (pport, c, 2)) {
write_log ("PARAPORT: write executeCycle failed, CTL=%02.2X DIR=%02.2X\n", v & 7, dir & 7);
return 0;
}
- write_log ("PARAPORT: write CTL=%02.2X DIR=%02.2X\n", v & 7, dir & 7);
+ para_log ("PARAPORT: write CTL=%02.2X DIR=%02.2X\n", v & 7, dir & 7);
return ok;
}
PARAPORT_CYCLE c[1];
int ok = 1;
uae_u8 v = 0;
+ static int oldack;
if (!pport)
return 0;
v |= 4;
if (c[0].Status & PARAPORT_MASK_STATUS_PAPEREND)
v |= 2;
- if (c[0].Status & PARAPORT_MASK_STATUS_BUSY)
+ if (!(c[0].Status & PARAPORT_MASK_STATUS_BUSY))
v |= 1;
- if (c[0].Status & PARAPORT_MASK_STATUS_ACKNOWLEDGE)
+ if (c[0].Status & PARAPORT_MASK_STATUS_ACKNOWLEDGE) {
v |= 8;
- write_log ("PARAPORT: read CTL=%02.2X\n", v);
+ if (!oldack)
+ cia_parallelack ();
+ oldack = 1;
+ } else {
+ oldack = 0;
+ }
+ para_log ("PARAPORT: read CTL=%02.2X\n", v);
v &= 7;
*vp &= ~7;
*vp |= v;
write_log ("PARAPORT: write executeCycle failed, data=%02.2X\n", v);
return 0;
}
- write_log ("PARAPORT: write DATA=%02.2X\n", v);
+ para_log ("PARAPORT: write DATA=%02.2X\n", v);
return 1;
}
return 0;
}
*v = c[0].Data;
- write_log("PARAPORT: read DATA=%02.2X\n", v);
+ para_log ("PARAPORT: read DATA=%02.2X\n", v);
return ok;
}
#include "gfxfilter.h"
#ifdef OPENGL
+//#define FSAA
#include <gl\gl.h>
#include <gl\glu.h>
#ifndef GL_UNSIGNED_SHORT_4_4_4_4_EXT
#define GL_UNSIGNED_SHORT_4_4_4_4_EXT 0x8033
#endif
+#define GL_MULTISAMPLE_ARB 0x809D
static GLint max_texture_size;
static GLint tex[4];
static int arbMultisampleSupported;
static int arbMultisampleFormat;
-#if 0
+
+#ifdef FSAA
// WGLisExtensionSupported: This Is A Form Of The Extension For WGL
static int WGLisExtensionSupported(const char *extension)
}
// InitMultisample: Used To Query The Multisample Frequencies
-static int InitMultisample(HDC hDC, PIXELFORMATDESCRIPTOR *pfd, int depth)
+static int InitMultisample(HDC hDC, PIXELFORMATDESCRIPTOR *pfd)
{
PFNWGLCHOOSEPIXELFORMATARBPROC wglChoosePixelFormatARB;
int pixelFormat;
WGL_DRAW_TO_WINDOW_ARB,GL_TRUE,
WGL_SUPPORT_OPENGL_ARB,GL_TRUE,
WGL_ACCELERATION_ARB,WGL_FULL_ACCELERATION_ARB,
- WGL_COLOR_BITS_ARB,pfd.cDepthBits,
+ WGL_COLOR_BITS_ARB, pfd->cDepthBits,
WGL_ALPHA_BITS_ARB,0,
WGL_DEPTH_BITS_ARB,0,
WGL_STENCIL_BITS_ARB,0,
if (valid && numFormats >= 1) {
arbMultisampleSupported = i;
arbMultisampleFormat = pixelFormat;
+ write_log ("OPENGL: max FSAA = %d\n", i);
return arbMultisampleSupported;
}
}
// Return The Valid Format
+ write_log ("OPENGL: no FSAA support detected\n");
return arbMultisampleSupported;
}
#endif
return errmsg;
}
- memset (&pfd, 0, sizeof (pfd));
- pfd.nSize = sizeof (PIXELFORMATDESCRIPTOR);
- pfd.nVersion = 1;
- pfd.dwFlags = PFD_DRAW_TO_WINDOW | PFD_SUPPORT_OPENGL | PFD_DOUBLEBUFFER | PFD_TYPE_RGBA;
- pfd.cColorBits = depth;
- pfd.iLayerType = PFD_MAIN_PLANE;
-
for (;;) {
+ memset (&pfd, 0, sizeof (pfd));
+ pfd.nSize = sizeof (PIXELFORMATDESCRIPTOR);
+ pfd.nVersion = 1;
+ pfd.dwFlags = PFD_DRAW_TO_WINDOW | PFD_SUPPORT_OPENGL | PFD_DOUBLEBUFFER | PFD_TYPE_RGBA;
+ pfd.cColorBits = depth;
+ pfd.iLayerType = PFD_MAIN_PLANE;
+
openglhdc = GetDC (hwnd);
if(!arbMultisampleSupported) {
strcpy (errmsg, "OPENGL: can't activate gl rendering context");
return errmsg;
}
-#if 0
+#ifdef FSAA
if(!arbMultisampleSupported) {
if(InitMultisample(openglhdc, &pfd)) {
OGL_free ();
- continue;
+ strcpy (errmsg, "*");
+ return errmsg;
}
}
#endif
break;
}
- glGetIntegerv (GL_MAX_TEXTURE_SIZE, &max_texture_size);
+ glGetIntegerv (GL_MAX_TEXTURE_SIZE, &max_texture_size);
required_texture_size = 2 << exact_log2 (t_width > t_height ? t_width : t_height);
if (max_texture_size < t_width || max_texture_size < t_height) {
sprintf (errmsg, "OPENGL: %d * %d or bigger texture support required\nYour card's maximum texture size is only %d * %d",
fx = (t_width * xm - w_width) / 2;
fy = (t_height * ym - w_height) / 2;
+#ifdef FSAA
+ glEnable (GL_MULTISAMPLE_ARB);
+#endif
glClear (GL_COLOR_BUFFER_BIT);
glMatrixMode (GL_MODELVIEW);
glLoadIdentity ();
glTexCoord2f (1.0f, -1.0f); glVertex2f (v, 0);
glEnd();
}
+ glFlush ();
+#ifdef FSAA
+ glDisable (GL_MULTISAMPLE_ARB);
+#endif
}
void OGL_render (void)
#define IDI_MEMORY 194
#define IDS_SOUND_MONO 200
#define IDS_SOUND_MIXED 201
+#define IDI_QUICKSTART 201
#define IDS_SOUND_STEREO 202
#define IDS_SOUND_INTERPOL_DISABLED 203
#define IDS_SOUND_INTERPOL_RH 204
+#define IDI_PATHS 204
#define IDS_SOUND_INTERPOL_CRUX 205
#define IDS_SOUND_FILTER_OFF 206
#define IDS_SOUND_FILTER_EMULATED 207
#define IDS_WINUAETITLE_NORMAL 237
#define IDS_STARTEMULATION 238
#define IDS_TREEVIEW_ABOUT 239
+#define IDS_NOHARDDRIVES 240
+#define IDS_NUMSG_NEEDEXT2 300
+#define IDS_NUMSG_NOROMKEY 301
+#define IDS_NUMSG_KSROMCRCERROR 302
+#define IDS_NUMSG_KSROMREADERROR 303
+#define IDS_NUMSG_NOEXTROM 304
+#define IDS_NUMSG_MODRIP_NOTFOUND 305
+#define IDS_NUMSG_MODRIP_FINISHED 306
+#define IDS_NUMSG_MODRIP_SAVE 307
+#define IDS_NUMSG_KS68020 308
+#define IDS_NUMSG_ROMNEED 309
+#define IDS_NUMSG_NOZLIB 310
+#define IDS_NUMSG_STATEHD 311
+#define IDS_NUMSG_NOCAPS 312
+#define IDS_NUMSG_OLDCAPS 313
#define IDC_RESOLUTION 1021
#define IDC_SERIAL 1022
#define IDC_REFRESHRATE 1022
#define IDC_CREATE_RAW 1283
#define IDC_SNAPSHOTNAME 1284
#define IDC_SNAPSHOT 1285
+#define IDC_SAVEIMAGE0 1285
#define IDC_DOSAVESTATE 1286
+#define IDC_SAVEIMAGE1 1286
#define IDC_DOLOADSTATE 1287
+#define IDC_SAVEIMAGE2 1287
#define IDC_PROWIZARD 1288
+#define IDC_SAVEIMAGE3 1288
#define IDC_PORT0_JOY0 1300
#define IDC_PORT0_JOY1 1301
#define IDC_PORT0_MOUSE 1302
#define IDC_QUICKLOAD 1409
#define IDC_EXIT 1410
#define IDC_EDITPATH 1410
-#define IDC_CREATEHF 1500
+#define IDC_HDF_RDB 1500
#define IDC_HFSIZE 1501
#define IDC_LINEMODE 1502
+#define IDC_CREATEHF 1502
#define IDC_SOCKETS 1503
#define IDC_RESETAMIGA 1504
#define IDC_QUITEMU 1505
#define IDC_CONSTJUMP 1579
#define IDC_SOUNDDRIVEVOLUME 1579
#define IDC_JITFPU 1580
+#define IDC_SOUNDVOLUME2 1580
#define IDC_NOFLAGS 1581
+#define IDC_SOUNDDRIVEVOLUME2 1581
#define IDC_CS_CACHE_TEXT 1582
#define IDC_FORCE 1583
#define IDC_COLLISIONS 1584
#define IDC_QUICKSTART_CONFIGURATION 1675
#define IDC_PATHS_AVIOUTPUT 1675
#define IDC_QUICKSTART_COMPATIBILITY 1676
-#define IDC_PATHS_SAVESTATES2 1676
#define IDC_PATHS_AVIOUTPUTS 1676
#define IDC_QUICKSTART_CONFIG 1677
#define IDC_DF0Q 1678
#ifndef APSTUDIO_READONLY_SYMBOLS
#define _APS_NO_MFC 1
#define _APS_3D_CONTROLS 1
-#define _APS_NEXT_RESOURCE_VALUE 198
-#define _APS_NEXT_COMMAND_VALUE 40020
-#define _APS_NEXT_CONTROL_VALUE 1693
+#define _APS_NEXT_RESOURCE_VALUE 205
+#define _APS_NEXT_COMMAND_VALUE 40021
+#define _APS_NEXT_CONTROL_VALUE 1694
#define _APS_NEXT_SYMED_VALUE 101
#endif
#endif
RTEXT "Flash RAM File:",IDC_FLASHTEXT,8,112,75,10
EDITTEXT IDC_FLASHFILE,89,110,185,15,ES_AUTOHSCROLL
PUSHBUTTON "...",IDC_FLASHCHOOSER,280,110,10,15
- CONTROL "MAPROM emulation",IDC_MAPROM,"Button",BS_AUTOCHECKBOX |
- WS_TABSTOP,95,54,80,10
- CONTROL "ShapeShifter support",IDC_KICKSHIFTER,"Button",
- BS_AUTOCHECKBOX | WS_TABSTOP,187,54,80,10
+ CONTROL "MAPROM emulation [] Creates BlizKick-compatible memory area.",
+ IDC_MAPROM,"Button",BS_AUTOCHECKBOX | WS_TABSTOP,95,54,
+ 82,10
+ CONTROL "ShapeShifter support [] Patches Kickstart ROM for ShapeShifter compatibility.",
+ IDC_KICKSHIFTER,"Button",BS_AUTOCHECKBOX | WS_TABSTOP,
+ 187,54,80,10
END
IDD_DISPLAY DIALOGEX 0, 0, 300, 194
EDITTEXT IDC_P96RAM,243,108,30,12,ES_CENTER | ES_READONLY
END
-IDD_CPU DIALOGEX 0, 0, 300, 191
+IDD_CPU DIALOGEX 0, 0, 300, 177
STYLE DS_SETFONT | DS_3DLOOK | DS_CONTROL | WS_CHILD
FONT 8, "MS Sans Serif", 0, 0, 0x0
BEGIN
GROUPBOX "CPU Type:",IDC_STATIC,5,5,81,166,BS_LEFT
CONTROL "68000",IDC_CPU0,"Button",BS_AUTORADIOBUTTON | WS_GROUP |
- WS_TABSTOP,10,18,34,10
+ WS_TABSTOP,10,18,63,10
CONTROL "68010",IDC_CPU1,"Button",BS_AUTORADIOBUTTON |
- WS_TABSTOP,10,33,34,10
+ WS_TABSTOP,10,33,65,10
CONTROL "68EC020",IDC_CPU2,"Button",BS_AUTORADIOBUTTON |
- WS_TABSTOP,10,48,45,10
+ WS_TABSTOP,10,48,65,10
CONTROL "68EC020 + FPU",IDC_CPU3,"Button",BS_AUTORADIOBUTTON |
- WS_TABSTOP,10,63,67,10
+ WS_TABSTOP,10,63,68,10
CONTROL "68020",IDC_CPU4,"Button",BS_AUTORADIOBUTTON |
- WS_TABSTOP,10,78,34,10
+ WS_TABSTOP,10,78,63,10
CONTROL "68020 + FPU",IDC_CPU5,"Button",BS_AUTORADIOBUTTON |
- WS_TABSTOP,10,93,58,10
+ WS_TABSTOP,10,93,64,10
CONTROL "68040",IDC_CPU6,"Button",BS_AUTORADIOBUTTON |
- WS_TABSTOP,10,108,36,10
- CONTROL "More compatible",IDC_COMPATIBLE,"Button",
- BS_AUTOCHECKBOX | BS_LEFT | WS_GROUP | WS_TABSTOP,10,130,
- 70,10
+ WS_TABSTOP,10,108,66,10
+ CONTROL "More compatible [] Emulate 68000's prefetch registers. More compatible but slower.",
+ IDC_COMPATIBLE,"Button",BS_AUTOCHECKBOX | BS_LEFT |
+ WS_GROUP | WS_TABSTOP,10,130,70,10
GROUPBOX "CPU Emulation Speed:",IDC_STATIC,90,5,205,86
CONTROL "Fastest possible, but maintain chipset timing",
IDC_CS_HOST,"Button",BS_AUTORADIOBUTTON | BS_LEFT |
WS_TABSTOP,230,142,45,10
CONTROL "After Picasso96",IDC_TRUST2,"Button",BS_AUTORADIOBUTTON |
WS_TABSTOP,230,155,64,10
- CONTROL "JIT",IDC_JITENABLE,"Button",BS_AUTOCHECKBOX |
- WS_TABSTOP,10,145,60,10
+ CONTROL "JIT [] Enable Just-In-Time CPU emulator. Increases the speed of CPU emulation 10-100x. Requires 68020 or 68040 CPU.",
+ IDC_JITENABLE,"Button",BS_AUTOCHECKBOX | WS_TABSTOP,10,
+ 145,64,10
END
IDD_FLOPPY DIALOGEX 0, 0, 300, 230
STYLE DS_SETFONT | DS_3DLOOK | DS_CONTROL | WS_CHILD
FONT 8, "MS Sans Serif", 0, 0, 0x0
BEGIN
- RTEXT "DF0:",IDC_STATIC,16,7,20,10,SS_CENTERIMAGE
+ RTEXT "DF0:",IDC_STATIC,10,7,20,10,SS_CENTERIMAGE
COMBOBOX IDC_DF0TEXT,2,22,296,75,CBS_DROPDOWN | CBS_AUTOHSCROLL |
WS_VSCROLL | WS_TABSTOP
COMBOBOX IDC_DF0TYPE,123,6,49,50,CBS_DROPDOWNLIST | WS_VSCROLL |
WS_TABSTOP,238,4,10,15
PUSHBUTTON "Eject",IDC_EJECT0,253,4,30,15
PUSHBUTTON "...",IDC_DF0,287,4,10,15
- RTEXT "DF1:",IDC_STATIC,16,42,20,10,SS_CENTERIMAGE
+ RTEXT "DF1:",IDC_STATIC,10,42,20,10,SS_CENTERIMAGE
COMBOBOX IDC_DF1TEXT,2,58,296,75,CBS_DROPDOWN | CBS_AUTOHSCROLL |
WS_VSCROLL | WS_TABSTOP
COMBOBOX IDC_DF1TYPE,123,42,49,50,CBS_DROPDOWNLIST | WS_VSCROLL |
WS_TABSTOP,238,40,10,15
PUSHBUTTON "Eject",IDC_EJECT1,253,40,30,15
PUSHBUTTON "...",IDC_DF1,287,40,10,15
- RTEXT "DF2:",IDC_STATIC,16,77,20,10,SS_CENTERIMAGE
+ RTEXT "DF2:",IDC_STATIC,10,77,20,10,SS_CENTERIMAGE
COMBOBOX IDC_DF2TEXT,2,93,296,75,CBS_DROPDOWN | CBS_AUTOHSCROLL |
WS_VSCROLL | WS_TABSTOP
- COMBOBOX IDC_DF2TYPE,123,76,49,50,CBS_DROPDOWNLIST | WS_VSCROLL |
+ COMBOBOX IDC_DF2TYPE,123,77,49,50,CBS_DROPDOWNLIST | WS_VSCROLL |
WS_TABSTOP
RTEXT "Write Protected",IDC_STATIC,174,77,59,10,SS_CENTERIMAGE
CONTROL "",IDC_DF2WP,"Button",BS_AUTOCHECKBOX | BS_MULTILINE |
WS_TABSTOP,238,75,9,15
PUSHBUTTON "Eject",IDC_EJECT2,253,75,30,15
PUSHBUTTON "...",IDC_DF2,287,75,10,15
- RTEXT "DF3:",IDC_STATIC,16,113,20,9,SS_CENTERIMAGE
- COMBOBOX IDC_DF3TEXT,2,130,296,75,CBS_DROPDOWN | CBS_AUTOHSCROLL |
+ RTEXT "DF3:",IDC_STATIC,10,112,20,9,SS_CENTERIMAGE
+ COMBOBOX IDC_DF3TEXT,2,128,296,75,CBS_DROPDOWN | CBS_AUTOHSCROLL |
WS_VSCROLL | WS_TABSTOP
- COMBOBOX IDC_DF3TYPE,123,110,49,50,CBS_DROPDOWNLIST | WS_VSCROLL |
+ COMBOBOX IDC_DF3TYPE,123,112,49,50,CBS_DROPDOWNLIST | WS_VSCROLL |
WS_TABSTOP
RTEXT "Write Protected",IDC_STATIC,174,113,59,10,
SS_CENTERIMAGE
CONTROL "",IDC_DF3WP,"Button",BS_AUTOCHECKBOX | BS_MULTILINE |
WS_TABSTOP,238,111,9,15
- PUSHBUTTON "Eject",IDC_EJECT3,253,111,30,15
- PUSHBUTTON "...",IDC_DF3,287,111,10,15
- GROUPBOX "New disk image",IDC_SETTINGSTEXT,5,152,289,35
- COMBOBOX IDC_FLOPPYTYPE,16,165,51,50,CBS_DROPDOWNLIST |
+ PUSHBUTTON "Eject",IDC_EJECT3,253,110,30,15
+ PUSHBUTTON "...",IDC_DF3,287,109,10,15
+ GROUPBOX "New disk image",IDC_SETTINGSTEXT,5,147,289,35
+ COMBOBOX IDC_FLOPPYTYPE,16,160,51,50,CBS_DROPDOWNLIST |
WS_VSCROLL | WS_TABSTOP
- PUSHBUTTON "Create Standard ""Floppy""",IDC_CREATE,76,165,97,15
- PUSHBUTTON "Create Custom ""Floppy""",IDC_CREATE_RAW,183,165,101,15
- GROUPBOX "Floppy drive emulation speed",IDC_SETTINGSTEXT2,5,190,
+ PUSHBUTTON "Create Standard ""Floppy"" [] Creates standard 880kb ADF disk image.",
+ IDC_CREATE,76,160,97,15
+ PUSHBUTTON "Create Custom ""Floppy"" [] Creates ~2Mb low level (MFM) ADF disk image. Useful for programs that use non-AmigaDOS disk format (for example some save disks or MSDOS formatted floppies)",
+ IDC_CREATE_RAW,183,160,101,15
+ GROUPBOX "Floppy drive emulation speed",IDC_SETTINGSTEXT2,5,185,
289,35
CONTROL "",IDC_FLOPPYSPD,"msctls_trackbar32",TBS_AUTOTICKS |
- TBS_TOP | WS_TABSTOP,32,198,116,20
- EDITTEXT IDC_FLOPPYSPDTEXT,169,201,107,12,ES_CENTER | ES_READONLY
+ TBS_TOP | WS_TABSTOP,32,193,116,20
+ EDITTEXT IDC_FLOPPYSPDTEXT,169,196,107,12,ES_CENTER | ES_READONLY
+ PUSHBUTTON "Delete Saveimage",IDC_SAVEIMAGE0,43,5,70,15,NOT
+ WS_VISIBLE
+ PUSHBUTTON "Delete Saveimage",IDC_SAVEIMAGE1,43,40,70,15,NOT
+ WS_VISIBLE
+ PUSHBUTTON "Delete Saveimage",IDC_SAVEIMAGE2,43,75,70,15,NOT
+ WS_VISIBLE
+ PUSHBUTTON "Delete Saveimage",IDC_SAVEIMAGE3,43,110,70,15,NOT
+ WS_VISIBLE
END
IDD_HARDDISK DIALOGEX 0, 0, 300, 242
BEGIN
CONTROL "List1",IDC_VOLUMELIST,"SysListView32",LVS_REPORT |
LVS_SINGLESEL | LVS_SHOWSELALWAYS | LVS_ALIGNLEFT |
- LVS_NOSORTHEADER | WS_BORDER | WS_TABSTOP,5,5,260,191
+ LVS_NOSORTHEADER | WS_BORDER | WS_TABSTOP,5,5,260,185
PUSHBUTTON "",IDC_UP,270,52,25,15,BS_ICON
PUSHBUTTON "",IDC_DOWN,270,132,25,15,BS_ICON
- PUSHBUTTON "Add &Directory...",IDC_NEW_FS,5,202,60,15
- PUSHBUTTON "Add &Hardfile...",IDC_NEW_HF,70,202,60,15
- PUSHBUTTON "Add Ha&rddrive",IDC_NEW_HD,135,202,60,15
+ PUSHBUTTON "Add &Directory...",IDC_NEW_FS,5,196,60,15
+ PUSHBUTTON "Add &Hardfile...",IDC_NEW_HF,70,196,60,15
+ PUSHBUTTON "Add Ha&rddrive...",IDC_NEW_HD,135,196,60,15
CONTROL "Add PC Drives at Startup",IDC_MAPDRIVES,"Button",
- BS_AUTOCHECKBOX | WS_TABSTOP,5,222,105,10,0,
+ BS_AUTOCHECKBOX | WS_TABSTOP,5,216,105,10,0,
HIDC_MAPDRIVES
- PUSHBUTTON "Remove",IDC_REMOVE,135,220,60,15
- PUSHBUTTON "&Properties",IDC_EDIT,200,220,60,15
+ PUSHBUTTON "Remove",IDC_REMOVE,135,218,60,15
+ PUSHBUTTON "&Properties",IDC_EDIT,200,218,60,15
+ CONTROL "Disable UAEFSDB-support",IDC_NOUAEFSDB,"Button",
+ BS_AUTOCHECKBOX | WS_TABSTOP,5,229,115,10
END
-IDD_SOUND DIALOGEX 0, 0, 300, 208
+IDD_SOUND DIALOGEX 0, 0, 300, 243
STYLE DS_SETFONT | DS_3DLOOK | DS_CONTROL | WS_CHILD
FONT 8, "MS Sans Serif", 0, 0, 0x1
BEGIN
SS_CENTERIMAGE
COMBOBOX IDC_SOUNDINTERPOLATION,220,74,67,75,CBS_DROPDOWNLIST |
WS_VSCROLL | WS_TABSTOP
- GROUPBOX "Disk Drive Sound Emulation",IDC_STATIC,8,102,285,29
- COMBOBOX IDC_SOUNDDRIVE,15,113,32,75,CBS_DROPDOWNLIST |
+ GROUPBOX "Disk Drive Sound Emulation",IDC_STATIC,8,100,285,46
+ COMBOBOX IDC_SOUNDDRIVE,237,111,46,75,CBS_DROPDOWNLIST |
WS_VSCROLL | WS_TABSTOP
- COMBOBOX IDC_SOUNDDRIVESELECT,55,113,120,75,CBS_DROPDOWNLIST |
+ COMBOBOX IDC_SOUNDDRIVESELECT,18,129,265,75,CBS_DROPDOWNLIST |
WS_VSCROLL | WS_TABSTOP
CONTROL "",IDC_SOUNDDRIVEVOLUME,"msctls_trackbar32",
- TBS_AUTOTICKS | TBS_TOP | WS_TABSTOP,183,109,107,19
- GROUPBOX "Sound buffer size",IDC_STATIC,7,136,161,31
+ TBS_AUTOTICKS | TBS_TOP | WS_TABSTOP,14,108,107,19
+ GROUPBOX "Sound buffer size",IDC_STATIC,8,176,164,31
CONTROL "Slider1",IDC_SOUNDBUFFERRAM,"msctls_trackbar32",
- TBS_AUTOTICKS | TBS_TOP | WS_TABSTOP,14,144,106,19
- GROUPBOX "Sound driver lag compensation",IDC_STATIC,7,170,286,30
+ TBS_AUTOTICKS | TBS_TOP | WS_TABSTOP,14,184,106,19
+ GROUPBOX "Sound driver lag compensation",IDC_STATIC,7,208,286,30
CONTROL "Slider1",IDC_SOUNDADJUST,"msctls_trackbar32",
- TBS_AUTOTICKS | TBS_TOP | WS_TABSTOP,14,178,107,19
- PUSHBUTTON "Calibrate",IDC_SOUNDCALIBRATE,181,179,40,14
- GROUPBOX "Volume",IDC_STATIC,181,136,112,29
+ TBS_AUTOTICKS | TBS_TOP | WS_TABSTOP,14,216,107,19
+ PUSHBUTTON "Calibrate",IDC_SOUNDCALIBRATE,183,218,40,14
+ GROUPBOX "Volume",IDC_STATIC,8,147,164,29
CONTROL "",IDC_SOUNDVOLUME,"msctls_trackbar32",TBS_AUTOTICKS |
- TBS_TOP | WS_TABSTOP,183,144,107,19
- EDITTEXT IDC_SOUNDBUFFERMEM,123,146,37,12,ES_CENTER | ES_READONLY
- EDITTEXT IDC_SOUNDADJUSTNUM,123,180,37,12,ES_CENTER | ES_READONLY
+ TBS_TOP | WS_TABSTOP,14,154,105,19
+ EDITTEXT IDC_SOUNDBUFFERMEM,124,187,40,12,ES_CENTER | ES_READONLY
+ EDITTEXT IDC_SOUNDADJUSTNUM,124,219,40,12,ES_CENTER | ES_READONLY
+ EDITTEXT IDC_SOUNDVOLUME2,124,157,40,12,ES_CENTER | ES_READONLY
+ EDITTEXT IDC_SOUNDDRIVEVOLUME2,124,111,40,12,ES_CENTER |
+ ES_READONLY
END
IDD_LOADSAVE DIALOGEX 0, 0, 302, 241
RTEXT "In:",IDC_MIDI2,150,64,29,15,SS_CENTERIMAGE
COMBOBOX IDC_MIDIINLIST,185,64,95,134,CBS_DROPDOWNLIST |
WS_VSCROLL | WS_TABSTOP
- GROUPBOX "Amiga Mouse Port 0",IDC_PORT0,7,92,116,100
+ GROUPBOX "Amiga Mouse Port 0",IDC_PORT0,7,92,116,106
CONTROL "PC Joystick 0",IDC_PORT0_JOY0,"Button",
- BS_AUTORADIOBUTTON | WS_GROUP | WS_TABSTOP,20,102,90,10
+ BS_AUTORADIOBUTTON | WS_GROUP | WS_TABSTOP,20,104,90,10
CONTROL "PC Joystick 1",IDC_PORT0_JOY1,"Button",
- BS_AUTORADIOBUTTON | WS_TABSTOP,20,116,90,10
+ BS_AUTORADIOBUTTON | WS_TABSTOP,20,118,90,10
CONTROL "PC Mouse",IDC_PORT0_MOUSE,"Button",BS_AUTORADIOBUTTON |
- WS_TABSTOP,20,131,90,11
- CONTROL "Keyboard Layout ""A""",IDC_PORT0_KBDA,"Button",
- BS_AUTORADIOBUTTON | WS_TABSTOP,20,147,90,10
- CONTROL "Keyboard Layout ""B""",IDC_PORT0_KBDB,"Button",
- BS_AUTORADIOBUTTON | WS_TABSTOP,20,162,90,10
- CONTROL "Keyboard Layout ""C""",IDC_PORT0_KBDC,"Button",
- BS_AUTORADIOBUTTON | WS_TABSTOP,20,177,90,10
- GROUPBOX "Amiga Mouse Port 1",IDC_PORT1,175,92,115,100
+ WS_TABSTOP,20,133,90,11
+ CONTROL "Keyboard Layout ""A"" []Numeric keypad, 0 and 5 = fire",
+ IDC_PORT0_KBDA,"Button",BS_AUTORADIOBUTTON | WS_TABSTOP,
+ 20,149,90,10
+ CONTROL "Keyboard Layout ""B"" []Cursor keys, right CTRL = fire",
+ IDC_PORT0_KBDB,"Button",BS_AUTORADIOBUTTON | WS_TABSTOP,
+ 20,164,90,10
+ CONTROL "Keyboard Layout ""C"" []T = up, B = down, F = left, H = right, left ALT = fire",
+ IDC_PORT0_KBDC,"Button",BS_AUTORADIOBUTTON | WS_TABSTOP,
+ 20,179,90,10
+ GROUPBOX "Amiga Mouse Port 1",IDC_PORT1,175,92,115,105
CONTROL "PC Joystick 0",IDC_PORT1_JOY0,"Button",
- BS_AUTORADIOBUTTON | WS_GROUP | WS_TABSTOP,190,102,90,10
+ BS_AUTORADIOBUTTON | WS_GROUP | WS_TABSTOP,190,104,90,10
CONTROL "PC Joystick 1",IDC_PORT1_JOY1,"Button",
- BS_AUTORADIOBUTTON | WS_TABSTOP,190,116,90,10
+ BS_AUTORADIOBUTTON | WS_TABSTOP,190,118,90,10
CONTROL "PC Mouse",IDC_PORT1_MOUSE,"Button",BS_AUTORADIOBUTTON |
- WS_TABSTOP,190,131,90,11
- CONTROL "Keyboard Layout ""A""",IDC_PORT1_KBDA,"Button",
- BS_AUTORADIOBUTTON | WS_TABSTOP,190,147,90,10
- CONTROL "Keyboard Layout ""B""",IDC_PORT1_KBDB,"Button",
- BS_AUTORADIOBUTTON | WS_TABSTOP,190,162,90,10
- CONTROL "Keyboard Layout ""C""",IDC_PORT1_KBDC,"Button",
- BS_AUTORADIOBUTTON | WS_TABSTOP,190,177,90,10
+ WS_TABSTOP,190,133,90,11
+ CONTROL "Keyboard Layout ""A"" []Numeric keypad, 0 and 5 = fire",
+ IDC_PORT1_KBDA,"Button",BS_AUTORADIOBUTTON | WS_TABSTOP,
+ 190,149,90,10
+ CONTROL "Keyboard Layout ""B"" []Cursor keys, right CTRL = fire",
+ IDC_PORT1_KBDB,"Button",BS_AUTORADIOBUTTON | WS_TABSTOP,
+ 190,164,90,10
+ CONTROL "Keyboard Layout ""C"" []T = up, B = down, F = left, H = right, left ALT = fire",
+ IDC_PORT1_KBDC,"Button",BS_AUTORADIOBUTTON | WS_TABSTOP,
+ 190,179,90,10
PUSHBUTTON "<-swap->",IDC_SWAP,130,132,40,14
PUSHBUTTON "Flush print job",IDC_FLUSHPRINTER,199,31,58,12
END
BEGIN
GROUPBOX "Advanced:",IDC_STATIC,8,4,285,90
CONTROL "Middle-Mouse-Button --> ALT-TAB",IDC_JULIAN,"Button",
- BS_AUTOCHECKBOX | WS_TABSTOP,29,15,120,10
+ BS_AUTOCHECKBOX | WS_TABSTOP,29,21,120,10
CONTROL "Show GUI on startup",IDC_SHOWGUI,"Button",
- BS_AUTOCHECKBOX | WS_TABSTOP,29,30,120,10
+ BS_AUTOCHECKBOX | WS_TABSTOP,29,36,120,10
CONTROL "On-Screen LEDs",IDC_SHOWLEDS,"Button",BS_AUTOCHECKBOX |
- WS_TABSTOP,29,45,115,10
+ WS_TABSTOP,29,51,115,10
CONTROL "UAEscsi.device",IDC_SCSIDEVICE,"Button",BS_AUTOCHECKBOX |
- WS_TABSTOP,29,60,117,10
- CONTROL "Disable UAEFSDB-support",IDC_NOUAEFSDB,"Button",
- BS_AUTOCHECKBOX | WS_TABSTOP,29,76,115,10
+ WS_TABSTOP,29,66,117,10
CONTROL "BSDsocket.library emulation",IDC_SOCKETS,"Button",
- BS_AUTOCHECKBOX | WS_TABSTOP,159,15,120,10
+ BS_AUTOCHECKBOX | WS_TABSTOP,159,21,120,10
CONTROL "Use CTRL-F11 to quit",IDC_CTRLF11,"Button",
- BS_AUTOCHECKBOX | WS_TABSTOP,159,30,120,10
+ BS_AUTOCHECKBOX | WS_TABSTOP,159,36,120,10
CONTROL "Don't use RGB overlays",IDC_NOOVERLAY,"Button",
- BS_AUTOCHECKBOX | WS_TABSTOP,159,45,120,10
+ BS_AUTOCHECKBOX | WS_TABSTOP,159,51,120,10
CONTROL "Use ASPI SCSI layer",IDC_ASPI,"Button",BS_AUTOCHECKBOX |
- WS_TABSTOP,159,60,115,10
+ WS_TABSTOP,159,66,115,10
GROUPBOX "Keyboard LEDs:",IDC_STATIC,7,99,85,73
COMBOBOX IDC_KBLED1,22,112,56,65,CBS_DROPDOWNLIST | WS_VSCROLL |
WS_TABSTOP
WS_VSCROLL | WS_TABSTOP
END
-IDD_HARDFILE DIALOGEX 0, 0, 229, 164
+IDD_HARDFILE DIALOGEX 0, 0, 299, 180
STYLE DS_SETFONT | DS_MODALFRAME | DS_SETFOREGROUND | DS_3DLOOK | DS_CENTER |
DS_CENTERMOUSE | WS_POPUP | WS_VISIBLE | WS_CAPTION | WS_SYSMENU
-CAPTION "Volume Settings"
+CAPTION "Hardfile Settings"
FONT 8, "MS Sans Serif", 0, 0, 0x0
BEGIN
- GROUPBOX "Hard File Settings",IDC_STATIC,10,5,210,90
+ GROUPBOX "Hard File Settings",IDC_STATIC,10,5,280,113
RTEXT "Path:",IDC_HARDFILE_DIR_TEXT,19,21,22,10
- EDITTEXT IDC_PATH_NAME,44,15,151,15,ES_AUTOHSCROLL
- PUSHBUTTON "...",IDC_SELECTOR,200,15,11,15
+ EDITTEXT IDC_PATH_NAME,44,15,222,15,ES_AUTOHSCROLL
+ PUSHBUTTON "...",IDC_SELECTOR,271,15,11,15
RTEXT "FileSys:",IDC_HARDFILE_FILESYS_TEXT,16,36,26,10
- EDITTEXT IDC_PATH_FILESYS,44,34,89,15,ES_AUTOHSCROLL
- PUSHBUTTON "...",IDC_FILESYS_SELECTOR,139,34,11,15
+ EDITTEXT IDC_PATH_FILESYS,44,34,221,15,ES_AUTOHSCROLL
+ PUSHBUTTON "...",IDC_FILESYS_SELECTOR,271,34,11,15
CONTROL "Read/Write",IDC_RW,"Button",BS_AUTOCHECKBOX |
- WS_TABSTOP,160,37,50,10
+ WS_TABSTOP,110,57,50,10
RTEXT "Device:",IDC_HARDFILE_DEVICE_TEXT,16,58,25,10
- EDITTEXT IDC_HARDFILE_DEVICE,44,54,32,15,ES_AUTOHSCROLL
- RTEXT "Surfaces:",IDC_SURFACES_TEXT,75,58,35,10
- EDITTEXT IDC_HEADS,115,54,27,15,ES_NUMBER
- RTEXT "Reserved:",IDC_RESERVED_TEXT,145,58,35,10
- EDITTEXT IDC_RESERVED,185,54,27,15,ES_NUMBER
+ EDITTEXT IDC_HARDFILE_DEVICE,44,54,40,15,ES_AUTOHSCROLL
+ RTEXT "Surfaces:",IDC_SURFACES_TEXT,112,79,30,10
+ EDITTEXT IDC_HEADS,147,75,35,15,ES_NUMBER
+ RTEXT "Reserved:",IDC_RESERVED_TEXT,197,79,35,10
+ EDITTEXT IDC_RESERVED,237,75,35,15,ES_NUMBER
RTEXT "BootPri:",IDC_HARDFILE_BOOTPRI_TEXT,11,80,30,8
- EDITTEXT IDC_HARDFILE_BOOTPRI,44,75,32,15
- RTEXT "Sectors:",IDC_SECTORS_TEXT,80,80,30,10
- EDITTEXT IDC_SECTORS,115,75,27,15,ES_NUMBER
- RTEXT "Block-Size:",IDC_BLOCKSIZE_TEXT,145,80,35,10
- EDITTEXT IDC_BLOCKSIZE,185,75,27,15,ES_NUMBER
- GROUPBOX "New Hard File",IDC_STATIC,10,100,210,35
- PUSHBUTTON "Create",IDC_CREATEHF,20,115,85,14
- EDITTEXT IDC_HFSIZE,110,115,60,15,ES_NUMBER
- LTEXT "MB",IDC_RESERVED_TEXT2,174,118,39,9,NOT WS_GROUP
- PUSHBUTTON "OK",IDOK,115,143,50,14
- PUSHBUTTON "Cancel",IDCANCEL,171,143,50,14
+ EDITTEXT IDC_HARDFILE_BOOTPRI,44,75,40,15
+ RTEXT "Sectors:",IDC_SECTORS_TEXT,112,101,30,10
+ EDITTEXT IDC_SECTORS,147,96,35,15,ES_NUMBER
+ RTEXT "Block-Size:",IDC_BLOCKSIZE_TEXT,197,101,35,10
+ EDITTEXT IDC_BLOCKSIZE,237,96,35,15,ES_NUMBER
+ GROUPBOX "New Hard File",IDC_STATIC,10,120,280,35
+ PUSHBUTTON "Enable RDB-mode",IDC_HDF_RDB,192,55,92,14
+ EDITTEXT IDC_HFSIZE,141,135,61,15,ES_NUMBER
+ LTEXT "MB",IDC_RESERVED_TEXT2,214,138,39,9,NOT WS_GROUP
+ PUSHBUTTON "OK",IDOK,102,161,50,14
+ PUSHBUTTON "Cancel",IDCANCEL,158,161,50,14
+ PUSHBUTTON "Create",IDC_CREATEHF,40,135,85,14
END
-IDD_FILESYS DIALOGEX 15, 25, 229, 111
+IDD_FILESYS DIALOGEX 15, 25, 299, 111
STYLE DS_SETFONT | DS_MODALFRAME | DS_SETFOREGROUND | DS_3DLOOK | DS_CENTER |
DS_CENTERMOUSE | WS_POPUP | WS_VISIBLE | WS_CAPTION | WS_SYSMENU
CAPTION "Volume Settings"
FONT 8, "MS Sans Serif", 0, 0, 0x0
BEGIN
LTEXT "Device Name:",-1,5,9,54,10
- EDITTEXT IDC_VOLUME_DEVICE,65,5,85,15,ES_AUTOHSCROLL
+ EDITTEXT IDC_VOLUME_DEVICE,65,5,86,15,ES_AUTOHSCROLL
LTEXT "Volume Label:",-1,5,31,54,10
EDITTEXT IDC_VOLUME_NAME,65,25,85,15,ES_AUTOHSCROLL
LTEXT "Path:",-1,5,51,44,10
- EDITTEXT IDC_PATH_NAME,65,46,139,15,ES_AUTOHSCROLL
- PUSHBUTTON "...",IDC_SELECTOR,210,46,10,15
+ EDITTEXT IDC_PATH_NAME,65,46,213,15,ES_AUTOHSCROLL
+ PUSHBUTTON "...",IDC_SELECTOR,283,46,10,15
CONTROL "Read/Write",IDC_RW,"Button",BS_AUTOCHECKBOX |
WS_TABSTOP,5,70,50,10
RTEXT "BootPri:",IDC_VOLUME_BOOTPRI_TEXT,68,70,30,8
FONT 8, "MS Sans Serif", 0, 0, 0x0
BEGIN
GROUPBOX "Chipset type",IDC_STATIC,14,11,145,82
- CONTROL "OCS",IDC_OCS,"Button",BS_AUTORADIOBUTTON | WS_GROUP |
- WS_TABSTOP,38,31,30,10
- CONTROL "ECS Agnus",IDC_ECS_AGNUS,"Button",BS_AUTORADIOBUTTON |
- WS_TABSTOP,38,47,50,10
- CONTROL "ECS Denise",IDC_ECS_DENISE,"Button",BS_AUTORADIOBUTTON |
- WS_TABSTOP,38,63,50,10
- CONTROL "Full ECS",IDC_ECS,"Button",BS_AUTORADIOBUTTON |
- WS_TABSTOP,102,31,42,10
- CONTROL "AGA",IDC_AGA,"Button",BS_AUTORADIOBUTTON | WS_TABSTOP,
- 102,47,30,10
- CONTROL "NTSC",IDC_NTSC,"Button",BS_AUTOCHECKBOX | WS_TABSTOP,
- 102,64,35,10
+ CONTROL "OCS [] The original Amiga chipset (A1000, most A500s)",
+ IDC_OCS,"Button",BS_AUTORADIOBUTTON | WS_GROUP |
+ WS_TABSTOP,38,31,51,10
+ CONTROL "ECS Agnus [] Partial Enhanced Chipset. Later A500 and A2000 hardware revisions.",
+ IDC_ECS_AGNUS,"Button",BS_AUTORADIOBUTTON | WS_TABSTOP,
+ 38,47,55,10
+ CONTROL "Full ECS [] Full ECS Chipset, ECS Agnus and ECS Denise. (A500+/A600, A3000)",
+ IDC_ECS,"Button",BS_AUTORADIOBUTTON | WS_TABSTOP,38,63,
+ 52,10
+ CONTROL "AGA [] The next generation Amiga chipset (A1200, A4000 and CD32)",
+ IDC_AGA,"Button",BS_AUTORADIOBUTTON | WS_TABSTOP,101,31,
+ 51,10
+ CONTROL "NTSC [] North American and Japanese display standard, 60Hz refresh rate. (PAL is 50Hz)",
+ IDC_NTSC,"Button",BS_AUTOCHECKBOX | WS_TABSTOP,102,63,50,
+ 10
GROUPBOX "Misc chipset options",IDC_STATIC,168,11,114,82
- CONTROL "Fast Copper",IDC_FASTCOPPER,"Button",BS_AUTOCHECKBOX |
- WS_TABSTOP,174,31,53,10
- CONTROL "Immediate Blitter",IDC_BLITIMM,"Button",BS_AUTOCHECKBOX |
- WS_TABSTOP,174,47,75,10
- CONTROL "Cycle exact CPU and Blitter",IDC_CYCLEEXACT,"Button",
- BS_AUTOCHECKBOX | BS_LEFT | WS_GROUP | WS_TABSTOP,174,64,
- 100,10
+ CONTROL "Fast Copper [] Faster but less compatible copper emulation.",
+ IDC_FASTCOPPER,"Button",BS_AUTOCHECKBOX | WS_TABSTOP,174,
+ 31,98,10
+ CONTROL "Immediate Blitter [] Faster but less compatible blitter emulation.",
+ IDC_BLITIMM,"Button",BS_AUTOCHECKBOX | WS_TABSTOP,174,47,
+ 96,10
+ CONTROL "Cycle exact CPU and Blitter [] The most compatible A500 emulation mode. Very fast CPU recommended.",
+ IDC_CYCLEEXACT,"Button",BS_AUTOCHECKBOX | BS_LEFT |
+ WS_GROUP | WS_TABSTOP,174,64,100,10
GROUPBOX "Collision level",IDC_STATIC,14,97,267,48
- CONTROL "None",IDC_COLLISION0,"Button",BS_AUTORADIOBUTTON |
- WS_GROUP | WS_TABSTOP,40,113,50,10
- CONTROL "Sprites only",IDC_COLLISION1,"Button",
- BS_AUTORADIOBUTTON | WS_TABSTOP,39,129,50,10
- CONTROL "Sprites and Sprites vs. Playfield",IDC_COLLISION2,
- "Button",BS_AUTORADIOBUTTON | WS_TABSTOP,104,113,114,10
- CONTROL "Full",IDC_COLLISION3,"Button",BS_AUTORADIOBUTTON |
- WS_TABSTOP,104,129,27,10
+ CONTROL "None [] Collision hardware emulation disabled.",
+ IDC_COLLISION0,"Button",BS_AUTORADIOBUTTON | WS_GROUP |
+ WS_TABSTOP,40,113,50,10
+ CONTROL "Sprites only [] Emulate only sprite vs sprite collisions.",
+ IDC_COLLISION1,"Button",BS_AUTORADIOBUTTON | WS_TABSTOP,
+ 39,129,50,10
+ CONTROL "Sprites and Sprites vs. Playfield [] Recommended collision emulation level.",
+ IDC_COLLISION2,"Button",BS_AUTORADIOBUTTON | WS_TABSTOP,
+ 104,113,161,10
+ CONTROL "Full [] 100% collision hardware emulation. Only very few games need this option. Slowest.",
+ IDC_COLLISION3,"Button",BS_AUTORADIOBUTTON | WS_TABSTOP,
+ 104,129,82,10
GROUPBOX "Sound emulation",IDC_STATIC,13,151,268,65
CONTROL "Disabled",IDC_CS_SOUND0,"Button",BS_AUTORADIOBUTTON |
WS_GROUP | WS_TABSTOP,39,167,102,10
PUSHBUTTON "Swap 1<>2",IDC_INPUTSWAP,249,226,45,14
END
-IDD_FILTER DIALOGEX 0, 0, 300, 226
+IDD_FILTER DIALOGEX 0, 0, 296, 216
STYLE DS_SETFONT | DS_3DLOOK | DS_CONTROL | WS_CHILD
FONT 8, "MS Sans Serif", 0, 0, 0x1
BEGIN
- GROUPBOX "Filter settings:",-1,0,0,291,174
+ GROUPBOX "Filter settings:",-1,0,0,294,174
CONTROL "Enable",IDC_FILTERENABLE,"Button",BS_AUTOCHECKBOX |
WS_TABSTOP,26,17,38,10
COMBOBOX IDC_FILTERMODE,67,15,56,150,CBS_DROPDOWNLIST |
EDITTEXT IDC_FILTERHOV,248,79,34,12,ES_CENTER | ES_READONLY
EDITTEXT IDC_FILTERVZV,248,59,34,12,ES_CENTER | ES_READONLY
EDITTEXT IDC_FILTERHZV,248,40,34,12,ES_CENTER | ES_READONLY
- GROUPBOX "Presets",-1,0,176,292,36
+ GROUPBOX "Presets",-1,0,176,296,36
COMBOBOX IDC_FILTERPRESETS,8,190,119,150,CBS_DROPDOWN | CBS_SORT |
CBS_HASSTRINGS | WS_VSCROLL | WS_TABSTOP
PUSHBUTTON "Load",IDC_FILTERPRESETLOAD,132,189,47,14
PUSHBUTTON "Delete",IDC_FILTERPRESETDELETE,236,189,47,14
END
-IDD_HARDDRIVE DIALOGEX 0, 0, 229, 66
+IDD_HARDDRIVE DIALOGEX 0, 0, 300, 66
STYLE DS_SETFONT | DS_MODALFRAME | DS_SETFOREGROUND | DS_3DLOOK | DS_CENTER |
DS_CENTERMOUSE | WS_POPUP | WS_VISIBLE | WS_CAPTION | WS_SYSMENU
CAPTION "Harddrive Settings"
FONT 8, "MS Sans Serif", 0, 0, 0x0
BEGIN
LTEXT "Harddrive:",-1,7,11,35,10
- COMBOBOX IDC_HARDDRIVE,49,9,173,150,CBS_DROPDOWNLIST |
+ COMBOBOX IDC_HARDDRIVE,49,9,246,150,CBS_DROPDOWNLIST |
CBS_HASSTRINGS | WS_VSCROLL | WS_TABSTOP
CONTROL "Read/Write",IDC_RW,"Button",BS_AUTOCHECKBOX |
WS_TABSTOP,15,30,50,10
- DEFPUSHBUTTON "OK",IDOK,116,47,50,14
- PUSHBUTTON "Cancel",IDCANCEL,172,47,50,14
+ DEFPUSHBUTTON "OK",IDOK,115,30,50,14
+ PUSHBUTTON "Cancel",IDCANCEL,189,30,50,14
END
IDD_MISC2 DIALOGEX 0, 0, 300, 92
PUSHBUTTON "...",IDC_PATHS_AVIOUTPUTS,282,144,11,15
END
-IDD_QUICKSTART DIALOGEX 0, 0, 300, 234
+IDD_QUICKSTART DIALOGEX 0, 0, 300, 242
STYLE DS_SETFONT | DS_3DLOOK | DS_CONTROL | WS_CHILD
FONT 8, "MS Sans Serif", 0, 0, 0x1
BEGIN
- GROUPBOX "Hardware configuration",IDC_QUICKSTART_CONFIG,5,0,294,
+ GROUPBOX "Hardware configuration",IDC_QUICKSTART_CONFIG,3,0,294,
54
- RTEXT "Model:",IDC_STATIC,7,14,56,10,SS_CENTERIMAGE
- COMBOBOX IDC_QUICKSTART_MODEL,67,12,225,50,CBS_DROPDOWNLIST |
+ RTEXT "Model:",IDC_STATIC,5,14,56,10,SS_CENTERIMAGE
+ COMBOBOX IDC_QUICKSTART_MODEL,65,12,225,50,CBS_DROPDOWNLIST |
WS_VSCROLL | WS_TABSTOP
- RTEXT "Configuration:",IDC_STATIC,7,33,56,10,SS_CENTERIMAGE
- COMBOBOX IDC_QUICKSTART_CONFIGURATION,67,31,225,50,
- CBS_DROPDOWNLIST | WS_VSCROLL | WS_TABSTOP
- GROUPBOX "Compatibility Settings",IDC_QUICKSTART_COMPA,5,56,294,
- 33
- RTEXT "Compatibility:",IDC_STATIC,8,70,55,10,SS_CENTERIMAGE
- COMBOBOX IDC_QUICKSTART_COMPATIBILITY,67,68,225,50,
+ RTEXT "Configuration:",IDC_STATIC,5,33,56,10,SS_CENTERIMAGE
+ COMBOBOX IDC_QUICKSTART_CONFIGURATION,65,31,225,50,
CBS_DROPDOWNLIST | WS_VSCROLL | WS_TABSTOP
- GROUPBOX "Disk Drive",IDC_QUICKSTART_DF,5,126,294,87
- LTEXT "Disk Drive DF0:",IDC_STATIC,12,141,56,10,SS_CENTERIMAGE
- PUSHBUTTON "Select Disk Image",IDC_DF0QQ,79,138,98,15
- RTEXT "Write Protected",IDC_STATIC,182,142,58,10,
+ RTEXT "Best compatibility",IDC_STATIC,13,70,67,10,
+ SS_CENTERIMAGE
+ GROUPBOX "Disk Drives",IDC_QUICKSTART_DF,3,126,294,84
+ LTEXT "Disk Drive DF0:",IDC_STATIC,10,138,56,10,SS_CENTERIMAGE
+ PUSHBUTTON "Select Disk Image",IDC_DF0QQ,77,135,98,15
+ RTEXT "Write Protected",IDC_STATIC,180,139,58,10,
SS_CENTERIMAGE
CONTROL "",IDC_DF0WPQ,"Button",BS_AUTOCHECKBOX | BS_MULTILINE |
- WS_TABSTOP,247,140,10,15
- PUSHBUTTON "Eject",IDC_EJECT0Q,262,139,30,15
- COMBOBOX IDC_DF0TEXTQ,11,157,282,75,CBS_DROPDOWN |
- CBS_AUTOHSCROLL | WS_VSCROLL | WS_TABSTOP
- COMBOBOX IDC_DF1TEXTQ,11,193,282,75,CBS_DROPDOWN |
- CBS_AUTOHSCROLL | WS_VSCROLL | WS_TABSTOP
+ WS_TABSTOP,245,137,10,15
+ PUSHBUTTON "Eject",IDC_EJECT0Q,260,136,30,15
+ COMBOBOX IDC_DF0TEXTQ,9,154,282,75,CBS_DROPDOWN | CBS_AUTOHSCROLL |
+ WS_VSCROLL | WS_TABSTOP
+ COMBOBOX IDC_DF1TEXTQ,9,190,282,75,CBS_DROPDOWN | CBS_AUTOHSCROLL |
+ WS_VSCROLL | WS_TABSTOP
CONTROL "",IDC_DF1WPQ,"Button",BS_AUTOCHECKBOX | BS_MULTILINE |
- WS_TABSTOP,247,176,10,15
- PUSHBUTTON "Eject",IDC_EJECT1Q,262,175,30,15
+ WS_TABSTOP,245,173,10,15
+ PUSHBUTTON "Eject",IDC_EJECT1Q,260,172,30,15
CONTROL "Start in Quickstart-mode",IDC_QUICKSTARTMODE,"Button",
- BS_AUTOCHECKBOX | BS_LEFT | WS_TABSTOP,202,221,94,10
- COMBOBOX IDC_QUICKSTART_HOSTCONFIG,67,103,225,50,CBS_DROPDOWNLIST |
+ BS_AUTOCHECKBOX | BS_LEFT | WS_TABSTOP,199,222,94,10
+ COMBOBOX IDC_QUICKSTART_HOSTCONFIG,65,103,225,50,CBS_DROPDOWNLIST |
WS_VSCROLL | WS_TABSTOP
- GROUPBOX "Host configuration",IDC_QUICKSTART_HOST,5,91,294,33
- RTEXT "Configuration:",IDC_STATIC,7,105,55,10,SS_CENTERIMAGE
- LTEXT "Disk Drive DF1:",IDC_STATIC,12,179,56,10,SS_CENTERIMAGE
- PUSHBUTTON "Select Disk Image",IDC_DF1QQ,79,175,98,15
- RTEXT "Write Protected",IDC_STATIC,182,178,58,10,
+ GROUPBOX "Host configuration",IDC_QUICKSTART_HOST,3,91,294,33
+ RTEXT "Configuration:",IDC_STATIC,5,105,55,10,SS_CENTERIMAGE
+ LTEXT "Disk Drive DF1:",IDC_STATIC,10,176,56,10,SS_CENTERIMAGE
+ PUSHBUTTON "Select Disk Image",IDC_DF1QQ,77,172,98,15
+ RTEXT "Write Protected",IDC_STATIC,180,175,58,10,
+ SS_CENTERIMAGE
+ CONTROL "",IDC_QUICKSTART_COMPATIBILITY,"msctls_trackbar32",
+ TBS_AUTOTICKS | TBS_TOP | WS_TABSTOP,88,65,115,21
+ RTEXT "Low compatibility",IDC_STATIC,215,70,63,10,
SS_CENTERIMAGE
+ GROUPBOX "Compatibility vs required CPU power ",
+ IDC_QUICKSTART_COMPA,3,56,294,33
END
IDI_DISPLAY ICON "screen.ico"
IDI_ROOT ICON "root.ico"
IDI_MEMORY ICON "chip.ico"
+IDI_QUICKSTART ICON "quickstart.ico"
+IDI_PATHS ICON "paths.ico"
/////////////////////////////////////////////////////////////////////////////
//
#ifdef APSTUDIO_INVOKED
GUIDELINES DESIGNINFO
BEGIN
- IDD_CPU, DIALOG
- BEGIN
- BOTTOMMARGIN, 175
- END
-
IDD_HARDDISK, DIALOG
BEGIN
- BOTTOMMARGIN, 175
- END
-
- IDD_SOUND, DIALOG
- BEGIN
- BOTTOMMARGIN, 206
+ BOTTOMMARGIN, 241
END
IDD_LOADSAVE, DIALOG
BOTTOMMARGIN, 212
END
- IDD_MISC1, DIALOG
+ IDD_FILESYS, DIALOG
BEGIN
- BOTTOMMARGIN, 215
+ RIGHTMARGIN, 229
END
IDD_INPUT, DIALOG
BOTTOMMARGIN, 187
END
- IDD_FILTER, DIALOG
- BEGIN
- RIGHTMARGIN, 292
- END
-
IDD_PANEL, DIALOG
BEGIN
LEFTMARGIN, 7
IDS_BLOCKSIZE "Block Size"
IDS_NAME "Name"
IDS_DESCRIPTION "Description"
- IDS_ONEINSTANCE "Only one instance of WinUAE can run at a time.\n"
IDS_INSTALLDIRECTX "You have to install DirectX on your system before you can use UAE.\nRefer to the documentation for further details.\n"
IDS_REGKEYCREATEFAILED "WinUAE could not create Registry keys! You need administrator privileges.\n"
IDS_COULDNOTLOADCONFIG "Could not load selected configuration!\n"
IDS_TREEVIEW_ABOUT "About"
END
+STRINGTABLE
+BEGIN
+ IDS_NOHARDDRIVES "No Amiga formatted or completely empty harddrives detected."
+END
+
+STRINGTABLE
+BEGIN
+ IDS_NUMSG_NEEDEXT2 "Program uses non-standard disk format. You may need to use ""Custom"" floppy instead of standard adf. This message does not appear again."
+ IDS_NUMSG_NOROMKEY "Could not find ROM key file."
+ IDS_NUMSG_KSROMCRCERROR "Kickstart checksum incorrect. You probably have a corrupted ROM image."
+ IDS_NUMSG_KSROMREADERROR "Error while reading Kickstart."
+END
+
+STRINGTABLE
+BEGIN
+ IDS_NUMSG_NOEXTROM "No extended Kickstart ROM found."
+ IDS_NUMSG_MODRIP_NOTFOUND "No modules or compressed data found."
+ IDS_NUMSG_MODRIP_FINISHED "Scan finished."
+ IDS_NUMSG_MODRIP_SAVE "Module/packer found\n%s\nDo you want to save it?"
+ IDS_NUMSG_KS68020 "Your Kickstart requires a 68020 CPU. This message does not appear again."
+ IDS_NUMSG_ROMNEED "You need any of following ROM(s)\n\n%s"
+ IDS_NUMSG_NOZLIB "Zip and gzip support disabled because zlib1.dll is missing."
+ IDS_NUMSG_STATEHD "WARNING: State saves do not support harddrive emulation. This message does not appear again."
+ IDS_NUMSG_NOCAPS "This disk image needs the C.A.P.S. plugin\nwhich is available from\nhttp//www.caps-project.org/download.shtml"
+ IDS_NUMSG_OLDCAPS "You need updated C.A.P.S. plugin\nwhich is available from\nhttp//www.caps-project.org/download.shtml"
+END
+
#endif // English (U.S.) resources
/////////////////////////////////////////////////////////////////////////////
//write_log ("restore failed %s\n", DXError (hr));
return 1;
}
+ pause_audio_ds ();
resume_audio_ds ();
return 1;
}
static void finish_sound_buffer_ds (void)
{
- DWORD playpos, safepos;
+ DWORD playpos, safepos, status;
HRESULT hr;
void *b1, *b2;
DWORD s1, s2;
int diff;
+ int counter = 1000;
double vdiff, m, skipmode;
+ hr = IDirectSoundBuffer_GetStatus (lpDSBsecondary, &status);
+ if (hr != DS_OK)
+ return;
+ if (status & DSBSTATUS_BUFFERLOST) {
+ restore (DSERR_BUFFERLOST);
+ return;
+ }
+ if ((status & (DSBSTATUS_PLAYING | DSBSTATUS_LOOPING)) != (DSBSTATUS_PLAYING | DSBSTATUS_LOOPING)) {
+ write_log ("sound status = %08.8X\n", status);
+ restore (DSERR_BUFFERLOST);
+ return;
+ }
for (;;) {
hr = IDirectSoundBuffer_GetCurrentPosition (lpDSBsecondary, &playpos, &safepos);
if (hr != DS_OK) {
if (diff > max_sndbufsize * 6 / 8) {
sleep_millis_busy (1);
+ counter--;
+ if (counter < 0) {
+ write_log ("sound system got stuck!?\n");
+ restore (DSERR_BUFFERLOST);
+ return;
+ }
continue;
}
break;
#endif
first++;
write_log ( "%s", VersionStr );
- write_log (" (OS: %s %d.%d%s)", os_winnt ? "NT" : "W9X/ME", osVersion.dwMajorVersion, osVersion.dwMinorVersion, os_winnt_admin ? " Administrator privileges" : "");
+ write_log (" (%s %d.%d %s%s)", os_winnt ? "NT" : "W9X/ME",
+ osVersion.dwMajorVersion, osVersion.dwMinorVersion, osVersion.szCSDVersion,
+ os_winnt_admin ? " Admin" : "");
write_log ("\n(c) 1995-2001 Bernd Schmidt - Core UAE concept and implementation."
"\n(c) 1998-2004 Toni Wilen - Win32 port, core code updates."
"\n(c) 1996-2001 Brian King - Win32 port, Picasso96 RTG, and GUI."
debugfile = 0;
}
-void target_default_options (struct uae_prefs *p)
+void target_default_options (struct uae_prefs *p, int type)
{
- p->win32_middle_mouse = 1;
- p->win32_logfile = 0;
- p->win32_iconified_nosound = 1;
- p->win32_iconified_pause = 1;
- p->win32_inactive_nosound = 0;
- p->win32_inactive_pause = 0;
- p->win32_no_overlay = 0;
- p->win32_ctrl_F11_is_quit = 0;
- p->win32_soundcard = 0;
- p->win32_active_priority = 0;
- p->win32_inactive_priority = 2;
- p->win32_iconified_priority = 3;
- p->win32_midioutdev = -2;
- p->win32_midiindev = 0;
+ if (type == 2 || type == 0) {
+ p->win32_middle_mouse = 1;
+ p->win32_logfile = 0;
+ p->win32_iconified_nosound = 1;
+ p->win32_iconified_pause = 1;
+ p->win32_inactive_nosound = 0;
+ p->win32_inactive_pause = 0;
+ p->win32_no_overlay = 0;
+ p->win32_ctrl_F11_is_quit = 0;
+ p->win32_soundcard = 0;
+ p->win32_active_priority = 0;
+ p->win32_inactive_priority = 2;
+ p->win32_iconified_priority = 3;
+ }
+ if (type == 1 || type == 0) {
+ p->win32_midioutdev = -2;
+ p->win32_midiindev = 0;
+ }
}
void target_save_options (FILE *f, struct uae_prefs *p)
fetch_path ("SaveimagePath", out, size);
}
}
+
void fetch_path (char *name, char *out, int size)
{
+ int size2 = size;
strcpy (out, start_path);
if (!strcmp (name, "FloppyPath"))
strcat (out, "..\\shared\\adf\\");
if (!strcmp (name, "KickstartPath"))
strcat (out, "..\\shared\\rom\\");
if (hWinUAEKey)
- RegQueryValueEx(hWinUAEKey, name, 0, NULL, out, &size);
+ RegQueryValueEx (hWinUAEKey, name, 0, NULL, out, &size);
+ if (out[0] == '\\') { /* relative? */
+ strcpy (out, start_path);
+ if (hWinUAEKey) {
+ size2 -= strlen (out);
+ RegQueryValueEx (hWinUAEKey, name, 0, NULL, out + strlen (out) - 1, &size2);
+ }
+ }
}
void set_path (char *name, char *path)
{
}
extern int scan_roms (char*);
-void read_rom_list (void)
+void read_rom_list (int force)
{
char tmp2[1000];
DWORD size2;
KEY_ALL_ACCESS, NULL, &fkey, &disp);
if (fkey == NULL)
return;
- if (disp == REG_CREATED_NEW_KEY)
+ if (disp == REG_CREATED_NEW_KEY || force)
scan_roms (NULL);
idx = 0;
for (;;) {
}
}
+static int parseversion (char **vs)
+{
+ char tmp[10];
+ int i;
+
+ i = 0;
+ while (**vs >= '0' && **vs <= '9') {
+ if (i >= sizeof (tmp))
+ return 0;
+ tmp[i++] = **vs;
+ (*vs)++;
+ }
+ if (**vs == '.')
+ (*vs)++;
+ tmp[i] = 0;
+ return atol (tmp);
+}
+
+static int checkversion (char *vs)
+{
+ if (strlen (vs) < 10)
+ return 0;
+ if (memcmp (vs, "WinUAE ", 7))
+ return 0;
+ vs += 7;
+ if (parseversion (&vs) < UAEMAJOR)
+ return 1;
+ if (parseversion (&vs) < UAEMINOR)
+ return 1;
+ if (parseversion (&vs) < UAESUBREV)
+ return 1;
+ return 0;
+}
+
static void WIN32_HandleRegistryStuff( void )
{
RGBFTYPE colortype = RGBFB_NONE;
DWORD dwType = REG_DWORD;
DWORD dwDisplayInfoSize = sizeof( colortype );
- DWORD qssize;
+ DWORD size;
DWORD disposition;
char path[MAX_DPATH] = "";
+ char version[100];
HKEY hWinUAEKeyLocal = NULL;
HKEY fkey;
+ int forceroms = 0;
/* Create/Open the hWinUAEKey which points to our config-info */
if( RegCreateKeyEx( HKEY_CLASSES_ROOT, ".uae", 0, "", REG_OPTION_NON_VOLATILE,
RegSetValueEx( hWinUAEKey, "xPosGUI", 0, REG_DWORD, (CONST BYTE *)&colortype, sizeof( colortype ) );
RegSetValueEx( hWinUAEKey, "yPosGUI", 0, REG_DWORD, (CONST BYTE *)&colortype, sizeof( colortype ) );
}
+ size = sizeof (version);
+ if (RegQueryValueEx( hWinUAEKey, "Version", 0, &dwType, (LPBYTE)&version, &size) == ERROR_SUCCESS) {
+ if (checkversion (version))
+ forceroms = 1;
+ } else {
+ forceroms = 1;
+ }
// Set this even when we're opening an existing key, so that the version info is always up to date.
- RegSetValueEx( hWinUAEKey, "Version", 0, REG_SZ, (CONST BYTE *)VersionStr, strlen( VersionStr ) + 1 );
+ if (RegSetValueEx( hWinUAEKey, "Version", 0, REG_SZ, (CONST BYTE *)VersionStr, strlen( VersionStr ) + 1 ) != ERROR_SUCCESS)
+ forceroms = 0;
RegQueryValueEx( hWinUAEKey, "DisplayInfo", 0, &dwType, (LPBYTE)&colortype, &dwDisplayInfoSize );
if( colortype == 0 ) /* No color information stored in the registry yet */
/* Set the 16-bit pixel format for the appropriate modes */
WIN32GFX_FigurePixelFormats( colortype );
}
- qssize = sizeof (quickstart);
- RegQueryValueEx( hWinUAEKey, "QuickStartMode", 0, &dwType, (LPBYTE)&quickstart, &qssize );
+ size = sizeof (quickstart);
+ RegQueryValueEx( hWinUAEKey, "QuickStartMode", 0, &dwType, (LPBYTE)&quickstart, &size );
}
fetch_path ("ConfigurationPath", path, sizeof (path));
path[strlen (path) - 1] = 0;
fetch_path ("ConfigurationPath", path, sizeof (path));
strcat (path, "Hardware");
CreateDirectory (path, NULL);
+ fetch_path ("StatefilePath", path, sizeof (path));
+ strcat (path, "default.uss");
+ strcpy (savestate_fname, path);
fkey = read_disk_history ();
if (fkey)
RegCloseKey (fkey);
- read_rom_list ();
+ read_rom_list (forceroms);
}
static void betamessage (void)
int os_winnt, os_winnt_admin;
-static int osdetect (void)
+static int isadminpriv (void)
{
- HANDLE hAccessToken;
- UCHAR InfoBuffer[1024];
- PTOKEN_GROUPS ptgGroups = (PTOKEN_GROUPS)InfoBuffer;
- DWORD dwInfoBufferSize;
- PSID psidAdministrators;
- SID_IDENTIFIER_AUTHORITY siaNtAuthority = SECURITY_NT_AUTHORITY;
- UINT x;
- BOOL bSuccess;
+ DWORD i, dwSize = 0, dwResult = 0;
+ HANDLE hToken;
+ PTOKEN_GROUPS pGroupInfo;
+ BYTE sidBuffer[100];
+ PSID pSID = (PSID)&sidBuffer;
+ SID_IDENTIFIER_AUTHORITY SIDAuth = SECURITY_NT_AUTHORITY;
+ int isadmin = 0;
+
+ // Open a handle to the access token for the calling process.
+ if (!OpenProcessToken( GetCurrentProcess(), TOKEN_QUERY, &hToken )) {
+ write_log ( "OpenProcessToken Error %u\n", GetLastError() );
+ return FALSE;
+ }
+
+ // Call GetTokenInformation to get the buffer size.
+ if(!GetTokenInformation(hToken, TokenGroups, NULL, dwSize, &dwSize)) {
+ dwResult = GetLastError();
+ if( dwResult != ERROR_INSUFFICIENT_BUFFER ) {
+ write_log( "GetTokenInformation Error %u\n", dwResult );
+ return FALSE;
+ }
+ }
+
+ // Allocate the buffer.
+ pGroupInfo = (PTOKEN_GROUPS) GlobalAlloc( GPTR, dwSize );
+
+ // Call GetTokenInformation again to get the group information.
+ if(! GetTokenInformation(hToken, TokenGroups, pGroupInfo, dwSize, &dwSize ) ) {
+ write_log ( "GetTokenInformation Error %u\n", GetLastError() );
+ return FALSE;
+ }
+
+ // Create a SID for the BUILTIN\Administrators group.
+ if(! AllocateAndInitializeSid( &SIDAuth, 2,
+ SECURITY_BUILTIN_DOMAIN_RID,
+ DOMAIN_ALIAS_RID_ADMINS,
+ 0, 0, 0, 0, 0, 0,
+ &pSID) ) {
+ write_log( "AllocateAndInitializeSid Error %u\n", GetLastError() );
+ return FALSE;
+ }
+ // Loop through the group SIDs looking for the administrator SID.
+ for(i=0; i<pGroupInfo->GroupCount; i++) {
+ if ( EqualSid(pSID, pGroupInfo->Groups[i].Sid) )
+ isadmin = 1;
+ }
+
+ if (pSID)
+ FreeSid(pSID);
+ if ( pGroupInfo )
+ GlobalFree( pGroupInfo );
+ return isadmin;
+}
+
+static int osdetect (void)
+{
os_winnt = 0;
os_winnt_admin = 0;
if (!os_winnt) {
return 1;
}
-
- if(!OpenThreadToken(GetCurrentThread(), TOKEN_QUERY, TRUE,
- &hAccessToken )) {
- if(GetLastError() != ERROR_NO_TOKEN)
- return 1;
- //
- // retry against process token if no thread token exists
- //
- if(!OpenProcessToken(GetCurrentProcess(), TOKEN_QUERY,
- &hAccessToken))
- return 1;
- }
-
- bSuccess = GetTokenInformation(hAccessToken,TokenGroups,InfoBuffer,
- 1024, &dwInfoBufferSize);
-
- CloseHandle(hAccessToken);
-
- if(!bSuccess )
- return 1;
-
- if(!AllocateAndInitializeSid(&siaNtAuthority, 2,
- SECURITY_BUILTIN_DOMAIN_RID,
- DOMAIN_ALIAS_RID_ADMINS,
- 0, 0, 0, 0, 0, 0,
- &psidAdministrators))
- return 1;
-
- // assume that we don't find the admin SID.
- bSuccess = FALSE;
-
- for(x=0;x<ptgGroups->GroupCount;x++)
- {
- if( EqualSid(psidAdministrators, ptgGroups->Groups[x].Sid) )
- {
- bSuccess = TRUE;
- break;
- }
-
- }
- FreeSid(psidAdministrators);
- os_winnt_admin = bSuccess ? 1 : 0;
- return 1;
- }
-
+ os_winnt_admin = isadminpriv ();
+ return 1;
+}
static int PASCAL WinMain2 (HINSTANCE hInstance, HINSTANCE hPrevInstance, LPSTR lpCmdLine,
int nCmdShow)
int argc;
int i;
int multi_display = 1;
- char tmp[MAX_DPATH];
#ifdef __GNUC__
__asm__ ("leal -2300*1024(%%esp),%0" : "=r" (win32_stackbase) :);
#ifdef AVIOUTPUT
AVIOutput_Initialize();
#endif
+ init_zlib ();
#ifdef __MINGW32__
argc = _argc; argv = _argv;
if((posn = strrchr (start_path, '\\')))
posn[1] = 0;
sprintf (help_file, "%sWinUAE.chm", start_path );
- strcat (tmp, "\\default.uss");
- strcpy (savestate_fname, tmp);
sprintf( VersionStr, "WinUAE %d.%d.%d%s", UAEMAJOR, UAEMINOR, UAESUBREV, WINUAEBETA ? WINUAEBETASTR : "" );
logging_init ();
DirectDraw_Release();
betamessage ();
keyboard_settrans ();
- init_zlib ();
#ifdef PARALLEL_PORT
paraport_mask = paraport_init ();
#endif
write_log ("failed to find and fix the problem (%p). crashing..\n", p);
} else {
m68k_setpc (0);
- exception2 (opc, p);
+ exception2 (opc, (uaecptr)p);
lRet = EXCEPTION_CONTINUE_EXECUTION;
}
}
extern int manual_palette_refresh_needed;
extern int mouseactive, focus;
#define WINUAEBETA 1
-#define WINUAEBETASTR " Beta 3"
+#define WINUAEBETASTR " Beta 6"
extern void my_kbd_handler (int, int, int);
extern void clearallkeys(void);
void exit_gui (int);
void fetch_path (char *name, char *out, int size);
void set_path (char *name, char *path);
-void read_rom_list (void);
+void read_rom_list (int);
#endif
\ No newline at end of file
#include "win32.h"
#include "win32gfx.h"
#include "gfxfilter.h"
+#include "dxwrap.h"
struct uae_filter uaefilters[] =
{
static int dst_width, dst_height, amiga_width, amiga_height, amiga_depth, dst_depth, scale;
uae_u8 *bufmem_ptr;
int bufmem_width, bufmem_height;
+static int tempsurf;
void S2X_configure (int rb, int gb, int bb, int rs, int gs, int bs)
{
bufmem_ptr = 0;
}
+void S2X_free (void)
+{
+ if (tempsurf)
+ IDirectDrawSurface7_Release (DirectDrawState.temporary.surface);
+ tempsurf = 0;
+}
+
void S2X_init (int dw, int dh, int aw, int ah, int mult, int ad, int dd)
{
int flags;
+ HRESULT ddrval;
flags = usedfilter->x[mult];
if (mult) {
amiga_height = ah;
amiga_depth = ad;
scale = mult;
+
+ tempsurf = 1;
+ ZeroMemory (&DirectDrawState.temporary.desc, sizeof (DDSURFACEDESC2));
+ DirectDrawState.temporary.desc.dwSize = sizeof (DDSURFACEDESC2);
+ DirectDrawState.temporary.desc.dwFlags = DDSD_CAPS | DDSD_WIDTH | DDSD_HEIGHT;
+ DirectDrawState.temporary.desc.ddsCaps.dwCaps = DDSCAPS_OFFSCREENPLAIN | DDSCAPS_VIDEOMEMORY;
+ DirectDrawState.temporary.desc.dwWidth = dst_width;
+ DirectDrawState.temporary.desc.dwHeight = dst_height;
+ if (DirectDraw_GetPrimaryPixelFormat (&DirectDrawState.temporary.desc.ddpfPixelFormat))
+ DirectDrawState.temporary.desc.dwFlags |= DDSD_PIXELFORMAT;
+ ddrval = IDirectDraw7_CreateSurface (DirectDrawState.directdraw.dd,
+ &DirectDrawState.temporary.desc,
+ &DirectDrawState.temporary.surface,
+ NULL);
+ if (ddrval != DD_OK) {
+ write_log ("DDRAW: failed to create temp surface\n%s\n", DXError (ddrval));
+ tempsurf = 0;
+ }
}
void S2X_render (void)
{
int aw = amiga_width, ah = amiga_height, v, pitch;
uae_u8 *dptr, *sptr, *endsptr;
- int ok = 0;
+ int ok = 0, temp_needed = 0;
+ RECT sr, dr;
+ HRESULT ddrval;
+ LPDIRECTDRAWSURFACE7 dds;
+ DDSURFACEDESC2 desc;
sptr = gfxvidinfo.bufmem;
endsptr = gfxvidinfo.realbufmem + (amiga_height - 1) * 3 * gfxvidinfo.rowbytes;
if (aw < 16)
return;
+ if (currprefs.gfx_filter_horiz_zoom || currprefs.gfx_filter_vert_zoom) {
+ sr.left = currprefs.gfx_filter_horiz_zoom * 2;
+ sr.top = currprefs.gfx_filter_vert_zoom * 2;
+ sr.right = dst_width - currprefs.gfx_filter_horiz_zoom * 2;
+ sr.bottom = dst_height - currprefs.gfx_filter_vert_zoom * 2;
+ dr.left = dr.top = 0;
+ dr.right = dst_width;
+ dr.bottom = dst_height;
+ if (sr.left >= sr.right) {
+ sr.left = dst_width / 2 - 1;
+ sr.right = dst_width / 2 + 1;
+ }
+ if (sr.left < 0) {
+ dr.left = -sr.left;
+ sr.left = 0;
+ }
+ if (sr.right > dst_width) {
+ dr.right = dst_width - (sr.right - dst_width);
+ sr.right = dst_width;
+ }
+ if (sr.top >= sr.bottom) {
+ sr.top = dst_height / 2 - 1;
+ sr.bottom = dst_height / 2 + 1;
+ }
+ if (sr.top < 0) {
+ dr.top = -sr.top;
+ sr.top = 0;
+ }
+ if (sr.bottom > dst_height) {
+ dr.bottom = dst_height - (sr.bottom - dst_height);
+ sr.bottom = dst_height;
+ }
+
+ if (tempsurf && sr.left != 0 || sr.top != 0 || sr.right != dst_width || sr.bottom != dst_height ||
+ dr.top != 0 || dr.right != dst_width || dr.left != 0 || dr.bottom != dst_height) {
+ dds = DirectDrawState.temporary.surface;
+ temp_needed = 1;
+ }
+ }
+
bufmem_ptr = sptr;
bufmem_width = aw;
bufmem_height = ah;
- if (!DirectDraw_SurfaceLock (lockable_surface))
- return;
-
- dptr = DirectDraw_GetSurfacePointer ();
- pitch = DirectDraw_GetSurfacePitch();
+ if (temp_needed) {
+ desc.dwSize = sizeof (desc);
+ while ((ddrval = IDirectDrawSurface7_Lock (dds, NULL, &desc, DDLOCK_SURFACEMEMORYPTR | DDLOCK_WAIT, NULL)) != DD_OK) {
+ if (ddrval == DDERR_SURFACELOST) {
+ ddrval = IDirectDrawSurface7_Restore (dds);
+ if (ddrval != DD_OK)
+ return;
+ } else if (ddrval != DDERR_SURFACEBUSY) {
+ return;
+ }
+ }
+ dptr = (uae_u8*)desc.lpSurface;
+ pitch = desc.lPitch;
+ } else {
+ DirectDraw_SurfaceLock (lockable_surface);
+ dptr = DirectDraw_GetSurfacePointer ();
+ pitch = DirectDraw_GetSurfacePitch ();
+ }
if (usedfilter->type == UAE_FILTER_SCALE2X ) { /* 16+32/2X */
changed_prefs.gfx_filter = usedfilter->type;
}
- DirectDraw_SurfaceUnlock ();
-
+ if (temp_needed) {
+ IDirectDrawSurface7_Unlock (dds, NULL);
+ DirectDraw_Blt (DirectDraw_GetLockableType(), &dr, temporary_surface, &sr, 0, NULL);
+ } else {
+ DirectDraw_SurfaceUnlock ();
+ }
}
void S2X_refresh (void)
void close_windows (void)
{
+ S2X_free ();
free (gfxvidinfo.realbufmem);
gfxvidinfo.realbufmem = 0;
DirectDraw_Release();
dr.right -= mi.rcMonitor.left;
dr.bottom -= mi.rcMonitor.top;
- w = currentmode->current_width * (currprefs.gfx_filter_horiz_zoom + 100) / 100;
- h = currentmode->current_height * (currprefs.gfx_filter_vert_zoom + 100) / 100;
+ w = currentmode->current_width; // * (currprefs.gfx_filter_horiz_zoom + 100) / 100;
+ h = currentmode->current_height; // * (currprefs.gfx_filter_vert_zoom + 100) / 100;
sr.left = 0;
sr.top = 0;
currentmode->amiga_width, currentmode->amiga_height, currentmode->current_depth);
if (err) {
OGL_free ();
- gui_message (err);
- changed_prefs.gfx_filter = currprefs.gfx_filter = 0;
+ if (err[0] != '*') {
+ gui_message (err);
+ changed_prefs.gfx_filter = currprefs.gfx_filter = 0;
+ }
currentmode->current_depth = currentmode->real_depth;
gfxmode_reset ();
ret = -1;
HARDDISK_ID = -1, PORTS_ID = -1, INPUT_ID = -1, MISC1_ID = -1, MISC2_ID = -1, AVIOUTPUT_ID = -1,
PATHS_ID = -1, QUICKSTART_ID = -1, ABOUT_ID = -1;
static HWND pages[MAX_C_PAGES];
-static HWND guiDlg;
+static HWND guiDlg, ToolTipHWND;
void exit_gui (int ok)
{
SendMessage (guiDlg, WM_COMMAND, ok ? IDOK : IDCANCEL, 0);
}
+static int getcbn (HWND hDlg, int v, char *out, int len)
+{
+ int val = SendDlgItemMessage (hDlg, v, CB_GETCURSEL, 0, 0L);
+ out[0] = 0;
+ if (val == CB_ERR) {
+ SendDlgItemMessage (hDlg, v, WM_GETTEXT, (WPARAM)len, (LPARAM)out);
+ return 1;
+ } else {
+ val = SendDlgItemMessage (hDlg, v, CB_GETLBTEXT, (WPARAM)val, (LPARAM)out);
+ return 0;
+ }
+}
+
static HICON hMoveUp = NULL, hMoveDown = NULL;
static HWND cachedlist = NULL;
static char szNone[ MAX_DPATH ] = "None";
+struct romscandata {
+ uae_u8 *keybuf;
+ int keysize;
+ HKEY fkey;
+ int got;
+};
-static struct romdata *scan_rom (char *path, uae_u8 *keybuf, int keysize)
+static struct romdata *scan_single_rom_2 (struct zfile *f, uae_u8 *keybuf, int keysize)
{
uae_u8 buffer[20] = { 0 };
uae_u8 *rombuf;
int cl = 0, size;
struct romdata *rd = 0;
- struct zfile *f;
-
- f = zfile_fopen (path, "rb");
- if (!f)
- return 0;
zfile_fseek (f, 0, SEEK_END);
size = zfile_ftell (f);
zfile_fseek (f, 0, SEEK_SET);
- if (size > 600000) {
- zfile_fclose (f);
+ if (size > 600000)
return 0;
- }
zfile_fread (buffer, 1, 11, f);
if (!memcmp (buffer, "AMIROMTYPE1", 11)) {
cl = 1;
decode_cloanto_rom_do (rombuf, size, size, keybuf, keysize);
cl = 0;
}
- if (!cl) {
+ if (!cl)
rd = getromdatabydata (rombuf, size);
- }
free (rombuf);
- zfile_fclose (f);
return rd;
}
+static struct romdata *scan_single_rom (char *path, uae_u8 *keybuf, int keysize)
+{
+ struct zfile *z = zfile_fopen (path, "rb");
+ if (!z)
+ return 0;
+ return scan_single_rom_2 (z, keybuf, keysize);
+}
+
+static int scan_rom_2 (struct zfile *f, struct romscandata *rsd)
+{
+ struct romdata *rd = scan_single_rom_2 (f, rsd->keybuf, rsd->keysize);
+ if (rd) {
+ char tmp[MAX_DPATH];
+ char *name = zfile_getname (f);
+ sprintf (tmp, "ROM%02d", rd->id);
+ RegSetValueEx (rsd->fkey, tmp, 0, REG_SZ, (CONST BYTE *)name, strlen (name) + 1);
+ rsd->got = 1;
+ }
+ return 1;
+}
+
+static int scan_rom (char *path, HKEY fkey, uae_u8 *keybuf, int keysize)
+{
+ struct romscandata rsd = { keybuf, keysize, fkey, 0 };
+ zfile_zopen (path, scan_rom_2, &rsd);
+ return rsd.got;
+}
+
static int listrom (int *roms)
{
int i;
int scan_roms (char *pathp)
{
HKEY fkey = NULL;
- char buf[MAX_PATH], path[MAX_PATH], tmp[100];
+ char buf[MAX_PATH], path[MAX_PATH];
WIN32_FIND_DATA find_data;
HANDLE handle;
uae_u8 *keybuf;
if (fkey == NULL)
goto end;
ret = 0;
- handle = FindFirstFile (buf, &find_data);
- if (handle == INVALID_HANDLE_VALUE)
- goto end;
for (;;) {
- char tmppath[MAX_PATH];
- struct romdata *rd;
- strcpy (tmppath, path);
- strcat (tmppath, find_data.cFileName);
- rd = scan_rom (tmppath, keybuf, keysize);
- if (rd) {
- sprintf (tmp, "ROM%02d", rd->id);
- RegSetValueEx(fkey, tmp, 0, REG_SZ, (CONST BYTE *)tmppath, strlen(tmppath) + 1);
- ret = 1;
+ handle = FindFirstFile (buf, &find_data);
+ if (handle == INVALID_HANDLE_VALUE)
+ goto end;
+ for (;;) {
+ char tmppath[MAX_PATH];
+ strcpy (tmppath, path);
+ strcat (tmppath, find_data.cFileName);
+ if (scan_rom (tmppath, fkey, keybuf, keysize))
+ ret = 1;
+ if (FindNextFile (handle, &find_data) == 0) {
+ FindClose (handle);
+ break;
+ }
}
- if (FindNextFile (handle, &find_data) == 0) {
- FindClose (handle);
- break;
+ if (!keybuf && ret) { /* did previous scan detect keyfile? */
+ keybuf = load_keyfile (&workprefs, path, &keysize);
+ if (keybuf) /* ok, maybe we now find more roms.. */
+ continue;
}
+ break;
}
end:
if (fkey)
RegCloseKey (fkey);
free_keyfile (keybuf);
- read_rom_list ();
+ read_rom_list (0);
show_rom_list ();
return ret;
}
cfgfile_save (&workprefs, full_path, 0);
break;
case IDC_ROMFILE:
- strcpy( workprefs.romfile, full_path );
+ strcpy (workprefs.romfile, full_path);
break;
case IDC_ROMFILE2:
- strcpy( workprefs.romextfile, full_path );
+ strcpy (workprefs.romextfile, full_path);
break;
case IDC_FLASHFILE:
- strcpy( workprefs.flashfile, full_path );
+ strcpy (workprefs.flashfile, full_path);
break;
case IDC_CARTFILE:
- strcpy( workprefs.cartfile, full_path );
+ strcpy (workprefs.cartfile, full_path);
break;
}
if (path_out)
strcat (name, ".uae");
SetDlgItemText (hDlg, IDC_EDITNAME, name);
}
+ strcpy (config->Name, name);
}
GetDlgItemText (hDlg, IDC_EDITDESCRIPTION, desc, MAX_DPATH);
if (config) {
break;
case CONFIG_SAVE:
- if (strlen (name) == 0) {
+ if (strlen (name) == 0 || strcmp (name, ".uae") == 0) {
char szMessage[ MAX_DPATH ];
WIN32GUI_LoadUIString( IDS_MUSTENTERNAME, szMessage, MAX_DPATH );
pre_gui_message (szMessage);
entry++;
}
listview_column_width [1] = 260;
- listview_column_width [2] = 50;
- listview_column_width [3] = 20;
+ listview_column_width [2] = 65;
+ listview_column_width [3] = 30;
update_listview_input (hDlg);
}
else if (lv_type == LV_DISK)
TreeView_SelectItem (GetDlgItem(hDlg, IDC_CONFIGTREE), config->item);
else
TreeView_SelectItem (GetDlgItem(hDlg, IDC_CONFIGTREE), root);
-
+ ShowWindow (GetDlgItem(hDlg, IDC_CONFIGAUTO), configtypepanel > 0 ? SW_SHOW : SW_HIDE);
recursive--;
return TRUE;
recursive++;
config = CreateConfigStore (config);
config = fixloadconfig (hDlg, config);
+ ConfigToRegistry (config, configtypepanel);
InitializeConfigTreeView (hDlg);
recursive--;
break;
recursive++;
config = CreateConfigStore (config);
config = fixloadconfig (hDlg, config);
+ ConfigToRegistry (config, configtypepanel);
InitializeConfigTreeView (hDlg);
recursive--;
break;
if (!hWinUAEKey)
return;
SHDeleteKey (hWinUAEKey, "DetectedROMs");
- SHDeleteKey (hWinUAEKey, "QuickStartMode");
+ RegDeleteValue (hWinUAEKey, "QuickStartMode");
RegDeleteValue (hWinUAEKey, "ConfigFile");
+ RegDeleteValue (hWinUAEKey, "ConfigFileHardware");
+ RegDeleteValue (hWinUAEKey, "ConfigFileHost");
+ RegDeleteValue (hWinUAEKey, "ConfigFileHardware_Auto");
+ RegDeleteValue (hWinUAEKey, "ConfigFileHost_Auto");
RegDeleteValue (hWinUAEKey, "ConfigurationPath");
RegDeleteValue (hWinUAEKey, "SaveimagePath");
RegDeleteValue (hWinUAEKey, "ScreenshotPath");
RegDeleteValue (hWinUAEKey, "QuickStartModel");
RegDeleteValue (hWinUAEKey, "QuickStartConfiguration");
RegDeleteValue (hWinUAEKey, "QuickStartCompatibility");
+ RegDeleteValue (hWinUAEKey, "QuickStartHostConfig");
}
static BOOL CALLBACK PathsDlgProc (HWND hDlg, UINT msg, WPARAM wParam, LPARAM lParam)
struct amigamodels {
char *name;
- char *compatxt[3];
+ int compalevels;
};
static struct amigamodels amodels[] = {
- { "A500",
- "High compatibility (>1.5GHz recommended)",
- "Medium compatibility (recommended for most users)",
- "Low compatiblity (for PCs with low CPU power)"
- },
-/*
- { "A500+/A600",
- "High compatibility (>1.5GHz recommended)",
- "Medium compatibility (recommended for most users)",
- "Low compatiblity (for PCs with low CPU power)"
- },
-*/
- { "A1000",
- "High compatibility (>1.5GHz recommended)",
- "Medium compatibility (recommended for most users)",
- "Low compatiblity (for PCs with low CPU power)"
- },
- { "A1200",
- "Good compatibility, slow CPU emulation",
- "Medium compatibility, very fast CPU emulation",
- "Low compatibility, very fast CPU emulation"
- },
- { "CD32",
- "Good compatibility, slow CPU emulation",
- "Medium compatibility, very fast CPU emulation",
- "Low compatibility, very fast CPU emulation"
- },
-/*
- { "CDTV",
- "High compatibility (incomplete)",
- "Medium compatibility (incomplete)",
- "Low compatiblity (incomplete)"
- },
-*/
+ { "Amiga 500", 4 },
+ { "Amiga 500+", 0 },
+ { "Amiga 600", 0 },
+ { "Amiga 1000", 4 },
+ { "Amiga 1200", 3 },
+ { "CD32", 3 },
+ { "CDTV", 0 },
{ 0 }
};
int model;
char *config;
char *name;
+ char *info;
};
static struct amigaconfig aconf[] = {
- { 0, "", "KS 1.3, ECS Agnus, 0.5M Chip + 0.5M Slow (most common)" },
- { 0, "", "KS 1.3, OCS Agnus, 0.5M Chip" },
- { 0, "", "KS 1.3, ECS Agnus, 1.0M Chip" },
- { 0, "", "KS 1.2, OCS Agnus, 0.5M Chip" },
- { 0, "", "KS 1.2, OCS Agnus, 0.5M Chip + 0.5M Slow" },
-
-/*
- { 1, "", "1.0M Chip" },
-*/
- { 1, "", "0.5M Chip" },
- { 1, "", "256K Chip" },
-
- { 2, "", "2.0M Chip" },
- { 2, "", "2.0M Chip + 4.0M Fast" },
+ { 0, "", "KS 1.3, OCS Agnus, 0.5M Chip + 0.5M Slow (most common)",
+ "This configuration is capable of running most games and demos ever produced "
+ "for the first Amiga line. Only few exceptions need different configuration. "
+ "Oldest Amiga games tend to be incompatible with this configuration. "
+ },
+ { 0, "", "KS 1.3, ECS Agnus, 0.5M Chip + 0.5M Slow",
+ "Later hardware revision of Amiga 500. Nearly 100% compatible with "
+ "previous configuration."
+ },
+ { 0, "", "KS 1.3, ECS Agnus, 1.0M Chip",
+ "Few newer games and demos require this configuration."
+ },
+ { 0, "", "KS 1.3, OCS Agnus, 0.5M Chip",
+ "Very old (~1987 and older) games and demos may require this configuration."
+ },
+ { 0, "", "KS 1.2, OCS Agnus, 0.5M Chip",
+ "The first Amiga 500 produced had this configuration. Some very "
+ "old programs only work correctly with this configuration. NOTE: This configuration "
+ "cannot boot the Amiga OS installed on an emulated HD."
+ },
+ { 0, "", "KS 1.2, OCS Agnus, 0.5M Chip + 0.5M Slow",
+ "This configuration adds expansion memory to the first Amiga 500 ever "
+ "produced. Try this if your game do not work with newer configurations "
+ "but works with the previous one. It could add some features to the game and "
+ "faster game loading. NOTE: This configuration cannot boot the Amiga OS "
+ "installed on an emulated HD."
+ },
- { 3, "", "CD32" },
+ { 3, "", "0.5M Chip",
+ "The Amiga 1000 was the first Amiga ever produced, configuration is basically "
+ "an OCS A500. You should never use this configuration unless "
+ "you are nostalgic and you want to hear short special A1000 boot tune :)"
+ },
+ { 3, "", "256K Chip",
+ "Unexpanded Amiga 1000. All later A1000 models were sold with 256K RAM "
+ "expansion build-in."
+ },
+ { 4, "", "2.0M Chip",
+ "Use this configuration to run most AGA demos and games."
+ },
+ { 4, "", "2.0M Chip + 4.0M Fast",
+ "Some newer AGA games and demos need an expanded A1200 to run."
+ },
+ { 5, "", "CD32",
+ "CD32 was the first 32bit console. It is basically an A1200 with "
+ "build-in CDROM. Insert your CD32 CDROM into a free CDROM drive to run CD32 "
+ "games."
+ },
/*
- { 4, "", "CDTV" },
+ { 6, "", "CDTV" },
*/
{ -1 }
};
if (getconfigstorefrompath (name, tmp, CONFIG_TYPE_HOST))
cfgfile_load (&workprefs, tmp, &type);
- else
- cfgfile_load (&workprefs, "default.uae", &type);
+}
+
+static void init_quickstartdlg_tooltip (HWND hDlg, char *tt)
+{
+ TOOLINFO ti;
+
+ ti.cbSize = sizeof(TOOLINFO);
+ ti.uFlags = TTF_SUBCLASS | TTF_IDISHWND;
+ ti.hwnd = hDlg;
+ ti.hinst = hInst;
+ ti.uId = (UINT)GetDlgItem (hDlg, IDC_QUICKSTART_CONFIGURATION);
+ ti.lpszText = tt;
+ SendMessage (ToolTipHWND, TTM_DELTOOL, 0, (LPARAM) (LPTOOLINFO) &ti);
+ if (!tt)
+ return;
+ SendMessage (ToolTipHWND, TTM_ADDTOOL, 0, (LPARAM) (LPTOOLINFO) &ti);
}
static void init_quickstartdlg (HWND hDlg)
{
static int firsttime;
- int i, j, cnt, idx;
+ int i, j, cnt, idx, idx2;
DWORD dwType, qssize;
char tmp1[MAX_DPATH], tmp2[MAX_DPATH];
CheckDlgButton (hDlg, IDC_QUICKSTARTMODE, quickstart);
SendDlgItemMessage (hDlg, IDC_QUICKSTART_MODEL, CB_RESETCONTENT, 0, 0L);
+ idx = idx2 = 0;
i = 0;
while (amodels[i].name) {
- SendDlgItemMessage (hDlg, IDC_QUICKSTART_MODEL, CB_ADDSTRING, 0, (LPARAM)amodels[i].name);
+ if (amodels[i].compalevels > 0) {
+ SendDlgItemMessage (hDlg, IDC_QUICKSTART_MODEL, CB_ADDSTRING, 0, (LPARAM)amodels[i].name);
+ if (i == quickstart_model)
+ idx2 = idx;
+ idx++;
+ }
i++;
}
- SendDlgItemMessage (hDlg, IDC_QUICKSTART_MODEL, CB_SETCURSEL, quickstart_model, 0);
+ SendDlgItemMessage (hDlg, IDC_QUICKSTART_MODEL, CB_SETCURSEL, idx2, 0);
+ init_quickstartdlg_tooltip (hDlg, 0);
SendDlgItemMessage (hDlg, IDC_QUICKSTART_CONFIGURATION, CB_RESETCONTENT, 0, 0L);
i = 0;
cnt = 0;
while (aconf[i].model >= 0) {
if (aconf[i].model == quickstart_model) {
- cnt++;
SendDlgItemMessage (hDlg, IDC_QUICKSTART_CONFIGURATION, CB_ADDSTRING, 0, (LPARAM)aconf[i].name);
+ if (quickstart_conf == cnt) {
+ init_quickstartdlg_tooltip (hDlg, aconf[i].info);
+ }
+ cnt++;
}
i++;
}
if (quickstart_conf >= cnt)
quickstart_conf = 0;
SendDlgItemMessage (hDlg, IDC_QUICKSTART_CONFIGURATION, CB_SETCURSEL, quickstart_conf, 0);
-
- SendDlgItemMessage (hDlg, IDC_QUICKSTART_COMPATIBILITY, CB_RESETCONTENT, 0, 0L);
- i = 0;
- while (i < 3 && amodels[quickstart_model].compatxt[i]) {
- SendDlgItemMessage (hDlg, IDC_QUICKSTART_COMPATIBILITY, CB_ADDSTRING, 0, (LPARAM)amodels[quickstart_model].compatxt[i]);
- i++;
- }
- if (quickstart_compa >= i)
+
+ if (quickstart_compa >= amodels[quickstart_model].compalevels)
quickstart_compa = 0;
- SendDlgItemMessage (hDlg, IDC_QUICKSTART_COMPATIBILITY, CB_SETCURSEL, quickstart_compa, 0);
+ SendDlgItemMessage (hDlg, IDC_QUICKSTART_COMPATIBILITY, TBM_SETRANGE, TRUE, MAKELONG (0, amodels[quickstart_model].compalevels - 1));
+ SendDlgItemMessage (hDlg, IDC_QUICKSTART_COMPATIBILITY, TBM_SETPAGESIZE, 0, 1);
+ SendDlgItemMessage( hDlg, IDC_QUICKSTART_COMPATIBILITY, TBM_SETPOS, TRUE, quickstart_compa);
SendDlgItemMessage (hDlg, IDC_QUICKSTART_HOSTCONFIG, CB_RESETCONTENT, 0, 0L);
SendDlgItemMessage (hDlg, IDC_QUICKSTART_HOSTCONFIG, CB_ADDSTRING, 0, (LPARAM)"Default configuration");
}
}
-static void testimage (HWND hDlg)
+static void floppytooltip (HWND hDlg, int num, uae_u32 crc32);
+static void testimage (HWND hDlg, int num)
{
int ret;
int reload = 0;
+ uae_u32 crc32;
+ floppytooltip (hDlg, num, 0);
quickstart_ok_floppy = 0;
if (workprefs.dfxtype[0] < 0) {
quickstart_ok_floppy = 1;
return;
}
- if (!workprefs.df[0][0])
+ if (!workprefs.df[num][0])
return;
- ret = DISK_examine_image (&workprefs, 0);
+ ret = DISK_examine_image (&workprefs, num, &crc32);
if (!ret)
return;
+ floppytooltip (hDlg, num, crc32);
+ if (num > 0)
+ return;
switch (ret)
{
case 10:
pre_gui_message ("Selected disk image has incorrect bootblock checksum");
break;
case 2:
- pre_gui_message ("Selected disk image is unformatted");
+ pre_gui_message ("Selected disk image is damaged or unformatted");
break;
}
if (reload) {
static BOOL CALLBACK QuickstartDlgProc (HWND hDlg, UINT msg, WPARAM wParam, LPARAM lParam)
{
static int recursive;
- int val, ret = FALSE;
+ int val, ret = FALSE, i;
char tmp[MAX_DPATH];
static char df0[MAX_DPATH];
+ static char df1[MAX_DPATH];
static int dfxtype[2] = { -1, -1 };
+ static int doinit;
switch( msg )
{
case WM_INITDIALOG:
pages[QUICKSTART_ID] = hDlg;
currentpage = QUICKSTART_ID;
- init_quickstartdlg (hDlg);
- enable_for_quickstart (hDlg);
- addfloppytype (hDlg, 0);
- addfloppytype (hDlg, 1);
+ doinit = 1;
break;
+ case WM_NULL:
+ if (doinit) {
+ init_quickstartdlg (hDlg);
+ enable_for_quickstart (hDlg);
+ addfloppytype (hDlg, 0);
+ addfloppytype (hDlg, 1);
+ init_quickstartdlg (hDlg);
+ }
+ doinit = 0;
+ break;
+
case WM_COMMAND:
if (recursive > 0)
break;
{
case IDC_QUICKSTART_MODEL:
val = SendDlgItemMessage (hDlg, IDC_QUICKSTART_MODEL, CB_GETCURSEL, 0, 0L);
- if (val != CB_ERR && val != quickstart_model) {
- quickstart_model = val;
- init_quickstartdlg (hDlg);
- load_quickstart (hDlg, 1);
- if (quickstart && !full_property_sheet)
- qs_request_reset = 2;
+ if (val != CB_ERR) {
+ i = 0;
+ while (amodels[i].name) {
+ if (amodels[i].compalevels > 0)
+ val--;
+ if (val < 0)
+ break;
+ i++;
+ }
+ if (i != quickstart_model) {
+ quickstart_model = i;
+ init_quickstartdlg (hDlg);
+ load_quickstart (hDlg, 1);
+ if (quickstart && !full_property_sheet)
+ qs_request_reset = 2;
+ }
}
break;
case IDC_QUICKSTART_CONFIGURATION:
qs_request_reset = 2;
}
break;
- case IDC_QUICKSTART_COMPATIBILITY:
- val = SendDlgItemMessage (hDlg, IDC_QUICKSTART_COMPATIBILITY, CB_GETCURSEL, 0, 0L);
- if (val != CB_ERR) {
- quickstart_compa = val;
- init_quickstartdlg (hDlg);
- load_quickstart (hDlg, 0);
- }
- break;
case IDC_QUICKSTART_HOSTCONFIG:
val = SendDlgItemMessage (hDlg, IDC_QUICKSTART_HOSTCONFIG, CB_GETCURSEL, 0, 0);
if (val != CB_ERR) {
break;
}
recursive--;
+ case WM_HSCROLL:
+ val = SendMessage (GetDlgItem (hDlg, IDC_QUICKSTART_COMPATIBILITY), TBM_GETPOS, 0, 0);
+ if (val >= 0 && val != quickstart_compa) {
+ quickstart_compa = val;
+ init_quickstartdlg (hDlg);
+ load_quickstart (hDlg, 0);
+ }
+ break;
}
- if (strcmp (workprefs.df[0], df0) || workprefs.dfxtype[0] != dfxtype[0] || workprefs.dfxtype[1] != dfxtype[1]) {
- strcpy (df0, workprefs.df[0]);
+ if (strcmp (workprefs.df[0], df0) || workprefs.dfxtype[0] != dfxtype[0]) {
+ strcpy (df0, workprefs.df[0]);
dfxtype[0] = workprefs.dfxtype[0];
- dfxtype[1] = workprefs.dfxtype[1];
- testimage (hDlg);
+ if (full_property_sheet)
+ testimage (hDlg, 0);
enable_for_quickstart (hDlg);
}
+ if (strcmp (workprefs.df[1], df1) || workprefs.dfxtype[1] != dfxtype[1]) {
+ strcpy (df1, workprefs.df[1]);
+ dfxtype[1] = workprefs.dfxtype[1];
+ if (full_property_sheet)
+ testimage (hDlg, 1);
+ }
return ret;
}
case CSMASK_ECS_AGNUS:
CheckRadioButton( hDlg, IDC_OCS, IDC_AGA, IDC_OCS+1 );
break;
+#if 0
case CSMASK_ECS_DENISE:
CheckRadioButton( hDlg, IDC_OCS, IDC_AGA, IDC_OCS+2 );
break;
+#endif
case CSMASK_ECS_AGNUS | CSMASK_ECS_DENISE:
CheckRadioButton( hDlg, IDC_OCS, IDC_AGA, IDC_OCS+3 );
break;
if (workprefs.cpu_cycle_exact != n) {
workprefs.cpu_cycle_exact = workprefs.blitter_cycle_exact = n;
if (n) {
- if (workprefs.cpu_level == 0)
+ if (workprefs.cpu_level == 0) {
workprefs.cpu_compatible = 1;
+ workprefs.m68k_speed = 0;
+ }
workprefs.immediate_blits = 0;
workprefs.fast_copper = 0;
}
: IsDlgButtonChecked (hDlg, IDC_COLLISION2) ? 2 : 3;
workprefs.chipset_mask = IsDlgButtonChecked( hDlg, IDC_OCS ) ? 0
: IsDlgButtonChecked( hDlg, IDC_ECS_AGNUS ) ? CSMASK_ECS_AGNUS
+#if 0
: IsDlgButtonChecked( hDlg, IDC_ECS_DENISE ) ? CSMASK_ECS_DENISE
+#endif
: IsDlgButtonChecked( hDlg, IDC_ECS ) ? CSMASK_ECS_AGNUS | CSMASK_ECS_DENISE
: CSMASK_AGA | CSMASK_ECS_AGNUS | CSMASK_ECS_DENISE;
n = IsDlgButtonChecked (hDlg, IDC_NTSC) ? 1 : 0;
char seltmp[1000];
struct romdata *rdx;
- rdx = scan_rom (path, keybuf, keysize);
+ rdx = scan_single_rom (path, keybuf, keysize);
SendDlgItemMessage(hDlg, d, CB_RESETCONTENT, 0, 0);
SendDlgItemMessage(hDlg, d, CB_ADDSTRING, 0, (LPARAM)"");
idx = 0;
EnableWindow( GetDlgItem( hDlg, IDC_DOSAVESTATE ), TRUE );
EnableWindow( GetDlgItem( hDlg, IDC_ASPI ), FALSE );
EnableWindow( GetDlgItem( hDlg, IDC_SCSIDEVICE ), FALSE );
- EnableWindow( GetDlgItem( hDlg, IDC_NOUAEFSDB ), FALSE );
EnableWindow( GetDlgItem( hDlg, IDC_CLOCKSYNC ), FALSE );
EnableWindow( GetDlgItem( hDlg, IDC_STATE_CAPTURE ), FALSE );
EnableWindow( GetDlgItem( hDlg, IDC_STATE_RATE ), FALSE );
CheckDlgButton( hDlg, IDC_NOOVERLAY, workprefs.win32_no_overlay );
CheckDlgButton( hDlg, IDC_SHOWLEDS, workprefs.leds_on_screen );
CheckDlgButton( hDlg, IDC_SCSIDEVICE, workprefs.scsi );
- CheckDlgButton( hDlg, IDC_NOUAEFSDB, workprefs.filesys_no_uaefsdb );
CheckDlgButton( hDlg, IDC_ASPI, workprefs.win32_aspi );
CheckDlgButton( hDlg, IDC_STATE_CAPTURE, workprefs.tod_hack );
case WM_COMMAND:
if (currentpage == MISC1_ID) {
- misc_getkbled (hDlg, IDC_KBLED1, 0);
- misc_getkbled (hDlg, IDC_KBLED2, 1);
- misc_getkbled (hDlg, IDC_KBLED3, 2);
- SendDlgItemMessage (hDlg, IDC_STATE_RATE, WM_GETTEXT, (WPARAM)sizeof (txt), (LPARAM)txt);
- workprefs.statecapturerate = atol (txt) * 50;
- SendDlgItemMessage (hDlg, IDC_STATE_BUFFERSIZE, WM_GETTEXT, (WPARAM)sizeof (txt), (LPARAM)txt);
- workprefs.statecapturebuffersize = atol (txt) * 1024 * 1024;
+ if (HIWORD (wParam) == CBN_SELENDOK || HIWORD (wParam) == CBN_KILLFOCUS || HIWORD (wParam) == CBN_EDITCHANGE) {
+ switch (LOWORD (wParam))
+ {
+ case IDC_KBLED1:
+ misc_getkbled (hDlg, IDC_KBLED1, 0);
+ break;
+ case IDC_KBLED2:
+ misc_getkbled (hDlg, IDC_KBLED2, 1);
+ break;
+ case IDC_KBLED3:
+ misc_getkbled (hDlg, IDC_KBLED3, 2);
+ break;
+ case IDC_STATE_RATE:
+ getcbn (hDlg, IDC_STATE_RATE, txt, sizeof (txt));
+ workprefs.statecapturerate = atol (txt) * 50;
+ break;
+ case IDC_STATE_BUFFERSIZE:
+ getcbn (hDlg, IDC_STATE_BUFFERSIZE, txt, sizeof (txt));
+ break;
+ }
+ }
} else {
misc_getpri (hDlg, IDC_ACTIVE_PRIORITY, &workprefs.win32_active_priority);
misc_getpri (hDlg, IDC_INACTIVE_PRIORITY, &workprefs.win32_inactive_priority);
case IDC_SCSIDEVICE:
workprefs.scsi = IsDlgButtonChecked( hDlg, IDC_SCSIDEVICE );
break;
- case IDC_NOUAEFSDB:
- workprefs.filesys_no_uaefsdb = IsDlgButtonChecked( hDlg, IDC_NOUAEFSDB );
- break;
case IDC_ASPI:
workprefs.win32_aspi = IsDlgButtonChecked( hDlg, IDC_ASPI );
break;
/* These four items only get enabled when adjustable CPU style is enabled */
EnableWindow (GetDlgItem (hDlg, IDC_SPEED), workprefs.m68k_speed > 0);
- EnableWindow (GetDlgItem (hDlg, IDC_CS_CPU_TEXT), workprefs.m68k_speed > 0);
- EnableWindow (GetDlgItem (hDlg, IDC_CS_CHIPSET_TEXT), workprefs.m68k_speed > 0);
+ EnableWindow (GetDlgItem (hDlg, IDC_CS_CPU_TEXT), (!workprefs.cpu_cycle_exact || workprefs.cpu_level > 0) && workprefs.m68k_speed > 0);
+ EnableWindow (GetDlgItem (hDlg, IDC_CS_CHIPSET_TEXT), (!workprefs.cpu_cycle_exact || workprefs.cpu_level > 0) && workprefs.m68k_speed > 0);
+ EnableWindow (GetDlgItem (hDlg, IDC_CS_HOST), !workprefs.cpu_cycle_exact || workprefs.cpu_level > 0);
+ EnableWindow (GetDlgItem (hDlg, IDC_CS_68000), !workprefs.cpu_cycle_exact || workprefs.cpu_level > 0);
+ EnableWindow (GetDlgItem (hDlg, IDC_CS_ADJUSTABLE), !workprefs.cpu_cycle_exact || workprefs.cpu_level > 0);
EnableWindow (GetDlgItem (hDlg, IDC_CPUTEXT), workprefs.m68k_speed > 0 );
EnableWindow (GetDlgItem (hDlg, IDC_CPUIDLE), workprefs.m68k_speed != 0 ? TRUE : FALSE);
#if !defined(CPUEMU_0) || defined(CPUEMU_68000_ONLY)
case 3: // 68EC020+FPU
workprefs.address_space_24 = 1;
workprefs.cpu_level = newcpu;
+ if (newcpu == 0 && workprefs.cpu_cycle_exact)
+ workprefs.m68k_speed = 0;
break;
case 4: // 68020
EnableWindow( GetDlgItem( hDlg, IDC_SOUNDSTEREO ), workprefs.produce_sound );
EnableWindow( GetDlgItem( hDlg, IDC_SOUNDINTERPOLATION ), workprefs.produce_sound );
EnableWindow( GetDlgItem( hDlg, IDC_SOUNDVOLUME ), workprefs.produce_sound );
+ EnableWindow( GetDlgItem( hDlg, IDC_SOUNDVOLUME2 ), workprefs.produce_sound );
EnableWindow( GetDlgItem( hDlg, IDC_SOUNDBUFFERMEM ), workprefs.produce_sound );
EnableWindow( GetDlgItem( hDlg, IDC_SOUNDBUFFERRAM ), workprefs.produce_sound );
EnableWindow( GetDlgItem( hDlg, IDC_SOUNDDRIVE ), workprefs.produce_sound );
EnableWindow( GetDlgItem( hDlg, IDC_SOUNDDRIVESELECT ), workprefs.produce_sound );
EnableWindow( GetDlgItem( hDlg, IDC_SOUNDDRIVEVOLUME ), workprefs.produce_sound );
+ EnableWindow( GetDlgItem( hDlg, IDC_SOUNDDRIVEVOLUME2 ), workprefs.produce_sound );
EnableWindow( GetDlgItem( hDlg, IDC_AUDIOSYNC ), workprefs.produce_sound );
SetDlgItemText (hDlg, IDC_SOUNDADJUSTNUM, txt);
SendDlgItemMessage( hDlg, IDC_SOUNDVOLUME, TBM_SETPOS, TRUE, 100 - workprefs.sound_volume );
+ sprintf (txt, "%d%%", 100 - workprefs.sound_volume);
+ SetDlgItemText (hDlg, IDC_SOUNDVOLUME2, txt);
+
SendDlgItemMessage( hDlg, IDC_SOUNDDRIVEVOLUME, TBM_SETPOS, TRUE, 100 - workprefs.dfxclickvolume );
+ sprintf (txt, "%d%%", 100 - workprefs.dfxclickvolume);
+ SetDlgItemText (hDlg, IDC_SOUNDDRIVEVOLUME2, txt);
}
static int soundfreqs[] = { 11025, 15000, 22050, 32000, 44100, 48000, 0 };
SetDlgItemInt( hDlg, IDC_BLOCKSIZE, current_hfdlg.blocksize, FALSE);
SetDlgItemInt( hDlg, IDC_HARDFILE_BOOTPRI, current_hfdlg.bootpri, TRUE);
CheckDlgButton (hDlg, IDC_RW, current_hfdlg.rw);
+ EnableWindow (GetDlgItem (hDlg, IDC_HDF_RDB),
+ !(current_hfdlg.sectors == 0 && current_hfdlg.surfaces == 0 && current_hfdlg.reserved == 0));
}
static void hardfile_testrdb (HWND hDlg)
case IDCANCEL:
EndDialog (hDlg, 0);
break;
+ case IDC_RW:
+ current_hfdlg.rw = IsDlgButtonChecked (hDlg, IDC_RW);
+ break;
+ case IDC_HDF_RDB:
+ SetDlgItemInt (hDlg, IDC_SECTORS, 0, FALSE);
+ SetDlgItemInt (hDlg, IDC_RESERVED, 0, FALSE);
+ SetDlgItemInt (hDlg, IDC_HEADS, 0, FALSE);
+ SetDlgItemText (hDlg, IDC_PATH_FILESYS, "");
+ SetDlgItemText (hDlg, IDC_HARDFILE_DEVICE, "");
+ current_hfdlg.sectors = current_hfdlg.reserved = current_hfdlg.surfaces = 0;
+ sethardfile (hDlg);
+ break;
}
}
current_hfdlg.surfaces = GetDlgItemInt( hDlg, IDC_HEADS, NULL, FALSE );
current_hfdlg.blocksize = GetDlgItemInt( hDlg, IDC_BLOCKSIZE, NULL, FALSE );
current_hfdlg.bootpri = GetDlgItemInt( hDlg, IDC_HARDFILE_BOOTPRI, NULL, TRUE );
- current_hfdlg.rw = IsDlgButtonChecked (hDlg, IDC_RW);
recursive--;
break;
switch (button) {
case IDC_NEW_FS:
current_fsvdlg = empty_fsvdlg;
- if (DialogBox( hUIDLL ? hUIDLL : hInst, MAKEINTRESOURCE (IDD_FILESYS), hDlg, VolumeSettingsProc))
+ if (DialogBox (hUIDLL ? hUIDLL : hInst, MAKEINTRESOURCE (IDD_FILESYS), hDlg, VolumeSettingsProc))
new_filesys (hDlg);
break;
case IDC_NEW_HF:
current_hfdlg = empty_hfdlg;
- if (DialogBox( hUIDLL ? hUIDLL : hInst, MAKEINTRESOURCE (IDD_HARDFILE), hDlg, HardfileSettingsProc))
+ if (DialogBox (hUIDLL ? hUIDLL : hInst, MAKEINTRESOURCE (IDD_HARDFILE), hDlg, HardfileSettingsProc))
new_hardfile (hDlg);
break;
case IDC_NEW_HD:
memset (¤t_hfdlg, 0, sizeof (current_hfdlg));
- if (DialogBox( hUIDLL ? hUIDLL : hInst, MAKEINTRESOURCE (IDD_HARDDRIVE), hDlg, HarddriveSettingsProc))
- new_harddrive (hDlg);
+ if (hdf_init() == 0) {
+ char tmp[MAX_DPATH];
+ WIN32GUI_LoadUIString (IDS_NOHARDDRIVES, tmp, sizeof (tmp));
+ gui_message (tmp);
+ } else {
+ if (DialogBox (hUIDLL ? hUIDLL : hInst, MAKEINTRESOURCE (IDD_HARDDRIVE), hDlg, HarddriveSettingsProc))
+ new_harddrive (hDlg);
+ }
break;
case IDC_EDIT:
case IDC_MAPDRIVES:
workprefs.win32_automount_drives = IsDlgButtonChecked( hDlg, button );
break;
+
+ case IDC_NOUAEFSDB:
+ workprefs.filesys_no_uaefsdb = IsDlgButtonChecked( hDlg, IDC_NOUAEFSDB );
+ break;
}
}
currentpage = HARDDISK_ID;
SendMessage( GetDlgItem( hDlg, IDC_UP ), BM_SETIMAGE, (WPARAM)IMAGE_ICON, (LPARAM)hMoveUp );
SendMessage( GetDlgItem( hDlg, IDC_DOWN ), BM_SETIMAGE, (WPARAM)IMAGE_ICON, (LPARAM)hMoveDown );
- EnableWindow (GetDlgItem(hDlg, IDC_NEW_HD), os_winnt ? TRUE : FALSE);
+ EnableWindow (GetDlgItem(hDlg, IDC_NEW_HD), os_winnt && os_winnt_admin ? TRUE : FALSE);
case WM_USER:
CheckDlgButton( hDlg, IDC_MAPDRIVES, workprefs.win32_automount_drives );
+ CheckDlgButton( hDlg, IDC_NOUAEFSDB, workprefs.filesys_no_uaefsdb );
InitializeListView( hDlg );
break;
SetDlgItemText (hDlg, IDC_FLOPPYSPDTEXT, txt);
}
-#define BUTTONSPERFLOPPY 5
+#define BUTTONSPERFLOPPY 6
static int floppybuttons[][BUTTONSPERFLOPPY] = {
- { IDC_DF0TEXT,IDC_DF0,IDC_EJECT0,IDC_DF0TYPE,IDC_DF0WP },
- { IDC_DF1TEXT,IDC_DF1,IDC_EJECT1,IDC_DF1TYPE,IDC_DF1WP },
- { IDC_DF2TEXT,IDC_DF2,IDC_EJECT2,IDC_DF2TYPE,IDC_DF2WP },
- { IDC_DF3TEXT,IDC_DF3,IDC_EJECT3,IDC_DF3TYPE,IDC_DF3WP }
+ { IDC_DF0TEXT,IDC_DF0,IDC_EJECT0,IDC_DF0TYPE,IDC_DF0WP,IDC_SAVEIMAGE0 },
+ { IDC_DF1TEXT,IDC_DF1,IDC_EJECT1,IDC_DF1TYPE,IDC_DF1WP,IDC_SAVEIMAGE1 },
+ { IDC_DF2TEXT,IDC_DF2,IDC_EJECT2,IDC_DF2TYPE,IDC_DF2WP,IDC_SAVEIMAGE2 },
+ { IDC_DF3TEXT,IDC_DF3,IDC_EJECT3,IDC_DF3TYPE,IDC_DF3WP,IDC_SAVEIMAGE3 }
};
static int floppybuttonsq[][BUTTONSPERFLOPPY] = {
- { IDC_DF0TEXTQ,IDC_DF0QQ,IDC_EJECT0Q,-1,IDC_DF0WPQ },
- { IDC_DF1TEXTQ,IDC_DF1QQ,IDC_EJECT1Q,-1,IDC_DF1WPQ },
- { -1,-1,-1,-1,-1 },
- { -1,-1,-1,-1,-1 }
+ { IDC_DF0TEXTQ,IDC_DF0QQ,IDC_EJECT0Q,-1,IDC_DF0WPQ,-1 },
+ { IDC_DF1TEXTQ,IDC_DF1QQ,IDC_EJECT1Q,-1,IDC_DF1WPQ,-1 },
+ { -1,-1,-1,-1,-1,-1 },
+ { -1,-1,-1,-1,-1,-1 }
};
+
+static void floppytooltip (HWND hDlg, int num, uae_u32 crc32)
+{
+ TOOLINFO ti;
+ int id;
+ char tmp[100];
+ if (currentpage == QUICKSTART_ID)
+ id = floppybuttonsq[num][0];
+ else
+ id = floppybuttons[num][0];
+ ti.cbSize = sizeof(TOOLINFO);
+ ti.uFlags = TTF_SUBCLASS | TTF_IDISHWND;
+ ti.hwnd = hDlg;
+ ti.hinst = hInst;
+ ti.uId = (UINT)GetDlgItem (hDlg, id);
+ SendMessage (ToolTipHWND, TTM_DELTOOL, 0, (LPARAM) (LPTOOLINFO) &ti);
+ if (crc32 == 0)
+ return;
+ sprintf (tmp, "CRC=%08.8X", crc32);
+ ti.lpszText = tmp;
+ SendMessage (ToolTipHWND, TTM_ADDTOOL, 0, (LPARAM) (LPTOOLINFO) &ti);
+}
+
static void addfloppytype (HWND hDlg, int n)
{
+ int nn = workprefs.dfxtype[n] + 1;
+ int state, i, chk;
+ char *s;
+ HKEY fkey;
+ char tmp[1000];
+
int f_text = floppybuttons[n][0];
int f_drive = floppybuttons[n][1];
int f_eject = floppybuttons[n][2];
int f_type = floppybuttons[n][3];
int f_wp = floppybuttons[n][4];
+ int f_si = floppybuttons[n][5];
- int f_textq = floppybuttonsq[n][0];
- int f_driveq = floppybuttonsq[n][1];
- int f_ejectq = floppybuttonsq[n][2];
- int f_wpq = floppybuttonsq[n][4];
-
- int nn = workprefs.dfxtype[n] + 1;
- int state, i, chk;
- char *s;
- HKEY fkey;
- char tmp[1000];
+ if (currentpage == QUICKSTART_ID) {
+ f_text = floppybuttonsq[n][0];
+ f_drive = floppybuttonsq[n][1];
+ f_type = -1;
+ f_eject = floppybuttonsq[n][2];
+ f_wp = floppybuttonsq[n][4];
+ f_si = -1;
+ }
if (nn <= 0)
state = FALSE;
else
state = TRUE;
- SendDlgItemMessage (hDlg, f_type, CB_SETCURSEL, nn, 0);
-
- EnableWindow(GetDlgItem(hDlg, f_text), state);
- if (f_textq >= 0)
- EnableWindow(GetDlgItem(hDlg, f_textq), state);
- EnableWindow(GetDlgItem(hDlg, f_eject), TRUE);
- if (f_ejectq >= 0)
- EnableWindow(GetDlgItem(hDlg, f_ejectq), TRUE);
- EnableWindow(GetDlgItem(hDlg, f_drive), state);
- if (f_driveq >= 0)
- EnableWindow(GetDlgItem(hDlg, f_driveq), state);
+ if (f_type >= 0)
+ SendDlgItemMessage (hDlg, f_type, CB_SETCURSEL, nn, 0);
+ if (f_si >= 0)
+ ShowWindow (GetDlgItem(hDlg, f_si), zfile_exists (DISK_get_saveimagepath (workprefs.df[n])) ? SW_SHOW : SW_HIDE);
+
+ if (f_text >= 0)
+ EnableWindow(GetDlgItem(hDlg, f_text), state);
+ if (f_eject >= 0)
+ EnableWindow(GetDlgItem(hDlg, f_eject), TRUE);
+ if (f_drive >= 0)
+ EnableWindow(GetDlgItem(hDlg, f_drive), state);
chk = disk_getwriteprotect (workprefs.df[n]) && state == TRUE ? BST_CHECKED : 0;
- CheckDlgButton(hDlg, f_wp, chk);
- if (f_wpq >= 0)
- CheckDlgButton(hDlg, f_wpq, chk);
+ if (f_wp >= 0)
+ CheckDlgButton(hDlg, f_wp, chk);
chk = state && DISK_validate_filename (workprefs.df[n], 0, 0) ? TRUE : FALSE;
- EnableWindow(GetDlgItem(hDlg, f_wp), chk);
- if (f_wpq >= 0)
- EnableWindow(GetDlgItem(hDlg, f_wpq), chk);
+ if (f_wp >= 0)
+ EnableWindow(GetDlgItem(hDlg, f_wp), chk);
fkey = read_disk_history ();
- SendDlgItemMessage(hDlg, f_text, CB_RESETCONTENT, 0, 0);
- SendDlgItemMessage(hDlg, f_text, WM_SETTEXT, 0, (LPARAM)workprefs.df[n]);
- if (f_textq >= 0) {
- SendDlgItemMessage(hDlg, f_textq, CB_RESETCONTENT, 0, 0);
- SendDlgItemMessage(hDlg, f_textq, WM_SETTEXT, 0, (LPARAM)workprefs.df[n]);
+ if (f_text >= 0) {
+ SendDlgItemMessage(hDlg, f_text, CB_RESETCONTENT, 0, 0);
+ SendDlgItemMessage(hDlg, f_text, WM_SETTEXT, 0, (LPARAM)workprefs.df[n]);
}
i = 0;
while (s = DISK_history_get (i)) {
i++;
- SendDlgItemMessage(hDlg, f_text, CB_ADDSTRING, 0, (LPARAM)s);
- if (f_textq >= 0)
- SendDlgItemMessage(hDlg, f_textq, CB_ADDSTRING, 0, (LPARAM)s);
+ if (strlen (s) == 0)
+ continue;
+ if (f_text >= 0)
+ SendDlgItemMessage (hDlg, f_text, CB_ADDSTRING, 0, (LPARAM)s);
if (fkey) {
sprintf (tmp, "Image%02d", i);
- RegSetValueEx(fkey, tmp, 0, REG_SZ, (CONST BYTE *)s, strlen(s) + 1);
+ RegSetValueEx (fkey, tmp, 0, REG_SZ, (CONST BYTE *)s, strlen(s) + 1);
}
if (!strcmp (workprefs.df[n], s)) {
- SendDlgItemMessage (hDlg, f_text, CB_SETCURSEL, i - 1, 0);
- if (f_textq >= 0)
- SendDlgItemMessage (hDlg, f_textq, CB_SETCURSEL, i - 1, 0);
+ if (f_text >= 0)
+ SendDlgItemMessage (hDlg, f_text, CB_SETCURSEL, i - 1, 0);
}
if (nn <= 0)
break;
if (val == CB_ERR) {
SendDlgItemMessage (hDlg, f_text, WM_GETTEXT, (WPARAM)sizeof (tmp), (LPARAM)tmp);
} else {
- char *s = DISK_history_get (val);
- if (s) {
- strcpy (tmp, s);
- /* add to top of list */
- DISK_history_add (tmp, -1);
+ val = SendDlgItemMessage (hDlg, f_text, CB_GETLBTEXT, (WPARAM)val, (LPARAM)tmp);
+ if (val != CB_ERR && val > 0) {
+ if (tmp[0]) {
+ /* add to top of list */
+ DISK_history_add (tmp, -1);
+ }
+ } else {
+ tmp[0] = 0;
}
}
- disk_insert (n, tmp);
- strcpy (workprefs.df[n], tmp);
+ if (tmp[0]) {
+ disk_insert (n, tmp);
+ strcpy (workprefs.df[n], tmp);
+ }
}
static void addallfloppies (HWND hDlg)
addfloppytype (hDlg, n);
}
+static void deletesaveimage (HWND hDlg, int num)
+{
+ char *p = DISK_get_saveimagepath (workprefs.df[num]);
+ if (zfile_exists (p)) {
+ DeleteFile (p);
+ DISK_reinsert (num);
+ addfloppytype (hDlg, num);
+ }
+}
+
static BOOL CALLBACK FloppyDlgProc (HWND hDlg, UINT msg, WPARAM wParam, LPARAM lParam)
{
static int recursive = 0;
workprefs.df[3][0] = 0;
addfloppytype (hDlg, 3);
break;
+ case IDC_SAVEIMAGE0:
+ deletesaveimage (hDlg, 0);
+ break;
+ case IDC_SAVEIMAGE1:
+ deletesaveimage (hDlg, 1);
+ break;
+ case IDC_SAVEIMAGE2:
+ deletesaveimage (hDlg, 2);
+ break;
+ case IDC_SAVEIMAGE3:
+ deletesaveimage (hDlg, 3);
+ break;
case IDC_CREATE:
DiskSelection (hDlg, wParam, 1, &workprefs, 0);
break;
break;
case WM_HSCROLL:
- workprefs.floppy_speed = SendMessage( GetDlgItem( hDlg, IDC_FLOPPYSPD ), TBM_GETPOS, 0, 0 );
+ workprefs.floppy_speed = SendMessage (GetDlgItem (hDlg, IDC_FLOPPYSPD), TBM_GETPOS, 0, 0);
if (workprefs.floppy_speed > 0) {
workprefs.floppy_speed--;
workprefs.floppy_speed = 1 << workprefs.floppy_speed;
EnableWindow (GetDlgItem (hDlg, IDC_FILTERENABLE), TRUE);
EnableWindow (GetDlgItem (hDlg, IDC_FILTERMODE), v);
CheckDlgButton( hDlg, IDC_FILTERENABLE, v );
- EnableWindow (GetDlgItem (hDlg, IDC_FILTERHZ), vv2);
- EnableWindow (GetDlgItem (hDlg, IDC_FILTERVZ), vv2);
+ EnableWindow (GetDlgItem (hDlg, IDC_FILTERHZ), v);
+ EnableWindow (GetDlgItem (hDlg, IDC_FILTERVZ), v);
EnableWindow (GetDlgItem (hDlg, IDC_FILTERHO), v);
EnableWindow (GetDlgItem (hDlg, IDC_FILTERVO), v);
EnableWindow (GetDlgItem (hDlg, IDC_FILTERSLR), vv2);
SendDlgItemMessage (hDlg, IDC_FILTERFILTER, CB_ADDSTRING, 0, (LPARAM)tmp);
modenum = 4;
} else {
- workprefs.gfx_filter_horiz_zoom = 0;
- workprefs.gfx_filter_vert_zoom = 0;
modenum = 0;
for (i = 1; i <= 4; i++) {
if (uf->x[i]) {
if (ok == 0) {
tmp1[0] = 0;
SendDlgItemMessage (hDlg, IDC_FILTERPRESETS, WM_GETTEXT, (WPARAM)sizeof (tmp1), (LPARAM)tmp1);
- if (tmp1[0] == 0) {
- gui_message ("No name");
+ if (tmp1[0] == 0)
goto end;
- }
}
RegSetValueEx (fkey, tmp1, 0, REG_SZ, (CONST BYTE *)&tmp2, strlen (tmp2) + 1);
values_to_hw3ddlg (hDlg);
char *help;
};
+static HWND panelhwnd;
+static BOOL CALLBACK childenumproc (HWND hwnd, LPARAM lParam)
+{
+ TOOLINFO ti;
+ char tmp[MAX_DPATH];
+ char *p;
+
+ tmp[0] = 0;
+ SendMessage (hwnd, WM_GETTEXT, (WPARAM)sizeof (tmp), (LPARAM)tmp);
+ p = strchr (tmp, '[');
+ if (strlen (tmp) > 0 && p && strlen(p) > 2 && p[1] == ']') {
+ *p++ = 0;
+ *p++ = 0;
+ if (p[0] == ' ')
+ *p++;
+ tmp[strlen(tmp) - 1] = 0;
+ SendMessage(hwnd, WM_SETTEXT, 0, (LPARAM)tmp);
+ ti.cbSize = sizeof (TOOLINFO);
+ ti.uFlags = TTF_SUBCLASS | TTF_IDISHWND;
+ ti.hwnd = GetParent (hwnd);
+ ti.hinst = hInst;
+ ti.uId = (UINT)hwnd;
+ ti.lpszText = p;
+ SendMessage(ToolTipHWND, TTM_ADDTOOL, 0, (LPARAM) (LPTOOLINFO) &ti);
+ return 1;
+ }
+ p = strchr (tmp, ']');
+ if (strlen (tmp) > 0 && p && strlen(p) > 2 && p[1] == '[') {
+ RECT r;
+ *p++ = 0;
+ *p++ = 0;
+ if (p[0] == ' ')
+ *p++;
+ tmp[strlen(tmp) - 1] = 0;
+ SendMessage(hwnd, WM_SETTEXT, 0, (LPARAM)tmp);
+ ti.cbSize = sizeof (TOOLINFO);
+ ti.uFlags = TTF_SUBCLASS;
+ ti.hwnd = GetParent (hwnd);
+ ti.hinst = hInst;
+ ti.uId = (UINT)hwnd;
+ ti.lpszText = p;
+ GetWindowRect (GetParent (hwnd), &r);
+ GetWindowRect (hwnd, &ti.rect);
+ ti.rect.top -= r.top;
+ ti.rect.left -= r.left;
+ ti.rect.right -= r.left;
+ ti.rect.bottom -= r.top;
+ SendMessage(ToolTipHWND, TTM_ADDTOOL, 0, (LPARAM) (LPTOOLINFO) &ti);
+ }
+ return 1;
+}
+
static struct GUIPAGE ppage[MAX_C_PAGES];
#define PANEL_X 174
#define PANEL_Y 12
static HWND updatePanel (HWND hDlg, int id)
{
- static HWND chwnd;
+ static HWND chwnd, hwndTT;
RECT r1c, r1w, r2c, r2w, r3c, r3w;
int w, h, pw, ph, x , y;
- EnableWindow( GetDlgItem (guiDlg, IDC_RESETAMIGA ), full_property_sheet ? FALSE : TRUE);
- EnableWindow( GetDlgItem (guiDlg, IDOK ), TRUE);
+ EnableWindow (GetDlgItem (guiDlg, IDC_RESETAMIGA), full_property_sheet ? FALSE : TRUE);
+ EnableWindow (GetDlgItem (guiDlg, IDOK), TRUE);
if (chwnd != NULL) {
ShowWindow (chwnd, FALSE);
DestroyWindow (chwnd);
+ chwnd = NULL;
+ }
+ if (ToolTipHWND != NULL) {
+ DestroyWindow (ToolTipHWND);
+ ToolTipHWND = NULL;
}
if (id < 0) {
if (!isfullscreen ()) {
EnableWindow (GetDlgItem (hDlg, IDHELP), FALSE);
return NULL;
}
+
GetWindowRect (GetDlgItem (hDlg, IDC_PANEL_FRAME), &r1w);
GetClientRect (GetDlgItem (hDlg, IDC_PANEL_FRAME), &r1c);
GetWindowRect (hDlg, &r2w);
SWP_NOSIZE | SWP_NOOWNERZORDER);
ShowWindow (chwnd, TRUE);
EnableWindow (GetDlgItem (hDlg, IDHELP), pHtmlHelp && ppage[currentpage].help ? TRUE : FALSE);
+
+ ToolTipHWND = CreateWindowEx (WS_EX_TOPMOST,
+ TOOLTIPS_CLASS, NULL,
+ WS_POPUP | TTS_NOPREFIX | TTS_BALLOON,
+ CW_USEDEFAULT, CW_USEDEFAULT, CW_USEDEFAULT, CW_USEDEFAULT,
+ chwnd, NULL, hInst, NULL);
+ SetWindowPos (ToolTipHWND, HWND_TOPMOST, 0, 0, 0, 0,
+ SWP_NOMOVE | SWP_NOSIZE | SWP_NOACTIVATE);
+#if 0
+ SendMessage(ToolTipHWND, TTM_SETDELAYTIME, (WPARAM)TTDT_INITIAL, (LPARAM)MAKELONG(100, 0));
+ SendMessage(ToolTipHWND, TTM_SETDELAYTIME, (WPARAM)TTDT_RESHOW, (LPARAM)MAKELONG(0, 0));
+#endif
+ SendMessage(ToolTipHWND, TTM_SETDELAYTIME, (WPARAM)TTDT_AUTOPOP, (LPARAM)MAKELONG(20000, 0));
+ SendMessage(ToolTipHWND, TTM_SETMAXTIPWIDTH, 0, 400);
+ EnumChildWindows (chwnd, &childenumproc, (LPARAM)NULL);
+ SendMessage (chwnd, WM_NULL, 0, 0);
+
return chwnd;
}
return 0;
drv = 0;
for (i = 0; i < cnt; i++) {
- struct zfile *f;
+ struct zfile *z;
DragQueryFile (hd, i, file, sizeof (file));
- f = zfile_fopen (file, "rb");
- if (f) {
- int type = zfile_gettype (f);
+ z = zfile_fopen (file, "rb");
+ if (z) {
+ int type = zfile_gettype (z);
+ zfile_fclose (z);
switch (type)
{
case ZFILE_DISKIMAGE:
case IDCANCEL:
updatePanel (hDlg, -1);
EndDialog (hDlg, 0);
- if (allow_quit)
- {
+ if (allow_quit) {
quit_program = 1;
regs.spcflags |= SPCFLAG_BRK;
}
ppage[id].pp.pszTemplate = MAKEINTRESOURCE (tmpl);
ppage[id].pp.pszIcon = MAKEINTRESOURCE (icon);
lpstrTitle = calloc (1, MAX_DPATH);
- LoadString( hUIDLL, title, lpstrTitle, MAX_DPATH );
+ LoadString (hUIDLL, title, lpstrTitle, MAX_DPATH);
ppage[id].pp.pszTitle = lpstrTitle;
ppage[id].pp.pfnDlgProc = func;
ppage[id].help = help;
#ifdef AVIOUTPUT
AVIOUTPUT_ID = init_page (IDD_AVIOUTPUT, IDI_AVIOUTPUT, IDS_AVIOUTPUT, AVIOutputDlgProc, "gui/output.htm");
#endif
- PATHS_ID = init_page (IDD_PATHS, IDI_ABOUT, IDS_PATHS, PathsDlgProc, "gui/paths.htm");
- QUICKSTART_ID = init_page (IDD_QUICKSTART, IDI_ABOUT, IDS_QUICKSTART, QuickstartDlgProc, "gui/quickstart.htm");
+ PATHS_ID = init_page (IDD_PATHS, IDI_PATHS, IDS_PATHS, PathsDlgProc, "gui/paths.htm");
+ QUICKSTART_ID = init_page (IDD_QUICKSTART, IDI_QUICKSTART, IDS_QUICKSTART, QuickstartDlgProc, "gui/quickstart.htm");
ABOUT_ID = init_page (IDD_ABOUT, IDI_ABOUT, IDS_ABOUT, AboutDlgProc, NULL);
C_PAGES = ABOUT_ID + 1;
init_called = 1;
static int fsdialog (HWND *hwnd, DWORD *flags)
{
+ HRESULT hr;
+
if (gui_active) {
*hwnd = guiDlg;
*flags |= MB_SETFOREGROUND;
*hwnd = hAmigaWnd;
if (!isfullscreen ())
return 0;
+ hr = DirectDraw_FlipToGDISurface();
+ if (hr != DD_OK)
+ write_log ("FlipToGDISurface failed, %s\n", DXError (hr));
*flags &= ~MB_SETFOREGROUND;
return 0;
/*
DWORD flags = MB_OK | MB_ICONWARNING | MB_TASKMODAL;
HWND hwnd;
+ va_start (parms, format);
+ vsprintf( msg, format, parms );
+ va_end (parms);
+ if (full_property_sheet) {
+ pre_gui_message (msg);
+ return;
+ }
pause_sound ();
flipflop = fsdialog (&hwnd, &flags);
if (flipflop)
ShowWindow (hAmigaWnd, SW_MINIMIZE);
- va_start (parms, format);
- vsprintf( msg, format, parms );
- va_end (parms);
write_log( msg );
if (msg[strlen(msg)-1]!='\n')
write_log("\n");
}
+static int transla[] = {
+ NUMSG_NEEDEXT2, IDS_NUMSG_NEEDEXT2,
+ NUMSG_NOROMKEY,IDS_NUMSG_NOROMKEY,
+ NUMSG_KSROMCRCERROR,IDS_NUMSG_KSROMCRCERROR,
+ NUMSG_KSROMREADERROR,IDS_NUMSG_KSROMREADERROR,
+ NUMSG_NOEXTROM,IDS_NUMSG_NOEXTROM,
+ NUMSG_MODRIP_NOTFOUND,IDS_NUMSG_MODRIP_NOTFOUND,
+ NUMSG_MODRIP_FINISHED,IDS_NUMSG_MODRIP_FINISHED,
+ NUMSG_MODRIP_SAVE,IDS_NUMSG_MODRIP_SAVE,
+ NUMSG_KS68020,IDS_NUMSG_KS68020,
+ NUMSG_ROMNEED,IDS_NUMSG_ROMNEED,
+ NUMSG_NOZLIB,IDS_NUMSG_NOZLIB,
+ NUMSG_STATEHD,IDS_NUMSG_STATEHD,
+ NUMSG_OLDCAPS, IDS_NUMSG_OLDCAPS,
+ NUMSG_NOCAPS, IDS_NUMSG_NOCAPS,
+ -1
+};
+
+static int gettranslation (int msg)
+{
+ int i;
+
+ i = 0;
+ while (transla[i] >= 0) {
+ if (transla[i] == msg)
+ return transla[i + 1];
+ i += 2;
+ }
+ return -1;
+}
+
+void notify_user (int msg)
+{
+ char tmp[MAX_DPATH];
+ int c = 0;
+
+ c = gettranslation (msg);
+ if (c < 0)
+ return;
+ WIN32GUI_LoadUIString (c, tmp, sizeof(tmp));
+ gui_message (tmp);
+}
+
+int translate_message (int msg, char *out)
+{
+ msg = gettranslation (msg);
+ out[0] = 0;
+ if (msg < 0)
+ return 0;
+ WIN32GUI_LoadUIString (msg, out, sizeof(out));
+ return 1;
+}
+
void gui_lock (void)
{
}
<File
RelativePath="..\resources\avioutput.ico">
</File>
- <File
- RelativePath="..\resources\bitmap1.bmp">
- </File>
<File
RelativePath="..\resources\chip.ico">
</File>
<File
RelativePath="..\resources\move_up.ico">
</File>
+ <File
+ RelativePath="..\resources\path.ico">
+ </File>
+ <File
+ RelativePath="..\resources\paths.ico">
+ </File>
+ <File
+ RelativePath="..\resources\quickstart.ico">
+ </File>
<File
RelativePath="..\resources\root.ico">
</File>
<File
RelativePath="..\..\cia.c">
</File>
- <File
- RelativePath="..\..\compiler.c">
- </File>
<File
RelativePath="..\..\cpudefs.c">
</File>
<File
RelativePath="..\..\uaelib.c">
</File>
- <File
- RelativePath="..\..\uaeserial.c">
- </File>
<File
RelativePath="..\..\unzip.c">
</File>
#include "newcpu.h"
#include "savestate.h"
#include "uae.h"
+#include "gui.h"
-int savestate_state;
+int savestate_state = 0;
#define MAX_STATERECORDS 1024 /* must be power of 2 */
struct staterecord {
#ifdef FILESYS
if (nr_units (currprefs.mountinfo) && !warned) {
warned = 1;
- gui_message("WARNING: State saves do not support harddrive emulation");
+ notify_user (NUMSG_STATEHD);
}
#endif
Read unzip.h for more info
*/
+#include "sysconfig.h"
+#include "sysdeps.h"
+
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include "unzip.h"
#include "disk.h"
#include "dms/pfile.h"
+#include "gui.h"
+#include "crc32.h"
#include <zlib.h>
static int zlib_test (void)
{
-#ifdef _WIN32
static int zlibmsg;
if (is_zlib)
return 1;
if (zlibmsg)
return 0;
zlibmsg = 1;
- gui_message("zip and gzip support disabled because zlib1.dll is missing");
+ notify_user (NUMSG_NOZLIB);
return 0;
-#else
- /* On non-Windows platforms, we can safely assume (I think) that if we got this
- * far zlib is present - Rich */
- return 1;
-#endif
}
static struct zfile *zfile_create (void)
unlink (f->name);
write_log ("deleted temporary file '%s'\n", f->name);
}
- free (f->name);
- free (f->data);
- free (f);
+ xfree (f->name);
+ xfree (f->data);
+ xfree (f);
}
void zfile_exit (void)
return z;
if (unzGoToFirstFile (uz) != UNZ_OK)
return z;
- write_log("checking zip file '%s':\n", z->name);
zipcnt = 1;
tmphist[0] = 0;
for (;;) {
if (err != UNZ_OK)
return z;
if (file_info.uncompressed_size > 0) {
- write_log("'%s':%d ", filename_inzip, file_info.uncompressed_size);
i = 0;
while (ignoreextensions[i]) {
if (strlen(filename_inzip) > strlen (ignoreextensions[i]) &&
break;
i++;
}
- if (ignoreextensions[i]) {
- write_log ("[ignored]");
- } else {
+ if (!ignoreextensions[i]) {
if (tmphist[0]) {
DISK_history_add (tmphist, -1);
tmphist[0] = 0;
DISK_history_add (tmphist, -1);
tmphist[0] = 0;
}
- write_log ("[check]");
select = 0;
if (!z->zipname)
select = 1;
select = -1;
if (select && !we_have_file) {
int err = unzOpenCurrentFile (uz);
- write_log ("[selected]");
if (err == UNZ_OK) {
zf = zfile_fopen_empty (filename_inzip, file_info.uncompressed_size);
if (zf) {
zf = zuncompress (zf);
if (select < 0 || zfile_gettype (zf)) {
we_have_file = 1;
- write_log("[ok]");
}
}
}
zfile_fclose (zf);
zf = 0;
}
- } else {
- write_log ("\nunzipping failed %d", err);
}
}
}
- write_log("\n");
}
zipcnt++;
err = unzGoToNextFile (uz);
return z;
}
+static int iszip (struct zfile *z)
+{
+ char *name = z->name;
+ char *ext = strrchr (name, '.');
+ uae_u8 header[4];
+
+ if (!ext || strcasecmp (ext, ".zip"))
+ return 0;
+ memset (header, 0, sizeof (header));
+ zfile_fseek (z, 0, SEEK_SET);
+ zfile_fread (header, sizeof (header), 1, z);
+ zfile_fseek (z, 0, SEEK_SET);
+ if (header[0] == 'P' && header[1] == 'K')
+ return 1;
+ return 0;
+}
+
static struct zfile *zuncompress (struct zfile *z)
{
char *name = z->name;
}
#endif
-/*
- * fopen() for a compressed file
- */
-struct zfile *zfile_fopen (const char *name, const char *mode)
+static struct zfile *zfile_fopen_2 (const char *name, const char *mode)
{
struct zfile *l;
FILE *f;
}
}
l->f = f;
+ return l;
+}
+
+static int zunzip (struct zfile *z, zfile_callback zc, void *user)
+{
+ unzFile uz;
+ unz_file_info file_info;
+ char filename_inzip[MAX_DPATH];
+ char tmp[MAX_DPATH], tmp2[2];
+ struct zfile *zf;
+ int err;
+
+ if (!zlib_test ())
+ return 0;
+ zf = 0;
+ uz = unzOpen (z);
+ if (!uz)
+ return 0;
+ if (unzGoToFirstFile (uz) != UNZ_OK)
+ return 0;
+ for (;;) {
+ err = unzGetCurrentFileInfo(uz, &file_info, filename_inzip, sizeof(filename_inzip), NULL, 0, NULL, 0);
+ if (err != UNZ_OK)
+ return 0;
+ if (file_info.uncompressed_size > 0) {
+ int err = unzOpenCurrentFile (uz);
+ if (err == UNZ_OK) {
+ tmp2[0] = FSDB_DIR_SEPARATOR;
+ tmp2[1] = 0;
+ strcpy (tmp, z->name);
+ strcat (tmp, tmp2);
+ strcat (tmp, filename_inzip);
+ zf = zfile_fopen_empty (tmp, file_info.uncompressed_size);
+ if (zf) {
+ err = unzReadCurrentFile (uz, zf->data, file_info.uncompressed_size);
+ unzCloseCurrentFile (uz);
+ if (err == 0 || err == file_info.uncompressed_size) {
+ zf = zuncompress (zf);
+ if (!zc (zf, user))
+ return 0;
+ }
+ }
+ }
+ }
+ err = unzGoToNextFile (uz);
+ if (err != UNZ_OK)
+ break;
+ }
+ return 1;
+}
+
+
+int zfile_zopen (const char *name, zfile_callback zc, void *user)
+{
+ struct zfile *l;
+
+ l = zfile_fopen_2 (name, "rb");
+ if (!l)
+ return 0;
+ if (!iszip (l)) {
+ zc (l, user);
+ } else {
+ zunzip (l, zc, user);
+ }
+ zfile_fclose (l);
+ return 1;
+}
+
+/*
+ * fopen() for a compressed file
+ */
+struct zfile *zfile_fopen (const char *name, const char *mode)
+{
+ struct zfile *l;
+ l = zfile_fopen_2 (name, mode);
+ if (!l)
+ return 0;
l = zuncompress (l);
return l;
}
char fname[2000];
FILE *f;
+ if (strlen (name) == 0)
+ return 0;
strcpy (fname, name);
f = openzip (fname, 0);
if (!f)
return zs.total_out;
}
+char *zfile_getname (struct zfile *f)
+{
+ return f->name;
+}
+
+uae_u32 zfile_crc32 (struct zfile *f)
+{
+ uae_u8 *p;
+ int pos = f->seek;
+ uae_u32 crc;
+
+ if (!f)
+ return 0;
+ if (f->data)
+ return get_crc32 (f->data, f->size);
+ p = xmalloc (f->size);
+ if (!p)
+ return 0;
+ zfile_fseek (f, 0, SEEK_SET);
+ zfile_fread (p, 1, f->size, f);
+ zfile_fseek (f, pos, SEEK_SET);
+ crc = get_crc32 (f->data, f->size);
+ xfree (p);
+ return crc;
+}