1
0
mirror of https://github.com/RevCurtisP/C02.git synced 2024-06-08 06:29:32 +00:00

Combined stack and stackx modules, updated documentation and test program

This commit is contained in:
Curtis F Kaylor 2020-10-19 22:44:24 -04:00
parent 85b04dff00
commit 414d673db5
6 changed files with 449 additions and 581 deletions

View File

@ -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

View File

@ -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

View File

@ -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();

View File

@ -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

View File

@ -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();

View File

@ -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);