From e979a3d61890d2092b67b17c6a15b7dc9aa752bf Mon Sep 17 00:00:00 2001 From: Raimon Zamora Date: Wed, 5 Feb 2025 21:32:58 +0100 Subject: [PATCH] - Seguim --- 6502m.cpp | 118 +++++++++++++++++++++++++++++++++++++++++++++----- microcode.txt | 4 +- 2 files changed, 108 insertions(+), 14 deletions(-) diff --git a/6502m.cpp b/6502m.cpp index 16da1fa..d7131df 100644 --- a/6502m.cpp +++ b/6502m.cpp @@ -11,17 +11,6 @@ #define fV 0b01000000 // Overflow #define fN 0b10000000 // Negative - // Jump types - #define cUnconditional 255 - #define cNZ 0 - #define cZ 1 - #define cNC 2 - #define cC 3 - #define cNN 4 - #define cN 5 - #define cNV 6 - #define cV 7 - // Addressing modes #define aAccumulator 0 #define aImmediate 1 @@ -103,6 +92,10 @@ namespace m6502 miReadAddress, miReadAddressAndSkip, miWriteRegister, + miWriteAddress, + miPushA, + miFetchOperandAndCheckBranch, + miCheckIfPageCrossed, miNumMicroinstructions }; @@ -114,6 +107,68 @@ namespace m6502 /* 0x03 --- */ { miFetchOpcode }, /* 0x04 --- */ { miFetchOpcode }, /* 0x05 ORA zpg */ { miFetchOperandLo, miReadAddress, miFetchOpcode }, + /* 0x06 ASL zpg */ { miFetchOperandLo, miReadAddress, miWriteAddress, miWriteAddress, miFetchOpcode }, + /* 0x07 --- */ { miFetchOpcode }, + /* 0x08 PHP */ { miFetchOperandLo, miPushP, miFetchOpcode }, + /* 0x09 ORA imm */ { miFetchOperandLo, miFetchOpcode }, + /* 0x0A ASL A */ { miFakeFetchOperand, miFetchOpcode }, + /* 0x0B --- */ { miFetchOpcode }, + /* 0x0C --- */ { miFetchOpcode }, + /* 0x0D ORA abs */ { miFetchOperandLo, miFetchOperandHi, miReadAddress, miFetchOpcode }, + /* 0x0E ASL abs */ { miFetchOperandLo, miFetchOperandHi, miReadAddress, miWriteAddress, miWriteAddress, miFetchOpcode }, + /* 0x0F --- */ { miFetchOpcode }, + + /* 0x10 BPL */ { miFetchOperandAndCheckBranch, miCheckIfPageCrossed, miFakeFetchOperand, miFetchOpcode }, + /* 0x11 ORA ind,Y */ { miFetchOperandLo, miFetchAddressLo, miFetchAddressHiAndIndex, miReadAddressAndSkip, miReadAddress, miFetchOpcode }, + /* 0x12 --- */ { miFetchOpcode }, + /* 0x13 --- */ { miFetchOpcode }, + /* 0x14 --- */ { miFetchOpcode }, + /* 0x15 ORA zpg,X */ { miFetchOperandLo, miIndexX, miReadAddress, miFetchOpcode }, + /* 0x16 ASL zpg,X */ { miFetchOperandLo, miIndexX, miReadAddress, miWriteAddress, miWriteAddress, miFetchOpcode }, + /* 0x17 --- */ { miFetchOpcode }, + /* 0x18 CLC */ { miFetchOperandLo, miFetchOpcode }, + /* 0x19 ORA abs,Y */ { miFetchOperandLo, miFetchOperandHiAndIndexY, miReadAddressAndSkip, miReadAddress, miFetchOpcode }, + /* 0x1A --- */ { miFetchOpcode }, + /* 0x1B --- */ { miFetchOpcode }, + /* 0x1C --- */ { miFetchOpcode }, + /* 0x1D ORA abs,X */ { miFetchOperandLo, miFetchOperandHiAndIndexX, miReadAddressAndSkip, miReadAddress, miFetchOpcode }, + /* 0x1E ASL abs,X */ { miFetchOperandLo, miFetchOperandHiAndIndexX, miReadAddress, miReadAddress, miWriteAddress, miWriteAddress, miFetchOpcode }, + /* 0x1F --- */ { miFetchOpcode }, + + /* 0x20 JSR abs */ { }, + /* 0x21 ORA X,ind */ { miFetchOperandLo, miIndexX, miFetchAddressLo, miFetchAddressHi, miReadAddress, miFetchOpcode }, + /* 0x22 --- */ { miFetchOpcode }, + /* 0x23 --- */ { miFetchOpcode }, + /* 0x24 --- */ { miFetchOpcode }, + /* 0x25 ORA zpg */ { miFetchOperandLo, miReadAddress, miFetchOpcode }, + /* 0x26 ASL zpg */ { miFetchOperandLo, miReadAddress, miWriteAddress, miWriteAddress, miFetchOpcode }, + /* 0x27 --- */ { miFetchOpcode }, + /* 0x28 PHP */ { miFetchOperandLo, miPushP, miFetchOpcode }, + /* 0x29 ORA imm */ { miFetchOperandLo, miFetchOpcode }, + /* 0x2A ASL A */ { miFakeFetchOperand, miFetchOpcode }, + /* 0x2B --- */ { miFetchOpcode }, + /* 0x2C --- */ { miFetchOpcode }, + /* 0x2D ORA abs */ { miFetchOperandLo, miFetchOperandHi, miReadAddress, miFetchOpcode }, + /* 0x2E ASL abs */ { miFetchOperandLo, miFetchOperandHi, miReadAddress, miWriteAddress, miWriteAddress, miFetchOpcode }, + /* 0x2F --- */ { miFetchOpcode }, + + /* 0x30 BPL */ { miFetchOperandAndCheckBranch, miCheckIfPageCrossed, miFakeFetchOperand, miFetchOpcode }, + /* 0x31 ORA ind,Y */ { miFetchOperandLo, miFetchAddressLo, miFetchAddressHiAndIndex, miReadAddressAndSkip, miReadAddress, miFetchOpcode }, + /* 0x32 --- */ { miFetchOpcode }, + /* 0x33 --- */ { miFetchOpcode }, + /* 0x34 --- */ { miFetchOpcode }, + /* 0x35 ORA zpg,X */ { miFetchOperandLo, miIndexX, miReadAddress, miFetchOpcode }, + /* 0x36 ASL zpg,X */ { miFetchOperandLo, miIndexX, miReadAddress, miWriteAddress, miWriteAddress, miFetchOpcode }, + /* 0x37 --- */ { miFetchOpcode }, + /* 0x38 CLC */ { miFetchOperandLo, miFetchOpcode }, + /* 0x39 ORA abs,Y */ { miFetchOperandLo, miFetchOperandHiAndIndexY, miReadAddressAndSkip, miReadAddress, miFetchOpcode }, + /* 0x3A --- */ { miFetchOpcode }, + /* 0x3B --- */ { miFetchOpcode }, + /* 0x3C --- */ { miFetchOpcode }, + /* 0x3D ORA abs,X */ { miFetchOperandLo, miFetchOperandHiAndIndexX, miReadAddressAndSkip, miReadAddress, miFetchOpcode }, + /* 0x3E ASL abs,X */ { miFetchOperandLo, miFetchOperandHiAndIndexX, miReadAddress, miReadAddress, miWriteAddress, miWriteAddress, miFetchOpcode }, + /* 0x3F --- */ { miFetchOpcode }, + }; void SetFlags(uint8_t flags) @@ -127,6 +182,19 @@ namespace m6502 void DoOpcodeWork() { switch (rI&0x03) { + case 0: /* Clear/set flags*/ + if ( (rI&0x1c)==0x18 ) { + switch (rI>>5) { + case 0: rP &= ~fC; break; + case 1: rP |= fC; break; + case 2: rP &= ~fI; break; + case 3: rP |= fI; break; + case 5: rP &= ~fV; break; + case 6: rP &= ~fD; break; + case 7: rP |= fD; break; + } + } + break; case 1: /* ALU */ switch ((rI>>5)&0x07) { case 0: /* ORA */ rB = rA | rB; SetFlags(fN|fZ); rA = rB; break; @@ -141,6 +209,27 @@ namespace m6502 }; } + void DoRMW() + { + switch (rI&0x03) { + case 2: /* RMW */ + if ((rI & 0xF)==0xA) rB = rA; + switch ((rI>>5)&0x07) { + case 0: /* ASL */ rP = ( rP & ~fC ) | ( (rB & 0x80)>>7 ); rB = rB << 1; SetFlags(fN|fZ); break; + }; + if ((rI & 0xF)==0xA) rA = rB; + break; + }; + } + + bool BranchCondition() + { + const uint8_t flags[4] = {fN, fV, fC, fZ}; + const uint8_t flag = flags[rI>>6]; + const bool condition = (rI>>5)&1; + return (rP & flag) == condition; + } + void InsertFetchOpcode() { microcode[microcode_pos] = miFetchOpcode; @@ -174,12 +263,17 @@ namespace m6502 void ReadAddressAndSkip() { rB = mem::read(rAD); rAD_hi += rTEMP_hi; if (rTEMP_hi) InsertFetchOpcode(); } void WriteRegister() { mem::write(rAD, (rI&3)==1 ? rA : (rI&3)==2 ? rX : rY ); } + void WriteAddress() { mem::write(rAD, rB); DoRMW(); } + void PushA() { mem::write(0x0100+(rS++), rA); } + void FetchOperandAndCheckBranch() { FetchOperandLo(); if (!BranchCondition()) InsertFetchOpcode(); else { rT = rPC_hi; rPC = rPC + (int8_t)rB; } } + void CheckIfPageCrossed() { FakeFetchOperand(); if (rPC_hi == rT) InsertFetchOpcode(); } void (*microinstructions[miNumMicroinstructions])(void) { FetchOpcode, FakeFetchOperand, FetchOperandLo, FetchOperandHi, FetchOperandHiAndIndexX, FetchOperandHiAndIndexY, PushPCHi, PushPCLo, PushP, PCLoInt, PCHiInt, IndexX, FetchAddressLo, FetchAddressHi, FetchAddressHiAndIndex, ReadAddress, - ReadAddressAndSkip, WriteRegister }; + ReadAddressAndSkip, WriteRegister, WriteAddress, PushA, FetchOperandAndCheckBranch, + CheckIfPageCrossed }; void reset() { diff --git a/microcode.txt b/microcode.txt index 5c6a578..0444762 100644 --- a/microcode.txt +++ b/microcode.txt @@ -202,8 +202,8 @@ WriteAddress Mem::Write(Address, B); DoOpcodeWork(); -CheckIfTaken - FakeFetchOperand(); +FetchOperandAndCheckBranch + Address.Lo = B = Mem::Read(PC++); If (!condition) InsertFetchOpcode(); else