65816 Native Mode Programming

Programming the 6502 microprocessor and its relatives in assembly and other languages.
Post Reply
User avatar
8BIT
Posts: 1787
Joined: 30 Aug 2002
Location: Sacramento, CA
Contact:

65816 Native Mode Programming

Post by 8BIT »

I have started my journey into 65816 native mode programming. Doing things to work outside of the first 64K requires a lot of re-thinking. The 65816 also allows for greater flexibility.

Having a repository of useful code snipets would be useful. I'm probably trying to create code that many have already done. Does anyone have a good source of 65816 code snipets?

Also, Mike, could we add a place on 6502.org for these to be stored?

I am working on font generation using look-up tables and block move routines. I would be happy to share these once they are optimized and cleaned up.

Any thoughts or suggestions?

Daryl
kc5tja
Posts: 1706
Joined: 04 Jan 2003

Post by kc5tja »

There is also the 6502.org wiki that someone else had started. The nice thing about the wiki is you won't have to depend on Mike to put up a cookbook. See viewtopic.php?t=1224&highlight=wiki
kc5tja
Posts: 1706
Joined: 04 Jan 2003

Post by kc5tja »

That being said, yes, native mode is essentially a whole new CPU in terms of what now becomes possible. The largest intellectual barriers, I find, comes from the following:

1) ROM is expected to be at $00xxxx-$00FFFF, which seems silly. It would have made things MUCH easier had WDC moved the ROM to $FFxxxx-$FFFFFF, especially from an address decoding point of view! The Apple IIgs designers apparently felt so strongly about this that they engineered their chipset specifically to work around this issue. When _VP is asserted, the ROM (which normally sits in banks $FF and $E1) vectors are banked into bank zero. These vectors point into I/O space (which for Apple II compatibility, sits in bank zero anyway at $00C0xx), which then have hard-wired registers containing long-jumps into bank $E1.

In my Kestrel-2 design, I'm leaving the ROM in bank zero (RAM from $000000-$007FFF, ROM at $008000-$00FFFF, RAM again from $010000-$FEFFFF, and I/O from $FF0000-$FFFFFF), but am planning on an I/O control bit that will disable ROM and reveal the RAM beneath it (e.g., a Commodore-like "layering" approach).

2) Stack and direct page are hardwired to use bank zero.

3) Indirect jumps are also hardwired to be bank zero, BUT not indirect-indexed. E.g., JMP ($ABCD) will always fetch its vector from $00ABCD, while JMP ($ABCD,X) will use the current program bank. The latter is more powerful anyway, but, it's a gotcha you gotta be aware of.
User avatar
8BIT
Posts: 1787
Joined: 30 Aug 2002
Location: Sacramento, CA
Contact:

Post by 8BIT »

kc5tja wrote:
There is also the 6502.org wiki that someone else had started. The nice thing about the wiki is you won't have to depend on Mike to put up a cookbook. See viewtopic.php?t=1224&highlight=wiki
This looks like a likely place. I belive dclxvi created that site.

dclxvi,

Can you add a 65816 Native Mode software section to your wiki? It would be better to keep it seperate from the 6502 code as the examples would not be cross compatible in most cases.

Daryl
kc5tja
Posts: 1706
Joined: 04 Jan 2003

Post by kc5tja »

Actually, if you have a membership on the wiki, you can edit it yourself. Here is the current source:

Code: Select all

++ Software Categories

* [[[software-math|Math]]]

++ Miscellaneous Software Articles

* [[[software-incdec|INC and DEC techniques]]]
* [[[software-delay|Delay routines]]]
Just change that to:

Code: Select all

++ Software Categories

* [[[software-math|Math]]]

++ Software by Processor

* [[[software-6502|6502 Software]]]
* [[[software-65816|65816 Software]]]

++ Miscellaneous Software Articles

* [[[software-incdec|INC and DEC techniques]]]
* [[[software-delay|Delay routines]]]
or something along those lines. The part before the pipe is the webpage name on the wiki, and the part after the pipe is what we humans see on the website. If the two are the same, you can forego the pipe notation and just use [[[a-webpage-name]]] like that.
User avatar
dclxvi
Posts: 362
Joined: 11 Mar 2004

Post by dclxvi »

