0 REM k'nex & Snap Circuit Control
1 REM Written by Ivan
2 REM Updated March 6, 2012
3 REM
4 GOSUB 2069: REM Load Sound Routines

6 Q = 1: REM Shadow Detector Quiet flag (0=off, 1=on)
7 SPRE% = 20: REM PDL(2) Shadow threshold value preset
8 XFAN = 70: REM Fan on-time preset
9 X = 50: REM Sound on-time preset
10 XM% = 127: REM Conveyor alarm delay time preset
11 M% = XM%: REM Conveyor alarm count-down
12 GOTO 99

15 SWS = 0: POKE -16294,0: REM Clear AN1; turn off space war sounds
20 CR = 0: POKE -16290,0: REM Clear AN3; turn off conveyor
30 FL = 0: POKE -16296,0: REM Clear AN0; turn off fan left
40 FR = 0: POKE -16292,0: REM Clear AN2; turn off fan right
45 RETURN

99 REM Dimension Arrays
110 DIM A$(2): REM On / Off string
120 DIM B$(7): REM Outputs Status
130 DIM C$(5): REM Inputs Status
135 DIM D$(2): REM Game Paddle Status
137 DIM E$(11): REM Keyboard Control
145 GOSUB 300: REM Loads arrays
147 GOSUB 4000: REM Load E$ array
150 GOSUB 15: REM Clear Annunciators
152 PRINT CHR$ (4) + "PR#3": REM Clear Screen and make 80-columns
153 GOSUB 5000: REM Print Keyboard control strings
154 GOSUB 3100: REM Print Status information
210 GOTO 462: REM Main Program Loop

219 REM Count & Print Coaster Rides
220 CRT% = CRT% + 1: VTAB 13: HTAB 50: PRINT CRT%;" COUNT OF COASTER ";
230 PRINT "RIDES"
240 IF CR THEN CR = 0:SWS = 1:Z = X: REM Stop conveyor & start space war sounds
250 M% = XM%: REM Reset alarm counter
260 RETURN

299 REM Load arrays with strings
300 A$(1) = "on "
310 A$(2) = "off"
320 B$(1) = "**** Ivan's EXPO 2012 Project ****"
325 B$(2) = "Annunciator Outputs Status"
330 B$(3) = "  [off] C)onveyor - AN3"
340 B$(4) = "  [off] S)ound IC - AN1"
350 B$(5) = "  [off] L)eft fan - AN2"
360 B$(6) = "  [off] R)ight fan - AN0"
370 B$(7) = "  [off] D)isc shooter- AN0 & AN2"
380 C$(1) = "Button & PDL Inputs Status"
390 C$(2) = "  [off] Light Beam - BTN 1"
400 C$(3) = "  [off] Snap Circ Btn - BTN 2"
410 C$(4) = "  [off] Motion Detector - BTN 3"
420 C$(5) = "  [off] Shadow Detector - PDL2"
450 D$(1) = "  PDL(0)=[   ] PDL(1)=[   ]"
452 D$(2) = "  PDL(2)=[   ] PDL(3)=[   ]"
456 TL% = LEN (B$(1)) - 2: REM Length of title
458 TI% = 3: REM Title index (for animation)
459 PTI% = TL%: REM Previous title index value
460 RETURN

