mirror of
https://github.com/RevCurtisP/C02.git
synced 2025-02-19 19:31:04 +00:00
Combined stack and stackx modules, updated documentation and test program
This commit is contained in:
parent
85b04dff00
commit
414d673db5
235
doc/stack.txt
235
doc/stack.txt
@ -1,141 +1,172 @@
|
|||||||
Sta Functions
|
Sta Functions
|
||||||
|
|
||||||
This module contains functions to access and manipulate a stack structure.
|
This module contains functions to access and manipulate a stack
|
||||||
The entries on a stack are stored in contiguous bytes of memory.
|
of multi-byte entries stored in a contiguous section of memory.
|
||||||
|
|
||||||
Each element of the stack can vary in size from 1 to 255 bytes. Both
|
Each entry of the stack consists of 1 to 255 bytes of data
|
||||||
arrays and strings may be pushed onto and pulled off the stack.
|
followed by a single byte containing the number of data bytes,
|
||||||
|
allowing entries to be of different sizes. Entries may be
|
||||||
|
arrays, strings, or structs.
|
||||||
|
|
||||||
Usage: at the beginning of the program use the directives
|
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 variables are defined:
|
||||||
|
|
||||||
|
int stkbgn Stack Begin: Address of the start of the stack.
|
||||||
|
|
||||||
|
int stkend Stack End: Address of the end of the stack.
|
||||||
|
|
||||||
|
zeropage int stkptr Stack Pointer: Current position in the stack.
|
||||||
|
|
||||||
|
The variables stkbgn and stkend must be set
|
||||||
|
before calling any functions. A program can
|
||||||
|
use multiple stacks by saving and restoring
|
||||||
|
stkbgn, stkend, and stkptr.
|
||||||
|
|
||||||
The following application functions are defined:
|
The following application functions are defined:
|
||||||
|
|
||||||
stkbgn(&b); Stack Begin: Sets the beginning of the stack
|
|
||||||
to address b.
|
|
||||||
|
|
||||||
The beginning of a stack is the first byte
|
|
||||||
of memory in the stack space.
|
|
||||||
|
|
||||||
Although stack space usually begins on a 256
|
|
||||||
byte boundary, this is not required.
|
|
||||||
|
|
||||||
Note: Sets variables stkslo and stkshi.
|
|
||||||
|
|
||||||
stkend(&e); Stack End: Sets the end of the stack to address
|
|
||||||
e. The end of a stack is the byte after the last
|
|
||||||
byte of memory in the stack space.
|
|
||||||
|
|
||||||
Although stack space usually ends on a 256
|
|
||||||
byte boundary, this is not required.
|
|
||||||
|
|
||||||
Note: Sets variables stkelo and steshi.
|
|
||||||
|
|
||||||
stkrst(); Stack Reset: Set stack pointer to stack begin
|
stkrst(); Stack Reset: Set stack pointer to stack begin
|
||||||
address.
|
address.
|
||||||
|
|
||||||
This routine is called before populating a
|
The first time s stack is used, this routine
|
||||||
stack with calls to the stkpsh function.
|
must be called after setting the variables
|
||||||
|
stkbgn and stkend and before calling any other
|
||||||
|
stack functions.
|
||||||
|
|
||||||
r = stkpsh(n ,&m); Stack Push: Creates a new entry at the end of
|
This routine can also be called to deallocate
|
||||||
the stack consisting of n bytes of array m.
|
all entries, effectively clearing the stack.
|
||||||
|
|
||||||
If n is 0 or the new entry would overflow the
|
Note: Sets stkptr to stkbgn.
|
||||||
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 stkslo and stkhi
|
r,i = stksiz(); Stack Size: Calculates and returns the current size
|
||||||
prior to the copy, updates stkslo and stkshi,
|
|
||||||
then calls the memcpy 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.
|
|
||||||
|
|
||||||
If the stack is empty, the value 0 is returned.
|
|
||||||
Otherwise, the number of bytes in the popped entry
|
|
||||||
is returned.
|
|
||||||
|
|
||||||
Note: Sets dstlo and dsthi to the address of m,
|
|
||||||
updates stklo and stkhi to point to the beginning
|
|
||||||
of the last entry, sets srclo and srchi to stklo
|
|
||||||
and stkhi, then calls the memcpy function.
|
|
||||||
|
|
||||||
r,m,l = stksiz(); Stack Size: Calculates and returns the current size
|
|
||||||
of the stack along with a flag indicating whether
|
of the stack along with a flag indicating whether
|
||||||
the stack is populated or empty.
|
the stack is populated or empty.
|
||||||
|
|
||||||
The first byte returned will be 255 (True) if the
|
Returns a char, which will be 255 (True) if the
|
||||||
stack contains at least one entry, or 0 (False) if
|
stack contains at least one entry, or 0 (False) if
|
||||||
the stack is empty. The second and third returned
|
the stack is empty, and int which is the size of
|
||||||
bytes are the size of the stack as a sixteen bit
|
the stack.
|
||||||
number, most-significant and least-significant byte,
|
|
||||||
respectively.
|
|
||||||
|
|
||||||
Note: Subtracts the sixteen bit value contained in
|
Note: Subtracts stkbgn from stkptr.
|
||||||
stkslo and stkhi from the value in stklo and stkhi.
|
|
||||||
|
r = stkpsh(n,m); Stack Push: Creates a new entry at the end of
|
||||||
|
the stack consisting of n bytes of array m.
|
||||||
|
|
||||||
|
Returns zero if n is 0 or an overflow would
|
||||||
|
occur. Otherwise, returns the the size of the
|
||||||
|
new entry.
|
||||||
|
|
||||||
|
Note: Sets srcptr to &m, dstptr to stkptr,
|
||||||
|
updates stkptr, then calls memcpy().
|
||||||
|
|
||||||
|
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.
|
||||||
|
|
||||||
|
Returns zero if s is empty or an overflow would
|
||||||
|
occur. Otherwise, returns the the size of the
|
||||||
|
new entry.
|
||||||
|
|
||||||
|
Note: Calls strlen(), then calls stkpsh().
|
||||||
|
|
||||||
|
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.
|
||||||
|
|
||||||
|
Returns zero if the stack is empty or an overflow
|
||||||
|
would occur. Otherwise, returns the the size of
|
||||||
|
the new entry.
|
||||||
|
|
||||||
|
Note: Sets dstptr to stkptr, sets srcptr to the
|
||||||
|
beginning of the last entry, updates stkptr,
|
||||||
|
then calls memcpy().
|
||||||
|
|
||||||
|
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.
|
||||||
|
|
||||||
|
Returns zero if the stack has less than two
|
||||||
|
entries or an overflow would occur. Otherwise,
|
||||||
|
returns the the size of the new entry.
|
||||||
|
|
||||||
|
Note: Sets dstptr to the stkptr and srcptr to
|
||||||
|
the beginning of the second to last entry,
|
||||||
|
updates stkptr then calls the memcpy().
|
||||||
|
|
||||||
|
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.
|
||||||
|
|
||||||
|
Returns zero if the stack has less than two
|
||||||
|
entries or an overflow would occur. Otherwise,
|
||||||
|
returns the the size of the new last entry.
|
||||||
|
|
||||||
|
Note: Saves stkptr, calls stkovr(), restores
|
||||||
|
stkptr, then calls memcpy() twice.
|
||||||
|
|
||||||
|
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.
|
||||||
|
|
||||||
|
Returns zero if the stack is empty. Otherwise,
|
||||||
|
returns the the size of the new entry.
|
||||||
|
|
||||||
|
Note: Saves stkptr, calls stkpop(), then restores
|
||||||
|
stkptr.
|
||||||
|
|
||||||
|
r = stkpop(m); Stack Pop: Copies the bytes from the last entry
|
||||||
|
of the stack into array m and deallocates the
|
||||||
|
entry from the stack.
|
||||||
|
|
||||||
|
If the stack is empty, the value 0 is returned.
|
||||||
|
Otherwise, the number of bytes in the popped
|
||||||
|
entry is returned.
|
||||||
|
|
||||||
|
Note: Sets dstptr to &m, sets stkptr to the
|
||||||
|
beginning of the last entry, sets srcptr to
|
||||||
|
stkptr, then calls the memcpy().
|
||||||
|
|
||||||
|
r = stkdrp(); Stack Drop: Deallocates the last entry from the
|
||||||
|
stack.
|
||||||
|
|
||||||
|
If the stack is empty, the value 0 is returned.
|
||||||
|
Otherwise, the number of bytes in the dropped
|
||||||
|
entry is returned.
|
||||||
|
|
||||||
|
Note: Sets dstptr to &m, sets stkptr to the
|
||||||
|
beginning of the last entry, sets srcptr to
|
||||||
|
stkptr, then calls the memcpy().
|
||||||
|
|
||||||
The following utility functions are not normally used in applications:
|
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.
|
|
||||||
|
|
||||||
Note: Reads variables stklo and stkhi.
|
|
||||||
|
|
||||||
stkset(&d); Stack Set: Sets stack pointer to address d.
|
|
||||||
|
|
||||||
Note: Sets variables stklo and stshi.
|
|
||||||
|
|
||||||
stkadd(b); Stack Add: Increases the stack pointer by b.
|
|
||||||
|
|
||||||
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
|
Note: This module expects the following functions to be defined
|
||||||
|
|
||||||
memcpl Copy memory (alternate entry point)
|
memcpy Copy memory
|
||||||
ressrc Restore source pointer
|
ressrc Restore source pointer
|
||||||
resrxy Restore X and Y registers
|
resrxy Restore X and Y registers
|
||||||
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
|
||||||
|
strlen Get string Length
|
||||||
|
|
||||||
along with the zero page variable pairs
|
along with the zero page integer variables
|
||||||
|
|
||||||
srclo, srchi Source String Pointer
|
srcptr Source String Pointer
|
||||||
dstlo, dsthi Destination String Pointer
|
dstptr Destination String Pointer
|
||||||
stklo, stkhi stack Pointer
|
stkptr stack Pointer
|
||||||
|
|
||||||
the static variables
|
the static integer variables
|
||||||
|
|
||||||
stkslo, stkshi Stack Start Address
|
stkbgn Stack Start Address
|
||||||
stkelo, stkehi Stack End Address
|
stkend Stack End Address
|
||||||
|
|
||||||
and the transient variables
|
and the transient variables
|
||||||
|
|
||||||
|
@ -1,244 +1,286 @@
|
|||||||
;C02 stack module assembly language subroutines
|
;C02 stack module assembly language subroutines
|
||||||
;Requires external zero page variables
|
;Requires external zero page words DSTPTR, SRCPTR, STKPTR,
|
||||||
;STKLO, STKHI, DSTLO, DSTHI, SRCLO, SRCHI
|
;words STKBGN, STKEND, and bytes TEMP0, TEMP1, TEMP2 (header)
|
||||||
;external variables
|
;and external routines RESRXY, SAVRXY, SETDST, SETSRC (stddef),
|
||||||
;STKSLO, STKSHI, STKELO, STKEHI, TEMP0, TEMP1, TEMP2
|
;MEMCPL (memory), and STRLEN (string)
|
||||||
;external routines
|
|
||||||
;MEMCPL, SETDST, SETSRC
|
|
||||||
|
|
||||||
;Implementation Notes:
|
;Implementation Notes:
|
||||||
;Stack starts at STKSLO,STKSHI and builds upward tp STKELO, STKEHI
|
;Stack starts at STKBGN and builds upward to STKEND
|
||||||
;Each entry on the stack consists of the entry data followed
|
;Each entry on the stack consists of the entry data followed
|
||||||
;by a single byte containing the length of the entry data
|
;by a single byte containing the length of the entry data
|
||||||
|
|
||||||
;stkbgn(&b) - Set Stack Start Address
|
SUBROUTINE STACK
|
||||||
;Args: X,Y = Address
|
|
||||||
;Sets: STKSLO, STKSHI = Stack Start Address
|
|
||||||
;Affects: Z, N
|
|
||||||
STKBGN: STX STKSLO ;Save Stack Start LSB
|
|
||||||
STY STKSHI ;Save Stack Start MSB
|
|
||||||
RTS
|
|
||||||
|
|
||||||
;stkend(&b) - Set Stack End Address (+1)
|
;Get Stack Pointer
|
||||||
;Args: X,Y = Address
|
|
||||||
;Sets: STKELO, STKEHI = Stack End Address
|
|
||||||
;Affects: Z, N
|
|
||||||
STKEND: STX STKELO ;Save Stack End LSB
|
|
||||||
STY STKEHI ;Save Stack End MSB
|
|
||||||
RTS
|
|
||||||
|
|
||||||
;stkptr() - Get Stack Pointer
|
|
||||||
;Uses: STKLO,STKHI = Stack Pointer
|
|
||||||
;Affects: N,Z
|
;Affects: N,Z
|
||||||
;Returns: X = Stack Pointer LSB
|
;Returns: X = Stack Pointer LSB
|
||||||
; Y = Stack Pointer MSB
|
; Y = Stack Pointer MSB
|
||||||
STKPTR: LDX STKLO ;Load Stack Pointer LSB
|
.GETPTR LDX STKPTR ;Load Stack Pointer LSB
|
||||||
LDY STKHI ;Load Stack Pointer MSB
|
LDY STKPTR+1 ;Load Stack Pointer MSB
|
||||||
RTS
|
RTS
|
||||||
|
|
||||||
;stkssp() - Save Stack Pointer
|
;Save Stack Pointer
|
||||||
;Uses: STKLO,STKHI = Stack Pointer
|
;Sets: TEMP1,TEMP2 = STKPTR
|
||||||
;Sets: TEMP1.TEMP2 = Stack Pointer
|
|
||||||
;Affects: N,Z
|
;Affects: N,Z
|
||||||
;Returns: X = Stack Pointer LSB
|
;Returns: X = Stack Pointer LSB
|
||||||
; Y = Stack Pointer MSB
|
; Y = Stack Pointer MSB
|
||||||
STKSSP: JSR STKPTR ;Get Stack Pointer
|
.SAVPTR JSR .GETPTR ;Get Stack Pointer
|
||||||
JMP SAVRXY ;Save in TEMP1, TEMP2
|
JMP SAVRXY ;Save in TEMP1, TEMP2
|
||||||
|
|
||||||
;stksrc() - Set Source Pointer to Stack Pointer
|
;.STKSRC() - Set Source Pointer to Stack Pointer
|
||||||
;Uses: STKLO,STKHI = Stack Pointer
|
;Sets: SRCPTR = STKPTR
|
||||||
;Sets: SRCLO,SRCHI = Source Array Pointer
|
|
||||||
;Affects: X,N,Z
|
;Affects: X,N,Z
|
||||||
;Returns: Y = 0
|
;Returns: Y = 0
|
||||||
STKSRC: JSR STKPTR ;Get Stack Pointer Address
|
.STKSRC JSR .GETPTR ;Get Stack Pointer Address
|
||||||
JMP SETSRC ;Set Source/ an/d Return
|
JMP SETSRC ;Set Source/ an/d Return
|
||||||
|
|
||||||
;stkdst() - Set Destination Pointer to Stack Pointer
|
;.STKDST() - Set Destination Pointer to Stack Pointer
|
||||||
;Uses: STKLO,STKHI = Stack Pointer
|
;Uses: STKPTR = Stack Pointer
|
||||||
;Sets: DSTLO,DSTHI = Destination Array Pointer
|
;Sets: DSTPTR = Destination Array Pointer
|
||||||
;Affects: N,Z
|
;Affects: N,Z
|
||||||
;Returns: X = Stack Pointer LSB
|
;Returns: X = Stack Pointer LSB
|
||||||
; Y = Stack Pointer MSB
|
; Y = Stack Pointer MSB
|
||||||
STKDST: JSR STKPTR ;Get Stack Pointer Address
|
.STKDST JSR .GETPTR ;Get Stack Pointer Address
|
||||||
JMP SETDST ;Set Destination and Return
|
JMP SETDST ;Set Destination and Return
|
||||||
|
|
||||||
;stkrst() - Reset Stack Pointer to Start Address
|
;stkrst() - Reset Stack Pointer to Start Address
|
||||||
;Uses: STKSLO, STKSHI = Stack Start Address
|
;Uses: STKBGN = Stack Start Address
|
||||||
;Sets: STKLO, STKHI = Stack Pointer
|
;Sets: STKPTR = Stack Pointer
|
||||||
;Affects: Z, N
|
;Affects: Z, N
|
||||||
;Returns: X = Stack Pointer LSB
|
;Returns: X = Stack Pointer LSB
|
||||||
; Y = Stack Pointer MSB
|
; Y = Stack Pointer MSB
|
||||||
STKRST: LDX STKSLO ;Load X with Stack Start LSB
|
STKRST: LDX STKBGN ;Load X with Stack Start LSB
|
||||||
LDY STKSHI ;Load X with Stack Start MSB
|
LDY STKBGN+1 ;Load X with Stack Start MSB
|
||||||
JMP STKSET ;Store in Stack Pointer
|
JMP .SETPTR ;Store in Stack Pointer
|
||||||
|
|
||||||
;stkrsp() - Restore Stack Pointer
|
;.RESPTR() - Restore Stack Pointer
|
||||||
;Uses: TEMP1.TEMP2 = Stack Pointer
|
;Uses: TEMP1.TEMP2 = Stack Pointer
|
||||||
;Sets: STKLO,STKHI = Stack Pointer
|
;Sets: STKPTR = Stack Pointer
|
||||||
;Affects: N,Z
|
;Affects: N,Z
|
||||||
;Returns: X = Stack Pointer LSB
|
;Returns: X = Stack Pointer LSB
|
||||||
; Y = Stack Pointer MSB
|
; Y = Stack Pointer MSB
|
||||||
STKRSP: JSR RESRXY ;Get TEMP1, TEMP2
|
.RESPTR JSR RESRXY ;Get TEMP1, TEMP2
|
||||||
;and fall into STKSET
|
;and fall into .SETPTR
|
||||||
|
|
||||||
;stkset() - Set Stack Pointer Address
|
;Set STKPTR to Y,X
|
||||||
;Args: X,Y = Address
|
.SETPTR STX STKPTR ;Store X in Stack Pointer LSB
|
||||||
;Sets: STKLO, STKHI = Stack Pointer Address
|
STY STKPTR+1 ;Store Y in Stack Pointer MSB
|
||||||
;Affects: Z, N
|
RTS ;Exit Routine
|
||||||
;Returns: X = Stack Pointer LSB
|
|
||||||
; Y = Stack Pointer MSB
|
|
||||||
STKSET: STX STKLO ;Store X in Stack Pointer LSB
|
|
||||||
STY STKHI ;Store Y in Stack Pointer MSB
|
|
||||||
RTS ;Exit Routine
|
|
||||||
|
|
||||||
;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
|
||||||
;Uses: STKELO, STKEHI = Stack End Address
|
;Uses: STKEND = Stack End Address
|
||||||
;Sets: DSTLO, DSTHI = Pointer to Stack Entry
|
;Sets: DSTPTR = Pointer to Stack Entry
|
||||||
; SRCHI, SRCLO = Pointer to Source Array
|
; SRCPTR = Pointer to Source Array
|
||||||
; TEMP0 = Number of Bytes to Append
|
; TEMP0 = Number of Bytes to Append
|
||||||
;Updates: STKLO, STKHI = Stack Pointer
|
;Updates: STKPTR = Stack Pointer
|
||||||
;Returns: A=Number of Bytes Pushed
|
;Returns: A=Number of Bytes Pushed
|
||||||
; 0 = Error: Stack Underflow
|
; 0 = Error: Stack Underflow
|
||||||
STKPSH: JSR SETSRC ;Set Source Address
|
STKPSH: JSR SETSRC ;Set Source Address
|
||||||
STKPSA: STA TEMP0 ;Save Number of Bytes
|
.STKPSH STA TEMP0 ;Save Number of Bytes
|
||||||
JSR STKDST ;Set Destination to Stack Pointer
|
JSR .STKDST ;Set Destination to Stack Pointer
|
||||||
JSR STKALC ;Allocate Space on Stack
|
JSR .ALLOC ;Allocate Space on Stack
|
||||||
JMP MEMCPL ;Copy Bytes and Return
|
JMP MEMCPL ;Copy Bytes and Return
|
||||||
|
|
||||||
;stkadd(n) - Add N Bytes to Stack Pointer
|
;Add A to STKPTR
|
||||||
;Args: A=Number of Bytes to Allocate
|
.ADDPTR CLC
|
||||||
;Updates: STKLO, STKHI = Stack Pointer
|
.ADCPTR ADC STKPTR ;Add to Stack Pointer LSB
|
||||||
;Affects: A,C,N,Z
|
STA STKPTR ;and Save
|
||||||
STKADD: CLC
|
LDA STKPTR+1 ;Add Carry
|
||||||
STKADC: ADC STKLO ;Add to Stack Pointer LSB
|
|
||||||
STA STKLO ;and Save
|
|
||||||
LDA STKHI ;Add Carry
|
|
||||||
ADC #0 ;to Stack Pointer MSB
|
ADC #0 ;to Stack Pointer MSB
|
||||||
STA STKHI ;and Save
|
STA STKPTR+1 ;and Save
|
||||||
RTS
|
RTS
|
||||||
|
|
||||||
;stkalc(n) - Allocate Space on Stack
|
;Allocate Space on Stack
|
||||||
;Args: A=Number of Bytes to Allocate
|
;Args: A=Number of Bytes to Allocate
|
||||||
;Updates: STKLO, STKHI = Stack Pointer
|
;Updates: STKPTR = Stack Pointer
|
||||||
;Affects: C,N,Z
|
;Affects: C,N,Z
|
||||||
;Returns: A = Number of Bytes Allocated
|
;Returns: A = Number of Bytes Allocated
|
||||||
; 0 if Error: Pointer Overflow or Length 0
|
; 0 if Error: Pointer Overflow or Length 0
|
||||||
; Y=0
|
.ALLOC JSR .SAVPTR ;Save Stack Pointer
|
||||||
STKALC: JSR STKSSP ;Save Stack Pointer
|
|
||||||
LDA TEMP0 ;If No Bytes
|
LDA TEMP0 ;If No Bytes
|
||||||
BEQ STKABT ; Abort Calling Routine
|
BEQ .POPRET ; Abort Calling Routine
|
||||||
JSR STKADD ;Add to Stack Pointer
|
JSR .ADDPTR ;Add to Stack Pointer
|
||||||
LDA STKEHI ;If Stack End MSB
|
LDA STKEND+1 ;If Stack End MSB
|
||||||
CMP STKHI ; < Stack Pointer MSB
|
CMP STKPTR+1 ; < Stack Pointer MSB
|
||||||
BCC STKRPA ; Abort Calling Routine
|
BCC .ABORT ; Abort Calling Routine
|
||||||
BNE STKALX ;Else if Not Equal
|
BNE .ALSKIP ;Else if Not Equal
|
||||||
LDA STKELO ;and Stack End LSB
|
LDA STKEND ;and Stack End LSB
|
||||||
CMP STKLO ; < Stack Pointer LSB
|
CMP STKPTR ; < Stack Pointer LSB
|
||||||
BCC STKRPA ; Abort Calling Routine
|
BCC .ABORT ; Abort Calling Routine
|
||||||
STKALX: LDA TEMP0 ;Get Number of Bytes from X Register
|
.ALSKIP LDA TEMP0 ;Get Number of Bytes from X Register
|
||||||
LDY #0 ;Initialize Index
|
LDY #0 ;Initialize Index
|
||||||
STA (STKLO),Y ;Store after Allocated Area
|
STA (STKPTR),Y ;Store after Allocated Area
|
||||||
;and fall inro STKINC
|
;and fall into .INCPTR
|
||||||
|
|
||||||
;stkinc(n) - Increment Stack Pointer
|
;Increment Stack Pointer
|
||||||
;Sets: STKLO, STKHI = Stack Pointer Address
|
.INCPTR INC STKPTR ;Increment LSB
|
||||||
;Affects: Y,Z,N
|
BNE .RETURN ;If Zero
|
||||||
STKINC: INC STKLO ;Increment LSB
|
INC STKPTR+1 ; Increment MSB
|
||||||
BNE STKINX ;If Zero
|
RTS
|
||||||
INC STKHI ; Increment MSB
|
|
||||||
STKINX: RTS
|
|
||||||
|
|
||||||
;stkcmp - Compare Stack Pointer to Stack Start Address
|
;STKPTR to STKBGN
|
||||||
;Uses: STKLO, STKHI = Stack Pointer Address
|
;Returns: C=1,Z=1 if STKPTR = STKBGN
|
||||||
; STKSLO, STKSHI = Stack Start Address
|
; C=1,Z=0 if STKPTR > STKBGN
|
||||||
;Returns: C=1,Z=1 if Stack Pointer = Stack Start
|
; C=0,Z=0 if STKPTR < STKBGN
|
||||||
; C=1,Z=0 if Stack Pointer > Stack Start
|
.CMPPTR LDA STKPTR+1 ;Compare MSB
|
||||||
; C=0,Z=0 if Stack Pointer < Stack Start
|
CMP STKBGN+1
|
||||||
STKCMP: LDA STKHI ;Compare MSB
|
BCC .RETURN ;If Pointer<Start Return C=0, Z=1
|
||||||
CMP STKSHI
|
BNE .RETURN ;If Pointer>Start Return C=1. Z=0
|
||||||
BCC STKRTS ;If Pointer<Start Return C=0, Z=1
|
LDA STKPTR ;If MSB Equal
|
||||||
BNE STKRTS ;If Pointer>Start Return C=1. Z=0
|
CMP STKBGN ;Compare LSB
|
||||||
LDA STKLO ;If MSB Equal
|
RTS
|
||||||
CMP STKSLO ;Compare LSB
|
|
||||||
STKRTS: RTS
|
|
||||||
|
|
||||||
;stkdec(n) - Decrement Stack Pointer
|
;.DECPTR(n) - Decrement Stack Pointer
|
||||||
;Sets: STKLO, STKHI = Stack Pointer Address
|
;Sets: STKPTR = Stack Pointer Address
|
||||||
;Affects: X,Z,N
|
;Affects: X,Z,N
|
||||||
STKDEC: LDX STKLO ;If LSB
|
.DECPTR LDX STKPTR ;If LSB
|
||||||
BNE STKDEL ; is Zero
|
BNE .DECLSB ; is Zero
|
||||||
DEC STKHI ; Decrement MSB
|
DEC STKPTR+1 ; Decrement MSB
|
||||||
STKDEL: DEC STKLO ; Decrement LSB
|
.DECLSB DEC STKPTR ; Decrement LSB
|
||||||
STKDER: RTS
|
RTS
|
||||||
|
|
||||||
;stksiz() - Get Stack Size in Bytes
|
;stksiz() - Get Stack Size in Bytes
|
||||||
;Uses: STKLO,STKHI = Stack Pointer
|
;Uses: STKPTR = Stack Pointer
|
||||||
;Sets: STKSLO, STKSHI = Stack Start Address
|
;Sets: STKBGN = Stack Start Address
|
||||||
;Returns: A = $FF if Stack Size is Non-Zero
|
;Returns: A = $FF if Stack Size is Non-Zero
|
||||||
; $00 if Stack is Empty
|
; $00 if Stack is Empty
|
||||||
; Y,X = Stack Size (MSB, LSB)
|
; Y,X = Stack Size (MSB, LSB)
|
||||||
STKSIZ: LDA STKLO ;Subtract
|
STKSIZ: LDA STKPTR ;Subtract
|
||||||
SEC ;Start Address LSB
|
SEC ;Start Address LSB
|
||||||
SBC STKSLO ;from Pointer LSB
|
SBC STKBGN ;from Pointer LSB
|
||||||
TAX ;and Copy to X
|
TAX ;and Copy to X
|
||||||
LDA STKHI ;Subtract Start MSB
|
LDA STKPTR+1 ;Subtract Start MSB
|
||||||
SBC STKSHI ;from Pointer MSB
|
SBC STKBGN+1 ;from Pointer MSB
|
||||||
TAY ;and Copy to Y
|
TAY ;and Copy to Y
|
||||||
BCC STKZRO ;Return FALSE if <=0
|
BCC .RETZRO ;Return FALSE if <=0
|
||||||
BNE STKTRU ;Return TRUE if MSB <> 0
|
BNE .RETTRU ;Return TRUE if MSB <> 0
|
||||||
TXA ;Else
|
TXA ;Else
|
||||||
BEQ STKRTS ;Return FALSE if LSB = 0
|
BEQ .RETURN ;Return FALSE if LSB = 0
|
||||||
STKTRU: LDA #$FF ;Else Return TRUE
|
.RETTRU LDA #$FF ;Else Return TRUE
|
||||||
RTS
|
.RETURN RTS
|
||||||
|
|
||||||
;stkdrp(&m) - Drop Top Entry from Stack
|
;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: STKBGN = Stack Start Address
|
||||||
;Sets: TEMP1, TEMP2 = Original Stack Pointer
|
;Sets: TEMP1, TEMP2 = Original Stack Pointer
|
||||||
;Updates: STKLO, STKHI = Stack Pointer
|
;Updates: STKPTR = Stack Pointer
|
||||||
;Affects: Y,C,N,Z
|
;Affects: Y,C,N,Z
|
||||||
;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
|
||||||
STKDRP: JSR STKSSP ;Save Stack Pointer
|
STKDRP: JSR .SAVPTR ;Save Stack Pointer
|
||||||
STKDRN: JSR STKCMP ;If Stack Pointer
|
.STKDRP JSR .CMPPTR ;If Stack Pointer
|
||||||
BCC STKRPA ; <= Stack Start
|
BCC .ABORT ; <= Stack Start
|
||||||
BEQ STKRPA ; Return 0
|
BEQ .ABORT ; Return 0
|
||||||
JSR STKDEC ;Decrement Stack Pointer
|
JSR .DECPTR ;Decrement Stack Pointer
|
||||||
LDY #0 ;Initialize Index
|
LDY #0 ;Initialize Index
|
||||||
LDA (STKLO),Y ;Get Number of Bytes in Entry
|
LDA (STKPTR),Y ;Get Number of Bytes in Entry
|
||||||
;and fall into STKSUB
|
;and fall into .SUBPTR
|
||||||
|
|
||||||
;stksub(n) - Reduce Stack Pointer by A
|
;Subtract A from STKPTR
|
||||||
STKSUB: STA TEMP0 ;Save Number in TEMP0
|
.SUBPTR STA TEMP0 ;Save Number in TEMP0
|
||||||
LDA STKLO
|
LDA STKPTR
|
||||||
SEC ;Subtract A from LSB
|
SEC ;Subtract A from LSB
|
||||||
SBC TEMP0
|
SBC TEMP0
|
||||||
STA STKLO
|
STA STKPTR
|
||||||
LDA STKHI ;Subtract 0 from LSB
|
LDA STKPTR+1 ;Subtract 0 from LSB
|
||||||
SBC #0 ;For Borrow
|
SBC #0 ;For Borrow
|
||||||
STA STKHI
|
STA STKPTR+1
|
||||||
JSR STKCMP ;If Stack Pointer < Start
|
JSR .CMPPTR ;If Stack Pointer < Start
|
||||||
BCC STKRPA ; Restore Pointer and Return 0
|
BCC .ABORT ; Restore Pointer and Return 0
|
||||||
STKSUE: LDA TEMP0 ;Retrieve Number of Bytes
|
LDA TEMP0 ;Retrieve Number of Bytes
|
||||||
RTS
|
RTS
|
||||||
STKRPA: JSR STKRSP ;Restore Stack Pointer
|
.ABORT JSR .RESPTR ;Restore Stack Pointer
|
||||||
STKABT: PLA ;Drop Return Address from Stack
|
.POPRET PLA ;Drop Return Address from Stack
|
||||||
PLA ; Aborting Calling Routine
|
PLA ; Aborting Calling Routine
|
||||||
STKZRO: LDA #0 ;Set A to 0
|
.RETZRO LDA #0 ;Set A to 0
|
||||||
RTS
|
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: STKBGN = Stack Start Address
|
||||||
;Updates: STKLO, STKHI = Stack Pointer
|
;Updates: STKPTR = Stack Pointer
|
||||||
;Affects: C,N,Z
|
;Affects: C,N,Z
|
||||||
;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 STKDRP ;Deallocate Stack Entry
|
JSR STKDRP ;Deallocate Stack Entry
|
||||||
STKPOS: JSR STKSRC ;Set Source Address to Stack Pointer
|
JSR .STKSRC ;Set Source Address to Stack Pointer
|
||||||
JMP MEMCPL ;Copy Bytes and Return
|
JMP MEMCPL ;Copy Bytes and Return
|
||||||
|
|
||||||
|
;stkstr(n, &m) - Push String onto Stack
|
||||||
|
;Args: Y,X = Address of Source Array
|
||||||
|
STKSTR: JSR STRLEN ;Get Length of String
|
||||||
|
BEQ .PSHSRC ;If Length > 0
|
||||||
|
BMI .PSHSRC ; and < 128
|
||||||
|
INY ; Increment Length to
|
||||||
|
TYA ; include null terminator
|
||||||
|
.PSHSRC LDY #0 ;Clear Y Index
|
||||||
|
JMP .STKPSH ;Push Bytes onto Stack
|
||||||
|
|
||||||
|
;stktop(&m) - Copy Top Entry off Stack
|
||||||
|
;Args: Y,X = Address of Source Array
|
||||||
|
;Uses: STKBGN = 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 .RETURN ;If Underflow, Return 0
|
||||||
|
JMP .RESPTR ;Else Restore Stack Pointer and Return
|
||||||
|
|
||||||
|
;stkdup(&m) - Duplicate Top Entry on Stack
|
||||||
|
;Uses: STKBGN = Stack Start Address
|
||||||
|
; STKEND = Stack End Address
|
||||||
|
;Updates: STKPTR = 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
|
||||||
|
.STKDUP JSR .STKSRC ;Set Source Pointer to Stack Pointer
|
||||||
|
JSR .RESPTR ;Restore Stack Pointer
|
||||||
|
JMP .PSHSRC ;Push Top Entry onto Stack
|
||||||
|
|
||||||
|
;stkovr(&m) - Duplicate Second Entry on Stack
|
||||||
|
;Uses: STKBGN = Stack Start Address
|
||||||
|
; STKEND = Stack End Address
|
||||||
|
;Updates: STKPTR = 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 .STKDRP ;Deallocate Second Entry
|
||||||
|
JMP .STKDUP ;Restore Pointer and Duplicate
|
||||||
|
|
||||||
|
;stkswp() - Swap Top Entry with Entry Below it
|
||||||
|
;Uses: STKBGN = Stack Start Address
|
||||||
|
; STKEND = Stack End Address
|
||||||
|
;Destroys: DSTPTR,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 .RETURN ;Exit if Error
|
||||||
|
JSR .STKDRP ;Deallocate Duplicate
|
||||||
|
STA TEMP3 ;Save Size of Duplicate
|
||||||
|
JSR .SAVPTR ;Save Pointer to Duplicate
|
||||||
|
JSR .STKDRP ;Deallocate Top Entry
|
||||||
|
JSR .STKSRC ;Set Source to Top Entry
|
||||||
|
STA DSTPTR ;Save Top Entry Size
|
||||||
|
JSR .STKDRP ;Deallocate Second Entry
|
||||||
|
LDA DSTPTR ;Retrieve Top Entry Size
|
||||||
|
JSR .COPY ;Copy Top Entry Down
|
||||||
|
JSR RESSRC ;Set Duplicate as Source
|
||||||
|
LDA TEMP3 ;Get Duplicate Length
|
||||||
|
.COPY 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 (DSTPTR),Y ;Store Number of Bytes after Entry
|
||||||
|
SEC ;Add Number of Bytes plus 1
|
||||||
|
JSR .ADCPTR ;to Stack Pointer
|
||||||
|
TYA ;Return Number of Bytes
|
||||||
|
RTS
|
||||||
|
|
||||||
|
ENDSUBROUTINE
|
@ -2,35 +2,20 @@
|
|||||||
* stack - Software Stack 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 *
|
/* Drop Top Entry from Stack *
|
||||||
* Returns: A=Number of bytes dropped *
|
* Returns: A=Number of bytes dropped *
|
||||||
* 0 if none */
|
* 0 if none */
|
||||||
char stkdrp();
|
char stkdrp();
|
||||||
|
|
||||||
/* Set Destination to Stack Pointer *
|
/* Duplicate Top Stack Entry *
|
||||||
* Returns: Y,X=Pointer Address */
|
* Returns: A=Number of bytes retrieved *
|
||||||
void stkdst();
|
* 0 if none or overflow */
|
||||||
|
char stkdup();
|
||||||
|
|
||||||
/* Set Stack End Address *
|
/* Duplicate Entry Under Top of Stack *
|
||||||
* Args: &addr - End Address */
|
* Returns: A=Number of bytes retrieved *
|
||||||
void stkend();
|
* 0 if none or overflow */
|
||||||
|
char stkovr();
|
||||||
/* Increment Stack Pointer Address *
|
|
||||||
* Internal Utility Function */
|
|
||||||
void stkinc();
|
|
||||||
|
|
||||||
/* 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 *
|
||||||
@ -46,34 +31,30 @@ char stkpop();
|
|||||||
* $00 if block was overflowed */
|
* $00 if block was overflowed */
|
||||||
char stkpsh();
|
char stkpsh();
|
||||||
|
|
||||||
/* Get Stack Pointer Address *
|
|
||||||
* Returns: Y,X=Pointer Address */
|
|
||||||
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 *
|
|
||||||
* Internal Utility Function *
|
|
||||||
* Args: &addr - Pointer Address */
|
|
||||||
void stkset();
|
|
||||||
|
|
||||||
/* Save Stack Pointer Address *
|
|
||||||
* Internal Utility Function */
|
|
||||||
void stkssp();
|
|
||||||
|
|
||||||
/* Get Stack Size *
|
/* Get Stack Size *
|
||||||
* Returns: A=$FF if size greater than 0 *
|
* Returns: A=$FF if size greater than 0 *
|
||||||
* $00 if stack is empty *
|
* $00 if stack is empty *
|
||||||
* Y,X=Stack size in bytes */
|
* Y,X=Stack size in bytes */
|
||||||
void stksiz();
|
void stksiz();
|
||||||
|
|
||||||
/* Subtract from Stack Pointer Address *
|
/* Push String onto Stack *
|
||||||
* Internal Utility Function *
|
* Args: &m - String to push *
|
||||||
* Args: b - Number of Bytes to Subtract */
|
* Returns: A=$FF if bytes were written *
|
||||||
void stksub();
|
* $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();
|
||||||
|
@ -1,80 +0,0 @@
|
|||||||
;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
|
|
@ -1,31 +0,0 @@
|
|||||||
/*********************************************
|
|
||||||
* 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();
|
|
255
test/stktest.c02
255
test/stktest.c02
@ -1,207 +1,132 @@
|
|||||||
/***********************************************
|
/***********************************************
|
||||||
* TESTSTK - Test Stack Manipulation Functions *
|
* STKTEST - Test Stack Manipulation Functions *
|
||||||
* Assumes free RAM from $7FFF to $807E *
|
* Assumes free RAM from $7FFF to $807E *
|
||||||
***********************************************/
|
***********************************************/
|
||||||
|
|
||||||
//use -h option on command line when compiling
|
//use -h option on command line when compiling
|
||||||
|
|
||||||
#include <stddef.h02>
|
#include <stddef.h02>
|
||||||
#include <stdlib.h02>
|
#include <stdlib.h02>
|
||||||
|
#include <intlib.h02>
|
||||||
#include <stdio.h02>
|
#include <stdio.h02>
|
||||||
#include <stdiox.h02>
|
#include <stdiox.h02>
|
||||||
#include <string.h02>
|
#include <string.h02>
|
||||||
#include <memory.h02>
|
#include <memory.h02>
|
||||||
#include <stack.h02>
|
#include <stack.h02>
|
||||||
|
|
||||||
char c,f,g,i;
|
char c,f,g,i,n;
|
||||||
char aa,xx,yy;
|
char aa,xx,yy,zz;
|
||||||
char zz,lo,hi;
|
int addr,adr,cptr,csiz,nn,optr,ptr,siz,yx;
|
||||||
const char r={6,7,8,9};
|
const char r={6,7,8,9};
|
||||||
const char s="Test String";
|
const char s="TEST STRING";
|
||||||
char t[255];
|
char t[255];
|
||||||
|
char stackb[128], stacke;
|
||||||
|
|
||||||
|
|
||||||
|
void pass() {putln(" PASS");}
|
||||||
|
void fail() {putln(" FAIL"); goto exit;}
|
||||||
|
void psorfl(aa) {if (aa) pass(); else fail();}
|
||||||
|
void florps(aa) {if (aa) fail(); else pass();}
|
||||||
|
void equals(aa,zz) {A = (aa == zz) ? #TRUE : #FALSE;}
|
||||||
|
void prtadr(adr) {puts("$"); putwrd(adr);}
|
||||||
|
void prtstk() {aa,yy,xx=stksiz(); for (zz=0; zz<xx; zz++) {if (zz) putc(','); putdec(stackb[zz]);}}
|
||||||
|
void errstk() {newlin(); puts("STACK={"); prtstk(); putc(')'); fail();}
|
||||||
|
void addsub(zz,yx) {if (zz:-) subayx(-zz+1,yx); else addayx(zz+1,yx);}
|
||||||
|
void updptr(aa) {if (aa) cptr=addsub(aa,cptr); else cptr=stkptr;}
|
||||||
|
void updsiz(aa) {if (aa) csiz=addsub(aa,csiz); else csiz=0;}
|
||||||
|
void cmpadr(adr) {f = equals(<addr,<adr); g = equals(>addr,>adr); return f & g;}
|
||||||
|
void chkadr(yx) {prtadr(addr); psorfl(cmpadr(yx));}
|
||||||
|
void chkint(yx) {putint(addr); psorfl(cmpadr(yx));}
|
||||||
|
void chkmem(aa,yx) {setdst(optr); florps(memcmp(aa, yx));}
|
||||||
|
void chkmet(aa,yx) {setdst(t); florps(memcmp(aa, yx));}
|
||||||
|
void chkptr(aa,ptr) {addr=stkptr; puts(" STKPTR="); chkadr(ptr); optr=stkptr;}
|
||||||
|
void chkres(aa,zz) {printf(zz,"=%d");if (aa<>zz) fail();}
|
||||||
|
void chksiz(siz) {puts(" STKSIZ()="); addr=stksiz(); chkint(siz);}
|
||||||
|
void chkstr(yx) {setdst(optr); florps(strcmp(yx));}
|
||||||
|
void chkstt(yx) {setdst(t); florps(strcmp(yx));}
|
||||||
|
void pause() {if (anykey()==#ESCKEY) goto exit;}
|
||||||
|
|
||||||
main:
|
main:
|
||||||
|
|
||||||
for (i=0;i<$20;i++) srclo[i]=0; //Initialize Pointers
|
stkbgn = &stackb; puts("STKBGN="); prtadr(stkbgn); newlin();
|
||||||
|
stkend = &stacke; puts("STKEND="); prtadr(stkend); newlin();
|
||||||
|
|
||||||
puts("Setting Stack Start Address\t");
|
putln("STKRST()");
|
||||||
puts("stkbgn($7FFF)\t");
|
stkrst();
|
||||||
stkbgn(&$7FFF); lo=stkslo; hi=stkshi;
|
updptr(0); chkptr(stkbgn); updsiz(0); chksiz(csiz);
|
||||||
setdst("stks"); cklohi(&$7FFF);
|
|
||||||
|
|
||||||
puts("Setting Stack End Address\t");
|
//Push Array - Stack=R
|
||||||
puts("stkend($807E)\t");
|
puts("STKPSH(@R,R)");
|
||||||
stkend(&$807E); lo=stkelo; hi=stkehi;
|
n=stkpsh(@r,r); chkres(@r,n); chkmem(@r, &r);
|
||||||
setdst("stke"); cklohi(&$807E);
|
updptr(n); chkptr(cptr); updsiz(n); chksiz(csiz);
|
||||||
|
|
||||||
puts("Setting Stack Pointer Address\t");
|
//Duplicate Top - Stack=R,R
|
||||||
puts("stkset($7765)\t");
|
puts("STKDUP()");
|
||||||
stkset(&$7765); lo=stklo; hi=stkhi;
|
n=stkdup(); chkres(@r,n); chkmem(@r, &r);
|
||||||
setdst("stk"); cklohi(0,&$7765);
|
updptr(n); chkptr(cptr); updsiz(n); chksiz(csiz);
|
||||||
chksiz(#FALSE, &$F766);
|
|
||||||
|
|
||||||
puts("Resetting Stack Pointer\t\t");
|
//Push String - Stack=S,R,R
|
||||||
puts("stkrst()\t");
|
puts("STKSTR(S)");
|
||||||
stkrst(); lo=stklo; hi=stkhi;
|
n=stkstr(s); chkres(@s+1,n); chkstr(s);
|
||||||
setdst("stk"); cklohi(0,&$7FFF);
|
updptr(n); chkptr(cptr); updsiz(n); chksiz(csiz);
|
||||||
chksiz(#FALSE, &0);
|
|
||||||
|
|
||||||
puts("Getting Stack Pointer Address\t");
|
pause();
|
||||||
puts("stkptr()\t");
|
|
||||||
aa, hi, lo = stkptr();
|
|
||||||
setdst(""); cklohi(0,&$7FFF);
|
|
||||||
|
|
||||||
puts("Setting Source to Stack Pointer\t");
|
//Copy Second to Top - Stack=R,S,R,R
|
||||||
puts("stksrc()\t");
|
puts("STKOVR()");
|
||||||
stksrc(); lo=srclo; hi=srchi;
|
n=stkovr(); chkres(@r,n); chkmem(@r, &r);
|
||||||
setdst("src"); cklohi(0,&$7FFF);
|
updptr(n); chkptr(cptr); updsiz(n); chksiz(csiz);
|
||||||
|
|
||||||
puts("Setting Dest. to Stack Pointer\t");
|
//Swap Top and Second - Stack=S,R,R,R
|
||||||
puts("stkdst()\t");
|
puts("STKSWP()");
|
||||||
stkdst(); lo=dstlo; hi=dsthi;
|
n=stkswp(s); chkres(@s+1,n); chkstr(s);
|
||||||
setdst("src"); cklohi(0,&$7FFF);
|
chkptr(cptr); chksiz(csiz);
|
||||||
|
|
||||||
puts("Incrementing Stack Pointer\t");
|
//Read String - Stack=S,R,R,R
|
||||||
puts("stkinc()\t");
|
puts("STKTOP(T)");
|
||||||
stkinc(); lo=stklo; hi=stkhi;
|
n=stktop(t); chkres(@s+1,n); chkstt(s);
|
||||||
setdst("stk"); cklohi(0,&$8000);
|
chkptr(cptr); chksiz(csiz);
|
||||||
chksiz(#TRUE, &1);
|
|
||||||
|
|
||||||
puts("Decrementing Stack Pointer\t");
|
//Pop String - Stack=R,R,R
|
||||||
puts("stkdec()\t");
|
puts("STKPOP(T)");
|
||||||
stkdec(); lo=stklo; hi=stkhi;
|
n=stkpop(&t); chkres(@s+1,n); chkstt(s);
|
||||||
setdst("stk"); cklohi(0,&$7FFF);
|
updptr(-n); chkptr(cptr); updsiz(-n); chksiz(csiz);
|
||||||
chksiz(#FALSE, &0);
|
|
||||||
|
|
||||||
c = anykey(); if (c == #esckey) goto exit;
|
pause();
|
||||||
|
|
||||||
puts("Pushing Array onto Stack\t");
|
//Drop Copy - Stack=R,R
|
||||||
puts("stkpsh(@r,$r)\t");
|
puts("STKDRP()");
|
||||||
aa,hi,lo=stkptr(); //Save Stack Pointer
|
n=stkdrp(); chkres(@r,n); pass();
|
||||||
f=stkpsh(@r,&r); printf(f,"bytes=%d:");
|
updptr(-n); chkptr(cptr); updsiz(-n); chksiz(csiz);
|
||||||
setdst(?,hi,lo); g=(memcmp(@r, &r)==0) ? #TRUE : #FALSE;
|
|
||||||
psorfl(f & g); chksiz(#TRUE, &5); chkptr(&$8004);
|
|
||||||
|
|
||||||
puts("Duplicating Top of Stack\t");
|
//Drop Duplicate - Stack=R
|
||||||
puts("stkdup()\t");
|
puts("STKDRP()");
|
||||||
aa,hi,lo=stkptr(); //Save Stack Pointer
|
n=stkdrp(); chkres(@r,n); pass();
|
||||||
f=stkdup(); printf(f,"bytes=%d:");
|
updptr(-n); chkptr(cptr); updsiz(-n); chksiz(csiz);
|
||||||
setdst(?,hi,lo); g=(memcmp(@r, &r)==0) ? #TRUE : #FALSE;
|
|
||||||
psorfl(f & g); chksiz(#TRUE, &10); chkptr(&$8009);
|
|
||||||
|
|
||||||
puts("Pushing String onto Stack\t");
|
//Pop Array - Stack Empty
|
||||||
puts("stkstr(&s)\t");
|
puts("STKPOP(&T)");
|
||||||
aa,hi,lo=stkptr(); //Save Stack Pointer
|
n=stkpop(&t); chkres(@r,n); chkmet(@r,t);
|
||||||
f=stkstr(&s); printf(f,"bytes=%d:");
|
updptr(-n); chkptr(cptr); updsiz(-n); chksiz(csiz);
|
||||||
setdst(?,hi,lo); g=(strcmp(&s)==0) ? #TRUE : #FALSE;
|
|
||||||
psorfl(f & g); chksiz(#TRUE, &23); chkptr(&$8016);
|
|
||||||
|
|
||||||
puts("Duplicating Second Stack Entry\t");
|
pause();
|
||||||
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;
|
//Pop from Empty Stack
|
||||||
|
puts("STKPOP(&T)");
|
||||||
|
n=stkpop(&t); chkres(0,n); pass();
|
||||||
|
chkptr(cptr); chksiz(csiz);
|
||||||
|
|
||||||
puts("Dropping Duplicate off Stack\t");
|
//Overflow Stack - Stack Empty
|
||||||
puts("stkdrp()\t");
|
puts("STKPSH(255,&T)");
|
||||||
f=stkdrp(); printf(f,"bytes=%d:");
|
n=stkpsh(255,&t); chkres(0,n); pass();
|
||||||
g=(f==4) ? #TRUE : #FALSE;
|
chkptr(cptr); chksiz(csiz);
|
||||||
psorfl(f & g); chksiz(#TRUE, &23); chkptr(&$8016);
|
|
||||||
|
|
||||||
puts("Copying String from Stack\t");
|
putln("TESTS COMPLETE");
|
||||||
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;
|
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) {
|
puts("Dropping Swapped Entry off Stack");
|
||||||
putc('{');
|
puts("stkdrp()");
|
||||||
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=$%x 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:");
|
f=stkdrp(); printf(f,"bytes=%d:");
|
||||||
g=(f==4) ? #TRUE : #FALSE;
|
g=(f==4) ? #TRUE : #FALSE;
|
||||||
psorfl(f & g);
|
psorfl(f & g);
|
||||||
|
Loading…
x
Reference in New Issue
Block a user