From 8cf5cb5cc2ef989f47c87af476d9ef93c964041f Mon Sep 17 00:00:00 2001 From: Toni Wilen Date: Sun, 4 Jul 2004 19:41:53 +0300 Subject: [PATCH] imported winuaesrc0990b6.zip --- autoconf.c | 1 - blitter.c | 3 +- cfgfile.c | 65 +- cia.c | 13 +- compemu_support.c | 1 - compiler.c | 4555 ----------------------- custom.c | 18 +- debug.c | 11 + disk.c | 156 +- ersatz.c | 9 +- filesys.c | 20 +- fsdb.c | 1 - gencomp.c | 1 - gencpu.c | 77 +- include/cia.h | 2 + include/compiler.h | 115 - include/disk.h | 4 +- include/fsdb.h | 1 + include/gfxfilter.h | 1 + include/gui.h | 10 + include/memory.h | 10 - include/newcpu.h | 31 +- include/options.h | 4 +- include/sysdeps.h | 8 +- include/zfile.h | 5 + main.c | 27 +- memory.c | 80 +- missing.c | 5 + moduleripper.c | 12 +- newcpu.c | 9 +- od-win32/blkdev_win32_aspi.c | 2 +- od-win32/caps/CapsAPI.h | 31 +- od-win32/caps/CapsLib.h | 1 + od-win32/caps/caps_win32.c | 73 +- od-win32/caps/caps_win32.h | 2 +- od-win32/dinput.c | 9 +- od-win32/dxwrap.c | 56 +- od-win32/dxwrap.h | 10 +- od-win32/fsdb_win32.c | 6 + od-win32/ioport.c | 23 +- od-win32/opengl.c | 39 +- od-win32/resources/avioutput.ico | Bin 1406 -> 1406 bytes od-win32/resources/bitmap1.bmp | Bin 1270 -> 0 bytes od-win32/resources/paths.ico | Bin 0 -> 318 bytes od-win32/resources/quickstart.ico | Bin 0 -> 318 bytes od-win32/resources/resource.h | 33 +- od-win32/resources/root.ico | Bin 318 -> 318 bytes od-win32/resources/screen.ico | Bin 1406 -> 1406 bytes od-win32/resources/winuae.rc | 438 ++- od-win32/sounddep/sound.c | 22 +- od-win32/win32.c | 231 +- od-win32/win32.h | 4 +- od-win32/win32_scale2x.c | 105 +- od-win32/win32gfx.c | 11 +- od-win32/win32gui.c | 806 ++-- od-win32/winuae_msvc/winuae_msvc.vcproj | 18 +- savestate.c | 5 +- unzip.c | 3 + zfile.c | 154 +- 59 files changed, 1838 insertions(+), 5499 deletions(-) delete mode 100755 compiler.c delete mode 100755 include/compiler.h delete mode 100755 od-win32/resources/bitmap1.bmp create mode 100755 od-win32/resources/paths.ico create mode 100755 od-win32/resources/quickstart.ico diff --git a/autoconf.c b/autoconf.c index 9ec9e294..0d94c4ff 100755 --- a/autoconf.c +++ b/autoconf.c @@ -17,7 +17,6 @@ #include "custom.h" #include "events.h" #include "newcpu.h" -#include "compiler.h" #include "autoconf.h" #include "osdep/exectasks.h" diff --git a/blitter.c b/blitter.c index 6c7dc53f..17738d61 100755 --- a/blitter.c +++ b/blitter.c @@ -116,7 +116,7 @@ static uae_u8 blit_cycle_diagram_fill[][10] = 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) @@ -807,6 +807,7 @@ static void blit_bltset (int con) 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); diff --git a/cfgfile.c b/cfgfile.c index 918df07e..1789e1ec 100755 --- a/cfgfile.c +++ b/cfgfile.c @@ -23,6 +23,7 @@ #include "gfxfilter.h" #include "savestate.h" #include "memory.h" +#include "gui.h" #define CONFIG_BLEN 2560 @@ -1039,6 +1040,10 @@ int cfgfile_parse_option (struct uae_prefs *p, char *option, char *value, int ty 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; @@ -1739,8 +1744,11 @@ static int configure_rom (struct uae_prefs *p, int *rom, int msg) 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) @@ -1854,7 +1862,7 @@ void default_prefs (struct uae_prefs *p, int type) p->curses_reverse_video = 0; - target_default_options (p); + target_default_options (p, type); p->immediate_blits = 0; p->collision_level = 2; @@ -1977,6 +1985,7 @@ static void buildin_default_prefs (struct uae_prefs *p) 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) @@ -1994,15 +2003,30 @@ 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; } } @@ -2104,16 +2128,14 @@ static int bip_a500 (struct uae_prefs *p, int config, int compa, int romcheck) 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; @@ -2121,7 +2143,14 @@ static int bip_a500 (struct uae_prefs *p, int config, int compa, int romcheck) 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; @@ -2129,7 +2158,7 @@ static int bip_a500 (struct uae_prefs *p, int config, int compa, int romcheck) 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; @@ -2142,7 +2171,7 @@ static int bip_a500 (struct uae_prefs *p, int config, int compa, int romcheck) 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) @@ -2150,14 +2179,16 @@ int build_in_prefs (struct uae_prefs *p, int model, int config, int compa, int r 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; diff --git a/cia.c b/cia.c index 33986ffd..a56116a2 100755 --- a/cia.c +++ b/cia.c @@ -309,6 +309,11 @@ void cia_diskindex (void) ciabicr |= 0x10; RethinkICRB(); } +void cia_parallelack (void) +{ + ciaaicr |= 0x10; + RethinkICRA(); +} static void ciab_checkalarm (void) { @@ -439,7 +444,7 @@ static uae_u8 ReadCIAA (unsigned int addr) 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) { @@ -533,7 +538,7 @@ static uae_u8 ReadCIAB (unsigned int addr) 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 (); @@ -610,7 +615,7 @@ static uae_u8 ReadCIAB (unsigned int addr) 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: @@ -755,7 +760,7 @@ static void WriteCIAA (uae_u16 addr,uae_u8 val) 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: diff --git a/compemu_support.c b/compemu_support.c index 26c4988e..b37a3c38 100755 --- a/compemu_support.c +++ b/compemu_support.c @@ -11,7 +11,6 @@ #include "include/memory.h" #include "custom.h" #include "newcpu.h" -#include "compiler.h" #include "comptbl.h" #include "compemu.h" diff --git a/compiler.c b/compiler.c deleted file mode 100755 index fd3ee040..00000000 --- a/compiler.c +++ /dev/null @@ -1,4555 +0,0 @@ - /* - * 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 - -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 */ diff --git a/custom.c b/custom.c index e14849d6..c0b43c1d 100755 --- a/custom.c +++ b/custom.c @@ -739,13 +739,15 @@ static int delayoffset; 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; } @@ -2835,12 +2837,10 @@ static void DDFSTRT (int hpos, uae_u16 v) 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; @@ -4116,7 +4116,7 @@ static void fpscounter (void) 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) diff --git a/debug.c b/debug.c index 4a00d83d..b67a8210 100755 --- a/debug.c +++ b/debug.c @@ -541,6 +541,7 @@ static struct memwatch_node mwnodes[MEMWATCH_TOTAL]; static struct memwatch_node mwhit; static uae_u8 *illgdebug; +static int illgdebug_break; extern int cdtv_enabled, cd32_enabled; static void illg_init (void) @@ -619,10 +620,16 @@ static void illg_debug_do (uaecptr addr, int rw, int size, uae_u32 val) 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 (); } } } @@ -847,6 +854,10 @@ static void memwatch (char **c) } 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; } diff --git a/disk.c b/disk.c index be921d69..e07c4fa5 100755 --- a/disk.c +++ b/disk.c @@ -31,6 +31,7 @@ #include "osemu.h" #include "execlib.h" #include "savestate.h" +#include "cia.h" #ifdef FDI2RAW #include "fdi2raw.h" #endif @@ -83,10 +84,7 @@ static uae_u8 writebuffer[544 * 11 * DDHDMULT]; #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 @@ -158,6 +156,7 @@ typedef struct { 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; @@ -548,6 +547,13 @@ static void reset_drive(int i) 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; @@ -586,18 +592,28 @@ static void drive_fill_bigbuf (drive * drv,int); 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) @@ -649,7 +665,7 @@ static int read_header_ext2 (struct zfile *diskfile, trackid *trackdata, int *nu return 1; } -static char *getwritefilename (const char *name) +char *DISK_get_saveimagepath (const char *name) { static char name1[MAX_DPATH]; char name2[MAX_DPATH]; @@ -679,7 +695,7 @@ static char *getwritefilename (const char *name) 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) @@ -1035,6 +1051,8 @@ static void drive_motor (drive * drv, int off) #endif #ifdef DISK_DEBUG2 write_dlog (" ->motor on"); + if (drv->indexhackmode > 0) + drv->indexhack = 1; #endif } if (!drv->motoroff && off) { @@ -1135,7 +1153,7 @@ static void drive_fill_bigbuf (drive * drv, int force) } 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) { @@ -1154,7 +1172,7 @@ static void drive_fill_bigbuf (drive * drv, int force) 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++) { @@ -1446,6 +1464,8 @@ static int drive_write_ext2 (uae_u16 *bigmfmbuf, struct zfile *diskfile, trackid 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; @@ -1456,7 +1476,11 @@ static void drive_write_data (drive * drv) 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; @@ -1610,6 +1634,12 @@ static void setdskchangetime(drive *drv, int dsktime) 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; @@ -1623,7 +1653,7 @@ int disk_setwriteprotect (int num, const char *name, int protect) 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); @@ -1639,8 +1669,7 @@ int disk_setwriteprotect (int num, const char *name, int protect) if (!needwritefile) diskfile_readonly (name, protect); diskfile_readonly (name2, protect); - drive_eject (&floppy[num]); - setdskchangetime (&floppy[num], 20); + DISK_reinsert (num); return 1; } @@ -1656,14 +1685,16 @@ void DISK_history_add (const char *name, int idx) { 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) { @@ -1683,8 +1714,6 @@ char *DISK_history_get (int idx) { if (idx >= MAX_PREVIOUS_FLOPPIES) return 0; - if (dfxhistory[idx][0] == 0) - return 0; return dfxhistory[idx]; } @@ -1781,6 +1810,17 @@ void DISK_select (uae_u8 data) 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)) @@ -1802,6 +1842,8 @@ void DISK_select (uae_u8 data) 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; } } } @@ -1861,7 +1903,7 @@ uae_u8 DISK_status (void) st &= ~0x20; #endif } else { - if (drv->dskready) + if (drv->dskready && !drv->indexhack) st &= ~0x20; } } else { @@ -1964,8 +2006,6 @@ static void fetchnextrevolution (drive *drv) } } -extern void cia_diskindex (void); - static int diskevent_flag; static int disk_sync_cycle; @@ -2070,6 +2110,7 @@ static void disk_doupdate_predict (drive * drv, int startcycle) int firstcycle = startcycle; uae_u32 tword = word; int mfmpos = drv->mfmpos; + int indexhack = drv->indexhack; diskevent_flag = 0; while (startcycle < (maxhpos << 8) && !diskevent_flag) { @@ -2089,17 +2130,21 @@ static void disk_doupdate_predict (drive * drv, int startcycle) 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; @@ -2156,13 +2201,20 @@ static void disk_doupdate_read (drive * drv, int floppybits) 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 @@ -2191,7 +2243,6 @@ static void disk_doupdate_read (drive * drv, int floppybits) dma_enable = 1; } } - bitoffset++; bitoffset &= 15; floppybits -= drv->trackspeed; @@ -2275,9 +2326,9 @@ void DISK_update (int tohpos) 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; @@ -2530,37 +2581,42 @@ void DISK_reset (void) 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) diff --git a/ersatz.c b/ersatz.c index 4b364fc0..0c4df382 100755 --- a/ersatz.c +++ b/ersatz.c @@ -76,7 +76,7 @@ static void ersatz_doio (void) default: write_log ("Only CMD_READ supported in DoIO()\n"); - abort(); + uae_restart (-1, NULL); } { uaecptr dest = get_long (request + 0x28); @@ -101,8 +101,7 @@ static void ersatz_init (void) 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; } @@ -225,7 +224,7 @@ void ersatz_perform (uae_u16 what) case EOP_NIMP: write_log ("Unimplemented Kickstart function called\n"); - uae_quit (); + uae_restart (-1, NULL); /* fall through */ case EOP_LOOP: @@ -235,6 +234,6 @@ void ersatz_perform (uae_u16 what) case EOP_OPENLIB: default: write_log ("Internal error. Giving up.\n"); - abort (); + uae_restart (-1, NULL); } } diff --git a/filesys.c b/filesys.c index 270b8821..c567aa44 100755 --- a/filesys.c +++ b/filesys.c @@ -37,7 +37,6 @@ #include "newcpu.h" #include "filesys.h" #include "autoconf.h" -#include "compiler.h" #include "fsusage.h" #include "native2amiga.h" #include "scsidev.h" @@ -54,11 +53,6 @@ #define DUMPLOCK(u,x) #endif -void xfree (void *p) -{ - free (p); -} - static void aino_test (a_inode *aino) { #ifdef AINO_DEBUG @@ -3774,6 +3768,18 @@ static char *device_dupfix (uaecptr expbase, char *devname) 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; @@ -3856,8 +3862,8 @@ static int rdb_mount (UnitInfo *uip, int unit_no, int partnum, uaecptr parmpacke 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; diff --git a/fsdb.c b/fsdb.c index 369b705b..7cfa24f5 100755 --- a/fsdb.c +++ b/fsdb.c @@ -19,7 +19,6 @@ #include "newcpu.h" #include "filesys.h" #include "autoconf.h" -#include "compiler.h" #include "fsusage.h" #include "native2amiga.h" #include "scsidev.h" diff --git a/gencomp.c b/gencomp.c index 884f83b3..39710edd 100755 --- a/gencomp.c +++ b/gencomp.c @@ -2870,7 +2870,6 @@ generate_includes (FILE * f) 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"); } diff --git a/gencpu.c b/gencpu.c index 2d8e15a1..c63707cd 100755 --- a/gencpu.c +++ b/gencpu.c @@ -354,7 +354,7 @@ static void fill_prefetch_next_delay (int extracycles) 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 { @@ -562,7 +562,10 @@ static void genamode (amodes mode, char *reg, wordsizes size, char *name, int ge 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; @@ -1177,7 +1180,7 @@ static void gen_opcode (unsigned long int opcode) 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; @@ -1187,7 +1190,7 @@ static void gen_opcode (unsigned long int opcode) 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; @@ -1638,7 +1641,6 @@ static void gen_opcode (unsigned long int opcode) 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"); @@ -1684,7 +1686,6 @@ static void gen_opcode (unsigned long int opcode) 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); @@ -1787,15 +1788,11 @@ static void gen_opcode (unsigned long int opcode) } 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"); @@ -1832,11 +1829,7 @@ static void gen_opcode (unsigned long int opcode) 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"); @@ -1852,7 +1845,7 @@ static void gen_opcode (unsigned long int opcode) 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); @@ -1883,10 +1876,15 @@ static void gen_opcode (unsigned long int opcode) 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"); @@ -1897,9 +1895,15 @@ static void gen_opcode (unsigned long int opcode) 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"); @@ -1915,8 +1919,15 @@ static void gen_opcode (unsigned long int opcode) 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"); @@ -1927,7 +1938,13 @@ static void gen_opcode (unsigned long int opcode) 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", "", ""); @@ -2819,7 +2836,6 @@ static void generate_includes (FILE * f) 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" @@ -2960,15 +2976,18 @@ static void generate_one_opcode (int rp) } 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; @@ -3038,8 +3057,6 @@ static void generate_one_opcode (int rp) 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"); diff --git a/include/cia.h b/include/cia.h index dbf92371..bd9f7892 100755 --- a/include/cia.h +++ b/include/cia.h @@ -12,6 +12,8 @@ extern void CIA_hsync_handler (void); 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); diff --git a/include/compiler.h b/include/compiler.h deleted file mode 100755 index 544a00e6..00000000 --- a/include/compiler.h +++ /dev/null @@ -1,115 +0,0 @@ - /* - * 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 diff --git a/include/disk.h b/include/disk.h index 12578095..199ccbca 100755 --- a/include/disk.h +++ b/include/disk.h @@ -26,7 +26,9 @@ extern void disk_creatediskfile (char *name, int type, drive_type adftype); 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); diff --git a/include/fsdb.h b/include/fsdb.h index 1c247d4d..b0127408 100755 --- a/include/fsdb.h +++ b/include/fsdb.h @@ -35,6 +35,7 @@ #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) diff --git a/include/gfxfilter.h b/include/gfxfilter.h index 17708208..cd941cd9 100755 --- a/include/gfxfilter.h +++ b/include/gfxfilter.h @@ -8,6 +8,7 @@ typedef unsigned long u32; 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; diff --git a/include/gui.h b/include/gui.h index 6f78f0c4..e865ce19 100755 --- a/include/gui.h +++ b/include/gui.h @@ -41,3 +41,13 @@ extern struct gui_info gui_data; /* 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; + diff --git a/include/memory.h b/include/memory.h index 60b58cd9..e7bf3501 100755 --- a/include/memory.h +++ b/include/memory.h @@ -45,16 +45,6 @@ extern void wait_cpu_cycle_write (uaecptr addr, int mode, uae_u32 v); #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 diff --git a/include/newcpu.h b/include/newcpu.h index 66b00703..3b2ccd1b 100755 --- a/include/newcpu.h +++ b/include/newcpu.h @@ -48,6 +48,7 @@ extern int fpp_movem_next[256]; #endif typedef unsigned long cpuop_func (uae_u32) REGPARAM; +typedef void cpuop_func_ce (uae_u32) REGPARAM; struct cputbl { cpuop_func *handler; @@ -154,15 +155,11 @@ STATIC_INLINE void unset_special (uae_u32 x) #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) { @@ -203,15 +200,29 @@ STATIC_INLINE uae_u32 next_ilong (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) { diff --git a/include/options.h b/include/options.h index d5e7ab6f..44b1ff12 100755 --- a/include/options.h +++ b/include/options.h @@ -52,6 +52,8 @@ struct uae_prefs { 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; @@ -246,7 +248,7 @@ extern char *cfgfile_subst_path (const char *path, const char *subst, const char 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 *); diff --git a/include/sysdeps.h b/include/sysdeps.h index 23bdcbff..6a78b428 100755 --- a/include/sysdeps.h +++ b/include/sysdeps.h @@ -227,6 +227,7 @@ extern char *my_strdup (const char*s); 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. */ @@ -432,13 +433,6 @@ extern void mallocemu_free (void *ptr); #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 diff --git a/include/zfile.h b/include/zfile.h index 8d6bd09d..c512efbc 100755 --- a/include/zfile.h +++ b/include/zfile.h @@ -9,6 +9,8 @@ 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); @@ -23,6 +25,9 @@ extern int zfile_iscompressed (struct zfile *z); 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 diff --git a/main.c b/main.c index f47a0ab1..88658040 100755 --- a/main.c +++ b/main.c @@ -32,7 +32,6 @@ #include "autoconf.h" #include "osemu.h" #include "osdep/exectasks.h" -#include "compiler.h" #include "picasso96.h" #include "bsdsocket.h" #include "uaeexe.h" @@ -376,12 +375,35 @@ static void parse_cmdline_2 (int argc, char **argv) } } +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) { @@ -642,7 +664,6 @@ static void real_main2 (int argc, char **argv) reset_frame_rate_hack (); init_m68k(); /* must come after reset_frame_rate_hack (); */ - compiler_init (); gui_update (); if (graphics_init ()) { diff --git a/memory.c b/memory.c index 2134d4d6..c4911cff 100755 --- a/memory.c +++ b/memory.c @@ -22,10 +22,7 @@ #include "savestate.h" #include "ar.h" #include "crc32.h" - -#ifdef USE_MAPPED_MEMORY -#include -#endif +#include "gui.h" #ifdef JIT int canbang; @@ -77,6 +74,8 @@ char *romlist_get (struct romdata *rd) { int i; + if (!rd) + return 0; for (i = 0; i < romlist_cnt; i++) { if (rl[i].rd == rd) return rl[i].path; @@ -95,26 +94,26 @@ static struct romdata roms[] = { { "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 }, @@ -1135,19 +1134,25 @@ uae_u8 *load_keyfile (struct uae_prefs *p, char *path, int *size) 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"); + } } } } @@ -1177,8 +1182,8 @@ static int decode_cloanto_rom (uae_u8 *mem, int size, int real_size) 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; } @@ -1200,7 +1205,7 @@ static int kickstart_checksum (uae_u8 *mem, int size) } #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; } @@ -1224,17 +1229,22 @@ int read_kickstart (struct zfile *f, uae_u8 *mem, int size, int dochecksum, int 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); @@ -1245,8 +1255,6 @@ int read_kickstart (struct zfile *f, uae_u8 *mem, int size, int dochecksum, int } if (dochecksum && i >= 262144) kickstart_checksum (mem, size); - if (cloanto_rom) - *cloanto_rom = cr; return i; } @@ -1259,7 +1267,7 @@ static int load_extendedkickstart (void) 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); @@ -1311,7 +1319,7 @@ static void kickstart_fix_checksum (uae_u8 *mem, int size) 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) { @@ -1634,7 +1642,7 @@ void map_overlay (int chip) void memory_reset (void) { - int custom_start; + int custom_start, bnk; be_cnt = 0; currprefs.chipmem_size = changed_prefs.chipmem_size; @@ -1657,10 +1665,13 @@ void memory_reset (void) 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 } } @@ -1671,12 +1682,11 @@ void memory_reset (void) 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) { @@ -1955,7 +1965,7 @@ uae_u8 *save_rom (int first, int *len, uae_u8 *dstptr) 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); diff --git a/missing.c b/missing.c index 27e62dcc..713735c8 100755 --- a/missing.c +++ b/missing.c @@ -42,3 +42,8 @@ void *xcalloc (size_t n, size_t size) } return a; } + +void xfree (void *p) +{ + free (p); +} diff --git a/moduleripper.c b/moduleripper.c index 954011b6..48bb226c 100755 --- a/moduleripper.c +++ b/moduleripper.c @@ -17,6 +17,7 @@ #include "memory.h" #include "autoconf.h" #include "moduleripper.h" +#include "gui.h" static int got, canceled; @@ -62,9 +63,9 @@ void moduleripper (void) } #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); } @@ -75,14 +76,15 @@ FILE *moduleripper_fopen (const char *name, const char *mode) 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) diff --git a/newcpu.c b/newcpu.c index 48a0e9b9..e02444e7 100755 --- a/newcpu.c +++ b/newcpu.c @@ -20,7 +20,6 @@ #include "autoconf.h" #include "ersatz.h" #include "debug.h" -#include "compiler.h" #include "gui.h" #include "savestate.h" #include "blitter.h" @@ -837,7 +836,6 @@ static void Exception_ce (int nr, uaecptr oldpc) int sv = regs.s; exception_debug (nr); - compiler_flush_jsr_stack(); MakeSR(); c = 0; @@ -944,7 +942,6 @@ static void Exception_normal (int nr, uaecptr oldpc) int sv = regs.s; exception_debug (nr); - compiler_flush_jsr_stack(); MakeSR(); if (!regs.s) { @@ -1527,9 +1524,8 @@ unsigned long REGPARAM2 op_illg (uae_u32 opcode) 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; } @@ -1702,9 +1698,6 @@ static int do_specialties (int cycles) do_copper (); } -#ifdef JIT - run_compiled_code(); -#endif if (regs.spcflags & SPCFLAG_DOTRACE) { Exception (9,last_trace_ad); } diff --git a/od-win32/blkdev_win32_aspi.c b/od-win32/blkdev_win32_aspi.c index ac4b1f10..873e5cb0 100755 --- a/od-win32/blkdev_win32_aspi.c +++ b/od-win32/blkdev_win32_aspi.c @@ -679,7 +679,7 @@ static int open_scsi_device (int unitnum) 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); diff --git a/od-win32/caps/CapsAPI.h b/od-win32/caps/CapsAPI.h index 5eaba9b2..efd7489b 100755 --- a/od-win32/caps/CapsAPI.h +++ b/od-win32/caps/CapsAPI.h @@ -14,6 +14,7 @@ // 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 @@ -23,6 +24,7 @@ #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 @@ -45,6 +47,16 @@ struct CapsDateTimeExt { 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 @@ -78,6 +90,22 @@ struct CapsTrackInfo { 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 @@ -118,7 +146,8 @@ enum { imgeDensityHeader, imgeDensityStream, imgeDensityData, - imgeIncompatible + imgeIncompatible, + imgeUnsupportedType }; #endif diff --git a/od-win32/caps/CapsLib.h b/od-win32/caps/CapsLib.h index bd2e4a63..dbb13da9 100755 --- a/od-win32/caps/CapsLib.h +++ b/od-win32/caps/CapsLib.h @@ -20,5 +20,6 @@ ExtSub SDWORD __cdecl CAPSLockTrack(PCAPSTRACKINFO pi, SDWORD id, UDWORD cylinde 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 diff --git a/od-win32/caps/caps_win32.c b/od-win32/caps/caps_win32.c index 195b5fce..831fbb32 100755 --- a/od-win32/caps/caps_win32.c +++ b/od-win32/caps/caps_win32.c @@ -6,6 +6,7 @@ #include "caps_win32.h" #include "zfile.h" +#include "gui.h" #include "ComType.h" #include "CapsAPI.h" @@ -13,34 +14,37 @@ 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; @@ -91,49 +95,70 @@ int caps_loadimage (struct zfile *zf, int drv, int *num_tracks) 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 @@ -142,8 +167,8 @@ int caps_loadtrack (uae_u16 *mfmbuf, uae_u16 *tracktiming, int drv, int track, i 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; } diff --git a/od-win32/caps/caps_win32.h b/od-win32/caps/caps_win32.h index 695818cb..7d534ebb 100755 --- a/od-win32/caps/caps_win32.h +++ b/od-win32/caps/caps_win32.h @@ -1,6 +1,6 @@ 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); diff --git a/od-win32/dinput.c b/od-win32/dinput.c index 04b0ebfd..121c143c 100755 --- a/od-win32/dinput.c +++ b/od-win32/dinput.c @@ -1222,7 +1222,10 @@ static int keyhack (int scancode,int pressed, int num) 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; } @@ -1235,8 +1238,8 @@ static int keyhack (int scancode,int pressed, int num) } 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 diff --git a/od-win32/dxwrap.c b/od-win32/dxwrap.c index 9b774515..4e79809a 100755 --- a/od-win32/dxwrap.c +++ b/od-win32/dxwrap.c @@ -56,8 +56,17 @@ static int restoresurface (LPDIRECTDRAWSURFACE7 surface) 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; } @@ -160,7 +169,7 @@ const char *DXError (HRESULT ddrval) return dderr; } -static struct DirectDrawSurfaceMapper DirectDrawState; +struct DirectDrawSurfaceMapper DirectDrawState; static int lockcnt = 0; @@ -200,6 +209,10 @@ static int LockStub( surface_type_e type ) 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; @@ -283,6 +296,10 @@ int DirectDraw_SurfaceLock( surface_type_e surface_type ) 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 ); @@ -1439,7 +1456,6 @@ HRESULT DirectDraw_CreatePalette( LPPALETTEENTRY pal ) 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; @@ -1676,6 +1692,10 @@ int DirectDraw_BltFast( surface_type_e dsttype, DWORD left, DWORD top, surface_t { lpDDS4_dst = DirectDrawState.primary.surface; } + else if (dsttype == temporary_surface) + { + lpDDS4_dst = DirectDrawState.temporary.surface; + } else { lpDDS4_dst = DirectDrawState.secondary.surface; @@ -1684,6 +1704,10 @@ int DirectDraw_BltFast( surface_type_e dsttype, DWORD left, DWORD top, surface_t { lpDDS4_src = DirectDrawState.primary.surface; } + else if (srctype == temporary_surface) + { + lpDDS4_src = DirectDrawState.temporary.surface; + } else { lpDDS4_src = DirectDrawState.secondary.surface; @@ -1855,6 +1879,10 @@ int DirectDraw_Blt( surface_type_e dsttype, LPRECT dstrect, { lpDDS4_dst = DirectDrawState.tertiary.surface; } + else if( dsttype == temporary_surface ) + { + lpDDS4_dst = DirectDrawState.temporary.surface; + } else { lpDDS4_dst = DirectDrawState.overlay.surface; @@ -1872,6 +1900,10 @@ int DirectDraw_Blt( surface_type_e dsttype, LPRECT dstrect, { 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; @@ -2053,4 +2085,20 @@ char *outGUID (GUID *guid) 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; +} diff --git a/od-win32/dxwrap.h b/od-win32/dxwrap.h index 9ae22ddf..9425ef85 100755 --- a/od-win32/dxwrap.h +++ b/od-win32/dxwrap.h @@ -135,7 +135,8 @@ typedef enum secondary_surface, tertiary_surface, overlay_surface, - lockable_surface + lockable_surface, + temporary_surface } surface_type_e; typedef enum @@ -180,6 +181,11 @@ struct DirectDrawSurfaceMapper DDSURFACEDESC2 desc; } overlay; struct + { + LPDIRECTDRAWSURFACE7 surface; + DDSURFACEDESC2 desc; + } temporary; + struct { DDSURFACEDESC2 desc; } current; @@ -238,6 +244,8 @@ DWORD DirectDraw_CurrentWidth( void ); 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() diff --git a/od-win32/fsdb_win32.c b/od-win32/fsdb_win32.c index 599c3ef9..f0fd6e75 100755 --- a/od-win32/fsdb_win32.c +++ b/od-win32/fsdb_win32.c @@ -96,6 +96,8 @@ int fsdb_fill_file_attrs (a_inode *aino) 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; } @@ -123,6 +125,10 @@ int fsdb_set_file_attrs (a_inode *aino, int mask) 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); } diff --git a/od-win32/ioport.c b/od-win32/ioport.c index b7a6b4f3..5da1726e 100755 --- a/od-win32/ioport.c +++ b/od-win32/ioport.c @@ -6,7 +6,7 @@ //#define IOPORT_EMU #define io_log -//#define io_log write_log +#define para_log write_log typedef int bool; @@ -170,13 +170,13 @@ int parallel_direct_write_status (uae_u8 v, uae_u8 dir) 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; } @@ -185,6 +185,7 @@ int parallel_direct_read_status (uae_u8 *vp) PARAPORT_CYCLE c[1]; int ok = 1; uae_u8 v = 0; + static int oldack; if (!pport) return 0; @@ -198,11 +199,17 @@ int parallel_direct_read_status (uae_u8 *vp) 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; @@ -232,7 +239,7 @@ int parallel_direct_write_data (uae_u8 v, uae_u8 dir) 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; } @@ -257,7 +264,7 @@ int parallel_direct_read_data (uae_u8 *v) 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; } diff --git a/od-win32/opengl.c b/od-win32/opengl.c index 43e16bf7..63085374 100755 --- a/od-win32/opengl.c +++ b/od-win32/opengl.c @@ -20,6 +20,7 @@ #include "gfxfilter.h" #ifdef OPENGL +//#define FSAA #include #include @@ -36,6 +37,7 @@ typedef BOOL (WINAPI * PFNWGLCHOOSEPIXELFORMATARBPROC) (HDC, const int *, const #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]; @@ -78,7 +80,8 @@ static int exact_log2 (int v) 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) @@ -123,7 +126,7 @@ 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; @@ -139,7 +142,7 @@ static int InitMultisample(HDC hDC, PIXELFORMATDESCRIPTOR *pfd, int depth) 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, @@ -165,10 +168,12 @@ static int InitMultisample(HDC hDC, PIXELFORMATDESCRIPTOR *pfd, int depth) 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 @@ -199,15 +204,15 @@ const char *OGL_init (HWND ahwnd, int w_w, int w_h, int t_w, int t_h, int depth) 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) { @@ -234,18 +239,19 @@ const char *OGL_init (HWND ahwnd, int w_w, int w_h, int t_w, int t_h, int depth) 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", @@ -468,6 +474,9 @@ static void OGL_dorender (int newtex) 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 (); @@ -500,6 +509,10 @@ static void OGL_dorender (int newtex) glTexCoord2f (1.0f, -1.0f); glVertex2f (v, 0); glEnd(); } + glFlush (); +#ifdef FSAA + glDisable (GL_MULTISAMPLE_ARB); +#endif } void OGL_render (void) diff --git a/od-win32/resources/avioutput.ico b/od-win32/resources/avioutput.ico index 30b40d932dc6cb9f374238c6d53a6e623cbb5a85..59cf0bed3d2c279e36a1dd6fa52d1f6adffb183a 100755 GIT binary patch literal 1406 zcmeH{u}*_f6o!9prPRU|E|hCaN$My`Cm#UUIyiM^XENz%(!r^5l+icv348)ZU!ao? zINH52@p?|1)&ME$~_PU~We+j~6h{S1|84$S;90)z|AaR;v}7ronQ#L|xY#pQ@^`SS&D~&oP_L zP?jZ%qQG=I#bh!;p6AH23~?OqpLBIn_ZLtPS5U7vNH2jt)wkO%Hk%FB>or!Z6_(2-7K;Vu^Eqa-877kn z#^W*aJV%yg7>!044u?q76obJ4Ns=H4g5vwf!*K$~3H;9l#NTRlSgr436HQhTG+1$i zeZ+t6#U6`n=tMG#YOJ^>L6@9K5-<+9=ItOzyF^?lzx-Fp#+LbTid!Tx&k>if_EMf;F> YAs&e-L;2JqdOx5YI3=F$=zRrz0`l!c?*IS* diff --git a/od-win32/resources/bitmap1.bmp b/od-win32/resources/bitmap1.bmp deleted file mode 100755 index df1851c7c6ca26c03e0906d05242c64a54306f82..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 1270 zcmeHGK@!3s42(10<1;+^2Je2yGf(45IeDeKDToj}IO9zNX~VKzlC-_v9!GJz<9dc) zsvl(ENOhm2Q+387$)}{m2#$du=Zrg%;!{dt1jiu6^^cqAvH@@UVoP$dwa6#1$tn|T z;CMh69`Hs+l8Vvn3HwWrC73F{gI65SA|GNp5ChRb3=&ZQVnzlQAj!bc045;>NDiWdf#LuE{|xWmy<>Rt zQJb967?Ud-raJ4I4Hv%$_})VdBJz3~g;~46(7X40d*QNTwi|+-Jbx0Jox& zQ1(v21KdJ_irIonKz`cn-C%y&Mny#kf2R;g9*u97IY|g4?!9}Wq9Tx11cL)yP;*&J aSAf6**3fVe2!PoPbUH%=(9h&xkX`^$WKR45 literal 0 HcmV?d00001 diff --git a/od-win32/resources/quickstart.ico b/od-win32/resources/quickstart.ico new file mode 100755 index 0000000000000000000000000000000000000000..df673484c4b848d35d59d648bfc99b86d2d81b19 GIT binary patch literal 318 zcmb7=%MAiC3`A!IoDd?x5?qnE>?MZq_oV@&CShONht*kl$6rk)|_#3R8mp{ n@sofCtEGv#11Tr~IUR&Q@G~$xU}s=Bz)To})cpXe2k8RSftpuvvT%11|h}OAU>av;yzsbLP5v$I3dMtZb0BHq?iH*Lh5O5 td+)kA7Acj1_~}3k%F@K#;g%|aoc@8If#Co%149GQ@5Eq`T96))UI1$JN{j#i diff --git a/od-win32/resources/screen.ico b/od-win32/resources/screen.ico index ce897d662ff1bdf650c5332bbf5454bf7fa55965..c165ac541539adf29a2ff55fa8e06acfb218af00 100755 GIT binary patch literal 1406 zcmeH{u}*|Q5QaZs;r8UbJup~X+FwsiPb}$aDX#Vk!vh#Q9>B!Xmd0oB348&c0cQa3 z5-qGv_&5LT&j0UDHd73EvUWQpTIvw4fm@+S+z3_w##IbT5l0NeFz%nS9q!@j86F$_mkul)_%|K!{={~(*-l8u zyQ#ISi`cm|opMhO6XsHvI&Ew`+xCRD(+4Es4C@jRNFv`v#+dM&M=G3ieD%%A2j7pv tldqmJK_LEEe>cNA{m^;zt=0Ys9e>KV)x-}6%3~mu8TpH<%Uz|u`vT7>ElL0Y literal 1406 zcmeH{p-#j=6h-f_EL(Plof&pZa7FSJ)fFU&>h)`D_=J7|V2VO?{o014f-gWJkQEpb zB!Z;8*O?Zvd;p?na;JTFdS8<#1`xE20qp@cQ{W81C5bFtkl628N`OUXN87gD^L7io z((CR8czgotci`&o4eRm)HxJJ^zrIJ)G^nZyWm%#q3gmf?EX$ClDUu{X9LI>F2w@ny z=Hot2V4T3eo`CoRH4B0hZS5-bhbvECi}{imDj}@3b2}JDf|jNZoL?-YM`?~ob?i}^ zBhpMfO53hJ^0*r2(9@q!JuVM(;BozN+M_i8Uk&qjHG9AC_4hdezDVDiG;?)L_hU`T LJ+V*UvN-z#1~E7$ diff --git a/od-win32/resources/winuae.rc b/od-win32/resources/winuae.rc index ffd62f04..c0f5dde5 100755 --- a/od-win32/resources/winuae.rc +++ b/od-win32/resources/winuae.rc @@ -53,10 +53,12 @@ BEGIN 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 @@ -141,28 +143,28 @@ BEGIN 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 | @@ -204,15 +206,16 @@ BEGIN 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 | @@ -222,7 +225,7 @@ BEGIN 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 | @@ -232,37 +235,47 @@ BEGIN 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 @@ -272,20 +285,22 @@ FONT 8, "MS Sans Serif", 0, 0, 0x1 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 @@ -317,25 +332,28 @@ 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 @@ -390,32 +408,38 @@ BEGIN 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 @@ -476,23 +500,21 @@ FONT 8, "MS Sans Serif", 0, 0, 0x1 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 @@ -521,54 +543,55 @@ BEGIN 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 @@ -595,35 +618,44 @@ STYLE DS_SETFONT | DS_3DLOOK | DS_CONTROL | WS_CHILD 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 @@ -703,11 +735,11 @@ BEGIN 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 | @@ -740,7 +772,7 @@ BEGIN 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 @@ -748,19 +780,19 @@ BEGIN 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 @@ -856,48 +888,51 @@ BEGIN 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 @@ -954,6 +989,8 @@ IDI_SOUND ICON "sound.ico" 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" ///////////////////////////////////////////////////////////////////////////// // @@ -1008,19 +1045,9 @@ IDC_MYHAND CURSOR "H_arrow.cur" #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 @@ -1034,9 +1061,9 @@ BEGIN BOTTOMMARGIN, 212 END - IDD_MISC1, DIALOG + IDD_FILESYS, DIALOG BEGIN - BOTTOMMARGIN, 215 + RIGHTMARGIN, 229 END IDD_INPUT, DIALOG @@ -1044,11 +1071,6 @@ BEGIN BOTTOMMARGIN, 187 END - IDD_FILTER, DIALOG - BEGIN - RIGHTMARGIN, 292 - END - IDD_PANEL, DIALOG BEGIN LEFTMARGIN, 7 @@ -1202,7 +1224,6 @@ BEGIN 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" @@ -1298,6 +1319,33 @@ BEGIN 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 ///////////////////////////////////////////////////////////////////////////// diff --git a/od-win32/sounddep/sound.c b/od-win32/sounddep/sound.c index 86bd5e6b..57d232aa 100755 --- a/od-win32/sounddep/sound.c +++ b/od-win32/sounddep/sound.c @@ -147,6 +147,7 @@ static int restore (DWORD hr) //write_log ("restore failed %s\n", DXError (hr)); return 1; } + pause_audio_ds (); resume_audio_ds (); return 1; } @@ -487,13 +488,26 @@ void sound_setadjust (double v) 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) { @@ -520,6 +534,12 @@ static void finish_sound_buffer_ds (void) 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; diff --git a/od-win32/win32.c b/od-win32/win32.c index 3df7cb1c..6dfe20bf 100755 --- a/od-win32/win32.c +++ b/od-win32/win32.c @@ -1386,7 +1386,9 @@ void logging_init( void ) #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." @@ -1405,22 +1407,26 @@ void logging_cleanup( void ) 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) @@ -1532,8 +1538,10 @@ void fetch_saveimagepath (char *out, int size, int dir) 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\\"); @@ -1542,7 +1550,14 @@ void fetch_path (char *name, char *out, int size) 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) { @@ -1578,7 +1593,7 @@ static void initpath (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; @@ -1594,7 +1609,7 @@ void read_rom_list (void) 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 (;;) { @@ -1616,16 +1631,52 @@ void read_rom_list (void) } } +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, @@ -1680,8 +1731,16 @@ static void WIN32_HandleRegistryStuff( void ) 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 */ @@ -1703,8 +1762,8 @@ static void WIN32_HandleRegistryStuff( void ) /* 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; @@ -1714,10 +1773,13 @@ static void WIN32_HandleRegistryStuff( void ) 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) @@ -1751,17 +1813,65 @@ static int dxdetect (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; iGroupCount; 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; @@ -1784,51 +1894,9 @@ static int osdetect (void) 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;xGroupCount;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) @@ -1839,7 +1907,6 @@ static int PASCAL WinMain2 (HINSTANCE hInstance, HINSTANCE hPrevInstance, LPSTR int argc; int i; int multi_display = 1; - char tmp[MAX_DPATH]; #ifdef __GNUC__ __asm__ ("leal -2300*1024(%%esp),%0" : "=r" (win32_stackbase) :); @@ -1871,6 +1938,7 @@ __asm{ #ifdef AVIOUTPUT AVIOutput_Initialize(); #endif + init_zlib (); #ifdef __MINGW32__ argc = _argc; argv = _argv; @@ -1903,8 +1971,6 @@ __asm{ 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 (); @@ -1943,7 +2009,6 @@ __asm{ DirectDraw_Release(); betamessage (); keyboard_settrans (); - init_zlib (); #ifdef PARALLEL_PORT paraport_mask = paraport_init (); #endif @@ -2077,7 +2142,7 @@ static LONG WINAPI ExceptionFilter( struct _EXCEPTION_POINTERS * pExceptionPoint 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; } } diff --git a/od-win32/win32.h b/od-win32/win32.h index 117da519..2b477b4a 100755 --- a/od-win32/win32.h +++ b/od-win32/win32.h @@ -21,7 +21,7 @@ extern int manual_painting_needed; 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); @@ -94,6 +94,6 @@ void systraymenu (HWND hwnd); 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 diff --git a/od-win32/win32_scale2x.c b/od-win32/win32_scale2x.c index 3466b956..f9d4b7da 100755 --- a/od-win32/win32_scale2x.c +++ b/od-win32/win32_scale2x.c @@ -8,6 +8,7 @@ #include "win32.h" #include "win32gfx.h" #include "gfxfilter.h" +#include "dxwrap.h" struct uae_filter uaefilters[] = { @@ -36,6 +37,7 @@ 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) { @@ -44,9 +46,17 @@ 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) { @@ -63,13 +73,35 @@ void S2X_init (int dw, int dh, int aw, int ah, int mult, int ad, int dd) 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; @@ -94,15 +126,68 @@ void S2X_render (void) 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 */ @@ -182,8 +267,12 @@ void S2X_render (void) 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) diff --git a/od-win32/win32gfx.c b/od-win32/win32gfx.c index aca67e18..fb1d19cd 100755 --- a/od-win32/win32gfx.c +++ b/od-win32/win32gfx.c @@ -1592,6 +1592,7 @@ uae_u32 OSDEP_minimize_uae( void ) void close_windows (void) { + S2X_free (); free (gfxvidinfo.realbufmem); gfxvidinfo.realbufmem = 0; DirectDraw_Release(); @@ -1751,8 +1752,8 @@ static void setoverlay(void) 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; @@ -2003,8 +2004,10 @@ static BOOL doInit (void) 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; diff --git a/od-win32/win32gui.c b/od-win32/win32gui.c index 5657384b..af76fd14 100755 --- a/od-win32/win32gui.c +++ b/od-win32/win32gui.c @@ -114,7 +114,7 @@ static int LOADSAVE_ID = -1, MEMORY_ID = -1, KICKSTART_ID = -1, CPU_ID = -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) { @@ -123,6 +123,19 @@ 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; @@ -147,26 +160,25 @@ 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; @@ -184,14 +196,40 @@ static struct romdata *scan_rom (char *path, uae_u8 *keybuf, int keysize) 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; @@ -259,7 +297,7 @@ static void show_rom_list (void) 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; @@ -281,30 +319,33 @@ int scan_roms (char *pathp) 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; } @@ -801,16 +842,16 @@ int DiskSelection( HWND hDlg, WPARAM wParam, int flag, struct uae_prefs *prefs, 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) @@ -1106,6 +1147,7 @@ static char *HandleConfiguration (HWND hDlg, int flag, struct ConfigStruct *conf strcat (name, ".uae"); SetDlgItemText (hDlg, IDC_EDITNAME, name); } + strcpy (config->Name, name); } GetDlgItemText (hDlg, IDC_EDITDESCRIPTION, desc, MAX_DPATH); if (config) { @@ -1128,7 +1170,7 @@ static char *HandleConfiguration (HWND hDlg, int flag, struct ConfigStruct *conf 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); @@ -1357,8 +1399,8 @@ void InitializeListView( HWND hDlg ) 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) @@ -1808,7 +1850,7 @@ static BOOL CALLBACK LoadSaveDlgProc (HWND hDlg, UINT msg, WPARAM wParam, LPARAM 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; @@ -1823,6 +1865,7 @@ static BOOL CALLBACK LoadSaveDlgProc (HWND hDlg, UINT msg, WPARAM wParam, LPARAM recursive++; config = CreateConfigStore (config); config = fixloadconfig (hDlg, config); + ConfigToRegistry (config, configtypepanel); InitializeConfigTreeView (hDlg); recursive--; break; @@ -1831,6 +1874,7 @@ static BOOL CALLBACK LoadSaveDlgProc (HWND hDlg, UINT msg, WPARAM wParam, LPARAM recursive++; config = CreateConfigStore (config); config = fixloadconfig (hDlg, config); + ConfigToRegistry (config, configtypepanel); InitializeConfigTreeView (hDlg); recursive--; break; @@ -2108,8 +2152,12 @@ static void resetregistry (void) 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"); @@ -2118,6 +2166,7 @@ static void resetregistry (void) RegDeleteValue (hWinUAEKey, "QuickStartModel"); RegDeleteValue (hWinUAEKey, "QuickStartConfiguration"); RegDeleteValue (hWinUAEKey, "QuickStartCompatibility"); + RegDeleteValue (hWinUAEKey, "QuickStartHostConfig"); } static BOOL CALLBACK PathsDlgProc (HWND hDlg, UINT msg, WPARAM wParam, LPARAM lParam) @@ -2211,43 +2260,16 @@ static BOOL CALLBACK PathsDlgProc (HWND hDlg, UINT msg, WPARAM wParam, LPARAM lP 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 } }; @@ -2255,26 +2277,59 @@ struct amigaconfig { 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 } }; @@ -2305,14 +2360,28 @@ static void quickstarthost (HWND hDlg, char *name) 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]; @@ -2341,36 +2410,42 @@ static void init_quickstartdlg (HWND hDlg) 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"); @@ -2395,21 +2470,27 @@ static void init_quickstartdlg (HWND hDlg) } } -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: @@ -2438,7 +2519,7 @@ static void testimage (HWND hDlg) 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) { @@ -2452,21 +2533,31 @@ static BOOL CALLBACK FloppyDlgProc (HWND hDlg, UINT msg, WPARAM wParam, LPARAM l 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; @@ -2476,12 +2567,22 @@ static BOOL CALLBACK QuickstartDlgProc (HWND hDlg, UINT msg, WPARAM wParam, LPAR { 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: @@ -2494,14 +2595,6 @@ static BOOL CALLBACK QuickstartDlgProc (HWND hDlg, UINT msg, WPARAM wParam, LPAR 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) { @@ -2540,14 +2633,28 @@ static BOOL CALLBACK QuickstartDlgProc (HWND hDlg, UINT msg, WPARAM wParam, LPAR 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; } @@ -3167,9 +3274,11 @@ static void values_to_chipsetdlg (HWND hDlg) 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; @@ -3202,8 +3311,10 @@ static void values_from_chipsetdlg (HWND hDlg, UINT msg, WPARAM wParam, LPARAM l 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; } @@ -3213,7 +3324,9 @@ static void values_from_chipsetdlg (HWND hDlg, UINT msg, WPARAM wParam, LPARAM l : 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; @@ -3431,7 +3544,7 @@ static void addromfiles (HKEY fkey, HWND hDlg, DWORD d, char *path, uae_u8 *keyb 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; @@ -3628,7 +3741,6 @@ static void enable_for_miscdlg (HWND hDlg) 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 ); @@ -3715,7 +3827,6 @@ static void values_to_miscdlg (HWND hDlg) 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 ); @@ -3768,13 +3879,27 @@ static BOOL MiscDlgProc (HWND hDlg, UINT msg, WPARAM wParam, LPARAM lParam) 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); @@ -3835,9 +3960,6 @@ static BOOL MiscDlgProc (HWND hDlg, UINT msg, WPARAM wParam, LPARAM lParam) 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; @@ -3881,8 +4003,11 @@ static void enable_for_cpudlg (HWND hDlg) /* 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) @@ -4021,6 +4146,8 @@ static void values_from_cpudlg (HWND hDlg) 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 @@ -4127,6 +4254,7 @@ static void enable_for_sounddlg (HWND hDlg) 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 ); @@ -4137,6 +4265,7 @@ static void enable_for_sounddlg (HWND hDlg) 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 ); @@ -4214,7 +4343,12 @@ static void update_soundgui (HWND hDlg) 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 }; @@ -4582,6 +4716,8 @@ static void sethardfile (HWND hDlg) 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) @@ -4660,6 +4796,18 @@ static int CALLBACK HardfileSettingsProc (HWND hDlg, UINT msg, WPARAM wParam, LP 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; } } @@ -4671,7 +4819,6 @@ static int CALLBACK HardfileSettingsProc (HWND hDlg, UINT msg, WPARAM wParam, LP 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; @@ -4873,20 +5020,26 @@ static void harddiskdlg_button (HWND hDlg, int button) 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: @@ -4910,6 +5063,10 @@ static void harddiskdlg_button (HWND hDlg, int button) case IDC_MAPDRIVES: workprefs.win32_automount_drives = IsDlgButtonChecked( hDlg, button ); break; + + case IDC_NOUAEFSDB: + workprefs.filesys_no_uaefsdb = IsDlgButtonChecked( hDlg, IDC_NOUAEFSDB ); + break; } } @@ -4949,10 +5106,11 @@ static BOOL CALLBACK HarddiskDlgProc (HWND hDlg, UINT msg, WPARAM wParam, LPARAM 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; @@ -5034,85 +5192,109 @@ static void out_floppyspeed (HWND hDlg) 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; @@ -5143,15 +5325,20 @@ static void getfloppyname (HWND hDlg, int n) 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) @@ -5168,6 +5355,16 @@ static void floppysetwriteprotect (HWND hDlg, int n, int protect) 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; @@ -5324,6 +5521,18 @@ static BOOL CALLBACK FloppyDlgProc (HWND hDlg, UINT msg, WPARAM wParam, LPARAM l 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; @@ -5335,7 +5544,7 @@ static BOOL CALLBACK FloppyDlgProc (HWND hDlg, UINT msg, WPARAM wParam, LPARAM l 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; @@ -6186,8 +6395,8 @@ static void enable_for_hw3ddlg (HWND hDlg) 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); @@ -6282,8 +6491,6 @@ static void values_to_hw3ddlg (HWND hDlg) 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]) { @@ -6393,10 +6600,8 @@ static void filter_preset (HWND hDlg, WPARAM wParam) 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); @@ -6834,6 +7039,58 @@ struct GUIPAGE { 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 @@ -6842,15 +7099,20 @@ static struct GUIPAGE ppage[MAX_C_PAGES]; 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 ()) { @@ -6867,6 +7129,7 @@ static HWND updatePanel (HWND hDlg, int id) EnableWindow (GetDlgItem (hDlg, IDHELP), FALSE); return NULL; } + GetWindowRect (GetDlgItem (hDlg, IDC_PANEL_FRAME), &r1w); GetClientRect (GetDlgItem (hDlg, IDC_PANEL_FRAME), &r1c); GetWindowRect (hDlg, &r2w); @@ -6892,6 +7155,23 @@ static HWND updatePanel (HWND hDlg, int id) 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; } @@ -7028,11 +7308,12 @@ int dragdrop (HWND hDlg, HDROP hd, struct uae_prefs *prefs, int currentpage) 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: @@ -7153,8 +7434,7 @@ static BOOL CALLBACK DialogProc(HWND hDlg, UINT msg, WPARAM wParam, LPARAM lPara case IDCANCEL: updatePanel (hDlg, -1); EndDialog (hDlg, 0); - if (allow_quit) - { + if (allow_quit) { quit_program = 1; regs.spcflags |= SPCFLAG_BRK; } @@ -7175,7 +7455,7 @@ static int init_page (int tmpl, int icon, int title, 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; @@ -7222,8 +7502,8 @@ static int GetSettings (int all_options, HWND hwnd) #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; @@ -7373,6 +7653,8 @@ void gui_filename (int num, const char *name) static int fsdialog (HWND *hwnd, DWORD *flags) { + HRESULT hr; + if (gui_active) { *hwnd = guiDlg; *flags |= MB_SETFOREGROUND; @@ -7381,6 +7663,9 @@ static int fsdialog (HWND *hwnd, DWORD *flags) *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; /* @@ -7457,14 +7742,18 @@ void gui_message (const char *format,...) 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"); @@ -7498,6 +7787,59 @@ void pre_gui_message (const char *format,...) } +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) { } diff --git a/od-win32/winuae_msvc/winuae_msvc.vcproj b/od-win32/winuae_msvc/winuae_msvc.vcproj index 4bc7835f..aceabe93 100755 --- a/od-win32/winuae_msvc/winuae_msvc.vcproj +++ b/od-win32/winuae_msvc/winuae_msvc.vcproj @@ -180,9 +180,6 @@ - - @@ -213,6 +210,15 @@ + + + + + + @@ -377,9 +383,6 @@ - - @@ -488,9 +491,6 @@ - - diff --git a/savestate.c b/savestate.c index 620ef06f..85c76065 100755 --- a/savestate.c +++ b/savestate.c @@ -57,8 +57,9 @@ #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 { @@ -506,7 +507,7 @@ void save_state (char *filename, char *description) #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 diff --git a/unzip.c b/unzip.c index e311918e..887441c3 100755 --- a/unzip.c +++ b/unzip.c @@ -4,6 +4,9 @@ Read unzip.h for more info */ +#include "sysconfig.h" +#include "sysdeps.h" + #include #include #include diff --git a/zfile.c b/zfile.c index 3e626e0d..9a0c55a4 100755 --- a/zfile.c +++ b/zfile.c @@ -16,6 +16,8 @@ #include "unzip.h" #include "disk.h" #include "dms/pfile.h" +#include "gui.h" +#include "crc32.h" #include @@ -35,20 +37,14 @@ int is_zlib; 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) @@ -72,9 +68,9 @@ static void zfile_free (struct zfile *f) 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) @@ -385,7 +381,6 @@ static struct zfile *unzip (struct zfile *z) return z; if (unzGoToFirstFile (uz) != UNZ_OK) return z; - write_log("checking zip file '%s':\n", z->name); zipcnt = 1; tmphist[0] = 0; for (;;) { @@ -393,7 +388,6 @@ static struct zfile *unzip (struct zfile *z) 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]) && @@ -401,9 +395,7 @@ static struct zfile *unzip (struct zfile *z) break; i++; } - if (ignoreextensions[i]) { - write_log ("[ignored]"); - } else { + if (!ignoreextensions[i]) { if (tmphist[0]) { DISK_history_add (tmphist, -1); tmphist[0] = 0; @@ -417,7 +409,6 @@ static struct zfile *unzip (struct zfile *z) DISK_history_add (tmphist, -1); tmphist[0] = 0; } - write_log ("[check]"); select = 0; if (!z->zipname) select = 1; @@ -427,7 +418,6 @@ static struct zfile *unzip (struct zfile *z) 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) { @@ -437,7 +427,6 @@ static struct zfile *unzip (struct zfile *z) zf = zuncompress (zf); if (select < 0 || zfile_gettype (zf)) { we_have_file = 1; - write_log("[ok]"); } } } @@ -445,12 +434,9 @@ static struct zfile *unzip (struct zfile *z) zfile_fclose (zf); zf = 0; } - } else { - write_log ("\nunzipping failed %d", err); } } } - write_log("\n"); } zipcnt++; err = unzGoToNextFile (uz); @@ -464,6 +450,23 @@ static struct zfile *unzip (struct zfile *z) 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; @@ -563,10 +566,7 @@ static struct zfile *zfile_opensinglefile(struct zfile *l) } #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; @@ -597,6 +597,83 @@ struct zfile *zfile_fopen (const char *name, const char *mode) } } 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; } @@ -606,6 +683,8 @@ int zfile_exists (const char *name) char fname[2000]; FILE *f; + if (strlen (name) == 0) + return 0; strcpy (fname, name); f = openzip (fname, 0); if (!f) @@ -745,4 +824,29 @@ int zfile_zcompress (struct zfile *f, void *src, int size) 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; +} -- 2.47.3