Source to jet/vector.c


Enter a symbol's name here to quickly find it.

#include <Events.h>
#include <Memory.h>
#include <OSEvents.h>
#include <OSUtils.h>
#include <Timer.h>
#include <Traps.h>
#include <GestaltEqu.h>
#include <Retrace.h>

#include "jet.h"

/* constants */

/* #define ALT_TRAP 1		use non-standard trap numbers (for debugging) */ 
/* #define DOS_ONLY 1		only install dos trap handler (for debugging) */

#ifdef ALT_TRAP
#define DOS 0x84L
#define BIOS 0x88L
#define XBIOS 0x8CL
#define AES 0x90L
#define LINEA 0x94L
#else
#define DOS 0x84L
#define BIOS 0xb4L
#define XBIOS 0xb8L
#define AES 0x88L
#define LINEA 0x94L
#endif

#define BUS 8L
#define ADDR 12L
#define ILL 16L
#define DIV0 20L
#define TRACE 36L
#define PRIV 32L
#define CHECK 24L
#define TRAPV 28L

#define INTVEC 0x64

#define TIMERDELAY 20
#define VBLDELAY 1
#define FIVEDELAY 5

#define DOS_MAX 0x60
#define BIOS_MAX 0x10
#define XBIOS_MAX 0x30

/* forward declarations for functions buried in assembly language */
void nullFive(void);
void timerIntr(void);
void fiveIntr(void);

/* global variables */

short longframe;
long mintusp;
long macssp;
long mintssp;
long minta5;
short vm;
short swap;
short call_sr;
long call_pc;
long call_sp;
long call_regs[7];
short syscall_max;
void *syscall_tab;
short dos_max = DOS_MAX;
void *dos_tab[DOS_MAX];
short bios_max = BIOS_MAX;
void *bios_tab[BIOS_MAX];
short xbios_max = XBIOS_MAX;
void *xbios_tab[XBIOS_MAX];

sysvars sysvar;
long old_intr;
short intr_flag = 0;
short current_flag =0;
/* local variables */

static struct {
	/* fake cookie */
	short op;
	long addr;
	short dbg;
	/* fpu cookie */
	char fpu_sig[4];
	long fpu_val;
	/* cpu cookie */
	char cpu_sig[4];
	long cpu_val;
	/* sysvar cookie */
	char svar_sig[4];
	long svar_val;
	/* last cookie */
	long zero;
} mac_cookies = {
	0x4ef9, 0, 0xa9ff,
	"_FPU", 0,
	"_CPU", 0,
	"SVAR", 0,
	0
};

/*
 0 - tos version
 1 -
 2 -
 3 -
 4 -
 5 -
 6 -
 7 - language
 8 -
 9 - keyboard shift
10 - tos basepage
 */
static long sb2[11];

static struct sb1 {
	long res[2];
	long *sb2;
} sb1 = {
	{0, 0},
	sb2
};

static TMTask timerTask;
static TMTask fiveTask;
static VBLTask vblTask;

static long old_dos = 0, old_bios, old_xbios, old_aes, old_linea;
static long save_dos = 0, save_bios, save_xbios, save_aes, save_linea;
static long *save_cookies, save_intr;
static long old_bus, old_addr, old_ill, old_div0, old_trace;
static long save_bus, save_addr, save_ill, save_div0, save_trace;
static long old_priv, old_chk, old_trapv;
static long save_priv, save_chk, save_trapv;
static void (*save_timer)(void), (*save_five)(void), (*save_vbl)(void);

void badfn(short n)
{
	char msg[40], *s;

	if (syscall_tab == dos_tab)
		s = "DOS";
	else if (syscall_tab == bios_tab)
		s = "BIOS";
	else
		s = "XBIOS";

	sprintf(msg, "bad %s function call: 0x%x\r\n", s, n);
	c_conws(msg);
}

static void init_dos(void)
{
	old_dos = *(long *)DOS;
	save_dos = (long)dos;
    
	/* main */
	dos_tab[0x00] = p_term0;
	dos_tab[0x4c] = p_term;
	dos_tab[0x2c] = t_gettime;
	dos_tab[0x2a] = t_getdate;
	dos_tab[0x20] = s_uper;
	
	/* memory */
	dos_tab[0x48] = m_alloc;
	dos_tab[0x49] = m_free;
	dos_tab[0x4a] = m_shrink;
	dos_tab[0x44] = m_xalloc;

	/* filesys */
	dos_tab[0x3c] = f_create;
	dos_tab[0x41] = f_delete;
	dos_tab[0x56] = f_rename;
	dos_tab[0x43] = f_attrib;
	dos_tab[0x57] = f_datime;
	dos_tab[0x3d] = f_open;
	dos_tab[0x3e] = f_close;
	dos_tab[0x3f] = f_read;
	dos_tab[0x40] = f_write;
	dos_tab[0x42] = f_seek;
	dos_tab[0x46] = f_force;
	dos_tab[0x0e] = d_setdrv;
	dos_tab[0x19] = d_getdrv;
	dos_tab[0x47] = d_getpath;
	dos_tab[0x39] = d_create;
	dos_tab[0x3a] = d_delete;
	dos_tab[0x1a] = f_setdta;
	dos_tab[0x2f] = f_getdta;
	dos_tab[0x4e] = f_sfirst;
	dos_tab[0x4f] = f_snext;

	/* console */
	dos_tab[0x09] = c_conws;

}

static void init_bios(void)
{
	old_bios = *(long *)BIOS;
 	save_bios = (long)bios;

	bios_tab[0x01] = b_constat;
	bios_tab[0x08] = b_costat;
	bios_tab[0x02] = b_conin;
	bios_tab[0x03] = b_conout;
	bios_tab[0x0b] = b_kbshift;
	bios_tab[0x05] = b_setexc;
}

static void init_xbios(void)
{
	old_xbios = *(long *)XBIOS;
	save_xbios = (long)xbios;
 
	xbios_tab[0x02] = x_physbase;
	xbios_tab[0x03] = x_logbase;
	xbios_tab[0x0e] = x_iorec;
	xbios_tab[0x22] = x_kbdvbase;
	xbios_tab[0x2c] = x_bconmap;
	xbios_tab[0x26] = s_upexec;
	xbios_tab[0x10] = x_keytbl;
}

static void init_aes(void)
{
	old_aes = *(long *)AES;
	save_aes = (long)aes;
}

static void init_linea(void)
{
	old_linea = *(long *)LINEA;
	save_linea = (long)linea;
}

static void vblIntr(void)
{
	intr_flag = current_flag;
	vblTask.vblCount = VBLDELAY;
}

static void nullTimer(void)
{
	sysvar.hz200++;
}

void IntrService(void)
{
asm("
	.globl _timerIntr
_timerIntr:
/* if vm is on call dtime as deferred function, otherwise just call it */
	movel #_dtime,a0
	tstw	_vm
	bnes	timdef	
	jmp	a0@
timdef:	.word 0xa08f  /* this is the Deferred Trap */
	rts

	.globl _fiveIntr
_fiveIntr:
/* if vm is on call dfive as deferred function, otherwise just call it */
	movel #_dfive,a0
	tstw	_vm
	bnes	fivdef
	jmp	a0@
fivdef:	
	.word 0xa08f
	rts

	.globl _nullFive
_nullFive:
	rts	
");
}

void dtime(void)
{
	(*sysvar.timer)();
	PrimeTime((QElemPtr)&timerTask, TIMERDELAY);
}

void dfive(void)
{
	(*sysvar.five)();
	PrimeTime((QElemPtr)&fiveTask, FIVEDELAY);
}

#ifndef XXX
typedef TimerProcPtr TimerUPP;
#define NewTimerProc(userRoutine) (TimerUPP)(userRoutine)

typedef VBLProcPtr VBLUPP;
#define NewVBLProc(userRoutine) (VBLUPP)(userRoutine)
#endif

static void init_intr(void)
{
	old_intr = *(long *)INTVEC;
	save_intr = (long)intr;
	sysvar.timer = nullTimer;
	save_timer = nullTimer;
	sysvar.hz200 = 0;
	sysvar.ticks = 20L << 16;
	sysvar.five = nullFive;
	save_five = nullFive;
	sysvar.vbl = nullVBL;
	save_vbl = nullVBL;
	sysvar.vbls = 0;
	sysvar.vblq = 0;
	timerTask.tmAddr = NewTimerProc(timerIntr);
	timerTask.tmWakeUp = 0;
	timerTask.tmReserved = 0;
	fiveTask.tmAddr = NewTimerProc(fiveIntr);  /* this is the Deferred Trap */
	fiveTask.tmWakeUp = 0;
	fiveTask.tmReserved = 0;
	vblTask.qType = vType;
	vblTask.vblAddr = NewVBLProc(vblIntr);
	vblTask.vblCount = VBLDELAY;
	vblTask.vblPhase = 0;
#ifndef DOS_ONLY
	InsTime((QElemPtr)&timerTask);
	PrimeTime((QElemPtr)&timerTask, TIMERDELAY);
	InsTime((QElemPtr)&fiveTask);
	PrimeTime((QElemPtr)&fiveTask, FIVEDELAY);
	VInstall((QElemPtr)&vblTask);
#endif
}

static void init_ex(void)
{
	save_bus = old_bus = *(long *)BUS;
	save_addr = old_addr = *(long *)ADDR;
	save_ill = old_ill = *(long *)ILL;
	save_div0 = old_div0 = *(long *)DIV0;
	save_trace = old_trace = *(long *)TRACE;
	save_priv = old_priv = *(long *)PRIV;
	save_chk = old_chk = *(long *)CHECK;
	save_trapv = old_trapv = *(long *)TRAPV;
}

void init_vector(void)
{
	long response;
	sb2[0] = 0xffffffff;
	sb2[7] = 0;
	sb2[9] = (long)&kbshft;
	sb2[10] = (long)&curbp;
	mac_cookies.addr = (long)*_p_cookies;
	FlushInstructionCache();
	Gestalt(gestaltFPUType, &response);
	mac_cookies.fpu_val = (response + 1) << 16;
	Gestalt(gestaltProcessorType, &response);
	mac_cookies.cpu_val = (response - 1) * 10;
	longframe = mac_cookies.cpu_val == 0 ? 0 : 1;
	mac_cookies.svar_val = (long)&sysvar;
	save_cookies = (long *)&mac_cookies;
	sysvar.version = SVAR_VERS;
	sysvar.sysbase = (long)&sb1;
	sysvar.saveda5 = saveda5;
	sysvar.savedsp = savedsp;
	sysvar.mac_env = mac_env;
	sysvar.mint_env = mint_env;
	sysvar.vm = vm;
	init_dos();
	init_bios();
	init_xbios();
	init_aes();
	init_linea();
	init_intr();
	init_ex();
	if (!vm && (mac_cookies.cpu_val == 40 || sysvar.powerpc)) 
		asm(".word 0x4e7a,0x807,0x4e7b,0x806" : : : "d0");
}

void put_vector(void)
{
	unsigned short sr;

	if (old_dos) {
		sr = spl7();
		sysvar.timer = save_timer;
		sysvar.five = save_five;
		sysvar.vbl = save_vbl;
		current_flag = 1;
		*_p_cookies = save_cookies;
		*(long *)DOS = save_dos;
#ifndef DOS_ONLY
 		*(long *)BIOS = save_bios;
		*(long *)XBIOS = save_xbios;
		*(long *)AES = save_aes;
		*(long *)LINEA = save_linea;
		*(long *)INTVEC = save_intr;
		*(long *)BUS = save_bus;
		*(long *)ADDR = save_addr;
		*(long *)ILL = save_ill;
		*(long *)DIV0 = save_div0;
		*(long *)PRIV = save_priv;
		*(long *)CHECK = save_chk;
		*(long *)TRAPV = save_trapv;
#endif
		*(long *)TRACE = save_trace;
		spl(sr);
	}
}

void pull_vector(void)
{
	unsigned short sr;

	if (old_dos) {
		sr = spl7();
		intr_flag = 0;
		current_flag = 0;
		save_timer = sysvar.timer;
		save_five = sysvar.five;
		save_vbl = sysvar.vbl;
		save_cookies = *_p_cookies;
		save_dos = *(long *)DOS;
#ifndef DOS_ONLY
		save_bios = *(long *)BIOS;
		save_xbios = *(long *)XBIOS;
		save_aes = *(long *)AES;
		save_linea = *(long *)LINEA;
		save_intr = *(long *)INTVEC;
		save_bus = *(long *)BUS;
		save_addr = *(long *)ADDR;
		save_ill = *(long *)ILL;
		save_div0 = *(long *)DIV0;
		save_priv = *(long *)PRIV;
		save_chk = *(long *)CHECK;
		save_trapv = *(long *)TRAPV;
#endif
		save_trace = *(long *)TRACE;
		sysvar.timer = nullTimer;
		sysvar.five = nullFive;
		sysvar.vbl = nullVBL;
		*_p_cookies = (long *)mac_cookies.addr;
		*(long *)DOS = old_dos;
#ifndef DOS_ONLY
		*(long *)BIOS = old_bios;
		*(long *)XBIOS = old_xbios;
		*(long *)AES = old_aes;
		*(long *)LINEA = old_linea;
		*(long *)INTVEC = old_intr;
		*(long *)BUS = old_bus;
		*(long *)ADDR = old_addr;
		*(long *)ILL = old_ill;
		*(long *)DIV0 = old_div0;
		*(long *)PRIV = old_priv;
		*(long *)CHECK = old_chk;
		*(long *)TRAPV = old_trapv;
#endif
		*(long *)TRACE = old_trace;
		spl(sr);
	}
}