mirror of
https://github.com/deater/dos33fsprogs.git
synced 2025-01-14 13:33:48 +00:00
Merge branch 'master' of https://github.com/deater/dos33fsprogs
This commit is contained in:
commit
f43650e1ef
@ -16,13 +16,16 @@
|
|||||||
While making an inside-joke filled game for my retro system of choice,
|
While making an inside-joke filled game for my retro system of choice,
|
||||||
the Apple II, I needed to create a Final-Fantasy-esque
|
the Apple II, I needed to create a Final-Fantasy-esque
|
||||||
flying-over-the-planet sequence.
|
flying-over-the-planet sequence.
|
||||||
I was originally going to fake this, but then I found that it was just barely
|
I was originally going to fake this, but why fake graphics when you
|
||||||
possible to achieve this in real time.
|
can laboriously spend weeks implementing the effect for real.
|
||||||
|
It turns out the Apple II is just barely capable of generating
|
||||||
|
the effect in real time.
|
||||||
|
|
||||||
Once I got the code working I realized it would be great as part of a
|
Once I got the code working I realized it would be great as part of a
|
||||||
graphics demo, so off on that tangent I went.
|
graphical demo, so off on that tangent I went.
|
||||||
This went well, despite the fact that all I know about the demoscene I learned
|
This turned out well, despite the fact that all I knew about the demoscene I
|
||||||
from a few viewings of the Future Crew {\em Second Reality} demo mixed with
|
had learned from a few viewings of the Future Crew {\em Second Reality} demo
|
||||||
dimly remembered Commodore 64 and Amiga flamewars.
|
combined with dimly remembered Commodore 64 and Amiga usenet flamewars.
|
||||||
|
|
||||||
% from a few decades ago.
|
% from a few decades ago.
|
||||||
% This started out as some SNES style mode7 pseudo-3d graphics code
|
% This started out as some SNES style mode7 pseudo-3d graphics code
|
||||||
@ -33,12 +36,13 @@ dimly remembered Commodore 64 and Amiga flamewars.
|
|||||||
%lot of time was wasted fitting it under that arbitrary size limitation.
|
%lot of time was wasted fitting it under that arbitrary size limitation.
|
||||||
|
|
||||||
While I hope you enjoy the description of the demo and the work that
|
While I hope you enjoy the description of the demo and the work that
|
||||||
went into it, I do suspect the whole enterprise is only of note
|
went into it, I suspect this whole enterprise is primarily of note
|
||||||
because so few people write demos for the Apple II platform.
|
due to the dearth of demos for the Apple II platform.
|
||||||
%So in the end this ends up being impressive mostly because so few people
|
%So in the end this ends up being impressive mostly because so few people
|
||||||
%have bothered to write demos for this particular platform.
|
%have bothered to write demos for this particular platform.
|
||||||
I would like to make a shout out to the FrenchTouch group whose Apple II
|
If you are truly interested in seeing impressive Apple II demos,
|
||||||
demos put this one to shame.
|
I would like to make a shout out to FrenchTouch whose works
|
||||||
|
put this one to shame.
|
||||||
|
|
||||||
% The codesize ended up being roughly around 8kB, so I thought I'd
|
% The codesize ended up being roughly around 8kB, so I thought I'd
|
||||||
% make it into an 8k demo. There aren't many out there for the Apple II.
|
% make it into an 8k demo. There aren't many out there for the Apple II.
|
||||||
@ -90,11 +94,13 @@ demos put this one to shame.
|
|||||||
\section{The Hardware}
|
\section{The Hardware}
|
||||||
|
|
||||||
The Apple II was introduced in 1977.
|
The Apple II was introduced in 1977.
|
||||||
This demo should run on an original system, though I do not
|
In theory this demo will run on hardware that old, although I do
|
||||||
have hardware quite that old to test on.
|
not have access to a system of that vintage.
|
||||||
I like to troll C64 fans by noting this predates the Commodore 64 by
|
I like to troll Commodore fans by noting this predates the Commodore 64 by
|
||||||
five years.
|
five years.
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
\vspace{1ex}
|
\vspace{1ex}
|
||||||
\noindent
|
\noindent
|
||||||
{\bf CPU, RAM and Storage:}
|
{\bf CPU, RAM and Storage:}
|
||||||
@ -147,28 +153,29 @@ Hardware page flip & Yes \\
|
|||||||
\end{tabular}
|
\end{tabular}
|
||||||
\end{center}
|
\end{center}
|
||||||
|
|
||||||
The hi-res graphics mode was a complex mess of NTSC hacks by Woz.
|
The hi-res graphics mode is a complex mess of NTSC hacks by Woz.
|
||||||
You got approximately 280x192 resolution, with 6 colors available.
|
You get approximately 280x192 resolution, with 6 colors available.
|
||||||
However the colors were from NTSC artifacts and there were limitations
|
The colors are NTSC artifacts with limitations
|
||||||
on which colors could be next to each other (in blocks of 3.5 pixels).
|
on which colors can be next to each other (in blocks of 3.5 pixels).
|
||||||
There was plenty of fringing on edges, and colors changed depending on
|
There is plenty of fringing on edges, and colors change depending on
|
||||||
whether they were drawn at odd or even pixels.
|
whether they are drawn at odd or even locations.
|
||||||
To add to the madness, the framebuffer is interleaved in a complex way,
|
To add to the madness, the framebuffer is interleaved in a complex way,
|
||||||
and pixels are drawn least-significant-bit first (all of this to make
|
and pixels are drawn least-significant-bit first (all of this to make
|
||||||
DRAM refresh better and to shave a few 7400 series logic chips from the design).
|
DRAM refresh better and to shave a few 7400 series logic chips from the design).
|
||||||
You do get two pages of graphics, Page 1 is at
|
You do get two pages of graphics, Page 1 is at
|
||||||
\$2000\footnote{On 6502 systems hexadecimal values are
|
{\tt \$2000}\footnote{On 6502 systems hexadecimal values are
|
||||||
indicated by the dollar sign}
|
traditionally indicated by a dollar sign}
|
||||||
and Page 2 at \$4000.
|
and Page 2 at {\tt \$4000}.
|
||||||
Optionally 4 lines of text can be shown at the bottom of the
|
Optionally 4 lines of text can be shown at the bottom of the
|
||||||
screen instead of graphics.
|
screen instead of graphics.
|
||||||
|
|
||||||
The lo-res mode is a bit easier to use.
|
The lo-res mode is a bit easier to use.
|
||||||
It provides 40x48 blocks (40x40 if the four
|
It provides 40x48 blocks, reusing the same memory as the 40x24 text mode.
|
||||||
lines of text are displayed at the bottom).
|
(As with hi-res you can switch to a 40x40 mode with four lines of
|
||||||
|
text displayed at the bottom).
|
||||||
Fifteen colors are available (there are two greys which are indistinguishable).
|
Fifteen colors are available (there are two greys which are indistinguishable).
|
||||||
Again the addresses are interleaved. Lo-res Page 1 is at \$400
|
Again the addresses are interleaved in a non-linear fashion.
|
||||||
and Page 2 is at \$800.
|
Lo-res Page 1 is at {\tt \$400} and Page 2 is at {\tt \$800}.
|
||||||
|
|
||||||
Some amazing effects can be achieved by cycle counting, reading
|
Some amazing effects can be achieved by cycle counting, reading
|
||||||
the floating bus, and racing the beam while toggling graphics
|
the floating bus, and racing the beam while toggling graphics
|
||||||
@ -191,10 +198,11 @@ I do all of my coding under Linux, using the nano text editor.
|
|||||||
I use the ca65 assembler from the cc65 project, which I find to be a reasonable
|
I use the ca65 assembler from the cc65 project, which I find to be a reasonable
|
||||||
tool although many ``real'' Apple II programmers look down on it for some
|
tool although many ``real'' Apple II programmers look down on it for some
|
||||||
reason.
|
reason.
|
||||||
I cross-compile the code, construct Apple DOS3.3 disk images using
|
I cross-compile the code, constructing Apple DOS3.3 disk images using
|
||||||
custom tools I have written, and then do most testing in an emulator.
|
custom tools I have written.
|
||||||
|
I test using emulators:
|
||||||
AppleWin (run under the wine emulator) is the easiest to use, but
|
AppleWin (run under the wine emulator) is the easiest to use, but
|
||||||
MESS/MAME has cleaner sound.
|
until recently MESS/MAME had cleaner sound.
|
||||||
|
|
||||||
Once the code appears to work, I put it on a USB stick and transfer
|
Once the code appears to work, I put it on a USB stick and transfer
|
||||||
to actual hardware using a CFFA3000 disk emulator installed in
|
to actual hardware using a CFFA3000 disk emulator installed in
|
||||||
@ -260,67 +268,73 @@ well-traveled guinea pig.
|
|||||||
|
|
||||||
An Applesoft BASIC ``HELLO'' program loads the binary automatically at bootup.
|
An Applesoft BASIC ``HELLO'' program loads the binary automatically at bootup.
|
||||||
This does not count towards the executable size, as you could manually BRUN
|
This does not count towards the executable size, as you could manually BRUN
|
||||||
the 8k program if you wanted.
|
the 8k machine-language program if you wanted.
|
||||||
|
|
||||||
To make the loading time slightly more interesting the binary is loaded at
|
To make the loading time slightly more interesting the HELLO program enables
|
||||||
address \$2000 (hi-res page1) and BASIC is nice enough to enable
|
graphics mode and loads the program to address {\tt \$2000} (hi-res page1).
|
||||||
graphics mode first so you can watch the display get filled with the random
|
This causes the display to filled with the colorful pattern corresponding
|
||||||
pattern of the compressed image.
|
to the compressed image.
|
||||||
This entirely fills the 8k of the display, or would
|
This conveniently fills all 8k of the display RAM, or would have
|
||||||
if we POKEd the right address to turn off
|
if we had POKEd the right soft-switch to turn off
|
||||||
the 4 lines of text on the bottom of the screen.
|
the bottom 4 lines of text.
|
||||||
|
|
||||||
Upon loading, execution starts at address \$2000
|
Upon loading, execution starts at address {\tt \$2000}.
|
||||||
|
|
||||||
\subsection{DECOMPRESSER}
|
\subsection{DECOMPRESSION}
|
||||||
|
|
||||||
The binary is encoded with the LZ4 algorithm.
|
The binary is encoded with the LZ4 algorithm.
|
||||||
We flip to hi-res Page 2 and decompress there so the user continues to get
|
We flip to hi-res Page 2 and decompress to this region so the display
|
||||||
a show of random noise.
|
now shows the executable code.
|
||||||
|
|
||||||
The 6502 size-optimized LZ4 decompression code was written by qkumba
|
The 6502 size-optimized LZ4 decompression code was written by qkumba
|
||||||
(Peter Ferrie).
|
(Peter Ferrie).
|
||||||
% http://pferrie.host22.com/misc/appleii.htm
|
% http://pferrie.host22.com/misc/appleii.htm
|
||||||
The program and data decompress to around 22k starting at \$4000.
|
The program and data decompress to around 22k starting at {\tt \$4000}.
|
||||||
It over-writes parts of DOS3.3, but since we will not be using the disk
|
This over-writes parts of DOS3.3, but since we are done with the disk
|
||||||
any more this is not an issue.
|
this is not an issue.
|
||||||
|
|
||||||
If you look carefully at the upper left corner of the screen during
|
If you look carefully at the upper left corner of the screen during
|
||||||
decompress you will see my triangular logo, which is supposed to evoke
|
decompress you will see my triangular logo, which is supposed to evoke
|
||||||
my VMW initials (see Figure~\ref{fig:vmw}).
|
my VMW initials (see Figure~\ref{fig:vmw}).
|
||||||
To do this I had to put the proper bit pattern at the interleaved
|
To do this I had to put the proper bit pattern inside the code
|
||||||
addresses of \$4000, \$4400, \$4800, and \$4C00.
|
at the interleaved addresses of {\tt \$4000}, {\tt \$4400}, {\tt \$4800},
|
||||||
This turned out to be way more trouble than it was worth.
|
and {\tt \$4C00}.
|
||||||
As an interesting note, the image data at \$4000 is executed as it maps
|
The image data at {\tt \$4000} maps to (mostly)
|
||||||
to (mostly) harmless code.
|
harmless code so it is left in place and executed.
|
||||||
|
Making this work turned out to be more trouble than it was worth, especially
|
||||||
|
as the logo is not visible in the youtube capture of the demo (the movie
|
||||||
|
compression does not handle screens full of seemingly random noise well).
|
||||||
|
|
||||||
The demo was optimized to fit in 8k, and this is difficult when your program
|
The demo was optimized to fit in 8k.
|
||||||
is compressed.
|
Optimizing code inside of a compressed image is much more complicated than
|
||||||
|
regular size optimization.
|
||||||
Removing instructions sometimes makes the binary {\em larger} as it no longer
|
Removing instructions sometimes makes the binary {\em larger} as it no longer
|
||||||
compresses as well.
|
compresses as well.
|
||||||
Long runs of values (such as 0 padding) are essentially free.
|
Long runs of values (such as 0 padding) are essentially free.
|
||||||
This mostly turned into an exercise of guess-and-check until everything fit.
|
This mostly turned into an exercise of guess-and-check until everything fit.
|
||||||
|
|
||||||
\subsection{FADE EFFECT}
|
|
||||||
|
|
||||||
|
\subsection{TITLE SCREEN}
|
||||||
|
|
||||||
|
Once decompression is done, execution continues at address {\tt \$4000}.
|
||||||
|
We switch to low-res mode for the rest of the demo.
|
||||||
|
|
||||||
|
\noindent
|
||||||
|
{\bf FADE EFFECT}:
|
||||||
The title screen fades in from black.
|
The title screen fades in from black.
|
||||||
|
|
||||||
This is a software hack as the Apple II does not have palette support.
|
This is a software hack as the Apple II does not have palette support.
|
||||||
The image is loaded to an off-screen buffer and a lookup table is used to
|
The image is loaded to an off-screen buffer and a lookup table is used to
|
||||||
copy in the faded versions on the fly.
|
copy in the faded versions on the fly.
|
||||||
|
|
||||||
\subsection{TITLE SCREEN}
|
\noindent
|
||||||
|
{\bf TITLE GRAPHICS}:
|
||||||
|
The title screen is shown in Figure~\ref{fig:title}.
|
||||||
Once decompression is done, execution continues at address \$4000.
|
|
||||||
We switch to low-res mode for the rest of the demo.
|
|
||||||
|
|
||||||
A title screen is loaded, as seen in Figure~\ref{fig:title}.
|
|
||||||
The image is run-length encoded (RLE) which is
|
The image is run-length encoded (RLE) which is
|
||||||
probably unnecessary when being further LZ4 encoded.
|
probably unnecessary in light of it being further LZ4 encoded.
|
||||||
(The LZ4 compression was a late addition to this endeavor).
|
(The LZ4 compression was a late addition to this endeavor).
|
||||||
|
|
||||||
Why not save some space and just load our demo at \$400 and negate the need
|
Why not save some space and just load our demo at {\tt \$400} and negate
|
||||||
|
the need
|
||||||
to copy the image in place?
|
to copy the image in place?
|
||||||
Remember the graphics are 40x48 (shared with the text display region).
|
Remember the graphics are 40x48 (shared with the text display region).
|
||||||
It might be easier to think of it as 40x24 characters, with the top / bottom
|
It might be easier to think of it as 40x24 characters, with the top / bottom
|
||||||
@ -332,8 +346,10 @@ There are ``holes'' in the address range that are not displayed, and
|
|||||||
various pieces of hardware can use these as scratchpad memory.
|
various pieces of hardware can use these as scratchpad memory.
|
||||||
This means just overwriting the whole 1k with data might not work out well
|
This means just overwriting the whole 1k with data might not work out well
|
||||||
unless you know what you are doing.
|
unless you know what you are doing.
|
||||||
To this end the RLE decompression code skips the holes just to be safe.
|
To this end our RLE decompression code skips the holes just to be safe.
|
||||||
|
|
||||||
|
\noindent
|
||||||
|
{\bf SCROLL TEXT}:
|
||||||
The title screen has scrolling text at the bottom.
|
The title screen has scrolling text at the bottom.
|
||||||
This is nothing fancy, the text is in a buffer off screen and a 40x4
|
This is nothing fancy, the text is in a buffer off screen and a 40x4
|
||||||
chunk of RAM is copied in every so many cycles.
|
chunk of RAM is copied in every so many cycles.
|
||||||
@ -347,20 +363,23 @@ movie encoding conspire to make this look worse than things look in person.
|
|||||||
\subsection{MOCKINGBOARD MUSIC}
|
\subsection{MOCKINGBOARD MUSIC}
|
||||||
|
|
||||||
No demo is complete without some exciting background music.
|
No demo is complete without some exciting background music.
|
||||||
I like chiptune music, especially the kind you can find that is made
|
I like chiptune music, especially the kind written
|
||||||
for AY-3-8910 based systems.
|
for AY-3-8910 based systems.
|
||||||
I gained some expertise during the long wait for my Mockingboard to arrive
|
During the long time waiting for my Mockingboard hardware to arrive
|
||||||
by building a Raspberry Pi chiptune player that is essentially the same
|
I designed and built a Raspberry Pi chiptune player that uses
|
||||||
hardware.
|
essentially the same hardware.
|
||||||
|
This allowed me to build up some expertise with the software/hardware
|
||||||
|
interface in advance.
|
||||||
|
|
||||||
The song being played is a stripped down and re-arranged version of
|
The song being played is a stripped down and re-arranged version of
|
||||||
``Electric Wave'' from CC'00 by EA (Ilya Abrosimov).
|
``Electric Wave'' from CC'00 by EA (Ilya Abrosimov).
|
||||||
|
|
||||||
Most of my sound infrastructure involves YM5 files, a format commonly
|
Most of my sound infrastructure involves YM5 files, a format commonly
|
||||||
used by ZX Spectrum and ATARI ST users.
|
used by ZX Spectrum and Atari ST users.
|
||||||
These are essentially just AY-3-8910 register dumps taken at 50Hz.
|
The YM file format is just AY-3-8910 register dumps taken at 50Hz.
|
||||||
To play these back just set up the sound card to interrupt 50 times a second
|
To play these back one sets up the sound card to interrupt 50 times a second
|
||||||
and then write out the 14 register values from that frame.
|
and then writes out the 14 register values from each frame in an interrupt
|
||||||
|
handler.
|
||||||
|
|
||||||
% To program the Mockingboard, each AY-3-8910 chip has 14 sound related
|
% To program the Mockingboard, each AY-3-8910 chip has 14 sound related
|
||||||
% registers that control the 3 channels. Each AY chip has a dedicated
|
% registers that control the 3 channels. Each AY chip has a dedicated
|
||||||
@ -381,7 +400,7 @@ and only write to the registers that have changed.
|
|||||||
% I have a whole suite of code for manipulating YM sound data, in my
|
% I have a whole suite of code for manipulating YM sound data, in my
|
||||||
% vmw-meter git repository.
|
% vmw-meter git repository.
|
||||||
|
|
||||||
Our code detects a Mockingboard at startup, we are lazy and only support
|
Our code detects the Mockingboard at startup; we are lazy and only support
|
||||||
finding the card in Slot 4 (which is a fairly typically location).
|
finding the card in Slot 4 (which is a fairly typically location).
|
||||||
% The first step for getting this to work is detecting if a Mockingboard is
|
% The first step for getting this to work is detecting if a Mockingboard is
|
||||||
%% there. This can be in any slot 1-7 on the Apple II, though typically
|
%% there. This can be in any slot 1-7 on the Apple II, though typically
|
||||||
@ -391,9 +410,9 @@ interrupt at 25Hz.
|
|||||||
% (it has to be an on-board timer as the default
|
% (it has to be an on-board timer as the default
|
||||||
% Apple II has no timers).
|
% Apple II has no timers).
|
||||||
Why 25Hz and not 50Hz? At 50Hz with 14 registers you use 700 bytes/s.
|
Why 25Hz and not 50Hz? At 50Hz with 14 registers you use 700 bytes/s.
|
||||||
So a 2 minute song would take 84k of RAM, much more than is available.
|
So a 2 minute song would take 84k of RAM, which is much more than is available.
|
||||||
To allow the song to fit in memory (without the fancy circular buffer
|
To allow the song to fit in memory (without a fancy circular buffer
|
||||||
decompression utilized in my VMW Chiptune Player music-disk demo) we have
|
decompression routine utilized in my VMW Chiptune music-disk demo) we have
|
||||||
to reduce the size.
|
to reduce the size.
|
||||||
First the music is changed so it only needs to be updated at 25Hz.
|
First the music is changed so it only needs to be updated at 25Hz.
|
||||||
Then the register data is compressed from 14 bytes to 11 bytes by stripping off
|
Then the register data is compressed from 14 bytes to 11 bytes by stripping off
|
||||||
@ -404,10 +423,10 @@ acceptably catchy chiptune inside of our 8k payload.
|
|||||||
\subsection{MODE7 BACKGROUND}
|
\subsection{MODE7 BACKGROUND}
|
||||||
|
|
||||||
``Mode7'' is a Super Nintendo (SNES) graphics mode that takes a tiled
|
``Mode7'' is a Super Nintendo (SNES) graphics mode that takes a tiled
|
||||||
background to be transformed by rotation and scaling.
|
background and transforms it by rotating and scaling.
|
||||||
The most common effect was to squash it out to the horizon, giving
|
The most common effect squashes the background out to the horizon, giving
|
||||||
a three-dimensional look.
|
a three-dimensional look.
|
||||||
The SNES did these transforms in hardware, but in this demo we implement
|
The SNES did these transforms in hardware, but our demo must do
|
||||||
them in software.
|
them in software.
|
||||||
|
|
||||||
% As found on Wikipedia, the transform is of the type
|
% As found on Wikipedia, the transform is of the type
|
||||||
@ -415,138 +434,158 @@ them in software.
|
|||||||
% [x'] = [a b]([x]-[x0])+[x0]
|
% [x'] = [a b]([x]-[x0])+[x0]
|
||||||
% [y'] [c d]([y] [y0]) [y0]
|
% [y'] [c d]([y] [y0]) [y0]
|
||||||
|
|
||||||
|
% http://www.helixsoft.nl/articles/circle/sincos.htm
|
||||||
|
|
||||||
|
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
|
||||||
|
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
|
||||||
Our algorithm is based on code by Martijn van Iersel.
|
Our algorithm is based on code by Martijn van Iersel.
|
||||||
It iterates through each y line on the screen and calculates based on
|
It iterates through each horizontal line on the screen and calculates the color
|
||||||
the camera location: height ({\em spacez}), x and y coordinates
|
to output based on the camera height ({\em spacez}) and {\em angle} as well
|
||||||
({\em cx} and {\em cy}) and the {\em angle}.
|
as the current x and y coordinates ({\em cx} and {\em cy}).
|
||||||
|
|
||||||
First calculate the distance
|
First the distance {\em d} is calculated based on fixed scale and
|
||||||
d = (z*yscale)/(y+horizon)
|
distance-to-horizon factors.
|
||||||
Then calculate the horizontal scale (distance between points on
|
Instead of a costly division we use a pre-generated lookup table for this.
|
||||||
this line)
|
\[d = \frac{z \times yscale}{y+horizon}\]
|
||||||
h = d/xscale
|
Next calculate the horizontal scale (distance between points on
|
||||||
Then calculate delta x and delta y values
|
this line):
|
||||||
dx = -sin(angle)*h
|
\[h = \frac{d}{xscale}\]
|
||||||
dy = cos(angle)*h
|
Then calculate delta x and delta y values between each block on the line.
|
||||||
It then calculates the starting offset of the left side of the line in
|
We use a pre-computed sine/cosine lookup table.
|
||||||
the tile lookup:
|
\[dx = -sin(angle) \times h\]
|
||||||
tilex = cx + (d*cos(angle) - (width/2) * dx;
|
\[dy = cos(angle) \times h\]
|
||||||
tiley = cy + (d*sin(angle) - (width/2) * dy;
|
The leftmost position in the tile lookup is calculated:
|
||||||
Now iterate the inner loop, where we lookup the tile color for each pixel
|
\[tilex = cx + (d*cos(angle) - (width/2) * dx\]
|
||||||
on the horizontal line.
|
\[tiley = cy + (d*sin(angle) - (width/2) * dy\]
|
||||||
putpixel (x, y, tilelookup(tilex,tiley)
|
Then an inner loop happens that adds dx and dy as we lookup the color
|
||||||
tilex += dx;
|
from the tilemap (just a wrap-around array lookup) for each block
|
||||||
tiley += dy;
|
on the line.
|
||||||
|
\[color = tilelookup(tilex,tiley)\]
|
||||||
|
\[plot (x, y) \]
|
||||||
|
\[tilex += dx, tiley+= dy\]
|
||||||
|
|
||||||
{\bf Optimizations}
|
\noindent
|
||||||
|
{\bf Optimizations:}
|
||||||
We managed to take this algorithm and speed it up in the following ways:
|
The 6502 processor cannot do floating point, so all of our routines use
|
||||||
\begin{itemize}
|
8.8 fixed point math.
|
||||||
\item blah
|
We eliminate all use of division, and convert as much as possible
|
||||||
\end{itemize}
|
to table lookups (which involves limiting the heights and angles a bit).
|
||||||
|
We also save some cycles by using self-modifying code,
|
||||||
For our code, we managed to reduce things to a small number of additions
|
most notably hard-coding the height (z) value and modifying the code
|
||||||
and subtractions for each pixel on the screen. Of course the 6502 can't
|
whenever this is changed.
|
||||||
do floating point, so we do fixed point math. We convert as much as we
|
The code started out only capable of roughly 4.9fps in 40x20 resolution
|
||||||
can to table lookups that are pre-calculated. We also make liberal use
|
and in the end we improved this to 5.7fps in 40x40 resolution.
|
||||||
of self-modifying code.
|
Care was taken to optimize the innermost loop, as every cycle saved there
|
||||||
|
results in 1280 cycles saved overall.
|
||||||
|
|
||||||
|
\noindent
|
||||||
{\bf Fast Multiply:}
|
{\bf Fast Multiply:}
|
||||||
|
One of the biggest bottlenecks in the mode7 code was the multiply.
|
||||||
|
Even our optimized algorithm calls for at least seven
|
||||||
|
16bit x 16bit = 32bit multiplies, something that is {\em really} slow on
|
||||||
|
the 6502.
|
||||||
|
A typical implementation takes around 700 cycles
|
||||||
|
for a 8.8 x 8.8 fixed point multiply.
|
||||||
|
|
||||||
Despite all of this there are still some cases where we have to do a
|
% Note, this is Quarter-square multiplication, apparently an ancient algorithm
|
||||||
16bit x 16bit = 32bit multiply, something that is *really* slow on 6502,
|
% https://en.wikipedia.org/wiki/Multiplication_algorithm#Quarter_square_multiplication
|
||||||
around 700 cycles (for a 8.8 x 8.8 fixed point multiply).
|
|
||||||
|
|
||||||
To make this faster we use a method described by Stephen Judd.
|
We improved this by using the ancient quarter-square
|
||||||
|
multiply algorithm, first described for 6502 use by Stephen Judd.
|
||||||
|
|
||||||
The key to note is that $(a+b)^{2} = a^{2}+2ab+b^{2}$
|
This works by noting these factorizations:
|
||||||
and $(a-b)^{2}=a^{2}-2ab+b^{2}$
|
\[(a+b)^{2} = a^{2}+2ab+b^{2}\]
|
||||||
and if you add them you can simplify to:
|
\[(a-b)^{2}=a^{2}-2ab+b^{2}\]
|
||||||
$a\times b =\frac{(a+b)^{2}}{4} - \frac{(a-b)^2}{4}$
|
If you subtract these you can simplify to
|
||||||
|
\[a\times b =\frac{(a+b)^{2}}{4} - \frac{(a-b)^2}{4}\]
|
||||||
|
|
||||||
This is you have a table of squares from 0..511 (all 8-bit a+b and a-b
|
For 8-bit values if you create a table of squares from 0 to 511
|
||||||
will fall in this range) then you can convert a multiply into a table
|
(all 8-bit a+b and a-b fall in this range) then you can convert a multiply
|
||||||
lookup plus a subtract.
|
into two table lookups and a subtraction.
|
||||||
|
This does have the downside of requiring 2kB of lookup tables
|
||||||
|
(which can be generated at startup) but it reduces the multiply
|
||||||
|
cost to the order of 250 cycles or so.
|
||||||
|
|
||||||
The downsize is you will need 2kB of squares lookup tables (which can
|
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
|
||||||
be generated at startup). This reduces the multiply cost to the order
|
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
|
||||||
of 200 to 250 cycles.
|
|
||||||
|
|
||||||
By using the fast multiply and a lot of careful optimization you can
|
\subsection{BALL ON CHECKERBOARD}
|
||||||
generate a Mode7 background in 40x40 graphics mode at about 5 frames/second.
|
|
||||||
|
|
||||||
The engine can be parameterized with different tilesets to use, which we
|
The first Mode7 scene transpires on an infinite checkerboard.
|
||||||
do to provide both a black+white checkerboard background, as well as the
|
A demo would be incomplete without some sort of bouncing geometric solid,
|
||||||
island background from the TFV game.
|
in this case we have a pink sphere.
|
||||||
|
The sphere is represented by 16 sprites that were captured from
|
||||||
\subsection{BOUNCING BALL ON CHECKERBOARD}
|
a 20 year old OpenGL game engine.
|
||||||
|
Screenshots were taken then reduced to the proper size and color
|
||||||
The first scence starts out viewing an infinite checkerboard.
|
limitations.
|
||||||
Any demo would be incomplete without some sort of bouncing geometric solid,
|
The shadows are also just sprites.
|
||||||
in our case a pink sphere.
|
Note that the Apple II has no dedicated sprite hardware, so these
|
||||||
This was accomplished with 16 sprites:
|
are drawn completely in software.
|
||||||
the sphere was modeled in OpenGL inside of a 20 year old game engine
|
|
||||||
and screenshots were taken then reduced in keeping with the size and
|
|
||||||
color limitations.
|
|
||||||
Similarly the shadow is also just sprites.
|
|
||||||
|
|
||||||
The clicking noise on bounce is generated by accessing the speaker port
|
The clicking noise on bounce is generated by accessing the speaker port
|
||||||
at address \$C030.
|
at address {\tt \$C030}.
|
||||||
This gives some sound for those viewing the demo without a Mockingboard.
|
This gives some sound for those viewing the demo without the benefit
|
||||||
|
of a Mockingboard.
|
||||||
|
|
||||||
\subsection{TFV SPACESHIP FLYING}
|
\subsection{TFV SPACESHIP FLYING}
|
||||||
|
|
||||||
|
|
||||||
This next scene has a spaceship flying over an island.
|
This next scene has a spaceship flying over an island.
|
||||||
|
The Mode7 graphics code is generic enough that only one copy of the code
|
||||||
|
is needed to generate both the checkerboard and island scenes.
|
||||||
The spaceship, water splash, and shadows are all sprites.
|
The spaceship, water splash, and shadows are all sprites.
|
||||||
They are all drawn in software as the Apple II has no sprite hardware.
|
|
||||||
The path the ship takes is pre-recorded; this is adapted from the
|
The path the ship takes is pre-recorded; this is adapted from the
|
||||||
Talbot Fantasy~7 game engine with the keyboard code replaced by a hard-coded
|
Talbot Fantasy~7 game engine with the keyboard code replaced by a hard-coded
|
||||||
script of actions to take.
|
script of actions to take.
|
||||||
|
|
||||||
\subsection{STARFIELD}
|
\subsection{STARFIELD}
|
||||||
|
|
||||||
The spaceship takes to the stars.
|
The spaceship now takes to the stars.
|
||||||
This is typical starfield code.
|
This is typical starfield code, where on each iteration the x and y
|
||||||
Only 16 stars are modeled, and the movement code re-uses the
|
values are changed by
|
||||||
same fast-multiply routine described previously.
|
\[dx=\frac{x}{z}, dy=\frac{y}{z}\]
|
||||||
|
In order to get a good frame rate and not clutter the lo-res screen
|
||||||
|
only 16 stars are modeled.
|
||||||
|
To avoid having to divide, the reciprocal of all possible z values
|
||||||
|
are stored in a table, and the fast-multiply routine described
|
||||||
|
previously is used.
|
||||||
|
|
||||||
The star positions require random number generation, but this is not
|
The star positions require random number generation, but there is no
|
||||||
fast on the 6502.
|
easy way to quickly get random data on the Apple II.
|
||||||
Originally we had a 256-byte blob of pre-generated ``random'' values
|
Originally we had a 256-byte blob of pre-generated ``random'' values
|
||||||
included in the code.
|
included in the code.
|
||||||
This wasted space, so now instead we just use our code at address
|
This wasted space, so now instead we just use our code at address
|
||||||
at \$5000 as if it were a block of random numbers.
|
at \$5000 as if it were a block of random numbers.
|
||||||
This was arbitrarily chosen, and it is not as random as it could be
|
This was arbitrarily chosen, and it is not as random as it could be
|
||||||
as seen when the ship enters hyperspace the lower right quadrant has fewer
|
as seen when the ship enters hyperspace and the lower-right quadrant
|
||||||
starts than one could desire.
|
is distressingly star-free.
|
||||||
|
|
||||||
A simple state machine controls star speed, ship movement, hyperspace,
|
A simple state machine controls star speed, ship movement, hyperspace,
|
||||||
background color (for the blue flash) and the eventual sequence of sprites
|
background color (for the blue flash) and the eventual sequence of sprites
|
||||||
as the ship vanishes into the distance.
|
as the ship vanishes into the distance.
|
||||||
|
|
||||||
\subsection{RASTERBARS/CREDITS}
|
\subsection{RASTERBARS/CREDITS}
|
||||||
|
|
||||||
Once the ship has departed, it is time for the credits as the stars
|
Once the ship has departed, it is time to run the credits as the stars
|
||||||
continue to run.
|
continue to fly by.
|
||||||
|
|
||||||
The text is written to the bottom 4 lines of the screen and appears
|
The text is written to the bottom four lines of the screen, seemingly
|
||||||
to be surrounded by low-res graphics blocks.
|
surrounded by graphics blocks.
|
||||||
Mixed graphics/text would generally not be possible on the Apple II, although
|
Mixed graphics/text is generally not be possible on the Apple II, although
|
||||||
with careful cycle counting and mode switching groups such as FrenchTouch
|
with careful cycle counting and mode switching groups such as FrenchTouch
|
||||||
have achieved this effect.
|
have achieved this effect.
|
||||||
I was lazy and instead used inverse-mode space characters which appear the same
|
What we see in this demo is the use of inverse-mode (inverted color)
|
||||||
as white graphics blocks.
|
space characters which appear the same as white graphics blocks.
|
||||||
|
|
||||||
The rasterbar effect is not really rasterbars, it's just a colorful assortment
|
The rasterbar effect is not really rasterbars, just a colorful assortment
|
||||||
of horizontal lines drawn at a location determined with a sine lookup table.
|
of horizontal lines drawn at a location determined with a sine lookup table.
|
||||||
Horizontal lines can take a surprising amount of time to draw, so this
|
Horizontal lines can take a surprising amount of time to draw, but these
|
||||||
was optimized using inlining and a few other methods.
|
were optimized using inlining and a few other tricks.
|
||||||
|
|
||||||
The rotating text is done by just rapidly rotating the output string through
|
The spinning text is done by just rapidly rotating the output string through
|
||||||
the ASCII table, with the clicking effect again by hitting the speaker
|
the ASCII table, with the clicking effect again generated
|
||||||
at address \$C030.
|
by hitting the speaker at address {\tt \$C030}.
|
||||||
The list of people to thank ended up being extremely critical to fitting in 8kB,
|
The list of people to thank ended up being the primary limitation to
|
||||||
as unique text strings do not compress well.
|
fitting in 8kB, as unique text strings do not compress well.
|
||||||
I apologize to everyone whose moniker got compressed beyond recognition,
|
I apologize to everyone whose moniker got compressed beyond recognition,
|
||||||
and I am still not totally happy with the centering of the text.
|
and I am still not totally happy with the centering of the text.
|
||||||
|
|
||||||
|
24
still_alive/Makefile
Normal file
24
still_alive/Makefile
Normal file
@ -0,0 +1,24 @@
|
|||||||
|
include ../Makefile.inc
|
||||||
|
|
||||||
|
DOS33 = ../dos33fs-utils/dos33
|
||||||
|
|
||||||
|
all: still_alive.dsk
|
||||||
|
|
||||||
|
still_alive.dsk: STILL_ALIVE ./SA.KRW
|
||||||
|
$(DOS33) -y still_alive.dsk BSAVE -a 0x0C00 STILL_ALIVE
|
||||||
|
$(DOS33) -y still_alive.dsk SAVE B ./SA.KRW
|
||||||
|
|
||||||
|
STILL_ALIVE: still_alive.o
|
||||||
|
ld65 -o STILL_ALIVE still_alive.o -C ../linker_scripts/apple2_c00.inc
|
||||||
|
|
||||||
|
still_alive.o: still_alive.s \
|
||||||
|
../asm_routines/mockingboard.s \
|
||||||
|
../asm_routines/dos33_routines.s \
|
||||||
|
../asm_routines/lz4_decode.s \
|
||||||
|
../asm_routines/keypress_minimal.s \
|
||||||
|
interrupt_handler.s \
|
||||||
|
ascii_art.inc zp.inc
|
||||||
|
ca65 -o still_alive.o still_alive.s -l still_alive.lst
|
||||||
|
|
||||||
|
clean:
|
||||||
|
rm -f *~ *.o *.lst STILL_ALIVE
|
2
still_alive/README.still_alive
Normal file
2
still_alive/README.still_alive
Normal file
@ -0,0 +1,2 @@
|
|||||||
|
initial: 2078
|
||||||
|
add ascii art: 9142
|
BIN
still_alive/SA.KRW
Normal file
BIN
still_alive/SA.KRW
Normal file
Binary file not shown.
223
still_alive/ascii_art.inc
Normal file
223
still_alive/ascii_art.inc
Normal file
@ -0,0 +1,223 @@
|
|||||||
|
aperture:
|
||||||
|
.asciiz " .,-:;//;:=,"
|
||||||
|
.asciiz " . :H@@@MM@M#H/.,+%;,"
|
||||||
|
.asciiz " ,/X+ +M@@M@MM%=,-%HMMM@X/,"
|
||||||
|
.asciiz " -+@MM; $M@@MH+-,;XMMMM@MMMM@+-"
|
||||||
|
.asciiz " ;@M@@M- XM@X;. -+XXXXXHHH@M@M#@/."
|
||||||
|
.asciiz " ,%MM@@MH ,@%= .---=-=:=,."
|
||||||
|
.asciiz " =@#@@@MX ., -%HX$$%%%+;"
|
||||||
|
.asciiz " =-./@M@M$ .;@MMMM@MM:"
|
||||||
|
.asciiz " X@/ -$MM/ .+MM@@@M$"
|
||||||
|
.asciiz ",@M@H: :@: . =X#@@@@-";
|
||||||
|
.asciiz ",@@@MMX, . /H- ;@M@M=";
|
||||||
|
.asciiz ".H@@@@M@+, %MM+..%#$.";
|
||||||
|
.asciiz " /MMMM@MMH/. XM@MH; =;"
|
||||||
|
.asciiz " /%+%$XHH@$= , .H@@@@MX,"
|
||||||
|
.asciiz " .=--------. -%H.,@@@@@MX,"
|
||||||
|
.asciiz " .%MM@@@HHHXX$$$%+- .:$MMX =M@@MM%."
|
||||||
|
.asciiz " =XMMM@MM@MM#H;,-+HMM@M+ /MMMX="
|
||||||
|
.asciiz " =%@M@M#@$-.=$@MM@@@M; %M%="
|
||||||
|
.asciiz " ,:+$+-,/H#MMMMMMM@= =,"
|
||||||
|
.asciiz " =++%%%%+/:-."
|
||||||
|
|
||||||
|
radioactive:
|
||||||
|
.asciiz " =+$HM####@H%;,"
|
||||||
|
.asciiz " /H###############M$,"
|
||||||
|
.asciiz " ,@################+"
|
||||||
|
.asciiz " .H##############+"
|
||||||
|
.asciiz " X############/"
|
||||||
|
.asciiz " $##########/"
|
||||||
|
.asciiz " %########/"
|
||||||
|
.asciiz " /X/;;+X/"
|
||||||
|
.asciiz " "
|
||||||
|
.asciiz " -XHHX-"
|
||||||
|
.asciiz " ,######,"
|
||||||
|
.asciiz "#############X .M####M. X#############";
|
||||||
|
.asciiz "##############- -//- -##############";
|
||||||
|
.asciiz "X##############%, ,+##############X";
|
||||||
|
.asciiz "-##############X X##############-";
|
||||||
|
.asciiz " %############% %############%"
|
||||||
|
.asciiz " %##########; ;##########%"
|
||||||
|
.asciiz " ;#######M= =M#######;"
|
||||||
|
.asciiz " .+M###@, ,@###M+."
|
||||||
|
.asciiz " :XH. .HX:"
|
||||||
|
|
||||||
|
atom:
|
||||||
|
.asciiz " =/;;/-"
|
||||||
|
.asciiz " +: //"
|
||||||
|
.asciiz " /; /;"
|
||||||
|
.asciiz " -X H."
|
||||||
|
.asciiz ".//;;;:;;-, X= :+ .-;:=;:;%;.";
|
||||||
|
.asciiz "M- ,=;;;#:, ,:#;;:=, ,@";
|
||||||
|
.asciiz ":% :%.=/++++/=.$= %=";
|
||||||
|
.asciiz " ,%; %/:+/;,,/++:+/ ;+."
|
||||||
|
.asciiz " ,+/. ,;@+, ,%H;, ,/+,"
|
||||||
|
.asciiz " ;+;;/= @. .H##X -X :///+;"
|
||||||
|
.asciiz " ;+=;;;.@, .XM@$. =X.//;=%/."
|
||||||
|
.asciiz " ,;: :@%= =$H: .+%-"
|
||||||
|
.asciiz " ,%= %;-///==///-// =%,"
|
||||||
|
.asciiz ";+ :%-;;;:;;;;-X- +:";
|
||||||
|
.asciiz "@- .-;;;;M- =M/;;;-. -X";
|
||||||
|
.asciiz " :;;::;;-. %- :+ ,-;;-;:=="
|
||||||
|
.asciiz " ,X H."
|
||||||
|
.asciiz " ;/ %="
|
||||||
|
.asciiz " // +;"
|
||||||
|
.asciiz " ,////,"
|
||||||
|
|
||||||
|
broken_heart:
|
||||||
|
.asciiz " .,---."
|
||||||
|
.asciiz " ,/XM#MMMX;,"
|
||||||
|
.asciiz " -%##########M%,"
|
||||||
|
.asciiz " -@######% $###@="
|
||||||
|
.asciiz " .,--, -H#######$ $###M:"
|
||||||
|
.asciiz " ,;$M###MMX; .;##########$;HM###X=";
|
||||||
|
.asciiz " ,/@##########H= ;################+";
|
||||||
|
.asciiz "-+#############M/, %##############+";
|
||||||
|
.asciiz "%M###############= /##############:";
|
||||||
|
.asciiz "H################ .M#############;.";
|
||||||
|
.asciiz "@###############M ,@###########M:."
|
||||||
|
.asciiz "X################, -$=X#######@:"
|
||||||
|
.asciiz "/@##################%- +######$-"
|
||||||
|
.asciiz ".;##################X .X#####+,"
|
||||||
|
.asciiz " .;H################/ -X####+."
|
||||||
|
.asciiz " ,;X##############, .MM/"
|
||||||
|
.asciiz " ,:+$H@M#######M#$- .$$="
|
||||||
|
.asciiz " .,-=;+$@###X: ;/=."
|
||||||
|
.asciiz " .,/X$; .::,"
|
||||||
|
.asciiz " ., .."
|
||||||
|
|
||||||
|
explosion:
|
||||||
|
.asciiz " .+"
|
||||||
|
.asciiz " /M;"
|
||||||
|
.asciiz " H#@: ;,"
|
||||||
|
.asciiz " -###H- -@/"
|
||||||
|
.asciiz " %####$. -; .%#X"
|
||||||
|
.asciiz " M#####+;#H :M#M."
|
||||||
|
.asciiz ".. .+/;%#########X###-"
|
||||||
|
.asciiz " -/%H%+;-, +##############/"
|
||||||
|
.asciiz " .:$M###MH$%+############X ,--=;-"
|
||||||
|
.asciiz " -/H#####################H+=."
|
||||||
|
.asciiz " .+#################X."
|
||||||
|
.asciiz " =%M####################H;."
|
||||||
|
.asciiz " /@###############+;;/%%;,"
|
||||||
|
.asciiz " -%###################$."
|
||||||
|
.asciiz " ;H######################M="
|
||||||
|
.asciiz " ,%#####MH$%;+#####M###-/@####%"
|
||||||
|
.asciiz " :$H%+;=- -####X.,H# -+M##@-"
|
||||||
|
.asciiz " . ,###; ; =$##+"
|
||||||
|
.asciiz " .#H, :XH,"
|
||||||
|
.asciiz " + .;-";
|
||||||
|
|
||||||
|
file:
|
||||||
|
.asciiz " -$-"
|
||||||
|
.asciiz " .H##H,"
|
||||||
|
.asciiz " +######+"
|
||||||
|
.asciiz " .+#########H."
|
||||||
|
.asciiz " -$############@."
|
||||||
|
.asciiz " =H###############@ -X:"
|
||||||
|
.asciiz " .$##################: @#@-"
|
||||||
|
.asciiz " ,; .M###################; H###;"
|
||||||
|
.asciiz " ;@#: @###################@ ,#####:"
|
||||||
|
.asciiz " -M###. M#################@. ;######H"
|
||||||
|
.asciiz " M####- +###############$ =@#######X"
|
||||||
|
.asciiz " H####$ -M###########+ :#########M,"
|
||||||
|
.asciiz " /####X- =########% :M########@/."
|
||||||
|
.asciiz " ,;%H@X; .$###X :##MM@%+;:-"
|
||||||
|
.asciiz " .."
|
||||||
|
.asciiz " -/;:-,. ,,-==+M########H"
|
||||||
|
.asciiz " -##################@HX%%+%%$%%%+:,,"
|
||||||
|
.asciiz " .-/H%%%+%%$H@###############M@+=:/+:";
|
||||||
|
.asciiz "/XHX%:#####MH%= ,---:;;;;/%%XHM,:###$";
|
||||||
|
.asciiz "$@#MX %+;- ."
|
||||||
|
|
||||||
|
|
||||||
|
check:
|
||||||
|
.asciiz " :X-";
|
||||||
|
.asciiz " :X###"
|
||||||
|
.asciiz " ;@####@"
|
||||||
|
.asciiz " ;M######X"
|
||||||
|
.asciiz " -@########$"
|
||||||
|
.asciiz " .$##########@"
|
||||||
|
.asciiz " =M############-";
|
||||||
|
.asciiz " +##############$";
|
||||||
|
.asciiz " .H############$=."
|
||||||
|
.asciiz " ,/: ,M##########M;."
|
||||||
|
.asciiz " -+@###; =##########M;"
|
||||||
|
.asciiz " =%M#######; :#########M/"
|
||||||
|
.asciiz "-$M###########; :#########/"
|
||||||
|
.asciiz " ,;X###########; =########$."
|
||||||
|
.asciiz " ;H#########+#######M="
|
||||||
|
.asciiz " ,+##############+"
|
||||||
|
.asciiz " /M#########@-"
|
||||||
|
.asciiz " ;M######%"
|
||||||
|
.asciiz " +####:"
|
||||||
|
.asciiz " ,$M-"
|
||||||
|
|
||||||
|
black_mesa:
|
||||||
|
.asciiz " .-;+$XHHHHHHX$+;-."
|
||||||
|
.asciiz " ,;X@@X%/;=----=:/%X@@X/,"
|
||||||
|
.asciiz " =$@@%=. .=+H@X:"
|
||||||
|
.asciiz " -XMX: =XMX="
|
||||||
|
.asciiz " /@@: =H@+"
|
||||||
|
.asciiz " %@X, .$@$"
|
||||||
|
.asciiz " +@X. $@%"
|
||||||
|
.asciiz "-@@, .@@=";
|
||||||
|
.asciiz "%@% +@$";
|
||||||
|
.asciiz "H@: :@H";
|
||||||
|
.asciiz "H@: :HHHHHHHHHHHHHHHHHHX, =@H";
|
||||||
|
.asciiz "%@% ;@M@@@@@@@@@@@@@@@@@H- +@$";
|
||||||
|
.asciiz "=@@, :@@@@@@@@@@@@@@@@@@@@@= .@@:";
|
||||||
|
.asciiz " +@X :@@@@@@@@@@@@@@@M@@@@@@:%@%"
|
||||||
|
.asciiz " $@$, ;@@@@@@@@@@@@@@@@@M@@@@@@$."
|
||||||
|
.asciiz " +@@HHHHHHH@@@@@@@@@@@@@@@@@@@@@@@+"
|
||||||
|
.asciiz " =X@@@@@@@@@@@@@@@@@@@@@@@@@@@@X="
|
||||||
|
.asciiz " :$@@@@@@@@@@@@@@@@@@@M@@@@$:"
|
||||||
|
.asciiz " ,;$@@@@@@@@@@@@@@@@@@X/-"
|
||||||
|
.asciiz " .-;+$XXHHHHHX$+;-."
|
||||||
|
|
||||||
|
cake:
|
||||||
|
.asciiz " ,:/+/-"
|
||||||
|
.asciiz " /M/ .,-=;//;-"
|
||||||
|
.asciiz " .:/= ;MH/, ,=/+%$XH@MM#@:"
|
||||||
|
.asciiz " -$##@+$###@H@MMM#######H:. -/H#";
|
||||||
|
.asciiz " .,H@H@ X######@ -H#####@+- -+H###@X";
|
||||||
|
.asciiz " .,@##H; +XM##M/, =%@###@X;-"
|
||||||
|
.asciiz "X%- :M##########$. .:%M###@%:"
|
||||||
|
.asciiz "M##H, +H@@@$/-. ,;$M###@%, -";
|
||||||
|
.asciiz "M####M=,,---,.-%%H####M$: ,+@##";
|
||||||
|
.asciiz "@##################@/. :%H##@$-"
|
||||||
|
.asciiz "M###############H, ;HM##M$="
|
||||||
|
.asciiz "#################. .=$M##M$="
|
||||||
|
.asciiz "################H..;XM##M$= .:+";
|
||||||
|
.asciiz "M###################@%= =+@MH%";
|
||||||
|
.asciiz "@################M/. =+H#X%="
|
||||||
|
.asciiz "=+M##############M, -/X#X+;."
|
||||||
|
.asciiz " .;XM##########H= ,/X#H+:,"
|
||||||
|
.asciiz " .=+HM######M+/+HM@+=."
|
||||||
|
.asciiz " ,:/%XM####H/."
|
||||||
|
.asciiz " ,.:=-."
|
||||||
|
|
||||||
|
|
||||||
|
glados:
|
||||||
|
.asciiz " #+ @ # # M#@"
|
||||||
|
.asciiz " . .X X.%##@;# # +@#######X. @#%"
|
||||||
|
.asciiz " ,==. ,######M+ -#####%M####M- #";
|
||||||
|
.asciiz " :H##M%:=##+ .M##M,;#####/+#######% ,M#";
|
||||||
|
.asciiz " .M########= =@#@.=#####M=M#######= X#";
|
||||||
|
.asciiz " :@@MMM##M. -##M.,#######M#######. = M";
|
||||||
|
.asciiz " @##..###:. .H####. @@ X,";
|
||||||
|
.asciiz " ############: ###,/####; /##= @#. M"
|
||||||
|
.asciiz " ,M## ;##,@#M;/M#M @# X#% X#"
|
||||||
|
.asciiz ".%= ######M## ##.M#: ./#M ,M #M ,#$"
|
||||||
|
.asciiz "##/ $## #+;#: #### ;#/ M M- @# :";
|
||||||
|
.asciiz "#+ #M@MM###M-;M #:$#-##$H# .#X @ + $#. #";
|
||||||
|
.asciiz " ######/.: #%=# M#:MM./#.-# @#: H#";
|
||||||
|
.asciiz "+,.= @###: /@ %#,@ ##@X #,-#@.##% .@#";
|
||||||
|
.asciiz "#####+;/##/ @## @#,+ /#M . X,"
|
||||||
|
.asciiz " ;###M#@ M###H .#M- ,##M ;@@; ###";
|
||||||
|
.asciiz " .M#M##H ;####X ,@#######M/ -M###$ -H";
|
||||||
|
.asciiz " .M###% X####H .@@MM@; ;@#M@"
|
||||||
|
.asciiz " H#M /@####/ ,++. / ==-,"
|
||||||
|
.asciiz " ,=/:, .+X@MMH@#H #####$=";
|
||||||
|
|
||||||
|
|
972
still_alive/eightycol.inc
Normal file
972
still_alive/eightycol.inc
Normal file
@ -0,0 +1,972 @@
|
|||||||
|
1 REM PORTAL CLOSING CREDITS APPLESOFT
|
||||||
|
2 REM BASED ON QBASIC VERSION BY Thomas Moss (spinneretsystems)
|
||||||
|
3 REM WORDS AND MUSIC BY JONATHAN COULTON
|
||||||
|
'
|
||||||
|
' Size Opt: Final Version = 20557
|
||||||
|
' Move Line 20 to Line 8 = 20182
|
||||||
|
'
|
||||||
|
5 TEXT:PRINT CHR$(4)+"PR#3": REM 80 COLUMN MODE
|
||||||
|
7 HOME:C$=CHR$(13):GOTO 50
|
||||||
|
'
|
||||||
|
' SLOWTEXT
|
||||||
|
'
|
||||||
|
8 FOR C = 1 TO LEN(T$):PRINT MID$(T$, C, 1);:FOR I = 1 TO 1:NEXT I: NEXT C:POKE 768,F:POKE 769,D:CALL 770:RETURN
|
||||||
|
'
|
||||||
|
10 REM SET LEFT WINDOW
|
||||||
|
11 POKE 32,2:POKE 33,35:POKE 34,1:POKE 35,21
|
||||||
|
12 RETURN
|
||||||
|
15 REM SET RIGHT WINDOW
|
||||||
|
16 POKE 32,39:POKE 33,40:POKE 34,1:POKE 35,23
|
||||||
|
17 RETURN
|
||||||
|
'
|
||||||
|
' Restore Cursor
|
||||||
|
'
|
||||||
|
18 X=PEEK(1403):Y=PEEK(37):RETURN
|
||||||
|
19 POKE 36,X:POKE 37,Y-1:RETURN
|
||||||
|
'
|
||||||
|
30 REM FASTTEXT
|
||||||
|
31 FOR C = 1 TO LEN(T$)
|
||||||
|
32 PRINT MID$(T$, C, 1);
|
||||||
|
33 FOR I = 1 TO 25:NEXT I
|
||||||
|
34 NEXT C
|
||||||
|
35 RETURN
|
||||||
|
'
|
||||||
|
' Assembly Language audio routine
|
||||||
|
' See http://eightbitsoundandfury.ld8.org/programming.html
|
||||||
|
50 FOR L = 770 TO 790: READ V: POKE L,V: NEXT L
|
||||||
|
51 DATA 173,48,192,136,208,5,206,1,3,240,9,202,208,245,174,0,3,76,2,3,96
|
||||||
|
55 PRINT " ------------------------------------ "
|
||||||
|
57 FOR I=1 TO 20: PRINT "| |":NEXT I
|
||||||
|
60 PRINT " ------------------------------------ "
|
||||||
|
65 GOSUB 10
|
||||||
|
'
|
||||||
|
70 HOME
|
||||||
|
72 T$="Forms FORM-29827281-12:"+C$:GOSUB 30
|
||||||
|
74 T$="Test Assessment Report"+C$:GOSUB 30
|
||||||
|
76 PRINT:PRINT
|
||||||
|
78 FOR I=1 TO 1000: NEXT I
|
||||||
|
'
|
||||||
|
' This was a triumph.
|
||||||
|
'
|
||||||
|
80 T$="This ":D=54:F=85:GOSUB 8
|
||||||
|
82 T$="was ":F=91:GOSUB 8
|
||||||
|
84 T$="a ":F=102:GOSUB 8
|
||||||
|
86 T$="tri":GOSUB 8
|
||||||
|
89 T$="umph."+C$:F=91:GOSUB 8
|
||||||
|
90 FOR I=1 TO 800:NEXT
|
||||||
|
'
|
||||||
|
' I'm making a note here:
|
||||||
|
'
|
||||||
|
94 T$="I'm ":F=152:GOSUB 8
|
||||||
|
96 T$="ma":F=85:GOSUB 8
|
||||||
|
98 T$="king ":F=91:GOSUB 8
|
||||||
|
100 T$="a ":F=102:GOSUB 8
|
||||||
|
102 T$="note ":D=108:F=102:GOSUB 8
|
||||||
|
104 T$ = "here:"+C$:D=54:F=91:GOSUB 8
|
||||||
|
105 FOR I=1 TO 160: NEXT
|
||||||
|
'
|
||||||
|
' HUGE SUCCESS.
|
||||||
|
'
|
||||||
|
106 T$ = "HUGE ":D=108:F=114:GOSUB 8
|
||||||
|
108 T$ = "SUC":D=54:F=102:GOSUB 8
|
||||||
|
110 T$ = "CESS."+C$:D=108:F=152:GOSUB 8
|
||||||
|
111 FOR I=1 TO 480: NEXT
|
||||||
|
'
|
||||||
|
' It's hard to overstate
|
||||||
|
'
|
||||||
|
112 T$="It's ":D=54:F=152:GOSUB 8
|
||||||
|
114 T$="hard ":D=108:F=102:GOSUB 8
|
||||||
|
116 T$="to ":D=54:F=91:GOSUB 8
|
||||||
|
118 T$="o":D=162:F=85:GOSUB 8
|
||||||
|
120 T$="ver":D=54:F=91:GOSUB 8
|
||||||
|
122 T$="state"+C$:D=108:F=121:GOSUB 8
|
||||||
|
'
|
||||||
|
' my satisfaction.
|
||||||
|
'
|
||||||
|
124 T$="my ":D=162:F=114:GOSUB 8
|
||||||
|
126 T$="sa":D=108:F=102:GOSUB 8
|
||||||
|
128 T$="tis":D=54:F=152:GOSUB 8
|
||||||
|
130 T$="fac":D=108:F=152:GOSUB 8
|
||||||
|
132 T$="tion."+C$:F=91:GOSUB 8
|
||||||
|
133 FOR I=1 TO 720:NEXT
|
||||||
|
'
|
||||||
|
' APERTURE SCIENCE LOGO
|
||||||
|
134 GOSUB 18:GOSUB 15:HOME:GOSUB 2000:GOSUB 10:GOSUB 19:PRINT
|
||||||
|
'
|
||||||
|
' Aperture Science
|
||||||
|
136 T$="A":D=54:F=85:GOSUB 8
|
||||||
|
138 T$="per":F=91:GOSUB 8
|
||||||
|
140 T$="ture ":F=102:GOSUB 8
|
||||||
|
142 T$="Sci":GOSUB 8
|
||||||
|
144 T$="ence"+C$:F=91:GOSUB 8
|
||||||
|
145 FOR I=1 TO 800:NEXT
|
||||||
|
'
|
||||||
|
' We do what we must
|
||||||
|
'
|
||||||
|
146 T$="We ":F=152:GOSUB 8
|
||||||
|
148 T$="do ":F=85:GOSUB 8
|
||||||
|
150 T$="what ":F=91:GOSUB 8
|
||||||
|
152 T$="we ":F=102:GOSUB 8
|
||||||
|
154 T$="must"+C$:GOSUB 8
|
||||||
|
155 FOR I=1 TO 160: NEXT
|
||||||
|
'
|
||||||
|
' because we can.
|
||||||
|
'
|
||||||
|
156 T$="be":F=91:GOSUB 8
|
||||||
|
158 T$="cause ":F=114:GOSUB 8
|
||||||
|
159 FOR I=1 TO 160: NEXT
|
||||||
|
160 T$="we ":F=102:GOSUB 8
|
||||||
|
162 T$="can."+C$:D=162:F=152:GOSUB 8
|
||||||
|
163 FOR I=1 TO 560: NEXT
|
||||||
|
'
|
||||||
|
' For the good of all of us.
|
||||||
|
'
|
||||||
|
164 T$="For ":D=108:F=102:GOSUB 8
|
||||||
|
166 T$="the ":D=54:F=91:GOSUB 8
|
||||||
|
168 T$="good ":D=162:F=85:GOSUB 8
|
||||||
|
170 T$="of ":D=54:F=102:GOSUB 8
|
||||||
|
172 T$="all ":D=162:F=121:GOSUB 8
|
||||||
|
174 T$="of ":D=54:F=114:GOSUB 8
|
||||||
|
176 T$="us."+C$:F=102:GOSUB 8
|
||||||
|
'177 FOR I=1 TO 80: NEXT
|
||||||
|
'
|
||||||
|
' RADIATION
|
||||||
|
178 GOSUB 18:GOSUB 15:HOME:GOSUB 2100: GOSUB 10:GOSUB 19:PRINT
|
||||||
|
'
|
||||||
|
' Except the ones who are dead.
|
||||||
|
'
|
||||||
|
180 T$="Ex":F=152:GOSUB 8
|
||||||
|
182 T$="cept ":F=114:GOSUB 8
|
||||||
|
184 T$="the ":F=102:GOSUB 8
|
||||||
|
186 T$="ones ":F=96:GOSUB 8
|
||||||
|
188 T$="who ":F=102:GOSUB 8
|
||||||
|
190 T$="are ":F=114:GOSUB 8
|
||||||
|
192 T$="dead."+C$:F=128:GOSUB 8
|
||||||
|
193 FOR I=1 TO 160: NEXT
|
||||||
|
'
|
||||||
|
' APERTURE SCIENCE LOGO
|
||||||
|
194 GOSUB 18:GOSUB 15:HOME:GOSUB 2000: GOSUB 10:GOSUB 19:PRINT
|
||||||
|
'
|
||||||
|
' But there's no sense crying\nover every mistake.
|
||||||
|
'
|
||||||
|
196 PRINT
|
||||||
|
198 T$="But ":F=152:GOSUB 8
|
||||||
|
200 T$="there's ":F=143:GOSUB 8
|
||||||
|
202 T$="no ":D=108:F=128:GOSUB 8
|
||||||
|
204 T$="sense ":F=96:GOSUB 8
|
||||||
|
206 T$="cry":D=54:F=102:GOSUB 8
|
||||||
|
208 T$="ing"+C$:F=114:GOSUB 8
|
||||||
|
210 T$="o":GOSUB 8
|
||||||
|
212 T$="ver ":F=128:GOSUB 8
|
||||||
|
214 T$="e":F=114:GOSUB 8
|
||||||
|
216 T$="very ":F=128:GOSUB 8
|
||||||
|
218 T$="mis":D=108:F=128:GOSUB 8
|
||||||
|
220 T$="take."+C$:F=128:GOSUB 8
|
||||||
|
'
|
||||||
|
' You just keep on trying\ntill you run out of cake.
|
||||||
|
'
|
||||||
|
222 T$="You ":D=54:F=152:GOSUB 8
|
||||||
|
224 T$="just ":F=143:GOSUB 8
|
||||||
|
226 T$="keep ":D=108:F=128:GOSUB 8
|
||||||
|
228 T$="on ":F=96:GOSUB 8
|
||||||
|
230 T$="try":D=54:F=85:GOSUB 8
|
||||||
|
232 T$="ing"+C$:F=96:GOSUB 8
|
||||||
|
234 T$="till ":F=102:GOSUB 8
|
||||||
|
236 T$="you ":F=114:GOSUB 8
|
||||||
|
238 T$="run ":GOSUB 8
|
||||||
|
240 T$="out ":F=102:GOSUB 8
|
||||||
|
242 T$="of ":D=108:F=96:GOSUB 8
|
||||||
|
244 T$="cake."+C$:F=96:GOSUB 8
|
||||||
|
'
|
||||||
|
' ATOM
|
||||||
|
'
|
||||||
|
246 GOSUB 18:GOSUB 15:HOME:GOSUB 2200: GOSUB 10:GOSUB 19:PRINT
|
||||||
|
'
|
||||||
|
' And the Science gets done.
|
||||||
|
'
|
||||||
|
248 T$="And ":D=54:F=85:GOSUB 8
|
||||||
|
250 T$="the ":F=76:GOSUB 8
|
||||||
|
252 T$="Sci":F=72:GOSUB 8
|
||||||
|
254 T$="ence ":GOSUB 8
|
||||||
|
256 T$="gets ":D=108:F=76:GOSUB 8
|
||||||
|
258 T$="done."+C$:F=85:GOSUB 8
|
||||||
|
'
|
||||||
|
' And you make a neat gun
|
||||||
|
'
|
||||||
|
260 T$="And ":D=54:F=96:GOSUB 8
|
||||||
|
262 T$="you ":F=85:GOSUB 8
|
||||||
|
264 T$="make ":F=76:GOSUB 8
|
||||||
|
266 T$="a ":F=76:GOSUB 8
|
||||||
|
268 T$="neat ":D=108:F=85:GOSUB 8
|
||||||
|
270 T$="gun."+C$:F=96:GOSUB 8
|
||||||
|
'
|
||||||
|
' APERTURE SCIENCE LOGO
|
||||||
|
272 GOSUB 18:GOSUB 15:HOME:GOSUB 2000: GOSUB 10:GOSUB 19:PRINT
|
||||||
|
'
|
||||||
|
' For the people who are
|
||||||
|
'
|
||||||
|
274 T$="For ":D=54:F=114:GOSUB 8
|
||||||
|
276 T$="the ":F=128:GOSUB 8
|
||||||
|
278 T$="peo":F=114:GOSUB 8
|
||||||
|
280 T$="ple ":F=96:GOSUB 8
|
||||||
|
282 T$="who ":GOSUB 8
|
||||||
|
284 T$="are"+C$:D=108:F=102:GOSUB 8
|
||||||
|
'
|
||||||
|
' still alive.
|
||||||
|
'
|
||||||
|
286 T$="still ":D=54:F=102:GOSUB 8
|
||||||
|
288 T$="a":F=91:GOSUB 8
|
||||||
|
290 T$="live."+C$:D=162:F=91:GOSUB 8
|
||||||
|
291 FOR I=1 TO 1900: NEXT
|
||||||
|
'
|
||||||
|
'
|
||||||
|
'
|
||||||
|
292 HOME:C$=CHR$(13):X=FRE(0)
|
||||||
|
294 T$="Forms FORM-55551-5:"+C$:GOSUB 30
|
||||||
|
296 T$="Personnel File Addendum:"+C$:GOSUB 30
|
||||||
|
298 T$=C$+"Dear <<Subject Name Here>>":GOSUB 30
|
||||||
|
300 PRINT:PRINT
|
||||||
|
'
|
||||||
|
' I'm not even angry.
|
||||||
|
'
|
||||||
|
302 T$="I'm ":D=54:F=152:GOSUB 8
|
||||||
|
304 T$="not ":F=85:GOSUB 8
|
||||||
|
306 T$="e":F=91:GOSUB 8
|
||||||
|
308 T$="ven ":F=102:GOSUB 8
|
||||||
|
310 T$="an":GOSUB 8
|
||||||
|
312 T$="gry."+C$:F=91:GOSUB 8
|
||||||
|
313 FOR I=1 TO 800: NEXT
|
||||||
|
'
|
||||||
|
' I'm being so sincere right now.
|
||||||
|
'
|
||||||
|
314 T$="I'm ":F=85:GOSUB 8
|
||||||
|
316 T$="be":F=91:GOSUB 8
|
||||||
|
320 T$="ing ":F=102:GOSUB 8
|
||||||
|
322 T$="so ":D=162:F=102:GOSUB 8
|
||||||
|
324 T$="sin":D=54:F=91:GOSUB 8
|
||||||
|
326 T$="cere ":D=108:F=114:GOSUB 8
|
||||||
|
328 T$="right ":F=102:GOSUB 8
|
||||||
|
330 T$="now."+C$:F=152:GOSUB 8
|
||||||
|
331 FOR I=1 TO 560: NEXT
|
||||||
|
'
|
||||||
|
' Even though you broke my
|
||||||
|
'
|
||||||
|
332 T$="E":F=102:GOSUB 8
|
||||||
|
334 T$="ven ":D=54:F=91:GOSUB 8
|
||||||
|
336 T$="though ":D=162:F=85:GOSUB 8
|
||||||
|
338 T$="you ":D=108:F=102:GOSUB 8
|
||||||
|
340 T$="broke ":F=121:GOSUB 8
|
||||||
|
342 T$="my ":D=54:F=114:GOSUB 8
|
||||||
|
'
|
||||||
|
' HEART
|
||||||
|
344 GOSUB 18:GOSUB 15:HOME:GOSUB 2300: GOSUB 10:GOSUB 19:PRINT
|
||||||
|
345 POKE 36,X
|
||||||
|
'
|
||||||
|
' heart.\nAnd killed me.
|
||||||
|
'
|
||||||
|
346 T$="heart."+C$:D=162:F=102:GOSUB 8
|
||||||
|
348 T$="And ":D=54:F=152:GOSUB 8
|
||||||
|
350 T$="killed ":D=108:F=152:GOSUB 8
|
||||||
|
352 T$="me."+C$:D=54:F=91:GOSUB 8
|
||||||
|
353 FOR I=1 TO 720: NEXT
|
||||||
|
'
|
||||||
|
' EXPLOSION
|
||||||
|
'
|
||||||
|
354 GOSUB 18:GOSUB 15:HOME:GOSUB 2400: GOSUB 10:GOSUB 19:PRINT
|
||||||
|
'
|
||||||
|
' And tore me to pieces.
|
||||||
|
'
|
||||||
|
356 T$="And ":F=152:GOSUB 8
|
||||||
|
358 T$="tore ":F=85:GOSUB 8
|
||||||
|
360 T$="me ":F=91:GOSUB 8
|
||||||
|
362 T$="to ":F=102:GOSUB 8
|
||||||
|
364 T$="pie":GOSUB 8
|
||||||
|
366 T$="ces."+C$:F=91:GOSUB 8
|
||||||
|
367 FOR I=1 TO 800:NEXT
|
||||||
|
'
|
||||||
|
' And threw every peice into
|
||||||
|
'
|
||||||
|
368 T$="And ":F=152:GOSUB 8:REM SOUND 220, 4.8
|
||||||
|
370 T$="threw ":F=85:GOSUB 8
|
||||||
|
372 T$="ev":F=91:GOSUB 8
|
||||||
|
374 T$="ery ":F=102:GOSUB 8
|
||||||
|
376 T$="piece ":GOSUB 8
|
||||||
|
377 FOR I=1 TO 160: NEXT
|
||||||
|
378 T$="in":F=91:GOSUB 8
|
||||||
|
380 T$="to ":F=114:GOSUB 8
|
||||||
|
'381 FOR I=1 TO 160: NEXT
|
||||||
|
'
|
||||||
|
' FIRE
|
||||||
|
382 GOSUB 18:GOSUB 15:HOME:GOSUB 2500: GOSUB 10:GOSUB 19:PRINT
|
||||||
|
383 POKE 36,X
|
||||||
|
'
|
||||||
|
' a fire.
|
||||||
|
'
|
||||||
|
384 T$="a ":F=102:GOSUB 8
|
||||||
|
386 T$="fire."+C$:D=108:F=152:GOSUB 8
|
||||||
|
387 FOR I=1 TO 560:NEXT
|
||||||
|
'
|
||||||
|
' As they burned it hurt because
|
||||||
|
'
|
||||||
|
388 T$="As ":F=102:GOSUB 8
|
||||||
|
390 T$="they ":D=54:F=91:GOSUB 8
|
||||||
|
392 T$="burned ":D=162:F=85:GOSUB 8
|
||||||
|
394 T$="it ":D=108:F=102:GOSUB 8
|
||||||
|
396 T$="hurt ":F=121:GOSUB 8
|
||||||
|
398 T$="be":D=54:F=114:GOSUB 8
|
||||||
|
400 T$="cause"+C$:F=102:GOSUB 8
|
||||||
|
401 FOR I=1 TO 80: NEXT
|
||||||
|
'
|
||||||
|
' I was so happy for you!
|
||||||
|
'
|
||||||
|
402 T$="I ":F=152:GOSUB 8:REM SOUND 220, 4.8
|
||||||
|
404 T$="was ":F=114:GOSUB 8:REM SOUND 293.6, 4.8
|
||||||
|
406 T$="so ":F=102:GOSUB 8:REM SOUND 329.6, 4.8
|
||||||
|
408 T$="hap":F=96:GOSUB 8:REM SOUND 349.2, 4.8
|
||||||
|
410 T$="py ":F=102:GOSUB 8:REM SOUND 329.6, 4.8
|
||||||
|
412 T$="for ":F=114:GOSUB 8:REM SOUND 293.6, 4.8
|
||||||
|
414 T$="you!"+C$:F=128:GOSUB 8:REM SOUND 261.6, 14.4
|
||||||
|
'415 FOR I=1 TO 160: NEXT
|
||||||
|
'
|
||||||
|
' CHECK
|
||||||
|
416 GOSUB 18:GOSUB 15:HOME:GOSUB 2600: GOSUB 10:GOSUB 19:PRINT
|
||||||
|
'
|
||||||
|
' Now these points of data\nmake a beautiful line.
|
||||||
|
'
|
||||||
|
418 T$="Now ":F=152:GOSUB 8
|
||||||
|
420 T$="these ":F=143:GOSUB 8
|
||||||
|
422 T$="points ":D=108:F=128:GOSUB 8
|
||||||
|
424 T$="of ":F=96:GOSUB 8
|
||||||
|
426 T$="da":D=54:F=102:GOSUB 8
|
||||||
|
428 T$="ta"+C$:F=114:GOSUB 8
|
||||||
|
430 T$="make ":GOSUB 8
|
||||||
|
432 T$="a ":F=128:GOSUB 8
|
||||||
|
434 T$="beau":F=114:GOSUB 8
|
||||||
|
436 T$="ti":F=128:GOSUB 8
|
||||||
|
438 T$="ful ":D=108:F=128:GOSUB 8
|
||||||
|
440 T$="line."+C$:F=128:GOSUB 8
|
||||||
|
'
|
||||||
|
' And we're out of beta.\nWe're releasing on time.
|
||||||
|
'
|
||||||
|
442 T$="And ":D=54:F=152:GOSUB 8
|
||||||
|
444 T$="we're ":F=143:GOSUB 8
|
||||||
|
446 T$="out ":D=108:F=128:GOSUB 8
|
||||||
|
448 T$="of ":F=96:GOSUB 8
|
||||||
|
450 T$="be":D=54:F=85:GOSUB 8
|
||||||
|
452 T$="ta."+C$:F=96:GOSUB 8
|
||||||
|
454 T$="We're ":F=102:GOSUB 8
|
||||||
|
456 T$="re":F=114:GOSUB 8
|
||||||
|
458 T$="lea":GOSUB 8
|
||||||
|
460 T$="sing ":F=102:GOSUB 8
|
||||||
|
462 T$="on ":D=108:F=96:GOSUB 8
|
||||||
|
464 T$="time."+C$:F=96:GOSUB 8
|
||||||
|
'
|
||||||
|
' EXPLOSION
|
||||||
|
466 GOSUB 18:GOSUB 15:HOME:GOSUB 2400: GOSUB 10:GOSUB 19:PRINT
|
||||||
|
'
|
||||||
|
' So I'm GLaD. I got burned.
|
||||||
|
'
|
||||||
|
468 T$="So ":D=54:F=85:GOSUB 8
|
||||||
|
470 T$="I'm ":F=76:GOSUB 8
|
||||||
|
472 T$="GLaD. ":F=72:GOSUB 8
|
||||||
|
474 T$="I ":GOSUB 8
|
||||||
|
476 T$="got ": D=108:F=76:GOSUB 8
|
||||||
|
478 T$="burned."+C$:F=85:GOSUB 8
|
||||||
|
'
|
||||||
|
' ATOM
|
||||||
|
'
|
||||||
|
480 GOSUB 18:GOSUB 15:HOME:GOSUB 2200: GOSUB 10:GOSUB 19:PRINT
|
||||||
|
'
|
||||||
|
' Think of all the things we learned
|
||||||
|
'
|
||||||
|
482 T$="Think ":D=54:F=96:GOSUB 8
|
||||||
|
484 T$="of ":F=85:GOSUB 8
|
||||||
|
486 T$="all ":F=76:GOSUB 8
|
||||||
|
488 T$="the ":GOSUB 8
|
||||||
|
490 T$="things ":F=85:GOSUB 8
|
||||||
|
492 T$="we ":F=96:GOSUB 8
|
||||||
|
494 T$="learned"+C$:D=108:F=96:GOSUB 8
|
||||||
|
'
|
||||||
|
' APERTURE SCIENCE LOGO
|
||||||
|
'
|
||||||
|
496 GOSUB 18:GOSUB 15:HOME:GOSUB 2000: GOSUB 10:GOSUB 19:PRINT
|
||||||
|
'
|
||||||
|
' for the people who are
|
||||||
|
'
|
||||||
|
498 T$="for ":D=54:F=114:GOSUB 8
|
||||||
|
500 T$="the ":F=128:GOSUB 8
|
||||||
|
502 T$="peo":F=114:GOSUB 8
|
||||||
|
504 T$="ple ":F=96:GOSUB 8
|
||||||
|
506 T$="who ":GOSUB 8
|
||||||
|
510 T$="are"+C$: D=108:F=102:GOSUB 8
|
||||||
|
'
|
||||||
|
' still alive.
|
||||||
|
'
|
||||||
|
512 T$="still ":D=54:F=102:GOSUB 8
|
||||||
|
'
|
||||||
|
' FIXME: CAN WE DO ALIVE SLOWLY LIKE IN THE VIDEO?
|
||||||
|
'
|
||||||
|
513 T$="a":F=91:GOSUB 8
|
||||||
|
514 T$="live."+C$:D=162:F=91:GOSUB 8
|
||||||
|
'
|
||||||
|
' PAGE 3
|
||||||
|
'
|
||||||
|
516 HOME:C$=CHR$(13)
|
||||||
|
517 X=FRE(0)
|
||||||
|
518 T$="Forms FORM-55551-6:"+C$:GOSUB 30
|
||||||
|
520 T$="Personnel File Addendum ":GOSUB 30
|
||||||
|
522 T$="Addendum:"+C$:GOSUB 30
|
||||||
|
523 PRINT
|
||||||
|
524 T$="One last thing:"+C$:GOSUB 30
|
||||||
|
526 PRINT
|
||||||
|
'
|
||||||
|
' Go ahead and leave me
|
||||||
|
'
|
||||||
|
528 T$="Go ":D=54:F=85:GOSUB 8
|
||||||
|
530 T$="a":D=27:F=91:GOSUB 8
|
||||||
|
531 T$="head ":GOSUB 8
|
||||||
|
532 T$="and ":D=54:F=102:GOSUB 8
|
||||||
|
534 T$="leave ":D=108:F=102:GOSUB 8
|
||||||
|
536 T$="me"+C$:D=54:F=91:GOSUB 8
|
||||||
|
537 FOR I=1 TO 520:NEXT
|
||||||
|
'
|
||||||
|
' I think I prefer to stay inside.
|
||||||
|
'
|
||||||
|
538 T$="I ":F=152:GOSUB 8
|
||||||
|
540 T$="think ":F=85:GOSUB 8
|
||||||
|
542 T$="I ":F=91:GOSUB 8
|
||||||
|
544 T$="pre":F=102:GOSUB 8
|
||||||
|
546 T$="fer ":F=102:GOSUB 8
|
||||||
|
547 FOR I=1 TO 160: NEXT
|
||||||
|
548 T$="to ":F=91:GOSUB 8
|
||||||
|
550 T$="stay ":F=114:GOSUB 8
|
||||||
|
551 FOR I=1 TO 160: NEXT
|
||||||
|
552 T$="in":F=102:GOSUB 8
|
||||||
|
554 T$="side."+C$:D=108:F=152:GOSUB 8
|
||||||
|
555 FOR I=1 TO 560: NEXT
|
||||||
|
'
|
||||||
|
' Maybe you'll find someone else
|
||||||
|
'
|
||||||
|
556 T$="May":F=102:GOSUB 8
|
||||||
|
558 T$="be ":D=54:F=91:GOSUB 8
|
||||||
|
560 T$="you'll ":D=162:F=85:GOSUB 8
|
||||||
|
562 T$="find ":D=108:F=102:GOSUB 8
|
||||||
|
564 T$="some":F=121:GOSUB 8
|
||||||
|
566 T$="one ":D=54:F=114:GOSUB 8
|
||||||
|
568 T$="else"+C$:D=162:F=102:GOSUB 8
|
||||||
|
570 T$="to ":D=54:F=152:GOSUB 8
|
||||||
|
572 T$="help ":D=108:F=152:GOSUB 8
|
||||||
|
574 T$="you."+C$:D=54:F=91:GOSUB 8
|
||||||
|
575 FOR I=1 TO 800:NEXT
|
||||||
|
'
|
||||||
|
' Black Mesa
|
||||||
|
'
|
||||||
|
576 GOSUB 18:GOSUB 15:HOME:GOSUB 2800: GOSUB 10:GOSUB 19:PRINT
|
||||||
|
'
|
||||||
|
' Maybe Black Mesa.
|
||||||
|
'
|
||||||
|
578 T$="May":F=85:GOSUB 8
|
||||||
|
580 T$="be ":F=91:GOSUB 8
|
||||||
|
582 T$="Black ":F=102:GOSUB 8
|
||||||
|
584 T$="Me":D=108:F=102:GOSUB 8
|
||||||
|
586 T$="sa.":D=54:F=91:GOSUB 8
|
||||||
|
587 FOR I=1 TO 800:NEXT I
|
||||||
|
'
|
||||||
|
' THAT WAS A JOKE.
|
||||||
|
'
|
||||||
|
588 T$=".."+C$:GOSUB 30
|
||||||
|
590 T$="THAT ":F=85:GOSUB 8
|
||||||
|
591 T$="WAS ":F=91:GOSUB 8
|
||||||
|
592 T$="A ":F=102:GOSUB 8
|
||||||
|
593 T$="JOKE.":F=102:GOSUB 8
|
||||||
|
594 FOR I=1 TO 160: NEXT
|
||||||
|
'
|
||||||
|
' HAHA
|
||||||
|
'
|
||||||
|
595 T$=" ":F=91:GOSUB 8
|
||||||
|
596 T$=" ":F=114:GOSUB 8
|
||||||
|
597 FOR I=1 TO 160: NEXT
|
||||||
|
'
|
||||||
|
' FAT CHANCE.
|
||||||
|
'
|
||||||
|
598 T$="FAT ":F=102:GOSUB 8
|
||||||
|
600 T$="CHANCE."+C$:D=108:F=152:GOSUB 8
|
||||||
|
601 FOR I=1 TO 560: NEXT
|
||||||
|
'
|
||||||
|
' Anyway, this cake is
|
||||||
|
'
|
||||||
|
602 T$="A":F=102:GOSUB 8
|
||||||
|
604 T$="ny":D=54:F=91:GOSUB 8
|
||||||
|
606 T$="way, ":D=162:F=85:GOSUB 8
|
||||||
|
608 T$="this ":D=108:F=102:GOSUB 8
|
||||||
|
610 T$="cake ":F=121:GOSUB 8
|
||||||
|
612 T$="is ":D=54:F=114:GOSUB 8
|
||||||
|
'
|
||||||
|
' CAKE
|
||||||
|
'
|
||||||
|
614 GOSUB 18:GOSUB 15:HOME:GOSUB 2900: GOSUB 10:GOSUB 19:PRINT
|
||||||
|
616 POKE 36,X
|
||||||
|
'
|
||||||
|
' great.
|
||||||
|
'
|
||||||
|
616 T$="great."+C$:F=102:GOSUB 8
|
||||||
|
617 FOR I=1 TO 80: NEXT
|
||||||
|
'
|
||||||
|
' It's so delicious and moist.
|
||||||
|
'
|
||||||
|
618 T$="It's ":F=152:GOSUB 8
|
||||||
|
620 T$="so ":F=114:GOSUB 8
|
||||||
|
622 T$="de":F=102:GOSUB 8
|
||||||
|
624 T$="li":F=96:GOSUB 8
|
||||||
|
626 T$="cious ":F=102:GOSUB 8
|
||||||
|
628 T$="and ":F=114:GOSUB 8
|
||||||
|
630 T$="moist."+C$:F=128:GOSUB 8
|
||||||
|
631 FOR I=1 TO 160: NEXT
|
||||||
|
'
|
||||||
|
' GLaDOS
|
||||||
|
'
|
||||||
|
632 GOSUB 18:GOSUB 15:HOME:GOSUB 3000: GOSUB 10:GOSUB 19:PRINT
|
||||||
|
'
|
||||||
|
' Look at me still talking.
|
||||||
|
'
|
||||||
|
634 T$="Look ":F=152:GOSUB 8
|
||||||
|
636 T$="at ":F=143:GOSUB 8
|
||||||
|
638 T$="me ":D=108:F=128:GOSUB 8
|
||||||
|
640 T$="still ":F=96:GOSUB 8
|
||||||
|
642 T$="tal":D=54:F=102:GOSUB 8
|
||||||
|
644 T$="king"+C$:F=114:GOSUB 8
|
||||||
|
'
|
||||||
|
' when there's
|
||||||
|
'
|
||||||
|
646 T$="when ":F=114:GOSUB 8
|
||||||
|
648 T$="there's ":F=128:GOSUB 8
|
||||||
|
'
|
||||||
|
' RADIATION
|
||||||
|
650 GOSUB 18:GOSUB 15:HOME:GOSUB 2100: GOSUB 10:GOSUB 19:PRINT
|
||||||
|
652 POKE 36,X
|
||||||
|
'
|
||||||
|
'Science to do.
|
||||||
|
'
|
||||||
|
654 T$="Sci":F=114:GOSUB 8
|
||||||
|
656 T$="ence ":F=128:GOSUB 8
|
||||||
|
658 T$="to ":D=108:F=128:GOSUB 8
|
||||||
|
660 T$="do."+C$:F=128:GOSUB 8
|
||||||
|
'
|
||||||
|
' APERTURE SCIENCE LOGO
|
||||||
|
'
|
||||||
|
662 GOSUB 18:GOSUB 15:HOME:GOSUB 2000: GOSUB 10:GOSUB 19:PRINT
|
||||||
|
'
|
||||||
|
' When I look out there
|
||||||
|
'
|
||||||
|
664 T$="When ":D=54:F=152:GOSUB 8
|
||||||
|
666 T$="I ":F=143:GOSUB 8
|
||||||
|
668 T$="look ":D=108:F=128:GOSUB 8
|
||||||
|
670 T$="out ":F=96:GOSUB 8
|
||||||
|
672 T$="there, "+C$:D=54:F=85:GOSUB 8
|
||||||
|
'
|
||||||
|
' it makes me GLaD I'm not you."+C$
|
||||||
|
'
|
||||||
|
674 T$="it ":F=96:GOSUB 8
|
||||||
|
676 T$="Makes ":F=102:GOSUB 8
|
||||||
|
678 T$="me ":F=114:GOSUB 8
|
||||||
|
680 T$="GLaD ":F=114:GOSUB 8
|
||||||
|
682 T$="I'm ":F=102:GOSUB 8
|
||||||
|
684 T$="not ":D=108:F=96:GOSUB 8
|
||||||
|
686 T$="you."+C$:F=96:GOSUB 8
|
||||||
|
'
|
||||||
|
' ATOM
|
||||||
|
'
|
||||||
|
688 GOSUB 18:GOSUB 15:HOME:GOSUB 2200: GOSUB 10:GOSUB 19:PRINT
|
||||||
|
'
|
||||||
|
' I've experiments to run.
|
||||||
|
'
|
||||||
|
690 T$="I've ":D=54:F=85:GOSUB 8
|
||||||
|
692 T$="ex":F=76:GOSUB 8
|
||||||
|
694 T$="pe":F=72:GOSUB 8
|
||||||
|
696 T$="ri":F=72:GOSUB 8
|
||||||
|
698 T$="ments ":F=76:GOSUB 8
|
||||||
|
700 T$="to ":F=85:GOSUB 8
|
||||||
|
702 T$="run."+C$:D=108:F=85:GOSUB 8
|
||||||
|
'
|
||||||
|
' EXPLOSION
|
||||||
|
'
|
||||||
|
704 GOSUB 18:GOSUB 15:HOME:GOSUB 2400: GOSUB 10:GOSUB 19:PRINT
|
||||||
|
'
|
||||||
|
' There is research to be done"
|
||||||
|
'
|
||||||
|
706 T$="There ":D=54:F=96:GOSUB 8
|
||||||
|
708 T$="is ":F=85:GOSUB 8
|
||||||
|
710 T$="re":F=76:GOSUB 8
|
||||||
|
712 T$="search ":F=76:GOSUB 8
|
||||||
|
714 T$="to ":F=85:GOSUB 8
|
||||||
|
716 T$="be ":F=96:GOSUB 8
|
||||||
|
718 T$="done."+C$:D=108:F=96:GOSUB 8
|
||||||
|
'
|
||||||
|
' APERTURE SCIENCE LOGO
|
||||||
|
'
|
||||||
|
720 GOSUB 18:GOSUB 15:HOME:GOSUB 2000: GOSUB 10:GOSUB 19:PRINT
|
||||||
|
'
|
||||||
|
' On the people who are
|
||||||
|
'
|
||||||
|
722 T$="On ":D=54:F=114:GOSUB 8
|
||||||
|
724 T$="the ":F=128:GOSUB 8
|
||||||
|
726 T$="peo":F=114:GOSUB 8
|
||||||
|
728 T$="ple ":F=96:GOSUB 8
|
||||||
|
730 T$="who ":F=96:GOSUB 8
|
||||||
|
732 T$="are"+C$:D=108:F=102:GOSUB 8
|
||||||
|
'
|
||||||
|
' still alive.
|
||||||
|
'
|
||||||
|
734 T$="still ":D=54:F=102:GOSUB 8
|
||||||
|
736 T$="a":F=91:GOSUB 8
|
||||||
|
738 T$="live."+C$:D=162:F=91:GOSUB 8
|
||||||
|
739 FOR I=1 TO 160: NEXT
|
||||||
|
'
|
||||||
|
'
|
||||||
|
'
|
||||||
|
740 HOME:PRINT:PRINT:PRINT
|
||||||
|
'
|
||||||
|
' PS: And believe me I am\nstill alive.
|
||||||
|
'
|
||||||
|
742 T$="PS: And ":D=54:F=76:GOSUB 8
|
||||||
|
744 T$="be":F=76:GOSUB 8
|
||||||
|
746 T$="lieve ":F=68:GOSUB 8
|
||||||
|
748 T$="me ":F=76:GOSUB 8
|
||||||
|
750 T$="I ":F=91:GOSUB 8
|
||||||
|
752 T$="am"+C$:D=108:F=114:GOSUB 8
|
||||||
|
754 T$="still ":D=54:F=102:GOSUB 8
|
||||||
|
756 T$="a":F=91:GOSUB 8
|
||||||
|
758 T$="live."+C$:D=162:F=91:GOSUB 8
|
||||||
|
759 FOR I=1 TO 240:NEXT
|
||||||
|
'
|
||||||
|
' PPS: I'm doing Science and I'm\nstill alive.
|
||||||
|
'
|
||||||
|
760 T$="PPS: ":GOSUB 30
|
||||||
|
762 T$="I'm ":D=54:F=76:GOSUB 8
|
||||||
|
764 T$="do":F=76:GOSUB 8
|
||||||
|
766 T$="ing ":F=76:GOSUB 8
|
||||||
|
768 T$="Sci":F=68:GOSUB 8
|
||||||
|
770 T$="ence ":F=76:GOSUB 8
|
||||||
|
772 T$="and ":F=91:GOSUB 8
|
||||||
|
774 T$="I'm"+C$:D=108:F=114:GOSUB 8
|
||||||
|
776 T$="still ":D=54:F=102:GOSUB 8
|
||||||
|
778 T$="a":F=91:GOSUB 8
|
||||||
|
780 T$="live."+C$:D=162:F=91:GOSUB 8
|
||||||
|
781 FOR I=1 TO 240:NEXT
|
||||||
|
'
|
||||||
|
' PPPS: I feel FANTASTIC and I'm\nstill alive
|
||||||
|
'
|
||||||
|
782 T$="PPPS: ":GOSUB 30
|
||||||
|
784 T$="I ":D=54:F=76:GOSUB 8
|
||||||
|
786 T$="feel ":F=76:GOSUB 8
|
||||||
|
788 T$="FAN":F=76:GOSUB 8
|
||||||
|
790 T$="TAS":F=68:GOSUB 8
|
||||||
|
792 T$="TIC ":F=76:GOSUB 8
|
||||||
|
794 T$="and ":F=91:GOSUB 8
|
||||||
|
796 T$="I'm"+C$:D=108:F=114:GOSUB 8
|
||||||
|
798 T$="still ":D=54:F=102:GOSUB 8
|
||||||
|
800 T$="a":F=91:GOSUB 8
|
||||||
|
802 T$="live."+C$:D=162:F=91:GOSUB 8
|
||||||
|
803 FOR I=1 TO 320:NEXT
|
||||||
|
804 PRINT
|
||||||
|
'
|
||||||
|
' FINAL THOUGHT:
|
||||||
|
'
|
||||||
|
806 T$="FINAL THOUGHT:"+C$:GOSUB 30
|
||||||
|
'
|
||||||
|
' While you're dying I'll be\nstill alive.
|
||||||
|
'
|
||||||
|
808 T$="While ":D=54:F=76:GOSUB 8
|
||||||
|
810 T$="you're ":F=76:GOSUB 8
|
||||||
|
812 T$="dy":F=68:GOSUB 8
|
||||||
|
814 T$="ing ":F=76:GOSUB 8
|
||||||
|
816 T$="I'll ":F=91:GOSUB 8
|
||||||
|
818 T$="be"+C$:D=108:F=114:GOSUB 8
|
||||||
|
820 T$="still ":D=54:F=102:GOSUB 8
|
||||||
|
822 T$="a":F=91:GOSUB 8
|
||||||
|
824 T$="live":D=162:F=91:GOSUB 8
|
||||||
|
825 FOR I=1 TO 240:NEXT
|
||||||
|
'
|
||||||
|
' FINAL THOUGHT PS
|
||||||
|
'
|
||||||
|
826 T$=C$+C$+"FINAL THOUGHT PS:"+C$:GOSUB 30
|
||||||
|
'
|
||||||
|
' And when you're dead I will be\nstill alive
|
||||||
|
'
|
||||||
|
828 T$="And ":D=54:F=76:GOSUB 8
|
||||||
|
830 T$="when ":F=76:GOSUB 8
|
||||||
|
832 T$="you're ":F=76:GOSUB 8
|
||||||
|
834 T$="dead ":F=68:GOSUB 8
|
||||||
|
836 T$="I ":F=76:GOSUB 8
|
||||||
|
838 T$="will ":F=91:GOSUB 8
|
||||||
|
840 T$="be"+C$:D=108:F=114:GOSUB 8
|
||||||
|
842 T$="still ":D=54:F=102:GOSUB 8
|
||||||
|
844 T$="a":F=91:GOSUB 8
|
||||||
|
846 T$="live"+C$:D=162:F=91:GOSUB 8
|
||||||
|
847 FOR I=1 TO 240:NEXT
|
||||||
|
'
|
||||||
|
'
|
||||||
|
'
|
||||||
|
848 PRINT:PRINT
|
||||||
|
'
|
||||||
|
' STILL ALIVE
|
||||||
|
'
|
||||||
|
850 T$="STILL ":D=54:F=85:GOSUB 8
|
||||||
|
851 T$="A":F=76:GOSUB 8
|
||||||
|
852 T$="LIVE":D=162:F=76:GOSUB 8
|
||||||
|
853 FOR I=1 TO 240:NEXT
|
||||||
|
854 PRINT:PRINT
|
||||||
|
'
|
||||||
|
' STILL ALIVE
|
||||||
|
'
|
||||||
|
855 T$=" ":D=54:F=85:GOSUB 8
|
||||||
|
856 T$=" ":F=91:GOSUB 8
|
||||||
|
857 T$=" ":D=162:F=91:GOSUB 8
|
||||||
|
858 FOR I=1 TO 240:NEXT
|
||||||
|
'
|
||||||
|
'
|
||||||
|
'
|
||||||
|
860 FOR I=1 TO 500:NEXT I
|
||||||
|
862 HOME
|
||||||
|
864 FOR I=1 TO 1000:NEXT I
|
||||||
|
866 T$="THANK YOU FOR PARTICIPATING"+C$:GOSUB 30
|
||||||
|
868 T$="IN THIS"+C$:GOSUB 30
|
||||||
|
870 T$="ENRICHMENT CENTER ACTIVITY!!"+C$:GOSUB 30
|
||||||
|
872 PRINT:PRINT
|
||||||
|
874 FOR I=1 TO 3000: NEXT I
|
||||||
|
1000 PRINT CHR$(4)+"PR#0"
|
||||||
|
1001 TEXT:HOME
|
||||||
|
1999 END
|
||||||
|
'
|
||||||
|
'
|
||||||
|
'
|
||||||
|
2000 REM APERTURE
|
||||||
|
2001 PRINT " .,-:;//;:=,"
|
||||||
|
2002 PRINT " . :H@@@MM@M#H/.,+%;,"
|
||||||
|
2003 PRINT " ,/X+ +M@@M@MM%=,-%HMMM@X/,"
|
||||||
|
2004 PRINT " -+@MM; $M@@MH+-,;XMMMM@MMMM@+-"
|
||||||
|
2005 PRINT " ;@M@@M- XM@X;. -+XXXXXHHH@M@M#@/."
|
||||||
|
2006 PRINT " ,%MM@@MH ,@%= .---=-=:=,."
|
||||||
|
2007 PRINT " =@#@@@MX ., -%HX$$%%%+;"
|
||||||
|
2008 PRINT " =-./@M@M$ .;@MMMM@MM:"
|
||||||
|
2009 PRINT " X@/ -$MM/ .+MM@@@M$"
|
||||||
|
2010 PRINT ",@M@H: :@: . =X#@@@@-";
|
||||||
|
2011 PRINT ",@@@MMX, . /H- ;@M@M=";
|
||||||
|
2012 PRINT ".H@@@@M@+, %MM+..%#$.";
|
||||||
|
2013 PRINT " /MMMM@MMH/. XM@MH; =;"
|
||||||
|
2014 PRINT " /%+%$XHH@$= , .H@@@@MX,"
|
||||||
|
2015 PRINT " .=--------. -%H.,@@@@@MX,"
|
||||||
|
2016 PRINT " .%MM@@@HHHXX$$$%+- .:$MMX =M@@MM%."
|
||||||
|
2017 PRINT " =XMMM@MM@MM#H;,-+HMM@M+ /MMMX="
|
||||||
|
2018 PRINT " =%@M@M#@$-.=$@MM@@@M; %M%="
|
||||||
|
2019 PRINT " ,:+$+-,/H#MMMMMMM@= =,"
|
||||||
|
2020 PRINT " =++%%%%+/:-."
|
||||||
|
2030 RETURN
|
||||||
|
'
|
||||||
|
2100 REM RADIOACTIVE
|
||||||
|
2101 PRINT " =+$HM####@H%;,"
|
||||||
|
2102 PRINT " /H###############M$,"
|
||||||
|
2103 PRINT " ,@################+"
|
||||||
|
2104 PRINT " .H##############+"
|
||||||
|
2105 PRINT " X############/"
|
||||||
|
2106 PRINT " $##########/"
|
||||||
|
2107 PRINT " %########/"
|
||||||
|
2108 PRINT " /X/;;+X/"
|
||||||
|
2109 PRINT
|
||||||
|
2110 PRINT " -XHHX-"
|
||||||
|
2111 PRINT " ,######,"
|
||||||
|
2112 PRINT "#############X .M####M. X#############";
|
||||||
|
2113 PRINT "##############- -//- -##############";
|
||||||
|
2114 PRINT "X##############%, ,+##############X";
|
||||||
|
2115 PRINT "-##############X X##############-";
|
||||||
|
2116 PRINT " %############% %############%"
|
||||||
|
2117 PRINT " %##########; ;##########%"
|
||||||
|
2118 PRINT " ;#######M= =M#######;"
|
||||||
|
2119 PRINT " .+M###@, ,@###M+."
|
||||||
|
2120 PRINT " :XH. .HX:"
|
||||||
|
2130 RETURN
|
||||||
|
'
|
||||||
|
2200 REM ATOM
|
||||||
|
2201 PRINT " =/;;/-"
|
||||||
|
2202 PRINT " +: //"
|
||||||
|
2203 PRINT " /; /;"
|
||||||
|
2204 PRINT " -X H."
|
||||||
|
2205 PRINT ".//;;;:;;-, X= :+ .-;:=;:;%;.";
|
||||||
|
2206 PRINT "M- ,=;;;#:, ,:#;;:=, ,@";
|
||||||
|
2207 PRINT ":% :%.=/++++/=.$= %=";
|
||||||
|
2208 PRINT " ,%; %/:+/;,,/++:+/ ;+."
|
||||||
|
2209 PRINT " ,+/. ,;@+, ,%H;, ,/+,"
|
||||||
|
2210 PRINT " ;+;;/= @. .H##X -X :///+;"
|
||||||
|
2211 PRINT " ;+=;;;.@, .XM@$. =X.//;=%/."
|
||||||
|
2212 PRINT " ,;: :@%= =$H: .+%-"
|
||||||
|
2213 PRINT " ,%= %;-///==///-// =%,"
|
||||||
|
2214 PRINT ";+ :%-;;;:;;;;-X- +:";
|
||||||
|
2215 PRINT "@- .-;;;;M- =M/;;;-. -X";
|
||||||
|
2216 PRINT " :;;::;;-. %- :+ ,-;;-;:=="
|
||||||
|
2217 PRINT " ,X H."
|
||||||
|
2218 PRINT " ;/ %="
|
||||||
|
2219 PRINT " // +;"
|
||||||
|
2220 PRINT " ,////,"
|
||||||
|
2230 RETURN
|
||||||
|
'
|
||||||
|
2300 REM BROKEN HEART
|
||||||
|
2301 PRINT " .,---."
|
||||||
|
2302 PRINT " ,/XM#MMMX;,"
|
||||||
|
2303 PRINT " -%##########M%,"
|
||||||
|
2304 PRINT " -@######% $###@="
|
||||||
|
2305 PRINT " .,--, -H#######$ $###M:"
|
||||||
|
2306 PRINT " ,;$M###MMX; .;##########$;HM###X=";
|
||||||
|
2307 PRINT " ,/@##########H= ;################+";
|
||||||
|
2308 PRINT "-+#############M/, %##############+";
|
||||||
|
2309 PRINT "%M###############= /##############:";
|
||||||
|
2310 PRINT "H################ .M#############;.";
|
||||||
|
2311 PRINT "@###############M ,@###########M:."
|
||||||
|
2312 PRINT "X################, -$=X#######@:"
|
||||||
|
2313 PRINT "/@##################%- +######$-"
|
||||||
|
2314 PRINT ".;##################X .X#####+,"
|
||||||
|
2315 PRINT " .;H################/ -X####+."
|
||||||
|
2316 PRINT " ,;X##############, .MM/"
|
||||||
|
2317 PRINT " ,:+$H@M#######M#$- .$$="
|
||||||
|
2318 PRINT " .,-=;+$@###X: ;/=."
|
||||||
|
2319 PRINT " .,/X$; .::,"
|
||||||
|
2320 PRINT " ., .."
|
||||||
|
2330 RETURN
|
||||||
|
'
|
||||||
|
2400 REM EXPLOSION
|
||||||
|
2401 PRINT " .+"
|
||||||
|
2402 PRINT " /M;"
|
||||||
|
2403 PRINT " H#@: ;,"
|
||||||
|
2404 PRINT " -###H- -@/"
|
||||||
|
2405 PRINT " %####$. -; .%#X"
|
||||||
|
2406 PRINT " M#####+;#H :M#M."
|
||||||
|
2407 PRINT ".. .+/;%#########X###-"
|
||||||
|
2408 PRINT " -/%H%+;-, +##############/"
|
||||||
|
2409 PRINT " .:$M###MH$%+############X ,--=;-"
|
||||||
|
2410 PRINT " -/H#####################H+=."
|
||||||
|
2411 PRINT " .+#################X."
|
||||||
|
2412 PRINT " =%M####################H;."
|
||||||
|
2413 PRINT " /@###############+;;/%%;,"
|
||||||
|
2414 PRINT " -%###################$."
|
||||||
|
2415 PRINT " ;H######################M="
|
||||||
|
2416 PRINT " ,%#####MH$%;+#####M###-/@####%"
|
||||||
|
2417 PRINT " :$H%+;=- -####X.,H# -+M##@-"
|
||||||
|
2418 PRINT " . ,###; ; =$##+"
|
||||||
|
2419 PRINT " .#H, :XH,"
|
||||||
|
2420 PRINT " + .;-";
|
||||||
|
2430 RETURN
|
||||||
|
'
|
||||||
|
2500 REM FIRE
|
||||||
|
2501 PRINT " -$-"
|
||||||
|
2502 PRINT " .H##H,"
|
||||||
|
2503 PRINT " +######+"
|
||||||
|
2504 PRINT " .+#########H."
|
||||||
|
2505 PRINT " -$############@."
|
||||||
|
2506 PRINT " =H###############@ -X:"
|
||||||
|
2507 PRINT " .$##################: @#@-"
|
||||||
|
2508 PRINT " ,; .M###################; H###;"
|
||||||
|
2509 PRINT " ;@#: @###################@ ,#####:"
|
||||||
|
2510 PRINT " -M###. M#################@. ;######H"
|
||||||
|
2511 PRINT " M####- +###############$ =@#######X"
|
||||||
|
2512 PRINT " H####$ -M###########+ :#########M,"
|
||||||
|
2513 PRINT " /####X- =########% :M########@/."
|
||||||
|
2514 PRINT " ,;%H@X; .$###X :##MM@%+;:-"
|
||||||
|
2515 PRINT " .."
|
||||||
|
2516 PRINT " -/;:-,. ,,-==+M########H"
|
||||||
|
2517 PRINT " -##################@HX%%+%%$%%%+:,,"
|
||||||
|
2518 PRINT " .-/H%%%+%%$H@###############M@+=:/+:";
|
||||||
|
2519 PRINT "/XHX%:#####MH%= ,---:;;;;/%%XHM,:###$";
|
||||||
|
2520 PRINT "$@#MX %+;- ."
|
||||||
|
2530 RETURN
|
||||||
|
'
|
||||||
|
2600 REM CHECK
|
||||||
|
2601 PRINT " :X-";
|
||||||
|
2602 PRINT " :X###"
|
||||||
|
2603 PRINT " ;@####@"
|
||||||
|
2604 PRINT " ;M######X"
|
||||||
|
2605 PRINT " -@########$"
|
||||||
|
2606 PRINT " .$##########@"
|
||||||
|
2607 PRINT " =M############-";
|
||||||
|
2608 PRINT " +##############$";
|
||||||
|
2609 PRINT " .H############$=."
|
||||||
|
2610 PRINT " ,/: ,M##########M;."
|
||||||
|
2611 PRINT " -+@###; =##########M;"
|
||||||
|
2612 PRINT " =%M#######; :#########M/"
|
||||||
|
2613 PRINT "-$M###########; :#########/"
|
||||||
|
2614 PRINT " ,;X###########; =########$."
|
||||||
|
2615 PRINT " ;H#########+#######M="
|
||||||
|
2616 PRINT " ,+##############+"
|
||||||
|
2617 PRINT " /M#########@-"
|
||||||
|
2618 PRINT " ;M######%"
|
||||||
|
2619 PRINT " +####:"
|
||||||
|
2620 PRINT " ,$M-"
|
||||||
|
2630 RETURN
|
||||||
|
'
|
||||||
|
2800 REM BLACK MESA
|
||||||
|
2801 PRINT " .-;+$XHHHHHHX$+;-."
|
||||||
|
2802 PRINT " ,;X@@X%/;=----=:/%X@@X/,"
|
||||||
|
2803 PRINT " =$@@%=. .=+H@X:"
|
||||||
|
2804 PRINT " -XMX: =XMX="
|
||||||
|
2805 PRINT " /@@: =H@+"
|
||||||
|
2806 PRINT " %@X, .$@$"
|
||||||
|
2807 PRINT " +@X. $@%"
|
||||||
|
2808 PRINT "-@@, .@@=";
|
||||||
|
2809 PRINT "%@% +@$";
|
||||||
|
2810 PRINT "H@: :@H";
|
||||||
|
2811 PRINT "H@: :HHHHHHHHHHHHHHHHHHX, =@H";
|
||||||
|
2812 PRINT "%@% ;@M@@@@@@@@@@@@@@@@@H- +@$";
|
||||||
|
2813 PRINT "=@@, :@@@@@@@@@@@@@@@@@@@@@= .@@:";
|
||||||
|
2814 PRINT " +@X :@@@@@@@@@@@@@@@M@@@@@@:%@%"
|
||||||
|
2815 PRINT " $@$, ;@@@@@@@@@@@@@@@@@M@@@@@@$."
|
||||||
|
2816 PRINT " +@@HHHHHHH@@@@@@@@@@@@@@@@@@@@@@@+"
|
||||||
|
2817 PRINT " =X@@@@@@@@@@@@@@@@@@@@@@@@@@@@X="
|
||||||
|
2818 PRINT " :$@@@@@@@@@@@@@@@@@@@M@@@@$:"
|
||||||
|
2819 PRINT " ,;$@@@@@@@@@@@@@@@@@@X/-"
|
||||||
|
2820 PRINT " .-;+$XXHHHHHX$+;-."
|
||||||
|
2830 RETURN
|
||||||
|
'
|
||||||
|
2900 REM CAKE DELICIOUS AND MOIST
|
||||||
|
2901 PRINT " ,:/+/-"
|
||||||
|
2902 PRINT " /M/ .,-=;//;-"
|
||||||
|
2903 PRINT " .:/= ;MH/, ,=/+%$XH@MM#@:"
|
||||||
|
2904 PRINT " -$##@+$###@H@MMM#######H:. -/H#";
|
||||||
|
2905 PRINT " .,H@H@ X######@ -H#####@+- -+H###@X";
|
||||||
|
2906 PRINT " .,@##H; +XM##M/, =%@###@X;-"
|
||||||
|
2907 PRINT "X%- :M##########$. .:%M###@%:"
|
||||||
|
2908 PRINT "M##H, +H@@@$/-. ,;$M###@%, -";
|
||||||
|
2909 PRINT "M####M=,,---,.-%%H####M$: ,+@##";
|
||||||
|
2910 PRINT "@##################@/. :%H##@$-"
|
||||||
|
2911 PRINT "M###############H, ;HM##M$="
|
||||||
|
2912 PRINT "#################. .=$M##M$="
|
||||||
|
2913 PRINT "################H..;XM##M$= .:+";
|
||||||
|
2914 PRINT "M###################@%= =+@MH%";
|
||||||
|
2915 PRINT "@################M/. =+H#X%="
|
||||||
|
2916 PRINT "=+M##############M, -/X#X+;."
|
||||||
|
2917 PRINT " .;XM##########H= ,/X#H+:,"
|
||||||
|
2918 PRINT " .=+HM######M+/+HM@+=."
|
||||||
|
2919 PRINT " ,:/%XM####H/."
|
||||||
|
2920 PRINT " ,.:=-."
|
||||||
|
2930 RETURN
|
||||||
|
'
|
||||||
|
3000 REM GLaDOS
|
||||||
|
3001 PRINT " #+ @ # # M#@"
|
||||||
|
3002 PRINT " . .X X.%##@;# # +@#######X. @#%"
|
||||||
|
3003 PRINT " ,==. ,######M+ -#####%M####M- #";
|
||||||
|
3004 PRINT " :H##M%:=##+ .M##M,;#####/+#######% ,M#";
|
||||||
|
3005 PRINT " .M########= =@#@.=#####M=M#######= X#";
|
||||||
|
3006 PRINT " :@@MMM##M. -##M.,#######M#######. = M";
|
||||||
|
3007 PRINT " @##..###:. .H####. @@ X,";
|
||||||
|
3008 PRINT " ############: ###,/####; /##= @#. M"
|
||||||
|
3009 PRINT " ,M## ;##,@#M;/M#M @# X#% X#"
|
||||||
|
3010 PRINT ".%= ######M## ##.M#: ./#M ,M #M ,#$"
|
||||||
|
3011 PRINT "##/ $## #+;#: #### ;#/ M M- @# :";
|
||||||
|
3012 PRINT "#+ #M@MM###M-;M #:$#-##$H# .#X @ + $#. #";
|
||||||
|
3013 PRINT " ######/.: #%=# M#:MM./#.-# @#: H#";
|
||||||
|
3014 PRINT "+,.= @###: /@ %#,@ ##@X #,-#@.##% .@#";
|
||||||
|
3015 PRINT "#####+;/##/ @## @#,+ /#M . X,"
|
||||||
|
3016 PRINT " ;###M#@ M###H .#M- ,##M ;@@; ###";
|
||||||
|
3017 PRINT " .M#M##H ;####X ,@#######M/ -M###$ -H";
|
||||||
|
3018 PRINT " .M###% X####H .@@MM@; ;@#M@"
|
||||||
|
3019 PRINT " H#M /@####/ ,++. / ==-,"
|
||||||
|
3020 PRINT " ,=/:, .+X@MMH@#H #####$=";
|
||||||
|
3030 RETURN
|
||||||
|
|
345
still_alive/interrupt_handler.s
Normal file
345
still_alive/interrupt_handler.s
Normal file
@ -0,0 +1,345 @@
|
|||||||
|
;================================
|
||||||
|
;================================
|
||||||
|
; mockingboard interrupt handler
|
||||||
|
;================================
|
||||||
|
;================================
|
||||||
|
; On Apple II/6502 the interrupt handler jumps to address in 0xfffe
|
||||||
|
; This is in the ROM, which saves the registers
|
||||||
|
; on older IIe it saved A to $45 (which could mess with DISK II)
|
||||||
|
; newer IIe doesn't do that.
|
||||||
|
; It then calculates if it is a BRK or not (which trashes A)
|
||||||
|
; Then it sets up the stack like an interrupt and calls 0x3fe
|
||||||
|
|
||||||
|
TIME_OFFSET EQU 13
|
||||||
|
|
||||||
|
interrupt_handler:
|
||||||
|
pha ; save A ; 3
|
||||||
|
; Should we save X and Y too?
|
||||||
|
|
||||||
|
; inc $0404 ; debug (flashes char onscreen)
|
||||||
|
|
||||||
|
bit $C404 ; clear 6522 interrupt by reading T1C-L ; 4
|
||||||
|
|
||||||
|
|
||||||
|
lda DONE_PLAYING ; 3
|
||||||
|
beq mb_play_music ; if song done, don't play music ; 3/2nt
|
||||||
|
jmp check_keyboard ; 3
|
||||||
|
;============
|
||||||
|
; 13
|
||||||
|
|
||||||
|
mb_play_music:
|
||||||
|
|
||||||
|
|
||||||
|
;======================================
|
||||||
|
; Write frames to Mockingboard
|
||||||
|
;======================================
|
||||||
|
; actually plays frame loaded at end of
|
||||||
|
; last interrupt, so 20ms behind?
|
||||||
|
|
||||||
|
mb_write_frame:
|
||||||
|
|
||||||
|
|
||||||
|
ldx #0 ; set up reg count ; 2
|
||||||
|
;============
|
||||||
|
; 2
|
||||||
|
|
||||||
|
;==================================
|
||||||
|
; loop through the 14 registers
|
||||||
|
; reading the value, then write out
|
||||||
|
;==================================
|
||||||
|
; inlined "write_ay_both" to save up to 156 (12*13) cycles
|
||||||
|
; unrolled
|
||||||
|
|
||||||
|
mb_write_loop:
|
||||||
|
lda REGISTER_DUMP,X ; load register value ; 4
|
||||||
|
cmp REGISTER_OLD,X ; compare with old values ; 4
|
||||||
|
beq mb_no_write ; 3/2nt
|
||||||
|
;=============
|
||||||
|
; typ 11
|
||||||
|
|
||||||
|
; special case R13. If it is 0xff, then don't update
|
||||||
|
; otherwise might spuriously reset the envelope settings
|
||||||
|
|
||||||
|
cpx #13 ; 2
|
||||||
|
bne mb_not_13 ; 3/2nt
|
||||||
|
cmp #$ff ; 2
|
||||||
|
beq mb_skip_13 ; 3/2nt
|
||||||
|
;============
|
||||||
|
; typ 5
|
||||||
|
mb_not_13:
|
||||||
|
|
||||||
|
; address
|
||||||
|
stx MOCK_6522_ORA1 ; put address on PA1 ; 4
|
||||||
|
stx MOCK_6522_ORA2 ; put address on PA2 ; 4
|
||||||
|
lda #MOCK_AY_LATCH_ADDR ; latch_address for PB1 ; 2
|
||||||
|
sta MOCK_6522_ORB1 ; latch_address on PB1 ; 4
|
||||||
|
sta MOCK_6522_ORB2 ; latch_address on PB2 ; 4
|
||||||
|
lda #MOCK_AY_INACTIVE ; go inactive ; 2
|
||||||
|
sta MOCK_6522_ORB1 ; 4
|
||||||
|
sta MOCK_6522_ORB2 ; 4
|
||||||
|
|
||||||
|
; value
|
||||||
|
lda REGISTER_DUMP,X ; load register value ; 4
|
||||||
|
sta MOCK_6522_ORA1 ; put value on PA1 ; 4
|
||||||
|
sta MOCK_6522_ORA2 ; put value on PA2 ; 4
|
||||||
|
lda #MOCK_AY_WRITE ; ; 2
|
||||||
|
sta MOCK_6522_ORB1 ; write on PB1 ; 4
|
||||||
|
sta MOCK_6522_ORB2 ; write on PB2 ; 4
|
||||||
|
lda #MOCK_AY_INACTIVE ; go inactive ; 2
|
||||||
|
sta MOCK_6522_ORB1 ; 4
|
||||||
|
sta MOCK_6522_ORB2 ; 4
|
||||||
|
|
||||||
|
;===========
|
||||||
|
; 62
|
||||||
|
mb_no_write:
|
||||||
|
inx ; point to next register ; 2
|
||||||
|
cpx #14 ; if 14 we're done ; 2
|
||||||
|
bmi mb_write_loop ; otherwise, loop ; 3/2nt
|
||||||
|
;============
|
||||||
|
; 7
|
||||||
|
mb_skip_13:
|
||||||
|
|
||||||
|
|
||||||
|
;=====================================
|
||||||
|
; Copy registers to old
|
||||||
|
;=====================================
|
||||||
|
ldx #13 ; 2
|
||||||
|
mb_reg_copy:
|
||||||
|
lda REGISTER_DUMP,X ; load register value ; 4
|
||||||
|
sta REGISTER_OLD,X ; compare with old values ; 4
|
||||||
|
dex ; 2
|
||||||
|
bpl mb_reg_copy ; 2nt/3
|
||||||
|
;=============
|
||||||
|
; 171
|
||||||
|
|
||||||
|
;===================================
|
||||||
|
; Load all 14 registers in advance
|
||||||
|
;===================================
|
||||||
|
; note, assuming not cross page boundary, not any slower
|
||||||
|
; then loading from zero page?
|
||||||
|
|
||||||
|
mb_load_values:
|
||||||
|
|
||||||
|
ldx #0 ; set up reg count ; 2
|
||||||
|
ldy MB_CHUNK_OFFSET ; get chunk offset ; 3
|
||||||
|
;=============
|
||||||
|
; 5
|
||||||
|
|
||||||
|
mb_load_loop:
|
||||||
|
lda (INL),y ; load register value ; 5
|
||||||
|
sta REGISTER_DUMP,X ; 4
|
||||||
|
;============
|
||||||
|
; 9
|
||||||
|
;====================
|
||||||
|
; point to next page
|
||||||
|
;====================
|
||||||
|
|
||||||
|
clc ; point to next interleaved ; 2
|
||||||
|
lda INH ; page by adding CHUNKSIZE (3/1); 3
|
||||||
|
adc CHUNKSIZE ; 3
|
||||||
|
sta INH ; 3
|
||||||
|
|
||||||
|
inx ; point to next register ; 2
|
||||||
|
cpx #14 ; if 14 we're done ; 2
|
||||||
|
bmi mb_load_loop ; otherwise, loop ; 3/2nt
|
||||||
|
;============
|
||||||
|
; 18
|
||||||
|
|
||||||
|
;=========================================
|
||||||
|
; if A_COARSE_TONE is $ff then we are done
|
||||||
|
|
||||||
|
lda A_COARSE_TONE ; 3
|
||||||
|
bpl mb_not_done ; 3/2nt
|
||||||
|
|
||||||
|
lda #1 ; set done playing ; 2
|
||||||
|
|
||||||
|
jmp quiet_exit ; 3
|
||||||
|
;===========
|
||||||
|
; typ 6
|
||||||
|
mb_not_done:
|
||||||
|
|
||||||
|
;==============================================
|
||||||
|
; incremement offset. If 0 move to next chunk
|
||||||
|
;==============================================
|
||||||
|
|
||||||
|
increment_offset:
|
||||||
|
|
||||||
|
inc MB_CHUNK_OFFSET ; increment offset ; 5
|
||||||
|
bne back_to_first_reg ; if not zero, done ; 3/2nt
|
||||||
|
|
||||||
|
|
||||||
|
;=====================
|
||||||
|
; move to next state
|
||||||
|
;=====================
|
||||||
|
|
||||||
|
clc
|
||||||
|
rol DECODER_STATE ; next state ; 5
|
||||||
|
; 20 -> 40 -> 80 -> c+00
|
||||||
|
bcs wraparound_to_a ; 3/2nt
|
||||||
|
|
||||||
|
bit DECODER_STATE ;bit7->N bit6->V
|
||||||
|
bvs back_to_first_reg ; do nothing on B ; 3/2nt
|
||||||
|
|
||||||
|
start_c:
|
||||||
|
lda #1
|
||||||
|
sta CHUNKSIZE
|
||||||
|
|
||||||
|
; setup next three chunks of song
|
||||||
|
|
||||||
|
lda #1 ; start decompressing
|
||||||
|
sta DECOMPRESS_TIME ; outside of handler
|
||||||
|
|
||||||
|
jmp back_to_first_reg
|
||||||
|
|
||||||
|
wraparound_to_a:
|
||||||
|
lda #$3
|
||||||
|
sta CHUNKSIZE
|
||||||
|
lda #$20
|
||||||
|
sta DECODER_STATE
|
||||||
|
sta COPY_TIME ; start copying
|
||||||
|
|
||||||
|
lda DECOMPRESS_TIME
|
||||||
|
beq blah
|
||||||
|
lda #1
|
||||||
|
sta DECODE_ERROR
|
||||||
|
blah:
|
||||||
|
;==============================
|
||||||
|
; After 14th reg, reset back to
|
||||||
|
; read R0 data
|
||||||
|
;==============================
|
||||||
|
|
||||||
|
back_to_first_reg:
|
||||||
|
lda #0 ; 2
|
||||||
|
bit DECODER_STATE ; 3
|
||||||
|
bmi back_to_first_reg_c ; 2nt/3
|
||||||
|
bvc back_to_first_reg_a ; 2nt/3
|
||||||
|
|
||||||
|
back_to_first_reg_b:
|
||||||
|
lda #$1 ; offset by 1
|
||||||
|
|
||||||
|
back_to_first_reg_a:
|
||||||
|
clc ; 2
|
||||||
|
adc #>UNPACK_BUFFER ; in proper chunk 1 or 2 ; 2
|
||||||
|
|
||||||
|
jmp update_r0_pointer ; 3
|
||||||
|
|
||||||
|
back_to_first_reg_c:
|
||||||
|
lda #>(UNPACK_BUFFER+$2A00) ; in linear C area ; 2
|
||||||
|
|
||||||
|
update_r0_pointer:
|
||||||
|
sta INH ; update r0 pointer ; 3
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
;=================================
|
||||||
|
; Finally done with this interrupt
|
||||||
|
;=================================
|
||||||
|
|
||||||
|
done_interrupt:
|
||||||
|
|
||||||
|
|
||||||
|
;=====================
|
||||||
|
; Update time counter
|
||||||
|
;=====================
|
||||||
|
update_time:
|
||||||
|
inc FRAME_COUNT ; 5
|
||||||
|
lda FRAME_COUNT ; 3
|
||||||
|
cmp #50 ; 3
|
||||||
|
bne done_time ; 3/2nt
|
||||||
|
|
||||||
|
lda #$0 ; 2
|
||||||
|
sta FRAME_COUNT ; 3
|
||||||
|
|
||||||
|
update_second_ones:
|
||||||
|
inc $7d0+TIME_OFFSET+3 ; 6
|
||||||
|
inc $bd0+TIME_OFFSET+3 ; 6
|
||||||
|
lda $bd0+TIME_OFFSET+3 ; 4
|
||||||
|
cmp #$ba ; one past '9' ; 2
|
||||||
|
bne done_time ; 3/2nt
|
||||||
|
lda #'0'+$80 ; 2
|
||||||
|
sta $7d0+TIME_OFFSET+3 ; 4
|
||||||
|
sta $bd0+TIME_OFFSET+3 ; 4
|
||||||
|
update_second_tens:
|
||||||
|
inc $7d0+TIME_OFFSET+2 ; 6
|
||||||
|
inc $bd0+TIME_OFFSET+2 ; 6
|
||||||
|
lda $bd0+TIME_OFFSET+2 ; 4
|
||||||
|
cmp #$b6 ; 6 (for 60 seconds) ; 2
|
||||||
|
bne done_time ; 3/2nt
|
||||||
|
lda #'0'+$80 ; 2
|
||||||
|
sta $7d0+TIME_OFFSET+2 ; 4
|
||||||
|
sta $bd0+TIME_OFFSET+2 ; 4
|
||||||
|
update_minutes:
|
||||||
|
inc $7d0+TIME_OFFSET ; 6
|
||||||
|
inc $bd0+TIME_OFFSET ; 6
|
||||||
|
; we don't handle > 9:59 songs yet
|
||||||
|
done_time:
|
||||||
|
;=============
|
||||||
|
; 90 worst
|
||||||
|
|
||||||
|
|
||||||
|
;=================================
|
||||||
|
; Moved visualization here as a hack
|
||||||
|
;=================================
|
||||||
|
|
||||||
|
;============================
|
||||||
|
; Visualization
|
||||||
|
;============================
|
||||||
|
|
||||||
|
check_keyboard:
|
||||||
|
|
||||||
|
jsr get_key
|
||||||
|
lda LASTKEY
|
||||||
|
beq exit_interrupt
|
||||||
|
|
||||||
|
cmp #(' '+$80)
|
||||||
|
bne key_left
|
||||||
|
key_space:
|
||||||
|
lda #$80
|
||||||
|
eor DONE_PLAYING
|
||||||
|
jmp quiet_exit
|
||||||
|
|
||||||
|
key_left:
|
||||||
|
cmp #'A'
|
||||||
|
bne key_right
|
||||||
|
|
||||||
|
lda #$40
|
||||||
|
bne quiet_exit
|
||||||
|
|
||||||
|
key_right:
|
||||||
|
cmp #'D'
|
||||||
|
bne done_key
|
||||||
|
|
||||||
|
lda #$20
|
||||||
|
bne quiet_exit
|
||||||
|
|
||||||
|
done_key:
|
||||||
|
jmp exit_interrupt
|
||||||
|
|
||||||
|
quiet_exit:
|
||||||
|
sta DONE_PLAYING
|
||||||
|
jsr clear_ay_both
|
||||||
|
|
||||||
|
;=====================================
|
||||||
|
; clear register area
|
||||||
|
;=====================================
|
||||||
|
ldx #13 ; 2
|
||||||
|
lda #0 ; 2
|
||||||
|
mb_clear_reg:
|
||||||
|
sta REGISTER_DUMP,X ; clear register value ; 4
|
||||||
|
sta REGISTER_OLD,X ; clear old values ; 4
|
||||||
|
dex ; 2
|
||||||
|
bpl mb_clear_reg ; 2nt/3
|
||||||
|
|
||||||
|
exit_interrupt:
|
||||||
|
|
||||||
|
pla ; restore a ; 4
|
||||||
|
|
||||||
|
rti ; return from interrupt ; 6
|
||||||
|
|
||||||
|
;============
|
||||||
|
; typical
|
||||||
|
; ???? cycles
|
||||||
|
|
||||||
|
|
||||||
|
REGISTER_OLD:
|
||||||
|
.byte 0,0,0,0,0,0,0,0,0,0,0,0,0,0
|
BIN
still_alive/still_alive.dsk
Normal file
BIN
still_alive/still_alive.dsk
Normal file
Binary file not shown.
558
still_alive/still_alive.s
Normal file
558
still_alive/still_alive.s
Normal file
@ -0,0 +1,558 @@
|
|||||||
|
; And Believe Me, I'm Still Alive
|
||||||
|
|
||||||
|
.include "zp.inc"
|
||||||
|
; program is ~4k, so from 0xc00 to 0x1C00
|
||||||
|
LZ4_BUFFER EQU $1C00 ; $1C00 - $5C00, 16k for now
|
||||||
|
UNPACK_BUFFER EQU $5E00 ; $5E00 - $9600, 14k, $3800
|
||||||
|
; trying not to hit DOS at $9600
|
||||||
|
; Reserve 3 chunks plus spare (14k)
|
||||||
|
|
||||||
|
NUM_FILES EQU 15
|
||||||
|
|
||||||
|
;=============================
|
||||||
|
; Setup
|
||||||
|
;=============================
|
||||||
|
jsr HOME
|
||||||
|
jsr TEXT
|
||||||
|
|
||||||
|
; init variables
|
||||||
|
|
||||||
|
lda #0
|
||||||
|
sta DRAW_PAGE
|
||||||
|
sta CH
|
||||||
|
sta CV
|
||||||
|
sta DONE_PLAYING
|
||||||
|
sta XPOS
|
||||||
|
sta MB_CHUNK_OFFSET
|
||||||
|
sta DECODE_ERROR
|
||||||
|
|
||||||
|
|
||||||
|
lda #0
|
||||||
|
sta WHICH_FILE
|
||||||
|
|
||||||
|
; print detection message
|
||||||
|
|
||||||
|
lda #<mocking_message ; load loading message
|
||||||
|
sta OUTL
|
||||||
|
lda #>mocking_message
|
||||||
|
sta OUTH
|
||||||
|
jsr move_and_print ; print it
|
||||||
|
|
||||||
|
jsr mockingboard_detect_slot4 ; call detection routine
|
||||||
|
cpx #$1
|
||||||
|
beq mockingboard_found
|
||||||
|
|
||||||
|
lda #<not_message ; if not found, print that
|
||||||
|
sta OUTL
|
||||||
|
lda #>not_message
|
||||||
|
sta OUTH
|
||||||
|
inc CV
|
||||||
|
jsr move_and_print
|
||||||
|
|
||||||
|
jmp forever_loop ; and wait forever
|
||||||
|
|
||||||
|
mockingboard_found:
|
||||||
|
; lda #<found_message ; print found message
|
||||||
|
; sta OUTL
|
||||||
|
; lda #>found_message
|
||||||
|
; sta OUTH
|
||||||
|
; inc CV
|
||||||
|
; jsr move_and_print
|
||||||
|
|
||||||
|
;============================
|
||||||
|
; Init the Mockingboard
|
||||||
|
;============================
|
||||||
|
|
||||||
|
jsr mockingboard_init
|
||||||
|
jsr reset_ay_both
|
||||||
|
jsr clear_ay_both
|
||||||
|
|
||||||
|
;=========================
|
||||||
|
; Setup Interrupt Handler
|
||||||
|
;=========================
|
||||||
|
; Vector address goes to 0x3fe/0x3ff
|
||||||
|
; FIXME: should chain any existing handler
|
||||||
|
|
||||||
|
lda #<interrupt_handler
|
||||||
|
sta $03fe
|
||||||
|
lda #>interrupt_handler
|
||||||
|
sta $03ff
|
||||||
|
|
||||||
|
;============================
|
||||||
|
; Enable 50Hz clock on 6522
|
||||||
|
;============================
|
||||||
|
|
||||||
|
sei ; disable interrupts just in case
|
||||||
|
|
||||||
|
lda #$40 ; Continuous interrupts, don't touch PB7
|
||||||
|
sta $C40B ; ACR register
|
||||||
|
lda #$7F ; clear all interrupt flags
|
||||||
|
sta $C40E ; IER register (interrupt enable)
|
||||||
|
|
||||||
|
lda #$C0
|
||||||
|
sta $C40D ; IFR: 1100, enable interrupt on timer one oflow
|
||||||
|
sta $C40E ; IER: 1100, enable timer one interrupt
|
||||||
|
|
||||||
|
lda #$E7
|
||||||
|
sta $C404 ; write into low-order latch
|
||||||
|
lda #$4f
|
||||||
|
sta $C405 ; write into high-order latch,
|
||||||
|
; load both values into counter
|
||||||
|
; clear interrupt and start counting
|
||||||
|
|
||||||
|
; 4fe7 / 1e6 = .020s, 50Hz
|
||||||
|
|
||||||
|
|
||||||
|
;============================
|
||||||
|
; Draw title screen
|
||||||
|
;============================
|
||||||
|
|
||||||
|
lda #$4 ; draw page 1
|
||||||
|
sta DRAW_PAGE
|
||||||
|
|
||||||
|
jsr clear_screens ; clear both screens
|
||||||
|
|
||||||
|
|
||||||
|
;==================
|
||||||
|
; load first song
|
||||||
|
;==================
|
||||||
|
|
||||||
|
jsr new_song
|
||||||
|
|
||||||
|
;============================
|
||||||
|
; Init Background
|
||||||
|
;============================
|
||||||
|
|
||||||
|
;============================
|
||||||
|
; Enable 6502 interrupts
|
||||||
|
;============================
|
||||||
|
|
||||||
|
cli ; clear interrupt mask
|
||||||
|
|
||||||
|
|
||||||
|
;============================
|
||||||
|
; Loop forever
|
||||||
|
;============================
|
||||||
|
main_loop:
|
||||||
|
lda DECODE_ERROR
|
||||||
|
beq check_copy
|
||||||
|
sei
|
||||||
|
brk
|
||||||
|
|
||||||
|
check_copy:
|
||||||
|
lda COPY_TIME
|
||||||
|
beq check_decompress ; if zero, skip
|
||||||
|
|
||||||
|
lda #0
|
||||||
|
sta COPY_OFFSET
|
||||||
|
check_copy_loop:
|
||||||
|
jsr page_copy ;6+3621
|
||||||
|
|
||||||
|
inc COPY_OFFSET ; (opt: make subtract?) ; 5
|
||||||
|
|
||||||
|
lda #14 ; NOT HEX URGH!
|
||||||
|
cmp COPY_OFFSET
|
||||||
|
bne check_copy_loop
|
||||||
|
|
||||||
|
lda #0 ; we are done
|
||||||
|
sta COPY_TIME
|
||||||
|
|
||||||
|
check_decompress:
|
||||||
|
lda DECOMPRESS_TIME
|
||||||
|
beq check_done ; if zero, skip
|
||||||
|
|
||||||
|
jsr setup_next_subsong ; decompress
|
||||||
|
|
||||||
|
lda MB_CHUNK_OFFSET
|
||||||
|
sta TIME_TAKEN
|
||||||
|
|
||||||
|
lda #0
|
||||||
|
sta DECOMPRESS_TIME
|
||||||
|
|
||||||
|
|
||||||
|
check_done:
|
||||||
|
lda #$ff
|
||||||
|
bit DONE_PLAYING
|
||||||
|
beq main_loop ; if was all zeros, loop
|
||||||
|
bmi main_loop ; if high bit set, paused
|
||||||
|
bvs minus_song ; if bit 6 set, then left pressed
|
||||||
|
|
||||||
|
; else, either song finished or
|
||||||
|
; right pressed
|
||||||
|
|
||||||
|
plus_song:
|
||||||
|
sei ; disable interrupts
|
||||||
|
jsr increment_file
|
||||||
|
jmp done_play
|
||||||
|
|
||||||
|
minus_song:
|
||||||
|
sei ; disable interrupts
|
||||||
|
jsr decrement_file
|
||||||
|
|
||||||
|
done_play:
|
||||||
|
|
||||||
|
lda #0
|
||||||
|
sta DONE_PLAYING
|
||||||
|
|
||||||
|
lda #0
|
||||||
|
sta CH
|
||||||
|
|
||||||
|
jsr clear_bottoms
|
||||||
|
|
||||||
|
jsr new_song
|
||||||
|
|
||||||
|
cli ; re-enable interrupts
|
||||||
|
|
||||||
|
jmp main_loop
|
||||||
|
|
||||||
|
forever_loop:
|
||||||
|
jmp forever_loop
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
;=================
|
||||||
|
; load a new song
|
||||||
|
;=================
|
||||||
|
|
||||||
|
new_song:
|
||||||
|
|
||||||
|
;=========================
|
||||||
|
; Init Variables
|
||||||
|
;=========================
|
||||||
|
|
||||||
|
lda #$0
|
||||||
|
sta FRAME_COUNT
|
||||||
|
sta A_VOLUME
|
||||||
|
sta B_VOLUME
|
||||||
|
sta C_VOLUME
|
||||||
|
sta COPY_OFFSET
|
||||||
|
sta DECOMPRESS_TIME
|
||||||
|
sta COPY_TIME
|
||||||
|
sta MB_CHUNK_OFFSET
|
||||||
|
lda #$20
|
||||||
|
sta DECODER_STATE
|
||||||
|
lda #3
|
||||||
|
sta CHUNKSIZE
|
||||||
|
|
||||||
|
;===========================
|
||||||
|
; Print loading message
|
||||||
|
;===========================
|
||||||
|
|
||||||
|
jsr clear_bottoms ; clear bottom of page 0/1
|
||||||
|
|
||||||
|
lda #0 ; print LOADING message
|
||||||
|
sta CH
|
||||||
|
lda #21
|
||||||
|
sta CV
|
||||||
|
|
||||||
|
lda #<loading_message
|
||||||
|
sta OUTL
|
||||||
|
lda #>loading_message
|
||||||
|
sta OUTH
|
||||||
|
jsr print_both_pages
|
||||||
|
|
||||||
|
|
||||||
|
;===========================
|
||||||
|
; Load in KRW file
|
||||||
|
;===========================
|
||||||
|
|
||||||
|
jsr get_filename
|
||||||
|
|
||||||
|
lda #8
|
||||||
|
sta CH
|
||||||
|
lda #21
|
||||||
|
sta CV
|
||||||
|
|
||||||
|
lda INL
|
||||||
|
sta OUTL
|
||||||
|
lda INH
|
||||||
|
sta OUTH
|
||||||
|
jsr print_both_pages
|
||||||
|
|
||||||
|
disk_buff EQU LZ4_BUFFER
|
||||||
|
read_size EQU $4000
|
||||||
|
|
||||||
|
jsr read_file ; read KRW file from disk
|
||||||
|
|
||||||
|
|
||||||
|
;=========================
|
||||||
|
; Print Info
|
||||||
|
;=========================
|
||||||
|
|
||||||
|
jsr clear_bottoms ; clear bottom of page 0/1
|
||||||
|
|
||||||
|
lda #>LZ4_BUFFER ; point to LZ4 data
|
||||||
|
sta OUTH
|
||||||
|
lda #<LZ4_BUFFER
|
||||||
|
sta OUTL
|
||||||
|
|
||||||
|
ldy #3 ; skip KRW magic at front
|
||||||
|
|
||||||
|
; print title
|
||||||
|
lda #20 ; VTAB 20: HTAB from file
|
||||||
|
jsr print_header_info
|
||||||
|
|
||||||
|
; Print Author
|
||||||
|
lda #21 ; VTAB 21: HTAB from file
|
||||||
|
jsr print_header_info
|
||||||
|
|
||||||
|
; Print clock
|
||||||
|
lda #23 ; VTAB 23: HTAB from file
|
||||||
|
jsr print_header_info
|
||||||
|
|
||||||
|
; Print Left Arrow (INVERSE)
|
||||||
|
lda #'<'
|
||||||
|
sta $750
|
||||||
|
sta $B50
|
||||||
|
|
||||||
|
lda #'-'
|
||||||
|
sta $751
|
||||||
|
sta $B51
|
||||||
|
|
||||||
|
; Print Rright Arrow (INVERSE)
|
||||||
|
lda #'-'
|
||||||
|
sta $776
|
||||||
|
sta $B76
|
||||||
|
|
||||||
|
lda #'>'
|
||||||
|
sta $777
|
||||||
|
sta $B77
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
; Point LZ4 src at proper place
|
||||||
|
|
||||||
|
ldy #0
|
||||||
|
lda #>(LZ4_BUFFER+3)
|
||||||
|
sta LZ4_SRC+1
|
||||||
|
lda #<(LZ4_BUFFER+3)
|
||||||
|
sta LZ4_SRC
|
||||||
|
|
||||||
|
lda (LZ4_SRC),Y ; get header skip
|
||||||
|
clc
|
||||||
|
adc LZ4_SRC
|
||||||
|
sta LZ4_SRC
|
||||||
|
lda LZ4_SRC+1
|
||||||
|
adc #0
|
||||||
|
sta LZ4_SRC+1
|
||||||
|
|
||||||
|
lda #<UNPACK_BUFFER ; set input pointer
|
||||||
|
sta INL
|
||||||
|
lda #>UNPACK_BUFFER
|
||||||
|
sta INH
|
||||||
|
|
||||||
|
; Decompress first chunks
|
||||||
|
|
||||||
|
lda #$0
|
||||||
|
sta COPY_OFFSET
|
||||||
|
sta DECOMPRESS_TIME
|
||||||
|
lda #$3
|
||||||
|
sta CHUNKSIZE
|
||||||
|
lda #$20
|
||||||
|
sta DECODER_STATE
|
||||||
|
sta COPY_TIME
|
||||||
|
|
||||||
|
jsr setup_next_subsong
|
||||||
|
|
||||||
|
rts
|
||||||
|
|
||||||
|
;=================
|
||||||
|
; next sub-song
|
||||||
|
;=================
|
||||||
|
setup_next_subsong:
|
||||||
|
|
||||||
|
ldy #0
|
||||||
|
|
||||||
|
lda (LZ4_SRC),Y ; get next size value
|
||||||
|
sta LZ4_END
|
||||||
|
iny
|
||||||
|
lda (LZ4_SRC),Y
|
||||||
|
sta LZ4_END+1
|
||||||
|
|
||||||
|
lda #2 ; increment pointer
|
||||||
|
clc
|
||||||
|
adc LZ4_SRC
|
||||||
|
sta LZ4_SRC
|
||||||
|
lda LZ4_SRC+1
|
||||||
|
adc #0
|
||||||
|
sta LZ4_SRC+1
|
||||||
|
|
||||||
|
jsr lz4_decode ; decode
|
||||||
|
|
||||||
|
; tail-call?
|
||||||
|
|
||||||
|
rts
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
;===================
|
||||||
|
; print header info
|
||||||
|
;===================
|
||||||
|
; shortcut to print header info
|
||||||
|
; a = VTAB
|
||||||
|
|
||||||
|
print_header_info:
|
||||||
|
|
||||||
|
sta CV
|
||||||
|
|
||||||
|
iny ; adjust pointer
|
||||||
|
tya
|
||||||
|
ldy #0
|
||||||
|
clc
|
||||||
|
adc OUTL
|
||||||
|
sta OUTL
|
||||||
|
lda OUTH
|
||||||
|
adc #$0
|
||||||
|
sta OUTH
|
||||||
|
|
||||||
|
lda (OUTL),Y ; get HTAB value
|
||||||
|
sta CH
|
||||||
|
|
||||||
|
inc OUTL ; increment 16-bits
|
||||||
|
bne bloop22
|
||||||
|
inc OUTH
|
||||||
|
bloop22:
|
||||||
|
|
||||||
|
jmp print_both_pages ; print, tail call
|
||||||
|
|
||||||
|
|
||||||
|
;==============================================
|
||||||
|
; plan: takes 256 50Hz to play a chunk
|
||||||
|
; need to copy 14 256-byte blocks
|
||||||
|
; PLAY A (copying C)
|
||||||
|
; PLAY B (copying C)
|
||||||
|
; PLAY D (decompressing A/B/C)
|
||||||
|
|
||||||
|
|
||||||
|
;========================
|
||||||
|
; page copy
|
||||||
|
;========================
|
||||||
|
; want to copy:
|
||||||
|
; SRC: chunk_buffer+(2*256)+(COPY_OFFSET*3*256)
|
||||||
|
; DST: chunk_buffer+$2A00+(COPY_OFFSET*256)
|
||||||
|
page_copy:
|
||||||
|
clc ; 2
|
||||||
|
lda #>(UNPACK_BUFFER+512) ; 3
|
||||||
|
adc COPY_OFFSET ; 3
|
||||||
|
adc COPY_OFFSET ; 3
|
||||||
|
adc COPY_OFFSET ; 3
|
||||||
|
sta page_copy_loop+2 ; self modify ; 5
|
||||||
|
|
||||||
|
lda #>(UNPACK_BUFFER+$2A00) ; 2
|
||||||
|
adc COPY_OFFSET ; 3
|
||||||
|
sta page_copy_loop+5 ; self modify ; 5
|
||||||
|
|
||||||
|
ldx #$00 ; 2
|
||||||
|
page_copy_loop:
|
||||||
|
lda $1000,x ; 4
|
||||||
|
sta $1000,X ; 5
|
||||||
|
inx ; 2
|
||||||
|
bne page_copy_loop ; 2nt/3
|
||||||
|
rts ; 6
|
||||||
|
;======================
|
||||||
|
; 2+14*256+6+29= 3621
|
||||||
|
|
||||||
|
|
||||||
|
;==================
|
||||||
|
; Get filename
|
||||||
|
;==================
|
||||||
|
; WHICH_FILE holds number
|
||||||
|
; MAX_FILES has max
|
||||||
|
; Scroll through until find
|
||||||
|
; point INH:INL to it
|
||||||
|
get_filename:
|
||||||
|
|
||||||
|
ldy #0
|
||||||
|
ldx WHICH_FILE
|
||||||
|
|
||||||
|
lda #<krw_file ; point to filename
|
||||||
|
sta INL
|
||||||
|
lda #>krw_file
|
||||||
|
sta INH
|
||||||
|
|
||||||
|
get_filename_loop:
|
||||||
|
cpx #0
|
||||||
|
beq filename_found
|
||||||
|
|
||||||
|
inner_loop:
|
||||||
|
iny
|
||||||
|
lda (INL),Y
|
||||||
|
bne inner_loop
|
||||||
|
|
||||||
|
iny
|
||||||
|
|
||||||
|
dex
|
||||||
|
jmp get_filename_loop
|
||||||
|
|
||||||
|
filename_found:
|
||||||
|
tya
|
||||||
|
clc
|
||||||
|
adc INL
|
||||||
|
sta INL
|
||||||
|
lda INH
|
||||||
|
adc #0
|
||||||
|
sta INH
|
||||||
|
|
||||||
|
rts
|
||||||
|
|
||||||
|
;===============================
|
||||||
|
; Increment file we want to load
|
||||||
|
;===============================
|
||||||
|
increment_file:
|
||||||
|
inc WHICH_FILE
|
||||||
|
lda WHICH_FILE
|
||||||
|
cmp #NUM_FILES
|
||||||
|
bne done_increment
|
||||||
|
lda #0
|
||||||
|
sta WHICH_FILE
|
||||||
|
done_increment:
|
||||||
|
rts
|
||||||
|
|
||||||
|
;===============================
|
||||||
|
; Decrement file we want to load
|
||||||
|
;===============================
|
||||||
|
decrement_file:
|
||||||
|
dec WHICH_FILE
|
||||||
|
bpl done_decrement
|
||||||
|
lda #(NUM_FILES-1)
|
||||||
|
sta WHICH_FILE
|
||||||
|
done_decrement:
|
||||||
|
rts
|
||||||
|
|
||||||
|
;==========
|
||||||
|
; filenames
|
||||||
|
;==========
|
||||||
|
krw_file:
|
||||||
|
.asciiz "SA.KRW"
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
;=========
|
||||||
|
;routines
|
||||||
|
;=========
|
||||||
|
.include "../asm_routines/gr_offsets.s"
|
||||||
|
.include "../asm_routines/text_print.s"
|
||||||
|
.include "../asm_routines/mockingboard_a.s"
|
||||||
|
.include "../asm_routines/gr_fast_clear.s"
|
||||||
|
.include "../asm_routines/pageflip.s"
|
||||||
|
.include "../asm_routines/gr_setpage.s"
|
||||||
|
.include "../asm_routines/dos33_routines.s"
|
||||||
|
.include "../asm_routines/gr_hlin.s"
|
||||||
|
.include "../asm_routines/lz4_decode.s"
|
||||||
|
.include "../asm_routines/keypress_minimal.s"
|
||||||
|
|
||||||
|
.include "interrupt_handler.s"
|
||||||
|
|
||||||
|
;=========
|
||||||
|
; strings
|
||||||
|
;=========
|
||||||
|
mocking_message: .asciiz "LOOKING FOR MOCKINGBOARD IN SLOT #4"
|
||||||
|
not_message: .byte "NOT "
|
||||||
|
found_message: .asciiz "FOUND"
|
||||||
|
;done_message: .asciiz "DONE PLAYING"
|
||||||
|
loading_message: .asciiz "LOADING"
|
||||||
|
|
||||||
|
.include "ascii_art.inc"
|
251
still_alive/zp.inc
Normal file
251
still_alive/zp.inc
Normal file
@ -0,0 +1,251 @@
|
|||||||
|
.define EQU =
|
||||||
|
|
||||||
|
LZ4_SRC EQU $00
|
||||||
|
LZ4_DST EQU $02
|
||||||
|
LZ4_END EQU $04
|
||||||
|
COUNT EQU $06
|
||||||
|
DELTA EQU $08
|
||||||
|
|
||||||
|
;; Zero page monitor routines addresses
|
||||||
|
|
||||||
|
WNDLFT EQU $20
|
||||||
|
WNDWDTH EQU $21
|
||||||
|
WNDTOP EQU $22
|
||||||
|
WNDBTM EQU $23
|
||||||
|
CH EQU $24
|
||||||
|
CV EQU $25
|
||||||
|
GBASL EQU $26
|
||||||
|
GBASH EQU $27
|
||||||
|
BASL EQU $28
|
||||||
|
BASH EQU $29
|
||||||
|
H2 EQU $2C
|
||||||
|
V2 EQU $2D
|
||||||
|
MASK EQU $2E
|
||||||
|
COLOR EQU $30
|
||||||
|
;INVFLG EQU $32
|
||||||
|
|
||||||
|
; dos33 zero page = 26-2f, 35-38, 3e 3f 40-4d
|
||||||
|
; overlap applesoft 67-6a,6f,70,af,b0,ca-cd,d8
|
||||||
|
|
||||||
|
|
||||||
|
; DOS33: Confirmed kills $68
|
||||||
|
|
||||||
|
RWTSL EQU $60
|
||||||
|
RWTSH EQU $61
|
||||||
|
DOSBUFL EQU $62
|
||||||
|
DOSBUFH EQU $63
|
||||||
|
FILEML EQU $64
|
||||||
|
FILEMH EQU $65
|
||||||
|
;TURNING EQU $60
|
||||||
|
;SCREEN_X EQU $61 ; not used?
|
||||||
|
;SCREEN_Y EQU $62
|
||||||
|
|
||||||
|
|
||||||
|
;ANGLE EQU $63
|
||||||
|
;HORIZ_SCALE_I EQU $64
|
||||||
|
;HORIZ_SCALE_F EQU $65
|
||||||
|
;FACTOR_I EQU $66
|
||||||
|
;FACTOR_F EQU $67
|
||||||
|
;DX_I EQU $68
|
||||||
|
;DX_F EQU $69
|
||||||
|
;SPACEX_I EQU $6A
|
||||||
|
;SPACEX_F EQU $6B
|
||||||
|
;CX_I EQU $6C
|
||||||
|
;CX_F EQU $6D
|
||||||
|
;DY_I EQU $6E
|
||||||
|
;DY_F EQU $6F
|
||||||
|
|
||||||
|
REGISTER_DUMP EQU $70
|
||||||
|
A_FINE_TONE EQU $70
|
||||||
|
A_COARSE_TONE EQU $71
|
||||||
|
B_FINE_TONE EQU $72
|
||||||
|
B_COARSE_TONE EQU $73
|
||||||
|
C_FINE_TONE EQU $74
|
||||||
|
C_COARSE_TONE EQU $75
|
||||||
|
NOISE EQU $76
|
||||||
|
ENABLE EQU $77
|
||||||
|
A_VOLUME EQU $78
|
||||||
|
B_VOLUME EQU $79
|
||||||
|
C_VOLUME EQU $7A
|
||||||
|
ENVELOPE_FINE EQU $7B
|
||||||
|
ENVELOPE_COARSE EQU $7C
|
||||||
|
ENVELOPE_SHAPE EQU $7D
|
||||||
|
COPY_OFFSET EQU $7E
|
||||||
|
DECODER_STATE EQU $7F
|
||||||
|
;SPACEY_I EQU $70
|
||||||
|
;SPACEY_F EQU $71
|
||||||
|
;CY_I EQU $72
|
||||||
|
;CY_F EQU $73
|
||||||
|
;TEMP_I EQU $74
|
||||||
|
;TEMP_F EQU $75
|
||||||
|
;DISTANCE_I EQU $76
|
||||||
|
;DISTANCE_F EQU $77
|
||||||
|
;SPACEZ_I EQU $78
|
||||||
|
;SPACEZ_F EQU $79
|
||||||
|
;DRAW_SPLASH EQU $7A
|
||||||
|
;SPEED EQU $7B
|
||||||
|
;SPLASH_COUNT EQU $7C
|
||||||
|
;OVER_LAND EQU $7D
|
||||||
|
;NUM1L EQU $7E
|
||||||
|
;NUM1H EQU $7F
|
||||||
|
CHUNKSIZE EQU $80
|
||||||
|
LZ4_DONE EQU $81
|
||||||
|
DECODE_ERROR EQU $82
|
||||||
|
|
||||||
|
A_COLOR EQU $83
|
||||||
|
B_COLOR EQU $84
|
||||||
|
C_COLOR EQU $85
|
||||||
|
COPY_TIME EQU $86
|
||||||
|
DECOMPRESS_TIME EQU $87
|
||||||
|
TIME_TAKEN EQU $88
|
||||||
|
SCREEN_Y EQU $89
|
||||||
|
WHICH_FILE EQU $8A
|
||||||
|
;NUM2L EQU $80
|
||||||
|
;NUM2H EQU $81
|
||||||
|
;RESULT EQU $82 ; 83,84,85
|
||||||
|
;NEGATE EQU $86 ; UNUSED?
|
||||||
|
;LAST_SPACEX_I EQU $87
|
||||||
|
;LAST_SPACEY_I EQU $88
|
||||||
|
;LAST_MAP_COLOR EQU $89
|
||||||
|
;DRAW_SKY EQU $8A
|
||||||
|
COLOR_MASK EQU $8B
|
||||||
|
RASTERBARS_ON EQU $8C
|
||||||
|
;KEY_COUNT EQU $8C
|
||||||
|
;KEY_OFFSET EQU $8D
|
||||||
|
;DRAW_BLUE_SKY EQU $8E
|
||||||
|
RANDOM_POINTER EQU $8F
|
||||||
|
FRAME_COUNT EQU $90
|
||||||
|
MB_VALUE EQU $91
|
||||||
|
;MB_CHUNK EQU $92
|
||||||
|
MB_ADDRL EQU $91
|
||||||
|
MB_ADDRH EQU $92
|
||||||
|
DONE_PLAYING EQU $93
|
||||||
|
;MB_FRAME_DIFF EQU $94
|
||||||
|
MB_CHUNK_OFFSET EQU $94
|
||||||
|
;LZSS_RL EQU $95
|
||||||
|
;LZSS_RH EQU $96
|
||||||
|
;LZSS_COUNT EQU $97
|
||||||
|
;LZSS_MASK EQU $98
|
||||||
|
;LZSS_ENDL EQU $99
|
||||||
|
;LZSS_ENDH EQU $9A
|
||||||
|
;MB_FRAME_DIFF2 EQU $9F
|
||||||
|
|
||||||
|
; More zero-page addresses
|
||||||
|
; we try not to conflict with anything DOS, MONITOR or BASIC related
|
||||||
|
|
||||||
|
;COLOR1 EQU $E0
|
||||||
|
COLOR2 EQU $E1
|
||||||
|
;MATCH EQU $E2
|
||||||
|
XX EQU $E3
|
||||||
|
;YY EQU $E4
|
||||||
|
;SHIPY EQU $E4
|
||||||
|
;YADD EQU $E5
|
||||||
|
;LOOP EQU $E6
|
||||||
|
;MEMPTRL EQU $E7
|
||||||
|
;MEMPTRH EQU $E8
|
||||||
|
;NAMEL EQU $E9
|
||||||
|
;NAMEH EQU $EA
|
||||||
|
;NAMEX EQU $EB
|
||||||
|
;CHAR EQU $EC
|
||||||
|
DISP_PAGE EQU $ED
|
||||||
|
DRAW_PAGE EQU $EE
|
||||||
|
|
||||||
|
;FIRST EQU $F0
|
||||||
|
LASTKEY EQU $F1
|
||||||
|
;PADDLE_STATUS EQU $F2
|
||||||
|
XPOS EQU $F3
|
||||||
|
YPOS EQU $F4
|
||||||
|
TEMP EQU $FA
|
||||||
|
;RUN EQU $FA
|
||||||
|
;TEMP2 EQU $FB
|
||||||
|
TEMPY EQU $FB
|
||||||
|
INL EQU $FC
|
||||||
|
INH EQU $FD
|
||||||
|
OUTL EQU $FE
|
||||||
|
OUTH EQU $FF
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
KEYPRESS EQU $C000
|
||||||
|
KEYRESET EQU $C010
|
||||||
|
|
||||||
|
;; SOFT SWITCHES
|
||||||
|
CLR80COL EQU $C000 ; PAGE0/PAGE1 normal
|
||||||
|
SET80COL EQU $C001 ; PAGE0/PAGE1 switches PAGE0 in Aux instead
|
||||||
|
EIGHTYCOL EQU $C00D
|
||||||
|
SPEAKER EQU $C030
|
||||||
|
SET_GR EQU $C050
|
||||||
|
SET_TEXT EQU $C051
|
||||||
|
FULLGR EQU $C052
|
||||||
|
TEXTGR EQU $C053
|
||||||
|
PAGE0 EQU $C054
|
||||||
|
PAGE1 EQU $C055
|
||||||
|
LORES EQU $C056 ; Enable LORES graphics
|
||||||
|
HIRES EQU $C057 ; Enable HIRES graphics
|
||||||
|
AN3 EQU $C05E ; Annunciator 3
|
||||||
|
|
||||||
|
PADDLE_BUTTON0 EQU $C061
|
||||||
|
PADDL0 EQU $C064
|
||||||
|
PTRIG EQU $C070
|
||||||
|
|
||||||
|
;; BASIC ROUTINES
|
||||||
|
|
||||||
|
NORMAL EQU $F273
|
||||||
|
|
||||||
|
;; MONITOR ROUTINES
|
||||||
|
|
||||||
|
HLINE EQU $F819 ;; HLINE Y,$2C at A
|
||||||
|
VLINE EQU $F828 ;; VLINE A,$2D at Y
|
||||||
|
CLRSCR EQU $F832 ;; Clear low-res screen
|
||||||
|
CLRTOP EQU $F836 ;; clear only top of low-res screen
|
||||||
|
SETCOL EQU $F864 ;; COLOR=A
|
||||||
|
TEXT EQU $FB36
|
||||||
|
TABV EQU $FB5B ;; VTAB to A
|
||||||
|
BASCALC EQU $FBC1 ;;
|
||||||
|
VTAB EQU $FC22 ;; VTAB to CV
|
||||||
|
HOME EQU $FC58 ;; Clear the text screen
|
||||||
|
WAIT EQU $FCA8 ;; delay 1/2(26+27A+5A^2) us
|
||||||
|
SETINV EQU $FE80 ;; INVERSE
|
||||||
|
SETNORM EQU $FE84 ;; NORMAL
|
||||||
|
COUT EQU $FDED ;; output A to screen
|
||||||
|
COUT1 EQU $FDF0 ;; output A to screen
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
COLOR_BLACK EQU 0
|
||||||
|
COLOR_RED EQU 1
|
||||||
|
COLOR_DARKBLUE EQU 2
|
||||||
|
COLOR_PURPLE EQU 3
|
||||||
|
COLOR_DARKGREEN EQU 4
|
||||||
|
COLOR_GREY EQU 5
|
||||||
|
COLOR_MEDIUMBLUE EQU 6
|
||||||
|
COLOR_LIGHTBLUE EQU 7
|
||||||
|
COLOR_BROWN EQU 8
|
||||||
|
COLOR_ORANGE EQU 9
|
||||||
|
COLOR_GREY2 EQU 10
|
||||||
|
COLOR_PINK EQU 11
|
||||||
|
COLOR_LIGHTGREEN EQU 12
|
||||||
|
COLOR_YELLOW EQU 13
|
||||||
|
COLOR_AQUA EQU 14
|
||||||
|
COLOR_WHITE EQU 15
|
||||||
|
|
||||||
|
COLOR_BOTH_BLACK EQU $00
|
||||||
|
COLOR_BOTH_RED EQU $11
|
||||||
|
COLOR_BOTH_DARKBLUE EQU $22
|
||||||
|
COLOR_BOTH_DARKGREEN EQU $44
|
||||||
|
COLOR_BOTH_GREY EQU $55
|
||||||
|
COLOR_BOTH_MEDIUMBLUE EQU $66
|
||||||
|
COLOR_BOTH_LIGHTBLUE EQU $77
|
||||||
|
COLOR_BOTH_BROWN EQU $88
|
||||||
|
COLOR_BOTH_ORANGE EQU $99
|
||||||
|
COLOR_BOTH_PINK EQU $BB
|
||||||
|
COLOR_BOTH_LIGHTGREEN EQU $CC
|
||||||
|
COLOR_BOTH_YELLOW EQU $DD
|
||||||
|
COLOR_BOTH_AQUA EQU $EE
|
||||||
|
COLOR_BOTH_WHITE EQU $FF
|
||||||
|
|
||||||
|
AUX_BOTH_MEDIUMBLUE EQU $33 ; 0011 0011
|
||||||
|
AUX_BOTH_GREY EQU $AA ; 1010 1010
|
Loading…
x
Reference in New Issue
Block a user