TweetFollow Us on Twitter

Controller
Volume Number:9
Issue Number:7
Column Tag:Hardware Interface

Developing Embedded Controller Software

A unified solution to embedded cross-development applications of the Macintosh

By Chris J. Magnuson, Hewlett-Packard Company

Note: Source code files accompanying article are located on MacTech CD-ROM or source code disks.

About the author

Chris Magnuson works as an embedded software engineer at Hewlett-Packard Company, designing software for a variety of instruments. He can be reached on the Internet at chrism@col.hp.com.

Have you ever wanted to produce an electronic gadget to solve a problem you had encountered? Have you ever had a great idea for an electronic gizmo that you could sell to the masses? Many obstacles can stand in the way of translating an idea into a viable, functioning piece of electronic equipment. But as with all things, a little perseverance and some information will get things rolling in the right direction. Most gadgets will require a microprocessor (also called an embedded controller) to provide control and handle user interfacing to the system. This article will give you the information you need to use your Macintosh as a software development platform to create your embedded controller idea.

Even if you have no experience designing electronic hardware and can only write software, you can still get an idea out of your head and into your hands. If your application calls for some sort of special hardware, like a data acquisition system or an audio digitizer, try to enlist the help of a knowledgable friend or other electronic-savvy designer to design the digitizer for you. One source to find individuals like this is your local university engineering college. Or try posting something on the Internet sci.electronics notes group. When the hardware is designed and the data is translated to digital streams, the software becomes the enabling link in the chain. And several companies produce SBC (single board computer) products that are microcontrollers with RAM, ROM, Input/Output (I/O) facilities and timers ready to run, needing only a power supply to activate them. So you don’t necessarily have to design an embedded control computer. Check a copy of Radio Electronics magazine or Embedded Systems Programming magazine for advertisements on these SBC products. Get copies of catalogs from electronic component suppliers such as Digi-Key to familiarize yourself with the types of switches, display units and packaging components available for your project.

Before you start coding, there are a few issues that need to be addressed. It is an extremely good idea to design the system on paper before you start implementing. One reason for this is because assumptions made during the analysis portion of the project can ripple down to the implementation phase and cause problems of untold magnitude should the assumptions prove false. Careful planning and investigation can minimize your disappointments. An embedded controller system is usually “realtime,” meaning that there are some expectations of its performance with regard to how the user interacts with it. An example of a bad analysis-phase assumption would be that there are no expectations for display speed. If your project uses some sort of display device you may want to make sure that the display can be written to fast enough that the user will not be waiting for the system to respond to his inputs. In other words, figure out whether the software you will need to write can run quickly enough to satisfy display update rate constraints. This may sound a bit like the “chicken and egg” paradox, but you can formulate some idea of how long your program will take to do various tasks once you start writing down what those tasks are. The mere act of translating your idea into verbage on paper can bring problems to your attention, and the earlier they are discovered the better your project will perform.

To make your idea a reality, you’ll need some hardware and software tools. The hardware tools are probably more difficult to understand for software designers, but are often needed to facilitate debugging and system implementation. There are a variety of hardware tools available for solving embedded development problems. They include in-circuit microprocessor emulators (called emulators or ICE), logic analyzers, EPROM programmers and ROM emulators, to name a few. Many of these devices will interface with your Macintosh via a serial cable. Be aware that the standard modem cable supplied with peripherals such as 2400 baud modems may not work, and that a high-speed modem cable that supports hardware handshaking (such as that supplied with a 9600 baud modem) is much more likely to be needed. In summary, there are two different Macintosh serial interconnection schemes that require two different cables.

ICE equipment can be thought of as nothing more than a large box of electronics that simulates the operations of your system microprocessor chip (Fig. 1). This seems inefficient, but the reason ICE are used is because they allow you to inspect the inner workings of the processor in the system, much like Macsbug allows you to see what the Macintosh is up to. The emulator will also have RAM available, which means that your program software can be downloaded into the emulator RAM and run from there. This is useful for simulating ROM if your code will eventually reside in ROM. The emulator can communicate with the Mac via one of the serial ports in conjunction with a terminal data communication program. When your system does not work, you will need to understand why, and tracing the execution of the code on the hardware may be the only way to determine the cause of the failure. This hardware trace capability is one of the great benefits of microprocessor emulators, since you are getting a bird’s eye view of the activity on the microprocessor busses and have the capability to stop, step or set breakpoints for program execution. Although the emulator trace information will often be in assembly mnemonics, there is a workaround for this so that high-level code like C or Pascal can be displayed along with the assembly code it produces. More on this later.

Figure 1: In-circuit emulation (ICE)

Be sure to understand that the ICE will require some room for the probe head to fit in your embedded system. The probe head is usually a bit larger than the microprocessor chip and your hardware must have room to accomodate it. When you buy an SBC ask the vendor if they can socket the microprocessor with a ZIF (zero-insertion force) socket and get clearance measurements from the emulator vendor to make sure that this will not be a problem. The SBC vendor will probably have some information for you concerning which emulators have successfully probed their product. Also, make sure that the mechanical design of your gadget (i.e. the case) will not interfere with emulator probing.

MACHINE 1 - State Listing

Label ADDR TI 34010 Mnemonic Time

0 3FEDF650 MOVE @3FED0020h,A8,0

