mirror of
https://github.com/DavidBuchanan314/6502-emu.git
synced 2025-04-12 06:39:02 +00:00
Made variable names slightly more consistent
This commit is contained in:
parent
12f80f409c
commit
1da995b11a
14
6502-emu.c
14
6502-emu.c
@ -6,7 +6,7 @@
|
||||
#include "6502.h"
|
||||
#include "6850.h"
|
||||
|
||||
struct termios oldTermios;
|
||||
struct termios initial_termios;
|
||||
|
||||
void step_delay()
|
||||
{
|
||||
@ -32,17 +32,17 @@ void run_cpu()
|
||||
|
||||
void restore_stdin()
|
||||
{
|
||||
tcsetattr(0, TCSANOW, &oldTermios);
|
||||
tcsetattr(0, TCSANOW, &initial_termios);
|
||||
}
|
||||
|
||||
void raw_stdin()
|
||||
{
|
||||
struct termios newTermios;
|
||||
struct termios new_termios;
|
||||
|
||||
tcgetattr(0, &oldTermios);
|
||||
newTermios = oldTermios;
|
||||
cfmakeraw(&newTermios);
|
||||
tcsetattr(0, TCSANOW, &newTermios);
|
||||
tcgetattr(0, &initial_termios);
|
||||
new_termios = initial_termios;
|
||||
cfmakeraw(&new_termios);
|
||||
tcsetattr(0, TCSANOW, &new_termios);
|
||||
atexit(restore_stdin);
|
||||
}
|
||||
|
||||
|
120
6502.c
120
6502.c
@ -14,12 +14,12 @@ int jumping; // used to check that we don't need to increment the PC after a jum
|
||||
|
||||
/* Flag Checks */
|
||||
|
||||
static inline void Nflag(int8_t val)
|
||||
static inline void N_flag(int8_t val)
|
||||
{
|
||||
SR.bits.sign = val < 0;
|
||||
}
|
||||
|
||||
static inline void Zflag(uint8_t val)
|
||||
static inline void Z_flag(uint8_t val)
|
||||
{
|
||||
SR.bits.zero = val == 0;
|
||||
}
|
||||
@ -40,12 +40,12 @@ static inline uint8_t stack_pull()
|
||||
|
||||
static inline uint8_t * read_ptr()
|
||||
{
|
||||
return readAddr = get_ptr[inst.mode]();
|
||||
return read_addr = get_ptr[inst.mode]();
|
||||
}
|
||||
|
||||
static inline uint8_t * write_ptr()
|
||||
{
|
||||
return writeAddr = get_ptr[inst.mode]();
|
||||
return write_addr = get_ptr[inst.mode]();
|
||||
}
|
||||
|
||||
/* Instruction Implementations */
|
||||
@ -57,15 +57,15 @@ static void inst_ADC()
|
||||
SR.bits.carry = tmp > 0xFF;
|
||||
SR.bits.overflow = ((A^tmp)&(operand^tmp)&0x80) != 0;
|
||||
A = tmp & 0xFF;
|
||||
Nflag(A);
|
||||
Zflag(A);
|
||||
N_flag(A);
|
||||
Z_flag(A);
|
||||
}
|
||||
|
||||
static void inst_AND()
|
||||
{
|
||||
A &= * read_ptr();
|
||||
Nflag(A);
|
||||
Zflag(A);
|
||||
N_flag(A);
|
||||
Z_flag(A);
|
||||
}
|
||||
|
||||
static void inst_ASL()
|
||||
@ -73,8 +73,8 @@ static void inst_ASL()
|
||||
uint8_t tmp = * read_ptr();
|
||||
SR.bits.carry = (tmp & 0x80) != 0;
|
||||
tmp <<= 1;
|
||||
Nflag(tmp);
|
||||
Zflag(tmp);
|
||||
N_flag(tmp);
|
||||
Z_flag(tmp);
|
||||
* write_ptr() = tmp;
|
||||
}
|
||||
|
||||
@ -102,8 +102,8 @@ static void inst_BEQ()
|
||||
static void inst_BIT()
|
||||
{
|
||||
uint8_t tmp = * read_ptr();
|
||||
Nflag(tmp);
|
||||
Zflag(tmp & A);
|
||||
N_flag(tmp);
|
||||
Z_flag(tmp & A);
|
||||
SR.bits.overflow = (tmp & 0x40) != 0;
|
||||
}
|
||||
|
||||
@ -180,8 +180,8 @@ static void inst_CMP()
|
||||
{
|
||||
uint8_t operand = * read_ptr();
|
||||
uint8_t tmpDiff = A - operand;
|
||||
Nflag(tmpDiff);
|
||||
Zflag(tmpDiff);
|
||||
N_flag(tmpDiff);
|
||||
Z_flag(tmpDiff);
|
||||
SR.bits.carry = A >= operand;
|
||||
}
|
||||
|
||||
@ -189,8 +189,8 @@ static void inst_CPX()
|
||||
{
|
||||
uint8_t operand = * read_ptr();
|
||||
uint8_t tmpDiff = X - operand;
|
||||
Nflag(tmpDiff);
|
||||
Zflag(tmpDiff);
|
||||
N_flag(tmpDiff);
|
||||
Z_flag(tmpDiff);
|
||||
SR.bits.carry = X >= operand;
|
||||
}
|
||||
|
||||
@ -198,8 +198,8 @@ static void inst_CPY()
|
||||
{
|
||||
uint8_t operand = * read_ptr();
|
||||
uint8_t tmpDiff = Y - operand;
|
||||
Nflag(tmpDiff);
|
||||
Zflag(tmpDiff);
|
||||
N_flag(tmpDiff);
|
||||
Z_flag(tmpDiff);
|
||||
SR.bits.carry = Y >= operand;
|
||||
}
|
||||
|
||||
@ -207,53 +207,53 @@ static void inst_DEC()
|
||||
{
|
||||
uint8_t tmp = * read_ptr();
|
||||
tmp--;
|
||||
Nflag(tmp);
|
||||
Zflag(tmp);
|
||||
N_flag(tmp);
|
||||
Z_flag(tmp);
|
||||
* write_ptr() = tmp;
|
||||
}
|
||||
|
||||
static void inst_DEX()
|
||||
{
|
||||
X--;
|
||||
Nflag(X);
|
||||
Zflag(X);
|
||||
N_flag(X);
|
||||
Z_flag(X);
|
||||
}
|
||||
|
||||
static void inst_DEY()
|
||||
{
|
||||
Y--;
|
||||
Nflag(Y);
|
||||
Zflag(Y);
|
||||
N_flag(Y);
|
||||
Z_flag(Y);
|
||||
}
|
||||
|
||||
static void inst_EOR()
|
||||
{
|
||||
A ^= * read_ptr();
|
||||
Nflag(A);
|
||||
Zflag(A);
|
||||
N_flag(A);
|
||||
Z_flag(A);
|
||||
}
|
||||
|
||||
static void inst_INC()
|
||||
{
|
||||
uint8_t tmp = * read_ptr();
|
||||
tmp++;
|
||||
Nflag(tmp);
|
||||
Zflag(tmp);
|
||||
N_flag(tmp);
|
||||
Z_flag(tmp);
|
||||
* write_ptr() = tmp;
|
||||
}
|
||||
|
||||
static void inst_INX()
|
||||
{
|
||||
X++;
|
||||
Nflag(X);
|
||||
Zflag(X);
|
||||
N_flag(X);
|
||||
Z_flag(X);
|
||||
}
|
||||
|
||||
static void inst_INY()
|
||||
{
|
||||
Y++;
|
||||
Nflag(Y);
|
||||
Zflag(Y);
|
||||
N_flag(Y);
|
||||
Z_flag(Y);
|
||||
}
|
||||
|
||||
static void inst_JMP()
|
||||
@ -275,22 +275,22 @@ static void inst_JSR()
|
||||
static void inst_LDA()
|
||||
{
|
||||
A = * read_ptr();
|
||||
Nflag(A);
|
||||
Zflag(A);
|
||||
N_flag(A);
|
||||
Z_flag(A);
|
||||
}
|
||||
|
||||
static void inst_LDX()
|
||||
{
|
||||
X = * read_ptr();
|
||||
Nflag(X);
|
||||
Zflag(X);
|
||||
N_flag(X);
|
||||
Z_flag(X);
|
||||
}
|
||||
|
||||
static void inst_LDY()
|
||||
{
|
||||
Y = * read_ptr();
|
||||
Nflag(Y);
|
||||
Zflag(Y);
|
||||
N_flag(Y);
|
||||
Z_flag(Y);
|
||||
}
|
||||
|
||||
static void inst_LSR()
|
||||
@ -298,8 +298,8 @@ static void inst_LSR()
|
||||
uint8_t tmp = * read_ptr();
|
||||
SR.bits.carry = tmp & 1;
|
||||
tmp >>= 1;
|
||||
Nflag(tmp);
|
||||
Zflag(tmp);
|
||||
N_flag(tmp);
|
||||
Z_flag(tmp);
|
||||
* write_ptr() = tmp;
|
||||
}
|
||||
|
||||
@ -311,8 +311,8 @@ static void inst_NOP()
|
||||
static void inst_ORA()
|
||||
{
|
||||
A |= * read_ptr();
|
||||
Nflag(A);
|
||||
Zflag(A);
|
||||
N_flag(A);
|
||||
Z_flag(A);
|
||||
}
|
||||
|
||||
static void inst_PHA()
|
||||
@ -329,8 +329,8 @@ static void inst_PHP()
|
||||
static void inst_PLA()
|
||||
{
|
||||
A = stack_pull();
|
||||
Nflag(A);
|
||||
Zflag(A);
|
||||
N_flag(A);
|
||||
Z_flag(A);
|
||||
}
|
||||
|
||||
static void inst_PLP()
|
||||
@ -345,8 +345,8 @@ static void inst_ROL()
|
||||
tmp |= SR.bits.carry & 1;
|
||||
SR.bits.carry = tmp > 0xFF;
|
||||
tmp &= 0xFF;
|
||||
Nflag(tmp);
|
||||
Zflag(tmp);
|
||||
N_flag(tmp);
|
||||
Z_flag(tmp);
|
||||
* write_ptr() = tmp;
|
||||
}
|
||||
|
||||
@ -356,8 +356,8 @@ static void inst_ROR()
|
||||
tmp |= SR.bits.carry << 8;
|
||||
SR.bits.carry = tmp & 1;
|
||||
tmp >>= 1;
|
||||
Nflag(tmp);
|
||||
Zflag(tmp);
|
||||
N_flag(tmp);
|
||||
Z_flag(tmp);
|
||||
* write_ptr() = tmp;
|
||||
}
|
||||
|
||||
@ -386,8 +386,8 @@ static void inst_SBC()
|
||||
SR.bits.carry = tmp > 0xFF;
|
||||
SR.bits.overflow = ((A^tmp)&(operand^tmp)&0x80) != 0;
|
||||
A = tmp & 0xFF;
|
||||
Nflag(A);
|
||||
Zflag(A);
|
||||
N_flag(A);
|
||||
Z_flag(A);
|
||||
}
|
||||
|
||||
static void inst_SEC()
|
||||
@ -424,29 +424,29 @@ static void inst_STY()
|
||||
static void inst_TAX()
|
||||
{
|
||||
X = A;
|
||||
Nflag(X);
|
||||
Zflag(X);
|
||||
N_flag(X);
|
||||
Z_flag(X);
|
||||
}
|
||||
|
||||
static void inst_TAY()
|
||||
{
|
||||
Y = A;
|
||||
Nflag(Y);
|
||||
Zflag(Y);
|
||||
N_flag(Y);
|
||||
Z_flag(Y);
|
||||
}
|
||||
|
||||
static void inst_TSX()
|
||||
{
|
||||
X = SP;
|
||||
Nflag(X);
|
||||
Zflag(X);
|
||||
N_flag(X);
|
||||
Z_flag(X);
|
||||
}
|
||||
|
||||
static void inst_TXA()
|
||||
{
|
||||
A = X;
|
||||
Nflag(A);
|
||||
Zflag(A);
|
||||
N_flag(A);
|
||||
Z_flag(A);
|
||||
}
|
||||
|
||||
static void inst_TXS()
|
||||
@ -457,8 +457,8 @@ static void inst_TXS()
|
||||
static void inst_TYA()
|
||||
{
|
||||
A = Y;
|
||||
Nflag(A);
|
||||
Zflag(A);
|
||||
N_flag(A);
|
||||
Z_flag(A);
|
||||
}
|
||||
|
||||
/* Addressing Implementations */
|
||||
|
4
6502.h
4
6502.h
@ -16,8 +16,8 @@ uint8_t Y;
|
||||
uint16_t PC;
|
||||
uint8_t SP; // points to first empty stack location
|
||||
|
||||
void * readAddr;
|
||||
void * writeAddr;
|
||||
void * read_addr;
|
||||
void * write_addr;
|
||||
|
||||
struct StatusBits{
|
||||
int carry:1; // bit 0
|
||||
|
16
6850.c
16
6850.c
@ -15,7 +15,7 @@ void init_uart() {
|
||||
uart_SR.bits.TDRE = 1; // we are always ready to output data
|
||||
|
||||
uart_SR.bits.RDRF = 0;
|
||||
incomingChar = 0;
|
||||
incoming_char = 0;
|
||||
|
||||
}
|
||||
|
||||
@ -27,22 +27,22 @@ int stdin_ready() {
|
||||
}
|
||||
|
||||
void step_uart() {
|
||||
if (writeAddr == &memory[DATA_ADDR]) {
|
||||
if (write_addr == &memory[DATA_ADDR]) {
|
||||
putchar(memory[DATA_ADDR]);
|
||||
fflush(stdout);
|
||||
writeAddr = NULL;
|
||||
} else if (readAddr == &memory[DATA_ADDR]) {
|
||||
write_addr = NULL;
|
||||
} else if (read_addr == &memory[DATA_ADDR]) {
|
||||
uart_SR.bits.RDRF = 0;
|
||||
readAddr = NULL;
|
||||
read_addr = NULL;
|
||||
}
|
||||
|
||||
/* update input register if empty */
|
||||
if ((n++ % 10000) == 0) { // polling stdin every cycle is performance intensive. This is a bit of a dirty hack.
|
||||
if (!uart_SR.bits.RDRF && stdin_ready()) { // the real hardware has no buffer. Remote the RDRF check for more accurate emulation.
|
||||
if (read(0, &incomingChar, 1) != 1) {
|
||||
if (read(0, &incoming_char, 1) != 1) {
|
||||
printf("Warning: read() returned 0\n");
|
||||
}
|
||||
if (incomingChar == 0x18) { // CTRL+X
|
||||
if (incoming_char == 0x18) { // CTRL+X
|
||||
printf("\r\n");
|
||||
exit(0);
|
||||
}
|
||||
@ -50,6 +50,6 @@ void step_uart() {
|
||||
}
|
||||
}
|
||||
|
||||
memory[DATA_ADDR] = incomingChar;
|
||||
memory[DATA_ADDR] = incoming_char;
|
||||
memory[CTRL_ADDR] = uart_SR.byte;
|
||||
}
|
||||
|
2
6850.h
2
6850.h
@ -19,7 +19,7 @@ union UartStatusReg {
|
||||
|
||||
union UartStatusReg uart_SR;
|
||||
|
||||
uint8_t incomingChar;
|
||||
uint8_t incoming_char;
|
||||
|
||||
void init_uart();
|
||||
|
||||
|
71
main.c
71
main.c
@ -1,71 +0,0 @@
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <termios.h>
|
||||
#include <time.h>
|
||||
|
||||
#include "6502.h"
|
||||
#include "6850.h"
|
||||
|
||||
struct termios oldTermios;
|
||||
|
||||
void step_delay()
|
||||
{
|
||||
struct timespec req, rem;
|
||||
|
||||
req.tv_sec = 0;
|
||||
req.tv_nsec = STEP_DURATION;
|
||||
|
||||
nanosleep(&req, &rem);
|
||||
}
|
||||
|
||||
void run_cpu()
|
||||
{
|
||||
for (;;) {
|
||||
// CPU timing is currently very far from being cycle-accurate
|
||||
for (int i = 0; i < (CPU_FREQ / (ONE_SECOND / STEP_DURATION)); i++) {
|
||||
step_cpu();
|
||||
step_uart();
|
||||
}
|
||||
step_delay(); // remove this for more speed
|
||||
}
|
||||
}
|
||||
|
||||
void restore_stdin()
|
||||
{
|
||||
tcsetattr(0, TCSANOW, &oldTermios);
|
||||
}
|
||||
|
||||
void raw_stdin()
|
||||
{
|
||||
struct termios newTermios;
|
||||
|
||||
tcgetattr(0, &oldTermios);
|
||||
newTermios = oldTermios;
|
||||
cfmakeraw(&newTermios);
|
||||
tcsetattr(0, TCSANOW, &newTermios);
|
||||
atexit(restore_stdin);
|
||||
}
|
||||
|
||||
int main(int argc, char *argv[])
|
||||
{
|
||||
if (argc != 2) {
|
||||
printf("Usage: %s file.rom\n", argv[0]);
|
||||
printf("The first 16k of \"file.rom\" is loaded into the last 16k of memory.\n");
|
||||
return EXIT_FAILURE;
|
||||
}
|
||||
|
||||
if (load_rom(argv[1]) != 0) {
|
||||
printf("Error loading \"%s\".\n", argv[1]);
|
||||
return EXIT_FAILURE;
|
||||
}
|
||||
|
||||
raw_stdin(); // allow individual keystrokes to be detected
|
||||
|
||||
init_tables();
|
||||
init_uart();
|
||||
|
||||
reset_cpu();
|
||||
run_cpu();
|
||||
|
||||
return EXIT_SUCCESS;
|
||||
}
|
Loading…
x
Reference in New Issue
Block a user