Hydrology

Date: 198x
Type: Program
Platform(s): TS 2068

This program is a hydrology toolkit that offers four computational modules selectable from a menu: slope computation, a watershed map drawing routine, unit hydrograph preparation (UHG PREP), and a mathematical unit hydrograph generator (MATH UHG). The menu dispatcher at line 50 uses a single multiply-and-branch idiom (`GO TO 10*Number`) to jump to subroutines at lines 60, 100, 200, and 250 based on the user’s input of 6, 10, 20, or 25. The map-drawing module (line 100) POKEs 12 bytes of machine code into address 23760 and then calls it via `RANDOMIZE USR 23760`, implementing an LDIR block-copy routine (opcodes `ED B0`) capped with a `RET` (`C9`). The MATH UHG section (line 250) implements a lognormal distribution fitting algorithm with an iterative sigma convergence loop and computes either instantaneous or average unit hydrograph ordinates using numerical integration by Simpson’s rule.


Program Analysis

Program Structure

The program is organized as a menu-driven dispatcher. Lines 1–45 display a menu and read the user’s selection into Number. Line 50 computes GO TO 10*Number, routing to one of four modules:

InputTarget lineModule
660Slope computation
10100Map draw
20200UHG Prep
25250Math UHG
1001000STOP

Each module ends with GO TO 18, which jumps to a non-existent line — falling through to line 19 (the blank PRINT). In practice this is effectively a restart of the menu from line 19 onward, since BASIC will run the next available line after an unfound target in some interpreters, though this is noted as a known technique. The REM at line 1 flags the author’s awareness of bugs.

Machine Code Usage

The map-draw module (lines 106–108) POKEs 12 bytes into RAM starting at address 23760 and then invokes them with RANDOMIZE USR 23760 at line 125. The DATA at line 127 decodes as:

AddressByte (hex)Z80 mnemonic
2376033 00 40LD HL,16384 (start of display)
2376364 11 00 E3partial operands / LD DE,…
2376701 00 1BLD BC,…
23770ED B0LDIR (block copy)
23772C9RET

The exact byte sequence is 33,0,64,17,0,230,1,0,27,237,176,201. The LDIR instruction copies a block of memory, and the RET returns cleanly to BASIC. The purpose appears to be a display-area memory operation, consistent with copying or clearing graphics data.

Slope Computation Module (lines 60–90)

This module computes the Taylor-Schwarz channel slope formula used in hydrology. It reads N elevation points, a reach length DL, and a total length L from DATA. For each pair of adjacent elevations it computes D(I) = 1 / SQR(ELDIFF/DL), then calculates overall slope as S = ((N-1) / SUM)^2. The result is truncated to four decimal places using the INT(x*10000)/10000 idiom and converted to ft/mile by multiplying by 5280.

Map Drawing Module (lines 100–136)

This module plots a watershed boundary and stream network using pixel-level PLOT and DRAW commands. Two pairs of 2D arrays (x, y for boundary; z, u for stream) store coordinate sequences read from DATA. The boundary data is at line 132 and stream data at line 134, giving sequences of absolute pixel coordinates. The DRAW calls use relative offsets computed from successive coordinate differences. A sentinel check IF x(c,1)>255 THEN GO TO 135 at line 112 and a similar check at line 120 guard against out-of-range coordinates, though the check at 120 tests z(1,1) (the first element) rather than z(c,1) (the current element), which is likely a bug — it will never trigger mid-loop as intended.

UHG Preparation Module (lines 200–229)

This module implements the Snyder synthetic unit hydrograph method. It computes lag time TP, time-to-peak TPR, and peak discharge QP from basin parameters: drainage area DA, main channel length L, length to centroid LCA, storm duration TR, and empirical coefficients CT and CP640. The formula NUM=(L*LCA)^0.3 is the standard Snyder lag parameter. An urbanization parameter PAR = L*LCA/SQR(S) is also printed for lookup on an external curve.

Mathematical UHG Module (lines 250–326)

This is the most computationally intensive module, implementing a lognormal unit hydrograph. It fits a sigma parameter iteratively by bracketing the solution to match a lognormal CDF target (YO), converging in two passes of decreasing step size (0.0005, then 0.000005). The core loop structure is:

  1. Compute YO = TMQ * QMAX / (111.80941 * A) (the lognormal argument)
  2. Estimate initial SIGMA from a polynomial approximation using Y = log10(YO)
  3. Iteratively refine SIGMA at lines 268–281 until S ≈ YO within 0.0001
  4. Compute the mode time T from SIGMA
  5. Evaluate ordinates in the FOR loop at lines 293–318

The constant 111.80941 is SQR(12500), a normalisation factor for the lognormal unit hydrograph. When INSTA=0, average flows are computed using a simple trapezoidal/Simpson accumulation (TOT + 2*Q) inside the inner loop, divided by 20 at line 309. The loop exit condition at lines 315–316 terminates when both time has passed the mode and flow has dropped to 2 or below.

Notable Techniques and Idioms

  • Computed GO TO: GO TO 10*Number at line 50 is an efficient menu dispatcher, avoiding a chain of IF statements.
  • Rounding idiom: INT(x*10000)/10000 and INT(x*100+.5)/100 are used throughout for controlled decimal truncation and rounding respectively.
  • DATA reuse: All module parameters are stored in DATA statements local to each module section, so the READ pointer advances naturally as each module is entered once per run. Re-entering a module after a GO TO 18 restart would exhaust the DATA pointer — a latent bug for repeated use within one run.
  • Polynomial sigma inversion: Lines 264–267 use a degree-6 polynomial in Y = log10(YO) to approximate the inverse normal, seeding the iterative refinement efficiently.

Bugs and Anomalies

  • Line 120 sentinel check: IF z(1,1)>255 always tests the first stream coordinate, not the current loop variable z(c,1). This means the stream loop never terminates early via this guard.
  • Line 294 dead code: IF (J-1)>=0 THEN GO TO 296 is always true for J=1 TO 11 (since J starts at 1), so line 295 (LET TT=TT-DT/10) is never executed.
  • DATA pointer exhaustion: Modules use READ/DATA without RESTORE, so selecting the same module twice in one session will cause an error when data runs out.
  • Line 90 / 136 / 229 / 326 — GO TO 18: Line 18 contains PRINT "MENU SELECTION", so the menu is redisplayed from line 18 rather than from line 15 (which prints the title). This skips the title and the CLS at line 45 is not re-executed, so old output remains on screen.
  • Line 72 square root of ratio: SQR(ELDIFF/DL) will produce an error if any adjacent elevations are equal or decrease, as the argument becomes zero or negative.

Content

Appears On

