• Updated 2023-07-12: Hello, Guest! Welcome back, and be sure to check out this follow-up post about our outage a week or so ago.

Writing a Time Manager Task for 68k

freitz85

Member
Hi,

I am currently learning how to write a classic Mac application for a little non-sense project of mine. The resulting app will be for both PowerPC and 68k using System 7.

Having read "Programming Starter Kit for Macintosh", which is a great book by the way, I have a good part of my app working. I am coding in plain C using CodeWarrior 6.

However, I am trying to write a TimeManager task that executes in a fixed interval. The PPC part is working good, but my problem is when I try to set the A5 world for the 68k code, as I have to access global variables in my task. I have defined a structure containing the TMTask information and a reference to the old A5 world:

typedef struct

{

TMTask tmTask;

long tmWakeUp;

long tmReserved;

long tmRefCon;

} TMInfo;

I have found the one example where the PPC part looks like this. it is working, because the TimeManager places the address of the TMTaskInfo passed to the InsXTime() function in the A1 register. What I don't understand is that, if I'm not mistaken, the pascal calling convention states that function parameters are passed on the stack, not in registers.

#if __POWERPC__

pascal void MyTaskRoutine(TMTaskPtr a1)

{

TMTaskInfo *recPtr = (TMTaskInfo*)a1;

// do stuff

PrimeTime((QElemPtr)&recPtr->tmTask, 1000);

}

#endif

In the same example there is a simple part for 68k written in assembler without using an A5 reference, but I can't get it to work with my own code.

The translated the Pascal Inside Macintosh examples, but I am getting a "missing ':' error" in the line where I call GetTMInfo():

asm TMInfo * GetTMInfo(void)

{

move.l a1, d0

rts

}

pascal void MyTaskRoutine(void)

{

TMInfo *recPtr;

long oldA5;

recPtr = GetTMInfo();

oldA5 = SetA5(recPtr->tmRefCon);

// do stuff

SetA5(oldA5);

PrimeTime((QElemPtr)&recPtr->tmTask, 1000);

}

I am sure I am missing a simple thing, but I can't seem to figure it out. I'd appreciate every hint!

Regards, Florian

 
Last edited by a moderator:

freitz85

Member
I fixed the compiler error: I mixed up the asm keyword of the function prototypes.

But my main problem still exists: how do I get to my TMInfo pointer?

 

techknight

Well-known member
There arent really any developers here. The chances someone will respond to this is very next to none. 

There are 3 guys who MAY be able to help you. thats Dougg3, bbraun, and bigmessowires. 

 

Gryphel

Active member
This is discussed on page 3-13 of the Time Manager chapter in "Inside Macintosh: Processes" (linked to in my list of Apple Developer Documentation), which has similar sample code. So yes, it says the task record is passed in register A1, which means that the Time Manager task is not following the Pascal calling convention. But it can still work in most compilers by calling GetTMInfo first thing to retrieve A1.

A more direct translation of GetTMInfo in this chapter would be

pascal TMInfoPtr GetTMInfo(void) = { 0x2E89 /* MOVE.L A1,(SP) */ };

Whether your version would work may depend on the compiler.

A1 is set only in the revised and extended Time Managers. In the original time manager, prior to system 6.0.3, you would need to do something else. The Time Manager chapter suggests poking the A5 value into the code. An alternative is to set up a global record variable with the first two bytes set to 0x4EB9 (A JSR instruction with 4 byte absolute address), followed by a 4 byte address of a routine with pascal interface and a single pointer argument, followed by data that gets passed to the routine. Then pass this record as the Time Manager task.

 
Last edited by a moderator:

freitz85

Member
Thanks for the answer, Gryphel.

I found a whitepaper where the Pascal code was translated into C.

My code is working now, at least that part.

 
Top