The secrets of the 68000

All 680x0 related coding posts in this section please.

Moderators: simonsunnyboy, Mug UK, Zorro 2, Moderator Team

Post Reply
ijor
Hardware Guru
Hardware Guru
Posts: 4013
Joined: Sat May 29, 2004 7:52 pm
Contact:

The secrets of the 68000

Post by ijor »

I plan to use this thread to post and discuss about interesting undocumented aspects of the 68000.
Fx Cast: Atari St cycle accurate fpga core
ijor
Hardware Guru
Hardware Guru
Posts: 4013
Joined: Sat May 29, 2004 7:52 pm
Contact:

The I/N field on the bus and address error stack frame

Post by ijor »

Quiz of the day for advanced 68000 coders:

It has been observed that the instruction MOVE Dn,-(An), if it provokes a bus or address error when writing the operand, the I/N bit would be set on the exception stack frame. According to the official documentation, the I/N set indicates that the processor wasn't processing an instruction. The observation actually is not accurate. The I/N might be set, but not always. Let's consider the following code sequence:

Code: Select all

  moveq    #1,D0
  move.l   D0,A0       ; A1 = 1
  move.w   D0,-(A0)    ; Attempt to access address -1 and provokes an address error exception
This will provoke an address error and the processor will create an extended stack frame that includes the I/N field as described in the manual. The I/N will be set in some circumstances, not always.

When I/N will be set and when it will be not, and why? Assume, of course, that SSP was valid and the stack frame was created successfully.

Edit: Added the size of the last instruction explicitly. I didn't include it before because most assemblers assume a default word size. There was no intention to hide it.
Fx Cast: Atari St cycle accurate fpga core
czietz
Hardware Guru
Hardware Guru
Posts: 1284
Joined: Tue May 24, 2016 6:47 pm

Re: The secrets of the 68000

Post by czietz »

I didn't test my theory, because that would be cheating. ;-)

But it is revealing that you omitted the operand size from the MOVE instruction. Thus, my guess is as follows: It depends on that size. If there is only one write access (.B / .W), the instruction is considered finished when the exception occurs. But if two write cycles are required (and the error occurs during the first cycle as in your example), the instruction is still considered under way.
ijor
Hardware Guru
Hardware Guru
Posts: 4013
Joined: Sat May 29, 2004 7:52 pm
Contact:

Re: The secrets of the 68000

Post by ijor »

czietz wrote:I didn't test my theory, because that would be cheating. ;-)
Not at all. You can test :)
But it is revealing that you omitted the operand size from the MOVE instruction. Thus, my guess is as follows: It depends on that size. If there is only one write access (.B / .W), the instruction is considered finished when the exception occurs. But if two write cycles are required (and the error occurs during the first cycle as in your example), the instruction is still considered under way.
Sorry, no. It wasn't intentional and I edited the post and added the size explicitly. If the size of the instruction would have been byte then no address error exception would be generated at all. A bus error could still happen depending on the platform. But no, the question assumes a word size that generates an address error exception.
Fx Cast: Atari St cycle accurate fpga core
czietz
Hardware Guru
Hardware Guru
Posts: 1284
Joined: Tue May 24, 2016 6:47 pm

Re: The secrets of the 68000

Post by czietz »

Now you've intrigued me and I had a look at the 68000 manual. (Even though that is definitively cheating.) With respect to the I/N bit is says: "The processor is processing an instruction if it is in the normal state or processing a group 2 exception; the processor is not processing an instruction if it is processing a group 0 or a group 1 exception."

EDIT:
So -- still not tested on the actual HW -- I'd now say that the state of the bit depends on whether your code is inside another exception handler. An address error while processing a group 0 exception (bus or address error) will cause a double fault and halt the CPU, but the behavior described in the manual should be observable by triggering the address error during a group 1 exception. For example in an interrupt handler.

After testing, I think that my previous theory was not correct -- but the basic idea was. In order for the I/N bit to be set to 1, the address error must not occur in the handler of a group 1 exception, but when the processor is actually setting up processing of a group 1 exception. I.e., when the TRACE bit is set while your code executes.