1 3FEDF660 0020h data read 536 ns

2 3FEDF670 3FEDh data read 528 ns

3 3FED0020 031Eh data read 400 ns

4 3FEDF680 CMP A8,A9 400 ns

5 3FEDF690 JREQ (JRZ) 015h 536 ns

6 3FEDF7F0 MOVE @3FDCC010h,A7,0 664 ns

7 3FEDF800 C010h data read 536 ns

8 3FEDF810 3FDCh data read 536 ns

9 3FDCC010 CC2Eh data read 400 ns

10 3FEDF820 MOVE @3FDCC000h,A8,0 400 ns

Figure 2. Logic analyzer inverse assembly state listing from HP16500A logic analyzer

A logic analyzer is a powerful tool for examining the workings of your system. A logic analyzer differs from ICE equipment in that the ICE is in the circuit in place of the microprocessor, while the logic analyzer probes are on the circuit. This is an important distinction, because it makes the difference between having program execution control and register-peeking capability (as with the ICE) and having only address/data bus information (as with the logic analyzer). Even so, the logic analyzer is versatile, because most logic analyzers have facilities to enable them to make sense of the information they find on the busses and produce mnemonic or disassembled displays (Fig. 2) that show where your code is executing. The logic analyzer can be set up to trigger on a certain event (arrival at a certain address range in the code, for example) and start storing all activity after the trigger point for examination in this mnemonic assembly code format. In this way system crashes can be tracked to the root cause by doing successive traces on suspected portions of the code. If necessary, many logic analyzers can be programmed using simple commands via a serial port if task automation is desirable (such as dumping all the data from the logic analyzer to a computer for storage).

Similar to the ICE equipment, many logic analyzers will have mechanical requirements to probe your system. Logic analyzers often work in conjunction with something called a preprocessor (different than a preprocessor for a software compiler). The preprocessor is a small circuit card that allows you to insert the microprocessor chip in it, attach the logic anlyzer cables to predefined connectors, then put the preprocessor in your circuit. It is still possible to get valuable information from logic analyzers without using a preprocessor, but preprocessors are handy, because they simplify the mechanical aspects of probing your system, making the probing of your system more convenient.

Logic analyzers and preprocessors use inverse assembly software (built-in or loadable for the logic analyzer) to produce the disassembled output displays. But there are a couple of things that can be done that will make your system easier to debug. For one, make sure that you have a way to disable the on-board cache of the microprocessor (if your microprocessor has one) with a wire jumper or resistor pullup. This will make traces easier to read and less confusing because many of the prefetched instructions and data may not appear in proper sequence on the trace otherwise. If the cache is enabled, the microprocessor will only go out on the bus if it needs something not stored in the cache, and that means the logic analyzer will not be able to see everything that is going on. Also, the logic analyzer may have the capability to define symbols for data and address values that appear on the busses. Taking the time to learn how the symbols can be defined and used in the logic analyzer is well worth the effort, as the displays become much easier to read.

Another class of device is the ROM emulator. You guessed it, the ROM emulator sits in your circuit in place of ROM chips and the Mac can download the program into the ROM emulator via a serial port just like the ICE. ROM emulators are not as versatile as emulators or logic analyzers, and for this reason are not as widespread. Designers that have used ICE or logic analyzers are seldom willing to give up the versatility they provide.

Most likely the first embedded development occurred using EPROM programmers to program each revision of code into ROM chips, and the ROM chips would then be put in the sockets of the embedded system. This is a crude approach, but is still used. EPROM programmers are available at low to medium cost, which makes them attractive to a certain class of designers.

Although most of the hardware development tools discussed here can be purchased, it is often advantageous to rent them if they will only be needed a short time. If you have done a large amount of simulation of your program on the Mac you may only need to rent some hardware development tools to integrate your software with the embedded microprocessor hardware at the end of your project. Expect to pay up to about seven or eight percent of product list cost per month for a rental unit. Companies that rent equipment can be found in the phone book under the Electronic Testing Equipment heading.

Now that the hardware development tools have been discussed, let’s turn our attention to the software tools that will be needed to develop your project. In addition to a development environment, such as MPW or A/UX (Apple Computer’s version of the UNIX operating system), compilers, assemblers, cross-assemblers, terminal communication programs, debuggers, format translators, operating systems and libraries may be needed.

Mac programmers usually have a compiler/assembler favorite that they would like to use. The THINK languages are very common, and have a variety of nice features, like the built-in debugger. Environments like MPW or A/UX are much more versatile. With this versatility comes increased cost and added time needed to learn how to use them effectively. There are a variety of tools that run in the MPW environment which are very useful to embedded developers. If you are using the THINK languages now and want to keep using them, try to keep an eye toward their limitations for embedded development use. Some original software tools may have to be created in order to use them for embedded development, whereas many contributed and commercially-available tools exist for MPW and A/UX.

A/UX is actually less expensive than a fully loaded MPW environment. Add to this the fact that there is much free software available for the UNIX environment and the picture looks more attractive. UNIX is difficult to learn, however, and this initial learning time requirement may be objectionable. UNIX is also more difficult to maintain from a system administration point of view. The TextEditor in A/UX greatly simplifies one of the most difficult portions of UNIX, that of learning a text editor. Both MPW and A/UX are equally suited to the task of embedded software development, but MPW is far more widespread as far as embedded development is concerned using the Mac.

