Skip to content
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -25,3 +25,4 @@ m68kmake
m68kops.?
sim
tags
test_driver
33 changes: 31 additions & 2 deletions Makefile
Original file line number Diff line number Diff line change
Expand Up @@ -13,17 +13,19 @@ EXEPATH = ./
.OFILES = $(.CFILES:%.c=%.o)

CC = gcc
WARNINGS = -Wall -Wextra -pedantic
WARNINGS = -Wall -Wextra -pedantic -g
CFLAGS = $(WARNINGS)
LFLAGS = $(WARNINGS)

DELETEFILES = $(MUSASHIGENCFILES) $(MUSASHIGENHFILES) $(.OFILES) $(TARGET) $(MUSASHIGENERATOR)$(EXE)
DELETEFILES = $(MUSASHIGENCFILES) $(MUSASHIGENHFILES) $(.OFILES) $(TARGET) $(MUSASHIGENERATOR)$(EXE) test_driver$(EXE)


all: $(.OFILES)

clean:
rm -f $(DELETEFILES)
@$(MAKE) -C test clean


m68kcpu.o: $(MUSASHIGENHFILES) m68kfpu.c m68kmmu.h softfloat/softfloat.c softfloat/softfloat.h

Expand All @@ -32,3 +34,30 @@ $(MUSASHIGENCFILES) $(MUSASHIGENHFILES): $(MUSASHIGENERATOR)$(EXE)

$(MUSASHIGENERATOR)$(EXE): $(MUSASHIGENERATOR).c
$(CC) -o $(MUSASHIGENERATOR)$(EXE) $(MUSASHIGENERATOR).c

test_driver$(EXE): test/test_driver.c $(.OFILES)
$(CC) $(CFLAGS) -o test_driver$(EXE) test/test_driver.c $(.OFILES) -I. -lm


TESTS_68000 = abcd adda add_i addq add addx andi_to_ccr andi_to_sr and \
bcc bchg bclr bool_i bset bsr btst \
chk cmpa cmpm cmp dbcc divs divu eori_to_ccr eori_to_sr eor exg ext \
lea_pea lea_tas lea_tst links \
movem movep moveq move move_usp move_xxx_flags muls mulu \
nbcd negs op_cmp_i ori_to_ccr ori_to_sr or \
rox roxx rtr sbcd scc shifts2 shifts suba sub_i subq sub subx swap trapv

TESTS_68040 = bfchg bfclr bfext bfffo bfins bfset bftst cas chk2 cmp2 \
divs_long divu_long interrupt jmp mul_long rtd shifts3 trapcc

TESTS_68000_RUN = $(TESTS_68000:%=%.bin)
$(TESTS_68000_RUN): test_driver$(EXE)
./test_driver$(EXE) test/mc68000/$@

TESTS_68040_RUN = $(TESTS_68040:%=%.bin)
$(TESTS_68040_RUN): test_driver$(EXE)
./test_driver$(EXE) test/mc68040/$@

build_tests:
@$(MAKE) -C test all
test: $(TESTS_68000_RUN) $(TESTS_68040_RUN)
4 changes: 4 additions & 0 deletions m68k.h
Original file line number Diff line number Diff line change
Expand Up @@ -293,7 +293,11 @@ void m68k_set_fc_callback(void (*callback)(unsigned int new_fc));
*/
void m68k_set_instr_hook_callback(void (*callback)(unsigned int pc));

void m68k_set_cmpild_instr_callback(void (*callback)(unsigned int, int));

void m68k_set_cmpild_instr_callback(void (*callback)(unsigned int, int));

void m68k_set_rte_instr_callback(void (*callback)(void));

