        REM ********** BASIC RUNTIME PACKAGE TEST **********
        REM *** PART 3 OF 3 PARTS (BASRTP14LT3.BAS) ***
        REM COPYRIGHT (C) 1977 SOFTWARE DYNAMICS
        REM ALL RIGHTS RESERVED
        REM 1/29/85 1230

        REM TEST RUNTIME PACKAGE OPCODES
        REM IF INPUT IS NULL, TESTS ALL OPCODES
        REM PROMPTS FOR OPCODE NUMBER (SEE LIST OF OPCODES IN BASIC COMPILER)
        REM REQUIRES I/O DEVICE WITH POSITION$ CAPABILITY AND READ/WRITE
        REM LINES WHICH TEST OPCODE NUMBER XXX...
        REM ARE LINES XXX00 THRU XXX99
        REM EACH OPCODE TEST ASSUMES ALL OTHER OPCODES WORK PROPERLY

        PROGRAM ORIGIN :2F80
        CONCATENATION BUFFER SIZE = 200
        REM FOR OPUPPERCASE, LOWERCASE TESTS

        REM DATA STORAGE
        DIM OPCODE$[10],V[100],S$/:1,"HELLO"/,T$[2]
        DIM U$[258],A[3,5],NEGONE/-1/,T/1/
        DIM BIN257$/:00,:00,:00,:00,:1,:1/,BINPI$/:41,03,14,15,92,65/
        DIM SIX$[6],FORMAT$/"ABC.##D"/,ZEROLEN$[0],ONELEN$[1]
        DIM EPSILON/1E-7/,GPOPF/0/
        DIM DOLLAR$/'$'/,MINUS$/'-'/,HASH$/'##########'/,PERIOD$/'.'/
        DIM CARET$/'^^^^^'/,F$(25)
        DIM TEMP/2/
        DIM INITSTRING$[25]/"STRING CONTENTS"/,GOELNFLAG/0/
        DIM JUNKFILE$/"JUNK"/
        DIM SPACES$[32]/"                                "/
        DIM STRINGARRAY$(10)(20)


50      REM INITIALIZE

        PRINT "*** RUNTIME PACKAGE TEST -- PART III (BASRTP14L) ***"
        PRINT "TESTS EXTENDED OPCODES 0-33"
        PRINT "TO TEST ALL OPCODES, TYPE <CR>"
        PRINT "TO TEST A SPECIFIC OPCODE 'X', TYPE 'X'"
        PRINT "TO TEST ALL OPCODES > X, TYPE '>X'"

        CREATE #T,JUNKFILE$\ ! A SCRATCH PLACE TO READ AND WRITE
        PRINT #T\ ! WRITE SOMETHING FOR SUBR 91 TO READ
        RESTORE #T,0\ !SET UP FOR SUBR 91

90      REM THIS IS WHERE WE ASK...
        ON ERROR GOTO 96
        INPUT "WHICH OPCODE ? " OPCODE$
        IF UPPERCASE$(OPCODE$)="STOP" THEN EXIT
        IF LEN(OPCODE$)=0
        THEN
                FOR OPCODE=0 TO 33
                        PRINT OPCODE;
                        GOSUB 95
                        IF GPOPF<>0 OR GOELNFLAG<>0
                        THEN GPOPF=0\GOELNFLAG=0\GOSUB 99
92              NEXT OPCODE
                PRINT '***DIAGNOSTIC PASS III COMPLETED***'
                EXIT
        ELSE
                IF OPCODE$(1)=ASC(">")
                THEN
                        FOR OPCODE=VAL(RIGHT$(OPCODE$,2))+1 TO 33
                                PRINT OPCODE;
                                GOSUB 95
                                IF GPOPF<>0 OR GOELNFLAG<>0
                                THEN GPOPF=0\GOELNFLAG=0\GOSUB 99
                        NEXT OPCODE
                        PRINT '*** PARTIAL DIAGNOSTIC PASS COMPLETED ***'
                ELSE
                        LET OPCODE=VAL(OPCODE$)
                        GOSUB 95
                        IF GPOPF<>0 OR GOELNFLAG<>0
                        THEN GPOPF=0\GOELNFLAG=0\GOSUB 99
                        PRINT "TEST COMPLETED"
                FI
        FI
        GOTO 90

91      REM SUBROUTINE TO INPUT INTO U$ FROM TEMP FILE
        REM AND REWIND TEMP FILE TO BYTE 0
        RESTORE #T,0
        INPUT #T,U$
        RESTORE #T,0
        RETURN

