6502 code assembler (6502ca)

18
6502 Code Assembler (6502CA) Version 1.3.5 Written by M.Davies

Upload: others

Post on 23-Dec-2021

36 views

Category:

Documents


0 download

TRANSCRIPT

Page 1: 6502 Code Assembler (6502CA)

6502 Code Assembler

(6502CA) Version 1.3.5

Written by M.Davies

Page 2: 6502 Code Assembler (6502CA)

Table of Contents Overview ........................................................................................................................................... 3

Editor ................................................................................................................................................ 4

Command-line Switches & Parameters .............................................................................................. 5

Labels & Variables ............................................................................................................................. 6

Variables (Symbols) ....................................................................................................................... 6

Labels ............................................................................................................................................ 7

Using a variable ............................................................................................................................. 8

Restrictions ................................................................................................................................... 9

Number types & Maths ................................................................................................................... 10

Number Types ............................................................................................................................. 10

Maths & Calculations ................................................................................................................... 11

Order of operator precedence ................................................................................................. 12

Macros ............................................................................................................................................ 13

Assembler Commands ..................................................................................................................... 16

Assert .......................................................................................................................................... 16

Include ........................................................................................................................................ 16

IncludeRoot ................................................................................................................................. 16

Import ......................................................................................................................................... 17

Fill ............................................................................................................................................... 17

Copy ............................................................................................................................................ 18

End .............................................................................................................................................. 18

SetMacro and ! ............................................................................................................................ 18

Page 3: 6502 Code Assembler (6502CA)

Overview

6502 Code Assembler (6502ca for short) is a 6502 code cross-assembler for Microsoft Windows.

It's primarily designed to be useful for those who wish to create their own "home brew" single-board

computers based on the 65c02 processor, but can be used to write application code to work in

assemblers or even old hardware.

Current Capabilities

Assemble all 6502 & WDC 65c02 instructions (complete)

All 6502 & WDC 65c02 addressing modes available (complete)

Support for data-type commands: String, Byte, Word (2 bytes), Double Word (4 bytes)

Labels & variables (both are treated the same)

Macros for repeating code easily

Ability to "Include" other source files so you can sub-divide source code into different files

Simple math supported on assemble: Add, Subtract, Multiply, Divide (integer and decimal), Mod

(remainder), OR, AND, XOR (EOR)

Command-line switches available to allow the following:

Save only a section of memory rather than the entire 64KB upon completion

Automatically overwrite existing binary file

Assemble (list in display), but do not save the resulting binary file

Pause at the end of assembly, but before 6502ca ends

Show variables, opcodes and macros created during the assembly process

Pipe the listing to a file (by default this goes to the display)

Multiple installation methods: Manual install, Single computer install, Mass deployment (GPO

deployable msi)

Command-line switches available for silent install

Page 4: 6502 Code Assembler (6502CA)

Editor

6502 Code Assembler is command-line based program and so does not come with a built-in editor.

As such, you need to use a text editor such as Notepad, Notepad++, etc.. Be sure to use an editor

that saves in basic text (ANSI).

My recommendation is to use Notepad++ as it has many capabilities and you can use the 6502CA

language extension which I’ve written. That can be downloaded from

https://6502ca.net/index.php?Editor

Installation instructions:

• Open notepad++

• Click the Language drop down menu

• Click User Defined Language

• Click Define Your Language

• Click Import

• Select the unzipped notepadplusplus_6502ca.xml file

• Close notepad++ and then reopen it

• Click the Language drop down menu

• Click User Defined Language

• Click 6502ca

When you save a file with the .6502ca file extension it will apply colour codes to your source code.

Here’s an example of the colour coding once the 6502CA language extension is installed:

Page 5: 6502 Code Assembler (6502CA)

Command-line Switches & Parameters

6502 Code Assembler supports a number of useful command-line switches. A list can be obtained by

typing ‘6502ca /?’ in a Command Prompt or PowerShell window once 6502ca is installed.

Syntax:

6502ca <source file> (options – see below)

Switch/parameter Description <source file> File which contains the 6502/65C02 source code to be assembled /o= Specify the output binary (object) code filename. If not specified then <source file> with an extension of .bin is assumed. Examples: /o=myfile.bin /overwrite= If the binary output file already exists then automatically overwrite or not

without asking Examples: /overwrite=y /overwrite=n /nobinary Do not attempt to output the binary file /debug Wait for a key to be pressed just before exiting after all operations have been

completed /range= Set the memory range (in hex, but without hex symbols) to be outputted to

the binary file Example: /range=3000-4000 /ver Show program version /console= Send the console (display) output to a file instead of the console window Example: /console=myoutput.txt /showvars At the completion of assembly show the value of all variables & labels /showopcodes Displays the opcodes file. All other switches are ignored. /showmacros At the completion of assembly show any macros declared and what they are

