Table of Contents Previous topic Next topic
Extension Examples->Memory Bank Switching->Extension Source Code
/*
* This single file is a complete extension, written in C, for the Crossware 8051 Virtual Workshop.
* It provides support for multiple xdata memory banks.
*
* As written (ie using DllExport), it will compile with the Microsoft Visual C++ compiler.
*
* Copyright (c) 1998 Crossware Products.
*
* This source code is provided as an example to complement the Crossware 8051 Virtual Workshop.
*/
#define DllExport __declspec( dllexport )
#define LONG long
#define BYTE unsigned char
#define TRUE 1
#define FALSE 0
// There are the four memory banks 0, 1, 2 and 3
// The simulator looks after bank 0, this extension looks after banks 1, 2 and 3
// The banks are at the top 32k of memory - addresses 0X8000 to 0XFFFF
// They are selected using port pins P1.0 and P1.1
#define MEMORY_BANK_SIZE 0X8000
BYTE g_nBank1[MEMORY_BANK_SIZE];
BYTE g_nBank2[MEMORY_BANK_SIZE];
BYTE g_nBank3[MEMORY_BANK_SIZE];
int g_nMemoryBank; // = 0
LONG* g_pnError; // placing a non-zero value in here will halt the simulator
DllExport LONG Initialise(LONG* pnError)
{
g_pnError = pnError; // save the address of the simulators error indicator
return 1; // must return a non-zero value otherwise extension will be ignored
}
DllExport LONG GetXDataMemory(LONG nExtensionState, int nAddress, BYTE* pByte, LONG nSimulating)
{
if (nAddress >= 0X8000)
{
// accessing the top 32k of memory if here
switch (g_nMemoryBank)
{
case 1:
*pByte = g_nBank1[nAddress - 0X8000];
return TRUE;
case 2:
*pByte = g_nBank2[nAddress - 0X8000];
return TRUE;
case 3:
*pByte = g_nBank3[nAddress - 0X8000];
return TRUE;
case 0:
return FALSE; // handled by simulator
}
}
return FALSE;
}
DllExport LONG SetXDataMemory(LONG nExtensionState, int nAddress, BYTE nValue, LONG nSimulating)
{
if (nAddress >= 0X8000)
{
// accessing the top 32k of memory if here
switch (g_nMemoryBank)
{
case 1:
g_nBank1[nAddress - 0X8000] = nValue;
return TRUE;
case 2:
g_nBank2[nAddress - 0X8000] = nValue;
return TRUE;
case 3:
g_nBank3[nAddress - 0X8000] = nValue;
return TRUE;
case 0:
return FALSE; // handled by simulator
}
}
return FALSE;
}
DllExport void ClearXDataMemory(LONG nExtensionState, int nFillByte)
{
int i;
for (i = 0; i < MEMORY_BANK_SIZE; i++)
{
g_nBank1[i] = nFillByte;
g_nBank2[i] = nFillByte;
g_nBank3[i] = nFillByte;
}
}
DllExport LONG SetPortPins(LONG nExtensionState, BYTE nPortAddress, BYTE nPins, LONG bSimulating)
{
// returning TRUE will cause the views to be updated
// keep track of port 1, this controls the xdata memory bank in use
if (nPortAddress == 0X90)
{
// port 1 if here
switch (nPins & 0X03)
{
case 0X03: // 11 is bank 0 (power up condition)
if (g_nMemoryBank != 0)
{
g_nMemoryBank = 0;
return TRUE;
}
case 0X02: // 10 is bank 2
if (g_nMemoryBank != 2)
{
g_nMemoryBank = 2;
return TRUE;
}
case 0X01: // 01 is bank 1
if (g_nMemoryBank != 1)
{
g_nMemoryBank = 1;
return TRUE;
}
break;
case 0X00: // 00 is bank 3
if (g_nMemoryBank != 3)
{
g_nMemoryBank = 3;
return TRUE;
}
break;
}
}
return FALSE;
}