| |
tlr
Registered: Sep 2003 Posts: 1717 |
best way to implement SEV?
I currently have this...
php
pha
txa
pha
tsx
pla
pla
pla
ora #%01000000 ; sev
pha
txs
pla
tax
pla
plp ...which is 16 bytes, uses 3 bytes stack. I suppose it isn't that much, but all those single byte instructions make it look huge. Any nice alternatives? |
|
... 5 posts hidden. Click here to view all posts.... |
| |
tlr
Registered: Sep 2003 Posts: 1717 |
Quote: Maybe like this:
sta somewhere
php
pla
ora #%01000000
pha
lda somewhere
plp
Yes, that works if we use one zp location. 10 bytes, 1 byte stack. I prefer only stack but this is shorter. |
| |
Fresh
Registered: Jan 2005 Posts: 101 |
While I clearly think Rastah Bar is the best solution, I'm adding this as a curious alternative, even though I do know it's not likely to fit any normal C64 code context, anyway...
Your first solution is not IRQ safe, as it relies on some bytes under SP not being changed during the routine execution.
Now, I honestly don't know the internals of superfluid, but if the code you're writing your library for is *not* indeed using IRQs, you may prepare $fffe and $ffff and use something like this:
IRQhandler:
sta somewhere
pla
ora #%01000000
pha
lda somewhere
rti
This can be called with just brk followed by any byte, which is a bit shorter than jsr: if the routine is called quite often you're going to get back the bytes you "lost" for initializing the IRQ handler and maybe even gaining some space. Moreover, it's even a bit faster!
My (silly) two cents :) |
| |
TWW
Registered: Jul 2009 Posts: 541 |
Quote: Yes, that works if we use one zp location. 10 bytes, 1 byte stack. I prefer only stack but this is shorter.
You can skip the ZP by using SMC at the cost of 1 byte (same execution time).
Now try figguring out how to do it without messing up the regs, stack or the flags while having it flexible to use in a library and ensure the execution cycles remain fixed (no branching^^) :D (hint, you cant...) <--- Bait! |
| |
tlr
Registered: Sep 2003 Posts: 1717 |
Quoting FreshYour first solution is not IRQ safe, as it relies on some bytes under SP not being changed during the routine execution.
Now, I honestly don't know the internals of superfluid, but if the code you're writing your library for is *not* indeed using IRQs, you may prepare $fffe and $ffff and use something like this:
IRQhandler:
sta somewhere
pla
ora #%01000000
pha
lda somewhere
rti
This can be called with just brk followed by any byte, which is a bit shorter than jsr: if the routine is called quite often you're going to get back the bytes you "lost" for initializing the IRQ handler and maybe even gaining some space. Moreover, it's even a bit faster!
Interesting approach but maybe not so practical. :)
for information, it is used in superfluid in many places to pass an additional easily branchable return flag besides the carry. |
| |
tlr
Registered: Sep 2003 Posts: 1717 |
Quoting TWWYou can skip the ZP by using SMC at the cost of 1 byte (same execution time).
Now try figguring out how to do it without messing up the regs, stack or the flags while having it flexible to use in a library and ensure the execution cycles remain fixed (no branching^^) :D (hint, you cant...) <--- Bait!
In my case the code is in ROM so no self mod for me, but please post any interesting solutions for others to use. |
| |
Krill
Registered: Apr 2002 Posts: 2850 |
Quoting tlrfor information, it is used in superfluid in many places to pass an additional easily branchable return flag besides the carry. So it's accu for a return code, with the N and Z flags set according to that value, plus independent C and V flags?
If so, i'll ask the XY question again. =)
What aboutpha
bit $xxxx; %x1xxxxxx somewhere in ROM code
pla to set the V flag with N+Z tied to accu value? |
| |
Fresh
Registered: Jan 2005 Posts: 101 |
If thats the case you dont even need to save/restore A.
Edit: my bad, you're perfectly right! |
| |
Krill
Registered: Apr 2002 Posts: 2850 |
Quoting FreshIf thats the case you dont even need to save/restore A. The BIT instruction sets N and Z, and those flags being set according to the value in the accu is a prerequisite.
Edit: Ah. :) |
| |
Fresh
Registered: Jan 2005 Posts: 101 |
Yes, I realized It Just a second after submitting :D |
| |
tlr
Registered: Sep 2003 Posts: 1717 |
Quoting KrillQuoting tlrfor information, it is used in superfluid in many places to pass an additional easily branchable return flag besides the carry. So it's accu for a return code, with the N and Z flags set according to that value, plus independent C and V flags?
If so, i'll ask the XY question again. =)
What aboutpha
bit $xxxx; %x1xxxxxx somewhere in ROM code
pla to set the V flag with N+Z tied to accu value? Yes, I suppose that should do the trick in most cases. It can be X/Y for return codes in some places though, think $ffd5.
So far I found it easier to just preserve everything to be safe. |
Previous - 1 | 2 - Next |