1
0
mirror of https://github.com/RevCurtisP/C02.git synced 2024-11-28 10:51:14 +00:00

Split module stack into stack and stackx

This commit is contained in:
Curtis F Kaylor 2018-09-23 18:39:27 -04:00
parent 172053262a
commit 9bee7114fd
8 changed files with 683 additions and 199 deletions

View File

@ -1,7 +1,7 @@
Sta Functions Sta Functions
This library contains functions to access and manipulate a stack. The This module contains functions to access and manipulate a stack structure.
entries on a stack are stored in contiguous bytes of memory. The entries on a stack are stored in contiguous bytes of memory.
Each element of the stack can vary in size from 1 to 255 bytes. Both Each element of the stack can vary in size from 1 to 255 bytes. Both
arrays and strings may be pushed onto and pulled off the stack. arrays and strings may be pushed onto and pulled off the stack.
@ -10,7 +10,6 @@ Usage: at the beginning of the program use the directives
#include <stddef.h02> #include <stddef.h02>
#include <memory.h02> #include <memory.h02>
#include <string.h02>
#include <stack.h02> #include <stack.h02>
The following application functions are defined: The following application functions are defined:
@ -53,21 +52,6 @@ The following application functions are defined:
prior to the copy, updates stkslo and stkshi, prior to the copy, updates stkslo and stkshi,
then calls the memcpy function. then calls the memcpy function.
r = stkstr(&s); Stack String: Creates a new entry at the end of
the stack consisting the characters in string
s, including the terminating ASCII null. This
ensures that when the entry is popped off the
stack, the destination string will be properly
terminated.
If the string is empty or the bew entry would
overflow the end of the stack space, no entry is
created and a value of 0 is returned. Otherwise,
the number of bytes in the new entry is returned.
Note: Calls the strlen function, then calls the
stkpsh function.
r = stkpop(&m); Stack Pop: Copies the bytes from the last entry of r = stkpop(&m); Stack Pop: Copies the bytes from the last entry of
the stack into array m and removes the entry from the stack into array m and removes the entry from
the stack. the stack.
@ -81,78 +65,59 @@ The following application functions are defined:
of the last entry, sets srclo and srchi to stklo of the last entry, sets srclo and srchi to stklo
and stkhi, then calls the memcpy function. and stkhi, then calls the memcpy function.
r = stktop(&m); Stack Top: Copies the bytes from the last entry of r,m,l = stksiz(); Stack Size: Calculates and returns the current size
the stack into array m and leaves the entry on the of the stack along with a flag indicating whether
stack. the stack is populated or empty.
The first byte returned will be 255 (True) if the
stack contains at least one entry, or 0 (False) if
the stack is empty. The second and third returned
bytes are the size of the stack as a sixteen bit
number, most-significant and least-significant byte,
respectively.
If the stack is empty, the value 0 is returned. Note: Subtracts the sixteen bit value contained in
Otherwise, the number of bytes in the entry is stkslo and stkhi from the value in stklo and stkhi.
returned.
Note: Calls stkpop, then restores stklo and stkhi The following utility functions are not normally used in applications:
to their prior values.
r = stkdup(); Stack Duplicate: Creates a new entry at the end of
the stack consisting of the bytes in the last entry
of the stack.
If the stack is empty or the new entry would
overflow the end of the stack space, no entry is
created and a value of 0 is returned. Otherwise,
the number of bytes in the new entry is returned.
Note: Sets dstlo and dsthi to the stklo and stkhi,
sets srclo and srchi to point to the beginning
of the last entry, updates stklo and stkhi, then
calls the memcpy function.
r = stkovr(); Stack Over: Creates a new entry at the end of
the stack consisting of the bytes in the second
to last entry of the stack.
If there are less than two entries in the stack
or the new entry would overflow the end of the
stack space, no entry is created and a value of
0 is returned. Otherwise, the number of bytes in
the new entry is returned.
Note: Sets dstlo and dsthi to the stklo and stkhi,
sets srclo and srchi to point to the beginning
of the second to last entry, updates stklo and
stkhi, then calls the memcpy function.
stkswp(n); Stack Swap: Moves the last entry in the stack to
the second to last position and the second to
last entry to the last position.
If there are less than two entries in the stack
or there is not enough room in the stack space
to make a copy of the second to last entry, the
entries are not swapped and a value of 0 is
returned. Otherwise, the number of bytes in the
new last entry is returned.
Note: Calls stkovr, creating a copy of the second
to last stack entry, restores stklo and stkhi to
their original values, then calls the memcpy twice.
*,m,l = stkptr(); Stack Pointer: Returns the address contained in *,m,l = stkptr(); Stack Pointer: Returns the address contained in
the stack pointer as the most significant byte the stack pointer as the most significant byte
and the least significant byte. and the least significant byte.
This is a utility function not normally used in Note: Reads variables stklo and stkhi.
application code.
Note: Gets variables stkslo and stkshi.
stkset(&d); Stack Set: Sets stack pointer to address d. stkset(&d); Stack Set: Sets stack pointer to address d.
This is a utility function not normally used in Note: Sets variables stklo and stshi.
application code.
Note: Sets variables stkslo and stkshi. stkadd(b); Stack Add: Increases the stack pointer by b.
Note: This library expects the following functions to be defined Note: Updates variables stklo and stshi.
stksub(b); Stack Subtract: Decreases the stack pointer by b.
Note: Updates variables stslo and stshi.
stkinc(b); Stack Increment: Increases the stack pointer by 1.
Note: Updates variables stklo and stshi.
stkdec(b); Stack Decrement: Secreases the stack pointer by 1.
Note: Updates variables stslo and stshi.
stkssp(); Save Stack Pointer: Copies contents of the stack
pointer to variables temp1 and temp2.
Note: Calls stkptr() then savrxy().
stkrsp(); Restore Stack Pointer: Copies contents of variables
temp1 and temp2 to the stack pointer.
Note: Calls resrxy() then stkset().
Note: This module expects the following functions to be defined
memcpl Copy memory (alternate entry point) memcpl Copy memory (alternate entry point)
ressrc Restore source pointer ressrc Restore source pointer
@ -160,7 +125,6 @@ Note: This library expects the following functions to be defined
savrxy Save X and Y registers savrxy Save X and Y registers
setdst Set destination pointer setdst Set destination pointer
setsrc Set source pointer and initialize index setsrc Set source pointer and initialize index
strlen Get string length
along with the zero page variable pairs along with the zero page variable pairs
@ -168,12 +132,11 @@ along with the zero page variable pairs
dstlo, dsthi Destination String Pointer dstlo, dsthi Destination String Pointer
stklo, stkhi stack Pointer stklo, stkhi stack Pointer
the static variable the static variables
stkslo, stkshi Stack Start Address stkslo, stkshi Stack Start Address
stkelo, stkehi Stack End Address stkelo, stkehi Stack End Address
as well as the transient variables and the transient variables
temp0, temp1 Temporary storage temp0, temp1, temp2 Temporary storage
temp2, temp3

