📄 datapage.c
字号:
/*--------------------------- 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
Below2000:
LSLD ;// D contains 0000 bit11..bit0, C contains bit12
BCC Below1000
// from 0x1000 to 0x1FFF
LDAB __RPAGE_ADR__
LDAA #0x10
MUL
EORB 0,SP
EORB #0x10 ;// clear 1 bit
STAB 0,SP
TFR A,B
PULX
RTS
Below1000:
LSLD ;// D contains 0000 0 bit10..bit0, C contains bit11
BCC Below0800
// from 0x0800 to 0x0FFF
LSLD ;// D contains 0000 00 bit9..bit0, C contains bit10
BCC Below0C00
// from 0x0C00 to 0x0FFF
LDAB #0x13
PULX
LEAX 0xF000,X
RTS ;// returns 0b0001 0011 1111 11 bit9...bit0
Below0C00:
// from 0x0800 to 0x0BFF
LDAB __EPAGE_ADR__
LDAA #0x04
MUL
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -