Disclaimer: If this post is in the wrong category, please move it! I'm new. idk wat im doin ¯\_(ツ)_/¯
Hello! I'm Ben, a 16 year old student interested in a career in computer engineering. I've recently started a project in designing and simulating a processor, and wanted to make sure I had a strong foundation before moving too much further. I'm designing a pipelined CPU that is heavily inspired from the 6502. It differs from the 6502 in that it has fewer addressing modes and only for certain instructions, the instructions are fixed length (16 bits), all instructions take one cycle, it lacks index registers, smaller address space, has branch predication (think ARM conditional execution), and a few added instructions.
I think the instruction set that I've put together is quite reasonable. The instructions are broken up into three fields: conditional execution field (3 bits), opcode (5 bits), address/immediate (8 bits). Since the implied addressing mode takes no arguments, the lower byte (where the address or immediate would usually be) can be used as an 8 bit opcode. I find programming it very easy (although I'm biased having designed the thing
) and has a good variety of opcodes. Shifting multiplication is only 4 lines! If you think this project is the worst thing you've ever seen, please tell me! I love to learn, and there's no point in holding back informative, educational criticism.
Questions for the community:
Have I cut to much? Am I going to see a huge loss in performance on general programs due to the lack of some opcodes and addressing modes? Is there any essential functionality (opcodes/addr modes etc.) that I should add? Are there things that the 6502 lacked or things that should've been done differently? For example in my processor, CMP updates the overflow flag unlike the 6502.
The address space gives me 256 bytes of RAM, and 512 bytes of PROM. I see this fit for myself and the programs that I'll be running. I thought that if I really required more space, I could employ bank switching. Is this silly? Should I get rid of the branch predication field, have a 6 bit opcode, and put the other two bits towards the address to give me 1024 bytes?
I'm very excited about this project! I will be designing it in Logisim first, and if I'm feeling ambitious enough, I'd love to built it out of ICs.
These are the different values for the branch predication field. Every instruction in the ISA is conditional, allowing me to reduce the number of branches and therefore branch mispredicts in the pipeline.
Condition Codes
000 tru true
001 otr overflow true
010 ctr carry true
011 cfl carry false
100 ztr zero true
101 zfl zero false
110 ntr negative true
111 nfl negative false
The opcodes here are divided by their addressing mode. Majority of opcodes function identically to their 6502 counterparts. Did the 6502 do them in a way that could be improved upon? If you need me to elaborate on how I plan to implement any of them, please ask!
There's plenty of room in the implied addressing mode for instructions that don't take any arguments (or maybe 4 bit ones?).
IMPLIED
00000 nop no operation
00001 brk break
00010 wai wait for interrupt
00011 clv clear overflow
00100 sec set carry
00101 clc clear carry
00110 sei set interrupt
00111 cli clear interrupt
01000 lsl logical shift left
01001 lsr logical shift right
01010 rol rotate left
01011 ror rotate right
01100 pha push accumulator
01101 pla pull accumulator
01110 php push flags
01111 plp pull flags
10000 rti return from interrupt
10001 rts return from subroutine
10010 tas transfer accumulator to stack
10011 tsa transfer stack to accumulator
IMMEDIATE
00001 add add
00010 adc add with carry
00011 and bitwise AND
00100 eor bitwise exceptional OR
00101 ior bitwise inclusive OR
00110 cmp compare
00111 cpc compare with carry
01000 lda load accumulator
ABSOLUTE
01001 add add
01010 adc add with carry
01011 and bitwise AND
01100 eor bitwise exceptional OR
01101 ior bitwise inclusive OR
01110 cmp compare
01111 cpc compare with carry
10000 sub subtract
10001 sbc subtract with carry
10010 inc increment
10011 dec decrement
10100 lsl logical shift left
10101 lsr logical shift right
10110 rol rotate left
10111 ror rotate right
11000 jmp jump relative
11001 jmp jump indirect
11010 jsr jump subroutine
11011 xch exchange accumulator with memory address
11100 lda load accumulator
11101 lda load accumulator indirect
11110 sta store accumulator
11111 sta store accumulator indirect
Thank you so much for reading this. Means a lot to me to have a community like this to share ideas with and learn from. Take care!
Ben