set to

Example usages:

6502ca mysrc

Assemble the source file mysrc.6502ca and output the binary file to mysrc.bin

6502ca mysrc.txt

Assemble the source file mysrc.txt and output the binary file to mysrc.bin

6502ca mysrc /o=obj.bin

Assemble the source file mysrc.6502ca and output the binary to obj.bin

6502ca mysrc /range=4000-4fff /console=mysrcout.txt

Assemble the source file mysrc.6502ca and output the binary to mysrc.bin, but only

6502 memory range $4000 to $4fff resulting in a mysrc.bin being a 4096 byte file.

The console output (the assembly listing) will be sent to the mysrcout.txt file and not

displayed.

Page 6: 6502 Code Assembler (6502CA)

Labels & Variables

Variables (Symbols)

6502ca supports up to 4000 variables (actually, these are symbols rather than variables, but I

refer to them as variables... because I wish to :) ).

Assigning (or re-assigning) a variable

To create a new variable simply type the name, put an equals sign and then the value. The

same as most other programming languages

Examples: OSroutineAddress = $4000

HelpCommand = "HELP"

To reassign the variable to a different value you just do the same.

Example: MyTestValue = 45

MyTestValue = Hello World

All variables, including numbers, are stored as strings. When the assembler encounters one

during assembly, it simply swaps the variable name for what the variable is set to.

Example: mydata = 65

LDA #mydata

Would convert to the follow and then be assembled in machine code: mydata = 65

LDA #65

When assigning a string, leading spaces between the ‘=’ sign and the value are removed as

are trailing spaces. If you need to include either category then encompass the string in a pair

of double quotes.

Example: Mydata = Hello World

Would result in mydata being set to ‘Hello World’

Mydata = " Hello World "

Would result in mydata being set to ‘ Hello World ’

To include a double quote and it be counted as part of the string, put two double quotes.

These will be treated as a single double quote.

Example:

Page 7: 6502 Code Assembler (6502CA)

Labels

Labels are actually variables, but are set by either putting a full stop (a period for those in the

U.S.) and then the label name -or- putting the label name then a colon. This will cause a

variable to be created (or have its value reassigned if it already exists) and the value set to the

current assembly address.

Example:

pc = $5000 ; you can use .org $5000 instead

LDX #10

.loop

INX

BNE loop

Would result in:

LDX #10 being assembled at $5000 & $5001

A label called "loop" being created and assigned the value of $5002

INX being assembled at $5002

BNE being assembled at $5003 & $5003, with the value in $5003 being an offset pointing to

the value of "loop" which, when calculated, points to $5002

Example:

pc = $5000 ; you can use .org $5000 instead

LDX #10

loop:

INX

BNE loop

Would result in:

LDX #10 being assembled at $5000 & $5001

A label called "loop" being created and assigned the value of $5002

INX being assembled at $5002

BNE being assembled at $5003 & $5003, with the value in $5003 being an offset pointing to

the value of "loop" which, when calculated, points to $5002

Page 8: 6502 Code Assembler (6502CA)

Using a variable

This works in the same way as any other language or script. Simply assign the variable (or

label) and then refer to it in another statement

Examples:

HW=Hello world

pc=$4000 ; you can use .org $4000 instead

EQUS HW

ALUE=42

pc=$4000 ; you can use .org $4000 instead

LDX #ALUE

A=5

B=10

C=2

pc=$4000 ; you can use .org $4000 instead

LDY #A+B*C ; this calculates as 5+(10*2) = 5+20 = 25

Page 9: 6502 Code Assembler (6502CA)

pc=$4000 ; you can use .org $4000 instead

temp = $e00

LDA age

STA temp

RTS

pc=$A01E ; you can use .org $A01E instead

.age

EQUB 21

Restrictions

Variable names must not contain any special character. These include:

! " # $ % ' ( ) * + , - . / : ; < = > ? @ \ ^

Variables may also not be named the same as any 6502 instruction (mnemonic) or assemble

reserved command.

Page 10: 6502 Code Assembler (6502CA)

Number types & Maths

Number Types

Three number types are supported: Decimal, Hexadecimal, Binary.

Hexadecimal numbers are, by default, designated by $, but can be set to & by using the

ASSERT command.

Examples:

x = $D0

JMP $4000

EQUW $A97F

ASSERT &

LDA #&7A

ASSERT $

LDA #$7B

Binary numbers are designated by %, with the most significant bit on the left and the least

significant bit on the right.

Examples:

index = %1001

LDA #%11000100

STX %100010

JMP %1011110000011100

The above is the equivalent of:

index = 9

LDA #196

