diff --git a/cpu/CpuIntegration.c b/cpu/CpuIntegration.c
index 8b24798..57590b7 100644
--- a/cpu/CpuIntegration.c
+++ b/cpu/CpuIntegration.c
@@ -1,4 +1,4 @@
-/* @(#) $Id: CpuIntegration.c,v 1.10 2013/01/08 19:17:33 peschau Exp $ */
+/* @(#) $Id: CpuIntegration.c,v 1.10 2013-01-08 19:17:33 peschau Exp $ */
/*=========================================================================*/
/* Fellow */
/* Initialization of 68000 core */
@@ -29,15 +29,12 @@
#include "CpuModule.h"
#include "CpuIntegration.h"
#include "CpuModule_Internal.h"
-//#include "bus.h"
-//#include "fileops.h"
-
+#include "bus.h"
+#include "fileops.h"
+#include "interrupt.h"
jmp_buf cpu_integration_exception_buffer;
-
-/* custom chip intreq bit-number to irq-level */
-static ULO cpu_integration_int_to_level[16] = {1,1,1,2, 3,3,3,4, 4,4,4,5, 5,6,6,7};
-static ULO cpu_integration_irq_source;
+ULO cpu_integration_chip_interrupt_number;
/* Cycles spent by chips (Blitter) as a result of an instruction */
static ULO cpu_integration_chip_cycles;
@@ -75,7 +72,7 @@ static ULO cpuIntegrationGetSpeedMultiplier(void)
return cpu_integration_speed_multiplier;
}
-static void cpuIntegrationCalculateMultiplier(void)
+void cpuIntegrationCalculateMultiplier(void)
{
ULO multiplier = 12;
@@ -144,65 +141,25 @@ ULO cpuIntegrationGetChipSlowdown(void)
return cpu_integration_chip_slowdown;
}
-ULO cpuIntegrationGetChipIrqToIntLevel(ULO chip_irq)
+void cpuIntegrationSetChipInterruptNumber(ULO chip_interrupt_number)
{
- return cpu_integration_int_to_level[chip_irq];
+ cpu_integration_chip_interrupt_number = chip_interrupt_number;
}
-void cpuIntegrationSetIrqSource(ULO irq_source)
+ULO cpuIntegrationGetChipInterruptNumber(void)
{
- cpu_integration_irq_source = irq_source;
+ return cpu_integration_chip_interrupt_number;
}
-ULO cpuIntegrationGetIrqSource(void)
+// A wrapper for cpuSetIrqLevel that restarts the
+// scheduling of cpu events if the cpu was stoppped
+void cpuIntegrationSetIrqLevel(ULO new_interrupt_level, ULO chip_interrupt_number)
{
- return cpu_integration_irq_source;
-}
-
-/*=====================================================
- Checking for waiting interrupts
- =====================================================*/
-
-static BOOLE cpuIntegrationCheckPendingInterruptsFunc(void)
-{
- ULO current_cpu_level = (cpuGetSR() >> 8) & 7;
- BOOLE chip_irqs_enabled = !!(intena & 0x4000);
-
- if (chip_irqs_enabled)
+ if (cpuSetIrqLevel(new_interrupt_level))
{
- LON highest_chip_irq;
- ULO chip_irqs = intreq & intena;
-
- if (chip_irqs == 0) return FALSE;
-
- for (highest_chip_irq = 13; highest_chip_irq >= 0; highest_chip_irq--)
- {
- if (chip_irqs & (1 << highest_chip_irq))
- {
- // Found a chip-irq that is both flagged and enabled.
- ULO highest_chip_level = cpuIntegrationGetChipIrqToIntLevel(highest_chip_irq);
- if (highest_chip_level > current_cpu_level)
- {
- cpuSetIrqLevel(highest_chip_level);
- cpuSetIrqAddress(memoryReadLong(cpuGetVbr() + 0x60 + highest_chip_level*4));
- cpuIntegrationSetIrqSource(highest_chip_irq);
-
- if (cpuGetStop())
- {
- cpuSetStop(FALSE);
- cpuEvent.cycle = bus.cycle;
- }
- return TRUE;
- }
- }
- }
+ cpuEvent.cycle = busGetCycle();
}
- return FALSE;
-}
-
-void cpuIntegrationCheckPendingInterrupts(void)
-{
- cpuCheckPendingInterrupts();
+ cpuIntegrationSetChipInterruptNumber(chip_interrupt_number);
}
/*=========================================*/
@@ -244,7 +201,7 @@ void cpuInstructionLogOpen(void)
void cpuIntegrationPrintBusCycle(void)
{
- fprintf(CPUINSTRUCTIONLOG, "%d:%.5d ", bus.frame_no, bus.cycle);
+ fprintf(CPUINSTRUCTIONLOG, "%I64u:%.5u ", bus.frame_no, bus.cycle);
}
void cpuIntegrationInstructionLogging(void)
@@ -293,37 +250,13 @@ void cpuIntegrationExceptionLogging(STR *description, ULO original_pc, UWO opcod
fprintf(CPUINSTRUCTIONLOG, "%s for opcode %.4X at PC %.8X from PC %.8X\n", description, opcode, original_pc, cpuGetPC());
}
-STR *cpuIntegrationGetInterruptName(ULO chip_irq_no)
-{
- switch (chip_irq_no)
- {
- case 0: return "TBE: Output buffer of the serial port is empty.";
- case 1: return "DSKBLK: Disk DMA transfer ended.";
- case 2: return "SOFT: Software interrupt.";
- case 3: return "PORTS: From CIA-A or expansion port.";
- case 4: return "COPER: Copper interrupt.";
- case 5: return "VERTB: Start of vertical blank.";
- case 6: return "BLIT: Blitter done.";
- case 7: return "AUD0: Audio data on channel 0.";
- case 8: return "AUD1: Audio data on channel 1.";
- case 9: return "AUD2: Audio data on channel 2.";
- case 10: return "AUD3: Audio data on channel 3.";
- case 11: return "RBF: Input buffer of the serial port full.";
- case 12: return "DSKSYN: Disk sync value recognized.";
- case 13: return "EXTER: From CIA-B or expansion port.";
- case 14: return "INTEN: BUG! Not an interrupt.";
- case 15: return "NMI: BUG! Not an interrupt.";
- }
- return "Illegal interrupt source!";
-}
-
void cpuIntegrationInterruptLogging(ULO level, ULO vector_address)
{
if (cpu_disable_instruction_log) return;
cpuInstructionLogOpen();
cpuIntegrationPrintBusCycle();
- fprintf(CPUINSTRUCTIONLOG, "Irq %d to %.6X (%s)\n", level, vector_address, cpuIntegrationGetInterruptName(cpuIntegrationGetIrqSource()));
+ fprintf(CPUINSTRUCTIONLOG, "Irq %u to %.6X (%s)\n", level, vector_address, interruptGetInterruptName(cpuIntegrationGetChipInterruptNumber()));
}
#endif
@@ -396,7 +329,7 @@ void cpuIntegrationSetDefaultConfig(void)
cpuIntegrationSetChipSlowdown(1);
cpuIntegrationSetSpeed(4);
- cpuSetCheckPendingInterruptsFunc(cpuIntegrationCheckPendingInterruptsFunc);
+ cpuSetCheckPendingInterruptsFunc(interruptRaisePending);
cpuSetMidInstructionExceptionFunc(cpuIntegrationMidInstructionExceptionFunc);
cpuSetResetExceptionFunc(cpuIntegrationResetExceptionFunc);
diff --git a/cpu/CpuModule.c b/cpu/CpuModule.c
index db33e59..b2bfa06 100644
--- a/cpu/CpuModule.c
+++ b/cpu/CpuModule.c
@@ -1,4 +1,4 @@
-/* @(#) $Id: CpuModule.c,v 1.7 2012/08/12 16:51:02 peschau Exp $ */
+/* @(#) $Id: CpuModule.c,v 1.7 2012-08-12 16:51:02 peschau Exp $ */
/*=========================================================================*/
/* Fellow */
/* Initialization of 68000 core */
@@ -48,7 +48,7 @@ void cpuClearEverything(void)
cpuSetSfc(0);
cpuSetDfc(0);
cpuSetIrqLevel(0);
- cpuSetIrqAddress(0);
+ cpuSetRaiseInterrupt(FALSE);
cpuSetStop(FALSE);
cpuSetInstructionTime(0);
cpuSetOriginalPC(0);
diff --git a/cpu/CpuModule.h b/cpu/CpuModule.h
index 2d3e956..52035c8 100644
--- a/cpu/CpuModule.h
+++ b/cpu/CpuModule.h
@@ -18,7 +18,7 @@ extern void cpuSetFLineExceptionFunc(cpuLineExceptionFunc func);
typedef BOOLE (*cpuCheckPendingInterruptsFunc)(void);
extern void cpuSetCheckPendingInterruptsFunc(cpuCheckPendingInterruptsFunc func);
extern void cpuCheckPendingInterrupts(void);
-extern void cpuSetUpInterrupt(void);
+void cpuSetUpInterrupt(ULO new_interrupt_level);
extern void cpuInitializeFromNewPC(ULO new_pc);
@@ -77,7 +77,7 @@ extern ULO cpuGetInitialSP(void);
extern ULO cpuGetInstructionTime(void);
-extern void cpuSetIrqLevel(ULO irq_level);
+extern BOOLE cpuSetIrqLevel(ULO new_interrupt_level);
extern ULO cpuGetIrqLevel(void);
extern void cpuSetIrqAddress(ULO irq_address);
diff --git a/cpu/CpuModule_Disassembler.c b/cpu/CpuModule_Disassembler.c
index a176802..01df00d 100644
--- a/cpu/CpuModule_Disassembler.c
+++ b/cpu/CpuModule_Disassembler.c
@@ -150,7 +150,7 @@ static ULO cpuDis05(ULO regno, ULO pcp, STR *sdata, STR *soperands)
ULO disp = memoryReadWord(pcp);
cpuDisWordAppend(disp, sdata);
- sprintf(cpuDisEoS(soperands), "$%.4X(A%1d)", disp, regno);
+ sprintf(cpuDisEoS(soperands), "$%.4X(A%1u)", disp, regno);
return pcp + 2;
}
@@ -168,22 +168,22 @@ static ULO cpuDis06Brief(ULO regno, ULO pcp, ULO ext, BOOLE is_pc_indirect, STR
{
if (!is_pc_indirect)
{
- sprintf(cpuDisEoS(soperands), "$%.2X(A%1d,%c%1d.%c)", offset, regno, indexregtype, indexregno, indexsize);
+ sprintf(cpuDisEoS(soperands), "$%.2X(A%1u,%c%1u.%c)", offset, regno, indexregtype, indexregno, indexsize);
}
else
{
- sprintf(cpuDisEoS(soperands), "$%.2X(PC,%c%1d.%c)", offset, indexregtype, indexregno, indexsize);
+ sprintf(cpuDisEoS(soperands), "$%.2X(PC,%c%1u.%c)", offset, indexregtype, indexregno, indexsize);
}
}
else
{
if (!is_pc_indirect)
{
- sprintf(cpuDisEoS(soperands), "$%.2X(A%1d,%c%1d.%c%s)", offset, regno, indexregtype, indexregno, indexsize, scale[scalefactor]);
+ sprintf(cpuDisEoS(soperands), "$%.2X(A%1u,%c%1u.%c%s)", offset, regno, indexregtype, indexregno, indexsize, scale[scalefactor]);
}
else
{
- sprintf(cpuDisEoS(soperands), "$%.2X(PC,%c%1d.%c%s)", offset, indexregtype, indexregno, indexsize, scale[scalefactor]);
+ sprintf(cpuDisEoS(soperands), "$%.2X(PC,%c%1u.%c%s)", offset, indexregtype, indexregno, indexsize, scale[scalefactor]);
}
}
return pcp;
@@ -250,7 +250,7 @@ static ULO cpuDis06Extended(ULO regno, ULO pcp, ULO ext, BOOLE is_pc_indirect, S
}
else
{
- sprintf(baseregstr, "A%d", regno);
+ sprintf(baseregstr, "A%u", regno);
}
}
@@ -262,7 +262,7 @@ static ULO cpuDis06Extended(ULO regno, ULO pcp, ULO ext, BOOLE is_pc_indirect, S
}
else
{ /* Index included */
- sprintf(indexstr, "%c%d.%c%s", indexregtype, indexregno, indexsize, scale[scalefactor]);
+ sprintf(indexstr, "%c%u.%c%s", indexregtype, indexregno, indexsize, scale[scalefactor]);
}
/* Base displacement */
@@ -373,11 +373,9 @@ static ULO cpuDis71(ULO pcp, STR *sdata, STR *soperands)
static ULO cpuDis72(ULO pcp, STR *sdata, STR *soperands)
{
ULO disp = memoryReadWord(pcp);
- ULO ea = pcp + disp;
- if (disp & 0x8000) ea += 0xffff0000;
cpuDisWordAppend(disp, sdata);
- sprintf(cpuDisEoS(soperands), "$%.4X ; $%.4X(PC)", ea, disp);
+ sprintf(cpuDisEoS(soperands), "$%.4X(PC)", disp);
return pcp + 2;
}
@@ -563,7 +561,7 @@ static ULO cpuDisArith4(ULO prc, UWO opc, ULO nr, STR *sdata, STR *sinstruction,
imm = 8;
}
sprintf(sinstruction, "%sQ.%c", cpu_dis_anr[nr], cpuDisSizeChar(size));
- sprintf(soperands, "#$%.1d,", imm);
+ sprintf(soperands, "#$%.1u,", imm);
return cpuDisAdrMode(eamode, eareg, prc + 2, size, sdata, soperands);
}
@@ -619,12 +617,12 @@ static ULO cpuDisShift(ULO prc, UWO opc, ULO nr, STR *sdata, STR *sinstruction,
dreg = 8;
}
sprintf(sinstruction, "%s%c.%c", cpu_dis_shnr[nr], rl, sc);
- sprintf(soperands, "#$%1X,D%1d", dreg, eareg);
+ sprintf(soperands, "#$%1X,D%1u", dreg, eareg);
}
else
{
sprintf(sinstruction, "%s%c.%c", cpu_dis_shnr[nr], rl, sc);
- sprintf(soperands, "D%1d,D%1d", dreg, eareg);
+ sprintf(soperands, "D%1u,D%1u", dreg, eareg);
}
prc += 2;
}
@@ -815,7 +813,7 @@ static ULO cpuDisDBcc(ULO prc, UWO opc, STR *sdata, STR *sinstruction, STR *sope
adr = (offset > 32767) ? (prc + offset - 65536) : (prc + offset);
cpuDisWordAppend(offset, sdata);
sprintf(sinstruction, "DB%s", (bratype == 0) ? "T" : ((bratype == 1) ? "F" : cpu_dis_btab[bratype]));
- sprintf(soperands, "D%1d,$%6.6X", cpuDisGetSourceRegister(opc), adr);
+ sprintf(soperands, "D%1u,$%6.6X", cpuDisGetSourceRegister(opc), adr);
return prc + 2;
}
@@ -851,7 +849,7 @@ static ULO cpuDisExg(ULO prc, UWO opc, STR *sdata, STR *sinstruction, STR *soper
static ULO cpuDisExt(ULO prc, UWO opc, STR *sdata, STR *sinstruction, STR *soperands)
{
sprintf(sinstruction, "EXT.%c", (cpuDisGetBit(opc, 6) == 0) ? 'W' : 'L');
- sprintf(soperands, "D%d", cpuDisGetSourceRegister(opc));
+ sprintf(soperands, "D%u", cpuDisGetSourceRegister(opc));
return prc + 2;
}
@@ -876,7 +874,7 @@ static ULO cpuDisLink(ULO prc, UWO opc, STR *sdata, STR *sinstruction, STR *sope
cpuDisWordAppend(imm, sdata);
sprintf(sinstruction, "LINK");
- sprintf(soperands, "A%1d,#$%.4X", cpuDisGetSourceRegister(opc), imm);
+ sprintf(soperands, "A%1u,#$%.4X", cpuDisGetSourceRegister(opc), imm);
return prc + 4;
}
@@ -1025,11 +1023,11 @@ static ULO cpuDisMovep(ULO prc, UWO opc, STR *sdata, STR *sinstruction, STR *sop
sprintf(sinstruction, "MOVEP.%c", sizech);
if (to_mem)
{
- sprintf(soperands, "D%1d,$%.4X(A%d)", dataregno, disp, adrregno);
+ sprintf(soperands, "D%1u,$%.4X(A%1u)", dataregno, disp, adrregno);
}
else
{
- sprintf(soperands, "$%.4X(A%1d),D%1d,", disp, adrregno, dataregno);
+ sprintf(soperands, "$%.4X(A%1u),D%1u", disp, adrregno, dataregno);
}
return prc + 4;
}
@@ -1037,7 +1035,7 @@ static ULO cpuDisMovep(ULO prc, UWO opc, STR *sdata, STR *sinstruction, STR *sop
static ULO cpuDisMoveq(ULO prc, UWO opc, STR *sdata, STR *sinstruction, STR *soperands)
{
sprintf(sinstruction, "MOVEQ.L");
- sprintf(soperands, "#$%8.8X,D%d", cpuDisGetLowByteSignExtend(opc), cpuDisGetDestinationRegister(opc));
+ sprintf(soperands, "#$%8.8X,D%u", cpuDisGetLowByteSignExtend(opc), cpuDisGetDestinationRegister(opc));
return prc + 2;
}
@@ -1224,31 +1222,31 @@ static ULO cpuDisBf(ULO prc, UWO opc, STR *sdata, STR *sinstruction, STR *sopera
sprintf(sinstruction, "BF%s", cpu_dis_bftxt[n]);
if (n == 7)
{
- sprintf(stmp, "D%d,", (ext >> 12) & 7);
+ sprintf(stmp, "D%u,", (ext >> 12) & 7);
strcat(soperands, stmp);
}
prc = cpuDisAdrMode(eamode, eareg, prc + 4, 16, sdata, soperands);
if (ext & 0x800)
{
- sprintf(stmp, "{D%d:", offset & 7);
+ sprintf(stmp, "{D%u:", offset & 7);
}
else
{
- sprintf(stmp, "{%d:", offset);
+ sprintf(stmp, "{%u:", offset);
}
strcat(soperands, stmp);
if (ext & 0x20)
{
- sprintf(stmp, "D%d}", width & 7);
+ sprintf(stmp, "D%u}", width & 7);
}
else
{
- sprintf(stmp, "%d}", width);
+ sprintf(stmp, "%u}", width);
}
strcat(soperands, stmp);
if ((n == 1) || (n == 3) || (n == 7))
{
- sprintf(stmp, ",D%d", (ext >> 12) & 7);
+ sprintf(stmp, ",D%u", (ext >> 12) & 7);
strcat(soperands, stmp);
}
return prc;
@@ -1268,7 +1266,7 @@ static ULO cpuDisCas(ULO prc, UWO opc, STR *sdata, STR *sinstruction, STR *soper
sprintf(sinstruction, "CAS2.%c", cpuDisSizeChar(size));
sprintf(soperands,
- "D%d:D%d,D%d:D%d,(%s%d):(%s%d)",
+ "D%u:D%u,D%u:D%u,(%s%u):(%s%u)",
ext & 7,
ext2 & 7,
(ext >> 6) & 7,
@@ -1282,7 +1280,7 @@ static ULO cpuDisCas(ULO prc, UWO opc, STR *sdata, STR *sinstruction, STR *soper
else
{
sprintf(sinstruction, "CAS.%c", cpuDisSizeChar(size));
- sprintf(soperands, "D%d,D%d,", ext & 7, (ext >> 6) & 7);
+ sprintf(soperands, "D%u,D%u,", ext & 7, (ext >> 6) & 7);
prc = cpuDisAdrMode(cpuDisGetEaNo(cpuDisGetSourceMode(opc), eareg), eareg, prc + 4, size, sdata, soperands);
}
return prc;
@@ -1308,7 +1306,7 @@ static ULO cpuDisChk2(ULO prc, UWO opc, STR *sdata, STR *sinstruction, STR *sope
cpuDisWordAppend(ext, sdata);
sprintf(sinstruction, "%s.%c", (ext & 0x800) ? "CHK2" : "CMP2", cpuDisSizeChar(size));
prc = cpuDisAdrMode(cpuDisGetEaNo(cpuDisGetSourceMode(opc), eareg), eareg, prc + 4, size, sdata, soperands);
- sprintf(stmp, ",%s%d", (ext & 0x8000) ? "A" : "D", (ext>>12) & 7);
+ sprintf(stmp, ",%s%u", (ext & 0x8000) ? "A" : "D", (ext>>12) & 7);
strcat(soperands, stmp);
return prc;
}
@@ -1328,11 +1326,11 @@ static ULO cpuDisDivl(ULO prc, UWO opc, STR *sdata, STR *sinstruction, STR *sope
prc = cpuDisAdrMode(cpuDisGetEaNo(cpuDisGetSourceMode(opc), eareg), eareg, prc + 4, 32, sdata, soperands);
if (ext & 0x400)
{
- sprintf(stmp, ",D%d:D%d", dr, dq);
+ sprintf(stmp, ",D%u:D%u", dr, dq);
}
else
{
- sprintf(stmp, ",D%d", dq);
+ sprintf(stmp, ",D%u", dq);
}
strcat(soperands, stmp);
return prc;
@@ -1341,7 +1339,7 @@ static ULO cpuDisDivl(ULO prc, UWO opc, STR *sdata, STR *sinstruction, STR *sope
static ULO cpuDisExtb(ULO prc, UWO opc, STR *sdata, STR *sinstruction, STR *soperands)
{
sprintf(sinstruction, "EXTB.L");
- sprintf(soperands, "D%d", cpuDisGetSourceRegister(opc));
+ sprintf(soperands, "D%u", cpuDisGetSourceRegister(opc));
return prc + 2;
}
@@ -1350,7 +1348,7 @@ static ULO cpuDisLinkl(ULO prc, UWO opc, STR *sdata, STR *sinstruction, STR *sop
ULO disp = memoryReadLong(prc + 2);
cpuDisLongAppend(disp, sdata);
sprintf(sinstruction, "LINK.L");
- sprintf(soperands, "A%d, #$%.8X", cpuDisGetSourceRegister(opc), disp);
+ sprintf(soperands, "A%u, #$%.8X", cpuDisGetSourceRegister(opc), disp);
return prc + 6;
}
@@ -1372,7 +1370,7 @@ static ULO cpuDisMovec(ULO prc, UWO opc, STR *sdata, STR *sinstruction, STR *sop
sprintf(sinstruction, "MOVEC.L");
if (opc & 1)
{ /* To control register */
- sprintf(stmp, "%s%d,", (extw & 0x8000) ? "A" : "D", (extw>>12) & 7);
+ sprintf(stmp, "%s%u,", (extw & 0x8000) ? "A" : "D", (extw>>12) & 7);
strcat(soperands, stmp);
}
creg = extw & 0xfff;
@@ -1410,7 +1408,7 @@ static ULO cpuDisMovec(ULO prc, UWO opc, STR *sdata, STR *sinstruction, STR *sop
}
if (!(opc & 1))
{ /* From control register */
- sprintf(stmp, ",%s%d", (extw & 0x8000) ? "A":"D", (extw >> 12) & 7);
+ sprintf(stmp, ",%s%u", (extw & 0x8000) ? "A":"D", (extw >> 12) & 7);
strcat(soperands, stmp);
}
return prc + 4;
@@ -1427,13 +1425,13 @@ static ULO cpuDisMoves(ULO prc, UWO opc, STR *sdata, STR *sinstruction, STR *sop
sprintf(sinstruction, "MOVES.%c", cpuDisSizeChar(size));
if (ext & 0x800)
{
- sprintf(stmp, "%s%d,", (ext & 0x8000) ? "A" : "D", (ext >> 12) & 7);
+ sprintf(stmp, "%s%u,", (ext & 0x8000) ? "A" : "D", (ext >> 12) & 7);
strcat(soperands, stmp);
}
prc = cpuDisAdrMode(cpuDisGetEaNo(cpuDisGetSourceMode(opc), eareg), eareg, prc + 4, size, sdata, soperands);
if (!(ext & 0x800))
{
- sprintf(stmp, ",%s%d", (ext & 0x8000) ? "A" : "D", (ext >> 12) & 7);
+ sprintf(stmp, ",%s%u", (ext & 0x8000) ? "A" : "D", (ext >> 12) & 7);
strcat(soperands, stmp);
}
return prc;
@@ -1454,11 +1452,11 @@ static ULO cpuDisMull(ULO prc, UWO opc, STR *sdata, STR *sinstruction, STR *sope
prc = cpuDisAdrMode(cpuDisGetEaNo(cpuDisGetSourceMode(opc), eareg), eareg, prc + 4, 32, sdata, soperands);
if (ext & 0x400)
{
- sprintf(stmp, ",D%d:D%d", dh, dl);
+ sprintf(stmp, ",D%u:D%u", dh, dl);
}
else
{
- sprintf(stmp, ",D%d", dl);
+ sprintf(stmp, ",D%u", dl);
}
strcat(soperands, stmp);
return prc;
@@ -1491,12 +1489,12 @@ static void cpuDisPflush030PrintFc(STR *soperands, ULO fcode)
else if (fcode == 1) strcat(soperands, "DFC,");
else if ((fcode & 0x18) == 8)
{
- sprintf(stmp, "D%d,", fcode & 7);
+ sprintf(stmp, "D%u,", fcode & 7);
strcat(soperands, stmp);
}
else if ((fcode & 0x18) == 0x10)
{
- sprintf(stmp, "#%d,", fcode & 7);
+ sprintf(stmp, "#%u,", fcode & 7);
strcat(soperands, stmp);
}
}
@@ -1566,11 +1564,11 @@ static ULO cpuDisPflush040(ULO prc, UWO opc, STR *sdata, STR *sinstruction, STR
{
case 0:
sprintf(sinstruction, "PFLUSHN");
- sprintf(soperands, "(A%d)", reg);
+ sprintf(soperands, "(A%u)", reg);
break;
case 1:
sprintf(sinstruction, "PFLUSH");
- sprintf(soperands, "(A%d)", reg);
+ sprintf(soperands, "(A%u)", reg);
break;
case 2:
sprintf(sinstruction, "PFLUSHAN");
@@ -1590,7 +1588,7 @@ static ULO cpuDisPtest040(ULO prc, UWO opc, STR *sdata, STR *sinstruction, STR *
ULO rw = cpuDisGetBit(opc, 5);
sprintf(sinstruction, "PTEST%c", (rw) ? 'R' : 'W');
- sprintf(soperands, "(A%d)", reg);
+ sprintf(soperands, "(A%u)", reg);
return prc + 2;
}
@@ -1652,14 +1650,14 @@ static ULO cpuDisCallm(ULO prc, UWO opc, STR *sdata, STR *sinstruction, STR *sop
ULO eareg = cpuDisGetSourceRegister(opc);
ULO ext = memoryReadWord(prc + 2);
cpuDisWordAppend(ext, sdata);
- sprintf(soperands, "#%d,", ext & 0xff);
+ sprintf(soperands, "#%u,", ext & 0xff);
return cpuDisAdrMode(cpuDisGetEaNo(cpuDisGetSourceMode(opc), eareg), eareg, prc + 4, 16, sdata, soperands);
}
static ULO cpuDisRtm(ULO prc, UWO opc, STR *sdata, STR *sinstruction, STR *soperands)
{
sprintf(sinstruction, "RTM");
- sprintf(soperands, "%c%d", (opc & 8) ? 'A':'D', cpuDisGetSourceRegister(opc));
+ sprintf(soperands, "%c%u", (opc & 8) ? 'A':'D', cpuDisGetSourceRegister(opc));
return prc + 2;
}
diff --git a/cpu/CpuModule_EffectiveAddress.c b/cpu/CpuModule_EffectiveAddress.c
index 2f4ae64..e40331f 100644
--- a/cpu/CpuModule_EffectiveAddress.c
+++ b/cpu/CpuModule_EffectiveAddress.c
@@ -1,4 +1,4 @@
-/* @(#) $Id: CpuModule_EffectiveAddress.c,v 1.3 2012/07/15 22:20:35 peschau Exp $ */
+/* @(#) $Id: CpuModule_EffectiveAddress.c,v 1.3 2012-07-15 22:20:35 peschau Exp $ */
/*=========================================================================*/
/* Fellow */
/* CPU 68k effective address calculation functions */
diff --git a/cpu/CpuModule_Exceptions.c b/cpu/CpuModule_Exceptions.c
index b2d803d..eda203e 100644
--- a/cpu/CpuModule_Exceptions.c
+++ b/cpu/CpuModule_Exceptions.c
@@ -1,4 +1,4 @@
-/* @(#) $Id: CpuModule_Exceptions.c,v 1.5 2012/08/12 16:51:02 peschau Exp $ */
+/* @(#) $Id: CpuModule_Exceptions.c,v 1.5 2012-08-12 16:51:02 peschau Exp $ */
/*=========================================================================*/
/* Fellow */
/* CPU 68k exception handling functions */
@@ -94,26 +94,54 @@ static STR *cpuGetExceptionName(ULO vector_offset)
Sets up an exception
===============================================*/
+void cpuExceptionFail(BOOLE executejmp)
+{
+ // Avoid endless loop that will crash the emulator.
+ // The (odd) address error exception vector contained an odd address.
+ cpuCallResetExceptionFunc();
+ cpuHardReset();
+ cpuSetInstructionTime(132);
+ if (executejmp)
+ {
+ cpuCallMidInstructionExceptionFunc(); // Supposed to be doing setjmp/longjmp back to machine emulator code
+ }
+}
+
void cpuThrowException(ULO vector_offset, ULO pc, BOOLE executejmp)
{
ULO vector_address;
+ BOOLE is_address_error_on_sub_020 = (cpuGetModelMajor() < 2 && vector_offset == 0xc);
+ BOOLE stack_is_even = !(cpuGetAReg(7) & 1);
+ BOOLE vbr_is_even = !(cpuGetVbr() & 1);
+
+ if ((is_address_error_on_sub_020 && !stack_is_even) || !vbr_is_even)
+ {
+ cpuExceptionFail(executejmp);
+ return;
+ }
#ifdef CPU_INSTRUCTION_LOGGING
cpuCallExceptionLoggingFunc(cpuGetExceptionName(vector_offset), cpuGetOriginalPC(), cpuGetCurrentOpcode());
#endif
- cpuActivateSSP();
+ cpuActivateSSP();
+
+ stack_is_even = !(cpuGetAReg(7) & 1);
+
+ if (is_address_error_on_sub_020 && !stack_is_even)
+ {
+ cpuExceptionFail(executejmp);
+ return;
+ }
+
cpuStackFrameGenerate((UWO) vector_offset, pc);
// read a memory position
vector_address = memoryReadLong(cpuGetVbr() + vector_offset);
- if (cpuGetModelMajor() < 2 && vector_address & 0x1 && vector_offset == 0xc)
+ if (is_address_error_on_sub_020 && vector_address & 1)
{
- // Avoid endless loop that will crash the emulator.
- // The (odd) address error exception vector contained an odd address.
- cpuCallResetExceptionFunc();
- cpuHardReset();
- cpuSetInstructionTime(132);
+ cpuExceptionFail(executejmp);
+ return;
}
else
{
@@ -192,7 +220,7 @@ void cpuThrowTraceException(void)
void cpuThrowAddressErrorException(void)
{
- cpuThrowException(0xc, cpuGetPC(), TRUE);
+ cpuThrowException(0xc, cpuGetPC() - 2, TRUE);
}
/*=================*/
diff --git a/cpu/CpuModule_Flags.c b/cpu/CpuModule_Flags.c
index f1859e2..aaca6b9 100644
--- a/cpu/CpuModule_Flags.c
+++ b/cpu/CpuModule_Flags.c
@@ -1,4 +1,4 @@
-/* @(#) $Id: CpuModule_Flags.c,v 1.3 2011/07/18 17:22:55 peschau Exp $ */
+/* @(#) $Id: CpuModule_Flags.c,v 1.3 2011-07-18 17:22:55 peschau Exp $ */
/*=========================================================================*/
/* Fellow */
/* 68000 flag and condition code handling */
diff --git a/cpu/CpuModule_Instructions.c b/cpu/CpuModule_Instructions.c
index 2d4101b..0a9e178 100644
--- a/cpu/CpuModule_Instructions.c
+++ b/cpu/CpuModule_Instructions.c
@@ -1,4 +1,4 @@
-/* @(#) $Id: CpuModule_Instructions.c,v 1.12 2013/01/08 18:55:48 peschau Exp $ */
+/* @(#) $Id: CpuModule_Instructions.c,v 1.12 2013-01-08 18:55:48 peschau Exp $ */
/*=========================================================================*/
/* Fellow */
/* CPU 68k functions */
@@ -105,40 +105,55 @@ static __inline void cpuTscAfter(LLO* a, LLO* b, ULO* c)
/* Maintains the integrity of the super/user state */
-void cpuUpdateSr(ULO new_sr) {
- BOOLE supermode_was_set = cpuGetFlagSupervisor();
- BOOLE master_was_set = (cpuGetModelMajor() >= 2) && cpuGetFlagMaster();
+void cpuUpdateSr(ULO new_sr)
+{
+ BOOLE supermode_was_set = cpuGetFlagSupervisor();
+ BOOLE master_was_set = (cpuGetModelMajor() >= 2) && cpuGetFlagMaster();
- BOOLE supermode_is_set = !!(new_sr & 0x2000);
- BOOLE master_is_set = (cpuGetModelMajor() >= 2) && !!(new_sr & 0x1000);
+ BOOLE supermode_is_set = !!(new_sr & 0x2000);
+ BOOLE master_is_set = (cpuGetModelMajor() >= 2) && !!(new_sr & 0x1000);
- ULO runlevel_old = (cpuGetSR() >> 8) & 7;
- ULO runlevel_new = (new_sr >> 8) & 7;
+ ULO runlevel_old = (cpuGetSR() >> 8) & 7;
+ ULO runlevel_new = (new_sr >> 8) & 7;
- if (!supermode_was_set)
- cpuSetUspDirect(cpuGetAReg(7));
- else if (master_was_set)
- cpuSetMspDirect(cpuGetAReg(7));
- else
- cpuSetSspDirect(cpuGetAReg(7));
+ if (!supermode_was_set)
+ {
+ cpuSetUspDirect(cpuGetAReg(7));
+ }
+ else if (master_was_set)
+ {
+ cpuSetMspDirect(cpuGetAReg(7));
+ }
+ else
+ {
+ cpuSetSspDirect(cpuGetAReg(7));
+ }
- if (!supermode_is_set)
- cpuSetAReg(7, cpuGetUspDirect());
- else if (master_is_set)
- cpuSetAReg(7, cpuGetMspDirect());
- else
- cpuSetAReg(7, cpuGetSspDirect());
+ if (!supermode_is_set)
+ {
+ cpuSetAReg(7, cpuGetUspDirect());
+ }
+ else if (master_is_set)
+ {
+ cpuSetAReg(7, cpuGetMspDirect());
+ }
+ else
+ {
+ cpuSetAReg(7, cpuGetSspDirect());
+ }
- cpuSetSR(new_sr);
+ cpuSetSR(new_sr);
- if (runlevel_old != runlevel_new) {
- cpuCallCheckPendingInterruptsFunc();
- }
+ if (runlevel_old != runlevel_new)
+ {
+ cpuCheckPendingInterrupts();
+ }
}
-static void cpuIllegal(void) {
- UWO opcode = memoryReadWord(cpuGetPC() - 2);
- if ((opcode & 0xf000) == 0xf000)
+static void cpuIllegal(void)
+{
+ UWO opcode = memoryReadWord(cpuGetPC() - 2);
+ if ((opcode & 0xf000) == 0xf000)
{
if (cpu_f_line_exception_func)
{
@@ -148,8 +163,8 @@ static void cpuIllegal(void) {
}
else
{
- cpuThrowFLineException();
- }
+ cpuThrowFLineException();
+ }
}
else if ((opcode & 0xa000) == 0xa000)
{
@@ -1059,9 +1074,9 @@ static void cpuMulL(ULO src1, UWO extension)
{
BOOLE o;
if (result >= 0)
- o = (result & 0xffffffff00000000) != 0;
+ o = (result & 0xffffffff00000000) != 0;
else
- o = (result & 0xffffffff00000000) != 0xffffffff00000000;
+ o = (result & 0xffffffff00000000) != 0xffffffff00000000;
cpuSetDReg(dl, (ULO)result);
cpuSetFlagsNZVC(result == 0, result < 0, o, FALSE);
}
@@ -1079,7 +1094,7 @@ static void cpuMulL(ULO src1, UWO extension)
else // 32bx32b=32b
{
cpuSetDReg(dl, (ULO)result);
- cpuSetFlagsNZVC(result == 0, !!(result & 0x8000000000000000), (result >> 32) != 0, FALSE);
+ cpuSetFlagsNZVC(result == 0, !!(result & 0x80000000), (result >> 32) != 0, FALSE);
}
}
cpuSetInstructionTime(4);
@@ -1097,7 +1112,7 @@ void cpuCreateMuluTimeTable(void)
j = 0;
for (k = 0; k < 8; k++)
if (((i>>k) & 1) == 1)
- j++;
+ j++;
cpuMuluTime[i] = (UBY) j*2;
}
}
@@ -1111,7 +1126,7 @@ void cpuCreateMulsTimeTable(void)
j = 0;
for (k = 0; k < 9; k++)
if ((((i>>k) & 3) == 1) || (((i>>k) & 3) == 2))
- j++;
+ j++;
cpuMulsTime[i] = (UBY) j*2;
}
}
@@ -1229,15 +1244,15 @@ static void cpuDivL(ULO divisor, ULO ext)
if (y_signed < 0)
{
- y = (ULL) -y_signed;
- resultsigned = !resultsigned;
+ y = (ULL) -y_signed;
+ resultsigned = !resultsigned;
}
else y = y_signed;
if (x_signed < 0)
{
- x = (ULL) -x_signed;
- resultsigned = !resultsigned;
- restsigned = TRUE;
+ x = (ULL) -x_signed;
+ resultsigned = !resultsigned;
+ restsigned = TRUE;
}
else x = (ULL) x_signed;
}
@@ -1255,30 +1270,30 @@ static void cpuDivL(ULO divisor, ULO ext)
{
if ((resultsigned && result > 0x80000000) || (!resultsigned && result > 0x7fffffff))
{
- /* Overflow */
- cpuSetFlagsVC(TRUE, FALSE);
+ /* Overflow */
+ cpuSetFlagsVC(TRUE, FALSE);
}
else
{
- LLO result_signed = (resultsigned) ? (-(LLO)result) : ((LLO)result);
- LLO rest_signed = (restsigned) ? (-(LLO)rest) : ((LLO)rest);
- cpuSetDReg(dr_reg, (ULO) rest_signed);
- cpuSetDReg(dq_reg, (ULO) result_signed);
- cpuSetFlagsNZ00NewL((ULO) result_signed);
+ LLO result_signed = (resultsigned) ? (-(LLO)result) : ((LLO)result);
+ LLO rest_signed = (restsigned) ? (-(LLO)rest) : ((LLO)rest);
+ cpuSetDReg(dr_reg, (ULO) rest_signed);
+ cpuSetDReg(dq_reg, (ULO) result_signed);
+ cpuSetFlagsNZ00NewL((ULO) result_signed);
}
}
else
{
if (result > 0xffffffff)
{
- /* Overflow */
- cpuSetFlagsVC(TRUE, FALSE);
+ /* Overflow */
+ cpuSetFlagsVC(TRUE, FALSE);
}
else
{
- cpuSetDReg(dr_reg, (ULO) rest);
- cpuSetDReg(dq_reg, (ULO) result);
- cpuSetFlagsNZ00NewL((ULO) result);
+ cpuSetDReg(dr_reg, (ULO) rest);
+ cpuSetDReg(dq_reg, (ULO) result);
+ cpuSetFlagsNZ00NewL((ULO) result);
}
}
}
@@ -1465,10 +1480,16 @@ static UBY cpuAslB(UBY dst, ULO sh, ULO cycles)
{
UBY mask = 0xff << (7-sh);
UBY out = dst & mask;
- BOOLE n;
res = ((BYT)dst) << sh;
- n = cpuMsbB(res);
- cpuSetFlagsShift(cpuIsZeroB(res), n, dst & (0x80>>(sh-1)), (cpuMsbB(dst)) ? (out != mask) : (out != 0));
+
+ // Overflow calculation:
+ // 1. The msb of the result and original are different
+ // 2. Or the bits shifted out were not all the same as the msb of the original
+ BOOLE n_result = cpuMsbB(res);
+ BOOLE n_original = cpuMsbB(dst);
+ BOOLE msb_changed = (n_result != n_original) || ((n_original) ? (out != mask) : (out != 0));
+
+ cpuSetFlagsShift(cpuIsZeroB(res), n_result, dst & (0x80>>(sh-1)), msb_changed);
}
cpuSetInstructionTime(cycles + sh*2);
return (UBY) res;
@@ -1495,10 +1516,16 @@ static UWO cpuAslW(UWO dst, ULO sh, ULO cycles)
{
UWO mask = 0xffff << (15-sh);
UWO out = dst & mask;
- BOOLE n;
res = ((WOR)dst) << sh;
- n = cpuMsbW(res);
- cpuSetFlagsShift(cpuIsZeroW(res), n, dst & (0x8000>>(sh-1)), (cpuMsbW(dst)) ? (out != mask) : (out != 0));
+
+ // Overflow calculation:
+ // 1. The msb of the result and original are different
+ // 2. Or the bits shifted out were not all the same as the msb of the original
+ BOOLE n_result = cpuMsbW(res);
+ BOOLE n_original = cpuMsbW(dst);
+ BOOLE msb_changed = (n_result != n_original) || ((n_original) ? (out != mask) : (out != 0));
+
+ cpuSetFlagsShift(cpuIsZeroW(res), n_result, dst & (0x8000>>(sh-1)), msb_changed);
}
cpuSetInstructionTime(cycles + sh*2);
return (UWO) res;
@@ -1525,10 +1552,16 @@ static ULO cpuAslL(ULO dst, ULO sh, ULO cycles)
{
ULO mask = 0xffffffff << (31-sh);
ULO out = dst & mask;
- BOOLE n;
res = ((LON)dst) << sh;
- n = cpuMsbL(res);
- cpuSetFlagsShift(cpuIsZeroL(res), n, dst & (0x80000000>>(sh-1)), (cpuMsbL(dst)) ? (out != mask) : (out != 0));
+
+ // Overflow calculation:
+ // 1. The msb of the result and original are different
+ // 2. Or the bits shifted out were not all the same as the msb of the original
+ BOOLE n_result = cpuMsbL(res);
+ BOOLE n_original = cpuMsbL(dst);
+ BOOLE msb_changed = (n_result != n_original) || ((n_original) ? (out != mask) : (out != 0));
+
+ cpuSetFlagsShift(cpuIsZeroL(res), n_result, dst & (0x80000000>>(sh-1)), msb_changed);
}
cpuSetInstructionTime(cycles + sh*2);
return (ULO) res;
@@ -1909,9 +1942,7 @@ static void cpuReset()
static void cpuRtd()
{
ULO displacement = cpuGetNextWordSignExt();
-
- cpuInitializeFromNewPC(memoryReadLong(cpuGetAReg(7)));
-
+ cpuInitializeFromNewPC(memoryReadLong(cpuGetAReg(7)));
cpuSetAReg(7, cpuGetAReg(7) + 4 + displacement);
cpuSetInstructionTime(4);
}
@@ -1937,10 +1968,10 @@ static void cpuRte()
if (cpuGetModelMajor() > 0)
{
- ULO frame_type = (memoryReadWord(cpuGetAReg(7)) >> 12) & 0xf;
- cpuSetAReg(7, cpuGetAReg(7) + 2);
- cpuSetAReg(7, cpuGetAReg(7) + cpuRteStackInc[frame_type]);
- redo = (frame_type == 1 && cpuGetModelMajor() >= 2 && cpuGetModelMajor() < 6);
+ ULO frame_type = (memoryReadWord(cpuGetAReg(7)) >> 12) & 0xf;
+ cpuSetAReg(7, cpuGetAReg(7) + 2);
+ cpuSetAReg(7, cpuGetAReg(7) + cpuRteStackInc[frame_type]);
+ redo = (frame_type == 1 && cpuGetModelMajor() >= 2 && cpuGetModelMajor() < 6);
}
else redo = FALSE;
@@ -2093,12 +2124,12 @@ static void cpuMovemwPre(UWO regs, ULO reg)
dstea -= 2;
if (cpuGetModelMajor() >= 2 && j == reg)
{
- ea_reg_seen = TRUE;
- ea_reg_ea = dstea;
+ ea_reg_seen = TRUE;
+ ea_reg_ea = dstea;
}
else
{
- memoryWriteWord(cpuGetRegWord(i, j), dstea);
+ memoryWriteWord(cpuGetRegWord(i, j), dstea);
}
cycles += 4;
}
@@ -2145,12 +2176,12 @@ static void cpuMovemlPre(UWO regs, ULO reg)
dstea -= 4;
if (cpuGetModelMajor() >= 2 && j == reg)
{
- ea_reg_seen = TRUE;
- ea_reg_ea = dstea;
+ ea_reg_seen = TRUE;
+ ea_reg_ea = dstea;
}
else
{
- memoryWriteLong(cpuGetReg(i, j), dstea);
+ memoryWriteLong(cpuGetReg(i, j), dstea);
}
cycles += 8;
}
@@ -2194,10 +2225,10 @@ static void cpuMovemwPost(UWO regs, ULO reg)
{
if (regs & index)
{
- // Each word, for both data and address registers, is sign-extended before stored.
- cpuSetReg(i, j, (ULO)(LON)(WOR) memoryReadWord(dstea));
- dstea += 2;
- cycles += 4;
+ // Each word, for both data and address registers, is sign-extended before stored.
+ cpuSetReg(i, j, (ULO)(LON)(WOR) memoryReadWord(dstea));
+ dstea += 2;
+ cycles += 4;
}
index = index << 1;
}
@@ -2223,9 +2254,9 @@ static void cpuMovemlPost(UWO regs, ULO reg)
{
if (regs & index)
{
- cpuSetReg(i, j, memoryReadLong(dstea));
- dstea += 4;
- cycles += 8;
+ cpuSetReg(i, j, memoryReadLong(dstea));
+ dstea += 4;
+ cycles += 8;
}
index = index << 1;
}
@@ -2251,10 +2282,10 @@ static void cpuMovemwEa2R(UWO regs, ULO ea, ULO eacycles)
{
if (regs & index)
{
- // Each word, for both data and address registers, is sign-extended before stored.
- cpuSetReg(i, j, (ULO)(LON)(WOR) memoryReadWord(dstea));
- dstea += 2;
- cycles += 4;
+ // Each word, for both data and address registers, is sign-extended before stored.
+ cpuSetReg(i, j, (ULO)(LON)(WOR) memoryReadWord(dstea));
+ dstea += 2;
+ cycles += 4;
}
index = index << 1;
}
@@ -2279,9 +2310,9 @@ static void cpuMovemlEa2R(UWO regs, ULO ea, ULO eacycles)
{
if (regs & index)
{
- cpuSetReg(i, j, memoryReadLong(dstea));
- dstea += 4;
- cycles += 8;
+ cpuSetReg(i, j, memoryReadLong(dstea));
+ dstea += 4;
+ cycles += 8;
}
index = index << 1;
}
@@ -2306,9 +2337,9 @@ static void cpuMovemwR2Ea(UWO regs, ULO ea, ULO eacycles)
{
if (regs & index)
{
- memoryWriteWord(cpuGetRegWord(i, j), dstea);
- dstea += 2;
- cycles += 4;
+ memoryWriteWord(cpuGetRegWord(i, j), dstea);
+ dstea += 2;
+ cycles += 4;
}
index = index << 1;
}
@@ -2333,9 +2364,9 @@ static void cpuMovemlR2Ea(UWO regs, ULO ea, ULO eacycles)
{
if (regs & index)
{
- memoryWriteLong(cpuGetReg(i, j), dstea);
- dstea += 4;
- cycles += 8;
+ memoryWriteLong(cpuGetReg(i, j), dstea);
+ dstea += 4;
+ cycles += 8;
}
index = index << 1;
}
@@ -2622,53 +2653,38 @@ static UBY cpuNbcdB(UBY dst)
}
// Bit field functions
-static void cpuGetBfRegBytes(UBY *bytes, ULO regno)
+struct cpuBfData
{
- bytes[0] = (UBY)(cpuGetDReg(regno) >> 24);
- bytes[1] = (UBY)(cpuGetDReg(regno) >> 16);
- bytes[2] = (UBY)(cpuGetDReg(regno) >> 8);
- bytes[3] = (UBY)cpuGetDReg(regno);
-}
+ LON offset;
+ ULO width;
+ ULO normalized_offset;
-static void cpuGetBfEaBytes(UBY *bytes, ULO address, ULO count)
-{
- ULO i;
- for (i = 0; i < count; ++i)
- {
- bytes[i] = memoryReadByte(address + i);
- }
-}
+ ULO base_address;
+ LON base_address_byte_offset;
+ ULO base_address_byte_count;
-static void cpuSetBfRegBytes(UBY *bytes, ULO regno)
-{
- cpuSetDReg(regno, cpuJoinByteToLong(bytes[0], bytes[1], bytes[2], bytes[3]));
-}
+ ULO field;
+ ULL field_mask;
+ ULO dn;
+ ULL field_memory;
+};
-static void cpuSetBfEaBytes(UBY *bytes, ULO address, ULO count)
-{
- ULO i;
- for (i = 0; i < count; ++i)
- {
- memoryWriteByte(bytes[i], address + i);
- }
-}
-
-static LON cpuGetBfOffset(UWO ext, BOOLE offsetIsDr)
+static LON cpuGetBfOffset(UWO ext, bool offsetIsDataRegister)
{
LON offset = (ext >> 6) & 0x1f;
- if (offsetIsDr)
+ if (offsetIsDataRegister)
{
offset = (LON) cpuGetDReg(offset & 7);
}
return offset;
}
-static ULO cpuGetBfWidth(UWO ext, BOOLE widthIsDr)
+static ULO cpuGetBfWidth(UWO ext, bool widthIsDataRegister)
{
ULO width = (ext & 0x1f);
- if (widthIsDr)
+ if (widthIsDataRegister)
{
- width = (cpuGetDReg(width & 7) & 0x1f);
+ width = cpuGetDReg(width & 7) & 0x1f;
}
if (width == 0)
{
@@ -2677,105 +2693,90 @@ static ULO cpuGetBfWidth(UWO ext, BOOLE widthIsDr)
return width;
}
-static ULO cpuGetBfField(UBY *bytes, ULO end_offset, ULO byte_count, ULO field_mask)
+static void cpuSetBfField(struct cpuBfData *bf_data, ULO ea_or_reg, bool has_ea)
{
- ULO i;
- ULO field = ((ULO)bytes[byte_count - 1]) >> end_offset;
-
- for (i = 1; i < byte_count; i++)
- {
- field |= ((ULO)bytes[byte_count - i - 1]) << (8*i - end_offset);
- }
- return field & field_mask;
-}
-
-static void cpuSetBfField(UBY *bytes, ULO end_offset, ULO byte_count, ULO field, ULO field_mask)
-{
- ULO i;
-
- bytes[byte_count - 1] = (UBY)((field << end_offset) | (bytes[byte_count - 1] & (UBY)~(field_mask << end_offset)));
- for (i = 1; i < byte_count - 1; ++i)
- {
- bytes[byte_count - i - 1] = (UBY)(field >> (end_offset + 8*i));
- }
- if (i < byte_count)
- {
- // clang warning...
- //bytes[0] = (bytes[0] & (UBY)~(field_mask >> (end_offset + 8*i)) | (UBY)(field >> (end_offset + 8*i)));
- bytes[0] = ((bytes[0] & (UBY)~(field_mask >> (end_offset + 8*i))) | (UBY)(field >> (end_offset + 8*i)));
- }
-}
-
-struct cpuBfData
-{
- UWO ext;
- BOOLE offsetIsDr;
- BOOLE widthIsDr;
- LON offset;
- ULO width;
- ULO base_address;
- ULO bit_offset;
- ULO end_offset;
- ULO byte_count;
- ULO field;
- ULO field_mask;
- ULO dn;
- UBY b[5];
-};
-
-void cpuBfExtWord(struct cpuBfData *bf_data, ULO val, BOOLE has_dn, BOOLE has_ea, UWO ext)
-{
- bf_data->ext = ext;
- bf_data->offsetIsDr = (bf_data->ext & 0x0800);
- bf_data->widthIsDr = (bf_data->ext & 0x20);
- bf_data->offset = cpuGetBfOffset(bf_data->ext, bf_data->offsetIsDr);
- bf_data->width = cpuGetBfWidth(bf_data->ext, bf_data->widthIsDr);
- bf_data->bit_offset = bf_data->offset & 7;
- bf_data->byte_count = ((bf_data->bit_offset + bf_data->width + 7) >> 3);
- bf_data->end_offset = (bf_data->byte_count*8 - (bf_data->offset + bf_data->width)) & 7;
- bf_data->field = 0;
- bf_data->field_mask = 0xffffffff >> (32 - bf_data->width);
- if (has_dn)
- {
- bf_data->dn = (bf_data->ext & 0x7000) >> 12;
- }
if (has_ea)
{
- bf_data->base_address = val + (bf_data->offset >> 3);
- cpuGetBfEaBytes(&bf_data->b[0], bf_data->base_address, bf_data->byte_count);
+ ULO shift = bf_data->base_address_byte_count*8 - bf_data->normalized_offset - bf_data->width;
+ ULL field_value = (bf_data->field_memory & ~(bf_data->field_mask << shift)) | (bf_data->field << shift);
+ ULO address = bf_data->base_address + bf_data->base_address_byte_offset;
+
+ for (int i = bf_data->base_address_byte_count - 1; i >= 0; --i)
+ {
+ UBY field_byte = (field_value >> (i*8)) & 0xff;
+ memoryWriteByte(field_byte, address);
+ ++address;
+ }
}
else
{
- cpuGetBfRegBytes(&bf_data->b[0], val);
+ ULO reg_shift = (32 - bf_data->offset - bf_data->width);
+ ULO reg_value = (cpuGetDReg(ea_or_reg) & ~(bf_data->field_mask << reg_shift)) | (bf_data->field << reg_shift);
+ cpuSetDReg(ea_or_reg, reg_value);
}
}
+void cpuBfDecodeExtWordAndGetField(struct cpuBfData *bf_data, ULO ea_or_reg, bool has_dn, bool has_ea, UWO ext)
+{
+ bool offsetIsDataRegister = ((ext & 0x0800) == 0x0800);
+ bool widthIsDataRegister = ((ext & 0x0020) == 0x0020);
+
+ bf_data->offset = cpuGetBfOffset(ext, offsetIsDataRegister);
+ bf_data->width = cpuGetBfWidth(ext, widthIsDataRegister);
+ bf_data->field_mask = 0xffffffff >> (32 - bf_data->width);
+
+ if (has_dn)
+ {
+ bf_data->dn = (ext & 0x7000) >> 12;
+ }
+
+ if (has_ea)
+ {
+ bf_data->base_address = ea_or_reg; // Base address of the field, before offset is applied
+ bf_data->base_address_byte_offset = (bf_data->offset >> 3); // The first byte in the field
+ bf_data->normalized_offset = bf_data->offset - (bf_data->base_address_byte_offset)*8; // Offset relative to the first byte in the field
+ bf_data->base_address_byte_count = (bf_data->normalized_offset + bf_data->width + 7) / 8;
+
+ ULO field = 0;
+ ULL field_memory = 0;
+ ULO address = bf_data->base_address + bf_data->base_address_byte_offset;
+ ULO shift = (8 - bf_data->normalized_offset - bf_data->width) & 7;
+ for (int i = bf_data->base_address_byte_count - 1; i >= 0; --i)
+ {
+ ULL value = (ULL) memoryReadByte(address);
+ field_memory |= (value << (8*i));
+ field |= ((value >> shift) << (8*i));
+ ++address;
+ }
+
+ bf_data->field_memory = field_memory;
+ bf_data->field = field;
+ }
+ else
+ {
+ bf_data->field = cpuGetDReg(ea_or_reg) >> (32 - bf_data->offset - bf_data->width);
+ }
+ bf_data->field &= bf_data->field_mask;
+}
+
///
/// bfchg common logic
///
-static void cpuBfChgCommon(ULO val, BOOLE has_ea, UWO ext)
+static void cpuBfChgCommon(ULO ea_or_reg, bool has_ea, UWO ext)
{
struct cpuBfData bf_data;
- cpuBfExtWord(&bf_data, val, FALSE, has_ea, ext);
- bf_data.field = cpuGetBfField(&bf_data.b[0], bf_data.end_offset, bf_data.byte_count, bf_data.field_mask);
+ cpuBfDecodeExtWordAndGetField(&bf_data, ea_or_reg, false, has_ea, ext);
cpuSetFlagsNZVC(bf_data.field == 0, bf_data.field & (1 << (bf_data.width - 1)), FALSE, FALSE);
- cpuSetBfField(&bf_data.b[0], bf_data.end_offset, bf_data.byte_count, (~bf_data.field) & bf_data.field_mask, bf_data.field_mask);
- if (has_ea)
- {
- cpuSetBfEaBytes(&bf_data.b[0], bf_data.base_address, bf_data.byte_count);
- }
- else
- {
- cpuSetBfRegBytes(&bf_data.b[0], val);
- }
+
+ bf_data.field = (~bf_data.field) & bf_data.field_mask;
+
+ cpuSetBfField(&bf_data, ea_or_reg, has_ea);
}
-///
-/// bfchg dx {offset:width}
-///
+// bfchg dx {offset:width}
static void cpuBfChgReg(ULO regno, UWO ext)
{
- cpuBfChgCommon(regno, FALSE, ext);
+ cpuBfChgCommon(regno, false, ext);
}
///
@@ -2783,27 +2784,22 @@ static void cpuBfChgReg(ULO regno, UWO ext)
///
static void cpuBfChgEa(ULO ea, UWO ext)
{
- cpuBfChgCommon(ea, TRUE, ext);
+ cpuBfChgCommon(ea, true, ext);
}
///
/// bfclr common logic
///
-static void cpuBfClrCommon(ULO val, BOOLE has_ea, UWO ext)
+static void cpuBfClrCommon(ULO ea_or_reg, bool has_ea, UWO ext)
{
struct cpuBfData bf_data;
- cpuBfExtWord(&bf_data, val, FALSE, has_ea, ext);
- bf_data.field = cpuGetBfField(&bf_data.b[0], bf_data.end_offset, bf_data.byte_count, bf_data.field_mask);
+ cpuBfDecodeExtWordAndGetField(&bf_data, ea_or_reg, false, has_ea, ext);
+
cpuSetFlagsNZVC(bf_data.field == 0, bf_data.field & (1 << (bf_data.width - 1)), FALSE, FALSE);
- cpuSetBfField(&bf_data.b[0], bf_data.end_offset, bf_data.byte_count, 0, bf_data.field_mask);
- if (has_ea)
- {
- cpuSetBfEaBytes(&bf_data.b[0], bf_data.base_address, bf_data.byte_count);
- }
- else
- {
- cpuSetBfRegBytes(&bf_data.b[0], val);
- }
+
+ bf_data.field = 0;
+
+ cpuSetBfField(&bf_data, ea_or_reg, has_ea);
}
///
@@ -2811,7 +2807,7 @@ static void cpuBfClrCommon(ULO val, BOOLE has_ea, UWO ext)
///
static void cpuBfClrReg(ULO regno, UWO ext)
{
- cpuBfClrCommon(regno, FALSE, ext);
+ cpuBfClrCommon(regno, false, ext);
}
///
@@ -2819,24 +2815,27 @@ static void cpuBfClrReg(ULO regno, UWO ext)
///
static void cpuBfClrEa(ULO ea, UWO ext)
{
- cpuBfClrCommon(ea, TRUE, ext);
+ cpuBfClrCommon(ea, true, ext);
}
///
/// bfexts common logic
///
-static void cpuBfExtsCommon(ULO val, BOOLE has_ea, UWO ext)
+static void cpuBfExtsCommon(ULO ea_or_reg, bool has_ea, UWO ext)
{
struct cpuBfData bf_data;
BOOLE n_flag;
- cpuBfExtWord(&bf_data, val, TRUE, has_ea, ext);
- bf_data.field = cpuGetBfField(&bf_data.b[0], bf_data.end_offset, bf_data.byte_count, bf_data.field_mask);
+ cpuBfDecodeExtWordAndGetField(&bf_data, ea_or_reg, true, has_ea, ext);
+
n_flag = bf_data.field & (1 << (bf_data.width - 1));
+
cpuSetFlagsNZVC(bf_data.field == 0, n_flag, FALSE, FALSE);
+
if (n_flag)
{
- bf_data.field = ~bf_data.field_mask | bf_data.field;
+ bf_data.field = (ULO)((~bf_data.field_mask) | bf_data.field);
}
+ // Destination is always Dn
cpuSetDReg(bf_data.dn, bf_data.field);
}
@@ -2845,7 +2844,7 @@ static void cpuBfExtsCommon(ULO val, BOOLE has_ea, UWO ext)
///
static void cpuBfExtsReg(ULO regno, UWO ext)
{
- cpuBfExtsCommon(regno, FALSE, ext);
+ cpuBfExtsCommon(regno, false, ext);
}
///
@@ -2853,18 +2852,18 @@ static void cpuBfExtsReg(ULO regno, UWO ext)
///
static void cpuBfExtsEa(ULO ea, UWO ext)
{
- cpuBfExtsCommon(ea, TRUE, ext);
+ cpuBfExtsCommon(ea, true, ext);
}
///
/// bfextu ea {offset:width}, Dn
///
-static void cpuBfExtuCommon(ULO val, BOOLE has_ea, UWO ext)
+static void cpuBfExtuCommon(ULO ea_or_reg, bool has_ea, UWO ext)
{
struct cpuBfData bf_data;
- cpuBfExtWord(&bf_data, val, TRUE, has_ea, ext);
- bf_data.field = cpuGetBfField(&bf_data.b[0], bf_data.end_offset, bf_data.byte_count, bf_data.field_mask);
+ cpuBfDecodeExtWordAndGetField(&bf_data, ea_or_reg, true, has_ea, ext);
cpuSetFlagsNZVC(bf_data.field == 0, bf_data.field & (1 << (bf_data.width - 1)), FALSE, FALSE);
+ // Destination is always Dn
cpuSetDReg(bf_data.dn, bf_data.field);
}
@@ -2873,7 +2872,7 @@ static void cpuBfExtuCommon(ULO val, BOOLE has_ea, UWO ext)
///
static void cpuBfExtuReg(ULO regno, UWO ext)
{
- cpuBfExtuCommon(regno, FALSE, ext);
+ cpuBfExtuCommon(regno, false, ext);
}
///
@@ -2881,22 +2880,22 @@ static void cpuBfExtuReg(ULO regno, UWO ext)
///
static void cpuBfExtuEa(ULO ea, UWO ext)
{
- cpuBfExtuCommon(ea, TRUE, ext);
+ cpuBfExtuCommon(ea, true, ext);
}
///
/// bfffo common logic
///
-static void cpuBfFfoCommon(ULO val, BOOLE has_ea, UWO ext)
+static void cpuBfFfoCommon(ULO val, bool has_ea, UWO ext)
{
struct cpuBfData bf_data;
ULO i;
- cpuBfExtWord(&bf_data, val, TRUE, has_ea, ext);
- bf_data.field = cpuGetBfField(&bf_data.b[0], bf_data.end_offset, bf_data.byte_count, bf_data.field_mask);
+ cpuBfDecodeExtWordAndGetField(&bf_data, val, true, has_ea, ext);
cpuSetFlagsNZVC(bf_data.field == 0, bf_data.field & (1 << (bf_data.width - 1)), FALSE, FALSE);
+
for (i = 0; i < bf_data.width; ++i)
{
- if (bf_data.field & (0x1 << (bf_data.width - i - 1)))
+ if (bf_data.field & (1 << (bf_data.width - i - 1)))
break;
}
cpuSetDReg(bf_data.dn, bf_data.offset + i);
@@ -2907,7 +2906,7 @@ static void cpuBfFfoCommon(ULO val, BOOLE has_ea, UWO ext)
///
static void cpuBfFfoReg(ULO regno, UWO ext)
{
- cpuBfFfoCommon(regno, FALSE, ext);
+ cpuBfFfoCommon(regno, false, ext);
}
///
@@ -2915,28 +2914,23 @@ static void cpuBfFfoReg(ULO regno, UWO ext)
///
static void cpuBfFfoEa(ULO ea, UWO ext)
{
- cpuBfFfoCommon(ea, TRUE, ext);
+ cpuBfFfoCommon(ea, true, ext);
}
///
/// bfins common logic
///
-static void cpuBfInsCommon(ULO val, BOOLE has_ea, UWO ext)
+static void cpuBfInsCommon(ULO ea_or_reg, bool has_ea, UWO ext)
{
struct cpuBfData bf_data;
- cpuBfExtWord(&bf_data, val, TRUE, has_ea, ext);
- bf_data.field = cpuGetBfField(&bf_data.b[0], bf_data.end_offset, bf_data.byte_count, bf_data.field_mask);
- cpuSetFlagsNZVC(bf_data.field == 0, bf_data.field & (1 << (bf_data.width - 1)), FALSE, FALSE);
+ cpuBfDecodeExtWordAndGetField(&bf_data, ea_or_reg, true, has_ea, ext);
+
bf_data.field = cpuGetDReg(bf_data.dn) & bf_data.field_mask;
- cpuSetBfField(&bf_data.b[0], bf_data.end_offset, bf_data.byte_count, bf_data.field, bf_data.field_mask);
- if (has_ea)
- {
- cpuSetBfEaBytes(&bf_data.b[0], bf_data.base_address, bf_data.byte_count);
- }
- else
- {
- cpuSetBfRegBytes(&bf_data.b[0], val);
- }
+
+ // Flags are set according to the inserted value
+ cpuSetFlagsNZVC(bf_data.field == 0, bf_data.field & (1 << (bf_data.width - 1)), FALSE, FALSE);
+
+ cpuSetBfField(&bf_data, ea_or_reg, has_ea);
}
///
@@ -2944,7 +2938,7 @@ static void cpuBfInsCommon(ULO val, BOOLE has_ea, UWO ext)
///
static void cpuBfInsReg(ULO regno, UWO ext)
{
- cpuBfInsCommon(regno, FALSE, ext);
+ cpuBfInsCommon(regno, false, ext);
}
///
@@ -2952,28 +2946,21 @@ static void cpuBfInsReg(ULO regno, UWO ext)
///
static void cpuBfInsEa(ULO ea, UWO ext)
{
- cpuBfInsCommon(ea, TRUE, ext);
+ cpuBfInsCommon(ea, true, ext);
}
///
/// bfset common logic
///
-static void cpuBfSetCommon(ULO val, BOOLE has_ea, UWO ext)
+static void cpuBfSetCommon(ULO ea_or_reg, bool has_ea, UWO ext)
{
struct cpuBfData bf_data;
- cpuBfExtWord(&bf_data, val, FALSE, has_ea, ext);
- bf_data.field = cpuGetBfField(&bf_data.b[0], bf_data.end_offset, bf_data.byte_count, bf_data.field_mask);
+ cpuBfDecodeExtWordAndGetField(&bf_data, ea_or_reg, false, has_ea, ext);
cpuSetFlagsNZVC(bf_data.field == 0, bf_data.field & (1 << (bf_data.width - 1)), FALSE, FALSE);
- bf_data.field = bf_data.field_mask;
- cpuSetBfField(&bf_data.b[0], bf_data.end_offset, bf_data.byte_count, bf_data.field, bf_data.field_mask);
- if (has_ea)
- {
- cpuSetBfEaBytes(&bf_data.b[0], bf_data.base_address, bf_data.byte_count);
- }
- else
- {
- cpuSetBfRegBytes(&bf_data.b[0], val);
- }
+
+ bf_data.field = (ULO)bf_data.field_mask;
+
+ cpuSetBfField(&bf_data, ea_or_reg, has_ea);
}
///
@@ -2981,7 +2968,7 @@ static void cpuBfSetCommon(ULO val, BOOLE has_ea, UWO ext)
///
static void cpuBfSetReg(ULO regno, UWO ext)
{
- cpuBfSetCommon(regno, FALSE, ext);
+ cpuBfSetCommon(regno, false, ext);
}
///
@@ -2989,17 +2976,16 @@ static void cpuBfSetReg(ULO regno, UWO ext)
///
static void cpuBfSetEa(ULO ea, UWO ext)
{
- cpuBfSetCommon(ea, TRUE, ext);
+ cpuBfSetCommon(ea, true, ext);
}
///
/// bftst common logic
///
-static void cpuBfTstCommon(ULO val, BOOLE has_ea, UWO ext)
+static void cpuBfTstCommon(ULO ea_or_reg, bool has_ea, UWO ext)
{
struct cpuBfData bf_data;
- cpuBfExtWord(&bf_data, val, FALSE, has_ea, ext);
- bf_data.field = cpuGetBfField(&bf_data.b[0], bf_data.end_offset, bf_data.byte_count, bf_data.field_mask);
+ cpuBfDecodeExtWordAndGetField(&bf_data, ea_or_reg, false, has_ea, ext);
cpuSetFlagsNZVC(bf_data.field == 0, bf_data.field & (1 << (bf_data.width - 1)), FALSE, FALSE);
}
@@ -3008,7 +2994,7 @@ static void cpuBfTstCommon(ULO val, BOOLE has_ea, UWO ext)
///
static void cpuBfTstReg(ULO regno, UWO ext)
{
- cpuBfTstCommon(regno, FALSE, ext);
+ cpuBfTstCommon(regno, false, ext);
}
///
@@ -3016,7 +3002,7 @@ static void cpuBfTstReg(ULO regno, UWO ext)
///
static void cpuBfTstEa(ULO ea, UWO ext)
{
- cpuBfTstCommon(ea, TRUE, ext);
+ cpuBfTstCommon(ea, true, ext);
}
///
@@ -3025,8 +3011,7 @@ static void cpuBfTstEa(ULO ea, UWO ext)
static void cpuMovepWReg(ULO areg, ULO dreg)
{
ULO ea = cpuGetAReg(areg) + cpuGetNextWordSignExt();
- memoryWriteByte((UBY) (cpuGetDReg(dreg) >> 8), ea);
- memoryWriteByte(cpuGetDRegByte(dreg), ea + 2);
+ cpuSetDRegWord(dreg, cpuJoinByteToWord(memoryReadByte(ea), memoryReadByte(ea + 2)));
cpuSetInstructionTime(16);
}
@@ -3036,10 +3021,7 @@ static void cpuMovepWReg(ULO areg, ULO dreg)
static void cpuMovepLReg(ULO areg, ULO dreg)
{
ULO ea = cpuGetAReg(areg) + cpuGetNextWordSignExt();
- memoryWriteByte((UBY)(cpuGetDReg(dreg) >> 24), ea);
- memoryWriteByte((UBY)(cpuGetDReg(dreg) >> 16), ea + 2);
- memoryWriteByte((UBY)(cpuGetDReg(dreg) >> 8), ea + 4);
- memoryWriteByte(cpuGetDRegByte(dreg), ea + 6);
+ cpuSetDReg(dreg, cpuJoinByteToLong(memoryReadByte(ea), memoryReadByte(ea + 2), memoryReadByte(ea + 4), memoryReadByte(ea + 6)));
cpuSetInstructionTime(24);
}
@@ -3049,7 +3031,8 @@ static void cpuMovepLReg(ULO areg, ULO dreg)
static void cpuMovepWEa(ULO areg, ULO dreg)
{
ULO ea = cpuGetAReg(areg) + cpuGetNextWordSignExt();
- cpuSetDRegWord(dreg, cpuJoinByteToWord(memoryReadByte(ea), memoryReadByte(ea + 2)));
+ memoryWriteByte((UBY) (cpuGetDReg(dreg) >> 8), ea);
+ memoryWriteByte(cpuGetDRegByte(dreg), ea + 2);
cpuSetInstructionTime(16);
}
@@ -3059,7 +3042,10 @@ static void cpuMovepWEa(ULO areg, ULO dreg)
static void cpuMovepLEa(ULO areg, ULO dreg)
{
ULO ea = cpuGetAReg(areg) + cpuGetNextWordSignExt();
- cpuSetDReg(dreg, cpuJoinByteToLong(memoryReadByte(ea), memoryReadByte(ea + 2), memoryReadByte(ea + 4), memoryReadByte(ea + 6)));
+ memoryWriteByte((UBY)(cpuGetDReg(dreg) >> 24), ea);
+ memoryWriteByte((UBY)(cpuGetDReg(dreg) >> 16), ea + 2);
+ memoryWriteByte((UBY)(cpuGetDReg(dreg) >> 8), ea + 4);
+ memoryWriteByte(cpuGetDRegByte(dreg), ea + 6);
cpuSetInstructionTime(24);
}
@@ -3127,41 +3113,41 @@ static void cpuMoveCFrom()
{
switch (ctrl_regno)
{
- case 0x000: cpuSetReg(da, regno, cpuGetSfc()); break;
- case 0x001: cpuSetReg(da, regno, cpuGetDfc()); break;
- case 0x800: cpuSetReg(da, regno, cpuGetUspDirect()); break; // In supervisor mode, usp is up to date.
- case 0x801: cpuSetReg(da, regno, cpuGetVbr()); break;
- default: cpuThrowIllegalInstructionException(FALSE); return; // Illegal instruction
+ case 0x000: cpuSetReg(da, regno, cpuGetSfc()); break;
+ case 0x001: cpuSetReg(da, regno, cpuGetDfc()); break;
+ case 0x800: cpuSetReg(da, regno, cpuGetUspDirect()); break; // In supervisor mode, usp is up to date.
+ case 0x801: cpuSetReg(da, regno, cpuGetVbr()); break;
+ default: cpuThrowIllegalInstructionException(FALSE); return; // Illegal instruction
}
}
else if (cpuGetModelMajor() == 2)
{
switch (ctrl_regno)
{
- case 0x000: cpuSetReg(da, regno, cpuGetSfc()); break;
- case 0x001: cpuSetReg(da, regno, cpuGetDfc()); break;
- case 0x002: cpuSetReg(da, regno, cpuGetCacr() & 3); break;
- case 0x800: cpuSetReg(da, regno, cpuGetUspDirect()); break; // In supervisor mode, usp is up to date.
- case 0x801: cpuSetReg(da, regno, cpuGetVbr()); break;
- case 0x802: cpuSetReg(da, regno, cpuGetCaar() & 0xfc); break;
- case 0x803: cpuSetReg(da, regno, cpuGetMspAutoMap()); break;
- case 0x804: cpuSetReg(da, regno, cpuGetIspAutoMap()); break;
- default: cpuThrowIllegalInstructionException(FALSE); return; // Illegal instruction
+ case 0x000: cpuSetReg(da, regno, cpuGetSfc()); break;
+ case 0x001: cpuSetReg(da, regno, cpuGetDfc()); break;
+ case 0x002: cpuSetReg(da, regno, cpuGetCacr() & 3); break;
+ case 0x800: cpuSetReg(da, regno, cpuGetUspDirect()); break; // In supervisor mode, usp is up to date.
+ case 0x801: cpuSetReg(da, regno, cpuGetVbr()); break;
+ case 0x802: cpuSetReg(da, regno, cpuGetCaar() & 0xfc); break;
+ case 0x803: cpuSetReg(da, regno, cpuGetMspAutoMap()); break;
+ case 0x804: cpuSetReg(da, regno, cpuGetIspAutoMap()); break;
+ default: cpuThrowIllegalInstructionException(FALSE); return; // Illegal instruction
}
}
else if (cpuGetModelMajor() == 3)
{
switch (ctrl_regno)
{
- case 0x000: cpuSetReg(da, regno, cpuGetSfc()); break;
- case 0x001: cpuSetReg(da, regno, cpuGetDfc()); break;
- case 0x002: cpuSetReg(da, regno, cpuGetCacr()); break;
- case 0x800: cpuSetReg(da, regno, cpuGetUspDirect()); break; // In supervisor mode, usp is up to date.
- case 0x801: cpuSetReg(da, regno, cpuGetVbr()); break;
- case 0x802: cpuSetReg(da, regno, cpuGetCaar() & 0xfc); break;
- case 0x803: cpuSetReg(da, regno, cpuGetMspAutoMap()); break;
- case 0x804: cpuSetReg(da, regno, cpuGetIspAutoMap()); break;
- default: cpuThrowIllegalInstructionException(FALSE); return; // Illegal instruction
+ case 0x000: cpuSetReg(da, regno, cpuGetSfc()); break;
+ case 0x001: cpuSetReg(da, regno, cpuGetDfc()); break;
+ case 0x002: cpuSetReg(da, regno, cpuGetCacr()); break;
+ case 0x800: cpuSetReg(da, regno, cpuGetUspDirect()); break; // In supervisor mode, usp is up to date.
+ case 0x801: cpuSetReg(da, regno, cpuGetVbr()); break;
+ case 0x802: cpuSetReg(da, regno, cpuGetCaar() & 0xfc); break;
+ case 0x803: cpuSetReg(da, regno, cpuGetMspAutoMap()); break;
+ case 0x804: cpuSetReg(da, regno, cpuGetIspAutoMap()); break;
+ default: cpuThrowIllegalInstructionException(FALSE); return; // Illegal instruction
}
}
}
@@ -3188,41 +3174,41 @@ static void cpuMoveCTo()
{
switch (ctrl_regno)
{
- case 0x000: cpuSetSfc(cpuGetReg(da, regno) & 7); break;
- case 0x001: cpuSetDfc(cpuGetReg(da, regno) & 7); break;
- case 0x800: cpuSetUspDirect(cpuGetReg(da, regno)); break;
- case 0x801: cpuSetVbr(cpuGetReg(da, regno)); break;
- default: cpuThrowIllegalInstructionException(FALSE); return; // Illegal instruction
+ case 0x000: cpuSetSfc(cpuGetReg(da, regno) & 7); break;
+ case 0x001: cpuSetDfc(cpuGetReg(da, regno) & 7); break;
+ case 0x800: cpuSetUspDirect(cpuGetReg(da, regno)); break;
+ case 0x801: cpuSetVbr(cpuGetReg(da, regno)); break;
+ default: cpuThrowIllegalInstructionException(FALSE); return; // Illegal instruction
}
}
else if (cpuGetModelMajor() == 2)
{
switch (ctrl_regno)
{
- case 0x000: cpuSetSfc(cpuGetReg(da, regno) & 7); break;
- case 0x001: cpuSetDfc(cpuGetReg(da, regno) & 7); break;
- case 0x002: cpuSetCacr(cpuGetReg(da, regno) & 0x3); break;
- case 0x800: cpuSetUspDirect(cpuGetReg(da, regno)); break;
- case 0x801: cpuSetVbr(cpuGetReg(da, regno)); break;
- case 0x802: cpuSetCaar(cpuGetReg(da, regno) & 0x00fc); break;
- case 0x803: cpuSetMspAutoMap(cpuGetReg(da, regno)); break;
- case 0x804: cpuSetIspAutoMap(cpuGetReg(da, regno)); break;
- default: cpuThrowIllegalInstructionException(FALSE); return; // Illegal instruction
+ case 0x000: cpuSetSfc(cpuGetReg(da, regno) & 7); break;
+ case 0x001: cpuSetDfc(cpuGetReg(da, regno) & 7); break;
+ case 0x002: cpuSetCacr(cpuGetReg(da, regno) & 0x3); break;
+ case 0x800: cpuSetUspDirect(cpuGetReg(da, regno)); break;
+ case 0x801: cpuSetVbr(cpuGetReg(da, regno)); break;
+ case 0x802: cpuSetCaar(cpuGetReg(da, regno) & 0x00fc); break;
+ case 0x803: cpuSetMspAutoMap(cpuGetReg(da, regno)); break;
+ case 0x804: cpuSetIspAutoMap(cpuGetReg(da, regno)); break;
+ default: cpuThrowIllegalInstructionException(FALSE); return; // Illegal instruction
}
}
else if (cpuGetModelMajor() == 3)
{
switch (ctrl_regno)
{
- case 0x000: cpuSetSfc(cpuGetReg(da, regno) & 7); break;
- case 0x001: cpuSetDfc(cpuGetReg(da, regno) & 7); break;
- case 0x002: cpuSetCacr(cpuGetReg(da, regno) & 0x3313); break;
- case 0x800: cpuSetUspDirect(cpuGetReg(da, regno)); break;
- case 0x801: cpuSetVbr(cpuGetReg(da, regno)); break;
- case 0x802: cpuSetCaar(cpuGetReg(da, regno) & 0x00fc); break;
- case 0x803: cpuSetMspAutoMap(cpuGetReg(da, regno)); break;
- case 0x804: cpuSetIspAutoMap(cpuGetReg(da, regno)); break;
- default: cpuThrowIllegalInstructionException(FALSE); return; // Illegal instruction
+ case 0x000: cpuSetSfc(cpuGetReg(da, regno) & 7); break;
+ case 0x001: cpuSetDfc(cpuGetReg(da, regno) & 7); break;
+ case 0x002: cpuSetCacr(cpuGetReg(da, regno) & 0x3313); break;
+ case 0x800: cpuSetUspDirect(cpuGetReg(da, regno)); break;
+ case 0x801: cpuSetVbr(cpuGetReg(da, regno)); break;
+ case 0x802: cpuSetCaar(cpuGetReg(da, regno) & 0x00fc); break;
+ case 0x803: cpuSetMspAutoMap(cpuGetReg(da, regno)); break;
+ case 0x804: cpuSetIspAutoMap(cpuGetReg(da, regno)); break;
+ default: cpuThrowIllegalInstructionException(FALSE); return; // Illegal instruction
}
}
}
@@ -3252,11 +3238,11 @@ static void cpuMoveSB(ULO ea, UWO extension)
UBY data = memoryReadByte(ea);
if (da == 0)
{
- cpuSetDRegByte(regno, data);
+ cpuSetDRegByte(regno, data);
}
else
{
- cpuSetAReg(regno, (ULO)(LON)(BYT) data);
+ cpuSetAReg(regno, (ULO)(LON)(BYT) data);
}
}
}
@@ -3265,7 +3251,7 @@ static void cpuMoveSB(ULO ea, UWO extension)
cpuThrowPrivilegeViolationException();
return;
}
- cpuSetInstructionTime(4);
+ cpuSetInstructionTime(4);
}
///
@@ -3286,11 +3272,11 @@ static void cpuMoveSW(ULO ea, UWO extension)
UWO data = memoryReadWord(ea);
if (da == 0)
{
- cpuSetDRegWord(regno, data);
+ cpuSetDRegWord(regno, data);
}
else
{
- cpuSetAReg(regno, (ULO)(LON)(WOR) data);
+ cpuSetAReg(regno, (ULO)(LON)(WOR) data);
}
}
}
@@ -3299,7 +3285,7 @@ static void cpuMoveSW(ULO ea, UWO extension)
cpuThrowPrivilegeViolationException();
return;
}
- cpuSetInstructionTime(4);
+ cpuSetInstructionTime(4);
}
///
@@ -3325,7 +3311,7 @@ static void cpuMoveSL(ULO ea, UWO extension)
cpuThrowPrivilegeViolationException();
return;
}
- cpuSetInstructionTime(4);
+ cpuSetInstructionTime(4);
}
///
@@ -3338,7 +3324,7 @@ static void cpuTrapcc(ULO cc)
cpuThrowTrapVException(); // TrapV and Trapcc share the exception vector
return;
}
- cpuSetInstructionTime(4);
+ cpuSetInstructionTime(4);
}
///
@@ -3352,7 +3338,7 @@ static void cpuTrapccW(ULO cc)
cpuThrowTrapVException(); // TrapV and Trapcc share the exception vector
return;
}
- cpuSetInstructionTime(4);
+ cpuSetInstructionTime(4);
}
///
@@ -3366,7 +3352,7 @@ static void cpuTrapccL(ULO cc)
cpuThrowTrapVException(); // TrapV and Trapcc share the exception vector
return;
}
- cpuSetInstructionTime(4);
+ cpuSetInstructionTime(4);
}
///
@@ -3658,18 +3644,18 @@ static void cpuPflush040(ULO opmode, ULO regno)
{
if (cpuGetFlagSupervisor())
{
- if (cpuGetModelMajor() != 2) // This is NOP on 68EC040
+ if (cpuGetModelMajor() != 2) // This is NOP on 68EC040
{
switch (opmode)
{
- case 0: //PFLUSHN (An)
- break;
- case 1: //PFLUSH (An)
- break;
- case 2: //PFLUSHAN
- break;
- case 3: //PFLUSHA
- break;
+ case 0: //PFLUSHN (An)
+ break;
+ case 1: //PFLUSH (An)
+ break;
+ case 2: //PFLUSHAN
+ break;
+ case 3: //PFLUSHA
+ break;
}
}
}
@@ -3693,15 +3679,15 @@ static void cpuPtest040(ULO rw, ULO regno)
{
if (cpuGetFlagSupervisor())
{
- if (cpuGetModelMajor() != 2) // This is NOP on 68EC040
+ if (cpuGetModelMajor() != 2) // This is NOP on 68EC040
{
if (rw == 0)
{
- // ptestr
+ // ptestr
}
else
{
- // ptestw
+ // ptestw
}
}
}
@@ -3739,11 +3725,14 @@ void cpuMakeOpcodeTableForModel(void)
}
}
+ULO irq_arrival_time = -1;
+extern ULO busGetCycle();
+
ULO cpuExecuteInstruction(void)
{
if (cpuGetRaiseInterrupt())
{
- cpuSetUpInterrupt();
+ cpuSetUpInterrupt(cpuGetRaiseInterruptLevel());
cpuCheckPendingInterrupts();
return 44;
}
@@ -3765,8 +3754,8 @@ ULO cpuExecuteInstruction(void)
cpuSetInstructionTime(0);
- cpu_opcode_data_current[opcode].instruction_func(
- cpu_opcode_data_current[opcode].data);
+ cpu_opcode_data_current[opcode].instruction_func(
+ cpu_opcode_data_current[opcode].data);
if (oldSr & 0xc000)
{
// This instruction was traced
diff --git a/cpu/CpuModule_Internal.h b/cpu/CpuModule_Internal.h
index b7bf858..9f68069 100644
--- a/cpu/CpuModule_Internal.h
+++ b/cpu/CpuModule_Internal.h
@@ -51,7 +51,7 @@ extern void cpuSetCaar(ULO caar);
extern ULO cpuGetCaar(void);
extern void cpuSetSR(ULO sr);
extern ULO cpuGetSR(void);
-extern void cpuSetIrqLevel(ULO irq_level);
+extern BOOLE cpuSetIrqLevel(ULO new_interrupt_level);
extern ULO cpuGetIrqLevel(void);
extern void cpuSetIrqAddress(ULO irq_address);
extern ULO cpuGetIrqAddress(void);
@@ -167,10 +167,11 @@ extern void cpuCallInterruptLoggingFunc(ULO level, ULO vector_address);
#endif
// Interrupt
-extern void cpuCallCheckPendingInterruptsFunc(void);
extern ULO cpuActivateSSP(void);
extern void cpuSetRaiseInterrupt(BOOLE raise_irq);
extern BOOLE cpuGetRaiseInterrupt(void);
+extern void cpuSetRaiseInterruptLevel(ULO raise_irq_level);
+extern ULO cpuGetRaiseInterruptLevel(void);
// Exceptions
extern void cpuThrowPrivilegeViolationException(void);
diff --git a/cpu/CpuModule_InternalState.c b/cpu/CpuModule_InternalState.c
index 2fba027..db93bba 100644
--- a/cpu/CpuModule_InternalState.c
+++ b/cpu/CpuModule_InternalState.c
@@ -1,4 +1,4 @@
-/* @(#) $Id: CpuModule_InternalState.c,v 1.9 2012/08/12 16:51:02 peschau Exp $ */
+/* @(#) $Id: CpuModule_InternalState.c,v 1.9 2012-08-12 16:51:02 peschau Exp $ */
/*=========================================================================*/
/* Fellow */
/* 68000 internal state */
@@ -43,8 +43,7 @@ static ULO cpu_caar;
/* Irq management */
static BOOLE cpu_raise_irq;
-static ULO cpu_irq_level;
-static ULO cpu_irq_address;
+static ULO cpu_raise_irq_level;
/* Reset values */
static ULO cpu_initial_pc;
@@ -186,12 +185,6 @@ ULO cpuGetCaar(void) {return cpu_caar;}
void cpuSetSR(ULO sr) {cpu_sr = sr;}
ULO cpuGetSR(void) {return cpu_sr;}
-void cpuSetIrqLevel(ULO irq_level) {cpu_irq_level = irq_level;}
-ULO cpuGetIrqLevel(void) {return cpu_irq_level;}
-
-void cpuSetIrqAddress(ULO irq_address) {cpu_irq_address = irq_address;}
-ULO cpuGetIrqAddress(void) {return cpu_irq_address;}
-
void cpuSetInstructionTime(ULO cycles) {cpu_instruction_time = cycles;}
ULO cpuGetInstructionTime(void) {return cpu_instruction_time;}
@@ -207,6 +200,10 @@ UWO cpuGetCurrentOpcode(void) {return cpu_current_opcode;}
void cpuSetRaiseInterrupt(BOOLE raise_irq) {cpu_raise_irq = raise_irq;}
BOOLE cpuGetRaiseInterrupt(void) {return cpu_raise_irq;}
+void cpuSetRaiseInterruptLevel(ULO raise_irq_level) {cpu_raise_irq_level = raise_irq_level;}
+ULO cpuGetRaiseInterruptLevel(void) {return cpu_raise_irq_level;}
+
+ULO cpuGetIrqLevel(void) {return (cpu_sr & 0x0700) >> 8;}
void cpuSetInitialPC(ULO pc) {cpu_initial_pc = pc;}
ULO cpuGetInitialPC(void) {return cpu_initial_pc;}
@@ -352,8 +349,6 @@ void cpuSaveState(FILE *F)
fwrite(&cpu_vbr, sizeof(cpu_vbr), 1, F);
fwrite(&cpu_cacr, sizeof(cpu_cacr), 1, F);
fwrite(&cpu_caar, sizeof(cpu_caar), 1, F);
- fwrite(&cpu_irq_level, sizeof(cpu_irq_level), 1, F);
- fwrite(&cpu_irq_address, sizeof(cpu_irq_address), 1, F);
fwrite(&cpu_initial_pc, sizeof(cpu_initial_pc), 1, F);
fwrite(&cpu_initial_sp, sizeof(cpu_initial_sp), 1, F);
}
@@ -382,8 +377,6 @@ void cpuLoadState(FILE *F)
fread(&cpu_vbr, sizeof(cpu_vbr), 1, F);
fread(&cpu_cacr, sizeof(cpu_cacr), 1, F);
fread(&cpu_caar, sizeof(cpu_caar), 1, F);
- fread(&cpu_irq_level, sizeof(cpu_irq_level), 1, F);
- fread(&cpu_irq_address, sizeof(cpu_irq_address), 1, F);
fread(&cpu_initial_pc, sizeof(cpu_initial_pc), 1, F);
fread(&cpu_initial_sp, sizeof(cpu_initial_sp), 1, F);
cpuSetModel(cpu_model_major, cpu_model_minor); // Recalculates stack frames etc.
diff --git a/cpu/CpuModule_Interrupts.c b/cpu/CpuModule_Interrupts.c
index 8558bd1..0dab357 100644
--- a/cpu/CpuModule_Interrupts.c
+++ b/cpu/CpuModule_Interrupts.c
@@ -1,4 +1,4 @@
-/* @(#) $Id: CpuModule_Interrupts.c,v 1.5 2012/08/12 16:51:02 peschau Exp $ */
+/* @(#) $Id: CpuModule_Interrupts.c,v 1.5 2012-08-12 16:51:02 peschau Exp $ */
/*=========================================================================*/
/* Fellow */
/* 68000 interrupt handling */
@@ -31,15 +31,10 @@
/* Function for checking pending interrupts */
cpuCheckPendingInterruptsFunc cpu_check_pending_interrupts_func;
-void cpuCallCheckPendingInterruptsFunc(void)
-{
- if (cpuGetRaiseInterrupt()) return;
- cpuSetRaiseInterrupt(cpu_check_pending_interrupts_func());
-}
-
void cpuCheckPendingInterrupts(void)
{
- cpuCallCheckPendingInterruptsFunc();
+ if (cpuGetRaiseInterrupt()) return;
+ if (cpu_check_pending_interrupts_func) cpu_check_pending_interrupts_func();
}
void cpuSetCheckPendingInterruptsFunc(cpuCheckPendingInterruptsFunc func)
@@ -70,24 +65,41 @@ ULO cpuActivateSSP(void)
return currentSP;
}
+// Retrns TRUE if the CPU is in the stopped state,
+// this allows our scheduling queue to start
+// scheduling CPU events again.
+BOOLE cpuSetIrqLevel(ULO new_interrupt_level)
+{
+ cpuSetRaiseInterrupt(TRUE);
+ cpuSetRaiseInterruptLevel(new_interrupt_level);
+
+ if (cpuGetStop())
+ {
+ cpuSetStop(FALSE);
+ return TRUE;
+ }
+ return FALSE;
+}
+
/*============================================================
Transfers control to an interrupt routine
============================================================*/
-// Returns TRUE if the cpu was stopped
-void cpuSetUpInterrupt(void)
+void cpuSetUpInterrupt(ULO new_interrupt_level)
{
- UWO vector_offset = (UWO) (0x60 + cpuGetIrqLevel()*4);
+ UWO vector_offset = (UWO) (0x60 + new_interrupt_level*4);
+ ULO vector_address = memoryReadLong(cpuGetVbr() + vector_offset);
+
cpuActivateSSP(); // Switch to using ssp or msp. Loads a7 and preserves usp if we came from user-mode.
cpuStackFrameGenerate(vector_offset, cpuGetPC()); // This will end up on msp if master is enabled, or on the ssp/isp if not.
cpuSetSR(cpuGetSR() & 0x38ff); // Clear interrupt level
cpuSetSR(cpuGetSR() | 0x2000); // Set supervisor mode
- cpuSetSR(cpuGetSR() | (UWO)(cpuGetIrqLevel() << 8)); // Set interrupt level
+ cpuSetSR(cpuGetSR() | (UWO)(new_interrupt_level << 8)); // Set interrupt level
#ifdef CPU_INSTRUCTION_LOGGING
- cpuCallInterruptLoggingFunc(cpuGetIrqLevel(), cpuGetIrqAddress());
+ cpuCallInterruptLoggingFunc(new_interrupt_level, vector_address);
#endif
if (cpuGetModelMajor() >= 2 && cpuGetModelMajor() < 6)
@@ -101,7 +113,7 @@ void cpuSetUpInterrupt(void)
cpuSetSR(cpuGetSR() & 0xefff); // Clear master bit
}
}
- cpuInitializeFromNewPC(cpuGetIrqAddress());
+ cpuInitializeFromNewPC(vector_address);
cpuSetStop(FALSE);
cpuSetRaiseInterrupt(FALSE);
}
diff --git a/cpu/CpuModule_Logging.c b/cpu/CpuModule_Logging.c
index 1336e06..fde361f 100644
--- a/cpu/CpuModule_Logging.c
+++ b/cpu/CpuModule_Logging.c
@@ -1,4 +1,4 @@
-/* @(#) $Id: CpuModule_Logging.c,v 1.3 2012/08/12 16:51:02 peschau Exp $ */
+/* @(#) $Id: CpuModule_Logging.c,v 1.3 2012-08-12 16:51:02 peschau Exp $ */
/*=========================================================================*/
/* Fellow */
/* CPU 68k logging functions */
diff --git a/cpu/CpuModule_StackFrameGen.c b/cpu/CpuModule_StackFrameGen.c
index d68583c..178c0d0 100644
--- a/cpu/CpuModule_StackFrameGen.c
+++ b/cpu/CpuModule_StackFrameGen.c
@@ -1,4 +1,4 @@
-/* @(#) $Id: CpuModule_StackFrameGen.c,v 1.3 2011/07/18 17:22:55 peschau Exp $ */
+/* @(#) $Id: CpuModule_StackFrameGen.c,v 1.3 2011-07-18 17:22:55 peschau Exp $ */
/*=========================================================================*/
/* Fellow */
/* 68000 stack frame generation */
diff --git a/cpu/defs.h b/cpu/defs.h
index 3c55584..33226dc 100644
--- a/cpu/defs.h
+++ b/cpu/defs.h
@@ -4,6 +4,7 @@
#include
#include
#include
+#include
#ifdef __cplusplus
extern "C" {