Carpooler

Products: The Carpooler
Date: 1982
Type: Cassette
Platform(s): TS 1000
Tags: Home

Carpooler is a carpool management database program that stores up to 100 records, each tracking assignment date, destination, driver, riders’ initials, and departure time. Records are packed into a 100×65 character string array T$, with fixed-width fields allocated across each row (date at columns 1–8, destination 9–28, driver 29–38, riders 39–58, time 59–65). The program supports adding, deleting, and displaying records either by category (destinations or drivers) or filtered by date, with a tape save facility for data persistence. A machine code routine is invoked via USR 16720, called through a sequence of POKEs to addresses 16707–16712 that configure its behavior, likely implementing a fast screen clear or display routine.


Program Analysis

Program Structure

The program is organized into clearly separated functional modules accessed via GOSUB. The top-level flow lives at lines 500–580, which calls initialization, setup, menu, and function-dispatch routines in sequence. The main loop at line 580 returns to line 560 (the function display), making the menu system re-entrant.

Line RangePurpose
100–150REM block containing embedded machine code (or data), GOTO 270 (non-existent line, falls through to 300)
200–260Utility POKE loader: reads address/value pairs via INPUT and POKEs them into memory
300–320Array dimensioning: C$(2,12) for category names, T$(100,65) for records
500–580Main program loop: initialization, menu, function dispatch
1000–1080Machine code call with POKE values 128 (enable mode)
1100–1180Machine code call with POKE values 0 (disable/reset mode)
1200–1299Title/splash screen with “CAR-POOL” and car graphic
1300–1399Master menu display
1400–1499Function selection display (Add/Delete/Display)
2000–2999Add record logic, including duplicate detection
3000–3499Delete record logic
3500–3590Display all records for a category
8000–8050Initialize category name array C$
8500–8520Quit confirmation
9000–9060Save data to tape
9100–9240List records by date

Data Storage

All carpool records are stored in the two-dimensional string array T$(100,65), giving space for 100 records of 65 characters each. Fields within each row use fixed-width substrings:

  • Columns 1–8: Date (MM/DD/YY)
  • Columns 9–28: Destination (20 chars)
  • Columns 29–38: Driver (10 chars)
  • Columns 39–58: Riders’ initials (20 chars)
  • Columns 59–65: Departure time (7 chars)

An empty record slot is detected by checking whether columns 1–8 equal eight spaces (" "). Deletion is implemented by overwriting an entire row with a 65-character blank string Z$ at line 3400.

Machine Code Interface

Two routines, at lines 1000–1080 and 1100–1180, POKE values into addresses 16707–16712 before calling USR 16720. The first routine POKEs 128 into all six locations; the second POKEs 0. The result is stored in C (unused thereafter), suggesting the USR call’s return value is incidental. This pattern is consistent with configuring a parameter block for a machine code screen utility — likely a fast CLS or inverse-video border effect — residing at address 16720. Addresses 16707–16712 fall in the ZX81 system variable region (specifically in the RAMTOP/display file area), which is an unusual choice and implies the machine code was loaded into RAM at a fixed address by the POKE loader at lines 200–260.

The line 100 REM block contains what appears to be the machine code payload: the REM statement holds binary data that the POKE loader routine (lines 200–260) would transfer to address 16720, bootstrapping the USR routine before the main program runs at line 500.

Key BASIC Idioms

  • Dynamic field-width substring matching: variables Q and W are computed as 8+LEN D$ and 28+LEN S$ respectively, so that string comparisons match exactly the stored field width rather than requiring the user input to be padded. This avoids false mismatches due to trailing spaces.
  • The category display routine at lines 3500–3590 uses conditional assignments to swap the roles of driver and destination labels (B$, K$) and field slice variables (L, H, Z, T) depending on whether A=1 or A=2, allowing a single display loop to serve both categories.
  • Input validation uses LEN P$<8 to enforce date format length before accepting the value.
  • Delay loops such as FOR N=1 TO 20: NEXT N provide brief pauses for user feedback messages.

Duplicate Detection

Before adding a record, the subroutine at lines 2500–2999 scans all 100 slots for an existing record with the same date, destination, and driver. If a duplicate is found, it is displayed and the user is asked whether to proceed anyway. If the user confirms, execution jumps to line 2550 to find the next free slot, effectively allowing intentional duplicates.

Tape Save

The save routine at lines 9000–9060 prompts the user to prepare the recorder, then executes SAVE "CARPOO[L]" (where [L] is an inverse-L character encoding in the source). After saving, it jumps to line 500 to reinitialize, which re-dimensions the arrays — this would destroy any data not yet saved, so the save-before-quit workflow is important.

Bugs and Anomalies

  • Line 150 executes GOTO 270, which does not exist. On a ZX81/TS1000, this causes execution to continue at the next higher line, which is line 300. This is the intended behavior — it skips the POKE loader at lines 200–260 during normal program startup.
  • The instructions branch at lines 1241–1250 is unreachable: line 1240 always executes GOTO 1299 (RETURN), so the DO YOU NEED INSTRUCTIONS? prompt and the routine at 7000 (which does not appear in the listing) are never reached.
  • Line 1384 checks IF A<1 OR A>2 THEN GOTO 550, but the menu also offers options 40, 50, and 99, which are handled by earlier IF statements. Any other out-of-range value correctly re-displays the menu.
  • At line 3496, GOSUB 1000 is called immediately before GOTO 560 at line 3499 — the screen clear happens but the display is then immediately redrawn by line 560’s function display routine, making this call redundant.
  • The RETURN at line 2999 is never reached in normal flow, as all paths from subroutine 2800 either GOTO 560 or GOTO 2550.

Content

Appears On

Related Products

Track of car usage by driver, destination, and date. Rider data can be input and time of departure logged. Checking...

Related Articles

Related Content

Image Gallery

