A few days back, my 5½ year old son William cut up some paper, drew symbols on them, flipped them over, made a logo, and said "do you want to play 'Bomb Blaster'?" The rules didn't make much sense, and was it basically a game of chance.
However I decided it'd be fun to whip up a computer game based on it, for his amusement. So after dinner the other night, I pondered some rules, fired up an Atari character set editor I had written for myself in BASIC in 1990, and did my best to reproduce his game's symbols.
Then, over the course of that evening, while ignoring a huge pile of laundry, and interrupted to help tend our infant son, I came up with an Atari version of my son's game, written in TurboBASIC XL:

I used "detokenize.pl" to convert the TurboBASIC XL code
to an ATASCII listing. (I should have used BASIC's
"" command, since I had
to manually put back some TBXL-specific code that was missing).
Then I created a little HTML script to convert ATASCII text into HTML, using Unicode characters to represent some of the Atari graphical characters. And here's the code:
|
HTML ATASCII Viewer by Bill Kendrick, 2012-2013 0 REM SAVE "D:BOMBBLST.TBS":RUN
5 DIM COVERED(9),PIECES(9) 10 GRAPHICS 18 15 POKE 712,10:POKE 708,0:POKE 709,200 20 CH=PEEK(106)-16 30 OPEN #1,4,0,"D:BOMBBLST.FNT" 40 BGET #1,CH*256,1024 50 POKE 756,CH 60 ? #6;" ;; BOMB BLASTER ;;" 70 ? #6;" BY BILL KENDRICK" 80 ? #6;"AND WILLIAM KENDRICK" 90 ? #6 100 ? #6;"{3 SPACES}{D}{E}{3 SPACES}*+{4 SPACES}[\" 110 ? #6;"{3 SPACES}{F}{G}{3 SPACES},-{4 SPACES}]^" 120 POKE 710,INT(RND(0)*15)+64 130 IF STRIG(0)=1 AND PEEK(53279)<>6 THEN 120 140 IF STRIG(0)=0 THEN 140 200 ? #6;"{CLEAR}{4 SPACES}BOMB BLASTER" 205 ? #6 206 POKE 712,10 207 FOR A=1 TO 3 210 ? #6;"{5 SPACES}#==#==#==#" 220 ? #6;"{5 SPACES}:??:??:??:" 230 ? #6;"{5 SPACES}:??:??:??:" 235 NEXT A 240 ? #6;"{5 SPACES}#==#==#==#" 250 X=1:Y=1:UNCOVERED=0:MONEY=0:HAPPY=0 260 FOR A=0 TO 8:COVERED(A)=1:PIECES(A)=-1:NEXT A 270 GOSUB 1000 280 POSITION 0,2:? #6;"{D}{E}" 285 POSITION 0,3:? #6;"{F}{G}" 300 POSITION (X*3)+5,(Y*3)+2 305 ? #6;"{C}{DOWN}{DOWN}{C}" 310 POSITION (X*3)+5,(Y*3)+5 315 ? #6;"{C}{DOWN}{DOWN}{C}" 320 FOR Z=3 TO 4:POSITION (X*3)+5,(Y*3)+Z:? #6;"{Z}":POSITION (X*3)+8,(Y*3)+Z:? #6;"{Z}":NEXT Z 350 S=STICK(0):F=STRIG(0) 355 POKE 710,INT(RND(0)*15)+64 360 IF S<>7 AND S<>11 AND S<>13 AND S<>14 AND F=1 THEN 350 400 POSITION (X*3)+5,(Y*3)+2 405 ? #6;"#==#" 410 POSITION (X*3)+5,(Y*3)+5 415 ? #6;"#==#" 420 FOR Z=3 TO 4:POSITION (X*3)+5,(Y*3)+Z:? #6;":":POSITION (X*3)+8,(Y*3)+Z:? #6;":":NEXT Z 500 IF S=7 THEN IF X<2 THEN X=X+1 510 IF S=11 THEN IF X>0 THEN X=X-1 520 IF S=13 THEN IF Y<2 THEN Y=Y+1 530 IF S=14 THEN IF Y>0 THEN Y=Y-1 535 IF STICK(0)<>15 THEN 535 540 IF S<>15 THEN FOR Z=15 TO 0 STEP -1:SOUND 0,100,10,Z:NEXT Z:GOTO 300 550 IF F=1 THEN 300 600 IF COVERED(Y*3+X)=0 THEN FOR Z=15 TO 0 STEP -:SOUND 0,200,12,Z:NEXT Z:GOTO 300 610 COVERED(Y*3+X)=0 620 P=PIECES(Y*3+X) 630 POSITION (X*3)+6,(Y*3)+3:? #6;CHR$(P);CHR$(P+1) 640 POSITION (X*3)+6,(Y*3)+4:? #6;CHR$(P+2);CHR$(P+3) 650 UNCOVERED=UNCOVERED+1 700 IF P=ASC("{D}") THEN GOSUB 2000 710 IF P=ASC("*") AND HAPPY=0 THEN GOSUB 3000 720 IF P=ASC("[") THEN GOSUB 5000 800 IF UNCOVERED=9 THEN GOSUB 10000:GOTO 200 990 POKE 710,INT(RND(0)*15)+64 999 GOTO 300 1000 FOR A=1 TO 5 1010 XX=INT(RND(0)*3):YY=INT(RND(0)*3) 1015 SOUND 0,50+YY*20+XX*10,10,8 1020 IF PIECES(YY*3+XX)<>-1 THEN 1010 1030 PIECES(YY*3+XX)=ASC("{D}"):REM MONEY 1040 NEXT A 1100 FOR A=1 TO 3 1110 XX=INT(RND(0)*3):YY=INT(RND(0)*3) 1115 SOUND 0,50+YY*20+XX*10,10,8 1120 IF PIECES(YY*3+XX)<>-1 THEN 1110 1130 PIECES(YY*3+XX)=ASC("*"):REM BAD 1140 NEXT A 1150 SOUND 0,0,0,0 1200 FOR A=0 TO 8 1210 IF PIECES(A)=-1 THEN PIECES(A)=ASC("["):REM GOOD 1220 NEXT A 1299 RETURN 2000 MONEY=MONEY+1:FOR A=1 TO 3:FOR Z=15 TO 0 STEP -1:SOUND 0,10,10,Z:NEXT Z:NEXT A 2010 POSITION 0,4:? #6;MONEY 2099 RETURN 3000 MONEY=0 3010 FOR A=0 TO 8 3020 IF COVERED(A)=0 AND PIECES(A)=ASC("{D}") THEN GOSUB 4000 3030 NEXT A 3040 POSITION 0,4:? #6;" " 3050 RETURN 4000 YY=INT(A/3):XX=A MOD 3 4010 POSITION (XX*3)+6,(YY*3)+3:? #6;";;" 4020 POSITION (XX*3)+6,(YY*3)+4:? #6;";;" 4030 RETURN 5000 HAPPY=1 5010 POSITION 18,2:? #6;"[\"; 5020 POSITION 18,3:? #6;"]^"; 5030 RETURN 10000 POSITION 1,1:? #6;"G A M E ;; O V E R" 10005 IF STRIG(0)=0 THEN 10005 10010 POKE 710,INT(RND(0)*15)+64 10011 IF MONEY=5:Z=Z-1:ELSE:Z=Z+1:ENDIF 10015 IF Z<0 THEN Z=250 10016 SOUND 0,Z,10,8 10017 SOUND 1,Z+2,10,6 10018 IF MONEY=5 THEN POKE 712,Z 10019 IF Z>250 THEN Z=0 10020 IF STRIG(0)=1 AND PEEK(53279)<>6 THEN 10010 10030 IF STRIG(0)=0 OR PEEK(53279)=6 THEN 10030 10040 SOUND 0,0,0,0:SOUND 1,0,0,0 10099 RETURN |
Set-Up, Title and Main Loop
Subroutines
Note: Only a few TurboBASIC XL commands were used:
|
Here's a screenshot of the font:

Here are the characters I redefined:
# | a + shape, for the grid |
$% | money |
*+ | bad-guy pirate bomb |
: | a | shape, for the grid |
; | an explosion |
= | a – shape, for the grid |
[\ | good-guy bomb |
Note that in "GRAPHICS 2" mode on the Atari, only the
first 64 characters of the character set are available. The second 64
appear as the first 64, but using a different color from the palette.
Inverse-video is not supported, either. The high bit causes another pair
of colors to be used. (e.g., the various colors of the character "!" can
be made with: "!", Ctrl+A, Inverse-"!", and Inverse-Ctrl+A.)
So, for example, the Ctrl+D character (┫)
in "P=ASC("┫")" is checking for a green-colored
"$" character (part of the "$%&'" sequence used to make the large (2x2)
dollar-sign symbol). The inverse-video ";" is the red-flashing one.