Emulating a CPU in C++ #33 (6502) - More Debugging

  Рет қаралды 5,072

Dave Poo

Dave Poo

Күн бұрын

I this i continue with the 6502 test program from github written by Klaus2m5 and use it to try and find and fix bugs in the 6502 implementation. I also try to fix the issue we had left over from last time with BRK/RTI.
Links:
Source for this project: github.com/davepoo/6502Emulator
Google Test: github.com/google/googletest
6502 Information: www.obelisk.me.uk/6502/
6502 test program: github.com/Klaus2m5/6502_65C0...
Timestamps
0:00 Last time...
1:10 Problems with BRK
3:05 Fixing RTI
4:39 Fixing PLP Test
6:24 Fixing BRK return address
12:22 Rerun test program
13:30 Missing instruction 150
14:04 STX Zero Page Y
18:05 Rerun test program
18:59 More missing instructions
19:45 To be continued...

Пікірлер: 16
@sil1235
@sil1235 3 жыл бұрын
Great vid series! Btw changing 0 to 1 in #if 0 / #endif would be slightly faster way of uncommenting (as opposed to always removing it ;) )
@jkobain
@jkobain 5 ай бұрын
These videos don't have a fancy intro/outro, they span for hours, the guy doesn't play a video game or set up pranks. Yet, it is enjoyable to watch.
@slygamer01
@slygamer01 3 жыл бұрын
From the previous video, I'm still trying to not point at the screen to the bit that says "This is the only time and place where the B flag actually exists: not in the status register itself, but in bit 4 of the copy that is written to the stack." Setting Flags.B to true in the BRK instruction is not actually correct. It should only be set in the copy pushed to the stack.
@M4RC90
@M4RC90 3 жыл бұрын
It's not ignoring bits 5 and 4, they just don't physically exist in the CPU. Just like it says at the beginning of that section: "While there are only six flags in the processor status register within the CPU, when transferred to the stack, there are two additional bits. These do not represent a register that can hold a value but can be used to distinguish how the flags were pushed. Some 6502 references call this the "B flag", though it does not represent an actual CPU register."
@tmbarral664
@tmbarral664 3 жыл бұрын
we used sometimes BRK like the TRAP for 68K. So like a system call with a function number following the BRK. Nice but that is taken a lot of cycles so it wasn't that much used ;)
@cigmorfil4101
@cigmorfil4101 3 жыл бұрын
7:23 I would say it does increment the PC - the reason a JSR stores the last byte of the instruction and not the address of the next instruction is where the push PC onto stack occurs: 1 - load OP code, PC++ 2 - load ADL, PC++; decode JSR 3 - read stack; save ADL 4 - push PCH 5 - push PCL 6 - load ADH; PC=AD By doing this it only needs to temporarily store an 8 bit value (the LSB of the destination). For the BRK instruction: The first increment occurs with *EVERY* instruction when read in the first cycle of every instruction. The second cycle appears to increment the PC again; this is either by design or a feature. During an interrupt these two cycles hold the PC value as it was at the start of the interrupt.
@DavePoo
@DavePoo 3 жыл бұрын
Thanks, that does seem to make sense about how JSR works. How do you know so much about the 6502? Is this all documented somewhere or have you found this out from experience?
@cigmorfil4101
@cigmorfil4101 3 жыл бұрын
@@DavePoo a bit of both. I have a copy of "SY6500/MCS6500 microcomputer family programming manual" of August 1976 from Synertek (first edition (C) MOS Technology Inc 1975), but my first experience of 6502 programming was on a PET, even though I actually learnt 6502 from the Acorn Atom manual, followed by an ITT 2020 (an Apple ][ clone). I got to the stage where I could read (and write) directly in 6502 using hex (a result of only have memory access (for reading/writing) from the PET monitor in hex, and having to hand assemble code).
@cigmorfil4101
@cigmorfil4101 3 жыл бұрын
@@DavePoo Regarding the BRK command, it is one of 4 interrupts: IRQ, NMI, RESET, BRK They *all* do the same 7 clock cycles with minor changes to the first two cycles. During RESET the write is disabled (read held) during cycles 3-5 where the other interrupts write the current PC and P to the stack. Interestingly the address output during cycle 2 of a RESET is the address it output during cycle 1 plus 1 (as for BRK), but IRQ and NMI output the same PC in cycle 2 as cycle 1 which is the current PC. Wrt the B bit - I'm not sure if I read it in comments elsewhere in your videos' comments or elsewhere on the web but the P register only has 6 bits: the unused and B bits do not actually exist, which means that when the status register is pulled off the stack only the 6 bits of NVDIZC can be restored. If you look up the "undocumented" instructions (which are an effect of how the processor actually does things) you'll find 8F is described as storing the A register ANDed with the X register. What the 6502 is trying to do is store both the A and X registers at the same time;* the AND effect seems to comes from using TTL style logic gates which float high unless specifically pulled low - the bits are floating high (1) unless specifically pulled low (0), thus any 0 bit will "win" over a 1 bit (the AND effect). (A floating high unused P-bit would explain why it appears as a 1.) * technically 4 bits are used to select the register (for comparable op codes where the same "micro code" runs and the register is selected by the bits) - consider $8C - $8F: if bit 0 is set (regardless of the state of bit 1) the A is selected, if bit 1 is set (regardless of the state of bit 0) X is selected, if neither is set Y is selected; thus if both bits 0 and 1 are set then both A and X are selected. This is possibly due to cost saving in not fully decoding bits 0&1...the deep-internal workings regarding how each cycle is defined for an instruction is something I have only tickled on the surface, there is a web page explaining how the "undocumented" instructions occur which I skim-summarised here.
@mshine5
@mshine5 3 жыл бұрын
I think I know why the RTI instruction goes to address + 2. It is used for debugging so the brk instruction can be substitued for a two-byte instruction without having to rearrange a whole lot of code.
@DavePoo
@DavePoo 3 жыл бұрын
Possibly, it does seem a little odd that it does it. Whatever the reason, the 6502 designers wouldn't have had it do something for no reason. I suspected that the hardware that handles the break is the same hardware that does interrupts and they are just both rigged to work the same way which causes the weirdness.
@cigmorfil4101
@cigmorfil4101 3 жыл бұрын
@@DavePoo 2:10 On an interrupt the CPU forces a BRK instruction into the command pipeline, regardless of type (NMI or IRQ). The BRK instruction takes the same number of cycles as an external interrupt. The difference comes in the first 2 cycles. During an interrupt the first is used to finish off the instruction the processor was running; the second is used to force the BRK into the command pipeline. The I-flag is used to prevent even cycle 1 occurring if it is set and the interrupt was an IRQ. A BRK will be processed even if the I-flag is set. During an interrupt in those first 2 cycles the PC value is held. With a BRK instruction, the first cycle loads the BRK instruction from memory and increments PC (like a normal instruction). It appears that during cycle 2 the BRK instruction is interpreted with its first micro-code instruction to be set the B-flag and increase PC. From cycle 3 to 7 an interrupt and the BRK do the same micro-code: save PCL, PCH, P on stack (cycles 3-5), fetch address of routine (from vector at FFFE or FFFA) into PC (cycles 6-7) with the next cycle (cycle 8 since the interrupt started) starting the program at the new address. Due to a "feature", if a NMI interrupt happens at the same time as the BRK instruction the 6502 uses the NMI vector instead of the IRQ vector for the BRK instruction. When it comes to the RTI, when the processor status (P) is pulled off the stack (I think) the B-flag is forced to 0. (The I-flag wouldn't need to be forced as I think the statis is pushed before the I-flag is set, but I could be wrong.) When the CPU is reset it is executed as an interrupt except that during cycles 3-5 the write is disabled so that memory is not destroyed, but it does mean that the stack pointer is 3 bytes earlier (with wrap) than when the CPU was reset.
@64jcl
@64jcl 3 жыл бұрын
I see you spent a lot of time figuring out the BRK stuff. I personally would have just fired up the C64 Vice emulator and just try it out and see what happens there by inspecting CPU status, stack and whatnot as it is a fully working emulator where you can break out into a monitor and step through things. :)
@DavePoo
@DavePoo 3 жыл бұрын
I could have done that, but I didn't want to emulate the emulator. I think I would consider double verifying my findings with another emulator once I got it working.
@lukasz-mf5ri
@lukasz-mf5ri Жыл бұрын
On my emulator test porgram fails somehow with sta absolute or something... it loops in address in tstay4 loop :(( I can't fugre out why
@lukasz-mf5ri
@lukasz-mf5ri Жыл бұрын
2:32, B flag doesn't exist in CPU, it exists only on stack, thats why they say that they ignore it. You can't set it either so it will be always 0
you need to stop using print debugging (do THIS instead)
7:07
Low Level Learning
Рет қаралды 381 М.
Barriga de grávida aconchegante? 🤔💡
00:10
Polar em português
Рет қаралды 13 МЛН
The World's Fastest Cleaners
00:35
MrBeast
Рет қаралды 104 МЛН
Which one will take more 😉
00:27
Polar
Рет қаралды 60 МЛН
蜘蛛侠这操作也太坏了吧#蜘蛛侠#超人#超凡蜘蛛
00:47
超凡蜘蛛
Рет қаралды 41 МЛН
I Designed My Own 16-bit CPU
15:46
AstroSam
Рет қаралды 1,8 МЛН
27c3: Reverse Engineering the MOS 6502 CPU (en)
51:57
Christiaan008
Рет қаралды 428 М.
NES Emulator Part #2: The CPU (6502 Implementation)
1:07:12
javidx9
Рет қаралды 408 М.
Optimising Code - Computerphile
19:43
Computerphile
Рет қаралды 136 М.
Making a Chip-8 Emulator
9:18
VoxelRifts
Рет қаралды 10 М.
Designing a Card Slot Modular Z80 Computer
14:29
Joshua Coleman Makes
Рет қаралды 40 М.
WHY IS THE STACK SO FAST?
13:46
Core Dumped
Рет қаралды 121 М.
Barriga de grávida aconchegante? 🤔💡
00:10
Polar em português
Рет қаралды 13 МЛН