95      REM BRANCH TO OPCODE TEST SUBROUTINE
        RESTORE #T,0\! THIS SAVES DOING IT EVERYWHERE ELSE
        ON OPCODE+1 GOTO 100,150,200,300,400,500,600,700,800,900,...
&       1000,1100,1200,1300,1400,1500,1600,1700,1800,1900,...
&       2000,2100,2200,2300,2400,2500,2600,2700,2800,2900,...
&       3000,3100,3200,3300
        PRINT "I CAN'T TEST THAT OPCODE IN THIS PASS"\ RETURN


96      REM ERROR TRAP ROUTINE
        IF ELN=310 AND ERR=21 THEN 320
        IF ELN=320 AND ERR=21 THEN 399
        IF ELN=420 AND ERR=14 THEN 499
        IF ELN=510 AND ERR=22 THEN 599
        IF ELN=1710 AND ERR=18 THEN 1799
        IF ELN=930 AND ERR=21 THEN 940
        IF ELN=940 AND ERR=14 THEN 999
        IF ELN=1000 AND ERR=14 THEN 1010
        IF ELN=1350 AND ERR=6 THEN 1360
        IF ELN=1370 AND ERR=6 THEN 1380
        IF ELN=1710 AND ERR=18 THEN 1799
        IF ELN=1805 AND ERR=7 THEN 1810
        IF ELN=1810 AND ERR=7 THEN 1820
        IF ELN=1820 AND ERR=7 THEN 1830
        IF ELN=1830 AND ERR=7 THEN 1840
        IF ELN=1840 AND ERR=7 THEN 1850
        IF ELN=1850 AND ERR=7 THEN 1860
        IF ELN=1860 AND ERR=7 THEN 1899
        IF ELN=2110 AND ERR=15 THEN 2199
        IF ELN=2210 AND ERR=14 THEN X=PI\ GOTO ELN
        IF ELN=2220 AND ERR=13 THEN 2299
        IF ELN=2310 AND ERR=16 THEN 2399
        IF ELN=2410 AND ERR=16 THEN 2499
        IF ELN=3010 AND ERR=19 THEN 3020
        IF ELN=3020 AND ERR=19 THEN 3099
        IF ELN=3110 AND ERR=INT(X+.5) THEN 3120
        IF ELN=3130 AND ERR=15 THEN 3140
        IF ELN=3140 AND ERR=15 THEN 3199
        IF ELN=3210 AND ERR=9 THEN 3220
        IF ELN=3220 AND ERR=9 THEN 3230
        IF ELN=3230 AND ERR=9 THEN 3240
        IF ELN=3240 AND ERR=9 THEN 3299
        IF ELN=96 AND ERR=1 THEN PRINT "ESCAPE BOTHERED ERROR TRAP LINE #!?"\
                                 GOSUB POP 0\
                                 GOTO 90
        REM NOT A VALID TRAP!
97      PRINT "ERROR"; ERR; "OCCURRED DURING OPCODE"; OPCODE; "(LINE ";ELN;")"
        GOSUB POP 0
        GOTO 90

99      PRINT "OPCODE"; OPCODE; "FAILED"\ RETURN

        SUBROUTINE TESTRELATIVEERROR(TESTVALUE,ACTUALVALUE)
        IF ACTUALVALUE=0
        THEN
                RELATIVEERROR=ABS(TESTVALUE-ACTUALVALUE)
        ELSE
                RELATIVEERROR=ABS((TESTVALUE-ACTUALVALUE)/ACTUALVALUE)
        FI
        IF RELATIVEERROR>EPSILON
        THEN PRINT "ERROR TOLERANCE EXCEEDED: ";TESTVALUE;ACTUALVALUE
        IF RELATIVEERROR>MAXRELATIVEERROR
        THEN    MAXRELATIVEERROR=RELATIVEERROR
        EXIT SUBROUTINE
        END

