In this page...


Index

$0A00-$0AFF - Kernal and Screen Editor Working Storage, Monitor Working Storage Area, Kernal Working Storage

Kernal and Screen Editor Working Storage ($0A00-$0A7F)

2560-2561 $0A00-$0A01 SYSTEM_VECTOR

BASIC restart vector

This pair of locations contains the address of the routine that will be used to restart BASIC. The RAMTAS routine $E093, part of the reset sequence, puts the value $4000 here the address of the BASIC cold start routine. Unless the Commodore or RUN/STOP keys are held down, the RESET routine $E000 ends with a JMP ($0A00) to cold start BASIC. One of the final steps in the BASIC cold start routine is to change the value here to $4003 - the address of the BASIC warm start routine.

The RUN/STOP-RESTORE sequence in the NMI handling routine $FA40 ends with a JMP ($0A00). Because of the cold start’s routine initialization, this will normally cause a warm start of BASIC. However, you can make RUN/STOP-RESTORE cause a jump to another routine by changing the value in these locations to point to the address of the new routine. The only restriction is that the target routine must be visible in the bank 15 configuration, since that is how memory is arranged when the JMP is executed.

The monitor X command routine $B0E3 also performs a JMP ($0A00), so the value in these locations determines the address of the routine which will be executed when you use that command to exit the built-in machine language monitor.

2562 $0A02 DEJAVU

Memory initialization status flag

This location is used to indicate whether the RAMTAS routine has been performed. If the RESET routine $E000 detects that the RUN/STOP key is being held down, indicating that the reset sequence should end by entering the monitor rather than BASIC, then the value here will be tested. If this location contains the value 165/$A5, the RAMTAS routine will be omitted from this reset sequence. The routine will hold a random value when the computer is first turned on, but the first call of the RAMTAS routine $E093 will initialize this location to 165/$A5. Thus, once RAMTAS has been performed at least once, the test of this flag location can be used to prevent its being performed again when entering the monitor after a reset. This allows you to preserve the contents of zero page, normally cleared by RAMTAS during the reset.

2563 $0A03 PALNTS

PAL/NTSC flag

The IOINIT routine $E109, part of the RESET sequence, checks the number of scan lines produced by the VIC chip to determine whether the 128 is using a NTSC (North American) or PAL (European/British) video system. This location is set to reflect the result of that test: to 0/$00 for NTSC systems or 255/$FF for PAL systems. Later routines that initialize the video chips and timers can then adjust the default settings accordingly. This eliminates the need for different versions of the Kernal ROM for different countries.

2564 $0A04 INIT_STATUS

System initialization status flag

This location is initialized to 0/$00 near the beginning of the Kernal RESET routine $E000. Bits are then set to %1 by later routines to indicate that certain initialization steps have been performed.

Bit 0: This bit is set to %1 during the BASIC cold start routine $4023 to indicate that the cold start has been performed. The IRQ handling routine $FA65 checks this bit and calls the BASIC IRQ routine $A84D only if the bit is %1. The BASIC IRQ routine, which handles sprite movement, sprite collision detection, and sound generation, copies the contents of a number of shadow locations into VIC and SID hardware registers. One way to turn off this interrupt routine and gain direct access to the hardware registers is to set this bit to %0.

Bits 1-5: Unused.

Bit 6: This bit is tested during the screen editor initialization (CINT) routine $C07B to determine whether the keyboard table pointers and function key definitions need to be initialized. If the bit is %0, the default pointer values and key definitions will be copied from ROM into the proper areas of RAM; then this bit will be set to %1. While this bit is %1, the pointer and function key initialization portion of the routine will be skipped. CINT is part of both the reset and RUN/STOP-RESTORE sequences, but the pointers and key definitions are normally initialized only during the reset sequence, which resets this bit to %0 before calling CINT. Custom keyboard table pointers and function key definitions are usually preserved during RUN/STOP-RESTORE, which does not affect this bit.

Bit 7: This bit is tested during the IOINIT routine $E109 to determine whether the 80-column (VDC) character set needs to be initialized. If the bit is %0, the INITSO routine $CE0C will be called to copy the standard character patterns from ROM into the VDC chip’s private RAM; then this bit will be set to %1. While this bit is %1, the character initialization portion of the routine will be skipped. IOINT is part of both the reset and RUN/STOP-RESTORE sequences, but the character patterns are normally initialized only during the reset sequence, which resets this bit to %0 before calling IOINT. Custom 80-column characters are usually preserved during RUN/STOP-RESTORE, which does not affect this bit.

2565-2566 $0A05-$0A06 MEMSTR

Kernal MEMBOT pointer

This pair of locations holds the default value of the lowest memory address available in block 0 RAM. The value here can be read or changed using the Kernal MEMBOT routine $F772, which has a Kernal jump table entry at 65436/$FF9C. The RAMTAS routine, part of the RESET sequence, calls MEMBOT to initialize these locations to 7168/$1C00. However, the value here is not used by any other system routine, so changing this value will not affect system operation in any way. This is a change from the Commodore 64, where the value in the MEMSTR pointer is used to establish the lowest address available of BASIC. In the 128, the start-of-BASIC pointer is always initialized to 7169/$1C01, regardless of the value here.

2567-2568 $0A07-$0A08 MEMSIZ

Kernal MEMTOP pointer

