6502.org Forum  Projects  Code  Documents  Tools  Forum
It is currently Sat Nov 23, 2024 3:27 am

All times are UTC




Post new topic Reply to topic  [ 7 posts ] 
Author Message
PostPosted: Sun Aug 13, 2017 9:18 am 
Offline

Joined: Wed Jun 07, 2017 1:22 pm
Posts: 16
An alternative to the parameter passing described at NesDev. The main difference is that the target routine is responsible for calling the parameter-extracting code. (I'm guessing this is a well used technique- I would be interested to know where it was first used and what the most efficient implementation looks like.)

This method seems particularly appropriate if you wish to call a routine that operates on a structure at a fixed memory location, but will work for any constant word parameters.

Load/store method of passing a word,

Code:
      LDA lo
      STA a
      LDA hi
      STA a+1
      JSR my-routine


Callsite method,


Code:
      JSR my-routine
      DW my-parameter
      ;;execution flow resumes here
      ...
   
   MY-ROUTINE:
      ;Dereference the parameter at the call-site
      JSR deref-w
      ...
      X and A now contain the lo and hi word of
      my-parameter respectively.
      ...
      RTS


Here is the implementation of the dereferencing sub-routine. Other tricks are of course possible, e.g. https://wiki.nesdev.com/w/index.php/650 ... ent_system


Code:
DEREF-W 0B28 BA      TSX
                     0B29 E8      INX        ;Points to return address of this function
                     0B2A E8      INX        ;Now skip to return address of grandparent
                     0B2B E8      INX
                     ;Store the grandparent return address
                     0B2C BD0001  LDA $0100,X
                     0B2F 8519    STA $19    ;TMP
                     0B31 BD0101  LDA $0101,X
                     0B34 851A    STA $1A    ;TMP + 1
                     ;Now we have the address of the parameter (-1)
                     ;Add two to it so we can skip it when parent returns
                     0B36 18      CLC
                     0B37 A902    LDA #$02
                     0B39 7D0001  ADC $0100,X
                     0B3C 9D0001  STA $0100,X
                     0B3F A900    LDA #$00
                     0B41 7D0101  ADC $0101,X
                     0B44 9D0101  STA $0101,X
                     0B47 A001    LDY #$01   ;Offset against -1 for return convention
                     ;Dereference the word at the parameter address
                     0B49 B119    LDA ($19),Y
                     0B4B AA      TAX
                     0B4C C8      INY
                     0B4D B119    LDA ($19),Y
                     0B4F 60      RTS


A nice extension would be a entry point that allows for only a single byte- I will add this at some point but haven't found it necessary yet for the game I am writing, see https://github.com/djangojames/exploratory/blob/master/blog.md


Top
 Profile  
Reply with quote  
PostPosted: Sun Aug 13, 2017 9:52 am 
Offline
User avatar

Joined: Thu Dec 11, 2008 1:28 pm
Posts: 10986
Location: England
(Might be worth mentioning the method used in some of the Acorn MOS calls: 'XY' is a 16-bit pointer to a parameter block, which in general can pass parameters in and also receive results back. 'A' can be used to request different services from the same service call. See
http://mdfs.net/Docs/Comp/BBC/Oswords
This is a general and powerful method, but not especially cheap. It's also used for remote calls between the host and parasite processor of a setup with an I/O processor and a co-processor - it doesn't need shared memory, just the transfer of the parameter block.
Note that this method is useful for the general case where parameters are not known at assembly time.

Edit: oddly, X is the low byte and Y the high byte of the address, so we should say 'YX' for clarity.
)


Last edited by BigEd on Sun Aug 13, 2017 11:39 am, edited 1 time in total.

Top
 Profile  
Reply with quote  
PostPosted: Sun Aug 13, 2017 10:41 am 
Offline

Joined: Wed Jun 07, 2017 1:22 pm
Posts: 16
Quote:
'XY' is a 16-bit pointer to a parameter block,


This is a good idea for when the parameter block is dynamic- I hadn't thought of that and have been stuffing things into the zero-page which takes the extra STA/STX.

I have the luxury of using a LISP program to generate most of the assembly so I can afford to be strict with the maxim 'Don't do at run-time what can be done at compile time.' I'll have a post up on some basic static analysis soon... this has helped save a few bytes here and there.


Top
 Profile  
Reply with quote  
PostPosted: Sun Aug 13, 2017 11:35 am 
Offline
User avatar

Joined: Thu Dec 11, 2008 1:28 pm
Posts: 10986
Location: England
That will be interesting to see!


Top
 Profile  
Reply with quote  
PostPosted: Thu Aug 17, 2017 12:16 am 
Offline
User avatar

Joined: Fri Aug 30, 2002 1:09 am
Posts: 8544
Location: Southern California
This is addressed in chapters 6 & 7 of the 6502 stacks treatise, at http://wilsonminesco.com/stacks/parampassing.html and http://wilsonminesco.com/stacks/inlinedData.html . There's a lot more flexibility there than meets the eye, and you don't need temporary variables to do it. Local variables are addressed in chapter 14, at http://wilsonminesco.com/stacks/loc_vars.html which also has a few good links at the end.

_________________
http://WilsonMinesCo.com/ lots of 6502 resources
The "second front page" is http://wilsonminesco.com/links.html .
What's an additional VIA among friends, anyhow?


Top
 Profile  
Reply with quote  
PostPosted: Thu Aug 17, 2017 3:56 am 
Offline

Joined: Tue Jun 08, 2004 11:51 pm
Posts: 213
There are other uses that make more efficient uses.
Often a program needs to print out a number of fixed
strings. These can be tacked onto the call to the print
routine with either a leading string count or just a zero
as a terminator. I find the byte string length useful as
one would need a pointer index anyway. I suspect that
either way is about the same but the count is useful
for updating the return address on the stack. Otherwise
you have to keep the index in until your ready to finish.
One might right the code either was and see which you
like best.
Dwight


Top
 Profile  
Reply with quote  
PostPosted: Fri Aug 18, 2017 1:37 pm 
Offline

Joined: Wed Jun 07, 2017 1:22 pm
Posts: 16
Thanks guys.

Lots of helpful info at Garth's website, that place is a bit of a treasure trove.

Dwight- strings is the thing for the adventure game I am working on, you might like some of the posts I made on string compression. My github blog is really more of a personal diary than something for public consumption, but here are a couple of links.

https://github.com/djangojames/exploratory/blob/master/blog.md#interesting-results
https://github.com/djangojames/exploratory/blob/master/blog.md#tunstall

I did say I might post on static analysis at some point, but I have some complete code for string decompression and also an extremely simple implementation of "Uniform Binary Search". I shall be posting about these soon.


Top
 Profile  
Reply with quote  
Display posts from previous:  Sort by  
Post new topic Reply to topic  [ 7 posts ] 

All times are UTC


Who is online

Users browsing this forum: No registered users and 31 guests


You cannot post new topics in this forum
You cannot reply to topics in this forum
You cannot edit your posts in this forum
You cannot delete your posts in this forum
You cannot post attachments in this forum

Search for:
Jump to:  
cron