Classic Computer Magazine Archive ANTIC VOL. 8, NO. 7 / DECEMBER 1989

Mapping the Atari


Classic 8-bit reference book returns.

By Ian Chadwick

Antic continues the exclusive serialization of key excerpts from the revised second edition of Ian Chadwick's "Mapping the Atari." Virtually impossible to obtain today, this book has been one of the key reference sources for intermediate and advanced Atari 8-bit programmers since 1983.

This exclusive Antic serialization began in the August 1989 issue, with an explanation of how to use the memory map locations presented in each successive issue.

Locations 512 to 1151 ($200 to $47F) are used by the OS for working variables, tables, and data buffers. In this area, locations 512 to 553 ($200 to $229) are used for interrupt vectors, and locations 554 to 623 ($22A to $26F) are for miscellaneous use. Much of pages two through five cannot be used except by the OS unless specifically noted. A number of bytes are marked as 'spare', i.e., not in use currently. The status of these bytes may change with an Atari upgrade, so their use is not recommended.

There are two types of interrupts: Non-Maskable Interrupts (NMI) processed by the ANTIC chip and Interrupt Requests (IRQ) processed by the POKEY and PIA chips. NMI's are for the VBLANK interrupts (VBI's; 546 to 549, $222 to $225), display list interrupts (DLI) and RESET key interrupts. They initiate the stage one and stage two VBLANK procedures; usually vectored through an OS service routine, they can be vectored to point to a user routine. IRQ's are for the timer interrupts, peripheral and serial bus interrupts, BREAK and other key interrupts, and 6502 BRK instruction interrupts. They can usually be used to vector to user routines. See NMIST 54278 ($D40F) and IRQEN 53774 ($D20E) for more information. NMI interrupt vectors are marked NMI; IRQ interrupt vectors are marked IRQ.

512,513 200,201 VDSLST

