Problem
Here is a picture (to scale) of how memory is being used in
units of "pages" (256 bytes) on the Apple 2.
000000001111111111111111 2222222222222222 3 ... ... 9
89ABCDEF0123456789ABCDEF 0123456789ABCDEF 0 ... ... 6
+------------------------+----------------+--------------+
|Basic:::::::::::::::::::|::: HGR | |
|Program:::::::::::::::::|::: Page 1 | |
+------------------------+----------------+--------------+
<-- Low Memory High Memory -->
Here is a zoomed-out view of memory (not to scale):
+----------+----------+----------+----------+----------+
|Basic/////:// HGR : HGR : Free : DOS or |
|Program///:// Page 1 : Page 2 : Memory : BASIC |
+----------+----------+----------+----------+----------+
$0800 $2000 $4000 $6000 $9600
\_________/ \__________/
6,143 bytes 13,823 bytes
~5 KB ~13 KB
Applesoft BASIC programs starts at memory address $0801 by default. Your program is so HUGE, that is > 5 KB, that it is spilling over into the memory of the HGR graphics page 1. You can get the end address of your program via:
PRINT PEEK(176)*256+PEEK(175)
8398
HGR Page 1 starts 8192 and ends at 16383. Thus When run the HGR
command literally "clears" the middle of your program and that is why it crashes at line 330.
i.e.
SYNTAX ERROR AT 330
]LIST 330-
330 HPLOT 114,99 TO 164,99: HPLOT
115,
65535 h DATA DIM h DATA
1019 b CAN'T CONTINUE CAN'T CONTINUE
SPC( L< ABS L: RND
19646
0 h h
You see "junk" because the bytes of the HGR graphics page are being
(re)interpreted as BASIC tokens.
It also has a bug where you leave HCOLOR
uninitialized and will use the
last HCOLOR set. That is easy to fix by adding HCOLOR=3
at the start.
You can move your program to be above HGR page 1 by telling Applesoft
where your program now resides at. You will also need to set the first
byte to be zero. By consulting the classic Beagle Bros Peeks and Pokes Chart we see that Zero Page address
locations 103 and 103 point to the start of the Applesoft BASIC program.
? PEEK(103)
1
? PEEK(104)
8
That is, $801, is the default start address as previously mentioned.
Solution 1
To tell Applesoft that our programs now starts at $4001 (16385 in decimal) we can execute these commands:
POKE 103,1:POKE 104,64:POKE 16384,0
RUN LOST.BAS
Voilà! Your program now runs without crashing.
Note: We also need to set the byte before the start of the program to zero due to a bug/feature of Applesoft BASIC. For anyone curious the zero page variable TXTTAB in COLD.START
F1B0- 91 67 3550 STA (TXTTAB),Y FIRST BYTE IN PROGRAM SPACE = 0
Solution 2
If you don't want to mess around with moving your Applesoft program to be
"above" the HGR memory to $4000 or $6000 then one solution would to split
your program into multiple programs that BLOAD
& BSAVE
partial image updates. Basically, (pardon the pun), composite the scene layer by layer, the same way artists due in Photoshop, etc.
i.e.
RUN MAKE.LOST.1.BAS
RUN MAKE.LOST.2.BAS
HGR
BLOAD LOST.HGR,A$2000
You can split the program into two like this:
File: MAKE.LOST.1.BAS
NEW
5 REM DHARMA INITIATIVE LOGO
10 HOME
15 HGR:HCOLOR=3
20 HPLOT 108,4 TO 170,4 TO 213,47 TO 213,110 to 170,153 TO 107,153 TO 64,110 TO 64,47 TO 107,4
25 HPLOT 108,5 TO 170,5 TO 212,47 TO 212,110 to 170,152 TO 107,152 TO 65,110 TO 65,47 TO 107,5
30 HPLOT 108,6 TO 170,6 TO 211,47 TO 211,110 to 170,151 TO 107,151 TO 66,110 TO 66,47 TO 107,6
31 HPLOT 108,7 TO 170,7 TO 210,47 TO 210,110 to 170,150 TO 107,150 TO 67,110 TO 67,47 TO 107,7
35 HPLOT 108,8 TO 170,8 TO 209,47 TO 209,110 to 170,149 TO 107,149 TO 68,110 TO 68,47 TO 107,8
40 HPLOT 108,9 TO 170,9 TO 208,47 TO 208,110 to 170,148 TO 107,148 TO 69,110 TO 69,47 TO 107,9
45 HPLOT 117,17 TO 160,17 TO 160,18 TO 117,18 TO 117,19 TO 160,19 : HPLOT 159,20 TO 118,20 TO 118,21 TO 159,21 : HPLOT 120,22 TO 157,22
50 HPLOT 167,21 TO 179,33 : HPLOT 179,34 TO 166,21 : HPLOT 166,22 TO 178,34 : HPLOT 178,35 TO 166,23 : HPLOT 165,23 TO 177,35 : HPLOT 177,36 TO 165,24 : HPLOT 165,25 TO 176,36
55 HPLOT 184,38 TO 196,50 : HPLOT 196,51 TO 183,38 : HPLOT 183,39 TO 195,51 : HPLOT 194,51 TO 182,39 : HPLOT 182,40 TO 194,52 : HPLOT 193,52 TO 181,40 : HPLOT 181,41 TO 192,52
60 HPLOT 200,57 TO 200,100 TO 199,100 TO 199,57 TO 198,57 TO 198,100 TO 197,99 TO 197,58 TO 196,58 TO 196,99 : HPLOT 195,97 TO 195,60
65 HPLOT 197,107 TO 167,137 : HPLOT 166,137 TO 197,106 : HPLOT 196,106 TO 166,136 : HPLOT 166,135 TO 195,106 : HPLOT 195,105 TO 165,135 : HPLOT 165,134 TO 194,105 : HPLOT 193,105 TO 165,133
70 HPLOT 159,140 TO 141,140 TO 141,139 TO 159,139 TO 159,138 TO 141,138 TO 141,137 TO 158,137 TO 158,136 TO 141,136 : HPLOT 141,135 TO 156,135
75 HPLOT 135,140 TO 117,140 TO 117,139 TO 135,139 TO 135,138 TO 117,138 TO 118,137 TO 135,137 TO 135,136 TO 118,136 : HPLOT 120,135 TO 135,135
80 HPLOT 109,136 TO 97,124 : HPLOT 97,123 TO 110,136 : HPLOT 110,135 TO 98,123 : HPLOT 98,122 TO 110,134 : HPLOT 111,134 TO 99,122 : HPLOT 99,121 TO 111,133 : HPLOT 111,132 TO 100,121
85 HPLOT 92,119 TO 80,107 : HPLOT 80,106 TO 93,119 : HPLOT 93,118 TO 81,106 : HPLOT 82,106 TO 94,118 : HPLOT 94,117 TO 82,105 : HPLOT 83,105 TO 95,117 : HPLOT 95,116 TO 84,105
90 HPLOT 77,100 TO 77,57 TO 78,57 TO 78,100 TO 79,100 TO 79,57 : HPLOT 80,58 TO 80,99 TO 81,99 TO 81,58 : HPLOT 82,60 TO 82,97
95 HPLOT 81,50 TO 93,38 : HPLOT 94,38 TO 81,51 : HPLOT 82,51 TO 94,39 : HPLOT 95,39 TO 83,51 : HPLOT 83,52 TO 95,40 : HPLOT 96,40 TO 84,52 : HPLOT 85,52 TO 96,41
100 HPLOT 98,33 TO 110,21 : HPLOT 111,21 TO 98,34 : HPLOT 99,34 TO 111,22 : HPLOT 111,23 TO 99,35 : HPLOT 100,35 TO 112,23 : HPLOT 112,24 TO 100,36 : HPLOT 101,36 TO 112,25
105 HPLOT 121,26 TO 135,26 TO 135,27 TO 121,27 TO 122,28 TO 135,28 TO 135,29 TO 122,29 TO 123,30 TO 135,30 TO 135,31 TO 123,31
110 HPLOT 141,26 TO 156,26 TO 156,27 TO 141,27 TO 141,28 TO 155,28 TO 155,29 TO 141,29 TO 141,30 TO 154,30 TO 154,31 TO 141,31
115 HPLOT 164,30 TO 174,40 TO 174,41 TO 163,30 TO 163,31 TO 173,41 TO 173,42 TO 163,32 TO 162,32 TO 172,42 TO 172,43 TO 162,33 TO 162,34 TO 171,43
120 HPLOT 178,44 TO 187,53 TO 187,54 TO 177,44 TO 177,45 TO 186,54 TO 185,54 TO 176,45 TO 176,46 TO 185,55 TO 184,55 TO 175,46 TO 175,47 TO 183,55
125 HPLOT 191,61 TO 191,96 TO 190,96 TO 190,61 : HPLOT 189,62 TO 189,95 TO 188,95 TO 188,62 : HPLOT 187,63 TO 187,94 TO 186,94 TO 186,63
130 HPLOT 187,104 TO 163,128 : HPLOT 162,128 TO 187,103 : HPLOT 186,103 TO 162,127 : HPLOT 162,126 TO 185,103 : HPLOT 185,102 TO 161,126 : HPLOT 161,125 TO 184,102 : HPLOT 183,102 TO 161,124
135 HPLOT 156,131 TO 121,131 TO 121,130 TO 156,130 : HPLOT 155,129 TO 122,129 TO 122,128 TO 155,128 : HPLOT 154,127 TO 123,127 TO 123,126 TO 154,126
140 HPLOT 113,127 TO 103,117 : HPLOT 103,116 TO 114,127 : HPLOT 114,126 TO 104,116 : HPLOT 104,115 TO 114,125 : HPLOT 115,125 TO 105,115 : HPLOT 105,114 TO 115,124 : HPLOT 115,123 TO 106,114
145 HPLOT 99,113 TO 90,104 : HPLOT 90,103 TO 100,113 : HPLOT 100,112 TO 91,103 : HPLOT 92,103 TO 101,112 : HPLOT 101,111 TO 92,102 : HPLOT 93,102 TO 102,111 : HPLOT 102,110 TO 94,102
150 HPLOT 86,96 TO 86,82 TO 87,82 TO 87,96 : HPLOT 88,95 TO 88,82 TO 89,82 TO 89,95 : HPLOT 90,94 TO 90,82 TO 91,82 TO 91,94
155 HPLOT 86,76 TO 86,61 TO 87,61 TO 87,76 TO 88,76 TO 88,62 TO 89,62 TO 89,76 TO 90,76 TO 90,63 TO 91,63 TO 91,76
160 HPLOT 89,54 TO 113,30 : HPLOT 114,30 TO 89,55 : HPLOT 90,55 TO 114,31 : HPLOT 114,32 TO 91,55 : HPLOT 91,56 TO 115,32 : HPLOT 115,33 TO 92,56 : HPLOT 93,56 TO 115,34
165 HPLOT 125,34 TO 152,34 TO 152,35 TO 125,35 : HPLOT 126,36 TO 151,36 TO 151,37 TO 126,37 : HPLOT 127,38 TO 150,38 TO 150,39 TO 127,39
170 HPLOT 160,38 TO 168,46 : HPLOT 168,47 TO 160,39 : HPLOT 160,40 TO 167,47 : HPLOT 167,48 TO 159,40 : HPLOT 159,41 TO 166,48 : HPLOT 166,49 TO 159,42 : HPLOT 159,43 TO 165,49
175 HPLOT 172,50 TO 179,57 : HPLOT 178,57 TO 171,50 : HPLOT 171,51 TO 177,57 : HPLOT 177,58 TO 170,51 : HPLOT 170,52 TO 176,58 : HPLOT 175,58 TO 169,52 : HPLOT 169,53 TO 174,58
180 HPLOT 183,65 TO 183,76 TO 182,76 TO 182,65 : HPLOT 181,66 TO 181,76 TO 180,76 TO 180,66 : HPLOT 179,67 TO 179,76 TO 178,76 TO 178,67
185 HPLOT 183,82 TO 183,92 TO 182,92 TO 182,82 TO 181,82 TO 181,91 TO 180,91 TO 180,82 TO 179,82 TO 179,90 TO 178,90 TO 178,82
190 HPLOT 179,100 TO 160,119 : HPLOT 160,118 TO 178,100 : HPLOT 177,100 TO 160,117 : HPLOT 159,117 TO 177,99 : HPLOT 176,99 TO 159,116 : HPLOT 159,115 TO 175,99 : HPLOT 174,99 TO 159,114
195 HPLOT 152,123 TO 141,123 TO 141,122 TO 152,122 : HPLOT 151,121 TO 141,121 TO 141,120 TO 151,120 : HPLOT 150,119 TO 141,119 TO 141,118 TO 150,118
200 HPLOT 135,123 TO 125,123 TO 125,122 TO 135,122 TO 135,121 TO 126,121 TO 126,120 TO 135,120 TO 135,119 TO 127,119 TO 127,118 TO 135,118
205 HPLOT 117,119 TO 98,100 : HPLOT 99,100 TO 117,118 : HPLOT 117,117 TO 100,100 : HPLOT 100,99 TO 118,117 : HPLOT 118,116 TO 101,99 : HPLOT 102,99 TO 118,115 : HPLOT 118,114 TO 103,99
210 HPLOT 94,92 TO 94,82 TO 95,82 TO 95,92 : HPLOT 96,91 TO 96,82 TO 97,82 TO 97,91 : HPLOT 98,90 TO 98,82 TO 99,82 TO 99,90
215 HPLOT 94,76 TO 94,65 TO 95,65 TO 95,76 TO 96,76 TO 96,66 TO 97,66 TO 97,76 TO 98,76 TO 98,67 TO 99,67 TO 99,76
220 HPLOT 97,58 TO 116,39 : HPLOT 116,40 TO 98,58 : HPLOT 99,58 TO 116,41 : HPLOT 117,41 TO 99,59 : HPLOT 100,59 TO 117,42 : HPLOT 117,43 TO 101,59 : HPLOT 102,59 TO 117,44
221 PRINT CHR$(4)"BSAVE LOST.HGR,A$2000,L$1FF8"
222 END
SAVE MAKE.LOST.1.BAS
File: MAKE.LOST.2.BAS
NEW
223 HGR:HCOLOR=3
224 PRINT CHR$(4)"BLOAD LOST.HGR,A$2000"
225 REM DHARMA LOGO CORE
230 HPLOT 135,46 TO 143,46 : HPLOT 130,47 TO 148,47 : HPLOT 127,48 TO 151,48 : HPLOT 125,49 TO 153,49 : HPLOT 124,50 TO 155,50 : HPLOT 122,51 TO 156,51 : HPLOT 120,52 TO 158,52
235 HPLOT 119,53 TO 160,53 : HPLOT 118,54 TO 160,54 : HPLOT 117,55 TO 161,55 : HPLOT 116,56 TO 162,56 : HPLOT 115,57 TO 163,57 : HPLOT 114,58 TO 164,58 : HPLOT 114,59 TO 164,59
240 HPLOT 113,60 TO 165,60 : HPLOT 112,61 TO 166,61 : HPLOT 112,62 TO 166,62 : HPLOT 111,63 TO 167,63 : HPLOT 111,64 TO 167,64 : HPLOT 110,65 TO 168,65 : HPLOT 109,66 TO 168,66
245 HPLOT 109,67 TO 169,67 : HPLOT 109,68 TO 169,68 : HPLOT 109,69 TO 169,69 : HPLOT 108,70 TO 170,70 : HPLOT 108,71 TO 170,71 : HPLOT 108,72 TO 170,72 : HPLOT 107,73 TO 170,73
250 HPLOT 107,74 TO 112,74 : HPLOT 119,74 TO 122,74 : HPLOT 124,74 TO 127,74 : HPLOT 129,74 TO 133,74 : HPLOT 136,74 TO 140,74 : HPLOT 146,74 TO 171,74
255 HPLOT 107,75 TO 112,75 : HCOLOR = 0 : HPLOT 112,75 : HCOLOR = 3: HPLOT 121,75 : HPLOT 125,75 TO 126,75 : HPLOT 129,75 TO 132,75 : HPLOT 136,75 TO 139,75 : HPLOT 148,75 TO 149,75
256 HPLOT 159,75 TO 162,75 : HPLOT 151,75 TO 156,75 : HPLOT 165,75 TO 171,75
260 HPLOT 107,76 TO 111,76 : HPLOT 115,76 TO 117,76 : HPLOT 121,76 : HPLOT 125,76 TO 126,76 : HPLOT 129,76 TO 132,76 : HPLOT 137,76 TO 139,76 : HPLOT 142,76 TO 145,76 : HPLOT 148,76 TO 149,76 : HPLOT 152,76 TO 155,76
265 HPLOT 159,76 TO 161,76 : HPLOT 166,76 TO 171,76
270 HPLOT 107,77 TO 111,77 : HPLOT 115,77 TO 118,77 : HPLOT 121,77 : HPLOT 125,77 TO 126,77 : HPLOT 129,77 TO 131,77 : HPLOT 134,77 TO 135,77 : HPLOT 138,77 TO 139,77 : HPLOT 142,77 TO 144,77 : HPLOT 148,77 TO 149,77
275 HPLOT 153,77 TO 154,77 : HPLOT 159,77 TO 160,77 : HPLOT 163,77 TO 164,77 : HPLOT 166,77 TO 171,77
280 HPLOT 107,78 TO 111,78 : HPLOT 115,78 TO 118,78 : HPLOT 121,78 : HPLOT 129,78 TO 131,78 : HPLOT 134,78 TO 135,78 : HPLOT 138,78 TO 139,78 : HPLOT 147,78 TO 149,78 : HPLOT 159,78 TO 160,78 : HPLOT 167,78 TO 171,78
285 HPLOT 107,79 TO 111,79 : HPLOT 115,79 TO 117,79 : HPLOT 121,79 : HPLOT 129,79 TO 130,79 : HPLOT 139,79 : HPLOT 146,79 TO 149,79 : HPLOT 152,79 : HPLOT 156,79 : HPLOT 159,79 : HPLOT 167,79 TO 171,79
290 HPLOT 107,80 TO 111,80 : HPLOT 120,80 TO 121,80 : HPLOT 125,80 TO 126,80 : HPLOT 129,80 : HPLOT 139,80 : HPLOT 142,80 TO 143,80 : HPLOT 148,80 TO 149,80 : HPLOT 152,80 TO 153,80 : HPLOT 155,80 TO 156,80 : HPLOT 159,80
295 HPLOT 162,80 TO 165,80 : HPLOT 168,80 TO 171,80
300 HPLOT 107,81 TO 111,81 : HPLOT 119,81 TO 121,81 : HPLOT 125,81 TO 126,81 : HPLOT 129,81 : HPLOT 133,81 TO 136,81 : HPLOT 139,81 : HPLOT 142,81 TO 144,81 : HPLOT 149,81 : HPLOT 152,81 TO 156,81 : HPLOT 159,81
305 HPLOT 162,81 TO 165,81 : HPLOT 169,81 TO 171,81
310 HPLOT 107,82 TO 111,82 : HPLOT 117,82 TO 122,82 : HPLOT 124,82 TO 127,82 : HPLOT 129,82 : HPLOT 132,82 TO 137,82 : HPLOT 139,82 : HPLOT 142,82 TO 145,82 : HPLOT 149,82 : HPLOT 152,82 TO 156,82 : HPLOT 159,82
315 HPLOT 161,82 TO 166,82 : HPLOT 169,82 TO 171,82
320 HPLOT 107,83 TO 171,83 : HPLOT 108,84 TO 170,84 : HPLOT 108,85 TO 170,85 : HPLOT 108,86 TO 170,86 : HPLOT 108,87 TO 170,87 : HPLOT 108,88 TO 169,88 : HPLOT 109,89 TO 169,89 : HPLOT 109,90 TO 169,90
325 HPLOT 109,91 TO 169,91 : HPLOT 110,92 TO 168,92 : HPLOT 110,93 TO 168,93 : HPLOT 111,94 TO 167,94 : HPLOT 112,95 TO 166,95 : HPLOT 112,96 TO 166,96 : HPLOT 113,97 TO 165,97 : HPLOT 114,98 TO 164,98
330 HPLOT 114,99 TO 164,99 : HPLOT 115,100 TO 163,100 : HPLOT 116,101 TO 162,101 : HPLOT 117,102 TO 162,102 : HPLOT 118,103 TO 160,103 : HPLOT 119,104 TO 159,104 : HPLOT 121,105 TO 157,105
335 HPLOT 122,106 TO 156,106 : HPLOT 124,107 TO 154,107 : HPLOT 125,108 TO 153,108 : HPLOT 127,109 TO 151,109 : HPLOT 131,110 TO 148,110 : HPLOT 135,111 TO 143,111
339 PRINT CHR$(4)"BSAVE LOST.HGR,A$2000,L$1FF8"
SAVE MAKE.LOST.2.BAS
Sooner or later you WILL run out of memory. That leads us to the next solution.
Solution 3
If we take a step back and apply a Data-Orientated Design methodology, of which Data-driven programming is a subset of, we see that the root problem is ASCII is horribly inefficient at storing numeric data! A single coordinate takes up anywhere from 3 to 4 bytes!!
e.g.
HPLOT 123 , 23 TO
\_/ \_/ \_/ \_/
3 1 2 1 Bytes
Total bytes for a pair: ~8 bytes (depending if the Y coordinate has 2 or 3 digits.)
How do we compress this data? Should we use delta compression? LZ4?
The first rule of DOD is:
KNOW THY DATA
By examining all the X and Y coordinates we see that each number is less then 256 due to the Apple's HGR screen being 280 x 192 and us never plotting beyond column 256. This means that we could simply store each number in binary as an 8-bit number.
Next, let's convert this into a data-driven program:
READ and DATA
Originally, I left converting lines 225-335 of the original program ("DHARMA LOGO CORE") as an exercise for the reader but due to some people being too lazy I've included walking through an example of how to convert this section to DATA statements:
First, split all the HPLOT statements so they are on their own line.
230 HPLOT 135,46 TO 143,46 :
HPLOT 130,47 TO 148,47 :
HPLOT 127,48 TO 151,48 :
HPLOT 125,49 TO 153,49 :
HPLOT 124,50 TO 155,50 :
HPLOT 122,51 TO 156,51 :
HPLOT 120,52 TO 158,52
:
335 HPLOT 122,106 TO 156,106 :
HPLOT 124,107 TO 154,107 :
HPLOT 125,108 TO 153,108 :
HPLOT 127,109 TO 151,109 :
HPLOT 131,110 TO 148,110 :
HPLOT 135,111 TO 143,111
Second, we notice that we drawing from Y=46 to Y=111. After we draw each line we can increment Y.
Third, we notice there are three groupings:
- Semi-circle above "DHARMA"
- The text "DHARMA"
- Semi-circle below "DHARMA"
Fourth, drawing the text "DHARMA" sometimes plots single pixels. If we convert these edge cases into the more convenient form of HPLOT X,Y TO X,Y
then the entire part 2 will a consistent format. We need these extra drawing routines:
- Draw N lines. For each line draw from X1,Y to X2,Y and increment Y.
- Draw M segments. For each segment draw from X1,Y to X2,Y. Afterwards increment Y.
That is, we'll have these two lines:
15 FOR J=1 TO N:READ X1,X2:HPLOT X1,Y TO X2,Y:Y=Y+1:NEXT:RETURN
16 FOR J=1 TO M:READ X1,X2:HPLOT X1,Y TO X2,Y:NEXT:Y=Y+1:RETURN
Next, we notice there are:
- 28 lines above "DHARMA"
- 9 lines for "DHARMA"
- 29 lines below "DHARMA"
To draw the DHARMA circle all we need is:
230 Y=46:N=28:GOSUB 15:FOR K=1 TO 9:READ M:GOSUB 16:NEXT:N=29:GOSUB 15:END
That leaves the data.
For the top of the circle we can store pairs of {start,end} X coordinates like this:
DATA 135,143,130,148,127,151,125,153,124,155,122,156,120,158,119,160,118,160,117,161,116,162,115,163,114,164,114,164,113,165,112,166,112,166,111,167,111,167,110,168,109,168,109,169,109,169,109,169,108,170,108,170,108,170,107,170
For the bottom of the circle we can again store pairs of X coordinates:
DATA 107,171,108,170,108,170,108,170,108,170,108,169,109,169,109,169,109,169,110,168,110,168,111,167,112,166,112,166,113,165,114,164,114,164,115,163,116,162,117,162,118,160,119,159,121,157,122,156,124,154,125,153,127,151,131,148,135,143
For the middle of the circle, the 9 scanlines that draw "DHARMA", each scanlines has a varying number of segments. Let's convert line 255 since it is the trickiest. Splitting it so that we have one HPLOT per line:
255 HPLOT 107,75 TO 112,75 :
HCOLOR = 0 : HPLOT 112,75 :
HCOLOR = 3 :
HPLOT 121,75 :
HPLOT 125,75 TO 126,75 :
HPLOT 129,75 TO 132,75 :
HPLOT 136,75 TO 139,75 :
HPLOT 148,75 TO 149,75
We can get rid of resetting the color to white by removing HCOLOR=3
:
255 HPLOT 107,75 TO 112,75 :
HCOLOR = 0 : HPLOT 112,75 :
HPLOT 121,75 :
HPLOT 125,75 TO 126,75 :
HPLOT 129,75 TO 132,75 :
HPLOT 136,75 TO 139,75 :
HPLOT 148,75 TO 149,75
We can also convert that HPLOT 121,75
to be of the form HPLOT X1,Y to X2,Y
:
255 HPLOT 107,75 TO 112,75 :
HCOLOR = 0 : HPLOT 112,75 :
HPLOT 121,75 TO 121,75 :
HPLOT 125,75 TO 126,75 :
HPLOT 129,75 TO 132,75 :
HPLOT 136,75 TO 139,75 :
HPLOT 148,75 TO 149,75
Instead of erasing that single pixel at 112,75 we can shorten the line segments on either side.
- We don't plot any pixels at 113 so we are good here.
- Our line went from 107 to 112 but since we erase 112 we can snip the end so it goes from 107 to 111 instead.
This is what our line 255 looks like:
255 HPLOT 107,75 TO 111,75
HPLOT 121,75 to 121,75
HPLOT 125,75 TO 126,75
HPLOT 129,75 TO 132,75
HPLOT 136,75 TO 139,75
HPLOT 148,75 TO 149,75
HPLOT 159,75 TO 162,75
HPLOT 151,75 TO 156,75
HPLOT 165,75 TO 171,75
What's left is to count the number of segments for each of the "DHARMA" lines.
* 6 on line 75
* 9 on line 76
* 11 on line 77
* 13 on line 78
* 9 on line 79
* 10 on line 80
* 12 on line 81
* 12 on line 82
* 12 on line 83
Putting it all together:
NEW
0 HGR:HCOLOR=3:GOTO 20
1 FOR J=1 TO N:READ X,Y:HPLOT X,Y:FOR I=1 TO M:READ X,Y:HPLOT TO X,Y:NEXT:NEXT:RETURN
2 M= 1:GOTO 1
4 M= 3:GOTO 1
5 REM DHARMA INITIATIVE LOGO
6 M= 5:GOTO 1
9 M= 8:GOTO 1
10 M= 9:N=1:GOTO 1
12 M=11:N=1:GOTO 1
14 M=13:N=1:GOTO 1
15 FOR J=1 TO N:READ X1,X2:HPLOT X1,Z TO X2,Z:Z=Z+1:NEXT:RETURN
16 FOR J=1 TO M:READ X1,X2:HPLOT X1,Z TO X2,Z:NEXT:Z=Z+1:RETURN
20 N= 6:GOSUB 9:DATA108,4,170,4,213,47,213,110,170,153,107,153,64,110,64,47,107,4,108,5,170,5,212,47,212,110,170,152,107,152,65,110,65,47,107,5
30 DATA108,6,170,6,211,47,211,110,170,151,107,151,66,110,66,47,107,6,108,7,170,7,210,47,210,110,170,150,107,150,67,110,67,47,107,7
35 DATA108,8,170,8,209,47,209,110,170,149,107,149,68,110,68,47,107,8,108,9,170,9,208,47,208,110,170,148,107,148,69,110,69,47,107,9
45 N= 1:GOSUB 6:DATA117,17,160,17,160,18,117,18,117,19,160,19
46 N= 1:GOSUB 4:DATA159,20,118,20,118,21,159,21
47 N=15:GOSUB 2:DATA120,22,157,22,167,21,179,33,179,34,166,21,166,22,178,34,178,35,166,23,165,23,177,35,177,36,165,24,165,25,176,36
55 DATA184,38,196,50,196,51,183,38,183,39,195,51,194,51,182,39,182,40,194,52,193,52,181,40,181,41,192,52
60 GOSUB 10:DATA200,57,200,100,199,100,199,57,198,57,198,100,197,99,197,58,196,58,196,99
61 N= 8:GOSUB 2:DATA195,97,195,60
65 DATA197,107,167,137,166,137,197,106,196,106,166,136,166,135,195,106,195,105,165,135,165,134,194,105,193,105,165,133
70 GOSUB 10:DATA159,140,141,140,141,139,159,139,159,138,141,138,141,137,158,137,158,136,141,136
71 N= 1:GOSUB 2:DATA141,135,156,135
75 GOSUB 10:DATA135,140,117,140,117,139,135,139,135,138,117,138,118,137,135,137,135,136,118,136
76 N=15:GOSUB 2:DATA120,135,135,135
80 DATA109,136,97,124,97,123,110,136,110,135,98,123,98,122,110,134,111,134,99,122,99,121,111,133,111,132,100,121
85 DATA92,119,80,107,80,106,93,119,93,118,81,106,82,106,94,118,94,117,82,105,83,105,95,117,95,116,84,105
90 N= 1:GOSUB 6:DATA77,100,77,57,78,57,78,100,79,100,79,57
91 N= 1:GOSUB 4:DATA80,58,80,99,81,99,81,58
92 N=15:GOSUB 2:DATA82,60,82,97,81,50,93,38,94,38,81,51,82,51,94,39,95,39,83,51,83,52,95,40,96,40,84,52,85,52,96,41
100 DATA98,33,110,21,111,21,98,34,99,34,111,22,111,23,99,35,100,35,112,23,112,24,100,36,101,36,112,25
105 GOSUB 12:DATA121,26,135,26,135,27,121,27,122,28,135,28,135,29,122,29,123,30,135,30,135,31,123,31
110 GOSUB 12:DATA141,26,156,26,156,27,141,27,141,28,155,28,155,29,141,29,141,30,154,30,154,31,141,31
115 GOSUB 14:DATA164,30,174,40,174,41,163,30,163,31,173,41,173,42,163,32,162,32,172,42,172,43,162,33,162,34,171,43
120 GOSUB 14:DATA178,44,187,53,187,54,177,44,177,45,186,54,185,54,176,45,176,46,185,55,184,55,175,46,175,47,183,55
125 N= 3:GOSUB 4:DATA191,61,191,96,190,96,190,61,189,62,189,95,188,95,188,62,187,63,187,94,186,94,186,63
130 N= 7:GOSUB 2:DATA187,104,163,128,162,128,187,103,186,103,162,127,162,126,185,103,185,102,161,126,161,125,184,102,183,102,161,124
135 N= 3:GOSUB 4:DATA156,131,121,131,121,130,156,130,155,129,122,129,122,128,155,128,154,127,123,127,123,126,154,126
140 N=14:GOSUB 2:DATA113,127,103,117,103,116,114,127,114,126,104,116,104,115,114,125,115,125,105,115,105,114,115,124,115,123,106,114
145 DATA99,113,90,104,90,103,100,113,100,112,91,103,92,103,101,112,101,111,92,102,93,102,102,111,102,110,94,102
150 N= 3:GOSUB 4:DATA86,96,86,82,87,82,87,96,88,95,88,82,89,82,89,95,90,94,90,82,91,82,91,94
155 GOSUB 12:DATA86,76,86,61,87,61,87,76,88,76,88,62,89,62,89,76,90,76,90,63,91,63,91,76
160 N= 7:GOSUB 2:DATA89,54,113,30,114,30,89,55,90,55,114,31,114,32,91,55,91,56,115,32,115,33,92,56,93,56,115,34
165 N= 3:GOSUB 4:DATA125,34,152,34,152,35,125,35,126,36,151,36,151,37,126,37,127,38,150,38,150,39,127,39
170 N=14:GOSUB 2:DATA160,38,168,46,168,47,160,39,160,40,167,47,167,48,159,40,159,41,166,48,166,49,159,42,159,43,165,49
175 DATA172,50,179,57,178,57,171,50,171,51,177,57,177,58,170,51,170,52,176,58,175,58,169,52,169,53,174,58
180 N= 3:GOSUB 4:DATA183,65,183,76,182,76,182,65,181,66,181,76,180,76,180,66,179,67,179,76,178,76,178,67
185 GOSUB 12:DATA183,82,183,92,182,92,182,82,181,82,181,91,180,91,180,82,179,82,179,90,178,90,178,82
190 N= 7:GOSUB 2:DATA179,100,160,119,160,118,178,100,177,100,160,117,159,117,177,99,176,99,159,116,159,115,175,99,174,99,159,114
195 N= 3:GOSUB 4:DATA152,123,141,123,141,122,152,122,151,121,141,121,141,120,151,120,150,119,141,119,141,118,150,118
200 GOSUB 12:DATA135,123,125,123,125,122,135,122,135,121,126,121,126,120,135,120,135,119,127,119,127,118,135,118
205 N= 7:GOSUB 2:DATA117,119,98,100,99,100,117,118,117,117,100,100,100,99,118,117,118,116,101,99,102,99,118,115,118,114,103,99
210 N= 3:GOSUB 4:DATA94,92,94,82,95,82,95,92,96,91,96,82,97,82,97,91,98,90,98,82,99,82,99,90
215 GOSUB 12:DATA94,76,94,65,95,65,95,76,96,76,96,66,97,66,97,76,98,76,98,67,99,67,99,76
220 N= 7:GOSUB 2:DATA97,58,116,39,116,40,98,58,99,58,116,41,117,41,99,59,100,59,117,42,117,43,101,59,102,59,117,44
230 Z=46:N=28:GOSUB 15:FOR K=1 TO 9:READ M:GOSUB 16:NEXT:N=29:GOSUB 15
240 DATA135,143,130,148,127,151,125,153,124,155,122,156,120,158,119,160,118,160,117,161,116,162,115,163,114,164,114,164,113,165,112,166,112,166,111,167,111,167,110,168,109,168,109,169,109,169,109,169,108,170,108,170,108,170,107,170
250 DATA 6,107,112,119,122,124,127,129,133,136,140,146,171
260 DATA 9,107,111,121,121,125,126,129,132,136,139,148,149,159,162,151,156,165,171
270 DATA11,107,111,115,117,121,121,125,126,129,132,137,139,142,145,148,149,152,155,159,161,166,171
280 DATA13,107,111,115,118,121,121,125,126,129,131,134,135,138,139,142,144,148,149,153,154,159,160,163,164,166,171
290 DATA 9,107,111,115,118,121,121,129,131,134,135,138,139,147,149,159,160,167,171
300 DATA10,107,111,115,117,121,121,129,130,139,139,146,149,152,152,156,156,159,159,167,171
310 DATA12,107,111,120,121,125,126,129,129,139,139,142,143,148,149,152,153,155,156,159,159,162,165,168,171
320 DATA12,107,111,119,121,125,126,129,129,133,136,139,139,142,144,149,149,152,156,159,159,162,165,169,171
330 DATA12,107,111,117,122,124,127,129,129,132,137,139,139,142,145,149,149,152,156,159,159,161,166,169,171
340DATA107,171,108,170,108,170,108,170,108,170,108,169,109,169,109,169,109,169,110,168,110,168,111,167,112,166,112,166,113,165,114,164,114,164,115,163,116,162,117,162,118,160,119,159,121,157,122,156,124,154,125,153,127,151,131,148,135,143
SAVE LOST.DATA.BAS
Our program now ends at:
PRINT PEEK(176)*256+PEEK(175)
7793
Which just ends before HGR Page 1 and we can safely use the HGR
.
Encoder
After we run it to verify it produces the same output we can trivially convert this into an "encoder". We'll read the raw data and poke the binary numbers into memory starting at HGR page 2.
We'll also need to store a 2-byte header:
M = number of X,Y pairs to HPLOT TO, and
N = number of "lines"
Lastly, we'll mark the end-of-data (First Half) with a double zero sentinel. Then when we draw the circle we'll re-use the header to store the number of segments.
Due to the data-driven nature we only need to make a few small changes to convert it to an encoder:
LOAD LOST.DATA.BAS
0 A=16384:P=A:GOTO 20
1 X=M:Y=N:GOSUB 3:FOR J=1 TO N:READ X,Y:GOSUB 3:FOR I=1 TO M:READ X,Y:GOSUB 3:NEXT:NEXT:RETURN
3 POKE P,X:POKE P+1,Y:P=P+2:PRINT ".";:RETURN
15 GOSUB 3:FOR J=1 TO N:READ X,Y:GOSUB 3:Z=Z+1:NEXT:RETURN
16 GOSUB 3:FOR J=1 TO M:READ X,Y:GOSUB 3:NEXT:Z=Z+1:RETURN
230 X=0:Y=0:GOSUB 3:N=28:Z=46:X=N:Y=Z:GOSUB 15:FOR K=1 TO 9:READ M:X=M:Y=Z:GOSUB 16:NEXT:N=29:X=N:Y=Z:GOSUB 15
350 PRINT CHR$(4)"BSAVE LOST.BIN,A";A;",L";(P-A):PRINT:PRINT "SAVED: LOST.BIN": PRINT "SIZE: ";(P-A)
SAVE LOST.ENCODE.BAS
Decoder
Our decoder becomes extremely trivial since are just replaying back HPLOT commands. The other good news is that we keep the spiral drawing effect! (That was an assumption that was never originally specified in the question.)
NEW
0 A=16384:HGR:HCOLOR=3:GOTO 20
1 X=PEEK(A):Y=PEEK(A+1):A=A+2:RETURN
15 GOSUB 1:N=X:Z=Y:FOR J=1 TO N:GOSUB 1:HPLOT X,Z TO Y,Z:Z=Z+1:NEXT:RETURN
16 GOSUB 1:M=X: FOR J=1 TO M:GOSUB 1:HPLOT X,Z TO Y,Z:NEXT:Z=Z+1:RETURN
20 PRINT CHR$(4)"BLOAD LOST.BIN,A";A
30 GOSUB 1:IF X = 0 THEN 50
40 M=X:N=Y:FOR J=1 TO N:GOSUB 1:HPLOT X,Y:FOR I=1 TO M:GOSUB 1:HPLOT TO X,Y:NEXT:NEXT:GOTO 30
50 GOSUB 15:FOR K=1 TO 9:GOSUB 16:NEXT:GOSUB 15
SAVE LOST.DECODE.BAS
Results
If we SAVE lines 5-220 of the original program as LOST.1.BAS
then under DOS 3.3 we notice it takes a whopping 17 sectors.
Our binary file LOST.BIN
takes 6 sectors while our LOST.DECODE.BAS
takes 2 sectors.
That's a savings of around 100*(17-8)/17 = 52% smaller!
Conclusions
- Do NOT use ASCII to store numeric data. It significantly bloats the data.
- Be mindful of the platform you are developing on.
- Analyze the data. Look at how the data is being used.
- Convert redundant code into data.
NOTE: With AppleWin you can use Shift-Insert
to paste text into the emulator.
HIMEM:8191 first and look if your program still fits. If not,
reboot and go for #3 (HGR version) with enteringPOKE 103,0 : POKE 104,64
before loading/entering above program. that should give you plenty room to continue the way you started. BTW, this is very much the same way as the very first graphical adventure were made on the A2 :))POKE 103,1:POKE 104,64:POKE 16384,0
), then enter/load your program - all without any reboot or reset inbetween. THe later is important, as otherwise the poked values get reset.