Most people know about assemblers and compilers, but what are cross-assemblers and cross-compilers? A cross-development tool is defined as a tool that runs on a certain native platform (like the Macintosh) but produces code that executes on a different target microprocessor other than the native machine. For example, a tool that compiles assembly code on a Macintosh that is destined to be executed on an Intel 8051 microcontroller is a cross-assembler. There are vendors that have cross-assemblers available for the Macintosh. For the example in this article, the Motorola 68000 microprocessor is used for the target (embedded) processor and also for the native machine (the Macintosh), both for simplicity and convenience of illustration. Since the Motorola 68000 family also has some processors with I/O and timer capabilities built-in there are plenty of reasons to use this family of chips in your design.

The debugger will be most useful in simulating the functionality of the embedded software on the native (Macintosh) platform before the target software/hardware integration phase of the project. It is important to have a good simulation strategy to minimize expenses involved with hardware development tool rentals. To do this simulation, the program will need to have some sort of in-target/out-of-target switch support. This is easily accomplished with the #ifdef directive in the C language (Listing 1). If the software is under simulation, for example, writing and reading of control registers mapped as hardware addresses is not possible. Instead, the simulation environment will need a stub which makes a probabilistic decision about the state of the hardware (whether it is busy, etc.) or otherwise simulates the presence of hardware without trying to access memory-mapped hardware addresses.

In recognition of the need to minimize hardware development tool expenditures, code quality tools such as syntactic analyzers can be beneficial. Although these tools (such as lint and complexity metric generators) can be expensive, any information they can give can help minimize the length of the hardware/software integration time, thus decreasing the amount of money spent on hardware rentals.

Macintosh operating system calls are obviously not going to do any good in the target environment, since the Mac Toolbox is not addressable by the target. In fact, it may be advisable to use your own library routines (or those written by someone else, like P. J. Plauger) if only to understand how they are implemented, where the global data references are, and other details. Another alternative is to port the Free Software Foundation GNU libgcc library for use in your development environment. The Apple SANE libraries should not be linked with your target program since they use operating system calls dependent on the Mac ROM.

Before your program can be downloaded to an emulator, the object code (application) will have to be translated to a format the emulator can understand. There are several MPW tools available to translate Mac applications into Motorola S record or Intel hex formats, both of which are readily digestible by emulators and EPROM programmers. One such tool is available from Apple Developer Technical Support, called DumpSRec. Another tool (Hex) was written by Paul Russell of the UK and is available via anonymous ftp from the mac.archive.umich.edu site as /mac/util/developer/mpwhexl.021.cpt.hqx. Other sources of various development tools include the Motorola Freeware BBS at 512-891-3733 and the Apple Developer CD, available with a subscription to develop magazine.

Other MPW tools that can help with the development process include the UltraSlimFast tool (on the Apple Developer CD) which produces a side-by-side listing of source code with assembly code that is produced by the source. This is invaluable for making sense of emulator traces and logic analyzer disassembly listings.

Terminal communication programs are invaluable for communicating with hardware development tools such as EPROM programmers and emulators. Some programs, like FreeTerm or ZTerm are free or shareware, while other more powerful programs containing such features as a scripting language are available at low cost. One program that contains a scripting language is White Knight. The ability to write custom scripts to satisfy unique communication requirements (such as interacting over the serial port with devices other than modems) is an attractive feature of this program. An unattractive feature is that it does not function properly under A/UX, so if you are not running the standard Mac desktop be aware of this.

Embedded operating system software can be either required or a nicety for your system. Generally, the larger the system (or the larger the number of distinct tasks that could be run in parallel) the more likely there will be a need for an operating system. Be advised that commercial multitasking packages can be quite expensive, and that not using an operating system can dramatically limit the capability of your system. Many beginning embedded designers design their first embedded system without an operating system, so using one is not essential. An in-depth discussion of the pros and cons of embedded operating systems is not possible here, so you may want to consult other resources.

Now it is time to apply the tools discussed to a real world application. An electrocardiogram system acquires data from a patient’s heart impulses by analog-digital conversion, analyzes the data to determine parameters such as heart rate, and displays the waveform data in a convenient format for viewing. The system must be capable of interacting with a user in order to allow changes to the display format and other characteristics. This system would be served well by four distinct processes running under an operating system on the target system. However, to simplify the example an operating system will not be used in the skeleton example code.

The hardware needed to acquire and display the data as well as to collect user inputs is simple. Most of the action surrounds the AcqStatus register, which will have certain bits set when some operations are ongoing by the acquisition hardware. The software will poll this register to see when the data are available, then read the data from another address and move it to another area of memory for use by the analyzer software. After the analyzer software has finished crunching the data, the data can be written to the display. All user interface inputs could invoke interrupt service routines. Alternatively, the user interface hardware could be polled periodically to see if any action occurs. Note that if an operating system were used, the user interface process could send a message to wake up another appropriate process when an event is received.

The hardware tool selected to debug the system was a Hewlett-Packard HP64742A Motorola 68000 emulator, selected because of its built-in terminal interface commands and the capability to accept Motorola S records for purposes of program download. There is sufficient RAM on the emulator to download the program and run it, with the emulator memory map set up to simulate emulation ROM behavior. In this manner, the emulator can be told to break when a write to ROM occurs, which could happen when the software goes haywire. The Macintosh serial ports can be easily connected to the emulator via a high-speed Macintosh modem cable to the emulator RS-232 port. The emulator configuration script (Listing 5) handles the details of presetting the instrument prior to program downloads. The emulator rear panel DIP switches were set to 56.7 Kbaud, no echo or parity.

