T32 Simulator: Basic Instruction set sim for ARMM3

The T32 can simulate bare instruction sets without periphery.
For the Cortex-M3 we have complete NVIC model including Systick Timer.
Currently a simple CiAO can run on the simulator.

TODO:
 - Let memlogger log all memory accesses.
 - Interact with FailT32 for a complete simulation/FI
This commit is contained in:
Martin Hoffmann
2013-03-20 17:17:38 +01:00
parent f0e26a9b63
commit 96bc39c05d
42 changed files with 5880 additions and 46 deletions

View File

@ -0,0 +1,876 @@
#include "simul.h"
/**************************************************************************
Offsets and width of the control registers
**************************************************************************/
#define DEMOPORT_WIDTH 4
#define DEMOPORT_DATA1REG 0
#define DEMOPORT_DATA2REG 1*DEMOPORT_WIDTH
#define DEMOPORT_DATA3REG 2*DEMOPORT_WIDTH
#define DEMOPORT_DATA5REG 3*DEMOPORT_WIDTH
#define DEMOPORT_DATA6REG 3*DEMOPORT_WIDTH+1
#define DEMOPORT_DATA6CREG 3*DEMOPORT_WIDTH+2
#define DEMOPORT_TIMER1REG 4*DEMOPORT_WIDTH
#define DEMOPORT_TIMER2REG 5*DEMOPORT_WIDTH
#define DEMOPORT_TIMER3REG 6*DEMOPORT_WIDTH
#define DEMOPORT_RAM1BASE 0x200
/**************************************************************************
Local port structure
**************************************************************************/
typedef struct
{
int bustype;
simulWord startaddress;
int baseport;
simulWord port2data;
simulWord port4data;
void * port4readcallback;
void * port4writecallback;
void * port5readhandle;
void * port5writehandle;
simulWord port5data;
int port6txint;
int port6rxint;
int port6txintpending;
int port6rxintpending;
void * timer1id;
simulWord timer2value;
void * timer3id;
int timer3running;
simulWord timer3startvalue;
simulTime timer3startclock;
}
demoPort;
/**************************************************************************
Data1 demonstrates a port which is directly connected to simulator ports.
The callback is called for reads and writes to the port.
**************************************************************************/
static int SIMULAPI PortWriteData1(simulProcessor processor, simulCallbackStruct * cbs, simulPtr private)
{
demoPort *demoportptr = (demoPort *) private;
SIMUL_SetPort(processor, demoportptr->baseport + DEMOPORT_DATA1REG * 8, cbs->x.bus.width, &cbs->x.bus.data);
cbs->x.bus.clocks += 4; /* add 4 waitstates */
return SIMUL_MEMORY_OK;
}
static int SIMULAPI PortReadData1(simulProcessor processor, simulCallbackStruct * cbs, simulPtr private)
{
demoPort *demoportptr = (demoPort *) private;
SIMUL_GetPort(processor, demoportptr->baseport + DEMOPORT_DATA1REG * 8, cbs->x.bus.width, &cbs->x.bus.data);
cbs->x.bus.clocks += 4; /* add 4 waitstates */
return SIMUL_MEMORY_OK;
}
static int SIMULAPI PortResetData1(simulProcessor processor, simulCallbackStruct * cbs, simulPtr private)
{
simulWord data;
demoPort *demoportptr = (demoPort *) private;
data = -1;
SIMUL_SetPort(processor, demoportptr->baseport + DEMOPORT_DATA1REG * 8, DEMOPORT_WIDTH * 8, &data);
return SIMUL_RESET_OK;
}
static void PortInitData1(simulProcessor processor, demoPort * demoportptr)
{
simulWord from, to;
SIMUL_RegisterResetCallback(processor, PortResetData1, (simulPtr) demoportptr);
from = demoportptr->startaddress + DEMOPORT_DATA1REG;
to = demoportptr->startaddress + DEMOPORT_DATA1REG + DEMOPORT_WIDTH - 1;
SIMUL_RegisterBusWriteCallback(processor, PortWriteData1, (simulPtr) demoportptr, demoportptr->bustype, &from, &to);
SIMUL_RegisterBusReadCallback(processor, PortReadData1, (simulPtr) demoportptr, demoportptr->bustype, &from, &to);
}
/**************************************************************************
Data2 demonstrates a port which holds its data local.
The callback is called for reads and writes to the port.
Only the correct bussize is allowed.
**************************************************************************/
static int SIMULAPI PortWriteData2(simulProcessor processor, simulCallbackStruct * cbs, simulPtr private)
{
demoPort *demoportptr = (demoPort *) private;
if (cbs->x.bus.width != DEMOPORT_WIDTH * 8)
return SIMUL_MEMORY_FAIL;
demoportptr->port2data = cbs->x.bus.data;
cbs->x.bus.clocks = 0; /* 0-cycle access */
return SIMUL_MEMORY_OK;
}
static int SIMULAPI PortReadData2(simulProcessor processor, simulCallbackStruct * cbs, simulPtr private)
{
demoPort *demoportptr = (demoPort *) private;
if (cbs->x.bus.width != DEMOPORT_WIDTH * 8)
return SIMUL_MEMORY_FAIL;
cbs->x.bus.data = demoportptr->port2data;
return SIMUL_MEMORY_OK;
}
static int SIMULAPI PortResetData2(simulProcessor processor, simulCallbackStruct * cbs, simulPtr private)
{
demoPort *demoportptr = (demoPort *) private;
demoportptr->port2data = 0;
return SIMUL_RESET_OK;
}
static void PortInitData2(simulProcessor processor, demoPort * demoportptr)
{
simulWord from, to;
demoportptr->port2data = 0;
SIMUL_RegisterResetCallback(processor, PortResetData2, (simulPtr) demoportptr);
from = demoportptr->startaddress + DEMOPORT_DATA2REG;
to = demoportptr->startaddress + DEMOPORT_DATA2REG + DEMOPORT_WIDTH - 1;
SIMUL_RegisterBusWriteCallback(processor, PortWriteData2, (simulPtr) demoportptr, demoportptr->bustype, &from, &to);
SIMUL_RegisterBusReadCallback(processor, PortReadData2, (simulPtr) demoportptr, demoportptr->bustype, &from, &to);
}
/**************************************************************************
Data3 demonstrates a port which holds global data (same for multiple instances).
The callback is called for reads and writes to the port.
All bussizes are supported.
**************************************************************************/
static simulWord Port3Data;
static int SIMULAPI PortWriteData3(simulProcessor processor, simulCallbackStruct * cbs, simulPtr private)
{
SIMUL_InsertWord(processor, &Port3Data, DEMOPORT_WIDTH*8, &cbs->x.bus.address, cbs->x.bus.width, &cbs->x.bus.data);
return SIMUL_MEMORY_OK;
}
static int SIMULAPI PortReadData3(simulProcessor processor, simulCallbackStruct * cbs, simulPtr private)
{
SIMUL_ExtractWord(processor, &Port3Data, DEMOPORT_WIDTH*8, &cbs->x.bus.address, cbs->x.bus.width, &cbs->x.bus.data);
return SIMUL_MEMORY_OK;
}
static void PortInitData3(simulProcessor processor, demoPort * demoportptr)
{
simulWord from, to;
from = demoportptr->startaddress + DEMOPORT_DATA3REG;
to = demoportptr->startaddress + DEMOPORT_DATA3REG + DEMOPORT_WIDTH - 1;
SIMUL_RegisterBusWriteCallback(processor, PortWriteData3, (simulPtr) demoportptr, demoportptr->bustype, &from, &to);
SIMUL_RegisterBusReadCallback(processor, PortReadData3, (simulPtr) demoportptr, demoportptr->bustype, &from, &to);
}
/**************************************************************************
Data4 demonstrates a port with a dynamic address.
The value written to the port is the address of the port.
The lower 8 address bits of the address are zero.
The callback is called for reads and writes to the port.
**************************************************************************/
static int SIMULAPI PortWriteData4(simulProcessor processor, simulCallbackStruct * cbs, simulPtr private)
{
demoPort *demoportptr = (demoPort *) private;
simulWord from, to;
SIMUL_InsertWord(processor, &demoportptr->port4data, DEMOPORT_WIDTH * 8, &cbs->x.bus.address, cbs->x.bus.width, &cbs->x.bus.data);
demoportptr->port4data &= ~0xff;
from = demoportptr->port4data;
to = demoportptr->port4data + DEMOPORT_WIDTH - 1;
SIMUL_RelocateBusCallback(processor, demoportptr->port4readcallback, demoportptr->bustype, &from, &to);
SIMUL_RelocateBusCallback(processor, demoportptr->port4writecallback, demoportptr->bustype, &from, &to);
return SIMUL_MEMORY_OK;
}
static int SIMULAPI PortReadData4(simulProcessor processor, simulCallbackStruct * cbs, simulPtr private)
{
demoPort *demoportptr = (demoPort *) private;
SIMUL_ExtractWord(processor, &demoportptr->port4data, DEMOPORT_WIDTH*8, &cbs->x.bus.address, cbs->x.bus.width, &cbs->x.bus.data);
return SIMUL_MEMORY_OK;
}
static int SIMULAPI PortResetData4(simulProcessor processor, simulCallbackStruct * cbs, simulPtr private)
{
simulWord from, to;
demoPort *demoportptr = (demoPort *) private;
demoportptr->port4data = (demoportptr->startaddress & ~0xff) + 0x100; /* initial address after reset */
from = demoportptr->port4data;
to = demoportptr->port4data + DEMOPORT_WIDTH - 1;
SIMUL_RelocateBusCallback(processor, demoportptr->port4readcallback, demoportptr->bustype, &from, &to);
SIMUL_RelocateBusCallback(processor, demoportptr->port4writecallback, demoportptr->bustype, &from, &to);
return SIMUL_RESET_OK;
}
static void PortInitData4(simulProcessor processor, demoPort * demoportptr)
{
simulWord from, to;
demoportptr->port4data = (demoportptr->startaddress & ~0xff) + 0x100; /* initial address */
SIMUL_RegisterResetCallback(processor, PortResetData4, (simulPtr) demoportptr);
from = demoportptr->port4data;
to = demoportptr->port4data + DEMOPORT_WIDTH - 1;
demoportptr->port4writecallback = SIMUL_RegisterBusWriteCallback(processor, PortWriteData4, (simulPtr) demoportptr, demoportptr->bustype, &from, &to);
demoportptr->port4readcallback = SIMUL_RegisterBusReadCallback(processor, PortReadData4, (simulPtr) demoportptr, demoportptr->bustype, &from, &to);
}
/**************************************************************************
Data5 demonstrates a port which writes or reads binary data to/from file.
The callback is called for reads and writes to the port.
All bussizes are supported.
**************************************************************************/
static int SIMULAPI PortWriteData5(simulProcessor processor, simulCallbackStruct * cbs, simulPtr private)
{
unsigned char bdata;
simulWord wdata;
demoPort *demoportptr = (demoPort *) private;
SIMUL_InsertWord(processor, &wdata, 8, &cbs->x.bus.address, cbs->x.bus.width, &cbs->x.bus.data);
bdata = wdata & 0xff;
if (SIMUL_WriteFile(processor, demoportptr->port5writehandle, &bdata, 1) <= 0)
return SIMUL_MEMORY_FAIL;
return SIMUL_MEMORY_OK;
}
static int SIMULAPI PortReadData5(simulProcessor processor, simulCallbackStruct * cbs, simulPtr private)
{
unsigned char bdata;
demoPort *demoportptr = (demoPort *) private;
if (cbs->x.bus.cycletype) { /* destructive read only done when CPU/DMA makes access */
if (!demoportptr->port5readhandle)
return SIMUL_MEMORY_FAIL;
if (SIMUL_ReadFile(processor, demoportptr->port5readhandle, &bdata, 1) <= 0)
return SIMUL_MEMORY_FAIL;
demoportptr->port5data = bdata;
}
SIMUL_ExtractWord(processor, &demoportptr->port5data, 8, &cbs->x.bus.address, cbs->x.bus.width, &cbs->x.bus.data);
return SIMUL_MEMORY_OK;
}
static int SIMULAPI PortResetData5(simulProcessor processor, simulCallbackStruct * cbs, simulPtr private)
{
demoPort *demoportptr = (demoPort *) private;
if (demoportptr->port5readhandle)
SIMUL_SeekFile(processor, demoportptr->port5readhandle, 0l, SIMUL_FILE_SEEKABS);
demoportptr->port5data = 0;
return SIMUL_RESET_OK;
}
static void PortInitData5(simulProcessor processor, demoPort * demoportptr)
{
simulWord from, to;
demoportptr->port5readhandle = SIMUL_OpenFile(processor, "~~~/portread.dat", SIMUL_FILE_READ);
demoportptr->port5writehandle = SIMUL_OpenFile(processor, "~~~/portwrit.dat", SIMUL_FILE_WRITE|SIMUL_FILE_CREATE);
demoportptr->port5data = 0;
SIMUL_RegisterResetCallback(processor, PortResetData5, (simulPtr) demoportptr);
from = demoportptr->startaddress + DEMOPORT_DATA5REG;
to = demoportptr->startaddress + DEMOPORT_DATA5REG;
SIMUL_RegisterBusWriteCallback(processor, PortWriteData5, (simulPtr) demoportptr, demoportptr->bustype, &from, &to);
SIMUL_RegisterBusReadCallback(processor, PortReadData5, (simulPtr) demoportptr, demoportptr->bustype, &from, &to);
}
/**************************************************************************
Terminal1 demonstrates a port which is connected to terminal window #1.
Terminal1 is the data port, Terminal1C the status and control port.
The callback is called for reads and writes to the port.
Bits 6+7 or control enable the interrupts.
The interrupt drives directly the CPU. For normal applications this
should go thru an interrupt controller.
When unloading the model we write a message to the terminal.
**************************************************************************/
static int SIMULAPI PortWriteTerminal1(simulProcessor processor, simulCallbackStruct * cbs, simulPtr private)
{
simulWord data;
demoPort *demoportptr = (demoPort *) private;
demoportptr->port6txintpending = 0;
if (!((demoportptr->port6txintpending && demoportptr->port6txint)
|| (demoportptr->port6rxintpending && demoportptr->port6rxint))) {
data = 0;
SIMUL_SetPort(processor, SIMUL_PORT_INTERRUPT, 1, &data);
}
if (SIMUL_WriteTerminal(processor, 1, (int) (cbs->x.bus.data & 0xff)) > 0) {
demoportptr->port6txintpending = 1;
if (((demoportptr->port6txintpending && demoportptr->port6txint)
|| (demoportptr->port6rxintpending && demoportptr->port6rxint))) {
data = 1;
SIMUL_SetPort(processor, SIMUL_PORT_INTERRUPT, 1, &data);
}
}
return SIMUL_MEMORY_OK;
}
static int SIMULAPI PortReadTerminal1(simulProcessor processor, simulCallbackStruct * cbs, simulPtr private)
{
simulWord data;
demoPort *demoportptr = (demoPort *) private;
if (cbs->x.bus.cycletype) { /* destructive read only done when CPU/DMA
* makes access */
cbs->x.bus.data = SIMUL_ReadTerminal(processor, 1);
demoportptr->port6rxintpending = 0;
if (!((demoportptr->port6txintpending && demoportptr->port6txint)
|| (demoportptr->port6rxintpending && demoportptr->port6rxint))) {
data = 0;
SIMUL_SetPort(processor, SIMUL_PORT_INTERRUPT, 1, &data);
}
return SIMUL_MEMORY_OK;
}
return SIMUL_MEMORY_FAIL;
}
static int SIMULAPI PortWriteTerminal1C(simulProcessor processor, simulCallbackStruct * cbs, simulPtr private)
{
simulWord data;
demoPort *demoportptr = (demoPort *) private;
demoportptr->port6txint = !!(cbs->x.bus.data & 0x80);
demoportptr->port6rxint = !!(cbs->x.bus.data & 0x40);
if (((demoportptr->port6txintpending && demoportptr->port6txint)
|| (demoportptr->port6rxintpending && demoportptr->port6rxint))) {
data = 1;
} else {
data = 0;
}
SIMUL_SetPort(processor, SIMUL_PORT_INTERRUPT, 1, &data);
return SIMUL_MEMORY_OK;
}
static int SIMULAPI PortReadTerminal1C(simulProcessor processor, simulCallbackStruct * cbs, simulPtr private)
{
demoPort *demoportptr = (demoPort *) private;
cbs->x.bus.data = SIMUL_StateTerminal(processor, 1);
cbs->x.bus.data |= (demoportptr->port6txint << 7) | (demoportptr->port6rxint << 6);
return SIMUL_MEMORY_OK;
}
static int SIMULAPI PortReceiveTerminal1(simulProcessor processor, simulCallbackStruct * cbs, simulPtr private)
{
simulWord data;
demoPort *demoportptr = (demoPort *) private;
demoportptr->port6rxintpending = 1;
if (((demoportptr->port6txintpending && demoportptr->port6txint)
|| (demoportptr->port6rxintpending && demoportptr->port6rxint))) {
data = 1;
SIMUL_SetPort(processor, SIMUL_PORT_INTERRUPT, 1, &data);
}
return SIMUL_MEMORY_OK;
}
static int SIMULAPI PortResetTerminal1(simulProcessor processor, simulCallbackStruct * cbs, simulPtr private)
{
demoPort *demoportptr = (demoPort *) private;
demoportptr->port6txint = 0;
demoportptr->port6rxint = 0;
demoportptr->port6txintpending = 0;
demoportptr->port6rxintpending = 0;
return SIMUL_RESET_OK;
}
static int SIMULAPI PortExitTerminal1(simulProcessor processor, simulCallbackStruct * cbs, simulPtr private)
{
int i;
demoPort *demoportptr = (demoPort *) private;
static const char exitmessage[] = "\r\nunloaded.\r\n";
for (i = 0; exitmessage[i]; i++)
SIMUL_WriteTerminal(processor, 1, exitmessage[i]);
return SIMUL_EXIT_OK;
}
static void PortInitTerminal1(simulProcessor processor, demoPort * demoportptr)
{
simulWord from, to;
demoportptr->port6txint = 0;
demoportptr->port6rxint = 0;
demoportptr->port6txintpending = 0;
demoportptr->port6rxintpending = 0;
SIMUL_RegisterResetCallback(processor, PortResetTerminal1, (simulPtr) demoportptr);
SIMUL_RegisterExitCallback(processor, PortExitTerminal1, (simulPtr) demoportptr);
from = demoportptr->startaddress + DEMOPORT_DATA6REG;
to = demoportptr->startaddress + DEMOPORT_DATA6REG;
SIMUL_RegisterBusWriteCallback(processor, PortWriteTerminal1, (simulPtr) demoportptr, demoportptr->bustype, &from, &to);
SIMUL_RegisterBusReadCallback(processor, PortReadTerminal1, (simulPtr) demoportptr, demoportptr->bustype, &from, &to);
from = demoportptr->startaddress + DEMOPORT_DATA6CREG;
to = demoportptr->startaddress + DEMOPORT_DATA6CREG;
SIMUL_RegisterBusWriteCallback(processor, PortWriteTerminal1C, (simulPtr) demoportptr, demoportptr->bustype, &from, &to);
SIMUL_RegisterBusReadCallback(processor, PortReadTerminal1C, (simulPtr) demoportptr, demoportptr->bustype, &from, &to);
SIMUL_RegisterTerminalCallback(processor, PortReceiveTerminal1, (simulPtr) demoportptr, 1);
}
/**************************************************************************
Ram1 demonstrates multiport RAM between different CPUs.
The callback is called for reads and writes to the port.
All bussizes are supported.
**************************************************************************/
static int SIMULAPI PortWriteRam1(simulProcessor processor, simulCallbackStruct * cbs, simulPtr private)
{
int offset, len;
unsigned char data[8];
len = cbs->x.bus.width / 8;
offset = cbs->x.bus.address & 0xff;
SIMUL_SaveWord(processor, data, cbs->x.bus.width, &cbs->x.bus.data);
if (SIMUL_WriteSharedResource(processor, offset, len, data) < 0)
return SIMUL_MEMORY_FAIL;
return SIMUL_MEMORY_OK;
}
static int SIMULAPI PortReadRam1(simulProcessor processor, simulCallbackStruct * cbs, simulPtr private)
{
int offset, len;
unsigned char data[8];
len = cbs->x.bus.width / 8;
offset = cbs->x.bus.address & 0xff;
if (SIMUL_ReadSharedResource(processor, offset, len, data) < 0)
return SIMUL_MEMORY_FAIL;
SIMUL_LoadWord(processor, data, cbs->x.bus.width, &cbs->x.bus.data);
return SIMUL_MEMORY_OK;
}
static void PortInitRam1(simulProcessor processor, demoPort * demoportptr)
{
simulWord from, to;
SIMUL_CreateSharedResource(processor, 256);
from = demoportptr->startaddress + DEMOPORT_RAM1BASE;
to = demoportptr->startaddress + DEMOPORT_RAM1BASE + 0xff - 1;
SIMUL_RegisterBusWriteCallback(processor, PortWriteRam1, (simulPtr) demoportptr, demoportptr->bustype, &from, &to);
SIMUL_RegisterBusReadCallback(processor, PortReadRam1, (simulPtr) demoportptr, demoportptr->bustype, &from, &to);
}
/**************************************************************************
Timer1 demonstrates a timer that increments every <n> clockticks.
The callback is called for each increment.
The timervalue is directly kept in simulated memory, no read callback.
A copy of the timer bits is also available in the ports.
Bit 0 of the timer is send to port #0xf0 (to trigger Timer2).
The command "SIM SETTIMER1 <clocks>" can set the period of the timer.
**************************************************************************/
static int SIMULAPI PortWriteTimer1(simulProcessor processor, simulCallbackStruct * cbs, simulPtr private)
{
demoPort *demoportptr = (demoPort *) private;
SIMUL_SetPort(processor, demoportptr->baseport+DEMOPORT_TIMER1REG*8, cbs->x.bus.width, &cbs->x.bus.data);
SIMUL_SetPort(processor, 0xf0, 1, &cbs->x.bus.data);
return SIMUL_MEMORY_CONTINUE; /* to update also the memory location */
}
static int SIMULAPI PortIncTimer1(simulProcessor processor, simulCallbackStruct * cbs, simulPtr private)
{
demoPort *demoportptr = (demoPort *) private;
simulWord data, address;
address = demoportptr->startaddress + DEMOPORT_TIMER1REG;
SIMUL_ReadMemory(processor, demoportptr->bustype, &address, DEMOPORT_WIDTH*8, SIMUL_MEMORY_HIDDEN, &data);
data++;
/* note: this write will cause the PortWriteTimer1 callback to be called */
SIMUL_WriteMemory(processor, demoportptr->bustype, &address, DEMOPORT_WIDTH*8, SIMUL_MEMORY_HIDDEN, &data);
return SIMUL_TIMER_OK;
}
static int SIMULAPI PortCommandTimer1(simulProcessor processor, simulCallbackStruct * cbs, simulPtr private)
{
simulTime time;
demoPort *demoportptr = (demoPort *) private;
if (!strcmp(cbs->x.command.argp[0], "SETTIMER1")) {
if (cbs->x.command.argc != 2 || cbs->x.command.argpint[1] <= 0) {
SIMUL_Warning(processor, "usage: SETTIMER1 <clocks>");
return SIMUL_COMMAND_FAIL;
}
time = cbs->x.command.argpint[1];
SIMUL_StartTimer(processor, demoportptr->timer1id, SIMUL_TIMER_REPEAT | SIMUL_TIMER_REL | SIMUL_TIMER_CLOCKS, &time);
}
return SIMUL_COMMAND_OK;
}
static int SIMULAPI PortResetTimer1(simulProcessor processor, simulCallbackStruct * cbs, simulPtr private)
{
simulTime time;
demoPort *demoportptr = (demoPort *) private;
time = 100;
SIMUL_StartTimer(processor, demoportptr->timer1id, SIMUL_TIMER_REPEAT | SIMUL_TIMER_REL | SIMUL_TIMER_CLOCKS, &time);
return SIMUL_RESET_OK;
}
static void PortInitTimer1(simulProcessor processor, demoPort * demoportptr)
{
simulTime time;
simulWord from, to;
SIMUL_RegisterResetCallback(processor, PortResetTimer1, (simulPtr) demoportptr);
SIMUL_RegisterCommandCallback(processor, PortCommandTimer1, (simulPtr) demoportptr);
from = demoportptr->startaddress + DEMOPORT_TIMER1REG;
to = demoportptr->startaddress + DEMOPORT_TIMER1REG + DEMOPORT_WIDTH - 1;
SIMUL_RegisterBusWriteCallback(processor, PortWriteTimer1, (simulPtr) demoportptr, demoportptr->bustype, &from, &to);
demoportptr->timer1id = SIMUL_RegisterTimerCallback(processor, PortIncTimer1, (simulPtr) demoportptr);
time = 100;
SIMUL_StartTimer(processor, demoportptr->timer1id, SIMUL_TIMER_REPEAT | SIMUL_TIMER_REL | SIMUL_TIMER_CLOCKS, &time);
}
/**************************************************************************
Timer2 demonstrates a timer that counts rising edges of port #0xf0.
Any write access resets the timer to 0.
The read callback does not take care about the buswidth and
will return wrong values for wrong bussizes (but it is faster).
**************************************************************************/
static int SIMULAPI PortWriteTimer2(simulProcessor processor, simulCallbackStruct * cbs, simulPtr private)
{
demoPort *demoportptr = (demoPort *) private;
demoportptr->timer2value = 0;
return SIMUL_MEMORY_OK;
}
static int SIMULAPI PortReadTimer2(simulProcessor processor, simulCallbackStruct * cbs, simulPtr private)
{
demoPort *demoportptr = (demoPort *) private;
cbs->x.bus.data = demoportptr->timer2value;
return SIMUL_MEMORY_OK;
}
static int SIMULAPI PortChangeTimer2(simulProcessor processor, simulCallbackStruct * cbs, simulPtr private)
{
demoPort *demoportptr = (demoPort *) private;
if (cbs->x.port.newdata)
demoportptr->timer2value++;
return SIMUL_PORT_OK;
}
static int SIMULAPI PortResetTimer2(simulProcessor processor, simulCallbackStruct * cbs, simulPtr private)
{
demoPort *demoportptr = (demoPort *) private;
demoportptr->timer2value = 0;
return SIMUL_RESET_OK;
}
static void PortInitTimer2(simulProcessor processor, demoPort * demoportptr)
{
simulWord from, to;
demoportptr->timer2value = 0;
SIMUL_RegisterResetCallback(processor, PortResetTimer2, (simulPtr) demoportptr);
from = demoportptr->startaddress + DEMOPORT_TIMER2REG;
to = demoportptr->startaddress + DEMOPORT_TIMER2REG + DEMOPORT_WIDTH - 1;
SIMUL_RegisterBusWriteCallback(processor, PortWriteTimer2, (simulPtr) demoportptr, demoportptr->bustype, &from, &to);
SIMUL_RegisterBusReadCallback(processor, PortReadTimer2, (simulPtr) demoportptr, demoportptr->bustype, &from, &to);
SIMUL_RegisterPortChangeCallback(processor, PortChangeTimer2, (simulPtr) demoportptr, 0xf0, 1);
}
/**************************************************************************
Timer3 demonstrates a timer that decrements every clocktick.
A write to the port starts the timer.
The timer send an interrupt to the CPU when the value reaches 0.
The callback is only called when the value reaches 0.
The read callback calculates the expected value.
**************************************************************************/
static int SIMULAPI PortWriteTimer3(simulProcessor processor, simulCallbackStruct * cbs, simulPtr private)
{
simulTime clocks;
demoPort *demoportptr = (demoPort *) private;
if (!demoportptr->timer3id)
return SIMUL_MEMORY_FAIL;
demoportptr->timer3running = 1;
demoportptr->timer3startvalue = cbs->x.bus.data;
SIMUL_GetClock(processor, 0, &demoportptr->timer3startclock);
clocks = demoportptr->timer3startvalue;
SIMUL_StartTimer(processor, demoportptr->timer3id, SIMUL_TIMER_REL | SIMUL_TIMER_CLOCKS, &clocks);
return SIMUL_MEMORY_OK;
}
static int SIMULAPI PortReadTimer3(simulProcessor processor, simulCallbackStruct * cbs, simulPtr private)
{
simulTime clocks;
demoPort *demoportptr = (demoPort *) private;
if (!demoportptr->timer3running) {
cbs->x.bus.data = 0;
return SIMUL_MEMORY_OK;
}
SIMUL_GetClock(processor, 0, &clocks);
clocks = clocks-demoportptr->timer3startclock;
cbs->x.bus.data = demoportptr->timer3startvalue - (simulWord) clocks;
return SIMUL_MEMORY_OK;
}
static int SIMULAPI PortCallTimer3(simulProcessor processor, simulCallbackStruct * cbs, simulPtr private)
{
simulWord data;
demoPort *demoportptr = (demoPort *) private;
demoportptr->timer3running = 0;
/* set the interrupt line */
data = 1;
SIMUL_SetPort(processor, SIMUL_PORT_INTERRUPT, 1, &data);
return SIMUL_TIMER_OK;
}
static int SIMULAPI PortResetTimer3(simulProcessor processor, simulCallbackStruct * cbs, simulPtr private)
{
demoPort *demoportptr = (demoPort *) private;
SIMUL_StopTimer(processor, demoportptr->timer3id);
demoportptr->timer3running = 0;
return SIMUL_RESET_OK;
}
static void PortInitTimer3(simulProcessor processor, demoPort * demoportptr)
{
simulWord from, to;
demoportptr->timer3running = 0;
SIMUL_RegisterResetCallback(processor, PortResetTimer3, (simulPtr) demoportptr);
from = demoportptr->startaddress + DEMOPORT_TIMER3REG;
to = demoportptr->startaddress + DEMOPORT_TIMER3REG + DEMOPORT_WIDTH - 1;
SIMUL_RegisterBusWriteCallback(processor, PortWriteTimer3, (simulPtr) demoportptr, demoportptr->bustype, &from, &to);
SIMUL_RegisterBusReadCallback(processor, PortReadTimer3, (simulPtr) demoportptr, demoportptr->bustype, &from, &to);
demoportptr->timer3id = SIMUL_RegisterTimerCallback(processor, PortCallTimer3, (simulPtr) demoportptr);
}
/**************************************************************************
Entry point of the Model
**************************************************************************/
int SIMULAPI SIMUL_Init(simulProcessor processor, simulCallbackStruct * cbs)
{
demoPort *demoportptr;
strcpy(cbs->x.init.modelname, __DATE__ " Demo Port");
demoportptr = (demoPort *) SIMUL_Alloc(processor, sizeof(demoPort));
if (cbs->x.init.argc != 3) {
SIMUL_Warning(processor, "parameters: <address> <portnumber>");
return SIMUL_INIT_FAIL;
}
demoportptr->bustype = cbs->x.init.argpbustype[1];
demoportptr->startaddress = cbs->x.init.argpaddress[1];
demoportptr->baseport = cbs->x.init.argpport[2];
PortInitData1(processor, demoportptr);
PortInitData2(processor, demoportptr);
PortInitData3(processor, demoportptr);
PortInitData4(processor, demoportptr);
PortInitData5(processor, demoportptr);
PortInitTerminal1(processor, demoportptr);
PortInitRam1(processor, demoportptr);
PortInitTimer1(processor, demoportptr);
PortInitTimer2(processor, demoportptr);
PortInitTimer3(processor, demoportptr);
return SIMUL_INIT_OK;
}

