APPENDIX TWELVE

The XL/XE Memory Map

Most of the information in the first edition of Mapping the Atari ap- plies equally well to the XL and XE lines of computers; only those locations below represent known changes. Atari made several changes to RAM locations, and the OS was almost entirely rewritten in the newer models. The information here pertains to the 600XL, 800XL, 1200XL, 65XE, and 130XE. Except for the 1200XL, the XL and XE models are virtually identical to each other. There have been changes in the BASIC ROMs, but I have no official word on any changes in the OS. al- though I have reason to believe there have been some. For those owners of XL computers who have difficulty using older 800 software, Atari (and several other companies) makes a Translator disk which loads an 800 operating system on top of the XL OS, allow- ing you to run almost all 800 programs. Ask your local Atari dealer for this disk if you don't already have it. Side A of the Translator disk permits you to press RESET and usually remain within the older OS; side B doesn't have this code patch. so it reboots the XL OS when RE- SET is pressed. A public domain translator called FIXXL is also avail- able on CompuServe. A hardware solution is available: the XL BOSS chip from Allen MacroWare. The DDT subprogram in OSS's MAC/65 assembler is an excellent tool for examining memory, especially since it gives you the option of ASCII display and disassembly of visible memory. It allows you to write directly to memory or jump to any location. I used it constantly while writing this chapter. Unless otherwise noted, this material pertains to all XL and XE models (as does much of the earlier section of the book). RAM locations and interrupt and OS vectors will remain the same in all systems; how- ever, the locations and contents of routines they point to may differ among computers. Not all of the OS ROM locations described here will be the same in the 1200XL. Some of the changes here are to vec tors, not to functions. References to function keys (Fl to F4) and LEDs are for 1200XL users only. My original 1200XL memory map ap- peared in COMPUTE!'s Third Book of Atari. Most RAM and hardware locations belonging to the GTIA, ANTIC, POKEY, and PIA chips (53248-55295; $D000-$D7FF except for PORTB) have generally not changed. The floating-point package remains at 55296-57343 ($D800-$DFFF), but routines have been altered within it. The major change in the OS was the shifting of interrupt handlers from high ROM into the area previously unused between 49152 and 52223 ($C000-$CBFF) and the addition of the international character set at 52224-53247 ($CC00-$CFFF). Atari promises the XE series will maintain 100 percent compatibility with the XL series--as long as the software obeys the "rules" and sticks to official, published vectors and entry points and doesn't try to take advantage of some ROM routine to save a few bytes (see 62026 and 62128 below). The OS in the XE series is the same as that in the 800XL, at least at the time of this writing. When the ROM routine gets moved--the software crashes. Don't blame Atari; they've published this material since day one. If developers don't pay attention, it's not Atari's fault.

Deleted Registers

The following registers have been completely deleted from the XL/XE, and other uses have been found for the location (previous 400/800 locations given): PTEMP (31; $1F) LINBUF (583-622; $247-$26E) CSTAT (648; $288) TMPX1 (668; $29C) HOLD5 (701; $2BD) ADDCOR (782; $30E).

00 00 LNFLG

Used by the Atari in-house debugging programs and OS on power-up.

01 01 NGFLAG

Used during power-up routines for self-testing; checks for bad memory bytes; zero means memory failure.

07 07 CMCMD

Command flag for 835 and 1030 modems set to any nonzero number to pass commands to the modem. Used to be TSTDAT.

10,11 A,B DOSVEC

Points to 6047 ($179F).

12,13 C,D DOSINI

Points to 5440 ($1540).

28-31 1C-1F ABUFPT

Intended OS use as buffer pointers; currently unused.

54,55 36,37 LTEMP

Temporary buffers for the general-purpose peripheral handler loader routines. The general-purpose handler routines help the OS deal with new handlers and peripherals which load their own handlers. All locations marked as being used by the peripheral handler or loader are tar OS use only; do not use them.

74,75 4A,4B ZCHAIN

Temporary storage registers for general-purpose peripheral handler loader.

96,97 60,61 FKDEF

The 1200XL has four redefinable function keys. FKDEF points (LSB/MSB) to their definition table--an eight-byte table for keys F1 to F4 and then SHIFT-F1 to SHIFT-F4. Each byte is assigned a value corresponding to an internal (not ASCII) code. The keys themselves are values 138-141 ($8A-$8D), but you must not as- sign a key its own value since it generates an endless loop. Ini- tially points to 64529 ($FC11). The function keys perform the following activities: Key Combination Function F1 Cursor up (ATASCII 28; $1C) F2 Cursor down (29; $1D) F3 Cursor left (30; $1E) F4 Cursor right (31; $1F) With SHIFT F1 Home (cursor to upper left, 28; $1C) F2 Cursor to lower-left corner (29; $1D) F3 Cursor to start of physical line (30; $1E) F4 Cursor to right end of physical line (31; $1F) With CTRL F1 Keyboard enable/disable toggle (not con- sole keys) F2 Screen display enable/disable F3 Key click sound enable/disable F4 Domestic/international character set toggle Function keys are ignored with both a SHIFT and CTRL combination. You cannot redefine CTRL-function key definitions.

98 62 PALNTS

Flag to determine PAL or NTSC version of the display handler, previously at 53268 ($D014). Zero means North American standard.

121,122 79,7A KEYDEF