To accomplish the development of the system, the MPW environment was selected, namely for flexibility reasons. The C compiler and assembler were used as well as the Hex and UltraSlimFast tools. Hex will serve as the format translator, transforming the application program into a text file containing Motorola S records. The UltraSlimFast tool will be used to make sense out of hardware emulator traces. The White Knight program was enlisted to handle the tasks of downloading the S records to the emulator and for communicating with the built-in terminal interface of the emulator.

Note that the low memory source (Listing 2) uses assembly for the target system vector table. Although it would seem that C function pointers could be used for the vectors, the C compiler would terminate the functions with the RTS instruction instead of RTE. The 68000 needs an RTE instruction when returning from exception processing in order to clean the stack properly.

Also, since global data in the Macintosh is referenced relative to A5, we will have to preset the A5 register to point to a safe area of RAM in the target system in order to access global items. A5 can be preset before anything else is done in the software by calling a small assembly routine. For this reason, it is a good idea to call a special routine to initialize globals after the A5 register has been set, instead of statically initializing the global variables. Also, some work will be necessary to make sure that the stack does not overrun the program or A5 space. Choose the initial values of the A5 and A7 registers carefully. Note that the first vector in the vector table is the initial value of the A7 stack pointer. Change this value as appropriate for your needs.

Note that the compiler in use may not always treat your program correctly when doing embedded development. For example, the MPW C 3.2 compiler does not strictly adhere to the conventional usage with regard to the use of the volatile and const keywords (Listing 8). Often, the volatile keyword is used to force the optimizer to leave references alone (do not optimize them out of the code) which is often necessary when talking to hardware. For example, just because the code has written nothing to the address does not mean that this activity should be eliminated from the code by the optimizer. You may need to talk to the hardware in this manner to accomplish certain operations. The workaround for MPW 3.2 is to confine all hardware accesses to another source file (compiled with -opt off) and assign values to the hardware (*StrobeIt=1;) instead of simply strobing (reading from) the hardware (*StrobeIt;). This places constraints on the hardware design, in that the designer must not rely on reads from locations to cause actions to occur. Alternatively, the hardware accesses could be coded in assembly, which is not as nice of a solution. Be aware of your compiler’s limitations.

The flow of operations for the software is compile, link, translate format to S records, produce source/assembly cross listings, and download to the emulator (Fig. 3). The Makefile (Listing 3) makes use of the Hex and UltraSlimFast tools in the process of producing the appropriate files. After the make cycle is complete, the White Knight program will be used to initiate a procedure (DoDownload, Listing 4) to send the code to the emulator. Downloads will proceed faster if the White Knight window is hidden, so that QuickDraw calls are not invoked in drawing to the window. Once the program is in the emulator, the “run from reset” command will get the program running. Setting breakpoints for execution, taking traces, and peeking/poking the values of registers will help you get the program running the way it should.

Figure 3: Development Process

Embedded development can be very satisfying. There is nothing quite like integrating specialized hardware and software to solve a specific problem. With the methods described here and a little sweat and inspiration, you may design the next “must have” electronic gizmo for the masses.

References

Plauger, P.J., The Standard C Library, Prentice Hall: Englewood Cliffs, NJ

Embedded Systems Programming, Magazine

Motorola MC68000 User’s Guide

Listing 1
/* filename: EKGmain.c
 *
 * This is tha main file for the system.
 */
 
/* Assembly routine that presets the A5 register to a 
 * place in RAM that we know to be a good spot for 
 * global data.  As itturns out, the A5 location is 
 * set below A7 (the stack pointer)in our embedded 
 * system RAM
 */
extern void InitA5Reg(void);

typedef enum {
 ACQ_INHIBITED  = 1,
 ACQ_ABORT      = 2,
 OK             = 3,
 ACQ_INCOMPLETE = 4,
} STATUS;

/* This typedef would need to be reversed for little-
 * endian target machines 
 */ 
typedef struct {
 unsigned AcqHoldoff   : 1 ;  /* Read/Write bit 0    */
 unsigned AcqComplete  : 1 ;  /* Read ONLY  bit 1    */
 unsigned AcqInProcess : 1 ;  /* Read ONLY  bit 2    */
 unsigned AcqStart     : 1 ;  /* Write ONLY bit 3    */
 unsigned AcqAbort     : 1 ;  /* Write ONLY bit 4    */
 unsigned unused       : 3 ;  /* unused     bits 5-7 */
} tAcqStatus;

typedef unsigned char uint8;
typedef unsigned char boolean;

#ifdef _NOT_SIMULATING_

#define ACQ_STATUS_REG_ADDR ( 0x00300000 ) 

#endif

tAcqStatus *AcqStatusReg;

boolean TheCowsAreOutRoaming;

/* Function protos
 */
void InitGlobals();
STATUS DoAnalysis();
STATUS DoDisplay();
STATUS DoAcquisition();


/************************************************* main() *
 *
 *
 */

