On keskiviikko 06 maaliskuu 2013, Laurent Sallafranque wrote:
When I added the "accurate cycles" for the 68030, I focused on the
"cycle exact" 68030 CPU, ie cpuemu_31.c
In that case you've unfortunately focused on the wrong file. :-/
As I stated earlier, OpcodeFamily isn't updated for the *default* WinUAE
core. Only generated cpuemu variants which don't update them are 20 and
21.
Default "cycle exact" 030 WinUAE CPU core uses the code from cpuemu_21..c
file, as can be seen from the WinUAE code:
---- src/cpu/newcpu.c ----
...
void build_cpufunctbl (void)
{
...
switch (currprefs.cpu_model)
{
...
case 68030:
lvl = 3;
tbl = op_smalltbl_2_ff;
if (currprefs.cpu_cycle_exact)
tbl = op_smalltbl_23_ff; <=== *****
if (currprefs.mmu_model)
tbl = op_smalltbl_32_ff;
break;
...
---- build/src/cpu/cpustbl.c ----
...
const struct cputbl CPUFUNC(op_smalltbl_23)[] = { <=== *****
{ (cpuop_func*)CPUFUNC(op_0000_21), 0 }, /* OR */
{ (cpuop_func*)CPUFUNC(op_0010_21), 16 }, /* OR */
...
{ (cpuop_func*)CPUFUNC(op_46fc_21), 18172 }, /* MV2SR */
{ (cpuop_func*)CPUFUNC(op_4800_23), 18432 }, /* NBCD */
{ (cpuop_func*)CPUFUNC(op_4808_21), 18440 }, /* LINK */
{ (cpuop_func*)CPUFUNC(op_4810_23), 18448 }, /* NBCD */
...
-----------------------------------
$ $ for i in src/cpu/cpuemu*.c; do
echo "$i:"; \
egrep -e 'op_[0-9a-f]*_21' -e 'op_[0-9a-f]*_23' $i | wc -l; \
done
src/cpu/cpuemu_0.c:
0
src/cpu/cpuemu_11.c:
0
src/cpu/cpuemu_12.c:
0
src/cpu/cpuemu_20.c:
0
src/cpu/cpuemu_21.c:
1893 <=== *****
src/cpu/cpuemu_31.c:
0
src/cpu/cpuemu_32.c:
0
----------------------------------
It's only with MMU that 31 & 32 variants are used.
In gencpu.c, you can see the code generated specifically for
the 030 "cycle-exact" CPU within "using_ce020 == 2" checks:
------------------------
static void returncycles (const char *s, int cycles)
{
if (using_ce)
return;
if (using_ce020 == 1)
printf ("%sreturn;\n", s);
else if (using_ce020 == 2) {
if (no_return_cycles == true)
return;
if (instr_table == TABLE_FALCON_CYCLES &&
table_falcon_cycles[instr_index].cache_cycles == 0) {
printf ("\tregs.ce030_instr_cycles =
table_falcon_cycles[0];\n");
}
else {
printf ("%s\tregs.ce030_instr_cycles =
%s[%d];\n", s, falcon_cycles_tables[instr_table], instr_table_index);
}
printf ("%s\treturn;\n", s);
}
else
printf ("%sreturn %d * CYCLE_UNIT / 2;\n", s, cycles);
}
...
static void genmovemel (uae_u16 opcode), and
static void genmovemle (uae_u16 opcode)
{
...
if (using_ce020 == 2) {
if (table68k[opcode].size == sz_long)
printf ("\tregs.ce030_instr_addcycles =
regs_number * 8;\n");
else
printf ("\tregs.ce030_instr_addcycles =
regs_number * 4;\n");
}
fill_prefetch_next ();
}
...
static void gen_opcode (unsigned long int opcode)
{
struct instr *curi = table68k + opcode;
insn_n_cycles = using_prefetch ? 0 : 4;
if (!using_ce020) {
printf ("\tOpcodeFamily = %d; CurrentInstrCycles =
\n", curi->mnemo);
nCurInstrCycPos = ftell(stdout) - 5;
}
else if (using_ce020 == 2) {
instr_table = TABLE_FALCON_CYCLES;
instr_table_index = instr_index;
no_return_cycles = false;
}
if (using_ce020) {
if (using_ce020 == 2) {
ce020_prefetch_long = "get_long_ce030_prefetch";
ce020_prefetch_word = "get_word_ce030_prefetch";
srcl = "get_long_ce030";
dstl = "put_long_ce030";
srcw = "get_word_ce030";
dstw = "put_word_ce030";
srcb = "get_byte_ce030";
dstb = "put_byte_ce030";
} else {
ce020_prefetch_long = "get_long_ce020_prefetch";
ce020_prefetch_word = "get_word_ce020_prefetch";
srcl = "get_long_ce020";
dstl = "put_long_ce020";
srcw = "get_word_ce020";
dstw = "put_word_ce020";
srcb = "get_byte_ce020";
dstb = "put_byte_ce020";
}
...
case i_RTS:
printf ("\tuaecptr pc = m68k_getpc ();\n");
if (using_ce020 == 1)
printf ("\tm68k_do_rts_ce020 ();\n");
else if (using_ce020 == 2)
printf ("\tm68k_do_rts_ce030 ();\n");
...
if (using_ce020 == 2) { /* For Falcon cycle exact timings
only (CPU_EMU_21) */
if (curi->size == sz_byte)
instr_table_index = 1;
else if (curi->size == sz_word)
instr_table_index = 2;
else
instr_table_index = 3;
}
...
int main (int argc, char **argv)
{
for (i = 0; i <= 32; i++) {
postfix = i;
if ((i >= 6 && i < 11) || (i > 12 && i < 20) || (i > 23
&& i < 31))
continue;
generate_stbl = 1;
// REDUNDANT CHECK, above if already handles this!
if (i == 0 || i == 11 || i == 12 || i == 20 || i == 21
|| i == 31 || i == 32) {
if (generate_stbl)
fprintf (stblfile, "#ifdef CPUEMU_%d\n",
postfix);
postfix2 = postfix;
sprintf (fname, "cpuemu_%d.c", postfix);
if (freopen (fname, "wb", stdout) == NULL) {
perror(fname);
return -1;
}
generate_includes (stdout);
}
using_mmu = 0;
using_prefetch = 0;
using_ce = 0;
using_ce020 = 0;
using_mmu = 0;
cpu_level = 5 - i;
if (i == 11 || i == 12) {
cpu_level = 0;
using_prefetch = 1;
using_exception_3 = 1;
if (i == 12)
using_ce = 1;
for (rp = 0; rp < nr_cpuop_funcs; rp++)
opcode_next_clev[rp] = 0;
} else if (i == 20) {
cpu_level = 2;
using_ce020 = 1;
read_counts ();
for (rp = 0; rp < nr_cpuop_funcs; rp++)
opcode_next_clev[rp] = cpu_level;
} else if (i == 21 || i == 22 || i == 23) {
cpu_level = 3 + (23 - i);
using_ce020 = 2;
if (i == 21) {
read_counts ();
for (rp = 0; rp < nr_cpuop_funcs; rp++)
opcode_next_clev[rp] = cpu_level;
}
} else if (i >= 31 && i < 40) {
cpu_level = 3 + 32 - i;
using_mmu = 1;
if (cpu_level == 3) {
fprintf (stdout, "#include
\"cpummu030.h\"\n");
mmu_postfix = "030";
}
else {
fprintf (stdout, "#include
\"cpummu.h\"\n"); mmu_postfix = "";
}
if (i == 31)
read_counts ();
for (rp = 0; rp < nr_cpuop_funcs; rp++)
opcode_next_clev[rp] = cpu_level;
}
---------
(comments are removed as they make this harder to read)
- Eero