Whenever a BASIC program stops because of an END or STOP statement, or because the end of the program has been reached, or because the RUN/STOP key has been pressed, then the STOP/END routine $4BCB will be executed. That routine stores the line number where the program stopped in this pair of locations (in low-byte/high-byte format). The CONT routine $5A60 uses the value here to determine where to restart the program. These locations are also used for temporary storage during the RENUMBER routine $5AF8.
Each time a BASIC program line is executed, the address of the first character of program text in the line is stored in these locations. The high byte ($1203) is also used as a flag to indicate whether the program can continue after being halted. The CONT routine $5A60 will give a CAN’T CONTINUE error message if the flag byte is 0/$00. The flag location is initialized to 0/$00 during the CLR routine $51F8-you can’t CONTinue a program before it is run. If the program halts without errors, the flag location will hold the high byte of the address of the line where the program stopped, which will always be nonzero, so the program can be CONTinued. However, if the program stopped because of an error, or if any lines are changed after the program has stopped, then the flag location will be reset to zero and the program cannot be CONTinued.
The values in these locations determine which characters will be used for the redefinable characters in the PRINT USING format. The default values are copied from locations $5250- $5253 in BASIC ROM during the CLR routine, so the default definitions will be restored each time a program is run. In BASIC, the definitions here can be changed using the PUDEF statement.
Whenever a BASIC error occurs, the ERROR routine $4D3C stores the error number here. The reserved variable ER always reflects the value in this location. Refer to the entry for the error message table $484B for a complete list of error numbers. Once an error number is stored here, the value is retained until another error occurs or until the location is reinitialized. This location is initialized to 255/$FF during CLR $51F8 (also executed as part of NEW and RUN). This setting results in a value of -1 in the reserved variable ER, so when ER contains that value no error has yet occurred.
Whenever a BASIC error occurs, the ERROR routine $4D3C checks the run mode flag (127/$7F) to see if the error occurred in a program line or an immediate mode line. If the error was in a program line, the current line number is copied here from locations 59-60/$3B-$3C. The reserved variable EL always reflects the value in these locations. Once a line number is stored here, it will be retained until another error occurs or until the locations are reinitialized. These locations are initialized to 65535/$FFFF during CLR $51F8 (also executed as part of NEW and RUN). Thus, when the reserved variable EL contains 65535 no error has yet occurred.
When error trapping is enabled with the TRAP statement, the target line number to which the program will be directed when an error occurs is stored here (in standard lowbyte/high-byte order). Location 4620/$120C is also used as a flag to determine whether trapping is enabled. The flag location is initialized to 255/$FF during CLR (which is also part of NEW and RUN). Since the high bytes of all valid line numbers are less than 255/$FF, trapping is considered disabled as long as the flag location contains that value. When trapping is enabled, the ERROR routine $4D3C will transfer control to the line number indicated here whenever a BASIC error occurs.
When an error is trapped to a specified line, the ERROR routine $4D3C copies the high byte of the target line number from 4620/$120C into this location, then stores the value 255/$FF in 4620/$120C. This disables the trapping of errors during the error-handling routine, which would otherwise put the program into an infinite loop. The value here is copied back into 4620/$120C during execution of the RESUME statement $5F62.
Whenever an error occurs, the ERROR routine $4D3C copies the value in 4610-4611/$1202-$1203 into these locations. The HELP subroutine that highlights the portion of the line where the error occurred uses the value here to determine where to begin the highlighting. The RESUME routine $5F62 uses the value here to determine where to resume execution.
These locations contain the address of the location immediately following the end of BASIC program text. The NEW statement $51D6 initializes the value here to two bytes beyond the address in the start-of-program pointer (45-46/ $2D-$2E). The value here is updated to reflect the new ending address whenever a line is added or deleted from the program. An OUT OF MEMORY error occurs if the value here ever exceeds the value in $1212-$1213. Following a LOAD or DLOAD, these locations are set to one byte beyond the last location to which data was loaded. For a SAVE or DSAVE, the value here determines the last address from which data will be saved.
The value in this pair of locations determines the top of free memory in block 0 RAM. The address will be one location beyond the highest one available for BASIC program text. An OUT OF MEMORY error will occur when the value in locations $1210-$1211 exceeds the value here. The BASIC cold-start initialization subroutine $4045 writes the value 65280/$FF00 here, so that all block 0 RAM below the MMU registers is available for program text. You can reserve an area at the top of program memory by reducing the value in these locations. Unlike some of the other pointers, you need only store the new value here; no subsequent NEW or CLR is required.
This pair of locations is used to temporarily hold the CHRGET text pointer value (from 61-62/$3D-$3E) during execution of the DO statement $5FE0.
This pair of locations is used to temporarily hold the current line number value (from 59-60/$3B-$3C) during execution of the DO statement $5FE0.
The BASIC function USR calls a machine language routine, like SYS, but it also allows a numeric value to be passed to and from the ML routine. The routine in BASIC ROM that executes USR ends with a JMP $1218. Location 4632/$1218 contains 76/$4C, the machine language JMP instruction. Locations 4633-4634/$1219-$121A should contain the address of the target machine language routine (in the usual lowbyte/high-byte format). You must explicitly load these locations with the address of the target routine before you use USR. This location is initialized to 32040/$7D28 during BASIC cold start. This is the address of the routine that issues the ILLEGAL QUANTITY ERROR message, which is what you’ll get if you use USR without changing locations 4633-4634/$1219-$121A. Refer to Chapter 5 for more information on passing values to and from the called routine.
This five-byte area holds the seed value for BASIC’s randomnumber-generator routine $8434. When a positive argument is supplied, the RND routine generates the next random number by performing calculations and manipulations with the value here. The generated values aren’t really random-any given seed value here will always produce the same result. However, the process is sufficiently complicated that the results aren’t easily predictable. Whenever any random number is generated, the resulting value is stored here for possible use as the seed for the next random number. Location 4635/$121B is initialized to 0/$00 during the BASIC cold-start routine. That is a change from previous Commodore models, where all five bytes of the seed value were initialized. The zero byte has the effect of making the initial seed value 0, so the first random number value generated after the computer is turned on or after a reset will always be 1.07870447E-03.
This location is used during the BASIC CIRCLE statement routine $668E to hold the number of degrees to turn for each segment of the circle. The value here is set from the ninth parameter in the CIRCLE statement, and defaults to 2 if that parameter is omitted.
Although Commodore literature states that this location holds a value relating to the reset status, no reference to this location occurs in any ROM routine.
The value here determines the tempo for notes played by the BASIC PLAY statement. The value here is subtracted from the sound duration value for each voice (in locations $1223-$1228) during each pass through the BASIC IRQ routine. The larger the value here, the faster the duration decreases and the faster each note plays. The value here is initialized to 16/$10 during the SID initialization routine $4112, part of both the BASIC cold start and warm start sequences. In BASIC, the TEMPO statement can be used to change the value here.
These locations hold the durations of the current PLAY statement notes for each of the SID chip voices:
Bit 7 of each of the high bytes (4644/$1224, 4646/$1226, and 4648/$1228) is used to indicate whether a note is currently being played by that voice. The voice is active when that bit is %0. The duration value for each active voice is decremented by the tempo value specified in location $1222 during each pass through the BASIC IRQ routine $A84D. When a duration is decremented below $0000, the high byte will roll over to $FF, which will set bit 7 to %1, marking the end of the note. At this point, the gate bit for the voice will be turned off, stopping sound output for that voice. Large tempo values cause the value here to decrease more rapidly, increasing the speed at which notes are played, while small tempo values increase the note time. The high bytes for all three voices are set to 255/$FF by the SID initialization routine $4112, part of both the BASIC cold start and warm start sequences. This makes all voices initially inactive. When the PLAY statement plays a note, the duration for that note will be copied from $1229-$122A into the slot for the voice specified for that note.
When the PLAY statement prepares a note, the duration for the note is first calculated in this location, then transferred to the proper slot in $1223-$1228. The value here is set to 288/$0120, the value for a quarter note, by the SID initialization routine $4112, part of both the BASIC cold start and warm start sequences.
The value in this location determines the octave for the current notes played by the PLAY statement. This value will affect the calculation of the frequency for the notes. The value here is set to 4/$04, the octave containing middle C, by the SID initialization routine $4112, part of both the BASIC cold start and warm start sequences. The octave value here remains in effect until changed by an 0 parameter in the PLAY string.
The value in this location holds a value that indicates whether the current note will be either sharp or flat. The location normally holds 0/$00 for natural notes. When a # character is found in the PLAY string, this location will be set to 1/$01 to indicate that the next note should be sharp. When a $ character is found in the string, this location will be set to 255/$FF to indicate that the next note should be flat.
When the PLAY statement prepares a note, the frequency for the note is calculated in these locations before being transferred into the SID chip registers for the specified voice. The frequency is calculated by loading a base frequency for the specified note from the table at 28665-28688/$6FF9-$7010, adjusted for the octave specified in $122B. If the flag at $122C indicates that the note is to be sharp or flat, the frequency is adjusted accordingly.
The value in this location specifies which voice will be used to play the next note. The value here is set to 0/$00 by the SID initialization routine $4112, part of both the BASIC cold start and warm start sequences. This selects voice 0 as the default voice. The value here will remain in effect until changed by a V parameter in the PLAY string. The parameter value will be reduced by 1 to convert the BASIC voice number (1-3) to a VIC voice number (0-2).
The values in these locations determine which waveforms will be used for each of the three voices:
These locations hold the waveform value for the instrument specified for the voice. All three voices are initialized to the default value for instrument O. This selects a default pulse waveform for all three voices. The value here remains in effect until changed by a T parameter in the PLAY string. The T parameter causes the value for the current voice to be changed to the waveform value for the specified instrument from the table at $123F-$1270.
The value in this location determines whether the next note will be normal or “dotted.” Dotted notes play Ph times as long as a standard note. This location normally holds 0/$00, but will be set to 35/$23 if a period (.) is found in the play string. In this case, the duration of the next note will be increased by 50 percent.
The filter parameters are copied here from 4721-4722/ $1271-$1272 at the beginning of the FILTER statement routine $7046. The filter parameter manipulations are then performed on these locations, and the results are copied back to the working storage area.
This location is used as a mask value to select individual filter control bits when evaluating the FILTER statement parameters.
This location is used as working storage by the FILTER and ENVELOPE routines.
This location will hold the instrument number specified in the most recent ENVELOPE statement.
The current parameters for the specified instrument are read from the instrument table into these locations at the beginning of the ENVELOPE routine $70C1:
If the ENVELOPE statement specifies new values for any of these parameters, the new values replace the original values here. The values here are then copied back into the table entries for the specified instrument number.
This value is used during the ENVELOPE routine $70C1 to hold the index to the current set of instrument parameters.
This area is used to hold the envelope parameters for the ten defined instruments supported by the PLAY statement $6DE1:
Instrument | Attack/Decay | Sustain/Release | Waveform | Pulsewidth low byte | Pulsewidth high byte |
---|---|---|---|---|---|
0 | 4671/$123F | 4681/$1249 | 4691/$1253 | 4701/$125D | 4711/$1267 |
1 | 4672/$1240 | 4682/$124A | 4692/$1254 | 4702/$125E | 4712/$1268 |
2 | 4673/$1241 | 4683/$124B | 4693/$1255 | 4703/$125F | 4713/$1269 |
3 | 4674/$1242 | 4684/$124C | 4694/$1256 | 4704/$1260 | 4714/$126A |
4 | 4675/$1243 | 4685/$124D | 4695/$1257 | 4705/$1261 | 4715/$126B |
5 | 4676/$1244 | 4686/$124E | 4696/$1258 | 4706/$1262 | 4716/$126C |
6 | 4677/$1245 | 4687/$124F | 4697/$1259 | 4707/$1263 | 4717/$126D |
7 | 4678/$1246 | 4688/$1250 | 4698/$125A | 4708/$1264 | 4718/$126E |
8 | 4679/$1247 | 4689/$1251 | 4699/$125B | 4709/$1265 | 4719/$126F |
9 | 4680/$1248 | 4690/$1252 | 4700/$125C | 4710/$1266 | 4720/$1270 |
All three voices are initially assigned the envelope parameters for instrument O. These settings remain in effect until changed with a T parameter in the PLAY string.
The values for any table entry can be changed using the ENVELOPE statement. Default instrument table values are copied into this area from a table in ROM at 28689-28728/ $7011-$7038 during the SID initialization routine $4112, part of both the BASIC cold start and warm start sequences. The default values are as follows:
Envelope | Attack/Decay | Sustain/Release | Waveform | Pulsewidth |
---|---|---|---|---|
0 (piano) | 9/$09 | 0/$00 | 65/$41 (pulse) | 1791/$06FF |
1 (accordion) | 192/$C0 | 192/$C0 | 33/$21 (sawtooth) | 0/$0000 |
2 (calliope) | 0/$00 | 240/$F0 | 17/$11 (triangle) | 255/$00FF |
3 (drum) | 5/$05 | 80/$50 | 129/$81 (noise) | 0/$0000 |
4 (flute) | 148/$94 | 64/$40 | 17/$11 (triangle) | 255/$00FF |
5 (guitar) | 9/$09 | 33/$21 | 33/$21 (sawtooth) | 0/$0000 |
6 (harpsichord) | 9/$09 | 0/$00 | 65/$41 (pulse) | 767/$02FF |
7 (organ) | 9/$09 | 144/$90 | 65/$41 (pulse) | 2048/$0800 |
8 (trumpet) | 137/$89 | 65/$41 | 65/$41 (pulse) | 767/$02FF |
9 (xylophone) | 9/$09 | 0/$00 | 17/$11 (triangle) | 0/$0000 |
Note that the pulsewidth values here are different from those specified in Commodore literature. The official values assume that all pulsewidth low bytes will be 0/$00. However, these bytes are not explicitly initialized, so they will hold their previous values after a reset. On power on, alternating pulsewidth low-byte locations will hold 255/$FF instead of 0/$00.
These locations hold the current cutoff frequency register setting, an 11-bit value divided among the two locations with bits 0-2 of the value in location 4721/$1271 and bits 3-10 of the value in location 4722/$1272. The value is copied to the SID cutoff frequency registers ($D415-$D416) when the X1 parameter is included in the PLAY string.
Bits 0-3 of this location determine which voices will be filtered and bits 4-7 control the filter resonance setting. The resonance setting can be changed using the FILTER statement. When an X1 parameter is included in the PLAY string, the filter control bit in this location corresponding to the current voice will be set to %1 and the value here will be copied into the SID register at $D417 to enable filtering of that voice. When an X0 parameter is included, the corresponding voice bit will be set to %0 and the value will again be copied to the SID register to turn off filtering for that voice.
Bits 4-6 of this location determine the type of filtering currently enabled. The setting of those bits can be changed using the FILTER statement. Because the SID register that controls filter type also controls volume, bits 0-3 of this location reflect the current volume setting as well. When an Xl parameter is included in a PLAY string, the value here is copied into the SID register at $D418 to enable the specified filter type. This location is set to 15/$0F, the value for all filters off and maximum volume, during the SID initialization routine $4112, part of both the BASIC cold start and warm start sequences.
Bits 0-3 of this location reflect the current volume setting for the SID chip. The value here can be changed either with the VOL statement or with the U parameter in a PLAY string. Because the SID register which controls volume also controls filter type selection, bits 4-6 of this location will reflect filter type as well. The value here is set to 15/$0F, the value for maximum volume, during the SID initialization routine $4112, part of both the BASIC cold start and warm start sequences.
The VIC internal interrupt register ($D019) is read during each pass through the BASIC IRQ routine $A84D to determine if a sprite collision has occurred or if a new light pen value has been latched. Because that register is automatically cleared after a read, the system uses these locations to record which conditions were detected:
Location | Collision type |
---|---|
$1276 | Sprite-sprite collision |
$1277 | Sprite-foreground collision |
$1278 | Light pen latch |
If a collision has occurred, the corresponding flag location will be set to 255/$FF, but only if the collision type has been enabled by setting to %1 the appropriate bit in location $127F. All three of these locations are set to 0/$00 during the SID initialization routine $4112, part of both the BASIC cold start and warm start sequences. A location set to 255/$FF will be reset to 0/$00 after COLLISION processing in the GONE routine $4A9F.
If the trapping of sprite collisions or light pen latches is enabled, a BASIC subroutine will be called (effectively a GOSUB) whenever one of the selected events occurs. These locations are used to hold the number (in low-byte/high-byte integer format) of the starting BASIC program line of the subroutine to be called. (The subroutine should end with a RETURN statement.) The values here can be set with the COLLISION statement.
Low byte | High byte | Collision type |
---|---|---|
4729/$1279 | 4732/$127C | sprite-sprite |
4730/$127A | 4733/$1270 | sprite-foreground |
4731/$127B | 4734/$127E | light pen |
Bits 0-2 of this location indicate the collision types for which trapping is currently enabled:
Bit | Collision type |
---|---|
0 | sprite-sprite |
1 | sprite-foreground |
2 | light pen |
Trapping is enabled if the bit is set to %1. Enabling trapping will allow the corresponding collision type to be recorded in the flags at $1276-$1278. Bits 3-7 of this location are unused. The value here is reset to 0/$00 during the BASIC cold-start sequence. This disables all COLLISION branching.
The value here is used during the COLLISION routine $7164 to hold an index into the line number table at $1279-$127E.
The value in this location specifies which group of entries in the following table should be loaded with the current SOUND parameters. The value here is set to the value of the first parameter in the SOUND statement, minus 1 to convert the BASIC voice number (1-3) into a SID voice number (0-2).
These locations hold the current SOUND parameters for the three SID chip voices:
Parameter | Voice 0 | Voice 1 | Voice 2 |
---|---|---|---|
Duration (low) | 4738/$1282 | 4739/$1283 | 4740/$1284 |
Duration (high) | 4741/$1285 | 4742/$1286 | 4743/$1287 |
Frequency (low) | 4744/$1288 | 4745/$1289 | 4746/$128A |
Frequency (high) | 4747/$128B | 4748/$128C | 4749/$128D |
Minimum frequency (low) | 4750/$128E | 4751/$128F | 4752/$1290 |
Minimum frequency (high) | 4753/$1291 | 4754/$1292 | 4755/$1293 |
Step direction | 4756/$1294 | 4757/$1295 | 4758/$1296 |
Step size (low) | 4759/$1297 | 4760/$1298 | 4761/$1299 |
Step size (high) | 4762/$129A | 4763/$129B | 4764/$129C |
Current frequency (low) | 4765/$129D | 4766/$129E | 4767/$129F |
Current frequency (high) | 4768/$12A0 | 4769/$12A1 | 4770/$12A2 |
Bit 7 of each of the duration high-byte values (locations 4741-4743/$1285-$1287) is used to indicate whether any SOUND statement is active for the corresponding voice. If the bit is %0, the voice is assumed to have an active sound, and the current frequency value for the voice will be copied into the SID chip frequency registers during each pass through the BASIC IRQ routine $A84D. Also during each pass through the interrupt routine, the duration value for each active voice will be decremented. When the value is decremented below $0000, the high byte will roll over to 255/$FF, setting bit 7 to %1, which marks the end of the sound. At this point the gate bit for the voice will be set to %0 to turn off the sound.
Each of the duration high-byte locations will be set to 255/$FF during the SID initialization routine, part of both the BASIC cold start and warm start sequences. This will turn off SOUND output for all three voices. The values in these locations are updated when the contents of 4771-4776/$12A3-$12A8 are copied to the entries for the specified voice during execution of the SOUND statement $71EC.
These locations are used to assemble the parameters for the current SOUND statement. The SOUND statement must include voice number, frequency, and duration parameters. The remaining parameters are optional; if they are omitted, default values are supplied. The base frequency value is initialized to the specified starting frequency. The locations and default values are as follows:
Parameter | Locations | Default value |
---|---|---|
Duration | 4771-4772/$12A3-$12A4 | |
Frequency | 4773-4774/$12A5-$12A6 | |
Minimum frequency | 4775-4776/$12A7-$12A8 | 0/$0000 |
Step direction | 4777/$12A9 | 0/$00 (sweep up) |
Step size | 4778-4779/$12AA-$12AB | 0/$0000 (no sweep) |
Base frequency | 4780-4781/$12AC-$12AD | |
Pulsewidth | 4782-4783/$12AE-$12AF | 2048/$0800 |
Waveform | 4784/$12B0 | 2/$02 (pulse) |
After all the parameters for a SOUND statement have been evaluated and assembled here, the values are transferred to the entries in the table at $1282-$12A2 for the specified voice. The base frequency value is used as the beginning current frequency value.
This location is used as temporary storage during the routines to perform the BASIC functions POT $824D and PEN $82AE.
During execution of the POT function routine $824D, the potentiometer reading from the SID chip register is stored here temporarily while the paddle buttons are being read.
When the WINDOW statement $72CC is executed, the parameter values associated with the statement are stored in these locations before the screen editor WINDOW routine $C02D is called to actually set the new window margins.
Location | Parameter |
---|---|
4787/$12B3 | left column |
4788/$12B4 | top row |
4789/$12B5 | right column |
4790/$12B6 | bottom row |
The routine which handles the BASIC 7.0 DOS support commands such as SCRATCH and RENAME copies the filename portion of the command here temporarily while the remainder of the command is being processed. Once the command is set up, the filename here is copied into the DOS command buffer at $1100-$112F
These locations are used during the SPRDEF statement routine $7372 to hold the original sprite pattern while a sprite is being defined. If the STOP key is pressed to cancel the current modifications, the pattern definition here will be restored to the definition area for the sprite. The first 63 of these locations are also used during the SPRSAV routine $76EC to hold the sprite pattern to be transferred to a string variable.
During the SPRSAV routine $76EC, these locations are initialized with the pattern $17 $00 $14 $00. When a sprite pattern is saved in a string variable, these bytes are appended to the sprite pattern in $12B7-$12F5 before the data is transferred to the string pool. Two bytes are needed as the tag for the variable, but exactly what this four-byte pattern is intended to achieve is unclear.
This location is used during the SPRDEF statement routine $7372 to hold a value indicating the mode of the sprite currently being defined. A value here of 0/$00 indicates a standard sprite, while a value of 128/$80 indicates a multicolor sprite.
This location is used during the SPRDEF statement routine $7372 to hold the number of the vertical line (0-20) within the sprite pattern which is currently being defined.
This location is used during the SPRDEF statement routine $7372 to hold the number (0-7) of the sprite currently being defined.
This location is tested at the beginning of the BASIC IRQ service routine $A84D. If it contains any nonzero value, the routine exits immediately. The location is initialized to 0/$00 during the SID initialization routine $4112. The BASIC IRQ routine increments this location (to 1/$01) when it begins, so the test prevents the routine from being restarted if another interrupt occurs before the current pass is completed. The IRQ routine resets the value here to 0/$00 before exiting.
The BASIC portion of the IRQ sequence is responsible for moving sprites, detecting sprite collisions, and handling the BASIC sound statements. The routine maintains a number of shadow locations which are copied into VIC and SID chip hardware registers during each interrupt. Sometimes you may want to turn off these shadow locations to have direct access to the hardware registers. One way to do that is to store some nonzero value in this location. While turning off the BASIC IRQ routine will give you direct access to the hardware registers, you should keep in mind that it will also effectively disable the BASIC statements MOVSPR, COLLISION, SOUND, and PLAY.
These locations are not used by any 128 ROM routine