This pair of locations holds the default value of the highest memory address available in block 0 RAM. The value here can be read or changed using the Kernal MEMTOP routine $F763, which has a Kernal jump table entry at 65433/$FF99. The RAMTAS routine, part of the RESET sequence, calls MEMTOP to initialize these locations to $FF00. However, the value here is not used by any other system routine, so changing this value will not affect the system operation in any way. This is a change from the Commodore 64, where the value in the MEMSIZ pointer is used to establish the highest address available for BASIC variable storage. In the 128, the top-of-BASIC pointers are always initialized to $FF00, regardless of the value here.

2569-2570 $0A09-$0A0A IRQTMP

Temporary storage for IIRQ vector during tape operations

These locations are used for temporary storage of the address value in the IIRQ vector at $0314-$0315 during tape operations. The tape routines stash the current IIRQ address here, then substitute the address of the IRQ service routine to handle the tape operation. Upon completion of the operation, the original address stored here will be restored to the IIRQ vector.

Location 2570/$0A0A is also used as a flag to indicate whether or not a tape IRQ routine is active. That location is initialized to 0/$00 by the IOINIT routine, part of the RESET sequence, and will also be reset to that value upon completion of the tape operation. Thus, a nonzero value in the flag location indicates that a tape interrupt routine is active.

2571 $0A0B CASTON

CIA #1 control register A log

This location is used to record the status of CIA #1 control register A ($DC0E) during tape operations.

2572 $0A0C

CIA #1 interrupt control register log

This location is used to record the status of the CIA #1 interrupt control register ($DC0D) during tape operations.

2573 $0A0D

CIA #1 timer A status log

The CIA #1 control register A log value from $0A0B is stored here during certain tape operations to preserve the timer A status.

2574 $0A0E TIMOUT

IEEE timeout flag

When the VIC-20 was introduced, its Kernal included a jump table entry (SETTMO, at $FFA2) to support a proposed IEEE bus interface. The IEEE bus is the parallel data bus used by Commodore’s original PET /CBM models for communications with peripheral devices. The interface was never introduced, but the Kernals of all subsequent Commodore models have slavishly included the SETTMO jump table entry. In the 128, the SETTMO routine $F75F does nothing more than store the accumulator contents in this location. This location is not used by any other 128 routine, and is provided strictly to maintain Kernal jump table compatibility with previous Commodore models.

2575 $0A0F ENABL

RS-232 activity flag

This location is used during the RS-232 routines to record the value in the CIA #2 interrupt control register ($DD0D). CIA #2 interrupt requests generate the NMI interrupts that drive RS-232 transmission and reception. While the CIA #2 interrupts for RS-232 are disabled, this location will be set to 0/$00. When bits are set in the CIA #2 interrupt control register to enable RS-232 operations, the corresponding bits are also set in this location. If any of the following bits is set to %1, the corresponding interrupt is enabled:

Bit Interrupt source RS-232 activity
0 Timer A bits being transmitted
1 Timer B bits being received
4 FLAG line waiting for start bit to be received

This location is initialized to 0/$00 during the IOINIT routine $E109, part of the reset and RUN/STOP-RESTORE sequences.

2576 $0A10 M51CTR

RS-232 control register

This location controls some of the operating characteristics of the RS-232 interface. When a file is opened to device 2, the first character of the filename is copied here. Although RS-232 communications in the 128 are managed by software, the bits of this location are defined to simulate the control register of a 6551 UART chip, a hardware device for controlling serial communications. The bits are used as follows:

Bits 0-3: These bits determine the baud rate for both transmission and reception-the rate (in bits per second) at which bits will be sent or received. Valid settings are as follows:

Bits 3-2-1-0 Bit value Baud rate
0 0 0 0 0 user defined
0 0 0 1 1 50 baud
0 0 1 0 2 75 baud
0 0 1 1 3 100 baud
0 1 0 0 4 134.5 baud
0 1 0 1 5 150 baud
0 1 1 0 6 300 baud
0 1 1 1 7 600 baud
1 0 0 0 8 1200 baud
1 0 0 1 9 1800 baud
1 0 1 0 10 2400 baud

When the user-defined rate is selected, the baud rate is determined by the value in locations $0A12-$0A13. The remaining possible bit patterns, %1011-%1111, result in invalid baud rates.

Bit 4: Unused.

Bits 5-6: These bits determine the number of data bits in each character sent or received (sometimes referred to as the word size). The total character length will also include a start bit, possibly a parity bit, and one or more stop bits.

Bits 6 5 Bit value Number of data bits
0 0 0 8 data bits
0 1 32 7 data bits
1 0 64 6 data bits
1 1 96 5 data bits

Bit 7: This bit determines the number of stop bits in each character. Stop bits are %1 bits added to the end of the character. They represent the minimum amount of time the communications line will remain at the low (%1 bit) level before the next start bit can be sent or received.

Bit 7 Bit value Number of stop bits
0 0 1 stop bit
1 128 2 stop bits

2577 $0A11 M51CDR

RS-232 command register

This location controls some of the operating characteristics of the RS-232 interface. When a file is opened to device 2, the second character of the filename, if any, is copied here. Although RS-232 communications in the 128 are managed by software, the bits of this location are defined to simulate the command register of a 6551 UART chip, a hardware device for controlling serial communications. The bits are used as follows:

Bit 0: This bit controls the handshaking mode for RS-232 transmission and reception. The RS-232 interface consists of three primary signal lines-transmitted data, received data, and ground-plus a number of supplementary control linesdata set ready (DSR), data terminal ready (DTR), ready to send (RTS), and clear to send (CTS). The control lines are called handshaking lines because they allow the sending and receiving units to exchange signals (handshakes) indicating whether data is being successfully transmitted and received. The 128’s RS-232 software interface can operate in two different modes: 3-line, where none of the handshaking lines are used, and xline, where all of the handshaking lines are used. These bits control the interface mode as follows:

Bit 0 Interface mode
0 3-line interface (no handshaking)
1 x-line interface (full handshaking)

For 3-line mode, the output handshaking lines (DTR and RTS) will be held at a constant high (+5 volts) level. The input handshaking lines (DSR and CTS) will be ignored.

Bits 1-3: Unused.

Bit 4: For unknown reasons, Commodore literature continues to indicate that this bit controls the duplex mode of the RS232 interface. The bit is supposed to select full duplex when set to %0 or half duplex when set to % 1. However, this bit is not checked by any RS-232 routine, and its setting has no effect on the operation of the interface. Duplex is often confused with local echo. A full-duplex interface can simultaneously send and receive data, while a half-duplex interface can send data and receive data, but not both at the same time. The 128’s RS-232 interface always operates in full-duplex mode. In casual usage, however, duplex is often used to describe whether or not the system echoes back the characters it receives. In remote echo mode (incorrectly referred to as full duplex), the system displays only characters received from the remote unit (the one being called). The assumption is that the remote unit will send back an “echo” of each character it receives from the system. In local echo mode (incorrectly called half duplex), the system displays the characters it sends as well as the ones it receives. The assumption in this case is that the remote unit will not echo the characters it receives.

Bits 5-7: This bit controls the parity generated for transmitted characters and the parity tested for in received characters. Parity is a simple method of detecting some errors in data transmission. A parity bit can be added between the data and stop bits in the character. The value of the parity bit is selected to make the total number of %1 bits in the character (not counting stop bits) either even or odd. The receiving unit can then count the number of %1 bits in the received character to determine if bits have been garbled in transmission. Parity checking did not work properly in the original versions of the Commodore 64 Kernal ROM, but that problem has been corrected in the 128’s Kernal (and in the version of 64 Kernal ROM for the 128’s 64 mode). Possible parity selections are as follows:

Bits 7 6 5 Parity selection
x x 0 parity not used
0 0 1 odd parity
0 1 1 even parity
1 0 1 mark parity
1 1 1 space parity

If bit 5 is %0, no parity bit will be generated in transmitted characters and the system will expect incoming characters to have no parity bit. This selection is common when a word size of eight data bits per character is used. Odd parity means that a parity bit will be generated for each transmitted character such that the character will have an odd total number of %1 bits (not counting the stop bits). When even parity is selected, the parity bit will be set to make the total number of %1 bits in the character even. For either even or odd parity, the number of %1 bits in each character received will be counted and compared against the parity selection. If the number does not match the specified parity type, the error will be indicated by setting bit 0 of the status register location $0A14 to %1. Mark and space parity are alternate forms of no parity. When mark parity is selected, the parity bit for each transmitted character will always be set to %1, and the parity bit for each received character will be ignored. When space parity is selected, the transmitted parity bit will always be %0 and the received parity bit will be ignored.

2578-2579 $0A12-$0A13 M51AJB

RS-232 baud-rate factor

The value in these locations determines the baud-rate timing factor. When a file is opened to device 2, the third and fourth characters of the filename are copied here (if the filename has that many characters). However, the filename characters are meaningful only if a user-defined baud rate has been specified - if bits 0-3 of the first character of the filename (copied into 2576/$0A10) are %0000. In that case, the value in these locations specifies the baud rate according to the following formula:

baud rate = clock frequency / (2 * (rate factor + 100))

For the standard baud-rate settings, the Kernal RS-232 OPEN routine copies the proper rate factor into these locations from tables in Kernal ROM ($E850-$E863 for NTSC systems or $E864-$E877 for PAL systems). The two separate tables are required because the different video systems use different clock frequencies.

There’s rarely a need to specify a custom baud rate, since the standard settings encompass all standard rates that the 128 can support. (The 128 cannot handle RS-232 communications faster than 2400 baud, so don’t try to specify a faster rate.) However, should you ever want to do so, the formula for the rate factor is as follows:

rate factor = ((clock frequency / desired baud rate) / 2) - 100

The clock-frequency value is 1022730 for NTSC (North American) systems or 985250 for PAL (European) systems. The low byte of the resulting factor should be stored in 2578/$0A12 and the high byte in 2579/$0A13.

2580 $0A14 RSSTAT

RS-232 status register

Although RS-232 communications in the 128 are managed by software, the bits of this location are defined to simulate the status register of a 6551 DART chip, a hardware device for controlling serial communications.

It is possible to read the value here directly, but this location can also be read using the Kernal READSS routine $F744 if the current device number in location $BA is 2 (for RS-232). The READSS routine also has a Kernal jump table entry at 65463/$FFB7. From BASIC, the reserved variable ST will reflect the value in this location as long as the current device number is 2. This location is initialized to 0/$00 each time the Kernal OPEN routine is called to open a file to device 2, the RS-232 interface. The value here is also reset to zero after each call to the READSS routine when device 2 is active, including each reference to the ST variable in a BASIC program.

Bit 0: This bit is the parity-error indicator. It is used only when either even or odd parity is selected, and is relevant only to received characters. The bit is set to %1 whenever a character is received for which the calculated total of %1 bits received for the character does not match the specified parity selection.

