TweetFollow Us on Twitter

A4, Code Resources
Volume Number:9
Issue Number:12
Column Tag:Think Top 10

Code Resources
and the A4 World

By Scott Shurr, Symantec Technical Support, Symantec Corp.

This article will describe the various kinds of code resources, and talk about the differences between writing applications and code resources. In applications, the machine code produced by the compiler uses the A5 register as a base address from which to access the applications global variables. Code resources are intended to be run simultaneously with applications, so they use a scheme designed to prevent interference with the application which called them up. In this case the A4 register is used as the base address for the resource’s global variables, as illustrated in the following diagram:

It is important when writing a code resource to be aware of how and when to set up A4. The different types of code resources require different declarations of the main() routine. The example consists of a single segment code resource which takes 2 arguments, which are a number of beeps, and the address of a string to receive a value. The code resource beeps the appropriate number of times, and then puts “Hello world” into the string. Here is the first version of the code resource:

/* 1 */

/* CodeResource.c */
void CRdoBeep(int beepSize);

void main(int beepSize, char *receiveString)
{
static char sLiteral[] = "Hello world"; 

strcpy(receiveString,sLiteral);
CRdoBeep(beepSize);
}

void CRdoBeep(int beepSize)
{
int i;

for (i=0; i<beepSize; i++)
  SysBeep(beepSize);
}

Create a new project, Resource.pi, and add the CodeResource.c file and the ANSI-A4 library to the project. Go to Set Project Type... and select the Code Resource button. Set Name to myCodeResource, Type to CODE, and ID to 31. One of the effects of changing the project type to anything other than Application is to cause the compiler to use the A4 register instead of the A5 as the address of the beginning of the application globals. Now select Build Code Resource..., and save the resource into Main.pi.rsrc. Another project called Main.pi will be used to test the code resource, and it will expect to find the code resource in that file in the folder. Create another new project in the same folder as Resource.pi, and add this program to it:

/* 2 */

/* UsesCodeResource.c */
#include <stdio.h>

typedef void (*CRPtr) (int,char*);

void main()
{
char myString[20];
Handle myCRhandle;

myCRhandle = GetNamedResource('CODE',"\pmyCodeResource");
HLock(myCRhandle);
(* (CRPtr) (*myCRhandle))(5,myString);
HUnlock(myCRhandle);
printf("myString=\"%s\"\n",myString);
}

Add UsesCodeResource.c and the ANSI library, and give it a try. The code resource will be loaded, it will beep 5 times, and then display some garbage instead of “Hello world”. The Disassemble command is useful in pointing out the problem. For the code resource:

main:
00000000: 4E56 0000          LINK      A6,#$0000
00000004: 486C 0000          PEA       sLiteral(A4)
00000008: 2F2E 000A          MOVE.L    receiveString(A6),-(A7)
0000000C: 4EAC 0000          JSR       strcpy(A4)
00000010: 3EAE 0008          MOVE.W    beepSize(A6),(A7)
00000014: 4EAC 0000          JSR       CRdoBeep(A4)
00000018: 4E5E               UNLK      A6
0000001A: 4E75               RTS
0000001C

CRdoBeep:
00000000: 4E56 0000          LINK      A6,#$0000
00000004: 2F07               MOVE.L    D7,-(A7)
00000006: 7E00               MOVEQ     #$00,D7
00000008: 6008               BRA.S     *+$000A      ; 00000012
0000000A: 3F2E 0008          MOVE.W    beepSize(A6),-(A7)
0000000E: A9C8               _SysBeep
00000010: 5247               ADDQ.W    #$1,D7
00000012: BE6E 0008          CMP.W     beepSize(A6),D7
00000016: 6DF2               BLT.S     *-$000C      ; 0000000A
00000018: 2E1F               MOVE.L    (A7)+,D7
0000001A: 4E5E               UNLK      A6
0000001C: 4E75               RTS
0000001E

Notice the instruction PEA sLiteral(A4). This depends on having A4 set to the address of the beginning of the code resource, so that sLiteral can be found. If MacsBug is used by putting a Debugger() call in CallsCodeResource.c, it can be seen that upon entry to the code resource’s main, A0 is set to the correct place, but A4 isn’t. Global variables always use offsets from A4 in code resources. In multi-segment code resources, all string literals also use an A4 offset. This works the same in C++, except that C++ has an option “Put string literals in code”, that will keep them from using A4. To fix the bug, change the code resource to look like this:

/* 3 */

/* CodeResource.c */
#include <SetUpA4.h>
void CRdoBeep(int beepSize);

