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:
parent
172053262a
commit
9bee7114fd
129
doc/stack.txt
129
doc/stack.txt
@ -1,7 +1,7 @@
|
||||
Sta Functions
|
||||
|
||||
This library contains functions to access and manipulate a stack. The
|
||||
entries on a stack are stored in contiguous bytes of memory.
|
||||
This module contains functions to access and manipulate a stack structure.
|
||||
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
|
||||
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 <memory.h02>
|
||||
#include <string.h02>
|
||||
#include <stack.h02>
|
||||
|
||||
The following application functions are defined:
|
||||
@ -53,21 +52,6 @@ The following application functions are defined:
|
||||
prior to the copy, updates stkslo and stkshi,
|
||||
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
|
||||
the stack into array m and removes the entry from
|
||||
the stack.
|
||||
@ -81,78 +65,59 @@ The following application functions are defined:
|
||||
of the last entry, sets srclo and srchi to stklo
|
||||
and stkhi, then calls the memcpy 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.
|
||||
r,m,l = stksiz(); Stack Size: Calculates and returns the current size
|
||||
of the stack along with a flag indicating whether
|
||||
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.
|
||||
Otherwise, the number of bytes in the entry is
|
||||
returned.
|
||||
Note: Subtracts the sixteen bit value contained in
|
||||
stkslo and stkhi from the value in stklo and stkhi.
|
||||
|
||||
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.
|
||||
|
||||
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.
|
||||
The following utility functions are not normally used in applications:
|
||||
|
||||
*,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.
|
||||
Note: Reads variables stklo and stkhi.
|
||||
|
||||
stkset(&d); Stack Set: Sets stack pointer to address d.
|
||||
|
||||
This is a utility function not normally used in
|
||||
application code.
|
||||
Note: Sets variables stklo and stshi.
|
||||
|
||||
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)
|
||||
ressrc Restore source pointer
|
||||
@ -160,7 +125,6 @@ Note: This library expects the following functions to be defined
|
||||
savrxy Save X and Y registers
|
||||
setdst Set destination pointer
|
||||
setsrc Set source pointer and initialize index
|
||||
strlen Get string length
|
||||
|
||||
along with the zero page variable pairs
|
||||
|
||||
@ -168,12 +132,11 @@ along with the zero page variable pairs
|
||||
dstlo, dsthi Destination String Pointer
|
||||
stklo, stkhi stack Pointer
|
||||
|
||||
the static variable
|
||||
the static variables
|
||||
|
||||
stkslo, stkshi Stack Start Address
|
||||
stkelo, stkehi Stack End Address
|
||||
|
||||
as well as the transient variables
|
||||
and the transient variables
|
||||
|
||||
temp0, temp1 Temporary storage
|
||||
temp2, temp3
|
||||
temp0, temp1, temp2 Temporary storage
|
||||
|
125
doc/stackx.txt
Normal file
125
doc/stackx.txt
Normal 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
|
@ -1,10 +1,10 @@
|
||||
;C02 library stack.h02 assembly language subroutines
|
||||
;Requires External Zero Page Variables
|
||||
;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, SETDST, SETSRC, STRLEN
|
||||
;external variables
|
||||
;STKSLO, STKSHI, STKELO, STKEHI, TEMP0, TEMP1, TEMP2
|
||||
;external routines
|
||||
;MEMCPL, SETDST, SETSRC
|
||||
|
||||
;Implementation Notes:
|
||||
;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
|
||||
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
|
||||
;Args: A = Number of Bytes to Append
|
||||
; Y,X = Address of Source Array
|
||||
@ -168,11 +158,11 @@ STKINX: RTS
|
||||
; C=0,Z=0 if Stack Pointer < Stack Start
|
||||
STKCMP: LDA STKHI ;Compare MSB
|
||||
CMP STKSHI
|
||||
BCC STKCMX ;If Pointer<Start Return C=0, Z=1
|
||||
BNE STKCMX ;If Pointer>Start Return C=1. Z=0
|
||||
BCC STKRTS ;If Pointer<Start Return C=0, Z=1
|
||||
BNE STKRTS ;If Pointer>Start Return C=1. Z=0
|
||||
LDA STKLO ;If MSB Equal
|
||||
CMP STKSLO ;Compare LSB
|
||||
STKCMX: RTS
|
||||
STKRTS: RTS
|
||||
|
||||
;stkdec(n) - Decrement Stack Pointer
|
||||
;Sets: STKLO, STKHI = Stack Pointer Address
|
||||
@ -183,7 +173,27 @@ STKDEC: LDX STKLO ;If LSB
|
||||
STKDEL: DEC STKLO ; Decrement LSB
|
||||
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
|
||||
;Uses: STKSLO, STKSHI = Stack Start Address
|
||||
;Sets: TEMP1, TEMP2 = Original Stack Pointer
|
||||
@ -192,8 +202,8 @@ STKDER: RTS
|
||||
;Returns: A=Number of Bytes in Entry
|
||||
; 0=Error: Stack Underflow
|
||||
; Y=0
|
||||
STKDAL: JSR STKSSP ;Save Stack Pointer
|
||||
STKDAN: JSR STKCMP ;If Stack Pointer
|
||||
STKDRP: JSR STKSSP ;Save Stack Pointer
|
||||
STKDRN: JSR STKCMP ;If Stack Pointer
|
||||
BCC STKRPA ; <= Stack Start
|
||||
BEQ STKRPA ; Return 0
|
||||
JSR STKDEC ;Decrement Stack Pointer
|
||||
@ -220,15 +230,6 @@ STKABT: PLA ;Drop Return Address from Stack
|
||||
STKZRO: LDA #0 ;Set A to 0
|
||||
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
|
||||
;Args: Y,X = Address of Source Array
|
||||
;Uses: STKSLO, STKSHI = Stack Start Address
|
||||
@ -237,68 +238,7 @@ STKDRP JSR STKDAL ;Deallocate Stack Entry
|
||||
;Returns: A,Y = Number of Bytes in Entry
|
||||
; 0 = Error: Stack Underflow
|
||||
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
|
||||
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
|
||||
|
@ -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 *
|
||||
* Args: &addr - Start Address */
|
||||
void stkbgn();
|
||||
|
||||
/* Decrement Stack Pointer Address *
|
||||
* Internal Utility Function */
|
||||
void stkdec();
|
||||
|
||||
/* Drop Top Entry from Stack *
|
||||
* Returns: A=Number of bytes dropped *
|
||||
* 0 if none */
|
||||
@ -15,19 +24,13 @@ char stkdrp();
|
||||
* Returns: Y,X=Pointer Address */
|
||||
void stkdst();
|
||||
|
||||
/* Duplicate Top Stack Entry *
|
||||
* Returns: A=Number of bytes retrieved *
|
||||
* 0 if none or overflow */
|
||||
char stkdup();
|
||||
|
||||
/* Set Stack End Address *
|
||||
* Args: &addr - End Address */
|
||||
void stkend();
|
||||
|
||||
/* Duplicate Entry Under Top of Stack *
|
||||
* Returns: A=Number of bytes retrieved *
|
||||
* 0 if none or overflow */
|
||||
char stkovr();
|
||||
/* Increment Stack Pointer Address *
|
||||
* Internal Utility Function */
|
||||
void stkinc();
|
||||
|
||||
/* Pop Top Stack Entry into Array *
|
||||
* Args: n - Number of bytes to write *
|
||||
@ -47,24 +50,30 @@ char stkpsh();
|
||||
* Returns: Y,X=Pointer Address */
|
||||
void stkptr();
|
||||
|
||||
/* Restore Stack Pointer Address *
|
||||
* Internal Utility Function */
|
||||
void stkrsp();
|
||||
|
||||
/* Reset Stack Pointer to Stack Start *
|
||||
* Returns: Y,X=Pointer Address */
|
||||
void stkrst();
|
||||
|
||||
/* Set Stack Pointer Address *
|
||||
* Internal Utility Function *
|
||||
* Args: &addr - Pointer Address */
|
||||
void stkset();
|
||||
|
||||
/* Push String onto Stack *
|
||||
* Args: &m - String to push *
|
||||
* Returns: A=$FF if bytes were written *
|
||||
* $00 if block was overflowed */
|
||||
char stkstr();
|
||||
/* Save Stack Pointer Address *
|
||||
* Internal Utility Function */
|
||||
void stkssp();
|
||||
|
||||
/* 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();
|
||||
/* Get Stack Size *
|
||||
* Returns: A=$FF if size greater than 0 *
|
||||
* $00 if stack is empty *
|
||||
* Y,X=Stack size in bytes */
|
||||
void stksiz();
|
||||
|
||||
/* Subtract from Stack Pointer Address *
|
||||
* Internal Utility Function *
|
||||
* Args: b - Number of Bytes to Subtract */
|
||||
void stksub();
|
||||
|
80
include/stackx.a02
Normal file
80
include/stackx.a02
Normal 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
31
include/stackx.h02
Normal 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
209
test/teststk.c02
Normal 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
127
test/teststkx.c02
Normal 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);
|
||||
|
Loading…
Reference in New Issue
Block a user