Pointer (LSB/MSB) to the keyboard definition table, initialized to 64337 ($FB51), where the system keyboard table resides. You can redefine the keyboard by writing a 192-byte table and POKEing its address here. The table consists of three 64-byte portions: lowercase keys, SHIFTed keys, and CTRL keys. The sys- tem table has the following assignments: Byte Key Byte Key 00 1 32 , 01 j 33 Space 02 ; 34 . 03 F1 (1200XL) 35 n 04 F2 (1200XL) 36 (128) 05 k 37 m 06 + 38 / 07 * 39 Inverse key (114) 08 o 40 r 09 (128; see below) 41 (128) 10 p 42 e 11 u 43 y 12 RETURN 44 TAB 13 i 45 t 14 - 46 w 15 = 47 q 16 v 48 9 17 HELP (128) 49 (128) 18 c 50 0 19 F3 (1200XL) 51 7 20 F4 (1200XL) 52 BACKSPACE 21 b 53 8 22 x 54 < 23 z 55 > 24 4 56 f 25 (128) 57 h 26 3 58 d 27 6 59 (128) 28 ESC 60 CAPS (130) 29 5 61 g 30 2 62 s 31 1 63 a The next 64 bytes contain the shifted characters (for example, a shifted is A, 5 shifted is %; look at the upper characters on your keyboard). The following 64 are CTRL key characters (many graphics characters), You have to create a table for all 192 bytes, although you need change key assignments only for a specific few. Use the ATASCII values when writing the table. Several values have specific meaning to the keyboard decoder on the XL: Dec/Hex Use 128/80 Not used; invalid combination 129/81 Inverse output 130/82 Upper/lowercase toggle 131/83 CAPS lock 132/84 CTRL key lock 133/85 End of file (EOF) 137/89 Keyboard click toggle 138-141/8A-8D Function keys F1-F4 (1200XL only) or: cursor up (ATASCII 28; $1C) cursor down (ATASCII 30; $1D) cursor left (ATASCII 31; $1E) cursor right (ATASCII 32; $1F) 142/8E Cursor home (upper-left screen corner) 143/8F Cursor to bottom-left corner 144/90 Cursor to left margin (1200) 145/91 Cursor to right margin (1200) You can't redefine BREAK, SHIFT, CTRL, or the console keys (nor the CTRL-function key assignments on the 1200XL). The 1200XL Addenda gives a Dvorak keyboard assignment easily written into memory, The system table address is returned to RAM on power-up or RESET.

128,129 80,8 1 LOMEM

Points to 7676 ($$1DFC).

512-551 200-227 Interrupt vectors

The locations of the vectors and their functions remain the same, but they now point to different locations in the OS memory: Vector Hex Label Points to 512,513 200,201 VDSLST 49358 ($C0CE) 514,515 202,203 VPRCED 49357 ($C0CD) 516,517 204,205 VINTER 49357 ($C0CD) 518,519 206,207 VBREAK 49357 ($C0CD) 520,521 208,209 VKEYBD 64537 ($FC19) 522,523 20A,20B VSERIN 6691 ($1A23) 524,525 20C,20D VSEROR 6630 ($19E6) 526,527 20E,20F VSEROC 60140 ($EAEC) 528,529 210,211 VTIMR1 49357 ($C0CD) 530,531 212,213 VTIMR2 49357 ($C0CD) 532,533 214,215 VTIMR3 49357 ($C0CD) 534,535 216,217 VIMIRQ 49200 ($C030) 546,547 222,223 VVBLKI 49378 ($C0E2) 548,549 224,225 VVBLKD 49802 ($C28A) 550,551 226,227 CDTMA1 60433 ($EC11) The OS was rewritten in the XL/XE models, moving the interrupt handlers down into the previously unused region 49152-53247 ($C000-$CFFF).

563 233 LCOUNT

Temporary counter for peripheral handler loader.

566,567 236,237 BRKKY

Now points to 49298 ($C092).

568,569 238,239 RELADR(1200XL) VPIRQ (All XL/XEs except 1200XL)

Previously spare bytes, now the address of the relocatable loader routine in the 1200XL and vector for parallel bus inter- rupt requests on all XL/XEs except 1200XL (where it points to a routine at 51566; $C96E)--the vector for any initialized generic parallel device.

581 245 RECLEN

Relocatable loader routine variable for record length. 583-618 $247-$26A .... Reserved (unused) on the 1200XL.

583 247 PDVMSK

Shadow mask for the device selection register at 53759 ($D1FF; active only when the OS deselects the floating-point ROM by writing to that address). You can run up to eight parallel de- vices through the bus; each bit in this register corresponds to one device. The mask must be set for the proper device before the OS will allow an IRQ to be sent to that device.

584 248 SHPDVS

Shadow for parallel bus register; each bit represents one of eight parallel devices. Allows the OS to service VBIs while run- ning the device masked by this bit.

585 249 PDMSK

Parallel bus interrupt mask; allows OS to service IRQs from the device masked by the bit in this register. See above.

586,587 24A,24B RELADR

Relocatable loader relative address.

588,589 24C,24D PPTMPA,PPTMPX

One-byte temporary storage registers for relocatable loader.

590-618 24E-26A ....

Spare bytes, reserved for future use.

619 26B CHSALT

Alternate character set pointer for the 1200XL, initialized to 204 ($CC) to point to the international character set as the next set to display on the CTRL-F4 toggle. The XL has two internal character sets, one at 52224 ($CC00) and the other at 57344 ($E000).

620 26C VSFLAG

Fine-scroll temporary register.

621 26D KEYDIS

Keyboard disable. POKE with 255 to disable the keyboard, 0 to reenable. You have to press RESET (all XL/XEs except 1200XL) to get control back if you are locked out; 1200XL users can press CTRL-F1 (toggles it on and off; LED 1 is on when the keyboard is disabled).

622 26E FINE

Fine-scroll enable for graphics mode 0 (text); POKE with 0 for coarse scrolling (the default) and 255 ($FF) for fine scrolling. Follow the POKE with GR.0 or an OPEN for device E:. Try listing a long program--it's slow and smooth! The display list for fine scrolling is one byte longer than for coarse scrolling. The OS places the address (64708; $FCC4) of a Display List Interrupt (DLI) at 512, 513 ($200,201), replacing any you might have placed there. The color register at 53271 ($D017) is altered for the last visible screen line. If you enable fine scrolling and go immediately to DOS, you'll see that it's still enabled when you do a copy to screen or disk directory. Jerry White wrote an article demonstrating fine scrolling and other XL features in Analog, February 1984.

628-631 272-277 PADDL4-7

The XL has only two ports, so only paddles 0-3 are active.

634-635 27A-27B STICK2-3

No longer in use since there are ports only for sticks 0 and 1. The OS VBLANK process now copies the PORTA joystick (0-1) and paddle (0-3) values into the shadow registers for PORTB so that STICK0 affects both STICK0 and STICK2, STICK1 affects STICK1 and STICK3, PADDL0 affects PADDLE0 and PADDL4, and so on.

640-643 280-283 PTRIG4-7

No longer in use (see PADDL4-7).

646-647 286-287 STRIG2-3

No longer in use (see STICK2-3).

648 288 HIBYTE

High-byte register for relocatable loader routine.

651 28B IMASK

Unused.

652 28C JVECK

Temporary jump vector; unused.

654,655 28E,28F NEWADR

Used by relocatable loader; new address vector.

