📄 datapage.lst
字号:
809: #pragma NO_FRAME
810:
811: void NEAR _FAR_COPY_RC(void) {
812: #if USE_SEVERAL_PAGES
813: __asm {
814: DEX ;// source addr-=1, because loop counter ends at 1
815: PSHX ;// save source offset
816: PSHD ;// save both pages
817: DEY ;// destination addr-=1, because loop counter ends at 1
818: PSHY ;// save destination offset
819: LDY 6,SP ;// Load Return address
820: LDX 2,Y+ ;// Load Size to copy
821: STY 6,SP ;// Store adjusted return address
822: loop:
823: LDD 4,SP ;// load source offset
824: LEAY D,X ;// calculate actual source address
825: LDAB 2,SP ;// load source page
826: __PIC_JSR(_LOAD_FAR_8) ;// load 1 source byte
827: PSHB ;// save value
828: LDD 0+1,SP ;// load destination offset
829: LEAY D,X ;// calculate actual destination address
830: PULA ;// restore value
831: LDAB 3,SP ;// load destination page
832: __PIC_JSR(_STORE_FAR_8) ;// store one byte
833: DEX
834: BNE loop
835: LEAS 6,SP ;// release stack
836: _SRET ;// debug info only: This is the last instr of a function with a special return
837: RTS ;// return
838: }
839: #else
840: __asm {
841: PSHD ;// store page registers
842: TFR X,D
843: PSHY ;// temporary space
844: LDY 4,SP ;// load return address
845: ADDD 2,Y+ ;// calculate source end address. Increment return address
846: STY 4,SP
847: PULY
848: PSHD ;// store src end address
849: LDAB 2,SP ;// reload source page
850: LDAA PAGE_ADDR ;// save page register
851: PSHA
852: loop:
853: STAB PAGE_ADDR ;// set source page
854: LDAA 1,X+ ;// load value
855: MOVB 4,SP, PAGE_ADDR ;// set destination page
856: STAA 1,Y+
857: CPX 1,SP
858: BNE loop
859:
860: LDAA 5,SP+ ;// restore old page value and release stack
861: STAA PAGE_ADDR ;// store it into page register
862: _SRET ;// debug info only: This is the last instr of a function with a special return
863: RTS
864: }
865: #endif
866: }
867:
868: /*--------------------------- _FAR_COPY --------------------------------
869:
870: The _FAR_COPY runtime routine was used to copied large memory blocks in previous compiler releases.
871: However this release now does use _FAR_COPY_RC instead. The only difference is how the size of
872: the area to be copied is passed into the function. For _FAR_COPY the size is passed on the stack just
873: above the return address. _FAR_COPY_RC does expect the return address just after the JSR _FAR_COPY_RC call
874: in the code of the caller. This allows for denser code calling _FAR_COPY_RC but does also need a slightly
875: larger runtime routine and it is slightly slower.
876: The _FAR_COPY routine is here now mainly for compatibility with previous releases.
877: The current compiler does not use it.
878:
879: --------------------------- _FAR_COPY ----------------------------------*/
880:
881: #ifdef __cplusplus
882: extern "C"
883: #endif
884: #pragma NO_ENTRY
885: #pragma NO_EXIT
886: #pragma NO_FRAME
887:
888: void NEAR _FAR_COPY(void) {
889: #if USE_SEVERAL_PAGES
890: __asm {
891: DEX ;// source addr-=1, because loop counter ends at 1
892: PSHX ;// save source offset
893: PSHD ;// save both pages
894: DEY ;// destination addr-=1, because loop counter ends at 1
895: PSHY ;// save destination offset
896: LDX 8,SP ;// load counter, assuming counter > 0
897:
898: loop:
899: LDD 4,SP ;// load source offset
900: LEAY D,X ;// calculate actual source address
901: LDAB 2,SP ;// load source page
902: __PIC_JSR(_LOAD_FAR_8) ;// load 1 source byte
903: PSHB ;// save value
904: LDD 0+1,SP ;// load destination offset
905: LEAY D,X ;// calculate actual destination address
906: PULA ;// restore value
907: LDAB 3,SP ;// load destination page
908: __PIC_JSR(_STORE_FAR_8) ;// store one byte
909: DEX
910: BNE loop
911: LDX 6,SP ;// load return address
912: LEAS 10,SP ;// release stack
913: JMP 0,X ;// return
914: }
915: #else
916: __asm {
917: PSHD ;// store page registers
918: TFR X,D
919: ADDD 4,SP ;// calculate source end address
920: STD 4,SP
921: PULB ;// reload source page
922: LDAA PAGE_ADDR ;// save page register
923: PSHA
924: loop:
925: STAB PAGE_ADDR ;// set source page
926: LDAA 1,X+ ;// load value
927: MOVB 1,SP, PAGE_ADDR ;// set destination page
928: STAA 1,Y+
929: CPX 4,SP
930: BNE loop
931:
932: LDAA 2,SP+ ;// restore old page value and release stack
933: STAA PAGE_ADDR ;// store it into page register
934: LDX 4,SP+ ;// release stack and load return address
935: JMP 0,X ;// return
936: }
937: #endif
938: }
939:
940: #else /* __HCS12X__ */
941:
942: /*
943: The HCS12X knows two different kind of addresses:
944: - Logical addresses. E.g.
945: MOVB #page(var),RPAGE
946: INC var
947:
948: - Global addresses E.g.
949: MOVB #page(var),GPAGE
950: GLDAA var
951: INCA
952: GSTAA var
953:
954: Global addresses are used with G-Load's and G-Store's, logical addresses are used for all the other instructions
955: and occasions. As HC12's or HCS12's do not have the G-Load and G-Store instructions,
956: global addresses are not used with these processor families.
957: They are only used with HCS12X chips (and maybe future ones deriving from a HCS12X).
958:
959: Logical and Global addresses can point to the same object, however the global and logical address of an object
960: are different for most objects (actually for all except the registers from 0 to 0x7FF).
961: Therefore the compiler needs to transform in between them.
962:
963: HCS12X Pointer types:
964:
965: The following are logical addresses:
966: - all 16 bit pointers
967: - "char* __near": always.
968: - "char *" in the small and banked memory model
969: - 24 bit dpage, epage, ppage or rpage pointers (*1) (note: the first HCS12X compilers may not support these pointer types)
970: - "char *__dpage": Note this type only exists for
971: orthogonality with the HC12 A4 chip which has a DPAGE reg.
972: It does not apply to the HCS12X.
973: - "char *__epage": 24 bit pointer using the EPAGE register
974: - "char *__ppage": 24 bit pointer using the PPAGE register.
975: As the PPAGE is also used for BANKED code,
976: using this pointer type is only legal from non banked code.
977: - "char *__rpage": 24 bit pointer using the RPAGE register
978:
979:
980: The following are global addresses:
981: "char*": in the large memory model (only HCS12X)
982: "char* __far": always for HCS12X.
983:
984: (*1): For the HC12 and HCS12 "char* __far" and "char*" in the large memory model are also logical.
985:
986: Some notes for the HC12/HCS12 programmers.
987:
988: 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 map.
989: For the HC12, a far address is using the logical addresses, for the HCS12X however, far addresses are using global addresses.
990: This does cause troubles for the unaware!
991:
992: The conversion routines implemented in this file support the special HCS12XE RAM mapping (when RAMHM is set).
993: To enable this mapping compile this file with the "-MapRAM" compiler option.
994:
995: HCS12X Logical Memory map
996:
997: Logical Addresses Used for shadowed at page register Global Address
998:
999: 0x000000 .. 0x0007FF Peripheral Registers Not Paged 0x000000
1000: 0x??0800 .. 0x??0BFF Paged EEPROM EPAGE (@0x17) 0x100000+EPAGE*0x0400
1001: 0x000C00 .. 0x000FFF Non Paged EEPROM 0xFF0800..0xFF0FFF Not Paged 0x13FC00
1002: 0x??1000 .. 0x??1FFF Paged RAM RPAGE (@0x16) 0x000000+RPAGE*0x1000
1003: 0x002000 .. 0x003FFF Non Paged RAM 0xFE1000..0xFF1FFF Not Paged 0x0FE000
1004: 0x004000 .. 0x007FFF Non Paged FLASH 0xFC8000..0xFCBFFF Not Paged 0x7F4000
1005: 0x??8000 .. 0x00BFFF Paged FLASH PPAGE (@0x30) 0x400000+PPAGE*0x4000
1006: 0x00C000 .. 0x00FFFF Non Paged FLASH 0xFF8000..0xFFBFFF Not Paged 0x7FC000
1007:
1008: NA: Not Applicable
1009:
1010: HCS12X Global Memory map
1011:
1012: Global Addresses Used for Logical mapped at
1013:
1014: 0x000000 .. 0x0007FF Peripheral Registers 0x000000 .. 0x0007FF
1015: 0x000800 .. 0x000FFF DMA registers Not mapped
1016: 0x001000 .. 0x0FFFFF RAM 0x??1000 .. 0x??1FFF
1017: 0x0FE000 .. 0x0FFFFF RAM, Log non paged 0x002000 .. 0x003FFF
1018: 0x100000 .. 0x13FFFF EEPROM 0x??0800 .. 0x??0BFF
1019: 0x13FC00 .. 0x13FFFF EEPROM non paged 0x000C00 .. 0x000FFF
1020: 0x140000 .. 0x3FFFFF External Space Not mapped
1021: 0x400000 .. 0x7FFFFF FLASH 0x??8000 .. 0x??BFFF
1022: 0x7F4000 .. 0x7F7FFF FLASH, Log non paged 0x004000 .. 0x007FFF
1023: 0x7FC000 .. 0x7FFFFF FLASH, Log non paged 0x00C000 .. 0x00FFFF
1024:
1025: HCS12X Logical Memory map (RAM mapped)
1026:
1027: Logical Addresses Used for shadowed at page register Global Address
1028:
1029: 0x000000 .. 0x0007FF Peripheral Registers Not Paged 0x000000
1030: 0x??0800 .. 0x??0BFF Paged EEPROM EPAGE (@0x17) 0x100000+EPAGE*0x0400
1031: 0x000C00 .. 0x000FFF Non Paged EEPROM 0xFF0800..0xFF0FFF Not Paged 0x13FC00
1032: 0x??1000 .. 0x??1FFF Paged RAM RPAGE (@0x16) 0x000000+RPAGE*0x1000
1033: 0x002000 .. 0x003FFF Non Paged RAM 0xFE1000..0xFF1FFF Not Paged 0x0FE000
1034: 0x004000 .. 0x007FFF Non Paged RAM 0xFA1000..0xFD1FFF Not Paged 0FC000
1035: 0x??8000 .. 0x00BFFF Paged FLASH PPAGE (@0x30) 0x400000+PPAGE*0x4000
1036: 0x00C000 .. 0x00FFFF Non Paged FLASH 0xFF8000..0xFFBFFF Not Paged 0x7FC000
1037:
1038: NA: Not Applicable
1039:
1040: HCS12X Global Memory map
1041:
1042: Global Addresses Used for Logical mapped at
1043:
1044: 0x000000 .. 0x0007FF Peripheral Registers 0x000000 .. 0x0007FF
1045: 0x000800 .. 0x000FFF DMA registers Not mapped
1046: 0x001000 .. 0x0FFFFF RAM 0x??1000 .. 0x??1FFF
1047: 0x0FA000 .. 0x0FFFFF RAM, Log non paged 0x002000 .. 0x007FFF
1048: 0x100000 .. 0x13FFFF EEPROM 0x??0800 .. 0x??0BFF
1049: 0x13FC00 .. 0x13FFFF EEPROM non paged 0x000C00 .. 0x000FFF
1050: 0x140000 .. 0x3FFFFF External Space Not mapped
1051: 0x400000 .. 0x7FFFFF FLASH 0x??8000 .. 0x??BFFF
1052: 0x7F4000 .. 0x7F7FFF FLASH, Log non paged Not mapped
1053: 0x7FC000 .. 0x7FFFFF FLASH, Log non paged 0x00C000 .. 0x00FFFF
1054:
1055:
1056: How to read this table:
1057: For logical addresses, the lower 16 bits of the address do determine in which area the address is,
1058: if this address is paged, then this entry also controls and which of the EPAGE, PPAGE or RPAGE
1059: page register is controlling the bits 16 to 23 of the address.
1060: For global addresses, the bits 16 to 23 have to be in the GPAGE register and the lower 16 bits
1061: have to be used with the special G load or store instructions (e.g. GLDAA).
1062: As example the logical address 0x123456 is invalid. Because its lower bits 0x3456 are in a
1063: non paged area, so the page 0x12 does not exist.
1064: The address 0xFE1020 however does exist. Do access it, the RPAGE has to contain 0xFE and the
1065: offset 0x1020 has to be used.
1066:
1067: ORG $7000
1068: MOVB #0xFE, 0x16 ; RPAGE
1069: LDAA 0x1020 ; reads at the logical address 0xFE1020
1070:
1071: Because the last two RAM pages are also accessible directly from 0x2000 to 0x3FFF, the
1072: following shorter code does read the same memory location:
1073:
1074: ORG $7000
1075: LDAA 0x2020 ; reads at the logical address 0x2020
1076: ; which maps to the same memory as 0xFE1020
1077:
1078: This memory location now also has a global address. For logical 0xFE1020 the global address is 0x0FE020.
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -