From: Stuart Cheshire <
[email protected]>
Subject: WriteThrough INIT source code
Date: 9 Apr 1994 17:28:11 GMT
// Disk cache bypass INIT
// Copyright (C) April 1994 Stuart Cheshire
// Should be compiled as an INIT resource
// (use the "custom header" option in Think C)
#include <Traps.h>
// I know an address should be defined as a pointer type (eg 'void *'),
// not a 'long', but Apple's Get & Set TrapAddress calls are defined to
// use longs, so it's not my fault
typedef struct { unsigned short opcode; long addr; } JmpInstruction;
typedef void ShowIconFamily(short iconId);
void main(void);
static void entry_point(void) /* no stack frame please ! */
{
asm {
@0 move.l a4, -(sp)
move.l a0, -(sp)
DetachResource
lea @0, a0
move.l a0, a4
bsr main
exit: move.l (sp)+, a4
}
}
void my_write(void); void sys_write(void);
static void my_write(void)
{
asm {
tst.w IOParam.ioRefNum(a0) ; Is this a file write?
bmi.s @sys_write
cmp.l #1024, IOParam.ioReqCount(a0) ; Is it at leask 1K?
blo.s @sys_write
ori.w #0x20, IOParam.ioPosMode(a0) ; Set "Don't cache" bit
extern sys_write:
jmp 0x12345678 ; Resume the system call
}
}
static Boolean TrapAvailable(unsigned long trap)
{
TrapType tType = (trap & 0x800 ? ToolTrap : OSTrap);
if (trap & 0x800) // if it is a ToolBox Trap
{
unsigned long n = 0x400; // number of toolbox traps
if (NGetTrapAddress(_InitGraf, ToolTrap) == NGetTrapAddress(0xAA6E,
ToolTrap))
n = 0x200;
if ((trap &= 0x7FF) >= n) trap = _Unimplemented;
}
return(NGetTrapAddress(trap, tType) != NGetTrapAddress(_Unimplemented,
ToolTrap));
}
void main(void)
{
register long *p = &((JmpInstruction*)sys_write)->addr;
*p = GetOSTrapAddress(_Write);
SetOSTrapAddress((long)&my_write,_Write);
if (TrapAvailable(_HWPriv)) FlushInstructionCache();
}
Stuart Cheshire <
[email protected]>
* <A HREF="file://brubeck.stanford.edu/www/cheshire-bio.html">WWW</A>
* Stanford Distributed Systems Group Research Assistant
* Escondido Village Resident Computer Coordinator
* Macintosh Programmer