125
doc/stackx.txt Normal file
View File

@ -0,0 +1,125 @@
Sta Functions
This module contains extended stack manipulation functions.
Usage: at the beginning of the program use the directives
#include <stddef.h02>
#include <memory.h02>
#include <string.h02>
#include <stack.h02>
#include <stackx.h02>
The following application functions are defined:
r = stkstr(&s); Stack String: Creates a new entry at the end of
the stack consisting the characters in string
s, including the terminating ASCII null. This
ensures that when the entry is popped off the
stack, the destination string will be properly
terminated.
If the string is empty or the bew entry would
overflow the end of the stack space, no entry is
created and a value of 0 is returned. Otherwise,
the number of bytes in the new entry is returned.
Note: Calls the strlen function, then calls the
stkpsh function.
r = stktop(&m); Stack Top: Copies the bytes from the last entry of
the stack into array m and leaves the entry on the
stack.
If the stack is empty, the value 0 is returned.
Otherwise, the number of bytes in the entry is
returned.
Note: Calls stkpop, then restores stklo and stkhi
to their prior values.
r = stkdup(); Stack Duplicate: Creates a new entry at the end of
the stack consisting of the bytes in the last entry
of the stack.
If the stack is empty or the new entry would
overflow the end of the stack space, no entry is
created and a value of 0 is returned. Otherwise,
the number of bytes in the new entry is returned.
Note: Sets dstlo and dsthi to the stklo and stkhi,
sets srclo and srchi to point to the beginning
of the last entry, updates stklo and stkhi, then
calls the memcpy function.
r = stkovr(); Stack Over: Creates a new entry at the end of
the stack consisting of the bytes in the second
to last entry of the stack.
If there are less than two entries in the stack
or the new entry would overflow the end of the
stack space, no entry is created and a value of
0 is returned. Otherwise, the number of bytes in
the new entry is returned.
Note: Sets dstlo and dsthi to the stklo and stkhi,
sets srclo and srchi to point to the beginning
of the second to last entry, updates stklo and
stkhi, then calls the memcpy function.
r = stkswp(); Stack Swap: Moves the last entry in the stack to
the second to last position and the second to
last entry to the last position.
If there are less than two entries in the stack
or there is not enough room in the stack space
to make a copy of the second to last entry, the
entries are not swapped and a value of 0 is
returned. Otherwise, the number of bytes in the
new last entry is returned.
Note: Calls stkovr, creating a copy of the second
to last stack entry, restores stklo and stkhi to
their original values, then calls the memcpy twice.
*,m,l = stkptr(); Stack Pointer: Returns the address contained in
the stack pointer as the most significant byte
and the least significant byte.
This is a utility function not normally used in
application code.
Note: Gets variables stkslo and stkshi.
stkset(&d); Stack Set: Sets stack pointer to address d.
This is a utility function not normally used in
application code.
Note: Sets variables stkslo and stkshi.
Note: This library expects the following functions to be defined
memcpl Copy memory (alternate entry point)
stkadd Add to stack pointer
stkdrn Stack drop (alternate entry point)
stkpsa Push entry onto stack (alternate entry point)
stkrsp Restore Stack Pointer
stkssp Save Stack Pointer
strlen Get string length
along with the zero page variable pairs
srclo, srchi Source String Pointer
dstlo, dsthi Destination String Pointer
stklo, stkhi stack Pointer
the static variables
stkslo, stkshi Stack Start Address
stkelo, stkehi Stack End Address
and the transient variables
temp0, temp1 Temporary storage
temp2, temp3

