There are occasions when you will want to divert an area of RAM from its normal usage. For example, you may need to set aside space for a machine language routine, an alternate screen display, or a data buffer. For machine language (ML) programming, you can use any area of RAM if you are willing to learn the intricacies of the 128's banking scheme. Other- wise, it's best to restrict your programming to certain known areas. For a machine language routine to be used in conjunc- tion with a BASIC program, you'll need to select an area which BASIC doesn't normally use, or to take away some memory that otherwise would be used for program text or variable storage. As noted in Chapter 3, locations 4864-7167/ $13OO-$1BFF are currently unused (even though they are
186
called "reserved" in Commodore literature). This 2304-byte area is the largest unused area of protected RAM in the 128, and it is becoming extremely popular with 128 ML program- mers—much like the $C000 block in the Commodore 64. You can expect to see many ML programs using this area.
Other, shorter blocks are also available if certain BASIC features are not used. If tape is not used, the 256 bytes at 2816-3071/$0B00-$0BFF are available. However, unlike other free blocks, this page may be overwritten during a reset be- cause disk boot sectors are read into this area. Thus, the time- honored Commodore tradition of using the cassette buffer for short ML routines is less suitable in the 128. (It's annoying to have to reload your routine after each reset.) If your program doesn't use RS-232 communications, the two RS-232 buffers at 3072-3583/$0C00-$0DFF provide a 512-byte workspace. This is probably the best area for short ML routines that you wish to use in conjunction with BASIC. (Unlike the cassette buffer, this area survives reset intact.) If your program does not use sprites, the 512-byte sprite definition area at 3584-4095/ $0E00-$0FFF is also available. Of course, if your program uses neither tape nor RS-232 nor sprites, you can use the full 1280 bytes at 2816-4095/$0B00-$0FFF or any subsection thereof.
To use a large ML program in conjunction with BASIC, there is an easy way to reserve over UK of protected RAM. However, this technique works only if neither the BASIC nor the ML program requires high-resolution graphics. The trick is to use the BASIC GRAPHIC statement to set aside a high- resolution screen area at 7168-16383/$lC00-$3FFF. As men- tioned above, this area remains allocated until a GRAPHIC CLR statement is executed. Simply begin your BASIC program with a line like GRAPHIC 1:GRAPHIC 0 (or GRAPHIC
1:GRAPHIC 5 if you want to use the 80-column display). Then BLOAD the machine language program into the reserved area. In addition to the 9K screen area, you can also use the contiguous unused area just below, at 4864-7167/$1300-$lBFF. If you want to use a machine language program in conjunction with BASIC and high-resolution graphics, you'll have to resort to bank-switching techniques if the program is too large to fit in the unused area at 4864/$1300.
It's possible to reserve space above or below either the BASIC or variable/string areas. To reserve space below the BASIC program text, increase the value in the start-of-BASIC
beyond the starting address in 45-46/$2D-$2E. An OUT OF MEMORY error occurs if the address in 4624-4625/ $1210-$1211 reaches the value in 4626-4627/ $1212-$1213. The ending address pointer is set after a BASIC LOAD [$912C], and the BASIC SAVE routine [$9112] uses the values in the starting and ending address pointers as the starting and end- ing address for the block of memory to be saved.
The address in the pointer at locations 47-48/$2F-$30 marks the start of scalar (nonarray) variables in bank I. The pointer is initialized to 1024/$0400 during the BASIC cold start routine. A pointer at 49-50/$31-$32 marks the end of scalar variables and the beginning of arrays; another pointer at 51-52/$33-$34 marks the end of arrays and the beginning of free memory in block 1. Both of these pointers are reset to the value in 47-48/$2F-$30 during the BASIC CLR routine. The pointer at 57-58/$39-$3A holds an address which is one byte beyond the highest address of free memory in block 1. It is initialized during BASIC cold start to point to 65280/$FF00. The free memory in block 1 is used to hold strings of all types—constants, variables, and arrays. The string pool starts at the top of free memory and is filled downward toward the bottom of free memory indicated in 51-52/$33-$34. The pointer at 53-54/$35-$36 marks the current address of the bottom of the string pool. That pointer is reset to the value in 57-58/$39-$3A by the BASIC CLR routine. An OUT OF MEMORY error occurs when the value in 53-54/$35-$36 reaches the value in 51-52/$33-$34.
Reserving RAM
There are occasions when you will want to divert an area of RAM from its normal usage. For example, you may need to set aside space for a machine language routine, an alternate screen display, or a data buffer. For machine language (ML) programming, you can use any area of RAM if you are willing to learn the intricacies of the 128's banking scheme. Other- wise, it's best to restrict your programming to certain known areas. For a machine language routine to be used in conjunc- tion with a BASIC program, you'll need to select an area which BASIC doesn't normally use, or to take away some memory that otherwise would be used for program text or variable storage. As noted in Chapter 3, locations 4864-7167/ $13OO-$1BFF are currently unused (even though they are
186
called "reserved" in Commodore literature). This 2304-byte area is the largest unused area of protected RAM in the 128, and it is becoming extremely popular with 128 ML program- mers—much like the $C000 block in the Commodore 64. You can expect to see many ML programs using this area.
Other, shorter blocks are also available if certain BASIC features are not used. If tape is not used, the 256 bytes at 2816-3071/$0B00-$0BFF are available. However, unlike other free blocks, this page may be overwritten during a reset be- cause disk boot sectors are read into this area. Thus, the time- honored Commodore tradition of using the cassette buffer for short ML routines is less suitable in the 128. (It's annoying to have to reload your routine after each reset.) If your program doesn't use RS-232 communications, the two RS-232 buffers at 3072-3583/$0C00-$0DFF provide a 512-byte workspace. This is probably the best area for short ML routines that you wish to use in conjunction with BASIC. (Unlike the cassette buffer, this area survives reset intact.) If your program does not use sprites, the 512-byte sprite definition area at 3584-4095/ $0E00-$0FFF is also available. Of course, if your program uses neither tape nor RS-232 nor sprites, you can use the full 1280 bytes at 2816-4095/$0B00-$0FFF or any subsection thereof.
To use a large ML program in conjunction with BASIC, there is an easy way to reserve over UK of protected RAM. However, this technique works only if neither the BASIC nor the ML program requires high-resolution graphics. The trick is to use the BASIC GRAPHIC statement to set aside a high- resolution screen area at 7168-16383/$lC00-$3FFF. As men- tioned above, this area remains allocated until a GRAPHIC CLR statement is executed. Simply begin your BASIC program with a line like GRAPHIC 1:GRAPHIC 0 (or GRAPHIC
1:GRAPHIC 5 if you want to use the 80-column display). Then BLOAD the machine language program into the reserved area. In addition to the 9K screen area, you can also use the contiguous unused area just below, at 4864-7167/$1300-$lBFF. If you want to use a machine language program in conjunction with BASIC and high-resolution graphics, you'll have to resort to bank-switching techniques if the program is too large to fit in the unused area at 4864/$1300.
It's possible to reserve space above or below either the BASIC or variable/string areas. To reserve space below the BASIC program text, increase the value in the start-of-BASIC
pointer at 45-46/$2D-$2E by the number of bytes you want to reserve. (To reserve an even number of 256-byte pages, you need only change the value in 46/$2E.) Two other steps are also necessary: BASIC requires a zero byte below the first lo- cation in its program text space, and a NEW operation is re- quired to reset other important memory pointers. For example, to reserve three pages (768 bytes) below the normal start of BASIC, you would use a statement like this:
POKE 46,31:POKE 31*256,0:NEW
After this statement is executed, the area at 7168-7935/ $1COO-$1EFF is protected from BASIC until the next time the BASIC cold start routine is performed (normally during the next reset sequence). The pointer value is unaffected by RUN/STOP-RESTORE. This technique is less useful when a high-resolution screen area is allocated. In that case, the start of BASIC is moved to 16384/$4000. The technique for reserv- ing space at the start of BASIC still works, but the reserved memory will lie above 16383/$3FFF, which is the highest ad- dress seen as RAM in bank 15—the bank in which Kernal ROM is visible and to which BASIC defaults. Thus, a routine above that boundary will be invisible unless you tinker with the MMU configuration register.
Space can be reserved at the top of the BASIC program area by reducing the value in the pointer at 4626-4627/ $1212—$1213 by the desired number of bytes. (Again, if you wish to reserve an even number of 256-byte pages, you can simply reduce the value in 4627/$l213.) No additional steps are required other than changing the pointer value. This tech- nique was often used in the Commodore 64 to reserve space for machine language routines; its usefulness is more limited in the 128 because of the 16384/$4000 boundary of RAM visi- ble in bank 15, which was mentioned above. To easily use the reserved area for an ML routine in conjunction with BASIC, the top of memory must be lowered sufficiently to make at least a portion of the reserved area appear below the bound- ary of RAM visible in bank 15; this dramatically reduces the amount of memory available for program text. It's not even possible when a high-resolution screen area is allocated. The technique can, however, be useful for setting aside an area in block 0 for a buffer, a reserved area of memory for data storage.
188
You can also reserve space in block 1, either above or be- low the variable/string area. To reserve space below variables, add a value corresponding to the number of bytes to be re- served to the address in the pointer at 47-48/$2F-$30, (As with the other pointers, you can simply increase the value in 48/$30 if you are reserving an even number of 256-byte pages.) This step must be followed by a BASIC CLR statement to reset other variable pointers, so it should be performed early in the program (CLR erases all variable values). The fol- lowing line reserves an additional IK at the bottom of variable space, locations 1024-2047/$0400-$07FF in block 1:
100 POKE 48,8:CLR
Once established, the reserved area will remain intact until the next time the BASIC cold start routine is executed, normally at the next reset. The setting is unaffected by RUN/STOP- RESTORE.
Since this reserved RAM is in block 1, it can't be used for ML routines as easily as the RAM from block 0. There is no standard bank configuration that makes BASIC and Kernal ROM visible in conjunction with block 1 RAM. Of course, it is possible to access Kernal or BASIC routines indirectly by using the JSRFAR or JMPFAR routine. One use for a reserved area in block 1 would be for an alternate 40-column screen. See the entry for the MMU RAM configuration register (54535/$D506) information on using block 1 for VIC-II screen memory.
To reserve space above strings, subtract a value cor- responding to the number of bytes to be reserved from the ad- dress in the pointer at 57-58/$39-$3A. (As with the other pointers, you can simply increase the value in 58/$3A if you are reserving an even number of 256-byte pages.) This step must also be followed by a BASIC CLR statement to reset other string pointers, so it should be performed early in the program (CLR erases all variable values). The following line reserves 31K at the top of string space, locations
32768-65279/$8000-$FEFF in block 1: 100 POKE 58,128:CLR
Once established, the reserved area will remain intact until the next time the BASIC cold start routine is executed—normally at the next reset. The setting is unaffected by RUN/STOP- RESTORE. As mentioned above, this area can't be easily used for machine language routines since it is in block 1. One ap-
pointer at 45-46/$2D-$2E by the number of bytes you want to reserve. (To reserve an even number of 256-byte pages, you need only change the value in 46/$2E.) Two other steps are also necessary: BASIC requires a zero byte below the first lo- cation in its program text space, and a NEW operation is re- quired to reset other important memory pointers. For example, to reserve three pages (768 bytes) below the normal start of BASIC, you would use a statement like this:
POKE 46,31:POKE 31*256,0:NEW
After this statement is executed, the area at 7168-7935/ $1COO-$1EFF is protected from BASIC until the next time the BASIC cold start routine is performed (normally during the next reset sequence). The pointer value is unaffected by RUN/STOP-RESTORE. This technique is less useful when a high-resolution screen area is allocated. In that case, the start of BASIC is moved to 16384/$4000. The technique for reserv- ing space at the start of BASIC still works, but the reserved memory will lie above 16383/$3FFF, which is the highest ad- dress seen as RAM in bank 15—the bank in which Kernal ROM is visible and to which BASIC defaults. Thus, a routine above that boundary will be invisible unless you tinker with the MMU configuration register.
Space can be reserved at the top of the BASIC program area by reducing the value in the pointer at 4626-4627/ $1212—$1213 by the desired number of bytes. (Again, if you wish to reserve an even number of 256-byte pages, you can simply reduce the value in 4627/$l213.) No additional steps are required other than changing the pointer value. This tech- nique was often used in the Commodore 64 to reserve space for machine language routines; its usefulness is more limited in the 128 because of the 16384/$4000 boundary of RAM visi- ble in bank 15, which was mentioned above. To easily use the reserved area for an ML routine in conjunction with BASIC, the top of memory must be lowered sufficiently to make at least a portion of the reserved area appear below the bound- ary of RAM visible in bank 15; this dramatically reduces the amount of memory available for program text. It's not even possible when a high-resolution screen area is allocated. The technique can, however, be useful for setting aside an area in block 0 for a buffer, a reserved area of memory for data storage.
188
You can also reserve space in block 1, either above or be- low the variable/string area. To reserve space below variables, add a value corresponding to the number of bytes to be re- served to the address in the pointer at 47-48/$2F-$30, (As with the other pointers, you can simply increase the value in 48/$30 if you are reserving an even number of 256-byte pages.) This step must be followed by a BASIC CLR statement to reset other variable pointers, so it should be performed early in the program (CLR erases all variable values). The fol- lowing line reserves an additional IK at the bottom of variable space, locations 1024-2047/$0400-$07FF in block 1:
100 POKE 48,8:CLR
Once established, the reserved area will remain intact until the next time the BASIC cold start routine is executed, normally at the next reset. The setting is unaffected by RUN/STOP- RESTORE.
Since this reserved RAM is in block 1, it can't be used for ML routines as easily as the RAM from block 0. There is no standard bank configuration that makes BASIC and Kernal ROM visible in conjunction with block 1 RAM. Of course, it is possible to access Kernal or BASIC routines indirectly by using the JSRFAR or JMPFAR routine. One use for a reserved area in block 1 would be for an alternate 40-column screen. See the entry for the MMU RAM configuration register (54535/$D506) information on using block 1 for VIC-II screen memory.
To reserve space above strings, subtract a value cor- responding to the number of bytes to be reserved from the ad- dress in the pointer at 57-58/$39-$3A. (As with the other pointers, you can simply increase the value in 58/$3A if you are reserving an even number of 256-byte pages.) This step must also be followed by a BASIC CLR statement to reset other string pointers, so it should be performed early in the program (CLR erases all variable values). The following line reserves 31K at the top of string space, locations
32768-65279/$8000-$FEFF in block 1: 100 POKE 58,128:CLR
Once established, the reserved area will remain intact until the next time the BASIC cold start routine is executed—normally at the next reset. The setting is unaffected by RUN/STOP- RESTORE. As mentioned above, this area can't be easily used for machine language routines since it is in block 1. One ap-
propriate use for a reserved area here would be for a data buffer—to hold downloaded text in a telecommunications pro- gram, for example.