STX 34

JMP 48156

Page 11: 6502 Code Assembler (6502CA)

Maths & Calculations

The following basic calculation & bitwise operators are available:

Action Symbol Example(s)

Multiply * x = 77 * 9 (would result in 693)

Divide (decimal) / d = 221 / 128 (would result in 1.7265625)

Divide (integer) \ d = 221 \ 128 (would result in 1)

Mod (remainder) mod r = 221 mod 128 (would result in 93)

Add + a = 23 + 99 (would result in 122)

Subtract - s = 23 - 99 (would result in -76)

Bitwise OR || o = 55 || 99 (would result in 119)

Bitwise AND && a = 55 && 99 (would result in 35)

Bitwise XOR (EOR) ~ x = 55 ~ 99 (would result in 84)

Calculations can be used anywhere, in any combination, and with a mixture of numbers and

variables.

Here are some further examples:

...would result in : LDA #16 adj = $100

STX $8000 + adj

...would result in : STX $8100

mycalc = 77 && 88

...would result in : mycalc = 72

divresult = 192 \ 128

remresult = 192 MOD 128

...would result in : divresult = 1 and remresult = 64 (There is one 128 in 192 and the

remainder is 64 after that)

divresult = 192 / 128

...would result in : divresult = 1.5 (decimal divide)

varA = 100

varB = 77

VarC = 10

JMP $1000 + VarA + VarB * VarC

...would result in : JMP $1366 (see order of operator precedence below as to why it's $1366

rather than $10B10)

Page 12: 6502 Code Assembler (6502CA)

Order of operator precedence Calculations within a given source code line are done as follows with the upper most ones done first: Multiplication

Division (decimal) Division (integer) Remainder (mod) Addition Subtraction Bitwise OR Bitwise AND Bitwise XOR

Example:

result = 99 + 5 * 10 / 4

EQUS result

...would result in:

99 + ((5 * 10) / 4)

= 99 + (50 / 4)

= 99 + 12.5

= 111.5

And would assemble as:

EQUS "111.5"

Page 13: 6502 Code Assembler (6502CA)

Macros

6502CA has a basic macro system which allows you to easily repeat code sections without

having to type them each time in your source code. All you need to do is declare the section

of code using the #setmacro reserved assembler command and then call the code with the ‘!’

command whenever you wish to repeat the code.

The system has a limit of 500 macros with 20 commands & 10 parameters per macro.

Syntax:

SetMacro <macro name> = <command>(@n)( | <command>(@n) | … )

!<command> (<parameter 1> (A<parameter 2> … ))

Example code:

; main code

#setmacro stacksave = PHA | PHX | PHY | PHP

#setmacro stackrestore = PLP | PLY | PLX | PLA

(some commands)

JSR mysubroutine

(more commands)

JSR anothersubroutine

RTS

; sub routines to do some stuff - each saves the

; registers & flags at the beginning and restores them

; afterwards

mysubroutine:

!stacksave

(commands)

!stackrestore

RTS

anothersubroutine:

!stacksave

(commands)

!stackrestore

RTS

Note that the above doesn't JSR, BRA or JMP to the macro commands; The assembler inserts

the commands to be assembled from the given macro as if they'd been typed in instead of the

! command.

Page 14: 6502 Code Assembler (6502CA)

Example:

#setmacro test=INX | LDA data,X

!test

INY

!test

...would assemble as:

INX

LDA data,X

INY

INX

LDA data,X

A feature of the macro system is the ability to pass parameters using the @ symbol. This

allows data to be supplied to the macro system when calling a given macro. Parameters are

declared within the #setmacro command by putting @ followed by a number between 0 and

9 representing the parameter number. When the ‘!’ command is used the parameters are then

listed after the macro name, ordered 0 to 9 separated by a pipe '|' character .

Example:

#setmacro test=LDA @0 | STA @1

LDX #0

!test #$7A | $900

!test #$23 | $901

RTS

...would assemble as:

LDX #0

LDA #$7A

STA $900

LDA #$23

STA $901

RTS

Note: Neither macro command is processed at all for variable names or maths. Such

processing is done on the commands inserted by the ‘!’ command.

Some useful macros:

bit0 = 1

bit1 = 2

bit2 = 4

bit3 = 8

bit4 = 16

bit5 = 32

Page 15: 6502 Code Assembler (6502CA)

bit6 = 64

bit7 = 128

#setmacro setbit = ORA @0

#setmacro flipbit = AND @0 ~ $FF

#setmacro clearbit = AND @0 && $FF

Some examples of how to use the above:

LDA #2

!setbit #4

Load 2 in to the A register (binary : 0000 0010)

Set bit 2 (which represents the value 4) of the A register (bit 2 in binary : 0000 0100)