void main()
{
   STATUS Status;
   
   InitGlobals();
   
   /* Run power-on self tests here
    */
   
   /* attempt an acquisition, then analyze and display
    * if successful
    */
   while ( TheCowsAreOutRoaming ) {
   
      if ( (Status = DoAcquisition() ) == OK ) {
         (void) DoAnalysis();
         (void) DoDisplay();
      }
      else {
         while (1) {
             ;  /* universal error trap ! */
         }
      }

   }
}

/****************************************** InitGlobals() *
 *
 * This routine sets up the globals (call it immediately).
 */
 
void InitGlobals() {

#ifdef _NOT_SIMULATING_

   InitA5Reg(); /* preset the global data register to RAM */
 
   /* set pointer to the hardware
    */
   AcqStatusReg =  (tAcqStatus *) ACQ_STATUS_REG_ADDR;
#endif

   /* init acq hardware 
    */
   AcqStatusReg->AcqAbort     = 1;
   AcqStatusReg->AcqHoldoff   = 0;
   AcqStatusReg->AcqStart     = 0;
   
   TheCowsAreOutRoaming = 1;
}

/******************************************* DoAnalysis() *
 *
 * This routine would extract measurement results from the
 * raw acquired data.
 */

STATUS DoAnalysis() {

   static STATUS PriorAcq;
   
   PriorAcq = OK;
   return (OK);
}

/******************************************** DoDisplay() *
 *
 * This routine would display the data acquired.
 */

STATUS DoDisplay() {
   return (OK);
}

/**************************************** DoAcquisition() *
 *
 * This routine manages the acquisition of data.
 */

STATUS DoAcquisition() {

#ifdef _NOT_SIMULATING_

   /* if acquisitions are inhibited, then forget it
    */
   if ( !AcqStatusReg->AcqHoldoff ) {
 
   /* start an acquisition
    */
   AcqStatusReg->AcqStart = 1;
    
   while ( AcqStatusReg->AcqInProcess ) { 
    ; /* wait for the acq to finish */
   }
   
   /* check to see if acq was completed
    */
   if ( AcqStatusReg->AcqComplete ) {
      return (OK);
   }
   else {
      return (ACQ_INCOMPLETE);
   }
   
   }
   else {  /* acqs are inhibited */
      return (ACQ_INHIBITED);
   }
  
#else  

/* simulation routines would go in here */

#endif /* _NOT_SIMULATING_ */
}
Listing 2
 TITLE ‘LowMemDataAndCode’
 BLANKS OFF
 PRINT OFF
 MACHINE  MC68000;pick 68000 target
 CODEREFS FORCEPC
 DATAREFS RELATIVE 

InitialStackPointer      EQU  $00093f3e   ;initial A7 value

;
; Here is the 256-vector exception table for the system.
;
VectTable     MAIN 
   ORG  0000     
LowMemVect

InitialSSPDC.L InitialStackPointer
InitialPC DC.L $00000400  ; ORG 1024, start of EKGmain.c
BusErrorDC.L256   ; jump to ExProc below
AddrError DC.L 256
IllegalInstruct  DC.L256
ZeroDivideDC.L 256
CHKInstruct DC.L 256
TRAPVInstruct  DC.L256
PrivViolate DC.L 256
Trace   DC.L256
Line1010Emu DC.L 256
Line1111Emu DC.L 256
Reserved12DC.L 256
Reserved13DC.L 256
FormatError DC.L 256 ; only for 68010/12
UninitINTVector  DC.L256
Reserved16DC.L 256
Reserved17DC.L 256
Reserved18DC.L 256
Reserved19DC.L 256
Reserved20DC.L 256
Reserved21DC.L 256
Reserved22DC.L 256
Reserved23DC.L 256
SpuriousINT DC.L 256  ;when bus error during INT processing
Lvl1AutoVector   DC.L256
Lvl2AutoVector   DC.L256
Lvl3AutoVector   DC.L256
Lvl4AutoVector   DC.L256
Lvl5AutoVector   DC.L256
Lvl6AutoVector   DC.L256
Lvl7AutoVector   DC.L256
TRAPVector1 DC.L 256
TRAPVector2 DC.L 256
TRAPVector3 DC.L 256
TRAPVector4 DC.L 256
TRAPVector5 DC.L 256
TRAPVector6 DC.L 256
TRAPVector7 DC.L 256
TRAPVector8 DC.L 256
TRAPVector9 DC.L 256
TRAPVector10DC.L 256
TRAPVector11DC.L 256
TRAPVector12DC.L 256
TRAPVector13DC.L 256
TRAPVector14DC.L 256
TRAPVector15DC.L 256

 ENDMAIN
 
* Start of exception processing routines.  These
* routines simply put a code on the stack and then
* jump to the main exception processing routine which
* handles the exception processing.  Note that an RTE
* instruction is used to return, NOT RTS.
*
* Note that the vectors above all point to this routine.
* In real life you would probably want each routine to
* do something a little different.

ExProc  PROC EXPORT
 ORG 256

* process exception code here

* and then return with RTE, not RTS
 RTE
 ENDPROC
 
 
 END
Listing 3
#   File:       EKG.make
#   Target:     EKG
#   Sources:    LowMemDataAndCode.a EKGmain.c

CCFLAGS = -r -sym on,novars,notypes -d _NOT_SIMULATING_

ASMFLAGS = -sym on

