This program implements a two-part checkbook reconciliation tool that handles both the review of checkbook entries and the reconciliation of a bank statement. It uses LPRINT throughout to produce a simultaneous paper hard copy alongside the screen display, with columnar formatting achieved via TAB stops. Currency arithmetic is performed entirely in integer pennies (multiplying by 100 and using INT with a 0.5 rounding offset) to avoid floating-point rounding errors, then formatted into dollar-and-cents strings by inserting a decimal point two characters from the right of the STR$ result. POKE 23658 controls the caps lock state, and POKE 23609 sets the keyboard repeat delay. The program contains several spelling errors in its labels (“RECONCILLIATION,” “RECCONCILLATION”) and a case-sensitivity bug at line 4048 where the test uses the uppercase variable I$ rather than the lowercase i$ used everywhere else for menu input.
Program Analysis
Program Structure
The program is organized into several functional regions separated by line-number ranges:
- Lines 1–46: Initialization, screen/printer setup, date entry, and branch to the main menu (via
GO SUB 2000). - Lines 50–155: Checkbook entry loop — prompts for checks (
c) or deposits (d), prints formatted rows on screen and printer, loops back to line 50. - Lines 200–255: Subroutine — formats check amount
cintoc$and subtracts from balanceb. - Lines 300–355: Subroutine — formats deposit amount
dintod$and adds to balanceb. - Lines 400–500: Subroutine — increments entry counter
eand formats balancebintob$. - Lines 2000–2070: Main menu — displays instructions and branches to checkbook review (option 1, line 26) or statement reconciliation (option 2, line 3000).
- Lines 3000–3090: Outstanding checks entry loop, accumulating total in
tc. - Lines 4000–4080: Outstanding deposits entry loop, accumulating total in
td. - Lines 5000–5220: Final reconciliation — compares adjusted bank balance with checkbook balance, reports discrepancy, then restarts.
Currency Arithmetic
All monetary values are stored internally as integer penny amounts. When a dollar figure is entered, it is immediately converted with the idiom INT (x*100+.5) (e.g., lines 44, 200, 300, 5008). The +.5 before truncation provides correct rounding. This avoids the accumulation of floating-point representation errors that would otherwise corrupt running totals.
Dollar-and-cents display strings are assembled by taking the STR$ of the penny integer and inserting a literal "." two characters from the right end:
b$( TO LEN b$-2)+"."+b$(LEN b$-1 TO )
A special case handles zero: if the amount is zero the string is set to "000" before slicing, so the result becomes "0.00". Negative balances are detected by checking VAL b$<0 and the leading minus sign is stripped from the string for separate formatting.
Dual Screen and Printer Output
Every significant display action has a parallel LPRINT statement, allowing simultaneous production of a paper hard copy. Columnar alignment on both screen and printer is achieved with TAB, and right-justification of variable-length currency strings uses expressions such as TAB 32-LEN b$. The header at line 15 prompts the user to turn on the printer before proceeding.
System POKEs
| Address | Effect | Line |
|---|---|---|
23658 | Caps lock — set to 8 (caps on) during entry mode; restored to 0 at menu | 8, 2002 |
23609 | Keyboard repeat delay — set to 100 | 9 |
Menu and Input Idioms
The main menu at line 2060 polls INKEY$ in a tight loop rather than using INPUT, so no Enter keypress is required — the program responds immediately when “1” or “2” is detected. The entry type menu at line 50 uses INPUT into i$ and then a chain of IF guards to dispatch to the correct subroutine.
The balance counter e is initialized to -1 at line 7 so that the first call to GO SUB 400 (which increments it before any display) results in entry number 0 for the opening balance line.
Subroutine Reuse and Side Effects
The formatting subroutines at lines 200, 300, and 400 each modify the shared balance variable b as a side effect in addition to formatting a display string. This tight coupling is relied upon throughout: for example, lines 5019 and 5038 call GO SUB 310 and GO SUB 410 — entry points mid-subroutine — to perform the arithmetic update without re-entering the amount conversion at the top of the subroutine.
Bugs and Anomalies
- Case mismatch at line 4048: The test
IF I$="f"uses uppercaseI$, but the variable populated by the precedingINPUTat line 4045 is lowercasei$. On a case-sensitive system these are distinct variables, so the"f"exit condition for the deposits loop will never trigger, trapping the user in an infinite loop. - Misspelled labels: “RECONCILLIATION” and “RECCONCILLATION” appear in multiple PRINT and LPRINT strings throughout the program; these are cosmetic errors only.
- Line 5038 calls
GO SUB 410, which does not exist; the nearest defined lines are 400 and 420. Execution will fall through to the next available line in the interpreter, which is 420 (IF b=0 THEN LET b$="000"), effectively bypassing the entry counter increment at line 400 and the initial STR$ conversion at line 410. This may produce incorrect output for the “TOTAL” line in the final reconciliation. - Line 5112 calls
GO SUB 420similarly — there is no line 420 defined as a standalone subroutine entry, so execution falls through from 420 onward within the 400-block, which is functional but relies on fall-through behavior. - Double semicolon at line 5117 (
PAPER 5;;"O.K...") produces an empty string between the attribute and the text, which is harmless but redundant.
Content
Source Code
1 REM program "bankrec"
5 CLS : BORDER 6: INK 9
6 LET b=0: LET c=0: LET d=0
7 LET e=-1: LET i$="":
8 POKE 23658,8
9 POKE 23609,100
10 PRINT PAPER 6;" BANK RECONCILLIATION "
15 PRINT AT 1,1; INK 7;"turn on printer for hard copy:";AT 1,0; OVER 1; PAPER 4;"________________________________"
20 INPUT FLASH 1; BRIGHT 1;" ENTER TODAY'S DATE ";e$
25 GO SUB 2000
26 BORDER 2
28 CLS : BEEP .2,18: PRINT AT 0,0;" CHECKBOOK RECONCILIATION ";AT 0,0; OVER 1; PAPER 4; INK 7;"________________________________"
29 PRINT INVERSE 1;" REVIEW OF CHECKBOOK ENTRIES "
30 PRINT AT 3,0;"Ent# Pay/Deb ";TAB 14;"Deposit";TAB 25;"BALANCE";AT 3,0; OVER 1; PAPER 5;"________________________________"
32 PRINT AT 2,3; PAPER 6;"DATE:";AT 2,15;e$;AT 2,0; OVER 1;"________________________________"
35 LPRINT AT 0,0;" CHECKBOOK RECONCILIATION ";AT 0,0; OVER 1; PAPER 4;"________________________________"
36 LPRINT INVERSE 1;" REVIEW OF CHECKBOOK ENTRIES "
37 LPRINT AT 1,15-LEN e$/2-3;"Date: ";e$;AT 1,0; OVER 1;"________________________________"
38 LPRINT AT 2,0;"Ent# Pay/Deb";TAB 14;"Deposit";TAB 25;"BALANCE";AT 2,0; OVER 1; PAPER 5;"________________________________"
40 INPUT "ENTER STARTING DTE/CK# BEGINNING ENTRIES: ";S$;: PRINT AT 4,0; PAPER 4;"BEGIN ENTRIES (Dte/ck#) ";s$;
41 LPRINT AT 4,0; PAPER 4;"BEGIN ENTRIES (Dte/ck#) ";s$;
43 INPUT "1-ENTER BALANCE: ";b
44 LET b=INT (b*100+.5)
45 GO SUB 400
46 GO TO 120
50 INPUT INK 9; PAPER 7;"NEXT ENTRY:"; PAPER 2;"CK??"; PAPER 7;" OR "; PAPER 1;"DEPOSIT?? "; PAPER 7;" (ENTER c OR d):""m"" FOR MENU";i$
70 IF i$="c" THEN INPUT INK 9;"Enter Amount of"; PAPER 2;" check: ";c
80 IF i$="d" THEN INPUT INK 9;"Enter Amount of"; PAPER 1;" DEPOSIT: ";d
85 IF i$="m" THEN CLS : GO TO 2000
90 IF i$<>"m" AND i$<>"c" AND i$<>"d" THEN GO TO 50
110 PRINT TAB 1;e;":$";
120 IF i$="c" THEN GO SUB 200: PRINT TAB 12-LEN c$;c$;
122 IF i$="d" THEN GO SUB 300: PRINT TAB 13;"$";TAB 22-LEN d$;d$;
123 GO SUB 400: PRINT TAB 23;"$";: IF b>=0 THEN PRINT TAB 32-LEN b$;b$
125 IF b<0 THEN PRINT TAB 31-LEN b$; INK 7; PAPER 2;"-";b$
130 IF i$="c" THEN LPRINT TAB 1;e;":";TAB 10-LEN c$;"$";c$;
131 IF i$="d" THEN LPRINT TAB 1;e;":";TAB 20-LEN d$;"$";d$;
132 LPRINT TAB 31-LEN b$;"$"+b$
140 LET c=0: LET d=0: LET i$=""
150 GO TO 50
200 LET c=INT (c*100+.5)
210 LET c$=STR$ c
220 IF c=0 THEN LET c$="000"
230 LET c$=c$( TO LEN c$-2)+"."+c$(LEN c$-1 TO )
240 IF VAL c$>=0 THEN GO TO 252
250 LET c$=c$(2 TO )
252 LET b=b-c
255 RETURN
300 LET d=INT (d*100+.5)
310 LET d$=STR$ d
320 IF d=0 THEN LET d$="000"
330 LET d$=d$( TO LEN d$-2)+"."+d$(LEN d$-1 TO )
340 IF VAL d$>=0 THEN GO TO 352
350 LET d$=d$(2 TO )
352 LET b=b+d
355 RETURN
400 LET e=e+1
410 LET b$=STR$ b
420 IF b=0 THEN LET b$="000"
430 LET b$=b$( TO LEN b$-2)+"."+b$(LEN b$-1 TO )
440 IF VAL b$>=0 THEN GO TO 500
450 LET b$=b$(2 TO )
500 RETURN
2000 BORDER 6
2002 POKE 23658,0
2005 PRINT TAB 15-LEN e$/2; PAPER 4; INK 7;e$
2010 PRINT : PRINT TAB 9; PAPER 3;"INSTRUCTIONS"
2020 PRINT : PRINT TAB 1;"1- To verify checkbook entries."
2030 PRINT : PRINT TAB 1;"2- To Reconcile Bank statement"'" with your checkbook."
2050 PRINT AT 21,0; FLASH 1; BRIGHT 1; PAPER 2;" PRESS APPROPRIATE NUMBER "
2060 IF INKEY$<>"1" AND INKEY$<>"2" THEN GO TO 2050
2070 IF INKEY$="1" THEN GO TO 26
3000 CLS : BORDER 2
3002 LET tc=0
3005 LET b=0: LET c=0: LET d=0
3010 PRINT PAPER 3;" STATEMENT RECCONCILLATION "
3015 LPRINT : LPRINT : LPRINT " STATEMENT RECCONCILLATION "
3020 PRINT AT 19,0;"ENTER CHECKS OUTSTANDING: CKS:IN"'" CHECKBOOK BUT NOT ON STATEMENT"
3023 LPRINT INVERSE 1;" CHECKS OUTSTANDING "
3024 PRINT AT 2,0; INVERSE 1;" CHECKS OUTSTANDING "
3025 PRINT AT 1,3; PAPER 6;"DATE:";AT 1,15;e$;AT 1,0; OVER 1;"________________________________"
3026 LPRINT AT 1,15-LEN e$/2-3;"Date: ";e$;AT 1,0; OVER 1;"________________________________"
3027 PRINT AT 3,0;"CHECK #/date AMOUNT TOTAL ";AT 3,0; OVER 1;"________________________________"
3028 LPRINT "CHECK #/date AMOUNT TOTAL ";AT 4,0; OVER 1;"________________________________"
3030 INPUT "ENTER CHECK DATE OR NUMBER:"' PAPER 2;"enter ""f"" when finished ";i$
3035 IF i$="f" THEN GO TO 4000
3040 PRINT i$;
3041 LPRINT i$;
3050 INPUT "ENTER AMOUNT OF CHECK";c
3052 LET tc=tc+c
3055 GO SUB 200: PRINT TAB 12;"$";TAB 21-LEN c$;c$;
3056 LPRINT TAB 12;"$";TAB 21-LEN C$;C$;
3060 GO SUB 400: PRINT TAB 23;"$";TAB 32-LEN b$;b$
3061 LPRINT TAB 23;"$";TAB 32-LEN b$;b$
3090 GO TO 3030
4000 CLS : BORDER 1: PRINT PAPER 3;" STATEMENT RECCONCILLATION "
4001 LPRINT : LPRINT : LPRINT PAPER 3;" STATEMENT RECCONCILLATION "
4002 LET b=0: LET d=0: LET c=0
4003 LET td=0
4005 PRINT AT 19,0;"ENTER DEPOSITS OUTSTANDING:DEP."'"IN CHECKBOOK : NOT ON STATEMENT"
4010 LPRINT INVERSE 1;" DEPOSITS OUTSTANDING "
4011 PRINT AT 1,0; INVERSE 1;" DEPOSITS OUTSTANDING "
4017 PRINT AT 2,3; PAPER 6;"DATE:";AT 2,15;e$;AT 2,0; OVER 1;"________________________________"
4018 LPRINT AT 1,15-LEN e$/2-3;"Date: ";e$;AT 1,0; OVER 1;"________________________________"
4030 PRINT AT 3,0;"DEPOSIT#/DATE AMOUNT TOTAL ";AT 3,0; OVER 1;"________________________________"
4040 LPRINT "DEPOSIT#/DATE AMOUNT TOTAL ";AT 4,0; OVER 1;"________________________________"
4045 INPUT "ENTER DEPOSIT DATE OR NUMBER:"' PAPER 2;"enter ""f"" when finished ";i$
4048 IF I$="f" THEN GO TO 5000
4050 PRINT i$;
4055 LPRINT i$;
4058 INPUT "ENTER AMOUNT OF DEPOSIT ";d
4059 LET td=td+d
4060 GO SUB 300: PRINT TAB 12;"$";TAB 21-LEN d$;d$;
4061 LPRINT TAB 12;"$";TAB 21-LEN d$;d$;
4065 GO SUB 400: PRINT TAB 23;"$";TAB 32-LEN b$;b$
4070 LPRINT TAB 23;"$";TAB 32-LEN b$;b$
4080 GO TO 4045
5000 CLS : BORDER 6: PRINT PAPER 6;" FINAL RECONCILLIATION "
5001 LPRINT : LPRINT : LPRINT ; INVERSE 1;" FINAL RECONCILLIATION "
5005 INPUT "ENTER FINAL BALANCE ON BANK STATEMENT: ";b
5008 LET b=INT (b*100+.5): GO SUB 400
5010 PRINT "STATEMENT BALANCE:";
5011 IF b<0 THEN PRINT TAB 23; PAPER 2; BRIGHT 1;"$";TAB 25;"-";TAB 32-LEN b$;b$
5012 IF b>=0 THEN PRINT TAB 23;"$";;TAB 32-LEN b$;b$
5015 LPRINT "STATEMENT BALANCE:";
5017 IF b<0 THEN LPRINT TAB 23; INVERSE 1;"$";TAB 25;"-";TAB 32-LEN b$;b$
5018 IF b>=0 THEN LPRINT TAB 23;"$";;TAB 32-LEN b$;b$
5019 LET d=INT (td*100+.5): GO SUB 310
5020 PRINT : PRINT "ADDITIONAL DEPOSITS"'"FROM CHECKBOOK:";TAB 23;"$";TAB 32-LEN d$;d$
5021 LPRINT : LPRINT "ADDITIONAL DEPOSITS"'"FROM CHECKBOOK:";TAB 23;"$";TAB 32-LEN d$;d$
5035 PRINT "--------------------------------"
5036 LPRINT "--------------------------------"
5038 GO SUB 410
5040 PRINT "TOTAL:";
5041 IF b<0 THEN PRINT TAB 23; BRIGHT 1; PAPER 2;"$";TAB 25;"-";TAB 32-LEN b$;b$
5042 IF b>=0 THEN PRINT TAB 23;"$";TAB 32-LEN b$;b$
5043 LPRINT "TOTAL:";
5044 IF b<0 THEN LPRINT INVERSE 1;TAB 23;"$";TAB 25;"-";TAB 32-LEN b$;b$
5045 IF b>=0 THEN LPRINT TAB 23;"$";TAB 32-LEN b$;b$
5048 PRINT "--------------------------------"
5049 LPRINT "--------------------------------"
5050 LET C=INT (TC*100+.5)
5055 GO SUB 210
5060 PRINT : PRINT "LESS CHECKS OUTSTANDING";TAB 23;"$";TAB 32-LEN C$;C$
5061 LPRINT : LPRINT "LESS OUTSTANDING CHECKS:";TAB 23;"$";TAB 32-LEN C$;C$
5065 GO SUB 400
5070 PRINT "--------------------------------"
5071 LPRINT "--------------------------------"
5080 PRINT : PRINT PAPER 5;"FINAL BALANCE:";: IF b<0 THEN PRINT TAB 20; BRIGHT 1; PAPER 2;"OD $";TAB 25;"-";TAB 32-LEN B$;B$
5081 IF b>=0 THEN PRINT TAB 23;"$";TAB 32-LEN b$;b$
5085 LPRINT : LPRINT "FINAL BALANCE:";: IF b<0 THEN LPRINT TAB 20; INVERSE 1;"OD $";TAB 25;"-";TAB 32-LEN B$;B$
5086 IF b>=0 THEN LPRINT TAB 23;"$";TAB 32-LEN b$;b$
5090 PRINT "--------------------------------"
5091 LPRINT "--------------------------------"
5100 INPUT "NOW ENTER CHECKBOOK BALANCE:";CB
5110 LET CB=CB*100
5112 LET B$=STR$ CB: GO SUB 420
5114 PRINT "CKBOOK BALANCE:";TAB 32-LEN B$;B$
5115 LPRINT "CKBOOK BALANCE:";TAB 32-LEN B$;B$
5117 IF B=CB THEN PRINT ;TAB 3; PAPER 5;;"O.K. CORRECT BALANCE:$";TAB 32-LEN B$; PAPER 7;B$
5118 IF B=CB THEN LPRINT ;TAB 3; INVERSE 1;"O.K.CORRECT BALANCE:$";TAB 32-LEN B$;B$
5120 IF B=CB THEN GO TO 5200
5123 LET B$=STR$ (B-CB): GO SUB 420
5124 IF B>CB THEN PRINT PAPER 1;"CKBOOK BAL.IS UNDER:$";TAB 32-LEN B$; PAPER 7;B$
5125 IF B>CB THEN LPRINT INVERSE 1;"CKBOOK BAL.IS UNDER:$";TAB 32-LEN B$;B$
5130 IF B<CB THEN PRINT PAPER 2;"CKBOOK BAL.IS OVER:$";TAB 32-LEN B$; PAPER 7;B$
5131 IF B<CB THEN LPRINT INVERSE 1;;"CKBOOK BAL.IS OVER:$";TAB 32-LEN B$;B$
5190 PRINT AT 20,0; PAPER 5;"Above balance should equal bal- ance in your checkbook."
5200 PRINT AT 20,0; PAPER 5;"Balance should equal CKbook Bal."
5210 PRINT PAPER 4;" PRESS ANY KEY TO START AGAIN "
5220 PAUSE 0: CLS : BEEP .2,25: GO TO 2000
Note: Type-in program listings on this website use ZMAKEBAS notation for graphics characters.
