diff --git a/.gitignore b/.gitignore index 7916534..199ea75 100644 --- a/.gitignore +++ b/.gitignore @@ -1,180 +1,182 @@ -# ---> C -# Prerequisites -*.d - -# Object files -*.o -*.ko -*.obj -*.elf - -# Linker output -*.ilk -*.map -*.exp - -# Precompiled Headers -*.gch -*.pch - -# Libraries -*.lib -*.a -*.la -*.lo - -# Shared objects (inc. Windows DLLs) -*.dll -*.so -*.so.* -*.dylib - -# Executables -*.exe -*.out -*.app -*.i*86 -*.x86_64 -*.hex - -# Debug files -*.dSYM/ -*.su -*.idb -*.pdb - -# Kernel Module Compile Results -*.mod* -*.cmd -.tmp_versions/ -modules.order -Module.symvers -Mkfile.old -dkms.conf - -# ---> Autotools -# http://www.gnu.org/software/automake - -Makefile.in -/ar-lib -/mdate-sh -/py-compile -/test-driver -/ylwrap -.deps/ -.dirstamp - -# http://www.gnu.org/software/autoconf - -autom4te.cache -/autoscan.log -/autoscan-*.log -/aclocal.m4 -/compile -/config.cache -/config.guess -/config.h.in -/config.log -/config.status -/config.sub -/configure -/configure.scan -/depcomp -/install-sh -/missing -/stamp-h1 - -# https://www.gnu.org/software/libtool/ - -/ltmain.sh - -# http://www.gnu.org/software/texinfo - -/texinfo.tex - -# http://www.gnu.org/software/m4/ - -m4/libtool.m4 -m4/ltoptions.m4 -m4/ltsugar.m4 -m4/ltversion.m4 -m4/lt~obsolete.m4 - -# Generated Makefile -# (meta build system like autotools, -# can automatically generate from config.status script -# (which is called by configure script)) -Makefile - -# ---> Emacs -# -*- mode: gitignore; -*- -*~ -\#*\# -/.emacs.desktop -/.emacs.desktop.lock -*.elc -auto-save-list -tramp -.\#* - -# Org-mode -.org-id-locations -*_archive - -# flymake-mode -*_flymake.* - -# eshell files -/eshell/history -/eshell/lastdir - -# elpa packages -/elpa/ - -# reftex files -*.rel - -# AUCTeX auto folder -/auto/ - -# cask packages -.cask/ -dist/ - -# Flycheck -flycheck_*.el - -# server auth directory -/server/ - -# projectiles files -.projectile - -# directory configuration -.dir-locals.el - -# network security -/network-security.data - - -# ---> Vim -# Swap -[._]*.s[a-v][a-z] -!*.svg # comment out if you don't need vector files -[._]*.sw[a-p] -[._]s[a-rt-v][a-z] -[._]ss[a-gi-z] -[._]sw[a-p] - -# Session -Session.vim -Sessionx.vim - -# Temporary -.netrwhist -*~ -# Auto-generated tag files -tags -# Persistent undo -[._]*.un~ - +# ---> C +# Prerequisites +*.d + +# Object files +*.o +*.ko +*.obj +*.elf + +# Linker output +*.ilk +*.map +*.exp + +# Precompiled Headers +*.gch +*.pch + +# Libraries +*.lib +*.a +*.la +*.lo + +# Shared objects (inc. Windows DLLs) +*.dll +*.so +*.so.* +*.dylib + +# Executables +*.exe +*.out +*.app +*.i*86 +*.x86_64 +*.hex + +# Debug files +*.dSYM/ +*.su +*.idb +*.pdb + +# Kernel Module Compile Results +*.mod* +*.cmd +.tmp_versions/ +modules.order +Module.symvers +Mkfile.old +dkms.conf + +# ---> Autotools +# http://www.gnu.org/software/automake + +Makefile.in +/ar-lib +/mdate-sh +/py-compile +/test-driver +/ylwrap +.deps/ +.dirstamp + +# http://www.gnu.org/software/autoconf + +autom4te.cache +/autoscan.log +/autoscan-*.log +/aclocal.m4 +/compile +/config.cache +/config.guess +/config.h.in +/config.log +/config.status +/config.sub +/configure +/configure.scan +/depcomp +/install-sh +/missing +/stamp-h1 + +# https://www.gnu.org/software/libtool/ + +/ltmain.sh + +# http://www.gnu.org/software/texinfo + +/texinfo.tex + +# http://www.gnu.org/software/m4/ + +m4/libtool.m4 +m4/ltoptions.m4 +m4/ltsugar.m4 +m4/ltversion.m4 +m4/lt~obsolete.m4 + +# Generated Makefile +# (meta build system like autotools, +# can automatically generate from config.status script +# (which is called by configure script)) +Makefile + +# ---> Emacs +# -*- mode: gitignore; -*- +*~ +\#*\# +/.emacs.desktop +/.emacs.desktop.lock +*.elc +auto-save-list +tramp +.\#* + +# Org-mode +.org-id-locations +*_archive + +# flymake-mode +*_flymake.* + +# eshell files +/eshell/history +/eshell/lastdir + +# elpa packages +/elpa/ + +# reftex files +*.rel + +# AUCTeX auto folder +/auto/ + +# cask packages +.cask/ +dist/ + +# Flycheck +flycheck_*.el + +# server auth directory +/server/ + +# projectiles files +.projectile + +# directory configuration +.dir-locals.el + +# network security +/network-security.data + + +# ---> Vim +# Swap +[._]*.s[a-v][a-z] +!*.svg # comment out if you don't need vector files +[._]*.sw[a-p] +[._]s[a-rt-v][a-z] +[._]ss[a-gi-z] +[._]sw[a-p] + +# Session +Session.vim +Sessionx.vim + +# Temporary +.netrwhist +*~ +# Auto-generated tag files +tags +# Persistent undo +[._]*.un~ + +*.html +/build \ No newline at end of file diff --git a/Makefile.am b/Makefile.am new file mode 100644 index 0000000..792d78e --- /dev/null +++ b/Makefile.am @@ -0,0 +1 @@ +SUBDIRS = lib disas vm \ No newline at end of file diff --git a/README.md b/README.md index 41d3415..4476384 100644 --- a/README.md +++ b/README.md @@ -1,2 +1,3 @@ -# 326502 - +# 65∞2 + +What Could Possibly Go Wrong? 🤪 diff --git a/configure.ac b/configure.ac new file mode 100644 index 0000000..7bad3c9 --- /dev/null +++ b/configure.ac @@ -0,0 +1,21 @@ +AC_INIT([65oo2], [1.0]) + +AM_INIT_AUTOMAKE([foreign subdir-objects]) + +AC_LANG(C) +AC_PROG_CC +AC_PROG_CPP +AC_PROG_INSTALL +AC_PROG_RANLIB +AM_PROG_AR +AM_PROG_CC_C_O + +AC_CHECK_INCLUDES_DEFAULT +AC_C_CONST + +AC_CONFIG_FILES([ + Makefile + lib/Makefile + disas/Makefile + vm/Makefile]) +AC_OUTPUT \ No newline at end of file diff --git a/disas/Makefile.am b/disas/Makefile.am new file mode 100644 index 0000000..854cd05 --- /dev/null +++ b/disas/Makefile.am @@ -0,0 +1,5 @@ +bin_PROGRAMS = disas + +disas_SOURCES = main.c +disas_CFLAGS =-I$(top_srcdir) +disas_LDADD = ../lib/lib65oo2.a \ No newline at end of file diff --git a/disas/main.c b/disas/main.c new file mode 100644 index 0000000..e161e1c --- /dev/null +++ b/disas/main.c @@ -0,0 +1,196 @@ +#include +#include +#include +#include +#include "lib/op.h" + +#define OP_ADDR_MODE (OP_ADDR_IMPL | OP_ADDR_REL | OP_ADDR_IND \ + | OP_ADDR_IMM | OP_ADDR_ABS) + +char *prg_name; +FILE *input; +FILE *output; + +uint8_t +readu8(void) +{ + uint8_t val; + + if (fread(&val, 1, 1, input) != 1) + { + return (-1); /* XXX: TODO */ + } + + return (val); +} + +uint16_t +readu16(void) +{ + uint16_t val; + + if (fread(&val, 1, 2, input) != 2) + { + return (-1); /* XXX: TODO */ + } + + return (val); +} + +uint32_t +readu32(void) +{ + uint32_t val; + + if (fread(&val, 1, 4, input) != 4) + { + return (-1); /* XXX: TODO */ + } + + return (val); +} + +int16_t +read16(void) +{ + int16_t val; + + if (fread(&val, 1, 2, input) != 2) + { + return (-1); /* XXX: TODO */ + } + + return (val); +} + +int32_t +read32(void) +{ + int32_t val; + + if (fread(&val, 1, 4, input) != 4) + { + return (-1); /* XXX: TODO */ + } + + return (val); +} + +void +fatal(const char *str, ...) +{ + va_list ap; + + fprintf(stderr, "%s: ", prg_name); + va_start(ap, str); + vfprintf(stderr, str, ap); + va_end(ap); + fprintf(stderr, "\n"); + + exit(EXIT_FAILURE); +} + +void +decode_imm(uint8_t opcode) +{ + uint8_t attr; + + attr = readu8(); + if ((attr & 0x3) == 0x3) + { + fprintf(output, "???\n"); + return; + } + + fprintf(output, "%s.", opcode_str[opcode]); + + switch (attr & 0x3) + { + case 0x0: + fprintf(output, "B #%X\n", readu8()); + break; + case 0x1: + fprintf(output, "W #%hX\n", readu16()); + break; + case 0x2: + fprintf(output, "D #%X\n", readu32()); + break; + default: + break; + } +} + +void +decode_ind(uint8_t opcode) +{ + uint8_t attr; + + attr = readu8(); + (void)attr; +} + +void +decode_abs(uint8_t opcode) +{ + uint8_t attr; + + attr = readu8(); + (void)attr; +} + +void +decode(void) +{ + uint8_t opcode; + int16_t relative; + + do { + opcode = readu8(); + switch (opcode_addr[opcode] & OP_ADDR_MODE) + { + case OP_ADDR_IMPL: + fprintf(output, "%s\n", opcode_str[opcode]); + break; + case OP_ADDR_REL: + relative = read16(); + fprintf(output, "%s $%hX\n", opcode_str[opcode], relative); + break; + case OP_ADDR_IMM: + decode_imm(opcode); + break; + case OP_ADDR_IND: + decode_ind(opcode); + break; + case OP_ADDR_ABS: + decode_abs(opcode); + break; + default: + fprintf(output, "???\n", opcode); + break; + } + } while (!feof(input)); +} + +int +main(int argc, char **argv) +{ + prg_name = argv[0]; + input = stdin; + output = stdout; + + if (argc > 2) + { + output = fopen(argv[2], "w"); + if (output == NULL) fatal("can't open %s.", argv[2]); + } + + if (argc > 1) + { + input = fopen(argv[1], "rb"); + if (input == NULL) fatal("can't open %s.", argv[1]); + } + + decode(); + + return (EXIT_SUCCESS); +} diff --git a/doc/isa.org b/doc/isa.org new file mode 100644 index 0000000..be27e21 --- /dev/null +++ b/doc/isa.org @@ -0,0 +1,99 @@ +#+title: 65∞2 Instruction Set Architecture +#+author: d0p1 + +** Registers + +- PC :: Program counter (32bit) +- AC :: Accumulator (32bit) +- X :: X register (32bit) +- Y :: Y register (32bit) +- SR :: status register (32bit) +- SP :: stack pointer (32bit) + +Status register flags + +#+begin_src + 31 0 + +------ .... ----+-+-+-+-+-+-+-+-+ + | |N|V| |B|D|I|Z|C| + +------ .... ----+-+-+-+-+-+-+-+-+ +#+end_src + +- N :: Negative + The negative flag (N) indicates the presence of a set sign bit in bit-position 31. +- V :: Overflow + 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 + +** Addressing Modes + +*** Implied Addressing + +*** Immediate Addressing + +A size and a literal operand is given immediately after the instruction. + +#+begin_src asm + LDA.B #7 + LDA.W #300 + LDA.D #$DEADBEEF +#+end_src + +*** Absolute Addressing + +** Opcodes + +#+begin_src + +----+----------+-----------+-------+----+-----------+-----------+-----------+----+----------+-----------+----------+----+-----------+-----------+-----------+----+ + | | -0 | -1 | -2 | -3 | -4 | -5 | -6 | -7 | -8 | -9 | -A | -B | -C | -D | -E | -F | + +----+----------+-----------+-------+----+-----------+-----------+-----------+----+----------+-----------+----------+----+-----------+-----------+-----------+----+ + | 0- | BRK impl | ORA X,ind | | | | ORA zpg | ASL zpg | | PHP impl | ORA # | ASL A | | | ORA abs | ASL abs | | + | 1- | BPL rel | ORA ind,Y | | | | ORA zpg,X | ASL zpg,X | | CLC impl | ORA abs,Y | | | | ORA abs,X | ASL abs,X | | + | 2- | JSR abs | AND X,ind | | | BIT zpg | AND zpg | ROL zpg | | PLP impl | AND # | ROL A | | BIT abs | AND abs | ROL abs | | + | 3- | BMI rel | AND ind,Y | | | | AND zpg,X | ROL zpg,X | | SEC impl | AND abs,Y | | | | AND abs,X | ROL abs,X | | + | 4- | RTI impl | EOR X,ind | | | | EOR zpg | LSR zpg | | PHA impl | EOR # | LSR A | | JMP abs | EOR abs | LSR abs | | + | 5- | BVC rel | EOR ind,Y | | | | EOR zpg,X | LSR zpg,X | | CLI impl | EOR abs,Y | | | | EOR abs,X | LSR abs,X | | + | 6- | RTS impl | ADC X,ind | | | | ADC zpg | ROR zpg | | PLA impl | ADC # | ROR A | | JMP ind | ADC abs | ROR abs | | + | 7- | BVS rel | ADC ind,Y | | | | ADC zpg,X | ROR zpg,X | | SEI impl | ADC abs,Y | | | | ADC abs,X | ROR abs,X | | + | 8- | | STA X,ind | | | STY zpg | STA zpg | STX zpg | | DEY impl | | TXA impl | | STY abs | STA abs | STX abs | | + | 9- | BCC rel | STA ind,Y | | | STY zpg,X | STA zpg,X | STX zpg,Y | | TYA impl | STA abs,Y | TXS impl | | | STA abs,X | | | + | A- | LDY # | LDA X,ind | LDX # | | LDY zpg | LDA zpg | LDX zpg | | TAY impl | LDA # | TAX impl | | LDY abs | LDA abs | LDX abs | | + | B- | BCS rel | LDA ind,Y | | | LDY zpg,X | LDA zpg,X | LDX zpg,Y | | CLV impl | LDA abs,Y | TSX impl | | LDY abs,X | LDA abs,X | LDX abs,Y | | + | C- | CPY # | CMP X,ind | | | CPY zpg | CMP zpg | DEC zpg | | INY impl | CMP # | DEX impl | | CPY abs | CMP abs | DEC abs | | + | D- | BNE rel | CMP ind,Y | | | | CMP zpg,X | DEC zpg,X | | CLD impl | CMP abs,Y | | | | CMP abs,X | DEC abs,X | | + | E- | CPX # | SBC X,ind | | | CPX zpg | SBC zpg | INC zpg | | INX impl | SBC # | NOP impl | | CPX abs | SBC abs | INC abs | | + | F- | BEQ rel | SBC ind,Y | | | | SBC zpg,X | INC zpg,X | | SED impl | SBC abs,Y | | | | SBC abs,X | INC abs,X | | + +----+----------+-----------+-------+----+-----------+-----------+-----------+----+----------+-----------+----------+----+-----------+-----------+-----------+----+ +#+end_src + +** Instruction encoding + +| 0-7 | +|--------| +| opcode | + +| 0-7 | 8-21 | +|--------|---------------| +| opcode | relative addr | + +| 0-7 | 8-15 | 16-X | +|--------|------|-------| +| opcode | attr | value | + +* Instruction Set + +| OP | ATTR | IMM | Size | Note | +|----|------|----------|------|-------------------------------------| +| 00 | | | 1 | Break | +| 01 | | XXXX | 3 | Or with accumulator | +| 08 | | | 1 | Push processor status | +| 09 | 01 | XX | 3 | Or with accumulator | +| 09 | 02 | XXXX | 4 | Or with accumulator | +| 09 | 03 | XXXXXXXX | 6 | Or with accumulator | +| 0A | | | 1 | Shift Left One Bit with accumulator | +| 10 | | XXXX | 3 | Branch on plus | diff --git a/lib/Makefile.am b/lib/Makefile.am new file mode 100644 index 0000000..2d2af21 --- /dev/null +++ b/lib/Makefile.am @@ -0,0 +1,3 @@ +noinst_LIBRARIES = lib65oo2.a + +lib65oo2_a_SOURCES = op.c \ No newline at end of file diff --git a/lib/op.c b/lib/op.c new file mode 100644 index 0000000..261fb89 --- /dev/null +++ b/lib/op.c @@ -0,0 +1,310 @@ +#include "op.h" + +const uint8_t opcode_addr[OP_MAX] = { + /* 0- */ + /* BRK */ OP_ADDR_IMPL, + /* ORA */ OP_ADDR_IND | OP_ADDR_X, + /* */ 0xFF, + /* */ 0xFF, + /* */ 0xFF, + /* ORA */ 0xFF, + /* ASL */ 0xFF, + /* */ 0xFF, + /* PHP */ OP_ADDR_IMPL, + /* ORA */ OP_ADDR_IMM, + /* ASL */ OP_ADDR_IMPL, + /* */ 0xFF, + /* */ 0xFF, + /* ORA */ OP_ADDR_ABS, + /* ASL */ OP_ADDR_ABS, + /* */ 0xFF, + + /* 1- */ + /* BPL */ OP_ADDR_REL, + /* ORA */ OP_ADDR_IND | OP_ADDR_Y, + /* */ 0xFF, + /* */ 0xFF, + /* */ 0xFF, + /* ORA */ 0xFF, + /* ASL */ 0xFF, + /* */ 0xFF, + /* CLC */ OP_ADDR_IMPL, + /* ORA */ OP_ADDR_ABS | OP_ADDR_Y, + /* */ 0xFF, + /* */ 0xFF, + /* */ 0xFF, + /* ORA */ OP_ADDR_ABS | OP_ADDR_X, + /* ASL */ OP_ADDR_ABS | OP_ADDR_X, + /* */ 0xFF, + + /* 2- */ + /* JSR */ OP_ADDR_ABS, + /* AND */ OP_ADDR_IND | OP_ADDR_Y, + /* */ 0xFF, + /* */ 0xFF, + /* BIT */ 0xFF, + /* AND */ 0xFF, + /* ROL */ 0xFF, + /* */ 0xFF, + /* PLP */ OP_ADDR_IMPL, + /* AND */ OP_ADDR_IMM, + /* ROL */ OP_ADDR_IMPL, + /* */ 0xFF, + /* BIT */ OP_ADDR_ABS, + /* AND */ OP_ADDR_ABS, + /* ROL */ OP_ADDR_ABS, + /* */ 0xFF, + + /* 3- */ + /* BMI */ OP_ADDR_REL, + /* AND */ OP_ADDR_IND | OP_ADDR_Y, + /* */ 0xFF, + /* */ 0xFF, + /* */ 0xFF, + /* AND */ 0xFF, + /* ROL */ 0xFF, + /* */ 0xFF, + /* SEC */ OP_ADDR_IMPL, + /* AND */ OP_ADDR_ABS | OP_ADDR_Y, + /* */ 0xFF, + /* */ 0xFF, + /* */ 0xFF, + /* AND */ OP_ADDR_ABS | OP_ADDR_X, + /* ROL */ OP_ADDR_ABS | OP_ADDR_X, + /* */ 0xFF, + + /* 4- */ + /* RTI */ OP_ADDR_IMPL, + /* EOR */ OP_ADDR_IND | OP_ADDR_X, + /* */ 0xFF, + /* */ 0xFF, + /* */ 0xFF, + /* EOR */ 0xFF, + /* LSR */ 0xFF, + /* */ 0xFF, + /* PHA */ OP_ADDR_IMPL, + /* EOR */ OP_ADDR_IMM, + /* LSR */ OP_ADDR_IMPL, + /* */ 0xFF, + /* JMP */ OP_ADDR_ABS, + /* EOR */ OP_ADDR_ABS, + /* LSR */ OP_ADDR_ABS, + /* */ 0xFF, + + /* 5- */ + /* BVC */ OP_ADDR_REL, + /* EOR */ OP_ADDR_IND | OP_ADDR_Y, + /* */ 0xFF, + /* */ 0xFF, + /* */ 0xFF, + /* EOR */ 0xFF, + /* LSR */ 0xFF, + /* */ 0xFF, + /* CLI */ OP_ADDR_IMPL, + /* EOR */ OP_ADDR_ABS | OP_ADDR_Y, + /* */ 0xFF, + /* */ 0xFF, + /* */ 0xFF, + /* EOR */ OP_ADDR_ABS | OP_ADDR_X, + /* LSR */ OP_ADDR_ABS | OP_ADDR_X, + /* */ 0xFF, + + /* 6- */ + /* RTS */ OP_ADDR_IMPL, + /* ADC */ OP_ADDR_IND | OP_ADDR_X, + /* */ 0xFF, + /* */ 0xFF, + /* */ 0xFF, + /* ADC */ 0xFF, + /* ROR */ 0xFF, + /* */ 0xFF, + /* PLA */ OP_ADDR_IMPL, + /* ADC */ OP_ADDR_IMM, + /* ROR */ OP_ADDR_IMPL, + /* */ 0xFF, + /* JMP */ OP_ADDR_IND, + /* ADC */ OP_ADDR_ABS, + /* ROR */ OP_ADDR_ABS, + /* */ 0xFF, + + /* 7- */ + /* BVS */ OP_ADDR_REL, + /* ADC */ OP_ADDR_IND | OP_ADDR_Y, + /* */ 0xFF, + /* */ 0xFF, + /* */ 0xFF, + /* ADC */ 0xFF, + /* ROR */ 0xFF, + /* */ 0xFF, + /* SEI */ OP_ADDR_IMPL, + /* ADC */ OP_ADDR_ABS | OP_ADDR_Y, + /* */ 0xFF, + /* */ 0xFF, + /* */ 0xFF, + /* ADC */ OP_ADDR_ABS | OP_ADDR_X, + /* ROR */ OP_ADDR_ABS | OP_ADDR_X, + /* */ 0xFF, + + /* 8- */ + /* */ 0xFF, + /* STA */ OP_ADDR_IND | OP_ADDR_X, + /* */ 0xFF, + /* */ 0xFF, + /* STY */ 0xFF, + /* STA */ 0xFF, + /* STX */ 0xFF, + /* */ 0xFF, + /* DEY */ OP_ADDR_IMPL, + /* */ 0xFF, + /* TXA */ OP_ADDR_IMPL, + /* */ 0xFF, + /* STY */ OP_ADDR_ABS, + /* STA */ OP_ADDR_ABS, + /* STX */ OP_ADDR_ABS, + /* */ 0xFF, + + /* 9- */ + /* BCC */ OP_ADDR_REL, + /* STA */ OP_ADDR_IND | OP_ADDR_Y, + /* */ 0xFF, + /* */ 0xFF, + /* STY */ 0xFF, + /* STA */ 0xFF, + /* STX */ 0xFF, + /* */ 0xFF, + /* TYA */ OP_ADDR_IMPL, + /* STA */ OP_ADDR_ABS | OP_ADDR_Y, + /* TXS */ OP_ADDR_IMPL, + /* */ 0xFF, + /* */ 0xFF, + /* STA */ OP_ADDR_ABS | OP_ADDR_X, + /* */ 0xFF, + /* */ 0xFF, + + /* A- */ + /* LDY */ OP_ADDR_IMM, + /* LDA */ OP_ADDR_IND | OP_ADDR_X, + /* LDX */ OP_ADDR_IMM, + /* */ 0xFF, + /* LDY */ 0xFF, + /* LDA */ 0xFF, + /* LDX */ 0xFF, + /* */ 0xFF, + /* TAY */ OP_ADDR_IMPL, + /* LDA */ OP_ADDR_IMM, + /* TAX */ OP_ADDR_IMPL, + /* */ 0xFF, + /* LDY */ OP_ADDR_ABS, + /* LDA */ OP_ADDR_ABS, + /* LDX */ OP_ADDR_ABS, + /* */ 0xFF, + + /* B- */ + /* BCS */ OP_ADDR_REL, + /* LDA */ OP_ADDR_IND | OP_ADDR_Y, + /* */ 0xFF, + /* */ 0xFF, + /* LDY */ 0xFF, + /* LDA */ 0xFF, + /* LDX */ 0xFF, + /* */ 0xFF, + /* CLV */ OP_ADDR_IMPL, + /* LDA */ OP_ADDR_ABS | OP_ADDR_Y, + /* TSX */ OP_ADDR_IMPL, + /* */ 0xFF, + /* LDY */ OP_ADDR_ABS | OP_ADDR_X, + /* LDA */ OP_ADDR_ABS | OP_ADDR_X, + /* LDX */ OP_ADDR_ABS | OP_ADDR_Y, + /* */ 0xFF, + + /* C- */ + /* CPY */ OP_ADDR_IMM, + /* CMP */ OP_ADDR_IND | OP_ADDR_X, + /* */ 0xFF, + /* */ 0xFF, + /* CPY */ 0xFF, + /* CMP */ 0xFF, + /* DEC */ 0xFF, + /* */ 0xFF, + /* INY */ OP_ADDR_IMPL, + /* CMP */ OP_ADDR_IMM, + /* DEX */ OP_ADDR_IMPL, + /* */ 0xFF, + /* CPY */ OP_ADDR_ABS, + /* CMP */ OP_ADDR_ABS, + /* DEC */ OP_ADDR_ABS, + /* */ 0xFF, + + /* D- */ + /* BNE */ OP_ADDR_REL, + /* CMP */ OP_ADDR_IND | OP_ADDR_Y, + /* */ 0xFF, + /* */ 0xFF, + /* */ 0xFF, + /* CMP */ 0xFF, + /* DEC */ 0xFF, + /* */ 0xFF, + /* CLD */ OP_ADDR_IMPL, + /* CMP */ OP_ADDR_ABS | OP_ADDR_Y, + /* */ 0xFF, + /* */ 0xFF, + /* */ 0xFF, + /* CMP */ OP_ADDR_ABS | OP_ADDR_X, + /* DEC */ OP_ADDR_ABS | OP_ADDR_X, + /* */ 0xFF, + + /* E- */ + /* CPX */ OP_ADDR_IMM, + /* SBC */ OP_ADDR_IND | OP_ADDR_X, + /* */ 0xFF, + /* */ 0xFF, + /* CPX */ 0xFF, + /* SBC */ 0xFF, + /* INC */ 0xFF, + /* */ 0xFF, + /* INX */ OP_ADDR_IMPL, + /* SBC */ OP_ADDR_IMM, + /* NOP */ OP_ADDR_IMPL, + /* */ 0xFF, + /* CPX */ OP_ADDR_ABS, + /* SBC */ OP_ADDR_ABS, + /* INC */ OP_ADDR_ABS, + /* */ 0xFF, + + /* F- */ + /* BEQ */ OP_ADDR_REL, + /* SBC */ OP_ADDR_IND | OP_ADDR_Y, + /* */ 0xFF, + /* */ 0xFF, + /* */ 0xFF, + /* SBC */ 0xFF, + /* INC */ 0xFF, + /* */ 0xFF, + /* SED */ OP_ADDR_IMPL, + /* SBC */ OP_ADDR_ABS | OP_ADDR_Y, + /* */ 0xFF, + /* */ 0xFF, + /* */ 0xFF, + /* SBC */ OP_ADDR_ABS | OP_ADDR_X, + /* INC */ OP_ADDR_ABS | OP_ADDR_X, + /* */ 0xFF +}; + +const char *opcode_str[OP_MAX] = { + "BRK", "ORA", NULL, NULL, NULL, "ORA", "ASL", NULL, "PHP", "ORA", "ASLA", NULL, NULL, "ORA", "ASL", NULL, + "BPL", "ORA", NULL, NULL, NULL, "ORA", "ASL", NULL, "CLC", "ORA", NULL, NULL, NULL, "ORA", "ASL", NULL, + "JSR", "AND", NULL, NULL, "BIT", "AND", "ROL", NULL, "PLP", "AND", "ROLA", NULL, "BIT", "AND", "ROL", NULL, + "BMI", "AND", NULL, NULL, NULL, "AND", "ROL", NULL, "SEC", "AND", NULL, NULL, NULL, "AND", "ROL", NULL, + "RTI", "EOR", NULL, NULL, NULL, "EOR", "LSR", NULL, "PHA", "EOR", "LSRA", NULL, "JMP", "EOR", "LSR", NULL, + "BVC", "EOR", NULL, NULL, NULL, "EOR", "LSR", NULL, "CLI", "EOR", NULL, NULL, NULL, "EOR", "LSR", NULL, + "RTS", "ADC", NULL, NULL, NULL, "ADC", "ROR", NULL, "PLA", "ADC", "RORA", NULL, "JMP", "ADC", "ROR", NULL, + "BVS", "ADC", NULL, NULL, NULL, "ADC", "ROR", NULL, "SEI", "ADC", NULL, NULL, NULL, "ADC", "ROR", NULL, + NULL, "STA", NULL, NULL, "STY", "STA", "STX", NULL, "DEY", NULL, "TXA", NULL, "STY", "STA", "STX", NULL, + "BCC", "STA", NULL, NULL, "STY", "STA", "STX", NULL, "TYA", "STA", "TXS", NULL, NULL, "STA", NULL, NULL, + "LDY", "LDA", "LDX", NULL, "LDY", "LDA", "LDX", NULL, "TAY", "LDA", "TAX", NULL, "LDY", "LDA", "LDX", NULL, + "BCS", "LDA", NULL, NULL, "LDY", "LDA", "LDX", NULL, "CLV", "LDA", "TSX", NULL, "LDY", "LDA", "LDX", NULL, + "CPY", "CMP", NULL, NULL, "CPY", "CMP", "DEC", NULL, "INY", "CMP", "DEX", NULL, "CPY", "CMP", "DEC", NULL, + "BNE", "CMP", NULL, NULL, NULL, "CMP", "DEC", NULL, "CLD", "CMP", NULL, NULL, NULL, "CMP", "DEC", NULL, + "CPX", "SBC", NULL, NULL, "CPX", "SBC", "INC", NULL, "INX", "SBC", "NOP", NULL, "CPX", "SBC", "INC", NULL, + "BEQ", "SBC", NULL, NULL, NULL, "SBC", "INC", NULL, "SED", "SBC", NULL, NULL, NULL, "SBC", "INC", NULL +}; diff --git a/lib/op.h b/lib/op.h new file mode 100644 index 0000000..16b551c --- /dev/null +++ b/lib/op.h @@ -0,0 +1,19 @@ +#ifndef OP_H +# define OP_H 1 + +# include + +# define OP_MAX 256 + +# define OP_ADDR_IMPL 0 +# define OP_ADDR_REL 1 << 0 +# define OP_ADDR_IMM 1 << 1 +# define OP_ADDR_IND 1 << 2 +# define OP_ADDR_ABS 1 << 3 +# define OP_ADDR_X 1 << 4 +# define OP_ADDR_Y 1 << 5 + +extern const uint8_t opcode_addr[]; +extern const char *opcode_str[]; + +#endif /* !OP_H */ diff --git a/vm/Makefile.am b/vm/Makefile.am new file mode 100644 index 0000000..e69de29