668 29C CRETRY

Number of command retries; moved from 54 ($36) in the 400/800.

701 2BD DRETRY

Number of device retries; moved from 55 ($37) in the 400/800.

713,714 2C9,2CA RUNADR

Run address register for relocatable loader routine.

715,716 2CB,2CC HIUSED

Used by relocatable loader routines.

717,718 2CD,2CE ZHIUSE

Used by relocatable loader routines.

719,720 2CF,2D0 GBYTEA

Used by relocatable loader routines.

721,722 2D1,2D2 LOADAD

Used by relocatable loader routines.

723,724 2D3,2D4 ZLOADA

Used by relocatable loader routines.

725,726 2D5,2D6 DSCTLN

Disk sector size register; default of 128 ($80) bytes, but can be altered to a length from 0 to 65535 ($FFFF). Your drive may not support other sizes, however.

717,728 2D7,2D8 ACMISR

Interrupt service routine address; unused.

729 2D9 KRPDEL

Auto-delay rate; the time elapsed before keyboard repeat be- gins. Initially set at 48 ($30; $28 for PAL machines) for 0.8 sec- onds; you can POKE it with the number of VBLANK intervals (1/60 second each) before repeat begins. A value of 60 would be a one-second delay. A value of 0 means no repeat.

730 2DA KEYREP

The rate of the repeat; default is 6, which means ten characters per second (one each six VBLANK intervals after the delay above). POKE with the number of VBLANK intervals between repeats; with a value of 1, you get 60 characters per second (50 on PAL systems)! A value of 0 provides one key repeat only per press.

731 2DB NOCLIK

This is the keyboard click disable register; POKE with any non- zero number to disable the annoying keyboard sound pro- duced through your TV. POKE again with 0 to enable the sound. On the 1200XL, CTRL-F3 toggles the sound as well.

732 2DC HELPFG

Register to hold the HELP key status; 17 is HELP has been pressed alone, 81 means it has been pressed with SHIFT, and 145 with CTRL. This register can be cleared under program control only by POKEing it with 0. The OS ignores it otherwise.

733 2DD DMASAV

This saves the DMA value from 559 ($22F) on the 1200XL when CTRL-F2 is pressed to disable the screen. On all XL/XEs except the 1200XL, if you POKE 559,0 to turn off the screen, the value is not saved in 733. However, if you POKE 733 with the DMA value (usually 34) at the next keystroke, the screen will automatically be activated again.

734 2DE PBPNT

Print buffer pointer; moved from 29 ($1D) on the 400/800.

735 2DF PBUFSZ

Print buffer size; moved from 30 ($1E) on the 400/800.

745 2E9 HNDLOD

Relocatable loader routine handler flag.

746-749 2EA-2ED DVSTAT

Additional device status registers to contain information re- turned to the computer by the peripheral after the new type 3 and 4 polls. The bytes contain: 746/747 LSB/MSB of the handler size (must be an even number) 748 Device SIO address to be used for loading 749 Peripheral revision number The new poll types are fully explained in the 1200XL operating system manual; earlier poll types are described in the 400/800 hardware manual. Basically, type 3 is an "are you there?" poll (device address $4F, command byte $40, AUX1 $4F, AUX2 $4F, checksum normal), and poll 4 is a null poll (values $4F, $40, $4E and $4E, respectively; checksum normal).

756 2F4 CHBAS

Character set select; default of 224. The international set can be selected by POKE 756,204 ($CC). On the 1200XL, the value in CHBAS is switched with that in CHSALT (619; $26B) whenever CTRL-F4 is used to toggle the alternate character set. The val- ues in the two registers are swapped and LED 2 is lit.

757 2F5 NEWROW

Moved from 96 ($60) in the 400/800.

758,759 2F6,2F7 NEWCOL

Moved from 97,98 ($61,$62) in the 400/800.

760 2F8 ROWINC

Moved from 121 ($79) in the 400/800.

761 2F9 COLINC

Moved from 122 ($7A) in the 400/800.

782 30E JMPERS

Storage for hardware option jumpers on the 1200XL, intended to tell the OS how the system is configured; if bit 0 (POT 4) is not set (0), then the self-test will run. Bits 1-7 are unused. Used only in the 1200XL.

787 313 TEMP2

One-byte temporary storage register.

788 314 PTIMOT

Moved from 28 ($1C) in the 400/800. Same initial value (30).

829-831 33D-33F PUPBT1-3

Power-up and reset validation registers 1-3. Used on warm start to verify the integrity of memory. The OS initializes these loca- tions to 92 ($5C), 147 ($93), and 37 ($25), respectively. When RE- SET is pressed, these bytes are checked, and it they are the same as initialized, a warm start is done; otherwise, a cold start occurs.

838,839 346,347 IOCB0

To send your output to the printer, POKE 838,202 and POKE 839,254. To turn off the printer and send everything back to the screen, POKE 838,175 and POKE 839,242. This program from Matt Ratcliff allows you to toggle output between printer and screen by pressing SELECT (it works equally well on the 400/800): 10 DIM A$(1):CONSOL=53279:GRAPHICS 0:IOCB0E =838 20 PHDLR=58422 30 EHDLR=58374 40 PL=PEEK(PHDLR):PH=PEEK(PHDLR+1) 50 EL=PEEK(EHDLR):EH=PEEK(EHDLR+1) 60 PRINT "Text will print continuously." 70 PRINT "Press SELECT to toggle output" 80 PRINT "between printer and screen.":? 90 PRINT "Get printer ready and press RETUR N" 100 INPUT A$:I=1:DIR=0 110 PRINT I;" Press select to change output .":I=I+1 120 IF PEEK(CONSOL)<>5 THEN 110 130 IF DIR THEN POKE IOCB0E,EL:POKE IOCB0E+ 1,EH 140 IF NOT DIR THEN POKE IOCB0E,PL:POKE IO CB0E+1,PH 150 DIR= NOT DIR 160 IF PEEK(CONSOL)<>7 THEN 160 170 GOTO 110 DOWNLOAD TOGGLE.BAS

1000 3E8 SUPERF

Screen editor register; cleared on entry to the "put byte" rou- tine, the editor changes keycodes 142-145 ($8E-$91) to 28-31 ($1C-$1F; see 121; $79) and sets SUPERF to nonzero.

1001 3E9 CKEY

Moved from 74 ($4A) in the 400/800.

