aboutsummaryrefslogtreecommitdiff
path: root/mapping.txt
diff options
context:
space:
mode:
Diffstat (limited to 'mapping.txt')
-rw-r--r--mapping.txt8814
1 files changed, 8814 insertions, 0 deletions
diff --git a/mapping.txt b/mapping.txt
new file mode 100644
index 0000000..584b8a1
--- /dev/null
+++ b/mapping.txt
@@ -0,0 +1,8814 @@
+ MEMORY MAP
+
+ Locations zero to 255 ($0 to $FF) are called "page zero" and have
+ special importance for assembly language programmers since these
+ locations are accessed faster and easier by the machine.
+
+ Locations zero to 127 ($0 to $7F) are reserved as the OS page zero,
+ while 128 to 255 ($80 to $FF) are the BASIC and the user zero page
+ RAM. Locations zero to 1792 ($0 to $700) are all used as the OS and (if
+ the cartridge is present) 8K BASIC RAM (except page six). Locations
+ zero to 8191 ($0 to $1FFF) are the minimum required for operation
+ (8K).
+
+ Locations two through seven are not cleared on any start operation.
+
+ DECIMAL HEX LABEL
+
+ 0,1 0,1 LINZBS
+
+ LINBUG RAM, replaced by the monitor RAM See the OS
+ Listing, page 31. It seems to be used to store the VBLANK timer
+ value. One user application I've seen for location zero is in a
+ metronome program in De Re Atari. Also used in cross-
+ assembling the Atari OS.
+
+
+ 2,3 2,3 CASINI
+
+ Cassette initialization vector: JSR through here if the cassette
+ boot was successful. This address is extracted from the first six
+ bytes of a cassette boot file. The first byte is ignored. The second
+ contains the number of records, the third and fourth contain the
+ low and high bytes of the load address, and the fifth and sixth
+ contain the low and high bytes of the initialization address.
+ Control upon loading jumps to the load address plus six for a
+ multi-stage load and through CASINI for initialization. JSR
+ through DOSVEC (10 and 11; $A,$B) to transfer control to the
+ application.
+
+
+ 4,5 4,5 RAMLO
+
+ RAM pointer for the memory test used on powerup. Also used to
+ store the disk boot address--normally 1798 ($706)--for the
+ boot continuation routine.
+
+
+ 6 6 TRAMSZ
+
+ Temporary Register for RAM size; used during powerup
+ sequence to test RAM availability. This value is then moved to
+ RAMTOP, location 106 ($6A). Reads one when the BASIC or the
+ A (left) cartridge is plugged in.
+
+
+ 7 7 TSTDAT
+
+ RAM test data register. Reads one when the B or the right
+ cartridge is inserted.
+
+ RAMLO, TRAMSZ and TSTDAT are all used in testing the RAM
+ size on powerup. On DOS boot, RAMLO and TRAMSZ also act as
+ temporary storage for the boot continuation address. TRAMSZ
+ and TSTDAT are used later to flag whether or not the A (left)
+ and/or B (right) cartridges, respectively, are plugged in (non-
+ zero equals cartridge plugged in) and whether the disk is to be
+ hooted.
+
+ Locations eight through 15 ($8-$F) are cleared on coldstart only.
+
+
+ 8 8 WARMST
+
+ Warmstart flag. If the location reads zero, then it is in the middle
+ of powerup; 255 is the normal RESET status. Warmstart is similar
+ to pressing RESET, so should not wipe out memory, variables, or
+ programs. WARMST is initialized to zero and will not change
+ values unless POKEd or until the first time the RESET button is
+ pressed. It will then read 255 ($FF).
+
+ Warmstart normally vectors to location 58484 ($E474). WARMST
+ is checked by the NMI status register at 54287 ($D40F) when
+ RESET is pressed to see whether or not to re-initialize the
+ software or to re-boot the disk.
+
+
+ 9 9 BOOT?
+
+ Boot flag success indicator. A value of 255 in this location will
+ cause the system to lockup if RESET is pressed. If BOOT? reads
+ one, then the disk boot was successful; if it reads two, then the
+ cassette boot was successful. If it reads zero, then neither
+ peripheral was booted.
+
+ If it is set to two, then the cassette vector at locations two and
+ three will be used on RESET. Set to one, it will use the DOS
+ vector at 10 and 11 ($A and $B). Coldstart attempts both a
+ cassette and a disk boot and flags this location with the success or
+ failure of the boots. BOOT? is checked during both disk and
+ cassette boot.
+
+
+ 10,11 A,B DOSVEC
+
+ Start vector for disk (or non-cartridge) software. This is the
+ address BASIC jumps to when you call up DOS. Can be set by
+ user to point to your own routine, but RESET will return DOSVEC
+ to the original address. To prevent this, POKE 5446 with the LSB
+ and 5450 with the MSB of your vector address and re-save DOS
+ using the WRITE DOS FILES option in the menu. Locations 10
+ and 11 are usually loaded with 159 and 23 ($9F and $17),
+ respectively. This allows the DUPSYS section of DOS to be
+ loaded when called. It is initially set to blackboard mode vector
+ (58481; $E471--called by typing "BYE" or "B." from BASIC); it
+ will also vector to the cassette run address if no DOS vector is
+ loaded in. If you create an AUTORUN.SYS file that doesn't end
+ with an RTS instruction, you should set BOOT? to one and 580
+ ($244) to zero.
+
+
+ 12,13 C,D DOSINI
+
+ Initialization address for the disk boot. Also used to store the
+ cassette-boot RUN address, which is then moved to CASINI (2,
+ 3). When you powerup without either the disk or an autoboot
+ cassette tape, DOSINI will read zero in both locations.
+
+
+ 14,15 E,F APPMHI
+
+ Applications memory high limit and pointer to the end of your
+ BASIC program, used by both the OS and BASIC. It contains the
+ lowest address you can use to set up a screen and Display List
+ (which is also the highest address usable for programs and data
+ below which the display RAM may not be placed). The screen
+ handler will not OPEN the "S:" device if it would extend the
+ screen RAM or the Display List below this address; memory
+ above this address may be used for the screen display and other
+ data (PM graphics, etc.).
+
+ If an attempted screen mode change would extend the screen
+ memory below APPMHI, then the screen is set up for GRAPHICS
+ mode zero; MEMTOP (locations 741, 742; $2E5, $2E6) is updated
+ and an error is returned to the user. Otherwise, the memory is not
+ too small for the screen editor; the mode change will take effect
+ and MEMTOP will be updated. This is one of five locations used
+ by the OS to keep track of the user and display memory.
+ Initialized to zero by the OS at powerup. Remember, you cannot
+ set up a screen display below the location specified here.
+
+ If you use the area below the Display List for your character sets,
+ PM graphics or whatever, be sure to set APPMHI above the last
+ address used so that the screen or the DL data will not descend
+ and destroy your own data. See RAMTOP location 106 ($6A),
+ MEMTOP at 741, 742 ($2E5, $2E6), PMBASE at 54279 ($D407)
+ and CHBASE at 54281 ($D409) for more information.
+
+ Locations 16 through 127 ($10-$7F) are cleared on either cold- or
+ warmstart.
+
+
+ 16 10 POKMSK
+
+ POKEY interrupts: the IRQ service uses and alters this location.
+ Shadow for 53774 ($D20E). POKE with 112 ($70; also POKE this
+ same value into 53774) to disable the BREAK key. If the following
+ bits are set (to one), then these interrupts are enabled (bit
+ decimal values are in parentheses):
+
+ BIT DECIMAL FUNCTION
+ 7 128 The BREAK key is enabled.
+ 6 64 The "other key" interrupt is enabled.
+ 5 32 The serial input data ready interrupt is
+ enabled.
+ 4 16 The serial output data required interrupt is
+ enabled.
+ 3 8 The serial out transmission finished
+ interrupt is enabled.
+ 2 4 The POKEY timer four interrupt is enabled
+ (only in the "B" or later versions of the OS
+ ROMs).
+ 1 2 The POKEY timer two interrupt is enabled.
+ 0 1 The POKEY timer one interrupt is enabled.
+
+ Timer interrupt enable means the associated AUDF registers are
+ used as timers and will generate an interrupt request when they
+ have counted down to zero. See locations 528 to 535 ($210 to
+ $217) and the POKEY chip from locations 53760 ($D200) on, for a
+ full explanation. 192 ($C0) is the default on powerup.
+
+ You can also disable the BREAK key by POKEing here with 64
+ ($40; or any number less than 128; $80) and also in location
+ 53774. The problem with simple POKEs is that the BREAK key is
+ re-enabled when RESET is pressed and by the first PRINT
+ statement that displays to the screen, or any OPEN statement that
+ addresses the screen (S: or E:), or the first PRINT statement after
+ such an OPEN and any GRAPHICS command. In order to
+ continually disable the BREAK key if such commands are being
+ used, it's best to use a subroutine that checks the enable bits
+ frequently during input and output operations, and POKEs a
+ value less than 128 into the proper locations, such as:
+
+ 1000 BREAK = PEEK(16) - 128: IF BREA
+ K < 0 THEN RETURN
+ 1010 POKE 16, BREAK: POKE 53774, BRE
+ AK: RETURN
+
+ The new OS "B" version ROMs have a vector for the BREAK key
+ interrupt, which allows users to write their own routines to
+ process the interrupt in the desired manner. It is located at 566,
+ 567 ($236, $237).
+
+
+ 17 11 BRKKEY
+
+ Zero means the BREAK key is pressed; any other number means
+ it's not. A BREAK during I/O returns 128 ($80). Monitored by
+ both keyboard, display, cassette and screen handlers. See
+ location 16 ($A) for hints on disabling the BREAK key. The latest
+ editions of OS provide for a proper vector for BREAK interrupts.
+ The BREAK key abort status code is stored in STATUS (48; $30).
+ It is also checked during all I/O and scroll/draw routines. During
+ the keyboard handler routine, the status code is stored in DSTAT
+ (76; $4C). BRKKEY is turned off at powerup. BREAK key abort
+ status is flagged by setting BIT 7 of 53774 ($D20E). See the note
+ on the BREAK key vector, above.
+
+
+ 18,19,20 12,13,14 RTCLOK
+
+ Internal realtime clock. Location 20 increments every stage one
+ VBLANK interrupt (1/60 second = one jiffy) until it reaches 255
+ ($FF); then location 19 is incremented by one and 20 is reset to
+ zero (every 4.27 seconds). When location 19 reaches 255, it and
+ 20 are reset to zero and location 18 is incremented by one (every
+ 18.2 minutes or 65536 TV frames). To use these locations as a
+ timer of seconds, try:
+
+ TIME = INT((PEEK(18) * 65536 + PEEK(19) * 256 +
+ PEEK(20) )/60)
+
+ To see the count in jiffies, eliminate the "/60" at the end. To see
+ the count in minutes, change "/60" to "/360." The maximum
+ value of the RT clock is 16,777,215. When it reaches this value, it
+ will be reset to zero on the next VBLANK increment. This value is
+ the result of cubing 256 (i.e., 256 * 256 * 256), the maximum
+ number of increments in each clock register. The RT clock is
+ always updated every VBLANK regardless of the time-critical
+ nature of the code being processed.
+
+ A jiffy is actually a long time to the computer. It can perform
+ upwards of 8000 machine cycles in that time. Think of what can
+ be done in the VBLANK interval (one jiffy). In human terms, a
+ jiffy can be upwards of 20 minutes, as witnessed in the phrase "I'll
+ be ready in a jiffy." Compare this to the oft-quoted phrase, "I'll
+ be there in a minute," used by intent programmers to describe a
+ time frame upwards of one hour.
+ Users can POKE these clock registers with suitable values for
+ their own use. The realtime clock is always updated during the
+ VBLANK interval. Some of the other timer registers (locations
+ 536 to 544; $218 to $220) are not always updated when the OS is
+ executing time critical code.
+ Here's one way to use the realtime clock for a delay timer:
+
+ 10 GOSUB 100
+ .
+ .
+ .
+ 100 POKE 20,0: POKE 19,0
+ 110 IF NOT PEEK(19) THEN 110
+ 120 RETURN
+
+ Line 110 waits to see if location 19 returns to zero and, when it
+ does, passes control to the RETURN statement.
+
+ See COMPUTE!, August 1982, for a useful program to create a
+ small realtime clock that will continue to display during your
+ BASIC programming. See also De Re Atari for another realtime
+ clock application.
+
+
+ 21,22 15,16 BUFADR
+
+ Indirect buffer address register (page zero). Temporary pointer
+ to the current disk buffer.
+
+
+ 23 17 ICCOMT
+
+ Command for CIO vector. Stores the CIO command; used to find
+ the offset in the command table for the correct vector to the
+ handler routine.
+
+
+ 24,25 18,19 DSKFMS
+
+ Disk file manager pointer. Called JMPTBL by DOS; used as
+ vector to FMS.
+
+
+ 26,27 1A,1B DSKUTL
+
+ The disk utilities pointer. Called BUFADR by DOS, it points to
+ the area saved for a buffer for the utilities package (data buffer;
+ DBUF) or for the program area (MEMLO; 743, 744; $2E7, $2E8).
+
+
+ 28 1C PTIMOT
+
+ Printer timeout, called every printer status request. Initialized to
+ 30, which represents 32 seconds (the value is 64 seconds per 60
+ increments in this register); typical timeout for the Atari 825
+ printer is five seconds. The value is set by your printer handler
+ software. It is updated after each printer status request operation.
+ It gets the specific timeout status from location 748 ($2EC), which
+ is loaded there by SIO.
+
+ The new "B" type OS ROMs have apparently solved the problem
+ of timeout that haunted the "A" ROMs; you saw it when the
+ printer or the disk drive periodically went to sleep (timed out) for
+ a few seconds, causing severe anxiety attacks in the owners who
+ thought their Ataris had just mysteriously died. This is
+ compounded when one removes a disk from the drive, believing
+ the I/O process to be finished--only to have the drive start up
+ again after the timeout and trying to write to or read from a
+ nonexistent disk. Usually both the system and the user crash
+ simultaneously at this point. See the appendix for more
+ information on the new ROMs.
+
+
+ 29 1D PBPNT
+
+ Print buffer pointer; points to the current position (byte) in the
+ print buffer. Ranges from zero to the value in location 30.
+
+
+ 30 1E PBUFSZ
+
+ Print buffer size of printer record for current mode. Normal
+ buffer size and line size equals 40 bytes; double-width print
+ equals 20 bytes (most printers use their own control codes for
+ expanded print); sideways printing equals 29 bytes (Atari 820
+ printer only). Printer status request equals four. PBUFSZ is
+ initialized to 40. The printer handler checks to see if the same
+ value is in PBPNT and, if so, sends the contents of the buffer to
+ the printer.
+
+
+ 31 1F PTEMP
+
+ Temporary register used by the printer handler for the value of
+ the character being output to the printer.
+
+ ----------------------------------------------------------------------
+
+ Locations 32 to 47 ($20 to $2F) are the ZIOCB: Page zero Input-Output
+ Control Block. They use the same structure as the IOCB's at locations
+ 832 to 959 ($340 to $3BF). The ZIOCB is used to communicate I/O con-
+ trol data between CIO and the device handlers. When a CIO opera-
+ tion is initiated, the information stored in the IOCB channel is moved
+ here for use by the CIO routines. When the operation is finished, the
+ updated information is returned to the user area.
+
+
+ 32 20 ICHIDZ
+
+ Handler index number. Set by the OS as an index to the device
+ name table for the currently open file. If no file is open on this
+ IOCB (IOCB free), then this register is set to 255 ($FF).
+
+
+ 33 21 ICDNOZ
+
+ Device number or drive number Called MAXDEV by DOS to in-
+ dicate the maximum number of devices. Initialized to one.
+
+
+ 34 22 ICCOMZ
+
+ Command code byte set by the user to define how the rest of the
+ IOCB is formatted, and what I/O action is to be performed.
+
+
+ 35 23 ICSTAZ
+
+ Status of the last IOCB action returned by the device, set by the
+ OS. May or may not be the same status returned by the STATUS
+ command.
+
+
+ 36,37 24,25 ICBALZ/HZ
+
+ Buffer address for data transfer or the address of the file name for
+ commands such as OPEN, STATUS, etc.
+
+
+ 38,39 26,27 ICPTLZ/HZ
+
+ Put byte routine address set by the OS. It is the address minus
+ one byte of the device's "put one byte" routine. It points to CIO's
+ "IOCB not OPEN" on a CLOSE statement.
+
+
+ 40,41 28,29 ICBLLZ/HZ
+
+ Buffer length byte count used for PUT and GET operations;
+ decreased by one for each byte transferred.
+
+
+ 42 2A ICAX1Z
+
+ Auxiliary information first byte used in OPEN to specify the type
+ of file access needed.
+
+
+ 43 2B ICAX2Z
+
+ CIO working variables, also used by some serial port functions.
+ Auxiliary information second byte.
+
+
+ 44,45 2C,2D ICAX3Z/4Z
+
+ Used by BASIC NOTE and POINT commands for the transfer of
+ disk sector numbers. These next four bytes to location 47 are also
+ labelled as: ICSPRZ and are defined as spare bytes for local CIO
+ use.
+
+
+ 46 2E ICAX5Z
+
+ The byte being accessed within the sector noted in locations 44
+ and 45. It is also used for the IOCB Number multiplied by 16.
+ Each IOCB block is 16 bytes long. Other sources indicate that the
+ 6502 X register also contains this information.
+
+
+ 47 2F ICAX6Z
+
+ Spare byte. Also labelled CIOCHR, it is the temporary storage
+ for the character byte in the current PUT operation.
+
+ -------------------------------------------------------------------
+
+
+ 48 30 STATUS
+
+ Internal status storage. The SIO routines in ROM use this byte to
+ store the status of the current SIO operation. See page 166 of the
+ OS User's Manual for status values. STATUS uses location 793
+ ($319) as temporary storage. STATUS is also used as a storage
+ register for the timeout, BREAK abort and error values during
+ SIO routines.
+
+
+ 49 31 CHKSUM
+
+ Data frame checksum used by SIO: single byte sum with carry to
+ the least significant bit. Checksum is the value of the number of
+ bytes transmitted (255; $FF). When the number of transmitted
+ bytes equals the checksum, a checksum sent flag is set at location
+ 59 ($3B). Uses locations 53773 ($D20D) and 56 ($38) for com-
+ parison of values (bytes transmitted).
+
+
+ 50,51 32,33 BUFRLO/HI
+
+ Pointer to the data buffer, the contents of which are transmitted
+ during an I/O operation, used by SIO and the Device Control
+ Block (DCB); points to the byte to send or receive. Bytes are
+ transferred to the eight-bit parallel serial output holding register
+ or from the input holding register at 53773 ($D20D). This register
+ is a one-byte location used to hold the eight bits which will be
+ transmitted one bit at a time (serially) to or from the device. The
+ computer takes the eight bits for processing when the register is
+ full or replaces another byte in it when empty after a
+ transmission.
+
+
+ 52,53 34,35 BFENLO/HI
+
+ Next byte past the end of the SIO and DCB data buffer described
+ above.
+
+
+ 54 36 CRETRY
+
+ Number of command frame retries. Default is 13 ($0D). This is the
+ number of times a device will attempt to carry out a command
+ such as read a sector or format a disk.
+
+
+ 55 37 DRETRY
+
+ Number of device retries. The default is one.
+
+
+ 56 38 BUFRFL
+
+ Data buffer full flag (255; $FF equals full).
+
+
+ 57 39 RECVDN
+
+ Receive done flag (255; $FF equals done).
+
+
+ 58 3A XMTDON
+
+ Transmission done flag (255; $FF equals done).
+
+
+ 59 3B CHKSNT
+
+ Checksum sent flag (255; $FF equals sent).
+
+
+ 60 3C NOCKSM
+
+ Flag for "no checksum follows data." Not zero means no
+ checksum follows; zero equals checksum follows transmission
+ data.
+
+
+ 61 3D BPTR
+
+ Cassette buffer pointer: record data index into the portion of data
+ being read or written. Ranges from zero to the current value at
+ location 650 ($28A). When these values are equal, the buffer at
+ 1021 ($3FD) is empty if reading or full if writing. Initialized to 128
+ ($80).
+
+
+ 62 3E FTYPE
+
+ Inter-record gap type between cassette records, copied from
+ location 43 ($2B; ICAX2Z) in the ZIOCB, stored there from
+ DAUX2 (779; $30B) by the user. Normal gaps are a non-zero
+ positive number; continuous gaps are zero (negative number).
+
+
+ 63 3F FEOF
+
+ Cassette end of file flag. If the value is zero, an end of file (EOF)
+ has not been reached. Any other number means it has been
+ detected. An EOF record has been reached when the command
+ byte of a data record equals 254 ($FE). See location 1021 ($3FD).
+
+
+ 64 40 FREQ
+
+ Beep count retain register. Counts the number of beeps required
+ by the cassette handler during the OPEN command for play or
+ record operations; one beep for play, two for record.
+
+
+ 65 41 SOUNDR
+
+ Noisy I/O flag used by SIO to signal the beeping heard during
+ disk and cassette I/O. POKE here with zero for blessed silence
+ during these operations. Other numbers return the beep. In-
+ itialized to three. The hardware solution to this problem is to turn
+ your speaker volume down. This can also be used to silence the
+ digital track when playing synchronized voice/data tapes. See
+ location 54018.
+
+
+ 66 42 CRITIC
+
+ Critical I/O region flag; defines the current operation as a time-
+ critical section when the value here is non-zero. Checked at the
+ NMI process after the stage one VBLANK has been processed.
+ POKEing any number other than zero here will disable the repeat
+ action of the keys and change the sound of the CTRL-2 buzzer.
+
+ Zero is normal; setting CRITIC to a non-zero value suspends a
+ number of OS processes including system software timer coun-
+ ting (timers two, three, four and five; see locations 536 to 558;
+ $218 to $22E). It is suggested that you do not set CRITIC for any
+ length of time. When one timer is being set, CRITIC stops the
+ other timers to do so, causing a tiny amount of time to be "lost."
+ When CRITIC is zero, both stage one and stage two VBLANK
+ procedures will be executed. When non-zero, only the stage one
+ VBLANK will be processed.
+
+
+ 67-73 43-49 FMZSPG
+
+ Disk file manager system (FMS) page zero registers (seven
+ bytes).
+
+
+ 67,68 43,44 ZBUFP
+
+ Page zero buffer pointer to the user filename for disk I/O.
+
+
+ 69,70 45,46 ZDRVA
+
+ Page zero drive pointer. Copied to here from DBUFAL and
+ DBUFAH; 4905 and 4913 ($1329, $1331). Also used in FMS "free
+ sector," setup and "get sector" routines.
+
+
+ 71,72 47,48 ZSBA
+
+ Zero page sector buffer pointer.
+
+
+ 73 49 ERRNO
+
+ Disk I/O error number. Initialized to 159 ($9F) by FMS.
+
+
+ 74 4A CKEY
+
+ Cassette boot request flag on coldstart. Checks to see if the
+ START key is pressed and, if so, CKEY is set. Autoboot cassettes
+ are loaded by pressing the START console key while turning the
+ power on. In response to the beep, press the PLAY button on the
+ recorder.
+
+
+ 75 4B CASSBT
+
+ Cassette boot flag. The Atari attempts both a disk and a cassette
+ boot simultaneously. Zero here means no cassette boot was suc-
+ cessful. See location 9
+
+
+ 76 4C DSTAT
+
+ Display status and keyboard register used by the display handler.
+ Also used to indicate memory is too small for the screen mode,
+ cursor out of range error, and the BREAK abort status.
+
+
+ 77 4D ATRACT
+
+ Attract mode timer and flag. Attract mode rotates colors on your
+ screen at low luminance levels when the computer is on but no
+ keyboard input is read for a long time (seven to nine minutes).
+ This helps to save your TV screen from "burn-out" damage suf-
+ fered from being left on and not used. It is set to zero by IRQ
+ whenever a key is pressed, otherwise incremented every four
+ seconds by VBLANK (see locations 18 - 20; $12 - $14). When the
+ value in ATRACT reaches 127 ($7F), it is then set to 254 ($FE) un-
+ til attract mode is terminated. This sets the flag to reduce the
+ luminance and rotate the colors when the Atari is sitting idle.
+ POKE with 128 ($80) to see this effect immediately: it normally
+ takes seven to nine minutes to enable the attract mode. The OS
+ cannot "attract" color generated by DLI's, although your DLI
+ routine can, at a loss of time.
+
+ Joysticks alone will not reset location 77 to zero. You will have to
+ add a POKE 77,0 to your program periodically or frequently call
+ in a subroutine to prevent the Atari from entering attract mode if
+ you are not using any keyboard input.
+
+
+ 78 4E DRKMSK
+
+ Dark attract mask; set to 254 ($FE) for normal brightness when
+ the attract mode is inactive (see location 77). Set to 246 ($F6)
+ when the attract mode is active to guarantee screen color
+ luminance will not exceed 50% . Initialized to 254 ($FE).
+
+
+ 79 4F COLRSH
+
+ Color shift mask; attract color shifter; the color registers are
+ EORd with locations 78 and 79 at the stage two VBLANK (see
+ locations 18 - 20; $12 - $14). When set to zero and location 78
+ equals 246, color luminance is reduced 50%. COLRSH contains
+ the current value of location 19, therefore is given a new color
+ value every 4.27 seconds.
+
+ Bytes 80 to 122 ($50 to $7A) are used by the screen editor and display
+ handler.
+
+
+ 80 50 TEMP
+
+ Temporary register used by the display handler in moving data to
+ and from screen. Also called TMPCHR.
+
+
+ 81 51 HOLD1
+
+ Same as location 80. It is used also to hold the number of Display
+ List entries.
+
+
+ 82 52 LMARGN
+
+ Column of the left margin of text (GR.0 or text window only).
+ Zero is the value for the left edge of the screen; LMARGN is
+ initialized to two. You can POKE the margin locations to set them
+ to your specific program needs, such as POKE 82,10 to make the
+ left margin start ten locations from the edge of the screen.
+
+
+ 83 53 RMARGN
+
+ Right margin of the text screen initialized to 39 ($27). Both
+ locations 82 and 83 are user-alterable, but ignored in all
+ GRAPHICS modes except zero and the text window.
+ Margins work with the text window and blackboard mode and are
+ reset to their default values by pressing RESET. Margins have no
+ effect on scrolling or the printer. However, DELETE LINE and
+ INSERT LINE keys delete or insert 40 character lines (or delete
+ one program line), which always start at the left margin and wrap
+ around the screen edge back to the left margin again. The right
+ margin is ignored in the process. Also, logical lines are always
+ three physical lines no matter how long or short you make those
+ lines.
+ The beep you hear when you are coming to the end of the logical
+ line works by screen position independent of the margins. Try
+ setting your left margin at 25 (POKE 82,25) and typing a few lines
+ of characters. Although you have just a few characters beyond
+ 60, the buzzer will still sound on the third line of text.
+
+
+ 84 54 ROWCRS
+
+ Current graphics or text screen cursor row, value ranging from
+ zero to 191 ($BF) depending on the current GRAPHICS mode
+ (maximum number of rows, minus one). This location, together
+ with location 85 below, defines the cursor location for the next
+ element to be read/written to the screen. Rows run horizontally,
+ left to right across the TV screen. Row zero is the topmost line;
+ row 192 is the maximum value for the bottom-most line.
+
+
+ 85,86 55,56 COLCRS
+
+ Current graphics or text mode cursor column; values range from
+ zero to 319 (high byte, for screen mode eight) depending on
+ current GRAPHICS mode (maximum numher of columns minus
+ one). Location 86 will always be zero in modes zero through
+ seven. Home position is 0,0 (upper left-hand corner). Columns
+ run vertically from the top to the bottom down the TV screen, the
+ leftmost column being number zero, the rightmost column the
+ maximum value in that mode. The cursor has a complete top to
+ bottom, left to right wraparound on the screen.
+
+ ROWCRS and COLCRS define the cursor location for the next
+ element to be read from or written to in the main screen segment
+ of the display. For the text window cursor, values in locations 656
+ to 667 ($290 to $29B) are exchanged with the current values in
+ locations 84 to 95 ($54 to $5F), and location 123 ($7B) is set to 255
+ ($FF) to indicate the swap has taken place. ROWCRS and
+ COLCRS are also used in the DRAW and FILL functions to
+ contain the values of the endpoint of the line being drawn. The
+ color of the line is kept in location 763 ($2FB). These values are
+ loaded into locations 96 to 98 ($60 to $62) so that ROWCRS and
+ COLCRS may be altered during the operation.
+
+ BASIC's LOCATE statement not only examines the screen, but
+ also moves the cursor one position to the right at the next PRINT
+ or PUT statement. It does this by updating locations 84 and 85,
+ above. You can override the cursor advance by saving the
+ contents of the screen before the LOCATE command, then
+ restoring them after the LOCATE. Try:
+
+ 100 REM: THE SCREEN MUST HAVE BEEN 0
+ PENED FOR READ OR READ/WRITE PREV
+ IOUSLY
+ 110 LOOK = PEEK(84): SEE = PEEK(85)
+ 120 LOCATE X,Y,THIS
+ 130 POKE 84, LOOK: POKE 65, SEE
+
+ Note that CHR$(253) is a non-printing character---the bell--
+ and doesn't affect the cursor position.
+
+ See COMPUTE!, August 198l, for an example of using COLCRS
+ for dynamic data restore and updating with the screen editor and
+ the IOCBs.
+
+
+ 87 57 DINDEX
+
+ Display mode/current screen mode. Labelled CRMODE by (*M).
+ DINDEX contains the number obtained from the low order four
+ bits of most recent open AUX1 byte. It can be used to fool the OS
+ into thinking you are in a different GRAPHICS mode by
+ POKEing DINDEX with a number from zero to 11. POKE with
+ seven after you have entered GRAPHICS mode eight, and it will
+ give you a split screen with mode seven on top and mode eight
+ below. However, in order to use both halves of the screen, you
+ will have to modify location 89 (below) to point to the area of the
+ screen you wish to DRAW in. (See Your Atan 400/800, pp. 280 -
+ 283.)
+ Watch for the cursor out-of-range errors (number 141) when
+ changing GRAPHICS modes in this manner and either PRINTing
+ or DRAWing to the new mode screen. POKE 87 with the BASIC
+ mode number, not the ANTIC mode number.
+ Did you know you can use PLOT and DRAWTO in GR.0? Try
+ this:
+
+ 10 GR.0
+ 20 PLOT 0,0: DRAWTO 10,10: DRAWTO 0
+ ,10
+ 30 DRAWTO 39,0: DRAWTO 20,23: DRAWT
+ O 0,20
+ 40 GOTO 40
+
+ You can also set the text window for PRINT and PLOT modes by
+ POKEing 87 with the graphics mode for the window. Then you
+ must POKE the address of the top left corner of the text window
+ into 88 and 89 ($58, $59). The screen mode of the text window is
+ stored at location 659 ($293).
+
+ You may have already discovered that you cannot call up the
+ GTIA modes from a direct command. Like the + 16 GRAPHICS
+ modes, they can only be called up during a program, and the
+ screen display will be reset to GR.0 on the first INPUT or PRINT
+ (not PRINT#6) statement executed in these modes.
+
+ Since this location only takes BASIC modes, you can't POKE it
+ with the other ANTIC modes such as "E", the famous "seven-and-
+ a-half" mode which offers higher resolution than seven and a four
+ color display (used in Datasoft's Micropainter program). If you're
+ not drawing to the screen, simply using it for display purposes,
+ you can always go into the Display List and change the
+ instructions there. But if you try to draw to the screen, you risk an
+ out-of-bounds error (error number 141).
+
+ See Creative Computing, March 1982, for an excellent look at
+ mode 7.5. The short subroutine below can be used to change the
+ Display List to GR.7.5:
+
+ 1000 GRAPHICS 8+16: DLIST = PEEK(560)
+ ) + PEEK(561) * 256:POKE DLIST +
+ 3,78
+ 1010 FOR CHANGE = DLIST + 6 TO DLIST
+ + 204: IF PEEK(CHANGE) = 15 THE
+ N POKE CHANGE,14
+ 1020 IF PEEK (CHANGE) = 79 THEN POKE
+ CHANGE,78: NEXT CHANGE
+ 1030 POKE 87,7:RETURN
+
+ DOWNLOAD MODE75.BAS
+
+ (Actually, 15 ($F) is the DL number for the maximum memory
+ mode; it also indicates modes eight through eleven. The DL's for
+ these modes are identical.) Fourteen is the ANTIC E mode;
+ GR.7.5 This program merely changes GR.8 to mode E in the
+ Display List. The value 79 is 64 + 15; mode eight screen with BIT
+ 6 set for a Load Memory Scan (LMS) instruction (see the DL
+ information in locations 560, 561; $230, $231). It does not check
+ for other DL bits.
+
+ You can also POKE 87 with the GTIA values (nine to eleven). To
+ get a pseudo-text window in GTIA modes, POKE the mode
+ number here and then POKE 623 with 64 for mode nine, 128 for
+ mode ten, and 192 for mode eleven, then POKE 703 with four, in
+ program mode. (In command mode, you will be returned to
+ GR.0.) You won't be able to read the text in the window, but you
+ will be able to write to it. However, to get a true text window,
+ you'll need to use a Display List Interrupt (see COMPUTE!,
+ September 1982). If you don't have the GTIA chip, it is still
+ possible to simulate those GRAPHICS modes by using DINDEX
+ with changes to the Display List Interrupt. See COMPUTE!, July
+ 1981, for an example of simulating GR.10.
+
+
+ 88,89 58,59 SAVMSC
+
+ The lowest address of the screen memory, corresponding to the
+ upper left corner of the screen (where the value at this address
+ will be displayed). The upper left corner of the text window is
+ stored at locations 660, 661 ($294, $295).
+ You can verify this for yourself by:
+
+ WINDOW = PEEK(88) + PEEK(89) * 256: POKE WINDOW,33
+
+ This will put the letter "A" in the upper left corner in GR.0, 1 and
+ 2. In other GRAPHICS modes, it will print a colored block or
+ bar. To see this effect, try:
+
+ 5 REM FIRST CLEAR SCREEN
+ 10 GRAPHICS Z: IF Z > 59 THEN END
+ 15 SCREEN = PEEK (88) + PEEK (89) *
+ 256
+ 20 FOR N = 0 TO 255: POKE SCREEN + N
+ ,N
+ 25 NEXT N: FOR N = 1 TO 300: NEXT N:
+ Z = Z + 1
+ 30 GOTO 10
+
+ DOWNLOAD SAVEMSC1.BAS
+
+ You will notice that you get the Atari internal character code, not
+ the ATASCII code. See also locations 560, 561 ($230, $231) and
+ 57344 ($E000).
+
+ How do you find the entire screen RAM? First, look at the chart
+ below and find your GRAPHICS mode. Then you multiply the
+ number of rows-per-screen type by the number of bytes-per-line.
+ This will tell you how many bytes each screen uses. Add this
+ value, minus one, to the address specified by SAVMSC.
+ However, if you subtract MEMTOP (locations 741, 742; $2E5,
+ $2E6) from RAMTOP (106; $6A * 256 for the number of bytes),
+ you will see that there is more memory reserved than just the
+ screen area. The extra is taken up by the display list or the text
+ window, or is simply not used (see the second chart below).
+
+ Mode 0 1 2 3 4 5 6 7 8 9-12
+
+ Rows
+ Full 24 24 12 24 48 48 96 96 192 192
+ Split -- 20 10 20 40 40 80 80 160 --
+
+ Bytes per
+ Line 40 20 20 10 10 20 20 40 40 40
+
+ Columns
+ per Line 40 20 20 40 80 80 160 160 320 80
+
+ Memory (1) 993 513 261 273 537 1017 2025 3945 7900 7900
+
+ Memory (2)
+ Full 992 672 420 432 696 1176 2184 4200 8138 8138
+ Split -- 674 424 434 694 1174 2174 4190 8112 --
+
+ (1) According to the Atari BASIC Reference Manual, p.45; OS
+ User's Manual, p.172, and Your Atari 400/800, p.360.
+
+ (2) According to Your Atari 400/800, p.274, and Atari Microsoft
+ Basic Manual, p.69. This is also the value you get when you
+ subtract MEMTOP from RAMTOP (see above).
+
+ For example, to POKE the entire screen RAM in GR.4, you
+ would find the start address of the screen (PEEK(88) + PEEK(89)
+ * 256), then use a FOR-NEXT loop to POKE all the locations
+ specified above:
+
+ 10 GRAPHICS 4: SCRN = PEEK(88) + PE
+ EK(89) * 256
+ 20 FOR LOOP = SCRN to SCRN + 479: R
+ EM 48 ROWS * 10 BYTES - 1
+ 30 POKE LOOP,35: NEXT LOOP
+
+ DOWNLOAD SAVEMSC2.BAS
+
+ Why the minus one in the calculation? The first byte of the screen
+ is the first byte in the loop. If we add the total size, we will go one
+ byte past the end of the soreen, so we subtract one from the total.
+ Here's how to arrive at the value for the total amount ot memory
+ located for screen use, display list and Text window:
+
+ Total memory allocation for the screen
+
+ Screen display Display List
+ -----------------------------------------------------------
+ Text unused bytes screen unused used
+ GR window always cond. use bytes bytes Total
+ -----------------------------------------------------------
+ 0 ... none none 960 none 32 992
+ 1 160 none 80 400 none 34 674
+ 2 160 none 40 200 none 24 424
+ 3 160 none 40 200 none 34 434
+ 4 160 none 80 400 none 54 694
+ 5 160 none 160 800 none 54 1174
+ 6 160 none 320 1600 none 94 2174
+ 7 160 none 640 3200 96 94 4190
+ 8 160 16 1280 6400 80 176 8112
+
+ The number of bytes from RAMTOP (location 106; $6A) is counted
+ from the left text window column towards the total column.
+ MEMTOP (741, 742; $2E5, $2E6) points to one byte below
+ RAMTOP * 256 minus the number of bytes in the total column. If
+ 16 is added to the GRAPHICS mode (no text window), then the
+ conditional unused bytes are added to the total. Then the bytes
+ normally added for the text window become unused, and the
+ Display List expands slightly. (See COMPUTE!, September 1981.)
+
+ When you normally PRINT CHR$(125) (clear screen), Atari sends
+ zeroes to the memory starting at locations 88 and 89. It continues to
+ do this until it reaches one byte less than the contents of RAMTQP
+ (location 106; $6A). Here is a potential source of conflict with your
+ program, however: CHR$(125)--CLEAR SCREEN--and any
+ GRAPHICS command actually continue to clear the first 64 ($40)
+ bytes above RAMTOP!
+
+ It would have no effect on BASIC since BASIC is a ROM
+ cartridge. The OS Source Listing seems to indicate that it ends at
+ RAMTOP, but Atari assumed that there would be nothing after
+ RAMTOP, so no checks were provided. Don't reserve any data
+ within 64 bytes of RAMTOP or else it will be eaten by the CLEAR
+ SCREEN routine, or avoid using a CLEAR SCREEN or a
+ GRAPHICS command. Scrolling the text window also clears 800
+ bytes of memory above RAMTOP.
+
+ You can use this to clear other areas of memory by POKEing the
+ LSB and MSB of the area to be cleared into these locations. Your
+ routine should always end on a $FF boundary (RAMTOP indicates
+ the number of pages). Remember to POKE back the proper screen
+ locations or use a GRAPHICS command immediately after doing
+ so to set the screen right. Try this:
+
+ 10 BOTTOM = 30000: TOP = 36863: REM
+ LOWEST AND HIGHEST ADDRESS TO CLEA
+ R = $7530 & $8FFF
+ 20 RAMTOP = PEEK(106): POKE 106, INT
+ (TOP + 1 / 256)
+ 30 TEST = INT(BOTTOM / 256): POKE89,
+ TEST
+ 40 POKE 88. BOTTOM - 256 * TEST
+ 50 PRINT CHR$(125): POKE 106, RAMTOP
+ 60 GRAPHICS 0
+
+ DOWNLOAD SAVEMSC3.BAS
+
+ This will clear the specified memory area and update the address
+ of screen memory. If you don't specify TOP, the CLEAR SCREEN
+ will continue merrily cleaning out memory and, most likely, will
+ cause your program to crash. Use it with caution.
+ Here's a means to SAVE your current GR.7 screen display to disk
+ using BASIC:
+
+ 1000 SCREEN = PEEK(88) + PEEK(89) *
+ 256
+ 1010 OPEN #2,8,0,"D:picturename"
+ 1020 MODE = PEEK(87): PUT #2, MODE:
+ REM SAVE GR. MODE
+ 1030 FOR SCN = 0 TO 4: COL PEEK(70
+ 8 + SCN): PUT #2,COL: NEXT SCN:
+ REM SAVE COLOR REGISTERS
+ 1040 FOR TV = SCREEN TO SCREEN + 319
+ 9:BYTE = PEEK(TV): PUT #2, BYTE:
+ NEXT TV: CLOSE #2
+
+ DOWNLOAD SAVEMSC4.BAS
+
+ To use this with other screen modes, you will have to change the
+ value of 3199 in line 1040 to suit your screen RAM (see the chart
+ above). For example, GR.7 + 16 would require 3839 bytes (3840
+ minus one). You can use the same routine with cassette by using
+ device C:. To retrieve your picture, you use GET#2 and POKE
+ commands. You will, however, find both routines very slow. Using
+ THE CIO routine at 58454 ($E456) and the IOCBs, try this machine
+ language save routine:
+
+ 10 DIM ML$(10): B$(10): GR.8+16
+ 20 B$ = "your picture name":Q = PEEK
+ (559)
+ 30 FOR N = 1 TO 6: READ BYTE: ML$(N,
+ N) = CHR$(BYTE): NEXT N
+ 35 DATA 104,162,16,76,86,228
+ 36 REM PLA,LDX,$10,JMP $E456
+ 40 OPEN #1,4,0,B$
+ 50 POKE 849,1: POKE 850,7: POKE 852,
+ PEEK(88): POKE 853,PEEK(89): POKE
+ 856,70: POKE 857,30: POKE 858,4
+ 55 REM THESE POKES SET UP THE IOCB
+ 60 POKE 559,0: REM TURN OFF THE SCRE
+ EN TO SPEED THINGS UP
+ 70 X = USR(ADR(ML$)): CLOSE #1
+ 80 POKE 559,Q: REM TURN IT BACK ON A
+ GAIN
+
+ DOWNLOAD SAVEMSC5.BAS
+
+ Note that there is no provision to SAVE the color registers in this
+ program, so I suggest you have them SAVEd after you have
+ SAVEd the picture. It will make it easier to retrieve them if they are
+ at the end of the file. You will have to make suitable adjustments
+ when SAVEing a picture in other than GR.8 + 16 -- such as
+ changing the total amount of screen memory to be SAVEd, POKEd
+ into 856 and 857. Also, you will need a line such as 1000 GOTO
+ 1000 to keep a GTIA or + 16 mode screen intact. See the Atari
+ column in InfoAge Magazine, July 1982, for more on this idea. See
+ location 54277 ($D405) for some ideas on scrolling the screen
+ RAM.
+
+ ------------------------------------------------------------------------
+ A SHORT DIGRESSION
+ There are two techniques used in this hook for calling a machine
+ language program from BASIC with the USR command. One method
+ is to POKE the values into a specific address -- say, page six -- and
+ use the starting address for the USR call, such as X = USR(1536). For
+ an example of this technique, see location 632 ($278).
+
+ The other technique, used above, is to make a string (ML$) out of the
+ routine by assigning to the elements of the string the decimal
+ equivalents of the machine language code by using a FOR-NEXT and
+ READ-DATA loop. To call this routine, you would use X =
+ USR(ADR(ML$)). This tells the Atari to call the machine language
+ routine located at the address where ML$ is stored. This address will
+ change with program size and memory use. The string method won't
+ be overwritten by another routine or data since it floats around safely
+ in memory. The address of the string itself is stored by the string/array
+ table at location 140 ($8C).
+ ------------------------------------------------------------------------
+
+
+ 90 5A OLDROW
+
+ Previous graphics cursor row. Updated from location 84 ($54)
+ before every operation. Used to determine the starting row for
+ the DRAWTO and XIO 18 (FILL command).
+
+
+ 91,92 5B,5C OLDCOL
+
+ Previous graphics cursor column. Updated from locations 85 and
+ 86 ($55, $56) before every operation. These locations are used by
+ the DRAWTO and XIO 18 (FILL) commands to determine the
+ starting column of the DRAW or FILL
+
+
+ 93 5D OLDCHR
+
+ Retains the value of the character under the cursor used to
+ restore that character when the cursor moves
+
+
+ 94,95 5E,5F OLDADR
+
+ Retains the memory location of the current cursor location. Used
+ with location 93 (above) to restore the character under the cursor
+ when the cursor moves
+
+
+ 96 60 NEWROW
+
+ Point (row) to which DRAWTO and XIO 18 (FILL) will go.
+
+
+ 97,98 61,62 NEWCOL
+
+ Point (column) to which DRAWTO and XIO 18 (FILL) will go.
+ NEWROW and NEWCOL are initialized to the values in
+ ROWCRS and COLCRS (84 to 86; $54 to $56) above, which
+ represent the destination end point of the DRAW and FILL
+ functions. This is done so that ROWCRS and COLCRS can be
+ altered during these routines.
+
+
+ 99 63 LOGCOL
+
+ Position of the cursor at the column in a logical line. A logical
+ line can contain up to three physical lines, so LOGCOL can
+ range between zero and 119. Used by the display handler.
+
+
+ 100,101 64,65 ADRESS
+
+ Temporary storage used by the display handler for the Display
+ List address, line buffer (583 to 622; $247 to $26E), new MEMTOP
+ value after DL entry, row column address, DMASK value, data to
+ the right of cursor, scroll, delete, the clear screen routine and for
+ the screen address memory (locations 88, 89; $58, $59).
+
+
+ 102,103 66,67 MLTTMP
+
+ Also called OPNTMP and TOADR; first byte used in OPEN as
+ temporary storage. Also used by the display handler as
+ temporary storage.
+
+
+ 104,105 68,69 SAVADR
+
+ Also called FRMADR. Temporary storage, used with ADRESS
+ above for the data under the cursor and in moving line data on
+ the screen.
+
+
+ 106 6A RAMTOP
+
+ RAM size, defined by powerup as passed from TRAMSZ (location
+ 6), given in the total number of available pages (one page equals
+ 256 bytes, so PEEK(106) * 256 will tell you where the Atari thinks
+ the last usable address --byte-- of RAM is). MEMIOP (741,
+ 742; $2E5. $2E6) may not extend below this value. In a 48K Atari,
+ RAMTOP is initialized to 160 ($A0), which points to location
+ 40960 ($A000). The user's highest address will be one byte less
+ than this value.
+
+ This is initially the same value as in location 740. PEEK(740) / 4 or
+ PEEK(106) / 4 gives the number of 1K blocks. You can fool the
+ computer into thinking you have less memory than you actually
+ have, thus reserving a relatively safe area for data (for your new
+ character set or player/missile characters, for example) or
+ machine language subroutines by:
+
+ POKE(106), PEEK(106) - # of pages you want to reserve.
+
+ The value here is the number of memory pages (256-byte blocks)
+ present. This is useful to know when changing GR.7 and GR.8
+ screen RAM. If you are reserving memory for PM graphics,
+ POKE 54279, PEEK(106) - # of pages you are reserving before
+ you actually POKE 106 with that value. To test to see if you have
+ exceeded your memory by reserving too much memory space,
+ you can use:
+
+ 10 SIZE = (PEEK(106) - # of pages)
+ * 256
+ 20 IF SIZE < = PEEK(144) + PEEK(145
+ ) * 256 THEN PRINT "TOO MUCH MEMOR
+ Y USED"
+
+ If you move RAMTOP to reserve memory, always issue a
+ GRAPHICS command (even issuing one to the same GRAPHICS
+ mode you are in will work) immediately so that the display list
+ and data are moved beneath the new RAMTOP.
+
+ You should note that a GRAPHICS command and a CLEAR
+ command (or PRINT CHR$(125)) actually clear the first 64 bytes
+ above RAMTOP (see location 88; $58 for further discussion).
+ Scrolling the text window of a GRAPHICS mode clears up to 800
+ ($320) bytes above RAMTOP (the text window scroll actually
+ scrolls an entire GR.0 screen-worth of data, so the unseen 20
+ lines * 40 bytes equals 800 bytes). PM graphics may be safe
+ (unless you scroll the text window) since the first 384 or 768 bytes
+ (double or single line resolution, respectively) are unused.
+ However, you should take both of these effects into account when
+ writing your programs.
+ To discover the exact end of memory, use this routine (it's a tad
+ slow):
+
+ 10 RAMTOP = 106: TOP = PEEK(RAMTOP)
+ 20 BYTE = TOP * 256: TEST = 255 - PE
+ EK(BYTE): POKE BYTE,TEST
+ 30 IF PEEK(BYTE) = TEST THEN TOP = T
+ OP +1: POKE BYTE, 255 - TEST
+ 40 GOTO 20
+ 50 PRINT "MEMORY ENDS AT "; BYTE
+
+ One caution: BASIC cannot always handle setting up a display
+ list and display memory for GRAPHICS 7 and GRAPHICS 8
+ when you modify this location by less than 4K (16 pages; 4096
+ bytes). Some bizarre results may occur if you use PEEK(106) - 8
+ in these modes, for example. Use a minimum of 4K (PEEK(106) -
+ 16) to avoid trouble. This may explain why some people have
+ difficulties with player/missile graphics in the hi-res (high
+ resolution; GR.7 and GR.8) modes. See location 54279 ($D407).
+
+ Another alternative to reserving memory in high RAM is to save
+ an area below MEMLO, location 743 ($2E7: below your BASIC
+ program). See also MEMTOP, locations 741, 742 ($2E5, $2E6).
+
+
+ 107 6B BUFCNT
+
+ Buffer count: the screen editor current logical line size counter.
+
+
+ 108,109 6C,6D BUFSTR
+
+ Editor low byte (AM). Display editor GETCH routine pointer
+ (location 62867 for entry; $F593). Temporary storage; returns the
+ character pointed to by BUFCNT above.
+
+
+ 110 6E BITMSK
+
+ Bit mask used in bit mapping routines by the OS display handler
+ at locations 64235 to 64305 ($FAEB to $FB31). Also used as a
+ display handler temporary storage register.
+
+
+ 111 6F SHFAMT
+
+ Pixel justification: the amount to shift the right justified pixel data
+ on output or the amount to shift the input data to right justify it.
+ Prior to the justification process, this value is always the same as
+ that in 672 ($2A0).
+
+
+ 112,113 70,71 ROWAC
+
+ ROWAC and COLAC (below) are both working accumulators for
+ the control of row and column point plotting and the increment
+ and decrement functions.
+
+
+ 114,115 72,73 COLAC
+
+ Controls column point plotting.
+
+
+ 116,117 74,75 ENDPT
+
+ End point of the line to be drawn. Contains the larger value of
+ either DELTAR or DELTAC (locations 118 and 119, below) to be
+ used in conjunction with ROWAC/COLAC (locations 112 and
+ 114, above) to control the plotting of line points.
+
+
+ 118 76 DELTAR
+
+ Delta row; contains the absolute value of NEWBOW (location 96;
+ $60) minus ROWCRS (location 84; $54).
+
+
+ 119,120 77,78 DELTAC
+
+ Delta column; contains the absolute value of NEWCOL (location
+ 97; $61) minus the value in COLCRS (location 85; $55). These
+ delta register values, along with locations 121 and 122 below, are
+ used to define the slope of the line to be drawn.
+
+
+ 121 79 ROWINC
+
+ The row increment or decrement value (plus or minus one).
+
+
+ 122 7A COLINC
+
+ The column increment or decrement value (plus or minus one).
+ ROWINC and COLINC control the direction of the line drawing
+ routine. The values represent the signs derived from the value in
+ NEWROW (location 96; $60) minus the value in ROWCRS
+ (location 84; $54) and the value in NEWCOL (locations 97, 98;
+ $61, $62) minus the value in COLCRS (locations 85, 86; $55,
+ $56).
+
+
+ 123 7B SWPFLG
+
+ Split-screen cursor control. Equal to 255 ($FF) if the text window
+ RAM and regular RAM are swapped; otherwise, it is equal to
+ zero. In split-screen modes, the graphics cursor data and the text
+ window data are frequently swapped in order to get the values
+ associated with the area being accessed into the OS data base
+ locations 84 to 95 ($54 to $5F). SWPFLG helps to keep track of
+ which data set is in these locations.
+
+
+ 124 7C HOLDCH
+
+ A character value is moved here before the control and shift logic
+ are processed for it.
+
+
+ 125 7D INSDAT
+
+ Temporary storage byte used by the display handler for the
+ character under the cursor and end of line detection.
+
+
+ 126,127 7E,7F COUNTR
+
+ Starts out containing the larger value of either DELTAR (location
+ 118; $76) or DELTAC (location 119; $77). This is the number of
+ iterations required to draw a line. As each point on a line is
+ drawn, this value is decremented. When the byte equals zero, the
+ line is complete (drawn).
+
+ ---------------------------------------------------------------------
+
+ User and/or BASIC page zero RAM begins here. Locations 128 to 145
+ ($80 to $91) are for BASIC program pointers; 146 to 202 ($92 to $CA)
+ are for miscellaneous BASIC RAM; 203 to 209 ($CB to $D1) are
+ unused by BASIC, and 210 to 255 ($D2 to $FF) are the floating point
+ routine work area. The Assembler Editor cartridge uses locations 128
+ to 176 ($80 to $B0) for its page zero RAM. Since the OS doesn't use this
+ area, you are free to use it in any non-BASIC or non-cartridge
+ environment. If you are using another language such as FORTH,
+ check that program's memory map to see if any conflict will occur.
+ See COMPUTE!'s First Book of Atari, pages 26 to 53, for a discussion
+ of Atari BASIC structure, especially that using locations 130 to 137
+ ($82 to $89). Included in the tutorials are a memory analysis, a line
+ dump, and a renumber utility. See also De Re Atari, BYTE, February
+ 1982, and the locations for the BASIC ROM 40960 to 49151 ($A000 to
+ $BFFF).
+
+
+ 128,129 80,81 LOMEM
+
+ Pointer to BASIC's low memory (at the high end of OS RAM
+ space). The first 256 bytes of the memory pointed to are the token
+ output buffer, which is used by BASIC to convert BASIC
+ statements into numeric representation (tokens; see locations
+ 136, 137; $88, $89). This value is loaded from MEMLO (locations
+ 743, 744; $2E7, $2E8) on initialization or the execution of a NEW
+ command (not on RESET!). Remember to update this value when
+ changing MEMLO to reserve space for drivers or buffers.
+ When a BASIC SAVE is made, two blocks of information are
+ written: the first block is the seven pointers from LOMEM to
+ STARP (128 to 141; $80 to $8D). The value of LOMEM is
+ subtracted from each of these two-byte pointers in the process, so
+ the first two bytes written will both be zero. The second block
+ contains the following: the variable name table, the variable
+ value table, the tokenized program, and the immediate mode
+ line.
+ When a BASIC LOAD is made, BASIC adds the value at MEMLO
+ (743, 744; $2E7, $2E8) to each of the two-byte pointers SAVEd as
+ above. The pointers are placed back in page zero, and the values
+ of RUNSTK (142, 143; $8E, $8F) and MEMTOP (144, 145; $90,
+ $91) are set to the value in STARP. Then 256 bytes are reserved
+ above the value in MEMLO for the token output buffer, and the
+ program is read in immediately following this buffer.
+ When you don't have DOS or any other application program
+ using low memory loaded, LOMEM points to 1792 ($700). When
+ DOS 2.0 is present, it points to 7420 ($1CFC). When you change
+ your drive and data buffer defaults (see 1801, 1802; $709, $70A),
+ you will raise or lower this figure by 128 bytes for each buffer
+ added or deleted, respectively. When you boot up the RS-232
+ handler, add another 1728 ($6C0) bytes used.
+ LOMEM is also called ARGOPS by BASIC when used in
+ expression evaluation. When BASIC encounters any kind of
+ expression, it puts the immediate results into a stack. ARGOPS
+ points to the same 256 byte area; for this operation it is reserved
+ for both the argument and operator stack. It is also called
+ OUTBUFF for another operation, pointing to the same 256 byte
+ buffer as ARGOPS points to. Used by BASIC when checking a
+ line for syntax and converting it to tokens. This buffer
+ temporarily stores the tokens before moving them to the
+ program.
+
+
+ 130,131 82,83 VNTP
+
+ Beginning address of the variable name table. Variable names
+ are stored in the order input into your program, in ATASCII
+ format. You can have up to 128 variable names. These are stored
+ as tokens representing the variable number in the tokenized
+ BASIC program, numbered from 128 to 255 ($80 to $FF).
+
+ The table continues to store variable names, even those no longer
+ used in your program and those used in direct mode entry. It is
+ not cleared by SAVEing your program. LOADing a new program
+ replaces the current VNT with the one it retrieves from the file.
+ You must LIST the program to tape or disk to save your program
+ without these unwanted variables from the table. LIST does not
+ SAVE the variable name or variable value tables with your
+ program. It stores the program in ATASCII, not tokenized form,
+ and requires an ENTER command to retrieve it. You would use a
+ NEW statement to clear the VNT in memory once you have
+ LISTed your program.
+
+ Each variable name is stored in the order it was entered, not the
+ ATASCII order. With numeric (scalar) variables, the MSB is set
+ on the last character in a name. With string variables, the last
+ character is a "$" with the MSB (BIT 7) set. With array variables,
+ the last character is a "(" with the MSB set. Setting the MSB turns
+ the character into its inverse representation so it can be easily
+ recognized.
+ You can use variable names for GOSUB and GOTO routines,
+ such as:
+
+ 10 CALCULATE = 1000
+ .
+ .
+ 100 GOSUB CALCULATE
+
+ This can save a lot of bytes for a frequently called routine. But
+ remember, each variable used for a GOSUB or GOTO address
+ uses one of the 128 possible variable names. A disadvantage of
+ using variable names for GOTO and GOSUB references is when
+ you try to use a line renumbering program. Line renumbering
+ programs will not change references to lines with variable
+ names, only to lines with numbered references.
+
+ Here's a small routine you can add to the start of your BASIC
+ program (or the end if you change the line numbers) to print out
+ the variable names used in your program. You call it up with a
+ GOTO statement in direct mode:
+
+ 1 POKE 1664, PEEK(130): POKE 1665,
+ PEEK (131)
+ 2 IF PEEK(1664) = PEEK(132) THEN IF
+ PEEK(1665) = PEEK(133) THEN STOP
+ 3 PRINT CHR$(PEEK(PEEK(1664) + PEEK
+ (1665) * 256)));
+ 4 IF PEEK(PEEK(1664) + PEEK(1665) *
+ 256)) > 127 THEN PRINT"";
+ 5 IF PEEK(1664) = 255 THEN POKE 166
+ 4, 0: POKE 1665, PEEK(1665) + 1: GO
+ TO 2
+ 6 POKE 1664, PEEK(1664) + 1: GOTO 2
+
+ DOWNLOAD VNTP.BAS
+
+ See COMPUTE!, October 1981.
+
+
+ 132,133 84,85 VNTD
+
+ Pointer to the ending address of the variable name table plus one
+ byte. When fewer than 128 variables are present, it points to a
+ dummy zero byte. When 128 variables are present, this points to
+ the last byte of the last variable name, plus one.
+
+ It is often useful to be able to list your program variables; using
+ locations 130 to 133, you can do that by:
+
+ 10 VARI = PEEK(130) + PEEK(131) * 2
+ 56 :REM This gives you the start o
+ f the table.
+ 20 FOR VARI = VARI TO PEEK(132) + P
+ EEK(133) * 256 - 1: PRINT CHR$(PEE
+ K(VARI) - 128 * PEEK(VARI > 127));
+ CHR$(27 + 128 * PEEK(VARI) > 127)
+ );:NEXT VARI
+ 25 REM this finds the end of the va
+ ri able name table (remember table
+ is end + 1). then PRINTs ASCII cha
+ racters < 128
+ 30 NUM = 0: FOR VARI = PEEK(130) +
+ PEEK(313) * 256 TO PEEK(132) + PEE
+ K(131) * 256 - 1:NUM = NUM + (PEEK
+ (VARI) < 127):NEXT VARI: PRINT NU
+ M; "Variables in use"
+
+ DOWNLOAD VNTD1.BAS
+
+ Or try this, for a possibly less opaque example of the same
+ routine:
+
+ 1000 NUM = 0: FOR LOOP = PEEK (130) +
+ PEEK(131) * 256 TO PEEK(132) +
+ PEEK(133) * 256 - 1
+ 1010 IF PEEK(LOOP) < 128 THEN PRINT
+ CHR$(PEEK(LOOP));: GOTO 1030
+ 1020 PRINT CHR$(PEEK(LOOP) - 128): N
+ UM - NUM + 1
+ 1030 NEXT LOOP: PRINT; PRINT NUM; "
+ VARIABLES IN USE": END
+
+ DOWNLOAD VNTD2.BAS
+
+
+ 134,135 86,87 VVTP
+
+ Address for the variable value table. Eight bytes are allocated for
+ each variable in the name table as follows:
+
+ Byte 1 2 3 4 5 6 7 8
+ Variable
+ --------------------------------------------------------------
+ Scalar 00 var # six byte BCD constant
+ Array;DIMed 65 var # offset first second
+ unDIMed 64 from DIM + 1 DIM + 1
+ STARP
+ String;DIMed 129 var # offset length DIM
+ unDIMed 128 from
+ STARP
+
+ In scalar (undimensioned numeric) variables, bytes three to eight
+ are the FP number; byte three is the exponent; byte four contains
+ the least significant two decimal digits, and byte eight contains
+ the most significant two decimal digits.
+ In array variables, bytes five and six contain the size plus one of
+ the first dimension of the array (DIM + 1; LSB/MSB), and bytes
+ seven and eight contain the size plus one of the second dimension
+ (the second DIM + 1; LSB/MSB).
+ In string variables, bytes five and six contain the current length
+ of the variable (LSB MSB), and bytes seven and eight contain the
+ actual dimension (up to 32767). There is an undocumented
+ BASIC statement, "COM," mentioned only in the BASIC
+ Reference Manual's index, which executes exactly the same as
+ the "DIM" statement (see Your Atari 400/800, p.346). Originally,
+ it was to be used to implement "common" variables.
+
+ In all cases, the first byte is always one of the number listed on the
+ chart above (you will seldom, if ever, see the undimensioned
+ values in a program). This number defines what type of variable
+ information will follow. The next byte, var # (variable number), is
+ in the range from zero to 127. Offset is the number of bytes from
+ the beginning of STARP at locations 140 and 141 ($8C, $8D).
+ Since each variable is assigned eight bytes, you could find the
+ values for each variable by:
+
+ 1000 VVTP = PEEK(134) + PEEK(135) *
+ 256: INPUT VAR: REM VARIABLE NUM
+ BER
+ 1010 FOR LOOP = 0 TO 7: PRINT PEEK(V
+ VTP + LOOP + 8 * VAR): NEXT LOOP
+
+ where VAR is the variable number from zero to 127.
+ If you wish to assign the same value to every element in a DIMed
+ string variable use this simple technique:
+
+ 10 DIM TEST$(100)
+ 20 TEST$ = "*": REM or use TEST$(1)
+ 30 TEST$(100) = TEST$
+ 40 TEST$(2) = TEST$: PRINT TEST$
+
+ By assigning the first, last and second variables in the array in
+ that order, your Atari will then assign the same value to the rest of
+ the array. Make sure you make the second and last elements
+ equal to the string, not the character value (i.e don't use
+ TEXT$(2) = "*").
+ See De Re Atari for an example of SAVEing the six-byte BCD
+ numbers to a disk file -- very useful when dealing with fixed
+ record lengths.
+
+
+ 136,137 88,89 STMTAB
+
+ The address of the statement table (which is the beginning of the
+ user's BASIC program), containing all the tokenized lines of
+ code plus the immediate mode lines entered by the user. Line
+ numbers are stored as two-byte integers, and immediate mode
+ lines are given the default value of line 32768 ($8000). The first
+ two bytes of a tokenized line are the line number, and the next is
+ a dummy byte reserved for the byte count (or offset) from the start
+ of this line to the start of the next line.
+
+ Following that is another count byte for the start of this line to the
+ start of the next statement. These count values are set only when
+ tokenization for the line and statement are complete.
+ Tokenization takes place in a 256 byte ($100) buffer that resides at
+ the end of the reserved OS RAM (pointed to by locations 128,
+ 129; $80, $81).
+ To see the starting address of your BASIC line numbers use this
+ routine:
+
+ 10 STMTAB = PEEK(136) + PEEK(137)*2
+ 56
+ 20 NUM = PEEK(STMTAB) + PEEK (STMTAB
+ +1)*256
+ 30 IF NUM = 32768 THEN END
+ 40 PRINT"LINE NUMBER: ";NUM;" ADDRE
+ SS: ";STMTAB
+ 50 STMTAB = STMTAB + PEEK(STMTAB+2)
+ 60 GOTO 20
+
+ The August 1982 issue of ANTIC provided a useful program to
+ delete a range of BASIC line numbers. The routine can be
+ appended to your program and even be used to delete itself.
+
+
+ 138,139 8A,8B STMCUR
+
+ Current BASIC statement pointer, used to access the tokens
+ being currently processed within a line of the statement table.
+ When BASIC is awaiting input, this pointer is set to the
+ beginning of the immediate mode (line 32768).
+
+ Using the address of the variable name table, the length, and the
+ current statement (locations 130 to 133, 138, 139), here is a way to
+ protect your programs from being LISTed or LOADed: they can
+ only be RUN! Remember, that restricts you too, so make sure you
+ have SAVEd an unchanqed version before you do this:
+
+ 32000 FOR VARI = PEEK(130) + PEEK(1
+ 31) * 256 TO PEEK(132) + PEEK(1
+ 33) * 256:POKE VARI,155:NEXT VA
+ RI
+ 32100 POKE PEEK(138) + PEEK(139) *
+ 256 + 2,0: SAVE "D:filename": N
+ EW
+
+ This will cause all variable names to be replaced with a RETURN
+ character. Other characters may be used: simply change 155 for
+ the appropriate ATASCII code for the character desired. Make
+ sure that these are the last two lines of your program and that
+ NEW is the last statement. CLOAD will not work, but a filename
+ with C: will.
+
+
+ 140,141 8C,8D STARP
+
+ The address for the string and array table and a pointer to the end
+ of your BASIC program. Arrays are stored as six-byte binary
+ coded decimal numbers (BCD) while string characters use one
+ bye each. The address of the strings in the table are the same as
+ those returned by the BASIC ADR function. Always use this
+ function under program control, since the addresses in the table
+ change according to your program size. Try:
+
+ 10 DIM A$(10),B$(10)
+ 20 A$ = "*": A$(10) = A$: A$(2) = A
+ $
+ 30 B$ = "&": B$(10) = B$: B$(2) = B
+ $
+ 40 PRINT ADR(A$), ADR(B$)
+ 50 PRINT PEEK(140) + PEEK(141) * 25
+ 6: REM ADDRESS OF A$
+ 60 PRINT PEEK(140) + PEEK(141) * 25
+ 6 + 10: REM ADRESS OF A$ + 10 BYTE
+ S = ADDRESS OF B$
+
+ This table is expanded as each dimension is processed by
+ BASIC, reducing available memory. A ten-element numeric
+ array will require 60 bytes for storage. An array variable such as
+ DIM A(100) will cost the program 600 bytes (100 * six per
+ dimensioned number equals 600). On the other hand, a string
+ array such as DIM A$(100) will only cost 100 bytes! It would save
+ a lot of memory to write your arrays as strings and retrieve the
+ array values using the VAL statement. For example:
+
+ 10 DIM A$(10): A$ = "1234567890"
+ 20 PRINT VAL(A$)
+ 30 PRINT VAL(A$(4,4))
+ 40 PRINT VAL(A$(3,3))+VAL(A$(8,9))
+
+ See COMPUTE!, June 1982, for a discussion of STARP and
+ VVTP. See De Re Atari for a means to SAVE the string/array area
+ with your program.
+
+
+ 142,143 8E,8F RUNSTK
+
+ Address of the runtime stack which holds the GOSUB entries
+ (four bytes each) and the FOR-NEXT entries (16 bytes each). The
+ POP command in BASIC affects this stack, pulling entries off it
+ one at a time for each POP executed. The stack expands and
+ contracts as necessary while the program is running.
+
+ Each GOSUB entry consists of four bytes in this order: a zero to
+ indicate a GOSUB, a two-byte integer line number on which the
+ call occurred, and an offset into that line so the RETURN can
+ come back and execute the next statement.
+
+ Each FOR-NEXT entry contains 16 bytes in this order: first, the
+ limit the counter variable can reach; second, the step or counter
+ increment. These two are allocated six bytes each in BCD format
+ (12 bytes total). The 13th byte is the counter variable number with
+ the MSB set; the 14th and 15th are the line number and the 16th is
+ the line offset to the FOR statement.
+ RUNSTK is also called ENDSTAR; it is used by BASIC to point to
+ the end of the string/array space pointed to by STARR above.
+
+
+ 144,145 90,91 MEMTOP
+
+ Pointer to the top of BASIC memory, the end of the space the
+ program takes up. There may still be space between this address
+ and the display list, the size of which may be retrieved by the
+ FRE(0) command (which actually subtracts the MEMTOP value
+ that is at locations 741 and 742; $2E5, $2E6). Not to be confused
+ with locations 741 and 742, which have the same name but are an
+ OS variable. MEMTOP is also called TOPSTK; it points to the top
+ of the stack space pointed to by RUNSTK above.
+
+ When reserving memory using location 106 ($6A) and MEMTOP,
+ here's a short error-trapping routine you can add:
+
+ 10 SIZE = (PEEK(106) - # of pages yo
+ u are reserving) * 256
+ 20 IF SIZE < = PEEK(144) + PEEK(145
+ ) * 256 THEN PRINT " PROGRAM TOO L
+ ARGE": END
+
+ Locations 146 to 202 ($92 to $CA) are reserved for use by the 8K
+ BASIC ROM.
+ Locations 176 to 207 ($B0 to $CF) are reserved by the Assembler
+ Editor cartridge for the user's page zero use. The Assembler debug
+ routine also reserves 30 bytes in page zero, scattered from location 164
+ ($A4) to 255 ($FF), but they cannot be used outside the debug process.
+ (See De Re Atari, Rev. 1, Appendix A for a list of these available
+ bytes.)
+
+
+ 186,187 BA,BB STOPLN
+
+ The line where a program was stopped either due to an error or
+ the use of the BREAK key, or a STOP or a TRAP statement
+ occurred. You can use PEEK (186) + PEEK (187) * 256 in a
+ GOTO or GOSUB statement.
+
+
+ 195 C3 ERRSAVE
+
+ The number of the error code that caused the stop or the TRAP.
+ You can use this location in a program in a line such as:
+
+ 10 IF PEEK(195) <> 144 THEN 100
+
+
+ 201 C9 PTABW
+
+ This location specifies the number of columns between TAB
+ stops. The first tab will beat PEEK(201). The default is ten. This is
+ the value between items separated in a PRINT statement by com-
+ mas -- such as PRINT AS, LOOP, C(12) -- not by the TAB key
+ spacing.
+ The minimum number of spaces between TABS is three. If you
+ POKE 201,2, it will be treated as four spaces, and POKE 201,1 is
+ treated as three spaces. POKE 201,0 will cause the system to
+ hang when it encounters a PRINT statement with commas. To
+ change the TAB key settings, see TABMAP (locations 675 to 689;
+ $2A3 - $2B1). PTABW is not reset to the default value by pressing
+ RESET or changing GRAPHICS modes (unlike TABMAP).
+ PTABW works in all GRAPHICS modes, not merely in text
+ modes. The size of the spaces between items depends on the pixel
+ size in the GRAPHICS mode in use. For example, in GR.0, each
+ space is one character wide, while in GR.8 each space is one-half
+ color clock (one dot) wide.
+
+
+ 203-207 CB-CF ....
+
+ Unused by either the BASIC or the Assembler cartridges.
+
+
+ 208-209 D0-D1 ....
+
+ Unused by BASIC. The only time I have seen any of these unused
+ locations in use is in COMPUTE! (March 1982 and October
+ 1981), when they were used for user sort routines, and in ANTIC
+ (June 1982), where they were used as flags in a graphic
+ demonstration. The bytes from 203 to 209 ($CB to $D1) are the
+ only page zero bytes uncontestably left free by BASIC.
+
+
+ 210-211 D2-D3 ....
+
+ Reserved for BASIC or other cartridge use.
+
+ Locations 212 to 255 ($D4 to $FF) are reserved for the floating point
+ package use. The FP routines are in ROM, from locations 55296 to
+ 57393 ($D800 to $E031). These page zero locations may be used if the
+ FP package is not called by the user's program. However, do not use
+ any of these locations for an interrupt routine, since such routines
+ might occur during an FP routine called by BASIC, causing the
+ system to crash.
+
+ Floating Point uses a six-byte precision. The first byte of the Binary
+ Coded Decimal (BCD) number is the exponent (where if BIT 7 equals
+ zero, then the number is positive; if one, then it is negative). The next
+ five bytes are the mantissa. If only that were all there was to it. The
+ BCD format is rather complex and is best explained in chapter eight of
+ De Re Atari.
+
+
+ 212-217 D4-D9 FR0
+
+ Floating point register zero; holds a six-byte internal form of the
+ FP number. The value at locations 212 and 213 are used to return
+ a two-byte hexadecimal value in the range of zero to 65536
+ ($FFFF) to the BASIC program (low byte in 212, high byte in
+ 213). The floating point package, if used, requires all locations
+ from 212 to 255. All six bytes of FR0 can be used by a machine
+ language routine, provided FR0 isn't used and no FP functions
+ are used by that routine. To use 16 bit values in FP, you would
+ place the two bytes of the number into the least two bytes of FR0
+ (212, 213; $D4, $D5), and then do a JSR to $D9AA (55722), which
+ will convert the integer to its FP representation, leaving the result
+ in FR0. To reverse this operation, do a JSR to $D9D2 (55762).
+
+
+ 218-223 DA-DF FRE
+
+ FP extra register (?)
+
+
+ 224-229 E0-E5 FR1
+
+ Floating point register one; holds a six-byte internal form of the
+ FP number as does FR0. The FP package frequently transfers
+ data between these two registers and uses both for two-number
+ arithmetic operations.
+
+
+ 230-235 E6-EB FR2
+
+ FP register two.
+
+
+ 236 EC FRX
+
+ FP spare register.
+
+
+ 237 ED EEXP
+
+ The value of E (the exponent).
+
+
+ 238 EE NSIGN
+
+ The sign of the FP number.
+
+
+ 239 EF ESIGN
+
+ The sign of the exponent.
+
+
+ 240 F0 FCHRFLG
+
+ The first character flag.
+
+ 241 Fl DIGRT
+ The number of digits to the right of the decimal.
+
+
+ 242 F2 CIX
+
+ Character (current input) index. Used as an offset to the input
+ text buffer pointed to by INBUFF below.
+
+
+ 243,244 F3,F4 INBUFF
+
+ Input ASCII text buffer pointer; the user's program line input
+ buffer, used in the translation of ATASCII code to FP values. The
+ result output buffer is at locations 1408 to 1535 ($580 to $5FF).
+
+
+ 245,246 F5,F6 ZTEMP1
+
+ Temporary register.
+
+
+ 247,248 F7,F8 ZTEMP4
+
+ Temporary register.
+
+
+ 249,250 F9,FA ZTEMP3
+
+ Temporary register.
+
+
+ 251 FB RADFLG
+
+ Also called DEGFLG. When set to zero, all of the trigonometric
+ functions are performed in radians; when set to six, they are done
+ in degrees. BASIC's NEW command and RESET both restore
+ RADFLG to radians.
+
+
+ 252,253 FC,FD FLPTR
+
+ Points to the user's FP number.
+
+
+ 254,255 FE,FF FPTR2
+
+ Pointer to the user's second FP number to be used in an
+ operation.
+
+ End of the page zero RAM.
+
+ ---------------------------------------------------------------------------
+
+ PAGE ONE: THE STACK
+
+ Locations 256 to 511 ($100 to $1FF) are the stack area for the OS, DOS
+ and BASIC. This area is page one. Machine language JSR, PHA and
+ interrupts all cause data to be written to page one, and RTS, PLA and
+ RTI instructions all read data from page one. On powerup or RESET,
+ the stack pointer is initialized to point to location 511 ($1FF). The stack
+ then pushes downward with each entry to 256 ($100). In case of
+ overflow, the stack will wrap around from 256 back to 511 again.
+
+ ---------------------------------------------------------------------------
+
+ PAGES TWO TO FOUR
+
+ 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 the 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 54287 ($D40F) and IRQEN
+ 53774 ($D20E) for more information. NMI interrupt vectors are marked
+ NMI; IRQ interrupt vectors are marked IRQ.
+ Refer to the chart below location 534 for a list of the interrupt vectors in
+ the new OS "B" version ROMs.
+
+
+ 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 54287 ($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, rather
+ than using the shadow registers that BASIC uses.
+
+ There is, unfortunately, only one DLI vector address. If you use
+ more than one DLI and they are to perform different activities,
+ then changing the vectoring to point to a different routine must
+ be done by the previous DLI's themselves.
+
+ Another way to accomplish interrupts is during the VBLANK
+ interval with a VBI. One small problem with using DLI's is that
+ the keyboard "click" routine interferes with the DLI by throwing
+ off the timing, since the click is provided by several calls to the
+ WSYNC register at 54282 ($D40A). Chris Crawford discusses
+ several solutions in De Re Atari, but the easiest of them is not to
+ allow input from the keyboard! See Micro, December 1981,
+ Creative Computing, July 1981 and December 1981.
+ Here's a short example of a DLI. It will print the lower half of your
+ text screen upside down:
+
+ 10 START = PEEK(560) + PEEK(561) *
+ 256: POKE START + 16,130
+ 20 PAGE = 1536: FOR PGM = PAGE TO P
+ AGE + 7: READ BYTE: POKE PGM, BYTE
+ : NEXT PGM
+ 30 DATA 72,169,4,141,1,212,104,64
+ 40 POKE 512,0: POKE 513,6: POKE 542
+ 86,192
+ 50 FOR TEST = 1 TO 240: PRINT"SEE "
+ ;: NEXT TEST
+ 60 GOTO 60
+
+ DOWNLOAD VDSLST.BAS
+
+ Another example of a DLI changes the color of the bottom half of
+ the screen. To use it, simply change the PAGE + 7 to PAGE + 10
+ in the program above and replace line 30 with:
+
+ 30 DATA 72,169,222,141,10,212,141,2
+ 4,208,104,64
+
+ Finally, delete lines 50 and 60. See also location 54282 ($D40A).
+
+
+ 514,515 202,203 VPRCED
+
+ Serial (peripheral) proceed line vector, initialized 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. According to
+ De Re Atari, this interrupt is not used and points to a PLA, RTI
+ instruction sequence. This interrupt is handled by the PIA chip
+ and can be used to provide more control over external devices.
+ See the OS Listing, page 33.
+
+
+ 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.
+ According to De Re Atari, this interrupt is not used and points to
+ a PLA, RTI sequence. This interrupt is processed by PIA. See the
+ OS Listing, page 33.
+
+
+ 518,519 206,207 VBREAK
+
+ Software break instruction vector for the 6502 BRK ($00)
+ command (not the BREAK key, which is at 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.
+
+ SIO uses the three last interrupts to control serial bus
+ communication with the serial bus devices. During serial bus
+ communication, all program execution is halted. The actual
+ serial I/O is interrupt driven; POKEY waits and watches for a flag
+ to be set when the requested I/O operation is completed. During
+ this wait, POKEY is sending or receiving bits along the seriai
+ bus. When the entire byte has been transmitted (or received), the
+ output needed (VSEROR) or the input ready (VSERIN) IRQ is
+ generated according to the direction of the data flow. This causes
+ the next byte to be processed until the entire buffer has been sent
+ or is full, and a flag for "transmission done" is set. At this point,
+ SIO exits back to the calling routine. You can see that SIO wastes
+ time waiting for POKEY to send or receive the information on the
+ bus.
+
+
+ 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).
+ See 53774 ($D20E) for more information on IRQ interrupts.
+
+ The new "B" version OS ROMs change the vectors above as
+ follows:
+
+ VDSLST 59280 ($E790)
+ VPRCED 59279 ($E78F)
+ VINTER 59279 ($E78F)
+ VBREAK 59279 ($E78F)
+ VKEYBD NO CHANGE
+ VSERIN 60175 ($EB0F)
+ VSEROR NO CHANGE
+ VSEROC 60111 ($EACF)
+ VTIMR 1-4 59279 ($E78F)
+ VIMIRQ 59142 ($E706)
+ VVBLKI 59310 ($E7AE)
+ VVBLKD 59653 ($E905)
+
+ ---------------------------------------------------------------------------
+ The locations from 536 to 558 ($218 to $22E) are used for the system
+ software timers. 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. See De Re Atari for
+ information regarding setting these timers in an assembly routine
+ using the SETVBV register (58460; $E45C). 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 than 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 (location 66; $42 set to non-zero
+ for critical code) is executed by the OS. Since the OS uses timer
+ one for its I/O routines and for timing serial bus operations
+ (setting it to different values for timeout routines), you should use
+ another timer to avoid conflicts or interference with the operation
+ of the system.
+
+
+ 538,539 21A,21B CDTMV2
+
+ System timer two. Decremented at the stage two VBLANK. Can
+ be decremented every stage one VBLANK, subject to critical
+ section test as defined by setting of CRITIC flag (location 66;
+ $42). This timer may miss (skip) a count when 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. Any prior value
+ in the register during this function will be lost.
+
+
+ 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. On powerup, VBI's are
+ enabled and DLI's are disabled. See location 512; $200.
+
+
+ 548,549 224,225 VVBLKD
+
+ 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.
+
+ These two VBLANK vectors point to interrupt routines that occur
+ at the beginning of the VBLANK time interval. The stage one
+ VBLANK routine is executed; then location 66 ($42) is tested for
+ the time-critical nature of the interrupt and, if a critical code
+ section has been interrupted, the stage two VBLANK routine is
+ not executed with a JMP made through the immediate vector
+ VVBLKI. If not critical, the deferred interrupt VVBLKD is used.
+ Normally the VBLANK interrupt bits are enabled (BIT 6 at
+ location 54286; $D40E is set to one). To disable them, clear BIT 6
+ (set to zero).
+
+ The normal seguence for VBLANK interrupt events is: after the
+ OS test, JMP to the user immediate VBLANK interrupt routine
+ through the vector at 546, 547 (above), then through SYSVBV at
+ 58463 ($E45F). This is directed by the OS through the VBLANK
+ interrupt service routine at 59345 ($E7D1) and then on to the
+ user-deferred VBLANK interrupt routine vectored at 548, 549. it
+ then exits the VBLANK interrupt routine through 58466 ($E462)
+ and an RTI instruction.
+
+ If you are changing the VBLANK vectors during the interrupt
+ routine, use the SETVBV routine at 58460 ($E45C). An
+ immediate VBI has about 3800 machine cycles of time to use a
+ deferred VBI has about 20,000 cycles. Since many of these cycles
+ are executed while the electron beam is being drawn, it is
+ suggested that you do not execute graphics routines in deferred
+ VBI's. See the table of VBLANK processes at the end of the map
+ area.
+
+ if you create your own VBI's, terminate an immediate VBI with a
+ JMP to 58463 ($E45F) and a deferred VBI with a JMP to 58466
+ ($E462). To bypass the OS VBI routine at 59345 ($E7D1) entirely,
+ terminate your immediate VBI with a JMP to 58466 ($E462).
+
+ Here's an example of using a VBI to create a flashing cursor. It
+ will also blink any text you display in inverse mode.
+
+ 10 FOR BLINK = 1664 TO 1680: READ B
+ YTE: POKE BLINK, BYTE: NEXT BLINK
+ 20 POKE 548,128: POKE 549,6
+ 30 DATA 8,72,165,20,41,16,74,74,74,
+ 141
+ 40 DATA 243,2,104,40,76,62,233
+
+ DOWNLOAD VVBLKD.BAS
+
+ To restore the normal cursor and display, POKE 548,62 and
+ POKE 549,233.
+
+
+ 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.
+ Problems may occur when timer values are set greater than 255,
+ since the 6502 cannot manipulate 16-bit values directly (a
+ number in the range of zero to 255 is an eight-bit value; if a value
+ requires two bytes to store, such as a memory location, it is a
+ 16-bit value). Technically, a VBLANK interrupt could occur
+ when one timer byte is being initialized and the other not yet set.
+ To avoid this, keep timer values less than 255. See the Atari OS
+ User's Manual, page 106, for details.
+
+ Since the OS uses timer one, it is recommended that you use
+ timer two instead, to avoid conflicts with the operation of the
+ Atari. Initialized to 60396 ($EBEA) in the old ROMs, 60400
+ ($EBF0) in the new ROMs. NMI
+
+
+ 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.
+ Every time a key is pressed, STIMER is set to 48 ($30). Whenever
+ SRTIMR is equal to zero and a key is being continuously pressed,
+ the value of that key is continually stored in CH, location 764
+ ($2FC).
+
+
+ 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 559,0 to turn off
+ ANTIC. When you are ready to bring the screen back to life,
+ POKE 559 with the number saved earlier.
+
+ This location is the shadow register for 54272 ($D400), and the
+ number you PEEKed above defines the playfield size, whether or
+ not the missiles and players are enabled, and the player size
+ resolution. To enable your options by using POKE 559, simply
+ add up the values below to obtain the correct number to POKE
+ into SDMCTL. Note that you must choose only one of the four
+ playfield options appearing at the beginning of the list:
+
+ Option Decimal Bit
+ No playfield 0 0
+ Narrow playfield 1 0
+ Standard playfield 2 0,1
+ Wide playfield 3 0,1
+ Enable missle DMA 4 2
+ Enable player DMA 8 3
+ Enable player and missile
+ DMA 12 2,3
+ One line player resolution 16 4
+ Enable instructions to fetch
+ DMA 32 5 (see below)
+
+ Note that two-line player resolution is the default and that it is not
+ necessary to add a value to 559 to obtain it. I have included the
+ appropriate bits affected in the table above. The default is 34
+ ($22).
+
+ The playfield is the area of the TV screen you will use for display,
+ text, and graphics. Narrow playfield is 128 color clocks (32
+ characters wide in GR.0), standard playfield is 160 color clocks
+ (40 characters), and wide playfield is 192 color clocks wide (48
+ characters). A color clock is a physical measure of horizontal
+ distance on the TV screen. There are a total of 228 color clocks on
+ a line, but only some of these (usually 176 maximum) will be
+ visible due to screen limitations. A pixel, on the other hand, is a
+ logical unit which varies in size with the GRAPHICS mode. Due
+ to the limitations of most TV sets, you will not be able to see all of
+ the wide playfield unless you scroll into the offscreen portions.
+ BIT 5 must be set to enable ANTIC operation; it enables DMA for
+ fetching the display list instructions.
+
+
+ 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). You can also find the address of the DL by
+ PEEKing one byte above the top of free memory:
+
+ PRINT PEEK(741) + PEEK(742) * 256 + 1.
+
+ However, 560 and 561 are more reliable pointers since custom
+ DL's can be elsewhere in memory. Atari standard display lists
+ simply instruct the ANTIC chip as to which types of mode lines to
+ use for a screen and where the screen data may be found in
+ memory. Normally, a DL is between 24 and 256 bytes long (most
+ are less than 100 bytes, however), depending on your
+ GRAPHICS mode (see location 88,89 for a chart of DL sizes and
+ screen display use).
+
+ By altering the DL, you can mix graphics modes on the same
+ screen; enable fine scrolling; change the location of the screen
+ data; and force interrupts (DLI's) in order to perform short
+ machine language routines.
+
+ DL bytes five and six are the addresses of the screen memory
+ data, the same as in locations 88 and 89 ($58, $59). Bytes four,
+ five, and six are the first Load Memory Scan (LMS) instruction.
+ Byte four tells ANTIC what mode to use; the next two bytes are
+ the location of the first byte of the screen RAM (LSB/MSB).
+ Knowing this location allows you to write directly to the screen by
+ using POKE commands (you POKE the internal character codes,
+ not the ATASCII codes -- see the BASIC Reference Manual, p.
+ 55).
+
+ For example, the program below will POKE the internal codes to
+ the various screen modes. You can see not only how each screen
+ mode handles the codes, but also roughly where the text window
+ is in relation to the display screen (the 160 bytes below
+ RAMTOP). Note that the GTIA modes have no text window. If
+ you don't have the GTIA chip, your Atari will default to
+ GRAPHICS 8, but with GTIA formatting.
+
+ 1 TRAP 10: GRAPHICS Z
+ 5 SCREEN = PEEK(560) + PEEK(561) *
+ 256
+ 6 TV = SCREEN + 4: TELE = SCREEN + 5
+ 8 DISPLAY = PEEK(TV) + PEEK(TELE) *
+ 256
+ 10 FOR N = 0 TO 255: POKE DISPLAY +
+ N,N: NEXT N
+ 20 DISPLAY = DISPLAY + N
+ 30 IF DISPLAY > 40959 THEN Z = Z + 1
+ : GOTO 1
+ 40 GOTO 10
+ 50 Z = Z + 1:IF Z > 60 THEN END
+ 60 GOTO 1
+
+ Here's another short program which will allow you to examine the
+ DL in any GRAPHICS mode:
+
+ 10 REM CLEAR SCREEN FIRST
+ 20 PRINT"ENTER GRAPHICS MODE": REM A
+ DD 16 TO THE MODE TO SUPPRESS THE
+ TEXT WINDOW
+ 30 INPUT A: GRAPHICS A
+ 40 DLIST = PEEK(560) + PEEIK(561) * 2
+ 56
+ 50 LOOK = PEEK(DLIST): PRINT LOOK;"
+ ";
+ 60 IF LOOK <> 65 THEN DLIST = DLIST
+ + 1: GOTO 50
+ 70 LPRINT PEEK(DLIST + 1);" ";PEEK(D
+ LIST + 2)
+ 80 END
+
+ The value 65 in the DL is the last instruction encountered. It tells
+ ANTIC to jump to the address in the next two bytes to re-execute
+ the DL, and wait for the next VBLANK. If you don't have a
+ printer, change the LPRINT commands to PRINT and modify the
+ routine to save the data in an array and PRINT it to the screen
+ after (in GR.0).
+
+ If you would like to examine the locations of the start of the
+ Display List, screen, and text window, try:
+
+ 5 REM CLEAR SCREEN FIRST
+ 6 INPUT A: GRAPHICS A
+ 10 DIM DLIST$(10), SAVMSC$(10), TXT$
+ (10)
+ 15 DLIST$ = "DLIST": SAVMSC$ = "SAVM
+ SC": TXT$ = "TEXT"
+ 20 DLIST = PEEK(560) + PEEK(561) * 2
+ 56
+ 30 SAV = PEEK(88) + PEEK(89) * 256:
+ TXT = PEEK(660) + PEEK(66l) * 256
+ 40 PRINT DLIST$;" "; DLIST,SAVMSC$;"
+ ";SAV
+ 50 PRINT TXT$;" "; TEXT
+ 60 INPUT A: GRAPHICS A: GOTO 20
+
+ Since an LMS is simply a map mode (graphics) or character
+ mode (text) instruction with BIT six set, you can make any or all of
+ these instructions into LMS instructions quite easily, pointing
+ each line to a different RAM area if necessary. This is discussed
+ in De Re Atari on implementing horizontal scrolling.
+
+ DL's can be used to help generate some of the ANTIC screen
+ modes that aren't supported by BASIC, such as 7.5 (ANTIC
+ mode E) or ANTIC mode three, the lowercase with descenders
+ mode (very interesting; ten scan lines in height which allow true
+ descenders on lowercase letters).
+
+ If you create your own custom DL, you POKE its address here.
+ Hitting BESET or changing GRAPHICS modes will restore the
+ OS DL address, however. The display list instruction is loaded
+ into a special register called the Display Instruction Register (IR).
+ which processes the three DL instructions (blank, jump, or
+ display). It cannot be accessed directly by the programmer in
+ either BASIC or machine language. A DL cannot cross a 1K
+ boundary unless a jump instruction is used.
+
+ There are only four display list instructions: blank line (uses BAK
+ color), map mode, text mode, and jump. Text (character mode)
+ instructions and map mode (graphics) instructions range from
+ two to 15 ($2 to $F) and are the same as the ANTIC GRAPHICS
+ modes. A DL instruction byte uses the following conventions
+ (functions are enabled when the bit is set to one):
+
+ Bit Decimal Function
+ 7 128 Display List Interrupt when set (enabled
+ equals one)
+ 6 64 Load Memory Scan. Next two bytes are the
+ LSB/MSB of the data to load.
+ 5 32 Enable vertical fine scrolling.
+ 4 16 Enable horizontal fine scrolling.
+ 3-0 8-1 Mode
+ 0 0 1 0 Character
+ to Modes
+ 0 1 1 1
+ . . . . . . .
+ 1 0 0 0 Map
+ to Modes
+ 1 1 1 1
+
+ The above bits may be combined (i.e., DLI, scrolling and LMS
+ together) if the user wishes.
+
+ Special DL instructions (with decimal values):
+ Blank 1 line = 0 5 lines = 64
+ 2 lines = 16 6 lines = 80
+ 3 lines = 32 7 lines = 96
+ 4 lines = 48 8 lines = 112
+
+ Jump instruction (JMP) = zero (three-byte instruction).
+ Jump and wait for Vertical Blank (JVP) = 65 (three-byte
+ instruction).
+ Special instructions may be combined only with DL interrupt
+ instructions.
+
+ A Display List Interrupt is a special form of interrupt that takes
+ place during the screen display when the ANTIC encounters a
+ DL instruction with the interrupt BIT 7 set. See location 512
+ ($200) for DLI information.
+
+ Since DL's are too large a topic to cover properly in this manual,
+ I suggest you look in the many magazines (i.e., Creative
+ Computing, July 1981, August 1981; Micro, December 1981;
+ Softside, #30 to 32, and BYTE, December 1981) for a more
+ detailed explanation
+
+
+ 562 232 SSKCTL
+
+ Serial port control register, shadow for 53775 ($D20F). Setting
+ the bits in this register to one has the following effect:
+
+ Bit Decimal Function
+ 0 1 Enable the keyboard debounce circuit.
+ 1 2 Enable the keyboard scanning circuit.
+ 2 4 The pot counter completes a read within two
+ scan lines instead of one frame time.
+ 3 8 Serial output transmitted as two-tone instead
+ of logic true/false (POKEY two-tone mode).
+ 4-6 16-64 Serial port mode control.
+ 7 128 Force break; serial output to zero.
+
+ Initialized to 19 ($13) which sets bits zero, one and four.
+
+
+ 563 233 SPARE
+
+ No OS use. See the note at location 651 regarding spare bytes.
+
+
+ 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 for 54285 ($D40D). Value is the
+ same as VCOUNT register for two-line resolution (see 54283;
+ $D40B). Both light pen values are modified when the trigger is
+ pressed (pulled low). The light pen positions are not the same as
+ the normal screen row and column positions. There are 96
+ vertical positions, numbered from 16 at the top to 111 at the
+ bottom, each one equivalent to a scan line. Horizontal positions
+ are marked in color clocks. There are 228 horizontal positions,
+ numbered from 67 at the left. When the LPENH value reaches
+ 255, it is reset to zero and begins counting again by one to the
+ rightmost edge, which has a value of seven.
+
+ Obviously, because of the number of positions readable and the
+ small size of each, a certain leeway must be given by the
+ programmer when using light pen readouts on a program. At the
+ time of this writing, Atari had not yet released its light pen onto
+ the market, although other companies have.
+
+
+ 566,567 236,237 BRKKY
+
+ BREAK key interrupt vector. This vector is available only with
+ the version "B" OS ROMs, not the earlier version. You can use
+ this vector to write your own BREAK key interrupt routine.
+ Initialized to 59220 ($E754).
+
+
+ 568,569 238,239 ....
+
+ Two spare bytes.
+
+
+ 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 two, 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 records 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 reboot. If POKEd with one (powerup in progress
+ flag), the computer will reboot whenever the RESET key is
+ pressed. Any non-zero number indicates the initial powerup
+ routine is in progress.
+
+ If you create an AUTORUN.SYS file, it should end with an RTS
+ instruction. If not, it should POKE 580 with zero and POKE 9 with one.
+ You can turn any binary file that boots when loaded with DOS menu
+ selection "L" into an auto-boot file simply by renaming it
+ "AUTORUN.SYS". Be careful not to use the same name for any two
+ files on the same disk.
+
+ When this is combined with the disabling of the BREAK key discussed
+ in location 16 ($10) and the program protection scheme discussed in
+ location 138 ($8A), you have the means to protect your BASIC
+ software fairly effectively from being LISTed or examined, although
+ not from being copied.
+
+
+ 581 245 ....
+
+ Spare byte.
+
+
+ 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.
+ It is updated after each disk status request to contain the value of
+ the third byte of the status frame (location 748; $2EC). All disk
+ operations have a seven second time-out (except FORMAT),
+ established by the disk handler (you had noticed that irritating
+ little delay, hadn't you?). The "sleeping disk syndrome" (the
+ printer suffers from this malady as well) happens when your drive
+ times out, or the timer value reaches zero. This has been cured
+ by the new OS "B" version ROMs.
+
+
+ 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. In this case, choose only one
+ of the four priorities stated at the beginning. BAK is the
+ background or border. You can also use this location to select
+ one of GTIA GRAPHICS modes nine, ten, or eleven.
+
+ Priority options in order Decimal Bit
+ Player 0 - 3, playfield 0 - 3, BAK
+ (background) 1 0
+ Player 0 - 1, playfield 0 - 3, player 2 - 3,
+ BAK 2 1
+ Playfield 0 - 3, player 0 - 3, BAK 4 2
+ Playfield 0 - 1, player 0 - 3, playfield 2 -3,
+ BAK 8 3
+ Other options
+ Four missiles = fifth player 16 4
+ Overlaps of players have 3rd color 32 5
+ GRAPHICS 9 (GTIA mode) 64 6
+ GRAPHICS 10 (GTIA mode) 128 7
+ GRAPHICS 11 (GTIA mode) 192 6, 7
+
+ It is quite easy to set conflicting priorities for players and
+ playfields. In such a case, areas where both overlap when a
+ conflict occurs will turn black. The same happens if the overlap
+ option is not chosen.
+ With the color/overlap enable, you can get a multicolor player
+ by combining players. The Atari performs a logical OR to colors
+ of players 0/1 and 2/3 when they overlap. Only the 0/1, 2/3
+ combinations are allowed; you will not get a third color when
+ players 1 and 3 overlap, for example (you will get black instead).
+ If player one is pink and player 0 is blue, the overlap is green. If
+ you don't enable the overlap option, the area of overlap for all
+ players will be black.
+ In GTIA mode nine, you have 16 different luminances of the
+ same hue. In BASIC, you would use SETCOLOR 4,HUE,0. To
+ see an example of GTIA mode nine, try:
+
+ 10 GRAPHICS 9: SETCOLOR 4,9,0
+ 20 FOR LOOP = 1 TO 15: COLOR LOOP
+ 30 FOR LINE = 1 TO 2
+ 40 FOR TEST = 1 TO 25: PLOT 4 + TES
+ T, LOOP + LINE + SPACE: NEXT TEST
+ 45 NEXT LINE
+ 50 SPACE = SPACE + 4
+ 60 NEXT LOOP
+ 70 GOTO 70: REM WITHOUT THIS LINE,
+ SCREEN WILL RETURN TO GR.0
+
+ DOWNLOAD GTIA9.BAS
+
+ In GTIA mode ten, you have all nine color registers available;
+ hue and luminance may be set separately for each (it would
+ otherwise allow 16 colors, but there are only nine registers). Try
+ this to see:
+
+ 10 N = 0: GRAPHICS 10
+ 20 FOR Q = 1 TO 2
+ 30 FOR B = 0 TO 8: POKE 704 + B, N
+ * 16 + A
+ 35 IF A > 15 THEN A = 0
+ 40 COLOR B
+ 45 A = A + 1: N = N + 1
+ 50 IF N > 15 THEN N = 0
+ 60 NEXT B
+ 65 TRAP 70: NEXT Q
+ 70 POP: N = N + 1: FOR Z = 1 TO 200
+ : NEXT Z
+ 75 GOTO 30
+
+ DOWNLOAD GTIA10.BAS
+
+ GTIA mode eleven is similar to mode nine except that it allows 16
+ different hues, all of the same luminance. In BASIC, use
+ SETCOLOR 4,O,luminance. Try this for a GTIA mode eleven
+ demonstration:
+
+ 10 GRAPHICS 11
+ 20 FOR LOOP = 0 TO 79: COLOR LOOP:
+ PLOT LOOP,0: DRAWTO LOOP,191: NEXT
+ LOOP
+ 30 GOTO 30
+
+ DOWNLOAD GTIA11.BAS
+
+ You can use these examples with the routine to rotate colors,
+ described in the text preceding location 704. GTIA mode pixels
+ are long and skinny; they have a four to one horizontal length to
+ height ratio. This obviously isn't very good for drawing curves
+ and circles!
+
+ GTIA modes are cleared on the OPEN command. How can you
+ tell if you have the GTIA chip? Try POKE 623,64. If you have the
+ GTIA, the screen will go all black. If not, you don't have it. Here
+ is a short routine, written by Craig Chamberlain and Sheldon
+ Leemon for COMPUTE!, which allows an Atari to test itself for the
+ presence of a CTIA or GTIA chip. The routine flashes the answer
+ on the screen, hut can easily be modified so a program will
+ "know" which chip is present so it can adapt itself accordingly:
+
+ 10 POKE 66,1:GRAPHICS 8:POKE 709,0:PO
+ KE 710,0:POKE 66,0:POKE 623,64:P0K
+ E 53248,42:POKE 5326l,3:PUT#6,1
+ 20 POKE 53278,0:FOR K=1 TO 300:NEXT K
+ :GRAPHICS 18:POKE 53248,0:POSITION
+ 8,5:? #6;CHR$(71-PEEK(53252));"TI
+ A"
+ 30 POKE 708,PEEK(20):GOTO 30
+
+ DOWNLOAD CTIAGTIA.BAS
+
+ How can you get the GTIA if you don't have one? Ask your local
+ Atari service representative or dealer, or write directly to Atari in
+ Sunnyvale, California.
+
+ See the GTIA/CTIA introduction at location 53248 ($D000) for
+ more discussion of the chip. See BYTE, May 1982, COMPUTE!,
+ July through September 1982, and De Re Atari for more on the
+ GTIA chip, and the GTIA Demonstration Diskette from the Atari
+ Program Exchange (APX).
+
+ ---------------------------------------------------------------------------
+ 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.
+ When used to move a player or cursor (i.e., PLOT
+ PADDLE(0),0), test your screen first. Many sets will not display
+ locations less than 48 ($30) or greater than 208 ($D0), and in
+ many GRAPHICS modes you will get an ERROR 141 -- cursor
+ out of range. Paddles are paired in the controller jacks, so paddle
+ 0 and paddle 1 both use jack one. PADDL registers are shadows
+ for POKEY locations 53760 to 53767 ($D200 to $D207).
+
+
+ 625 271 PADDL1
+
+ This and the next six bytes are the same as 624, but for the other
+ paddles.
+
+
+ 626 272 PADDL2
+
+ 627 273 PADDL3
+
+ 628 274 PADDL4
+
+ 629 275 PADDL5
+
+ 630 276 PADDL6
+
+ 631 277 PADDL7
+
+ 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 incrememts)
+ read by each joystick register (using the STICKn command),
+ depending on the position of the stick:
+
+ Decimal Binary
+ 14 1110
+ | |
+ 10 | 6 1010 | 0110
+ \ |/ \ |/
+ 11-- 15 ---7 1011-- 1111 --0111
+ / |\ / |\
+ 9 | 5 1001 | 0101
+ | |
+ 13 1101
+
+ 15 (1111) equals stick in the upright (neutral) position.
+ See Micro, December 1981,for an article on making a
+ proportional joystick. For an example of a machine language
+ joystick driver you can add to your BASIC program, see
+ COMPUTE!, July 1981.
+ One machine language joystick reader is listed below, based on
+ an article in COMPUTE!, August 1981:
+
+ 1 GOSUB 1000
+ 10 LOOK = STICK(0)
+ 20 X = USR(1764,LOOK): Y = USR(1781,
+ LOOK)
+ 30 ON X GOTO 120, 100, 110
+ .
+ .
+ .
+ 100 REM YOUR MOVE LEFT ROUTINE HERE
+ 105 GOTO 10
+ 110 REM YOUR MOVE RIGHT ROUTINE HERE
+ 115 GOTO 10
+ 120 ON Y GOTO 150, 130, 140
+ 130 REM YOUR MOVE DOWN ROUTINE HERE
+ 135 GOTO 10
+ 140 REM YOUR MOVE UP ROUTINE HERE
+ 145 GOTO 10
+ 150 REM IF X <> 1 THEN NOTHING DOING.
+ BRANCH TO YOUR OTHER ROUTINES OR
+ TO 155
+ 155 GOTO 10
+ .
+ .
+ .
+ 1000 FOR LOOP = 1764 TO 1790: READ BY
+ TE: POKE LOOP, BYTE: NEXT LOOP
+ 1010 DATA 104,104,133,213,104,41,12,7
+ 4,74,73,2,24,105,1
+ 1020 DATA 133,212,96,104,104,133,213,
+ 104,41,3,76,237,6
+ 1030 RETURN
+
+ DOWNLOAD STICK0.BAS
+
+ See locations 88, 89 ($58, $59) for an example of a USR call using
+ a string instead of a fixed memory location.
+
+
+ 633 279 STICK1
+
+ This and the next two locations are the same as 632, but for the
+ other joysticks. These four locations are also used to determine if
+ a lightpen (PEN 0 - 3) switch is pressed.
+
+
+ 634 27A STICK2
+
+ 635 27B STICK3
+
+ 636 27C PTRIG0
+
+ Paddle trigger 0. Used to determine if the trigger or hutton on
+ paddle 0 is pressed (zero is returned) or not (one is returned).
+ Since these are the same lines as the joystick left/right switches,
+ you can use PTRIG for horizontal movement. PTRIG(1) -
+ PTRIG(0) returns -1 (left), 0 (center), + 1 (right). The next seven
+ locations are for the other paddle buttons. PTRIG 0 - 3 are
+ shadows for PIA register 54016 ($D300).
+
+
+ 637 27D PTRIG1
+
+ 638 27E PTRIG2
+
+ 639 27F PTRIG3
+
+ 640 280 PTRIG4
+
+ PTRIG 4-7 are shadows for PIA register 54017 ($D301).
+
+
+ 641 281 PTRIG5
+
+ 642 282 PTRIG6
+
+ 643 283 PTRIG7
+
+ 644 284 STRIG0
+
+ Stick trigger 0. This and the next three locations perform the
+ same function as the PTRIG locations except for the joysticks.
+ Like PTBIG, zero is returned when the button is pressed; one is
+ returned when it is not. STRIG registers are shadow registers for
+ GTIA/CTIA locations 53264 to 53267 ($D010 to $D013).
+
+
+ 645 285 STRIG1
+
+ 646 286 STRIG2
+
+ 647 287 STRIG3
+
+ ---------------------------------------------------------------------------
+ Locations 648 to 655 ($288 to $28F) are for miscellaneous OS use.
+
+
+ 648 288 CSTAT
+
+ Cassette status register.
+
+
+ 649 289 WMODE
+
+ Register to store either the read or the write mode for the cassette
+ handler, depending on the operation: zero equals read, 128 ($80)
+ equals write.
+
+
+ 650 28A BLIM
+
+ Cassette data record buffer size; contains the number of active
+ data bytes in the cassette buffer for the record being read or
+ written, at location 1021 ($3FD). Values range from zero to 128
+ (cassette record size is 128; $80). The pointer to the byte being
+ read or written is at 61 ($3D). The value of BLIM is drawn from
+ the control bytes that precede every cassette record, as
+ explained in location 1021.
+
+
+ 651-655 28B-28F ....
+
+ Spare bytes. It is not recommended that you use the spare bytes
+ for your own program use. In later upgrades of the OS, these
+ bytes may be used, causing a conflict with your program. For
+ example, the new OS ROMs use locations 652 and 653 ($28C,
+ $28D) in the new IRQ interrupt handler routines. It is best to use a
+ protected area of memory such as page six, locations 1536 to
+ 1791 ($600 to $6FF).
+
+ ---------------------------------------------------------------------------
+ Locations 656 to 703 ($290 to $2BF) are used for the screen RAM
+ display handler (depending on GRAPHICS mode).
+ In split-screen mode, the text window is controlled by the screen editor
+ (E:), while the graphics region is controlled by the display handler
+ (S:), using two separate IOCB's. Two separate cursors are also
+ maintained. The display handler will set AUX1 of the IOCB to split-
+ screen option. Refer to the IOCB area, locations 832 to 959 ($340 to
+ $3BF). See COMPUTE!, February 1982, for a program to put GR.1
+ and GR.2 into the text window area. The text window uses 160 bytes of
+ RAM located just below RAMTOP (see location 106; $6A). See
+ location 88 ($58) for a chart of screen RAM use.
+
+
+ 656 290 TXTROW
+
+ Text window cursor row; value ranges from zero to three (the text
+ window has only four lines). TXTROW specifies where the next
+ read or write in the text window will occur
+
+
+ 657,658 291,292 TXTCOL
+
+ Text window cursor column; value ranges from zero to 39. Unless
+ changed by the user, location 658 will always be zero (there are
+ only 40 columns in the display, so the MSB will be zero). Since
+ POSITION, PLOT, LOCATE and similar commands refer to the
+ graphics cursor in the display area above the text window, you
+ must use POKE statements to write to this area if PRINT
+ statements are insufficient.
+
+
+ 659 293 TINDEX
+
+ Contains the current split-screen text window GRAPHICS mode.
+ It is the split-screen equivalent to DINDEX (location 87; $57) and
+ is always equal to zero when location 128 ($7B) equals zero.
+ Initialized to zero (which represents GR.0). You can alter the
+ display list to change the text window into any GRAPHICS mode
+ desired. If you do so, remember to change TINDEX to reflect that
+ alteration.
+
+
+ 660,661 294,295 TXTMSC
+
+ Address of the upper left corner of the text window. Split-screen
+ equivalent of locations 88, 89 ($58, $59).
+
+
+ 662-667 296-29B TXTOLD
+
+ These locations contain the split-screen equivalents of OLDROW
+ (90; $5A), OLDCOL (91, 92; $5B, $5C), OLDCHR (location 93,
+ $5D) and OLDADR (locations 94, 95; $5E, $5F). They hold the
+ split-screen cursor data.
+
+
+ 668 29C TMPX1
+
+ Temporary register, used by the display handler for the scroll
+ loop count record.
+
+
+ 669 29D HOLD3
+
+ Temporary register.
+
+
+ 670 29E SUBTMP
+
+ Temporary storage.
+
+
+ 671 29F HOLD2
+
+ Temporary register.
+
+
+ 672 2A0 DMASK
+
+ Pixel location mask. DMASK contains zeroes tor all bits which do
+ not correspond to the specific pixel to be operated upon, and
+ ones for bits which do correspond, according to the GRAPHICS
+ mode in use, as follows:
+
+ 11111111 Modes 0, 1 and 2: one pixel per screen display
+ byte.
+ 11110000 Modes 9, 10 and 11: two pixels per byte.
+ 00001111
+ 11000000 Modes 3, 5 and 7: four pixels per byte.
+ 00110000
+ 00001100
+ 00000011
+ 10000000 Modes 4, 6 and 8: eight pixels per byte.
+ 01000000
+
+ etc. to:
+
+ 00000001
+
+ A pixel (short for picture cell or picture element) is a logical unit
+ of video size which depends on the GRAPHICS mode in use for
+ its dimensions. The smallest pixel is in GR.8 where it is only .5
+ color clock wide and one scan line high. In GR.0 it is also only .5
+ color clock wide, but it is eight scan lines high. Here is a chart of
+ the pixel sizes for each mode:
+
+ Text Modes Graphics modes
+ GR. mode 0 1 2 3 4 5 6 7 8
+ Scan lines
+ per pixel 8 8 16 8 4 4 2 2 1
+ Bits
+ per pixel 1 1 1 2 1 2 1 2 1
+ Color clocks
+ per pixel .5 1 1 4 2 2 1 1 .5
+ Characters
+ per line 40 20 20 -- -- -- -- -- --
+ Pixels
+ per width -- -- -- 40 80 80 160 160 320
+
+ The number of pixels per screen width is based on the normal
+ playfield screen. See location 559 ($22F) for information on
+ playfield size.
+
+
+ 673 2A1 TMPLBT
+
+ Temporary storage for the bit mask.
+
+
+ 674 2A2 ESCFLG
+
+ Escape flag. Normally zero, it is set to 128 ($80) if the ESC key is
+ pressed (on detection of the ESC character; 27, $1B). It is reset to
+ zero following the output of the next character. To display
+ ATASCII control codes without the use of an ESC character, set
+ location 766 ($2FE) to a non-zero value.
+
+
+ 675-689 2A3-2B1 TABMAP
+
+ Map of the TAB stop positions. There are 15 byte (120 bits) here,
+ each bit corresponding to a column in a logical line. A one in any
+ bit means the TAB is set; to clear all TABs simply POKE every
+ location with zero. There are 120 TAB locations because there
+ are three physical lines to one logical line in GRAPHICS mode
+ zero, each consisting of 40 columns. Setting the TAB locations for
+ one logical line means they will also be set for each subsequent
+ logical line until changed. Each physical line in one logical line
+ can have different TAB settings, however.
+
+ To POKE TAB locations from BASIC, you must POKE in the
+ number (i.e., set the bit) that corresponds to the location of the
+ bit in the byte (there are five bytes in each line). For example:
+ To set tabs at locations 5, 23, 27 and 32, first visualize the line as a
+ string of zeros with a one at each desired tab setting:
+
+ 0000100000000000000000100010000100000000
+
+ Then break it into groups of eight bits (one byte units). There are
+ three bytes with ones (bits set), two with all zeros:
+
+ 00001000 = 8
+ 00000000 = 0
+ 00000010 = 2
+ 00100001 = 33
+ 00000000 = 0
+
+ Converting these to decimal, we get the values listed at the right
+ of each byte. These are the numbers you'd POKE into locations
+ 675 (the first byte) to 679 (the fifth byte on the line). On powerup
+ or when you OPEN the display screen (S: or E:), each byte is
+ given a value of one (i.e., 00000001) so that there are tab default
+ tab stops at 7, 15, 23, etc., incrementing by eight to 119. Also,
+ the leftmost screen edge is also a valid TAB stop (2, 42, and 82).
+ In BASIC, these are set by the SET-TAB and CLR-TAB keys.
+ TABMAP also works for the lines in the text display window in
+ split-screen formats. TABMAP is reset to the default values on
+ pressing RESET or changing GRAPHICS modes.
+ See location 201 ($C9) about changing the TAB settings used
+ when a PRINT statement encounters a comma.
+
+
+ 690-693 2B2-2B5 LOGMAP
+
+ Logical line start bit map. These locations map the beginning
+ physical line number for each logical line on the screen (initially
+ 24, for GR.0). Each bit in the first three bytes shows the start of a
+ logical line if the bit equals one (three bytes equals eight bits *
+ three equals 24 lines on the screen). The map format is as follows:
+
+ Bit 7 6 5 4 3 2 1 0 Byte
+ ------------------------------------------------------------
+ Line 0 1 2 3 4 5 6 7 690
+ 8 9 10 11 12 13 14 15 691
+ 16 17 18 19 20 21 22 23 692
+ -- -- -- -- -- -- -- -- 693
+
+ The last byte is ignored. The map bits are all set to one when the
+ text screen is OPENed or CLEARed, when a GRAPHICS com-
+ mand is issued or RESET is pressed. The map is updated as
+ logical lines are entered, edited, or deleted.
+
+
+ 694 2B6 INVFLG
+
+ Inverse character flag; zero is normal and the initialization value
+ (i.e., normal ATASCII video codes have BIT 7 equals zero). You
+ POKE INVFLG with 128 ($80) to get inverse characters (BIT 7
+ equals one). This register is normally set by toggling the Atari
+ logo key; however, it can be user-altered. The display handler
+ XOR's the ATASCII codes with the value in INVFLG at all times.
+ See location 702 ($2BE) below.
+
+ INVFLG works to change the input, not the output. For example,
+ if you have A$ = "HELLO", POKE 694, 128 will not change A$
+ when you PRINT it to the screen. However, if you POKE 694, 128
+ before an INPUT A$, the string will be entered as inverse.
+
+
+ 695 2B7 FILFLG
+
+ Right fill flag for the DRAW command. If the current operation is
+ a DRAW, then this register reads zero. If it is non-zero, the
+ operation is a FILL.
+
+
+ 696 2B8 TMPROW
+
+ Temporary register for row used by ROWCRS (location 84; $54).
+
+
+ 697,698 2B9,2BA TMPCOL
+
+ Temporary register for column used by COLCRS (locations 85,
+ 86; $55, $56).
+
+
+ 699 2BB SCRFLG
+
+ Scroll flag; set if a scroll occurs. It counts the number of physical
+ lines minus one that were deleted from the top of the screen. This
+ moves the entire screen up one physical line for each line
+ scrolled off the top. Since a logical line has three physical lines,
+ SCRFLG ranges from zero to two.
+
+ Scrolling the text window is the equivalent to scrolling an entire
+ GR.0 screen. An additional 20-line equivalent of bytes (800) is
+ scrolled upwards in the memory below the text window address.
+ This can play havoc with any data such as P/M graphics you have
+ stored above RAMTOP
+
+
+ 700 2BC HOLD4
+
+ Temporary register used in the DRAW command only; used to
+ save and restore the value in ATACHR (location 763; $2FB)
+ during the FILL process.
+
+
+ 701 2BD HOLD5
+
+ Same as the above register.
+
+
+ 702 2BE SHFLOK
+
+ Flag for the shift and control keys. It returns zero for lowercase
+ letters, 64 ($40) for all uppercase (called caps lock: uppercase is
+ required for BASIC statements and is also the default mode on
+ powerup). SHFLOK will set characters to all caps during your
+ program if 64 is POKEd here. Returns the value 128 ($80;
+ control-lock) when the CTRL key is pressed. Forced control-lock
+ will cause all keys to output their control-code functions or
+ graphics figures. Other values POKEd here may cause the
+ system to crash. You can use this location with 694 ($2B6) above
+ to convert all keyboard entries to uppercase, normal display by:
+
+ 10 OPEN #2,4,0,"K:"
+ 20 GET #2,A
+ 30 GOSUB 1000
+ 40 PRINT CHR$(A);: GOTO 20
+ .
+ .
+ .
+ 1000 IF A = 155 THEN 1030: REM RETURN
+ KEY
+ 1010 IF A > = 128 THEN A = A - 128: R
+ EM RESTORE TO NORMAL DISPLAY
+ 1020 IF PEEK (702) = 0 AND A > 96 THEN
+ A = A - 32: REM LOWERCASE TO UP
+ PER
+ 1030 POKE 702,64: POKE 694,0
+ 1040 RETURN
+
+ DOWNLOAD SHFLOK.BAS
+
+
+ 703 2BF BOTSCR
+
+ Flag for the number of text rows available for printing. 24 ($18) is
+ normal for text mode GR.0; four for the text window, zero for all
+ graphics modes. In all GRAPHICS modes except zero, if there is
+ no text window then 703 will also read zero. The large-text
+ displays in GR.1 and GR.2 are treated as graphics displays for
+ this purpose. The display handler specifically checks for split-
+ screen mode by looking for the variable 24 or four here. If it finds
+ 24 here, it assumes there is no text window; if not, it looks for the
+ variable four.
+
+ You can add a text window to GR.0 by POKEing here with four.
+ The top portion (20 lines) of the screen will not scroll with the
+ bottom. To write to the top part of the screen you will have to use
+ the PRINT#6 statement as with modes one and two. One possible
+ application of this would be to keep a fixed menu at the top of the
+ screen while scrolling the bottom part, as done with the DOS
+ menu.
+
+ ---------------------------------------------------------------------------
+ Locations 704 to 712 ($2C0 to $2C8) are the color registers for players,
+ missiles, and playfields. These are the RAM shadow registers for
+ locations 53266 to 53274 ($D012 to $D01A). For the latter, you can use
+ the SETCOLOR command from BASIC. For all registers you can
+ POKE the desired color into the location by using this formula:
+
+ COLOR = HUE * 16 + LUMINANCE
+
+ It is possible to get more colors in GR.8 than the one (and a half) that
+ Atari says is possible by using a technique called artifacting. There is a
+ small example of artifacting shown at location 710 ($2C6). See De Re
+ Atari, Your Atari 400/800, Creative Computing, June 1981, and
+ COMPUTE!, May 1982.
+
+ Here are the 16 colors the Atari produces, along with their POKE
+ values for the color registers. The POKE values assume a luminance of
+ zero. Add the luminance value to the numbers to brighten the color.
+ The color registers ignore BIT 0; that's why there are no "odd" values
+ for luminance, just even values.
+
+ Color Value Color Value
+ Black 0, 0 Medium blue 8, 128
+ Rust 1, 16 Dark blue 9, 144
+ Red-orange 2, 32 Blue-grey 10, 160
+ Dark orange 3, 48 Olive green 11, 176
+ Red 4, 64 Medium green 12, 192
+ Dk lavender 5, 80 Dark green 13, 208
+ Cobalt blue 6, 96 Orange-green 14, 224
+ Ultramarine 7, 112 Orange 15, 240
+
+ The bit use of the PCOLR and COLOR registers is as follows:
+
+ Bit 7 6 5 4 3 2 1 0
+ --color-- luminance unused
+ Grey 0 0 0 0 0 0 0 Darkest
+ Rust 0 0 0 1 0 0 1
+ etc. to: etc. to:
+ Orange 1 1 1 1 1 1 1 Lightest
+
+ When you enable the color overlap at location 623 ($26F), ANTIC
+ performs a logical OR on the overlap areas. For example:
+
+ 01000010 Red, luminance two
+ OR 10011010 Darkblue,luminance ten
+ --------
+ Result = 10011010 Dark green, luminance ten
+
+ Here's a short machine language routine which will rotate the colors in
+ registers 705 to 712:
+
+ 10 DIM ROT$(30)
+ 20 FOR LOOP = 1 TO 27: READ BYTE: R
+ OT$(LOOP,LOOP) = CHR$(BYTE): NEXT
+ LOOP
+ .
+ . PUT YOUR GRAPHICS ROUTINE HERE
+ .
+ 100 CHANGE = USR(ADR(ROT$))
+ 105 FOR LOOP = 1 TO 200: NEXT LOOP:
+ GOTO 100
+ 110 DATA 104,162,0,172,193,2,189,194
+ ,2,157
+ 120 DATA 193,2,232,224,8,144,245,140
+ ,200,2
+ 130 DATA 96,65,65,65,65,65,65
+
+ If you wish to rotate the colors in registers 704 to 711 instead, change
+ lines 110 and 120 to read as follows:
+
+ 110 DATA 104,162,0,172,192,2,189,193
+ ,2,157
+ 120 DATA 192,2,232,224,8,144,245,140
+ ,199,2
+
+ DOWNLOAD BOTSCR.BAS
+
+ If you wish to include all of the registers 704 to 712 in the routine, make
+ the changes as above and change the eight in line 120 to nine and
+ restore the 199 to 200 in line 120. This routine works well with the
+ GTIA demos at location 623 ($26F).
+
+ For further detail, refer to your Atari BASIC Reference Manual, pp. 45
+ -56, and the GTIA Demo Disk from APX.
+
+
+ 704 2C0 PCOLR0
+
+ Color of player 0 and missile 0. Locations 704 to 707 are also
+ called COLPM# in some sources. This is the shadow for 53266
+ ($D012). In GTIA mode ten, 704 holds the background color
+ (BAK; normally held by 712). You cannot use the SETCOLOR
+ commands to change the PCOLR registers; color values must be
+ POKEd into them.
+
+
+ 705 2C1 PCOLR1
+
+ Color of player and missile 1. Shadow for 53267 ($D013).
+
+
+ 706 2C2 PCOLR2
+
+ Color of player and missile 2. Shadow for 53268 ($D014).
+
+
+ 707 2C3 PCOLR3
+
+ Color of player and missile 3. When the four missiles are
+ combined to make a fifth player, it takes on the color in location
+ 711 (COLOR3). Shadow for 53269 ($D015).
+
+
+ 708 2C4 COLOR0
+
+ Color register zero, color of playfield zero, controlled by the
+ BASIC SETCOLOR0 command. In GRAPHICS 1 and
+ GRAPHICS 2, this color is used for the uppercase letters.
+ Shadow for 53270 ($D016). You can change the values in all of
+ the COLOR registers from BASIC by using either the
+ SETCOLOR command or a POKE.
+
+
+ 709 2C5 COLOR1
+
+ The next four locations are the same as location 708 for the
+ different playfields and SETCOLOB commands. In GR.1 and
+ GR.2, this register stores the color for lowercase letters.
+ COLOR1 is also used to store the luminance value of the color
+ used in GR.0 and GR.8. Shadow for 53271 ($D017).
+
+
+ 710 2C6 COLOR2
+
+ The same as above for playfield two; in GR.1 and GR.2, this
+ register stores the color of the inverse uppercase letters. Shadow
+ for 53272 ($D018). Used for the background color in GR.0 and
+ GR.8. Both use COLOR1 for the luminance value.
+
+ Despite the official limitations of color selection in GR.8, it is
+ possible to generate additional colors by "artifacting", turning
+ on specific pixels (.5 color clock each) on the screen. Taking
+ advantage of the physical structure of the TV set itself, we
+ selectively turn on vertical lines of pixels which all show the same
+ color. For example:
+
+ 10 A = 40: B = 30: C = 70: D = 5: F
+ = 20 GRAPHICS 8: POKE 87,7: P0K
+ E 710,0: POKE 709,15: COLOR 1
+ 30 PLOT A,D: DRAWTO A,C: COLOR 2: P
+ LOT F,D: DRAWTO F,C:
+ 40 PLOT A + 1,D: DRAWTO A + 1,C
+ 50 COLOR 3: PLOT B,D: DRAWTO B,C
+ 60 GOTO 60
+
+ DOWNLOAD COLOR2.BAS
+
+ A little experimentation with this will show you that the colors
+ obtained depend on which pixels are turned on and how close
+ together the pixel columns are. There are four "colors" you can
+ obtain, as shown before. Pixels marked one are on; marked zero
+ means they are off. Each pair of pixels is one color clock. Three
+ color clocks are shown together for clarity:
+
+ 00:01:00 = color A 00:11:00 = color B
+ 00:10:00 = color C 00:01:10 = color D
+
+ See BYTE, May 1982, De Re Atari, and Your Atari 400/800.
+
+
+ 711 2C7 COLOR3
+
+ The same as the above but for playfield three. Also, the color for
+ GR.1 and GR.2 inverse lowercase letters. Shadow for 53273
+ ($D019).
+
+
+ 712 2C8 COLOR4
+
+ The same as the above but for the background (BAK) and border
+ color. Shadow for 53274 ($D01A). In GTIA mode ten, 704 stores
+ the background color (BAK), while 712 becomes a normal color
+ register.
+
+ Here are the default (powerup) values for the COLOR registers
+ (PCOL registers are all set to zero on powerup):
+
+ Register Color = Hue Luminance
+ 708 (CO.0) 40 2 8
+ 709 (CO.1) 202 12 10
+ 710 (CO.2) 148 9 4
+ 711 (CO.3) 70 4 6
+ 712 (CO.4) 0 0 0
+
+ ----------------------------------------------------------------------------
+ Locations 713 to 735 ($2C9 to $2DF) are spare bytes. Locations 736 to
+ 767 ($2E0 to $2FF) are for miscellaneous use.
+
+
+ 736-739 2E0-2E3 GLBABS
+
+ Global variables, or, four spare bytes for non DOS users. For
+ DOS users they are used as below:
+
+
+ 736-737 2E0-2E1 RUNAD
+
+ Used by DOS for the run address read from the disk sector one or
+ from a binary file. Upon completion of any binary load, control
+ will normally be passed back to the DOS menu. However, DOS
+ can be forced to pass control to any specific address by storing
+ that address here. If RUNAD is set to 40960 ($A000), then the left
+ cartridge (BASIC if inserted) will be called when the program is
+ booted.
+
+ With DOS 1.0, if you POKE the address of your binary load file
+ here, the file will be automatically run upon using the DOS
+ Binary Load (selection L). Using DOS 1.0's append (/A) option
+ when saving a binary file to disk, you can cause the load address
+ POKEd here to be saved with the data. In DOS 2.0, you may
+ specify the initialization and the run address with the program
+ name when you save it to disk (i.e.,
+ GAME.OBJ,2000,4FFF,4F00,4000). DOS 2.0 uses the /A option
+ to merge files. In order to prevent your binary files from running
+ automatically upon loading in DOS 2.0, use the /N appendage to
+ the file name when loading the file.
+
+ For users of CompuServe, there is an excellent little BASIC
+ program (with machine language subroutines) to create autoboot
+ files, chain machine language files with BASIC and to add an 850
+ autoboot file in the Popular Electronics Magazine (PEM) access
+ area. It is available free for downloading.
+
+
+ 738-739 2E2-2E3 INITAD
+
+ Initialization address read from the disk. An autoboot file must
+ load an address value into either RUNAD above or INITAD. The
+ code pointed to by INITAD will be run as soon as that location is
+ loaded. The code pointed to by RUNAD will be executed only
+ after the entire load process has been completed. To return
+ control to DOS after the execution of your program, end your
+ code with an RTS instruction.
+
+
+ 740 2E4 RAMSIZ
+
+ RAM size, high byte only; this is the number of pages that the top
+ of RAM represents (one page equals 256 bytes). Since there can
+ never be less than a whole page, it becomes practical to measure
+ RAM in those page units. This is the same value as in RAMTOP,
+ location 106 ($6A), passed here from TRAMSZ, location 6. Space
+ saved by moving RAMSIZ or RAMTOP has the advantage of
+ being above the display area. Initialized to 160 for a 48K Atari.
+
+
+ 741,742 2E5,2E6 MEMTOP
+
+ Pointer to the top of free memory used by both BASIC (which
+ calls it HIMEM) and the OS, passed here from TRAMSZ, location
+ 6 after powerup. This address is the highest free location in RAM
+ for programs and data. The value is updated on powerup, when
+ RESET is pressed, when you change GRAPHICS mode, or when
+ a channel (IOCB) is OPENed to the display. The display list starts
+ at the next byte above MEMTOP.
+
+ The screen handler will only OPEN the S: device if no RAM is
+ needed below this value (i.e. there is enough free RAM below
+ here to accommodate the requested GRAPHICS mode change).
+ Memory above this address is used for the display list and the
+ screen display RAM. Also, if a screen mode change would
+ extend the screen mode memory below APPMHI (locations 14,
+ 15: $E, $F), then the screen is set back for GR.0, MEMTOP is
+ updated, and an error is returned to the user. Otherwise the
+ mode change will take place and MEMTOP will be updated.
+
+ Space saved by moving MEMTOP is below the display list. Be
+ careful not to overwrite it if you change GRAPHICS modes in
+ mid-program. When using memory below MEMTOP for storage,
+ make sure to set APPMHI above your data to avoid having the
+ screen data descend into it and destroy it.
+
+
+ 743,744 2E7,2E8 MEMLO
+
+ Pointer to the bottom of free memory, initialized to 1792 ($700)
+ and updated by the presence of DOS or any other low-memory
+ application program. It is used by the OS; the BASIC pointer to
+ the bottom of free memory is at locations 128, 129 ($80, $81). The
+ value in MEMLO is never altered by the OS after powerup.
+
+ This is the address of the first free location in RAM available for
+ program use. Set after all FMS buffers have been allocated (see
+ locations 1801 and 1802; $709 and $70A). The address of the last
+ sector buffer is incremented by 128 (the buffer size in bytes) and
+ the value placed in MEMLO. The value updates on powerup or
+ when RESET is pressed. This value is passed back to locations
+ 128, 129 ($80, $81) on the execution of the BASIC NEW
+ command, but not RUN, LOAD or RESET.
+
+ If you are reserving space for your own device driver(s) or
+ reserving buffer space, you load your routine into the address
+ specified by MEMLO, add the size of your routine to the MEMLO
+ value, and POKE the new value plus one back into MEMLO.
+
+ When you don't have DOS or any other application program
+ using low-memory resident, MEMLO points to 1792 ($700. With
+ DOS 2.0 present, MEMLO points to 7420 ($1CFC). If you change
+ the buffer defaults mentioned earlier, you will raise or lower this
+ latter value by 128 ($80) bytes for every buffer added or deleted,
+ respectively. When you boot up the 850 Interface with or without
+ disk, you add another 1728 ($6C0) bytes to the value in MEMLO.
+
+ You can alter MEMLO to protect an area of memory below your
+ program. This is an alternative to protecting an area above
+ RAMTOP (location 106; $6A) and avoids the problem of the
+ CLEAR SCREEN routine destroying data. However, unless you
+ have created a MEM.SAV file, the data will be wiped out when
+ you call DOS. To alter MEMLO, you start by POKEing WARMST
+ (location 8) with zero, then doing a JMP to the BASIC cartridge
+ entry point at 40960($A000) after defining your area to protect.
+ For example, try this:
+
+ 10 DIM MEM$(24):PROTECT=700:REM NUMBE
+ R OF BYTES TO CHANGE
+ 15 HIBYTE=INT(PROTECT/256):LOBYTE=PRO
+ TECT-256*HIBYTE
+ 20 FOR N=1 TO 24:READ PRG:MEM$(N)=CHR
+ $(PRG):NEXT N
+ 30 MEM$(6,6)=CHR$(LOBYTE):MEM$(14,14)
+ =CHR$(HIBYTE)
+ 40 RESERVE=USR(ADR(MEM$))
+ 50 DATA 24,173,231,2,105,0,141,231,2,
+ 173,232,2,105
+ 60 DATA 0,141,232,2,169,0,133,8,76,0,
+ 160
+
+ DOWNLOAD MEMLO.BAS
+
+ You will find the address of your reserved memory by: PRINT
+ PEEK(743) + PEEK(744) * 256 before you run the program. This
+ program will wipe itself out when run. Altering MEMLO is the
+ method used by both DOS and the RS-232 port driver in the 850
+ Interface. See COMPUTE!, July 1981.
+
+
+ 745 2E9 ....
+
+ Spare byte.
+
+
+ 746-749 2EA-2ED DVSTAT
+
+ Four device status registers used by the I/O status operation as
+ follows:
+
+ 746 ($2EA) is the device error status and the command status
+ byte. If the operation is a disk I/O, then the status returned is that
+ of the 1771 controller chip in your Atari disk drive. Bits set to one
+ return the following error codes:
+
+ Bit Decimal Error
+ 0 1 An invalid command frame was received (error).
+ 1 2 An invalid data frame was received.
+ 2 4 An output operation was unsuccessful.
+ 3 8 The disk is write-protected.
+ 4 16 The system is inactive (on standby).
+ 7 32 The peripheral controller is "intelligent" (has its
+ own microprocessor: the disk drive). All Atari
+ devices are intelligent except the cassette
+ recorder, so BIT 7 will normally be one when a
+ device is attached.
+
+ 747 ($2EB) is the device status byte. For the disk, it holds the
+ value of the status register of the drive controller. For the 850
+ Interface, it holds the status for DSR,CTS,CRX and RCV when
+ concurrent I/O is not active (see the 850 Interface Manual). It also
+ contains the AUX2 byte value from the previous operation (see
+ the IOCB description at 832 to 959; $340 to $3AF).
+ 748 ($2EC) is the maximum device time-out value in seconds. A
+ value of 60 here represents 64 seconds. This value is passed back
+ to location 582 ($246) after every disk status request. Initialized to
+ 31.
+ 749 ($2ED) is used for number of bytes in output buffer. See 850
+ Manual, p. 43.
+ When concurrent I/O is active, the STATUS command returns
+ the number of characters in the input buffer to locations 747 and
+ 748, and the number of characters in the output buffer to location
+ 749.
+
+
+ 750,751 2EE,2EF CBAUDL/H
+
+ Cassette baud rate low and high bytes. Initialized to 1484
+ ($5CC), which represents a nominal 600 baud (bits per second).
+ After baud rate calculations, these locations will contain POKEY
+ values for the corrected baud rate. The baud rate is adjusted by
+ SIO to account for motor variations, tape stretch, etc. The
+ beginning of every cassette record contains a pattern of
+ alternating off/on bits (zero/one) which are used solely for speed
+ (baud) correction.
+
+
+ 752 2F0 CRSINH
+
+ Cursor inhibit flag. Zero turns the cursor on; any other number
+ turns the cursor off. A visible cursor is an inverse blank (space)
+ character. Note that cursor visibility does not change until the
+ next time the cursor moves (if changed during a program). If you
+ wish to change the cursor status without altering the screen data,
+ follow your CRSINH change with a cursor movement (i.e., up,
+ down) sequence. This register is set to zero (cursor restored) on
+ powerup, RESET, BREAK, or an OPEN command to either the
+ display handler (S:) or screen editor (E:). See location 755 for
+ another means to turn off the cursor.
+
+
+ 753 2F1 KEYDEL
+
+ Key delay flag or key debounce counter; used to see if any key
+ has been pressed. If a zero is returned, then no key has been
+ pressed. If three is returned, then any key. It is decremented
+ every stage two VBLANK (1/60 or 1/30th second) until it reaches
+ zero. If any key is pressed while KEYDEL is greater than zero, it
+ is ignored as "bounce." See COMPUTE!, December 1981, for a
+ routine to change the keyboard delay to suit your own typing
+ needs.
+
+
+ 754 2F2 CH1
+
+ Prior keyboard character code (most recently read and
+ accepted). This is the previous value passed from 764 ($2FC). If
+ the value of the new key code equals the value in CH1, then the
+ code is accepted only if a suitable key debounce delay has taken
+ place since the prior value was accepted.
+
+
+ 755 2F3 CHACT
+
+ Character Mode Register. Zero means normal inverse
+ characters, one is blank inverse characters (inverse characters
+ will be printed as blanks, i.e., invisible), two is normal
+ characters, three is solid inverse characters. Four to seven is the
+ same as zero to three, but prints the display upside down.
+ This register also controls the transparency of the cursor. It is
+ transparent with values two and six, opaque with values three
+ and seven. The cursor is absent with values zero, one, four and
+ five.
+
+ Toggling BIT 0 on and off can be a handy way to produce a
+ blinking effect for printed inverse characters (characters with
+ ATASCII values greater than 128 -- those that have BIT 7 set).
+ Shadow for 54273 ($D401). There is no visible cursor for the
+ graphics mode output. CHACT is initialized to two.
+ Here's an example of blinking text using this register:
+
+ 10 CHACT=755:REM USE INVERSE FOR WORD
+ S BELOW
+ 15 PRINT "[THIS IS A TEST OF BLINKING ]
+ [TEXT]"
+ 20 POKE CHACT,INT(RND(0)*4)
+ 30 FOR N=1 TO 100:NEXT N:GOTO 15
+
+ See COMPUTE!, December 1981.
+ Using a machine language routine and page six space, try:
+
+ 10 PAGE=1536:EXIT=1568
+ 20 FOR N=PAGE TO EXIT:READ BYTE:POKE
+ N,BYTE:NEXT N
+ 30 PGM=USR(PAGE)
+ 40 PRINT "[THIS] IS A [TEST] OF [BLINKING]
+ TEXT":REM MAKE SOME WORDS INVERSE
+ 50 GOTO 50
+ 60 DATA 104,169,17,141,40,2,169,6,141
+ ,41
+ 70 DATA 2,169,30,141,26,2,98,173,243,
+ 2
+ 80 DATA 41,1,73,1,141,243,2,169,30,14
+ 1,26,2,96
+
+ DOWNLOAD CHACT.BAS
+
+ The blink frequency is set .5 second; to change it, change the
+ 30 in line 80 to any number from one (1/30 second) to 255 (eight
+ .5 seconds). For another way to make the cursor visible or
+ invisible, see locations 752 above.
+
+
+ 756 2F4 CHBAS
+
+ Character Base Register, shadow for 54281 ($D409). The default
+ (initialization value) is 224 ($E0) for uppercase characters and
+ numbers; POKE CHBAS with 226 ($E2) to get the lowercase and
+ the graphics characters in GR.1 and GR.2. In GR.0 you get the
+ entire set displayed to the screen, but in GR.1 and GR.2, you
+ must POKE 756 for the appropriate half-set to be displayed.
+
+ How do you create an altered character set? First you must
+ reserve an area in memory for your set (512 or 1024 bytes; look at
+ location 106; $6A to see how). Then either you move the ROM set
+ (or half set, if that's all you intend to change) into that area and
+ alter the selected characters, or you fill up the space with bytes
+ which make up your own set. Then you POKE 756 with the MSB
+ of the location of your set so the computer knows where to find it.
+
+ What does an altered character set look like? Each character is a
+ block one byte wide by eight bytes high. You set the bits for the
+ points on the screen you wish to be "on" when displayed. Here
+ are two examples:
+
+ one byte wide:
+ 00100000 = 32 #
+ 00010000 = 16 #
+ 00010000 = 16 #
+ 00010000 = 16 #
+ 00011110 = 30 ####
+ 00000010 = 2 #
+ 00001100 = 12 ##
+ 00010000 = 16 #
+
+ Hebrew letter Lamed
+
+
+ one byte wide:
+ 10000001 = 129 # #
+ 10011001 = 153 # ## #
+ 10111101 = 189 # #### #
+ 11111111 = 255 ########
+ 11111111 = 255 ########
+ 10111101 = 189 # #### #
+ 10011001 = 153 # ## #
+ 10000001 = 129 # #
+
+ Tie-fighter
+
+ You can turn these characters into DATA statements to be POKEd
+ into your reserved area by using the values for the bytes as in the
+ above examples. To change the ROM set once it is moved, you
+ look at the internal code (see the BASIC Reference Manual, p.
+ 55) and find the value of the letter you want to replace--such as
+ the letter A--code 33. Multiply this by eight bytes for each code
+ number from the start of the set (33 * eight equals 264). You then
+ replace the eight bytes used by the letter A, using a FOR-NEXT
+ loop with the values for your own character. For example, add
+ these lines to the machine language found a few pages further on:
+
+ 1000 FOR LOOP=1 TO 4:READ CHAR:SET=CH
+ ACT+CHAR*8
+ 1010 FOR TIME=0 TO 7:READ BYTE:POKE S
+ ET+TIME,BYTE: NEXT TIME
+ 1020 NEXT LOOP
+ 1030 DATA 33,0,120,124,22,22,124,120,
+ 0
+ 1040 DATA 34,0,126,82,82,82,108,0,0
+ 1050 DATA 35,56,84,254,238,254,68,56,
+ 0
+ 1060 DATA 36,100,84,76,0,48,72,72,48
+ 2000 END
+
+ RUN it and type the letters A to D.
+ Why 224 and 226? Translated to hex, these values are $E0 and
+ $E2, respectively. These are the high bytes (MSB) for the location
+ of the character set stored in ROM: $E000 (57344) is the address
+ for the start of the set (which begins with punctuation, numbers
+ and uppercase letters), and $E200 (57856), for the second half of
+ the ROM set, lowercase and graphic control characters (both
+ start on page boundaries). The ROM set uses the internal order
+ given on page 55 of your BASIC Reference Manual, not the
+ ATASCII order. See also location 57344 ($E000).
+
+ You will notice that using the PRINT#6 command will show you
+ that your characters have more than one color available to them
+ in GR.1 and GR.2. Try PRINTing lowercase or inverse
+ characters when you are using the uppercase set. This effect can
+ be very useful in creating colorful text pages. Uppercase letters,
+ numbers, and special characters use color register zero (location
+ 708; $2C4 - orange) for normal display, and color register two
+ (710; $2C6 - blue) for inverse display. Lowercase letters use
+ register one (709; $2C5 - aqua) for normal display and register
+ three (711; $2C7 - pink) for inverse. See COMPUTE!, December
+ 1981, page 98, for a discussion of using the CTRL keys with letter
+ keys to get different color effects.
+
+ One problem with POKEing 756 with 226 is that there is no blank
+ space character in the second set: you get a screen full of hearts.
+ You have two choices: you can change the color of register zero
+ to the same as the background and lose those characters which
+ use register zero--the control characters--but get your blanks
+ (and you still have registers one, two and three left). Or you can
+ redefine your own set with a blank character in it. The latter is
+ obviously more work. See "Ask The Readers," COMPUTE!, July
+ 1982.
+
+ It is seldom mentioned in the manuals, but you cannot set 756 to
+ 225 ($El) or any other odd number. Doing so will only give you
+ screen garbage. The page number 756 points to must be evenly
+ divisible by two.
+
+ When you create your own character set and store it in memory,
+ you need to reserve at least 1K for a full character set (1024 bytes
+ --$400 or four pages), and you must begin on a page boundary.
+ In hex these are the numbers ending with $XX00 such as $C000
+ or $600 because you store the pointer to your set here in 756; it
+ can only hold the MSB of the address and assumes that the LSB is
+ always zero--or rather a page boundary. You can reserve
+ memory by:
+
+ POKE 106,PEEK(106)-4 (or any multiple of four)
+
+ And do a GRAPHICS command immediately after to have your
+ new memory value accepted by the computer. If you are using
+ only one half of the entire set, for GR.1 or GR.2, you need only
+ reserve 512 bytes, and it may begin on a .5K boundary (like
+ $E200; these are hexadecimal memory locations that end in
+ $X200). If you plan to switch to different character sets, you will
+ need to reserve the full 1K or more, according to the number of
+ different character sets you need to display. RAM for half-K sets
+ can be reserved by:
+
+ POKE 106,PEEK(106)-2 (or a multiple of two)
+
+ The location for your set will then begin at PEEK(106)*256.
+ Because BASIC cannot always handle setting up a display list for
+ GR.7 and GR.8 when you modify location 106 by less than 4K (16
+ pages), you may find you must use PEEK(106)-16. See location
+ 88,89 ($58,$59) and 54279 ($D407) for information regarding
+ screen use and reserving memory.
+
+ Make sure you don't have your character set overlap with your
+ player/missile graphics. Be very careful when using altered
+ character sets in high memory. Changing GRAPHICS modes, a
+ CLEAR command, or scrolling the text window all clear memory
+ past the screen display. When you scroll the text window, you
+ don't simply scroll the four lines; you actually scroll a full 24 (20
+ additional lines * 40 bytes equals 800 bytes scrolled past
+ memory)! This messes up the memory past the window display
+ address, so position your character sets below all possible
+ interference (or don't scroll or clear the screen).
+
+ You can create and store as many character sets as your memory
+ will allow. You switch back and forth between them and the ROM
+ set by simply POKEing the MSB of the address into 756. Of
+ course, you can display only one set at a time unless you use an
+ altered display list and DLI to call up other sets. There are no
+ restrictions outside of memory requirements on using altered
+ character sets with P/M graphics as long as the areas reserved for
+ them do not overlap.
+
+ A GRAPHICS command such as GR.0, RESET or a DOS call
+ restores the character set pointer to the ROM location, so you
+ must always POKE it again with the correct location of your new
+ set after any such command. A useful place to store these sets is
+ one page after the end of RAM, assuming you've gone back to
+ location 106 ($6A) and subtracted the correct number of pages
+ from the value it holds (by POKE 106,PEEK(106) minus the
+ number of pages to be reserved; see above). Then you can reset
+ the character set location by simply using POKE
+ 756,PEEK(106)+1 (the plus one simply makes sure you start at
+ the first byte of your set).
+
+ A full character set requires 1024 bytes (1K: four pages) be
+ reserved for it. Why? Because there are 128 characters, each
+ represented by eight bytes, so 128 * eight equals 1024. If you are
+ using a graphics mode that uses only half the character set, you
+ need only reserve 512 bytes (64 * eight equals 512). Remember to
+ begin either one on a page boundary (1K boundary for full sets or
+ .5K for half sets). By switching back and forth between two
+ character sets, you could create the illusion of animation.
+
+ Many magazines have published good utilities to aid in the
+ design of altered character sets, such as the January 1982
+ Creative Computing, and SuperFont in COMPUTE!, January
+ 1982. I suggest that you examine The Next Step from Online,
+ Instedit from APX, or FontEdit from the Code Works for very
+ useful set generators. One potentially useful way to alter just a
+ few of the characters is to duplicate the block of memory which
+ holds the ROM set by moving it byte by byte into RAM. A BASIC
+ FOR-NEXT loop can accomplish this, although it's very slow. For
+ example:
+
+ 5 CH=57344
+ 10 START=PEEK(106)-4:PLACE=START*256:
+ POKE 106,PEEK(106)-5:GRAPHICS 0: RE
+ M RESERVE EXTRA IN CASE OF SCREEN
+ CLEAR
+ 20 FOR LOOP=0 TO 1023:POKE PLACE+LOOP
+ ,PEEK(CH+LOOP):NEXT LOOP:REM MOVE
+ THE ROM SET
+ 30 POKE 756,PLACE/256:REM TELL ANTIC
+ WHERE CHSET IS
+
+ Here's a machine language routine to move the set:
+
+ 10 DIM BYTE$(80)
+ 15 REM MEM-1 TO PROTECT SET FROM CLEA
+ R SCREEN DESTRUCTION (SEE LOC.88)
+ 20 MEM=PEEK(106)-4:POKE 106,MEM-1: CHA
+ CT=MEM*256:GRAPHICS 0
+ 30 FOR LOOP=1 TO 32:READ PGM:BYTE$(LO
+ OP,LOOP)=CHR$(PGM):NEXT LOOP
+ 40 DATA 104,104,133,213,104,133,212
+ 50 DATA 104,133,215,104,133,214,162
+ 60 DATA 4,160,0,177,212,145,214
+ 70 DATA 200,208,249,230,213,230,215
+ 80 DATA 202,208,240,96
+ 90 Z=USR(ADR(BYTE$),224*256,CHACT)
+ .
+ . ADD YOUR OWN ALTERATION PROGRAM OR
+ THE EARLIER EXAMPLE HERE
+ .
+ .
+ 1500 POKE MEM-1,0:POKE 756,MEM
+
+ If you have Microsoft BASIC or BASIC A+, you can do this very
+ easily with the MOVE command!
+
+ Remember, when altering the ROM set, that the characters aren't
+ in ATASCII order; rather they are in their own internal order.
+ Your own set will have to follow this order if you wish to have the
+ characters correlate to the keyboard and the ATASCII values.
+ See page 55 of your BASIC Reference Manual for a listing of the
+ internal order. Creative Computing, January 1982, had a good
+ article on character sets, as well as a useful method of
+ transferring the ROM set to RAM using string manipulation. See
+ also "Using Text Plot for Animated Games" in COMPUTE!, April
+ 1982, for an example of using character sets for animated
+ graphics.
+
+
+ 757-761 2F5-2F9 ....
+
+ Spare bytes.
+
+
+ 762 2FA CHAR
+
+ Internal code value for the most recent character read or written
+ (internal code for the value in ATACHR below). This register is
+ difficult to use with PEEK statements since it returns the most
+ recent character; most often the cursor value (128, $80 for a
+ visible, zero for an invisible cursor).
+
+
+ 763 2FB ATACHR
+
+ Returns the last ATASCII character read or written or the value of
+ a graphics point. ATACHR is used in converting the ATASCII
+ code to the internal character code passed to or from CIO. It also
+ returns the value of the graphics point. The FILL and DRAW
+ commands use this location for the color of the line drawn,
+ ATACHR being temporarily loaded with the value in FILDAT,
+ location 765; $2FD. To force a color change in the line, POKE the
+ desired color number here (color * sixteen + luminance). To see
+ this register in use as character storage, try:
+
+ 10 OPEN#2,4,0,"K:"
+ 20 GET#2,A
+ 30 PRINT PEEK(763);" "; CHR$(A)
+ 40 GOTO 20
+
+ Make sure the PEEK statement comes before the PRINT CHR$
+ statement, or you will not get the proper value returned. When
+ the RETURN key is the last key pressed, ATACHR will show a
+ value of 155.
+
+
+ 764 2FC CH
+
+ Internal hardware value for the last key pressed. POKE CH with
+ 255 ($FF; no key pressed) to clear it. The keyboard handler gets
+ all of its key data from CH. It stores the value 255 here to indicate
+ the key code has been accepted, then passes the code to CH1,
+ location 754 ($2F2). If the value in CH is the same as in CH1, a
+ key code will be accepted only if the proper key debounce delay
+ time has transpired. If the code is the CTRL-1 combination (the
+ CTRL and the "1" keys pressed simultaneously), then the
+ start/stop flag at 767 ($2FF) is complemented, but the value is not
+ stored in CH. The auto repeat logic will also store store key
+ information here as a result of the continuous pressing of a key.
+ This is neither the ATASCII nor the internal code value; it is the
+ "raw" keyboard matrix code for the key pressed. The table for
+ translation of this code to ATASCII is on page 50 of the OS User's
+ Manual. In a two-key operation, BIT 7 is set if the CTRL key is
+ pressed, BIT 6 if the SHIFT key is pressed. The rest of the bytes
+ are the code (ignored if both BITs 7 and 6 are set). Only the code
+ for the last key pressed is stored here (it is a global variable for
+ keyboard).
+
+ When a read request is issued to the keyboard, CH is set to 255
+ by the handler routine. After a keycode has been read from this
+ register, it is reset to 255. BREAK doesn't show here, and CTRL
+ and SHIFT will not show here on their own. However, the inverse
+ toggle (Atari logo key), CAPS/LOWR, TAB and the ESC keys
+ will show by themselves. You can examine this register with:
+
+ 10 LOOK=PEEK(764)
+ 20 PRINT "KEY PRESSED = ";LOOK
+ 30 POKE 764,255
+ 40 FOR LOOP=1 TO 250:NEXT LOOP
+ 50 GOTO 10
+
+ See COMPUTE!'s First Book of Atari for an example of using this
+ register as a replacement for joystick input.
+
+
+ 765 2FD FILDAT
+
+ Color data for the fill region in the XIO FILL command.
+
+
+ 766 2FE DSPFLG
+
+ Display flag, used in displaying the control codes not associated
+ with an ESC character (see location 674; $2A2). If zero is
+ returned or POKEd here, then the ATASCII codes 27 - 31, 123 -
+ 127, 187 - 191 and 251 - 255 perform their normal display screen
+ control functions (i.e., clear screen, cursor movement,
+ delete/insert line, etc.). If any other number is returned, then a
+ control character is displayed (as in pressing the ESC key with
+ CTRL-CLEAR for a graphic representation of a screen clear).
+ POKEing any positive number here will force the display instead
+ of the control code action. There is, however, a small bug, not
+ associated with location 766, in Atari BASIC: a PRINTed CTRL-R
+ or CTRL-U are both treated as a semicolon.
+
+
+ 767 2FF SSFLAG
+
+ Start/stop display screen flag, used to stop the scrolling of the
+ screen during a DRAW or graphics routine, a LISTing or a
+ PRINTing. When the value is zero, the screen output is not
+ stopped. When the value is 255 ($FF; the one's complement), the
+ output to the screen is stopped, and the machine waits for the
+ value to become zero again before continuing with the scrolling
+ display. Normally SSFLAG is toggled by the user during these
+ operations by pressing the CTRL-1 keys combination to both start
+ and stop the scroll. Set to zero by RESET and powerup.
+
+ ---------------------------------------------------------------------------
+
+ PAGE THREE
+
+ Locations 768 to 831 ($300 to $33F) are used for the device handler and
+ vectors to the handler routines (devices S:, P:, E:, D:, C:, R: and K:).
+ A device handler is a routine used by the OS to control the transfer of
+ data in that particular device for the task allotted (such as read, write,
+ save, etc.). The resident D: handler does not conform entirely with the
+ other handler--SIO calling routines. Instead, you use the DCB to
+ communicate directly with the disk handler. The device handler for R:
+ is loaded in from the 850 interface module. See De Re Atari, the 850
+ Interface Manual, and the OS Listings pages 64 - 65.
+
+ Locations 768 to 779 ($300 to $30B) are the resident Device Control
+ Block (DCB) addresses, used for I/O operations that require the serial
+ bus; also used as the disk DCB. DUP.SYS uses this block to interface
+ the FMS with the disk handler. The Atari disk drive uses a serial access
+ at 19,200 baud (about 20 times slower than the Apple!). It has its own
+ microprocessor, a 6507, plus 128 bytes of RAM, a 2316 2K masked
+ ROM chip (like a 2716), a 2332 RAM-I/O timer chip with another 128
+ bytes of RAM (like the PIA chip) and a WD 1771 FD controller chip.
+ See the "Outpost Atari" column, Creative Computing, May 1982, for
+ an example of using the disk DCB.
+
+ All of the parameters passed to SIO are contained in the DCB. SIO
+ uses the DCB information and returns the status in the DCB for
+ subsequent use by the device handler.
+
+
+ 768 300 DDEVIC
+
+ Device serial bus ID (serial device type) set up by the handler,
+ not user-alterable. Values are:
+
+ Disk drives Dl - D4 49-52 ($31-$34)
+ Printer P1 64 ($40)
+ Printer P2 79 ($4F)
+ RS232 ports R1-R4 80-83 ($50-$53)
+
+
+ 769 301 DUNIT
+
+ Disk or device unit number: one to four, set up by the user.
+
+
+ 770 302 DCOMND
+
+ The number of the disk or device operation (command) to be
+ performed, set by the user or by the device handler prior to
+ calling SIO. Serial bus commands are:
+
+ Read 82 ($52)
+ Write (verily) 87 ($57)
+ Status 83 ($53)
+ Put (no verify) 80 (0)
+ Format 33 ($21)
+ Download 32 ($20)
+ Read address 84 ($54)
+ Read spin 81 ($51)
+ Motor on 85 ($55)
+ Verify sector 86 ($56)
+
+ All of the above are disk device commands, except write and
+ status, which are also printer commands (with no verify).
+
+
+ 771 303 DSTATS
+
+ The status code upon return to user. Also used to set the data
+ direction; whether the device is to send or receive a data frame.
+ This byte is used by the device handler to indicate to SIO what to
+ do after the command frame is sent and acknowledged. Prior to
+ the SIO call, the handler examines BIT 6 (one equals receive
+ data) and BIT 7 (one equals send data). If both bits are zero, then
+ no data transfer is associated with the operation. Both bits set to
+ one is invalid. SIO uses it to indicate to the handler the status of
+ the requested operation after the SIO call.
+
+
+ 772,773 304,305 DBUFLO/HI
+
+ Data buffer address of the source or destination of the data to be
+ transferred or the device status information (or the disk sector
+ data). Set by the user, it need not be set if there is no data
+ transferred, as in a status request.
+
+
+ 774 306 DTIMLO
+
+ The time-out value for the handler in one-second units, supplied
+ by the handler for use by SIO. The cassette time-out value is 35,
+ just over 37 seconds. The timer values are 64 seconds per 60 units
+ of measurement. Initialized to 31.
+
+
+ 775 307 DUNUSE
+
+ Unused byte.
+
+
+ 776,777 308,309 DBYTLO/HI
+
+ The number of bytes transferred to or from the data buffer (or the
+ disk) as a result of the most recent operation, set by the handler.
+ Also used for the count of bad sector data. There is a small bug in
+ SIO which causes incorrect system actions when the last byte in a
+ buffer is in a memory location ending with $FF, such as $A0FF.
+
+
+ 778,779 30A,30B DAUX1/2
+
+ Used for device specific information such as the disk sector
+ number for the read or write operation. Loaded down to locations
+ 572, 573 ($23C, $23D) by SIO.
+
+ There are only five commands supported by the disk handler:
+ GET sector (82; $52), PUT sector (80; $50), PUT sector with
+ VERIFY (87; $57), STATUS request (83; $53) and FORMAT entire
+ disk (33; $21). There is no command to FORMAT a portion of the
+ disk; this is done by the INS 1771-1 formatter/controller chip in
+ the drive itself and isn't user-accessible. There is a new disk drive
+ ROM to replace the current "C" version. It is the "E" ROM. Not
+ only is it faster than the older ROMs, but it also allows for
+ selective formatting of disk sectors. Atari has not announced yet
+ whether this new 810 ROM will be made available. For more
+ information, see the OS User's Manual.
+
+ Locations 780 to 793 ($30C to $319) are for miscellaneous use.
+ Locations 794 to 831 ($31A to $33F) are handler address tables. To use
+ these DCBs, the user must provide the required parameters to this
+ block and then do a machine language JSR to $E453 (58451) for disk
+ I/O or $E459 (58457; the SIO entry point) for other devices.
+
+
+ 780,781 30C,30D TIMER1
+
+ Initial baud rate timer value.
+
+
+ 782 30E ADDCOR
+
+ Addition correction flag for the baud rate calculations involving
+ the timer registers.
+
+
+ 783 30F CASFLG
+
+ Cassette mode when set. Used by SIO to control the program
+ flow through shared code. When set to zero, the current
+ operation is a standard SIO operation; when non-zero, it is a
+ cassette operation.
+
+
+ 784,785 310,311 TIMER2
+
+ Final timer value. Timer one and timer two contain reference
+ times for the start and end of the fixed bit pattern receive period.
+ The first byte of each timer contains the VCOUNT value (54283;
+ $D40B), and the second byte contains the current realtime clock
+ value from location 20 ($14). The difference between the timer
+ values is used in a lookup table to compute the interval for the
+ new values for the baud rate passed on to location 750, 751
+ ($2EE, $2EF).
+
+
+ 786,787 312,313 TEMP1
+
+ Two-byte temporary storage register used by SIO for the
+ VCOUNT calculation during baud timer routines. See location
+ 54283 ($D40B).
+
+
+ 788 314 TEMP2
+
+ Temporary storage register.
+
+
+ 789 315 TEMP3
+
+ Ditto.
+
+
+ 790 316 SAVIO
+
+ Save serial data-in port used to detect, and updated after, each
+ bit arrival. Used to retain the state of BIT 4 of location 53775
+ ($D20F; serial data-in register).
+
+
+ 791 317 TIMFLG
+
+ Time-out flag for baud rate correction, used to define an
+ unsuccessful baud rate value. Initially set to one, it is
+ decremented during the I/O operation. If it reaches zero (after
+ two seconds) before the first byte of the cassette record is read,
+ the operation will be aborted.
+
+
+ 792 318 STACKP
+
+ SIO stack pointer register. Points to a byte in the stack being
+ used in the current operation (locations 256 to 511; $100 to $1FF).
+
+
+ 793 319 TSTAT
+
+ Temporary status holder for location 48 ($30).
+
+
+ 794-831 31A-33F HATABS
+
+ Handler Address Table. Thirty-eight bytes are reserved for up to
+ 12 entries of three bytes per handler, the last two bytes being set
+ to zero. On powerup, the HATABS table is copied from ROM.
+ Devices to be booted, such as the disk drive, add their handler
+ information to the end of the table. Each entry has the character
+ device name (C,D,E,K,P,S,R) in ATASCII code and the handler
+ address (LSB/MSB). Unused bytes are all set to zero. FMS
+ searches HATABS from the top for a device "D:" entry, and when
+ it doesn't find it, it then sets the device vector at the end of the
+ table to point to the FMS vector at 1995 ($7CB). CIO searches for
+ a handler character from the bottom up. This allows new handlers
+ to take precedence over the old. Pressing RESET clears HATABS
+ of all but the resident handler entries!
+
+ 794 31A Printer device ID (P:), initialized to 58416 ($E430).
+ 797 31D Cassette device ID (C:), initialized to 58432 ($E440).
+ 800 320 Display editor ID (E:), initialized to 58368 ($E400).
+ 803 323 Screen handler ID (S:), initialized to 58384 ($E410).
+ 806 326 Keyboard handler ID (K:), initialized to 58400
+ ($E420).
+
+ HATABS unused entry points:
+ 809 ($329), 812 ($32C), 815 ($32F), 818 ($332), 821 ($335), 824
+ ($338), 827 ($33B), and 830 ($33E). These are numbered
+ sequentially from one to eight. There are only two bytes in the last
+ entry (unused), both of which are set to zero. When DOS is
+ present, it adds an entry to the table with the ATASCII code for
+ the letter "D" and a vector to address 1995 ($7CB).
+
+ The format for the HATABS table is:
+
+ Device name
+ Handler vector table address
+ More entries
+ Zero fill to the end of the table
+
+ The device handler address table entry above for the specific
+ handler points to the first byte (low byte/high byte) of the vector
+ table which starts at 58368 ($E400). Each handler is designed
+ with the following format:
+
+ OPEN vector
+ CLOSE vector
+ GET BYTE vector
+ PUT BYTE vector
+ GET STATUS vector
+ SPECIAL vector
+ Jump to initialization code (JMP LSB/MSB)
+
+ CIO uses the ZIOCB (see location 32; $20) to pass parameters to
+ the originating IOCB, the A, Y and X registers and CIO. It is
+ possible to add your own device driver(s) to OS by following
+ these rules:
+ 1) Load your routine, with necessary buffers at the address
+ pointed to by MEMLO: location 743 ($2E7).
+ 2) Add the size of your routine to the MEMLO value and POKE
+ the result back into MEMLO.
+ 3) Store the name and address of your driver in the handler
+ address table; HATABS.
+ 4) Change the vectors so that the OS will re-execute the above
+ steps if RESET has been pressed. This is usually done by
+ adjusting locations 12 ($C: DOSINIT) and 10 ($A; DOSVEC).
+
+ See the "Insight: Atari" columns in COMPUTE!, January and
+ April 1982, for details. The APX program "T: A Text Display
+ Device" is a good example of a device handler application.
+ See De Re Atari for more information on the DCB and HATABS,
+ including the use of a null handler.
+
+ ---------------------------------------------------------------------------
+ Locations 832 to 959 ($340 to $3BF) are reserved for the eight IOCB's
+ (input/output control blocks). IOCB's are channels for the transfer of
+ information (data bytes) into and out of the Atari, or between devices.
+ You use them to tell the computer what operation to perform, how
+ much data to move and, if necessary, where the data to be moved is
+ located. Each block has 16 bytes reserved for it.
+
+ What is an IOCB? Every time you PRINT something on the screen or
+ the printer, every time you LOAD or SAVE a file, every time you OPEN
+ a channel, you are using an IOCB. In some cases, operations have
+ automatic OPEN and CLOSE functions built in--like LPRINT. In
+ others, you must tell the Atari to do each step as you need it. Some
+ IOCB's are dedicated to specific use, such as zero for the screen
+ display. Others can be used for any I/O function you wish. The
+ information you place after the OPEN command tells CIO how you
+ want the data transferred to or from the device. It is SIO and the device
+ handlers that do the actual transfer of data.
+ You can easily POKE the necessary values into the memory locations
+ and use a machine language subroutine through a USR function to call
+ the CIO directly (you must still use an OPEN and CLOSE statement for
+ the channel, however). This is useful because BASIC only supports
+ either record or single byte data transfer, while the CIO will handle
+ complete buffer I/O. See the CIO entry address, location 58454
+ ($E456), for more details. These blocks are used the same way as the
+ page zero IOCB (locations 32 to 47; $20 to $2F). The OS takes the
+ information here, moves it to the ZIOCB for use by the ROM CIO, then
+ returns the updated information back to the user area when the
+ operation is done.
+ Note that when BASIC encounters a DOS command, it CLOSEs all
+ channels except zero. Refer to the Atari Hardware Manual and the 850
+ Interface Manual for more detailed use of these locations.
+
+
+ 832-847 340-34F IOCB0
+
+ I/O Control Block (IOCB) zero. Normally used for the screen
+ editor (E:). You can POKE 838,166 and POKE 839,238 and send
+ everything to the printer instead of to the screen (POKE 838,163,
+ and POKE 839,246 to send everything back to the screen again).
+ You could use this in a program to toggle back and forth between
+ screen and printed copy when prompted by user input. This will
+ save you multiple PRINT and LPRINT coding.
+
+ You can use these locations to transfer data to other devices as
+ well since they point to the address of the device's "put one byte"
+ routine. See the OS Manual for more information. Location 842
+ can be given the value 13 for read from screen and 12 for write to
+ screen. POKE 842,13 puts the Atari into "RETURN key mode" by
+ setting the auxiliary byte one (ICAX1) to screen input and
+ output. POKEing 842 with 12 returns it to keyboard input and
+ screen output mode. The former mode allows for dynamic use of
+ the screen to act upon commands the cursor is made to move
+ across.
+
+ You can use this "forced read" mode to read data on the screen
+ into BASIC without user intervention. For example, in the
+ program below, lines 100 through 200 will be deleted by the
+ program itself as it runs.
+
+ 10 GRAPHICS 0:POSITlON 2,4
+ 20 PRINT 100:PRINT 150:PRINT 200
+ 25 PRINT "CONT"
+ 30 POSITION 2,0
+ 50 POKE 842,13:STOP
+ 60 POKE 842,12
+ 70 REM THE NEXT LINES WILL BE DELETED
+ 100 PRINT "DELETING..."
+ 150 PRINT "DELETING..."
+ 200 PRINT "DELETED!"
+
+ DOWNLOAD FORCREAD.BAS
+
+ See COMPUTE!, August 1981, for a sample of this powerful
+ technique. See Santa Cruz's Tricky Tutorial #1 (display lists) for
+ another application. The last four bytes (844 to 847; $34C to $34F
+ in this case) are spare (auxiliary) bytes in all IOCB's.
+ When you are in a GRAPHICS mode other than zero, channel
+ zero is OPENed for the text window area. If the window is absent
+ and you OPEN channel zero, the whole screen returns to mode
+ zero. A BASIC NEW or RUN command closes all channels
+ except zero. OPENing a channel to S: or E: always clears the
+ display screen.
+ See COMPUTE!, October 1981,for an example of using an IOCB
+ with the cassette program recorder, and September 1981 for
+ another use with the Atari 825 printer.
+
+
+ 848-863 350-35F IOCB1
+
+ IOCB one.
+
+
+ 864-879 360-36F IOCB2
+
+ IOCB two.
+
+
+ 880-895 370-37F IOCB3
+
+ IOCB three.
+
+
+ 896-911 380-38F IOCB4
+
+ IOCB four.
+
+
+ 912-927 390-39F IOCB5
+
+ IOCB five.
+
+
+ 928-943 3A0-3AF IOCB6
+
+ IOCB six. The GRAPHICS statement OPENs channel six for
+ screen display (S:), so once you are out of mode zero, you cannot
+ use channel six unless you first issue a CLOSE#6 statement. If
+ you CLOSE this channel, you will not be able to use the
+ DRAWTO, PLOT or LOCATE commands until you reOPEN the
+ channel. The LOAD command closes channel six; it also closes
+ all channels except zero.
+
+
+ 944-959 3B0-3BF IOCB7
+
+ IOCB seven. LPRINT automatically uses channel seven for its
+ use. If the channel is OPEN for some other use and an LPRINT is
+ done, an error will occur, the channel will be CLOSEd, and
+ subsequent LPRINTs will work. The LIST command also uses
+ channel seven, even if channel seven is already OPEN. However,
+ when the LIST is done, it CLOSEs channel seven. The LOAD
+ command uses channel seven to transfer programs to and from
+ the recorder or disk. LIST (except to the display screen), LOAD
+ and LPRINT also close all sound voices. The RUN from tape or
+ disk and SAVE commands use channel seven, as does LIST.
+ The bytes within each IOCB are used as follows:
+
+ Label Offset Bytes Description
+ --------------------------------------------------------------------
+ ICHID 0 1 Index into the device name
+ table for the currently OPEN file. Set by the OS. If not in use, the
+ value is 255 ($FF), which is also the initialization value.
+
+ ICDNO 1 1 Device number such as one
+ for Dl: or two for D2:. Set by the OS.
+
+ ICCOM 2 1 Command for the type of
+ action to be taken by the device, set by the user. This is the first
+ variable after the channel number in an OPEN command. See
+ below for a command summary. Also called ICCMD.
+
+ ICSTA 3 1 The most recent status
+ returned by the device, set by the OS. May or may not be the
+ same value as that which is returned by the STATUS request in
+ BASIC. See the OS User's Manual, pp. 165-166, fora list of status
+ byte values.
+
+ ICBAL/H 4,5 2 Two-byte (LSB,MSB) buffer
+ address for data transfer or the address of the file name for OPEN,
+ STATUS, etc.
+
+ ICPTL/H 6,7 2 Address of the device's put-
+ one-byte routine minus one. Set by the OS at OPEN command,
+ but not actually used by the OS (it is used by BASIC, however).
+ Points to CIO's "IOCB NOT OPEN" message at powerup.
+
+ ICBLL/H 8,9 2 Buffer length set to the
+ maximum number of bytes to transfer in PUT and GET
+ operations. Decremented by one for each byte transferred;
+ updated after each READ or WRITE operation. Records the
+ number of bytes actually transferred in and out of the buffer after
+ each operation.
+
+ ICAX1 10 1 Auxiliary byte number one,
+ referred to as AUX1. Used in the OPEN statement to specify the
+ type of file access: four for READ, eight for WRITE, twelve for
+ both (UPDATE). Not all devices can use both kinds of operations.
+ This byte can be used in user-written drivers for other purposes
+ and can be altered in certain cases once the IOCB has been
+ OPENed (see the program example above). For the S: device, if
+ AUX1 equals 32, it means inhibit the screen clear function when
+ changing GRAPHICS modes. Bit use is as follows for most
+ applications:
+ Bit 7 6 5 4 3 2 1 0
+ Use ....unused.... W R D A
+
+ W equals write, R equals read, D equals directory, A equals
+ append.
+
+ ICAX2 11 1 Auxiliary byte two, referred
+ to as AUX2. Special use by each device driver; some serial port
+ functions may use this byte. Auxiliary bytes two to five have no
+ fixed use; they are used to contain device-dependent and/or
+ user-established data.
+
+ ICAX3/4 12,13 2 Auxiliary bytes three and
+ four; used to maintain a record of the disk sector number for the
+ BASIC NOTE and POINT commands.
+
+ ICAX5 14 1 Auxiliary byte five. Used by
+ NOTE and POINT to maintain a record of the byte within a sector.
+ It stores the relative displacement in sector from zero to 124
+ ($7C). Bytes 125 and 126 of a sector are used for sector-link
+ values, and byte 127 ($7F) is used as a count of the number of
+ data bytes in actual use in that sector.
+
+ ICAX6 15 1 Spare auxiliary byte.
+
+ Offset is the number you would add to the start of the IOCB in
+ order to POKE a value into the right field, such as POKE 832 +
+ OFFSET, 12.
+
+ The following is a list of the values associated with OPEN
+ parameter number 1. Most of these values are listed in Your Atari
+ 400/800. These are the values found in ICAX1, not the ICCOM
+ values.
+
+ Device Task # Description
+ ----------------------------------------------------------------------
+ Cassette 4 Read
+ recorder 8 Write (can do either, not both)
+
+ Disk 4 Read
+ file 6 Read disk directory
+ 8 Write new file. Any file OPENed in
+ this mode will be deleted, and the first byte written will be at the
+ start of the file.
+ 9 Write--append. In this mode the
+ file is left intact, and bytes written are put at the end of the file.
+ 12 Read and write--update. Bytes
+ read or written will start at the first byte in the file.
+
+ D: if BIT 0 equals one and BIT 3 equals one in AUX1,then
+ operation will be appended output.
+
+ Screen 8 Screen output
+ editor 12 Keyboard input and screen output
+ (E:) 13 Screen input and output
+
+ E: BIT 0 equals one is a forced read (GET command).
+
+ Keyboard 4 Read
+
+ Printer 8 Write
+
+ RS-232 5 Concurrent read
+ serial 8 Block write
+ port 9 Concurrent write
+ 13 Concurrent read and write
+
+ Clear Text Read
+ Screen Window Oper-
+ after GR. also ation
+
+ Screen 8 yes no no
+ display 12 yes no yes
+ (S:) 24 yes yes no
+ 28 yes yes yes
+ 40 no no no
+ 44 no no yes
+ 56 no yes no
+ 60 no yes yes
+
+ Note that with S:, the screen is always cleared in GR.0 and there
+ is no separate text window in GR.0 unless specifically user-
+ designed. Without the screen clear, the previous material will
+ remain on screen between GRAPHICS mode changes, but will
+ not be legible in other modes. The values with S: are placed in
+ the first auxiliary byte of the IOCB. All of the screen values above
+ are also a write operation.
+
+ The second parameter in an OPEN statement (placed in the
+ second auxiliary byte) is far more restricted in its use. Usually set
+ to zero. If set to 128 ($80) for the cassette, it changes from normal
+ to short inter-record gaps (AUX2).
+
+ With the Atari 820 printer, 83 ($53; AUX byte two) means
+ sideways characters (Atari 820 printer only). Other printer
+ variables (all for AUX2 as well) are: 70 ($4E) for normal 40
+ character per line printing and 87 ($57) for wide printing mode.
+ With the screen (S:), a number can be used to specify the
+ GRAPHICS modes zero through eleven. If mode zero is chosen,
+ then the AUX1 options as above are ignored.
+ For the ICCOM field, the following values apply (BASIC XIO
+ commands use the same values):
+
+ Command Decimal Hex
+ ----------------------------------------------------------------------
+ Open channel 3 3
+ Get text record (line) 5 5 BASIC:
+ INPUT
+ #n,A
+ Get binary record (buffer) 7 7 BASIC:
+ GET #n,A
+ Put text record (line) 9 9
+ Put binary record (buffer) 11 B BASIC:
+ PUT #n,A
+ Close 12 C
+ Dynamic (channel) status 13 D
+
+ BASIC uses a special "put byte" vector in the IOCB to talk
+ directly to the handler for the PRINT#n,A$ command.
+ Disk File Management System Commands (BASIC XIO
+ command):
+
+ Rename 32 20
+ Erase (delete) 33 21
+ Protect (lock) 35 23
+ Unprotect (unlock) 36 24
+ Point 37 25
+ Note 38 26
+ Format 254 FE
+
+ In addition, XIO supports the following commands:
+
+ Get character 7 7
+ Put character 11 B
+ Draw line 17 11 Display
+ handler
+ only.
+ Fill area 18 12 Display
+ handler
+ only.
+
+ FILL is done in BASIC with XIO 18,#6,12,0,"S:" (see the BASIC
+ Reference Manual for details).
+
+ For the RS-232 (R:), XIO supports:
+
+ Output partial block 32 20
+ Control RTS,XMT,DTR 34 22
+ Baud, stop bits, word size 36 24
+ Translation mode 38 26
+ Concurrent mode 40 28
+
+ (see the 850 Interface Manual for details)
+
+ CIO treats any command byte value greater than 13 ($D) as a
+ special case, and transfers control over to the device handler for
+ processing. For more information on IOCB use, read Bill
+ Wilkinson's "Insight: Atari" columns in COMPUTE!, November
+ and December 1981, and in Microcomputing, August 1982. Also
+ refer to the OS User's Manual and De Re Atari.
+
+ ---------------------------------------------------------------------------
+
+ 960-999 3C0-3E7 PRNBUF
+
+ Printer buffer. The printer handler collects output from LPRINT
+ statements here, sending them to the printer when an End of Line
+ (EOL; carriage return) occurs or when the buffer is full. Normally
+ this is 40 characters. However, if an LPRINT statement generates
+ fewer than 40 characters and ends with a semicolon or 38
+ characters and ends with a comma, Atari sends the entire buffer
+ on each FOR-NEXT loop, the extra bytes filled with zeros. The
+ output of the next LPRINT statement will appear in column 41 of
+ the same line. According to the Operating System User's
+ Manual, the Atari supports an 80-column printer device called
+ P2:. Using OPEN and PUT statements to P2: may solve this
+ problem. Here is a small routine for a GR.0 BASIC screen dump:
+
+ 10 DIM TEXT$(1000): OPEN#2,4,0,"S:":
+ TRAP 1050
+ .
+ .
+ .
+ 1000 FOR LINE = 1 TO 24: POSITION PE
+ EK(82),LINE
+ 1010 FOR COL = 1 TO 38: GET#2,CHAR:
+ TEXT$(COL,COL)=CHR$(CHAR)
+ 1020 NEXT COL: GET#2,COL
+ 1030 LPRINT TEXT$
+ 1040 NEXT LINE
+ 1050 RETURN
+
+ You can use the PTABW register at location 201 ($C9) to set the
+ number of spaces between print elements separated by a comma.
+ The minimum number of spaces accepted is two. LPRINT
+ automatically uses channel seven for output. No OPEN statement
+ is necessary and CLOSE is automatic.
+
+ ---------------------------------------------------------------------------
+ Locations 1000 to 1020 ($3E8 to $3FC) are a reserved spare buffer
+ area.
+
+
+ 1021-1151 3FD-47F CASBUF
+
+ Cassette buffer. These locations are used by the cassette handler
+ to read data from and write data to the program (tape) recorder.
+ The 128 ($80) data bytes for each cassette record are stored
+ beginning at 1024 ($400 - page four). The current buffer size is
+ found in location 650 ($28A). Location 61 ($3D) points to the
+ current byte being written or read.
+ CASBUF is also used in the disk boot process; the first disk
+ record is read into this buffer.
+
+ A cassette record consists of 132 bytes: two control bytes set to 85
+ ($55; alternating zeros and ones) for speed measurement in the
+ baud rate correction routine; one control byte (see below); 128
+ data bytes (compared to 125 data bytes for a disk sector), and a
+ checksum byte. Only the data bytes are stored in the cassette
+ buffer. See De Re Atari for more ~nformaUon on the cassette
+ recorder.
+
+
+
+ CONTROL BYTE VALUES
+
+ Value Meaning
+ 250 ($FA) Partial record follows. The actual number of bytes is stored
+ in the last byte of the record (127).
+ 252 ($FC) Record full; 128 bytes follow.
+ 254 ($FE) End of File (EOF) record; followed by 128 zero bytes.
+
+ ---------------------------------------------------------------------------
+ Locations 1152 to 1791 ($480 to $6FF) are for user RAM (outer
+ environment) requirements, depending on the amount of RAM
+ available in the machine. Provided you don't use the FP package or
+ BASIC, you have 640 ($280) free bytes here.
+ Locations 1152 to 1279 ($480 to $4FF) are 128 ($80) spare bytes.
+ The floating point package, when used, requires locations 1406 to 1535
+ ($57E to $5FF).
+
+
+ 1406 57E LBPR1
+
+ LBUFF prefix one.
+
+
+ 1407 57F LBPR2
+
+ LBUFF prefix two.
+
+
+ 1408-1535 580-5FF LBUFF
+
+ BASIC line buffer; 128 bytes. Used as an output result buffer for
+ the FP to ASCII routine at 55526 ($D8E6). The input buffer is
+ pointed to by locations 243, 244 ($F3, $F4).
+
+
+ 1504 5E0 PLYARG
+
+ Polynomial arguments (FP use).
+
+
+ 1510-1515 5E6-5EB FPSCR
+
+ FP scratch pad use.
+
+
+ 1516-1535 5EC-5FF FPSCR1
+
+ Ditto. The end of the buffer is named LBFEND.
+
+ ---------------------------------------------------------------------------
+
+ 1536-1791 600-6FF ....
+
+ Page six: 256 ($FF) bytes protected from OS use. Page six is not
+ used by the OS and may be safely used for machine language
+ subroutines, special I/O handlers, altered character sets, or
+ whatever the user can fit into the space. Some problem may arise
+ when the INPUT statement retrieves more than 128 characters.
+ The locations from 1536 to 1663 ($600 to $67F) are then
+ immediately used as a buffer for the excess characters. To avoid
+ overflow, keep INPUT statements from retrieving more than 128
+ characters. The valFORTH implementation of fig-FORTH (from
+ ValPar International) uses all of page six for its boot code, so it is
+ not available for your use. However, FORTH allows you to
+ reserve other blocks of memory for similar functions. BASIC A+
+ uses locations $0600 - $67F.
+
+ ---------------------------------------------------------------------------
+ Locations 1792 to the address specified by LOMEM (locations
+ 128, 129; ($80, $81) - the pointer to BASIC low memory) are also
+ used by DOS and the File Management System (FMS). Refer to
+ the DOS source code and Inside Atari DOS for details. The
+ addresses which follow are those for DOS 2.0S, the official Atari
+ DOS at the time of this writing. Another DOS is available as an
+ alternative to DOS 2.0 -- K-DOS (TM), from K-BYTE (R). K-DOS
+ is not menu driven but command driven. It does not use all of the
+ same memory locations as the Atari DOS although it does use a
+ modified version of the Atari FMS. (Another command-driven
+ DOS, called OS/A+, is completely compatible with DOS 2.OS
+ and is available from OSS, the creators of DOS 2.0S.)
+
+
+ 1792-5377 700-1501
+
+ File management system RAM (pages seven to fifteen). FMS
+ provides the interface between BASIC or DUP and the disk
+ drive. It is a sophisticated device driver for all I/O operations
+ involving the D: device. It allows disk users to use the special
+ BASIC XIO disk commands (see the IOCB area 832 to 959: $340
+ to $3BF). It is resident in RAM below your BASIC RAM and
+ provides the entry point to DOS when called by BASIC.
+
+
+ 5440-13062 1540-3306
+
+ DUP.SYS RAM. The top will vary with the amount of buffer
+ storage space allocated to the drive and sector buffers.
+
+
+ 6780-7547 1A7C-1D7B
+
+ Drive buffers and sector-data buffers. The amount of memory will
+ vary with the number of buffers allocated.
+
+
+ 7548-MEMLO 1D7C-3306 (maximum)
+
+ Non-resident portion of DUP.SYS, DOS utility routines. DUP
+ provides the utilities chosen from the DOS menu page, not from
+ BASIC. It is not resident in RAM when you are using BASIC or
+ another cartridge; rather it is loaded when DOS is called from
+ BASIC or on autoboot powerup (and no cartridge supersedes it).
+ When DUP is loaded, it overwrites the lower portion of memory.
+ If you wish to save your program from destruction, you must have
+ created a MEM.SAV file on disk before you called DOS from your
+ program. See the DOS Reference Manual.
+
+ ---------------------------------------------------------------------------
+ Locations 1792 to 2047 ($700 to $7FF; page seven) are the user boot
+ area. MEMLO and LOMEM point to 1792 when no DOS or DUP
+ program is loaded. This area can then be used for your BASIC or
+ machine language programs. The lowest free memory address is 1792,
+ and programs may extend upwards from here. There is a one-page
+ buffer before the program space used for the tokenization of BASIC
+ statements, pointed to by locations 128, 129 ($80, $81). Actually a
+ program may start from any address above 1792 and below the screen
+ display list as long as it does not overwrite this buffer if it is a BASIC
+ program. Also, 1792 is the start of the FMS portion of DOS when
+ resident.
+
+ When software is booted, the MEMLO pointer at 743,744 ($2E7,$2E8)
+ in the OS data base (locations 512 to 1151; $512 to $47F) points to the
+ first free memory location above that software; otherwise, it points to
+ 1792. The DUP portion of DOS is partly resident here, starting at 5440
+ ($1540) and running to 13062 ($1540 to $3306). The location of the OS
+ disk boot entry routine (DOBOOT) is 62189 ($F2ED). The standard
+ Atari DOS 2.OS takes up sectors one through 83 ($53) on a disk. Sector
+ one is the boot sector. Sectors two through 40 ($28) are the FMS
+ portion, and sectors 41 ($29) through 83 are the DUP.SYS portion of
+ DOS. For more information, see the DOS and OS source listings and
+ Inside Atari DOS.
+
+ ---------------------------------------------------------------------------
+
+ FMS, DOS.SYS and DUP.SYS
+
+ Disk boot records (sector one on a disk) are read into 1792 ($700).
+ Starting from $700 (1792), the format is:
+
+ Byte Hex Label and use
+ 0 700 BFLAG: Boot flag equals zero (unused).
+ 1 701 BRCNT: Number of consecutive sectors to
+ read (if the file is DOS, then BRCNT equals
+ one).
+ 2,3 702,703 BLDADR: Boot sector load address ($700).
+ 4,5 704,705 BIWTARR: Initialization address.
+ 6 706 JMP XBCONT: Boot continuation vector; $4C
+ (76): JMP command to next address in bytes seven and eight.
+
+ 7,8 707,708 Boot read continuation address
+ (LSB/MSB).
+
+ 9 709 SABYTE: Maximum number of concurrently
+ OPEN files. The default is three (see 1801 below).
+
+ 10 70A DRVBYT: Drive bits: the maximum number
+ of drives attached to the system. The default is two (see 1802
+ below).
+
+ 11 70B (unused) Buffer allocation direction, set to
+ zero.
+
+ 12,13 70C,70D SASA: Buffer allocation start address. Points
+ to 1995 ($7CB) when DOS is loaded.
+
+ 14 70E DSFLG: DOS flag. Boot flag set to non-zero
+ Must be non-zero for the second phase of boot process. Indicates
+ that the file DOS.SYS has been written to the disk; zero equals no
+ DOS file, one equals 128 byte sector disk, two equals 256 byte
+ sector disk.
+
+ 15,16 70F,710 DFLINK: Pointer to the first sector of DOS.SYS
+ file.
+
+ 17 711 BLDISP: Displacement to the sector link byte
+ 125 ($7D). The sector link byte is the pointer to the next disk
+ sector to be read. If it is zero, the end of the file has been
+ reached.
+
+ 18,19 712,713 DFLADR: Address of the start of DOS.SYS
+ file.
+
+ 20+ 714+ Continuation of the boot load file. See the
+ OS User's Manual and Chapter 20 of Inside Atari DOS.
+
+ Data from the boot sector is placed in locations 1792 to 1916 ($700
+ to $77C). Data from the rest of DOS.SYS is located starting from
+ 1917 ($77D). All binary file loads start with 255 ($FF). The next
+ four bytes are the start and end addresses (LSB/MSB),
+ respectively.
+
+
+ 1801 709 SABYTE
+
+ This records the limit on the number of files that can be open
+ simultaneously. Usually set to three, the maximum is seven (one
+ for each available IOCB -- remember IOCB0 is used for the
+ screen display). Each available file takes 128 bytes for a buffer,
+ if you increase the number of buffers, you decrease your RAM
+ space accordingly. You can POKE 1801 with your new number to
+ increase or decrease the number of files and then rewrite DOS
+ (by calling DOS from BASIC and choosing menu selection "H")
+ and have this number as your default on the new DOS.
+
+
+ 1802 70A DRVBYT
+
+ The maximum number of disk drives in your system, the DOS 2.0
+ default value is two. The least four bits are used to record which
+ drives are available, so if you have drives one, three and four,
+ this location would read:
+
+ 00001101 or 13 in decimal.
+
+ Each drive has a separate buffer of 128 bytes reserved for it in
+ RAM. If you have more or less than the default (two), then POKE
+ 1802 with the appropriate number:
+
+ 1 drive = 1 BIT 0 Binary 00000001
+ 2 drives = 3 BITS 0 & 1 00000011
+ 3 drives = 7 BITS 0, 1 & 2 00000111
+ 4 drives = 15 BITS 0, 1, 2 & 3 00001111
+
+ This assumes you have them numbered sequentially. If not,
+ POKE the appropriate decimal translation for the correct binary
+ code: each drive is specified by one of the least four bits from one
+ in BIT 0 to four in BIT 3. If you PEEK (1802) and get back three,
+ for example, it means drives one and two are allocated, not three
+ drives.
+
+ You can save your modification to a new disk by calling up DOS
+ and choosing menu selection "H." This new DOS will then boot
+ up with the number of drives and buffers you have allocated. A
+ one-drive system can save 128 bytes this way (256 if one less data
+ buffer is chosen). See the DOS Manual, page G.87.
+
+
+ 1900 76C BSIO
+
+ Entry point to FMS disk sector I/O routines.
+
+
+ 1906 772 BSIOR
+
+ Entry point to the FMS disk handler (?).
+
+
+ 1913 779 ....
+
+ Write verify flag for disk I/O operations. POKE with 80 ($50) to
+ turn off the verify function, 87 ($57) to turn it back on. Disk write
+ without verify is faster, but you may get errors in your data. I
+ have had very few errors generated by turning off the verify
+ function, but even one error in critical material can destroy a
+ whole program. Be careful about using this location. You can
+ save DOS (as above with menu selection "H") without write verify
+ as your new default by writing DOS to a new disk. See the DOS
+ Manual, page F.85. K-DOS's write-verify flag is located at 1907
+ ($773).
+
+
+ 1995 7CB DFMSDH
+
+ Entry point to a 21-byte FMS device (disk) handler. The address
+ of this handler is placed in HATABS (locations 794 to 831; $31A
+ to $33F) by the FMS initialization routine. When CIO needs to
+ call an FMS function, it will locate the address of that function via
+ the handler address table. See Chapters 8-11 of Inside Atari
+ DOS, published by COMPUTE! Books.
+
+
+ 2016 7E0 DINT
+
+ FMS initialization routine. The entry point is 1995 ($7CB). DUP
+ calls FMS at this point. K-DOS uses the same location for its
+ initialization routine.
+
+
+ 2219 8AB DFMOPN
+
+ OPEN routines, including open for append, update, and output.
+
+
+ 2508 900 DFMPUT
+
+ PUT byte routines.
+
+
+ 2591 A1F WTBUR
+
+ Burst I/O routines.
+
+
+ 2592-2773 A20-AD5 ....
+
+ In COMPUTE!, May and July 1982, Bill Wilkinson discussed
+ BURST I/O, which should not take place when a file is OPEN for
+ update, but does, due to a minor bug in DOS 2.0 (see also Inside
+ Atari DOS, Chapter 12). This will cause update writes to work
+ properly, but update reads to be bad. The following POKEs will
+ correct the problem. Remember to save DOS back to a new disk.
+
+ POKE 2592,130 ($A20,82)
+ POKE 2593,19 ($A21,13)
+ POKE 2594,73 ($A22,49)
+ POKE 2595,12 ($A23,0C)
+ POKE 2596,240 ($A24,F0)
+ POKE 2597,36 ($A25,24)
+ POKE 2598,106 ($A26,6A)
+ POKE 2599,234 ($A27,EA)
+ POKE 2625,16 ($A41,10)
+ POKE 2773,31 ($AD5,1F)
+
+ (Note that the July 1982 issue of COMPUTE! contained a typo
+ where the value to be POKEd into 2773 was mistakenly listed as
+ 13, not 31!) Wilkinson points out that one way to completely
+ disable BURST I/O (useful in some circumstances such as using
+ the DOS BINARY SAVE to save the contents of ROM to disk!) is
+ by:
+
+ POKE 2606,0 ($A2E,0)
+
+ This, however, will make the system LOAD and SAVE files
+ considerably more slowly, so it's not recommended as a
+ permanent change to DOS.
+
+
+ 2751 ABF DFMGET
+
+ GET byte routines, including GET file routines.
+
+ 2817 B0l DFMSTA
+ Disk STATUS routines.
+
+
+ 2837 B15 DFMCLS
+
+ IOCB CLOSE routines.
+
+
+ 2983 BA7 DFMDDC
+
+ Start of the device-dependent command routines, including the
+ BASIC XIO special commands:
+
+
+ 3033 BD9 XRENAME
+
+ RENAME a file.
+
+
+ 3122 C32 XDELETE
+
+ DELETE a file.
+
+
+ 3196 C7C XLOCK, XUNLOCK
+
+ LOCK and UNLOCK files. UNLOCK routines begin at 3203
+ ($C83).
+
+
+ 3258 CBA XPOINT
+
+ BASIC POINT command.
+
+
+ 3331 D03 XNOTE
+
+ BASIC NOTE command. See the DOS Manual for information
+ regarding these two BASIC commands, and see De Re Atari for a
+ sample use.
+
+
+ 3352 D18 XFORMAT
+
+ Format the entire diskette.
+
+
+ 3501 DAD LISTDIR
+
+ List the disk directory.
+
+
+ 3742 E9E FNDCODE
+
+ File name decode, including wildcard validity test. The current
+ file name is pointed to by ZBUFP at locations 67, 68 ($43, $44).
+
+
+ 3783 EC7 ....
+
+ By POKEing the desired ATASCII value here, you can change
+ the wildcard character (*; ATASCII 42, $2A) used by DOS to any
+ other character of your choice. Your altered DOS can be saved
+ back to disk with DOS menu selection "H".
+
+
+ 3818,3822 EEA,EEE ....
+
+ By POKEing 3818 with 33 and 3822 with 123 ($21 ,$7B;), you can
+ modify DOS to accept file names with punctuation, numbers and
+ lowercase as valid; 33 is the low range of the ATASCII code and
+ 127 the high range (lower or higher values are control and
+ graphics codes and inverse characters). Of course, any
+ unmodified DOS still won't accept such file names. You could
+ actually change the range to any value from zero to 255 at your
+ discretion. This, however, may cause other problems with such
+ ATASCII codes as spaces and the wildcard (*; see above). Can
+ be saved back to disk with menu selection "H".
+
+
+ 3850 F0A FDSCHAR
+
+ Store the file name characters that result from the file name
+ decode routines.
+
+
+ 3873 F21 SFDIR
+
+ Directory search routines; search for the user-specified file
+ name.
+
+
+ 3988 F94 WRTNXS
+
+ Write data sector routine.
+
+
+ 4111 100F RDNXTS
+
+ Read data sector routine.
+
+
+ 4206 106E RDDIR
+
+ Read and write directory sector routines.
+
+
+ 4235 108B RDVTOC
+
+ Read or write the volume table of contents (VTOC) sectors.
+
+
+ 4293 10C5 FRESECT
+
+ Free sector(s) routine; returns the number of free sectors on a
+ disk that are available to the user.
+
+
+ 4358 1106 GETSECTOR
+
+ Get sector routine; retrieves a free sector for use from the disk.
+
+
+ 4452 1164 SETUP
+
+ SETUP -- initialization of the FMS parameters. Prepares FMS to
+ deal with the operation to be performed and to access a
+ particular file. See Inside Atari DOS, Chapter seven.
+
+
+ 4618 120A WRTDOS
+
+ Write new DOS.SYS file to disk routine, including new FMS file
+ to DOS.SYS file.
+
+
+ 4789 12B5 ERRNO
+
+ Start of the FMS error number table.
+
+
+ 4856-4978 12F8-1372 ....
+
+ Miscellaneous FMS storage area: sector length, drive tape, stack
+ level, file number, etc.
+
+
+ 4993-5120 1381-1400 FCB
+
+ Start of the FMS File Control Blocks (FCB's). FCB's are used to
+ store information about files currently being processed. The
+ eight FCB's are 16-byte blocks that correspond in a one-on-one
+ manner with the IOCB's. Each FCB consist of:
+
+ Label Bytes Purpose
+ FCBFNO 1 File number of the current file being
+ processed.
+
+ FCBOTC 1 Which mode the file has been OPENed for:
+ append is one, directory read is two, input is four, output is
+ eight, update is twelve.
+
+ SPARE 1 Not used.
+
+ FCBSLT 1 Flag for the sector length type; 128 or 256
+ bytes
+
+ FCBFLG 1 Working flag. If equal to 128 ($80), then the
+ file has been OPENed for output or append and may acquire new
+ data sectors. If the value is 64, then sector is in the memory buffer
+ awaiting writing to disk.
+
+ FCBMLN 1 Maximum sector data length; 125 or 253 bytes
+ depending on drive type (single or double density). The last
+ three sector bytes are reserved for sector link and byte count
+ data.
+
+ FCBDLN 1 Current byte to be read or modified in the
+ operation in a data sector.
+
+ FCBBUF 1 Tell FMS which buffer has been allocated
+ to the file being processed.
+
+ FCBCSN 2 Sector number of the sector currently in the
+ buffer.
+
+ FCBLSN 2 Number of the next sector in data chain.
+
+ FCBSSN 2 Starting sectors for appended data if the file
+ has been OPENed for append.
+
+ FCBCNT 2 Sector count for the current file.
+
+ DUP doesn't use these FCB's; it writes to the IOCB's directly.
+ CIO transfers the control to FMS as the operation demands, then
+ on to SIO.
+
+
+ 5121 1401 FILDIR
+
+ File directory, a 256 ($100) byte sequential buffer for entries to
+ the disk directory.
+
+
+ 5377 1501 ENDFMS
+
+ Disk directory (VTOC -- Volume Table Of Contents) buffer. 64
+ ($40) bytes are reserved, one byte for each possible file. It also
+ marks the end of FMS. The VTOC (sector 360; $168) is a
+ sequential bit map of each of the 720 sectors on the disk. It starts
+ at byte ten and continues through to byte 99. When a bit is set
+ (one), it indicates that the sector associated is in use.
+
+
+ 5440 1540 DOS
+
+ DUP.SYS initialization address. Beginning of mini-DOS; the
+ RAM-resident portion of DUP. Used for the same purpose in K-
+ DOS.
+
+
+ 5446,5450 1546,154A ....
+
+ Contains the location (LSB/MSB) of the DOS VEC (location 10;
+ $A). This is the pointer to the address BASIC will jump to when
+ DOS is called.
+
+
+ 5533 159D DUPFLG
+
+ Flag to test if DUP is already resident in memory. Zero equals
+ DUP is not there.
+
+
+ 5534 159E OPT
+
+ Used to store the value of the disk menu option chosen by the
+ user.
+
+
+ 5535 159F LOADFLG
+
+ If this location reads 128, then a memory file (MEM.SAV) file
+ doesn't have to be loaded.
+
+
+ 5540 15A4 SFLOAD
+
+ Routines to load a MEM.SAV file if it exists.
+
+
+ 5888 1700 USRDOS
+
+ Listed in the DUP.SYS equates file but never explained in the
+ listings.
+
+
+ 5899 170B MEMLDD
+
+ Flags that the MEM.SAV file has been loaded. Zero means it has
+ not been loaded.
+
+
+ 5947 173B ....
+
+ The MEM.SAV (MEMSAVE) file creation routines begin here.
+ They start with the file name MEM.SAV stored in ATASCII
+ format. The write routines begin at MWRITE, 5958 ($1746). The
+ DOS utility MEMSAVE copies the lower 6000 bytes of memory to
+ disk to save your BASIC program from being destroyed when
+ you call DOS, which then loads DUP.SYS into that area of
+ memory.
+
+
+ 6044,6045 179C-179D INISAV
+
+ DOSINI (see location 12, 13; $C, $D) vector save location. Entry
+ point to DOS on a call from BASIC.
+
+
+ 6046 179E MEMFLG
+
+ Flag to show if memory has been written to disk using a
+ MEM.SAV file.
+
+
+ 6418 1912 CLMJMP
+
+ Test to see if DOS must load MEM.SAV from the disk before it
+ does a run at cartridge address, then jumps to the cartridge
+ address.
+
+
+ 6432 1920 LMTR
+
+ Test to see if DOS must load MEM.SAV before it performs a run at
+ address command from the DOS menu.
+
+
+ 6457 1939 LDMEM
+
+ MEMSAVE load routines (for the MEM.SAV file).
+
+
+ 6518 1979 INITIO
+
+ DUP.SYS warmstart entry. An excellent program to eliminate the
+ need for DUP.SYS and MEM.SAV (not to mention the time
+ required to load them!) was presented in COMPUTE!, July 1982,
+ called MicroDOS; it's well worth examining. See also "The Atari
+ Wedge," COMPUTE!, December 1982.
+
+ 663C 19E6 ISRODN
+ Start of the serial interrupt service routine to output data needed
+ routines in DUP.SYS.
+
+
+ 6691 1A23 ISRSIR
+
+ Start of the serial interrupt ready service routines in DUP.SYS.
+
+
+ 6781 1A7D ....
+
+ Start of the drive and data buffers. Drive buffers are numbered
+ sequentially one to four, data buffers one to eight, assuming that
+ many are allocated for each. Normally, the first two buffers are
+ allocated for drives and the next three for data. Buffers are 128
+ ($80) bytes long each and start at 6908 ($1AFC), 7036 ($1B7C),
+ 7162 ($1BFA) and 7292 ($1C7C). See locations 1801 and 1802
+ ($709, $70A).
+
+
+ 7420 1CFC ....
+
+ MEMLO (743, 744; $2E7, $2E8) points here when DOS is resident
+ unless the buffer allocation has been altered. MEMLO will point
+ to 7164 for a one drive, two data buffer setup, a saving of 256
+ bytes. Loading the RS-232 handler from the 850 Interface will
+ move MEMLO up another 1728 bytes. The RS-232 handler in the
+ 850 Interface will only boot (load into memory) if you first boot
+ the AUTORUN.SYS file on your Atari master diskette or use
+ another RS-232 boot program such as a terminal package. The
+ RS-232 handler will boot up into memory if you do not have a disk
+ attached and you have turned it on before turning on the
+ computer. You may still use the printer (parallel) port on the 850
+ even if the RS-232 handler is not booted.
+
+
+ 7548 1D7C ....
+
+ Beginning of non-resident portion of DUP; 40 ($28) byte
+ parameter buffer.
+
+
+ 7588 1DA4 LINE
+
+ 80 ($50) byte line buffer.
+
+
+ 7668 1DF4 DBUF
+
+ 256 ($100) byte data buffer for COPY routines. Copy routines
+ work in 125-byte passes, equal to the number of data bytes in
+ each sector on the disk. There are 256 bytes because Atari had
+ planned a double density drive which has 253 data bytes in each
+ sector.
+
+
+ 7924 1EF4 ....
+
+ Miscellaneous variable storage area and data buffers.
+
+
+ 7951-8278 1F0F-2056 DMENU
+
+ Disk menu screen display data is stored here.
+
+
+ 8191 1FFF ....
+
+ This is the top of the minimum RAM required for operation (8K).
+ To use DOS, you must have a minimum of 16K.
+
+ ---------------------------------------------------------------------------
+
+ DUP.SYS ROUTINES
+
+ Locations 8192 to 32767 ($2000 to $7FFF) are the largest part of the
+ RAM expansion area; this space is generally for your own use. If you
+ have DOS.SYS or DUP.SYS loaded in, they also use a portion of this
+ area to 13062 ($3306) as below:
+
+
+ 8309 2075 DOSOS
+
+ Start of the DOS utility monitor, including the utilities called
+ when a menu selection function is completed and the display of
+ the "SELECT ITEM" message.
+
+
+ 8505 2139 DIRLST
+
+ Directory listing.
+
+
+ 8649 21C9 DELFIL
+
+ Delete a file.
+
+
+ 8990 231E ....
+
+ Copy a file. This area starts with the copy messages. The copy
+ routines themselves begin at PYFIL, 9080 ($2378).
+
+
+ 9783 2637 RENFIL
+
+ Rename a disk file routines.
+
+
+ 9856 2680 FMTDSK
+
+ Format the entire disk. There is no way to format specific sectors
+ of a disk with the "C" ROMs currently used in your 810 drives.
+ There is a new ROM, the "E" version, which not only allows
+ selective sector formatting, but is also considerably faster. It was
+ not known at the time of this writing whether Atari would release
+ the "E" version.
+
+
+ 9966 26EE STCAR
+
+ Start a cartridge.
+
+
+ 10060 274C BRUN
+
+ Run a binary file at the user-specified address.
+
+
+ 10111 277F ....
+
+ Start of the write MEM.SAV file to disk routine. The entry point is
+ at MEMSAV, 10138 ($279A).
+
+
+ 10201 27D9 WBOOT
+
+ Write DOS/DUP files to disk.
+
+
+ 10483 28F3 TESTVER2
+
+ Test for version two DOS. DOS.20S is the latest official DOS,
+ considerably improved over the earlier DOS 1.0. The S stands for
+ single density. Atari had planned to release a dual density drive
+ (the 815), but pulled it out of the production line at the last minute
+ for some obscure high-level reason. A double density drive is
+ available from the Percom company.
+
+
+ 10522 291A LDFIL
+
+ Load a binary file into memory. If it has a run address specified in
+ the file, it will autoboot.
+
+
+ 10608 2970 LKFIL, ULFIL
+
+ Lock and unlock files on a disk.
+
+
+ 10690 29C2 DDMG
+
+ Duplicate a disk.
+
+
+ 11528 2D08 DFFM
+
+ Duplicate a file.
+
+
+ 11841 2E41 ....
+
+ Miscellaneous subroutines.
+
+
+ 12078 2F2E SAVFIL
+
+ Save a binary file.
+
+
+ 12348 303C ....
+
+ Miscellaneous subroutines.
+
+
+ 13062 3306 ....
+
+ End of DUP.SYS.
+ The rest of RAM is available to location 32767 ($7FFF).
+
+ ---------------------------------------------------------------------------
+
+ CARTRIDGE B: 8K
+
+ Locations 32768 to 40959 ($8000 to $9FFF) are used by the right
+ cartridge (Atari 800 only), when present. When not present, this RAM
+ area is available for use in programs. When the 8K BASIC cartridge is
+ being used, this area most frequently contains the display list and screen
+ memory. As of this writing, the only cartridge that uses this slot is
+ Monkey Wrench from Eastern House Software.
+
+ It is possible to have 16K cartridges on the Atari by either combining
+ both slots using two 8K cartridges or simply having one with large
+ enough ROM chips and using one slot. In this case, the entire area from
+ 32768 to 49151 ($8000 to $BFFF) would be used as cartridge ROM.
+
+ Technically, the right cartridge slot is checked first for a resident
+ cartridge and initialized, then the left. You can confirm this by putting
+ the Assembler Editor cartridge in the right and BASIC in the left slots.
+ BASIC will boot, but not the ASED. Using FRE(0), you will see,
+ however, that you have 8K less RAM to use; and PEEKing through this
+ area will show that the ASED program is indeed in memory, but that
+ control was passed to BASIC. Control will pass to the ASED cartridge if
+ the cartridges are reversed. This is because the last six bytes of the
+ cartridge programs tell the OS where the program begins -- in both
+ cases, it is a location in the area dedicated to the left cartridge. The six
+ bytes are as follows:
+
+ Byte Purpose
+ Left (A) Right(B)
+ 49146 ($BFFA) 40954 ($9FFA) Cartridge start address (low byte)
+ 49147 ($BFFB) 40955 ($9FFB) Cartridge start address (high byte)
+ 49148 ($BFFC) 40956,($9FFC) Reads zero if a cartridge is
+ inserted, non-zero when no cartridge is present. This information
+ is passed down to the page zero RAM: if the A cartridge is plugged
+ in, then location 6 will read one; if the B cartridge is plugged in,
+ then location 7 will read one; otherwise they will read zero.
+ 49149 ($BFFD) 40957 ($9FFD) Option byte. If BIT 0 equals one,
+ then boot the disk (else there is no disk boot). If BIT 2 equals one,
+ then initialize and start the cartridge (else initialize but do not
+ start). If BIT 7 equals one, then the cartridge is a diagnostic
+ cartridge which will take control, but not initialize the OS (else
+ non-diagnostic cartridge). Diagnostic cartridges were used by
+ Atari in the development of the system and are not available to the
+ public.
+ 49150 ($BFFE) 40958 ($9FFE) Cartridge initialization address
+ low byte.
+ 49151 ($BFFF) 40959 ($9FFF) Cartridge initialization address
+ high byte. This is the address to which the OS will jump during all
+ powerup and RESETs.
+
+ The OS makes temporary use of locations 36876 to 36896 ($900C to
+ $9020) to set up vectors for the interrupt handler. See the OS
+ listings pages 31 and 81. This code was only used in the
+ development system used to design the Atari.
+
+ ---------------------------------------------------------------------------
+
+ CARTRIDGE A: 8K
+
+ Locations 40960 to 49151 ($A000 to $BFFF) are used by the left
+ cartridge, when present. When not present, this RAM area is available
+ for other use. The display list and the screen display data will be in this
+ area when there is no cartridge present.
+
+ Most cartridges use this slot (see above) including the 8K BASIC,
+ Assembler-Editor, and many games. Below are some of the entry
+ points for the routines in Atari 8K BASIC. There is no official Atari
+ listing of the BASIC ROM yet. Many of the addresses below are listed
+ in Your Atari 400/800. Others have been provided in numerous
+ magazine articles and from disassembling the BASIC cartridge.
+
+
+ BASIC ROUTINES
+
+ 40960-41036 A000-A04C
+ Cold start.
+
+ 41037-41055 A04D-A05F
+ Warm start.
+
+ 41056-42081 A060-A461
+ Syntax checking routines.
+
+ 42082-42158 A462-A4AE
+ Search routines.
+
+ 42159-42508 A4AF-A60C
+ STATEMENT name table. The statement TOKEN list begins at 42161
+ ($A4B1). You can print a list of these tokens by:
+
+ 5 ADDRESS = 42161
+ 10 IF NOT PEEK(ADDRESS) THEN PRINT:
+ END
+ 15 PRINT TOKEN,
+ 20 BYTE = PEEK(ADDRESS): ADDRESS = A
+ DDRESS + 1
+ 30 IF BYTE < 128 THEN PRINT CHR$(BYT
+ E);: GOTO 20
+ 40 PRINT CHR$(BYTE - 128)
+ 50 ADDRESS = ADDRESS + 2: TOKEN = TO
+ KEN + 1: GOTO 10
+
+ DOWNLOAD STATMENT.BAS
+
+ 42509-43134 A60D-A87E
+ Syntax tables. The OPERATOR token list begins at 42979 ($A7E3). You
+ can print a list of these tokens by:
+
+ 5 ADDRESS = 42979: TOKEN = 16
+ 10 IF NOT PEEK (ADDRESS) THEN PRINT:
+ END
+ 15 PRINT TOKEN,
+ 20 BYTE = PEEK(ADDRESS): ADDRESS = A
+ DDRESS + 1
+ 30 IF BYTE < 128 THEN PRINT CHR$(BYT
+ E);: GOTO 20
+ 40 PRINT CHR$(BYTE - 128)
+ 50 TOKEN = TOKEN + 1
+ 60 GOTO 10
+
+ DOWNLOAD OPERATOR.BAS
+
+ See COMPUTE!, January and February 1982; BYTE, February 1982,
+ and De Re Atari for an explanation of BASIC tokens.
+
+ 43135-43358 A87F-A95E
+ Memory manager.
+
+ 43359-43519 A95F-A9FF
+ Execute CONT statement.
+
+ 43520-43631 AA00-AA6F
+ Statement table.
+
+ 43632-43743 AA70-AADF
+ Operator table.
+
+ 43744-44094 AAE0-AC3E
+ Execute expression routine.
+
+ 44095-44163 AC3F-AC83
+ Operator precedence routine.
+
+ 44164-45001 AC84-AFC9
+ Execute operator routine.
+
+ 45002-45320 AFCA-B108
+ Execute function routine.
+
+ 45321-47127 B109-B817
+ Execute statement routine.
+
+ 47128-47381 B818-B915
+ CONT statement subroutines.
+
+ 47382-47542 B916-B9B6
+ Error handling routines.
+
+ 47543-47732 B9B7-BA74
+ Graphics handling routines.
+
+ 47733-48548 BA75-BDA4
+ I/O routines.
+
+ 48549-49145 BDA5-BFF9
+ Floating point routines (see below).
+
+
+ 48551 BDA7 SIN
+
+ Calculate SIN(FR0). Checks DEGFLG (location 251; $FB) to see if
+ trigonometric calculations are in radians (DEGFLG equals zero)
+ or degrees (DEGFLG equals six).
+
+
+ 48561 BDB1 COS
+
+ Calculate Cosine (FR0) with carry. FR0 is Floating Point register
+ zero, locations 212-217; $D4-$D9. See the Floating Point package
+ entry points from location 55296 on.
+
+
+ 48759 BE77 ATAN
+
+ Calculate Atangent using FR0, with carry.
+
+
+ 48869 BEE5 SQR
+
+ Calculate square root (FR0) with carry.
+ Note that there is some conflict of addresses for the above
+ routines. The addresses given are from the first edition of De Re
+ Atari. The Atari OS Source Code Listing gives the following
+ addresses for these FP routines:
+
+ These are entry points, not actual start addresses.
+
+ SIN 48513 ($BD81)
+ COS 48499 ($BD73)
+ ATAN 48707 ($BE43)
+ SQR 48817 ($BEB1)
+
+ However, after disassembling the BASIC ROMs, I found that the
+ addresses in De Re Atari appear to be correct.
+
+ 49146,7 BFFA,B
+ Left cartridge start address.
+
+ 49148 BFFC
+ A non-zero number here tells the OS that there is no cartridge in
+ the left slot.
+
+ 49149 BFFD
+ Option byte. A cartridge which does not specify a disk boot may
+ use all of the memory from 1152 ($480) to MEMTOP any way it sees
+ fit.
+
+ 49150,1 BFFE,F
+ Cartridge initialization address. See the above section on the right
+ slot, 32768 to 40959, for more information.
+
+ ---------------------------------------------------------------------------
+ When a BASIC program is SAVEd, only 14 of the more than 50
+ page zero locations BASIC uses are written to the disk or cassette
+ with the program. The rest are all recalculated with a NEW or
+ SAVE command, sometimes with RUN or GOTO. These 14
+ locations are:
+
+ 128,129 80,81 LOMEM
+ 130,131 82,83 VNTP
+ 132,133 84,85 VNTD
+ 134,135 86,87 VVTP
+ 136,137 88,89 STMTAB
+ 138,139 8A,8B STMCUR
+ 140,141 8C,8D STARP
+
+ The string/array space is not loaded; STARP is included only to
+ point to the end of the BASIC program.
+ The two other critical BASIC page zero pointers, which are not
+ SAVEd with the program, are:
+
+ 142,143 8E,8F RUNSTK
+ 144,145 90,91 MEMTOP
+
+ For more information concerning Atari BASIC, see the appendix.
+ For detailed description, refer to the Atari BASIC Reference
+ Manual. For more technical information, see De Re Atari, BYTE,
+ February 1982, and COMPUTE!'s First Book of Atari and
+ COMPUTE!'s Second Book of Atari.
+
+ ---------------------------------------------------------------------------
+ Locations 49152 to 53247 ($C000 to $CFFF) are unused.
+ Unfortunately, this rather large 4K block of memory cannot be written
+ to by the user, so it is presently useless. Apparently, this area of ROM
+ is reserved for future expansion. Rumors abound about new Atari OS's
+ that allow 3-D graphics, 192K of on-board RAM and other delights.
+ Most likely this space will be consumed in the next OS upgrade.
+ PEEKing this area will show it not to be completely empty; it was
+ apparently used for system development in Atari's paleozoic age.
+ Although the Atari is technically a 64K machine (1K equals 1024 bytes,
+ so 64K equals 65536 bytes), you don't really have all 64K to use. The
+ OS takes up 10K; there is the 4K block here that's unused, plus a few
+ other unused areas in the ROM and, of course, there are the hardware
+ chips. BASIC (or any cartridge) uses another 8K. The bottom 1792
+ bytes are used by the OS, BASIC, and floating point package. Then
+ DOS and DUP take up their memory space, not to mention the 850
+ handler if booted -- leaving you with more or less 38K of RAM to use
+ for your BASIC programming.
+
+ ---------------------------------------------------------------------------
+ Locations 53248 to 55295 ($D000 to $D7FF) are for ROM for the special
+ I/O chips that Atari uses. The CTIA (or GTIA, depending on which
+ you have) uses memory locations 53248 to 53503 ($D000 to $D0FF).
+ POKEY uses 53760 to 54015 ($D200 to $D2FF). PIA uses 54016 to 54271
+ ($D300 to $D3FF). ANTIC uses 54272 to 54783 ($D400 to $D5FF).
+ ANTIC, POKEY and G/CTIA are Large Scale Integration (LSI) circuit
+ chips. Don't confuse this chip ROM with the OS ROM which is be
+ found in higher memory. For the most extensive description of these
+ chips, see the Atari Hardware Manual.
+
+ There are two blocks of unused, unavailable memory in the I/O areas:
+ 53504 to 53759 ($D100 to $D1FF) and 54784 to 55295 ($D600 to
+ $D7FF).
+
+ Many of the following registers can't be read directly, since they are
+ hardware registers. Writing to them can often be difficult because in
+ most cases the registers change every 30th second (stage two
+ VBLANK) or even every 60th second (stage one VBLANK)! That's
+ where the shadow registers mentioned earlier come in. The values
+ written into these ROM locations are drawn from the shadow registers;
+ to effect any "permanent" change in BASIC (i.e., while your program
+ is running), you have to write to these shadow registers (in direct mode
+ or while your program is running; these values will all be reset to their
+ initialization state on RESET or powerup).
+
+ Shadow register locations are enclosed in parentheses; see these
+ locations for further descriptions. If no shadow register is mentioned,
+ you may be able to write to the location directly in BASIC. Machine
+ language is fast enough to write to the ROM locations and may be able
+ to bypass the shadow registers entirely.
+
+ Another feature of many of these registers is their dual nature. They
+ are read for one value and written to for another. The differences
+ between these functions are noted by the (R) for read and (W) for write
+ functions. You will notice that many of these dual-purpose registers
+ also have two labels.
+
+ ---------------------------------------------------------------------------
+
+ CTIA or GTIA
+
+ 53248-53505 D000-D0FF
+
+ GTIA (or CTIA) is a special television interface chip designed
+ exclusively for the Atari to process the video signal. ANTIC
+ controls most of the C/GTIA chip functions. The GTIA shifts the
+ display by one-half color clock off what the CTIA displays, so it
+ may display a different color than the CTIA in the same piece of
+ software. However, this shift allows players and playfields to
+ overlap perfectly.
+
+ There is no text window available in GTIA modes, but you can
+ create a defined area on your screen with either a DLI (see
+ COMPUTE!, September 1982) or by POKEing the GTIA mode
+ number into location 87 ($57), POKEing 703 with four and then
+ setting the proper bits in location 623 ($26F) for that mode. Only in
+ the former method will you be able to get a readable screen,
+ however. In the latter you will only create a four line, scrolling,
+ unreadable window. You will be able to input and output as with
+ any normal text window; you just won't be able to read it! GTIA,
+ by the way, apparently stands for "George's Television Interface
+ Adapter." Whoever George is, thanks, but what is CTIA?
+ See the OS User's Manual, the Hardware Manual, De Re Atari and
+ COMPUTE!, July 1982 to September 1982, for more information.
+
+
+ 53248 D000 HPOSP0
+
+ (W) Horizontal position of player 0. Values from zero to 227 ($E3)
+ are possible but, depending on the size of the playfield, the range
+ can be from 48 ($30) as the leftmost position to 208 ($D0) as the
+ rightmost position. Other positions will be "off screen."
+ Here are the normal screen boundaries for players and missiles.
+ The values may vary somewhat due to the nature of your TV
+ screen. Players and missiles may be located outside these
+ boundaries, but will not be visible (off screen):
+
+ Top
+ 32 for single,
+ 16 for double line
+ resolution
+ +--------------------------------+
+ | |
+ | |
+ | |
+ 48 for both | | 208 for both
+ resolutions | | resolutions
+ | |
+ | |
+ | |
+ +--------------------------------+
+ Bottom
+ 224 for single,
+ 112 for double line
+ resolution
+
+ Although you can POKE to these horizontal position registers, they
+ are reset to zero immediately. The player or missile will stay on the
+ screen at the location specified by the POKE, but in order to move
+ it using the horizontal position registers, you can't use:
+
+ POKE 53248, PEEK (53248) + n (or -n)
+
+ which will end up generating an error message. Instead, you need
+ to use something like this:
+
+ 10 POKE 704,220: GRAPHICS 1: HPOS =
+ 53248: POKE 623,8
+ 20 N = 100: POKE HPOS,N: POKE 53261
+ ,255
+ 30 IF STICK(0) = 11 THEN N = N - 1:
+ POKE HPOS,N: PRINT N
+ 40 IF STICK(0) = 7 THEN N = N + 1:
+ POKE HPOS,N: PRINT N
+ 50 GOTO 30
+
+ There are no vertical position registers for P/M graphics, so you
+ must use software routines to move players vertically. One idea for
+ vertical motion is to reposition the player within the P/M region
+ rather than the screen RAM. For example, the program below uses
+ a small machine language routine to accomplish this move:
+
+ 1 REM LINES 5 TO 70 SET UP THE PLAYER
+ 5 KEEP=PEEK(106)-16
+ 10 POKE 106,KEEP:POKE 54279,KEEP
+ 20 GRAPHICS 7+16:POKE 704,78:POKE 559
+ ,46:POKE 53277,3
+ 30 PMBASE=KEEP*256
+ 40 FOR LOOP=PMBASE+512 TO PMBASE+640:
+ POKE LOOP,0:NEXT LOOP:REM CLEAR OU
+ T MEMORY FIRST
+ 50 X=100:Y=10:POKE 53248,X
+ 60 FOR LOOP=0 TO 7:READ BYTE:POKE PMB
+ ASE+512+Y+LOOP,BYTE:NEXT LOOP:REM
+ PLAYER GRAPHICS INTO MEMORY
+ 70 DATA 129,153,189,255,255,189,153,1
+ 29
+ 80 REM LINES 100 TO 170 SET UP MACHIN
+ E LANGUAGE ROUTINE
+ 100 DIM UP$(21),DOWN$(21):UP=ADR(UP$)
+ :DOWN=ADR(DOWN$)
+ 110 FOR LOOP=UP TO UP+20:READ BYTE:PO
+ KE LOOP,BYTE:NEXT LOOP
+ 120 FOR LOOP=DOWN TO DOWN+20:READ BYT
+ E:POKE LOOP,BYTE:NEXT LOOP
+ 130 DATA 104,104,133,204,104,133,203,
+ 160,1,177
+ 140 DATA 203,136,145,203,200,200,192,
+ 11,208,245,96
+ 150 DATA 104,104,133,204,104,133,203,
+ 160,10,177
+ 160 DATA 203,200,145,203,136,136,192,
+ 255,208,245,96
+ 200 REM VERTICAL CONTROL
+ 210 IF STICK(0)=14 THEN GOSUB 300
+ 220 IF STICK(0)=13 THEN D=USR(DOWN,PM
+ BASE+511+Y):Y=Y+1
+ 250 GOTO 210
+ 300 U=USR(UP,PMBASE+511+Y):Y=Y-l
+ 310 RETURN
+
+ DOWNLOAD MOVEPM.BAS
+
+ This will move any nine-line (or less) size player vertically with the
+ joystick. If you have a larger player size, increase the 11 in line 140
+ to a number two larger than the number of vertical lines the player
+ uses, and change the ten in line 150 to one greater than the
+ number of lines. To add horizontal movement, add the following
+ lines:
+
+ 6 HPOS = 53248
+ 230 IF STICK(0) = 11 THEN X = X - 1:
+ POKE HPOS, X
+ 240 IF STICK(0) = 7 THEN X = X + 1:
+ POKE HPOS, X
+
+ You can use the routine to move any player by changing the
+ number 511 in the USR calls to one less than the start address of the
+ object to be moved. See the appendix for a map of P/M graphics
+ memory use. Missiles are more difficult to move vertically with this
+ routine, since it moves an entire byte, not bits. It would be useful
+ for moving all four missiles vertically if you need to do so; they
+ could still be moved horizontally in an individual manner.
+ See COMPUTE!, December 1981, February 1982, and May 1982,
+ for some solutions and some machine language move routines, and
+ COMPUTE!, October 1981, for a solution with animation involving
+ P/M graphics.
+
+
+ M0PF
+
+ (R) Missile 0 to playfield collision. This register will tell you which
+ playfield the object has "collided" with, i.e., overlapped. If missile
+ 0 collides with playfield two, the register would read four and so
+ on. Bit use is:
+
+ Bit 7 6 5 4 3 2 1 0
+ Playfield .....unused..... 3 2 1 0
+ Decimal ................ 8 4 2 1
+
+
+ 53249 D00l HOPSP1
+
+ (W) Horizontal position of player 1.
+
+
+ M1PF
+
+ (R) Missile 1 to playfield collision.
+
+
+ 53250 D002 HPOSP2
+
+ (W) Horizontal position of player 2.
+
+
+ M2PF
+
+ (R) Missile 2 to playfield collision.
+
+
+ 53251 D003 HPOSP3
+
+ (W) Horizontal position of player 3.
+
+
+ M3PF
+
+ (R) Missile 3 to playfield collision.
+
+
+ 53252 D004 HPOSM0
+
+ (W) Horizontal position of missile 0. Missiles move horizontally like
+ players. See the note in 53248 ($D000) concerning the use of
+ horizontal registers.
+
+
+ P0PF
+
+ (R) Player 0 to playfield collisions. There are some problems using
+ collision detection in graphics modes nine to eleven. There are no
+ obviously recognized collisions in GR.9 and GR.11. In GR.10
+ collisions work only for the playfield colors that correspond to the
+ usual playfield registers. Also, the background (BAK) color is set
+ by PCOLR0 (location 704; $2C0) rather than the usual COLOR4
+ (location 712; $2C8), which will affect the priority detection. In
+ GR.10, playfield colors set by PCOLR0 to PCOLR3 (704 to 707;
+ $2C0 to $2C3) behave like players where priority is concerned. Bit
+ use is:
+
+ Bit 7 6 5 4 3 2 1 0
+ Playfield .....unused..... 3 2 1 0
+ Decimal ................ 8 4 2 1
+
+
+ 53253 D005 HPOSM1
+
+ (W) Horizontal position of missile 1.
+
+
+ P1PF
+
+ (R) Player 1 to playfield collisions.
+
+
+ 53254 D006 HPOSM2
+
+ (W) Horizonal position of missile 2.
+
+
+ P2PF
+
+ (R) Player 2 to playfield collisions.
+
+
+ 53255 D007 HPOSM3
+
+ (W) Horizontal position of missile 3.
+
+
+ P3PF
+
+ (R) Player 3 to playfield collisions.
+
+
+ 53256 D008 SIZEP0
+
+ (W) Size of player 0. POKE with zero or two for normal size (eight
+ color clocks wide), POKE with one to double a player's width
+ (sixteen color clocks wide), and POKE with three for quadruple
+ width (32 color clocks wide). Each player can have its own width set.
+ A normal size player might look something like this:
+
+ 00011000
+ 00111100
+ 01111110
+ 11111111
+ 11111111
+ 01111110
+ 00111100
+ 00011000
+
+ In double width, the same player would like this:
+
+ 0000001111000000
+ 0000111111110000
+ 0011111111111100
+ 0011111111111100
+ 0000111111110000
+ 0000001111000000
+
+ In quadruple width, the same player would become:
+
+ 00000000000011111111000000000000
+ 00000000111111111111111100000000
+ 00001111111111111111111111110000
+ 11111111111111111111111111111111
+ 11111111111111111111111111111111
+ 00001111111111111111111111110000
+ 00000000111111111111111100000000
+ 00000000000011111111000000000000
+
+ Bit use is:
+
+ Bit 7 6 5 4 3 2 1 0
+ Size: .....unused..... 0 0 Normal (8 color clocks)
+ 0 1 Double (16 color clocks)
+ 1 0 Normal
+ 1 1 Quadruple (32 color clocks)
+
+
+ M0PL
+
+ (R) Missile 0 to player collisions. There is no missile-to-missile
+ collision register. Bit use is:
+
+ Bit 7 6 5 4 3 2 1 0
+ Player ..unused.. 3 2 1 0
+ Decimal .......... 8 4 2 1
+
+
+ 53257 D009 SIZEP1
+
+ (W) Size of player 1.
+
+
+ M1PL
+
+ (R) Missile 1 to player collisions.
+
+
+ 53258 D00A SIZEP2
+
+ (W) Size of player 2.
+
+
+ M2PL
+
+ (R) Missile 2 to player collisions.
+
+
+ 53259 D00B SIZEP3
+
+ (W) Size of player 3.
+
+
+ M3PL
+
+ (R) Missile 3 to player collisions.
+
+
+ 53260 D00C SIZEM
+
+ (W) Size for all missiles; set bits as below (decimal values
+ included):
+
+ Bits Size:
+ Normal Double Quadruple
+ 7 & 6: missile 3 0,128 64 192
+ 5 & 4: missile 2 0, 32 16 48
+ 3 & 2: missile l 0, 8 4 12
+ 1 & 0: missile 0 0, 2 1 3
+
+ where turning on the bits in each each pair above does as follows:
+
+ 0 and 0: normal size -- two color clocks wide
+ 0 and 1: twice normal size -- four color clocks wide
+ 1 and 0: normal size
+ 1 and 1: four times normal size -- eight color clocks wide
+
+ So, to get a double-sized missile 2, you would set BITs 5 and 6, or
+ POKE 53260,48. Each missile can have a size set separately from
+ the other missiles or players when using the GRAF registers.
+ A number of sources, including De Re Atari, say that you can set
+ neither missile sizes nor shapes separately. Here's a routine to
+ show that you can in fact do both:
+
+ 10 POKE 53265,255: REM SHAPE START
+ 15 GR.7
+ 20 POKE 623,1: REM SET PRIORITIES
+ 30 FOR X = 1 TO 25
+ 35 F = 50
+ 40 FOR C = 704 TO 707: POKE C,F + X:
+ F = F + 50: NEXT C: REM COLOURS
+ 45 S = 100
+ 50 FOR P = 53252 TO 53255: POKE P,S
+ + X: S = S + 20: NEXT P : REM SCRE
+ EN POSITIONS
+ 60 NEXT X
+ 70 INPUT A,B: REM MISSILE SIZE AND S
+ HAPES
+ 80 POKE 53260,A: POKE 53265,5
+ 100 GOTO 30
+
+ Here's another example using DMA; GRACTL and DACTL
+ (53277 and 54272; $D0lD and $D400):
+
+ 10 POKE 623,1: POKE 559,54: POKE 542
+ 79, 224: POKE 53277,1
+ 20 FOR N = 53252 TO 53255: POKE N, 1
+ 00 + X: X = X + 10: NEXT N: X = 0
+ 30 INPUT SIZE: POKE 53260, SIZE
+ 40 GOTO 30
+
+ See 54279 ($D407) for more information on P/M graphics.
+
+
+ P0PL
+
+ (R) Player 0 to player collisions. Bit use is:
+
+ Bit 7 6 5 4 3 2 1 0
+ Player ...unused.... 3 2 1 0
+ Decimal ............. 8 4 2 1
+
+
+ 53261 D00D GRAFP0
+
+ (W) Graphics shape for player 0 written directly to the player
+ graphics register. In using these registers, you bypass ANTIC.
+ You only use the GRAFP# registers when you are not using
+ Direct Memory Access (DMA: see GRACTL at 53277). If DMA is
+ enabled, then the graphics registers will be loaded automatically
+ from the area specified by PMBASE (54279; $D407).
+
+ The GRAF registers can only write a single byte to the playfield,
+ but it runs the entire height of the screen. Try this to see:
+
+ 10 POKE 53248, 160: REM SET HORIZONT
+ AL POSITION OF PLAYER 0
+ 20 POKE 704, 245: REM SET PLAYER 0 C
+ OLOUR TO ORANGE
+ 30 POKE 53261, 203: REM BIT PATTERN
+ 11001011
+
+ To remove it, POKE 53261 with zero. The bit order runs from
+ seven to zero, left to right across the TV screen. Each bit set will
+ appear as a vertical line on the screen. A value of 255 means all
+ bits are set, creating a wide vertical line. You can also use the
+ size registers to change the player width. Using the GRAF
+ registers will allow you to use players and missiles for such things
+ as boundaries on game or text fields quite easily.
+
+
+ P1PL
+
+ (R) Player 1 to player collisions.
+
+
+ 53262 D00E GRAFP1
+
+ (W) Graphics for player 1.
+
+
+ P2PL
+
+ (R) Player 2 to player collisions.
+
+
+ 53263 D00F GRAFP2
+
+ (W) Graphics for player 3.
+
+
+ P3PL
+
+ (R) Player 3 to player collisions.
+
+
+ 53264 D010 GRAFP3
+
+ (W) Graphics for player 3.
+
+
+ TRIG0
+
+ (R) Joystick trigger 0 (644). Controller jack one, pin six. For all
+ triggers, zero equals button pressed, one equals not pressed. If
+ BIT 2 of GRACTL (53277; $D01D) is set to one, then all TRIG
+ BITs 0 are latched when the button is pressed (set to zero) and are
+ only reset to one (not pressed) when BIT 2 of GRACTL is reset to
+ zero. The effect of latching the triggers is to return a constant
+ "button pressed" read until reset.
+
+
+ 53265 D011 GRAFM
+
+ (W) Graphics for all missiles, not used with DMA. GRAFM works
+ the same as GRAFP0 above. Each pair of bits represents one
+ missile, with the same allocation as in 53260 ($D00C) above.
+
+ Bit 7 6 5 4 3 2 1 0
+ Missile -3- -2- -1- -0-
+
+ Each bit set will create a vertical line running the entire height of
+ the TV screen. Missile graphics shapes may be set separately
+ from each other by using the appropriate bit pairs. To mask out
+ unwanted players, write zeros to the bits as above.
+
+
+ TRIG1
+
+ (R) Joystick trigger 1 (645). Controller jack two, pin six.
+
+
+ 53266 D012 COLPM0
+
+ (W) Color and luminance of player and missile 0 (704). Missiles
+ share the same colors as their associated players except when
+ joined together to make a fifth player. Then they take on the same
+ value as in location 53733 ($D019; color register 3).
+
+
+ TRIG2
+
+ (R) Joystick trigger 2 (646). Controller jack three, pin six.
+
+
+ 53267 D013 COLPM1
+
+ (W) Color and luminance of player and missile 1 (705).
+
+
+ TRIG3
+
+ (R) Joystick trigger 3 (647). Controller jack four, pin six.
+
+
+ 53268 D014 COLPM2
+
+ (W) Color and luminance of player and missile 2 (706).
+
+
+ PAL
+
+ (R) Used to determine if the Atari is PAL (European and Israeli
+ TV compatible when BITs 1 - 3 equal zero) or NTSC (North
+ American compatible when BITs 1 - 3 equal one; 14 decimal, $E).
+ European Ataris run 12% slower if tied to the VBLANK cycle (the
+ PAL VBLANK cycle is every 50th second rather than every 60th
+ second). They use only one CPU clock at three MHZ, so the 6502
+ runs at 2.217 MHZ -- 25% faster than North American Ataris.
+ Also, their $E000 and $F000 ROMs are different, so there are
+ possible incompatibilities with North American Ataris in the
+ cassette handling routines. There is a third TV standard called
+ SECAM, used in France, the USSR, and parts of Africa. I am
+ unaware if there is any Atari support for SECAM standards.
+
+ PAL TV has more scan lines per frame, 312 compared to 262.
+ NTSC Ataris compensate by adding extra lines at the beginning
+ of the VBLANK routine. Display lists do not have to be altered,
+ and colors are the same because of a hardware modification.
+
+
+ 53269 D015 COLPM3
+
+ Color and luminance of player and missile 3 (707).
+
+
+ 53270 D016 COLPF0
+
+ Color and luminance of playfield zero (708).
+
+
+ 53271 D017 COLPF1
+
+ Color and luminance of playfield one (709).
+
+
+ 53272 D018 COLPF2
+
+ Color and luminance of playfield two (710).
+
+
+ 53273 D019 COLPF3
+
+ Color and luminance of playfield three (711).
+
+
+ 53274 D01A COLBK
+
+ Color and luminance of the background (BAK).(712).
+
+
+ 53275 D01B PRIOR
+
+ (W) Priority selection register. PRIOR establishes which objects
+ on the screen (players, missiles, and playfields) will be in front of
+ other objects. Values used in this register are also described at
+ location 623 ($26F), the shadow register. If you use conflicting
+ priorities, objects whose priorities are in conflict will turn black
+ in their overlap region.
+
+ Priority order
+ (Decimal values in brackets):
+
+ Bit 0 = 1 (1): Bit 1 = 1 (2):
+ Player 0 Player 0
+ Player 1 Player 1
+ Player 2 Playfield 0
+ Player 3 Playfield 1
+ Playfield 0 Playfield 2
+ Playfield 1 Playfield 3 and Player 5
+ Playfield 2 Player 2
+ Playfield 3 and Player 5 Player 3
+ Background Background
+
+ Bit 2 = 1 (4): Bit 3 = 1 (8):
+ Playfield 0 Playfield 0
+ Playfield 1 Playfield 1
+ Playfield 2 Player 0
+ Playfield 3 and Player 5 Player 1
+ Player 0 Player 2
+ Player 1 Player 3
+ Player 2 Playfield 2
+ Player 3 Playfield 3 and Player 5
+ Background Background
+
+ Bit 4 = 1: Enable a fifth player out of the four missiles.
+
+ Bit 5 = 1: Overlap of players 0 and 1, 2 and 3 is third color (else
+ overlap is black). The resulting color is a logical OR of the two
+ player colors.
+
+ Bits 6 and 7 are used to select GTIA modes:
+ 0 0 = no GTIA modes
+ 0 1 = GTIA GR.9
+ 1 0 = GTIA GR.10
+ 1 1 = GTIA GR.11
+
+
+ 53276 D01C VDELAY
+
+ (W) Vertical delay register. Used to give one-line resolution
+ movement capability in the vertical positioning of an object when
+ the two line resolution display is enabled. Setting a bit in
+ VDELAY to one moves the corresponding object down by one TV
+ line. If DMA is enabled, then moving an object by more than one
+ line is accomplished by moving bits in the memory map instead.
+
+ Bit Decimal Object
+ 7 128 Player 3
+ 6 64 Player 2
+ 5 32 Player 1
+ 4 16 Player 0
+ 3 8 Missile 3
+ 2 4 Missile 2
+ 1 2 Missile 1
+ 0 1 Missile 0
+
+
+ 53277 D01D GRACTL
+
+ (W) Used with DMACTL (location 54272; $D400) to latch all stick
+ and paddle triggers (to remember if triggers on joysticks or
+ paddles have been pressed), to turn on players and to turn on
+ missiles. To get the values to be POKEd here, add the following
+ options together for the desired function:
+
+ Decimal Bit
+ To turn on missiles 1 0
+ To turn on players 2 1
+ To latch trigger inputs 4 2
+
+ To revoke P/M authorization and turn off both players and
+ missiles, POKE 53277,0. Once latched, triggers will give a
+ continuous "button pressed" read the first time they are pressed
+ until BIT 2 is restored to zero. Triggers are placed in "latched"
+ mode when each individual trigger is pressed, but you cannot set
+ the latch mode for individual triggers.
+
+ Have you ever hit BREAK during a program and still had players
+ or their residue left on the screen? Sometimes hitting RESET
+ doesn't clear this material from the screen. There are ways to get
+ rid of it:
+
+ POKE 623,4: This moves all players behind playfields.
+ POKE 53277,0: This should turn them off.
+ POKE 559,2: This should return you to a blank screen.
+
+ Make sure you SAVE your program before POKEing, just in
+ case!
+
+
+ 53278 D01E HITCLR
+
+ (W) POKE with any number to clear all player/missile collision
+ registers. It is important to clear this register often in a program
+ -- such as a game -- which frequently tests for collisions.
+ Otherwise, old collision values may remain and confuse the
+ program. A good way to do this is to POKE HITCLR just before
+ an event which may lead to a collision; for example, right before
+ a joystick or paddle is "read" to move a player or fire a missile.
+ Then test for a collision immediately after the action has taken
+ place. Remember that multiple collisions cause sums of the
+ collision values to be written to the collision registers; if you do
+ not clear HITCLR often enough, a program checking for
+ individual collisions will be thrown off by these sums.
+
+
+ 53279 D01F CONSOL
+
+ (W/R) Used to see if one of the three yellow console buttons has
+ been pressed (not the RESET button!). To clear the register,
+ POKE CONSOL with eight. POKEing any number from zero to
+ eight will cause a click from the speaker. A FOR-NEXT loop that
+ alternately POKEs CONSOL with eight and zero or just zero,
+ since the OS put in an 8 every 1/60 second, will produce a buzz.
+ Values PEEKed will range from zero to seven according to the
+ following table:
+
+ |Key Value 0 1 2 3 4 5 6 7 |
+ | |
+ +------------------------------------------------------------+
+ | |
+ |OPTION X X X X |
+ |SELECT X X X X |
+ |START X X X X |
+ | |
+ +------------------------------------------------------------+
+ Bits 2 0 0 0 0 1 1 1 1
+ 1 0 0 1 1 0 0 1 1
+ 0 0 1 0 1 0 1 0 1
+
+
+ Where zero means all keys have been pressed, one means
+ OPTION and SELECT have been pressed, etc., to seven, which
+ means no keys have been pressed. CONSOL is updated every
+ stage two VBLANK procedure with the value eight.
+
+ It is possible to use the console speaker to generate different
+ sounds. Here is one idea based on an article in COMPUTE!,
+ August 1981:
+
+ 10 GOSUB 1000
+ 20 TEST = USR(1536)
+ 999 END
+ 1000 FOR LOOP = 0 TO 26: READ BYTE: P
+ OKE 1536 + LOOP, BYTE: NEXT LOOP
+ : RETURN
+ 1010 DATA 104,162,255,169,255,141,31,
+ 208,169
+ 1020 DATA 0,160,240,136,208,253,141,3
+ 1,208,160
+ 1030 DATA 240,136,208,253,202,208,233
+ ,96
+
+ To change the tone, you POKE 1547 and 1555 with a higher or
+ lower value (both are set to 240 above). To change the tone
+ duration, you POKE 1538 with a lower value (it is set to 255 in the
+ routine above). Do these before you do your USR call or alter the
+ DATA statements to permanently change the values in your own
+ program. Turn off DMA (see location 559) to get clearer tones.
+
+ ---------------------------------------------------------------------------
+ Locations 53280 to 53503 ($D020 to $D0FF) are repeats of locations
+ 53248 to 53279 ($D000 to $D01F). You can't use any of the repeated
+ locations; consider them "filler." They maybe used for other purposes
+ in any Atari OS upgrade.
+
+ ---------------------------------------------------------------------------
+ Locations 53504 to 53759 ($D100 to $D1FF) are unused. These loca-
+ tions are not empty; you can PEEK into them and find out what's
+ there. They cannot, however, be user-altered.
+
+ ---------------------------------------------------------------------------
+
+
+ POKEY
+
+ 53760-54015 D200-D2FF
+
+ POKEY is a digital I/O chip that controls the audio frequency and
+ control registers, frequency dividers, poly noise counters, pot
+ (paddle) controllers, the random number generator, keyboard
+ scan, serial port I/O, and the IRQ interrupts.
+
+ The AUDF# (audio frequency) locations are used for the pitch for
+ the corresponding sound channels, while the AUDC# (audio
+ control registers) are the volume and distortion values for those
+ same channels. To POKE sound values, you must first POKE zero
+ into locations 53768 ($D208) and a three into 53775 ($D20F).
+
+ Frequency values can range from zero to 255 ($FF), although the
+ value is increased by the computer by one to range from one to
+ 256. Note that the sum of the volumes should not exceed 32, since
+ volume is controlled by the least four bits. It is set from zero as no
+ volume to 15 ($F) as the highest. A POKE with 16 ($10) forces
+ sound output even if volume is not set (i.e., it pushes the speaker
+ cone out. A tiny "pop" will be heard). The upper four bits control
+ distortion: 192 ($C0) is for pure tone; other values range from 32 to
+ 192. Note that in BASIC, the BREAK key will not turn off the
+ sound; RESET will, however. See De Re Atari and BYTE, April
+ 1982, for more information on sound generation.
+
+ The AUDF registers are also used as the POKEY hardware timers.
+ These are generally used when counting an interval less than one
+ VBLANK. For longer intervals, use the software timers in locations
+ 536 to 545 ($218 to $221). You load the AUDCTL register with the
+ number for the desired clock frequency. You then set the volume
+ to zero in the AUDC register associated with the AUDF register
+ you plan to use as a timer. You load the AUDF register itself with
+ the number of clock intervals you wish to count. Then you load
+ your interrupt routine into memory, and POKE the address into the
+ appropriate timer vector between locations 528 and 533 ($210 and
+ $215). You must set the proper bit(s) in IRQEN and its shadow
+ register POKMSK at location 16 ($10) to enable the interrupt.
+ Finally, you load STIMER with any value to load and start the
+ timer(s). The OS will force a jump to the timer vector and then to
+ your routine when the AUDF register counts down to zero. Timer
+ processing can be preempted by ANTIC's DMA, a DLI, or the
+ VBLANK process.
+
+ POT values are for the paddles, ranging from zero to 240,
+ increasing as the paddle knob is turned counterclockwise, but
+ values less than 40 and greater than 200 represent an area on
+ either edge of the screen that may not be visible on all TV sets or
+ monitors.
+
+
+ 53760 D200 AUDF1
+
+ (W) Audio channel one frequency. This is actually a number (N)
+ used in a "divide by N circuit"; for every N pulses coming in (as set
+ by the POKEY clock), one pulse goes out. As N gets larger, output
+ pulses will decrease, and thus the sound produced will be a lower
+ note. N can be in the range from one to 256; POKEY adds one to
+ the value in the AUDF register. See BYTE, April 1982, for a
+ program to create chords instead of single tones.
+
+
+ POT0
+
+ (R) Pot (paddle) 0 (624); pot is short for potentiometer. Turning the
+ paddle knob clockwise results in decreasing pot values. For
+ machine language use: these pot values are valid only 228 scan
+ lines after the POTGO command or after ALLPOT changes (see
+ 53768; $D208 and 53771; $D20B). POT registers continually count
+ down to zero, decrementing every scan line. They are reset to 228
+ when they reach zero or by the values read from the shadow
+ registers. This makes them useful as system timers. See
+ COMPUTE!, February 1982, for an example of this use.
+
+ The POTGO sequence (see 53771; $D20B) resets the POT
+ registers to zero, then reads them 228 scan lines later. For the fast
+ pot scan, BIT 2 of SKCTL at 53775 ($D20F) must be set.
+
+
+ 53761 D201 AUDC1
+
+ (W) Audio channel one control. Each AUDF register has an
+ associated control register which sets volume and distortion levels.
+ The bit assignment is:
+
+ Bit 7 6 5 4 3 2 1 0
+ Distortion Volume Volume
+ (noise) only level
+ 0 0 0 0 0 0 0 0 Lowest
+ 0 0 1 0 0 0 1
+ etc. to: etc. to:
+ 1 1 1 1 1 1 1 1 Highest
+ (forced
+ output)
+
+ The values for the distortion bits are as follows. The first process is
+ to divide the clock value by the frequency, then mask the output
+ using the polys in the order below. Finally, the result is divided by
+ two.
+
+ Bit
+ 7 6 5
+ 0 0 0 five bit, then 17 bit, polys
+ 0 0 1 five bit poly only
+ 0 1 0 five bit, then four bit, polys
+ 0 1 1 five bit poly only
+ 1 0 0 l7 bit poly only
+ 1 0 1 no poly counters (pure tone)
+ 1 1 0 four bit poly only
+ 1 1 1 no poly counters (pure tone)
+
+ In general, the tones become more regular (a recognizable
+ droning becomes apparent) with fewer and lower value polys
+ masking the output. This is all the more obvious at low frequency
+ ranges. POKE with 160 ($A0) or 224 ($E0) plus the volume for pure
+ tones.
+
+ See De Re Atari and the Hardware Manual for details.
+
+
+ POT1
+
+ (R) Pot 1 register (625).
+
+
+ 53762 D202 AUDF2
+
+ (W) Audio channel two frequency. Also used with AUDF3 to store
+ the 19200 baud rate for SIO.
+
+
+ POT2
+
+ (R) Pot 2 (626).
+
+
+ 53763 D203 AUDC2
+
+ (W) Audio channel two control.
+
+
+ POT3
+
+ (R) Pot 3 (627).
+
+
+ 53764 D204 AUDF3
+
+ (W) Audio channel three frequency. Used with AUDF3 above and
+ with AUDF4 to store the 600 baud rate for SIO.
+
+
+ POT4
+
+ (R) Pot 4 (628).
+
+
+ 53765 D205 AUDC3
+
+ (W) Audio channel three control.
+
+
+ POT5
+
+ (R) Pot 5 (629).
+
+
+ 53766 D206 AUDF4
+
+ (W) Audio channel four frequency.
+
+
+ POT6
+
+ (R) Pot 6 (630).
+
+
+ 53767 D207 AUDC4
+
+ (W) Audio channel four control.
+
+
+ POT7
+
+ (R) Pot 7 (631).
+
+
+ 53768 D208 AUDCTL
+
+ (W) Audio control. To properly initialize the POKEY sound
+ capabilities, POKE AUDCTL with zero and POKE 53775,3
+ ($D20F). These two are the equivalent of the BASIC statement
+ SOUND 0,0,0,0. AUDCTL is the option byte which affects all
+ sound channels. This bit assignment is:
+
+ Bit Description:
+ 7 Makes the 17 bit poly counter into nine bit poly
+ (see below)
+ 6 Clock channel one with 1.79 MHz
+ 5 Clock channel three with 1.79 MHz
+ 4 Join channels two and one (16 bit)
+ 3 Join channels four and three (16 bit)
+ 2 Insert high pass filter into channel one, clocked by channel
+ two
+ 1 Insert high pass filter into channel two, clocked by channel
+ four
+ 0 Switch main clock base from 64 KHz to 15 KHz
+
+ Poly (polynomial) counters are used as a source of random pulses
+ for noise generation. There are three polys: four, five and 17 bits
+ long. The shorter polys create repeatable sound patterns, while the
+ longer poly has no apparent repetition. Therefore, setting BIT 7
+ above, making the 17-bit into a nine-bit poly will make the pattern
+ in the distortion more evident. You chose which poly(s) to use by
+ setting the high three bits in the AUDC registers. The 17-bit poly is
+ also used in the generation of random numbers; see 53770
+ ($D20A).
+
+ The clock bits allow the user to speed up or slow down the clock
+ timers, respectively, making higher or lower frequency ranges
+ possible. Setting the channels to the 1.79 MHz will produce a
+ much higher sound, the 64 KHz clock will be lower, and the 15
+ KHz clock the lowest. The clock is also used when setting the
+ frequency for the AUDF timers.
+
+ Two bits (three and four) allow the user to combine channels one
+ and two or three and four for what amounts to a nine octave range
+ instead of the usual five. Here's an example from De Re Atari of
+ this increased range, which uses two paddles to change the
+ frequency: the right paddle makes coarse adjustments, the left
+ paddle makes fine adjustments:
+
+ 10 SOUND 0,0,0,0:POKE 53768,80:REM SE
+ T CLOCK AND JOIN CHANNELS 1 AND 2
+ 20 POKE 53761,160:POKE 53763,168:REM
+ TURN OFF CHANNEL 1 AND SET 2 TO PU
+ RE TONE GENERATION
+ 50 POKE 53760,PADDLE(0):POKE 53762,PA
+ DDLE(1):GOTO 30
+
+ High pass filters allow only frequencies higher than the clock value
+ to pass through. These are mostly used for special effects. Try:
+
+ 10 SOUND 0,0,0,0:POKE 53768,4:REM HIG
+ H PASS FILTER ON CHANNEL 1
+ 20 POKE 53761,168:POKE 53765,168:REM
+ PURE TONES
+ 30 POKE 53760,254:POKE 53764,127
+ 40 GOTO 40
+
+ See the excellent chapter on sound in De Re Atari: it is the best
+ explanation of sound functions in the Atari available. See also the
+ Hardware Manual for complete details.
+
+
+ ALLPOT
+
+ (R) Eight line pot port state; reads all of the eight POTs together.
+ Each bit represents a pot (paddle) of the same number. If a bit is
+ set to zero, then the register value for that pot is valid (it's in use); if
+ it is one, then the value is not valid. ALLPOT is used with the
+ POTGO command at 53771 ($D20B).
+
+ ----------------------------------------------------------------------
+
+ 53769 D209 STIMER
+
+ (W) Start the POKEY timers (the AUDF registers above). You
+ POKE any non-zero value here to load and start the timers; the
+ value isn't itself used in the calculations. This resets all of the audio
+ frequency dividers to their AUDF values. If enabled by IRQEN
+ below, these AUDF registers generate timer interrupts when they
+ count down from the number you POKEd there to zero. The
+ vectors for the AUDF1, AUDF2 and AUDF4 timer interrupts are
+ located between 528 and 533 ($210 and $215). POKEY timer four
+ interrupt is only enabled in the new "B" OS ROMs.
+
+
+ KBCODE
+
+ (R) Holds the keyboard code which is then loaded into the shadow
+ register (764; $2FC) when a key is hit. Usually read in response to
+ the keyboard interrupt. Compares the value with that in CH1 at
+ 754 ($2F2). If both values are the same, then the new code is
+ accepted only if a suitable key debounce delay time has passed.
+ The routines which test to see if the key code will be accepted start
+ at 65470 ($FFBE). BIT 7 is the control key flag, BIT 6 is the shift key
+ flag.
+
+
+ 53770 D20A SKREST
+
+ (W) Reset BITs 5 - 7 of the serial port status register at 53775 to one.
+
+
+ RANDOM
+
+ (R) When this location is read, it acts as a random number
+ generator. It reads the high order eight bits of the 17 bit
+ polynomial counter (nine bit if BIT 7 of AUDCTL is set) for the
+ value of the number. You can use this location in a program to
+ generate a random integer between zero and 255 by:
+
+ 10 PRINT PEEK(53770)
+
+ This is a more elegant solution than INT(RND(0) * 256). For a test of
+ the values in this register, use this simple program:
+
+ 10 FOR N = 1 TO 20: PRINT PEEK(53770): NEXT N
+
+
+ 53771 D20B POTGO
+
+ (W) Start the POT scan sequence. You must read your POT values
+ first and then start the scan sequence, since POTGO resets the
+ POT registers to zero. Written by the stage two VBLANK
+ sequence.
+
+
+ 53772 D20C ....
+
+ Unused.
+
+
+ 53773 D20D SEROUT
+
+ (W) Serial port data output. Usually written to in the event of a
+ serial data out interrupt. Writes to the eight bit (one byte) parallel
+ holding register that is transferred to the serial shift register when a
+ full byte of data has been transmitted. This "holding" register is
+ used to contain the bits to be transmitted one at a time (serially) as
+ a one-byte unit before transmission.
+
+
+ SERIN
+
+ (R) Serial port input. Reads the one-byte parallel holding register
+ that is loaded when a full byte of serial input data has been
+ received. As above, this holding register is used to hold the bits as
+ they are received one bit at a time until a full byte is received. This
+ byte is then taken by the computer for processing. Also used to
+ verify the checksum value at location 49 ($31).
+
+ The serial bus is the port on the Atari into which you plug your
+ cassette or disk cable. For the pin values of this port, see the OS
+ User's Manual, p. 133, and the Hardware Manual.
+
+
+ 53774 D20E IRQEN
+
+ (W) Interrupt request enable. Zero turns off all interrupt requests
+ such as the BREAK key; to disable or re-enable interrupts, POKE
+ with the values according to the following chart (setting a bit to one
+ -- i.e., true -- enables that interrupt; decimal values are also
+ shown for each bit):
+
+ Bit Decimal Interrupt Vector
+ 0 1 Timer 1 (counted down to zero) VTIMR1
+ (528; $210)
+ 1 2 Timer 2 (counted down to zero) VTIMR2
+ (530; $212)
+ 2 4 Timer 4 (counted down to zero) VTIMR4
+ (532; $214), OS
+ "B" ROMs only)
+ 3 8 Serial output transmission done VSEROC (526;
+ $20E)
+ 4 16 Serial output data needed VSEROR
+ (524; $20C)
+ 5 32 Serial input data ready VSERIN
+ (522; $20A)
+ 6 64 Other key pressed VKEYBD
+ (520; $208)
+ 7 128 BREAK key pressed see below
+
+ Here is the procedure for the BREAK key interrupt: clear the
+ interrupt register. Set BRKKEY (17; $11) to zero; clear the
+ start/stop flag SSFLAG at 767 ($2FF); clear the cursor inhibit flag
+ CRSINH at 752 ($2F0); clear the attract mode flag at 77 ($4D), and
+ return from the interrupt after restoring the 6502 A register. (There
+ is now (in the OS "B" ROMs) a proper vector for BREAK key
+ interrupts at 566, 567 ($236, $237) which is initialized to point to
+ 59220 ($E754).) If the interrupt was due to a serial I/O bus proceed
+ line interrupt, then vector through VPRCED at 514 ($202). If due to
+ a serial I/O bus interrupt line interrupt, then vector through
+ VINTER at 516 ($204). If due to a 6502 BRK instruction, then vector
+ through VBREAK at 518 ($206).
+
+ Timers relate to audio dividers of the same number (an interrupt is
+ processed when the dividers count down to zero). These bits in
+ IRQEN are not set on powerup and must be initiated by the user
+ program before enabling the processor IRQ.
+ There are two other interrupts, processed by PIA, generated over
+ the serial bus Proceed and Interrupt lines, set by the bits in the
+ PACTL and PBCTL registers (54018 and 54019; $D302, $D303):
+
+ Bit Decimal Locution Interrupt
+ 0 1 PACTL Peripheral A (PORTA) interrupt enable
+ bit.
+ 7 128 PACTL Peripheral A interrupt status bit.
+ 0 1 PBCTL Peripheral B (PORTB) interrupt enable
+ bit.
+ 7 128 PBCTL Peripheral B interrupt status bit.
+
+ The latter PORT interrupts are automatically disabled on powerup.
+ Only the BREAK key and data key interrupts are enabled on
+ powerup. The shadow register is 16 ($10).
+
+
+ IRQST
+
+ (R) Interrupt request status. Bit functions are the same as IRQEN
+ except that they register the interrupt request when it is zero rather
+ than the enable when a bit equals one. IRQST is used to determine
+ the cause of interrupt request with IRQEN, PACTL and PBCTL as
+ above.
+
+ All IRQ interrupts are normally vectored through 65534 ($FFFE) to
+ the IRQ service routine at 59123 ($E6F3), which determines the
+ cause of the interrupt. The IRQ global RAM vector VIMIRQ at 534
+ ($216) ordinarily points to the IRQ processor at 59126 ($E6F6). The
+ processor then examines 53774 ($D20E) and the PIA registers at
+ 54018 and 54019 to determine the interrupt cause. Once
+ determined, the routine vectors through one of the IRQ RAM
+ vectors in locations 514 to 526 ($202 to $20E). For Non-Maskable
+ Interrupts (NMI's), see locations 54286 to 54287 ($D40E; $D40F).
+ See the OS User's Manual for complete details.
+
+
+ 53775 D20F SKCTL
+
+ (W) Serial port control. Holds the value 255 ($255) if no key is
+ pressed, 251 ($FB) for most other keys pressed, 247 ($F7) for
+ SHIFT key pressed (*M). See the (R) mode below for an
+ explanation of the bit functions. POKE with three to stop the
+ occasional noise from cassette after I/O to bring POKEY out of the
+ two-tone mode. (562).
+
+
+ SKSTAT
+
+ (R) Beads the serial port status. It also returns values governed by
+ a signal on the digital track of the cassette tape. You can generate
+ certain values using the SOUND command in BASIC and a PEEK
+ to SKSTAT:
+
+ SOUND 0,5,10,15 returns a value to here of 255 (or, on
+ occasion, 127).
+ SOUND 0,8,10,3 returns a value of 239.
+
+ This is handy for adding a voice track to Atari tapes. You use the
+ left channel for your voice track and the right for the tone(s) you
+ want to use as cuing marks. You can use the speaker on your TV to
+ generate the tones by placing the right microphone directly in
+ front of the speaker. The computer will register these tones in this
+ register when it encounters them during a later cassette load. See
+ COMPUTE!, July 1981, for some other suggestions on doing this.
+ Bemember, you can turn the cassette off by POKEing 54018
+ ($D302) with 60 ($3C) and back on with 52 ($34).
+
+ Bits in the SKCTL (W) register are normally zero and perform the
+ functions below when set to one. The status when used as (R) is
+ listed below the write (W) function:
+
+ Bit Function
+ 0 (W) Enable keyboard debounce circuits.
+ (R) Not used by SKSTAT.
+ 1 (W) Enable keyboard scanning circuit.
+ (R) Serial input shift register busy.
+ 2 (W) Fast pot scan: the pot scan counter completes its
+ sequence in two TV line times instead of one frame time (228
+ scan lines). Not as accurate as the normal pot scan,
+ however.
+ (R) the last key is still pressed.
+ 3 (W) Serial output is transmitted as a two-tone signal rather
+ than a logic true/false. POKEY two-tone mode.
+ (R) The shift key is pressed.
+ 4,5,6 (W) Serial port mode control used to set the bi-directional
+ clock lines so that you can either receive external clock data
+ or provide clock data to external devices (see the Hardware
+ Manual, p. II.27). There are two pins on the serial port for
+ Clock IN and Clock OUT data. See the OS User's Manual,
+ p. 133.
+ 4 (R) Data can be read directly from the serial input port,
+ ignoring the shift register.
+ 5 (R) Keyboard over-run. Reset BITs 7 to 5 (latches) to one
+ using SKRES at 53770 ($D20A).
+ 6 (R) Serial data input over-run. Reset latches as above.
+ 7 (W) Force break (serial output to zero).
+ (R) Serial data input frame error caused by missing or extra
+ bits. Beset latches as above.
+
+ BIT 2 is first set to zero to reset POT registers to zero (dumping the
+ capacitors used to change the POT registers). Then BIT 2 is set to
+ one to enable the fast scan. Fast scan is not as accurate as the
+ normal scan routine. BIT 2 must be reset to zero to enable the
+ normal scan mode; otherwise, the capacitors will never dump.
+
+ ---------------------------------------------------------------------------
+ Locations 53776 to 54015 ($D210 to $D2FF) are duplications of locations
+ 53760 to 53775 and have no particular use at present.
+
+ ---------------------------------------------------------------------------
+
+
+ PIA: 6520 CHIP
+
+ 54016-54271 D300-D3FF
+
+ The Peripheral Interface Adapter (PIA) integrated circuit is a
+ special microprocessor used to control the Atari ports, controller
+ jacks one to four. Ports can be used for both input and output
+ simultaneously or alternately. Barely tapped at the time of this
+ writing, the ports represent a major resource for external (and
+ internal) control and expansion. PIA also processes two of the IRQ
+ interrupts: VINTER and VPRCED, vectored at locations 514 to 517
+ ($202 to $205). These interrupts are unused by the OS, but also
+ may be used to provide greater control over external devices.
+
+
+ 54016 D300 PORTA
+
+ (W/R) Reads or writes data from controller jacks one and two if BIT
+ 2 of PACTL (location 54018) is one. Writes to direction control if
+ BIT 2 of PACTL is zero.
+
+ These two port registers also control the direction of data flow to
+ the port, if the controller register (54018, below) is POKEd with 48
+ ($30). Then, if the bits in the register read zero, it is in input (R)
+ mode; if they read one, it is in output (W) mode. A zero POKEd
+ here makes all bits input, a 255 ($FF) makes all bits output. BITs 0
+ to 3 address pins one to four on jack one, BITs 4 to 7 address pins
+ one to four on jack two. POKE 54018 with 52 to make this location
+ into a data register again. Shadow registers are: STICK0 (632;
+ $278, jack one), STICK1 (633; $279, jack two) and PTRIG0-3
+ (636-639; $27C-$27F).
+
+ Bits used as data register
+ 7 6 5 4 3 2 1 0
+ --Jack 0-- --Jack 1--
+ --Stick 1-- --Stick 0--
+
+ Forward = BIT 0, 4 = 1
+ Backward = BIT 1, 5 = 1
+ Left = BIT 2,6 = 1
+ Right = BIT 3,7 = 1
+ Neutral = All four jack bits = 1
+
+ PORTA is also used to test if the paddle 0-3 triggers (PTRIG) have
+ been pressed, using these bits:
+
+ Bit 7 6 5 4 3 2 1 0
+ PTRIG 3 2 - - 1 0 - -
+
+ Where zero in the appropriate bit equals trigger pressed, one
+ equals trigger not pressed.
+
+ The PORT registers are also used in the keyboard controller (used
+ with a keypad) operation where:
+
+ Bit 7 6 5 4 3 2 1 0
+ Row 4 3 2 Top 4 3 2 Top
+ Jack ..........2.......... ..........1...........
+
+ Columns for the keyboard operation are read through the POT
+ (PADDL) and TRIG registers. See Micro, May 1982, and the
+ Hardware Manual for more information on jacks and ports.
+
+
+ 54017 D301 PORTB
+
+ (W/R) Port B. Reads or writes data to and/or from jacks three and
+ four. Same as PORTA, above, for the respective jacks. Shadow
+ registers are: STICK2 (634; $27A, jack three), STICK3 (635, $27B,
+ jack four), and PTRIG4-7 (640-643; $280-$283).
+
+
+ 54018 D302 PACTL
+
+ (W/R) Port A controller (see 54016 above). POKE with 60 ($3C) to
+ turn the cassette motor off, POKE with 52 to turn it on. You can put
+ a music cassette in your program recorder, press PLAY and then
+ POKE 54018,52. Your music will play through the TV speaker or
+ external amplifier while you work at the Atari. You can use this
+ technique to add voice tracks to your programs. To turn off the
+ music or voice, type POKE 54018,60.
+
+ PACTL can be used for other external applications by the user. Bit
+ use is as follows:
+
+ Bit Function
+ 7 (read only) Peripheral A interrupt (IRQ) status bit. Set by
+ Peripheral (PORT) A. Reset by reading PORTA
+ (53774; $D20E).
+ 6 Set to zero.
+ 5 Set to one.
+ 4 Set to one.
+ 3 (write) Peripheral motor control line (turn the cassette on
+ or off; zero equals on).
+ 2 (write) Controls PORTA addressing. One equals PORTA
+ register; zero equals direction control register.
+ 1 Set to zero.
+ 0 (write) Peripheral A interrupt (IRQ) enable. One equals
+ enable. Set by the OS but available to the user;
+ reset on powerup.
+
+
+ 54019 D303 PBCTL
+
+ (W/R) Port B controller. Initialized to 60 ($3C) by the OS IRQ
+ code. PBCTL is the same as PACTL, above, with the following
+ exception (this may actually perform the same function as in
+ PACTL, but I am not sure of the distinction between descriptions):
+
+ Bit Function
+ 3 Peripheral command identification (serial bus
+ command), initialized to 60 ($3C).
+
+ Ports can be used for external control applications by the
+ technically minded reader who is willing to do some soldering to
+ develop cables and connectors. A good example can be found in
+ COMPUTE!, February 1981, where the author gives directions for
+ using jacks three and four as a printer port. The Macrotronic
+ printer cables use just this method, bypassing the 830 interface
+ entirely (one way of reducing your hardware costs). Theoretically,
+ the entire Atari can be controlled through the ports!
+
+ ---------------------------------------------------------------------------
+ Locations 54020 to 54271 ($D304 to $D3FF) are repeats of locations
+ 54016 to 54019 ($D300 to $D303).
+
+ ---------------------------------------------------------------------------
+
+
+ ANTIC
+
+ 54272-54783 D400-D5FF
+
+ ANTIC is a special, separate microprocessor used in your Atari
+ to control C/GTIA, the screen display, and other screen-related
+ functions including processing the NMI interrupts. It uses its own
+ instruction set, called the display list, which tells ANTIC where to
+ find the screen data in RAM and how to display it. ANTIC also
+ uses an internal four bit counter called the Delta Counter (DCTR)
+ to control the vertical dimension of each block.
+
+
+ 54272 D400 DMACTL
+
+ (W) Direct Memory Access (DMA) control. It is also used to
+ define one- or two-line resolution for players and to turn on
+ players and missiles. Values are POKEd into the shadow register,
+ 559 ($22F), and are also described there. You POKE the shadow
+ register with the following numbers in order to:
+
+ Turn off the playfield 0
+ Use narrow playfield 1
+ Use normal playfield 2
+ Use wide playfield 3
+ Enable missile DMA 4
+ Enable player DMA 8
+ Enable both player and missile DMA 12
+ Single line player resolution 16
+ Enable DMA Fetch instructions 32
+
+ Double line resolution is the default status. Use this register in
+ conjunction with GRACTL at 53277 ($D01D). Both must be set
+ properly or no display will result. BIT 5 enables DMA to fetch the
+ display list instructions. If BIT 5 is not set (BIT 5 equals zero),
+ ANTIC will not work. DMACTL is initialized to 34 ($22).
+ A player in single line resolution might look like this:
+
+ 00011000 ##
+ 00111100 ####
+ 01111110 ######
+ 11111111 ########
+ 11111111 ########
+ 01111110 ######
+ 00111100 ####
+ 00011000 ##
+
+ so that each byte is displayed on one TV line. The same player in
+ double line resolution would look like this:
+
+ 00011000 ##
+ 00011000 ##
+ 00111100 ####
+ 00111100 ####
+ 01111110 ######
+ 01111110 ######
+ 11111111 ########
+ 11111111 ########
+ 11111111 ########
+ 11111111 ########
+ 01111110 ######
+ 01111110 ######
+ 00111100 ####
+ 00111100 ####
+ 00011000 ##
+ 00011000 ##
+
+ where every byte is displayed over two TV lines.
+
+
+ 54273 D401 CHACTL
+
+ (W) Character mode control. See shadow register 755 for values
+ that can be POKEd in. Only the least three bits (decimal zero to
+ seven) are read, as below:
+
+ Decimal 0 1 2 3 4 5 6 7
+ Cursor
+ Transparent X X X X
+ Opaque X X X X
+ Present X X X X
+ Absent X X X X
+ ----------------------------------------------------------------------
+ Characters
+ Normal X X X X
+ Inverted X X X X
+
+
+ 54274,5 D402,3 DLISTL/H
+
+ Display list pointer. Tells the OS the address of the display list
+ instructions about what screen mode(s) to display and where to
+ find the screen data. See SDLIST (560, 561; $230, $231).
+
+
+ 54276 D404 HSCROL
+
+ (W) Horizontal scroll enable, POKE HSCROL with from zero to
+ 16 clock cycles for the number of cycles to scroll. Horizontal fine
+ scrolls can be used only if BIT 4 of the display list instruction is
+ set. The difficulty in horizontal scrolling lies in arranging the
+ screen data to be scrolled in such a manner as to prevent
+ wraparound (i.e., the bit or byte scrolled off screen in one line
+ becomes the bit or byte scrolled on screen in an adjacent line).
+ Normal data arranged for TV display looks like this on the screen:
+
+ +----------+
+ |..........|
+ |..........|
+ |..........|
+ |..........|
+ |..........|
+ |..........|
+ +----------+
+
+ where it is a one-dimensional memory area "folded" at the proper
+ places to create the image of a two dimensional screen. This is
+ done by the DL character or map mode instruction. Without
+ other instructions, it reads the memory continuously from the first
+ specified location, each line taking the correct number of bytes
+ for the GRAPHICS mode specified. To properly scroll it
+ horizontally, you must arrange it in relation to the TV screen like
+ this:
+
+ +----------+
+ .....|..........|.....
+ .....|..........|.....
+ .....|..........|.....
+ .....|..........|.....
+ .....|..........|.....
+ .....|..........|.....
+ +----------+
+
+ Now you will have to make each display instruction for each line
+ into a Load Memory Scan (LMS) instruction. To direct each LMS
+ to the proper screen RAM for that line, you will have to increment
+ each memory location by the total length of the line. For
+ example, if you want to scroll a 256-byte horizontal screen, each
+ LMS instruction will have to point to a location in memory 256
+ bytes above the last one. Of course, you will have to implement
+ error-trapping routines so that your screen does not extend
+ beyond your desired boundaries.
+
+ Coarse scrolling, one byte at a time, can be done without setting
+ the HSCROL register by the method described above. For
+ smooth scrolling, you will have to use this register. See De Re
+ Atari.
+
+
+ 54277 D405 VSCROL
+
+ (W) Vertical scroll enable, POKE VSCROL with from zero to 16
+ scan lines, depending on the GRAPHICS mode of the screen for
+ the number of scan lines to scroll. Vertical fine scrolls can be
+ used only if BIT 5 of the display list instruction has been set.
+
+ Coarse scrolling can be done without using this register, simply
+ by moving the top of the screen address (as defined by the DL
+ LMS instruction) up or down one mode line (plus or minus 40 or
+ 20 bytes, depending on the GRAPHICS mode). The top of the
+ screen address can be found by:
+
+ 10 DLIST = PEEK(560) + PEEK(561) * 2
+ 56
+ 20 SCRNLO = DLIST + 4: SCRNHI = DLIS
+ T + 5: REM LSB/MSB OF SCREEN ADDRE
+ SS
+ 25 PRINT "SCREEN ADDRESS = " PEEK(SC
+ RNLO) + PEEK(SCRNHI) * 256
+
+ You could then add a routine to this for a coarse - scroll vertically
+ through the memory with a joystick, such as:
+
+ 30 LOBYTE = 0: HIBYTE = 0
+ 40 IF STICK(0) = 14 THEN LOBYTE = LO
+ BYTE + 40:GOTO 100
+ 50 IF STICK(0) = 13 THEN LOBYTE = LO
+ BYTE - 40
+ 60 IF LOBYTE < 0 THEN LOBYTE = LOBYT
+ E + 256: HIBYTE = HIBYTE - 1
+ 70 IF HIBYTE < 0 THEN HIBYTE = 0
+ 80 GOTO 200
+ 100 IF LOBYTE 255 THEN LOBYTE = LOB
+ YTE - 256
+ 110 HIBYTE = HIBYTE + 1
+ 200 POKE SCRNLOW, LOBYTE: POKE SCRNHI
+ , HIBYTE
+ 210 GOTO 40
+
+ DOWNLOAD VSCROL.BAS
+
+ Coarse scrolling is relatively easy to implement in the Atari: one
+ basically alters the screen RAM to display the new material. Fine
+ scrolling is more difficult: each scroll register must be POKEd
+ with the number of units to be scrolled -- color clocks or scan
+ lines -- and the corresponding display list instructions must have
+ the proper bits set. This means you can selectively fine scroll any
+ mode lines you wish by setting only those bits of the lines you
+ intend to scroll. Other lines will be displayed normally. You can
+ set a DL instruction for both horizontal and vertical scroll enable.
+ See the Hardware Manual for a discussion of the problems in fine
+ scrolling.
+
+ Fine scrolling will allow only a certain amount of data to be
+ scrolled before the register must be reset (16 clock bits or scan
+ lines maximum). In order to make the scrolling activity
+ continuous, the register involved must be reset to zero when the
+ desired value is reached, a coarse scroll must be implemented
+ (usually during a DLI or VBLANK interval) and a new fine scroll
+ begun. This is not easily done in BASIC since it is too slow, and
+ changing registers during ANTIC's display process usually
+ causes rough or jerky motion. Assembly routines are suggested
+ for smooth display. See De Re Atari, Micro, November 1981,
+ BYTE, January 1982, and Santa Cruz's Tricky Tutorial #2 for
+ more information.
+
+
+ 54278 D406 ....
+
+ Unused.
+
+
+ 54279 D407 PMBASE
+
+ (W) MSB of the player/missile base address used to locate the
+ graphics for your players and missiles (the address equals
+ PMBASE * 256. P/M graphics are tricky to use since there are no
+ direct Atari 8K BASIC commands to either create or move them
+ (there are, however, commands for P/M graphics in BASIC A+
+ and in valFORTH utilities).
+
+ Your P/M graphics must always begin on a 1K boundary
+ (PEEK(RAMTOP)-4 for double line resolution players) or 2K
+ boundary (PEEK(RAMTOP)-5 for single line resolution), so the
+ LSB is always zero (page numbers always end in $XX00). For
+ example:
+
+ 10 POKE 106, PEEK(106) - 8: GRAPHIC
+ S 8: SETCOLOR 2,3,4
+ 20 POKE 559,62: POKE 53248,100: POK
+ E 704,160: POKE 53256,2
+ 30 MEM = PEEK(106) - 8
+ 40 POKE 54279, MEM: POKE 53277,3: S
+ TART = MEM * 256 + 1024
+ 50 FOR LOOP = 100 TO 119: READ BYTE
+ : POKE START + LOOP, BYTE: NEXT LO
+ OP
+ 60 DATA 16,16,56,40,40,56,40,40,40
+ 70 DATA 124,84,124,84,254,146,254,1
+ 70,170,68
+ 100 END
+
+ You can change the color, width, resolution, and horizontal
+ position of the player in the example by altering the registers
+ used above.
+
+ Each player is one byte (eight bits) wide. Single line resolution
+ P/M characters (POKE 559,62) can be up to 256 bytes high.
+ Double line resolution P/M characters (POKE 559,46) can be up
+ to 128 bytes high. In either case, they can map to the height of the
+ screen. Missiles have the same height, but are only two bits wide
+ each. Four missiles can be combined into a fifth player by setting
+ BIT 4 of location 623 ($26F). You need not fill the entire height of
+ a P/M character, but you should POKE unused bytes with zero to
+ eliminate any screen garbage. You can do this by:
+
+ FOR N = PMBASE + 1024 TO PMBASE + 2048:
+ POKE N,0: NEXT N
+
+ where PMBASE is the starting address of the reserve memory
+ area. In double line resolution, change the loop value to N =
+ PMBASE + 512 TO PMBASE + 1024. Here's a short machine
+ language routine to do the same thing. You would put the start
+ address of the area to be loaded with zero and the number of
+ bytes to be cleared in with the USR call as the first two
+ parameters. In this example, I have arbitrarily chosen 38012 and
+ 2048 for these values.
+
+ 10 START = 38012: BYTE = 2048: DIM
+ PGM$(42)
+ 20 FOR LOOP = 1 TO 42: READ ML: PGM
+ $(LOOP, LOOP) = CHR$(ML): NEXT LOO
+ P
+ 30 DATA 104,104,133,204,104,133,203
+ ,104,133,206,104
+ 40 DATA 133,205,166,206,160,0,169,0
+ ,145,203,136
+ 50 DATA 208,251,230,204,202,48,6,20
+ 8,244,164
+ 60 DATA 205,208,240,198,204,160,0,1
+ 45,203,96
+ 70 A = USR(ADR(PGM$),START,BYTE)
+
+ You can use this routine to clear out memory anywhere in the
+ Atari. You can also use it to load any one value into memory by
+ changing the second zero (after the 169) in line 40 to the value
+ desired.
+
+ Locating your graphics tables at the high end of memory may
+ cause addressing problems for playfield graphics, or may leave
+ some of the display unusable and cause PLOT to malfunction. If
+ you locate your tables just before the screen display, it may be
+ erased if you change graphics modes. You can look at your
+ highest RAM use graphics statement and plan accordingly. To
+ calculate a safe starting address below the display list, try:
+
+ 100 DLIST = PEEK(560) + PEEK(561) * 256: PMBASE =
+ INT (DLIST/SIZE -1) * SIZE
+
+ where SIZE is 2048 for single line resolution, 1024 for double
+ line.
+
+ Once you have the starting address, determine the ending
+ address of your table by adding the correct number of bytes for
+ the size (same as the SIZE variable above), and POKE this
+ number (LSB/MSB) into APPMHI at locations 14 and 15 ($E, $F).
+ This sets the lower limit for playfield graphics memory use. If you
+ change graphics modes in the program now, it should leave your
+ player tables intact. For example, if the DL is at 39968, the
+ PMBASE will equal 36864 in the equation above. Add 2048
+ (single line resolution) to get 38912. This is $9800. In decimal,
+ the LSB is zero and the MSB is 152. POKE these values into
+ APPMHI. This sets the lowest limit to which the screen and DL
+ data may descend.
+
+ The unused portion of the RAM set aside for P/M use, or any
+ RAM reserved for players, but not used, may be used for other
+ purposes in your program such as machine language routines.
+ See the appendix for a map of P/M memory use. The register
+ stores the address as below:
+
+ Bit 7 6 5 4 3 2 1 0
+ One line resolution: ......MSB....... ...unused...
+ Two line resolution: ........MSB......... unused..
+
+ There are some restrictions on locating your P/M data above the
+ display list. If not positioned far enough above your screen data,
+ you may end up with both the normal and screen data being
+ displayed at once, resulting in garbage on the screen. A display
+ list may not cross a 1K boundary without a jump instruction, and
+ the screen display RAM cannot cross a 4K boundary without an
+ LMS instruction to point to the proper byte(s). Due to problems
+ that arise when moving the GR.7 and GR.8 screens and data less
+ than 4K, you should never reserve less than 16 pages above
+ RAMTOP in these modes. If you are reserving more, add the
+ pages in blocks of 4K (16 pages).
+ See COMPUTE!, September 1981, for a discussion of the
+ problems of positioning P/M graphics in memory, and using P/M
+ graphics for animation.
+ See De Re Atari, COMPUTE!, June 1982, and Creative
+ Computing, April 1982, for a discussion of using string
+ manipulation with P/M graphics. See Your Atari 400/800 for a
+ general discussion of P/M graphics. Most of the popular
+ magazines have also carried articles on simplifying P/M
+ graphics.
+
+
+ 54280 D408 ....
+
+ Unused.
+
+
+ 54281 D409 CHBASE
+
+ (W) Character base address; the location of the start of the
+ character set, either the standard Atari set or a user-designed set.
+ The default is 224 ($E0), which points to the start of the Atari
+ ROM character set. Iridis, a short-lived disk -and- documentation
+ magazine, produced a good utility called FontEdit to aid in the
+ design of altered character sets. Online Systems' program The
+ Next Step is also very useful for this purpose, as is COMPUTE!'s
+ "SuperFont," January 1982. Uses shadow register 756 ($2F4).
+ Normally, this points to location 57344 or 57856 ($E000 or $E200)
+ depending on your choice of characters used in which text mode.
+ GRAPHICS mode zero uses the entire 128-character set; GR.1
+ and GR.2 use only half the set (64 characters). You POKE a
+ different number into the shadow register at 756 ($2F4) to point to
+ your own character set in RAM. This must be an even number
+ that points to a page in memory that is evenly divisible by two. In
+ GR.1 and GR.2 this number is 224 (pointing to $E000), giving
+ you uppercase, punctuation and numbers. POKEing the shadow
+ or this location (in machine language) with 226 will give you
+ lowercase and control characters.
+ See the information about the ROM character set at 57344
+ ($E000).
+
+
+ 54282 D40A WSYNC
+
+ (W) Wait for horizontal synchronization. Allows the OS to
+ synchronize the vertical TV display by causing the 6502 to halt
+ and restart seven machine cycles before the beginning of the
+ next TV line. It is used to synchronize the VBI's or DLI's with the
+ screen display.
+ To see the effect of the WSYNC register, type in the second
+ example of a Display List Interrupt at location 512. RUN it and
+ observe that it causes a clean separation of the colors at the
+ change boundary. Now change line 50 to:
+
+ 50 DATA 72,169,222,234,234,234,141,24,208,104,64
+
+ This eliminates the WSYNC command. RUN it and see the
+ difference in the boundary line.
+
+ The keyboard handler sets WSYNC repeatedly while generating
+ the keyboard click on the console speaker at 53279 ($D01F).
+ When interrupts are generated during the WSYNC period, they
+ get delayed by one scan line. To bypass this, examine the
+ VCOUNT register below and delay the interrupt processing by
+ one line when no WSYNC delay has occurred.
+
+
+ 54283 D40B VCOUNT
+
+ (R) Vertical line counter. Used to keep track of which line is
+ currently being generated on the screen. Used during Display
+ List Interrupts to change color or graphics modes. PEEKing here
+ returns the line count divided by two, ranging from zero to 130
+ ($82; zero to 155 on the PAL system; see 53268; $D014) for the
+ 262 lines per TV frame.
+
+
+ 54284 D40C PENH
+
+ (R) Light pen horizontal position (564). Holds the horizontal color
+ clock count when the pen trigger is pressed.
+
+
+ 54285 D40D PENV
+
+ (R) Light pen vertical position (565). Holds the VCOUNT value
+ (above) when the pen trigger is pressed. See the Hardware
+ Manual, p. II-32, for a description of light pen operation.
+
+
+ 54286 D40E NMIEN
+
+ (W) Non-maskable interrupt (NMI) enable. POKE with 192 to
+ enable the Display List Interrupts. When BIT 7 is set to one, it
+ means DL instruction interrupt; any display list instruction where
+ BIT 7 equals one will cause this interrupt to be enabled at the
+ start of the last video line displayed by that instruction. When BIT
+ 6 equals one, it allows the Vertical Blank Interrupt and when BIT
+ 5 equals one, it allows the RESET button interrupt. The RESET
+ interrupt is never disabled by the OS. You should never press
+ RESET during powerup since it will be acted upon.
+
+ NMIEN is set to 64 ($40) by the OS IRQ code on powerup,
+ enabling VBI's, but disabling DLI's. All NMI interrupts are
+ vectored through 65530 ($FFFA) to the NMI service routine at
+ 59316 ($E7B4) to determine their cause.
+
+ Bit 7 6 5 4 3 2 1 0
+ Interrupt: DLI VBI RESET .... unused .....
+
+
+ 54287 D40F NMIRES
+
+ (W) Reset for NMIST (below); clears the interrupt request
+ register; resets all of the NMI status together.
+
+
+ NMIST
+
+ (R) NMI status; holds cause for the NMI interrupt in BITs 5, 6 and
+ 7; corresponding to the same bits in NMIEN above. If a DLI is
+ pending, a jump is made through the global RAM vector
+ VDSLST (512; $200). The OS doesn't use DLI's, so 512 is
+ initialized to point to an RTI instruction and must be changed by
+ the user before a DLI is allowed.
+
+ If the interrupt is not a DLI, then a test is made to see if the
+ interrupt was caused by pressing RESET key and, if so, a jump is
+ made to 58484 ($E474). If not a RESET interrupt, then the system
+ assumes the interrupt was a VBLANK interrupt, and a jump is
+ made through VVBLKI at 546 ($222), which normally points to
+ the stage one VBLANK processor. From there it checks the flag at
+ CRITIC (66; $42) and, if not from a critical section, jumps
+ through VVBLKD at 548 ($224), which normally points to the
+ VBLANK exit routine. On powerup, the VBLANK interrupts are
+ enabled while the display list interrupts are disabled. See the end
+ of the memory map for a description of the VBLANK procedures.
+ For IRQ interrupts, see location 53744 ($D20E).
+
+ ---------------------------------------------------------------------------
+ Locations 54288 to 54303 ($D410 to $D41F) are repeats of locations
+ 54272 to 54287 ($D400 to $D40F).
+
+ ---------------------------------------------------------------------------
+ Locations 54784 to 55295 ($D600 to $D7FF) are unused but not empty
+ nor user alterable. See the note at 53504 ($D100).
+
+ ---------------------------------------------------------------------------
+
+ OPERATING SYSTEM ROM
+
+ Locations 55296 to 65535 ($D800 to $FFFF) are the OS ROM.
+ These locations are contained in the 10K ROM cartridge, which sits in
+ the front slot of the Atari 800 or inside the Atari 400. The OS is
+ identical for both computers.
+
+ The locations given here are for the "A" version of the OS ROMs.
+ There are changes in the new "B" version ROMs, which are explained
+ in the appendix. Most of the changes affect the interrupt handler
+ routines and SIO. In making these changes, Atari cured some bugs
+ such as the device time-out problem. Unfortunately, there is a cloud
+ with this silver lining: not all of your old software will run with the new
+ ROMs. Megalegs, one of my favorite games, cannot run under the new
+ ROMs. A pity that. There are others; I'm sure you'll find them. The
+ solution is to have both sets of ROMs so you can use all of your
+ software.
+
+
+ FLOATING POINT PACKAGE ROM
+
+ Locations 55296 to 57343 ($D800 to $DFFF) are reserved for the ROM's
+ Floating Point Mathematics Package. There are other areas used by the
+ FP package: page zero (locations 212 to 254; $D4 to $FE) and page five
+ (locations 1406 to 1535; $57E to $5FF), which are used only if FP
+ routines are called. There are also trigonometric functions in the BASIC
+ cartridge located between 48549 and 49145 ($BDA5 to $BFF9) which
+ use the FP routines. See De Re Atari for more information.
+
+ These are the entry points to some of the subroutines; unless otherwise
+ noted, they use FP register zero (FR0 at 212 to 217, $D4 to $DB):
+
+
+ 55296 D800 AFP
+
+ ASCII to Floating Point (FP) conversion.
+
+
+ 55526 D8E6 FASC
+
+ FP value to ASCII conversion.
+
+
+ 55722 D9AA IFP
+
+ Integer to FP conversion.
+
+
+ 55762 D9D2 FPI
+
+ FP to integer conversion.
+
+
+ 55876 DA44 ZFR0
+
+ Clear FR0 at 212 to 217 ($D4-$DB) by setting all bytes to zero.
+
+
+ 55878 DA46 ZF1
+
+ Clear the FP number from FR1, locations 224 to 229 ($E0 to $E5),
+ by setting all bytes to zero. Also called AF1 by De Re Atari.
+
+
+ 55904 DA60 FSUB
+
+ FP subtract routine, the value in FR0 minus the value in FR1.
+
+
+ 55910 DA66 FADD
+
+ FP addition routine; FR0 plus FR1.
+
+
+ 56027 DADB FMUL
+
+ FP multiplication routine; FR0 times FR1.
+
+
+ 56104 DB28 FDIV
+
+ FP division routine; FR0 divided by FR1.
+
+
+ 56640 DD40 PLYEVL
+
+ FP polynomial evaluation.
+
+
+ 56713 DD89 FLD0R
+
+ Load the FP number into FR0 from the 6502 X,Y registers.
+
+
+ 56717 DD8D FLD0P
+
+ Load the FP number into FR0 from user routine, using FLPTR at
+ 252 ($FC).
+
+
+ 56728 DD98 FLD1R
+
+ Load the FP number into FR1 from the 6502 X,Y registers.
+
+
+ 56732 DD9C FLD1P
+
+ Load the FP number into FR1 from user program, using FLPTR.
+
+
+ 56743 DDA7 FST0R
+
+ Store the FP number into the 6502 X,Y registers from FR0.
+
+
+ 56747 DDAB FST0P
+
+ Store the FP number from FR0, using FLPTR.
+
+
+ 56758 DDB6 FMOVE
+
+ Move the FP number from FR0 to FR1.
+
+
+ 56768 DDC0 EXP
+
+ FP base e exponentiation.
+
+
+ 56780 DDCC EXP10
+
+ FP base 10 exponentiation.
+
+
+ 57037 DECD LOG
+
+ FP natural logarithm.
+
+
+ 57041 DED1 LOG10
+
+ FP base 10 logarithm.
+
+ ---------------------------------------------------------------------------
+ Locations 57344 to 58367 ($E000 to $E3FF) hold the standard Atari
+ character set: at $E000 the special characters, punctuation and numbers
+ begin; at $E100 (57600) the capital letters begin; at $E200 (57856) the
+ special graphics begin, and at $E300 (58112) the lowercase letters
+ begin.
+
+ There are 1024 bytes here ($400), with each character requiring eight
+ bytes, for a total of 128 characters (inverse characters simply manipulate
+ the information here to reverse the bits by performing an OR with 128 --
+ the value in location 694 ($2B6) when the Atari logo key is toggled -- on
+ the bits. To return to the normal ATASCII display, the inverse characters
+ are EORed with 128). The first half of the memory is for numerals,
+ punctuation, and uppercase characters; the second half ($E200 to
+ $E3FF) is for lowercase and control characters. When you POKE 756
+ ($2F4) with 224 ($E0), you are POKEing it with the MSB of this address
+ ($E000). When you POKE it with 226 ($E2), you are moving the address
+ pointer to the second half of the character set. In GR.0, you have the
+ entire character set to use. In GR.1 and GR.2, you can use only one half
+ of the set at a time. You can't POKE it with 225 because the number
+ POKEd must be evenly divisible by two.
+
+ The characters stored here aren't in ATASCII order; they have their own
+ internal order for storage. The order of the characters is listed on page
+ 55 of your BASIC Reference Manual.
+
+ Here's an example of how a letter (A) is stored in ROM. Each line
+ represents a byte. The decimal values are those you'd find if you
+ PEEKed the eight locations where "A" is stored (starting at 57608;
+ $E108):
+
+ Bit 76543210 Decimal
+ +--------+
+ 00000000 0 | |
+ 00011000 24 | ## |
+ 00111100 60 | #### |
+ 01100110 102 | ## ## |
+ 01100110 102 | ## ## |
+ 01111110 126 | ###### |
+ 01100110 102 | ## ## |
+ 00000000 0 | |
+ +--------+
+
+ When you create your own character sets (or alter the Atari set
+ when you move it to RAM -- see location 756; $2F4 for a routine
+ to do this), you do a "bit-map" for each character as in the
+ example above. It could as easily be a spaceship, a Hebrew
+ letter, an APL character, or a face. Chris Crawford's game
+ Eastern Front 1941 (APX) shows excellent use of an altered
+ character set to create his large map of Russia, plus the symbols
+ for the armies.
+
+ Here's an example of using the bit-mapping of the character set
+ to provide text in GRAPHICS 8:
+
+ 1 GRAPHICS 8
+ 5 DLIST = PEEK(560) + PEEK(561)*256
+ 6 LOBYTE = DLIST+4: HIBYTE = DLIST +
+ 5
+ 7 REAL = PEEK(LOBYTE) + PEEK(HIBYTE)
+ *256: SCREEN = REAL: TV = SCREEN
+ 10 CHBASE = 57344
+ 20 DIM A$(128),BYTE(128),WANT(128)
+ 27 PRINT "INPUT A 40 CHARACTER STRIN
+ G:"
+ 30 INPUT A$
+ 35 TIME = TIME + 1
+ 40 FOR LOOK = 1 TO LEN(A$)
+ 50 BYTE(LOOK) = ASC(A$(LOOK,LOOK))
+ 51 IF BYTE(LOOK) > 127 THEN BYTE(LOO
+ K) = BYTE(LOOK) - 128
+ 52 IF BYTE(LOOK) < 32 THEN BYTE(LOOK
+ ) = BVTE(LOOK) + 64: GOTO 55
+ 53 IF BYTE(LOOK) < 97 THEN BVTE(LOOK
+ ) = BYTE(LOOK) - 32
+ 55 NEXT LOOK
+ 59 FOR EXTRA = 0 TO 7
+ 60 FOR LOOK = 1 TO LEN(A$)
+ 70 WANT(LOOK) = PEEK(CHBASE + EXTRA
+ + BYTE(LOOK)*8)
+ 80 POKE TV + EXTRA, WANT(LOOK): TV =
+ TV + 1
+ 82 NEXT LOOK
+ 85 SCREEN = SCREEN + 39: TV = SCREEN
+ 90 NEXT EXTRA
+ 100 SCREEN = REAL + TIME*320
+ 110 IF SCREEN > REAL + 6080 THEN TIM
+ E = 0: GOTO 100
+ 120 GOTO 30
+
+ DOWNLOAD BITMAP8.BAS
+
+ This program simply takes the bytes which represent the letters
+ you input as A$ and finds their places in the ROM character set.
+ It then proceeds to POKE the bytes into the screen RAM, using a
+ FOR-NEXT loop.
+
+ To convert ATASCII codes to the internal codes, use this table:
+
+ ATASCII value Operation for
+ internal code
+ 0 -- 31 add 64
+ 32 -- 95 subtract 32
+ 96 -- 127 remains the same
+ 128 -- 159 add 64
+ 160 -- 223 subtract 32
+ 224 -- 255 remains the same
+
+ See COMPUTE!, November 1981, for the program "TextPlot"
+ which displays text in different sizes in GRAPHICS modes three
+ to eight, and January 1982 for a program to edit character sets,
+ "SuperFont."
+
+ ---------------------------------------------------------------------------
+
+ Locations 58368 to 58447 ($E400 to $E44F) are the vector tables, stored
+ as LSB, MSB. These base addresses are used by resident handlers.
+ Handler vectors use the following format:
+
+ OPEN vector
+ CLOSE vector
+ GET BYTE vector
+ PUT BYTE vector
+ GET STATUS vector
+ SPECIAL vector
+ Jump to handler initialization routine (JMP LSB/MSB)
+
+ The device tables in location 794 ($31A) point to the particular
+ vector(s) used in each appropriate table. In each case, the 6502 X
+ register is used to point to the originating IOCB.
+
+
+ 58368 E400 EDITRV
+
+ Screen Editor (E:) entry point table.
+
+
+ 58383 E40F ....
+
+ If you PEEK here and get back 56, then you have the older "A"
+ version of the OS ROMs. If you get back zero, then you have the
+ newer "B" version that was released in January 1982. The "B"
+ version fixes some minor bugs, including the device time-out
+ problems, enables POKEY timer four, and provides a vector for
+ BREAK key interrupts. See Appendix 4.
+
+
+ 58384 E410 SCRENV
+
+ Display handler (television screen) (S:).
+
+
+ 58400 E420 KEYBDV
+
+ Keyboard handler (K:).
+
+
+ 58416 E430 PRINTV
+
+ Printer handler (P:).
+
+
+ 58432 E440 CASETV
+
+ Cassette handler (C:).
+
+ ---------------------------------------------------------------------------
+ Locations 58448 to 58533 ($E450 to $E4A5) are more vectors: those to
+ location 58495 ($E47F) are Jump vectors, those from 58496 to 58533
+ ($E480 to $E4A5) are the initial RAM vectors.
+
+
+ 58448 E450 DISKIV
+
+ Disk handler initialization vector, initialized to 60906 ($EDEA).
+
+
+ 58451 E453 DSKINV
+
+ Disk handler (interface) entry; checks the disk status. Initialized
+ to 60912 ($EDF0).
+
+
+ 58454 E456 CIOV
+
+ Central Input/Output (CIO) utility entry. CIO handles all of the
+ I/O operations or data transfers. Information placed in the
+ IOCB's tells CIO what operations are necessary. CIO passes this
+ information to the correct device driver routine and then passes
+ control to the Device Control Block (DCB). This in turn calls up
+ SIO (below) to control the actual peripheral(s). CIO treats all I/O
+ in the same manner: device independent. The differentiation
+ between operations is done by the actual device drivers.
+
+ You jump to here to use the IOCB handler routines in ROM.
+ BASIC supports only record I/O or one-byte-at-a-time I/O (GET
+ and PUT). Addressing CIOV directly will allow the user to input
+ or output a buffer of characters at a time, such as loading a
+ machine language program directly into memory from a disk file.
+ This is considerably faster than using BASIC functions such as
+ GET. Here is a typical machine language subroutine to do this:
+
+ PLA, PLA, PLA, TAX, JMP $E456
+ (104,104,104,170,76,86,228)
+ ($68,$68,$68,$AA,$4C,$56,$E4)
+
+ This gets the IOCB number into the 6502 X register and the
+ return address on the stack. CIOV expects to find the IOCB
+ number 16 in the 6502 X register (i.e., IOCB zero is zero, IOCB
+ one is 16; $10, IOCB two is 32, $20, etc.). $E456 is the CIO
+ initialization entry point (this address).
+
+ To use CIOV in a program, first you must have OPENed a
+ channel for the appropriate actions, POKEd the correct IOCB
+ (locations 848 to 959; $350 to $3BF) with the correct values, and
+ established a location in which to load your file (IOCB address
+ plus four and plus five). One use is calling up a high-res picture
+ from a disk and storing it in the screen memory (locations 88, 89;
+ $58, $59). You can POKE the appropriate decimal values into
+ memory and call it with a USR call, or make it into a string
+ (START$ = "hhh*LVd" where the * and the d are both inverse
+ characters) and call it by:
+
+ JUMP = USR(ADR(START$))
+
+ This method is used to start the concurrent mode in the RS-232 of
+ the 850 interface in the 850 Interface Manual. See location 88, 89
+ ($58, $59) for another example of the machine language routine
+ technique. Still another use of this method can be found in De Re
+ Atari. Initialized to 58564 ($E4C4).
+
+
+ 58457 E459 SIOV
+
+ Serial Input/Output (SIO) utility entry point. SIO drives the
+ serial bus and the peripherals. When a request is placed in the
+ Device Control Block (DCB) by a device handler, SIO takes
+ control and uses the data in the DCB to perform the operation
+ required. SIO takes care of the transfer of data as defined by the
+ DCB. CIO (above) is responsible for the "packaging" of the data
+ and transfers control to SIO when necessary. See the DCB
+ locations 768 to 779 ($300-$30B).
+ SIO first sends a command frame to the device, consisting of five
+ bytes: the device ID, the command BYTE, two auxiliary bytes for
+ device-specific information, then a checksum (which is the sum
+ of the first four bytes). If the device acknowledges this frame, it is
+ followed, if necessary, by the data frame of a fixed number of
+ bytes depending on the device record size, plus a checksum
+ byte. Initialized to 59737 ($E959).
+
+
+ 58460 E45C SETVBV
+
+ Set system timers during the VBLANK routine. Uses the 6502 X
+ register for the MSB of vector/times, Y for the LSB and A for the
+ number of the vector to hack (change). SETVBV insures that both
+ bytes of the vector addressed will be updated while VBLANK is
+ enabled. You can JSR here when creating your own timer
+ routines. See COMPUTE!, November 1981, for an application.
+ Initialized to 59666 ($E912) old ROMs, 59629 ($E8ED) new
+ ROMs.
+
+
+ 58463 E45F SYSVBV
+
+ Stage one VBLANK calculations entry. It performs the
+ processing of a VBLANK interrupt. Contains JMP instruction for
+ the vector in the next two addresses (58464, 58465; $E460,
+ $E461). This is the address normally found in VVBLKI (546, 547;
+ $222, $223). It is initialized to 59345 ($E7D1), which is the
+ VBLANK routine entry. Initialized to 59345 ($E7D1) old ROMs,
+ 59310 ($E7AE) new ROMs.
+
+
+ 58466 E462 XITVBV
+
+ Exit from the VBLANK routine, entry point. Contains JMP to the
+ address stored in next two locations (58467, 58468; $E463,
+ $E464). This is the address normally found in VVBLKD (548, 549;
+ $224, $225). Initialized to 59710 ($E93E), which is the VBLANK
+ exit routine. It is used to restore the computer to its pre-interrupt
+ state and to resume normal processing. Initialized to 59710
+ ($E93E) old ROMs, 59653 ($E905) new ROMs.
+
+
+ 58469 E465 SIOINV
+
+ SIO utility initialization, OS use only.
+
+
+ 58472 E468 SENDEV
+
+ Send enable routine, OS use only.
+
+
+ 58475 E46B INTINV
+
+ Interrupt handler initialization, OS use only.
+
+
+ 58478 E46E CIOINV
+
+ CIO utility initialization, OS use only.
+
+
+ 58481 E471 BLKBDV
+
+ Blackboard mode entry. Blackboard mode is the "ATARI MEMO
+ PAD" mode. It can be reached from BASIC by typing "BYE",
+ "B." or by powering up with no peripherals or cartridges.
+ Nothing you write to the screen in blackboard mode is acted
+ upon by the computer. You can enter this mode to protect your
+ programs temporarily from prying and curious fingers.
+
+ All of the screen editing commands continue to work in
+ blackboard mode. You can enter blackboard mode from any
+ graphics mode with a text window; the display screen will remain
+ intact on the screen while the text window will be in blackboard
+ mode. Pressing RESET will, of course, return the entire screen to
+ GR.0. You can also enter blackboard mode from a program, but
+ cannot get out of it in BASIC once you are in it.
+
+ If you entered blackboard mode from BASIC, you can return to it
+ by pressing RESET. Any BASIC program will still be there. So
+ will any RS-232 or DOS handlers previously booted. Initialized to
+ 61987 ($F223).
+
+
+ 58484 E474 WARMSV
+
+ Warmstart entry point (RESET button vector). Initializes the OS
+ RAM region. The RESET key produces an NMI interrupt and a
+ chip reset (see below). Jump to here on an NMI caused by
+ pressing the RESET key. Initialized to 61723 ($F11B).
+
+
+ 58487 E477 COLDSV
+
+ Coldstart (powerup) entry point. Initializes the OS and user RAM
+ regions; wipes out any program in memory. Initialized to 61733
+ ($F125).
+
+
+ 58490 E47A RBLOKV
+
+ Cassette read block routine entry, OS use only.
+
+
+ 58493 E47D CSOPIV
+
+ Cassette OPEN for input vector, OS use only.
+
+
+ 58496 E480 VCTABL
+
+ RAM vector initial value table.
+
+ ---------------------------------------------------------------------------
+
+ The following are the addresses for the handler routines:
+
+
+ 58534-59092 E4A6-E6D4 CIOORG
+
+ Addresses for the Central Input/Output routines (CIO):
+
+
+ 58534 ($E4A6) CIOINT
+
+ is the CIO initialization routine called by the monitor on powerup.
+
+
+ 58577 ($E4D1);
+
+ move the user IOCB to the ZIOCB.
+
+
+ 58596 ($E4E4);
+
+ check for a valid command.
+
+
+ 58633 ($E509);
+
+ OPEN command routines.
+
+
+ 58675 ($E533);
+
+ CLOSE command routines.
+
+
+ 58702 ($E54E);
+
+ STATUS and special command routines.
+
+
+ 58729 ($E569) CIREAD;
+
+ process the CIO commands for read and
+ write, including buffer check for full or empty.
+
+
+ 58907 ($E61B);
+
+ routine to return to the user from CIO.
+
+
+ 58941 ($E63D),
+
+ routines to compute the device handler entry point,
+ jump to the handler, transfer control, and then return to CIO after the
+ operation.
+
+
+ 59093-59715 E6D5-E943 INTORG
+
+ Addresses for the interrupt handler routines:
+
+
+ 59123 ($E6F3) PIRQ;
+
+ IRQ interrupt service routines start here.
+
+
+ 59126 ($E6F6);
+
+ the immediate IRQ vector to the IRQ handler. The
+ global NMI and IRQ RAM vectors in locations 512 to 527 ($200 to $20F)
+ are all initialized to this area (59142, $E706 for the new OS ROMs).
+
+
+ 59314 ($E7B2);
+
+ the vector for the IRQ interrupts on powerup; it
+ points to a PLA and RTI instruction sequence (new OS ROMs; 59219;
+ $E78F).
+
+
+ 59316 ($E7B4) PNMI;
+
+ the NMI handler, tests for the reason for the
+ NMI, then jumps through the appropriate RAM vector. Also called the
+ Interrupt Service Routine (ISR).
+
+
+ 59345 ($E7D1) SYSVBL;
+
+ the VBLANK routines start here,
+ including frame counter, update timer, update hardware registers
+ from shadow registers, update the attract mode counter and the
+ realtime clock. The vertical blank immediate vector, VVBLKL1,
+ normally pointed to by locations 546, 547 ($222, $223), points to here.
+ The Updated OS ROMs point to 59310 ($E7AE).
+
+
+ 59666 ($E912) SETVBL;
+
+ subroutines to set the VBLANK timers
+ and vectors.
+
+ The vertical blank deferred interrupt, normally vectored from
+ locations 548, 549 ($224, $225), points to 59710 ($E93E). In the
+ Updated OS ROMs, it points to 59653 ($E905). In both cases they point
+ to the VBLANK exit routine.
+
+ See page 104 of the OS User's Manual for a list of the vectors and
+ MICRO, January 1982, for an explanation of the VBLANK process.
+
+
+ 59716-60905 E944-EDE9 SIOORG
+
+ Routines for the Serial Input/Output (SIO) routines:
+
+
+ 60011 ($EA6B) SEND;
+
+ is the SIO send buffer routine entry.
+
+
+ 60048 ($EA90) ISRODN,
+
+ is the serial output ready IRQ vector.
+
+
+ 60113 ($EAD1) ISRTD;
+
+ is the serial output complete IRQ vector.
+ This is at 60111 ($EACF) in the new OS ROMs.
+
+
+ 60177 ($EB11) ISRSIR;
+
+ is the serial input ready IRQ vector. This
+ is 60175 ($EB0F) in the new OS ROMs.
+
+
+ 60292 ($EB84) CASENT;
+
+ is the start of the cassette handling code
+ SIO subroutine to set baud rate, tone values, inter-record gap, to load
+ the buffer from the cassette and to turn on the recorder motor. Write
+ routines are located in 61249 to 61666 ($EFF5 to $F0E2).
+
+
+ 60515 ($EC63)
+
+ is the start of the disable POKEY interrupts routine
+ entry, which also disables the send and receive functions.
+
+
+ 60583 ($ECA7) COMPUT;
+
+ is the subroutine to calculate baud
+ rate using the POKEY frequency registers and the VCOUNT timer.
+ The tables for the AUDF and VCOUNT values are between 60882 and
+ 60905 ($EDD2 and $EDE9).
+
+
+ 60906-61047 EDEA-EE77 DSKORG
+
+ Routines for the disk handler.
+ Initialization is at DINIT, 60906 ($EDEA), entry is at DSKIF, 60912
+ ($EDF0).
+
+
+ 61048-61248 EE78-EF40 PRNORG
+
+ Routines for the printer handler.
+
+
+ 61249-61666 EF41-F0E2 CASORG
+
+ Routines for the cassette handler.
+
+ The buzz used in the cassette CLOAD command can be called up from
+ BASIC by:
+
+ BUZZ = USR(61530).
+
+ You can turn it off with the RESET key. While this isn't terribly
+ exciting, it points to the potential of using the console speaker for
+ sound instead of merely for beeps (the RAM location for the speaker is
+ at 53279; $D01F). See the speaker location and COMPUTE!, August
+ 1981, for a short routine to use the speaker for sound effects.
+
+
+ 61667-62435 F0E3-F3E3 MONORG
+
+ Routines for the monitor handler. This is also the address area of
+ PWRUP, the powerup module (61733; $F125). Coldstart routines are
+ initialized to this location. The routine to check for cartridge
+ installation begins at 61845 ($F195). Hardware initialization begins at
+ 62081 ($F281).
+
+
+ 61723 ($F11B) RESET;
+
+ the RESET button routine starts here.
+
+
+ 62081 ($F281) HARDI,
+
+ the start of the hardware initialization
+ routines.
+
+
+ 62100 ($F294) OSRAM;
+
+ the start of the OS RAM initialization
+ and setup routines.
+
+
+ 62159 ($F2CF) BOOT;
+
+ the entry point for the disk boot routine.
+
+
+ 62189 ($F2ED) DOBOOT;
+
+ the disk boot routine activation.
+
+
+ 62334 ($F37E) DOPEN;
+
+ the entry point for the reinitialization
+ of disk software.
+
+
+ 62436-65535 F3E4-FFFF KBDORG
+
+ Routines for the display and keyboard handler. The display
+ handler beqins at 62454 ($F3F6) and the keyboard handler
+ begins at 63197 ($F6DD), below.
+
+
+ 63038 F63E EGETCH
+
+ Like the BASIC INPUT command, EGETCH gets a line from the
+ screen and keyboard, but only one character at a time. You must
+ do a JSR $F63E for each character input. This is also the address
+ of the beginning of the screen editor routines.
+
+
+ 63140 F6A4 EOUTCH
+
+ This routine puts the character currently in the accumulator onto
+ the screen in the next print location. Similar to the BASIC PUT
+ command.
+
+
+ 63197 F6DD KGETC2
+
+ Beginning of the keyboard handler.
+
+
+ 63202 F6E2 KGETCH
+
+ This routine waits for a key to be pressed and returns its value to
+ the accumulator (6502 register A). Similar to the BASIC GET
+ command.
+
+
+ 64428 FBAC SCROLL
+
+ The screen scroll routine starts here.
+
+
+ 64764 FCFC DRAW
+
+ Screen draw routines begin here, end at 65092 ($FE44). See
+ Creative Computing, March 1982, for an example of a
+ modification to the draw routines to avoid the "out-of-bounds"
+ error for use in GR.7+.
+
+
+ 65093-469 FE45-FFBD ....
+
+ The ROM tables for display lists, ANTIC codes, control codes,
+ and ATASCII conversion codes.
+
+
+ 65470 FFBE PIRQQ
+
+ Subroutines to test the acceptance of the last key pressed and to
+ process the debounce delay routines start here.
+ When a key is pressed, it initiates an IRQ through VKEYBD at
+ locations 520, 521 ($208, $209) to 65470 ($FFBE). This is the
+ keyboard service routine. It processes debounce, and SHIFT-
+ CTRL logic (see location 559; $22F); saves the internal keyboard
+ code in 754 ($2F2) and 764 ($2FC); sets the ATTRACT mode flag
+ at 77 ($4D) and sets location 555 ($22B -- SRTIMR) to 48 ($30).
+
+
+ 65528 FFF8 CHKSUN
+
+ According to Softside Magazine, December 1981, if a PEEK here
+ returns 255, then you have the older OS ROM(s). There were
+ some troubles with cassette loads in the older ROMs that
+ sometimes require the following to cure:
+
+ Do an LPRINT without a printer attached before CLOAD. This
+ clears the cassette buffer.
+
+ Press RESET before CSAVEing or CLOADing will restore the
+ system to its initialization parameters and help with loading and
+ saving routines.
+
+ There is a new OS available from Atari which fixes a bug that
+ would cause the I/O operations to "time out" for a few seconds. It
+ apparently does not alter any of the routines mentioned here.
+
+ The chip reset interrupt (powerup) vectors through location
+ 65532 ($FFFC) to 58487 ($E477) where a JMP vector to the
+ powerup routine is located. A chip reset is not the same as
+ pressing the RESET key, which in itself does not generate a chip
+ reset.
+
+ The NMI interrupts are vectored through 65530 ($FFFA) to the
+ NMI service routine (ISR) at 59316 ($E7B4), and all IRQ
+ interrupts are vectored through 65534 ($FFFE) to the IRQ service
+ routine at 59123 ($E6F3). In these service routine areas, the
+ cause of the interrupt is determined, and the appropriate action
+ is taken, either by the OS or through a JMP to a RAM vector
+ where a user routine exists.
+
+ ----------------------------------------------------------------------
+
+ Return to Table of Contents | Previous Chapter | Next Chapter
+
+
+
+
+
+
+
+
+
+
+
+ [IMG]
+ [IMG]