⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 datapage.c

📁 CAN 网关原代码,汽车电子中的总线网关
💻 C
📖 第 1 页 / 共 4 页
字号:
        STAB    0,X               ;// set page register
        LDAB    0,Y               ;// actual load, overwrites page of address
        LDY     1,Y               ;// actual load, overwrites offset of address
        STAA    0,X               ;// restore page register
        PULA                      ;// restore A register
        PULX                      ;// restore X register
        RTS
L_NOPAGE:
        LDAB    0,Y               ;// actual load, overwrites page of address
        LDY     1,Y               ;// actual load, overwrites offset of address
        PULX                      ;// restore X register
        RTS
  }
#else /* USE_SEVERAL_PAGES */
  __asm {
        PSHA                      ;// save A register
        LDAA    PAGE_ADDR         ;// save page register
        STAB    PAGE_ADDR         ;// set page register
        LDAB    0,Y               ;// actual load, overwrites page of address
        LDY     1,Y               ;// actual load, overwrites offset of address
        STAA    PAGE_ADDR         ;// restore page register
        PULA                      ;// restore A register
        RTS
  }
#endif /* USE_SEVERAL_PAGES */

}

/*--------------------------- _LOAD_FAR_32 --------------------------------
  This runtime routine is used to access paged memory via a runtime function.
  It may also be used if the compiler  option -Cp is not used with the runtime argument.

  Arguments :
  - offset part of an address in the Y register
  - page part of an address in the B register

  Result :
  - low 16 bit of value to be read in the D registers
  - high 16 bit of value to be read in the Y registers
  - all other registers remains unchanged
  - all page register still contain the same value
  --------------------------- _LOAD_FAR_32 ----------------------------------*/

#ifdef __cplusplus
extern "C"
#endif
#pragma NO_ENTRY
#pragma NO_EXIT
#pragma NO_FRAME

void NEAR _LOAD_FAR_32(void) {
#if USE_SEVERAL_PAGES
  __asm {
        PSHX                      ;// save X register
        __PIC_JSR(_GET_PAGE_REG)
        BEQ     L_NOPAGE
        LDAA    0,X               ;// save page register
        PSHA                      ;// put it onto the stack
        STAB    0,X               ;// set page register
        LDD     2,Y               ;// actual load, low word
        LDY     0,Y               ;// actual load, high word
        MOVB    1,SP+,0,X         ;// restore page register
        PULX                      ;// restore X register
        RTS
L_NOPAGE:
        LDD     2,Y               ;// actual load, low word
        LDY     0,Y               ;// actual load, high word
        PULX                      ;// restore X register
        RTS
  }
#else /* USE_SEVERAL_PAGES */
  __asm {
        LDAA    PAGE_ADDR         ;// save page register
        PSHA                      ;// put it onto the stack
        STAB    PAGE_ADDR         ;// set page register
        LDD     2,Y               ;// actual load, low word
        LDY     0,Y               ;// actual load, high word
        MOVB    1,SP+,PAGE_ADDR   ;// restore page register
        RTS
  }
#endif /* USE_SEVERAL_PAGES */
}

/*--------------------------- _STORE_FAR_8 --------------------------------
  This runtime routine is used to access paged memory via a runtime function.
  It may also be used if the compiler  option -Cp is not used with the runtime argument.

  Arguments :
  - offset part of an address in the Y register
  - page part of an address in the B register
  - value to be stored in the B register

  Result :
  - value stored at the address
  - all registers remains unchanged
  - all page register still contain the same value
  --------------------------- _STORE_FAR_8 ----------------------------------*/

#ifdef __cplusplus
extern "C"
#endif
#pragma NO_ENTRY
#pragma NO_EXIT
#pragma NO_FRAME

void NEAR _STORE_FAR_8(void) {
#if USE_SEVERAL_PAGES
  __asm {
        PSHX                      ;// save X register
        __PIC_JSR(_GET_PAGE_REG)
        BEQ     L_NOPAGE
        PSHB                      ;// save B register
        LDAB    0,X               ;// save page register
        MOVB    0,SP, 0,X         ;// set page register
        STAA    0,Y               ;// store the value passed in A
        STAB    0,X               ;// restore page register
        PULB                      ;// restore B register
        PULX                      ;// restore X register
        RTS
L_NOPAGE:
        STAA    0,Y               ;// store the value passed in A
        PULX                      ;// restore X register
        RTS
  }
#else /* USE_SEVERAL_PAGES */
  __asm {
        PSHB                      ;// save A register
        LDAB    PAGE_ADDR         ;// save page register
        MOVB    0,SP,PAGE_ADDR    ;// set page register
        STAA    0,Y               ;// store the value passed in A
        STAB    PAGE_ADDR         ;// restore page register
        PULB                      ;// restore B register
        RTS
  }
#endif /* USE_SEVERAL_PAGES */
}

/*--------------------------- _STORE_FAR_16 --------------------------------
  This runtime routine is used to access paged memory via a runtime function.
  It may also be used if the compiler  option -Cp is not used with the runtime argument.

  Arguments :
  - offset part of an address in the Y register
  - page part of an address in the B register
  - value to be stored in the X register

  Result :
  - value stored at the address
  - all registers remains unchanged
  - all page register still contain the same value
  --------------------------- _STORE_FAR_16 ----------------------------------*/

#ifdef __cplusplus
extern "C"
#endif
#pragma NO_ENTRY
#pragma NO_EXIT
#pragma NO_FRAME

void NEAR _STORE_FAR_16(void) {
#if USE_SEVERAL_PAGES
  __asm {
        PSHX                      ;// save X register
        __PIC_JSR(_GET_PAGE_REG)
        BEQ     L_NOPAGE

        PSHA
        LDAA    0,X               ;// save page register
        STAB    0,X               ;// set page register
        MOVW    1,SP,0,Y          ;// store the value passed in X
        STAA    0,X               ;// restore page register
        PULA                      ;// restore A register
        PULX                      ;// restore X register
        RTS

L_NOPAGE:
        STX 0,Y                   ;// store the value passed in X
        PULX                      ;// restore X register
        RTS
  }
#else /* USE_SEVERAL_PAGES */
  __asm {
        PSHA                      ;// save A register
        LDAA    PAGE_ADDR         ;// save page register
        STAB    PAGE_ADDR         ;// set page register
        STX     0,Y               ;// store the value passed in X
        STAA    PAGE_ADDR         ;// restore page register
        PULA                      ;// restore A register
        RTS
  }
#endif /* USE_SEVERAL_PAGES */
}
/*--------------------------- _STORE_FAR_24 --------------------------------
  This runtime routine is used to access paged memory via a runtime function.
  It may also be used if the compiler  option -Cp is not used with the runtime argument.

  Arguments :
  - offset part of an address in the Y register
  - page part of an address in the B register
  - value to be stored in the X:A registers (X : low 16 bit, A : high 8 bit)

  Result :
  - value stored at the address
  - all registers remains unchanged
  - all page register still contain the same value
  --------------------------- _STORE_FAR_24 ----------------------------------*/

#ifdef __cplusplus
extern "C"
#endif
#pragma NO_ENTRY
#pragma NO_EXIT
#pragma NO_FRAME

void NEAR _STORE_FAR_24(void) {
#if USE_SEVERAL_PAGES
  __asm {
        PSHX                      ;// save X register
        __PIC_JSR(_GET_PAGE_REG)
        BEQ     L_NOPAGE

        PSHA
        LDAA    0,X               ;// save page register
        STAB    0,X               ;// set page register
        MOVW    1,SP, 1,Y         ;// store the value passed in X
        MOVB    0,SP, 0,Y         ;// store the value passed in A
        STAA    0,X               ;// restore page register
        PULA                      ;// restore A register
        PULX                      ;// restore X register
        RTS

L_NOPAGE:
        STX     1,Y               ;// store the value passed in X
        STAA    0,Y               ;// store the value passed in X
        PULX                      ;// restore X register
        RTS
  }
#else /* USE_SEVERAL_PAGES */
  __asm {
        PSHA                      ;// save A register
        LDAA    PAGE_ADDR         ;// save page register
        STAB    PAGE_ADDR         ;// set page register
        MOVB    0,SP, 0,Y         ;// store the value passed in A
        STX     1,Y               ;// store the value passed in X
        STAA    PAGE_ADDR         ;// restore page register
        PULA                      ;// restore A register
        RTS
  }
#endif /* USE_SEVERAL_PAGES */
}
/*--------------------------- _STORE_FAR_32 --------------------------------
  This runtime routine is used to access paged memory via a runtime function.
  It may also be used if the compiler  option -Cp is not used with the runtime argument.

  Arguments :
  - offset part of an address in the Y register
  - page part of an address is on the stack at 3,SP (just below the return address)
  - value to be stored in the X:D registers (D : low 16 bit, X : high 16 bit)

  Result :
  - value stored at the address
  - all registers remains unchanged
  - the page part is removed from the stack
  - all page register still contain the same value
  --------------------------- _STORE_FAR_32 ----------------------------------*/

#ifdef __cplusplus
extern "C"
#endif
#pragma NO_ENTRY
#pragma NO_EXIT
#pragma NO_FRAME

void NEAR _STORE_FAR_32(void) {
#if USE_SEVERAL_PAGES
  __asm {
        PSHX                      ;// save X register
        __PIC_JSR(_GET_PAGE_REG)
        BEQ     L_NOPAGE

        PSHD
        LDAA    0,X               ;// save page register
        MOVB    6,SP, 0,X         ;// set page register
        MOVW    2,SP, 0,Y         ;// store the value passed in X (high word)
        MOVW    0,SP, 2,Y         ;// store the value passed in D (low word)
        STAA    0,X               ;// restore page register
        PULD                      ;// restore A register
        BRA     done

L_NOPAGE:
        MOVW    0,SP, 0,Y         ;// store the value passed in X (high word)
        STD           2,Y         ;// store the value passed in D (low word)
done:
        PULX                      ;// restore X register
        MOVW    0,SP, 1,+SP       ;// move return address
        RTS
  }
#else /* USE_SEVERAL_PAGES */
  __asm {
        PSHD                      ;// save D register
        LDAA    PAGE_ADDR         ;// save page register
        LDAB    4,SP              ;// load page part of address
        STAB    PAGE_ADDR         ;// set page register
        STX     0,Y               ;// store the value passed in X
        MOVW    0,SP, 2,Y         ;// store the value passed in D (low word)
        STAA    PAGE_ADDR         ;// restore page register
        PULD                      ;// restore D register
        MOVW    0,SP, 1,+SP       ;// move return address
        RTS
  }
#endif /* USE_SEVERAL_PAGES */
}

/*--------------------------- _FAR_COPY --------------------------------
  This runtime routine is used to access paged memory via a runtime function.
  It may also be used if the compiler  option -Cp is not used with the runtime argument.

  Arguments :
  - offset part of the source int the X register
  - page part of the source in the A register
  - offset part of the dest int the Y register
  - page part of the dest in the B register
  - number of bytes to be copied at 2,SP. The number of bytes is always > 0

  Result :
  - memory area copied
  - no registers are saved, i.e. all registers may be destroyed
  - all page register still contain the same value
  - number of bytes is released from the stack


  stack-structure at the loop-label:
     0,SP : destination offset
     2,SP : source page
     3,SP : destination page
     4,SP : source offset
     6,SP : return address
     8,SP : counter, > 0
  --------------------------- _FAR_COPY ----------------------------------*/

#ifdef __cplusplus
extern "C"
#endif
#pragma NO_ENTRY
#pragma NO_EXIT
#pragma NO_FRAME

