In this page...


Index

$0300-$03FF - Basic/Kernal indirect vectors, Screen editor tables, Kernal file tables, Basic working storage

BASIC Indirect Vectors

The next nine vectors, $0300-$0311, are used in BASIC statement processing routines. The default values for these vectors are copied from a table at $4267-$4278 in BASIC ROM by the BASIC vector initialization routine $4251, part of the cold-start sequence. Thus, unlike the Kernal indirect vectors, the BASIC vectors are not affected by the RUN/STOP-RESTORE sequence. Any changes you make to the vectors will remain in effect until the next cold start of BASIC, as during a reset.

768-769 $0300-$0301 IERROR

Indirect vector for BASIC error handling routine

In BASIC ROM, the jump through this vector is taken at the beginning of the error handling routine (ERROR $4D3C). At the point the jump is taken, the X register will contain the current BASIC error number (0-41, or 128 to print READY) and the accumulator will hold the last character read from program text. The default target address of the vector is $4D3F, which simply reenters the error handling routine at the point immediately following the jump. You can redirect this vector to change the way BASIC handles errors.

In addition to modifying error handling, you can also use this vector to provide an alternate method of adding commands to BASIC.

770-771 $0302-$0303 IMAIN

Indirect vector in main BASIC loop

The jump through this indirect vector is taken in the main BASIC direct mode routine $4DB7 at the point immediately after the READY prompt has been printed and the mode flag (127/$7F) has been set for immediate mode. The vector normally holds $4DC6, the address of the instruction immediately following the indirect jump. You can redirect this vector to a routine of your own if you wish to change the behavior of BASIC’s immediate mode.

772-773 $0304-$0305 ICRNCH

Indirect vector in BASIC tokenization routine

The jump through this indirect vector is taken at the beginning of the CRUNCH routine $430A, which is responsible for converting lines of input text into tokenized program lines.

The vector normally holds $430D, the address of the instruction immediately following the indirect jump. You can redirect this vector to a routine of your own if you wish to change the way program lines are tokenized.

774-775 $0306-$0307 IQPLOP

Indirect vector in BASIC detokenization routine

The jump through this indirect vector is taken in the QPLOP routine $5123 at the point where the accumulator contains the next character to be listed from the program line. The vector normally holds $5151, the address of the instruction immediately following the indirect jump. You can redirect this vector to a routine of your own if you wish to change the way program lines are listed.

776-777 $0308-$0309 IGONE

Indirect vector in BASIC execution routine

The jump through this indirect vector is taken at the beginning of the GONE routine $4F92, the routine to execute a program line. The vector normally holds $4AA2, the address of the instruction immediately following the indirect jump. You can redirect this vector to a routine of your own if you wish to change the way program lines are executed.

778-779 $030A-$030B IEVAL

Indirect vector in BASIC evaluation routine

The jump through this indirect vector is taken at the beginning of the EVAL routine, which determines the value of the next variable, string, or number in the program. The vector normally holds $78DA, the address of the instruction immediately following the indirect jump. You can redirect this vector to a routine of your own if you wish to change the way values are evaluated.

780-781 $030C-$030D ICRNCH2

Indirect vector for tokenizing additional keywords

The jump through this vector is taken in the tokenization routine at the point where the first character of the keyword has been read into the accumulator and the carry bit has been set. H carry is still set upon return from this jump, the tokenization process will proceed normally. The vector normally holds $4321, the address of the instruction immediately following the jump. Thus, the jump normally has no effect. If you want to add extended tokens to BASIC, you should redirect this vector to your routine to tokenize the new keywords. The routine should compare the text pointed to by $3D-$3E with the target keyword. If a match is found, your routine should return with the second byte of the two-byte extended token in the accumulator. The X register should be set to indicate whether the keyword is a statement or a function. X should be set to 0/$00 for a function, in which case the first byte will be 206/$CE, or to 255/$FF for a statement, in which case the first byte will be 254/$FE. The Y register should contain the length of the filename. Finally, you should make sure that the carry bit is clear upon exit so that your new token will be properly processed.

782-783 $030E-$030F IQPLOP2

Indirect vector for detokenizing additional keywords

The jump through this indirect vector is taken in the routine that lists BASIC program lines at the point where two-byte extended statement or function tokens have been found which are greater than the largest standard tokens. When the jump is taken, the accumulator will hold the second byte of the offending token and the X register will hold 0/$00 if the first byte was 206/$CE, indicating an extended function token, or 255/$FF if the first byte was 254/$FE, indicating an extended statement token. The status register carry bit will also be set. If that bit is still set upon return from this indirect jump, the character will simply be printed. However, if carry is cleared, the extended keyword will be listed. The vector normally holds 20941/$51CD, the address of the instruction immediately following the indirect jump, so carry will normally remain set. If you add new extended keywords to BASIC, you should change this vector to point to the routine to support listing the keywords.

