: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];