You are on page 1of 124

This book is an independent production of Ing. W.

HOFACKER
GMBH International. It is published as a service to all ATARI
personal computer user worldwide.
All rights reserved. No part of th is book may be reproduced by
any means without the express written permission of the publisher.
Example programs are for personal use only. Every reasonable
effort has been made to ensure accuracy throughout this book,
but neither the author or publisher can assume responsibility for
any errors or omissions. No liability is assumed for any direct, or
indirect, damages resulting from the use of information contained
herein.
First Edition
First Printing
1983 in the Federal Republic of Germany

Copyright 1983 by Winfried Hofacker


Cover design by Franz Berthold

ISBN 3-88963-172-X
Reference is made to ATARI throughout this book . ATARI is a trademark of ATARI
Inc .. a division of Warner Communications Company.

Publisher:
Ing. W. HOFACKER GmbH. Tegernseerstr. 18. D-8150 Holzkirchen. W.-Germany

US-Distributor:
E LCOMP Publishing. Inc .. 53 Redrock Lane. Pomona CA 91766

PREFACE
Since more and more users of the ATARI personal computers
write programs in machine language, more and more "workhorse"routines, performing standard tasks, are required.
This book contains a variety of programs for the real computer
"Hacker" and the machine language programmer.
All the programs have been fully tested and a complete source
code is provided.
I extend my thanks to Franz Ende for the translation and Karl
Wagner for his proofreading.

Munich, Spring 1983

H. C. Wagner

IMPORTANT NOTICE
This book is written for the experienced AT AR I Personal
Computer owner. To run the programs you need a symbolic
Editor/Assembler or the ATAS/ATMAS from ELCOMP Publishing.
For details please refer to the OS-Manual from AT AR I.

CONTENTS

CHAPTER 1
1-1
I nput and output of numbers. . . . . . . . . . . . . . . . . .. 1
1-1-1 Hexadecimal input . . . . . . . . . . . . . . . . . . . . . . . . . . . 1
1-1-2 Hexadecimal output. . . . . . . . . . . . . . . . . . . . . . . . .. 2
1-1-3 Decimalinput ............................... 5
1-1-4 Decimal output ............................. 6
1-2
16-bit arithmetic without sign .................. 8
1-2-1 16-bit addition . . . . . . . . . . . . . . . . . . . . . . . . . . . . .. 8
1-2-2 16-bit subtraction. . . . . . . . . . . . . . . . . . . . . . . . . . .. 10
1-2-3 16-bitmultiplication ......................... 10
1-2-4 16-bit division .............................. 13
CHAPTER 2
STR I NGOUTPUT ........................... 15
2-1
Output of text
15
CHAPTER 3
INTRODUCTION TO CIO ................... .. 18
The standard CIO commands .................. , 21
How to read or write data in machine-language
24
CHAPTER 4
INTRODUCTION TO THE DISK-CONTROLLER
31
The DCB-commands . . . . . . . . . . . . . . . . . . . . . . . . . . 32
How to write a sector to disk ................... 34
CHAPTER 5
HOW TO MAKE A BOOTABLE PROGRAM ....... 39
How to make a bootable disk ................... 42

CHAPTER 6
HOW TO MAKE A BOOTABlE CARTRIDGE
Sample program for a cartridge: MEMORY TEST ...
EPROM-BURNER for the ATARI 800/400 ........
Hexdump of the EPROM BURNER software .......
Using the EPROM board Kit from Hofacker .......

43
47
50
59
65

CHAPTER 7
HOW TO ADD OR CHANGE A DEVICE ......... 67
CHAPTER 8
A BOOTABlE TAPE GENERATOR PROGRAM ... 75
CHAPTER 9
A DIRECT CASSETTE TO DISK COPY PROGRAM

89

CHAPTER 10
HOW TO CONNECT YOUR ATARI WITH
ANOTHER COMPUTER ...................... 98
CHAPTER 11
300 Baud serial interface via the Atari joystick ports 103
CHAPTER 12
Printer Interface ............................ 106
Differences between the ATAR I Editor/Assembler
cartridge and AT AS-1 and A TMAS-1 ............ 115

ARITHMETIC
CHAPTER 1

1-1 Input and output of numbers

When working with numbers one often wants


to input and output them via the screen.
The following programs show how this can
be done with hexadecimal as
well
as
decimal numbers.
1-1-1 Hexadecimal input

This
program
allows
you
to
enter
hexadecimal numbers using the keyboard.
The number entered is displayed on the
screen. The input stops if a character
different from the hexadecimal numbers (0 ..
F) is entered .
The program first deletes memory locations
EXPR and EXPR+l .
This ensures a result
equal to zero, even if an invalid number
is entered.
Ne x t,
the program reads a
character and checks whether or not it is
a hexadecimal number.
If it is, then the
upper
bits
of
the
number
in
the
accumulator are erased and the lower bits
are shifted up. Now, these four bits can
be shifted to EXPR from the right. The
preceeding number in EXPR is shifted to
the left by doing so .
If you enter a number with more than four
digits, only the last four digits are used.
Example : ABCDEF => CDEF

******~*******************************

*
*
HEXINPUT ROUTINE
*
*
*
*
**************************************
EXPR

EQU $80.1

SCROUT
GETCHR

EQU $F6A4
EQU $F6DD
ORG $A800

A800:
A802:
A804:
A806:
A809:
A80B:
A80D:
A80F:
A81l:
A813:
A815:
A817 :
A819:
A81B:
A81C:
A81D:
A81E:
A81F:
A821 :
A822:
A824 :
A826:
A827:
A829:
A82B:

HEXIN
A200
8680
8681
202CA8 HEXIN1
C930
901E
C93A
900A
C941
9016
C947
B012
E936
OA
HEXIN2
OA
OA
OA
A204
HEXIN3
OA
2680
2681
CA
DOF8
FODB
HEXRTS
60

A82C: 20DDF6 NEXTCH


A82F: 20A4F6
A832: 60
2

LDX
STX
STX
JSR
CMP
BCC
CMP
BCC
CMP
BCC
CMP
BCS
SBC
ASL
ASL
ASL
ASL
LDX
ASL
ROL
ROL
DEX
BNE
BEQ
RTS

#0
EXPR
EXPR+1
NEXTCH
,0
HEXRTS
'9+1
HEXIN2
'A
HEXRTS
'F+1
HEXRTS
'A-10-1

#4
EXPR
EXPR+1
HEXIN3
HEXIN1

JSR GETCHR
JSR SCROUT
RTS

ALWAYS ! !

SHOW CHARACTE.

PHYSICAL ENDADDRESS: $A833

***

NO WARNINGS

EXPR
GETCHR
HEXINI
HEXIN3
NEXTCH

$80
$F6DD
$A806
$A821
$A82C

SCROUT
HEXIN
HEXIN2
HEXRTS

$F6A4
$A800
$A81B
$A82B

UNUSED

1-1-2 Hexadecimal output


The
next
program explains
the output
process of the calculated numerals.
You will recognize,
that the portion of
the program which controls the output is a
subroutine. This subroutine only displays
the contents of the accumulator.
This
means that you first have to load the
accumulator
with,
for example,
the
contents of EXPR+l,
then jump into the
subroutine where first the MSB (EXPR+l in
our case) and then the LSB (EXPR)
will be
printed.
Subroutine PRBYTE independently prints the
most significant bytes of
the accumulator
first
and the least significant bytes
second.
3

**************************************
*
*
HEXOUT
PRINTS
1
BYTE
*
*
*
*
**************************************
EXPR

EPZ $80.1

SCROUT

EQU $F6A4
ORG $A800

A800:
A802:
A805:
A807:
A80A:

A80B:
A80C:
A80D:
ABOE:
A80F:
A810:
A813:
A814:
A816:
A818:
A8IA:
A8IC:
A81E:
A820:

A581
PRWORD
200BA8
A580
200BA8
60

48
4A
4A
4A
4A
2016A8
68
290F
C90A
B004
0930
D002
6936
4CA4F6

LDA
JSR
LDA
JSR
RTS

EXPR+l
PRBYTE
EXPR
PRBYTE

THE VERY PRBYTE ROUTINE

PRBYTE

PHA
LSR
LSR
LSR
LSR
JSR
PLA
AND
CMP
BCS
ORA
BNE
ADC
JMP

HEX OUT

ALFA
HXOUT

HEXOUT
#%00001111
#10
ALFA
'0
HXOUT
'A-I0-l
SCROUT

PHYSICAL ENDADDRESS: $A823

*** NO WARNINGS
EXPR
PRWORD
HEX OUT
HXOUT
4

$80
$A800
$A816
$A820

UNUSED

SCROUT
PRBYTE
ALFA

$F6A4
$A80B
$A81E

1-1-3 Decimal input


When you calculate
with
numbers
you
probably prefer decimals over hexadecimals.
The following program can be used to read
decimal
numbers and convert them into
binary numbers readable by computers.
The program first checks,
to see if the
input is a decimal number (0 . 9) or if the
input has been terminated
by
another
character.
EXPR and EXPR+l are erased. If
a digit is accepted then the upper bits
are erased.
Next the contents of EXPR and
EXPR+l are multiplied by 10 and the new
number is added. In the end the MSB is in
location EXPR+l and the LSB is in location
EXPR.
Numbers greater than 65535 are displayed
in modulo 65536
(the rest which remains
after deduction of 65535).

**************************************

*
*
*
*
*

DECIMAL TO 1 WORD
CONVERSION

*
*
*
*
*

**************************************
EXPR

EQU $80.1

SCROUT
GETCHR

EQU $F6A4
EQU $F6DD
ORG $A800

A800:
A802:
A804:
A806:
A809:
A80B:
A80D:
A80F:

A200
DECIN
8680
8681
2026A8 DEC1
C930
9018
C93A
B014

LDX
STX
STX
JSR
CMP
BCC
CMP
BCS

#0
EXPR
EXPR+1
NEXTCH
'0
DECEND
'9+1
DECEND
5

A811: 290F
A813: A211
A815: D005
A817:
A819:
A81B:
A81C:
A81E:
A820:
A821:
A823:
A825 :

9002
6909
4A
6681
6680
CA
DOF4
FOEl
60

AND #%00001111
LDX #17
BNE DEC3
ALWAYS TAKEN
DEC2
DEC3

DECEND

A826: 20DDF6 NEXTCH


A829: 20A4F6
A82C: 60

BCC
ADC
LSR
ROR
ROR
DEX
BNE
BEQ
RTS

*+.4
#10-1
EXPR+l
EXPR
DEC2
DECl

ALWAYS! !

JSR GETCHR
JSR SCROUT
RTS

PHYSICAL ENDADDRESS: $A82D


*** NO WARNINGS
EXPR
GETCHR
DECl
DEC3
NEXTCH

$80
$F6DD
$A806
$A81C
$A826

SCROUT
DECIN
DEC2
DEC END

$F6A4
$A800
$A817
$A825

UNUSED

1-1-4 Decimal output


The next program allows you to display
decimal numbers.
The program works as follows :
The X-register is loaded with the ASCII
equivalent of the digit o. This number is
then incremented to the highest potency of
10
(10000) and is displayed on the screen.
6

The same procedure is repeated for 1000,


100,
and 10 . The remaining is converted
into an ASCII number, using an OR-command,
and is displayed.
You
might
want to change the output
routine so that it avoids leading zeroes.

**************************************

2 BYTE BINARY NUMBER


*
*
*
*
TO 5 DIGITS DECIMAL
*
*
*
*
CONVERSION
*
*
*
*
WITH LEADING ZEROS
*
*
*
*
**************************************
DECL
DECH
TEMP

EQU $80
EQU $81
EQU $82

SCROUT

EQU $F6A4
ORG $A800

A800:
A802:
A804:
A805:
A807 :
A80A:
A80B:
A80C:
A80E:
A811:
A813:
A815:
A816:
A8I8:
A8I9:

A007
DECOUT
A230
DECOUT1
38
DECOUT2
A580
F92EA8
48
88
A581
F930A8
9009
8581
68
8580
E8
C8

LDY
LDX
SEC
LDA
SBC
PHA
DEY
LDA
SBC
BCC
STA
PLA
STA
INX
INY

#7
'0
DECL
DECTAB-1,Y
DECH
DECTAB+1,Y
DECOUT3
DECH
DECL

ABIA:
ABIC:
ABID:
ABlE:
AB20:
AB23 :
A82S:
A826:
A828 :
A82A:
A82C:

DOEB
DECOUT3
6B
BA
B4B2
20A4F6
A4B2
88
10DA
AS80
0930
4CA4F6

BNE
PLA
TXA
STY
JSR
LDY
DEY
BPL
LDA

DECOUT2

AB2F:
A831:
A833:
A83S:

OAOO
6400
E803
1027

DFW
DFW
DFW
DFW

10
100
1000
10000

DECTAB

TEMP
SCROUT
TEMP

DECOUTI
DECL
ORA 10
JMP SCROUT

PHYSICAL ENDADDRESS: $A837

***

NO WARNINGS

DECL
TEMP
DECOUT
DECOUT2
DECTAB

$80
$82
$A800
$A804
$A82F

DECH
SCROUT
DECOUT1
DECOUT3

$81
$F6A4
$A802
$A81C

UNUSED

1-2 16-bit arithmetic without sign


1-2-1 16-bit addition
The 16-bit addition is well known,
but it
is shown here one more time, together with
the subtraction.
8

**************************************
*
*
16 BIT ADDITION
*
*
*
*
UNSIGNED INTEGER
*
*
*
*
EXPRI := EXPRI + EXPR2
*
*
*
*
**************************************
EXPRI
EXPR2

EPZ $80.1
EPZ $82.3
ORG $A800

A800:
A801:
A803:
A805:
A807:
A809:
A80B:
A80D:

18
A580
6582
8580
A581
6583
8581
60

ADD

CLC
LDA
ADC
STA
LDA
ADC
STA
RTS

EXPRI
EXPR2
EXPRI
EXPR1+1
EXPR2+1
EXPRl+l

PHYSICAL ENDADDRESS: $A80E

*** NO WARNINGS
EXPR1
ADD

$80
$A800

EXPR2
UNUSED

$82

1-2-2 16-bit subtraction


**************************************
*
*
16 BIT SUBTRACTION
*
*
*
*
*
UNSIGNED
INTEGER
*
*
*
EXPRI := EXPRI - EXPR2
*
*
*
*
**************************************
EXPRI
EXPR2

EPZ $80.1
EPZ $82.3
ORG $A800

A800:
A801:
A803:
A805:
A807 :
A809:
A80B:
A80D:

38
A580
E582
8580
A581
E583
8581
60

SUB

SEC
LDA
SBC
STA
LDA
SBC
STA
RTS

EXPRI
EXPR2
EXPRI
EXPRl+l
EXPR2+1
EXPRl+l

PHYSICAL ENDADDRESS: $A80E


*** NO WARNINGS
EXPRI
SUB

$80
$A800

EXPR2

$82

UNUSED

1-2-3 16-bit multiplication


The
multiplication
is
much
more
complicated than addition or subtraction.
Multiplication in the binary number system
is actually the same as in the decimal
system .
Let's have a look at how we
multiply using the decimal system.
For
example, how do we calculate 5678*203 ?
10

5678
203

17034
00000
11356
1152634
With each digit the previous number is
shifted to the right.
If
the digit
is
different
from
zero
the new
interim
results are added. In the binary system it
works the same way. For example :
1011
1101

1011
0000
1011
1011
10001111
As you can see it is simpler in the binary
system than in the decimal system.
Since
the highest possible number for each digit
is 1 the highest interim results
is equal
to the multiplicand.
The following program in principle does
the same as the procedure described above,
except that the interim result
is shifted
to the right and the multiplicand is added,
if required. The results are the same.
Six memory locations are required. Two of
these
(SCRATCH and SCRATCH+l)
are used
only part of
the time,
while the other

11

four locations keep the two numbers to be


multiplied
(EXPRl and EXPRl+l, EXPR2 and
EXPR2+l).
After the
calculations
the
result is
in locations EXPRl
(LSB) and
EXPRl+l (MSB).

**************************************

*
*
*
*
*
*
*

16 BIT MULTIPLICATION
UNSIGNED INTEGER
EXPRI := EXPRI

EXPR2

*
*
*
*
*

**************************************
EXPRI
EXPR2
SCRATCH

EPZ $80.1
EPZ $82.3
EPZ $84.5
ORG $A800

A800:
A802:
A804:
A806:
A808:
A80A:
A80B:
A80D:
A80F:
A811:
A813:
A815:
A817:
A819:
A81B:
A81D:
A81F:
A820:
A822:
A824:
A826:
12

A200
8684
8685
AOI0
DOOD
18
A584
6582
8584
A585
6583
8585
4685
6684
6681
6680
88
3004
90F3
BOE4
60

MUL

MULl

MUL2

MULRTS

LDX
STX
STX
LDY
BNE
CLC
LDA
ADC
STA
LDA
ADC
STA
LSR
ROR
ROR
ROR
DEY
BMI
BCC
BCS
RTS

#0
SCRATCH
SCRATCH+l
#16
MUL2
ALWAYS! 1
SCRATCH
EXPR2
SCRATCH
SCRATCH+l
EXPR2+1
SCRATCH+l
SCRATCH+l
SCRATCH
EXPRl+l
EXPRl
MULRTS
MUL2
MULl

PHYSICAL ENDADDRESS: $A827

*** NO WARNINGS
EXPRl
SCRATCH
MULl
MULRTS

$80
$84
$A80A
$A826

EXPR2
MUL
MUL2

$82
$A800
$A817

UNUSED

1-2-4 16-bit division


The division of two numbers actually is
just the opposit of the multiplication.
Therefor, you can see in the program below,
that the divisor is subtracted and the
dividend is shifted to the left rather
than to the right. The memory locations
used
are
the
same
as
with
the
multiplication,
except that locations
SCRATCH and SCRATCH+l are named REMAIN and
REMAIN+l.
This means the remainder of the
division is stored in those locations.

**************************************

*
16 BIT DIVISION
*
*
*
*
UNSIGNED INTEGER
*
*
*
- EXPRl OVER EXPR2
EXPRl ..*
*
*
*
- EXPRl MOD EXPR2
REMAIN ..*
*
*
*
**************************************
EXPRl
EXPR2
REMAIN

EPZ $80.1
EPZ $82.3
EPZ $84 . 5

ORG $A800
ABOO: A200
A802: 8684

DIV

LDX #0
STX REMAIN
13

A804:
A806:
A808 :
A80A:
A80C:
A80E:
A810:
A811:
A813:
A815:
A816:
A818:
A8IA:
A8IC:
A8IE:
A820 :
A822:
A823:
A825:

8685
AOI0
0680
2681
2684
2685
38
A584
E582

DIVI

AA

A585
E583
9006
8684
8585
E680
88
DOE3
60

DIV2

STX
LDY
ASL
ROL
ROL
ROL
SEC
LDA
SBC
TAX
LDA
SBC
BCC
STX
STA
INC
DEY
BNE
RTS

REMAIN+l
#16
EXPRI
EXPRl+l
REMAIN
REMAIN+l
REMAIN
EXPR2
REMAIN+I
EXPR2+1
DIV2
REMAIN
REMAIN+I
EXPRI
DIVI

PHYSICAL ENDADDRESS: $A826

***

NO WARNINGS

EXPRI
REMAIN
DIVI

14

$80
$84
$A808

EXPR2
DIV
DIV2

$82
$A800
$A822

UNUSED

STRINCOUTPUT

CHAPTER 2

2-1 Output of text