784-785 $0310-$0311 IGONE2

Indirect vector in extended statement execution subroutine

The jump through this indirect vector is taken in the statement execution routine at the point where a two-byte extended statement token has been found with a value greater than one of the standard extended statement tokens (second byte greater than 38/$26). When the jump is taken, the accumulator will hold the second byte of the extended token and the carry bit will be set. If the carry bit is not clear upon return, a SYNTAX error will be generated. The vector normally holds 19369/$4BA9, the address of the instruction immediately following the indirect jump. Thus, the out-of-range token will normally cause an error. If you add new extended-token statements to BASIC, you should change this vector to point to the address of the routine which executes the new statement.

786-787 $0312-$0313 Unused

These two locations are not used for any system vector, and are thus available for your programming. For example, you could use these locations to set up an indirect vector in one of your own programs, or to store the original value when changing one of the other vectors.

Kernal Indirect Vectors

The next 16 vectors, $0314-$0333, are initialized from a table at 57459-57490/$E073-$E092 in Kernal ROM by the RESTOR routine $E056. The RESTOR routine is called during both the reset and RUN/STOP-RESTORE sequences, so either of those will reinitialize the vectors. The values in this vector table can be read or modified using the Kernal VECTOR routine $E05B.

788-789 $0314-$0315 IIRQ

Indirect vector to IRQ interrupt handling routine

When an IRQ interrupt occurs or a BRK instruction is executed, a jump is automatically taken through the processor IRQ vector at $FFFE to the handling routine at $FF17. That routine stores the accumulator, X and Y register, and bank configuration values on the stack, then checks whether the routine was called as the result of an IRQ or a BRK. If an IRQ was responsible, a jump is taken through this indirect vector. The vector normally holds $FA65, the address of the standard system IRQ routine. You can redirect this vector to a routine of your own to add custom steps to the IRQ process. However, your target routine must be visible in bank 15, since that is how memory will be configured when the jump through this vector is taken. If your routine does not jump to the standard IRQ handler, it must exit by jumping to the common IRQ exit routine at $FF33.

790-791 $0316-$0317 IBRK

Indirect vector to BRK instruction handling

When an IRQ interrupt occurs or a BRK instruction is executed, a jump is automatically taken through the processor IRQ vector at $FFFE to the handling routine at $FF17. That routine stores the accumulator, X and Y register, and bank configuration values on the stack, then checks whether the routine was called as the result of an IRQ or a BRK. If the execution of a BRK was responsible, a jump is taken through this indirect vector. The vector normally holds $B003, the address of the BRK entry into the machine language monitor. You can redirect this vector to a routine of your own if you want some other handling of BRK instructions.

792-793 $0318-$0319 INMI

Indirect vector to NMI interrupt handling routine

When an NMI interrupt occurs, a jump is automatically taken through the processor NMI vector at $FFFA to the NMI handling routine at $FF05. That routine stores the accumulator, X and Y register, and bank configuration values on the stack, then configures the system for bank 15 and takes a jump through this indirect vector. The vector normally holds $FA40, the address of the standard system NMI service routine. You can redirect this vector to a routine of your own to add custom steps to the NMI process. However, your routine must be in an area of memory visible in bank 15, since that is how memory will be configured when the jump is taken. If your routine does not jump to the standard NMI handler, it must exit by jumping to the common IRQ exit routine at $FF33.

794-795 $031A-$031B IOPEN

Indirect vector to Kernal OPEN routine

This vector is the normal link between the Kernal jump table entry at $FFC0 and the OPEN routine at $EFBD. You can redirect this vector to a routine of your own if you wish to modify the behavior of OPEN.

796-797 $031C-$031D ICLOSE

Indirect vector to Kernal CLOSE routine

This vector is the normal link between the Kernal jump table entry at $FFC3 and the CLOSE routine at $F188. You can redirect this vector to a routine of your own if you wish to modify the behavior of CLOSE. When the jump is taken, the accumulator should hold the number of the logical file to be closed.

798-799 $031E-$031F ICHKIN

Indirect vector to Kernal CHKIN routine

This vector is the normal link between the Kernal jump table entry at $FFC6 and the CHKIN routine at $F106. You can redirect this vector to a routine of your own if you wish to modify the behavior of CHKIN. When the jump is taken, the X register should hold the number of the logical file selected as the input source.

800-801 $0320-$0321 ICKOUT

Indirect vector to Kernal CKOUT routine

This vector is the normal link between the Kernal jump table entry at $FFC9 and the CKOUT routine at $F14C. You can redirect this vector to a routine of your own if you wish to modify the behavior of CKOUT. When the jump is taken, the X register should hold the number of the logical file selected as the output source.

802-803 $0322-$0323 ICLRCH