100     REM TEST OPATN
        IF ATN(0)<>0 THEN GOSUB 99
        LET MAXRELATIVEERROR=0
        CALL TESTRELATIVEERROR(ATN(.001),.000999999667)
        CALL TESTRELATIVEERROR(ATN(.01),.00999966687)
        CALL TESTRELATIVEERROR(ATN(.05),.049958395722)
        CALL TESTRELATIVEERROR(ATN(.25),.244978663127)
        CALL TESTRELATIVEERROR(ATN(.45),.422853926133)
        CALL TESTRELATIVEERROR(ATN(.65),.576375220591)
        CALL TESTRELATIVEERROR(ATN(.85),.704494064242)
        CALL TESTRELATIVEERROR(ATN(1.0),.785398163397)
        REM TRY THIS INTEGER CASE, IT HAS BEEN KNOWN TO FAIL!
        CALL TESTRELATIVEERROR(ATN(1),.785398163397)
        CALL TESTRELATIVEERROR(ATN(4.9130581),1.37)
        CALL TESTRELATIVEERROR(ATN(92.6204963),1.56)
        CALL TESTRELATIVEERROR(ATN(1255.7655915),1.57)
        PRINT "ATN TEST VALUES MAX ERROR = "; MAXRELATIVEERROR
        LET MAXRELATIVEERROR=0
        LET X=1E-120
        WHILE X<1000 DO
110             CALL TESTRELATIVEERROR(ATN(X),-ATN(-X))
                LET X=X*(1+RND)
        END
        PRINT "ATN IDENTITY MAX ERROR = "; MAXRELATIVEERROR
        RETURN

150     REM TEST OPSIN
        IF SIN(0)<>0 THEN GOSUB 99
        LET MAXRELATIVEERROR=0
        CALL TESTRELATIVEERROR( SIN(.001),.0009999998333333)
        CALL TESTRELATIVEERROR( SIN(.01), .0099998333341)
        CALL TESTRELATIVEERROR( SIN(.1),.099833416646 )
        CALL TESTRELATIVEERROR( SIN(.3),.2955202066 )
        CALL TESTRELATIVEERROR( SIN(.6),.5646424733 )
        CALL TESTRELATIVEERROR( SIN(.9),.7833269096 )
        CALL TESTRELATIVEERROR( SIN(1.2),.9320390859 )
        CALL TESTRELATIVEERROR( SIN(1.5707963267),1 )
        CALL TESTRELATIVEERROR( SIN(3),.14112000805 )
        PRINT "SIN TEST VALUES MAX ERROR = "; MAXRELATIVEERROR
        LET MAXRELATIVEERROR=0
        FOR X=PI/2 TO PI-.01 STEP .01
160             CALL TESTRELATIVEERROR(SIN(X),SIN(PI-X))
        NEXT X
        FOR X=PI TO 1.5*PI-.01 STEP .01
170             CALL TESTRELATIVEERROR(SIN(X),-SIN(X-PI))
        NEXT X
        FOR X= 1.5*PI TO 2*PI-.01 STEP .01
180             CALL TESTRELATIVEERROR(SIN(X),-SIN(2*PI-X))
        NEXT X
        FOR I=1 TO 10
190             CALL TESTRELATIVEERROR(SIN(.6),SIN(.6+I*2*PI))
                REM SIN(.6)-SIN(.6+2*I*(PI+EPSILON)) == 2*I*EPSILON*COS(.6)
        NEXT I
        FOR X=0 TO PI/2 STEP .01
195             CALL TESTRELATIVEERROR(SIN(X),-SIN(-X))
        NEXT X
        PRINT "SIN IDENTITY TEST MAX ERROR = "; MAXRELATIVEERROR
        RETURN

200     REM TEST OPCOS
        IF COS(0)<>1 THEN GOSUB 99
        LET MAXRELATIVEERROR=0
        CALL TESTRELATIVEERROR( COS(.3),.9553364891 )
        CALL TESTRELATIVEERROR( COS(.6),.8253356149 )
        CALL TESTRELATIVEERROR( COS(.9),.6216099682 )
        CALL TESTRELATIVEERROR( COS(1.2),.3623577544 )
        CALL TESTRELATIVEERROR( COS(1.5707963267),0 )
        PRINT "COS TEST VALUES MAX ERROR = ";MAXRELATIVEERROR
        LET MAXRELATIVEERROR=0
        FOR X=-2*PI TO 2*PI STEP .01
210             CALL TESTRELATIVEERROR(SIN(X)^2+COS(X)^2,1.0)
        NEXT X
        PRINT "COS IDENTITY TEST MAX ERROR = ";MAXRELATIVEERROR
        RETURN

