i = 99
DIM UT(i), UP(i), SUX(i)
SCREEN 9
WIDTH 80, 43
delay = 500
QU = 10      'Quantum time units per second
NU = 40      'Number of UNITS
PEi = 30     'Packet Period
PLi = 1      'Packet Length
TTi = 480    'Total TIme
DO
CLS
PRINT "APRS UNPROTO Packet Simulator Program,  SIMULATE.bas version 1.0"
PRINT
PRINT
PRINT
PRINT "This program simulates the performance of a given number of Packet units on"
PRINT "a simplex packet channel with no digipeater.  The preformance criteria are:"
PRINT
PRINT "  Number of units"
PRINT "  Nominal period between packets (PER = PER + RND(x)"
PRINT "  Packet Length"
PRINT "  Total time of simulation"
PRINT
PRINT "The numeric data show the STATION number, the TIME of the next transmission"
PRINT "and the current PERIOD in seconds.  If you choose more than 40 stations, this"
PRINT "data will not fit on the screen, so it is not displayed..."
PRINT
PRINT "SIMULATE.bas displays the number of stations vertically, and the number of"
PRINT "packets transmitted horizontally.  The BLUE boxes represent packets"
PRINT "transmitted.  If the packet is successful without collisions, then a GREEN"
PRINT "green box is added to that row and the packet turns yellow."
PRINT
PRINT "If all the rows turn green in the given time period, then you have 100%"
PRINT "communication success.  When 100% is reached, the simulation stops, otherwise"
PRINT "it runs for the given time period.  The number of green boxes per row,"
PRINT "shows the redundancy required to achieve that measure of success.  "
PRINT
PRINT "Run the simulation several times for your chosen project.  The results will"
PRINT "be different each time, but will tend to indicate an overall performance."
PRINT
PRINT "WARNING:  This program is based on TWO specific assumptions:"
PRINT ""
PRINT "   1)  That stations BEGIN transmitting randomly within the given PERIOD."
PRINT "   2)  It assumes ONLY one form of RETRY PERIODICITY calculation."
PRINT
PRINT "EXTRAPOLATING these results to any other conditions may yield SIGNIFICANTLY"
PRINT "different results!"
PRINT
PRINT
PRINT "Enter all times in seconds"
PRINT
PRINT
PRINT "Enter number of units or Q to quit.  ("; NU; ")"; : INPUT a$
PRINT : IF a$ <> "" THEN NU = VAL(a$)
PRINT "Enter nominal packet period ("; PEi; ")"; : INPUT a$
PRINT : IF a$ <> "" THEN PEi = VAL(a$)
PRINT "Enter Packet Length in Seconds ("; PLi; ")"; : INPUT a$
PRINT : IF a$ <> "" THEN PLi = VAL(a$)
PRINT "Enter Total time of simulation ("; TTi; ")"; : INPUT a$
PRINT : IF a$ <> "" THEN TTi = VAL(a$)
PE = PEi * QU           'Convert all time units to quantum units
PL = PLi * QU
TT = TTi * QU
TS = INT(TT / 502) + 1                     'Time Scale Horizontal
SV = INT(350 / NU): IF SV > 8 THEN SV = 8  'Scale Factor Vertical
CLS : T = 0: pct = 0: All = 0
PRINT "STN TIME PRD GOOD   STATIONS ="; NU; "  PERIOD ="; PEi; "  LENGTH ="; PLi; "       TIME ="
LOCATE 43, 1: PRINT "Hit S for Slower, F for Faster, Space Bar to PAUSE, and Q to Quit......";
LOCATE 2, 1
FOR i = 1 TO NU:
    UT(i) = INT(PE * RND(i)): REM j = RND(i)
    UP(i) = PE
    SUX(i) = 0
    IF NU < 43 THEN GOSUB PrintI
NEXT i: LINE (138, 1 * SV)-(138, (NU + 1) * SV), 14
TX = 0: JE = 0
DO UNTIL T = TT + 1 OR All
   LOCATE 1, 1
   T = T + 1
   LOCATE 1, 75: PRINT INT(T / QU)
   None = -1
   FOR i = 1 TO NU
       IF T >= UT(i) THEN         'It is transmitting
          None = 0
          LINE (138 + T / TS, i * SV)-(138 + T / TS, (i + 1) * SV), 9
          IF TX = 0 THEN TB = T
          IF TX = 0 OR TX = i THEN TX = i ELSE TX = 9999: TB = 0
          IF T >= UT(i) + PL THEN 'Time to stop packet
             UP(i) = UP(i) + INT(PE * RND(TIMER))
             REM UP(i) = PE + INT(PE * RND(TIMER))
             UT(i) = UT(i) + UP(i)
             JE = i
             IF NU < 43 THEN LOCATE i + 1, 1: GOSUB PrintI
          END IF
       END IF
   NEXT i
   IF JE AND TX = JE THEN
      SOUND 3000, .1
      REM The one ending is the same as the one beginning
      LINE (138 + TB / TS, TX * SV)-(138 + T / TS, (TX + 1) * SV), 14, BF
      SUX(JE) = SUX(JE) + 1
      All = -1
      FOR j = 1 TO NU
          LINE (106, SV * j)-(106 + 5 * SUX(j), SV * (j + 1) - 1), 10, BF
          IF SUX(j) = 0 THEN All = 0
      NEXT j
      TX = 0
   
   END IF
   IF None THEN TX = 0
   a$ = INKEY$
   IF a$ = " " THEN DO UNTIL INKEY$ <> "": LOOP
   IF UCASE$(a$) = "F" THEN delay = delay / 2: IF delay < 10 THEN delay = 10
   IF UCASE$(a$) = "S" THEN delay = delay * 2
   IF UCASE$(a$) = "Q" THEN EXIT DO
   FOR i = 1 TO delay: a = a + a + a + a + a: NEXT i
LOOP
FOR i = 1 TO NU
    IF SUX(i) THEN pct = pct + 1
NEXT i
LOCATE 42, 1: PRINT "Success rate"; INT(100 * pct / NU); "%";
LOCATE 43, 1: PRINT "in "; INT(T / QU); " seconds.";
IF All THEN LINE (0, 324)-(150, 349), 12, B
LOCATE 43, 17: PRINT SPACE$(18);
INPUT "Hit ENTER for another run, or Q to quit"; a$
IF UCASE$(a$) = "Q" THEN EXIT DO
LOOP
SYSTEM

PrintI: PRINT MID$(STR$(i), 2); TAB(4); INT(UT(i) / QU); TAB(9); INT(UP(i) / QU)
        RETURN

