Schedi-Mort

Products: Schedi-Mort
Date: 1983
Type: Cassette
Platform(s): TS 1000
Tags: Finance

SCHEDI-MORT is a loan amortization scheduler that computes periodic payment amounts and produces a full schedule showing payment number, payment amount, interest portion, principal portion, and remaining balance for each period. The program supports five payment frequencies (daily, weekly, monthly, quarterly, and yearly) and uses the standard annuity formula H = (I1 / (1 − (1 + I1)^(−P))) × L to derive the fixed payment, with each period’s values rounded to the nearest cent using INT(…×100 + 0.5)/100. Output can be directed either to the screen or to a printer, with the printer path offering a choice between 32-column and 80-column widths, adjusting TAB positions via a scaling factor S. A decorative border routine at line 1020 draws a pixel-level rectangle using PLOT, and block-graphic characters (the inverse checkerboard \!!) form separator lines throughout the display.


Program Analysis

Program Structure

The program is organized into a linear sequence of distinct phases, with a subroutine for border drawing and a branch into a separate printer output path:

  1. Lines 20–220: Splash screen — fills the display with inverse characters, draws a pixel border, and shows title, publisher, and copyright notices with timed pauses.
  2. Lines 230–360: Publisher information and extended copyright warning screens.
  3. Lines 370–630: Input phase — borrower name, date, interest rate, loan amount, payment frequency, and number of payments.
  4. Lines 631–635: Printer selection branch; if printing is wanted, jumps to line 1110.
  5. Lines 640–920: Screen output path — computes and displays the amortization table.
  6. Lines 930–1010: Repeat-or-exit prompt, looping back to line 370 or stopping.
  7. Lines 1020–1100: Border subroutine using PLOT.
  8. Lines 1110–1440: Printer output path — mirrors the screen path but uses LPRINT with width-adjusted TAB positions, then falls through to the repeat prompt at line 940.

Amortization Formula

The fixed periodic payment H is computed at line 810 (screen) and line 1330 (printer) using the standard annuity formula:

H = INT(((I1 / (1 − (1 + I1)^(−P))) × L × 100) + 0.5) / 100

where I1 = I / R is the per-period interest rate, P is the total number of payments, and L is the loan principal. The ** operator is used for exponentiation. Each period’s interest portion V1 and updated balance L are also rounded to the nearest cent in the same way, preventing floating-point drift from accumulating across hundreds of periods.

Payment Frequency Handling

The variable R holds the number of periods per year, set by string comparison against the user’s single-letter input:

InputPeriodR
DDaily365
WWeekly52
MMonthly12
QQuarterly4
YYearly1

The program also normalizes the interest rate at line 480: if the entered value is greater than 1 (i.e., entered as a percentage rather than a decimal), it divides by 100.

Printer Output Path

When the user requests a printed copy (line 634–635), execution jumps to the subroutine starting at line 1110. The user selects between 32-column (Q$="A", S=0) and 80-column (Q$="B", S=5) output. All TAB positions in the LPRINT statements are scaled by multiples of S (e.g., TAB(5+2*S), TAB(10+4*S)) so that columns spread appropriately for wider paper. The 80-column separator uses 80 asterisk characters, while the 32-column version uses the block-graphic inverse checkerboard pattern.

Display Techniques

  • Screen fill: Lines 30–90 allocate a 704-character string A$, fill every element with the inverse @ character (creating a solid block pattern), and PRINT it to cover the entire display.
  • Pixel border: The subroutine at lines 1020–1100 uses PLOT to draw a rectangular border along the edges of the 64×44 pixel ZX81 screen, called before each major text screen.
  • Separator lines: The variable Z$ is assigned a 32-character string of the block-graphic inverse checkerboard (\!! escape sequences) to form decorative horizontal rules above and below the schedule header and footer.
  • Timed displays: PAUSE statements throughout (ranging from 60 to 900 frames) control how long each splash, copyright, and summary screen remains visible.

Key BASIC Idioms

  • The FAST/SLOW pair (lines 20/110 and 240/260) switches the display mode for faster string initialization before returning to normal rendering.
  • Repeated IF tests (lines 560–600, 710–750) replace a SELECT/CASE structure absent from this BASIC dialect.
  • The loop at lines 50–70 pre-fills A$(F) one character at a time, which is required because DIM initializes a string array to spaces and direct substring assignment fills all elements.

Bugs and Anomalies

  • Final payment rounding: Because each payment is a fixed rounded value of H, the final period’s remaining balance L will generally not reach exactly zero — a common artifact of fixed-payment amortization schedules that do not include a balloon-payment adjustment for the last period.
  • No input validation: There is no check that B$ matches one of the five valid letters; an unrecognized entry leaves R undefined (or retaining a prior value), which would produce incorrect results without any error message.
  • Column label mismatch: The column header uses “PRINCIPLE” (line 800/1320) rather than the standard spelling “PRINCIPAL.”
  • LPRINT AT usage: Lines 1210 uses LPRINT AT 7,0; — the AT modifier has no defined effect on a printer and the behaviour depends on the specific printer driver in use.