void NEAR _FAR_COPY(void) {
#if USE_SEVERAL_PAGES
  __asm {
        DEX                       ;// source addr-=1, because loop counter ends at 1
        PSHX                      ;// save source offset
        PSHD                      ;// save both pages
        DEY                       ;// destination addr-=1, because loop counter ends at 1
        PSHY                      ;// save destination offset
        LDX     8,SP              ;// load counter, assuming counter > 0

loop:
        LDD     4,SP              ;// load source offset
        LEAY    D,X               ;// calculate actual source address
        LDAB    2,SP              ;// load source page
        __PIC_JSR(_LOAD_FAR_8)    ;// load 1 source byte
        PSHB                      ;// save value
        LDD     0+1,SP            ;// load destination offset
        LEAY    D,X               ;// calculate actual destination address
        PULA                      ;// restore value
        LDAB    3,SP              ;// load destination page
        __PIC_JSR(_STORE_FAR_8)   ;// store one byte
        DEX
        BNE     loop
        LDX     6,SP              ;// load return address
        LEAS    10,SP             ;// release stack
        JMP     0,X               ;// return
  }
#else
  __asm {
        PSHD                      ;// store page registers
        TFR     X,D
        ADDD    4,SP              ;// calculate source end address
        STD     4,SP
        PULB                      ;// reload source page
        LDAA    PAGE_ADDR         ;// save page register
        PSHA
loop:
        STAB    PAGE_ADDR         ;// set source page
        LDAA    1,X+              ;// load value
        MOVB    1,SP, PAGE_ADDR   ;// set destination page
        STAA    1,Y+
        CPX     4,SP
        BNE     loop

        LDAA    2,SP+             ;// restore old page value and release stack
        STAA    PAGE_ADDR         ;// store it into page register
        LDX     4,SP+             ;// release stack and load return address
        JMP     0,X               ;// return
  }
#endif
}

#else  /* __HCS12X__  */

/*
  The HCS12X knows two different kind of addresses:
    - Logical addresses. E.g.
       MOVB #page(var),RPAGE
       INC var

    - Global addresses E.g.
       MOVB #page(var),GPAGE
       GLOAA var
       INCA
       GSTAA var

  Global addresses are used with G-Load's and G-Store's, logical addresses are used for all the other instructions
  and occasions. As HC12's or HCS12's do not have the G-Load and G-Store instructions,
  global addresses are not used with these processor families.
  They are only used with HCS12X chips (and maybe future ones deriving from a HCS12X).

  Logical and Global addresses can point to the same object, however the global and logical address of an object
  are different for most objects (actually for all except the registers from 0 to 0x7FF).
  Therefore the compiler needs to transform in between them.

  HCS12X Pointer types:

    The following are logical addresses:
    - all 16 bit pointers
       - "char* __near": always.
       - "char *" in the small and banked memory model
    - 24 bit dpage, epage, ppage or rpage pointers (*1) (note: the first HCS12X compilers may not support these pointer types)
       - "char *__dpage": Note this type only exists for
                          orthogonality with the HC12 A4 chip which has a DPAGE reg.
                          It does not apply to the HCS12X.
       - "char *__epage": 24 bit pointer using the EPAGE register
       - "char *__ppage": 24 bit pointer using the PPAGE register.
                          As the PPAGE is also used for BANKED code,
                          using this pointer type is only legal from non banked code.
       - "char *__rpage": 24 bit pointer using the RPAGE register


    The following are global addresses:
       "char*": in the large memory model (only HCS12X)
       "char* __far": always for HCS12X.

   (*1): For the HC12 and HCS12 "char* __far" and "char*" in the large memory model are also logical.

   Some notes for the HC12/HCS12 programmers.

   The address of a far object for a HC12 and for a HCS12X is different, even if they are at the same place in the memory mal.
   For the HC12, a far address is using the logical addresses, for the HCS12X however, far addresses are using global addresses.

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -