Emulating a CPU in C++ #16 (6502) - Increment & Decrement

  Рет қаралды 4,617

Dave Poo

Dave Poo

Күн бұрын

In this episode I test and implement all the 6502 instructions to increment and decrement values.
Links:
Source for this project: github.com/davepoo/6502Emulator
Google Test: github.com/google/googletest
6502 Information: www.obelisk.me.uk/6502/
Timestamps:
0:00 Intro
1:38 INX tests
6:10 INX implemented
6:49 INY tests
8:06 INY implemented
8:48 DEY tests
11:25 DEY implemented
11:53 DEX tests
12:34 DEX implemented
13:00 DEC Zero Page tests
16:25 DEC Zero Page implemented
19:57 DEC Zero Page X tests
21:23 DEC Zero Page X implemented
22:22 DEC Absolute tests
23:37 DEC Absolute implemented
24:29 DEC Absolute X tests
25:13 DEC Absolute X implemented
28:40 INC Tests
29:30 INC implemented
30:48 A little 6502 program

Пікірлер: 5
@cigmorfil4101
@cigmorfil4101 3 жыл бұрын
3:23 Increasing/decreasing the index registers/memory just wrap without any Carry. Carry is intended for Arithmetic operations, including the unsigned multiply/divide by 2 (the shift instructions), where the C flag is used to transfer between the bytes of a multi-byte number. Increasing/decreasing an index register/memory location is not considered an arithmetic operation hence they do not affect the C flag. The N flag (bit 7 of the status register) is always set to match bit 7 of any result (calculated, eg INC, ADC, ROL, or loaded: LDA, etc). Similarly Z is always set depending upon a similar zero result. An example is the charget routine of the PET (and C64) which has been located in zero page. It increases the low byte of the next character of the pointer into the program and if this is not zero it bypasses increasing the high byte. This code takes 6 bytes so by replacing those 6 bytes with a call to a subroutine (which includes increasing the pointer) you can intercept the charget routine and interpret your own commands, and intercept standard commands and use your own version of them (possibly how your C64 assembler is working).
@AxeMurderer2222
@AxeMurderer2222 3 жыл бұрын
19:40 Most CPUs have some registers you are not implementing. MAR, MBR, & IR aka Memory Address Register, Memory Buffer Register, and Instruction Register. I think some of the confusion you are having with the clock counting has to do with moving stuff between the registers, the instruction decoding, and the MAR/MBR loading done behind the scenes, none of which are simulated by your code. When accessing memory the MAR is used to hold the memory address being accessed, and the MBR holds the data value that is read from or written to the memory bus. The IR is used to hold the instruction retrieved during the last fetch operation. The decoding operates there. You've simplified all that circuitry into a giant switch statement. All that addressing mode code you have going would be applied to values manipulated while in the MAR so that when it comes time to read or write, it is already in there ready to go out onto the bus with the correct values (based on the addressing mode selected in the instruction), since the MAR and MBR are connected to the memory and data busses. I suspect one of these registers (most likely the MBR) is where the data being operated on resides when you do something like a DEC. So the sequence is: read from mem, which loads the MAR from the instruction's opcode/operands and the MBR from the memory read access, then decrement the MBR (since the value is now already in there), then since the destination is already set in the MAR, and now the new value is already in the MBR, the only thing left is to tell the memory chip to write. No wasted clocks moving it into the accumulator to change it then back into the MBR again to write it. The MAR and MBR aren't needed during instructions that have no memory requirements. The MAR and MBR are both always set up with valid values before every memory access. So any garbage you put in them when they aren't needed will never interfere with memory operations. Therefore, it makes sense that they might be leveraged internally as general purpose registers in those situations where the currently executing instruction requires no memory accesses to occur, or after it has already finished with the memory.
@DavePoo
@DavePoo 3 жыл бұрын
Yeah. I think that's probably why it was a bad idea to try and do the clock counting the way i did. As i wasn't going to implement the microcode, so the clock counting sometimes doesn't make much sense without it, and the way some of the opcodes work.
@jorenheit
@jorenheit 3 жыл бұрын
34:25 You could templatize the LoadPrg function to deduce the array size for you: template Word LoadPrg(Byte (&program)[NumElements], ...) { /* not checked */ } Saves you from having to pass the number of elements :-)
@CostasB-jv1ko
@CostasB-jv1ko 3 жыл бұрын
my little program is running correctly!
Emulating a CPU in C++ #17 (6502) - BEQ Conditional Branch
32:41
A Introduction to Handles (in C++)
42:23
Dave Poo
Рет қаралды 10 М.
Этого От Него Никто Не Ожидал 😂
00:19
Глеб Рандалайнен
Рет қаралды 8 МЛН
【獨生子的日常】让小奶猫也体验一把鬼打墙#小奶喵 #铲屎官的乐趣
00:12
“獨生子的日常”YouTube官方頻道
Рет қаралды 83 МЛН
I Trapped Myself in a Box with Colored Smoke!
00:50
A4
Рет қаралды 19 МЛН
27c3: Reverse Engineering the MOS 6502 CPU (en)
51:57
Christiaan008
Рет қаралды 428 М.
I Asked GPT-4 To Refactor My Legacy Codebase
12:39
Nick Chapsas
Рет қаралды 347 М.
Basics - 6502 Assembly Crash Course 01
12:49
NesHacker
Рет қаралды 105 М.
Bitwise Operators and WHY we use them
8:41
Alex Hyett
Рет қаралды 54 М.
HOW IT'S MADE: CPU
9:07
How It's Made
Рет қаралды 381 М.
Bjarne Stroustrup: C++ | Lex Fridman Podcast #48
1:47:13
Lex Fridman
Рет қаралды 1 МЛН
Этого От Него Никто Не Ожидал 😂
00:19
Глеб Рандалайнен
Рет қаралды 8 МЛН