300     REM TEST OPLOG
        LET MAXRELATIVEERROR=0
        CALL TESTRELATIVEERROR( LOG(1),0 )
        CALL TESTRELATIVEERROR( LOG(.001),-6.9077552789 )
        CALL TESTRELATIVEERROR( LOG(.155),-1.8643301620 )
        CALL TESTRELATIVEERROR( LOG(.455),-.7874578600 )
        CALL TESTRELATIVEERROR( LOG(.755),-.2810375297 )
        CALL TESTRELATIVEERROR( LOG(1.355),.3038014543 )
        CALL TESTRELATIVEERROR( LOG(1.655),.5038010088 )
        CALL TESTRELATIVEERROR( LOG(1.955),.6703901934 )
        CALL TESTRELATIVEERROR( LOG(2.718281828),1 )
        PRINT "LOG TEST VALUES MAX ERROR = ";MAXRELATIVEERROR
        LET MAXRELATIVEERROR=0
        FOR X=1 TO 100000 STEP 1000
                FOR Y=.1 TO .9 STEP .1
305                     CALL TESTRELATIVEERROR(LOG(X*Y),LOG(X)+LOG(Y))
                NEXT Y
        NEXT X
        PRINT "LOG IDENTITY TEST MAX ERROR = ";MAXRELATIVEERROR
310     IF LOG(-5)*0=0 THEN GOSUB 99
320     IF LOG(0)*0=0 THEN GOSUB 99
399     RETURN

400     REM TEST OPEXP
        IF EXP(0)<>1 THEN GOSUB 99
        LET MAXRELATIVEERROR=0
        CALL TESTRELATIVEERROR(EXP(.001),1.0010005001)
        CALL TESTRELATIVEERROR(EXP(.151),1.1629966580)
        CALL TESTRELATIVEERROR(EXP(.5),1.6487212707)
        CALL TESTRELATIVEERROR(EXP(1),2.718281828)
        CALL TESTRELATIVEERROR(EXP(1.5),4.4816890703)
        CALL TESTRELATIVEERROR(EXP(2.9),18.1741453694)
        CALL TESTRELATIVEERROR(EXP(5.1),164.0219072999)
        PRINT "EXP TEST VALUES MAX ERROR = "; MAXRELATIVEERROR
        LET MAXRELATIVEERROR=0
        FOR X=0 TO 3 STEP .01
410             CALL TESTRELATIVEERROR(EXP(X),1/EXP(-X))
411             CALL TESTRELATIVEERROR(LOG(EXP(X)),X)
        NEXT X
        PRINT "EXP IDENTITY MAX ERROR = ";MAXRELATIVEERROR
        IF EXP(-(LOG(.1E126)*10))<>0 THEN GOSUB 99
420     IF EXP(LOG(.1E126)*10)*0=0 THEN GOSUB 99
499     RETURN

500     REM TEST OPSQR
        IF SQR(0)<>0 THEN GOSUB 99
        LET MAXRELATIVEERROR=0
        LET I=SQR(1E-125)
        UNTIL I>SQR(1E120) DO
505             CALL TESTRELATIVEERROR( SQR(I*I),I)
                REM (SQR(I)*(1+E))^2-I^2 == 2*I*E
                LET I=I*(1+RND)
        END
        PRINT "SQR TEST MAX ERROR = ";MAXRELATIVEERROR
510     IF SQR(-2)*0=0 THEN GOSUB 99
599     RETURN

600     REM TEST OPRND
        FOR I=0 TO 9\ LET V[I]=0\ NEXT I
        FOR I=0 TO 10000
                LET Y=RND
                IF 0>Y OR Y>1 THEN GOSUB 99
                LET Y=INT(10*Y)
                LET V[Y]=V(Y)+1
        NEXT I
        J=0\ REM COMPUTE CHI-SQUARE STATISTIC
        FOR I=0 TO 9
                LET J=J+(V[I]-1000)*(V(I)-1000)/1000
        NEXT I
        IF 3.33>J OR J>16.92
        THEN GOSUB 99\! FAILED 9 DEGREES OF FREEDOM, 5 TO 95% TEST
        RETURN

700     REM TEST OPABS
        LET X=-100
710     WHILE X<100 DO
                IF X<0 AND ABS(X)<>-X THEN GOSUB 99\ RETURN
                IF X>=0 AND ABS(X)<>X THEN GOSUB 99\ RETURN
                LET X=X+RND
        END
        RETURN

800     REM TEST OPDBG
        IF LEN(OPCODE$)=0 OR OPCODE$(1)=ASC(">")
        THEN PRINT "MUST TEST OPDBG IN MANUAL MODE"
        ELSE DEBUG
        RETURN