View File

@ -0,0 +1,30 @@
wclear
system.up
sim.res
sim.load demoport.dll 20000 0
name.s p.128 timer0
name.s p.129 timer1
name.s p.130 timer2
name.s p.131 timer3
name.s p.132 timer4
name.s p.133 timer5
name.s p.134 timer6
name.s p.135 timer7
name.group g.timer p.timer0 p.timer1 p.timer2 p.timer3 p.timer4 p.timer5 p.timer6 p.timer7
name.word w.timer g.timer
term.protocol sim
winpos ,,,,,,, iconic
term 1 1
winpos ,,,,,,, iconic
port.get
per demoport
enddo

View File

@ -0,0 +1,7 @@
LIBRARY DEMOPORT
DESCRIPTION 'TRACE32 Hardware Simulation Demoport'
EXPORTS
SIMUL_Interface

Binary file not shown.

View File

@ -0,0 +1,44 @@
width 9. 7.
base d:20000
group.long 0--3 "Data1 (Simple Parallel port, available in Portanalyzer)"
line.long 0 "Data1"
group.long 4--7 "Data2 (Simple Parallel port)"
line.long 0 "Data2"
group.long 8--0x0b "Data3 (Parallel port, shared data)"
line.long 0 "Data3"
group.long 100--0x10b "Data4 (Relocatable Parallel port)"
line.long 0 "Data4"
group.byte 0x0c--0x0c "Data5 (Parallel port connected to FILE I/O)"
line.byte 0 "Data5"
group.byte 0x0d--0x0d "Terminal1 (Serial I/O simulation to Terminal I/O)"
line.byte 0 "DATA"
group.byte 0x0e--0x0e
line.byte 0 "STAT"
bitfld 0 7 "TXIE ,TX Interrupt Enable" "no,yes"
bitfld 0 6 " RXIE ,RX Interrupt Enable" "no,yes"
bitfld 0 4 " TWAV ,Terminal Window Available" "yes,no"
bitfld 0 1 " TXR ,TX Ready" "no,yes"
bitfld 0 0 " RXR ,RX Ready" "no,yes"
group.long 0x200--0x20f "Ram1 (Shared memory)"
line.long 0 "00"
line.long 4 "04"
line.long 8 "08"
line.long 0c "0c"
group.long 0x10--0x13 "Timer1 (Incrementing each 100 clockticks)"
line.long 0 "Timer1"
group.long 0x14--0x17 "Timer2 (Incrementing on each Port #0xf0 rising edge)"
line.long 0 "Timer2"
group.long 0x18--0x1b "Timer3 (Decrementing each clockticks after activation)"
line.long 0 "Timer3"

