Crossware

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;
}