kc5tja wrote:
There is also the 6502.org wiki that someone else had started.
I was gonna hype the wiki, but you beat me to it! :)
8BIT wrote:
Does anyone have a good source of 65816 code snipets?

(snip)

I am working on font generation using look-up tables and block move routines.
I've got a few 65816 routines/techniques that I could add to the wiki, including two memory move routines. One is an extension of my 6502 memory move routines in the repostory that uses [zp],Y addressing, moves 2 bytes at time, and can handle lengths up to 16 meg. The other is faster, as it self modifies MVN and MVP instructions, and can also handle lengths up to 16 meg (MVN and MVP by themselves cannot span banks). (Actually lengths of >64k should generally be minimized since they are so time-consuming, but block spanning is useful.) I'll have to double check them, because I don't remember how extensively, or even if, I've tested them.

Other routines/techniques are:

1. m & x flag independence
2. Relative JSR and data
3. Parameter passing via the stack (it's not the only to do it, but it's available)
8BIT wrote:
Can you add a 65816 Native Mode software section to your wiki? It would be better to keep it seperate from the 6502 code as the examples would not be cross compatible in most cases.
I agree that this is a reasonable category. I've started one called "65816 specific code" and added an m & x flag independence article as a starting point.

Most 6502 code should be applicable to the 65816, so a "6502 specific" category is probably not necessary.
kc5tja wrote:
ROM is expected to be at $00xxxx-$00FFFF, which seems silly.
Yes it does, but this is a ramification of the fact that RESET puts the 65816 in emulation mode, rather than native mode.
kc5tja wrote:
When _VP is asserted, the ROM (which normally sits in banks $FF and $E1) vectors are banked into bank zero. These vectors point into I/O space (which for Apple II compatibility, sits in bank zero anyway at $00C0xx), which then have hard-wired registers containing long-jumps into bank $E1.
Banks $FE and $FF are ROM. Bank $E1 is RAM (and I/O). At power up (RESET), bank $E1 is initialized with default values for various vectors (interrupt and otherwise).
kc5tja wrote:
Indirect jumps are also hardwired to be bank zero, BUT not indirect-indexed. E.g., JMP ($ABCD) will always fetch its vector from $00ABCD, while JMP ($ABCD,X) will use the current program bank.
Yes. JMP/JML [abs] is also uses bank 0, and JSR (abs,X) uses the program bank.
kc5tja wrote:
The part before the pipe is the webpage name on the wiki, and the part after the pipe is what we humans see on the website.
It's able to figure out that [[[A Webpage Name]]] means the page a-webpage-name, but I like to explicitly state both the page name and what is displayed for clarity's sake.
fachat
Posts: 1124
Joined: 05 Jul 2005
Location: near Heidelberg, Germany
Contact:

Post by fachat »

dclxvi wrote:
kc5tja wrote:
ROM is expected to be at $00xxxx-$00FFFF, which seems silly.
Yes it does, but this is a ramification of the fact that RESET puts the 65816 in emulation mode, rather than native mode.
Yes, but if in emulation mode the upper address byte is ignored, it would not matter which bank to use in emulation mode. Considering the importance of bank $00, I would have used bank $ff in emulation mode. But that is all theoretical.

In my (not yet published) 65816 design, I of course have to use bank $00 as boot area, but will remap that after initialization so I can have bank $00 with 64k RAM.

André
User avatar
8BIT
Posts: 1787
Joined: 30 Aug 2002
Location: Sacramento, CA
Contact:

Post by 8BIT »

Great!

I have a block fill routine I use to clear the screen that uses MVN and a block move routine I use for scrolling the screen that also uses MVN. These move almost an entire 64k ram bank. I'll get the comments neatened up an add them to the wiki.

thanks!

Daryl
kc5tja
Posts: 1706
Joined: 04 Jan 2003

Post by kc5tja »

dclxvi wrote:
3. Parameter passing via the stack (it's not the only to do it, but it's available)
I just wrote a book on this topic. It is live on the Wiki now.
Quote:
Yes it does, but this is a ramification of the fact that RESET puts the 65816 in emulation mode, rather than native mode.
Had they used bank $FF for emulation mode, it would have made much, much more sense. Actually, that gives me a great idea -- use the CPU's E pin to 8 XOR gates covering A23-A16. That would work great. That forces bank 0 to be bank $FF when in emulation mode. That requires the ROM setup an image of the vectors in low RAM prior to engaging native mode, but it should work.
Quote:
It's able to figure out that [[[A Webpage Name]]] means the page a-webpage-name, but I like to explicitly state both the page name and what is displayed for clarity's sake.
I don't because that requires me to constantly look up page names. This brings me back to good wiki style -- a page name should match its file name, unless circumstances require otherwise.
User avatar
dclxvi
Posts: 362
Joined: 11 Mar 2004

Post by dclxvi »

kc5tja wrote:
I just wrote a book on this topic. It is live on the Wiki now.
Wow, you really went to town on that one! Good work! All I had in mind was the just basics of getting at parameters on the stack in subroutines with ,S and (,S),Y addressing, and the basic benefits of the TSC-TCD techinique. You've covered at least 10 times as much material I would have.

Incidentally, I've added the memory move, and the relative JSR/data/etc., so Daryl, there will be a pop quiz on Monday. Please bring a #2 pencil. :)
kc5tja wrote:
Actually, that gives me a great idea -- use the CPU's E pin to 8 XOR gates covering A23-A16. That would work great. That forces bank 0 to be bank $FF when in emulation mode. That requires the ROM setup an image of the vectors in low RAM prior to engaging native mode, but it should work.
If the only thing that you're doing in emulation mode is a RESET ISR that switches to native mode right away and you don't use the stack or (write to the) zero page while in emulation mode, then yeah, that should work. Systems that want/need a usable emulation mode would need some RAM in bank $FF for the emulation zero page and stack.

Anyway, we could probably fill a thread just on the 65816 vectors. :)
kc5tja wrote:
I don't because that requires me to constantly look up page names. This brings me back to good wiki style -- a page name should match its file name, unless circumstances require otherwise.
That's true. However, in theory, a wiki is going to be written once, edited and expanded a few times, and (hopefully) read many times. Links to other wiki pages probably won't be the majority of the content. Given that wikis generally don't have completely unrestricted file names, to me it is worth looking up the file name once (per link, albeit) and having a separate displayed name when it makes it more legible for the reader. Yes, that makes it more work for the writer/editor. To me, the major benefits of wiki are that they enable collaboration and they make it easier to generate articles than something like raw HTML (even if its not as easy as possible). It's not perfect, but hopefully it's not so off-putting that it would discourage anyone from contributing. Again, I think it's worth the extra effort for the reader's benefit. Anyway, whether any of this is a good excuse for separate display and file names is another matter. :)

In practice... I started out by organizing the wiki as something of hierarchical table of contents, and for the most part it's the (sub)table of contents pages that contain links to other pages, and not the articles (including your book). The only place I can recall linking one article to another is the cube root article and that's because I didn't feel like explaining the algorithm :). Certainly it's debatable whether this is the best way to organize the wiki, though.

Again, one of the reasons I set up a wiki was to get opinions and inspire discussion. The nice thing is we can try different approaches to see the pros and cons. There's room for a variety of styles.

All IMO.
User avatar
8BIT
Posts: 1787
Joined: 30 Aug 2002
Location: Sacramento, CA
Contact:

Post by 8BIT »

dclxvi wrote:
Incidentally, I've added the memory move, and the relative JSR/data/etc., so Daryl, there will be a pop quiz on Monday. Please bring a #2 pencil. :)
All I have is this #2 keyboard :wink:

I looked over your relative JSR/data/etc code. Interesting ideas if you want to easily use relocatable code.

Thanks for helping to get this idea rolling!!!!

Daryl
User avatar
dclxvi
Posts: 362
Joined: 11 Mar 2004

Post by dclxvi »

kc5tja wrote:
I just wrote a book on this topic. It is live on the Wiki now.
I couldn't help myself. In the "Collect Your Garbage" section, I corrected the PLA/PLX/PLY cycle count (it takes 5 cycles with 16-bit registers; they take 4 cycles with 8-bit registers; it's PHA/PHX/PHY that take 4 cycles with 16-bit registers), meaning TSC-SEC-SBC-TCS is faster than 2 or more (rather than 3 or more) pulls. Also I added another technique for discarding input parameters (in the same section).

I added stuff to Daryl's memory fill article too. I know, I'm out of control! :)
Post Reply