With most programs
it is necessary to
display text (menues etc.).
The following program
allows
you
to
display
strings of any length at any
location you desire.
The output command
can be located at any place within your
program.
How does that program work ?
As you know the 6502 microprocessor uses
its stack to store the return address if a
JSR-command is to be executed.
The number
that is stored on the stack actually is
the return-address minus one.
The trick
used in this program is, that the string
to be printed is stored immediately after
the JSR-command and the last character of
the string is
incremented by 128.
The
subroutine calculates the start address of
the string, using the number on the stack,
and reads the string byte by byte, until
it finds
the
byte
which
has
been
incremented by 128 .
The address of this
byte now is stored on the stack and an RTScommand is executed.
By doing so, the
string is jumped and the command after it
is executed .
15

**************************************
*
*
STRINGOUTPUT FOR
*
*
*
*
*
VARIOUS LENGTH
*
*
*
**************************************
EPZ $80
AUX
SCROUT

EQU $F6A4
ORG $A800

A800:
A803:
A806:
A809:
A80C:
A80F:
A812:
A815:

A816:
A817 :
A819:
A81A:
A81C:
A81E:
A820 :
A822:
A824 :
A826:
A828:
A82B:
A82D:
A82F:
A831:
A833:
A834:
A836:
A837:
16

*
2016A8 EXAMPLE
544849
532049
532041
4E2045
58414D
504CC5
60
*
PRINT

68
8580
68
8581
A200
E680
PRINTI
D002
E68l
A180
297F
20A4F6
A200
A180
lOED
A581
48
A580
48
60

EXAMPLE
JSR PRINT
ASC \THIS . IS AN EXAMPLE\

RTS
THE VERY PRINTROUTINE
PLA
STA AUX
PLA
STA AUX+l
LDX #0
INC AUX
BNE *+4
INC AUX+l
LDA (AUX,X)
AND #$7F
JSR SCROUT
LDX #0
LDA (AUX,X)
BPL PRINTl
LDA AUX+l
PHA
LDA AUX
PHA
RTS

PHYSICAL ENDADDRESS: $A838

***

NO WARNINGS

AUX
EXAMPLE
PRINTI

$80
$A800
$A81E

UNUSED

SCROUT
PRINT

$F6A4
$A816

17

INTRODUCTION
TOCIO
CHAPTER 3

The CIO can handle up to 8 devices/files


at the same time.
This happens via so
called 10-ControlBlocks (IOCB). This means
that there are 8 10CB'S starting from
$0340. Each of the 10CB's is 16 bytes long.

+----------------+
~

10CB #0

$0340

+----------------+
~

10CB #1

$0350

+----------------+
~

10CB #2

$0360

+----------------+
'1
I OC B # 3
'1 $ 0 3 7 0
+----------------+
~

10CB #4

$0380

+----------------+
~

10CB #5

$0390

+----------------+
~

10CB #6

$03AO

+----------------+
~

10CB #7

$0380

+----------------+
A single 10CB has the following
scheme:

internal

+----------------+

'1

ICHID

'1

ICDNO

'1

HANDLER ID

'1

DEVICE NUMBER

+----------------+
+----------------+
'1
ICCMD
'1 COMMAND
+----------------+
18

ICSTA

STATUS

+----------------+
~

,
,

ICBAL

-+ BUFFERADR

+ICBAH

+----------------+
~

ICPTL

-+ PUTADR

+ICPTH

+----------------+
~

ICBLL

+~

ICBLH

-+ BUFFERLEN
~

+----------------+
,

ICAXl

AUXl

+----------------+
,

ICAX2

AUX2

+----------------+
~

ICAX3

Remaining 4 byte

+----------------+
~

ICAX4

+----------------+
,

ICAX5

+----------------+
,

ICAX6

+----------------+
There are just a few locations which are
important to the user:
The commandbyte which
contains
the
command to be executed by the CIO.
The bufferaddress which contains the
address of the actual databuffer.
The bufferlength which contains
the
number of bytes to be transferred (rounded
up to a variety of 128 bytes for the
cassette device)
And there are two auxiliaries
which
contain device-dependent information.
19

There are also locations


altered by CIO such as:

which

The handler-ID is an
devicetable.
This table
devicenames and pointers
specific handlertable.

offset to the
contains
all
to the device-

+----------------+
~

device name

+----------------+
~

handler table

+----------------+
~

other

entries

+----------------+
~

zero fill to

end of table

+----------------+
A handlertable looks like:

+----------------+
~

OPEN-l

+----------------+
~

CLOSE-I

+----------------+
~

GETBYTE-I

+----------------+
~

PUTBYTE-I

+----------------+
'1

GETSTATUS-I

'1

+----------------+
~

SPECIAL-I

+----------------+
~

JMP INIT
& 00

+----------------+
20

be

--+

'1

'1
+- one entry

'1

address

will

'1

--+

The CIa is thus quite clear to the user.


It is easy to add new devices by adding
just 3 bytes to the devicetable and to
make
a specific handlertable for this
device.
You
can
also
change
the
handlerpointer of an existing device and
let point it to a new handler.
Later we
will describe how to add or change devices.
The
devicenumber
shows
us
which
subdevice is meant.
(e.g. Disknumber or
RS232 Channel).
- After calling CIa the status will be
altered. A 1 means a successfull operation
while a value greater than 128 means an
error has occurred.
- PUTADR is used internally by the CIa
If
there
have
been
less
bytes
transferred than desired,
because of an
EOL or an error, BUFLEN will contain the
actual number of transferred bytes.
The standard CIa commands:
- OPEN opens a file.
IOCB
Before
execution
the
following
locations have to be set:
COMMAND = $03
BUFFADR
points
to
device/filename
specification (like C:
or D: TEST. SRC)
terminated by an EOL ($9B)
OPEN-directionbits (read or write)
AUXl
plus devicedependent information.
AUX2 = devicedependent information.
After execution:
HANDLER ID = Index to the devicetable.
DEVICE
NUMBER
=
number
taken
from
device/filename specification
STATUS = result of OPEN-Operation.
21

- CLOSE closes an open 10CB


Before
execution
the
location has to be set:
COMMAND = SOC

following

10CB

After execution:
HANDLER ID = $FF
STATUS = result of CLOSE-operation
- GET CHARACTERS read byte aligned.
has no termination feature.

EOL

Before
execution
the
following
10CB
locations have to be set:
COMMAND = $07
BUFFERADR = points to databuffer.
BUFFERLEN = contains number of characters
to be read. If BUFFERLEN is equal to zero
the 6502 A-register contains the data.
After execution:
STATUS = result of GET CHARACTER-operation
BUFFERLEN = number of bytes read to the
buffer. The value will always be equal
before execution,
only if EOF or an error
occurred.
- PUT CHARACTERS write byte aligned
Before
execution
the
following
10CB
locations have to be set:
COMMAND = SOB
BUFFERADR = points to the databuffer
BUFFERLEN = number of bytes to be put, if
equal to zero the 6502 A-register has to
contain the data.
After execution:
STATUS = result of PUT CHARACTER-operation
22

- GET RECORD characters are read to the


databuffer until the buffer is full, or an
EOL is read from the device/file.
Before
execution
the
following
IOCB
locations have to be set:
COMMAND = $05
BUFFERADR = points to the databuffer
BUFFERLEN = maximum of bytes to be read
(Including EOL character)
After execution:
STATUS = result of
the
GET
RECORDoperation
BUFFERLEN = number of bytes read to buffer
this may less then the maximum length.
- PUT RECORD characters are written to the
device/file from the databuffer until the
buffer is empty or an EOL is written.
If
the buffer is empty CIO will automatically
send an EOL to the device/file.
IOCB
Before
execution
the
following
locations have to be set:
COMMAND = $09
BUFFERADR = points to databuffer
BUFFERLEN = maximum number of bytes in
databuffer.
After execution:
STATUS = result of PUT RECORD-operation.
In addition to the main-commands,
there
is also a GET STATUS ($00) command, which
obtains the status from the device/filecontroller and places these four bytes
from location $02EA (DVSTAT).
Commands
greater than $00 are so called SPECIALS
and devicehandler-dependent.
23

GET STATUS and SPECIALS have an implied


