Date : Fri, 17 Mar 2006 15:35:35 +0100
From : John Kortink <kortink@...>
Subject: Re: 1MHZ SCSI/ATA board
On Fri, 17 Mar 2006 13:29:37 +0000, Andy Armstrong wrote:
>On 16 Mar 2006, at 07:39, David Harper wrote:
>> How much have you good folk used the idea when writing 6502 code?
>
>Yeah, all the time :)
>
>For example for things like this:
>
>
>prstr php
> pha
> tya
> pha
> lda txptr
> pha
> lda txptr + 1
> pha
> tsx
> lda stack + 6, x
> sta txptr
> lda stack + 7, x
> sta txptr + 1
> ldy #0
>
>.prstr1 inc txptr
> bne .prstr2
> inc txptr + 1
>.prstr2 lda (txptr), y
> beq .prstr3
> jsr oswrch
> jmp .prstr1
>
>.prstr3 lda txptr
> sta stack + 6, x
> lda txptr + 1
> sta stack + 7, x
> pla
> sta txptr + 1
> pla
> sta txptr
> pla
> tay
> pla
> plp
> rts
>
>Which outputs an inline string and returns to the instruction after
>the trailing null byte. Used like this
>
> jsr prstr
> !text "Hello, World", 13, 10, 0
> rts
>
>If anyone fancies it how about a quick competition for the shortest
>version of the above code?
Well, ok, boredom strikes :
You don't save X. Costs four more. But : save X instead
of Y and use LDX #0, LDA (txptr,X) and an extra TSX at
prstr3. Saves three.
Also, it seems a waste to save and restore zero page
locations. Better assign a few for free use (as long
as intervening JSRs and interrupt routines stay away
from them), e.g. three of them (save and restore at
a higher level if need be, e.g. across service call
handling, if in a ROM), then (this is my own library
function for inline printing, well sort of, I also
corrupt A in practice, not using 'free') :
STA free
PLA
STA ptr+0
PLA
STA ptr+1
TYA
PHA
LDY #0
.char
INC ptr+0
BNE inced
INC ptr+1
.inced
LDA (ptr),Y
BEQ finish
JSR oswrch
JMP char
.finish
PLA
TAY
LDA ptr+1
PHA
LDA ptr+0
PHA
LDA free
RTS
Doesn't save flags though, but then I rarely do, it's
usually a waste of time.
It's not a real challenge is it. What about an AXY
neutralising call, e.g. you do :
JSR neutralise
...
routine
...
RTS
and you've still saved AXY. My library function for this is :
\
\
\ Call a routine preserving A,X,Y
\
\ On entry
\
\ - return address is that of target routine (must return with RTS)
\ - flags after target routine RTS is as after PLA
\
\
.`Call_AXY_Neutral
\
PHA \ Save A,X,Y
TXA
PHA
TYA
PHA
\
LDA #(`cnaxy_fini - 1) DIV 256 \ Ensure RTS to finaliser
PHA
LDA #(`cnaxy_fini - 1) MOD 256
PHA
\
LDY #5
\
.`cnaxy_copy
\
TSX \ Copy 'over' relevant data
LDA &101+6,X
PHA
\
DEY
BNE `cnaxy_copy
\
\
\ We now have stacked
\
\ caller hi (caller of our caller)
\ caller lo
\ target hi (target routine)
\ target lo
\ A
\ X
\ Y
\ finaliser hi
\ finaliser lo
\ target hi
\ target lo
\ A
\ X
\ Y
\
\
PLA \ Restore A,X,Y
TAY
PLA
TAX
PLA
\
RTS \ Return to target routine
\
]
:
`cnaxy_U% = 7:REM &101+7+SP = caller-caller address
`cnaxy_A% = 4:REM &101+4+SP = A
`cnaxy_X% = 3:REM &101+3+SP = X
`cnaxy_Y% = 2:REM &101+2+SP = Y
:
[OPT `P
\
.`cnaxy_fini
\
TSX \ Overwrite target hi with A
LDA &101+2,X
STA &101+4,X
\
PLA \ Restore A,X,Y
TAY
PLA
TAX
PLA
PLA
PLA
\
RTS
Much more fun !
John Kortink
--
Email : kortink@...
Homepage : http://www.inter.nl.net/users/J.Kortink
GoMMC, the ultimate BBC B/B+/Master storage system :
http://web.inter.nl.net/users/J.Kortink/home/hardware/gommc