View File

@ -1,10 +1,10 @@
;C02 library stack.h02 assembly language subroutines ;C02 stack module assembly language subroutines
;Requires External Zero Page Variables ;Requires external zero page variables
;STKLO, STKHI, DSTLO, DSTHI, SRCLO, SRCHI ;STKLO, STKHI, DSTLO, DSTHI, SRCLO, SRCHI
;External Variables ;external variables
;STKSLO, STKSHI, STKELO, STKEHI, TEMP0, TEMP1, TEMP2, TEMP3 ;STKSLO, STKSHI, STKELO, STKEHI, TEMP0, TEMP1, TEMP2
;External Routines ;external routines
;MEMCPL, SETDST, SETSRC, STRLEN ;MEMCPL, SETDST, SETSRC
;Implementation Notes: ;Implementation Notes:
;Stack starts at STKSLO,STKSHI and builds upward tp STKELO, STKEHI ;Stack starts at STKSLO,STKSHI and builds upward tp STKELO, STKEHI
@ -91,16 +91,6 @@ STKSET: STX STKLO ;Store X in Stack Pointer LSB
STY STKHI ;Store Y in Stack Pointer MSB STY STKHI ;Store Y in Stack Pointer MSB
RTS ;Exit Routine RTS ;Exit Routine
;stkstr(n, &m) - Push String onto Stack
;Args: Y,X = Address of Source Array
STKSTR: JSR STRLEN ;Get Length of String
BEQ STKSTY ;If Length > 0
BMI STKSTY ; and < 128
INY ; Increment Length to
TYA ; include null terminator
STKSTY: LDY #0 ;Clear Y Index
BEQ STKPSA ;Execute STKPSH, skippping SETSRC
;stkpsh(n, &m) - Push n Bytes of m onto Stack ;stkpsh(n, &m) - Push n Bytes of m onto Stack
;Args: A = Number of Bytes to Append ;Args: A = Number of Bytes to Append
; Y,X = Address of Source Array ; Y,X = Address of Source Array
@ -168,11 +158,11 @@ STKINX: RTS
; C=0,Z=0 if Stack Pointer < Stack Start ; C=0,Z=0 if Stack Pointer < Stack Start
STKCMP: LDA STKHI ;Compare MSB STKCMP: LDA STKHI ;Compare MSB
CMP STKSHI CMP STKSHI
BCC STKCMX ;If Pointer<Start Return C=0, Z=1 BCC STKRTS ;If Pointer<Start Return C=0, Z=1
BNE STKCMX ;If Pointer>Start Return C=1. Z=0 BNE STKRTS ;If Pointer>Start Return C=1. Z=0
LDA STKLO ;If MSB Equal LDA STKLO ;If MSB Equal
CMP STKSLO ;Compare LSB CMP STKSLO ;Compare LSB
STKCMX: RTS STKRTS: RTS
;stkdec(n) - Decrement Stack Pointer ;stkdec(n) - Decrement Stack Pointer
;Sets: STKLO, STKHI = Stack Pointer Address ;Sets: STKLO, STKHI = Stack Pointer Address
@ -183,7 +173,27 @@ STKDEC: LDX STKLO ;If LSB
STKDEL: DEC STKLO ; Decrement LSB STKDEL: DEC STKLO ; Decrement LSB
STKDER: RTS STKDER: RTS
;stkdal() - Deallocate Stack Entry ;stksiz() - Get Stack Size in Bytes
;Uses: STKLO,STKHI = Stack Pointer
;Sets: STKSLO, STKSHI = Stack Start Address
;Returns: A = $FF if Stack Size is Non-Zero
; $00 if Stack is Empty
; Y,X = Stack Size (MSB, LSB)
STKSIZ: LDA STKLO ;Subtract
SEC ;Start Address LSB
SBC STKSLO ;from Pointer LSB
TAX ;and Copy to X
LDA STKHI ;Subtract Start MSB
SBC STKSHI ;from Pointer MSB
TAY ;and Copy to Y
BCC STKZRO ;Return FALSE if <=0
BNE STKTRU ;Return TRUE if MSB <> 0
TXA ;Else
BEQ STKRTS ;Return FALSE if LSB = 0
STKTRU: LDA #$FF ;Else Return TRUE
RTS
;stkdrp(&m) - Drop Top Entry from Stack
;Note: Aborts Calling Routine if Error ;Note: Aborts Calling Routine if Error
;Uses: STKSLO, STKSHI = Stack Start Address ;Uses: STKSLO, STKSHI = Stack Start Address
;Sets: TEMP1, TEMP2 = Original Stack Pointer ;Sets: TEMP1, TEMP2 = Original Stack Pointer
@ -192,8 +202,8 @@ STKDER: RTS
;Returns: A=Number of Bytes in Entry ;Returns: A=Number of Bytes in Entry
; 0=Error: Stack Underflow ; 0=Error: Stack Underflow
; Y=0 ; Y=0
STKDAL: JSR STKSSP ;Save Stack Pointer STKDRP: JSR STKSSP ;Save Stack Pointer
STKDAN: JSR STKCMP ;If Stack Pointer STKDRN: JSR STKCMP ;If Stack Pointer
BCC STKRPA ; <= Stack Start BCC STKRPA ; <= Stack Start
BEQ STKRPA ; Return 0 BEQ STKRPA ; Return 0
JSR STKDEC ;Decrement Stack Pointer JSR STKDEC ;Decrement Stack Pointer
@ -220,15 +230,6 @@ STKABT: PLA ;Drop Return Address from Stack
STKZRO: LDA #0 ;Set A to 0 STKZRO: LDA #0 ;Set A to 0
RTS RTS
;stkdrp(&m) - Drop Top Entry from Stack
;Uses: STKSLO, STKSHI = Stack Start Address
;Updates: STKLO, STKHI = Stack Pointer
;Affects: C,N,Z
;Returns: A = Number of Bytes in Dropped Entry
; 0 = Error: Stack Underflow
STKDRP JSR STKDAL ;Deallocate Stack Entry
RTS
;stkpop(&m) - Pop Top Entry off Stack ;stkpop(&m) - Pop Top Entry off Stack
;Args: Y,X = Address of Source Array ;Args: Y,X = Address of Source Array
;Uses: STKSLO, STKSHI = Stack Start Address ;Uses: STKSLO, STKSHI = Stack Start Address
@ -237,68 +238,7 @@ STKDRP JSR STKDAL ;Deallocate Stack Entry
;Returns: A,Y = Number of Bytes in Entry ;Returns: A,Y = Number of Bytes in Entry
; 0 = Error: Stack Underflow ; 0 = Error: Stack Underflow
STKPOP: JSR SETDST ;Set Destination Address STKPOP: JSR SETDST ;Set Destination Address
JSR STKDAL ;Deallocate Stack Entry JSR STKDRP ;Deallocate Stack Entry
STKPOS: JSR STKSRC ;Set Source Address to Stack Pointer STKPOS: JSR STKSRC ;Set Source Address to Stack Pointer
JMP MEMCPL ;Copy Bytes and Return JMP MEMCPL ;Copy Bytes and Return
;stktop(&m) - Copy Top Entry off Stack
;Args: Y,X = Address of Source Array
;Uses: STKSLO, STKSHI = Stack Start Address
;Affects: C,N,Z
;Returns: A,Y = Number of Bytes in Entry
; 0 = Error: Stack Underflow
STKTOP: JSR STKPOP ;Pop Top Entry Off Stack
BEQ STKDER ;If Underflow, Return 0
JMP STKRSP ;Else Restore Stack Pointer and Return
;stkdup(&m) - Duplicate Top Entry on Stack
;Uses: STKSLO, STKSHI = Stack Start Address
; STKELO, STKEHI = Stack End Address
;Updates: STKLO, STKHI = Stack Pointer
;Affects: C,N,Z
;Returns: A,Y = Number of Bytes in Entry
; 0 = Error: Stack Overflow or Underflow
STKDUP: JSR STKDAL ;Deallocate Top Entry
STKDUS: JSR STKSRC ;Set Source Pointer to Stack Pointer
JSR STKRSP ;Restore Stack Pointer
JMP STKSTY ;Push Top Entry onto Stack
;stkovr(&m) - Duplicate Second Entry on Stack
;Uses: STKSLO, STKSHI = Stack Start Address
; STKELO, STKEHI = Stack End Address
;Updates: STKLO, STKHI = Stack Pointer
;Affects: C,N,Z
;Returns: A,Y = Number of Bytes in Entry
; 0 = Error: Stack Overflow or Underflow
STKOVR: JSR STKDAL ;Deallocate Top Entry
JSR STKDAN ;Deallocate Second Entry
JMP STKDUS ;Restore Pointer and Duplicate
;stkswp() - Swap Top Entry with Entry Below it
;Uses: STKSLO, STKSHI = Stack Start Address
; STKELO, STKEHI = Stack End Address
;Affects: C,N,Z
;Returns: A,Y = Number of Bytes in Entry
; 0 = Error: Stack Overflow or Underflow
STKSWP: JSR STKOVR ;Duplicate Second Entry
BEQ STKDER ;Exit if Error
JSR STKDAN ;Deallocate Duplicate
STA TEMP3 ;Save Size of Duplicate
JSR STKSSP ;Save Pointer to Duplicate
JSR STKDAN ;Deallocate Top Entry
JSR STKSRC ;Set Source to Top Entry
STA DSTLO ;Save Top Entry Size
JSR STKDAN ;Deallocate Second Entry
LDA DSTLO ;Retrieve Top Entry Size
JSR STKSWC ;Copy Top Entry Down
JSR RESSRC ;Set Duplicate as Source
LDA TEMP3 ;Get Duplicate Length
STKSWC: STA TEMP0 ;Save Number of Bytes
JSR STKDST ;Set Destination to Stack Pointer
LDY #0 ;Clear Index Register
JSR MEMCPL ;Copy Bytes and Return
STA (DSTLO),Y ;Store Number of Bytes after Entry
SEC ;Add Number of Bytes plus 1
JSR STKADC ;to Stack Pointer
TYA ;Return Number of Bytes
RTS

