--- generator/main/cpu68k.c 2020/03/04 04:46:43 1.1 +++ generator/main/cpu68k.c 2020/03/04 04:47:21 1.1.1.3 @@ -5,8 +5,8 @@ #include #include "generator.h" -#include "mem68k.h" #include "cpu68k.h" +#include "mem68k.h" #include "vdp.h" #include "ui.h" #include "def68k-iibs.h" @@ -19,12 +19,12 @@ uint8 *cpu68k_rom = NULL; unsigned int cpu68k_romlen = 0; uint8 *cpu68k_ram = NULL; t_iib *cpu68k_iibtable[65536]; -void (*cpu68k_functable[65536*2])(t_ipc *ipc); +void (*cpu68k_functable[65536 * 2]) (t_ipc * ipc); int cpu68k_totalinstr; int cpu68k_totalfuncs; unsigned int cpu68k_clocks; unsigned int cpu68k_frames; -unsigned int cpu68k_frozen; /* cpu frozen, do not interrupt, make pending */ +unsigned int cpu68k_frozen; /* cpu frozen, do not interrupt, make pending */ t_regs regs; uint8 movem_bit[256]; t_ipclist *ipclist[LEN_IPCLISTTABLE]; @@ -56,7 +56,7 @@ int cpu68k_init(void) dbits = 0; for (j = 0; j < 2; j++) { - switch(j ? iib->stype : iib->dtype) { + switch (j ? iib->stype : iib->dtype) { case dt_Dreg: case dt_Areg: case dt_Aind: @@ -64,86 +64,86 @@ int cpu68k_init(void) case dt_Adec: case dt_Adis: case dt_Aidx: - if (j) { - bitmap ^= 7<sbitpos; - sbits = 3; - } else { - bitmap ^= 7<dbitpos; - dbits = 3; - } - break; + if (j) { + bitmap ^= 7 << iib->sbitpos; + sbits = 3; + } else { + bitmap ^= 7 << iib->dbitpos; + dbits = 3; + } + break; case dt_AbsW: case dt_AbsL: case dt_Pdis: case dt_Pidx: - break; + break; case dt_ImmB: case dt_ImmW: case dt_ImmL: case dt_ImmS: - break; + break; case dt_Imm3: - if (j) { - bitmap ^= 7<sbitpos; - sbits = 3; - } else { - bitmap ^= 7<dbitpos; - dbits = 3; - } - break; + if (j) { + bitmap ^= 7 << iib->sbitpos; + sbits = 3; + } else { + bitmap ^= 7 << iib->dbitpos; + dbits = 3; + } + break; case dt_Imm4: - if (j) { - bitmap ^= 15<sbitpos; - sbits = 4; - } else { - bitmap ^= 15<dbitpos; - dbits = 4; - } - break; + if (j) { + bitmap ^= 15 << iib->sbitpos; + sbits = 4; + } else { + bitmap ^= 15 << iib->dbitpos; + dbits = 4; + } + break; case dt_Imm8: case dt_Imm8s: - if (j) { - bitmap ^= 255<sbitpos; - sbits = 8; - } else { - bitmap ^= 255<dbitpos; - dbits = 8; - } - break; + if (j) { + bitmap ^= 255 << iib->sbitpos; + sbits = 8; + } else { + bitmap ^= 255 << iib->dbitpos; + dbits = 8; + } + break; case dt_ImmV: - sbits = 12; - bitmap ^= 0x0FFF; - break; + sbits = 12; + bitmap ^= 0x0FFF; + break; case dt_Ill: - /* no src/dst parameter */ - break; + /* no src/dst parameter */ + break; default: - LOG_CRITICAL(("CPU definition #%d incorrect", i)); - return 1; + LOG_CRITICAL(("CPU definition #%d incorrect", i)); + return 1; } } if (bitmap != 0xFFFF) { LOG_CRITICAL(("CPU definition #%d incorrect (0x%x)", i, bitmap)); return 1; } - for (sbit = 0; sbit < (1<bits | (sbit<sbitpos) | (dbit<dbitpos); - if (iib->stype == dt_Imm3 || iib->stype == dt_Imm4 || - iib->stype == dt_Imm8) { - if (sbit == 0 && iib->flags.imm_notzero) { - continue; - } - } - if (cpu68k_iibtable[bitmap] != NULL) { - LOG_CRITICAL(("CPU definition #%d conflicts (0x%x)", i, bitmap)); - return 1; - } - cpu68k_iibtable[bitmap] = iib; - /* set both flag and non-flag versions */ - cpu68k_functable[bitmap*2] = cpu68k_funcindex[i*2]; - cpu68k_functable[bitmap*2+1] = cpu68k_funcindex[i*2+1]; - cpu68k_totalinstr++; + for (sbit = 0; sbit < (1 << sbits); sbit++) { + for (dbit = 0; dbit < (1 << dbits); dbit++) { + bitmap = iib->bits | (sbit << iib->sbitpos) | (dbit << iib->dbitpos); + if (iib->stype == dt_Imm3 || iib->stype == dt_Imm4 + || iib->stype == dt_Imm8) { + if (sbit == 0 && iib->flags.imm_notzero) { + continue; + } + } + if (cpu68k_iibtable[bitmap] != NULL) { + LOG_CRITICAL(("CPU definition #%d conflicts (0x%x)", i, bitmap)); + return 1; + } + cpu68k_iibtable[bitmap] = iib; + /* set both flag and non-flag versions */ + cpu68k_functable[bitmap * 2] = cpu68k_funcindex[i * 2]; + cpu68k_functable[bitmap * 2 + 1] = cpu68k_funcindex[i * 2 + 1]; + cpu68k_totalinstr++; } } } @@ -157,7 +157,7 @@ int cpu68k_init(void) } if (j != cpu68k_totalinstr) { LOG_CRITICAL(("Instruction count not verified (%d/%d)\n", - cpu68k_totalinstr, i)); + cpu68k_totalinstr, i)); return 1; } @@ -165,29 +165,30 @@ int cpu68k_init(void) for (i = 0; i < 256; i++) { for (j = 0; j < 8; j++) { - if (i & 1<opcode, ipc->used, ipc->set); + printf(" opcode: %04X, uses %X set %X\n", ipc->opcode, ipc->used, + ipc->set); printf(" src = %08X\n", ipc->src); printf(" dst = %08X\n", ipc->dst); } /* fill in ipc */ -void cpu68k_ipc(uint32 addr68k, uint8 *addr, t_iib *iib, t_ipc *ipc) +void cpu68k_ipc(uint32 addr68k, uint8 *addr, t_iib * iib, t_ipc * ipc) { t_type type; uint32 *p; @@ -205,24 +206,24 @@ void cpu68k_ipc(uint32 addr68k, uint8 *a if ((iib->mnemonic == i_Bcc) || (iib->mnemonic == i_BSR)) { /* special case - we can calculate the offset now */ /* low 8 bits of current instruction are addr+1 */ - ipc->src = (sint32)(*(sint8 *)(addr+1)); + ipc->src = (sint32)(*(sint8 *)(addr + 1)); if (ipc->src == 0) { - ipc->src = (sint32)(sint16)LOCENDIAN16(*(uint16 *)(addr+2)); + ipc->src = (sint32)(sint16)LOCENDIAN16(*(uint16 *)(addr + 2)); ipc->wordlen++; } - ipc->src+= addr68k+2; /* add PC of next instruction */ + ipc->src += addr68k + 2; /* add PC of next instruction */ return; } if (iib->mnemonic == i_DBcc || iib->mnemonic == i_DBRA) { /* special case - we can calculate the offset now */ - ipc->src = (sint32)(sint16)LOCENDIAN16(*(uint16 *)(addr+2)); - ipc->src+= addr68k+2; /* add PC of next instruction */ + ipc->src = (sint32)(sint16)LOCENDIAN16(*(uint16 *)(addr + 2)); + ipc->src += addr68k + 2; /* add PC of next instruction */ ipc->wordlen++; return; } - addr+= 2; - addr68k+= 2; + addr += 2; + addr68k += 2; for (type = 0; type < 2; type++) { if (type == tp_src) @@ -230,90 +231,90 @@ void cpu68k_ipc(uint32 addr68k, uint8 *a else p = &(ipc->dst); - switch(type == tp_src ? iib->stype : iib->dtype) { + switch (type == tp_src ? iib->stype : iib->dtype) { case dt_Adis: *p = (sint32)(sint16)LOCENDIAN16(*(uint16 *)addr); ipc->wordlen++; - addr+= 2; - addr68k+= 2; + addr += 2; + addr68k += 2; break; case dt_Aidx: *p = (sint32)(sint8)addr[1]; - *p = (*p & 0xFFFFFF) | (*addr)<<24; + *p = (*p & 0xFFFFFF) | (*addr) << 24; ipc->wordlen++; - addr+= 2; - addr68k+= 2; + addr += 2; + addr68k += 2; break; case dt_AbsW: *p = (sint32)(sint16)LOCENDIAN16(*(uint16 *)addr); ipc->wordlen++; - addr+= 2; - addr68k+= 2; + addr += 2; + addr68k += 2; break; case dt_AbsL: - *p = (uint32)( (LOCENDIAN16(*(uint16 *)addr)<<16) + - LOCENDIAN16(*(uint16 *)(addr+2)) ); - ipc->wordlen+= 2; - addr+= 4; - addr68k+= 4; + *p = (uint32)((LOCENDIAN16(*(uint16 *)addr) << 16) + + LOCENDIAN16(*(uint16 *)(addr + 2))); + ipc->wordlen += 2; + addr += 4; + addr68k += 4; break; case dt_Pdis: *p = (sint32)(sint16)LOCENDIAN16(*(uint16 *)addr); - *p+= addr68k; /* add PC of extension word (this word) */ + *p += addr68k; /* add PC of extension word (this word) */ ipc->wordlen++; - addr+= 2; - addr68k+= 2; + addr += 2; + addr68k += 2; break; case dt_Pidx: *p = ((sint32)(sint8)addr[1]) + addr68k; - *p = (*p & 0xFFFFFF) | (*addr)<<24; + *p = (*p & 0xFFFFFF) | (*addr) << 24; ipc->wordlen++; - addr+= 2; - addr68k+= 2; + addr += 2; + addr68k += 2; break; case dt_ImmB: /* low 8 bits of next 16 bit word is addr+1 */ - *p = (uint32)(*(uint8 *)(addr+1)); + *p = (uint32)(*(uint8 *)(addr + 1)); ipc->wordlen++; - addr+= 2; - addr68k+= 2; + addr += 2; + addr68k += 2; break; case dt_ImmW: *p = (uint32)LOCENDIAN16(*(uint16 *)addr); ipc->wordlen++; - addr+= 2; - addr68k+= 2; + addr += 2; + addr68k += 2; break; case dt_ImmL: - *p = (uint32)( (LOCENDIAN16(*(uint16 *)addr)<<16) + - LOCENDIAN16(*(uint16 *)(addr+2)) ); - ipc->wordlen+= 2; - addr+= 4; - addr68k+= 4; + *p = (uint32)((LOCENDIAN16(*(uint16 *)addr) << 16) + + LOCENDIAN16(*(uint16 *)(addr + 2))); + ipc->wordlen += 2; + addr += 4; + addr68k += 4; break; case dt_Imm3: if (type == tp_src) - *p = (ipc->opcode >> iib->sbitpos) & 7; + *p = (ipc->opcode >> iib->sbitpos) & 7; else - *p = (ipc->opcode >> iib->dbitpos) & 7; + *p = (ipc->opcode >> iib->dbitpos) & 7; break; case dt_Imm4: if (type == tp_src) - *p = (ipc->opcode >> iib->sbitpos) & 15; + *p = (ipc->opcode >> iib->sbitpos) & 15; else - *p = (ipc->opcode >> iib->dbitpos) & 15; + *p = (ipc->opcode >> iib->dbitpos) & 15; break; case dt_Imm8: if (type == tp_src) - *p = (ipc->opcode >> iib->sbitpos) & 255; + *p = (ipc->opcode >> iib->sbitpos) & 255; else - *p = (ipc->opcode >> iib->dbitpos) & 255; + *p = (ipc->opcode >> iib->dbitpos) & 255; break; case dt_Imm8s: if (type == tp_src) - *p = (sint32)(sint8)((ipc->opcode >> iib->sbitpos) & 255); + *p = (sint32)(sint8)((ipc->opcode >> iib->sbitpos) & 255); else - *p = (sint32)(sint8)((ipc->opcode >> iib->dbitpos) & 255); + *p = (sint32)(sint8)((ipc->opcode >> iib->dbitpos) & 255); break; default: break; @@ -324,8 +325,8 @@ void cpu68k_ipc(uint32 addr68k, uint8 *a t_ipclist *cpu68k_makeipclist(uint32 pc) { int size = 16; - t_ipclist *list = malloc(sizeof(t_ipclist) + 16*sizeof(t_ipc) + 8); - t_ipc *ipc = (t_ipc *)(list+1); + t_ipclist *list = malloc(sizeof(t_ipclist) + 16 * sizeof(t_ipc) + 8); + t_ipc *ipc = (t_ipc *) (list + 1); t_iib *iib; int instrs = 0; uint16 required; @@ -334,7 +335,7 @@ t_ipclist *cpu68k_makeipclist(uint32 pc) if (list == NULL) ui_err("Out of memory"); - pc&= 0xffffff; + pc &= 0xffffff; list->pc = pc; list->clocks = 0; list->norepeat = 0; @@ -343,48 +344,49 @@ t_ipclist *cpu68k_makeipclist(uint32 pc) if (instrs > size) { if (size > 10000) ui_err("Something has gone seriously wrong @ %08X", pc); - size+= 16; - list = realloc(list, sizeof(t_ipclist) + size*sizeof(t_ipc) + 8); + size += 16; + list = realloc(list, sizeof(t_ipclist) + size * sizeof(t_ipc) + 8); if (list == NULL) ui_err("Out of memory whilst making ipc list @ %08X", pc); - ipc = ((t_ipc *)(list+1))+instrs-1; + ipc = ((t_ipc *) (list + 1)) + instrs - 1; } if (!(iib = cpu68k_iibtable[fetchword(pc)])) { - ui_err("Invalid instruction @ %08X", pc); + ui_err("Invalid instruction @ %08X [%04X]", pc, fetchword(pc)); } - cpu68k_ipc(pc, mem68k_memptr[pc>>12](pc), iib, ipc); - list->clocks+= iib->clocks; - pc+= (iib->wordlen)<<1; + cpu68k_ipc(pc, mem68k_memptr[pc >> 12] (pc), iib, ipc); + list->clocks += iib->clocks; + pc += (iib->wordlen) << 1; ipc++; - } while (!iib->flags.endblk); + } + while (!iib->flags.endblk); *(int *)ipc = 0; if (instrs == 2) { ipc--; if (iib->mnemonic == i_Bcc && ipc->src == list->pc) { /* we have a 2-instruction block ending in a branch to start */ - ipc = (t_ipc *)(list+1); + ipc = (t_ipc *) (list + 1); iib = cpu68k_iibtable[ipc->opcode]; if (iib->mnemonic == i_TST || iib->mnemonic == i_CMP) { - /* it's a tst/cmp and then a Bcc */ - if (!(iib->stype == dt_Ainc || iib->stype == dt_Adec)) { - /* no change could happen during the block */ - list->norepeat = 1; - } + /* it's a tst/cmp and then a Bcc */ + if (!(iib->stype == dt_Ainc || iib->stype == dt_Adec)) { + /* no change could happen during the block */ + list->norepeat = 1; + } } } } - ipc = ((t_ipc *)(list+1))+instrs-1; - required = 0x1F; /* all 5 flags need to be correct at end */ + ipc = ((t_ipc *) (list + 1)) + instrs - 1; + required = 0x1F; /* all 5 flags need to be correct at end */ for (i = 0; i < instrs; i++) { - ipc->set&= required; - required&= ~ipc->set; - required|= ipc->used; + ipc->set &= required; + required &= ~ipc->set; + required |= ipc->used; if (ipc->set) { - ipc->function = cpu68k_functable[(ipc->opcode<<1)+1]; + ipc->function = cpu68k_functable[(ipc->opcode << 1) + 1]; } else { - ipc->function = cpu68k_functable[ipc->opcode<<1]; + ipc->function = cpu68k_functable[ipc->opcode << 1]; } ipc--; } @@ -392,12 +394,25 @@ t_ipclist *cpu68k_makeipclist(uint32 pc) return list; } +void cpu68k_clearcache(void) +{ + int i; + + for (i = 0; i < LEN_IPCLISTTABLE; i++) { + if (ipclist[i]) { + free(ipclist[i]); + ipclist[i] = NULL; + } + } +} + void cpu68k_reset(void) { int i; if (!cpu68k_ram) { - if ((cpu68k_ram = malloc(0x10000)) == NULL) + /* +4 due to bug in DIRECTRAM hdr/mem68k.h code over-run of buffer */ + if ((cpu68k_ram = malloc(0x10000 + 4)) == NULL) ui_err("Out of memory"); } memset(cpu68k_ram, 0, 0x10000); @@ -405,10 +420,10 @@ void cpu68k_reset(void) regs.pc = fetchlong(4); regs.regs[15] = fetchlong(0); regs.sr.sr_int = 0; - regs.sr.sr_struct.s = 1; /* Supervisor mode*/ + regs.sr.sr_struct.s = 1; /* Supervisor mode */ regs.stop = 0; - cpu68k_clocks = 0; - cpu68k_frames = 0; /* Number of frames */ + cpu68k_clocks = 0; + cpu68k_frames = 0; /* Number of frames */ for (i = 0; i < LEN_IPCLISTTABLE; i++) { if (ipclist[i]) {