Indirect vector to Kernal CLRCH routine

This vector is the normal link between the Kernal jump table entry at $FFCC and the CLRCH routine at $F226. You can redirect this vector to a routine of your own if you wish to modify the behavior of CLRCH.

804-805 $0324-$0325 IBASIN

Indirect vector to Kernal BASIN routine

This vector is the normal link between the Kernal jump table entry at $FFCE and the BASIN routine at $EF06. You can redirect this vector to a routine of your own if you wish to modify the behavior of BASIN. The routines which call BASIN expect it to return a character in the accumulator.

806-807 $0326-$0327 IBSOUT

Indirect vector to Kernal BSOUT routine

This vector is the normal link between the Kernal jump table entry at $FFD2 and the BSOUT routine at $EF79. You can redirect this vector to a routine of your own if you wish to modify the behavior of BSOUT. When this routine is called, the value to be output should be in the accumulator.

808-809 $0328-$0329 ISTOP

Indirect vector to Kernal STOP routine

This vector is the normal link between the Kernal jump table entry at $FFE1 and the STOP routine at $F66E. You can redirect this vector to a routine of your own if you wish to modify the behavior of STOP. The routines which call STOP expect it to return with the status register Z bit set if the RUN/STOP key was pressed, or clear otherwise.

810-811 $032A-$032B IGETIN

Indirect vector to Kernal GETIN routine

This vector is the normal link between the Kernal jump table entry at $FFE4 and the GETIN routine at $EEEB. You can redirect this vector to a routine of your own if you wish to modify the behavior of GETIN. The routines which call GETIN expect it to return a character code in the accumulator.

812-813 $032C-$032D ICLALL

Indirect vector to Kernal CLALL routine

This vector is the normal link between the Kernal jump table entry at $FFE7 and the CLALL routine $F222. You can redirect this vector to a routine of your own if you wish to modify the behavior of CLALL.

814-815 $032E-$032F IEXMON

Indirect vector in monitor command execution routine

This indirect vector appears in the machine language monitor’s main loop $B08B at the point where the first nonspace character has been read from the input buffer and is ready to be interpreted as a command. The vector normally holds the address 45062/$B006, which in turn is a vector back to $B0B2, the address immediately following the indirect jump.

However, you can redirect this vector to a routine of your own if you wish to add commands to the machine language monitor. The following example adds two new monitor commands-P, which behaves like D (disassemble) but routes output to the printer, and Q, which closes the file to the printer:

0D00 LDA #$0B   // Redirect vector to new handling routine
0D02 STA $032E
0D05 LDA #$0D
0D07 STA $032F
0D0A RTS
0D0B CMP #$51   // Is character code for Q?
0D0D BNE $0D1A
0D0F LDA #$04   // If so, close logical file 4
0D11 JSR $FFC3
0D14 JSR $FFCC  // Restore normal I/O channels (CLRCH)
0D17 JMP $B08B  // Return to monitor main loop
0D1A CMP #$50   // Is character code for P?
0D1C BNE $0D35
0D1E LDA #$04   // If so, OPEN 4,4,0
0D20 TAX
0D21 LDY #00
0D23 JSR $FFBA
0D26 LDA #$00
0D28 JSR $FFBD
0D2B JSR $FFC0
0D2E LDA #$04   // Set logical file 4 for output
0D30 JSR $FFC9  // Change monitor command to D (disassemble)
0D33 LDA #$44   // Return to monitor command processing loop
0D35 JMP $B006

816-817 $0330-$0331 ILOAD

Indirect vector in Kernal WAD routine

This indirect vector appears in the Kernal LOAD routine $F265 at the point after the starting address (in X and Y when the routine is entered) has been stored in $C3-$C4. The accumulator should still contain a value indicating whether the operation is a load or a verify ($00 for load, nonzero for verify). The vector normally holds $F26C, the address immediately following the indirect jump. You can redirect this vector to a routine of your own if you wish to modify the behavior of LOAD.

818-819 $0332-$0333 ISAVE

Indirect vector in Kernal SAVE routine

This indirect vector appears in the Kernal SAVE routine $F53E at the point after the ending address has been stored in $AE-$AF and the starting address has been stored in $C1-$C2. The vector normally holds $F54E, the address immediately following the indirect jump. You can redirect this vector to a routine of your own if you wish to modify the behavior of SAVE.

Screen Editor Indirect Vectors

The next five vectors, $0334-$033D, are copied from a table at $C065-$C06E in screen editor ROM by the CINT routine $C07B during the reset sequence. CINT is also part of RUN/STOP-RESTORE, but a flag in the routine is normally used to skip the vector initialization step in this case. As a result, vector addresses aren’t usually changed by RUN/STOP-RESTORE.

820-821 $0334-$0335 CTLVEC

Indirect vector in screen BSOUT handling