461 REM Print current paddle input values
462 VTAB 15: HTAB 11: PRINT RIGHT$ ("  " + STR$ ( PDL (0)),3)
464 VTAB 15: HTAB 24: PRINT RIGHT$ ("  " + STR$ ( PDL (1)),3)
466 VTAB 16: HTAB 11: PRINT RIGHT$ ("  " + STR$ ( PDL (2)),3)
468 VTAB 16: HTAB 24: PRINT RIGHT$ ("  " + STR$ ( PDL (3)),3)
469 REM Print current button input values
470 IF PEEK ( - 16287) > 127 THEN VTAB 11: HTAB 4: PRINT A$(1)
480 IF PEEK ( - 16287) < 128 THEN VTAB 11: HTAB 4: PRINT A$(2)
482 IF PEEK ( - 16287) > 127 AND NOT PB% THEN GOSUB 220
484 PB% = INT ( PEEK ( - 16287) / 128): REM Previous Beam
490 IF PEEK ( - 16285) > 127 THEN VTAB 13: HTAB 4: PRINT A$(1)
500 IF PEEK ( - 16285) < 128 THEN VTAB 13: HTAB 4: PRINT A$(2)
510 IF  PDL (2) > SPRE% THEN VTAB 14: HTAB 4: PRINT A$(1): GOSUB 6100: GOSUB 2000
520 IF  PDL (2) < SPRE% THEN VTAB 14: HTAB 4: PRINT A$(2): VTAB 21: HTAB 33: PRINT "                                              "
530 K = PEEK ( - 16384) - 128: REM Keyboard key pressed
531 POKE -16368,0: REM Clears keyboard strobe
535 IF K = ASC ("Q") THEN Q = 1 - Q: REM Quiet the Shadow detector
540 IF K = ASC ("C") THEN CR = 1 - CR: GOSUB 1100: REM Conveyor Start/Stop
545 IF K = ASC ("P") THEN GOSUB 6000: REM Parameter Update
550 IF K = ASC ("L") THEN FL = 1 - FL: REM Left Fan On/Off
555 IF K = ASC ("E") THEN POKE -16368,0: GOSUB 2065: GOSUB 15: TEXT : END
560 IF K = ASC ("R") THEN FR = 1 - FR: REM Right Fan On/Off
570 IF K = ASC ("S") THEN SWS = 1 - SWS: REM Space War Sounds On/Off
580 IF K = ASC ("D") THEN DS = 1 - DS: GOSUB 1000: REM Disk Shooter On/Off

599 REM Set Outputs On or Off using POKE (1=on 0=off)
600 IF CR = 1 THEN POKE -16289,0: VTAB 4: HTAB 4: PRINT A$(1)
602 IF FR = 0 THEN POKE -16292,0: VTAB 7: HTAB 4: PRINT A$(2)
605 IF FL = 0 THEN POKE -16296,0: VTAB 6: HTAB 4: PRINT A$(2)
610 IF CR = 0 THEN POKE -16290,0: VTAB 4: HTAB 4: PRINT A$(2)
630 IF DS = 1 THEN VTAB 8: HTAB 4: PRINT A$(1)
640 IF DS = 0 THEN VTAB 8: HTAB 4: PRINT A$(2)
660 IF SWS = 1 THEN POKE -16293,0: VTAB 5: HTAB 4: PRINT A$(1)
670 IF SWS = 0 THEN POKE -16294,0: VTAB 5: HTAB 4: PRINT A$(2)
680 IF FL = 1 THEN POKE -16295,0: VTAB 6: HTAB 4: PRINT A$(1)

684 REM Print current Button #2 (Emergency Stop) input value
685 IF PEEK ( - 16286) > 127 THEN VTAB 12: HTAB 4: PRINT A$(1): VTAB 8: HTAB 4: PRINT A$(2):DS = 0:ZFAN = 0:Z = 0: GOSUB 15: GOSUB 3000
686 IF PEEK ( - 16286) < 128 THEN VTAB 12: HTAB 4: PRINT A$(2)
690 IF FR = 1 THEN POKE -16291,0: VTAB 7: HTAB 4: PRINT A$(1)

699 REM Space War Sound on-time count-down
700 IF Z < 1 THEN 800
710 Z = Z - 1
720 IF Z > 0 THEN 800
730 CR = 1:SWS = 0:ZFAN = XFAN: REM Turn On Fan & Conveyor when done
740 I% = INT ( RND (1) * 3) + 1: REM Pick random direction for Fan
750 IF I% = 0 THEN ZFAN = 0
760 IF I% = 1 THEN FL = 1:FR = 0:DS = 0
770 IF I% = 2 THEN FL = 0:FR = 1:DS = 0
780 IF I% = 3 THEN FL = 1:FR = 1:DS = 1

