mirror of
https://github.com/RaySollium99/picodrive.git
synced 2025-09-05 07:17:45 -04:00
some new cpu debug code
This commit is contained in:
parent
f81107f590
commit
12da51c27a
12 changed files with 224 additions and 54 deletions
3
Makefile
3
Makefile
|
@ -6,7 +6,8 @@ CFLAGS += -O2 -DNDEBUG
|
|||
endif
|
||||
#CFLAGS += -DEVT_LOG
|
||||
#CFLAGS += -DDRC_CMP
|
||||
#drc_debug = 4
|
||||
#cpu_cmp = 1
|
||||
#drc_debug = 3
|
||||
#profile = 1
|
||||
|
||||
|
||||
|
|
|
@ -1 +1 @@
|
|||
Subproject commit 194104e334f7c26015b99c862486a73be0d80162
|
||||
Subproject commit 1f9661c5a2919ba91c0f4b89985e0712871e5762
|
|
@ -19,7 +19,7 @@
|
|||
#define MEMHANDLERS_NEED_CYCLES 1
|
||||
#define MEMHANDLERS_CHANGE_PC 0
|
||||
#define MEMHANDLERS_CHANGE_FLAGS 0
|
||||
#define MEMHANDLERS_CHANGE_CYCLES 0
|
||||
#define MEMHANDLERS_CHANGE_CYCLES 1
|
||||
|
||||
#define MEMHANDLERS_DIRECT_PREFIX "cyclone_"
|
||||
|
||||
|
|
|
@ -136,15 +136,6 @@ void sh2_unpack(SH2 *sh2, const unsigned char *buff)
|
|||
|
||||
static SH2 sh2ref[2];
|
||||
static unsigned int mem_val;
|
||||
static FILE *f;
|
||||
|
||||
enum ctl_byte {
|
||||
CTL_MASTERSLAVE = 0x80,
|
||||
CTL_EA = 0x82,
|
||||
CTL_EAVAL = 0x83,
|
||||
CTL_M68KPC = 0x84,
|
||||
CTL_CYCLES = 0x85,
|
||||
};
|
||||
|
||||
static unsigned int local_read32(SH2 *sh2, u32 a)
|
||||
{
|
||||
|
@ -176,12 +167,6 @@ static unsigned int local_read32(SH2 *sh2, u32 a)
|
|||
return 0;
|
||||
}
|
||||
|
||||
static void write_uint(unsigned char ctl, unsigned int v)
|
||||
{
|
||||
fwrite(&ctl, 1, 1, f);
|
||||
fwrite(&v, sizeof(v), 1, f);
|
||||
}
|
||||
|
||||
void do_sh2_trace(SH2 *current, int cycles)
|
||||
{
|
||||
static int current_slave = -1;
|
||||
|
@ -193,39 +178,36 @@ void do_sh2_trace(SH2 *current, int cycles)
|
|||
u32 val;
|
||||
int i;
|
||||
|
||||
if (f == NULL)
|
||||
f = fopen("tracelog", "wb");
|
||||
|
||||
if (SekPc != current_m68k_pc) {
|
||||
current_m68k_pc = SekPc;
|
||||
write_uint(CTL_M68KPC, current_m68k_pc);
|
||||
tl_write_uint(CTL_M68KPC, current_m68k_pc);
|
||||
}
|
||||
|
||||
if (current->is_slave != current_slave) {
|
||||
current_slave = current->is_slave;
|
||||
v = CTL_MASTERSLAVE | current->is_slave;
|
||||
fwrite(&v, 1, 1, f);
|
||||
tl_write(&v, sizeof(v));
|
||||
}
|
||||
|
||||
for (i = 0; i < offsetof(SH2, read8_map) / 4; i++) {
|
||||
if (i == 17) // ppc
|
||||
continue;
|
||||
if (regs_a[i] != regs_o[i]) {
|
||||
write_uint(i, regs_a[i]);
|
||||
tl_write_uint(CTL_SH2_R + i, regs_a[i]);
|
||||
regs_o[i] = regs_a[i];
|
||||
}
|
||||
}
|
||||
|
||||
if (current->ea != sh2o->ea) {
|
||||
write_uint(CTL_EA, current->ea);
|
||||
tl_write_uint(CTL_EA, current->ea);
|
||||
sh2o->ea = current->ea;
|
||||
}
|
||||
val = local_read32(current, current->ea);
|
||||
if (mem_val != val) {
|
||||
write_uint(CTL_EAVAL, val);
|
||||
tl_write_uint(CTL_EAVAL, val);
|
||||
mem_val = val;
|
||||
}
|
||||
write_uint(CTL_CYCLES, cycles);
|
||||
tl_write_uint(CTL_CYCLES, cycles);
|
||||
}
|
||||
|
||||
static const char *regnames[] = {
|
||||
|
@ -264,17 +246,14 @@ void do_sh2_cmp(SH2 *current)
|
|||
int cycles;
|
||||
int i, ret;
|
||||
|
||||
if (f == NULL) {
|
||||
f = fopen("tracelog", "rb");
|
||||
sh2ref[1].is_slave = 1;
|
||||
}
|
||||
sh2ref[1].is_slave = 1;
|
||||
|
||||
while (1) {
|
||||
ret = fread(&code, 1, 1, f);
|
||||
ret = tl_read(&code, 1);
|
||||
if (ret <= 0)
|
||||
break;
|
||||
if (code == CTL_CYCLES) {
|
||||
fread(&cycles_o, 1, 4, f);
|
||||
tl_read(&cycles_o, 4);
|
||||
break;
|
||||
}
|
||||
|
||||
|
@ -284,23 +263,27 @@ void do_sh2_cmp(SH2 *current)
|
|||
current_slave = code & 1;
|
||||
break;
|
||||
case CTL_EA:
|
||||
fread(&sh2o->ea, 4, 1, f);
|
||||
tl_read_uint(&sh2o->ea);
|
||||
break;
|
||||
case CTL_EAVAL:
|
||||
fread(¤t_val, 4, 1, f);
|
||||
tl_read_uint(¤t_val);
|
||||
break;
|
||||
case CTL_M68KPC:
|
||||
fread(&val, 4, 1, f);
|
||||
tl_read_uint(&val);
|
||||
if (SekPc != val) {
|
||||
printf("m68k: %08x %08x\n", SekPc, val);
|
||||
bad = 1;
|
||||
}
|
||||
break;
|
||||
default:
|
||||
if (code < offsetof(SH2, read8_map) / 4)
|
||||
fread(regs_o + code, 4, 1, f);
|
||||
else {
|
||||
printf("invalid code: %02x\n", code);
|
||||
if (CTL_SH2_R <= code && code < CTL_SH2_R +
|
||||
offsetof(SH2, read8_map) / 4)
|
||||
{
|
||||
tl_read_uint(regs_o + code - CTL_SH2_R);
|
||||
}
|
||||
else
|
||||
{
|
||||
printf("wrong code: %02x\n", code);
|
||||
goto end;
|
||||
}
|
||||
break;
|
||||
|
|
33
pico/debug.c
33
pico/debug.c
|
@ -40,7 +40,7 @@ char *PDebugMain(void)
|
|||
sprintf(dstrp, "mode set 4: %02x\n", (r=reg[0xC])); MVP;
|
||||
sprintf(dstrp, "interlace: %i%i, cells: %i, shadow: %i\n", bit(r,2), bit(r,1), (r&0x80) ? 40 : 32, bit(r,3)); MVP;
|
||||
sprintf(dstrp, "scroll size: w: %i, h: %i SRAM: %i; eeprom: %i (%i)\n", reg[0x10]&3, (reg[0x10]&0x30)>>4,
|
||||
!!(SRam.flags & SRF_ENABLED), !!(SRam.flags & SRF_EEPROM), SRam.eeprom_type); MVP;
|
||||
!!(SRam.flags & SRF_ENABLED), !!(SRam.flags & SRF_EEPROM), SRam.eeprom_type); MVP;
|
||||
sprintf(dstrp, "sram range: %06x-%06x, reg: %02x\n", SRam.start, SRam.end, Pico.m.sram_reg); MVP;
|
||||
sprintf(dstrp, "pend int: v:%i, h:%i, vdp status: %04x\n", bit(pv->pending_ints,5), bit(pv->pending_ints,4), pv->status); MVP;
|
||||
sprintf(dstrp, "pal: %i, hw: %02x, frame#: %i, cycles: %i\n", Pico.m.pal, Pico.m.hardware, Pico.m.frame_count, SekCyclesDoneT()); MVP;
|
||||
|
@ -535,4 +535,35 @@ void pevt_dump(void)
|
|||
}
|
||||
#endif
|
||||
|
||||
#if defined(CPU_CMP_R) || defined(CPU_CMP_W) || defined(DRC_CMP)
|
||||
static FILE *tl_f;
|
||||
|
||||
void tl_write(const void *ptr, size_t size)
|
||||
{
|
||||
if (tl_f == NULL)
|
||||
tl_f = fopen("tracelog", "wb");
|
||||
|
||||
fwrite(ptr, 1, size, tl_f);
|
||||
}
|
||||
|
||||
void tl_write_uint(unsigned char ctl, unsigned int v)
|
||||
{
|
||||
tl_write(&ctl, sizeof(ctl));
|
||||
tl_write(&v, sizeof(v));
|
||||
}
|
||||
|
||||
int tl_read(void *ptr, size_t size)
|
||||
{
|
||||
if (tl_f == NULL)
|
||||
tl_f = fopen("tracelog", "rb");
|
||||
|
||||
return fread(ptr, 1, size, tl_f);
|
||||
}
|
||||
|
||||
int tl_read_uint(void *ptr)
|
||||
{
|
||||
return tl_read(ptr, 4);
|
||||
}
|
||||
#endif
|
||||
|
||||
// vim:shiftwidth=2:ts=2:expandtab
|
||||
|
|
20
pico/debug.h
20
pico/debug.h
|
@ -9,3 +9,23 @@ void PDebugDumpMem(void);
|
|||
void PDebugZ80Frame(void);
|
||||
void PDebugCPUStep(void);
|
||||
|
||||
#if defined(CPU_CMP_R) || defined(CPU_CMP_W) || defined(DRC_CMP)
|
||||
enum ctl_byte {
|
||||
CTL_68K_SLAVE = 0x02,
|
||||
CTL_68K_PC = 0x04,
|
||||
CTL_68K_SR = 0x05,
|
||||
CTL_68K_CYCLES = 0x06,
|
||||
CTL_68K_R = 0x10, // .. 0x20
|
||||
CTL_MASTERSLAVE = 0x80,
|
||||
CTL_EA = 0x82,
|
||||
CTL_EAVAL = 0x83,
|
||||
CTL_M68KPC = 0x84,
|
||||
CTL_CYCLES = 0x85,
|
||||
CTL_SH2_R = 0x90, // .. 0xa8
|
||||
};
|
||||
|
||||
void tl_write(const void *ptr, size_t size);
|
||||
void tl_write_uint(unsigned char ctl, unsigned int v);
|
||||
int tl_read(void *ptr, size_t size);
|
||||
int tl_read_uint(void *ptr);
|
||||
#endif
|
||||
|
|
|
@ -24,16 +24,18 @@
|
|||
cyclone_checkpc:
|
||||
ldr r1, [r7, #0x60] @ membase
|
||||
sub r0, r0, r1
|
||||
bic r0, r0, #0xff000000
|
||||
bics r0, r0, #1
|
||||
and r3, r0, #0xff000000
|
||||
bic r0, r0, #1
|
||||
bics r2, r0, #0xff000000
|
||||
beq crashed
|
||||
|
||||
ldr r1, [r7, #0x6c] @ read16 map
|
||||
mov r2, r0, lsr #M68K_MEM_SHIFT
|
||||
mov r2, r2, lsr #M68K_MEM_SHIFT
|
||||
ldr r1, [r1, r2, lsl #2]
|
||||
movs r1, r1, lsl #1
|
||||
bcs crashed
|
||||
|
||||
sub r1, r1, r3
|
||||
str r1, [r7, #0x60] @ membase
|
||||
add r0, r0, r1
|
||||
bx lr
|
||||
|
|
|
@ -146,7 +146,7 @@ int PicoReset(void)
|
|||
if (Pico.romsize <= 0)
|
||||
return 1;
|
||||
|
||||
#ifdef DRC_CMP
|
||||
#if defined(CPU_CMP_R) || defined(CPU_CMP_W) || defined(DRC_CMP)
|
||||
PicoOpt |= POPT_DIS_VDP_FIFO|POPT_DIS_IDLE_DET;
|
||||
#endif
|
||||
|
||||
|
|
|
@ -50,6 +50,7 @@ static __inline void SekRunM68k(int cyc)
|
|||
#endif
|
||||
|
||||
out:
|
||||
SekTrace(0);
|
||||
pevt_log_m68k_o(EVT_RUN_END);
|
||||
pprof_end(m68k);
|
||||
}
|
||||
|
|
|
@ -46,8 +46,10 @@ extern struct Cyclone PicoCpuCM68k, PicoCpuCS68k;
|
|||
#define SekEndTimesliceS68k(after) PicoCpuCS68k.cycles=after
|
||||
#define SekPc (PicoCpuCM68k.pc-PicoCpuCM68k.membase)
|
||||
#define SekPcS68k (PicoCpuCS68k.pc-PicoCpuCS68k.membase)
|
||||
#define SekDar(x) (x < 8 ? PicoCpuCM68k.d[x] : PicoCpuCM68k.a[x - 8])
|
||||
#define SekDar(x) (x < 8 ? PicoCpuCM68k.d[x] : PicoCpuCM68k.a[x - 8])
|
||||
#define SekDarS68k(x) (x < 8 ? PicoCpuCS68k.d[x] : PicoCpuCS68k.a[x - 8])
|
||||
#define SekSr CycloneGetSr(&PicoCpuCM68k)
|
||||
#define SekSrS68k CycloneGetSr(&PicoCpuCS68k)
|
||||
#define SekSetStop(x) { PicoCpuCM68k.state_flags&=~1; if (x) { PicoCpuCM68k.state_flags|=1; PicoCpuCM68k.cycles=0; } }
|
||||
#define SekSetStopS68k(x) { PicoCpuCS68k.state_flags&=~1; if (x) { PicoCpuCS68k.state_flags|=1; PicoCpuCS68k.cycles=0; } }
|
||||
#define SekIsStoppedM68k() (PicoCpuCM68k.state_flags&1)
|
||||
|
@ -74,8 +76,10 @@ extern M68K_CONTEXT PicoCpuFM68k, PicoCpuFS68k;
|
|||
#define SekEndTimesliceS68k(after) PicoCpuFS68k.io_cycle_counter=after
|
||||
#define SekPc fm68k_get_pc(&PicoCpuFM68k)
|
||||
#define SekPcS68k fm68k_get_pc(&PicoCpuFS68k)
|
||||
#define SekDar(x) (x < 8 ? PicoCpuFM68k.dreg[x].D : PicoCpuFM68k.areg[x - 8].D)
|
||||
#define SekDar(x) (x < 8 ? PicoCpuFM68k.dreg[x].D : PicoCpuFM68k.areg[x - 8].D)
|
||||
#define SekDarS68k(x) (x < 8 ? PicoCpuFS68k.dreg[x].D : PicoCpuFS68k.areg[x - 8].D)
|
||||
#define SekSr PicoCpuFM68k.sr
|
||||
#define SekSrS68k PicoCpuFS68k.sr
|
||||
#define SekSetStop(x) { \
|
||||
PicoCpuFM68k.execinfo &= ~FM68K_HALTED; \
|
||||
if (x) { PicoCpuFM68k.execinfo |= FM68K_HALTED; PicoCpuFM68k.io_cycle_counter = 0; } \
|
||||
|
@ -109,8 +113,10 @@ extern m68ki_cpu_core PicoCpuMM68k, PicoCpuMS68k;
|
|||
#define SekEndTimesliceS68k(after) PicoCpuMS68k.cyc_remaining_cycles=after
|
||||
#define SekPc m68k_get_reg(&PicoCpuMM68k, M68K_REG_PC)
|
||||
#define SekPcS68k m68k_get_reg(&PicoCpuMS68k, M68K_REG_PC)
|
||||
#define SekDar(x) PicoCpuMM68k.dar[x]
|
||||
#define SekSr m68k_get_reg(&PicoCpuMM68k, M68K_REG_SR)
|
||||
#define SekDar(x) PicoCpuMM68k.dar[x]
|
||||
#define SekDarS68k(x) PicoCpuMS68k.dar[x]
|
||||
#define SekSr m68k_get_reg(&PicoCpuMM68k, M68K_REG_SR)
|
||||
#define SekSrS68k m68k_get_reg(&PicoCpuMS68k, M68K_REG_SR)
|
||||
#define SekSetStop(x) { \
|
||||
if(x) { SET_CYCLES(0); PicoCpuMM68k.stopped=STOP_LEVEL_STOP; } \
|
||||
else PicoCpuMM68k.stopped=0; \
|
||||
|
@ -633,6 +639,11 @@ PICO_INTERNAL void SekUnpackCpu(const unsigned char *cpu, int is_sub);
|
|||
void SekStepM68k(void);
|
||||
void SekInitIdleDet(void);
|
||||
void SekFinishIdleDet(void);
|
||||
#if defined(CPU_CMP_R) || defined(CPU_CMP_W)
|
||||
void SekTrace(int is_s68k);
|
||||
#else
|
||||
#define SekTrace(x)
|
||||
#endif
|
||||
|
||||
// cd/sek.c
|
||||
PICO_INTERNAL void SekInitS68k(void);
|
||||
|
|
118
pico/sek.c
118
pico/sek.c
|
@ -420,6 +420,122 @@ void SekFinishIdleDet(void)
|
|||
}
|
||||
|
||||
|
||||
#if defined(CPU_CMP_R) || defined(CPU_CMP_W)
|
||||
#include "debug.h"
|
||||
|
||||
struct ref_68k {
|
||||
u32 dar[16];
|
||||
u32 pc;
|
||||
u32 sr;
|
||||
u32 cycles;
|
||||
u32 pc_prev;
|
||||
};
|
||||
struct ref_68k ref_68ks[2];
|
||||
static int current_68k;
|
||||
|
||||
void SekTrace(int is_s68k)
|
||||
{
|
||||
struct ref_68k *x68k = &ref_68ks[is_s68k];
|
||||
u32 pc = is_s68k ? SekPcS68k : SekPc;
|
||||
u32 sr = is_s68k ? SekSrS68k : SekSr;
|
||||
u32 cycles = is_s68k ? SekCycleCntS68k : SekCycleCnt;
|
||||
u32 r;
|
||||
u8 cmd;
|
||||
#ifdef CPU_CMP_W
|
||||
int i;
|
||||
|
||||
if (is_s68k != current_68k) {
|
||||
current_68k = is_s68k;
|
||||
cmd = CTL_68K_SLAVE | current_68k;
|
||||
tl_write(&cmd, sizeof(cmd));
|
||||
}
|
||||
if (pc != x68k->pc) {
|
||||
x68k->pc = pc;
|
||||
tl_write_uint(CTL_68K_PC, x68k->pc);
|
||||
}
|
||||
if (sr != x68k->sr) {
|
||||
x68k->sr = sr;
|
||||
tl_write_uint(CTL_68K_SR, x68k->sr);
|
||||
}
|
||||
for (i = 0; i < 16; i++) {
|
||||
r = is_s68k ? SekDarS68k(i) : SekDar(i);
|
||||
if (r != x68k->dar[i]) {
|
||||
x68k->dar[i] = r;
|
||||
tl_write_uint(CTL_68K_R + i, r);
|
||||
}
|
||||
}
|
||||
tl_write_uint(CTL_68K_CYCLES, cycles);
|
||||
#else
|
||||
int i, bad = 0;
|
||||
|
||||
while (1)
|
||||
{
|
||||
int ret = tl_read(&cmd, sizeof(cmd));
|
||||
if (ret == 0) {
|
||||
elprintf(EL_STATUS, "EOF");
|
||||
exit(1);
|
||||
}
|
||||
switch (cmd) {
|
||||
case CTL_68K_SLAVE:
|
||||
case CTL_68K_SLAVE + 1:
|
||||
current_68k = cmd & 1;
|
||||
break;
|
||||
case CTL_68K_PC:
|
||||
tl_read_uint(&x68k->pc);
|
||||
break;
|
||||
case CTL_68K_SR:
|
||||
tl_read_uint(&x68k->sr);
|
||||
break;
|
||||
case CTL_68K_CYCLES:
|
||||
tl_read_uint(&x68k->cycles);
|
||||
goto breakloop;
|
||||
default:
|
||||
if (CTL_68K_R <= cmd && cmd < CTL_68K_R + 0x10)
|
||||
tl_read_uint(&x68k->dar[cmd - CTL_68K_R]);
|
||||
else
|
||||
elprintf(EL_STATUS, "invalid cmd: %02x", cmd);
|
||||
}
|
||||
}
|
||||
|
||||
breakloop:
|
||||
if (is_s68k != current_68k) {
|
||||
printf("bad 68k: %d %d\n", is_s68k, current_68k);
|
||||
bad = 1;
|
||||
}
|
||||
if (cycles != x68k->cycles) {
|
||||
printf("bad cycles: %u %u\n", cycles, x68k->cycles);
|
||||
bad = 1;
|
||||
}
|
||||
if ((pc ^ x68k->pc) & 0xffffff) {
|
||||
printf("bad PC: %08x %08x\n", pc, x68k->pc);
|
||||
bad = 1;
|
||||
}
|
||||
if (sr != x68k->sr) {
|
||||
printf("bad SR: %03x %03x\n", sr, x68k->sr);
|
||||
bad = 1;
|
||||
}
|
||||
for (i = 0; i < 16; i++) {
|
||||
r = is_s68k ? SekDarS68k(i) : SekDar(i);
|
||||
if (r != x68k->dar[i]) {
|
||||
printf("bad %c%d: %08x %08x\n", i < 8 ? 'D' : 'A', i & 7,
|
||||
r, x68k->dar[i]);
|
||||
bad = 1;
|
||||
}
|
||||
}
|
||||
if (bad) {
|
||||
for (i = 0; i < 8; i++)
|
||||
printf("D%d: %08x A%d: %08x\n", i, x68k->dar[i],
|
||||
i, x68k->dar[i + 8]);
|
||||
printf("PC: %08x, %08x\n", x68k->pc, x68k->pc_prev);
|
||||
|
||||
PDebugDumpMem();
|
||||
exit(1);
|
||||
}
|
||||
x68k->pc_prev = x68k->pc;
|
||||
#endif
|
||||
}
|
||||
#endif // CPU_CMP_*
|
||||
|
||||
#if defined(EMU_M68K) && M68K_INSTRUCTION_HOOK == OPT_SPECIFY_HANDLER
|
||||
static unsigned char op_flags[0x400000/2] = { 0, };
|
||||
static int atexit_set = 0;
|
||||
|
@ -447,3 +563,5 @@ void instruction_hook(void)
|
|||
op_flags[REG_PC/2] = 1;
|
||||
}
|
||||
#endif
|
||||
|
||||
// vim:shiftwidth=2:ts=2:expandtab
|
||||
|
|
|
@ -30,6 +30,13 @@ SRCS_COMMON += $(R)cpu/debug.c
|
|||
LDFLAGS += -lreadline
|
||||
endif
|
||||
endif
|
||||
ifeq "$(cpu_cmp)" "1"
|
||||
ifdef cpu_cmp_w
|
||||
DEFINES += CPU_CMP_W
|
||||
else
|
||||
DEFINES += CPU_CMP_R
|
||||
endif # cpu_cmp_w
|
||||
endif
|
||||
ifeq "$(pprof)" "1"
|
||||
DEFINES += PPROF
|
||||
SRCS_COMMON += $(R)platform/linux/pprof.c
|
||||
|
@ -157,10 +164,6 @@ SRCS_COMMON += $(R)cpu/sh2/mame/sh2dasm.c
|
|||
SRCS_COMMON += $(R)platform/libpicofe/linux/host_dasm.c
|
||||
LDFLAGS += -lbfd -lopcodes -liberty
|
||||
endif
|
||||
ifeq "$(drc_debug_interp)" "1"
|
||||
DEFINES += DRC_DEBUG_INTERP
|
||||
use_sh2mame = 1
|
||||
endif
|
||||
endif # use_sh2drc
|
||||
#
|
||||
ifeq "$(use_sh2mame)" "1"
|
||||
|
@ -183,7 +186,7 @@ $(FR)cpu/cyclone/Cyclone.h:
|
|||
|
||||
$(FR)cpu/cyclone/Cyclone.s:
|
||||
@echo building Cyclone...
|
||||
@make -C $(R)cpu/cyclone/ CONFIG_FILE='\"../cyclone_config.h\"'
|
||||
@make -C $(R)cpu/cyclone/ CONFIG_FILE=../cyclone_config.h
|
||||
|
||||
$(FR)cpu/musashi/m68kops.c:
|
||||
@make -C $(R)cpu/musashi
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue