A. S. S. I.  ATARI 6502 - (PC) Cross-Assembler

some hints at the beginning



installation / uninstallation

ASSI.ZIP includes the following, needed to run ASSI, files:

furthermore the archive includes the following files: Do the following steps to install ASSI: ASSI doesnt create any files in systemdirectories like WINDOWS or others. ASSI doesnt create any keys in the WINDOWS REGISTRY !
To uninstall ASSI, simply delete the whole ASSI directory.



commandline parameters

All commandline parameters must be separated through a blank. The last parameter must be the sourcefilename. Additional comandline parameters must be added before the filename:

/k
ASSI waits for a keypress after ending the assembling process. With the /k parameter you can supress this function. If an error occurs ASSI ever waits for a keypress.


displayed infos

The assembling process is showed through a gauge. The following additional infos are showed in cycle:


Assemblerdirectives

Organisationdirectives

ORG | *=  <physical + logical address>
ORG | *=  <physical address> , <logical address>
The ORG directive is used to set the program counter. Only one parameter will set the physical and the logical address to the same value. If there are two parameters the physical and the logical address can have separate values. The logical address is the address on wich the machinecode runs, the physical address is the place where the machinecode is stored.

EQU | EPZ | = | .= <ausdr>
Sets the label on the beginning of the line to the value <ausdr>.

OUT {LNMTOSA | / -}
With the OUT directive you can set options to form your output listing. The following parameters are available:

An '-' or '/' before the option letter disables the option. All changes are active immediately, so you can switch some options only for special parts of the sourcecode.

SET {M | / -}
With the SET directive you can set several options for the assembler module:

An '-' or '/' before the option letter disables the option. All changes are active immediately, so you can switch some options only for special parts of the sourcecode.

IF | .IF <ausdr>
Begins a sourcecodeblock wich is assembled conditional if <ausdr> is 'true'. The maximum recoursion is 250, practical endless.

EL | ELSE | .ELSE
Begins an alternative conditional sourcecodeblock.

EI | ENDIF | .ENDIF
Ends a conditional sourcecodeblock wich is started by the IF directive.

RELOC
Starts a sourcecodblock wich is assembled with relocating infos.

RELEND
Ends the sourcecodeblock thats started by the RELOC directive.

LOCAL | LOC | .LOCAL
A new local area starts, you can also type an @ at the linebeginning.

Datadirectives

HEX <hexstring> [' ',','<hexstring> ...]
With this function its possible to assemble hexstrings direct into the machinecode. A starting '$' isnt required. Example:

ASC <ASCII-String> [,<ASCII-String>,...]
This function produces ATARI ASCII Codes. <ASCII> must have two delimiters one at the begin and one at the end. The following options are given: ASCN <ASCII-String> [,<ASCII-String>,...]
Look at ASC directive. The end of each string is terminated by a zero byte.

ASCA <ASCII-String> [,<ASCII-String>,...]
Look at ASC directive. The end of each string ist terminated by a $9B (atari Return).

ASCL <ASCII-String> [,<ASCII-String>,...]
Look at ASC directive. At the beginning of the string a length byte is included.

ASCLN <ASCII-String> [,<ASCII-String>,...]
Look at ASC directive. At the beginning of the string a length byte is included. The end of each string is terminated by a zero byte.

ASCLA <ASCII-String> [,<ASCII-String>,...]
Look at ASC directive. At the beginning of the string a length byte is included. The end of each string ist terminated by a $9B (atari Return).

      asc "hello"                    ;simple string definition
      ascl 'hello ',/ world /,'!'    ;defines three strings with length byte, one is invers screen

DFB  | .BYTE <ausdr1> [,<ausdr2>,<ausdr3>, ...]
The low byte of <ausdr> is assembled.

DFBH <ausdr1> [,<ausdr2>,<ausdr3>, ...]
The high byte of <ausdr> is assembled.

