PROGRAM SMITH

   SET MODE "LACEHIGH4"
   
   OPEN #1 : SCREEN .2, 1, 0, 1
   
   CALL Generate_Smith_Chart
   
   LET r = 25
   LET x = -15
   SET COLOR "RED"
   CALL SmithPlot(r,x)
   
   WINDOW #0
   CALL PrintZ(r, x, 1, 1)

END



SUB Generate_Smith_Chart

    LET XLeft   =  2
    LET XRight  =  0
    LET YBottom = -1
    LET YTop    =  1
    LET XMid    =  1
    LET YMid    =  0
    SET WINDOW XLeft, XRight, YBottom, YTop


    ! Draw outside circle, real axis, and center
    !
    PLOT XLeft,YMid; XRight,YMid
    BOX CIRCLE XLeft, XRight, YBottom, YTop
    BOX CIRCLE XMid-.02, XMid+.02, YMid-.02, YMid+.02

    DO
       READ RN                    ! Radius number
       LET RealRadius = 1/(1+RN)
       BOX CIRCLE 2*RealRadius,0,-RealRadius,RealRadius
       LET ImagRadius = 1/RN
       CALL X_Arc(RN)

    LOOP until end data

    DATA .2, .5, 1, 2, 5

END SUB



SUB X_Arc(XRAD)

    CALL Draw_X_Arc(XRAD,1)
    CALL Draw_X_Arc(XRAD,-1)

END SUB



SUB Draw_X_Arc(XRAD, SIGN)

    OPTION ANGLE degrees

    LET dAngle = 1/XRAD
    LET Angle  = -90
    LET x =  XRAD*COS(Angle)
    LET y = SIGN*(XRAD+XRAD*SIN(Angle))
    PLOT x,y;
    DO
       LET Angle = Angle+dAngle
       LET x = XRAD*COS(Angle)
       LET y = SIGN*(XRAD+XRAD*SIN(Angle))
       IF ((x-1)^2 + y^2 ) > 1 then
          LET Angle = Angle-dAngle              ! Go back one step
          LET dAngle = dAngle / 10              ! Reduce step size
          IF dAngle < .01/XRAD THEN EXIT DO
       ELSE 
          PLOT x,y; 
       END IF
    LOOP
    PLOT

END SUB



SUB SmithPlot(Rs,Xs)

    OPTION ANGLE degrees

    ! We don't handle negative resistances
    IF Rs < 0 then EXIT SUB

    ! Normalize to 50 Ohms
    LET Rn = Rs/50
    LET Xn = Xs/50

    ! Radii of reactive and resistive phasors
    IF Xn = 0 then
       LET RADX = 1000000
    ELSE
       LET RADX = 1/Xn
    END IF
    IF Rn = -1 then
       LET RADR = 1000000
    ELSE
       LET RADR = 1/(1+Rn)
    END IF

    ! Angle of reactive phasor and end coordinates
    LET Theta = 2 * ATN(RADR/RADX)
    LET x = sqr(RADX^2 - (RADX * COS(Theta))^2)
    LET y = RADX - RADX * COS(Theta)

    ! Display cross for single color displays
    PLOT x-.025,y+.025; x+.025,y-.025
    PLOT x-.025,y-.025; x+.025,y+.025

END SUB



SUB PrintZ(r, x, ver, hor)

    SET CURSOR ver, hor
    PRINT REPEAT$(" ", 20)
    SET CURSOR ver, hor
    PRINT "Z = ";
    PRINT STR$(r);
    IF x < 0 then
       PRINT " -j";
    ELSE
       PRINT " +j";
    END IF
    PRINT STR$(ABS(x))

END SUB