View File

@ -1,11 +1,20 @@
/****************************************** /********************************************
* stack - Stack Memory Functions for C02 * * stack - Software Stack Functions for C02 *
******************************************/ ********************************************/
/* Add to Stack Pointer Address *
* Internal Utility Function *
* Args: b - Number of Bytes to Add */
void stkadd();
/* Set Stack Start Address * /* Set Stack Start Address *
* Args: &addr - Start Address */ * Args: &addr - Start Address */
void stkbgn(); void stkbgn();
/* Decrement Stack Pointer Address *
* Internal Utility Function */
void stkdec();
/* Drop Top Entry from Stack * /* Drop Top Entry from Stack *
* Returns: A=Number of bytes dropped * * Returns: A=Number of bytes dropped *
* 0 if none */ * 0 if none */
@ -15,19 +24,13 @@ char stkdrp();
* Returns: Y,X=Pointer Address */ * Returns: Y,X=Pointer Address */
void stkdst(); void stkdst();
/* Duplicate Top Stack Entry *
* Returns: A=Number of bytes retrieved *
* 0 if none or overflow */
char stkdup();
/* Set Stack End Address * /* Set Stack End Address *
* Args: &addr - End Address */ * Args: &addr - End Address */
void stkend(); void stkend();
/* Duplicate Entry Under Top of Stack * /* Increment Stack Pointer Address *
* Returns: A=Number of bytes retrieved * * Internal Utility Function */
* 0 if none or overflow */ void stkinc();
char stkovr();
/* Pop Top Stack Entry into Array * /* Pop Top Stack Entry into Array *
* Args: n - Number of bytes to write * * Args: n - Number of bytes to write *
@ -47,24 +50,30 @@ char stkpsh();
* Returns: Y,X=Pointer Address */ * Returns: Y,X=Pointer Address */
void stkptr(); void stkptr();
/* Restore Stack Pointer Address *
* Internal Utility Function */
void stkrsp();
/* Reset Stack Pointer to Stack Start * /* Reset Stack Pointer to Stack Start *
* Returns: Y,X=Pointer Address */ * Returns: Y,X=Pointer Address */
void stkrst(); void stkrst();
/* Set Stack Pointer Address * /* Set Stack Pointer Address *
* Internal Utility Function *
* Args: &addr - Pointer Address */ * Args: &addr - Pointer Address */
void stkset(); void stkset();
/* Push String onto Stack * /* Save Stack Pointer Address *
* Args: &m - String to push * * Internal Utility Function */
* Returns: A=$FF if bytes were written * void stkssp();
* $00 if block was overflowed */
char stkstr();
/* Copy Top Stack Entry into Array * /* Get Stack Size *
* Args: n - Number of bytes to write * * Returns: A=$FF if size greater than 0 *
* &m - Array to pop contents into * * $00 if stack is empty *
* Returns: A=Number of bytes retrieved * * Y,X=Stack size in bytes */
* 0 if none */ void stksiz();
char stktop();
/* Subtract from Stack Pointer Address *
* Internal Utility Function *
* Args: b - Number of Bytes to Subtract */
void stksub();