Content

Appears On

Related Products

Professional amortization scheduler.

Related Articles

Related Content

Image Gallery

Schedi-Mort

Source Code

  10 REM "SCHEDI-MORT"
  20 FAST 
  30 DIM A$(704)
  40 LET A$="\@@"
  50 FOR F=1 TO 704
  60 LET A$(F)=A$
  70 NEXT F
  80 PRINT AT 0,0;
  90 PRINT A$
 100 PRINT AT 0,0;
 110 SLOW 
 120 GOSUB 1020
 130 PAUSE 60
 140 PRINT AT 7,8;"\ .\:'\''\''\''\''\''\''\''\''\''\''\''\':\. "
 150 PRINT AT 8,8;"\ : SCHEDI-MORT \: "
 160 PRINT AT 9,8;"\ '\:.\..\..\..\..\..\..\..\..\..\..\..\.:\' "
 170 PAUSE 120
 180 PRINT AT 13,10;"PROFESSIONAL"
 190 PRINT AT 14,5;"AMORTIZATION SCHEDULER"
 200 PAUSE 60
 210 PRINT AT 18,9;"COPYRIGHT 1983"
 220 PAUSE 360
 230 CLS 
 240 FAST 
 250 GOSUB 1020
 260 SLOW 
 270 PRINT AT 8,10;"SCHEDI-MORT"
 280 PRINT TAB (8);"IS A PRODUCT OF" 
 290 PRINT TAB (4);"E. ARTHUR BROWN COMPANY"
 300 PRINT TAB (5);"1702 OAK KNOLL DRIVE"
 310 PRINT TAB (5);"ALEXANDRIA, MN 56308"
 320 PAUSE 360
 330 CLS 
 340 PRINT AT 5,0;"COPYRIGHT 1983 BY EBEN A. BROWN.ALL RIGHTS RESERVED.  NO PART OFTHIS  PROGRAM MAY BE  REPRODUCEDFOR RESALE BY ANY MEANS,MECHANI-CAL  OR  ELECTRONIC,   INCLUDINGPHOTOCOPYING,  RECORDING, OR ANYINFORMATION STORAGE AND RETRIEV-AL SYSTEM  WITHOUT  WRITTEN PER-MISSION FROM THE AUTHOR.";
 350 PRINT "CASSETTEAND  PRINTED  VERSIONS  OF  THISPROGRAM  ARE  PRODUCED ON COPY -DETECTING   MAGNETIC   TAPE  ANDPAPER.  COPYRIGHT   INFRINGEMENTIS A FEDERAL OFFENSE."
 360 PAUSE 900
 370 CLS 
 380 PRINT AT 6,5;"ENTER NAME OF BORROWER"
 390 INPUT F$
 400 PRINT AT 10,7;"ENTER TODAYS DATE"
 410 INPUT E$
 420 CLS 
 430 PRINT AT 8,6;"ENTER INTEREST RATE"
 440 INPUT I
 450 PRINT AT 12,7;"ENTER LOAN AMOUNT"
 460 INPUT L
 470 CLS 
 480 IF I>1 THEN LET I=I/100
 490 PRINT AT 2,3;"SELECT YOUR PAYMENT PERIOD"
 500 PRINT TAB (6);"(D) DAILY"
 510 PRINT TAB (6);"(W) WEEKLY"
 520 PRINT TAB (6);"(M) MONTHLY"
 530 PRINT TAB (6);"(Q) QUARTERLY"
 540 PRINT TAB (6);"(Y) YEARLY"
 550 INPUT B$
 560 IF B$="D" THEN LET R=365
 570 IF B$="W" THEN LET R=52
 580 IF B$="M" THEN LET R=12
 590 IF B$="Q" THEN LET R=4
 600 IF B$="Y" THEN LET R=1
 610 PRINT AT 9,1;"ENTER TOTAL NUMBER OF PAYMENTS"
 620 INPUT P
 630 CLS 
 631 PRINT AT 9,3;"WILL YOU BE NEEDING A PRINTEDCOPY?"
 632 PRINT TAB (10);"(Y)YES"
 633 PRINT TAB (10);"(N)NO"
 634 INPUT Y$
 635 IF Y$="Y" THEN GOTO 1110
 640 LET Z$="\!!\!!\!!\!!\!!\!!\!!\!!\!!\!!\!!\!!\!!\!!\!!\!!\!!\!!\!!\!!\!!\!!\!!\!!\!!\!!\!!\!!\!!\!!\!!\!!"
 650 LET I1=I/R
 655 CLS 
 660 PRINT AT 7,0;Z$
 670 PRINT AT 9,5;"AMORTIZATION SCHEDULE"
 680 PRINT TAB (7);"FOR ";F$
 690 PRINT TAB (15);"ON"
 700 PRINT TAB (12);E$
 710 IF B$="D" THEN PRINT "$";L;" AT ";I*100;" PERCENT-PAID DAILY"
 720 IF B$="W" THEN PRINT "$";L;" AT ";I*100;" PERCENT-PAID WEEKLY"
 730 IF B$="Q" THEN PRINT "$";L;" AT ";I*100;" PERCENT-PAID QUARTERLY"
 740 IF B$="M" THEN PRINT "$";L;" AT ";I*100;" PERCENT-PAID MONTHLY"
 750 IF B$="Y" THEN PRINT "$";L;" AT ";I*100;" PERCENT-PAID YEARLY"
 760 PRINT 
 770 PRINT Z$
 780 PAUSE 360
 790 CLS 
 800 PRINT "PERIOD";TAB (5);"PAYMENT";TAB (10);"INTEREST";TAB (15);"PRINCIPLE";TAB (20);"REM. BAL."
 810 LET H=((INT (((I1/(1-(1+I1)**(-P)))*L*100)+.5)))/100
 820 FOR V=1 TO P
 830 LET V1=(INT (L*I1*100+.5))/100
 840 LET L=(INT (((L-(H-V1))*100)+.5))/100
 850 PRINT V;TAB (5);H;"      ";TAB (10);V1;"      ";TAB (15);H-V1;"      ";TAB (20);L
 860 NEXT V
 870 PRINT Z$
 880 PRINT 
 890 PRINT TAB (6);"PROCESSING COMPLETE"
 900 PRINT 
 910 PRINT Z$
 920 PAUSE 200
 930 CLS 
 940 PRINT AT 10,0;"DO YOU WISH TO AMORTIZE ANY MORE LOANS? (YES) OR (NO)"
 950 INPUT U$
 960 IF U$="YES" THEN GOTO 370
 970 CLS 
 980 PRINT AT 10,2;"OKAY,THAT ENDS THIS PROCESSING RUN"
 990 PAUSE 240
