/***********************************************
 * STKTEST - Test Stack Manipulation Functions *
 * Assumes free RAM from $7FFF to $807E        *
 ***********************************************/

//use -h option on command line when compiling
#include <stddef.h02>
#include <stdlib.h02>
#include <intlib.h02>
#include <stdio.h02>
#include <stdiox.h02>
#include <string.h02>
#include <memory.h02>
#include <stack.h02>

char c,f,g,i,n;
char aa,xx,yy,zz;
int addr,adr,cptr,csiz,nn,optr,ptr,siz,yx;
const char r={6,7,8,9};
const char s="TEST STRING";
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:

stkbgn = &stackb; puts("STKBGN="); prtadr(stkbgn); newlin();
stkend = &stacke; puts("STKEND="); prtadr(stkend); newlin();

putln("STKRST()"); 
stkrst(); 
updptr(0); chkptr(stkbgn); updsiz(0); chksiz(csiz);

//Push Array - Stack=R
puts("STKPSH(@R,R)");
n=stkpsh(@r,r); chkres(@r,n); chkmem(@r, &r);
updptr(n); chkptr(cptr); updsiz(n); chksiz(csiz); 

//Duplicate Top - Stack=R,R
puts("STKDUP()");
n=stkdup(); chkres(@r,n); chkmem(@r, &r);
updptr(n); chkptr(cptr); updsiz(n); chksiz(csiz); 

//Push String - Stack=S,R,R
puts("STKSTR(S)");
n=stkstr(s); chkres(@s+1,n); chkstr(s);
updptr(n); chkptr(cptr); updsiz(n); chksiz(csiz); 

pause();

//Copy Second to Top - Stack=R,S,R,R
puts("STKOVR()");
n=stkovr(); chkres(@r,n); chkmem(@r, &r);
updptr(n); chkptr(cptr); updsiz(n); chksiz(csiz); 

//Swap Top and Second - Stack=S,R,R,R
puts("STKSWP()");
n=stkswp(s); chkres(@s+1,n); chkstr(s);
chkptr(cptr); chksiz(csiz); 

//Read String - Stack=S,R,R,R
puts("STKTOP(T)"); 
n=stktop(t); chkres(@s+1,n); chkstt(s);
chkptr(cptr); chksiz(csiz); 

//Pop String - Stack=R,R,R
puts("STKPOP(T)"); 
n=stkpop(&t); chkres(@s+1,n); chkstt(s);
updptr(-n); chkptr(cptr); updsiz(-n); chksiz(csiz); 

pause();

//Drop Copy - Stack=R,R
puts("STKDRP()");
n=stkdrp(); chkres(@r,n); pass();
updptr(-n); chkptr(cptr); updsiz(-n); chksiz(csiz); 

//Drop Duplicate - Stack=R
puts("STKDRP()");
n=stkdrp(); chkres(@r,n); pass();
updptr(-n); chkptr(cptr); updsiz(-n); chksiz(csiz); 

//Pop Array - Stack Empty
puts("STKPOP(&T)"); 
n=stkpop(&t); chkres(@r,n); chkmet(@r,t);
updptr(-n); chkptr(cptr); updsiz(-n); chksiz(csiz); 

pause();

//Pop from Empty Stack
puts("STKPOP(&T)");
n=stkpop(&t); chkres(0,n); pass();
chkptr(cptr); chksiz(csiz); 

//Overflow Stack - Stack Empty
puts("STKPSH(255,&T)");
n=stkpsh(255,&t); chkres(0,n); pass();
chkptr(cptr); chksiz(csiz); 

putln("TESTS COMPLETE");

goto exit;


puts("Dropping Swapped Entry off Stack");
puts("stkdrp()");
f=stkdrp(); printf(f,"bytes=%d:");
g=(f==4) ? #TRUE : #FALSE;
psorfl(f & g);
chkptr(&$8016);

