6502.org Forum  Projects  Code  Documents  Tools  Forum
It is currently Mon Apr 29, 2024 4:27 am

All times are UTC




Post new topic Reply to topic  [ 22 posts ]  Go to page 1, 2  Next
Author Message
 Post subject: 65816 nuances
PostPosted: Thu Mar 14, 2019 11:30 pm 
Offline

Joined: Sat Dec 13, 2003 3:37 pm
Posts: 1004
So, I'm getting in to the meatier part of my simulator which means I'm a maze of edge cases, all alike.

Anyway, first question.

Given:
Code:
    CLC
    XCE
    REP #$30
    LONGA
    LONGI
    LDA $02FFFF

So, will this load the 16b accumulator from $02:FFFF and $03:0000, rather than $02:FFFF and $02:0000?

I know that if you're index addressing, the calculation of the final address will cross banks, but I don't know about the about load. I assume it will, but I don't know. I don't think there's any limitation about loading 16b values needed to be aligned to an even address.

Also, if the load crosses a page, does that add an extra cycle? or only if the address calculation crosses a bank or page?


Top
 Profile  
Reply with quote  
 Post subject: Re: 65816 nuances
PostPosted: Thu Mar 14, 2019 11:51 pm 
Offline
User avatar

Joined: Sun Jun 30, 2013 10:26 pm
Posts: 1927
Location: Sacramento, CA, USA
Have you had a chance to study Bruce's work on or near the subject?

http://www.6502.org/tutorials/65c816opcodes.html

I haven't had a chance to see if the exact answer to your question is there, but I like the odds.

_________________
Got a kilobyte lying fallow in your 65xx's memory map? Sprinkle some VTL02C on it and see how it grows on you!

Mike B. (about me) (learning how to github)


Top
 Profile  
Reply with quote  
 Post subject: Re: 65816 nuances
PostPosted: Fri Mar 15, 2019 9:06 pm 
Offline

Joined: Sat Dec 13, 2003 3:37 pm
Posts: 1004
barrym95838 wrote:
Have you had a chance to study Bruce's work on or near the subject?

http://www.6502.org/tutorials/65c816opcodes.html

That work cites that the 16 bit load should cross banks.

But I couldn't find any reference within the WDC book (which seems to be what WDC considers authoritative) regarding this. All discussion about bank wrapping is pretty much limited to calculating effective addresses, not necessarily loading 16 bit values. It's also noted that the PC can not incrementally cross banks (Thus a multi-byte instruction at bb:FFFF will wrap within the bank to find the rest of the operands).

Also, there's no note of whether a 16 bit load that crosses a bank counts another cycle or not. Intuitively I'd think it would, but, frankly, again, intuitively, it's surprising to me that the 16 bit load does NOT wrap, given the nature of the processor.

Mind, this is an extraordinary case for sure. I don't know if anyone handy has a board with more than 64K of contiguous RAM that could test it. (I'm sure you could test it without RAM with suitable diagnostic equipment).

So. In the end, I have no reason to doubt Bruce's work, I simply can't correlate it anywhere else. If it's in the WDC book, I'd love a reference (it's a big book, so I could have easily missed it).

I've been referring to both works during my development, both have values the other lacks.


Top
 Profile  
Reply with quote  
 Post subject: Re: 65816 nuances
PostPosted: Fri Mar 15, 2019 10:15 pm 
Offline
User avatar

Joined: Thu Dec 11, 2008 1:28 pm
Posts: 10793
Location: England
This is why Bruce went to the trouble of writing his document, I think: there is no decent authoritative reference.
Edit: Bruce didn't only write the document, of course, he did loads of testing so he could write it.


Top
 Profile  
Reply with quote  
 Post subject: Re: 65816 nuances
PostPosted: Fri Mar 15, 2019 10:27 pm 
Offline

Joined: Sat Dec 13, 2003 3:37 pm
Posts: 1004
Ok, well, great. I can just move on then.

As I said, this is a really remote edge case anyway. But when you're sitting there in the bowels of a LDA implementation, with the caret blinking.."Uh..what now?".

Those things tend to derail me sometimes. If I had more momentum at the time, I would have pushed on - but I had just started working on it, bumped in to that, and it took all the wind out of my sails. I should be able to restart and get a bunch of stuff done now.


Top
 Profile  
Reply with quote  
 Post subject: Re: 65816 nuances
PostPosted: Wed Mar 20, 2019 5:29 am 
Offline

Joined: Sat Dec 13, 2003 3:37 pm
Posts: 1004
Next up, Page Wrapping.

In Bruce's Opcode document we have this:
Quote:
Page boundary wrapping only occurs in emulation mode, and only for "old" instructions and addressing modes, i.e. instructions and addressing modes that are available on the 65C02. Page boundary wrapping only occurs in the following situations:

A. When the DL register is $00 (and in emulation mode -- both conditions must be met), the direct page wraps at a page boundary

So, if I read this right, page wrapping only happens in emulation mode -- at all. In native mode, there is no page wrapping whatsoever (just bank wrapping), correct?

The example (A), in isolation, is confusing in that it suggests that if the DL register is $00 (ANY time it's zero, and regardless of what's in DH), then page wrapping can occur. I color this as just unclear rather than contradictory.

Are there any "new" instructions that operate in emulation mode that are thus NOT subject to page wrapping?

However, in the WDC book, we have, on Page 48, under "The Direct Page Register":
Quote:
If the direct page register is set to zero, the direct page memory is the zero page, and direct page addressing is operationally identical to zero page addressing.

This doesn't make any discrimination between emulation and native.

So, just to summarize my understanding.

In reality, Page Wrapping only happens in 2 places, both in emulation mode. On Zero Page and on the stack area (0100-01FF), like the regular 6502.

Or are there edge cases that I need to worry about?


Top
 Profile  
Reply with quote  
 Post subject: Re: 65816 nuances
PostPosted: Wed Mar 20, 2019 7:53 am 
Offline
User avatar

Joined: Thu Dec 11, 2008 1:28 pm
Posts: 10793
Location: England
Where WDC are ambiguous or unclear, and Bruce is unambiguous, then Bruce will be right - because he's tested all his examples. (There still might be places where Bruce doesn't give us the answers.)

