Here's the Applesoft BASIC source code for the program that's always running on my dedicated Apple IIgs.

If you want know how to write software to display messages on your BetaBrite, the part you'll be most interested in is lines 21900..24xxx. Note that the routine at 23000 sets up the BetaBrite in a nice state where you can feed in text messages later (one at a time), without having to set up the overall configration each time.

24020 sends the actual message, by sending a string of 10 bytes of value 0, followed by byte value 1, 'Z', digit '0', digit '0', byte value 2, text, byte value 4.

All the other junk here is for doing Caller ID (which gets fed to the BetaBrite), and controlling "PatchBoy", which is unrelated (it switches audio & video signals).


0 REM PatchBoy
10 UI = 6:GS = 4
90 GOTO 1000
99 :
100 REM * dest D <-- source S
105 POKE DD + D,S
110 OO = (D * 16) + (15 - S):
115 O = OO: GOSUB 200
120 O = OO + 128: GOSUB 200
130 O = OO: GOSUB 200
140 RETURN 
190 :
200 REM * output o
205 POKE 0,O: CALL 921: RETURN 
299 :
300 REM * draw status string
310 VTAB 24: HTAB 1
320 FOR I = 0 TO 7
330 PRINT CHR$ (65 + PEEK (DD + I));
340 NEXT 
345 VTAB 23: HTAB 1: PRINT "        ";
350 VTAB 23: HTAB 1 + O1: PRINT "v";
398 RETURN 
399 :
400 REM * delayed/periodic tasks
410 IF T0 = 0 THEN RETURN 
420 T0 = T0 - 1: IF T0 > 0 THEN RETURN 
425 N9% = NC%: REM * Preserve the new-calls count
430 A$ = CHR$ (13): RETURN : REM * reset Time display
498 RETURN 
499 :
800 REM * special keypresses A$
815 IF KP THEN 900
899 GOTO 995
900 REM * function keys/keypad
902 M0 = INT (M / 2):CT = M0 / 2 < > INT (M0 / 2): REM CT = Control key
905 IF A$ = "Z" THEN S$ = "aaaaaphp":U0 = 7:UI = 6: GOSUB 5000: RETURN 
909 IF A$ = "Q" AND CT THEN S$ = "7---7-5-": GOSUB 5000: RETURN 
910 IF A$ = "Q" THEN S$ = "----7-5-": GOSUB 5000: RETURN 
915 IF A$ = "K" THEN S$ = "--dd--d-": GOSUB 5000: RETURN 
920 IF A$ = "X" THEN S$ = "--b---b-": GOSUB 5000: RETURN : REM F2 = VCR2 on top & phones1
925 IF A$ = "C" THEN S$ = "-b-b-b--": GOSUB 5000: RETURN : REM F3 = VCR2 in Room2
990 IF A$ = "0" THEN T$ = "<hold>": GOSUB 21900: RETURN 
995 PRINT CHR$ (7);: RETURN 
999 :
1000 REM * main
1002 PRINT CHR$ (4);"PR#3": PRINT CHR$ (17);: PRINT CHR$ (4);"PR#0,A$C307"
1003 GOSUB 25000: REM * Init BetaBrite
1005 SP$ = "                    "
1010 GOSUB 3000
1020 GOSUB 10000
1022 O1 = 0:I1 = PEEK (DD + O1)
1025 REM * redraw PatchBoy main screen
1026 O0 = - 1:I0 = - 1
1030 TEXT : HOME : NORMAL 
1050 GOSUB 3100
1060 GOSUB 3200
1090 VTAB 1: HTAB 1
1091 HH$ = "----------------------------------------"
1095 PRINT HH$;"PatchBoy 1.1                  March 1998";HH$: POKE 34,3
1099 :
1100 REM * get a keypress
1102 GOSUB 300
1104 I1 = PEEK (DD + O1): GOSUB 3200
1105 IF PEEK ( - 16384) > 127 THEN 1110
1106 M = 0:A$ = "": GOSUB 400: IF A$ < > "" THEN 1112
1107 CALL 864: IF PEEK (0) THEN GOSUB 31000
1108 GOTO 1105
1110 WAIT - 16384,128:M = PEEK (49152 + 37): GET A$: IF A$ > = "a" AND A$ < = "z" THEN A$ = CHR$ ( ASC (A$) - 32)
1112 M0 = INT (M / 16):KP = M0 / 2 < > INT (M0 / 2)
1113 IF KP THEN 1275
1115 IF A$ = CHR$ (27) THEN GOSUB 1600: GOTO 1100
1120 IF A$ = " " THEN GOSUB 20000: GOTO 1025: REM * BetaBrite
1122 IF A$ = CHR$ (17) THEN T0 = PEEK (DD + UI):D = UI:S = GS: GOSUB 100: POKE DD + UI,T0:A$ = "Q"
1125 IF A$ = "Q" THEN TEXT : HOME : PRINT "Bye!": END 
1200 IF A$ = CHR$ (11) THEN Z = - 1: GOSUB 2000: GOTO 1100
1205 IF A$ = CHR$ (10) THEN Z = 1: GOSUB 2000: GOTO 1100
1210 IF A$ = CHR$ (8) THEN Z = - 1: GOSUB 2100: GOTO 1100
1215 IF A$ = CHR$ (21) THEN Z = 1: GOSUB 2100: GOTO 1100
1220 IF M > 127 AND A$ = "M" THEN GOSUB 1500: GOTO 1100
1225 IF M > 127 AND A$ = "C" THEN GOSUB 1550: GOTO 1100
1230 IF A$ > = "1" AND A$ < = "8" THEN O1 = ASC (A$) - ASC ("1"):I1 = PEEK (DD + O1): GOSUB 3200: GOTO 1100
1235 IF A$ > = "A" AND A$ < = "P" THEN D = O1:I1 = ASC (A$) - ASC ("A"): GOSUB 3200:S = I1: GOSUB 100: GOTO 1100
1240 IF A$ = CHR$ (34) THEN GOSUB 4000: GOTO 1100
1250 IF A$ = CHR$ (13) THEN GOSUB 6000: GOTO 1100
1252 IF A$ = "#" THEN GOSUB 30900: GOTO 1025
1260 IF A$ = "R" THEN GOSUB 33000: GOTO 1025
1275 GOSUB 800: GOTO 1100
1280 PRINT CHR$ (7);: GOTO 1100
1299 :
1300 REM  * low-level "D,S" prompt
1303 T0 = PEEK (DD + UI):D = UI:S = GS: GOSUB 100
1305 VTAB 23: HTAB 1
1310 INPUT "D,S:";D,S: GOSUB 100
1320 VTAB 23: HTAB 1: PRINT SP$;
1330 IF D < > UI THEN D = UI:S = T0: GOSUB 100
1380 RETURN 
1390 :
1400 REM * Save UI display
1410 U0 = PEEK (DD + UI):D = UI:S = GS: GOSUB 100: RETURN 
1420 :
1450 REM * Restore UI display
1460 D = UI:S = U0: GOSUB 100: RETURN 
1470 :
1500 REM * Toggle muting
1510 IF PEEK (DD + O1) < > 15 THEN POKE DD + 8 + O1, PEEK (DD + O1):D = O1:S = 15: GOSUB 100:I1 = 15: GOSUB 3200: RETURN 
1520 D = O1:S = PEEK (DD + 8 + O1): GOSUB 100:I1 = S: GOSUB 3200
1548 RETURN 
1549 :
1550 REM * Toggle captioning
1560 I = PEEK (DD + O1)
1570 IF I = 0 THEN I1 = 7: GOTO 1580
1575 IF I = 7 THEN I1 = 0: GOTO 1580
1577 RETURN 
1580 D = O1:S = I1: GOSUB 100: GOSUB 3200
1598 RETURN 
1599 :
1600 REM * Handle Escape (toggle user interface)
1610 U2 = 6: IF M > 127 THEN U2 = 4: REM  Apple key = use TV for UI
1620 IF UI = U2 THEN 1650
1630 IF PEEK (DD + UI) = GS THEN D = UI:S = U0: GOSUB 100
1640 UI = U2
1650 REM * toggle UI
1659 REM * restore UI display
1660 IF PEEK (DD + UI) = GS THEN D = UI:S = U0: GOSUB 100: RETURN 
1670 REM * grab UI display
1680 U0 = PEEK (DD + UI):D = UI:S = GS: GOSUB 100: RETURN 
1690 RETURN 
1699 :
2000 REM * scrolled to new output
2010 O1 = O0 + Z: IF O1 < 0 THEN O1 = 7
2020 IF O1 > 7 THEN O1 = 0
2030 I1 = PEEK (DD + O1)
2040 GOSUB 3200
2050 RETURN 
2060 :
2100 REM * Scroll to new input
2110 I1 = I0 + Z: IF I1 < 0 THEN I1 = 15
2120 IF I1 > 15 THEN I1 = 0
2130 D = O0:S = I1: GOSUB 100
2140 GOSUB 3200
2150 RETURN 
2160 :
2999 :
3000 REM * set up grid
3010 DIM O$(7),I$(15)
3020 FOR I = 0 TO 7: READ O$(I): NEXT 
3030 FOR I = 0 TO 15: READ I$(I): NEXT 
3040 DATA MainSound,Room2Sound,Headphones1,Headphones2,MainVideo,Room2Video,TopMonitor,Workbench
3050 DATA VCR1,VCR2,VCR3,SuperNintendo,AppleIIgs,DVD,-unused-,Captions/TV Audio,CD,Tape,Radio,-unused-,-unused-,-unused-,-unused-,[Mute]
3060 RETURN 
3070 :
3100 REM * draw grid
3110 V0 = 4:H1 = 18
3120 FOR I = 0 TO 7: VTAB V0 + I: HTAB 2: PRINT O$(I);: NEXT 
3130 FOR I = 0 TO 15: VTAB V0 + I: HTAB H1: PRINT I$(I);: NEXT 
3140 RETURN 
3199 :
3200 REM * Hilite new O1,I1
3201 SP$ = "                    "
3210 IF O1 = O0 THEN 3250
3220 IF O0 > = 0 THEN VTAB V0 + O0: HTAB 2: PRINT LEFT$ (O$(O0) + SP$,12);
3230 O0 = O1: VTAB V0 + O0: HTAB 2: INVERSE : PRINT LEFT$ (O$(O0) + SP$,12);: NORMAL 
3250 IF I1 = I0 THEN 3290
3260 IF I0 > = 0 THEN VTAB V0 + I0: HTAB H1: PRINT LEFT$ (I$(I0) + SP$,20);
3270 I0 = I1: VTAB V0 + I0: HTAB H1: INVERSE : PRINT LEFT$ (I$(I0) + SP$,20);: NORMAL 
3290 RETURN 
3299 :
4000 REM * Get a 8-character string & apply it
4010 T0 = PEEK (DD + UI):D = UI:S = GS: GOSUB 100
4050 VTAB 21: HTAB 1: PRINT SP$;: HTAB 1: INPUT "New state: ";S$
4052 VTAB 21: HTAB 1: PRINT SP$;
4055 D = UI:S = T0: GOSUB 100
4060 IF S$ = "" OR LEN (S$) > 8 THEN PRINT CHR$ (7);: RETURN 
4070 GOSUB 5000
4090 RETURN 
4099 :
5000 REM * Apply status S$
5005 IF LEN (S$) > 8 THEN STOP 
5010 FOR I = 0 TO 7:OLD(I) = PEEK (DD + I): NEXT 
5020 FOR I = 1 TO LEN (S$)
5030 C$ = MID$ (S$,I,1)
5040 IF C$ > = "1" AND C$ < = "8" THEN S = OLD( VAL (C$) - 1): GOTO 5070
5050 IF C$ > = "A" AND C$ < = "P" THEN S = ASC (C$) - 65: GOTO 5070
5055 IF C$ > = "a" AND C$ < = "p" THEN S = ASC (C$) - ASC ("a"): GOTO 5070
5057 IF C$ = "-" THEN 5080
5060 PRINT CHR$ (7);: RETURN 
5070 D = I - 1: GOSUB 100
5080 NEXT 
5090 RETURN 
5099 :
6000 REM * Rebuild normal lightboard display
6005 NC% = N9%:N9% = 0
6010 T$ = "<hold><time>"
6020 IF NC% THEN T$ = T$ + "  <green><<" + STR$ (NC%) + ">"
6030 GOSUB 21900
6040 RETURN 
6050 :
9999 :
10000 REM * init
10005 DATA 8,120,169,4,12,45,192,156,165,192,169,255,141,164,192,169,4,141,165,192,28,45,192,40,96,8,120,169,4,12,45,192,165,0,141,164,192,169,4,28,45,192,40,96
10006 FOR A = 896 TO 939: READ B: POKE A,B: NEXT : CALL 896
10009 REM * that was to init the IO32 (port a = output), and set up for Call 921
10020 DD = 768: IF PEEK (DD + 16) < > 77 THEN FOR I = 0 TO 15: POKE DD + I,0:: NEXT : POKE DD + 16,77
10030 FOR D = 0 TO 7:S = PEEK (DD + D): GOSUB 100: NEXT 
10040 O0 = - 1:I0 = - 1
10050 GOSUB 30000
10060 GOSUB 34200: REM * Area code init
10090 RETURN 
10099 :
20000 REM * BetaBrite controller
20010 REM * by David A. Lyons, 28-Feb-93
20020 :
20030 VN$ = "1.0d3":DT$ = "14-Jul-96"
20040 GOSUB 25000
20045 GOSUB 25900
20050 GOSUB 23000
20100 INPUT T$
20105 IF T$ = "" THEN RETURN 
20110 IF T$ = "t" THEN GOSUB 21000: GOTO 140
20120 M$ = "A": REM text file ID
20130 GOSUB 22000
20140 GOTO 20100
20900 REM * Put date in DT$
20905 PRINT D$;"FLUSH"
20910 A = PEEK (49040):B = PEEK (49041)
20920 Y = INT (B / 2)
20930 M = (B - Y * 2) + INT (A / 32)
20935 IF Y > 99 THEN Y = Y - 100
20940 D = A - 32 * INT (A / 32)
20950 DT$ = STR$ (D) + "-" + MID$ ("JanFebMarAprMayJunJulAugSepOctNovDec",3 * M - 2,3) + "-" + RIGHT$ ("0" + STR$ (Y),2)
20990 RETURN 
20995 :
21000 REM * Set current time
21002 PRINT D$;"CLOSE":M0 = PEEK (49042): PRINT "Waiting for minute to change..."
21005 PRINT D$;"CLOSE"
21010 H = PEEK (49043)
21020 M = PEEK (49042)
21030 IF M = M0 THEN 21005
21050 T$ = RIGHT$ ("0" + STR$ (H),2) + RIGHT$ ("0" + STR$ (M),2)
21090 REM * fall into Set Time T$
21095 :
21100 REM * Set time to T$ ("hhmm")
21110 CMD$ = "E " + T$
21120 GOSUB 24000
21130 RETURN 
21140 :
21900 REM * message T$
21910 M$ = "A"
22000 REM * text t$
22005 GOSUB 22500
22010 CMD$ = "A" + M$ + T$
22020 GOSUB 24000
22025 T0 = 0: REM reset timer
22030 RETURN 
22040 :
22500 REM * translate special characters in T$
22510 T0$ = T$:T$ = ""
22520 IF T0$ = "" THEN 22590
22530 CH$ = LEFT$ (T0$,1):T0$ = MID$ (T0$,2)
22535 IF CH$ = "<" THEN GOSUB 22700: GOTO 22580
22540 IF CH$ < > "$" THEN 22580
22550 CH$ = LEFT$ (T0$,1):T0$ = MID$ (T0$,2)
22555 IF CH$ = "$" THEN 22580
22560 GOSUB 22600:V = DEC:CH$ = LEFT$ (T0$,1):T0$ = MID$ (T0$,2): GOSUB 
22600:V = V * 16 + DEC:CH$ = CHR$ (V)
22580 T$ = T$ + CH$: GOTO 22520
22590 RETURN 
22595 :
22600 REM * return dec = value of CH$
22610 IF CH$ > = "0" AND CH$ < = "9" THEN DEC = ASC (CH$) - 48: RETURN 
22620 IF CH$ > = "a" THEN CH$ = CHR$ ( ASC (CH$) - 32)
22630 IF CH$ > = "A" AND CH$ < = "F" THEN DEC = ASC (CH$) - 55: RETURN 
22640 DEC = 0: RETURN 
22690 :
22700 REM * Parse a "<...>" string
22710 CH$ = LEFT$ (T0$,1):T0$ = MID$ (T0$,2)
22720 IF CH$ = "<" THEN RETURN : REM * "<<" makes a "<"
22730 TK$ = ""
22740 IF CH$ = ">" OR T0$ = "" THEN 22760
22745 IF CH$ < = "Z" AND CH$ > = "A" THEN CH$ = CHR$ ( ASC (CH$) + 32)
22747 TK$ = TK$ + CH$
22750 CH$ = LEFT$ (T0$,1):T0$ = MID$ (T0$,2)
22755 GOTO 22740
22760 CH$ = ""
22770 IF TK$ = "hold" THEN CH$ = CHR$ (27) + " b"
22771 IF TK$ = "time" THEN CH$ = CHR$ (19)
22780 IF TK$ = "red" THEN CH$ = CHR$ (28) + "1"
22781 IF TK$ = "green" THEN CH$ = CHR$ (28) + "2"
22782 IF TK$ = "amber" THEN CH$ = CHR$ (28) + "3"
22783 IF TK$ = "lred" THEN CH$ = CHR$ (28) + "4"
22784 IF TK$ = "lgreen" THEN CH$ = CHR$ (28) + "5"
22785 IF TK$ = "brown" THEN CH$ = CHR$ (28) + "6"
22786 IF TK$ = "orange" THEN CH$ = CHR$ (28) + "7"
22787 IF TK$ = "yellow" THEN CH$ = CHR$ (28) + "8"
22788 IF TK$ = "rb1" THEN CH$ = CHR$ (28) + "9"
22789 IF TK$ = "rb2" THEN CH$ = CHR$ (28) + "A"
22790 IF TK$ = "mix" THEN CH$ = CHR$ (28) + "B"
22800 IF TK$ = "cr" THEN CH$ = CHR$ (27) + " t": RETURN 
22801 IF TK$ = "rotate" OR TK$ = "rot" THEN CH$ = CHR$ (27) + " a": RETURN 
22810 IF TK$ = "welcome" THEN CH$ = CHR$ (27) + "0n8"
22811 IF TK$ = "nosmoke" THEN CH$ = CHR$ (27) + "0nU"
22812 IF TK$ = "special" THEN CH$ = CHR$ (27) + "0n"
22813 IF TK$ = "horse" THEN CH$ = CHR$ (27) + "0nW"
22814 IF TK$ = "thanks" THEN CH$ = CHR$ (27) + "0nS"
22990 RETURN 
22995 :
23000 REM * Set up a handy memory configuration
23010 CMD$ = "E$AAU0800FF00BAU0800FF00"
23020 GOSUB 24000
23090 RETURN 
23095 :
24000 REM  * send cmd$, no response
24010 PRINT D$;"PR#1"
24020 PRINT NUL$; CHR$ (1);"Z00"; CHR$ (2);CMD$; CHR$ (4)
24025 PRINT D$;"PR#0"
24030 RETURN 
24999 :
25000 REM * Initialize
25005 TRUE = (1 < 2):FALSE = NOT TRUE
25010 D$ = CHR$ (4)
25610 NUL$ = CHR$ (0) + CHR$ (0) + CHR$ (0) + CHR$ (0) + CHR$ (0) + CHR$ 
(0) + CHR$ (0) + CHR$ (0) + CHR$ (0) + CHR$ (0)
25620 RETURN 
25630 :
25900 REM * INIT SCREEN
25910 TEXT : HOME : NORMAL : SPEED= 255: NOTRACE 
25922 PRINT HH$;"BetaBrite v";VN$;"               ";DT$;HH$
25930 POKE 34,4
25935 HOME 
25940 RETURN 
25990 :
30000 REM * CallerID INIT
30005 REM * Data at $360 for slot 2 status/read
30010 DATA 162,194,160,32,169,1,32,72,194,169,0,42,133,0,96,234,162,194,160,32,32,70,194,133,0,96
30020 FOR A = 864 TO 889: READ B: POKE A,B: NEXT 
30030 PRINT CHR$ (4);"PR#2": PRINT : PRINT CHR$ (4);"PR#0"
30050 DIM CID$(50):NC = 0
30090 RETURN 
30099 :
30900 REM * "#" simulate incoming call
30910 VTAB 24: HTAB 1: PRINT : PRINT 
30920 INPUT "CID$: ";CID$
30925 IF CID$ = "" THEN RETURN 
30926 IF LEN (CID$) = 3 THEN CID$ = CID$ + "0000000"
30927 IF CID$ = "2" THEN CID$ = "4082539779"
30930 CID$ = "xxxxxxxx" + CID$
30950 GOSUB 31145
30960 RETURN 
30970 :
31000 REM * Incoming CallerID character
31010 CALL 880
31020 IF PEEK (0) = 4 THEN 31100
31030 IF PEEK (0) = 128 THEN 31500
31090 RETURN 
31095 :
31100 REM * SMDF format (just a phone number)
31110 CALL 880:L = PEEK (0)
31115 CID$ = ""
31120 FOR I = 1 TO L: CALL 880:CID$ = CID$ + CHR$ ( PEEK (0)): NEXT 
31130 CALL 880:CK = PEEK (0)
31140 CALL 864: IF PEEK (0) THEN CALL 880: GOTO 31140
31145 REM * CID$ = "mmddhhmm#..."
31147 NC% = NC% + 1
31150 NN$ = MID$ (CID$,9)
31175 GOSUB 32000
31200 T$ = "<hold>": IF LEN (NN$) > 14 THEN T$ = "<cr>"
31205 T$ = T$ + "<green>" + NN$: GOSUB 21900
31210 T0 = 500: REM countdown till retoring display
31250 GOSUB 33500: REM Log
31300 RETURN 
31310 :
31500 REM * MDMF format (multiple messages)
31505 C1$ = "":C2$ = "":C3$ = "": REM c1$=time, c2$=number, c3$=name
31510 CALL 880:L9 = PEEK (0)
31515 REM * next param in msg
31520 CALL 880:T = PEEK (0)
31530 CALL 880:L = PEEK (0)
31540 C$ = "": FOR I = 1 TO L: CALL 880:C$ = C$ + CHR$ ( PEEK (0)): NEXT 
31550 IF T = 1 THEN C1$ = C$: GOTO 31600
31560 IF T = 2 OR T = 4 THEN C2$ = C$: GOTO 31600
31570 IF T = 7 THEN C3$ = C$
31600 REM * get get param, if any
31610 L9 = L9 - L - 2: IF L9 > 0 THEN 31515
31700 IF C3$ = "" THEN CID$ = C1$ + C2$: GOTO 31140: REM * fall through to old code
31710 NN$ = C2$: IF LEN (NN$) = 10 THEN NN$ = LEFT$ (NN$,3) + " " + MID$ (NN$,4,3) + "-" + MID$ (NN$,7)
31712 IF LEN (NN$) = 1 THEN GOSUB 32000: REM O and P
31715 LL$ = ""
31720 IF LEFT$ (NN$,4) = "408 " THEN NN$ = MID$ (NN$,5): GOTO 31800
31750 AA% = VAL ( LEFT$ (NN$,3)): GOSUB 34000
31800 REM * NN$ = number, C3$=name, LL$=area code
31810 T$ = "<hold><cr><green>" + NN$
31820 IF C3$ < > "" THEN T$ = T$ + "<red> " + C3$
31830 T$ = T$ + "<orange> " + LL$
31850 GOSUB 21900: REM * msg T$
31860 T0 = 750: REM countdown till restoring display
31900 CID$ = C1$ + NN$ + " " + C3$ + LL$: GOSUB 33500
31910 RETURN 
31990 STOP 
31995 :
32000 REM * Translate well-known phone numbers (NN$)
32002 IF NN$ = "O" THEN NN$ = "Out of area": RETURN 
32003 IF NN$ = "P" THEN NN$ = "Private call": RETURN 
32005 IF LEN (NN$) = 10 THEN NN$ = LEFT$ (NN$,3) + " " + MID$ (NN$,4,3) + "-" + MID$ (NN$,7)
32007 C9$ = " <orange>"
...
32070 IF NN$ = "408 257-5555" THEN NN$ = NN$ + C9$ + " Pizza Presto": GOTO 32900
...
32800 IF LEFT$ (NN$,7) = "408 253" THEN NN$ = NN$ + C9$ + "probably Apple": RETURN 
32900 :
32960 IF LEFT$ (NN$,4) = "408 " THEN NN$ = MID$ (NN$,5): RETURN 
32970 AA% = VAL ( LEFT$ (NN$,3)): GOSUB 34000: IF LL$ < > "" THEN NN$ = NN$ + " <orange>" + LL$
32990 RETURN 
32995 :
33000 REM * Review CallerID calls
33010 TEXT : HOME : PRINT HH$;"Review recent calls": PRINT HH$: POKE 34,3
33020 PRINT "Number of calls: ";NC
33030 IF NC = 0 THEN 33210
33040 FOR I = 1 TO NC
33050 CID$ = CID$(I)
33060 PRINT LEFT$ (CID$,2);"/"; MID$ (CID$,3,2);" ";
33070 PRINT MID$ (CID$,5,2);":"; MID$ (CID$,7,2);" ";
33080 NN$ = MID$ (CID$,9)
33090 IF NN$ = "O" THEN NN$ = "Out of area"
33100 IF NN$ = "P" THEN NN$ = "Private call"
33110 N0$ = NN$: GOSUB 32000
33120 PRINT N0$;: IF NN$ < > N0$ THEN PRINT " (";NN$;")";
33130 PRINT 
33200 NEXT 
33210 GET A$: RETURN 
33220 :
33500 REM * Log CID$
33510 NC = NC + 1
33520 IF NC = 50 THEN FOR I = 1 TO 40:CID$(I) = CID$(I + 10): NEXT : FOR I = 40 TO 49:CID$(I) = "": NEXT :NC = 40
33528 ZZ$ = CID$:CID$ = "": FOR I = 1 TO LEN (ZZ$):CC = ASC ( MID$ (ZZ$ + " ",I,1)): IF CC < 32 OR CC > 127 THEN CC = 32
33529 CID$ = CID$ + CHR$ (CC): NEXT 
33530 CID$(NC) = CID$
33540 REM * flush any garbage characters from incoming serial
33550 FOR I = 1 TO 9000: NEXT 
33560 CALL 864: IF PEEK (0) THEN CALL 880: GOTO 33560
33570 RETURN 
33990 :
33999 :
34000 REM * Compute LL$ = descr of area code AA%
34010 LL$ = AA$(AA%(AA%)): RETURN 
34199 :
34200 REM * Init area code data
34205 DIM AA%(1000),AA$(100)
34210 FOR I = 1 TO 1000
34220 READ AA$(I): IF AA$(I) = "*" THEN RETURN 
34230 FOR J = 1 TO 2 STEP 0: READ A: IF A = 0 THEN 34240
34235 IF AA%(A) THEN STOP 
34237 AA%(A) = I: NEXT 
34240 NEXT I: STOP 
34295 :
34300 REM * Area code data
34500 DATA Alberta,403,780,0
34505 DATA Alabama,205,256,334,0
34510 DATA Alaska,907,0
34515 DATA Arizona,520,602,0
34516 DATA Arkansas,501,0
34520 DATA Bahamas,242,0
34521 DATA Barbados,246,0
34525 DATA Bermuda,441,0
34530 DATA British Colombia,250,604,0
34531 DATA British Virgin Isles,284,0
34535 DATA California,209,213,310,323,408,415,510,530,559,562,619,626,650,661,707,714,760,805,818,831,909,916,925,949,0
34540 DATA Caribbean,649,784,809,0
34545 DATA Cayman Islands,345,0
34550 DATA Colorado,303,719,720,970,0
34555 DATA Connecticut,203,860,0
34560 DATA Delaware,302,0
34562 DATA DOMINICA,767,0
34565 DATA Florida,305,352,407,561,813,850,904,941,954,0
34570 DATA Georgia,404,678,706,770,912,0
34571 DATA Grenada,473,0
34575 DATA Guam,671,0
34580 DATA Hawaii,808,0
34585 DATA Idaho,208,0
34590 DATA Illinois,217,309,312,618,630,708,773,815,847,0
34595 DATA Indiana,219,317,812,765,0
34600 DATA Intl. Inbound,456,0
34605 DATA Iowa,319,515,712,0
34610 DATA Jamaica,876,0
34615 DATA Kansas,316,785,913,0
34620 DATA Kentucky,502,606,0
34625 DATA Louisiana,318,504,0
34630 DATA Maine,207,0
34631 DATA Manitoba,204,0
34635 DATA Maryland,240,301,410,443,0
34640 DATA Massachusetts,413,508,617,781,978,0
34645 DATA Michigan,248,313,517,616,734,810,906,0
34650 DATA Minnesota,218,320,507,612,0
34651 DATA Mississippi,228,601,0
34655 DATA Missouri,314,417,573,660,816,0
34660 DATA Montana,406,0
34661 DATA Montserrat,664,0
34665 DATA Nebraska,308,402,0
34670 DATA Nevada,702,0
34671 DATA Newfoundland,709,0
34672 DATA New Brunswick,506,0
34675 DATA New Hampshire,603,0
34680 DATA New Jersey,201,609,732,908,973,0
34685 DATA New Mexico,505,0
34690 DATA New York,212,315,347,516,518,607,646,716,718,914,917,0
34695 DATA North Carolina,252,336,704,828,910,919,0
34696 DATA Nova Scotia,902,0
34700 DATA North Dakota,701,0
34705 DATA Ohio,216,330,419,440,513,614,740,937,0
34710 DATA Oklahoma,405,580,918,0
34715 DATA Ontario,416,519,613,705,807,905,0
34720 DATA Oregon,503,541,0
34725 DATA Pennsylvania,215,412,610,717,724,814,0
34730 DATA Puerto Rico,787,0
34735 DATA Quebec,418,450,514,819,0
34740 DATA Rhode Island,401,0
34741 DATA Saskatchewan,306,0
34745 DATA South Carolina,803,843,864,0
34750 DATA South Dakota,605,0
34755 DATA Tennesee,423,615,901,931,0
34760 DATA Texas,210,214,254,281,409,512,713,806,817,830,903,915,940,956,972,0
34761 DATA Trinidad/Tobago,868,0
34765 DATA US Gov,710,0
34770 DATA Utah,435,801,0
34775 DATA Vermont,802,0
34777 DATA Virgin Islands,340,0
34780 DATA Virginia,540,703,757,804,0
34785 DATA Wash. State,206,360,509,0
34790 DATA WashDC,202,0
34795 DATA West Virginia,304,0
34800 DATA Wisconsin,414,608,715,920,0
34805 DATA Wyoming,307,0
34810 DATA Yukon/NW Territories,867,0
34990 DATA *
34995 :
63998 STOP 
63999 PRINT CHR$ (4);"Save PatchBoy"