--- title: "Stamp Collector" id: 51778 type: "computer_media" slug: "stamp-collector" url: "http://localhost/computer_media/stamp-collector/" markdown_url: "http://localhost/computer_media/stamp-collector.md" published_at: "2023-08-13T23:14:31+00:00" modified_at: "2026-04-04T20:18:02+00:00" author: "David Anderson" featured_image: url: "http://localhost/wp-content/uploads/2019/02/20230809-041332.jpg" excerpt: "A full philatelic inventory system lets you log stamps by Scott number and condition, adjust quantities, flag wanted items, and save your collection to tape." 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: "Timex Computer Corporation" slug: "timex-computer-corporation" taxonomy: "post_tag" url: "http://localhost/tag/timex-computer-corporation/" - 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: "Hobby" slug: "hobby" taxonomy: "genre" url: "http://localhost/type/hobby/" media_type: "Program" download_url: "https://archive.org/download/timex-sinclair-software-archive/Stamp Collector (1983)(Timex)(US)(TS1000)(Cassette).zip" mediadate: "1983" producer_company: - id: 11401 title: "Timex Computer Corporation" type: "company" url: "http://localhost/company/timex-computer-corporation/" images: - url: "http://localhost/wp-content/uploads/2023/08/SCR-20260404-eigq.png" related_products: - id: 14040 title: "Stamp Collector" type: "product" url: "http://localhost/product/stamp-collector/" media_type_tags: "Hobby" --- Stamp Collector is a philatelic inventory management program that allows users to track postage stamp collections by Scott catalog number and condition category. It uses a two-dimensional string array, `F$`, dimensioned at 600 rows by 15 characters, where each record packs a 5-character Scott number, a 1-character condition code, a 6-character quantity field, and a 1-character want-list flag. The program supports 18 stamp categories (singles, blocks, plate blocks, coils, imperforate, first day covers, and strips in mint or used conditions) encoded as alphanumeric codes 1–9 and A–H. Options include adjusting inventory quantities with positive or negative values, searching records by number and type, listing wanted stamps, and saving the entire array to tape. *** ## Program Analysis ### Program Structure The program is organized as a menu-driven application anchored at line `70`, which calls the main menu subroutine at `1000` and dispatches to one of five branches based on the value of `O$`. The structure is as follows: - **Lines 50–80:** Initialization — sets SLOW mode, dimensions the master array, and enters the menu loop. - **Lines 1000–1099:** Main menu display and input subroutine. - **Lines 1500–1599:** Code-to-description translation subroutine (maps `C$` to human-readable `J$`). - **Lines 2000–2022:** Quit confirmation handler. - **Lines 2500–2999:** Option 1 — Adjust inventory (add/remove a stamp record or update quantity). - **Lines 3000–3320:** Option 2 — Search inventory by Scott number and/or category. - **Lines 3500–3710:** Option 3 — List all stamps flagged on the want list. - **Lines 4000–4020:** Option 4 — Save the inventory array to tape. - **Lines 5000–5999:** Classification input subroutine (displays category table, reads code into `C$`). ### Data Storage Layout All data is held in the two-dimensional string array `F$(600,15)`. Each row encodes one inventory record using a fixed-width field layout: | Columns | Width | Contents | | --- | --- | --- | | 1–5 | 5 | Scott catalog number (left-justified, space-padded) | | 6 | 1 | Condition/type code (1–9, A–H) | | 7–12 | 6 | Quantity as a string (`STR$` of numeric value) | | 13 | 1 | Want-list flag (“Y” or “N”) | | 14–15 | 2 | Unused | The 6-character key `K$` formed by concatenating the padded Scott number and the type code (columns 1–6) serves as a composite primary key for searching and insertion. ### Menu Input Idiom The main menu uses a polling loop rather than `INPUT` for single-keypress capture. Line `1028` waits until `INKEY$` is non-empty, then line `1029` captures the character into `O$`. Line `1030` validates the key and re-loops on invalid input. The same pattern is repeated in the classification subroutine at lines `5072`–`5075` and in the quit confirmation at lines `2016`–`2022`. This approach avoids the cursor and input-buffer overhead of `INPUT` for menu navigation. ### Inventory Adjustment Logic Option 1 (lines 2500–2990) performs a linear scan of `F$` from row 1 to 800 — notably exceeding the declared dimension of 600, which would cause a subscript error if the file is full and the loop reaches row 601. When a blank row is found (line `2556`), a new record is inserted; when a matching key is found (line `2558`), the existing record is updated. The quantity is read back with `VAL F$(N,7 TO 12)`, adjusted by the signed input `Q`, and written back via `STR$ (P+Q)`. Line `2811` guards against negative resulting quantities by looping back to re-enter the adjustment. ### Search Logic The search routine (lines 3000–3320) accepts an optional Scott number. If left blank, `E$` becomes all spaces after padding, and the condition at line `3044` — `IF K$(1 TO 5)=" " AND C$=F$(N,6 TO 6)` — matches all records of the selected type across the entire file, effectively doing a type-only scan. The display subroutine at `3300` uses a counter `G` to suppress clearing the screen after the first match, allowing multiple results to accumulate on screen before prompting for the user to press Enter at end-of-file. ### Category Code Translation The subroutine at lines 1500–1599 maps the single-character `C$` to a descriptive string `J$` using 18 sequential `IF` tests. Codes 1–9 cover numeric ASCII characters and codes A–H cover uppercase letters, giving 18 distinct stamp categories. The validation in the classification subroutine (line `5082`) checks `C$<"1" OR C$>"H"`, which in ASCII order accepts all characters from “1” (ASCII 49) through “H” (ASCII 72), inadvertently including characters like the colon, letters A–G, and digits 1–9 — the intended valid range — but also characters such as “:”, “;”, “<“, “=”, “>”, “?”, “@” which fall between “9” and “A” in ASCII. These intermediate codes would produce the default `J$="?????????"` translation but are otherwise harmless. ### Want List Option 3 (lines 3500–3710) iterates all 600 rows and prints entries where column 13 equals “Y”. The want-list flag is set during inventory adjustment (lines 2840–2842) via a Y/N prompt. The listing routine at line `3600` reads the type code from `F$(N,6 TO 6)` back into `C$` before calling the translation subroutine, correctly recovering the stored category description. ### Tape Save Option 4 prompts the user to ready the tape recorder and then executes `SAVE "STAM%P"` at line `4016`. The `%P` notation represents an inverse-video “P” character in the filename. ### Notable Bugs and Anomalies - The inventory adjustment loop at line `2552` iterates `FOR N=1 TO 800`, but `F$` is only dimensioned to 600 rows. Accessing `F$(N,...)` for N > 600 will cause a subscript error if the file fills up and no match or blank is found within the first 600 entries. - The quit confirmation at lines `2016`–`2022` reads `INKEY$` twice in sequence without looping between the “Y” and “N” checks, meaning the second `INKEY$` call at line `2018` may capture a different (or empty) value than the one that satisfied line `2016`. This can cause neither branch to fire, falling through to the unconditional `GOTO 70` at line `2022`. - Line `2516` prints an error for Scott numbers longer than 5 characters but does not loop back to re-prompt; the program continues to the `GOSUB 5000` at line `2520` regardless. - The search loop at line `3038` iterates `FOR N=1 TO 600`, consistent with the array size, unlike the adjustment loop. However, blank-row detection at line `3040` terminates the scan early, so stamps entered after a gap of blank rows would never be found. ## Source Code ``` 50 REM "STAMP" 52 SLOW 54 DIM F$(600,15) 70 GOSUB 1000 72 IF O$="Q" THEN GOTO 2000 74 IF O$="1" THEN GOTO 2500 76 IF O$="2" THEN GOTO 3000 78 IF O$="3" THEN GOTO 3500 80 IF O$="4" THEN GOTO 4000 999 STOP 1000 CLS 1010 PRINT AT 2,12;"%S%T%A%M%P" 1012 PRINT AT 3,10;"ACCOUNTING" 1014 PRINT AT 5,4;"WHICH OPTION DO YOU DESIRE ?" 1016 PRINT AT 8,4;"%O%P%T%I%O%N";AT 8,15;"%D%E%S%C%R%I%P%T%I%O%N" 1018 PRINT AT 10,6;"1";AT 10,15;"ADJUST INVENTORY" 1020 PRINT AT 12,6;"2";AT 12,15;"SEARCH INVENTORY" 1021 PRINT AT 14,6;"3";AT 14,15;"LIST WANTED NO.S" 1022 PRINT AT 16,6;"4";AT 16,15;"SAVE INVENTORY" 1024 PRINT AT 18,6;"Q";AT 18,15;"QUIT" 1026 PRINT AT 21,0;"%E%N%T%E%R OPTION NUMBER OR Q" 1028 IF INKEY$="" THEN GOTO 1026 1029 LET O$=INKEY$ 1030 IF O$<>"Q" AND O$<>"1" AND O$<>"2" AND O$<>"3" AND O$<>"4" THEN GOTO 1026 1099 RETURN 1500 REM 1501 LET J$="?????????" 1502 IF C$="1" THEN LET J$="MINT SINGLE" 1504 IF C$="2" THEN LET J$="USED SINGLE" 1506 IF C$="3" THEN LET J$="MINT BLOCK" 1508 IF C$="4" THEN LET J$="USED BLOCK" 1510 IF C$="5" THEN LET J$="MINT PLATE" 1512 IF C$="6" THEN LET J$="USED PLATE" 1514 IF C$="7" THEN LET J$="MINT SHEET" 1516 IF C$="8" THEN LET J$="MINT COIL" 1518 IF C$="9" THEN LET J$="USED COIL" 1520 IF C$="A" THEN LET J$="MINT COIL PAIR" 1522 IF C$="B" THEN LET J$="USED COIL PAIR" 1524 IF C$="C" THEN LET J$="MINT LINE PAIR" 1526 IF C$="D" THEN LET J$="USED LINE PAIR" 1528 IF C$="E" THEN LET J$="MINT IMPERF" 1530 IF C$="F" THEN LET J$="USED IMPERF" 1532 IF C$="G" THEN LET J$="USED FIRST DAY" 1534 IF C$="H" THEN LET J$="MINT STRIP" 1599 RETURN 2000 REM 2010 CLS 2012 PRINT AT 1,0;"ARE YOU SURE YOU WANT TO QUIT ?" 2014 PRINT "Y/N" 2016 IF INKEY$="" THEN GOTO 2012 2018 IF INKEY$="Y" THEN STOP 2020 IF INKEY$="N" THEN GOTO 70 2022 GOTO 70 2500 CLS 2510 PRINT "ENTER SCOTT NO. (MAX IS 5 LONG)" 2511 PRINT "IF NO NUMBER THEN ENTER YOUR NO." 2512 INPUT S$ 2514 PRINT S$ 2516 IF LEN S$>5 THEN PRINT "TOO BIG - RE-ENTER 5 OR LESS" 2518 IF LEN S$=0 THEN GOTO 2510 2520 GOSUB 5000 2530 CLS 2535 GOSUB 1500 2540 PRINT "NUMBER ";S$;" ";J$ 2541 PRINT "ENTER THE QUANTITY(+ OR -)" 2545 INPUT Q 2547 PRINT Q 2548 LET S$=S$+" " 2549 LET S$=S$(1 TO 5) 2550 LET K$=S$+C$ 2552 FOR N=1 TO 800 2554 LET X$=F$(N,1 TO 6) 2556 IF X$=" " THEN GOTO 2600 2558 IF X$=K$ THEN GOTO 2700 2560 NEXT N 2600 LET P=0 2610 LET F$(N,1 TO 6)=K$ 2699 GOTO 2710 2700 LET P=VAL F$(N,7 TO 12) 2710 PRINT 2712 PRINT "OLD QUANTITY WAS ";P 2800 REM 2810 PRINT "NEW QUANTITY IS ";P+Q 2811 IF P+Q<0 THEN GOTO 2535 2812 LET F$(N,7 TO 12)=STR$ (P+Q) 2820 PRINT 2825 PRINT AT 18,0;"PLACE THIS STAMP ON WANT LIST ?" 2830 PRINT "Y/N" 2832 IF INKEY$="" THEN GOTO 2825 2840 IF INKEY$="Y" THEN LET F$(N,13 TO 13)="Y" 2842 IF INKEY$="N" THEN LET F$(N,13 TO 13)="N" 2990 GOTO 70 2999 STOP 3000 CLS 3005 LET G=0 3010 CLS 3020 PRINT "ENTER SCOTT NUMBER OR HIT ENTER" 3030 PRINT "IF NUMBER IS BLANK ENTIRE FILE" 3032 PRINT "WILL BE SCANNED" 3034 INPUT E$ 3035 GOSUB 5000 3036 LET E$=E$+" " 3037 LET K$=E$(1 TO 5)+C$ 3038 FOR N=1 TO 600 3040 IF F$(N,1 TO 6)=" " THEN GOTO 3200 3042 IF F$(N,1 TO 6)=K$ THEN GOSUB 3300 3044 IF K$(1 TO 5)=" " AND C$=F$(N,6 TO 6) THEN GOSUB 3300 3046 NEXT N 3050 FOR N=1 TO 100 3052 NEXT N 3055 GOTO 70 3200 IF G>0 THEN GOTO 3240 3201 CLS 3202 GOSUB 1500 3203 PRINT K$(1 TO 5);" ";J$ 3205 PRINT "NO STAMPS OF THIS TYPE ON FILE" 3220 FOR N=1 TO 150 3225 NEXT N 3230 GOTO 70 3240 PRINT "FILE AT END--PRESS ENTER" 3242 INPUT Y$ 3244 GOTO 70 3300 IF G>0 THEN GOTO 3302 3301 CLS 3302 LET G=G+1 3304 GOSUB 1500 3306 PRINT F$(N,1 TO 5);" ";J$;" ";"QUAN= ";F$(N,7 TO 12) 3320 RETURN 3500 REM 3510 CLS 3512 PRINT "WANT LIST" 3514 FOR N=1 TO 600 3520 IF F$(N,1 TO 5)=" " THEN GOTO 3700 3525 IF F$(N,13 TO 13)="Y" THEN GOSUB 3600 3530 NEXT N 3600 LET C$=F$(N,6 TO 6) 3610 GOSUB 1500 3612 PRINT F$(N,1 TO 5);" ";J$ 3699 RETURN 3700 PRINT "FILE AT END-PRESS ENTER" 3705 INPUT Y$ 3710 GOTO 70 3999 STOP 4000 CLS 4010 PRINT "SET TAPE RECORDER FOR RECORD " 4012 PRINT "MODE--START RECORDER" 4014 PRINT "PRESS ENTER WHEN READY" 4015 INPUT Y$ 4016 SAVE "STAM%P" 4018 CLS 4020 GOTO 70 5000 REM 5010 CLS 5012 PRINT "CLASSIFY YOUR REQUEST BY CODE " 5014 PRINT AT 2,0;"%D%E%S%C%R%I%P%T%I%O%N";AT 2,18;"%M%I%N%T %U%S%E%D" 5016 PRINT AT 3,0;"SINGLE";AT 3,19;"1 2" 5018 PRINT AT 4,0;"BLOCK OF FOUR";AT 4,19;"3 4" 5020 PRINT AT 5,0;"PLATE BLOCK";AT 5,19;"5 6" 5022 PRINT AT 6,0;"SHEET";AT 6,19;"7 " 5024 PRINT AT 7,0;"COIL";AT 7,19;"8 9" 5026 PRINT AT 8,0;"COIL PAIR";AT 8,19;"A B" 5028 PRINT AT 9,0;"LINE PAIR";AT 9,19;"C D" 5030 PRINT AT 10,0;"IMPERFORATE";AT 10,19;"E F" 5032 PRINT AT 11,0;"FIRST DAY";AT 11,19;" G" 5034 PRINT AT 12,0;"STRIP";AT 12,19;"H " 5070 PRINT AT 20,0;"%E%N%T%E%R THE APPLICABLE CODE" 5072 IF INKEY$="" THEN GOTO 5070 5075 LET C$=INKEY$ 5082 IF C$<"1" OR C$>"H" THEN GOTO 5070 5083 PRINT C$ 5999 RETURN ```