The vector for NMI Display List Interrupts (DLI): containing the address of the instructions to be executed during a DLI (DLI's are used to interrupt the processor flow for a few microseconds at the particular screen display line where the bit was set, allowing you to do another short routine such as music, changing graphics modes, etc.). The OS doesn't use DLI's; they must be user-enabled, written and vectored through here. The NMI status register at 54278 ($D40F) first tests to see if an interrupt was caused by a DLI and, if so, jumps through VDSLST to the routine written by the user. DLI's are disabled on powerup, but VBI's are enabled (see 546 to 549; $222 to $225)

VDSLST is initialized to point to 59315 ($E7B3), which is merely an RTI instruction. To enable DLI's, you must first POKE 54286 ($D40E) with 192 ($C0); otherwise, ANTIC will ignore your request. You then POKE 512 and 513 with the address (LSB/MSB) of the first assembly language routine to execute during the DLI. You must then set BIT 7 of the Display List instruction(s) where the DLI is to occur. You have only between 14 and 61 machine cycles available for your DLI, depending on your GRAPHICS mode. You must first push any 6502 registers onto the stack, and you must end your DLI with an RTI instruction. Because you are dealing with machine language for your DLI, you can POKE directly into the hardware registers you plan to change.

514,515 202,203 VPRCED

Serial (peripheral) proceed line vector, initialize to 59314 ($E7B2), which is merely a PLA, RTI instruction sequence. It is used when an IRQ interrupt occurs due to the serial I/O bus proceed line which is available for peripheral use.

516,517 204,205 VINTER

Serial (peripheral) interrupt vector, initialized to 59314 ($E7B2). Used for the IRQ interrupt due to a serial bus I/O interrupt.

518,519 206,207 VBREAK

Software break instruction vector for the 6502 BRK ($00) command (not the BREAK key, which is location 17; $11), initialized to 59314 ($E7B2). This vector is normally used for setting break points in an assembly language debug operation. IRQ.

520,521 208,209 VKEYBD

POKEY keyboard interrupt vector, used for an interrupt generated when any keyboard key is pressed other than BREAK or the console buttons. Console buttons never generate an interrupt unless one is specifically user-written. VKEYBD can be used to process the key code before it undergoes conversion to ATASCII form. Initialized to 65470 ($FFBE), which is the OS keyboard IRQ routine.

522,523 20A,20B VSERIN

POKEY serial I/O bus receive data ready interrupt vector, initialized to 60177 ($EB11), which is the OS code to place a byte from the serial input port into a buffer. Called INTRVEC by DOS, it is used as an interrupt vector location for an SIO patch. DOS changes this vector to 6691 ($1A23), the start of the DOS interrupt ready service routine. IRQ.

524,525 20C,20D VSEROR

POKEY serial I/O transmit ready interrupt vector, initialized to 60048 (EA90), which is the OS code to provide the next byte in a buffer to the serial output port. DOS changes this vector to 6630 ($19E6), the start of the DOS output needed interrupt routine. IRQ.

526,527 20E,20F VSEROC

POKEY serial bus transmit complete interrupt vector, initialized to 60113 ($EAD1), which sets a transmission done flag after the checksum byte is sent. IRQ.

528,529 210,211 VTIMR1

POKEY timer one interrupt vector, initialized to 59314 ($E7B2), which is a PLA, RTI instruction sequence. Timer interrupts are established when the POKEY timer AUDF1 (53760; $D200) counts down to zero. Values in the AUDF registers are loaded into STIMER at 53769 ($D209). IRQ.

530,531 212,213 VTIMR2

POKEY timer two vector for AUDF2 (53762, $D202), initialized to 59314 ($E7B2). IRQ.

532,533 214,215 VTIMR4

POKEY timer four vector for AUDF4 (53766, $D206), initialized to 59314 ($E7B2). This IRQ is only vectored in the 'B' version of the OS ROMs.

534,535 216,217 VIMIRQ

The IRQ immediate vector (general). Initialized to 59126 ($E6F6). JMP through here to determine cause of the IRQ interrupt. Note that with the new ('B') OS ROMs, there is a BREAK key interrupt vector at locations 566,567 ($236,$237).

The locations from 536 to 558 ($218 to $22E) are used for the system software times. Hardware timers are located in the POKEY chip and use the AUDF registers. These timers count backwards every 1/60 second (stage one VBLANK) or 1/30 second (stage two VBLANK) interval until they reach zero. If the VBLANK process is disabled or intercepted, the timers will not be updated. These locations are user-accessible and can be made to count time for music duration, game I/O, game clock and other functions.

Software timers are used for durations greater that one VBLANK interval (1/60 second). For periods of shorter duration, use the hardware registers.

536,537 218,219 CDTMV1

System timer one value. Counts backwards from 255. This SIO timer is decremented every stage one VBLANK. When it reaches zero, it sets a flag to jump (JSR) through the address stored in locations 550,551 ($226,$227). Only the realtime clock (locations 18-20; $12-$14), timer one, and the attract mode register (77; $4D) are updated when the VBLANK routine is cut short because time-critical code (CRITIC equals non-zero) is being executed. It performs a JSR through location 552,553 ($228, $229) when the value counts down to zero.

540,541 21C,21D CDTMV3

System timer three. Same as 538. Timers three, four, and five are stopped when the OS sets the CRITIC flag to non-zero as well. The OS uses timer three to OPEN the cassette recorder and to set the length of time to read and write tape headers.

542,543 21E,21F CDTMV4

System timer four. Same as 538 ($21A).

544,545 220,221 CDTMV5

System timer five. Same as 538 ($21A). Timers three, four, and five all set flags at 554, 556 and 558 ($22A, $22C, $22E), respectively, when they decrement to zero.

546,547 222,223 VVBLKI

VBLANK immediate register. Normally jumps to the stage one VBLANK vector NMI interrupt processor at location 59345 ($E7D1); in the new OS 'B' ROMs; 59310 ($E7AE). The NMI status register tests to see if the interrupt was due to a VBI (after testing for a DLI) and, if so, vectors through here to the VBI routine, which may be user-written.

548,549 224,225 VBLANK

VBLANK deferred register; system return from interrupt, initialized to 59710 ($E93E, in the new OS 'B' ROMs; 59653; $E905), the exit for the VBLANK routine. NMI.

550,551 226,227 CDTMA1

System timer one jump address, initialized to 60400 ($EBF0). When locations 536, 537 ($218, $219) reach (count down to) zero, the OS vectors through here (jumps to the location specified by these two addresses). You can set your machine code routine address here for execution when timer one reaches (counts down to) zero. Your code should end with the RTS instruction.

552,553 228,229 CDTMA2

System timer two jump address. Not used by the OS, available to user to enter the address of his or her own routine to JMP to when the timer two (538, 539; $21A, $21B) count reaches zero. Initialized to zero; the address must be user specified. NMI.

554 22A CDTMF3

System timer three flag, set when location 540,541 ($21C, $21D) reaches zero. This register is also used by DOS as a timeout flag.

555 22B SRTIMR

Software repeat timer, controlled by the IRQ device routine. It establishes the initial 1/2 second delay before a key will repeat. Stage two VBLANK establishes the 1/10 second repeat rate, decrements the timer and implements the auto repeat logic.

556 22C CDTMF4

System timer four flag. Set when location 542, 543 ($21E, $21F) counts down to zero.

557 22D INTEMP

Temporary register used by the SETVBL routine at 58460 ($E45C).

558 22E CDTMF5

System timer five flag. Set when location 558, 559 ($22E, $22F) counts down to zero.

559 22F SDMCTL

Direct Memory Access (DMA) enable. POKEing with zero allows you to turn off ANTIC and speed up processing by 30%. Of course, it also means the screen goes blank when ANTIC is turned off! This is useful to speed things up when you are doing a calculation that would take a long time. It is also handy to turn off the screen when loading a drawing, then turning it on when the screen is loaded so that it appears instantly, complete on the screen. To use it you must first PEEK(559) and save the result in order to return your screen to you. Then POKE 599,0 to turn off ANTIC. When you are ready to bring the screen back to life, POKE 559 with the number saved earlier.

560,561 230,231 SDLSTL

Starting address of the display list. The display list is an instruction set to tell ANTIC where the screen data is and how to display it. These locations are the shadow for 54274 and 54275 ($D402, $D403).

562 232 SSKCTL

Serial port control register, shadow for 53775 ($D20F).

564 234 LPENH

Light pen horizontal value: shadow for 54284 ($D40C). Values range from zero to 227.

565 235 LPENV

Light pen vertical value: shadow 54285 ($D40D).

566,567 236,237 BRKKY

BREAK key interrupt vector. You can use this vector to write your own BREAK key interrupt routine. Initialized to 59220 ($E754).

570 23A CDEVIC

Four-byte command frame buffer (CFB) address for a device -- used by SIO while performing serial I/O, not for user access. CDEVIC is used for the SIO bus ID number. The other three CFB bytes are:

571 23B CCOMND

The SIO bus command code.

572 23C CAUX1

Command auxiliary byte one, loaded from location 778 ($30A) by SIO.

573 23D CAUX2

Command auxiliary byte one, loaded from location 779 ($30B) by SIO.

574 23E TEMP

Temporary RAM register for SIO.

575 23F ERRFLG

SIO error flag; any device error except the timeout error (time equals zero).

576 240 DFLAGS

Disk flags read from the first byte of the boot file (sector one) of the disk.

577 241 DBSECT

The number of disk boot sectors read from the first disk record.

578,579 242,243 BOOTAD

The address for where the disk boot loader will be put. The record just read will be moved to the address specified here, followed by the remaining record to be read. Normally, with DOS, this address is 1792 ($700), the value also stored temporarily in RAMLO at 4,5. Address 62189 ($F2ED) is the OS disk boot routine entry point (DOBOOT).

580 244 COLDST

Coldstart flag. Zero is normal; if zero, then pressing RESET will not result in a reboot. If POKEd with on (powerup in progress flag), the computer will reboot whenever the RESET key is pressed.

582 246 DSKTIM

Disk time-out register (the address of the OS worst case disk time-out). It is said by many sources to be set to 160 at initialization, which represents a 171 second time-out, but my system shows a value of 224 on initialization. Timer values are 64 seconds for each 60 units of measurement expressed.

583-622 247-26E LINBUF

Forty-byte character line buffer, used to temporarily buffer one physical line of text when the screen editor is moving screen data. The pointer to this buffer is stored in 100,101 ($64,$65) during the routine.

623 26F GPRIOR

Priority selection register, shadow for 53275 ($D01B). Priority options select which screen objects will be in front of others. It also enables you to use all four missiles as a fifth player and allows certain overlapping players to have different colors in the areas of overlap. You add your options up as in location 559, prior to POKEing the total into 623.

Locations 624 to 647 ($270 to $287) are used for game controllers: paddle, joystick and lightpen values.

624 270 PADDL0

The value of paddle 0 (paddles are also called pots, short for potentiometer); PEEK 624 returns a number between zero and 228 ($E4), increasing as the knob is turned counter- clockwise.

625 271 PADDL1

This and the next six bytes are the same as 624, but for the other paddles.

632 278 STICK0

The value of joystick 0. STICK registers are shadow locations for PIA locations 54016 and 54017 ($D300,$D301). There are nine possible decimal values (representing 45 degree increments) read by each joystick register (using the STICKn command).

Copyright 1983 and 1985, COMPUTE! Publications, Inc.
$16.95, COMPUTE! Books, P.O. Box 5406, Greensboro, NC 27403. (919) 275-9809.

Ian Chadwick is a Toronto-based free- lance writer.