900     REM TEST OPOWER
        LET MAXRELATIVEERROR=0
        FOR J=-5 TO +5
                LET K=1
                FOR I=0 TO 30
905                     IF ABS(K)<1E10 AND J^I<>K...
&                               OR ABS(K)>=1E10 AND ABS((J^I-K)/K)>=EPSILON
                        THEN GOSUB 99
                        CALL TESTRELATIVEERROR( J^I,K )
                        K=K*J
                NEXT I
910             IF J=0 THEN CYCLE J
                LET K=1/J
                FOR I=-1 TO -30 STEP -1
915                     IF ABS((J^I-K)/K) >= EPSILON THEN GOSUB 99
                        CALL TESTRELATIVEERROR( J^I,K )
                        K=K/J
                NEXT I
        NEXT J
        PRINT "POWER TEST MAX RELATIVE ERROR = ";MAXRELATIVEERROR
        FOR J=.1 TO 5 STEP .3
                FOR I=.1 TO 20 STEP .2
                        LET K=EXP(I*LOG(J))
920                     IF J^I-K <> 0 THEN GOSUB 99
                NEXT I
        NEXT J
        IF 1^65535<>1 THEN GOSUB 99
923     IF 1^.1E126*0<>0 THEN GOSUB 99
925     IF 2^-800<>0 THEN GOSUB 99
930     IF (-1^2.6)*0 = 0 THEN GOSUB 99
940     IF (0^-1)*0=0 THEN GOSUB 99
999     RETURN

1000   REM TEST OPERRST
        CALL ERRSTTEST(5)
1010    IF OPCODE$='' OR OPCODE$(1)=ASC(">")
        THEN PRINT "SHOULD TEST OPERRST IN MANUAL MODE, ALSO"
        ELSE
                Print "Should print 'Error 14' and then stop"
                ERROR
                GOSUB 99
        FI
1099    RETURN

SUBROUTINE ERRSTTEST(ERRSTARG)
        X=ERRSTARG
        ON ERROR GOTO ERRST1
        IF ERRSTARG/0*0=0 THEN GOSUB 99
        GOSUB 99
ERRST1: IF ERR=14 THEN X=0\ ERROR
        GOSUB 99
        END

1100    REM TEST OPSETSEED
        LET RND=ATN(PI/10)
        LET X=RND
        LET RND=ATN(PI/10)
        IF RND<>X THEN GOSUB 99
        RETURN

1200    REM TEST OPCOL
        PRINT #T
        FOR I=1 TO 255
                IF COL(T)<>I THEN GOSUB 99
                PRINT #T,"*";
        NEXT I
        REM TEST RESTORE RESETS COL(T) = 1
        RESTORE #T,0
        IF COL(T)<>1 THEN GOSUB 99
        RETURN

1300    REM TEST OPGPOP
        PRINT "MUST TEST OPGPOP IN SUBROUTINE, TOO!"
        PRINT "TO MAKE SURE IT DOESN'T AFFECT MAINLINE CODE"
        GOSUB 1310\GOTO 1340
1310    GOSUB 1320\ GOSUB 99\GOSUB POP 0\ GOTO 90
1320    GOSUB 1330\ GOSUB 99\GOSUB POP 0\ GOTO 90
1330    GOSUB POP 2\ RETURN
1340    GOSUB POP 0\ GPOPF=1
1350    RETURN\!SHOULD TRAP
1360    GOSUB POP 0\ GOSUB 1370\ REM PUT A RETURN ADDRESS ON THE STACK
1370    GOSUB POP 2\ REM TEST TOO MANY POPS ... SHOULD TRAP
        GOSUB 99
1380    GPOPF=0
        IF LEN(OPCODE$)=0 THEN 92 ELSE PRINT "TEST COMPLETED"\ GOTO 90

1400    REM TEST OPDAT
        PRINT "CURRENT DATE SHOULD BE: ";DATE$
        RETURN

1500    REM TEST OPTIM
        PRINT "TIME OF DAY IS: ";TIME$
        RETURN

1600    IF NUM$(1.273E2)<>" 127.3" THEN GOSUB 99
        LET X=.0100000000E-126
1610    PRINT #T,X\GOSUB 91
        IF U$<>NUM$(X) THEN GOSUB 99
        X=X*1.19
        IF X>.9999999999E+126/1.19 THEN 1610
        LET X=100
1620    IF X<-100 THEN RETURN
        PRINT #T,X\GOSUB 91
        IF U$<>NUM$(X) THEN GOSUB 99
        LET X=X-1
        GOTO 1620