80
include/stackx.a02 Normal file
View File

@ -0,0 +1,80 @@
;C02 stack module assembly language subroutines
;Requires external zero page variables
;STKLO, STKHI, DSTLO, DSTHI, SRCLO, SRCHI
;external variables
;STKSLO, STKSHI, STKELO, STKEHI, TEMP0, TEMP1, TEMP2, TEMP3
;external routines
;MEMCPL, STKADD, STKDRN, STKPSA, STKRSP, STKSRC, STKSSP, STRLEN
;stkstr(n, &m) - Push String onto Stack
;Args: Y,X = Address of Source Array
STKSTR: JSR STRLEN ;Get Length of String
BEQ STKSTY ;If Length > 0
BMI STKSTY ; and < 128
INY ; Increment Length to
TYA ; include null terminator
STKSTY: LDY #0 ;Clear Y Index
JMP STKPSA ;Push Bytes onto Stack
;stktop(&m) - Copy Top Entry off Stack
;Args: Y,X = Address of Source Array
;Uses: STKSLO, STKSHI = Stack Start Address
;Affects: C,N,Z
;Returns: A,Y = Number of Bytes in Entry
; 0 = Error: Stack Underflow
STKTOP: JSR STKPOP ;Pop Top Entry Off Stack
BEQ STKSWR ;If Underflow, Return 0
JMP STKRSP ;Else Restore Stack Pointer and Return
;stkdup(&m) - Duplicate Top Entry on Stack
;Uses: STKSLO, STKSHI = Stack Start Address
; STKELO, STKEHI = Stack End Address
;Updates: STKLO, STKHI = Stack Pointer
;Affects: C,N,Z
;Returns: A,Y = Number of Bytes in Entry
; 0 = Error: Stack Overflow or Underflow
STKDUP: JSR STKDRP ;Deallocate Top Entry
STKDUS: JSR STKSRC ;Set Source Pointer to Stack Pointer
JSR STKRSP ;Restore Stack Pointer
JMP STKSTY ;Push Top Entry onto Stack
;stkovr(&m) - Duplicate Second Entry on Stack
;Uses: STKSLO, STKSHI = Stack Start Address
; STKELO, STKEHI = Stack End Address
;Updates: STKLO, STKHI = Stack Pointer
;Affects: C,N,Z
;Returns: A,Y = Number of Bytes in Entry
; 0 = Error: Stack Overflow or Underflow
STKOVR: JSR STKDRP ;Deallocate Top Entry
JSR STKDRN ;Deallocate Second Entry
JMP STKDUS ;Restore Pointer and Duplicate
;stkswp() - Swap Top Entry with Entry Below it
;Uses: STKSLO, STKSHI = Stack Start Address
; STKELO, STKEHI = Stack End Address
;Destroys: DSTLO,TEMP0,TEMP0,TEMP1,TEMP2,TEMP3
;Affects: C,N,Z
;Returns: A,Y = Number of Bytes in Entry
; 0 = Error: Stack Overflow or Underflow
STKSWP: JSR STKOVR ;Duplicate Second Entry
BEQ STKSWR ;Exit if Error
JSR STKDRN ;Deallocate Duplicate
STA TEMP3 ;Save Size of Duplicate
JSR STKSSP ;Save Pointer to Duplicate
JSR STKDRN ;Deallocate Top Entry
JSR STKSRC ;Set Source to Top Entry
STA DSTLO ;Save Top Entry Size
JSR STKDRN ;Deallocate Second Entry
LDA DSTLO ;Retrieve Top Entry Size
JSR STKSWC ;Copy Top Entry Down
JSR RESSRC ;Set Duplicate as Source
LDA TEMP3 ;Get Duplicate Length
STKSWC: STA TEMP0 ;Save Number of Bytes
JSR STKDST ;Set Destination to Stack Pointer
LDY #0 ;Clear Index Register
JSR MEMCPL ;Copy Bytes and Return
STA (DSTLO),Y ;Store Number of Bytes after Entry
SEC ;Add Number of Bytes plus 1
JSR STKADC ;to Stack Pointer
TYA ;Return Number of Bytes
STKSWR: RTS

