From 9bee7114fdb79cb0786df3c15a2e9e20344fce2f Mon Sep 17 00:00:00 2001 From: Curtis F Kaylor Date: Sun, 23 Sep 2018 18:39:27 -0400 Subject: [PATCH] Split module stack into stack and stackx --- doc/stack.txt | 129 ++++++++++------------------ doc/stackx.txt | 125 +++++++++++++++++++++++++++ include/stack.a02 | 126 +++++++-------------------- include/stack.h02 | 55 +++++++----- include/stackx.a02 | 80 +++++++++++++++++ include/stackx.h02 | 31 +++++++ test/teststk.c02 | 209 +++++++++++++++++++++++++++++++++++++++++++++ test/teststkx.c02 | 127 +++++++++++++++++++++++++++ 8 files changed, 683 insertions(+), 199 deletions(-) create mode 100644 doc/stackx.txt create mode 100644 include/stackx.a02 create mode 100644 include/stackx.h02 create mode 100644 test/teststk.c02 create mode 100644 test/teststkx.c02 diff --git a/doc/stack.txt b/doc/stack.txt index 74bda60..992ab14 100644 --- a/doc/stack.txt +++ b/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 #include - #include #include 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 diff --git a/doc/stackx.txt b/doc/stackx.txt new file mode 100644 index 0000000..44f075d --- /dev/null +++ b/doc/stackx.txt @@ -0,0 +1,125 @@ +Sta Functions + +This module contains extended stack manipulation functions. + +Usage: at the beginning of the program use the directives + + #include + #include + #include + #include + #include + +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 diff --git a/include/stack.a02 b/include/stack.a02 index 301b142..0e1ca46 100644 --- a/include/stack.a02 +++ b/include/stack.a02 @@ -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 PointerStart Return C=1. Z=0 + BCC STKRTS ;If PointerStart 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 diff --git a/include/stack.h02 b/include/stack.h02 index a58dd7e..a80f9db 100644 --- a/include/stack.h02 +++ b/include/stack.h02 @@ -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(); diff --git a/include/stackx.a02 b/include/stackx.a02 new file mode 100644 index 0000000..e7cc6ed --- /dev/null +++ b/include/stackx.a02 @@ -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 diff --git a/include/stackx.h02 b/include/stackx.h02 new file mode 100644 index 0000000..42f4510 --- /dev/null +++ b/include/stackx.h02 @@ -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(); diff --git a/test/teststk.c02 b/test/teststk.c02 new file mode 100644 index 0000000..fcde59e --- /dev/null +++ b/test/teststk.c02 @@ -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 +#include +#include +#include +#include +#include +#include + +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 +#include +#include +#include +#include +#include +#include +#include + +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