So, I see that the I/N bit is set, when running this code, while it is cleared when I comment the line marked with "<===".

Code: Select all

	move.l	#inthdl,0x24.w
	ori		#0x8000,sr | <===
	moveq	#1,D0
	move.l	D0,A0
	move.w	D0,-(A0)
	
inthdl:
	rte
ijor
Hardware Guru
Hardware Guru
Posts: 4013
Joined: Sat May 29, 2004 7:52 pm
Contact:

Re: The secrets of the 68000

Post by ijor »

czietz wrote: EDIT:
So -- still not tested on the actual HW -- I'd now say that the state of the bit depends on whether your code is inside another exception handler. An address error while processing a group 0 exception (bus or address error) will cause a double fault and halt the CPU, but the behavior described in the manual should be observable by triggering the address error during a group 1 exception. For example in an interrupt handler.

After testing, I think that my previous theory was not correct -- but the basic idea was.
It was wrong indeed. Interrupt or exception handler is a software concept, not a hardware one. The processor doesn't care, and even doesn't really know if you are inside a handler or not. So it is even possible to have an address or bus error inside a group 0 exception handler and it will not halt the cpu.
In order for the I/N bit to be set to 1, the address error must not occur in the handler of a group 1 exception, but when the processor is actually setting up processing of a group 1 exception.
Right. Or more precisely, when the processor is processing the exception itself and before the exception handler takes control. That includes saving the stack frame (normal or extended) and fetching the exception vector..
... I.e., when the TRACE bit is set while your code executes.
So, I see that the I/N bit is set, when running this code, while it is cleared when I comment the line marked with "<===".

Code: Select all

	move.l	#inthdl,0x24.w
	ori		#0x8000,sr | <===
	moveq	#1,D0
	move.l	D0,A0
	move.w	D0,-(A0)
	
inthdl:
	rte
This is partially true. But this is not the only circumstances that the I/N would be set. And you don't explain why it is set. It shouldn't (at least according to you might except). The address error didn't occur when saving the stack or when fetching the exception vector. The processor was still executing a regular instruction.
Fx Cast: Atari St cycle accurate fpga core
czietz
Hardware Guru
Hardware Guru
Posts: 1284
Joined: Tue May 24, 2016 6:47 pm

Re: The secrets of the 68000

Post by czietz »

Another clue might be that for "MOVE.W D0,-(A0)" the write access that causes the address error only happens after the prefetch for the next instruction. Unlike you, I don't know how the internal sequencer of the 68000 works, but one could assume that the I/N bit due to the upcoming TRACE handler is updated in parallel to the prefetch. This would explain why the I/N is not set even with tracing in effect, if the address error is triggered by "MOVE.W D0,(A0)", instead.
ijor
Hardware Guru
Hardware Guru
Posts: 4013
Joined: Sat May 29, 2004 7:52 pm
Contact:

Re: The secrets of the 68000

Post by ijor »

czietz wrote:Another clue might be that for "MOVE.W D0,-(A0)" the write access that causes the address error only happens after the prefetch for the next instruction. Unlike you, I don't know how the internal sequencer of the 68000 works, but one could assume that the I/N bit due to the upcoming TRACE handler is updated in parallel to the prefetch. This would explain why the I/N is not set even with tracing in effect, if the address error is triggered by "MOVE.W D0,(A0)", instead.
You are getting closer. It is not directly related to the prefetch, but to the address error hapening at the last microcycle of the instruction.

I am posting a small article on the next message elaborating about the bus/address error exception stack frame. Last section of the article elaborates on this issue of the I/N bit.
Fx Cast: Atari St cycle accurate fpga core
ijor
Hardware Guru
Hardware Guru
Posts: 4013
Joined: Sat May 29, 2004 7:52 pm
Contact:

Re: The I/N field on the bus and address error stack frame

Post by ijor »

Attached in a small article I wrote about the bus and address exception stack frame.

Whole article in PDF form (updated version):
M68000-ExceptionStackFrame.pdf
I am pasting here the sections relevant to the I/N field. But it might be easier to understand the context checking the whole article.