1002 3EA CASSBT

Moved from 75 ($4B) in the 400/800.

1003 3EB CARTCK

Cartridge checksum. A checksum of page one of the cartridge. The checksum is recalculated each VBLANK and checked against this register. If not the same, the OS assumes the car- tridge isn't there any more (was pulled out) and does a cold start; 1200XL only.

1004 3EC DERRF

Screen open error flag; if zero, then no error, if nonzero, then OS can't initialize the screen editor.

1005-1015 3ED-3F7 ACMVAR

Reserved for OS variables; on power-up or cold start, all vari- ables between 1005 and 1023 ($3ED-$3FF), inclusive, are set to zero, but are left unchanged on warm start.

1016 3F8 BASICF

Shadow of current status of BASIC. Zero means ROM BASIC is enabled; nonzero means it's not. Must be in sync with disabling of ROM BASIC. To disable BASIC, set BASICF to nonzero, then do a warm start (press RESET); DOS will load and tell you there is no cartridge present when you try to return to BASIC.

1017 3F9 MINTLK

Unused.

1018 3FA GINTLK

Cartridge interlock register; the complement of BASICF, above. It reads 1 when an external cartridge is installed, 0 when not (or ROM BASIC is in use). The value of TRIG3 (53267; $D103) is loaded here by the OS initialization routine. If at any time, the external cartridge is pulled, the system will crash.

1019,1020 3FB,3FC CHLINK

Relocatable handler chain use; allows chaining of portions of handler routines.

1792-7419 700-1CFB ....

Used by DOS when loaded; otherwise available as free RAM.

3889 F31 DOS 3

If you PEEK here and get 76 ($4C), you have an early version of DOS 3 (the later version will read 78). To correct some errors in the earlier FMS files, type this in: 10 FOR N=1 TO 9:READ A,B:POKE A,B:NEXT N 20 DATA 3889,78,3923,78,3943,78,3929,76,389 5,76 30 DATA 3901,77,3935,77,3955,77,2117,240 Better yet, get DOS 2.5 from Atari (supports double-density and the 130XE RAMdisk). DOS 3.0 saves in blocks, not sectors--of a minimum 1000 bytes per block. If you write a program 1001 bytes long, it saves 2000 bytes, wasting 999 bytes on your disk.

20480-22527 $5000-$57FF Self-test ROM

Self-test ROM when enabled, controlled by bit 7 of PORTB (54017; $D301). The self-test code is in a special ROM area underneath the GTIA, POKEY, ANTIC chips area (starting at 53248; $D3000) and is moved (remapped) here when you type BYE in BASIC or when you POKE PORTB with the right value and JMP (or USR) to the initialization vector (see 58481; $E471 and 58496-58499, $E480-$E483). RAM when self-test isn't enabled.

39967-40959 9C1F-9FFF ....

Display list and screen RAM, moved into lower memory if a cartridge is 16K (using RAM from 32767 to 49151 as well).

43234 A8E2 BASIC ROM

If you PEEK here and get 96 ($60), you have the BASIC Revision B ROMs. What you need is Revision C. B stands for Bugs! See Appendix 13 on enhancements and bugs. If you get 234 ($EA), you have Revision C. From Matt Ratcliff. You can turn BASIC off when you go to DOS by POKEing 1016 ($3F8), then pressing RESET. The problem is to turn it back on again from DOS rather than rebooting the system. There is a public domain program by Matt Ratcliff on the Gateway BBS which does this for you.

Introduction to the OS ROM

Atari modified the new XL/XE ROMs since Revision B. Atari main- tained the handler and interrupt vectors, although the routines they point to changed between versions. Atari did produce a listed source code for the XL OS, although for some reason it was never published for public sale as it was in- tended. It may be available now through Atari--write and ask for it. It is an excellent 500+ page resource document.

49152-52223 C000-CBFF Interrupt handlers

Os ROM. In the 400/800, the block between 49152 and 53247 was unused; now the area holds many of the interrupt handlers (vectored here from page two). Some 400/800 software checks for certain values in these locations and won't run if the value is not found. Use the Translator disk in that case (with the 400/800 OS installed; the area between $C000 and $CEFF becomes user- accessible RAM). The area between 52069 ($CB65) and 52223 ($CBFF) is empty (all zeros). A lot of interrupts are set to jump to 49357 or 49358 ($C0CD or $C0CE). The former contains a PLA statement followed by an RTI. The net result is a simple return back into the program without any other activity taking place. Bytes 49152-49163 ($C000-$C00B) are used to identify the com- puter and the ROM in the $C000-$DFFF block: Byte Use 49152-3/C000-1 Checksum (LSB/MSB) of all the bytes in ROM except the checksum bytes themselves. 49154/C002 Revision date, stored in the form DDMMYY. This is DD, day, usually $10. 49155/C003 Revision date, month; usually $05. 49156/C004 Revision date, year; usually $83. 49157/C005 Reserved option byte; reads zero for the 1200, 800XL, and 130XE. 49158/C006 Part number in the form AANNNNNN; AA is an ASCII character and NNNNNN is a four-bit BCD digit. This is byte A1. 49159-62/C007-A Part number, bytes A2, N1-N6 (each byte has two N values of four bits each). 49163/C00B Revision number. My 800XL and 130XE say 2. 49164/C00C Interrupt handler initialization 49176/C018 NMI intitialization Interrupt handlers and other routines in the $C000 block: Entry Handler or Use 49196/C02C IRQ processor 49298/C092 BREAK key IRQ 49312/C0A0 Continue IRQ processing 49359/C0CF Table of IRQ types and offsets (16 bytes) 49378/C0E2 Immediate VBLANK NMI processing 49743/C24F Process countdown timer 1 expiration 49890/C2E2 Process countdown timer 2 expiration 49749/C255 Decrement countdown timer 49778/C272 Set VBLANK parameters 49802/C28A Process deferred VBLANK NMI 49808/C290 Perform warm start 49834/C2AA Process RESET 49864/C2C8 Perform cold start 49866/C2CA Preset memory (cold and warm start continuation) 50217/C429 Initialize cartridge software 50220/C42C Process ACMI interrupt 50237/C43D BOOT ERROR message 50248/C448 Screen editor specification (E:) 50251/C44B Table of interrupt handler vectors (same or- der as RAM vectors at 512-549 ($200-$225) 50289/C471 Miscellaneous initialization routines: OP- TION key status checked at 50330 ($C49A); BASIC enabled at 50337 ($C4A1) 50394/C4DA Hardware initialization 50485/C535 Software and RAM variable initialization 50571/C58B Attempt disk boot 50619/C5BB Boot and initialize disk 50633/C5C9 Complete boot and initialize 50729/C629 Execute boot loader 50747/C63B Initialize booted software 50750/C63E Display BOOT ERROR message 50777/C659 Get next sector routine 50798/C66E Attempt cassette boot 50851/C6A3 Initialize DIO (disk I/O) 50867/C6B3 Disk I/O (DIO) 51002/C73A Set buffer address 51013/C745 Relocate relocatable routine to new address 51093/C795 Handle end record type 51l5l/C7CF Get byte 51154/C7D2 Execute run at address 51157/C7D5 Handle text record 51281/C851 Relocate text into memory 51309/C86D Handle word reference record type 51346/C892 Handle low-byte and one-byte record type 51452/C8FC Select and execute self-test 51468/C90C Initialize generic parallel device 51507/C933 PIO--parallel device I/O; PIO vector tables (see 58368, $E400) begin at 51601 ($C991) 51631/C9AF Select next parallel device 51658/C9CA Invoke parallel device handler 51753/CA29 Load and initialize peripheral handler 51799/CA57 Start of self-test offsets and text (uses hard- ware values for character display) 52054/CB56 Checksum linkage table

52224-53247 CC00-CFFF CHARSET2

International character set, assembled in the same manner as the standard character set at 57344 ($E000). There are two character sets in the XL series, and you can switch between them by POKE 756,224 (standard) or POKE 756,204 (international).

53279 D01F CONSOL

If you hold down the OPTION key when booting an application on the XL, you disable BASIC (but no other cartridge), allowing the memory space to be used for applications, You generally need to keep the key held down only for the first few seconds of the boot.

53504-53759 D100-D1FF ....

Unused in both the 400/800 and XL models by the OS, this area is switched out when an external device connected to the expansion bus is selected and the device memory switched in. The situation is reversed when the device I/O is completed. Locations Hex Use 53504-53758 D100-D1FE Device registers 53504 D100 Hardware get and put register (HWGET, HWPUT); data from the device on the bus is stored here. 53505 D101 Hardware reset and status reg- ister (HWRSET for write--this re- sets the get/put register; HWSTAT for read). 53759 D1FF Hardware select register, shad- owed by byte 583 ($247). Bit 0 is device 0, bit 1 device 1, and so on. Writing to this byte de- selects the FP ROM and selects the device ROM (try looking at it and subsequent locations with MAC/65's DDT or a similar tool while altering $D1FF).

54017 D301 PORTB

Since the XL and XE series no longer have a PORT B (on the 400/800 this controls joystick ports 3 and 4), this register is used for LED control (1200XL only) and memory management. You can disable the ROM between 49152-53247 ($C000-$CFFF) and 55296-65535 ($D800-$FFFF) by setting bit 0 to 0 (the ROM area becomes RAM; note that the area between $D000 and $D7FF remains intact). However, unless another OS has been provided, the system will crash at the next interrupt (1/60 sec- ond later!), so you need to disable the interrupts first. Bit 1 controls BASIC; if 0, BASIC is enabled, if 1, it is disabled and the 8K RAM space enabled for program use. If you disable BASIC within a BASIC program, you lock up. Disable BASIC dur- ing a boot operation by holding down the OPTION key. Bits 2 and 3 control the 1200XL LEDs; 0 means on, 1 means off. LED 1 means the keyboard is disabled; LED 2 means the inter- national character set is selected. In the 130XE, these bits are used for bank switching 16K blocks of RAM. The 130XE allows you to use the extra memory as video memory or program/ data memory. See the section on memory management in the 13OXE at the end of this chapter. Bits 4-6 are reserved (unused) in the XL and 65XE. Bits 4 and 5 in the 13OXE are used to enable bank switching (see below). Bit 7 controls the RAM region 20480-22527 ($5000-$57FF), nor- mally enabled 1). When disabled 0), the OS ROM in that area is enabled and access provided to the self-test code moved from 53248-55295 ($D000-$D7FF). Try this: POKE 54017,PEEK(54017)-128 to enable the self-test ROM. Now type X=USR(20480). The self-test screen appears. The RAM is reset on power-up or warm start. Of course, you can al- ways simply type BYE to enter the test routines as well. Here's a program from Joe Miller of Koala Technologies which copies portions (skips the $D000-$D7FF block) of the OS into RAM, disables the ROM, then moves the copied portion back: 100 REM RAMROM - Install RAMŸbased 110 REM OS in an XL computer 120 REM by Joe Miller 130 REM March 23, 1985 190 PRINT "MOVING OS INTO RAM" 200 FOR I=1536 TO 1635 210 READ B:POKE I,B:NEXT I 220 B=USR(1536) 230 PRINT CHR$(125) 240 PRINT "RAM OS INSTALLED" 250 PRINT "PRESS RETURN TO TEST IT" 260 PRINT :PRINT :PRINT 270 PRINT "POKE 57344,1" 275 PRINT "{5 SPACES}$E000=1":PRINT 280 PRINT "POKE 57344,0" 290 POSITION 1,4 300 DATA 169,0,133,203,133,205,169 310 DATA 192,133,204,169,64,133,206 320 DATA 160,0,177,203,145,205,200 330 DATA 208,249,230,206,230,204,240 340 DATA 12,165,204,201,208,208,237 350 DATA 169,216,133,204,208,231,8 360 DATA 120,173,14,212,72,169,0 370 DATA 141,14,212,173,1,211,41 380 DATA 254,141,1,211,169,192,133 390 DATA 206,169,64,133,204,177,203 400 DATA 145,205,200,208,249,230,204 410 DATA 230,206,240,12,165,206,201 420 DATA 208,208,237,169,216,133,206 430 DATA 208,231,104,141,14,212,40 440 DATA 104,96 DOWNLOAD RAMROM.BAS You can make this into a machine language AUTORUN.SYS file by changing the loop to 1634, removing the number 104 in line 440, and deleting the USR call in line 220. Go to DOS and do a binary save (option K) at addresses $600-$662, with a run ad- dress of $600. This will change your ROM OS into a RAM OS ev- ery time you boot up that disk. Pressing RESET switches the OS back to ROM. The machine language source code for this short program (also by Joe Miller) is included here because I felt it important for machine language programmers to see how this is done: ;Move XL OS ROM into RAM ; ;RAMROM--Installs the XL ROM-based ; OS in RAM at the same address ; space. This is useful for ; making small patches to the ; OS or for experimenting with ; new design concepts, such as ; multitasking, window ; management, etc. ; ; By Joe Miller. ; ;This version is configured ;as an AUTORUN.SYS file. ; SOURCE EQU $CB ;zero page usage DEST EQU SOURCE+2 START EQU $0600 ;START address OSROM EQU $C000 ;address of OS ROM start OSRAM EQU $4000 ;address of ROM destination NMIEN EQU $D40E ;NMI enable register PORTB EQU $D301 ;memory mgt control latch ORG START LDA #low OSROM STA SOURCE STA DEST ;initialize copy addrs LDA #high OSROM STA SOURCE+1 LDA #high OSRAM STA DEST+l LDY #0 ;Repeat Pass1 LDA (SOURCE),Y ;copy ROM to RAM STA (DEST),Y INY BNE Pass1 INC DEST+1 INC SOURCE+1 BEQ Swap ;If done LDA SOURCE+l CMP #$D0 BNE Pass1 ;skip 2K block at $D000 LDA #$D8 STA SOURCE+1 BNE Pass1 ;Until SOURCE = $0000 Swap PHP ;save processor status SEI ;disable IRQs LDA NMIEN PHA ;save NMIEN LDA #0 STA NMIEN ;disable NMIs LDA PORTB AND #$FE ;turn off ROMs STA PORTB ;(leaving BASIC unchanged!) LDA #high OSROM STA DEST+1 ;set up block copy LDA #high OSRAM STA SOURCE+1 ;Repeat Pass2 LDA (SOURCE),Y ;move RAM OS to proper address STA (DEST),Y INY BNE Pass2 INC SOURCE+1 ;move to next page INC DEST+1 BEQ Enable ;If complete LDA DEST+1 CMP #$D0 BNE Pass2 ;skip block at $D000 LDA #$D8 STA DEST+1 BNE Pass2 ;Until DEST = $000 Enable PLA STA NMIEN ;reestablish NMI mask PLP ;reenable IRQs RTS END START DOWNLOAD RAMROM.ASM A sophisticated program called "RamMaster," by Matt Ratcliff, is available free through the Gateway BBS in St. Louis, Missouri. It not only creates a RAM OS, but it has a trap to keep the OS as RAM even when you press RESET. It also allows you to switch BASIC in and out from DOS. Probably the most elegant solution is the XL BOSS board which allows you to switch in a RAM OS, the older 800 OS, and the XL OS, as well as turn BASIC on or off with a few keypresses. It's available from Allen MacroWare in Redondo Beach, California. When you change the OS ROM into RAM, you can change all but a small portion of the OS at 53248-55295 ($D000-$D7FF), since it's RAM. You could always write an OS, load it into RAM, disable the ROM, and load yours in. You can change the character sets in their original locations rather than having to move them and use more memory. You could rewrite the han- dlers, interrupts, and other routines--almost anything. This is exactly what the Translator disk does when it writes the 800 OS into the XL. Boot the Translator and place a regular DOS disk in at the prompt so that BASIC READY comes up. Now type: 10 FOR N=57344 TO 57351 20 READ A:POKE N,A:NEXT N 30 DATA 255,1,1,1,1,1,1,1 You'll see a "graph pad" screen: You've POKEd directly into the character set at $E000, altering the first character (space). This also means that the area from 49152 to 52991 ($C000 to $CEFF) isn't used--almost 4K of free RAM for player missiles, machine language routines, anything you need it for. Be care- ful not to run over into the interrupt handlers at 52992 ($CF00).

