Compare commits
12 commits
master
...
basilisk-s
| Author | SHA1 | Date | |
|---|---|---|---|
| 8dcac80091 | |||
| 43de90a9df | |||
|
|
b3144f12c1 | ||
|
|
c8c2089edd | ||
|
|
0b85a7a648 | ||
|
|
d4c4aa290d | ||
|
|
91ecb76b7b | ||
|
|
765c5af223 | ||
|
|
c2695c09d7 | ||
|
|
2ff6fd0683 | ||
|
|
fc885ffb03 | ||
|
|
7fcef8fe6a |
9 changed files with 339 additions and 62 deletions
|
|
@ -183,6 +183,27 @@
|
|||
#define M68K_LOG_1010_1111 OPT_OFF
|
||||
#define M68K_LOG_FILEHANDLE some_file_handle
|
||||
|
||||
/* Build in the disassembler. If disabled, the API still exists
|
||||
* but does nothing. Turn off to save text/bss space.
|
||||
*/
|
||||
#define M68K_DASM_ENABLE OPT_ON
|
||||
|
||||
/* Use dynamically-created tables for decode and cyclecounts (if
|
||||
* enabled by CYCLE_COUNTING), as opposed to tables created at build
|
||||
* time. Using the dynamic version of the decode jumptable adds 256KB
|
||||
* to RAM usage but makes the binary smaller. Using the static
|
||||
* version adds 256KB to the binary and no RAM, but doesn't currently
|
||||
* support instruction cycle counts.
|
||||
*/
|
||||
#define M68K_DYNAMIC_INSTR_TABLES OPT_ON
|
||||
|
||||
/* Count instruction cycles. This costs a table (created at runtime
|
||||
* in RAM if DYNAMIC_INSTR_TABLES is on).
|
||||
*
|
||||
* NOTE: This is not currently supported when DYNAMIC_INSTR_TABLES is
|
||||
* off.
|
||||
*/
|
||||
#define M68K_CYCLE_COUNTING OPT_ON
|
||||
|
||||
/* ----------------------------- COMPATIBILITY ---------------------------- */
|
||||
|
||||
|
|
|
|||
5
m68k.h
5
m68k.h
|
|
@ -151,6 +151,11 @@ typedef enum
|
|||
M68K_REG_CPU_TYPE /* Type of CPU being run */
|
||||
} m68k_register_t;
|
||||
|
||||
|
||||
#ifndef M68K_FAST_FUNC
|
||||
#define M68K_FAST_FUNC(x) x
|
||||
#endif
|
||||
|
||||
/* ======================================================================== */
|
||||
/* ====================== FUNCTIONS CALLED BY THE CPU ===================== */
|
||||
/* ======================================================================== */
|
||||
|
|
|
|||
52
m68k_in.c
52
m68k_in.c
|
|
@ -109,12 +109,26 @@ XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX
|
|||
M68KMAKE_PROTOTYPE_FOOTER
|
||||
|
||||
|
||||
#if M68K_DYNAMIC_INSTR_TABLES
|
||||
/* Build the opcode handler table */
|
||||
void m68ki_build_opcode_table(void);
|
||||
|
||||
extern void (*m68ki_instruction_jump_table[0x10000])(void); /* opcode handler jump table */
|
||||
#if M68K_CYCLE_COUNTING
|
||||
extern unsigned char m68ki_cycles[][0x10000];
|
||||
#endif
|
||||
#else
|
||||
/* Opcode handler table is already built at compile time */
|
||||
static inline void m68ki_build_opcode_table(void) {}
|
||||
extern void (*const m68ki_static_instruction_jump_table[0x10000])(void);
|
||||
|
||||
#if M68K_CYCLE_COUNTING
|
||||
/* To support cycle counting in a static-tables scenario, extend
|
||||
* m68kmake to generate a static table.
|
||||
*/
|
||||
#error "CYCLE_COUNTING is only supported with DYNAMIC_INSTR_TABLES"
|
||||
#endif
|
||||
#endif
|
||||
|
||||
/* ======================================================================== */
|
||||
/* ============================== END OF FILE ============================= */
|
||||
|
|
@ -136,8 +150,12 @@ M68KMAKE_TABLE_HEADER
|
|||
|
||||
#define NUM_CPU_TYPES 5
|
||||
|
||||
#if M68K_DYNAMIC_INSTR_TABLES
|
||||
void (*m68ki_instruction_jump_table[0x10000])(void); /* opcode handler jump table */
|
||||
|
||||
#if M68K_CYCLE_COUNTING
|
||||
unsigned char m68ki_cycles[NUM_CPU_TYPES][0x10000]; /* Cycles used by CPU type */
|
||||
#endif
|
||||
|
||||
/* This is used to generate the opcode handler jump table */
|
||||
typedef struct
|
||||
|
|
@ -162,12 +180,16 @@ M68KMAKE_TABLE_FOOTER
|
|||
{0, 0, 0, {0, 0, 0, 0, 0}}
|
||||
};
|
||||
|
||||
#if M68K_CYCLE_COUNTING
|
||||
#define SET_CPU_CYCLECOUNT(a, b, val) do { m68ki_cycles[k][i] = (val); } while(0)
|
||||
#else
|
||||
#define SET_CPU_CYCLECOUNT(a, b, val) do { } while(0)
|
||||
#endif
|
||||
|
||||
/* Build the opcode handler jump table */
|
||||
void m68ki_build_opcode_table(void)
|
||||
{
|
||||
const opcode_handler_struct *ostruct;
|
||||
int cycle_cost;
|
||||
int instr;
|
||||
int i;
|
||||
int j;
|
||||
|
|
@ -178,7 +200,7 @@ void m68ki_build_opcode_table(void)
|
|||
/* default to illegal */
|
||||
m68ki_instruction_jump_table[i] = m68k_op_illegal;
|
||||
for(k=0;k<NUM_CPU_TYPES;k++)
|
||||
m68ki_cycles[k][i] = 0;
|
||||
SET_CPU_CYCLECOUNT(k, i, 0);
|
||||
}
|
||||
|
||||
ostruct = m68k_opcode_handler_table;
|
||||
|
|
@ -190,7 +212,7 @@ void m68ki_build_opcode_table(void)
|
|||
{
|
||||
m68ki_instruction_jump_table[i] = ostruct->opcode_handler;
|
||||
for(k=0;k<NUM_CPU_TYPES;k++)
|
||||
m68ki_cycles[k][i] = ostruct->cycles[k];
|
||||
SET_CPU_CYCLECOUNT(k, i, ostruct->cycles[k]);
|
||||
}
|
||||
}
|
||||
ostruct++;
|
||||
|
|
@ -201,7 +223,7 @@ void m68ki_build_opcode_table(void)
|
|||
{
|
||||
m68ki_instruction_jump_table[ostruct->match | i] = ostruct->opcode_handler;
|
||||
for(k=0;k<NUM_CPU_TYPES;k++)
|
||||
m68ki_cycles[k][ostruct->match | i] = ostruct->cycles[k];
|
||||
SET_CPU_CYCLECOUNT(k, ostruct->match | i, ostruct->cycles[k]);
|
||||
}
|
||||
ostruct++;
|
||||
}
|
||||
|
|
@ -214,7 +236,7 @@ void m68ki_build_opcode_table(void)
|
|||
instr = ostruct->match | (i << 9) | j;
|
||||
m68ki_instruction_jump_table[instr] = ostruct->opcode_handler;
|
||||
for(k=0;k<NUM_CPU_TYPES;k++)
|
||||
m68ki_cycles[k][instr] = ostruct->cycles[k];
|
||||
SET_CPU_CYCLECOUNT(k, instr, ostruct->cycles[k]);
|
||||
/* SBF: don't add it here or the costs are added twice!
|
||||
// For all shift operations with known shift distance (encoded in instruction word)
|
||||
if((instr & 0xf000) == 0xe000 && (!(instr & 0x20)))
|
||||
|
|
@ -238,7 +260,7 @@ void m68ki_build_opcode_table(void)
|
|||
{
|
||||
m68ki_instruction_jump_table[ostruct->match | i] = ostruct->opcode_handler;
|
||||
for(k=0;k<NUM_CPU_TYPES;k++)
|
||||
m68ki_cycles[k][ostruct->match | i] = ostruct->cycles[k];
|
||||
SET_CPU_CYCLECOUNT(k, ostruct->match | i, ostruct->cycles[k]);
|
||||
}
|
||||
ostruct++;
|
||||
}
|
||||
|
|
@ -248,7 +270,7 @@ void m68ki_build_opcode_table(void)
|
|||
{
|
||||
m68ki_instruction_jump_table[ostruct->match | (i << 9)] = ostruct->opcode_handler;
|
||||
for(k=0;k<NUM_CPU_TYPES;k++)
|
||||
m68ki_cycles[k][ostruct->match | (i << 9)] = ostruct->cycles[k];
|
||||
SET_CPU_CYCLECOUNT(k, ostruct->match | (i << 9), ostruct->cycles[k]);
|
||||
}
|
||||
ostruct++;
|
||||
}
|
||||
|
|
@ -258,7 +280,7 @@ void m68ki_build_opcode_table(void)
|
|||
{
|
||||
m68ki_instruction_jump_table[ostruct->match | i] = ostruct->opcode_handler;
|
||||
for(k=0;k<NUM_CPU_TYPES;k++)
|
||||
m68ki_cycles[k][ostruct->match | i] = ostruct->cycles[k];
|
||||
SET_CPU_CYCLECOUNT(k, ostruct->match | i, ostruct->cycles[k]);
|
||||
}
|
||||
ostruct++;
|
||||
}
|
||||
|
|
@ -266,11 +288,13 @@ void m68ki_build_opcode_table(void)
|
|||
{
|
||||
m68ki_instruction_jump_table[ostruct->match] = ostruct->opcode_handler;
|
||||
for(k=0;k<NUM_CPU_TYPES;k++)
|
||||
m68ki_cycles[k][ostruct->match] = ostruct->cycles[k];
|
||||
SET_CPU_CYCLECOUNT(k, ostruct->match, ostruct->cycles[k]);
|
||||
ostruct++;
|
||||
}
|
||||
}
|
||||
|
||||
#endif // M68K_DYNAMIC_INSTR_TABLES
|
||||
|
||||
|
||||
/* ======================================================================== */
|
||||
/* ============================== END OF FILE ============================= */
|
||||
|
|
@ -379,6 +403,7 @@ cpu cycles: Base number of cycles required to execute this opcode on the
|
|||
name size proc ea bit pattern A+-DXWLdxI 0 1 2 3 4 000 010 020 030 040 comments
|
||||
====== ==== ==== ==== ================ ========== = = = = = === === === === === =============
|
||||
M68KMAKE_TABLE_START
|
||||
emul_op 0 . . 011100011....... .......... U U U U U 4 4 4 4 4 Extended opcodes (illegal moveq form)
|
||||
1010 0 . . 1010............ .......... U U U U U 4 4 4 4 4
|
||||
1111 0 . . 1111............ .......... U U U U U 4 4 4 4 4
|
||||
040fpu0 32 . . 11110010........ .......... . . . . U . . . . 0
|
||||
|
|
@ -903,6 +928,11 @@ unpk 16 mm . 1000...110001... .......... . . U U U . . 13 1
|
|||
XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX
|
||||
M68KMAKE_OPCODE_HANDLER_BODY
|
||||
|
||||
M68KMAKE_OP(emul_op, 0, ., .)
|
||||
{
|
||||
m68ki_emul_op();
|
||||
}
|
||||
|
||||
M68KMAKE_OP(1010, 0, ., .)
|
||||
{
|
||||
m68ki_exception_1010();
|
||||
|
|
@ -9577,8 +9607,8 @@ M68KMAKE_OP(stop, 0, ., .)
|
|||
m68ki_trace_t0(); /* auto-disable (see m68kcpu.h) */
|
||||
CPU_STOPPED |= STOP_LEVEL_STOP;
|
||||
m68ki_set_sr(new_sr);
|
||||
if(m68ki_remaining_cycles >= CYC_INSTRUCTION[REG_IR])
|
||||
m68ki_remaining_cycles = CYC_INSTRUCTION[REG_IR];
|
||||
if(m68ki_remaining_cycles >= CYC_INSTRUCTION(REG_IR))
|
||||
m68ki_remaining_cycles = CYC_INSTRUCTION(REG_IR);
|
||||
else
|
||||
USE_ALL_CYCLES();
|
||||
return;
|
||||
|
|
|
|||
38
m68kconf.h
38
m68kconf.h
|
|
@ -43,7 +43,6 @@
|
|||
#define OPT_ON 1
|
||||
#define OPT_SPECIFY_HANDLER 2
|
||||
|
||||
|
||||
/* ======================================================================== */
|
||||
/* ============================== MAME STUFF ============================== */
|
||||
/* ======================================================================== */
|
||||
|
|
@ -188,6 +187,41 @@
|
|||
* so enable this only if it's useful */
|
||||
#define M68K_EMULATE_PMMU OPT_ON
|
||||
|
||||
/* Build in the disassembler. If disabled, the API still exists
|
||||
* but does nothing. Turn off to save text/bss space.
|
||||
*/
|
||||
#define M68K_DASM_ENABLE OPT_ON
|
||||
|
||||
/* Use dynamically-created tables for decode and cyclecounts (if
|
||||
* enabled by CYCLE_COUNTING), as opposed to tables created at build
|
||||
* time. Using the dynamic version of the decode jumptable adds 256KB
|
||||
* to RAM usage but makes the binary smaller. Using the static
|
||||
* version adds 256KB to the binary and no RAM, but doesn't currently
|
||||
* support instruction cycle counts.
|
||||
*/
|
||||
#define M68K_DYNAMIC_INSTR_TABLES OPT_ON
|
||||
|
||||
/* Count instruction cycles. This costs a table (created at runtime
|
||||
* in RAM if DYNAMIC_INSTR_TABLES is on).
|
||||
*
|
||||
* NOTE: This is not currently supported when DYNAMIC_INSTR_TABLES is
|
||||
* off.
|
||||
*/
|
||||
#define M68K_CYCLE_COUNTING OPT_ON
|
||||
|
||||
/* Support bus error API: if this isn't ever called by the application,
|
||||
* save some cycles by disabling it.
|
||||
*/
|
||||
|
||||
#define M68K_BUS_ERR_ENABLE OPT_ON
|
||||
|
||||
/* If ON, CPU will support "emul_op" instructions from 0x7100..0x713f by
|
||||
* calling m68k_end_timeslice when they are encountered. The caller can (must)
|
||||
* check the IR register and implement the operation.
|
||||
* If off, these remain illegal instructions.
|
||||
*/
|
||||
#define M68K_EMUL_OP OPT_OFF
|
||||
|
||||
/* ----------------------------- COMPATIBILITY ---------------------------- */
|
||||
|
||||
/* The following options set optimizations that violate the current ANSI
|
||||
|
|
@ -195,7 +229,7 @@
|
|||
*/
|
||||
|
||||
|
||||
/* If ON, the enulation core will use 64-bit integers to speed up some
|
||||
/* If ON, the emulation core will use 64-bit integers to speed up some
|
||||
* operations.
|
||||
*/
|
||||
#define M68K_USE_64_BIT OPT_ON
|
||||
|
|
|
|||
95
m68kcpu.c
95
m68kcpu.c
|
|
@ -38,12 +38,11 @@
|
|||
/* ================================ INCLUDES ============================== */
|
||||
/* ======================================================================== */
|
||||
|
||||
#include <assert.h>
|
||||
|
||||
extern void m68040_fpu_op0(void);
|
||||
extern void m68040_fpu_op1(void);
|
||||
extern void m68881_mmu_ops(void);
|
||||
extern unsigned char m68ki_cycles[][0x10000];
|
||||
extern void (*m68ki_instruction_jump_table[0x10000])(void); /* opcode handler jump table */
|
||||
extern void m68ki_build_opcode_table(void);
|
||||
|
||||
#include "m68kops.h"
|
||||
#include "m68kcpu.h"
|
||||
|
|
@ -51,6 +50,18 @@ extern void m68ki_build_opcode_table(void);
|
|||
#include "m68kfpu.c"
|
||||
#include "m68kmmu.h" // uses some functions from m68kfpu.c which are static !
|
||||
|
||||
|
||||
#if M68K_DYNAMIC_INSTR_TABLES
|
||||
extern void (*m68ki_instruction_jump_table[0x10000])(void); /* opcode handler jump table */
|
||||
void (**instruction_jump_table)(void) = m68ki_instruction_jump_table;
|
||||
#if M68K_CYCLE_COUNTING
|
||||
extern unsigned char m68ki_cycles[][0x10000];
|
||||
#endif
|
||||
#else
|
||||
extern void (*const m68ki_static_instruction_jump_table[0x10000])(void);
|
||||
void (**instruction_jump_table)(void) = (void (**)(void))m68ki_static_instruction_jump_table;
|
||||
#endif
|
||||
|
||||
/* ======================================================================== */
|
||||
/* ================================= DATA ================================= */
|
||||
/* ======================================================================== */
|
||||
|
|
@ -92,7 +103,9 @@ uint m68ki_aerr_address;
|
|||
uint m68ki_aerr_write_mode;
|
||||
uint m68ki_aerr_fc;
|
||||
|
||||
#if M68K_BUS_ERR_ENABLE
|
||||
jmp_buf m68ki_bus_error_jmp_buf;
|
||||
#endif
|
||||
|
||||
/* Used by shift & rotate instructions */
|
||||
const uint8 m68ki_shift_8_table[65] =
|
||||
|
|
@ -661,6 +674,9 @@ unsigned int m68k_get_reg(void* context, m68k_register_t regnum)
|
|||
case M68K_REG_PPC: return MASK_OUT_ABOVE_32(cpu->ppc);
|
||||
case M68K_REG_IR: return cpu->ir;
|
||||
case M68K_REG_CPU_TYPE:
|
||||
#ifdef M68K_FIXED_CPU_TYPE
|
||||
return M68K_FIXED_CPU_TYPE;
|
||||
#else
|
||||
switch(cpu->cpu_type)
|
||||
{
|
||||
case CPU_TYPE_000: return (unsigned int)M68K_CPU_TYPE_68000;
|
||||
|
|
@ -670,6 +686,7 @@ unsigned int m68k_get_reg(void* context, m68k_register_t regnum)
|
|||
case CPU_TYPE_040: return (unsigned int)M68K_CPU_TYPE_68040;
|
||||
}
|
||||
return M68K_CPU_TYPE_INVALID;
|
||||
#endif
|
||||
default: return 0;
|
||||
}
|
||||
return 0;
|
||||
|
|
@ -776,16 +793,32 @@ void m68k_set_instr_hook_callback(void (*callback)(unsigned int pc))
|
|||
CALLBACK_INSTR_HOOK = callback ? callback : default_instr_hook_callback;
|
||||
}
|
||||
|
||||
#if M68K_DYNAMIC_INSTR_TABLES && M68K_CYCLE_COUNTING
|
||||
#define CYC_INSTR_INIT(x) m68ki_cpu.cyc_instruction = (x)
|
||||
#else
|
||||
/* FIXME: how to select a CPU flavour at compile time is TBD. */
|
||||
#define CYC_INSTR_INIT(x) m68ki_cpu.cyc_instruction = NULL
|
||||
#endif
|
||||
|
||||
#ifdef M68K_FIXED_CPU_TYPE
|
||||
#define CPU_TYPE_INIT(x) do {} while(0)
|
||||
#else
|
||||
#define CPU_TYPE_INIT(x) do { CPU_TYPE = (x); } while(0)
|
||||
#endif
|
||||
|
||||
/* Set the CPU type. */
|
||||
void m68k_set_cpu_type(unsigned int cpu_type)
|
||||
{
|
||||
#ifdef M68K_FIXED_CPU_TYPE
|
||||
assert(cpu_type == M68K_FIXED_CPU_TYPE);
|
||||
#endif
|
||||
switch(cpu_type)
|
||||
{
|
||||
case M68K_CPU_TYPE_68000:
|
||||
CPU_TYPE = CPU_TYPE_000;
|
||||
CPU_TYPE_INIT(CPU_TYPE_000);
|
||||
CPU_ADDRESS_MASK = 0x00ffffff;
|
||||
CPU_SR_MASK = 0xa71f; /* T1 -- S -- -- I2 I1 I0 -- -- -- X N Z V C */
|
||||
CYC_INSTRUCTION = m68ki_cycles[0];
|
||||
CYC_INSTR_INIT(m68ki_cycles[0]);
|
||||
CYC_EXCEPTION = m68ki_exception_cycle_table[0];
|
||||
CYC_BCC_NOTAKE_B = -2;
|
||||
CYC_BCC_NOTAKE_W = 2;
|
||||
|
|
@ -801,13 +834,13 @@ void m68k_set_cpu_type(unsigned int cpu_type)
|
|||
case M68K_CPU_TYPE_SCC68070:
|
||||
m68k_set_cpu_type(M68K_CPU_TYPE_68010);
|
||||
CPU_ADDRESS_MASK = 0xffffffff;
|
||||
CPU_TYPE = CPU_TYPE_SCC070;
|
||||
CPU_TYPE_INIT(CPU_TYPE_SCC070);
|
||||
return;
|
||||
case M68K_CPU_TYPE_68010:
|
||||
CPU_TYPE = CPU_TYPE_010;
|
||||
CPU_TYPE_INIT(CPU_TYPE_010);
|
||||
CPU_ADDRESS_MASK = 0x00ffffff;
|
||||
CPU_SR_MASK = 0xa71f; /* T1 -- S -- -- I2 I1 I0 -- -- -- X N Z V C */
|
||||
CYC_INSTRUCTION = m68ki_cycles[1];
|
||||
CYC_INSTR_INIT(m68ki_cycles[1]);
|
||||
CYC_EXCEPTION = m68ki_exception_cycle_table[1];
|
||||
CYC_BCC_NOTAKE_B = -4;
|
||||
CYC_BCC_NOTAKE_W = 0;
|
||||
|
|
@ -821,10 +854,10 @@ void m68k_set_cpu_type(unsigned int cpu_type)
|
|||
HAS_PMMU = 0;
|
||||
return;
|
||||
case M68K_CPU_TYPE_68EC020:
|
||||
CPU_TYPE = CPU_TYPE_EC020;
|
||||
CPU_TYPE_INIT(CPU_TYPE_EC020);
|
||||
CPU_ADDRESS_MASK = 0x00ffffff;
|
||||
CPU_SR_MASK = 0xf71f; /* T1 T0 S M -- I2 I1 I0 -- -- -- X N Z V C */
|
||||
CYC_INSTRUCTION = m68ki_cycles[2];
|
||||
CYC_INSTR_INIT(m68ki_cycles[2]);
|
||||
CYC_EXCEPTION = m68ki_exception_cycle_table[2];
|
||||
CYC_BCC_NOTAKE_B = -2;
|
||||
CYC_BCC_NOTAKE_W = 0;
|
||||
|
|
@ -838,10 +871,10 @@ void m68k_set_cpu_type(unsigned int cpu_type)
|
|||
HAS_PMMU = 0;
|
||||
return;
|
||||
case M68K_CPU_TYPE_68020:
|
||||
CPU_TYPE = CPU_TYPE_020;
|
||||
CPU_TYPE_INIT(CPU_TYPE_020);
|
||||
CPU_ADDRESS_MASK = 0xffffffff;
|
||||
CPU_SR_MASK = 0xf71f; /* T1 T0 S M -- I2 I1 I0 -- -- -- X N Z V C */
|
||||
CYC_INSTRUCTION = m68ki_cycles[2];
|
||||
CYC_INSTR_INIT(m68ki_cycles[2]);
|
||||
CYC_EXCEPTION = m68ki_exception_cycle_table[2];
|
||||
CYC_BCC_NOTAKE_B = -2;
|
||||
CYC_BCC_NOTAKE_W = 0;
|
||||
|
|
@ -855,10 +888,10 @@ void m68k_set_cpu_type(unsigned int cpu_type)
|
|||
HAS_PMMU = 0;
|
||||
return;
|
||||
case M68K_CPU_TYPE_68030:
|
||||
CPU_TYPE = CPU_TYPE_030;
|
||||
CPU_TYPE_INIT(CPU_TYPE_030);
|
||||
CPU_ADDRESS_MASK = 0xffffffff;
|
||||
CPU_SR_MASK = 0xf71f; /* T1 T0 S M -- I2 I1 I0 -- -- -- X N Z V C */
|
||||
CYC_INSTRUCTION = m68ki_cycles[3];
|
||||
CYC_INSTR_INIT(m68ki_cycles[3]);
|
||||
CYC_EXCEPTION = m68ki_exception_cycle_table[3];
|
||||
CYC_BCC_NOTAKE_B = -2;
|
||||
CYC_BCC_NOTAKE_W = 0;
|
||||
|
|
@ -872,10 +905,10 @@ void m68k_set_cpu_type(unsigned int cpu_type)
|
|||
HAS_PMMU = 1;
|
||||
return;
|
||||
case M68K_CPU_TYPE_68EC030:
|
||||
CPU_TYPE = CPU_TYPE_EC030;
|
||||
CPU_TYPE_INIT(CPU_TYPE_EC030);
|
||||
CPU_ADDRESS_MASK = 0xffffffff;
|
||||
CPU_SR_MASK = 0xf71f; /* T1 T0 S M -- I2 I1 I0 -- -- -- X N Z V C */
|
||||
CYC_INSTRUCTION = m68ki_cycles[3];
|
||||
CYC_INSTR_INIT(m68ki_cycles[3]);
|
||||
CYC_EXCEPTION = m68ki_exception_cycle_table[3];
|
||||
CYC_BCC_NOTAKE_B = -2;
|
||||
CYC_BCC_NOTAKE_W = 0;
|
||||
|
|
@ -889,10 +922,10 @@ void m68k_set_cpu_type(unsigned int cpu_type)
|
|||
HAS_PMMU = 0; /* EC030 lacks the PMMU and is effectively a die-shrink 68020 */
|
||||
return;
|
||||
case M68K_CPU_TYPE_68040: // TODO: these values are not correct
|
||||
CPU_TYPE = CPU_TYPE_040;
|
||||
CPU_TYPE_INIT(CPU_TYPE_040);
|
||||
CPU_ADDRESS_MASK = 0xffffffff;
|
||||
CPU_SR_MASK = 0xf71f; /* T1 T0 S M -- I2 I1 I0 -- -- -- X N Z V C */
|
||||
CYC_INSTRUCTION = m68ki_cycles[4];
|
||||
CYC_INSTR_INIT(m68ki_cycles[4]);
|
||||
CYC_EXCEPTION = m68ki_exception_cycle_table[4];
|
||||
CYC_BCC_NOTAKE_B = -2;
|
||||
CYC_BCC_NOTAKE_W = 0;
|
||||
|
|
@ -906,10 +939,10 @@ void m68k_set_cpu_type(unsigned int cpu_type)
|
|||
HAS_PMMU = 1;
|
||||
return;
|
||||
case M68K_CPU_TYPE_68EC040: // Just a 68040 without pmmu apparently...
|
||||
CPU_TYPE = CPU_TYPE_EC040;
|
||||
CPU_TYPE_INIT(CPU_TYPE_EC040);
|
||||
CPU_ADDRESS_MASK = 0xffffffff;
|
||||
CPU_SR_MASK = 0xf71f; /* T1 T0 S M -- I2 I1 I0 -- -- -- X N Z V C */
|
||||
CYC_INSTRUCTION = m68ki_cycles[4];
|
||||
CYC_INSTR_INIT(m68ki_cycles[4]);
|
||||
CYC_EXCEPTION = m68ki_exception_cycle_table[4];
|
||||
CYC_BCC_NOTAKE_B = -2;
|
||||
CYC_BCC_NOTAKE_W = 0;
|
||||
|
|
@ -923,9 +956,9 @@ void m68k_set_cpu_type(unsigned int cpu_type)
|
|||
HAS_PMMU = 0;
|
||||
return;
|
||||
case M68K_CPU_TYPE_68LC040:
|
||||
CPU_TYPE = CPU_TYPE_LC040;
|
||||
CPU_TYPE_INIT(CPU_TYPE_LC040);
|
||||
m68ki_cpu.sr_mask = 0xf71f; /* T1 T0 S M -- I2 I1 I0 -- -- -- X N Z V C */
|
||||
m68ki_cpu.cyc_instruction = m68ki_cycles[4];
|
||||
CYC_INSTR_INIT(m68ki_cycles[4]);
|
||||
m68ki_cpu.cyc_exception = m68ki_exception_cycle_table[4];
|
||||
m68ki_cpu.cyc_bcc_notake_b = -2;
|
||||
m68ki_cpu.cyc_bcc_notake_w = 0;
|
||||
|
|
@ -943,7 +976,7 @@ void m68k_set_cpu_type(unsigned int cpu_type)
|
|||
|
||||
/* Execute some instructions until we use up num_cycles clock cycles */
|
||||
/* ASG: removed per-instruction interrupt checks */
|
||||
int m68k_execute(int num_cycles)
|
||||
int M68K_FAST_FUNC(m68k_execute)(int num_cycles)
|
||||
{
|
||||
/* eat up any reset cycles */
|
||||
if (RESET_CYCLES) {
|
||||
|
|
@ -972,7 +1005,6 @@ int m68k_execute(int num_cycles)
|
|||
/* Main loop. Keep going until we run out of clock cycles */
|
||||
do
|
||||
{
|
||||
int i;
|
||||
/* Set tracing accodring to T1. (T0 is done inside instruction) */
|
||||
m68ki_trace_t1(); /* auto-disable (see m68kcpu.h) */
|
||||
|
||||
|
|
@ -985,15 +1017,16 @@ int m68k_execute(int num_cycles)
|
|||
/* Record previous program counter */
|
||||
REG_PPC = REG_PC;
|
||||
|
||||
#if M68K_BUS_ERR_ENABLE
|
||||
/* Record previous D/A register state (in case of bus error) */
|
||||
for (i = 15; i >= 0; i--){
|
||||
for (int i = 15; i >= 0; i--){
|
||||
REG_DA_SAVE[i] = REG_DA[i];
|
||||
}
|
||||
|
||||
#endif
|
||||
/* Read an instruction and call its handler */
|
||||
REG_IR = m68ki_read_imm_16();
|
||||
m68ki_instruction_jump_table[REG_IR]();
|
||||
USE_CYCLES(CYC_INSTRUCTION[REG_IR]);
|
||||
REG_IR = m68ki_read_opcode_16();
|
||||
instruction_jump_table[REG_IR]();
|
||||
USE_CYCLES(CYC_INSTRUCTION(REG_IR));
|
||||
|
||||
/* Trace m68k_exception, if necessary */
|
||||
m68ki_exception_if_trace(); /* auto-disable (see m68kcpu.h) */
|
||||
|
|
@ -1102,7 +1135,9 @@ void m68k_init(void)
|
|||
/* Trigger a Bus Error exception */
|
||||
void m68k_pulse_bus_error(void)
|
||||
{
|
||||
#if M68K_BUS_ERR_ENABLE
|
||||
m68ki_exception_bus_error();
|
||||
#endif
|
||||
}
|
||||
|
||||
/* Pulse the RESET line on the CPU */
|
||||
|
|
@ -1155,7 +1190,7 @@ void m68k_pulse_halt(void)
|
|||
|
||||
/* Get and set the current CPU context */
|
||||
/* This is to allow for multiple CPUs */
|
||||
unsigned int m68k_context_size()
|
||||
unsigned int m68k_context_size(void)
|
||||
{
|
||||
return sizeof(m68ki_cpu_core);
|
||||
}
|
||||
|
|
|
|||
59
m68kcpu.h
59
m68kcpu.h
|
|
@ -325,7 +325,11 @@ typedef uint32 uint64;
|
|||
/* ------------------------------ CPU Access ------------------------------ */
|
||||
|
||||
/* Access the CPU registers */
|
||||
#ifdef M68K_FIXED_CPU_TYPE
|
||||
#define CPU_TYPE M68K_FIXED_CPU_TYPE
|
||||
#else
|
||||
#define CPU_TYPE m68ki_cpu.cpu_type
|
||||
#endif
|
||||
|
||||
#define REG_DA m68ki_cpu.dar /* easy access to data and address regs */
|
||||
#define REG_DA_SAVE m68ki_cpu.dar_save
|
||||
|
|
@ -370,7 +374,12 @@ typedef uint32 uint64;
|
|||
#define CPU_INSTR_MODE m68ki_cpu.instr_mode
|
||||
#define CPU_RUN_MODE m68ki_cpu.run_mode
|
||||
|
||||
#define CYC_INSTRUCTION m68ki_cpu.cyc_instruction
|
||||
#if M68K_DYNAMIC_INSTR_TABLES && M68K_CYCLE_COUNTING
|
||||
#define CYC_INSTRUCTION(x) m68ki_cpu.cyc_instruction[x]
|
||||
#else
|
||||
#define CYC_INSTRUCTION(x) (8)
|
||||
#endif
|
||||
|
||||
#define CYC_EXCEPTION m68ki_cpu.cyc_exception
|
||||
#define CYC_BCC_NOTAKE_B m68ki_cpu.cyc_bcc_notake_b
|
||||
#define CYC_BCC_NOTAKE_W m68ki_cpu.cyc_bcc_notake_w
|
||||
|
|
@ -874,7 +883,7 @@ extern jmp_buf m68ki_aerr_trap;
|
|||
#define USE_CYCLES(A) m68ki_remaining_cycles -= (A)
|
||||
#define SET_CYCLES(A) m68ki_remaining_cycles = A
|
||||
#define GET_CYCLES() m68ki_remaining_cycles
|
||||
#define USE_ALL_CYCLES() m68ki_remaining_cycles %= CYC_INSTRUCTION[REG_IR]
|
||||
#define USE_ALL_CYCLES() m68ki_remaining_cycles %= CYC_INSTRUCTION(REG_IR)
|
||||
|
||||
|
||||
|
||||
|
|
@ -925,19 +934,24 @@ typedef union
|
|||
|
||||
typedef struct
|
||||
{
|
||||
/* Most-used items at the front */
|
||||
uint ir; /* Instruction Register */
|
||||
uint ppc; /* Previous program counter */
|
||||
uint pc; /* Program Counter */
|
||||
#ifndef M68K_FIXED_CPU_TYPE
|
||||
uint cpu_type; /* CPU Type: 68000, 68008, 68010, 68EC020, 68020, 68EC030, 68030, 68EC040, or 68040 */
|
||||
#endif
|
||||
uint dar[16]; /* Data and Address Registers */
|
||||
#ifdef M68K_BUS_ERR_ENABLE
|
||||
uint dar_save[16]; /* Saved Data and Address Registers (pushed onto the
|
||||
stack when a bus error occurs)*/
|
||||
uint ppc; /* Previous program counter */
|
||||
uint pc; /* Program Counter */
|
||||
#endif
|
||||
uint sp[7]; /* User, Interrupt, and Master Stack Pointers */
|
||||
uint vbr; /* Vector Base Register (m68010+) */
|
||||
uint sfc; /* Source Function Code Register (m68010+) */
|
||||
uint dfc; /* Destination Function Code Register (m68010+) */
|
||||
uint cacr; /* Cache Control Register (m68020, unemulated) */
|
||||
uint caar; /* Cache Address Register (m68020, unemulated) */
|
||||
uint ir; /* Instruction Register */
|
||||
floatx80 fpr[8]; /* FPU Data Register (m68030/040) */
|
||||
uint fpiar; /* FPU Instruction Address Register (m68040) */
|
||||
uint fpsr; /* FPU Status Register (m68040) */
|
||||
|
|
@ -1072,6 +1086,14 @@ static inline uint m68ki_read_imm_16(void)
|
|||
#endif /* M68K_EMULATE_PREFETCH */
|
||||
}
|
||||
|
||||
/* Read an opcode. Properties: always aligned! */
|
||||
static inline uint m68ki_read_opcode_16(void)
|
||||
{
|
||||
/* FIXME: fc, check addr err, check PMMU, etc. */
|
||||
REG_PC += 2;
|
||||
return m68k_read_instr_16(ADDRESS_68K(REG_PC-2));
|
||||
}
|
||||
|
||||
static inline uint m68ki_read_imm_8(void)
|
||||
{
|
||||
/* map read immediate 8 to read immediate 16 */
|
||||
|
|
@ -1847,7 +1869,7 @@ static inline void m68ki_exception_trap(uint vector)
|
|||
m68ki_jump_vector(vector);
|
||||
|
||||
/* Use up some clock cycles and undo the instruction's cycles */
|
||||
USE_CYCLES(CYC_EXCEPTION[vector] - CYC_INSTRUCTION[REG_IR]);
|
||||
USE_CYCLES(CYC_EXCEPTION[vector] - CYC_INSTRUCTION(REG_IR));
|
||||
}
|
||||
|
||||
/* Trap#n stacks a 0 frame but behaves like group2 otherwise */
|
||||
|
|
@ -1858,7 +1880,7 @@ static inline void m68ki_exception_trapN(uint vector)
|
|||
m68ki_jump_vector(vector);
|
||||
|
||||
/* Use up some clock cycles and undo the instruction's cycles */
|
||||
USE_CYCLES(CYC_EXCEPTION[vector] - CYC_INSTRUCTION[REG_IR]);
|
||||
USE_CYCLES(CYC_EXCEPTION[vector] - CYC_INSTRUCTION(REG_IR));
|
||||
}
|
||||
|
||||
/* Exception for trace mode */
|
||||
|
|
@ -1904,9 +1926,10 @@ static inline void m68ki_exception_privilege_violation(void)
|
|||
m68ki_jump_vector(EXCEPTION_PRIVILEGE_VIOLATION);
|
||||
|
||||
/* Use up some clock cycles and undo the instruction's cycles */
|
||||
USE_CYCLES(CYC_EXCEPTION[EXCEPTION_PRIVILEGE_VIOLATION] - CYC_INSTRUCTION[REG_IR]);
|
||||
USE_CYCLES(CYC_EXCEPTION[EXCEPTION_PRIVILEGE_VIOLATION] - CYC_INSTRUCTION(REG_IR));
|
||||
}
|
||||
|
||||
#if M68K_BUS_ERR_ENABLE
|
||||
extern jmp_buf m68ki_bus_error_jmp_buf;
|
||||
|
||||
#define m68ki_check_bus_error_trap() setjmp(m68ki_bus_error_jmp_buf)
|
||||
|
|
@ -1929,7 +1952,7 @@ static inline void m68ki_exception_bus_error(void)
|
|||
CPU_RUN_MODE = RUN_MODE_BERR_AERR_RESET_WSF;
|
||||
|
||||
/* Use up some clock cycles and undo the instruction's cycles */
|
||||
USE_CYCLES(CYC_EXCEPTION[EXCEPTION_BUS_ERROR] - CYC_INSTRUCTION[REG_IR]);
|
||||
USE_CYCLES(CYC_EXCEPTION[EXCEPTION_BUS_ERROR] - CYC_INSTRUCTION(REG_IR));
|
||||
|
||||
for (i = 15; i >= 0; i--){
|
||||
REG_DA[i] = REG_DA_SAVE[i];
|
||||
|
|
@ -1946,6 +1969,9 @@ static inline void m68ki_exception_bus_error(void)
|
|||
|
||||
longjmp(m68ki_bus_error_jmp_buf, 1);
|
||||
}
|
||||
#else /* M68K_BUS_ERR_ENABLE */
|
||||
#define m68ki_check_bus_error_trap() do {} while(0)
|
||||
#endif
|
||||
|
||||
extern int cpu_log_enabled;
|
||||
|
||||
|
|
@ -1964,7 +1990,7 @@ static inline void m68ki_exception_1010(void)
|
|||
m68ki_jump_vector(EXCEPTION_1010);
|
||||
|
||||
/* Use up some clock cycles and undo the instruction's cycles */
|
||||
USE_CYCLES(CYC_EXCEPTION[EXCEPTION_1010] - CYC_INSTRUCTION[REG_IR]);
|
||||
USE_CYCLES(CYC_EXCEPTION[EXCEPTION_1010] - CYC_INSTRUCTION(REG_IR));
|
||||
}
|
||||
|
||||
/* Exception for F-Line instructions */
|
||||
|
|
@ -1983,7 +2009,7 @@ static inline void m68ki_exception_1111(void)
|
|||
m68ki_jump_vector(EXCEPTION_1111);
|
||||
|
||||
/* Use up some clock cycles and undo the instruction's cycles */
|
||||
USE_CYCLES(CYC_EXCEPTION[EXCEPTION_1111] - CYC_INSTRUCTION[REG_IR]);
|
||||
USE_CYCLES(CYC_EXCEPTION[EXCEPTION_1111] - CYC_INSTRUCTION(REG_IR));
|
||||
}
|
||||
|
||||
#if M68K_ILLG_HAS_CALLBACK == OPT_SPECIFY_HANDLER
|
||||
|
|
@ -2014,7 +2040,7 @@ static inline void m68ki_exception_illegal(void)
|
|||
m68ki_jump_vector(EXCEPTION_ILLEGAL_INSTRUCTION);
|
||||
|
||||
/* Use up some clock cycles and undo the instruction's cycles */
|
||||
USE_CYCLES(CYC_EXCEPTION[EXCEPTION_ILLEGAL_INSTRUCTION] - CYC_INSTRUCTION[REG_IR]);
|
||||
USE_CYCLES(CYC_EXCEPTION[EXCEPTION_ILLEGAL_INSTRUCTION] - CYC_INSTRUCTION(REG_IR));
|
||||
}
|
||||
|
||||
/* Exception for format errror in RTE */
|
||||
|
|
@ -2025,7 +2051,7 @@ static inline void m68ki_exception_format_error(void)
|
|||
m68ki_jump_vector(EXCEPTION_FORMAT_ERROR);
|
||||
|
||||
/* Use up some clock cycles and undo the instruction's cycles */
|
||||
USE_CYCLES(CYC_EXCEPTION[EXCEPTION_FORMAT_ERROR] - CYC_INSTRUCTION[REG_IR]);
|
||||
USE_CYCLES(CYC_EXCEPTION[EXCEPTION_FORMAT_ERROR] - CYC_INSTRUCTION(REG_IR));
|
||||
}
|
||||
|
||||
/* Exception for address error */
|
||||
|
|
@ -2132,6 +2158,13 @@ static inline void m68ki_exception_interrupt(uint int_level)
|
|||
#endif /* M68K_EMULATE_INT_ACK */
|
||||
}
|
||||
|
||||
static inline void m68ki_emul_op(void) {
|
||||
#if M68K_EMUL_OP
|
||||
m68k_end_timeslice();
|
||||
#else
|
||||
m68ki_exception_illegal();
|
||||
#endif
|
||||
}
|
||||
|
||||
/* ASG: Check for interrupts */
|
||||
static inline void m68ki_check_interrupts(void)
|
||||
|
|
|
|||
30
m68kdasm.c
30
m68kdasm.c
|
|
@ -146,6 +146,7 @@
|
|||
#define COMBINE_OPCODE_FLAGS(X) (X)
|
||||
#endif
|
||||
|
||||
#if M68K_DASM_ENABLE
|
||||
|
||||
/* ======================================================================== */
|
||||
/* =============================== PROTOTYPES ============================= */
|
||||
|
|
@ -3715,6 +3716,7 @@ static void build_opcode_table(void)
|
|||
}
|
||||
}
|
||||
}
|
||||
#endif // M68K_DASM_ENABLE
|
||||
|
||||
|
||||
|
||||
|
|
@ -3725,6 +3727,7 @@ static void build_opcode_table(void)
|
|||
/* Disasemble one instruction at pc and store in str_buff */
|
||||
unsigned int m68k_disassemble(char* str_buff, unsigned int pc, unsigned int cpu_type)
|
||||
{
|
||||
#if M68K_DASM_ENABLE
|
||||
if(!g_initialized)
|
||||
{
|
||||
build_opcode_table();
|
||||
|
|
@ -3770,18 +3773,31 @@ unsigned int m68k_disassemble(char* str_buff, unsigned int pc, unsigned int cpu_
|
|||
g_instruction_table[g_cpu_ir]();
|
||||
sprintf(str_buff, "%s%s", g_dasm_str, g_helper_str);
|
||||
return COMBINE_OPCODE_FLAGS(g_cpu_pc - pc);
|
||||
#else
|
||||
(void)str_buff;
|
||||
(void)pc;
|
||||
(void)cpu_type;
|
||||
return 0;
|
||||
#endif
|
||||
}
|
||||
|
||||
char* m68ki_disassemble_quick(unsigned int pc, unsigned int cpu_type)
|
||||
{
|
||||
#if M68K_DASM_ENABLE
|
||||
static char buff[100];
|
||||
buff[0] = 0;
|
||||
m68k_disassemble(buff, pc, cpu_type);
|
||||
return buff;
|
||||
#else
|
||||
(void)pc;
|
||||
(void)cpu_type;
|
||||
return 0;
|
||||
#endif
|
||||
}
|
||||
|
||||
unsigned int m68k_disassemble_raw(char* str_buff, unsigned int pc, const unsigned char* opdata, const unsigned char* argdata, unsigned int cpu_type)
|
||||
{
|
||||
#if M68K_DASM_ENABLE
|
||||
unsigned int result;
|
||||
(void)argdata;
|
||||
|
||||
|
|
@ -3790,11 +3806,20 @@ unsigned int m68k_disassemble_raw(char* str_buff, unsigned int pc, const unsigne
|
|||
result = m68k_disassemble(str_buff, pc, cpu_type);
|
||||
g_rawop = NULL;
|
||||
return result;
|
||||
#else
|
||||
(void)str_buff;
|
||||
(void)pc;
|
||||
(void)opdata;
|
||||
(void)argdata;
|
||||
(void)cpu_type;
|
||||
return 0;
|
||||
#endif
|
||||
}
|
||||
|
||||
/* Check if the instruction is a valid one */
|
||||
unsigned int m68k_is_valid_instruction(unsigned int instruction, unsigned int cpu_type)
|
||||
{
|
||||
#if M68K_DASM_ENABLE
|
||||
if(!g_initialized)
|
||||
{
|
||||
build_opcode_table();
|
||||
|
|
@ -3996,6 +4021,11 @@ unsigned int m68k_is_valid_instruction(unsigned int instruction, unsigned int cp
|
|||
return 0;
|
||||
|
||||
return 1;
|
||||
#else
|
||||
(void)instruction;
|
||||
(void)cpu_type;
|
||||
return 0;
|
||||
#endif
|
||||
}
|
||||
|
||||
// f028 2215 0008
|
||||
|
|
|
|||
12
m68kfpu.c
12
m68kfpu.c
|
|
@ -646,7 +646,7 @@ static uint64 READ_EA_64(int ea)
|
|||
|
||||
static floatx80 READ_EA_FPE(int mode, int reg, uint32 di_mode_ea)
|
||||
{
|
||||
floatx80 fpr;
|
||||
floatx80 fpr = {0};
|
||||
|
||||
switch (mode)
|
||||
{
|
||||
|
|
@ -727,7 +727,7 @@ static floatx80 READ_EA_FPE(int mode, int reg, uint32 di_mode_ea)
|
|||
|
||||
static floatx80 READ_EA_PACK(int ea)
|
||||
{
|
||||
floatx80 fpr;
|
||||
floatx80 fpr = {0};
|
||||
int mode = (ea >> 3) & 0x7;
|
||||
int reg = (ea & 0x7);
|
||||
|
||||
|
|
@ -1749,7 +1749,7 @@ static void fmovem(uint16 w2)
|
|||
}
|
||||
}
|
||||
|
||||
static void fscc()
|
||||
static void fscc(void)
|
||||
{
|
||||
// added by JFF, this seems to work properly now
|
||||
int condition = OPER_I_16() & 0x3f;
|
||||
|
|
@ -1819,7 +1819,7 @@ static void fbcc32(void)
|
|||
}
|
||||
|
||||
|
||||
void m68040_fpu_op0()
|
||||
void m68040_fpu_op0(void)
|
||||
{
|
||||
m68ki_cpu.fpu_just_reset = 0;
|
||||
|
||||
|
|
@ -1908,7 +1908,7 @@ static void perform_fsave(uint32 addr, int inc)
|
|||
}
|
||||
|
||||
// FRESTORE on a NULL frame reboots the FPU - all registers to NaN, the 3 status regs to 0
|
||||
static void do_frestore_null()
|
||||
static void do_frestore_null(void)
|
||||
{
|
||||
int i;
|
||||
|
||||
|
|
@ -1926,7 +1926,7 @@ static void do_frestore_null()
|
|||
m68ki_cpu.fpu_just_reset = 1;
|
||||
}
|
||||
|
||||
void m68040_fpu_op1()
|
||||
void m68040_fpu_op1(void)
|
||||
{
|
||||
int ea = REG_IR & 0x3f;
|
||||
int mode = (ea >> 3) & 0x7;
|
||||
|
|
|
|||
89
m68kmake.c
89
m68kmake.c
|
|
@ -1207,6 +1207,93 @@ void read_insert(char* insert)
|
|||
*ptr++ = 0;
|
||||
}
|
||||
|
||||
void build_opcode_jump_table(FILE *outfile, const opcode_struct *opcode_table, int opcode_table_len)
|
||||
{
|
||||
/* Do what m68ki_build_opcode_table does, but generate a static version
|
||||
* at build time. This allows a project to trade off RAM usage vs binary
|
||||
* size (or even ROM size)
|
||||
*/
|
||||
int instr;
|
||||
int i;
|
||||
int j;
|
||||
int k;
|
||||
|
||||
/* One entry per opcode/instruction. After allocating valid entries,
|
||||
* anything remaining zero is implicitly the illegal instr handler.
|
||||
*/
|
||||
const char **handler_names = calloc(0x10000, sizeof(char *));
|
||||
/* FIXME: Support cycle table -- for one CPU type? */
|
||||
|
||||
for (int opc = 0; opc < opcode_table_len; opc++) {
|
||||
const opcode_struct *ostruct = &opcode_table[opc];
|
||||
|
||||
switch (ostruct->op_mask) {
|
||||
default:
|
||||
printf("Unsupported op_mask %04x for %s\n", ostruct->op_mask, ostruct->name);
|
||||
[[fallthrough]]
|
||||
case 0xf000:
|
||||
case 0xf100:
|
||||
case 0xf180:
|
||||
case 0xf1c0:
|
||||
case 0xfe00:
|
||||
for(i = 0;i < 0x10000;i++)
|
||||
{
|
||||
if((i & ostruct->op_mask) == ostruct->op_match)
|
||||
{
|
||||
handler_names[i] = ostruct->name;
|
||||
}
|
||||
}
|
||||
break;
|
||||
|
||||
case 0xff00:
|
||||
for(i = 0;i <= 0xff;i++)
|
||||
{
|
||||
handler_names[ostruct->op_match | i] = ostruct->name;
|
||||
}
|
||||
break;
|
||||
case 0xf1f8:
|
||||
for(i = 0;i < 8;i++)
|
||||
{
|
||||
for(j = 0;j < 8;j++)
|
||||
{
|
||||
instr = ostruct->op_match | (i << 9) | j;
|
||||
handler_names[instr] = ostruct->name;
|
||||
}
|
||||
}
|
||||
break;
|
||||
case 0xfff0:
|
||||
for(i = 0;i <= 0x0f;i++)
|
||||
{
|
||||
handler_names[ostruct->op_match | i] = ostruct->name;
|
||||
}
|
||||
break;
|
||||
case 0xf1ff:
|
||||
for(i = 0;i <= 0x07;i++)
|
||||
{
|
||||
handler_names[ostruct->op_match | (i << 9)] = ostruct->name;
|
||||
}
|
||||
break;
|
||||
case 0xfff8:
|
||||
for(i = 0;i <= 0x07;i++)
|
||||
{
|
||||
handler_names[ostruct->op_match | i] = ostruct->name;
|
||||
}
|
||||
break;
|
||||
case 0xffff:
|
||||
handler_names[ostruct->op_match] = ostruct->name;
|
||||
}
|
||||
}
|
||||
|
||||
/* Output handler names to create the final table: */
|
||||
fprintf(outfile, "#if !M68K_DYNAMIC_INSTR_TABLES\n");
|
||||
fprintf(outfile, "void (*const m68ki_static_instruction_jump_table[0x10000])(void) = {\n");
|
||||
for (i = 0; i < 0x10000; i++) {
|
||||
fprintf(outfile, "\t%s,\n", handler_names[i] ?
|
||||
handler_names[i] : " m68k_op_illegal");
|
||||
}
|
||||
fprintf(outfile, "};\n#endif\n");
|
||||
free(handler_names);
|
||||
}
|
||||
|
||||
|
||||
/* ======================================================================== */
|
||||
|
|
@ -1380,6 +1467,8 @@ int main(int argc, char **argv)
|
|||
fprintf(g_table_file, "%s\n\n", table_header_insert);
|
||||
print_opcode_output_table(g_table_file);
|
||||
fprintf(g_table_file, "%s\n\n", table_footer_insert);
|
||||
build_opcode_jump_table(g_table_file,
|
||||
g_opcode_output_table, g_opcode_output_table_length);
|
||||
|
||||
fprintf(g_prototype_file, "%s\n\n", prototype_footer_insert);
|
||||
|
||||
|
|
|
|||
Loading…
Reference in a new issue