Classic Computer Magazine Archive A.N.A.L.O.G. ISSUE 72 / MAY 1989 / PAGE 68




MASTER MEMORY
MAP PART X

by Robin Sherer


How to Read the Memory Map

    Beginning users: Read the text that is printed in bold type only. These memory locations will be the easiest for you to use and usually don't involve assembly language.
    Advanced users: Read everything! Many areas of memory are not of any practical use, but you can learn a lot about how a computer works by reading the boring parts.



The Character Set

    The data for the regular Atari character set is stored in Locations 57344 through 58367. There are eight bytes for each character and 128 characters in all (for a grand total of 1024 bytes). But wait a minute. Doesn't the Atari have 256 characters? Yes, but the information for the regular characters is all the Atari needs to know to print inverse characters, so that's why there are only 128 character descriptions.
    For lots of information on how the bytes are used to describe a character, and on the order of the characters within the character set, see CHBAS at Location 756.
    The following program will use the character descriptions to put text on the screen in graphics mode 8:

100 GRAPHICS 8
105 SCRMEM=PEEK(88)+PEEK(89
)*256

110 DIM TEXT$(120)
120 PRINT "Start text in wh
at column (0-39)";
130 INPUT COL

140 PRINT "In what row (0-1
52)";

150 INPUT ROW
160 PRINT "Type in the text
 you want to print:"

170 INPUT TEXT$
180 CHSET=PEEK(756)*256
190 FOR CHAR=1 TO LEN(TEXT$
)
200 ATASC=ASC(TEXT$(CHAR,CH
AR))

210 NOINV=ATASC-128*(ATASC)
127)