The jump through this indirect vector is taken as the first step in the screen BSOUT subroutine $C7B6 which processes character code values less than 32/$20. At the time the jump is taken, the accumulator holds the current character code. The vector normally holds $C7B9, the address immediately following the indirect jump. You can change this vector to point to a routine of your own if you wish to change the printing behavior of character codes in the range $00-$1F. All codes in this range perform cursor movements, color changes, or other control functions rather than printing characters. If you wish to add new control functions, codes 0, 1, 3, 4, 6, 16, 21-23, 25, and 26 are currently unused.

822-823 $0336-$0337 SHFVEC

Indirect vector in screen BSOUT handling

The jump through this indirect vector is taken as the first step in the screen BSOUT subroutine $C802 which processes character code values greater than $7F. At the time the jump is taken, the accumulator holds the current character code. The vector normally holds $C805, the address immediately following the indirect jump. You can change this vector to point to a routine of your own if you wish to change the printing behavior of character codes in the range $80-$FF. Codes $81-$9F perform cursor movements, color changes, or other control functions rather than printing characters. If you wish to add new control functions, codes 128, 131, and 132 are currently unused.

824-825 $0338-$0339 ESCVEC

Indirect vector in ESC sequence handling routine

The jump through this indirect vector is taken as the first step in the screen BSOUT subroutine $C9BE which processes ESC (escape) key sequences. At the time the jump is taken, a test will have determined that the previous character was ESC (code 27/$1B). The accumulator holds the current character code, the one which followed ESC. The vector normally holds $C9C1, the address immediately following the indirect jump. You can redirect this vector to add your own ESC sequences. The following example adds ESC t, which moves the position of the bitmap/text division of a screen line up one row each time the sequence is used:

1400 LDA #$0B     // Redirect vedor to handling routine
1402 STA $0338
1405 LDA #$14
1407 STA $0339
140A RTS
140B CMP #$5E     // Is character t1
1400 BEQ $1412
140F JMP $C9C1    // If not, jump to normal processing
                  // routine
1412 LDA $08      // Is a split screen in use?
1414 AND #$40
1416 BEQ $140F    // If not, use normal processing routine
1418 LDA $0A34    // Is the split already at the top row of the
                  // screen?
141B CMP #$3A
1410 BCC $140F    // If so, ignore this sequence
141F SBC #$08     // Move the split position up one row (8
1421 STA $0A34    // scan lines)
1424 RTS

826-827 $033A-$033B KEYVEC

Indirect vector in keyboard scanning routine

The jump through this indirect vector is taken during the SCNKEY routine $C550 at the point following completion of the keyscan and the evaluation of the shift key status. At the point the jump is taken, the accumulator (along with location 212/$04) will contain the current keyboard matrix code, and location 211/$03 will reflect the current shift key status. The vector normally holds the address $C5E1, the point in the keys can routine immediately following the indirect jump, but you can redirect the vector if you wish to change the behavior of the keyscan routine.

828-829 $033C-$033D KEYCHK

Indirect vector in keyboard scanning routine

The jump through this indirect vector is taken during the SCNKEY routine $C550 after the character code for the keypress has been read from the decoding table and immediately before the test for a programmable key. At the point the jump is taken, the accumulator will contain the character code corresponding to the current keypress and the X register will contain the current shift key status (from 211/$03). The vector normally holds $C6A0, the point in the keyscan routine immediately following the indirect jump, but you can redirect this pointer to modify the behavior of the keyscan.

One use of this vector is to disable programmable keys. While the definition strings are handy, sometimes-particularly when you are adapting programs from the Commodore 64-you might like for them to instead generate their standard character codes. One way to achieve this is to change this pointer so that the test for programmable keys is bypassed:

POKE 828,183

This changes the low byte of the pointer so that the target address becomes $C6B7, the point in the routine immediately beyond the test for programmable keys.

Screen Editor Tables

Locations 830-865/$033E-$0361 are the domain of the screen editor.

830-841 $033E-$0349 DECODE

Keyboard table pointers

These six 2-byte pointers hold the starting addresses of the 89- byte tables used to translate the matrix code for the current keypress into a character code:

Pointer Shift pattern Default table address
$033E-$033F Unshifted $FA80
$0340-$0341 SHIFT $FAD9
$0342-$0343 Commodore $FB32
$0344-$0345 CONTROL $FB8B
$0346-$0347 ALT $FA80 (same as unshifted)
$0348-$0349 CAPS LOCK $FBE4

