X-Git-Url: https://notaz.gp2x.de/cgi-bin/gitweb.cgi?a=blobdiff_plain;f=cpu%2Ffame%2Ffamec.c;h=3dcb8b121aff011d9a80b2460724200eb3444d3f;hb=03e4f2a349247334666c87abe3a908df72d23051;hp=609b76fe029d50fe8b15b24378972960a286a57f;hpb=70357ce52578dee0dd3b3663902cf872c3d34258;p=picodrive.git diff --git a/cpu/fame/famec.c b/cpu/fame/famec.c index 609b76fe..3dcb8b12 100644 --- a/cpu/fame/famec.c +++ b/cpu/fame/famec.c @@ -306,44 +306,38 @@ static u32 flag_I; #define POST_IO \ // CCnt = io_cycle_counter; -#ifndef FAME_BIG_ENDIAN +#define READ_BYTE_F(A, D) \ + D = m68kcontext.read_byte(A) & 0xFF; + +#define READ_WORD_F(A, D) \ + D = m68kcontext.read_word(A) & 0xFFFF; - #define READ_BYTE_F(A, D) \ - D = m68kcontext.read_byte(A) & 0xFF; +#define READ_LONG_F(A, D) \ + D = m68kcontext.read_long(A); - #define READ_WORD_F(A, D) \ - D = m68kcontext.read_word(A) & 0xFFFF; +#define READSX_LONG_F READ_LONG_F - #define READ_LONG_F(A, D) \ - D = m68kcontext.read_word((A)) << 16; \ - D |= m68kcontext.read_word((A) + 2) & 0xFFFF; +#define WRITE_LONG_F(A, D) \ + m68kcontext.write_long(A, D); - #define READSX_LONG_F(A, D) \ - D = m68kcontext.read_word((A)) << 16; \ - D |= m68kcontext.read_word((A) + 2) & 0xFFFF; +#define WRITE_LONG_DEC_F(A, D) \ + m68kcontext.write_word((A) + 2, (D) & 0xFFFF); \ + m68kcontext.write_word((A), (D) >> 16); - #define WRITE_LONG_F(A, D) \ - m68kcontext.write_word((A), (D) >> 16); \ - m68kcontext.write_word((A) + 2, (D) & 0xFFFF); +#define PUSH_32_F(D) \ + AREG(7) -= 4; \ + m68kcontext.write_long(AREG(7), D); - #define WRITE_LONG_DEC_F(A, D) \ - m68kcontext.write_word((A), (D) >> 16); \ - m68kcontext.write_word((A) + 2, (D) & 0xFFFF); +#define POP_32_F(D) \ + D = m68kcontext.read_long(AREG(7)); \ + AREG(7) += 4; + +#ifndef FAME_BIG_ENDIAN #define FETCH_LONG(A) \ (A) = PC[1] | (PC[0] << 16); \ PC += 2; - #define PUSH_32_F(D) \ - AREG(7) -= 4; \ - m68kcontext.write_word(AREG(7), (D) >> 16); \ - m68kcontext.write_word(AREG(7) + 2, (D) & 0xFFFF); - - #define POP_32_F(D) \ - D = m68kcontext.read_word(AREG(7)) << 16; \ - D |= m68kcontext.read_word(AREG(7) + 2) & 0xFFFF; \ - AREG(7) += 4; - #define GET_SWORD \ (s16)(*PC) @@ -372,37 +366,10 @@ static u32 flag_I; #else - #define READ_BYTE_F(A, D) \ - D = m68kcontext.read_byte(A) & 0xFF; - - #define READ_WORD_F(A, D) \ - D = m68kcontext.read_word(A) & 0xFFFF; - - #define READ_LONG_F(A, D) \ - D = m68kcontext.read_long(A); - - #define READSX_LONG_F(A, D) \ - D = m68kcontext.read_long(A); - - #define WRITE_LONG_F(A, D) \ - m68kcontext.write_long(A, D); - - #define WRITE_LONG_DEC_F(A, D) \ - m68kcontext.write_word((A) + 2, (D) >> 16); \ - m68kcontext.write_word((A), (D) & 0xFFFF); - #define FETCH_LONG(A) \ (A) = PC[0] | (PC[1] << 16); \ PC += 2; - #define PUSH_32_F(D) \ - AREG(7) -= 4; \ - m68kcontext.write_long(AREG(7), D); - - #define POP_32_F(D) \ - D = m68kcontext.read_long(AREG(7)); \ - AREG(7) += 4; - #define GET_SWORD \ ((s16)(((*PC & 0xFF) << 8) | (*PC >> 8))) @@ -514,7 +481,7 @@ static u32 flag_I; if ((_PC_)&1) \ { \ u32 pr_PC=GET_PC; \ - m68kcontext.execinfo |= M68K_EMULATE_GROUP_0; \ + m68kcontext.execinfo |= FM68K_EMULATE_GROUP_0; \ execute_exception_group_0(M68K_ADDRESS_ERROR_EX, 0, pr_PC, 0x12 ); \ CHECK_BRANCH_EXCEPTION_GOTO_END \ } @@ -523,7 +490,7 @@ static u32 flag_I; #endif -static void init_jump_table(void); +static int init_jump_table(void); /* Custom function handler */ typedef void (*icust_handler_func)(u32 vector); @@ -626,35 +593,6 @@ static const s32 exception_cycle_table[256] = }; -/********************/ -/* helper functions */ -/********************/ - - -#if 0 -static void famec_SetFetch(u32 low_adr, u32 high_adr, u32 fetch_adr) -{ - u32 i, j; - - i = (low_adr >> M68K_FETCHSFT) & M68K_FETCHMASK; - j = (high_adr >> M68K_FETCHSFT) & M68K_FETCHMASK; - - while (i <= j) - g_m68kcontext->Fetch[i++] = fetch_adr; -} - -static void famec_SetBanks(void) -{ - u32 i=0; - while(m68kcontext.fetch[i].low_addr != (u32)-1) - { - famec_SetFetch(m68kcontext.fetch[i].low_addr,m68kcontext.fetch[i].high_addr,m68kcontext.fetch[i].offset); - i++; - } -} -#endif - - /***********************/ /* core main functions */ /***********************/ @@ -664,14 +602,14 @@ static void famec_SetBanks(void) /* Debe ser llamado para inicializar la tabla de saltos de instruccion */ /* No recibe parametros y no devuelve nada */ /***************************************************************************/ -void m68k_init(void) +void fm68k_init(void) { #ifdef FAMEC_DEBUG puts("Initializing FAME..."); #endif if (!initialised) - m68k_emulate(0); + fm68k_emulate(0); #ifdef FAMEC_DEBUG puts("FAME initialized."); @@ -687,17 +625,17 @@ void m68k_init(void) /* M68K_NO_SUP_ADDR_SPACE (2): No se puede resetear porque no hay mapa */ /* de memoria supervisor de extraccion de opcodes */ /******************************************************************************/ -int m68k_reset(void) +int fm68k_reset(void) { if (!initialised) - m68k_emulate(0); + fm68k_emulate(0); // Si la CPU esta en ejecucion, salir con M68K_RUNNING if (m68kcontext.execinfo & M68K_RUNNING) return M68K_RUNNING; // Resetear registros - memset(&m68kcontext.dreg[0], 0, 16*4); + //memset(&m68kcontext.dreg[0], 0, 16*4); // Resetear interrupts, execinfo y ASP m68kcontext.interrupts[0] = 0; @@ -705,7 +643,7 @@ int m68k_reset(void) ASP = 0; // Fijar registro de estado - m68kcontext.sr = 0x2700; + m68kcontext.sr = (m68kcontext.sr & 0xff) | 0x2700; // Obtener puntero de pila inicial y PC AREG(7) = m68kcontext.read_long(0); @@ -725,138 +663,12 @@ int m68k_reset(void) /* No recibe parametros */ /* Retorna 68k PC */ /****************************************************************************/ -u32 m68k_get_pc(M68K_CONTEXT *context) +u32 fm68k_get_pc(M68K_CONTEXT *context) { return (context->execinfo & M68K_RUNNING)?(u32)PC-BasePC:context->pc; } -/***************************************************************************/ -/* m68k_get_register(register) */ -/* Parametro: Registro a obtener valor (indice) */ -/* Retorno: Valor del registro requerido */ -/* Observacion: En caso de que el indice no sea correcto */ -/* la funcion devolvera -1 */ -/***************************************************************************/ -u32 m68k_get_register(M68K_CONTEXT *context, m68k_register reg) -{ - M68K_CONTEXT *oldcontext = g_m68kcontext; - s32 ret; - - g_m68kcontext = context; - - switch (reg) - { - case M68K_REG_D0: - case M68K_REG_D1: - case M68K_REG_D2: - case M68K_REG_D3: - case M68K_REG_D4: - case M68K_REG_D5: - case M68K_REG_D6: - case M68K_REG_D7: - ret = DREG(reg - M68K_REG_D0); - break; - - case M68K_REG_A0: - case M68K_REG_A1: - case M68K_REG_A2: - case M68K_REG_A3: - case M68K_REG_A4: - case M68K_REG_A5: - case M68K_REG_A6: - case M68K_REG_A7: - ret = AREG(reg - M68K_REG_A0); - break; - - case M68K_REG_ASP: - ret = ASP; - break; - - case M68K_REG_PC: - ret = m68k_get_pc(context); - break; - - case M68K_REG_SR: - ret = m68kcontext.sr; - break; - - default: - ret = M68K_INV_REG; - break; - } - - g_m68kcontext = oldcontext; - return ret; -} - -/***********************************************************************/ -/* m68k_set_register(register,value) */ -/* Parametros: Registro (indice) y valor a asignar */ -/* Retorno: Exito de la operacion */ -/* 0 La operacion se ha realizado satisfactoriamente */ -/* 1 El indice del registro no es valido (fuera de limites) */ -/***********************************************************************/ -u32 m68k_set_register(M68K_CONTEXT *context, m68k_register reg, u32 value) -{ - M68K_CONTEXT *oldcontext = g_m68kcontext; - s32 ret = M68K_OK; - - g_m68kcontext = context; - - switch (reg) - { - case M68K_REG_D0: - case M68K_REG_D1: - case M68K_REG_D2: - case M68K_REG_D3: - case M68K_REG_D4: - case M68K_REG_D5: - case M68K_REG_D6: - case M68K_REG_D7: - DREG(reg - M68K_REG_D0) = value; - break; - - case M68K_REG_A0: - case M68K_REG_A1: - case M68K_REG_A2: - case M68K_REG_A3: - case M68K_REG_A4: - case M68K_REG_A5: - case M68K_REG_A6: - case M68K_REG_A7: - AREG(reg - M68K_REG_A0) = value; - break; - - case M68K_REG_ASP: - ASP = value; - break; - - case M68K_REG_PC: - if (m68kcontext.execinfo & M68K_RUNNING) - { - SET_PC(value & M68K_ADR_MASK); - } - else - { - m68kcontext.pc = value; - } - break; - - case M68K_REG_SR: - m68kcontext.sr = value & 0xFFFF; - break; - - default: - ret = M68K_INV_REG; - break; - } - - g_m68kcontext = oldcontext; - return ret; -} - - ////////////////////////// // Chequea las interrupciones y las inicia static FAMEC_EXTRA_INLINE s32 interrupt_chk__(void) @@ -867,6 +679,10 @@ static FAMEC_EXTRA_INLINE s32 interrupt_chk__(void) return 0; } +int fm68k_would_interrupt(void) +{ + return interrupt_chk__(); +} static FAMEC_EXTRA_INLINE void execute_exception(s32 vect) { @@ -901,7 +717,7 @@ static FAMEC_EXTRA_INLINE void execute_exception(s32 vect) /* adjust SR */ flag_S = M68K_SR_S; - newPC&=M68K_ADR_MASK; + newPC&=M68K_ADR_MASK&~1; // don't crash on games with bad vector tables SET_PC(newPC) @@ -935,24 +751,28 @@ static u32 Opcode; // main exec function ////////////////////// -int m68k_emulate(s32 cycles) +int fm68k_emulate(s32 cycles) { if (!initialised) { +#ifdef FAMEC_NO_GOTOS init_jump_table(); return 0; +#else + goto init_jump_table; +#endif } - /* Comprobar si la CPU esta detenida debido a un doble error de bus */ - if (m68kcontext.execinfo & M68K_FAULTED) return -1; + // won't emulate double fault + // if (m68kcontext.execinfo & M68K_FAULTED) return -1; - if (m68kcontext.execinfo & M68K_HALTED) + if (m68kcontext.execinfo & FM68K_HALTED) { if (interrupt_chk__() <= 0) { return cycles; } - m68kcontext.execinfo &= ~M68K_HALTED; + m68kcontext.execinfo &= ~FM68K_HALTED; } #ifdef FAMEC_DEBUG @@ -965,8 +785,8 @@ int m68k_emulate(s32 cycles) // Cache SR SET_SR(m68kcontext.sr) - // Cache PPL - flag_I = M68K_PPL; + // Cache PPL + flag_I = M68K_PPL; // Fijar PC SET_PC(m68kcontext.pc) @@ -981,7 +801,7 @@ int m68k_emulate(s32 cycles) cycles_needed = 0; #ifdef FAMEC_EMULATE_TRACE - if (!(m68kcontext.execinfo & M68K_EMULATE_TRACE)) + if (!(m68kcontext.execinfo & FM68K_EMULATE_TRACE)) #endif { s32 line=interrupt_chk__(); @@ -995,12 +815,13 @@ int m68k_emulate(s32 cycles) execute_exception(line + 0x18); flag_I = (u32)line; + if (m68kcontext.io_cycle_counter <= 0) goto famec_End; } #ifdef FAMEC_EMULATE_TRACE else if (flag_T) { - m68kcontext.execinfo |= M68K_EMULATE_TRACE; + m68kcontext.execinfo |= FM68K_EMULATE_TRACE; cycles_needed= m68kcontext.io_cycle_counter; m68kcontext.io_cycle_counter=0; } @@ -1008,9 +829,9 @@ int m68k_emulate(s32 cycles) } -#ifndef FAMEC_NO_GOTOS +//#ifndef FAMEC_NO_GOTOS famec_Exec: -#endif +//#endif #ifdef FAMEC_DEBUG printf("Antes de NEXT... PC = %p\n", PC); @@ -1028,11 +849,11 @@ famec_Exec: #endif #ifdef FAMEC_EMULATE_TRACE - if (m68kcontext.execinfo & M68K_EMULATE_TRACE) + if (m68kcontext.execinfo & FM68K_EMULATE_TRACE) { m68kcontext.io_cycle_counter= cycles_needed; - m68kcontext.execinfo &= ~M68K_EMULATE_TRACE; - m68kcontext.execinfo |= M68K_DO_TRACE; + m68kcontext.execinfo &= ~FM68K_EMULATE_TRACE; + m68kcontext.execinfo |= FM68K_DO_TRACE; execute_exception(M68K_TRACE_EX); flag_T=0; if (m68kcontext.io_cycle_counter > 0) @@ -1042,7 +863,7 @@ famec_Exec: } else #endif - if (cycles_needed>0) + if (cycles_needed != 0) { s32 line=interrupt_chk__(); m68kcontext.io_cycle_counter= cycles_needed; @@ -1061,10 +882,12 @@ famec_Exec: #endif if (m68kcontext.io_cycle_counter > 0) { - NEXT + //NEXT + goto famec_Exec; } } +famec_End: m68kcontext.sr = GET_SR; m68kcontext.pc = GET_PC; @@ -1078,14 +901,20 @@ famec_Exec: #endif return cycles - m68kcontext.io_cycle_counter; -} - +#ifdef FAMEC_NO_GOTOS +} -static void init_jump_table(void) +static int init_jump_table(void) +{{ +#else +init_jump_table: { +#endif u32 i, j; + m68kcontext.sr = 0x2704; // Z flag + for(i = 0x0000; i <= 0xFFFF; i += 0x0001) JumpTable[0x0000 + i] = CAST_OP(0x4AFC); for(i = 0x0000; i <= 0x0007; i += 0x0001) @@ -1596,6 +1425,7 @@ static void init_jump_table(void) JumpTable[0x1EC0 + i] = CAST_OP(0x1EC0); for(i = 0x0000; i <= 0x0007; i += 0x0001) JumpTable[0x1F00 + i] = CAST_OP(0x1F00); +#if 0 for(i = 0x0000; i <= 0x0007; i += 0x0001) for(j = 0x0000; j <= 0x0E00; j += 0x0200) JumpTable[0x1008 + i + j] = CAST_OP(0x1008); @@ -1622,6 +1452,7 @@ static void init_jump_table(void) JumpTable[0x1EC8 + i] = CAST_OP(0x1EC8); for(i = 0x0000; i <= 0x0007; i += 0x0001) JumpTable[0x1F08 + i] = CAST_OP(0x1F08); +#endif for(i = 0x0000; i <= 0x0007; i += 0x0001) for(j = 0x0000; j <= 0x0E00; j += 0x0200) JumpTable[0x1010 + i + j] = CAST_OP(0x1010); @@ -3751,9 +3582,11 @@ static void init_jump_table(void) for(i = 0x0000; i <= 0x0007; i += 0x0001) for(j = 0x0000; j <= 0x0E00; j += 0x0200) JumpTable[0x9000 + i + j] = CAST_OP(0x9000); +#if 0 for(i = 0x0000; i <= 0x0007; i += 0x0001) for(j = 0x0000; j <= 0x0E00; j += 0x0200) JumpTable[0x9008 + i + j] = CAST_OP(0x9008); +#endif for(i = 0x0000; i <= 0x0007; i += 0x0001) for(j = 0x0000; j <= 0x0E00; j += 0x0200) JumpTable[0x9010 + i + j] = CAST_OP(0x9010); @@ -4030,9 +3863,11 @@ static void init_jump_table(void) for(i = 0x0000; i <= 0x0007; i += 0x0001) for(j = 0x0000; j <= 0x0E00; j += 0x0200) JumpTable[0xB000 + i + j] = CAST_OP(0xB000); +#if 0 for(i = 0x0000; i <= 0x0007; i += 0x0001) for(j = 0x0000; j <= 0x0E00; j += 0x0200) JumpTable[0xB008 + i + j] = CAST_OP(0xB008); +#endif for(i = 0x0000; i <= 0x0007; i += 0x0001) for(j = 0x0000; j <= 0x0E00; j += 0x0200) JumpTable[0xB010 + i + j] = CAST_OP(0xB010); @@ -4556,9 +4391,11 @@ static void init_jump_table(void) for(i = 0x0000; i <= 0x0007; i += 0x0001) for(j = 0x0000; j <= 0x0E00; j += 0x0200) JumpTable[0xD000 + i + j] = CAST_OP(0xD000); +#if 0 for(i = 0x0000; i <= 0x0007; i += 0x0001) for(j = 0x0000; j <= 0x0E00; j += 0x0200) JumpTable[0xD008 + i + j] = CAST_OP(0xD008); +#endif for(i = 0x0000; i <= 0x0007; i += 0x0001) for(j = 0x0000; j <= 0x0E00; j += 0x0200) JumpTable[0xD010 + i + j] = CAST_OP(0xD010); @@ -5090,6 +4927,7 @@ static void init_jump_table(void) JumpTable[0xF000 + i] = CAST_OP(0xF000); initialised = 1; -} + return 0; +}}