--- title: "Conversational German" id: 51872 type: "computer_media" slug: "conversational-german" url: "http://localhost/computer_media/conversational-german/" markdown_url: "http://localhost/computer_media/conversational-german.md" published_at: "2023-08-16T01:42:19+00:00" modified_at: "2026-04-03T07:59:14+00:00" author: "David Anderson" featured_image: url: "http://localhost/wp-content/uploads/2019/02/20230809-041332.jpg" excerpt: "A six-mode German language tutor quizzes words and phrases in both directions, tracks your score, and prevents repeat questions using a clever array-based deduplication technique." 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: "German" slug: "german" taxonomy: "genre" url: "http://localhost/type/german/" media_type: "Cassette" download_url: "https://archive.org/download/timex-sinclair-software-archive/Conversational German (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/" related_products: - id: 12240 title: "Conversational German" type: "product" url: "http://localhost/product/conversational-german/" media_type_tags: "German" --- Conversational German is an interactive language-learning program that teaches vocabulary and phrases through a quiz-and-review system. It stores vocabulary in string arrays G$, E$, R$, and T$ (German words, English words, German phrases, and English phrases respectively), populated via a GOSUB to line 9000. The program offers six modes: reviewing words or phrases in paginated lists, and four quiz modes testing German-to-English and English-to-German translation in both directions for both individual words and complete phrases. A machine code routine embedded in the REM statement at line 1 is invoked via USR 16514 to perform a screen-clear operation efficiently. Random question selection (lines 5200 and 5400) uses an array to track previously asked questions, preventing repeats within a ten-question round, and a running score S is maintained and displayed at the end of each round. *** ## Program Analysis ### Program Structure The program is organized into several functional blocks: - **Lines 1–60:** Machine code REM stub and initialization; entry point routes to the title/menu via `GOSUB 9000`. - **Lines 100–210:** Word review mode — paginated display of German/English word pairs from `G$` and `E$`, nine at a time. - **Lines 700–890:** Quiz modes — German-to-English (700) and English-to-German (800), each running 10 random questions. - **Lines 900–1090:** Phrase quiz modes — English-to-German (900) and German-to-English (1000) using `R$` and `T$`. - **Lines 1100–1120:** Input display subroutine — prints the user’s answer `P$` neatly at a fixed screen position. - **Lines 2000–3070:** Title screen display and main menu with six numbered choices. - **Lines 4000–5100:** Score display, wrong-answer feedback, correct-answer celebration, and end-of-round handler. - **Lines 5200–5550:** Random question selection subroutines for phrase (`5200`) and word (`5400`) questions, with duplicate prevention. - **Lines 6000–6100:** “Press any key to continue” pause subroutine with a graphical border. - **Lines 7990–8050:** Phrase review mode — paginated display of phrase pairs, six at a time. - **Line 9000–9020:** Screen-clear subroutine using the machine code routine and `PRINT AT 0,0;`. ### Machine Code Routine Line 1 contains a `REM` statement whose body is a machine code routine loaded at address 16514 (the byte immediately following the REM token in memory). The hex bytes encode a Z80 routine: | Hex | Mnemonic | Purpose | | --- | --- | --- | | `16 17` | LD D,17h | Load D with 23 (number of rows) | | `2A 0C 40` | LD HL,(400Ch) | Load HL with display file address | | `3E 21` | LD A,21h | Load A with 33 (number of columns) | | `23` | INC HL | Advance pointer | | `36 00` | LD (HL),00 | Write space to screen | | `3D` | DEC A | Decrement column counter | | `FE 01` | CP 01h | Compare with 1 | | `20 F8` | JR NZ,-8 | Loop over columns | | `23` | INC HL | Skip to next row | | `15` | DEC D | Decrement row counter | | `5F` | LD E,A | Save A into E | | `7A` | LD A,D | Move row count to A | | `FE 01` | CP 01h | Compare with 1 | | `7B` | LD A,E | Restore A | | `20 ED` | JR NZ,-19 | Loop over rows | | `C9` | RET | Return to BASIC | This routine rapidly clears the display by writing zeros to the display file directly, bypassing the BASIC `CLS` command. It is called via `LET Z=USR 16514` at line 9000 each time a screen clear is needed. ### Random Question Selection and Duplicate Prevention Two subroutines handle random selection without repeats. The word quiz subroutine at line 5400 picks a random index `R` in the range 1–220 (implying the vocabulary array holds up to 220 entries), stores it in `U(L)`, then iterates through all previously used values in `U` to check for a collision, restarting if a duplicate is found. Similarly, the phrase subroutine at line 5200 selects from 1–50 using array `V`. This is a standard rejection-sampling deduplication approach in BASIC. ### Answer Matching with Trailing-Space Trimming Because the string arrays `G$`, `E$`, `R$`, and `T$` are fixed-width (padded with spaces), a substring comparison loop is used to find the effective length of each answer before comparing. For example, lines 735–750 scan `E$(R)` two characters at a time for a double space, then set `A` to the last non-space position. The comparison at line 760 is then `P$=E$(R,1 TO A)`, avoiding spurious mismatches due to trailing padding. ### Two-Attempt Quiz Logic Each question allows two attempts via an inner `FOR Q=1 TO 2` loop (e.g., lines 715–767). On the first wrong answer, the message “WRONG—TRY AGAIN” is printed; on the second failure (`IF Q>1`), the correct answer is revealed and the program moves on without awarding a point. This pattern is consistently applied across all four quiz modes. ### Score Tracking The variable `S` is initialized to 0 at line 2060 and incremented at line 5085 for each correct answer. At the end of a 10-question round (detected at line 5087 when `L=10`), the program jumps to line 4000, which displays the score in inverse video and returns to the menu. Score is not reset between rounds unless the user navigates back through the menu to line 2060. ### Display and Graphics Techniques The program makes extensive use of block graphics characters to draw decorative borders and dividers. The wrong-answer display at line 4500 uses `▄` characters for a top border and `▀` characters for a bottom border. The “press any key” pause subroutine at line 6000 constructs a three-line bordered box using `▌` and `▐` side characters. Menu separators use checkerboard-pattern graphics for visual flair. All `PRINT AT` statements are used carefully to write to specific screen coordinates without full redraws. ### Subroutine at Line 5000 (Missing) The correct-answer handler calls `GOSUB 5000` (lines 780, 880, 980, 1080), but the listing jumps from line 4500 directly to line 5010. Line 5000 is absent; BASIC will execute from line 5010 as the nearest following line, which is standard behavior — a `GOSUB` to a non-existent line number executes from the next line present. This is an intentional memory optimization, not an error. ### Vocabulary Data The program does not contain its vocabulary inline; the arrays `G$`, `E$`, `R$`, and `T$` are presumably populated by a `GOSUB 9000` call or loaded from the tape alongside this program. The absence of `DIM` or `DATA`/`READ` statements in the listing confirms the data is expected to reside elsewhere (likely a second program block or a separate loader). Line 1200 contains a `SAVE "GERMA%N"` command (the `%N` being an inverse N) used to save the program. ## Source Code ``` 1 REM 16172AC403E21233603DFE120F823155F7AFE17B20EDC9 50 GOSUB 9000 60 LET X=1 100 PRINT "GERMAN ENGLISH " 110 PRINT "====== ======= " 170 FOR X=X TO X+8 182 PRINT G$(X);TAB 15;E$(X) 183 PRINT 184 IF X=240 THEN GOTO 2056 185 NEXT X 189 PRINT "'''''''''''''''''''''''''''''''''''''''''''''''''''' PRESS C TO CONTINUE, S TO STOP." 192 IF INKEY$="S" THEN GOTO 2049 194 IF INKEY$="C" THEN GOTO 200 195 GOTO 192 200 GOSUB 9000 210 GOTO 170 700 FOR L=1 TO 10 710 GOSUB 5400 715 FOR Q=1 TO 2 718 PRINT AT 9,0;G$(R) 720 PRINT AT 10,0;"IS GERMAN FOR WHAT WORD?" 731 INPUT P$ 732 GOSUB 1100 735 FOR A=1 TO 16 737 IF E$(R,A TO A+1)=" " THEN GOTO 750 740 NEXT A 750 LET A=A-1 760 IF P$=E$(R,1 TO A) THEN GOTO 780 765 IF Q>1 THEN GOTO 768 766 PRINT AT 12,0;"WRONG---TRY AGAIN" 767 NEXT Q 768 GOSUB 4500 770 PRINT "THE WORD WAS : ";E$(R) 772 GOSUB 6000 773 GOSUB 5087 775 NEXT L 780 GOSUB 5000 790 NEXT L 800 FOR L=1 TO 10 810 GOSUB 5400 815 FOR Q=1 TO 2 820 PRINT AT 9,0;"WHAT IS THE GERMAN WORD FOR:" 825 PRINT AT 10,0;E$(R) 826 INPUT P$ 827 GOSUB 1100 828 FOR A=1 TO 16 829 IF G$(R,A TO A+1)=" " THEN GOTO 831 830 NEXT A 831 LET A=A-1 840 IF P$=G$(R,1 TO A) THEN GOTO 880 845 IF Q>1 THEN GOTO 860 850 PRINT AT 12,0;"WRONG---TRY AGAIN" 855 NEXT Q 860 GOSUB 4500 870 PRINT "THE WORD WAS : ";G$(R) 872 GOSUB 6000 873 GOSUB 5087 875 NEXT L 880 GOSUB 5000 890 NEXT L 900 FOR L=1 TO 10 910 GOSUB 5200 915 FOR Q=1 TO 2 920 PRINT AT 9,0;"WHAT IS THE GERMAN PHRASE FOR:" 925 PRINT AT 10,0;T$(R) 926 INPUT P$ 927 GOSUB 1100 928 FOR A=1 TO 32 929 IF R$(R,A TO A+1)=" " THEN GOTO 931 930 NEXT A 931 LET A=A-1 940 IF P$=R$(R,1 TO A) THEN GOTO 980 945 IF Q>1 THEN GOTO 960 950 PRINT AT 12,0;"WRONG---TRY AGAIN" 955 NEXT Q 960 GOSUB 4500 970 PRINT "THE PHRASE WAS : " 971 PRINT R$(R) 972 GOSUB 6000 973 GOSUB 5087 975 NEXT L 980 GOSUB 5000 990 NEXT L 1000 FOR L=1 TO 10 1010 GOSUB 5200 1015 FOR Q=1 TO 2 1020 PRINT AT 9,0;"WHAT IS THE ENGLISH PHRASE FOR:" 1025 PRINT AT 10,0;R$(R) 1026 INPUT P$ 1027 GOSUB 1100 1028 FOR A=1 TO 32 1029 IF T$(R,A TO A+1)=" " THEN GOTO 1031 1030 NEXT A 1031 LET A=A-1 1040 IF P$=T$(R,1 TO A) THEN GOTO 1080 1045 IF Q>1 THEN GOTO 1060 1050 PRINT AT 12,0;"WRONG---TRY AGAIN" 1055 NEXT Q 1060 GOSUB 4500 1070 PRINT "THE PHRASE WAS : " 1071 PRINT T$(R) 1072 GOSUB 6000 1073 GOSUB 5087 1075 NEXT L 1080 GOSUB 5000 1090 NEXT L 1100 PRINT AT 11,0;" ";AT 11,0;P$ 1110 PRINT AT 12,0;" " 1120 RETURN 1200 SAVE "GERMA%N" 2000 PRINT AT 8,0;A$ 2002 PRINT AT 2,0;I$;AT 18,0;I$ 2010 PRINT AT 16,4;"PRESS ANY KEY TO BEGIN" 2020 IF INKEY$="" THEN GOTO 2020 2049 GOSUB 9000 2050 PRINT 2055 PRINT 2056 PRINT "% ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;% " 2060 LET S=0 3000 PRINT "CHOOSE MODE:" 3010 PRINT " (1)ENGLISH TO GERMAN" 3020 PRINT " (2)GERMAN TO ENGLISH" 3040 PRINT " (3)ENGLISH TO GERMAN PHRASES" 3041 PRINT " (4)GERMAN TO ENGLISH PHRASES" 3042 PRINT " (5)REVIEW WORDS" 3043 PRINT " (6)REVIEW PHRASES" 3046 PRINT "% !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!% " 3050 LET M$=INKEY$ 3055 IF M$="1" THEN GOTO 800 3060 IF M$="2" THEN GOTO 700 3065 IF M$="5" THEN GOTO 50 3067 IF M$="3" THEN GOTO 900 3068 IF M$="4" THEN GOTO 1000 3069 IF M$="6" THEN GOTO 7990 3070 GOTO 3050 4000 GOSUB 9000 4001 PRINT " % %Y%O%U%R% %S%C%O%R%E% %I%S%:% ";S 4010 GOTO 2050 4500 PRINT ".................................................... ---WRONG--- '''''''''''''''''''''''''''''''''''''''''''''''''''' " 4510 RETURN 5010 PRINT AT 14,0;" % ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;% % % % % CORRECT % % % % % !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!% " 5080 FOR P=1 TO 15 5081 NEXT P 5085 LET S=S+1 5087 IF L=10 THEN GOTO 4000 5100 RETURN 5200 GOSUB 9000 5210 LET R=INT (50*RND)+1 5220 LET V(L)=R 5230 FOR P=1 TO L-1 5240 IF V(L)=V(P) THEN GOTO 5210 5245 NEXT P 5248 PRINT AT 4,6;"QUESTION NO. ";L 5250 RETURN 5400 GOSUB 9000 5405 LET R=INT (220*RND)+1 5500 LET U(L)=R 5510 FOR P=1 TO L-1 5520 IF U(L)=U(P) THEN GOTO 5405 5540 NEXT P 5545 PRINT AT 4,6;"QUESTION NO. ";L 5550 RETURN 6000 PRINT AT 19,0;"..,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,..";AT 21,0;"''~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~''";AT 20,0;": PRESS ANY KEY TO CONTINUE :" 6005 IF INKEY$="" THEN GOTO 6005 6100 RETURN 7990 GOSUB 9000 7995 PRINT " PHRASES =============" 8000 LET X=1 8001 FOR X=X TO X+5 8003 PRINT R$(X) 8004 PRINT T$(X) 8005 PRINT 8008 IF X=50 THEN GOTO 2050 8010 NEXT X 8015 PRINT "'''''''''''''''''''''''''''''''''''''''' PRESS C TO CONTINUE, S TO STOP." 8020 IF INKEY$="S" THEN GOTO 2049 8021 IF INKEY$="C" THEN GOTO 8040 8025 GOTO 8020 8040 GOSUB 9000 8050 GOTO 8001 9000 LET Z=USR 16514 9010 PRINT AT 0,0; 9020 RETURN ```