PC BASIC Bot 280 char Demos
Background
After doing a lot of demos on the
Applesoft BASIC bot I got to thinking about GW-BASIC and QBasic,
the other two BASIC dialects I spent time coding on in the 90s.
I did some prep work in October 2020 as there wasn't a GW-BASIC bot.
Then in February 2021 Kay Savetz set up the
PC BASIC Bot.
Palette Shift Demo
actual link
simulated link
Despite spending a lot of time coding on GW-BASIC I never really used
any of the advanced features at the time. It is a much more rich and
complex environment than
Applesoft and I am sure there are all kinds of advanced tricks.
This one uses the "MODE 9" 640x350x16 EGA mode (back in the day it
was a revelation when someone told me about this, all of my older BASIC
books only went up to CGA and I didn't know you could program anything
better).
While EGA only supported 16 colors, you could choose from a palette of 64,
which is what this example is doing. This is the first time I've ever
used the "PALETTE USING" and "FIX" functions. It's also so nice
to have a built in "MOD" operator.
Anyway I wanted to have a nice color pallette shifting demo, you can't
do that on the Apple II and the other 8-bit/16-bit architectures won't
let you forget it.
1 DIM A%(16):SCREEN 9
2 FOR I=0 TO 6:READ C:A%(I)=C:NEXT:DATA 32,52,38,46,38,52,32
3 FOR Y=0 TO 350:LINE (0,Y)-(639,Y),FIX((Y MOD 14)/2):NEXT
4 PALETTE USING A%(0)
5 A%(7)=A%(0):FOR I=0 to 7:A%(I)=A%(I+1):NEXT
6 FOR I=0 TO 1000:NEXT:GOTO 4
Machine Language Loader -- Color Bars
actual link
simulated link
The PC BASIC bot would be an interesting venu for loading DOS demos.
DOS demos are a bit crazy, and people do amazing
things in 32-bytes or less. I over-optimistically thought I'd try
with a 128-byte demo as that's what we can load in Applesoft, but it
turns out loading assembly language is really hard in GW-BASIC despite
a lot of support in the language for doing so.
The demo I chose is my 128B
color bar demo that I actually wrote for this purpose.
It's a DOS COM file which allows a lot of assumptions that the expert
demo size coders exploit.
I tried to avoid those as I am sure many don't hold inside of GW-BASIC.
I did have to modify the program to set the DS segment to be the same as CS
(raising the file size to 129 bytes).
The demo targets an 8086 machine with MCGA graphics, sort of like
the IBM PS/2 Model 25 machines they replaced the Apple IIs with
at my high school. The demo uses 320x200x256 Model 13h which
in theory isn't directly supported by GW-BASIC.
Below is the first successful attempt at getting the program to load.
It uses the 6-bit encoding from the Applesoft (and other 6502) BASIC bots.
I thought it would be more compact due to the avaiability of MOD and
AND but not really, those are big, and you can't run things together without
spaces like you can for Applesoft.
Also the machine code is stored in a string. GW-BASIC supports getting
the address of arrays and strings, I'm not sure if I can consistently
get data out of a REM statement like on Applesoft.
Knowing where to put things involves all kinds of x86 knowledge about
segments and the like. I just picked somewhere high up as GW-BASIC
lives in one 64k segment.
0 DIM B%(200),Q(200),D(200)
1 A$="h:J]ph>:m>h:b]jFyhl:hJ:\pvdLWwhp:uC<WxuC<Wxi@:]gU:f;eI:W;IjW:wA\je:KyNZx;Y:yfl\puJef;nruLLntuntuJPrryZu;Xktf<:::::I::;<=U::>BFb::;<==HMFrwJ>fat:G:A^N=:JDFZKOCZLFP]]akSfAs?:A:?s"
2 FOR I=1 TO 132
3 B%(I)=(ASC(MID$(A$,I,1))-58)*4
4 Q(I)=((ASC(MID$(A$,133+(I-2)/3,1))-58))
5 D(I)=(4^((I-1) MOD 3))
6 B%(I)=B%(I)+(INT(Q(I)/D(I)) AND 3)
7 NEXT
35 DEF SEG=&H4000
40 for I=0 to 132:POKE I+256,B%(I+1):NEXT
70 V=256:CALL V
I spent more time than I should have trying to reduce this in
size, and came up with this, which is still too big to fit in
a tweet.
1DEF SEG=100:DEF FNP(X)=ASC(MID$(A$,X))-58:A$="=Ah>:m>h:b]jFyhl:hJ:\pvdLWwhp:uC<WxuC<Wxi@:]gT:f;eI:W;IjW:wA\je:KyNZx;Y:yfl\puJef;nruLLntuntuJPrryZu;Xktf<:::::I::;<=U::>BFb::;<=HMFrwJ>fat:G:A^K=:JDFZKOCZLFP]]akSfAs?:A:?s"
3FOR I=0 TO 128:POKE I,FNP(I+1)*4+(INT(FNP(130+(I-1)/3)/(4^(I MOD 3))) AND 3):NEXT:CALL V
When the bot finally arrived, I worked and got it fitting in a tweet.
I had to reduce the color bars to only two as I could only fit 116 bytes
of executable.
1DEF SEG=256:DEF FNP(X)=ASC(MID$(A$,X))-35:A$="3:a32f4a3MSc0oaa2aB3U^m]<NpSf3n<5Mqn<5Ppb6*T`I2_4^B3P4>bP1p:Rc^+BrCRq/Q3p_eMgn?]_1gkiDE_kn_kn:Gk_oSh3QYk_433%03A3345616/[`3'OJ]#0#*G4-/C48,C5/9FFJT<O*\(#"
2FOR I=0 TO 116:POKE I,4*FNP(I+1)-64+FNP(118+I\3)\4^(I MOD 3):NEXT:CALL V
In the end this didn't work, as for GWBASIC the PC bot uses
PC-BASIC.
So my only hope was QBASIC and I did manage to get it working with
the following code:
DEF FNP(X)=ASC(MID$(A$,X))-35:A$="3:a32f4a3MSc0oaa2aB3U^m]<NpSf3n<5Mqn<5Ppb6*T`I2_4^B3P4>bP1p:Rc^+BrCRq/Q3p_eMgn?]_1gkiDE_kn_kn:Gk_oSh3QYk_433%03A3345616/[`3'OJ]#0#*G4-/C48,C5/9FFJT<O*\(#"
FOR I=0 TO 116:POKE I,4*FNP(I+1)-64+FNP(118+I\3)\4^(I MOD 3):NEXT:CALL ABSOLUTE (V)
Three Colors Bars -- 122 byte Machine Language
link
It took a while but I figured out how to find the address of the
string directly (hint: use SADD not VARPTR).
This allowed fitting another line of colors in
the color bars.
{QB20}
A$="3:a32f4a3MSc0oaa2aB3U^m]<NpSf3n<5Mqn<5Ph`7*T`I2_4^B3P4>bP1p:Rc^+BrCRq/Q3p_eMgn?]_1gkiDE_kn_kn:Gk_oSh3QYk_433%03A33456M337;?16/[`3'OJ]#0#JG4-/C48,C5/9FFJT<O*\(#*#"
V=SADD(A$)
FOR I=0 TO 122
POKE I,4*PEEK(V+I)-204+(PEEK(V+123+I\3)-35)\4^(I MOD 3)
NEXT
CALL ABSOLUTE(Q)
Rickroll Animation -- Pure Basic
link
I thought I was done, but then Foone was trying to get a Rickroll going,
and I knew this would be the perfect thing for my box drawing library
for the AppleIIbot and one thing led to another...
I originally used PEEK but Foone's idea to use MID$ ended up being a lot
more robust and smaller in the end.
{Q}
A$="p ~ ~7GYG~31FG\3U^Ge2/BP\27Zf~2U[Ue`FM:FwJS/A&GU).&AI,;8RTO~8OUCMwSU8;1+F]k`GP\ep_j\p1[ifq`itipp^wft1^gfq`_f\e"
DEF FNP(X)=ASC(MID$(A$,I*5+X))
SCREEN 13
FOR I=0 TO 21
LINE (FNP(2),FNP(4))-(FNP(3),FNP(5)),FNP(1)-32,BF
IF I=18 OR I=21 THEN SLEEP 1
IF I=21 THEN I=15
NEXT
One Program / Two Bots -- Applesoft and GW-Basic
link
I was wondering how hard it would be to make a program that would run
under both Applesoft and GW-Basic. Turns out to not be too bad.
The fact both are by Microsoft helped.
The PEEK used to check which machine we're on is the official Apple II
machine-detection code which is 6 on IIe machines like the bot.
Luckily GW-BASIC doesn't try to parse code you don't reach. QBasic
does so this won't run there.
0 A$="'2aBW'271A'8?8A&.1DU&RaBS&bkHW$2ORS% -FS"
1 DEF FNP(X)=ASC(MID$(A$,I*5+X))
2 IF PEEK(64435)=6 THEN 9
5 SCREEN 7:FOR I=0 TO 7:LINE (FNP(2),FNP(4))-(FNP(3),FNP(5)),FNP(1)-32,BF:NEXT
7 END
9 HGR:FORI=0TO7:HCOLOR=FNP(1)-32:FORY=FNP(4)TOFNP(5):HPLOTFNP(2),YTOFNP(3),Y:NEXTY,I
The first attempt the colors on the PC version didn't match.
The HGR colors 4 5 6 7 almost match CGA colors 0 2 1 3 so if we could
only somehow efficiently swap to get those... I did manage in the
end but it's really ugly. I also changed the machine detection to
PEEK(0) which on Applesoft is a JMP instruction ($4C / 76).
0 A$="'2aBW'271A'8?8A&.1DU&RaBS&bkHW$2ORS% -FS":DEF FNP(X)=ASC(MID$(A$,I*5+X))
2 IF PEEK(0)=76 THEN HGR:FORI=0TO7:HCOLOR=FNP(1)-32:FORY=FNP(4)TOFNP(5):HPLOTFNP(2),YTOFNP(3),Y:NEXTY,I:END
5 SCREEN 1:FOR I=0 TO 7:LINE (FNP(2),FNP(4))-(FNP(3),FNP(5)),3 AND(216\4^(FNP(1)-36)),BF:NEXT
Frequent Questions
- Q. You posted a bunch of PC-BOT demos. Why aren't
they described here like your Applesoft Demos?
A. I spent a lot of time in the early 90s on GWBASIC/QBASIC on DOS
and so many of the programs I posted were from that era.
You'll note they weren't particularly interesting or good.
I find DOS/GWBASIC to be almost too powerful and
simultaenously too much of and too little of a challenge.
I might change my mind at some point but for now I won't
be writing many new programs for the platform.
Code/Tool Availability
The code and utilities I used to make these can be found on github:
https://github.com/deater/dos_programs.git
Back to my Demos Page
See my AppleIIbot programs