It is currently Sun Dec 10, 2017 5:25 pm

All times are UTC - 7 hours





Post new topic Reply to topic  [ 3 posts ] 
Author Message
PostPosted: Thu May 19, 2016 5:15 pm 
Offline

Joined: Thu May 19, 2016 3:59 pm
Posts: 2
Hello!
I'm currently working on a small NES emulator for learning purpose and trying to test my CPU.
When I run the nestest.nes it works fine until (from nestest-1.log)
Code:
// nesttest-1.log
CE42  68        PLA                             A:69 X:7E Y:01 P:27 SP:7E CYC:269 SL:258
CE43  68        PLA                             A:39 X:7E Y:01 P:25 SP:7F CYC:281 SL:258
CE44  BA        TSX                             A:CE X:7E Y:01 P:A5 SP:80 CYC:293 SL:258

The Problem i think is that somehow a PLA gets ignored since at CE44 the Accumulator should have the value 0xCE.
Code:
// My result
[CE42] - A: 69 X: 7E Y: 01 P: 27 SP: 7E
[CE43] - A: 69 X: 7E Y: 01 P: 25 SP: 7F
[CE44] - A: 39 X: 7E Y: 01 P: 25 SP: 80


I have no idea where this comes from since the tests works fine with PLA and the other instructions until that point.
Running the test again in nestopia also gets the correct results.
I wonder how this can happen when everything works fine before 0xCE42 (stack Operations etc).

Since I'm writing my emulator in ASM and handle writing to the memory with byte ptr ds: and word ptr ds: could it be that i have to switch something
or create one function for push8 and one for push16 instead having it in one?

Code:
cpu_push      proc   USES eax ecx          pValue:WORD, pSize:BYTE
   mov cx, 100h
   or cl, CPU_REG_SP
   invoke cpu_write, cx, pValue, pSize
   sub cl, pSize
   mov CPU_REG_SP, cl
   ret

cpu_push endp

cpu_pop         proc   USES ecx          pSize:BYTE
   mov cx, 100h
   or cl, CPU_REG_SP
   add cl, pSize
   mov CPU_REG_SP, cl
   invoke cpu_read, cx, pSize
   ret
   
cpu_pop endp


are my stack functions.
I hope someone can help me!
Regards,


Top
 Profile  
 
PostPosted: Thu May 19, 2016 8:51 pm 
Offline
User avatar

Joined: Sun Sep 19, 2004 9:28 pm
Posts: 3192
Location: Mountain View, CA, USA
Perhaps an easier method would be to print out the contents of the stack (or at least 16 bytes of it; say, 8 bytes before and 8 bytes after (as well as including) whatever S (what you call "SP") is) [u]after[u] every instruction executes.

Possibly the problem isn't with your pull operations, but with your push operations (pushing the wrong value on the stack, or possibly things are off-by-one).

Nestopia's register contents, I believe, are printed at the time the instruction is encountered (i.e. has yet to be executed).

In your case, I would expect to see $CE43 having A=$39, but it doesn't until an additional PLA is done. To me, that indicates possibly an off-by-one situation somewhere.

We have a page on the 6502 stack here: http://wiki.nesdev.com/w/index.php/Stack -- the main article, as well as "Pushing values" and "Pulling values" are relevant (the rest isn't entirely relevant to this specific discussion subject).

I think your issue may be deeper -- note that not only A is incorrect, but so is P. So you may have something bigger/more problematic going on outside of just your pull routine. Sadly, you're the author, you understand all the variable names and code, so... :-)

You can use something like http://skilldrick.github.io/easy6502/ to play around with identical code and examine things each step of the way. Alternately I would suggest stepping through things in FCEUX or Nintendulator, as both have quite good debuggers. Here's some code you can use that's more or less akin to the situation:

Code:
ldx #$80
txs
lda #$ce
pha
lda #$39
pha
lda #$69
pha
pla
pla


Top
 Profile  
 
PostPosted: Fri May 20, 2016 3:35 am 
Offline

Joined: Thu May 19, 2016 3:59 pm
Posts: 2
Hey,
Thanks for your fast answer !

Well the the value of P differs too because of the wrong load.

in PLA after popping a byte from the stack the byte gets testetd and the Zero and Sign flags are
getting set depending on the results.

I've did what you've said with the Stack printing and I think I have found a bug:
Code:
[JSR: C600  SP:FD] // Before
00 00 00 00 00 00 00 00 FF C5 00 00 00 00 00 00
[JSR: C7DB  SP:FB] //After
00 00 00 00 00 00 00 00 00 00 02 C6 00 00 00 00

Somehow my Stack functions are wrong (I've recoded it in a damn ugly way and it works now but i have to clean it up).

This is the write part fromt he RAM:
Code:
@ram:
   and cx, 7FFh
   mov esi, CPU_RAM
   cmp pSize, SWORD
   je @F
   mov byte ptr ds:[esi+ecx], al
   ret
@@:   mov word ptr ds:[esi+ecx], ax
   ret


and the read Part:
Code:
@ram:
   and cx, 7FFh
   mov esi, CPU_RAM
   mov ax, word ptr ds:[esi+ecx]
   cmp pSize, SWORD
   je @F
   xor ah, ah
@@:   ret


somehow if i use my old push/pop functions it places the value wrong into the stack ( I think it's a placement/logic mistake that my brain doesn't notice at the moment).
If I'm correct it works this way
for push 8Bits:
Code:
-> Write the 8Bits to SP|0x100
-> Increase SP by 1


for pull 8Bits:
Code:
-> Decrease SP by 1
-> Read 8Bits from SP|0x100


Anyways if i do it like this:
Code:
push16:
-------
push8 ah
push8 al

pull16:
------
pull8
push ax
pull8
pop bx
xchg ah, al
mov al, bl


works so far.

BUT I'm still wondering what the exact issue is and if it's not possible to stick to my old function with a slight change.
The reason for that may be stupid but if i would do it my old way I would save a whole call of
the function to pull something from the stack since I could pull 16Bits directly from the stack.

Regards,


Top
 Profile  
 
Display posts from previous:  Sort by  
Post new topic Reply to topic  [ 3 posts ] 

All times are UTC - 7 hours


Who is online

Users browsing this forum: Majestic-12 [Bot] and 12 guests


You cannot post new topics in this forum
You cannot reply to topics in this forum
You cannot edit your posts in this forum
You cannot delete your posts in this forum
You cannot post attachments in this forum

Search for:
Jump to:  
Powered by phpBB® Forum Software © phpBB Group