Source Code

 100 REM E£RND7▘#▘ GOSUB #Q█TAN     E£RND7▘#▘ GOSUB #▞?Q█F▌TAB [1]RNDE£RND7▘#▘ GOSUB #▞?Q█7▌TAB [J]RNDTAN              E£RND7▘E▘ GOSUB #▞?Q█7▌TAB INT RNDTAN          :-E£RND7)5 ▞4 GOSUB #6 COPYRNDQ[▒]7▌TAB  LIST RNDE COPYRND$TAB  DIM RNDTAN ▌#         E£RND7▘? )5  GOSUB #:+ GOSUB #Q█$TAB /INKEY$ TAN                            <=#▞  ▘ ██████        GOSUB #£RND< GOSUB #WINKEY$ Y▞MYINKEY$ Y-MRNDINKEY$ Y▌MINKEY$ INKEY$  GOSUB #YINKEY$ 5#INKEY$  GOSUB [K]UINKEY$ INKEY$ XTAB #INKEY$ EWINKEY$ )5  GOSUB #6WINKEY$  FOR URNDINKEY$ XMRNDINKEY$ W#▌TAB #INKEY$ TAN                                                                                                                                                                                                                                                                                                                         
 150 GOTO 270
 200 INPUT A
 220 INPUT B
 230 PRINT B
 240 POKE A,B
 250 LET A=A+1
 260 GOTO 220
 300 DIM C$(2,12)
 320 DIM T$(100,65)
 500 GOSUB 1000
 505 GOSUB 8000
 510 GOSUB 1200
 520 GOSUB 1000
 550 GOSUB 1300
 560 GOSUB 1400
 570 IF B=1 THEN GOSUB 2000
 576 IF B=2 THEN GOSUB 3000
 578 IF B=3 THEN GOSUB 3500
 580 GOTO 560
 999 STOP
 1000 REM 
 1010 POKE 16707,128
 1020 POKE 16708,128
 1030 POKE 16709,128
 1040 POKE 16710,128
 1050 POKE 16711,128
 1060 POKE 16712,128
 1070 LET C=USR 16720
 1080 RETURN
 1100 REM 
 1110 POKE 16707,0
 1120 POKE 16708,0
 1130 POKE 16709,0
 1140 POKE 16710,0
 1150 POKE 16711,0
 1160 POKE 16712,0
 1170 LET C=USR 16720
 1180 RETURN
 1200 REM 
 1210 PRINT AT 10,12;"CAR-POOL"
 1220 PRINT AT 11,9;"           "
 1225 PRINT AT 12,11;"O██████O"
 1228 PRINT AT 20,2;"HIT ENTER WHEN READY"
 1229 INPUT Y$
 1230 FOR N=1 TO 50
 1235 NEXT N
 1240 GOTO 1299
 1241 PRINT AT 1,1;"DO YOU NEED INSTRUCTIONS ?"
 1244 INPUT A$
 1246 PRINT AT 3,1;A$
 1248 IF A$="N" THEN GOTO 550
 1250 GOTO 7000
 1299 RETURN
 1300 REM 
 1310 GOSUB 1000
 1320 PRINT AT 1,7;"CAR-POOL CONTROL"
 1330 PRINT AT 2,6;"MASTER MENU DISPLAY"
 1340 PRINT AT 18,1;"ENTER NUMBER OF TYPE"
 1342 PRINT AT 6,5;"1=MAINTAIN DESTINATIONS"
 1344 PRINT AT 8,5;"2=MAINTAIN DRIVERS"
 1366 PRINT AT 14,1;"***ENTER 40 TO LIST BY DATE"
 1368 PRINT AT 15,1;"***ENTER 50 TO SAVE TO TAPE"
 1369 PRINT AT 16,1;"***ENTER 99 TO QUIT "
 1370 INPUT A
 1372 PRINT AT 19,1;A
 1377 IF A=40 THEN GOTO 9100
 1380 IF A=99 THEN GOTO 8500
 1382 IF A=50 THEN GOTO 9000
 1384 IF A<1 OR A>2 THEN GOTO 550
 1399 RETURN
 1400 REM 
 1410 GOSUB 1000
 1420 PRINT AT 1,8;"FUNCTION DISPLAY"
 1422 PRINT AT 3,1;"ENTER NUMBER FOR FUNCTION"
 1424 PRINT AT 4,1;"YOU WISH TO PERFORM"
 1425 PRINT AT 6,5;"TYPE= ";C$(A)
 1426 PRINT AT 10,2;"1=ADD A ";C$(A)
 1428 PRINT AT 12,2;"2=DELETE A ";C$(A)
 1440 PRINT AT 14,2;"3=DISPLAY ALL ";C$(A)
 1442 PRINT AT 18,2;"99=QUIT THIS SECTION"
 1444 INPUT B
 1446 PRINT AT 20,1;B
 1448 IF B=99 THEN GOTO 550
 1450 IF B<1 OR B>4 THEN GOTO 560
 1499 RETURN
 2000 REM ADD LOGIC
 2010 GOSUB 1000
 2020 PRINT AT 1,10;C$(A)
 2025 PRINT AT 2,10;"ADD DISPLAY"
 2040 PRINT AT 5,0;"DATE OF ASSIGNMENT--MM/DD/YY"
 2045 INPUT P$
 2046 IF LEN P$<8 THEN GOTO 2040
 2048 PRINT P$
 2049 PRINT 
 2050 PRINT "DESTINATION"
 2060 INPUT D$
 2062 PRINT D$
 2063 PRINT 
 2064 PRINT "DRIVER"
 2066 INPUT S$
 2068 PRINT S$
 2069 PRINT 
 2070 PRINT "RIDERS INITIALS--E.G. GBG,BCS"
 2072 INPUT E$
 2074 PRINT E$
 2080 PRINT "TIME OF DEPARTURE"
 2082 INPUT F$
 2084 PRINT F$
 2100 PRINT AT 20,1;"ALL ABOVE CORRECT ? Y/N"
 2110 INPUT Y$
 2120 PRINT Y$
 2130 IF Y$="N" THEN GOTO 2000
 2152 GOSUB 2500
 2200 LET T$(X,1 TO 8)=P$
 2202 LET T$(X,9 TO 28)=D$
 2204 LET T$(X,29 TO 38)=S$
 2206 LET T$(X,39 TO 58)=E$
 2208 LET T$(X,59 TO 65)=F$
 2220 GOSUB 1000
 2225 PRINT AT 2,2;"RECORD ADDED"
 2229 PRINT 
 2232 PRINT "HIT ENTER KEY WHEN READY"
 2234 INPUT G$
 2236 GOSUB 1000
 2499 RETURN
 2500 REM 
 2510 GOSUB 1000
 2512 LET Q=8+LEN D$
 2514 LET W=28+LEN S$
 2520 FOR N=1 TO 100
 2530 IF D$=T$(N,9 TO Q) AND S$=T$(N,29 TO W) AND P$=T$(N,1 TO 8) THEN GOTO 2800
 2540 NEXT N
 2550 FOR R=1 TO 100
 2560 IF T$(R,1 TO 8)="        " THEN GOTO 2700
 2580 NEXT R
 2600 PRINT AT 2,2;"NO MORE ROOM IN FILE"
 2610 PRINT AT 4,2;"MUST DO SOME DELETES"
 2620 FOR N=1 TO 20
 2640 NEXT N
 2642 GOTO 560
 2700 LET X=R
 2710 RETURN
 2800 GOSUB 1000
 2810 PRINT AT 2,2;"RECORD WITH SAME DATE"
 2820 PRINT AT 3,2;"DEST, DRIVER EXISTS"
 2840 PRINT 
 2842 PRINT "DATE: ";T$(N,1 TO 8)
 2844 PRINT "DEST: ";T$(N,9 TO 28)
 2846 PRINT "DRIVER: ";T$(N,29 TO 38)
 2848 PRINT "TIME: ";T$(N,59 TO 65)
 2850 PRINT AT 15,2;"SHOULD ADD STILL BE DONE ?"
 2852 INPUT Y$
 2854 PRINT Y$
 2856 IF Y$="N" THEN GOTO 560
 2858 IF Y$="Y" THEN GOTO 2550
 2860 GOTO 2800
 2999 RETURN
 3000 REM 
 3010 GOSUB 1000
 3020 PRINT AT 3,8;"DELETE SCREEN"
 3030 PRINT 
 3040 PRINT AT 2,8;C$(A)
 3050 PRINT AT 5,2;"DATE--MM/DD/YY"
 3060 INPUT P$
 3062 IF LEN P$<8 THEN GOTO 3050
 3070 PRINT P$
 3080 PRINT AT 8,2;"DESTINATION"
 3082 INPUT D$
 3084 PRINT D$
 3086 PRINT AT 11,2;"DRIVER"
 3088 INPUT S$
 3090 PRINT S$
 3095 LET G=1
 3100 LET Q=8+LEN D$
 3110 LET W=28+LEN S$
 3112 FOR N=G TO 100
 3114 IF P$=T$(N,1 TO 8) AND D$=T$(N,9 TO Q) AND S$=T$(N,29 TO W) THEN GOTO 3200
 3116 NEXT N
 3120 GOSUB 1000
 3122 PRINT AT 2,2;"RECORD IS NOT ON FILE"
 3124 FOR J=1 TO 20
 3126 NEXT J
 3130 GOTO 560
 3200 GOSUB 1000
 3210 PRINT AT 2,2;"IS THIS THE RECORD" 
 3211 PRINT AT 3,2;"TO DELETE ?"
 3212 PRINT 
 3214 PRINT "DATE :";T$(N,1 TO 8)
 3216 PRINT "DEST :";T$(N,9 TO 28)
 3218 PRINT "DRIVER :";T$(N,29 TO 38)
 3220 PRINT "TIME :";T$(N,59 TO 65)
 3240 PRINT 
 3244 PRINT "ANSWER Y/N"
 3246 INPUT Y$
 3248 PRINT Y$
 3250 IF Y$="Y" THEN GOTO 3400
 3252 IF Y$="N" THEN LET G=N+1
 3254 IF Y$="N" THEN GOTO 3112
 3400 LET Z$="                                                                 "
 3410 LET T$(N)=Z$
 3411 GOSUB 1000
 3412 PRINT AT 17,2;"RECORD DELETED"
 3415 FOR N=1 TO 30
 3420 NEXT N
 3496 GOSUB 1000
 3499 GOTO 560
 3500 REM 
 3510 GOSUB 1100
 3515 CLS
 3517 LET B$="DRIVER :"
 3518 LET K$="DEST :"
 3520 IF A=1 THEN LET B$="DEST :"
 3522 IF A=1 THEN LET K$="DRIVER :"
 3524 LET Z=29
 3525 LET T=38
 3526 LET L=9
 3527 LET H=28
 3528 IF A=1 THEN LET L=29
 3529 IF A=1 THEN LET H=38
 3530 IF A=1 THEN LET Z=9
 3531 IF A=1 THEN LET T=28
 3532 FOR N=1 TO 100
 3533 IF T$(N,1 TO 8)="        " THEN GOTO 3565
 3534 PRINT B$;T$(N,Z TO T)
 3535 PRINT K$;T$(N,L TO H)
 3540 PRINT "DATE : ";T$(N,1 TO 8)
 3545 PRINT "RIDERS ";T$(N,39 TO 58)
 3550 PRINT "TIME :";T$(N,59 TO 65)
 3560 PRINT 
 3565 NEXT N
 3570 PRINT "HIT ENTER KEY WHEN READY"
 3580 INPUT Y$
 3590 GOTO 560
 8000 REM 
 8010 LET C$(1)="DESTINATION"
 8020 LET C$(2)="DRIVER"
 8050 RETURN
 8500 GOSUB 1000
 8510 PRINT AT 2,2;"ARE YOU SURE QUIT IS"
 8512 PRINT AT 3,2;"WHAT YOU WANT ?   Y/N"
 8514 INPUT L$
 8516 PRINT AT 5,2;L$
 8517 IF L$="Y" THEN STOP
 8520 GOTO 550
 9000 REM 
 9010 GOSUB 1000
 9020 PRINT AT 2,2;"SET RECORDER FOR SAVE MODE"
 9030 PRINT AT 4,2;"WHEN READY HIT ENTER KEY"
 9040 INPUT L$
 9050 SAVE "CARPOO[L]"
 9060 GOTO 500
 9100 REM 
 9110 GOSUB 1000
 9120 PRINT AT 2,2;"ENTER DATE DESIRED"
 9130 INPUT D$
 9140 PRINT AT 4,8;D$
 9160 FOR N=1 TO 20
 9170 NEXT N
 9174 GOSUB 1100
 9176 PRINT AT 1,2;D$
 9178 PRINT 
 9182 FOR N=1 TO 100
 9184 IF D$<>T$(N,1 TO 8) THEN GOTO 9200
 9185 PRINT "DEST.: ";T$(N,9 TO 28)
 9186 PRINT "DRIVER: ";T$(N,29 TO 38)
 9187 PRINT "RIDERS: ";T$(N,39 TO 58)
 9188 PRINT "TIME: ";T$(N,59 TO 65)
 9190 PRINT 
 9200 NEXT N
 9220 PRINT "HIT ENTER WHEN READY"
 9230 INPUT Y$
 9240 GOTO 550

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

People

No people associated with this content.

Scroll to Top