This page (revision-8) was last changed on 03-Feb-2023 15:21 by Carsten Strotmann 

This page was created on 14-Mar-2010 18:44 by Carsten Strotmann

Only authorized users are allowed to rename pages.

Only authorized users are allowed to delete pages.

Page revision history

Version Date Modified Size Author Changes ... Change note
8 03-Feb-2023 15:21 59 KB Carsten Strotmann to previous
7 26-Dec-2010 10:59 59 KB Carsten Strotmann to previous | to last Synapse Assembler ==> Synapse Assembler Manual
6 14-Mar-2010 19:15 59 KB Carsten Strotmann to previous | to last
5 14-Mar-2010 19:14 59 KB Carsten Strotmann to previous | to last
4 14-Mar-2010 19:01 27 KB Carsten Strotmann to previous | to last
3 14-Mar-2010 18:48 5 KB Carsten Strotmann to previous | to last
2 14-Mar-2010 18:44 5 KB Carsten Strotmann to previous | to last
1 14-Mar-2010 18:44 5 KB Carsten Strotmann to last

Page References

Incoming links Outgoing links

Version management

Difference between version and

At line 443 changed one line
DISPLAY MEMORY: adrs1.adrs2 [RETURN] This command allows you to display the memory from address1 to address2.
DISPLAY MEMORY: adrs1.adrs2 ~[RETURN] This command allows you to display the memory from address1 to address2.
At line 546 added one line
!! SOURCE PROGRAM FORMAT
At line 548 added 659 lines
Source programs are entered a line at a time, with a five digit line number identifying each line. The line numbers may run from 00000 through 63999. Source program line numbers are kept sorted in line-number order; the numbers are used for editing purposes just as in BASIC. A blank must always follow the line number. After the blank, there are four fields of information: the label, opcode, operand, and comment fields. Adjacent fields must be separated by at least one blank.
Although the fields are not restricted to begin in any particular columns, it is convenient to enter them in this way for neatness. Therefore tab stops are built in to the SYNASSEMBLER at columns 9, 13, and 21.
! LABEL FIELD:
May be left blank, or may contain a label of from one to 32 characters. The first character of a label must be a letter; remaining characters may be either letters or numbers. Labels are used to name places in your program to which you will branch, as well as constants and variables.
The standard tab settings leave enough room for only 9 character labels; however, you can go ahead and use 32 characters as long as there is at least one space between the label and the opcode. If you like, you may type labels on a separate line, with the opcode and the following fields left blank. The label will be defined as the current value of the location counter. There are some examples of this in various listings throughout the manuals and in the example source code on the disk.
! OPCODE FIELD:
Contains a three-letter machine language mnemonic opcode, or assembler directive. However, opcodes may begin in any column after at least one blank from a label or two blanks from a line number.
! OPERAND FIELD:
Usually contains an operand expression of some sort. Some of the 6502 instructions have no written operand, such as NOP, BRK, DEX, and others. In these cases the comment field may be started right after the opcode. Four of the opcodes (ROL, ROR, ASL, and LSR) may be used both with and without an operand. If no operand is present, you must type at least TWO blanks before a comment with these four opcodes.
! COMMENT FIELD:
Comments are separated from the operand field by at least one blank. Actually, comments may begin earlier or later on the line, just so at least one blank separates them from the operand expression.
! COMMENT LINES:
Full lines of comments may be entered by typing an asterisk or a semi-colon (;) in the first column of the label field. This type of comment is useful in separating various routines from each other, and labeling their contents. It is analogous to the REM statement in BASIC.
! LABELS:
One to nine characters; the first character must be a letter, while the others may be either letters or digits. Labels must be defined somewhere in the program if they are to be used in an expression. In some cases they must be defined prior to use in expressions to prevent an undefined or ambiguous location counter. For example, if the expression in the operand field of an origin (".OR") directive is not defined prior to use, the assembler will not know how to define any subsequent labels.
A problem can occur if you postpone the definition of page-zero variables until after their use in operand expressions. If these labels are used with instructions which could assume both absolute and zero-page address modes, a discrepancy in the location count will occur between pass 1 and pass 2, of the assembler. This discrepancy cannot be detected by the present design of the assembler, so make it a habit to always define your page-zero variables at the beginning of your program.
There are two types of labels used in SYNASSEMBLER: normal labels and local labels.
! NORMAL LABELS:
The first character of a normal label must be a letter; subsequent characters may be letters, digits, or the period character (".") The period is useful for making long labels readable. For example, the subroutine used to read the next source line might be named "read.next.source.line".
Tab stops are set up within the editor assuming that most of your labels will be 9 characters or less. However, since the assembler is relatively free-formatt you may type any length label followed by a blank and the opcode, operand, and comment fields. Or, if you wish, you may type the long label on a line all by itself. In this form the label is assigned the current value of the location counter, just as if you had appended ".EQ" to the line.
{{{
01000 * SAMPLE PROGRAM WITH LONG LABELS
01010 SOURCE.LINE.POINTER .EQ $13 AND $14
01020 CHAR.POINTER .EQ $12
0l030 *
01040 READ.NEXT.CHAR.FROM.LINE
01050 LDY CHAR.POINTER
01060 LDA (SOURCE.LINE.POINTER),Y
01070 INC SOURCE.LINE.POINTER
01080 RTS
}}}
! LOCAL LABELS:
SYNASSEMBLER introduces a new kind of label called "local labels". The main purpose for the local labels is to make programs more readable by reducing the number of label names you must invent. As a side effect, local labels save considerable space in the symbol table during assembly; they only reqire two bytes each. The use of local labels also encourages structured programming habits.
Local labels have a period as the first character followed by one or two digits. Any label from .0 through .99 may be used.
The local label must be within a page of the normal label or an error will result.
Since each set of local labels is associated with a particular normal label, you may reuse the same local label
Here is an example of three little routines in the same source program using normal and local labels:
{{{
01000 PRINT.MESSAGE
01010 PHA SAVE A-REGISTER
01020 .1 JSR PRINT.CHARACTER
01030 INY
01040 LDA MESSAGES,Y
01050 BNE .1 =0 FOR END OF MESSAGE
01060 PLA RESTORES A-REGISTER
01070 RTS
01080 *
01090 GET.NEXT.CHARACTER
01100 LDY CHAR.POINTER
01110 LDA INPUT.BUFFER,Y
01120 CMP #RETURN
01130 BEQ .1 END OF LINE
01140 INC CHAR.POINTER
01150 .1 RTS
0ll60 *
01170 GET.NEXT.NONBLANK.CHAR
0ll80 .1 JSR GET.NEXT.CHARACTER
0ll90 BEQ .2 END OF LINE
01200 CMP #BLANK
01210 BEQ .1
01220 .2 RTS
}}}
!! OPERAND EXPRESSIONS
Operand expressions are written using terms and operators. The valid operators are + and -. Terms may be decimal numbers, hexidecimal, labels, or an asterisk (*). The first term in an expression may be preceded by a + or a - sign.
!! DECIMAL NUMBERS
Any number in the range from 0 through 65535, written in the normal way.
!! HEXIDECIMAL NUMBERS:
Any number in the range from $0 through $FFFF. Hexidecimal numbers are indicated by a preceding dollar sign ($), and may have from one to four digits. Beware of leaving out the dollar sign; the assembler may be quite satisfied to think of your hexadecimal number as a decimal one if you omit the ($). In some cases even a number with letters in it, such as 23AB, may be acceptable; it may be interpreted as decimal 23 and a comment "AB".
!! BINARY NUMBERS:
Any number in the range from 00000000 to 11111111. Binary numbers are indicated by the preceding percent (%) sign.
NUMBERS EXAMPLE:
{{{
Ok.
00010 * A DECIMAL NUMBER
4000: F1 00020 NUM1 .DA #241
00030 * A HEX NUMBER
4001: E3 00040 NUM2 .DA #$E3
00050 * A BINARY NUMBER
4002: D6 00060 NUM3 .DA #%11010110
00070 .EN
--- Symbol table ---
4000: NUM1
4001: NUM2
4003: NUM3
}}}
ASTERISK ~[*]:
Stands for, the current value of the location counter. This is useful for storing the length of a string as a constant in a program.
{{{
080A- 0B 1070 QT .DA #QTSZ # BYTES IN MSG
080B- 41 4E 59
080E- 20 4D 45
0811- 53 53 41
0814- 47 45 1080 .AS /ANY MESSAGE/
1090 QTSZ .EQ *-QT-1 # BYTES IN MSG
0816- 00 00 1100 VARW .DA 0 2-BYTE VARIABLE
0818- 00 1110 VARB .DA #0 1-BYTE VARIABLE
1120 HERE .EQ *
}}}
It is considered VERY POOR programming practice to include branch instructions in your program with operand expressions in the form "*-5" or "*+7". If you value your sanity and time, avoid them like the plague! They breed bugs that can be very difficult to find. Don't be afraid to use another label or two, no matter how silly the names might sound.
!! DIRECTIVES
Twelve assembler directives are available through SYNASSEMBLER.
.AS (stores ASCII literals.)
.AT (stores ATASCII literals)
.BS ~[expression]. (RESERVE ~[expression] bytes at the current location.
.DA ~[expression] enter data
.EN ENd of sources optional
.EQ ~[expression] (EQuate labels)
.HS (define Hex data)
.LI OFF (Turn off the assembly listing.)
.LI ON (Turn on the assembly listing.)
.IN ~[filename] .(Include a source program the specified file.)
.OR ~[expression] Indicates the originating address of your assembled code.
.TA ~[expression] (Target Address)
.TF ~[filename] --Put the object program on the specified file.
! ASCII STRING: .AS daaa...ad
The .AS directive stores the binary form of the ascii characters "aaa...a" in sequential locations beginning at the current location. If a label is present, it is defined as the address where the first character is stored. The string "aaa ... a" may contain any number of printing ASCII characters. You indicate the beginning and end of the string, by using any delimiter ("d" in the example), that you choose.
ASCII character codes are seven bit values. The .AS directive normally sets the high order bit (8th), to zero. Some people like to use ascii codes with the high order byte set to one, so SYNASSEMBLER includes an option for this.
.AS daaa....d sets the high order bits=0
.AS -daaa...d sets the high order bits=1
This syntax restricts the choice of the delimiter slightly, in that the delimiter can be any printing character other than a space or a minus sign. Since the Atari inverse characters are set with the high order bits to zero, you merely put the minus sign before the string and you will get the characters in inverse mode.
! ATASCII STRING: .AT daaa...ad
This is the same as .AS except that output is in ATARI ASCII.
! BLOCK STORAGE: .BS exp
Reserves a block of bytes at the current location in the program. The expression specifies the number of bytes to advance the location counter. If there is a label, it assigned the value at the beginning of the block.
The address of the beginning of the block will be printed in the address column of the assembly listing. If the object code is being stored directly into memory, no bytes are stored for the .BS directive. However, if the object code is being written on a file using the .TF directive, the .BS directive will write bytes on the file. All the bytes written will have the value of $00.
!DATA: label .DA expression (two bytes, LSB first)
.DA #expression (one byte, LSB of expression)
.DA /expression (one byte, MSB of expression)
Creates a constant or variable in your program. The value of the expression as one or two bytes, is stored at the current location. If a label is present, it is defined as the address where the first byte of data is stored.
{{{
4000: 0A 00 64
4003: 00 E8 03
4006: 10 27 00020 DEC.NUM .DA 10,100,1000,10000
4008: 64 00030 VALUE .DA #100
4009: FB 00040 VAL2 .DA #-5
400A: FF 00050 VAL3 .DA #$FF
--- Symbol table ----
4000: DEC.NLM
4009: VAL2
400A: VAL3
4008: VALUE
}}}
! END OF PROGRAM: .EN
This defines the end of the source program. You would normally make this the last line, but you may place it earlier in order to assemble only a portion of the source program. If no .EN is present anywhere in your program, the assembler will assume you meant to put this the last line.
!EQUATE: label .EQ [expression]
Defines the label to have the value of the expression. If the expression is not defined, an error message is printed (UNDEFINED LABEL), and the offending line is listed out. If you neglect to use a label with an equate directive an error message (UNDEFINED LABEL), is printed. In either case, the assembly is aborted so that you can correct the error. All page zero references must be made before they are used or all labels defined after that reference will be off by 1.
EXAMPLE
{{{
00020 .OR $80
0080: 00030 NUM1 .BS 1
0081: 00040 NUM2 .BS 1
0082: 00050 TABLE1 .BS 1
00E6: 00060 ADR .BS 100
00070 .OR $4000
00080 * main program *
--- Symbol table ---
00E6: ADR
0080: NUM1
0081: NUM2
0082: TABLE1
}}}
! HEX STRING: label .HS hhh...h
Converts a string of hex digits (hhh...h) to binary, two digits per byte, and stores them starting at the current location. If a label is present, it is defined as the address where the first byte is stored. If you do not have an even number of hexadecimal digits, the assembler aborts with an error message, (BAD ADDRESS), and lists the offending line. NOTE: Unlike hexadecimal numbers used in the operand expressions you must NOT use a dollar sign with the .HS directive.
!LISTING CONTROL: .LI OFF and .LI ON
This pair of directives turns the assembly listing on and off. If .LI OFF is put at the beginning of the source program, and no LI ON is used, no listing at all will be produced. The program will assemble much faster without a listing, as most of the time is consumed putting the characters on the screen, and scrolling the screen up.
If you put .LI OFF at the beginning of your source program and .LI ON at the end, only the alphabetized symbol table will print.
You may also use this pair of directives to bracket any portion of the listing you may wish to see or not see.
!INCLUDE: .IN [file name]
Causes the contents of the specified source file to be included in the assembly.
The program which is in the memory at the time the ASM command is typed is called the "root" program. Only the root program may have .IN directives in it. If you attempt to put .IN directives in an included program, the "NESTED INCLUDE FILE" error will print.
When the .IN directive is processed the root program is temporarily "hidden" and the included program is loaded. Assembly then continues through the included program. When the end of the included program is reached, it is deleted from memory and the root program is restored. Assembly then continues with the next line of the root program.
The .IN directive is useful in assembling extremely large programs which cannot fit in memory all at once. It is also useful for connecting a library of subroutines with a main program.
The ~[filename] portion of the directive is in standard FILESPEC format.
{{{
00020 * START OF PROGRAM
00030 .OR $5000
00040 .IN "D:PART1"
00050 .IN "D:PAPT2"
00060 .IN "D:PART3"
00070 .EN
}}}
! ORIGIN: .OR
This sets the program origin and the target address to the value of the expression. Program orign, is the address at which the object program will be executed. Target address is the address is the memory address at which the object program will be stored during the assembly. The .OR directive sets both of these addresses to the same value, which is the normal way of operating. If you do not use the .OR directive the assembler will set both the program origin and the target address to $4000. If the is not defined during SYNASSEMBLERS pass 1 prior to it's use in the .OR directive, an error message is printed and assembly is aborted. The error message that appears is "UNDEFINED LABEL" and the offending line is listed for easy editing.
!TARGET ADDRESS: .TA [expression]
Sets the target address at which the object code will be stored during assembly. The target address is distinct from the program origin (which is either set by the .OR directive or default at $4000). The .OR directive directive as we have seen, sets both the origin and target address. The .TA directive allows the added control of setting only the target address. Object code is produced and ready to run at the program origin, but is stored starting at the target address.
!TARGET FILE: .TF [filename]
Causes the object code generated to be stored an a binary file rather than in memory. Only the code which follows the .TF directive will be stored on the file. Code will be stored on the file until another .TF directive is encountered, or until a .TA or .OR directive is encountered. The [filename] format is the standard ATARI filespec format.
When you wish to assemble a program which will execute at an address normally occuppied by the assembler ($9C00 through $C000) or an already resident source program, you need to use the .TA and the .OR directives. Set the origin first, using the .OR directive and then set the target address to a safe value using the .TA directive. It is always safe to start the target area at $4000.
{{{
00010 * SAMPLE PROGRAM TO ILLUSTRATE
00020 * THE .TA DIRECTIVE
00030 .OR $1000
00040 .TA $4000
1000: AD 0C 10 00050 MAIN LDA TEMP.A
1003: AE 0D 10 00060 LDX TEMP.X
1006: AC 0E 10 00070 LDY TBIP.Y
1009: 4C 00 10 00080 JMP MAIN
100C: 32 00090 TEMP.A .DA #50
100D: 64 00100 TEMP.X .DA #100
100E: 22 00110 TEMP.Y .DA #34
--- Symbol table ---
1000: MAIN
100C: TEMP.A
100D: TEMP.X
100E: TEMP.Y
}}}
As you can see in the example, the assembly language listing looks as though the program was stored at $1000. However, the object code is actually stored at $4000, which is the target address set in the .TA directive. If we disassemble memory starting at $4000, we see:
{{{
Ok
MON
Zynapse monitor
[*] Ok
4000L
4000: AD 0C 10 LDA $100C
4003: AE 0D 10 LDX $100D
4006: AC 0E 10 LDY $100E
4009: 4C 00 10 JMP $1000
400C: 32 ???
400D: 64 ???
400E: 22 ???
400F: 00 BRK
4010: 00 BRK
4011: 00 BRK
4012: 00 BRK
}}}
After the assembly is complete, there are several ways to position the code in memory where it really should be. You can save the object code on cassette or disk from its current location and reload it at the correct location for execution. Be sure not to reload it while executing the assembler or you may clobber it.
Another method is to enter the monitor and use the monitor move command (addr1 addr2.addr3M). This command will move the block of memory from addr2 through addr3 to the area beginning at addr1.
!! ADDRESSING MODES
The MOS Technology 6502 microprocessor used in the ATARI has many great features; one of the greatest is its variety of addressing modes. There are thirteen different modes in all, though no single opcode can use every one of them. The chart in the appendix shows which modes can be used with each opcode. But first, here is a chart showing an example of each mode and the way it is written in assembly language.
| MODE | EXAMPLE
| Implied | DEX at least two blanks
| Accumulator | ROL before comments begin
| Relative | BNE expr
| Immediate | LDA #expr
| | LDA /expr
| Zero Page | LDA expr
| Absolute | LDA expr Assembler uses
| Zero Page,X | LDA expr,X Zero Page form
| Absolute,X | LDA expr,X if possible;
| Zero Page,Y | LDA expr,Y if not, it uses
| Absolute,Y | LDA expr,Y Absolute form.
| (Zero Page,X) | LDA (expr,X)
| (Zero Page),Y | LDA (expr),Y
| (Absolute) | JMP (expr)
For a full explanation of the modes and how to use them, I refer you to the MOS Tecnology Hardware and Programming Manuals, as well as the other references mentioned in the bibliography in Appendix IV.
SYNASSEMBLER has one syntactical addition. The immediate mode may be indicated by either a pound sign (#) or a slash (/). The "#" means that the least significant byte of the 16-bit expression value should be used.
The "/" means that the most significant byte should be used.
One use for this feature is in setting up the address of a subroutine or a buffer in a pointer. (A pointer is a pair of bytes containing an address which "points" at a subroutine or into a buffer.) For example:
{{{
0080: 00010 ADR .EQ $80
4000: A9 0D 00020 START LDA #SOUND
4002: 85 80 00030 STA ADR
4004: A9 40 00040 LDA/SOUND
4006: 85 81 00050 STA ADR+1
4008: A0 00 00060 LDY #0
400A: B1 80 00070 LDA (ADR),Y
400C: 00 00080 BRK
400D: 10 20 50 00090 SOUND .HS 102050
4010: 20 40 90 00100 .HS 204090
--- Symbol table ---
0080: ADR
400D: SOUND
4000: START
400D: SOUND
}}}
Trying to comprehend and remember thirteen different addressing modes can be very difficult; therefore it is convenient to try to group them into categories. You may wish to consider the following breakdown: implied mode, relative mode, and other modes. "Other" modes now includes eleven modes, so you can break it down further: accumulator, immediate, direct, and indirect. Each of direct and indirect modes can be either indexed or not indexed, and either Zero page or Absolute. The following outline will give you a better idea of what has been described:
{{{
I. Implied
II. Accumulator
III. Direct
A. Not Indexed
1. Zero Page
2. Absolute
B. Indexed by X-register
1. Zero Paqe,X
2. Absolute,X
C. Indexed by Y-register
1. Zero Page,Y
2. Absolute,Y
IV. Indirect
A. Not Indexed - (Absolute)
B. Indexed by X-register
(Zero'Page,X)
C. Indexed by Y-register
(Zero Page),Y
}}}
! IMPLIED MODE
In this mode, the address is implied by the nature of the instruction; the operand field is left blank. All of the opcodes in this class are only one byte long. They are:
{{{
BRK DEX PHA RTS TAY
CLC DEY PHP SEC TSX
CLD INX PLA SED TXA
CLI INY PLP SEI TXS
CLV NOP RTI TAX TYA
}}}
! RELATIVE MODE
This mode is used only by the conditional branch instructions. The expression is converted to a signed offset from the location following the branch instruction. The result must be in the range from -128 through +127 to be legal. All of these instructions occupy two bytes. They are:
{{{
BCC/BGE* BEQ BNE BVC
BCS/BLT* BMI BPL BVS
}}}
* you may use either form for greater than/less than branches.
! OTHER MODES
Usage of the other eleven modes is much more complex. The table in the appendix shows which modes are defined for each of the remaining opcodes. These instructions occupy one byte in the accumulator mode, two bytes in any zero page modes, and three bytes in any of the absolute modes. They are:
{{{
ADC AND ASL BIT CMP
CPX CPY DEC EOR INC
LDA LDX LDY LSR ORA
ROL ROR SBC STA STY
STX JMP JSR
}}}
You might notice especially that only four opcodes are usable in the accumulator mode (ASL, LSR, ROL, ROR); that only two opcodes use the "ZP,Y" mode (LDX and STX), and that only one opcode uses the indirect absolute non-indexed mode (JMP).
!! DEBUGGING PROGRAMS
Each step ("S") command decodes, display,s and executes one instruction at a time, and the trace ("T") command quickly steps through a program, stopping when a BRK instruction is executed.
Each step command causes the monitor to execute the instruction in memory pointed to by the program pointer. The instruction is displayed in its disassembled form, then executed. The contents of the 6502's internal registers are displayed after the instruction is executed. Then the program counter is bumped up to point to the next instruction in the program.
Here's what happens when you list and then step through a sample program:
{{{
Ok.
MON
Zynapse monitor
[*] Ok.
4000L
4000: A9 05 LDA #$05
4002: 0A ASL
4003: 0A ASL
4004: 8D 00 20 STA $2000
4007: 00 BRK
4008: 00 BRK
*
*
*
4015: 00 BRK
4016: 00 BRK
[*] Ok.
}}}
!STEP EXAMPLE:
{{{
[*] Ok.
4000S
4000: A9 05 LDA #$05
A=05 X=00 Y=00 P=30 S=FD
[*] Ok.
S
4002: 0A ASL
A=0A X=00 Y=00 P=30 S=FD
[*] Ok.
200
0200: 90
[*] Ok.
S
4003: 0A ASL
A=14 X=00 Y=00 P=30 S=FD
[*] Ok.
S
4004: 8D 00 20 STA $2000
A=14 X=00 Y=00 P=30 S=FD
[*] Ok.
2000
2000: 14
[*] Ok.
S
4007: 00 BRK
A=14 X=00 Y=00 P=30 S=FD
[*] OK.
}}}
!TRACE EXAMPLE:
{{{
Ok.
MON
Zynapse monitor
[*] Ok.
4000T
4000: A9 05 LDA #$05
A=05 X=00 Y=00 P=30 S=FD
4002: 0A ASL
A=0A X=00 Y=00 P=30 S=FD
4003: 0A ASL
A=14 X=00 Y=00 P=30 S=FD
4004: 8D 00 20 STA $2000
A=14 X=00 Y=00 P=30 S-FD
4007: 00 BRK
A=14 X=00 Y=00 P=30 S=FD
[*] Ok.
}}}
!EXAMINING AND CHANGING REGISTERS
The EXAMINE command is invoked by pressing "R" which tells the monitor to display the contents of the five 6502 registers on the screen. To change these values, type the semi-colon and the new values:
{{{
[*] Ok.
R
A=0A X=FF Y=D8 P=B0 S=F8
*;B0 02
R
A=B0 X=02 Y=D8 P=B0 S=F8
}}}
!! Appendix
!MONITOR TRICKS
There are few tricks that you can use in the ZYNAPSE monitor. These will generally make your life easier and programming less of a chore. All monitor commands may be put on a single line if you separate the commands with a space.
{{{
EXAMPLE: D01F D01F D01F
}}}
This will display memory location D01F 3 times.
Some commands are only one letter long, so you needn't separate them with a space.
{{{
EXAMPLE: 2000LLLL
}}}
This will disassemble 80 instructions
Sometimes you may need to utilize certain commands repeatedly. You can do this by typing the command many times, or type it once and tell the monitor to repeat it for you.
{{{
EXAMPLE: N 2FC AD;0N
}}}
This will display location 2FC until
~[BREAK] or ~[SYSTEM RESET] is pressed.
!SYNASSEMBLER Memory Map
(assumes 48K memory)
{{{
0000-00EF : O.S. and Assembler zero page usage.
00F0-00FF : Free space
0100-01FF : 6502 hardware stack
0200-02FF : Operating System vector table
0300-03FF : IOCB vector table
0400-047F : DOS usage area
0480-04FF : Assembler usage
0500-05FF : Assembler input buffer
0600-06FF : Free space (if REPlace not used)
0700-1D00 : DOS II
1D00-9BFF : Free space for source, symbol table, and object code
9C00-BC1F : SYNASSEMBLER
BC20-BFFF : Screen display list and data
}}}
!CONVERTING ATARI ASSEMBLER FILES
In order, to convert your ATARI Assembler/Editor files to SynAssembler format follow these simple instructions:
.Read the ATARI editor/assembler files into the SynAssembler using the ENTer command.
.Save the file back to the disk using the SAVE command. This will store your file in compacted format.
.Make the following changes to your source code:
# Remove all references to "A". For example, in the instruction LSR A, the "A" should be removed, since SynAssembler assumes the "A" reference.
# SynAssembler has no multiply or divide so these must be put in by long hand.
# To get the Hi and Lo bytes, make the following changes:
Atari Assembler
{{{
LDA #PLACE/256 high byte
LDA #PLACE&255 lo byte
}}}
SynAssembler
{{{
LDA /PLACE high byte
LDA #PLACE lo byte
}}}
4. All of the Atari directives must be changed to the SynAssembler equivalents.
Now that you have your file in SynAssembler format, you may use the local labels and long 32 character labels.
!BIBLIOGRAPHY
Publishers have begun to release some good technical resource books for learning to program the 6502 microprocessor.
The ATARI Assembler, Don Inman & Kurt Inman. RESTON Publishing Company, 1981. Designed for the beginner to intermediated this book has 270 pages including many illustrations, diagrams and examples. $12.95
6502 Software Design, Leo J. Scanlon. One of the Blacksburg Continuing Education Series, published by Howard W. Sams & Co.,1980. 270 pages, paper, $10.50.
6502 Assembly Language Programming, Lance A. Leventhal. Osborne/McGraw Hill, Inc., 1979, over 80 programming examples. $16.99
Programming and Interfacing the 6502, with Experiments, Marvin L. DeJong. One of the Blacksburg Continuing Education Series, published by Howard W. Sams & Co., 198O. 414 pagest paperback.
6502 Software Gourmet Guide and Cookbook, Robert Findley. Scelbi Publications, 1979. 204 pages, paperback. Includes listings of conversion routines, search and sort routines, and floating point routines.
6502 Games, Rodney Zaks, SYBEX. The third in the SYBEX series on programming the 6502. Includes listings of games in assembly language.
Practical Microcomputer, Programming: the 6502, W.J. Weller, Northern Technology Books, 1980. 459 pages, includes a listing of a 6502 assembler and a debugging package.
!Instruction Code Table
{{{
==================================================================
ACCUM- IMMED- DIRECT INDIRECT
ULATOR IATE INDEXED INDEXED
-------------------------------------------------------------------
blank #expr expr expr,X expr,Y (expr) (expr,X) (expr),Y
/expr ZP/ABS ZP/ABS ZP/ABS
========================================================================
ADC -- 69 65/6D 75/7D --/79 -- 61 71
AND -- 29 25/2D 35/3D --/39 -- 21 31
ASL 0A -- 06/0E 16/1E --/-- -- -- --
BIT -- -- 24/2C --/-- --/-- -- -- --
CMP -- C9 C5/CD D5/DD --/D9 -- C1 D1
CPX -- E0 E4/EC --/-- --/-- -- -- --
CPY -- C0 C4/CC --/-- --/-- -- -- --
DEC -- -- C6/CE D6/DE --/-- -- -- --
EOR -- 49 45/4D 55/5D --/59 -- 41 51
INC -- -- E6/EE F6/FE --/-- -- -- --
LDA -- A9 A5/AD B5/BD --/B9 -- Al B1
LDX -- A2 A6/AE --/-- B6/BE -- -- --
LDY -- A0 A4/AC B4/BC --/-- -- -- --
LSR 4A -- 46/4E 56/5E --/-- -- -- --
ORA -- 09 05/0D 15/1D --/19 -- 01 11
ROL 2A -- 26/2E 36/3E --/-- -- -- --
ROR 6A -- 66/6E 76/7E --/-- -- -- --
SBC -- E9 E5/ED F5/FD --/F9 -- E1 F1
STA -- -- 85/8D 95/9D --/99 -- 01 91
STX -- -- 86/8E --/-- 96/-- -- -- --
STY -- -- 84/8C 94/-- --/-- -- -- --
========================================================================
JMP -- -- --/4C --/-- --/-- 6C -- --
JSR -- -- --/20 --/-- --/-- -- -- --
}}}