Retrochallenge 2016/01:
Maze War for Olivetti M10 and NEC PC-8201A

Addendum: A Final Fix

It's true, our previous episode was the last one, but there's a little bug to be fixed. — A qestion of honour.

RC2016/01:Viewport into the maze, final version

There's a tiny little bug (here fixed) hiding behind one of the corners …

Tiny Little Walls

There aren't just tiny little passages in our maze, also, from time to time, we'll hit a wall in front of us. And here it is, where our little application doesn't do exactly what we expected it to do. And we won't leave this project as-is with this little bug, just because Retrochallenge 2016/01 is over.

So, what's it all about? Most dungeon crawlers are drawing walls simply as unit segments, each one separated from the next one by an edge. Not so Maze War: Here, adjacent wall segements are mended into a single, continuous wall. This works fine in our little game, but there's an edge case regarding a junction right where we hit a wall in front of us. It's here, where our program became a little confused about when to draw and when not to draw an edge.

This is what we have to deal with and how we want it to be drawn onto the screen:

RC2016/01:Viewport and frontal walls

Frontal walls and adjacent edges in the viewport.

At closer inspection, there are just 3 types of how a frontal wall may connect at either side to the rest of the scene as rendered in the viewport. We introduced code 4 for the edge case concerning a junction to the side and ahead, and get the following codes for this (code 1 represents a passage, a 2 OR-ed represents a corner, 4 is a junction):

RC2016/01:Types of frontal walls in the viewport

Encodings for the sides to be drawn adjacently to a frontal wall:
bit 0 (dec. 1): passage, bit 1 (dec. 2): edge/corner, bit 2 (dec. 4): special case.

So, there are two possible parts of our program that may cause the trouble: Either, we get the encoding wrong where we collect the view-path info, or we get it wrong when we render a frontal wall and its adjacent sides.

Let's check the encoding first. We'll insert a line printing a debug message below the maze map, just at the end of the code for collecting the view-path information:

1645 IF W0>CM THEN PRINT CHR$(ES);"Y";CHR$(EB+C7);CHR$(EB+22);VL(W0);VR(W0);
     ELSE PRINT CHR$(ES);"Y";CHR$(EB+C7);CHR$(EB+22);"      ";

Turns out, the encoding is correct. Thus, we may conclude, the bug is somewhere in the rendering routine. It concerns the right side only (so no debugging with Virtual T, since there is no support for display offset decrements, as required for writing from right to left; that's also, why we didn't manage to catch this bug in the first place) — and it concerns only codes 1 and 2:

RC2016/01:Rendering errors

Upper row: expected results, below: what we actually get.

So this must be the culprit:

122 REM handle right side
124 IF VR(W0)=C4 THEN 136
126 VM=VR(W0) AND C1:VE=VL(W0) AND C2
128 FOR VS=C2 TO C3:OUT PA,PV(VS)
130 FOR K=VI(VS,W0,VM,C0) TO VI(VS,W0,VM,C1) STEP C3
132 ON VK(K) GOSUB 31,32,33,34
134 NEXT:NEXT:GOTO 148
136 VE=C1:REM passage to the right and ahead
138 FOR VS=C2 TO C3:OUT PA,PV(VS)
140 FOR K=VI(VS,W0,C1,C0) TO VI(VS,W0,C1,C1) STEP C3
142 ON VK(K) GOSUB 31,36,37,34
144 NEXT:NEXT
146 REM finally draw the wall
148 (...)

After staring at the code for a while (no, there isn't a magical red mark-up in the original), we detect a stupid copy'n'paste error in line 126, where we refer to the left side, as in "VL", instead of the right one, "VR". — Fixed easily, phew!

126 VM=VR(W0) AND C1:VE=VR(W0) AND C2

And this is what we get (no erroneous edge drawn anymore on the wall leading to the passage at the far right):

RC2016/01:Viewport into the maze, fixed

NEC PC-8201A — The same scene as last episode, now fixed.

— As it turns out, this entire post is about a single letter ("R" as in "VR").   :-)

Here is our final program, legible version including spaces (slow, for a suitable runtime version see the listing below):

