L51_BANK.A51
上传用户:hjhsjcl
上传日期:2020-09-25
资源大小:11378k
文件大小:40k
源码类别:

压缩解压

开发平台:

C++ Builder

  1. $NOMOD51 NOLINES
  2. $NOCOND
  3. ;------------------------------------------------------------------------------
  4. ;  This file is part of the BL51 / LX51 Banked Linker/Locater package
  5. ;  Copyright (c) 1988 - 2002 Keil Elektronik GmbH and Keil Software, Inc.
  6. ;  Version 2.13 (Code and Variable Banking for Classic 8051 Derivatives)
  7. ;------------------------------------------------------------------------------
  8. ;************************ Configuration Section *******************************
  9. ?B_NBANKS       EQU  2    ; Define maximum Number of Banks                    *
  10. ;                         ; following values are allowed: 2, 4, 8, 16, 32, 64 *
  11. ;                         ; for BL51 the maximum value for ?B_BANKS is 32     *
  12. ;                         ; for LX51 the maximum value for ?B_BANKS is 64     *
  13. ;                                                                             *
  14. ?B_MODE         EQU  4    ; 0 for Bank-Switching via 8051 Port                *
  15. ;                         ; 1 for Bank-Switching via XDATA Port               *
  16. ;                         ; 4 for user-provided bank switch code              *
  17. ;                                                                             *
  18. ?B_RTX          EQU  0    ; 0 for applications without real-time OS           *
  19. ;                         ; 1 for applications using the RTX-51 real-time OS  *
  20. ;                                                                             *
  21. ?B_VAR_BANKING  EQU  0    ; Variable Banking via L51_BANK (far memory support)*
  22. ;                         ; 0 Variable Banking does not use L51_BANK.A51      *
  23. ;                         ; 1 Variable Banking uses this L51_BANK.A51 module  *
  24. ; Notes: ?B_VAR_BANKING uses the 'far' and 'far const' C51 memory types to    *
  25. ;        extent the space for variables in RAM and/or ROM of classic 8051     *
  26. ;        device.  The same hardware as for code banking is used.  Program     *
  27. ;        code banking and variable banking share the same hardware I/O pins.  *
  28. ;        The C51 Compiler must be used with the VARBANKING directive.         *
  29. ;        Variable Banking is only supported with the LX51 linker/locater.     *
  30. ;                                                                             *
  31. ?B_RST_BANK     EQU  0xFF ; specifies the active code bank number after CPU   *
  32. ;                         ; Reset.  Used to reduce the entries in the         *
  33. ;                         ; INTERBANK CALL TABLE.  The value 0xFF disables    *
  34. ;                         ; this LX51 linker/locater optimization.            *
  35. ; Note:  Interbank Call Table optimization is only possible with LX51.        *
  36. ;                                                                             *
  37. ;-----------------------------------------------------------------------------*
  38. ;                                                                             *
  39. IF  ?B_MODE = 0;                                                              *
  40. ;-----------------------------------------------------------------------------*
  41. ; if ?BANK?MODE is 0 define the following values                              *
  42. ; For Bank-Switching via 8051 Port define Port Address / Bits                 *
  43. ;                                                                             *
  44. P1              DATA    90H      ; I/O Port Address                           *
  45. ;                                                                             *
  46. ?B_PORT         EQU     P1       ; default is P1                              *
  47. ?B_FIRSTBIT     EQU     0        ; default is Bit 2                           *
  48. ;-----------------------------------------------------------------------------*
  49. ENDIF;                                                                        *
  50. ;                                                                             *
  51. IF  ?B_MODE = 1;                                                              *
  52. ;-----------------------------------------------------------------------------*
  53. ; if ?BANK?MODE is 1 define the following values                              *
  54. ; For Bank-Switching via XDATA Port define XDATA Port Address / Bits          *
  55. ?B_XDATAPORT    EQU     0FFFFH   ; default is XDATA Port Address 0FFFFH       *
  56. ?B_FIRSTBIT     EQU     0        ; default is Bit 0                           *
  57. ;-----------------------------------------------------------------------------*
  58. ENDIF;                                                                        *
  59. ;                                                                             *
  60. IF  ?B_MODE = 4;                                                              *
  61. ;-----------------------------------------------------------------------------*
  62. ; if ?BANK?MODE is 4 define the following switch macros                       *
  63. ; For bank switching via user-provided bank switch code you must define for   *
  64. ; each memory bank a own macro which contains the bank switch code.  The      *
  65. ; following example shows how to use the I/O lines P1.4 and P1.7 for bank     *
  66. ; switching.  Since you can select just 4 banks with two address lines, just  *
  67. ; four macros are defined.  The number of macros must conform with the number *
  68. ; ?B_NBANKS number, i.e. for an application with 16 memory banks you must     *
  69. ; define 16 macros.                                                           *
  70. ;                                                                             *
  71. ; IMPORTANT NOTES:                                                            *
  72. ; 1. The bank switch logic must be initialized before using it.  Therefore    *
  73. ;    add the following lines of code at the end of the STARTUP.A51 file:      *
  74. ;                :                                                            *
  75. ;      EXTRN CODE (?B_SWITCH0)                                                *
  76. ;               CALL    ?B_SWITCH0    ; init bank mechanism to code bank 0    *
  77. ;               LJMP    ?C_START      ; line already exits at the end of file *
  78. ;                :                                                            *
  79. ;                                                                             *
  80. ; 2. If the bank switch macros and the additional control code generate more  *
  81. ;    than 256 bytes, you need to set the LONG_MACRO flag below.  The error    *
  82. ;    message "BANK SWITCH CODE BIGGER THAN 256 BYTES, SET LONG_MACRO TO 1"    *
  83. ;    is generated in case that this is required.                              *
  84. ;                                                                             *
  85. LONG_MACRO      EQU  0    ; 0 default, for normal macros and up to 8 banks    *
  86. ;                         ; 1 big macro code or many banks                    *
  87. ;                                                                             *
  88. ;                                                                             *
  89. P1              DATA    90H      ; I/O Port Addresses                         *
  90. P3              DATA    0B0H     ;                                            *
  91. ;                                                                             *
  92. SWITCH0         MACRO            ; Switch to Memory Bank #0                   *
  93.                 CLR     P1.0     ; Clear Port 1 Bit 0                         *
  94. ;                CLR     P3.3     ; Clear Port 3 Bit 3                         *
  95.                 ENDM             ;                                            *
  96. ;                                                                             *
  97. SWITCH1         MACRO            ; Switch to Memory Bank #1                   *
  98.                 SETB    P1.0     ; Set   Port 1 Bit 0                         *
  99. ;                CLR     P3.3     ; Clear Port 3 Bit 3                         *
  100.                 ENDM             ;                                            *
  101. ;                                                                             *
  102. SWITCH2         MACRO            ; Switch to Memory Bank #2                   *
  103.                 CLR     P1.5     ; Clear Port 1 Bit 5                         *
  104.                 SETB    P3.3     ; Set   Port 3 Bit 3                         *
  105.                 ENDM             ;                                            *
  106. ;                                                                             *
  107. SWITCH3         MACRO            ; Switch to Memory Bank #3                   *
  108.                 SETB    P1.5     ; Set   Port 1 Bit 5                         *
  109.                 SETB    P3.3     ; Set   Port 3 Bit 3                         *
  110.                 ENDM             ;                                            *
  111. ;                                                                             *
  112. ;-----------------------------------------------------------------------------*
  113. ENDIF;                                                                        *
  114. ;       *
  115. IF ?B_VAR_BANKING = 1;                                                        *         
  116. ;       * 
  117. XMEM EQU 0x02000000       ; LX51 xdata symbol offset: do not change!       *
  118. ;       *
  119. ;******* Configuration Section for uVision2 Memory Simulation Support *********
  120. ;                                                                             *
  121. ; The following settings allow you to map the physical xdata and code memory  *
  122. ; banks into simulation memory of the uVision2 Simulator.                     *
  123. ;                                                                             *
  124. ?B?XSTART EQU 0x8000      ; Start of xdata bank area                          *
  125. ?B?XEND   EQU 0xFFFF      ; Stop of xdata bank area                           *
  126. ?B?XMEM   EQU XMEM+0x400000  ; First HDATA memory bank in xdata space         *
  127. ;                                                                             *
  128. ; The above setting redirects the symbols in the area X:0x20000 .. X:0x2FFFF  *
  129. ; into the uVision2 simulation memory area for the EEPROM  V:0 .. V:0xFFFF    *
  130. ;                                                                             *
  131. ;-----------------------------------------------------------------------------*
  132. ;                                                                             *
  133.                 PUBLIC ?B?XSTART, ?B?XEND, ?B?XMEM;                           *
  134. ENDIF;                                                                        *
  135. ;                                                                             *
  136. ;******************************************************************************
  137. ;                                                                             *
  138. ; THEORY OF OPERATION                                                         *
  139. ; -------------------                                                         *
  140. ; The section below describes the code generated by BL51 or LX51 and the      *
  141. ; operation of the L51_BANK.A51 module.  BL51/LX51 generates for each         *
  142. ; function that is located in a code memory bank and called from the common   *
  143. ; area or a different code bank and entry into the INTRABANK CALL TABLE.  The *
  144. ; INTRABANK CALL TABLE is located in the SEGMENT ?BANK?SELECT and listed in   *
  145. ; the Linker MAP file. The entries in that TABLE have the following format:   *
  146. ;                                                                             *
  147. ;   ?FCT?1:  MOV  DPTR,#FCT     ; Load Address of target FCT                  *
  148. ;            JMP  ?B_BANKn      ; Switch to Bank and Jump to Target Code      *
  149. ;                                                                             *
  150. ; Instead of directly calling the function FCT, the Linker changes the entry  *
  151. ; to ?FCT?1.  This entry selects the bank where the function FCT is located   *
  152. ; and calls that function via the routines defined in this L51_BANK.A51 file. *
  153. ; The L51_BANK.A51 file contains two sets of functions for each bank:         *
  154. ;                                                                             *
  155. ; ?B_BANKn    is a routine which saves the entry of the ?B_SWITCHn function   *
  156. ;             for the current active bank on the STACK and switches to the    *
  157. ;             bank 'n'.  Then it jumps to the address specified by the DPTR   *
  158. ;             register.  It is allowed to modify the following registers in   *
  159. ;             the ?B_BANKn routine:  A, B, R0, DPTR, PSW                      *
  160. ;                                                                             *
  161. ; ?B_SWITCHn  is a function which selects the bank 'n'.  This function is     *
  162. ;             used at the end of a user function to return to the calling     *
  163. ;             code bank.  Only the following registers may be altered in the  *
  164. ;             ?B_SWITCHn function:  R0, DPTR                                  *
  165. ;                                                                             *
  166. ; The current active bank is stored in ?B_CURRENTBANK.  RTX-51 uses this      *
  167. ; variable to restore the code bank after a task switch.  To get correct      *
  168. ; results, ?B_CURRENTBANK must be set to the code bank before the hardware    *
  169. ; switch is done, or the code banking sequences must be interrupt protected.  *
  170. ;******************************************************************************
  171.                 NAME    ?BANK?SWITCHING
  172.                 PUBLIC  ?B_NBANKS, ?B_MODE, ?B_CURRENTBANK, ?B_MASK
  173.                 PUBLIC  ?B_FACTOR, ?B_RST_BANK
  174. IF (?B_RTX = 1)
  175.                 PUBLIC  ?B_RESTORE_BANK
  176. ENDIF
  177. ; Standard SFR Symbols required in L51_BANK.A51
  178. ACC     DATA    0E0H
  179. B       DATA    0F0H
  180. DPL     DATA    82H
  181. DPH     DATA    83H
  182. IE      DATA    0A8H
  183. EA      BIT     IE.7
  184. ; generate Mask and Bank Number Information
  185. IF      ?B_NBANKS <= 2
  186.   MASK          EQU     00000001B
  187. ELSEIF  ?B_NBANKS <= 4
  188.   MASK          EQU     00000011B
  189. ELSEIF  ?B_NBANKS <= 8
  190.   MASK          EQU     00000111B
  191. ELSEIF  ?B_NBANKS <= 16
  192.   MASK          EQU     00001111B
  193. ELSEIF  ?B_NBANKS <= 32
  194.   MASK          EQU     00011111B
  195. ELSE
  196.   MASK          EQU     00111111B
  197. ENDIF     
  198. IF  ?B_MODE = 0 ;**************************************************************
  199. ?B_FACTOR       EQU     1 SHL ?B_FIRSTBIT
  200. ?B_MASK         EQU     MASK SHL ?B_FIRSTBIT
  201. BANKN           MACRO   N
  202. BANK&N           EQU     N SHL ?B_FIRSTBIT
  203.                 ENDM
  204. CNT             SET     0
  205.                 REPT    ?B_NBANKS
  206.                 BANKN   %CNT
  207. CNT             SET     CNT+1
  208.                 ENDM
  209. ?B_CURRENTBANK  EQU     ?B_PORT
  210.   IF ?B_RTX = 1 OR ?B_NBANKS > 32
  211.   ; Convert Bank No in Accu to Address * 4
  212.   IF  ?B_FIRSTBIT = 0
  213.   CONVBANKNO    MACRO
  214.                 RL      A
  215.                 RL      A
  216.                 ENDM
  217.   ENDIF
  218.   IF  ?B_FIRSTBIT = 1
  219.   CONVBANKNO    MACRO
  220.                 RL      A
  221.                 ENDM
  222.   ENDIF
  223.   IF  ?B_FIRSTBIT = 2
  224.   CONVBANKNO    MACRO
  225.                 ENDM
  226.   ENDIF
  227.   IF  ?B_FIRSTBIT = 3
  228.   CONVBANKNO    MACRO
  229.                 RR      A
  230.                 ENDM
  231.   ENDIF
  232.   IF  ?B_FIRSTBIT = 4
  233.   CONVBANKNO    MACRO
  234.                 RR      A
  235.                 RR      A
  236.                 ENDM
  237.   ENDIF
  238.   IF  ?B_FIRSTBIT = 5
  239.   CONVBANKNO    MACRO
  240.                 SWAP    A
  241.                 RL      A
  242.                 ENDM
  243.   ENDIF
  244.   IF  ?B_FIRSTBIT = 6
  245.   CONVBANKNO    MACRO
  246.                 SWAP    A
  247.                 ENDM
  248.   ENDIF
  249.   IF  ?B_FIRSTBIT = 7
  250.   CONVBANKNO    MACRO
  251.                 SWAP    A
  252.                 RR      A
  253.                 ENDM
  254.   ENDIF
  255.   ; Macro code to select the 'N'
  256.   SWITCH        MACRO   N
  257.                 ORG     N * 4
  258.                 PUBLIC  ?B_SWITCH&N
  259.   ?B_SWITCH&N:
  260.                 MOV     R0,#(BANK&N OR NOT ?B_MASK) 
  261.   IF ?B_NBANKS > 32
  262.     IF (N < 32) 
  263.                 SJMP    SWITCHBNK_H
  264.     ELSEIF (N = 32)
  265.       SWITCHBNK_H:
  266.                 SJMP    SWITCHBNK
  267.     ELSEIF (N <> ?B_NBANKS-1)
  268.                 SJMP    SWITCHBNK
  269.     ENDIF
  270.   ELSE
  271.     IF N <> (?B_NBANKS-1)
  272.                 SJMP    SWITCHBNK
  273.     ENDIF
  274.   ENDIF
  275.                 ENDM
  276. ENDIF
  277. IF ?B_RTX = 0 AND ?B_NBANKS <= 32
  278.   ; Convert Bank No in Accu to Address * 8
  279.   IF  ?B_FIRSTBIT = 0
  280.   CONVBANKNO    MACRO
  281.                 SWAP    A
  282.                 RR      A
  283.                 ENDM
  284.   ENDIF
  285.   IF  ?B_FIRSTBIT = 1
  286.   CONVBANKNO    MACRO
  287.                 RL      A
  288.                 RL      A
  289.                 ENDM
  290.   ENDIF
  291.   IF  ?B_FIRSTBIT = 2
  292.   CONVBANKNO    MACRO
  293.                 RL      A
  294.                 ENDM
  295.   ENDIF
  296.   IF  ?B_FIRSTBIT = 3
  297.   CONVBANKNO    MACRO
  298.                 ENDM
  299.   ENDIF
  300.   IF  ?B_FIRSTBIT = 4
  301.   CONVBANKNO    MACRO
  302.                 RR      A
  303.                 ENDM
  304.   ENDIF
  305.   IF  ?B_FIRSTBIT = 5
  306.   CONVBANKNO    MACRO
  307.                 RR      A
  308.                 RR      A
  309.                 ENDM
  310.   ENDIF
  311.   IF  ?B_FIRSTBIT = 6
  312.   CONVBANKNO    MACRO
  313.                 SWAP    A
  314.                 RL      A
  315.                 ENDM
  316.   ENDIF
  317.   IF  ?B_FIRSTBIT = 7
  318.   CONVBANKNO    MACRO
  319.                 SWAP    A
  320.                 ENDM
  321.   ENDIF
  322.   ; Macro code to select the 'N'
  323.   SWITCH        MACRO   N
  324.                 ORG     N * 8
  325.                 PUBLIC  ?B_SWITCH&N
  326.   ?B_SWITCH&N:
  327.     IF  N <> 0
  328.                 ORL     ?B_CURRENTBANK,#?B_MASK
  329.     ENDIF
  330.     IF  N <> (?B_NBANKS-1)
  331.                 ANL     ?B_CURRENTBANK,#(BANK&N OR NOT ?B_MASK) 
  332.     ENDIF
  333.                 RET
  334.                 ENDM
  335. ENDIF
  336. SELECT          MACRO   N
  337. LOCAL           XLABEL, YLABEL
  338.                 PUBLIC  ?B_BANK&N
  339. ?B_BANK&N:      
  340.                 MOV     A,?B_CURRENTBANK
  341.                 ANL     A,#?B_MASK
  342.                 CONVBANKNO         ; Convert Bank Number to Address
  343.                 PUSH    ACC
  344.                 MOV     A,#HIGH ?BANK?SWITCH
  345.                 PUSH    ACC
  346.                 PUSH    DPL
  347.                 PUSH    DPH
  348.                 LJMP    ?B_SWITCH&N
  349.                 ENDM
  350. ?BANK?SELECT    SEGMENT  CODE
  351.                 RSEG    ?BANK?SELECT
  352. CNT             SET     0
  353.                 REPT    ?B_NBANKS
  354.                 SELECT  %CNT
  355. CNT             SET     CNT+1
  356.                 ENDM
  357. ?BANK?SWITCH    SEGMENT  CODE  PAGE
  358.                 RSEG    ?BANK?SWITCH
  359. CNT             SET     0
  360.                 REPT    ?B_NBANKS
  361.                 SWITCH  %CNT
  362. CNT             SET     CNT+1
  363.                 ENDM
  364.   IF ?B_RTX = 0 AND ?B_NBANKS > 32
  365.     SWITCHBNK:  XCH     A,R0
  366.     SWITCHBNK2: ORL     ?B_CURRENTBANK, #?B_MASK
  367.                 ANL     ?B_CURRENTBANK, A
  368.                 MOV     A,R0
  369.                 RET
  370.   ELSEIF ?B_RTX = 1
  371.     SWITCHBNK:  XCH     A,R0
  372.     SWITCHBNK2: JBC     EA,SWITCHBNK_EA1
  373.                 ORL     ?B_CURRENTBANK, #?B_MASK
  374.                 ANL     ?B_CURRENTBANK, A
  375.                 MOV     A,R0
  376.                 RET
  377.     SWITCHBNK_EA1:                     ; interrupts where enabled
  378.                 ORL     ?B_CURRENTBANK, #?B_MASK
  379.                 ANL     ?B_CURRENTBANK, A
  380.                 MOV     A,R0
  381.                 SETB    EA             ; enable interrupts again
  382.                 RET
  383.     ?B_RESTORE_BANK:                   ; entry for RTX-51 bank restore
  384.                 ANL     A,#?B_MASK
  385.                 XCH     A,R0
  386.                 SJMP    SWITCHBNK
  387.  
  388.   ELSEIF ?B_VAR_BANKING = 1
  389.     SWITCHBNK2: ORL     ?B_CURRENTBANK, #?B_MASK
  390.                 ANL     ?B_CURRENTBANK, A
  391.                 MOV     A,R0
  392.                 RET
  393.   ENDIF
  394. ENDIF  ; close block IF ?B_MODE = 0 *******************************************
  395. IF ?B_MODE = 1 ;***************************************************************
  396. ?B_FACTOR       EQU     1 SHL ?B_FIRSTBIT
  397. ?B_MASK         EQU     MASK SHL ?B_FIRSTBIT
  398. BANKN           MACRO   N
  399. BANK&N           EQU     N SHL ?B_FIRSTBIT
  400.                 ENDM
  401. CNT             SET     0
  402.                 REPT    ?B_NBANKS
  403.                 BANKN   %CNT
  404. CNT             SET     CNT+1
  405.                 ENDM
  406. ?C_INITSEG      SEGMENT   CODE          ; Segment for Variable Initialization
  407.                 RSEG    ?C_INITSEG
  408.                 DB      01H             ; IData
  409.                 DB      ?B_CURRENTBANK  ; Init Current Bank
  410.                 DB      0               ; Set to Zero
  411.                 DB      41H             ; XData
  412.                 DW      ?B_XDATAPORT    ; Init XDATA Port
  413.                 DB      0               ; Set to Zero
  414.                 PUBLIC  ?B_XDATAPORT
  415. ?BANK?DATA      SEGMENT DATA
  416.                 RSEG    ?BANK?DATA
  417. ?B_CURRENTBANK: DS      1
  418. IF ?B_NBANKS > 16
  419.   ; Convert Bank No in Accu to Address * 4
  420.   IF  ?B_FIRSTBIT = 0
  421.   CONVBANKNO    MACRO
  422.                 RL      A
  423.                 RL      A
  424.                 ENDM
  425.   ENDIF
  426.   IF  ?B_FIRSTBIT = 1
  427.   CONVBANKNO    MACRO
  428.                 RL      A
  429.                 ENDM
  430.   ENDIF
  431.   IF  ?B_FIRSTBIT = 2
  432.   CONVBANKNO    MACRO
  433.                 ENDM
  434.   ENDIF
  435.   IF  ?B_FIRSTBIT = 3
  436.   CONVBANKNO    MACRO
  437.                 RR      A
  438.                 ENDM
  439.   ENDIF
  440.   IF  ?B_FIRSTBIT = 4
  441.   CONVBANKNO    MACRO
  442.                 RR      A
  443.                 RR      A
  444.                 ENDM
  445.   ENDIF
  446.   IF  ?B_FIRSTBIT = 5
  447.   CONVBANKNO    MACRO
  448.                 SWAP    A
  449.                 RL      A
  450.                 ENDM
  451.   ENDIF
  452.   IF  ?B_FIRSTBIT = 6
  453.   CONVBANKNO    MACRO
  454.                 SWAP    A
  455.                 ENDM
  456.   ENDIF
  457.   IF  ?B_FIRSTBIT = 7
  458.   CONVBANKNO    MACRO
  459.                 SWAP    A
  460.                 RR      A
  461.                 ENDM
  462.   ENDIF
  463.   ; Macro code to select the 'N'
  464.   SWITCH        MACRO   N
  465.                 ORG     N * 4
  466.                 PUBLIC  ?B_SWITCH&N
  467.   ?B_SWITCH&N:
  468.                 MOV     R0,#BANK&N 
  469.   IF ?B_NBANKS > 32
  470.     IF (N < 32) 
  471.                 SJMP    SWITCHBNK_H
  472.     ELSEIF (N = 32)
  473.       SWITCHBNK_H:
  474.                 SJMP    SWITCHBNK
  475.     ELSEIF (N <> ?B_NBANKS-1)
  476.                 SJMP    SWITCHBNK
  477.     ENDIF
  478.   ELSE
  479.     IF N <> (?B_NBANKS-1)
  480.                 SJMP    SWITCHBNK
  481.     ENDIF
  482.   ENDIF
  483.                 ENDM
  484. ENDIF
  485. IF ?B_NBANKS <= 16
  486.   ; Convert Bank No in Accu to Address * 16
  487.   IF  ?B_FIRSTBIT = 0
  488.   CONVBANKNO    MACRO
  489.                 SWAP    A
  490.                 ENDM
  491.   ENDIF
  492.   IF  ?B_FIRSTBIT = 1
  493.   CONVBANKNO    MACRO
  494.                 SWAP    A
  495.                 RR      A
  496.                 ENDM
  497.   ENDIF
  498.   IF  ?B_FIRSTBIT = 2
  499.   CONVBANKNO    MACRO
  500.                 RL      A
  501.                 RL      A
  502.                 ENDM
  503.   ENDIF
  504.   IF  ?B_FIRSTBIT = 3
  505.   CONVBANKNO    MACRO
  506.                 RL      A
  507.                 ENDM
  508.   ENDIF
  509.   IF  ?B_FIRSTBIT = 4
  510.   CONVBANKNO    MACRO
  511.                 ENDM
  512.   ENDIF
  513.   IF  ?B_FIRSTBIT = 5
  514.   CONVBANKNO    MACRO
  515.                 RR      A
  516.                 ENDM
  517.   ENDIF
  518.   IF  ?B_FIRSTBIT = 6
  519.   CONVBANKNO    MACRO
  520.                 RR      A
  521.                 RR      A
  522.                 ENDM
  523.   ENDIF
  524.   IF  ?B_FIRSTBIT = 7
  525.   CONVBANKNO    MACRO
  526.                 SWAP    A
  527.                 RL      A
  528.                 ENDM
  529.   ENDIF
  530.   SWITCH        MACRO   N
  531.                 ORG     N * 16
  532.                 PUBLIC  ?B_SWITCH&N
  533.   ?B_SWITCH&N:
  534.                 MOV     R0,A
  535.                 MOV     A,#BANK&N
  536.                 MOV     DPTR,#?B_XDATAPORT
  537.                 MOV     ?B_CURRENTBANK,A
  538.                 MOVX    @DPTR,A
  539.                 MOV     A,R0
  540.                 RET
  541.                 ENDM
  542.   
  543. ENDIF
  544. SELECT          MACRO   N
  545. LOCAL           XLABEL, YLABEL
  546.                 PUBLIC  ?B_BANK&N
  547. ?B_BANK&N:      
  548.                 MOV     A,?B_CURRENTBANK
  549.                 ANL     A,#?B_MASK
  550.                 CONVBANKNO         ; Convert Bank Number to Address
  551.                 PUSH    ACC
  552.                 MOV     A,#HIGH ?BANK?SWITCH
  553.                 PUSH    ACC
  554.                 PUSH    DPL
  555.                 PUSH    DPH
  556.                 LJMP    ?B_SWITCH&N
  557.                 ENDM
  558. ?BANK?SELECT    SEGMENT  CODE
  559.                 RSEG    ?BANK?SELECT
  560. CNT             SET     0
  561.                 REPT    ?B_NBANKS
  562.                 SELECT  %CNT
  563. CNT             SET     CNT+1
  564.                 ENDM
  565. ?BANK?SWITCH    SEGMENT  CODE  PAGE
  566.                 RSEG    ?BANK?SWITCH
  567. CNT             SET     0
  568.                 REPT    ?B_NBANKS
  569.                 SWITCH  %CNT
  570. CNT             SET     CNT+1
  571.                 ENDM
  572.   IF ?B_NBANKS > 16
  573.     SWITCHBNK:  XCH     A,R0
  574.                 MOV     DPTR,#?B_XDATAPORT
  575.                 MOV     ?B_CURRENTBANK,A
  576.                 MOVX    @DPTR,A
  577.                 MOV     A,R0
  578.                 RET
  579.   ENDIF
  580.   IF (?B_RTX = 1 OR ?B_VAR_BANKING = 1)
  581.     ?B_RESTORE_BANK:                   ; entry for RTX-51/XBANKING bank restore
  582.                 MOV     DPTR,#?B_XDATAPORT
  583.                 MOV     ?B_CURRENTBANK,A
  584.                 MOVX    @DPTR,A
  585.                 RET
  586.   ENDIF
  587. ENDIF  ; close block IF ?B_MODE = 1 *******************************************
  588. IF  ?B_MODE = 4 ;**************************************************************
  589. ?B_FACTOR       EQU     0               ; Dummy Declarations
  590. ?B_FIRSTBIT     EQU     0
  591. ?B_MASK         EQU     MASK
  592. ?BANK?SELECT    SEGMENT CODE
  593. ?BANK?DATA      SEGMENT DATA
  594.                 RSEG    ?BANK?DATA
  595. ?B_CURRENTBANK: DS      1
  596. BANK            MACRO   N
  597.                 PUBLIC  ?B_BANK&N
  598. ?B_BANK&N:
  599.                 PUSH    ?B_CURRENTBANK
  600.                 MOV     A,#HIGH ?BANK?SWITCH
  601.                 PUSH    ACC
  602.                 PUSH    DPL
  603.                 PUSH    DPH
  604.                 ENDM
  605. SWITCH          MACRO   N
  606.                 PUBLIC  ?B_SWITCH&N
  607.   IF (LONG_MACRO = 1)
  608.     ?B_SWITCHJ&N:
  609.   ELSE
  610.     ?B_SWITCH&N:
  611.   ENDIF
  612.                 MOV     ?B_CURRENTBANK,#LOW ?B_SWITCH&N
  613.                 SWITCH&N
  614.                 RET
  615.                 ENDM
  616.   IF (LONG_MACRO = 1)
  617.     SWITCHJ     MACRO   N
  618.     ?B_SWITCH&N:
  619.                 JMP     ?B_SWITCHJ&N
  620.                 ENDM
  621.   ENDIF
  622. ?BANK?SWITCH    SEGMENT CODE PAGE
  623.                 RSEG    ?BANK?SWITCH
  624. B_SWITCH_START  EQU     $
  625.   IF (LONG_MACRO = 1)
  626.     ; Generate ?B_SWITCHn jmp table entries
  627.     CNT         SET     0
  628.                 REPT    ?B_NBANKS
  629.                 SWITCHJ %CNT
  630.     CNT         SET     CNT+1
  631.                 ENDM
  632.   ENDIF
  633. ; Generate ?B_SWITCHn functions
  634. CNT             SET     0
  635.                 REPT    ?B_NBANKS
  636.                 BANK    %CNT
  637.                 SWITCH  %CNT
  638. CNT             SET     CNT+1
  639.                 ENDM
  640. B_SWITCH_SIZE   EQU     $-B_SWITCH_START
  641.   IF (LONG_MACRO = 0) AND (B_SWITCH_SIZE > 256)
  642.     __ERROR__ "BANK SWITCH CODE BIGGER THAN 256 BYTES, SET LONG_MACRO TO 1"
  643.   ENDIF
  644. ENDIF  ; close block IF ?B_MODE = 4 *******************************************
  645.                 RSEG    ?BANK?SELECT
  646. ;************************  SWITCHBANK FUNCTION  *******************************
  647. ;                                                                             *
  648. ; SWITCHBANK allows use of bank-switching for C programs                      *
  649. ;                                                                             *
  650. ; prototype:   extern switchbank (unsigned char bank_number);                 *
  651. ;                                                                             *
  652. ;******************************************************************************
  653.                 PUBLIC  _SWITCHBANK, ?B_SWITCHBANK_A
  654. _SWITCHBANK:    MOV     A,R7
  655. IF  ?B_MODE = 0 ;**************************************************************
  656. ?B_SWITCHBANK_A:
  657. IF ?B_NBANKS > 32 OR ?B_RTX = 1
  658.                 RL      A
  659.                 RL      A
  660. ENDIF
  661. IF ?B_NBANKS <= 16 AND ?B_RTX = 0
  662.                 SWAP    A
  663.                 RR      A
  664. ENDIF
  665.                 MOV     DPTR,#?BANK?SWITCH
  666.                 JMP     @A+DPTR
  667. ENDIF  ; close block IF ?B_MODE = 0 *******************************************
  668. IF ?B_MODE = 1 ;***************************************************************
  669. ?B_SWITCHBANK_A:
  670. IF ?B_NBANKS > 16
  671.                 RL      A
  672.                 RL      A
  673. ENDIF
  674. IF ?B_NBANKS <= 16
  675.                 SWAP    A
  676. ENDIF
  677.                 MOV     DPTR,#?BANK?SWITCH
  678.                 JMP     @A+DPTR
  679. ENDIF  ; close block IF ?B_MODE = 1 *******************************************
  680. IF  ?B_MODE = 4 ;**************************************************************
  681. IF (?B_VAR_BANKING = 1)
  682.                 SJMP    ?B_SWITCHBANK_A
  683. SELECT_BANK_R3:
  684.                 MOV     A,R3
  685.                 DEC     A
  686.                 ANL     A,#3FH
  687. ENDIF
  688. ?B_SWITCHBANK_A:
  689.                 MOV DPTR,#switch_tab
  690.                 MOVC    A,@A+DPTR
  691. ?B_RESTORE_BANK:                       ; entry for RTX-51/XBANKING bank restore
  692.                 MOV     DPTR,#?BANK?SWITCH
  693.                 JMP     @A+DPTR
  694. S_ENTRY         MACRO   N
  695.                 DB      LOW ?B_SWITCH&N
  696.                 ENDM
  697. switch_tab:     
  698. CNT             SET     0
  699.                 REPT    ?B_NBANKS
  700.                 S_ENTRY %CNT
  701. CNT             SET     CNT+1
  702.                 ENDM
  703. ENDIF  ; close block IF ?B_MODE = 4 *******************************************
  704. IF ?B_VAR_BANKING  ;***********************************************************
  705. ;******************************************************************************
  706. ;                                                                             *
  707. ; THEORY OF OPERATION                                                         *
  708. ; -------------------                                                         *
  709. ; This section describes how the extended LX51 linker/locater manages the     *
  710. ; extended address spaces that are addressed with the new C51 memory types    *
  711. ; 'far' and 'far const'.  The C51 Compiler uses 3 byte pointer generic        *
  712. ; pointer to access these memory areas.  'far' variables are placed in the    *
  713. ; memory class HDATA and 'far const' variables get the memory class 'HCONST'. *
  714. ; The LX51 linker/locater allows you to locate these memory classes in the    *
  715. ; logical 16 MBYTE CODE or 16 MBYTE XDATA spaces.                             *
  716. ;                                                                             *
  717. ; The memory access itself is performed via eight different subroutines that  *
  718. ; can be configured in this assembler module.  These routines are:            *
  719. ;    ?C?CLDXPTR, ?C?CSTXPTR  ; load/store BYTE (char)  in extended memory     *
  720. ;    ?C?ILDXPTR, ?C?ISTXPTR  ; load/store WORD (int)   in extended memory     *
  721. ;    ?C?PLDXPTR, ?C?PSTXPTR  ; load/store 3-BYTE PTR   in extended memory     *
  722. ;    ?C?LLDXPTR, ?C?LSTXPTR  ; load/store DWORD (long) in extended memory     *
  723. ;                                                                             *
  724. ; Each function gets as a parameter the memory address with 3 BYTE POINTER    *
  725. ; representation in the CPU registers R1/R2/R3.  The register R3 holds the    *
  726. ; memory type.  The C51 compiler uses the following memory types:             *
  727. ;                                                                             *
  728. ; R3 Value | Memory Type | Memory Class | Address Range                       *
  729. ; -----------------------+--------------+--------------------------           *
  730. ;    00    | data/idata  | DATA/IDATA   | I:0x00     .. I:0xFF                *
  731. ;    01    | xdata       | XDATA        | X:0x0000   .. X:0xFFFF              *
  732. ;  02..7F  | far         | HDATA        | X:0x010000 .. X:0x7E0000            *
  733. ;  80..FD  | far const   | HCONST       | C:0x800000 .. C:0xFD0000 (see note) *
  734. ;    FE    | pdata       | XDATA        | one 256-byte page in XDATA memory   *
  735. ;    FF    | code        | CODE         | C:0x0000   .. C:0xFFFF              *
  736. ;                                                                             *
  737. ; Note: the far const memory area is mapped into the banked memory areas.     *
  738. ;                                                                             *
  739. ; The R3 values 00, 01, FE and FF are already handled within the C51 run-time *
  740. ; library.  Only the values 02..FE are passed to the XPTR access functions    *
  741. ; described below.  The AX51 macro assembler provides the MBYTE operator      *
  742. ; that calculates the R3 value that needs to be passed to the XPTR access     *
  743. ; function.   AX51 Assembler example for using XPTR access functions:         *
  744. ;     MOV  R1,#LOW   (variable)   ; gives LSB address byte of variable        *
  745. ;     MOV  R1,#HIGH  (variable)   ; gives MSB address byte of variable        *
  746. ;     MOV  R1,#MBYTE (variable)   ; gives memory type byte of variable        *
  747. ;     CALL ?C?CLDXPTR             ; load BYTE variable into A                 *
  748. ;******************************************************************************
  749. PUBLIC ?C?CLDXPTR, ?C?CSTXPTR, ?C?ILDXPTR, ?C?ISTXPTR
  750. PUBLIC ?C?PLDXPTR, ?C?PSTXPTR, ?C?LLDXPTR, ?C?LSTXPTR
  751. ?C?LIB_CODE     SEGMENT CODE
  752.                 RSEG    ?C?LIB_CODE
  753. IF  ?B_MODE = 0 ;**************************************************************
  754. ; Select Bank depending on value in R3
  755. SEL_BNK         MACRO   SaveA
  756. LOCAL lab
  757. IF NOT NUL SaveA
  758.                 MOV     R0,A
  759. ENDIF
  760.                 CALL    SELECT_BANK_R3
  761. IF NOT NUL SaveA
  762.                 MOV     A,R0
  763. ENDIF
  764.                 MOV     DPL,R1
  765.                 MOV     DPH,R2
  766.                 CJNE    R3,#80H,lab
  767. lab:            
  768.                 ENDM
  769. ; Pop previous Bank and select it again
  770. POP_BNK         MACRO   SaveA
  771. IF NOT NUL SaveA
  772.                 MOV     R0,A             ; SWITCHBNK2 ends with MOV A,R0
  773. ENDIF
  774.                 POP     ACC
  775.                 ANL     A,#?B_MASK
  776.                 JMP     SWITCHBNK2
  777.                 ENDM
  778. SELECT_BANK_R3:
  779.                 MOV     A,R3
  780.                 DEC     A
  781.                 ANL     A,#3FH
  782. IF ?B_NBANKS > 32 OR ?B_RTX = 1
  783.                 RL      A
  784.                 RL      A
  785. ENDIF
  786. IF ?B_NBANKS <= 16 AND ?B_RTX = 0
  787.                 RL      A
  788.                 RL      A
  789.                 RL      A
  790. ENDIF
  791.                 MOV     DPTR,#?BANK?SWITCH
  792.                 JMP     @A+DPTR
  793. ENDIF  ; close block IF ?B_MODE = 0 *******************************************
  794. IF ?B_MODE = 1 ;***************************************************************
  795. ; Select Bank depending on value in R3
  796. SEL_BNK         MACRO   SaveA
  797. LOCAL lab
  798. IF NOT NUL SaveA
  799.                 MOV     R0,A
  800. ENDIF
  801.                 CALL    SELECT_BANK_R3
  802. IF NOT NUL SaveA
  803.                 MOV     A,R0
  804. ENDIF
  805.                 MOV     DPL,R1
  806.                 MOV     DPH,R2
  807.                 CJNE    R3,#80H,lab
  808. lab:            
  809.                 ENDM
  810. ; Pop previous Bank and select it again
  811. POP_BNK         MACRO   SaveA
  812. IF NOT NUL SaveA
  813.                 MOV     R0,A             ; SWITCHBNK2 ends with MOV A,R0
  814. ENDIF
  815.                 POP     ACC
  816.                 MOV     DPTR,#?B_XDATAPORT
  817.                 MOV     ?B_CURRENTBANK,A
  818.                 MOVX    @DPTR,A
  819. IF NOT NUL SaveA
  820.                 MOV     A,R0             ; SWITCHBNK2 ends with MOV A,R0
  821. ENDIF
  822.                 RET
  823.                 ENDM
  824. SELECT_BANK_R3:
  825.                 MOV     A,R3
  826.                 DEC     A
  827.                 ANL     A,#3FH
  828. IF ?B_NBANKS > 16
  829.                 RL      A
  830.                 RL      A
  831. ENDIF
  832. IF ?B_NBANKS <= 16
  833.                 RL      A
  834.                 RL      A
  835.                 RL      A
  836.                 RL      A
  837. ENDIF
  838.                 MOV     DPTR,#?BANK?SWITCH
  839.                 JMP     @A+DPTR
  840. ENDIF  ; close block IF ?B_MODE = 1 *******************************************
  841. IF  ?B_MODE = 4 ;**************************************************************
  842. ; Select Bank depending on value in R3
  843. SEL_BNK         MACRO   SaveA
  844. LOCAL lab
  845. IF NOT NUL SaveA
  846.                 MOV     R0,A
  847. ENDIF
  848.                 CALL    SELECT_BANK_R3
  849. IF NOT NUL SaveA
  850.                 MOV     A,R0
  851. ENDIF
  852.                 MOV     DPL,R1
  853.                 MOV     DPH,R2
  854.                 CJNE    R3,#80H,lab
  855. lab:            
  856.                 ENDM
  857. ; Pop previous Bank and select it again
  858. POP_BNK         MACRO   SaveA
  859. IF NOT NUL SaveA
  860.                 MOV     R0,A             ; SWITCHBNK2 ends with MOV A,R0
  861.                 POP     ACC
  862.                 CALL    ?B_RESTORE_BANK
  863.                 MOV     A,R0
  864.                 RET
  865. ELSE
  866.                 POP     ACC
  867.                 MOV     DPTR,#?BANK?SWITCH
  868.                 JMP     @A+DPTR
  869. ENDIF
  870.                 ENDM
  871. ENDIF  ; close block IF ?B_MODE = 4 *******************************************
  872. ; CLDXPTR: Load   BYTE in A             via Address given in R1/R2/R3
  873. ?C?CLDXPTR:     PUSH    ?B_CURRENTBANK
  874.                 SEL_BNK
  875.                 JNC     CLDCODE
  876.                 MOVX    A,@DPTR
  877.                 SJMP    RETURN_A
  878. CLDCODE:        CLR     A
  879.                 MOVC    A,@A+DPTR
  880. RETURN_A:       POP_BNK 1
  881. ; CSTXPTR: Store  BYTE in A             via Address given in R1/R2/R3
  882. ?C?CSTXPTR:     PUSH    ?B_CURRENTBANK
  883.                 SEL_BNK 1          
  884.                 JNC     CSTCODE
  885.                 MOVX    @DPTR,A
  886. CSTCODE:        SJMP RETURN_NO_A
  887. ; ILDXPTR: Load   WORD in A(LSB)/B(HSB) via Address given in R1/R2/R3 
  888. ?C?ILDXPTR:     PUSH    ?B_CURRENTBANK
  889.                 SEL_BNK
  890.                 JNC     ILDCODE
  891.                 MOVX    A,@DPTR
  892.                 MOV     B,A
  893.                 INC     DPTR
  894.                 MOVX    A,@DPTR
  895.                 SJMP    RETURN_A
  896. ILDCODE:        CLR     A
  897.                 MOVC    A,@A+DPTR
  898.                 MOV     B,A
  899.                 MOV     A,#1
  900.                 MOVC    A,@A+DPTR
  901.                 SJMP    RETURN_A
  902. ; ISTXPTR: Store  WORD in A(HSB)/B(LSB) via Address given in R1/R2/R3 
  903. ?C?ISTXPTR:     PUSH    ?B_CURRENTBANK
  904.                 SEL_BNK 1
  905.                 JNC     ISTCODE
  906.                 MOVX    @DPTR,A
  907.                 INC     DPTR
  908.                 MOV     A,B
  909.                 MOVX    @DPTR,A
  910. ISTCODE:        SJMP    RETURN_NO_A
  911. ; PLDXPTR: Load    PTR in R1/R2/R3      via Address given in R1/R2/R3 
  912. ?C?PLDXPTR:     PUSH    ?B_CURRENTBANK
  913.                 SEL_BNK
  914.                 JNC     PLDCODE
  915.                 MOVX    A,@DPTR
  916.                 MOV     R3,A
  917.                 INC     DPTR
  918.                 MOVX    A,@DPTR
  919.                 MOV     R2,A
  920.                 INC     DPTR
  921.                 MOVX    A,@DPTR
  922.                 MOV     R1,A
  923.                 SJMP    RETURN_NO_A
  924. PLDCODE:        CLR     A
  925.                 MOVC    A,@A+DPTR
  926.                 MOV     R3,A
  927.                 MOV     A,#1
  928.                 MOVC    A,@A+DPTR
  929.                 MOV     R2,A
  930.                 MOV     A,#2
  931.                 MOVC    A,@A+DPTR
  932.                 MOV     R1,A
  933. RETURN_NO_A:    POP_BNK
  934. ; PSTXPTR: Store   PTR in R0/A/B        via Address given in R1/R2/R3 
  935. ?C?PSTXPTR:     PUSH    ?B_CURRENTBANK
  936.                 POP     ACC
  937.                 SEL_BNK
  938.                 POP     ACC
  939.                 JNC     PSTCODE
  940.                 XCH     A,B
  941.                 MOVX    @DPTR,A
  942.                 INC     DPTR
  943.                 XCH     A,B
  944.                 MOVX    @DPTR,A
  945.                 INC     DPTR
  946.                 MOV     A,R0
  947.                 MOVX    @DPTR,A
  948. PSTCODE:        SJMP    RETURN_NO_A 
  949. ; LLDXPTR: Load  DWORD in R4/R5/R6/R7   via Address given in R1/R2/R3 
  950. ?C?LLDXPTR:     PUSH    ?B_CURRENTBANK
  951.                 SEL_BNK
  952.                 JNC     LLDCODE
  953.                 MOVX    A,@DPTR
  954.                 MOV     R4,A
  955.                 INC     DPTR
  956.                 MOVX    A,@DPTR
  957.                 MOV     R5,A
  958.                 INC     DPTR
  959.                 MOVX    A,@DPTR
  960.                 MOV     R6,A
  961.                 INC     DPTR
  962.                 MOVX    A,@DPTR
  963.                 MOV     R7,A
  964.                 SJMP    RETURN_NO_A
  965. LLDCODE:        CLR     A
  966.                 MOVC    A,@A+DPTR
  967.                 MOV     R4,A
  968.                 MOV     A,#1
  969.                 MOVC    A,@A+DPTR
  970.                 MOV     R5,A
  971.                 MOV     A,#2
  972.                 MOVC    A,@A+DPTR
  973.                 MOV     R6,A
  974.                 MOV     A,#3
  975.                 MOVC    A,@A+DPTR
  976.                 MOV     R7,A
  977.                 SJMP    RETURN_NO_A
  978. ; LSTXPTR: Store DWORD in R4/R5/R6/R7   via Address given in R1/R2/R3 
  979. ?C?LSTXPTR:     PUSH    ?B_CURRENTBANK
  980.                 SEL_BNK
  981.                 JNC     LSTCODE
  982.                 MOV     A,R4
  983.                 MOVX    @DPTR,A
  984.                 INC     DPTR
  985.                 MOV     A,R5
  986.                 MOVX    @DPTR,A
  987.                 INC     DPTR
  988.                 MOV     A,R6
  989.                 MOVX    @DPTR,A
  990.                 INC     DPTR
  991.                 MOV     A,R7
  992.                 MOVX    @DPTR,A
  993. LSTCODE:        SJMP    RETURN_NO_A
  994.  
  995. ENDIF  ; close block IF ?B_VAR_BANKING ****************************************
  996.                 END