Bit 1: This bit is the framing-error indicator. The bit is set to % 1 when a framing error occurs-when no stop bits are found following the specified number of data and parity bits.

Bit 2: This bit is the receiver buffer-overflow indicator. It will be set to %1 when a character is received after the RS-232 input buffer at 3072/$0C00 is already full.

Bit 3: This bit is the receiver buffer-empty indicator. It will be set to % 1 whenever there are no characters waiting to be read from the input buffer. This bit should be tested before each attempt to read characters from the RS-232 interface.

Bit 4: This bit is the CTS-missing error indicator. It is used only when x-line handshaking is selected. The bit will be set to %1 if the CTS (clear to send) input line drops to a low (0 volts) state while data is being transmitted. When x-line handshaking is used, the external device connected to the interface is expected to hold the CTS line at a high (+ 5 volts) state. If the line goes low, it is taken as an indication that the external device is not ready to receive data, so transmission is suspended until CTS goes high.

Bit 5: Unused. This bit should always be %0 when read.

Bit 6: This bit is the DSR-missing error indicator. It is used only when x-line handshaking is selected. The bit will be set to %1 if the DSR (data set ready) signal input line drops to a low (0 volts) state during either transmission or reception of characters. When x-line handshaking is used, the external device connected to the interface is expected to hold the DSR line high (+5 volts). If the line goes low, it is taken as an indication that nothing is connected to the interface.

Bit 7: This bit is the break indicator. A break occurs when, during reception of characters, a byte is received consisting of all %0 bits not followed by stop bits (which are always %1). In other words, a break occurs if the received data signal line is held at the %0 bit (+ 5 volt) level for longer than the time required to receive a character.

2581 $0A15 BITNUM

RS-232 bit count

This location will hold the number of bits prior to the parity and stop bits for each character received or transmitted. The location is initialized during the RS-232 OPEN routine $F040 to the number of data bits (specified in bits 5-6 of $0A10) plus 1. For transmission, the value here is copied into location $B4, the countdown of bits to send. For reception, the value here is copied into location 168/$A8, the countdown of bits remaining to be received.

2582-2583 $0A16-$0A17 BAUDOF

RS-232 baud-rate timing constant

Commodore’s insistence on providing an exact software emulation of the 6551 UART chip leads to some odd software gyrations. The baud-rate timing factor specified in locations $0A12-$0A13 must be converted back into an absolute timing value. The Kernal OPEN routine for RS-232 performs the following calculation:

timing constant = (rate factor * 2) - 200

Given the formula for rate factor, this is equivalent to:

timing constant = dock frequency / baud rate

This yields the number of system clock cycles required to send or receive each bit at the specified baud rate. The resulting value is stored in these locations. When transmission or reception is initiated, the value here is copied into one of the CIA #2 timers. This determines the time between the NMI interrupts that drive the transmission or reception of bits.

2584 $0A18 RIDBE

Index to first character in RS-232 input buffer

This location holds the offset from the start of the RS-232 input buffer to the position where the next character received will be stored. The input buffer normally begins at location $0C00. The value here is incremented before each received character is added to the buffer, unless incrementing would make the value here equal to the value in location $0A19. In that case, a buffer overflow has occurred (more characters have been received than the buffer can hold), so bit 2 of the status location ($0A14) is set to %1.

2585 $0A19 RIDBS

Index to last character in RS-232 input buffer

This location holds the offset from the start of the RS-232 input buffer to the position of the next character waiting to be removed from the buffer. The buffer normally begins at $0C00. The value here is incremented after each character is retrieved from the buffer. When the value here equals the value in location $0A18, all characters have been removed and the buffer is empty. In this case, bit 3 of the status location ($0A14) will be set to %1.

2586 $0A1A RODBS

Index to first character in RS-232 output buffer

This location holds the offset from the start of the RS-232 output buffer to the position of the next character awaiting transmission. The output buffer normally begins at $0D00. The value here is incremented after each character is removed from the buffer for transmission. When the value here equals the value in location $0A1B, all characters awaiting transmission have been sent and the buffer is empty.

2587 $0A1B RODBE

Index to last character in RS-232 output buffer

This location holds the offset from the start of the RS-232 output buffer to the position where the next character will be added to await transmission. The output buffer normally begins at $0D00. The value here is incremented before each character is added to the buffer, unless the incrementing would make the value here equal the value in $0A1A. In that case, the buffer is already full, and some characters must be transmitted before any more can be added to the buffer.

2588 $0A1C SERIAL

Fast serial mode flag

This location is used to indicate whether the currently specified serial bus device, such as the 1571 disk drive, is capable of fast serial communications. The location is initialized to 0/$00, the value for standard (slow) communications, during the IOINIT routine $E109. The routines that handle the serial bus TALK and LISTEN commands attempt a fast serial handshake. If the external device responds properly, bits 6 and 7 of this location will be set to %1. Bit 7 indicates that the external device is capable of fast transmission and reception of individual bytes. The bit is reset to %0 during the Kernal routines that handle the serial bus UNTALK and UNLISTEN routines. Bit 6 indicates that the system is capable of high-speed burst mode loading.

2589-2591 $0A1D-$0A1F TIMER

Software jiffy timer

