mirror of https://github.com/ksherlock/mpw.git
fellow cpu code
This commit is contained in:
parent
f97b6eae24
commit
ea246894be
|
@ -0,0 +1,458 @@
|
|||
/* @(#) $Id: CpuIntegration.c,v 1.10 2013/01/08 19:17:33 peschau Exp $ */
|
||||
/*=========================================================================*/
|
||||
/* Fellow */
|
||||
/* Initialization of 68000 core */
|
||||
/* Integrates the 68k emulation with custom chips */
|
||||
/* */
|
||||
/* Author: Petter Schau */
|
||||
/* */
|
||||
/* Copyright (C) 1991, 1992, 1996 Free Software Foundation, Inc. */
|
||||
/* */
|
||||
/* This program is free software; you can redistribute it and/or modify */
|
||||
/* it under the terms of the GNU General Public License as published by */
|
||||
/* the Free Software Foundation; either version 2, or (at your option) */
|
||||
/* any later version. */
|
||||
/* */
|
||||
/* This program is distributed in the hope that it will be useful, */
|
||||
/* but WITHOUT ANY WARRANTY; without even the implied warranty of */
|
||||
/* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the */
|
||||
/* GNU General Public License for more details. */
|
||||
/* */
|
||||
/* You should have received a copy of the GNU General Public License */
|
||||
/* along with this program; if not, write to the Free Software Foundation, */
|
||||
/* Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */
|
||||
/*=========================================================================*/
|
||||
|
||||
#include "defs.h"
|
||||
#include "fellow.h"
|
||||
#include "fmem.h"
|
||||
#include "CpuModule.h"
|
||||
#include "CpuIntegration.h"
|
||||
#include "CpuModule_Internal.h"
|
||||
#include "bus.h"
|
||||
#include "fileops.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;
|
||||
|
||||
/* Cycles spent by chips (Blitter) as a result of an instruction */
|
||||
static ULO cpu_integration_chip_cycles;
|
||||
static ULO cpu_integration_chip_slowdown;
|
||||
|
||||
/*===========================================================================*/
|
||||
/* CPU properties */
|
||||
/*===========================================================================*/
|
||||
|
||||
ULO cpu_integration_speed; // The speed as expressed in the fellow configuration settings
|
||||
ULO cpu_integration_speed_multiplier; // The cycle multiplier used to adjust the cpu-speed, calculated from cpu_integration_speed
|
||||
cpu_integration_models cpu_integration_model; // The cpu model as expressed in the fellow configuration settings
|
||||
|
||||
/*===========================================================================*/
|
||||
/* CPU properties */
|
||||
/*===========================================================================*/
|
||||
|
||||
void cpuIntegrationSetSpeed(ULO speed)
|
||||
{
|
||||
cpu_integration_speed = speed;
|
||||
}
|
||||
|
||||
ULO cpuIntegrationGetSpeed(void)
|
||||
{
|
||||
return cpu_integration_speed;
|
||||
}
|
||||
|
||||
static void cpuIntegrationSetSpeedMultiplier(ULO multiplier)
|
||||
{
|
||||
cpu_integration_speed_multiplier = multiplier;
|
||||
}
|
||||
|
||||
static ULO cpuIntegrationGetSpeedMultiplier(void)
|
||||
{
|
||||
return cpu_integration_speed_multiplier;
|
||||
}
|
||||
|
||||
static void cpuIntegrationCalculateMultiplier(void)
|
||||
{
|
||||
ULO multiplier = 12;
|
||||
|
||||
switch (cpuGetModelMajor())
|
||||
{
|
||||
case 0:
|
||||
multiplier = 12;
|
||||
break;
|
||||
case 1:
|
||||
multiplier = 12;
|
||||
break;
|
||||
case 2:
|
||||
multiplier = 11;
|
||||
break;
|
||||
case 3:
|
||||
multiplier = 11;
|
||||
break;
|
||||
}
|
||||
|
||||
if (cpuIntegrationGetSpeed() >= 8) cpuIntegrationSetSpeedMultiplier(multiplier);
|
||||
else if (cpuIntegrationGetSpeed() >= 4) cpuIntegrationSetSpeedMultiplier(multiplier - 1);
|
||||
else if (cpuIntegrationGetSpeed() >= 2) cpuIntegrationSetSpeedMultiplier(multiplier - 2);
|
||||
else if (cpuIntegrationGetSpeed() >= 1) cpuIntegrationSetSpeedMultiplier(multiplier - 3);
|
||||
else cpuIntegrationSetSpeedMultiplier(multiplier - 4);
|
||||
}
|
||||
|
||||
BOOLE cpuIntegrationSetModel(cpu_integration_models model)
|
||||
{
|
||||
BOOLE needreset = (cpu_integration_model != model);
|
||||
cpu_integration_model = model;
|
||||
|
||||
switch (cpu_integration_model)
|
||||
{
|
||||
case M68000: cpuSetModel(0, 0); break;
|
||||
case M68010: cpuSetModel(1, 0); break;
|
||||
case M68020: cpuSetModel(2, 0); break;
|
||||
case M68030: cpuSetModel(3, 0); break;
|
||||
case M68EC20: cpuSetModel(2, 1); break;
|
||||
case M68EC30: cpuSetModel(3, 1); break;
|
||||
}
|
||||
return needreset;
|
||||
}
|
||||
|
||||
cpu_integration_models cpuIntegrationGetModel(void)
|
||||
{
|
||||
return cpu_integration_model;
|
||||
}
|
||||
|
||||
void cpuIntegrationSetChipCycles(ULO chip_cycles)
|
||||
{
|
||||
cpu_integration_chip_cycles = chip_cycles;
|
||||
}
|
||||
|
||||
ULO cpuIntegrationGetChipCycles(void)
|
||||
{
|
||||
return cpu_integration_chip_cycles;
|
||||
}
|
||||
|
||||
void cpuIntegrationSetChipSlowdown(ULO chip_slowdown)
|
||||
{
|
||||
cpu_integration_chip_slowdown = chip_slowdown;
|
||||
}
|
||||
|
||||
ULO cpuIntegrationGetChipSlowdown(void)
|
||||
{
|
||||
return cpu_integration_chip_slowdown;
|
||||
}
|
||||
|
||||
ULO cpuIntegrationGetChipIrqToIntLevel(ULO chip_irq)
|
||||
{
|
||||
return cpu_integration_int_to_level[chip_irq];
|
||||
}
|
||||
|
||||
void cpuIntegrationSetIrqSource(ULO irq_source)
|
||||
{
|
||||
cpu_integration_irq_source = irq_source;
|
||||
}
|
||||
|
||||
ULO cpuIntegrationGetIrqSource(void)
|
||||
{
|
||||
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)
|
||||
{
|
||||
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;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
void cpuIntegrationCheckPendingInterrupts(void)
|
||||
{
|
||||
cpuCheckPendingInterrupts();
|
||||
}
|
||||
|
||||
/*=========================================*/
|
||||
/* Exception mid-instruction exit function */
|
||||
/*=========================================*/
|
||||
|
||||
void cpuIntegrationMidInstructionExceptionFunc(void)
|
||||
{
|
||||
longjmp(cpu_integration_exception_buffer, -1);
|
||||
}
|
||||
|
||||
/*===================================================*/
|
||||
/* Handles reset exception event from the cpu-module */
|
||||
/*===================================================*/
|
||||
|
||||
void cpuIntegrationResetExceptionFunc(void)
|
||||
{
|
||||
fellowSoftReset();
|
||||
}
|
||||
|
||||
/*=========*/
|
||||
/* Logging */
|
||||
/*=========*/
|
||||
|
||||
#ifdef CPU_INSTRUCTION_LOGGING
|
||||
|
||||
FILE *CPUINSTRUCTIONLOG;
|
||||
int cpu_disable_instruction_log = TRUE;
|
||||
|
||||
void cpuInstructionLogOpen(void)
|
||||
{
|
||||
if (CPUINSTRUCTIONLOG == NULL)
|
||||
{
|
||||
char filename[MAX_PATH];
|
||||
fileopsGetGenericFileName(filename, "WinFellow", "cpuinstructions.log");
|
||||
CPUINSTRUCTIONLOG = fopen(filename, "w");
|
||||
}
|
||||
}
|
||||
|
||||
void cpuIntegrationPrintBusCycle(void)
|
||||
{
|
||||
fprintf(CPUINSTRUCTIONLOG, "%d:%.5d ", bus.frame_no, bus.cycle);
|
||||
}
|
||||
|
||||
void cpuIntegrationInstructionLogging(void)
|
||||
{
|
||||
char saddress[256], sdata[256], sinstruction[256], soperands[256];
|
||||
|
||||
if (cpu_disable_instruction_log) return;
|
||||
cpuInstructionLogOpen();
|
||||
/*
|
||||
fprintf(CPUINSTRUCTIONLOG,
|
||||
"D0:%.8X D1:%.8X D2:%.8X D3:%.8X D4:%.8X D5:%.8X D6:%.8X D7:%.8X\n",
|
||||
cpuGetDReg(0),
|
||||
cpuGetDReg(1),
|
||||
cpuGetDReg(2),
|
||||
cpuGetDReg(3),
|
||||
cpuGetDReg(4),
|
||||
cpuGetDReg(5),
|
||||
cpuGetDReg(6),
|
||||
cpuGetDReg(7));
|
||||
|
||||
fprintf(CPUINSTRUCTIONLOG,
|
||||
"A0:%.8X A1:%.8X A2:%.8X A3:%.8X A4:%.8X A5:%.8X A6:%.8X A7:%.8X\n",
|
||||
cpuGetAReg(0),
|
||||
cpuGetAReg(1),
|
||||
cpuGetAReg(2),
|
||||
cpuGetAReg(3),
|
||||
cpuGetAReg(4),
|
||||
cpuGetAReg(5),
|
||||
cpuGetAReg(6),
|
||||
cpuGetAReg(7));
|
||||
*/
|
||||
saddress[0] = '\0';
|
||||
sdata[0] = '\0';
|
||||
sinstruction[0] = '\0';
|
||||
soperands[0] = '\0';
|
||||
cpuDisOpcode(cpuGetPC(), saddress, sdata, sinstruction, soperands);
|
||||
fprintf(CPUINSTRUCTIONLOG, "SSP:%.6X USP:%.6X SP:%.4X %s %s\t%s\t%s\n", cpuGetSspDirect(), cpuGetUspDirect(), cpuGetSR(), saddress, sdata, sinstruction, soperands);
|
||||
}
|
||||
|
||||
void cpuIntegrationExceptionLogging(STR *description, ULO original_pc, UWO opcode)
|
||||
{
|
||||
if (cpu_disable_instruction_log) return;
|
||||
cpuInstructionLogOpen();
|
||||
|
||||
cpuIntegrationPrintBusCycle();
|
||||
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()));
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
void cpuIntegrationExecuteInstructionEventHandler68000Fast(void)
|
||||
{
|
||||
ULO cycles;
|
||||
cycles = cpuExecuteInstruction();
|
||||
|
||||
if (cpuGetStop())
|
||||
{
|
||||
cpuEvent.cycle = BUS_CYCLE_DISABLE;
|
||||
}
|
||||
else
|
||||
{
|
||||
cpuEvent.cycle += ((cycles*cpuIntegrationGetChipSlowdown())>>1) + cpuIntegrationGetChipCycles();
|
||||
}
|
||||
cpuIntegrationSetChipCycles(0);
|
||||
}
|
||||
|
||||
void cpuIntegrationExecuteInstructionEventHandler68000General(void)
|
||||
{
|
||||
ULO cycles = 0;
|
||||
ULO time_used = 0;
|
||||
|
||||
do
|
||||
{
|
||||
cycles = cpuExecuteInstruction();
|
||||
cycles = cycles*cpuIntegrationGetChipSlowdown(); // Compensate for blitter time
|
||||
time_used += (cpuIntegrationGetChipCycles()<<12) + (cycles<<cpuIntegrationGetSpeedMultiplier());
|
||||
}
|
||||
while (time_used < 8192 && !cpuGetStop());
|
||||
|
||||
if (cpuGetStop())
|
||||
{
|
||||
cpuEvent.cycle = BUS_CYCLE_DISABLE;
|
||||
}
|
||||
else
|
||||
{
|
||||
cpuEvent.cycle += (time_used>>12);
|
||||
}
|
||||
cpuIntegrationSetChipCycles(0);
|
||||
}
|
||||
|
||||
void cpuIntegrationExecuteInstructionEventHandler68020(void)
|
||||
{
|
||||
ULO time_used = 0;
|
||||
do
|
||||
{
|
||||
cpuExecuteInstruction();
|
||||
time_used += (cpuIntegrationGetChipCycles()<<12) + (4<<cpuIntegrationGetSpeedMultiplier());
|
||||
}
|
||||
while (time_used < 8192 && !cpuGetStop());
|
||||
|
||||
if (cpuGetStop())
|
||||
{
|
||||
cpuEvent.cycle = BUS_CYCLE_DISABLE;
|
||||
}
|
||||
else
|
||||
{
|
||||
cpuEvent.cycle += (time_used>>12);
|
||||
}
|
||||
cpuIntegrationSetChipCycles(0);
|
||||
}
|
||||
|
||||
void cpuIntegrationSetDefaultConfig(void)
|
||||
{
|
||||
cpuIntegrationSetModel(M68000);
|
||||
cpuIntegrationSetChipCycles(0);
|
||||
cpuIntegrationSetChipSlowdown(1);
|
||||
cpuIntegrationSetSpeed(4);
|
||||
|
||||
cpuSetCheckPendingInterruptsFunc(cpuIntegrationCheckPendingInterruptsFunc);
|
||||
cpuSetMidInstructionExceptionFunc(cpuIntegrationMidInstructionExceptionFunc);
|
||||
cpuSetResetExceptionFunc(cpuIntegrationResetExceptionFunc);
|
||||
|
||||
#ifdef CPU_INSTRUCTION_LOGGING
|
||||
cpuSetInstructionLoggingFunc(cpuIntegrationInstructionLogging);
|
||||
cpuSetExceptionLoggingFunc(cpuIntegrationExceptionLogging);
|
||||
cpuSetInterruptLoggingFunc(cpuIntegrationInterruptLogging);
|
||||
#endif
|
||||
}
|
||||
|
||||
/*=========================*/
|
||||
/* Fellow lifecycle events */
|
||||
/*=========================*/
|
||||
|
||||
void cpuIntegrationSaveState(FILE *F)
|
||||
{
|
||||
cpuSaveState(F);
|
||||
|
||||
fwrite(&cpu_integration_chip_slowdown, sizeof(cpu_integration_chip_slowdown), 1, F);
|
||||
// Everything else is configuration options which will be set when the associated config-file is loaded.
|
||||
}
|
||||
|
||||
void cpuIntegrationLoadState(FILE *F)
|
||||
{
|
||||
cpuLoadState(F);
|
||||
|
||||
fread(&cpu_integration_chip_slowdown, sizeof(cpu_integration_chip_slowdown), 1, F);
|
||||
// Everything else is configuration options which will be set when the associated config-file is loaded.
|
||||
}
|
||||
|
||||
void cpuIntegrationEmulationStart(void)
|
||||
{
|
||||
cpuIntegrationCalculateMultiplier();
|
||||
}
|
||||
|
||||
void cpuIntegrationEmulationStop(void)
|
||||
{
|
||||
}
|
||||
|
||||
void cpuIntegrationHardReset(void)
|
||||
{
|
||||
cpuIntegrationSetChipCycles(0);
|
||||
cpuIntegrationSetChipSlowdown(1);
|
||||
cpuSetInitialPC(memoryInitialPC());
|
||||
cpuSetInitialSP(memoryInitialSP());
|
||||
cpuHardReset();
|
||||
}
|
||||
|
||||
void cpuIntegrationStartup(void)
|
||||
{
|
||||
cpuStartup();
|
||||
cpuIntegrationSetDefaultConfig();
|
||||
cpuCreateMulTimeTables();
|
||||
}
|
||||
|
||||
void cpuIntegrationShutdown(void)
|
||||
{
|
||||
cpuProfileWrite();
|
||||
}
|
|
@ -0,0 +1,44 @@
|
|||
#ifndef CpuIntegration_H
|
||||
#define CpuIntegration_H
|
||||
|
||||
typedef enum {
|
||||
M68000 = 0,
|
||||
M68010 = 1,
|
||||
M68020 = 2,
|
||||
M68030 = 3,
|
||||
M68EC30 = 4,
|
||||
M68EC20 = 9
|
||||
} cpu_integration_models;
|
||||
|
||||
extern void cpuIntegrationSetUpInterruptEventHandler(void);
|
||||
extern void cpuIntegrationExecuteInstructionEventHandler68000Fast(void);
|
||||
extern void cpuIntegrationExecuteInstructionEventHandler68000General(void);
|
||||
extern void cpuIntegrationExecuteInstructionEventHandler68020(void);
|
||||
extern void cpuIntegrationCheckPendingInterrupts(void);
|
||||
extern ULO cpuIntegrationDisOpcode(ULO disasm_pc, STR *saddress, STR *sdata, STR *sinstruction, STR *soperands);
|
||||
|
||||
extern BOOLE cpuIntegrationSetModel(cpu_integration_models model);
|
||||
extern cpu_integration_models cpuIntegrationGetModel(void);
|
||||
extern ULO cpuIntegrationGetModelMajor(void);
|
||||
extern ULO cpuIntegrationGetPC(void);
|
||||
|
||||
extern ULO cpuIntegrationGetInstructionTime(void);
|
||||
extern void cpuIntegrationSetSpeed(ULO speed);
|
||||
extern ULO cpuIntegrationGetSpeed(void);
|
||||
extern void cpuIntegrationSetChipCycles(ULO chip_cycles);
|
||||
extern ULO cpuIntegrationGetChipCycles(void);
|
||||
extern void cpuIntegrationSetChipSlowdown(ULO chip_slowdown);
|
||||
extern ULO cpuIntegrationGetChipSlowdown(void);
|
||||
|
||||
extern jmp_buf cpu_integration_exception_buffer;
|
||||
|
||||
// Fellow limecycle events
|
||||
extern void cpuIntegrationSaveState(FILE *F);
|
||||
extern void cpuIntegrationLoadState(FILE *F);
|
||||
extern void cpuIntegrationEmulationStart(void);
|
||||
extern void cpuIntegrationEmulationStop(void);
|
||||
extern void cpuIntegrationHardReset(void);
|
||||
extern void cpuIntegrationStartup(void);
|
||||
extern void cpuIntegrationShutdown(void);
|
||||
|
||||
#endif
|
|
@ -0,0 +1,80 @@
|
|||
/* @(#) $Id: CpuModule.c,v 1.7 2012/08/12 16:51:02 peschau Exp $ */
|
||||
/*=========================================================================*/
|
||||
/* Fellow */
|
||||
/* Initialization of 68000 core */
|
||||
/* */
|
||||
/* Author: Petter Schau */
|
||||
/* */
|
||||
/* Copyright (C) 1991, 1992, 1996 Free Software Foundation, Inc. */
|
||||
/* */
|
||||
/* This program is free software; you can redistribute it and/or modify */
|
||||
/* it under the terms of the GNU General Public License as published by */
|
||||
/* the Free Software Foundation; either version 2, or (at your option) */
|
||||
/* any later version. */
|
||||
/* */
|
||||
/* This program is distributed in the hope that it will be useful, */
|
||||
/* but WITHOUT ANY WARRANTY; without even the implied warranty of */
|
||||
/* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the */
|
||||
/* GNU General Public License for more details. */
|
||||
/* */
|
||||
/* You should have received a copy of the GNU General Public License */
|
||||
/* along with this program; if not, write to the Free Software Foundation, */
|
||||
/* Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */
|
||||
/*=========================================================================*/
|
||||
|
||||
#include "defs.h"
|
||||
#include "CpuModule.h"
|
||||
#include "fellow.h"
|
||||
#include "fmem.h"
|
||||
#include "CpuModule_Internal.h"
|
||||
|
||||
void cpuClearEverything(void)
|
||||
{
|
||||
ULO i,j;
|
||||
|
||||
for (j = 0; j < 2; j++)
|
||||
for (i = 0; i < 8; i++)
|
||||
cpuSetReg(j, i, 0);
|
||||
|
||||
cpuSetUspDirect(0);
|
||||
cpuSetSspDirect(0);
|
||||
cpuSetMspDirect(0);
|
||||
cpuSetPC(0);
|
||||
cpuClearPrefetch();
|
||||
cpuSetVbr(0);
|
||||
cpuSetSR(0);
|
||||
cpuSetCacr(0);
|
||||
cpuSetCaar(0);
|
||||
cpuSetSfc(0);
|
||||
cpuSetDfc(0);
|
||||
cpuSetIrqLevel(0);
|
||||
cpuSetIrqAddress(0);
|
||||
cpuSetStop(FALSE);
|
||||
cpuSetInstructionTime(0);
|
||||
cpuSetOriginalPC(0);
|
||||
cpuSetInitialPC(0);
|
||||
cpuSetInitialSP(0);
|
||||
cpuSetModel(0, 0); // Also sets model-mask
|
||||
cpuSetCheckPendingInterruptsFunc(NULL);
|
||||
|
||||
#ifdef CPU_INSTRUCTION_LOGGING
|
||||
cpuSetCurrentOpcode(0);
|
||||
cpuSetInstructionLoggingFunc(NULL);
|
||||
cpuSetExceptionLoggingFunc(NULL);
|
||||
cpuSetInterruptLoggingFunc(NULL);
|
||||
#endif
|
||||
|
||||
cpuSetMidInstructionExceptionFunc(NULL);
|
||||
cpuSetResetExceptionFunc(NULL);
|
||||
}
|
||||
|
||||
void cpuHardReset(void)
|
||||
{
|
||||
cpuThrowResetException();
|
||||
cpuSetRaiseInterrupt(FALSE);
|
||||
}
|
||||
|
||||
void cpuStartup(void)
|
||||
{
|
||||
cpuClearEverything();
|
||||
}
|
|
@ -0,0 +1,93 @@
|
|||
#ifndef CpuModule_H
|
||||
#define CpuModule_H
|
||||
|
||||
// This header file defines the internal interfaces of the CPU module.
|
||||
|
||||
#define CPU_INSTRUCTION_LOGGING
|
||||
|
||||
// Function to check if there are any external interrupt sources wanting to issue interrupts
|
||||
typedef BOOLE (*cpuCheckPendingInterruptsFunc)(void);
|
||||
extern void cpuSetCheckPendingInterruptsFunc(cpuCheckPendingInterruptsFunc func);
|
||||
extern void cpuCheckPendingInterrupts(void);
|
||||
extern void cpuSetUpInterrupt(void);
|
||||
extern void cpuInitializeFromNewPC(ULO new_pc);
|
||||
|
||||
// Logging interface
|
||||
#ifdef CPU_INSTRUCTION_LOGGING
|
||||
|
||||
typedef void (*cpuInstructionLoggingFunc)(void);
|
||||
extern void cpuSetInstructionLoggingFunc(cpuInstructionLoggingFunc func);
|
||||
typedef void (*cpuExceptionLoggingFunc)(STR *description, ULO original_pc, UWO opcode);
|
||||
extern void cpuSetExceptionLoggingFunc(cpuExceptionLoggingFunc func);
|
||||
typedef void (*cpuInterruptLoggingFunc)(ULO level, ULO vector_address);
|
||||
extern void cpuSetInterruptLoggingFunc(cpuInterruptLoggingFunc func);
|
||||
|
||||
#endif
|
||||
|
||||
// CPU register and control properties
|
||||
extern void cpuSetPC(ULO pc);
|
||||
extern ULO cpuGetPC(void);
|
||||
|
||||
extern void cpuSetReg(ULO da, ULO i, ULO value);
|
||||
extern ULO cpuGetReg(ULO da, ULO i);
|
||||
|
||||
extern void cpuSetDReg(ULO i, ULO value);
|
||||
extern ULO cpuGetDReg(ULO i);
|
||||
|
||||
extern void cpuSetAReg(ULO i, ULO value);
|
||||
extern ULO cpuGetAReg(ULO i);
|
||||
|
||||
extern void cpuSetSR(ULO sr);
|
||||
extern ULO cpuGetSR(void);
|
||||
|
||||
extern void cpuSetUspDirect(ULO usp);
|
||||
extern ULO cpuGetUspDirect(void);
|
||||
extern ULO cpuGetUspAutoMap(void);
|
||||
|
||||
extern void cpuSetMspDirect(ULO msp);
|
||||
extern ULO cpuGetMspDirect(void);
|
||||
|
||||
extern void cpuSetSspDirect(ULO ssp);
|
||||
extern ULO cpuGetSspDirect(void);
|
||||
extern ULO cpuGetSspAutoMap(void);
|
||||
|
||||
extern ULO cpuGetVbr(void);
|
||||
|
||||
extern void cpuSetStop(BOOLE stop);
|
||||
extern BOOLE cpuGetStop(void);
|
||||
|
||||
extern void cpuSetInitialPC(ULO pc);
|
||||
extern ULO cpuGetInitialPC(void);
|
||||
|
||||
extern void cpuSetInitialSP(ULO sp);
|
||||
extern ULO cpuGetInitialSP(void);
|
||||
|
||||
extern ULO cpuGetInstructionTime(void);
|
||||
|
||||
extern void cpuSetIrqLevel(ULO irq_level);
|
||||
extern ULO cpuGetIrqLevel(void);
|
||||
|
||||
extern void cpuSetIrqAddress(ULO irq_address);
|
||||
extern ULO cpuGetIrqAddress(void);
|
||||
|
||||
extern ULO cpuExecuteInstruction(void);
|
||||
extern ULO cpuDisOpcode(ULO disasm_pc, STR *saddress, STR *sdata, STR *sinstruction, STR *soperands);
|
||||
|
||||
extern void cpuSaveState(FILE *F);
|
||||
extern void cpuLoadState(FILE *F);
|
||||
extern void cpuHardReset(void);
|
||||
extern void cpuStartup(void);
|
||||
|
||||
typedef void (*cpuMidInstructionExceptionFunc)(void);
|
||||
extern void cpuSetMidInstructionExceptionFunc(cpuMidInstructionExceptionFunc func);
|
||||
extern void cpuThrowAddressErrorException(void);
|
||||
|
||||
typedef void (*cpuResetExceptionFunc)(void);
|
||||
extern void cpuSetResetExceptionFunc(cpuResetExceptionFunc func);
|
||||
|
||||
// Configuration settings
|
||||
extern void cpuSetModel(ULO major, ULO minor);
|
||||
extern ULO cpuGetModelMajor(void);
|
||||
extern ULO cpuGetModelMinor(void);
|
||||
|
||||
#endif
|
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
|
@ -0,0 +1,97 @@
|
|||
#ifndef CPUMODULE_DISASSEMBLER_H
|
||||
#define CPUMODULE_DISASSEMBLER_H
|
||||
|
||||
extern ULO cpuDisOpcode(ULO disasm_pc, STR *saddress, STR *sdata, STR *sinstruction, STR *soperands);
|
||||
|
||||
extern ULO cpuDisIllegal(ULO prc, ULO opc, STR *sdata, STR *sinstruction, STR *soperands);
|
||||
extern ULO cpuDisAbcd(ULO prc, ULO opc, STR *sdata, STR *sinstruction, STR *soperands);
|
||||
extern ULO cpuDisAdd(ULO prc, ULO opc, STR *sdata, STR *sinstruction, STR *soperands);
|
||||
extern ULO cpuDisAdda(ULO prc, ULO opc, STR *sdata, STR *sinstruction, STR *soperands);
|
||||
extern ULO cpuDisAddi(ULO prc, ULO opc, STR *sdata, STR *sinstruction, STR *soperands);
|
||||
extern ULO cpuDisAddq(ULO prc, ULO opc, STR *sdata, STR *sinstruction, STR *soperands);
|
||||
extern ULO cpuDisAddx(ULO prc, ULO opc, STR *sdata, STR *sinstruction, STR *soperands);
|
||||
extern ULO cpuDisAnd(ULO prc, ULO opc, STR *sdata, STR *sinstruction, STR *soperands);
|
||||
extern ULO cpuDisAndi(ULO prc, ULO opc, STR *sdata, STR *sinstruction, STR *soperands);
|
||||
extern ULO cpuDisAsx(ULO prc, ULO opc, STR *sdata, STR *sinstruction, STR *soperands);
|
||||
extern ULO cpuDisBcc(ULO prc, ULO opc, STR *sdata, STR *sinstruction, STR *soperands);
|
||||
extern ULO cpuDisBt(ULO prc, ULO opc, STR *sdata, STR *sinstruction, STR *soperands);
|
||||
extern ULO cpuDisChk(ULO prc, ULO opc, STR *sdata, STR *sinstruction, STR *soperands);
|
||||
extern ULO cpuDisClr(ULO prc, ULO opc, STR *sdata, STR *sinstruction, STR *soperands);
|
||||
extern ULO cpuDisCmp(ULO prc, ULO opc, STR *sdata, STR *sinstruction, STR *soperands);
|
||||
extern ULO cpuDisCmpa(ULO prc, ULO opc, STR *sdata, STR *sinstruction, STR *soperands);
|
||||
extern ULO cpuDisCmpi(ULO prc, ULO opc, STR *sdata, STR *sinstruction, STR *soperands);
|
||||
extern ULO cpuDisCmpm(ULO prc, ULO opc, STR *sdata, STR *sinstruction, STR *soperands);
|
||||
extern ULO cpuDisDBcc(ULO prc, ULO opc, STR *sdata, STR *sinstruction, STR *soperands);
|
||||
extern ULO cpuDisDivs(ULO prc, ULO opc, STR *sdata, STR *sinstruction, STR *soperands);
|
||||
extern ULO cpuDisDivu(ULO prc, ULO opc, STR *sdata, STR *sinstruction, STR *soperands);
|
||||
extern ULO cpuDisEor(ULO prc, ULO opc, STR *sdata, STR *sinstruction, STR *soperands);
|
||||
extern ULO cpuDisEori(ULO prc, ULO opc, STR *sdata, STR *sinstruction, STR *soperands);
|
||||
extern ULO cpuDisExg(ULO prc, ULO opc, STR *sdata, STR *sinstruction, STR *soperands);
|
||||
extern ULO cpuDisExt(ULO prc, ULO opc, STR *sdata, STR *sinstruction, STR *soperands);
|
||||
extern ULO cpuDisJmp(ULO prc, ULO opc, STR *sdata, STR *sinstruction, STR *soperands);
|
||||
extern ULO cpuDisJsr(ULO prc, ULO opc, STR *sdata, STR *sinstruction, STR *soperands);
|
||||
extern ULO cpuDisLea(ULO prc, ULO opc, STR *sdata, STR *sinstruction, STR *soperands);
|
||||
extern ULO cpuDisLink(ULO prc, ULO opc, STR *sdata, STR *sinstruction, STR *soperands);
|
||||
extern ULO cpuDisLsx(ULO prc, ULO opc, STR *sdata, STR *sinstruction, STR *soperands);
|
||||
extern ULO cpuDisMove(ULO prc, ULO opc, STR *sdata, STR *sinstruction, STR *soperands);
|
||||
extern ULO cpuDisMoveToCcr(ULO prc, ULO opc, STR *sdata, STR *sinstruction, STR *soperands);
|
||||
extern ULO cpuDisMoveToSr(ULO prc, ULO opc, STR *sdata, STR *sinstruction, STR *soperands);
|
||||
extern ULO cpuDisMoveFromSr(ULO prc, ULO opc, STR *sdata, STR *sinstruction, STR *soperands);
|
||||
extern ULO cpuDisMoveUsp(ULO prc, ULO opc, STR *sdata, STR *sinstruction, STR *soperands);
|
||||
extern ULO cpuDisMovea(ULO prc, ULO opc, STR *sdata, STR *sinstruction, STR *soperands);
|
||||
extern ULO cpuDisMovem(ULO prc, ULO opc, STR *sdata, STR *sinstruction, STR *soperands);
|
||||
extern ULO cpuDisMovep(ULO prc, ULO opc, STR *sdata, STR *sinstruction, STR *soperands);
|
||||
extern ULO cpuDisMoveq(ULO prc, ULO opc, STR *sdata, STR *sinstruction, STR *soperands);
|
||||
extern ULO cpuDisMuls(ULO prc, ULO opc, STR *sdata, STR *sinstruction, STR *soperands);
|
||||
extern ULO cpuDisMulu(ULO prc, ULO opc, STR *sdata, STR *sinstruction, STR *soperands);
|
||||
extern ULO cpuDisNbcd(ULO prc, ULO opc, STR *sdata, STR *sinstruction, STR *soperands);
|
||||
extern ULO cpuDisNeg(ULO prc, ULO opc, STR *sdata, STR *sinstruction, STR *soperands);
|
||||
extern ULO cpuDisNegx(ULO prc, ULO opc, STR *sdata, STR *sinstruction, STR *soperands);
|
||||
extern ULO cpuDisNop(ULO prc, ULO opc, STR *sdata, STR *sinstruction, STR *soperands);
|
||||
extern ULO cpuDisNot(ULO prc, ULO opc, STR *sdata, STR *sinstruction, STR *soperands);
|
||||
extern ULO cpuDisOr(ULO prc, ULO opc, STR *sdata, STR *sinstruction, STR *soperands);
|
||||
extern ULO cpuDisOri(ULO prc, ULO opc, STR *sdata, STR *sinstruction, STR *soperands);
|
||||
extern ULO cpuDisPea(ULO prc, ULO opc, STR *sdata, STR *sinstruction, STR *soperands);
|
||||
extern ULO cpuDisReset(ULO prc, ULO opc, STR *sdata, STR *sinstruction, STR *soperands);
|
||||
extern ULO cpuDisRox(ULO prc, ULO opc, STR *sdata, STR *sinstruction, STR *soperands);
|
||||
extern ULO cpuDisRoxx(ULO prc, ULO opc, STR *sdata, STR *sinstruction, STR *soperands);
|
||||
extern ULO cpuDisRte(ULO prc, ULO opc, STR *sdata, STR *sinstruction, STR *soperands);
|
||||
extern ULO cpuDisRtr(ULO prc, ULO opc, STR *sdata, STR *sinstruction, STR *soperands);
|
||||
extern ULO cpuDisRts(ULO prc, ULO opc, STR *sdata, STR *sinstruction, STR *soperands);
|
||||
extern ULO cpuDisSbcd(ULO prc, ULO opc, STR *sdata, STR *sinstruction, STR *soperands);
|
||||
extern ULO cpuDisScc(ULO prc, ULO opc, STR *sdata, STR *sinstruction, STR *soperands);
|
||||
extern ULO cpuDisStop(ULO prc, ULO opc, STR *sdata, STR *sinstruction, STR *soperands);
|
||||
extern ULO cpuDisSub(ULO prc, ULO opc, STR *sdata, STR *sinstruction, STR *soperands);
|
||||
extern ULO cpuDisSuba(ULO prc, ULO opc, STR *sdata, STR *sinstruction, STR *soperands);
|
||||
extern ULO cpuDisSubi(ULO prc, ULO opc, STR *sdata, STR *sinstruction, STR *soperands);
|
||||
extern ULO cpuDisSubq(ULO prc, ULO opc, STR *sdata, STR *sinstruction, STR *soperands);
|
||||
extern ULO cpuDisSubx(ULO prc, ULO opc, STR *sdata, STR *sinstruction, STR *soperands);
|
||||
extern ULO cpuDisSwap(ULO prc, ULO opc, STR *sdata, STR *sinstruction, STR *soperands);
|
||||
extern ULO cpuDisTas(ULO prc, ULO opc, STR *sdata, STR *sinstruction, STR *soperands);
|
||||
extern ULO cpuDisTrap(ULO prc, ULO opc, STR *sdata, STR *sinstruction, STR *soperands);
|
||||
extern ULO cpuDisTrapv(ULO prc, ULO opc, STR *sdata, STR *sinstruction, STR *soperands);
|
||||
extern ULO cpuDisTst(ULO prc, ULO opc, STR *sdata, STR *sinstruction, STR *soperands);
|
||||
extern ULO cpuDisUnlk(ULO prc, ULO opc, STR *sdata, STR *sinstruction, STR *soperands);
|
||||
extern ULO cpuDisBkpt(ULO prc, ULO opc, STR *sdata, STR *sinstruction, STR *soperands);
|
||||
extern ULO cpuDisBf(ULO prc, ULO opc, STR *sdata, STR *sinstruction, STR *soperands);
|
||||
extern ULO cpuDisCas(ULO prc, ULO opc, STR *sdata, STR *sinstruction, STR *soperands);
|
||||
extern ULO cpuDisChkl(ULO prc, ULO opc, STR *sdata, STR *sinstruction, STR *soperands);
|
||||
extern ULO cpuDisChk2(ULO prc, ULO opc, STR *sdata, STR *sinstruction, STR *soperands);
|
||||
extern ULO cpuDisDivl(ULO prc, ULO opc, STR *sdata, STR *sinstruction, STR *soperands);
|
||||
extern ULO cpuDisExtb(ULO prc, ULO opc, STR *sdata, STR *sinstruction, STR *soperands);
|
||||
extern ULO cpuDisLinkl(ULO prc, ULO opc, STR *sdata, STR *sinstruction, STR *soperands);
|
||||
extern ULO cpuDisMoveFromCcr(ULO prc, ULO opc, STR *sdata, STR *sinstruction, STR *soperands);
|
||||
extern ULO cpuDisMovec(ULO prc, ULO opc, STR *sdata, STR *sinstruction, STR *soperands);
|
||||
extern ULO cpuDisMoves(ULO prc, ULO opc, STR *sdata, STR *sinstruction, STR *soperands);
|
||||
extern ULO cpuDisMull(ULO prc, ULO opc, STR *sdata, STR *sinstruction, STR *soperands);
|
||||
extern ULO cpuDisPack(ULO prc, ULO opc, STR *sdata, STR *sinstruction, STR *soperands);
|
||||
extern ULO cpuDisPflush030(ULO prc, ULO opc, STR *sdata, STR *sinstruction, STR *soperands);
|
||||
extern ULO cpuDisPflush040(ULO prc, ULO opc, STR *sdata, STR *sinstruction, STR *soperands);
|
||||
extern ULO cpuDisPtest040(ULO prc, ULO opc, STR *sdata, STR *sinstruction, STR *soperands);
|
||||
extern ULO cpuDisRtd(ULO prc, ULO opc, STR *sdata, STR *sinstruction, STR *soperands);
|
||||
extern ULO cpuDisTrapcc(ULO prc, ULO opc, STR *sdata, STR *sinstruction, STR *soperands);
|
||||
extern ULO cpuDisUnpk(ULO prc, ULO opc, STR *sdata, STR *sinstruction, STR *soperands);
|
||||
extern ULO cpuDisCallm(ULO prc, ULO opc, STR *sdata, STR *sinstruction, STR *soperands);
|
||||
extern ULO cpuDisRtm(ULO prc, ULO opc, STR *sdata, STR *sinstruction, STR *soperands);
|
||||
|
||||
#endif
|
File diff suppressed because it is too large
Load Diff
|
@ -0,0 +1,194 @@
|
|||
/* @(#) $Id: CpuModule_EffectiveAddress.c,v 1.3 2012/07/15 22:20:35 peschau Exp $ */
|
||||
/*=========================================================================*/
|
||||
/* Fellow */
|
||||
/* CPU 68k effective address calculation functions */
|
||||
/* */
|
||||
/* Author: Petter Schau */
|
||||
/* */
|
||||
/* */
|
||||
/* Copyright (C) 1991, 1992, 1996 Free Software Foundation, Inc. */
|
||||
/* */
|
||||
/* This program is free software; you can redistribute it and/or modify */
|
||||
/* it under the terms of the GNU General Public License as published by */
|
||||
/* the Free Software Foundation; either version 2, or (at your option) */
|
||||
/* any later version. */
|
||||
/* */
|
||||
/* This program is distributed in the hope that it will be useful, */
|
||||
/* but WITHOUT ANY WARRANTY; without even the implied warranty of */
|
||||
/* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the */
|
||||
/* GNU General Public License for more details. */
|
||||
/* */
|
||||
/* You should have received a copy of the GNU General Public License */
|
||||
/* along with this program; if not, write to the Free Software Foundation, */
|
||||
/* Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */
|
||||
/*=========================================================================*/
|
||||
|
||||
#include "defs.h"
|
||||
#include "fellow.h"
|
||||
#include "fmem.h"
|
||||
|
||||
#include "CpuModule.h"
|
||||
#include "CpuModule_Internal.h"
|
||||
|
||||
/* Calculates EA for (Ax). */
|
||||
ULO cpuEA02(ULO regno)
|
||||
{
|
||||
return cpuGetAReg(regno);
|
||||
}
|
||||
|
||||
/* Calculates EA for (Ax)+ */
|
||||
ULO cpuEA03(ULO regno, ULO size)
|
||||
{
|
||||
ULO tmp = cpuGetAReg(regno);
|
||||
if (regno == 7 && size == 1) size++;
|
||||
cpuSetAReg(regno, tmp + size);
|
||||
return tmp;
|
||||
}
|
||||
|
||||
/* Calculates EA for -(Ax) */
|
||||
ULO cpuEA04(ULO regno, ULO size)
|
||||
{
|
||||
if (regno == 7 && size == 1) size++;
|
||||
cpuSetAReg(regno, cpuGetAReg(regno) - size);
|
||||
return cpuGetAReg(regno);
|
||||
}
|
||||
|
||||
/* Calculates EA for disp16(Ax) */
|
||||
ULO cpuEA05(ULO regno)
|
||||
{
|
||||
return cpuGetAReg(regno) + cpuGetNextWordSignExt();
|
||||
}
|
||||
|
||||
/* Calculates EA for disp8(Ax,Ri.size) with 68020 extended modes. */
|
||||
static ULO cpuEA06Ext(UWO ext, ULO base_reg_value, ULO index_value)
|
||||
{
|
||||
ULO base_displacement;
|
||||
ULO outer_displacement;
|
||||
BOOLE index_register_suppressed = (ext & 0x0040);
|
||||
BOOLE base_register_suppressed = (ext & 0x0080);
|
||||
ULO base_displacement_size = (ext >> 4) & 3;
|
||||
ULO memory_indirect_action = (ext & 7);
|
||||
|
||||
if (memory_indirect_action == 4
|
||||
|| (memory_indirect_action > 4 && index_register_suppressed))
|
||||
{
|
||||
cpuThrowIllegalInstructionException(TRUE); /* Illegal instruction */
|
||||
// Never returns
|
||||
}
|
||||
|
||||
if (index_register_suppressed)
|
||||
{
|
||||
index_value = 0;
|
||||
}
|
||||
|
||||
if (base_register_suppressed)
|
||||
{
|
||||
base_reg_value = 0;
|
||||
}
|
||||
|
||||
switch (base_displacement_size)
|
||||
{
|
||||
case 0: /* Reserved */
|
||||
cpuThrowIllegalInstructionException(TRUE); /* Illegal instruction */
|
||||
break;
|
||||
case 1: /* Null base displacement */
|
||||
base_displacement = 0;
|
||||
break;
|
||||
case 2: /* Word base displacement */
|
||||
base_displacement = cpuGetNextWordSignExt();
|
||||
break;
|
||||
case 3: /* Long base displacement */
|
||||
base_displacement = cpuGetNextLong();
|
||||
break;
|
||||
}
|
||||
|
||||
switch (memory_indirect_action)
|
||||
{
|
||||
case 0: /* No memory indirect action */
|
||||
return base_reg_value + base_displacement + index_value;
|
||||
case 1: /* Indirect preindexed with null outer displacement */
|
||||
return memoryReadLong(base_reg_value + base_displacement + index_value);
|
||||
case 2: /* Indirect preindexed with word outer displacement */
|
||||
outer_displacement = cpuGetNextWordSignExt();
|
||||
return memoryReadLong(base_reg_value + base_displacement + index_value) + outer_displacement;
|
||||
case 3: /* Indirect preindexed with long outer displacement */
|
||||
outer_displacement = cpuGetNextLong();
|
||||
return memoryReadLong(base_reg_value + base_displacement + index_value) + outer_displacement;
|
||||
case 5: /* Indirect postindexed with null outer displacement, reserved for index register suppressed */
|
||||
return memoryReadLong(base_reg_value + base_displacement) + index_value;
|
||||
case 6: /* Indirect postindexed with word outer displacement, reserved for index register suppressed */
|
||||
outer_displacement = cpuGetNextWordSignExt();
|
||||
return memoryReadLong(base_reg_value + base_displacement) + index_value + outer_displacement;
|
||||
case 7: /* Indirect postindexed with long outer displacement, reserved for index register suppressed */
|
||||
outer_displacement = cpuGetNextLong();
|
||||
return memoryReadLong(base_reg_value + base_displacement) + index_value + outer_displacement;
|
||||
}
|
||||
return 0; /* Should never come here. */
|
||||
}
|
||||
|
||||
/* Calculates EA for disp8(Ax,Ri.size), calls cpuEA06Ext() for 68020 extended modes. */
|
||||
ULO cpuEA06(ULO regno)
|
||||
{
|
||||
ULO reg_value = cpuGetAReg(regno);
|
||||
UWO ext = cpuGetNextWord();
|
||||
ULO index_value = cpuGetReg(ext >> 15, (ext >> 12) & 7);
|
||||
if (!(ext & 0x0800))
|
||||
{
|
||||
index_value = cpuSignExtWordToLong((UWO)index_value);
|
||||
}
|
||||
if (cpuGetModelMajor() >= 2)
|
||||
{
|
||||
index_value = index_value << ((ext >> 9) & 3); /* Scaling index value */
|
||||
if (ext & 0x0100) /* Full extension word */
|
||||
{
|
||||
return cpuEA06Ext(ext, reg_value, index_value);
|
||||
}
|
||||
}
|
||||
return reg_value + index_value + cpuSignExtByteToLong((UBY)ext);
|
||||
}
|
||||
|
||||
/* Calculates EA for xxxx.W */
|
||||
ULO cpuEA70(void)
|
||||
{
|
||||
return cpuGetNextWordSignExt();
|
||||
}
|
||||
|
||||
/* Calculates EA for xxxxxxxx.L */
|
||||
ULO cpuEA71(void)
|
||||
{
|
||||
return cpuGetNextLong();
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Calculates EA for disp16(PC)
|
||||
/// </summary>
|
||||
/// <returns>Address</returns>
|
||||
ULO cpuEA72(void)
|
||||
{
|
||||
ULO pc_tmp = cpuGetPC();
|
||||
return pc_tmp + cpuGetNextWordSignExt();
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Calculates EA for disp8(PC,Ri.size). Calls cpuEA06Ext() to calculate extended 68020 modes.
|
||||
/// </summary>
|
||||
/// <returns>Address</returns>
|
||||
ULO cpuEA73(void)
|
||||
{
|
||||
ULO reg_value = cpuGetPC();
|
||||
UWO ext = cpuGetNextWord();
|
||||
ULO index_value = cpuGetReg(ext >> 15, (ext >> 12) & 0x7);
|
||||
if (!(ext & 0x0800))
|
||||
{
|
||||
index_value = cpuSignExtWordToLong((UWO)index_value);
|
||||
}
|
||||
if (cpuGetModelMajor() >= 2)
|
||||
{
|
||||
index_value = index_value << ((ext >> 9) & 0x3); // Scaling index value
|
||||
if (ext & 0x0100) // Full extension word
|
||||
{
|
||||
return cpuEA06Ext(ext, reg_value, index_value);
|
||||
}
|
||||
}
|
||||
return reg_value + index_value + cpuSignExtByteToLong((UBY)ext);
|
||||
}
|
|
@ -0,0 +1,266 @@
|
|||
/* @(#) $Id: CpuModule_Exceptions.c,v 1.5 2012/08/12 16:51:02 peschau Exp $ */
|
||||
/*=========================================================================*/
|
||||
/* Fellow */
|
||||
/* CPU 68k exception handling functions */
|
||||
/* */
|
||||
/* Author: Petter Schau */
|
||||
/* */
|
||||
/* */
|
||||
/* Copyright (C) 1991, 1992, 1996 Free Software Foundation, Inc. */
|
||||
/* */
|
||||
/* This program is free software; you can redistribute it and/or modify */
|
||||
/* it under the terms of the GNU General Public License as published by */
|
||||
/* the Free Software Foundation; either version 2, or (at your option) */
|
||||
/* any later version. */
|
||||
/* */
|
||||
/* This program is distributed in the hope that it will be useful, */
|
||||
/* but WITHOUT ANY WARRANTY; without even the implied warranty of */
|
||||
/* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the */
|
||||
/* GNU General Public License for more details. */
|
||||
/* */
|
||||
/* You should have received a copy of the GNU General Public License */
|
||||
/* along with this program; if not, write to the Free Software Foundation, */
|
||||
/* Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */
|
||||
/*=========================================================================*/
|
||||
|
||||
#include "defs.h"
|
||||
#include "fellow.h"
|
||||
#include "fmem.h"
|
||||
|
||||
#include "CpuModule.h"
|
||||
#include "CpuModule_Internal.h"
|
||||
|
||||
/* Function for exiting from mid-instruction exceptions */
|
||||
static cpuMidInstructionExceptionFunc cpu_mid_instruction_exception_func;
|
||||
|
||||
static void cpuCallMidInstructionExceptionFunc(void)
|
||||
{
|
||||
cpu_mid_instruction_exception_func();
|
||||
}
|
||||
|
||||
void cpuSetMidInstructionExceptionFunc(cpuMidInstructionExceptionFunc func)
|
||||
{
|
||||
cpu_mid_instruction_exception_func = func;
|
||||
}
|
||||
|
||||
/* Function for notifying the emulator about a reset */
|
||||
static cpuResetExceptionFunc cpu_reset_exception_func;
|
||||
|
||||
void cpuCallResetExceptionFunc(void)
|
||||
{
|
||||
cpu_reset_exception_func();
|
||||
}
|
||||
|
||||
void cpuSetResetExceptionFunc(cpuResetExceptionFunc func)
|
||||
{
|
||||
cpu_reset_exception_func = func;
|
||||
}
|
||||
|
||||
static STR *cpuGetExceptionName(ULO vector_offset)
|
||||
{
|
||||
char *name;
|
||||
|
||||
if (vector_offset == 0x8)
|
||||
name = "Exception: 2 - Access fault";
|
||||
else if (vector_offset == 0xc)
|
||||
name = "Exception: 3 - Address error";
|
||||
else if (vector_offset == 0x10)
|
||||
name = "Exception: 4 - Illegal Instruction";
|
||||
else if (vector_offset == 0x14)
|
||||
name = "Exception: 5 - Integer division by zero";
|
||||
else if (vector_offset == 0x18)
|
||||
name = "Exception: 6 - CHK, CHK2";
|
||||
else if (vector_offset == 0x1c)
|
||||
name = "Exception: 7 - FTRAPcc, TRAPcc, TRAPV";
|
||||
else if (vector_offset == 0x20)
|
||||
name = "Exception: 8 - Privilege Violation";
|
||||
else if (vector_offset == 0x24)
|
||||
name = "Exception: 9 - Trace";
|
||||
else if (vector_offset == 0x28)
|
||||
name = "Exception: 10 - A-Line";
|
||||
else if (vector_offset == 0x2c)
|
||||
name = "Exception: 11 - F-Line";
|
||||
else if (vector_offset == 0x38)
|
||||
name = "Exception: 14 - Format error";
|
||||
else if (vector_offset >= 0x80 && vector_offset <= 0xbc)
|
||||
name = "Exception: TRAP";
|
||||
else
|
||||
name = "Exception: Unknown";
|
||||
|
||||
return name;
|
||||
}
|
||||
|
||||
/*===============================================
|
||||
Sets up an exception
|
||||
===============================================*/
|
||||
|
||||
void cpuThrowException(ULO vector_offset, ULO pc, BOOLE executejmp)
|
||||
{
|
||||
ULO vector_address;
|
||||
|
||||
#ifdef CPU_INSTRUCTION_LOGGING
|
||||
cpuCallExceptionLoggingFunc(cpuGetExceptionName(vector_offset), cpuGetOriginalPC(), cpuGetCurrentOpcode());
|
||||
#endif
|
||||
|
||||
cpuActivateSSP();
|
||||
cpuStackFrameGenerate((UWO) vector_offset, pc);
|
||||
|
||||
// read a memory position
|
||||
vector_address = memoryReadLong(cpuGetVbr() + vector_offset);
|
||||
if (cpuGetModelMajor() < 2 && vector_address & 0x1 && vector_offset == 0xc)
|
||||
{
|
||||
// Avoid endless loop that will crash the emulator.
|
||||
// The (odd) address error exception vector contained an odd address.
|
||||
cpuCallResetExceptionFunc();
|
||||
cpuHardReset();
|
||||
cpuSetInstructionTime(132);
|
||||
}
|
||||
else
|
||||
{
|
||||
// set supervisor modus
|
||||
cpuSetSR(cpuGetSR() | 0x2000);
|
||||
cpuSetSR(cpuGetSR() & 0x3fff);
|
||||
|
||||
// restart cpu, if needed
|
||||
cpuSetStop(FALSE);
|
||||
|
||||
cpuInitializeFromNewPC(vector_address);
|
||||
cpuSetInstructionTime(40);
|
||||
}
|
||||
|
||||
// If the exception happened mid-instruction...
|
||||
if (executejmp)
|
||||
{
|
||||
cpuCallMidInstructionExceptionFunc(); // Supposed to be doing setjmp/longjmp back to machine emulator code
|
||||
}
|
||||
}
|
||||
|
||||
void cpuThrowPrivilegeViolationException(void)
|
||||
{
|
||||
// The saved pc points to the instruction causing the violation
|
||||
// (And the kickstart excpects pc in the stack frame to be the opcode PC.)
|
||||
cpuThrowException(0x20, cpuGetOriginalPC(), FALSE);
|
||||
}
|
||||
|
||||
void cpuThrowIllegalInstructionException(BOOLE executejmp)
|
||||
{
|
||||
// The saved pc points to the illegal instruction
|
||||
cpuThrowException(0x10, cpuGetOriginalPC(), executejmp);
|
||||
}
|
||||
|
||||
void cpuThrowALineException(void)
|
||||
{
|
||||
// The saved pc points to the a-line instruction
|
||||
cpuThrowException(0x28, cpuGetOriginalPC(), FALSE);
|
||||
}
|
||||
|
||||
void cpuThrowFLineException(void)
|
||||
{
|
||||
// The saved pc points to the f-line instruction
|
||||
cpuThrowException(0x2c, cpuGetOriginalPC(), FALSE);
|
||||
}
|
||||
|
||||
void cpuThrowTrapVException(void)
|
||||
{
|
||||
// The saved pc points to the next instruction, which is now in pc
|
||||
cpuThrowException(0x1c, cpuGetPC(), FALSE);
|
||||
}
|
||||
|
||||
void cpuThrowDivisionByZeroException(BOOLE executejmp)
|
||||
{
|
||||
// The saved pc points to the next instruction, which is now in pc
|
||||
cpuThrowException(0x14, cpuGetPC(), executejmp);
|
||||
}
|
||||
|
||||
void cpuThrowTrapException(ULO vector_no)
|
||||
{
|
||||
// The saved pc points to the next instruction, which is now in pc
|
||||
cpuThrowException(0x80 + vector_no*4, cpuGetPC(), FALSE);
|
||||
}
|
||||
|
||||
void cpuThrowChkException(void)
|
||||
{
|
||||
// The saved pc points to the next instruction, which is now in pc
|
||||
cpuThrowException(0x18, cpuGetPC(), FALSE);
|
||||
}
|
||||
|
||||
void cpuThrowTraceException(void)
|
||||
{
|
||||
// The saved pc points to the next instruction, which is now in pc
|
||||
cpuThrowException(0x24, cpuGetPC(), FALSE);
|
||||
}
|
||||
|
||||
void cpuThrowAddressErrorException(void)
|
||||
{
|
||||
cpuThrowException(0xc, cpuGetPC(), TRUE);
|
||||
}
|
||||
|
||||
/*=================*/
|
||||
/* Reset exception */
|
||||
/*=================*/
|
||||
|
||||
static void cpuThrowResetException000(void)
|
||||
{
|
||||
cpuSetSR(cpuGetSR() & 0x271f); /* T = 0 */
|
||||
cpuSetSR(cpuGetSR() | 0x2700); /* S = 1, ilvl = 7 */
|
||||
cpuSetVbr(0);
|
||||
cpuSetSspDirect(cpuGetInitialSP()); /* ssp = fake vector 0 */
|
||||
cpuInitializeFromNewPC(cpuGetInitialPC()); /* pc = fake vector 1 */
|
||||
}
|
||||
|
||||
static void cpuThrowResetException010(void)
|
||||
{
|
||||
cpuSetSR(cpuGetSR() & 0x271f); /* T = 0 */
|
||||
cpuSetSR(cpuGetSR() | 0x2700); /* S = 1, ilvl = 7 */
|
||||
cpuSetVbr(0);
|
||||
cpuSetSspDirect(cpuGetInitialSP()); /* ssp = fake vector 0 */
|
||||
cpuInitializeFromNewPC(cpuGetInitialPC()); /* pc = fake vector 1 */
|
||||
}
|
||||
|
||||
static void cpuThrowResetException020(void)
|
||||
{
|
||||
cpuSetSR(cpuGetSR() & 0x271f); /* T1T0 = 0, M = 0 */
|
||||
cpuSetSR(cpuGetSR() | 0x2700); /* S = 1, ilvl = 7 */
|
||||
cpuSetVbr(0);
|
||||
cpuSetCacr(0); /* E = 0, F = 0 */
|
||||
cpuSetCaar(0);
|
||||
/* Invalidate cache, we don't have one */
|
||||
cpuSetSspDirect(cpuGetInitialSP()); /* ssp = fake vector 0 */
|
||||
cpuInitializeFromNewPC(cpuGetInitialPC()); /* pc = fake vector 1 */
|
||||
}
|
||||
|
||||
static void cpuThrowResetException030(void)
|
||||
{
|
||||
cpuSetSR(cpuGetSR() & 0x271f); /* T1T0 = 0, M = 0 */
|
||||
cpuSetSR(cpuGetSR() | 0x2700); /* S = 1, ilvl = 7 */
|
||||
cpuSetVbr(0);
|
||||
cpuSetCacr(0); /* E = 0, F = 0 */
|
||||
cpuSetCaar(0);
|
||||
/* Invalidate cache, we don't have one */
|
||||
cpuSetSspDirect(cpuGetInitialSP()); /* ssp = fake vector 0 */
|
||||
cpuInitializeFromNewPC(cpuGetInitialPC()); /* pc = fake vector 1 */
|
||||
}
|
||||
|
||||
/*============================*/
|
||||
/* Performs a Reset exception */
|
||||
/*============================*/
|
||||
|
||||
void cpuThrowResetException(void)
|
||||
{
|
||||
cpuSetStop(FALSE);
|
||||
switch (cpuGetModelMajor())
|
||||
{
|
||||
case 0:
|
||||
cpuThrowResetException000();
|
||||
break;
|
||||
case 1:
|
||||
cpuThrowResetException010();
|
||||
break;
|
||||
case 2:
|
||||
cpuThrowResetException020();
|
||||
break;
|
||||
case 3:
|
||||
cpuThrowResetException030();
|
||||
break;
|
||||
}
|
||||
}
|
|
@ -0,0 +1,578 @@
|
|||
/* @(#) $Id: CpuModule_Flags.c,v 1.3 2011/07/18 17:22:55 peschau Exp $ */
|
||||
/*=========================================================================*/
|
||||
/* Fellow */
|
||||
/* 68000 flag and condition code handling */
|
||||
/* */
|
||||
/* Author: Petter Schau */
|
||||
/* */
|
||||
/* Copyright (C) 1991, 1992, 1996 Free Software Foundation, Inc. */
|
||||
/* */
|
||||
/* This program is free software; you can redistribute it and/or modify */
|
||||
/* it under the terms of the GNU General Public License as published by */
|
||||
/* the Free Software Foundation; either version 2, or (at your option) */
|
||||
/* any later version. */
|
||||
/* */
|
||||
/* This program is distributed in the hope that it will be useful, */
|
||||
/* but WITHOUT ANY WARRANTY; without even the implied warranty of */
|
||||
/* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the */
|
||||
/* GNU General Public License for more details. */
|
||||
/* */
|
||||
/* You should have received a copy of the GNU General Public License */
|
||||
/* along with this program; if not, write to the Free Software Foundation, */
|
||||
/* Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */
|
||||
/*=========================================================================*/
|
||||
#include "defs.h"
|
||||
#include "fellow.h"
|
||||
#include "CpuModule.h"
|
||||
#include "CpuModule_Internal.h"
|
||||
|
||||
|
||||
/// Sets the Z flag for bit operations
|
||||
void cpuSetZFlagBitOpsB(UBY res)
|
||||
{
|
||||
ULO flags = cpu_sr & 0xfffb;
|
||||
if (res == 0) flags |= 4;
|
||||
cpu_sr = flags;
|
||||
}
|
||||
|
||||
/// Sets the Z flag for bit operations
|
||||
void cpuSetZFlagBitOpsL(ULO res)
|
||||
{
|
||||
ULO flags = cpu_sr & 0xfffb;
|
||||
if (res == 0) flags |= 4;
|
||||
cpu_sr = flags;
|
||||
}
|
||||
|
||||
// rm,dm,sm
|
||||
ULO cpu_xnvc_flag_add_table[2][2][2] = { 0,0x11,0x11,0x13,0xa,8,8,0x19};
|
||||
|
||||
/// <summary>
|
||||
/// Calculate XNVC flags of an add operation.
|
||||
/// </summary>
|
||||
/// <param name="rm">The MSB of the result.</param>
|
||||
/// <param name="dm">The MSB of the destination source.</param>
|
||||
/// <param name="sm">The MSB of the source.</param>
|
||||
static ULO cpuMakeFlagXNVCAdd(BOOLE rm, BOOLE dm, BOOLE sm)
|
||||
{
|
||||
return cpu_xnvc_flag_add_table[rm][dm][sm];
|
||||
}
|
||||
|
||||
// rm,dm,sm
|
||||
ULO cpu_nvc_flag_add_table[2][2][2] = { 0,1,1,3,0xa,8,8,9};
|
||||
|
||||
/// <summary>
|
||||
/// Calculate NVC flags of an add operation for instructions not setting X.
|
||||
/// </summary>
|
||||
/// <param name="rm">The MSB of the result.</param>
|
||||
/// <param name="dm">The MSB of the destination source.</param>
|
||||
/// <param name="sm">The MSB of the source.</param>
|
||||
static ULO cpuMakeFlagNVCAdd(BOOLE rm, BOOLE dm, BOOLE sm)
|
||||
{
|
||||
return cpu_nvc_flag_add_table[rm][dm][sm];
|
||||
}
|
||||
|
||||
// rm,dm,sm
|
||||
ULO cpu_xnvc_flag_sub_table[2][2][2] = { 0,0x11,2,0,0x19,0x1b,8,0x19};
|
||||
|
||||
/// <summary>
|
||||
/// Calculate XNVC flags of a sub operation.
|
||||
/// </summary>
|
||||
/// <param name="rm">The MSB of the result.</param>
|
||||
/// <param name="dm">The MSB of the destination source.</param>
|
||||
/// <param name="sm">The MSB of the source.</param>
|
||||
static ULO cpuMakeFlagXNVCSub(BOOLE rm, BOOLE dm, BOOLE sm)
|
||||
{
|
||||
return cpu_xnvc_flag_sub_table[rm][dm][sm];
|
||||
}
|
||||
|
||||
// rm,dm,sm
|
||||
ULO cpu_nvc_flag_sub_table[2][2][2] = { 0,1,2,0,9,0xb,8,9};
|
||||
|
||||
/// <summary>
|
||||
/// Calculate NVC flags of a sub operation for instructions not setting X.
|
||||
/// </summary>
|
||||
/// <param name="rm">The MSB of the result.</param>
|
||||
/// <param name="dm">The MSB of the destination source.</param>
|
||||
/// <param name="sm">The MSB of the source.</param>
|
||||
static ULO cpuMakeFlagNVCSub(BOOLE rm, BOOLE dm, BOOLE sm)
|
||||
{
|
||||
return cpu_nvc_flag_sub_table[rm][dm][sm];
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Set the X and C flags to the value f.
|
||||
/// </summary>
|
||||
/// <param name="f">The new state of the flags.</param>
|
||||
void cpuSetFlagXC(BOOLE f)
|
||||
{
|
||||
cpu_sr = (cpu_sr & 0xffee) | ((f) ? 0x11 : 0);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Set the C flag to the value f.
|
||||
/// </summary>
|
||||
/// <param name="f">The new state of the flag.</param>
|
||||
void cpuSetFlagC(BOOLE f)
|
||||
{
|
||||
cpu_sr = (cpu_sr & 0xfffe) | ((f) ? 1 : 0);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Set the V flag.
|
||||
/// </summary>
|
||||
/// <param name="f">The new state of the flag.</param>
|
||||
void cpuSetFlagV(BOOLE f)
|
||||
{
|
||||
cpu_sr = (cpu_sr & 0xfffd) | ((f) ? 2 : 0);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Clear the V flag.
|
||||
/// </summary>
|
||||
static void cpuClearFlagV(void)
|
||||
{
|
||||
cpu_sr = cpu_sr & 0xfffd;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Get the V flag.
|
||||
/// </summary>
|
||||
BOOLE cpuGetFlagV(void)
|
||||
{
|
||||
return cpu_sr & 0x2;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Set the N flag.
|
||||
/// </summary>
|
||||
/// <param name="f">The new state of the flag.</param>
|
||||
void cpuSetFlagN(BOOLE f)
|
||||
{
|
||||
cpu_sr = (cpu_sr & 0xfff7) | ((f) ? 8 : 0);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Set the Z flag.
|
||||
/// </summary>
|
||||
/// <param name="f">The new state of the flag.</param>
|
||||
void cpuSetFlagZ(BOOLE f)
|
||||
{
|
||||
cpu_sr = (cpu_sr & 0xfffb) | ((f) ? 4 : 0);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Clear the Z flag.
|
||||
/// </summary>
|
||||
static void cpuClearFlagZ(void)
|
||||
{
|
||||
cpu_sr = cpu_sr & 0xfffb;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Get the Z flag.
|
||||
/// </summary>
|
||||
static BOOLE cpuGetFlagZ(void)
|
||||
{
|
||||
return cpu_sr & 0x4;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Get the X flag.
|
||||
/// </summary>
|
||||
BOOLE cpuGetFlagX(void)
|
||||
{
|
||||
return cpu_sr & 0x10;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Set the flags.
|
||||
/// </summary>
|
||||
void cpuSetFlags0100(void)
|
||||
{
|
||||
cpu_sr = (cpu_sr & 0xfff0) | 4;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Clear V and C.
|
||||
/// </summary>
|
||||
static void cpuClearFlagsVC(void)
|
||||
{
|
||||
cpu_sr = cpu_sr & 0xfffc;
|
||||
}
|
||||
|
||||
UWO cpuGetZFlagB(UBY res) {return (UWO)((res) ? 0 : 4);}
|
||||
UWO cpuGetZFlagW(UWO res) {return (UWO)((res) ? 0 : 4);}
|
||||
UWO cpuGetZFlagL(ULO res) {return (UWO)((res) ? 0 : 4);}
|
||||
|
||||
UWO cpuGetNFlagB(UBY res) {return (UWO)((res & 0x80) >> 4);}
|
||||
UWO cpuGetNFlagW(UWO res) {return (UWO)((res & 0x8000) >> 12);}
|
||||
UWO cpuGetNFlagL(ULO res) {return (UWO)((res & 0x80000000) >> 28);}
|
||||
|
||||
/// <summary>
|
||||
/// Set the flags NZVC.
|
||||
/// </summary>
|
||||
/// <param name="z">The Z flag.</param>
|
||||
/// <param name="n">The N flag.</param>
|
||||
/// <param name="v">The V flag.</param>
|
||||
/// <param name="c">The C flag.</param>
|
||||
void cpuSetFlagsNZVC(BOOLE z, BOOLE n, BOOLE v, BOOLE c)
|
||||
{
|
||||
ULO flags = cpu_sr & 0xfff0;
|
||||
if (n) flags |= 8;
|
||||
else if (z) flags |= 4;
|
||||
if (v) flags |= 2;
|
||||
if (c) flags |= 1;
|
||||
cpu_sr = flags;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Set the flags VC.
|
||||
/// </summary>
|
||||
/// <param name="v">The V flag.</param>
|
||||
/// <param name="c">The C flag.</param>
|
||||
void cpuSetFlagsVC(BOOLE v, BOOLE c)
|
||||
{
|
||||
ULO flags = cpu_sr & 0xfffc;
|
||||
if (v) flags |= 2;
|
||||
if (c) flags |= 1;
|
||||
cpu_sr = flags;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Set the flags (all) of an add operation.
|
||||
/// </summary>
|
||||
/// <param name="z">The Z flag.</param>
|
||||
/// <param name="rm">The MSB of the result.</param>
|
||||
/// <param name="dm">The MSB of the destination source.</param>
|
||||
/// <param name="sm">The MSB of the source.</param>
|
||||
void cpuSetFlagsAdd(BOOLE z, BOOLE rm, BOOLE dm, BOOLE sm)
|
||||
{
|
||||
ULO flags = cpu_sr & 0xffe0;
|
||||
if (z) flags |= 4;
|
||||
flags |= cpuMakeFlagXNVCAdd(rm, dm, sm);
|
||||
cpu_sr = flags;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Set the flags (all) of a sub operation.
|
||||
/// </summary>
|
||||
/// <param name="z">The Z flag.</param>
|
||||
/// <param name="rm">The MSB of the result.</param>
|
||||
/// <param name="dm">The MSB of the destination source.</param>
|
||||
/// <param name="sm">The MSB of the source.</param>
|
||||
void cpuSetFlagsSub(BOOLE z, BOOLE rm, BOOLE dm, BOOLE sm)
|
||||
{
|
||||
ULO flags = cpu_sr & 0xffe0;
|
||||
if (z) flags |= 4;
|
||||
flags |= cpuMakeFlagXNVCSub(rm, dm, sm);
|
||||
cpu_sr = flags;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Set the flags (all) of an addx operation.
|
||||
/// </summary>
|
||||
/// <param name="z">The Z flag.</param>
|
||||
/// <param name="rm">The MSB of the result.</param>
|
||||
/// <param name="dm">The MSB of the destination source.</param>
|
||||
/// <param name="sm">The MSB of the source.</param>
|
||||
void cpuSetFlagsAddX(BOOLE z, BOOLE rm, BOOLE dm, BOOLE sm)
|
||||
{
|
||||
ULO flags = cpu_sr & ((z) ? 0xffe4 : 0xffe0); // Clear z if result is non-zero
|
||||
flags |= cpuMakeFlagXNVCAdd(rm, dm, sm);
|
||||
cpu_sr = flags;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Set the flags (all) of a subx operation.
|
||||
/// </summary>
|
||||
/// <param name="z">The Z flag.</param>
|
||||
/// <param name="rm">The MSB of the result.</param>
|
||||
/// <param name="dm">The MSB of the destination source.</param>
|
||||
/// <param name="sm">The MSB of the source.</param>
|
||||
void cpuSetFlagsSubX(BOOLE z, BOOLE rm, BOOLE dm, BOOLE sm)
|
||||
{
|
||||
ULO flags = cpu_sr & ((z) ? 0xffe4 : 0xffe0); // Clear z if result is non-zero
|
||||
flags |= cpuMakeFlagXNVCSub(rm, dm, sm);
|
||||
cpu_sr = flags;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Set the flags (all) of a neg operation.
|
||||
/// </summary>
|
||||
/// <param name="z">The Z flag.</param>
|
||||
/// <param name="rm">The MSB of the result.</param>
|
||||
/// <param name="dm">The MSB of the destination source.</param>
|
||||
void cpuSetFlagsNeg(BOOLE z, BOOLE rm, BOOLE dm)
|
||||
{
|
||||
ULO flags = cpu_sr & 0xffe0;
|
||||
if (z) flags |= 4;
|
||||
else
|
||||
{
|
||||
flags |= 0x11; // set XC if result is non-zero
|
||||
if (rm)
|
||||
{
|
||||
flags |= 8;
|
||||
if (dm) flags |= 2; // V
|
||||
}
|
||||
}
|
||||
cpu_sr = flags;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Set the flags (all) of a negx operation.
|
||||
/// </summary>
|
||||
/// <param name="z">The Z flag.</param>
|
||||
/// <param name="rm">The MSB of the result.</param>
|
||||
/// <param name="dm">The MSB of the destination source.</param>
|
||||
void cpuSetFlagsNegx(BOOLE z, BOOLE rm, BOOLE dm)
|
||||
{
|
||||
ULO flags = cpu_sr & ((z) ? 0xffe4 : 0xffe0); // Clear z if result is non-zero
|
||||
if (dm || rm)
|
||||
{
|
||||
flags |= 0x11; // XC
|
||||
if (rm)
|
||||
{
|
||||
flags |= 8;
|
||||
if (dm) flags |= 2; // V
|
||||
}
|
||||
}
|
||||
cpu_sr = flags;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Set the flags (all) of a cmp operation. (Same as sub, but no X.)
|
||||
/// </summary>
|
||||
/// <param name="z">The Z flag.</param>
|
||||
/// <param name="rm">The MSB of the result.</param>
|
||||
/// <param name="dm">The MSB of the destination source.</param>
|
||||
/// <param name="sm">The MSB of the source.</param>
|
||||
void cpuSetFlagsCmp(BOOLE z, BOOLE rm, BOOLE dm, BOOLE sm)
|
||||
{
|
||||
ULO flags = cpu_sr & 0xfff0;
|
||||
if (z) flags |= 4;
|
||||
flags |= cpuMakeFlagNVCSub(rm, dm, sm);
|
||||
cpu_sr = flags;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Set the flags of a 0 shift count operation.
|
||||
/// </summary>
|
||||
/// <param name="z">The Z flag.</param>
|
||||
/// <param name="rm">The MSB of the result.</param>
|
||||
void cpuSetFlagsShiftZero(BOOLE z, BOOLE rm)
|
||||
{
|
||||
ULO flags = cpu_sr & 0xfff0; // Always clearing the VC flag
|
||||
if (rm) flags |= 8;
|
||||
else if (z) flags |= 4;
|
||||
cpu_sr = flags;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Set the flags of a shift operation.
|
||||
/// </summary>
|
||||
/// <param name="z">The Z flag.</param>
|
||||
/// <param name="rm">The MSB of the result.</param>
|
||||
/// <param name="c">The carry of the result.</param>
|
||||
/// <param name="c">The overflow of the result.</param>
|
||||
void cpuSetFlagsShift(BOOLE z, BOOLE rm, BOOLE c, BOOLE v)
|
||||
{
|
||||
ULO flags = cpu_sr & 0xffe0;
|
||||
if (rm) flags |= 8;
|
||||
else if (z) flags |= 4;
|
||||
if (v) flags |= 2;
|
||||
if (c) flags |= 0x11;
|
||||
cpu_sr = flags;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Set the flags of a rotate operation.
|
||||
/// </summary>
|
||||
/// <param name="z">The Z flag.</param>
|
||||
/// <param name="rm">The MSB of the result.</param>
|
||||
/// <param name="c">The carry of the result.</param>
|
||||
void cpuSetFlagsRotate(BOOLE z, BOOLE rm, BOOLE c)
|
||||
{
|
||||
ULO flags = cpu_sr & 0xfff0; // Always clearing the V flag
|
||||
|
||||
if (rm) flags |= 8;
|
||||
else if (z) flags |= 4;
|
||||
if (c) flags |= 1;
|
||||
|
||||
cpu_sr = flags;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Set the flags of a rotate with x operation.
|
||||
/// </summary>
|
||||
/// <param name="z">The Z flag.</param>
|
||||
/// <param name="rm">The MSB of the result.</param>
|
||||
/// <param name="c">The extend bit and carry of the result.</param>
|
||||
void cpuSetFlagsRotateX(UWO z, UWO rm, UWO x)
|
||||
{
|
||||
cpu_sr = (cpu_sr & 0xffe0) | z | rm | x;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Set the flags (ZN00).
|
||||
/// </summary>
|
||||
void cpuSetFlagsNZ00NewB(UBY res)
|
||||
{
|
||||
ULO flag = cpu_sr & 0xfff0;
|
||||
if (res & 0x80) flag |= 0x8;
|
||||
else if (res == 0) flag |= 0x4;
|
||||
cpu_sr = flag;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Set the flags (ZN00).
|
||||
/// </summary>
|
||||
void cpuSetFlagsNZ00NewW(UWO res)
|
||||
{
|
||||
ULO flag = cpu_sr & 0xfff0;
|
||||
if (res & 0x8000) flag |= 0x8;
|
||||
else if (res == 0) flag |= 0x4;
|
||||
cpu_sr = flag;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Set the flags (ZN00).
|
||||
/// </summary>
|
||||
void cpuSetFlagsNZ00NewL(ULO res)
|
||||
{
|
||||
ULO flag = cpu_sr & 0xfff0;
|
||||
if (res & 0x80000000) flag |= 0x8;
|
||||
else if (res == 0) flag |= 0x4;
|
||||
cpu_sr = flag;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Set the flags (ZN00).
|
||||
/// </summary>
|
||||
void cpuSetFlagsNZ00New64(LLO res)
|
||||
{
|
||||
ULO flag = cpu_sr & 0xfff0;
|
||||
if (res < 0) flag |= 0x8;
|
||||
else if (res == 0) flag |= 0x4;
|
||||
cpu_sr = flag;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Set the 4 flags absolute.
|
||||
/// </summary>
|
||||
/// <param name="f">flags</param>
|
||||
void cpuSetFlagsAbs(UWO f)
|
||||
{
|
||||
cpu_sr = (cpu_sr & 0xfff0) | f;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Calculates the values for the condition codes.
|
||||
/// </summary>
|
||||
/// <returns>TRUE or FALSE</returns>
|
||||
BOOLE cpuCalculateConditionCode0(void)
|
||||
{
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
BOOLE cpuCalculateConditionCode1(void)
|
||||
{
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
BOOLE cpuCalculateConditionCode2(void)
|
||||
{
|
||||
return !(cpu_sr & 5); // HI - !C && !Z
|
||||
}
|
||||
|
||||
BOOLE cpuCalculateConditionCode3(void)
|
||||
{
|
||||
return cpu_sr & 5; // LS - C || Z
|
||||
}
|
||||
|
||||
BOOLE cpuCalculateConditionCode4(void)
|
||||
{
|
||||
return (~cpu_sr) & 1; // CC - !C
|
||||
}
|
||||
|
||||
BOOLE cpuCalculateConditionCode5(void)
|
||||
{
|
||||
return cpu_sr & 1; // CS - C
|
||||
}
|
||||
|
||||
BOOLE cpuCalculateConditionCode6(void)
|
||||
{
|
||||
return (~cpu_sr) & 4; // NE - !Z
|
||||
}
|
||||
|
||||
BOOLE cpuCalculateConditionCode7(void)
|
||||
{
|
||||
return cpu_sr & 4; // EQ - Z
|
||||
}
|
||||
|
||||
BOOLE cpuCalculateConditionCode8(void)
|
||||
{
|
||||
return (~cpu_sr) & 2; // VC - !V
|
||||
}
|
||||
|
||||
BOOLE cpuCalculateConditionCode9(void)
|
||||
{
|
||||
return cpu_sr & 2; // VS - V
|
||||
}
|
||||
|
||||
BOOLE cpuCalculateConditionCode10(void)
|
||||
{
|
||||
return (~cpu_sr) & 8; // PL - !N
|
||||
}
|
||||
|
||||
BOOLE cpuCalculateConditionCode11(void)
|
||||
{
|
||||
return cpu_sr & 8; // MI - N
|
||||
}
|
||||
|
||||
BOOLE cpuCalculateConditionCode12(void)
|
||||
{
|
||||
ULO tmp = cpu_sr & 0xa;
|
||||
return (tmp == 0xa) || (tmp == 0); // GE - (N && V) || (!N && !V)
|
||||
}
|
||||
|
||||
BOOLE cpuCalculateConditionCode13(void)
|
||||
{
|
||||
ULO tmp = cpu_sr & 0xa;
|
||||
return (tmp == 0x8) || (tmp == 0x2); // LT - (N && !V) || (!N && V)
|
||||
}
|
||||
|
||||
BOOLE cpuCalculateConditionCode14(void)
|
||||
{
|
||||
ULO tmp = cpu_sr & 0xa;
|
||||
return (!(cpu_sr & 0x4)) && ((tmp == 0xa) || (tmp == 0)); // GT - (N && V && !Z) || (!N && !V && !Z)
|
||||
}
|
||||
|
||||
BOOLE cpuCalculateConditionCode15(void)
|
||||
{
|
||||
ULO tmp = cpu_sr & 0xa;
|
||||
return (cpu_sr & 0x4) || (tmp == 0x8) || (tmp == 2);// LE - Z || (N && !V) || (!N && V)
|
||||
}
|
||||
|
||||
BOOLE cpuCalculateConditionCode(ULO cc)
|
||||
{
|
||||
switch (cc & 0xf)
|
||||
{
|
||||
case 0: return cpuCalculateConditionCode0();
|
||||
case 1: return cpuCalculateConditionCode1();
|
||||
case 2: return cpuCalculateConditionCode2();
|
||||
case 3: return cpuCalculateConditionCode3();
|
||||
case 4: return cpuCalculateConditionCode4();
|
||||
case 5: return cpuCalculateConditionCode5();
|
||||
case 6: return cpuCalculateConditionCode6();
|
||||
case 7: return cpuCalculateConditionCode7();
|
||||
case 8: return cpuCalculateConditionCode8();
|
||||
case 9: return cpuCalculateConditionCode9();
|
||||
case 10: return cpuCalculateConditionCode10();
|
||||
case 11: return cpuCalculateConditionCode11();
|
||||
case 12: return cpuCalculateConditionCode12();
|
||||
case 13: return cpuCalculateConditionCode13();
|
||||
case 14: return cpuCalculateConditionCode14();
|
||||
case 15: return cpuCalculateConditionCode15();
|
||||
}
|
||||
return FALSE;
|
||||
}
|
File diff suppressed because it is too large
Load Diff
|
@ -0,0 +1,200 @@
|
|||
#ifndef CpuModule_Internal_H
|
||||
#define CpuModule_Internal_H
|
||||
|
||||
// This header file defines the internal interfaces of the CPU module.
|
||||
extern void cpuMakeOpcodeTableForModel(void);
|
||||
extern void cpuCreateMulTimeTables(void);
|
||||
|
||||
// StackFrameGen
|
||||
extern void cpuStackFrameGenerate(UWO vector_no, ULO pc);
|
||||
extern void cpuStackFrameInit(void);
|
||||
|
||||
// Registers
|
||||
extern ULO cpu_sr; // Not static because the flags calculation uses it extensively
|
||||
extern BOOLE cpuGetFlagSupervisor(void);
|
||||
extern BOOLE cpuGetFlagMaster(void);
|
||||
extern void cpuSetUspDirect(ULO usp);
|
||||
extern ULO cpuGetUspDirect(void);
|
||||
extern ULO cpuGetUspAutoMap(void);
|
||||
extern void cpuSetSspDirect(ULO ssp);
|
||||
extern ULO cpuGetSspDirect(void);
|
||||
extern ULO cpuGetSspAutoMap(void);
|
||||
extern void cpuSetMspDirect(ULO msp);
|
||||
extern ULO cpuGetMspDirect(void);
|
||||
extern ULO cpuGetMspAutoMap(void);
|
||||
extern void cpuSetMspAutoMap(ULO new_msp);
|
||||
extern ULO cpuGetIspAutoMap(void);
|
||||
extern void cpuSetIspAutoMap(ULO new_isp);
|
||||
extern void cpuSetDReg(ULO i, ULO value);
|
||||
extern ULO cpuGetDReg(ULO i);
|
||||
extern void cpuSetAReg(ULO i, ULO value);
|
||||
extern ULO cpuGetAReg(ULO i);
|
||||
extern void cpuSetReg(ULO da, ULO i, ULO value);
|
||||
extern ULO cpuGetReg(ULO da, ULO i);
|
||||
extern void cpuSetPC(ULO address);
|
||||
extern ULO cpuGetPC(void);
|
||||
extern void cpuSetStop(BOOLE stop);
|
||||
extern BOOLE cpuGetStop(void);
|
||||
extern void cpuSetVbr(ULO vbr);
|
||||
extern ULO cpuGetVbr(void);
|
||||
extern void cpuSetSfc(ULO sfc);
|
||||
extern ULO cpuGetSfc(void);
|
||||
extern void cpuSetDfc(ULO dfc);
|
||||
extern ULO cpuGetDfc(void);
|
||||
extern void cpuSetCacr(ULO cacr);
|
||||
extern ULO cpuGetCacr(void);
|
||||
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 ULO cpuGetIrqLevel(void);
|
||||
extern void cpuSetIrqAddress(ULO irq_address);
|
||||
extern ULO cpuGetIrqAddress(void);
|
||||
extern void cpuSetInstructionTime(ULO cycles);
|
||||
extern ULO cpuGetInstructionTime(void);
|
||||
extern void cpuSetOriginalPC(ULO pc);
|
||||
extern ULO cpuGetOriginalPC(void);
|
||||
|
||||
#ifdef CPU_INSTRUCTION_LOGGING
|
||||
|
||||
extern void cpuSetCurrentOpcode(UWO opcode);
|
||||
extern UWO cpuGetCurrentOpcode(void);
|
||||
|
||||
#endif
|
||||
|
||||
extern void cpuProfileWrite(void);
|
||||
|
||||
extern void cpuSetModelMask(UBY model_mask);
|
||||
extern UBY cpuGetModelMask(void);
|
||||
extern void cpuSetDRegWord(ULO regno, UWO val);
|
||||
extern void cpuSetDRegByte(ULO regno, UBY val);
|
||||
extern UWO cpuGetRegWord(ULO i, ULO regno);
|
||||
extern UWO cpuGetDRegWord(ULO regno);
|
||||
extern UBY cpuGetDRegByte(ULO regno);
|
||||
extern ULO cpuGetDRegWordSignExtLong(ULO regno);
|
||||
extern UWO cpuGetDRegByteSignExtWord(ULO regno);
|
||||
extern ULO cpuGetDRegByteSignExtLong(ULO regno);
|
||||
extern UWO cpuGetARegWord(ULO regno);
|
||||
extern UBY cpuGetARegByte(ULO regno);
|
||||
|
||||
extern UWO cpuGetNextWord(void);
|
||||
extern ULO cpuGetNextWordSignExt(void);
|
||||
extern ULO cpuGetNextLong(void);
|
||||
extern void cpuSkipNextWord(void);
|
||||
extern void cpuSkipNextLong(void);
|
||||
extern void cpuClearPrefetch(void);
|
||||
extern void cpuValidateReadPointer(void);
|
||||
|
||||
extern void cpuInitializeFromNewPC(ULO new_pc);
|
||||
|
||||
// Effective address
|
||||
extern ULO cpuEA02(ULO regno);
|
||||
extern ULO cpuEA03(ULO regno, ULO size);
|
||||
extern ULO cpuEA04(ULO regno, ULO size);
|
||||
extern ULO cpuEA05(ULO regno);
|
||||
extern ULO cpuEA06(ULO regno);
|
||||
extern ULO cpuEA70(void);
|
||||
extern ULO cpuEA71(void);
|
||||
extern ULO cpuEA72(void);
|
||||
extern ULO cpuEA73(void);
|
||||
|
||||
// Flags
|
||||
extern void cpuSetFlagsAdd(BOOLE z, BOOLE rm, BOOLE dm, BOOLE sm);
|
||||
extern void cpuSetFlagsSub(BOOLE z, BOOLE rm, BOOLE dm, BOOLE sm);
|
||||
extern void cpuSetFlagsCmp(BOOLE z, BOOLE rm, BOOLE dm, BOOLE sm);
|
||||
extern void cpuSetZFlagBitOpsB(UBY res);
|
||||
extern void cpuSetZFlagBitOpsL(ULO res);
|
||||
|
||||
extern void cpuSetFlagsNZ00NewB(UBY res);
|
||||
extern void cpuSetFlagsNZ00NewW(UWO res);
|
||||
extern void cpuSetFlagsNZ00NewL(ULO res);
|
||||
extern void cpuSetFlagsNZ00New64(LLO res);
|
||||
|
||||
extern void cpuSetFlagZ(BOOLE f);
|
||||
extern void cpuSetFlagN(BOOLE f);
|
||||
extern void cpuSetFlagV(BOOLE f);
|
||||
extern void cpuSetFlagC(BOOLE f);
|
||||
extern void cpuSetFlagXC(BOOLE f);
|
||||
extern void cpuSetFlags0100(void);
|
||||
extern void cpuSetFlagsNeg(BOOLE z, BOOLE rm, BOOLE dm);
|
||||
extern BOOLE cpuGetFlagX(void);
|
||||
extern void cpuSetFlagsNegx(BOOLE z, BOOLE rm, BOOLE dm);
|
||||
extern BOOLE cpuGetFlagV(void);
|
||||
extern void cpuSetFlagsNZVC(BOOLE z, BOOLE n, BOOLE v, BOOLE c);
|
||||
extern void cpuSetFlagsVC(BOOLE v, BOOLE c);
|
||||
extern void cpuSetFlagsShiftZero(BOOLE z, BOOLE rm);
|
||||
extern void cpuSetFlagsShift(BOOLE z, BOOLE rm, BOOLE c, BOOLE v);
|
||||
extern void cpuSetFlagsRotate(BOOLE z, BOOLE rm, BOOLE c);
|
||||
extern void cpuSetFlagsRotateX(UWO z, UWO rm, UWO x);
|
||||
extern void cpuSetFlagsAddX(BOOLE z, BOOLE rm, BOOLE dm, BOOLE sm);
|
||||
extern void cpuSetFlagsSubX(BOOLE z, BOOLE rm, BOOLE dm, BOOLE sm);
|
||||
extern void cpuSetFlagsAbs(UWO f);
|
||||
extern UWO cpuGetZFlagB(UBY res);
|
||||
extern UWO cpuGetZFlagW(UWO res);
|
||||
extern UWO cpuGetZFlagL(ULO res);
|
||||
extern UWO cpuGetNFlagB(UBY res);
|
||||
extern UWO cpuGetNFlagW(UWO res);
|
||||
extern UWO cpuGetNFlagL(ULO res);
|
||||
|
||||
extern BOOLE cpuCalculateConditionCode0(void);
|
||||
extern BOOLE cpuCalculateConditionCode1(void);
|
||||
extern BOOLE cpuCalculateConditionCode2(void);
|
||||
extern BOOLE cpuCalculateConditionCode3(void);
|
||||
extern BOOLE cpuCalculateConditionCode4(void);
|
||||
extern BOOLE cpuCalculateConditionCode5(void);
|
||||
extern BOOLE cpuCalculateConditionCode6(void);
|
||||
extern BOOLE cpuCalculateConditionCode7(void);
|
||||
extern BOOLE cpuCalculateConditionCode8(void);
|
||||
extern BOOLE cpuCalculateConditionCode9(void);
|
||||
extern BOOLE cpuCalculateConditionCode10(void);
|
||||
extern BOOLE cpuCalculateConditionCode11(void);
|
||||
extern BOOLE cpuCalculateConditionCode12(void);
|
||||
extern BOOLE cpuCalculateConditionCode13(void);
|
||||
extern BOOLE cpuCalculateConditionCode14(void);
|
||||
extern BOOLE cpuCalculateConditionCode15(void);
|
||||
extern BOOLE cpuCalculateConditionCode(ULO cc);
|
||||
|
||||
// Logging
|
||||
#ifdef CPU_INSTRUCTION_LOGGING
|
||||
extern void cpuCallInstructionLoggingFunc(void);
|
||||
extern void cpuCallExceptionLoggingFunc(STR *description, ULO original_pc, UWO opcode);
|
||||
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);
|
||||
|
||||
// Exceptions
|
||||
extern void cpuThrowPrivilegeViolationException(void);
|
||||
extern void cpuThrowIllegalInstructionException(BOOLE executejmp);
|
||||
extern void cpuThrowFLineException(void);
|
||||
extern void cpuThrowALineException(void);
|
||||
extern void cpuThrowTrapVException(void);
|
||||
extern void cpuThrowTrapException(ULO vector_no);
|
||||
extern void cpuThrowDivisionByZeroException(BOOLE executejmp);
|
||||
extern void cpuThrowChkException(void);
|
||||
extern void cpuThrowTraceException(void);
|
||||
extern void cpuThrowResetException(void);
|
||||
extern void cpuCallResetExceptionFunc(void);
|
||||
extern void cpuFrame1(UWO vector_offset, ULO pc);
|
||||
|
||||
// Private help functions
|
||||
static ULO cpuSignExtByteToLong(UBY v) {return (ULO)(LON)(BYT) v;}
|
||||
static UWO cpuSignExtByteToWord(UBY v) {return (UWO)(WOR)(BYT) v;}
|
||||
static ULO cpuSignExtWordToLong(UWO v) {return (ULO)(LON)(WOR) v;}
|
||||
static ULO cpuJoinWordToLong(UWO upper, UWO lower) {return (((ULO)upper) << 16) | ((ULO)lower);}
|
||||
static ULO cpuJoinByteToLong(UBY upper, UBY midh, UBY midl, UBY lower) {return (((ULO)upper) << 24) | (((ULO)midh) << 16) | (((ULO)midl) << 8) | ((ULO)lower);}
|
||||
static UWO cpuJoinByteToWord(UBY upper, UBY lower) {return (((UWO)upper) << 8) | ((UWO)lower);}
|
||||
static BOOLE cpuMsbB(UBY v) {return v>>7;}
|
||||
static BOOLE cpuMsbW(UWO v) {return v>>15;}
|
||||
static BOOLE cpuMsbL(ULO v) {return v>>31;}
|
||||
static BOOLE cpuIsZeroB(UBY v) {return v == 0;}
|
||||
static BOOLE cpuIsZeroW(UWO v) {return v == 0;}
|
||||
static BOOLE cpuIsZeroL(ULO v) {return v == 0;}
|
||||
|
||||
|
||||
#endif
|
|
@ -0,0 +1,390 @@
|
|||
/* @(#) $Id: CpuModule_InternalState.c,v 1.9 2012/08/12 16:51:02 peschau Exp $ */
|
||||
/*=========================================================================*/
|
||||
/* Fellow */
|
||||
/* 68000 internal state */
|
||||
/* */
|
||||
/* Author: Petter Schau */
|
||||
/* */
|
||||
/* Copyright (C) 1991, 1992, 1996 Free Software Foundation, Inc. */
|
||||
/* */
|
||||
/* This program is free software; you can redistribute it and/or modify */
|
||||
/* it under the terms of the GNU General Public License as published by */
|
||||
/* the Free Software Foundation; either version 2, or (at your option) */
|
||||
/* any later version. */
|
||||
/* */
|
||||
/* This program is distributed in the hope that it will be useful, */
|
||||
/* but WITHOUT ANY WARRANTY; without even the implied warranty of */
|
||||
/* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the */
|
||||
/* GNU General Public License for more details. */
|
||||
/* */
|
||||
/* You should have received a copy of the GNU General Public License */
|
||||
/* along with this program; if not, write to the Free Software Foundation, */
|
||||
/* Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */
|
||||
/*=========================================================================*/
|
||||
#include "defs.h"
|
||||
#include "CpuModule.h"
|
||||
#include "fellow.h"
|
||||
#include "fmem.h"
|
||||
#include "CpuModule_Internal.h"
|
||||
|
||||
/* M68k registers */
|
||||
static ULO cpu_regs[2][8]; /* 0 - data, 1 - address */
|
||||
static ULO cpu_pc;
|
||||
static ULO cpu_usp;
|
||||
static ULO cpu_ssp;
|
||||
static ULO cpu_msp;
|
||||
static ULO cpu_sfc;
|
||||
static ULO cpu_dfc;
|
||||
ULO cpu_sr; // Not static because flags calculation use it extensively
|
||||
static ULO cpu_vbr;
|
||||
static UWO cpu_prefetch_word;
|
||||
static ULO cpu_cacr;
|
||||
static ULO cpu_caar;
|
||||
|
||||
/* Irq management */
|
||||
static BOOLE cpu_raise_irq;
|
||||
static ULO cpu_irq_level;
|
||||
static ULO cpu_irq_address;
|
||||
|
||||
/* Reset values */
|
||||
static ULO cpu_initial_pc;
|
||||
static ULO cpu_initial_sp;
|
||||
|
||||
/* Flag set if CPU is stopped */
|
||||
static BOOLE cpu_stop;
|
||||
|
||||
/* The current CPU model */
|
||||
static ULO cpu_model_major = -1;
|
||||
static ULO cpu_model_minor;
|
||||
static UBY cpu_model_mask;
|
||||
|
||||
/* For exception handling */
|
||||
#ifdef CPU_INSTRUCTION_LOGGING
|
||||
|
||||
static UWO cpu_current_opcode;
|
||||
|
||||
#endif
|
||||
|
||||
static ULO cpu_original_pc;
|
||||
|
||||
/* Number of cycles taken by the last intstruction */
|
||||
static ULO cpu_instruction_time;
|
||||
|
||||
/* Getters and setters */
|
||||
|
||||
void cpuSetDReg(ULO i, ULO value) {cpu_regs[0][i] = value;}
|
||||
ULO cpuGetDReg(ULO i) {return cpu_regs[0][i];}
|
||||
|
||||
void cpuSetAReg(ULO i, ULO value) {cpu_regs[1][i] = value;}
|
||||
ULO cpuGetAReg(ULO i) {return cpu_regs[1][i];}
|
||||
|
||||
void cpuSetReg(ULO da, ULO i, ULO value) {cpu_regs[da][i] = value;}
|
||||
ULO cpuGetReg(ULO da, ULO i) {return cpu_regs[da][i];}
|
||||
|
||||
/// <summary>
|
||||
/// Get the supervisor bit from sr.
|
||||
/// </summary>
|
||||
BOOLE cpuGetFlagSupervisor(void)
|
||||
{
|
||||
return cpu_sr & 0x2000;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Get the master/irq state bit from sr.
|
||||
/// </summary>
|
||||
BOOLE cpuGetFlagMaster(void)
|
||||
{
|
||||
return cpu_sr & 0x1000;
|
||||
}
|
||||
|
||||
void cpuSetUspDirect(ULO usp) {cpu_usp = usp;}
|
||||
ULO cpuGetUspDirect(void) {return cpu_usp;}
|
||||
ULO cpuGetUspAutoMap(void) {return (cpuGetFlagSupervisor()) ? cpuGetUspDirect() : cpuGetAReg(7);}
|
||||
|
||||
void cpuSetSspDirect(ULO ssp) {cpu_ssp = ssp;}
|
||||
ULO cpuGetSspDirect(void) {return cpu_ssp;}
|
||||
ULO cpuGetSspAutoMap(void) {return (cpuGetFlagSupervisor()) ? cpuGetAReg(7) : cpuGetSspDirect();}
|
||||
|
||||
void cpuSetMspDirect(ULO msp) {cpu_msp = msp;}
|
||||
ULO cpuGetMspDirect(void) {return cpu_msp;}
|
||||
|
||||
/// <summary>
|
||||
/// Returns the master stack pointer.
|
||||
/// </summary>
|
||||
ULO cpuGetMspAutoMap(void)
|
||||
{
|
||||
if (cpuGetFlagSupervisor() && cpuGetFlagMaster())
|
||||
{
|
||||
return cpuGetAReg(7);
|
||||
}
|
||||
return cpuGetMspDirect();
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Sets the master stack pointer.
|
||||
/// </summary>
|
||||
void cpuSetMspAutoMap(ULO new_msp)
|
||||
{
|
||||
if (cpuGetFlagSupervisor() && cpuGetFlagMaster())
|
||||
{
|
||||
cpuSetAReg(7, new_msp);
|
||||
}
|
||||
else
|
||||
{
|
||||
cpuSetMspDirect(new_msp);
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Returns the interrupt stack pointer. ssp is used as isp.
|
||||
/// </summary>
|
||||
ULO cpuGetIspAutoMap(void)
|
||||
{
|
||||
if (cpuGetFlagSupervisor() && !cpuGetFlagMaster())
|
||||
{
|
||||
return cpuGetAReg(7);
|
||||
}
|
||||
return cpuGetSspDirect();
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Sets the interrupt stack pointer. ssp is used as isp.
|
||||
/// </summary>
|
||||
void cpuSetIspAutoMap(ULO new_isp)
|
||||
{
|
||||
if (cpuGetFlagSupervisor() && !cpuGetFlagMaster())
|
||||
{
|
||||
cpuSetAReg(7, new_isp);
|
||||
}
|
||||
else
|
||||
{
|
||||
cpuSetSspDirect(new_isp);
|
||||
}
|
||||
}
|
||||
|
||||
void cpuSetPC(ULO address) {cpu_pc = address;}
|
||||
ULO cpuGetPC(void) {return cpu_pc;}
|
||||
|
||||
void cpuSetStop(BOOLE stop) {cpu_stop = stop;}
|
||||
BOOLE cpuGetStop(void) {return cpu_stop;}
|
||||
|
||||
void cpuSetVbr(ULO vbr) {cpu_vbr = vbr;}
|
||||
ULO cpuGetVbr(void) {return cpu_vbr;}
|
||||
|
||||
void cpuSetSfc(ULO sfc) {cpu_sfc = sfc;}
|
||||
ULO cpuGetSfc(void) {return cpu_sfc;}
|
||||
|
||||
void cpuSetDfc(ULO dfc) {cpu_dfc = dfc;}
|
||||
ULO cpuGetDfc(void) {return cpu_dfc;}
|
||||
|
||||
void cpuSetCacr(ULO cacr) {cpu_cacr = cacr;}
|
||||
ULO cpuGetCacr(void) {return cpu_cacr;}
|
||||
|
||||
void cpuSetCaar(ULO caar) {cpu_caar = caar;}
|
||||
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;}
|
||||
|
||||
void cpuSetOriginalPC(ULO pc) {cpu_original_pc = pc;}
|
||||
ULO cpuGetOriginalPC(void) {return cpu_original_pc;}
|
||||
|
||||
#ifdef CPU_INSTRUCTION_LOGGING
|
||||
|
||||
void cpuSetCurrentOpcode(UWO opcode) {cpu_current_opcode = opcode;}
|
||||
UWO cpuGetCurrentOpcode(void) {return cpu_current_opcode;}
|
||||
|
||||
#endif
|
||||
|
||||
void cpuSetRaiseInterrupt(BOOLE raise_irq) {cpu_raise_irq = raise_irq;}
|
||||
BOOLE cpuGetRaiseInterrupt(void) {return cpu_raise_irq;}
|
||||
|
||||
void cpuSetInitialPC(ULO pc) {cpu_initial_pc = pc;}
|
||||
ULO cpuGetInitialPC(void) {return cpu_initial_pc;}
|
||||
|
||||
void cpuSetInitialSP(ULO sp) {cpu_initial_sp = sp;}
|
||||
ULO cpuGetInitialSP(void) {return cpu_initial_sp;}
|
||||
|
||||
void cpuSetModelMask(UBY model_mask) {cpu_model_mask = model_mask;}
|
||||
UBY cpuGetModelMask(void) {return cpu_model_mask;}
|
||||
|
||||
ULO cpuGetModelMajor(void) {return cpu_model_major;}
|
||||
ULO cpuGetModelMinor(void) {return cpu_model_minor;}
|
||||
|
||||
static void cpuCalculateModelMask(void)
|
||||
{
|
||||
switch (cpuGetModelMajor())
|
||||
{
|
||||
case 0:
|
||||
cpuSetModelMask(0x01);
|
||||
break;
|
||||
case 1:
|
||||
cpuSetModelMask(0x02);
|
||||
break;
|
||||
case 2:
|
||||
cpuSetModelMask(0x04);
|
||||
break;
|
||||
case 3:
|
||||
cpuSetModelMask(0x08);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
void cpuSetModel(ULO major, ULO minor)
|
||||
{
|
||||
BOOLE makeOpcodeTable = (cpu_model_major != major);
|
||||
cpu_model_major = major;
|
||||
cpu_model_minor = minor;
|
||||
cpuCalculateModelMask();
|
||||
cpuStackFrameInit();
|
||||
if (makeOpcodeTable) cpuMakeOpcodeTableForModel();
|
||||
}
|
||||
|
||||
void cpuSetDRegWord(ULO regno, UWO val) {*((WOR*)&cpu_regs[0][regno]) = val;}
|
||||
void cpuSetDRegByte(ULO regno, UBY val) {*((UBY*)&cpu_regs[0][regno]) = val;}
|
||||
UWO cpuGetRegWord(ULO i, ULO regno) {return (UWO)cpu_regs[i][regno];}
|
||||
|
||||
UWO cpuGetDRegWord(ULO regno) {return (UWO)cpu_regs[0][regno];}
|
||||
UBY cpuGetDRegByte(ULO regno) {return (UBY)cpu_regs[0][regno];}
|
||||
|
||||
ULO cpuGetDRegWordSignExtLong(ULO regno) {return cpuSignExtWordToLong(cpuGetDRegWord(regno));}
|
||||
UWO cpuGetDRegByteSignExtWord(ULO regno) {return cpuSignExtByteToWord(cpuGetDRegByte(regno));}
|
||||
ULO cpuGetDRegByteSignExtLong(ULO regno) {return cpuSignExtByteToLong(cpuGetDRegByte(regno));}
|
||||
|
||||
UWO cpuGetARegWord(ULO regno) {return (UWO)cpu_regs[1][regno];}
|
||||
UBY cpuGetARegByte(ULO regno) {return (UBY)cpu_regs[1][regno];}
|
||||
|
||||
typedef UWO (*cpuGetWordFunc)(void);
|
||||
typedef ULO (*cpuGetLongFunc)(void);
|
||||
|
||||
static UWO cpuGetNextWordInternal(void)
|
||||
{
|
||||
UWO data = memoryReadWord(cpuGetPC() + 2);
|
||||
return data;
|
||||
}
|
||||
|
||||
static ULO cpuGetNextLongInternal(void)
|
||||
{
|
||||
ULO data = memoryReadLong(cpuGetPC() + 2);
|
||||
return data;
|
||||
}
|
||||
|
||||
UWO cpuGetNextWord(void)
|
||||
{
|
||||
UWO tmp = cpu_prefetch_word;
|
||||
cpu_prefetch_word = cpuGetNextWordInternal();
|
||||
cpuSetPC(cpuGetPC() + 2);
|
||||
return tmp;
|
||||
}
|
||||
|
||||
ULO cpuGetNextWordSignExt(void)
|
||||
{
|
||||
return cpuSignExtWordToLong(cpuGetNextWord());
|
||||
}
|
||||
|
||||
ULO cpuGetNextLong(void)
|
||||
{
|
||||
ULO tmp = cpu_prefetch_word << 16;
|
||||
ULO data = cpuGetNextLongInternal();
|
||||
cpu_prefetch_word = (UWO) data;
|
||||
cpuSetPC(cpuGetPC() + 4);
|
||||
return tmp | (data >> 16);
|
||||
}
|
||||
|
||||
void cpuInitializePrefetch(void)
|
||||
{
|
||||
cpu_prefetch_word = memoryReadWord(cpuGetPC());
|
||||
}
|
||||
|
||||
void cpuClearPrefetch(void)
|
||||
{
|
||||
cpu_prefetch_word = 0;
|
||||
}
|
||||
|
||||
void cpuSkipNextWord(void)
|
||||
{
|
||||
cpuSetPC(cpuGetPC() + 2);
|
||||
cpuInitializePrefetch();
|
||||
}
|
||||
|
||||
void cpuSkipNextLong(void)
|
||||
{
|
||||
cpuSetPC(cpuGetPC() + 4);
|
||||
cpuInitializePrefetch();
|
||||
}
|
||||
|
||||
void cpuInitializeFromNewPC(ULO new_pc)
|
||||
{
|
||||
cpuSetPC(new_pc);
|
||||
cpuInitializePrefetch();
|
||||
}
|
||||
|
||||
void cpuSaveState(FILE *F)
|
||||
{
|
||||
ULO i, j;
|
||||
|
||||
fwrite(&cpu_model_major, sizeof(cpu_model_major), 1, F);
|
||||
fwrite(&cpu_model_minor, sizeof(cpu_model_minor), 1, F);
|
||||
for (i = 0; i < 2; i++)
|
||||
{
|
||||
for (j = 0; j < 7; j++)
|
||||
{
|
||||
fwrite(&cpu_regs[i][j], sizeof(cpu_regs[i][j]), 1, F);
|
||||
}
|
||||
}
|
||||
fwrite(&cpu_pc, sizeof(cpu_pc), 1, F);
|
||||
fwrite(&cpu_usp, sizeof(cpu_usp), 1, F);
|
||||
fwrite(&cpu_ssp, sizeof(cpu_ssp), 1, F);
|
||||
fwrite(&cpu_msp, sizeof(cpu_msp), 1, F);
|
||||
fwrite(&cpu_sfc, sizeof(cpu_sfc), 1, F);
|
||||
fwrite(&cpu_dfc, sizeof(cpu_dfc), 1, F);
|
||||
fwrite(&cpu_sr, sizeof(cpu_sr), 1, F);
|
||||
fwrite(&cpu_prefetch_word, sizeof(cpu_prefetch_word), 1, 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);
|
||||
}
|
||||
|
||||
void cpuLoadState(FILE *F)
|
||||
{
|
||||
ULO i, j;
|
||||
|
||||
fread(&cpu_model_major, sizeof(cpu_model_major), 1, F);
|
||||
fread(&cpu_model_minor, sizeof(cpu_model_minor), 1, F);
|
||||
for (i = 0; i < 2; i++)
|
||||
{
|
||||
for (j = 0; j < 7; j++)
|
||||
{
|
||||
fread(&cpu_regs[i][j], sizeof(cpu_regs[i][j]), 1, F);
|
||||
}
|
||||
}
|
||||
fread(&cpu_pc, sizeof(cpu_pc), 1, F);
|
||||
fread(&cpu_usp, sizeof(cpu_usp), 1, F);
|
||||
fread(&cpu_ssp, sizeof(cpu_ssp), 1, F);
|
||||
fread(&cpu_msp, sizeof(cpu_msp), 1, F);
|
||||
fread(&cpu_sfc, sizeof(cpu_sfc), 1, F);
|
||||
fread(&cpu_dfc, sizeof(cpu_dfc), 1, F);
|
||||
fread(&cpu_sr, sizeof(cpu_sr), 1, F);
|
||||
fread(&cpu_prefetch_word, sizeof(cpu_prefetch_word), 1, 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.
|
||||
}
|
|
@ -0,0 +1,107 @@
|
|||
/* @(#) $Id: CpuModule_Interrupts.c,v 1.5 2012/08/12 16:51:02 peschau Exp $ */
|
||||
/*=========================================================================*/
|
||||
/* Fellow */
|
||||
/* 68000 interrupt handling */
|
||||
/* */
|
||||
/* Author: Petter Schau */
|
||||
/* */
|
||||
/* Copyright (C) 1991, 1992, 1996 Free Software Foundation, Inc. */
|
||||
/* */
|
||||
/* This program is free software; you can redistribute it and/or modify */
|
||||
/* it under the terms of the GNU General Public License as published by */
|
||||
/* the Free Software Foundation; either version 2, or (at your option) */
|
||||
/* any later version. */
|
||||
/* */
|
||||
/* This program is distributed in the hope that it will be useful, */
|
||||
/* but WITHOUT ANY WARRANTY; without even the implied warranty of */
|
||||
/* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the */
|
||||
/* GNU General Public License for more details. */
|
||||
/* */
|
||||
/* You should have received a copy of the GNU General Public License */
|
||||
/* along with this program; if not, write to the Free Software Foundation, */
|
||||
/* Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */
|
||||
/*=========================================================================*/
|
||||
#include "defs.h"
|
||||
#include "fellow.h"
|
||||
#include "fmem.h"
|
||||
|
||||
#include "CpuModule.h"
|
||||
#include "CpuModule_Internal.h"
|
||||
|
||||
/* 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();
|
||||
}
|
||||
|
||||
void cpuSetCheckPendingInterruptsFunc(cpuCheckPendingInterruptsFunc func)
|
||||
{
|
||||
cpu_check_pending_interrupts_func = func;
|
||||
}
|
||||
|
||||
ULO cpuActivateSSP(void)
|
||||
{
|
||||
ULO currentSP = cpuGetAReg(7);
|
||||
|
||||
// check supervisor bit number (bit 13) within the system byte of the status register
|
||||
if (!cpuGetFlagSupervisor())
|
||||
{
|
||||
// we are in user mode, thus save user stack pointer (USP)
|
||||
cpuSetUspDirect(currentSP);
|
||||
currentSP = cpuGetSspDirect();
|
||||
|
||||
if (cpuGetModelMajor() >= 2)
|
||||
{
|
||||
if (cpuGetFlagMaster())
|
||||
{
|
||||
currentSP = cpuGetMspDirect();
|
||||
}
|
||||
}
|
||||
cpuSetAReg(7, currentSP);
|
||||
}
|
||||
return currentSP;
|
||||
}
|
||||
|
||||
/*============================================================
|
||||
Transfers control to an interrupt routine
|
||||
============================================================*/
|
||||
|
||||
// Returns TRUE if the cpu was stopped
|
||||
void cpuSetUpInterrupt(void)
|
||||
{
|
||||
UWO vector_offset = (UWO) (0x60 + cpuGetIrqLevel()*4);
|
||||
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
|
||||
|
||||
#ifdef CPU_INSTRUCTION_LOGGING
|
||||
cpuCallInterruptLoggingFunc(cpuGetIrqLevel(), cpuGetIrqAddress());
|
||||
#endif
|
||||
|
||||
if (cpuGetModelMajor() >= 2 && cpuGetModelMajor() < 6)
|
||||
{
|
||||
if (cpuGetFlagMaster())
|
||||
{ // If the cpu was in master mode, preserve msp, and switch to using ssp (isp) in a7.
|
||||
ULO oldA7 = cpuGetAReg(7);
|
||||
cpuSetMspDirect(oldA7);
|
||||
cpuSetAReg(7, cpuGetSspDirect());
|
||||
cpuFrame1(vector_offset, cpuGetPC()); // Make the throwaway frame on ssp/isp
|
||||
cpuSetSR(cpuGetSR() & 0xefff); // Clear master bit
|
||||
}
|
||||
}
|
||||
cpuInitializeFromNewPC(cpuGetIrqAddress());
|
||||
cpuSetStop(FALSE);
|
||||
cpuSetRaiseInterrupt(FALSE);
|
||||
}
|
|
@ -0,0 +1,71 @@
|
|||
/* @(#) $Id: CpuModule_Logging.c,v 1.3 2012/08/12 16:51:02 peschau Exp $ */
|
||||
/*=========================================================================*/
|
||||
/* Fellow */
|
||||
/* CPU 68k logging functions */
|
||||
/* */
|
||||
/* Author: Petter Schau */
|
||||
/* */
|
||||
/* */
|
||||
/* Copyright (C) 1991, 1992, 1996 Free Software Foundation, Inc. */
|
||||
/* */
|
||||
/* This program is free software; you can redistribute it and/or modify */
|
||||
/* it under the terms of the GNU General Public License as published by */
|
||||
/* the Free Software Foundation; either version 2, or (at your option) */
|
||||
/* any later version. */
|
||||
/* */
|
||||
/* This program is distributed in the hope that it will be useful, */
|
||||
/* but WITHOUT ANY WARRANTY; without even the implied warranty of */
|
||||
/* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the */
|
||||
/* GNU General Public License for more details. */
|
||||
/* */
|
||||
/* You should have received a copy of the GNU General Public License */
|
||||
/* along with this program; if not, write to the Free Software Foundation, */
|
||||
/* Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */
|
||||
/*=========================================================================*/
|
||||
|
||||
#include "defs.h"
|
||||
#include "fellow.h"
|
||||
|
||||
#include "CpuModule.h"
|
||||
|
||||
#ifdef CPU_INSTRUCTION_LOGGING
|
||||
|
||||
/* Function for logging the intruction execution */
|
||||
static cpuInstructionLoggingFunc cpu_instruction_logging_func;
|
||||
static cpuExceptionLoggingFunc cpu_exception_logging_func;
|
||||
static cpuInterruptLoggingFunc cpu_interrupt_logging_func;
|
||||
|
||||
void cpuSetInstructionLoggingFunc(cpuInstructionLoggingFunc func)
|
||||
{
|
||||
cpu_instruction_logging_func = func;
|
||||
}
|
||||
|
||||
void cpuCallInstructionLoggingFunc(void)
|
||||
{
|
||||
if (cpu_instruction_logging_func != NULL)
|
||||
cpu_instruction_logging_func();
|
||||
}
|
||||
|
||||
void cpuSetExceptionLoggingFunc(cpuExceptionLoggingFunc func)
|
||||
{
|
||||
cpu_exception_logging_func = func;
|
||||
}
|
||||
|
||||
void cpuCallExceptionLoggingFunc(STR *description, ULO original_pc, UWO opcode)
|
||||
{
|
||||
if (cpu_exception_logging_func != NULL)
|
||||
cpu_exception_logging_func(description, original_pc, opcode);
|
||||
}
|
||||
|
||||
void cpuSetInterruptLoggingFunc(cpuInterruptLoggingFunc func)
|
||||
{
|
||||
cpu_interrupt_logging_func = func;
|
||||
}
|
||||
|
||||
void cpuCallInterruptLoggingFunc(ULO level, ULO vector_address)
|
||||
{
|
||||
if (cpu_interrupt_logging_func != NULL)
|
||||
cpu_interrupt_logging_func(level, vector_address);
|
||||
}
|
||||
|
||||
#endif
|
|
@ -0,0 +1,8 @@
|
|||
#ifndef CPUMODULE_PROFILE_H
|
||||
#define CPUMODULE_PROFILE_H
|
||||
|
||||
#include "fileops.h"
|
||||
void cpuProfileWrite(void)
|
||||
{
|
||||
}
|
||||
#endif
|
|
@ -0,0 +1,259 @@
|
|||
/* @(#) $Id: CpuModule_StackFrameGen.c,v 1.3 2011/07/18 17:22:55 peschau Exp $ */
|
||||
/*=========================================================================*/
|
||||
/* Fellow */
|
||||
/* 68000 stack frame generation */
|
||||
/* */
|
||||
/* Author: Petter Schau */
|
||||
/* */
|
||||
/* Copyright (C) 1991, 1992, 1996 Free Software Foundation, Inc. */
|
||||
/* */
|
||||
/* This program is free software; you can redistribute it and/or modify */
|
||||
/* it under the terms of the GNU General Public License as published by */
|
||||
/* the Free Software Foundation; either version 2, or (at your option) */
|
||||
/* any later version. */
|
||||
/* */
|
||||
/* This program is distributed in the hope that it will be useful, */
|
||||
/* but WITHOUT ANY WARRANTY; without even the implied warranty of */
|
||||
/* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the */
|
||||
/* GNU General Public License for more details. */
|
||||
/* */
|
||||
/* You should have received a copy of the GNU General Public License */
|
||||
/* along with this program; if not, write to the Free Software Foundation, */
|
||||
/* Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */
|
||||
/*=========================================================================*/
|
||||
#include "defs.h"
|
||||
#include "fellow.h"
|
||||
#include "fmem.h"
|
||||
|
||||
#include "CpuModule.h"
|
||||
#include "CpuModule_Internal.h"
|
||||
|
||||
/* Exception stack frame jmptables */
|
||||
typedef void(*cpuStackFrameGenFunc)(UWO, ULO);
|
||||
static cpuStackFrameGenFunc cpu_stack_frame_gen_func[64];
|
||||
|
||||
static void cpuSetStackFrameGenFunc(ULO vector_no, cpuStackFrameGenFunc func)
|
||||
{
|
||||
cpu_stack_frame_gen_func[vector_no] = func;
|
||||
}
|
||||
|
||||
/*========================================================================
|
||||
Group 1 Frame format
|
||||
|
||||
000: All, except bus and address error
|
||||
========================================================================*/
|
||||
|
||||
static void cpuFrameGroup1(UWO vector_offset, ULO pcPtr)
|
||||
{
|
||||
// save PC
|
||||
cpuSetAReg(7, cpuGetAReg(7) - 4);
|
||||
memoryWriteLong(pcPtr, cpuGetAReg(7));
|
||||
|
||||
// save SR
|
||||
cpuSetAReg(7, cpuGetAReg(7) - 2);
|
||||
memoryWriteWord((UWO)cpuGetSR(), cpuGetAReg(7));
|
||||
}
|
||||
|
||||
/*========================================================================
|
||||
Group 2 Frame format
|
||||
|
||||
000: Bus and address error
|
||||
|
||||
memory_fault_address contains the violating address
|
||||
memory_fault_read is TRUE if the access was a read
|
||||
========================================================================*/
|
||||
|
||||
static void cpuFrameGroup2(UWO vector_offset, ULO pcPtr)
|
||||
{
|
||||
// save PC
|
||||
cpuSetAReg(7, cpuGetAReg(7) - 4);
|
||||
memoryWriteLong(pcPtr, cpuGetAReg(7));
|
||||
|
||||
// save SR
|
||||
cpuSetAReg(7, cpuGetAReg(7) - 2);
|
||||
memoryWriteWord((UWO)cpuGetSR(), cpuGetAReg(7));
|
||||
|
||||
// fault address, skip ireg
|
||||
cpuSetAReg(7, cpuGetAReg(7) - 6);
|
||||
memoryWriteLong(memory_fault_address, cpuGetAReg(7));
|
||||
|
||||
cpuSetAReg(7, cpuGetAReg(7) - 2);
|
||||
memoryWriteLong(memory_fault_read << 4, cpuGetAReg(7));
|
||||
}
|
||||
|
||||
static void cpuFrame4Words(UWO frame_code, UWO vector_offset, ULO pc)
|
||||
{
|
||||
// save vector_offset word
|
||||
cpuSetAReg(7, cpuGetAReg(7) - 2);
|
||||
memoryWriteWord(frame_code | vector_offset, cpuGetAReg(7));
|
||||
|
||||
// save PC
|
||||
cpuSetAReg(7, cpuGetAReg(7) - 4);
|
||||
memoryWriteLong(pc, cpuGetAReg(7));
|
||||
|
||||
// save SR
|
||||
cpuSetAReg(7, cpuGetAReg(7) - 2);
|
||||
memoryWriteWord((UWO)cpuGetSR(), cpuGetAReg(7));
|
||||
}
|
||||
|
||||
|
||||
/*========================================================================
|
||||
Frame format $0, four word frame
|
||||
|
||||
Stack words:
|
||||
------------
|
||||
SR
|
||||
PCHI
|
||||
PCLO
|
||||
0000 Vector offset (4 upper bits are frame no., rest is vector offset)
|
||||
|
||||
010: All, except bus and address errors
|
||||
020: Irq, Format error, Trap #N, Illegal inst., A-line, F-line,
|
||||
Priv. violation, copr preinst
|
||||
030: Same as for 020
|
||||
========================================================================*/
|
||||
|
||||
static void cpuFrame0(UWO vector_offset, ULO pc)
|
||||
{
|
||||
cpuFrame4Words(0x0000, vector_offset, pc);
|
||||
}
|
||||
|
||||
/*========================================================================
|
||||
Frame format $1, 4 word throwaway frame
|
||||
|
||||
Stack words:
|
||||
------------
|
||||
SR
|
||||
PCHI
|
||||
PCLO
|
||||
0000 Vector offset (4 upper bits are frame no., rest is Vvctor offset)
|
||||
|
||||
020: Irq, second frame created
|
||||
030: Same as for 020
|
||||
040: Same as for 020
|
||||
========================================================================*/
|
||||
|
||||
void cpuFrame1(UWO vector_offset, ULO pc)
|
||||
{
|
||||
cpuFrame4Words(0x1000, vector_offset, pc);
|
||||
}
|
||||
|
||||
/*========================================================================
|
||||
Frame format $2
|
||||
|
||||
020: chk, chk2, cpTrapcc, trapcc, trapv, trace, zero divide, MMU config,
|
||||
copr postinst
|
||||
030: Same as for 020
|
||||
040: chk, chk2, FTrapcc, trapcc, trapv, trace, zero divide, address error,
|
||||
Unimplemented FPU inst.
|
||||
060: Same as for 040
|
||||
========================================================================*/
|
||||
|
||||
static void cpuFrame2(UWO vector_offset, ULO pc)
|
||||
{
|
||||
// save inst address
|
||||
cpuSetAReg(7, cpuGetAReg(7) - 4);
|
||||
memoryWriteLong(cpuGetOriginalPC(), cpuGetAReg(7));
|
||||
cpuFrame4Words(0x2000, vector_offset, pc);
|
||||
}
|
||||
|
||||
/*========================================================================
|
||||
Frame format $8
|
||||
|
||||
010: Bus and address error
|
||||
|
||||
========================================================================*/
|
||||
|
||||
static void cpuFrame8(UWO vector_offset, ULO pc)
|
||||
{
|
||||
cpuSetAReg(7, cpuGetAReg(7) - 50);
|
||||
cpuFrame4Words(0x8000, vector_offset, pc);
|
||||
}
|
||||
|
||||
/*========================================================================
|
||||
Frame format $A
|
||||
|
||||
020: Address or bus-error on instruction boundrary
|
||||
030: Same as for 020
|
||||
|
||||
Will not set any values beyond the format/offset word
|
||||
Fellow will always generate this frame for bus/address errors
|
||||
========================================================================*/
|
||||
|
||||
static void cpuFrameA(UWO vector_offset, ULO pc)
|
||||
{
|
||||
// save vector_offset offset
|
||||
cpuSetAReg(7, cpuGetAReg(7) - 24);
|
||||
cpuFrame4Words(0xa000, vector_offset, pc);
|
||||
}
|
||||
|
||||
void cpuStackFrameGenerate(UWO vector_offset, ULO pc)
|
||||
{
|
||||
cpu_stack_frame_gen_func[vector_offset>>2](vector_offset, pc);
|
||||
}
|
||||
|
||||
/*==================================*/
|
||||
/* Initialize stack frame jmptables */
|
||||
/*==================================*/
|
||||
|
||||
static void cpuStackFrameInitSetDefaultFunc(cpuStackFrameGenFunc default_func)
|
||||
{
|
||||
ULO i;
|
||||
for (i = 0; i < 64; i++)
|
||||
cpuSetStackFrameGenFunc(i, default_func);
|
||||
}
|
||||
|
||||
static void cpuStackFrameInit000(void)
|
||||
{
|
||||
cpuStackFrameInitSetDefaultFunc(cpuFrameGroup1);
|
||||
cpuSetStackFrameGenFunc(2, cpuFrameGroup2); /* 2 - Bus error */
|
||||
cpuSetStackFrameGenFunc(3, cpuFrameGroup2); /* 3 - Address error */
|
||||
}
|
||||
|
||||
static void cpuStackFrameInit010(void)
|
||||
{
|
||||
cpuStackFrameInitSetDefaultFunc(cpuFrame0);
|
||||
cpuSetStackFrameGenFunc(2, cpuFrame8); /* 2 - Bus error */
|
||||
cpuSetStackFrameGenFunc(3, cpuFrame8); /* 3 - Address error */
|
||||
}
|
||||
|
||||
static void cpuStackFrameInit020(void)
|
||||
{
|
||||
cpuStackFrameInitSetDefaultFunc(cpuFrame0);
|
||||
cpuSetStackFrameGenFunc(2, cpuFrameA); /* 2 - Bus Error */
|
||||
cpuSetStackFrameGenFunc(3, cpuFrameA); /* 3 - Addrss Error */
|
||||
cpuSetStackFrameGenFunc(5, cpuFrame2); /* 5 - Zero Divide */
|
||||
cpuSetStackFrameGenFunc(6, cpuFrame2); /* 6 - CHK, CHK2 */
|
||||
cpuSetStackFrameGenFunc(7, cpuFrame2); /* 7 - TRAPV, TRAPcc, cpTRAPcc */
|
||||
cpuSetStackFrameGenFunc(9, cpuFrame2); /* 9 - Trace */
|
||||
}
|
||||
|
||||
static void cpuStackFrameInit030(void)
|
||||
{
|
||||
cpuStackFrameInitSetDefaultFunc(cpuFrame0);
|
||||
cpuSetStackFrameGenFunc(2, cpuFrameA); /* 2 - Bus Error */
|
||||
cpuSetStackFrameGenFunc(3, cpuFrameA); /* 3 - Addrss Error */
|
||||
cpuSetStackFrameGenFunc(5, cpuFrame2); /* 5 - Zero Divide */
|
||||
cpuSetStackFrameGenFunc(6, cpuFrame2); /* 6 - CHK, CHK2 */
|
||||
cpuSetStackFrameGenFunc(7, cpuFrame2); /* 7 - TRAPV, TRAPcc, cpTRAPcc */
|
||||
cpuSetStackFrameGenFunc(9, cpuFrame2); /* 9 - Trace */
|
||||
}
|
||||
|
||||
void cpuStackFrameInit(void)
|
||||
{
|
||||
switch (cpuGetModelMajor())
|
||||
{
|
||||
case 0:
|
||||
cpuStackFrameInit000();
|
||||
break;
|
||||
case 1:
|
||||
cpuStackFrameInit010();
|
||||
break;
|
||||
case 2:
|
||||
cpuStackFrameInit020();
|
||||
break;
|
||||
case 3:
|
||||
cpuStackFrameInit030();
|
||||
break;
|
||||
}
|
||||
}
|
|
@ -0,0 +1,72 @@
|
|||
#ifndef DEFS_H
|
||||
#define DEFS_H
|
||||
|
||||
#include <stdint.h>
|
||||
#include <stdio.h>
|
||||
#include <string.h>
|
||||
|
||||
/* Maximum values for memory, don't change */
|
||||
|
||||
#define CHIPMEM 0x200000
|
||||
#define FASTMEM 0x800000
|
||||
#define BOGOMEM 0x1c0000
|
||||
#define KICKMEM 0x080000
|
||||
|
||||
/* Fellow types to ensure correct sizes */
|
||||
|
||||
typedef uint8_t UBY;
|
||||
typedef uint16_t UWO;
|
||||
typedef uint32_t ULO;
|
||||
typedef uint64_t ULL;
|
||||
typedef int8_t BYT;
|
||||
typedef int16_t WOR;
|
||||
typedef int32_t LON;
|
||||
typedef int64_t LLO;
|
||||
typedef int BOOLE;
|
||||
#define FALSE 0
|
||||
#define TRUE 1
|
||||
typedef char STR;
|
||||
|
||||
/*
|
||||
#ifndef X64
|
||||
#define PTR_TO_INT(i) ((ULO)i)
|
||||
#endif
|
||||
#ifdef X64
|
||||
#define PTR_TO_INT(i) ((ULL)i)
|
||||
#endif
|
||||
*/
|
||||
|
||||
/* Filename length used throughout the code */
|
||||
|
||||
#define CFG_FILENAME_LENGTH 256
|
||||
|
||||
/*------------------------------------*/
|
||||
/* The decode routines have this type */
|
||||
/*------------------------------------*/
|
||||
|
||||
typedef void (*decoderoutinetype)(ULO,ULO);
|
||||
|
||||
extern UBY configromname[];
|
||||
|
||||
typedef union {
|
||||
ULO *lptr;
|
||||
UWO *wptr;
|
||||
UBY *bptr;
|
||||
ULO lval;
|
||||
UWO wval[2];
|
||||
UBY bval[4];
|
||||
} ptunion;
|
||||
|
||||
typedef void (*planar2chunkyroutine)(void);
|
||||
|
||||
typedef void (*playbuffer_routine)(void);
|
||||
typedef void (*sound_before_emu_routine)(void);
|
||||
typedef void (*sound_after_emu_routine)(void);
|
||||
|
||||
typedef void (*buseventfunc)(void);
|
||||
|
||||
#define FELLOWVERSION "WinFellow alpha v0.5.0 build 0 (CVS)"
|
||||
#define FELLOWLONGVERSION "WinFellow Amiga Emulator alpha v0.5.0 - CVS"
|
||||
#define FELLOWNUMERICVERSION "0.5.0.0"
|
||||
|
||||
#endif
|
File diff suppressed because it is too large
Load Diff
|
@ -0,0 +1,152 @@
|
|||
#ifndef FMEM_H
|
||||
#define FMEM_H
|
||||
|
||||
/* Memory access functions */
|
||||
|
||||
extern UBY memoryReadByte(ULO address);
|
||||
extern UWO memoryReadWord(ULO address);
|
||||
extern ULO memoryReadLong(ULO address);
|
||||
extern void memoryWriteByte(UBY data, ULO address);
|
||||
extern void memoryWriteWord(UWO data, ULO address);
|
||||
extern void memoryWriteLong(ULO data, ULO address);
|
||||
|
||||
extern UWO memoryChipReadWord(ULO address);
|
||||
extern void memoryChipWriteWord(UWO data, ULO address);
|
||||
|
||||
#define memoryReadByteFromPointer(address) (address[0])
|
||||
#define memoryReadWordFromPointer(address) ((address[0] << 8) | address[1])
|
||||
#define memoryReadLongFromPointer(address) ((address[0] << 24) | (address[1] << 16) | (address[2] << 8) | address[3])
|
||||
|
||||
/* IO Bank functions */
|
||||
|
||||
typedef UWO (*memoryIoReadFunc)(ULO address);
|
||||
typedef void (*memoryIoWriteFunc)(UWO data, ULO address);
|
||||
|
||||
extern void memorySetIoReadStub(ULO index, memoryIoReadFunc ioreadfunction);
|
||||
extern void memorySetIoWriteStub(ULO index, memoryIoWriteFunc iowritefunction);
|
||||
|
||||
/* For the copper */
|
||||
extern memoryIoWriteFunc memory_iobank_write[257];
|
||||
|
||||
/* Expansion card functions */
|
||||
|
||||
typedef void (*memoryEmemCardInitFunc)(void);
|
||||
typedef void (*memoryEmemCardMapFunc)(ULO);
|
||||
|
||||
extern void memoryEmemClear(void);
|
||||
extern void memoryEmemCardAdd(memoryEmemCardInitFunc cardinit,
|
||||
memoryEmemCardMapFunc cardmap);
|
||||
extern void memoryEmemSet(ULO index, ULO data);
|
||||
extern void memoryEmemMirror(ULO emem_offset, UBY *src, ULO size);
|
||||
|
||||
/* Device memory functions. fhfile is using these. */
|
||||
|
||||
extern void memoryDmemSetByte(UBY data);
|
||||
extern void memoryDmemSetWord(UWO data);
|
||||
extern void memoryDmemSetLong(ULO data);
|
||||
extern void memoryDmemSetLongNoCounter(ULO data, ULO offset);
|
||||
extern void memoryDmemSetString(STR *data);
|
||||
extern void memoryDmemSetCounter(ULO val);
|
||||
extern ULO memoryDmemGetCounter(void);
|
||||
extern void memoryDmemClear(void);
|
||||
|
||||
/* Module management functions */
|
||||
|
||||
extern void memorySaveState(FILE *F);
|
||||
extern void memoryLoadState(FILE *F);
|
||||
extern void memorySoftReset(void);
|
||||
extern void memoryHardReset(void);
|
||||
extern void memoryHardResetPost(void);
|
||||
extern void memoryEmulationStart(void);
|
||||
extern void memoryEmulationStop(void);
|
||||
extern void memoryStartup(void);
|
||||
extern void memoryShutdown(void);
|
||||
|
||||
/* Memory bank functions */
|
||||
|
||||
typedef UBY (*memoryReadByteFunc)(ULO address);
|
||||
typedef UWO (*memoryReadWordFunc)(ULO address);
|
||||
typedef ULO (*memoryReadLongFunc)(ULO address);
|
||||
typedef void (*memoryWriteByteFunc)(UBY data, ULO address);
|
||||
typedef void (*memoryWriteWordFunc)(UWO data, ULO address);
|
||||
typedef void (*memoryWriteLongFunc)(ULO data, ULO address);
|
||||
|
||||
extern memoryReadByteFunc memory_bank_readbyte[65536];
|
||||
extern memoryReadWordFunc memory_bank_readword[65536];
|
||||
extern memoryReadLongFunc memory_bank_readlong[65536];
|
||||
extern memoryWriteByteFunc memory_bank_writebyte[65536];
|
||||
extern memoryWriteWordFunc memory_bank_writeword[65536];
|
||||
extern memoryWriteLongFunc memory_bank_writelong[65536];
|
||||
|
||||
extern UBY *memory_bank_pointer[65536];
|
||||
extern UBY *memory_bank_datapointer[65536];
|
||||
|
||||
extern void memoryBankSet(memoryReadByteFunc rb,
|
||||
memoryReadWordFunc rw,
|
||||
memoryReadLongFunc rl,
|
||||
memoryWriteByteFunc wb,
|
||||
memoryWriteWordFunc ww,
|
||||
memoryWriteLongFunc wl,
|
||||
UBY *basep,
|
||||
ULO bank,
|
||||
ULO basebank,
|
||||
BOOLE pointer_can_write);
|
||||
extern UBY *memoryAddressToPtr(ULO address);
|
||||
extern void memoryChipMap(BOOLE overlay);
|
||||
|
||||
/* Memory configuration properties */
|
||||
|
||||
extern BOOLE memorySetChipSize(ULO chipsize);
|
||||
extern ULO memoryGetChipSize(void);
|
||||
extern BOOLE memorySetFastSize(ULO fastsize);
|
||||
extern ULO memoryGetFastSize(void);
|
||||
extern void memorySetFastAllocatedSize(ULO fastallocatedsize);
|
||||
extern ULO memoryGetFastAllocatedSize(void);
|
||||
extern BOOLE memorySetSlowSize(ULO bogosize);
|
||||
extern ULO memoryGetSlowSize(void);
|
||||
extern BOOLE memorySetUseAutoconfig(BOOLE useautoconfig);
|
||||
extern BOOLE memoryGetUseAutoconfig(void);
|
||||
extern BOOLE memorySetAddress32Bit(BOOLE address32bit);
|
||||
extern BOOLE memoryGetAddress32Bit(void);
|
||||
extern BOOLE memorySetKickImage(STR *kickimage);
|
||||
extern STR *memoryGetKickImage(void);
|
||||
extern void memorySetKey(STR *key);
|
||||
extern STR *memoryGetKey(void);
|
||||
extern BOOLE memoryGetKickImageOK(void);
|
||||
|
||||
/* Derived from memory configuration */
|
||||
|
||||
extern ULO memoryGetKickImageBaseBank(void);
|
||||
extern ULO memoryGetKickImageVersion(void);
|
||||
extern ULO memoryInitialPC(void);
|
||||
extern ULO memoryInitialSP(void);
|
||||
|
||||
/* Kickstart load error handling */
|
||||
|
||||
#define MEMORY_ROM_ERROR_SIZE 0
|
||||
#define MEMORY_ROM_ERROR_AMIROM_VERSION 1
|
||||
#define MEMORY_ROM_ERROR_AMIROM_READ 2
|
||||
#define MEMORY_ROM_ERROR_KEYFILE 3
|
||||
#define MEMORY_ROM_ERROR_EXISTS_NOT 4
|
||||
#define MEMORY_ROM_ERROR_FILE 5
|
||||
#define MEMORY_ROM_ERROR_KICKDISK_NOT 6
|
||||
#define MEMORY_ROM_ERROR_CHECKSUM 7
|
||||
#define MEMORY_ROM_ERROR_KICKDISK_SUPER 8
|
||||
#define MEMORY_ROM_ERROR_BAD_BANK 9
|
||||
|
||||
/* Global variables */
|
||||
|
||||
extern UBY memory_chip[];
|
||||
extern UBY *memory_fast;
|
||||
extern UBY memory_slow[];
|
||||
extern UBY memory_kick[];
|
||||
extern ULO memory_chipsize;
|
||||
extern UBY memory_emem[];
|
||||
|
||||
extern ULO intenar,intena,intreq;
|
||||
extern ULO potgor;
|
||||
|
||||
extern ULO memory_fault_address;
|
||||
extern BOOLE memory_fault_read;
|
||||
|
||||
#endif
|
Loading…
Reference in New Issue