Crossware

Table of Contents        Previous topic       Next topic       

C COMPILER->Code Bank Switching->Using the Bank Pragma

The bank pragma is placed in your source file ahead of any functions that you wish to be placed in banked memory.  The bank pragma can also be used to turn off code banking if it has been enabled earlier in the file.  See #pragma bank for details of the syntax.

The following example illustrate the use of the bank pragma:

#pragma bank("functions", 1, "port", 0X90, 0X02, 0X0F)

func(int f)
{
    int j;
    f++;
    j++;
}

#pragma bank("functions", 0, "port", 0X90, 0X01, 0X0F)

func1(int f1)
{
    int j;
    f1++;
    j++;
}

func2(int f2)
{
    int j;
    f1++;
    j++;
}


#pragma bank("functions", -1)

func3(int f3)
{
    int j;
    f3++;
    j++;
}

Function func() will be placed in bank 1.  Bank 1 is activated by a write to port 1 (address 0X90) with a value of 0X02.  The mask is 0X0F indicating that pins 0, 1, 2 and 3 are used to switch banks.  The compiler will generate the following code to automatically switch banks and call the main body of func():

    PUSH __LastBank
    ANL 090h,#not(0Fh)
    ORL 090h,#02h
    MOV __LastBank,#02h
    CALL _func_banked
    POP ACC
    ANL 090h,#not(0Fh)
    ORL 090h,A
    MOV __LastBank,A

The main body of func() is at location _func_banked in code bank 1.

This portion of code will be located in unbanked code space and so function func() can be called from anywhere, including a different code bank.  There is therefore no need to be concerned about where banked functions are located - any banked function can be called from anywhere.

Functions func1() and func2() will be placed in bank 0.  Bank 0 is activated by a write to port 1 (address 0X90) with a value of 0X01.  The mask is 0X0F indicating that pins 0, 1, 2 and 3 are used to switch banks.  The compiler will generate the following code to automatically switch banks and call the main body of func1():

    PUSH __LastBank
    ANL 090h,#not(0Fh)
    ORL 090h,#01h
    MOV __LastBank,#01h
    CALL _func1_banked
    POP ACC
    ANL 090h,#not(0Fh)
    ORL 090h,A
    MOV __LastBank,A

A similar code sequence except that _func1_banked will be replaced with _func2_banked will be generated for func2().

Function func3() will be placed in normal code space and will be called normally.


If port 1 was not being used for any other function, then it would have been more efficient to use:

#pragma bank("functions", 0, "port", 0X90, 0X01, 0XFF)

When the mask is 0XFF, the compiler does not need to use a mask and can write the bank switch value directly:

    PUSH __LastBank
    MOV 090h,#01h
    MOV __LastBank,#01h
    CALL _func1_banked
    POP ACC
    MOV 090h,A
    MOV __LastBank,A

This is shorted and faster than the masked alternative so use a mask of 0XFF if you can.

If the code bank is switched by a write to memory mappped i/o, then the pragma might be:

#pragma bank("functions", 0, "xdata", 0XFFEE, 0X01, 0XFF)

If the body of func1() follows this pragma, the compiler will generate the following code to automatically switch code banks:

    PUSH __LastBank
    MOV dptr,#0FFEEh
    MOV A,#01h
    MOVX @dptr,A
    MOV __LastBank,A
    CALL _func1_banked
    POP ACC
    MOV __LastBank,A
    MOV dptr,#0FFEEh
    MOVX @dptr,A

Note that the mask is 0XFF.  Since the ANL/ORL instructions are not supported for xdata, only the 0XFF mask is supported.  (If you use a different mask value, a warning will be issued and 0XFF will be used anyway).