The status of the five shift keys, recorded in $D3, is used to select one of the table addresses from this area. If no shift key is pressed, the unshifted table is used. If one shift key is pressed, the appropriate decoding table is selected. If more than one shift key is pressed simultaneously, the table is selected as follows: CONTROL has the highest priority; when it is pressed in combination with any other shift keys, the CONTROL table is used. The SHIFT and Commodore keys are next in priority; however, when they are pressed Simultaneously, no decoding table is selected (although the combination may cause character set switching). ALT and CAPS LOCK have the lowest priority. They are effective in selecting the decoding table only if no other shift keys are being pressed. If pressed simultaneously, both are ignored and the unshifted table is used. Once a table is selected, its address is loaded into $CC-$CD, and the current matrix code in 212/$D4 is used as an offset to the specific character code to be retrieved from the table.

The default decoding table addresses are copied here from a table at $C06F in screen editor ROM by the CINT screen editor initialization routine $C07B during the reset sequence. CINT is also part of the RUN/STOP-RESTORE sequence, but it includes a flag that normally prevents the vectors from being reinitialized in that case. To redefine the 128 keyboard, you need only set up a new decoding table in RAM and change one of the address values here to point to the new table. For example, if you’ve used the CAPS LOCK key, you’ve probably discovered that it doesn’t appear to affect the Q key. Actually, the problem is that whoever prepared the CAPS LOCK decoding table used the wrong value for the Q key entry. The following shows how to fix the CAPS-Q bug by setting up a new copy of the decoding table for that shift pattern:

100 REM ** COPY CAPS LOCK TABLE TO RAM
110 FOR 1=0 TO 88:POKE 6912+I,PEEK(64484+I):NEXT
120 REM ** CHANGE INCORRECT CHARACTER CODE FOR Q
130 POKE 6912+62,209
140 REM ** REDIRECT POINTER TO NEW TABLE
150 POKE 840,0:POKE 841,27

A custom table should consist of 89 values in matrix code order. The final value in the table should be $FF, and you should be sure to include the shift key codes in the proper locations. The following program sets up a Dvorak-style keyboard:

100 FOR 1=0 TO 88:READ K:POKE 6912+1,K:NEXT
110 POKE 830,0:POKE 831,27:END
120 DATA 20, 13, 29, 136, 133, 134, 135, 17, 51, 44
130 DATA 65, 52, 59, 79, 46, 1, 53, 80, 69, 54
140 DATA 74, 85, 89, 81, 55, 70, 73, 56, 88, 68
150 DATA 71, 75, 57, 67, 72, 48, 77, 84, 82, 66
160 DATA 43, 76, 78, 45, 86, 83, 47, 87, 92, 42
170 DATA 59, 19, 1, 61, 94, 90, 49, 95, 4, 50
180 DATA 32, 2, 39, 3, 132, 56, 53, 9, 50, 52
190 DATA 55, 49, 27, 43, 45, 10, 13, 54, 57, 51
200 DATA 8, 48, 46, 145, 17, 157, 29, 255, 255

842-851 $034A-$0353 KEYBUF

Keyboard buffer

This ten-byte area is the keyboard buffer. When the SCNKEY routine $C55D detects a valid keypress, it generates a corresponding character code. The character code is then stored in this buffer to await processing. The Kernal GETIN and BASIN routines are normally used to retrieve characters from this buffer. Location 208/$D0 holds the number of characters currently waiting in the buffer. The maximum number of characters that can be held in the buffer is determined by the value in location $0A20. If the value there is greater than 10, the keyboard buffer will overwrite the following memory areas such as the tab stop bitmap. When the value in $D0 equals the value in $0A20, the buffer is full; any further keypresses will be ignored until one or more characters are removed from the buffer.

This key buffering system allows for a powerful programming technique known as the dynamic keyboard. By storing character code values in the buffer and storing the number of characters in $D0, a program can appear to type on the keyboard. For example, the following lines add a default answer to the INPUT prompt:

200 POKE 842,89: POKE 208,1: REM PLACE Y IN BUFFER
210 INPUT" ARE YOU SURE"iA$

When the INPUT statement begins to look for characters, it will find the Y already in the buffer.

An even more powerful use of the dynamic keyboard technique is to allow a program to execute a series of commands after it ends. When a program is finished executing, BASIC looks to the keyboard buffer for the characters of the next command. Thus, any characters placed in the buffer while a program is running will effectively be typed if the program ends. Since the buffer can hold only ten characters, the common practice is to print commands at carefully planned places on the screen, then fill the buffer with cursor movement and RETURN characters to execute the commands. The following program illustrates this technique. It creates DATA statements for one of the sprite patterns. You can adapt the program for your own needs by changing the values in line

  1. AD is the starting address of the data, NI is the number of DATA items to be generated, and LN is the line number of the first DATA statement to be generated. The program prints a DATA line and a GOTO statement on the screen, then places {HOME} {RETURN} {RETURN} in the buffer and ends. The buffered characters are executed, entering the DATA line and restarting the program.