OPEN-option.
Thus
the file will be
it
automatically opened and closed if
wasn't already opened.
How to link the CIO with machine language?
First we have to modify the IOCB before
calling CIO.
The offset to the IOCB (IOCB# times 16)
has to be in the X-register. The STATUS
will be loaded in the Y-register after
returning from CIO. It is not necessary to
explicitly check the Y-register
(Comparing
with 128)
because loading the status into
the Y-register was the last instruction
before leaving CIO with an RTS. We simply
jump on the signflag
(BMI or BPL).
The
signflag is set if an error occurred. In
the next section we will discuss it in
more detail with an example.
How to read or write data
in machine-language
To describe the writing of data to a
device/file we will take the cassettedevice as an example. We can also use any
other device because CIO is very clear-cut
(see introduction).
Before
discussing the program,
some
conventions must be discussed.
The user has to put the address of his
databuffer into the locations BUFfER ($80.
l) and the bufferlength into the locations
BUFLEN
($82.3). Then the program should be
called as a subroutine. The description of
this subroutine follows.
First we have to open the cassette, so
we load the IOCB-offset in the X-register,

24

store the OPEN-command in ICCMD, and let


the BUFADR (ICBAL and ICBAH) point to the
device/filename specification. We have to
store the write-direction in ICAXI and the
tape-recordlength
(128)
in ICAX2,
just
call CIO ($E4S6). The Signflag indicates
if an error occurred.
After a correct opening of the file for
writing data, bit 3 is set because AUXl
contains a $08 (bit 2 is readbit).

+---------------+
'1 '1 '1 '1 'IW'I R'I ~I'I

+---------------+

AUXl

765 4 3 210

ICCMD
will be changed into the PUT
CHARACTERS-command ($OB),
BUFADR points
to
the
User-Databuffer
(contents
of
BUFFER) and BUFLEN (ICBLL and ICBLH) will
contain the number of bytes to write (the
user stores this value BUFLEN
($82. 3)).
Next
CIO
will be called,
and after
successfull operation,
the file will be
closed (ICCMD=$OC).
If, during any of these three CIO-calls,
an error occurs, the file will be closed
and both the ACCUMULATOR and Y-register
will contain the STATUS (errorcode).
By changing the string at CFILE in for
instance 'D: TEST. TST '
the program will
write the buffer to the specified diskfile.
The second listing shows you a program
that reads from a device,
only two bytes
are different,
so the program is selfexplaining.

25

**************************************

*
*
WRITE
BUFFER
TO
CASSETTE
*
*
****************************************
BUFFER
BUFLEN
ICCMD
ICBAL
ICBAH
ICBLL
ICBLH
ICAXI
ICAX2

EPZ $80.1
EPZ $82.3-BUFLEN ROUNDED
UP TO 128 BYTES
EQU $0342
EQU $0344
EQU $0345
EQU $0348
EQU $0349
EQU $034A
EQU $034B

OPEN
PUTCHR
CLOSE

EQU 3
EQU 11
EQU 12

WMODE
RECL

EQU 8
EQU 128

CIO

EQU $E456

EOL

EQU $9B

IOCBNUM

EQU 1
ORG $A800

*
A800:
A802:
A804:
A807:
A809:
A80C:
A80E:

26

A210
A903
9D4203
A908
9D4A03
A980
9D4B03

OPEN FILE
LDX
LDA
STA
LDA
STA
LDA
STA

#IOCBNUM*16
#OPEN
ICCMD,X
#WMODE
ICAXl,X
#RECL
ICAX2,X

A811:
A813:
A816:
A818:
A8IB:
A8IE:

A956
904403
A9A8
904503
2056 E4
3029

LOA
STA
LOA
STA
JSR
BMI

*
*
A820 :
A822:
A825:
A827 :
A82A:
A82C:
A82F:
A831:
A834:
A836:
A839:
A83C:

A90B
904203
A580
904403
A581
904503
A582
904803
A583
904903
2056 E4
300B

A83E:
A840:
A843:
A846:

A90C
904203
2056 E4
3001

....

PUT BUFFER IN RECORDS


TO CASSETTE
LOA #PUTCHR
STA ICCMO,X
LOA BUFFER
STA ICBAL,X
LOA BUFFER+I
STA ICBAH,X
LOA BUFLEN
STA ICBLL,X
LOA BUFLEN+1
STA ICBLH,X
JSR CIO
BMI CERR
CLOSE CASSETTE FILE

LOA
STA
JSR
BMI

#CFILE:L
ICBAL,X
#CFILE:H
ICBAH,X
CIO
CERR

#CLOSE
ICCMO,X
CIO
CERR

RETURN TO SUPERVISOR
RTS

A848: 60

*
*

RETURN WITH ERRORCOOE IN


ACCUMULATOR

27

A849:
A84A:
A84B:
A84D:
A850 :
A853:
A854:
A855:

~8

CERR

TYA
PHA
LDA #CLOSE
STA ICCMD,X
JSR CIO
PLA
TAY
RTS

CFILE

ASC "e: II
DFB EOL

48
A90C
9D4203
2056 E4
68
A8
60

A856: 433A
A858: 9B

PHYSICAL ENDADDRESS: $A859

*** NO WARNINGS
$80
$0342
$0345
$0349
$034B
SOB
$08
$E456
$01
$A856

BUFFER
ICCMD
ICBAH
ICBLH
ICAX2
PUTCHR
WMODE
CIO
IOCBNUM
CFILE

BUFLEN
ICBAL
ICBLL
ICAXl
OPEN
CLOSE
RECL
EOL
CERR

$82
$0344
$0348
$034A
$03
SOC
$80
$9B
$A849

**************************************
*
*
*
READ BUFFER FROM CASSETTE
*
*
*
**************************************
BUFFER
BUFLEN

EPZ $80.1
EPZ $82.3

ICCMD
ICBAL
ICBAH
ICBLL
ICBLH
ICAXl
ICAX2

EQU
EQU
EQU
EQU
EQU
EQU
EQU

28

$0342
$0344
$0345
$0348
$0349
$034A
$034B

BUFLEN ROUNDED
UP TO 128 BYTES

OPEN
GETCHR
CLOSE

EQU 3
EQU 7
EQU 12

RMODE
RECL

EQU 4
EQU 128

CIO

EQU $E456

EOL

EQU $9B

IOCBNUM

EQU 1
ORG $A800

*
A800:
A802:
A804:
A807:
A809:
A80C:
A80E:
A811:
A813:
A816:
A818 :
A81B:
A81E:

LDX
LDA
STA
LDA
STA
LDA
STA
LDA
STA
LDA
STA
JSR
BMI

A210
A903
9D4203
A904
9D4A03
A980
9D4B03
A956
9D4403
A9A8
9D4503
2056E4
3029
*
*

A820 :
A822 :
A825:
A827 :
A82A:
A82C:
A82F:
A83l:

A907
9D4203
A580
9D4403
A581
9D4503
A582
9D4803

OPEN FILE
#IOCBNUM*16
#OPEN
ICCMD,X
#RMODE
ICAXl,X
#RECL
ICAX2,X
#CFILE:L
ICBAL,X
#CFILE:H
ICBAH,X
CIO
CERR

GET BUFFER IN RECORDS


FROM CASSETTE
LDA
STA
LDA
STA
LDA
STA
LDA
STA

#GETCHR
ICCMD,X
BUFFER
ICBAL,X
BUFFER+l
ICBAH,X
BUFLEN
ICBLL,X

29

A834:
A836:
A839:
A83C:
A83E:
A840:
A843:
A846:

LDA
STA
JSR
BMI

1\583

9D4903
2056E4
300B
A90C
9D4203
2056 E4
3001

CLOSE CASSETTE FILE


LDA #CLOSE
STA ICCMD,X
JSR CIO
BMI CERR

RETURN TO SUPERVISOR

A848: 60

RTS

*
*
A849:
A84A:
A84B:
A84D:
A850:
A853:
A854:
A855:

98
CERR
48
A90C
9D4203
2056E4
68
A8
60

A856: 433A
A858 : 9B

BUFLEN+1
ICBLH,X
CIO
CERR

CFILE

RETURN WITH ERRORCODE If


ACCUMULATOR
TYA
PHA
LDA #CLOSE
STA ICCMD,X
JSR CIO
PLA
TAY
RTS
ASC lie:"
DFB EOL

PHYSICAL ENDADDRESS: $A859

*** NO WARNINGS
BUFFER
$80
ICCMD
$0342
$0345
ICBAH
$0349
ICBLH
ICAX2
$034B
GETCHR
$07
RMODE
$04
CIO
$E456
IOCBNUM
$01
CFILE
$A856
30

BUFLEN
ICBAL
ICBLL
ICAXI
OPEN
CLOSE
RECL
EOL
CERR

$82
$0344
$0348
$034A
$03

SOC
$80
$9B
$A849

INTRODUCTION
TO THE DISK
CONTROLLER
CHAPTER 4
We
already
know
how
to handle any
device/file via CIO,
including handle a
diskfile.
Included on a disk is also a
a sector-IO which allows you to address a
single
sector
for a read- or writehandling. Sector-IO doesn't need any file
on the disk.
The disk has only to be
fOrIna t ted.
A floppy disk with the ATARI-drive has 720
sectors
and
each
of
them is fully
addressable.
How does the sector-IO function?
simplistic
The disk-controller
has
a
design
containing
a single IOCB like
DCB
is
Data Control Block (DCB).
This
described in the following scheme.

+----------------+
~

DCBSBI

Serial bus ID

+----------------+
~

DCBDRV

Disk drive #

+----------------+
"

DCBCMD

" Command

DCBSTA

10 Status

+----------------+

+----------------+
"
+"

DCBBUF
DCBBUF

LO"
-+ 10 Buffer address
HI',

+----------------+
"

DC BTO
DCBTO

LO"
-+ Time out count
HI"

+------- ---------+

31

DCBCNT

LO

+-

'1

-+
DCBCNT

10 Buffer length

HI'I

+----------------+
'1
DCBSEC LO'I

+-+
DCBSEC HI'I
+----------------+

10 Sector number

'1

Instead of a handler-ID there is a BUSID (DCBSBI)


to
address
a
particular
diskdrive via the Serial-Bus of the ATARI.
- Also a logical drivenumber (DCBDRV)
- A commandbyte (DCUCMD), which is similar
to an IOCB, and 5 commands for sector-IO,
which will be described later.
- The statusbyte for error detection after,
and data-direction previous to execution
of the command ($80 is write, $40 is read).
The DCBBUF locations (L and H) to point
to the databuffer.
DCBTO
(L & H)
is a
special
word
containing the maximum time for executing
a command, so called timeout.
- DCBCNT (L & H) is a device specific word
which contains the sector length (128 for
the 810-drive or 256 for
the
double
density drives).
DCBSEC
(L & H)
contains the sector
number to do 10 on.
The DCB-commands
Prior to executing any DCB-command,
the
following DCB-entries must be set.
DCBSBI has to contain the bus-ID of the
drive:
DRIVE
DRIVE
DRIVE
DRIVE
32

1
2
3
4

=
=
=
=

$31
$32
$33
$34

=
=
=
=

'1
'2

'3
'4

DCBDRV has to contain the logical drive


number (1.. 4) .
DCBTO the timeout (normally 15 lowbyte=$OF
highbyte=$OO).

- READ SECTOR reads


by the user

one

sector

specified

DCBCMD = $52 = 'R


DCBBUF = points to databuffer
DCBCNT = contains sector length
DCBSEC = number of sector to read
After execution:
DCBSTAT = result of READ SECTOR-operation
PUT SECTOR writes one sector specified
by the user without verify.
DCBCMD = $50 = 'p
DCBBUF = points to databuffer
DCBSEC = number of sector to write
After execution:
DcnSTAT = result of PUT SECTOR-operation
- WRITE SECTOR writes one sector specified
by the user with automatic verify.
DCBCMD = $57 = 'w
Further like PUT SECTOR.
STATUS REQUEST obtains the status from
the specified drive.

DCBCMD = $53 =

's
33

After execution:
REQUESTSTATUS
DCBSTAT = result
of
operation
The
drive outputs four bytes and the
controller puts them to $02EA (DVSTAT).
- FORMAT formats the specified disk.
DCBCMD = $21 = '!
DCBTO = has to be larger than 15 due to
more time taken by the FORMAT-command. You
can ignore the error,
but this will be
risky.
After execution:
DCBSTAT = result of the FORMAT-operation.
How is the disk controller invoked?
Because the disk controller is resident,
this is a simple process. You don't have
to load DOS,
nor anything similar. You
just have to call the sro (Serial ro
$E459)
instead of the cro. Therefore, you
can see that it is quite easy to link the
Diskcontroller with machine language.
How to write a sector to disk
The first program writes a specified
sector from a buffer to diskdrive# 1.
There are a few conventions to call this
program as subroutine. The user has to put
the
buffer
address
into the pointer
locations labelled BUFFER and the sector
number into the locations labelled SECTR.
The program also needs a RETRY-location,
to serve as a counter so the program is
able to determine how often it will retry
the ro.
34

The
next
paragraph
describes
the
subroutine.
At first we built the DCB,
special we
move a $80 (BIT 3 the write bit is set) to
DCBSTA and we retry the 10 4 times.
SIO
does,
as well as CIO, load the STATUS into
the Y-register so you only have to check
the
signflag
again .
After an error
occurence we decrement the retry value and
set DCBSTA again, then try again.
By using this program, you only have to
look at the signflag after returning for
error detection (signflag TRUE means error,
otherwise success).
The second program
reads
a
sector
instead of writing it. The only two bytes
which are different are the DCBCMD and the
DCBSTA ($40 for read).
**************************************

*
*
WRITE
A
SECTOR
TO
DISK
*
*
****************************************
SECTR
BUFFER
RETRY

EQU $80.1
EQU $82.3
EQU $84

DCBSBI
DCBDRV
DCBCMD
DCBSTA
DCBBUF
DCBTO
DCBCNT
DCBSEC

EQU
EQU
EQU
EQU
EQU
EQU
EQU
EQU

SIO

EQU $E459

$0300
$0301
$0302
$0303
$0304
$0306
$0308
$030A

ORG $A800
35

A800:
A802:
A805:
A807:
A80A:
A80C:
A80F:
A811:
A814:
A816:
A819:
A81B:
A81E:
A820:
A823 :
A825 :
A828:
A82A:
A82D:
A82F:
A831:
A833:
A836:
A838:
A83B:
A83E:
A840:
A842:
A844:
A846:
A849:
A84C:
A84F:

A582
WRITSECT LDA BUFFER
8D0403
STA DCBBUF
A583
LDA BUFFER+l
8D0503
STA DCBBUF+l
A580
LDA SECTR
8DOA03
STA DCBSEC
A581
LDA SECTR+l
8DOB03
STA DCBSEC+l
A957
LDA 'w
REPLACE "w"
8D0203
STA DCBCMD BY A "p" IF
A980
LDA #$80
YOU WANT IT
8D0303
STA DCBSTA
FAST
A931
LDA ' 1
8DOO03
STA DCBSBI
A901
LDA #1
8DOI03
STA DCBDRV
A90F
LDA #15
8D0603
STA DCBTO
A904
LDA #4
8584
STA RETRY
A980
LDA #128
8D0803
STA DCBCNT
A900
LDA #0
8D0903
STA DCBCNT+l
2059E4 JMPSIO
JSR SIO
100C
BPL WRITEND
C684
DEC RETRY
3008
BMI WRITEND
A280
LDX #$80
8E0303
STX DCBSTA
4C3BA8
JMP JMPSIO
AC0303 WRITEND LDY DCBSTA
60
RTS

PHYSICAL ENDADDRESS: $A850

***

NO WARNINGS

SECTR
RETRY
DCBDRV
DCBSTA
36

$80
$84
$0301
$0303

BUFFER
DCBSBI
DCBCMD
DCBBUF

$82
$0300
$0302
$0304

DCBTO
DCBSEC
WRITSECT
WRITEND

$0306
$030A
$A800
$A84C

UNUSED

DCBCNT
SIO
JMPSIO

$0308
$E459
$A83B

**************************************

*
*
*

READ A SECTOR FROM DISK

*
*

**************************************
SECTR
BUFFER
RETRY

EQU $80.1
EQU $82 . 3
EQU $84

DCBSBI
DCBDRV
DCBCMD
DCBSTA
DCBBUF
DCBTO
DCBCNT
DCBSEC

EQU
EQU
EQU
EQU
EQU
EQU
EQU
EQU

SIO

EQU $E459

$0300
$0301
$0302
$0303
$0304
$0306
$0308
$030A

ORG $A800
A800:
A802:
A805:
A807 :
A80A:
A80C:
A80F:
A811:
A814:
A816:
A819:
A81B:
A81E:
A820 :

A582
READSECT LDA BUFFER
8D0403
STA DCBBUF
LDA BUFFER+1
A583
STA DCBBUF+1
8D0503
LDA SECTR
A580
STA DCBSEC
8DOA03
LDA SECTR+1
A581
STA DCBSEC+1
8DOB03
LDA 'R
A952
STA DCBCMD
8D0203
LDA #$40
A940
STA DCBSTA
8D0303
LDA ' 1
A931
STA DCBSBI
8DOO03
37

AS23:
AS25:
AS2S:
AS2A:
AS2D:
AS2F:
AS31:
AS33:
AS36:
AS3S:
AS3B:
AS3E:
AS40:
AS42:
AS44:
AS46:
AS49:
A84C:
A84F:

A901
SDOI03
A90F
SD0603
A904
S5 S4
A9S0
SDOS03
A900
SD0903
2059E4 JMPSIO
100C
C6S4
300S
A240
SE0303
4C3BAS
AC0303 READEND
60

LDA
STA
LDA
STA
LDA
STA
LDA
STA
LDA
STA
JSR
BPL
DEC
BMI
LDX
STX
JMP
LDY
RTS

#1
DCBDRV
#15
DCBTO
#4
RETRY
#128
DCBCNT
#0
DCBCNT+l
SIO
READEND
RETRY
READ END
#$40
DCBSTA
JMPSIO
DCBSTA

PHYSICAL ENDADDRESS: $AS50

***

NO WARNINGS

SECTR
RETRY
DCBDRV
DCBSTA

DCBTO
DCBSEC
READSECT
READ END

38

$80
$84
$0301
$0303

$0306
$030A
$A800
$A84C

BUFFER
DCBSBI
DCBCMD
DCBBUF

UNUSED

$82
$0300
$0302
$0304

DCBCNT
SIO
JMPSIO

$030S
$E459
$A83B

HOWTOMAKE
ABOOTABLE
PROCRAM
CHAPTER 5
What is a bootable program ?
A bootable program is a program which will
be automatically loaded at powering up the
ATARI,
and directly after loading be
executed.
A bootable program needs a header with
specific information about the program,
such as the length and the start address.
The header of a bootable program looks
like the following scheme :

+----------------+
"

unused

"

+----------------+

first byte

" # of 128 bytes "

+----- -- ------ - --+


~

store

address

+----------------+
" ini tialization "
+~

-+

address

sixth byte

+------- - --------+
~
~
~

boot
continuation
code

~
~
~

and should
- The first byte is unused,
equal zero.
The second byte contains the length of
in records
(128
bytes),
the program,
(rounded up).
The next word contains
storethe
39

address of the program.


contains
the
The
last
word
of
the program.
initialization-address
This vector will be transferred to the
CASINI-vector ($02.3).
After these 6 bytes there has to be the
boot continuation code. This
is a short
program,
the as will jump to directly
after loading. This program can continue
the boot process (multistage boot) or stop
the cassette by the following sequence :
LDA #$3C
STA PACTL i$D302
The program then allows the DOSVEC ($OA. B)
to point to the start address of the
program. It is also possible, to store in
MEMLO ($02E7. 8),
the first unused memory
address. The continuation code must return
to the as with c=o (Carry clear). Now as
jumps via DOSVEC to
the
applicationprogram.
So far we know what a bootable cassette
looks like, but how do we create such a
bootable tape?
If
there is a program, we only have to put
the header in front of
it
(including the
continuation
code)
and to save it as
normal data on the tape. We can use tile
later
described
program to write the
contents of a buffer on the tape or the
boot generator.
If the program is saved, we can put the
tape in the recorder,
press the yellow
START-key,
power on the ATARI and press
RETURN. Now the program on the tape will
be booted.
The next listing shows us the general
outline of a bootable program.
40

**************************************

*
*
GENERAL OUTLINE
*
*
*
*
OF AN
*
*
*
*
BOOTABLE PROGRAM
*
*
****************************************
*

PROGRAM START
ORG $A800

THE BOOTH EADER

PST

DFB
DFW
DFW
DFW

0
SHOULD BE 0
PND-PST+127/128 # OF RECORDS
PST
STORE ADDRESS
INIT
INITALIZATION ADDRESS

THE BOOT CONTINUATION CODE


LOA *$3C
STA PACTL

STOP CASSETTE MOTOR

LOA
STA
LOA
STA

#PND:L
MEMLO
#PND:H
MEMLO+l

SET MEMLO TO END OF PROGRAM

LOA
STA
LOA
STA

#RESTART:L
DOSVEC
#RESTART:H
DOSVEC+l

SET RESTART VECTOR IN DOSVECTOR

CLC
RTS

RETURN WITH C=O (SUCCESSFULL BOOT)

INITIALIZATION ADDRESS

INIT

(OR AN OTHER)

RTS IS THE MINIMUM PROGRAM

RTS

THE MAIN PROGRAM

RESTAHT

EQU

* THE MAIN PROGRAM ENDS HERE


PND

EQU

NEXT FREE LOCATION

41

How to make a bootable disk


Making a bootable disk is in fact the same
as for the cassette. The only exceptions
are as follows.
The program (including the header) must be
stored up from sector one. The boot continuation code doesn't need to switch off
anything such as the cassette motor.
How to create a bootable disk ?
This is only a bit more complicated than
the cassette version. We need our writesector program we described earlier. Then
we have to write,
sector by sector,
to
disk.
You can also make a bootable
cassette first and then copy it directly
to disk with the later discussed program.

42

HOWTOMAKE
ABOOTABLE
CARTRIDGE
CHAPTER 6
Preparing the program.
Most of the games and some other programs
written in machine language are stored in
a cartridge.
Booting a program, the OS
recognizes the cartridge and starts the
program.
What do you have to do when you want to
make a bootable cartridge
of
your own
program?
As- an example we will make a cartridge
with a program for testing the memory. The
bit pattern
10101010 = $AA
01010101 = $55
00000000 = $00
11111111 = $FF
is
written
in
every memory location
starting above the hardware
stack
at
address $200. First the content is saved,
then the bit pattern is written into and
read from the memory location. If there is
any difference in writing and reading the
program prints an error message : ERROR IN
<ADR).
Then the program waits in an
endless loop.
If the error message is
ERROR IN AOOO, the RAM is ok because $AOOO
is the first address of the ROM in the
left cartridge.
43

The address range for the left cartridge


ranges from $AOOO to $BFFF and $8000 to
$9FFF for the right cartridge. As starting
address for our memory test program we
choose $BFOO. This is the last page of the
left cartridge. The software for the EPRON
burner is also stored in a cartridge.
Therefore the object code generated by the
assembler is stored at $9000.
Like a bootable program the cartridge has
a header.
The following scheme shows the
outline of this cartridge header.
$BFFA or
+----------------+
$9FFA
I
cartridge
I

+-+
I start address I
+----------------+
I
00
I
+----------------+
I option byte
I
+----------------+

I
cartridge
I
+-+
I in it address
I

+----------------+

$BFFF or
$9FFF

The header for the right cartridge starts


at $9FFA, for the left cartridge (the more
important for us) at $BFFA.
- The first two bytes contain the start
address of the cartridge.
- The third byte is the cartridge-ID. It
shows the OS that a cartridge has been
inserted. It must be 00.
The fourth byte is the option-byte. This
byte has the following options:
BIT-O = 0 don't allow diskboot
1 allow diskboot
BIT 2 = 0 only initialize the
cartridge
1 initialize and start
the cartridge
44

BIT 7

=0

Cartridge is not a diagnostic


cartridge
1 Cartridge is a diagnostic
cartridge
before OS is initialized
the cartridge takes control

- The last two bytes contain the cartridge


initialization address.
The initialization address is the starting
address of a program
part
which
is
executed in advance of the main program.
If there is no such a program this address
must be the address of an RTS instruction.
In our example the low byte
of
the
starting
address
$BFOO
is stored in
location $BFFA,
the high byte in location
$BFFB.
The option byte in location $BFFD is 04.
The
program
in
the
cartridge
is
initialized and started, but there is no
disk boot.
The initializing address is
$BF~3,
an RTS instruction within the
program.
After assembling and storing the object
code the burning of an EPROM can start.

45

OF A CARTRIDGE

*
*

RTS

THE CARTRIDGE ID SHOULD BE 0


THE OPTION BYTE
THE CARTRIDGE INITIALIZATION ADDRESS

DFW
DFB
DFB
DFW

RESTART
0
OPTIONS
INIT

$9FFA FOR RIGHT CARTTRIDGE

RTS IS THE SHORTEST INITIALIZATION

ORG $BFFA

THE CARTRIDGE HEADER

EQU

THE MAIN PROGRAM

REST ART

$8000 FOR RIGHT CARTRIDGE

THE INITIALIZATION ADDRESS

ORG $AOOO

THE CARTRIDGE START (LEFT CARTR.)

INIT

**************************************

**************************************
*
*
GENERAL OUTLINE
*
*

Sample program for a cartridge: MEMORY TEST

*
AUXE
TESl'
Ou.rcH

MEMORY TESl'
EPZ $FE
EPZ $FO
mU $F6A4
ORG $BFOO,$9000

BFOO:
BF02:
BF05:
BF08:
BFOB:
BFOE:
BFll:
BFl3 :
BF15:
BF17:
BF19:
BFIB:
BFID:
BFIF:
BF21:
BF24:
BF26:
BF29:
BF2B:
BF2E:
BF30:
BF33:
BF35:
BF37 :
BF39:
BF3B:
BF3D:
BF3E:

A97D
Sl'ART
20A4F6
2064BF
4D454D
4F5259
205445
53D4
AOOO
84FO
A902
85Fl
BIFO
TESl'l
85F2
A9AA
2059BF
A955
2059BF
A900
2059BF
A9FF
2059BF
ASF2
91FO
E6FO
DOEO
E6Fl
18
90DB

BF40: 2064BF FIN


BF43: 455252

LDA #$7D
JSR OOTCH
JSR MESS
AS( \MErvlORY TESl'\

LDY #00
SI'Y. TESI'
LDA #02
STA TESl'+l
LDA (TEST},Y
STA TESl'+2
LDA #$AA
JSR TST
LDA #$55
JSR TST
LDA #00
JSR TST
LDA #$FF
JSR TST
LDA TESI'+2
STA (TESl'},Y
INC TESl'
BNE TESl'l
INC TESl'+l
CLC

BCC TESl'l
JSR HESS
ABC \ERROR IN \
47

BF46:
BF49:
BF4C:
BF4E:
BFSl:
BFS3:
BFS6:

4FS220
494EAO
ASFI
2086BF
ASFO
2086BF
4CS6BF FINI

LDA
JSR
LDA
JSR
JMP

BFS9:
BF5B:
BFSD:
BF5F:
BF61:
BF63:

85F3
9lFO
BIFO
CSF3
DODD
60

STA TEST+3
STA (TEST),Y
LOA (TEST), Y
Q1P'l'EST+3
BNE FIN
RTS

BF64:
BF6S:
BF67:
BF68:
BF6A:
BF6C:
BF6E:
BF70:
BF72:
BF74:
BF76:
BF79:
BF7B:
BF7D:
BF7F:
BF81:
BF82:
BF84:
BF8S.:

68
NESS
85FE
68
8SFF
A200
E6FE MSI
D002
E6FF
AlFE
297F
20A4F6
A200
AlFE
lOrn
ASFF
48
ASFE
48
60

PIA
S'l'A AUXE
PLA
STA AUXE+I
LOX #0
INC AUXE
BNE *+4
INC AUXE+l
LDA (AUXE,X)
AND #$7F
JSR CUTCH
LOX #0
LOA (AUXE,X)
BPL NSI
LOA AUXE+l
PHA
LOAAUXE
PHA
RTS

BF86:
BF87:
BF88:
BF89:
BF8A:
BF8B:
BF8E:
BF8F:

48
PRrBYT
4A
4A
4A
4A
2091BF
68
290F

PHA
LSR
LSR
LSR
LSR
JSR HEX21
PIA
AND #$OF

48

TST

FRI'S

TEST+l
PRTBYT
TEST
PRTBYT
FINI

BF91:
BF93:
BF9S:
BF97:
BF99:
BF9A:
BF9C:

C90A
HEX21
B004
0930
D003
18
BUCHST
6937
4CA4F6 HEXOur

BFFA:
BFFC:
BFFD:
BFFE:

OOBF
00
04
63BF

#9+1
BCS BUCHST

OW

ORA '0

BNE HEXCXJ1'
CLC

AOC

'A-I0

JMP CUTCfI

ORG $BFFA,$90FA
Df1Il STAR'!'

DFB 00
DFB 04
Df1Il FRTS

PHYSICAL ENDADDRESS: $9100

***

00 vll\P,Nlt.GS

49

EPROM-BURNER
FOR THE
ATAR1800/400
With this epranburner yeo can burn your am EPl<U1S. It
is possible to burn four different types.
The four
types dre ~le 2532(4k), Ule 2732(4k),the 2516(2k) and
the 2716 (2k). The burner uses ~le CJame ports 1 ,2 and 3.
1) 'ilIE lIA:RIJ.vAHE.

The circuit of ~le epranburner is sho.m in FIG. l.'i'he


data for the burner is exchanged via CJame port 1 and 2.
The control si(jnals are provided l.Jy yame port 3.'i'he
addl-esses are de ceded by bvo 7 bit counters 4024. The
physical aJdresses for ~1e EPRCl'lS are always in ~1e
range of 0000 to 07FF for 2k and 0000 to OFFF for 4k.
This ceonter is reset by a signal, de ceded fran PEO and
PEl via U1e 7415139. PB2 is used to decide if a 2532,
or a 271G has to be burned.
Not all signals for the different types of EPRa1S are
switdled by softwdre.A three lJOle, double threw S'vlitch
is used to switch beb.een the different types. The
softVlare tells you when you have to set the switch into
the correct position. For oorning, you need a burniny
voltage of 25 Volts. This voltage is converted fran the
5 Volts of the garne port to 2U Volt by ~le OCOC
converter OCP 528. This voltage is limited to 25 Volts
by two Zener diCXies in serie ( ZIJ 24 and ZN 1 ). 'i'hree
universal NPN transistors are used to switch iJebJecn
10.1 level voltages and the high level of the burning
voltage.

50

PBl

PBO

PB2

PB 3

v~

GND

lA
16

101

~
~

IC1

e2

-U-~

12

1/640491CS

'>

14

15

GND.

vee

18

19

22

23

Ii

IC2

-..!2
04 16

L
05

GN~ ~

I~

...

1C3

t:!

as

.... Q4 6

vee

-~ 05 5

7
14
0 1 12
IN
11
2 1 RES 02
039

2 x 1/64049 ICS

AO
Al
A2
A3
A4
A5
A6

A7
AB
A9
AlO
All

-'"
r--

:;!

l"N

..,

All

III
N

l"N

Vpp

21

NIPGMt N/NPP.

aO ~l.Jl l l
01

20

Q2 ~

.cr

All

Al0

18

19

A ID
04

&

Sl

03 ~
05
M

!::!.

as
07

r--

~
N
M

l!l ~PGM I
v pp

3 x BC108A

vpp

Ala

OE

CE

):i

L.O

01

I\.)

