| |
Frantic
Registered: Mar 2003 Posts: 1648 |
ACME macro for delaying X cycles
Anybody got an macro handy for the ACME assembler for delaying X number of cycles? It is OK if it kills the A or X register. |
|
... 21 posts hidden. Click here to view all posts.... |
| |
lft
Registered: Jul 2007 Posts: 369 |
But in that case, the byte following BRK would be some random byte from the original code. If multiple patches were used, there would be no guarantee that the extra bytes would be different from each other.
Meanwhile, the *address* of the extra byte is available on the stack, and you would have to retrieve it anyway in order to read the extra byte. Hence, it is easier to just use the address (which is unique) to distinguish between different patches. |
| |
Oswald
Registered: Apr 2002 Posts: 5094 |
thanks for the clarification.
"The 6502 was designed as a micro-controller for industrial machines"
more accurately Chuck Peddle had ATM machines and POS terminals (till/cash register) in mind, and so on. Cheap CPU that can be built into everyday products.
this is in "on the edge". |
| |
Frantic
Registered: Mar 2003 Posts: 1648 |
This is getting off topic |
| |
Krill
Registered: Apr 2002 Posts: 2980 |
Quoting lftBut in that case, the byte following BRK would be some random byte from the original code. If multiple patches were used, there would be no guarantee that the extra bytes would be different from each other. Collection of 8 bits, to be precise, each of which you can null individually until having a unique byte. And if that fails, null the bits of consecutive bytes and read past null bytes in the BRK handler. But anyhow, yes, that argument byte's just a bonus, which might or might not come in handy depending on the use-case. And patches were probably relatively rare. :) |
| |
ChristopherJam
Registered: Aug 2004 Posts: 1409 |
This is what I'm using in ca65 at the moment.
Given that I'm still clobbering flags with pha/pla, it's a bit OTT using illegals for NOP zeropage instead of BIT zeropage, but there's no harm in it, and this way you can convert the macro into a flag preserving one by removing the N=7 case.
I elected not to use the (0,x) thing, because I don't want to watch out for accidentally reading from IO.
; preserves a,x,y,sp
; may use a few bytes of stack
; Remove the N=7 case to get one that also preserves flags
.macro wait N
.if N = 2
nop
.elseif N = 3
.byt $04,3 ; NOP zp
.elseif N = 7
pha
pla
.elseif N < 9
nop
wait N-2
.elseif N = 12
jsr wait12
.elseif N < 14
wait 7
wait N-7
.elseif N<77
jsr wait14+14-(N)
.elseif N<84
wait 76
wait (N)-76
.elseif N<152
wait (N)/2
wait ((N)+1)/2
.else
wait 76
wait (N)-76
.endif
.endmacro
.segment "CODE"
.res 61,$80 ; NOP#nn
.byt $04 ; NOP zp
wait14:
nop
wait12:
rts
(I'll probably add it to codebase after I've done some more testing, unless someone else gets there first) |
| |
doynax Account closed
Registered: Oct 2004 Posts: 212 |
Off-topic but I don't suppose that anyone here has gotten around to writing a usable 6502 super-optimizer? It might be handy to brute-force this type or thing, finding a use for the more obscure illegal-opcodes, etc. Then again the solution in practice is typically to redefine the problem with the 6510 architecture in mind, so perhaps not.
Quoting ChristopherJamGiven that I'm still clobbering flags with pha/pla, it's a bit OTT using illegals for NOP zeropage instead of BIT zeropage, but there's no harm in it, and this way you can convert the macro into a flag preserving one by removing the N=7 case. PHP/PLP? |
| |
ChristopherJam
Registered: Aug 2004 Posts: 1409 |
Quoting doynaxPHP/PLP?
OMG, of course!
*fixes* |
| |
ChristopherJam
Registered: Aug 2004 Posts: 1409 |
Quoting doynaxOff-topic but I don't suppose that anyone here has gotten around to writing a usable 6502 super-optimizer? It might be handy to brute-force this type or thing, finding a use for the more obscure illegal-opcodes, etc.
Not yet, much as I've wondered about it from time to time.. |
| |
ChristopherJam
Registered: Aug 2004 Posts: 1409 |
Erm, replace the tail of that macro with
.elseif N<77
jsr wait14+14-(N)
.elseif N=77
wait 2
wait 75
.elseif N<84
wait 76
wait (N)-76
.elseif N<153
wait (N)/2
wait ((N)+1)/2
.else
wait 76
wait (N)-76
.endif
.endmacro
or you'll get errors for a few edge cases (it tries to call wait 1 and falls into an infinite recursion, triggering a fatal error: Too many nested .IFs) |
| |
Copyfault
Registered: Dec 2001 Posts: 478 |
The unintended RMW-Opcodes allow zp-indexed adressing plus they can be paired so that at least part of the change that is performed by the first opcode is inverted by the latter, e.g.ISB ($00,x)
DCP ($00,x) The cycle demand per RMW-zp-indexed-instruction is always 8. This way, it should be possible to cut down the amount of bytes for the delay routine if the no.of delay-cycles is high enough (>=16). It will take some extra effort (-> extra delay cycles) to also save accu and/or flags (e.g. some kind of PHP&PHA+PLP&PLA-bracket should do).
With these instructions, it's even more important to make sure that no accidental accesses of I/O-registers occur. This means the macro will have to handle it by choosing the operand byte accordingly.
Just a few thoughts, didn't implement such delay macros as of yet. |
Previous - 1 | 2 | 3 | 4 - Next |