View File

@ -0,0 +1,10 @@
COPTS = -c -W3 -D_X86_=1 -DWIN32 -Z7 -Od -Gs
all: demoport.dll
demoport.dll: demoport.obj simul.obj
link -dll -debug:full -debugtype:cv -out:demoport.dll demoport.obj simul.obj -def:demoport.def
.c.obj: ; cl $(COPTS) $*.c

View File

@ -0,0 +1,7 @@
OBJECTS = demoport.o simul.o
COPTS = +e +z -c -O
demoport.so.1: $(OBJECTS)
ld -b -o demoport.sl $(OBJECTS)
.c.o: ; c89 ${COPTS} $*.c

View File

@ -0,0 +1,7 @@
OBJECTS = demoport.o simul.o
COPTS = -c -O
demoport.so.1: $(OBJECTS)
cc -shared -o demoport.so.1 $(OBJECTS)
.c.o: ; cc ${COPTS} $*.c

View File

@ -0,0 +1,7 @@
OBJECTS = demoport.o simul.o
COPTS = -c -O
demoport.so.1: $(OBJECTS)
cc -G -o demoport.so.1 $(OBJECTS)
.c.o: ; cc ${COPTS} $*.c

View File

@ -0,0 +1,532 @@
#include "simul.h"
/**************************************************************************
Model entry
**************************************************************************/
int SIMULAPI SIMUL_Interface(simulProcessor processor, simulCallbackStruct * cbs)
{
cbs->x.init.version = SIMUL_VERSION;
#if SIMUL_ARCHITECTURE_WIDTH == 8
cbs->x.init.argpword = cbs->x.init.argpword64;
cbs->x.init.argpaddress = cbs->x.init.argpaddress64;
#else
cbs->x.init.argpword = cbs->x.init.argpword32;
cbs->x.init.argpaddress = cbs->x.init.argpaddress32;
#endif
return SIMUL_Init(processor, cbs);
}
/**************************************************************************
Generic configuration functions
**************************************************************************/
void SIMULAPI SIMUL_Printf(simulProcessor processor, const char *format, ...)
{
va_list ap;
va_start(ap, format);
(*((simulProcInfo *) processor)->printf) (processor, format, ap);
va_end(ap);
}
void SIMULAPI SIMUL_Warning(simulProcessor processor, const char *format, ...)
{
va_list ap;
va_start(ap, format);
(*((simulProcInfo *) processor)->warning) (processor, format, ap);
va_end(ap);
}
void SIMULAPI SIMUL_Stop(simulProcessor processor)
{
(*((simulProcInfo *) processor)->stop) (processor);
}
void SIMULAPI SIMUL_Update(simulProcessor processor, int flags)
{
(*((simulProcInfo *) processor)->update) (processor, flags);
}
void * SIMULAPI SIMUL_Alloc(simulProcessor processor, int size)
{
return (*((simulProcInfo *) processor)->alloc)(processor, size);
}
void SIMULAPI SIMUL_Free(simulProcessor processor, void * ptr)
{
(*((simulProcInfo *) processor)->free)(processor, ptr);
}
int SIMULAPI SIMUL_GetEndianess(simulProcessor processor)
{
return ((simulProcInfo *) processor)->endianess;
}
void * SIMULAPI SIMUL_RegisterCommandCallback(simulProcessor processor, simulCallbackFunctionPtr func, simulPtr private)
{
return (*((simulProcInfo *) processor)->registerCommandCallback) (processor, func, private, SIMUL_ARCHITECTURE_WIDTH);
}
void * SIMULAPI SIMUL_RegisterResetCallback(simulProcessor processor, simulCallbackFunctionPtr func, simulPtr private)
{
return (*((simulProcInfo *) processor)->registerResetCallback)(processor, func, private);
}
void * SIMULAPI SIMUL_RegisterExitCallback(simulProcessor processor, simulCallbackFunctionPtr func, simulPtr private)
{
return (*((simulProcInfo *) processor)->registerExitCallback)(processor, func, private);
}
void * SIMULAPI SIMUL_RegisterGoCallback(simulProcessor processor, simulCallbackFunctionPtr func, simulPtr private)
{
return (*((simulProcInfo *) processor)->registerGoCallback)(processor, func, private);
}
void * SIMULAPI SIMUL_RegisterBreakCallback(simulProcessor processor, simulCallbackFunctionPtr func, simulPtr private)
{
return (*((simulProcInfo *) processor)->registerBreakCallback)(processor, func, private);
}
/**************************************************************************
Clocks and Timers
**************************************************************************/
void SIMULAPI SIMUL_GetClockFrequency(simulProcessor processor, int id, simulWord64 * pfrequency)
{
(*((simulProcInfo *) processor)->getClockFrequency)(processor, id, pfrequency);
}
void SIMULAPI SIMUL_SetClockFrequency(simulProcessor processor, int id, simulWord64 * pfrequency)
{
(*((simulProcInfo *) processor)->setClockFrequency)(processor, id, pfrequency);
}
void SIMULAPI SIMUL_GetClockCycle(simulProcessor processor, int id, simulTime * ptime)
{
(*((simulProcInfo *) processor)->getClockCycle)(processor, id, ptime);
}
void SIMULAPI SIMUL_SetClockCycle(simulProcessor processor, int id, simulTime * ptime)
{
(*((simulProcInfo *) processor)->setClockCycle)(processor, id, ptime);
}
void SIMULAPI SIMUL_GetTime(simulProcessor processor, simulTime * ptime)
{
(*((simulProcInfo *) processor)->getTime)(processor, ptime);
}
void SIMULAPI SIMUL_GetClock(simulProcessor processor, int timerid, simulTime * ptime)
{
(*((simulProcInfo *) processor)->getClock) (processor, timerid, ptime);
}
void SIMULAPI SIMUL_Stall(simulProcessor processor, int mode, simulTime * ptime)
{
(*((simulProcInfo *) processor)->stall) (processor, mode, ptime);
}
void SIMULAPI SIMUL_StartTimer(simulProcessor processor, void * timerid, int mode, simulTime * ptime)
{
(*((simulProcInfo *) processor)->startTimer)(processor, timerid, mode, ptime);
}
void SIMULAPI SIMUL_StopTimer(simulProcessor processor, void * timerid)
{
(*((simulProcInfo *) processor)->stopTimer)(processor, timerid);
}
void SIMULAPI SIMUL_StopAllTimer(simulProcessor processor)
{
(*((simulProcInfo *) processor)->stopTimer) (processor);
}
void * SIMULAPI SIMUL_RegisterTimerCallback(simulProcessor processor, simulCallbackFunctionPtr func, simulPtr private)
{
return (*((simulProcInfo *) processor)->registerTimerCallback)(processor, func, private);
}
/**************************************************************************
Buses and Memories
**************************************************************************/
int SIMULAPI SIMUL_ReadMemory(simulProcessor processor, int bustype, simulWord * paddress, int width, int cycletype, simulWord * pdata)
{
#if SIMUL_ARCHITECTURE_WIDTH == 8
return (*((simulProcInfo *) processor)->readMemory64) (processor, bustype, paddress, width, cycletype, pdata);
#else
return (*((simulProcInfo *) processor)->readMemory32) (processor, bustype, paddress, width, cycletype, pdata);
#endif
}
int SIMULAPI SIMUL_WriteMemory(simulProcessor processor, int bustype, simulWord * paddress, int width, int cycletype, simulWord * pdata)
{
#if SIMUL_ARCHITECTURE_WIDTH == 8
return (*((simulProcInfo *) processor)->writeMemory64) (processor, bustype, paddress, width, cycletype, pdata);
#else
return (*((simulProcInfo *) processor)->writeMemory32) (processor, bustype, paddress, width, cycletype, pdata);
#endif
}
void * SIMULAPI SIMUL_RegisterBusWriteCallback(simulProcessor processor, simulCallbackFunctionPtr func, simulPtr private, int bustype, simulWord * paddressFrom, simulWord * paddressTo)
{
return (*((simulProcInfo *) processor)->registerBusWriteCallback)(processor, func, private, bustype, paddressFrom, paddressTo, SIMUL_ARCHITECTURE_WIDTH);
}
void * SIMULAPI SIMUL_RegisterBusReadCallback(simulProcessor processor, simulCallbackFunctionPtr func, simulPtr private, int bustype, simulWord * paddressFrom, simulWord * paddressTo)
{
return (*((simulProcInfo *) processor)->registerBusReadCallback)(processor, func, private, bustype, paddressFrom, paddressTo, SIMUL_ARCHITECTURE_WIDTH);
}
void SIMULAPI SIMUL_RelocateBusCallback(simulProcessor processor, void * callbackid, int bustype, simulWord * paddressFrom, simulWord * paddressTo)
{
(*((simulProcInfo *) processor)->relocateBusCallback)(processor, callbackid, bustype, paddressFrom, paddressTo, SIMUL_ARCHITECTURE_WIDTH);
}
void SIMULAPI SIMUL_InsertWord(simulProcessor processor, simulWord * ptarget , int wordwidth, simulWord * paddress, int width, simulWord * pdata)
{
int offset;
if (width >= wordwidth) {
*ptarget = *pdata;
} else if (width == 8) {
if (((simulProcInfo *) processor)->endianess) {
offset = wordwidth - 8 - ((*paddress << 3) & (wordwidth - 1));
} else {
offset = (*paddress << 3) & (wordwidth - 1);
}
*ptarget = (*ptarget & ~(0xff << offset)) | ((*pdata & 0xff) << offset);
} else if (width == 16) {
if (((simulProcInfo *) processor)->endianess) {
offset = wordwidth - 16 - ((*paddress << 3) & (wordwidth - 1));
} else {
offset = (*paddress << 3) & (wordwidth - 1);
}
*ptarget = (*ptarget & ~(0xffff << offset)) | ((*pdata & 0xffff) << offset);
#if SIMUL_ARCHITECTURE_WIDTH == 8
} else if (width == 32) {
if (((simulProcInfo *) processor)->endianess) {
offset = wordwidth - 32 - ((*paddress << 3) & (wordwidth - 1));
} else {
offset = (*paddress << 3) & (wordwidth - 1);
}
*ptarget = (*ptarget & ~(0xffffffff << offset)) | ((*pdata & 0xffffffff) << offset);
#endif
}
}
void SIMULAPI SIMUL_ExtractWord(simulProcessor processor, simulWord * psource, int wordwidth, simulWord * paddress, int width, simulWord * pdata)
{
int offset;
if (width >= wordwidth) {
*pdata = *psource;
} else if (width == 8) {
if (((simulProcInfo *) processor)->endianess) {
offset = wordwidth - 8 - ((*paddress << 3) & (wordwidth - 1));
} else {
offset = (*paddress << 3) & (wordwidth - 1);
}
*pdata = (*psource >> offset) & 0xff;
} else if (width == 16) {
if (((simulProcInfo *) processor)->endianess) {
offset = wordwidth - 16 - ((*paddress << 3) & (wordwidth - 1));
} else {
offset = (*paddress << 3) & (wordwidth - 1);
}
*pdata = (*psource >> offset) & 0xffff;
#if SIMUL_ARCHITECTURE_WIDTH == 8
} else if (width == 32) {
if (((simulProcInfo *) processor)->endianess) {
offset = wordwidth - 32 - ((*paddress << 3) & (wordwidth - 1));
} else {
offset = (*paddress << 3) & (wordwidth - 1);
}
*pdata = (*psource >> offset) & 0xffffffff;
#endif
}
}
void SIMULAPI SIMUL_SaveWord(simulProcessor processor, void * ptarget, int width, simulWord * pdata)
{
if (((simulProcInfo *) processor)->endianess) {
switch (width>>3) {
#if SIMUL_ARCHITECTURE_WIDTH == 8
case 8:
((unsigned char *) ptarget)[0] = *pdata >> 56;
((unsigned char *) ptarget)[1] = *pdata >> 48;
((unsigned char *) ptarget)[2] = *pdata >> 40;
((unsigned char *) ptarget)[3] = *pdata >> 32;
((unsigned char *) ptarget)[4] = *pdata >> 24;
((unsigned char *) ptarget)[5] = *pdata >> 16;
((unsigned char *) ptarget)[6] = *pdata >> 8;
((unsigned char *) ptarget)[7] = *pdata;
break;
#endif
case 4:
((unsigned char *) ptarget)[0] = *pdata >> 24;
((unsigned char *) ptarget)[1] = *pdata >> 16;
((unsigned char *) ptarget)[2] = *pdata >> 8;
((unsigned char *) ptarget)[3] = *pdata;
break;
case 2:
((unsigned char *) ptarget)[0] = *pdata >> 8;
((unsigned char *) ptarget)[1] = *pdata;
break;
default:
((unsigned char *) ptarget)[0] = *pdata;
break;
}
} else {
switch (width>>3) {
#if SIMUL_ARCHITECTURE_WIDTH == 8
case 8:
((unsigned char *) ptarget)[7] = *pdata >> 56;
((unsigned char *) ptarget)[6] = *pdata >> 48;
((unsigned char *) ptarget)[5] = *pdata >> 40;
((unsigned char *) ptarget)[4] = *pdata >> 32;
#endif
case 4:
((unsigned char *) ptarget)[3] = *pdata >> 24;
((unsigned char *) ptarget)[2] = *pdata >> 16;
case 2:
((unsigned char *) ptarget)[1] = *pdata >> 8;
default:
((unsigned char *) ptarget)[0] = *pdata;
}
}
}
void SIMULAPI SIMUL_LoadWord(simulProcessor processor, void * psource, int width, simulWord * pdata)
{
if (((simulProcInfo *) processor)->endianess) {
switch (width>>3) {
#if SIMUL_ARCHITECTURE_WIDTH == 8
case 8:
{
simulWord low, high;
low = (((unsigned char *) psource)[7]) | (((unsigned char *) psource)[6] << 8)
| (((unsigned char *) psource)[5] << 16) | (((unsigned char *) psource)[4] << 24);
high = (((unsigned char *) psource)[3]) | (((unsigned char *) psource)[2] << 8)
| (((unsigned char *) psource)[1] << 16) | (((unsigned char *) psource)[0] << 24);
*pdata = low | (high << 32);
}
break;
#endif
case 4:
*pdata = (((unsigned char *) psource)[3]) | (((unsigned char *) psource)[2] << 8)
| (((unsigned char *) psource)[1] << 16) | (((unsigned char *) psource)[0] << 24);
break;
case 2:
*pdata = (((unsigned char *) psource)[1]) | (((unsigned char *) psource)[0] << 8);
break;
default:
*pdata = ((unsigned char *) psource)[0];
}
} else {
switch (width>>3) {
#if SIMUL_ARCHITECTURE_WIDTH == 8
case 8:
{
simulWord low, high;
low = (((unsigned char *) psource)[0]) | (((unsigned char *) psource)[1] << 8)
| (((unsigned char *) psource)[2] << 16) | (((unsigned char *) psource)[3] << 24);
high = (((unsigned char *) psource)[4]) | (((unsigned char *) psource)[5] << 8)
| (((unsigned char *) psource)[6] << 16) | (((unsigned char *) psource)[7] << 24);
*pdata = low | (high << 32);
}
break;
#endif
case 4:
*pdata = (((unsigned char *) psource)[0]) | (((unsigned char *) psource)[1] << 8)
| (((unsigned char *) psource)[2] << 16) | (((unsigned char *) psource)[3] << 24);
break;
case 2:
*pdata = (((unsigned char *) psource)[0]) | (((unsigned char *) psource)[1] << 8);
break;
default:
*pdata = ((unsigned char *) psource)[0];
}
}
}
/**************************************************************************
Ports
**************************************************************************/
int SIMULAPI SIMUL_GetPort(simulProcessor processor, int offset, int width, simulWord * pdata)
{
#if SIMUL_ARCHITECTURE_WIDTH == 8
return (*((simulProcInfo *) processor)->getPort64) (processor, offset, width, pdata);
#else
return (*((simulProcInfo *) processor)->getPort32) (processor, offset, width, pdata);
#endif
}
int SIMULAPI SIMUL_SetPort(simulProcessor processor, int offset, int width, simulWord * pdata)
{
#if SIMUL_ARCHITECTURE_WIDTH == 8
return (*((simulProcInfo *) processor)->setPort64) (processor, offset, width, pdata);
#else
return (*((simulProcInfo *) processor)->setPort32) (processor, offset, width, pdata);
#endif
}
void * SIMULAPI SIMUL_RegisterPortChangeCallback(simulProcessor processor, simulCallbackFunctionPtr func, simulPtr private, int offset, int width)
{
return (*((simulProcInfo *) processor)->registerPortChangeCallback)(processor, func, private, offset, width, SIMUL_ARCHITECTURE_WIDTH);
}
/**************************************************************************
Shared Resources
**************************************************************************/
int SIMULAPI SIMUL_CreateSharedResource(simulProcessor processor, int size)
{
return (*((simulProcInfo *) processor)->createSharedResource) (processor, size);
}
int SIMULAPI SIMUL_ReadSharedResource(simulProcessor processor, int offset, int len, void * pdata)
{
return (*((simulProcInfo *) processor)->readSharedResource) (processor, offset, len, pdata);
}
int SIMULAPI SIMUL_WriteSharedResource(simulProcessor processor, int offset, int len, void * pdata)
{
return (*((simulProcInfo *) processor)->writeSharedResource) (processor, offset, len, pdata);
}
/**************************************************************************
File I/O
**************************************************************************/
void * SIMULAPI SIMUL_OpenFile(simulProcessor processor, const char * filename, int mode)
{
return (*((simulProcInfo *) processor)->openFile) (processor, filename, mode);
}
void SIMULAPI SIMUL_CloseFile(simulProcessor processor, void * file)
{
(*((simulProcInfo *) processor)->closeFile) (processor, file);
}
int SIMULAPI SIMUL_ReadFile(simulProcessor processor, void * file, void * pdata, int length)
{
return (*((simulProcInfo *) processor)->readFile) (processor, file, pdata, length);
}
int SIMULAPI SIMUL_WriteFile(simulProcessor processor, void * file, void * pdata, int length)
{
return (*((simulProcInfo *) processor)->writeFile) (processor, file, pdata, length);
}
int SIMULAPI SIMUL_ReadlineFile(simulProcessor processor, void * file, void * pdata, int length)
{
return (*((simulProcInfo *) processor)->readlineFile) (processor, file, pdata, length);
}
int SIMULAPI SIMUL_WritelineFile(simulProcessor processor, void * file, void * pdata)
{
return (*((simulProcInfo *) processor)->writelineFile) (processor, file, pdata);
}
long SIMULAPI SIMUL_SeekFile(simulProcessor processor, void * file, long pos, int mode)
{
return (*((simulProcInfo *) processor)->seekFile) (processor, file, pos, mode);
}
/**************************************************************************
Terminal I/O
**************************************************************************/
int SIMULAPI SIMUL_StateTerminal(simulProcessor processor, int id)
{
return (*((simulProcInfo *) processor)->stateTerminal) (processor, id);
}
int SIMULAPI SIMUL_ReadTerminal(simulProcessor processor, int id)
{
return (*((simulProcInfo *) processor)->readTerminal) (processor, id);
}
int SIMULAPI SIMUL_WriteTerminal(simulProcessor processor, int id, int ch)
{
return (*((simulProcInfo *) processor)->writeTerminal) (processor, id, ch);
}
void * SIMUL_RegisterTerminalCallback(simulProcessor processor, simulCallbackFunctionPtr func, simulPtr private, int id)
{
return (*((simulProcInfo *) processor)->registerTerminalCallback) (processor, func, private, id, SIMUL_ARCHITECTURE_WIDTH);
}