10 REM Maze War Dungeon Roamer (final), N.Landsteiner 01/2016
20 DEFSNG A:DEFINT B-Z:SCREEN 0,0:CLS:PRINT"Setting up...":GOTO 200
35 REM == time critical subroutines ==
30 REM viewport draw commands
31 OUT PC,VK(K+C1):RETURN
32 B=VK(K+C2):FOR J=C0 TO VK(K+C1):OUT PD,B:NEXT:RETURN
33 FOR J=VK(K+C1) TO VK(K+C2):OUT PD,BL(J):NEXT:RETURN
34 IF VE THEN OUT PD,VK(K+C1) ELSE OUT PD,VK(K+C2)
35 RETURN
36 FOR J=C0 TO VK(K+C1):OUT PD,C0:NEXT:RETURN
37 FOR J=VK(K+C1) TO VK(K+C2):OUT PD,C0:NEXT:RETURN
39 REM subroutine: render-viewport
40 ON G GOSUB 910,920,930,930,940
42 OUT PB,C0
44 OUT PA,PL:OUT PC,PU:OUT PA,PR:OUT PC,PQ
46 FOR I=C0 TO C7
48 IF W0=I THEN GOSUB 100:I=C7:GOTO 76
50 IF W1=I THEN GOSUB 90
52 IF VL(I)=HL(I) THEN 64
54 VM=VL(I) AND C1:VE=VL(I) AND C2
56 FOR VS=C0 TO C1:OUT PA,PV(VS)
58 FOR K=VI(VS,I,VM,C0) TO VI(VS,I,VM,C1) STEP C3
60 ON VK(K) GOSUB 31,32,33,34
62 NEXT:NEXT
64 IF VR(I)=HR(I) THEN 76
66 VM=VR(I) AND C1:VE=VR(I) AND C2
68 FOR VS=C2 TO C3:OUT PA,PV(VS)
70 FOR K=VI(VS,I,VM,C0) TO VI(VS,I,VM,C1) STEP C3
72 ON VK(K) GOSUB 31,32,33,34
74 NEXT:NEXT
76 NEXT
78 FOR I=C0 TO C7:HL(I)=VL(I):HR(I)=VR(I):NEXT:W1=W0
80 OUT PA,PR:OUT PC,PU
82 ON G GOSUB 960,970,980,980,990
84 RETURN
89 REM erase a wall 
90 IF W1=C7 THEN RETURN
92 FOR VS=C0 TO C3:OUT PA,PV(VS):K=VI(VS,W1,C2,C0):OUT PC,VK(K+C1)
94 FOR J=C0 TO VK(K+C4):OUT PD,C0:NEXT
96 NEXT:RETURN
98 REM draw blocking wall; handle left side
100 IF VL(W0)=C4 THEN 112
102 VM=VL(W0) AND C1:VE=VL(W0) AND C2
104 FOR VS=C0 TO C1:OUT PA,PV(VS)
106 FOR K=VI(VS,W0,VM,C0) TO VI(VS,W0,VM,C1) STEP C3
108 ON VK(K) GOSUB 31,32,33,34
110 NEXT:NEXT:GOTO 124
112 VE=C1:REM passage to the left and ahead
114 FOR VS=C0 TO C1:OUT PA,PV(VS)
116 FOR K=VI(VS,W0,C1,C0) TO VI(VS,W0,C1,C1) STEP C3
118 ON VK(K) GOSUB 31,36,37,34
120 NEXT:NEXT
122 REM handle right side
124 IF VR(W0)=C4 THEN 136
126 VM=VR(W0) AND C1:VE=VL(W0) AND C2
128 FOR VS=C2 TO C3:OUT PA,PV(VS)
130 FOR K=VI(VS,W0,VM,C0) TO VI(VS,W0,VM,C1) STEP C3
132 ON VK(K) GOSUB 31,32,33,34
134 NEXT:NEXT:GOTO 148
136 VE=C1:REM passage to the right and ahead
138 FOR VS=C2 TO C3:OUT PA,PV(VS)
140 FOR K=VI(VS,W0,C1,C0) TO VI(VS,W0,C1,C1) STEP C3
142 ON VK(K) GOSUB 31,36,37,34
144 NEXT:NEXT
146 REM finally draw the wall
148 IF W0=C7 THEN RETURN
150 FOR VS=C0 TO C3:OUT PA,PV(VS)
152 FOR K=VI(VS,W0,C2,C0) TO VI(VS,W0,C2,C1) STEP C3
154 ON VK(K) GOSUB 31,32,33,34
156 NEXT:NEXT
158 RETURN
160 REM == setup, execution starts here ==
195 REM G: 1=PC-8201A, 2=M10 (w/o modem), 3=Model 100, 4=Model 102, 5=KC85
200 B=PEEK(1):G= -(B=148) -(B=35)*2 -(B=51)*3 -(B=167)*4 -(B=225)*5
205 IF G=0 THEN SCREEN 0,1:PRINT "Sorry, model not supported. Gestalt:";B:END
210 IF G=1 THEN AK=65128! ELSE IF G=2 THEN AK=65389! ELSE IF G=5 THEN AK=65387! ELSE AK=65450!
215 C0=0:C1=1:C2=2:C3=3:C4=4:C5=5:C6=6:C7=7:C8=8:C9=9
220 CA=10:CC=12:CE=14:CN=49:CL=50:CP=64:CM=-1
225 UC=223:LC=97:CK=27:ES=27:EB=32:E8=17
230 PA=185:PB=186:PC=254:PD=255:DIM SA(9),SB(9):SG=-1:SH=0
235 FOR I=C0 TO C9:READ B1,B2:SA(I)=B1:SB(I)=B2:NEXT
240 DX=0:DY=0:DIM DX(3),DY(3):FOR I=C0 TO C3:READ B1,B2:DX(I)=B1:DY(I)=B2:NEXT
245 DL=0:DR=0:DIM DL(3),DR(3)
250 FOR I=C0 TO C3:READ B:DL(I)=B:NEXT
255 FOR I=C0 TO C3:READ B:DR(I)=B:NEXT
260 DIM DD(3):FOR I=C0 TO C3:READ B:DD(I)=B:NEXT
269 REM setup the maze
270 DIM SM(3,3,2):FOR I=C0 TO C3:FOR Y=C0 TO C3:READ B1,B2:SM(I,Y,C1)=B1:SM(I,Y,C0)=B2:NEXT:NEXT
275 DIM ST(3,1,1):FOR I=C0 TO C3:FOR Y=C0 TO C1:READ B1,B2:ST(I,Y,C1)=B1:ST(I,Y,C0)=B2:NEXT:NEXT
280 MW=31:MH=15:ML=132:MT=5:DIM M(MH,MW),BM(C9)
285 FOR Y=C0 TO C9:READ B:BM(Y)=B:NEXT
290 FOR Y=C0 TO MH:FOR X=C0 TO MW:READ B:M(Y,X)=B:NEXT:NEXT
295 GOSUB 1010:GOSUB 1110:REM setup viewport
299 REM == main  ==
300 CLS:GOSUB 700:MX=11:MY=7:MD=0:DX=DX(MD):DY=DY(MD):DL=DL(MD):DR=DR(MD)
310 PRINT CHR$(ES);"Y";CHR$(EB+C7);CHR$(EB+22);"Crsr,IJKL,Q:quit";
315 GOSUB 460:GOSUB 1770:GOSUB 1510:GOSUB 40
319 REM main loop
320 B=PEEK(AK):IF B=C0 THEN 320
330 K=PEEK(AK+B):POKE AK,C0:IF K>CK THEN ON K-CK GOTO 500,520,540,560
340 IF K>=LC THEN K=K AND UC
350 ON INSTR("JLKI Q",CHR$(K)) GOTO 520,500,560,540,580,590
360 GOTO 320
398 REM == subroutines ==
399 REM segement/pos select
400 SH=SG:SG=SX\CL:IF SY>C3 THEN SG=SG+C5
410 IF (SG<>SH) THEN OUT PA,SA(SG):OUT PB,SB(SG)
420 OUT PC,(SY MOD C4)*CP OR SX MOD CL:RETURN
449 REM clear/draw marker
450 X=ML+MX*C3:Y=MT+MY*C3:FOR I=C0 TO C3:PRESET(X+SM(MD,I,C0),Y+SM(MD,I,C1)):NEXT:RETURN
460 X=ML+MX*C3:Y=MT+MY*C3:FOR I=C0 TO C3:PSET(X+SM(MD,I,C0),Y+SM(MD,I,C1)):NEXT:RETURN
470 X=ML+MX*C3:Y=MT+MY*C3:PRESET(X+ST(MD,T0,C0),Y+ST(MD,T0,C1)):PSET(X+ST(MD,T1,C0),Y+ST(MD,T1,C1)):RETURN
499 REM key handling (right, left, bkwd, fwd, fire, quit)
500 T0=C1:T1=C0:GOSUB 470:MD=DR:DX=DX(MD):DY=DY(MD):DL=DL(MD):DR=DR(MD):GOTO 610
520 MD=DL:T0=C0:T1=C1:GOSUB 470:DX=DX(MD):DY=DY(MD):DL=DL(MD):DR=DR(MD):GOTO 610
540 GOSUB 450:MX=MX+DX:MY=MY+DY:IF M(MY,MX)=C0 THEN MX=MX-DX:MY=MY-DY:GOSUB 460:GOTO 320
550 GOSUB 460:GOTO 610
560 GOSUB 450:MX=MX-DX:MY=MY-DY:IF M(MY,MX)=C0 THEN MX=MX+DX:MY=MY+DY:GOSUB 460:GOTO 320
570 GOSUB 460:GOTO 610
580 GOTO 320:REM shoot
590 SCREEN 0,1:CLS:PRINT"- Bye -":END
600 REM view port: get path and display it
610 GOSUB 1510:GOSUB 40:GOTO 320
699 REM maze display
700 SY=MT\C8:Y0=0:D=MT MOD C8+C2:ON G GOSUB 910,920,930,930,940
710 Y1=Y0+C1:Y2=Y0+C2:Y3=Y0+C3:B0=BM(D)
720 IF (Y1<=MH) AND (D<C7) THEN B1=BM(D+C3) ELSE B1=C0
730 IF (Y2<=MH) AND (D<C4) THEN B2=BM(D+C6) ELSE B2=C0
740 IF (Y3<=MH) AND (D=C0) THEN B3=BM(D+C9) ELSE B3=C0
750 SX=ML:GOSUB 400
760 FOR MX=C0 TO MW:IF M(Y0,MX)=C0 THEN B=B0 ELSE B=C0
770 IF B1 THEN IF M(Y1,MX)=C0 THEN B=B OR B1
780 IF B2 THEN IF M(Y2,MX)=C0 THEN B=B OR B2
790 IF B3 THEN IF M(Y3,MX)=C0 THEN B=B OR B3
800 FOR I=C0 TO C2:IF SX MOD CL=C0 THEN GOSUB 400
810 OUT PD,B:SX=SX+C1:NEXT:NEXT
820 Y0=Y0+(CA-D)\C3:IF Y0>MH THEN 840
830 D=(D+C1)MOD C3:SY=SY+C1:GOTO 710
840 ON G GOSUB 960,970,980,980,990:RETURN
900 REM disable interrupts
910 EXEC 30437:RETURN
920 CALL 29558:RETURN
930 CALL 30300:RETURN
940 CALL 29450:RETURN
950 REM enable interrupts
960 EXEC 29888:RETURN
970 CALL 28998:RETURN
980 CALL 29756:RETURN
990 CALL 28906:RETURN
1000 REM setup viewport
1010 PL=33:PR=66:REM LCD blocks 0+5, 1+6
1020 PU=59:PQ=58:REM LCD counter setting increment/decrement
1030 DIM PV(3):FOR I=0 TO 3:READ B:PV(I)=B:NEXT
1040 DIM BL(29):FOR I=0 TO 29:READ B:BL(I)=B:NEXT
1050 DIM BP(33):FOR I=0 TO 33:READ B:BP(I)=B:NEXT
1060 DIM VL(7),VR(7),HL(7),HR(7)
1070 DIM VI(3,7,2,1):REM segment,level,mode,idx-from/idx-to
1080 DIM VK(1392)
1090 RETURN
1100 REM compile-viewport-instr
1110 I4=C0
1120 READ B:IF B<C0 THEN RETURN:REM level
1130 FOR J=C0 TO C2:READ B0:REM mode, get length
1140 JL=B0*C3:I0=I4:I1=I0+JL:I2=I1+JL:I3=I2+JL:I4=I3+JL
1150 VI(C0,B,J,C0)=I0:VI(C0,B,J,C1)=I1-C3
1160 VI(C1,B,J,C0)=I1:VI(C1,B,J,C1)=I2-C3
1170 VI(C2,B,J,C0)=I2:VI(C2,B,J,C1)=I3-C3
1180 VI(C3,B,J,C0)=I3:VI(C3,B,J,C1)=I4-C3
1190 FOR K=C1 TO B0
1193 READ B1,B2,B3:VK(I0)=B1:VK(I1)=B1:VK(I2)=B1:VK(I3)=B1
1196 ON B1 GOTO 1200,1260,1320,1380
1200 VK(I0+C1)=(B2*CP) OR B3
1210 VK(I1+C1)=((C3-B2)*CP) OR B3
1220 VK(I2+C1)=((C3-B2)*CP) OR (CN-B3)
1230 VK(I3+C1)=(B2*CP) OR (CN-B3)
1240 P=B3
1250 GOTO 1430
1260 L=B2-P:P=B2+C1
1270 VK(I0+C1)=L:VK(I0+C2)=BP(B3)
1280 VK(I1+C1)=L:VK(I1+C2)=BP(B3+E8)
1290 VK(I2+C1)=L:VK(I2+C2)=BP(B3+E8)
1300 VK(I3+C1)=L:VK(I3+C2)=BP(B3)
1310 GOTO 1430
1320 L=B2-P+B3:P=B2+C1
1330 VK(I0+C1)=B3:VK(I0+C2)=L
1340 VK(I1+C1)=B3+CE:VK(I1+C2)=L+CE
1350 VK(I2+C1)=B3+CE:VK(I2+C2)=L+CE
1360 VK(I3+C1)=B3:VK(I3+C2)=L
1370 GOTO 1430
1380 VK(I0+C1)=BP(B2):VK(I0+C2)=BP(B3)
1390 VK(I1+C1)=BP(B2+E8):VK(I1+C2)=BP(B3+E8)
1400 VK(I2+C1)=BP(B2+E8):VK(I2+C2)=BP(B3+E8)
1410 VK(I3+C1)=BP(B2):VK(I3+C2)=BP(B3)
1420 P=P+C1
1430 I0=I0+C3:I1=I1+C3:I2=I2+C3:I3=I3+C3
1440 NEXT:NEXT:GOTO 1120
1500 REM assemble view path data
1510 Y=MY:X=MX:VL=DD(DL):VR=DD(DR):VF=DD(MD):W0=CM:FW=C0
1520 FOR I=C0 TO C7:B=M(Y,X)
1523 IF B AND VL THEN VL(I)=C1 ELSE VL(I)=C0
1526 IF B AND VR THEN VR(I)=C1 ELSE VR(I)=C0
1530 IF I=C0 THEN 1570
1540 IF VL(I)<>VL(I-C1) THEN VL(I-C1)=VL(I-C1) OR C2
1560 IF VR(I)<>VR(I-C1) THEN VR(I-C1)=VR(I-C1) OR C2
1570 IF B AND VF THEN 1610
1580 IF VL(I)=C0 THEN VL(I)=C2 ELSE IF M(Y+DY(DL),X+DX(DL)) AND VF THEN VL(I)=C4 ELSE VL(I)=C1
1590 IF VR(I)=C0 THEN VR(I)=C2 ELSE IF M(Y+DY(DR),X+DX(DR)) AND VF THEN VR(I)=C4 ELSE VR(I)=C1
1600 W0=I:FW=I+C1:I=C7:GOTO 1620
1610 X=X+DX:Y=Y+DY
1620 NEXT
1630 IF W0=W1 THEN W1=CM
1640 IF (FW) AND (FW<C8) THEN FOR I=FW TO C7:VL(I)=CM:VR(I)=CM:NEXT
1650 RETURN
1700 REM clear/init viewport
1710 ON G GOSUB 910,920,930,930,940
1720 OUT PA,PL OR PR:OUT PB,C0:REM enable blocks 0,1,5,6 at once
1730 FOR Y=C0 TO C3:OUT PC,Y*CP
1740 FOR X=C0 TO CN:OUT PD,C0:NEXT
1750 NEXT
1760 ON G GOSUB 960,970,980,980,990
1770 FOR I=0 TO 7:HL(I)=CM:HR(I)=CM:NEXT:W0=CM:W1=CM
1780 RETURN
2000 REM port patterns for segments (0..9: PA,PB)
2001 DATA 1,0,2,0,4,0,8,0,16,0,32,0,64,0,128,0,0,1,0,2
2002 REM directions (0..3:dx,dy)
2003 DATA 0,-1,-1,0,0,1,1,0
2004 REM turns (L: 0..3, R: 0..3)
2005 DATA 1,2,3,0, 3,0,1,2
2006 REM directional codes (2^0..3)
2007 DATA 1,2,4,8
2008 REM maze maker defs (0..3:Y,X)
2009 DATA 0,1,1,0,1,1,1,2, 0,1,1,0,1,1,2,1, 1,0,1,1,1,2,2,1, 0,1,1,1,1,2,2,1
2010 REM maze marker turn pixel mods (Y,X)
2011 DATA 2,1,1,0, 1,2,2,1, 0,1,1,2, 1,0,0,1
2012 REM maze bit patterns
2013 DATA 1,3,7,14,28,56,112,224,192,128
2019 REM maze data
2020 DATA 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0
2021 DATA 0,12,10,14,10,14,10,10,10,14,10,10,14,2,0,8,14,10,10,10,10,14,10,10,10,14,10,10,10,10,6,0
2022 DATA 0,1,0,5,0,5,0,0,0,5,0,0,5,0,0,0,5,0,0,0,0,5,0,0,0,5,0,0,0,0,5,0
2023 DATA 0,0,0,5,0,9,14,10,10,3,0,12,11,14,10,10,11,14,10,6,0,5,0,12,10,11,6,0,12,10,3,0
2024 DATA 0,4,0,5,0,0,5,0,0,0,0,5,0,1,0,0,0,5,0,5,0,5,0,5,0,0,9,10,7,0,0,0
2025 DATA 0,13,10,15,10,10,11,10,10,10,10,7,0,0,0,4,0,5,0,9,10,11,10,11,6,0,0,0,9,6,0,0
2026 DATA 0,5,0,5,0,0,0,0,0,0,0,5,0,12,10,11,10,7,0,0,0,0,0,0,13,10,10,6,0,9,2,0
2027 DATA 0,5,0,9,10,14,10,10,10,6,0,5,0,5,0,0,0,9,10,10,10,6,0,0,5,0,0,13,2,0,0,0
2028 DATA 0,5,0,0,0,5,0,0,0,13,10,7,0,13,10,6,0,0,0,0,0,5,0,12,11,6,0,5,0,0,4,0
2029 DATA 0,9,10,6,0,13,10,6,0,5,0,5,0,5,0,5,0,12,10,6,0,5,0,5,0,5,0,9,14,10,7,0
2030 DATA 0,0,0,5,0,5,0,1,0,5,0,13,10,7,0,5,0,5,0,5,0,5,0,5,0,5,0,0,5,0,5,0
2031 DATA 0,4,0,5,0,5,0,0,0,5,0,5,0,5,0,5,0,5,0,5,0,5,0,5,0,9,14,10,7,0,5,0
2032 DATA 0,5,0,5,0,9,10,10,10,3,0,5,0,1,0,9,10,11,14,11,10,3,0,9,6,0,5,0,1,0,5,0
2033 DATA 0,5,0,5,0,0,0,0,0,0,0,5,0,0,0,0,0,0,5,0,0,0,0,0,5,0,5,0,0,0,5,0
2034 DATA 0,9,10,11,10,10,10,10,10,10,10,11,10,10,10,10,10,10,11,10,10,10,10,10,11,10,11,10,10,10,3,0
2035 DATA 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0
3000 REM segment addresses (port A)
3001 DATA 1,32,64,2
3005 REM line pixels
3006 DATA  1,   1,   2,   2,   4,   4,   8,   8,  16,  16
3007 DATA 32,  32,  64,  64, 128, 128,  64,  64,  32,  32
3008 DATA 16,  16,   8,   8,   4,   4,   2,   2,   1,   1
3010 REM pixels for repeats
3011 DATA 0,1,2,4,8,16,32,64,128
3012 DATA 255,254,252,248,240,224,192,128
3013 REM inverse direction (bottom up)
3014 DATA 0,128,64,32,16,8,4,2,1
3015 DATA 255,127,63,31,15,7,3,1
3020 REM viewport commands struct, 1st quadrant, per level and mode
3021 DATA 0:REM level 0
3022 DATA 10
3023 DATA 1,0,0, 3,5,10
3024 DATA 1,1,0, 2,5,0, 2,6,1, 4,9,1
3025 DATA 1,2,7, 4,9,0
3026 DATA 1,3,7, 4,9,0
3027 DATA 9
3028 DATA 1,0,0, 2,5,0
3029 DATA 1,1,0, 2,6,1, 4,9,1
3030 DATA 1,2,7, 4,9,0
3031 DATA 1,3,7, 4,9,0
3032 DATA 6
3033 DATA 1,1,8, 2,49,1
3034 DATA 1,2,8, 2,49,0
3035 DATA 1,3,8, 2,49,0
3036 DATA 1:REM level 1
3037 DATA 7
3038 DATA 1,1,8,  3,15,2, 4,14,6
3039 DATA 1,2,16, 4,9,0
3040 DATA 1,3,16, 4,9,0
3041 DATA 7
3042 DATA 1,1,8,  2,15,6, 4,14,6
3043 DATA 1,2,16, 4,9,0
3044 DATA 1,3,16, 4,9,0
3045 DATA 6
3046 DATA 1,1,17, 2,49,6
3047 DATA 1,2,17, 2,49,0
3048 DATA 1,3,17, 2,49,0
3049 DATA 2:REM level 2
3050 DATA 8
3051 DATA 1,1,17, 3,21,11
3052 DATA 1,2,17, 2,21,0, 3,23,0, 4,10,2
3053 DATA 1,3,24, 4,9,0
3054 DATA 7
3055 DATA 1,1,17, 2,21,0
3056 DATA 1,2,17, 2,23,2, 4,10,2
3057 DATA 1,3,24, 4,9,0
3058 DATA 4
3059 DATA 1,2,25, 2,49,2
3060 DATA 1,3,25, 2,49,0
3061 DATA 3:REM level 3
3062 DATA 5
3063 DATA 1,2,25, 3,30,3, 4,13,5
3064 DATA 1,3,31, 4,9,0
3065 DATA 5
3066 DATA 1,2,25, 2,30,5, 4,13,5
3067 DATA 1,3,31, 4,9,0
3068 DATA 4
3069 DATA 1,2,32, 2,49,5
3070 DATA 1,3,32, 2,49,0
3071 DATA 4:REM level 4
3072 DATA 5
3073 DATA 1,2,32, 3,36,10, 4,8,8
3074 DATA 1,3,37, 4,9,0
3075 DATA 5
3076 DATA 1,2,32, 2,36,8,  4,8,8
3077 DATA 1,3,37, 4,9,0
3078 DATA 4
3079 DATA 1,2,38, 2,49,8
3080 DATA 1,3,38, 2,49,0
3081 DATA 5:REM level 5
3082 DATA 3
3083 DATA 1,3,38, 3,41,0, 4,11,3
3084 DATA 3
3085 DATA 1,3,38, 2,41,3, 4,11,3
3086 DATA 2
3087 DATA 1,3,43, 2,49,3
3089 DATA 6:REM level 6
3090 DATA 3
3091 DATA 1,3,43, 3,45,5, 4,13,5
3092 DATA 3
3093 DATA 1,3,43, 2,45,5, 4,13,5
3094 DATA 2
3095 DATA 1,3,47, 2,49,5
3096 DATA 7:REM level 7
3097 DATA 3
3098 DATA 1,3,47, 3,48,9, 4,14,14
3099 DATA 3
3100 DATA 1,3,47, 2,48,6, 4,14,14
3101 DATA 2
3102 DATA 1,3,49, 2,49,14
3103 DATA -1

