XL/XE systems with >16K
by Eric Petrich
[Archiver's Note: This article did not appear in any issue of ANALOG. It seemed appropriate, however, to include it here.]
Kyle Peacock's Bacterion! made my list of top games once my friend Robert and I managed to type it in correctly. We were astonished at what we got for our money that month.
There was, however, a problem: We found that the program crashed on us at odd intervals. When you're running off a cassette tape, that's very aggravating. More aggravating still, it happened on Robert's 800XL, but it did not happen on another friend's 400. Some months later, ANALOG admitted that yes, there was an incompatibility with XL machines.
So matters remained for seventeen years. With newer systems, however, came new possibilities. Emulation tools made it possible to determine why the program was crashing, and pointed the way to a fix. I am pleased to present Bacterion! Patch, which will stabilize the program for XL/XE users with more than 16K of RAM. (It will not, unfortunately, work for systems with only 16K. I'll explain why later.)
Listing 1 is a patch program in Atari BASIC. It will convert a Bacterion! executable into a more stable version. Enter the program and save it to disk, then run it and follow the prompts.
The program makes some simple checks to avoid patching the wrong file, but it's possible that another file might slip through. Don't try to patch any other executable; it won't work, and may corrupt the program.
Nothing for which I can blame anyone, least of all Kyle Peacock. He had to arrange his memory use so that Bacterion! would run in 16K. To do this, he used a region of memory later reserved by the XL OS.
What region? The region starting at memory location 0. The assembly listing contains the following line:
PLAYBS EQU $0000
With this line, Bacterion!'s player/missile data reside in the lowest 2K of memory. This region contains a lot of important stuff, including the 6502 stack and many of Bacterion!'s own registers! But the vagaries of P/M memory leave those regions untouched.
Unfortunately, locations $0300-$03FF do not remain pristine. And therein lies the rub: The XL OS uses several of these locations for its own purposes. The primary problem comes from location $03FA, called GINTLK on some memory maps.
The OS shadows TRIG3($D013) into GINTLK. On XL and XE systems, TRIG3 indicates if the system has a cartridge inserted. If the OS discovers a mismatch between TRIG3 and GINTLK, it locks up the system. (Specifically, it enters an infinite loop at location $C0DF.)
The patch changes Bacterion! so it starts its P/M graphics data at location $4000. If you wanted to change the assembly source, you could change the line discussed earlier to read:
PLAYBS EQU $4000
Location $4000 marks the second 16K block of RAM. And that is why the patch won't work for machines with 16K; the memory doesn't exist.
The patch program works from a table to find the instructions which reference the P/M graphics data. It then alters them to use region $4000-$47FF instead of $0000-$07FF.
I owe a great debt to the folks who created and maintain the Atari800 emulator. Without it, I wouldn't have been able to trace Bacterion!'s operation. And to Kyle Peacock: You kept me up many late nights entering your programs, and I'd do it all over again. (Come to think of it, I have been doing it all over again....)
BACPATCH.LST is available in ATASCII format.
10 REM BACTERION! XL PATCH PROGRAM 20 REM BY ERIC PETRICH 30 REM 40 REM PATCHES BACTERION! EXECUTABLE 50 REM SO IT WILL RUN CORRECTLY ON 60 REM XL/XE MACHINES WITH >16K RAM. 70 REM 80 DIM FN$(15),YN$(5) 100 ? "FILE TO PATCH";:INPUT FN$ 110 ? "PASS 1: VERIFYING...":PASS=1 120 TRAP 270 130 OPEN #1,12,0,FN$ 140 RESTORE 1000 150 OFFSET=0 160 TRAP 280 170 READ TARG,SB,DB:IF TARG=-1 THEN 23 0 180 IF OFFSET<>TARG THEN GET #1,D:OFFS ET=OFFSET+1:GOTO 180 190 IF PASS=2 THEN PUT #1,DB:GOTO 220 200 GET #1,D:IF D<>SB THEN 280 210 ? "OFFSET ";OFFSET;" = ";D 220 OFFSET=OFFSET+1:GOTO 170 230 CLOSE #1 240 IF PASS=2 THEN ? "PATCH COMPLETE": END 250 ? "VERIFIED. PRESS RETURN TO PATCH ";:INPUT YN$ 260 ? "PASS 2: PATCHING...":PASS=2:GOT O 130 270 ? "UNABLE TO OPEN ";FN$:END 280 ? "OFFSET ";OFFSET;" = ";D;", SHOU LD BE ";SB 290 ? "VERIFY FAILED. NO PATCH.":CLOSE #1:END 1000 DATA 145,0,64 1010 DATA 164,4,68 1020 DATA 167,5,69 1030 DATA 467,3,67 1040 DATA 470,6,70 1050 DATA 473,7,71 1060 DATA 3189,4,68 1070 DATA 3191,5,69 1080 DATA 3193,6,70 1090 DATA 3195,7,71 1100 DATA 3197,3,67 1110 DATA -1,0,0