@Bean, STACK issues
Bean,
I was trying to use manual banking to access stack variables.
The attached program tries to calculate signed division using
2 FUNC's with local variables.
The declaration of locals is straight forward.
The list output shows
So the addresses of the declared locals are outside the stackbank (which·is at $20).
So I thought, lets use bank @__STACK to gain access to the stackbank.
That works, except that imAccuB_MSB has the same address as imSign,
so when imUDIV16 is called, imSign gets overwritten.
Then I remembered that we need to calculate the true addresses, using
· w = @imLocal
· fsr = w
This selects the stackbank.
However, calling UDIV16, imAccuB_MSB still overwrite imSign.
Now, how can we prevent that from happening while imAccuB_MSB and imSign
have the identical offset to their local top of stack.
regards peter
I was trying to use manual banking to access stack variables.
The attached program tries to calculate signed division using
2 FUNC's with local variables.
FUNC imSDIV16
imLocal var byte (1)
imSign var byte @imLocal(0)
bank @imLocal 'use #__STACK and the stackbank is accessed, imSign @$2F
imSign = __param2 XOR __param4
__wparam12 = abs __wparam12 'make values positive
__wparam34 = abs __wparam34
imUDIV16 __param1,__param2,__param3,__param4
bank @imLocal 'use #__STACK and the stackbank is accessed
if imSign.7 = 1 then
__wparam12 = - __wparam12
__wparam34 = - __wparam34
endif
bank __DEFAULT
return 'prevents warning
ENDFUNC
FUNC imUDIV16 imLocal var byte (4) imAccuA var word @imLocal(0) imAccuB var word @imLocal(2) bank @imLocal 'use #__STACK and the stackbank is accessed, imAccuB_MSB at $2F imAccuB = __wparam34 imAccuA = __wparam12 / imAccuB __wparam34 = __wremainder 'save the remainder __wparam12 = imAccuA bank __DEFAULT return 'prevents warning ENDFUNC
The declaration of locals is straight forward.
The list output shows
198 =0000003B imSDIV16: ;FUNC imSDIV16
199
200 =0000001F imLocal = __STACK-$01 ; imLocal var byte (1)
201 003B 0C01 ADD __STACKPTR,#1
003C 01EF
202
203 =0000001F imSign = imLocal+0 ; imSign var byte @imLocal(0)
204
260 =0000006B imUDIV16: ;FUNC imUDIV16
261
262 =0000001C imLocal = __STACK-$04 ; imLocal var byte (4)
263 006B 0C04 ADD __STACKPTR,#4
006C 01EF
264
265 =0000001C imAccuA = imLocal+0 ; imAccuA var word @imLocal(0)
266 =0000001C imAccuA_LSB = imAccuA
267 =0000001D imAccuA_MSB = imAccuA+1
268
269 =0000001E imAccuB = imLocal+2 ; imAccuB var word @imLocal(2)
270 =0000001E imAccuB_LSB = imAccuB
271 =0000001F imAccuB_MSB = imAccuB+1
272
So the addresses of the declared locals are outside the stackbank (which·is at $20).
So I thought, lets use bank @__STACK to gain access to the stackbank.
That works, except that imAccuB_MSB has the same address as imSign,
so when imUDIV16 is called, imSign gets overwritten.
Then I remembered that we need to calculate the true addresses, using
· w = @imLocal
· fsr = w
This selects the stackbank.
However, calling UDIV16, imAccuB_MSB still overwrite imSign.
Now, how can we prevent that from happening while imAccuB_MSB and imSign
have the identical offset to their local top of stack.
regards peter


Comments
is by declaring skipbytes like this
which skips the amount of bytes already allocated from stack
when entering imUDIV16. In this case the number is 1,
but in general, the number must be equal to the deepest
level at which imUDIV16 is called (it may also be called from
another sub that uses 3 localbytes, in which the skipbytes must be set to 3).
That really is not a workable solution because one has to trace the calls.
Besides that, it makes us run out of locals much quicker.
regards peter
but then accessing the locals takes quite more code,
so that's why I tried to use manual banking, but it looks
impossible to make that happen.
regards peter
and inserted it as asm, removing unnecessary instructions.
It turns out·imAccuB is not required when directly using asm.
This looks the best I can get.
regards peter