/* ======================================================================== */
/* ====================== FUNCTIONS TO ACCESS THE CPU ===================== */
Expand Down
135 changes: 32 additions & 103 deletions m68k_in.c
Original file line number Diff line number Diff line change
Expand Up @@ -167,7 +167,6 @@ M68KMAKE_TABLE_FOOTER
void m68ki_build_opcode_table(void)
{
const opcode_handler_struct *ostruct;
int cycle_cost;
int instr;
int i;
int j;
Expand Down Expand Up @@ -221,6 +220,7 @@ void m68ki_build_opcode_table(void)
{
// On the 68000 and 68010 shift distance affect execution time.
// Add the cycle cost of shifting; 2 times the shift distance
int cycle_cost;
cycle_cost = ((((i-1)&7)+1)<<1);
m68ki_cycles[0][instr] += cycle_cost;
m68ki_cycles[1][instr] += cycle_cost;
Expand Down Expand Up @@ -2476,10 +2476,7 @@ M68KMAKE_OP(bfchg, 32, ., .)
sint offset = (word2>>6)&31;
uint width = word2;
uint mask_base;
uint data_long;
uint mask_long;
uint data_byte = 0;
uint mask_byte = 0;
m68ki_bitfield_t data;
uint ea = M68KMAKE_GET_EA_AY_8;


Expand All @@ -2488,34 +2485,20 @@ M68KMAKE_OP(bfchg, 32, ., .)
if(BIT_5(word2))
width = REG_D[width&7];

/* Offset is signed so we have to use ugly math =( */
ea += offset / 8;
offset %= 8;
if(offset < 0)
{
offset += 8;
ea--;
}
width = ((width-1) & 31) + 1;

mask_base = MASK_OUT_ABOVE_32(0xffffffff << (32 - width));
mask_long = mask_base >> offset;
ea = m68ki_bitfield_patch_ea(ea, offset);
offset = m68ki_bitfield_patch_offset(offset);
data = m68ki_load_bitfield(ea, offset, width);

data_long = m68ki_read_32(ea);
FLAG_N = NFLAG_32(data_long << offset);
FLAG_Z = data_long & mask_long;
FLAG_N = NFLAG_32(data.field & mask_base);
FLAG_Z = data.field & mask_base;
FLAG_V = VFLAG_CLEAR;
FLAG_C = CFLAG_CLEAR;

m68ki_write_32(ea, data_long ^ mask_long);

if((width + offset) > 32)
{
mask_byte = MASK_OUT_ABOVE_8(mask_base);
data_byte = m68ki_read_8(ea+4);
FLAG_Z |= (data_byte & mask_byte);
m68ki_write_8(ea+4, data_byte ^ mask_byte);
}
data.field ^= mask_base;
m68ki_store_bitfield(ea, offset, width, data.field, &data);
return;
}
m68ki_exception_illegal();
Expand Down Expand Up @@ -2567,10 +2550,7 @@ M68KMAKE_OP(bfclr, 32, ., .)
sint offset = (word2>>6)&31;
uint width = word2;
uint mask_base;
uint data_long;
uint mask_long;
uint data_byte = 0;
uint mask_byte = 0;
m68ki_bitfield_t data;
uint ea = M68KMAKE_GET_EA_AY_8;


Expand All @@ -2579,34 +2559,20 @@ M68KMAKE_OP(bfclr, 32, ., .)
if(BIT_5(word2))
width = REG_D[width&7];

/* Offset is signed so we have to use ugly math =( */
ea += offset / 8;
offset %= 8;
if(offset < 0)
{
offset += 8;
ea--;
}
width = ((width-1) & 31) + 1;

mask_base = MASK_OUT_ABOVE_32(0xffffffff << (32 - width));
mask_long = mask_base >> offset;
ea = m68ki_bitfield_patch_ea(ea, offset);
offset = m68ki_bitfield_patch_offset(offset);
data = m68ki_load_bitfield(ea, offset, width);

data_long = m68ki_read_32(ea);
FLAG_N = NFLAG_32(data_long << offset);
FLAG_Z = data_long & mask_long;
FLAG_N = NFLAG_32(data.field & mask_base);
FLAG_Z = data.field & mask_base;
FLAG_V = VFLAG_CLEAR;
FLAG_C = CFLAG_CLEAR;

m68ki_write_32(ea, data_long & ~mask_long);

if((width + offset) > 32)
{
mask_byte = MASK_OUT_ABOVE_8(mask_base);
data_byte = m68ki_read_8(ea+4);
FLAG_Z |= (data_byte & mask_byte);
m68ki_write_8(ea+4, data_byte & ~mask_byte);
}
data.field &= ~mask_base;
m68ki_store_bitfield(ea, offset, width, data.field, &data);
return;
}
m68ki_exception_illegal();
Expand Down Expand Up @@ -2916,13 +2882,8 @@ M68KMAKE_OP(bfins, 32, ., .)
sint offset = (word2>>6)&31;
uint width = word2;
uint insert_base = REG_D[(word2>>12)&7];
uint insert_long;
uint insert_byte;
m68ki_bitfield_t data;
uint mask_base;
uint data_long;
uint mask_long;
uint data_byte = 0;
uint mask_byte = 0;
uint ea = M68KMAKE_GET_EA_AY_8;