54019 D303 PBCTL

The PORT B controller on the 400/800; not used since there isn't one on the XL/XE series.

54528-54783 D500-D5FF ....

Unused in both XL and 400/800 models. Any access read or write to this area enables the cartridge control line CCNTL as in the cartridge interface in the 400/800.

55296-57343 D800-DFFF FP

Floating-point package; although corrected, the entry point re- mains the same as in the 400/800. You now get an error if you try to get a LOG or LOG 10 of 0. This area becomes addressable by the device when the OS switches out ROM to perform I/O on a device connected to the expansion slot. There are several tables built into the FP package: Address Table 56909/DE4D Power of 10 coefficients 57202/DF72 Logarithm coefficients 57262/DFAE Arctangent coefficients (unused?) The OS switches the floating point out and switches in the par- allel bus interface (PBI) ROM when an external device attached through the bus is selected, switching it back when the I/O is completed. This means an external device can't use floating point or any software which does (such as BASIC). The first 26 bytes of the hardware ROM vector area (when OS ROM is deselected) are: Byte Hex Use 55296/55297 D800/D801 ROM checksum LSB/MSB (optional) 55298 D802 ROM revision number (optional) 55299 D803 ID number (128; $80) 55300 D804 Device type (optional) 55301 D805 JMP instruction ($4C) 55302/55303 D806/D807 I/O vector LSB/MSB 55304 D808 JMP 55305/55306 D809/D80A Interrupt vector LSB/MSB 55307 D80B ID number (145; $91) 55308 D80C Device name in ASCII (optional) 55309/55310 D80D/D80E Open vector LSB-1/MSB 55311/55312 D80F/D810 Close vector LSB-1/MSB 55313/55314 D811/D812 Get byte LSB-1/MSB 55315/55316 D813/D814 Put byte LSB-1/MSB 55317/55318 D815/D816 Status vector LSB-1/MSB 55319/55320 D817/D818 Special vector LSB-1/MSB 55321 D819 JMP 55322/55323 D81A/D81B Init vector LSB/MSB 55324 D81C Unused On a cold start, the OS polls for parallel devices, and if it finds one, JMPs (through 55321; $D819) to the INIT routine at 55322/55323 ($D81A, $D81B) which places the address of the ge- neric parallel device handler into the handler tables with the device name.

57344-58367 E000-E3FF CHARSET1

Standard (domestic) character set; default on power-up or RE- SET; pointed to by 756 (S2F4).

58368-65535 E400-FFFF OS

