initial commit

This commit is contained in:
Jorj Bauer 2017-02-19 13:46:13 -05:00
commit 85a97abe13
9 changed files with 25884 additions and 0 deletions

Makefile Executable file
View File

@ -0,0 +1,16 @@
CXXFLAGS=-Wall -I .. -I . -O3
TSRC=cpu.cpp util/testharness.cpp
@echo There is no 'all' target. Yet.
rm -f *.o *~ */*.o */*~ testharness.basic testharness.verbose testharness.extended
test: $(TSRC)
g++ $(CXXFLAGS) -DBASICTEST $(TSRC) -o testharness.basic
g++ $(CXXFLAGS) -DVERBOSETEST $(TSRC) -o testharness.verbose
g++ $(CXXFLAGS) -DEXTENDEDTEST $(TSRC) -o testharness.extended

README.txt Normal file
View File

@ -0,0 +1,52 @@
Aiie! is an Apple //e emulator, written ground-up for the Teensy
The name comes from a game I used to play on the Apple //e back
around 1986 - Ali Baba and the Forty Thieves, published by Quality
Software in 1981.
When characters in the game did damage to each other, they exclaimed
something like "HAH! JUST A SCRATCH!" or "AAARGH!" or "OH MA, I THINK
ITS MY TIME" [sic]. One of these exclamations was "AIIYEEEEE!!"
Build log:
The CPU is a 65C02, not quite complete; it supports all of the 65C02
documented opcodes but not the undocumented ones here:
The timing of the CPU is also not quite correct. It's close, but
doesn't count cycles due to page boundary crossings during branch
instructions. (See the "cycle count footnotes" in cpu.cpp.)
The CPU passes the 6502 functional test from here:
... which is included in binary form in the test harness (see the .h
files in util/ for notes).
testharness.basic should reach "test number 240", hang for a while,
and then exit.
testharness.verbose should show that it gets through 43 tests, test
240, and then loops repeatedly for a while (exiting at a somewhat
arbitrary point).
testharness.extended currently fails (hanging at 0x733) because I
haven't implemented the undocumented opcodes. It should get to address
0x24a8 and hang. Some day I'll finish implementing all of the
undocumented opcodes :)

cpu.cpp Normal file

File diff suppressed because it is too large Load Diff

cpu.h Normal file
View File

@ -0,0 +1,73 @@
#ifndef __CPU_H
#define __CPU_H
#include <stdlib.h>
#include <stdint.h>
class MMU;
// Flags (P) register bit definitions.
// Negative
#define F_N (1<<7)
// Overflow
#define F_V (1<<6)
#define F_UNK (1<<5) // What the heck is this?
// Break
#define F_B (1<<4)
// Decimal
#define F_D (1<<3)
// Interrupt Disable
#define F_I (1<<2)
// Zero
#define F_Z (1<<1)
// Carry
#define F_C (1<<0)
class Cpu {
void Reset();
void nmi();
void rst();
void brk();
void irq();
uint8_t Run(uint8_t numSteps);
uint8_t step();
uint8_t X();
uint8_t Y();
uint8_t A();
uint16_t PC();
uint8_t SP();
uint8_t P();
// Stack manipulation
void pushS8(uint8_t b);
void pushS16(uint16_t w);
uint8_t popS8();
uint16_t popS16();
void SetMMU(MMU *mmu) { this->mmu = mmu; }
uint16_t pc;
uint8_t sp;
uint8_t a;
uint8_t x;
uint8_t y;
uint8_t flags;
uint32_t cycles;
MMU *mmu;

mmu.h Normal file
View File

@ -0,0 +1,17 @@
#ifndef __MMU_H
#define __MMU_H
#include <stdint.h>
class MMU {
virtual ~MMU() {}
virtual void Reset() = 0;
virtual uint8_t read(uint16_t mem) = 0;
virtual void write(uint16_t mem, uint8_t val) = 0;
virtual uint8_t readDirect(uint16_t address, uint8_t fromPage) = 0;

util/6502_functional_test.h Normal file

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

util/testharness.cpp Normal file
View File

@ -0,0 +1,64 @@
#include <stdio.h>
#include <time.h>
#include <string.h>
#include "cpu.h"
#include "mmu.h"
#include "6502_functional_test.h"
#elif defined(VERBOSETEST)
#include "6502_functional_test_2.h"
#elif defined(EXTENDEDTEST)
#include "65C02_extended_opcodes_test.h"
#error undefined test - specify one of BASICTEST, VERBOSETEST, or EXTENDEDTEST
class TestMMU : public MMU {
TestMMU() {}
virtual ~TestMMU() {}
virtual void Reset() {}
virtual uint8_t read(uint16_t mem) { if (mem == 0xBFF0) { return 'R'; } return ram[mem];}
virtual void write(uint16_t mem, uint8_t val) {
if (mem == 0xBFF0) {printf("%c", val); return;}
if (mem == 0x200) {printf("Start test %d\n", val);}
ram[mem] = val;}
virtual uint8_t readDirect(uint16_t address, uint8_t fromPage) { return read(address);}
uint8_t ram[65536];
Cpu cpu;
TestMMU mmu;
int main(int argc, char *argv[])
// Load the 6502 functional test
memcpy(mmu.ram, functest, 0x10000);
cpu.pc = 0x400;
// cpu.Reset();
time_t startTime = time(NULL);
// call cpu.Run() in the worst possible way (most overhead)
for (uint32_t i=0; i<1000000000; i++) {
#if 0
if (cpu.pc < 0x477F) {
printf("%llu OP $%.2X #%d 0x%.2X X 0x%.2X Y 0x%.2X A 0x%.2X SP 0x%.2X S 0x%.2X\n", cpu.cycles,,, cpu.pc, cpu.x, cpu.y, cpu.a, cpu.sp, cpu.flags);
time_t endTime = time(NULL);
printf("%ld seconds\n", endTime - startTime);
printf("Ending PC: 0x%X\n", cpu.pc);