switch

the

mountmg

"

ZD2

~ ~...c:=>-..

R4

T2

R2

R1

VPP
PGMI

All : -

R1

Fig. 2: Parts Layout

C3

,U- of

I..JR..

21
-- -- -- I . 20 4
PGM

0
o15mVf 0
3
0 GND VCC 7
0

l.

I.

I.

___ -,.

Area for

ZD1

.;

T3

~. ~:~;~~J 2:42~~D 2:i'!] ~!~:::]d1


--:;;;~~S~c";;T: ~2.?_:~~S~
. 1!. . .~. ...].-Cb

co

R5
..c=>-e

of game port 3

G32 means pin 2

Male side

~oooo1
o 0 0 0

AT AR I Game connector

C
""

..::'"

0-"

,.....
v .

::;;

c=:

- '.

Co"'

(D

~~

.,...,

I'-:

Figure 3

A 11

20

Vpp

Fig. 4: Rear side of the 3P2T switch


53

FIG.2 sha.vs the parts layou t. I t is recanended to use


sockets for the integrated circuits. Attention !.The
cOQPOnent side for tile int~Jrated circuits is the side
sllOnliny the text EPHQ'lBURNER, rut ti1e socket for the
EPRCt1 is rrounted ~pa;ite to this carponent side. ( see
FIG.
3) The picture of the IJurner is sbam in FIG. 3.
After asseJablinlj the board,
the connections to the
A'I'ARI are rrade. Use tilree female plu(js and a flatlland
cable. Last the tilree pole double thra.v swi tcll is
assembled.
'I'he wiring of the switch and tile connection
to the board is shO'm in FIG. 4.
3) '!HE SOF'IWAllli

The ~oftwd.re for ti1e burner is canpletely written in


maclllne code~ It canes on a bootable diskette. '1'0 load
the program, Insert the disk and REMOVE ALL CAR'I'IlX:ES.
Turn on the disk drive and the A'l'ARI. After a short
manent, yoo Hill see the first rnenue:

Yoo are asked what type of EPHC1-1 you want to burn. After
typing the apprq)riate cllaracter, you get the message
to set the switch to the correct position and insert
the EPHC1-1. This is sila.vn in the foll<k/in<J example:

54

Then, pressir1tJ the slJace Oar, you see the main li1enue:

First 'vIe \lant to R)EAD an EPRa1. Type R and then the


addresses fo'RQ'l and 'ID . TIle physical addresses of the
EPRal are always in range bet'vleen 0000 and OFFF. Ycu
can read the whole EPR(1'l or only a part of it. Next yoo
have to type the address IN'lU \lhich the content of the
EPRCX'I is read. All adresses which are not used by the
system or the burner sofblare ( A8UO to AFFF ) are
accessible. By typing Y after the question OK (YIN),
the program is loaded. There is a very important key,
the X key. 'Illis key cancels the input and leads back
into the rmin rrenue. An example of reading an EPRC11 is
sham in the next figure:

55

To verify that the content of the RAM is idetical to


the content of the EPRCl1, type V. After specifing the
adresses for the EPRC11 and the HAM and typing Y,
the
contents are compared. If there are any differences,
ycu get an error rressage, such as the follONing:

56

Yoo may then make a ITEmOry dWT-P. Type M for M)EMORY,


either R
for R)AM or E for E)PllOO , and the address
range. There is a slight difference in memory dumps.
With the mer.lory dump of RAN, the bytes are printed, if
it is possiole, as ASCII characters.
Burning an EPRa1 begins by testing as to whether or not
the EPRa1 is erased in the address range you want to
burn. 'IYpe E and the address range. You Hill get the
message EPRQ'1 ERASED when the assigned address range
has been erased, or the message EP.Ra1 NaI' ERASED IN
CELL NNN.
For writing the EPRCJvl, type W, ti1e address range in RAM,
and the starting address in EP.Ra1. After hitting Y, yoo
have to wait two minutes for burning 2k and four
minutes for burning 4k. Don't get angry,
the program
will stq>.
After burning ooe cell the prCXJram does an
automatic verify. If ti1ere is a difference you recieve
ti1e error rrEssage EPRCJvl NOT PRCX;RAMHED IN CELL NNN and
the burning steps. Otherwise if all goes
Hell ti1e
r;lessage EPRa1 PR<XRAl'lHED is printed.
For d1anging the type of EPRG1 you want to burn, type S.
The first rrenue is sho.vn and you can begin a new
burning procedure.
4) PARI'S LIST.

ICl
IC2,IC3
IC4
IC5
Tl,T2,T3

74I.S139
4024
4016
4049
UNIVERSAL NPN TRANSIS'IDH
30V,O.3W (2N 3390 % 2N3399

Rl

470 K
100 K
33 K
1 V
24 V
OCP528

R2,R3
R4,R5
Zl
Z2
I'll

Cl,C2

RES IS'IDH
RESIS'IDR
RES IS'IDR
ZENER DIODE
ZENER DIODE
OCOC CONVERI'ER
ELPAC rovER SYS'!'F.lI1S
100 NF CAPACITOR

57

C3

Sl
1
3
2
3

10 MF

rAN'l'AL CAPACI'lDR

3P2r

SVolITCH
TEX'IU)L S<X:KE'l.'
14 PIN Ie S<.X:KET
16 PIN IC S<XKET
FflvlALE PLUGS, ATARI CA!"ll.: CONNEC'IOHS
24 PW

5) S'l'EP BY S'EP ASS E1-'tBLING


I.
Insert and solder sockets.
Cmlponent
side sho.vs the text EPRavII3URlJER.
*
Insert and solder resistors.
2.
Insert and solder Zener dicrles.
3.
'lhe
anodeS are clooest to the to the
*
transistors.
*
Insert and solder transistors.
4.
Insert and solder capacitors.
5.
'lhe
+ pole of the tan tal is marked.
*
Hoont the OCIX converter rrodule.
6.
'I\.lrn the board to the soldering side.
7.
Insert fra:1 this side the TEX'.LmL socket.
8.
The knob siloold be in the
*
ulJper right corner. Solder the socket.
*
9.
Hake the connections on the s\oJitch. (FIG.4)
Connect switch and bexird via
*
a 7 lead flatband cable.
*
10.
Connect the plugs to the board. (FIG.5)
Insert tl1e int~Jrated circuits. (fIG.2)
II.
'lurn off the ATARI. Insert tile plugs.
12.
Insert tl1e diskette and turn on the A'l'ARI.
*

58

HEXDUMP of the EPROM BURNER software

ABOO
A808
A810
A818
A820
A828
A830
AB38
A840
A848
AB50
AB58
A860
AB68
A870
AB78
A880
A888
A890
A898
A8AO
A8A8
A8BO
A8B8
A8CO
A8C8
A8DO
A8D8
A8EO
A8E8
A8FO
A8F8
A900
A908
A910
A918
A920
A928
A930
A938
A940

2076A9204CA82078
A8006885EE6885EF
A200E6EED002E6EF
AIEE297F20A4F6A2
OOAIEEIOEDA5EF48
A5EE4860A5FD2940
F006A5FE090lD004
A5FE290E8DOID348
68ADOOD348A5FE8D
OlD36860A90085FO
85Fl85F8A9308D03
D3A90F8DOID385F5
A9348D03D3A9FF85
F4A9B085F9A9028D
OlD360A99B4CA4F6
A97D20A4F6A90585
54A90A8555A90085
56200AA852294541
44204550524FCD20
73ABA90A8555200A
A857295249544520
4550524FCD2073A8
A90A8555200AA845
2950524F4D204552
415345C42073A8A9
OA8555200AA85629
4552494659205052
4F47524lCD2073A8
A90A8555200AA84D
29454D4F52592044
554DD02073ABA90D
8555200AA8522941
CD2073A8A90D8555
200AA8452950524F
CD2073A8A90A8555
200AA85329455420
4550524F4D205459
50C52073A82073A8
A90A8555200AA857
484154BA20FOAE48
20A4F668C952D003

v)

L( x

(@hEnhEo
"@fnPBfo
In)
$v"
@!nPm%oH
%nH'% ) @
pF% IAPD
% }NNASH
h-@SH% M
ASh'}@Ep
EqEx)OHC
S}OHASEu
)4MCS} E
t}OEy}BM
AS'} [L$v
} $v}EE
T}JEU)@E
V J(R}EA
D EPRmi
s () JEU J
(W}RITE
EPROf.1 s(
)JEU J(E
}PROH ER
ASED s ()
JEU J (V)
ERIFY PR
OGRAM s(
}JEU J(M
) EHORY D
UHP s () M
EU J(R}A
r1 s () MEU
J(E}PRO
M s () JEU
J(S}ET
EPROM TY
PE s ( s (
}JEU J(W
HAT: p.H
$vhIRPC
59

A948
A950
A958
A960
A968
A970
A978
A980
A988
A990
A998
A9AO
A9A8
A9BO
A9B8
A9CO
A9C8
A9DO
A9D8
A9EO
A9E8
A9FO
A9F8
AAOO
M08
AA10
AA18
M20
M28
AA30
AA38
M40
AA48
AA50
AA58
M60
M68
M70
AA78
AA80
AA88
AA90
AA98
60

4C30ACC957DOO34C
10ADC945DOO34C8B
ACC956DOO34C2DAF
C953DOO34C76A9C9
4DDOO34CFBADA9FD
20A4F66COAOOA97D
20A4F62073A8200A
A857484943482045
50524F4D20444F20
594F552057414E54
20544F204255524E
20BFA9088554A90A
8555200M8412920
323533B22073A8A9
OA8555200M84229
20323733B22073A8
A90A8555200M843
2920323731362C32
3531B62073A82073
A8A90A8555200AA8
57484154BA20FOAE
4820A4F66885FCC9
41D006A90085FDFO
12C942DOO6A98085
FD3008C943D078A9
C085FD2073A82073
A8200M853455420
5357495443482054
4F20504F53495449
4F4EAOA5FCC941DO
OA200M8323533B2
18901EC942DOOA20
OM8323733B21890
10C943D032200M8
323731362C323531
B62073A82073A8A9
OA8555200AA84E4F
5720494E53455254
204550524FCD20D7
AB208FAA4C03A8A9
FD20A4F64CEDA920
73A8A90A8555200A
A850524553532053

LO,IWPCL
P-IEPCLK
, IVPCL-/
ISPCLv)I
~1PCL {-)
$v1J@)
$v 5( J
(WHICH E
PROH DO
YOU WANT
TO BURN
?)HET)J
EU J(A)
2532 5()
JEU J(B)
2732 5(
)JEU J(C
) 2716,2
516 5 ( 5
() JEU J (
WHAT: p.
H $vhEII
APF)@E P
RIBPF)@E
OHICPx)
@E 5 ( 5
( J(SET
SWITCH T
o POSITI
ON %I lAP
J 01(2532
XP IBPJ
J(2732XP
PICP2 J(
2716,251
6 5( 5()
JEU J(NO
vI INSERT
EPROH W
+ O*LC ()
$vLm)
5 () JEU J
(PRESS S

MAO
MA8
AABO
MB8
AACO
MC8
AADO
AAD8
AAEO
ME8
AAFO
AAF8
ABOO
AB08
AB10
AB18
AB20
AB28
AB30
AB38
AB40
AB48
AB50
AB58
AB60
AB68
AB70
AB78
AB80
AB88
AB90
AB98
ABAO
ABA8
ABBO
ABB8
ABCO
ABC8
ABDO
ABD8
ABEO
ABE8
ABFO

50414345204241D2
20FOAE602073A8A9
OA8555200M84F4B
2028592F4EA920FO
AE4820A4F668C94E
F003A90060A90160
484A4A4A4A20DBAA
68290FC90ABOO409
30DOO31869374CA4
F6A90085F285F385
FEA90485FC20FOAE
48C99BFOO320A4F6
68C9303025C94710
21C93A3007C94130
191869090AOAOAOA
AOO42A26F226F388
DOF8A98085FEC6FC
DOCB60A9308D02D3
A9FF8DOOD3A9348D
02D360A9308D02D3
A9008DOOD3A9348D
02D3602073A820FD
AEA90A8555200M8
46524F4DBA20E9M
A5FE300DA5F120DO
MA5F020DOAA4C79
ABA5F285FOA5F385
F12073A8A90A8555
200M8544F2020BA
20E9MA5FE300DA5
F520DOMA5F420DO
M4CA4ABA5F285F4
A5F385F5A5FB302E
2073A82015AFA90A
8555200M8494E54
4FBA20E9AAA5FE30
ODA5F920DOAAA5F8
20DOM4CD6ABA5F2
85F8A5F385F960A9
0185FEA90385FCA9
0985FFA5FD1021A9
041865FE85FEA904
1865FC85FCA90418

PACE, BAR
p. sO
JEU J(OK

(yiN) P

.H $vhIN
pC) @") A'
HJJJJ [*
h)OIJODI
OPCXi7L$
v)@ErEsE
) DE I p.
HI[pC $v
hIOO%IGP
!I:OGIAO
YXiIJJJJ
D*&r&sH
Px)@E FI
PK') OMBS
) M@S)4M
BS") Of.ms
)@M@S)4M
BS" s (
.) JEU J (
FROH: i*
% Of.l%q P
*%p P*Ly
+%rEp%sE
q s () JEU
J(TO
i*% OH%
u p*%t P
*L$+%rEt
%sEu%{O.
s( u/)J
EU J(INT
0: i*% 0
M%y P*%x
P*LV+%r
Ex%sEy" )
AE ) CE I)
IE % P 1)
DXe E )D
Xe I E I) DX
61

ABF8
ACOO
AC08
ACIO
ACI8
AC20
AC28
AC30
AC38
AC40
AC48
AC50
AC58
AC60
AC68
AC70
AC7S
ACSO
AC88
AC90
AC9S
ACAO
ACA8
ACBO
ACBS
ACCO
ACCS
ACDO
ACDS
ACEO
ACE8
ACFO
ACF8
ADOO
AD08
ADIO
AD18
AD20
AD28
AD30
AD38
AD40
AD48

62

65FF85FFA5FD2940
FOO6A5FE290F85FE
60A5F085F2A5FI85
F3A5F2DOO2A5F3FO
I6A5FC8DOID3A5FE
8DOID3C6F2A5F2C9
FFDOE6C6F310E260
A98085FAA90085FB
203BAB204BAB20AC
AADOF820D7AB2009
ACAOOO202CA89IF8
A5FIC5F59004A5FO
C5F4F019E6FODOO2
E6FIE6F8DOO2E6F9
A5FC8DOID3A5FE8D
OID3I890D42073A8
A90A8555200AAS4C
4F4I4445C420SFAA
4C03A8A98085FBS5
FA203BAB204BAB20
ACAADOF820D7AB20
09ACAOOO202CASC9
FFD039A5FIC5F590
04A5FOC5F4FOI3E6
FODOO2E6FIA5FC8D
OID3A5FE8DOID3IS
90D82073ASA90A85
55200AA845524I53
45C4208FAAA90085
FB4C03A82073A8A9
OA8555200AA84E4F
5420455241534544
20494EAOA5FI20DO
AAA5F020DOAA208F
AAA90085FB4C03A8
A90085FB85FA202B
AB204BAB20ACAADO
F820D7ABA5F885F2
A5F985F3201IACAO
OOBIF08DOOD320A9
ADA5FIC5F59004A5
FOC5F4FOI3E6FODO
02E6FIA5FC8DOID3