The OS has been considerably rewritten and changed since the 400/800. The ANTIC, PIA, and POKEY chips are the same, but many OS routines have been moved. The vectors in RAM have remained in place for the most part, so software which avails it- self of these locations can run on all machines, Always use the vectors when writing software to use OS routines, never the ac- tual routines themselves; they may change, while the vectors will not. Locations 58368-58495 ($E400-$E47F) still contain the vector ta- bles. but point to different locations than the 400/800 (for more information, refer back to the 400/800 section). The vectors (ex- cept JMP) all point to the address of the routine minus 1: Device & Loc Open Close Get Put Status Special JMP to E: 58368 $E400 EF93 F2D2 F249 F2AF F21D F2C2 EF6E S: 58384 $E410 EF8D F2D2 F17F F1A3 F21D F9AE EF6E K: 58400 SE420 F21D F21D F2FC F22C F21D F22C EF6E P: 58416 $E430 FEC1 FF06 FEC0 FECA FEA2 FEC0 FE99 C: 58432 $E440 FCE5 FDCE FD79 FDB3 FDCB FCE4 FCDB The JMP vectors in locations 58448-58583 ($E450-$E4D7) remain the same, but point to new vector addresses: Label Loc JMP to DISKIV E450 C6A3 DISKINV E453 C6B3 CIOV E456 E4DF SIOV E459 C933 SETBV E45C C272 SYSBV E45F C0E2 XITBV E462 C28A SIOINV E465 E95C SENDEV E468 EC17 INTINV E46B C00C CIOINV E46E E4C1 SELFSV E471 F223 (used to be BLKBVD) WARMSV E474 C290 COLDSV E477 C2C8 RBLOKV E47A FD8D CSOPIV E47D FCF7 Several of these locations themselves are JMP locations to other routines, done to maintain compatibility with the older 800 OS. Some new fixed entry point vectors have been added: 58496/E480 PUPDIV: Entry to power-on display (self-test mode in all XL/XEs except 1200XL; Atari logo screen display in the 1200XL). Try X=USR(58496). Points to 61987 ($F223). 58499/E483 SLFTSV: 1200XL only: entry to self-test mode. Points to 20480 ($5000) (see PORTB above). 58502/E486 PENTV: Entry to the handler uploaded from peripheral or disk. Points to 61116 ($EEBC). 58505/E489 PHUNLV: Entry to uploaded handler unlink. Points to 59669 ($E915). 58508/E48C PHINIV: Entry to uploaded handler initializa- tion. Points to 59544 ($E898).

58481 E471 SELFTST

Entry into the self-test mode by typing BYE in BASIC or X = USR(58481). This used to be the blackboard (Memo Pad) mode--a feature parents used to entertain their children, while keeping them from actually tinkering with the system or pro- grams. In the 1200XL, this is the location of the logo screen. I miss the blackboard mode myself; the self-test isn't really all that useful. There is no equivalent mode to blackboard in the XL/XE system.

58511 E48F GPDVV

Generic parallel device handler general-purpose vector. You can use this to talk to any expansion port device; move this ad- dress into HATABS (794-831; $31A-$33F) along with an appro- priate device name such as V: or T:. See the appendix on the expansion bus. There are seven vectors in this table, corresponding to the vector tables at 58348 ($E400).

58528-58560 E4A0-E4C0 ....

Blank area (all zeros).

58561 E4C1 ICIO

Initialize CIO.

58588 E4DC IIN

IOCB not OPEN error routine.

58591 E4DF CIO

The CIO area includes the following routines: Address Routine 58640/E510 Nonexistent device error 58645/E515 Load peripheral handler for OPEN 58650/E51A Perform CIO command 58687/E53F Execute OPEN command 58716/E55C Initialize IOCB for OPEN 58742/E576 Poll peripheral for OPEN 58748/E57C Execute CLOSE command 58775/E597 Execute STATUS and SPECIAL commands 58802/E5B2 Execute GET command 58910/E610 Execute PUT command 58992/E670 Set status 58994/E672 Complete CIO operation 59029/E695 Compute handler entry point 59067/E6BB Decrement buffer length 59080/E6C8 Decrement buffer pointer 59089/E6D1 Increment buffer pointer 59096/E6D8 Set final buffer length 59114/E6EA Execute handler command 59124/E6F4 Invoke device handler 59135/E6FF Search handler table 59158/E716 Find device handler

59193 E739 PHR

Peripheral handler loader. Includes the following routines: Address Routine 59193/E739 Initialization 59326/E7BE Perform poll 59358/E7DE Load handler 59414/E816 Get byte routine 59443/E833 Get next load block 59485/E85D Search handler chain 59540/E894 Handler warm start initialization 59544/E898 Warm start initialization with chaining 59550/E89E Cold start initialization 59584/E8C0 Initialize handler and update MEMLO 59648/E900 Initialize handler 59669/E915 Handler unlinking

59740 E95C SIO

The SIO section includes the following routines: Address Routine 59740/E95C Initialization 59761/E971 SIO main routine 59946/EA2A Complete SIO operation 59959/EA37 Wait for completion or ACK 60040/EA88 Send buffer to serial bus 60077/EAAD Process serial output ready IRQ 60140/EAEC Process serial output complete 60157/EAFD Receive 60199/EB27 Indicate timeout 60204/EB2C Process serial input ready IRQ 60295/EB87 Set buffer pointers 60317/EB9D Process cassette I/O 60433/EC11 Timer expiration 60439/EC17 Enable SIO send 60480/EC40 Enable SIO receive 60502/EC56 Set for send or receive 60548/EC84 Disable send or receive 60570/EC9A Get device timeout 60585/ECA9 Table of SIO interrupt handlers (six bytes) 60591/ECAF Send to intelligent device 60608/ECC0 Set timer and wait 60616/ECC8 Compute baud rate 60718/ED2E Adjust VCOUNT value 60733/ED3D Set initial baud rate 60871/EDC7 Process BREAK key 60898/EDE2 Set SIO VBLANK parameters

60921 EDF9 TPFV

Table of POKEY frequency values (24 bytes).

60945 EE11 NTSC/PAL

Table of constant values.

60957 EE1D Tables

Screen memory and display list tables. Address Table 60957/EE1D Screen memory allocation 60973/EE2D Display list entry counts 61005/EE4D ANTIC graphics modes 61021/EE5D Display list vulnerability 61037/EE6D Left shift columns 61053/EE7D Mode column counts 61069/EE8D Mode row counts 61085/EE9D Right shift counts 61101/EEAD Display masks