Expand All @@ -2932,37 +2893,22 @@ M68KMAKE_OP(bfins, 32, ., .)
width = REG_D[width&7];

/* Offset is signed so we have to use ugly math =( */
ea += offset / 8;
offset %= 8;
if(offset < 0)
{
offset += 8;
ea--;
}
width = ((width-1) & 31) + 1;

mask_base = MASK_OUT_ABOVE_32(0xffffffff << (32 - width));
mask_long = mask_base >> offset;
ea = m68ki_bitfield_patch_ea(ea, offset);
offset = m68ki_bitfield_patch_offset(offset);
data = m68ki_load_bitfield(ea, offset, width);

insert_base = MASK_OUT_ABOVE_32(insert_base << (32 - width));

FLAG_N = NFLAG_32(insert_base);
FLAG_Z = insert_base;
insert_long = insert_base >> offset;

data_long = m68ki_read_32(ea);
FLAG_V = VFLAG_CLEAR;
FLAG_C = CFLAG_CLEAR;

m68ki_write_32(ea, (data_long & ~mask_long) | insert_long);

if((width + offset) > 32)
{
mask_byte = MASK_OUT_ABOVE_8(mask_base);
insert_byte = MASK_OUT_ABOVE_8(insert_base);
data_byte = m68ki_read_8(ea+4);
FLAG_Z |= (data_byte & mask_byte);
m68ki_write_8(ea+4, (data_byte & ~mask_byte) | insert_byte);
}
data.field = (data.field & ~mask_base) | insert_base;
m68ki_store_bitfield(ea, offset, width, data.field, &data);
return;
}
m68ki_exception_illegal();
Expand Down Expand Up @@ -3014,10 +2960,7 @@ M68KMAKE_OP(bfset, 32, ., .)
sint offset = (word2>>6)&31;
uint width = word2;
uint mask_base;
uint data_long;
uint mask_long;
uint data_byte = 0;
uint mask_byte = 0;
m68ki_bitfield_t data;
uint ea = M68KMAKE_GET_EA_AY_8;


Expand All @@ -3027,34 +2970,20 @@ M68KMAKE_OP(bfset, 32, ., .)
width = REG_D[width&7];

/* Offset is signed so we have to use ugly math =( */
ea += offset / 8;
offset %= 8;
if(offset < 0)
{
offset += 8;
ea--;
}
width = ((width-1) & 31) + 1;


mask_base = MASK_OUT_ABOVE_32(0xffffffff << (32 - width));
mask_long = mask_base >> offset;
ea = m68ki_bitfield_patch_ea(ea, offset);
offset = m68ki_bitfield_patch_offset(offset);
data = m68ki_load_bitfield(ea, offset, width);

data_long = m68ki_read_32(ea);
FLAG_N = NFLAG_32(data_long << offset);
FLAG_Z = data_long & mask_long;
FLAG_N = NFLAG_32(data.field);
FLAG_Z = data.field & mask_base;
FLAG_V = VFLAG_CLEAR;
FLAG_C = CFLAG_CLEAR;

m68ki_write_32(ea, data_long | mask_long);

if((width + offset) > 32)
{
mask_byte = MASK_OUT_ABOVE_8(mask_base);
data_byte = m68ki_read_8(ea+4);
FLAG_Z |= (data_byte & mask_byte);
m68ki_write_8(ea+4, data_byte | mask_byte);
}
data.field |= mask_base;
m68ki_store_bitfield(ea, offset, width, data.field, &data);
return;
}
m68ki_exception_illegal();
Expand Down
2 changes: 1 addition & 1 deletion m68kcpu.c
Original file line number Diff line number Diff line change
Expand Up @@ -60,7 +60,7 @@ int m68ki_remaining_cycles = 0; /* Number of clocks remaini
uint m68ki_tracing = 0;
uint m68ki_address_space;

#ifdef M68K_LOG_ENABLE
#if M68K_LOG_ENABLE
const char *const m68ki_cpu_names[] =
{
"Invalid CPU",
Expand Down
Loading