LDFLAGS = -t APPL -c ‘????’ -sym on -mf

OBJS1 = EKGmain.c.o A5Init.a.o

OBJS2 = LowMemDataAndCode.a.o 

EKG ƒƒ EKG.make {OBJS1} {OBJS2}
 Link {LDFLAGS} 
  {OBJS1} 
 “{Libraries}”Runtime.o 
 “{Libraries}”Interface.o 
 -o EKG
 
# load main program at 1024 decimal, 0400 hex
 Hex EKG -a $0400 -h s1 > 
 ‘A/UX:Comm:WhiteKnight:EKG’
 
# produce assy/C listing useful for debug
 DumpObj EKGmain.c.o > CSymbols
 UltraSlimFast CSymbols > EKGSrcAssy
 
# load the vector table and exception processing code at 0 
 Link -t APPL -c ‘????’ -mf 
 {OBJS2} -o LowMemDataAndCode
 Hex LowMemDataAndCode -a $0000 -h s1 > 
 ‘A/UX:Comm:WhiteKnight:LowMemDataAndCode’ 

# dependencies/rules for embedded code

LowMemDataAndCode.a.o ƒ EKG.make LowMemDataAndCode.a
  Asm {ASMFLAGS} LowMemDataAndCode.a

A5Init.a.o ƒ EKG.make A5Init.a
  Asm {ASMFLAGS} A5Init.a
  
EKGmain.c.o ƒ EKG.make EKGmain.c
  C  {CCFLAGS} EKGmain.c
Listing 4
**************
*filename: DoDownload
*This White Knight script configures the emulator,
*then downloads 2 pieces of an executable
*program.  First go the vector table and
*second the main program.
*This script works with a HP64742A/B Motorola 68000 emulator
*that is set for 56700-N-8-1-HALF DUPLEX for the terminal communications
**************
NEST EmulConfig.PROC
TYPE b^M
ERASE @2
ERASE @0
COPYINTO @1,Downloading S records...
SHOW@
NEST DownloadLowMem.PROC
NEST DownloadEKG.PROC
END
Listing 5
****************
*filename: EmulConfig
*This White Knight script configures an emulator
*before a program is downloaded to it.
****************
* Abort any transfers that may be occurring
TYPE ^C
* Force power-on init
TYPE init -c^M
PAUSE 400
* Select internal clock
TYPE cf clk=int^M
PAUSE 60
* Reset the emulator
TYPE rst^M
PAUSE 60
* Break into monitor
TYPE b^M
PAUSE 60
* Clear the memory map
TYPE map -d *^M
PAUSE 60
* Set default (non-assigned address space) TO TARGET RAM
TYPE map other tram^M
PAUSE 360
* Now setup the memory map
TYPE map 0000..03ff eram^M
PAUSE 60
TYPE map 0400..03ffff erom^M
PAUSE 60
TYPE map 80000..9f3ff eram^M
PAUSE 60
TYPE map 100000..13ffff trom^M
* Disable real time only mode
TYPE cf rrt=dis^M
PAUSE 60
* Disable target BERR
TYPE cf be=dis^M
PAUSE 60
* Disable target bus arbitration
TYPE cf ba=dis^M
PAUSE 60
* Select background monitor
TYPE cf mon=bg^M
PAUSE 60
* Select no break on write to ROM
TYPE bc -d rom^M
PAUSE 60
*     -e to enable break on write to ROM
* Enable target interrupts
TYPE cf ti=en^M
PAUSE 60
* Enable DTACK interlock
TYPE cf dti=en^M
PAUSE 60
* Set the initial stack pointer
TYPE cf rssp=9f3feh^M
PAUSE 60
* Disable background cycle drive
TYPE cf dbc=dis^M
PAUSE 60
* Disable bus arbitration tagging
TYPE cf bat=dis^M
PAUSE 60
* Break into monitor, then reset, then break into monitor again
TYPE b^M
PAUSE 60
TYPE rst^M
PAUSE 60
TYPE b^M
NESTEND
Listing 6
**************
*filename: DownloadEKG
*This White Knight script downloads the
*main program to an emulator.
**************
USEROPENI 1,EKG
IF ERROR JUMPTO ENDERR
@ ON
ERASE @0
ERASE @2
COPYINTO @1,Downloading main program...
SHOW@
TYPE load -mp^M
WATCH ON
:LOOP
*GET an S record...
USERREAD 1,S$
*If error then we are probably done sending...
IF ERROR JUMPTO END
LOCK ON
*Send an S record...
TYPE S$
*Loop for the ACK or NAK response...
:WAIT1
INBUFFER
IF NO JUMPTO WAIT1
FETCHBYTE A$
LOCK OFF
BYTEVAL A$,1,R%
:TRYSND
TEST R% = 6
IF YES JUMPTO LOOP
LOCK ON
* Else, retransmit S record...
TYPE S$
:WAIT2
INBUFFER
IF NO JUMPTO WAIT2
FETCHBYTE A$
LOCK OFF
BYTEVAL A$,1,R%
JUMPTO TRYSND
:END
ERASE @0
ERASE @2
COPYINTO @1,Done with program download.
SHOW@
WATCH OFF
USERCLOSE 1
BELL 
BELL
BELL
PAUSE
@ OFF
NESTEND
* An error must have occurred (only one bell)
:ENDERR
TYPE ^C
BELL
ERASE @0
COPYINTO @1,ERROR Occurred.
ERASE @2
SHOW@
PAUSE
WATCH OFF
USERCLOSE 1
END
Listing 7
***************
*filename: DownloadLowMem
*This White Knight script downloads a low memory object
*to the emulator.
***************
USEROPENI 1,LowMemDataAndCode
IF ERROR JUMPTO ENDERR
@ ON
ERASE @0
ERASE @2
COPYINTO @1,Downloading vector table...
SHOW@
TYPE load -mp^M
WATCH ON
:LOOP
*GET an S record...
USERREAD 1,S$
*If error then we are probably done sending...
IF ERROR JUMPTO END
LOCK ON
*Send an S record...
TYPE S$
*Loop for the ACK or NAK response...
:WAIT1
INBUFFER
IF NO JUMPTO WAIT1
FETCHBYTE A$
LOCK OFF
BYTEVAL A$,1,R%
:TRYSND
TEST R% = 6
IF YES JUMPTO LOOP
LOCK ON
* Else, retransmit S record...
TYPE S$
:WAIT2
INBUFFER
IF NO JUMPTO WAIT2
FETCHBYTE A$
LOCK OFF
BYTEVAL A$,1,R%
JUMPTO TRYSND
:END
ERASE @0
ERASE @2
COPYINTO @1,Done downloading vector table.
SHOW@
WATCH OFF
USERCLOSE 1
@ OFF
NESTEND
* An error must have occurred (only one bell)
:ENDERR
TYPE ^C
BELL
ERASE @0
COPYINTO @1,ERROR Occurred.
ERASE @2
SHOW@
PAUSE
WATCH OFF
USERCLOSE 1
END
Listing 8

