CF68KLib Technical Overview

Please note that CF68KLib is an older tool which is no longer supported. See here for our current range.

How CF68KLib handles Unimplemented 680x0 Instructions

Many 680x0 instructions also exist in ColdFire and use the same opcodes. However, certain opcodes corresponding to legal 680x0 instructions are not valid for ColdFire.

A 680x0 opcode may be invalid in ColdFire because it corresponds to an instruction which does not exist - for example ADD.B or RTD. Such opcodes will cause the ColdFire processor to take an 'Illegal Instruction' exception. (A few unimplemented instructions such as MOVE16 cause a line-F exception).

Other 680x0 opcodes are invalid because they correspond to instructions which exist in ColdFire but for which the addressing mode specified is invalid. For example the instruction "NEG.L (A0)" would be illegal because the ColdFire version of the NEG instruction only allows a data register as its operand. Such opcodes will cause the ColdFire processor to take an 'Address Error' exception.

CF68KLib installs its own routines to handle these exceptions. When an unimplemented 680x0 instruction causes an exception the handler will decode the opcode of the instruction and dispatch to a small subroutine where a series of legal ColdFire instructions achieve an equivalent effect.

In the example of "NEG.L (A0)" above, CF68KLib would first decode the opcode to determine that it was a NEG.L instruction. It would then decode the addressing mode to determine that it was (A0). Finally, it would read the operand from (A0), negate it, and write it back, setting the condition bits appropriately before returning to the instruction following the NEG.

How CF68KLib handles Supervisor-Level Code

The ColdFire supervisor-level architecture is simpler than that of the 680x0 family. For example, ColdFire only has a single stack pointer instead of two for the 68000, (and three for the 68020). Exception stack frames have a different format, and the stack pointer is always aligned to a four-byte boundary before an exception frame is created. These differences mean that without the aid of CF68KLib you could not simply take a 680x0 Operating System - even if it contains only legal ColdFire instructions - and expect it to run on a ColdFire board.

The Supervisor Mode form of CF68KLib allows you to run a whole 680x0 operating system under emulation. To do this it surrounds the 680x0 code with an entire 'virtual machine' which hides the differences in architecture. To achieve this CF68KLib uses a number of techniques:

  • CF68KLib takes over the 'Illegal Instruction', 'Address Error', 'Line-A' and 'Line-F' exceptions and fixes up unimplemented user-mode 680x0 instructions in the manner described above.
  • In order to coerce exception stack frames into 680x0 format, CF68KLib installs its own handlers for all ColdFire exceptions. When an exception such as a TRAP is taken the CF68KLib handler will modify the exception stack frame so that it is in the correct format and then pass control to the original 680x0 trap handler.
  • Since exception frames are now in 680x0 format, CF68KLib needs to take steps to regain control before an RTE instruction (which is also legal in ColdFire) tries to execute with a frame format that would be invalid for ColdFire. To do this it runs the 680x0 program in ColdFire User Mode. In user mode, supervisor instructions like RTE will cause a privilege violation exception. By catching this exception CF68KLib can unpick the 680x0 exception frame and hence pass control back to the appropriate address.
  • Certain 680x0 registers have no equivalent in ColdFire - for example the 68020 has three stack pointers, the USP, the ISP and the MSP. Some instructions such as RTE may cause a change to the active stack pointer; others such as "MOVEC to USP" may alter an inactive stack pointer. CF68KLib keeps track of the current contents of these unmapped registers in its private data area, and when a privileged instruction such as MOVEC or RTE is executed, the library will use/update its private copies. For example, when the 680x0 code switches stack from the SSP to the USP, the CF68KLib library saves away the current state of A7 into the location it uses to track the SSP, and reloads A7 from the location where it stored the USP value.