The three-byte value in these locations is decremented 60 times per second by the Kernal UDTIM routine $F5F8, part of the IRQ sequence. Thus, these locations function in a manner opposite that of the jiffy clock at $A0-$A2, which is incremented 60 times per second by UDTIM. The order of bytes here is the opposite of the order of bytes in the jiffy clock: $0A1D is the low byte and $0A1F is the high byte.

Since the countdown for this timer is handled automatically during the IRQ, it is useful for many timing applications. The way to use this timer is to load the locations with the value in jiffies (1/60-second intervals) for the desired delay period, then test for a value of $FF in location $0A1F. That location will contain $FF after the three-byte value rolls over from $000000 to $FFFFFF at the end of the countdown. The highest allowable initial value when using this scheme is $FF0000, which corresponds to 16,711,680 jiffies-a little over three days.

There is one caution in using this location from BASIC. The SLEEP statement routine $6BD7 uses this timer for its delay countdown, so any use of the SLEEP statement will overwrite any values you may have stored in these locations.

2592 $0A20 XMAX

Maximum number of keys in the keyboard buffer

The value in these locations determines the maximum number of characters that can be held in the keyboard buffer pending processing. The value is initialized to 10/$0A - the full length of the standard keyboard buffer at $034A-$0353 - by the CINT screen editor initialization routine $C07B, part of the reset sequence. During the SCNKEY routine $C55D, the value here is compared against the value in location $D0, the count of characters currently in the buffer, to determine if there is room in the buffer to record another keypress.

You can reduce the value here to decrease the number of unprocessed keypresses that can accumulate in the buffer. However, you should not increase the value above 10, as this will cause overflow from the buffer to overwrite the tab stop table at $0354-$035D.

2593 $0A21 PAUSE

Scroll pause flag

This location is used to pause printing. During the screen BSOUT routine $C72D, the value here is tested. If it is nonzero, the routine will wait indefinitely for the location to be reset to zero. The value is initialized to 0/$00 by the CINT routine $C07B. To implement the pause feature, the SCNKEY routine $C55D, part of the system IRQ sequence, sets this location to 13/$0D when either the NO SCROLL or CONTROL-S keys are pressed, and resets the location to 0/$00 when the next key is pressed.

2594 $0A22 RPTFLG

Key repeat flag

The value here determines which keys, if any, will repeat if held down. If bit 7 of this location is %1 (value 128/$80), all keys repeat. If bit 6 is %1 (value 64/$40), no keys repeat. Otherwise, only the cursor, space, and INST /DEL keys repeat. This location is initialized to 128/$80-all keys repeat-by the screen editor CINT routine $C07B. This is different from the Commodore 64, where the default value is 0/$00-only cursor, space, and INST/DEL repeating.

2595 $0A23 KOUNT

Countdown between key repeats

This location is used as a counter to establish the delay between repeats when a key is held down. Once repeating has begun, indicated by a value of 0/$00 in location $0A24, the value here will be decremented on each pass through the SCNKEY routine $C55D as long as the same key is held down. Each time the count reaches zero, the key is repeated and this location is reinitialized to 4/$04. This results in a key-repeat rate of 15 times per second. The starting value of 4 for this countdown is loaded from ROM in the SCNKEY routine, and thus cannot be changed, so the delay period between repeats is not programmable.

2596 $0A24 DELAY

Countdown until key repeating begins

This location is used as a counter to establish the delay before repeating begins when a key is held down. Location $0A22 controls which keys, if any, will repeat if held down. If the scan code of the current key is the same as the scan code detected on the last pass through the SCNKEY routine $C55D, the value here will be decremented. When the count reaches zero, repeating can begin at the rate determined by location $0A23. When the key is released, this location is reinitialized to 16/$10. This results in a delay before repeating of about 1/4 second. The starting value of 16 is loaded from ROM in the SCNKEY routine, and thus cannot be changed, so the delay before repeating begins is not programmable.

2597 $0A25

Delay between case-switching repeats

This location is used to provide a delay between character case switches when the SHIFT-Commodore key combination is held down. This location isn’t a countdown. Rather, it is initialized to 128/$80; then the value is shifted one bit to the right on each pass through the SCNKEY routine until it becomes zero. This provides a delay of about 1/8 second.

2598 $0A26 BLNON

Bit 6 of this location controls whether the cursor on the 40- column (VIC) screen will blink. When the bit is %0, the cursor blinks at a rate determined by location $0A28. When the bit is %1, the cursor will be a solid, unblinking block. This location is initialized to 0/$00 during the CINT screen editor initialization routine $C07B, so the default cursor will be blinking. The bit can be set to %1 using the ESC E key sequence, and cleared to %0 using ESC F. Bit 7 of this location indicates the blink phase of the cursor on the 40-column (VIC) screen. When the bit is %0, the character at the cursor position is in its original state. When the bit is %1, the character is reversed to provide the cursor blink effect.

2599 $0A27 BLNSW

Cursor enable flag

This location controls whether a cursor will be present on the 40-column (VIC) screen. The cursor will be enabled when the value here is zero and disabled when this location contains any nonzero value. This location can be used to enable the cursor when it is normally turned off. For example, the following statement provides a cursor at the prompt (GET and GETKEY don’t normally provide a cursor):

300 POKE 2599,0: PRINT"PRESS A KEY: ";: GETKEY K$

2600 $0A28 BLNCT

