From a1d1c3f6eedd13023657b84f3c81d12af021f77f Mon Sep 17 00:00:00 2001 From: Craig Thomas Date: Wed, 21 Sep 2022 12:19:33 -0400 Subject: [PATCH] Update documentation for v1.0.0 release. Further updates to the README.md file. Add more to the README.md file. Add more documentation to README.md. More documentation in README.md Start documenting addressing modes in README.md Final set of changes to README.md file. --- LICENSE | 2 +- README.md | 506 +++++++++++++++--- assembler.py | 2 +- cocoasm/exceptions.py | 2 +- cocoasm/instruction.py | 2 +- cocoasm/operand_type.py | 2 +- cocoasm/operands.py | 2 +- cocoasm/program.py | 2 +- cocoasm/statement.py | 2 +- cocoasm/values.py | 2 +- cocoasm/virtualfiles/binary.py | 2 +- cocoasm/virtualfiles/cassette.py | 2 +- cocoasm/virtualfiles/coco_file.py | 2 +- cocoasm/virtualfiles/disk.py | 2 +- cocoasm/virtualfiles/source_file.py | 2 +- cocoasm/virtualfiles/virtual_file.py | 2 +- .../virtualfiles/virtual_file_container.py | 2 +- .../virtualfiles/virtual_file_exceptions.py | 2 +- file_util.py | 2 +- test/test_exceptions.py | 2 +- test/test_integration.py | 2 +- test/test_operands.py | 2 +- test/test_program.py | 2 +- test/test_statement.py | 4 +- test/test_values.py | 4 +- test/virtualfiles/test_binary.py | 3 +- test/virtualfiles/test_cassette.py | 2 +- test/virtualfiles/test_coco_file.py | 2 +- test/virtualfiles/test_disk.py | 2 +- test/virtualfiles/test_source_file.py | 2 +- 30 files changed, 462 insertions(+), 107 deletions(-) diff --git a/LICENSE b/LICENSE index 89bc5f8..e74ac10 100644 --- a/LICENSE +++ b/LICENSE @@ -1,4 +1,4 @@ -Copyright (C) 2013-2019 Craig Thomas +Copyright (C) 2013-2022 Craig Thomas Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in diff --git a/README.md b/README.md index fb3ced7..acca38d 100644 --- a/README.md +++ b/README.md @@ -3,6 +3,7 @@ [![GitHub Workflow Status](https://img.shields.io/github/workflow/status/craigthomas/CoCoAssembler/Build%20Test%20Coverage?style=flat-square)](https://github.com/craigthomas/CoCoAssembler/actions) [![Codecov](https://img.shields.io/codecov/c/gh/craigthomas/CoCoAssembler?style=flat-square)](https://codecov.io/gh/craigthomas/CoCoAssembler) [![Dependencies](https://img.shields.io/librariesio/github/craigthomas/CoCoAssembler?style=flat-square)](https://libraries.io/github/craigthomas/CoCoAssembler) +[![Releases](https://img.shields.io/github/release/craigthomas/CoCoAssembler?style=flat-square)](https://github.com/craigthomas/CoCoAssembler/releases) [![License: MIT](https://img.shields.io/badge/license-MIT-blue.svg?style=flat-square)](https://opensource.org/licenses/MIT) # Table of Contents @@ -11,18 +12,26 @@ 2. [Requirements](#requirements) 3. [License](#license) 4. [Installing](#installing) -5. [Assembler](#assembler) +5. [The Assembler](#the-assembler) 1. [Assembler Usage](#assembler-usage) 1. [Input File Format](#input-file-format) 2. [Print Symbol Table](#print-symbol-table) 3. [Print Assembled Statements](#print-assembled-statements) 4. [Save to Binary File](#save-to-binary-file) 5. [Save to Cassette File](#save-to-cassette-file) + 6. [Save to Disk File](#save-to-disk-file) 2. [Mnemonic Table](#mnemonic-table) 1. [Mnemonics](#mnemonics) 2. [Pseudo Operations](#pseudo-operations) - 3. [Operands](#operands) - 4. [Addressing Modes](#addressing-modes) + 3. [Addressing Modes](#addressing-modes) + 1. [Inherent](#inherent) + 2. [Immediate](#immediate) + 3. [Extended](#extended) + 4. [Extended Indirect](#extended-indirect) + 5. [Direct](#direct) + 6. [Indexed](#indexed) + 7. [Indexed Indirect](#indexed-indirect) + 8. [Program Counter Relative](#program-counter-relative) 6. [File Utility](#file-utility) 1. [Listing Files](#listing-files) 2. [Extracting to Binary File](#extracting-to-binary-file) @@ -35,58 +44,81 @@ # What is it? -This project is an assembler for the Tandy Color Computer 1, 2 and 3 written in Python 3.6. -It is intended to be statement compatible with any code written for the EDTASM+ assembler. -The assembler is capable of taking EDTASM+ assembly language code and translating it into -machine code for the Color Computer 1, 2, and 3. Current support is for 6809 CPU instructions, -but future enhancements will add 6309 instructions. +This project is an assembler for the Tandy Color Computer 1, 2 and 3 written in Python 3.6+. +More broadly speaking, it is an assembler that targets the Motorola 6809 processor, meaning it +targets any computer that used the 6809 as it's main CPU (e.g. the +[Dragon 32 and 64](https://en.wikipedia.org/wiki/Dragon_32/64), +[Vectrex](https://en.wikipedia.org/wiki/Vectrex), [Thomson TO7](https://en.wikipedia.org/wiki/Thomson_TO7), +etc). It is intended to be statement compatible with any code written for the EDTASM+ assembler. +The assembler is capable of taking EDTASM+ assembly language code and translating it into 6809 machine code. +Current support is for 6809 CPU instructions, but future enhancements will add 6309 instructions. This project also includes a general purpose file utility, used mainly for manipulating -`CAS`, `DSK`, and `WAV` files. +`CAS`, `DSK`, and `WAV` files. The file utility specifically targets the disk file formats and +cassette formats used by the Color Computer line of personal computers. -# Requirements - -In order to run the assembler, you will need Python 3.6 or greater. If you -prefer to clone the repository, you will need Git (if you don't want to -install Git, then check the [Releases](https://github.com/craigthomas/CoCoAssembler/releases) -section for the newest release of the package that you can download). +--- # License -This project makes use of an MIT style license. Please see the file called +This project makes use of an MIT style license. Generally speaking, the license +is extremely permissive, allowing you to copy, modify, distribute, sell, or +distribute it for personal or commercial purposes. Please see the file called [LICENSE](https://github.com/craigthomas/CoCoAssembler/blob/master/LICENSE) for more information. +--- + +# Requirements + +The assembler can be run on any OS platform, including but not limited to: + +- Windows (XP, Vista, 7, 8, 10, 11, etc) +- Linux (Ubuntu, Debian, Arch, Raspbian, etc) +- Mac (Mojave, Catalina, Big Sur, Monterey, Ventura, etc) + +The only requirement is Python 3.6 or greater will need to be installed and +available on the search path, along with the Package Installer for Python (`pip`). +To download Python, visit the [Downloads](https://www.python.org/downloads/) +section on the Python website. See the Python installation documentation for more +information on ensuring the Python interpreter is installed on the search path, +and that `pip` is installed along with it. + +--- + # Installing -To install the source files, download the latest release from the +There is no specific installer that needs to be run in order to install +the assembler. Simply copy the source files to a directory of your choice. +A zipfile containing the latest release of the source files can be downloaded from the [Releases](https://github.com/craigthomas/CoCoAssembler/releases) -section of the repository and unzip the contents in a directory of your -choice. Or, clone the repository in the directory of your choice with: - - git clone https://github.com/craigthomas/CoCoAssembler.git +section of the code repository. Unzip the contents to a directory of your +choice. Next, you will need to install the required packages for the file: pip install -r requirements.txt - -# Assembler +--- + +# The Assembler The assembler is contained in a file called `assmbler.py` and can be invoked with: - python assembler.py + python3 assembler.py In general, the assembler recognizes EDTASM+ mnemonics, along with a few other somewhat standardized mnemonics to make program compilation easier. By default, the assembler assumes it is assembling statements in 6809 machine code. Future releases will include a 6309 extension. - + +--- + ## Assembler Usage To run the assembler: - python assembler.py input_file + python3 assembler.py input_file This will assemble the instructions found in file `input_file` and will generate the associated Color Computer machine instructions in binary format. You will need @@ -100,6 +132,8 @@ that are available: * `--dsk_file` - save assembled contents to a virtual disk file * `--name` - saves the program with the specified name on a cassette or virtual disk file +--- + ### Input File Format The input file needs to follow the format below: @@ -110,7 +144,7 @@ Where: * `LABEL` is a 10 character label for the statement * `MNEMONIC` is a 6809 operation mnemonic from the [Mnemonic Table](#mnemonic-table) below -* `OPERANDS` are registers, values, expressions, or labels as described in the [Operands](#operands) section +* `OPERANDS` are registers, values, expressions, or labels * `COMMENT` is a 40 character comment describing the statement (must have a `;` preceding it) An example file: @@ -133,14 +167,15 @@ An example file: BEQ FINISH ; No key pressed, wait for keypress JMP $A027 ; Restart BASIC END START - + +--- ### Print Symbol Table To print the symbol table that is generated during assembly, use the `--symbols` switch: - python assembler.py test.asm --symbols + python3 assembler.py test.asm --symbols Which will have the following output: @@ -152,15 +187,18 @@ Which will have the following output: $0E11 MESSAGE $0E1E FINISH -The first column of output is the hex value of the symbol, the second columns is the symbol name -itself. +The first column of output is the hex value of the symbol. This may be the address in +memory where the symbol exits if it labels a mnemonic, or it may be the value that the +symbol is defined as being if it references an `EQU` statement. The second columns is +the symbol name itself. +--- ### Print Assembled Statements To print out the assembled version of the program, use the `--print` switch: - python assembler.py test.asm --print + python3 assembler.py test.asm --print Which will have the following output: @@ -198,12 +236,13 @@ The columns are as follows: 5. Operands that the instruction processes (`$A928`). 6. The comment string (`Clear the screen`). +--- ### Save to Binary File To save the assembled contents to a binary file, use the `--bin_file` switch: - python assembler.py test.asm --bin_file test.bin + python3 assembler.py test.asm --bin_file test.bin The assembled program will be saved to the file `test.bin`. Note that this file may not be useful on its own, as it does not have any meta information about @@ -212,31 +251,54 @@ will not have any effect on the assembled file). **NOTE**: If the file `test.bin` exists, it will be erased and overwritten. +--- ### Save to Cassette File To save the assembled contents to a cassette file, use the `--cas_file` switch: - python assembler.py test.asm --cas_file test.cas + python3 assembler.py test.asm --cas_file test.cas This will assemble the program and save it to a cassette file called `test.cas`. The source code must include the `NAM` mnemonic to name the program (e.g. `NAM myprog`), or the `--name` switch must be used on the command line (e.g. -`--name myprog`). The program name on the cassette file will be `myprog`. +`--name myprog`). The program name on the cassette file will be `MYPROG`. **NOTE**: if the file `test.cas` exists, assembly will stop and the file will not be overwritten. If you wish to add the program to `test.cas`, you must -specify the `--append` flag during compilation: +specify the `--append` flag during assembly: - python assembler.py test.asm --cas_file test.cas --append + python3 assembler.py test.asm --cas_file test.cas --append -This will add the file to the `test.cas` file as an additional binary within -the cassette. To load from the cassette file using BASIC's `CLOADM` command -would be done as follows +To load from the cassette file, you must use BASIC's `CLOADM` command as follows: CLOADM"MYPROG" - +--- + +### Save to Disk File + +To save the assembled contents to a disk file, use the `--dsk_file` switch: + + python3 assembler.py test.asm --dsk_file test.dsk + +This will assemble the program and save it to a disk file called `test.dsk`. +The source code must include the `NAM` mnemonic to name the program on disk (e.g. +`NAM myprog`), or the `--name` switch must be used on the command line (e.g. +`--name myprog`). The program name on the disk file will be `MYPROG.BIN`. + +**NOTE**: if the file `test.dsk` exists, assembly will stop and the file will +not be updated. If you wish to add the program to `test.dsk`, you must specify the +`--append` flag during assembly: + + python3 assembler.py test.asm --dsk_file test.dsk --append + +To load from the disk file, you must use Disk Basic's `LOADM` command as follows: + + LOADM"MYPROG.BIN" + +--- + ## Mnemonic Table Below are the mnemonics that are accepted by the assembler (these mnemonics are @@ -252,42 +314,174 @@ symbols are: * `U` - 16-bit user stack register. * `X` - 16-bit index register. * `Y` - 16-bit index register. + +Note that the operations described below may use different addressing modes for operands (e.g. `LDA` may +use immediate, direct, indexed or extended addressing to load values). See the section below on addressing +modes, and consult the MC6809 datasheet for more information on what addressing modes are applicable, +as well as the number of cycles used to execute each operation. -### Mnemonics +--- -| Mnemonic | Description | Example | -| -------- | ----------- | ------- | -| `ABX` | Adds contents of `B` to value in register `X` and stores in `X`. | `ABX` | -| `ADCA` | Adds contents of `A`, memory value `M`, and carry bit and stores in `A`. | `ADCA $FFEE` | -| `ADCB` | Adds contents of `B`, memory value `M`, and carry bit and stores in `B`. | `ADCB $FFEF` | -| `ADDA` | Adds contents of `A` with memory value `M` and stores in `A`. | `ADDA #$03` | -| `ADDB` | Adds contents of `B` with memory value `M` and stores in `B`. | `ADDB #$90` | -| `ADDD` | Adds contents of `D` (`A:B`) with memory value `M:M+1` and stores in `D`. | `ADDD #$2000` | -| `ANDA` | Performs a logical AND on `A` with memory value `M` and stores in `A`. | `ANDA #$05` | -| `ANDB` | Performs a logical AND on `B` with memory value `M` and stores in `B`. | `ANDB $FFEE` | -| `ANDCC` | Performs a logical AND on `CC` with immediate value `M` and stores in `CC`.| `ANDCC #01` | -| `ASLA` | Shifts bits in `A` left (0 placed in bit 0, bit 7 goes to carry in `CC`). | `ASLA` | -| `ASLB` | Shifts bits in `B` left (0 placed in bit 0, bit 7 goes to carry in `CC`). | `ASLB` | -| `ASL` | Shifts bits in `M` left (0 placed in bit 0, bit 7 goes to carry in `CC`). | `ASL $0E00` | -| `ASRA` | Shifts bits in `A` right (bit 0 goes to carry in `CC`, bit 7 remains same).| `ASRA` | -| `ASRB` | Shifts bits in `B` right (bit 0 goes to carry in `CC`, bit 7 remains same).| `ASRB` | -| `ASR` | Shifts bits in `M` right (bit 0 goes to carry in `CC`, bit 7 remains same).| `ASR $0E00` | +### Mnemonics +| Mnemonic | Description | Example | +|----------|----------------------------------------------------------------------------------|----------------| +| `ABX` | Adds contents of `B` to value in register `X` and stores in `X`. | `ABX` | +| `ADCA` | Adds contents of `A`, memory value `M`, and carry bit and stores in `A`. | `ADCA $FFEE` | +| `ADCB` | Adds contents of `B`, memory value `M`, and carry bit and stores in `B`. | `ADCB $FFEF` | +| `ADDA` | Adds contents of `A` with memory value `M` and stores in `A`. | `ADDA #$03` | +| `ADDB` | Adds contents of `B` with memory value `M` and stores in `B`. | `ADDB #$90` | +| `ADDD` | Adds contents of `D` (`A:B`) with memory value `M:M+1` and stores in `D`. | `ADDD #$2000` | +| `ANDA` | Performs a logical AND on `A` with memory value `M` and stores in `A`. | `ANDA #$05` | +| `ANDB` | Performs a logical AND on `B` with memory value `M` and stores in `B`. | `ANDB $FFEE` | +| `ANDCC` | Performs a logical AND on `CC` with immediate value `M` and stores in `CC`. | `ANDCC #$01` | +| `ASLA` | Shifts bits in `A` left (0 placed in bit 0, bit 7 goes to carry in `CC`). | `ASLA` | +| `ASLB` | Shifts bits in `B` left (0 placed in bit 0, bit 7 goes to carry in `CC`). | `ASLB` | +| `ASL` | Shifts bits in `M` left (0 placed in bit 0, bit 7 goes to carry in `CC`). | `ASL $0E00` | +| `ASRA` | Shifts bits in `A` right (bit 0 goes to carry in `CC`, bit 7 remains same). | `ASRA` | +| `ASRB` | Shifts bits in `B` right (bit 0 goes to carry in `CC`, bit 7 remains same). | `ASRB` | +| `ASR` | Shifts bits in `M` right (bit 0 goes to carry in `CC`, bit 7 remains same). | `ASR $0E00` | +| `BCC` | Branches if carry bit in `CC` is 0. | `BCC CLS` | +| `BCS` | Branches if carry bit in `CC` is 1. | `BCS CLS` | +| `BEQ` | Branches if zero bit in `CC` is 1. | `BEQ CLS` | +| `BGE` | Branches if negative and overflow bits in `CC` are equal. | `BGE CLS` | +| `BGT` | Branches if negative and overflow bits are equal, and zero bit is zero in `CC`. | `BGT CLS` | +| `BHI` | Branches if carry and zero bit in `CC` are 0. | `BHI CLS` | +| `BHS` | Same as `BCC`. | `BHS CLS` | +| `BITA` | Logically ANDs `A` with memory contents `M` and sets bits in `CC`. | `BITA #$1E` | +| `BITB` | Logically ANDs `B` with memory contents `M` and sets bits in `CC`. | `BITB #$1E` | +| `BLE` | Branches if negative and overflow bits are not equal, or zero bit is 1 in `CC`. | `BLE CLS` | +| `BLO` | Same as `BCS`. | `BLO CLS` | +| `BLS` | Branches if zero bit is 1, or carry bit is 1 in `CC`. | `BLS CLS` | +| `BLT` | Branches if negative bit is not equal overflow bit in `CC`. | `BLT CLS` | +| `BMI` | Branches if negative bit is 1 in `CC`. | `BMI CLS` | +| `BNE` | Branches if zero bit is 0 in `CC`. | `BNE CLS` | +| `BGE` | Branches if negative bit is 0 in `CC`. | `BGE CLS` | +| `BRA` | Branch always. | `BRA CLS` | +| `BRN` | Branch never - essentially 2-byte `NOP`. | `BRN CLS` | +| `BSR` | Saves the value of `PC` on the `S` stack and branches to subroutine. | `BSR PRINT` | +| `BVC` | Branches if overflow bit is 0 in `CC`. | `BVC CLS` | +| `BVS` | Branches if overflow bit is 1 in `CC`. | `BVS CLS` | +| `CLRA` | Zeroes out the `A` register, and clears `CC`. | `CLRA` | +| `CLRB` | Zeroes out the `B` register, and clears `CC`. | `CLRB` | +| `CLR` | Zeroes out the memory contents `M` and clears `CC`. | `CLR $01E0` | +| `CMPA` | Subtract value from `A` register, and sets bits in `CC`. | `CMPA #$1E` | +| `CMPB` | Subtract value from `B` register, and sets bits in `CC`. | `CMPB #$1E` | +| `CMPD` | Subtract value from `D` register, and sets bits in `CC`. | `CMPD #$1E1F` | +| `CMPS` | Subtract value from `S` register, and sets bits in `CC`. | `CMPS #$1E1F` | +| `CMPU` | Subtract value from `U` register, and sets bits in `CC`. | `CMPU #$1E1F` | +| `CMPX` | Subtract value from `X` register, and sets bits in `CC`. | `CMPX #$1E1F` | +| `CMPY` | Subtract value from `Y` register, and sets bits in `CC`. | `CMPY #$1E1F` | +| `COMA` | Perform logical complement of value in `A` and store in `A`. | `COMA` | +| `COMB` | Perform logical complement of value in `B` and store in `B`. | `COMA` | +| `COM` | Perform logical complement of value in memory location `M` and store in `M`. | `COM $FFEE` | +| `CWAI` | Clear `CC` register, push state onto stack, and wait for interrupt. | `CWAI` | +| `DAA` | Perform decimal addition adjust in `A`. Converts to Binary Coded Decimal. | `DAA` | +| `DECA` | Decrement the value in `A` by 1. | `DECA` | +| `DECB` | Decrement the value in `B` by 1. | `DECB` | +| `DEC` | Decrement the value in memory location `M` by 1. | `DEC $FFEE` | +| `EORA` | Perform exclusive OR with value in `A`, and store in `A`. | `EORA #$1F` | +| `EORB` | Perform exclusive OR with value in `B`, and store in `B`. | `EORB #$1F` | +| `EXG` | Swap values in registers. | `EXG A,B` | +| `INCA` | Increment value in `A` by 1. | `INCA` | +| `INCB` | Increment value in `B` by 1. | `INCB` | +| `INC` | Increment the value in memory location `M` by 1. | `INC $FFEE` | +| `JMP` | Unconditional jump to location. | `JMP $C000` | +| `JSR` | Jump to subroutine at the specified location. | `JSR PRINT` | +| `LBCC` | Same as `BCC`, except can branch more than -126 and +129 bytes. | `LBCC CLS` | +| `LBCS` | Same as `BCS`, except can branch more than -126 and +129 bytes. | `LBCS CLS` | +| `LBEQ` | Same as `BEQ`, except can branch more than -126 and +129 bytes. | `LBEQ CLS` | +| `LBGE` | Same as `BGE`, except can branch more than -126 and +129 bytes. | `LBGE CLS` | +| `LBGT` | Same as `BGT`, except can branch more than -126 and +129 bytes. | `LBGT CLS` | +| `LBHI` | Same as `BHI`, except can branch more than -126 and +129 bytes. | `LBHI CLS` | +| `LBHS` | Same as `BHS`, except can branch more than -126 and +129 bytes. | `LBHS CLS` | +| `LBLE` | Same as `BLE`, except can branch more than -126 and +129 bytes. | `LBLE CLS` | +| `LBLO` | Same as `BLO`, except can branch more than -126 and +129 bytes. | `LBLO CLS` | +| `LBLS` | Same as `BLS`, except can branch more than -126 and +129 bytes. | `LBLS CLS` | +| `LBLT` | Same as `BLT`, except can branch more than -126 and +129 bytes. | `LBLT CLS` | +| `LBMI` | Same as `BMI`, except can branch more than -126 and +129 bytes. | `LBMI CLS` | +| `LBNE` | Same as `BNE`, except can branch more than -126 and +129 bytes. | `LBNE CLS` | +| `LBPL` | Same as `BPL`, except can branch more than -126 and +129 bytes. | `LBPL CLS` | +| `LBRA` | Same as `BRA`, except can branch more than -126 and +129 bytes. | `LBRA CLS` | +| `LBRN` | Same as `BRN`, except can branch more than -126 and +129 bytes. | `LBRN CLS` | +| `LBSR` | Same as `BSR`, except can branch more than -126 and +129 bytes. | `LBSR CLS` | +| `LBVC` | Same as `BVC`, except can branch more than -126 and +129 bytes. | `LBVC CLS` | +| `LBVS` | Same as `BVS`, except can branch more than -126 and +129 bytes. | `LBVS CLS` | +| `LDA` | Loads `A` with the specified value. | `LDA #$FE` | +| `LDB` | Loads `B` with the specified value. | `LDB #$FE` | +| `LDD` | Loads `D` with the specified value. | `LDD #$FEFE` | +| `LDS` | Loads `S` with the specified value. | `LDS #$FEFE` | +| `LDU` | Loads `U` with the specified value. | `LDU #$FEEE` | +| `LDX` | Loads `X` with the specified value. | `LDX #$FEEE` | +| `LDY` | Loads `Y` with the specified value. | `LDY #$FEEE` | +| `LEAS` | Loads `S` with the address computed from an indexed addressing mode operand. | `LEAS A,X` | +| `LEAU` | Loads `U` with the address computed from an indexed addressing mode operand. | `LEAU A,X` | +| `LEAX` | Loads `X` with the address computed from an indexed addressing mode operand. | `LEAX A,X` | +| `LEAY` | Loads `Y` with the address computed from an indexed addressing mode operand. | `LEAY A,X` | +| `LSLA` | Logically shift bits left in `A`, bit 7 stored in carry of `CC`, bit 0 gets 0. | `LSLA` | +| `LSLB` | Logically shift bits left in `B`, bit 7 stored in carry of `CC`, bit 0 gets 0. | `LSLB` | +| `LSL` | Logically shift bits left in `M`, bit 7 stored in carry of `CC`, bit 0 gets 0. | `LSL $FFEE` | +| `LSRA` | Logically shift bits right in `A`, bit 0 stored in carry of `CC`, bit 7 gets 0. | `LSRA` | +| `LSRB` | Logically shift bits right in `B`, bit 0 stored in carry of `CC`, bit 7 gets 0. | `LSRB` | +| `LSR` | Logically shift bits right in `M`, bit 0 stored in carry of `CC`, bit 7 gets 0. | `LSR $FFEE` | +| `MUL` | Unsigned multiple of `A` and `B`, and stored in `D`. | `MUL` | +| `NEGA` | Perform twos complement of `A` and store in `A`. | `NEGA` | +| `NEGB` | Perform twos complement of `B` and store in `B`. | `NEGB` | +| `NEG` | Perform twos complement of `M` and store in `M`. | `NEG $FFEE` | +| `NOP` | Do nothing but advance program counter to next memory location. | `NOP` | +| `ORA` | Perform logical OR of `A` and value, and store in `A`. | `ORA #$A1` | +| `ORB` | Perform logical OR of `B` and value, and store in `B`. | `ORB #$CD` | +| `ORCC` | Perform logical OR of `CC` and value, and store in `CC`. | `ORCC #$C0` | +| `PSHS` | Pushes specified registers onto the `S` stack. | `PSHS A,B,X` | +| `PSHU` | Pushes specified registers onto the `U` stack. | `PSHU A,B,X` | +| `PULS` | Pulls values from the `S` stack back into their registers. | `PULS A,B,X` | +| `PULU` | Pulls values from the `U` stack back into their registers. | `PULU A,B,X` | +| `ROLA` | Rotates bits left in `A`, bit 7 stored in carry, and carry stored in bit 0. | `ROLA` | +| `ROLB` | Rotates bits left in `B`, bit 7 stored in carry, and carry stored in bit 0. | `ROLB` | +| `ROL` | Rotates bits left in `M`, bit 7 stored in carry, and carry stored in bit 0. | `ROL $FFEE` | +| `RORA` | Rotates bits right in `A`, carry stored in bit 7, and bit 0 stored in carry. | `RORA` | +| `RORB` | Rotates bits right in `B`, carry stored in bit 7, and bit 0 stored in carry. | `RORB` | +| `ROR` | Rotates bits right in `M`, carry stored in bit 7, and bit 0 stored in carry. | `ROL $FFEE` | +| `RTI` | Return from interrupt, pops `CC`, then `A`, `B`, `DP`, `X`, `Y`, `U` if `E` set. | `RTI` | +| `RTS` | Return from subroutine, pops `PC` from `S` stack. | `RTS` | +| `SBCA` | Subtract byte and carry from `A` and store in `A`. | `SBCA #$C0` | +| `SBCB` | Subtract byte and carry from `B` and store in `B`. | `SBCB #$C0` | +| `SEX` | Sign extend bit 7 from `B` into all of `A` and into negative of `CC`. | `SEX` | +| `STA` | Stores value in `A` at the specified memory location `M`. | `STA $FFEE` | +| `STB` | Stores value in `B` at the specified memory location `M`. | `STB $1EEE` | +| `STD` | Stores value in `D` at the specified memory location `M`. | `STD $1EEE` | +| `STS` | Stores value in `S` at the specified memory location `M`. | `STS $1EEE` | +| `STU` | Stores value in `U` at the specified memory location `M`. | `STU $1EEE` | +| `STX` | Stores value in `X` at the specified memory location `M`. | `STX $1EEE` | +| `STY` | Stores value in `Y` at the specified memory location `M`. | `STY $1EEE` | +| `SUBA` | Subtracts the 8-bit value from `A` and stores in `A`. | `SUBA #$1E` | +| `SUBB` | Subtracts the 8-bit value from `B` and stores in `B`. | `SUBB #$1E` | +| `SUBD` | Subtracts the 16-bit value from `D` and stores in `D`. | `SUBB #$1E` | +| `SWI` | Push all registers on the stack and branch to subroutine at `$FFFA`. | `SWI` | +| `SWI2` | Push all registers on the stack and branch to subroutine at `$FFF4`. | `SWI2` | +| `SWI3` | Push all registers on the stack and branch to subroutine at `$FFF2`. | `SWI3` | +| `SYNC` | Halt and wait for interrupt. | `SYNC` | +| `TFR` | Transfer source register value to destination register. | `TFR A,B` | +| `TSTA` | Test value in `A`, and set negative in `CC` and zero in `CC` as required. | `TSTA` | +| `TSTB` | Test value in `B`, and set negative in `CC` and zero in `CC` as required. | `TSTB` | +| `TST` | Test value in `M`, and set negative in `CC` and zero in `CC` as required. | `TST $FFFE` | + +--- ### Pseudo Operations -| Mnemonic | Description | Example | -| -------- | ----------- | ------- | -| `FCB` | Defines a single byte constant value. | `FCB $1C` | -| `FCC` | Defines a string constant value enclosed in a matching pair of delimiters. | `FCC "hello"` | -| `FDB` | Defines a two byte constant value. | `FDB $2000` | -| `END` | Defines the end of the program. | `END` | -| `EQU` | Defines a symbol with a set value. | `SCRMEM EQU $1000` | -| `INCLUDE`| Includes another assembly source file at this location. | `INCLUDE globals.asm` | -| `NAM` | Sets the name for the program when assembled to disk or cassette. | `NAM myprog` | -| `ORG` | Defines where in memory the program should originate at. | `ORG $0E00` | -| `RMB` | Defines a block of _n_ bytes initialized to a zero value. | `RMB $8` | -| `SETDP` | Sets the direct page value for the assembler (see notes below). | `SETDP $0E00` | +| Mnemonic | Description | Example | +|-----------|----------------------------------------------------------------------------|-----------------------| +| `FCB` | Defines a single byte constant value. | `FCB $1C` | +| `FCC` | Defines a string constant value enclosed in a matching pair of delimiters. | `FCC "hello"` | +| `FDB` | Defines a two byte constant value. | `FDB $2000` | +| `END` | Defines the end of the program. | `END` | +| `EQU` | Defines a symbol with a set value. | `SCRMEM EQU $1000` | +| `INCLUDE` | Includes another assembly source file at this location. | `INCLUDE globals.asm` | +| `NAM` | Sets the name for the program when assembled to disk or cassette. | `NAM myprog` | +| `ORG` | Defines where in memory the program should originate at. | `ORG $0E00` | +| `RMB` | Defines a block of _n_ bytes initialized to a zero value. | `RMB $8` | +| `SETDP` | Sets the direct page value for the assembler (see notes below). | `SETDP $0E00` | **Notes** @@ -297,19 +491,163 @@ using direct page addressing. Instructions such as `JMP $0E8F` will become `JMP responsible for loading the direct page register manually - this mnemonic does not output opcodes that change the direct page register. -## Operands - -(Under construction) +--- ## Addressing Modes -(Under construction) +The assembler understands several type of addressing modes for each operation. Please note that +you will need to consult the MC6809 Data Sheet for information regarding what operations support which +addressing modes. The different modes are explained below. Again, the discussion below is a simplified +explanation of the material that exists in the MC6809 Data Sheet. + +--- + +### Inherent + +The operation takes no additional information to execute. For example, the decimal additional adjust +operation requires no additional inputs and is specified with: + + DAA + +--- + +### Immediate + +The operation requires a value that is specified directly following the mnemonic. All immediate values +must be prefixed with an `#` symbol. For example, to load the value of `$FE` into register `A`: + + LDA #$FE + +--- + +### Extended + +The operation requires a 16-bit address that is used for execution of the instruction. The address +may be specified as a hard-coded value, or as a symbol. For example: + + JMP $FFEE + BSR POLCAT + +--- + +### Extended Indirect + +The operation requires a 16-bit address where the memory contents specify another 16-bit address. +Extended indirect addressing mode is denoted by using square brackets to enclose the operand. For +example: + + JMP [$010E] + BSR [PRINT] + +--- + +### Direct + +Works similarly to extended addressing, however, instead of using a 16-bit value to specify the +address, uses the contents of the direct page `DP` register and an 8-bit value to form the +full 16-bit address. This addressing mode saves space. Direct addressing also has a lower +clock-cycle count for execution. For example, assuming that the `DP` register is set to `$FF`, then +the following statement: + + JMP $EE + +Is equivalent to the extended addressing mode variant of: + + JMP $FFEE + +Additionally, the direct addressing mode can be explicitly invoked on the operand by prefixing +the operand with an `<` symbol. For example: + + JMP