799 REM Fan on-time count-down
800 IF ZFAN < 1 THEN 840
810 ZFAN = ZFAN - 1
820 IF ZFAN > 0 THEN 840
830 FL = 0:FR = 0:DS = 0: REM Turn Off Fan Outputs when done

840 REM Check for conveyor problem
845 IF CR = 0 THEN 860
847 M% = M% - 1
850 IF M% > 0 THEN 860
852 INVERSE : VTAB 18: HTAB 50: PRINT "!! ALARM !!";: NORMAL
854 PRINT " NO CAR AT TOP"
856 HTAB 53: PRINT "Check Conveyor For Problems"
858 CR = 0:M% = XM%: REM Turn off conveyor and reset alarm counter
860 VTAB 14: HTAB 50: PRINT M%;" NO CAR DETECTED COUNT DOWN  "
862 VTAB 15: HTAB 50: PRINT Z;" SOUND ON  "
864 VTAB 16: HTAB 50: PRINT ZFAN;" FAN ON  "

900 REM Title Animation
910 VTAB 1: HTAB TI%
920 INVERSE : PRINT MID$ (B$(1),TI%,1): NORMAL
930 VTAB 1: HTAB PTI%
940 PRINT MID$ (B$(1),PTI%,1)
950 PTI% = TI%:TI% = TI% + 1
960 IF TI% > TL% THEN TI% = 4
980 REM End of Title Animation
998 GOTO 462: REM Goto start of Main Loop

999 REM Disk Shooter Control
1000 IF DS = 1 THEN FL = 1:FR = 1
1010 IF DS = 0 THEN FL = 0:FR = 0
1020 RETURN

1100 REM Clear Alarm Message
1110 VTAB 18: HTAB 50: PRINT "                          "
1120 HTAB 53: PRINT "                            "
1130 RETURN

1999 REM Make a sound when Shadow detected
2000 IF Q < > 1 THEN RETURN
2010 POKE 768,25: POKE 769,10: CALL 770
2060 RETURN

2064 REM End of program tune
2065 POKE 768,34: POKE 808,56: POKE 769,56: POKE 794,1: CALL 770
2066 POKE 769,255: POKE 808,255: POKE 769,255: POKE 794,255: CALL 770
2067 RETURN

2069 REM Poke assembly language sound routine into memory
2070 IF PEEK (770) = 173 AND PEEK (814) = 96 THEN 6
2072 FOR ADR = 770 TO 814
2074 READ DT
2076 POKE ADR,DT
2078 NEXT ADR
2080 RETURN

2081 REM Data for assembly language sound routine
2082 DATA 173,48,192,136,208,5,206,1,3,240,9,202
2084 DATA 208,245,174,0,3,76,2,3,96,0,0
2090 DATA 160,1,162,0,138,24,233,1,208,252,141
2100 DATA 48,192,232,224,150,208,242,136,208,237,96

2999 REM Sound apple makes when BTN2 is pressed
3000 A% = 0
3010 POKE 678, INT ( RND (1) * 50): POKE 769,1: CALL 770
3015 A% = A% + 1
3020 IF A% = 10 THEN RETURN
3040 GOTO 3010

3099 REM Print the Status Information
3100 VTAB 1: HTAB 1
3110 PRINT B$(1): PRINT
3120 FOR A = 2 TO 7: PRINT B$(A): NEXT A
3130 PRINT : FOR A = 1 TO 5: PRINT C$(A): NEXT A
3140 FOR A = 1 TO 2: PRINT D$(A): NEXT A
3150 VTAB 18: HTAB 3: PRINT "Q)uiet shadow detector (touch once)"
3160 VTAB 19: HTAB 3: PRINT "P)arameter Update"
3170 VTAB 20: HTAB 3: PRINT "E)END"
3180 RETURN