10 AD=3584:NI=64:LN=100:I=0
20 IF I=>NI THEN END
30 PRINT" {CLR}" ;LN; "DATA"; :LN=LN+10 :J=0
40 PRINT PEEK(AD+I)::I=I+1:IF I=>NI THEN 60
50 J=J+1 :IF J<8 THEN PRINT"{LEFT}, "; :GOTO 40
60 PRINT:PRINT"GOTO 20"
70 POKE 842,19:POKE 843,13:POKE 844,13:POKE 208,3:END

852-861 $0354-$035D TABMAP

Tab stop bitmap

These ten bytes provide an 80-bit map of the display’s horizontal character positions. Each horizontal position in the currently active display has a corresponding bit in the map. For the VIC chip’s 40-column display, only the first five bytes (40 bits) are used. When a bit is set to %1, a tab stop is established at the corresponding screen column. Printing the TAB character, code $09, or pressing the TAB key will move the cursor rightward to the next tab stop (or the right window margin if no tab stops are set between the current cursor position and the right margin).

During the CINT screen editor initialization sequence, all locations in the map are set to 128/$80, which establishes a tab stop every eighth column. Printing character code 24/$18 (or pressing SHIFT-TAB) toggles the map bit corresponding to the current cursor column, setting a tab stop if the bit was previously %0 or clearing the tab stop if the bit was previously %1. The ESC Z sequence can be used to clear all tab stops (all locations in the map will be filled with 0/$00), and the ESC Y sequence can be used to restore default tab stops (all locations in the map will be filled with 128/$80).

When the active display is switched, screen editor SWAPPER routine $CD2E exchanges the contents of this area with the contents of locations $0A60-$0A69, the storage area for the inactive display tab stop bitmap. Thus, tab stop settings are preserved while the screen is inactive.

862-865 $035E-$0361 LNKMAP

These four bytes are used to provide a 25-bit map of the 25 rows of the active screen display (bits 0-6 of location 865/$361 are unused). Each row of the currently active display has a corresponding bit in the map. When a bit is set to %1, the corresponding row is linked to the row above as part of a logical line. Bits set to %0 indicate unlinked lines (or rows that are the first physical line of a logical line). These locations are cleared to 0/$00, unlinking all lines, whenever the output window is cleared or reset to full screen size, or whenever the screen editor WINDOW routine is used to change the size of the output window. A screen line is normally linked to the one above when the cursor moves onto the line by wrapping from the right margin of the line above. Line linking can be disabled by setting the flag bit in location $F8.

When the active display is switched, the screen editor SWAPPER routine $CD2E exchanges the contents of this area with the contents of locations $0A6A-$0A6D, the storage area for the inactive display line link bitmap. Thus, the line link status is preserved when the screen is inactive.

Kernal File Tables

The following three ten-byte tables hold information on any currently open logical files. The three tables are parallel; the entry for a particular file will appear at the same position in all three tables. Location 152/$98 serves as an index to the next available entry in the tables. The fact that there are only ten bytes per table means that no more than ten logical files may be opened simultaneously.

866-875 $0362-$036B LATBL

Logical file number table for currently open files

When a logical file is opened, the OPEN routine $EFBD examines the contents of this table. A FILE OPEN error occurs if an existing file already uses the specified logical file number, and a TOO MANY FILES error occurs if ten files are already open. Otherwise, the logical file number for the file is stored in the next available entry in this table. When the Kernal CHKIN $F106 or CKOUT $F14C routines are used to select a logical file for input or output, this table is searched for the specified logical file number. A FILE NOT OPEN error occurs if the file number is not found in the table. Otherwise, the corresponding device number and secondary address will be read from the respective tables. When a file is closed, the Kernal CLOSE routine $F188 removes the fIle’s entry from this table.

The Kernal includes a routine [LKUPLA, $F79D] to search for a particular file number in this table.

876-885 $036C-$0375 DNTBL

Device number table for currently open files

When a logical file is opened, the OPEN routine $EFBD stores the device number for the file in the next available entry in this table. When the Kernal CHKIN $F106 or CKOUT $F14C routines are used to select a logical file for input or output, the device number for the selected file will be read from this table. When a file is closed, the Kernal CLOSE routine $F188 removes the file’s entry from this table.

886-895 $0376-$037F SATBL

Secondary address table for currently open files

When a logical file is opened, the OPEN routine $EFBD will OR the specified secondary address for the file with the value 96/$60, then store the result in the next available entry in this table. When the Kernal CHKIN $F106 or CKOUT $F14C routines are used to select a logical file for input or output, the secondary address for the selected file will be read from this table. When a file is closed, the Kernal CLOSE routine $F188 removes the file’s entry from this table.

The Kernal includes a routine [LKUPSA, $F786] to search for a particular secondary address in this table.

BASIC Working Storage