\n1000 CLS 
\n1010 STOP 
\n1020 FOR G=0 TO 63
\n1030 PLOT G,0
\n1040 PLOT G,43
\n1050 NEXT G
\n1060 FOR J=0 TO 43
\n1070 PLOT 0,J
\n1080 PLOT 63,J
\n1090 NEXT J
\n1100 RETURN 
\n1110 CLS 
\n1120 PRINT AT 9,0;"PLEASE SELECT THE SIZE OF PRINT-OUT YOU DESIRE."
\n1130 PRINT TAB (6);"(A)32 CHARACTER WIDTH"
\n1140 PRINT TAB (6);"(B)80 CHARACTER WIDTH"
\n1150 INPUT Q$
\n1160 IF Q$="A" THEN LET S=0
\n1170 IF Q$="A" THEN LET Z$="\!!\!!\!!\!!\!!\!!\!!\!!\!!\!!\!!\!!\!!\!!\!!\!!\!!\!!\!!\!!\!!\!!\!!\!!\!!\!!\!!\!!\!!\!!\!!\!!"
\n1180 IF Q$="B" THEN LET S=5
\n1189 IF Q$="B" THEN LET Z$="********************************************************************************"
\n1200 LET I1=I/R
\n1210 LPRINT AT 7,0;Z$
\n1220 LPRINT AT 9,5+3*S;"AMORTIZATION SCHEDULE"
\n1230 LPRINT TAB (7+3*S);"FOR ";F$
\n1240 LPRINT TAB (12+3*S);E$
\n1250 IF B$="D" THEN LPRINT TAB (3*S);"$";L;" AT ";I*100;" PERCENT-PAID DAILY"
\n1260 IF B$="W" THEN LPRINT TAB (3*S);"$";L;" AT ";I*100;" PERCENT-PAID WEEKLY"
\n1270 IF B$="Q" THEN LPRINT TAB (3*S);"$";L;" AT ";I*100;" PERCENT-PAID QUARTERLY"
\n1280 IF B$="M" THEN LPRINT TAB (3*S);"$";L;" AT ";I*100;" PERCENT-PAID MONTHLY"
\n1290 IF B$="Y" THEN LPRINT TAB (3*S);"$";L;" AT ";I*100;" PERCENT-PAID YEARLY"
\n1300 LPRINT 
\n1310 LPRINT Z$
\n1320 LPRINT "PERIOD";TAB (5+2*S);"PAYMENT";TAB (10+4*S);"INTEREST";TAB (15+6*S);"PRINCIPLE";TAB (20+8*S);"REM.BAL."
\n1330 LET H=((INT (((I1/(1-(1+I1)**(-P)))*L*100)+.5)))/100
\n1340 FOR V=1 TO P
\n1350 LET V1=(INT (L*I1*100+.5))/100
\n1360 LET L=(INT (((L-(H-V1))*100)+.5))/100
\n1370 LPRINT V;TAB (5+2*S);H;"       ";TAB (10+4*S);V1;"       ";TAB (15+6*S);H-V1;"       ";TAB (20+8*S);L
\n1380 NEXT V
\n1390 LPRINT Z$
\n1400 LPRINT 
\n1410 LPRINT TAB (6+2*S);"PROCESSING COMPLETE"
\n1420 LPRINT 
\n1430 LPRINT Z$
\n1435 CLS 
\n1440 GOTO 940

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

Scroll to Top