Rework instruction encoding

This commit is contained in:
d0p1 🏳️‍⚧️ 2024-04-12 15:35:39 +02:00
parent 3b0e785644
commit 84f0e10070
12 changed files with 2938 additions and 47 deletions

2656
Doxyfile Normal file

File diff suppressed because it is too large Load diff

View file

@ -5,7 +5,6 @@
- PC :: Program counter (32bit)
- A :: Accumulator (32bit)
- D :: Direct register (32bit)
- X :: X index register (32bit)
- Y :: Y index register (32bit)
- SR :: status register (8bit)
@ -14,10 +13,10 @@
Status register flags
#+begin_src
31 0
+------ .... ----+-+-+-+-+-+-+-+-+
| |N|V| |B|D|I|Z|C|
+------ .... ----+-+-+-+-+-+-+-+-+
7 0
+-+-+-+-+-+-+-+-+
|N|V|0|B|D|0|Z|C|
+-+-+-+-+-+-+-+-+
#+end_src
- N :: Negative
@ -26,11 +25,12 @@ Status register flags
The overflow flag (V) indicates overflow with signed binary arithmetics.
- B :: Break
- D :: Decimal
- I :: Interrupt
- Z :: Zero
The zero flag (Z) indicates a value of all zero bits.
- C :: Carry
** Control Registers
** Addressing Modes
*** Implied Addressing
@ -53,38 +53,50 @@ A size and a literal operand is given immediately after the instruction.
** Opcodes
| | -0 | -1 | -2 | -3 | -4 | -5 | -6 | -7 | -8 | -9 | -A | -B | -C | -D | -E | -F |
|----|----------|-----------|-------|----|----|----|----|----|----------|-----------|----------|----|-----------|-----------|-----------|----|
| 0- | BRK impl | ORA X,ind | | | | | | | PHP impl | ORA # | ASL A | | | ORA abs | ASL abs | |
| 1- | BPL rel | ORA ind,Y | | | | | | | CLC impl | ORA abs,Y | | | | ORA abs,X | ASL abs,X | |
| 2- | JSR abs | AND X,ind | | | | | | | PLP impl | AND # | ROL A | | BIT abs | AND abs | ROL abs | |
| 3- | BMI rel | AND ind,Y | | | | | | | SEC impl | AND abs,Y | | | | AND abs,X | ROL abs,X | |
| 4- | RTI impl | EOR X,ind | | | | | | | PHA impl | EOR # | LSR A | | JMP abs | EOR abs | LSR abs | |
| 5- | BVC rel | EOR ind,Y | | | | | | | CLI impl | EOR abs,Y | | | | EOR abs,X | LSR abs,X | |
| 6- | RTS impl | ADC X,ind | PER? | | | | | | PLA impl | ADC # | ROR A | | JMP ind | ADC abs | ROR abs | |
| 7- | BVS rel | ADC ind,Y | | | | | | | SEI impl | ADC abs,Y | | | | ADC abs,X | ROR abs,X | |
| 8- | | STA X,ind | | | | | | | DEY impl | | TXA impl | | STY abs | STA abs | STX abs | |
| 9- | BCC rel | STA ind,Y | | | | | | | TYA impl | STA abs,Y | TXS impl | | | STA abs,X | | |
| A- | LDY # | LDA X,ind | LDX # | | | | | | TAY impl | LDA # | TAX impl | | LDY abs | LDA abs | LDX abs | |
| B- | BCS rel | LDA ind,Y | | | | | | | CLV impl | LDA abs,Y | TSX impl | | LDY abs,X | LDA abs,X | LDX abs,Y | |
| C- | CPY # | CMP X,ind | | | | | | | INY impl | CMP # | DEX impl | | CPY abs | CMP abs | DEC abs | |
| D- | BNE rel | CMP ind,Y | | | | | | | CLD impl | CMP abs,Y | | | | CMP abs,X | DEC abs,X | |
| E- | CPX # | SBC X,ind | | | | | | | INX impl | SBC # | NOP impl | | CPX abs | SBC abs | INC abs | |
| F- | BEQ rel | SBC ind,Y | | | | | | | SED impl | SBC abs,Y | | | | SBC abs,X | INC abs,X | |
| | -0 | -1 | -2 | -3 | -4 | -5 | -6 | -7 | -8 | -9 | -A | -B | -C | -D | -E | -F |
|----|----------|-----------|-------|--------|----|----|----|----|----------|-----------|----------|----|-----------|-----------|-----------|----|
| 0- | BRK impl | ORA X,ind | | prefix | | | | prefix | PHP impl | ORA # | ASL A | | | ORA abs | ASL abs | |
| 1- | BPL rel | ORA ind,Y | | prefix | | | | prefix | CLC impl | ORA abs,Y | | | | ORA abs,X | ASL abs,X | |
| 2- | JSR abs | AND X,ind | | prefix | | | | prefix | PLP impl | AND # | ROL A | | BIT abs | AND abs | ROL abs | |
| 3- | BMI rel | AND ind,Y | | prefix | | | | prefix | SEC impl | AND abs,Y | | | | AND abs,X | ROL abs,X | |
| 4- | RTI impl | EOR X,ind | | prefix | | | | prefix | PHA impl | EOR # | LSR A | | JMP abs | EOR abs | LSR abs | |
| 5- | BVC rel | EOR ind,Y | | prefix | | | | prefix | CLI impl | EOR abs,Y | | | | EOR abs,X | LSR abs,X | |
| 6- | RTS impl | ADC X,ind | PER? | prefix | | | | prefix | PLA impl | ADC # | ROR A | | JMP ind | ADC abs | ROR abs | |
| 7- | BVS rel | ADC ind,Y | | prefix | | | | prefix | SEI impl | ADC abs,Y | | | | ADC abs,X | ROR abs,X | |
| 8- | | STA X,ind | | prefix | | | | prefix | DEY impl | | TXA impl | | STY abs | STA abs | STX abs | |
| 9- | BCC rel | STA ind,Y | | prefix | | | | prefix | TYA impl | STA abs,Y | TXS impl | | | STA abs,X | | |
| A- | LDY # | LDA X,ind | LDX # | prefix | | | | prefix | TAY impl | LDA # | TAX impl | | LDY abs | LDA abs | LDX abs | |
| B- | BCS rel | LDA ind,Y | | prefix | | | | prefix | CLV impl | LDA abs,Y | TSX impl | | LDY abs,X | LDA abs,X | LDX abs,Y | |
| C- | CPY # | CMP X,ind | | prefix | | | | prefix | INY impl | CMP # | DEX impl | | CPY abs | CMP abs | DEC abs | |
| D- | BNE rel | CMP ind,Y | | prefix | | | | prefix | CLD impl | CMP abs,Y | | | | CMP abs,X | DEC abs,X | |
| E- | CPX # | SBC X,ind | | prefix | | | | prefix | INX impl | SBC # | NOP impl | | CPX abs | SBC abs | INC abs | |
| F- | BEQ rel | SBC ind,Y | | prefix | | | | prefix | SED impl | SBC abs,Y | | | | SBC abs,X | INC abs,X | |
** Instruction encoding
| 0-7 |
|--------|
| opcode |
*** Prefix
| 7 | 6 | 5 | 4 | 3 | 2 | 1 | 0 |
|---|---|---|---|---|---|---|---|
| A | A | OS | OS | 0 | S | 1 | 1 |
- OS :: Size
- 00 8bit
- 01 16bit
- 10 32bit
- 11 64bit
- A :: Address Size
- S :: sign-extension
#+begin_src
8bits 8bits 8/16/32/64bits
+--------+--------+-------...---+
| prefix | opcode | value |
+--------+--------+-------...---+
#+end_src
| 0-7 | 8-21 |
|--------|---------------|
| opcode | relative addr |
| 0-7 | 8-15 | 16-X |
|--------|------|-------|
| opcode | attr | value |
** Instructions Listing
@ -93,4 +105,10 @@ A size and a literal operand is given immediately after the instruction.
- ASL :: arithmetic shift left
- BCC :: branch on carry clear
- BCS :: branch on carry set
- BEQ :: branch on equa (zero set)
- BEQ :: branch on equal (zero set)
- BIT :: bitwise test with accumulator
- BMI :: branch on minus
- BNE :: branch not equal
- BPL :: Branch on plus
- BRK ::
- BSR ::