And here it is compressed, without spaces — amazingly faster:

10'Maze War Dungeon Roamer (final, compressed), N.Landsteiner 01/2016
20DEFSNGA:DEFINTB-Z:SCREEN0,0:CLS:?"Setting up...":GOTO200
35'== time critical subroutines ==
30'viewport draw commands
31OUTPC,VK(K+C1):RETURN
32B=VK(K+C2):FORJ=C0TOVK(K+C1):OUTPD,B:NEXT:RETURN
33FORJ=VK(K+C1)TOVK(K+C2):OUTPD,BL(J):NEXT:RETURN
34IFVETHENOUTPD,VK(K+C1)ELSEOUTPD,VK(K+C2)
35RETURN
36FORJ=C0TOVK(K+C1):OUTPD,C0:NEXT:RETURN
37FORJ=VK(K+C1)TOVK(K+C2):OUTPD,C0:NEXT:RETURN
39'subroutine: render-viewport
40ONGGOSUB910,920,930,930,940
42OUTPB,C0
44OUTPA,PL:OUTPC,PU:OUTPA,PR:OUTPC,PQ
46FORI=C0TOC7
48IFW0=ITHENGOSUB100:I=C7:GOTO76
50IFW1=ITHENGOSUB90
52IFVL(I)=HL(I)THEN64
54VM=VL(I)ANDC1:VE=VL(I)ANDC2
56FORVS=C0TOC1:OUTPA,PV(VS)
58FORK=VI(VS,I,VM,C0)TOVI(VS,I,VM,C1)STEPC3
60ONVK(K)GOSUB31,32,33,34
62NEXT:NEXT
64IFVR(I)=HR(I)THEN76
66VM=VR(I)ANDC1:VE=VR(I)ANDC2
68FORVS=C2TOC3:OUTPA,PV(VS)
70FORK=VI(VS,I,VM,C0)TOVI(VS,I,VM,C1)STEPC3
72ONVK(K)GOSUB31,32,33,34
74NEXT:NEXT
76NEXT
78FORI=C0TOC7:HL(I)=VL(I):HR(I)=VR(I):NEXT:W1=W0
80OUTPA,PR:OUTPC,PU
82ONGGOSUB960,970,980,980,990
84RETURN
89'erase a wall 
90IFW1=C7THENRETURN
92FORVS=C0TOC3:OUTPA,PV(VS):K=VI(VS,W1,C2,C0):OUTPC,VK(K+C1)
94FORJ=C0TOVK(K+C4):OUTPD,C0:NEXT
96NEXT:RETURN
98'draw blocking wall; handle left side
100IFVL(W0)=C4THEN112
102VM=VL(W0)ANDC1:VE=VL(W0)ANDC2
104FORVS=C0TOC1:OUTPA,PV(VS)
106FORK=VI(VS,W0,VM,C0)TOVI(VS,W0,VM,C1)STEPC3
108ONVK(K)GOSUB31,32,33,34
110NEXT:NEXT:GOTO124
112VE=C1:'passage to the left and ahead
114FORVS=C0TOC1:OUTPA,PV(VS)
116FORK=VI(VS,W0,C1,C0)TOVI(VS,W0,C1,C1)STEPC3
118ONVK(K)GOSUB31,36,37,34
120NEXT:NEXT
122'handle right side
124IFVR(W0)=C4THEN136
126VM=VR(W0)ANDC1:VE=VL(W0)ANDC2
128FORVS=C2TOC3:OUTPA,PV(VS)
130FORK=VI(VS,W0,VM,C0)TOVI(VS,W0,VM,C1)STEPC3
132ONVK(K)GOSUB31,32,33,34
134NEXT:NEXT:GOTO148
136VE=C1:'passage to the right and ahead
138FORVS=C2TOC3:OUTPA,PV(VS)
140FORK=VI(VS,W0,C1,C0)TOVI(VS,W0,C1,C1)STEPC3
142ONVK(K)GOSUB31,36,37,34
144NEXT:NEXT
146'finally draw the wall
148IFW0=C7THENRETURN
150FORVS=C0TOC3:OUTPA,PV(VS)
152FORK=VI(VS,W0,C2,C0)TOVI(VS,W0,C2,C1)STEPC3
154ONVK(K)GOSUB31,32,33,34
156NEXT:NEXT
158RETURN
160'== setup, execution starts here ==
195'G: 1=PC-8201A, 2=M10 (w/o modem), 3=Model 100, 4=Model 102, 5=KC85
200B=PEEK(1):G=-(B=148)-(B=35)*2-(B=51)*3-(B=167)*4-(B=225)*5
205IFG=0THENSCREEN0,1:?"Sorry, model not supported. Gestalt:";B:END
210IFG=1THENAK=65128!ELSEIFG=2THENAK=65389!ELSEIFG=5THENAK=65387!ELSEAK=65450!
215C0=0:C1=1:C2=2:C3=3:C4=4:C5=5:C6=6:C7=7:C8=8:C9=9
220CA=10:CC=12:CE=14:CN=49:CL=50:CP=64:CM=-1
225UC=223:LC=97:CK=27:ES=27:EB=32:E8=17
230PA=185:PB=186:PC=254:PD=255:DIMSA(9),SB(9):SG=-1:SH=0
235FORI=C0TOC9:READB1,B2:SA(I)=B1:SB(I)=B2:NEXT
240DX=0:DY=0:DIMDX(3),DY(3):FORI=C0TOC3:READB1,B2:DX(I)=B1:DY(I)=B2:NEXT
245DL=0:DR=0:DIMDL(3),DR(3)
250FORI=C0TOC3:READB:DL(I)=B:NEXT
255FORI=C0TOC3:READB:DR(I)=B:NEXT
260DIMDD(3):FORI=C0TOC3:READB:DD(I)=B:NEXT
269'setup the maze
270DIMSM(3,3,2):FORI=C0TOC3:FORY=C0TOC3:READB1,B2:SM(I,Y,C1)=B1:SM(I,Y,C0)=B2:NEXT:NEXT
275DIMST(3,1,1):FORI=C0TOC3:FORY=C0TOC1:READB1,B2:ST(I,Y,C1)=B1:ST(I,Y,C0)=B2:NEXT:NEXT
280MW=31:MH=15:ML=132:MT=5:DIMM(MH,MW),BM(C9)
285FORY=C0TOC9:READB:BM(Y)=B:NEXT
290FORY=C0TOMH:FORX=C0TOMW:READB:M(Y,X)=B:NEXT:NEXT
295GOSUB1010:GOSUB1110:'setup viewport
299'== main  ==
300CLS:GOSUB700:MX=11:MY=7:MD=0:DX=DX(MD):DY=DY(MD):DL=DL(MD):DR=DR(MD)
310?CHR$(ES);"Y";CHR$(EB+C7);CHR$(EB+22);"Crsr,IJKL,Q:quit";
315GOSUB460:GOSUB1770:GOSUB1510:GOSUB40
319'main loop
320B=PEEK(AK):IFB=C0THEN320
330K=PEEK(AK+B):POKEAK,C0:IFK>CKTHENONK-CKGOTO500,520,540,560
340IFK>=LCTHENK=KANDUC
350ONINSTR("JLKI Q",CHR$(K))GOTO520,500,560,540,580,590
360GOTO320
398'== subroutines ==
399'segement/pos select
400SH=SG:SG=SX\CL:IFSY>C3THENSG=SG+C5
410IF(SG<>SH)THENOUTPA,SA(SG):OUTPB,SB(SG)
420OUTPC,(SYMODC4)*CPORSXMODCL:RETURN
449'clear/draw marker
450X=ML+MX*C3:Y=MT+MY*C3:FORI=C0TOC3:PRESET(X+SM(MD,I,C0),Y+SM(MD,I,C1)):NEXT:RETURN
460X=ML+MX*C3:Y=MT+MY*C3:FORI=C0TOC3:PSET(X+SM(MD,I,C0),Y+SM(MD,I,C1)):NEXT:RETURN
470X=ML+MX*C3:Y=MT+MY*C3:PRESET(X+ST(MD,T0,C0),Y+ST(MD,T0,C1)):PSET(X+ST(MD,T1,C0),Y+ST(MD,T1,C1)):RETURN
499'key handling (right, left, bkwd, fwd, fire, quit)
500T0=C1:T1=C0:GOSUB470:MD=DR:DX=DX(MD):DY=DY(MD):DL=DL(MD):DR=DR(MD):GOTO610
520MD=DL:T0=C0:T1=C1:GOSUB470:DX=DX(MD):DY=DY(MD):DL=DL(MD):DR=DR(MD):GOTO610
540GOSUB450:MX=MX+DX:MY=MY+DY:IFM(MY,MX)=C0THENMX=MX-DX:MY=MY-DY:GOSUB460:GOTO320
550GOSUB460:GOTO610
560GOSUB450:MX=MX-DX:MY=MY-DY:IFM(MY,MX)=C0THENMX=MX+DX:MY=MY+DY:GOSUB460:GOTO320
570GOSUB460:GOTO610
580GOTO320:'shoot
590SCREEN0,1:CLS:?"- Bye -":END
600'view port: get path and display it
610GOSUB1510:GOSUB40:GOTO320
699'maze display
700SY=MT\C8:Y0=0:D=MTMODC8+C2:ONGGOSUB910,920,930,930,940
710Y1=Y0+C1:Y2=Y0+C2:Y3=Y0+C3:B0=BM(D)
720IF(Y1<=MH)AND(D<C7)THENB1=BM(D+C3)ELSEB1=C0
730IF(Y2<=MH)AND(D<C4)THENB2=BM(D+C6)ELSEB2=C0
740IF(Y3<=MH)AND(D=C0)THENB3=BM(D+C9)ELSEB3=C0
750SX=ML:GOSUB400
760FORMX=C0TOMW:IFM(Y0,MX)=C0THENB=B0ELSEB=C0
770IFB1THENIFM(Y1,MX)=C0THENB=BORB1
780IFB2THENIFM(Y2,MX)=C0THENB=BORB2
790IFB3THENIFM(Y3,MX)=C0THENB=BORB3
800FORI=C0TOC2:IFSXMODCL=C0THENGOSUB400
810OUTPD,B:SX=SX+C1:NEXT:NEXT
820Y0=Y0+(CA-D)\C3:IFY0>MHTHEN840
830D=(D+C1)MODC3:SY=SY+C1:GOTO710
840ONGGOSUB960,970,980,980,990:RETURN
900'disable interrupts
910EXEC30437:RETURN
920CALL29558:RETURN
930CALL30300:RETURN
940CALL29450:RETURN
950'enable interrupts
960EXEC29888:RETURN
970CALL28998:RETURN
980CALL29756:RETURN
990CALL28906:RETURN
1000'setup viewport
1010PL=33:PR=66:'LCD blocks 0+5, 1+6
1020PU=59:PQ=58:'LCD counter setting increment/decrement
1030DIMPV(3):FORI=0TO3:READB:PV(I)=B:NEXT
1040DIMBL(29):FORI=0TO29:READB:BL(I)=B:NEXT
1050DIMBP(33):FORI=0TO33:READB:BP(I)=B:NEXT
1060DIMVL(7),VR(7),HL(7),HR(7)
1070DIMVI(3,7,2,1):'segment,level,mode,idx-from/idx-to
1080DIMVK(1392)
1090RETURN
1100'compile-viewport-instr
1110I4=C0
1120READB:IFB<C0THENRETURN:'level
1130FORJ=C0TOC2:READB0:'mode, get length
1140JL=B0*C3:I0=I4:I1=I0+JL:I2=I1+JL:I3=I2+JL:I4=I3+JL
1150VI(C0,B,J,C0)=I0:VI(C0,B,J,C1)=I1-C3
1160VI(C1,B,J,C0)=I1:VI(C1,B,J,C1)=I2-C3
1170VI(C2,B,J,C0)=I2:VI(C2,B,J,C1)=I3-C3
1180VI(C3,B,J,C0)=I3:VI(C3,B,J,C1)=I4-C3
1190FORK=C1TOB0
1193READB1,B2,B3:VK(I0)=B1:VK(I1)=B1:VK(I2)=B1:VK(I3)=B1
1196ONB1GOTO1200,1260,1320,1380
1200VK(I0+C1)=(B2*CP)ORB3
1210VK(I1+C1)=((C3-B2)*CP)ORB3
1220VK(I2+C1)=((C3-B2)*CP)OR(CN-B3)
1230VK(I3+C1)=(B2*CP)OR(CN-B3)
1240P=B3
1250GOTO1430
1260L=B2-P:P=B2+C1
1270VK(I0+C1)=L:VK(I0+C2)=BP(B3)
1280VK(I1+C1)=L:VK(I1+C2)=BP(B3+E8)
1290VK(I2+C1)=L:VK(I2+C2)=BP(B3+E8)
1300VK(I3+C1)=L:VK(I3+C2)=BP(B3)
1310GOTO1430
1320L=B2-P+B3:P=B2+C1
1330VK(I0+C1)=B3:VK(I0+C2)=L
1340VK(I1+C1)=B3+CE:VK(I1+C2)=L+CE
1350VK(I2+C1)=B3+CE:VK(I2+C2)=L+CE
1360VK(I3+C1)=B3:VK(I3+C2)=L
1370GOTO1430
1380VK(I0+C1)=BP(B2):VK(I0+C2)=BP(B3)
1390VK(I1+C1)=BP(B2+E8):VK(I1+C2)=BP(B3+E8)
1400VK(I2+C1)=BP(B2+E8):VK(I2+C2)=BP(B3+E8)
1410VK(I3+C1)=BP(B2):VK(I3+C2)=BP(B3)
1420P=P+C1
1430I0=I0+C3:I1=I1+C3:I2=I2+C3:I3=I3+C3
1440NEXT:NEXT:GOTO1120
1500'assemble view path data
1510Y=MY:X=MX:VL=DD(DL):VR=DD(DR):VF=DD(MD):W0=CM:FW=C0
1520FORI=C0TOC7:B=M(Y,X)
1523IFBANDVLTHENVL(I)=C1ELSEVL(I)=C0
1526IFBANDVRTHENVR(I)=C1ELSEVR(I)=C0
1530IFI=C0THEN1570
1540IFVL(I)<>VL(I-C1)THENVL(I-C1)=VL(I-C1)ORC2
1560IFVR(I)<>VR(I-C1)THENVR(I-C1)=VR(I-C1)ORC2
1570IFBANDVFTHEN1610
1580IFVL(I)=C0THENVL(I)=C2ELSEIFM(Y+DY(DL),X+DX(DL))ANDVFTHENVL(I)=C4ELSEVL(I)=C1
1590IFVR(I)=C0THENVR(I)=C2ELSEIFM(Y+DY(DR),X+DX(DR))ANDVFTHENVR(I)=C4ELSEVR(I)=C1
1600W0=I:FW=I+C1:I=C7:GOTO1620
1610X=X+DX:Y=Y+DY
1620NEXT
1630IFW0=W1THENW1=CM
1640IF(FW)AND(FW<C8)THENFORI=FWTOC7:VL(I)=CM:VR(I)=CM:NEXT
1650RETURN
1700'clear/init viewport
1710ONGGOSUB910,920,930,930,940
1720OUTPA,PLORPR:OUTPB,C0:'enable blocks 0,1,5,6 at once
1730FORY=C0TOC3:OUTPC,Y*CP
1740FORX=C0TOCN:OUTPD,C0:NEXT
1750NEXT
1760ONGGOSUB960,970,980,980,990
1770FORI=0TO7:HL(I)=CM:HR(I)=CM:NEXT:W0=CM:W1=CM
1780RETURN
2000'port patterns for segments (0..9: PA,PB)
2001DATA1,0,2,0,4,0,8,0,16,0,32,0,64,0,128,0,0,1,0,2
2002'directions (0..3:dx,dy)
2003DATA0,-1,-1,0,0,1,1,0
2004'turns (L: 0..3, R: 0..3)
2005DATA1,2,3,0,3,0,1,2
2006'directional codes (2^0..3)
2007DATA1,2,4,8
2008'maze maker defs (0..3:Y,X)
2009DATA0,1,1,0,1,1,1,2,0,1,1,0,1,1,2,1,1,0,1,1,1,2,2,1,0,1,1,1,1,2,2,1
2010'maze marker turn pixel mods (Y,X)
2011DATA2,1,1,0,1,2,2,1,0,1,1,2,1,0,0,1
2012'maze bit patterns
2013DATA1,3,7,14,28,56,112,224,192,128
2019'maze data
2020DATA0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0
2021DATA0,12,10,14,10,14,10,10,10,14,10,10,14,2,0,8,14,10,10,10,10,14,10,10,10,14,10,10,10,10,6,0
2022DATA0,1,0,5,0,5,0,0,0,5,0,0,5,0,0,0,5,0,0,0,0,5,0,0,0,5,0,0,0,0,5,0
2023DATA0,0,0,5,0,9,14,10,10,3,0,12,11,14,10,10,11,14,10,6,0,5,0,12,10,11,6,0,12,10,3,0
2024DATA0,4,0,5,0,0,5,0,0,0,0,5,0,1,0,0,0,5,0,5,0,5,0,5,0,0,9,10,7,0,0,0
2025DATA0,13,10,15,10,10,11,10,10,10,10,7,0,0,0,4,0,5,0,9,10,11,10,11,6,0,0,0,9,6,0,0
2026DATA0,5,0,5,0,0,0,0,0,0,0,5,0,12,10,11,10,7,0,0,0,0,0,0,13,10,10,6,0,9,2,0
2027DATA0,5,0,9,10,14,10,10,10,6,0,5,0,5,0,0,0,9,10,10,10,6,0,0,5,0,0,13,2,0,0,0
2028DATA0,5,0,0,0,5,0,0,0,13,10,7,0,13,10,6,0,0,0,0,0,5,0,12,11,6,0,5,0,0,4,0
2029DATA0,9,10,6,0,13,10,6,0,5,0,5,0,5,0,5,0,12,10,6,0,5,0,5,0,5,0,9,14,10,7,0
2030DATA0,0,0,5,0,5,0,1,0,5,0,13,10,7,0,5,0,5,0,5,0,5,0,5,0,5,0,0,5,0,5,0
2031DATA0,4,0,5,0,5,0,0,0,5,0,5,0,5,0,5,0,5,0,5,0,5,0,5,0,9,14,10,7,0,5,0
2032DATA0,5,0,5,0,9,10,10,10,3,0,5,0,1,0,9,10,11,14,11,10,3,0,9,6,0,5,0,1,0,5,0
2033DATA0,5,0,5,0,0,0,0,0,0,0,5,0,0,0,0,0,0,5,0,0,0,0,0,5,0,5,0,0,0,5,0
2034DATA0,9,10,11,10,10,10,10,10,10,10,11,10,10,10,10,10,10,11,10,10,10,10,10,11,10,11,10,10,10,3,0
2035DATA0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0
3000'segment addresses (port A)
3001DATA1,32,64,2
3005'line pixels
3006DATA1,1,2,2,4,4,8,8,16,16
3007DATA32,32,64,64,128,128,64,64,32,32
3008DATA16,16,8,8,4,4,2,2,1,1
3010'pixels for repeats
3011DATA0,1,2,4,8,16,32,64,128
3012DATA255,254,252,248,240,224,192,128
3013'inverse direction (bottom up)
3014DATA0,128,64,32,16,8,4,2,1
3015DATA255,127,63,31,15,7,3,1
3020'viewport commands struct, 1st quadrant, per level and mode
3021DATA0:'level 0
3022DATA10
3023DATA1,0,0,3,5,10
3024DATA1,1,0,2,5,0,2,6,1,4,9,1
3025DATA1,2,7,4,9,0
3026DATA1,3,7,4,9,0
3027DATA9
3028DATA1,0,0,2,5,0
3029DATA1,1,0,2,6,1,4,9,1
3030DATA1,2,7,4,9,0
3031DATA1,3,7,4,9,0
3032DATA6
3033DATA1,1,8,2,49,1
3034DATA1,2,8,2,49,0
3035DATA1,3,8,2,49,0
3036DATA1:'level 1
3037DATA7
3038DATA1,1,8,3,15,2,4,14,6
3039DATA1,2,16,4,9,0
3040DATA1,3,16,4,9,0
3041DATA7
3042DATA1,1,8,2,15,6,4,14,6
3043DATA1,2,16,4,9,0
3044DATA1,3,16,4,9,0
3045DATA6
3046DATA1,1,17,2,49,6
3047DATA1,2,17,2,49,0
3048DATA1,3,17,2,49,0
3049DATA2:'level 2
3050DATA8
3051DATA1,1,17,3,21,11
3052DATA1,2,17,2,21,0,3,23,0,4,10,2
3053DATA1,3,24,4,9,0
3054DATA7
3055DATA1,1,17,2,21,0
3056DATA1,2,17,2,23,2,4,10,2
3057DATA1,3,24,4,9,0
3058DATA4
3059DATA1,2,25,2,49,2
3060DATA1,3,25,2,49,0
3061DATA3:'level 3
3062DATA5
3063DATA1,2,25,3,30,3,4,13,5
3064DATA1,3,31,4,9,0
3065DATA5
3066DATA1,2,25,2,30,5,4,13,5
3067DATA1,3,31,4,9,0
3068DATA4
3069DATA1,2,32,2,49,5
3070DATA1,3,32,2,49,0
3071DATA4:'level 4
3072DATA5
3073DATA1,2,32,3,36,10,4,8,8
3074DATA1,3,37,4,9,0
3075DATA5
3076DATA1,2,32,2,36,8,4,8,8
3077DATA1,3,37,4,9,0
3078DATA4
3079DATA1,2,38,2,49,8
3080DATA1,3,38,2,49,0
3081DATA5:'level 5
3082DATA3
3083DATA1,3,38,3,41,0,4,11,3
3084DATA3
3085DATA1,3,38,2,41,3,4,11,3
3086DATA2
3087DATA1,3,43,2,49,3
3089DATA6:'level 6
3090DATA3
3091DATA1,3,43,3,45,5,4,13,5
3092DATA3
3093DATA1,3,43,2,45,5,4,13,5
3094DATA2
3095DATA1,3,47,2,49,5
3096DATA7:'level 7
3097DATA3
3098DATA1,3,47,3,48,9,4,14,14
3099DATA3
3100DATA1,3,47,2,48,6,4,14,14
3101DATA2
3102DATA1,3,49,2,49,14
3103DATA-1

The compressed program (diff.: 1,335 bytes) executes faster by a remarkable amount and is suitably responsive for an interactive game! — Finally, we met our goal of doing some usable pseudo-3D in BASIC only. Not a bad ending, at all!

Download it here: MazeWarRoamer.txt

Before we close, a last glance at our trusty Olivetti M10 running the program:

RC2016/01:Viewport into the maze, Olivetti M10

Roaming the passages of the Maze War labyrinth on the Olivetti M10.

And here, we arrived at the end of our story, even at the end of the addendum to it. I guess, we'll have to find out, if there is such a thing as an addendum to the addendum. I might be in error, but I do not think so …

Cheers, again, and thanks again to all who followed these posts, and, finally,

— finis —

 

Previous:   Episode 12: A Screen With A View

Back to the index.

— This series is part of Retrochallenge 2016/01. —