--- hatari/src/uae-cpu/readcpu.c 2019/04/01 07:09:16 1.1 +++ hatari/src/uae-cpu/readcpu.c 2019/04/09 08:47:24 1.1.1.10 @@ -1,23 +1,31 @@ /* - * UAE - The Un*x Amiga Emulator + * UAE - The Un*x Amiga Emulator - CPU core * * Read 68000 CPU specs from file "table68k" * * Copyright 1995,1996 Bernd Schmidt + * + * Adaptation to Hatari by Thomas Huth + * + * This file is distributed under the GNU Public License, version 2 or at + * your option any later version. Read the file gpl.txt for details. */ + +/* 2008/04/26 [NP] Handle sz_byte for Areg as a valid srcmode if current instruction is a MOVE */ +/* (e.g. move.b a1,(a0) ($1089)) (fix Blood Money on Superior 65) */ + + +const char ReadCpu_fileid[] = "Hatari readcpu.c : " __DATE__ " " __TIME__; + #include -/* -#include "sysconfig.h" -#include "config.h" -#include "options.h" -*/ -#include "sysdeps.h" +#include + #include "readcpu.h" int nr_cpuop_funcs; -struct mnemolookup lookuptab[] = { +const struct mnemolookup lookuptab[] = { { i_ILLG, "ILLEGAL" }, { i_OR, "OR" }, { i_CHK, "CHK" }, @@ -194,37 +202,44 @@ static void build_insn (int insn) { int find = -1; int variants; + int isjmp = 0; struct instr_def id; const char *opcstr; - int i; + int j; int flaglive = 0, flagdead = 0; id = defs68k[insn]; - for (i = 0; i < 5; i++) { - switch (id.flaginfo[i].flagset){ + /* Note: We treat anything with unknown flags as a jump. That + is overkill, but "the programmer" was lazy quite often, and + *this* programmer can't be bothered to work out what can and + can't trap. Usually, this will be overwritten with the gencomp + based information, anyway. */ + + for (j = 0; j < 5; j++) { + switch (id.flaginfo[j].flagset){ case fa_unset: break; - case fa_isjmp: break; - case fa_zero: flagdead |= 1 << i; break; - case fa_one: flagdead |= 1 << i; break; - case fa_dontcare: flagdead |= 1 << i; break; - case fa_unknown: flagdead = -1; goto out1; - case fa_set: flagdead |= 1 << i; break; + case fa_isjmp: isjmp = 1; break; + case fa_isbranch: isjmp = 1; break; + case fa_zero: flagdead |= 1 << j; break; + case fa_one: flagdead |= 1 << j; break; + case fa_dontcare: flagdead |= 1 << j; break; + case fa_unknown: isjmp = 1; flagdead = -1; goto out1; + case fa_set: flagdead |= 1 << j; break; } } - out1: - for (i = 0; i < 5; i++) { - switch (id.flaginfo[i].flaguse) { + out1: + for (j = 0; j < 5; j++) { + switch (id.flaginfo[j].flaguse) { case fu_unused: break; - case fu_isjmp: flaglive |= 1 << i; break; - case fu_maybecc: flaglive |= 1 << i; break; - case fu_unknown: flaglive = -1; goto out2; - case fu_used: flaglive |= 1 << i; break; + case fu_isjmp: isjmp = 1; flaglive |= 1 << j; break; + case fu_maybecc: isjmp = 1; flaglive |= 1 << j; break; + case fu_unknown: isjmp = 1; flaglive |= 1 << j; break; + case fu_used: flaglive |= 1 << j; break; } } - out2: opcstr = id.opcstr; for (variants = 0; variants < (1 << id.n_variable); variants++) { @@ -283,7 +298,7 @@ static void build_insn (int insn) bitval[bitc] = bitval[bitC]; pos = 0; - while (opcstr[pos] && !isspace(opcstr[pos])) { + while (opcstr[pos] && !isspace((unsigned)opcstr[pos])) { if (opcstr[pos] == '.') { pos++; switch (opcstr[pos]) { @@ -318,7 +333,7 @@ static void build_insn (int insn) mnemonic[mnp] = 0; /* now, we have read the mnemonic and the size */ - while (opcstr[pos] && isspace(opcstr[pos])) + while (opcstr[pos] && isspace((unsigned)opcstr[pos])) pos++; /* A goto a day keeps the D******a away. */ @@ -349,6 +364,9 @@ static void build_insn (int insn) case 'P': srcmode = Aipi; pos++; break; } break; + case 'L': + srcmode = absl; + break; case '#': switch (opcstr[pos++]) { case 'z': srcmode = imm; break; @@ -394,6 +412,14 @@ static void build_insn (int insn) srcpos = bitpos[bitK]; } break; + case 'p': srcmode = immi; srcreg = bitval[bitK]; + if (CPU_EMU_SIZE < 5) { + /* 0..3 */ + srcgather = 1; + srctype = 7; + srcpos = bitpos[bitp]; + } + break; default: abort(); } break; @@ -501,7 +527,8 @@ static void build_insn (int insn) { srcgather = 0; } - if (srcmode == Areg && sz == sz_byte) +// if (srcmode == Areg && sz == sz_byte) + if (srcmode == Areg && sz == sz_byte && strcmp ( mnemonic , "MOVE" ) != 0 ) // [NP] move.b is valid on 68000 goto nomatch; if (opcstr[pos] != ',') @@ -518,19 +545,27 @@ static void build_insn (int insn) case 'R': destreg = bitval[bitR]; dstgather = 1; dstpos = bitpos[bitR]; break; default: abort(); } + if (dstpos < 0 || dstpos >= 32) + abort (); break; case 'A': destmode = Areg; switch (opcstr[pos++]) { case 'r': destreg = bitval[bitr]; dstgather = 1; dstpos = bitpos[bitr]; break; case 'R': destreg = bitval[bitR]; dstgather = 1; dstpos = bitpos[bitR]; break; + case 'x': destreg = 0; dstgather = 0; dstpos = 0; break; default: abort(); } + if (dstpos < 0 || dstpos >= 32) + abort (); switch (opcstr[pos]) { case 'p': destmode = Apdi; pos++; break; case 'P': destmode = Aipi; pos++; break; } break; + case 'L': + destmode = absl; + break; case '#': switch (opcstr[pos++]) { case 'z': destmode = imm; break; @@ -703,7 +738,8 @@ static void build_insn (int insn) #endif table68k[opc].flagdead = flagdead; table68k[opc].flaglive = flaglive; - nomatch: + table68k[opc].isjmp = isjmp; + nomatch: /* FOO! */; } } @@ -748,6 +784,8 @@ static void handle_merges (long int opco smsk = 7; sbitdst = 8; break; case 5: smsk = 63; sbitdst = 64; break; + case 7: + smsk = 3; sbitdst = 4; break; default: smsk = 0; sbitdst = 0; abort();