initial commit

master
Drake 2 years ago
commit b66ddfb4a8

1
.gitignore vendored

@ -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,11 @@
#include <stdint.h>
int8_t bin[] = {
0xa9, 0x05, 0x85, 0x30, 0x85, 0x33, 0xa9, 0xa4, 0x85, 0x34, 0xa9, 0x07,
0x85, 0x35, 0xa9, 0xf6, 0x85, 0x36, 0xa9, 0x44, 0xa5, 0x37, 0xa0, 0x00,
0x84, 0x32, 0xb1, 0x30, 0xaa, 0xc8, 0xca, 0xb1, 0x30, 0xc8, 0xd1, 0x30,
0x90, 0x10, 0xf0, 0x0e, 0x48, 0xb1, 0x30, 0x88, 0x91, 0x30, 0x68, 0xc8,
0x91, 0x30, 0xa9, 0xff, 0x85, 0x32, 0xca, 0xd0, 0xe6, 0x24, 0x32, 0x30,
0xd9, 0x60
};
unsigned int __6502_functional_test_bin_len = 62;

@ -0,0 +1,183 @@
#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("irx - %d\n", irx);
printf("iry - %d\n", iry);
printf("acc - %d\n", acc);
}
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++;
}
while (prc < size) {
uint8_t inst = memory[addr+prc];
switch (inst) {
//BRK
case 0x00:
cpuStatus.brk = 0x01;
prc++;
prc++;
break;
//NOP
case 0xEA:
prc++;
break;
case 0x80:
prc++;
break;
//variations on an INC
case 0xE6:
memory[memory[++prc+addr]]++;
prc++;
break;
case 0xE8:
irx++;
prc++;
break;
case 0xC8:
iry++;
prc++;
break;
//LDA
case 0xA9: {
uint8_t mem = memory[memory[++prc+addr]];
acc = mem;
prc++;
break;
}
case 0xA5: {
uint8_t mem = memory[memory[++prc+addr]];
acc = mem;
prc++;
break;
}
case 0xB1: {
uint8_t mem = memory[(++prc)+addr];
mem+=iry;
acc = memory[mem];
prc++;
break;
}
//STA
case 0x85: {
memory[memory[++prc+addr]] = acc;
prc++;
break;
}
//STY
case 0x84: {
memory[memory[++prc+addr]] = iry;
prc++;
break;
}
//variations on an LDY (it doesn't work as well the second time)
case 0xA0: {
uint8_t mem = memory[memory[++prc+addr]];
iry = mem;
prc++;
break;
}
//ORA
case 0x01: {
uint8_t mem = memory[(++prc)+addr];
mem+=irx;
uint8_t val = memory[mem];
acc = acc | val;
prc++;
break;
}
//TAX
case 0xAA: {
irx = acc;
if (irx == 0) {
cpuStatus.zero = 1;
} else {
cpuStatus.zero = 0;
}
prc++;
break;
}
//DEX
case 0xCA: {
irx--;
if (irx == 0) {
cpuStatus.zero = 1;
} else {
cpuStatus.zero = 0;
}
prc++;
break;
}
case 0xD1: {
uint8_t mem = memory[(++prc)+addr];
mem+=iry;
mem = memory[mem];
if (acc >= mem) {
cpuStatus.carry = 1;
} else {
cpuStatus.carry = 0;
}
if (acc == mem) {
cpuStatus.zero = 1;
} else {
cpuStatus.zero = 0;
}
prc++;
break;
}
case 0x90: {
uint8_t mem = memory[memory[++prc+addr]];
if (cpuStatus.carry == 0x00) {
prc += mem;
}
break;
}
case 0x10: {
uint8_t mem = memory[memory[++prc+addr]];
if (cpuStatus.neg == 0x00) {
prc += mem;
}
break;
}
case 0xF0: {
uint8_t mem = memory[memory[++prc+addr]];
if (cpuStatus.zero == 0x00) {
prc += mem;
}
break;
}
default:
printf("Opcode 0x%02X\n not implemented!\n", inst);
_exit(0);
}
printf("Ran inst 0x%02X\n", inst);
memview();
}
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*)bin;
int size = __6502_functional_test_bin_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;
}
Loading…
Cancel
Save