void main(int beepSize, char *receiveString)
{
static char sLiteral[] = "Hello world"; 

RememberA0();
SetUpA4();
strcpy(receiveString,sLiteral);
CRdoBeep(beepSize);
RestoreA4();
}

void CRdoBeep(int beepSize)
{
int i;

for (i=0; i<beepSize; i++)
  SysBeep(beepSize);
}

To understand why this change makes the code resource work, see the disassembly of CallsCodeResource.c:

main:
00000000: 4E56 FFEC          LINK      A6,#$FFEC
00000004: 2F0C               MOVE.L    A4,-(A7)
00000006: 42A7               CLR.L     -(A7)
00000008: 2F3C 434F 4445     MOVE.L    #$434F4445,-(A7)
  ; 'CODE'
0000000E: 486D 0000          PEA       "\pmyCodeResource"
00000012: A9A1               _GetNamedResource
00000014: 285F               MOVEA.L   (A7)+,A4
00000016: 204C               MOVEA.L   A4,A0
00000018: A029               _HLock
0000001A: 486E FFEC          PEA       myString(A6)
0000001E: 3F3C 0005          MOVE.W    #$0005,-(A7)
00000022: 2054               MOVEA.L   (A4),A0
00000024: 4E90               JSR       (A0)
00000026: 204C               MOVEA.L   A4,A0
00000028: A02A               _HUnlock
0000002A: 486E FFEC          PEA       myString(A6)
0000002E: 486D 0000          PEA       "myString="%s""
00000032: 4EAD 0000          JSR       printf
00000036: 286E FFE8          MOVEA.L   $FFE8(A6),A4
0000003A: 4E5E               UNLK      A6
0000003C: 4E75               RTS

The _GetNamedResource trap returns a handle to the code resource on the stack. It is saved in A4 (A4 is not special in this case, it’s just what the compiler chose to use). Its dereferenced value is placed in A0, and the program does a JSR to the address in A0, the start of the code resource. The code resource itself begins with a header. It is possible to write your own header by including it in the source code for the code resource, and checking the Custom Header option in the Set Project Type dialog. In most cases, the option will not be selected, and the compiler will provide a default header for the code resource, like this:

00000000: BRA.S  *+$0010
     ...
00000010: LEA    start-of-resource,A0
00000014: NOP
00000016: NOP
00000018: BRA    main-of-code-resource

This sets A0 to the current address of the beginning of the code resource, and then jumps to the LINK instruction in the main function of the resource. A commented version of SetUpA4.h is useful in seeing the change made in the second version of the code resource:

/* 4 */

/*
 *  SetUpA4.h
 *
 *  Copyright (c) 1991 Symantec Corporation.
 *   All rights reserved.
 *
 *  This defines "SetUpA4()" and "RestoreA4()" routines that 
 *  will work in all A4-based projects.
 *
 *  "RememberA4()" or "RememberA0()" must be called in advance 
 *  to store away the value of A4 where it can be found by 
 *  "SetUpA4()".  The matching calls to "RememberA4()" (or 
 *  "RememberA0()") and "SetUpA4()" *MUST* occur in the same 
 *  file.
 *
 *  Note that "RememberA4()", "RememberA0()" "SetUpA4()", and
 *  "RestoreA4()" are not external.  Each file that uses them 
 *  must include its own copy.
 *
 *  If this file is used in the main file of a code resource 
 *  with "Custom Headers", be sure to #include it *AFTER* the 
 *  custom header!  Otherwise, the code resource will begin 
 *  with the code for the function "__GetA4()", defined below.
 *
 */

static void
__GetA4(void)
{
 asm {
 bsr.s  @1;  PC, (points to next line) goes on the stack
 ;  Branch to @1
 
 dc.l 0 ;  store A4 here
@1 move.l (sp)+,a1 ;  pop item from stack (which points
 ;  to previous line) into a1
 }
}

#define RememberA4() do { __GetA4(); asm { move.l a4,(a1) } } while (0)
 // __GetA4() puts pointer to spot for storing a4 in a1
 // move a4 to spot a1 points to
 
#define RememberA0() do { __GetA4(); asm { move.l a0,(a1) } } while (0)
 // __GetA4() puts pointer to spot for storing a4 in a1
 // move a0 to spot a1 points to
 
#define SetUpA4()do { asm { move.l a4,-(sp) } __GetA4(); /
  asm { move.l (a1),a4 } } while (0);
 // push a4 onto the stack
 // Call __GetA4 which puts a pointer to the space into a1
 // move whatever a1 is pointing to into a4
 