View file

@ -1,3 +1,3 @@
noinst_LIBRARIES = lib65oo2.a
lib65oo2_a_SOURCES = op.c
lib65oo2_a_SOURCES = op.c mnemonic.c

19
lib/addressing.h Normal file
View file

@ -0,0 +1,19 @@
#ifndef LIB_65oo2_ADDRESSING_H
# define LIB_65oo2_ADDRESSING_H 1
typedef enum
{
ADDRESSING_NONE,
ADDRESSING_IMPLIED,
ADDRESSING_ACCUMULATOR,
ADDRESSING_ABSOLUTE_X,
ADDRESSING_ABSOLUTE_Y,
ADDRESSING_IMMEDIATE,
ADDRESSING_INDIRECT,
ADDRESSING_X_INDIRECT,
ADDRESSING_INDIRECT_Y,
ADDRESSING_RELATIVE,
ADDRESSING_MAX
} AddressingMode;
#endif /* !LIB_65oo2_ADDRESSING_H */

0
lib/decoder.c Normal file
View file

33
lib/decoder.h Normal file
View file

@ -0,0 +1,33 @@
#ifndef LIB_65oo2_DECODER_H
# define LIB_65oo2_DECODER_H 1
#include <stddef.h>
#include <stdint.h>
#include "mnemonic.h"
#include "addressing.h"
typedef enum {
ADDRESS_SIZE_HINT_NONE, /* default 8bits */
ADDRESS_SIZE_HINT_16,
ADDRESS_SIZE_HINT_32,
ADDRESS_SIZE_HINT_MAX
} AddressSizeHint;
typedef enum {
OPERAND_SIZE_HINT_NONE,
OPERAND_SIZE_HINT_16,
OPERAND_SIZE_HINT_32,
OPERAND_SIZE_HINT_MAX
} OperandSizeHint;
typedef struct {
Mnemonic mnemonic;
uint8_t length;
AddressingMode addressing;
} DecodedInstruction;
int decoder_decode(uint8_t *buffer, size_t length, DecodedInstruction *instruction);
#endif /* !LIB_65oo2_DECODER_H */

