It is currently Sat Dec 16, 2017 3:45 pm

All times are UTC - 7 hours



Forum rules


Related:



Post new topic Reply to topic  [ 138 posts ]  Go to page 1, 2, 3, 4, 5 ... 10  Next
Author Message
PostPosted: Mon May 23, 2016 8:10 am 
Offline

Joined: Mon Nov 10, 2008 3:09 pm
Posts: 431
From the WDC W65C816S datasheet, page 42 (emphasis added):

Quote:
8.2.1 The Direct Addressing modes are often used to access memory registers and pointers.
The effective address generated by Direct; Direct,X and Direct,Y addressing modes will always be in the Native mode range 000000 to 00FFFF. When in the Emulation mode, the direct addressing range is 000000 to 0000FF, except for [Direct] and [Direct],Y addressing modes and the PEI instruction which will increment from 0000FE or 0000FF into the Stack area.
8.2.2 When in the Emulation mode and DH is not equal to zero, the direct addressing range is 00DH00 to 00DHFF, except for [Direct] and [Direct],Y addressing modes and the PEI instruction which will increment from 00DHFE or 00DHFF into the next higher page.


Here's what the 65816 core in higan v098 does for direct page address calculation (from higan/processor/r65816/memory.hpp):

Code:
alwaysinline auto readdp(uint32 addr) -> uint8 {
  if(regs.e && regs.d.l == 0x00) {
    return read((regs.d & 0xff00) + ((regs.d + (addr & 0xffff)) & 0xff));
  } else {
    return read((regs.d + (addr & 0xffff)) & 0xffff);
  }
}

// snip

alwaysinline auto writedp(uint32 addr, uint8 data) -> void {
  if(regs.e && regs.d.l == 0x00) {
    write((regs.d & 0xff00) + ((regs.d + (addr & 0xffff)) & 0xff), data);
  } else {
    write((regs.d + (addr & 0xffff)) & 0xffff, data);
  }
}


Assuming the datasheet is correct, the emulation flag and DP low byte test should not be done for pei and indirect long addressing modes. There should either be an "alwaysnative" argument to the functions, or a second pair of "readdpn" and "writedpn" functions that always do the native mode behaviour. The second is the prevailing style in the r65816 core, but the first is more DRY, and weren't you planning to update the code style in the older parts of higan anyway?

Of course there's a possibility that the datasheet is wrong (I noticed that it incorrectly claims that indexed indirect jmp fetches the vector from bank 0--it's actually from the PB) But the datasheet seems highly plausible to me--there's a definite pattern in the 65816 where emulation mode preserves 6502 behaviour only for instructions and addressing modes that actually exist on a 6502, while new 65816 instructions and modes always have "native mode" behaviour.

Also, the masking in those direct page functions is extremely redundant. The following much simpler and more readable formulas are exactly equivalent to what you have:

Code:
if(regs.e && regs.d.l == 0x00) {
  return read(regs.d + (addr & 0xff)); // we've just tested that (regs.d & 0xff00) == regs.d
} else {
  return read((regs.d + addr) & 0xffff); // we only need to mask with 0xffff once
}


Top
 Profile  
 
PostPosted: Mon May 23, 2016 9:01 am 
Online

Joined: Sun Sep 19, 2004 11:12 pm
Posts: 19352
Location: NE Indiana, USA (NTSC)
Can you whip up a Super NES ROM that exhibits the difference, so I can run it on my PowerPak?


Top
 Profile  
 
PostPosted: Mon May 23, 2016 9:06 am 
Offline
User avatar

