6502.org Forum  Projects  Code  Documents  Tools  Forum
It is currently Thu Nov 14, 2024 4:42 am

All times are UTC




Post new topic Reply to topic  [ 35 posts ]  Go to page 1, 2, 3  Next
Author Message
PostPosted: Fri May 20, 2016 4:19 am 
Offline
User avatar

Joined: Fri Aug 30, 2002 1:09 am
Posts: 8540
Location: Southern California
I have my tester going for the 65816 which I set up for Jeff Laughton to get info he needs for his fast, non-memory-mapped I/O tricks using the WDM instruction.  Is there anything anyone else would like tested?  It lets me raise and lower Φ2 one edge at a time, and at any time in the clock sequence, also alter the other inputs, ie, ABORT\, IRQ\, NMI\, RST\, and RDY, and it prints out what's on the address bus and data bus and every signal line, both input and output.  Op codes are converted to mnemonics in the printout, and bank bytes, op codes, operands, data, and dead bus cycles are labeled as such, per VDA and VPA.  BDD had me check for what would happen if ABORT\ hits during the SToP instruction, and the answer is that the processor stops without acting on the ABORT interrupt.

If you want something else tested, please let me know, in detail, for example if you want one of the inputs to go low or high at a particular part of a particular cycle of an instruction.  I can't test for nanosecond timings, but in slow motion, I can go a half cycle at a time and alter or read the various things before or after any given clock edge, on a real '816, to discover the behaviors that are not in the data sheet.  Don't give me any programs to run please, but a few instructions to set up the desired conditions and then see what happens in a given instruction is fine.

_________________
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: Fri May 20, 2016 8:17 am 
Offline
User avatar

Joined: Thu Dec 11, 2008 1:28 pm
Posts: 10977
Location: England
We could get some interesting findings from this - good project!


Top
 Profile  
Reply with quote  
PostPosted: Fri May 20, 2016 4:30 pm 
Offline
User avatar

Joined: Fri Dec 11, 2009 3:50 pm
Posts: 3367
Location: Ontario, Canada
GARTHWILSON wrote:
tricks using the WDM instruction
:?: Some of you may be wondering, given that the WDM instruction could hardly be simpler. (The CPU just fetches and ignores the $42 opcode and its operand byte.) The info Garth is collecting has to do with interrupt response. We're contemplating a scheme that uses the WDM as a prefix that works in combination with the following instruction. The two are are supposed to execute consecutively. But there's a risk of the WDM and the "target" instruction being separated by an ill-timed interrupt. We need to either do a fixup afterward, or prevent the problem in advance by briefly (2~) masking interrupts by means of external logic. It's the latter option that raises questions about behavior. Thanks for doing this, Garth!

-- Jeff

_________________
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  
PostPosted: Fri May 20, 2016 7:35 pm 
Offline
User avatar

Joined: Thu May 28, 2009 9:46 pm
Posts: 8483
Location: Midwestern USA
GARTHWILSON wrote:
BDD had me check for what would happen if ABORT\ hits during the SToP instruction, and the answer is that the processor stops without acting on the ABORT interrupt.

Garth's test on the actual hardware confirmed something that Bill Mensch had investigated via simulation following a query of mine a while back. The 65C816's behavior when hit with an /ABORT immediately after fetching an STP instruction is something that I will have to consider when I eventually design my protected mode '816 system. The complex logic will have to do more than merely assert /ABORT if a program attempts to execute STP. I envision that somehow the bit pattern on the data bus would have to be tinkered with to convert STP to a "harmless" instruction before the fall of Ø2. With that done, /ABORT could be asserted to wrest control away from the misbehaving program.

The STP instruction is opcode $DB, or %11011011. Very conveniently, %11011011 XOR %11111111 results in %00100100 or $24, which is a BIT <dp> instruction. So if I can get something in the system to invert the state of all data bus bits when logic detects that an STP is being fetched I would then avert an MPU shutdown.

Timing with /ABORT is critical if the MPU is to be "aborted" at the right time. Converting the opcode to a BIT <dp> gives the glue logic enough time to toggle /ABORT at a point in the instruction cycle where the MPU will correctly respond.*

My goal is to eventually design a 65C816 system whose hardware can be operated in "real mode" or "protected mode." In "real mode," there is no policing of instructions or memory access, and a program can unconditionally touch anything in the system and unconditionally execute any instruction, including STP, which would normally cause "fatality" (the MPU's internal clock is halted in the high state and only a reset will get things going again). Direct page and stack accesses would occur in physical zero page and bank $00, respectively.

In protected mode, "user" and "supervisor" sub-modes would exist, both of which would impose certain rules on memory and I/O access, and use of certain instructions that could potentially cause system fatality. In "user" sub-mode, read/write to on memory would be restricted to the bank in which the program is running, causing accesses to bank $00 to be mapped back to the in-context bank. Hence there would never be conflicts over direct page or stack space.

In "supervisor" sub-mode, no restrictions will exist on instruction usage and the bank $00 remapping could be turned off to allow the supervisor program (kernel) to write anywhere in RAM.

It's all out-loud thinking, of course.

————————————————————
*/ABORT must be asserted for no more than one Ø2 cycle, with the toggle sequence occurring as soon as the error condition is recognized but before the final Ø2 cycle of the instruction, which is when the computational results of the instruction are stored in registers or in memory.

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


Top
 Profile  
Reply with quote  
PostPosted: Fri May 20, 2016 7:44 pm 
Offline
User avatar

Joined: Thu Dec 11, 2008 1:28 pm
Posts: 10977
Location: England
(It would be enough, wouldn't it, to invert just one bit? $DB is STP, whereas $DA is PHX and $CB is WAI - and maybe anything would do, if you plan to abort anyway. Or did I miss something?)


Top
 Profile  
Reply with quote  
PostPosted: Fri May 20, 2016 8:36 pm 
Offline
User avatar

Joined: Thu May 28, 2009 9:46 pm
Posts: 8483
Location: Midwestern USA
BigEd wrote:
(It would be enough, wouldn't it, to invert just one bit? $DB is STP, whereas $DA is PHX and $CB is WAI - and maybe anything would do, if you plan to abort anyway. Or did I miss something?)

PHX is problematic, since it is a stack instruction. The actual toggling of /ABORT would probably not be possible in the same Ø2 cycle in which the opcode substitution takes place. Hence it might not be possible to abort soon enough to prevent PHX from actually writing to the stack.

WAI could be used, since it would merely stop the '816 until any hardware interrupt hits (/ABORT qualifies as an interrupt). However, in "user" sub-mode, WAI would be an illegal instruction and its detection would trigger a secondary attempt to abort. The CPLD logic would have to be arranged to not look at the data bus once the sequence to prevent STP from being executed had been started. Also, the restart of the '816 will occur in one Ø2 cycle after any interrupt, which would make timing quite touchy.

Conversion of STP to BIT <dp> does have the advantage of increasing the number of Ø2 cycles required to execute the "bogus" BIT instruction, giving the system a little more timing headroom for toggling /ABORT.

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


Top
 Profile  
Reply with quote  
PostPosted: Fri May 20, 2016 8:47 pm 
Offline
User avatar

Joined: Fri Aug 30, 2002 1:09 am
Posts: 8540
Location: Southern California
I suppose I can understand why you wouldn't want a user program to have a SToP instruction in it.  Otherwise, I thought the purpose of ABORT\ was to take care of memory accesses that were illegal, either because there is no memory at the address given by an instruction's operand or the effective address derived from indexing and/or indirection, or because the user's program does not have permission to access (or at least write to) that address.  I have not looked into that kind of application myself though.  If there's another way to make sure the program does not have an STP, it seems like that might be the better solution.

_________________
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: Sat May 21, 2016 4:52 am 
Offline
User avatar

Joined: Thu May 28, 2009 9:46 pm
Posts: 8483
Location: Midwestern USA
GARTHWILSON wrote:
I suppose I can understand why you wouldn't want a user program to have a SToP instruction in it. Otherwise, I thought the purpose of ABORT\ was to take care of memory accesses that were illegal, either because there is no memory at the address given by an instruction's operand or the effective address derived from indexing and/or indirection, or because the user's program does not have permission to access (or at least write to) that address. I have not looked into that kind of application myself though. If there's another way to make sure the program does not have an STP, it seems like that might be the better solution.

Use of /ABORT to terminate a program that uses forbidden instructions is a natural application. STP is special in that it will halt the MPU, effectively killing the system and requiring a hard reset. The only way that I've conjured to prevent that in protected mode is to change the apparent opcode on D0-7 during the opcode fetch cycle and toggle /ABORT. I'd welcome alternative ideas.

Aside from STP, other instructions that should be forbidden in "user" sub-mode would be any that set the I bit in SR, RTI (would knock the stack out of whack), and XCE.

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


Top
 Profile  
Reply with quote  
PostPosted: Sat May 21, 2016 8:37 am 
Offline
User avatar

Joined: Thu Dec 11, 2008 1:28 pm
Posts: 10977
Location: England
STP must be an anomaly, I think. No instruction can do anything useful in cycle 1 (when it hasn't quite arrived) or cycle 2 (when it's only just being decoded) so I'd've thought ABORT in cycle 2 should always be OK - unless, as does not seem to be the case, ABORT is only expected during a memory cycle.

When can you get ABORT ready? Cycle 2? Or do you find you're not ready until cycle 3?

(Edit: branch instructions, at least, are subject to predecode in the cycle they are fetched. It's possible that causes a slight exception to my second sentence above.)


Top
 Profile  
Reply with quote  
PostPosted: Sat May 21, 2016 8:57 pm 
Offline
User avatar

Joined: Sun Jun 30, 2013 10:26 pm
Posts: 1949
Location: Sacramento, CA, USA
I'm not a hardware guy, BDD, but is it possible that you could make your RESET routine use a "powered-up" memory location with an unusual value, so it could reliably recognize the difference between a cold reset and a warm reset, and proceed accordingly? Then, you could just have a little counter that ran off the clock and asserted /RES if it counted seven or eight clocks without a SYNC. The warm RESET routine could examine the active process list, and identify the culprit. The culprit's register state may be lost, but everything else should be intact, if done carefully.

Mike B.


Top
 Profile  
Reply with quote  
PostPosted: Sat May 21, 2016 9:07 pm 
Offline
User avatar

Joined: Thu Dec 11, 2008 1:28 pm
Posts: 10977
Location: England
Counting missing SYNCs - I like that!


Top
 Profile  
Reply with quote  
PostPosted: Mon May 30, 2016 12:32 am 
Offline

Joined: Mon May 30, 2016 12:08 am
Posts: 7
Hi,

As you may know the SNES uses a custom CPU that contains a 65816 core with some internal peripherals, including a memory controller that inserts wait states on read and write cycles to some address ranges, but not on I/O cycles.

Examinations of the timing of interrupt processing on the SNES seem to show that one of the two I/O cycles at the beginning of an interrupt (before the return PC is pushed onto the stack) is not actually a regular I/O cycle; it gets a wait state inserted as if it was a read from the PC address. Furthermore, if an interrupt is asserted during the fetch of a one-byte, two-cycle instruction (CLC, SEC, TXY, etc.), the cycle of that instruction that is normally an I/O cycle also apparently turns into a read from the PC, at least for wait state purposes. I'm curious whether these behaviours are caused by a quirk of the 65816 or whether they're unique to the SNES custom CPU.

Can you tell me the state of the output lines (particularly VPA and VDA) on a standard 65816 during each Φ2 state when an IRQ or NMI is asserted during the opcode fetch cycle of a one-byte, two-cycle instruction (say TXY), starting at the fetch of the one-byte instruction and ending at the end of the interrupt pseudo-instruction?


Top
 Profile  
Reply with quote  
PostPosted: Mon May 30, 2016 6:05 am 
Offline
User avatar

Joined: Fri Aug 30, 2002 1:09 am
Posts: 8540
Location: Southern California
Welcome!

AWJ wrote:
Can you tell me the state of the output lines (particularly VPA and VDA) on a standard 65816 during each Φ2 state when an IRQ or NMI is asserted during the opcode fetch cycle of a one-byte, two-cycle instruction (say TXY), starting at the fetch of the one-byte instruction and ending at the end of the interrupt pseudo-instruction?

It pretends to read an operand of the TXY instruction (although the instruction really has no operand), then on the first of the two dead bus cycles at the beginning of the interrupt sequence, without incrementing the address, it pretends to read another op code before showing a dead bus cycle for that second cycle.  You can see it in the printout below.  The VPA and VDA signals are merged into the column that says either "op code coming" (when Φ2 is low), or the mnemonic for the op code itself (when Φ2 is high), or "operand [coming]", or "data [coming]", or "dead bus cycle".  There's an extra line I should not have printed, the first Φ2-high line of the first byte of fetching the IRQ vector, at FFEE, where it says the data if FF but I just hadn't put the 00 on the data bus yet for it to read.

Attachment:
816TXY_IRQtest.gif
816TXY_IRQtest.gif [ 222.53 KiB | Viewed 4504 times ]

_________________
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: Mon May 30, 2016 6:57 am 
Offline

Joined: Mon May 30, 2016 12:08 am
Posts: 7
Thank you very much for the prompt reply!

So the SNES CPU's quirk is indeed inherited from the 65816. The SNES CPU has completely different external bus signals from a 65816 (the bank address isn't multiplexed with the data bus, and it has separate /WR and /RD outputs like a Z80) but it seems most likely that Nintendo/Ricoh implemented it by wrapping additional logic around a totally stock 65816 core.

If it isn't too much trouble, could you please repeat the exact same test, only with an XBA (a one-byte, three-cycle instruction) in place of the TXY? Again, assert /IRQ during the fetch of the XBA.


Top
 Profile  
Reply with quote  
PostPosted: Mon May 30, 2016 7:13 am 
Offline
User avatar

Joined: Thu May 28, 2009 9:46 pm
Posts: 8483
Location: Midwestern USA
BigEd wrote:
When can you get ABORT ready? Cycle 2? Or do you find you're not ready until cycle 3?

It appears that in order for an abort to be effective it must come as soon as the machine state generates the condition that is to be aborted. In the case of a memory access violation or a page fault in a virtual memory system, that would be when the address is placed on the bus. That's relatively easy to handle, since the address appears midway during Ø2 low. If /ABORT is asserted when Ø2 goes high the instruction will not change anything and the operating system (or whatever) can do what has to be done to handle the situation.

More difficult is preventing "forbidden" instructions from being executed. The ideal time to assert /ABORT would be on the opcode fetch cycle, which would assure that the instruction can't alter a register or memory. However, the timing window is small, as the opcode can only be examined during Ø2 high, which is also when /ABORT would have to be asserted. Asserting /ABORT on the second Ø2 cycle might be too late in some cases to prevent errant operation. This is where having a means to change the apparent opcode on the data bus would be useful.

_________________
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  [ 35 posts ]  Go to page 1, 2, 3  Next

All times are UTC


Who is online

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