Skip to content

Latest commit

 

History

History
382 lines (280 loc) · 19.4 KB

File metadata and controls

382 lines (280 loc) · 19.4 KB

8 bits Breadboard Computer - Assembly Language

Guidelines

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

Comments can be added anywhere in the code with the following syntax :

// Full comment
LDA #10    // Inline comment

Addressing Modes

This assembly is specifically designed to work with the Breadboard computer, therefore it includes all the addressing modes that the hardware implements :

Implied

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

Immediate

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)

Absolute

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

Zero Page

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

Indexed

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

Instructions

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

NOP

Does nothing and passes to the next instruction.

LDA

Loads a value into the A Register from operand or memory depending on Addressing Mode.

LDB

Loads a value into the B Register from operand or memory depending on Addressing Mode.

STA

Stores the value of the A Register in memory

ADD

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

SUB

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

CLS

Clears the Status Register

CMP

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

PHA

Pushes the content of the A Register into the stack.

The stack pointer will be automatically updated.

PHS

Pushes the content of the Status Register into the stack.

The Stack Pointer will be automatically updated.

PLA

Pulls the most recent element from the stack and stores it in to A Register

The Stack Pointer will be automatically updated.

PLB

Pulls the most recent element from the stack and stores it in to B Register

The Stack Pointer will be automatically updated.

PLS

Pulls the most recent element from the stack and stores it in to Status Register

The Stack Pointer will be automatically updated.

JSR

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.

RTS

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.

JMP

Jumps to a specified address, determined by the Addressing Mode.

BCC

Jumps to a specified address, determined by the Addressing Mode if the Status Register has the Carry Flag cleared : Status & 0b0010 == 0b0000

BCS

Jumps to a specified address, determined by the Addressing Mode if the Status Register has the Carry Flag set : Status & 0b0010 == 0b0010

BNE

Jumps to a specified address, determined by the Addressing Mode if the Status Register has the Zero Flag cleared : Status & 0b0100 == 0b0001

BEQ

Jumps to a specified address, determined by the Addressing Mode if the Status Register has the Zero Flag set : Status & 0b0100 == 0b0100

BPL

Jumps to a specified address, determined by the Addressing Mode if the Status Register has the Negative Flag cleared : Status & 0b0001 == 0b0000

BMI

Jumps to a specified address, determined by the Addressing Mode if the Status Register has the Negative Flag set : Status & 0b0001 == 0b0001

BOC

Jumps to a specified address, determined by the Addressing Mode if the Status Register has the Overflow Flag cleared : Status & 0b1000 == 0b0000

BOS

Jumps to a specified address, determined by the Addressing Mode if the Status Register has the Overflow Flag set : Status & 0b1000 == 0b1000

HLT

Halts the Clock until reset

Memory Blocks

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 .block and specify the base address
  • Size is arbitrary but addr + size should 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

Declaration

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 .const followed 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

Usages

See Addressing Mode examples

Variable

Declaration

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 .var followed 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

Usages

See Addressing Mode examples

Labels

Declaration

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

Usage

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