--- title: "Checkbook Manager" id: 51713 type: "computer_media" slug: "checkbook-manager" url: "http://localhost/computer_media/checkbook-manager/" markdown_url: "http://localhost/computer_media/checkbook-manager.md" published_at: "2023-08-13T23:14:28+00:00" modified_at: "2026-03-30T21:49:03+00:00" author: "David Anderson" featured_image: url: "http://localhost/wp-content/uploads/2023/08/SCR-20260330-ppfz.png" excerpt: "A full-featured personal checking account manager packs binary-encoded balances, multi-field search, category tracking, and tape save/load into a single BASIC program." category: - name: "Archived Media" slug: "archived-media" taxonomy: "category" url: "http://localhost/category/archived-media/" post_tag: - name: "Downloadable" slug: "downloadable" taxonomy: "post_tag" url: "http://localhost/tag/downloadable/" - name: "Timex Computer Corporation" slug: "timex-computer-corporation" taxonomy: "post_tag" url: "http://localhost/tag/timex-computer-corporation/" - name: "TS 2068" slug: "ts2068" taxonomy: "post_tag" url: "http://localhost/tag/ts2068/" model: - name: "Timex/Sinclair 2068" slug: "ts-2068" taxonomy: "model" url: "http://localhost/model/ts-2068/" genre: - name: "Finance" slug: "finance" taxonomy: "genre" url: "http://localhost/type/finance/" - name: "Home" slug: "home" taxonomy: "genre" url: "http://localhost/type/home/" media_type: "Program" download_url: "https://archive.org/download/timex-sinclair-software-archive/Checkbook Manager (1982)(Timex)(US)(TS2068)(Cassette).zip" mediadate: "1982" producer_company: - id: 11401 title: "Timex Computer Corporation" type: "company" url: "http://localhost/company/timex-computer-corporation/" images: - url: "http://localhost/wp-content/uploads/2023/08/SCR-20260330-ppfz.png" - url: "http://localhost/wp-content/uploads/2023/08/SCR-20260330-ppba.png" - url: "http://localhost/wp-content/uploads/2021/01/CheckbookManager.jpg" related_products: - id: 12116 title: "The Checkbook Manager" type: "product" url: "http://localhost/product/checkbook-manager/" media_type_tags: "Finance, Home" --- # Checkbook Manager This program implements a personal checking account management system, storing up to 500 transaction records in a dimensioned string array where each 46-character record encodes the check number, date, payee name, amount, running balance, category, and void status using a compact binary packing scheme. Amounts and balances are stored as 5-byte binary-encoded values using a custom FN n$/FN n pair of functions that pack a floating-point dollar amount into three bytes of integer magnitude, one sign byte, and one byte of cents. The system supports writing checks, recording deposits, and searching transactions by month, date, payee name, or spending category across 16 predefined categories. Data persistence is handled by saving and loading the entire array to tape, with metadata such as the current year, check-charge fee, and transaction count stored in the last record slot. An ON ERR handler at line 9990 inspects the system variable at address 23736–23737 to recover gracefully from input errors at specific line numbers rather than crashing. *** ## Program Analysis ### Program Structure The program is organized into functional modules accessed through a menu at line 500. Navigation uses computed `GO SUB` targets stored in variables (`bord`, `getdate`, `senter`, `nospace`, `list`), and the menu dispatcher at line 710 uses a lookup string to jump to the correct routine: | Menu Key | Label | Line | | --- | --- | --- | | A | Write a check | 1000 | | B | Make a deposit | 1500 | | C | Review all transactions | 2000 | | D | List by month | 5000 | | E | List by date | 2500 | | F | List by name | 3000 | | G | List by category | 5500 | | H | Display category list | 6000 | | I | Void a transaction | 3500 | | J | Save data | 4000 | | K | Load data | 6500 | | L | Quit | 4500 | The dispatch string at line 708 is `"100015002000500025003000550060003500400065004500"`; the correct 4-character substring is selected using the computed index `x` derived from the key pressed. ### Record Layout Each transaction is stored as a fixed-length 46-character string in `a$(next, rlen)` where `rlen = 46` (30+2+2+5+5+1+1). The fields are: | Bytes | Content | | --- | --- | | 1–2 | Check/deposit number (little-endian 16-bit) | | 3 | Month (1–12) | | 4 | Day | | 5–34 | Payee name (30 chars, space-padded) | | 35–39 | Amount (5-byte packed binary float) | | 40–44 | Running balance (5-byte packed binary float) | | 45 | Void flag (CHR$ 255 = voided) | | 46 | Category index (1–16) | Deposits are distinguished from checks by having their transaction number ≥ 10000 (starting at 10001). Deposit amounts are stored as negated values so that a uniform running-balance formula (`old - amnt`) works for both checks and deposits. ### Binary Amount Encoding The most technically interesting aspect is the custom 5-byte binary floating-point encoding for dollar amounts, implemented entirely in BASIC using `DEF FN`. The packing function `FN n$(q)` at line 40 encodes an amount as: - Byte 1: high byte of integer part (`INT ABS q / 65536`) - Byte 2: middle byte of integer part - Byte 3: low byte of integer part - Byte 4: sign byte (0 = positive, 1 = negative via `q<0`) - Byte 5: cents (fractional part × 100) The complementary unpacking function `FN n(y$)` at line 12 reconstructs the value using `FN z(y$)` (line 10) which reassembles the 3-byte integer, then subtracts twice its value if the sign byte is nonzero. This avoids storing negative numbers using two’s-complement, instead using a sign-magnitude scheme. ### Search and Result Packing All search routines (by date, name, month, category) build a result list `p$` as a packed string of 2-byte little-endian record indices. After searching, the generic list display routine at line 2700 iterates over `p$` in steps of 2, reconstructing each record index with `CODE p$(t)+CODE p$(t+1)*256`. This is an efficient indirect-reference scheme that avoids duplicating record data. The cycling BORDER color (`BORDER u-INT(u/8)*8`) during searches provides a visual progress indicator. ### Error Handling The program installs a global `ON ERR GO TO 9990` handler. The handler at line 9990 reads the error line number from system variables at addresses 23736–23737 and dispatches to appropriate recovery points for known problematic lines (9050, 205, 9030). Line 9995 uses `IF erl=205` to recover from a `VAL ""` error when the user enters an empty check-charge string. If the error occurs within the handler itself (line ≥ 9990), execution stops with `ON ERR RESET`. ### Date Handling The `getdate` subroutine at line 9010 accepts dates in `MM/DD` format, scanning the input string for a `/` delimiter. If no delimiter is found, it falls back to using the previously entered month and interpreting the entire input as a day number. Leap year detection for February is handled in the `DATA` statement at line 135: `28+(1 AND year/4=INT(year/4))`. ### Display Utilities The `senter` subroutine at line 9100 center-prints a name by trimming trailing spaces then using `TAB 15-LEN e$/2`. The `FN p$(s)` function at line 50 formats dollar amounts to two decimal places by appending `"."` when the value is a whole number, then appending `"00"` and slicing to ensure the correct length. ### Notable Anomalies - Line 9370 uses `LET r$=r$+CHR$ (...)` which appends to any existing content of `r$` rather than assigning fresh. Since `r$` is initialized to `""` at line 5510, this is harmless in normal flow, but could accumulate stale data on repeated category lookups without that initialization path. - The word “catagory” (a misspelling of “category”) is used consistently throughout all menus and messages. - Several lines of code are commented out inline with `REM` prefixes mid-line (e.g., lines 2027, 2050), suggesting iterative development and debugging. - The quit routine at line 4510 uses `ON ERR RESET : STOP`, a defensive measure to clean up the error handler state before halting. - The metadata record stored in `a$(max+1)` at line 4025 encodes only a single byte for `year` (the 2-digit form), limiting the system to years expressible as values 0–255 offset from 1900. ## Source Code ``` 1 ON ERR GO TO 9990 4 INVERSE 0 5 INK 0: PAPER 1: BORDER 1: CLS : PRINT INK 7;AT 8,2;"THE PERSONAL CHECKING SYSTEM" 7 PAUSE 100: CLS 10 DEF FN z(x$)=CODE x$(1)*65536+CODE x$(2)*256+CODE x$(3) 12 DEF FN n(y$)=VAL (STR$ (FN z(y$)-(2*FN z(y$) AND CODE y$(4)))+"."+STR$ CODE y$(5)) 20 DEF FN a(u)=INT (u/65536) 30 DEF FN b(w)=w-FN a(w)*65536 40 DEF FN n$(q)=CHR$ FN a(INT ABS q)+CHR$ (INT (FN b(INT ABS q)/256))+CHR$ (FN b(INT ABS q)-256*INT (FN b(INT ABS q)/256))+CHR$ (q<0)+CHR$ (100*(ABS q-INT ABS q)) 50 DEF FN p$(s)=(STR$ s+("." AND s=INT (s))+("00"))( TO LEN STR$ INT s+3) 60 LET dep=1 70 DIM m$(12,3): RESTORE 80: FOR t=1 TO 12: READ m$(t): NEXT t 80 DATA "Jan","Feb","Mar","Apr","May","Jun","Jul","Aug","Sep","Oct","Nov","Dec" 100 REM 120 INPUT "Year: ";year: IF year>1900 THEN LET year=year-1900 130 DIM m(12): FOR t=1 TO 12: READ m(t): NEXT t 135 DATA 31,28+(1 AND year/4=INT (year/4)),31,30,31,30,31,31,30,31,30,31 140 LET oldm=1: LET oldd=1 150 REM 155 LET list=2700 160 GO SUB 9010 200 INPUT "Check charge: ";z$ 205 LET cc=VAL (z$+("0" AND z$="")) 210 LET bord=9900 212 LET ctri=6 214 LET getdate=9010 216 LET senter=9100 218 LET nospace=9200 300 REM 305 LET max=500 310 LET rlen=VAL "30+2+2+5+5+1+1" 320 DIM a$(max+1,rlen) 330 LET next=1 340 DIM c$(16,20) 350 RESTORE 360: FOR r=1 TO 16: READ c$(r): NEXT r 360 DATA "Automotive","Vacation","Food","Heating","Clothing","Home Improvements","Mortgage/Loans","Insurance","Paycheck","Medical Care","Cash- personal","Rent","Telephone","Special 1","Special 2","Special 3" 500 REM 501 INVERSE 0 502 LET k=4: LET h=4 510 INK 0: PAPER 5: BORDER 6: CLS 520 GO SUB bord 525 PRINT INK 0;AT 1,2;"The Personal Checking System" 526 PLOT 0,156: DRAW 255,0 527 FOR e=h-1 TO h+15: PRINT INVERSE 1;AT e,1;" ": NEXT e 528 ON ERR GO TO 9990 530 PRINT INVERSE 1;AT h,k;"[A] Write a check";AT h+1,k;"[B] Make a deposit";AT h+2,k;"[C] Review all transactions";AT h+3,k;"[D] List by month" 532 PRINT INVERSE 1;AT h+4,k;"[E] List by date";AT h+5,k;"[F] List by name";AT h+6,k;"[G] List by catagory";AT h+7,k;"[H] Display catagory list";AT h+8,k;"[I] Void a transaction" 534 PRINT INVERSE 1;AT h+9,k;"[J] Save data";AT h+10,k;"[K] Load data";AT h+11,k;"[L] Quit" 550 PRINT AT 18,25; INVERSE 1;" "; INVERSE 0;year+1900; INVERSE 1;" ";AT 17,25;" ";AT 19,25;" " 560 PRINT AT 17,k; INK 1;" Please select... " 600 REM 622 FOR y=-1 TO 8: PLOT OVER 1;k*8-1,176-(17)*8-y-1: DRAW OVER 1;145,0 630 LET k$=CHR$ PEEK 23556 640 IF k$>="A" AND k$<="L" THEN GO TO 700 645 REM IF k$<>CHR$ 255 THEN BEEP .125,-24 650 NEXT y 660 GO TO 600 700 LET x=CODE k$-CODE "A"+1 701 LET x=4*(x-1)+1 702 INVERSE 0: PAPER 5 705 BEEP .125,32 708 LET x$="100015002000500025003000550060003500400065004500" 710 GO SUB VAL x$(x TO x+3) 720 GO TO 500 999 STOP 1000 REM check 1002 LET qq=5 1005 IF next=max+1 THEN GO TO nospace 1010 CLS : GO SUB bord 1020 INPUT "Check number: ";cn 1030 IF cn<>INT cn OR cn<1 OR cn>9999 THEN GO TO 1020 1035 PRINT PAPER qq;AT 2,1;"Check number: ";cn 1040 GO SUB getdate 1045 PRINT PAPER qq;AT 3,1;"Date: ";m$(m);" ";STR$ d;",";year+1900 1050 INPUT "Check issued to: ";n$ 1051 IF n$="" THEN LET n$="CASH" 1052 GO SUB bord 1054 IF LEN n$>30 THEN LET n$=n$( TO 30) 1055 PRINT PAPER qq;AT 6,1;: GO SUB senter 1060 INPUT "Amount: ";amnt 1070 IF amnt>=256^3 OR amnt<0 THEN GO TO 1060 1071 IF n$="" THEN LET n$="PAYCHECK" 1075 PRINT PAPER qq;AT 9,1;"Amount: $";FN p$(amnt) 1080 LET cn1=INT (cn/256): LET cn2=cn-cn1*256: LET r$=CHR$ cn2+CHR$ cn1 1090 LET r$=r$+CHR$ m+CHR$ d 1095 IF LEN n$>30 THEN LET n$=n$( TO 30) 1100 LET n$=n$+" "( TO 30-LEN n$) 1110 LET r$=r$+n$ 1120 LET r$=r$+FN n$(amnt) 1125 LET old=0: IF next=1 THEN GO TO 1140 1130 LET old=FN n(a$(next-1)(40 TO 44)) 1140 LET new=old-amnt-(cc AND cn<10000) 1150 LET r$=r$+FN n$(new)+CHR$ 0 1155 GO SUB 9300 1160 LET a$(next)=r$ 1170 LET next=next+1 1180 RETURN 1500 REM deposit 1510 IF next=max THEN GO TO nospace 1520 CLS : GO SUB bord 1530 LET cn=10000+dep: LET dep=dep+1 1540 PRINT AT 2,1;"Deposit Number: ";cn-10000 1550 GO SUB getdate 1560 PRINT AT 3,1;"Date: ";m$(m);" ";STR$ d;",";year+1900 1570 INPUT "Source: ";n$ 1572 GO SUB bord 1575 IF LEN n$>30 THEN LET n$=n$( TO 30) 1580 PRINT AT 6,1;: GO SUB senter 1590 INPUT "Amount: ";amnt 1600 IF amnt>=256^3 OR amnt<0 THEN GO TO 1590 1610 PRINT AT 7,1;"Amount $";FN p$(amnt) 1615 LET amnt=0-amnt 1620 GO TO 1080 2000 REM latest 2020 LET cur=next-1 2025 IF cur<1 THEN RETURN 2027 REM CLS : REM GO SUB bord 2030 GO SUB 2300 2040 PRINT AT 17,1;("Press {M} to see the next one." AND cur>1)+("Done, Press {X} for menu. " AND cur=1);AT 18,1;("Press any other key for menu." AND cur>1)+(" " AND cur=1) 2050 LET l$=INKEY$: REM BEEP .0025,40: BEEP .0025,60: REM BEEP .0025,50 2055 IF l$="" THEN GO TO 2050 2060 IF l$="m" OR l$="M" THEN LET cur=cur-1: GO TO 2025 2070 IF l$="x" OR l$="X" THEN RETURN 2080 IF l$="" THEN GO TO 2050 2090 RETURN 2300 REM 2310 CLS : GO SUB bord 2315 LET crec=cur 2317 LET w$=a$(crec) 2320 INK 0 2325 LET tn=CODE w$+CODE w$(2)*256 2327 LET o$="Deposit": IF tn<10000 THEN LET o$="Check" 2328 PRINT AT 3,15-LEN o$/2;o$ 2329 INK 0 2330 PLOT 5,60: DRAW 245,0: DRAW 0,80: DRAW -245,0: DRAW 0,-80 2335 INK 1 2340 PRINT INVERSE 1;AT 5,31-LEN STR$ (tn-(10000 AND tn>10000)); INVERSE 1;tn-(10000 AND tn>10000) 2350 LET m=CODE w$(3): LET d=CODE w$(4) 2360 PRINT AT 5,1;m$(m);" ";STR$ d;",";STR$ (year+1900);" " 2365 PLOT 8,126: DRAW 8*(9+LEN STR$ d),0 2367 DRAW INK 5;20,0 2370 PRINT AT 8,1;: LET n$=w$(5 TO 5+29): GO SUB senter 2375 PLOT 8,111-8: DRAW 255-(16),0 2377 PRINT AT 10,1;c$(CODE w$(46)) 2380 PRINT AT 13,1;"Amount:"; 2390 PRINT AT 13,31-LEN FN p$(ABS FN n(w$(35 TO 39)));FN p$(ABS FN n(w$(35 TO 39))) 2392 IF CODE w$(45)=255 THEN PRINT AT 11,12;"**VOID**" 2395 INK 0 2400 PRINT AT 15,1;"Balance Forward: "; 2410 PRINT AT 15,31-LEN FN p$(FN n(w$(40 TO 44)));FN p$(FN n(w$(40 TO 44))) 2415 PRINT AT 18,1;"Press any other key to go on." 2420 PRINT AT 17,1;"For a printer copy, press {"; FLASH 1;"C"; FLASH 0;"}" 2422 LET l$=INKEY$: IF l$="c" OR l$="C" THEN COPY 2424 REM BEEP .0125,28 2425 IF l$="" THEN GO TO 2422 2430 IF INKEY$<>"" THEN GO TO 2430 2490 RETURN 2500 REM by date 2505 CLS : GO SUB bord 2510 LET p$="" 2520 GO SUB getdate 2530 LET i$=CHR$ m+CHR$ d 2535 PRINT AT 15,10; FLASH 1;" SEARCHING " 2540 FOR u=1 TO next-1 2545 BORDER u-INT (u/8)*8 2550 IF i$=a$(u)(3 TO 4) THEN LET a1=INT (u/256): LET a2=u-a1*256: LET p$=p$+CHR$ a2+CHR$ a1 2560 NEXT u 2570 BORDER 6 2580 PRINT AT 15,10;" " 2585 IF LEN p$ THEN GO TO 2620 2590 PRINT AT 1,1;"You made no transactions on ";AT 2,1;"the date of ";m$(m);" ";STR$ d;",";year+1900;"." 2600 PRINT AT 4,1;"Press any key to return to the";AT 5,1;"menu." 2610 PAUSE 0: RETURN 2620 GO SUB list 2630 RETURN 2700 REM list 2710 FOR t=1 TO LEN p$ STEP 2 2720 LET cur=CODE p$(t)+CODE p$(t+1)*256: GO SUB 2300 2730 PRINT AT 17,1;("Press {M} to go on " AND t30 THEN GO TO 3020 3050 LET p$="" 3060 PRINT AT 10,10; FLASH 1;" SEARCHING " 3070 FOR j=1 TO next-1 3075 BORDER j-INT (j/8)*8 3080 IF a$(j,5 TO 5+LEN s$-1)=s$ THEN LET p1=INT (j/256): LET p2=j-p1*256: LET p$=p$+CHR$ p2+CHR$ p1 3090 NEXT j 3100 PRINT AT 10,10;" " 3110 IF LEN p$ THEN GO TO list 3115 BORDER 6: CLS : GO SUB bord 3120 PRINT AT 1,1;"No such name exists." 3130 PRINT AT 3,1;"Press any key to return to the";AT 4,1;"menu." 3140 PAUSE 0 3150 RETURN 3500 REM void 3510 CLS : GO SUB bord 3520 INPUT "Transaction: ";tn 3530 LET t1=INT (tn/256): LET t2=tn-t1*256 3540 LET t$=CHR$ t2+CHR$ t1 3550 PRINT AT 10,10; FLASH 1;" SEARCHING " 3560 FOR y=1 TO next-1 3570 BORDER y-INT (y/8)*8 3590 IF a$(y)( TO 2)=t$ THEN GO TO 3650 3600 NEXT y 3605 BORDER 6 3610 PRINT AT 10,10;" " 3620 PRINT AT 1,1;"No such transaction exists.";AT 2,1;"Press any key to return to the";AT 3,1;"menu." 3630 PAUSE 0 3640 RETURN 3650 LET a$(y,45)=CHR$ 255 3660 LET adj=FN n(a$(y,35 TO 39)) 3661 LET adj=adj+cc 3665 PRINT AT 10,10; FLASH 1;" ADJUSTING " 3670 FOR j=y TO next-1 3675 BORDER j-INT (j/8)*8 3680 LET a$(j,40 TO 44)=FN n$(FN n(a$(j,40 TO 44))+adj) 3690 NEXT j 3700 RETURN 4000 REM save 4010 CLS : GO SUB bord 4020 PRINT AT 1,1;"Please connect the MIC jack on";AT 2,1;"your computer to the MIC jack";AT 3,1;"on your tape recorder." 4022 LET n1=INT (next/256): LET n2=next-n1*256 4025 LET a$(max+1)=CHR$ oldm+CHR$ oldd+CHR$ year+CHR$ cc+CHR$ n2+CHR$ n1 4030 SAVE "CHECKS"+STR$ year DATA a$() 4150 RETURN 4500 REM quit 4505 BORDER 7: PAPER 7: INK 0: CLS 4510 ON ERR RESET : STOP 4520 GO TO 500 4999 RETURN 5000 REM list by month 5010 CLS : GO SUB bord 5020 INPUT "Month: ";m 5030 LET p$="" 5040 PRINT AT 10,10; FLASH 1;" SEARCHING " 5050 FOR u=1 TO next-1 5055 BORDER u-INT (u/8)*8 5060 IF CODE a$(u,3)=m THEN LET p1=INT (u/256): LET p2=u-p1*256: LET p$=p$+CHR$ p2+CHR$ p1 5070 NEXT u 5075 BORDER 6 5080 IF p$>"" THEN GO TO list 5085 CLS : GO SUB bord 5090 PRINT AT 1,1;"No transactions were made in";AT 2,1;m$(m);", ";year+1900;"." 5100 PRINT AT 4,1;"Press any key to return to the";AT 5,1;"menu." 5120 PAUSE 0 5130 RETURN 5500 REM list by catagory 5510 LET r$="" 5520 GO SUB 9300 5530 LET p$="" 5540 FOR t=1 TO next-1 5545 BORDER t-INT (t/8)*8 5550 IF a$(t,46)=r$ THEN LET p1=INT (t/256): LET p2=t-p1*256: LET p$=p$+CHR$ p2+CHR$ p1 5560 NEXT t 5565 BORDER 6 5570 IF p$="" THEN CLS : GO SUB bord: PRINT AT 1,1;"No transactions have been made";AT 2,1;"in that catagory.": GO TO 5100 5580 GO TO list 6000 REM review catagory list 6010 GO SUB 9250 6020 IF INKEY$="" THEN GO TO 6020 6030 RETURN 6499 STOP 6500 REM load 6510 CLS : GO SUB bord 6520 PRINT AT 1,1;"Rewind your tape.";AT 3,1;"Connect the EAR jack on your";AT 4,1;"computer to the EAR jack on";AT 5,1;"your tape recorder." 6530 PRINT AT 7,1;"Then press PLAY on your tape";AT 8,1;"recorder." 6540 LOAD "" DATA a$() 6550 LET z$=a$(max+1) 6560 LET oldm=CODE z$ 6570 LET oldd=CODE z$(2) 6580 LET year=CODE z$(3) 6590 LET cc=CODE z$(4) 6600 LET next=CODE z$(5)+CODE z$(6)*256 6610 RETURN 9000 REM 9010 REM getdate 9015 ON ERR GO TO 9990 9020 INPUT "Date (ie 11/20): ";d$: IF d$="" THEN LET d=oldd: LET m=oldm: GO TO 9060 9025 LET m=0: LET d=0 9030 FOR y=1 TO LEN d$: IF d$(y)="/" THEN LET m=VAL d$( TO y-1): LET d=VAL d$(y+1 TO ): GO TO 9060 9040 NEXT y 9050 LET m=oldm: LET d=VAL d$ 9060 LET oldm=m: LET oldd=d 9064 IF m<1 OR m>12 THEN GO SUB 9940: GO TO 9010 9065 IF d<0 THEN GO SUB 9940: GO TO 9010 9067 IF d>m(m) THEN GO SUB 9940: GO TO 9010 9070 RETURN 9100 REM senter 9110 LET e$=n$ 9120 IF e$="" THEN RETURN 9130 IF e$(LEN e$)=" " THEN LET e$=e$( TO LEN e$-1): GO TO 9120 9140 PRINT TAB 15-LEN e$/2;e$ 9150 RETURN 9200 REM nospace 9210 CLS : GO SUB bord: PRINT AT 1,1;"There is no more space to hold";AT 2,1;"more transactions." 9220 PRINT AT 4,1;"You should SAVE this set of";AT 5,1;"data for ";year+1900;"." 9230 PRINT AT 7,1;"Press any key to return to the";AT 8,1;"menu.": PAUSE 0: RETURN 9250 REM 9260 LET spec=1 9270 GO TO 9310 9300 REM get catagory 9305 LET spec=0 9310 CLS : GO SUB bord 9320 PRINT AT 1,1;("Choose your catagory: " AND NOT spec)+("Catagories: [Any key for menu]" AND spec) 9330 FOR y=0 TO 15: PRINT AT y+3,3;"{"+CHR$ (CODE "A"+y)+"} ";c$(y+1) 9340 NEXT y 9345 IF spec THEN RETURN 9350 LET k$=CHR$ PEEK 23556 9360 IF k$<"A" OR k$>"P" THEN GO TO 9350 9370 LET r$=r$+CHR$ (CODE k$-CODE "A"+1) 9380 RETURN 9900 REM 9910 FOR z=0 TO 1: PLOT 0+z,0+z: DRAW 255-(2*z),0: DRAW 0,175-(2*z): DRAW -(255-(2*z)),0: DRAW 0,-(175-(2*z)): NEXT z 9920 PRINT AT 20,1; PAPER 3; BRIGHT 1;" \* 1982, by Purple Sunrise " 9939 RETURN 9940 BEEP .05,-12 9949 RETURN 9990 ON ERR RESET 9991 LET erl=PEEK 23736+256*PEEK 23737 9992 IF erl>=9990 THEN ON ERR RESET : STOP 9993 ON ERR GO TO 9990 9994 IF erl=9050 THEN GO TO 9010 9995 IF erl=205 THEN GO TO 200 9996 IF erl=9030 THEN GO TO 9020 9998 ON ERR CONTINUE 9999 INK 0: PAPER 7: BORDER 7: CLS ```