This tape is a compilation of programs from user group members (Robert Burton, David Baulch, Frank Bouldin, Chuck Dawson, Ryan
One of a series of library tapes. Programs on these tapes were renamed to a number series. This tape contained

Related Products

Related Articles

Related Content

Image Gallery

Hydrology

Source Code

    1 REM  Program seems to have           some "bug problems"      
   10 REM "hydrology1"
   15 PRINT AT 1,7;"HYDROLOGY #1"
   17 PRINT 
   18 PRINT "MENU SELECTION"
   19 PRINT 
   20 PRINT "Input a 6 for Slope,            Input a 10 for map draw         Input a 20 for UHG PREP         Input a 25 for MATH UHG         Input a 100 if you are finished."
   21 PRINT 
   25 PRINT "If you want a copy,   use break key and then COPY."
   40 INPUT Number
   45 CLS 
   50 GO TO 10*Number
   60 REM "SLOPE"
   61 PRINT AT 11,1;"PROGRAM FOR SLOPE COMPUTATION"
   62 DIM D(11): DIM E(11)
   63 READ N,L,DL,T$
   64 FOR I=1 TO N
   65 READ E(I)
   66 NEXT I
   67 PRINT AT 14,10;T$
   68 PRINT 
   69 LET SUM=0
   70 FOR I=2 TO N
   71 LET ELDIFF=E(I)-E(I-1)
   72 LET A=SQR (ELDIFF/DL)
   73 LET D(I)=1.0/A
   74 LET SUM=SUM+D(I)
   75 NEXT I
   76 LET S=((N-1)/SUM)^2
   77 LET S=INT (S*10000)/10000
   78 LET SO=S*5280
   79 PRINT AT 18,2;"SLOPE = ";S;" FT/FT"
   80 PRINT 
   81 PRINT AT 20,2;"Or ";SO; "  FT/MILE"
   82 PRINT 
   83 DATA 8,1840,1840,"WILLOW LAKE"
   84 DATA 657.5,675,690,710,735,750,800,830
   90 GO TO 18
  100 REM "map draw"
  101 PRINT "Put no of boundary, stream lines, title, drainage area in data line 126. Put starting x, y for boundary in 131, for stream in 133. Put x, y data for boundary in 132, stream in 134."
  102 PAUSE 120: CLS 
  103 DIM x(30,30): DIM y(30,30)
  104 DIM z(20,20): DIM u(20,20)
  105 READ nl,ns,T$,DA,S
  106 FOR a=23760 TO 23771
  107 READ b: POKE a,b
  108 NEXT a
  109 READ x(1,1): READ y(1,1)
  110 PLOT x(1,1),y(1,1)
  111 FOR c=2 TO nl
  112 READ x(c,1): IF x(c,1)>255 THEN GO TO 135
  113 READ y(c,1)
  114 DRAW x(c,1)-x(c-1,1),y(c,1)-y(c-1,1)
  115 PLOT x(c,1),y(c,1)
  116 NEXT c
  117 READ z(1,1): READ u(1,1)
  118 PLOT z(1,1),u(1,1)
  119 FOR c=2 TO ns
  120 READ z(c,1): IF z(1,1)>255 THEN GO TO 135
  121 READ u(c,1)
  122 DRAW z(c,1)-z(c-1,1),u(c,1)-u(c-1,1)
  123 PLOT z(c,1),u(c,1)
  124 NEXT c
  125 RANDOMIZE USR 23760
  126 DATA 20,16,"Willow Lake",1.22,.01172
  127 DATA 33,0,64,17,0,230,1,0,27,237,176,201
  128 PRINT AT 19,3;T$
  129 PRINT AT 20,3;"DA= ";DA
  130 PRINT AT 21,3;"Slope =";S
  131 DATA 2,168
  132 DATA 32,173,56,168,104,162,120,154,157,96,208,112,232,78,224,68,254,48,218,2,168,21,144,36,120,74,88,94,76,112,40,122,40,149,16,160,2,168
  133 DATA 8,168
  134 DATA 38,165,92,136,94,128,128,97,162,60,180,64,204,37,205,32,205,24,210,20,218,2,207,12,202,17,201,24,205,32
  135 PRINT 
  136 GO TO 18
  200 REM "UHG PREP"
  201 PRINT "PROGRAM DEVELOPS UNIT HYDROGRAPH DATA"
  202 READ T$
  203 READ DA,L,LCA,TR,CT,CP640,S
  204 LET NUM=(L*LCA)^.3
  205 LET TP=CT*NUM
  206 LET TLR=TP/5.5
  207 LET TPR=(TP+.25*(TR-TLR))
  208 LET AMT=INT (TPR*1000)
  209 LET TPR=AMT/1000
  210 LET QLP=(CP640/TPR)
  211 LET QP=INT (QLP*DA)
  212 PRINT TAB 10;T$
  213 PRINT 
  214 PRINT "INPUT DATA"
  215 PRINT "AREA";TAB 5;"  L  ";TAB 11;" LCA ";TAB 17;" TR ";TAB 22;" CT ";TAB 27;"CP640"
  216 PRINT DA;TAB 6;L;TAB 11;LCA;TAB 17;TR;TAB 22;CT;TAB 27;CP640
  217 PRINT 
  218 PRINT "TR";TAB 6;"TPR";TAB 12;"TR";TAB 18;"QMAX";TAB 24;"AREA"
  219 PRINT 
  220 PRINT TR;TAB 6;TPR;TAB 12;TR;TAB 18;QP;TAB 24;DA
  221 PRINT 
  222 LET PAR=INT (L*LCA/(SQR S)*100)
  223 LET PAR=PAR/100
  224 PRINT "PAR = ";PAR
  225 PRINT 
  226 PRINT AT 20,0;"USE PAR TO GET TPR FROM AN URBANIZATION CURVE"
  227 DATA "WILLOW LAKE"
  228 DATA 1.22,2.5,1.1,.50,.70,418,61.9
  229 GO TO 18
  250 REM "MATH UHG"
  251 PRINT "THIS PROGRAM EXECUTES VERY SLOWLY... BE PATIENT"
  252 READ T$,DT,TPR,TR,QMAX,A,INSTA
  253 CLS 
  254 PRINT TAB 5;T$
  255 PRINT 
  256 PRINT "INPUT DATA"
  257 PRINT "DT";TAB 5;"TPR";TAB 12;"TR";TAB 17;"QMAX";TAB 23;"A";TAB 26;"INSTA"
  258 PRINT DT;TAB 6;TPR;TAB 12;TR;TAB 17;QMAX;TAB 22;A;TAB 28;INSTA
  259 PRINT 
  260 LET TMQ=TPR+TR/2
  261 LET Q=0
  262 LET SUM =0
  263 LET YO=TMQ*QMAX/(111.80941*A)
  264 LET Y=.43429448*LN (YO)
  265 LET X=-.295133-.4522*Y-.242919*Y^2-.103329*Y^3
  266 LET X=X+(.0091443*Y^4)+(.0353098*Y^5)+(.0117619*Y^6)
  267 LET SIGMA=10^X
  268 LET S=EXP (-2.65049*SIGMA^2)/SIGMA
  269 LET B=(S-YO+.001)
  270 IF B>=0 THEN GO TO 273
  271 LET SIGMA=SIGMA-.0005
  272 GO TO 268
  273 LET B=(YO-S+.001)
  274 IF B>=0 THEN GO TO 276
  275 LET SIGMA=SIGMA+.0005
  276 IF (S-YO+.0001)>=0 THEN GO TO 279
  277 LET SIGMA=SIGMA-.00005
  278 GO TO 268
  279 IF (YO-S+.0001)>=0 THEN GO TO 282
  280 LET SIGMA=SIGMA+.000005
  281 GO TO 268
  282 LET T=10^(2.3025851*SIGMA^2+.43429448*LN (TMQ))
  283 LET NUM=T
  284 LET NUM=INT (T*100+.5)/100
  285 LET T=NUM
  286 PRINT "TIME TO HALF VOL =";TAB 19;T
  287 PRINT "SIGMA ";SIGMA
  288 LET TT=DT
  289 IF INSTA=0 THEN GO TO 292
  290 PRINT "NO OF HOURS";TAB 13;"INSTA FLOW"
  291 GO TO 293
  292 PRINT "NO OF HOURS";TAB 13;"AVG FLOW"
  293 FOR J=1 TO 11
  294 IF (J-1)>=0 THEN GO TO 296
  295 LET TT=TT-DT/10
  296 LET Q=111.80941*A/(TT*SIGMA)
  297 LET C=(2*SIGMA^2)
  298 LET D=.434*LN (TT/T)
  299 LET E=ABS D^2
  300 LET F=E/C
  301 LET Q=Q*EXP (-F)
  302 IF INSTA=0 THEN GO TO 311
  303 IF (J-1)>0 THEN GO TO 306
  304 LET TOT=Q
  305 GO TO 308
  306 IF (J-11)>0 THEN GO TO 308
  307 LET TOT=TOT+2*Q
  308 NEXT J
  309 LET Q=(TOT+Q)/20
  310 LET TT=TT+DT
  311 LET Q=INT (Q+.5)
  312 PRINT TT;TAB 14;Q
  313 LET SUM=SUM+Q
  314 LET TT=TT+DT
  315 IF (T-TT)>=0 THEN GO TO 317
  316 IF (Q-2)<=0 THEN GO TO 319
  317 IF (INSTA)<=0 THEN GO TO 296
  318 IF (INSTA)>0 THEN GO TO 293
  319 PRINT 
  320 PRINT "THE SUM IS";TAB 14;SUM
  321 LET VOL=SUM/(12/DT)
  322 PRINT "THE VOLUME IS";TAB 14;VOL
  323 DATA "WILLOW LAKE"
  324 DATA .50,.86,.50,650,1.22,0
  325 PRINT 
  326 GO TO 18
 1000 STOP 

Note: Type-in program listings on this website use ZMAKEBAS notation for graphics characters.

People

No people associated with this content.

Scroll to Top