31
include/stackx.h02 Normal file
View File

@ -0,0 +1,31 @@
/*********************************************
* stackx - Extended Stack Functions for C02 *
*********************************************/
/* Duplicate Top Stack Entry *
* Returns: A=Number of bytes retrieved *
* 0 if none or overflow */
char stkdup();
/* Duplicate Entry Under Top of Stack *
* Returns: A=Number of bytes retrieved *
* 0 if none or overflow */
char stkovr();
/* Push String onto Stack *
* Args: &m - String to push *
* Returns: A=$FF if bytes were written *
* $00 if block was overflowed */
char stkstr();
/* Swap Top and Second Stack Entries *
* Returns: A=Number of bytes in new top *
* 0 if none or overflow */
char stkswp();
/* Copy Top Stack Entry into Array *
* Args: n - Number of bytes to write *
* &m - Array to pop contents into *
* Returns: A=Number of bytes retrieved *
* 0 if none */
char stktop();

209
test/teststk.c02 Normal file
View File

@ -0,0 +1,209 @@
/***********************************************
* TESTSTK - Test Stack Manipulation Functions *
* Assumes free RAM from $7FFF to $807E *
***********************************************/
//use -h option on command line when compiling
#include <stddef.h02>
#include <stdlib.h02>
#include <stdio.h02>
#include <stdiox.h02>
#include <string.h02>
#include <memory.h02>
#include <stack.h02>
char c,f,g,i;
char aa,xx,yy;
char zz,lo,hi;
const char r={6,7,8,9};
const char s="Test String";
char t[255];
main:
for (i=0;i<$20;i++) srclo[i]=0; //Initialize Pointers
puts("Setting Stack Start Address\t");
puts("stkbgn($7FFF)\t");
stkbgn(&$7FFF); lo=stkslo; hi=stkshi;
setdst("stks"); cklohi(&$7FFF);
puts("Setting Stack End Address\t");
puts("stkend($807E)\t");
stkend(&$807E); lo=stkelo; hi=stkehi;
setdst("stke"); cklohi(&$807E);
puts("Setting Stack Pointer Address\t");
puts("stkset($7765)\t");
stkset(&$7765); lo=stklo; hi=stkhi;
setdst("stk"); cklohi(0,&$7765);
chksiz(#FALSE, &$F766);
puts("Resetting Stack Pointer\t\t");
puts("stkrst()\t");
stkrst(); lo=stklo; hi=stkhi;
setdst("stk"); cklohi(0,&$7FFF);
chksiz(#FALSE, &0);
puts("Getting Stack Pointer Address\t");
puts("stkptr()\t");
aa, hi, lo = stkptr();
setdst(""); cklohi(0,&$7FFF);
puts("Setting Source to Stack Pointer\t");
puts("stksrc()\t");
stksrc(); lo=srclo; hi=srchi;
setdst("src"); cklohi(0,&$7FFF);
puts("Setting Dest. to Stack Pointer\t");
puts("stkdst()\t");
stkdst(); lo=dstlo; hi=dsthi;
setdst("src"); cklohi(0,&$7FFF);
puts("Incrementing Stack Pointer\t");
puts("stkinc()\t");
stkinc(); lo=stklo; hi=stkhi;
setdst("stk"); cklohi(0,&$8000);
chksiz(#TRUE, &1);
puts("Decrementing Stack Pointer\t");
puts("stkdec()\t");
stkdec(); lo=stklo; hi=stkhi;
setdst("stk"); cklohi(0,&$7FFF);
chksiz(#FALSE, &0);
c = anykey(); if (c == #esckey) goto exit;
puts("Pushing Array onto Stack\t");
puts("stkpsh(@r,$r)\t");
aa,hi,lo=stkptr(); //Save Stack Pointer
f=stkpsh(@r,&r); printf(f,"bytes=%d:");
setdst(*,hi,lo); g=(memcmp(@r, &r)==0) ? #TRUE : #FALSE;
psorfl(f & g); chksiz(#TRUE, &5); chkptr(&$8004);
puts("Duplicating Top of Stack\t");
puts("stkdup()\t");
aa,hi,lo=stkptr(); //Save Stack Pointer
f=stkdup(); printf(f,"bytes=%d:");
setdst(*,hi,lo); g=(memcmp(@r, &r)==0) ? #TRUE : #FALSE;
psorfl(f & g); chksiz(#TRUE, &10); chkptr(&$8009);
puts("Pushing String onto Stack\t");
puts("stkstr(&s)\t");
aa,hi,lo=stkptr(); //Save Stack Pointer
f=stkstr(&s); printf(f,"bytes=%d:");
setdst(*,hi,lo); g=(strcmp(&s)==0) ? #TRUE : #FALSE;
psorfl(f & g); chksiz(#TRUE, &23); chkptr(&$8016);
puts("Duplicating Second Stack Entry\t");
puts("stkovr()\t");
aa,hi,lo=stkptr(); //Save Stack Pointer
f=stkovr(); printf(f,"bytes=%d:");
setdst(*,hi,lo); g=(memcmp(@r, &r)==0) ? #TRUE : #FALSE;
psorfl(f & g); chksiz(#TRUE, &28); chkptr(&$801B);
c = anykey(); if (c == #esckey) goto exit;
puts("Dropping Duplicate off Stack\t");
puts("stkdrp()\t");
f=stkdrp(); printf(f,"bytes=%d:");
g=(f==4) ? #TRUE : #FALSE;
psorfl(f & g); chksiz(#TRUE, &23); chkptr(&$8016);
puts("Copying String from Stack\t");
puts("stktop(&t)\t");
f=stktop(&t); setdst(&t); printf("\"%s\":");
g=(strcmp(&s)==0) ? #TRUE : #FALSE;
psorfl(f & g);
chkptr(&$8016);
puts("Popping String off Stack\t");
puts("stkpop(&t)\t");
f=stkpop(&t); setdst(&t); printf("\"%s\":");
g=(strcmp(&s)==0) ? #TRUE : #FALSE;
psorfl(f & g);
chkptr(&$8009);
puts("Dropping Duplicate off Stack\t");
puts("stkdrp()\t");
f=stkdrp(); printf(f,"bytes=%d:");
g=(f==4) ? #TRUE : #FALSE;
psorfl(f & g);
chkptr(&$8004);
puts("Popping Array off Stack\t\t");
puts("stkpop(&t)\t");
f=stkpop(&t); prtary(f); puts(": ");
g=(memcmp(f,&r)==0) ? #TRUE : #FALSE;
psorfl(f & g);
chkptr(&$7FFF);
puts("Popping off Empty Stack\t\t");
puts("stkpop(&t)\t");
f=stkpop(&t); printf(f,"bytes=%d:");
if (f) fail(); else pass();
chkptr(&$7FFF);
puts("Overflowing Stack\t\t");
puts("stkpsh(255,&t)\t");
f=stkpsh(255,&t); printf(f,"bytes=%d:");
if (f) fail(); else pass();
chkptr(&$7FFF);
putln("Tests Complete");
goto exit;
void chkptr(aa,yy,xx) {
puts("\tChecking Stack Pointer\t\t\t");
puts("address=$"); prbyte(stkhi); prbyte(stklo); putc(':');
xx = (stklo == xx) ? #TRUE : #FALSE;
yy = (stkhi == yy) ? #TRUE : #FALSE;
psorfl(xx & yy);
}
void prtary(aa) {
putc('{');
for (i=0;i<aa;i++) {
if (i) putc(',');
putdec(t[i]);
}
putc('}');
}
void cklohi(aa,yy,xx) {
putdst(); puts("lo=$"); prbyte(lo); putc(' ');
putdst(); puts("hi=$"); prbyte(hi); putc(':');
xx = (lo == xx) ? #TRUE : #FALSE;
yy = (hi == yy) ? #TRUE : #FALSE;
psorfl(xx & yy);
}
void chksiz(aa,yy,xx) {
puts("\tChecking Stack Size\t");
puts("stksiz()\t");
zz, dsthi, dstlo = stksiz();
printf(zz, "Sts=$%h Size=$%w:");
if (zz == aa and dsthi == yy and dstlo == xx ) pass();
else {fail(); goto exit;}
}
void psorfl(aa) {if (aa) pass(); else {fail(); goto exit;}}
void pass() {putln(" Pass");}
void fail() {putln(" Fail");}
puts("Swapping Top and Second Entry\t");
puts("stkswp()\t");
f=stkswp(); printf(f,"bytes=%d:");
g=(f==12) ? #TRUE : #FALSE;
psorfl(f & g);
chkptr(&$801B);
puts("Dropping Swapped Entry off Stack\t");
puts("stkdrp()\t");
f=stkdrp(); printf(f,"bytes=%d:");
g=(f==4) ? #TRUE : #FALSE;
psorfl(f & g);
chkptr(&$8016);

127
test/teststkx.c02 Normal file
View File

@ -0,0 +1,127 @@
/********************************************
* TESTSTKX - Test Extended Stack Functions *
* Assumes free RAM from $7FFF to $807E *
********************************************/
//use -h option on command line when compiling
#include <stddef.h02>
#include <stdlib.h02>
#include <stdio.h02>
#include <stdiox.h02>
#include <string.h02>
#include <memory.h02>
#include <stack.h02>
#include <stackx.h02>
char c,f,g,i;
char aa,xx,yy;
char zz,lo,hi;
const char r={6,7,8,9};
const char s="Test String";
char t[255];
main:
for (i=0;i<$20;i++) srclo[i]=0; //Initialize Pointers
puts("Setting Stack Start Address\t");
puts("stkbgn($7FFF)\t");
stkbgn(&$7FFF); lo=stkslo; hi=stkshi;
setdst("stks"); cklohi(&$7FFF);
puts("Setting Stack End Address\t");
puts("stkend($807E)\t");
stkend(&$807E); lo=stkelo; hi=stkehi;
setdst("stke"); cklohi(&$807E);
puts("Resetting Stack Pointer\t\t");
puts("stkrst()\t");
stkrst(); lo=stklo; hi=stkhi;
setdst("stk"); cklohi(0,&$7FFF);
chksiz(#FALSE, &0);
puts("Pushing Array onto Stack\t");
puts("stkpsh(@r,$r)\t");
aa,hi,lo=stkptr(); //Save Stack Pointer
f=stkpsh(@r,&r); printf(f,"bytes=%d:");
setdst(*,hi,lo); g=(memcmp(@r, &r)==0) ? #TRUE : #FALSE;
psorfl(f & g); chksiz(#TRUE, &5); chkptr(&$8004);
puts("Pushing String onto Stack\t");
puts("stkstr(&s)\t");
aa,hi,lo=stkptr(); //Save Stack Pointer
f=stkstr(&s); printf(f,"bytes=%d:");
setdst(*,hi,lo); g=(strcmp(&s)==0) ? #TRUE : #FALSE;
psorfl(f & g); chksiz(#TRUE, &18); chkptr(&$8011);
puts("Swapping Top and Second Entry\t");
puts("stkswp()\t");
f=stkswp(); printf(f,"bytes=%d:");
g=(f==4) ? #TRUE : #FALSE;
psorfl(f & g); chksiz(#TRUE, &18); chkptr(&$8011);
puts("Popping Array off Stack\t\t");
puts("stkpop(&t)\t");
f=stkpop(&t); prtary(f); puts(": ");
g=(memcmp(f,&r)==0) ? #TRUE : #FALSE;
psorfl(f & g); chksiz(#TRUE, &13); chkptr(&$800C);
puts("Popping String off Stack\t");
puts("stkpop(&t)\t");
f=stkpop(&t); setdst(&t); printf("\"%s\":");
g=(strcmp(&s)==0) ? #TRUE : #FALSE;
psorfl(f & g); chksiz(#FALSE, &0); chkptr(&$7FFF);
putln("Tests Complete");
goto exit;
if (anykey() == #esckey) goto exit;
void chkptr(aa,yy,xx) {
puts("\tChecking Stack Pointer\t\t\t");
puts("address=$"); prbyte(stkhi); prbyte(stklo); putc(':');
xx = (stklo == xx) ? #TRUE : #FALSE;
yy = (stkhi == yy) ? #TRUE : #FALSE;
psorfl(xx & yy);
}
void prtary(aa) {
putc('{');
for (i=0;i<aa;i++) {
if (i) putc(',');
putdec(t[i]);
}
putc('}');
}
void cklohi(aa,yy,xx) {
putdst(); puts("lo=$"); prbyte(lo); putc(' ');
putdst(); puts("hi=$"); prbyte(hi); putc(':');
xx = (lo == xx) ? #TRUE : #FALSE;
yy = (hi == yy) ? #TRUE : #FALSE;
psorfl(xx & yy);
}
void chksiz(aa,yy,xx) {
puts("\tChecking Stack Size\t");
puts("stksiz()\t");
zz, dsthi, dstlo = stksiz();
printf(zz, "Sts=$%h Size=$%w:");
if (zz == aa and dsthi == yy and dstlo == xx ) pass();
else {fail(); goto exit;}
}
void psorfl(aa) {if (aa) pass(); else {fail(); goto exit;}}
void pass() {putln(" Pass");}
void fail() {putln(" Fail");}
puts("Dropping Swapped Entry off Stack\t");
puts("stkdrp()\t");
f=stkdrp(); printf(f,"bytes=%d:");
g=(f==4) ? #TRUE : #FALSE;
psorfl(f & g);
chkptr(&$8016);