📄 datapage.c
字号:
MOVB #0x0F, 0x10 ; GPAGE
GLDAA 0xE020 ; reads at the global address 0x0FE020
; which maps to the same memory as the logical addr. 0xFE1020
Therefore every memory location for the HCS12X has up to 3 different addresses.
Up to two logical and one global.
Notes.
- Not every address has a logical equivalent. The external space is only available in the global address space.
- The PPAGE must only be set if the code is outside of the 0x8000 to 0xBFFF range.
If not, the next code fetch will be from the new wrong PPAGE value.
- Inside of the paged area, the highest pages are allocated first. So all HCS12X's do have the FF pages
(if they have this memory type at all).
- For RPAGE, the value 0 is illegal. Otherwise the global addresses would overlap with the registers.
*/
/*lint -e10, -e106, -e30 */
#if __OPTION_ACTIVE__("-MapRAM")
#define __HCS12XE_RAMHM_SET__
#endif
/*lint +e10, +e106, +e30 */
/*--------------------------- pointer conversion operations -------------------------------*/
/*--------------------------- _CONV_GLOBAL_TO_LOGICAL --------------------------------
Convert 24 bit logical to 24 bit global pointer
("char*__far" to "char*__gpage")
Arguments :
- B : page part of global address
- X : 16 offset part of global address
Postcondition :
- B == page of returned logical address
- X == offset of returned logical address
- Y remains unchanged
- A remains unchanged
*/
/*--------------------------- Convert 24 bit global to 24 bit logical pointer ----------------------------------*/
/* B:X = Logical(B:X) */
#ifdef __cplusplus
extern "C"
#endif
#pragma NO_FRAME
#pragma NO_ENTRY
#pragma NO_EXIT
void NEAR _CONV_GLOBAL_TO_LOGICAL(void) {
asm {
CMPB #0x40 ;/* flash (0x400000..0x7FFFFF) or not? */
BLO Below400000
/* from 0x400000 to 0x7FFFFF */
CMPB #0x7F ;/* check for Unpaged areas 0x7FC000..0x7FFFFF and 0x7F4000..0x7F7FFF */
BNE PAGED_FLASH_AREA
#ifndef __HCS12XE_RAMHM_SET__
BITX #0x4000
BEQ PAGED_FLASH_AREA
#else
CPX #0xC000
BLO PAGED_FLASH_AREA
#endif
/* from 0x7F4000 to 0x7F7FFF or 0x7FC000 to 0x7FFFFF */
;/* Note: offset in X is already OK. */
CLRB ;/* logical page == 0 */
RTS
PAGED_FLASH_AREA: ;/* paged flash. Map to 0x8000..0xBFFF */
/* from 0x400000 to 0x7F3FFF or 0x7F8000 to 0x7FBFFF */
LSLX ; /* shift 24 bit address 2 bits to the left to get correct page in B */
ROLB
LSLX
ROLB
LSRX ; /* shift back to get offset from 0x8000 to 0xBFFF */
SEC
RORX
RTS ;/* done */
Below400000:
/* from 0x000000 to 0x3FFFFF */
#if 0 /* How should we handle mapping to External Space. There is no logical equivalent. This is an error case! */
CMPB #0x14 ;/* check if above 0x140000. If so, its in the external space */
BLO Below140000
ERROR !!!! ;/* this mapping is not possible! What should we do? */
RTS
Below140000:
/* from 0x000000 to 0x13FFFF */
#endif
CMPB #0x10 ;/* if >= 0x100000 it's EEPROM */
BLO Below100000
/* from 0x100000 to 0x13FFFF (or 0x3FFFFF) */
CMPB #0x13 ;/* check if its is in the non paged EEPROM area at 0x13FC00..0x13FFFF */
BLO Below13FC00
CPX #0xFC00
BLO Below13FC00
/* from 0x13FC00 to 0x13FFFF (or 0x3FFFFF) */
LEAX 0x1000,X ;/* same as SUBX #0xF000 // map from 0xFC00 to 0x0C00 */
CLRB
RTS
Below13FC00:
/* from 0x100000 to 0x13FBFF */
PSHA
TFR XH,A ;/* calculate logical page */
EXG A,B
LSRD
LSRD
PULA
ANDX #0x03FF
LEAX 0x0800,X ;/* same as ORX #0x0800 */
RTS
Below100000:
/* from 0x000000 to 0x0FFFFF */
TSTB
BNE RAM_AREA
CPX #0x1000
BLO Below001000
RAM_AREA:
/* from 0x001000 to 0x0FFFFF */
CMPB #0x0F
BNE PagedRAM_AREA
#ifndef __HCS12XE_RAMHM_SET__
CPX #0xE000
BLO PagedRAM_AREA
/* from 0x0FE000 to 0x0FFFFF */
SUBX #(0xE000-0x2000) ;/* map 0xE000 to 0x2000 */
#else
CPX #0xA000
BLO PagedRAM_AREA
/* from 0x0FA000 to 0x0FFFFF */
SUBX #(0xA000-0x2000) ;/* map 0xA000 to 0x2000 */
#endif
CLRB ;/* Page is 0 */
RTS
PagedRAM_AREA:
/* from 0x001000 to 0x0FDFFF */
PSHA
TFR XH, A ;/* calculate logical page */
EXG A,B
LSRD
LSRD
LSRD
LSRD
PULA
ANDX #0x0FFF
LEAX 0x1000,X ;/* same as ORX #0x1000 */
RTS
Below001000:
/* from 0x000000 to 0x000FFF */
#if 0
CMPA #0x08
BLO Below000800
/* from 0x000800 to 0x000FFF */
/* ??? DMA Regs? */
RTS
Below000800:
/* from 0x000000 to 0x0007FF */
#endif
CLRB
RTS
}
}
/*--------------------------- _CONV_GLOBAL_TO_NEAR --------------------------------
Convert 24 bit global to 16 bit logical pointer
("char*__far" to "char*")
Arguments :
- B : page part of global address
- X : 16 offset part of global address
Postcondition :
- B is undefined
- A remains unchanged
- X == offset of returned logical address
- Y remains unchanged
*/
/*--------------------------- Convert 24 bit global to 16 bit logical pointer ----------------------------------*/
/* X = Logical(B:X) */
#ifdef __cplusplus
extern "C"
#endif
#define _REUSE_CONV_GLOBAL_TO_LOGICAL 1
#pragma NO_FRAME
#pragma NO_ENTRY
#pragma NO_EXIT
void NEAR _CONV_GLOBAL_TO_NEAR(void){
#if _REUSE_CONV_GLOBAL_TO_LOGICAL /* do we want an optimized version? */
__asm JMP _CONV_GLOBAL_TO_LOGICAL; /* offset for NEAR is same as for LOGICAL. */
#else
asm {
CMPB #0x40 ;/* flash (0x400000..0x7FFFFF) or not? */
BLO Below400000
/* from 0x400000 to 0x7FFFFF */
#ifndef __HCS12XE_RAMHM_SET__
CMPB #0x7F ;/* check for Unpaged areas 0x7FC000..0x7FFFFF and 0x7F4000..0x7F7FFF */
BNE PAGED_FLASH_AREA
CPX #0x4000
BLO PAGED_FLASH_AREA
/* from 0x7F4000 to 0x7FFFFF */
#else
CMPB #0x7F ;/* check for Unpaged area 0x7FC000..0x7FFFFF */
BNE PAGED_FLASH_AREA
CPX #0xC000
BLO PAGED_FLASH_AREA
/* from 0x7FC000 to 0x7FFFFF */
#endif
;/* note non PAGED flash areas or paged area 0x7F8000..0x7FBFFF which are mapping all correctly */
RTS
PAGED_FLASH_AREA: ;/* paged flash. Map to 0x8000..0xBFFF */
/* from 0x400000 to 0x7F3FFF */
ANDX #0x3F00 ;/* cut to 0.. 0x3FFF */
LEAX 0x8000,X ;/* same as ORX #0x8000 ;// move to 0x8000..0xBFFF */
RTS ;/* done */
Below400000:
/* from 0x000000 to 0x3FFFFF */
#if 0 /* How should we handle mapping to External Space. There is no logical equivalent. This is an error case! */
CMPB #0x14 ;/* check if above 0x140000. If so, its in the external space */
BLO Below140000
ERROR !!!! ;/* this mapping is not possible! What should we do? */
RTS
Below140000:
/* from 0x000000 to 0x13FFFF */
#endif
CMPB #0x10 ;/* if >= 0x100000 it's EEPROM */
BLO Below100000
/* from 0x100000 to 0x13FFFF (or 0x3FFFFF) */
CMPB #0x13 ;/* check if its is in the non paged EEPROM area at 0x13FC00..0x13FFFF */
BNE Below13FC00
CPX #0xFC00
BLO Below13FC00
/* from 0x13FC00 to 0x13FFFF (or 0x3FFFFF) */
SUBX #0xF000 ;/* map from 0xFC00 to 0x0C00 */
RTS
Below13FC00:
/* from 0x100000 to 0x13FBFF */
ANDX #0x03FF
LEAX 0x800,X ;/* same as ORX #0x0800 */
RTS
Below100000:
/* from 0x000000 to 0x0FFFFF */
TBNE B,RAM_AREA
CPX #0x1000
BLO Below001000
RAM_AREA:
/* from 0x001000 to 0x0FFFFF */
CMPB #0x0F
BNE PagedRAM_AREA
#ifndef __HCS12XE_RAMHM_SET__
CPX #0xE000
BLO PagedRAM_AREA
/* from 0x0FE000 to 0x0FFFFF */
SUBX #(0xE000-0x2000) ;/* map 0xE000 to 0x2000 */
#else
CPX #0xA000
BLO PagedRAM_AREA
/* from 0x0FA000 to 0x0FFFFF */
SUBX #(0xA000-0x2000) ;/* map 0xA000 to 0x2000 */
#endif
RTS
PagedRAM_AREA:
/* from 0x001000 to 0x0FDFFF (0x001000 to 0x0F9FFF if HCS12XE RAM mapping is enabled) */
ANDX #0x0FFF
LEAX 0x1000,X ;/* same as ORX #0x1000 */
RTS
Below001000:
/* from 0x000000 to 0x000FFF */
RTS
}
#endif
}
/*--------------------------- _CONV_NEAR_TO_GLOBAL --------------------------------
Convert 16 bit logical to 24 bit global pointer
("char*__near" to "char*__far")
Arguments :
- X : 16 bit near pointer
Postcondition :
- B == page of returned global address
- X == offset of returned global address
- Y remains unchanged
- A is unspecified
*/
/*--------------------------- Convert 16 bit logical to 24 bit global pointer ----------------------------------*/
/* B:X = Global(X) */
#ifdef __cplusplus
extern "C"
#endif
#pragma NO_FRAME
#pragma NO_ENTRY
#pragma NO_EXIT
void NEAR _CONV_NEAR_TO_GLOBAL(void){
asm {
/* syntax: */
/* input 16 bit offset is bit15..bit0 */
/* ppage values: ppage7..ppage0 */
/* epage values: epage7..epage0 */
/* dpage values: dpage7..dpage0 */
/* rpage values: rpage7..rpage0 */
PSHX ;/* D contains bit15..bit0 */
TFR X,D ;/* D is cheaper to shift */
LSLD ;/* D contains 0 bit14..bit0, C contains bit15 */
BCC Below8000 ;/* bit15 == 0? */
/* from 0x8000 to 0xFFFF */
LSLD ;/* D contains 00 bit13..bit0, C contains bit14 */
BCC BelowC000
LDAB #0x7F
PULX
RTS ;/* returns 0b0111 1111 11 bit13...bit0 */
BelowC000: ;/* from 0x8000 to 0xBFFF */
TFR D,X
LDAB __PPAGE_ADR__
SEC
RORB
RORX
LSRB
RORX
LEAS 2,SP
RTS ;/* returns 0b01 ppage7..ppage0 bit13...bit0 */
Below8000:
LSLD ;/* D contains 00 bit13..bit0, C contains bit14 */
BCC Below4000
/* from 0x4000 to 0x7FFF */
PULX
#ifndef __HCS12XE_RAMHM_SET__
LDAB #0x7F
#else
LEAX (0xC000-0x4000),X
LDAB #0x0F
#endif
RTS ;/* returns 0b0111 1111 01 bit13...bit0 */
Below4000:
LSLD ;/* D contains 000 bit12..bit0, C contains bit13 */
BCC Below2000
/* from 0x2000 to 0x3FFF */
PULX
#ifndef __HCS12XE_RAMHM_SET__
LEAX (0xE000-0x2000),X
#else
LEAX (0xA000-0x2000),X
#endif
LDAB #0x0F
RTS ;/* returns 0b0000 1111 111 bit12...bit0 */
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -