commit
dcc4ae1ecd
@ -0,0 +1,14 @@
|
||||
code = """
|
||||
;comment parsing test
|
||||
IRX ;increment RAX
|
||||
IRY ;increment RAY
|
||||
|
||||
DBG ;RAX=1,RAY=1
|
||||
|
||||
LDX $00
|
||||
LDY #AF
|
||||
|
||||
STY $FFFF
|
||||
|
||||
DBG ;RAY=175,0xFFFF=175
|
||||
"""
|
@ -0,0 +1,87 @@
|
||||
#the closest thing to writing raw ASM
|
||||
import re
|
||||
|
||||
code = """LOL 01 010f
|
||||
LOL 01 0113
|
||||
LOL 01 0115
|
||||
LOL 01 0117
|
||||
LOL 00 0117
|
||||
JML 0000
|
||||
DBG"""
|
||||
|
||||
out = """#include <stdint.h>
|
||||
|
||||
int8_t PRG_BIN[] = {
|
||||
"""
|
||||
|
||||
def writeHex(str):
|
||||
global out
|
||||
out += f"{str}, "
|
||||
|
||||
count = 1
|
||||
for i in re.split("\n| ",code):
|
||||
match i:
|
||||
case "INC":
|
||||
writeHex("0x01")
|
||||
case "IRA":
|
||||
writeHex("0x02")
|
||||
case "IRX":
|
||||
writeHex("0x03")
|
||||
case "IRY":
|
||||
writeHex("0x04")
|
||||
case "DNC":
|
||||
writeHex("0x05")
|
||||
case "DCA":
|
||||
writeHex("0x06")
|
||||
case "DCX":
|
||||
writeHex("0x07")
|
||||
case "DCY":
|
||||
writeHex("0x07")
|
||||
case "JEA":
|
||||
writeHex("0x10")
|
||||
case "JER":
|
||||
writeHex("0x11")
|
||||
case "JML":
|
||||
writeHex("0x1A")
|
||||
case "JMA":
|
||||
writeHex("0x1B")
|
||||
case "LXA":
|
||||
writeHex("0x20")
|
||||
case "LXL":
|
||||
writeHex("0x21")
|
||||
case "LYA":
|
||||
writeHex("0x22")
|
||||
case "LYL":
|
||||
writeHex("0x23")
|
||||
case "LAA":
|
||||
writeHex("0x24")
|
||||
case "LAL":
|
||||
writeHex("0x25")
|
||||
case "LOA":
|
||||
writeHex("0x26")
|
||||
case "LOL":
|
||||
writeHex("0x27")
|
||||
case "STX":
|
||||
writeHex("0x2A")
|
||||
case "STY":
|
||||
writeHex("0x2B")
|
||||
case "STA":
|
||||
writeHex("0x2C")
|
||||
case "DBG":
|
||||
writeHex("0xFF")
|
||||
case other:
|
||||
if len(i) == 4: #assume memory address
|
||||
writeHex(f"0x{i[0]+i[1]}")
|
||||
writeHex(f"0x{i[2]+i[3]}")
|
||||
elif len(i) == 2:
|
||||
writeHex(f"0x{i}")
|
||||
else:
|
||||
writeHex("0x00")
|
||||
count+=1
|
||||
|
||||
out = out.rstrip(", ")
|
||||
out += f""", 0xFC
|
||||
}};
|
||||
int PRG_LEN = {count};
|
||||
"""
|
||||
print(out)
|
@ -0,0 +1,93 @@
|
||||
#reads TESM code, outputs rawASM
|
||||
code = """vput 1 0
|
||||
vput 1 4
|
||||
vput 1 6
|
||||
prnt
|
||||
jmp 0
|
||||
dump"""
|
||||
|
||||
OFFSET = 0x00FF #how far into memory should we store TESM memory banks
|
||||
|
||||
prc = 0
|
||||
hist = []
|
||||
|
||||
def intToHex(addr, video=False):
|
||||
addr = int(addr)
|
||||
if video:
|
||||
if addr > 7:
|
||||
return OFFSET+16+7 #clamp value
|
||||
return OFFSET+16+addr
|
||||
else:
|
||||
if addr > 15:
|
||||
return OFFSET+15 #clamp value
|
||||
return OFFSET+addr
|
||||
|
||||
def hexstr(integer, len=2, inc=True):
|
||||
global prc
|
||||
if inc:
|
||||
prc+=int(len/2)
|
||||
return "{0:0{1}x}".format(integer, len)
|
||||
|
||||
for line in code.split("\n"):
|
||||
inst = line.split(" ")
|
||||
match inst[0]:
|
||||
case "put":
|
||||
hist.append(prc)
|
||||
print(f"LOL {hexstr(int(inst[1]))} {hexstr(intToHex(inst[2]), 4)}")
|
||||
prc+=1
|
||||
case "vput":
|
||||
hist.append(prc)
|
||||
print(f"LOL {hexstr(int(inst[1]))} {hexstr(intToHex(inst[2], True), 4)}")
|
||||
prc+=1
|
||||
case "equl":
|
||||
hist.append(prc)
|
||||
arg1 = hexstr(intToHex(inst[1]), 4)
|
||||
arg2 = hexstr(intToHex(inst[2]), 4)
|
||||
arg3 = hexstr(intToHex(inst[3]), 4)
|
||||
print(f"""JEA {arg1} {arg2} {hexstr(prc+5,4,False)}
|
||||
JML {hexstr(prc+9,4,False)}
|
||||
LOL {hexstr(1,2,False)} {arg3}""")
|
||||
prc+=8
|
||||
case "vequl":
|
||||
hist.append(prc)
|
||||
arg1 = hexstr(intToHex(inst[1], True), 4)
|
||||
arg2 = hexstr(intToHex(inst[2], True), 4)
|
||||
arg3 = hexstr(intToHex(inst[3], True), 4)
|
||||
print(f"""JEA {arg1} {arg2} {hexstr(prc+5,4,False)}
|
||||
JML {hexstr(prc+9,4,False)}
|
||||
LOL {hexstr(1,2,False)} {arg3}""")
|
||||
prc+=8
|
||||
case "cpy":
|
||||
hist.append(prc)
|
||||
arg1 = hexstr(intToHex(inst[1]), 4)
|
||||
arg2 = hexstr(intToHex(inst[2], True), 4)
|
||||
print(f"""LOA {arg1} {arg2}""")
|
||||
prc+=5
|
||||
case "mov":
|
||||
hist.append(prc)
|
||||
arg1 = hexstr(intToHex(inst[1]), 4)
|
||||
arg2 = hexstr(intToHex(inst[2], True), 4)
|
||||
print(f"""LOA {arg1} {arg2}
|
||||
LOL {hexstr(0,2,False)} {arg1}""")
|
||||
prc+=9
|
||||
case "prnt":
|
||||
hist.append(prc)
|
||||
print(f"""LOL 01 0117
|
||||
LOL 00 0117""")
|
||||
prc+=7
|
||||
case "jmp":
|
||||
hist.append(prc)
|
||||
print(f"""JML {hexstr(hist[int(inst[1])],4,False)}""")
|
||||
prc+=3
|
||||
case "dump":
|
||||
hist.append(prc)
|
||||
print("DBG")
|
||||
prc+=1
|
||||
case "vdump":
|
||||
hist.append(prc)
|
||||
print("DBG")
|
||||
prc+=1
|
||||
case other:
|
||||
hist.append(prc)
|
||||
print("NOP")
|
||||
prc+=1
|
@ -0,0 +1 @@
|
||||
bin/
|
@ -0,0 +1,3 @@
|
||||
Permission to use, copy, modify, and/or distribute this software for any purpose with or without fee is hereby granted.
|
||||
|
||||
THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
|
@ -0,0 +1,28 @@
|
||||
CC ?= gcc
|
||||
target ?= $(shell ${CC} -dumpmachine)
|
||||
CC_FLAGS ?=
|
||||
CC_FLAGS := ${CC_FLAGS} -Ilib
|
||||
DESTDIR ?= /
|
||||
|
||||
.PHONY: all debug clean build-release install
|
||||
all:
|
||||
@$(shell mkdir -p bin)
|
||||
all: main
|
||||
|
||||
main:
|
||||
@${CC} -o bin/main src/main.c ${CC_FLAGS}
|
||||
|
||||
debug: CC_FLAGS:=-g -O0 -v -fsanitize=undefined -fsanitize=address ${CC_FLAGS}
|
||||
debug: all
|
||||
|
||||
clean:
|
||||
@rm -rf bin
|
||||
|
||||
release: CC_FLAGS:=-O3 ${CC_FLAGS}
|
||||
release: all
|
||||
release:
|
||||
@strip bin/*
|
||||
tar -czf release.tar.gz bin/*
|
||||
|
||||
install:
|
||||
@install -m 777 bin/main ${DESTDIR}/usr/local/bin
|
@ -0,0 +1,2 @@
|
||||
-Ilib
|
||||
-DDRAKECU_VERSION="placeholder"
|
Binary file not shown.
@ -0,0 +1,42 @@
|
||||
;THIS SUBROUTINE ARRANGES THE 8-BIT ELEMENTS OF A LIST IN ASCENDING
|
||||
;ORDER. THE STARTING ADDRESS OF THE LIST IS IN LOCATIONS $30 AND
|
||||
;$31. THE LENGTH OF THE LIST IS IN THE FIRST BYTE OF THE LIST. LOCATION
|
||||
;$32 IS USED TO HOLD AN EXCHANGE FLAG.
|
||||
lda #$05
|
||||
sta $30
|
||||
sta $33
|
||||
lda #$A4
|
||||
sta $34
|
||||
lda #$07
|
||||
sta $35
|
||||
lda #$F6
|
||||
sta $36
|
||||
lda #$44
|
||||
lda $37
|
||||
|
||||
SORT8 ldy #$00 ;TURN EXCHANGE FLAG OFF (= 0)
|
||||
sty $32
|
||||
lda ($30),Y ;FETCH ELEMENT COUNT
|
||||
tax ; AND PUT IT INTO X
|
||||
iny ;POINT TO FIRST ELEMENT IN LIST
|
||||
dex ;DECREMENT ELEMENT COUNT
|
||||
NXTEL lda ($30),Y ;FETCH ELEMENT
|
||||
iny
|
||||
cmp ($30),Y ;IS IT LARGER THAN THE NEXT ELEMENT?
|
||||
bcc CHKEND
|
||||
beq CHKEND
|
||||
;YES. EXCHANGE ELEMENTS IN MEMORY
|
||||
pha ; BY SAVING LOW BYTE ON STACK.
|
||||
lda ($30),Y ; THEN GET HIGH BYTE AND
|
||||
dey ; STORE IT AT LOW ADDRESS
|
||||
sta ($30),Y
|
||||
pla ;PULL LOW BYTE FROM STACK
|
||||
iny ; AND STORE IT AT HIGH ADDRESS
|
||||
sta ($30),Y
|
||||
lda #$FF ;TURN EXCHANGE FLAG ON (= -1)
|
||||
sta $32
|
||||
CHKEND dex ;END OF LIST?
|
||||
bne NXTEL ;NO. FETCH NEXT ELEMENT
|
||||
bit $32 ;YES. EXCHANGE FLAG STILL OFF?
|
||||
bmi SORT8 ;NO. GO THROUGH LIST AGAIN
|
||||
rts ;YES. LIST IS NOW ORDERED
|
@ -0,0 +1,4 @@
|
||||
inc $00E7
|
||||
inc $0001
|
||||
inx
|
||||
iny
|
@ -0,0 +1,8 @@
|
||||
#!/bin/sh
|
||||
|
||||
mkdir -p bin
|
||||
|
||||
for i in *.asm
|
||||
do
|
||||
xa -v -o bin/`echo $i | sed "s/.asm/.bin/g"` -l bin/`echo $i | sed "s/.asm/.lst/g"` $i
|
||||
done
|
@ -0,0 +1,27 @@
|
||||
#pragma once
|
||||
#include <stdint.h>
|
||||
#include <stdbool.h>
|
||||
|
||||
uint8_t memory[0xFFFF + 1]; //16kib memory (probably)
|
||||
//0x0000 - 0x00FF is Zero Paged
|
||||
//0x0100 - 0x01FF is system stack
|
||||
|
||||
uint16_t prc = 0; //16bit program counter
|
||||
|
||||
uint8_t spt = 0; //8bit stack pointer
|
||||
|
||||
uint8_t acc = 0; //8bit accumulator
|
||||
uint8_t irx,iry = 0; //2 8bit index registers
|
||||
|
||||
struct status {
|
||||
bool carry; //carry flag
|
||||
bool zero; //zero flag
|
||||
bool ird; //interrupt disable flag
|
||||
bool dec; //decimal mode flag for arithmetic
|
||||
bool brk; //break bit
|
||||
bool overflow; //overflow flag
|
||||
bool neg; //negative flag
|
||||
};
|
||||
|
||||
|
||||
struct status cpuStatus;
|
@ -0,0 +1,6 @@
|
||||
#include <stdint.h>
|
||||
|
||||
int8_t PRG_BIN[] = {
|
||||
0x27, 0x01, 0x01, 0x0f, 0x27, 0x01, 0x01, 0x13, 0x27, 0x01, 0x01, 0x15, 0x27, 0x01, 0x01, 0x17, 0x27, 0x00, 0x01, 0x17, 0x1A, 0x00, 0x00, 0xFF, 0xFC
|
||||
};
|
||||
int PRG_LEN = 19;
|
@ -0,0 +1,147 @@
|
||||
#include "constants.h"
|
||||
|
||||
#include <stdint.h>
|
||||
#include <stdio.h>
|
||||
#include <unistd.h>
|
||||
|
||||
void memview() {
|
||||
for (int i = 0x00; i <= 0xFFFF; i++) {
|
||||
if (memory[i] != 0x00) {
|
||||
printf("Mem Address 0x%04X: 0x%04X\n", i, memory[i]);
|
||||
}
|
||||
}
|
||||
printf("rax - %d\n", irx);
|
||||
printf("ray - %d\n", iry);
|
||||
printf("acc - %d\n", acc);
|
||||
printf("prc - %d\n", prc);
|
||||
}
|
||||
|
||||
int emulate(uint8_t exec[], int size, uint8_t addr) {
|
||||
//uint8_t* program = (uint8_t*)exec;
|
||||
/*for (int i = addr, i2=0; i < size+addr; i++) {
|
||||
memory[i] = exec[i2];
|
||||
i2++;
|
||||
}*/ //not needed: LRIS has separate prgrom
|
||||
|
||||
while (prc < UINT16_MAX) { //FIXME: this can cause a vuln where you can at least read OOB memory (jumping past the 0xFC)
|
||||
uint8_t inst = exec[prc];
|
||||
switch (inst) {
|
||||
case 0x00: //NOP
|
||||
break;
|
||||
case 0x03: //INC RX
|
||||
irx++;
|
||||
break;
|
||||
case 0x04: //INC RY
|
||||
iry++;
|
||||
break;
|
||||
case 0x10: { //A/L JIE
|
||||
uint8_t upper = exec[++prc];
|
||||
uint8_t lower = exec[++prc];
|
||||
uint16_t addr1 = 256U*upper+lower;
|
||||
upper = exec[++prc];
|
||||
lower = exec[++prc];
|
||||
uint16_t addr2 = 256U*upper+lower;
|
||||
upper = exec[++prc];
|
||||
lower = exec[++prc];
|
||||
uint16_t newPRC = 256U*upper+lower;
|
||||
if (memory[addr1] == memory[addr2]) {
|
||||
prc = newPRC-1; //we need to account for the prc++ at the end of the loop
|
||||
} else { /* DO NOTHING */ }
|
||||
break;
|
||||
}
|
||||
case 0x1A: { //LITERAL JMP
|
||||
uint8_t upper = exec[++prc];
|
||||
uint8_t lower = exec[++prc];
|
||||
uint16_t addr = 256U*upper+lower;
|
||||
prc = memory[addr]-1;
|
||||
break;
|
||||
}
|
||||
case 0x20: { //ABSOLUTE LDX
|
||||
uint8_t upper = exec[++prc];
|
||||
uint8_t lower = exec[++prc];
|
||||
uint16_t addr = 256U*upper+lower;
|
||||
irx = memory[addr];
|
||||
break;
|
||||
}
|
||||
case 0x23: { //LITERAL LDY
|
||||
uint8_t val = exec[++prc];
|
||||
iry = val;
|
||||
break;
|
||||
}
|
||||
case 0x26: { //ABSOLUTE LOD
|
||||
uint8_t upper = exec[++prc];
|
||||
uint8_t lower = exec[++prc];
|
||||
uint16_t addr1 = 256U*upper+lower;
|
||||
upper = exec[++prc];
|
||||
lower = exec[++prc];
|
||||
uint16_t addr2 = 256U*upper+lower;
|
||||
memory[addr2] = memory[addr1];
|
||||
break;
|
||||
}
|
||||
case 0x27: { //LITERAL LOD
|
||||
uint8_t val = exec[++prc];
|
||||
uint8_t upper = exec[++prc];
|
||||
uint8_t lower = exec[++prc];
|
||||
uint16_t addr = 256U*upper+lower;
|
||||
memory[addr] = val;
|
||||
break;
|
||||
}
|
||||
case 0x2B: { //STY
|
||||
uint8_t upper = exec[++prc];
|
||||
uint8_t lower = exec[++prc];
|
||||
uint16_t addr = 256U*upper+lower;
|
||||
memory[addr] = iry;
|
||||
break;
|
||||
}
|
||||
case 0x50:
|
||||
acc = ~(irx & iry);
|
||||
case 0xFC:
|
||||
_exit(0);
|
||||
case 0xFF:
|
||||
memview();
|
||||
break;
|
||||
default:
|
||||
printf("Opcode 0x%02X\n not implemented!\n", inst);
|
||||
memview();
|
||||
_exit(0);
|
||||
}
|
||||
//printf("Ran inst 0x%02X\n", inst);
|
||||
//memview();
|
||||
prc++;
|
||||
|
||||
if (memory[0x010F+8]) {
|
||||
int charcode = 0;
|
||||
if (memory[0x010F]) {
|
||||
charcode += 64;
|
||||
//printf("%d\n", charcode);
|
||||
}
|
||||
if (memory[0x0110]) {
|
||||
charcode += 32;
|
||||
//printf("%d\n", charcode);
|
||||
}
|
||||
if (memory[0x0111]) {
|
||||
charcode += 16;
|
||||
//printf("%d\n", charcode);
|
||||
}
|
||||
if (memory[0x0112]) {
|
||||
charcode += 8;
|
||||
//printf("%d\n", charcode);
|
||||
}
|
||||
if (memory[0x0113]) {
|
||||
charcode += 4;
|
||||
//printf("%d\n", charcode);
|
||||
}
|
||||
if (memory[0x0114]) {
|
||||
charcode += 2;
|
||||
//printf("%d\n", charcode);
|
||||
}
|
||||
if (memory[0x0115]) {
|
||||
charcode += 1;
|
||||
//printf("%d\n", charcode);
|
||||
}
|
||||
printf("%c%c", charcode, memory[0x0116] ? '\n' : 0x0);
|
||||
}
|
||||
}
|
||||
printf("out of length");
|
||||
return 0;
|
||||
}
|
@ -0,0 +1,85 @@
|
||||
#include "constants.h"
|
||||
#include "file.h"
|
||||
|
||||
#define _GNU_SOURCE
|
||||
#include <stdint.h>
|
||||
#include <stdio.h>
|
||||
#include <getopt.h>
|
||||
#include <unistd.h>
|
||||
#include <string.h>
|
||||
#include <errno.h>
|
||||
#include <sys/stat.h>
|
||||
#include <stdlib.h>
|
||||
|
||||
#include "emu.c"
|
||||
|
||||
uint16_t* fileRead(char* name) {
|
||||
FILE* fp = fopen(name, "rb");
|
||||
if (!(access(name, F_OK) == 0)) {
|
||||
errno = -1;
|
||||
printf("Hi?\n");
|
||||
return 0;
|
||||
}
|
||||
|
||||
struct stat st;
|
||||
stat(name, &st);
|
||||
int length = st.st_size;
|
||||
|
||||
uint16_t rbuf[length+1];
|
||||
|
||||
for (int i = 0; i < length; i++) {
|
||||
fread(&rbuf[i], 2, 1, fp);
|
||||
}
|
||||
fclose(fp);
|
||||
|
||||
uint16_t* tmp = rbuf;
|
||||
return tmp;
|
||||
}
|
||||
|
||||
//blanks out memory and initializes various things
|
||||
int init() {
|
||||
for (int i = 0; i <= 0xFFFF; i++) { //blank memory
|
||||
memory[i] = 0x00;
|
||||
}
|
||||
|
||||
cpuStatus.brk = 0;
|
||||
cpuStatus.carry = 0;
|
||||
cpuStatus.dec = 0;
|
||||
cpuStatus.ird = 0;
|
||||
cpuStatus.neg = 0;
|
||||
cpuStatus.overflow = 0;
|
||||
cpuStatus.zero = 0;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
void help(char* exe) {
|
||||
printf("%s - a 6502 emulator.\n"
|
||||
" Usage: %s [prg]", exe, exe);
|
||||
}
|
||||
|
||||
int main(int argc, char* argv[]) {
|
||||
char* filename = *++argv; //TODO: jankiest thing ever
|
||||
|
||||
/*uint16_t* binary = (uint16_t*)fileRead(filename);
|
||||
|
||||
//uint16_t binary[] = {0xe7e6, 0xeaea, 0x01e6, 0xe8ea, 0xc8ea, 0x00ea};
|
||||
int size = sizeof(binary)/sizeof(binary[0])+1;
|
||||
uint8_t exec[size*2];
|
||||
for (int i,i2 = 0; i < size-1; i++) {
|
||||
printf("%04X\n", binary[i]);
|
||||
uint8_t lsb = (binary[i] & 0xFF);
|
||||
uint8_t hsb = (binary[i] & 0xFF00) >> 8;
|
||||
exec[i2] = lsb;
|
||||
exec[++i2] = hsb;
|
||||
i2++;
|
||||
}*/
|
||||
uint8_t* exec = (uint8_t*)PRG_BIN;
|
||||
int size = PRG_LEN;
|
||||
printf("Program ROM:\n");
|
||||
for (int i = 0; i < size; i++) {
|
||||
printf("0x%02X\n", exec[i]);
|
||||
}
|
||||
emulate(exec, size, 0x0400); //hacky lol
|
||||
return 0;
|
||||
}
|
@ -0,0 +1,158 @@
|
||||
## LRIS CPU/ASM specification (wip)
|
||||
~~shamelessly ripped off~~ very inspired by 6502 because it's the only thing i kinda know
|
||||
|
||||
### Registers
|
||||
| Register | Purpose | Size |
|
||||
| --- | --- | --- |
|
||||
| ACC | Stores the result of any calculation opcodes (if in ACC mode) | 1 byte |
|
||||
| RAX | General purpose register | 1 byte |
|
||||
| RAY | General purpose register | 1 byte |
|
||||
|
||||
### Memory
|
||||
- Up to 64kib of RAM
|
||||
- Up to 64kib of Program ROM
|
||||
|
||||
### Addressing Modes
|
||||
#### Absolute
|
||||
Directly reads from a 2 byte memory address with instruction.
|
||||
```
|
||||
LDX $0A2F
|
||||
```
|
||||
<sub><sup>Note: 1 byte addresses should be padded by the assembler.</sup></sub>
|
||||
|
||||
#### Literal
|
||||
Uses a literal byte, in place of reading from a memory address.
|
||||
```
|
||||
LDX #0A2F
|
||||
```
|
||||
<sub><sup>Note: 1 byte addresses should be padded by the assembler.</sup></sub>
|
||||
|
||||
### Opcodes
|
||||
NOTE: these do not specify a higher level assembly langauge, only the opcodes interpreted by the CPU itself (ie there cannot be 3 increments for the different registers that all use `INC`)
|
||||
|
||||
#### NOP- No Operation
|
||||
seriously?
|
||||
| Addressing | Action | Opcode | Size |
|
||||
| --- | --- | --- | --- |
|
||||
| N/A | NOP | `$00` | 1 byte |
|
||||
|
||||
#### INC - Increment
|
||||
what do you think it does
|
||||
| Addressing | Action | Opcode | Size |
|
||||
| --- | --- | --- | --- |
|
||||
| Absolute | Increments the value at specified memory address | `$01` | 3 bytes |
|
||||
| Accumulator | Increments the accumulator | `$02` | 1 byte |
|
||||
| RX | Increments the RAX register | `$03` | 1 byte |
|
||||
| RY | Increments the RAY register | `$04` | 1 byte |
|
||||
|
||||
#### DNC - Decrement
|
||||
what do you think it does (pt. 2)
|
||||
| Addressing | Action | Opcode | Size |
|
||||
| --- | --- | --- | --- |
|
||||
| Absolute | Decrements the value at specified memory address | `$05` | 3 bytes |
|
||||
| Accumulator | Decrements the accumulator | `$06` | 1 byte |
|
||||
| RX | Decrements the RAX register | `$07` | 1 byte |
|
||||
| RY | Decrements the RAY register | `$08` | 1 byte |
|
||||
|
||||
#### JIE - Jump If Equal
|
||||
jumps if something is equal to other something
|
||||
| Addressing | Action | Opcode | Size |
|
||||
| --- | --- | --- | --- |
|
||||
| Absolute/Literal | Sets PRC to value if memory address is equal to other memory address | `$10` | 7 bytes |
|
||||
| Register/Literal | Sets PRC to value if RAX and RAY are equal | `$11` | 1 byte |
|
||||
|
||||
#### JMP - Jump
|
||||
jumps unconditionally
|
||||
| Addressing | Action | Opcode | Size |
|
||||
| --- | --- | --- | --- |
|
||||
| Literal | Sets PRC to a literal value | `$1A` | 3 bytes
|
||||
| Absolute | Sets PRC to the value of a byte in memory | `$1B` | 3 bytes
|
||||
|
||||
##### Example:
|
||||
```
|
||||
;OP PRC ADDR ADDR
|
||||
JIE 0x00A2 0x0013 0x0014
|
||||
```
|
||||
|
||||
#### LDX - Load [RA]X
|
||||
loads a value into RAX
|
||||
| Addressing | Action | Opcode | Size |
|
||||
| --- | --- | --- | --- |
|
||||
| Absolute | Loads the value of another byte of memory into RAX | `$20` | 3 bytes |
|
||||
| Literal | Loads a literal byte into RAX | `$21` | 2 bytes |
|
||||
|
||||
#### LDY - Load [RA]Y
|
||||
loads a value into RAY
|
||||
| Addressing | Action | Opcode | Size |
|
||||
| --- | --- | --- | --- |
|
||||
| Absolute | Loads the value of another byte of memory into RAY | `$22` | 3 bytes |
|
||||
| Literal | Loads a literal byte into RAY | `$23` | 2 bytes |
|
||||
|
||||
#### LDA - Load A(ccumulator)
|
||||
loads a value into the accumulator
|
||||
| Addressing | Action | Opcode | Size |
|
||||
| --- | --- | --- | --- |
|
||||
| Absolute | Loads the value of another byte of memory into ACC | `$24` | 3 bytes |
|
||||
| Literal | Loads a literal byte into ACC | `$25` | 2 bytes |
|
||||
|
||||
#### LOD - Load Address
|
||||
loads a value into an address
|
||||
| Addressing | Action | Opcode | Size |
|
||||
| --- | --- | --- | --- |
|
||||
| Absolute | Loads the value of another byte of memory into the memory address | `$26` | 5 bytes |
|
||||
| Literal | Loads a literal byte into the memory address | `$27` | 4 bytes |
|
||||
|
||||
#### STX - Store [RA]X
|
||||
stores RAX into a memory address
|
||||
| Addressing | Action | Opcode | Size |
|
||||
| --- | --- | --- | --- |
|
||||
| Absolute | Loads the value of RAX into a byte of memory | `$2A` | 3 bytes |
|
||||
|
||||
#### STY - Store [RA]Y
|
||||
stores RAY into a memory address
|
||||
| Addressing | Action | Opcode | Size |
|
||||
| --- | --- | --- | --- |
|
||||
| Absolute | Loads the value of RAY into a byte of memory | `$2B` | 3 bytes |
|
||||
|
||||
#### STA - Store A(ccumulator)
|
||||
stores the accumulator into a memory address
|
||||
| Addressing | Action | Opcode | Size |
|
||||
| --- | --- | --- | --- |
|
||||
| Absolute | Loads the value of ACC into a byte of memory | `$2C` | 3 bytes |
|
||||
|
||||
#### ADD - Adds Two Values
|
||||
adds two values of various source into a register or memory address
|
||||
| Addressing | Action | Opcode | Size |
|
||||
| --- | --- | --- | --- |
|
||||
| RAX | Adds RAX to the value in ACC, and stores it into ACC | `$40` | 1 byte |
|
||||
| RAY | Adds RAY to the value in ACC, and stores it into ACC | `$41` | 1 byte |
|
||||
| Absolute/Absolute | Adds the values of two memory addresses, and stores it into ACC | `$42` | 5 bytes |
|
||||
| Absolute/ACC | Adds the value of a memory address into the value in ACC, and stores it into ACC | `$43` | 3 bytes |
|
||||
|
||||
#### SUB - Subtracts Two Values
|
||||
subtracts two values of various source into a register or memory address
|
||||
| Addressing | Action | Opcode | Size |
|
||||
| --- | --- | --- | --- |
|
||||
| RAX | Subtracts RAX from the value in ACC, and stores it into ACC | `$45` | 1 byte |
|
||||
| RAY | Subtracts RAY from the value in ACC, and stores it into ACC | `$46` | 1 byte |
|
||||
| Absolute/Absolute | Subtracts the first address' value by the second address' value, and stores it into ACC | `$47` | 5 bytes |
|
||||
| Absolute/ACC | Subtracts the value of a memory address from the value in ACC, and stores it into ACC | `$48` | 3 bytes |
|
||||
|
||||
#### NAD - NAND
|
||||
if you don't know what a NAND is why are you looking at opcode documentation
|
||||
| Addressing | Action | Opcode | Size |
|
||||
| --- | --- | --- | --- |
|
||||
| Register | Performs a bitwise NAND on RAX and RAY and stores it into ACC | `$50` | 1 byte |
|
||||
|
||||
#### HLT - Halt Operation
|
||||
entirely stops execution and attempts to shutdown on hardware
|
||||
| Addressing | Action | Opcode | Size |
|
||||
| --- | --- | --- | --- |
|
||||
| N/A | | `$FC` | |
|
||||
|
||||
#### DBG - Debug
|
||||
(in emulators) print a view of memory
|
||||
(in hardware or an optimizing assembler) NOP
|
||||
| Addressing | Action | Opcode | Size |
|
||||
| --- | --- | --- | --- |
|
||||
| N/A | | `$FF` | |
|
Reference in new issue