Re: [stella] disassemblies and other stuff

Subject: Re: [stella] disassemblies and other stuff
From: Erik Mooney <emooney@xxxxxxxxxxxxxxxx>
Date: Mon, 8 Jan 2001 17:06:05 -0500
> I was wondering if there was a sure-fire disassembly method out there
> anyone could share with me.  The two methods I know of are diStella and
> using PCAtari.
>
> I tried disassembling Super Challenge Football with diStella and it left
> large patches.

Well, you could do it by hand, or use Distella and do the chunks it leaves
by hand...

> SCF won't even run on PCAtari for some reason.  It runs fine on Stella so I
> have to assume it's the emulator, not the ROM image.

Really?  I'm sure I've run it on PC Atari before.  I know it doesn't work
on an unmodified Supercharger, if that means anything.  I'm pretty sure
it's a standard 4k game, no RAM in the cart or anything.

> I'd like to get a good disassembly of that, Surround, and Indy500.

I find that disassemblies really don't help all that much for programming.
It can be neat to see how a game does a certain effect, but I haven't yet
seen a case where I couldn't figure that out by deduction and Stella's
ability to turn off specified graphical elements.

> Speaking of Surround, or any pseudobitmap game, generally speaking, what's
> the best approach to storing and accessing the bitmap?
>
> So far in my game I'm setting the playfield mode to reflect and will only
> update PF1 and PF2.
>
> What is the safe range of cycle counts for rewriting these registers?

I don't recall it offhand, but I've posted it to the list before.  I think
it's also in the comments in the code for INV, you could check that.

> Also, there is a lot of "reinventing the wheel" I seem to be easing into
> regarding simple assembly algorithms.  Is there somewhere I could go that
> has a lot of general routines that everybody always uses??

The only procedures I've used that I didn't write myself were the VSYNC
setup and timer from How to Draw a Playfield (hi Nick), and the six-digit
score routine.  Nick's page and the source codes in there (and in the list
archives) are pretty much the only place that has anything resembling a
library of general routines.  Assembly stuff almost always has to be
handcrafted for its specific purpose.

> For instance, In modifying How to Draw a Playfield, I want to change the
> playfield graphics every 8 scanlines, but the scanline kernel still needs
> to update the sprites every scanline (visually, every two if I use the
> usual VDEL routines to produce 2-scanline tall sprites).
>
> I'm not worrying about the sprites right now but I need to leave room in
> the kernel for them later.  The only tricky sprite stuff will be the
> missiles as the horizontal position and width need to change from scanline
> to scanline.  The cars are like Combat, with the horizontal positions pre
> calculated once before screentime begins.  I know there is enough time for
> this kernel as Super Challenge Football features a nonreflective
> (scrolling, which I won't do) playfield and the missile tricks.

Look closely at SCF.  It uses a repeated playfield.  It looks a bit
asymmetrical because there is a HMOVE black line at the left of every
scanline, but it's repeated.

> But anyway, for things like this, my immediate thinking process is:
>
> I switched around Nick's code to count up instead of down.  This is going
> to make things a lot easier for me to conceptualize the screen.  (I realize
> that counting down has benefits in that the branch routines test for zero.):
>
> if scanlinecounter is divisible by 8

Okay, there's three ways you can go here.   One is your way, testing for
divisibility by 8 every time.

Another way is to use nested loops, like
Loop1:
[do border stuff]
Loop2:
LDY #8
do PF1/PF2/WSYNC
DEY
BNE Loop2
Add 8 to Scanlinecounter
CMP #192
BNE Loop1

The other way to do it, and you'll need to do this if you want more
complexity in the kernel (I had to do tons of this kind of thing in the
INV kernel), is to unroll the inner loop.

Loop:
[do border stuff]
do PF1/PF2/sprites/WSYNC
do PF1/PF2/sprites/WSYNC
do PF1/PF2/sprites/WSYNC
do PF1/PF2/sprites/WSYNC
do PF1/PF2/sprites/WSYNC
do PF1/PF2/sprites/WSYNC
do PF1/PF2/sprites/WSYNC
do PF1/PF2/sprites/WSYNC
add 8 to scanlinecounter
CMP #192
BNE Loop

This is how I'd set it up.  It takes more ROM space, but that is fairly
plentiful if you aren't restricting yourself to 4k, using either
Supercharger multiload (or even flat 6k), or 16k/32k/Megacart (hi Chris
Wilkson) bankswitch.  It takes a lot less branching-and-checking code, and
you can also spread out the housekeeping code among the 8 scanlines.
Like, say, your border-update routine took 20 instructions per 8-line
block.  You could put 2 or 3 of those instructions in each scanline, when
you have time between playfield and sprite rewrites.  (Hi Piero, I'm sure
Oystron needs to do this sort of thing too :) )

> So I'm thinking, what's an easy way to figure out if a number is divisible
> (evenly) by another number?
> I played around with Nick's LSR/AND stuff but I don't quite understand what
> it's doing, as I'm thinking more in terms of decimal rather than bitwise or
> binary math.

If you're testing for divisibility by a power of two, it's real easy.  To
test for divisibility by 8, do LDA scanlinecounter, AND #$07, BNE
SkipBorderLoc.  You need to have a good handle on bitwise (binary) math to
do this sort of thing (hi Pete Holland :) )


--
Archives (includes files) at http://www.biglist.com/lists/stella/archives/
Unsub & more at http://www.biglist.com/lists/stella/

Current Thread