The 78K0/Kx2 has a memory bank function. What is this function and how should it be used?
[Introduction]
Generally, the architecture of an 8-bit microcontroller uses a memory of up to 64 KB by using 16 address signals.
If the basic architecture (instruction system) of a microcontroller were to be changed, a memory of 64 KB or more could still be used, but this would make the microcontroller totally different.
(Also refer to "Microcontroller and Memory".)
[Memory bank]
Methods called bank switching and memory banking are used to access a memory of more than 64 KB without having to substantially change the specifications of a conventional microcontroller. These methods overlap some memories on some areas of the memory that the microcontroller can directly handle, without changing the memory range (64 KB in this case) of the microcontroller, as illustrated below.
By the normal memory allocation, addresses correspond to a memory on a one-to-one basis. By the memory bank method shown above on the right, however, two or more memory banks (four banks in this example) correspond to one address in a bank area (16 KB of 8000 to BFFF in this example). The number of memory banks that can be handled can be increased by increasing the number of memory banks corresponding to one address. Note, however, that, although two or more memory banks correspond to one address, this does not mean that all of these banks are accessible. In the bank area, one memory bank to be used (accessed) is specified in advance by a bank select signal. When the bank area is accessed, therefore, one memory bank that has been specified can be selected and accessed. The procedure for this is as follows.
Manipulation |
|
Operation of corresponding hardware |
| (1) Select a bank to use. |
→ |
One memory bank is selected by the bank select signal. |
| (2) Access the bank area. |
→ |
Memory at the corresponding address of the memory bank specified in (1) is accessed. |
|
By using these two steps, memory at any address in any memory bank can be accessed. However, this is a method to access a memory bank while the program is executed in the ordinary memory. If the program runs in a memory bank, other memory banks cannot be directly accessed. To access another memory bank, the program must be moved to the ordinary memory and the memory bank must be changed.
[Using memory banks]
Memory banks extend the memory without substantially changing the specifications of the microcontroller. They are not frequently used when the microcontroller is used. In particular, to enhance the efficiency of memory access, clarify the usage of the memory banks and do not change the banks frequently. We recommend using the memory areas as follows.
| Ordinary memory area: |
Program entity, and routine and data commonly used
Processing asynchronous with program execution, such as interrupt
Processing with limited processing time |
| Bank area: |
Processing to be closed in a bank area and its data
Processing and data that are not often used
Processing wherein processing time has some leeway
Data having few access time limits |
|
If this recommendation is followed, processing that extends one memory bank to another is limited. Therefore, prepare processing that changes the address bank at a fixed address of the ordinary memory only when processing to extend from one memory bank to another is necessary, and change the memory bank by using this processing. An example of calling a subroutine of memory bank 1 from memory bank 0 by using this method is given below.
In this example, the subroutine named TARGET in memory bank 1 is called, exceeding the memory bank. In the ordinary memory area, the subroutine named ENTRY is prepared as processing that serves as a stepping-stone for calling subroutine TARGET. Subroutine ENTRY performs processing for changing the memory bank, calls the target subroutine TARGET, restores the memory bank, and returns.
If ENTRY in the ordinary memory area is called from memory bank 1 in this situation <1>, TARGET in memory bank 1 is called from there <2>. When processing of TARGET is completed, execution once returns to ENTRY <3> and then to memory bank 0 <4>. Preparing a stepping-stone for each subroutine in the ordinary memory area will therefore allow the subroutines of the other memory banks to be used.
A specific example of the program that should be prepared in the ordinary memory area is shown below. The memory of saddr area is used for works (such as holding and transferring data). For the saddr area, refer to "Microcontroller and Memory".
(1) Program example 1
In this example, 1 byte (R_BNKN) of RAM of the saddr area is used as a work area to prevent destruction of the register contents.
| ; |
|
| ; |
Input parameter |
| ; |
None |
| ; |
Output parameter |
| ; |
None |
| ; |
|
| ENTRY: |
|
|
|
|
MOV |
R_BNKN,A |
; Saves the A register. |
|
MOV |
A,#BANKNUM TARGET |
; Specifies the bank number of a subroutine. |
|
XCH |
A,BANK |
; Sets the bank at the return destination |
|
|
|
; and the bank number of the subroutine. |
|
XCH |
A,R_BNKN |
; Restores the A register and saves the original bank. |
|
CALL |
!TARGET |
; Calls the actual subroutine. |
|
XCH |
A,R_BNKN |
|
|
MOV |
BANK,A |
; Sets the bank of return destination. |
|
MOV |
A,R_BNKN |
|
|
RET |
|
|
(2) Program example 2
If it is absolutely necessary to move from one memory bank to another, at least two of the above program must be used. However, the program in Example 1 cannot support multiple calls between banks because it saves the return destination bank number to the work memory (R_BNKN) in the saddr area when it calls a subroutine in another bank. In this case, save the value, which must not be lost (the bank number of the return destination), to stack as shown below. Note that 2 bytes of RAM (RSAVEAX) in the saddr area are used as a work area in this example because the AX register is used as a work register.
| ; |
|
| ; |
Input parameter |
| ; |
None |
| ; |
Output parameter |
| ; |
None |
| ; |
|
| ENTRY2: |
|
|
|
|
MOV |
RSAVEAX,A |
; Saves the A register. |
|
MOV |
A,#BANKNUM TARGET |
|
|
XCH |
A,BANK |
; Reads the bank of the return destination |
|
|
|
; and sets the bank number of the subroutine. |
|
PUSH |
AX |
; Saves the return destination bank to stack. |
|
MOV |
A, RSAVEAX |
; Restores the A register. |
|
CALL |
!TARGET |
; Calls the actual subroutine. |
|
MOVW |
RSAVEAX,AX |
; Saves the AX register. |
|
POP |
AX |
|
|
MOV |
BANK,A |
; Sets the return destination bank. |
|
MOVW |
AX,RSAVEAX |
; Restores the AX register. |
|
RET |
|
|
(3) Program example 3
If many subroutines move between memory banks, it is not efficient to prepare as many programs that serve as a stepping-stone. In such a case, a general-purpose program is used as illustrated below. This program calls a subroutine by setting the bank number of the subroutine to R_BANK of the saddr area and its address to R_BNKA. Moreover, a 2-byte RAM area (RSAVEAX) is used as a work area during processing. This program does not destroy the values of registers when the subroutine is called and when execution returns from the subroutine. Therefore, subroutine call is processed in two steps by using a dummy call.
As an operation, set the bank number and address of the subroutine to be called in the saddr area in <1>, then call the stepping-stone program in <2>. The stepping-stone program sets the bank number of the saddr area to the BANK register and then calls the subroutine in the post-processing block (BNLCALSA2) in <3>. The post-processing block saves the address of the subroutine to stack, and branches to the subroutine specified by the RET instruction in <4>. The subroutine performs the necessary processing, and execution is returned to the stepping-stone program by the RET instruction in <5>. The stepping-stone program restores the bank number before call to the BANK register and returns execution to the program of the calling source by using the RET instruction in <6>.
The specific program is as follows.
| ; |
|
| ; |
Input parameter |
| ; |
R_BNKN: Bank number at reference destination |
| ; |
R_BNKA: Address at reference destination |
| ; |
Output parameter |
| ; |
None |
| ; |
|
| ENTRY3: |
|
|
; Processing routing for calling between memory banks |
|
MOVW |
RSAVEAX,AX |
; Saves the AX register. |
|
MOV |
A,R_BNKN |
; Obtains the bank number at the call destination. |
|
XCH |
A,BANK |
; Changes the bank and obtains the return destination bank. |
|
PUSH |
AX |
; Saves the memory bank number of the return destination to stack. |
|
CALL |
!BNKCALSA2 |
; Dummy call to branch to the call destination. |
|
MOVW |
RSAVEAX,AX |
; Saves the AX register. |
|
POP |
AX |
; Obtains the return destination bank number. |
|
MOV |
BANK,A |
; Specifies the memory bank number of the return destination. |
|
MOVW |
AX,RSAVEAX |
; Restores the AX register. |
|
RET |
|
; Returns to the call destination. |
| BNKCALSA2: |
|
|
|
|
MOVW |
AX,R_BNKA |
; Specifies the address of the call destination. |
|
PUSH |
AX |
; Sets the call destination to stack. |
|
MOVW |
AX,RSAVEAX |
; Restores the original value of the AX register. |
|
RET |
|
; Branches to the call destination. |
This program is hard to use as is because the processing to set the bank number and address of the subroutine must be described each time the stepping-stone is used. To avoid this, define a macro as follows.
| BNKCAL |
MACRO |
PARA1 |
|
|
MOV |
R_BNKN,#BANKNUM PARA1 |
; Stores the memory bank number of the reference destination. |
|
MOVW |
R_BNKA,#PARA1 |
; Stores the address of the reference destination. |
|
CALL |
!ENTRY3 |
|
|
ENDM |
|
|
In this way, the stepping-stone program can be used with ease only by describing the following program by using the BNKCAL instruction that defines a new macro, instead of describing three instructions.
(4) Program branch processing between memory banks
A subroutine call that extends from one memory bank to another was explained above. Next, an example of a program for branching is explained.
For branching to a fixed address, the following two simple instructions are prepared in the ordinary memory area. Because the processing is simple, only arranging these instructions can serve a practical purpose. The program at the branch source only has to branch to this stepping-stone program.
| ; |
|
| ; |
Input parameter |
| ; |
None |
| ; |
Output parameter |
| ; |
None |
| ; |
|
| ENTRY4: |
|
|
|
|
MOV |
BANK,#BANKNUM TARGET |
|
|
BR |
!TARGET |
|
For your reference, an example of a program that branches between general-purpose memory banks is given below. This program is for reference only because it requires many instructions and, to use this program, the bank number and address at the branch destination to be set in the saddr area in advance.
| ; |
|
| ; |
Input parameter |
| ; |
R_BNKN: Bank number at reference destination |
| ; |
R_BNKA: Address at reference destination |
| ; |
Output parameter |
| ; |
None |
| ; |
|
| ENTRY5: |
|
|
|
|
MOVW |
RSAVEAX,AX |
; Saves the AX register. |
|
MOV |
A,R_BNKN |
; |
|
MOV |
BANK,A |
; Specifies the memory bank number of the branch destination. |
|
MOVW |
AX,R_BNKA |
; Specifies the address of the branch destination. |
|
PUSH |
AX |
; Sets the branch destination address to stack. |
|
MOVW |
AX,RSAVEAX |
; Restores the AX register at the branch source. |
|
RET |
|
; Branches to the branch destination. |
In this case also, only "BNKBR TARGET" has to be described if a macro is defined.
| BNKBR |
MACRO |
PARA1 |
|
|
MOV |
R_BNKN,#BANKNUM PARA1 |
; Stores the memory bank number of the reference destination. |
|
MOVW |
R_BNKA,#PARA1 |
; Stores the address of reference destination. |
|
BR |
!ENTRY5 |
|
|
ENDM |
|
|
(5) Data reference processing between memory banks
A program example of processing to reference data between memory banks is given next. In this example, the necessary parameters are transferred by using registers.
| ; |
|
| ; |
Input parameter |
| ; |
A register: Bank number of reference destination |
| ; |
HL register: Address of reference destination |
| ; |
Output parameter |
| ; |
A register: Reference result |
| ; |
|
| ENTRY6: |
|
|
|
|
XCH |
A,BANK |
; Exchanges the bank of the reference source with that of the reference destination. |
|
MOV |
R_BNKN,A |
; Saves the memory bank number of the reference source. |
|
MOV |
A,[HL] |
; Read the target value. |
|
XCH |
A,R_BNKN |
; Obtains the memory bank number of the reference source. |
|
MOV |
BANK,A |
; Specifies the memory bank number of the reference source. |
|
MOV |
A,R_BNKN |
; Restores the reference result to the A register. |
|
RET |
|
|
An example of integrating a general-purpose subroutine call and input parameters is also given for your reference.
| ; |
|
| ; |
Input parameter |
| ; |
R_BNKN: Bank number of reference destination |
| ; |
R_BNKA: Address of reference destination |
| ; |
Output parameter |
| ; |
A register: Reference result |
| ; |
|
| ENTRY7: |
|
|
; Subroutine for referencing between memory banks |
|
PUSH |
HL |
; Saves the contents of the HL register. |
|
MOV |
A,R_BNKN |
; |
|
XCH |
A,BANK |
; Exchanges the bank number of the reference source |
|
|
|
; with that of the reference destination. |
|
MOV |
R_BNKN,A |
; Saves the memory bank number of the reference source. |
|
XCHW |
AX,HL |
; Saves the X register. |
|
MOVW |
AX,R_BNKA |
; |
|
XCHW |
AX,HL |
; Specifies the address of the reference destination. |
|
MOV |
A,[HL] |
; Reads the target value. |
|
XCH |
A,R_BNKN |
; Obtains the memory bank number of the reference source. |
|
MOV |
BANK,A |
; Specifies the memory bank number of the reference source. |
|
MOV |
A,R_BNKN |
; |
|
POP |
HL |
; Restores the contents of the HL register. |
|
RET |
|
; Return |