summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--docs/interpreter.md64
-rw-r--r--docs/opcodes-reference.pdfbin20266 -> 0 bytes
-rw-r--r--font.bmpbin10310 -> 0 bytes
-rw-r--r--src/Makefile5
-rw-r--r--src/apple.c21
l---------src/cpu/.#addressing.c1
-rw-r--r--src/cpu/6502.c2
-rw-r--r--src/cpu/addressing.c11
-rw-r--r--src/cpu/addressing.h8
-rw-r--r--src/cpu/core.h2
-rw-r--r--src/cpu/instructions.c15
-rw-r--r--src/cpu/table.c18
-rw-r--r--src/cpu/table.h4
-rw-r--r--src/main.c2
-rw-r--r--src/test.c100
15 files changed, 143 insertions, 110 deletions
diff --git a/docs/interpreter.md b/docs/interpreter.md
deleted file mode 100644
index 85ab792..0000000
--- a/docs/interpreter.md
+++ /dev/null
@@ -1,64 +0,0 @@
-# interpreter
-
-This is a small program intended to help with testing the 6502 CPU, or running programs on it.
-
-The expected input is machine code written in plaintext.
-
-The program assumes you will write statements correctly so it doesn't waste time checking that you put four digits in instead of three. If you are using this I assume you know what you are doing.
-
-The program accepts stdin, so it can be used in two ways.
-- Typing instructions inline.
-- Piping a file in with cat.
-
-## Instructions
-
-To express the syntax of instructions, here are some valid examples to express LDA $01:
-
- a901
- A901
- A9 01
-
-If you downloaded my project on Github, I have included a PDF called `opcodes_reference.pdf` which has a table with every legal opcode in it.
-
-Statements can be seperated or on a single line. For instance,
-
- a901
- p
- q
-
-Can be written as
-
- a901pq
-
-The only case in which this should be avoided is after an M/m command.
-
-## Debug Commands
-
-The interpreter comes with multiple statements for the purpose of debugging the emulator.
-
-`Q/q` Quits the program.
-
-`R/r` Resets the virtual computer.
-
-`P/p` Dumps processor state.
-
-`M/m` Prints out memory.
-There are two forms which memory can be printed.
-The first is `sXX` where `XX` is a memory page. The whole page of memory is printed onto the screen.
-The second is `sXXXX` where `XXXX` is a specific address. This prints out the value of the 1 byte requested.
-Be aware that unallocated memory will be dumped if it happens to be accessed with this command.
-
-`S/s` Directly set a piece of memory.
-Syntax is strictly of form `sXXXX.xx` where `XXXX` is the address and `xx` is the value.
-
-`/` Prints until newline.
-
-`#` Ignores until newline.
-
-## Anomalies
-
-I don't care a whole lot about making this interpreter foolproof since its mostly for my personal debugging use. There are a couple anomalies to look out for if you intend to write programs with it.
-
-1. After M/m command, a newline is *necessary* or it will have unexpected behavior.
-2. Two newlines are necessary after single byte-length instructions or it will segfault.
-3. If Q/q is not used at the end of a program, it will segfault. It's inconsequential if it does, but it's important to know. \ No newline at end of file
diff --git a/docs/opcodes-reference.pdf b/docs/opcodes-reference.pdf
deleted file mode 100644
index ecff92b..0000000
--- a/docs/opcodes-reference.pdf
+++ /dev/null
Binary files differ
diff --git a/font.bmp b/font.bmp
deleted file mode 100644
index ec738c1..0000000
--- a/font.bmp
+++ /dev/null
Binary files differ
diff --git a/src/Makefile b/src/Makefile
index 22cf4fc..c7bf2a8 100644
--- a/src/Makefile
+++ b/src/Makefile
@@ -9,7 +9,10 @@ BUILD_STATIC_LIBRARY = ar -rcs $@ $^
# Executable Targets
default: computer.a video.a
- gcc -g -o ../apple-c -lncurses main.c $^
+ gcc -o ../apple-c -lncurses main.c $^
+
+test: computer.a video.a
+ gcc -o ../test.out -lncurses test.c $^
# Internal Libraries
diff --git a/src/apple.c b/src/apple.c
index 5877bc8..ba8737a 100644
--- a/src/apple.c
+++ b/src/apple.c
@@ -1,7 +1,7 @@
#include"apple.h"
// The Incredible Wozmon!
-const byte ROM[256] = {
+byte ROM[256] = {
0xd8, 0x58, 0xa0, 0x7f, 0x8c, 0x12, 0xd0, 0xa9,
0xa7, 0x8d, 0x11, 0xd0, 0x8d, 0x13, 0xd0, 0xc9,
0xdf, 0xf0, 0x13, 0xc9, 0x9b, 0xf0, 0x03, 0xc8,
@@ -10,25 +10,25 @@ const byte ROM[256] = {
0xf6, 0xad, 0x11, 0xd0, 0x10, 0xfb, 0xad, 0x10,
0xd0, 0x99, 0x00, 0x02, 0x20, 0xef, 0xff, 0xc9,
0x8d, 0xd0, 0xd4, 0xa0, 0xff, 0xa9, 0x00, 0xaa,
- 0x0a, 0x85, 0x2b, 0xc8, 0xb9, 0x00, 0x02, 0xc9,
+ 0x0a, 0x85, 0x2b, 0xc8, 0xb9, 0x00, 0x02, 0xc9, //0x40 ->
0x8d, 0xf0, 0xd4, 0xc9, 0xae, 0x90, 0xf4, 0xf0,
0xf0, 0xc9, 0xba, 0xf0, 0xeb, 0xc9, 0xd2, 0xf0,
0x3b, 0x86, 0x28, 0x86, 0x29, 0x84, 0x2a, 0xb9,
0x00, 0x02, 0x49, 0xb0, 0xc9, 0x0a, 0x90, 0x06,
0x69, 0x88, 0xc9, 0xfa, 0x90, 0x11, 0x0a, 0x0a,
- 0x0a, 0x0a, 0xa2, 0x04, 0x0a, 0x26, 0x28, 0x26,
+ 0x0a, 0x0a, 0xa2, 0x04, 0x0a, 0x26, 0x28, 0x26, // 0x70->
0x29, 0xca, 0xd0, 0xf8, 0xc8, 0xd0, 0xe0, 0xc4,
0x2a, 0xf0, 0x97, 0x24, 0x2b, 0x50, 0x10, 0xa5,
0x28, 0x81, 0x26, 0xe6, 0x26, 0xd0, 0xb5, 0xe6,
0x27, 0x4c, 0x44, 0xff, 0x6c, 0x24, 0x00, 0x30,
0x2b, 0xa2, 0x02, 0xb5, 0x27, 0x95, 0x25, 0x95,
- 0x23, 0xca, 0xd0, 0xf7, 0xd0, 0x14, 0xa9, 0x8d,
+ 0x23, 0xca, 0xd0, 0xf7, 0xd0, 0x14, 0xa9, 0x8d, // 0xA0->
0x20, 0xef, 0xff, 0xa5, 0x25, 0x20, 0xdc, 0xff,
0xa5, 0x24, 0x20, 0xdc, 0xff, 0xa9, 0xba, 0x20,
0xef, 0xff, 0xa9, 0xa0, 0x20, 0xef, 0xff, 0xa1,
0x24, 0x20, 0xdc, 0xff, 0x86, 0x2b, 0xa5, 0x24,
0xc5, 0x28, 0xa5, 0x25, 0xe5, 0x29, 0xb0, 0xc1,
- 0xe6, 0x24, 0xd0, 0x02, 0xe6, 0x25, 0xa5, 0x24,
+ 0xe6, 0x24, 0xd0, 0x02, 0xe6, 0x25, 0xa5, 0x24, // 0xD0->
0x29, 0x07, 0x10, 0xc8, 0x48, 0x4a, 0x4a, 0x4a,
0x4a, 0x20, 0xe5, 0xff, 0x68, 0x29, 0x0f, 0x09,
0xb0, 0xc9, 0xba, 0x90, 0x02, 0x69, 0x06, 0x2c,
@@ -41,17 +41,6 @@ void AppleOn() {
//ROM = calloc(256, sizeof(byte));
InitInstructionTable();
PC = 0xFF00;
- // Load ROM (alternative)
- /*FILE *ROM_File = fopen ("rom.bin", "rb");
- if (ROM_File == NULL) {
- printf("\n\rROM does not exist.\n");
- abort();
- }
- for (int i = 0; i < 128; i++) {
- // Retrieve in reversed order.
- ROM[(2*i)+1] = fgetc(ROM_File);
- ROM[(2*i) ] = fgetc(ROM_File);
- }*/
}
void AppleReset(){
diff --git a/src/cpu/.#addressing.c b/src/cpu/.#addressing.c
new file mode 120000
index 0000000..e0e3e02
--- /dev/null
+++ b/src/cpu/.#addressing.c
@@ -0,0 +1 @@
+aleksei@arch-desktop.664:1701869620 \ No newline at end of file
diff --git a/src/cpu/6502.c b/src/cpu/6502.c
index e7c1669..595cd4e 100644
--- a/src/cpu/6502.c
+++ b/src/cpu/6502.c
@@ -36,7 +36,7 @@ void SetFlagN(byte x){
//Perform prior to any changes TODO: FIX THIS! WTF WERE YOU THINKING?
void SetFlagV(byte x, byte y){
address z = (address)x + (address)y;
- if (z > 0xFF)
+ if ((x & 0x80) != (y & 0x80))
SetFlag(flag_V, 1);
else
SetFlag(flag_V, 0);
diff --git a/src/cpu/addressing.c b/src/cpu/addressing.c
index e5625fa..60ec4f0 100644
--- a/src/cpu/addressing.c
+++ b/src/cpu/addressing.c
@@ -8,7 +8,7 @@
//Holds address of current instruction.
void* current_instruction;
-address fAddressGetAddress(Addressing mode, short x) {
+address fAddressGetAddress(Addressing mode, address x) {
switch(mode){
case eImplied:
case eRelative:
@@ -47,12 +47,11 @@ int fAddressGetLength(Addressing mode){
}
}
-byte fAddressGetValue(Addressing mode, short x, address addr) {
+byte fAddressGetValue(Addressing mode, address x, address addr) {
switch(mode){
case eImplied:
- case eIndirectAbsolute:
return 0;
- case eRelative: // TODO: MARKER FOR 3/12/2023
+ case eRelative:
case eImmediate:
return x;
case eAccumulator:
@@ -62,7 +61,7 @@ byte fAddressGetValue(Addressing mode, short x, address addr) {
}
}
-int fAddressGetCycles(Addressing mode, short x, address addr) {
+int fAddressGetCycles(Addressing mode, address x, address addr) {
int cycles;
//case &fADC: case &fAND: case &fBIT: case &fCMP: case &fCPX: case &fCPY: case &fEOR: case &fLDA:
@@ -170,7 +169,7 @@ int fAddressGetCycles(Addressing mode, short x, address addr) {
return cycles;
}
-AddData fAddress(Addressing mode, short x) {
+AddData fAddress(Addressing mode, address x) {
AddData ret;
ret.add = fAddressGetAddress (mode, x);
ret.value = fAddressGetValue (mode, x, ret.add);
diff --git a/src/cpu/addressing.h b/src/cpu/addressing.h
index e2c882e..790b912 100644
--- a/src/cpu/addressing.h
+++ b/src/cpu/addressing.h
@@ -12,8 +12,8 @@
// For a given addressing mode and opcode, return data about the instruction.
-AddData fAddress (Addressing mode, short x );
-address fAddressGetAddress (Addressing mode, short x );
+AddData fAddress (Addressing mode, address x );
+address fAddressGetAddress (Addressing mode, address x );
int fAddressGetLength (Addressing mode );
-byte fAddressGetValue (Addressing mode, short x, address addr);
-int fAddressGetCycles (Addressing mode, short x, address addr); \ No newline at end of file
+byte fAddressGetValue (Addressing mode, address x, address addr);
+int fAddressGetCycles (Addressing mode, address x, address addr);
diff --git a/src/cpu/core.h b/src/cpu/core.h
index 5a73818..4545cd5 100644
--- a/src/cpu/core.h
+++ b/src/cpu/core.h
@@ -15,7 +15,7 @@ extern byte P;
extern byte S;
extern address PC;
extern byte* Memory;
-extern const byte ROM[];
+extern byte ROM[];
enum Addressing
diff --git a/src/cpu/instructions.c b/src/cpu/instructions.c
index b4daf6e..1a94386 100644
--- a/src/cpu/instructions.c
+++ b/src/cpu/instructions.c
@@ -68,6 +68,7 @@ void fSBC(Addressing addr, address val){
SetFlag(flag_C, (buffer > acc) ? 1 : 0);
acc = buffer;
+
SetFlagN(acc);
SetFlagZ(acc);
}
@@ -135,7 +136,7 @@ void fEOR(Addressing addr, address val){
// Jump, Branch, Compare, and Test Bits
void fJMP(Addressing addr, address val){
- PC = idata.add - idata.length;
+ PC = idata.value - idata.length;
}
void fBCC(Addressing addr, address val){
@@ -189,9 +190,9 @@ void fCPY(Addressing addr, address val){
}
void fBIT(Addressing addr, address val){
- SetFlag(flag_N, (idata.value & flag_N) ? 1 : 0);
- SetFlag(flag_V, (idata.value & flag_V) ? 1 : 0);
- SetFlag(flag_Z, (idata.value & acc) ? 0 : 1);
+ SetFlag(flag_N, ((idata.value & flag_N) != 0) ? 1 : 0);
+ SetFlag(flag_V, ((idata.value & flag_V) != 0) ? 1 : 0);
+ SetFlag(flag_Z, ((idata.value & acc) == 0) ? 1 : 0);
}
// Shift and Rotate Instructions
@@ -321,14 +322,14 @@ void fPLP(Addressing addr, address val){
// Subroutine Instructions
void fJSR(Addressing addr, address val){
- SetStack((PC+3) >> 8);
- SetStack((PC+3) & 0x00FF);
+ SetStack ((PC+idata.length) >> 8);
+ SetStack(((PC+idata.length) & 0x00FF) - 1);
PC = idata.add;
PC -= idata.length;
}
void fRTS(Addressing addr, address val){
- PC = (address)(GetStack());
+ PC = (address)(GetStack()) + 1;
PC += ((address)(GetStack())) << 8;
PC -= idata.length;
}
diff --git a/src/cpu/table.c b/src/cpu/table.c
index 735ab80..4e60f58 100644
--- a/src/cpu/table.c
+++ b/src/cpu/table.c
@@ -17,24 +17,28 @@ Addressing* GetInstructionTableAddressing(int i){
return r;
}
-void CallInstructionTable(int i, address val){
- val = 0; // TODO: Let the initial value of val be redundant for now so as to not break anything, but fix later
+void CallInstructionTable(){
+ int val = 0;
// Setup to call the correct function.
+ int i = (address)GetMemory(PC);
uintptr_t a = GetInstructionTableFunction(i);
memcpy(&func, a, sizeof(uintptr_t));
// Find the correct addressing mode.
- Addressing* r = (InstructionTable + ((sizeof(uintptr_t)*256) + (sizeof(Addressing) * i)));
+ Addressing r = *(Addressing*)(InstructionTable + ((sizeof(uintptr_t)*256) + (sizeof(Addressing) * i)));
// Set val
- if (fAddressGetLength(*r) >= 2)
+ if (fAddressGetLength(r) >= 2)
val += (address)GetMemory(PC+1);
- if (fAddressGetLength(*r) == 3)
+ if (fAddressGetLength(r) == 3)
val += (address)GetMemory(PC+2) << 8;
+
// Set idata
- idata = fAddress(*r, val);
+ idata = fAddress(r, val);
// Perform function
- func(*r, val); // TODO: MARKER FOR 3/12/2023
+ func(r, val); // TODO: MARKER FOR 3/12/2023
+
+
PC += idata.length;
}
diff --git a/src/cpu/table.h b/src/cpu/table.h
index 18cac90..7406c9c 100644
--- a/src/cpu/table.h
+++ b/src/cpu/table.h
@@ -14,10 +14,10 @@ uintptr_t* GetInstructionTableFunction(int i);
Addressing* GetInstructionTableAddressing(int i);
-void CallInstructionTable(int i, address val);
+void CallInstructionTable();
// Sets an individual portion of an instruction set
void SetInstructionTable(int i, uintptr_t p, Addressing r);
// Initializes instruction table in memory.
-void InitInstructionTable(); \ No newline at end of file
+void InitInstructionTable();
diff --git a/src/main.c b/src/main.c
index f4ddf1b..d857d43 100644
--- a/src/main.c
+++ b/src/main.c
@@ -20,7 +20,7 @@ int main() {
fprintf(Log, "%04x : %04x\n", Time, PC);
fflush(Log);
// Computing
- CallInstructionTable(GetMemory(PC), 0);
+ CallInstructionTable();
// Display information
PrintInfo();
// Logging
diff --git a/src/test.c b/src/test.c
new file mode 100644
index 0000000..0aec2ce
--- /dev/null
+++ b/src/test.c
@@ -0,0 +1,100 @@
+#include "cpu/core.h"
+#include "apple.h"
+#include "video/interface.h"
+#include <ncurses.h>
+#include <unistd.h>
+
+
+/*
+ README
+ Assumes that the definition of ROM in apple.c has
+ been commented out.
+
+ This program is a successor to my 'interpreter.c'
+ utility, which unfortunately did not keep up with
+ the progress of my program.
+ This one works by letting you program the ROM with
+ whatever machine code you want.
+
+ */
+
+
+
+byte ROM[] = {
+ // ADC : 0xFF00
+ 0x18,
+ 0xA5, 0x20,
+ 0x65, 0x22,
+ 0x85, 0x24,
+ 0xA5, 0x21,
+ 0x65, 0x23,
+ 0x85, 0x25,
+ // SBC : 0xFF0D
+ 0x38,
+ 0xA5, 0x30,
+ 0xE5, 0x32,
+ 0x85, 0x34,
+ 0xA5, 0x31,
+ 0xE5, 0x33,
+ 0x85, 0x35
+};
+
+int main() {
+
+
+ AppleOn();
+
+ PC = 0xFF0D;
+
+ // ADC Memory
+ SetMemory(0x0020, 0x31);
+ SetMemory(0x0021, 0x11);
+ SetMemory(0x0022, 0xF9);
+ SetMemory(0x0023, 0x0A);
+ // SBC Memory
+ SetMemory(0x0030, 0x34);
+ SetMemory(0x0031, 0x12);
+ SetMemory(0x0032, 0x43);
+ SetMemory(0x0033, 0x01);
+
+ DisplayInit();
+
+ while(1) {
+ // Computing
+ CallInstructionTable(GetMemory(PC), 0);
+ // Display information
+ PrintInfo();
+ // Wait to proceed
+ WAIT_ON_USER:
+ char c = getch();
+ mvprintw(28, 4, " ");
+ // If user presses enter, get input.
+ if (c == 0x0A) {
+ address a = 0x0000;
+ mvprintw(28, 4, "Enter address: 0x");
+ for (int i = 3; i >= 0; i--) {
+ GET_HEX:
+ c = getch();
+ char cc;
+ if ((c >= '0') && (c <= '9')) {
+ cc = c-'0';
+ }
+ else if ((c >= 'A') && (c <= 'F')) {
+ cc = c-'A'+10;
+ }
+ else {
+ goto GET_HEX;
+ // Direct all complaints to /dev/null
+ }
+ mvaddch(28, 24-i, c);
+ a |= ((address)cc) << 4*i;
+ }
+ mvprintw(28, 25, " -> %02x", GetMemory(a));
+ goto WAIT_ON_USER;
+ }
+ }
+
+ DisplayClose();
+
+ return 0;
+}