This assembly language has some global restrictions :
- Values are 1 byte.
- Addresses are 2 bytes.
- Address space can go up to $FFFF
- The address space is 1KByte but the last page ($FF00 to $FFFF) is reserved to the stack.
- Stack overflow will trigger the computer to HALT.
- The base computer is designed to work with big endian values.
File should start with this header :
#BB8BC_ASM_v1
Comments can be added anywhere in the code with the following syntax :
// Full comment
LDA #10 // Inline comment
This assembly is specifically designed to work with the Breadboard computer, therefore it includes all the addressing modes that the hardware implements :
Instructions using this addressing mode will be 1 byte long and have no operand, the instruction is enough to deduce everything needed for the execution.
Examples :
NOP
PHA
PLB
CLS
Instructions using this addressing mode will be 2 byte long and have 1 operand, the operand is interpreted as a plain hexadecimal value.
This addressing mode is compatible with 1 byte Constants.
Operands should be formatted as follows :
- Start with a
#. - Constants should be surrounded by parenthesis.
Examples :
LDA #FF
STA #(CONST8)
This addressing mode works as an absolute pointer.
Instructions using this addressing mode will be 3 byte long and have 2 operands, the operand is interpreted as a big endian 2 bytes address.
This addressing mode is compatible with Variables and 1 & 2 bytes Constants, 1 byte Constants should be completed by a memory page or an offset, if only a 1 byte constant is passed, the compiler will replace it with the Zero Page version as it is faster to execute.
Operands should be formatted as follows :
- Start with a
$for plain address and Constants. - Constants should be surrounded by parenthesis.
- Variable should not be prefixed or surrounded.
Examples :
LDA $(CONST16)
ADD $2FF
STA VARIABLE
ADD $02(CONST8)
ADD $(CONST8)A9
This addressing mode works in the same way as the Absolute mode but is restricted to the first 256 bytes page of memory, and is 1 cycle faster to execute.
Instructions using this addressing mode will be 2 byte long and have 1 operand, the operand is interpreted as an offset in the 0th memory page.
This addressing mode is compatible with 1 byte Constants
Operands should be formatted as follows :
- Start with a
$ - Constants should be surrounded by parenthesis
Examples :
LDA $(CONST8)
ADD $80
This addressing mode is kind of an extension of Zero Page and Absolute as it allows to index a specified memory page using the A Register.
Instructions using this addressing mode will be 2 byte long and have 1 operand, the operand is interpreted the page to index (the 8 MSB of the address), the offset inside the page is retrieved from the A Register
This addressing mode is compatible with 1 byte Constants
Operands should be formatted as follows :
- Start with a
$ - End with
, A - Constants should be surrounded by parenthesis
Examples :
ADD $02, A
ADD $(CONST8), A
| Hex | Assembly | Addressing Mode | Type | Size | Clock cycles |
|---|---|---|---|---|---|
| 0x00 | NOP | Implied | Misc. | 1 | 4c |
| 0x01 | LDA #FD | Immediate | Memory | 2 | 5c |
| 0x02 | LDA $FD | Zero Page | Memory | 2 | 8c |
| 0x03 | LDA $02FD | Absolute | Memory | 3 | 9c |
| 0x04 | LDB #FD | Immediate | Memory | 2 | 5c |
| 0x05 | LDB $FD | Zero Page | Memory | 2 | 8c |
| 0x06 | LDB $02FD | Absolute | Memory | 3 | 9c |
| 0x07 | STA $FD | Zero Page | Memory | 2 | 8c |
| 0x08 | STA $02FD | Absolute | Memory | 3 | 9c |
| 0x09 | NOP | Implied | Misc. | 1 | 4c |
| 0x0A | NOP | Implied | Misc. | 1 | 4c |
| 0x0B | ADD #FD | Immediate | Logic | 2 | 6c |
| 0x0C | ADD $FD | Zero Page | Logic | 2 | 9c |
| 0x0D | ADD $02FD | Absolute | Logic | 3 | 10c |
| 0x0E | ADD $FD, A | Indexed | Logic | 2 | 9c |
| 0x0F | SUB #FD | Immediate | Logic | 2 | 6c |
| 0x10 | SUB $FD | Zero Page | Logic | 2 | 9c |
| 0x11 | SUB $02FD | Absolute | Logic | 3 | 10c |
| 0x12 | SUB $FD, A | Indexed | Logic | 2 | 9c |
| 0x13 | NOP | Implied | Misc. | 1 | 4c |
| 0x14 | CLS | Implied | Logic | 1 | 3c |
| 0x15 | CMP | Implied | Logic | 1 | 3c |
| 0x16 | CMP #FD | Immediate | Logic | 2 | 6c |
| 0x17 | CMP $FD | Zero Page | Logic | 2 | 9c |
| 0x18 | CMP $02FD | Absolute | Logic | 3 | 10c |
| 0x19 | PHA | Implied | Memory | 1 | 4c |
| 0x1A | NOP | Implied | Misc. | 1 | 4c |
| 0x1B | PHS | Implied | Memory | 1 | 4c |
| 0x1C | PLA | Implied | Memory | 1 | 5c |
| 0x1D | PLB | Implied | Memory | 1 | 5c |
| 0x1E | PLS | Implied | Logic | 1 | 5c |
| 0x1F | NOP | Implied | Misc. | 1 | 4c |
| 0x20 | JSR $02FD | Absolute | Branching | 3 | 11c |
| 0x21 | RTS | Implied | Branching | 1 | 12c |
| 0x22 | JMP $FD | Zero Page | Branching | 2 | 7c |
| 0x23 | JMP $02FD | Absolute | Branching | 3 | 8c |
| 0x24 | JMP $FD, A | Indexed | Branching | 2 | 7c |
| 0x25 | BCS $FD | Zero Page | Branching | 2 | 4-7c |
| 0x26 | BCS $02FD | Absolute | Branching | 3 | 5-8c |
| 0x27 | BCS $FD, A | Indexed | Branching | 2 | 4-7c |
| 0x28 | BCC $FD | Zero Page | Branching | 2 | 4-7c |
| 0x29 | BCC $02FD | Absolute | Branching | 3 | 5-8c |
| 0x2A | BCC $FD, A | Indexed | Branching | 2 | 4-7c |
| 0x2B | BNE $FD | Zero Page | Branching | 2 | 4-7c |
| 0x2C | BNE $02FD | Absolute | Branching | 3 | 5-8c |
| 0x2D | BNE $FD, A | Indexed | Branching | 2 | 4-7c |
| 0x2E | BEQ $FD | Zero Page | Branching | 2 | 4-7c |
| 0x2F | BEQ $02FD | Absolute | Branching | 3 | 5-8c |
| 0x30 | BEQ $FD, A | Indexed | Branching | 2 | 4-7c |
| 0x31 | BPL $FD | Zero Page | Branching | 2 | 4-7c |
| 0x32 | BPL $02FD | Absolute | Branching | 3 | 5-8c |
| 0x33 | BPL $FD, A | Indexed | Branching | 2 | 4-7c |
| 0x34 | BMI $FD | Zero Page | Branching | 2 | 4-7c |
| 0x35 | BMI $02FD | Absolute | Branching | 3 | 5-8c |
| 0x36 | BMI $FD, A | Indexed | Branching | 2 | 4-7c |
| 0x37 | BOC $FD | Zero Page | Branching | 2 | 4-7c |
| 0x38 | BOC $02FD | Absolute | Branching | 3 | 5-8c |
| 0x39 | BOC $FD, A | Indexed | Branching | 2 | 4-7c |
| 0x3A | BOS $FD | Zero Page | Branching | 2 | 4-7c |
| 0x3B | BOS $02FD | Absolute | Branching | 3 | 5-8c |
| 0x3C | BOS $FD, A | Indexed | Branching | 2 | 4-7c |
| 0x3D | NOP | Implied | Misc. | 1 | 4c |
| 0x3E | NOP | Implied | Misc. | 1 | 4c |
| 0x3F | HLT | Implied | Misc. | 1 | 4c |
Does nothing and passes to the next instruction.
Loads a value into the A Register from operand or memory depending on Addressing Mode.
Loads a value into the B Register from operand or memory depending on Addressing Mode.
Stores the value of the A Register in memory
Adds a value to the A Register, value is determined from the operand depending on Addressing Mode.
Will override the B Register with the resolved value to add.
Will update the Status Register :
- O : A_8 ^ R_8
- Z : R == 0
- C : R_9 == 1
- N : R_8 == 1
Subtracts a value from the A Register, value is determined from the operand depending on Addressing Mode.
Will override the B Register with the resolved value to subtract.
Will update the Status Register :
- O : A_8 ^ R_8
- Z : R == 0
- C : R_9 == 1
- N : R_8 == 1
Clears the Status Register
Compares 2 values, the A Register and an operand determined by the Addressing Mode.
Will update the Status Register but not the A Register :
- O : A_8 ^ R_8
- Z : R == 0
- C : R_9 == 1
- N : R_8 == 1
Pushes the content of the A Register into the stack.
The stack pointer will be automatically updated.
Pushes the content of the Status Register into the stack.
The Stack Pointer will be automatically updated.
Pulls the most recent element from the stack and stores it in to A Register
The Stack Pointer will be automatically updated.
Pulls the most recent element from the stack and stores it in to B Register
The Stack Pointer will be automatically updated.
Pulls the most recent element from the stack and stores it in to Status Register
The Stack Pointer will be automatically updated.
Jumps to a subroutine, and pushes the return address into the stack.
Will take 2 bytes on the stack.
The Stack Pointer will be automatically updated.
Returns from a subroutine, by pulling the return address into the stack.
Execution will resume at the instruction right after the last JSR instruction
The Stack Pointer will be automatically updated.
Jumps to a specified address, determined by the Addressing Mode.
Jumps to a specified address, determined by the Addressing Mode if the Status Register has the Carry Flag cleared : Status & 0b0010 == 0b0000
Jumps to a specified address, determined by the Addressing Mode if the Status Register has the Carry Flag set : Status & 0b0010 == 0b0010
Jumps to a specified address, determined by the Addressing Mode if the Status Register has the Zero Flag cleared : Status & 0b0100 == 0b0001
Jumps to a specified address, determined by the Addressing Mode if the Status Register has the Zero Flag set : Status & 0b0100 == 0b0100
Jumps to a specified address, determined by the Addressing Mode if the Status Register has the Negative Flag cleared : Status & 0b0001 == 0b0000
Jumps to a specified address, determined by the Addressing Mode if the Status Register has the Negative Flag set : Status & 0b0001 == 0b0001
Jumps to a specified address, determined by the Addressing Mode if the Status Register has the Overflow Flag cleared : Status & 0b1000 == 0b0000
Jumps to a specified address, determined by the Addressing Mode if the Status Register has the Overflow Flag set : Status & 0b1000 == 0b1000
Halts the Clock until reset
Memory blocks allows you to declare a static block of memory and fill it with arbitrary data.
A Memory block is defined as follows
.block $(addr)
00 01 02 03 04 05 06 07 08 09 0A 0B 0C 0D 0E 0F
.endblock
- Declaration must start with
.blockand specify the base address - Size is arbitrary but
addr + sizeshould not exceed #FFFF, in practice higher memory address are allowed, but mirroring will be applied - A Memory Block can not be mapped to reserved addresses, which are $0000 and $0001 that are the entrypoint of execution, and $FF00 to $FFFF which is reserved for the Stack
- Declaration must end with
.endblock
Constants are the same as a memory block, but only allows for a size of 1 or 2 bytes
A constant if defined as follows
.const byte name #FF
.const word name #FFFF
Legal types are byte for 8 bits Constants and word for 16 bits Constants
- Declaration must start with
.constfollowed a type and an alias - Aliases must start with a letter, and can contain alphanumeric characters, '-' or '_'
- Value must be specified as hexadecimal and is mandatory
See Addressing Mode examples
Variable allows you to abstract a memory address, it will allocate an available address in the address space and use it as a container
A variable is defined as follows
.var name #FF
- Declaration must start with
.varfollowed by an alias - Aliases must start with a letter, and can contain alphanumeric characters, '-' or '_'
- Value is specified as Hexadecimal and is optional, if no value is passed it is assumed to be 0
See Addressing Mode examples
Labels are just memory address aliases, they are placed one line before an instruction and will reference the address of that instruction they can then be referenced by branching instructions
A Label is declared as follows
:LABEL
A Label can be referenced by branching instructions as follows
:LOOP
ADD #10
BCC @LOOP
This code will loop until the value in the A Register rolls over 0xFF and sets the Carry Flag,
the BCC instruction will jump to the address referenced by the LOOP label, which in this case is the ADD #10 instruction