e E % )@
pF% )OE
%pEr%qE
s%rPB%sp
V%IMAS%
HASFr%rI
PfFsPb'
)@Ez)@E{
;+ K+ ,
*Px W+ I
, @ ,( Qx
%qEuPD%p
EtpYfpPB
f1fXPBfY
% MAS% fwl
ASXPT s(
)JEU J(L
OADED 0*
LC() @E{E
z ; + K+
,*Px vl+
I, @ ,(I
P9%qEuP
D%pEtpSf
pPBfq%lfwl
AS% MAS X
PX 5 () JE
U J(ERAS
ED O*)@E
{LC ( 5 ()
JEU J(NO
T ERASED
IN %q P
*%p p* 0
*)@E{LC(
)@E{Ez +
+ K+ ,*P
x W+%xEr
%yEs Q,
@lpltl@S )
-%qEuPD%
pEtpSfpP
Bfq%lfwlAS

AD50
AD58
AD60
AD68
AD70
AD78
AD80
AD88
AD90
AD98
ADAO
ADA8
ADBO
ADB8
ADCO
ADC8
ADDO
ADD8
ADEO
ADE8
ADFO
ADF8
AEOO
AE08
AEIO
AE18
AE20
AE28
AE30
AE38
AE40
AE48
AE50
AE58
AE60
AE68
AE70
AE78
AE80
AE88
AE90
AE98
AEAO

A5FE8DOlD3l890D7
2073A8A90A855520
OAA850524F475241
4D4D45C4208FAA4C
03A82073A8A90A85
55200AA843454C4C
AOA5F120DOAAA5FO
20DOAA200AA8204E
4F542050524F4752
4l4D4D45C4208FAA
4C03A8AOFF88DOFD
60A5FF8DOlD320A3
AD290E8DOlD34820
DDAD68090l8DOlD3
A5FE8DOlD320A3AD
203BAB202CA8AOOO
DlFOFOO568684C72
AD202BAB60A9FF85
F6A90B85F7A5F6DO
02A5F7FOODC6F6A5
F6C9FFDOFOC6F7l8
90EB6020FOAE4820
A4F668C952DOO6A9
0085FAF012C945DO
06A98085FA3008A9
FD20A4F64CFBAD20
3BABA98085FB204B
AB20ACAADOF820D7
AB2037AE4C03A8A5
FAlOO32009ACA97D
20A4F6A90085F620
73A8A90085F7A5Fl
85F320DOAAA5F085
F220DOAA20DBAEA5
FAlOO620EOAE1890
04AOOOBlF020DOAA
E6F7A5F7C908FOOB
20DBAEE6FODOO2E6
FIDODCA90085F720
DBAEA5FA302lAOOO
BlF2C9209004C97A
9002A92E20A4F6E6
F7A5F7C908FOO8E6

% MASXPW
s () JEU
J(PROGRA
HMED O*L
C ( s () JE
U J(CELL
%q P*%p
P* J( N
OT PROGR
AMMED 0*
LC(
HP
'% HAS #
-)NMASH
]-hIAMAS
% HAS #; + ,( @
QppEhhLr
- ++') E
v)KEw%vP
B%wpMFv%
vI PpFwX
Pk' p.H
$vhIRPF)
@EzpRIEP
F) @EzOH)
$vL{;+)@E{ K
+ ,*Px W
+ 7.LC(%
zPC I,)
$v)@Ev
s () @Ew%q
Es P*%pE
r P* [.%
zPF '.XP
D @lp p*
fw%wIHpK
[ fpPBf
qP\)@Ew
[.%zO! @
lrI PDIz
PB). $vf
w%wIHpHf
63

AEA8
AEBO
AEB8
AECO
AEC8
AEDO
AED8
AEEO
AEE8
AEFO
AEF8
AFOO
AF08
AFIO
AFI8
AF20
AF28
AF30
AF38
AF40
AF48
AF50
AF58
AF60
AF68
AF70
AF78
AF80
AF88
AF90
AF98
AFAO
AFA8
AFBO
AFB8
AFCO
AFC8

F2DOO2E6F3DODBA5
FIC5F59004A5FOC5
F49006208FAA4C03
A8E6FOD002E6FIE6
F6A5F6C9I4FOO34C
47AE208FAA20D7AB
4C3EAEA9204CA4F6
202CA848A5FC8DOI
D3A5FE8DOID36860
20E2F6C958DOO568
684C03A860A90485
55A5FAI009200AA8
4550524FCD60200A
A8524ICD60A90485
55A5FAI007200AA8
524ICD60200AA845
50524FCD60A98085
FAA90085FB203BAB
204BAB20ACAADOF8
20D7AB2009ACAOOO
202CA848D1F8D03E
68A5F1C5F59004A5
FOC5F4F019E6FODO
02E6F1E6F8DOO2E6
F9A5FC8D01D3A5FE
8D01D31890D02073
A8A90A8555200AA8
56455259464945C4
208FAA4C03A82073
A8200AA844494646
4552454E54204259
544553A06820DOAA
20DBAEAOOOB1F820
DOAA200AA820494E
AOA5F920DOAAA5F8
20DOAA208FAA4C03
A800000000000000

rPBfsP[%
qEUPD%EE
tPF 0* C
(fpPBfqf
v%vITpCL
G. 0* W+
L>. ) L$v
, (H% I MA
S% MASh'
bvIXPEh
hLC ( ') DE
U%zPI J(
EPRm1' J
(RAM')DE
U%zPG J(
RAM' J(E
PROH')@E
z)@E{ i+
K+ ,*Px
W+ I, @
,(HQxP>
h%qEuPD%
pEtpYfpP
BfrfxPBf
y% MAS%
MASXPP s
()JEU J(
VERYFIED
O*LC( s
( J(DIFF
ERENT BY
TES h p*
[. @1x
p* J ( IN
%y P*%x
P* O*LC
(@@@@@@@

This hexdump has to be keyed in starting at address A800. This means


you need a 48K RAM AT AR I and a machine language monitor (ATMONA-',
Editor/Assembler cartridge from AT AR I or ATMAS-1). The program starts
at address A800 hex.

64

Using the EPROM board Kit from HOFACKER


After you burned an EPROM you certainly want to plug it into your ATAR I.
For this you need a pc-board. You can buy those boards from various vendors
(APEX, ELCOMP PUBLISHING) .
The following description shows how to use the EPROM board from
ELCOMP PUBLISHING, INC.

,.

.&a _____ .--1

With this versatile ROM module you can use


2716
2732
and
2532 type EPROMs.
To set the board for the specific EPROM, just solder their jumpers according
to the list shown below. Without any soldering you can use the module for
the 2532 right away.

If you use only one EPROM,


insert it into the right socket.
If you use two EPROMs, put the
one with the higher address into
the right socket.
The

modul

must

be

plugged

into the left slot of your ATAR I


computer with the parts directed
to the back of the computer .

65

EPROM I 2716 1 2732 1 2~16 I 2~32 1


-------1------1------1------1------1

I
I
I

I
1

IO
I

1
1
I

1
1

1
1
I

VI
I

-------I------I------I------I------1
III
I
I
2

I
I

101
I
I

-------I------I------l-----I------1
I

I
I

1
I

1
1

IO

-------1------1------1------1------1
III
I
I
4

III

-----------------------------------5
I I
I
,
'

0
V
'l
0 I 0 :
/
I
I
______ '- ____ -' ______ L ----l-----..1
I
I

v = means connected
o = means open

(jumper)

jumper
~wiring

area

+
+
66

IIIII

HOWTOADDOR
CHANCE A DEVICE
CHAPTER 7
If you want to add your own device, you
first have to write a handler/controller
(interface).
You have to submit the
handler on the following design decisions.
There has to be an OPEN routine, which
opens the device/file and returns with the
status of these operations stored in the Yregister of your 6502 .
- You also need a CLOSE routine,
which
unlinks the device and returns the status
as the OPEN- routine does.
- Further needed is a GETBYTE routine,
which receives the data from your device
and returns the data in the A-register and
the status in the Y-register.
If your
device is a write only device
(such as a
printer) you have to return with errorcode
146 (not implemented function)
in the Yregister.
A PUTBYTE routine, sends a byte (which
will be in the A-register) to your device,
and returns, as the other routines do, the
status. If your device is read only,
then
return the 146 errorcode.
67

A GET STATUS routine stores the status


of your device (max.
4 bytes) at DVSTAT
($02EA. D).
If the GET STATUS function is
not necessary, you have to leave the dummy
routine
with
146
in your Y-register
(error).
- A SPECIAL COMMAND routine is required,
if you need more commands than previous.
If not, return with Y=146.
OS will load the X-register with the IOCB
number times 16 so you are able to get
specific file information out of the user
IOCB.
These 6 entries have to be placed in a so
called handlertable. The vectors of these
have to be one less than the real address,
due to OS requirements.

+----------------+
~

OPEN vector-l

+----------------+
~

CLOSE vector-l

+----------------+
~GETBYTE

vector-l~

+----------------+
~PUTBYTE

vector-l~

+----------------+
~GETSTAT

vector-l~

+----------------+
~SPECIAL

vector-l~

+----------------+
Now you have to add the device to the
device table. A device entry needs 3 bytes.
The device name,
which is usually
a
character that indicates the device (first
character of the full devicename) is first.
Second,
a vector that points to the
devicehandler.
68

+----------------+
~

device name

+----------------+
'1 handler table

'1

address

+----------------+
If you only want to change the handler of
a device to your own handler, you only
have to scan the devicetable (started from
$03IA)
and let the vector point to your
handler table.
If it is a totally new device, you have to
add it,
at the next free position of the
device table (filled with zero).
The first listing shows you a handler for
a new printer device. Calling INITHAN will
install the new handler table. Now you can
connect
a
printer
with
centronics
interface at
gameport
3
&
4
(see
connection
scheme).
After each SYSTEM
RESET you have to initialize the device
again.
For program description see program
listing.
The second listing is a listing of an
inexpensive
(write only)
RS232 interface
for your ATARI. Just call INITHAN and the
new device will be added to the device
table. It is now possible to use it like
any other device.
The RS232 output is on
gameport 3 (see connection scheme).
It is
not our intention to describe detail the
working of the RS232 interface.
The
comments in the program should help a bit
though.

69

**************************************

*
*
*

CENTRONICS PARALLEL INTERFACE

**************************************

PRTENTRY EQU $031A


TRIG3
PACTL
PORTA

EQU $D013
EQU $D303
EQU $D301

EOL
CR
LF

EQU $9B
EQU $OD
EQU $OA

STANDARD ENTRY BY SYSTEM

ORG $0600,$A800
THE HANDLERTABLE

*
0600
0602
0604
0606
0608:
060A:

OF06
2306
2606
2906
2606
2606

HANDLTAB DFW
DFW
DFW
DFW
DFW
DFW

DFB 0,0,0,0

060C: 000000
060F: 00

*
0610 :
0612 :
0615:
0617 :
061A:
061C:
061F:
0621 :
0624 :
0626 :

OPEN
INIT
A930
8D03D3
A9FF
8D01D3
A934
8D03D3
A980
8D01D3
SUCCES
AD01
60

0627 : AD92
0629 : 60

70

OPEN-1
CLOSE-1
GETBYTE-1
PUTBYTE-1
STATUS-1
SPECIAL-1
FILL REST WITH ZERO

THE OPEN ROUTINE


EQU
LDA
STA
LDA
STA
LDA
STA
LDA
STA
LDY
RTS

#$30
PACTL
#$FF
PORTA
#$34
PACTL
#$ 80
$D301
#1

*
*

THE CLOSE DUMMY ROUTINE


ONLY RETURN SUCCESS IN Y (1)

CLOSE

EQU SUCCES

NOTIMPL

LDY #146
RTS

*
*
*

THE FOLLOWING COMMANDS ARE


NOT IMPLEMENTED SO GET ERROR
CODE 146

GETBYTE
STATUS
SPECIAL

EQU NOTIMPL
EQU NOTIMPL
EQU NOTIMPL

THE PUTBYTE ROUTINE

062A: C99B
062C: D007

PUTBYTE

*
062E:
0630:
0633 :
0635 :
0638 :
063A:

A90D
203B06
A90A
203B06 NOEOL
AOOI
60

AC13DO PARA OUT


DOFB
A080
0980
8DOID3
297F
8DOID3
8COID3
60

iCR
PARAOUT
#LF
PARAOUT
#l

LDY
BNE
LDY
ORA
STA
AND
STA
STY
RTS

TRIG3
PARAOUT
#%10000000
1%10000000
PORTA
#%01111111
PORTA
PORTA

WAIT IF BUSY
STROBE ON AND PUT DATA ON
BUS
STROBE OFF
CLEAR BUS

PUT NEW ADDRESS IN HANDLERVECTOR

*
0650:
0652 :
0655 :
0657 :
065A:

LDA
JSR
LDA
JSR
LDY
RTS

THE PARALLEL OUT

*
063B:
063E:
0640 :
0642:
0644:
0647 :
0649 :
064C:
064F:

CMP #EOL
BNE NOEOL
IF EOL THEN CRLF TO PRINTER

A900
INITHAN
8DIB03
A906
8DIC03
4CI006

LDA
STA
LDA
STA
JMP

#HANDLTAB:L
PRTENTRY+l
#HANDLTAB:H
PRTENTRY+2
OPEN

PHYSICAL ENDADDRESS: $A85D

*** NO WARNINGS
PRTENTRY
PACTL
EOL
LF
OPEN
SUCCES
NOTIMPL
STATUS
PUTBYTE
PARAOUT

$031A
$D303
$9B
$OA
$0610
$0624
$0627
$0627
$062A
$063B

TRIG3
PORTA
CR
HANDLTAB
INIT
CLOSE
GETBYTE
SPECIAL
NOEOL
INITHAN

$D013
$D30l
$OD
$0600
$0610
$0624
$0627
$0627
$0635
$0650

UNUSED

UNUSED

For more information about the parallel interface refer


page 106.

to

71

**************************************

RS232 SERIAL INTERFACE

*
*

*
*
*

**************************************

COUNT

EPZ $lF

RSENTRY

EQU $032C

PACTL
PORTA
NMIEN
DMACTL

EQU
EQU
EQU
EQU

EOL
CR
LF

EQU $9B
EQU SOD
EQU $OA

EQU 150
EQU 6
EQU 18

L
*L

NEXT FREE POSITION IN DEVICE


TABLE

$0303
$0301
$040E
$0400

110 AND 300 BAUD


300 BAUD
110 BAUD

ORG $0600, $A800


0600:
0602 :
0604 :
0606 :
0608:
060A:
060C:
06 OF:

OF06
HANDLTAB DFW OPEN-l
2906
DFW CLOSE-l
2C06
DFW GETBYTE-l
2F06
DFW PUTBYTE-l
2C06
DFW STATUS-l
2C06
DFW SPECIAL-l
000000
DFB 0,0,0,0
00

*
0610 :
0612:
0615 :
0617 :
061A:
061C:
061F:
0621 :
0624 :
0627 :
062A:
062C:

OPEN
A930
INIT
8D03D3
MOl
8DOI03
A934
8003D3
A900
8DOID3
208506
208506
ADOl
SUCCES
60

062D: AD92
062F: 60

THE OPEN ROUTINE


EQU
LDA
STA
LOA
STA
LDA
STA
LDA
STA
JSR
JSR
LOY
RTS

*
#$30
PACTL
#%00000001
PORTA
#$34
PACTL
#$00
PORTA
BITWAIT
BITWAIT
H

*
*

THE CLOSE ROUTINE IS A DUMMY


BUT Y=l (SUCCESSFULL CLOSE)

CLOSE

EQU SUCCES

NOTIMPL

LOY #146
RTS

THE FOLLOWING COMMANDS ARE


NOT IMPLEMENTED

72

JUST FILL WITH ZERO

RETURN WITH Y=146

GETBYTE
STATUS
SPECIAL

*
*
*

0630
0631
0633

0635:
0637:
063A:
063C:
063F:
0640:
0642:

48
C99B
D007

PUTBYTE

PHA
CMP #EOL
BNE NOEOL

IF EOL GIVE CRLF TO DEVICE

A90D
204306
A90A
204306 NOEOL
68
ADOl
60

*
0643: 49FF
SEROUT
0645: 8DA206

*
0648:
0649:
064B:
064E:

tCR
SEROUT
#LF
SEROUT
*1

SERIALOUT FIRST REVERSE BYTE


EOR U11111111
STA BUFFER
DISABLE INTERRUPTS

SEND STARTBIT
LDA #%00000001
STA PORTA
JSR BITWAIT

0651: A901
0653: 8DOID3
0656: 208506

SEND BYTE
LDY #8
STY COUNT

0659: AD08
065B: 841F

ADA206 SENDBYTE LDA BUFFER


8DOID3
STA PORTA
6A
ROR
8DA206
STA BUFFER
208506
JSR BITWAIT
C61F
DEC COUNT
DOEF
BNE SENDBYTE

*
066E:
0670:
0673:
0676:

LDA
JSR
LDA
JSR
PLA
LDY
RTS

SEI
LDA #0
STA NmEN
STA DMACTL

78
A900
8DOED4
8DOOD4

065D:
0660 :
0663:
0664:
0667:
066A:
066C:

EQU NOTIMPL
EQU NOTIMPL
EQU NOTIMPL
THE PUTBYTE COMMAND
DATA IN ACCU
STATUS IN Y (=1)

SEND TWO STOPBITS


LDA
STA
JSR
JSR

A900
8DOID3
208506
208506

#%00000000
PORTA
BITWAIT
BITWAIT

ENABLE INTERRUPTS

73

0679:
067B:
067E:
0680 :
0683 :
0684:

0685 :
0687 :
0689 :
068A:
068C:
068D:
06 8F:

LDA
STA
LDA
STA
CLI
RTS

A922
8DOOD4
A9FF
8DOED4
58
60

A296
A006
88
DOFD
CA
DOF8
60

*
*

THE BITTIME ROUTINE FOR


AN EXACT BAUDRATE

BITWAIT
LOOPK
LOOPL

LDX
LDY
DEY
BNE
DEX
BNE
RTS

*
*
0690:
0692 :
0695 :
0697 :
069A:
069C:
069F:

#$22
DMACTL
i$FF
NMIEN

#K
iL
LOOPL
LOOPK

ROUTINE FOR INSTALLING THE


RS232 HANDLER

A952
INITHAN
8D2C03
A900
8D2D03
A906
8D2E03
4CI006
BUFFER

LDA
STA
LDA
STA
LDA
STA
JMP

'R
RSENTRY
#HANDLTAB:L
RSENTRY+l
#HANDLTAB:H
RSENTRY+2
OPEN

DEVICE NAME

EQU

ONE BYTE BUFFER

PHYSICAL ENDADDRESS: $A8A2

*** NO WARNINGS
COUNT
PACTL
NMIEN
EOL
LF
L
OPEN
SUCCES
NOTIMPL
STATUS
PUTBYTE
SEROUT
BITWAIT
LOOPL
BUFFER

74

$IF
$D303
$D40E
$9B
$OA
$06
$0610
$062A
$062D
$062D
$0630
$0643
$0685
$0689
$06A2

RSENTRY
PORTA
DMACTL
CR
K
HANDLTAB
INIT
CLOSE
GETBYTE
SPECIAL
NOEOL
SENDBYTE
LOOPK
INITHAN

$032C
$D301
$D400
SOD
$96
$0600
$0610
$062A
$062D
$062D
$063C
$065D
$0687
$0690

UNUSED

UNUSED

A BOOTABLE
TAPE CENERATOR
PROCRAM
CHAPTER 8
The
following
program
allows you to
generate a bootable program on tape.
This
generator must be in memory at the same
time as the program.
After you have jumped to the generator,
a
dialogue will be started. First, the boot
generator asks for the address where your
program
is
stored
(physical address).
After you have entered start- and endaddress
(physical),
you will be asked to
enter the address where the program has to
be -stored during boot (logical address).
The generator further asks for the restart
address
(where OS must jump to, to start
your program).
There is no feature
to define your own
initialization address.
This address will
be generated automatically and points to a
single RTS.
Also given is the boot continuation code,
which will stop the cassette motor,
and
store the restart address into DOSVEC ($OA.
B)

So, you just have to put a cassette in


your recorder,
start the generator, and
the dialogue will be started.
The generator puts the boot information
header in front of your program, so there
have to be at least 31 free bytes in front
of the start address (physical & logical).

75

The
generator
program
will
not
be
explained here,
but after reading the
previous chapters you should have
the
knowledge to understand it. There are also
some helpfull comments in the program.

**************************************

*
*

BOOT-GENERATOR

*
*
*

**************************************

76

STOREADR
ENDADR
PROGLEN
JMPADR
EXPR
LOGSTORE
HEXCOUNT

EPZ
EPZ
EPZ
EPZ
EPZ
EPZ
EPZ

DOSVEC

EPZ $OA

MEMLO

EPZ $02E7

ICCOM
ICBAL
ICBAH
ICBLL
ICBLH
ICAXI
ICAX2

EQU
EQU
EQU
EQU
EQU
EQU
EQU

OPEN
PUTCHR
CLOSE

EQU $03
EQU SOB
EQU SOC

OPNOT

EQU 8

SCROUT
GETCHR
BELL
CIOV

EQU
EQU
EQU
EQU

$FO.l
$F2.3
$F4.5
$F6.7
$F8.9
$FA.B
$FC

$0342
$0344
$0345
$0348
$0349
$034A
S034B

$F6A4
$F6DD
$F90A
$E456

PACTL

EQU $D302

CLS
EOL
BST
CR

EQU
EQU
EQU
EQU

IOCBNUM

EQU 1

$7D
$9B
$lE
SOD

ORG $A800
A800: A97D
START
A802: 20A4F6

*
A805:
A808:
A80A:
A80D:
A810:
A813:
A816 :
A819:
A81C:
A81F:
A822 :

2000AA
ODOD
424F4F
544745
4E4552
41544F
522046
524F4D
20484F
464143
4B45D2

PRINT MESSAGE
JSR PRINT
DFB CR,CR
ASC \BOOTGENERATOR FROM
HOFACKER\

*
A825:
A828:
A82A:
A82D:
A830:
A833:
A836:
A839:
A83C:
A83E:

LDA #CLS
JSR SCROUT

2000AA
ODOD
53544F
524541
444452
455353
203AA4
2028AA
84FO
85Fl

GET
JSR
DFB
ASC

STOREADDREBS
PRINT
CR,CR
\STOREADDRESS :$\

JSR HEXIN
STY STOREADR
STA STOREADR+l

GET ENDADDRESS
77

A840:
A843:
A846:
A849:
A84C:
A84F:
A852:
A855:
A858 :
A85A:

2000AA
ODODOD
454E44
414444
524553
532020
203AA4
2028AA
84F2
85F3

JSR PRINT
DFB CR,CR,CR
ASC \ENDADDRESS

JSR HEXIN
STY ENDADR
STA ENDADR+1

*
A85C:
A85F:
A862:
A865:
A868:
A86B:
A86E:
A871:
A874:
A877:
A879:
A87C:
A87E:

2000AA
ODODOD
4C4F47
494341
4C2053
544F52
454144
445245
535320
3AA4
2028AA
84FA
85FB

78

2000AA
ODODOD
4A554D
504144
445245
535320
202020
3AA4
2028AA
84F6
85F7

GET LOGICAL STORE


JSR PRINT
DFB CR,CR,CR
ASC \LOGICAL STOREADDRESS :$\

JSR HEXIN
STY LOGS TORE
STA LOGSTORE+1

*
A880:
A883:
A886:
A889:
A88C:
A88F:
A892:
A895:
A897:
A89A:
A89C:

:$\

GET JUMP
JSR PRINT
DFB CR,CR,CR
ASC \JUMPADDRESS

JSR HEXIN
STY JMPADR
STA JMPADR+1

:$\

CALCULATE NEW STORE

AB9E: ASFO
ABAO: 3B

LDA STOREADR
SEC

ABA1:
ABA3:
ABAS:
ABA7:

SBC
STA
BCS
DEC

E920
BSFO
BOO2
C6F1
*

ABA9:
ABAB:
ABAC:
ABAE:
ABBO:
A8B2:

# (HEADEND-HEAD)+1
LOGS TORE
*+4
LOGSTORE+1

MOVE HEADER IN FRONT OF


PROGRAM

CALCULATE LENGTHE OF PROGR.


LDA
SEC
SBC
STA
LDA
SBe
STA
BCS
JMP

ASF2
38
ESFO
8SF4
ASF3
E5Fl
8SFS
BOO3
4CDAA9
*

ABC9: ASF4
A8CB: 18

LOGS TORE

JSR MOVEHEAD

ABB'4 : 20FSA9

A8B7:
ABB9:
ABBA:
ABBC:
ABBE:
ABeo:
ABC2:
ABC4:
A8C6:

CALCULATE LOGICAL STORE


LDA
SEC
SBC
STA
BCS
DEC

ASFA
38
E920
8SFA
BOO2
C6FB

# (HEADEND-HEAD)+1
STOREADR
*+4
STOREADR+1

ENDADR
STOREADR
PROGLEN
ENDADR+1
STOREADR+l
PROGLEN+1
*+5
ADRERR

ROUND UP TO 128 RECORDS


LDA PROGLEN
CLC
79

A8CC :.
A8CE:
A8DO:
A8D2:
A8D4:

ADC
AND
STA
BCC
INC

697F
2980
85F4
9002
E6F5
*

#127
#128
PROGLEN
*+4
PROGLEN+1

CALCULATE NUMBER OF
RECORDS

A8D6:
A8D7:
A8D9:
A8DA:
A8DC:

OA
A5F5
2A
AOOl
91FO

ASL
LDA PROGLEN+1
ROL
LDY #RECN-HEAD
STA (STOREADR) ,Y

A8DE:
A8EO:
A8E2:
A8E4:
A8E6:
A8E7 :

A002
A5FA
91FO
A5FB
C8
9lFO

LDY
LDA
STA
LDA
INY
STA

A8E9:
A8EB:
A8EC:
A8EE:

A004
18
A5FA
691F

LDY #PINITADR-HEAD
CLC
LDA LOGS TORE
ADC #PINIT-HEAD

A8FO:
A8F2:
A8F3:
A8F5:
A8F7:

9lFO
C8
A5FB
6900
91FO

STA
INY
LDA
ADC
STA

A8F~:

AOOC
A5FA
18
65F4
91FO
AOll
A5FB
65F5
91FO

LDY
LDA
CLC
ADC
STA
LDY
LDA
ADC
STA

A8FB:
A8FD:
A8FE:
A900:
A902:
A904:
A906 :
A908:
80

#PST-HEAD
LOGS TORE
(STOREADR) ,Y
LOGSTORE+1
(STOREADR), Y

(STOREADR) ,Y
LOGSTORE+l
#0
(STOREADR) ,Y
#PNDLO-HEAD
LOGS TORE
PROGLEN
(STOREADR) ,Y
#PNDHI-HEAD
LOGSTORE+l
PROGLEN+1
(STOREADR) ,Y

A90A:
A90C:
A90E:
A910:
A912:
A914:

A916 :
A919:
A91B:
A91E:
A921:
A924:
A927 :
A92A:
A920:
A92E:
A93 0:
A933:
A936 :
A939:
A93C:
A93F:
A942:
A945:

LOY
LOA
STA
LOY
LOA
STA

A016
A5F6
91FO
AOIA
A5F7
91FO
*
*

BOOTTAPE GENERATION PART

GIVE INSTRUCTIONS
JSR PRINT
OFB CR,CR
ASC "PRESS PLAY & RECORD"

2000AA
0000
505245
535320
504C41
592026
205245
434F52
44
0000
414654
455220
544845
204245
455053
202752
455455
524EA7

OFB CR,CR
ASC \AFTER THE BEEPS
'RETURN'\

*
A948 :
A94A:
A94C:
A94F:
A951:
A954:
A956:
A959:

#JUMPADRL-HEAD
JMPADR
(STOREADR) , Y
#JUMPADRH-HEAD
JMPADR+l
(STOREADR) , Y

OPEN CASSETTE FOR WRITE

A210
OPENIOCB LOX #IOCBNUM*16
LOA #OPEN
A903
STA ICCOM,X
9D4203
LDA #OPNOT
A908
STA ICAXl,X
9D4A03
LDA #128
A980
STA ICAX2,X
904B03
LDA #CFILE:L
A9F2
81

A95B:
A95E:
A960:
A963:
A966:

9D4403
A9A9
9D4503
2056E4
3028

STA
LDA
STA
JSR
BMI
*

A968:
A96A:
A96D:
A96F:
A972 :
A974 :
A977:
A979 :
A97C:
A97E:
A981:
A984:

A90B
PUTPROG
9D4203
A5FO
9D4403
A5Fl
9D4503
A5F4
9D4803
A5F5
9D4903
2056 E4
300A
*

A986:
A988:
A98B:
A98E:

82

PUT PROGRAM ON TAPE


LDA
STA
LDA
STA
LDA
STA
LDA
STA
LDA
STA
JSR
BMI

#PUTCHR
ICCOM,X
STOREADR
ICBAL,X
STOREADR+l
ICBAH,X
PROGLEN
ICBLL,X
PROGLEN+l
ICBLH,X
CIOV
CERR

CLOSE IOCB

A90C
CLOSIOCB LDA #CLOSE
9D4203
STA ICCOM,X
2056 E4
JSR CIOV
1024
BPL SUCCES
*
*

A990:
A991:
A992:
A994:
A996:
A999:
A99C:
A99F:
A9Al:
A9A4:
A9A7:
A9A8:

ICBAL,X
#CFILE:H
ICBAH,X
CIOV
CERR

CERR
98
48
A210
A90C
9D4203
2056E4
2000AA
ODOD
455252
4F522D
AO
68

IF ERROR OCCURS
SHOW THE ERRORNUMBER
TYA
PHA
LDX
LDA
STA
JSR
JSR
DFB
ASC
PLA

#IOCBNUM*16
#CLOSE
ICCOM,X
CIOV
PRINT
CR,CR
\ERROR- \

A9A9:
A9AA:
A9AD:
A9BO:
A9B1 :

AA
2088AA
2000AA
8D
4CA2AA

TAX

JSR
JSR
DFB
JMP

IF NO ERROR OCCURS
TELL IT THE USER

*
*
A9B4:
A9B7:
A9B9 :
A9BC:
A9BF:
A9C2 :
A9C5 :
A9C8:
A9CB:
A9CE:
A9D1:
A9D4 :
A9D7:

2000AA SUCCES
ODOD
535543
434553
46554C
4C2042
4F4F54
544150
452047
454E45
524154
494F4E
OD8D

DFB CR,CR+l28
BRK-INSTRUCTION TO TERMINATE
THE PROGRAM. MOSTLY A JUMP
INTO THE MONITOR-PROGRAM
FROM WHERE YOU STARTED THE
PROGRAM. INSTEAD OF THE 'BRK'
YOU ALSO CAN USE THE 'RTS'
THE RTS-INSTRUCTION, IF THIS
PROGRAM WAS CALLED AS A SUB-

ROUTINE.
BRK

*
*
2000AA ADRERR
ODOD
414444
524553
53494E
472045
52524F
D2
4CA2AA

A9F2: 433A
A9F4: 9B

JSR PRINT
DFB CR,CR
ASC "SUCCESFULL BOOTTAPE GENERATION"

*
*
*
*
*
*
*
*
A9D9: 00

A9DA:
A9DD:
A9DF:
A9E2:
A9E5:
A9E8:
A9EB:
A9EE:
A9EF:

PUTINT
PRINT
CR+128
WAIT

IF ERROR IN THE ADDRESSES


TELL IT THE USER
JSR PRINT
DFB CR,CR
ASC \ADDRESSING ERROR\

JMP WAIT

*
*

THESE 3 CHARACTERS ARE NEEDED


TO OPEN A CASSETTE IOCB.

CFILE

ASC "C:"
DFB EOL

*
*

ROUTINE FOR MOVING THE HEADER


IN FRONT OF THE USER-PROGRAM

83

A9F5:
A9F7:
A9FA:
A9FC:
A9FD:
A9FF:

AOIF
MOVEHEAD LDY #HEADEND-HEAD
B9A8AA MOVELOOP LDA HEAD,Y
91FO
STA (STOREADR) , Y
DEY
88
BPL MOVELOOP
10F8
RTS
60

*
*
*
*
*
*
*
AAOO:
AA01:
AA03:
AA04:
AA06:
AA08:
AAOA:
AAOC:
AAOE:
AAIO:
AA12:
AA14:
AA16:
AA18:
AAIB:
AA1D:
AA1F:
AA21:
AA23:
AA24:
AA26:
AA27 :

PRINT
68
8SF8
68
8SF9
A200
E6F8
PRINTl
D002
E6F9
AIF8
297F
C90D
D002
A99B
20MF6 NOCR
A200
AIF8
10E7
ASF9
48
ASF8
48
60

*
*
*
AA28:
AA2A:
AA2C:
AA2E:
AA30:
AA32:
AA34:
AA37:
AA38:
AA3B:

84

HEXIN
A900
8SF8
8SF9
A903
8SFC
HEXINl
3031
20DDF6
48
20MF6
68

THIS ROUTINE PRINTS A CHARACTERS


WHICH ARE BE POINTED BY THE
STACKPOINTER (USING THE 'JSR'
TO CALL THIS ROUTINE).
THE STRING HAS TO BE TERMINATED
BY A CHARACTER WHOSE SIGNBIT
IS ON.
PLA
STA
PLA
STA
LDX
INC
BNE
INC
LDA
AND
CMP
BNE
LDA
JSR
LDX
LDA
BPL
LDA
PHA
LDA
PHA
RTS

EXPR
EXPR+l
#0
EXPR
*+4
EXPR+l
(EXPR,X)
#%01111111
#CR
NOCR
#EOL
SCROUT
#0
(EXPR, X)
PRINTl
EXPR+l
EXPR

HEX INPUT ROUTINE


WAITS FOR CORRECT FOUR DIGITS
OR ' RETURN'
LDA
STA
STA
LDA
STA
BMI
JSR
PHA
JSR
PLA

#0
EXPR
EXPR+l
#3
HEX COUNT
HEXRTS
GETCHR
SCROUT

AA3C:
AA3E:
AA40:
AA42:
AA44:
AA46:
AA48:
AA4A:
AA4C:
AA4E:
AA51 :

C99B
F025
C958
F096
C930
9022
C93A
B008
290F
2075AA
4C32AA

CMP
BEQ
CMP
BEQ
CMP
BCC
CMP
BCS
AND
JSR
JMP

AA54:
AA56 :
AA58:
AA5A:
AA5C:
AA5D:
AA5F:
AA62:

ALFA
C941
9012
C947
BOOE
38
E937
2075AA
4C32AA

CMP
BCC
CMP
BCS
SEC
SBC
JSR
JMP

AA65: A4F8
AA67: A5F9
AA69 : 60

#EOL
HEXRTS

,x

ADRERR
,0
HEXERR
'9+1
ALFA
#%00001111
HEXROT
HEXIN1
'A
HEXERR
'F+1
HEXERR
'A-10
HEXROT
HEXIN1

HEXRTS

LDY EXPR
LDA EXPR+1
RTS

*
*
*

IF WRONG DIGIT
RINGS THE BUZZER
AND PRINT BACKSTEP

AA6A:
AA6D:
AA6F:
AA72:

200AF9 HEXERR
A91E
20A4F6
4C32AA

AA75:
AA77:
AA78:
AA7A:
AA7B:
AA7C:
AA7D:
AA7E:

C6FC
08
A204
OA
OA
OA
OA
OA

HEXROT

HEXROT1

JSR
LDA
JSR
JMP

BELL
#BST
SCROUT
HEXIN1

DEC HEXCOUNT
PHP
LDX #4
ASL
ASL
ASL
ASL
ASL
85

AA7F:
AA81:
AA83:
AA84:
AA86:
AA87:

26F8
26F9
CA
DOF8
28
60

ROL EXPR
ROL EXPR+l
DEX
BNE HEXROTI
PLP
RTS
THE RECURSIVE PUTINT
FOR PRINTING ONE BYTE

*
*
*
AA88: 48
AA89: 8A
AA8A: C90A
AA8C: 900D
AA8E: A2FF
*** WARNING:
AA90: E90A
AA92: E8
AA93: BOFB
AA95: 690A
AA97: 2088AA
AA9A: 18
AA9B: 6930
AA9D: 20A4F6
AAAO: 68
AAAl: 60

PUTINT

PHA
TXA
CMP no
BCC PUTDIG -IF A<lO THEN STOP RECURSION
LDX #-1
OPERAND OVERFLOW
DIV
SBC no
INX
BCS DIV
ADC no
JSR PUTINT- THE RECURSION STEP
CLC
PUTDIG
ADC '0
JSR SCROUT
PLA
RTS

*
AAA2: 20DDF6 WAIT
AAA5: 4COOA8

*
*

AAA8:
AAA9:
AAAA:
AAAC:

00
00
0000
0000

AAAE: A93C
AABO: 8D02D3

86

IN DECIMAL FORM

WAIT FOR ANY KEY


JSR GETCHR
JMP START
THE BARE CODE FOR THE HEADER
TO PUT IN FRONT OF PROGRAM
THE DUMMY HEADER

DUMMY

EQU 0

HEAD
RECN
PST
PINITADR

DFB
.DFB
DFW
DFW

THE BOOT CONTINUATION CODE

0
DUMMY
DUMMY
DUMMY

LDA #$3C
STA PACTL

AAB3: A900
PNDLO
AAB5: 8DE702
AAB8: A900
PNDHI
AABA: 8DE802
AABD: A900
AABF: 850A
AACl: A900
AAC3: 850B

LOA
JUMPADRL EQU
STA
LDA
JUMPADRH EQU
STA

AAC5: 18
AAC6: 60
AAC7: 60

LOA
EQU
STA
LOA
EQU
STA

#OUMMY
*-1
MEMLO
#DUMMY
*-1
MEMLO+l
iDUMMY
*-1
DOSVEC
#DUMMY
*-1
DOSVEC+l

CLC
RTS
HEAD END
PINIT

EQU *
RTS

PHYSICAL ENDADDRESS: $AAC8


STOREADR
PROGLEN
EXPR
HEXCOUNT
MEMLO
ICBAL
ICBLL
ICAXI
OPEN
CLOSE
SCROUT
BELL
PACTL
EOL
CR
START
PUTPROG
CERR
AORERR
MOVEHEAD

$FO
$F4

ENDADR
JMPADR
$F8
$FC
$02E7
$0344
$0348
$034A
$03
SOC
$F6A4
$F90A
$D302
$9B
SOD
$A800
$A968
$A990
$A9DA
$A9F5

$F2
$F6

UNUSED

87

PRINT
NOCR
HEXINl
HEXRTS
HEXROT
PUTINT
PUTDIG
DUMMY
RECN
PINITADR
PNDHI
JUMPADRH
PINIT
LOGSTORE
DOSVEC
ICCOM
ICBAH
ICBLH
ICAX2
PUTCHR
OPNOT
GETCHR
CIOV
CLS
BST
IOCBNUM
OPENIOCB
CLOSIOCB
SUCCES
CFILE
MOVELOOP
PRINTl
HEXIN
ALFA
HEXERR
HEXROTI
DIV
WAIT
HEAD
PST
PNDLO
JUMPADRL
HEAD END
88

$AAOO
$AA18
$AA32
$AA65
$AA75
$AA88
$AA9B
$00
$AAA9
$AAAC
$AAB9
$AAC2
$AAC7
$FA
$OA
$0342
$0345
$0349
$034B
SOB
$08
$F6DD
$E456
$7D
$lE
$01
$A948
$A986
$A9B4
$A9F2
$A9F7
$AA08
$AA28
$AA54
$AA6A
$AA7E
$AA90
$AAA2
$AAA8
$AAAA
$AAB4
$AABE
$AAC7

UNUSED
UNUSED

A DIRECT
CASSETTETO
DISKCOPY
PROCRAM
CHAPTER 9
If you have a bootable program on cassette,
and you want to have it on a bootable disk,
the following program will help you.
This program is easy to understand if you
have read the previous chapters. It allows
you to copy direct from tape to disk,
using a buffer.
When you start your program from your
machine language monitor, you must put the
cassette into
the
recorder
and
the
formatted disk into the drive (#1). After
the beep, press return,
and the cassette
will be read. After a succesful read the
program will be written on the disk.
If,
during one of these lOis an error occurrs,
the program stops and shows you the error
code.
Now, power up the ATARI again and the disk
will be booted.
Sometimes the program
doesnlt work correctly. Just press SYSTEM
RESET and most of the time the program
will work.
The copy program will not be described,
but it has helpful comments,
and you
possess the knowledge of the 10.
It is important that the buffer (BUFADR)
is large enough for the program.
89

**************************************
*
*
....
DIRECT CASSETTE TO DISK
*
*
*
COpy PROGRAM
*
*
'l<
*
**************************************
,,-

90

SECTR
DBUFFER
BUFFER
BUFLEN
RETRY
XSAVE

EPZ
EPZ
EPZ
EPZ
EPZ
EPZ

$80.1
$82.3
$84.5
$86.7
$88
$89

DCBSBI
DCBDRV
DCBCMD
DCBSTA
DCBBUF
DCBTO
DCBCNT
DCBSEC

EQU
EQU
EQU
EQU
EQU
EQU
EQU
EQU

$0300
$0301
$0302
$0303
$0304
$0306
$0308
$030A

ICCMD
ICBAL
ICBAH
ICBLL
ICBLH
ICAX1
ICAX2

EQU
EQU
EQU
EQU
EQU
EQU
EQU

$0342
$0344
$0345
$0348
$0349
$034A
$034B

OPEN
GETCHR
CLOSE

EQU 3
EQU 7
EQU 12

RMODE
RECL

EQU 4
EQU 128

CIO
SIO
EOUTCH

EQU $E456
EQU $E459
EQU $F6A4

EOL
EOF

EQU $9B
EQU $88

IOCBNUM

EQU 1
ORG $A800

*
A800: 20A7A8 MAIN
A803: 3063

*
*
A805:
A807:
A809:
A80B:
A80D:
A80F:
A811 :
A8l3:

OPEN CASSETTE FOR READ


JSR OPENCASS
BMI IOERR
INITIALIZE BUFFERLENGTH &
BUFFER POINTER
LDA
STA
LDA
STA
LDA
STA
LDA
STA

A956
8584
A9A9
8585
A980
8586
A900
8587

*
,~

#BUFADR:L
BUFFER
#BUFADR:H
BUFFER+l
#128
BUFLEN
#0
BUFLEN+l

READ RECORD BY RECORD


TO BUFFER UNTILL EOF REACHED

A815: 20C8A8 READLOOP JSR READCASS


BMI QEOF
A818: 3010

*
*
A81A:
A81C:
A81D:
A81F:
A821:
A823:
A825:
A827:

A584
18
6980
8584
A585
6900
8585
4C15A8

LDA
CLC
ADC
STA
LDA
ADC
STA
JMP

*
*
*
A82A:
A82C:
A82E:
A831:

IF NO ERROR OR EOF INCREASE


THE BUFFER POINTER

C088 QEOF
D03A
20E9A8
3035

BUFFER
#128
BUFFER
BUFFER+l
#0
BUFFER+l
READLOOP

IF EOF REACHED THEN WRITE


BUFFER TO DISK
ELSE ERROR
CPY
BNE
JSR
BMI

#EOF
IOERR
CLOSCASS
IOERR
91

*
*
A833:
A835:
A837:
A839:
A83B:
A83D:
A83F:
A841:

A901
8580
A900
8581
A956
8582
A9A9
8583

INIT POINTERS FOR


SECTOR WRITE
LDA
STA
LDA
STA
LDA
STA
LDA
STA

#1
SECTR
#0
SECTR+1
#BUFADR:L
DBUFFER
#BUFADR:H
DBUFFER+1

WRITE SECTOR BY SECTOR


BUFFER TO DISK

A843: 2006A9 WRITLOOP JSR WRITSECT


A846: 3020
BMI IOERR
*
*
A848:
A84A:
A84C:
A84E:
A850:

A582
C584
A583
E585
BOIS

LDA
CMP
LDA
SBC
BCS
*
*

DBUFFER
BUFFER
DBUFFER+1
BUFFER+1
READY

INCREASE BUFFER AND SECTOR


POINTERS

A852:
A854:
A855:
A857:
A859:
A85B:
A85D:

A582
18
6980
8582
A583
6900
8583

LDA
CLC
ADC
STA
LDA
ADC
STA

#128
DBUFFER
DBUFFER+1
#0
DBUFFER+1

A85F:
A861:
A863:
A865:

E680
D002
E681
DO DC

INC
BNE
INC
BNE

SECTR
*+4
SECTR+1
WRITLOOP

A867: 00
A868:
A869:
A86A:
A86C:
A86E:
A871:

92

IF BUFFER IS WRITTEN THEN


STOP PROGRAM

DBUFFER

JUMP ALWA YS! ! !

*
*

THE BREAK FOR RETURNING


TO THE CALLING MONITOR

READY

BRK

98
IOERR
48
A208
8689
ERRLOOP
BD84A8
20A4F6

TYA
PHA
LDX
STX
LDA
JSR

#LENGTH
XSAVE
ERROR,X
EOUTCH

AB74:
AB76:
AB77:
AB79:
AB7A:
AB7B:
AB7E:
ABBO:

A6B9
CA
lOF3
6B
AA
20BDAB
A99B
20A4F6

LDX
DEX
BPL
PLA
TAX
JSR
LDA
JSR

*
*
ABB3: 00

202D52 ERROR
4F5252
45
9B9B

ABBD: 4B
ABBE: BA
ABBF: C90A
AB91: 900D
AB93: A2FF
*** WARNING:
AB95: E90A
AB97: EB
AB9B: BOFB
AB9A: 690A
AB9C: 20BDAB
AB9F: IB
ABAO: 6930
ABA2: 20A4F6
ABA5: 6B
ABA6: 60

ERRLOOP
PUTINT
#EOL
EOUTCH

THE BREAK FOR RETURNING


TO THE CALLING MONITOR
BRK

*
ABB4:
ABB7:
ABBA:
ABBB:

XSAVE

TEXT FOR ERROR MESSAGE


ASC " -RORRE"
DFB $9B,$9B

LENGTH

EQU (*-I)-ERROR

*
*

RECURSIVE PUTINT FOR


DECIMAL ERRORCODE

PUTINT

PHA
TXA
CMP #10
BCC PUTDIG
LDX #-1
OPERAND OVERFLOW
DIV
SBC #10
INX
BCS DIV
ADC #10
JSR PUTINT
CLC
PUTDIG ADC '0
JSR EOUTCH
PLA
RTS
*
*

RECURSION STEP

THE WELL KNOWN CASSETTE


READ SECTION JUST A LITTLE
MODIFIED

93

_c

-e

ASA7:
ASA9:
ASAB:
ASAE:
ASBO:
ASB3:
ASB5:
ASBS:
ASBA:
ASBD:
ASBF:
ASC2:
ASC5:
ASC7:

A210
OPENCASS LDX #IOCBNUM*16
A903
LDA #OPEN
9D4203
STA ICCMD,X
A904
LDA #RMODE
9D4A03
STA ICAXl ,X
A9S0
LDA #RECL
9D4B03
STA ICAX2,X
A903
LDA #CFILE:L
9D4403
STA ICBAL,X
A9A9
LDA #CFILE:H
9D4503
STA ICBAH,X
2056E4
JSR CIO
302F
BMI CERR
60
RTS
-,-_c
"-,-

ASCS:
ASCA:
ASCC:
ASCF:
ASDl:
ASD4:
ASD6:
ASD9:
ASDB:
ASDE:
ASEO:
ASE3:
ASE6:
ASES:

94

GET BUFFER IN RECORDS


FROM CASSETTE

A2l0
READCASS LDX #IOCBNUM*16
A907
LDA #GETCHR
9D4203
STA ICCMD,X
A5S4
LDA BUFFER
9D4403
STA ICBAL,X
A5S5
LDA BUFFER+l
9D4503
STA ICBAH,X
A5S6
LDA BUFLEN
9D4S03
STA ICBLL,X
A5S7
LDA BUFLEN+l
9D4903
STA ICBLH,X
2056E4
JSR CIO
300E
BMI CERR
60
RTS
-,--,-

ASE9:
ASEB:
ASED:
ASFO:
ASF3:

OPEN FILE

CLOSE CASSETTE FILE

A210
CLOSCASS LDX #IOCBNUM*16
A90C
LDA #CLOSE
9D4203
STA ICCMD,X
2056E4
JSR CIO
3001
BMI CERR

-"
-,-

A8F5: 60

RTS
-"
-,~:<

A8F6:
A8F7:
A8F8:
A8FA:
A8FD:
A900:
A901:
A902:

98
CERR
48
A90C
9D4203
2056E4
68
A8
60

A903: 433A
A905: 9B

RETURN WITH ERRORCODE IN


ACCUMULATOR
TYA
PHA
LDA #CLOSE
STA ICCMD,X
JSR CIO
PLA
TAY
RTS

CFILE

ASC "C:"
DFB EOL

.,--"

THE WELL KNOWN WRITE SECTOR


ROUTINE

::~

A906:
A908:
A90B:
A90D:
A910:
A912:
A915:
A917:
A91A:
A91C:
A91F:
A921 :
A924:
A926:
A929:
A92B:
A92E:
A930:
A933:
A935:
A937:

RETURN TO SUPERVISOR

A582
WRITSECT LDA DBUFFER
8D0403
STA DCBBUF
A583
LDA DBUFFER+l
8D0503
STA DCBBUF+l
A580
LDA SECTR
8DOA03
STA DCBSEC
A581
LDA SECTR+l
8DOB03
STA DCBSEC+l
A957
LDA 'w Replace "W" by a "P" if you want it fast
8D0203
STA DCBCMD
A980
LDA #$80
8D0303
STA DCBSTA
A931
LDA 'I
8DOO03
STA DCBSBI
A901
LDA #1
8DOl03
STA DCBDRV
A90F
LDA #15
8D0603
STA DCBTO
A904
LDA #4
8588
STA RETRY
A980
LDA #128
95

A939:
A93C:
A93E:
A941:
A944:
A946:
A948:
A94A:
A94C:
A94F:
A952:
A955:

8D0803
A900
8D0903
2059E4 JMPSIO
100C
C688
3008
A280
8E0303
4C41A9
AC0303 WRITEND
60

STA
LDA
STA
JSR
BPL
DEC
BMI
LDX
STX
JMP
LDY
RTS

BUFADR

DCBCNT
#0
DCBCNT+l
SIO
WRIT END
RETRY
WRITEND
#$80
DCBSTA
JMPSIO
DCBSTA

EQU;~

PHYSICAL ENDADDRESS: $A956


SECTR
BUFFER
RETRY
DCBSBI
DCBCMD
DCBBUF
DCBCNT
ICCMD
ICBAH
ICBLH
ICAX2
GETCHR
RMODE
CIO
EOUTCH
EOF
MAIN
QEOF
READY
ERRLOOP
LENGTH
DIV
OPENCASS
CLOSCASS
CFILE
96

$80
$84
$88
$0300
$0302
$0304
$0308
$0342
$0345
$0349
$034B
$07
$04
$E456
$F6A4
$88
$A800
$A82A
$A867
$A86C
$08
$A895
$A8A7
$A8E9
$A903

UNUSED

JMPSIO
BUFADR
DBUFFER
BUFLEN
XSAVE
DCBDRV
DCBSTA
DCBTO
DCBSEC
ICBAL
ICBLL
ICAXl
OPEN
CLOSE
RECL
SIO
EOL
IOCBNUM
READLOOP
WRITLOOP
IOERR
ERROR
PUTINT
PUTDIG
READCASS
CERR
WRITSECT
WRITEND

$A941
$A956
$82
$86
$89
$0301
$0303
$0306
$030A
$0344
$0348
$034A
$03
$OC
$80
$E459
$9B
$01
$A815
$A843
$A868
$A884
$A88D
$A8AO
$A8C8
$A8F6
$A906
$A952

97

HOWTO
CONNECT YOUR
ATARIWITH
ANOTHER
COMPUTER
CHAPTER 10
The following programs make it possib le to
communicate between an ATARI and a PET/CBM.
The output ports are referenced as PORTA
and DATABUS between th e two computers.
Bit
o on th e ATARI PORTB is the 'hand' of the
ATARI and bit 7 on the same port
is
the
'hand'
of
the CBM.
Now a handshake
communication between both can be started.
The routines PUT and GET are, in this case,
dummies.
Further,
you
need
a
stop
criterium to stop the transfer. See these
routines merely as a general outlines and
not as complete transfer programs.
(Send information from A TAR I to PET ICBM)
IEEE Port
PET/C BM
PET IC BM USER PORT

/OP

1,..1, ,.I,

.==12
,~--

1i

. ~ HJ

L M N

..

~~~~g

:J

H J

12

M N

D E

GND

0 ,

(3)
5

0
5

.,.

0\'.0.0~)O 0\.0 0)0 0\ )0o~


.0 .0)0

:P
-i

:P
~

.0.0

.,.

~
<Xl

0
0

The AT AR I - - CBM / PET connection-wiring diagram

98

**************************************

*
*

RECEIVE FOR ATARI

*
*
**************************************
PORTB
PBCTL
PORTA
PACTL

EQU
EQU
EQU
EQU

$D30l
$D303
$D300
$D302

PUT

EQU $3309
ORG $A800

*
*
A800:
A802:
A805:
A807 :
A80A:
A80C:

SET BIT 0 ON PORTB


AS OUTPUT
LDA
STA
LDA
STA
LDA
STA

A930
8D03D3
A90l
8DOlD3
A934
8D03D3

*
*
RFD
A80F: A90l
A8ll: 8DOlD3

*
*
A8l4: 2COlD3 WAITDAV
A8l7 : 30FB

*
*

#$30
PBCTL
#%00000001
PORTB
#$34
PBCTL

GIVE YOUR 'HAND' TO THE


PET
LDA #1
STA PORTB
WAIT UNTIL PET TAKES
YOUR 'HAND'
BIT PORTB
BMI WAITDAV
GET DATA FROM BUS
& PUT THEM SOMEWHERE
LDA PORTA
JSR PUT

A819: ADOOD3
A8lC: 200933

TAKE YOUR 'HAND' BACK


99

LDA #0
STA PORTB

A81F: A900
A821: 8D01D3

*
*

WAIT UNTIL 'PETS HAND'


IS IN HIS POCKET

AB24: 2C01D3 WAITDAVN BIT PORTB


BPL WAITDAVN
A827 : 10FB

START AGAIN

A829: 4COFA8

JMP RFD

PHYSICAL ENDADDRESS: $A82C

*** NO WARNINGS
PORTB
PORTA
PUT
WAITDAV
PBCTL
PACTL
RFD
WAITDAVN

$D301
$D300
$3309
$A814
$D303
$D302
$ABOF
$AB24

UNUSED

**************************************

*
*

SEND FOR PET CBM

PORTB
PBCTL
PORTA

EQU $EB4F
EQU $EB43
EQU $A822

GET

EQU $FFCF

*
*

************ **************************

*
ORG $033A,$A800
100

USER GET BYTE


ROUTINE

*
*
033A: A980
033C: 8D43E8

SET BIT 7 ON PET


TO OUTPUT
LDA #%10000000
STA PBCTL

033F: 20CFFF GETDATA


0342: 8D22A8

*
0345: A900
DAV
0347: 8D4FE8

*
*

GET DATA FROM USER


PUT IT ON BUS
JSR GET
STA PORTA
TELL ATARI DATA VALID
LDA #0
STA PORTB
WAIT UNTIL ATARI
GIVES HIS 'HAND'

034A: AD4FE8 WAITNRFD LDA PORTB


034D: 2901
AND #%00000001
034F: DOF9
BNE WAITNRFD

*
0351: A980
DANV
0353: 8D4FE8

*
*
0356: AD4FE8 WAITRFD
0359: 2901
035B: FOF9

*
035D: 4C3F03

SHAKE 'HANDS' WITH ATARI


LDA #%10000000
STA PORTB
WAIT UNTIL ATARI RELEASE
HIS 'HAND'
LDA PORTB
AND #%00000001
BEQ WAITRFD
START AGAIN WITH DATA
JMP GETDATA

101

PHYSICAL ENDADDRESS: $A826

***

NO WARNINGS

PORTB
PORTA
GETDATA
WAITNRFD
WAITRFD
PBCTL
GET
DAV
DANV

102

$E84F
$A822
$033F
$034A
$0356
$E843
$FFCF
$0345
$0351

UNUSED
UNUSED

300 BAUD SERIAL


INTERFACE VIA
THEATARI
JOYSTICK PORTS
Chapter 11
The following construction article allows you to build your own
RS232 interface for the ATAR I computer. The interface only
works with 300 Baud and just in one direction (output).
The interface consists of:
a) RS232 serial interface driver on a bootable cassette or
as a SYS file on disk.
b) Two wires hooked up to game port 3 on your AT AR I.
TRANSMIT
DATA

9
GND

GAME PORT 3
We used this interface with a DEC-writer, a NEC spinwriter, and
a Brother H R-15. The DEC-writer worked with just the two wires
connected (Transmit DATA and GND).
The Spinwriter and the Brother needed some jumper wires as
shown below:
103

Receive data on DEC-writer

..

13
{

",,"0 0

1
ooo~oo)

000

0/

25

-.

14

Receive data on Brother HR-15

3
6 5 4

13
000

>

\:0000
0

>

000

0
0

25

/
0

14

Receive DATA on N EC Spinwriter

7
13
00000

25

20

14

Depending on the printer you use you will have to make the
appropriate wiring according to the instructions in the manual.
The source code for the RS232 driver is listed on a previous page
in this book.
104

This is a sample printout in BASIC:


10 0 PE N # 1,8,0, "R : "
20 FOR X=1 TO 10
30 PRINT #1,"ELCOMP-RS232",X
'10 NEXT X
50 CLOSE #1

will generate the following printout :


ELCOMP-RS232
E LCOMP-RS2 32
ELCOMP-RS232
ELCOMP-RS232
ELCOMP-RS232
ELCOMP-RS232
ELCOMP-RS232
E L COM P- R S 232
ELCOMP-RS232
ELCOMP-RS232

1
2
3
'I
5

6
7
8
9
10

The source code for the RS-232 Interface


page 72.

you will find

on

105

Printer Interface
Chapter 12
Screen to Printer I nterface for the AT AR I 400/800
Many ATAR I users would like to connect a parallel interface to
the computer. For many people buying an interface is too expensive. On the other hand, they may not have the experience to
build one by their own. Also a lot of software is needed.
The following instructions make it easy to hook up an EPSON
or Centronics printer to the ATAR I.
Only seven of the eight DATA bits are used for a printout.
DATA 8 is grounded. BUSY and STROB E are used for handshake.
There is an automatic formfeed every 66 lines. Thus it is necessary
to adjust the paper before starting to print. You may need to
make several trials to find the best position of the paper. For a
different form-length you mayPOKE 1768, ... (number of lines).
After system reset the line counter is set to zero, so you have to
provide your own formfeed for a correct paper position.
You can control the length of a line by a POKE 1770, xxx. After
doing so, press system reset and enter LPRINT.
The program SCREENPRINT is called by BASIC thru an USR
(1670) and by the assembler with a GOTO S0687.
You may install pnp transistors between the game output and the
printer, as it is shown in this little figure and in the schematic on
page 112.
~-MX80

ATARI---I

PNP-TRANSISTOR
2N722 or similar

106

The next figure shows the connection of the ATAR I game outlets
and the connector for the MX -80 printer. This is a so-called
Centronics interface and the program can be used with each
printer and this interface.

EPSON MX80 - ATARI 400/800


Interconnection -Scheme
MX80-Connector
Pin #
1 (19) STROBE
2 (20) DATA 1
3 (21) DATA 2
4 (22) DATA 3
5 (23) DATA 4
6 (24) DATA 5
7 (25) DATA 6
8 (26) DATA 7
9 (27) DATA 8
11 (29) BUSY
(GND)
(19)-(29)

ATAR I-Connectors
Port3
Port 4
Pin #
Pin#
4

1
2
3
4

1
2
3
8
6

= Ground

8
(GND)

Plugs seen from the rear view .


Front view of the computer outlets .

ooeo

PORT 3

.oeo

PORT 4

107

The next figure shows the program

*******************************

UNIVERSAL PRINT FOR ATAR!

400/800 VERSION ELCOMP

*
**

BY HANS-CHRISTOPH WAGNER

**

*******************************
BA~:;

1=0'1"
F~:;T

I ~:;

EF'Z

:li5E~

EPl 'liFE
EDU 1i600
Cm(3 PST

0600:
0601:
060~'? ~

0604::
0606:
J)60B;
060[1:
06(lD ~
0610~

0612:
06:[!:;:
0617::
0619:
061 B:
061D:
061E:
06:LF:
()62:?:

00
02
0006
(":-1::'06
?"1 cr:;c
BOO:?D::::'
(.:.CjlEB

fmE70:::
f-Vi06
f3DE80:~:

f:,96E
f:350P,
A906
f3~.jOE{

OFB 0
OFB ::
DFV) FoE;T
m=-(.lJ II\j I T
LDt~ :IH:5C
STI~ $0302
LOA #PNO
~nA $02E7
l... DA HPND/2~56
~-3TA $02EB
LOt:'1 #HnT
STI~

$OA

L.DA 1* I t,1 I T I 256

f3TA $OB

113

CU::

60

F:'r:3

~0:~D064:'?
Oh~~;F~()6

06~0?5:

iL?06::~;F

0628:

063F06 HANOLTAB DFW DUMMY.


WRITE-l.RTS1-l.WRITE - l . RTS1-l.
F:TS 1 ....:1.

DFU :[
108

062C:
062E:
0631 :
0633:
0636:
0638:
0638:
0630:
0640:
0642:
0643:
0645:
0647:
064A:
0640:
0650:
0652:
0654:
0657:
065A:
065C:
065F:
0662:
0664:
0667:
Ob6A:
066C:
066E:
0670:
0673:
0675:
0678:
067A:
067D:
0680:
0683:

A930
800303
A9FF
800103
A934
800303
A980
800103
A001
60
C99B
0010
AOEA06
80E906
CEE806
1000
A90C
206406
EEE906
A941
8DE806
EEE906
A90D
20D106
CEE906
FOD8
DOD2
A91F
801803
A906
801C03
A941
8DE806
ADEA06
8DE906
4C2C06

0686:
0687:
0689:
0688:
0680:
068F:

68

A558
85FE
A559
85FF
A917

OPEN

RTSI
WRITE
CARR

NOFF
PRINT

INIT

BASIC
NORMAL

#$30
$D303
#SFF
$0301
#$34
$0303
#$80
$0301
#1

LOA
BTA
LOA
BTA
LOA
BTA
LOA
BTA
LOY
RTS
CMP
8NE
LOA
BTA
DEC
8PL
LOA
JSR
INC
LOA
STA
INC
LDA
JSR
DEC
8EQ
BNE
LDA
STA
LOA
STA
LDA
STA
LDA
STA
JMP

#$98
PRINT
LINLEN
LCOUNT
COUNT
NOFF
#12
PRINT
LCOUNT
#65
COUNT
LCOUNT
#13
OUTCHAR
LCOUNT
CARR
RTS1
#HANDLTAB
$0318
#HANDLTAB /2 56
$031C
#65
COUNT
LINLEN
LCOUNT
OPEN

PLA
LOA
STA
LOA
STA
LOA

8ASIS
PT
BASIS+l
PT+l
#23
109

06 cn ~
0694:
0696:
01.:8<,1:
069B:
069D:
069F:
Ot,A 1 :
06A3:
06A::'i:
06A8:
06AA:
06('~C=

BDE606
A927
F:DVJLOOF'
BDE706
A:,200
PdFE
LOOF'
:~97F

Cf:760
BOO:.?
6(":;20
:.'20D106 U]DP 1
E6FE
0002
E6FF
CEE70 6
10E8
f:,90D
20D106
CEE606
10D7

06AE:
0681 ~
0683:
0685:
0(::J8fl :
068B:
068D: <SO

BC~:;
(~DC

\J~3F

F:Ol.>J
tt- ~~:'9

COLUt'lN
#0
<F'T,

X)

#~;7F

#$60
L.OOF'l
f1;$20
OLlTCHf:,F:
F'T
*>+-4
F'T+:l
COLUMN
LOOF'
#1 :::;;

INC
Bf\,IE
INC
DEC
BF'L
LDA
J f.3F: OUTCH{~F:
DEC F:Cll.>J
8F'L FWl.>JLDOF'
fnS

068E:
06C1 :
06C4:
06C7:
06CA:
06CD:
06DO:

484l4E
532057
41474E

06D1 :
06D4:
06D6:
06DB:
06DA:
06DD:
06DF:

AC13DO DUTCHI0tF:
DOF8
f."1080
0980
8001D3

4552:?(1

3T::'72E
T12E38
::)1 AUTHOF

(~GC

2c~7F:-

06E6: 1 7
0(::JE7: ...:: l
06EB: 41
06E <,) : FF'
, .. ,

~7

"1'-lANS l}JAGNE F:
LDY

~liDO:l3

ClUTCHAF:
LDY # '$00
CmA #$BO

BI'-JE

~3 TA

~t;D30:l

AI\W

#~l;7F

STA 'l;D30 1
STY $D301
F:H;

8001D3
8C01D3
O(::JE~) :
60

06E2~

110

:3Tr;
I_DPI
STA
LDX
LDA
(4NO
CI'1F'

RDl.>J
C(JLUI"IN
COUNT
LC(JUNT

DFB .,.,:: ...-:r-:1


DF'B 39
DFB C) ... .J
;t:'"

DFE<

l-.,c:-c::,,::,~,.J

DFB
F'ND
Bf"-"1~; I~;

~i :'jEl

F'T

liFE

F'~:;T

'1;0600

HPINDLT{~B

<tiU (} :/. F

DUI'II'!\,

~~062B

OPEN
Rr ~:; :l.

$06:2C

l.>m I TI::::

$(1643

o {,:)4 7

'"'lDFF
F'F;: I NT
INT r

$06~=:;F

(~UTHOf;:

DUTCHAF::

I::: [) (,,I
CDL.LII"II'I
COUt"..IT
L.CClUI'.IT
LINLEN
F'ND

~ii0640

Cf4f:.:F~:

B{1SIC
NClF:t'1f4L
f;: [) vJ L. Cl [) F'
L.ClOP
L.CJDF' 1

EClU

r',r.::-r:::-

L,Jd

:~0664

,*i066E:
:ti06El(S
1i06137
't;0694
$ o c) ':?B

Ur,.IU!::;ED
UNUSED

't;06{~5

$06BE
't;06Dl
$06E:6
li06E7"
$06Ef.-3
't;06E9
~:;06E{~

'liO()EEl

Program description:
Address
0600 - 061E
end of the booting part
0610 - 062B
HANTAB for the ATARI OS
062C --- 0642
opens the ports for output
0643 - 066D
printer driver
066E - 0685
initialize . Now LPRINT and PRINT "P" use the printer
driver
0686 - 06BD
label BASIC starting address for a call by 8ASIC
Label NORMAL starting address for a call by assembler.

111

STROBE

r:r -i
:2
:3
:4

DATA 1
DATA 2
DATA 3

'6

'5

I__ __ J

:8
:1 1

:7

DATA 4

DATA6

DATA 5

printer
connector

5
7

9
a:
11
13
~

a:

"-

I-

mnect
ound
so to
3,21,
3, 31 ,
J

connections on pc-board

8 general
purpose
pnp
transistors

tD '

Schematic of the parallel printer interface for the EPSON MX-80 or MX100 . (Centronics like)

The numbers on the printer connector may vary with the different parallel printer used .
In this case go by the name of signal rather than by the numbers.

port 3

port 4

...

Q.

""~
>-

3 '"15
c.
4

2 ~

(J

""

Q.

>-

i;;

068E - 0600
060L - 06E5

Copyright notice
Subroutine, brings one ASCII character from
the accumulator to the printer
values for the various counters
ROW sets the number of horizontal lines to
23,
COLUMN sets the number of characters of
one line to 39.
COUNT sets the number of lines between
two formfeeds to 65
LCOUNT, LlNLEN contains the actual parameters for the number of characters and
lines,

06E6 - 06EA

Boot-R outine

FST
F'ND
I=-LEN

EOU $0600
EDU $0700
EQU FND-FST+127/128*128
ORG 1i6000

6000:

A210

6002~

(~lclO::::;

6004:

CjlD4:~'0:3

(:)0 () 7' ~

(~CfOt3

<:) () () S) ~
600C:

(~'7'f30

CjlD4AO::::;

600E~

9D4B03

601 :I.

(~Cf4?~

t.:lO

13~

6016~

C;>044 0:':;;
f~S"J60

601 El:

9D4503

601B~

20::::;6E4

601E::
602() ~

3(}~29

{~'7'OB

(S(l:::~:~~ ~

CjlD4:~~O~=:'

f:.) () ~~~~) ;:

'~'7'O()

(S():2~?

::

\SC):??~ ~

9D4403
?~9()6

6U2C~

CjlD4~50::::;

60~;: F' ~

{~r:ro(>

BOOTB

LDX
l_DA
STA
LDA
STA
LDA
!3TA
L.DA
!3TA
LDA
STA
,JSR
BMI
l_DA
STA
LDA
!:; T f=)
L.DA
!3TA
LDA

#~li:l.

#-,
0._'
$0::::A2!, X
#8
$O:34A, X
#$80
$0:34B, X
#CFILE
$0::::A4, X
#CFILE/256
~liO::::A5, X
'tiE4~'56

CEF:F;:
*~$OB
~li O:A2, X
:j:!:F' ST
$O:A4!, )(
#F'ST/Z56
~liO:A5 , X
:J.tFLEN

113

6031 :
:
6036:
6039:
603C:
6u .~;A

60::::;E~

6040:
6043:
6046:
604f3 :
6049:

(JlD 1l!:lO:::;;
Pt90 1
(JlD4903

(jl D4:,~~O::;

~:;TPI :!iO::A8 ~ X
l_DA #FI_EN/:,~:56
[iTA ~~iO::::Jj.9 X
J ~3r-;: 'M::456
BMI CEF:F:
l..DA #1iOC
~:;TPI <li O::;4:2!. X

20~;6E4

~r ~:;I::;:

20~;6E4

30oE(
A90C

<tiE4~56

~:;OO:l.

EWII CE::r;:F:

00

BF;:k

4T:;{'~

(~04C~

7B

Bm:::

CEF;:f;:
CF II....E

00

604{~~

F'~)T

';fj060()

F'I\ID
FL..EN
BClClTB

<t"O:l. ()O

[:E:Ff~;:

$6()49

PISC "L "


DF'B '$7B

~~070 0
~1i6000

UI\IU~:;ED

~lihO-:;'A
CF I L. E
If you want to use this program, it has to be bootable, Therefore
you must enter both programs and start the boot routine at
address $ 6000. This will create a bootable cassette, you can use
afterwards in the following manner, to enter the SCREENPRINT
in your comouter.
- turn off the computer
- press the start key
- turn on the computer
- release the start key
- press PLAY on the recorder and
- press RETURN

BASIC or assemblereditor cartridge must be in the left slot of


your ATARI computer.
How to wire the board:

1
to ~
printer

0
0
0
0
0
0

0
0
0
0

60 0 0 0
9

so 0

0 0

to port 4
114

60 0 0 90
o~

So

to port 3

o~

Differences between the


ATARI EditorlAssembler
Cartrigde and ATAS-1
andATMAS-1
The programs in this book are developed using theATMAS (ATAS)
syntax. In the following I would like to explain the difference
of some mnemonics of the ATARI Editor/Assembler cartridge and
the Editor/Assembler and ATMAS-1 from Elcomp Publishing.
Instead of the asterisk the ATAS uses the pseudo op-codes ORG.
Another difference is that the AT AS is screen oriented (no line
numbers needed). Instead of the equal sign ATAS uses EQU.
Additionally ATAS allows you the pseudo op-codes EPZ: Equal
Page Zero.
There is also a difference in using the mnemonics regarding storage
of strings within the program .
ATARI
- BYTE "STR I NG"

ELCOMP
ASC "STR I NG"

- BYTE 5

DFB 5 (Insertion of a byte)

-WORD

D FW

(I nsertion of a word
Lower byte, higher byte)

The end of string marker of the AT AR I 800/400 output routine


is hex 9B .
In the listing you can see , how this command is used in the two
assemblers:
ATARI Assembler:
- .BYTE 59B
ATMAS from ELCOMP
- DFB 59B
Depending on what Editor/ Assembler from ELCOMP you use,
th e stringoutpu t is handled as foll ows:

115

1. ATAS 32K and ATAS 48K cassette version


LOX #TEXT
LOY # TEXT /256
TEXT ASC "STRING"
OFB59B
2. ATMAS 48K
LOX #TEXT : L
LOY #TEXT:H
TEXT ASC "STR I NG
OFB 59B

1/

There is also a difference between other assemblers and the


ATAS-1 or ATMAS-1 in the mnemonic code for shift and relocate
commands for the accumulator.
(ASL A = ASL) = OA
(LSR A = LSR) = 4A
ROL A = ROL = 2A
ROR A = ROR = 6A
The ATMAS/ATAS also allows you to comment consecutive bytes
as follows:
JUMP EQU 5F5.7
5 F5 = Label Jump
5 F6 and 5 F7 are empty locations.
This is a comment and not an instruction.

116

ORDER FORM

HOFACKER

ELCOMP PUBLISHING , INC " 53 Redrock Lane, Pomona, CA 91766 (Phone: (714) 6238314)
Please mako chocki ou t 10 ELCOMP PUBLISHING,INC.

Please bi ll to my Master Card or Visa account

Name: "". " . ". "." , . ' .". " . , ' ."

# ..

Card #

Address: ." . , . . ,

Expiration Date . ...

Master Charge Bank Code, ... , , , . , , . . . .. . . . '


City / State / Zi p: , , , , , ' , , , ' . , . , , , , ' , '

Signature .. .... . . . . . .. . .. . .. . . .
Order

Oty .

N,

..... 29
..... 159
..... 151
.... . 152
. ... . l:i3
... .. 154
... .. 156
.. ... 15B
.. .. . 159
.. ... 168
.... . 161
... .. 162
..... 1b4
.... . 166
..... 169
..... 170
..... 171
..... 173
... .. 174
... .. 176
.. ... 2e 2
... .. 684
.... . be5
-.. ..
. ....

.. ...
.....
.....
... ..
.....
... ..
... ..
.....
.. ...
... ..
.. ...
.. ...
.....
.. ...
.... .
.. ...

... ..

606
6e7
60 B
689
61 e
blS
bB0
239B
2399
2488
3276
3475
482b
4B44
4B4B
4878
48B0
4BB 1
4BB3

Description

MICROC . HARDUARE HANDB.


CARE AND FEEDING
Bt: MICROSOfT BASIC
EXP.HANDB . 6592 AND 6B8:?
HIeROe. APPLICATION NOTE S
COMPLEX SOUND
SMALL BUSINESS PROGR.
SECOND B001: Of OHIO
THE THIRD BOOI: or OHIO
THE FOURTH BOOl: OF OH \0
THE fifTH BOO K or OHIO
GAH ES f OR THE ATARI
ATAR I LEARNING BY USING
PROGR . I. b582 HACH.LANG .
HOU TO PROGR.IN MACH.L.
FORTH ON THE ATARl
A LOO K INTO THE rUTURE
PROGRAM DESCRIPTIONS
lX-B I IT IHE X
TR ICI:S FOR VICS
JANA / 1 HilI! nOR
PROTOnPING CARD
6522 VIA 110 EXP. CARD
SLOT REP EATER
2716 EPROM PROGRAM HER
SOUND WITH THE GI AY3- 8912
BI: EPROH CARD (2: 1b )
12 BIT AI D CONVERTER BOAR
161: RAMR OM- BOARD
THE CUSTOH APP LE BOOI:
MAILING LIST FOR lX-B1
HACHINE LANG . HO NITOR
ADA PTE R BOARD FOR lX-BI
ED ITOR / ASS. FOR CBM
ASS EHBLER FOR CBH
GUNFIGHT FOR PET I CB M
UNIV ERSA L EXP. BOARD
ADAPTER BOARD
PROF I UORDPROC. r. VIC
TIC TAC VI C
GAHEPACI: FOR VIC
MA I L -V I C

Price S
14. '15
9 . 95
'1.95
9 .95
9 .95
6.'15
14.98
?95
7. 95
9.95
7 . 95

7 . 95
7 .95
'1'1.95
9 . 95
7 .95
9 . 95
4. 95
'1 .95
9 . 95

29 . l lS
29.80
39 . 09
49.80
49 . 09
39.00
29.01
7 4.0'
59 . 95
24 . '15
19.95
9.95
14.B0
39.00
39. 95
9. 95
18.95
3 . 95
19. '15
9 . 95
1\ . 95
1\ . 95

PI! vment : Check . Mone 0 , d or , VI S A, M I$le rch,


I gil. Access.
Interbank. Eurocheck
Prepaid orders add SJ .SO for shipping (USA)
tiS.DO handling fee for C.O.D.
A LL ORDERS OUTSI DE USA : Add 15 " shipping.
California residents add 6 .5" Sl ies ta x .

Gty.

. ....
. ....

. ....
.....
. ... .

Order

No ,

Price S

4BB9
4B94
4896
b 153
61 55
1822
1823
7024

EXPANDING YOU R VIC


RUNfl LL
MINIASSEMBLER
LEARN -fORTH
POWER fORTH (APPLE)
ATM ONA-1, CASSo
ATMONA-1, OISt:
ATHON A-1 , CARTRIDGE

14.95
9. 95
19.95
19.'15
39 . '15
19.95
24.95
5'1. 00

. .. ..
. ....
. ... .
. .. ..
. ... . 7842
... .. 7043
..... 7049
. ... . 7050
. .... 7853
. ....
.... .

.....

.....
.... .

... ..

.....
... ..

.. ...
... ..
... ..
.... .
.. .. .
.. ...
... ..

.....
.... .
.... .
.. ...
... ..
.. ...
.....

.....
.....
.....
.. ...
.... .

' ., " ,

Description

7855
709B
7899
7 100
72 00
72 07
72 I 8
1211

7212
7" 13
72 14
7215
72 1tS

72 17
722 1

7222
722 3
?:~2

1238
729 1

729 2
73 07
730'1
7310
7312
7313
73 14

. .... ... . . ..

EPROM BURNER fOR ATARI


EPROM BOARD ( CARTR IDGE )
ATHONA-2, CASSo
ATHONA-2. 0:(5):
LEARN-FORTH
POWER FORTH
ATAS
ATHAS
PROGRAKS fROH BOO1: " 164
I NVOICE URITlNG,OISI:
GUN FIGH T FO R ATAR I
WORDPROCESSOR , CASS .
HOW TO CONNECT
HAILING LI ST, CA SS o
MA I LI NG LI ST, 0151:
INVE NTOR'( CONTR . , CA SS.
IN VENTORY CONTR . , 01 51:
UORDPR OCE SSOR. DISK
WO RDPROCESSOR. CARTRIDGE
PROGRAMS FROM BOOI: n 162
I: NAUS OGINO
ASTROLOGY PROGRAM
EPROH BOARD KIT
FLOATING POINT PACt:AG E
RS2 32-INT ERFAC[
EPROM BURNER I: IT
ATCASH
HOON PHASES
ATAME MO
SUPER MAIL
BUSIPACI: 1
BIORHYTHM FOR ATARI

'1'1. '15
1'1 . 95
24,1, 5
111. '15
24 . 95
34, 95
69.08
29 , I7S
29 . 95
29.'15
14.94
299 .'15
19 . 95
\ 9 .0 0
49.95
19 . 95
29.9 5
49 . 01
9B .0 0
9.95

.. ... .. .. ..... . .... .. ... .. .

. ... ... .

'17 9 .00
29 . 95
49 . 95
54 . 00
19 . 95

C
;,

1]5

49 . 95
89 . 0e
29 . 95
39 . e 0
19 . '15

217. 95

S u per bollrd and C I P a r a t rada mark , o f Oh io Sc la ntl fl c Co.


AT A R llla tradem ar k 0 1 A T A RI Wa rn er Commu n lctlt lons
PET . CB M and V IC 20 a r e tra d emar k . o f Commod o re Bu,lness
Machlnos.
TRS e O I,a trademar k 0 1 T A ND Y R a dio Shack .
APP LE 111.a tradomo r k o f A PP L E C o mp ut or In c.

You might also like