#define RestoreA4()do { asm { move.l (sp)+,a4 } } while (0)
 // pop item from stack into a4
 
/* In other words:

 RememberA4 puts the value in A4 in special spot.
 RememberA0 puts the value in A0 in special spot.
 
 SetUpA4 puts current value in A4 on the stack and gets 
 value in special spot and puts it in A4.
 RestoreA4 pops saved value of A4 from stack into A4.
*/

Here is the disassembly of the changed portion of the code resource:

__GetA4:
00000000: 6104               BSR.S     *+$0006      ; 00000006
00000002: 0000 0000          ORI.B     #$00,D0
00000006: 225F               MOVEA.L   (A7)+,A1
00000008: 4E75               RTS
0000000A

main:
00000000: 4E56 0000          LINK      A6,#$0000
00000004: 4EAC 0000          JSR       __GetA4(A4)
00000008: 2288               MOVE.L    A0,(A1)
0000000A: 2F0C               MOVE.L    A4,-(A7)
0000000C: 4EAC 0000          JSR       __GetA4(A4)
00000010: 2851               MOVEA.L   (A1),A4
00000012: 486C 0000          PEA       sLiteral(A4)
00000016: 2F2E 000A          MOVE.L    receiveString(A6),-(A7)
0000001A: 4EAC 0000          JSR       strcpy(A4)
0000001E: 508F               ADDQ.L    #$8,A7
00000020: 3F2E 0008          MOVE.W    beepSize(A6),-(A7)
00000024: 4EAC 0000          JSR       CRdoBeep(A4)
00000028: 548F               ADDQ.L    #$2,A7
0000002A: 285F               MOVEA.L   (A7)+,A4
0000002C: 4E5E               UNLK      A6
0000002E: 4E75               RTS
00000030

The RememberA0() in the source creates the 2 instructions after the LINK. It first does a JSR to __GetA4, whose job it is to get an address into A1. Notice that the second line of __GetA4 is a DC.L, which allocates 4 bytes, which are used for storing the addresses. The fact that the SetUpA4.h actually reserves some memory, unlike most other header files, is why it must always be included in each segment that uses any of RememberA4(), RememberA0(), SetUpA4(), or RestoreA4(). The BSR.S pushes the address of the 4 bytes onto the stack and then jumps over the 4 bytes. Then the address is popped from the stack into A1, and the function returns. The value of A0 is then saved at that address. The next 3 instructions in the code resource’s main are generated from SetUpA4(). It first pushes the current value of A4 onto the stack, so that it can be restored before returning to the application, which was probably using A4 for its own purposes. Then, the JSR to __GetA4 again gets the address of the storage area into A1. The address stored there is then placed into A4, which now holds the correct base address for the code resource. After the code resource does its work, it finishes up with RestoreA4(). That generates the MOVEA.L instruction which restores the old value of A4 from the stack before the code resource returns to the application which called it. This example may have raised some more questions, which I will try to answer here.

Q. Does this work the same in C++ as it works in C?

A. The code produced by C++ for a code resource that contains #include <SetUpA4.h> is almost identical to that produced by C, but the mechanism for producing it is different. If you look at SetUpA4.h (in Mac #includes: THINK #includes) you will see #if THINK_C which will select the C or the C++ version of the source. The __GetA4 is essentially the same for both versions, but the C++ version reflects its less powerful asm capabilities. In C, the calls like RememberA4() are implemented as #defines, while in C++ they are inline functions.

Q. Does any of this also apply to the other non-application projects, like Desk Accessories and Device Drivers?

A. The non-application projects are similar in that they all use offsets from A4 instead of A5 to access globals. You don't need to use SetUpA4 for desk accessories and device drivers, because the compiler provides a header which sets up the A4 for you.

Q. Why would one want to use a custom header in a code resource?

A. You can use the 18 bytes of the header for any purpose, as long as the first word is reserved for the code which will branch to where the resource is to begin execution. You could put flags for the version of the resource, or similar information, to be read by the code resource or by the program that is calling it. Just remember when you do that to put the #include <SetUpA4.h> after the header, or the code resource will start in the code SetUpA4.h generates, which isn’t desireable.

Q. What are the prototypes for the main() functions of various kinds of code resources?

A.

CDEF control definition
pascal long main(short varCode, ControlHandle theControl, 
 short message, long param);
FKEY function key
main();
INIT
main();
LDEF list definition
pascal main(short lMessage, Boolean lSelect, Rect lRect, 
 Cell lCell, short lDataOffset, short lDataLen, 
 ListHandle lHandle);
