Hi everyone.
(i'm already sorry if this post is kind of a mess, i'm not good at writing informative things)
I've been working for the past few weeks on a Project, and as the title may suggest it's an Extended 6502 build in a logic simualtor known as Logisim (Evolution HC).
GitHub link to that here:
https://github.com/kevinawalsh/logisim-evolutionI currently just call the CPU "6502V" for one reason, if you read the last 3 characters backwards it says "V20", and that is the CPU i basically want to replicate in function.
(for anyone who doesn't know the V20 is an Intel 8088 compatible CPU that has more instructions and can run at greater clock speeds, but even at the same clock speed it's slightly faster than an 8088 due to fewer cycle counts on some instructions), and i want this to be the V20 of the 6502.
I have already "finished" the circuit, i just need to overlook it to see if i missed any mistakes, then i need to decide on the Instructions to program into it (besides the regular ones i mean).
Here the main goals i want to reach with this CPU:
1. it should be 6502 compatible (minus the bugs)
2. it should be as fast or faster than a 6502 running at the same clock speed (ie fewer cycles per instruction; also more consistent cylce counts, no extra cycles because of page boundaries or something)
3. it should have more instructions and useful features
?. final goal is to have this run on a cheap FPGA, but that'll take a while. first i just want this to work on a Logic Simulator.
The first one is already showing some problems. while making the CPU functionally identical (enough) to the 6502 is not that hard it's the timings of some things that are a bit harder to get right.
for example i
assume RDY gets acknowledged on the rising edge of a Memory Access, that is atleast how i wired it up in my CPU...
and SYNC/VPB get pulled down for a whole clock cycle, from falling edge to falling edge.
I was not able to verfy these things, while
this site was a big help with the memory accesses it doesn't cover the rest of the control signals, so i just assumed that this is how those signals are supposed to work. the
original datasheet wasn't very helpful either...
The second one is pretty easy and basically just a result of the fact that i designed the CPU from scratch instead of just copying the 6502's design.
the only thing that really holds me back from reaching even lower cycles counts are memory accesses.
also having the CPU be faster than a regular 6502 at the same clock speed makes it a bit more likely people will actually this CPU for real projects (once i got Verilog code done).
which would be nice.
The third one, that is also a bit more complicated. because i don't just want to fill the Instruction set with stuff that i think is useful, but rather with stuff that people who have worked with these CPUs for decades think is useful (ie you guys, on this forum).
about the features i have added/plan to add:
Registers:
B - basically a Secondary Accumulator, used for 16 bit arithmetics and some other instructions.
DN (Direct Page) - it's used as the upper byte for any Zeropage Addressing Mode, essentially allowing you to relocate the Zeropage to anywhere in Memory.
SN (Stack Page) - same as DN but for the Stack, upon startup/hardware reset is initialized with 0x01 for backwards compatibility.
VP (Vector Pointer) - this pointer is used to specify where the Vectors for the Reset/IRQ/NMI/BRK are located in Memory, upon startup/hardware reset is initialized with 0xFFFA for backwards compatibility. (one problem is, during a hardware Reset this register is cleared, so it makes the Reset Vector kinda pointless, should it be left uncleared upon a hardware reset? or maybe just be left uncleared after a software reset?)
Now about the instructions:
I'll post them in a style similar to
this site that i used as source for all the 6502 instructions.
note that i didn't program any of them so i don't have the cycle counts or opcodes for them (yet).
I took some of the 65C02's Instructions that i found useful: (though i could add more if needed/useful)
Code:
BIT #
BRA r
JMP (a,x)
PHX/PLX
PHY/PLY
INC/DEC A
All instructions that use the Indirect Zeropage addressing mode
Code:
#------------------------------------------------#
Existing Instructions with new Addressing Modes:
#------------------------------------------------#
LDA - Load Accumulator with Memory
N Z C I E D V
+ + - - - - -
addressing assembler opc bytes cyles
-----------------------------------------------------
ind zp post-inc LDA (oper)+ - 2 -
ind zp pre-dec LDA -(oper) - 2 -
STA - Store Accumulator in Memory
N Z C I E D V
- - - - - - -
addressing assembler opc bytes cyles
-----------------------------------------------------
ind zp post-inc STA (oper)+ - 2 -
ind zp pre-dec STA -(oper) - 2 -
JSR - Jump Subroutine
N Z C I E D V
- - - - - - -
addressing assembler opc bytes cyles
-----------------------------------------------------
indirect,X JSR (oper,x) - 3 -
long relative JSR oper - 3 -
ADC - Add Memory to Accumulator with Carry
N Z C I E D V
+ + + - - - +
addressing assembler opc bytes cyles
-----------------------------------------------------
implied ADC B - 1 -
SBC - Subtract Memory from Accumulator with Borrow
N Z C I E D V
+ + + - - - +
addressing assembler opc bytes cyles
-----------------------------------------------------
implied SBC B - 1 -
AND - AND Memory with Accumulator
N Z C I E D V
+ + - - - - -
addressing assembler opc bytes cyles
-----------------------------------------------------
implied AND B - 1 -
ORA - OR Memory with Accumulator
N Z C I E D V
+ + - - - - -
addressing assembler opc bytes cyles
-----------------------------------------------------
implied ORA B - 1 -
XOR - XOR Memory with Accumulator
N Z C I E D V
+ + - - - - -
addressing assembler opc bytes cyles
-----------------------------------------------------
implied XOR B - 1 -
CMP - Compare Memory with Accumulator
N Z C I E D V
+ + + - - - -
addressing assembler opc bytes cyles
-----------------------------------------------------
implied CMP B - 1 -
#-----------------#
New Instructions:
#-----------------#
LDB - Load Secondary Accumulator (B) with Memory
N Z C I E D V
+ + - - - - -
addressing assembler opc bytes cyles
-----------------------------------------------------
immidiate LDB #oper - 2 -
zeropage LDB oper - 2 -
zeropage,X LDB oper,X - 2 -
absolute LDB oper - 3 -
absolute,X LDB oper,X - 3 -
LDV - Load Vector Pointer with Memory
N Z C I E D V
+ + - - - - -
addressing assembler opc bytes cyles
-----------------------------------------------------
immidiate LDV #oper - 3 -
zeropage LDV oper - 2 -
STB - Store Secondary Accumulator (B) in Memory
N Z C I E D V
- - - - - - -
addressing assembler opc bytes cyles
-----------------------------------------------------
zeropage STB oper - 2 -
zeropage,X STB oper,X - 2 -
absolute STB oper - 3 -
absolute,X STB oper,X - 3 -
STV - Store Vector Pointer in Memory
N Z C I E D V
- - - - - - -
addressing assembler opc bytes cyles
-----------------------------------------------------
zeropage STV oper - 2 -
TXD - Transfer X to Direct Page
N Z C I E D V
- - - - - - -
addressing assembler opc bytes cyles
-----------------------------------------------------
implied TXD - 1 -
TXN - Transfer X to Stack Page
N Z C I E D V
- - - - - - -
addressing assembler opc bytes cyles
-----------------------------------------------------
implied TXN - 1 -
TDX - Transfer Direct Page to X
N Z C I E D V
+ + - - - - -
addressing assembler opc bytes cyles
-----------------------------------------------------
implied TDX - 1 -
TNX - Transfer Stack Page to X
N Z C I E D V
+ + - - - - -
addressing assembler opc bytes cyles
-----------------------------------------------------
implied TNX - 1 -
SNB - Swap Nibble (of the Accumulator)
N Z C I E D V
- - - - - - -
addressing assembler opc bytes cyles
-----------------------------------------------------
implied SNB - 1 -
SAB - Swap Accumulator and Secondary Accumulator (B)
N Z C I E D V
- - - - - - -
addressing assembler opc bytes cyles
-----------------------------------------------------
implied SAB - 1 -
SXY - Swap X and Y
N Z C I E D V
- - - - - - -
addressing assembler opc bytes cyles
-----------------------------------------------------
implied SXY - 1 -
PHB - Push Secondary Accumulator (B) on Stack
N Z C I E D V
- - - - - - -
addressing assembler opc bytes cyles
-----------------------------------------------------
implied PHB - 1 -
PHM - Push Memory on Stack
N Z C I E D V
- - - - - - -
addressing assembler opc bytes cyles
-----------------------------------------------------
zeropage PHM oper - 2 -
PLB - Pull Secondary Accumulator (B) from Stack
N Z C I E D V
+ + - - - - -
addressing assembler opc bytes cyles
-----------------------------------------------------
implied PHB - 1 -
PLM - Pull Memory from Stack
N Z C I E D V
- - - - - - -
addressing assembler opc bytes cyles
-----------------------------------------------------
zeropage PLM oper - 2 -
BRL - Branch Always Long
N Z C I E D V
- - - - - - -
addressing assembler opc bytes cyles
-----------------------------------------------------
long relative BRL oper - 3 -
SEV - Set Overflow Flag
N Z C I E D V
- - - - - - 1
addressing assembler opc bytes cyles
-----------------------------------------------------
implied SEV - 1 -
SEE - Set Enable Carry Flag
N Z C I E D V
- - - - 1 - -
addressing assembler opc bytes cyles
-----------------------------------------------------
implied SEE - 1 -
CLE - Clear Enable Carry Flag
N Z C I E D V
- - - - 0 - -
addressing assembler opc bytes cyles
-----------------------------------------------------
implied CLE - 1 -
RES - Software Reset
N Z C I E D V
- - - - - - -
addressing assembler opc bytes cyles
-----------------------------------------------------
implied RES - 1 -
MUL - Multiply Accumualtor with Memory (8 bit) (Low Byte stored in A, High Byte stored in B)
N Z C I E D V
+ + - - - - -
addressing assembler opc bytes cyles
-----------------------------------------------------
immidiate MUL #oper - 2 -
zeropage MUL oper - 2 -
zeropage,X MUL oper,X - 2 -
absolute MUL oper - 3 -
absolute,X MUL oper,X - 3 -
DIV - Divide Accumualtor by Memory (8 bit) (Result stored in A, Remainder stored in B)
N Z C I E D V
+ + - - - - -
addressing assembler opc bytes cyles
-----------------------------------------------------
immidiate DIV #oper - 2 -
zeropage DIV oper - 2 -
zeropage,X DIV oper,X - 2 -
absolute DIV oper - 3 -
absolute,X DIV oper,X - 3 -
ADX - Add Secondary Accumulator (B) to X with Carry
N Z C I E D V
+ + + - - - +
addressing assembler opc bytes cyles
-----------------------------------------------------
implied ADX B - 1 -
SBX - Subtract Secondary Accumulator (B) from X with Borrow
N Z C I E D V
+ + + - - - +
addressing assembler opc bytes cyles
-----------------------------------------------------
implied SBX B - 1 -
ADY - Add Secondary Accumulator (B) to Y with Carry
N Z C I E D V
+ + + - - - +
addressing assembler opc bytes cyles
-----------------------------------------------------
implied ADY B - 1 -
SBY - Subtract Secondary Accumulator (B) from Y with Borrow
N Z C I E D V
+ + + - - - +
addressing assembler opc bytes cyles
-----------------------------------------------------
implied SBY B - 1 -
ADW - Add Memory Word to Accumulator with Carry (16 bit) (Low Byte stored in A, High Byte stored in B)
N Z C I E D V
+ + + - - - +
addressing assembler opc bytes cyles
-----------------------------------------------------
immidiate ADW #oper - 3 -
zeropage ADW oper - 2 -
zeropage,X ADW oper,X - 2 -
absolute ADW oper - 3 -
absolute,X ADW oper,X - 3 -
SBW - Subtract Memory Word from Accumulator with Borrow (16 bit) (Low Byte stored in A, High Byte stored in B)
N Z C I E D V
+ + + - - - +
addressing assembler opc bytes cyles
-----------------------------------------------------
immidiate SBW #oper - 3 -
zeropage SBW oper - 2 -
zeropage,X SBW oper,X - 2 -
absolute SBW oper - 3 -
absolute,X SBW oper,X - 3 -
INW - Increment Memory word by One (16 bit)
N Z C I E D V
+ + - - - - -
addressing assembler opc bytes cyles
-----------------------------------------------------
zeropage INW oper - 2 -
absolute INW oper - 3 -
DEW - Decrement Memory word by One (16 bit)
N Z C I E D V
+ + - - - - -
addressing assembler opc bytes cyles
-----------------------------------------------------
zeropage DEW oper - 2 -
absolute DEW oper - 3 -
(no idea why the TABs are broken, it looks perfectly aligned in Notepad++ and Pastebin)
a bit more detail about some things though:
the E Flag, or "Enable Carry" Flag.
This flag is by default 1, when cleared it makes all ADC and SBC instructions (including the 16 bit variants) behave like regular ADD and SUB instructions similar to non-6502 CPUs.
that way you don't need to constantly set or clear the flag before Adding/Subtracting something.
especially useful since this CPU natively supports 16 bit Addition/Subtraction, so unless you run some regular 6502 code or need to do 32 bit math, it can simply be cleared to save yourself some SEC and CLC Instructions here and there.
next up the "ind zp post-inc" (Indirect Zeropage Post-Increment) and "ind zp pre-dec" (Indirect Zeropage Pre-Decrement) addressing modes.
the first one works like the regular "Indirect Zeropage" addressing mode, but after the read/write it Adds the contents of B to the Address and writes it back to Memory.
the second works the same but before the read/write it subtracts the contents of B from the Address, and after the read/write writes the Address back to Memory.
the idea behind using the B register instead of just Incrementing/Decrementing was to give programmers more control.
I also thought about an alternative way of doing these 2 Addressing Modes. instead of adding/subtracting B as an unsigned value, i could instead only add it but treat it like a signed value, so both the "post" and "pre" addressing modes could be used to go backwards and forwards in Memory instead of being locked to a single direction, giving the programmer even more control over them without adding more instructions. (plus ironically, it would make the circuitry a bit easier)
.
I like to hear some thoughts about this project, and Obviously i'm open for suggestions on what could get added/removed or should be changed. (to be honest i can already see the AND B, ORA B, and XOR B instructions getting removed, since i don't really know what they would be useful for, since it's slower than just using an immediate AND/OR/XOR)
and of course help is also welcome about some details on how things work... for example the timings, and i also still need to do the BCD Adder/Subtractor... but I'll pass on that one until
much later.
anyways, i'm tried, and probably missed some important detail, like always.
but i'll care about that tomorrow after i got some sleep.