..., but also the I/N field is set indicating, or seeming to indicate, that the processor wasn’t executing an instruction when the exception was triggered. Normally the I/N field would be set only when the processor was already processing a group 1 exception, such as when a bus or address error occurs when saving the PC or the SR during an interrupt. It is not expected to be set when processing an instruction. The reason that it would be set in some circumstances, is once more again, how the microcode works.

As explained in the previous section, the processor updates its state for the next instruction before it actually completes. This includes updating the TVN (Trap Vector Number) latch. The TVN is used slightly differently depending on the exception group. For group 1 exceptions, besides specifying the vector number, it is also the flag to process an exception after the current instruction completes.

Group 0 exceptions, on the other hand, are processed after the current microinstruction and do not update or modify the TVN latch until later, once the exception is already processing.

Consider the following code sequence (assembled machine code is included because it would be useful for the waveform below):

Code: Select all

7001  moveq    #1,d0
2040  move.l   d0,a0
3100  move.w   d0,-(a0)
4AFC  illegal
When the write to memory occurs as part of the third instruction, the EA is odd which will provoke an address error. In this particular instruction using pre decrement addressing mode, the write bus cycle is performed at the end of the instruction. That means that the TVN latch is updated before the write cycle completes (either normally or not). In addition, because in this particular code sequence the next instruction is illegal, the TVN is set for an illegal exception. Lastly, once the exception microcode starts, the I/N field in the SSW is set because the TVN latch indicates a group 1 exception. Note that this would not happen if the following instruction would be a regular one, not unless another group 1 exception, like Trace or Interrupt was being triggered.

It might seem surprising that both the IRD and the TVN are updated before the current instruction actually completes. From a software processing point of view, it could be expected that first the instruction completes, only then the state for the next instruction is updated, and finally the next instruction or exception is processed. But hardware doesn’t work like that. There is certainly no gap between instructions, and there isn’t an exact edge that absolutely separates one instruction from the other. For pipelining reasons and because of internal delays, some updates must be performed some cycles ahead. In this case specifically, the processor cannot update the TVN latch at the very last cycle. The TVN latch determines the address of the next microcode and the processor needs a couple of cycles to decode the address and the internal microcode ROM output.


FX68K simulation waveform

This is a simulation waveform of my FX68K FPGA core performing the above code. The waveform for a real 68000 would be slightly different, mainly because synchronization is different. But the result would be exactly the same.

StackFrame0-WaveSimul1.jpg
The yellow vertical marks enclose the faulty bus cycle that attempts to access an odd address. Note the flow of the opcodes through the prefetch. Both the IRD and the TVN latch are updated at the start of the last microcycle of the MOVE instruction, coinciding also with the start of the bus cycle. The address error is signaled internally rather early; this is needed to abort the bus cycle at the external signals. However, internally the bus cycle continues, the MOVE instruction is still executing and the actual exception microcode has not yet started. Exception processing, including updating the SSW as one of its first tasks, starts a couple of cycles later (not shown on the waveform). By then, IRD already has the ILLEGAL instruction’s opcode, and the TVN latch indicates a group 1 exception.

Edit: Expanded the elaboration about the TVN usage and group 0 exceptions
You do not have the required permissions to view the files attached to this post.
Fx Cast: Atari St cycle accurate fpga core
orionfuzion
Atariator
Atariator
Posts: 28
Joined: Fri Nov 11, 2016 1:57 pm
Location: Paris, France
Contact:

Re: The secrets of the 68000

Post by orionfuzion »

Fascinating!
Thanks for this clear and detailed explanation.
I guess no emulator handles this correctly?
ThorstenOtto
Atari God
Atari God
Posts: 1210
Joined: Sun Aug 03, 2014 5:54 pm

Re: The secrets of the 68000

Post by ThorstenOtto »

