[comp.sys.cbm] needed: LARGE stack on c64

s887212@minyos.xx.rmit.oz.au (Stephen Riehm [Romulis]) (12/03/90)

I am trying to implement a highly recursive routine.. which requires some
local variables. (ie: this routine can easily do 600 iterations.. each with
4 variables). Naturally this wont fit on the c64's stack.. so I have tried
making my own (included below) which half works (the push half).
has anyone experimented with this sort of thing before??

the push and pop functions need to be written as subroutines (ie called
with JSR) as its a recursive group of functions which call each other.
they need to be able to store both the return address of the routine
calling push/pop.. and they need to be able to save some local variables..
this can be done explicitly..


here is my failed attempt.. any fixes.. or completely different solutions
GLADLY accepted.. and if enough people are interested I will post the best
one....

thanx in advance
Stephen Riehm.. s887212@minyos.xx.rmit.oz.au - soon to be dead for christmas :-(
Note: this means that replies after the 7th may not be received until the new
year.
--- cut here for pseudo assembly code ---

push onto user stack ((fd) = stack pointer)

   sei                 /* stop interrupts from possibly corrupting stack */
   ldy #$00
   jsr $dec.(fd)       /* lda $fd ; beq skip ; dec $fe ; skip dec $fd ; rts */
   lda $var1           /* store local variables onto user stack */
   sta ($fd),y
   jsr $dec.(fd)
   lda $var2
   sta ($fd),y
   jsr $dec.(fd)
   lda $var3
   sta ($fd),y
   jsr $dec.(fd)
   txs                 /* get address of calling function from stack.. 
   inx
   inx
   inx
   lda $0100,x
   sta ($fd),y          /* and push it onto the user stack...
   inx
   jsr $dec.(fd)
   lda $0100,x
   sta ($fd),y
   lda $fe,x            /* shift calling address for this function up on
   sta $0100,x          /* the stack..removing the hole left by the above
   dex
   lda $fe,x
   sta $0100,x
   dex
   txs                 /* reset stack pointer to the new current location
   cli                 /* interrupts are allowed again
   rts


note this much works. (i have written test code which successfully creates a
stack 4000ish bytes long..)

however...
pop from user stack ((fd) = stack pointer)

   sei
   ldy #$00
   tsx               /* create a hole to put new return address into stack
   inx
   lda $0100,x       /* shift address on bottom of stack.. creating space
   sta $fe,x         /* for address from user stack
   inx
   lda $0100,x
   sta $fe,x
   lda ($fd),y       /* copy address from bottom of user stack */
   sta $0100,x
   dex
   iny               /* stack is volatile at the moment.. so dont to any jsrs
   lda ($fd),y       /* this kluge is catered for later.. when the stack 
   sta $0100,x       /* should be stable again.
   dex
   dex               /* skip shifted address.. leaving it actively on the stack
   dex
   txs               /* reset stack pointer. stack should now be stable again
*  jsr $inc.(fd)     /* inc $fd ; beq skip ; inc $fe ; skip rts */
*  jsr $inc.(fd)     /* cater for iny above
   ldy #$00
   lda ($fd),y       /* get back local variables
   sta $var3
*  jsr $inc.(fd)
   lda ($fd),y
   sta $var2
*  jsr $inc.(fd)
   lda ($fd),y
   sta $var1
*  jsr $inc.(fd)
   cli               /* interrupts are allowed again
   rts


test routine

set (fd) = $8000   /* user stack.. grows down toward $7000
set var1 = 2       /* simple iteration counter
jsr recur
rts

recur
   jsr $push onto user stack
   dec var1 
   beq skip
   jsr recur
skip
   jsr $pop off user stack
   rts

ok.. the push works.. and keeps the correct values for var1 etc.. no
problems.. (and doesn't have any adverse effects on the stack.. although
its a bit difficult walking through the code in micromon.. it also tries to
use the stack.. and gets confused )

pop doesnt work... for some reason when it returns at the end (ie after cli)
it goes to the point which i have marked with '*'.. then to the next '*'
and so on until it gets to the last one in pop and once again.. gets
confused and goes off into no-mans land.

any suggestions please???