WDC don't know how to write documentation, and in a sense they don't know what their chip does. It's very likely the case that their C tooling works perfectly well because everything which their C exercises and needs works exactly as their C needs it to.

If there's any remaining lack of clarity once Bruce's doc has been taken into account, then experiment is needed.


Top
 Profile  
Reply with quote  
 Post subject: Re: 65816 nuances
PostPosted: Wed Mar 20, 2019 8:14 am 
Offline
User avatar

Joined: Fri Aug 30, 2002 1:09 am
Posts: 8428
Location: Southern California
BigEd wrote:
If there's any remaining lack of clarity once Bruce's doc has been taken into account, then experiment is needed.

I've made a test fixture to exercise the '816 a half cycle at a time to see how it behaves, and allows making choices as to the next course of action based on what it did in each half cycle. It will take time to get it back out and set up, and I can't do it right away; but if you want to list some exact things you would like me to check, and no one beats me to it, I'll try to do it for you. I'm sure many of us would like to know.

_________________
http://WilsonMinesCo.com/ lots of 6502 resources
The "second front page" is http://wilsonminesco.com/links.html .
What's an additional VIA among friends, anyhow?


Top
 Profile  
Reply with quote  
 Post subject: Re: 65816 nuances
PostPosted: Wed Mar 20, 2019 8:42 am 
Offline
User avatar

Joined: Thu Dec 11, 2008 1:28 pm
Posts: 10793
Location: England
That's a great setup!


Top
 Profile  
Reply with quote  
 Post subject: Re: 65816 nuances
PostPosted: Wed Mar 20, 2019 4:44 pm 
Offline

Joined: Sat Dec 13, 2003 3:37 pm
Posts: 1004
GARTHWILSON wrote:
BigEd wrote:
If there's any remaining lack of clarity once Bruce's doc has been taken into account, then experiment is needed.

I've made a test fixture to exercise the '816 a half cycle at a time to see how it behaves, and allows making choices as to the next course of action based on what it did in each half cycle. It will take time to get it back out and set up, and I can't do it right away; but if you want to list some exact things you would like me to check, and no one beats me to it, I'll try to do it for you. I'm sure many of us would like to know.


That's sounds pretty neat.

I don't have any burning needs, I'm mostly just trying to get some gut check that I'm interpreting things properly. I guess the consensus is that the WDC book simply isn't detailed enough to rely upon at the intimate details, and better to cede to Bruce's document.

When I was doing my 6502 simulator, I was relying on a web based 6502 to vet my assumptions. I could test code in it easily (I think it had an assembler and/or you could just type in simply hex code). It didn't help that I found bugs in their implementation as well. Eventually I was able to run the test suite and get it to pass.

But I don't know of a readily accessible an '816 simulator that's really easy to dabble with.

I would be quite interested to know the cycle counts on 16 bit loads that cross bank boundaries, see if the bank bump eats a cycle or two (it's not really important to me as I don't even keep track of cycles now -- but I'd like to).

Also curious what the chip does when it encounters '816 instructions in emulation mode. Like JMP LONG, the Move instructions, etc. Does it do anything? treat them as NOPs? Partially work? "Undefined"? "Don't do that"?

But for "normal code", that's not an issue. It's reasonable to assume that if you're traipsing through '816 code in emulation mode, your code is "crashing" anyway, so it doesn't matter what it actually does. So, more just trivia knowledge than anything. In the end if the straight forward code I write on my simulator works on the raw chip, I'm happy.

Writing the Addressing code, keeping the bank registers, the page/bank wrapping, the emulation modes all straight -- it warps my Pooh brain. It would probably be easier if I was starting from scratch vs trying to uplift my 6502 simulator. I'm already a bull in a china shop as it is, but, yea, all of the addressing code is getting redone and I have to be careful to not uplift bad 6502 based code, as it makes assumptions that are just not valid anymore.

I already rewrote my Direct stuff twice. Part of the problem was that I call the Direct register the Direct Page register -- and it's not. It has nothing to do with pages. It's a conflation of the idea of Zero Page and Direct, and they're not related. So early on I was taking the Direct register and multiplying it by 256 to get the right "page", then adding the offset.

Nope! Doesn't work like that. There's no alignments whatsoever with the Direct register, rather it's simply bound to bank 0, and wraps at the bank boundary. It doesn't help that Bruce's doc uses the term Direct page as well. I think treating the Direct register as a "big" Zero Page isn't the right way to approach it, and using the DP idiomatically as a frame pointer makes more sense (set D to SP at routine entry, every routine has their own "zero page"). I dunno. It'll all come out in the wash.

So, anyway, walking on eggs writing the addressing code.


Top
 Profile  
Reply with quote  
 Post subject: Re: 65816 nuances
PostPosted: Wed Mar 20, 2019 5:55 pm 
Offline
User avatar

Joined: Thu Dec 11, 2008 1:28 pm
Posts: 10793
Location: England
If you have an appetite for reading C++, the MAME sources might be useful to you:
https://github.com/mamedev/mame/tree/ma ... cpu/g65816

I'm not sure if - or how - they get the cycle counts right, but it's usually important in game emulation to get cycle counts right.

Sam Falvo's lib65816 and my small wrapper run65816 might be helpful. Both mentioned on the Emulators page
http://www.6502.org/tools/emu/
which might give you other ideas too.

If you have an appetite for the JavaScript console in your browser, a 65816 or snes emulator might be a good tool. I'm not sure how mature this one is:
https://github.com/pskupinski/65816.js


Top
 Profile  
Reply with quote  
 Post subject: Re: 65816 nuances
PostPosted: Wed Mar 20, 2019 9:11 pm 
Offline

Joined: Mon May 21, 2018 8:09 pm
Posts: 1462
According to WDC, '816 instructions still work in emulation mode, including the 24-bit addressing and the Direct Page Register. But the high half of the stack pointer is forced to $01, the bank byte of the PC is not saved on interrupts nor restored by RTI, and the index and accumulator registers are forced to 8-bit mode (the relevant mode bits are "hidden"). It's basically the minimum hobbling they could do to ensure backwards compatibility with 65sc02 software.


Top
 Profile  
Reply with quote  
 Post subject: Re: 65816 nuances
PostPosted: Wed Mar 20, 2019 10:23 pm 
Offline

Joined: Sat Dec 13, 2003 3:37 pm
Posts: 1004
Yea, that's actually what I expect. Why swap out a bunch of functionality. Emulation mode is really (apparently) just locking down the Direct register and the Stack behavior.


Top
 Profile  
Reply with quote  
 Post subject: Re: 65816 nuances
PostPosted: Wed Mar 20, 2019 10:38 pm 
Offline
User avatar

Joined: Fri Dec 11, 2009 3:50 pm
Posts: 3349
Location: Ontario, Canada
whartung wrote:
Emulation mode is really (apparently) just locking down the Direct register and the Stack behavior.
Right -- and also adding various page wrap-arounds and dead cycles etc (to match 6502 behavior).

_________________
In 1988 my 65C02 got six new registers and 44 new full-speed instructions!
https://laughtonelectronics.com/Arcana/ ... mmary.html


Top
 Profile  
Reply with quote  
 Post subject: Re: 65816 nuances
PostPosted: Fri Apr 19, 2019 4:03 am 
Offline

Joined: Sat Dec 13, 2003 3:37 pm
Posts: 1004
So, moving along on the simulator, I ran in to the problem of the B register.

Right now, A is simply an integer variable, acc, and I just use it blindly:
Code:
    public void ORA(Address addr) {
        int value = fetchAccumulator(addr);
        acc = acc | value;
        setFlagsNZAcc(acc);
    }

Being as this is an uplift of a 6502 simulator, where the code was essentially identical to this, this idiom of using the accumulator is done everywhere. (It should be noted the fetchAccumulator is more "fetch with regards to the Accumulator mode bit" than working actually on the accumulator.)

Then, I bumped in to the B register. Oh no. I thought about going through, and replacing code like this to something like:
Code:
    public void ORA(Address addr) {
        int value = fetchAccumulator(addr);
        int acc = getAcc() | value;
        setFlagsNZAcc(acc);
        setAcc(acc);
    }

Where get/secAcc handles the details about the status of the B register. I'd have to do this just everywhere.

But then it occurred to me, I only care about B really in four places: XCE, XBA, and REP/SEP of the accumulator bit. When these states change, I synchronize my internal A (acc) and B variables depending on the state of the processor. Other than that, all of my acc routines remain untouched and I mostly just leave B alone.

For example, when REP #$20 happens (accumulator switched to 16b), I'll combine B and A in to A. When it switches back, I'll split A in to a B and A component, etc.

Any corner cases I might be missing?


Top
 Profile  
Reply with quote  
Display posts from previous:  Sort by  
Post new topic Reply to topic  [ 22 posts ]  Go to page 1, 2  Next

All times are UTC


Who is online

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