Well, what is "correctly"? If i understand that, it could also happen that an interrupt happens as the "next" instruction, which would have the same effect as the illegal instruction in the example. So imho for an exception handler, the I/N field in the stack frame is rather meaningless.
orionfuzion
Atariator
Atariator
Posts: 28
Joined: Fri Nov 11, 2016 1:57 pm
Location: Paris, France
Contact:

Re: The secrets of the 68000

Post by orionfuzion »

By masking interrupts it is possible to have a deterministic behavior. Based on that trick, one could write a small protection scheme that works on a real HW but fails on emulators.
ijor
Hardware Guru
Hardware Guru
Posts: 4013
Joined: Sat May 29, 2004 7:52 pm
Contact:

Re: The secrets of the 68000

Post by ijor »

orionfuzion wrote:I guess no emulator handles this correctly?
Not that I know. But I'm in contact with Toni Wilen (Winuae maintainer) and already let him know.
ThorstenOtto wrote:Well, what is "correctly"? If i understand that, it could also happen that an interrupt happens as the "next" instruction, which would have the same effect as the illegal instruction in the example. So imho for an exception handler, the I/N field in the stack frame is rather meaningless.
Well, you can say that an exception handler can't reliable check the I/N field. But that's not the point. The point is that under some conditions the hardware has some specific behavior, and an emulator (or FPGA core, or clone) should ideally reproduce exactly the same behavior. Otherwise, and as orionfuzion is saying, some code might depend on this (intentionally or not )and have different behavior than on real hardware.

You might think that probably no software depend on this. But there are several ST protections that do depend on the exact content of the exception stack frame including the undocumented bits on the first word of the stack frame (see my article for a description of those undocumented bits). And it is just by chance that no case, that I know, sets the I/N field. If just by chance it would have, say, a LINE-A or LINE-F opcode after the instruction that provokes the exception, then, bingo ... :)
Fx Cast: Atari St cycle accurate fpga core
User avatar
Eero Tamminen
Fuji Shaped Bastard
Fuji Shaped Bastard
Posts: 2211
Joined: Sun Jul 31, 2011 1:11 pm

Re: The secrets of the 68000

Post by Eero Tamminen »

> You might think that probably no software depend on this.

There are currently also some other differences in exception handling when comparing real HW with emulation, for example when 030 MMU raises exception on auto-increment instruction:
https://listengine.tuxfamily.org/lists. ... 00004.html
ijor
Hardware Guru
Hardware Guru
Posts: 4013
Joined: Sat May 29, 2004 7:52 pm
Contact:

Re: The secrets of the 68000

Post by ijor »

I edited the post with the article about the I/N field. One section was expanded because I was told it was difficult to understand. The attached PDF article was also updated accordingly.
Eero Tamminen wrote:There are currently also some other differences in exception handling when comparing real HW with emulation, for example when 030 MMU raises exception on auto-increment instruction: ...
We are talking about the plain 68000. There are plenty emulation inaccuracies for the later 680X0 models, including even the 68010 (which is the closest to the 68000, of course).
Fx Cast: Atari St cycle accurate fpga core
ijor
Hardware Guru
Hardware Guru
Posts: 4013
Joined: Sat May 29, 2004 7:52 pm
Contact:

Re: The secrets of the 68000

Post by ijor »

We are having quite a long email exchange with Toni Wilen (again, Winuae maintainer). I didn't actually test it, but at this point most, if not all, Winuae inaccuracies related to bus and address error exceptions should be fixed. At least regarding the behavior, timing might not be exact. Hatari uses Winuae cpu core, so eventually this will improve Hatari emulation as well.
Fx Cast: Atari St cycle accurate fpga core
czietz
Hardware Guru
Hardware Guru
Posts: 1284
Joined: Tue May 24, 2016 6:47 pm

Re: The secrets of the 68000

Post by czietz »

Thank you, to everyone involved!
User avatar
Cyprian
10 GOTO 10
10 GOTO 10
Posts: 1958
Joined: Fri Oct 04, 2002 11:23 am
Location: Warsaw, Poland

Re: The secrets of the 68000

Post by Cyprian »