Which results in A being 6 (binary : 0000 0110)

LDA #6

!clearbit #4

Load 6 in to the A register (binary : 0000 0110)

Clear bit 2 (which represents the value 4) of the A register (bit 2 in binary : 0000 0100)

Which results in A being 2 (binary : 0000 0010)

LDA #255

!flipbit #bit6

!flipbit #bit6

Load 255 in to the A register (binary : 1111 1111)

Flip bit 6 (which represents the value 64) of the A register to 0 (bit 6 in binary : 0100 0000)

Which results in A being 191 (binary : 1011 1111)

Flip bit 6 of the A register back to 1

Which results in A being 255 again (binary : 1111 1111)

Notice with that last example we used the variable 'bit6'. That variable is set to 64 which is

the value of bit 6. We could have used the number '64' instead of 'bit6' in the ! command, but

'bit6' more easily tells whoever is viewing the code that you're referring to bit 6.

Nesting Macros:

Macros can be nested to a depth of 20, allowing one macro to call another and that to call yet

another, and so on. The only restrictions are the nest (depth) limit of 20 and that a macro (or

any macros it calls) cannot call itself as this would cause a loop.

Example:

#setmacro LCD_E_set = LDA LCD_E_PORT | ORA #LCD_E | STA LCD_E_PORT

#setmacro LCD_RS_set = LDA LCD_RS_PORT | ORA #LCD_RS | STA LCD_RS_PORT

#setmacro LCD_RW_set = LDA LCD_RW_PORT | ORA #LCD_RW | STA LCD_RW_PORT

#setmacro LCD_CheckBusy = !LCD_E_set | !LCD_RS_set | !LCD_RW_set

Page 16: 6502 Code Assembler (6502CA)

Assembler Commands

The assembler has a number of built-in reserved commands. Apart from the '!' command, all

others need to start with a '#'.

Assert

The Assert command is used to control which character is used ot prefix hexadecimal value.

It's restricted to & and $. By default, 6502CA assumes $.

Syntax:

#ASSERT <character>

Examples:

#ASSERT &

#ASSERT $

Include The Include command is used to insert the source code from other files. This allows you to split a project into different files and allows for easier. The filename parameter can, optionally, be encased in double quotes if it contains spaces, otherwise only the first word will be used.

Syntax:

#INCLUDE <filename>

Examples: #INCLUDE "LCD routines.6502ca"

#INCLUDE SerialComms.6502ca

IncludeRoot The RootInclude command is used to set the path where a project’s include files are located. The path specified is prepended to the filename in any Include commands. The path parameter can, optionally, be encased in double quotes if it contains spaces, otherwise only the first word will be used. If '\' is not included at the end of path then one is added automatically.

Syntax:

#INCLUDEROOT <path>

Examples:

Page 17: 6502 Code Assembler (6502CA)

#INCLUDEROOT "c:\myproject\my includes\"

#INCLUDEROOT \\mynas\common_includes

Import The Import command instructs the assembler to import a binary file into the 6502 memory map at assembly time. You can optionally specify where in the imported file to start importing to (starting byte is address 0) and you can also specify the end byte. This allows a section of a file to be imported if desired.

Syntax:

#IMPORT <filename> <import address>

#IMPORT <filename> <import address> <file from-address>

#IMPORT <filename> <import address> <file from-address> TO <file to-address>

Examples: #IMPORT "memory-map-template.bin" $0

#IMPORT "RAMmap.bin" $3000 $1000

#IMPORT "RAMmap.bin" $3000 $1000 TO $9fff

Fill

Fill allows you to fill a section of 6502 RAM with a repeated series of bytes or a repeated

string. For s string with spaces, you will need to encase it with double quotes otherwise only

the first word will be used.

When the fill routine hits <address end> it will cease filling, even if the series of byte / string

is not been completed.

Syntax:

#FILL <address start> <address end> BYTE <byte> (<byte>) (<byte>) (<byte>) ...

#FILL <address start> <address end> STRING <string>

Examples:

#FILL $1000 $1FFF BYTE $ea

#FILL $1000 $1FFF BYTE 65 66 67

#FILL $1000 $1FFF STRING "Hello!"

Page 18: 6502 Code Assembler (6502CA)

Copy

Copy allows you to copy one section of 6502 RAM to another section of 6502 RAM.

Syntax:

#COPY <source address start> <source address end> TO <destination address>

Examples:

#COPY $1000 $1FFF TO $8000

#COPY $4000 $6FFF TO $A000

End

The End command causes the assembler to treat the command as the end of the source file,

ignoring any further source code beyond that point. The assembler will then process any

remaining passes (up to this command).

Syntax:

#END

SetMacro and !

Please see the Macro section for these command.