From: Toni Wilen Date: Sat, 23 Jun 2007 10:45:39 +0000 (+0300) Subject: imported winuaesrc1430b6.zip X-Git-Tag: 2100~216 X-Git-Url: https://git.unchartedbackwaters.co.uk/w/?a=commitdiff_plain;h=35fd8e9ea6f81755e63a8cdbe5444cabdad4a57a;p=francis%2Fwinuae.git imported winuaesrc1430b6.zip --- diff --git a/archivers/xfd/xfd.c b/archivers/xfd/xfd.c index 2d08dde5..f0880cfa 100755 --- a/archivers/xfd/xfd.c +++ b/archivers/xfd/xfd.c @@ -236,12 +236,12 @@ int init_xfd(void) codememory = 0x2000; codeptr = malloc (FAKEMEM_SIZE); - sprintf (tmp, "%suae_data%cxfd", start_path_data, FSDB_DIR_SEPARATOR); + sprintf (tmp, "%splugins%cxfd", start_path_data, FSDB_DIR_SEPARATOR); d = my_opendir(tmp); if (d) { while(my_readdir(d, tmp)) { char tmp2[MAX_DPATH]; - sprintf (tmp2, "%suae_data%cxfd%c%s", start_path_data, FSDB_DIR_SEPARATOR, FSDB_DIR_SEPARATOR, tmp); + sprintf (tmp2, "%splugins%cxfd%c%s", start_path_data, FSDB_DIR_SEPARATOR, FSDB_DIR_SEPARATOR, tmp); load_xfd(tmp2); } my_closedir(d); diff --git a/filesys_bootrom.c b/filesys_bootrom.c index 09211a0a..6c62c9e8 100755 --- a/filesys_bootrom.c +++ b/filesys_bootrom.c @@ -1,35 +1,35 @@ db(0x00); db(0x00); db(0x00); db(0x10); db(0x00); db(0x00); db(0x00); db(0x00); - db(0x60); db(0x00); db(0x04); db(0xf6); db(0x00); db(0x00); db(0x03); db(0xb2); + db(0x60); db(0x00); db(0x04); db(0xee); db(0x00); db(0x00); db(0x03); db(0xaa); db(0x00); db(0x00); db(0x00); db(0x34); db(0x00); db(0x00); db(0x00); db(0xd4); db(0x00); db(0x00); db(0x00); db(0x20); db(0x00); db(0x00); db(0x01); db(0x8e); - db(0x00); db(0x00); db(0x06); db(0xb8); db(0x00); db(0x00); db(0x07); db(0xdc); - db(0x43); db(0xfa); db(0x09); db(0xb4); db(0x4e); db(0xae); db(0xff); db(0xa0); + db(0x00); db(0x00); db(0x06); db(0xb0); db(0x00); db(0x00); db(0x07); db(0xd4); + db(0x43); db(0xfa); db(0x09); db(0xac); db(0x4e); db(0xae); db(0xff); db(0xa0); db(0x20); db(0x40); db(0x20); db(0x28); db(0x00); db(0x16); db(0x20); db(0x40); db(0x4e); db(0x90); db(0x4e); db(0x75); db(0x48); db(0xe7); db(0xff); db(0xfe); db(0x2c); db(0x78); db(0x00); db(0x04); db(0x30); db(0x3c); db(0xff); db(0xfc); - db(0x61); db(0x00); db(0x06); db(0x66); db(0x2a); db(0x50); db(0x43); db(0xfa); - db(0x09); db(0xac); db(0x70); db(0x24); db(0x7a); db(0x00); db(0x4e); db(0xae); + db(0x61); db(0x00); db(0x06); db(0x5e); db(0x2a); db(0x50); db(0x43); db(0xfa); + db(0x09); db(0xa4); db(0x70); db(0x24); db(0x7a); db(0x00); db(0x4e); db(0xae); db(0xfd); db(0xd8); db(0x4a); db(0x80); db(0x66); db(0x0c); db(0x43); db(0xfa); - db(0x09); db(0x9c); db(0x70); db(0x00); db(0x7a); db(0x01); db(0x4e); db(0xae); + db(0x09); db(0x94); db(0x70); db(0x00); db(0x7a); db(0x01); db(0x4e); db(0xae); db(0xfd); db(0xd8); db(0x28); db(0x40); db(0x20); db(0x3c); db(0x00); db(0x00); db(0x02); db(0x2c); db(0x72); db(0x01); db(0x4e); db(0xae); db(0xff); db(0x3a); db(0x26); db(0x40); db(0x27); db(0x4c); db(0x01); db(0x9c); db(0x7c); db(0x00); db(0xbc); db(0xad); db(0x01); db(0x0c); db(0x64); db(0x24); db(0x2f); db(0x06); db(0x7e); db(0x01); db(0x2f); db(0x0b); db(0x20); db(0x4b); db(0x61); db(0x00); - db(0x03); db(0x2a); db(0x26); db(0x5f); db(0x0c); db(0x80); db(0xff); db(0xff); + db(0x03); db(0x22); db(0x26); db(0x5f); db(0x0c); db(0x80); db(0xff); db(0xff); db(0xff); db(0xfe); db(0x67); db(0x08); db(0x48); db(0x46); db(0x52); db(0x46); db(0x48); db(0x46); db(0x60); db(0xe4); db(0x2c); db(0x1f); db(0x52); db(0x46); db(0x60); db(0xd6); db(0x2c); db(0x78); db(0x00); db(0x04); db(0x22); db(0x4c); db(0x4e); db(0xae); db(0xfe); db(0x62); db(0x30); db(0x3c); db(0xff); db(0x80); - db(0x61); db(0x00); db(0x05); db(0xf6); db(0x4e); db(0x90); db(0x72); db(0x03); + db(0x61); db(0x00); db(0x05); db(0xee); db(0x4e); db(0x90); db(0x72); db(0x03); db(0x74); db(0xf6); db(0x20); db(0x7c); db(0x00); db(0x20); db(0x00); db(0x00); db(0x90); db(0x88); db(0x65); db(0x0a); db(0x67); db(0x08); db(0x78); db(0x00); db(0x22); db(0x44); db(0x4e); db(0xae); db(0xfd); db(0x96); db(0x4c); db(0xdf); db(0x7f); db(0xff); db(0x4e); db(0x75); db(0x48); db(0xe7); db(0x00); db(0x20); - db(0x30); db(0x3c); db(0xff); db(0x50); db(0x61); db(0x00); db(0x05); db(0xca); + db(0x30); db(0x3c); db(0xff); db(0x50); db(0x61); db(0x00); db(0x05); db(0xc2); db(0x70); db(0x00); db(0x4e); db(0x90); db(0x4a); db(0x80); db(0x67); db(0x00); db(0x00); db(0xa0); db(0x2c); db(0x78); db(0x00); db(0x04); db(0x30); db(0x3c); - db(0xff); db(0x50); db(0x61); db(0x00); db(0x05); db(0xb4); db(0x70); db(0x02); + db(0xff); db(0x50); db(0x61); db(0x00); db(0x05); db(0xac); db(0x70); db(0x02); db(0x4e); db(0x90); db(0x0c); db(0x40); db(0x00); db(0x01); db(0x6d); db(0x7a); db(0x6e); db(0x06); db(0x4e); db(0xae); db(0xfe); db(0x92); db(0x60); db(0xe6); db(0x0c); db(0x40); db(0x00); db(0x02); db(0x6e); db(0x08); db(0x20); db(0x01); @@ -47,11 +47,11 @@ db(0x25); db(0x49); db(0x00); db(0x1a); db(0x20); db(0x69); db(0x00); db(0x10); db(0x22); db(0x4a); db(0x4e); db(0xae); db(0xfe); db(0x92); db(0x60); db(0x00); db(0xff); db(0x76); db(0x30); db(0x3c); db(0xff); db(0x50); db(0x61); db(0x00); - db(0x05); db(0x28); db(0x70); db(0x04); db(0x4e); db(0x90); db(0x70); db(0x01); + db(0x05); db(0x20); db(0x70); db(0x04); db(0x4e); db(0x90); db(0x70); db(0x01); db(0x4c); db(0xdf); db(0x04); db(0x00); db(0x4e); db(0x75); db(0x48); db(0xe7); db(0xc0); db(0xc0); db(0x70); db(0x1a); db(0x22); db(0x3c); db(0x00); db(0x01); db(0x00); db(0x01); db(0x4e); db(0xae); db(0xff); db(0x3a); db(0x22); db(0x40); - db(0x41); db(0xfa); db(0x08); db(0x25); db(0x23); db(0x48); db(0x00); db(0x0a); + db(0x41); db(0xfa); db(0x08); db(0x1d); db(0x23); db(0x48); db(0x00); db(0x0a); db(0x41); db(0xfa); db(0xff); db(0x2a); db(0x23); db(0x48); db(0x00); db(0x0e); db(0x41); db(0xfa); db(0xff); db(0x22); db(0x23); db(0x48); db(0x00); db(0x12); db(0x33); db(0x7c); db(0x02); db(0x14); db(0x00); db(0x08); db(0x70); db(0x03); @@ -64,24 +64,23 @@ db(0x00); db(0x00); db(0x00); db(0x0e); db(0x52); db(0x40); db(0x0c); db(0x40); db(0x00); db(0x8c); db(0x66); db(0xf2); db(0x20); db(0x0a); db(0xe4); db(0x88); db(0x21); db(0x40); db(0x00); db(0x36); db(0x22); db(0x48); db(0x41); db(0xfa); - db(0x07); db(0xbf); db(0x23); db(0x48); db(0x00); db(0x0a); db(0x20); db(0x6b); + db(0x07); db(0xb7); db(0x23); db(0x48); db(0x00); db(0x0a); db(0x20); db(0x6b); db(0x01); db(0x98); db(0x41); db(0xe8); db(0x00); db(0x12); db(0x4e); db(0xae); db(0xff); db(0x10); db(0x4c); db(0xdf); db(0x4f); db(0x03); db(0x4e); db(0x75); db(0x48); db(0xe7); db(0x7f); db(0x7e); db(0x2c); db(0x78); db(0x00); db(0x04); db(0x24); db(0x48); db(0x0c); db(0x9a); db(0x00); db(0x00); db(0x03); db(0xf3); - db(0x66); db(0x00); db(0x00); db(0xec); db(0x50); db(0x8a); db(0x2e); db(0x2a); + db(0x66); db(0x00); db(0x00); db(0xe4); db(0x50); db(0x8a); db(0x2e); db(0x2a); db(0x00); db(0x04); db(0x9e); db(0x92); db(0x50); db(0x8a); db(0x52); db(0x87); db(0x26); db(0x4a); db(0x20); db(0x07); db(0xd0); db(0x80); db(0xd0); db(0x80); db(0xd7); db(0xc0); db(0x28); db(0x4a); db(0x9b); db(0xcd); db(0x7c); db(0x00); - db(0x24); db(0x12); db(0xe5); db(0x8a); db(0x72); db(0x01); db(0x08); db(0x03); - db(0x00); db(0x1e); db(0x67); db(0x04); db(0x08); db(0xc1); db(0x00); db(0x01); - db(0x08); db(0xc1); db(0x00); db(0x10); db(0x08); db(0x83); db(0x00); db(0x1f); - db(0x08); db(0x83); db(0x00); db(0x1e); db(0x20); db(0x02); db(0x66); db(0x04); + db(0x24); db(0x12); db(0x72); db(0x01); db(0x08); db(0x02); db(0x00); db(0x1e); + db(0x67); db(0x04); db(0x08); db(0xc1); db(0x00); db(0x01); db(0x08); db(0xc1); + db(0x00); db(0x10); db(0xe5); db(0x8a); db(0x20); db(0x02); db(0x66); db(0x04); db(0x42); db(0x9a); db(0x60); db(0x1e); db(0x50); db(0x80); db(0x4e); db(0xae); db(0xff); db(0x3a); db(0x4a); db(0x80); db(0x67); db(0x00); db(0x00); db(0xa0); db(0x20); db(0x40); db(0x20); db(0xc2); db(0x24); db(0xc8); db(0x22); db(0x0d); db(0x67); db(0x06); db(0x20); db(0x08); db(0xe4); db(0x88); db(0x2a); db(0x80); - db(0x2a); db(0x48); db(0x52); db(0x86); db(0xbe); db(0x86); db(0x66); db(0xb8); + db(0x2a); db(0x48); db(0x52); db(0x86); db(0xbe); db(0x86); db(0x66); db(0xc0); db(0x7c); db(0x00); db(0x22); db(0x06); db(0xd2); db(0x81); db(0xd2); db(0x81); db(0x20); db(0x74); db(0x18); db(0x00); db(0x58); db(0x88); db(0x26); db(0x1b); db(0x28); db(0x1b); db(0xe5); db(0x8c); db(0x0c); db(0x83); db(0x00); db(0x00); @@ -123,10 +122,10 @@ db(0xff); db(0x28); db(0x61); db(0x00); db(0x02); db(0xdc); db(0x22); db(0x48); db(0x20); db(0x5f); db(0x42); db(0xa8); db(0x01); db(0x90); db(0x42); db(0xa8); db(0x01); db(0x94); db(0x4e); db(0x91); db(0x26); db(0x00); db(0x0c); db(0x83); - db(0xff); db(0xff); db(0xff); db(0xfe); db(0x67); db(0x00); db(0xfc); db(0xec); + db(0xff); db(0xff); db(0xff); db(0xfe); db(0x67); db(0x00); db(0xfc); db(0xf4); db(0x0c); db(0x83); db(0x00); db(0x00); db(0x00); db(0x02); db(0x67); db(0x0c); db(0xc0); db(0x85); db(0x67); db(0x08); db(0x4a); db(0xa8); db(0x01); db(0x90); - db(0x67); db(0x00); db(0xfc); db(0xd8); db(0x20); db(0x28); db(0x01); db(0x90); + db(0x67); db(0x00); db(0xfc); db(0xe0); db(0x20); db(0x28); db(0x01); db(0x90); db(0x67); db(0x12); db(0x2f); db(0x08); db(0x72); db(0x01); db(0x2c); db(0x78); db(0x00); db(0x04); db(0x4e); db(0xae); db(0xff); db(0x3a); db(0x20); db(0x5f); db(0x21); db(0x40); db(0x01); db(0x94); db(0x4a); db(0x83); db(0x6a); db(0x10); @@ -138,16 +137,16 @@ db(0x70); db(0x00); db(0x27); db(0x40); db(0x00); db(0x08); db(0x27); db(0x40); db(0x00); db(0x10); db(0x27); db(0x40); db(0x00); db(0x20); db(0x4a); db(0xa9); db(0x01); db(0x94); db(0x67); db(0x28); db(0x20); db(0x69); db(0x01); db(0x94); - db(0x61); db(0x00); db(0xfd); db(0xc6); db(0x48); db(0xe7); db(0x80); db(0xc0); + db(0x61); db(0x00); db(0xfd); db(0xce); db(0x48); db(0xe7); db(0x80); db(0xc0); db(0x20); db(0x29); db(0x01); db(0x90); db(0x22); db(0x69); db(0x01); db(0x94); db(0x2c); db(0x78); db(0x00); db(0x04); db(0x4e); db(0xae); db(0xff); db(0x2e); db(0x4c); db(0xdf); db(0x03); db(0x01); db(0x4a); db(0x80); db(0x67); db(0x04); - db(0x61); db(0x00); db(0xfd); db(0x50); db(0x4a); db(0x83); db(0x6b); db(0x00); - db(0xfc); db(0x52); db(0x30); db(0x3c); db(0xff); db(0x18); db(0x61); db(0x00); + db(0x61); db(0x00); db(0xfd); db(0x58); db(0x4a); db(0x83); db(0x6b); db(0x00); + db(0xfc); db(0x5a); db(0x30); db(0x3c); db(0xff); db(0x18); db(0x61); db(0x00); db(0x02); db(0x20); db(0x4e); db(0x90); db(0x20); db(0x03); db(0x16); db(0x29); db(0x00); db(0x4f); db(0x4a); db(0x80); db(0x66); db(0x1a); db(0x27); db(0x7c); db(0x00); db(0x00); db(0x0f); db(0xa0); db(0x00); db(0x14); db(0x43); db(0xfa); - db(0xfb); db(0x5c); db(0x20); db(0x09); db(0xe4); db(0x88); db(0x27); db(0x40); + db(0xfb); db(0x64); db(0x20); db(0x09); db(0xe4); db(0x88); db(0x27); db(0x40); db(0x00); db(0x20); db(0x70); db(0xff); db(0x27); db(0x40); db(0x00); db(0x24); db(0x4a); db(0x87); db(0x67); db(0x36); db(0x2c); db(0x78); db(0x00); db(0x04); db(0x70); db(0x14); db(0x72); db(0x00); db(0x4e); db(0xae); db(0xff); db(0x3a); @@ -212,7 +211,7 @@ db(0x24); db(0x51); db(0x70); db(0x18); db(0x4e); db(0xae); db(0xff); db(0x2e); db(0x06); db(0x86); db(0x00); db(0x01); db(0x00); db(0x00); db(0x20); db(0x0a); db(0x66); db(0xec); db(0x26); db(0x87); db(0x2a); db(0x1f); db(0x4e); db(0x75); - db(0x41); db(0xfa); db(0xf9); db(0x4a); db(0x02); db(0x80); db(0x00); db(0x00); + db(0x41); db(0xfa); db(0xf9); db(0x52); db(0x02); db(0x80); db(0x00); db(0x00); db(0xff); db(0xff); db(0xd1); db(0xc0); db(0x4e); db(0x75); db(0x00); db(0x00); db(0x0c); db(0xaf); db(0x00); db(0x00); db(0x00); db(0x22); db(0x00); db(0x08); db(0x66); db(0x30); db(0x48); db(0xe7); db(0xc0); db(0xe2); db(0x2c); db(0x78); diff --git a/gencpu_mini.c b/gencpu_mini.c new file mode 100755 index 00000000..0ffc265a --- /dev/null +++ b/gencpu_mini.c @@ -0,0 +1,1975 @@ +/* + * UAE - The Un*x Amiga Emulator + * + * MC68000 emulation generator + * + * This is a fairly stupid program that generates a lot of case labels that + * can be #included in a switch statement. + * As an alternative, it can generate functions that handle specific + * MC68000 instructions, plus a prototype header file and a function pointer + * array to look up the function for an opcode. + * Error checking is bad, an illegal table68k file will cause the program to + * call abort(). + * The generated code is sometimes sub-optimal, an optimizing compiler should + * take care of this. + * + * The source for the insn timings is Markt & Technik's Amiga Magazin 8/1992. + * + * Copyright 1995, 1996, 1997, 1998, 1999, 2000 Bernd Schmidt + */ + +#include "sysconfig.h" +#include "sysdeps.h" +#include + +#include "readcpu.h" + +#define BOOL_TYPE "int" + +static int optimized_flags; + +static int *opcode_map; +static int *opcode_next_clev; +static int *opcode_last_postfix; +static unsigned long *counts; + +static void read_counts (void) +{ + FILE *file; + unsigned long opcode, count, total; + char name[20]; + int nr = 0; + memset (counts, 0, 65536 * sizeof *counts); + + count = 0; + file = fopen ("frequent.68k", "r"); + if (file) { + fscanf (file, "Total: %lu\n", &total); + while (fscanf (file, "%lx: %lu %s\n", &opcode, &count, name) == 3) { + opcode_next_clev[nr] = 6; + opcode_last_postfix[nr] = -1; + opcode_map[nr++] = opcode; + counts[opcode] = count; + } + fclose (file); + } + if (nr == nr_cpuop_funcs) + return; + for (opcode = 0; opcode < 0x10000; opcode++) { + if (table68k[opcode].handler == -1 && table68k[opcode].mnemo != i_ILLG + && counts[opcode] == 0) + { + opcode_next_clev[nr] = 6; + opcode_last_postfix[nr] = -1; + opcode_map[nr++] = opcode; + counts[opcode] = count; + } + } + if (nr != nr_cpuop_funcs) + abort (); +} + +static char endlabelstr[80]; +static int endlabelno = 0; +static int need_endlabel; + +static int n_braces = 0, limit_braces; +static int m68k_pc_offset = 0; +static int insn_n_cycles; + +static int isreg(amodes mode) +{ + if (mode == Dreg || mode == Areg) + return 1; + return 0; +} + +static void start_brace (void) +{ + n_braces++; + printf ("{"); +} + +static void close_brace (void) +{ + assert (n_braces > 0); + n_braces--; + printf ("}"); +} + +static void finish_braces (void) +{ + while (n_braces > 0) + close_brace (); +} + +static void pop_braces (int to) +{ + while (n_braces > to) + close_brace (); +} + +static int bit_size (int size) +{ + switch (size) { + case sz_byte: return 8; + case sz_word: return 16; + case sz_long: return 32; + default: abort (); + } + return 0; +} + +static const char *bit_mask (int size) +{ + switch (size) { + case sz_byte: return "0xff"; + case sz_word: return "0xffff"; + case sz_long: return "0xffffffff"; + default: abort (); + } + return 0; +} + +static void gen_nextilong (char *type, char *name, int norefill) +{ + int r = m68k_pc_offset; + m68k_pc_offset += 4; + + printf ("\t%s %s = get_ilong (regs, %d);\n", type, name, r); +} + +static const char *gen_nextiword (int norefill) +{ + static char buffer[80]; + int r = m68k_pc_offset; + m68k_pc_offset += 2; + + sprintf (buffer, "get_iword (regs, %d)", r); + return buffer; +} + +static const char *gen_nextibyte (int norefill) +{ + static char buffer[80]; + int r = m68k_pc_offset; + m68k_pc_offset += 2; + + sprintf (buffer, "get_ibyte (regs, %d)", r); + return buffer; +} + +static void sync_m68k_pc (void) +{ + if (m68k_pc_offset == 0) + return; + printf ("\tmini_m68k_incpc (regs, %d);\n", m68k_pc_offset); + m68k_pc_offset = 0; +} + +/* getv == 1: fetch data; getv != 0: check for odd address. If movem != 0, + * the calling routine handles Apdi and Aipi modes. + * gb-- movem == 2 means the same thing but for a MOVE16 instruction */ +static void genamode2 (amodes mode, char *reg, wordsizes size, char *name, int getv, int movem, int flags, int e3fudge) +{ + char namea[100]; + int m68k_pc_offset_last = m68k_pc_offset; + + sprintf (namea, "%sa", name); + + start_brace (); + switch (mode) { + case Dreg: + if (movem) + abort (); + if (getv == 1) + switch (size) { + case sz_byte: + printf ("\tuae_s8 %s = m68k_dreg (regs, %s);\n", name, reg); + break; + case sz_word: + printf ("\tuae_s16 %s = m68k_dreg(regs, %s);\n", name, reg); + break; + case sz_long: + printf ("\tuae_s32 %s = m68k_dreg(regs, %s);\n", name, reg); + break; + default: + abort (); + } + return; + case Areg: + if (movem) + abort (); + if (getv == 1) + switch (size) { + case sz_word: + printf ("\tuae_s16 %s = m68k_areg(regs, %s);\n", name, reg); + break; + case sz_long: + printf ("\tuae_s32 %s = m68k_areg(regs, %s);\n", name, reg); + break; + default: + abort (); + } + return; + case Aind: + printf ("\tuaecptr %sa = m68k_areg(regs, %s);\n", name, reg); + break; + case Aipi: + printf ("\tuaecptr %sa = m68k_areg(regs, %s);\n", name, reg); + break; + case Apdi: + printf ("\tuaecptr %sa;\n", name); + switch (size) { + case sz_byte: + if (movem) + printf ("\t%sa = m68k_areg(regs, %s);\n", name, reg); + else + printf ("\t%sa = m68k_areg(regs, %s) - areg_byteinc[%s];\n", name, reg, reg); + break; + case sz_word: + printf ("\t%sa = m68k_areg(regs, %s) - %d;\n", name, reg, movem ? 0 : 2); + break; + case sz_long: + printf ("\t%sa = m68k_areg(regs, %s) - %d;\n", name, reg, movem ? 0 : 4); + break; + default: + abort (); + } + break; + case Ad16: + printf ("\tuaecptr %sa = m68k_areg(regs, %s) + (uae_s32)(uae_s16)%s;\n", name, reg, gen_nextiword ()); + break; + case Ad8r: + printf ("\tuaecptr %sa;\n", name); + printf ("\t%sa = get_disp_ea_000(regs, m68k_areg(regs, %s), %s);\n", name, reg, gen_nextiword ()); + break; + case PC16: + printf ("\tuaecptr %sa = m68k_getpc (regs) + %d;\n", name, m68k_pc_offset); + printf ("\t%sa += (uae_s32)(uae_s16)%s;\n", name, gen_nextiword (flags & GF_NOREFILL)); + break; + case PC8r: + printf ("\tuaecptr tmppc;\n"); + printf ("\tuaecptr %sa;\n", name); + printf ("\ttmppc = mini_m68k_getpc(regs) + %d;\n", m68k_pc_offset); + printf ("\t%sa = get_disp_ea_000(regs, tmppc, %s);\n", name, gen_nextiword (flags & GF_NOREFILL)); + break; + case absw: + printf ("\tuaecptr %sa = (uae_s32)(uae_s16)%s;\n", name, gen_nextiword (flags & GF_NOREFILL)); + break; + case absl: + gen_nextilong ("uaecptr", namea, flags & GF_NOREFILL); + break; + case imm: + if (getv != 1) + abort (); + switch (size) { + case sz_byte: + printf ("\tuae_s8 %s = %s;\n", name, gen_nextibyte ()); + break; + case sz_word: + printf ("\tuae_s16 %s = %s;\n", name, gen_nextiword ()); + break; + case sz_long: + gen_nextilong ("uae_s32", name); + break; + default: + abort (); + } + return; + case imm0: + if (getv != 1) + abort (); + printf ("\tuae_s8 %s = %s;\n", name, gen_nextibyte ()); + return; + case imm1: + if (getv != 1) + abort (); + printf ("\tuae_s16 %s = %s;\n", name, gen_nextiword ()); + return; + case imm2: + if (getv != 1) + abort (); + gen_nextilong ("uae_s32", name); + return; + case immi: + if (getv != 1) + abort (); + printf ("\tuae_u32 %s = %s;\n", name, reg); + return; + default: + abort (); + } + + /* We get here for all non-reg non-immediate addressing modes to + * actually fetch the value. */ + + if (getv == 1) { + start_brace (); + if (using_ce) { + switch (size) { + case sz_byte: printf ("\tuae_s8 %s = mini_get_byte_ce (%sa);\n", name, name); break; + case sz_word: printf ("\tuae_s16 %s = mini_get_word_ce (%sa);\n", name, name); break; + case sz_long: printf ("\tuae_s32 %s = mini_get_word_ce (%sa) << 16; %s |= mini_get_word_ce (%sa + 2);\n", name, name, name, name); break; + default: abort (); + } + } else { + switch (size) { + case sz_byte: insn_n_cycles += 4; printf ("\tuae_s8 %s = mini_get_byte (%sa);\n", name, name); break; + case sz_word: insn_n_cycles += 4; printf ("\tuae_s16 %s = mini_get_word (%sa);\n", name, name); break; + case sz_long: insn_n_cycles += 8; printf ("\tuae_s32 %s = mini_get_long (%sa);\n", name, name); break; + default: abort (); + } + } + } + + /* We now might have to fix up the register for pre-dec or post-inc + * addressing modes. */ + if (!movem) + switch (mode) { + case Aipi: + switch (size) { + case sz_byte: + printf ("\tm68k_areg(regs, %s) += areg_byteinc[%s];\n", reg, reg); + break; + case sz_word: + printf ("\tm68k_areg(regs, %s) += 2;\n", reg); + break; + case sz_long: + printf ("\tm68k_areg(regs, %s) += 4;\n", reg); + break; + default: + abort (); + } + break; + case Apdi: + printf ("\tm68k_areg (regs, %s) = %sa;\n", reg, name); + break; + default: + break; + } +} + +static void genamode (amodes mode, char *reg, wordsizes size, char *name, int getv, int movem, int flags) +{ + genamode2 (mode, reg, size, name, getv, movem, flags, 0); +} +static void genamode_e3 (amodes mode, char *reg, wordsizes size, char *name, int getv, int movem, int flags, int e3fudge) +{ + genamode2 (mode, reg, size, name, getv, movem, flags, e3fudge); +} + +static void genastore_2 (char *from, amodes mode, char *reg, wordsizes size, char *to, int store_dir) +{ + switch (mode) { + case Dreg: + switch (size) { + case sz_byte: + printf ("\tm68k_dreg(regs, %s) = (m68k_dreg(regs, %s) & ~0xff) | ((%s) & 0xff);\n", reg, reg, from); + break; + case sz_word: + printf ("\tm68k_dreg(regs, %s) = (m68k_dreg(regs, %s) & ~0xffff) | ((%s) & 0xffff);\n", reg, reg, from); + break; + case sz_long: + printf ("\tm68k_dreg(regs, %s) = (%s);\n", reg, from); + break; + default: + abort (); + } + break; + case Areg: + switch (size) { + case sz_word: + printf ("\tm68k_areg(regs, %s) = (uae_s32)(uae_s16)(%s);\n", reg, from); + break; + case sz_long: + printf ("\tm68k_areg(regs, %s) = (%s);\n", reg, from); + break; + default: + abort (); + } + break; + case Aind: + case Aipi: + case Apdi: + case Ad16: + case Ad8r: + case absw: + case absl: + case PC16: + case PC8r: + switch (size) { + case sz_byte: + printf ("\tmini_put_byte (%sa,%s);\n", to, from); + break; + case sz_word: + printf ("\tmini_put_word (%sa,%s);\n", to, from); + break; + case sz_long: + printf ("\tmini_put_long (%sa,%s);\n", to, from); + break; + default: + abort (); + } + } + break; + case imm: + case imm0: + case imm1: + case imm2: + case immi: + abort (); + break; + default: + abort (); + } +} + +static void genastore (char *from, amodes mode, char *reg, wordsizes size, char *to) +{ + genastore_2 (from, mode, reg, size, to, 0); +} +static void genastore_rev (char *from, amodes mode, char *reg, wordsizes size, char *to) +{ + genastore_2 (from, mode, reg, size, to, 1); +} + + +static void genmovemel (uae_u16 opcode) +{ + char getcode[100]; + int size = table68k[opcode].size == sz_long ? 4 : 2; + + if (table68k[opcode].size == sz_long) { + strcpy (getcode, "get_long(srca)"); + } else { + strcpy (getcode, "(uae_s32)(uae_s16)get_word(srca)"); + } + + printf ("\tuae_u16 mask = %s;\n", gen_nextiword (0)); + printf ("\tunsigned int dmask = mask & 0xff, amask = (mask >> 8) & 0xff;\n"); + genamode (table68k[opcode].dmode, "dstreg", table68k[opcode].size, "src", 2, 1, 0); + start_brace (); + printf ("\twhile (dmask) { m68k_dreg(regs, movem_index1[dmask]) = %s; srca += %d; dmask = movem_next[dmask]; }\n", + getcode, size); + printf ("\twhile (amask) { m68k_areg(regs, movem_index1[amask]) = %s; srca += %d; amask = movem_next[amask]; }\n", + getcode, size); + + if (table68k[opcode].dmode == Aipi) + printf ("\tm68k_areg(regs, dstreg) = srca;\n"); +} + +static void genmovemle (uae_u16 opcode) +{ + char putcode[100]; + int size = table68k[opcode].size == sz_long ? 4 : 2; + if (table68k[opcode].size == sz_long) { + strcpy (putcode, "put_long(srca"); + } else { + strcpy (putcode, "put_word(srca"); + } + + printf ("\tuae_u16 mask = %s;\n", gen_nextiword (0)); + genamode (table68k[opcode].dmode, "dstreg", table68k[opcode].size, "src", 2, 1, 0); + if (using_prefetch) + sync_m68k_pc (); + + start_brace (); + if (table68k[opcode].dmode == Apdi) { + printf ("\tuae_u16 amask = mask & 0xff, dmask = (mask >> 8) & 0xff;\n"); + printf ("\tint type = get_cpu_model() >= 68020;\n"); + printf ("\twhile (amask) {\n"); + printf ("\t\tsrca -= %d;\n", size); + printf ("\t\tif (type) m68k_areg(regs, dstreg) = srca;\n"); + printf ("\t\t%s, m68k_areg(regs, movem_index2[amask]));\n", putcode); + printf ("\t\tamask = movem_next[amask];\n"); + printf ("\t}\n"); + printf ("\twhile (dmask) { srca -= %d; %s, m68k_dreg(regs, movem_index2[dmask])); dmask = movem_next[dmask]; }\n", + size, putcode); + printf ("\tm68k_areg(regs, dstreg) = srca;\n"); + } else { + printf ("\tuae_u16 dmask = mask & 0xff, amask = (mask >> 8) & 0xff;\n"); + printf ("\twhile (dmask) { %s, m68k_dreg(regs, movem_index1[dmask])); srca += %d; dmask = movem_next[dmask]; }\n", + putcode, size); + printf ("\twhile (amask) { %s, m68k_areg(regs, movem_index1[amask])); srca += %d; amask = movem_next[amask]; }\n", + putcode, size); + } +} + +static void duplicate_carry (int n) +{ + int i; + for (i = 0; i <= n; i++) + printf ("\t"); + printf ("COPY_CARRY (®s->ccrflags);\n"); +} + +typedef enum +{ + flag_logical_noclobber, flag_logical, flag_add, flag_sub, flag_cmp, flag_addx, flag_subx, flag_zn, + flag_av, flag_sv +} +flagtypes; + +static void genflags_normal (flagtypes type, wordsizes size, char *value, char *src, char *dst) +{ + char vstr[100], sstr[100], dstr[100]; + char usstr[100], udstr[100]; + char unsstr[100], undstr[100]; + + switch (size) { + case sz_byte: + strcpy (vstr, "((uae_s8)("); + strcpy (usstr, "((uae_u8)("); + break; + case sz_word: + strcpy (vstr, "((uae_s16)("); + strcpy (usstr, "((uae_u16)("); + break; + case sz_long: + strcpy (vstr, "((uae_s32)("); + strcpy (usstr, "((uae_u32)("); + break; + default: + abort (); + } + strcpy (unsstr, usstr); + + strcpy (sstr, vstr); + strcpy (dstr, vstr); + strcat (vstr, value); + strcat (vstr, "))"); + strcat (dstr, dst); + strcat (dstr, "))"); + strcat (sstr, src); + strcat (sstr, "))"); + + strcpy (udstr, usstr); + strcat (udstr, dst); + strcat (udstr, "))"); + strcat (usstr, src); + strcat (usstr, "))"); + + strcpy (undstr, unsstr); + strcat (unsstr, "-"); + strcat (undstr, "~"); + strcat (undstr, dst); + strcat (undstr, "))"); + strcat (unsstr, src); + strcat (unsstr, "))"); + + switch (type) { + case flag_logical_noclobber: + case flag_logical: + case flag_zn: + case flag_av: + case flag_sv: + case flag_addx: + case flag_subx: + break; + + case flag_add: + start_brace (); + printf ("uae_u32 %s = %s + %s;\n", value, dstr, sstr); + break; + case flag_sub: + case flag_cmp: + start_brace (); + printf ("uae_u32 %s = %s - %s;\n", value, dstr, sstr); + break; + } + + switch (type) { + case flag_logical_noclobber: + case flag_logical: + case flag_zn: + break; + + case flag_add: + case flag_sub: + case flag_addx: + case flag_subx: + case flag_cmp: + case flag_av: + case flag_sv: + start_brace (); + printf ("\t" BOOL_TYPE " flgs = %s < 0;\n", sstr); + printf ("\t" BOOL_TYPE " flgo = %s < 0;\n", dstr); + printf ("\t" BOOL_TYPE " flgn = %s < 0;\n", vstr); + break; + } + + switch (type) { + case flag_logical: + printf ("\tCLEAR_CZNV (®s->ccrflags);\n"); + printf ("\tSET_ZFLG (®s->ccrflags, %s == 0);\n", vstr); + printf ("\tSET_NFLG (®s->ccrflags, %s < 0);\n", vstr); + break; + case flag_logical_noclobber: + printf ("\tSET_ZFLG (®s->ccrflags, %s == 0);\n", vstr); + printf ("\tSET_NFLG (®s->ccrflags, %s < 0);\n", vstr); + break; + case flag_av: + printf ("\tSET_VFLG (®s->ccrflags, (flgs ^ flgn) & (flgo ^ flgn));\n"); + break; + case flag_sv: + printf ("\tSET_VFLG (®s->ccrflags, (flgs ^ flgo) & (flgn ^ flgo));\n"); + break; + case flag_zn: + printf ("\tSET_ZFLG (®s->ccrflags, GET_ZFLG (&(regs->ccrflags)) & (%s == 0));\n", vstr); + printf ("\tSET_NFLG (®s->ccrflags, %s < 0);\n", vstr); + break; + case flag_add: + printf ("\tSET_ZFLG (®s->ccrflags, %s == 0);\n", vstr); + printf ("\tSET_VFLG (®s->ccrflags, (flgs ^ flgn) & (flgo ^ flgn));\n"); + printf ("\tSET_CFLG (®s->ccrflags, %s < %s);\n", undstr, usstr); + duplicate_carry (0); + printf ("\tSET_NFLG (®s->ccrflags, flgn != 0);\n"); + break; + case flag_sub: + printf ("\tSET_ZFLG (®s->ccrflags, %s == 0);\n", vstr); + printf ("\tSET_VFLG (®s->ccrflags, (flgs ^ flgo) & (flgn ^ flgo));\n"); + printf ("\tSET_CFLG (®s->ccrflags, %s > %s);\n", usstr, udstr); + duplicate_carry (0); + printf ("\tSET_NFLG (®s->ccrflags, flgn != 0);\n"); + break; + case flag_addx: + printf ("\tSET_VFLG (®s->ccrflags, (flgs ^ flgn) & (flgo ^ flgn));\n"); /* minterm SON: 0x42 */ + printf ("\tSET_CFLG (®s->ccrflags, flgs ^ ((flgs ^ flgo) & (flgo ^ flgn)));\n"); /* minterm SON: 0xD4 */ + duplicate_carry (0); + break; + case flag_subx: + printf ("\tSET_VFLG (®s->ccrflags, (flgs ^ flgo) & (flgo ^ flgn));\n"); /* minterm SON: 0x24 */ + printf ("\tSET_CFLG (®s->ccrflags, flgs ^ ((flgs ^ flgn) & (flgo ^ flgn)));\n"); /* minterm SON: 0xB2 */ + duplicate_carry (0); + break; + case flag_cmp: + printf ("\tSET_ZFLG (®s->ccrflags, %s == 0);\n", vstr); + printf ("\tSET_VFLG (®s->ccrflags, (flgs != flgo) && (flgn != flgo));\n"); + printf ("\tSET_CFLG (®s->ccrflags, %s > %s);\n", usstr, udstr); + printf ("\tSET_NFLG (®s->ccrflags, flgn != 0);\n"); + break; + } +} + +static void genflags (flagtypes type, wordsizes size, char *value, char *src, char *dst) +{ + /* Temporarily deleted 68k/ARM flag optimizations. I'd prefer to have + them in the appropriate m68k.h files and use just one copy of this + code here. The API can be changed if necessary. */ + if (optimized_flags) { + switch (type) { + case flag_add: + case flag_sub: + start_brace (); + printf ("\tuae_u32 %s;\n", value); + break; + + default: + break; + } + + /* At least some of those casts are fairly important! */ + switch (type) { + case flag_logical_noclobber: + printf ("\t{uae_u32 oldcznv = GET_CZNV & ~(FLAGVAL_Z | FLAGVAL_N);\n"); + if (strcmp (value, "0") == 0) { + printf ("\tSET_CZNV (®s->ccrflags, olcznv | FLAGVAL_Z);\n"); + } else { + switch (size) { + case sz_byte: printf ("\toptflag_testb (regs, (uae_s8)(%s));\n", value); break; + case sz_word: printf ("\toptflag_testw (regs, (uae_s16)(%s));\n", value); break; + case sz_long: printf ("\toptflag_testl (regs, (uae_s32)(%s));\n", value); break; + } + printf ("\tIOR_CZNV (®s->ccrflags, oldcznv);\n"); + } + printf ("\t}\n"); + return; + case flag_logical: + if (strcmp (value, "0") == 0) { + printf ("\tSET_CZNV (®s->ccrflags, FLAGVAL_Z);\n"); + } else { + switch (size) { + case sz_byte: printf ("\toptflag_testb (regs, (uae_s8)(%s));\n", value); break; + case sz_word: printf ("\toptflag_testw (regs, (uae_s16)(%s));\n", value); break; + case sz_long: printf ("\toptflag_testl (regs, (uae_s32)(%s));\n", value); break; + } + } + return; + + case flag_add: + switch (size) { + case sz_byte: printf ("\toptflag_addb (regs, %s, (uae_s8)(%s), (uae_s8)(%s));\n", value, src, dst); break; + case sz_word: printf ("\toptflag_addw (regs, %s, (uae_s16)(%s), (uae_s16)(%s));\n", value, src, dst); break; + case sz_long: printf ("\toptflag_addl (regs, %s, (uae_s32)(%s), (uae_s32)(%s));\n", value, src, dst); break; + } + return; + + case flag_sub: + switch (size) { + case sz_byte: printf ("\toptflag_subb (regs, %s, (uae_s8)(%s), (uae_s8)(%s));\n", value, src, dst); break; + case sz_word: printf ("\toptflag_subw (regs, %s, (uae_s16)(%s), (uae_s16)(%s));\n", value, src, dst); break; + case sz_long: printf ("\toptflag_subl (regs, %s, (uae_s32)(%s), (uae_s32)(%s));\n", value, src, dst); break; + } + return; + + case flag_cmp: + switch (size) { + case sz_byte: printf ("\toptflag_cmpb (regs, (uae_s8)(%s), (uae_s8)(%s));\n", src, dst); break; + case sz_word: printf ("\toptflag_cmpw (regs, (uae_s16)(%s), (uae_s16)(%s));\n", src, dst); break; + case sz_long: printf ("\toptflag_cmpl (regs, (uae_s32)(%s), (uae_s32)(%s));\n", src, dst); break; + } + return; + + default: + break; + } + } + + genflags_normal (type, size, value, src, dst); +} + +static void force_range_for_rox (const char *var, wordsizes size) +{ + /* Could do a modulo operation here... which one is faster? */ + switch (size) { + case sz_long: + printf ("\tif (%s >= 33) %s -= 33;\n", var, var); + break; + case sz_word: + printf ("\tif (%s >= 34) %s -= 34;\n", var, var); + printf ("\tif (%s >= 17) %s -= 17;\n", var, var); + break; + case sz_byte: + printf ("\tif (%s >= 36) %s -= 36;\n", var, var); + printf ("\tif (%s >= 18) %s -= 18;\n", var, var); + printf ("\tif (%s >= 9) %s -= 9;\n", var, var); + break; + } +} + +static const char *cmask (wordsizes size) +{ + switch (size) { + case sz_byte: return "0x80"; + case sz_word: return "0x8000"; + case sz_long: return "0x80000000"; + default: abort (); + } +} + +static int source_is_imm1_8 (struct instr *i) +{ + return i->stype == 3; +} + +static void shift_ce (amodes dmode, int size) +{ + if (using_ce && isreg (dmode)) { + printf ("\t{\n"); + printf ("\t\tint cycles = %d * %d;\n", size == sz_long ? 8 : 6, CYCLE_UNIT / 2); + printf ("\t\tcycles += 2 * %d * ccnt;\n", CYCLE_UNIT / 2); + addcycles3 ("\t\t"); + printf ("\t}\n"); + } +} + +static void gen_opcode (unsigned long int opcode) +{ + struct instr *curi = table68k + opcode; + int tmpc = 0; + insn_n_cycles = using_prefetch ? 0 : 4; + + start_brace (); + m68k_pc_offset = 2; + if (curi->plev) + return; + switch (curi->mnemo) { + case i_OR: + case i_AND: + case i_EOR: + genamode (curi->smode, "srcreg", curi->size, "src", 1, 0, 0); + genamode (curi->dmode, "dstreg", curi->size, "dst", 1, 0, 0); + printf ("\tsrc %c= dst;\n", curi->mnemo == i_OR ? '|' : curi->mnemo == i_AND ? '&' : '^'); + genflags (flag_logical, curi->size, "src", "", ""); + if (curi->size == sz_long && isreg (curi->dmode)) + addcycles (curi->mnemo == i_AND ? 2 : 4); + fill_prefetch_next (); + genastore ("src", curi->dmode, "dstreg", curi->size, "dst"); + break; + case i_SUB: + genamode (curi->smode, "srcreg", curi->size, "src", 1, 0, 0); + genamode (curi->dmode, "dstreg", curi->size, "dst", 1, 0, 0); + if (isreg (curi->dmode)) { + if (curi->dmode == Dreg && curi->size == sz_long) + addcycles ((curi->smode == imm || curi->smode == immi) ? 4 : 2); + } + fill_prefetch_next (); + start_brace (); + genflags (flag_sub, curi->size, "newv", "src", "dst"); + genastore ("newv", curi->dmode, "dstreg", curi->size, "dst"); + break; + case i_SUBA: + genamode (curi->smode, "srcreg", curi->size, "src", 1, 0, 0); + genamode (curi->dmode, "dstreg", sz_long, "dst", 1, 0, 0); + if (isreg (curi->dmode) && curi->dmode == Areg) { + tmpc += curi->size == sz_long ? 2 : 4; + if (curi->size == sz_long) + tmpc += (isreg (curi->smode) || curi->smode == imm) ? 2 : 0; + addcycles (4); + } + fill_prefetch_next (); + start_brace (); + printf ("\tuae_u32 newv = dst - src;\n"); + genastore ("newv", curi->dmode, "dstreg", sz_long, "dst"); + break; + case i_SUBX: + genamode (curi->smode, "srcreg", curi->size, "src", 1, 0, GF_AA); + genamode (curi->dmode, "dstreg", curi->size, "dst", 1, 0, GF_AA); + if ((isreg (curi->smode) && curi->size == sz_long) || !isreg (curi->smode)) + addcycles (2); + fill_prefetch_next (); + start_brace (); + printf ("\tuae_u32 newv = dst - src - (GET_XFLG (®s->ccrflags) ? 1 : 0);\n"); + genflags (flag_subx, curi->size, "newv", "src", "dst"); + genflags (flag_zn, curi->size, "newv", "", ""); + genastore ("newv", curi->dmode, "dstreg", curi->size, "dst"); + break; + case i_SBCD: + genamode (curi->smode, "srcreg", curi->size, "src", 1, 0, GF_AA); + genamode (curi->dmode, "dstreg", curi->size, "dst", 1, 0, GF_AA); + fill_prefetch_next (); + start_brace (); + printf ("\tuae_u16 newv_lo = (dst & 0xF) - (src & 0xF) - (GET_XFLG (®s->ccrflags) ? 1 : 0);\n"); + printf ("\tuae_u16 newv_hi = (dst & 0xF0) - (src & 0xF0);\n"); + printf ("\tuae_u16 newv, tmp_newv;\n"); + printf ("\tint bcd = 0;\n"); + printf ("\tnewv = tmp_newv = newv_hi + newv_lo;\n"); + printf ("\tif (newv_lo & 0xF0) { newv -= 6; bcd = 6; };\n"); + printf ("\tif ((((dst & 0xFF) - (src & 0xFF) - (GET_XFLG (®s->ccrflags) ? 1 : 0)) & 0x100) > 0xFF) { newv -= 0x60; }\n"); + printf ("\tSET_CFLG (®s->ccrflags, (((dst & 0xFF) - (src & 0xFF) - bcd - (GET_XFLG (®s->ccrflags) ? 1 : 0)) & 0x300) > 0xFF);\n"); + duplicate_carry (0); + genflags (flag_zn, curi->size, "newv", "", ""); + printf ("\tSET_VFLG (®s->ccrflags, (tmp_newv & 0x80) != 0 && (newv & 0x80) == 0);\n"); + addcycles (2); + genastore ("newv", curi->dmode, "dstreg", curi->size, "dst"); + break; + case i_ADD: + genamode (curi->smode, "srcreg", curi->size, "src", 1, 0, 0); + genamode (curi->dmode, "dstreg", curi->size, "dst", 1, 0, 0); + if (isreg (curi->dmode)) { + if (curi->dmode == Dreg && curi->size == sz_long) + addcycles ((curi->smode == imm || curi->smode == immi) ? 4 : 2); + } + fill_prefetch_next (); + start_brace (); + genflags (flag_add, curi->size, "newv", "src", "dst"); + genastore ("newv", curi->dmode, "dstreg", curi->size, "dst"); + break; + case i_ADDA: + genamode (curi->smode, "srcreg", curi->size, "src", 1, 0, 0); + genamode (curi->dmode, "dstreg", sz_long, "dst", 1, 0, 0); + if (isreg (curi->dmode) && curi->dmode == Areg) { + tmpc += curi->size == sz_long ? 2 : 4; + if (curi->size == sz_long) + tmpc += (isreg (curi->smode) || curi->smode == imm) ? 2 : 0; + addcycles (tmpc); + } + fill_prefetch_next (); + start_brace (); + printf ("\tuae_u32 newv = dst + src;\n"); + genastore ("newv", curi->dmode, "dstreg", sz_long, "dst"); + break; + case i_ADDX: + genamode (curi->smode, "srcreg", curi->size, "src", 1, 0, GF_AA); + genamode (curi->dmode, "dstreg", curi->size, "dst", 1, 0, GF_AA); + start_brace (); + printf ("\tuae_u32 newv = dst + src + (GET_XFLG (®s->ccrflags) ? 1 : 0);\n"); + genflags (flag_addx, curi->size, "newv", "src", "dst"); + genflags (flag_zn, curi->size, "newv", "", ""); + genastore ("newv", curi->dmode, "dstreg", curi->size, "dst"); + break; + case i_ABCD: + genamode (curi->smode, "srcreg", curi->size, "src", 1, 0, GF_AA); + genamode (curi->dmode, "dstreg", curi->size, "dst", 1, 0, GF_AA); + start_brace (); + printf ("\tuae_u16 newv_lo = (src & 0xF) + (dst & 0xF) + (GET_XFLG (®s->ccrflags) ? 1 : 0);\n"); + printf ("\tuae_u16 newv_hi = (src & 0xF0) + (dst & 0xF0);\n"); + printf ("\tuae_u16 newv, tmp_newv;\n"); + printf ("\tint cflg;\n"); + printf ("\tnewv = tmp_newv = newv_hi + newv_lo;"); + printf ("\tif (newv_lo > 9) { newv += 6; }\n"); + printf ("\tcflg = (newv & 0x3F0) > 0x90;\n"); + printf ("\tif (cflg) newv += 0x60;\n"); + printf ("\tSET_CFLG (®s->ccrflags, cflg);\n"); + duplicate_carry (0); + genflags (flag_zn, curi->size, "newv", "", ""); + printf ("\tSET_VFLG (®s->ccrflags, (tmp_newv & 0x80) == 0 && (newv & 0x80) != 0);\n"); + addcycles (2); + genastore ("newv", curi->dmode, "dstreg", curi->size, "dst"); + break; + case i_NEG: + genamode (curi->smode, "srcreg", curi->size, "src", 1, 0, 0); + start_brace (); + genflags (flag_sub, curi->size, "dst", "src", "0"); + genastore_rev ("dst", curi->smode, "srcreg", curi->size, "src"); + break; + case i_NEGX: + genamode (curi->smode, "srcreg", curi->size, "src", 1, 0, 0); + start_brace (); + printf ("\tuae_u32 newv = 0 - src - (GET_XFLG (®s->ccrflags) ? 1 : 0);\n"); + genflags (flag_subx, curi->size, "newv", "src", "0"); + genflags (flag_zn, curi->size, "newv", "", ""); + genastore_rev ("newv", curi->smode, "srcreg", curi->size, "src"); + break; + case i_NBCD: + genamode (curi->smode, "srcreg", curi->size, "src", 1, 0, 0); + start_brace (); + printf ("\tuae_u16 newv_lo = - (src & 0xF) - (GET_XFLG (®s->ccrflags) ? 1 : 0);\n"); + printf ("\tuae_u16 newv_hi = - (src & 0xF0);\n"); + printf ("\tuae_u16 newv;\n"); + printf ("\tint cflg;\n"); + printf ("\tif (newv_lo > 9) { newv_lo -= 6; }\n"); + printf ("\tnewv = newv_hi + newv_lo;"); + printf ("\tcflg = (newv & 0x1F0) > 0x90;\n"); + printf ("\tif (cflg) newv -= 0x60;\n"); + printf ("\tSET_CFLG (®s->ccrflags, cflg);\n"); + duplicate_carry(0); + genflags (flag_zn, curi->size, "newv", "", ""); + genastore ("newv", curi->smode, "srcreg", curi->size, "src"); + break; + case i_CLR: + genamode (curi->smode, "srcreg", curi->size, "src", cpu_level == 0 ? 1 : 2, 0, 0); + genflags (flag_logical, curi->size, "0", "", ""); + genastore_rev ("0", curi->smode, "srcreg", curi->size, "src"); + break; + case i_NOT: + genamode (curi->smode, "srcreg", curi->size, "src", 1, 0, 0); + start_brace (); + printf ("\tuae_u32 dst = ~src;\n"); + genflags (flag_logical, curi->size, "dst", "", ""); + genastore_rev ("dst", curi->smode, "srcreg", curi->size, "src"); + break; + case i_TST: + genamode (curi->smode, "srcreg", curi->size, "src", 1, 0, 0); + genflags (flag_logical, curi->size, "src", "", ""); + break; + case i_BTST: + genamode (curi->smode, "srcreg", curi->size, "src", 1, 0, 0); + genamode (curi->dmode, "dstreg", curi->size, "dst", 1, 0, 0); + if (curi->size == sz_byte) + printf ("\tsrc &= 7;\n"); + else + printf ("\tsrc &= 31;\n"); + printf ("\tSET_ZFLG (®s->ccrflags, 1 ^ ((dst >> src) & 1));\n"); + break; + case i_BCHG: + genamode (curi->smode, "srcreg", curi->size, "src", 1, 0, 0); + genamode (curi->dmode, "dstreg", curi->size, "dst", 1, 0, 0); + if (curi->size == sz_byte) + printf ("\tsrc &= 7;\n"); + else + printf ("\tsrc &= 31;\n"); + printf ("\tdst ^= (1 << src);\n"); + printf ("\tSET_ZFLG (®s->ccrflags, ((uae_u32)dst & (1 << src)) >> src);\n"); + genastore ("dst", curi->dmode, "dstreg", curi->size, "dst"); + break; + case i_BCLR: + genamode (curi->smode, "srcreg", curi->size, "src", 1, 0, 0); + genamode (curi->dmode, "dstreg", curi->size, "dst", 1, 0, 0); + if (curi->size == sz_byte) + printf ("\tsrc &= 7;\n"); + else + printf ("\tsrc &= 31;\n"); + printf ("\tSET_ZFLG (®s->ccrflags, 1 ^ ((dst >> src) & 1));\n"); + printf ("\tdst &= ~(1 << src);\n"); + genastore ("dst", curi->dmode, "dstreg", curi->size, "dst"); + break; + case i_BSET: + genamode (curi->smode, "srcreg", curi->size, "src", 1, 0, 0); + genamode (curi->dmode, "dstreg", curi->size, "dst", 1, 0, 0); + if (curi->size == sz_byte) + printf ("\tsrc &= 7;\n"); + else + printf ("\tsrc &= 31;\n"); + printf ("\tSET_ZFLG (®s->ccrflags, 1 ^ ((dst >> src) & 1));\n"); + printf ("\tdst |= (1 << src);\n"); + genastore ("dst", curi->dmode, "dstreg", curi->size, "dst"); + break; + case i_CMPM: + genamode (curi->smode, "srcreg", curi->size, "src", 1, 0, GF_AA); + genamode (curi->dmode, "dstreg", curi->size, "dst", 1, 0, GF_AA); + start_brace (); + genflags (flag_cmp, curi->size, "newv", "src", "dst"); + break; + case i_CMP: + genamode (curi->smode, "srcreg", curi->size, "src", 1, 0, 0); + genamode (curi->dmode, "dstreg", curi->size, "dst", 1, 0, 0); + start_brace (); + genflags (flag_cmp, curi->size, "newv", "src", "dst"); + break; + case i_CMPA: + genamode (curi->smode, "srcreg", curi->size, "src", 1, 0, 0); + genamode (curi->dmode, "dstreg", sz_long, "dst", 1, 0, 0); + start_brace (); + genflags (flag_cmp, sz_long, "newv", "src", "dst"); + break; + /* The next two are coded a little unconventional, but they are doing + * weird things... */ + case i_MVPRM: + genamode (curi->smode, "srcreg", curi->size, "src", 1, 0, 0); + printf ("\tuaecptr memp = m68k_areg(regs, dstreg) + (uae_s32)(uae_s16)%s;\n", gen_nextiword (0)); + if (curi->size == sz_word) { + printf ("\tmini_put_byte (memp, src >> 8); mini_put_byte (memp + 2, src);\n"); + } else { + printf ("\tmini_put_byte (memp, src >> 24); mini_put_byte (memp + 2, src >> 16);\n"); + printf ("\tmini_put_byte (memp + 4, src >> 8); mini_put_byte (memp + 6, src);\n"); + } + break; + case i_MVPMR: + printf ("\tuaecptr memp = m68k_areg(regs, srcreg) + (uae_s32)(uae_s16)%s;\n", gen_nextiword (0)); + genamode (curi->dmode, "dstreg", curi->size, "dst", 2, 0, 0); + if (curi->size == sz_word) { + printf ("\tuae_u16 val = (mini_get_byte (memp) << 8) + mini_get_byte (memp + 2);\n"); + } else { + printf ("\tuae_u32 val = (mini_get_byte (memp) << 24) + (mini_get_byte (memp + 2) << 16)\n"); + printf (" + (mini_get_byte (memp + 4) << 8) + mini_get_byte (memp + 6);\n"); + } + genastore ("val", curi->dmode, "dstreg", curi->size, "dst"); + break; + case i_MOVE: + case i_MOVEA: + { + genamode (curi->smode, "srcreg", curi->size, "src", 1, 0, 0); + genamode_e3 (curi->dmode, "dstreg", curi->size, "dst", 2, 0, 1, curi->smode == Dreg && curi->dmode == Aind ? 2 : 0); + if (curi->mnemo == i_MOVEA && curi->size == sz_word) + printf ("\tsrc = (uae_s32)(uae_s16)src;\n"); + genastore ("src", curi->dmode, "dstreg", curi->size, "dst"); + if (curi->mnemo == i_MOVE) + genflags (flag_logical, curi->size, "src", "", ""); + sync_m68k_pc (); + } + break; + case i_SWAP: + genamode (curi->smode, "srcreg", sz_long, "src", 1, 0, 0); + fill_prefetch_next (); + start_brace (); + printf ("\tuae_u32 dst = ((src >> 16)&0xFFFF) | ((src&0xFFFF)<<16);\n"); + genflags (flag_logical, sz_long, "dst", "", ""); + genastore ("dst", curi->smode, "srcreg", sz_long, "src"); + break; + case i_EXG: + genamode (curi->smode, "srcreg", curi->size, "src", 1, 0, 0); + genamode (curi->dmode, "dstreg", curi->size, "dst", 1, 0, 0); + addcycles (2); + fill_prefetch_next (); + genastore ("dst", curi->smode, "srcreg", curi->size, "src"); + genastore ("src", curi->dmode, "dstreg", curi->size, "dst"); + break; + case i_EXT: + genamode (curi->smode, "srcreg", sz_long, "src", 1, 0, 0); + fill_prefetch_next (); + start_brace (); + switch (curi->size) { + case sz_byte: printf ("\tuae_u32 dst = (uae_s32)(uae_s8)src;\n"); break; + case sz_word: printf ("\tuae_u16 dst = (uae_s16)(uae_s8)src;\n"); break; + case sz_long: printf ("\tuae_u32 dst = (uae_s32)(uae_s16)src;\n"); break; + default: abort (); + } + genflags (flag_logical, + curi->size == sz_word ? sz_word : sz_long, "dst", "", ""); + genastore ("dst", curi->smode, "srcreg", + curi->size == sz_word ? sz_word : sz_long, "src"); + break; + case i_MVMEL: + genmovemel (opcode); + break; + case i_MVMLE: + genmovemle (opcode); + break; + case i_NOP: + break; + case i_RTD: + 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"); + printf ("\tm68k_setpc(regs, pc);\n"); + /* PC is set and prefetch filled. */ + m68k_pc_offset = 0; + break; + case i_LINK: + genamode (Apdi, "7", sz_long, "old", 2, 0, GF_AA); + genamode (curi->smode, "srcreg", sz_long, "src", 1, 0, GF_AA); + genastore ("src", Apdi, "7", sz_long, "old"); + genastore ("m68k_areg(regs, 7)", curi->smode, "srcreg", sz_long, "src"); + genamode (curi->dmode, "dstreg", curi->size, "offs", 1, 0, 0); + printf ("\tm68k_areg(regs, 7) += offs;\n"); + break; + case i_UNLK: + genamode (curi->smode, "srcreg", curi->size, "src", 1, 0, 0); + printf ("\tm68k_areg(regs, 7) = src;\n"); + genamode (Aipi, "7", sz_long, "old", 1, 0, 0); + genastore ("old", curi->smode, "srcreg", curi->size, "src"); + break; + case i_RTS: + printf ("\tmini_m68k_do_rts(regs);\n"); + m68k_pc_offset = 0; + break; + case i_JSR: + genamode (curi->smode, "srcreg", curi->size, "src", 0, 0, GF_AA|GF_NOREFILL); + start_brace (); + printf ("\tuaecptr oldpc = mini_m68k_getpc(regs) + %d;\n", m68k_pc_offset); + printf ("\tmini_m68k_setpc (regs, srca);\n"); + m68k_pc_offset = 0; + printf("\tmini_m68k_areg (regs, 7) -= 4;\n"); + printf("\tmini_put_long (m68k_areg (regs, 7), oldpc);\n"); + break; + case i_JMP: + genamode (curi->smode, "srcreg", curi->size, "src", 0, 0, GF_AA|GF_NOREFILL); + printf ("\tmini_m68k_setpc(regs, srca);\n"); + m68k_pc_offset = 0; + break; + case i_BSR: + printf ("\tuae_s32 s;\n"); + genamode (curi->smode, "srcreg", curi->size, "src", 1, 0, GF_AA|GF_NOREFILL); + printf ("\ts = (uae_s32)src + 2;\n"); + printf ("\tmini_m68k_do_bsr (regs, mini_m68k_getpc(regs) + %d, s);\n", m68k_pc_offset); + m68k_pc_offset = 0; + fill_prefetch_full (); + break; + case i_Bcc: + genamode (curi->smode, "srcreg", curi->size, "src", 1, 0, GF_AA | GF_NOREFILL); + printf ("\tif (!cctrue(®s->ccrflags, %d)) goto didnt_jump;\n", curi->cc); + printf ("\tm68k_incpc (regs, (uae_s32)src + 2);\n"); + printf ("didnt_jump:;\n"); + need_endlabel = 1; + sync_m68k_pc (); + break; + case i_LEA: + genamode (curi->smode, "srcreg", curi->size, "src", 0, 0, GF_AA); + genamode (curi->dmode, "dstreg", curi->size, "dst", 2, 0, GF_AA); + genastore ("srca", curi->dmode, "dstreg", curi->size, "dst"); + break; + case i_PEA: + genamode (curi->smode, "srcreg", curi->size, "src", 0, 0, GF_AA); + genamode (Apdi, "7", sz_long, "dst", 2, 0, GF_AA); + genastore ("srca", Apdi, "7", sz_long, "dst"); + break; + case i_DBcc: + genamode (curi->smode, "srcreg", curi->size, "src", 1, 0, GF_AA | GF_NOREFILL); + genamode (curi->dmode, "dstreg", curi->size, "offs", 1, 0, GF_AA | GF_NOREFILL); + printf ("\tuaecptr oldpc = m68k_getpc(regs);\n"); + printf ("\tif (!cctrue(®s->ccrflags, %d)) {\n", curi->cc); + printf ("\t\tm68k_incpc(regs, (uae_s32)offs + 2);\n"); + printf ("\t"); + printf ("\t"); + genastore ("(src-1)", curi->smode, "srcreg", curi->size, "src"); + printf ("\tmini_m68k_setpc (regs, oldpc + %d);\n", m68k_pc_offset); + m68k_pc_offset = 0; + need_endlabel = 1; + break; + case i_Scc: + genamode (curi->smode, "srcreg", curi->size, "src", cpu_level == 0 ? 1 : 2, 0, 0); + start_brace (); + printf ("\tint val = cctrue(®s->ccrflags, %d) ? 0xff : 0;\n", curi->cc); + genastore ("val", curi->smode, "srcreg", curi->size, "src"); + break; + case i_DIVU: + printf ("\tuaecptr oldpc = mini_m68k_getpc(regs);\n"); + genamode (curi->smode, "srcreg", sz_word, "src", 1, 0, 0); + genamode (curi->dmode, "dstreg", sz_long, "dst", 1, 0, 0); + printf ("\tCLEAR_CZNV (®s->ccrflags);\n"); + printf ("\tif (src == 0) {\n"); + printf ("\t} else {\n"); + printf ("\t\tuae_u32 newv = (uae_u32)dst / (uae_u32)(uae_u16)src;\n"); + printf ("\t\tuae_u32 rem = (uae_u32)dst %% (uae_u32)(uae_u16)src;\n"); + printf ("\t\tif (newv > 0xffff) {\n"); + printf ("\t\t\tSET_VFLG (®s->ccrflags, 1);\n"); + printf ("\t\t\tSET_NFLG (®s->ccrflags, 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"); + printf ("\t\t"); genastore ("newv", curi->dmode, "dstreg", sz_long, "dst"); + printf ("\t\t}\n"); + fill_prefetch_next (); + sync_m68k_pc (); + printf ("\t}\n"); + insn_n_cycles += 136 - (136 - 76) / 2; /* average */ + need_endlabel = 1; + break; + case i_DIVS: + printf ("\tuaecptr oldpc = mini_m68k_getpc(regs);\n"); + genamode (curi->smode, "srcreg", sz_word, "src", 1, 0, 0); + genamode (curi->dmode, "dstreg", sz_long, "dst", 1, 0, 0); + printf ("\tCLEAR_CZNV (®s->ccrflags);\n"); + printf ("\tif (src == 0) {\n"); + printf ("\t\tgoto %s;\n", endlabelstr); + printf ("\t} else {\n"); + printf ("\t\tuae_s32 newv = (uae_s32)dst / (uae_s32)(uae_s16)src;\n"); + printf ("\t\tuae_u16 rem = (uae_s32)dst %% (uae_s32)(uae_s16)src;\n"); + printf ("\t\tif ((newv & 0xffff8000) != 0 && (newv & 0xffff8000) != 0xffff8000) {\n"); + printf ("\t\t\tSET_VFLG (®s->ccrflags, 1);\n"); + printf ("\t\t\tSET_NFLG (®s->ccrflags, 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", "", ""); + printf ("\t\t\tnewv = (newv & 0xffff) | ((uae_u32)rem << 16);\n"); + printf ("\t\t"); genastore ("newv", curi->dmode, "dstreg", sz_long, "dst"); + printf ("\t\t}\n"); + sync_m68k_pc (); + printf ("\t}\n"); + need_endlabel = 1; + break; + case i_MULU: + genamode (curi->smode, "srcreg", sz_word, "src", 1, 0, 0); + genamode (curi->dmode, "dstreg", sz_word, "dst", 1, 0, 0); + start_brace (); + printf ("\tuae_u32 newv = (uae_u32)(uae_u16)dst * (uae_u32)(uae_u16)src;\n"); + genflags (flag_logical, sz_long, "newv", "", ""); + genastore ("newv", curi->dmode, "dstreg", sz_long, "dst"); + sync_m68k_pc (); + break; + case i_MULS: + genamode (curi->smode, "srcreg", sz_word, "src", 1, 0, 0); + genamode (curi->dmode, "dstreg", sz_word, "dst", 1, 0, 0); + start_brace (); + printf ("\tuae_u32 newv = (uae_s32)(uae_s16)dst * (uae_s32)(uae_s16)src;\n"); + genflags (flag_logical, sz_long, "newv", "", ""); + genastore ("newv", curi->dmode, "dstreg", sz_long, "dst"); + break; + case i_ASR: + genamode (curi->smode, "srcreg", curi->size, "cnt", 1, 0, 0); + genamode (curi->dmode, "dstreg", curi->size, "data", 1, 0, 0); + start_brace (); + switch (curi->size) { + case sz_byte: printf ("\tuae_u32 val = (uae_u8)data;\n"); break; + case sz_word: printf ("\tuae_u32 val = (uae_u16)data;\n"); break; + case sz_long: printf ("\tuae_u32 val = data;\n"); break; + default: abort (); + } + printf ("\tuae_u32 sign = (%s & val) >> %d;\n", cmask (curi->size), bit_size (curi->size) - 1); + printf ("\tint ccnt = cnt & 63;\n"); + printf ("\tcnt &= 63;\n"); + printf ("\tCLEAR_CZNV (®s->ccrflags);\n"); + printf ("\tif (cnt >= %d) {\n", bit_size (curi->size)); + printf ("\t\tval = %s & (uae_u32)-sign;\n", bit_mask (curi->size)); + printf ("\t\tSET_CFLG (®s->ccrflags, sign);\n"); + duplicate_carry (1); + if (source_is_imm1_8 (curi)) + printf ("\t} else {\n"); + else + printf ("\t} else if (cnt > 0) {\n"); + printf ("\t\tval >>= cnt - 1;\n"); + printf ("\t\tSET_CFLG (®s->ccrflags, val & 1);\n"); + duplicate_carry (1); + printf ("\t\tval >>= 1;\n"); + printf ("\t\tval |= (%s << (%d - cnt)) & (uae_u32)-sign;\n", + bit_mask (curi->size), + bit_size (curi->size)); + printf ("\t\tval &= %s;\n", bit_mask (curi->size)); + printf ("\t}\n"); + genflags (flag_logical_noclobber, curi->size, "val", "", ""); + shift_ce (curi->dmode, curi->size); + genastore ("val", curi->dmode, "dstreg", curi->size, "data"); + break; + case i_ASL: + genamode (curi->smode, "srcreg", curi->size, "cnt", 1, 0, 0); + genamode (curi->dmode, "dstreg", curi->size, "data", 1, 0, 0); + start_brace (); + switch (curi->size) { + case sz_byte: printf ("\tuae_u32 val = (uae_u8)data;\n"); break; + case sz_word: printf ("\tuae_u32 val = (uae_u16)data;\n"); break; + case sz_long: printf ("\tuae_u32 val = data;\n"); break; + default: abort (); + } + printf ("\tint ccnt = cnt & 63;\n"); + printf ("\tcnt &= 63;\n"); + printf ("\tCLEAR_CZNV (®s->ccrflags);\n"); + printf ("\tif (cnt >= %d) {\n", bit_size (curi->size)); + printf ("\t\tSET_VFLG (®s->ccrflags, val != 0);\n"); + printf ("\t\tSET_CFLG (®s->ccrflags, cnt == %d ? val & 1 : 0);\n", + bit_size (curi->size)); + duplicate_carry (1); + printf ("\t\tval = 0;\n"); + if (source_is_imm1_8 (curi)) + printf ("\t} else {\n"); + else + printf ("\t} else if (cnt > 0) {\n"); + printf ("\t\tuae_u32 mask = (%s << (%d - cnt)) & %s;\n", + bit_mask (curi->size), + bit_size (curi->size) - 1, + bit_mask (curi->size)); + printf ("\t\tSET_VFLG (®s->ccrflags, (val & mask) != mask && (val & mask) != 0);\n"); + printf ("\t\tval <<= cnt - 1;\n"); + printf ("\t\tSET_CFLG (®s->ccrflags, (val & %s) >> %d);\n", cmask (curi->size), bit_size (curi->size) - 1); + duplicate_carry (1); + printf ("\t\tval <<= 1;\n"); + printf ("\t\tval &= %s;\n", bit_mask (curi->size)); + printf ("\t}\n"); + genflags (flag_logical_noclobber, curi->size, "val", "", ""); + shift_ce (curi->dmode, curi->size); + genastore ("val", curi->dmode, "dstreg", curi->size, "data"); + break; + case i_LSR: + genamode (curi->smode, "srcreg", curi->size, "cnt", 1, 0, 0); + genamode (curi->dmode, "dstreg", curi->size, "data", 1, 0, 0); + start_brace (); + switch (curi->size) { + case sz_byte: printf ("\tuae_u32 val = (uae_u8)data;\n"); break; + case sz_word: printf ("\tuae_u32 val = (uae_u16)data;\n"); break; + case sz_long: printf ("\tuae_u32 val = data;\n"); break; + default: abort (); + } + printf ("\tint ccnt = cnt & 63;\n"); + printf ("\tcnt &= 63;\n"); + printf ("\tCLEAR_CZNV (®s->ccrflags);\n"); + printf ("\tif (cnt >= %d) {\n", bit_size (curi->size)); + printf ("\t\tSET_CFLG (®s->ccrflags, (cnt == %d) & (val >> %d));\n", + bit_size (curi->size), bit_size (curi->size) - 1); + duplicate_carry (1); + printf ("\t\tval = 0;\n"); + if (source_is_imm1_8 (curi)) + printf ("\t} else {\n"); + else + printf ("\t} else if (cnt > 0) {\n"); + printf ("\t\tval >>= cnt - 1;\n"); + printf ("\t\tSET_CFLG (®s->ccrflags, val & 1);\n"); + duplicate_carry (1); + printf ("\t\tval >>= 1;\n"); + printf ("\t}\n"); + genflags (flag_logical_noclobber, curi->size, "val", "", ""); + shift_ce (curi->dmode, curi->size); + genastore ("val", curi->dmode, "dstreg", curi->size, "data"); + break; + case i_LSL: + genamode (curi->smode, "srcreg", curi->size, "cnt", 1, 0, 0); + genamode (curi->dmode, "dstreg", curi->size, "data", 1, 0, 0); + start_brace (); + switch (curi->size) { + case sz_byte: printf ("\tuae_u32 val = (uae_u8)data;\n"); break; + case sz_word: printf ("\tuae_u32 val = (uae_u16)data;\n"); break; + case sz_long: printf ("\tuae_u32 val = data;\n"); break; + default: abort (); + } + printf ("\tint ccnt = cnt & 63;\n"); + printf ("\tcnt &= 63;\n"); + printf ("\tCLEAR_CZNV (®s->ccrflags);\n"); + printf ("\tif (cnt >= %d) {\n", bit_size (curi->size)); + printf ("\t\tSET_CFLG (®s->ccrflags, cnt == %d ? val & 1 : 0);\n", + bit_size (curi->size)); + duplicate_carry (1); + printf ("\t\tval = 0;\n"); + if (source_is_imm1_8 (curi)) + printf ("\t} else {\n"); + else + printf ("\t} else if (cnt > 0) {\n"); + printf ("\t\tval <<= (cnt - 1);\n"); + printf ("\t\tSET_CFLG (®s->ccrflags, (val & %s) >> %d);\n", cmask (curi->size), bit_size (curi->size) - 1); + duplicate_carry (1); + printf ("\t\tval <<= 1;\n"); + printf ("\tval &= %s;\n", bit_mask (curi->size)); + printf ("\t}\n"); + genflags (flag_logical_noclobber, curi->size, "val", "", ""); + shift_ce (curi->dmode, curi->size); + genastore ("val", curi->dmode, "dstreg", curi->size, "data"); + break; + case i_ROL: + genamode (curi->smode, "srcreg", curi->size, "cnt", 1, 0, 0); + genamode (curi->dmode, "dstreg", curi->size, "data", 1, 0, 0); + start_brace (); + switch (curi->size) { + case sz_byte: printf ("\tuae_u32 val = (uae_u8)data;\n"); break; + case sz_word: printf ("\tuae_u32 val = (uae_u16)data;\n"); break; + case sz_long: printf ("\tuae_u32 val = data;\n"); break; + default: abort (); + } + printf ("\tint ccnt = cnt & 63;\n"); + printf ("\tcnt &= 63;\n"); + printf ("\tCLEAR_CZNV (®s->ccrflags);\n"); + if (source_is_imm1_8 (curi)) + printf ("{"); + else + printf ("\tif (cnt > 0) {\n"); + printf ("\tuae_u32 loval;\n"); + printf ("\tcnt &= %d;\n", bit_size (curi->size) - 1); + printf ("\tloval = val >> (%d - cnt);\n", bit_size (curi->size)); + printf ("\tval <<= cnt;\n"); + printf ("\tval |= loval;\n"); + printf ("\tval &= %s;\n", bit_mask (curi->size)); + printf ("\tSET_CFLG (®s->ccrflags, val & 1);\n"); + printf ("}\n"); + genflags (flag_logical_noclobber, curi->size, "val", "", ""); + shift_ce (curi->dmode, curi->size); + genastore ("val", curi->dmode, "dstreg", curi->size, "data"); + break; + case i_ROR: + genamode (curi->smode, "srcreg", curi->size, "cnt", 1, 0, 0); + genamode (curi->dmode, "dstreg", curi->size, "data", 1, 0, 0); + start_brace (); + switch (curi->size) { + case sz_byte: printf ("\tuae_u32 val = (uae_u8)data;\n"); break; + case sz_word: printf ("\tuae_u32 val = (uae_u16)data;\n"); break; + case sz_long: printf ("\tuae_u32 val = data;\n"); break; + default: abort (); + } + printf ("\tint ccnt = cnt & 63;\n"); + printf ("\tcnt &= 63;\n"); + printf ("\tCLEAR_CZNV (®s->ccrflags);\n"); + if (source_is_imm1_8 (curi)) + printf ("{"); + else + printf ("\tif (cnt > 0) {"); + printf ("\tuae_u32 hival;\n"); + printf ("\tcnt &= %d;\n", bit_size (curi->size) - 1); + printf ("\thival = val << (%d - cnt);\n", bit_size (curi->size)); + printf ("\tval >>= cnt;\n"); + printf ("\tval |= hival;\n"); + printf ("\tval &= %s;\n", bit_mask (curi->size)); + printf ("\tSET_CFLG (®s->ccrflags, (val & %s) >> %d);\n", cmask (curi->size), bit_size (curi->size) - 1); + printf ("\t}\n"); + genflags (flag_logical_noclobber, curi->size, "val", "", ""); + shift_ce (curi->dmode, curi->size); + genastore ("val", curi->dmode, "dstreg", curi->size, "data"); + break; + case i_ROXL: + genamode (curi->smode, "srcreg", curi->size, "cnt", 1, 0, 0); + genamode (curi->dmode, "dstreg", curi->size, "data", 1, 0, 0); + start_brace (); + switch (curi->size) { + case sz_byte: printf ("\tuae_u32 val = (uae_u8)data;\n"); break; + case sz_word: printf ("\tuae_u32 val = (uae_u16)data;\n"); break; + case sz_long: printf ("\tuae_u32 val = data;\n"); break; + default: abort (); + } + printf ("\tint ccnt = cnt & 63;\n"); + printf ("\tcnt &= 63;\n"); + printf ("\tCLEAR_CZNV (®s->ccrflags);\n"); + if (source_is_imm1_8 (curi)) + printf ("{"); + else { + force_range_for_rox ("cnt", curi->size); + printf ("\tif (cnt > 0) {\n"); + } + printf ("\tcnt--;\n"); + printf ("\t{\n\tuae_u32 carry;\n"); + printf ("\tuae_u32 loval = val >> (%d - cnt);\n", bit_size (curi->size) - 1); + printf ("\tcarry = loval & 1;\n"); + printf ("\tval = (((val << 1) | GET_XFLG (®s->ccrflags)) << cnt) | (loval >> 1);\n"); + printf ("\tSET_XFLG (®s->ccrflags, carry);\n"); + printf ("\tval &= %s;\n", bit_mask (curi->size)); + printf ("\t} }\n"); + printf ("\tSET_CFLG (®s->ccrflags, GET_XFLG (®s->ccrflags));\n"); + genflags (flag_logical_noclobber, curi->size, "val", "", ""); + shift_ce (curi->dmode, curi->size); + genastore ("val", curi->dmode, "dstreg", curi->size, "data"); + break; + case i_ROXR: + genamode (curi->smode, "srcreg", curi->size, "cnt", 1, 0, 0); + genamode (curi->dmode, "dstreg", curi->size, "data", 1, 0, 0); + start_brace (); + switch (curi->size) { + case sz_byte: printf ("\tuae_u32 val = (uae_u8)data;\n"); break; + case sz_word: printf ("\tuae_u32 val = (uae_u16)data;\n"); break; + case sz_long: printf ("\tuae_u32 val = data;\n"); break; + default: abort (); + } + printf ("\tint ccnt = cnt & 63;\n"); + printf ("\tcnt &= 63;\n"); + printf ("\tCLEAR_CZNV (®s->ccrflags);\n"); + if (source_is_imm1_8 (curi)) + printf ("{"); + else { + force_range_for_rox ("cnt", curi->size); + printf ("\tif (cnt > 0) {\n"); + } + printf ("\tcnt--;\n"); + printf ("\t{\n\tuae_u32 carry;\n"); + printf ("\tuae_u32 hival = (val << 1) | GET_XFLG (®s->ccrflags);\n"); + printf ("\thival <<= (%d - cnt);\n", bit_size (curi->size) - 1); + printf ("\tval >>= cnt;\n"); + printf ("\tcarry = val & 1;\n"); + printf ("\tval >>= 1;\n"); + printf ("\tval |= hival;\n"); + printf ("\tSET_XFLG (®s->ccrflags, carry);\n"); + printf ("\tval &= %s;\n", bit_mask (curi->size)); + printf ("\t} }\n"); + printf ("\tSET_CFLG (®s->ccrflags, GET_XFLG (®s->ccrflags));\n"); + genflags (flag_logical_noclobber, curi->size, "val", "", ""); + shift_ce (curi->dmode, curi->size); + genastore ("val", curi->dmode, "dstreg", curi->size, "data"); + break; + case i_ASRW: + genamode (curi->smode, "srcreg", curi->size, "data", 1, 0, 0); + start_brace (); + switch (curi->size) { + case sz_byte: printf ("\tuae_u32 val = (uae_u8)data;\n"); break; + case sz_word: printf ("\tuae_u32 val = (uae_u16)data;\n"); break; + case sz_long: printf ("\tuae_u32 val = data;\n"); break; + default: abort (); + } + printf ("\tuae_u32 sign = %s & val;\n", cmask (curi->size)); + printf ("\tuae_u32 cflg = val & 1;\n"); + printf ("\tval = (val >> 1) | sign;\n"); + genflags (flag_logical, curi->size, "val", "", ""); + printf ("\tSET_CFLG (®s->ccrflags, cflg);\n"); + duplicate_carry (0); + genastore ("val", curi->smode, "srcreg", curi->size, "data"); + break; + case i_ASLW: + genamode (curi->smode, "srcreg", curi->size, "data", 1, 0, 0); + start_brace (); + switch (curi->size) { + case sz_byte: printf ("\tuae_u32 val = (uae_u8)data;\n"); break; + case sz_word: printf ("\tuae_u32 val = (uae_u16)data;\n"); break; + case sz_long: printf ("\tuae_u32 val = data;\n"); break; + default: abort (); + } + printf ("\tuae_u32 sign = %s & val;\n", cmask (curi->size)); + printf ("\tuae_u32 sign2;\n"); + printf ("\tval <<= 1;\n"); + genflags (flag_logical, curi->size, "val", "", ""); + printf ("\tsign2 = %s & val;\n", cmask (curi->size)); + printf ("\tSET_CFLG (®s->ccrflags, sign != 0);\n"); + duplicate_carry (0); + + printf ("\tSET_VFLG (®s->ccrflags, GET_VFLG (®s->ccrflags) | (sign2 != sign));\n"); + genastore ("val", curi->smode, "srcreg", curi->size, "data"); + break; + case i_LSRW: + genamode (curi->smode, "srcreg", curi->size, "data", 1, 0, 0); + start_brace (); + switch (curi->size) { + case sz_byte: printf ("\tuae_u32 val = (uae_u8)data;\n"); break; + case sz_word: printf ("\tuae_u32 val = (uae_u16)data;\n"); break; + case sz_long: printf ("\tuae_u32 val = data;\n"); break; + default: abort (); + } + printf ("\tuae_u32 carry = val & 1;\n"); + printf ("\tval >>= 1;\n"); + genflags (flag_logical, curi->size, "val", "", ""); + printf ("SET_CFLG (®s->ccrflags, carry);\n"); + duplicate_carry (0); + genastore ("val", curi->smode, "srcreg", curi->size, "data"); + break; + case i_LSLW: + genamode (curi->smode, "srcreg", curi->size, "data", 1, 0, 0); + start_brace (); + switch (curi->size) { + case sz_byte: printf ("\tuae_u8 val = data;\n"); break; + case sz_word: printf ("\tuae_u16 val = data;\n"); break; + case sz_long: printf ("\tuae_u32 val = data;\n"); break; + default: abort (); + } + printf ("\tuae_u32 carry = val & %s;\n", cmask (curi->size)); + printf ("\tval <<= 1;\n"); + genflags (flag_logical, curi->size, "val", "", ""); + printf ("SET_CFLG (®s->ccrflags, carry >> %d);\n", bit_size (curi->size) - 1); + duplicate_carry (0); + genastore ("val", curi->smode, "srcreg", curi->size, "data"); + break; + case i_ROLW: + genamode (curi->smode, "srcreg", curi->size, "data", 1, 0, 0); + start_brace (); + switch (curi->size) { + case sz_byte: printf ("\tuae_u8 val = data;\n"); break; + case sz_word: printf ("\tuae_u16 val = data;\n"); break; + case sz_long: printf ("\tuae_u32 val = data;\n"); break; + default: abort (); + } + printf ("\tuae_u32 carry = val & %s;\n", cmask (curi->size)); + printf ("\tval <<= 1;\n"); + printf ("\tif (carry) val |= 1;\n"); + genflags (flag_logical, curi->size, "val", "", ""); + printf ("SET_CFLG (®s->ccrflags, carry >> %d);\n", bit_size (curi->size) - 1); + genastore ("val", curi->smode, "srcreg", curi->size, "data"); + break; + case i_RORW: + genamode (curi->smode, "srcreg", curi->size, "data", 1, 0, 0); + start_brace (); + switch (curi->size) { + case sz_byte: printf ("\tuae_u8 val = data;\n"); break; + case sz_word: printf ("\tuae_u16 val = data;\n"); break; + case sz_long: printf ("\tuae_u32 val = data;\n"); break; + default: abort (); + } + printf ("\tuae_u32 carry = val & 1;\n"); + printf ("\tval >>= 1;\n"); + printf ("\tif (carry) val |= %s;\n", cmask (curi->size)); + genflags (flag_logical, curi->size, "val", "", ""); + printf ("SET_CFLG (®s->ccrflags, carry);\n"); + genastore ("val", curi->smode, "srcreg", curi->size, "data"); + break; + case i_ROXLW: + genamode (curi->smode, "srcreg", curi->size, "data", 1, 0, 0); + start_brace (); + switch (curi->size) { + case sz_byte: printf ("\tuae_u8 val = data;\n"); break; + case sz_word: printf ("\tuae_u16 val = data;\n"); break; + case sz_long: printf ("\tuae_u32 val = data;\n"); break; + default: abort (); + } + printf ("\tuae_u32 carry = val & %s;\n", cmask (curi->size)); + printf ("\tval <<= 1;\n"); + printf ("\tif (GET_XFLG (®s->ccrflags)) val |= 1;\n"); + genflags (flag_logical, curi->size, "val", "", ""); + printf ("SET_CFLG (®s->ccrflags, carry >> %d);\n", bit_size (curi->size) - 1); + duplicate_carry (0); + genastore ("val", curi->smode, "srcreg", curi->size, "data"); + break; + case i_ROXRW: + genamode (curi->smode, "srcreg", curi->size, "data", 1, 0, 0); + start_brace (); + switch (curi->size) { + case sz_byte: printf ("\tuae_u8 val = data;\n"); break; + case sz_word: printf ("\tuae_u16 val = data;\n"); break; + case sz_long: printf ("\tuae_u32 val = data;\n"); break; + default: abort (); + } + printf ("\tuae_u32 carry = val & 1;\n"); + printf ("\tval >>= 1;\n"); + printf ("\tif (GET_XFLG (®s->ccrflags)) val |= %s;\n", cmask (curi->size)); + genflags (flag_logical, curi->size, "val", "", ""); + printf ("SET_CFLG (®s->ccrflags, carry);\n"); + duplicate_carry (0); + genastore ("val", curi->smode, "srcreg", curi->size, "data"); + break; + case i_PACK: + if (curi->smode == Dreg) { + printf ("\tuae_u16 val = m68k_dreg(regs, srcreg) + %s;\n", gen_nextiword (0)); + printf ("\tm68k_dreg(regs, dstreg) = (m68k_dreg(regs, dstreg) & 0xffffff00) | ((val >> 4) & 0xf0) | (val & 0xf);\n"); + } else { + printf ("\tuae_u16 val;\n"); + printf ("\tm68k_areg(regs, srcreg) -= areg_byteinc[srcreg];\n"); + printf ("\tval = (uae_u16)get_byte(m68k_areg(regs, srcreg));\n"); + printf ("\tm68k_areg(regs, srcreg) -= areg_byteinc[srcreg];\n"); + printf ("\tval = (val | ((uae_u16)mini_get_byte(m68k_areg(regs, srcreg)) << 8)) + %s;\n", gen_nextiword (0)); + printf ("\tm68k_areg(regs, dstreg) -= areg_byteinc[dstreg];\n"); + printf ("\tmini_put_byte(m68k_areg(regs, dstreg),((val >> 4) & 0xf0) | (val & 0xf));\n"); + } + break; + case i_UNPK: + if (curi->smode == Dreg) { + printf ("\tuae_u16 val = m68k_dreg(regs, srcreg);\n"); + printf ("\tval = (((val << 4) & 0xf00) | (val & 0xf)) + %s;\n", gen_nextiword (0)); + printf ("\tm68k_dreg(regs, dstreg) = (m68k_dreg(regs, dstreg) & 0xffff0000) | (val & 0xffff);\n"); + } else { + printf ("\tuae_u16 val;\n"); + printf ("\tm68k_areg(regs, srcreg) -= areg_byteinc[srcreg];\n"); + printf ("\tval = (uae_u16)get_byte(m68k_areg(regs, srcreg));\n"); + printf ("\tval = (((val << 4) & 0xf00) | (val & 0xf)) + %s;\n", gen_nextiword (0)); + printf ("\tm68k_areg(regs, dstreg) -= areg_byteinc[dstreg];\n"); + printf ("\tmini_put_byte(m68k_areg(regs, dstreg),val);\n"); + printf ("\tm68k_areg(regs, dstreg) -= areg_byteinc[dstreg];\n"); + printf ("\tmini_put_byte(m68k_areg(regs, dstreg),val >> 8);\n"); + } + break; + case i_TAS: + genamode (curi->smode, "srcreg", curi->size, "src", 1, 0, 0); + genflags (flag_logical, curi->size, "src", "", ""); + printf ("\tsrc |= 0x80;\n"); + genastore ("src", curi->smode, "srcreg", curi->size, "src"); + break; + default: + return; + } + finish_braces (); + if (limit_braces) { + printf ("\n#endif\n"); + n_braces = limit_braces; + limit_braces = 0; + finish_braces (); + } + sync_m68k_pc (); +} + +static void generate_includes (FILE * f) +{ + fprintf (f, "#include \"sysconfig.h\"\n"); + fprintf (f, "#include \"sysdeps.h\"\n"); + fprintf (f, "#include \"options.h\"\n"); + fprintf (f, "#include \"memory.h\"\n"); + fprintf (f, "#include \"custom.h\"\n"); + fprintf (f, "#include \"events.h\"\n"); + fprintf (f, "#include \"newcpu.h\"\n"); + fprintf (f, "#include \"cpu_prefetch.h\"\n"); + fprintf (f, "#include \"cputbl.h\"\n"); + + fprintf (f, "#define CPUFUNC(x) x##_ff\n" + "#define SET_CFLG_ALWAYS(flags, x) SET_CFLG(flags, x)\n" + "#define SET_NFLG_ALWAYS(flags, x) SET_NFLG(flags, x)\n" + "#ifdef NOFLAGS\n" + "#include \"noflags.h\"\n" + "#endif\n"); +} + +static int postfix; + + +static char *decodeEA (amodes mode, wordsizes size) +{ + static char buffer[80]; + + buffer[0] = 0; + switch (mode){ + case Dreg: + strcpy (buffer,"Dn"); + break; + case Areg: + strcpy (buffer,"An"); + break; + case Aind: + strcpy (buffer,"(An)"); + break; + case Aipi: + strcpy (buffer,"(An)+"); + break; + case Apdi: + strcpy (buffer,"-(An)"); + break; + case Ad16: + strcpy (buffer,"(d16,An)"); + break; + case Ad8r: + strcpy (buffer,"(d8,An,Xn)"); + break; + case PC16: + strcpy (buffer,"(d16,PC)"); + break; + case PC8r: + strcpy (buffer,"(d8,PC,Xn)"); + break; + case absw: + strcpy (buffer,"(xxx).W"); + break; + case absl: + strcpy (buffer,"(xxx).L"); + break; + case imm: + switch (size){ + case sz_byte: + strcpy (buffer,"#.B"); + break; + case sz_word: + strcpy (buffer,"#.W"); + break; + case sz_long: + strcpy (buffer,"#.L"); + break; + default: + break; + } + break; + case imm0: + strcpy (buffer,"#.B"); + break; + case imm1: + strcpy (buffer,"#.W"); + break; + case imm2: + strcpy (buffer,"#.L"); + break; + case immi: + strcpy (buffer,"#"); + break; + + default: + break; + } + return buffer; +} + +static char *outopcode (int opcode) +{ + static char out[100]; + struct instr *ins; + int i; + + ins = &table68k[opcode]; + for (i = 0; lookuptab[i].name[0]; i++) { + if (ins->mnemo == lookuptab[i].mnemo) + break; + } + strcpy (out, lookuptab[i].name); + if (ins->size == sz_byte) + strcat (out,".B"); + if (ins->size == sz_word) + strcat (out,".W"); + if (ins->size == sz_long) + strcat (out,".L"); + strcat (out," "); + if (ins->suse) + strcat (out, decodeEA (ins->smode, ins->size)); + if (ins->duse) { + if (ins->suse) strcat (out,","); + strcat (out, decodeEA (ins->dmode, ins->size)); + } + return out; +} + +static void generate_one_opcode (int rp) +{ + int i; + uae_u16 smsk, dmsk; + long int opcode = opcode_map[rp]; + int i68000 = table68k[opcode].clev > 0; + + if (table68k[opcode].mnemo == i_ILLG + || table68k[opcode].clev > cpu_level) + return; + + for (i = 0; lookuptab[i].name[0]; i++) { + if (table68k[opcode].mnemo == lookuptab[i].mnemo) + break; + } + + if (table68k[opcode].handler != -1) + return; + + if (opcode_next_clev[rp] != cpu_level) { + fprintf (stblfile, "{ CPUFUNC(op_%04lx_%d), %ld }, /* %s */\n", opcode, opcode_last_postfix[rp], + opcode, lookuptab[i].name); + return; + } + if (i68000) + fprintf (stblfile, "#ifndef CPUEMU_68000_ONLY\n"); + 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 %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 ("%s REGPARAM2 CPUFUNC(op_%04lx_%d)(uae_u32 opcode, struct regstruct *regs)\n{\n", using_ce ? "void" : "unsigned long", opcode, postfix); + + switch (table68k[opcode].stype) { + case 0: smsk = 7; break; + case 1: smsk = 255; break; + case 2: smsk = 15; break; + case 3: smsk = 7; break; + case 4: smsk = 7; break; + case 5: smsk = 63; break; + case 7: smsk = 3; break; + default: abort (); + } + dmsk = 7; + + next_cpu_level = -1; + if (table68k[opcode].suse + && table68k[opcode].smode != imm && table68k[opcode].smode != imm0 + && table68k[opcode].smode != imm1 && table68k[opcode].smode != imm2 + && table68k[opcode].smode != absw && table68k[opcode].smode != absl + && table68k[opcode].smode != PC8r && table68k[opcode].smode != PC16) + { + if (table68k[opcode].spos == -1) { + if (((int) table68k[opcode].sreg) >= 128) + printf ("\tuae_u32 srcreg = (uae_s32)(uae_s8)%d;\n", (int) table68k[opcode].sreg); + else + printf ("\tuae_u32 srcreg = %d;\n", (int) table68k[opcode].sreg); + } else { + char source[100]; + int pos = table68k[opcode].spos; + + if (pos) + sprintf (source, "((opcode >> %d) & %d)", pos, smsk); + else + sprintf (source, "(opcode & %d)", smsk); + + if (table68k[opcode].stype == 3) + printf ("\tuae_u32 srcreg = imm8_table[%s];\n", source); + else if (table68k[opcode].stype == 1) + printf ("\tuae_u32 srcreg = (uae_s32)(uae_s8)%s;\n", source); + else + printf ("\tuae_u32 srcreg = %s;\n", source); + } + } + if (table68k[opcode].duse + /* Yes, the dmode can be imm, in case of LINK or DBcc */ + && table68k[opcode].dmode != imm && table68k[opcode].dmode != imm0 + && table68k[opcode].dmode != imm1 && table68k[opcode].dmode != imm2 + && table68k[opcode].dmode != absw && table68k[opcode].dmode != absl) + { + if (table68k[opcode].dpos == -1) { + if (((int) table68k[opcode].dreg) >= 128) + printf ("\tuae_u32 dstreg = (uae_s32)(uae_s8)%d;\n", (int) table68k[opcode].dreg); + else + printf ("\tuae_u32 dstreg = %d;\n", (int) table68k[opcode].dreg); + } else { + int pos = table68k[opcode].dpos; + if (pos) + printf ("\tuae_u32 dstreg = (opcode >> %d) & %d;\n", + pos, dmsk); + else + printf ("\tuae_u32 dstreg = opcode & %d;\n", dmsk); + } + } + need_endlabel = 0; + endlabelno++; + sprintf (endlabelstr, "endlabel%d", endlabelno); + gen_opcode (opcode); + if (need_endlabel) + printf ("%s: ;\n", endlabelstr); + returncycles ("", insn_n_cycles); + printf ("}\n"); + if (i68000) + printf("#endif\n"); + opcode_next_clev[rp] = next_cpu_level; + opcode_last_postfix[rp] = postfix; +} + +static void generate_func (void) +{ + int j, rp; + + /* sam: this is for people with low memory (eg. me :)) */ + printf ("\n" + "#if !defined(PART_1) && !defined(PART_2) && " + "!defined(PART_3) && !defined(PART_4) && " + "!defined(PART_5) && !defined(PART_6) && " + "!defined(PART_7) && !defined(PART_8)" + "\n" + "#define PART_1 1\n" + "#define PART_2 1\n" + "#define PART_3 1\n" + "#define PART_4 1\n" + "#define PART_5 1\n" + "#define PART_6 1\n" + "#define PART_7 1\n" + "#define PART_8 1\n" + "#endif\n\n"); + + rp = 0; + for(j = 1; j <= 8; ++j) { + int k = (j * nr_cpuop_funcs) / 8; + printf ("#ifdef PART_%d\n",j); + for (; rp < k; rp++) + generate_one_opcode (rp); + printf ("#endif\n\n"); + } + + fprintf (stblfile, "{ 0, 0 }};\n"); +} + +int main (int argc, char **argv) +{ + int i, rp, postfix2; + char fname[100]; + + read_table68k (); + do_merges (); + + opcode_map = (int *) xmalloc (sizeof (int) * nr_cpuop_funcs); + opcode_last_postfix = (int *) xmalloc (sizeof (int) * nr_cpuop_funcs); + opcode_next_clev = (int *) xmalloc (sizeof (int) * nr_cpuop_funcs); + counts = (unsigned long *) xmalloc (65536 * sizeof (unsigned long)); + read_counts (); + + generate_func (); + + free (table68k); + return 0; +} diff --git a/include/zarchive.h b/include/zarchive.h index 545c53cf..a57a4bde 100755 --- a/include/zarchive.h +++ b/include/zarchive.h @@ -19,6 +19,7 @@ struct znode { struct zvolume *volume; struct znode *next; struct znode *prev; + struct znode *vfile; // points to real file when this node is virtual directory char *name; char *fullname; unsigned int size; @@ -40,6 +41,7 @@ struct zvolume struct znode root; struct zvolume *next; struct znode *last; + struct zvolume *parent; unsigned int size; unsigned int blocks; unsigned int id; @@ -67,6 +69,7 @@ struct zarchive_info extern int zfile_is_ignore_ext(const char *name); extern struct zvolume *zvolume_alloc(struct zfile *z, unsigned int id, void *handle); +extern struct zvolume *zvolume_alloc_empty(const char *name); extern struct znode *zvolume_addfile_abs(struct zvolume *zv, struct zarchive_info*); extern struct znode *zvolume_adddir_abs(struct zvolume *zv, struct zarchive_info *zai); diff --git a/od-win32/mman.c b/od-win32/mman.c index a22dd548..ff72b9f8 100755 --- a/od-win32/mman.c +++ b/od-win32/mman.c @@ -290,14 +290,8 @@ void *shmat(int shmid, void *shmaddr, int shmflg) p96ram_start = currprefs.z3fastmem_start + ((currprefs.z3fastmem_size + 0xffffff) & ~0xffffff); shmaddr = natmem_offset + p96ram_start; virtualfreewithlock(shmaddr, os_winnt ? size : 0, os_winnt ? MEM_DECOMMIT : MEM_RELEASE); - if (os_winnt) { - virtualfreewithlock(p96fakeram, p96fakeramsize, MEM_RELEASE); - p96fakeramsize = size + 4096; - p96fakeram = virtualallocwithlock(NULL, p96fakeramsize, MEM_COMMIT, 0); - } else { - xfree(p96fakeram); - result = p96fakeram = xcalloc (size + 4096, 1); - } + xfree(p96fakeram); + result = p96fakeram = xcalloc (size + 4096, 1); shmids[shmid].attached = result; return result; } diff --git a/od-win32/win32.c b/od-win32/win32.c index dfa7b0e7..f8d60941 100755 --- a/od-win32/win32.c +++ b/od-win32/win32.c @@ -87,6 +87,7 @@ RECT amigawin_rect; static UINT TaskbarRestart; static int TaskbarRestartOk; static int forceroms; +static int start_data = 0; char VersionStr[256]; char BetaStr[64]; @@ -1997,11 +1998,11 @@ void fetch_path (char *name, char *out, int size) strcat (out, "..\\shared\\rom\\"); if (!strcmp (name, "ConfigurationPath")) strcat (out, "Configurations\\"); - if (hWinUAEKey) + if (hWinUAEKey && start_data >= 0) RegQueryValueEx (hWinUAEKey, name, 0, NULL, out, &size); if (out[0] == '\\' && (strlen(out) >= 2 && out[1] != '\\')) { /* relative? */ strcpy (out, start_path_data); - if (hWinUAEKey) { + if (hWinUAEKey && start_data >= 0) { size2 -= strlen (out); RegQueryValueEx (hWinUAEKey, name, 0, NULL, out + strlen (out) - 1, &size2); } @@ -2512,7 +2513,7 @@ static int osdetect (void) typedef HRESULT (CALLBACK* SHGETFOLDERPATH)(HWND,int,HANDLE,DWORD,LPTSTR); typedef BOOL (CALLBACK* SHGETSPECIALFOLDERPATH)(HWND,LPTSTR,int,BOOL); -static void getstartpaths(int start_data) +static void getstartpaths(void) { SHGETFOLDERPATH pSHGetFolderPath; SHGETSPECIALFOLDERPATH pSHGetSpecialFolderPath; @@ -2696,7 +2697,6 @@ static void makeverstr(char *s) } static int multi_display = 1; -static int start_data = 0; static int process_arg(char **xargv) { @@ -2800,7 +2800,7 @@ static int process_arg(char **xargv) if (!strcmp (arg, "-datapath")) { i++; strcpy(start_path_data, np); - start_data = 1; + start_data = -1; continue; } if (!strcmp (arg, "-maxmem")) { @@ -2859,7 +2859,7 @@ static int PASCAL WinMain2 (HINSTANCE hInstance, HINSTANCE hPrevInstance, LPSTR argv = xcalloc (sizeof (char*), __argc); argc = process_arg(argv); - getstartpaths(start_data); + getstartpaths(); makeverstr(VersionStr); SetCurrentDirectory (start_path_data); diff --git a/od-win32/win32.h b/od-win32/win32.h index ea77c5ff..13d07473 100755 --- a/od-win32/win32.h +++ b/od-win32/win32.h @@ -15,9 +15,9 @@ #define GETBDM(x) (((x) - ((x / 10000) * 10000)) / 100) #define GETBDD(x) ((x) % 100) -#define WINUAEBETA 5 +#define WINUAEBETA 8 #define WINUAEPUBLICBETA 1 -#define WINUAEDATE MAKEBD(2007, 6, 18) +#define WINUAEDATE MAKEBD(2007, 6, 23) #define WINUAEEXTRA "" #define WINUAEREV "" diff --git a/od-win32/winuae_msvc/winuae_msvc.vcproj b/od-win32/winuae_msvc/winuae_msvc.vcproj index 6fb09dd1..f06fa8ad 100755 --- a/od-win32/winuae_msvc/winuae_msvc.vcproj +++ b/od-win32/winuae_msvc/winuae_msvc.vcproj @@ -2467,10 +2467,6 @@ RelativePath="..\resources\drive_startup.wav" > - - diff --git a/od-win32/winuaechangelog.txt b/od-win32/winuaechangelog.txt index 2ddce2d9..ff1df76e 100755 --- a/od-win32/winuaechangelog.txt +++ b/od-win32/winuaechangelog.txt @@ -1,4 +1,39 @@ +Beta 6: + +- rar unpacking double memory deallocation (unrar.dll is still + the most stupidly designed unpacking library) +- crash if dearchiver (rar or archiveaccess) was not available +- hardfile filesys loader/relocator sometimes incorrectly allocated + code/data space from chip memory +- lha/lzh archive detection fixed +- P96 ram allocation forced indirect JIT mode +- -datapath fixed, overrides paths-panel paths again + +- recursive harddrive archive support enabled + + Archives inside archive are only unpacked when first accessed for + best performance. Tested by creating 200MB zip archive that contained + ~250 pre-installed zipped WHDLoad demo slaves. (Note that this can + confuse some programs because size of "harddrive" gets bigger and + bigger the more archives inside archives are unpacked..) + + Original archive is "duplicated" as a directory called + .DIR + + "file not found" or "empty directory" is returned if decompression + fails + + In future there may be options to disable recursive archive support + and ability to replace original archive file with unpacked directory + (without .DIR extension) Another future idea is write access (to + separate "diff" directory) + + + Note: rar archive inside another archive can not be unpacked + without archiveaccess.dll (unrar.dll can't do it without temp + files and I refuse to use temp files) + Beta 5: - JIT on/off switching via uae-configuration re-enables direct mode @@ -31,6 +66,8 @@ Beta 5: mounted if safety check is not disabled and drive is non-empty. - disable "add harddrive" on vista without full admin privileges - harddisk panel directory and archive dragndrop added +- included beta updated rtg.library, fully enables >1024 pixel wide + bitmaps (including acceleration), obsoletes picasso96fix. (BR) Beta 4: diff --git a/zfile.c b/zfile.c index c3afd974..6cd19afb 100755 --- a/zfile.c +++ b/zfile.c @@ -8,6 +8,7 @@ */ #define ZLIB_WINAPI +#define RECURSIVE_ARCHIVES 1 #include "sysconfig.h" #include "sysdeps.h" @@ -274,7 +275,7 @@ static int iszip (struct zfile *z) { char *name = z->name; char *ext = strrchr (name, '.'); - uae_u8 header[6]; + uae_u8 header[7]; int i; if (!ext) @@ -289,12 +290,12 @@ static int iszip (struct zfile *z) return ArchiveFormat7Zip; if (!strcasecmp (ext, ".rar") && header[0] == 'R' && header[1] == 'a' && header[2] == 'r' && header[3] == '!') return ArchiveFormatRAR; - if ((!strcasecmp (ext, ".lha") || !strcasecmp (ext, ".lzh")) && header[2] == '-' && header[3] == 'l' && header[3] == 'h' && header[5] == '-') + if ((!strcasecmp (ext, ".lha") || !strcasecmp (ext, ".lzh")) && header[2] == '-' && header[3] == 'l' && header[4] == 'h' && header[6] == '-') return ArchiveFormatLHA; if (!strcasecmp (ext, ".lzx") && header[0] == 'L' && header[1] == 'Z' && header[2] == 'X') return ArchiveFormatLZX; #if defined(ARCHIVEACCESS) - for (i = 0; plugins_7z[i]; i++) { + for (i = 0; plugins_7z_x[i]; i++) { if (plugins_7z_x[i] && !strcasecmp (ext + 1, plugins_7z[i]) && !memcmp (header, plugins_7z_x[i], strlen (plugins_7z_x[i]))) return plugins_7z_t[i]; @@ -307,7 +308,7 @@ static struct zfile *zuncompress (struct zfile *z) { char *name = z->name; char *ext = strrchr (name, '.'); - uae_u8 header[6]; + uae_u8 header[7]; int i; if (ext != NULL) { @@ -316,8 +317,7 @@ static struct zfile *zuncompress (struct zfile *z) return archive_access_select (z, ArchiveFormat7Zip); if (strcasecmp (ext, "zip") == 0) return archive_access_select (z, ArchiveFormatZIP); - if (strcasecmp (ext, "lha") == 0 - || strcasecmp (ext, "lzh") == 0) + if (strcasecmp (ext, "lha") == 0 || strcasecmp (ext, "lzh") == 0) return archive_access_select (z, ArchiveFormatLHA); if (strcasecmp (ext, "lzx") == 0) return archive_access_select (z, ArchiveFormatLZX); @@ -334,7 +334,7 @@ static struct zfile *zuncompress (struct zfile *z) if (strcasecmp (ext, "dms") == 0) return dms (z); #if defined(ARCHIVEACCESS) - for (i = 0; plugins_7z[i]; i++) { + for (i = 0; plugins_7z_x[i]; i++) { if (strcasecmp (ext, plugins_7z[i]) == 0) return archive_access_arcacc_select (z, plugins_7z_t[i]); } @@ -353,7 +353,7 @@ static struct zfile *zuncompress (struct zfile *z) return dms (z); if (header[0] == 'L' && header[1] == 'Z' && header[2] == 'X') return archive_access_select (z, ArchiveFormatLZX); - if (header[2] == '-' && header[3] == 'l' && header[3] == 'h' && header[5] == '-') + if (header[2] == '-' && header[3] == 'l' && header[4] == 'h' && header[6] == '-') return archive_access_select (z, ArchiveFormatLHA); } return z; @@ -823,14 +823,26 @@ static struct znode *znode_alloc_sibling(struct znode *sibling, const char *name return zn; } -struct zvolume *zvolume_alloc(struct zfile *z, unsigned int id, void *handle) +static void zvolume_addtolist(struct zvolume *zv) +{ + if (!zv) + return; + if (!zvolume_list) { + zvolume_list = zv; + } else { + struct zvolume *v = zvolume_list; + while (v->next) + v = v->next; + v->next = zv; + } +} + +static struct zvolume *zvolume_alloc_2(const char *name, struct zfile *z, unsigned int id, void *handle) { struct zvolume *zv = xcalloc(sizeof (struct zvolume), 1); struct znode *root; - char *name; size_t pos; - name = zfile_getname(z); root = &zv->root; zv->last = root; zv->archive = z; @@ -840,20 +852,22 @@ struct zvolume *zvolume_alloc(struct zfile *z, unsigned int id, void *handle) root->volume = zv; root->name = my_strdup(name); root->fullname = my_strdup(name); - if (!zvolume_list) { - zvolume_list = zv; - } else { - struct zvolume *v = zvolume_list; - while (v->next) - v = v->next; - v->next = zv; + if (z) { + pos = zfile_ftell(z); + zfile_fseek(z, 0, SEEK_END); + zv->archivesize = zfile_ftell(z); + zfile_fseek(z, pos, SEEK_SET); } - pos = zfile_ftell(z); - zfile_fseek(z, 0, SEEK_END); - zv->archivesize = zfile_ftell(z); - zfile_fseek(z, pos, SEEK_SET); return zv; } +struct zvolume *zvolume_alloc(struct zfile *z, unsigned int id, void *handle) +{ + return zvolume_alloc_2(zfile_getname(z), z, id, handle); +} +struct zvolume *zvolume_alloc_empty(const char *name) +{ + return zvolume_alloc_2(name, 0, 0, 0); +} static struct zvolume *get_zvolume(const char *path) { @@ -867,14 +881,127 @@ static struct zvolume *get_zvolume(const char *path) return NULL; } +static struct zvolume *zfile_fopen_archive_ext(struct zfile *zf) +{ + struct zvolume *zv = NULL; + char *ext = strrchr (zfile_getname(zf), '.'); + + if (ext != NULL) { + ext++; + if (strcasecmp (ext, "lha") == 0 || strcasecmp (ext, "lzh") == 0) + zv = archive_directory_lha (zf); + if (strcasecmp (ext, "zip") == 0) + zv = archive_directory_zip (zf); + if (strcasecmp (ext, "7z") == 0) + zv = archive_directory_7z (zf); + if (strcasecmp (ext, "lzx") == 0) + zv = archive_directory_lzx (zf); + if (strcasecmp (ext, "rar") == 0) + zv = archive_directory_rar (zf); + } + return zv; +} + + +struct zvolume *zfile_fopen_archive_data(struct zfile *zf) +{ + struct zvolume *zv = NULL; + uae_u8 header[7]; + + memset (header, 0, sizeof (header)); + zfile_fread (header, sizeof (header), 1, zf); + zfile_fseek (zf, 0, SEEK_SET); + if (header[0] == 'P' && header[1] == 'K') + zv = archive_directory_zip (zf); + if (header[0] == 'R' && header[1] == 'a' && header[2] == 'r' && header[3] == '!') + zv = archive_directory_rar (zf); + if (header[0] == 'L' && header[1] == 'Z' && header[2] == 'X') + zv = archive_directory_lzx (zf); + if (header[2] == '-' && header[3] == 'l' && header[4] == 'h' && header[6] == '-') + zv = archive_directory_lha (zf); + return zv; +} + +static struct znode *get_znode(struct zvolume *zv, const char *ppath); + +static int zfile_fopen_archive_recurse(struct zvolume *zv) +{ + struct znode *zn; + int i, added; + + added = 0; + zn = zv->root.child; + while (zn) { + char *ext = strrchr (zn->name, '.'); + if (ext && !zn->vchild && zn->isfile) { + for (i = 0; plugins_7z[i]; i++) { + if (!strcasecmp(ext + 1, plugins_7z[i])) { + struct zvolume *zvnew; + struct znode *zndir; + char tmp[MAX_DPATH]; + + sprintf(tmp, "%s.DIR", zn->fullname + strlen(zv->root.name) + 1); + zndir = get_znode(zv, tmp); + if (!zndir) { + struct zarchive_info zai = { 0 }; + zvnew = zvolume_alloc_empty (tmp); + zai.name = tmp; + zai.t = zn->mtime; + zndir = zvolume_adddir_abs(zv, &zai); + zndir->vfile = zn; + zndir->vchild = zvnew; + zvnew->parent = zv; + } + } + } + } + zn = zn->next; + } + return 0; +} + +static void recursivepath(char *path, struct zvolume *zv) +{ + char tmp[2] = { FSDB_DIR_SEPARATOR, 0 }; + if (!zv) + return; + recursivepath(path, zv->parent); + strcat(path, zv->root.fullname); + strcat(path, tmp); +} + +static struct zvolume *prepare_recursive_volume(struct zvolume *zv, const char *path) +{ + struct zfile *zf = NULL; + struct zvolume *zvnew = NULL; + + write_log("unpacking '%s'\n", path); + zf = zfile_open_archive(path, 0); + if (!zf) + goto end; + zvnew = zfile_fopen_archive_ext(zf); + if (!zvnew) + goto end; + zvnew->parent = zv->parent; + zfile_fopen_archive_recurse(zvnew); + zfile_fclose_archive(zv); + return zvnew; +end: + write_log("unpack failed\n"); + zfile_fclose_archive (zvnew); + zfile_fclose(zf); + return NULL; +} + static struct znode *get_znode(struct zvolume *zv, const char *ppath) { struct znode *zn; - const char *path = ppath; int prevlen = 0; + char path[MAX_DPATH]; if (!zv) return NULL; + strcpy (path, ppath); zn = &zv->root; while (zn) { if (zn->isfile) { @@ -886,9 +1013,27 @@ static struct znode *get_znode(struct zvolume *zv, const char *ppath) if (path[len] == 0) return zn; if (zn->vchild) { - /* jump to separate tree */ - zn = zn->vchild->root.child; - path += prevlen + 1; + /* jump to separate tree, recursive archives */ + struct zvolume *zvdeep = zn->vchild; + char *p = path + prevlen + 1; + if (zvdeep->archive == NULL) { + zvdeep = prepare_recursive_volume(zvdeep, zn->fullname); + if (!zvdeep) { + write_log("failed to unpack '%s'\n", zn->fullname); + return NULL; + } + /* replace dummy empty volume with real volume */ + zn->vchild = zvdeep; + } + zn = zvdeep->root.child; + while (*p && *p != FSDB_DIR_SEPARATOR) + p++; + if (*p == 0) + return NULL; + p++; + strcpy (path, zn->volume->root.name); + memmove(path + strlen(path) + 1, p, strlen (p) + 1); + path[strlen(path)] = FSDB_DIR_SEPARATOR; } else { zn = zn->child; } @@ -902,6 +1047,19 @@ static struct znode *get_znode(struct zvolume *zv, const char *ppath) } +static void addvolumesize(struct zvolume *zv, int size) +{ + int blocks = (size + 511) / 512; + + if (blocks == 0) + blocks++; + while (zv) { + zv->blocks += blocks; + zv->size += size; + zv = zv->parent; + } +} + struct znode *znode_adddir(struct znode *parent, const char *name, struct zarchive_info *zai) { struct znode *zn; @@ -913,7 +1071,7 @@ struct znode *znode_adddir(struct znode *parent, const char *name, struct zarchi return zn; zn = znode_alloc_child(parent, name); zn->mtime = zai->t; - parent->volume->blocks++; + addvolumesize(parent->volume, 0); return zn; } @@ -962,95 +1120,12 @@ struct znode *zvolume_addfile_abs(struct zvolume *zv, struct zarchive_info *zai) if (zai->comment) zn->comment = my_strdup(zai->comment); zn->flags = zai->flags; - zn->volume->blocks += (zai->size + 511) / 512; - zn->volume->size += zai->size; + addvolumesize(zn->volume, zai->size); } xfree(path); return zn; } -static struct zvolume *zfile_fopen_archive_ext(struct zfile *zf) -{ - struct zvolume *zv = NULL; - char *ext = strrchr (zfile_getname(zf), '.'); - - if (ext != NULL) { - ext++; - if (strcasecmp (ext, "lha") == 0 || strcasecmp (ext, "lzh") == 0) - zv = archive_directory_lha (zf); - if (strcasecmp (ext, "zip") == 0) - zv = archive_directory_zip (zf); - if (strcasecmp (ext, "7z") == 0) - zv = archive_directory_7z (zf); - if (strcasecmp (ext, "lzx") == 0) - zv = archive_directory_lzx (zf); - if (strcasecmp (ext, "rar") == 0) - zv = archive_directory_rar (zf); - } - return zv; -} - - -struct zvolume *zfile_fopen_archive_data(struct zfile *zf) -{ - struct zvolume *zv = NULL; - uae_u8 header[6]; - - memset (header, 0, sizeof (header)); - zfile_fread (header, sizeof (header), 1, zf); - zfile_fseek (zf, 0, SEEK_SET); - if (header[0] == 'P' && header[1] == 'K') - zv = archive_directory_zip (zf); - if (header[0] == 'R' && header[1] == 'a' && header[2] == 'r' && header[3] == '!') - zv = archive_directory_rar (zf); - if (header[0] == 'L' && header[1] == 'Z' && header[2] == 'X') - zv = archive_directory_lzx (zf); - if (header[2] == '-' && header[3] == 'l' && header[3] == 'h' && header[5] == '-') - zv = archive_directory_lha (zf); - return zv; -} - -static int zfile_fopen_archive_recurse(struct zvolume *zv) -{ - struct znode *zn; - int i, added; - - added = 0; - zn = zv->root.child; - while (zn) { - char *ext = strrchr (zn->name, '.'); - if (ext && !zn->vchild && zn->isfile) { - for (i = 0; plugins_7z[i]; i++) { - if (!strcasecmp(ext + 1, plugins_7z[i])) { - struct zfile *zf; - struct zvolume *zvnew; - char tmp[MAX_DPATH]; - zf = zfile_open_archive(zn->fullname, 0); - zvnew = zfile_fopen_archive_ext(zf); - if (!zvnew) { - zfile_fclose(zf); - } else { - struct znode *zndir; - sprintf(tmp, "%s.DIR", zn->fullname + strlen(zv->root.name) + 1); - zndir = get_znode(zv, tmp); - if (!zndir) { - struct zarchive_info zai = { 0 }; - zai.name = tmp; - zai.t = zn->mtime; - zndir = zvolume_adddir_abs(zv, &zai); - zndir->vchild = zvnew; - zfile_fopen_archive_recurse(zvnew); - } - } - } - } - } - zn = zn->next; - } - return 0; -} - - struct zvolume *zfile_fopen_archive(const char *filename) { struct zvolume *zv = NULL; @@ -1061,13 +1136,14 @@ struct zvolume *zfile_fopen_archive(const char *filename) zv = zfile_fopen_archive_ext(zf); if (!zv) zv = zfile_fopen_archive_data(zf); -#if 0 +#if RECURSIVE_ARCHIVES if (zv) zfile_fopen_archive_recurse (zv); #endif /* pointless but who cares? */ if (!zv) zv = archive_directory_plain (zf); + zvolume_addtolist (zv); return zv; } @@ -1076,6 +1152,8 @@ void zfile_fclose_archive(struct zvolume *zv) struct znode *zn; struct zvolume *v; + if (!zv) + return; zn = &zv->root; while (zn) { struct znode *zn2 = zn->next; @@ -1117,10 +1195,16 @@ void *zfile_opendir_archive(const char *path) if (!zn || (!zn->child && !zn->vchild)) return NULL; - if (zn->child) + if (zn->child) { zd->n = zn->child; - else + } else { + if (zn->vchild->archive == NULL) { + struct zvolume *zvnew = prepare_recursive_volume (zn->vchild, path); + if (zvnew) + zn->vchild = zvnew; + } zd->n = zn->vchild->root.next; + } return zd; } void zfile_closedir_archive(struct zdirectory *zd) @@ -1206,7 +1290,9 @@ void *zfile_open_archive (const char *path, int flags) zfile_fseek(zn->f, 0, SEEK_SET); return zn->f; } - z = archive_getzfile (zn, zv->id); + if (zn->vfile) + zn = zn->vfile; + z = archive_getzfile (zn, zn->volume->id); if (z) zfile_fseek(z, 0, SEEK_SET); zn->f = z; diff --git a/zfile_archive.c b/zfile_archive.c index 2ae74e94..16248800 100755 --- a/zfile_archive.c +++ b/zfile_archive.c @@ -102,13 +102,16 @@ struct zfile *archive_getzfile(struct znode *zn, unsigned int id) struct zfile *archive_access_select (struct zfile *zf, unsigned int id) { - struct zvolume *zv = getzvolume(zf, id); + struct zvolume *zv; struct znode *zn; int zipcnt, first, select; char tmphist[MAX_DPATH]; struct zfile *z = NULL; int we_have_file; + zv = getzvolume(zf, id); + if (!zv) + return zf; we_have_file = 0; tmphist[0] = 0; zipcnt = 1; @@ -483,7 +486,6 @@ struct RARContext static void archive_close_rar(struct RARContext *rc) { - pRARCloseArchive (rc->hArcData); xfree(rc); } @@ -533,7 +535,6 @@ struct zvolume *archive_directory_rar (struct zfile *z) zftmp = zfile_fopen_empty (z->name, 0); zv->archive = zftmp; zv->method = ArchiveFormatRAR; - zfile_fclose(z); return zv; }