View File

@ -0,0 +1,551 @@
/**************************************************************************
Basic types and includes
**************************************************************************/
#ifdef WIN32
#ifndef _WINDOWS_
#include <windows.h>
#endif
typedef __int64 simulTime;
typedef unsigned __int64 simulWord64;
#define SIMULAPI __cdecl
#else
#include "stdarg.h"
#ifdef NSC32000
typedef QUAD simulTime;
typedef QUAD simulWord64;
#else
typedef long long simulTime;
typedef unsigned long long simulWord64;
#endif
#define SIMULAPI
#endif
typedef unsigned int simulWord32;
#define SIMUL_VERSION 1
#ifdef SIMUL_ARCHITECTURE_64BIT
#define SIMUL_ARCHITECTURE_WIDTH 8
typedef simulWord64 simulWord;
#else
#define SIMUL_ARCHITECTURE_WIDTH 4
typedef simulWord32 simulWord;
#endif
typedef void * simulProcessor;
typedef void * simulPtr;
/**************************************************************************
Internal callback structure (DO NOT ACCESS THIS STRUCTURE)
**************************************************************************/
typedef struct
{
int endianess;
int addresswidth;
int datawidth;
int processortype;
int id;
int resvd1;
int resvd2;
int resvd3;
void (SIMULAPI *printf)();
void (SIMULAPI *warning)();
void (SIMULAPI *stop)();
void (SIMULAPI *update)();
void * (SIMULAPI *alloc)();
void (SIMULAPI *free)();
void * (SIMULAPI *registerCommandCallback)();
void * (SIMULAPI *registerResetCallback)();
void * (SIMULAPI *registerExitCallback)();
void (SIMULAPI *getClockFrequency)();
void (SIMULAPI *setClockFrequency)();
void (SIMULAPI *getClockCycle)();
void (SIMULAPI *setClockCycle)();
void (SIMULAPI *getTime)();
void (SIMULAPI *getClock)();
void (SIMULAPI *stall)();
void (SIMULAPI *startTimer)();
void (SIMULAPI *stopTimer)();
void (SIMULAPI *stopAllTimer)();
void * (SIMULAPI *registerTimerCallback)();
int (SIMULAPI *readMemory32)();
int (SIMULAPI *readMemory64)();
int (SIMULAPI *writeMemory32)();
int (SIMULAPI *writeMemory64)();
void * (SIMULAPI *registerBusReadCallback)();
void * (SIMULAPI *registerBusWriteCallback)();
void (SIMULAPI *relocateBusCallback)();
int (SIMULAPI *getPort32)();
int (SIMULAPI *getPort64)();
int (SIMULAPI *setPort32)();
int (SIMULAPI *setPort64)();
void * (SIMULAPI *registerPortChangeCallback)();
int (SIMULAPI *createSharedResource)();
int (SIMULAPI *readSharedResource)();
int (SIMULAPI *writeSharedResource)();
void * (SIMULAPI *openFile)();
void (SIMULAPI *closeFile)();
int (SIMULAPI *readFile)();
int (SIMULAPI *writeFile)();
int (SIMULAPI *readlineFile)();
int (SIMULAPI *writelineFile)();
long (SIMULAPI *seekFile)();
int (SIMULAPI *readTerminal)();
int (SIMULAPI *writeTerminal)();
int (SIMULAPI *stateTerminal)();
void * (SIMULAPI *registerTerminalCallback)();
void * (SIMULAPI *registerGoCallback)();
void * (SIMULAPI *registerBreakCallback)();
}
simulProcInfo;
/**************************************************************************
Callback structure
**************************************************************************/
#define SIMUL_CALLBACK_INIT 0x0000
#define SIMUL_CALLBACK_BUSREAD 0x0001
#define SIMUL_CALLBACK_BUSWRITE 0x0002
#define SIMUL_CALLBACK_PORTCHANGE 0x0004
#define SIMUL_CALLBACK_TIMER 0x0010
#define SIMUL_CALLBACK_EXIT 0x0020
#define SIMUL_CALLBACK_RESET 0x0040
#define SIMUL_CALLBACK_TERMINAL 0x0080
#define SIMUL_CALLBACK_COMMAND 0x0100
#define SIMUL_CALLBACK_GO 0x0200
#define SIMUL_CALLBACK_BREAK 0x0400
typedef struct
{
int version;
char * modelname;
char * commandline;
int argc;
char ** argp;
int * argpint;
simulWord * argpword;
simulWord32 * argpword32;
simulWord64 * argpword64;
int * argpport;
int * argpbustype;
simulWord * argpaddress;
simulWord32 * argpaddress32;
simulWord64 * argpaddress64;
simulTime * argptime;
}
simulParamCallbackStruct;
typedef struct
{
simulWord address;
simulWord data;
int width;
int cycletype;
int clocks;
}
simulBusCallbackStruct;
typedef struct
{
simulWord32 address;
simulWord32 data;
int width;
int cycletype;
int clocks;
}
simulBusCallbackStruct32;
typedef struct
{
simulWord64 address;
simulWord64 data;
int width;
int cycletype;
int clocks;
}
simulBusCallbackStruct64;
typedef struct
{
simulWord newdata;
simulWord olddata;
}
simulPortCallbackStruct;
typedef struct
{
simulWord32 newdata;
simulWord32 olddata;
}
simulPortCallbackStruct32;
typedef struct
{
simulWord64 newdata;
simulWord64 olddata;
}
simulPortCallbackStruct64;
typedef struct
{
int data;
}
simulTerminalCallbackStruct;
typedef struct
{
int type;
simulTime time;
union {
simulParamCallbackStruct init;
simulParamCallbackStruct command;
simulBusCallbackStruct bus;
simulBusCallbackStruct32 bus32;
simulBusCallbackStruct64 bus64;
simulPortCallbackStruct port;
simulPortCallbackStruct32 port32;
simulPortCallbackStruct64 port64;
simulTerminalCallbackStruct terminal;
} x;
}
simulCallbackStruct;
typedef int (SIMULAPI * simulCallbackFunctionPtr)(simulProcessor processor, simulCallbackStruct *, simulPtr private);
#ifdef __cplusplus
extern "C" {
#endif
/**************************************************************************
Model entry definition
**************************************************************************/
#define SIMUL_INIT_OK 1
#define SIMUL_INIT_FAIL -1
extern int SIMULAPI SIMUL_Init(simulProcessor processor, simulCallbackStruct * cbs);
/**************************************************************************
Generic configuration functions
**************************************************************************/
extern void SIMULAPI SIMUL_Printf(simulProcessor processor, const char *format, ...);
extern void SIMULAPI SIMUL_Warning(simulProcessor processor, const char *format, ...);
extern void SIMULAPI SIMUL_Stop(simulProcessor processor);
extern void SIMULAPI SIMUL_Update(simulProcessor processor, int flags);
extern void * SIMULAPI SIMUL_Alloc(simulProcessor processor, int size);
extern void SIMULAPI SIMUL_Free(simulProcessor processor, void * ptr);
#define SIMUL_ENDIANESS_LITTLE 0
#define SIMUL_ENDIANESS_BIG 1
extern int SIMULAPI SIMUL_GetEndianess(simulProcessor processor);
#define SIMUL_COMMAND_OK 1
#define SIMUL_COMMAND_FAIL -1
extern void * SIMULAPI SIMUL_RegisterCommandCallback(simulProcessor processor, simulCallbackFunctionPtr func, simulPtr private);
#define SIMUL_RESET_OK 1
extern void * SIMULAPI SIMUL_RegisterResetCallback(simulProcessor processor, simulCallbackFunctionPtr func, simulPtr private);
#define SIMUL_EXIT_OK 1
extern void * SIMULAPI SIMUL_RegisterExitCallback(simulProcessor processor, simulCallbackFunctionPtr func, simulPtr private);
#define SIMUL_GO_OK 1
extern void * SIMULAPI SIMUL_RegisterGoCallback(simulProcessor processor, simulCallbackFunctionPtr func, simulPtr private);
#define SIMUL_BREAK_OK 1
extern void * SIMULAPI SIMUL_RegisterBreakCallback(simulProcessor processor, simulCallbackFunctionPtr func, simulPtr private);
/**************************************************************************
Clocks and Timers
**************************************************************************/
#define SIMUL_TIMER_OK 1
#define SIMUL_CLOCK_CORE 0
#define SIMUL_CLOCK_BUS 1
#define SIMUL_CLOCK_POWERPC_TIMEBASE 2
extern void SIMULAPI SIMUL_GetClockFrequency(simulProcessor processor, int clockid, simulWord64 * pfrequency);
extern void SIMULAPI SIMUL_SetClockFrequency(simulProcessor processor, int clockid, simulWord64 * pfrequency);
extern void SIMULAPI SIMUL_GetClockCycle(simulProcessor processor, int clockid, simulTime * ptime);
extern void SIMULAPI SIMUL_SetClockCycle(simulProcessor processor, int clockid, simulTime * ptime);
extern void SIMULAPI SIMUL_GetTime(simulProcessor processor, simulTime * ptime);
extern void SIMULAPI SIMUL_GetClock(simulProcessor processor, int clockid, simulTime * ptime);
#define SIMUL_STALL_ABS 0x000
#define SIMUL_STALL_REL 0x100
#define SIMUL_STALL_CLOCKS 0x400
extern void SIMULAPI SIMUL_Stall(simulProcessor processor, int mode, simulTime * ptime);
/* timer modes */
#define SIMUL_TIMER_ABS 0x000
#define SIMUL_TIMER_REL 0x100
#define SIMUL_TIMER_SINGLE 0x000
#define SIMUL_TIMER_REPEAT 0x200
#define SIMUL_TIMER_CLOCKS 0x400
extern void SIMULAPI SIMUL_StartTimer(simulProcessor processor, void * timerid, int mode, simulTime * ptime);
extern void SIMULAPI SIMUL_StopTimer(simulProcessor processor, void * timerid);
extern void SIMULAPI SIMUL_StopAllTimer(simulProcessor processor);
extern void * SIMULAPI SIMUL_RegisterTimerCallback(simulProcessor processor, simulCallbackFunctionPtr func, simulPtr private);
/**************************************************************************
Buses and Memories
**************************************************************************/
/* return values for bus callback functions */
#define SIMUL_MEMORY_CONTINUE 0
#define SIMUL_MEMORY_OK 1
#define SIMUL_MEMORY_FAIL -1
/* cycle types */
#define SIMUL_MEMORY_HIDDEN 0x00
#define SIMUL_MEMORY_FETCH 0x02
#define SIMUL_MEMORY_DATA 0x04
#define SIMUL_MEMORY_DMA 0x08
#define SIMUL_MEMORY_DEFAULT 0
#define SIMUL_MEMORY_POWERPC_SPR 1
#define SIMUL_MEMORY_POWERPC_DCR 2
#define SIMUL_MEMORY_ARM_CPX 1
#define SIMUL_MEMORY_SH_INTACK 255
#define SIMUL_MEMORY_M68K_INTACK 255
extern int SIMULAPI SIMUL_ReadMemory(simulProcessor processor, int bustype, simulWord * paddress, int width, int cycletype, simulWord * pdata);
extern int SIMULAPI SIMUL_WriteMemory(simulProcessor processor, int bustype, simulWord * paddress, int width, int cycletype, simulWord * pdata);
extern void * SIMULAPI SIMUL_RegisterBusReadCallback(simulProcessor processor, simulCallbackFunctionPtr func, simulPtr private, int bustype, simulWord * paddressFrom, simulWord * paddressTo);
extern void * SIMULAPI SIMUL_RegisterBusWriteCallback(simulProcessor processor, simulCallbackFunctionPtr func, simulPtr private, int bustype, simulWord * paddressFrom, simulWord * paddressTo);
extern void SIMULAPI SIMUL_RelocateBusCallback(simulProcessor processor, void * callbackid, int bustype, simulWord * paddressFrom, simulWord * paddressTo);
extern void SIMULAPI SIMUL_InsertWord(simulProcessor processor, simulWord * ptarget, int wordwidth, simulWord * paddress, int width, simulWord * pdata);
extern void SIMULAPI SIMUL_ExtractWord(simulProcessor processor, simulWord * psource, int wordwidth, simulWord * paddress, int width, simulWord * pdata);
extern void SIMULAPI SIMUL_SaveWord(simulProcessor processor, void * ptarget, int width, simulWord * pdata);
extern void SIMULAPI SIMUL_LoadWord(simulProcessor processor, void * psource, int width, simulWord * pdata);
/**************************************************************************
Ports
**************************************************************************/
/* predefined core ports */
#define SIMUL_PORT_RESET -1
#define SIMUL_PORT_INTERRUPT -2
#define SIMUL_PORT_PPC_INT -2
#define SIMUL_PORT_ARM_IRQ -2
#define SIMUL_PORT_ARM_FIQ -3
#define SIMUL_PORT_SH_IRL0 -2
#define SIMUL_PORT_SH_IRL1 -3
#define SIMUL_PORT_SH_IRL2 -4
#define SIMUL_PORT_SH_IRL3 -5
#define SIMUL_PORT_MIPS_NMI -2
#define SIMUL_PORT_MIPS_INT0 -3
#define SIMUL_PORT_MIPS_INT1 -4
#define SIMUL_PORT_MIPS_INT2 -5
#define SIMUL_PORT_MIPS_INT3 -6
#define SIMUL_PORT_MIPS_INT4 -7
#define SIMUL_PORT_MIPS_INT5 -8
#define SIMUL_PORT_M68K_IRL0 -2
#define SIMUL_PORT_M68K_IRL1 -3
#define SIMUL_PORT_M68K_IRL2 -4
#define SIMUL_PORT_C166_IRL0 -2
#define SIMUL_PORT_C166_IRL1 -3
#define SIMUL_PORT_C166_IRL2 -4
#define SIMUL_PORT_C166_IRL3 -5
#define SIMUL_PORT_C166_NMI -6
/* return values for port callback functions */
#define SIMUL_PORT_OK 1
extern int SIMULAPI SIMUL_GetPort(simulProcessor processor, int offset, int width, simulWord * pdata);
extern int SIMULAPI SIMUL_SetPort(simulProcessor processor, int offset, int width, simulWord * pdata);
extern void * SIMULAPI SIMUL_RegisterPortChangeCallback(simulProcessor processor, simulCallbackFunctionPtr func, simulPtr private, int offset, int width);
/**************************************************************************
Shared Resources
**************************************************************************/
extern int SIMULAPI SIMUL_CreateSharedResource(simulProcessor processor, int size);
extern int SIMULAPI SIMUL_ReadSharedResource(simulProcessor processor, int offset, int len, void * pdata);
extern int SIMULAPI SIMUL_WriteSharedResource(simulProcessor processor, int offset, int len, void * pdata);
/**************************************************************************
File I/O
**************************************************************************/
/* file modes */
#define SIMUL_FILE_READ 0x001
#define SIMUL_FILE_WRITE 0x002
#define SIMUL_FILE_CREATE 0x010
#define SIMUL_FILE_APPEND 0x020
#define SIMUL_FILE_BINARY 0x000
#define SIMUL_FILE_ASCII 0x100
extern void * SIMULAPI SIMUL_OpenFile(simulProcessor processor, const char * filename, int mode);
extern void SIMULAPI SIMUL_CloseFile(simulProcessor processor, void * file);
extern int SIMULAPI SIMUL_ReadFile(simulProcessor processor, void * file, void * pdata, int length);
extern int SIMULAPI SIMUL_WriteFile(simulProcessor processor, void * file, void * pdata, int length);
extern int SIMULAPI SIMUL_ReadlineFile(simulProcessor processor, void * file, void * pdata, int length);
extern int SIMULAPI SIMUL_WritelineFile(simulProcessor processor, void * file, void * pdata);
#define SIMUL_FILE_SEEKABS 0
#define SIMUL_FILE_SEEKREL 1
#define SIMUL_FILE_SEEKEND 2
extern long SIMULAPI SIMUL_SeekFile(simulProcessor processor, void * file, long pos, int mode);
/**************************************************************************
Terminal I/O
**************************************************************************/
/* status bits */
#define SIMUL_STATE_RXREADY 0x001
#define SIMUL_STATE_TXREADY 0x002
#define SIMUL_STATE_NOTEXISTING 0x010
extern int SIMULAPI SIMUL_ReadTerminal(simulProcessor processor, int id);
extern int SIMULAPI SIMUL_WriteTerminal(simulProcessor processor, int id, int ch);
extern int SIMULAPI SIMUL_StateTerminal(simulProcessor processor, int id);
extern void * SIMUL_RegisterTerminalCallback(simulProcessor processor, simulCallbackFunctionPtr func, simulPtr private, int id);
/**************************************************************************
End of Include
**************************************************************************/
#ifdef __cplusplus
}
#endif

View File

@ -0,0 +1,27 @@
;Add some extra buttons to the toolbar
menu.rp
(
add
toolbar
(
separator
toolitem "Source/List" ":list" "Data.List"
toolitem "Memory Dump" ":dump" "Data.dump"
toolitem "Register" ":reg" "Register /SpotLight"
separator
toolitem "Watch" ":var" "Var.Watch"
toolitem "Stack" ":varframe" "Var.Frame /l /c"
toolitem "Automatic Watch" ":varref" "Var.Ref"
separator
toolitem "List Breakpoints" ":break" "Break.List"
toolitem "List Symbols" ":symbols" "sYmbol.Browse"
toolitem "List Tracebuffer" ":alist" "Analyzer.List"
separator
)
)
do demoport
enddo

View File

@ -0,0 +1,12 @@
F DEMOPORT.C demoport.c
F DEMOPORT.CMM demoport.cmm
F DEMOPORT.DEF demoport.def
F DEMOPORT.DLL demoport.dll
F DEMOPORT.PER demoport.per
F MAKEFILE. makefile
F MAKEHP. makehp
F MAKELINUX. makelinux
F MAKESUN. makesun
F SIMUL.C simul.c
F SIMUL.H simul.h
F T32.CMM t32.cmm