It is currently Sun Dec 17, 2017 10:55 am

All times are UTC - 7 hours





Post new topic Reply to topic  [ 3 posts ] 
Author Message
PostPosted: Fri Sep 07, 2012 5:03 pm 
Offline

Joined: Thu Jul 12, 2012 2:56 am
Posts: 6
Location: Sweden
I'm writing a gameboy emulator and is currently debugging it by running Blargg's GB rom tests.
In Blargg's GB rom tests for the CPU instructions, test number 2, the interrupts, this code is used to check EI:
Code:
     set_test 2,"EI"
     ei
     ld   bc,0
     push bc
     pop  bc
     inc  b
     wreg IF,$04
interrupt_addr:
     dec  b
     jp   nz,test_failed
     ld   hl,sp-2
     ldi  a,(hl)
     cp   <interrupt_addr
     jp   nz,test_failed
     ld   a,(hl)
     cp   >interrupt_addr
     jp   nz,test_failed
     lda  IF
     and  $04
     jp   nz,test_failed


Here the IME flag is turned on with help of the EI-instruction and an interrupt is expected to occur due to this line:
Code:
wreg IF,$04

because, that's a manual triggering of the timer interrupt. This happens, and the interrupt code runs:
Code:
.bank 0 slot 0
.org $50
     inc a
     ret

When the interrupt is triggered, the IME flag should be set to 0 according to the pandocs: http://nocash.emubase.de/pandocs.htm#interrupts. This IME is not enabled by the interrupt routine as RET is used instead of RETI (which would have re-enabled the IME flag upon returning from the interrupt routine). After this test, the next test, which tests the DI instruction is run:
Code:
     set_test 3,"DI"
     di
     ld   bc,0
     push bc
     pop  bc
     wreg IF,$04
     ld   hl,sp-2
     ldi  a,(hl)
     or   (hl)
     jp   nz,test_failed
     lda  IF
     and  $04
     jp   z,test_failed


The test seems to be designed for checking that the IME flag is disabled when executing the DI instruction. However, since I don't see anything enabling the IME flag after it was disabled in the previous test, nor does my emulator enable it, I would think this test has a bug in it and will always pass (unless, of course there are other bugs making it fail for some unrelated reason). Is that so or am I just missing something?

I actually think I am missing something is more likely because of the following in the next test:
Code:
set_test 4,"Timer doesn't work"
     wreg TAC,$05
     wreg TIMA,0
     wreg IF,0
     delay 500
     lda  IF
     delay 500
     and  $04
     jp   nz,test_failed
     delay 500
     lda  IF
     and  $04
     jp   z,test_failed
     pop  af

Here it seems to be relayed on that a timer interrupt is generated at the right timing. That is during the second "delay 500" macro, so that it is the timer interrupt bit in IF is disabled. However, I don't see where the IME flag is turned on in this code again nor does my emulator turn it on. What's even more strange is the I'm running the debugger of bgb (which passes all the tests) and all of a sudden has IF set to 0xE4 from 0xE0 (I think the E part is a bug, but it shouldn't matter for this, I guess). I can't check the IME flag in the debugger because it only shows a dot (.), I guess that's a bug too.

For convenience I post the entire test code:
Code:
; Tests DI, EI, and HALT (STOP proved untestable)

.include "shell.inc"

main:
     wreg IE,$04
     
     set_test 2,"EI"
     ei
     ld   bc,0
     push bc
     pop  bc
     inc  b
     wreg IF,$04
interrupt_addr:
     dec  b
     jp   nz,test_failed
     ld   hl,sp-2
     ldi  a,(hl)
     cp   <interrupt_addr
     jp   nz,test_failed
     ld   a,(hl)
     cp   >interrupt_addr
     jp   nz,test_failed
     lda  IF
     and  $04
     jp   nz,test_failed
     
     set_test 3,"DI"
     di
     ld   bc,0
     push bc
     pop  bc
     wreg IF,$04
     ld   hl,sp-2
     ldi  a,(hl)
     or   (hl)
     jp   nz,test_failed
     lda  IF
     and  $04
     jp   z,test_failed
     
     set_test 4,"Timer doesn't work"
     wreg TAC,$05
     wreg TIMA,0
     wreg IF,0
     delay 500
     lda  IF
     delay 500
     and  $04
     jp   nz,test_failed
     delay 500
     lda  IF
     and  $04
     jp   z,test_failed
     pop  af
     
     set_test 5,"HALT"
     wreg TAC,$05
     wreg TIMA,0
     wreg IF,0
     halt      ; timer interrupt will exit halt
     nop       ; avoids DMG bug
     lda  IF
     and  $04
     jp   z,test_failed
     
     jp   tests_passed

.bank 0 slot 0
.org $50
     inc a
     ret


Hope someone can explain what's going on here! :)


Top
 Profile  
 
PostPosted: Sat Sep 08, 2012 9:09 am 
Offline

Joined: Sat Aug 28, 2010 9:01 am
Posts: 204
It seems like you are right. I tried this in BGB and interrupts are disabled at the start of that test, as expected. (On second thought, though, this may not be to test the DI instructions as such, but to check interrupt can be disabled at all. The DI is just there so that individual test could be run independently and set up its own state.)
Shameless plug, btw, if you use IRC, feel free to join #gbdev on EFNet.


Top
 Profile  
 
PostPosted: Tue Sep 11, 2012 6:51 am 
Offline

Joined: Thu Jul 12, 2012 2:56 am
Posts: 6
Location: Sweden
The discussion was continued on the IRC. The conclusions that were made there were the following:

- As nitro2k01 stated in the his post above: The second test probably is just meant to test the behavior for when IME is cleared and the di instruction is just there to make sure the IME flag is cleared irregardless of what have happened earlier in the program.

- The third test works by reading the IF register rather than relying on an interrupt to occur. The IF register is written to irregardless of the IME flag when a timer interrupt occurs, so that it can work even if IME is cleared.

This led to my emulator passing the interrupt-test and by now it passes all of Blargg's cpu instruction tests. Hooray!!! :D

Many thanks to Nitro2k01 for helping me out with this on IRC! :D


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: No registered users and 2 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