1700    REM INVENT ALL POSSIBLE NUMBER FORMATS
        FOR LEFTDOLLAR=0 TO 1
            FOR LEFTSIGN=0 TO 1
                FOR LEFTDIGITS=0 TO 10
                    FOR DP=0 TO 1
                        FOR RIGHTDIGITS=1-SGN(LEFTDIGITS) TO (10-LEFTDIGITS)*DP
                            FOR EXPONENT=0 TO 4-LEFTSIGN
                                LET F$=DOLLAR$[1,LEFTDOLLAR] CAT...
&                               MINUS$[1,LEFTSIGN] CAT...
&                               HASH$[1,LEFTDIGITS] CAT...
&                               PERIOD$[1,DP] CAT...
&                               HASH$[1,RIGHTDIGITS]
                                LET X=RND*10^LEFTDIGITS\ REM PICK RANDOM NUMBER TO FORMAT
                                IF LEFTSIGN=1 OR EXPONENT=4
                                THEN LET X=X*SGN(RND-.5)
                                IF EXPONENT>0 AND EXPONENT<>4 AND LEFTDOLLAR<>1
                                THEN
                                        LET F$=F$ CAT CARET$[1,EXPONENT+2]
                                        LET X=X*10^INT(100*RND)
                                FI
                                IF EXPONENT=4 THEN LET F$=F$ CAT "-"
                                PRINT #T,USING F$,X\ GOSUB 91\! OUTPUT RANDOM NUMBER
                                IF U$<>NUMF$(F$,X)
                                THEN GOSUB 99\ PRINT F$;X;"!";NUMF$(F$,X);"<>";U$;"!"\ RETURN
                            NEXT EXPONENT
                        NEXT RIGHTDIGITS
                    NEXT DP
                NEXT LEFTDIGITS
            NEXT LEFTSIGN
        NEXT LEFTDOLLAR
        REM WHEW!!!!
        IF NUMF$("$##.##-",PI)<>" $3.14 " THEN GOSUB 99
1710    LET U$=NUMF$("##.##-.",1)\ GOSUB 99
1799    RETURN

1800    REM TEST OPVAL
        IF VAL("       0A")<>0 THEN GOSUB 99
        IF VAL("-0.")<>0 THEN GOSUB 99
        IF VAL("00.12.")<>.12 THEN GOSUB 99
        IF VAL("-96.13")<>-96.13 THEN GOSUB 99
        IF VAL(".00013E+4.")<>1.3 THEN GOSUB 99
        IF VAL("1.0E-27")<>1E-27 THEN GOSUB 99
        IF VAL("-.9999999999E126")<>-.9999999999E126 THEN GOSUB 99
        IF VAL(":239G")<>:239 THEN GOSUB 99
        LET U$="    -27.2E-1"
        IF VAL(U$)<>-2.72 THEN GOSUB 99
        IF VAL(U$[1,9])<>-27.2 THEN GOSUB 99
        IF VAL("1E")<>1 THEN GOSUB 99
        IF VAL("2.7E-")<>2.7 THEN GOSUB 99
        IF VAL("-.00042E+:3")<>-.00042 THEN GOSUB 99
1805    IF VAL(":7AACD")*0=0 THEN GOSUB 99
1810    IF VAL("1E200")*0=0 THEN GOSUB 99
1820    IF VAL("E1")*0=0 THEN GOSUB 99
1830    IF VAL("")*0=0 THEN GOSUB 99
1840    IF VAL(":")*0=0 THEN GOSUB 99
1850    IF VAL("   -")*0=0 THEN GOSUB 99
1860    IF VAL(".E2")*0=0 THEN GOSUB 99
1899    RETURN

1900    REM TEST OPTAN
        IF TAN(0)<>0 THEN GOSUB 99
        LET MAXRELATIVEERROR=0
        CALL TESTRELATIVEERROR( TAN(.000999999667), .001)
        CALL TESTRELATIVEERROR( TAN(.00999966687), .01)
        CALL TESTRELATIVEERROR( TAN(.049958395722), .05)
        CALL TESTRELATIVEERROR( TAN(.244978663127), .25)
        CALL TESTRELATIVEERROR( TAN(.422853926133), .45)
        CALL TESTRELATIVEERROR( TAN(.576375220591), .65)
        CALL TESTRELATIVEERROR( TAN(.704494064242), .85)
        CALL TESTRELATIVEERROR( TAN(.785398163397), 1)
        CALL TESTRELATIVEERROR( TAN(1.37),4.9130581)
        CALL TESTRELATIVEERROR( TAN(1.56),92.6204963)
        CALL TESTRELATIVEERROR( TAN(1.57),1255.7655915)
        PRINT "TAN VALUE TEST MAX ERROR = "; MAXRELATIVEERROR
        LET MAXRELATIVEERROR=0
        FOR X=.01 TO PI/2-.05 STEP .01