/* Test file to see how the compiler handles volatile 
 * and const keywords.
 *
 * Compile normally, then inspect the assembly output
 * (using DumpObj or whatever) to see if
 * REGISTER_ADDRESS is written to.  MPW 3.2 will not 
 * comply with this intended use.  Then, change the last 
 * line to 
 *      *TheStrobe=1;
 * and notice the difference in the assembly code.
 */
 
#define REGISTER_ADDRESS  0x3000000

main() {

 /* RegStrobe is a type of register that is 8 bits wide.
  * It is a constant pointer to a volatile entity.
  */
 typedef unsigned char volatile * const RegStrobe;
 
 /* Obviously, you won’t want to EXECUTE this program 
  * on your Mac since it will write to a hard-coded  
  * address, which will only be polite in your
  * target environment
  */
 RegStrobe TheStrobe = (RegStrobe) REGISTER_ADDRESS;

 /* whack the register
  */
 *TheStrobe;  /* Any compiler that optimizes this out is not
               * respecting your use of const and volatile
   * keywords.  While not strictly a violation
   * of the ANSI C standard, it is sub-optimal
   * for purposes of embedded development.  Use
   * caution!
   */
}
Listing 9
 TITLE ‘A5Init’
 BLANKS OFF
 PRINT OFF
 MACHINE  MC68000   ;pick 68000 target
 CASE ON              ;C-callable routines are case-sensitive
 
InitialStackPointer    EQU  $0009343e   
 ;initial A5 value, below
 ;stack (A7) in system RAM
   
   
* put a value in A5 for initialization purposes (prior
* to any A5 global accesses)

InitA5Reg PROC EXPORT
 

 LINK   A6,#$0000;make it reentrant in case an 
 ;an interrupt occurs
 MOVE.L #$0009343e,A5
 
 UNLK   A6;collapse the stack frame
 
 RTS
 
 ENDPROC
 
 END

 

Community Search:
MacTech Search:

Software Updates via MacUpdate

Latest Forum Discussions

See All

Summon your guild and prepare for war in...
Netmarble is making some pretty big moves with their latest update for Seven Knights Idle Adventure, with a bunch of interesting additions. Two new heroes enter the battle, there are events and bosses abound, and perhaps most interesting, a huge... | Read more »
Make the passage of time your plaything...
While some of us are still waiting for a chance to get our hands on Ash Prime - yes, don’t remind me I could currently buy him this month I’m barely hanging on - Digital Extremes has announced its next anticipated Prime Form for Warframe. Starting... | Read more »
If you can find it and fit through the d...
The holy trinity of amazing company names have come together, to release their equally amazing and adorable mobile game, Hamster Inn. Published by HyperBeard Games, and co-developed by Mum Not Proud and Little Sasquatch Studios, it's time to... | Read more »
Amikin Survival opens for pre-orders on...
Join me on the wonderful trip down the inspiration rabbit hole; much as Palworld seemingly “borrowed” many aspects from the hit Pokemon franchise, it is time for the heavily armed animal survival to also spawn some illegitimate children as Helio... | Read more »
PUBG Mobile teams up with global phenome...
Since launching in 2019, SpyxFamily has exploded to damn near catastrophic popularity, so it was only a matter of time before a mobile game snapped up a collaboration. Enter PUBG Mobile. Until May 12th, players will be able to collect a host of... | Read more »
Embark into the frozen tundra of certain...
Chucklefish, developers of hit action-adventure sandbox game Starbound and owner of one of the cutest logos in gaming, has released their roguelike deck-builder Wildfrost. Created alongside developers Gaziter and Deadpan Games, Wildfrost will... | Read more »
MoreFun Studios has announced Season 4,...
Tension has escalated in the ever-volatile world of Arena Breakout, as your old pal Randall Fisher and bosses Fred and Perrero continue to lob insults and explosives at each other, bringing us to a new phase of warfare. Season 4, Into The Fog of... | Read more »
Top Mobile Game Discounts
Every day, we pick out a curated list of the best mobile discounts on the App Store and post them here. This list won't be comprehensive, but it every game on it is recommended. Feel free to check out the coverage we did on them in the links below... | Read more »
Marvel Future Fight celebrates nine year...
Announced alongside an advertising image I can only assume was aimed squarely at myself with the prominent Deadpool and Odin featured on it, Netmarble has revealed their celebrations for the 9th anniversary of Marvel Future Fight. The Countdown... | Read more »
HoYoFair 2024 prepares to showcase over...
To say Genshin Impact took the world by storm when it was released would be an understatement. However, I think the most surprising part of the launch was just how much further it went than gaming. There have been concerts, art shows, massive... | Read more »

