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


 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

 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 ]