1 Commits

Author SHA1 Message Date
d0193727e7 Updated contact details 2017-01-22 12:58:48 +10:00
12 changed files with 71 additions and 381 deletions

BIN
.DS_Store vendored

Binary file not shown.

BIN
6502tests/.DS_Store vendored

Binary file not shown.

View File

@ -4,7 +4,7 @@ Bunch of unit tests I wrote during the development of the emulator.
These are very nasty and not really release worthy but someone might These are very nasty and not really release worthy but someone might
find them useful! find them useful!
Copyright (c) 2015, Damian Peckett <damian.peckett@gmail.com> Copyright (c) 2015, Damian Peckett <damian@pecke.tt>
All rights reserved. All rights reserved.
Redistribution and use in source and binary forms, with or without Redistribution and use in source and binary forms, with or without

Binary file not shown.

BIN
APPLEII/.DS_Store vendored

Binary file not shown.

View File

@ -1,5 +1,5 @@
/* /*
Copyright (c) 2015, Damian Peckett <damian.peckett@gmail.com> Copyright (c) 2015, Damian Peckett <damian@pecke.tt>
All rights reserved. All rights reserved.
Redistribution and use in source and binary forms, with or without Redistribution and use in source and binary forms, with or without

View File

@ -1,54 +0,0 @@
// In fastcpu ino
extern unsigned short PC;
extern unsigned char X, Y;
// Addressing Modes
unsigned short inline a_abs() {
PC += 2;
return read16(PC-2);
}
unsigned short inline a_absx() {
PC += 2;
return (read16(PC-2) + (unsigned short)X);
}
unsigned short inline a_absy() {
PC += 2;
return (read16(PC-2) + (unsigned short)Y);
}
unsigned short inline a_imm() {
return PC++;
}
//ignore page wrap bug
unsigned short inline a_ind() {
PC += 2;
return read16(read16(PC-2));
}
unsigned short inline a_indx() {
return read16(((unsigned short)read8(PC++) + (unsigned short)X)&0xFF);
}
unsigned short inline a_indy() {
return read16(((unsigned short)read8(PC++) + (unsigned short)Y)&0xFF);
}
unsigned short inline a_rel() {
unsigned short addr = (unsigned short)read8(PC++);
return addr | ((addr&0x80)?0xFF00:0x0000);
}
unsigned short inline a_zpg() {
return (unsigned short)read8(PC++);
}
unsigned short inline a_zpgx() {
return ((unsigned short)read8(PC++) + (unsigned short)X)&0xFF;
}
unsigned short inline a_zpgy() {
return ((unsigned short)read8(PC++) + (unsigned short)Y)&0xFF;
}

View File

@ -1,6 +1,6 @@
// μ6502 - Barebones 6502 Emulator By Damian Peckett // μ6502 - Barebones 6502 Emulator By Damian Peckett
// dpeckett.com, <damian.peckett@gmail.com> // dpeckett.com, <damian@pecke.tt>
/*
// Address Modes // Address Modes
#define AD_IMP 0x01 #define AD_IMP 0x01
#define AD_A 0x02 #define AD_A 0x02
@ -60,10 +60,6 @@ const unsigned char flags[] PROGMEM = {
AD_REL, FL_ALL|AD_INDY, UNDF, UNDF, UNDF, FL_ALL|AD_ZPGX, FL_ZN|AD_ZPGX, UNDF, AD_IMP, FL_ALL|AD_ABSY, UNDF, UNDF, UNDF, FL_ALL|AD_ABSX, FL_ZN|AD_ABSX, UNDF AD_REL, FL_ALL|AD_INDY, UNDF, UNDF, UNDF, FL_ALL|AD_ZPGX, FL_ZN|AD_ZPGX, UNDF, AD_IMP, FL_ALL|AD_ABSY, UNDF, UNDF, UNDF, FL_ALL|AD_ABSX, FL_ZN|AD_ABSX, UNDF
}; };
const void *opcode[] PROGMEM = {
}
// CPU registers // CPU registers
unsigned short PC; unsigned short PC;
unsigned char STP = 0xFD, A = 0x00, X = 0x00, Y = 0x00, SR = SR_FIXED_BITS; unsigned char STP = 0xFD, A = 0x00, X = 0x00, Y = 0x00, SR = SR_FIXED_BITS;
@ -93,6 +89,25 @@ void setflags() {
if(opflags&0x40) SR |= ((result^((unsigned short)A))&(result^value16)&0x0080)>>1; if(opflags&0x40) SR |= ((result^((unsigned short)A))&(result^value16)&0x0080)>>1;
} }
// Stack functions
void push16(unsigned short pushval) {
write8(STP_BASE + (STP--), (pushval>>8)&0xFF);
write8(STP_BASE + (STP--), pushval&0xFF);
}
void push8(unsigned char pushval) {
write8(STP_BASE + (STP--), pushval);
}
unsigned short pull16() {
value16 = read8(STP_BASE + (++STP)) | ((unsigned short)read8(STP_BASE + (++STP))<< 8);
return value16;
}
unsigned char pull8() {
return read8(STP_BASE + (++STP));
}
void run() { void run() {
// Load the reset vector // Load the reset vector
PC = read16(0xFFFC); PC = read16(0xFFFC);
@ -156,8 +171,6 @@ void run() {
break; break;
} }
//opcodes //opcodes
switch(opcode) { switch(opcode) {
//ADC //ADC
@ -512,4 +525,4 @@ void run() {
break; break;
} }
} }
}*/ }

View File

@ -1,209 +0,0 @@
// μ6502 v2.0 - Barebones 6502 Emulator By Damian Peckett
// dpeckett.com, <damian.peckett@gmail.com>
//Other constants
#define SR_FIXED_BITS 0x20
#define SR_CARRY 0x01
#define SR_ZERO 0x02
#define SR_INT 0x04
#define SR_DEC 0x08
#define SR_BRK 0x10
#define SR_OVER 0x40
#define SR_NEG 0x80
//Stack pointer base address
#define STP_BASE 0x100
// CPU registers
unsigned short PC;
unsigned char STP = 0xFD, A = 0x00, X = 0x00, Y = 0x00, SR = SR_FIXED_BITS;
void run() {
// Opcode Addresses, Labels As Values
static const void* opcodes[] = {
&&BRK, &&ORA_INDX, &&UNDF, &&UNDF, &&UNDF, &&ORA_ZPG, &&ASL_ZPG, &&UNDF, &&PHP, &&ORA_IMM, &&ASL_A, &&UNDF, &&UNDF, &&ORA_ABS, &&ASL_ABS, &&UNDF,
&&BPL_REL, &&ORA_INDY, &&UNDF, &&UNDF, &&UNDF, &&ORA_ZPGX, &&ASL_ZPGX, &&UNDF, &&CLC, &&ORA_ABSY, &&UNDF, &&UNDF, &&UNDF, &&ORA_ABSX, &&ASL_ABSX, &&UNDF,
&&JSR_ABS, &&AND_INDX, &&UNDF, &&UNDF, &&BIT_ZPG, &&AND_ZPG, &&ROL_ZPG, &&UNDF, &&PLP, &&AND_IMM, &&ROL_A, &&UNDF, &&BIT_ABS, &&AND_ABS, &&ROL_ABS, &&UNDF
};
unsigned char value8, result8;
unsigned short value16, result16;
unsigned short ptr;
// Load the reset vector
PC = read16(0xFFFC);
// Begin Execution
goto *opcodes[read8(PC++)];
// Instruction interpreter
BRK:
push16(PC+1);
push8(SR|SR_BRK);
SR |= SR_INT;
PC = read16(0xFFFE);
goto *opcodes[read8(PC++)];
ORA_INDX:
A |= read8(a_indx());
flagZero(A);
flagNegative(A);
goto *opcodes[read8(PC++)];
ORA_ZPG:
A |= read8(a_zpg());
flagZero(A);
flagNegative(A);
goto *opcodes[read8(PC++)];
ASL_ZPG:
ptr = a_zpg();
value16 = read8(ptr);
result16 = value16<<1;
flagZero(result16&0x00FF);
flagNegative(result16&0x00FF);
flagCarry(result16);
write8(ptr, result16&0x00FF);
goto *opcodes[read8(PC++)];
PHP:
push8(SR|SR_BRK);
goto *opcodes[read8(PC++)];
ORA_IMM:
A |= read8(a_imm());
flagZero(A);
flagNegative(A);
goto *opcodes[read8(PC++)];
ASL_A:
value16 = A;
result16 = value16<<1;
flagZero(result16&0x00FF);
flagNegative(result16&0x00FF);
flagCarry(result16);
A = result16&0x00FF;
goto *opcodes[read8(PC++)];
ORA_ABS:
A |= read8(a_abs());
flagZero(A);
flagNegative(A);
goto *opcodes[read8(PC++)];
ASL_ABS:
ptr = a_abs();
value16 = read8(ptr);
result16 = value16<<1;
flagZero(result16&0x00FF);
flagNegative(result16&0x00FF);
flagCarry(result16);
write8(ptr, result16&0x00FF);
goto *opcodes[read8(PC++)];
BPL_REL:
if(!(SR&SR_NEG)) PC += a_rel();
goto *opcodes[read8(PC++)];
ORA_INDY:
A |= read8(a_indy());
flagZero(A);
flagNegative(A);
goto *opcodes[read8(PC++)];
ORA_ZPGX:
A |= read8(a_zpgx());
flagZero(A);
flagNegative(A);
goto *opcodes[read8(PC++)];
ASL_ZPGX:
ptr = a_zpgx();
value16 = read8(ptr);
result16 = value16<<1;
flagZero(result16&0x00FF);
flagNegative(result16&0x00FF);
flagCarry(result16);
write8(ptr, result16&0x00FF);
goto *opcodes[read8(PC++)];
CLC:
SR &= ~SR_CARRY;
goto *opcodes[read8(PC++)];
ORA_ABSY:
A |= read8(a_absy());
flagZero(A);
flagNegative(A);
goto *opcodes[read8(PC++)];
ORA_ABSX:
A |= read8(a_absx());
flagZero(A);
flagNegative(A);
goto *opcodes[read8(PC++)];
ASL_ABSX:
ptr = a_absx();
value16 = read8(ptr);
result16 = value16<<1;
flagZero(result16&0x00FF);
flagNegative(result16&0x00FF);
flagCarry(result16);
write8(ptr, result16&0x00FF);
goto *opcodes[read8(PC++)];
JSR_ABS:
push16(PC-1);
PC = a_abs();
goto *opcodes[read8(PC++)];
AND_INDX:
A &= read8(a_indx());
flagZero(A);
flagNegative(A);
goto *opcodes[read8(PC++)];
BIT_ZPG:
value8 = read8(a_zpg());
result8 = A & value8;
flagZero(result8);
SR = (SR&0x3F) | (value8&0xC0);
goto *opcodes[read8(PC++)];
AND_ZPG:
A &= read8(a_zpg());
flagZero(A);
flagNegative(A);
goto *opcodes[read8(PC++)];
ROL_ZPG:
ptr = a_zpg();
value16 = read8(ptr);
result16 = (value16 << 1) | (SR&SR_CARRY);
flagZero(result16&0x00FF);
flagNegative(result16&0x00FF);
flagCarry(result16);
write8(ptr, result16&0x00FF);
goto *opcodes[read8(PC++)];
PLP:
SR = pull8() | SR_FIXED_BITS;
goto *opcodes[read8(PC++)];
AND_IMM:
A &= read8(a_imm());
flagZero(A);
flagNegative(A);
goto *opcodes[read8(PC++)];
ROL_A:
value16 = A;
result16 = (value16 << 1) | (SR&SR_CARRY);
flagZero(result16&0x00FF);
flagNegative(result16&0x00FF);
flagCarry(result16);
A = result16&0x00FF;
goto *opcodes[read8(PC++)];
BIT_ABS:
value8 = read8(a_abs());
result8 = A & value8;
flagZero(result8);
SR = (SR&0x3F) | (value8&0xC0);
goto *opcodes[read8(PC++)];
AND_ABS:
A &= read8(a_abs());
flagZero(A);
flagNegative(A);
goto *opcodes[read8(PC++)];
ROL_ABS:
ptr = a_abs();
value16 = read8(ptr);
result16 = (value16 << 1) | (SR&SR_CARRY);
flagZero(result16&0x00FF);
flagNegative(result16&0x00FF);
flagCarry(result16);
write8(ptr, result16&0x00FF);
goto *opcodes[read8(PC++)];
// -- Undefined Opcodes
UNDF:
// Raise an error
goto *opcodes[read8(PC++)];
}

View File

@ -1,16 +0,0 @@
void inline flagZero(unsigned char value) {
if(!value) SR |= SR_ZERO;
else SR &= ~SR_ZERO;
}
void inline flagNegative(unsigned char value) {
if(value&0x80) SR |= SR_NEG;
else SR &= ~SR_NEG;
}
void inline flagCarry(unsigned short value) {
if(value&0xFF00) SR |= SR_CARRY;
else SR &= ~SR_CARRY;
}

View File

@ -1026,82 +1026,52 @@ const unsigned char rom[] PROGMEM = { //$E000 - FFFF
}; };
unsigned char ram[1024]; unsigned char ram[1024];
// Free memory for storing BASIC programs
unsigned char basic[512];
unsigned char inline read8(unsigned short address) { unsigned char read8(unsigned short address) {
switch(address>>8) { unsigned char page = address>>8;
case 0x00: case 0x01: if(page < 0x04) {
case 0x02: case 0x03:
return ram[address]; return ram[address];
case 0x04: case 0x05: } else if (page >= 0x04 && page < 0x08) {
case 0x06: case 0x07:
return screenRead(address); return screenRead(address);
case 0xC0: } else if (page >= 0x08 && page < 0x10) {
return softSwitch(address); return basic[address-0x800];
case 0xE0: case 0xE1: } else if (page >= 0xE0) {
case 0xE2: case 0xE3:
case 0xE4: case 0xE5:
case 0xE6: case 0xE7:
case 0xE8: case 0xE9:
case 0xEA: case 0xEB:
case 0xEC: case 0xED:
case 0xEE: case 0xEF:
case 0xF0: case 0xF1:
case 0xF2: case 0xF3:
case 0xF4: case 0xF5:
case 0xF6: case 0xF7:
case 0xF8: case 0xF9:
case 0xFA: case 0xFB:
case 0xFC: case 0xFD:
case 0xFE: case 0xFF:
return pgm_read_byte_near(rom+address-0xE000); return pgm_read_byte_near(rom+address-0xE000);
default: } else {
return 0xFF; // Keyboard Data
if(address == 0xC000) return keyboard_read();
// Keyboard Strobe
if(address == 0xC010) keyboard_strobe();
// Speaker toggle
if(address == 0xC030) speaker_toggle();
return 0;
} }
} }
unsigned short inline read16(unsigned short address) { unsigned short read16(unsigned short address) {
return (unsigned short)read8(address) | (((unsigned short)read8(address+1))<<8); return (unsigned short)read8(address) | (((unsigned short)read8(address+1))<<8);
} }
void inline write8(unsigned short address, unsigned char value) { void write8(unsigned short address, unsigned char value) {
switch(address>>8) { unsigned char page = address>>8;
case 0x00: case 0x01: if(page < 0x04) {
case 0x02: case 0x03:
ram[address] = value; ram[address] = value;
break; } else if(page >= 0x04 && page < 0x08) {
case 0x04: case 0x05:
case 0x06: case 0x07:
screenWrite(address, value); screenWrite(address, value);
break; } else if (page >= 0x08 && page < 0x10) {
case 0xC0: basic[address-0x800] = value;
softSwitch(address); } else {
break; // Keyboard Strobe
default: if(address == 0xC010) keyboard_strobe();
return; // Speaker toggle
if(address == 0xC030) speaker_toggle();
} }
} }
void inline write16(unsigned short address, unsigned short value) { void write16(unsigned short address, unsigned short value) {
write8(address, value&0x00FF); write8(address, value&0x00FF);
write8(address+1, (value>>8)&0x00FF); write8(address+1, (value>>8)&0x00FF);
} }
// Stack functions
void inline push16(unsigned short pushval) {
write8(STP_BASE + (STP--), (pushval>>8)&0xFF);
write8(STP_BASE + (STP--), pushval&0xFF);
}
void inline push8(unsigned char pushval) {
write8(STP_BASE + (STP--), pushval);
}
unsigned short inline pull16() {
unsigned short value16 = read8(STP_BASE + (++STP)) | ((unsigned short)read8(STP_BASE + (++STP))<< 8);
return value16;
}
unsigned char inline pull8() {
return read8(STP_BASE + (++STP));
}

View File

@ -1,14 +0,0 @@
unsigned char softSwitch(unsigned short address) {
switch(address&0x00FF) {
case 0x00: // Keyboard Data
return keyboard_read();
case 0x10: // Keyboard Strobe
keyboard_strobe();
return 0xFF;
case 0x30: // Speaker toggle
speaker_toggle();
return 0xFF;
default:
return 0xFF;
}
}