Price Scanner via MacPrices.net

Amazon is offering a $100 discount on every M...
Amazon is offering a $100 instant discount on each configuration of Apple’s new 13″ M3 MacBook Air, in Midnight, this weekend. These are the lowest prices currently available for new 13″ M3 MacBook... Read more
You can save $300-$480 on a 14-inch M3 Pro/Ma...
Apple has 14″ M3 Pro and M3 Max MacBook Pros in stock today and available, Certified Refurbished, starting at $1699 and ranging up to $480 off MSRP. Each model features a new outer case, shipping is... Read more
24-inch M1 iMacs available at Apple starting...
Apple has clearance M1 iMacs available in their Certified Refurbished store starting at $1049 and ranging up to $300 off original MSRP. Each iMac is in like-new condition and comes with Apple’s... Read more
Walmart continues to offer $699 13-inch M1 Ma...
Walmart continues to offer new Apple 13″ M1 MacBook Airs (8GB RAM, 256GB SSD) online for $699, $300 off original MSRP, in Space Gray, Silver, and Gold colors. These are new MacBook for sale by... Read more
B&H has 13-inch M2 MacBook Airs with 16GB...
B&H Photo has 13″ MacBook Airs with M2 CPUs, 16GB of memory, and 256GB of storage in stock and on sale for $1099, $100 off Apple’s MSRP for this configuration. Free 1-2 day delivery is available... Read more
14-inch M3 MacBook Pro with 16GB of RAM avail...
Apple has the 14″ M3 MacBook Pro with 16GB of RAM and 1TB of storage, Certified Refurbished, available for $300 off MSRP. Each MacBook Pro features a new outer case, shipping is free, and an Apple 1-... Read more
Apple M2 Mac minis on sale for up to $150 off...
Amazon has Apple’s M2-powered Mac minis in stock and on sale for $100-$150 off MSRP, each including free delivery: – Mac mini M2/256GB SSD: $499, save $100 – Mac mini M2/512GB SSD: $699, save $100 –... Read more
Amazon is offering a $200 discount on 14-inch...
Amazon has 14-inch M3 MacBook Pros in stock and on sale for $200 off MSRP. Shipping is free. Note that Amazon’s stock tends to come and go: – 14″ M3 MacBook Pro (8GB RAM/512GB SSD): $1399.99, $200... Read more
Sunday Sale: 13-inch M3 MacBook Air for $999,...
Several Apple retailers have the new 13″ MacBook Air with an M3 CPU in stock and on sale today for only $999 in Midnight. These are the lowest prices currently available for new 13″ M3 MacBook Airs... Read more
Multiple Apple retailers are offering 13-inch...
Several Apple retailers have 13″ MacBook Airs with M2 CPUs in stock and on sale this weekend starting at only $849 in Space Gray, Silver, Starlight, and Midnight colors. These are the lowest prices... Read more

Jobs Board

Relationship Banker - *Apple* Valley Financ...
Relationship Banker - Apple Valley Financial Center APPLE VALLEY, Minnesota **Job Description:** At Bank of America, we are guided by a common purpose to help Read more
IN6728 Optometrist- *Apple* Valley, CA- Tar...
Date: Apr 9, 2024 Brand: Target Optical Location: Apple Valley, CA, US, 92308 **Requisition ID:** 824398 At Target Optical, we help people see and look great - and Read more
Medical Assistant - Orthopedics *Apple* Hil...
Medical Assistant - Orthopedics Apple Hill York Location: WellSpan Medical Group, York, PA Schedule: Full Time Sign-On Bonus Eligible Remote/Hybrid Regular Apply Now Read more
*Apple* Systems Administrator - JAMF - Activ...
…**Public Trust/Other Required:** None **Job Family:** Systems Administration **Skills:** Apple Platforms,Computer Servers,Jamf Pro **Experience:** 3 + years of Read more
Liquor Stock Clerk - S. *Apple* St. - Idaho...
Liquor Stock Clerk - S. Apple St. Boise Posting Begin Date: 2023/10/10 Posting End Date: 2024/10/14 Category: Retail Sub Category: Customer Service Work Type: Part Read more
All contents are Copyright 1984-2011 by Xplain Corporation. All rights reserved. Theme designed by Icreon.