mirror of
https://github.com/livingcomputermuseum/Darkstar.git
synced 2026-02-28 17:39:41 +00:00
39 lines
9.6 KiB
Plaintext
39 lines
9.6 KiB
Plaintext
head 1.1;
|
||
branch 1.1.1;
|
||
access ;
|
||
symbols start:1.1.1.1 Xerox:1.1.1;
|
||
locks ; strict;
|
||
comment @# @;
|
||
|
||
|
||
1.1
|
||
date 2001.08.12.22.22.20; author freier; state Exp;
|
||
branches 1.1.1.1;
|
||
next ;
|
||
|
||
1.1.1.1
|
||
date 2001.08.12.22.22.20; author freier; state Exp;
|
||
branches ;
|
||
next ;
|
||
|
||
|
||
desc
|
||
@@
|
||
|
||
|
||
|
||
1.1
|
||
log
|
||
@Initial revision
|
||
@
|
||
text
|
||
@{File name: CoreInitial.mc
|
||
Description: Core of the initial microcode booting sequence,
|
||
Author: PXJ ,
|
||
Created: November 12, 1980,
|
||
Last Edited: RDH, 1-Oct-86 14:27:50 Clear double bit memory parity error flag for emulator task before testing for extended VM support.
|
||
Last Edited: CRF, 23-Sep-86 18:49:51 Add IOPage.extendedVMSupport BOOLEAN.
|
||
Last Edited: Dennis DEG , 8-Oct-84 11:48:51 Place VMMSize in IOPage location 2006F hex or offset 111 decimal.
|
||
Last Edited: Dennis DEG , 1-Sep-84 21:53:22 Add copyright notice
|
||
Last Edited: AeF AEF , 27-Sep-83 15:21:23 Modify for 24-bit VA space
|
||
Last Edited: ETN , April 2, 1982 6:28 PM @@ TridentInit elim use of U0400.
|
||
Last Edited: ETN , December 11, 1981 9:59 AM Eliminated mapZap subr.
|
||
Last Edited: ETN , November 13, 1981 3:47 PM Added Trident Switch.
|
||
Last Edited: PXJ , March 21, 1981 8:39 AM}
|
||
|
||
Reserve[ProtectStart, ProtectFence], Reserve[0FE0, 0FFF]; {save room for boot kernel}
|
||
|
||
{ Copyright (C) 1981, 1982, 1983 by Xerox Corporation. All rights reserved. }
|
||
|
||
|
||
SetTask[0], StartAddress[go];
|
||
|
||
go: MCtl¬ 0, CANCELBR[$, 0F], c1;
|
||
IOPCtl¬ 0, c2;
|
||
IfGreater[Config,1,SkipTo[TridentInit],];
|
||
|
||
KCtl¬ 0, c3; {SAx000}
|
||
SkipTo[NoTridentInit];
|
||
|
||
TridentInit!
|
||
RCnt ¬ 0F, c3; {Trident}
|
||
KCtl ¬ RCnt LRot12, c1; {Trident}
|
||
acR ¬ 4, c2; {Trident}
|
||
KCmd ¬ acR LRot8, c3; {Trident}
|
||
|
||
NoTridentInit!
|
||
|
||
DCtl ¬ 3, c1; {display black, enable task}
|
||
PCtl ¬ 0, c2;
|
||
EICtl ¬ 0, c3;
|
||
EOCtl ¬ 0, c1;
|
||
Noop, c2;
|
||
GOTO[mapInit], c3;
|
||
|
||
{map initialization goes on during this interval}
|
||
|
||
mapRet:
|
||
{clear all but the first two pages of bank 0}
|
||
acR¬ 0, c2;
|
||
passTraps¬ acR, c3;
|
||
rD¬ 2, c1;
|
||
rD¬ rD LRot8, c2;
|
||
rDrh¬ 0, c3;
|
||
|
||
clear: MAR¬ [rDrh, rD+0], c1;
|
||
MDR¬ acR, rD¬ rD+1, ZeroBr, c2;
|
||
BRANCH[clear, $], c3;
|
||
|
||
Noop, c1;
|
||
acR¬ 0FF+1, c2;
|
||
uBootStart¬ acR, GOTO[OnceOnlyInit], c3;
|
||
|
||
{OnceOnlyInit transfers control to DoneOnceOnlyInit. DoneOnceOnlyInit lives in the device specific initial microcode. When that finishes, control passes to exitToEmulator.}
|
||
|
||
exitToEmulator:
|
||
Noop, c1;
|
||
rErh ¬ IOPageHigh, c2;
|
||
|
||
{make sure the display is off when the germ starts}
|
||
DPYOff: acR¬ RShift1 0, SE¬ 1, c3; {acR¬ 8000}
|
||
rE¬ uIOPage, c1; {IOPage real address}
|
||
rB¬ mapPages, c2;
|
||
rBrh¬ 0, c3;
|
||
|
||
MAR¬ [rErh, IOPage.DSCB.syncCmd+0], c1;
|
||
MDR¬ acR, c2;
|
||
rB ¬ rB LRot8, c3; {VMMSize is equivalent to mapPages LRot8}
|
||
|
||
SetVMMSize: MAR¬ [rErh, IOPage.VMMSize+0], c1;
|
||
MDR¬ rB, c2; {VMMSize is set by constant declarations in Dandelion.dfn}
|
||
rB ¬ uExtendedVM, c3;
|
||
|
||
MAR¬ [rErh, IOPage.extendedVMSupport+0], c1;
|
||
MDR¬ rB, c2;
|
||
enableIOP: rB ¬ 0, c3; {Set rB to its real value: 0}
|
||
|
||
MAR¬ [rBrh, 0+0], c1;
|
||
MDR¬ 0FF, c2;
|
||
Noop, c3;
|
||
|
||
|
||
MAR¬ [rBrh, 0+1], c1;
|
||
MDR¬ uBootStart, CANCELBR[$, 0], c2;
|
||
IOPCtl¬ IOPInMode, GOTOABS[IdleLoc], c3;
|
||
|
||
{subroutines and end matter}
|
||
|
||
{Map initialization -- Sets up map and leaves next available page in topPage. Start looking for pages before 768K, i.e., below bank 0C. Does not map any pages in bank 0.
|
||
|
||
Beware -- clobbers the first word of each page in bank 0 even though you don't mean it!!!!!!!!!!!!!!!!!!!!!!!!
|
||
|
||
Write page number in the first word of each page. Go through memory top down to give lower addresses precedence
|
||
|
||
Register usage
|
||
acR page number
|
||
rB memory address register
|
||
rC temporary
|
||
rD temporary
|
||
rE next available page}
|
||
|
||
mapInit: rBrh¬ 0C, {start in bank 0B} c1;
|
||
rB¬ 0, c2; {address within bank}
|
||
acR¬ rB-1, c3;
|
||
passTraps¬ acR, c1; {catch faults}
|
||
acR¬ 0C, c2;
|
||
acR¬ acR LRot8, c3; {page counter}
|
||
Noop, c1;
|
||
GOTO[mark1], c2;
|
||
|
||
{mark the first word of each page with its page number}
|
||
markPages: MAR¬ [rBrh, rB+0], c1;
|
||
MDR¬ acR, c2;
|
||
mark1: acR¬ acR-1, NegBr, c3; {written all pages?}
|
||
rC¬ 0FF+1, BRANCH[$, mapBuild], c1;
|
||
rC¬ rB-rC, CarryBr, c2;
|
||
rB¬ rC, BRANCH[$, markPages], c3;
|
||
rB¬ rBrh, c1;
|
||
rB¬ rB-1, c2;
|
||
rBrh¬ rB LRot0, c3;
|
||
rB¬ rC, c1;
|
||
Noop, c2;
|
||
GOTO[markPages], c3;
|
||
|
||
mapBuild: Noop, c2;
|
||
Noop, c3;
|
||
rBrh¬ 1, c1;
|
||
rC¬ 1 {TRUE for "uExtendedVM ¬" below}, c2;
|
||
rB¬ 0, c3;
|
||
|
||
{make all pages vacant}
|
||
MAR¬ [rBrh, rB+0], c1;
|
||
MDR¬ vacant, c2;
|
||
rErh ¬ 0F0, c3;
|
||
|
||
{Do a trial Map operation using a large address. If the Map doesn't trap, our CP board supports large virtual memory, so we set the extendedVMSupport BOOLEAN to TRUE. If the Map traps, we will catch the trap and eventually return to mapOutOfBound, where we set the BOOLEAN to FALSE for an older CP board. Note that this version of the microcode sets the size of the VM map to the static constant mapPages from Dandelion.dfn, which allows using a small 22-bit VM even if the hardware supports extended VM. This saves on real memory since the VM map is smaller.}
|
||
|
||
{To distinguish between Map trap and double bit memory parity trap, we must first clear the memory parity error bit for this task emulator task. i.e. Do an MCtl¬ 800}
|
||
acR ¬ 8, c1;
|
||
acR ¬ acR LRot8, c2;
|
||
MCtl¬ acR, c3;
|
||
Map ¬ [rErh, rE], c1;
|
||
Noop, c2;
|
||
uExtendedVM ¬ rC {TRUE}, GOTO[largeVMOK], c3;
|
||
|
||
mapOutOfBound: {only supports 22-bit vm}
|
||
uExtendedVM ¬ 0 {FALSE}, c3;
|
||
|
||
largeVMOK:
|
||
acR¬ mapPages, c1;
|
||
rBrh¬ 1, c2;
|
||
rC¬ rCrh¬ 1, c3;
|
||
|
||
acR¬ acR LRot8, L0¬ 0A, c1;
|
||
acR¬ acR-1, c2;
|
||
rB ¬ 0, GOTO[BLT], c3;
|
||
|
||
{Set up the rE pair with the real address of the virtual memory map and the rB pair with the real address of the first location to be mapped. acR must contain the page number of the first real page to be mapped.}
|
||
|
||
rErh ¬ MapRealAddrHigh, c1, at[0A, 10, subrRet];
|
||
rE ¬ MapRealAddrLow, c2;
|
||
rBrh ¬ rB ¬ FirstRealPageToMapHigh, c3;
|
||
|
||
acR ¬ rB LRot8, {construct page number in acR} c1;
|
||
rC ¬ FirstRealPageToMap, c2;
|
||
rB ¬ rC LRot8, c3;
|
||
|
||
acR ¬ acR or rC, c1;
|
||
Noop, c2;
|
||
|
||
{Check if the page has its own page number in the first location of the page.}
|
||
mapLoop3:
|
||
Noop, c3;
|
||
|
||
mapLoop1:
|
||
MAR¬ [rBrh, rB+0], c1;
|
||
Noop, c2;
|
||
rC ¬ MD, {double bit error possible here} c3;
|
||
|
||
[] ¬ rC xor acR, ZeroBr, c1;
|
||
rC ¬ IOPageHigh, BRANCH[nextReal3, $], c2;
|
||
|
||
{Check if this is the page number of the IOPage. If so, then do not map this real page yet. Go on to the next real page.}
|
||
|
||
rC ¬ rC LRot8, c3;
|
||
|
||
rC ¬ rC or IOPage, c1;
|
||
[] ¬ rC xor acR, ZeroBr, c2;
|
||
rC ¬ IOPageVirtual, BRANCH[NotIOPageReal, IsIOPageReal], c3;
|
||
|
||
IsIOPageReal:
|
||
Noop, c1;
|
||
GOTO[nextReal3], c2;
|
||
|
||
{Check if this is the virtual map entry for the IOPage. If so, map the IOPage to this map entry. Do not increment the real page number.}
|
||
|
||
NotIOPageReal:
|
||
[] ¬ rC xor rE, NZeroBr, c1;
|
||
Noop, BRANCH[$, NotIOPageVirt], c2;
|
||
|
||
MapIOPage:
|
||
rC ¬ IOPage, c3;
|
||
|
||
rC ¬ IOPage, c1;
|
||
rC ¬ rC LRot8, c2;
|
||
rC ¬ rC or IOPageHigh, c3;
|
||
|
||
MAR¬ [rErh, rE + 0], c1;
|
||
MDR¬ rC or present, c2;
|
||
rE ¬ rE + 1, GOTO[mapLoop1], c3;
|
||
|
||
{Map this page in.}
|
||
NotIOPageVirt:
|
||
topPage¬ rB, c3;
|
||
|
||
rB¬ rB or rBrh, c1;
|
||
rC¬ rB, c2;
|
||
rB¬ topPage, c3;
|
||
|
||
MAR¬ [rErh, rE + 0], c1;
|
||
MDR¬ rC or present, c2;
|
||
rE ¬ rE + 1, GOTO[nextReal1], c3;
|
||
|
||
nextReal3:
|
||
Noop, c3;
|
||
nextReal1:
|
||
acR ¬ acR + 1, GOTO[IncReal], c1;
|
||
nextReal:
|
||
Noop, c1;
|
||
IncReal:
|
||
rC ¬ 0FF + 1, c2;
|
||
rC¬ rB+rC, CarryBr, c3;
|
||
|
||
rB¬ rBrh, BRANCH[$, nextBank], c1;
|
||
rB¬ rC, GOTO[mapLoop3], c2;
|
||
|
||
nextBank:
|
||
rB¬ rB+1, c2;
|
||
[]¬ rB xor 0C, ZeroBr, c3;
|
||
|
||
rBrh¬ rB LRot0, BRANCH[$, clearMem], c1;
|
||
rB¬ rC, GOTO[mapLoop3], c2;
|
||
|
||
{clear all mapped pages}
|
||
clearMem:
|
||
topPage¬ rE, c2; {save away}
|
||
rE¬ 0, c3; {word offset}
|
||
rD¬ 0, c1; {source of zero}
|
||
passTraps¬ rD, {die on double bit errors} c2;
|
||
Noop, c3;
|
||
|
||
clearLoop: MAR¬ [rErh, rE+0], c1; {read the map}
|
||
rC¬ 0, c2;
|
||
acR¬ MD, c3;
|
||
|
||
rB¬ acR and 0F, c1;
|
||
rBrh¬ rB LRot0, c2;
|
||
rB¬ acR and ~0FF, c3;
|
||
|
||
{write into every word of the page}
|
||
clearPage: MAR¬ [rBrh, rC+0], c1;
|
||
MDR¬ rD, rC¬ rC+1, PgCarryBr, c2;
|
||
acR¬ topPage, BRANCH[clearPage, $], c3;
|
||
|
||
rE¬ rE+1, c1;
|
||
[]¬ rE xor acR, ZeroBr, c2; {compare to topPage}
|
||
BRANCH[clearLoop, $], c3;
|
||
|
||
GOTO[mapRet], c1;
|
||
|
||
{trap catcher, gets here with rC¬ RRot1 ErrnIBnStkp}
|
||
error: Xbus¬ rC LRot0, XwdDisp, c2, at[ErrorHandlerLoc];
|
||
DISP2[errorType], c3;
|
||
|
||
GOTO[death], {control store parity error} c1, at[0, 4, errorType];
|
||
Xbus¬ MStatus, XLDisp, GOTO[memFault], c1, at[1, 4, errorType];
|
||
GOTO[death], {stack error} c1, at[2, 4, errorType];
|
||
GOTO[death], {instruction buffer empty} c1, at[3, 4, errorType];
|
||
death: GOTO[death], c*;
|
||
|
||
memFault: BRANCH[mapOutOfBound, $, 1], c2; {map out of bound?}
|
||
GOTO[nextReal], c3; {no, double bit error}
|
||
|
||
{block transfer, takes count in acR, from in rB, and to in rC, returns first word past from block in rE}
|
||
BLT2: Noop, c2;
|
||
BLT3: Noop, c3;
|
||
BLT: MAR¬ [rBrh, rB+0], c1;
|
||
[]¬ acR, ZeroBr, c2;
|
||
rE¬ MD, BRANCH[$, endBLT], c3;
|
||
MAR¬ [rCrh, rC+0], c1;
|
||
MDR¬ rE, c2;
|
||
acR¬ acR-1, c3;
|
||
rB¬ rB+1, c1;
|
||
rC¬ rC+1, c2;
|
||
GOTO[BLT], c3;
|
||
endBLT: Noop, c1;
|
||
endBLT1: pRet0, c2;
|
||
endBLT2: RET[subrRet], c3;
|
||
|
||
{******* Not used anymore
|
||
{takes count in acR, virtual page number in rE, and map entry in rC. Beware, rErh better have a 1 !!!!}
|
||
mapZap3: Noop, c3;
|
||
mapZap: MAR¬ [rErh, rE+0], c1;
|
||
MDR¬ rC or present, c2; {referenced and present}
|
||
rC¬ rC+0FF+1, c3;
|
||
rE¬ rE+1, c1;
|
||
acR¬ acR-1, ZeroBr, c2;
|
||
BRANCH[mapZap, $], c3;
|
||
Noop, c1;
|
||
endMisc1: pRet0, c2;
|
||
endMisc2: RET[miscRet], c3;
|
||
*********}
|
||
{swaps two locations in memory, takes address in rE and rB, clobbers acR}
|
||
memSwap2: Noop, c2;
|
||
memSwap3: Noop, c3;
|
||
memSwap: MAR¬ [rErh, rE+0], c1;
|
||
Noop, c2;
|
||
acR¬ MD, c3;
|
||
MAR¬ [rBrh, rB+0], c1;
|
||
MDR¬ acR, c2;
|
||
acR¬ MD, c3;
|
||
MAR¬ [rErh, rE+0], c1;
|
||
MDR¬ acR, pRet0, c2;
|
||
RET[subrRet], c3;@
|
||
|
||
|
||
1.1.1.1
|
||
log
|
||
@first add
|
||
@
|
||
text
|
||
@@
|