DFBD <ausdr1> [,<ausdr2>,<ausdr3>, ...]
The low byte of the decremented word of <ausdr> is assembled.

DFBDH <ausdr1> [,<ausdr2>,<ausdr3>, ...]
The high byte of the decremented word of <ausdr> is assembled.

DFBB | .DBYTE  <ausdr1> [,<ausdr2>,<ausdr3>, ...]
The high and the low byte (in this order) of <ausdr> are assembled.

DFW | .WORD <ausdr1> [,<ausdr2>,<ausdr3>, ...]
The low and the high byte (in this order) of <ausdr> are assembled.

DFWD <ausdr1> [,<ausdr2>,<ausdr3>, ...]
The low and the high byte (in this order) of the decremented <ausdr> are assembled.

Tip: The decrementing directives are good to implement atari typical jump tables:

jumptablo       dfbd adr1,adr2,adr3,adr4
jumptabhi       dfbdh adr1,adr2,adr3,adr4

                ...

                lda jumptabhi,x
                pha
                lda jumptablo,x
                pha
                rts

Typdefinitions

BYT
Byte. The programmcounter is incremented one time.

WRD
Word.The programcounter is incremented two times.

SPC | .DS  <ausdr>
<ausdr> is added to the programcounter.

'SPC 1' is equal to 'BYT', 'SPC 2' is equal to 'WRD', but you should use BYT and WRD for a better readability of the sourcecode.

;define Z-Page registers (Z-page space at $00e0):

;example 1: its hard to change the registers or add one more:

reg1      equ $e0                  ;...
reg2      =   $e2                  ;...
color1    =   $e3
color2    epz $e4
arr1      =   $e5

;example 2: better you use type instructions, then all definitions are relative

          org $e0

reg1      wrd                      ;...
reg2      wrd                      ;...
color1    byt
color2    byt
arr1      spc 4                    ;4 byte long variable

;example to test memory overflow:

          if *>$ff                 ;if programcounter (*) greater $00ff
          error Z-page overflow    ;do this line only if 'if' is true -> produces error message
          endif                    ;end of the if block

Macrodirektives

MACRO | MC
Begins a macrodefinition

MEND | ME
Ends a macrodefinition

Macros must be defined before they are used first. Up to 10 macrospaceholders per macro can be used. The replacement of the macrospaceholders is done by stringoperations, so all kinds of constants and variables can be replaced. The separation of the spaceholders is done by a ','. To overgive a ',' to the macro you must use a point '.', this will be replaced though a ',' at the assembling time. If you want a '.' in a macro, use a '..' to overgive it. Strings delimited with '  ' are not changed (. -> ,).  Example:

;example1: A macro for a $0D0A terminated string should be created

asc0d0a        macro string               ;start macrodefiniton, macrospaceholder1 is 'string'
               asc string                 ;string directive
               dfb $d,$a                  ;adding $0d0a
               mend                       ;end macrodefinition

               ...

               asc0d0a "hello"            ;activate the macro, defines terminated string 'hello'

               asc0d0a "hello"./world/    ;another example, defines two terminated strings
                                          ;the '.' will be replaced by a ',' at macroexpansiontime

               asc0d0a "hello world.."    ;results: "hello world.", overgive a '.'
               asc0d0a '"hello world."'   ;results: "hello world."

;example2: A macro for a terminated string should be created, the termination bytes are unknown

ascterm        macro string,term          ;macrospaceholder1 is 'string',
                                          ;macrospaceholder2 is 'term'
               asc string
               dfb term
               mend

               ...

               ascterm 'hello world!',0   ;zero terminated string

               ascterm 'hello world!',$d.$a    ;0D0A terminated string, you can add termination bytes as much as you want
               ascterm 'hello world!','$d,$a'  ;same as above, another script

Assemblerdirectives are searched first, before the searchalgorithm goes to macrodefinitions. Theres no error message if assemblerdirectives with the same name like a macrodefinition are used. So it is possible to program often used macros as a assemblerdirective later. Then no changes must be done in the sourcecode.

