1.3 CONFIGURING MEMORY IN THE C-128 The C-128 uses an 8502 eight bit microprocessor. The 8502 is only capable of accessing 64K bytes of memory at any one time. In order to allow the 8502 to access different combinations of RAM and ROM in that 64K space, a technique of reconfiguring the memory was designed. This technique enables the computer to configure the memory in such a way to allow the 8502 to be able to see or access different layers or sections of memory (this will be discussed in more detail later). The term 'BANK' is alittle misleading when discussing how the 8502 can access different 'MEMORY CONFIGURATIONS' in the 128. A 'BANK' is nothing more than a 'MEMORY CONFIGURATION' that can be accessed by the BASIC BANK command. There are 256 possible memory configurations which can be accessed by the 8502 through the use of the registers in the MMU in the 128. However, only sixteen of these memory configurations are supported by the BASIC operating system when utilizing the BASIC BANK command. These sixteen memory configurations are named BANK 0 through BANK 15. Out of these sixteen, four of the so called 'BANKS' are used at the present time: BANK 0, BANK 1, BANK 14, and BANK 15. RAM BANKs 1 and 2 are not available on the C-128, the hardware was not installed. The expansion RAM that is currently available is not RAM BANK 2 and/or 3, it is an external memory device that stores memory in a different manor then the ram inside the C-128. For more information on the external ram expansion module refer to the section on RAM EXPANSION in this book. For the purpose of discussion in the text that follows, we will stick to the term 'MEMORY CONFIGURATIONS' except, when the term 'BANK' refers to a BASIC BANK accessible by the BASIC BANK command. The thing that makes different memory configurations possible in the C-128 is a custom chip called the Memory Management Unit or MMU (8722). The MMU along with another chip called the Programmable Logic Array or PLA (8721) provide the C-128 with the capability of operating in the C-64 mode, the C-128 mode, and the CP/M mode. The MMU however, is the main controlling chip that performs the job of managing the memory. The MMU has 11 registers located at memory locations $D500 - $D50B which are used by the operating system to configure the MMU for the mode or operation that is to be performed. These registers, their memory loctions, and their functions, are contained in the table below. [INSERT TABLE 1.3 HERE] As you may have probably noticed, the registers that are located at $D500 - $D504 are also copied to locations $FF00 - $FF04. These memory locations in the C-128 mode will always reflect what is in the registers at $D500 - $D504. This allows for entering into other memory configurations even if the I/O block from $D000 - $DFFF is switched out. 1.3.1 THE CONFIGURATION REGISTER (CR) The Configuration Register (CR) for the MMU is located at $D500. This register is the main register that allows the MMU to set up memory for up to 256 different memory configurations. The value that is stored in register is also stored at $FF00. This location ($FF00) provides a means of reconfiguring the memory independent of which memory configuration you are in. If a value is stored to location $D500, the value will also appear in location $FF00. If a value is stored in location $FF00, the value will also appear in location $D500. If either of these locations is read, the value that is returned is the current value that is stored in the Configuration Register at $D500. Each bit in location $D500 has the job of determining what will appear in the particular area of memory that it controls. The values of these bits and their functions are contained in the following table. BIT BEING DESCRIBED LOCATIONS AFFECTED SWITCH REPRESENTATION ------------------------------------------------------------------------- BIT 0 $D000 - $DFFF S4 POSITION ---------------------------------------------------------------------- 0 = I/O POS A 1 = CHARACTER ROM/SELECTED RAM BANK POS B BIT 1 $4000 - $7FFF S1 POSITION ----------------------------------------------------------------------- 0 = BASIC ROM LOW POS A 1 = SELECTED RAM BANK POS B BITS 3 AND 2 $8000 -$BFFF S2 POSITION ----------------------------------------------------------------------- 3 2 --- --- 0 0 = BASIC ROM HIGH POS A 0 1 = INTERNAL FUNCTION ROM POS B 1 0 = EXTERNAL FUNCTION ROM POS C 1 1 = SELECTED RAM BANK POS D BITS 5 AND 4 $C000 - $FFFF S3a AND S3b POSITION (except $D000 - $DFFF) ------------------------------------------------------------------------- 5 4 --- --- 0 0 = KERNAL ROM POS A 0 1 = INTERNAL FUNCTION ROM POS B 1 0 = EXTERNAL FUNCTION ROM POS C 1 1 = SELECTED RAM BANK POS D BITS 7 AND 6 SELECTED RAM BANK (see NOTE) -------------------------------------------------------------------------- 7 6 --- --- 0 0 = RAM BANK 0 0 0 = RAM BANK 1 1 0 = RAM BANK 2 (NOT AVAILABLE) 1 1 = RAM BANK 3 (NOT AVAILABLE) NOTE: the RAM BANK that is selected by these bits is what appears where the SELECTED RAM BANK note appears The SWITCH REPRESENTATION that appears in the table represents the position of that particular switch in the diagram below if the bit value is as noted. For instance, if BIT 1 in the CR ($D500) contained a value of 0, then S1 would be in POS A, thereby selecting the BASIC ROM LOW for the area of memory $4000 - $7FFF. [rEFER TO table.txt HERE] To better illustrate the use of this table and the diagram pictured above, let's take the value $10 and show how the table and the diagram can better help you to understand the different memory configurations and the way that the MMU is capable of configuring memory through the use of the Configuration Register. First of all, convert the HEX value into its binary equivalent. The HEX value of $10 converted to binary is %00010000. Therefore, the following memory configuration would be selected and the switches in the diagram would be in the following positions. Since BIT 0 contains a value of 0, this means that S4 would be in POSition A, thereby, selecting I/O for the area of memory $D000 - $DFFF. Since BIT 1 contains a value of 0, this means that S1 would be in POSition A, thereby, selecting BASIC ROM LOW for the area of memory $4000 - $7FFF. Since BITS 3 and 2 both contain a value of 0, this means that S2 would be in POSition A, thereby, selecting BASIC ROM HIGH for the area of memory $8000 - $BFFF. Since BIT 5 contains a value of 0 and BIT 4 contains a value of 1, this means that both S3a and S3b would be in POSition B, thereby, selecting INTERNAL FUNCTION ROM for the area of memory $C000 - $FFFF except, the area of memory $D000 - $DFFF which was defined for the use of I/O by BIT 0. The last two bits, BITS 7 and 6, do not have a corresponding switch. However, the result of the values stored in these two bit locations determines which RAM BANK will appear in those areas of memory that have RAM selected for them. Since BITS 7 and 6 both contain a value of 0, then RAM BANK 0 is selected. In APPENDIX G, what has been discussed here is in one big table. The table gives the 256 memory configurations that are possible if each of the values from $00 to $FF were to be placed into the CR at $D500 or $FF00. 1.3.2 THE PRECONFIGURATION REGISTERS (PCR) The Preconfiguration Registers are located at $D501 - $D504 and a copy of these registers appear in the Load Configuration Registers (LCR) at $FF01 - $FF04. Upon power up, PCRA - PCRD ($D501 - $D504) are initialized with the following memory configuration values: $D501 = $3F (BANK 0), $D502 = $7F (BANK 1), $D503 = $01 (BANK 14), and $D504 = $41 (BANK 14 with RAM BANK 1). These values represent the four memory configurations that the operating system uses in its routines for its own internal processing. However, these four registers can be programmed to any four memory preconfigurations that the user wants. For instance, if for some reason you wanted to program all of the Preconfiguration Registers to contain the value for BANK 15, the following short machine language routine would do the trick. (NOTE: If you use this routine, BASIC will no longer function because you will have changed the memory configuration values that the BASIC operating system uses for its internal processing.) LDA #$00 ;Load the accumulator with the value ;For BANK 15 TAY ;Zero the index register LOOP STA $D501,Y ;Store the value for BANK 15 in ;The Preconfiguration Register INY ;Increment the index CPY #$04 ;Are all the registers done? BNE LOOP ;If they are not, then branch After all of the Preconfiguration Registers have been set to the memory configuation value for BANK 15, you will find that the Load Configuration Registers at $FF01 - $FF04 will also contain the memory configuration value for BANK 15. Anytime a PCR is changed, the corresponding LCR is also changed to reflect the same value. However, if you try to store a value to any of the LCRs at $FF01 - $FF04, the value in the LCR does not change. Instead, what occurs is that the value that is stored in the corresponding PCR is moved to the Configuration Register at $D500 and $FF00. For instance, if you execute the following: STA $FF02 ;Store the accumulator to $FF02 ;(the value in the accumulator is ;irrelevant) The value that is in PCRB at $D502 will be moved into the CR at $D500 and $FF00. Anytime that a read is made of an LCR, the value returned is that value which is stored in the cooresponding PCR. For instance, if you read the contents of $FF01, the value that is returned is the value that is stored in location $D501. However, if you read the contents of a PCR, the value that will be returned will be the value in thE pcr. cONSEQUENTLY, THERE ARE THREE WAYS TO SWITCH TO DIFFERENT MEMORY CONFIGURATIONS: STORE THE VALUE FOR THE MEMORY CONFIGURATION DESIRED INTO LOCATION $ff00, STORE THE VALUE FOR THE MEMORY CONFIGURATION DESIRED INTO LOCATION $d500, OR STORE ANY VALUE TO THE CORRESPONDING lcr ($ff01 - $ff04) OF THE pcr ($d501 - $d504) THAT CONTAINS THE VALUE OF THE MEMORY CONFIGURATION DESIRED. iF YOU SHOULD DEFINE A MEMORY CONFIGURATION THAT SWITCHES OUT THE i/o BLOCK, THEN THE ONLY WAY TO SWITCH TO A DIFFERENT MEMORY CONFIGURATION IS TO STORE THE VALUE OF THE MEMORY CONFIGURTION TO SWITCH TO IN THE cONFIGURATION rEGISTER AT $ff00 OR STORE ANY VALUE TO THE CORRESPONDING lcr ($ff01 - $ff04) OF THE pcr ($d501 - $d504) THAT CONTAINS THE VALUE OF THE MEMORY CONFIGURATION DESIRED. 1.3.3 the mode configuration register (mcr) tHE mODE cONFIGURATION rEGISTER (mcr) IS LOCATED AT $d505. iTS MAIN FUNCTION IS TO SET UP THE COMPUTER MODE TO BE USED. tHEREFORE, IT CONTROLS WHICH MICROPROCESSOR IS TO BE ACTIVE (8502 OR z80a). bIT 7, AND BITS 5 THRU 3 FUNCTIONS AS A BIDIRECTIONAL PORT, IF A VALUE IS WRITTEN TO THE PORT, THE HARDWARE LINE WILL REFLECT WHATEVER VALUE THAT WAS WRITTEN, AND IF THE BIT IS READ THEN THE VALUE THAT WAS WRITTEN WILL BE RETURNED. iF A DEVICE CONNECTED TO THE HARDWARE LINE IS PULLING THIS LINE LOW THEN THE VALUE THAT WAS PREVIOULY SET WILL BE RETURNED WITH A READ. eACH ONE OF THESE LINES CAN ONLY BE BROUGHT LOW BY A DEVICE AND NOT HIGH, THEREFORE IF YOU BRING ONE OF THESE LOCATIONS LOW BY CLEARING THE BIT, YOU WILL NOT BEABLE TO DETECT THE LOCATION BEING BROUGHT 'HIGH'. tHE FUNCTION OF EACH BIT OF THE mcr IS AS FOLLOWS: bit 7 iNDICATES WHAT THE STATUS OF THE 40/80 COLUMN KEY WAS AT RESET (0 = 80 COLUMN, 1 = 40 COLUMN) bit 6 iNDICATES WHICH MODE IS ACTIVE (0 = 128 MODE, 1 = 64 MODE) (SEE THE SECTION ON autobooting FOR AN EXAMPLE OF SWITCHING INTO THE 64 MODE AND RUNNING A PROGRAM FROM THE 128 MODE) bits 5,4 tHESE BITS INDICATE THE STATUS OF THE game AN exromin LINES. iF THESE LINES ARE BEING USED, THEN THE COMPUTER SWITCHES INTO THE 64 MODE FOR THE 64 CARTRIDGE. tHESE LINES ARE NOT USED IN THE 128 MODE. bit 3 tHIS BIT IS USED AS THE fsdir CONTROL BIT FOR THE FAST SERIAL DATA BUFFER. iT IS ALSO USED AS THE INPUT BIT FOR THE DISK ENABLE SIGNAL. bits 2,1 nOT USED bit 0 tHIS BIT ALLOWS THE SELECTION OF ONE OF THE TWO PROCESSORS (0 = z80a, 1 = 8502) tHE FOLLOWING PROGRAM IS AN EXAMPLE ON HOW TO TEST FOR THE 40/80 DISPLAY KEY. tHE PROGRAM WILL ENABLE YOU TO TEST THE KEY CLOSURE AND IF THE KEY IS IN THE 80 COLUMN POSITION IT WILL CHANGE THE PROCESSOR SPEED TO 2 mhZ WHICH IS THE fast MODE AND IF THE 40 COLUMN POSITION IS SELECTED THEN THE slow MODE IS ENABLED. tO USE THIS EXAMPLE JUST ENTER THE FOLLOWING PROGRAM AND sys dec("0c00"), OR run"mcr example" WHICH WILL LOAD UP THE PROGRAM FOR YOU AND 'run' IT. 10 ln=1000:a=dec("0c00") 20 fori=atoa+50step8 30 forj=0to7:readd$ 40 v=dec(d$) 50 pokei+j,v:ck=ck+v 60 nextj 70 readck$:if(ckand255)<>dec(ck$)thenprint"error in line "ln:goto140 80 ln=ln+10 90 ck=0:nexti 100 print"do you want to save this program ?" 110 getkeya$:ifa$="n"then 130 120 bsave "mcr example.o",b0,p3072 to p3123 130 print"type 'sys 3072' to activate" 140 end 1000 data 78,a9,0d,a0,0c,8d,14,03, 7e 1010 data 8c,15,03,58,60,ad,05,d5, e3 1020 data 09,80,8d,05,d5,ad,00,ff, 9c 1030 data 48,a9,00,8d,00,ff,2c,05, ae 1040 data d5,30,05,20,b3,77,d0,03, 27 1050 data 20,c4,77,68,8d,00,ff,4c, 9b 1060 data 65,fa,3b,67,65,74,a0,74, ee 1.3.4 the ram configuration register (rcr) tHE rAM cONFIGURATION rEGISTER IS LOCATED AT $d506. iTS MAIN FUNCTION IS TO DEFINE THE COMMON USER AREAS. tHESE AREAS ARE USED BY THE DIFFERENT ROUTINES TO PASS INFORMATION BETWEEN DIFFERENT MEMORY CONFIGURATIONS. wITHOUT THESE COMMON AREAS, THE CONCEPT OF RECONFIGURING THE MEMORY WOULD NOT BE POSSIBLE. tHE DEFINITION FOR THE EACH BIT OF THIS REGISTER IS AS FOLLOWS: bits 7,6 tHESE TWO BITS DETERMINE WHERE THE ram FOR THE vic CHIP WILL APPEAR FOR THE STORAGE OF TEXT AND GRAPHICS. tHE VIDEO ram IS USUALLY LOCATED IN bank 0. 7 6 --- --- 0 0 = ram bank 0 0 1 = ram bank 1 1 0 = ram bank 2 (not available) 1 1 = ram bank 3 (not available) bits 5,4 tHESE TWO BITS ARE UNUSED bits 3,2 tHESE TWO BITS INDICATE IF THERE IS A COMMON USER AREA AND IF THERE IS, WHERE THAT AREA IS LOCATED. 3 2 --- --- 0 0 = no common area is shared 0 1 = the lower ram area is shared 1 0 = the upper ram area is shared 1 1 = both the upper and the lower ram areas are shared bits 1,0 tHESE TWO BITS DETERMINE THE SIZE OF THE COMMON ram AREAS IF THERE ARE ANY COMMON AREAS. 1 0 --- --- 0 0 = 1k of ram is common 0 1 = 4k of ram is common 1 0 = 8k of ram is common 1 1 = 16k of ram is common fOR EXAMPLE, THE VALUE OF THIS LOCATION UPON POWER UP IS $04 OF WHOSE BINARY EQUIVALENT IS %00000100. bITS 4-0 ARE THE CONTROL BITS WHICH DETERMINE WHETHER OR NOT THERE IS A COMMON USER AREA AND WHERE THAT COMMON USER AREA IS LOCATED. fIRST, SINCE bit 3 CONTAINS A 0 AND bit 2 CONTAINS A 1, THE COMMON USER AREA IS DEFINED AS BEING IN THE LOWER ram AREA IN ALL OF THE MEMORY CONFIGURATIONS. sECONDLY, SINCE bits 1 AND 0 BOTH CONTAIN A 0, THIS DEFINES A COMMON USER AREA SIZE OF 1k. cONSEQUENTLY, THE FINAL RESULT THAT THE VALUE OF $04 IN THE rcr ($d506) HAS UPON THE COMMON USER AREA IS THAT IT DEFINES A 1k AREA IN THE LOWER ram FROM $0000 - $03ff IN ALL OF THE MEMORY CONFIGURATIONS. iT IS POSSIBLE TO HAVE A TOTAL OF 32k OF COMMON USER AREA IF A SIZE OF 16k IS SELECTED AND BOTH THE UPPER AND LOWER COMMON USER AREAS ARE ENABLED. tHE VALUE FOR THIS TYPE OF COMMON USER AREA CONFIGURATION WOULD BE $0f. 1.3.5 the page pointers tHE pAGE-zERO AND pAGE oNE POINTERS ARE LOCATED IN $d507/$d508 AND $d509/$d50a RESPECTIVELY. tHESE REGISTERS ARE USED WHEN YOU WISH TO MOVE EITHER pAGE zERO OR pAGE oNE. $d507 p0l page zero pointer lsb $d508 p0h page zero pointer msb $d509 p1l page one pointer lsb $d50a p1h page one pointer msb 1.3.6 the version register (vr) tHE vERSION rEGISTER IS LOCATED AT $d50b. tHIS REGISTER IS A READ ONLY REGISTER AND IS USED TO RETURN THE CODE THAT CONTAINS THE VERSION OF THE mmu AND THE SIZE AND CAPABLILITY OF THE MEMORY THAT IS RESIDENT IN THE SYSTEM. bits 7-4 tHESE BITS CONTAIN THE CODE THAT REPRESENTS THE TOTAL AVAILABLE MEMORY SPACE. nORMALLY THESE BITS CONTAIN A 2 FOR TWO 64k BLOCKS OF MEMORY FOR A TOTAL OF 128k OF MEMORY STORAGE. bits 3-0 tHESE BITS CONTAIN THE CODE THAT REPRESENTS THE VERSION NUMBER OF THE mmu THAT IS IN THE c-128.