Rework instruction encoding
This commit is contained in:
parent
3b0e785644
commit
84f0e10070
86
doc/isa.org
86
doc/isa.org
|
@ -5,7 +5,6 @@
|
||||||
|
|
||||||
- PC :: Program counter (32bit)
|
- PC :: Program counter (32bit)
|
||||||
- A :: Accumulator (32bit)
|
- A :: Accumulator (32bit)
|
||||||
- D :: Direct register (32bit)
|
|
||||||
- X :: X index register (32bit)
|
- X :: X index register (32bit)
|
||||||
- Y :: Y index register (32bit)
|
- Y :: Y index register (32bit)
|
||||||
- SR :: status register (8bit)
|
- SR :: status register (8bit)
|
||||||
|
@ -14,10 +13,10 @@
|
||||||
Status register flags
|
Status register flags
|
||||||
|
|
||||||
#+begin_src
|
#+begin_src
|
||||||
31 0
|
7 0
|
||||||
+------ .... ----+-+-+-+-+-+-+-+-+
|
+-+-+-+-+-+-+-+-+
|
||||||
| |N|V| |B|D|I|Z|C|
|
|N|V|0|B|D|0|Z|C|
|
||||||
+------ .... ----+-+-+-+-+-+-+-+-+
|
+-+-+-+-+-+-+-+-+
|
||||||
#+end_src
|
#+end_src
|
||||||
|
|
||||||
- N :: Negative
|
- N :: Negative
|
||||||
|
@ -26,11 +25,12 @@ Status register flags
|
||||||
The overflow flag (V) indicates overflow with signed binary arithmetics.
|
The overflow flag (V) indicates overflow with signed binary arithmetics.
|
||||||
- B :: Break
|
- B :: Break
|
||||||
- D :: Decimal
|
- D :: Decimal
|
||||||
- I :: Interrupt
|
|
||||||
- Z :: Zero
|
- Z :: Zero
|
||||||
The zero flag (Z) indicates a value of all zero bits.
|
The zero flag (Z) indicates a value of all zero bits.
|
||||||
- C :: Carry
|
- C :: Carry
|
||||||
|
|
||||||
|
** Control Registers
|
||||||
|
|
||||||
** Addressing Modes
|
** Addressing Modes
|
||||||
|
|
||||||
*** Implied Addressing
|
*** Implied Addressing
|
||||||
|
@ -53,38 +53,50 @@ A size and a literal operand is given immediately after the instruction.
|
||||||
|
|
||||||
** Opcodes
|
** Opcodes
|
||||||
|
|
||||||
| | -0 | -1 | -2 | -3 | -4 | -5 | -6 | -7 | -8 | -9 | -A | -B | -C | -D | -E | -F |
|
| | -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 | |
|
| 0- | BRK impl | ORA X,ind | | prefix | | | | prefix | 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 | |
|
| 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 | | | | | | | PLP impl | AND # | ROL A | | BIT abs | AND abs | ROL abs | |
|
| 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 | | | | | | | SEC impl | AND abs,Y | | | | AND abs,X | ROL abs,X | |
|
| 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 | | | | | | | PHA impl | EOR # | LSR A | | JMP abs | EOR abs | LSR abs | |
|
| 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 | | | | | | | CLI impl | EOR abs,Y | | | | EOR abs,X | LSR abs,X | |
|
| 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? | | | | | | PLA impl | ADC # | ROR A | | JMP ind | ADC abs | ROR abs | |
|
| 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 | | | | | | | SEI impl | ADC abs,Y | | | | ADC abs,X | ROR abs,X | |
|
| 7- | BVS rel | ADC ind,Y | | prefix | | | | prefix | 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 | |
|
| 8- | | STA X,ind | | prefix | | | | prefix | 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 | | |
|
| 9- | BCC rel | STA ind,Y | | prefix | | | | prefix | 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 | |
|
| 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 | | | | | | | CLV impl | LDA abs,Y | TSX impl | | LDY abs,X | LDA abs,X | LDX abs,Y | |
|
| 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 | | | | | | | INY impl | CMP # | DEX impl | | CPY abs | CMP abs | DEC abs | |
|
| C- | CPY # | CMP X,ind | | prefix | | | | prefix | 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 | |
|
| D- | BNE rel | CMP ind,Y | | prefix | | | | prefix | 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 | |
|
| E- | CPX # | SBC X,ind | | prefix | | | | prefix | 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 | |
|
| F- | BEQ rel | SBC ind,Y | | prefix | | | | prefix | SED impl | SBC abs,Y | | | | SBC abs,X | INC abs,X | |
|
||||||
|
|
||||||
** Instruction encoding
|
** Instruction encoding
|
||||||
|
|
||||||
| 0-7 |
|
*** Prefix
|
||||||
|--------|
|
|
||||||
| opcode |
|
| 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
|
** Instructions Listing
|
||||||
|
|
||||||
|
@ -93,4 +105,10 @@ A size and a literal operand is given immediately after the instruction.
|
||||||
- ASL :: arithmetic shift left
|
- ASL :: arithmetic shift left
|
||||||
- BCC :: branch on carry clear
|
- BCC :: branch on carry clear
|
||||||
- BCS :: branch on carry set
|
- 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 ::
|
||||||
|
|
|
@ -1,3 +1,3 @@
|
||||||
noinst_LIBRARIES = lib65oo2.a
|
noinst_LIBRARIES = lib65oo2.a
|
||||||
|
|
||||||
lib65oo2_a_SOURCES = op.c
|
lib65oo2_a_SOURCES = op.c mnemonic.c
|
19
lib/addressing.h
Normal file
19
lib/addressing.h
Normal 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
0
lib/decoder.c
Normal file
33
lib/decoder.h
Normal file
33
lib/decoder.h
Normal 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
0
lib/disassembler.h
Normal file
72
lib/mnemonic.c
Normal file
72
lib/mnemonic.c
Normal 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
84
lib/mnemonic.h
Normal 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 */
|
1
lib/op.c
1
lib/op.c
|
@ -1,3 +1,4 @@
|
||||||
|
#include <stddef.h>
|
||||||
#include "op.h"
|
#include "op.h"
|
||||||
|
|
||||||
const uint8_t opcode_addr[OP_MAX] = {
|
const uint8_t opcode_addr[OP_MAX] = {
|
||||||
|
|
2
lib/op.h
2
lib/op.h
|
@ -5,6 +5,8 @@
|
||||||
|
|
||||||
# define OP_MAX 256
|
# define OP_MAX 256
|
||||||
|
|
||||||
|
# define IS_PREFIX(x) (x & 0x3)
|
||||||
|
|
||||||
# define OP_ADDR_IMPL 1 << 0
|
# define OP_ADDR_IMPL 1 << 0
|
||||||
# define OP_ADDR_REL 1 << 1
|
# define OP_ADDR_REL 1 << 1
|
||||||
# define OP_ADDR_IMM 1 << 2
|
# define OP_ADDR_IMM 1 << 2
|
||||||
|
|
|
@ -1,15 +1,21 @@
|
||||||
#ifndef REGISTER_H
|
#ifndef LIB_65oo2_REGISTER_H
|
||||||
# define REGISTER_H
|
# define LIB_65oo2_REGISTER_H 1
|
||||||
|
|
||||||
enum
|
typedef enum {
|
||||||
{
|
REGISTER_NONE,
|
||||||
REG_PC,
|
/** Program Counter (32bits) */
|
||||||
REG_AC,
|
REGISTER_PC,
|
||||||
REG_X,
|
/** Accumulator (32bits)*/
|
||||||
REG_Y,
|
REGISTER_AC,
|
||||||
REG_SR,
|
/** X register (32bits)*/
|
||||||
REG_SP,
|
REGISTER_X,
|
||||||
REG_MAX
|
/** Y register (32bits) */
|
||||||
};
|
REGISTER_Y,
|
||||||
|
/** Status register (8bits) */
|
||||||
|
REGISTER_SR,
|
||||||
|
/** Stack pointer (32bits) */
|
||||||
|
REGISTER_SP,
|
||||||
|
REGISTER_MAX
|
||||||
|
} Register;
|
||||||
|
|
||||||
#endif /* !REGISTER_H */
|
#endif /* !REGISTER_H */
|
||||||
|
|
Loading…
Reference in a new issue