Tip: Set the option 'Macroexpansion' in the OUT directive to see how the macroexpansion works.

Directives to include filedata

BGET | INCBIN | .INCBIN <filename>
The specified binary file will be assembled byte by byte in the machinecode.

INCLUDE | .INCLUDE <filename>
Assembles the sourcecode of the includefile in the project. A recoursion is not allowed.

Filelinker directives

The filelinker is used to save the machinecode into several fileformats. Saving the information is done in the last assembler pass.

FILE <filename>
Opens a binary file for output.

SAVE <startadr>, <endadr>
Memory from <startadr> to <endadr> is saved with the ATARI typical header ($FFFF, from, to)

PUT <startadr>, <length>
Memory from <startadr> to <startadr>+<length> is saved with the ATARI typical header ($FFFF, from, to).

BSAVE <startadr>, <endadr>
Memoryarea is saved without header.

RELSAVE <startadr>,<endadr>
The memoryarea is saved in the ATARI reloc format. The memoryarea must be assembled with RELOC / RELEND activated!

BPUT <startadr>, <length>
Memoryarea is saved without header

EXEC <adresse>
<adresse> will be saved as ATARI EXEC Vector (e002e102).

INIT <adresse>
<adresse> will be saved as ATARI INIT Vector (e202e302).

FEND
The open file will be closed.

RUN <application-path / parameters>
Starts a non ASSI  application. This function can be used to start some tools like the ATARI filelister.

;Example: Save a complete COM File Structure (must be located at the end of the sourcecode)

              file test.com           ;open file for binary output
              save $4000,$41FF        ;save block 1
              init $4000              ;start at init vector $4000
              save $4200,$7FFF        ;save block 2
              put $9000,256           ;save block 3
              init $9000              ;start at init vector $9000
              exec $4200              ;run at $4200
              fend                    ;close file

              file charset.bin        ;and another one
              bput charbase,$400
              fend


Arithmetic

For the intern arithmetic ASSI uses simple binary manipulations. Each value is a word form 0..65535 or -32768..32767. Boolean values are definited through 0 and -1. The recoursion of the arithmetic evens is practical endless. The following syntaxes for constants can be used:

${0..9,a..f,A..F}
Input a hexadecimal value with a $