0
lib/disassembler.h Normal file
View file

72
lib/mnemonic.c Normal file
View file

@ -0,0 +1,72 @@
#include "mnemonic.h"
static const char *MNEMONIC_STR[MNEMONIC_MAX] = {
"invalid",
"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"
};
const char *
mnemonic_to_string(Mnemonic mnemonic)
{
if (mnemonic >= MNEMONIC_MAX)
{
return (MNEMONIC_STR[MNEMONIC_INVALID]);
}
return (MNEMONIC_STR[mnemonic]);
}

84
lib/mnemonic.h Normal file
View file

@ -0,0 +1,84 @@
#ifndef LIB_65oo2_MNEMONIC_H
# define LIB_65oo2_MNEMONIC_H 1
typedef enum {
MNEMONIC_INVALID,
/** add with carry */
MNEMONIC_ADC,
/** and (with accumulator)*/
MNEMONIC_AND,
/** arithmetic shift left */
MNEMONIC_ASL,
/** branch on carry clear */
MNEMONIC_BCC,
/** branch on carry set */
MNEMONIC_BCS,
/** branch on equal (zero set) */
MNEMONIC_BEQ,
/** bit test */
MNEMONIC_BIT,
/** branch on minus (negative set) */
MNEMONIC_BMI,
/** branch on not equal (zero clear) */
MNEMONIC_BNE,
/** branch on plus (negative clear) */
MNEMONIC_BPL,
/** break / interrupt */
MNEMONIC_BRK,
MNEMONIC_BVC,
MNEMONIC_BVS,
MNEMONIC_CLC,
MNEMONIC_CLD,
MNEMONIC_CLI,
MNEMONIC_CLV,
MNEMONIC_CMP,
MNEMONIC_CPX,
MNEMONIC_CPY,
MNEMONIC_DEC,
MNEMONIC_DEX,
MNEMONIC_DEY,
MNEMONIC_EOR,
MNEMONIC_INC,
MNEMONIC_INX,
MNEMONIC_INY,
/** jump */
MNEMONIC_JMP,
/** jump subroutine */
MNEMONIC_JSR,
MNEMONIC_LDA,
MNEMONIC_LDX,
MNEMONIC_LDY,
MNEMONIC_LSR,
MNEMONIC_NOP,
MNEMONIC_ORA,
MNEMONIC_PHA,
MNEMONIC_PHP,
MNEMONIC_PLA,
MNEMONIC_PLP,
MNEMONIC_ROL,
MNEMONIC_ROR,
MNEMONIC_RTI,
MNEMONIC_RTS,
MNEMONIC_SBC,
MNEMONIC_SEC,
MNEMONIC_SED,
MNEMONIC_SEI,
MNEMONIC_STA,
/** store X */
MNEMONIC_STX,
/** store Y */
MNEMONIC_STY,
MNEMONIC_TAX,
MNEMONIC_TAY,
MNEMONIC_TSX,
MNEMONIC_TXA,
MNEMONIC_TXS,
MNEMONIC_TYA,
MNEMONIC_MAX
} Mnemonic;
/** Return specified mnemonic string */
const char *mnemonic_to_string(Mnemonic mnemonic);
#endif /* !LIB_65oo2_MNEMONIC_H */

View file

@ -1,3 +1,4 @@
#include <stddef.h>
#include "op.h"
const uint8_t opcode_addr[OP_MAX] = {

View file

@ -5,6 +5,8 @@
# define OP_MAX 256
# define IS_PREFIX(x) (x & 0x3)
# define OP_ADDR_IMPL 1 << 0
# define OP_ADDR_REL 1 << 1
# define OP_ADDR_IMM 1 << 2

View file

@ -1,15 +1,21 @@
#ifndef REGISTER_H
# define REGISTER_H
#ifndef LIB_65oo2_REGISTER_H
# define LIB_65oo2_REGISTER_H 1
enum
{
REG_PC,
REG_AC,
REG_X,
REG_Y,
REG_SR,
REG_SP,
REG_MAX
};
typedef enum {
REGISTER_NONE,
/** Program Counter (32bits) */
REGISTER_PC,
/** Accumulator (32bits)*/
REGISTER_AC,
/** X register (32bits)*/
REGISTER_X,
/** Y register (32bits) */
REGISTER_Y,
/** Status register (8bits) */
REGISTER_SR,
/** Stack pointer (32bits) */
REGISTER_SP,
REGISTER_MAX
} Register;
#endif /* !REGISTER_H */