SuperCPU rayed - Episode 9
16 MB at 20x accelerated C64 - the bread box of superlatives.
How to program him, our course explains the turbo card - we are now
already well advanced, but there just at the SuperRAM Card's still a lot
to discover ...
In the previous Kurstell we have learned by the memory of SuperRAM Card
access the long addressing. Instead of two bytes you just take three bytes,
to determine the location. An LDA $ 050 000 fetches a byte (or two if
one mode is 16-bit) of exactly this address. Then we learned yet another
Opportunity to know, get at the store: The Data Bank Register.
This is always davorgehaengt all 2 byte addresses as bank-byte and is
Normally $ 00, thus leads a LDA $ 2000 also to address $ 002 thousandth
If you change the contents of the register (the PLB command is announced here), for example, to $ 07,
so the same LDA now leads to address $ 072 thousandth
This made it possible to quickly and easily to any location within
of the 16-Mbyte address space access. Depending on the application remains free to Coder,
to use the 24-bit addressing and leave the data bank register are left,
or (in case of frequent memory access to a bank other than 0), this register there
show to have, where you then of course must be careful when Bank 0 accesses, eg also
STA to write $ 00D020. We also had the opportunity to know, about a
3-byte pointer in the Zero Page (eg LDA (FC), Y) access, with low and high byte in
$ FC / $ FD are stored, the Bankbyte logically in $ FE.
Lightning Transfer
As promised, this time there's something very fine: the block-move instructions. This makes it possible,
to transfer up to 64K in one shot through the area. This works within
a memory bank, but also from one bank to another. It is so to speak a
in terms of hardware implemented Transferier routine. The SuperCPU need for a byte
only 7 clock cycles so far faster than a normal loop transfer!
The only catch: These commands do not transfer over bank limits - probably would be a
Exceeding of test gone at the expense of speed.
Now, however, apply: Somehow you have the processor say yes, from where and how much according to where
is to be transferred. This battery, the X and Y registers are used, all 16 bits
switched (REP # $ 30). In the battery then to write in, how many bytes to transfer one
wants. In's X-register is the source address in's Y-register the destination address.
So that looks for example like this:
LDA # $ 2000; Number of bytes
LDY # $ 8000; thence
LDX # $ 1000; still there
Accepted. we want this transfer within the normal 64K, ie bank 0 drove through,
so now would the block move command:
MVN $ 00, $ 00; according to Bank 0 of Bank 0
Behind the opcode only comes the target bank, then the source database. MVN stands for
'Move Block Next', which means nothing more than that the first byte is first transferred
then the next, etc. This can also be transferred over overlapping ranges,
namely those where the target before the source is (eg $ 7000 after $ 4000).
Of course, there are as yet counterpart of the MVP - 'Move Previous Block', where the transfer
begins with the last byte if the transfer regions on the opposite
Page transformation overlap (eg transfer of $ 4,000 bytes $ 3000 after $ 3200). When you have MVP
important to note specify the END address to move the block you, both as a source
well as the destination! Furthermore, a byte is basically in the battery to provide less than
to be transferred: If $ 0005 in it, 6 bytes are transferred.
WIll you are now shifting from one to another bank, it just goes with
MVN $ 03, $ 06; according to Bank 3, Bank of 6
The register must be set beforehand, correspondingly, of course. Changed Moreover,
the processor is in the moment in which the block move instruction is executed,
also the data bank register - after that it is namely le target bank. So one should
before saving the data bank register (with PHB on the stack) and then get back again.
So, now we want so times $ 5,000 bytes of $ 08A000 $ 022 000 after transfer (for whatever reason):
LDA # $ 5000; Number of bytes
LDX # $ A000; Low / High Source
LDY # $ 2000; Low / High Dest
PHB; Push Data Bank Reg
MVN $ 02, $ 08; according to Bank 2, Bank of 8
PLB; Get back data bank register
The whole thing must of course happen in native mode, so that one switch at all on 16 bit
can. Usually you will have then sold a SEI, but what if not? For
habitually the current command is executed to end in a interrupt, then in the
Jumped IRQ Routlne. The block-move instruction can but, if done correctly transferred much
even longer last more than one frame. Note: Without Optimization he manages over $ 4,000
Byles per frame, even with Optimization over $ D000 bytes per frame!
As long as we can with the IRQ not wait. So in such a case, but again a normal
Transfer Loop? No, because the developers have thought of that. For the first time in the middle of
Instruction of the interrupt occur - the current byte is not transferred, then the
Block Move command is interrupted and branches to the interrupt routine! Anyone familiar with the 1764 REU know
that something like this does not allow (her controller also works even with such block-moves)
and is thus Fragmenting the transfer 'had. for example, still playing music or other
IRQ-based things are going to allow. This is not required on the SuperCPU everything! Only needs to
be careful also hoellisch, because the computer enters in the IRQ routine is the Data
Bank Register so on a set of block move value. This should save you, their own,
for the IRQ routine REQUIRED write in (most probably $ 00), and at the end of
IRQ routine restore the data bank register - otherwise, the block move his
Yes not work according to regulations resume. Listing 1 illustrates the use of the
Block Move commands in Listing 2 is still running to an IRQ routine; the straight Signposted
is again illustrated by the comments.
Routines outside the 64K
It is perfectly possible to program parts or the whole program outside the usual
Memory area run permit. Finally, the additional memory is indeed not merely a
RAM disk, but it can also commands are processed. As the whole process starts?
Actually, nothing special there. Each command works eg $ 025 000 as well
as at $ 005 thousandth With a 'long' JMP or JSR, you can start any routines directly.
However, using the long 'JSR, the subroutine must end with a RTL, which is nothing
has to do with a certain TV station, but stands for ReTurn Long - finally
must be kept as Ruecksprungadresse three bytes on the stack.
Exists within the 65816, analogous to data bank register. the Program bank register,
which actually is nothing more than the bank byte of the program counter. Stored using
is $ 00 in it, and only about a 'long' JMP / JSR Is to Change - direct commands are there
not for that. Other concerns one need not be provided: through changes in Program Bank
the stack is still in bank 0, also the Zero-/Direct Page. A STA $ 50 writes
So, provided that the Direct Page is $ 0000 or $ 000 050, although Databank
Program and bank elsewhere! The vectors (IRQ, etc.) are always stored in bank 0
Otherwise, there is at all no problem, run routines to allow arbitrary memory locations.
Only the operating system routines (eg delete screen. Query keyboard) you can from there
of non-use - they end up with an RTS, this brings only two bytes as Ruecksprungadresse
from the stack, thereby rescued the 'long' JSR Program zuruckbleibt bank register and
the C64 does not know where he should go. Everything else works as usual! Of course,
you must now always have an eye on the data bank register, you put eg variables behind
from the code, and this is found from $ 020 000 in the store, only to get over these variables
the 3-byte addressing approach, or you have to grab the value of $ 02 into the data bank register.
By the way, one thing else you should know: In contrast to data access, where the
Also come Indexreglster about bank boundaries easily, the Program Counter jumps
upon reaching the address $ FFFF not next bank, but remains in the same and
go there with $ 0000 going again. To use the program in the next bank run welter allow
Suffice but a simple 'long' JMP. Assuming that the routine proceeds from $ 02F000 to $ 03017A,
it must at $ 02FFFC a JMP $ 030 000 are - done. The handlen of routines in benches
non-zero and jumps, you see again in the listings. In Listing 3 jump
We vigorously back and forth, Listing 4 is the dazugehoerige routine in the other bank.
Old routines, new location
So in order to let programs run outside of the normal 64K, you have the codes some
note, but has the advantage, for example, Bank 0 freizuhaben almost completely for graphics.
How does it look now but from when you already existent routines in another Ram-bank
wants to leave running? Also does not present a problem, even though only everywhere
2-byte addressing is used! We have our routine yet in, say,
Bank 2 running. We simply provide the data bank register to $ 02 from now will our
Routine also their data again - and then jump out with a 'long' JMP. Since the routine
but ends with an RTS (not RTL), the computer will hang - but even that is quickly
solved: in bank 2 is a normal JSR on our routine, directly behind a RTL.
With a 'long' JSR (ie 3-byte address), we jump to the normal JSR, the routine
is executed, returns back, the processor finds our RTL and we are back in bank 0
Music!
As a small grand finale we want a try, a conventional sound,
which is at $ 1000, to run in Bank 2, at $ 021 thousandth
Init and play we jump to about above explained solution, so we do not ever thus
Have problems, The Data Bank Register, we have also set to $ 02 - the routine seems
to run. But to hear is the music absolutely nothing! Actually quite logical, right?
The Data Bank Register on bench 2 Music has all pattern and note data found
has all the settings to waveforms and filters and this .. from $ 02D400 in the memory
geschrleben!
The SID, as always from $ D400, $ or better 00D400, sitting, still waiting for the data,
are to come, Of course, a completely new playback routine could code but still clear
with Zero Page-shift, 16-bit and other fine things, the speed would be Gewinnn
sure deutllch visible even in 1 MHz mode (less screen time). But this is the moment
not the goal - we want this routine, as it is, get them to play music!
But nothing could be simpler than that: The area 02D400 $ $ 02D41C is already with all data
fully written. In a small loop nor the play-calling, we copy the stuff
done simply by $ 00D400 $ 00D41C! Finest SID Sounds penetrate to our ears.
And the normal C64 Memory? Completely free for other data, for graphics, for code.
For this, the music is now even in bank 2, there has, however, not only the area of ??their
taken its own length, but also the couple said bytes if $ 02D400 - but
that you can get over easily. Listing 5 is all that is normal in the 64K memory,
Listing 6 is the little-mentioned routine in bank 2, which does the rest.
To the way, to get the routines and the sound in bank 2. whatâ her either small
Write Block move routines or with the 65816 monitor the flash8-Assblaster V1.2
here is this there directly load. On our disk directory you will find source code
also the final routine, individually linked as a file and already with a music
(After the RUN everything is transferred and started). Besides sounds by copying
some sound not quite true to the original. Wen this bothers and no new
Write routine will play:
The SuperCPU also has enough power, short reinzuswappen the music by block move,
to play and then to restore the originial memory contents again.
But that would be already almost PC-like, right?
(w) Malte Mundt
©1999 Go64 Redax! & Count Zero/SCS*TRC for all HTML Stuff.
Special Thanks to Matthias Hensler for Scanning this part of the tutorial.
[ Zum 8. Teil ][ Zum Index ][ Zum 10. Teil ]