% | ~ {0..1 | . .. *| . .. #}
Input a binary value with an % or ~

{0..9}
A simple decimal value

'{ascii}
Input an ASCII char with an '

The following runtime variables are available:

*
the actual programcounter

Tip: Any value specified above can be optionally terminated with a :H (:h) to separate the high byte or with a :L (:l) to separate the low byte.

The following arithmetic routines are implemented: (sort by priority, lowest first):

& !
logical AND bzw. OR

= < >
comparsion equal, greater, less

+ -
Addition, Subtraction

* /
Multiplication, Division

^
Exponent

The following functions are available:

( )
to change arithmetic priority

n(<ausdr>) or not(<ausdr>)
negates <ausdr>.

r(<label>) oder ref(<label>)
gives a boolean value. True if the label is referenced in the sourcecode

d(<label>) oder def(<label>)
gives a boolean value . True if the label is definited in the sourcecode

l(<string>) oder len(<string>)
gives the length of <string>

rnd(<ausdr>)
gives a random value from 0...<ausdr>

peek(<ausdr>)
gives the byte content of the memorylocation <ausdr>

deek(<ausdr>)
gives the word content of the memorylocation <ausdr> and <ausdr>+1

existf(<filename>)
gives 'true' if filename exists, 'false' if not.


Labels

A label must start with a letter and can be up to 32 bytes long. Labels are case sensitive.

standard label:

local label: local label out of macro range: variable label: A label at the beginning of a line is definited with the actual PC. Is a label located at the adresspart of a sourcecodeline it will be referenced. This circumstances can be asked with the functions REF() and DEF().


Warnings and errormessages

1000: 'no sourcefile specified!'
1001: 'error on opening sourcefile!'
1002: 'error on writing errorfile!'
1003: 'error on reading includefile!'
1004: 'error on reading sourcefile!'
1005: 'programcounter not defined!'
1006: 'error on writing bin-outfile!'
1007: 'error on closing bin-outfile!'
1008: 'outfile already open!'
1009: 'no outfile specified (missing file instruction)!'
1010: 'Divison by zero!'
1011: 'no numeric parameter found'
1012: 'no hex-digit'
1013: 'no bin-digit'
1014: 'number error'
1015: 'unknown pre-type (only :h and :l allowed)'
1016: 'error on writing listfile!'
1017: 'label double defined!'
1018: 'outfile not closed!'
1019: 'outfile already closed!'
1020: 'equ/epz/= needs label at linestart!'
1021: 'unknown hexstring digit!'
1022: 'opcode different!'
1023: 'exponent>15!'
1024: 'unknown label!'
1025: 'branch out of range!'
1026: 'opcode not found!'
1027: 'unknown opcode!'
1028: 'label not found!'
1029: 'error opening bget file!'
1030: 'wrong string delimiter!'
1031: 'too many recoursive if !'
1032: 'missing endif!'
1033: 'missing if for endif!'
1034: 'if construct must be absolute!'
1035: 'includefile already open!'
1036: 'error on opening includefile!'
1037: 'illegal OUT parameter!'
1038: 'line longer 250 bytes!'
1039: 'label longer 32 bytes!'
1040: 'too many symbols!'
1041: 'macro in macro!'
1042: 'missing mend!'
1043: 'too many macro lines!'
1044: 'too many macro sections!'
1045: 'too many macro parameters!'
1046: 'macroparameter not defined!'
1047: 'too many macroparameters!'
1048: 'no macro definition!'
1049: 'error on opening bin-outfile!'
1050: 'illegal SET parameter!'
1051: 'physical and logical org must be equal!'
1052: 'reloc already active!'
1053: 'relend without reloc!'
1054: 'org not allowed in reloc area!'
1055: 'local in macro section not allowed!'

1900..1931: 'system errors'


;********************************************************************
;a little example to see the principal structure of a sourcecodelist
;********************************************************************
 

;********************************************************************
;first assemble all include files:
;********************************************************************

          out lmn                     ;set options for the include outputlist
          set m                       ;set assembleroptions if needed for includes
          include peekpoke.src        ;load atari os labels

          out lmnop                   ;set options for the include outputlist
          set /m                      ;set assembleroptions if needed for includes
          include nextincl.src        ;...

;         ...                         ;more includes if needed

;********************************************************************
;set options fopr the following sourcefile:
;********************************************************************

          out lmn                     ;set options for the outputlist for the following sourcefile
          set m                       ;set assembleroptions if needed

;********************************************************************
; define Z-Page registers
;********************************************************************

          org $e0

reg1      wrd                      ;...
reg2      wrd                     ;...
color1    byt
color2    byt
arr1      spc 4                    ;4 byte long variable

;example to test z-page overflow:

          if *>$ff                 ;if programcounter (*) greater $00ff
          error Z-page overflow    ;do this line only if 'if' is true -> produces error message
          endif                    ;end of the if block
 

;********************************************************************
; programcode
;********************************************************************
 

          org $3000

progstart ldy #0
;         ...
          sta (reg1),y
progend

;********************************************************************
; filelinker definitions to save file
;********************************************************************

          file test.com           ;open file for binary output
          save $4000,$41FF        ;save block 1
          init $4000              ;start at init vector $4000
          save progstart,progend  ;save block 2 (
          put $9000,256           ;save block 3
          init $9000              ;start at init vector $9000
          exec progstart          ;run at $3000
          fend                    ;close file


00000000