Hi everyone,
I have an 8051 boot loader for in-system programming. I have a command protocol that allows me to read and write to flash, XRAM, and IRAM over the in-system communications interface (e.g. UART). I would like to add the four pages (0x00, 0x10, 0x0f, and 0x0c) of SFRs, but of course they can only be accessed directly, not indirectly.
Does anyone have a clever way of taking e.g. an SFR address in the range of 0x80 to 0xff as an input and returning the value of the SFR?
The best idea I have at the moment is a jump table, indexed by (addr-0x80), where each entry is a pre-programmed get/set of the corresponding SFR, followed by a jump to the end (effectively a 128-entry switch statement). Assuming I do the SFR paging and any loop management externally, the smallest I can see to shrink this is 3 bytes per entry (MOV A, addr ; RET), for 384 B to cover the full 128 B address space.
Speed is not of particular importance for this particular application, but code space is.
Cheers, -Lance
Your best bet would be: don't do that. Seriously.
But if you absolutely have to, the most space-efficient way this can be done, assuming your hardware can be set up that way, is self-modifying code. Copy the code bytes for
MOV A, 0x80 RET
into a 3-byte absolutely located section of von-Neumann mapped XRAM, overwrite the '0x80' byte with the SFR address you want, and call that snippet.
I don't really understand what it means, but since you got two people say the same thing in quick succession, it would be sensible to at least consider the idea.
Agreed. However, I do not believe it is possible to map XRAM (or other RAM) onto code space on SiLabs 8051 devices. Or, put another way, I believe the instructions fetch only from internal flash memory, which is a separate memory space from IRAM, which is separate again from XRAM.
In theory I could re-progam the flash memory on the fly, but that's a non-started since this is intended to be a very reliable boot loader.
SFR access is definitely a "nice-to-have", I'm just trying to see if there's anything that can be done before dismissing it entirely.
when I have needed :incirect SFR" I have used a state machine switch (type) case 0: SFRa = 47 break; if 1: SFRb =47 ......
View all questions in Keil forum