3999 REM The Keyboard Control screen message
4000 E$(1) = "__________________________________________"
4010 E$(2) = "| To control the things on the table...  |"
4020 E$(3) = "|                                        |"
4030 E$(4) = "| Hit 'C' to start conveyor              |"
4040 E$(5) = "| Hit 'S' to start the space war sounds  |"
4050 E$(6) = "| Hit 'L' to make fan go left            |"
4060 E$(7) = "| Hit 'R' to make fan go right           |"
4070 E$(8) = "| Hit 'D' to start disc launcher         |"
4080 E$(9) = "| Hit again to stop or start!            |"
4090 E$(10) = "| !!!!!!!!!!! Ask First !!!!!!!!!!!!!!!!!|"
4100 E$(11) = "|________________________________________|"
4110 RETURN

4999 REM Print the Keyboard Control Screen message at column 38
5000 VTAB 1
5005 Y = 38
5010 HTAB Y: PRINT E$(1)
5020 HTAB Y: PRINT E$(2)
5030 HTAB Y: PRINT E$(3)
5040 HTAB Y: PRINT E$(4)
5050 HTAB Y: PRINT E$(5)
5060 HTAB Y: PRINT E$(6)
5070 HTAB Y: PRINT E$(7)
5080 HTAB Y: PRINT E$(8)
5090 HTAB Y: PRINT E$(9)
5100 HTAB Y: PRINT E$(10)
5110 HTAB Y: PRINT E$(11)
5120 RETURN

5999 REM Update the parameter presets
6000 VTAB 22: PRINT "SHADOW=";SPRE%
6010 VTAB 23: INPUT "TYPE A NEW VALUE FOR SHADOW; SHADOW=";A$
6015 IF A$ < > "" THEN SPRE% = VAL (A$)
6020 VTAB 22: PRINT "                                          "
6030 PRINT "                                           "
6035 GOSUB 6060
6040 TEXT
6045 VTAB 22: PRINT "                                        "
6047 PRINT "                             "
6050 RETURN
6060 VTAB 22: PRINT "FAN ON TIME PRESET = ";XFAN
6065 VTAB 23: INPUT "TYPE A NEW VALUE FOR XFAN; XFAN=";A$
6067 IF A$ < > "" THEN XFAN = VAL (A$)
6069 VTAB 22: PRINT "                                               "
6070 PRINT "                                               "
6072 VTAB 22: PRINT "SOUND ON TIME PRESET = ";X
6074 VTAB 23: INPUT "TYPE A NEW VALUE FOR X; X=";A$
6076 IF A$ < > "" THEN X = VAL (A$)
6078 VTAB 22: PRINT "                                           "
6079 PRINT "                                           "
6080 VTAB 22: PRINT "CAR ALARM = ";XM%
6082 VTAB 23: INPUT "TYPE A NEW VALUE FOR CAR ALARM; CAR ALARM = ";A$
6084 IF A$ < > "" THEN XM% = VAL (A$)
6085 VTAB 22: PRINT "                                                 "
6086 VTAB 23: PRINT "                                                 "
6087 VTAB 22: PRINT "NUMBER OF CAR RIDES = ";CRT%
6088 VTAB 23: INPUT "TYPE A NEW VALUE FOR CAR RIDES; CAR RIDES = ";A$
6089 IF A$ < > "" THEN CRT% = VAL (A$)
6090 VTAB 22: PRINT "                                                 "
6091 VTAB 23: PRINT "                                                                  "
6092 VTAB 13: HTAB 50: PRINT CRT%;" COUNT OF COASTER ";
6093 PRINT "RIDES"
6094 RETURN

6099 REM Indicate when a shadow is detected by the photo resistor
6100 VTAB 21: HTAB 33: INVERSE : PRINT "SHADOW";: NORMAL
6110 PRINT " DETECTED ";
6120 INVERSE : PRINT "BY PDL(2)"
6130 NORMAL
6140 RETURN