This location determines the delay between cursor blinks for the 40-column (VIC) screen. Bit 6 of location $0A26 must be %0 to enable cursor blinking. The value here is decremented on each pass through the screen editor IRQ routine. Whenever the value reaches zero, the blink phase of the cursor changes and bit 7 of the screen code at the cursor position is toggled. This reverses the character at that position. The value here is reinitialized to 20/$14 whenever it counts down to zero. It takes two countdowns to complete a cursor blink (one while the character is in its normal state and one while it is reversed), so 40 passes of the screen editor IRQ routine are required for each cursor blink. As a result, the cursor blink rate for the VIC screen is about every 2/3 second. The initialization value is read from ROM, so the 40-column blink rate is not programmable.

22601 $0A29 GDBLN

Character under cursor

This location is used to hold the original (unblinked) screen code for the character at the current 40-column screen cursor position. If the cursor is moved from the current position without printing a new character, this value will be restored to the position when the cursor is moved.

22602 $0A2A GDCOL

Color under cursor

This location is used to hold the original color of the character at the current 40-column screen cursor position. If the cursor is moved from the current position without printing a new character, this value will be restored to corresponding color memory location for the position when the cursor is moved.

22603 $0A2B CURMOD

VDC cursor mode

This location is a shadow for VDC internal register 10/$0A. The value here is copied into the register every time the screen editor routines are used to print a character to the 80-column screen.

22604 $0A2C VM1

VIC text screen and character base

This location is a shadow for the VIC chip screen and character base address register ($D018) for the text (GRAPHIC 0) screen, or for the text portion of a split display. The value here is copied into the VIC register during the text screen-setup portion of the screen editor IRQ routine $C194. During the screen editor initialization $C07B, this location is set to 20/$14. That value places screen memory at 1024/$0400 and character memory at 4096/$1000. If the SHIFT-Commodore combination is detected during the SCNKEY routine $C55D, bit 1 of this location is toggled. This switches the character set base address between 4096/$1000 and 6144/$1800.

2605 $0A2D VM2

VIC bitmap and video matrix base

This location is a shadow for the VIC chip bitmap and videomatrix base address register ($D018) for the bitmapped (GRAPHIC 1 or GRAPHIC 3) screen, or for the bitmapped portion of a split display. The value here is copied into the VIC register during the bitmapped screen-setup portion of the screen editor IRQ routine $C194. During the screen editor initialization routine $C07B, this location is set to 120/$78. This value places the default video-matrix area at 7168/$1C00 and the bitmap at 8192/$2000.

2606 $0A2E VMS

Starting page for VDC screen memory

The value in this location is used during the screen editor routines to determine the starting page within VDC RAM for 80-column screen memory. During the screen editor initialization routine $C07B, this location is set to 0/$00, which places screen memory at address 0/$0000 in VDC RAM. The value here determines where the screen editor thinks VDC screen memory begins, but not the actual starting address of the screen. This location is not a shadow for a VDC register. The actual screen starting address is determined by the value in VDC internal registers $0C-$0D. If you change the register value, you should also change the value in this location, and vice versa.

2607 $0A2F VM4

Starting page for VDC attribute memory

The value in this location is used during the screen editor routines to determine the starting page within VDC RAM for 80-column attribute memory. During the screen editor initialization routine $C07B, this location is set to 8/$08, which places attribute memory at address 2048/$0800 in VDC RAM. The value here determines where the screen editor thinks VDC attribute memory begins, but not the actual starting address of attributes. (This location is not a shadow for a VDC register.) The actual attribute starting address is determined by the value in VDC internal registers $14-$15. If you change the register value, you should also change the value in this location, and vice versa.

2608 $0A30 LINTMP

Ending row for screen input

This location is used by the routines which accept lines of input from the screen or keyboard to hold the number of the screen row on which the displayed line of characters ends. This value is tested to determine when the end of the input has been reached. For input from the screen, the BASIN routine $C29B fails to set this location, so the row number for the end of the input line must be set explicitly by storing the proper value (0-24) in this location.

2609-2610 $0A31-$0A32 SAV80

Temporary storage for 80-column memory manipulation

These locations are used to store the current row and column number values during the routines that clear or scroll lines on the 80-column screen. Location 2609/$0A31 holds the row number and 2610/$0A32 holds the column number.

2611 $0A33 CURCOL

Attribute of current cursor position

This location is used to hold the original attribute of the character at the current 80-column screen cursor position. If the cursor is moved from the current position without printing a new character, this value will be restored to corresponding attribute memory location for the position when the cursor is moved.

2612 $0A34 SPLIT

Scan line for screen split

This location holds the scan line for the raster interrupt which will set up the lower (text) portion of a split bitmapped/text screen. When a split screen is selected (when bit 6 of location $D8 is set to %1), the value here will be copied into the VIC raster compare register ($D012) during the bitmapped screen-setup portion of the screen IRQ routine $C194. This will cause a raster interrupt at the specified scan line, which will execute the text screen-setup portion of the interrupt routine to establish the text portion of the split screen. To find the scan-line value corresponding to a character row number, use the following formula:

scan line = (row number * 8) + 48

The default value for this location, set during the screen editor initialization routine $C07B, is $D0, which places the default split at screen row 20. The value here can be changed in BASIC by specifying a split parameter with the GRAPHIC statement.

2613 $0A35 FNADRX

Temporary storage for X register

This location is used to preserve the contents of the X register during the Kernal routine that reads a character from a filename $F7AE.

2614 $0A36 PALCNT

Jiffy clock compensation flag