1920            CALL TESTRELATIVEERROR(TAN(X),-TAN(-X))
        NEXT X
        PRINT "TAN IDENTITY TEST MAX ERROR = ";MAXRELATIVEERROR
        REM *** TAN(PI/2) DOESN'T CAUSE ERROR SINCE PI/2 IS NOT ACCURATE ENOUGH  ***
        RETURN

2000    REM TEST OPPOLY
        REM OPPOLY NOT GENERATED BY COMPILER
        REM IF ALL TRANSCENTDENTALS PASS, OPPOLY MUST WORK
        RETURN

2100    REM TEST OPHEX
        IF HEX$(:B972)<>":B972" THEN GOSUB 99
        FOR I=0 TO 65535
                IF VAL(HEX$(I))<>I THEN GOSUB 99
        NEXT I
2110    IF HEX$(1.1)="" OR 1=1 THEN GOSUB 99
2199    RETURN

2200    REM TEST OPGOELN
        LET X=0
        PRINT "Should print 'Got back from error trap routine'"
2210    IF X<>PI THEN LET X=X/0
        PRINT "Got back from error trap routine"
2220    GOTO ELN\ GOSUB 99
2299    RETURN

2300    REM TEST OPUPPERC
        FOR I=0 TO 127
                LET U$(I+1)=I
        NEXT I
        LET LEN(U$)=128
        LET U$=UPPERCASE$(U$)
        FOR I=0 TO 127
                IF I<ASC('A')+32 OR I>ASC('Z')+32
                THEN    IF U$(I+1)<>I THEN GOSUB 99 FI
                ELSE    IF U$(I+1)<>I-32 THEN GOSUB 99
        NEXT I
        REM CHECK FOR CATBUF OVERFLOW CORRECTLY DETECTED
        LET LEN(U$)=MAXLEN(U$)
2310    LET U$=UPPERCASE$(U$)
2399    RETURN

2400    REM TEST OPLOWRC
        FOR I=0 TO 127
                LET U$(I+1)=I
        NEXT I
        LET LEN(U$)=128
        LET U$=LOWERCASE$(U$)
        FOR I=0 TO 127
                IF I<ASC('A') OR I>ASC('Z')
                THEN    IF U$(I+1)<>I THEN GOSUB 99 FI
                ELSE    IF U$(I+1)<>I+32 THEN GOSUB 99
        NEXT I
        REM CHECK FOR CATBUF OVERFLOW CORRECTLY DETECTED
        LET LEN(U$)=MAXLEN(U$)
2410    LET U$=UPPERCASE$(U$)
2499    RETURN

2500    REM TEST OPEXIT
        IF LEN(OPCODE$)=0 OR OPCODE$(1)=ASC(">")
        THEN PRINT "MUST TEST OPEXIT IN MANUAL MODE"
        ELSE
                PRINT "Should EXIT properly."
                EXIT
        FI
        RETURN

2600    REM TEST OPLENVECTOR
        IF 100<>LEN(V) THEN GOSUB 99
        CALL TESTOPLENVECTORONPARAMETER(V)
        RETURN

SUBROUTINE TESTOPLENVECTORONPARAMETER(TESTOPLENVECTORARG[*])
        IF LEN(TESTOPLENVECTORARG)<>100 THEN GOSUB 99
        EXIT SUBROUTINE
END

2700    REM TEST OPROWSARRAY
        IF 3<>ROWS(A) THEN GOSUB 99
        CALL TESTOPROWSARRAYONPARAMETER(A)
        RETURN

SUBROUTINE TESTOPROWSARRAYONPARAMETER(TESTOPROWSARRAYARG[*,*])
        IF ROWS(TESTOPROWSARRAYARG)<>3 THEN GOSUB 99
        EXIT SUBROUTINE
END

2800    REM TEST OPCOLSARRAY
        IF 5<>COLUMNS(A) THEN GOSUB 99
        CALL TESTOPCOLSARRAYONPARAMETER(A)
        RETURN

