[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]
Re: AUX memory question
David Empson wrote:
> One convenient way of dealing with this area would be if your routine
> pretended that the second $D000-$DFFF bank was located in $C000-$CFFF.
I realized that last night on the bus ride home. :)
>
> > Currently, I load two 9 byte stubs into main memory at $e0 -> $f3. I
> > have asm wrappers that pop my C args from the virtual stack (it is what
> > cc65 uses for passing args). These functions test my argument ranges,
> > then call the appropriate read/write function at $e0 or $e9. These
> > functions just store the accumulator to the softswitch $c002/$c004 (as
> > required), lda/sta my byte, then set the softswitch back to main memory,
> > then return to the caller.
>
> OK, that code will work fine for $0800-$BFFF, but it won't work for the
> auxiliary language card area ($D000-$FFFF or the second bank in
> $D000-$DFFF), because you need to use different soft-switches, and
> switching in the auxiliary language card will switch out the main memory
> zero page (and stack).
>
> If you haven't already used the $0200-$03DF area in main memory, I
> suggest adding four stub routines in there which will deal with the
> auxiliary language card area (read bank 1, write bank 1, read bank 2,
> write bank 2).
>
> Your main ASM wrapper code should check for three address ranges:
>
> $0800-$BFFF go to your existing zero-page routine.
> $C000-$CFFF go to the read/write aux bank 1 routine, with the high byte
> patched by adding $10 (thus $C000-$CFFF map to $D000-$DFFF).
> $D000-$FFF9 go to the read/write bank 2 routine, with an unpatched high
> byte.
>
> (You can use either bank 1 or 2 to access $E000-$FFFF. It is only the
> $D000-$DFFF area which changes according to the bank selection.)
>
Here comes the good stuff (A real implementation using the soft
switches):
> The stub routines to access the auxiliary language card area are as
> follows:
>
> RDAUX1 SEI ; No interrupts!
> LDX C088 ; Read-enable language card bank 1
> STA C009 ; Switch in auxiliary language card, etc.
> LDA xxxx ; Read target location (patched)
> STA C008 ; Switch in main language card, etc.
> LDX C08A ; Switch the ROM back in
> CLI ; Enable interrupts
> RTS
>
> WRAUX1 SEI ; No interrupts!
> LDX C08B ; Read/write language card bank 1
> LDX C08B ; (must access twice)
> STA C009 ; Switch in auxiliary language card, etc.
> STA xxxx ; Write target location (patched)
> STA C008 ; Switch in main language card, etc.
> LDX C08A ; Switch the ROM back in
> CLI ; Enable interrupts
> RTS
>
> RDAUX2 SEI ; No interrupts!
> LDX C080 ; Read-enable language card bank 2
> STA C009 ; Switch in auxiliary language card, etc.
> LDA xxxx ; Read target location (patched)
> STA C008 ; Switch in main language card, etc.
> LDX C082 ; Switch the ROM back in
> CLI ; Enable interrupts
> RTS
>
> WRAUX2 SEI ; No interrupts!
> LDX C083 ; Read/write language card bank 2
> LDX C083 ; (must access twice)
> STA C009 ; Switch in auxiliary language card, etc.
> STA xxxx ; Write target location (patched)
> STA C008 ; Switch in main language card, etc.
> LDX C082 ; Switch the ROM back in
> CLI ; Enable interrupts
> RTS
Since the above code is for hitting the language card at >$bfff, I
assume that I can leave the above code in my main code segment (er, um,
whatever it is called...) in MAIN memory. Is this correct, or do I need
to shove it all into zero page (along with my other stubs)?
> The C008/C009 switch controls both read and write access, unlike the
> switches for the main $0200-$BFFF area, but note the different
> instruction sequences needed to control read enable and read/write
> enable for the language card area. (You could set up the language card
> for write-only access using C081 or C089 instead of C083 or C08B, but it
> won't make the code any shorter.)
Why did they bother with write only access to this ram?
> > I do disconnect /RAM, and I don't care if /RAM is to be re-attached when
> > I'm done.
>
> Are you sure about that? If your application disconnects /RAM, then it
> is the responsibility of your application to reconnect it again when you
> terminate. The only reasonable exceptions to this would be an
> application which installs its own replacement RAM disk driver, or a
> special-purpose application which never quits.
>
> The /RAM volume is there for the convenience of the user. If you don't
> restore it, then subsequent applications which need to use it won't be
> able to, and some application won't be able to use auxiliary memory at
> all if there is no /RAM volume present (others might assume that they
> have full rein, and overwrite anything you might have left there).
> .
I never thought about being "polite". In my normal usage of an Apple
II, I reboot it quite often. Rebooting (or doing -prodos) reinitializes
/RAM. I can add code to re-attach and reformat /RAM, but I will now
have to make sure that I don't trash important memory areas that ProDOS
would like me to preserve. I'll try to find that technote.
If I am free to use the RAM in the language card, then I assume that
ProDOS 'lives' in the upper 16K (or 12K?) of the AUX memory proper,
accessed via the ALTZP switch?
And I thought that PCs had funky memory layouts!
Dave,
Thank you very much. I finally understand how the Apple II memory is
layed out. Your post makes much more sense than a simple list of
softswitches.