Joined: Sun Sep 19, 2004 9:28 pm
Posts: 3192
Location: Mountain View, CA, USA
I'd second your theory on this (that the indirect long and indirect long indexed modes probably page wrap regardless of e=1). It'd be easy enough to test for -- I do have my Apple IIGS laying around. Easy enough to test using lda [$xx] or the like (I don't see the need to test [$xx],y or pei directly because the design aspect pertains to long indirect addressing as a whole).

Also, if you're ever curious about actual 65816 CPU behaviour, feel free to contact WDC directly. Bill Mensch (CPU inventor) actually answers support requests (I know, because he actually got back to me!), and I'm sure something he doesn't know off the top of his head he could review the schematics for. His direct Email address is bill.mensch at westerndesigncenter.com.

Footnote: I don't see how testing this on a SNES is practical (or rather, "quickly achievable" given that there's no easy to way to get details (registers, etc.) without writing a whole bunch of code and PPU stuffs. The Apple IIGS monitor + mini assembler make this pretty easy. Testing it on actual hardware is important here (emulators, ex. KEGS or ActiveGS, may get it wrong).


Top
 Profile  
 
PostPosted: Mon May 23, 2016 9:11 am 
Offline

Joined: Mon Nov 10, 2008 3:09 pm
Posts: 431
koitsu wrote:
I'd second your theory on this (that the indirect long and indirect long indexed modes probably page wrap regardless of e=1). It'd be easy enough to test for -- I do have my Apple IIGS laying around. Easy enough to test using lda [$xx] or the like (I don't see the need to test [$xx],y or pei directly because the design aspect pertains to long indirect addressing as a whole).

Also, if you're ever curious about actual 65816 CPU behaviour, feel free to contact WDC directly. Bill Mensch (CPU inventor) actually answers support requests (I know, because he actually got back to me!), and I'm sure something he doesn't know off the top of his head he could review the schematics for. His direct Email address is bill.mensch at westerndesigncenter.com.

Footnote: I don't see how testing this on a SNES is practical (or rather, "quickly achievable" given that there's no easy to way to get details (registers, etc.) without writing a whole bunch of code and PPU stuffs. The Apple IIGS monitor + mini assembler make this pretty easy. Testing it on actual hardware is important here (emulators, ex. KEGS or ActiveGS, may get it wrong).


I'd much appreciate it if you did test on your IIGS--fully agree that using a built-in monitor is much less work than assembling a SNES ROM!


Top
 Profile  
 
PostPosted: Mon May 23, 2016 9:59 am 
Online

Joined: Sun Sep 19, 2004 11:12 pm
Posts: 19352
Location: NE Indiana, USA (NTSC)
I think other CPU test ROMs work by ripping the "code and PPU stuffs" from another test ROM. This is certainly true of Blargg's NES tests, which appear to all use the same output framework.


Top
 Profile  
 
PostPosted: Mon May 23, 2016 10:11 am 
Offline
User avatar

Joined: Sun Sep 19, 2004 9:28 pm
Posts: 3192
Location: Mountain View, CA, USA
Prefer a second or tertiary set of eyes before pulling out hardware and having to set all that up. Working on the test case for 8.2.1 (8.2.2 may be more complicated given that $00/02xx on the Apple II is ROM, so I can't control what's in $00/02xx):

Code:
; Bank $00/0000-00ff = zero page (RAM)
; Bank $00/0100-01ff = stack (RAM)
; Bank $01/0000-ffff = 64KB RAM

; $00/0000 = bank byte (if $00ff->$0100 wrap doesn't happen) of pointer to $00/6502
; $00/00fe = low byte of long pointer to $01/6502
; $00/00ff = high byte of long pointer to $01/6502
; $00/0100 = bank byte of long pointer to $01/6502

; $00/6502 = $aa
; $01/6502 = $bb

; $00/fdda = Apple II ROM: prints 8-bit accumulator in hex

.org $8000
sei
clc
xce
rep #$30
lda #$0000
tcd
sep #$30

lda #$00
pha
plb

clc
xce
lda [$fe]   ; Expect $bb
jsr $fdda

sec
xce
lda [$fe]   ; Expect: $aa
jsr $fdda

brk $00

And in the monitor, preassign some values:
Code:
00/0000:00
00/00fe:02
00/00ff:65
00/0100:01
00/6502:aa
01/6502:bb

If this look correct: the results on ActiveGS (not hardware!) are BBBB. I'd expect BBAA, since in the 2nd situation, e=1, which should read from $00/6502 not $01/6502.


Top
 Profile  
 
PostPosted: Mon May 23, 2016 10:14 am 
Online

Joined: Sun Sep 19, 2004 11:12 pm
Posts: 19352
Location: NE Indiana, USA (NTSC)
koitsu wrote:
Working on the test case for 8.2.1 (8.2.2 may be more complicated given that $00/02xx on the Apple II is ROM, so I can't control what's in $00/02xx):

Since when? I thought ROM on a GS was $F00000 and above (with the language card area $FFD000-$FFFFFF optionally mirrored down to $00D000-$00FFFF), and $000200-$0002FF was Applesoft BASIC's input buffer (source).


Top
 Profile  
 
PostPosted: Mon May 23, 2016 10:20 am 
Offline
User avatar

Joined: Sun Sep 19, 2004 9:28 pm
Posts: 3192
Location: Mountain View, CA, USA
tepples wrote:
koitsu wrote:
Working on the test case for 8.2.1 (8.2.2 may be more complicated given that $00/02xx on the Apple II is ROM, so I can't control what's in $00/02xx):

Since when? I thought ROM on a GS was $F00000 and above (optionally mirrored down to $00D000-$00FFFF), and $000200-$0002FF was Applesoft BASIC's input buffer (source).

It acts as ROM in the sense that any changes you make to it in the monitor (ex. 00/0200: 01 02 03 04 05 06 07 08) are completely ignored (previous values remain in effect). Coding something that writes to $00/0200 also does nothing (silently ignored). I believe the sources (and trust me, I've already looked), but I can't fight what's there. Either way, we can determine what $00/0200 is (it'd be the bank byte for the indirect long), just that we can't change it.


Top
 Profile  
 
PostPosted: Mon May 23, 2016 10:20 am 
Offline

Joined: Mon Nov 10, 2008 3:09 pm
Posts: 431
koitsu wrote:
Prefer a second or tertiary set of eyes before pulling out hardware and having to set all that up. Working on the test case for 8.2.1 (8.2.2 may be more complicated given that $00/02xx on the Apple II is ROM, so I can't control what's in $00/02xx):

Code:
; Bank $00/0000-00ff = zero page (RAM)
; Bank $00/0100-01ff = stack (RAM)
; Bank $01/0000-ffff = 64KB RAM

; $00/0000 = bank byte (if $00ff->$0100 wrap doesn't happen) of pointer to $00/6502
; $00/00fe = low byte of long pointer to $01/6502
; $00/00ff = high byte of long pointer to $01/6502
; $00/0100 = bank byte of long pointer to $01/6502

; $00/6502 = $aa
; $01/6502 = $bb

; $00/fdda = Apple II ROM: prints 8-bit accumulator in hex

.org $8000
sei
clc
xce
rep #$30
lda #$0000
tcd
sep #$30

lda #$00
pha
plb

clc
xce
lda [$fe]   ; Expect $bb
jsr $fdda

sec
xce
lda [$fe]   ; Expect: $aa
jsr $fdda

brk $00

And in the monitor, preassign some values:
Code:
00/0000:00
00/00fe:02
00/00ff:65
00/0100:01
00/6502:aa
01/6502:bb

If this look correct: the results on ActiveGS (not hardware!) are BBBB. I'd expect BBAA, since in the 2nd situation, e=1, which should read from $00/6502 not $01/6502.


If the datasheet is correct (and higan is wrong) then hardware should print BBBB. The datasheet claims that lda [$fe] always has "native mode" wrapping behaviour regardless of the e flag.


Top
 Profile  
 
PostPosted: Mon May 23, 2016 10:25 am 
Offline
User avatar

Joined: Sun Sep 19, 2004 9:28 pm
Posts: 3192
Location: Mountain View, CA, USA
Thanks AWJ. I have to keep going back and trying to re-comprehend the datasheet phrasing. So yeah, great, BBBB is correct (while BBAA would be wrong). I'll go pull out the IIGS, hook it up, and see what the results there are. But at least ActiveGS gets it correct.


Top
 Profile  
 
PostPosted: Mon May 23, 2016 12:49 pm 
Offline
User avatar

Joined: Sun Sep 19, 2004 9:28 pm
Posts: 3192
Location: Mountain View, CA, USA
Testing this on actual hardware is going to a bit of a pain, simply because the native ROM routines apparently behave very badly (in 8.2.2's case, stp ends up getting executed -- awesome!) if you change D on them. So I'll need to re-work some of this code to be significantly more safe with ROM routines.

In the meantime, I've removed the jsr accumulator-print call (replaced with brk so I could drop to the debugger easier, but then realise this was pointless since I was already in it), and stepped through the actual code in GSBug to see what the indirect long lda ended up getting for 8.2.2. It got $BB in both cases (e=0 and e=1) (I only show the e=0 case but trust me, e=1 has the same thing; I even set A=$0000 before the lda [$fe]).


Attachments:
Capture.PNG
Capture.PNG [ 31.35 KiB | Viewed 2122 times ]
Capture2.PNG
Capture2.PNG [ 35.42 KiB | Viewed 2122 times ]
Top
 Profile  
 
PostPosted: Mon May 23, 2016 4:31 pm 
Offline

Joined: Mon Nov 10, 2008 3:09 pm
Posts: 431
koitsu wrote:
Testing this on actual hardware is going to a bit of a pain, simply because the native ROM routines apparently behave very badly (in 8.2.2's case, stp ends up getting executed -- awesome!) if you change D on them. So I'll need to re-work some of this code to be significantly more safe with ROM routines.


Can you stash the test results in RAM somewhere they aren't going to get clobbered, put the CPU back into a state that the ROM is happy with, and then call the print routine?


Top
 Profile  
 
PostPosted: Mon May 23, 2016 5:25 pm 
Offline

Joined: Sat Apr 25, 2015 1:47 pm
Posts: 337
Location: FL
https://dl.dropboxusercontent.com/u/431 ... getest.sfc

For anyone who cares, here's a quick and dirty SNES version of koitsu's test. As expected(?), it shows BBBB on hardware, but BBAA in bsnes-plus (not sure about current higan).


Top
 Profile  
 
PostPosted: Mon May 23, 2016 9:12 pm 
Offline
User avatar

Joined: Sun Sep 19, 2004 9:28 pm
Posts: 3192
Location: Mountain View, CA, USA
Revenant wrote:
https://dl.dropboxusercontent.com/u/43107309/dpagetest.sfc

For anyone who cares, here's a quick and dirty SNES version of koitsu's test. As expected(?), it shows BBBB on hardware, but BBAA in bsnes-plus (not sure about current higan).

Thank you for this!


Top
 Profile  
 
PostPosted: Tue May 24, 2016 12:02 am 
Offline

Joined: Mon Mar 27, 2006 5:23 pm
Posts: 1339
Okay, I'll fix it in the next WIP. Much appreciated for the bug report and for the help confirming it!

> Also, the masking in those direct page functions is extremely redundant.

Yeah, that code's been around since 2005 or so. I'm not a great programmer now, but I was a total hack back then. I finally just outright killed the balanced PPU core, which was some of the ugliest code I've ever written bar xkas. I've been doing some gradual code cleanups in the v098 WIPs, and as expected, it's caused some regressions that I've had to fix, so it's not very enjoyable doing many cleanups per release.

I have a huge list of important fixes (mostly UI related, but my GB/C core is falling apart at the moment), yet I haven't done anything at all in over two weeks now. I don't really have an excuse, I don't know what my deal is right now. But this one will be near the top of the list for its importance.

For what it's worth, there's likely a lot more emulation mode bugs. I don't know of a single official game in the entire SNES library that runs in emulation mode, so there's bound to be more issues lurking in there than just this. Doesn't mean the issues aren't critical. Single opcode tests to detect bsnes are a huge problem.

> I think other CPU test ROMs work by ripping the "code and PPU stuffs" from another test ROM.

On my eternal todo list is building a testing framework out of the 21fx module. Why bother with writing results on the screen when we can send them back to the PC and automate pass/fail regression tests? We won't be able to test mid-scanline PPU timing with such tests, but CPU/SMP/DSP behaviors (up to the echo buffer) should all be quite doable.


Top
 Profile  
 
Display posts from previous:  Sort by  
Post new topic Reply to topic  [ 138 posts ]  Go to page 1, 2, 3, 4, 5 ... 10  Next

All times are UTC - 7 hours


Who is online

Users browsing this forum: No registered users and 5 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