# 6502 Restricted Assembler

[![Python application](https://github.com/CyberZHG/cpu-6502-restricted-assembler/actions/workflows/python-test.yml/badge.svg)](https://github.com/CyberZHG/cpu-6502-restricted-assembler/actions/workflows/python-test.yml)
[![Coverage Status](https://coveralls.io/repos/github/CyberZHG/mos-6502-restricted-assembler/badge.svg?branch=main)](https://coveralls.io/github/CyberZHG/mos-6502-restricted-assembler?branch=main)

A 6502 assembler with restricted functions.

## Install

```bash
pip install mos-6502-restricted-assembler
```

## Usage

```python
from asm_6502 import Assembler

code = """
START ORG $0080
      JMP START
"""
assembler = Assembler()
results = assembler.assemble(code, add_entry=False)
# Results will be `[(0x0080, [0x4C, 0x80, 0x00])]`
#     0x0080 is the offset of the codes, the following are the bytes generated by the assembler.

code = """
ORG $0080
JMP $abcd
"""
results = assembler.assemble(code)
# Results will be `[
#     (0x0080, [0x4C, 0xcd, 0xab]),
#     (0xFFFC, [0x80, 0x00]),
# ]`
# By default, the assembler will set to 0xFFFE/F the address of the first line that can be executed.
```

## Instructions

### List

Official:

|     |     |     |     |     |     |     |     |     |     |     |     |     |     |
|:---:|:---:|:---:|:---:|:---:|:---:|:---:|:---:|:---:|:---:|:---:|:---:|:---:|:---:|
| ADC | AND | ASL | BCC | BCS | BEQ | BIT | BMI | BNE | BPL | BRK | BVC | BVS | CLC |
| CLD | CLI | CLV | CMP | CPX | CPY | DEC | DEX | DEY | EOR | INC | INX | INY | JMP |
| JSR | LDA | LDX | LDY | LSR | NOP | ORA | PHA | PHP | PLA | PLP | ROL | ROR | RTI |
| RTS | SBC | SEC | SED | SEI | STA | STX | STY | TAX | TAY | TSX | TXA | TXS | TYA |

Undocumented:

|     |     |     |     |     |     |     |     |     |     |     |     |     |     |
|:---:|:---:|:---:|:---:|:---:|:---:|:---:|:---:|:---:|:---:|:---:|:---:|:---:|:---:|
| ANC | ARR | ASR | DCP | ISC | JAM | LAS | LAX | RLA | RRA | SAX | SBX | SHA | SHS |
| SHX | SHY | SLO | SRE | XAA |  -  |  -  |  -  |  -  |  -  |  -  |  -  |  -  |  -  |


### Pseudo

```
ORG $0080    ; The following codes will be generated from this offset
.BYTE $AB    ; Set to the current address $0080 with a byte $AB
.WORD $ABCD  ; Set to the current address $0081 with two bytes $CD and $AB
.END         ; This is equivelent to JMP *
```

### Addressing

```
START ORG $0080
      .WORD *+3
      NOP                 ; Implied addressing
      JMP (START)         ; Indirect addressing
      LDA #10             ; Load $0A into the accumulator
      LDA #LO $ABCD       ; Load $CD into the accumulator
      LDA #HI $ABCD       ; Load $AB into the accumulator
      LDA $00             ; Load into accumulator from zero-page address $00
      LDA $10,X           ; Load into accumulator from zero-page address ($10 + X) % $0100
      LDX $10,Y           ; Load into X from zero-page address ($10 + Y) % $0100
      LDA $ABCD           ; Load into accumulator from address $ABCD
      LDA $ABCD,X         ; Load into accumulator from address $ABCD + X
      LDA $ABCD,Y         ; Load into accumulator from address $ABCD + Y
      LDA ($40,X)         ; Load into accumulator from the 2-byte address contained in ($40 + X) % $0100
      LDA ($40),Y         ; Load into accumulator from (the 2-byte address contained in $40) + Y
```

Special rules for zero-page addressing:

```
LDA $0010           ; This is not zero-page addressing as the input contains a word
LDA *               ; This is not zero-page addressing no matter what the current code address is
LDA LABEL           ; This is not zero-page addressing no matter where LABEL points to
LDA $FF+10-10       ; This is not zero-page addressing as the intermedidate result is greater than a byte
```
