mirror of
https://github.com/ksherlock/mpw.git
synced 2025-01-08 07:31:45 +00:00
fellow cpu code
This commit is contained in:
parent
f97b6eae24
commit
ea246894be
458
cpu/CpuIntegration.c
Normal file
458
cpu/CpuIntegration.c
Normal file
@ -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();
|
||||
}
|
44
cpu/CpuIntegration.h
Normal file
44
cpu/CpuIntegration.h
Normal file
@ -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
|
80
cpu/CpuModule.c
Normal file
80
cpu/CpuModule.c
Normal file
@ -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();
|
||||
}
|
93
cpu/CpuModule.h
Normal file
93
cpu/CpuModule.h
Normal file
@ -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
|
12233
cpu/CpuModule_Code.h
Normal file
12233
cpu/CpuModule_Code.h
Normal file
File diff suppressed because it is too large
Load Diff
69648
cpu/CpuModule_Data.h
Normal file
69648
cpu/CpuModule_Data.h
Normal file
File diff suppressed because it is too large
Load Diff
1685
cpu/CpuModule_Decl.h
Normal file
1685
cpu/CpuModule_Decl.h
Normal file
File diff suppressed because it is too large
Load Diff
1764
cpu/CpuModule_Disassembler.c
Normal file
1764
cpu/CpuModule_Disassembler.c
Normal file
File diff suppressed because it is too large
Load Diff
97
cpu/CpuModule_Disassembler.h
Normal file
97
cpu/CpuModule_Disassembler.h
Normal file
@ -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
|
4103
cpu/CpuModule_DisassemblerFunc.h
Normal file
4103
cpu/CpuModule_DisassemblerFunc.h
Normal file
File diff suppressed because it is too large
Load Diff
194
cpu/CpuModule_EffectiveAddress.c
Normal file
194
cpu/CpuModule_EffectiveAddress.c
Normal file
@ -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);
|
||||
}
|
266
cpu/CpuModule_Exceptions.c
Normal file
266
cpu/CpuModule_Exceptions.c
Normal file
@ -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;
|
||||
}
|
||||
}
|
578
cpu/CpuModule_Flags.c
Normal file
578
cpu/CpuModule_Flags.c
Normal file
@ -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;
|
||||
}
|
3735
cpu/CpuModule_Instructions.c
Normal file
3735
cpu/CpuModule_Instructions.c
Normal file
File diff suppressed because it is too large
Load Diff
200
cpu/CpuModule_Internal.h
Normal file
200
cpu/CpuModule_Internal.h
Normal file
@ -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
|
390
cpu/CpuModule_InternalState.c
Normal file
390
cpu/CpuModule_InternalState.c
Normal file
@ -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.
|
||||
}
|
107
cpu/CpuModule_Interrupts.c
Normal file
107
cpu/CpuModule_Interrupts.c
Normal file
@ -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);
|
||||
}
|
71
cpu/CpuModule_Logging.c
Normal file
71
cpu/CpuModule_Logging.c
Normal file
@ -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
|
8
cpu/CpuModule_Profile.h
Normal file
8
cpu/CpuModule_Profile.h
Normal file
@ -0,0 +1,8 @@
|
||||
#ifndef CPUMODULE_PROFILE_H
|
||||
#define CPUMODULE_PROFILE_H
|
||||
|
||||
#include "fileops.h"
|
||||
void cpuProfileWrite(void)
|
||||
{
|
||||
}
|
||||
#endif
|
259
cpu/CpuModule_StackFrameGen.c
Normal file
259
cpu/CpuModule_StackFrameGen.c
Normal file
@ -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;
|
||||
}
|
||||
}
|
72
cpu/defs.h
Normal file
72
cpu/defs.h
Normal file
@ -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
|
2094
cpu/fmem.c
Normal file
2094
cpu/fmem.c
Normal file
File diff suppressed because it is too large
Load Diff
152
cpu/fmem.h
Normal file
152
cpu/fmem.h
Normal file
@ -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
Block a user