--- title: "QBert" id: 67619 type: "computer_media" slug: "qbert-2" url: "http://localhost/computer_media/qbert-2/" markdown_url: "http://localhost/computer_media/qbert-2.md" published_at: "2026-03-28T14:04:17+00:00" modified_at: "2026-03-30T21:44:51+00:00" author: "David Anderson" featured_image: url: "http://localhost/wp-content/uploads/2026/03/q-bert-homebrew-2.png" excerpt: "Guide your hero diagonally across a hazardous board, collecting eggs and dodging two enemies, in this faithful arcade conversion with joystick support and a high-score table." 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 2068" slug: "ts2068" taxonomy: "post_tag" url: "http://localhost/tag/ts2068/" model: - name: "Timex/Sinclair 2068" slug: "ts-2068" taxonomy: "model" url: "http://localhost/model/ts-2068/" indiv: - name: "Werner Kaelin" slug: "werner-kaelin" taxonomy: "indiv" url: "http://localhost/indiv/werner-kaelin/" genre: - name: "Arcade" slug: "arcade" taxonomy: "genre" url: "http://localhost/type/arcade/" - name: "Game" slug: "game" taxonomy: "genre" url: "http://localhost/type/game/" media_contents: - id: 51212 title: "CATS Library Tape 1" type: "computer_media" url: "http://localhost/computer_media/cats-library-tape-1/" media_type: "Cartridge" programmers: - name: "Werner Kaelin" slug: "werner-kaelin" taxonomy: "indiv" url: "http://localhost/indiv/werner-kaelin/" mediadate: "1984" images: - url: "http://localhost/wp-content/uploads/2026/03/q-bert-homebrew-2.png" - url: "http://localhost/wp-content/uploads/2026/03/q-bert-homebrew-1.png" related_products: - id: 35494 title: "Q*Bert" type: "product" url: "http://localhost/product/qbert/" media_type_tags: "Arcade, Game" --- # QBert This program is a BASIC implementation of the arcade game Q*bert, where the player navigates a character across a diamond-shaped board while avoiding enemies named Sammy and the Snake. Movement is controlled via Q/W/A/S keys or a joystick (read via the STICK function), with diagonal movement dispatched through a computed GOSUB using PEEK 23560. The program makes extensive use of machine code routines loaded at addresses 65200–65330 for animation and sound effects, called via USR. A ten-entry high-score table with name entry is maintained in a string array, and UDGs (user-defined graphics) are used for all character sprites. *** ## Program Analysis ### Program Structure The program is organized into several well-defined functional blocks: 1. **Lines 999, 5800–5840:** Entry point; sets up border/colors and displays a title/credits screen. 2. **Lines 6710–6890:** Initialization — plays intro music, dimensions the high-score array, defines sprite strings using UDG escape sequences, and falls through to the attract loop. 3. **Lines 5500–5790:** Attract/menu loop — cycles through character showcase, controls help, scoring info, and the leaderboard, returning to `1000` on keypress. 4. **Lines 1000–1100:** Main game loop — initializes variables, draws HUD, plays level start tune, then repeatedly reads input, dispatches movement, moves enemies, and redraws. 5. **Lines 1500–2099:** Movement subroutines for four diagonal directions (down-left, up-left, down-right, up-right), each separated by a dummy `RETURN` at the base of the group. 6. **Lines 2800–2980:** Enemy AI for Sammy (the bouncer) and the Snake, using random direction selection each turn. 7. **Lines 3000–3040:** Death sequence — plays sounds, animates, decrements lives. 8. **Lines 3500–3540:** Egg collection — increments score, checks for level completion. 9. **Lines 4000–4070:** Enemy-collision death sequence with explosion effect. 10. **Lines 5000–5240:** Game over and high-score entry. 11. **Lines 9900–9970:** Save/load block for the BASIC program and associated machine code. ### Input Dispatching via Computed GOSUB The key input mechanism is a notable idiom. Line 1075 reads the joystick state via `STICK (1,1)` and stores an ASCII key code into system variable address 23560: ``` POKE 23560, (113*(j=5) + 119*(j=9) + 97*(j=6) + 115*(j=10)) ``` The values 113, 119, 97, 115 correspond to the ASCII codes for Q, W, A, S respectively. Line 1050 then dispatches to a movement subroutine with: ``` GO SUB PEEK 23560 * 5 + 1500 ``` The mapping is: | Key | ASCII | PEEK*5+1500 | Target line | Direction | | --- | --- | --- | --- | --- | | Q | 113 | 2065 | 2065 | Up-left | | W | 119 | 2095 | 2095 | Up-right | | A | 97 | 1985 | 1985 | Down-left | | S | 115 | 2075 | 2075 | Down-right | | (none) | 0 | 1500 | 1500 | No-op RETURN | Dummy `RETURN` statements are placed at lines 1984, 2064, 2074, and 2094 to catch any off-by-one addresses that might land between valid entry points. Line 1500 itself is the no-input no-op. ### Machine Code Usage Several calls to `USR` at high memory addresses appear throughout the program. These invoke pre-loaded machine code routines saved separately as a CODE block (see line 9910: `SAVE "Q-BERT" CODE 58280,7225`). The routines and their apparent purposes are: | Address | Usage context | Apparent purpose | | --- | --- | --- | | 65200 | After movement delta applied | Delay / animation frame | | 65230 | Death/collision animation loop | Screen flash or shake effect | | 65250 | Death animation loop | Further animation frame | | 65275 | Death animation loop | Further animation frame | | 65312 | Level init and intro | Board drawing / initialization | | 65330 | On death/collision | Flash/explosion effect trigger | The return value of each `USR` call is assigned to the dummy variable `l` (e.g., `LET l=USR 65312`) purely to satisfy BASIC syntax, as the results are not used. ### Sprite Representation All character sprites are two rows of two UDG characters each, stored in short strings. The variables `a$` through `i$` are initialized at lines 6800–6820 using UDG escape sequences (e.g., `\a\b` for the first row of the hero). The hero uses UDGs \a–\d for display and erase (blank-tile) versions, enemies use \e–\l and \n–\q, and a single-character UDG \m is used for Sammy’s erase frame. The program draws and erases sprites by printing with `OVER 1`, which XORs pixels — printing the same image twice restores the background. ### Enemy AI Both enemies (Sammy at `bx,by` and the Snake at `sx,sy`) use the same movement strategy each game tick in subroutine 2800–2980. A random direction is chosen via `GO TO RND*4+2801` (or `2901`), selecting one of four diagonal moves. Boundary and screen-content checks prevent movement off the board. The Snake has an additional behavior (line 2970): with a probability that increases with round number (`.9-ro/200`), it drops an “o” marker on a vacated cell, deducting 50 from the field counter `fi` — effectively placing obstacles for the player. ### Collision Detection Collision detection is performed entirely via `SCREEN$` character reads rather than coordinate comparison. Movement routines check `SCREEN$ (qy+1, qx)=" "` to detect falling off the board (empty space below), and check adjacent cells for valid landing squares. Enemy-to-player collision is checked by coordinate equality (e.g., `bx=qx AND by=qy`) after each enemy move. ### High-Score Table The leaderboard uses `DIM w$(12,24)` — a 12-row by 24-character string array. Only 10 entries are displayed; the extra rows serve as overflow guards. Scores are left-padded to 6 digits with `"000000"(TO 6-LEN STR$ sc)+STR$ sc` for lexicographic comparison. The insertion sort at lines 5050–5070 walks down the table comparing string values to find the insertion point. ### HUD and Lives Display Lives remaining are displayed as pairs of UDG characters — `"\a\b\a\b\a\b"(TO li*2)` — which neatly scales the display to show exactly `li` sprite pairs by using a string slice. Score is right-justified by printing at column `7-LEN STR$ sc`. ### Level Progression The field counter `fi` tracks egg collection progress. Collecting an egg (an “o” character detected by `SCREEN$`) adds 50 to both `sc` and `fi`. When `fi` reaches 1350 (27 eggs × 50 points), the level-complete sequence fires at line 3510, awarding a 500-point bonus and incrementing the round counter `ro` (capped at 120), which influences enemy speed and Snake drop probability. ### Notable Anomalies - Line 5010 uses variable `a` in DATA statements (e.g., `a,0`, `a*2,7`). This is legal in Spectrum BASIC — `READ` evaluates expressions, so `a` is read as the current numeric variable. The value of `a` is set to `.135+q/500` at line 5100 before `RESTORE 5010` is called, making the tune tempo dependent on leaderboard rank. - The `GO TO RND*4+2801` idiom generates a non-integer target; BASIC truncates it, so valid targets are 2801–2804 and 2901–2904 — exactly the four direction sub-blocks. - Line 1037 uses `INPUT ""` as a one-frame pause to allow the display to refresh before the game loop starts, rather than for actual user input. ## Source Code ``` 999 GO TO 5800 1000 POKE 23658,0: LET ro=1: LET bon=0: LET sc=0: LET li=3 1010 CLS : LET l=USR 65312: LET fi=0: LET qx=16: LET qy=1: LET bx=4: LET by=19: LET sx=28: LET sy=19: LET qx1=qx: LET qy1=qy: LET bx1=bx: LET by1=by: LET sx1=sx: LET sy1=sy 1015 POKE 23560,0: PAPER 1: PRINT AT 1,7-LEN STR$ sc; INK 6;sc;AT 4,30-LEN STR$ ro; INK 6;ro;AT 1,32-li*2; INK 6;"\a\b\a\b\a\b"( TO li*2);AT 2,32-li*2; INK 6;"\c\d\c\d\c\d"( TO li*2): PAPER 0: IF bon THEN GO TO 1035 1020 RESTORE 1030: FOR q=1 TO 16: READ a: BEEP .095+li/100,a: NEXT q: LET bon=0 1030 DATA 20,16,12,10,20,16,12,10,20,16,19,23,19,16,12,10 1035 RANDOMIZE : PRINT OVER 1; INK 5;AT 18,4;e$;AT 19,4;f$; INK 6;AT 18,28;h$;AT 19,28;i$ 1037 INPUT "" 1040 PRINT OVER 1;AT qy-1,qx;a$;AT qy,qx;b$; INK 5;AT by-1,bx;e$;AT by,bx;f$; INK 6;AT sy-1,sx;h$;AT sy,sx;i$ 1050 GO SUB PEEK 23560*5+1500: POKE 23560,0 1060 PRINT OVER 1;AT qy-1,qx;c$;AT qy,qx;d$ 1070 PRINT OVER 1;AT qy-1,qx;a$;AT qy,qx;b$; INK 5;AT by-1,bx;e$;AT by,bx;f$; INK 6;AT sy-1,sx;h$;AT sy,sx;i$ 1075 LET j= STICK (1,1): POKE 23560,(113*(j=5)+119*(j=9)+97*(j=6)+115*(j=10)) 1080 GO SUB 2800 1090 PRINT OVER 1;AT qy-1,qx;c$;AT qy,qx;d$ 1100 GO TO 1040 1500 RETURN 1984 RETURN 1985 PRINT OVER 1;AT qy-1,qx;a$;AT qy,qx;b$: LET qx=qx-2: LET qy=qy+3: LET l=USR 65200: IF SCREEN$ (qy+1,qx)=" " OR qy>=21 THEN GO TO 3000 1986 IF SCREEN$ (qy-3,qx+2)="" THEN PRINT OVER 1;AT qy-4,qx+2;a$;AT qy-3,qx+2;b$: GO TO 1986 1987 IF qy=by AND qx=bx OR qy=sy AND qx=sx THEN LET qx1=qx: LET qy1=qy: LET qx=qx+2: LET qy=qy-3: GO TO 4000 1988 LET qx1=qx: LET qy1=qy: IF SCREEN$ (qy,qx)="o" THEN GO SUB 3500 1989 RETURN 2064 RETURN 2065 PRINT OVER 1;AT qy-1,qx;a$;AT qy,qx;b$: LET qx=qx-2: LET qy=qy-3: LET l=USR 65200: IF SCREEN$ (qy+1,qx)=" " OR qy<=0 THEN GO TO 3000 2066 IF SCREEN$ (qy+3,qx+2)="" THEN PRINT OVER 1;AT qy+2,qx+2;a$;AT qy+3,qx+2;b$: GO TO 2066 2067 IF qy=by AND qx=bx OR qy=sy AND qx=sx THEN LET qx1=qx: LET qy1=qy: LET qx=qx+2: LET qy=qy+3: GO TO 4000 2068 LET qx1=qx: LET qy1=qy: IF SCREEN$ (qy,qx)="o" THEN GO SUB 3500 2069 RETURN 2074 RETURN 2075 PRINT OVER 1;AT qy-1,qx;a$;AT qy,qx;b$: LET qx=qx+2: LET qy=qy+3: LET l=USR 65200: IF SCREEN$ (qy+1,qx)=" " OR qy>=21 THEN GO TO 3000 2076 IF SCREEN$ (qy-3,qx-2)="" THEN PRINT OVER 1;AT qy-4,qx-2;a$;AT qy-3,qx-2;b$: GO TO 2076 2077 IF qy=by AND qx=bx OR qy=sy AND qx=sx THEN LET qx1=qx: LET qy1=qy: LET qx=qx-2: LET qy=qy-3: GO TO 4000 2078 LET qx1=qx: LET qy1=qy: IF SCREEN$ (qy,qx)="o" THEN GO SUB 3500 2079 RETURN 2094 RETURN 2095 PRINT OVER 1;AT qy-1,qx;a$;AT qy,qx;b$: LET qx=qx+2: LET qy=qy-3: LET l=USR 65200: IF SCREEN$ (qy+1,qx)=" " OR qy<=0 THEN GO TO 3000 2096 IF SCREEN$ (qy+3,qx-2)="" THEN PRINT OVER 1;AT qy+2,qx-2;a$;AT qy+3,qx-2;b$: GO TO 2096 2097 IF qy=by AND qx=bx OR qy=sy AND qx=sx THEN LET qx1=qx: LET qy1=qy: LET qx=qx-2: LET qy=qy+3: GO TO 4000 2098 LET qx1=qx: LET qy1=qy: IF SCREEN$ (qy,qx)="o" THEN GO SUB 3500 2099 RETURN 2798 RETURN 2800 LET bx1=bx: LET by1=by: GO TO RND*4+2801 2801 LET bx=bx+2: LET by=by+3: GO TO 2810 2802 LET bx=bx+2: LET by=by-3: GO TO 2810 2803 LET bx=bx-2: LET by=by+3: GO TO 2810 2804 LET bx=bx-2: LET by=by-3 2810 IF by<0 OR by>21 THEN LET by=by1: LET bx=bx1: GO TO 2860 2820 IF SCREEN$ (by+1,bx)=" " THEN LET bx=bx1: LET by=by1: GO TO 2860 2830 IF bx=qx AND by=qy THEN PRINT OVER 1; INK 7;AT by1-1,bx1;e$;AT by1,bx1;f$; INK 5;AT by-1,bx;e$;AT by,bx;f$: GO TO 4000 2840 PRINT OVER 1; INK 7;AT by1-1,bx1;e$;AT by1,bx1;f$ 2850 PRINT OVER 1; INK 5;AT by-1,bx;e$;AT by,bx;f$ 2860 BEEP .01,-by: BEEP .01,-bx 2900 LET sx1=sx: LET sy1=sy: GO TO RND*4+2901 2901 LET sx=sx-2: LET sy=sy+3: GO TO 2910 2902 LET sx=sx+2: LET sy=sy-3: GO TO 2910 2903 LET sx=sx+2: LET sy=sy+3: GO TO 2910 2904 LET sx=sx-2: LET sy=sy-3 2910 IF sy<0 OR sy>21 THEN LET sy=sy1: LET sx=sx1: GO TO 2980 2920 IF SCREEN$ (sy+1,sx)=" " THEN LET sx=sx1: LET sy=sy1: GO TO 2980 2930 IF sx=qx AND sy=qy THEN PRINT OVER 1; INK 7;AT sy1-1,sx1;h$;AT sy1,sx1;i$; INK 6;AT sy-1,sx;h$;AT sy,sx;i$: GO TO 4000 2940 PRINT OVER 1; INK 7;AT sy1-1,sx1;h$;AT sy1,sx1;i$ 2950 PRINT OVER 1; INK 6;AT sy-1,sx;h$;AT sy,sx;i$ 2960 IF RND<.9-ro/200 THEN BEEP .01,-sy: BEEP .01,-sx: RETURN 2970 IF SCREEN$ (sy1,sx1)<>"o" AND sx1<>sx AND sy1<>sy AND sx1<>bx AND sy1<>by THEN PRINT AT sy1,sx1;"o": BEEP .01,0: BEEP .01,10: LET fi=fi-50 2980 BEEP .01,-sy: BEEP .01,-sx: RETURN 3000 LET l=USR 65330: BEEP .3,10: BEEP .3,0: BEEP .3,-10: FOR q=1 TO 8: LET l=USR 65230: NEXT q: FOR q=1 TO 5: LET l=USR 65250: LET l=USR 65275: NEXT q 3005 PRINT OVER 1; INK 6;AT 1,32-li*2;"\e\f\e\f\e\f"( TO li*2);AT 2,32-li*2;"\g\h\g\h\g\h"( TO li*2) 3010 PRINT OVER 1;AT qy1-1,qx1;a$;AT qy1,qx1;b$: IF SCREEN$ (qy1,qx1)="" THEN GO TO 3010 3020 FOR q=20 TO -20 STEP -1: BEEP .02,q: BEEP .01,q: NEXT q: FOR q=-20 TO 0: BEEP .01,q: NEXT q 3030 LET li=li-1: IF li<=0 THEN GO TO 5000 3040 LET bon=0: GO TO 1010 3500 LET sc=sc+50: BEEP .01,20: BEEP .01,10: PRINT AT qy,qx;" ": PRINT AT 1,7-LEN STR$ sc; PAPER 1; INK 6;sc: LET fi=fi+50: IF fi<1350 THEN RETURN 3510 PRINT OVER 1;AT qy1-1,qx1;a$;AT qy1,qx1;b$: IF SCREEN$ (qy1,qx1)="" THEN GO TO 3510 3515 PRINT OVER 1;AT qy-1,qx;a$;AT qy,qx;b$ 3520 FOR q=1 TO 500 STEP 10: LET sc=sc+10: BEEP .01,0: PRINT AT 1,7-LEN STR$ sc; PAPER 1; INK 6;sc: NEXT q 3530 FOR q=-20 TO 50 STEP 5: BEEP .1,q: NEXT q 3540 LET bon=1: LET ro=ro+(1 AND ro<120): GO TO 1010 4000 LET l=USR 65330: BEEP .3,10: BEEP .3,0: BEEP .3,-10 4005 PRINT OVER 1; INK 6;AT 1,32-li*2;"\e\f\e\f\e\f"( TO li*2);AT 2,32-li*2;"\g\h\g\h\g\h"( TO li*2) 4010 PRINT OVER 1;AT qy1-1,qx1;a$;AT qy1,qx1;b$ 4020 IF qx1<26 THEN PRINT AT qy1-1,qx1+2; FLASH 1; BRIGHT 1; PAPER RND*3; INK RND*4+4;"*%*''": GO TO 4040 4030 PRINT AT qy1-1,qx1+2; FLASH 1; BRIGHT 1; PAPER RND*3; INK RND*4+4;"*%";AT qy1,qx1+2;"!'" 4040 FOR q=1 TO 8: LET l=USR 65230: NEXT q: FOR q=1 TO 5: LET l=USR 65250: LET l=USR 65275: NEXT q 4050 FOR q=20 TO -20 STEP -1: BEEP .02,q: BEEP .01,q: NEXT q: FOR q=-20 TO 0: BEEP .01,q: NEXT q 4060 LET li=li-1: IF li<=0 THEN GO TO 5000 4070 LET bon=0: GO TO 1010 5000 LET x$="": PRINT AT 1,30; PAPER 1; INK 6;" ";AT 2,30;" " 5010 DATA a,0,a,2,a/2,3,a/2,2,a,0,a,0,a,2,a/2,3,a/2,2,a,0,a,3,a,5,a*2,7,a,3,a,5,a*2,7,.075,7,.025,8,a/2,7,a/2,5,a/2,3,a/2,2,a,0,.075,7,.025,8,a/2,7,a/2,5,a/2,3,a/2,2,a,0,a,0,a,-5,a*1.5,0,a,0,a,-5,a*1.5,0 5020 LET x$=x$+"000000"( TO 6-LEN STR$ sc)+STR$ sc: LET q=1 5050 IF q=11 OR sc=0 THEN GO TO 5240 5060 IF x$11 THEN LET w$(q,f-4)=" ": LET f=f-1: PRINT AT 14,f;" ";: IF INKEY$<>"" THEN GO TO 5220 5170 IF q$<" " OR q$>"z" THEN GO TO 5130 5180 PRINT AT 14,f;q$: LET w$(q,f-3)=q$: BEEP .01,20: LET f=f+1: IF f>=28 THEN LET f=11 5220 IF INKEY$<>"" THEN GO TO 5220 5230 GO TO 5130 5240 CLS : PRINT AT 11,9; FLASH 1; PAPER RND*3; INK RND*4+4;" GAME OVER ": BEEP 1,-25: BEEP 1,-30 5500 GO SUB 5780: PRINT AT 6,7; BRIGHT 1;" The persons: " 5510 PRINT AT 9,6;a$;AT 10,6;b$;"......the Hero" 5520 PRINT INK 5;AT 12,6;e$;AT 13,6;f$; INK 7;".........Sammy" 5530 PRINT INK 6;AT 15,6;h$;AT 16,6;i$; INK 7;".....the Snake" 5540 PAUSE 100: PRINT OVER 1;AT 9,6;c$;AT 10,6;d$;AT 12,6; INK 5;g$: GO SUB 5790: PAUSE 100 5545 IF INKEY$<>"" THEN GO TO 1000 5550 GO SUB 5780: PRINT BRIGHT 1;AT 7,7;" To move press: " 5560 PRINT AT 10,12;"Q W";AT 11,13;"\\ /";AT 12,14;"x";AT 13,13;"/ \\";AT 14,12;"A S" 5570 PRINT AT 17,6; BRIGHT 1;" Or use joysticks ": GO SUB 5790: PAUSE 200 5580 IF INKEY$<>"" THEN GO TO 1000 5620 GO SUB 5780: PRINT AT 7,7; BRIGHT 1;" Scoring: " 5630 PRINT AT 11,7; INVERSE 1;" 50"; INVERSE 0;" Points for each egg";AT 16,11;"for every new game";AT 14,7; INVERSE 1;"500"; INVERSE 0;" Points bonus": GO SUB 5790: PAUSE 200 5640 IF INKEY$<>"" THEN GO TO 1000 5660 CLS : PRINT TAB 3; BRIGHT 1; INK RND*4+4; PAPER RND*3;" The 10 leaders: ": PRINT 5680 FOR q=1 TO 10: PRINT 'TAB 3; INK 6-INT ((q-1)/2);w$(q, TO 6); INK 5;w$(q,7 TO ): NEXT q: GO SUB 5790: PAUSE 200 5720 IF INKEY$="" THEN GO TO 5500 5740 IF INKEY$<>"" THEN GO TO 1000 5750 GO TO 1000 5780 RANDOMIZE : CLS : PRINT AT 3,10; BRIGHT 1; INK RND*4+4; PAPER RND*3;" Q-BERT ": RETURN 5790 PRINT #1;" Press any key to start Q-BERT ": RETURN 5800 BORDER 0: PAPER 0: INK 7: CLS 5810 LET w$="Q-BERT" 5820 PRINT AT 3,8; FLASH 1; BRIGHT 1; PAPER RND*3; INK RND*4+4;" HOMECOMPUTER ";AT 5,10; PAPER RND*3; INK RND*4+4;" presents ";AT 18,3; INK 1; PAPER 6; FLASH 0;" adapted by Werner Kaelin " 5830 FOR q=1 TO 6: PRINT AT 8+q,11+q; FLASH 1; BRIGHT 1; INK RND*6+2;w$(q): NEXT q: POKE 23658,8 5840 GO SUB 5790: PAUSE 0 6710 LET l=USR 65312 6720 DATA 0,6,9,15,9,6,0 6730 FOR i=40 TO -20 STEP -3: RESTORE 6720: FOR q=1 TO 4: READ a: BEEP .04,a+i: NEXT q: NEXT i: BEEP 1,i+1: BEEP 1,i: BEEP 2,i+5 6750 DIM w$(12,24): FOR q=1 TO 12 STEP 3 6760 LET w$(q)="000000 Q-BERT___________" 6770 LET w$(q+1)="000000 SAMMY____________" 6780 LET w$(q+2)="000000 THE SNAKE________" 6790 NEXT q 6800 LET a$="\a\b": LET b$="\c\d": LET c$="\e\f": LET d$="\g\h" 6810 LET e$="\i\j": LET f$="\k\l": LET g$="\m" 6820 LET h$="\n\o": LET i$="\p\q" 6890 GO TO 5500 9000 STOP 9900 CLEAR : SAVE "Q-BERT" LINE 9940 9910 SAVE "Q-BERT"CODE 58280,7225 9930 STOP 9940 CLEAR 58200: LOAD "Q-BERT"CODE 9970 GO TO 5800 ```