61116 EEBC PHE

Peripheral handler entry, includes the following routines: Address Routine 61177/EEF9 PH poll at OPEN 61222/EF26 Put-byte routine for provisionally open IOCB

61294 EF6E SIN

Initialize screen routine. Includes other screen handler routines: Address Routine 61326/EF8E Perform screen OPEN 61332/EF94 Perform editor OPEN 61340/EF9C Complete OPEN command 61824/F180 Screen get-byte routine 61839/F18F Get data under cursor 61860/F184 Screen put-byte routine 61828/F184 Check end of line 61898/F1CA Plot point 61929/F1E9 Display 61960/F208 Set exit conditions 61982/F21E Screen STATUS 61997/F22D Screen editor SPECIAL (just RTS) 61998/F22E Screen editor CLOSE 62026/F24A Editor get-byte (see below) 62128/F2B0 Editor put-byte (see below) 62142/F2BE Process character

62026 F24A GETCHAR

New location for the "get character" routine (used to be at 63038). If you use the routines for screen display in Machine Language for Beginners, you'll have to change this address for proper XL operation.

62128 F2B0 OUTCHAR

New location for the "put character" routine. See the note in 62026. Several programs make use of an illegal call to the "get character" and "put character" routines, previously at 63038 and 63140 ($F63E and F6A4), now at locations 62026 and 62128 ($F24A and $F2B0), respectively. You may be able to correct some problems in your software by searching for and replac- ing the older vectors with the new locations.

62200 F2F8 IGN

Ignore character and do keyboard get-byte.

62205 F2FD KGB

Keyboard GET-BYTE routine. The keyboard handler follows and includes the following routines: Address Routine 62432/F3E0 Escape character handler 62438/F3E6 Move cursor up 62451/F3F3 Move cursor down 62464/F400 Move cursor left 62474/F40A Move cursor to right margin 62476/F40C Set cursor column 62481/F411 Move cursor point 62491/F41B Move cursor to left margin 62496/F420 Clear screen 62528/F440 Move cursor home (upper-left corner) 62586/F47A Tab character handler 62613/F495 Set tab 62618/F49A Clear tab 62623/F49F Insert character 62677/F4D5 Delete character 62732/F50C Insert line 62752/F52D Delete line 62806/F556 Sound bell 62815/F55F Cursor to bottom 62821/F565 Double-byte double decrement 62825/F569 Store data for fine scrolling 62840/F578 Double-byte single decrement 62880/F5A0 Set scrolling display list entry 62892/F5AC Convert cursor row/column to address 62986/F60A Advance cursor routines 63073/F661 Return with scrolling 63077/F665 Return 63150/F6AE Subtract end point 63164/F6BC Check cursor range routines 63256/F718 Restore old data under cursor

63267 F723 BMI

Bitmap routines for the editor and screen handler.

63479 F7F7 SCR

Screen scroll routines.

63665 F8B1 CBC

Buffer count computation routines; various keyboard, editor, and screen follow, including: Address Routine 63768/F918 Delete line 63804/F93C Check for control character 63820/F94C Save row and column values 63831/F957 Restore row and column 63842/F962 Swap cursor with regular cursor position 63875/F983 Sound key click 63895/F997 Set cursor at left edge 63910/F9A6 Set memory scan counter address 63919/F9AF Perform screen SPECIAL command

64260 FB04 TMSK

Various screen and keyboard tables begin here: Address Table 64260/FB04 Bit masks 64264/FB08 Default screen colors (PF0-3, BAK) 64269/FB0D Control character routines (each entry is three bytes; control character and two-byte address of processing routine) 64317/FB3D Shifted function key routines (1200XL) 64329/FB49 ATASCII to internal conversion constants 64333/FB4D Internal to ATASCII conversion constants 64337/FB51 Keyboard definition (see below) 64529/FC11 Function key definitions

64337 FB51 ....

Start of the 192-byte keyboard definition table; see location 121, 122 ($79, $7A).

64537 FC19 KIR

Keyboard IRQ processing routines; check and process charac- ter, CONTROL-1, HELP key, CONTROL and function keys (1200XL; although the code for function keys remains in the 800XL and XE series) 64708 FCC4 FDL Process display list interrupt for fine scrolling.

64728 FCD8 CIN

Cassette initialization routine, followed by cassette I/O routines and table of NTSC/PAL constants for file leader length and beep duration.

65177 FE99 PIN

Printer initialization and I/O routines including: Address Routine 65218/FEC2 Printer OPEN 65227/FECB Printer put-byte 65261/FEED Fill printer buffer 65270/FEF6 Perform printer put 65287/FF07 Printer CLOSE 65300/FF17 Set up DCB for printer 65348/FF44 Printer timeout from STATUS 65355/FF4B Process print mode

65395 FF73 VFR

ROM checksum verify routines for first 8K bank.

65426 FF92 VSR

Verify routines for ROM checksum, second 8K bank, including routines to examine checksum region and table of addresses to verify.

65518-65529 FFEE-FFF9 ....

Checksum and identification data for the ROM area 57344-65535 ($E000-$FFFF--see 49152, $C000 for more information): Byte Use 65518/FFEE Revision date D1 and D2 (four-bit BCD) 65519/FFEF Revision date M1 and M2 65520/FFF0 Revision date Y1 and Y2 65521/FFF1 Option byte; should read 1 for the 1200XL (my 800XL reads 2) 65522-26/FFF2-6 Part number in the form AANNNNNN 65527/FFF7 Revision number (again, mine reads 2) 65528-9/FFF8-9 Checksum, bytes (LSB/MSB) 65527 and 65528 should read 221 ($DD) and 87 ($57) for the 400/800 revision A ROMS; 243 ($F3) and 230 ($E6) for the B ROMS. PAL versions read 214/87 ($D6/$57) and 34/88 ($22/$58), respectively. The 1200XL should read 10 at 65527 for revision A and 11 for revision B. The 600XL should read 1 at 65527, and the 800XL, 2. For the 1200XL, 64728 ($FCD8) should not read 162 ($A2).

65530-65535 FFFA-FFFF Machine vectors

Contain NMI, RESET (power-up), and IRQ service vectors, initial- ized to 49176 ($C0l8), 49834 ($C2AA), and 49196 ($C02C), respectively.

Return to Table of Contents | Previous Chapter | Next Chapter