--- title: "EE1 Filter Design" id: 51878 type: "computer_media" slug: "ee1-filter-design" url: "http://localhost/computer_media/ee1-filter-design/" markdown_url: "http://localhost/computer_media/ee1-filter-design.md" published_at: "2023-08-16T01:42:19+00:00" modified_at: "2026-04-03T07:59:15+00:00" author: "David Anderson" featured_image: url: "http://localhost/wp-content/uploads/2019/02/20230809-041332.jpg" excerpt: "Design active band-pass, low-pass, and high-pass filters with Butterworth or Chebyshev approximations, then plot the frequency response on screen." category: - name: "Archived Media" slug: "archived-media" taxonomy: "category" url: "http://localhost/category/archived-media/" post_tag: - name: "American Micro Products" slug: "american-micro-products-inc" taxonomy: "post_tag" url: "http://localhost/tag/american-micro-products-inc/" - name: "Downloadable" slug: "downloadable" taxonomy: "post_tag" url: "http://localhost/tag/downloadable/" - name: "TS 1000" slug: "ts1000" taxonomy: "post_tag" url: "http://localhost/tag/ts1000/" model: - name: "Timex/Sinclair 1000" slug: "ts-1000" taxonomy: "model" url: "http://localhost/model/ts-1000/" genre: - name: "Electronics" slug: "electronics" taxonomy: "genre" url: "http://localhost/type/electronics/" media_type: "Cassette" download_url: "https://archive.org/download/timex-sinclair-software-archive/EE1 Filter Design (1983)(American Micro Products)(US)(TS1000)(Cassette.zip" mediadate: "1983" producer_company: - id: 10643 title: "American Micro Products, Inc" type: "company" url: "http://localhost/company/american-micro-products-inc/" images: - url: "http://localhost/wp-content/uploads/2023/08/SCR-20260402-pkqa.png" - url: "http://localhost/wp-content/uploads/2023/08/SCR-20260402-pkmv.png" related_products: - id: 12423 title: "E.E. 1 Filter Design" type: "product" url: "http://localhost/product/e-e-1-filter-design/" media_type_tags: "Electronics" --- # EE1 Filter Design EE1 Filter Design is an active filter design calculator that computes component values for band-pass, low-pass, and high-pass second-order active filters using an operational amplifier topology. For low-pass and high-pass designs, the user selects from four filter approximations — Butterworth, 0.1 dB Chebyshev, 0.5 dB Chebyshev, and 1 dB Chebyshev — with the corresponding pole coefficients stored in arrays T() and H(). Given user-supplied cutoff frequency, voltage gain, and capacitor values, the program solves for resistor values R1 through R4 using standard active filter synthesis equations. The program also includes a frequency-response plotting routine that computes gain in decibels (using the natural log converted to base-10) across 50 points and scales the results to fit the screen using PLOT statements. *** ## Program Analysis ### Program Structure The program is organized as a menu-driven application with distinct sections for each filter type and shared subroutines. Control flow is governed by the variable `P$`, which holds the menu selection (“1” for band-pass, “2” for low-pass, “3” for high-pass), and is consulted throughout shared subroutines to select the appropriate transfer function branch. | Line Range | Function | | --- | --- | | 8–32 | Initialization: array allocation, Chebyshev/Butterworth coefficient tables | | 90–360 | Main menu | | 400–710 | Band-pass filter design | | 720–1040 | Low-pass filter design | | 1100–1210 | Plot menu (frequency vs. W/W0) | | 1220–1340 | Frequency-domain plot setup | | 1500–1690 | Subroutine: transfer function evaluation (VV in dB) | | 2000–2240 | High-pass filter design | | 2300–2410 | Normalized W/W0 plot | | 3000–4250 | Graph labeling subroutines | | 5000–5480 | Logon/splash screen | | 5500–5510 | Error message: band width must be positive | | 8000–8230 | Frequency-sweep plot routine | | 9200–9370 | Filter approximation selection (sets A, B coefficients) | | 9400–9850 | Plot axis drawing | | 9900–9961 | Utility subroutines (keypress wait, error clear) | | 9990–9995 | SAVE and RUN | ### Filter Approximation Coefficients Arrays `T()` and `H()` (lines 23–30) store the second-order polynomial coefficients (a and b) for four filter approximations. These correspond to the standard normalized denominator polynomial s² + As + B for each approximation type. | Index | Type | A (T) | B (H) | | --- | --- | --- | --- | | 1 | Butterworth | √2 ≈ 1.41421 | 1 | | 2 | 0.1 dB Chebyshev | 2.37209 | 3.31329 | | 3 | 0.5 dB Chebyshev | 1.42562 | 1.5162 | | 4 | 1 dB Chebyshev | 1.09773 | 1.01251 | ### Transfer Function Evaluation The subroutine at line 1500 computes the gain in decibels at a given frequency `I`. It branches on `P$` to apply the correct transfer function for band-pass (lines 1630–1670), low-pass (lines 1570–1590), or high-pass (lines 1530–1560). The complex numerator and denominator are split into real parts `X` and imaginary parts `Y`, and the magnitude is converted to dB at line 1680 using the identity 20·log₁₀(|H|) = 20·ln(|H|)/ln(10). ### Plot Routine The plotting routine at line 8000 samples the transfer function at 50 equally spaced frequency points between `SF` (start frequency) and `EF` (end frequency), storing results in array `G()`. It then finds the minimum (`Y0`) and maximum (`Y1`) gain values (lines 8080–8130), normalizes the data into array `O()`, and scales with `SCA=29/Y2` to map the dynamic range to 29 pixel columns. PLOT statements at line 8210 draw each point. The W/W0 normalized plot at line 2300 uses a logarithmic frequency sweep: `I=10^(L-2)*WC/(2*PI)` for L from 1 to 3 in steps of 2/50, covering two decades. ### Key BASIC Idioms and Techniques - The string array `Z$(11,13)` acts as a string table for menu labels and separators, avoiding repeated string literals. - `Y$(1)="ENTER "` and `Y$(2)=" "` (spaces) are used to overwrite prompts after input by reprinting the same screen position with blanks — a common screen-editing trick in lieu of line clearing. - The INKEY$ debounce pattern at lines 290–296 and 9280–9310 first waits for a key to be released (`IF INKEY$<>"" THEN GOTO`), then waits for a new keypress, preventing auto-repeat artifacts. - FAST/SLOW bracketing (lines 560/675, 2301) is used to accelerate computation-heavy sections while restoring display output for interactive prompts. - The variable `V$` set in the plot menu (line 1175) is later tested throughout the plotting and labeling subroutines to distinguish frequency-axis from W/W0-axis plots. ### High-Pass Filter Code Path Anomaly The high-pass filter section (line 2000) redirects to line 760 (the low-pass input sequence) via `GOTO 760` at line 2040, sharing the input routine. After capacitor input at the low-pass line 845, a check `IF P$="3" THEN GOTO 2050` is intended to divert to the high-pass computation. However, line 2050 does not exist in the listing; execution would fall through to line 850 (the C1 input for low-pass). This is a bug in the high-pass code path — the high-pass resistor formulas at lines 2090–2140 are unreachable under normal execution. ### Screen Coordinate System The axis-drawing subroutine at line 9400 uses both character-cell `PRINT AT` positioning and pixel-level `PLOT` statements. The horizontal axis is drawn as a row of block graphic characters at row 14 (line 9410), while tick marks are placed with `PLOT` at pixel coordinates. The graph plots data points starting at pixel column 9 (line 8210: `PLOT 8+I, ...`), with the vertical offset of 14 pixels providing a baseline above the axis line. ### Logon Subroutine The GOSUB at line 8 calls the logon routine at line 5000 before any initialization. This routine allocates a separate `DIM O$(2,29)` array locally (which shadows the numeric `O()` array declared later at line 32), displays a company name in both normal and inverse video by iterating character by character, and prints location and copyright text. The character-by-character print loop (lines 5040–5060) prints each character of the string individually at successive column positions, creating an animated reveal effect. ## Source Code ``` 8 GOSUB 5000 10 DIM Z$(11,13) 20 DIM Y$(2,6) 21 DIM T(4) 22 DIM H(4) 23 LET T(1)=SQR 2 24 LET T(2)=2.37209 25 LET T(3)=1.42562 26 LET T(4)=1.09773 27 LET H(1)=1 28 LET H(2)=3.31329 29 LET H(3)=1.5162 30 LET H(4)=1.01251 31 DIM G(55) 32 DIM O(55) 90 CLS 100 PRINT AT 4,14;"MENU" 110 PRINT AT 5,14;"''''''''" 120 PRINT AT 7,2;"%S%E%L%E%C%T% %O%P%T%I%O%N%:" 130 LET Z$(1)="BAND PASS" 140 LET Z$(2)="LOW PASS" 150 LET Z$(3)="HIGH PASS" 160 LET Z$(4)="''''''''''''''''''" 170 LET Z$(5)="FREQUENCY" 180 LET Z$(6)="CENTER FREQ." 190 LET Z$(7)="BAND WIDTH" 200 LET Z$(8)="VOLTAGE GAIN" 210 LET Z$(9)="C IN FARADS" 214 LET Z$(10)="C1 IN FARADS" 216 LET Z$(11)=" = ?" 220 LET Y$(1)="ENTER " 230 LET Y$(2)=" " 240 LET A=9 250 FOR I=1 TO 3 260 PRINT AT A,10;INT (I);" = ";Z$(I) 270 LET A=A+2 280 NEXT I 282 PRINT AT A,10;"4 = END" 285 PRINT AT 7,2;"SELECT OPTION:" 290 IF INKEY$<>"" THEN GOTO 300 294 PRINT AT 7,2;"%S%E%L%E%C%T% %O%P%T%I%O%N:" 296 GOTO 285 300 LET P$=INKEY$ 310 IF P$="1" THEN GOTO 400 320 IF P$="2" THEN GOTO 720 330 IF P$="3" THEN GOTO 2000 340 IF P$="4" THEN STOP 350 PRINT AT 20,0;"**INVALID ENTRY, TRY AGAIN**" 360 GOTO 290 400 REM ****BAND PASS**** 405 CLS 410 PRINT AT 1,11;Z$(1) 420 PRINT AT 2,11;Z$(4) 430 PRINT AT 4,0;Y$(1);Z$(6);Z$(11) 440 INPUT F0 445 PRINT AT 4,0;Y$(2);TAB 22;F0 450 GOSUB 9960 451 IF F0>0 THEN GOTO 460 452 GOSUB 9950 454 GOTO 430 460 PRINT AT 6,0;Y$(1);Z$(7);Z$(11) 470 INPUT BW 471 GOSUB 9960 480 PRINT AT 6,0;Y$(2);TAB 22;BW 482 IF BW>0 THEN GOTO 490 484 GOSUB 5500 486 GOTO 460 490 PRINT AT 8,0;Y$(1);Z$(8);Z$(11) 500 INPUT K 505 GOSUB 9960 510 PRINT AT 8,0;Y$(2);TAB 22;K 512 IF K>=1 THEN GOTO 520 514 PRINT AT 18,0;" **GAIN MUST BE >= ONE**" 516 GOTO 490 520 PRINT AT 10,0;Y$(1);Z$(9);Z$(11) 530 INPUT C1 540 PRINT AT 10,0;Y$(2);TAB 22;C1 560 FAST 580 LET Q=F0/BW 590 LET W0=2*PI*F0 600 LET R1=2*Q/(C1*W0*K) 610 LET R2=2*Q/(C1*W0*(-1+SQR ((K-1)**2+8*Q**2))) 620 LET R3=(1/(C1*C1*W0**2))/(1/R1+1/R2) 630 LET R4=2*R3 640 PRINT AT 12,6;"Q = ";Q;AT 14,6;"R1 = ";R1 650 PRINT AT 16,6;"R2 = ";R2;AT 18,6;"R3 = ";R3 660 PRINT AT 20,6;"R4 = ";R4 670 PRINT AT 21,10;"PLOT (Y/N)?" 675 SLOW 680 IF INKEY$="" THEN GOTO 680 690 IF INKEY$="N" THEN GOTO 90 700 IF INKEY$="Y" THEN GOTO 1100 710 GOTO 680 720 REM **LOW PASS** 725 LET J=2 730 GOSUB 9200 735 CLS 740 PRINT AT 1,11;Z$(2) 750 PRINT AT 2,11;Z$(4) 760 PRINT AT 4,0;Y$(1);Z$(8);Z$(11) 770 INPUT K 775 GOSUB 9960 780 PRINT AT 4,0;Y$(2);TAB 22;K 782 IF K>=1 THEN GOTO 790 784 PRINT AT 18,0;" **GAIN MUST BE >= ONE**" 786 GOTO 760 790 PRINT AT 6,0;Y$(1);"CUTOFF FREQ. ";Z$(11) 800 INPUT FC 801 GOSUB 9960 810 PRINT AT 6,0;Y$(2);TAB 22;FC 812 IF FC>0 THEN GOTO 820 814 GOSUB 9950 816 GOTO 790 820 PRINT AT 8,0;Y$(1);Z$(9);Z$(11) 830 INPUT C 840 PRINT AT 8,0;Y$(2);TAB 22;C 841 PRINT AT 18,0;" " 842 IF C<1E-5/FC THEN GOTO 845 843 PRINT AT 18,0;"**INVALID VALUE OF CAPACITOR C**" 844 GOTO 820 845 IF P$="3" THEN GOTO 2050 850 PRINT AT 10,0;Y$(1);Z$(10);Z$(11) 860 INPUT C1 862 PRINT AT 18,0;" " 865 PRINT AT 10,0;Y$(2);TAB 22;C1 866 IF C1<(A*A+4*B*(K-1))*C/(4*B) THEN GOTO 870 867 PRINT AT 18,0;"*INVALID VALUE OF CAPACITOR C1*" 868 GOTO 850 870 LET AA=(A*A+4*B*(K-1))*C*C 880 LET WC=2*PI*FC 900 LET R1=2/((A*C+SQR (AA-4*B*C*C1))*WC) 910 LET R2=1/(B*C*C1*R1*WC*WC) 920 IF K=1 THEN GOTO 940 930 LET R3=K*(R1+R2)/(K-1) 940 LET R4=K*(R1+R2) 960 PRINT AT 12,4;"R1 = ";R1;AT 14,4;"R2 = ";R2 970 IF K=1 THEN GOTO 985 980 PRINT AT 16,4;"R3 = ";R3;AT 18,4;"R4 = ";R4 982 GOTO 1000 985 PRINT AT 16,4;"R3 = INFINITY";AT 18,4;"R4 = ";R4 1000 PRINT AT 20,10;"PLOT (Y/N)?" 1010 IF INKEY$="" THEN GOTO 1010 1020 IF INKEY$="N" THEN GOTO 90 1030 IF INKEY$="Y" THEN GOTO 1100 1040 GOTO 1010 1100 REM **PLOT LOW PASS** 1105 CLS 1110 PRINT AT 1,14;"PLOT" 1120 PRINT AT 2,14;"''''''''" 1130 PRINT AT 7,2;"SELECT OPTION:" 1140 PRINT AT 9,10;"1 = W/W0" 1150 PRINT AT 11,10;"2 = FREQUENCY" 1160 PRINT AT 7,2;"%S%E%L%E%C%T% %O%P%T%I%O%N:" 1170 IF INKEY$="" THEN GOTO 1200 1175 LET V$=INKEY$ 1180 IF INKEY$="1" THEN GOTO 2300 1190 IF INKEY$="2" THEN GOTO 1220 1200 PRINT AT 7,2;"SELECT OPTION:" 1210 GOTO 1160 1220 REM **PLOT FREQ.** 1230 CLS 1240 PRINT AT 7,0;Y$(1);"START FREQUENCY = ?" 1250 INPUT SF 1255 GOSUB 9960 1260 PRINT AT 7,0;Y$(2);TAB 24;SF 1262 IF SF>0 THEN GOTO 1265 1263 GOSUB 9950 1264 GOTO 1240 1265 PRINT AT 18,5;" ";AT 19,0;" " 1270 PRINT AT 9,0;Y$(1);"END FREQUENCY = ?" 1280 INPUT EF 1290 PRINT AT 9,0;Y$(2);TAB 24;EF 1291 IF EF>SF THEN GOTO 1296 1292 PRINT AT 18,5;"**INVALID DATA**" 1293 PRINT AT 19,0;"START FREQ. IS GREATER THAN END FREQ." 1294 GOTO 1240 1296 FAST 1300 CLS 1310 GOSUB 9400 1320 GOSUB 8000 1330 GOTO 1000 1340 GOTO 90 1500 REM **SUB. VV** 1505 LET S=2*PI*I 1510 IF P$="1" THEN GOTO 1630 1520 IF P$="2" THEN GOTO 1570 1530 LET M1=-K*S*S 1540 LET P1=(WC*WC/B)-S*S 1550 LET RR=A*WC*S/B 1560 GOTO 1600 1570 LET M1=K*B*WC*WC 1580 LET P1=(B*WC*WC-S*S) 1590 LET RR=A*WC*S 1600 LET X=M1*P1/(P1*P1+RR*RR) 1610 LET Y=-M1*RR/(P1*P1+RR*RR) 1620 GOTO 1680 1630 LET M1=K*BW*S*2*PI 1640 LET P1=W0*W0-S*S 1650 LET RR=2*PI*BW*S 1660 LET X=M1*RR/(P1*P1+RR*RR) 1670 LET Y=M1*P1/(P1*P1+RR*RR) 1680 LET VV=20*LN (SQR (ABS ((X*X)+ABS (Y*Y))))/LN (10) 1690 RETURN 2000 REM **HIGH PASS** 2004 LET J=3 2005 GOSUB 9200 2010 CLS 2020 PRINT AT 1,11;Z$(3) 2030 PRINT AT 2,11;Z$(4) 2040 GOTO 760 2090 LET WC=2*PI*FC 2100 LET R2=4*B/(C*SQR (A+(A*A+8*B*(K-1)))*WC) 2110 LET R1=B/(C*C*R2*WC*WC) 2120 IF K=1 THEN GOTO 2140 2130 LET R3=K*R2/(K-1) 2140 LET R4=K*R2 2150 PRINT AT 11,4;"R1 = ";R1;AT 13,4;"R2 = ";R2 2160 IF K=1 THEN GOTO 2190 2170 PRINT AT 15,4;"R3 = ";R3;AT 17,4;"R4 = ";R4 2180 GOTO 2200 2190 PRINT AT 15,4;"R3 = INFINITY";AT 17,4;"R4 = ";R4 2200 PRINT AT 20,10;"PLOT (Y/N)?" 2210 IF INKEY$="" THEN GOTO 2210 2220 IF INKEY$="N" THEN GOTO 90 2230 IF INKEY$="Y" THEN GOTO 1100 2240 GOTO 2210 2299 REM **PLOT W0/W** 2300 CLS 2301 FAST 2302 GOSUB 9400 2310 LET II=1 2315 LET IN=2/50 2320 IF P$="1" THEN LET WC=W0 2330 FOR L=1 TO 3 STEP IN 2340 LET I=10**(L-2)*WC/(2*PI) 2350 GOSUB 1500 2360 LET G(II)=VV 2370 LET II=II+1 2380 NEXT L 2390 GOSUB 8080 2400 GOTO 1000 2410 GOTO 90 3000 REM **LABEL FREQ.** 3010 PRINT AT 5,0;"G" 3020 PRINT AT 6,0;"A" 3030 PRINT AT 7,0;"I" 3040 PRINT AT 8,0;"N" 3050 PRINT AT 10,0;"D" 3060 PRINT AT 11,0;"B" 3061 RETURN 3065 GOSUB 3000 3070 PRINT AT 17,10;"FREQUENCY (HZ)" 3080 GOSUB 4000 3090 GOSUB 4100 3100 RETURN 3500 REM **LABEL W0/W** 3510 GOSUB 3000 3520 PRINT AT 17,12;"W/W0" 3530 GOSUB 4000 3540 GOSUB 4100 3550 RETURN 3990 REM 4000 IF P$="1" THEN GOTO 4040 4010 IF P$="2" THEN GOTO 4060 4020 PRINT AT 19,10;"HIGH PASS FILTER" 4030 RETURN 4040 PRINT AT 19,10;"BAND PASS FILTER" 4050 RETURN 4060 PRINT AT 19,10;"LOW PASS FILTER" 4070 RETURN 4090 REM 4100 LET Y5=INT ((Y1-Y0)/3) 4110 LET LL=0 4120 LET Y6=INT (Y1) 4130 FOR L=1 TO 4 4140 PRINT AT LL,1;Y6 4150 LET LL=LL+5 4160 LET Y6=Y6-Y5 4170 NEXT L 4175 IF V$="1" THEN RETURN 4180 LET Y5=INT ((EF-SF)/5) 4190 LET Y6=INT (SF) 4195 LET LL=4 4200 FOR L=1 TO 6 4210 PRINT AT 16,LL;Y6 4220 LET LL=LL+5 4230 LET Y6=Y6+Y5 4240 NEXT L 4250 RETURN 5000 REM **LOGON** 5005 DIM O$(2,29) 5010 LET O$(1)="AMERICAN MICRO PRODUCTS, INC." 5020 LET O$(2)="%A%M%E%R%I%C%A%N% %M%I%C%R%O% %P%R%O%D%U%C%T%S%,% %I%N%C%." 5030 FOR L=1 TO 2 5040 FOR I=1 TO 29 5050 PRINT AT 10,I;O$(L,I) 5060 NEXT I 5450 PRINT AT 16,8;"RICHARDSON, TEXAS" 5460 PRINT AT 20,9;"COPYRIGHT,1982" 5470 NEXT L 5480 RETURN 5500 PRINT AT 18,0;" **BAND WIDTH MUST > ZERO**" 5510 RETURN 8000 REM **PLOT ROUTINE** 8010 LET INC=(EF-SF)/50 8020 LET II=1 8030 FOR I=SF TO EF STEP INC 8040 GOSUB 1500 8050 LET G(II)=VV 8060 LET II=II+1 8070 NEXT I 8080 LET Y1=-1E+38 8090 LET Y0=1E+38 8100 FOR I=1 TO II-1 8110 IF Y0>G(I) THEN LET Y0=G(I) 8120 IF Y1"" THEN GOTO 9315 9300 PRINT AT 7,2;"SELECT OPTION:" 9310 GOTO 9280 9315 LET E$=INKEY$ 9320 IF E$="1" OR E$="2" OR E$="3" OR E$="4" THEN GOTO 9330 9322 PRINT AT 20,0;"**INVALID ENTRY, TRY AGAIN**" 9324 GOTO 9280 9330 IF E$="1" THEN LET SS=1 9332 IF E$="2" THEN LET SS=2 9334 IF E$="3" THEN LET SS=3 9335 IF E$="4" THEN LET SS=4 9350 LET A=T(SS) 9360 LET B=H(SS) 9370 RETURN 9400 REM **PLOT AXIS** 9410 PRINT AT 14,4;"...................................................." 9420 FOR I=13 TO 43 9430 PLOT 9,I 9440 NEXT I 9450 PLOT 8,24 9460 PLOT 8,34 9470 PLOT 8,43 9475 IF V$="1" THEN GOTO 9720 9480 PLOT 19,13 9490 PLOT 29,13 9500 PLOT 39,13 9510 PLOT 49,13 9520 PLOT 59,13 9710 RETURN 9720 PLOT 17,13 9730 PLOT 21,13 9740 PLOT 29,13 9750 PLOT 34,13 9760 PLOT 42,13 9780 PLOT 46,13 9790 PLOT 51,13 9800 PLOT 54,13 9810 PLOT 57,13 9820 PLOT 59,13 9830 PRINT AT 16,7;".2";TAB 10;".3";TAB 13;".6";TAB 17;"1";TAB 21;"2";TAB 23;"3" 9840 PRINT AT 16,25;"5";TAB 27;"6";TAB 29;"10" 9850 RETURN 9900 PRINT AT 21,2;">>PRESS ANY KEY TO CONTINUE<<" 9910 IF INKEY$="" THEN GOTO 9910 9920 RETURN 9950 PRINT AT 18,0;"*FREQUENCY MUST BE > THAN ZERO*" 9951 RETURN 9960 PRINT AT 18,0;" " 9961 RETURN 9990 SAVE "EE%1" 9995 RUN ```