220 INTRNL=NOINV-32*(NOINV<
96)+96*(NOINV(32)

230 FOR BYTE=CHSET+INTRNL*8
 TO CHSET+INTRNL*8+7

240 POKE SCRMEM+ROW*40+COL,
ABS(255*(ATASC>127)-PEEK(BY
TE))

250 ROW=ROW+1
260 NEXT BYTE
270 ROW=ROW-8
280 COL=COL+1
290 IF COL=40 THEN COL=0:RO
W=ROW+8

300 NEXT CHAR
310 PRINT
320 GOTO 120


Vectors and Vector Tables
     What are vector tables? You remember that a vector is a pair of memory locations that holds the address of a routine. A vector table is, quite simply, a table of vectors. Thus, Locations 58368 through 58533 hold the addresses of various routines, mostly having to do with I/O or interrupts.

EDITRV
58368-58383     E400-E40F

    This is the vector table for the screen-editor handler. For a description of its contents, along with the contents of the next four vector tables, see HATABS at Locations 794 through 831 (where we called it a "handler address table").

SCRENV
58384-58399     E410-E41F

    The vector table for the display handler. See the note at EDITRV.

KEYBDV
58400-58415     E420-E42F

    The vector table for the keyboard handler. See the note at EDITRV.

PRINTV
58416-58431     E430-E43F

    The vector table for the printer handler. See the note at EDITRV.

CASETV
58432-58447     E440-E44F

    The vector table for the cassette handler. See the note at EDITRV.
    You will notice that the following 16 vectors are three bytes long rather than two. Why the extra byte? The first byte is a 6502 JMP instruction, while the address is in the second two bytes.
    The purpose of these vectors may not be obvious to you (it wasn't to me). Atari knew that it would probably need to make changes to the OS at some point. It also wanted to make sure that old programs would still be able to work with these newer versions of the OS, even though some of the addresses would be different. The solution was to use vectors. That way, even though the addresses in the vectors would change, the addresses of the vectors would remain the same, and programs using these addresses would still work. The reason that some programs don't work with Version B of the OS is that these programs didn't use the vectors.

DISKIV
58448-58450     E450-E452

    DISKIV is the initialization vector for the disk handler. It points to Location 60906.

DISKINV
58451-58453     E453-E455

    This is the entry vector for the disk handler. It points to Location 60912.

CIOV
48454-48456     E456-E458

    CIOV is the entry vector for CIO (Central Input/Output).
    You can see CIO yourself by first setting up an IOCB (see Locations 832 through 959), and then using the following routine:


100 DIM ML$(7)
110 GOSUB 10000
120 CIO=USR(ADR(ML$),IOCB*1
6)

130 END
10000 FOR BYTE=1 TO 7
10010 READ INSTR
10020 ML$(BYTE,BYTE)=CHR$(I
NSTR)

10030 NEXT BYTE
10040 RETURN
10050 DATA 104,104,104,170,
32,86,228



    The data is for this machine-language routine:


68     PLA
68     PLA
68     PLA
AA     TAX
2056E4 JSR  $E456


    CIO expects the number of the IOCB you want to use, times 16, in the X register. That's why we have IOCB*16 in the preceding program. You should substitute the IOCB number you are using for IOCB. Remember to OPEN the IOCB first.
    CIOV points to 58564.

SIOV
58457-58469     E459-E45B
    This is the entry vector for SIO (Serial Input/output).

    SIOV points to 59737.

SETVBV
58460-58462     E45C-E45E

    SETVBV is the entry vector for a routine that serves two purposes. First of all, as we saw at VVBLKD (548,549), it will set up VVBLKI and VVBLKD for us. Second, as we saw at CDTMAI (550,551), it will also set up the vectors for the system timers. See VVBLKD and CDTMAI for more information.
    SETBV points to 59666 in Version A of the OS, and to 59629 in Version B.

SYSVBV
58463-58465     E45F-E461

    This is the entry vector for the Stage 1 VBLANK routine. Unless you have your own routine, VVBLKI (546,547) normally points here. See VVBLKI and VVBLKD (548,549) for more information on VBLANK.
    SYSVBV points to 59345 in Version A of the OS, and to 59310 in Version B.

XITVBV
58466-58468     E462-E464

    XITVBV is the exit vector for the VBLANK routine. This is what VVBLKD points to unless you've changed it.
    Use XITVBV to return to where the computer left off from when the VBLANK interrupt occurred. It points to 59710 in Version A of the OS, and to 59653 in Version B.
    The following four vectors are designed for use by the OS only.

SIOINV
58469-58471     E465-E467

    This is the initialization vector for SIO.

SENDEV
58472-58474     E468-E46A

    SENDEV is the vector for the "send-able" routine.

INTINV
58475-58477     E46B-E46D

    This is the initialization vector for the interrupt-handler routine.

CIOINV
58478-58480     E46E-E470

    CIOINV is the initialization vector for CIO.

BLKBDV
58481-584483     E471-E473

    This is the entry vector for the blackboard mode, which is more commonly known as the "Atari memo pad" mode. Type BYE from BASIC, or turn on the computer with no cartridges or disk drives to see what I mean. This mode lets you type things on the screen without anybody caring what you type. In other words, you can press Return and nothing will happen. To get back to BASIC, press System Reset (this won't erase your BASIC program).
    BLKBDV points to 61987.

WARMSEV
58484-58486     E474-E476

    WARMSV is the entry vector for the warmstart routine. The OS jumps through here when System Reset is pressed.
    WARMSV points to 61723.
    In case these locations don't seem useful to you, try this:

X = USR(58484)

    What you have just done is told the computer to go to 58484, which contains a machine-language instruction to go to the address in the next two memory locations. Since this routine is for what's called warmstart, the computer will now act just like you pressed System Reset. You use the other locations in this section just like this. Try it!

COLDSV
58487-58489     E477-E479

    This, appropriately, is the entry vector for the coldstart routine. Whereas going through WARMSV only initializes the OS RAM, going through COLDSV initializes all RAM, meaning that any programs in memory will be erased. See COLDST at Location 580 for a way to hook COLDSV up to System Reset rather than WARMSV.
    COLDSV points to 61733.
    The following two vectors are designed for use by the OS only.

RBLOCKV
58490-58492     E47A-E47C

    RBLOKV is the entry vector for the cassette "read-block" routine.

CSOPIV
58493-58495     E47D-E47E

    This is the vector for the cassette "OPENfor-input" routine.

VCTABL
58496-58533     E480-E4A5

    VCTABL is a table of the initial values for the OS RAM vectors.

    Now we're into the final part of the OS, which consists mostly of the various built-in handlers, interrupt routines, and so forth. What follows is a list of addresses for some of these routines, which can be useful to you in one of several ways. If you're a beginner, the list will provide you with an idea of exactly what the OS does. If you're a machinelanguage programmer then, along with the OS listing, the list will help you find the various routines so that you can see exactly how things are done. By studying the routines, you can also pick up on programming techniques (don't be afraid of the OS listing; it's really not that difficult to understand). Finally, if you really know what you're doing, you can rewrite the routines and put them in your own programs, customizing them to your own needs.
    Most of the routines will not work without some kind of previous setup, so make sure you check the OS listing before you attempt to use them.
    Please note that all the following addresses are for the original OS only. Some of them may be different in the newer versions. At the time of this writing, however, the OS listing is for the original version, and that is why these addresses are used.


CIO Routines

CIOINT
58534     E4A6

    CIO's initialization routine.

CIO
58564     E4C4

    The main CIO routine (includes the following routines).

CIOPEN
58633     E509

    OPEN routine.

CICLOS
58675     E533

    CLOSE routine.

CISTSP
58702    E54E

    STATUS and special requests routine.

CIREAD
58729     E569

    GET routine (GET character and GET record).

CIWRIT
58825     E5C9

    PUT routine (PUT character and PUT record).

CIRTNI
58907     E61B

    Return from CIO with the status in the Y register.

CIRTN2
58909     E61D

    Return from CIO with the status in ICSTAZ (35).

COMENT
58941     E63D

    Compute the handler entry point using HATABS (794) and COMTAB (59081).

GOHAND
59017     E689

    Jump indirectly to the device handler. An indirect jump, in this case, means fooling the 6502 into thinking that the address you want to jump to is actually the one you want to RTS to. This involves playing with the stack and is a pretty neat trick you may want to look at.

DEVSRC
59038     E69E

    Find a particular device in the handler address table.

COMTAB
59081     E6C9

    This is a table of offsets into the handler entry point table for the desired device. It is used to find the correct vector for the given command.


Interrupt Handler Routines

IHINIT
59093     E6D5

    Initialize the interrupt handlers.

PIRQ
59123     E6F3

    Jump to the main IRQ handler routine through VIMIRQ (534,535). Unless you've changed it, VIMIRQ points to SYIRQ.

SYIRQ
59126     E6176

    This is the system's IRQ handler routine.

PNMI
59316     E7B4

    This is the system's NMI handler routine.


System VBLANK Routines

SYSVBL
59345     E7D1

    This is the immediate vertical blank routine (Stage 1 VBLANK).

SYSVB3
59400     E808

    This is the Stage 2 VBLANK routine.

SETVBL
59666     E912

    This routine can be used to set up vectors for your own VBLANK routines, and also for the system timers. See SETVBV at 58460.

XITVBL
59710     E93E

    Exit from vertical blank.


SIO Routines

SIOINT
59716     E944

    SIO's initialization routine.

SIO
59737     E959

    The main SIO routine (includes the following routines).

RETURN
59917     EA0D

    Return from SIO.

WAIT
59930     EAIA

    Wait for the device to finish what it has been told to do.

SEND
60011     EA6B

    Send a buffer of bytes to a device.

ISRODN
60048     EA90

    This is the "serial-output data needed" interrupt routine. See SER-OUT at Location 53773.

ISRTD
60113     EADI

    This is the "transmission done interrupt" routine. See POKMSK at Location 16.

RECEIV
60130     EAE2

    Receive a bunch of bytes from a device and store them in a buffer.

ISRSIR
60177     EB11

    This is the "serial-input data needed" interrupt routine. See SERIN at Location 53773.

CASENT
60292     EB84

    Read or write a record to cassette (SIO handles the cassette differently than other devices).

BEGIN
60692     ED14

    Figure out the baud rate for the next record. See CBAUDL/H at Locations 750 and 751.

POKTAB
60882     EDD2

    This is a table of values used in the preceding baud-rate routine.


Disk Interface Routines

DINIT
60906     EDEA

    The disk interface's initialization routine.

DSKIF
60912     EDF0

    The main disk interface routine.


Printer Handler Routines

PRNORG
61048     EE78

    This is the beginning of the printer handler. See HATABS at Location 794 for a list of routines in this or any handler.


Cassette Handler Routines

CASORG
61249     EF41

    This is the beginning of the cassette handler. See the note at PRNORG.

BEEP
61528     F058

    The cassette handler uses this routine to make the keyboard speaker beep when you type CLOAD or CSAVE.


Monitor Routines

RESET
61723    F11B

    This is the start of the System Reset routine.

PWRUP
61733    F125

    The start of the coldstart routine.

ZERORM
61752    F138

    Clear all the RAM locations.

ZOSRAM
61792     F160

    Clear the OS RAM only (for warmstart).

BLACKB
61994     F22A

    The blackboard routine (memo pad mode).

SPECL
62015     F23F

    Check to see how much RAM there is.

HARDI
62081    F281

    Initialize the hardware locations.

OSRAM
62100     F294

    Initialize the OS RAM locations.

BOOT
62159     F2CF

    Boot the disk if it's so desired (i.e., the disk drive is hooked up and turned on).

CSBOOT
62386     F3B2

    Boot the cassette if it's so desired (i.e., the Start button was held down when the computer was turned on).


Display Handler Routines

DOPEN
62454     F3F6

    OPEN the display handler (set up a graphics mode).

GETCH
62867     F593

    GET a character from the screen.

OUTCH
62903     F5B7

    PUT a character on the screen.

OUTPLT
62944     F5E0

    PLOT a point on the screen.


Screen Editor Routines

EGETCH
63038     F63E

    INPUT a logical line from the keyboard and print it to the screen. Remember that a logical line ends either when you press Return or fill three rows on the screen.

EOUTCH
63140     F6A4

    PRINT a character on the screen, making sure that control characters are processed instead of just printing (i.e., a CTRL-arrow will move the cursor rather than printing an arrow).


Keyboard Handler Routines

KGETC2
63197     F6DD

    GET a character from the keyboard.

ESCAPE
63353     F779

    Process all the various control characters.

BELL
63754     F90A

    Ring the bell.


More Display Handler Routines

CONVRT
63815     F947

    Take the row number and column number that the cursor is on and figure out what memory location that corresponds to.

INATAC
64306     FB32

    Convert an internal character value to its ATASCII value.

CLRLIN
64411    FB9B

    Clear the line that the cursor is currently on.

SCROLL
64428     FBAC

    Scroll the screen.

DRAW
64764     FCFC

    Draw a line from OLDROW OLDCOL to TWOCRS,COLCRS (Locations 90 through 92 and 84 through 86).


Tables, Tables and More Tables

    Locations 65093 through 65469 are various tables for use with the display handler. Check the OS listing for more details and to find out which routines use them (use the cross-reference table at the end of the listing).


One More Keyboard Routine

PIRQQ
65470     FFBE

    The IRQ in this location's name should tip you off to the fact that this is the interrupt routine for the keyboard. It debounces the keys, checks for CTRL-1 (pause) and sets SSFLAG accordingly (767), stores the key value in CH (764) and CHI (754), and clears ATRACT (77).


That's All Folks

    Yup, that brings us to the end of Atari memory. Thanks for bearing with me for all of this. You can now relax and take a welldeserved break!