6502.org Forum  Projects  Code  Documents  Tools  Forum
It is currently Tue Nov 12, 2024 8:57 am

All times are UTC




Post new topic Reply to topic  [ 8 posts ] 
Author Message
PostPosted: Tue Oct 30, 2012 6:53 pm 
Offline
User avatar

Joined: Mon Dec 08, 2008 6:32 pm
Posts: 143
Location: Brighton, England
How do you guys handle the problem that the 65816 registers could be in 8-bit or 16-bit mode when an interrupt occurs?

Obviously, in an interrupt routine, you would need to stack the registers, then set the register sizes to suit the interrupt routine at the start of the routine and at the end of the routine restore them to their previous sizes and then pop them off the stack.

Am I right in thinking that popping the status register restores the register sizes? So if I push the status register after pushing all the other registers, when I restore the registers popping the status register first will re-set the sizes of the other registers so they can then be popped off the stack?

Is there a better way than this? I.E. something that doesn't end up with the status register pushed twice?

_________________
Shift to the left,
Shift to the right,
Mask in, Mask Out,
BYTE! BYTE! BYTE!


Top
 Profile  
Reply with quote  
PostPosted: Tue Oct 30, 2012 7:53 pm 
Online
User avatar

Joined: Fri Aug 30, 2002 1:09 am
Posts: 8539
Location: Southern California
Looking back at my multiple prioritized interrupt system on my '816 Forth that I did many years ago (and hence have forgotten), I see I just set the accumulator to 16 bits and pushed it, restored it at the end, and did RTI. That way you're safe whether you started in 8- or 16-bit, either way. If the individual ISR in the list that claimed responsibility for the interrupt and serviced it needed one or both index registers too, it could do the same thing. You can always save and restore in 16-bit. If the RTI at the end sets one or both sets back to 8-bit, it will be correct, and all you've lost is the few extra cycles to needlessly push and pull the high byte. No time is taken to test whether they were in 8- or 16-bit mode at the time of the interrupt sequence.

My sytem was intended for no emulation-mode operation at all after the initial reset routine. I go into native mode and leave it there permanently. Also, A is rarely taken out of 16-bit mode and the index registers are rarely taken out of 8-bit mode.

_________________
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  
PostPosted: Tue Oct 30, 2012 9:09 pm 
Offline
User avatar

Joined: Thu May 28, 2009 9:46 pm
Posts: 8482
Location: Midwestern USA
See here for some explanatory info.

_________________
x86?  We ain't got no x86.  We don't NEED no stinking x86!


Top
 Profile  
Reply with quote  
PostPosted: Tue Oct 30, 2012 9:20 pm 
Offline

Joined: Mon Mar 02, 2009 7:27 pm
Posts: 3258
Location: NC, USA
BigDumbDinosaur wrote:
See here for some explanatory info.

Wouldn't you do a PHP as well as pushing, the accumulator, X and Y registers?

_________________
65Org16:https://github.com/ElEctric-EyE/verilog-6502


Top
 Profile  
Reply with quote  
PostPosted: Tue Oct 30, 2012 9:48 pm 
Online
User avatar

Joined: Fri Aug 30, 2002 1:09 am
Posts: 8539
Location: Southern California
Quote:
Wouldn't you do a PHP as well as pushing, the accumulator, X and Y registers?

PHP is automatically included in the interrupt sequence, kind of like the CMP#0 being automatically included in instructions that affect A, X, or Y.

The article mentions having a different stack area for the ISR's use, but I can't think of any reason for that. It won't step on anything, because that's part of a stack's function-- that wherever you are, it leaves it alone and builds past it then when it's done it removes anything it has added without affecting anything that was there previously. My zero-overhead system of servicing interrupts in Forth takes advantage of that. Before I did it, people said it could not be done without the overhead of setting up another pair of stacks. If either the background program or the ISR need a lot of stack space for local variables and environments, recursion, etc., the best use of stack space will be gained by having one large continuous stack space with one large free area at the end, as opposed to fragmenting it and having dead zones between the fragments.

I forgot about saving the banks, since my use of the '816 has been limited to bank zero only. (You still get a ton of benefits.) The bank pushes and pulls are always 8-bit though. The direct-page register is 16-bit, so pushing and pulling it are always 16-bit regardless of status bits.

_________________
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  
PostPosted: Wed Oct 31, 2012 2:04 am 
Offline
User avatar

Joined: Thu May 28, 2009 9:46 pm
Posts: 8482
Location: Midwestern USA
GARTHWILSON wrote:
Quote:
Wouldn't you do a PHP as well as pushing, the accumulator, X and Y registers?

PHP is automatically included in the interrupt sequence, kind of like the CMP#0 being automatically included in instructions that affect A, X, or Y.

Disclaimer: it was I who wrote that "Interrupt handler considerations section in the Wiki article (as well as some other sections). Incidentally, that entire article is under attack by a user named Wtshymanski who thinks that it should be deleted because it doesn't fit his narrow definition of what Wikipedia is all about.

As Garth noted, an effective PHP is executed by the MPU during the interrupt acknowledgement sequence, which means the register widths at the time of the interrupt will have been preserved and thus will automatically be restored. The recommendation, if 100 percent transparency is to be assured, is to set .A, .X and .Y to 16 bits before pushing them. You of course can skip this step if you know for a fact that your ISR will not disturb the registers.

Quote:
The article mentions having a different stack area for the ISR's use, but I can't think of any reason for that. It won't step on anything, because that's part of a stack's function-- that wherever you are, it leaves it alone and builds past it then when it's done it removes anything it has added without affecting anything that was there previously. My zero-overhead system of servicing interrupts in Forth takes advantage of that. Before I did it, people said it could not be done without the overhead of setting up another pair of stacks. If either the background program or the ISR need a lot of stack space for local variables and environments, recursion, etc., the best use of stack space will be gained by having one large continuous stack space with one large free area at the end, as opposed to fragmenting it and having dead zones between the fragments.

The article doesn't say, however, that a separate stack is required. That paragraph starts with "If the ISR has its own assigned stack location..." In the case of Forth, what you have is a mono-tasking environment, so stack usage is fairly predictable. In a preemptive multitasking operating system, the kernel most likely is going to have its own stack and as the ISR is part of the kernel, it may be preferable, after the registers have been pushed, to use a different stack area for the kernel processing, especially if a context switch is going to occur.

Quote:
I forgot about saving the banks, since my use of the '816 has been limited to bank zero only. (You still get a ton of benefits.) The bank pushes and pulls are always 8-bit though. The direct-page register is 16-bit, so pushing and pulling it are always 16-bit regardless of status bits.

Bank, not banks. PB is automatically pushed during interrupt acknowledgement, however DB is not. In a system with more than 64KB, it is likely that the data area used by the kernel, of which the ISR would be part, will not be the same as used by applications. Saving DB and then changing it to a new bank protects the foreground task data and allows the kernel to use 16 bit addresses to access its own data.

_________________
x86?  We ain't got no x86.  We don't NEED no stinking x86!


Last edited by BigDumbDinosaur on Wed Oct 31, 2012 6:34 pm, edited 1 time in total.

Top
 Profile  
Reply with quote  
PostPosted: Wed Oct 31, 2012 1:27 pm 
Offline
User avatar

Joined: Mon Dec 08, 2008 6:32 pm
Posts: 143
Location: Brighton, England
Thanks for your replies gentlemen. They have been very helpful. BDD - that wikipedia article is very good and extreemly useful. I hope it doesn't get removed due to other people's narrowmindedness.

_________________
Shift to the left,
Shift to the right,
Mask in, Mask Out,
BYTE! BYTE! BYTE!


Top
 Profile  
Reply with quote  
PostPosted: Wed Oct 31, 2012 6:31 pm 
Offline
User avatar

Joined: Thu May 28, 2009 9:46 pm
Posts: 8482
Location: Midwestern USA
PaulF wrote:
Thanks for your replies gentlemen. They have been very helpful. BDD - that wikipedia article is very good and extreemly useful. I hope it doesn't get removed due to other people's narrowmindedness.

The user who is trying to get it deleted has some sort of meglomaniacal bent. When he can't get articles that he doesn't like deleted he more often than not deletes entire sections from them without any sort of consensus. He's been the target of several investigations due to his "slash and burn" methods, but so far no sanctions have been levied against him. This illustrates one of Wikipedia's principle weaknesses: lack of enforcement against disruptive users.

_________________
x86?  We ain't got no x86.  We don't NEED no stinking x86!


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

All times are UTC


Who is online

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