In systems using the PAL video format, this location is used as a counter during the Kernal UDTIM routine $F5F8. It is incremented each time UDTIM is called to update the jiffy clock locations (160-162/$A0-$A2). When the count has reached 5, the UDTIM routine is repeated and the counter is reset to zero. This triggers an extra update of the jiffy clock every fifth IRQ in PAL systems, so that ten extra jiffy clock “ticks” occur for each 50 IRQs. This means that the jiffy clock still increments 60 times per second on PAL-video 128s where the IRQ rate is only 50 per second. For systems using the NTSC format, this portion of the UDTIM routine is skipped, so the location will always hold its initial value of zero.

2615 $0A37 SPEED

Temporary storage for clock rate register

This location is used to hold the value in the VIC system clock rate register ($D030) during tape and serial bus operations. The current register value is stored here at the beginning of the operation and the register is reset for slow (1-MHz) mode for the duration of the operation; then the value here is restored to the register once the operation is completed.

2616 $0A38 SPRITES

Temporary storage for sprite enable register

This location is used to hold the value in the VIC sprite enable register ($D015) during tape and serial bus operations. The current register value is stored here at the beginning of the operation and the register is reset to 0/$00 to disable all sprites for the duration of the operation. The VIC chip requires extra timing cycles while sprites are active, so they are disabled to avoid disrupting the precise timing required for tape and serial operations. Once the operations are complete, the value here is restored to the VIC register.

2617 $0A39 BLANKING

Temporary storage for VIC control register

This location is used to hold the value in the VIC control register at $D011 during tape operations. The register value is stored here at the beginning of the tape operation, before bit 4 of the register is set to %0 to blank the screen during the operation. Upon completion of the tape operation, the value here is restored to the register.

2618 $0A3A HOLD_OFF

Custom mode flag

Normally, the system clock is set for the slow (1-MHz) rate and sprites are disabled during tape and disk operations to insure proper timing. However, this location can be used to allow the VIC clock and sprite registers to retain their current settings during such operations. When bit 7 of this location is set to %1, the registers are left unchanged. This location is initialized to 0/$00 by the IOINIT routine $E109, part of the reset sequence. That setting is not changed by any ROM routine, so this feature is not used by the system.

2619 $0A3B LDTB1_SA

Starting page for 40-column screen memory

The value in this location is used during the screen editor routines to determine the starting page for 40-column (VIC) screen memory. During the screen editor initialization routine $C07B, this location is set to the value in location $C04C, which is currently 4/$04. This specifies screen memory at address 1024/$0400.

The value here determines where the screen editor thinks VIC screen memory begins, but not the actual starting address of the screen. (This location is not a shadow for a VIC register.) The actual screen starting address is determined by the value in bits 4-7 of the VIC register at $D018. If you change the register value, you should also change the value in this location, and vice versa.

2620-2621 $0A3C-$0A3D CLR_EA

Working pointer into SO-column memory

These locations are used to hold an address in VDC memory during the routine that clears a line of text on the 80-column screen $C4C0 and the one that copies a line up or down for scrolling $C53C.

2622-2623 $0A3E-$0A3F Unused

These locations are unused by any system ROM routine, and are thus available for your own programming.

2624-2650 $0A40-$0A5A

Screen editor variable storage for the inactive screen

The screen editor variables for whichever screen (40- or 80- column) is currently inactive are stored here. When the screens are switched, the screen editor SWAPPER routine $CD2E exchanges the contents of this area with the values for the active screen at $E0-$FA. Thus, the active and inactive screens are totally independent, and all window size settings for the inactive screen will be preserved until the screen becomes active again.

Location $0A5A should not be included in this range. Only locations $E0-$F9 actually hold screen editor variables. However, the SWAPPER routine incorrectly copies 27 values instead of the proper 26, so the contents of location $0A5A and location $FA will be exchanged whenever the active screen is switched. Both locations are normally unused.

2651-2655 $0A5B-$0A5F Unused

None of the locations in this range is used by any system routine, so all are available for your own programming.

2656-2665 $0A60-$0A69

Storage for inactive tab-stop bitmap

The tab-stop bitmap for whichever screen (40- or 80-column) is currently inactive is stored here. When the screens are switched, the screen editor SWAPPER routine $CD2E exchanges the contents of this area with the tab-stop bitmap for the active screen at 852-861/$0354-$035D

2666-2669 $0A6A-$0A6D

The line-link bitmap for whichever screen (40- or 80-column) is currently inactive is stored here. When the screens are switched, the screen editor SWAPPER routine $CD2E exchanges the contents of this area with the line-link bitmap for the active screen at 862-865/$035E-$0361.

2670-2687 $0A6E-$0A7F Unused

None of the locations in this 18-byte area is used by any system ROM routine, so they are available for your own programming.

Monitor Working Storage Area $0A80-$0ABF

2688-2703 $0A80-$0A8F FNBUFF

Filename buffer for load, save, or verify

The load/save/verify setup routine stores the filename associated with a monitor L, 5, or V command here (up to 16 characters).

2688-2719 $0A80-$0A9F HBUFF

Search pattern buffer

The monitor H (hunt for byte pattern) routine $B2CE fills this buffer with the byte pattern being searched for (up to 32 characters). Characters in the specified memory range are then compared against the buffer contents to search for a matching pattern in memory. If the address range for the search includes this buffer, an artificial match will be found-the buffer contents will always match themselves

2720-2727 $0AA0-$0AA7 XFORM

Working storage for base conversion

