I am trying to write 0xAA to Address location 0x5555. The following code is working. May someone kindly explain in details how C167 controller interpret it? Why is #09555H used???
MOV DPP2,#0001H
MOV R12,#09555H
MOVB RL1,#00AAH
MOV [R12],RL1
You must be using small memory model and near data pointers. The C166 compiler utilizes DPP addressing mechanism of the C167 microcontroller for near data pointers, which means that a near absolute address will most likely be translated to a different physical address. To specify absolute physical address, you have to use far, huge or xhuge pointers. Use macros from absacc.h, they were designed for that:
MVAR(char, 0x5555) = '\xAA';
Thank you for you information, Mike. This is written in Assembly code which was obtained from the web site, and not from the compiler. Somehow, the bit 15-14 had to be set to 10B. On similar situation where address 0x2AAA is to be written, R12 is loaded with #AAAAH!! Probably the addressing is different when in SMALL model, as what you had mentioned. I am not able to get any information from the C167 manual. Maybe you can help.
It is usually not a good idea (or style) to modify the contents of the DPPx-Registers. The DPPx-Registers should be set to fixed values in the startup sequence (start.a66) and the compiler usually assumes that they are not changed. You are using "near" addressing mode together with DPP2. The shortest code would be: MOV DPP2,#1 MOVB RL1,#0AAh MOV DPP2:1555h,RL1 By using "DPP2:1555h" the assembler will calculate 9555h as near address, so you don't have to calc it yourself. There's no difference between "DPP2:1555h" and "DPP2:5555h" The first two bits of a near-address select the DPPx-Register, the last 14 bits contain the address offset. The first two bits of 9555h are "10", so DPP2 is selected. The contents of DPP2 is "1", and so data page #1 with start address 4000h is selected. The address offset (14 bit) is 1555h. By adding 4000h and 1555h you get the physical address 5555h. Instead of using DPP2, the "huge" addressing mode would be easier to use: MOVB RL1,#0AAh EXTS #0,#1 MOV 05555h,RL1 where #0 is the segment number (= high-word of the physical address), and #1 is the number of following instructions. (This code does not work for the C166 device, but it works well for all other devices such as C167, C164. Also beware when using EXT-instructions in a Class B trap handler: save and reset the TFR-Register first.)
You can read about addressing modes of the C167 in "C166 Instruction Set Manual". This document in PDF format is here: http://www.infineon.com/cgi/ecrm.dll/ecrm/scripts/public_download.jsp?oid=8056&parent_oid=-8137 Basically, what happens is the following. Bits 15 and 14 of R12 (which was used as a pointer in your example) select which of the four DPPs to use. 10 binary means DPP2. Then the physical address is calculated according to the formula Addr = (DPP2 << 14) + (R12 & 0x3FFF) In your case it yields 0x5555, as expected. There is a DPP override mechanism, which uses EXTP and EXTS instructions. You can find details in the C166 Instruction Set Manual, or you can use compiler generated code as an example. - Mike
The two MSBits specify the DPP register that should be used to complete the address. In address 0x9555, the two MSBits are 10B or 0x02. This means that DPP2 is used. Since DPP2 contains the value 0x01 you have to replace the two MSBits of the address with 0x01. So 1001B becomes 0101B which results in the address 0x5555. DPP usage is kind of a pain in the butt when you are debugging but it does allow you locate data and such anywhere in the 16 Mbyte address space and still use 16-bit addressing mode. -Walt
Another remark: The addressing mode ("near" or "far" or huge") has nothing to do with the memory model ("small" or "large" or whatever). The addressing modes will work in any memory model. You can also force the C-compiler to use a certain addressing mode by using (near*), (far*) or (huge*). Only the "tiny" memory model may have some restrictions, but you won't have to modify the DPP-Registers in tiny model.