great
Portfolio / Lynx II / Jaguar / TT030 / Mega STe / 800 XL / 1040 STe / Falcon030 / 65 XE / 520 STm / SM124 / SC1435
SDrive / PAK68/3 / Lynx Multi Card / LDW Super 2000 / XCA12 / SkunkBoard / CosmosEx / SatanDisk / UltraSatan / USB Floppy Drive Emulator / Eiffel / SIO2PC / Crazy Dots / PAM Net
Hatari / Steem SSE / Aranym / Saint
http://260ste.appspot.com/
User avatar
npomarede
Atari God
Atari God
Posts: 1346
Joined: Sat Dec 01, 2007 7:38 pm
Location: France

Re: The secrets of the 68000

Post by npomarede »

Hi
I confirm the latest changes from WinUAE are merged in my devel branch for Hatari and that it should support all those bus/address error behaviors for 68000 (including the examples that Ijor reported above).
I will push the changes to main tree soon, I have to do some test first with new 68030 + MMU + basic bus error to check there's no regression with CPU > 68000.

Historical note : as Amiga don't have bus error, WinUAE's cpu core didn't support it directly and it was done as an add-on at Hatari level ; now that WinUAE has optionnal support for bus error emulation, this new code will be used instead in Hatari (as it's much more accurate and avoid maintaining a patched version of cpu core in Hatari). Huge thanks to Toni for his work with WinUAE.

Nicolas
Gunstick
Captain Atari
Captain Atari
Posts: 294
Joined: Thu Jun 20, 2002 6:49 pm
Location: Luxembourg
Contact:

Re: The secrets of the 68000

Post by Gunstick »

Amiga does not have a bus error? That's one of the more frequent events on ST. How does that work?
User avatar
Cyprian
10 GOTO 10
10 GOTO 10
Posts: 1958
Joined: Fri Oct 04, 2002 11:23 am
Location: Warsaw, Poland

Re: The secrets of the 68000

Post by Cyprian »

yep,
due to amiga was born as a gaming console, there were no need to use serious 68000 stuff like user/supervisor mode or full bus mastering.

the OS works on the same level as the user's applications. It means that there is no any protected area and every application have possibility override OS vectors and hardware registers.
Portfolio / Lynx II / Jaguar / TT030 / Mega STe / 800 XL / 1040 STe / Falcon030 / 65 XE / 520 STm / SM124 / SC1435
SDrive / PAK68/3 / Lynx Multi Card / LDW Super 2000 / XCA12 / SkunkBoard / CosmosEx / SatanDisk / UltraSatan / USB Floppy Drive Emulator / Eiffel / SIO2PC / Crazy Dots / PAM Net
Hatari / Steem SSE / Aranym / Saint
http://260ste.appspot.com/
User avatar
npomarede
Atari God
Atari God
Posts: 1346
Joined: Sat Dec 01, 2007 7:38 pm
Location: France

Re: The secrets of the 68000

Post by npomarede »

Hi, this is quite a shortcut of what the Amiga is :)

Yes, there's no supervisor only memory area, but instead of detecting HW by writing at different addresses and see if you get some bus error (as the TOS does when trying to detect STE/Falcon/TT for example), the Amiga and all its extension boards are using an 'autoconfig method' where each board is able to declare itself to the OS, which is quite flexible as the OS doesn't have to know all the possible board.

But as I fear the thread might soon divert to an Amiga vs ST discussion :) and not to secret of 68000, Amiga was just like that. Whether it's a good thing or not to access HW without supervisor mode is another debate, at least it didn't stop Amiga from working :)
User avatar
npomarede
Atari God
Atari God
Posts: 1346
Joined: Sat Dec 01, 2007 7:38 pm
Location: France

Re: The secrets of the 68000

Post by npomarede »

Hi
just to let you know that all the work done by Toni with WinUAE's cpu core (also with some input from Ijor) has been merged in public Hatari devel source tree.

So now you can test all those "undocumented" flags/behaviours as the 68000 cpu core in Hatari should be 100% accurate.
Windows/Linux pre-built binaries are here http://antarctica.no/~hatari/latest/

Nicolas
Post Reply

Return to “680x0”