:TITLE[AltoX];	*Alto/Mesa interface module
		*Ed Fiala 3 June 1982

%Places with code specific to the Mesa emulator but also needed by
the Alto emulator have been collected here.  To run the Alto emulator in
combination with, say, SmallTalk or Lisp, instead of Mesa, only this file,
GlobalDefs, and Fault need be edited or contain emulator-specific assembly
conditionals.  MesaP, MesaLS, MesaJ, MesaX, and MesaFP modules can then be
replaced by ones for the other emulator.
%

*These are the final two dispatch entries for the Alto emulator opcode
*dispatch at neMemI.  They appear here so that the SmallTalk emulator
*can define additional Alto opcodes for its own use.
	T ← (PCF.word) + 1, GoTo[IOUnIm], At[OpTab,16];	*70000-73777
	T ← (PCF.word) + 1, GoTo[IOUnIm], At[OpTab,17];	*74000-77777

*Save the current pc + 1 in memory location 527b and jump to location pointed
*to by location 530b + inst[3,7]
IOUnIm:	PCB ← (PCB) + T;
	PCF[IBuf] ← (LdF[PCF[IBuf],3,5]) + 1;
	T ← (R400) or (127C), GoTo[intXit];

%Opcodes 60000b to 63777b have been preceded by:
	LoadPage[xoPage], Disp[Cycle], At[OpTab,14];

Extended opcodes then have:

xoDisp:	Dispatch[PCF[IBuf],13,4], SkipP[R Odd], At[IO0Tab,4];	*61000-61177
OnPage[xoPage];
	  StkP ← rwpAC1, Disp[xoDir];
	StkP ← rwpAC1, Disp[xoEIR];
The Disp's above send control to one of 40b locations, of which the following
are not presently used.  NOTE: These first traps are particularly important
because new opcodes are being added in this area, so there will be transition
periods when new software will have to deal with older emulators that don't
implement new features.
%

:IF[xoTraps]; **********************************
*Traps for unimplemented opcodes in the range 61000b to 61037b
	LoadPage[nePage], GoTo[xoUnIm], At[xoTab1,6];	*61015b (Alto2 DREAD)
	LoadPage[nePage], GoTo[xoUnIm], At[xoTab0,7];	*61016b (Alto2 DWRITE)
	LoadPage[nePage], GoTo[xoUnIm], At[xoTab1,7];	*61017b (Alto2 DEXCH)
	LoadPage[nePage], GoTo[xoUnIm], At[xoTab0,14];	*61030b
	LoadPage[nePage], GoTo[xoUnIm], At[xoTab1,14];	*61031b
:ENDIF; ****************************************

:IF[neAltoTraps]; ******************************
*All the other opcodes in the 60000b-63777b range come through here;
*Cycle:	..., At[IO0Tab,0];	*60000-60177 (CYCLE in Alto.Mc)
	LoadPage[nePage], GoToP[xoUnIm], At[IO0Tab,1];	*60200
	LoadPage[nePage], GoToP[xoUnIm], At[IO0Tab,2];	*60400
	LoadPage[nePage], GoToP[xoUnIm], At[IO0Tab,3];	*60600
*	..., At[IO0Tab,4];	*61000-61177 (extended opcodes in Alto.Mc)
	LoadPage[nePage], GoToP[xoUnIm], At[IO0Tab,5];	*61200
	LoadPage[nePage], GoToP[xoUnIm], At[IO0Tab,6];	*61400
	LoadPage[nePage], GoToP[xoUnIm], At[IO0Tab,7];	*61600
	LoadPage[nePage], GoToP[xoUnIm], At[IO0Tab,10];	*62000
	LoadPage[nePage], GoToP[xoUnIm], At[IO0Tab,11];	*62200
	LoadPage[nePage], GoToP[xoUnIm], At[IO0Tab,12];	*62400
	LoadPage[nePage], GoToP[xoUnIm], At[IO0Tab,13];	*62600
	LoadPage[nePage], GoToP[xoUnIm], At[IO0Tab,14];	*63000
	LoadPage[nePage], GoToP[xoUnIm], At[IO0Tab,15];	*63200
	LoadPage[nePage], GoToP[xoUnIm], At[IO0Tab,16];	*63400
	LoadPage[nePage], GoToP[xoUnIm], At[IO0Tab,17];	*63600

%These are the undefined opcodes in the dispatch for 64000 - 67777.
They can be commented out with no harm, but trap instructions are used
here to reserve space for SmallTalk, which has opcodes in these positions.
Previous mi was
	T ← PCF[IBuf] or not T, Disp[JSRIIp];
%
	T ← (PCF.word) + 1, GoTo[IOUnIm], At[IO1Tab,0];	*64000
	T ← (PCF.word) + 1, GoTo[IOUnIm], At[IO1Tab,1];	*64200
*	..., At[IO1Tab,2];				*64400 (JSRII)
*	..., At[IO1Tab,3];				*64600 (JSRII)
*	..., At[IO1Tab,4];				*64600 (JSRIS)
*	..., At[IO1Tab,5];				*65200 (JSRIS)
	T ← (PCF.word) + 1, GoTo[IOUnIm], At[IO1Tab,6];	*65400
	T ← (PCF.word) + 1, GoTo[IOUnIm], At[IO1Tab,7];	*65600
	T ← (PCF.word) + 1, GoTo[IOUnIm], At[IO1Tab,10];	*66000
	T ← (PCF.word) + 1, GoTo[IOUnIm], At[IO1Tab,11];	*66200
	T ← (PCF.word) + 1, GoTo[IOUnIm], At[IO1Tab,12];	*66400
	T ← (PCF.word) + 1, GoTo[IOUnIm], At[IO1Tab,13];	*66600
*	..., At[IO1Tab,14];				*67000 (CONVERT)
*	..., At[IO1Tab,15];				*67200 (CONVERT)
:UNLESS[LispMode]; *****************************
*Used by Lisp
	T ← (PCF.word) + 1, GoTo[IOUnIm], At[IO1Tab,16];	*67400
:ENDIF; ****************************************
	T ← (PCF.word) + 1, GoTo[IOUnIm], At[IO1Tab,17];	*67600
:ENDIF;

:IF[LispMode]; *********************************
JMPRAM:	LoadPage[nePage], GoTo[xoUnIm], At[xoTab0,4];	*jmpram - 61010
xoUnIm:	T ← (PCF.word) + 1, GoToP[IOUnIm];	*Good programs never get here
:ELSE; *****************************************
JMPRAM:	T ← 20C, At[xoTab0,4];			*jmpram - 61010
	LU ← (RHMask[AC1]) xor T;
	LoadPage[nePage], Skip[ALU=0];
xoUnIm:	  T ← (PCF.word) + 1, GoToP[IOUnIm];	*Good programs never get here
	T ← AC0, LoadPage[MStartPage], GoToP[.+1];
OnPage[nePage];
	GoToP[MStart];
:ENDIF; ****************************************


%Bits 0:3 = engineering number (0 or 1 on Alto I, 2 on Alto II without
extended memory, 3 on Alto II with extended memory, 4 for D0, 5 for Dorado)
4:7 = build number as follows:
	0	Alto emulator only
	1	Alto Mesa
	2	PrincOps Mesa
	3	Cedar Mesa
	4	Lisp
	5	Smalltalk 76
	6	Smalltalk 78
	7	Butte
%
:IF[LispMode]; *********************************
xoVERS:	AC0 ← 42000C, GoTo[xoWRTRAM], At[xoTab0,6];	*vers - 61014
:ELSEIF[ButteMode]; ****************************
xoVERS:	AC0 ← 43400C, GoTo[xoWRTRAM], At[xoTab0,6];	*vers - 61014
:ELSE; *****************************************
xoVERS:	AC0 ← 40400C, GoTo[xoWRTRAM], At[xoTab0,6];	*vers - 61014
:ENDIF; ****************************************


*Code for Mesa exit and interrupt terminations from BitBlt

:UNLESS[LispMode]; *****************************
OnPage[bbPage];

*Enter MIPend knowing it will not return.
bbMesaInt:
	IntType ← 1C, Skip[ALU=0];	*IntType ← 1 (PC backup if stopping)
	  T ← bbDBMR, GoTo[bbAdvD];
	LoadPage[prPage];
**Worst case time since return is 17 cycles at entry to MIPend
	T ← (SStkP&NStkP) xor (377C), GoToP[MIPend];	*T ← StkP

bbMDone:	*Time to next opcode = 20 (Pilot), 30 or 33 (Alto Mesa)
	PFetch4[PCB,IBuf,0];	*Restore IBuf
  :IF[AltoMode]; *******************************
*In Alto mode, the opcode after BitBlt is the even byte of the next word,
*so if BitBlt occurs on an even byte, the next byte must be skipped.
	Cycle&PCXF, Skip[R Even];
	  CSkipData;	*Won't cause refill
	Stack&-2, LoadPage[opPage2];
	PFetch4[LOCAL,LocalCache0,4], GoToP[JSwapx];	*In MesaJ
  :ELSE; ***************************************
	Stack&-2, LoadPage[opPage0];
	PFetch4[LOCAL,LocalCache0,4], GoToP[P4Tail];
  :ENDIF; **************************************
:ENDIF; ****************************************

:END[AltoX];