//MesaX.bcpl - XM support for RunMesa - R. Levin //last modified by Levin: October 17, 1978 10:41 AM get "Mesa.d" external [ MoveBlock; Zero ] // OS external [ DetermineConfiguration ] //exported to Mesa.bcpl manifest [ WakeupsWaiting = #452 Active = #453 ] manifest [ EmulatorBR = #177740 ] structure BankRegister: [ unused bit 12 primary bit 2 alternate bit 2 ] let DetermineConfiguration() be [DetermineConfiguration manifest bank0only = #10 let vers=table [ #61014 //VERS #1401 //JMP 1 3 ] let engineeringNumber = vers() rshift 12 Zero(HardwareConfiguration,lHardwareInfo) test engineeringNumber eq 0 ifso HardwareConfiguration>>HardwareInfo.AltoType = 1 ifnot HardwareConfiguration>>HardwareInfo.AltoType = engineeringNumber HardwareConfiguration>>HardwareInfo.useXM = false HardwareConfiguration>>HardwareInfo.banks = bank0only // bank 0 only HardwareConfiguration>>HardwareInfo.secondROM = false HardwareConfiguration>>HardwareInfo.mesaMicrocodeVersion = 0 HardwareConfiguration>>HardwareInfo.XMMicrocodeVersion = 0 if (HardwareConfiguration>>HardwareInfo.AltoType < 2) % (HardwareConfiguration>>HardwareInfo.AltoType > 3) then return // ignore pseudo-Altos ROMVersion() if HardwareConfiguration>>HardwareInfo.AltoType ne 3 then return let banksAvailable = FindMemoryBanks() HardwareConfiguration>>HardwareInfo.banks = banksAvailable HardwareConfiguration>>HardwareInfo.useXM = (banksAvailable ne bank0only) & HardwareConfiguration>>HardwareInfo.secondROM & (HardwareConfiguration>>HardwareInfo.XMMicrocodeVersion ne 0) ]DetermineConfiguration and let ROMVersion() be [ROMVersion manifest [ RealRAMloc = #300; PossibleRAMloc = #777-1 ] manifest highword = #2000 let versionTable = table [ 34 ] let saveRealRAM = vec 3 let savePossibleRAM = vec 3 let WriteOne=table [ // (high,address,low) #55001 //STA 3 1 2 #35003 //LDA 3 3 2 #61012 //WRTRAM #35001 //LDA 3 1 2 #1401 //JMP 1 3 ] let ReadOne=table [ // (pointer,address) #55001 //STA 3 1 2 #115000 //MOV 0 3 #61011 //RDRAM #41400 //STA 0 0 3 #35001 //LDA 3 1 2 #1401 //JMP 1 3 ] let JmpRAM=table [ #61010 //JMPRAM #1401 //JMP 1 3 ] let initCP = table [ #100; #170301; // L←ALLONES, SWMODE, :x1; #60110; #102020; // x1: cp←L, :START; ] let getVersionCode = table [ #60110; #102020; // x2: cp←L,:START; #60; #170776; // L←-2, SWMODE,:x2; ] let readCP = table [ #60060; #100301; // L←cp, SWMODE, :x3; #14030; #102020; // x3: AC0←L, :START; ] ReadOne(saveRealRAM,highword+RealRAMloc); ReadOne(saveRealRAM+1,RealRAMloc); ReadOne(saveRealRAM+2,highword+RealRAMloc+1); ReadOne(saveRealRAM+3,RealRAMloc+1); WriteOne(initCP!0,RealRAMloc,initCP!1); WriteOne(initCP!2,RealRAMloc+1,initCP!3); JmpRAM(0,RealRAMloc); // cp ← -1 ReadOne(savePossibleRAM,highword+PossibleRAMloc); ReadOne(savePossibleRAM+1,PossibleRAMloc); ReadOne(savePossibleRAM+2,highword+PossibleRAMloc+1); ReadOne(savePossibleRAM+3,PossibleRAMloc+1); WriteOne(getVersionCode!0,PossibleRAMloc,getVersionCode!1); WriteOne(getVersionCode!2,PossibleRAMloc+1,getVersionCode!3); JmpRAM(0,PossibleRAMloc+1); WriteOne(savePossibleRAM!0,PossibleRAMloc,savePossibleRAM!1); WriteOne(savePossibleRAM!2,PossibleRAMloc+1,savePossibleRAM!3); WriteOne(readCP!0,RealRAMloc,readCP!1); WriteOne(readCP!2,RealRAMloc+1,readCP!3); let valCP = JmpRAM(0,RealRAMloc); WriteOne(saveRealRAM!0,RealRAMloc,saveRealRAM!1); WriteOne(saveRealRAM!2,RealRAMloc+1,saveRealRAM!3); switchon valCP into [VersionCases case -2: // no ROM on machine [ endcase ] case -1: // Mesa 4.1 ROM on machine [ HardwareConfiguration>>HardwareInfo.mesaMicrocodeVersion = versionTable!0 HardwareConfiguration>>HardwareInfo.secondROM = true endcase ] default: // some other ROM on machine [ HardwareConfiguration>>HardwareInfo.secondROM = true if (valCP & #100000) ne 0 then [GetXM let version = 0 let val = valCP while (val & #100000) ne 0 do [loop version = version+1 val = val lshift 1 ]loop valCP = valCP & (#177777 rshift version) HardwareConfiguration>>HardwareInfo.XMMicrocodeVersion = version ]GetXM HardwareConfiguration>>HardwareInfo.mesaMicrocodeVersion = versionTable!valCP endcase ] ]VersionCases ]ROMVersion and let FindMemoryBanks() = valof [FindMemoryBanks manifest testlocation = 0 let bitToSet = #4 // start with bank 1 let bankbits = #10 // bank 0 always present let savedActive = @Active let GetAlternateBank=table [ #61025 //XMLDA #1401 //JMP 1 3 ] let SetAlternateBank=table [ #61026 //XMSTA #1401 //JMP 1 3 ] @Active = 0 EmulatorBR>>BankRegister.alternate = 0 until bitToSet eq 0 do [ EmulatorBR>>BankRegister.alternate = EmulatorBR>>BankRegister.alternate+1 let oldval = GetAlternateBank(0,testlocation) SetAlternateBank(oldval+1,testlocation) if GetAlternateBank(testlocation) eq oldval+1 then [ bankbits = bankbits % bitToSet; ClearBank() ] bitToSet = bitToSet rshift 1 ] @WakeupsWaiting = 0 @Active = savedActive resultis bankbits ]FindMemoryBanks and let ClearBank() be // will be unnecessary when Alto OS does it for us [ClearBank manifest BBTlength = 16 let BitBltTable = vec BBTlength // extra word for even alignment // Clears pages [0..253]; pages 254-255 are I/O registers let InitialBBT = table [ #34 // dest in alternate bank, gray, replace #0 // unused #0 // dest address 256*2 // length of scan line (words) #0 // dest block X-offset (bits) #0 // dest block Y-offset (scan lines) 256*2*16 // dest block width (bits) [2 pages wide] 127 // dest block height (scan lines) #0; #0; #0; #0 // source info not relevant #0; #0; #0; #0 // gray ] let DoBitBLT=table [ #54411 //STA 3 savedAC3 #50407 //STA 2 savedAC2 #111000 //MOV 0 2 #126400 //SUB 1 1 #61024 //BITBLT #30403 //LDA 2 savedAC2 #34403 //LDA 3 savedAC3 #1401 //JMP 1 3 #0 //savedAC2 #0 //savedAC3 ] BitBltTable = BitBltTable + (BitBltTable & 1) // ensure even word alignment MoveBlock(BitBltTable,InitialBBT,BBTlength) DoBitBLT(BitBltTable) ]ClearBank