The remainder of page 3, locations $0380-$03FF, is used to hold BASIC character retrieval subroutines and to store values for a variety of BASIC routines. The subroutines in locations $0380-$03D4 are copied here from locations $4279-$42CD in BASIC ROM during the BASIC cold-start sequence. The routines are not reinitialized by RUN/STOP-RESTORE.

896-926 $0380-$039E CHRGET

Main BASIC character retrieval routine

This is BASIC’s primary routine for reading program text for interpretation and execution. The routine is designed to retrieve the next nonspace character from a BASIC line (in bank 0), and to return information about the type of character retrieved. The routine begins by incrementing the current address in the text pointer at locations $3D-$3E. The system is set for the bank 0 configuration, the value at the location specified in the pointer is loaded into the accumulator, and the system is reset for the bank 14 configuration. The routine then performs a series of tests that will set the processor status register to reflect the type of character that was read. If a space character (code 32/$20) is read, the routine loops back to read another character (which is why spacing is not usually significant in BASIC program lines). If the character is one of the numbers 0-9, the carry bit will be clear (carry will be set if the character is not a digit). If the character was a colon (:), BASIC’s end-of-statement marker, or a zero byte, BASIC’s end-of-line marker, the status register Z bit will be set; otherwise, the Z bit will be clear.

This routine has an alternate entry point at 902/$386, called CHRGOT, which retrieves and tests the current character, the one at the address currently in $3D-$3E, without updating the pointer.

Since this routine is in RAM, it can be modified to change the way BASIC program text is read.

927-938 $039F-$03AA INDSUB-RAMO

Alternate routine for reading characters from program text

This routine retrieves a character from program text (bank 0). The value in the accumulator upon entry specifies the address of the zero-page pointer containing the base address, and the value in the Y register specifies the offset from this base address to the character to be read. The character will be in the accumulator upon return from the routine and the system will be left in the bank 14 configuration. BASIC ROM includes a collection of character retrieval subroutines (17102-17159/ $42CE-$4307) that make use of this routine.

939-950 $03AB-$03B6 INDSUB-RAM

Alternate routine for reading characters from variable storage

This routine retrieves a character from the variable storage area (bank 1). The value in the accumulator upon entry specifies the address of the zero-page pointer containing the base address, and the value in the Y register specifies the offset from this base address to the character to be read. The character will be in the accumulator upon return from the routine and the system will be left in the alternate bank 14 configuration that includes block 1 RAM. BASIC ROM includes a collection of character retrieval subroutines ($42CE-$4307) that make use of this routine.

951-959 $03B7-$03BF INDINl-RAM1

Alternate routine to retrieve a character from variable storage

This routine retrieves a character from the variable storage area (bank 1) using locations $24-$25 as a pointer and the contents of the Y register as an offset from the address in the pointer. The character will be in the accumulator upon return from the routine and the system will be left in the alternate bank 14 configuration that includes block 1 RAM.

960-968 $03C0-$03C8 INDIN2

Alternate routine to retrieve a character from program text

This routine retrieves a character from program text (bank 0) using locations $26-$27 as a pointer and the contents of the Y register as an offset from the address in the pointer. The character will be in the accumulator upon return from the routine and the system will be left in the bank 14 configuration.

969-977 $03C9-$03D1 INDTXT

Alternate routine to retrieve current program text character

This routine retrieves the current program text character using $3D-$3E as a pointer. The character will be in the accumulator upon return from the routine and the system will be left in the bank 14 configuration. The routine is similar to the CHRGOT entry into GHRGET, but without the tests for character type.

978-980 $03D2-$03D4 ZERO

Null descriptor

If the routine $7AAF which searches for a variable name in the variable table fails to find the name when called by EVAL $7978 or POINTER $82FA, the address of this area is returned as the variable descriptor address. This prevents variable table entries from being created if a variable name is first used in an expression argument or in the POINTER function. For example, if you use B$=A$ or AD=POINTER(A$) when no variable A$ exists, no entry for A$ will be created. These three locations are all filled with the value $00, copied here from ROM along with the preceding subroutines.

981 $03D5 CURRENT-BANK

Bank number for BASIC operations

The value in this location specifies the bank number used during BASIC routines which directly access memory. The value here doesn’t affect the current system configuration-only the configuration that will be established for certain operations. The value here specifies the bank to which data will stored when the POKE statement is used, or from which data will be read when the PEEK statement is used. The value here determines the bank configuration in which the target address for a SYS statement will be seen. It also determines the bank for the address used in the WAIT statement. The value here determines the default bank for the BOOT, BLOAD, and BSAVE statements. It also determines the system bank affected by the STASH, FETCH, and SWAP statements.

The value here is initialized to $0F during the BASIC cold-start sequence, so bank 15 is the default. The BANK statement can be used to change the value here.

982-985 $03D6-$03D9 TMPDES

Pointers for INSTR evaluation

