Hi,
I had another look at this today because the thought occurred: rather
than changing stack args and so forth, why not just push the entire code
anew to the stack? So, I came up with the following:
; Construct "RET" instruction.
ld a, #0x81
push a
; Construct "LDF ($1234, X), A" instruction on stack.
ldw y, (0x06+1, sp)
pushw y
ldw y, (0x04+3, sp)
ld yh, #0xA7
pushw y
; Construct "LD A, ($1234, X)" instruction on stack
ldw y, (0x08+5, sp)
pushw y
ld a, #0xD6
push a
; Make a note of the location of stack code.
ldw y, sp
; Initialise loop counter to zero.
clrw x
0001$:
; Test if counter has reached block size, and exit loop if so.
cpw x, #FLASH_BLOCK_SIZE
jrnc 0002$
; Call the stack code to perform copy of a byte from buffer and
write it to
; flash, both offset by the counter value.
call (0x01, y)
; Increment counter and loop around.
incw x
jra 0001$
0002$:
; Clear code from the stack.
addw sp, #8
It was a bit confusing trying to work with the fact the stack is
expanded from top to bottom, so the code needs to be filled in
last-to-first, plus having to keep track of the offsets of the C
function arguments and their additional offsets after pushing each part
of the code (is there some assembler feature that might help with
that?), but I got there in the end. I hope it is correct. Haven't tested
it yet.
Oh, I've just thought while writing this that I probably should also
change the call/ret for callf/retf when __SDCC_MODEL_LARGE is defined.
I admit that this procedure is a but messy, but this is hacking a
machine, so what else can it be?
Yes, I agree. I'm not sure whether the additional complexity of this
solution of making a re-entrant function is worth it, especially as it
doesn't truly need it to be so, for my needs at least.
This would all be much easier if SDCC had features to allow reference to
local C variables from within inline ASM. :-)
Regards,
Basil
_______________________________________________
Sdcc-user mailing list
Sdcc-user@lists.sourceforge.net
https://lists.sourceforge.net/lists/listinfo/sdcc-user