diff options
author | alekseiplusplus <alekseijeaves@protonmail.com> | 2023-12-07 02:19:48 +1100 |
---|---|---|
committer | alekseiplusplus <alekseijeaves@protonmail.com> | 2023-12-07 02:19:48 +1100 |
commit | 98dd41e2ce7dedb81ab91342eed29da017006ea4 (patch) | |
tree | de5efd1f899815dcad218accda405873687cbaf1 | |
parent | 5bb10fc4121a8c8434dcd367f2e611599a11e12e (diff) |
about to rip apart my code, so saving progress
-rw-r--r-- | docs/interpreter.md | 64 | ||||
-rw-r--r-- | docs/opcodes-reference.pdf | bin | 20266 -> 0 bytes | |||
-rw-r--r-- | font.bmp | bin | 10310 -> 0 bytes | |||
-rw-r--r-- | src/Makefile | 5 | ||||
-rw-r--r-- | src/apple.c | 21 | ||||
l--------- | src/cpu/.#addressing.c | 1 | ||||
-rw-r--r-- | src/cpu/6502.c | 2 | ||||
-rw-r--r-- | src/cpu/addressing.c | 11 | ||||
-rw-r--r-- | src/cpu/addressing.h | 8 | ||||
-rw-r--r-- | src/cpu/core.h | 2 | ||||
-rw-r--r-- | src/cpu/instructions.c | 15 | ||||
-rw-r--r-- | src/cpu/table.c | 18 | ||||
-rw-r--r-- | src/cpu/table.h | 4 | ||||
-rw-r--r-- | src/main.c | 2 | ||||
-rw-r--r-- | src/test.c | 100 |
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 Binary files differdeleted file mode 100644 index ecff92b..0000000 --- a/docs/opcodes-reference.pdf +++ /dev/null diff --git a/font.bmp b/font.bmp Binary files differdeleted file mode 100644 index ec738c1..0000000 --- a/font.bmp +++ /dev/null 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(); @@ -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; +} |