SUBROUTINE TESTOPCOLSARRAYONPARAMETER(TESTOPCOLSARRAYARG[*,*])
        IF COLUMNS(A)<>5 THEN GOSUB 99
        EXIT SUBROUTINE
END

2900    REM TEST OPFUNRET
        DEF OPFUNRET1(OPFUNRETARG)=12
        DEF OPFUNRET2$(OPFUNRETARG1)="HELL" CAT "O"
        REM MUST TEST CONTEXT BLOCK POP
        IF 12<>OPFUNRET1(0) THEN GOSUB 99
        IF "HELLO"<>OPFUNRET2$(0) THEN GOSUB 99
        RETURN

3000    REM TEST OPCHR
        FOR I=0 TO 255
                IF I<>CHR$(I)[1] THEN GOSUB 99
        NEXT I
        IF "A"<>CHR$(ASC("A")+.2) THEN GOSUB 99
        IF "B"<>CHR$(ASC("A")+.5) THEN GOSUB 99
        IF "B"<>CHR$(ASC("A")+.999) THEN GOSUB 99
3010    LET U$=CHR$(256)\ GOSUB 99
3020    LET U$=CHR$(-1)\ GOSUB 99
3099    RETURN

3100    REM TEST OPERRCAUSE
        FOR I=1 TO 100
                LET X=RND*65535
3110            ERROR X
                GOSUB 99
3120    NEXT I
3130    ERROR -1\ GOSUB 99
3140    ERROR 65536\ GOSUB 99
3199    RETURN

3200    REM TEST OPSSA
        FOR I=1 TO LEN(STRINGARRAY$)
3201            LET STRINGARRAY$(I)=NUMF$('##',I)
        NEXT I
        FOR J=LEN(STRINGARRAY$) TO 1 STEP -1
3202            IF NUMF$('##',J)<>STRINGARRAY$(J) THEN GOSUB 99
        NEXT J
        REM TEST STRING ARRAY COMPONENTS ARE ALL INDEPENDENT
        FOR I=1 TO LEN(STRINGARRAY$)
3203            LET LEN(STRINGARRAY$(I))=I
        NEXT I
        FOR I=1 TO LEN(STRINGARRAY$)
3204            IF LEN(STRINGARRAY$(I))<>I THEN GOSUB 99
        NEXT I
        REM TEST ROUNDING OF SUBSCRIPTS
        FOR I=LEN(STRINGARRAY$)+.49999 TO 1 STEP -1
3205            IF LEN(STRINGARRAY$(I))<>INT(I) THEN GOSUB 99
        NEXT I
3207    REM TEST STRING ARRAY ELEMENTS ARE PASSED PROPERLY AS ARGUMENTS
        FOR I=1 TO LEN(STRINGARRAY$)
                CALL OPSSATEST1(STRINGARRAY$(I))
        NEXT I
3209    REM TEST STRING ARRAY IS PASSED PROPERLY AS ARGUMENT
        CALL OPSSATEST2(STRINGARRAY$)
3210    REM TEST SUBSCRIPT OUT OF RANGE ERROR
        LET U$=STRINGARRAY$(-1)\GOSUB 99
3220    LET U$=STRINGARRAY$(0)\GOSUB 99
3230    LET U$=STRINGARRAY$(LEN(STRINGARRAY$)+1)\GOSUB 99
3240    REM TEST OVERFLOW IN MULTIPLY CALLED BY OPSSA
        LET U$=STRINGARRAY$(65535)\ GOSUB 99
3299    RETURN

SUBROUTINE OPSSATEST1(OPSSATEST1$)
        IF OPSSATEST1$<>STRINGARRAY$(I) THEN GOSUB 99
        RETURN SUBROUTINE
END

SUBROUTINE OPSSATEST2(OPSSATEST2$[*])
        IF LEN(OPSSATEST2$)<>LEN(STRINGARRAY$) THEN GOSUB 99
        FOR I=1 TO LEN(OPSSATEST2$)
                IF STRINGARRAY$(I)<>OPSSATEST2$[I] THEN GOSUB 99
        NEXT I
        RETURN SUBROUTINE
END


3300    REM TEST OPSAINIT
        IF LEN(STRINGARRAY$)<>10 THEN GOSUB 99
        FOR I=1 TO LEN(STRINGARRAY$)
3310            IF MAXLEN(STRINGARRAY$(I))<>20 THEN GOSUB 99
        NEXT I
        RETURN

        END