These locations are used as working pointers for the INSTR statement routine [$99C1]. Locations $03D6-$03D7 hold the address of the first string parameter and locations $03D8-$03D9 hold the address of the second string.

986 $03DA FIN-BANK

String block flag

This location is used during the routine $8D22 to convert character strings into floating-point values to indicate whether the string being converted resides in BASIC program text (block a RAM) or in the string pool (block 1 RAM).

987-990 $03DB-$03DE SAVSIZ

Temporary storage for SHAPE data

These locations are used during the SSHAPE routine $642B to hold coordinates of the area being saved, and during the SPRSAV routine $76EC to hold the descriptor of the first parameter value.

991 $03DF BITS

Floating-point overflow byte

This location is used for working storage while aligning floating-point values for mathematical operations, or for converting floating-point values into integers. The value here is initialized to $00 during the BASIC cold-start sequence, and will be reset to that value during CLR or warm start.

992-993 $03E0-$03E1 SPRTMP

Temporary pointer storage

These locations are used during the SPRSAV routine $76EC to temporarily preserve the current value in the CHRGET pointer $3D-$3E.

994 $03E2 FG-BG

Standard bitmap color fill value

This location holds the color memory fill pattern for standard bitmapped mode. When the SCNCLR routine $6A79 is used to clear the standard bitmapped (GRAPHIC 1 or GRAPHIC 2) display, all locations in the video matrix area will be filled with the value here. The SCNCLR routine is also used when the clear parameter is specified in a GRAPHIC statement. In standard bitmapped mode, the video matrix area holds foreground and background color information, so the value here determines the default foreground and background colors for all screen positions after the screen is cleared.

Whenever the BASIC graphics routines are used to draw anything on the standard bitmapped display, the value in this location will determine the color of the line drawn. If color source 0 was specified for the line, the value in the lower four bits here will be stored in the lower four bits of the video matrix locations corresponding to the line’s location in the bitmap. If color source 1 is specified, the value in the upper four bits here will be stored in the upper four bits of the video matrix locations corresponding to the line’s location in the bitmap.

The value in this location is updated whenever the COLOR statement $69E2 is executed. The high four bits here are set to the value in the lower four bits of the foreground color in location $86. The lower four bits here are set to the value in the lower four bits of the VIC background color register at $D021. These locations are initialized during the BASIC cold-start sequence to the default foreground and background colors, so this location will initially hold 219/$DB, for a light green foreground and dark gray background. The value here is not affected by RUN/STOP-RESTORE.

995 $03E3 FG-MCI

Multicolor bitmap color fill value

This location holds the color memory fill pattern for multicolor bitmapped mode. When the SCNCLR routine $6A79 is used to clear the multicolor bitmapped (GRAPHIC 3 or GRAPHIC 4) display, all locations in the video matrix area will be filled with the value here. The SCNCLR routine is also used when the clear parameter is specified in a GRAPHIC statement. In multicolor bitmapped mode, the video matrix area holds color information for pixels with %01 and %10 bit patterns, so the value here determines the default colors for those pixel patterns in all screen positions after the screen is cleared.

For the BASIC graphics routines that draw on the multicolor bitmapped display, the value in this location will determine the color of any lines drawn using color sources 1 or 2. If color source 1 was specified for the line, the value in the upper four bits here will be stored in the upper four bits of the video matrix locations corresponding to the line’s location in the bitmap. If color source 2 was specified, the value in the lower four bits here will be stored in the lower four bits of the video matrix locations corresponding to the line’s location in the bitmap.

The value in these locations can be changed with the COLOR statement $69E2. The high four bits here are set to the value in the lower four bits of the foreground color in location $86. The lower four bits here are set to the multicolor 1 value in the lower four bits of location $84. The location is initialized during the BASIC cold-start sequence to the default multicolor pixel colors for %01 and %10 patterns, so this location will initially hold $D1, for light green %01 pixels and white %10 pixels. The value here is not affected by RUN/STOP-RESTORE.

996-1007 $03E4-$03EF Unused

The locations in this range are not used by any system ROM routine, and are thus available for your own programming.

1008-1020 $03F0-$03FC DMA

DMA_CALL execution routine

This area holds the RAM-resident portion of the Kernal DMA-CALL routine $F7A5. The routine is copied here from Kernal ROM during the reset sequence. It is designed to initiate a DMA (direct memory access) command to the REC (RAM expansion controller) chip in an installed memory expansion module. The routine loads the current memory configuration register contents, then stores the contents of the Y register in the REC command register address (57089/$DF01) and stores the contents of the accumulator in the MMU memory configuration register ($FF00). If the REC is configured in its default state, storing the value in the MMU register should trigger the specified REC operation. Upon completion of the operation, the original memory configuration register setting will be restored.

1021-1023 $03FD-$03FF Unused

The locations in this range are not used by any system ROM routine, and are thus available for your own programming.