Real Estate Programs is a menu-driven financial calculator suite offering eight mortgage and property analysis tools, including monthly payment computation, full amortization schedules, remaining balance, accelerated payments, balloon payments, affordable house calculation, mortgage with second, and rental property analysis. The menu dispatch at line 185 uses an arithmetic expression combining the selected menu index with conditional offsets to compute the target subroutine address directly in a GO SUB statement, avoiding a lookup table or series of IF statements. Input is collected into a numeric array P() via a reusable INPAR subroutine that increments a parameter counter K, and string arrays X$() and Q$() handle menu labels and dialog prompts respectively. The amortization schedule loop at lines 665–695 rounds each month’s interest, principal, and balance to cents using INT with a 0.5 offset. A tight INKEY$ polling loop handles all keyboard input throughout, with separate routines for single-character entry and yes/no responses.
Program Structure
The program is organized as a collection of named subroutines, each anchored at a round line number. A top-level loop at lines 100–190 initializes the menu, presents it, collects a choice, and dispatches to the appropriate module. After each module returns, execution loops back to line 100 for reinitalization.
| Line Range | Label / Role |
|---|---|
| 100–190 | Main loop: menu setup and dispatch |
| 235–255 | Payment calculation subroutine (annuity formula) |
| 275–330 | Shared data-entry for amount, rate, term |
| 375–390 | Balance reduction loop (N months) |
| 405–460 | Module 1: Monthly Payment |
| 605–725 | Module 2: Mortgage Schedule |
| 2200–2235 | ANOTH – “Again?” prompt |
| 3000–3030 | DIALOG – three-line status/prompt display |
| 3800–3830 | INCH – single-character input via INKEY$ |
| 4200–4240 | INIT – CLS, title, DIM arrays |
| 4400–4440 | INPAR – prompt and read one parameter into P(K) |
| 4600–4690 | MENU – display choices, validate selection |
| 4800–4845 | PAUSE – “press any key” routine |
| 5400–5435 | YES-NO – accept only Y or N via INKEY$ |
| 6635 | Orphaned GO SUB 4400 with no enclosing module |
Menu Dispatch Technique
Line 185 is the most distinctive feature of the program:
GO SUB X*200+(200 AND X<5)+(300 AND X>4)
This computes the target subroutine address arithmetically from the user’s menu choice X. For choices 1–4, the offset is X*200+200, producing addresses 400, 600, 800, and 1000. For choices 5–8, the offset is X*200+300, yielding 1300, 1500, 1700, and 1900. This avoids a chain of IF … GO SUB statements and doubles as a compact dispatch table, though it requires the modules to be placed precisely at those line numbers.
Parameter Input System
User inputs are stored in the numeric array P(10). The subroutine INPAR (line 4400) uses a global counter K to index successive entries: it displays the prompt stored in Q$(3), reads a value into P(K), echoes it on screen with PRINT AT, and increments K. Callers set K=1 before the first call and update Q$(3) before each call. This makes adding or reordering inputs straightforward.
Dialog / Prompt System
All user-facing messages use a three-slot string array Q$(3,32). The DIALOG subroutine (line 3000) prints a separator line followed by the concatenation of Q$(1), Q$(2), and Q$(3) on consecutive screen rows. Modules load these slots before calling GO SUB 3000 directly or via INPAR/ANOTH, giving a uniform look to every prompt without duplicating PRINT statements.
Penny-Rounding Arithmetic
Financial values are rounded to the nearest cent throughout using the standard idiom:
INT(value * 100 + 0.5) / 100
This appears at line 439 for the monthly payment result, and at lines 670, 675, and 680 inside the amortization schedule loop to keep interest, principal, and balance figures consistent across iterations.
INKEY$ Input Loops
Three distinct routines handle keyboard input without using INPUT for single keypresses:
- INCH (3820–3825): tight poll on
INKEY$until a non-empty character arrives, stored inC$. - YES-NO (5415–5430): polls until exactly “Y” or “N” is pressed, stored in
Y$. - PAUSE (4835–4840): polls until any key is pressed, stored in
Z$.
The MENU routine calls INCH and converts the result with VAL C$, treating “0” as choice 10 for a potential tenth menu option.
Array Reinitialization
The INIT subroutine (line 4200) calls DIM X$(10,28), DIM Q$(3,32), and DIM P(10) every time a new module is entered via the main loop. This clears all arrays to empty/zero before each module populates them, preventing stale values from a prior run. It is a simple but effective reset strategy.
Notable Anomalies
- Line 6635 (
GO SUB 4400) appears in isolation with no surrounding module code. It is likely a fragment of an unfinished or partially deleted module. - The MENU subroutine (lines 4605–4610) contains a
FOR J=1 TO 10 … NEXT Jloop with no body, which serves only as a brief delay and has no functional effect on program logic. - The listing includes
REMcomments at key subroutine entries (e.g.,REM "ANOTH",REM "DIALOG") that serve as subroutine name labels, a common documentation convention when the language lacks named procedures. - Several modules referenced by the dispatch formula (addresses 800, 1000, 1300, 1500, 1700, 1900) are absent from the provided listing, suggesting the listing is incomplete.
Content
Source Code
100 REM
105 LET N$="REAL ESTATE PROGRAMS"
115 GO SUB 4200
135 LET X$(1)="MONTHLY PMT"
140 LET X$(2)="MORTGAGE SCHEDULE"
145 LET X$(3)="REMAINING BALANCE"
150 LET X$(4)="ACCELERATED PAYMTS"
155 LET X$(5)="BALLON PMT"
160 LET X$(6)="AFFORDABLE HOUSE"
165 LET X$(7)="MORTGAGE W/SECOND"
170 LET X$(8)="RENTAL PROP ANALYSIS"
175 LET N=8
180 GO SUB 4600
185 GO SUB X*200+(200 AND X<5)+(300 AND X>4)
190 GO TO 100
235 LET N1=12*YR
240 LET I1=IN/100/12
245 LET V=1/(1+I1)
250 LET P=AM*I1/(1-V^N1)
255 RETURN
275 LET Q$(1)="SPECIFY DATA"
280 LET Q$(2)=""
285 LET Q$(3)="AMT BORROWED ($)"
290 GO SUB 4400
295 LET Q$(3)="ANN,INT RATE % "
300 GO SUB 4400
305 LET Q$(3)="TERM OF LOAN (YRS)"
310 GO SUB 4400
315 LET AM=P(1)
320 LET IN=P(2)
325 LET YR=P(3)
330 RETURN
375 FOR I=1 TO N
380 LET AM=AM-P+IN/12/100*AM
385 NEXT I
390 RETURN
405 LET N$="MONTHLY PMT"
415 GO SUB 4200
420 LET K=1
425 GO SUB 260
430 GO SUB 195
435 PRINT
439 LET P= INT (P*100+.5)/100
440 PRINT "MONTHLY PMT IS"; TAB 23;P
445 LET Q$(2)="COMPUTE"
450 GO SUB 2200
455 IF Y$="N" THEN RETURN
460 GO TO 400
605 LET N$="MORTGAGE SCHEDULE"
615 GO SUB 4200
620 LET K=1
625 GO SUB 260
630 LET Q$(3)="YEAR YOU WANT?"
635 GO SUB 4400
640 LET N=P(4)
645 GO SUB 195
650 LET N=12*N-12
655 GO SUB 335
657 PAUSE 60:CLS
660 PRINT "MONTH PRINC INT BAL"
661 PRINT
665 FOR J=1 TO 12
670 LET I1= INT (IN/12*AM+.5)/100
675 LET P1= INT (100*(P-I1)+.5)/100
680 LET AM= INT (100*(AM-P1)+.5)/100
685 PRINT AT J+2,0;" ";
689 PRINT AT J+2,0;N+1; TAB 6;P1; TAB 13;I1; TAB 22;AM
690 LET N=N+1
695 NEXT J
698 PRINT
700 PRINT "PRESS ENTER WHEN READY "
704 PRINT " "
705 INPUT A$
710 LET Q$(2)="COMPUTE"
715 GO SUB 2200
720 IF Y$="N" THEN RETURN
725 GO TO 600
2200 REM "ANOTH"
2215 LET Q$(1)="DO YOU WANT TO"
2220 LET Q$(3)="AGAIN (Y OR N)"
2225 GO SUB 3000
2230 GO SUB 5400
2235 RETURN
3000 REM "DIALOG"
3020 PRINT AT 18,0;"--------------------------------"
3025 PRINT Q$(1);Q$(2);Q$(3)
3030 RETURN
3800 REM "INCH"
3815 REM WAIT FOR INPUT CHAR
3820 LET C$= INKEY$
3825 IF C$="" THEN GO TO 3820
3830 RETURN
4200 REM "INIT"
4215 CLS
4220 PRINT N$
4225 DIM X$(10,28)
4230 DIM Q$(3,32)
4235 DIM P(10)
4240 RETURN
4400 REM "INPAR"
4420 GO SUB 3000
4425 INPUT P(K)
4430 PRINT AT K+2,0;Q$(3); AT K+2,23;P(K)
4435 LET K=K+1
4440 RETURN
4600 REM "MENU"
4605 FOR J=1 TO 10
4610 NEXT J
4615 CLS
4620 FOR I=1 TO N
4625 IF I=10 THEN PRINT "0 = ";X$(I)
4630 IF I<10 THEN PRINT I;" = ";X$(I)
4635 NEXT I
4640 LET Q$(1)=""
4645 LET Q$(2)=""
4650 LET Q$(3)="CHOOSE PROGRAM"
4655 GO SUB 3000
4660 GO SUB 3800
4665 LET X= VAL C$
4670 IF X=0 THEN LET X=10
4675 IF X >=1 AND X <=N THEN RETURN
4680 LET Q$(1)="ILLEGAL CHOICE -CHOOSE AGAIN":BEEP .5,10
4685 GO SUB 3000
4690 GO TO 4660
4800 REM "PAUSE"
4815 LET Q$(1)="PRESS ANY KEY TO CONTINUE"
4820 LET Q$(2)=""
4825 LET Q$(3)=""
4830 GO SUB 3000
4835 LET Z$= INKEY$
4840 IF Z$="" THEN GO TO 4835
4845 RETURN
5400 REM "YES-NO"
5415 LET Y$= INKEY$
5420 IF Y$="" THEN GO TO 5415
5425 IF Y$="Y" OR Y$="N" THEN GO TO 5435
5430 GO TO 5415
5435 RETURN
6635 GO SUB 4400
Note: Type-in program listings on this website use ZMAKEBAS notation for graphics characters.
