--- title: "Real Estate Spreadsheet" id: 56985 type: "computer_media" slug: "real-estate-spreadsheet" url: "http://localhost/computer_media/real-estate-spreadsheet/" markdown_url: "http://localhost/computer_media/real-estate-spreadsheet.md" published_at: "2024-10-02T01:14:58+00:00" modified_at: "2026-03-30T21:20:29+00:00" author: "David Anderson" featured_image: url: "http://localhost/wp-content/uploads/2024/10/10_RE_SS.png" excerpt: "A real estate database storing 60 property records with a machine code–driven scrolling spreadsheet view, all packed 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: "TS 1000" slug: "ts1000" taxonomy: "post_tag" url: "http://localhost/tag/ts1000/" model: - name: "Timex/Sinclair 1000" slug: "ts-1000" taxonomy: "model" url: "http://localhost/model/ts-1000/" genre: - name: "Business" slug: "business" taxonomy: "genre" url: "http://localhost/type/business/" - name: "Database" slug: "database" taxonomy: "genre" url: "http://localhost/type/database/" media_contents: - id: 56732 title: "Timex Sinclair Public Domain Library Tape 1001" type: "computer_media" url: "http://localhost/computer_media/timex-sinclair-public-domain-library-tape-1001/" media_type: "Program" mediadate: "198x" images: - url: "http://localhost/wp-content/uploads/2024/10/10_RE_SS.png" media_type_tags: "Business, Database" --- # Real Estate Spreadsheet This program implements a real estate property database and spreadsheet viewer for up to 60 records, each storing fields such as property type, price, mortgage details, loan type, address, city, agency name, and phone number in a fixed-width string array. Record entry is handled through a sequential INPUT menu, with numeric values right-justified into fixed-width fields using LEN STR$ arithmetic. A machine code routine embedded in the REM at line 1 drives the spreadsheet display, invoked via RAND USR 16524, and handles scrolling or navigation through the 60-record array stored at a known memory address. *** ## Program Analysis ### Program Structure The program is organised into three functional blocks: initialisation (lines 1–90), a main menu (lines 105–140), and two branches — the spreadsheet viewer (lines 150–180) and the record entry form (lines 200–440). Line 450 saves the program and line 460 issues a `RUN`, though these are only reachable if control falls through from line 445’s `CLEAR`, which would destroy variables; in practice these lines serve as a manual save/restart facility. ### Data Structures Two string arrays are used. `T$` (line 10, length 100) holds a column-header template string displayed in inverse video. `A$` (line 20, 60×100) holds up to 60 property records, each 100 characters wide, pre-initialised with a fixed template at lines 50–80. The field layout within each 100-character record is as follows: | Columns | Field | | --- | --- | | 1–4 | Property type (4 letters) | | 7–12 | Price (right-justified, 6 chars) | | 14–20 | First mortgage amount (right-justified) | | 25–30 | Loan rate (right-justified) | | 32–35 | Loan type (VA/FHA/CONV) | | 37–67 | Property address (31 chars) | | 69–83 | City (15 chars) | | 85–91 | Agency name (7 chars) | | 93–100 | Phone number (8 chars) | ### Initialisation Loop Lines 40–80 pre-fill all 60 rows of `A$()` with a blank template string containing colon separators and a two-digit record number embedded at columns 2–3 via `LET A$(N,2 TO 3)=STR$ N`. The loop runs in `FAST` mode (line 50) to reduce initialisation time, returning to `SLOW` at line 90. ### Numeric Right-Justification Idiom Lines 260, 290, and 320 use the idiom `LET A$(A, end-LEN STR$ X TO end)=STR$ X` to right-justify a numeric value into a fixed-width field. By subtracting the string length of the number from the field’s last column index, the value is placed flush-right regardless of its magnitude — a common and elegant ZX81 BASIC technique. ### Machine Code Routine (REM Line 1) The REM at line 1 contains 196 bytes of Z80 machine code. It is invoked at line 170 by `RAND USR 16524`. The address 16524 (0x408C) falls within the system variables area on a 16K ZX81, specifically pointing into the REM data. The routine implements the interactive spreadsheet display: it scans the `A$` array data in memory, copies rows to the display file, and polls the keyboard for navigation (scrolling up/down and returning to menu with `M`). The byte sequences `\1D` (dec/INC patterns) at the end of the REM suggest a lookup table or displacement table used for cursor movement within the display. Notable Z80 constructs visible in the machine code include `ED 4A` (ADC HL,BC for 16-bit arithmetic), `CD BB 02` and `CD BD 07` (calls to ROM routines, likely the display or keyboard scan), and block-copy loops using `LD (HL),A` / `INC HL` / `DEC BC` / `LD A,B` / `OR C` patterns. ### Menu and Navigation The main menu at lines 110–140 uses a polling loop: `IF INKEY$="1"` and `IF INKEY$="2"` are tested on successive lines, with `GOTO 120` forming the idle loop. This is the standard ZX81 keypress-detection idiom. The record counter variable `A` is initialised to 1 at line 5 and incremented at line 430 after each successful entry, so successive records fill successive rows of `A$()`. ### Spreadsheet Display Line 160 prints the column headers and a row of block-graphic characters (built from `\''\''` pairs, rendering as solid top-half block characters) as a visual separator, along with a prompt to press `M` for the menu. Control then passes to the machine code via `RAND USR 16524` at line 170; when the routine detects `M` being pressed it returns to BASIC, and line 180 loops back to the menu at line 100 (which does not exist — control therefore falls to line 105, the next extant line, a deliberate technique). ### Notable Anomalies - Line 100 is referenced by `GOTO 100` at lines 180 and 440 but does not exist; the ZX81 will continue from the next line (105, `CLS`), which is the intended behaviour. - Line 445 contains `CLEAR` immediately before `SAVE` at line 450. If executed sequentially, `CLEAR` would erase all variables including `A$` before saving, making the save useless for data preservation. These lines are likely intended to be reached only manually or never during normal program flow. - The variable `A` declared at line 5 as `LET A=1` is also used as a loop variable `N` in the `FOR` loop at lines 40–80. Since `FOR N` does not conflict with simple variable `A`, this is not a bug, but the reuse of a scalar variable as both a record pointer and a loop bound is worth noting. ## Source Code ``` 1 REM \19\48\04\4B\00\00\00\32\98\4A\3E\08\0E\00\21\82\40\71\23\3D\FE\00\20\F9\2A\10\40\7E\FE\C6\28\03\23\18\F8\23\7E\FE\75\28\03\23\18\EF\3E\07\23\3D\FE\00\20\FA\22\84\40\3A\86\40\2A\84\40\01\64\00\FE\00\28\05\ED\4A\3D\18\F7\22\84\40\3A\87\40\2A\84\40\FE\00\28\04\23\3D\18\F8\22\84\40\2A\0C\40\01\A6\00\ED\4A\22\82\40\CD\BB\02\7C\C6\02\38\09\44\4D\CD\BD\07\06\00\4E\79\32\89\40\01\00\0C\0B\78\B1\20\FB\3A\89\40\FE\23\20\0E\3A\86\40\FE\32\28\07\3A\86\40\3C\32\86\40\3A\89\40\FE\22\20\0E\3A\86\40\FE\00\28\07\3A\86\40\3D\32\86\40\3A\87\40\FE\00\28\0E\3A\89\40\FE\24\20\07\3A\87\40\3D\32\87\40\3A\87\40\FE\44\28\0E\3A\89\40\FE\21\20\07\3A\87\40\3C\32\87\40\3E\0A\32\88\40\2A\10\40\7E\FE\D9\28\03\23\18\F8\23\7E\FE\67\28\03\23\18\EF\23\23\23\23\23\3A\87\40\FE\00\28\04\23\3D\18\F8\22\8A\40\2A\0C\40\01\64\00\ED\4A\ED\5B\8A\40\0E\21\1A\77\0D\79\3D\23\13\FE\00\28\02\18\F3\2A\82\40\ED\5B\84\40\0E\21\3A\88\40\FE\0A\20\05\1A\C6\80\18\01\1A\77\0D\79\3D\23\13\FE\00\28\02\18\E7\23\3E\44\13\3D\FE\00\20\FA\3A\88\40\3D\32\88\40\FE\00\C2\A8\41\3A\89\40\FE\32\28\07\FE\28\28\03\C3\9A\40\C9\1B\1B\1B\1D\1D\1D\1D\1D\1D\1D\1D\1D\1D\1D\1D\1D\1D\1D\1D\1D\1D\1D\1D\1D\1D\1D\1D\1E\1E\1E\1E\1E\1E\1E\1E\1E\1E\1E\1E 5 LET A=1 10 DIM T$(100) 20 DIM A$(60,100) 30 LET T$="%T%Y%P%E\ :%P%R%I%C%E% % \ :%1%S%T% %M%O%R%T%G%A%G%E\ :%R%A%T%E\ :%L%O%A%N\ :%A%D%D%R%E%S%S% % % % % % % % % % % % % % % % % % % % % % % % \ :%C%I%T%Y% % % % % % % % % % % \ :% %A%G%E%N%C%Y\ :%P%H%O%N%E% % " 40 FOR N=1 TO 60 50 FAST 60 LET A$(N)=" :$ :$ : : : : : :" 70 LET A$(N,2 TO 3)=STR$ N 80 NEXT N 90 SLOW 105 CLS 110 PRINT AT 5,11;"%M %E %N %U";AT 7,8;"(ENTER CHOICE)";AT 10,5;"1. ENTER A RECORD.";AT 12,5;"2. VIEW SPREADSHEET." 120 IF INKEY$="1" THEN GOTO 200 130 IF INKEY$="2" THEN GOTO 150 140 GOTO 120 150 CLS 160 PRINT " REAL ESTATE SPREADSHEET";AT 16,0;"\''\''\''\''\''\''\''\''\''\''\''\''\''\''\''\''\''\''\''\''\''\''\''\''\''\''\''\''\''\''\''\''";TAB 6;"PRESS ""M"" FOR MENU." 170 RAND USR 16524 180 GOTO 100 200 CLS 210 PRINT "ENTER RECORD INFORMATION." 220 PRINT ,,"1. TYPE? (4 LETTERS)" 230 INPUT A$(A,1 TO 4) 240 PRINT "2. PRICE?" 250 INPUT X 260 LET A$(A,13-LEN STR$ X TO 12)=STR$ X 270 PRINT "3. FIRST MORTGAGE PRICE?" 280 INPUT X 290 LET A$(A,21-LEN STR$ X TO 20)=STR$ X 300 PRINT "4. 1ST MTG. LOAN RATE?" 310 INPUT X 320 LET A$(A,31-LEN STR$ X TO 30)=STR$ X 330 PRINT "5. TYPE OF LOAN (VA-FHA-CONV.)?" 340 INPUT A$(A,32 TO 35) 350 PRINT "6. PROPERTY ADDRESS?" 360 INPUT A$(A,37 TO 67) 370 PRINT "7. CITY?" 380 INPUT A$(A,69 TO 83) 390 PRINT "8. AGENCY OFFERING PROPERTY?" 400 INPUT A$(A,85 TO 91) 410 PRINT "9. AGENCIES PHONE NUMBER?" 420 INPUT A$(A,93 TO 100) 430 LET A=A+1 440 GOTO 100 445 CLEAR 450 SAVE "1001%0" 460 RUN ```