MDEF menu definition
pascal main(short message, MenuHandle theMenu, 
 Rect *menuRect, Point hitPt, short *whichItem);
WDEF window definition
pascal long main(short varCode, WindowPtr theWindow, 
 short message, long param);

 

Community Search:
MacTech Search:

Software Updates via MacUpdate

Bookends 12.5.8 - Reference management a...
Bookends is a full-featured bibliography/reference and information-management system for students and professionals. Access the power of Bookends directly from Mellel, Nisus Writer Pro, or MS Word (... Read more
Chromium 44.0.2403.125 - Fast and stable...
Chromium is an open-source browser project that aims to build a safer, faster, and more stable way for all Internet users to experience the web. Version 44.0.2403.125: This release contains a number... Read more
iMazing 1.2.2 - Complete iOS device mana...
iMazing (was DiskAid) is the ultimate iOS device manager with capabilities far beyond what iTunes offers. With iMazing and your iOS device (iPhone, iPad, or iPod), you can: Copy music to and from... Read more
Audio Hijack 3.2.0 - Record and enhance...
Audio Hijack (was Audio Hijack Pro) drastically changes the way you use audio on your computer, giving you the freedom to listen to audio when you want and how you want. Record and enhance any audio... Read more
FontExplorer X Pro 5.0.1 - Font manageme...
FontExplorer X Pro is optimized for professional use; it's the solution that gives you the power you need to manage all your fonts. Now you can more easily manage, activate and organize your... Read more
Calcbot 1.0.2 - Intelligent calculator a...
Calcbot is an intelligent calculator and unit converter for the rest of us. Featuring an easy-to-read history tape, expression view, intuitive conversion, and much more! Features History Tape -... Read more
MTR 5.0.0.1 - The Mac's oldest and...
MTR (was MacTheRipper)--the Mac's oldest and smartest DVD-backup app--is now updated to version 5.001 MTR -- the complete toolbox, not a one-trick, point-and-click extractor. MTR is intended for... Read more
LibreOffice 4.4.5.2 - Free, open-source...
LibreOffice is an office suite (word processor, spreadsheet, presentations, drawing tool) compatible with other major office suites. The Document Foundation is coordinating development and... Read more
Adobe Lightroom 6.1.1 - Import, develop,...
Adobe Lightroom is available as part of Adobe Creative Cloud for as little as $9.99/month bundled with Photoshop CC as part of the photography package. Lightroom 6 is also available for purchase as a... Read more
File Juicer 4.41 - Extract images, video...
File Juicer is a drag-and-drop can opener and data archaeologist. Its specialty is to find and extract images, video, audio, or text from files which are hard to open in other ways. It finds and... Read more

Pac-Man Championship Edition DX has brou...
Bandai Namco has released Pac-Man Championship Edition DX on iOS and Android, which features the classic arcade gameplay that we've all grown to love. Pac-Man Championship Edition DX can be enjoyed in much shorter bursts than the arcade versions... | Read more »
Cosmonautica (Games)
Cosmonautica 1.1 Device: iOS Universal Category: Games Price: $6.99, Version: 1.1 (iTunes) Description: Cast off! Are you ready for some hilarious adventures in outer space? | Read more »
Rescue humanity from a Demon horde in An...
Angel Stone is Fincon's follow up to the massively successful Hello Hero and is out now on iOS and Android. You play as a member of The Resistance, a group of mighty human warriors who have risen up in defiance of the Demon horde threatening to... | Read more »
Gallery Doctor (Photography)
Gallery Doctor 1.0 Device: iOS iPhone Category: Photography Price: $2.99, Version: 1.0 (iTunes) Description: Free up valuable iCloud and iPhone storage with Gallery Doctor, the only iPhone cleaner that automatically identifies the... | Read more »
You Against Me (Games)
You Against Me 1.0 Device: iOS Universal Category: Games Price: $.99, Version: 1.0 (iTunes) Description: A simple game… You. Me. Claim, steal, lock, score, win! | Read more »
Yep, it's True - Angry Birds 2 is O...
The not exactly rumors were true and the birds are back. Angry Birds 2 has come to the App Store and the world will... well I suppose it'll still be the same, but now we have more bird-flinging options! [Read more] | Read more »
You Could Design Your Own Card for Chain...
If you've ever wanted to create your own item, weapon, trap, or even monster for Chainsaw Warrior: Lords of the Night, this is your chance. Auroch Digital is currently holding a contest so that fans can fight to the death (not really) to see which... | Read more »
Bitcoin Billionaire is Going Back in Tim...
If you thought you managed to buy everything there is to buy in Bitcoin Billionaire and make all the money, well you though wrong. Those of you who made it far enough might remember investing in time travel - and it looks like that investment is... | Read more »
Domino Drop (Games)
Domino Drop 1.0 Device: iOS Universal Category: Games Price: $1.99, Version: 1.0 (iTunes) Description: Domino Drop is a delightful new puzzle game with dominos and gravity!Learn how to play it in a minute, master it day by day.Your... | Read more »
OPERATION DRACULA (Games)
OPERATION DRACULA 1.0.1 Device: iOS Universal Category: Games Price: $5.99, Version: 1.0.1 (iTunes) Description: 25% off launch sale!!! 'Could prove to be one of the most accurate representations of the Japanese bullet hell shmup... | Read more »

Price Scanner via MacPrices.net

Sale! 13-inch MacBook Pros on sale for $100 o...
B&H Photo has 13″ MacBook Pros on sale for $100 off MSRP. Shipping is free, and B&H charges NY sales tax only: - 13″ 2.5GHz/500GB MacBook Pro: $999.99 save $100 - 13″ 2.7GHz/128GB Retina... Read more
Sale! Save $100 on 13-inch MacBook Airs this...
B&H Photo has the 13″ 1.6GHz/128GB MacBook Air on sale for $899.99 including free shipping plus NY tax only. Their price is $100 off MSRP, and it’s the lowest price available for this model.... Read more
Worldwide Tablet Market Decline Continues, Ap...
The worldwide tablet market declined -7.0% year-over-year in the second quarter of 2015 (2Q15) with shipments totaling 44.7 million units according to preliminary data from the International Data... Read more
TP-LINK TL-PA8030P KIT Powerline Featuring Ho...
Consumer and business networking products provider TP-LINK is now shipping its TL-PA8030P KIT AV1200 3-Port Gigabit Passthrough Powerline Starter Kit that expands your home’s network over its... Read more
Apple refurbished iPad Air 2s available for u...
The Apple Store has Apple Certified Refurbished iPad Air 2s available for up to $140 off the price of new models. Apple’s one-year warranty is included with each model, and shipping is free: - 128GB... Read more
Updated Apple iPad Price Trackers
We’ve updated our iPad Air Price Tracker and our iPad mini Price Tracker with the latest information on prices and availability from Apple and other resellers. Read more
Apple refurbished 2014 13-inch 128GB MacBook...
The Apple Store has Apple Certified Refurbished 2014 13″ MacBook Airs available starting at $759. An Apple one-year warranty is included with each MacBook, and shipping is free: - 13″ 1.4GHz/128GB... Read more
Apple’s Education discount saves up to $300 o...
Purchase a new Mac or iPad at The Apple Store for Education and take up to $300 off MSRP. All teachers, students, and staff of any educational institution qualify for the discount. Shipping is free,... Read more
Save up to $600 with Apple refurbished Mac Pr...
The Apple Store has Apple Certified Refurbished Mac Pros available for up to $600 off the cost of new models. An Apple one-year warranty is included with each Mac Pro, and shipping is free. The... Read more
Mac Pros on sale for up to $260 off MSRP
B&H Photo has Mac Pros on sale for up to $260 off MSRP. Shipping is free, and B&H charges sales tax in NY only: - 3.7GHz 4-core Mac Pro: $2799, $200 off MSRP - 3.5GHz 6-core Mac Pro: $3719.99... Read more

Jobs Board

Executive Administrative Assistant, *Apple*...
…supporting presentation development for senior leadership. * User experience with Apple hardware and software is preferred. Additional Requirements The following list Read more
*Apple* Bus Company is now hirin - Apple Bus...
Apple Bus Company is now hiring school bus drivers in the Pettis County area. Class B CDL preferred. Free training provided. No nights or weekends required. Flexible Read more
*Apple* Certified Mac Technician - Updated 6...
…and friendly, hands-on technical support to customers troubleshooting and repairing Apple /Mac products with courtesy, speed and skill. Use your problem-solving skills Read more
Infrastructure Engineer - *Apple* /Mac Envir...
…a part of a team Requires proven problem solving skills Preferred Additional Apple Certified System Administrator (ACSA) Apple Certified Technical Coordinator (ACTC) Read more
*Apple* Retail - Multiple Positions (US) - A...
Job Description: Sales. Specialist - Retail Customer Service and Sales. Transform Apple Store visitors into loyal Apple customers. When customers enter the store, Read more
All contents are Copyright 1984-2011 by Xplain Corporation. All rights reserved. Theme designed by Icreon.