

|
Volume Number: 13 (1997)
Issue Number: 5
Column Tag: Tips & Tidbits
Tips & Tidbits
By Steve Sisak
File Manager Tip
If you've got a program, such as a compiler, which creates a temporary file, writes and reads from it, and then no longer needs the data, don't just close it and delete it; doing so usually causes the temporary data to be written to disk. Before closing it, call SetEOF(fRefNum, 0); This tells the disk cache that none of the data associated with the file need ever be written.
Jorg Brown
brown@connectix.com
Running m68k Codes "Compiled-in" (embedded) in a PowerPC Program
Here is a tip I bumped into recently. I wanted to run a sequence of m68k instructions (actually, to perform a system trap) on a PowerMac. Usually, this is a trivial task: compile the code in the 68k universe (for example, with in-line assembly supported by many m68k C/C++ compilers). From within a PowerPC application, one can call PowerPC glue code to the trap, which is probably present in the ‘InterfaceLib'.
Unfortunately, neither of these easy options would apply in my case: I only have a PowerPC compiler (I don't have disk space to install both 68k and PowerPC parts of the CodeWarrior). The trap I wanted to call (_ReadXPRam), is not an "official" one, thus there is no glue code for it in PowerPC libraries. Nevertheless, I found an easy way to run a sequence of 68k codes "compiled in" a PowerPC executable, and pass data in and out. By the way, this is working code that prints the contents of the xPRAM (more on xPRAM can be found at http://pobox.com/~oleg/ftp/xPRAM.html).
// Printing out the contents of the xPRAM // The trick is that _ReadXPRam/_WriteXPRam traps are available only // from within 68K universe. So, if this code runs in the PowerPC mode, // we've got to switch universes before running M68K code sequences... #include <stdio.h> #include <MixedMode.h> // This is // CLR.L D0 address would be 0 // MOVE.W $4(A7),D0 size -> lo word of d0 // SWAP D0 size -> hi word of d0 // MOVEA.L 6(A7),A0where -> A0 // _ReadXPRam // MOVEA.L (A7)+,A0 standard PASCAL epilogue // ADDQ.W #$6,A7 // JMP (A0) // RTS // This is a sequence of M68K instructions; unfortunately, // a PowerMac compiler doesn't understand them. So we've // got to assemble by hand <sigh> // // BTW, to write into xPRAM, replace 0xA051 in the sequence // below with 0xA052 //pascal void read_extended_PRAM(char * where, const short size) = static short read_extended_PRAM []= { 0x4280, 0x302F, 0x0004, 0x206F, 0x006, 0x4840, 0xA051, 0x205F, 0x5C4F, 0x4ED0 }; #define COMP_NORET_2(name, a1, a2) \ name##_procinfo = kPascalStackBased \ | STACK_ROUTINE_PARAMETER(1, SIZE_CODE(sizeof(a1))) \ | STACK_ROUTINE_PARAMETER(2, SIZE_CODE(sizeof(a2))) #define RD_ALLOC(routine) static RoutineDescriptor \ routine##_RD = BUILD_ROUTINE_DESCRIPTOR \ (routine##_procinfo, routine) enum { COMP_NORET_2(read_extended_PRAM,char *,const short) }; void main(void) { unsigned char whole_xPRAM_buffer[256]; UniversalProcPtr u_read_extended_PRAM = NewRoutineDescriptor((long (*)())read_extended_PRAM, read_extended_PRAM_procinfo, kM68kISA); CallUniversalProc(u_read_extended_PRAM, read_extended_PRAM_procinfo, whole_xPRAM_buffer, sizeof(whole_xPRAM_buffer)); DisposeRoutineDescriptor(u_read_extended_PRAM); printf("\ncontents of the xPRAM\n"); for(register int i=0; i<sizeof(whole_xPRAM_buffer); i+=16) { printf("\n%04x ",i); for(register int j=0; j<16; j++) printf("%s%02x", j%4 == 0 ? " " : "", whole_xPRAM_buffer[i+j]); } }
Oleg Kiselyov
oleg@pobox.com

- SPREAD THE WORD:
- Slashdot
- Digg
- Del.icio.us
- Newsvine