The hex-to-decimal conversion routine $BA07 uses these locations for working storage during the conversion, leaving the results in $0AA0-$0AA3 in BCD (binary coded decimal) format. The base conversion routine $BA47 puts the value to be converted into $0AA0-$0AA3 for manipulation. The routine to print octal, binary, or decimal values uses $0AA0-$0AA3 to hold the value to be displayed.

2730 $0AAA FORMAT

Instruction format flag

The routine to calculate the mnemonic and addressing mode for an opcode $B659 uses this location to hold a flag value indicating the addressing mode in use, which determines the format in which the instruction must be displayed or entered.

2731 $0AAB LENGTH

Instruction length

The routine to calculate the mnemonic and addressing mode for an opcode $B659 uses this location to hold the number of bytes which should follow the opcode in the instruction (0-2).

2732-2734 $0AAC-$0AAE MSAL

Three-character mnemonic pattern

The assemble routine $B406 stores the first three-character group from the input line in these locations for evaluation as an ML mnemonic.

2735 $0AAF SXREG

Temporary storage for X register

The subroutine to determine the proper opcode for a mnemonic $B57C, the routine to print hexadecimal byte values, and the routine to test the next buffer character $B8E7 all stash the X register contents here upon entry, and restore the value to the X register upon exit. The routine to decrement the pointer address or line count stored in 96-98/$60-$62 uses this location to hold the amount by which the stored value is to be decremented.

2736 $0AB0 Unused

This location is not used by any 128 ROM routine, and is thus available for your own programming.

2737 $0AB1 OPCODE

Calculated opcode

The assemble routine $B406 uses this location to hold the opcode calculated for the instruction being assembled.

2738 $0AB2 XSAVE

Temporary storage for X register

The monitor indirect fetch $B11A, indirect store $B12A, and indirect compare $B13D routines stash the value in the X register here upon entry, then restore the value to the X register upon exit.

2739 $0AB3 DIRECTION

Transfer direction flag

The monitor compare/transfer routine $B231 uses this location in execution of the T (transfer) command to indicate the direction in which bytes are to be transferred. For downward moves (source address greater than destination address), the flag will be set to zero; for upward moves (destination address greater than source address), the flag will be set to 128/$80.

2740 $0AB4 COUNT

Digit counter

The routine to convert input parameters into numeric values $B7CE uses this location to hold a count of the hexadecimal digits in the converted value. The routine to print values in octal, inary, or decimal $BA47 uses this location as a counter of digits printed in the value being displayed.

2741 $0AB5 NUMBER

Temporary storage for parameter conversion

The routine to convert input parameters into numeric values $B7CE uses this location to hold the numeric value of the input digit currently being evaluated.

2742 $0AB6 SHIFT

Number of bits per digit for base

The routine to convert input parameters into numeric values $B7CE and the routine to print values in octal, binary, or decimal $BA47 use this location to hold the number of bits to be interpreted per digit for the value being converted or displayed.

2743-2745 $0AB7-$0AB9 TEMPS

Monitor temporary storage

The routine to convert input parameters into numeric values $B7CE uses these locations as working storage when evaluating decimal digits. Monitor routines which accept two or more address parameters store the second (ending) address here. For upward transfers, the compare/transfer routine $B231 moves the value here to the working pointer at 102-104/$66-$68.

2746-2751 $0ABA-$0ABF Unused

These locations are not used by any 128 ROM routines, and are thus available for your own programming.

Kernal Working Storage ($0AC0-$0AFF)

2752 $0AC0 CURBNK

Counter for function ROM testing

Both the Kernal routine which checks for the presence of ROM in the internal and external (cartridge) ROM address slots $E26B and the Kernal PHOENIX routine $F867 which initializes function ROMs use this location as a countdown for the number of slots remaining to be tested. The location is set to 3, then decremented each time a slot is checked or initialized. The routines end when the value here rolls over from 0/$00 to 255/$FF after the fourth slot is tested or initialized. Thus, this location will normally contain 255/$FF upon completion of either routine.

2753-2756 $0AC1-$0AC4 PAT

Table of identifiers for function ROMs

The Kernal routine which tests for the presence of function ROMs $E26B initializes these locations to 0/$00 before checking any of the four possible ROM address slots. A ROM is considered present in the slot if the character codes for the letters CBM are found at an offset of seven bytes from the starting address of the slot. If this test pattern is found, the function ROM ID byte is copied from an offset of six bytes beyond the starting address of the slot into the corresponding location in this table:

Location ROM slot address
2753/$0AC1 32768/$8000 internal
2754/$0AC2 49152/$C000 internal
2755/$0AC3 32768/$8000 external
2756/$0AC4 49152/$C000 external

If the identifier byte is 1/$01, the cartridge is autostarting and the test routine immediately calls the cold-start vector for that ROM. Otherwise, the Kernal PHOENIX routine $F867, part of the BASIC cold-start sequence, will call the cold-start vector for any ROM slots with nonzero entries in this table.

2757 $0AC5 DILFLAG

This location is mentioned in Commodore literature as “reserved for foreign screen editors,” but its exact use is unclear. It is unused by any routine in the U.S. version of the system ROMs.

2758-2815 $0AC6-$0AFF Unused

This 58-byte area is described in Commodore literature as “reserved for system use.” However, no routines in the current version of the system ROMs make use of any of these locations. Still, unless you are desperate for free locations outside the BASIC area, it’s probably best to avoid using these locations to insure compatibility with future versions of the ROM.