It is currently Sun Apr 23, 2017 4:39 pm

All times are UTC - 7 hours





Post new topic Reply to topic  [ 6 posts ] 
Author Message
 Post subject: Calling Convention
PostPosted: Thu Mar 10, 2016 7:53 pm 
Offline

Joined: Tue Dec 29, 2015 2:42 pm
Posts: 11
6502/816 is still something new to me so I'm still figuring out how to organise my code best. For subroutines I've been doing this strange form of calling convention, if you can call it that, where I use the first sixteen bytes of RAM for arguments and return data by using a pointer in X. I don't really like this much, and it makes recursion basically impossible. Is there a better way to do this? For NES and SNES programming, how do you prefer to do your function calling conventions?


Top
 Profile  
 
 Post subject: Re: Calling Convention
PostPosted: Thu Mar 10, 2016 8:05 pm 
Offline
User avatar

Joined: Sun Jan 22, 2012 12:03 pm
Posts: 5032
Location: Canada
You can store anything you need for recursion using the stack (see: PHA/PLA/TXS/TSX). Use TSX and you can use indexed loads/stores to access your function-local stuff.

I rarely need recursion, though. Usually I just specify the use of ZP temporaries and registers in the function documentation (i.e. where is the return value, which are paramters, which get clobbered, etc.) and where functions call eachother I try not to overlap. In the cases where I can't avoid overlap (e.g. later code changes), I use the stack as an escape route.


Top
 Profile  
 
 Post subject: Re: Calling Convention
PostPosted: Thu Mar 10, 2016 8:08 pm 
Online

Joined: Sun Sep 19, 2004 11:12 pm
Posts: 18182
Location: NE Indiana, USA (NTSC)
ashterix wrote:
For subroutines I've been doing this strange form of calling convention, if you can call it that, where I use the first sixteen bytes of RAM for arguments

As do I, incidentally. Because subroutines call other subroutines, I document which bytes in $0000-$000F are overwritten by any particular subroutine.

Quote:
and return data by using a pointer in X.

Could you give an example?

Quote:
I don't really like this much, and it makes recursion basically impossible.

What recursion are you trying to accomplish in 27,000 cycles? The only thing I can anticipate needing recursion for would be a flood fill in a game like Rampart or Bombliss or Magical Drop or Bust-A-Move or Puzzle League, and that can be done as easily with a circular buffer of next things to check.


Top
 Profile  
 
 Post subject: Re: Calling Convention
PostPosted: Sat Mar 12, 2016 12:10 am 
Offline
User avatar

Joined: Mon Feb 07, 2011 12:46 pm
Posts: 880
It may be useful to use different calling conventions for different subroutines (if you are programming in pure assembly language rather than in C). What memory locations, registers, and/or flags affect and are affected by the subroutine can vary by each one. And in some cases you can use macros instead of subroutine calls. You could also see if something you are doing that is using recursion, does not necessarily need it; if it does you could use a different calling convention in such a case.

_________________
.


Top
 Profile  
 
 Post subject: Re: Calling Convention
PostPosted: Sat Dec 17, 2016 7:13 pm 
Offline

Joined: Wed Nov 30, 2016 4:45 pm
Posts: 48
Location: Southern California
In my 6502 stacks treatise, chapter 14 is on local variables and environments at http://wilsonminesco.com/stacks/loc_vars.html, and, following naturally, is chapter 15 on recursion at http://wilsonminesco.com/stacks/recurse.html . You can do it!

_________________
http://WilsonMinesCo.com/ lots of 6502 resources


Top
 Profile  
 
 Post subject: Re: Calling Convention
PostPosted: Fri Jan 06, 2017 11:01 am 
Offline
Formerly 43110
User avatar

Joined: Wed Feb 05, 2014 7:01 am
Posts: 284
I have been trying out many different ways to implement the data stack idea since my canceled game in 2014. I believe I now have a parameter convention that works for my entire code base and fixes the many gripes I had about wasting space and cycles on load and store instructions.

The Y register for the first low byte; the A register for the second high byte which can be ignored for subroutines that don't need it; and the X register for the pointer to the data stack of 16-bit numbers in little endian order. Y and A together form the 16-bit number for the top of stack. 32-bit numbers are also entirely little endian where the high word gets pushed first contrary to the convention of 6502 forth.

Using the Y register as the low byte was counter intuitive for me, but works better for data addressing using (Indirect),Y for Incrementing TOS, and for pushing an address to the return stack, and other things. Representing all numbers as little endian in memory helps reduce the size of 32-bit addition and subtraction subroutines, and removes the need to use swap for UM/MOD.


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

All times are UTC - 7 hours


Who is online

Users browsing this forum: No registered users and 4 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:  
Powered by phpBB® Forum Software © phpBB Group