mirror of
https://github.com/PDP-10/its.git
synced 2026-03-04 02:35:00 +00:00
12144 lines
369 KiB
Plaintext
Executable File
12144 lines
369 KiB
Plaintext
Executable File
.ABS
|
||
VERN==%FNAM2
|
||
%COMPAT==0 ;SUPRESS INCOMPATABLE OP-CODE MESSAGES
|
||
NPC==0
|
||
NTKDIS==0
|
||
TVS==0
|
||
NTVS==0
|
||
NTVCHN==0
|
||
MBFLG==0
|
||
.INSRT SITS;SITMAC >
|
||
.IIF NDF GUY,GUY==0
|
||
|
||
.IF Z GUY
|
||
NTKDIS==4
|
||
TVS==1
|
||
MBFLG==1
|
||
.ENDC
|
||
.IFNZ TVS
|
||
NTVS==32.
|
||
NTVCHN==4
|
||
.ENDC
|
||
.SBTTL INTERNAL REGISTER DEFINITIONS
|
||
;MEMORY SEGMENTATION UNIT
|
||
SSR0=177572
|
||
SSR1=177574
|
||
SSR2=177576
|
||
SSR3=172516
|
||
USRISD=177600
|
||
USRDSD=177620
|
||
USRISA=177640
|
||
USRDSA=177660
|
||
SUPISD=172200
|
||
SUPDSD=172220
|
||
SUPISA=172240
|
||
SUPDSA=172260
|
||
KERISD=172300
|
||
KERDSD=172320
|
||
KERISA=172340
|
||
KERDSA=172360
|
||
|
||
;SEGMENTATION REGISTER DEFINITION
|
||
SEGNRA==100000 ;SEGMENTATION NON RESIDENT ABORT
|
||
SEGSLE==40000 ;SEGMENT LENGTH ERROR
|
||
SEGRVI==20000 ;READ ONLY VIOLATION
|
||
SEGTRP==10000 ;SEGMENTATION TRAP
|
||
SEGPMO==177637 ;PAGE MODE THAT CAUSED TRAP
|
||
SEGKER==0 ;KERNEL MODE
|
||
SEGUSR==140 ;USER MODE
|
||
SEGPNO==177741 ;THE PAGE NO. MASK
|
||
|
||
;CONSOLE SWITCHES AND DISPLAY
|
||
CDISP=177570
|
||
CSWR=177570
|
||
|
||
;PROGRAM INTERUPT REQUEST REGISTER
|
||
PIRQ=177772
|
||
|
||
;STACK LIMIT REGISTER
|
||
STKLIM=177774
|
||
|
||
;PROCESSOR STATUS
|
||
PS=177776
|
||
|
||
;START OF PARITY REGISTERS
|
||
PARCSR=172100
|
||
|
||
RUGST==157000 ;RUG STARTING LOCATION
|
||
;KERNAL MAP REGISTERS
|
||
I0AR=KERISA
|
||
I1AR=I0AR+2
|
||
I2AR=I1AR+2
|
||
I3AR=I2AR+2
|
||
I4AR=I3AR+2
|
||
I5AR=I4AR+2
|
||
I6AR=I5AR+2
|
||
I7AR=I6AR+2
|
||
RUGIAR=I6AR
|
||
|
||
I0DR=KERISD
|
||
I1DR=I0DR+2
|
||
I2DR=I1DR+2
|
||
I3DR=I2DR+2
|
||
I4DR=I3DR+2
|
||
I5DR=I4DR+2
|
||
I6DR=I5DR+2
|
||
I7DR=I6DR+2
|
||
RUGIDR=I6DR
|
||
|
||
VAR0AR=KERDSA
|
||
VAR1AR=VAR0AR+2
|
||
VAR2AR=VAR1AR+2
|
||
ITM0AR=VAR2AR+2
|
||
ITM1AR=ITM0AR+2
|
||
ITM2AR=ITM1AR+2
|
||
RUGDAR=ITM2AR+2
|
||
IOAR=RUGDAR+2
|
||
|
||
VAR0DR=KERDSD
|
||
VAR1DR=VAR0DR+2
|
||
VAR2DR=VAR1DR+2
|
||
ITM0DR=VAR2DR+2
|
||
ITM1DR=ITM0DR+2
|
||
ITM2DR=ITM1DR+2
|
||
RUGDDR=ITM2DR+2
|
||
IODR=RUGDDR+2
|
||
|
||
;INTERNAL TRAP VECTORS
|
||
BEBRV=4
|
||
ILLBRV=10
|
||
BPTBRV=14
|
||
IOTBRV=20
|
||
PWFBRV=24
|
||
EMTBRV=30
|
||
TRPBRV=34
|
||
PARBRV=114
|
||
PIRBRV=240
|
||
FPPBRV=244
|
||
SEGBRV=250
|
||
.SBTTL DEVICE DEFINITIONS
|
||
;RF11 FIXED HEAD DISK
|
||
RFCS=177460 ;CONTROL AND STATUS
|
||
RFWC=177462 ;WORD COUNT
|
||
RFBA=177464 ;BUSS ADDRESS
|
||
RFDA=177466 ;DISK ADDRESS (LOW PART)
|
||
RFDAE=177470 ;HIGH PART OF ADDRESS AND ERROR REGISTER
|
||
RFBRV=204
|
||
|
||
;RK11 MOVING HEAD DISK
|
||
RKDS=177400 ;DRIVE STATUS REGISTER
|
||
RKER=177402 ;ERROR REGISTER
|
||
RKCS=177404 ;CONTROL AND STATUS REGISTER
|
||
RKWC=177406 ;WORD COUNT
|
||
RKBA=177410 ;BUSS ADDRESS
|
||
RKDA=177412 ;DISK ADDRESS
|
||
RKBRV=220
|
||
|
||
;CONSOLE TELETYPE
|
||
;BREAK LEVEL 4
|
||
TKBRV=60 ;CONSOLE KEYBOARD BREAK VECTOR
|
||
TKS=177560 ;CONSOLE KEYBOARD STATUS
|
||
TKB=177562 ;CONSOLE KEYBOARD DATA
|
||
TPBRV=64 ;CONSOLE PRINTER BREAK VECTOR
|
||
TPS=177564 ;CONSOLE PRINTER STATUS
|
||
TPB=177566 ;CONSOLE PRINTER DATA
|
||
|
||
|
||
;PROGRAMMABLE CLOCK KW11-P
|
||
PCCS=172540 ;CONTROL AND STATUS
|
||
PCCB=172542 ;COUNT SET BUFFER
|
||
PCCN=172544 ;COUNTER
|
||
PCBRV=104 ;INTERUPT VECTOR
|
||
|
||
;LINE FEQUENCY CLOCK KW11-L
|
||
LCCS=177546 ;CONTROL AND STATUS
|
||
LCBRV=100 ;INTERUPT VECTOR
|
||
|
||
;TK DISPLAY
|
||
NGCSR=164040 ;CONTROL AND STATUS
|
||
NGREL=164042 ;RELOCATION
|
||
|
||
;PAPER TAPE PUNCH AND READER
|
||
PTRSR=177550 ;PAPER TAPE READER STATUS
|
||
PTRBR=177552 ;PAPER TAPE READER BUFFER
|
||
PTPSR=177554 ;PAPER TAPE PUNCH STATUS
|
||
PTPBR=177556 ;PAPER TAPE PUNCH BUFFER
|
||
PTRBRV=70 ;VECTOR FOR READER
|
||
PTPBRV=74 ;VECTOR FOR PUNCH
|
||
|
||
PLTBCR=177500 ;PLOTTER BYTE COUNT REGISTER
|
||
LPTMEX=177502 ;DMA MEMORY EXTENSION BITS REGISTER
|
||
PRTBCR=177504 ;PRINTER BYTE COUNT REGISTER
|
||
LPTBA=177506 ;BUSS ADDRESS FOR THE DMA CONTROLLER
|
||
PLTCSR=177510 ;PLOTTER CONTROL STATUS REGISTER
|
||
PLTDBR=177512 ;PLOTTER DATA BUFFER REGISTER
|
||
PRTCSR=177514 ;PRINTER CONTROL STATUS REGISTER
|
||
PRTDBR=177516 ;PRINTER DATA BUFFER REGISTER
|
||
PRTBRV=200 ;PRINTER VECTOR
|
||
PLTBRV=174 ;PLOTTER VECTOR
|
||
|
||
;MB11 MAR AND HISTORY REGISTER
|
||
MBCSR=170000+0 ;CONTROL AND STATUS
|
||
MBXHGH=MBCSR+2 ;HIGH BITS OF X REGISTER
|
||
MBXLOW=MBCSR+4 ;LOW BITS OF X REGISTER
|
||
MBYHGH=MBCSR+6 ;HIGH BITS OF Y REGISTER
|
||
MBYLOW=MBCSR+10 ;LOW BITS OF Y REGISTER
|
||
MBHHGH=MBCSR+12 ;HIGH BITS OF HISTORY REGISTER
|
||
MBHLOW=MBCSR+14 ;LOW BITS OF HISTORY REGISTER
|
||
MBHCNT=MBCSR+16 ;HISTORY MEMORY COUNTER
|
||
|
||
;BITS IN MBCSR
|
||
MBINTE==100
|
||
MBAFRZ==200
|
||
MBXAYR==400 ;X<A<Y READ TRAP
|
||
MBXAYW==1000 ;X<A<Y WRITE TRAP
|
||
MBNOIN==2000 ;IGNORE INIT
|
||
MBINAO==4000 ;INTERRUPT ON ALMOST OVERFLOW
|
||
|
||
;BITS IN MBXHGH AND MBYHGH
|
||
MBREDT==4 ;READ TRAP BIT
|
||
MBWRTT==10 ;WRITE TRAP BIT
|
||
|
||
;BITS IN MBHHGH
|
||
MBWRTB==4 ;WRITE BIT IN HISTORY MEMORY HIGH BITS
|
||
|
||
;BREAK VECTOR
|
||
MBBRV=374
|
||
|
||
.SBTTL MACROS FOR DEFINING VARIOUS THINGS
|
||
|
||
;MACRO TO INITIALIZE DEFINITION OF SOME RANDOM THING
|
||
.MACRO DTHING
|
||
FOO==0
|
||
.ENDM
|
||
|
||
;MACRO TO DEFINE A WORD FOR SOME RANDOM THING
|
||
.MACRO DWORD A,B
|
||
.IIF P1,.IIF DF A,.ERROR A ALREADY DEFINED
|
||
A==FOO
|
||
.IF NB B
|
||
.IIF P1,.IIF DF B,.ERROR B ALREADY DEFINED
|
||
B==FOO+1
|
||
.ENDC
|
||
FOO==FOO+2
|
||
.ENDM
|
||
|
||
;MACRO TO INIT THE DEFINITION OF RANDOM FLAGS
|
||
.MACRO DFLAGS
|
||
BAR==1
|
||
.ENDM
|
||
|
||
;MACRO TO DEFINE A RANDOM FLAG BIT
|
||
.MACRO DFLAG FLAG
|
||
.IIF P1,.IIF DF FLAG,.ERROR FLAG ALREADY DEFINED
|
||
.IIF Z BAR,.ERROR FLAG TOO MANY FLAGS
|
||
FLAG==BAR
|
||
BAR==BAR_1
|
||
.ENDM
|
||
|
||
;MACRO TO ADD SOMETHING TO A REMOTE MACRO
|
||
.MACRO ADDMAC MAC,STUFF
|
||
MAC <
|
||
.MACRO MAC A,B,C
|
||
A>,<STUFF>,<B
|
||
C
|
||
.ENDM>
|
||
.ENDM
|
||
|
||
;MACRO FOR THE INITLS TABLE
|
||
.MACRO INITSL A,B,C
|
||
A
|
||
INITLS:
|
||
B
|
||
C
|
||
.ENDM
|
||
|
||
;MACRO FOR STORAGE ALLOCATION OF LIST SPACE
|
||
.MACRO LSTSTO A,B,C
|
||
A
|
||
LISTST:
|
||
B
|
||
C
|
||
.ENDM
|
||
|
||
.MACRO ALSTM FREENM,TABNAM,LENGTH,NUM
|
||
ADDMAC LSTSTO,<FREENM: 0
|
||
.IIF NB TABNAM,TABNAM:
|
||
.BLKB LENGTH*NUM
|
||
AILSTM FREENM,NUM,LENGTH>
|
||
.ENDM
|
||
|
||
.MACRO AILSTM FREENM,NUM,LENGTH
|
||
ADDMAC INITSL,<ILIST FREENM+2,FREENM,NUM,LENGTH>
|
||
.ENDM
|
||
|
||
;MACRO TO DEFINE A LIST STORAGE AREA
|
||
.MACRO ILISTS FREENM,TABNAM,NUM
|
||
ALSTM FREENM,TABNAM,\FOO,NUM
|
||
.ENDM
|
||
|
||
.MACRO ILIST AD,FREE,NUM,LEN
|
||
WORDS <AD+LEN,FREE,NUM-2,LEN>
|
||
.ENDM
|
||
.SBTTL DEFINITIONS FOR VARIOUS TYPES OF ITEMS
|
||
;MACROS TO DEFINE ITEMS WITH
|
||
|
||
;THE START DEFINING ITEM MACRO
|
||
.MACRO SITEMD SYM
|
||
FOO==2
|
||
ITMTFO==ITMTFO+1
|
||
SYM==ITMTFO
|
||
.ENDM
|
||
|
||
;THE DEFINE SYMBOL MACRO
|
||
;IF SECOND ARG IS PRESENT, IT IS HOW MUCH SPACE TO RESERVE, IN BYTES
|
||
.MACRO DITMS SYM,SIZE
|
||
.IIF P1,.IIF DF SYM,.ERROR SYM ALREADY DEFININED
|
||
SYM==FOO
|
||
.IIF B SIZE,FOO==FOO+2
|
||
.IIF NB SIZE,FOO==FOO+<SIZE>
|
||
.ENDM
|
||
|
||
;THE DEFINE FLAG WORD MACRO
|
||
;SPACE IS RESERVED FOR THE FLAG WORD, AND FLAGS ARE DEFIND
|
||
;SEQUENTIALLY FROM THE RIGHT TO THE LEFT
|
||
.MACRO DFWORD SYM,BITS
|
||
FOOBAR==0
|
||
SYM==FOO
|
||
FOO==FOO+2
|
||
.IRP X,<BITS>
|
||
X==1_FOOBAR
|
||
FOOBAR==FOOBAR+1
|
||
.ENDM
|
||
.ENDM
|
||
|
||
;THE DEFINE ITEM SIZE MACRO
|
||
;DEFINES A SYMBOL AS THE SIZE OF THE ITEM DEFINED SO FAR
|
||
.MACRO DITMSZ SYM
|
||
SYM==FOO_-6
|
||
.ENDM
|
||
.SBTTL MACROS FOR GENERATING CODE
|
||
|
||
.MACRO LBRLEM ADDR,COND,A,Q
|
||
.IF IDN COND,A
|
||
B'Q .+6
|
||
JMP ADDR
|
||
.ENDC
|
||
.IF IDN COND,Q
|
||
B'A .+6
|
||
JMP ADDR
|
||
.ENDC
|
||
.ENDM
|
||
|
||
.MACRO LBR COND,ADDR
|
||
.IF1
|
||
.IFDF ADDR
|
||
.IFGE ADDR-.+376
|
||
.=.+2
|
||
.IFF
|
||
.=.+6
|
||
.IIF B COND,.=.-2
|
||
.ENDC
|
||
.IFF
|
||
.=.+6
|
||
.IIF B COND,.=.-2
|
||
.ENDC
|
||
.IFF
|
||
LBRCSW==0
|
||
.IFLE ADDR-.
|
||
.IFGE ADDR-.+376
|
||
LBRCSW==1
|
||
.IF NB COND
|
||
B'COND ADDR
|
||
.IFF
|
||
BR ADDR
|
||
.ENDC
|
||
.ENDC
|
||
.ENDC
|
||
.IFZ LBRCSW
|
||
.IIF B COND,JMP ADDR
|
||
LBRLEM ADDR,COND,EQ,NE
|
||
LBRLEM ADDR,COND,LT,GE
|
||
LBRLEM ADDR,COND,LE,GT
|
||
LBRLEM ADDR,COND,HIS,LO
|
||
LBRLEM ADDR,COND,LOS,HI
|
||
LBRLEM ADDR,COND,CS,CC
|
||
LBRLEM ADDR,COND,VS,VC
|
||
.ENDC
|
||
.ENDC
|
||
.ENDM
|
||
;MACRO TO DO A BUG CHECK IN THE "NATURAL DIRECTION"
|
||
;THAT IS, IF THE CONDITION IS TRUE, BPT
|
||
.MACRO NBUGC COND
|
||
RBRPP4 COND
|
||
BPT
|
||
.ENDM
|
||
|
||
;MACRO TO BRANCH TO .+4 (PP4) ON THE OPPISITE OF THE SUPPLIED CONDITON
|
||
.MACRO RBRPP4 COND
|
||
BRO .+4,COND,MI,PL
|
||
BRO .+4,COND,EQ,NE
|
||
BRO .+4,COND,LT,GE
|
||
BRO .+4,COND,LE,GT
|
||
BRO .+4,COND,HIS,LO
|
||
BRO .+4,COND,LOS,HI
|
||
BRO .+4,COND,CS,CC
|
||
BRO .+4,COND,VS,VC
|
||
.ENDM
|
||
|
||
;MACRO TO GENERATE BRANCH OF OPPISTIE CONDITION
|
||
.MACRO BRO ADDR,COND,A,Q
|
||
.IIF IDN COND,A, B'Q ADDR
|
||
.IIF IDN COND,Q, B'A ADDR
|
||
.ENDM
|
||
|
||
.MACRO BUGC COND
|
||
NBUGC COND
|
||
.ENDM
|
||
|
||
|
||
.MACRO CHECKP
|
||
; JSR PC,CHEKIN
|
||
.ENDM
|
||
|
||
.MACRO TRAPV DEV,PRI
|
||
.=DEV'BRV
|
||
.IIF P2,.IIF NDF DEV'BRK,DEV'BRK==0
|
||
DEV'BRK
|
||
.IIF NB PRI, PRI_5
|
||
.IIF B PRI, 200
|
||
.ENDM
|
||
;MACRO TO GENERATE A CONDITIONAL ERROR TRAP
|
||
.MACRO ERRORC COND,ERR,F1,F2
|
||
RBRPP4 COND
|
||
ERROR ERR,F1,F2
|
||
.ENDM
|
||
|
||
;MACRO TO GENERATE AN ERROR TRAP
|
||
.MACRO ERROR ERR,F1,F2
|
||
ERRCOD==.E'ERR!TRPZBT
|
||
EFLAG F1
|
||
EFLAG F2
|
||
TRAP ERRCOD
|
||
.ENDM
|
||
|
||
;MACRO TO HELP OUT ERROR
|
||
.MACRO EFLAG FLAG
|
||
.IIF IDN FLAG,SZ,ERRCOD==ERRCOD!TRPZBT
|
||
.IIF IDN FLAG,CZ,ERRCOD==ERRCOD&<-TRPZBT-1>
|
||
.IIF IDN FLAG,SV,ERRCOD==ERRCOD!TRPVBT
|
||
.IIF IDN FLAG,CV,ERRCOD==ERRCOD&<-TRPVBT-1>
|
||
.ENDM
|
||
|
||
TRPZBT==200
|
||
TRPVBT==100
|
||
|
||
;MACRO TO ASSIGN AN ERROR SYMBOL
|
||
.MACRO ERDEF CODE
|
||
.E'CODE==FOO
|
||
FOO==FOO+1
|
||
.ENDM
|
||
|
||
.MACRO EMTD NAME
|
||
.IF NB NAME
|
||
.'NAME==FOO+EMT
|
||
$'NAME==FOO+200+EMT
|
||
E'NAME
|
||
.IFF
|
||
BADEMT
|
||
.ENDC
|
||
FOO==FOO+1
|
||
.ENDM
|
||
|
||
|
||
.SBTTL SYSTEM PARAMETERS
|
||
|
||
;GENERALIZED ITEM POINTER DEFINITION
|
||
GIPBIT==100000 ;SET IF IT IS A GENERALIZED ITEM POINTER
|
||
GIPSPR==40000 ;BIT SET IF UPT IS IN A SPHERE
|
||
GIPITM==176000 ;MASK FOR ITEM INDEX
|
||
GIPUPT==141777 ;MASK FOR UPT NUMBER (IN SPHERE)
|
||
GIPFUP==140000 ;MASK FOR FLOATING UPT TABLE OFFSET
|
||
|
||
;FOR THE ITEM LIST
|
||
NITEMS==150. ;MAXIMUM NUMBER OF ITEMS
|
||
NITMBL==8. ;MAXIMUM NUMBER OF BLOCKS ALLOCATED TO ITEM STROAGE
|
||
NITMPS==20. ;MAXIMUM DEPTH OF ITEM PUSHES
|
||
NITALS==NITMBL*8. ;NUMBER OF FREE STROAGE NODES
|
||
;DEFINITION OF AN ITEM TABLE ENTRY
|
||
DTHING
|
||
DWORD ITLINK ;LINK WORD FOR FREE ENTRIES
|
||
ITMADR==ITLINK ;WHERE THE ADDRES OF THE ITEM IS KEPT
|
||
DWORD ITACCS,ITLNGT ;ACCESS CODE, LENGTH
|
||
ILISTS ITMFRE,ITMTAB,NITEMS
|
||
ITMTEL==FOO
|
||
.IIF NZ 4-ITMTEL,.ERROR ITEM NODES AND ITEM ALLOCATE NODES NOT SAME SIZE!
|
||
ITACCD==6 ;ITEM ACCESS CODE (READ-WRITE NO TRAP)
|
||
FOO==4
|
||
ILISTS ITMAFR,,NITALS ;FREE STORAGE NODES
|
||
;ADDRESSES OF THE ITEM SLOTS
|
||
ITM0AD==<ITM0AR-KERDSA>_12.
|
||
ITM1AD==<ITM1AR-KERDSA>_12.
|
||
ITM2AD==<ITM2AR-KERDSA>_12.
|
||
|
||
;PROCESS AND USER PARAMETERS
|
||
NPROSS==80. ;MAXIMUM NUMBER OF PROCESSES AND USERS
|
||
PRPDLL==200 ;LENGTH OF THE PDL FOR THE PROCESS (BYTES)
|
||
PIT2PL==14 ;LENGTH OF ITEM 2 PDL IN PROCESS
|
||
;DEFINITION OF A PROCESS TABLE ENTRY
|
||
PRSTEL==16 ;LENGTH OF A PROCESS TABLE ENTRY
|
||
PRTFRD==0 ;FORWARD POINTER
|
||
PRTBCK==2 ;BACK POINTER
|
||
PRTPPT==4 ;PROCESS POINTER (OR TO ITEM IF USER)
|
||
PRTUPT==6 ;USER POINTER (-1 FOR USER)
|
||
PRTJTM==10 ;JTMU
|
||
PRTPRI==12 ;HIS PRIORITY
|
||
PRTTIM==14 ;TIME IN HALF-SECS THIS PROCESS PUT ON THIS QUEUE
|
||
|
||
;SPHERE PARAMTERS
|
||
MNCLSE==200 ;MAXIMUM NUMBER OF C-LIST ENTRIES
|
||
NCLSEB==10 ;NUMBER OF C-LIST ENTRIES PER BLOCK
|
||
CLSELN==12 ;LENGTH OF A C-LIST ENTRY (NOTE THAT THE LENGTH OF A BLOCK=NCLSEB*CLSELN, WHATEVER IT IS)
|
||
;DEFINITION OF A C-LIST ENTRY
|
||
CLSETY==0 ;TYPE
|
||
CLSEPI==2 ;PRIMARY ITEM FOR ENTRY
|
||
CLSESI==4 ;SECONDARY ITEM FOR ENTRY
|
||
CLSEM0==6 ;FIRST RANDOM WORD FOR ENTRY
|
||
CLSEM1==10 ;SECOND RANDOM WORD
|
||
;THESE ARE FOR THE .RDMAP CALL
|
||
.PLENM==177770 ;MASK FOR THE LENGTH OF THE PAGE
|
||
.PACCM==174377 ;MASK FOR THE ACCESS
|
||
.PDEI==100000 ;BIT FOR DATA = I PAGE
|
||
.PABS==40000 ;BIT FOR ABSOLUTE PAGE
|
||
.PFIL==2000 ;BIT FOR FILE PAGE
|
||
|
||
|
||
;FOR THE TELETYPE ITEM
|
||
TITQ==TOQM-1
|
||
TIQSZ==350.
|
||
TIBSZ==50.
|
||
TOQSZ==64.
|
||
TIBT==TIQM
|
||
TIQLM==TOQM
|
||
TOQLM==TOQM+TOQSZ
|
||
|
||
;FOR THE QUE ITEM
|
||
QUESZ==64 ;THE SIZE OF THE QUE
|
||
|
||
;FOR THE PAPER TAPE ITEMS
|
||
PTRSZ==120.
|
||
PTPSZ==120.
|
||
;FOR THE LOCKED SWITCH LISTS
|
||
NLCKBL==NPROSS/4 ;A GUESS
|
||
DTHING
|
||
DWORD LCKLNK ;THE LINK
|
||
DWORD LCKDSP ;DISPATCH ADDRESS FOR LOCK
|
||
DWORD LCKTIT ;ITEM
|
||
DWORD LCKWD1 ;WORD ONE OF LOCK DATA
|
||
DWORD LCKWD2 ;WORD TWO
|
||
ILISTS LCKFRE,,NLCKBL
|
||
|
||
;MISC SYSTEM PARAMETERS
|
||
LTIMEL==6 ;TIME BETWEEN CHECKING INATIVE GUYS
|
||
JTMUUT==6 ;NUMBER OF TICKS BETWEEN JTMU UPDATES
|
||
JTMUAC==40 ;ADDITIVE CONSTANT
|
||
JTMUDC==4 ;DECAY CONSTANT
|
||
CLKL==1 ;LEVEL CLOCK RUNS AT
|
||
CLKPIR==1_<CLKL+10> ;BIT FOR PIRQ
|
||
TTYL==2 ;LEVEL TTY PROCESSING RUNS AT
|
||
TTYPIR==1_<TTYL+10>
|
||
DMRL==3 ;LEVEL THE MIDDLE LEVEL DISK ROUTINES RUN AT
|
||
DMRPIR==1_<DMRL+10> ;MIDDLE LEVEL DISK PIRQ BIT
|
||
IPRIOR==4 ;PRIORITY TO SET A NEWLY CREATED PROCESS TO
|
||
IQUANT==4 ;INTIAL QUANTUM
|
||
ITMTFO==0 ;THE TYPE OF THE LAST ITEM DEFINED
|
||
ITTYPE==0 ;FOR ALL ITEMS, THE FIRST WORD IS THE TYPE
|
||
;DEFINITION OF A PROCESS ITEM
|
||
SITEMD ITPROC
|
||
;THE NEXT THREE SHOULD NOT BE MOVED
|
||
;WITHOUT MOVING THE COORESPONDING THREE IN THE USER DEFINITION
|
||
DITMS PRSREF ;REFERENCE COUNT
|
||
DITMS PPRTPT ;POINTER TO PROCESS TABLE
|
||
DITMS PQBIT ;THE QUEUE BIT
|
||
DITMS PRSUSR ;THE USER PROCESS TABLE POINTER
|
||
DITMS PTUSED,4 ;TIME USED BY THIS PROCESS IN HALF-TICKS
|
||
DITMS PRSID1 ;PROCESS ID LOW PART
|
||
DITMS PRSID2 ;PROCESS ID HIGH PART
|
||
DITMS PFAULT ;IF NON-ZERO, WHAT KIND OF FAULT
|
||
DITMS PERRW ;ERROR WORD FOR SYSTEM CALLS (PERRW AND PERRAD MUST BE IN THIS ORDER)
|
||
DITMS PERRAD ;SYSTEM ADDRES WHERE ERRRO TRAP HAPPENED FROM
|
||
DITMS PSPHRP ;POINTER TO SPHERE
|
||
DITMS PSPHCP ;CIRCULAR POINTER TO OTHER PROCESSES IN SPHERE
|
||
DITMS PLCKSL ;END OF THE LOCKED SWITCH LIST
|
||
DITMS PUPDLO ;OFFSET OF USER'S PDL IF CALL COMPLETES
|
||
DITMS PITM2P,PIT2PL ;PROCESS'S ITEM2 PDL
|
||
DITMS PITM2C ;COUNT OF ITEMS ON ITEM2 PDL
|
||
DITMS PUREGS,14 ;THE USER'S REGISTER'S
|
||
DITMS PUP ;THE USER'S PDL POINTER
|
||
DITMS PUPC ;THE USER'S PC
|
||
DITMS PUPS ;THE USER'S PROCESSOR STATUS
|
||
DITMS PSREGS,14 ;THE SYSTEM'S REGISTERS
|
||
DITMS PSP ;THE SYSTEM'S PDL POINTER
|
||
DITMS PSPC ;THE SYSTEM'S PC
|
||
DITMS OPSPC ;OLD SYSTEM PC
|
||
DITMS PPDL,PRPDLL ;THE PROCESS'S PDL
|
||
DFWORD PFLAGS,<PFALTB,PFAILB,PFPFLG,PACSVF,PPCLSR,PTVFLG,PPBNMP,PPCLDF> ;PROCESS FLAG WORD
|
||
DITMS PSTOPC ;STOP COUNT
|
||
DFWORD PSTOP,<PSPHSB,PSUPSB> ;STOP WORD
|
||
;PSPHSB INDICATES THE SPHERE HAS STOPPED THE PROCESS
|
||
;PSUPSB INDICATES SOME OTHER SUPERIOR PROCESS HAS STOPPED IT
|
||
DITMS PTVMAP ;-1 => DON'T MAP IN TV, HIGH BYTE IS TVSEL REGISTER
|
||
DITMSZ PRSLNF ;SIZE WITH NO FLOATING POINT
|
||
DITMS PTVMSK ;SAVED MASK
|
||
DITMS PTVINC ;SAVED INCREMENT REGISTER
|
||
DITMS PTVSHR ;SAVED SHIFT COUNT
|
||
DITMS PTVRAD ;THE ADDRESS REGISTER
|
||
DITMS PFPPRG,24.*2 ;FLOATING POINT REGISTERS
|
||
DITMS PFPPS ;FLOATING POINT STATUS
|
||
;NEXT TWO MUST BE IN THIS ORDER
|
||
DITMS PFEC ;FLOATING EXCEPTION CODE
|
||
DITMS PFEAP ;FLOATING EXCEPTION ADDRESS POINTER
|
||
DITMSZ PRSLFP ;LENGTH WITH FLOATING POINT
|
||
|
||
;DEFINITION OF A USER ITEM
|
||
SITEMD ITUSER
|
||
;THE NEXT THREE SHOULD NOT BE MOVED (SEE PROCESS)
|
||
DITMS USRREF ;THE REFERENCE COUNT
|
||
DITMS UPRTPT ;POINTER INTO PROCESS TABLE
|
||
DITMS UQBIT ;THE QUEUE BIT (HAD BETTER BE USER QUEUE)
|
||
DITMS UTUSED,4 ;TIME USED BY THIS USER
|
||
DITMS USRTTY ;THE TTY NUMBER OF THIS USER
|
||
DITMS USRNAM,10. ;USER NAME
|
||
DITMSZ USRLEN ;LENGTH OF A USER ITEM
|
||
|
||
;DEFINITION OF A SPHERE ITEM
|
||
SITEMD ITSPHR
|
||
;THE NEXT THREE SHOULD NOT BE MOVED (SEE USER)
|
||
DITMS SPHREF ;REFERENCE COUNT
|
||
DITMS SPRTPT ;THE SPHERE PROCESS TABLE POINTER
|
||
DITMS SQBIT ;THE QUEUE BIT (BETTER BE SPHERE QUE)
|
||
DITMS SCLSLK ;SPHERE C-LIST LOCK (CONTAINS THE ITEM NO. OF THE PROCESS THAT
|
||
;LOCKED IT
|
||
DFWORD SFLAG,<ENFLT1,ENFLT2,FAULT1,FAULT2,FAULT3> ;ENABLE FAULTS ONE AND TWO
|
||
;AND SAY WHETHER FAULT OR NOT
|
||
DITMS STTFG1 ;TELETYPE FLAG WORD 1
|
||
DITMS STTFG2 ;TTY FLAG WORD 2
|
||
DITMS SMTTY ;ITEM NO. OF MASTER TTY ITEM
|
||
DITMS SIFTTY ;ITEM NO. OF INFERIOR TTY SPHERE
|
||
DITMS SPHPRP ;POINTER TO FIRST PORCESS
|
||
DITMS SPHPRC ;COUNT OF PROCESSES IN SPHERE
|
||
DITMS SPHAPR ;COUNT OF ACTIVE PROCESSES
|
||
DITMS SUSRPT ;POINTER TO USER ITEM RESPONSIBLE FOR THIS SPHERE
|
||
DITMS SMSSPT ;POINTER TO MASTER SPHERE OF THIS SPHERE
|
||
DITMS SCLSEP ;POINTER TO FIRST UNUSED LOCATION, RELATIVE TO ITEM
|
||
.IFNZ MBFLG ;IF WE HAVE AN MB11 ON
|
||
;NEXT 5 MUST BE IN THIS ORDER
|
||
DITMS SPMBCN ;CONTROL REGISTER FOR MB11 (0=> NOT USING)
|
||
DITMS SPMBHX ;HIGH X BITS
|
||
DITMS SPMBLX ;LOW X BITS
|
||
DITMS SPMBHY ;HIGH Y BITS
|
||
DITMS SPMBLY ;LOW Y BITS
|
||
.ENDC
|
||
DITMS SUPTS,16.*UPTLEN ;THE UPT ENTRIES
|
||
DITMS SCLSTT,MNCLSE/NCLSEB ;THE INDEX OFFSETS TO THE C-LIST
|
||
DITMS SICLST,NCLSEB*CLSELN*2 ;START WITH 2 BLOCKS OF C-LIST
|
||
DITMSZ SPHLEN
|
||
|
||
;DEFINITION OF A TELETYPE ITEM
|
||
SITEMD ITTTY
|
||
DITMS TTYREF ;REFERENCE COUNTER FOR TTY
|
||
DITMS TTITM ;ITEM THAT CURRENTLY OWNS THIS TTY
|
||
DITMS TTLTTY ;THE LOGICAL TTY NO. ASSOCIATED WITH THIS ITEM
|
||
DITMS TTYU ;USER NUMBER OF THE OWNER OF THIS TTY
|
||
DFWORD TTYST1,<TIRST,TIQF,TOTRAN,TIMAGI,TIMAGO,TIRBM,TIEDM,TIECM,TICVM,TILIPM,TORST,TERST,TICTM,TICTF,TMORM,TMORF>
|
||
;STATUS OF TTY - FIRST WORD
|
||
.TIRST==TIRST ;=> RESET THE TTY ON NEXT INPUT BREAK
|
||
.TIQF==TIQF ;=> SUPER QUOTE THE NEXT CHARACTER
|
||
.TOTRN==TOTRAN ;=> CURRENTLY TRANSMITTING
|
||
.TIMGI==TIMAGI ;=> INPUT IMAGE MODE
|
||
.TIMGO==TIMAGO ;=> OUTPUT IMAGE MODE
|
||
.TIRBM==TIRBM ;=> IN RUBOUT MODE
|
||
.TIEDM==TIEDM ;=> IN EDIT MODE
|
||
.TIECM==TIECM ;=> IN ECHO MODE
|
||
.TICVM==TICVM ;=> CONVERT FROM LOWER TO UPPER CASE MODE
|
||
.TLIPM==TILIPM ;=> LOGO INPUT MODE
|
||
.TORST==TORST ;=> RESET THE TTY ON NEXT OUTPUT BREAK
|
||
.TERST==TERST ;=> RESET THE TTY EDIT BUFFER ON THE NEXT OUTPUT COMMMAND
|
||
.TICTM==TICTM ;=> CONTROLIFY MODE
|
||
.TICTF==TICTF ;=> CONTROLIFY THE NEXT CHAR FLAG
|
||
.TMORM==TMORM ;=> ENABLE MORE PROCESSING
|
||
.TMORF==TMORF ;=> MORE BREAK TRIGGERED
|
||
DFWORD TTYST2,<TSCRL,TOEDM,TILWT,TTHANG,TTBK>
|
||
;TTY STATUS, SECOND WORD
|
||
.TSCRL==TSCRL ;=> SCROLL MODE. IF ZERO THEN WRAP MODE IS ASSUMED
|
||
.TOEDM==TOEDM ;=> MEANS THAT THE BYTE OUTPUT WILL GO TO THE EDIT BUFFER
|
||
.TTHNG==TTHANG ;=> MEANS THAT WE ARE HANGING ON INPUT IN LINE MODE
|
||
;TTBK MEANS THAT WE SHOULD TRANSMIT A BREAK FOR TTBRKL CHARACTERS ON
|
||
;NEXT OUTPUT INTERRUPT
|
||
DITMS TOTSR ;ADDR OF TRANSMIT STATUS REGISTER
|
||
DITMS TIBI ;POINTER TO WHERE NEXT CHAR. GOES IN, IN INPUT BUFFER
|
||
DITMS TIBO ; " " " " " COMES OUT " " "
|
||
DITMS TIBN ;NUMBER OF CHAR. IN INPUT BUFFER
|
||
DITMS TIQI ;POINTER TO WHERE NEXT CHAR GOES IN, IN INPUT QUE
|
||
DITMS TIQO ; " " " " " COMES OUT " " "
|
||
DITMS TIQN ;NUMBER OF CHAR. IN INPUT QUE
|
||
DITMS TOQI ;POINTER TO WHERE NEXT CHAR. GOES IN, IN OUTPUT QUE
|
||
DITMS TOQO ; " " " " " COMES OUT " " "
|
||
DITMS TOQN ;NUMBER OF CHAR. IN OUTPUT QUE
|
||
DITMS TIEQO ;POINTER TO WHERE NEXT CHAR COMES OUT, IN OUTPUT QUE
|
||
DITMS TIEQN ;NUMBER OF CHARACTERS IN EDIT QUE
|
||
DITMS TIBC ;NUMBER OF UNMATCHED LEFT BRACKETS IN INPUT QUE
|
||
DITMS TIEBC ; " " " " " " " "
|
||
DITMS TIQTO ;POINTER TO WHERE ECHO IS PROCESSING
|
||
DITMS TIQTON ;NUMBER OF CHAR THAT ECHO STILL HAS TO PROCESS
|
||
DITMS TIEQTN ;NUMBER OF CHAR THAT RDSTR HAS TO PROCESS
|
||
DITMS TIEQTO ;POINTER TO WHERE RDSTR IS PROCESSING
|
||
DITMS TITQN ;TOTAL NUMBER OF CHAR IN INPUT/EDIT QUE
|
||
DITMS TOPAD ;NUMBER OF CHAR LEFT TO SEND PAD
|
||
DITMS TOIPC ;SAVED PC FOR ECHO
|
||
DITMS TOISVA ;SAVED A FOR ECHO
|
||
DITMS TOPC ;SAVED PC FOR OUTPUT
|
||
DITMS TOOPC ;SAVED SAVED PC FOR DEBUGGING
|
||
DITMS TOSVC ;SAVED C FOR OUTPUT
|
||
DITMS TOSVD ;SAVED D FOR OUTPUT
|
||
DITMS CHARNO ;NUMBER OF CHAR PRINTED FROM LEFT EDGE OF PAGE
|
||
DITMS LINENO ;NUMBER OF LINES FROM TOP OF SCREEN
|
||
DITMS TLAST ;THE LAST CHAR TYPED
|
||
DITMS LINEL ;THE LENGTH OF A LINE
|
||
DITMS TIHPIT ;ITEM OF PROCESS HANGING ON INPUT
|
||
DITMS TIHPI1 ;ID WORD 1 OF "
|
||
DITMS TIHPI2 ;ID WORD 2
|
||
DITMS TTBRKL ;LENGTH OF BREAK CONDITION IN CHARACTERS
|
||
.IFNZ NTVS
|
||
DITMS TVCRLN ;BYTE ADDRESS OF THE CURSOR IN BUFFER
|
||
DITMS TVSCRL ;ADDRESS IN 64 BIT CHUNKS OF SCROLL START
|
||
DITMS TVLINE ;THE LINE NUMBER OF THE CURSOR (CHAR LINE NUMBER)
|
||
DITMS TVHIGH ;THE NUMBER OF CHAR LINES ON A SCREEN
|
||
DITMS TVFONT ;THE FONT NUMBER OF THIS TV
|
||
DITMS TVST ;TV STATUS (CONTENTS OF TVCNSL)
|
||
DITMS TVCUR ;INTERRUPT LEVEL CURSOR POSITION
|
||
DITMS TVBUF ;THE NUMBER OF THE TV BUFFER FOR THIS TV,AND CURSOR MODE
|
||
DITMS TVNLSC ;THE NUMBER OF LINES TO SCROLL
|
||
DITMS TVHBIT ;THE HORIZONTAL BIT POSITION ON THE CURRENT LINE OF CURSOR
|
||
DITMS TVLCNT ;THE NUMBER OF LINES IN A CHAR - 1, USED BY BLINK FOR TVWC
|
||
DITMS TVMSK1 ;THE LEFT SIDE OF THE CURSOR MASK
|
||
DITMS TVMSK2 ;THE RIGHT SIDE OF THE CURSOR MASK, IN CASE CURSOR CROSSES WORD
|
||
DITMS TVSHCT ;SHIFT COUNT FOR THE CURSOR POSITION
|
||
DITMS TVCRSN ;BYTE ADDRESS OF THE BEGINNING OF LINE, LIKE TVCRLN
|
||
DITMS TVOFFL ;TOP LINE IN WRAP MODE, WHERE THE CURSOR GOES FROM BOTTOM
|
||
.ENDC
|
||
DITMS TIBB,TIBSZ ;INPUT BUFFER
|
||
DITMS TIQM,TIQSZ ;INPUT QUE
|
||
DITMS TOQM,TOQSZ ;OUTPUT QUE
|
||
DITMSZ TTYLEN
|
||
|
||
;DEFINITION OF A QUE ITEM
|
||
SITEMD ITQUE ;QUE ITEM
|
||
DITMS QUEREF ;REFERENCE COUNT OF THE ITEM
|
||
DITMS QUEENO ;NO OF ENTRIES IN QUE
|
||
DITMS QUECNT ;NO OF PEOPLE ON QUE
|
||
DITMS QUENUM ;THE NUMBER OF PEOPLE WHO CAN LOCK QUE
|
||
DITMS QUEQUE,QUESZ ;THE QUE
|
||
DITMSZ QUELEN
|
||
|
||
|
||
;DEFINITION OF A MASTER FILE ITEM
|
||
SITEMD ITMF ;TOP BYTE IS COUNT OF CAP WITH LOCK ON MFI
|
||
DITMS MFFREF ;REFERENCE COUNT INCREMENTED BY INFERIOR MFI'S
|
||
;AND FA CAPS
|
||
DITMS MFPBRF ;REFERENCE COUNT INCREMENTED BY FPBS
|
||
DITMS MFELN ;ACTUAL LENGTH OF THE ITEM IN BYTES
|
||
DITMS MFENDB ;DISK ADDRESS OF LAST BLOCK IN THE FILE, SET BY MUTATE AND RESET WHEN BLOCK ADDED
|
||
DITMS MFENDT ;DISPATCH ADDRESS FOR TYPE OF LAST REAL BYTE
|
||
DITMS MFENDP ;POINTER TO LAST REAL BYTE
|
||
DITMS MFIDLN ;NUMBER OF BLOCKS CURRENTLY ALLOCATED TO DIRECTORY
|
||
DITMS MFIUCF ;BYTES IN DIRECORY NOT COMMITED TO EXITANT MFI'S
|
||
DITMS MFICBY ;BYTES COMMITTED FOR US IN THE DIRECTORY ABOVE
|
||
DITMS MFDISK ;DISK THE FILE/DIRECTORY IS ON
|
||
DITMS MFDLNK ;LINK TO OTHER OPEN FILES ON THIS DISK
|
||
DITMS MFIUPT ;SLOT FOR SYSTEM TO STORE FUPT
|
||
DITMS MFIPB ;FIRST IN LIST OF LINKED FPBS
|
||
DITMS MFIFNO ;FILE NUMBER IN DIRECTORY
|
||
DITMS MFBAKP ;ITEM NUMBER OF PARENT MFI IF A FILE
|
||
DITMS MFLAGW ;BOTTOM BYTE IS LOGICAL DSK #
|
||
.FALNK==100000 ;USER REQUEST FOR A LINK
|
||
;BIT SET IF DIRECTORY
|
||
.FADIR==40000 ;USER REQUEST FOR DIRECTORY
|
||
;ROOT DIR. BIT
|
||
.FARUT==10000 ;USER REQUEST FOR ROOT DIRECTORY
|
||
;LOCKED BY USER BIT
|
||
.FALOK==4000 ;USER REQUEST TO LOCK MFI
|
||
MFEBMB==2000 ;ENTRY BEEN MUNGED
|
||
MFIBEB==1000 ;MFI BEING ENLARGED BIT
|
||
MFOPNB==400 ;FILE BEING OPENED BIT
|
||
MFDWDB==200 ;DELETE WHEN DONE BIT
|
||
MFTMPF==100 ;TEMPORARY FILE
|
||
MFNODR==40 ;NO ENTRY IN DIR FOR THIS YET
|
||
MFELEN==FOO ;EXACT LEGNTH IN BYTES OF OVERHEAD
|
||
DITMS MFENHD ;ENTRY HEADER
|
||
DITMS MFVERN
|
||
DITMS MFPGNO ;EOF PAGE NUMBER
|
||
DITMS MFBYTP ;EOF BYTE POINTER
|
||
DITMS MFDATE ;FILE DATE
|
||
DITMS MFTIME ;AND TIME
|
||
DITMS MFNAME ;START OF NAME IF NO ACCESS CODES
|
||
DITMS MFDUM,12 ;SPACE TO INTIALLY ALLOCATE FOR ENTRY
|
||
MFPARE==0 ;BITS IN ENTRY HEADER FLAG WORD
|
||
MFDIRE==1000
|
||
MFFILE==2000
|
||
;TYPE 3000 IS UNUSED
|
||
MFSLFE==4000
|
||
MFLNKE==5000
|
||
;TYPES 14 AND 16 ARE UNUSED
|
||
|
||
MFEOFB==100000 ;SET IF EOF DATE AND TIME WORDS EXIST
|
||
MFACCB==40000 ;SET IF ACCESS CODE EXIST
|
||
;BIT 20000 IS UNUSED
|
||
MFSHRB==10000 ;SET IF BLOCKS SHARED WITH OTHER FILE
|
||
;BITS 7000 ARE USED BY ENTRY TYPES
|
||
MFLSTB==400 ;SET IF EOF WORD POINTS TO EXISTING BLOCK
|
||
DITMSZ MFLEN
|
||
|
||
;DEFINITION OF CORE LINK ITEM, (WHEN A PAGE, IT LOOKS THE SAME)
|
||
SITEMD ITCL
|
||
DITMS CLREF ;THE REFERENCE COUNT
|
||
DITMS CLCONP ;POINTER TO THE CONSUMER
|
||
DITMS CLCNT ;THE AMOUNT OF VALID DATA IN ITEM
|
||
DITMS CLNUM ;THE NUMBER OF SLOTS IN THE BUFFER
|
||
DITMS CLDATI ;POINTER TO DATA IN
|
||
DITMS CLDATO ;POINTER TO DATA OUT
|
||
CLDATL==FOO ;THE LENGTH OF THE DATA WORDS
|
||
|
||
|
||
|
||
;DEFINITION OF A FONT ITEM
|
||
SITEMD ITFNT
|
||
DITMS FNTREF ;NOT REALLY USED FOR ANYTHING
|
||
DITMS FNWIDE ;WIDTH OF THIS FONT
|
||
DITMS FNHIGH ;HEIGHT OF THIS FONT
|
||
DITMS FNTEND ;POINTER TO THE END OF THE FONT
|
||
DITMS FNTLCL ;THE NUMBER OF TV LINES IN ONE CHAR LINE
|
||
DITMS FNMSK ;A RIGHT ADJUSTED MASK FOR CHARS IN THIS FONT
|
||
;THE SYSTEM COMPUTES THE NEXT 2 VARIABLES WHEN THE ITEM IS CREATED
|
||
DITMS FNLINE ;THE NUMBER OF CHAR LINES THAT FIT ON A SCREEN
|
||
DITMS FLFINC ;NUMBER OF BYTES IN ONE CHAR LINE
|
||
DITMS FNREM ;THE NUMBER OF BYTES AFTER LAST SCREEN LINE. MAY BE NEGATIVE.
|
||
DITMS FNLINL ;THE NUMBER OF CHARS PER LINE
|
||
DITMS FNLSC ;THE NUMBER OF LINES TO SCROLL
|
||
;VARIOUS PRECOMPUTED VARIABLES GO HERE
|
||
FOO==40 ;THE DISPATCH TABLE ALWAYS STARTS AT 40
|
||
DITMS FNTPNT,400 ;AND IS 128. WORDS LONG
|
||
|
||
;DEFINITION OF THE PAPER TAPE READER ITEM
|
||
SITEMD ITPTR
|
||
;DON'T CHANGE THE ORDER BELOW!
|
||
DITMS PTRREF ;REFERENCE COUNT
|
||
DITMS PTRDAI ;POINTER TO WHERE DATA GOES IN
|
||
DITMS PTRDAO ;POINTER TO WHERE DATA COMES OUT
|
||
DITMS PTRNO ;NUMBER OF BYTES IN BUFFER
|
||
DITMS PTRBUF,PTRSZ ;BUFFER FOR PAPER TAPE READER
|
||
PTREND==FOO ;TOP OF BUFFER
|
||
DITMSZ PTRLEN
|
||
|
||
;DEFINITION OF THE PAPER TAPE PUNCH ITEM
|
||
SITEMD ITPTP
|
||
;DON'T CHANGE THE ORDER BELOW!
|
||
DITMS PTPREF ;REFERENCE COUNT
|
||
DITMS PTPDAI ;POINTER TO WHERE DATA GOES IN
|
||
DITMS PTPDAO ;POINTER TO WHERE DATA COMES OUT
|
||
DITMS PTPNO ;NUMBER OF BYTES
|
||
DITMS PTPBUF,PTPSZ ;BUFFER FOR DATA
|
||
PTPEND==FOO ;TOP OF THE BUFFER
|
||
DITMSZ PTPLEN
|
||
|
||
LPTBSZ==512.
|
||
PLTBSZ==4096.
|
||
LINSIZ==264. ;THE NUMBER OF BYTES IN A PLODDING LINE
|
||
;DEFINITION OF A LINE PRINTER ITEM.
|
||
SITEMD ITLPT
|
||
;DON'T CHANGE THE ORDER BLEOW WITHOUT CHECKING THE CCPRLP ROUTINE
|
||
DITMS LPTREF ;REFERENCE COUNT
|
||
DITMS LPTEND ;POINTER TO THE END OF THE BUFFER
|
||
DITMS LPTLCT ;NUMBER OF TIMES TO OUTPUT THIS LINE
|
||
DITMS LPTMOD ;ZERO IF IN PRINT MODE, OTHERWISE THE SCALE FACTOR FOR PLODDING
|
||
DITMS LPTCSR ;CONTAINS THE CONTROL STATUS REGISTER OF THE CURRENT MODE
|
||
DITMS LPTDAI ;POINTER TO WHERE DATA GOES IN
|
||
DITMS LPTDAO ;POINTER TO WHERE DATA COMES OUT FROM
|
||
DITMS LPTNUM ;NUMBER OF CHARACTERS IN THE BUFFER
|
||
DITMS LPTWCT ;THE NUMBER OF BYTES TRANSFERED IN THIS TRANSFER
|
||
DITMS LPTPCT ;COUNT OF PLOT BYTES TO GO INTO THIS LINE
|
||
DITMS LPTPIT ;PROCESS TO ACTIVE
|
||
DITMS LPTPI1 ;ID WORD 1 OF PROCESS
|
||
DITMS LPTPI2 ;ID WORD 2 OF PROCESS
|
||
DITMS LPTBUF,LPTBSZ ;THE BUFFER
|
||
PRTEND==FOO ;THE END OF THE PRINTER BUFFER
|
||
DITMSZ PRTLEN ;LENGTH FO PRINTER ITEM
|
||
DITMS LPTBEX,PLTBSZ-LPTBSZ ;BUFFER EXTENSION FOR THE PLODDER
|
||
PLTEND==FOO ;THE END OF THE PLODDER BUFFER
|
||
DITMS LPTLBF,LINSIZ ;THE BUFFER FOR THE CURRENT PLODDER LINE
|
||
DITMSZ PLTLEN ;LENGTH OF PLODDER ITEM
|
||
|
||
.SBTTL ERROR DEFINITIONS
|
||
|
||
FOO==0
|
||
|
||
ERDEF NUL ;NO ERROR AT ALL
|
||
ERDEF APEF ;ACCESS PAST END OF FILE
|
||
ERDEF BAC ;BAD ACCESS
|
||
ERDEF BAD ;BAD ARGUMENTS TO CALL
|
||
ERDEF BCN ;BAD CAPABILITY NUMBER
|
||
ERDEF BCT ;BAD CAPABILITY TYPE
|
||
ERDEF BFN ;BAD FILE NAME
|
||
ERDEF BFUN ;BAD FUNCTION
|
||
ERDEF BPN ;BAD PAGE NUMBER
|
||
ERDEF CDD ;CAN'T DELETE NON-EMPTY DIRECTORY
|
||
ERDEF DEVE ;DEVICE ERROR
|
||
ERDEF DFL ;DISK FULL
|
||
ERDEF DRF ;DIRECTORY FULL
|
||
ERDEF EAE ;ENTRY ALREADY EXISTS
|
||
ERDEF FLOK ;FILE LOCKED
|
||
ERDEF FNF ;FILE NOT FOUND
|
||
ERDEF FNTL ;FILE NAME TOO LONG
|
||
ERDEF FTL ;FILE ENTRY TOO LONG
|
||
ERDEF NIS ;NO ITEM SPACE AVAILABLE
|
||
ERDEF NIT ;NO ITEM AVAILABLE
|
||
ERDEF NSS ;NO SWAP SPACE LEFT
|
||
ERDEF RNA ;RESOURCE NOT AVAILABLE
|
||
ERDEF RPEF ;ATTEMPT TO READ PAST END OF FILE
|
||
ERDEF SYS ;CALL MAY ONLY BE EXECUTED BY SYSSPR
|
||
ERDEF CLF ;C LIST IS FULL
|
||
ERDEF DSKE ;DISK ERROR (ONLY USED BY LSITS)
|
||
ERDEF DVBE ;DISK VERY BAD ERROR (ONLY LSITS)
|
||
.SBTTL TRAP VECTORS
|
||
.=0
|
||
BPT
|
||
.=4
|
||
.REPT 77
|
||
.+2
|
||
BPT
|
||
.ENDR
|
||
|
||
;TRAP VECTORS FOR INTERNAL DEVICES
|
||
TRAPV BE ;BUSS ERRORS
|
||
TRAPV ILL ;ILLEGAL INSTRUCTIONS
|
||
TRAPV BPT ;BREAKPOINTS
|
||
TRAPV IOT ;IOT
|
||
TRAPV PWF,7 ;POWER FAILURE
|
||
TRAPV EMT ;EMT
|
||
TRAPV TRP ;TRAP
|
||
TRAPV PAR ;PARITY ERROR
|
||
TRAPV PIR,7 ;PROGRAMMED INTERUPT
|
||
TRAPV FPP ;FLOATING POINT ERROR
|
||
TRAPV SEG ;SEGMENTATION ABORT OR TRAP
|
||
|
||
;TRAP VECTORS FOR OTHER DEVICES
|
||
TRAPV RF,5 ;FIXED HEAD DISK
|
||
TRAPV RK,5 ;MOVING HEAD DISK
|
||
TRAPV LC,6 ;LINE CLOCK
|
||
TRAPV PC,6 ;PROGRAMABLE CLOCK
|
||
TRAPV TK ;CONSOLE KEYBOARD
|
||
TRAPV TP ;CONSOLE PRINTER
|
||
TRAPV PTR,4 ;PAPER TAPE READER
|
||
TRAPV PTP,4 ;PAPER TAPE PUNCH
|
||
TRAPV PRT,4 ;LINE PRINTER IN PRINT MODE
|
||
TRAPV PLT,4 ;LINE PRINTER IN PLOT MODE
|
||
.IIF NZ MBFLG,TRAPV MB,7 ;MAR AND HISTORY REGISTER
|
||
;USER SYMBOLS FOR TRAP FAULTS
|
||
.IRP X,<BE,ILL,BPT,IOT,EMT,TRP,FPP,SLE,RDO,NXM>
|
||
.'X'TF==1+.IRPCN
|
||
.ENDM
|
||
.=400
|
||
.SBTTL SYSTEM VARIABLES AND TABLES
|
||
ZERO: 0 ;DEFINED TO BE ZERO
|
||
|
||
ABSLD:
|
||
.OFFSET 160000-.
|
||
ABSLOD: MOV #ABLDPD,P ;REINIT THE PDL POINTER
|
||
CLR D
|
||
MOV #20000,E
|
||
CLR (D)+
|
||
SOB E,.-2
|
||
CLR ABSCNT
|
||
;C IS CHECKSUM
|
||
;D IS CORE ADDRESS
|
||
;E IS BYTE COUNT
|
||
ABSLOP: CLR C
|
||
JSR PC,GBYTE
|
||
CMPB #1,A ;IS IT THE START OF A BLOCK?
|
||
BNE ABSLOP ;NO, TRY AGAIN
|
||
JSR PC,GBYTE
|
||
TST A
|
||
BNE ABSLOP ;SHOULD BE A ZERO NEXT
|
||
JSR PC,GWORD ;GET THE COUNT
|
||
MOV A,E ;SAVE IT
|
||
JSR PC,GWORD ;GET THE ADDRESS
|
||
MOV A,D
|
||
ADD E,A ;CHECK THAT WE AREN'T OVERLOADING
|
||
CMP #40000,A
|
||
BHI .+4 ;MUST BE UNDER 8K
|
||
BPT
|
||
CMP #6,E ;IS IT THE START BLOCK?
|
||
BEQ ABSSRT ;YUP
|
||
SUB #6,E ;THAT MANY ALREADY LOADED
|
||
ABSLP1: JSR PC,GBYTE
|
||
MOVB A,(D)+
|
||
SOB E,ABSLP1
|
||
JSR PC,GBYTE ;THE CHECKSUM
|
||
TSTB C
|
||
BEQ ABSLOP ;CHECKSUM GOOD
|
||
BPT ;BAD CHECKSUM
|
||
ABSSRT: JSR PC,GBYTE ;GET CHECKSUM
|
||
TSTB C
|
||
BEQ .+4
|
||
BPT ;BAD CHECKSUM
|
||
CMP -(P),-(P) ;EXTRA WORDS
|
||
SAVE <SYSFCP>
|
||
BIS #.DELCP,(P) ;DELETE CAPABILITY TO FILE
|
||
$INVOK
|
||
JMP (D)
|
||
|
||
GBYTE: DEC ABSCNT
|
||
BLT GBYTE1
|
||
MOVB @ABSPNT,A
|
||
INC ABSPNT
|
||
ADD A,C
|
||
RTS PC
|
||
GBYTE1: MOV #2000,ABSCNT ;A BARFER LOAD
|
||
MOV #ABSBRF,ABSPNT
|
||
SAVE <#ABSBRF,#-2000,SYSFCP>
|
||
$BLKI
|
||
BR GBYTE
|
||
|
||
GWORD: JSR PC,GBYTE
|
||
SAVE A
|
||
JSR PC,GBYTE
|
||
MOVB A,1(P)
|
||
REST A
|
||
RTS PC
|
||
SYSFCP: 0
|
||
ABSPNT: 0
|
||
ABSCNT: 0
|
||
ABLDPD==.+20
|
||
ABSBRF==ABLDPD
|
||
ABSEND==.
|
||
.OFFSET 0
|
||
;THE PDL MAY GROW DOWN HERE ON A POWER FAILURE
|
||
.BLKW 100 ;FOR THE SYSTEM PDL
|
||
.=<.&177700>+200 ;MAKE A NICE NUMBER
|
||
PDL:
|
||
PARREG: .BLKW 20 ;FOR THE REAL PARITY REGISTERS
|
||
CHEKPN: CHEKBG
|
||
CHEKBG: .BLKW 20
|
||
CHEKEN::
|
||
SSTATS:: ;THE SYSTEM STATUS BLOCK
|
||
VERN ;SYSTEM VERSION
|
||
TIME: .BLKW 2 ;TIME IN 60TH'S SINCE SYS START
|
||
SVCSR: 0 ;THE CONSOLE SWITCHES
|
||
LOOKSW: 0 ;NON-ZERO=>PAY ATTENTION TO SWITCHES
|
||
NSTATS==<.-SSTATS>/2
|
||
;DON'T CHANGE ORDER OF THESE THINGS
|
||
FDATE: -1 ;FILE DATE
|
||
FTIME: -1 ;FILE TIME
|
||
SECNT: 1. ;HALF SECOND COUNTER
|
||
SECOND: 0 ;CURRENT SECOND
|
||
MINUTE: 0 ;MINUTE
|
||
HOUR: 0
|
||
DAY: 0
|
||
MONTH: 0
|
||
YEAR: -1
|
||
MONS: .BYTE 31.,28.,31.,30.,31.,30.,31.,31.,30.,31.,30.,31.
|
||
SECONL: 60.
|
||
MINUTL: 60.
|
||
HOURL: 24.
|
||
DAYL: 0 ;SET FROM MONS
|
||
MONTHL: 12.
|
||
YEARL: 2000. ;SYSTEM LOSES IN YEAR 2000.
|
||
RESETT: .WORD 0,0,0,1,1 ;VALUES TO RESET TO
|
||
TSHIFT: .WORD 4,5,5,6,5 ;AMOUNT TO SHIFT BY
|
||
TIMCHK: 0 ;IF NON-ZERO MAINTAIN LEVEL TABLE
|
||
LEVTAB: .BLKW 8. ;LEVEL CLOCK INTERUPTED FROM
|
||
MFITST: .FARUT!0 ;DATA BLOCK TO MAKE ROOT DIR
|
||
MFIBIT: ASCIZ <BITS>
|
||
MFISYS: ASCIZ <. SYSSPR>
|
||
MFIDSC: ASCIZ <DESCR>
|
||
.EVEN
|
||
PATCH:
|
||
PAT: .BLKW 140
|
||
SYSJPD: ;THE SYSTEM JOB'S PDL
|
||
BMT: .BYTE 1,2,4,10,20,40,100,200 ;BIT MARK TABLE
|
||
;FOR MARKING BIT TABLES, THE NTH ENTRY IS THE NTH BIT
|
||
DECTAB: .WORD 10000.,1000.,100.,10.,1,0
|
||
INITSW: -1 ;ZERO AFTER EXITING INIT CODE
|
||
PRUNNG: -1 ;ITEM # OF RUNNING PROCESS, NEG=> IN SYSTEM
|
||
;(THIS IS NOT SET TO -1 BY INTERUPT ROUTINES)
|
||
USRMOD: -1 ;IF A PROCESS IS RUNNING, NON-ZERO=> IN SYSTEM CODE
|
||
;0=>IN USER'S CODE
|
||
SYSSPR: -1 ;ITEM NUMBER OF THE SYSTEM SPHERE
|
||
CURUSR: -1 ;PROCESS BLOCK INDEX OF THE RUNNING PROCESS'S USER
|
||
CURSPH: -1 ;ITEM INDEX OF SPHERE OF THE RUNNING PROCESS
|
||
NEWPRI: .BLKW 2 ;PROCESS ID OF NEXT PROCESS TO BE CREATED
|
||
STPSVP: 0 ;SAVED P WHEN WE WENT TO START A PROCESS (FOR ERROR RECOVERY)
|
||
BPCLSR: 0 ;NON-ZERO WHEN IN PROCESS OF PCLSRING THE GUY GETTING UNLOCKED
|
||
QUANT: 0 ;NUMBER OF TICKS BEFORE THE RUNNING PROCESS SHOULD BE STOPPED
|
||
PQUANT: IQUANT ;QUANTUM TO GIVE A PROCESS WHEN YOU START IT
|
||
WQUANT: IQUANT*2 ;SAME, BUT FOR WINNERS
|
||
TUSED: 0 ;TIME THE PROCESS HAS USED SINCE LAST STARTED
|
||
STIMER: 0 ;TIME TILL NEXT CHECK OF SHORT FLUSHES
|
||
LTIMER: 0 ;TIME TILL NEXT CHECK OF LONG FLUSES
|
||
JTMUUP: JTMUUT ;NUMBER OF TICKS TILL NEXT UPDATE OF JTMUS
|
||
RUGVEC: 0 ;STORING PLACE FOR RUG'S VECTOR
|
||
RUGSTA: 0 ;DITTO FOR RUG'S STATUS
|
||
;SAVED VALUES FROM THE SEGMENTER
|
||
PSSR0: 0
|
||
PSSR1: 0
|
||
PSSR2: 0
|
||
PIRDIS: .WORD PIRLOS,STOPPR,TTYBRK,DMRBRK,PIRLOS,PIRLOS,PIRLOS,PIRLOS ;THE PIR DISPATCH
|
||
PIRBIT: .WORD 0,1000,2000,4000,10000,20000,40000,100000 ;THE PIR BITS
|
||
;EMT DISPACTCH TABLES
|
||
FOO==0
|
||
;REMEMBER THAT USER PROGRAMS DEPEND ON THESE TABLES
|
||
;NOT CHANGING ORDER
|
||
EMTDIS:
|
||
EMTD NOOP ;NOP CALL
|
||
EMTD FORK
|
||
EMTD POOFF
|
||
EMTD SLEEP
|
||
EMTD SINK
|
||
EMTD FLOAT
|
||
EMTD INVOK
|
||
EMTD QULK
|
||
EMTD QUNLK
|
||
EMTD TTGIV
|
||
EMTD TTGET
|
||
EMTD WRDI
|
||
EMTD WRDO
|
||
EMTD BYTI
|
||
EMTD BYTO
|
||
EMTD BLKI
|
||
EMTD BLKO
|
||
EMTD MAP
|
||
EMTD ALLOC
|
||
EMTD CRUSR
|
||
EMTD RDMAP
|
||
EMTD FONT
|
||
EMTD SSTAT
|
||
EMTD VIDSW
|
||
EMTD RUG
|
||
EMTD GERRW
|
||
EMTD TIME
|
||
EMTD SYSJB
|
||
EMTD GETID
|
||
EMTD MFPI
|
||
EMTHGH==FOO
|
||
.MACRO CLSTYD X
|
||
.'X'CAP==FOO
|
||
.=IVKCTB+<2*FOO>
|
||
CAPR'X
|
||
.IRP Y,<CCPR,CPY,DEL,GIV,TAK,DOIO>
|
||
.=.+CAPHGH-2
|
||
Y''X
|
||
.ENDM
|
||
.IIF P1,CAPHGH==CAPHGH+2
|
||
.=IVKCTB+<CAPHGH*7> ;7 IS THE NUMBER OF TABLES
|
||
FOO==FOO+1
|
||
.ENDM
|
||
.IIF P1,CAPHGH==0
|
||
FOO==0
|
||
|
||
;REMEMBER THAT USER PROGRAMS DEPEND ON THESE TABLES
|
||
;NOT CHANGING ORDER
|
||
IVKCTB:
|
||
|
||
CLSTYD XX ;THE ZERO CAPABILITY SHOULD NOT EXIST
|
||
CLSTYD CC ;CREATE CAPABILITY
|
||
CLSTYD MS ;MASTER SPHERE
|
||
CLSTYD SP ;SPHERE (NON-MASTER I.E. COPY OF MASTER)
|
||
CLSTYD PR ;PROCESS CAPABILITY
|
||
CLSTYD TT ;TELETYPE CAPABILITY (NO DATA WORDS)
|
||
CLSTYD FA ;FILE ACCESS CAPABILITY
|
||
CLSTYD QU ;THE QUE CAPABILITY
|
||
CLSTYD CL ;CORE LINK CAPABILIY
|
||
CLSTYD DS ;DISPLAY CAPABILITY
|
||
CLSTYD TR ;PAPER TAPE READER
|
||
CLSTYD TP ;PAPER TAPE PUNCH
|
||
CLSTYD LP ;LINE PRINTER CAPABILITY
|
||
CLSTYD CM ;COLOR MAP
|
||
|
||
;FIRST ITEM IS THE SPHERE
|
||
;SECOND IS SPHERE (IF ANY) IN CIRCULAR LIST OF SPHERES HAVING SHPERE
|
||
;CAPABILITY TO THIS SPHERE
|
||
;FIRST MISC IS FAULT ENTRY ADDRESS
|
||
;SECOND MISC IS C-LIST NUMBER (IF ANY) FOR CIRCULAR LIST
|
||
;BITS ARE:
|
||
.SPFES==4000 ;SURPRESS ENTERS THROUGH HERE
|
||
.SPCLC==10000 ;ALLOW COPY FROM C-LIST
|
||
.SPCLD==20000 ;ALLOW DELETE FROM C-LIST
|
||
.SPCRR==400 ;ALLOW CORE READ
|
||
.SPCRW==1000 ;ALLOW CORE WRITE
|
||
.SPCRE==2000 ;ALLOW CORE EXECUTE
|
||
;THESE FLAGS ARE FOR EMAP, DIFFERENT NAMES, SAME FUNCTION
|
||
.CRPRI==4000 ;PRIVATE PAGE
|
||
.CRRD==.SPCRR
|
||
.CRWRT==.SPCRW
|
||
.CREX==.SPCRE
|
||
.SPCAD==40000 ;ALLOW C-LIST APPEND
|
||
MSPCBT==.SPCAD!.SPCLC!.SPCLD!.SPCRR!.SPCRW!.SPCRE ;ALL SET IN SPHERE
|
||
|
||
;SAME PROPERTIES AS MASTER SPHERE, EXCEPT SOME BITS MAY NOT BE SET
|
||
;AND THERE IS NO ENTRY ADDRESS
|
||
;HERE ARE THE FUNCTIONS FOR THE .SPCAP AND .MSCAP INVOK'S
|
||
.SPPTT==0 ;PUT THE PROCESS INTO SPHERE
|
||
.SPCLR==1 ;READ THE C-LIST
|
||
|
||
;WORDS ARE ASSIGNED AS IN MASTER SPHERE AND ENTER ADDRESS IS STARTING ADDRESS
|
||
;BITS ARE:
|
||
.PRWRA==10000 ;ALLOW WRITING OF INFORMATION
|
||
|
||
;FLAGS ARE
|
||
.TTYO==10000 ;ALLOW OUTPUT TO TTY
|
||
.TTYI==20000 ;ALLOW INPUT FROM TTY
|
||
|
||
FAMFI==2 ;FIRST WORD IS MFI PTR
|
||
FAFPN==4 ;SECOND IS FILE PAGE NUMBER
|
||
FAUPT==6 ;THIRD IS GIP FOR FUPT
|
||
FAFBP==10 ;FOURTH IS BYTE PTR IN FILE PAGE (SEE 2ND WORD)
|
||
|
||
.FAEOFB==1000 ;SET IF THE POINTER IS IN THE LAST BLOCK OF THE FILE
|
||
.FAWD==2000 ;SET IF FIRST BYTE OF DKWDO IS WRITTEN
|
||
.FARD==4000 ;FILE READ ACCESS
|
||
.FAWT==10000 ;FILE WRITE ACCESS
|
||
.FAAP==20000 ;FILE APPEND ACCESS
|
||
.FAAC==40000 ;ACCESS CODES ACCESS
|
||
.FALB==100000 ;LOCK BIT
|
||
|
||
;NO FLAGS
|
||
|
||
;FIRST ITEM IS GIP TO THE BUFFER
|
||
;FLAGS ARE
|
||
.CLCONS==400 ;I AM THE CONSUMER FLAG
|
||
|
||
;IT HAS AN ITEM IF IT IS A TV DISPLAY, THE ITEM WORD IS 0 IF TV.
|
||
;THE FIRST MISCELLANEOUS WORD IS THE INDEX OF THE DISPLAY. FOR
|
||
;TK DISPLAYS, THIS NUMBER IS THE WORD INDEX INTO THE TKD TABLES.
|
||
;FOR TV DISPLAYS, IT IS STILL A WORD INDEX, AND SINCE THE TV TABLES
|
||
;ARE BYTE TABLES, THE NUMBER MUST BE DIVIDED BY 2 AND HAVE NFTVDS
|
||
;SUBTRACTED FROM IT BEFORE USE.
|
||
|
||
;NO FLAGS, ITEM IS THE PTR ITEM
|
||
|
||
;NO FLAGS, ITEM IS PTP ITEM
|
||
|
||
;NO FLAGS, ITEM IS THE LPT ITEM
|
||
|
||
;NO ITEM, THESE ARE FLAGS FOR CALLS:
|
||
.CMRED==2000 ;SET RED
|
||
.CMGRN==1000 ;SET GREEN
|
||
.CMBLU==400 ;SET BLUE
|
||
.CMBIT==100000 ;SET BIT COORESPONDENCE
|
||
;DISPATCH TABLES
|
||
FOO==IVKCTB
|
||
.IRP X,<CC,CPY,DEL,GIV,TAK,DOI>
|
||
FOO==FOO+CAPHGH
|
||
X'TAB=FOO
|
||
.ENDM
|
||
|
||
;GENERAL FUNCTIONS FOR INVOKE
|
||
.MACRO GENFUN NAME
|
||
NAME'CAP
|
||
.'NAME'CP==400*<200+FOO>
|
||
FOO==FOO+1
|
||
.ENDM
|
||
|
||
FOO==0
|
||
GENDIS: GENFUN DEL ;DELETE THE CAPABLITY
|
||
GENFUN CPY ;COPY THE CAPABILITY
|
||
GENFUN GIV ;GIVE THE CAPABILIITY AWAY
|
||
GENFUN TAK ;TAKE THE CAPABILITY (GIMMEE,GIMMEE)
|
||
GENHGH==FOO*2
|
||
|
||
;THIS IS THE DISPATCH TABLE FOR I-O DEVICES
|
||
|
||
.IRP OP,<WDI,WDO,BTI,BTO,BKI,BKO> ;INITIALZE TABLES FOR THESE TRANSFER TYPES
|
||
OP'TAB:
|
||
.IRP DEV,<DK,TT,CL,TR,TP,LP>
|
||
DEV'IDX==.IRPCN
|
||
DEV''OP
|
||
.ENDM
|
||
.ENDM
|
||
|
||
;THESE ARE THE TABLES FOR THE PROCESS INVOK
|
||
.MACRO PRINVK FUN,CNT
|
||
.PR'FUN==FOO
|
||
.IFB CNT
|
||
FOO==FOO+1
|
||
PR'FUN
|
||
.IFF
|
||
FOO==FOO+CNT
|
||
.REPT CNT
|
||
PR'FUN
|
||
.ENDR
|
||
.ENDC
|
||
.ENDM
|
||
|
||
FOO==0
|
||
PRIVTB: PRINVK REG,8 ;8 REGISTERS
|
||
PRINVK PSW ;PROGRAM STATUS WORD
|
||
PRINVK FREG,6 ;6 FLOATING POINT REGISTERS
|
||
PRINVK FPST ;FLOATING POINT STATUS WORD
|
||
PRINVK FPEN ;ENABLE FLOATING POINT
|
||
PRINVK STOP ;THE STOP WORD OF THE PROCESS
|
||
PRINVK ERR ;THE ERROR WORD
|
||
PRINVK FAUL ;THE FAULT WORD (OR WORDS)
|
||
PRINVK ERA ;ERROR ADDRESS IN SYSTEM
|
||
PRHGH==FOO*2
|
||
.PRRD==0 ;THE READ FUNCTION
|
||
.PRWRT==40 ;THE WRITE FUNCTION
|
||
|
||
.MACRO SPINVK FUN
|
||
.SP'FUN==FOO
|
||
FOO==FOO+1
|
||
SP'FUN
|
||
.ENDM
|
||
FOO==0
|
||
|
||
SPITAB: SPINVK PTP ;PUT PROCESS
|
||
SPINVK RCP ;RETURN CAPABILITY
|
||
SPINVK KIL ;KILL ALL PROCESSES
|
||
SPINVK STP ;STOP ALL PROCESSES
|
||
SPINVK STR ;START ALL PROCESSES
|
||
SPINVK PGT ;GET ID AND PC OF PROCESS
|
||
SPINVK GNP ;GET NUMBER OF PROCESSES
|
||
SPINVK GPC ;GET CAPABILITY TO PROCESS
|
||
SPINVK ENT ;SET THE ENTER ADDRESS
|
||
SPINVK STX ;SET X OF MAR
|
||
SPINVK STY ;SET Y OF MAR
|
||
SPINVK SMC ;SET MAR CONTROL REGISTER
|
||
SPIHGH==FOO
|
||
|
||
;FOR THE TTY INVOK
|
||
.MACRO TTIVK FNC
|
||
.'FNC==NTTFNC
|
||
FNC
|
||
NTTFNC==NTTFNC+1
|
||
.ENDM
|
||
|
||
.TTWRT==40
|
||
.TTIBK==400 ;TTY I/O FLAG SPECIFING AN INPUT TYPE BREAK
|
||
.TTMBK==10000 ;TTY FLAG SPECIFYING A MORE BREAK
|
||
.TTWD==40000 ;FLAG SAYING THAT FIRST BYTE DONE ON WORD OUTS
|
||
.TTEDM==1000 ;SAYING THAT THIS OUTPUT IS TO GO TO THE EDIT BUFFER
|
||
|
||
NTTFNC==0
|
||
;THESE FUNCTIONS WRITE IF THE .TTWRT BIT IS SET AND READ OTHERWISE
|
||
TTIVTB: TTIVK TTMOV ;MOVE INTO TTY STATUS WORD (ALWAYS WRITE)
|
||
TTIVK TTBIS ;BIS INTO TTY STATUS (ALWAYS WRITE)
|
||
TTIVK TTBIC ;BIC INTO TTY STATUS (ALWAYS WRITE)
|
||
TTIVK TTRD ;READ THE TTY STATUS (ALWAYS READ)
|
||
TTIVK TTCNO ;READ OR SET THE CHARNO VARIABLE
|
||
TTIVK TVATC ;ATTACH A DISPLAY BUFFER TO A TTY
|
||
TTIVK TVCL ;CLEAR THE SCREEN
|
||
TTIVK TTBRK ;READ THE LAST BREAK CHAR TYPED, HANG IF NONE
|
||
TTIVK TVREV ;REVERSE WHITE AND BLACK ON SCREEN
|
||
TTIVK TTMV2 ;SET TTYST2
|
||
TTIVK TTSPD ;SET THE SPEED AND LINE PARAMETERS (DH11 ONLY)
|
||
TTIVK TTTYP ;RETURN THE TYPE OF THE TTY TO THE USER
|
||
TTIVK TVFNT ;CHANGE THE FONT OF THE TV TTY
|
||
TTIVK TTBS2 ;BIS INTO TTY STATUS 2
|
||
TTIVK TTBC2 ;BIC INTO TTY STATUS 2
|
||
TTIVK TVSET ;READ OR SET TVLINE AND TVCUR
|
||
TTIVK TVOFF ;READ OR SET TVOFFL
|
||
TTIVK TVRFN ;READ CHAR WIDTH IN BITS AND LINE HEIGHT IN TVLINES
|
||
TTIVK TTPEK ;PEEK AT THE NEXT CHARACTER
|
||
TTIVK TVMOD ;SET THE CURSOR WRITING MODE
|
||
TTIVK TBRAK ;CAUSE BREAK ON LINE FOR (ARG) NUMBER OF CHARACTERS
|
||
TTIVK TTSLNL ;SET LINE LENGTH
|
||
|
||
;THE TV WRITING MODES
|
||
.TVIOR=TVIOR_-6
|
||
.TVXOR=TVXOR_-6
|
||
.TVMOV=TVMOV_-6
|
||
|
||
|
||
.IFNZ NTVS
|
||
.MACRO TDSIVK FUNCTION
|
||
.WORD FUNCTION
|
||
.'FUNCTION==TVDSIM+100
|
||
TVDSIM==TVDSIM+1
|
||
.ENDM
|
||
|
||
TVDSIM==0
|
||
;TV DISPLAY INVOKES
|
||
TVDSIT: TDSIVK TVDSRC ;READ THE CURSOR
|
||
TDSIVK TVDSSC ;SET THE CURSOR
|
||
TDSIVK TVDSNL ;DRAW A NULL LINE
|
||
TDSIVK TVDSIL ;IOR A LINE
|
||
TDSIVK TVDSXL ;XOR A LINE
|
||
TDSIVK TVDSCL ;CLEAR A BLOCK OF THE SCREEN
|
||
TDSIVK TVSAVE ;SAVE TV REGISTERS FOR THIS PROCESS
|
||
TDSIVK TVMAPS ;MAP IN TV PAGES FOR THIS PROCESS
|
||
|
||
;VIDEO SWITCH MODES
|
||
.VIABS==0 ;ABSOLUTE MODE
|
||
.VILOT==1 ;LOGICAL TTY NUMBER MODE
|
||
.VILOD==2 ;LOGICAL DISPLAY NUMBER MODE
|
||
.VICAM==3 ;CAPABILITY MODE
|
||
.ENDC
|
||
|
||
.IRPC X,<012>
|
||
ITEM'X: -1 ;ITEM CURRENTLY IN PAGE ITM0
|
||
ITM'X'PB: 0 ;IF ITEM IS A GIP, THIS IS THE PB FOR IT
|
||
ITM'X'A: ITM'X'AD ;ADDRESS OF ITEM IN ITEM'X
|
||
ITM'X'D: 0 ;PUSH DEPTH
|
||
ITM'X'P: ITM'X'PD ;PDL POINTER FOR ITM'X
|
||
.BLKW NITMPS ;PDL FOR ITM'X'
|
||
ITM'X'PD::
|
||
.ENDM
|
||
|
||
ITMATB: .BLKW 200 ;ITEM ALLOCATE TABLE (ONE WORD PER SIZE)
|
||
;THESE POINT INTO ITMALS
|
||
ITMBAL: .BLKW 1 ;ITEM BLOCK STORAGE ALLOCATE LOCK
|
||
INITM1:: ;INITIALIZE FOLLOWING AREA TO -1
|
||
ITMBNF: .BLKW NITMBL ;NUMBER OF BLOCKS FREE IN THIS BIG BLOCK
|
||
ITMBST: .BLKW NITMBL ;ADDRESS OF FIRST BLOCK OF THIS BIG BLOCK
|
||
ITMBTP: .BLKW NITMBL ;POINTERS TO BEGGININGS OF BIT TABLES
|
||
.BLKW 1 ;THIS IS THE BACKWARDS-SEARCHING FENCE FOR THE 1ST BIT TABLE
|
||
ITMBIT: .BLKW 11*NITMBL ;8 WORD BIT TABLE FOR EACH BIG BLOCK
|
||
;AND A FENCE BETWEEN THE BLOCKS
|
||
EINTM1:: ;END OF STUFF TO INIT TO -1
|
||
;TABLES AND SYMBOLS FOR THE FILE SYSTEM
|
||
|
||
;MACRO TO DEFINE FILE ACCESS CAPABILITY FUNCTIONS
|
||
.MACRO MFADCF SYMBOL
|
||
.FA'SYMBOL==FOO
|
||
MFA'SYMBOL
|
||
FOO==FOO+1000
|
||
.ENDM
|
||
FOO==0
|
||
FATAB:
|
||
MFADCF CF ;CLEAR FLAGS
|
||
MFADCF RE ;RETURN EOF WORDS
|
||
MFADCF SP ;SET POINTER
|
||
MFADCF RP ;RETURN POINTER
|
||
MFADCF DL ;DELETE ENTRY
|
||
MFADCF AD ;ADD ENTRY
|
||
MFADCF MU ;MUTATE CAPABILITY
|
||
MFADCF MB ;SET UP BIT TABLE FOR ROOT DIR
|
||
MFADCF RI ;RETURN INFORMATION ABOUT THE FILE
|
||
MFADCF DI ;RETURN INFORMAITON ABOUT THE DISK
|
||
MFADCF SDL ;DELETE THE FILE OR DIRECTORY, EVEN IF STUFF IN DIR
|
||
MFADCF MD ;MAKE A DIRECTORY
|
||
MFAHGH==<FOO-1000>/400
|
||
|
||
;STUFF FOR GROVELING THROUGH DESCRIPTORS
|
||
MFBLTB: MFBSKP ;SKIP AND GRAB ONE
|
||
MFBGET ;GET LOTS
|
||
MFBSET ;SET ADDRESS AND GRAB LOTS
|
||
MFBSKG ;SKIP SOME, GRAB SOME
|
||
MFENTB: MFESKP ;SKIP AND GRAB ONE
|
||
MFEGET ;GET LOTS
|
||
MFESET ;SET ADDRESS AND GRAB LOTS
|
||
MFESKG ;SKIP SOME, GRAB SOME
|
||
ENTPNT: 0 ;POINTER INTO MFI
|
||
ENTEND: 0 ;END OF MFI ENTRY
|
||
ENTCNT: 0 ;COUNT FOR COUNT TYPES
|
||
ENTMOD: 0 ;MODE OF CURENT BYTE, USED FOR ADDING A BLOCK
|
||
.SBTTL PROCESS QUEUES
|
||
;FOR THE PROCESS TABLE
|
||
;MACRO FOR DEFINING A QUEUE
|
||
.MACRO DEFQ NAME
|
||
NAME'Q: .BLKW 2
|
||
NAME'QB==1_FOO
|
||
1_FOO
|
||
FOO==FOO+1
|
||
.ENDM
|
||
QLEN==6 ;THE LENGTH OF A QUEUE POINTER
|
||
QBIT==4 ;POSITION OF QUEUE BIT WITHIN THE POINTER
|
||
FOO==0 ;INITALIZE THE QUEUE NUMBER
|
||
FIRSTQ==.
|
||
DEFQ WIN ;GUYS WHO ARE REAL WINNERS
|
||
DEFQ ACT ;GUYS WHO ARE MODERATE WINNERS
|
||
DEFQ DOR ;MODERATE WINNERS WHO ARE HUNG
|
||
DEFQ RUN ;GUYS WHO WANT TO RUN BUT ARE LOSERS
|
||
DEFQ IACT ;GUYS WHO ARE HUNG AND ARE LOSERS
|
||
DEFQ STOP ;GUYS WHO ARE STOPPED
|
||
DEFQ USER ;FOR CONFORMITY, USERS ARE KEPT HERE
|
||
DEFQ SPHR ;FOR CONFORMITY SPHERES ARE KEPT HERE
|
||
NQS==FOO
|
||
PFREQB==1_FOO
|
||
PFREEQ: .WORD PRSTAB,0,PFREQB ;FREE PROCESS BLOCKS LIST POINTER
|
||
FOO==PRSTAB+PRSTEL
|
||
FOOBAR==PFREEQ
|
||
PRSTAB: .REPT NPROSS
|
||
FOO
|
||
FOOBAR
|
||
FOO==FOO+PRSTEL
|
||
FOOBAR==.-4
|
||
.=.+PRSTEL-4
|
||
.ENDR
|
||
.WORD 0,FOOBAR
|
||
.BLKB PRSTEL-2 ;THE LAST PROCESS BLOCK MUST GO HERE
|
||
|
||
DTHING ;THE PROCESS ACTIVATE BLOCKS
|
||
DWORD ACTLNK ;LINK WORD
|
||
DWORD ACTITM ;PROCESS ITEM
|
||
DWORD ACTPI1 ;ID WORD 1
|
||
DWORD ACTPI2 ;ID WORD 2
|
||
ILISTS ACTFRE,,10. ;TEN OUGHT TO BE PLENTY
|
||
ACTLST: 0 ;LIST TO ACTIVATE
|
||
PTRITM: 0 ;PAPER TAPE READER ITEM NO.
|
||
PTPITM: 0 ;PAPER TAPE PUNCH ITEM NO.
|
||
LPTITM: 0 ;CONTAINS ITEM NO OF THE LINE PRINTER ITEM
|
||
CMUSE: 0 ;COUNT OF COLOR MAP CAPS
|
||
|
||
.SBTTL RANDOM DISK PARAMETERS
|
||
NRRKD==4 ;NUMBER OF REGULAR RK11S
|
||
NRFD==0 ;NUMBER OF RF11 DISKS
|
||
|
||
NDISKS==NRRKD+NRFD ;TOTAL NUMBER OF DISKS
|
||
|
||
NSWPA==NDISKS ;MAX NUMBER OF DISK SWAP AREAS
|
||
|
||
MNRTY==50. ;NUMBER OF TIMES TO RETRY OPERATION
|
||
|
||
NDRQBL==20 ;NUMBER OF LOW LEVEL DISK REQUEST BLOCKS TO ALLOCATE
|
||
|
||
;LOW LEVEL DISK REQUEST BLOCKS
|
||
DTHING
|
||
DWORD DRQLNK ;LINK WORD
|
||
DWORD DRQDNO ;DISK NUMBER
|
||
DWORD DRQHCA,DRQFUN ;HIGH CORE ADDRESS,,FUNCTION (ALSO GETS ERROR BIT)
|
||
DRQFER==100000 ;INT ROUTINES SET THIS BIT TO INDICATE ERROR
|
||
DWORD DRQCA ;CORE ADDRESS (LOW PART)
|
||
DWORD DRQDA ;DISK BLOCK ADDRESS
|
||
DWORD DRQWC ;WORD COUNT
|
||
DWORD DRQABL ;PAGE REQUEST BLOCK TO ACTIVATE
|
||
ILISTS DSKRFL,,NDRQBL ;ALLOCATE NDRQBL OF THESE BLOCKS
|
||
|
||
;MIDDLE LEVEL DISK REQUEST BLOCKS
|
||
DTHING
|
||
DWORD DMRLNK
|
||
DWORD DMRPBP ;PAGE BLOCK POINTER
|
||
;NEXT 3 MUST STAY IN THIS ORDER
|
||
DWORD DMRPWK ;ITEM OF PROCESS TO WAKE UP
|
||
DWORD DMRPW1 ;ID WORD 1 OF PROCESS TO WAKE UP
|
||
DWORD DMRPW2 ;ID WORD 2 OF PROCESS TO WAKE UP
|
||
DWORD DMRFUN ;FUNCTION
|
||
DWORD DMRDRC ;COUNT OF DISK REQUESTS ENTERED FOR THIS BLOCK
|
||
DWORD DMRPBB ;PB BIT(S) TO CLEAR ON COMPLETION OF REQUESTS
|
||
ILISTS DMRPNT,,10. ;ONLY 10 OF THESE=> MAX OF 10 PAGES MOVING AT ONCE
|
||
.SBTTL CORE DATA STRUCTURE DEFINITIONS
|
||
|
||
;DEFINITION OF A PAGE BLOCK
|
||
DTHING
|
||
DWORD PBFLAG ;WORD OF RANDOM FLAGS, USED AS LINK IN FREE LIST
|
||
DFLAGS
|
||
DFLAG PBUSED ;MUST BE THE 1 BIT-SET IF USED
|
||
DFLAG PBZERO ;THIS PAGE WANTS TO BE ZERO
|
||
DFLAG PBWCHK ;THIS PAGE SHOULD ALWAYS BE WRITE-CHECKED
|
||
DFLAG PBVAS ;PAGE IS VALID AT SOURCE
|
||
DFLAG PBVASS ;PAGE IS VALID AT SWAP SPACE
|
||
DFLAG PBVACR ;PAGE IS VALID AT CORE
|
||
DFLAG PBFILE ;PAGE IS A FILE PAGE
|
||
DFLAG PBSTS ;PAGE SHOULD BE SWAPPED TO SOURCE
|
||
DFLAG PBDISK ;PAGE HAS DISK TRANSFER(S) PENDING
|
||
DFLAG PBLOCK ;HANDS OFF!
|
||
DFLAG PBERR ;PAGE IN ERROR DUE TO DISK LOSSAGE
|
||
DFLAG PBNOSW ;NEVER ASSIGN SWAP SPACE
|
||
DWORD PBLKPC ;TEMP WORD, PC PB LOCKED FROM
|
||
DWORD PBLKPS ;TEMP WORD, PROCESS THAT LOCKED PB
|
||
DWORD PBGIP ;GIP IN TH ECIRC LIST OF GIPS FOR THIS PAGE
|
||
DWORD PBCAR ;CORE ADDRESS, ZERO=>OUT
|
||
DWORD PBRAN,PBLEN ;RANDOM (START AND DISK #),,LENGTH
|
||
PBSTRT==177770 ;MASK FOR START
|
||
PBDSKM==177407 ;MASK FOR DISK
|
||
PBDISS==2 ;DISK SHIFT (LOW ORDER BIT OF DISK IS 0)
|
||
DWORD PBDA ;START OF SWAP AREA ADDRESS
|
||
DWORD PBAUSR ;NUMBER OF ACTIVE USERS OF THIS PAGE
|
||
ILISTS PBFREL,,50. ;ALLOW FOR 50 DIFFERENT PAGES TO EXIST
|
||
;THE FOLLOWING IS THE EXTENSION OF PAGE BLOCKS TO FILE PAGE BLOCKS
|
||
DWORD PBSDSK ;THE DISK THE SOURCE IS ON
|
||
DWORD PBSDA ;THE SOURCE DISK ADDRESSES (8 OF THEM)
|
||
FOO==PBSDA+20 ;ALLOCATE THEM
|
||
DWORD PBFLEN,PBNEWB ;LENGTH OF PAGE IN BLOCKS, # OF NEW BLOCK
|
||
DWORD PBFLNK ;LINK BETWEEN PBS FOR THIS FILE
|
||
DWORD PBFPNO ;PAGE NUMBER IN FILE THAT THIS FPB IS FOR
|
||
DWORD PBMFIP ;POINTER BACK TO MFI FOR THIS FPB
|
||
ILISTS FPBFRE,,50. ;ALLOW FOR 50 FILE PAGES
|
||
|
||
;DEFINITION OF A UPT OR FUPT
|
||
DTHING
|
||
DWORD UPTFLG,UPTSTL ;FLAGS, START AND LENGTH
|
||
DFLAGS
|
||
DFLAG UPTEXB ;THIS PAGE EXISTS!
|
||
DFLAG UPTABS ;ABSOLUTE PAGE
|
||
DFLAG UPTEXD ;EXPAND DOWN
|
||
DFLAG UPTRDO ;READ ONLY
|
||
DFLAG UPTEXO ;EXECUTE ONLY
|
||
DFLAG UPTIED ;I=D, THIS SET IN THE I SPACE PAGE
|
||
DFLAG UPTDEI ;D=I, THIS SET IN THE DATA PAGE
|
||
UPTLMS==177770 ;LENGTH
|
||
UPTSMS==177617 ;START
|
||
UPTSSH==4 ;SHIFT FOR START
|
||
DWORD UPTPBP ;POINTER TO PAGE BLOCK (AR OF ABS PAGE)
|
||
DWORD UPTGIP ;CIRCULAR LIST POINTER (DR OF ABS PAGE)
|
||
UPTLEN==FOO ;LENGTH OF UPT
|
||
;FOR FUPTS ALSO HAVE:
|
||
DWORD FUPTPR ;POINTER TO PROCESS THAT CURRENTLY "OWNS" THIS FUPT
|
||
ILISTS FUPTFR,,50. ;ALLOCATE 50 FUPTS
|
||
|
||
;LIST FOR DELETEING UPT OR FUPTS
|
||
DTHING
|
||
DWORD DLULNK ;LINK WORD
|
||
DWORD DLUUPT ;UPT TO DELETE
|
||
ILISTS DLUFRE,,10.
|
||
DLULST: 0 ;DLU LIST TO ACT ON
|
||
.SBTTL DISK RANDOM STORAGE
|
||
DSKPS: 0 ;PDL POINTER SAVE FOR ERROR CHECK
|
||
DSKPSV: 0 ;PDL POINTER SAVE FOR MAIN PROG PDL POINTER
|
||
DSKP: DPDL-14 ;PDL POINTER FOR DISK ROUTINES
|
||
.BLKW 100 ;DPL STORAGE FOR DISK
|
||
DPDL: DSTART ;CAREFULLY INITED PDL
|
||
|
||
DSKRQ: 0 ;POINTER TO LIST OF PENDING REQUESTS
|
||
DRQDL: 0 ;POINTER TO LIST OF DONE REQUESTS
|
||
DRQFCN: NDRQBL ;NUMBER OF FREE DISK REQUEST BLOCKS
|
||
DMRLST: 0 ;MIDDLE LEVEL DISK REQUEST LIST
|
||
|
||
DISKER: .BLKW NDISKS ;ERRORS ON EACH DISK
|
||
DSKOFS: .REPT NRRKD
|
||
.RPCNT_13.
|
||
.ENDR
|
||
DSKRQS: ;SERVICE ROUTINES FOR THE VARIOUS DISKS
|
||
.REPT NRRKD
|
||
RKDSKS
|
||
.ENDR
|
||
|
||
DSKREA==0 ;READ
|
||
DSKWRT==2 ;WRITE
|
||
DSKWCH==4 ;IF THIS BIT IS SET, WRITE-CHECK AFTER READ OR WRITE
|
||
DKWCH==10 ;THE INDEX OF THE WRITE CHECK FUNCTION
|
||
|
||
RKFUN: 105 ;READ
|
||
103 ;WRITE
|
||
105 ;READ W DSKWCH SET
|
||
103 ;WRITE W DSKWCH SET
|
||
107 ;WRITE CHECK
|
||
|
||
NRETRY: 0 ;NUMBER OF DISK RETRYS BEFORE GIVIN GUP
|
||
DERBL: .BLKW 10 ;PLACE WHERE THE LAST ERROR IS STORED
|
||
CURDSK: RKCS ;CS OF THE CURRENTLY RUNNING DISK
|
||
MFBITS: .BLKW NDISKS ;FUPTS OF BIT TABLES
|
||
MFFREE: .BLKW NDISKS ;COUNT OF FREE BLOCKS
|
||
MFBLNK: .BLKW NDISKS ;LINK THROUGH MFI'S ACTIVE ON THIS DISK
|
||
MFROVR: .BLKW NDISKS ;ROVING POINTER INTO BIT TABLE
|
||
|
||
;FILE NAME BLOCKS
|
||
FNBNML==20. ;MAX CHARS IN A FILE NAME
|
||
DTHING
|
||
DWORD FNBFNE ;END OF THE FILE NAME IN THE USER
|
||
DWORD FNBVER ;VERSION NUMBER OF THE FILE NAME
|
||
DWORD FNBFNO ;NUMBER O FFILE IN DIR
|
||
DWORD FNBFNL ;LENGTH OF FILE NAME
|
||
DWORD FNBFN ;ACTUAL FILE NAME
|
||
FOO==FNBFN+FNBNML ;ALLOCATE ENOGUH SPACE FOR FILE NAME
|
||
ILISTS FNBFRE,,4 ;SHOULDN'T NEED VERY MANY
|
||
.SBTTL RANDOM STORAGE FOR SWAP AREA INFO
|
||
SWPBPT: SWPBIT ;POINTERS TO THE SWAP AREA BITS TABLES
|
||
.BLKW NSWPA
|
||
SWPBDK: .BLKW NSWPA ;DISK NUMBER FOR THIS SWAP AREA
|
||
SWPBDA: .BLKW NSWPA ;BEGGINING DISK ADDRESS FOR THIS SWAP AREA
|
||
SWPEDA: .BLKW NSWPA ;ENDING DISK ADDRESS FOR THIS SWAP AREA
|
||
SWPFCN: .BLKW NSWPA ;NUMBER OF FREE SWAP BLOCKS IN THIS SWAP AREA
|
||
SWPBIT: .BLKW 105 ;ACTUAL SWAPPING BIT TABLES
|
||
SWPBTE:: ;END OF BIT TABLES
|
||
|
||
BITS: .WORD 1,2,4,10,20,40,100,200
|
||
.WORD 400,1000,2000,4000,10000,20000,40000,100000
|
||
|
||
BITSST: .WORD 0,1,3,7,17,37,77,177,777,1777
|
||
.WORD 3777,7777,17777,37777,77777,177777
|
||
|
||
MNCBLK==124.*2 ;MAX NUMBER OF BLOCKS OF CORE TO WORRY ABOUT
|
||
.IIF NZ NTVS,MNCBLK==108.*2 ;NOT AS MANY POSSIBLE IF TVS EXIST
|
||
.SBTTL RANDOM STORAGE FOR CORE INFORMATION
|
||
DFLAGS
|
||
DFLAG CSTFRB ;INDICATES BLOCK IS FREE
|
||
DFLAG CSTSYB ;INDICATES BLOCK USED BY SYSTEM
|
||
DFLAG CSTBEB ;THE BLOCK EXISTS BIT
|
||
CST: .BLKW MNCBLK ;CORE STATUS TABLE
|
||
0 ;MAKE SURE THE TABLE HAS AN END
|
||
CSTPB: .BLKW MNCBLK ;PB POINTERS FOR CORE USED BY PBS
|
||
FREECR: 0 ;AMOUNT OF CORE THAT IS FREE
|
||
CSTROV: CSTPB ;FOR LOGJAMS, PLACE TO SWAP A PAGE OUT
|
||
CST1FR: CST+<FSTFRB*2> ;POINTER TO FIRST FREE CST ENTRY
|
||
CST1NS: CST+<FSTFRB*2> ;POINTER TO FIRST NON-SYSTEM CST ENTRY
|
||
CSTTOP: 0 ;POINTER TO LAST REAL WORD IN CST
|
||
USRCOR: 0 ;AMOUNT OF CORE NOT USED BY SYSTEM
|
||
SYSUPD: 0 ;NUMBER OF TIMES SYS JOB HAS DELETEED UPTS
|
||
LOGJAM: 0 ;TIMES WHEN THERE WAS NOT ENOUGH CONGIOUS SPACE
|
||
;TO PUT SOME SIZE PAGE, BUT THERE WAS MORE THAN
|
||
;6K ACTUALLY FREE
|
||
NOFIT: 0 ;NUMBER OF TIMES A PAGE COULDN'T FIT IN CORE
|
||
;WHEN THERE WAS ENOUGH FREE
|
||
HSECNT: 30. ;60THS TILL TIME TO INC HSECS
|
||
HSECS: 0 ;TIME IN .5 SECS, FOR SWAP DESICIONS
|
||
LTPSTA: 0 ;LAST TIME PROCESS STARTED (IN .5 SEC)
|
||
ACTCHK: 0 ;FLAG TO INDICATE CHECKING FOR ACTIVATING PROSSES
|
||
ACORE: 0 ;AMOUNT OF CORE POTENITIALLY NEEDED BY ACTIVE PROCESSES
|
||
PBSWPO: .BLKW 50. ;PAGES WHICH MAY BE SWAPPED OUT
|
||
PBSWOE: 0 ;DUMMY END ENTRY
|
||
NPBSWO: 0 ;NUMBER OF PBS ON SWAP OUT LIST
|
||
KERSBT: .BLKB 16.*3 ;KERNAL, NON-EX AND SUPER
|
||
.REPT 16. ;USER
|
||
.BYTE 1 ;SEGBRK LEGAL ON ALL PAGES
|
||
.ENDR
|
||
.IRPC X,<012>
|
||
ITM'X'KB==KERSBT+<<ITM'X'AR-I0AR>/2> ;BYTE FOR A PARTICULAR PAGE
|
||
.ENDM
|
||
.SBTTL ASSEMBLE THE STUFF GENEATED BY THE REMOTE MACROS
|
||
LSTSTO ;STORAGE FOR THE LISTS
|
||
LSTEND: ;END OF LIST STORAGE AREA
|
||
INITSL ;INIT TABLE FOR THE LISTS
|
||
0
|
||
;DISPLAY VARIABLES
|
||
;AND PARAMTERS
|
||
.IFNZ NTKDIS
|
||
DISMAL==2
|
||
DISBIG==4
|
||
TKDLEN: .WORD DISMAL,DISMAL,DISMAL,DISBIG
|
||
.IIF NE .-TKDLEN-<2*NTKDIS>,.ERROR BAD TKDLEN TABLE LENGTH
|
||
TKDITM: .BLKW 8. ;THE ITEMS FOR THE DISPLAYS
|
||
TKDOWN: .BLKW 8. ;IF DISPLAY OWNED
|
||
TKDPDA: 0 ;PDL ADDRESS
|
||
TKDPDL: 0 ;THE ITEM FOR THE DISPLAY PDLS
|
||
TKRELS: 0 ;THE RELOCATION REGISTER FOR THE DISPLAY
|
||
TKDRUN: .WORD -1,-1,-1,-1,-1,-1,-1,-1 ;THE RUN FLAGS
|
||
TKDPDP: .WORD 40,130,220,310,400,470,560,650 ;PDL POINTERS FOR EACH DISPLAY
|
||
DPUSHJ==100000
|
||
DSTOP==140400
|
||
TKRUN==4000
|
||
TKGO==10000
|
||
TKSTOP==20000
|
||
.ENDC
|
||
|
||
.IFNZ NTVS
|
||
NFTVDS==NTKDIS ;THE FIRST TV IS THE ONE AFTER THE TK DISPLAYS
|
||
|
||
;THIS TABLE CONTAINS THE REFERENCE COUNTS FOR EACH OF THE TVS. THE BUFFER
|
||
;FOR A TV SHOULD BE RELEASED WHEN THE REFERENCE COUNT REACHES ZERO. THE
|
||
;REFERENCE COUNT CAN BE INCREMENTED FOR EACH TTY ITEM WHICH REFERS TO
|
||
;THIS TV AND FOR EACH DISPLAY CAPABILITY TO THE TV.
|
||
TVDSRF:
|
||
.REPT NTVS
|
||
.BYTE 0
|
||
.ENDR
|
||
|
||
;TVDSBF CONTAINS THE BUFFER NUMBER OF EACH TV. THIS NUMBER IS -1 WHEN
|
||
;THERE IS NO BUFFER ALLOCATED TO A PARTICULAR TV.
|
||
TVDSBF:
|
||
.REPT NTVS
|
||
.BYTE -1
|
||
.ENDR
|
||
|
||
;TVBUFF SHOWS WHICH BUFFERS HAVE BEEN ALLOCATED. IF THE VALUE IS -1,
|
||
;THEN THE BUFFER IS FREE. OTHERWISE, IT CONTAINS THE NUMBER OF THE
|
||
;TV WHICH USES THIS BUFFER.
|
||
TVBUFF:
|
||
.REPT NTVCHN
|
||
.BYTE -1
|
||
.ENDR
|
||
.ENDC
|
||
|
||
|
||
;TV DISPLAY CURSOR (OR TURTLE) VARIABLES
|
||
;Y POSITIONS
|
||
TVDSCY: .REPT NTVCHN
|
||
.WORD 0
|
||
.ENDR
|
||
|
||
;X POSITIONS
|
||
TVDSCX: .REPT NTVCHN
|
||
.WORD 0
|
||
.ENDR
|
||
|
||
;FONT TABLE CONTAINS THE ITEM OF EACH FONT
|
||
NFONTS==4 ;INITIALLY, THERE CAN BE TWO FONTS
|
||
FNTITM: .BLKW NFONTS
|
||
.INSRT STYI >
|
||
CHEKIN: SAVE PS
|
||
SPL 7
|
||
ADD #2,CHEKPN
|
||
CMP #CHEKEN,CHEKPN
|
||
BHI 1$
|
||
MOV #CHEKBG,CHEKPN
|
||
1$: MOV 2(P),@CHEKPN
|
||
REST PS
|
||
RTS PC
|
||
|
||
.SBTTL DISK INTERUPT LEVEL ROUTINES
|
||
|
||
;ALL DISK INTERUPTS COME HERE-ONLY ONE DISK CAN BE ACTIVE AT A TIME
|
||
;IN THIS SCHEME.
|
||
RKBRK:RFBRK:
|
||
DSKBRK: JSR F,ACSAV ;COMPLETE THE SAVE OF THE CURRENT CONTEXT
|
||
MOV P,DSKPSV ;SAVE A POINTER TO THE "FRAME"
|
||
MOV DSKP,P ;POINT TO DISK CONTEXT FRAME
|
||
MOV P,DSKPS ;SAVE FOR ERROR CHECKING
|
||
JMP ACRET
|
||
|
||
;THIS IS THE ROUTINE TO CALL TO RETURN TO NORMAL CONTEXT UNTIL NEXT INTERUPT
|
||
|
||
DFLUSH: CMP DSKP,DSKPS ;CHECK THAT STACK DIDN'T OVERFLOW
|
||
BUGC NE
|
||
JSR F,ACSAV ;SAVE THE DISK LEVEL CONTEXT
|
||
MOV P,DSKP ;AND THE FRAME POINTER
|
||
MOV DSKPSV,P ;PREPARE TO RESTORE REGULAR CONTEXT
|
||
JSR F,ACRES ;RETORE REGISTERS
|
||
CHECKP
|
||
RTT ;RETORE PS AND PC
|
||
|
||
|
||
;MAIN DISK SERVICE LOOP
|
||
;PICKS UP REQUESTS FROM THE DSKRQ LIST AND SERVICES THEM
|
||
;BY CALLING SERVICE ROUTINE FOR PROPER DISK
|
||
|
||
DSTART: MOV DSKRQ,A ;GET FIRST NODE ON LIST
|
||
BNE DSKRQP ;GOT ONE, GO PROCESS IT
|
||
CLR @CURDSK ;NO REQUEST, CLEAR CS OF CURRENT DISK
|
||
JSR PC,DFLUSH ;AND RETURN CONTROL
|
||
BR DSTART ;GO TRY AGAIN
|
||
|
||
;REALLY PROCESS A REQUEST
|
||
DSKRQP: MOV (A),DSKRQ ;TAKE THE BLOCK OFF THE LIST
|
||
CLR (A) ;AND CLEAR ITS LINK POINTER
|
||
MOV #MNRTY,NRETRY ;NUMBER OF TIMES TO TRY BEFORE YOU GIVE UP
|
||
DSKRQR: MOVB DRQDNO(A),B ;GET THE DISK NUMBER
|
||
MOVB DRQFUN(A),D ;AND THE FUNCTION
|
||
JSR PC,@DSKRQS(B) ;RUN THE SERVICE ROUTINE
|
||
BNE DSKRQD ;ERROR ON TRANSFER?
|
||
DEC NRETRY ;HAVE WE EXHUASTED RETRY COUNT?
|
||
BGE DSKRQR ;IF NOT, GO RETRY
|
||
BIS #DRQFER,DRQHCA(A) ;SET THE TRANSFER ERROR BIT
|
||
DSKRQD: MOV #DRQDL,B ;ADDRESS OF BEG OF THE DONE LIST
|
||
JSR PC,BLISTE ;GET TO END OF LIST IN B
|
||
MOV A,(B) ;PUT THIS ONE ON THE END OF THE LIST
|
||
BIS #DMRPIR,PIRQ ;CAUSE A MIDDLE LEVEL INTERUPT
|
||
BR DSTART ;AND TRY FOR ANOTHER
|
||
|
||
;SEARCH TO THE END OF THE LIST POINTED TO BY B
|
||
;LEAVE THE POINTER IN B POINTING TO THE LINK WORD
|
||
;OF THE NODE ON THE END OF THE LIST
|
||
BLISTE: TST (B) ;IS THIS THE LAST NODE
|
||
BEQ BLIST1 ;YUP
|
||
MOV (B),B ;GO TO NEXT NODE
|
||
BR BLISTE
|
||
BLIST1: RTS PC
|
||
;ENTER HERE TO WRITE-CHECK THE FUNCTION YOU JUST PERFORMED
|
||
RKDSKW: MOV #DKWCH,D ;CHANGE FUNCTION TO WRITE CHECK
|
||
|
||
;THE DISK SERVICE ROUTINE FOR REGULAR TYPE RK11 DISKS
|
||
RKDSKS: MOV #RKCS,CURDSK ;THE RK11 IS THE CURRENT DISK
|
||
MOV #RKDA,C ;POINTER TO THE DISK REGISTERS
|
||
CLR E ;FOR THE DIVIDE
|
||
MOV DRQDA(A),F ;GET THE DISK ADDRESS
|
||
ASL F ;CONVERT TO 256 WORD BLOCKS
|
||
DIV #12.,E ;CONVERT TO CYLENDIR AND SECTOR ADDRESSES
|
||
ASH #4,E ;PUT THE CYLENDER ADDRESS IN THE RIGHT PLACE
|
||
BIS F,E ;AND THE SECTOR ADDRESS
|
||
BIS DSKOFS(B),E ;THE DISK NUMBER TOO
|
||
MOV E,(C) ;ALL THAT JUST FOR THE DISK ADDRESS
|
||
MOV DRQCA(A),-(C) ;CORE ADDRESS IS SIMPLE
|
||
MOV DRQWC(A),-(C) ;SO IS WORD COUNT
|
||
MOV DRQHCA(A),E ;HIGH CORE ADDRESS IS HARDER
|
||
ASH #4,E ;PUT IT IN THE RIGHT PLACE
|
||
BIS RKFUN(D),E ;AND BIS IN THE FUNCTION
|
||
MOV E,-(C) ;START UP THE DISK!
|
||
RKDSWT: JSR PC,DFLUSH ;WAIT FOR TH ENEXT INTERUPT
|
||
TSTB (C) ;IS THE DISK REALLY DONE?
|
||
BGE RKDSWT ;NOPE, KEEP WAITING
|
||
TST (C) ;WAS THERE AN ERROR?
|
||
BLT RKDSKE ;BRANCH IF THERE WAS
|
||
BIT #DSKWCH,D ;AM I SUPOSED TO WRITE CHECK THIS FUNCTION?
|
||
BNE RKDSKW ;YUP, GO CALL YOURSELF
|
||
CLZ ;FINISHED SUCESSFULLY
|
||
RTS PC
|
||
|
||
;GOT AN ERROR ON THE RK11
|
||
RKDSKE: INC DISKER(B) ;INC NUMBER OF ERRORS ON THIS DISK
|
||
MOV #DERBL,C ;THE DISK ERROR RECORDING BLOCK
|
||
MOV #RKDS,D ;THE REGISTERS OF THE RK11
|
||
MOV #6,E ;ALL 6 OF THEM
|
||
2$: MOV (D)+,(C)+ ;GET COPYIED
|
||
SOB E,2$
|
||
MOV #17,RKCS ;RESET THE DRIVE
|
||
MOV #1,RKCS ;AND THE CONTROL
|
||
1$: TSTB RKCS ;MAKE SURE ITS READY
|
||
BGE 1$
|
||
SEZ ;RETURN AN ERROR
|
||
RTS PC
|
||
.SBTTL LOW LEVEL MAIN PROGRAM LEVEL DISK ROUTINES
|
||
|
||
;GET A LOW LEVEL DISK REQUEST BLOCK AND LEAVE IT'S INDEX IN C
|
||
GRQBLK: MOV DSKRFL,C ;TRY TO GET A BLOCK
|
||
BUGC EQ ;MUST BE ONE THERE!
|
||
MOV (C),DSKRFL ;LINK IT OUT OF LIST
|
||
DEC DRQFCN ;ONE LESS FREE
|
||
RTS PC
|
||
|
||
;PUT A LOW LEVEL DISK REQUEST BLOCK ONTO THE REQUEST LIST
|
||
;POINT TO REQUEST ARRIVES IN C
|
||
ADDRQ: SAVE B ;RANDOM REG
|
||
MOV #DSKRQ,B ;LIST OF REQUESTS
|
||
JSR PC,BLISTE ;GET TO THE END OF THE LIST
|
||
CLR (C) ;MAKE SURE NEW GUY DOESN'T POINT ANYWHERE
|
||
MOV C,(B) ;CLOBBER NEW GUY ONTO END
|
||
BIS #100,@CURDSK ;WAKE UP THE DISK IF IT NEEDS IT
|
||
REST B
|
||
RTS PC
|
||
.SBTTL MIDDLE LEVEL DISK ROUTINES
|
||
;REQUEST A MIDDLE LEVEL DISK TRANSFER AND WAIT FOR ITS COMPLETION
|
||
;ENTER WITHT THE POINTER TO THE PAGE BLOCK IN B
|
||
;AND THE FUNCTION IN E
|
||
DMRWT: JSR PC,DMRBGT ;TRY TO PLACE THE REQUEST
|
||
BNE DMRWT1 ;IF SUCCESS, CONTINUE
|
||
JSR PC,SFLUSH ;WAIT A SEC
|
||
JSR PC,RUNME ;NOT LONG
|
||
BR DMRWT ;AND TRY AGAIN
|
||
DMRWT1: JSR PC,PBWAIT ;WAIT FOR THE TRANSFER TO BE DONE
|
||
RTS PC ;AND RETURN
|
||
|
||
|
||
;REQUEST A MIDDLE LEVEL PAGE VALIDATION DISK TRANSFER
|
||
;ENTER WITH THE POINTER TO THE PAGE BLOCK IN B
|
||
;AND THE FUNTION IN E
|
||
DMRBGT: SAVE A
|
||
SPL 7 ;TO PREVENT THE DISK ROUTINES FROM SCREWING US
|
||
MOV DMRPNT,A ;TRY TO GET A DISK REQUEST BLOCK
|
||
BNE DMRBG1 ;GOT ONE
|
||
REST A
|
||
SPL 0
|
||
SEZ ;FAILED
|
||
RTS PC
|
||
DMRBG1: MOV (A),DMRPNT ;TAKE IT OFF THE FREE LIST
|
||
SPL 0 ;OUT OF DANGER
|
||
CLR (A) ;DON'T POINT LIKE THAT, IT'S IMPOLITE!
|
||
BIS #PBDISK,(B) ;DISK TRANSFER PENDING FOR THIS PAGE
|
||
MOV B,DMRPBP(A) ;THIS IS THE PAGE TO OPERATE ON
|
||
SAVE B
|
||
MOV A,B ;POINTER TO BLOCK
|
||
ADD #DMRPWK,B ;FIRST OF 3 WORDS
|
||
JSR PC,ACTSET ;SETUP TO ACTIVATE ME
|
||
MOV E,DMRFUN(A) ;SET IN THE FUNCTION
|
||
CLR DMRDRC(A) ;NO REQUESTS ENTERED FOR HIM YET
|
||
CLR DMRPBB(A) ;AND NO BITS TO CLEAR
|
||
MOV #DMRLST,B ;NOW FIND THE END OF THE REQUEST LIST
|
||
JSR PC,BLISTE
|
||
MOV A,(B) ;AND TACK THE REQUEST ON THERE
|
||
REST <B,A>
|
||
BIS #DMRPIR,PIRQ ;CAUSE A MIDDLE LEVEL INTERUPT
|
||
CLZ ;INDICATE REQUEST PLACED
|
||
RTS PC
|
||
|
||
;WAIT FOR A GIP TO STOP DISKING
|
||
GPWAIT: SAVE B
|
||
JSR PC,GIPPB ;CONVERT TO PB
|
||
JSR PC,PBWAIT ;WAIT FOR PB TO STOP
|
||
REST B
|
||
RTS PC
|
||
|
||
;WAIT FOR A PAGE BLOCK TO NO LONGER HAVE A DISK REQUEST PENDING
|
||
;THE PAGE BLOCK INDEX IS IN B
|
||
PBWAIT: SAVE A
|
||
MOV #PBDISK,A
|
||
BR PBULW3
|
||
|
||
PBWAI1: REST A
|
||
RTS PC
|
||
|
||
;WAIT FOR A PAGE TO BE HACKABLE
|
||
;I.E. PBDISK AND PBLOCK CLEAR
|
||
PBULWT: SAVE A
|
||
MOV #PBDISK!PBLOCK,A ;WAIT FOR THESE FLAGS TO CLEAR
|
||
PBULW3: BIT A,(B) ;IS IT UNLOCKED NOW?
|
||
BEQ PBWAI1 ;YES, JUST RETURN
|
||
PBULW1: JSR PC,SFLUSH ;WAIT A LITTLE WHILE
|
||
BIT #PBUSED,(B) ;STILL THERE?
|
||
BEQ PBULW5 ;GONE???
|
||
BIT A,(B) ;NOW?
|
||
BNE PBULW1 ;NOT YET
|
||
JSR PC,RUNME ;MAYBE NOW
|
||
BR PBULW3 ;TRY AGAIN
|
||
PBULW5: MOV ITM0A,A ;POINT TO PROCESS
|
||
BIT #PPCLSR,PFLAGS(A) ;IS HE GOING TO PCLOSER>
|
||
BEQ PBULW6 ;NO, BETTER EXPECT THIS THEN
|
||
JSR PC,RUNME ;THIS WILL NEVER RETURN
|
||
BPT ;I HOPE
|
||
PBULW6: BIT #PPBNMP,PFLAGS(A) ;DID HE EPECT IT?
|
||
BUGC EQ ;NO, WHAT A LOSER
|
||
JSR PC,RUNME ;REVIVE HIM
|
||
BR PBWAI1
|
||
|
||
;ROUTINE CALLED BY THE PIRQ ROUTINE
|
||
DMRBRK: JSR F,ACSAV ;SAVE MAIN PROG ACS
|
||
DMRBR1: BIC #DMRPIR,PIRQ ;PREVENT UNNESSARY INTERUPTS
|
||
MOV DRQDL,A ;ANYHTING ON LIST OF DONE REQUESTS?
|
||
BEQ DMRBR2 ;NOPE
|
||
MOV DSKRFL,F ;POINTER TO FREE BLOCKS
|
||
MOV A,DSKRFL ;LIST BEING FREED IS NOW AT FRONT OF FREELIST
|
||
DMRBR3: INC DRQFCN ;ONE MORE FREE ONE
|
||
JSR PC,DRQDNE ;GO CLEAN UP FOR THIS REQUEST
|
||
SPL 7 ;I VANT TO BE ALONE
|
||
TST (A) ;IS THERE ANOTHER DONE ONE?
|
||
BEQ DMRBR4 ;NOPE
|
||
SPL DMRL ;BACK TO NORMAL
|
||
MOV (A),A ;GET NEXT ONE
|
||
BR DMRBR3 ;AND PROCESS IT
|
||
DMRBR4: MOV F,(A) ;TACK OLD FREE LIST ON END OF NEW
|
||
CLR DRQDL ;ALL DONE ONES PROCESSED
|
||
SPL DMRL ;AND GO BACK TO NORMAL
|
||
DMRBR2: CMP #8.,DRQFCN ;ARE THERE AT LEAST 8 BLOCKS FREE?
|
||
BGE DMRBR9 ;EXIT TO WAIT FOR MORE BLOCKS FREE
|
||
MOV DMRLST,A ;GET FIRST REQUEST
|
||
BEQ DMRBR9 ;NO REQUESTS
|
||
MOV (A),DMRLST ;TAKE IT OFF THE LIST
|
||
MOV DMRPBP(A),B ;GET POINTER TO PAGE BLOCK
|
||
BIT DMRFUN(A),(B) ;IS WHAT WE WNAT ALREADY TRUE?
|
||
BNE DMRBR8 ;YUP, IGNORE THE REQUEST
|
||
CLR F ;TO BUILD UP THE FUNCTION IN
|
||
BIT #PBWCHK,(B) ;ARE WE SUPPOSED TO BE CAREFU WITH THIS PAGE?
|
||
BEQ 1$ ;NO, NO WRITE CHECK
|
||
BIS #DSKWCH,F ;SET THE WRITE CHECK BIT
|
||
1$: BIT #PBVACR,DMRFUN(A) ;VALIDATE IN CORE?
|
||
BNE DMRBVC ;YES, GO DO IT
|
||
BIT #PBVACR,(B) ;IT BETTER BE VALID IN CORE!
|
||
BUGC EQ
|
||
BIS #DSKWRT,F ;FUNCTION WILL BE A WRITE TO DISK
|
||
BIS DMRFUN(A),(B) ;AND THIS INDICATES THAT THE TRUE WILL
|
||
;EVENTUALLY BE THAT THE REQUEST HAS BEEN GRANTED
|
||
;THUS IF THE PAGE IS MODIFIED IN CORE AFTER WE
|
||
;START TO WRITE IT OUT, THE WRITE WILL HAVE BEEN
|
||
;A NO-OP, WHICH IS THE RIGHT THING
|
||
BIT #PBVASS,DMRFUN(A) ;WANT TO VALIDATE AT SWAP SPACE?
|
||
BNE DMRBVW ;GO DO IT
|
||
BIT #PBVAS,DMRFUN(A) ;VALIDATE AT SOURCE?
|
||
BNE DMRBVS ;GO DO THAT
|
||
BPT ;NO FUNCTION????
|
||
|
||
;COME HERE FOR A REQUEST THAT NEEDS NO ACTION
|
||
DMRBR8: BIC #PBDISK,(B) ;DISK TRANSFER "DONE"
|
||
JSR PC,ACTDMR ;ACTIVATE PROCESS THAT MADE THIS REQUEST (THE TURKEY)
|
||
MOV DMRPNT,(A) ;PUT REQUEST
|
||
MOV A,DMRPNT ;ONTO FREE LIST
|
||
BR DMRBR2 ;AND TRY TO FIND SOMEONE WHO IS MORE OF A WINNER
|
||
|
||
;COME HERE WHEN WE THINK WE'RE ALL DONE
|
||
DMRBR9: BIT #DMRPIR,PIRQ ;IS SOMEONE TRING TO WAKE US UP?
|
||
BNE DMRBR1 ;SIGH GO FIND OUT WHAT HE WANTS
|
||
JSR F,ACRES
|
||
REST A
|
||
CHECKP
|
||
RTT
|
||
|
||
;COME HERE TO TRY TO VALIDATE THE PAGE IN CORE
|
||
DMRBVC: BIS #DSKREA,F ;WE WANT TO READ FROM THE DISK
|
||
MOV #PBVACR,DMRPBB(A) ;WILL SET THE VALID IN CORE BIT WHEN DONE
|
||
BIT #PBVASS,(B) ;IS IT VALID ON SWAP SPACE?
|
||
BNE DMRBVW ;GO GET IT FROM SWAP SPACE
|
||
BIT #PBVAS,(B) ;IS IT VALID AT SOURCE?
|
||
BNE DMRBVS ;GO GET IT FROM SOURCE
|
||
BPT ;NOT VALID ANYWHERE????
|
||
|
||
;COME HERE TO DO A TRANSFER TO OR FROM SWAP SPACE
|
||
;DEPENDING ON THE FUNCTION THAT IS IN F
|
||
DMRBVW: BIT #PBSTS,(B) ;IS IT A SWAP TO SOURCE PAGE?
|
||
BNE DMRBVS ;YUP
|
||
JSR PC,GRQBLK ;GET A REQUEST BLOCK
|
||
MOVB F,DRQFUN(C) ;STORE AWAY THE FUNCTION
|
||
CLR E ;FOR THE ASHC
|
||
MOV PBCAR(B),F ;THE CORE ADDRESS IN 512 WORD BLOCKS
|
||
ASHC #10.,E ;MAKE INTO A BYTE ADDRESS
|
||
MOVB E,DRQHCA(C) ;SET THE HIGH PART OF THE ADDRESS
|
||
MOV F,DRQCA(C) ;SET THE LOW PART
|
||
MOVB PBRAN(B),E ;GET DISK #
|
||
BIC #PBDSKM,E ;CLEAR CRAP
|
||
ASH #-PBDISS,E ;SHIFT INTO PLACE
|
||
MOV E,DRQDNO(C) ;SET IN THE DISK NUMBER
|
||
MOV PBDA(B),E ;GET THE STARTING DISK ADDRESS
|
||
MOVB PBRAN(B),F ;NOW NEED THE START
|
||
BIC #PBSTRT,F ;TO GET TO THE RIGHT PLACE IN THE SWAP SPACE
|
||
ADD F,E ;THIS SHOULD BE IT
|
||
MOV E,DRQDA(C) ;PUT IT INTO THE BLOCK
|
||
MOVB PBLEN(B),E ;GET THE LENGTH
|
||
INC E ;CONVERT 0 TO 1
|
||
ASH #9.,E ;CONVERT TO WORDS
|
||
NEG E ;WORD COUNT ONLY A DISK COULD LOVE
|
||
MOV E,DRQWC(C) ;SO GIVE IT TO A DISK
|
||
MOV A,DRQABL(C) ;ACTIVE ME ON YOUR COMPLETION
|
||
INC DMRDRC(A) ;NUMBER OF REQUESTS MADE FOR THIS REQUEST
|
||
JSR PC,ADDRQ ;MAKE THE REQUEST
|
||
JMP DMRBR2
|
||
|
||
;COME HERE TO READ OR WRITE SOURCE
|
||
;DEPENDING ON FUNCTION IN F
|
||
DMRBVS: BIT #PBFILE,(B) ;BETTER BE A FILE PAGE
|
||
BUGC EQ
|
||
SAVE F ;SAVE THE FUNCTION
|
||
CLR E ;TO COMUTE CORE ADDRESS
|
||
MOV PBCAR(B),F ;HAVE TO SHIFT IT
|
||
ASHC #10.,E ;TO MAKE IT INTO BYTES
|
||
SAVE <E,F> ;SAVE IT ON THE STACK
|
||
MOV B,D ;COPY THE PB POINTER
|
||
ADD #PBSDA,D ;POINT TO FIRST DISK ADDRESS
|
||
MOVB PBRAN(B),E ;TO GET START
|
||
BIC #PBSTRT,E ;CLEAR CRAP
|
||
ASL E ;BITES
|
||
ADD E,D ;BLOCK TO REALLY START WITH
|
||
MOVB PBLEN(B),E ;NUMBER OF BLOCKS WE WANT
|
||
DRBVS3: JSR PC,GRQBLK ;GET A BLOCK TO MAKE THE REQUEST WITH
|
||
INC DMRDRC(A) ;NUBER OF REQUESTS FOR THIS REQUEST
|
||
MOV A,DRQABL(C) ;ACTIVATE ME ON YOUR COMPELETION
|
||
MOVB 4(P),DRQFUN(C) ;GET BACK THE FUNCTION
|
||
MOVB 2(P),DRQHCA(C) ;THE HIGH CORE ADDRESS
|
||
MOV (P),DRQCA(C) ;AND THE LOW CORE ADDRESS
|
||
MOVB PBSDSK(B),DRQDNO(C) ;THE DISK #
|
||
CLR DRQWC(C) ;NOW COMPUTE TRANSFER LENGTH
|
||
MOV (D),DRQDA(C) ;GET STARTING DISK ADDRESS
|
||
BUGC EQ ;SHOULD NEVER TOUCH BLOCK ZERO!
|
||
DRBVS2: MOV (D)+,F ;INTO F ALSO
|
||
CMP #-1,F ;MAKE SURE NOT NON-EX BLOCK
|
||
BUGC EQ
|
||
ADD #2000,(P) ;INC CORE ADDRESS
|
||
ADC 2(P) ;TO NEXT BLOCK
|
||
ADD #-1000,DRQWC(C) ;ONE MORE BLOCK
|
||
DEC E ;ONE MORE BLOCK READY TO GO
|
||
BLT DRBVS1 ;THAT'S ALL WE WANT
|
||
INC F ;ADDRESS OF NEXT SEQUENTIAL BLOCK
|
||
CMP F,(D) ;IS THE NEXT BLOCK RIGHT AFTER THIS ONE?
|
||
BEQ DRBVS2 ;YUP, GOBBLE IT ON THIS TRANSFER
|
||
JSR PC,ADDRQ ;HAVE TO SPLIT TRANSFER
|
||
BR DRBVS3 ;GO TAKE ANOTHER CRACK AT IT
|
||
DRBVS1: JSR PC,ADDRQ ;ADD THE LAST REQUEST
|
||
ADD #6,P ;FLUSH CRAP FROM STACK
|
||
JMP DMRBR2 ;DONE WITH THIS ONE
|
||
;COME HERE TO CLEAN UP FOR EACH DISK REQUEST THAT FINISHES
|
||
;MUST CHECK IF ALL REQUESTS ARE DONE, AND FINISH THE GUY UP IF THEY ARE
|
||
;THE REQUEST BLOCK IS POINTED TO BY A
|
||
DRQDNE: MOV DRQABL(A),B ;MIDDLE LEVEL BLOCK TO ACTIVATE
|
||
MOV DMRPBP(B),C ;POINTER TO PAGE BLOCK
|
||
BIT #DRQFER,DRQHCA(A) ;WAS THERE A HARD ERROR?
|
||
BEQ DRQDN1 ;NOPE
|
||
BIS #PBERR,(C) ;FLAG ERROR FOR MAIN PROGRAM
|
||
BPT ;UGH
|
||
DRQDN1: DEC DMRDRC(B) ;ONE LESS REQUEST PENDING
|
||
BNE DRQDN2 ;BUT MORE STILL THERE
|
||
SAVE A ;THIS GUY IS ALL DONE, FINISH HIM OFF
|
||
MOV B,A ;ACTDMR EXPECTS ARG IN A
|
||
JSR PC,ACTDMR ;THIS GUY IS A WINNER, RUN HIM QUICK
|
||
REST A
|
||
BIS DMRPBB(B),(C) ;SET ANY BITS YOU NEED TO
|
||
BIC #PBDISK,(C) ;AND INDICATE DISK OP IS DONE
|
||
MOV DMRPNT,(B) ;PUT THE FREE LIST
|
||
MOV B,DMRPNT ;BACK TOGETHER
|
||
DRQDN2: RTS PC
|
||
|
||
ACTDMR: JSR F,ACSAV ;GROSS OUT
|
||
MOV #DMRPWK,B ;POINTER TO 3 WORD BLOCK
|
||
ADD A,B ;IN THIS BLOCK
|
||
JSR PC,GOACT ;GO PUT ON ACTIVATE LIST
|
||
JMP ACRET
|
||
.SBTTL MAIN PROGRAM LEVEL PAGE VALIDATION ROUTINES
|
||
|
||
;VALIDATE THE PAGE WHOSE PB IS IN B IN CORE
|
||
;THE ASSUMPTION IS THAT THE PAGE IS EITHER PBZERO OR
|
||
;IS VALID ON SWAP OR SOURCE
|
||
;ALSO, THE PAGE MUST HAV ECORE ASSIGNED TO IT
|
||
VALCOR: JSR F,ACSAV ;SO WE DON'T HAVE TO WORRY
|
||
BIT #PBLOCK!PBDISK,(B) ;IS SOMETHING FISHY?
|
||
BUGC NE
|
||
BIT #PBZERO,(B) ;SHOULD IT BE ZEROED?
|
||
BEQ VALCO3 ;NOPE, GO SWAP IT IN INSTEAD
|
||
BIC #PBZERO,(B) ;WE GO THIS WAY BUT ONCE....
|
||
;NOW WE PROCEED TO PLAY WITH ITEM2
|
||
;IN A FUNNY WAY TO CLEAR THE PAGE
|
||
MOV #-1,A ;FIRST WE DO A FAKE PUSH
|
||
JSR PC,ITM2PL
|
||
MOV PBCAR(B),A ;GET THE REAL CORE ADDRESS
|
||
BUGC EQ ;WHICH BETTER BE NON-ZERO
|
||
ASH #4,A ;MAKE IT IN 32 WORD BLOCKS
|
||
MOV #ITM2AD,C ;POINT TO ITEM2
|
||
MOVB PBLEN(B),D ;GET THE LENGTH
|
||
INC D ;0=>1
|
||
ASH #9.,D ;CONVERT TO WORDS
|
||
SPL 7 ;PREVENT INT LEVEL FROM GETTIGN CONFUSED
|
||
MOV A,ITM2AR ;POINT TO PAGE
|
||
MOV #77406,ITM2DR ;MAXIMAL LENGTH PAGE
|
||
1$: CLR (C)+ ;CLEAR A WORD
|
||
SOB D,1$
|
||
SPL 0 ;INTS OK NOW
|
||
JSR PC,ITM2PO
|
||
BIS #PBVACR,(B) ;NOW VALID IN CORE
|
||
BIC #PBVAS!PBVASS,(B) ;NOT VALID ON SOURCE OR SWAP SPACE
|
||
VALCO1: JMP ACRET
|
||
|
||
VALCO5: JSR PC,RUNME ;TRY AGAIN FOR BLOCK
|
||
|
||
;COME HERE TO TRY TO ENTER REQUEST TO VALIDATE PAGE IN CORE
|
||
VALCO3: MOV (B),F ;SAVE FOR THE LOCK FLAG
|
||
MOV #PBVACR,E ;REQUEST TO VALIDATE IN CORE
|
||
JSR PC,DMRBGT ;TRY TO ENTER REQUEST
|
||
BNE VALCO2 ;BR IF YOU WON
|
||
VALCO4: JSR PC,SFLUSH ;WAIT....
|
||
BIT #PBLOCK,F ;IF IT WAS LOCKED WHEN I STARTED
|
||
BNE VALCO5 ;THEN IT DAMN WELL BETTER BE ME WHO HAS IT LOCKED!
|
||
BIT #PBLOCK!PBVACR,(B) ;SOMEONE ELSE BRINGING IT IN?
|
||
BEQ VALCO5
|
||
BIT #PBLOCK!PBDISK,(B) ;WAIT FOR IT TO SETTLE DOWN?
|
||
BNE VALCO4
|
||
JSR PC,RUNME ;SOMEONE ELSE WAS KIND ENOUGH TO BRING IT IN
|
||
BR VALCO1 ;I CAN RETURN
|
||
VALCO2: JSR PC,PBWAIT ;WAIT FOR THE DISK TO WIN
|
||
BR VALCO1 ;DONE!
|
||
;VALIDATE PAGE ON SWAP SPACE
|
||
;THE PAGE MUST BE VALID IN CORE WHEN THE ROUTINE IS ENTERED
|
||
;A PB POINTER TO THE PAGE IS IN B
|
||
VALSWP: BIT #PBSTS,(B) ;IS IT A SWAP TO SOURCE PAGE?
|
||
BNE PBVLSR ;YES, VALIDATE AT SOURCE INSTEAD
|
||
JSR F,ACSAV ;BETTER SAFE THAN...
|
||
MOV (B),F
|
||
VALSW5: JSR PC,PBWAIT
|
||
BIT #PBVASS,(B) ;IS PAGE ALREADY VALID ON SWAP SPACE?
|
||
BNE VALCO1 ;RETURN IF ALREADY VALID
|
||
BIT #PBVACR,(B) ;IT BETTER BE VALID IN CORE!
|
||
; BUGC EQ
|
||
BNE VALSW1
|
||
JSR PC,BUGGER
|
||
|
||
;COME HERE TO ENTER THE REQUEST TO VALIDATE THE PAGE ON SWAP SPACE
|
||
VALSW1: MOV #PBVASS,E ;REQUEST VALIDATION OF PAGE ON SWAP SPACE
|
||
BIT #PBFILE,(B) ;IS THIS A FILE PAGE?
|
||
BNE 1$ ;YES
|
||
BIS #PBVAS,E ;SWAP SPACE IS SOURCE
|
||
1$: JSR PC,DMRBGT ;GO TRY TO REQUEST IT
|
||
BNE VALCO1 ;BRANCH IF YOU WIN, WE'RE DONE
|
||
VALSW2: JSR PC,SFLUSH ;WAIT FOR CONDITIONS TO IMPROVE
|
||
BIT #PBLOCK,F ;HAVE I GOT THE PAGE LOCKED?
|
||
BNE VALSW4 ;BR IF I'VE GOT IT
|
||
BIT #PBLOCK,(B) ;SOMEONE ELSE GOT IT LOCKED?
|
||
BNE VALSW2 ;BR TO WAIT FOR UNLOCKED
|
||
VALSW4: JSR PC,RUNME ;TRY AGAIN
|
||
BR VALSW5
|
||
|
||
;VALIDATE A PAGE BLOCK ON SOURCE
|
||
PBVLSR: JSR F,ACSAV ;SAVE THE RESGISTERS
|
||
BR VALS59 ;JUMP IN AFTER GIP CONVERT
|
||
|
||
;VALIDATE PAGE AT SOURCE
|
||
;THE PAGE MUST BE VALID IN CORE WHEN ROUTINE IS ENTERED
|
||
;A GIP TO TH PAGE IS IN B
|
||
VALSRC: JSR F,ACSAV ;BETTER SAFE THAN...
|
||
JSR PC,GIPPB ;CONVERT GIP TO PB
|
||
VALS59: MOV (B),F
|
||
VALS5: JSR PC,PBWAIT ;WAIT FOR ANY DISKING TO DIE DOWN
|
||
BIT #PBVAS,(B) ;IS PAGE ALREADY VALID ON SOURCE
|
||
BNE VALCO1 ;RETURN IF ALREADY VALID
|
||
BIT #PBFILE,(B) ;IS IT REALLY A FILE PAGE?
|
||
BEQ VALSW5 ;NO, REALLY VALIDATE IT AT SWAP
|
||
BIT #PBVACR,(B) ;IT BETTER BE VALID IN CORE!
|
||
; BUGC EQ
|
||
BNE VALS1
|
||
JSR PC,BUGGER ;TRY TO PCLOSER OUT
|
||
|
||
;COME HERE TO ENTER THE REQUEST TO VALIDATE THE PAGE ON SAP SPACE
|
||
VALS1: MOV #PBVAS,E ;REQUEST VALIDATION OF PAGE ON SAP SPACE
|
||
JSR PC,DMRBGT ;GO TRY TO REQUEST IT
|
||
BNE VALCO1 ;BRANCH IF YOU WIN, WE'RE DONE
|
||
VALS2: JSR PC,SFLUSH ;WAIT FOR CONDITIONS TO IMPROVE
|
||
BIT #PBLOCK,F ;HAVE I GOT THE PAGE LOCKED?
|
||
BNE VALS4 ;BR IF I'VE GOT IT
|
||
BIT #PBLOCK,(B) ;SOMEONE ELSE GOT IT LOCKED?
|
||
BNE VALS2 ;BR TO WAIT FOR UNLOCKED
|
||
VALS4: JSR PC,RUNME ;TRY AGAIN
|
||
BR VALS5
|
||
.SBTTL SWAP SPACE ALLOCATE/DEALLOCATE ROUTINES
|
||
;FIND SWAP SPACE FOR THE PB IN B
|
||
;AND CLOBBER THE PB TO REFLECT IT
|
||
FINSWP: JSR F,ACSAV
|
||
MOV B,F ;SAVE AWAY THE PB POINTER SO IT IS EASY TO GET LATER
|
||
CLR C ;INDEX TO BIT TABLE POINTERS
|
||
FINSW1: MOV SWPBPT+2(C),B ;HAVE WE EXHAUSTED SPACE TO SEARCH?
|
||
BEQ FINSW8 ;YUP, YOU LOSE
|
||
MOV SWPBPT(C),A ;POINT TO BEG OF THIS TABLE
|
||
TST (C)+ ;GO TO THE NEXT ONE
|
||
TST SWPFCN-2(C) ;ARE THERE ANY FREE ONES?
|
||
BEQ FINSW1 ;NO, TRY FOR THE NEXT ONE
|
||
JSR PC,FINBIT ;TRY TO FIND A FREE BIT
|
||
BEQ FINSW1 ;LOSEY LOSEY
|
||
DEC SWPFCN-2(C) ;ONE LESS FREE ONE
|
||
ASH #3,B ;FROM 4K => 512
|
||
ADD SWPBDA-2(C),B ;GET THE REAL DISK ADDRESS
|
||
MOV B,PBDA(F) ;SET IN THE DISK ADDRESS
|
||
BIC #PBVASS!PBSTS,(F) ;SHOULD NOT BE SWAPPED TO SOURCE, NOT VALID AT SWAP SPACE
|
||
MOV SWPBDK-2(C),D ;GET THE DISK
|
||
ASH #PBDISS,D ;PUT IT IN THE RIGHT PLACE
|
||
BISB D,PBRAN(F) ;SET IT IN
|
||
ACRETC: JSR F,ACRES
|
||
CLZ
|
||
RTS PC
|
||
|
||
ACRETS:
|
||
FINSW8: JSR F,ACRES
|
||
SEZ
|
||
RTS PC
|
||
|
||
;FIND A FREE BIT IN A RANDOM BT TABLE AND SET IT
|
||
;CALL WITH START OF TABLE IN A, END IN B
|
||
;SEZ IF CAN'T FIND ONE
|
||
;IF YOU WIN, A GETS THE POINTER TO TH WORD AND B GETS THE BIT NUMBER
|
||
FINBIT: SAVE <C,A>
|
||
FINBI1: CMP A,B ;OFF THE END OF THE TABLE
|
||
BHIS FINBI7 ;YUP, NO BITS FOR YOU
|
||
CMP #-1,(A)+ ;ANY FREE BITS IN THIS WORD?
|
||
BEQ FINBI1 ;NOPE, TRY THE NEXT
|
||
CLR B ;CLEAR A COUNTER
|
||
MOV -(A),C ;GET THE WORD IN QUESTION
|
||
FINBI2: ROR C ;GET THE LOW ORDER BIT
|
||
BCC FINBI3 ;IF CARRY IS CLEAR, THATS THE ONE WE WANT
|
||
SOB B,FINBI2 ;CHUCKLE
|
||
;WE NEVER (I HOPE) FALL THROUGH THE SOB
|
||
FINBI3: NEG B ;MAY HAVE SAVED SOME CYCLES WITH THIS TRICK
|
||
ASL B ;GET A WORD INDEX
|
||
BIS BITS(B),(A) ;SET THE RIGHT BIT
|
||
ASR B ;ADJUST BACK
|
||
SUB (P),A ;OFFSET FROM START OF TABLE
|
||
ASH #3,A ;MULITPLIED BY 16
|
||
ADD A,B ;GIVES BIT NUMBER IN TABLE
|
||
REST <A,C>
|
||
CLZ ;WIN
|
||
RTS PC
|
||
|
||
FINBI7: REST <A,C>
|
||
SEZ ;LOSE
|
||
RTS PC
|
||
|
||
;FREE THE SWAP AREA USED BY THE PB IN B
|
||
PBSFRE: BIT #PBSTS,(B) ;DOES IT HAVE SWAP SPACE?
|
||
BNE PBSFR3 ;NO SPACE, DON'T FREE IT!
|
||
JSR F,ACSAV
|
||
CLR C ;POINTER TO THE BIT TABLE TABLES
|
||
MOVB PBRAN(B),A ;GET THE DISK NUMBER
|
||
BIC #PBDSKM,A ;MASK THE DISK # OFF
|
||
ASH #-PBDISS,A ;SHIFT IT TO A REASNABLE SPOT
|
||
MOV PBDA(B),E ;MAKE THE DISK ADDRESS EASY TO GET AT
|
||
PBSFR1: CMP A,SWPBDK(C) ;IS IT MAYBE IN THIS BIT TABLE?
|
||
BNE PBSFR2 ;NOPE
|
||
CMP E,SWPBDA(C) ;IS IT AFTER THE START
|
||
BLO PBSFR2 ;NOPE (???)
|
||
CMP E,SWPEDA(C) ;BUT BEFORE THE END
|
||
BHIS PBSFR2 ;NO
|
||
SUB SWPBDA(C),E ;MAKE IT RELATIVE TO THIS TABLE
|
||
MOV E,F ;NOW HAVE 2 COPIES
|
||
ASH #-6,E ;GET THE WORD NUMBER
|
||
BIC #160001,E ;EXTRA CRAP
|
||
ASH #-2,F ;THE BIT NUMBER
|
||
BIC #177741,F ;LIKEWISE
|
||
ADD SWPBPT(C),E ;POINT
|
||
BIC BITS(F),(E) ;CLEAR THE RIGHT BIT
|
||
INC SWPFCN(C) ;ONE MORE FREE
|
||
CLR PBDA(B) ;MAKE SURE HE DOESN'T USE IT AGAIN!
|
||
JSR F,ACRES
|
||
PBSFR3: RTS PC
|
||
|
||
PBSFR2: TST (C)+ ;GO TO THE NEXT BIT TABLE
|
||
TST SWPBPT+2(C) ;MAKE SURE IT ISN'T NON-EX
|
||
BNE PBSFR1 ;WIN
|
||
BPT ;LOSE
|
||
|
||
;ALLOCATE SWAP SPACE
|
||
;THIS CALL MAY ONLY BE EXECUTED BY THE SYSSPR
|
||
;THE 3 ARGS ON THE STACK ARE THE SIZE OF THESWAP SPACE
|
||
;IN BLOCKS, THE BLOCK ADDRESS OF THE START OF SWAP SPACE
|
||
;AND THE DISK NUMBER THAT THIS SWAP SPACE IS ON
|
||
;THE CALL IS EXECUTED ONCE FOR EACH SWAP SPACE TO BE ALLOCATED
|
||
EALLOC: JSR PC,SYSCHK ;CHECK THAT THIS IS SYSSPR
|
||
JSR PC,RETNSW ;GET THE DISK NUMBER
|
||
MOV A,E ;STORE IT AWAY
|
||
JSR PC,RETNSW ;GET THE NUMBER OF BLOCKS
|
||
MOV A,F ;AND SAVE IT
|
||
JSR PC,RETNSW ;FINNALLY, GET THE START
|
||
MOV #NSWPA,D ;NUMBER OF SWAP SPACES POSSIBLE
|
||
CLR C ;POINTER INTO SWAP SPACE TABLES
|
||
EALLO1: TST SWPBPT+2(C) ;IS THIS SPACE FREE?
|
||
;IF IT IS, NEXT SPACE BEGGINING=0
|
||
BEQ EALLO3 ;FOUND A FREE SPACE
|
||
TST (C)+ ;TRY THE NEXT
|
||
SOB D,EALLO1 ;UNLESS WE RUN OUT
|
||
ERROR BAD ;SYSSPR WAS BAD, SLAP ITS WRIST
|
||
EALLO3: MOV E,SWPBDK(C) ;SAVE THE DISK NUMBER
|
||
MOV A,SWPBDA(C) ;AND SAVE THAT AS THE START
|
||
MOV SWPBPT(C),D ;GET THE POINTER TO THIS BIT TABLE
|
||
ADD F,A ;GET END BLOCK
|
||
MOV A,SWPEDA(C) ;STORE IT AWAY
|
||
ASH #-3,F ;CONVERT TO 4K BLOCKS
|
||
MOV F,SWPFCN(C) ;SAVE COUNT OF FREE SWAP SPACES
|
||
EALLO4: CLR (D)+ ;16 FREE BITS
|
||
SUB #20,F ;ALLOCATE 16 SWAP SPACES
|
||
BGT EALLO4 ;MORE
|
||
BEQ EALLO6 ;A FULL WORD OF BITS
|
||
MOV #100000,E ;GET A BIT
|
||
INC F ;CAUSE ONE BIT IS ALREADY SET
|
||
ASH F,E ;SET THE BITS IN THE HIGH PART OF THE WORD
|
||
BIS E,-(D) ;PUT THEM IN THE WORD WE JUST CLEARED
|
||
EALLO6: TST (D)+ ;GO TO THE FIRST FREE WORD
|
||
CMP D,#SWPBTE ;HIGHER THAN THE END OF THE TABLE?
|
||
BUGC HIS
|
||
MOV D,SWPBPT+2(C) ;SET THE START OF THE NEXT TABL
|
||
JMP ERETCZ ;WIN
|
||
.SBTTL SWAP IN/OUT AND ITEM SPACE ALLOCATE
|
||
;SWAP OUT PAGE WHOSE PB IS IN B
|
||
;BUT BE HAPPY IF THE PAGE GETS FREED OUT FROM UNDER US
|
||
SWPNMP: SAVE A
|
||
MOV ITM0A,A
|
||
BIS #PPBNMP,PFLAGS(A) ;SET THE MAGIC FLAG
|
||
JSR PC,SWPPAG ;DO THE SWAP
|
||
BIC #PPBNMP,PFLAGS(A)
|
||
REST A
|
||
RTS PC
|
||
;SWAP OUT PAGE WHOSE PB IS IN B
|
||
SWPPAG: JSR PC,PBULWT ;WAIT FOR IT TO BE HACKABLE
|
||
SAVE B
|
||
MOV PBGIP(B),B ;CONVERT PB TO GIP
|
||
JSR PC,PAGPCL ;PCLOSER EVERYONE WHO MIGHT DEPEND ON THIS PAGE
|
||
REST B ;GET BACK PB
|
||
SWPPG: JSR PC,SAVAWB ;IN CASE IT IS IN MY MAP
|
||
JSR PC,PBLCK ;NOW I LOCK IT!
|
||
JSR PC,VALSWP ;VALIDATE ON SWAP SPACE
|
||
JSR PC,PBWAIT ;WAIT FOR DISKING TO STOP
|
||
JSR PC,LSWPOP ;POP SWITCH, UNLOCKING BLOCK
|
||
BIT #PBVASS!PBVAS,(B) ;IS IT REALLY VALID AT SWAP, OR AT LEAST AT SOURCE?
|
||
BEQ SWPPAG ;NOPE, TRY AGAIN
|
||
JSR PC,PBCFRE ;FREE THE CORE IT TOOK
|
||
JMP MAPRES ;IN CASE MY MAP NEEDS UPDATEING
|
||
|
||
|
||
;GET CORE TO EXPAND ITEM SPACE
|
||
;CALL WITH DESIRED AMOUNT OF COORE IN A
|
||
ITMSEX: JSR F,ACSAV
|
||
INC A ;0=1
|
||
ITMSE1: MOV CST1NS,C ;POINT TO FIRST NON-SYSTEM BLOCK
|
||
ITMSE6: MOV A,D ;COPY FOR SOB
|
||
MOV C,E ;COPY START OF SPACE BEING GOBBLED
|
||
ITMSE2: BIT #CSTFRB,(C)+ ;IS THIS BLOCK FREE?
|
||
BEQ ITMSE4 ;NOPE, HAVE TO FREE IT
|
||
SOB D,ITMSE2 ;CHECK ALL THE BLOCKS WE WANT TO GOBBLE
|
||
SUB A,FREECR ;THAT MUCH LESS FREE CORE TOO
|
||
SUB A,USRCOR ;THIS MUCH WILL BE STOLEN FROM USERS
|
||
BUGC LE ;SYSTEM HAS ZERO OR NEGATIVE CORE FOR USERS!
|
||
MOV E,C ;POINT TO START AGAIN, THEY ARE ALL FREEE
|
||
SUB #CST,E ;CONVERT
|
||
ASR E ;TO BLOCK NUMBER
|
||
MOV E,2(P) ;RETURN THE START IN B FOR THE USER
|
||
ITMSE3: BIT #CSTFRB,(C) ;IS IT REALLY FREE?
|
||
BUGC EQ
|
||
BIS #CSTSYB,(C) ;USED BY SYSTEM
|
||
BIC #CSTFRB,(C)+ ;AND NO LONGER FREE
|
||
CMP C,CST1FR ;IS THIS THE FIRST FREE BLOCK?
|
||
BNE 1$
|
||
ADD #2,CST1FR ;NOT ANY MORE
|
||
1$: SOB A,ITMSE3 ;FOR ALL THE BLOCKS
|
||
JMP ACRET
|
||
ITMSE4: TST -(C) ;BACK TO BLOCK THAT ISN'T FREE
|
||
BIT #CSTSYB,(C) ;IS THIS BLOCK ALREADY USED BY THE SYSTEM?
|
||
BNE ITMSE5 ;YES, WE'LL IGNORE IT
|
||
MOV CSTPB-CST(C),B ;WHO IS THAT, ANYWAY
|
||
JSR PC,PCLDEF ;DEFERE A PCLOSER TILL WE ARE DONE
|
||
JSR PC,SWPNMP ;OUT WITH HIM!(NOT MY PAGE)
|
||
BR ITMSE1 ;GO TRY IT ALL AGAIN
|
||
ITMSE5: TST (C)+ ;GO HIGHER
|
||
CMP C,CSTTOP ;OFF THE TOP?
|
||
BUGC HIS ;UGH RAN OFF TOP
|
||
BR ITMSE6 ;TRY AGAIN
|
||
|
||
.SBTTL SEGMENT BREAK ROUTINES
|
||
SEGBRK: MOV SSR0,PSSR0 ;COPY INTO PSEUDO SEGMENT REGISTERS
|
||
MOV SSR1,PSSR1
|
||
MOV SSR2,PSSR2
|
||
BIC #174000,SSR0 ;RESUME MONITORING
|
||
MOV PSSR2,(P) ;GET THE PC WHERE THE INSTRUCTION STARTED
|
||
BIT #200,PSSR0 ;DID THE INSTRUCTION COMPLETE?
|
||
BUGC NE ;STRANGE, I DON'T THINK THIS SHOULD HAPPEN
|
||
BIT #140000,2(P) ;WAS IT FROM KERNAL MODE?
|
||
BEQ SEGKR ;YES, GO PROCESS IT LIKE A SUBROUTINE CALL
|
||
MOV PC,USRMOD ;FROM USER MODE, TREAT LIKE A SSYTEM CAL
|
||
SPL 0
|
||
JSR F,SPCPSP ;SAVE THE PS, PC AND P POINTER OF TH EUSER
|
||
JSR PC,PACSAV ;AND HIS ACS
|
||
MOV ITM0A,A ;POINT TO THE PROCESS BLOCK
|
||
ADD #PUREGS,A ;POINT TO SAVED REGISTERS
|
||
JSR PC,ACFIX ;FIX UP THE USERS REGISTERS
|
||
JSR PC,PAGIN ;SWAP IN THE PAGE
|
||
MOV ITM0A,B ;POINT TO THE PROCESS
|
||
JSR PC,PACRES ;RESTORE USERS REGISTERS
|
||
SAVE PUP(B) ;GET USERS P POINTER
|
||
MTPI P ;RESTORE IT
|
||
SAVE <PUPS(B),PUPC(B)> ;TO RETURN TO USER MODE
|
||
SPL CLKL ;PREVENT A SCHEDULE
|
||
CLR USRMOD ;THIS COULD CAUSE ONE
|
||
TST QUANT ;HAS HE OVERSTAYED HIS WELCOME?
|
||
BGE 1$ ;NO
|
||
BIS #CLKPIR,PIRQ ;GET HIM AFTER THE RTT
|
||
1$: CHECKP
|
||
RTT ;GO TO USER MODE
|
||
|
||
SEGKR: SPL 0
|
||
CLR -(P) ;SAVE A 0 VALUE FOR P
|
||
JSR F,ACSAV ;SAVE THE REST OF THE KERNAL REGISTERS
|
||
MOV PSSR0,A ;GET SEGMENTER STATUS
|
||
ASR A ;SHIFT
|
||
BIC #177700,A ;GET THE PAGE NUMBER THAT WE FAULTED ON
|
||
TSTB KERSBT(A) ;IS IT OK TO FAULT ON THIS PAGE FROM KERNAL?
|
||
BUGC EQ ;NO, UGH
|
||
BGT SEGKR1 ;YES, IT IS A USER PAGE
|
||
BIT #SEGNRA,PSSR0 ;THE ONLY LEGAL KERNAL PAGE TRAP
|
||
BUGC EQ ;IS NON-RESIDENT
|
||
SEGKR1: MOV P,A ;A POINTER TO THE KERNAL REGISTERS
|
||
JSR PC,ACFIX ;FIX THEM UP
|
||
JSR F,ACRES ;GET BACK THE FIXED UP ACS
|
||
TST (P) ;DOES KERNAL P NEED FIXING?
|
||
BUGC LT ;CAN'T WIN IF NEED TO ADD TO IT
|
||
ADD (P),P ;CORRECT THE P STACK (REMOVE THINGS PUSHED)
|
||
TST (P)+ ;AND FLUSH THE DUMMY P VALUE
|
||
SAVE <A,B> ;SAVE THE CORRECTED ACS ON THE CORRECTED STACK
|
||
JSR PC,PAGIN ;TRY TO SWAP IN THE PAGE
|
||
REST <B,A> ;RESTORE THE KERNAL REGISTERS
|
||
CHECKP
|
||
RTT ;RETURN FROM THIS "SUBROUTINE"
|
||
;FIX UP THE REGISTER SET POINTED TO BY A
|
||
ACFIX: MOV #2,F ;DO IT TWICE
|
||
MOV PSSR1,E ;GET THE CORRECTION VALUES
|
||
ACFIX1: MOVB E,B ;GET ONE OF THEM
|
||
BEQ ACFIX2 ;ZERO, ALL DONE
|
||
BIC #177770,B ;WHCIH REGISTER?
|
||
CMP #7,B ;NEVER FIX UP THE PC
|
||
BEQ ACFIX2 ;SSR2 TAKES CARE OF THAT
|
||
ASL B ;WORD INDEX
|
||
MOVB E,C ;GET THE AMOUNT(SIGN EXTENDED)
|
||
ASH #-3,C ;THEN FLUSH THE REGISTER # AND SIGN EXTEND MORE
|
||
ADD A,B ;POINT TO THE STORED REGISTER VALUE
|
||
SUB C,(B) ;CORRECT IT
|
||
ACFIX2: SWAB E ;FOR THE SECOND ONE
|
||
SOB F,ACFIX1 ;DO IT AGAIN
|
||
ACFIX3: RTS PC
|
||
|
||
;SWAP IN THE PAGE THAT WE FAULTED ON, OR GIVE THE USER AN ERROR
|
||
;IF THE FAULT WAS NOT NON-RESIDENT OR THE PAGE IS NON-EX
|
||
PAGIN: MOV PSSR0,A ;GET STATUS
|
||
BIT #SEGNRA,A ;NON-RESIDENT?
|
||
BEQ PAGERR ;NO, ERROR ON THE PART OF THE USER
|
||
ASR A ;CONVERT TO PAGE NUM
|
||
BIT #60,A ;IS IT A KERNAL PAGE?
|
||
BEQ PAGIN1 ;YES, BETTER BE ITEM2
|
||
BIC #177760,A ;GET PAGE NUMBER
|
||
MOV A,B ;COPY IT
|
||
MUL #UPTLEN,B ;MAKE A POINTER
|
||
ADD ITM1A,B ;INTO THE SPHERE'S
|
||
ADD #SUPTS,B ;UPTS
|
||
TST (B) ;DOES THE PAGE EXIST?
|
||
BEQ PAGACV ;NXM ERRROR
|
||
MOV UPTPBP(B),B ;GET THE PB TO SWAP IN
|
||
JSR PC,PBULWT ;MAKE SURE IT IS UNLOCKED
|
||
JSR PC,SAVAWB ;SAVE THE W BITS
|
||
JSR PC,PBSWPI ;GO DO IT
|
||
JMP MAPRES ;RESTORE THE MAP WITH THE NEW PAGE
|
||
|
||
PAGIN1: BIC #177700,A ;CLEAR CRAP
|
||
CMP #<<ITM2AR-I0AR>/2>,A ;IS IT ITEM2?
|
||
BUGC NE
|
||
MOV ITEM2,B ;GET THE ITEM
|
||
JSR PC,SWPIN ;SWAP IT IN
|
||
MOV ITEM2,A ;NOW
|
||
JMP ITM2LD ;RELOAD IT
|
||
|
||
PAGERR: MOV ITM0A,A ;THE PROCESS
|
||
BIT #SEGSLE,PSSR0 ;SEGMENT LENGTH ERROR?
|
||
BNE PAGSLE ;ITS SET
|
||
BIT #SEGRVI,PSSR0 ;READ ONLY VIOLATION?
|
||
BNE PAGRDO ;READ ONLY PAGE
|
||
BPT
|
||
|
||
PAGSLE: MOV #100000+.SLETF,PFAULT(A) ;SEGMENT LENGTH ERROR
|
||
SEGFLT: CMP (P)+,(P)+ ;POP OFF SSR0,SSR1, AND RETURN ADDRESS
|
||
JMP CFAULT ;HE LOSES
|
||
PAGRDO: MOV #100000+.RDOTF,PFAULT(A) ;READ ONLY FAULT
|
||
BR SEGFLT ;FAULT HIM
|
||
PAGACV: MOV ITM0A,A ;POINT TO PROCESS
|
||
MOV #100000+.NXMTF,PFAULT(A) ;NON EXISTANT MEMORY FAULT
|
||
BR SEGFLT
|
||
;SWAP IN THE PAGE POINTED TO BY THE GIP IN B
|
||
SWPIN: SAVE B
|
||
JSR PC,UPTPLD ;GET THE UPT FOR THE PAGE
|
||
MOV UPTPBP(B),B ;GET THE POINTER TO THE PAGE BLOCK
|
||
JSR PC,ITM2PO ;PUSHED BY UPTPLD
|
||
JSR PC,PBSWPI ;SWAP IN THE PAGE
|
||
REST B
|
||
RTS PC
|
||
|
||
;SWPA IN THE PAGE REPRESENTED BY THE PB IN B
|
||
;THIS ROUTINE TAKES CARE OF MAKING SPACE IN CORE BY SWAPPING
|
||
;OUT PAGES AND/OR DEACTIVATING OTHER USERS AS NEEDED
|
||
PBSWPI: JSR PC,PBWAIT ;MAKE SURE PAGE IS AVAILABLE
|
||
BIT #PBVACR,(B) ;ALREADY IN CORE?
|
||
BNE PBSWP1 ;YES, NOTING TO DO
|
||
JSR PC,FINPAG ;TRY TO FIND A PLACE TO PUT IT
|
||
BEQ PBSWP2 ;UGH, HAVE TO WORK FOR OUR CORE
|
||
JSR PC,VALCOR ;SWAP IT IN
|
||
BR PBSWPI ;AND WE SHOULD BE ALL SET
|
||
PBSWP1: RTS PC
|
||
PBSWP2: JSR PC,CRFREE ;GO OFF TO FREE SOME CORE
|
||
BR PBSWPI ;AND TRY AGAIN
|
||
.SBTTL SWAP SCHEDULING ROUTINES
|
||
;THE PROCESS IN A IS ABOUT TO BE MOVED TO THE QUQUE IN B
|
||
;IF THE PAGES THE PROCESS USES SHOULD BE ACTIVIATED OR DEACTIVATED
|
||
;THIS ROUTINE WILL DO IT
|
||
PRSAOD: JSR F,ACSAV ;GORSS
|
||
MOV PRTPPT(A),A ;GET ITEM #
|
||
JSR PC,ITM0PL ;LOAD PROCESS
|
||
BIT #WINQB!ACTQB!DORQB,PQBIT(A) ;ARE THE PAGES ACTIVE NOW?
|
||
BEQ PRSAC1 ;NO, GO SEE IF WE SHOULD ACTIVATE
|
||
BIT #WINQB!ACTQB!DORQB,QBIT(B) ;ARE WE GOING TO AN ACTIVE QUQE?
|
||
BNE PRSAO1 ;YES, DO NOTHING
|
||
MOV #PBDACT,F ;MUST DEATIVATE PAGES
|
||
MOV #-1,C ;ONE LESS ACTIVE
|
||
BR PRSAO2 ;GO DO IT
|
||
|
||
PRSAC1: BIT #RUNQB!IACTQB!STOPQB!PFREQB,QBIT(B) ;ARE WE GOING TO AN INACTIVE QUQE?
|
||
BNE PRSAO1 ;YES, DO NOTHING
|
||
MOV #PBACT,F ;NO, ACTIVATE THE PAGES
|
||
MOV #1,C ;ONE MORE ACTIVE
|
||
PRSAO2: MOV PPRTPT(A),B ;GET POINTER TO PROCESS TABLE ENTRY
|
||
MOV HSECS,PRTTIM(B) ;TIME THAT THIS PROCESS WENT ONTO THIS QUQUE
|
||
MOV PSPHRP(A),A ;GET THE SPHERE
|
||
JSR PC,ITM1PL ;LOAD IT UP
|
||
ADD C,SPHAPR(A) ;ONE MORE OR LESS ACTIVE
|
||
ADD #SUPTS,A ;POINT TO THE UPTS
|
||
MOV #16.,D ;PROCESS ALL 16 OF THEM
|
||
PRSAO3: TST (A) ;DOES IT EXIST?
|
||
BEQ PRSAO4 ;NO, IGNORE IT
|
||
BIT #UPTABS,(A) ;IS IT AN ABSOLUTE PAGE?
|
||
BNE PRSAO4 ;YES, LEAVE IT ALONE
|
||
MOV UPTPBP(A),B ;GET ITS PAGE BLOCK
|
||
MOV #1,C ;ONLY ONE PROCESS
|
||
JSR PC,(F) ;CALL APPROPRIATE ROUTINE
|
||
PRSAO4: ADD #UPTLEN,A ;NEXT
|
||
SOB D,PRSAO3
|
||
JSR PC,ITM1PO
|
||
PRSAO1: JSR PC,ITM0PO
|
||
JMP ACRET
|
||
|
||
PBDACT: SUB C,PBAUSR(B) ;ONE LESS ACTIVE PROCESS USING THIS PAGE
|
||
BUGC LT ;FIX THIS
|
||
BNE PBDAC2 ;ALREADY NON-ZERO
|
||
SAVE A
|
||
MOVB PBLEN(B),A ;GET THE LENTGH OF THE PAGE BEING DEATIVATED
|
||
SUB A,ACORE ;THAT MUCH LESS ACTIVE CORE
|
||
BIT #PBVACR,(B) ;IS IT VALID IN CORE?
|
||
BEQ PBDAC3 ;NO, DON'T PUT ON SWAP OUT LIST
|
||
MOV #PBSWPO,A ;SIMPLE LINEAR SWAP OUT LIST
|
||
1$: TST (A)+ ;LOOK FOR A FREE ENTRY
|
||
BNE 1$
|
||
CMP #PBSWOE,A ;DID WE GET TOT THE END?
|
||
BUGC EQ ;OOPS, TRYING TO PUT TOO MANY PAGES ON SWAP OUT LIST
|
||
MOV B,-(A) ;PUT IT ON THE LIST
|
||
INC NPBSWO ;ONE MORE PAGE TO BE SWAPPED OUT
|
||
PBDAC3: REST A
|
||
PBDAC2: RTS PC
|
||
;ACTIVATE PAGE POINTED TO BY B
|
||
PBACT: TST PBAUSR(B) ;IS IT ALREADY ACTIVE?
|
||
BNE PBACT1 ;YUP, NOTHING TO DO
|
||
SAVE <A,C>
|
||
MOVB PBLEN(B),A ;LENGTH OF PAGE BEING ACTIVATED
|
||
ADD A,ACORE ;MORE ACTIVE CORE
|
||
JSR PC,PBNSWP ;TAKE OFF SWAP OUT LIST IF ON IT
|
||
REST <C,A>
|
||
PBACT1: ADD C,PBAUSR(B) ;INC THE COUNT
|
||
RTS PC
|
||
|
||
;IF THE PB IN B IS ON THE SWAP OUT LIST, TAKE IT OFF
|
||
PBNSWP: SAVE A
|
||
MOV #PBSWPO,A ;IS IT ON SWAP OUT LIST?
|
||
PBNSW2: CMP B,(A)+ ;THIS ONE?
|
||
BNE PBNSW3 ;YUP, SAVE HIM
|
||
DEC NPBSWO
|
||
CLR -(A)
|
||
PBNSW3: CMP #PBSWOE,A ;AT END OF LIST?
|
||
BNE PBNSW2 ;NOT YET
|
||
PBNSW4: REST A
|
||
RTS PC
|
||
;FREE UP SOME CORE, MOVING PROCESSES FROM DORMANT TO INACTIVE OR
|
||
;ACTIVE TO RUNNING AS NEEDED
|
||
CRFREE: JSR F,ACSAV
|
||
CRFRE1: CMP #NDRQBL-4,DRQFCN ;ARE THERE MANY ACTIVE DISK TRANSFERS?
|
||
BLT CRFRE3 ;NO, LETS DO SOME
|
||
CRFRE2: JSR PC,SFLUSH ;WAIT FOR THINGS TO CALM DOWN
|
||
CMP #NDRQBL-4,DRQFCN ;HAVE THEY?
|
||
BGE CRFRE2 ;NOPE
|
||
JSR PC,RUNME ;MAYBE NOW THERE WILL BE ROOM
|
||
CMP #8,FREECR ;IS THERE AT LEAST 4K?
|
||
BLE CRFRE9 ;YES, ASSUME THERE MIGHT BE ENOUGH FREE
|
||
CRFRE3: TST NPBSWO ;ANY PAGES WAITING TO BE SWAPPED OUT?
|
||
BEQ CRFRE4 ;NO, BETTER MAKE SOME
|
||
MOV #PBSWPO,A ;POINT TO THE SWAP OUT LIST
|
||
1$: MOV (A)+,B ;LOOK FOR A NON-ZERO ENTRY
|
||
BEQ 1$
|
||
CMP #PBSWOE,A ;WITHIN THE TABLE?
|
||
BUGC LOS ;UGH
|
||
DEC NPBSWO ;ONE LESS ENTRY
|
||
CLR -(A) ;FLUSH IT
|
||
CRFRE8: BIT #PBUSED,(B) ;REALLY STILL THERE?
|
||
BEQ CRFRE3 ;NO, TRY AGAIN
|
||
JSR PC,SWPNMP ;SWAP IT OUT (NOT MY PAGE)
|
||
JSR PC,PCLCHK ;MUST PCLOSER SELF IF SWAPPED OUT MY OWN PAGE
|
||
CRFRE9: JMP ACRET ;MAYBE NOW THERE WILL BE SPACE
|
||
CRFRE4: CMP #12.,FREECR ;IS THERE MORE THAN 6K FREE?
|
||
BLE CRFRE7 ;THEN THINGS ARE IN BAD SHAPE
|
||
MOV #DORQ,A ;SEE IF ANYONE ON THE DORMANT QUEUE
|
||
MOV #IACTQ,E ;WOULD LIKE TO BECOME INACTIVE
|
||
JSR PC,CRFREL
|
||
BNE CRFRE3 ;GOT ONE, GO SWAP OUT A PAGE OF HIS
|
||
MOV #ACTQ,A ;HAVE TO REMOVE AN ACTIVE USER
|
||
MOV #RUNQ,E ;TO THE RUNQ
|
||
JSR PC,CRFREL
|
||
BNE CRFRE3 ;GOT ONE, GO SWAP
|
||
BR CRFRE2 ;UGH BLETCH!!!!!!
|
||
|
||
CRFRE7: INC LOGJAM ;ANOTHER DAY, ANOTHER LOGJAM
|
||
MOV CSTROV,A ;ROVING CSTPB POINTER
|
||
1$: MOV (A)+,B ;GET A PB
|
||
BNE 2$ ;FOUND ONE
|
||
BIT #CSTBEB,CST-CSTPB(A) ;COME TOT HE END OF THE CORE?
|
||
BNE 1$ ;NOPE
|
||
MOV #CSTPB,A ;RESET POINTER
|
||
BR 1$
|
||
2$: MOV A,CSTROV ;FOR THE NEXT TIME
|
||
BR CRFRE8
|
||
|
||
CRFREL: JSR PC,GLQTIM ;GET THE GUY LONGEST ON THE QUEUE
|
||
TST A ;ANYONE ON?
|
||
BEQ CRFRL1 ;NOPE
|
||
MOV E,B ;MOVE HIM TO A LESS FAVORED POSITION
|
||
JSR PC,PRSAOD ;DEACTIVATE HIS PAGES
|
||
JSR PC,TQUEUE ;AND MOVE HIM
|
||
CLZ
|
||
CRFRL1: RTS PC
|
||
.SBTTL RANDOM UTILITIES FOR MUNGING WITH CORE TABLES
|
||
;CONVERT THE GIP IN B TO A PAGE BLOCK POINTER IN B
|
||
GIPPB: SAVE A
|
||
MOV #-1,A
|
||
JSR PC,ITM1PL ;DO A DUMMY PUSH
|
||
TST B ;MAKE SURE WE HAVE A GIP
|
||
BUGC GT ;WHATCH OUT FOR REAL ITEMS
|
||
BIT #GIPSPR,B ;IS IT A SPHERE GIP?
|
||
BEQ GIPPB1 ;NOPE
|
||
MOV B,A ;COPY IT
|
||
BIC #GIPITM,A ;GET THE ITEM PART
|
||
ASH #2,A ;MAKE IT A REAL ITEM INDEX
|
||
JSR PC,ITM1LD ;LOAD IT UP
|
||
ADD #SUPTS,A ;POINT INTO UPTS
|
||
BIC #GIPUPT,B ;GET THE UPT #
|
||
ASH #-10.,B ;INTO THE RIGHT PLACE
|
||
MUL #UPTLEN,B ;MAKE IT AN INDEX
|
||
ADD A,B ;REAL POINTER
|
||
BR GIPPB2
|
||
GIPPB1: BIC #GIPBIT,B ;CLEAR THE EXTRA BIT
|
||
GIPPB2: MOV UPTPBP(B),B ;GET THE PAGE BLOCK POINTER
|
||
JSR PC,ITM1PO
|
||
REST A
|
||
RTS PC
|
||
|
||
;GET A FILE PAGE BLOCK, SETTING THE LENGTH TO WHAT
|
||
;IS IN B. RETRUN POINTER TO PAGE BLOCK IN B
|
||
;SET PBFILE BUT NOT PBZERO
|
||
;SWAP SPACE IS NOT ALLOCATED
|
||
;WILL HANG FOREVER FOR PB IF NONE AVAILABLE
|
||
FPBGET: SAVE <A,B>
|
||
MOV #FPBFRE,B ;POINTER TO FILE PAGE BLOCKS
|
||
JSR PC,FREEGT ;GET ONE
|
||
MOV #PBUSED!PBFILE!PBVAS!PBSTS,(A) ;INDICATE IT IS A FILE BLOCK
|
||
BR PBGET1 ;GO JOIN NORMAL PB GETTING
|
||
|
||
;GET A REGULAR PAGE BLOCK, ARGS AND RETURNS
|
||
;JUST LIKE FPBGET, EXCEPT IT SETS PBZERO AND NOT PBFILE
|
||
PBGET: SAVE <A,B>
|
||
MOV #PBFREL,B ;POINTER TO REGULAR FREE LIST
|
||
JSR PC,FREEGT ;GET THE BLOCK
|
||
MOV #PBUSED!PBZERO,(A) ;ZERO BLOCK ON FIRST SWAP IN
|
||
PBGET1: JSR PC,FREELK ;MAKE A LOCK THAT WILL PUT IT BACK ON THE FREE LIST
|
||
MOVB (P)+,PBLEN(A) ;POP THE LENGTH OFF THE STACK
|
||
CLRB PBRAN(A) ;CLEAR THE RANDOM BYTE
|
||
CLR PBAUSR(A) ;NO ACTIVE USERS (???)
|
||
CLR PBGIP(A) ;DOESN'T POINT AT GIP
|
||
MOV A,B ;COPY POINTER TO THE PB
|
||
REST A
|
||
RTS PC
|
||
|
||
;LOCK THE "LOCKED" BIT IN THE PB POINTED TO BY B
|
||
;TO BE UNLOCKED WHENEVER SWITCH IS POPED
|
||
PBLCK: SAVE <A,B,C>
|
||
JSR PC,PBWAIT ;WAIT FOR ANY DISKING TO STOP
|
||
MOV B,A
|
||
MOV #PBLOCK,B ;BIT TO LOCK
|
||
CLR C ;NO ITEM
|
||
JSR PC,LCKASW ;LOCK IT
|
||
REST <C,B,A>
|
||
MOV (P),PBLKPC(B) ;SAVE PC
|
||
MOV PRUNNG,PBLKPS(B) ;AND PROCESS
|
||
RTS PC
|
||
|
||
;GET A NODE OUT OF A STANDARD FREE LIST
|
||
;B CONTAINS POINTER TO FREE POINTER
|
||
;ON RETURN A CONTAINS POINTER TO GOBBLED NODE
|
||
;ROUTINE WILL HANG FOREVER WAITING FOR NODE
|
||
FREEGT: TST (B) ;ANY FREE ONES?
|
||
BNE FREEG2 ;YES, GO GOBBLE
|
||
FREEG1: JSR PC,SFLUSH ;WAIT A LITTLE
|
||
TST (B) ;ANY?
|
||
BEQ FREEG1 ;NOPE
|
||
JSR PC,RUNME ;HOPE ITS STILL THERE WHEN I GET BACK
|
||
BR FREEGT ;TRY AGAIN
|
||
FREEG2: MOV (B),A ;THE FREE ONE
|
||
MOV (A),(B) ;FREE POINTER NOW POINTS AT NEXT FREE
|
||
RTS PC
|
||
|
||
;LOCK A STANDARD NODE OFF A FREE LIST
|
||
;NO PROCESSING IS DONE ON PCLOSERING EXCPET FREEING THE
|
||
;NODE, SO BE CAREFUL HOW YOU USE THIS!
|
||
;ON ENTRY, A POINTS TO THE NODE AND B POINTS
|
||
;TO THE FREE POINTER FOR THIS TYPE OF NODE
|
||
FREELK: SAVE <A,B>
|
||
MOV #LSPULN,A ;AN UNLINK TYPE OF LOCK
|
||
CLR B ;NO ITEM
|
||
JSR PC,LOCKSW ;GET A LOCK BLOCK
|
||
MOV (P),LCKWD2(A) ;LOCK WORD 2 POINTS TO THE FREE POINTER
|
||
MOV 2(P),LCKWD1(A) ;WORD ONE POINTS TOT EH NODE
|
||
REST <B,A>
|
||
RTS PC
|
||
|
||
;THIS CROCK WILL FREE A LOCKED LIST NODE IF YOU FAIL IN
|
||
;SOME WAY OTHER THAN PCLOSERING BY PRETENDING TO PCLOSER
|
||
;FOR THE TOP SWITCH
|
||
FRELSE: MOV PC,BPCLSR ;SAY WE ARE PCLOSERING
|
||
JSR PC,LSWPOP ;POP THE SWITCH
|
||
CLR BPCLSR ;PREVIOUS STATEMENTS ARE NOW INOOPERATIVE
|
||
;(WE LIED)
|
||
RTS PC
|
||
.SBTTL CORE HACKING ROUTINES
|
||
;INTIAL MAP-SETTING ROUTINE
|
||
;CLOBBERS MOST AC'S, INTENDED TO BE RUN ONLY AT ITIALIZE TIME
|
||
;OR AFTER A POWER FAIL RESTART
|
||
MAPSET: MOV #I0AR,A ;FIRST WE'LL SET UP A STRAIGHT MAP
|
||
CLR B ;I AND D SPACE THE SAME AND MAPPED DIRECTLY
|
||
MOV #8.,C ;FROM VIRTUAL CORE TO PHYSICAL
|
||
MAPST1: MOV #77406,VAR0DR-I0AR(A) ;DATA SPACE 4K SEGEMNET
|
||
MOV #77406,I0DR-I0AR(A) ;INSTRUCTION SPACE 4K SEGMENT
|
||
MOV B,VAR0AR-I0AR(A) ;VIRTUAL MAPPED DIRECTLY TO PHYSICAL
|
||
MOV B,(A)+ ;FOR BOTH INST AND DATA SPACE
|
||
ADD #200,B ;4K WORTH
|
||
SOB C,MAPST1 ;DO FORR 8 SEGMENTS
|
||
;NOW WE'LL HACK THE SPEECAIL THINGS
|
||
MOV #7600,IOAR ;MAP USUAL I/O SPACE TO REAL I/O SPACE
|
||
;THE FOLLOWING THING IS THE DR FOR THE RUG PAGES (UGH!)
|
||
FOO==<<200-<<RUGIDR-I0DR+2>*100>+<<RUGST_-6>&1777>>_8.>+16
|
||
MOV #FOO,RUGDDR ;MAP 156000-157776 VIRTUAL TO SAME PHYSICAL
|
||
MOV #VAR2DR,A ;NOW FLUSH UNUSED VARIABLE PAGE AND 3 ITEM PAGES
|
||
CLR (A)+
|
||
CLR (A)+
|
||
CLR (A)+
|
||
CLR (A)
|
||
MOV #I7DR,A
|
||
CLR (A) ;FLUSH HIGH INSTRUCTION PAGE
|
||
TST -(A) ;DON'T CLOBBER RUG PAGE
|
||
MOV #120000,B ;FIRST LOCATION IN A PAGE BEFORE RUG PAGE
|
||
MAPST2: CMP #LSTILC,B ;LAST INSTRUCTION LOCATION
|
||
BHI MAPST3 ;IF THERE IS SOMETHING THERE, WE'RE DONE
|
||
CLR -(A) ;NO ONE THERE, FLUSH IT
|
||
SUB #20000,B ;NEXT PAGE DOWN
|
||
BR MAPST2
|
||
MAPST3: MOV #7,SSR3 ;ENABLE I AND D FOR ALL MAPS
|
||
MOV #1,SSR0 ;THERE WE GO!!
|
||
RTS PC
|
||
;MAP RESTORE ROUTINE
|
||
;CLOBBERS NO REGISTERS
|
||
;EXPECTS THE SPHERE TO RESTORE IN ITEM1
|
||
;DOES NOT RESTORE IF CURSPH IS SAME AS ITEM1
|
||
MAPRES: CMP CURSPH,ITEM1 ;IS IT ALREADY LOADED?
|
||
BNE 1$ ;NO
|
||
RTS PC
|
||
1$: CMP #-1,CURSPH ;IS THERE A SPHERE MAPPED IN?
|
||
BUGC NE ;UGH, THAT MEANS HIS W BITS DIDN'T GET COPIED OUT!
|
||
MAPRE1: MOV ITEM1,CURSPH
|
||
JSR F,ACSAV ;THIS IS THE ENTRY POINT FOR RESTORING THE MAP EVERY TIME
|
||
MOV #20,A ;FOR ALL PAGES
|
||
MOV #USRISD,B ;ALL DR'S
|
||
1$: CLR (B)+ ;MAKE NON-EX
|
||
SOB A,1$
|
||
MOV ITM1A,A ;POINTER TO THE ITEM
|
||
ADD #SUPTS,A ;GET POINTER TO UPTS FOR SPHERE
|
||
CLR B ;POINT TO USER MAP
|
||
MOV #20,C ;NUMBER OF SEGMENTS TO LOAD
|
||
MAPRE2: TST (A) ;DOES THE PAGE EXIST?
|
||
BEQ MAPRE3 ;NO PAGE HERE
|
||
MAPRE7: BIT #UPTABS,(A) ;IS IT AN ABS PAGE?
|
||
BNE MAPRE8 ;YUP, GO LOAD IT
|
||
BIT #UPTDEI,(A) ;IS IT THE DATA PART OF A D=I ?
|
||
BNE MAPRE3 ;YUP, GO IGNORE IT
|
||
MOV UPTPBP(A),D ;GET A POINTER TO THE PAGE BLOCK
|
||
BEQ MAPRE3 ;NO PB=>NO PAGE
|
||
BIT #PBVACR,(D) ;IS THE PAGE IN CORE?
|
||
BEQ MAPRE3 ;NOPE, IGNORE IT
|
||
BIT #PBLOCK!PBDISK,(D) ;LOCKED OR IN DISK TRANSFER?
|
||
BNE MAPRE3 ;IF SO, IGNORE IT
|
||
MOVB UPTSTL(A),E ;GET THE UPT START AND LENGTH
|
||
BIC #UPTSMS,E ;CLEAR OFF CRAP
|
||
ASH #-UPTSSH,E ;SHIFT TO GET # OF START BLOCK
|
||
MOVB PBRAN(D),F ;TO GET PB START
|
||
BIC #PBSTRT,F ;IT IS IN BLOCKS
|
||
SUB F,E ;GETS HOW FAR PAST PB START UPT START IS
|
||
ADD PBCAR(D),E ;WHICH TELLS US WHAT TO ADD TO THE CORE ADDRESS
|
||
ASH #4,E ;32.=512.
|
||
BIT #UPTEXD,(A) ;IF IT IS EXPAND DOWN
|
||
BUGC NE ;WE HAVE TO DO SPECIAL STUFF
|
||
MOV E,USRISA(B) ;LOAD THE AR
|
||
MOVB UPTSTL(A),E ;NOW TO GET THE START TO USE
|
||
BIC #UPTLMS,E ;GET THE START
|
||
ASH #12.,E ;GET INTO DR FORMAT
|
||
BIS #17_8.,E ;FIX FOR THE SEGMENTER
|
||
MOV #4,F ;READ/WRITE TRAP (TRAP IS NOT ENABLED THOUGH)
|
||
BIT #UPTRDO,(A) ;IS IT READ-ONLY?
|
||
BEQ 1$ ;NO, READ-WRITE
|
||
MOV #1,F ;READ-ONLY, TRAP
|
||
1$: BIS F,E ;SET INTO DR WORD
|
||
MOV E,USRISD(B) ;SET INTO THE DR
|
||
MAPRE6: BIT #UPTIED,(A) ;IS THIS TH EI SPACE HALF OF AN I=D?
|
||
BEQ MAPRE3
|
||
MOV USRISD(B),USRDSD(B) ;COPY THE DR
|
||
MOV USRISA(B),USRDSA(B) ;COPY THE AR
|
||
MAPRE3: TST (B)+ ;NEXT
|
||
ADD #UPTLEN,A
|
||
DEC C
|
||
BEQ 1$
|
||
JMP MAPRE2
|
||
1$:
|
||
.IFNZ TVS
|
||
MOVB #73,TVSHR+1 ;SET THE THING INTO MEMORY
|
||
MOV ITM0A,A ;POINTER TO ITEM 0
|
||
MOVB PTVMAP+1(A),TVSEL ;SET SELECT REGISTER
|
||
MOVB PTVMAP(A),D ;SET >0 IF HE WANTS IT IN HIS MAP
|
||
BMI MAPRE0 ;DOESNT WANT IT
|
||
CLR TVMSK ;NO MASKING
|
||
ASL D ;FOR INDEXING
|
||
MOV #4,E ;MAX NUMBER OF DISPLAY PAGES
|
||
MOV #6600,F ;THE APPROPRIATE AR
|
||
MAPRE4: CMP #20,D ;PAST ALL THE POSSIBLE D PAGES?
|
||
BLOS MAPRE0 ;THEN WE'RE DONE
|
||
MOV #77406,USRDSD(D) ;A FULL 4K PAGE
|
||
MOV F,USRDSA(D) ;WHERE THE DISPLAY IS
|
||
ADD #200,F ;4K MORE
|
||
TST (D)+ ;NEXT PAGE
|
||
SOB E,MAPRE4
|
||
.ENDC
|
||
MAPRE0: JSR F,ACRES
|
||
MAPRE9: RTS PC
|
||
|
||
MAPRE8: MOV UPTPBP(A),USRISA(B) ;PB POINTER IS THE AR
|
||
MOV UPTGIP(A),USRISD(B) ;GIP POINTER IS THE DR
|
||
BR MAPRE6 ;CHECK FOR I=D
|
||
;THE MEMORY TABLE INITIALIZER
|
||
;CLOBBERS ALL REGISTERS
|
||
MEMTST: MOV #20,ITM0AR ;FIRST FIND HOW MUCH MEMORY
|
||
MOV #6,ITM0DR ;LENGTH 1 PAGE
|
||
SAVE BEBRV ;SAVE THE BUSS ERROR VECTOR
|
||
MOV #MEMTS1,BEBRV ;TRAP BACK TO THE ROUTINE
|
||
MOV #MNCBLK,A ;THE MOST WE WILL PAY ATTENTION TO
|
||
MOV #CST,B
|
||
MEMTS2: TST ITM0AD ;CAUSE BUSS ERROR IF NXM
|
||
ADD #20,ITM0AR ;INCREMENT BY 512 WORDS
|
||
MOV #CSTBEB!CSTSYB,(B)+ ;SAY IT EXISTS AND SYSTEM USING IT
|
||
SOB A,MEMTS2 ;TRY AGAIN UNLESS WE HAVE ENOUGH
|
||
MOV B,CSTTOP
|
||
BR MEMTS3
|
||
MEMTS1: SPL 0
|
||
MOV B,CSTTOP
|
||
CMP (P)+,(P)+ ;FLUSH THE TRAP
|
||
1$: MOV #CSTSYB,(B)+ ;SAY THE SYSTEM IS USING NON-EX CORE
|
||
SOB A,1$
|
||
MEMTS3: REST BEBRV
|
||
MOV ITM0AR,B
|
||
.IF NZ NTVS
|
||
CMP #<124.-16.>*<1024./32.>,B ;DOES CORE CONFLICT WITH DISPLAY?
|
||
BUGC LO
|
||
.ENDC
|
||
SUB #20+<<<RUGIAR-I0AR>+2>*100>,B ;CONVERT TO AMOUNT ABOVE RUG
|
||
BUGC LE ;IS THERE ENOGUH FOR RUG
|
||
ASH #-4,B ;CONVERT TO 512 WORD BLOCKS
|
||
MOV #<<RUGIAR-I0AR>+2>*4,A ;FIRST BLOCK AFTER RUG
|
||
.IIF NZ NTKDIS,JSR PC,DISALC
|
||
ASL A ;CONVERT TO
|
||
ADD #CST,A ;INDEX IN TO THE CST
|
||
MOV B,FREECR ;AMOUNT OF FREE CORE
|
||
MEMAL1: BIC #CSTSYB,(A) ;NOT USED BY SYSTEM
|
||
BIS #CSTFRB,(A)+ ;AND FREE
|
||
SOB B,MEMAL1
|
||
|
||
MOV #CST+<FSTFRB*2>,A ;POINT TO FIRST FREE CST ENTRY
|
||
MOV #<<<RUGST-LSTILC>_-10.>>&77-1,B ;NUMBER FREE BEFORE RUG
|
||
ADD B,FREECR
|
||
MOV FREECR,USRCOR ;ALL FREE CORE IS CURRENTLY USER CORE
|
||
MEMAL2: BIC #CSTSYB,(A)
|
||
BIS #CSTFRB,(A)+ ;FREE BLOCK, NOT USED BY SYSTEM
|
||
SOB B,MEMAL2
|
||
MOV #CSTSYB!CSTBEB,CST+<<RUGST_-9.>&176> ;PROTECT RUG PAGE
|
||
RTS PC
|
||
.IFNZ NTKDIS
|
||
;DISPLAY ALLOCATION ROUTINE
|
||
;ENTER WITH PLACE TO START ALLOCATING IN A
|
||
;NUMBER OF BLOCKS FREE IN B
|
||
;RETURN WITH A POINTING PAST WHAT WE HAVE ALLOCATED
|
||
;AND B HAVING WHAT WE HAVE ALLOCATED REMOVED
|
||
DISALC: CMP #100,A ;THE DISPLAYS MUST START
|
||
NBUGC LE
|
||
MOV A,C ;SAVE START
|
||
ASH #10.,C ;CONVERT TO WORD ADDRESS
|
||
MOV C,TKRELS ;AND SAVE AS THE RELOCATION
|
||
MOV C,NGREL ;ALSO SET RELOCATION
|
||
MOV #1,C ;LENGTH ONE BLOCK
|
||
JSR PC,ITMFAK ;FAKE UP AN ITEM
|
||
MOV D,TKDPDL ;THE PDL AND START VECTOR ITEM
|
||
MOV ITMTAB(D),TKDPDA ;SAVE THE START IN A CONVEINET PLACE
|
||
CLR E ;THE ONE WE ARE ALLOCATING
|
||
MOV #NTKDIS,F
|
||
DISAL1: MOV TKDLEN(E),C ;LENGTH FOR THIS ONE
|
||
JSR PC,ITMFAK ;FAKE UP AN ITEM
|
||
MOV D,TKDITM(E) ;SAVE THE ITEM FOR THIS DISPLAY BUFFER
|
||
TST (E)+
|
||
SOB F,DISAL1
|
||
SAVE <A>
|
||
MOV TKDPDL,A ;THE PDLS AND START WORDS
|
||
JSR PC,ITM2LD
|
||
MOV #8.,C
|
||
DISAL2: MOV #DSTOP,(A)+ ;STOP ALL DISPLAYS
|
||
SOB C,DISAL2
|
||
REST <A>
|
||
RTS PC
|
||
|
||
;FAKE UP AN ITEM
|
||
ITMFAK: SAVE <C>
|
||
MOV ITMFRE,D ;THE ITEM LIST
|
||
MOV (D),ITMFRE ;TAKE THIS ITEM
|
||
ASH #4,C ;MAKE LENGHT INTO 32. WORD BLOCKS
|
||
DEC C ;CAUSE OF WAY SEGMENTS WORK
|
||
MOVB C,ITLNGT(D) ;SET LENGHT
|
||
MOVB #ITACCD,ITACCS(D) ;AND ACCESS
|
||
MOV A,C ;COPY START
|
||
ASH #4,C ;MAKE IT INTO 32. WORD BLOCKS
|
||
MOV C,(D) ;SET THE ADDRESS INTO THE ITEM
|
||
SUB #ITMTAB,D ;MAKE IT INTO AN ITEM NUMBER
|
||
REST <C> ;RESTORE LENGHT IN 512. WORD BLOCKS
|
||
ADD C,A ;NEXT PLACE TO ALLOCATE
|
||
SUB C,B ;STUFF WE'VE USED
|
||
BUGC LE
|
||
RTS PC
|
||
.ENDC
|
||
;TRY TO FIND A NUMBER OF CONTIGOUS BLOCKS LARGE ENOUGH FOR THE PAGE
|
||
;REPRESENTED BY THE PB POINTED TO BY B
|
||
;ON SUCESS, CLOBBER THE CAR OF THE PAGE TO THE RIGHT THING
|
||
;AND UNFREE THE CORE IN CST AND CSTPB
|
||
FINPAG: TST PBCAR(B) ;DOES IT ALREADY HAVE CORE?
|
||
BNE FINPA0 ;YES, JUST RETURN WINNING
|
||
JSR F,ACSAV ;MIGHT AS WELL SAVE THEM ALL...
|
||
MOVB PBLEN(B),A ;HOW LONG DO WE NEED?
|
||
INC A ;0=1
|
||
CMP A,FREECR ;DO WE HAVE THAT MUCH ALL TOGETHER?
|
||
BGT FINPA8 ;NO WAY TO WIN
|
||
MOV CST1FR,C ;POINT TO CST ENTRY OF FIRST FREE BLOCK
|
||
MOV #CSTFRB,E ;A COMMONLY USED CONSTANT
|
||
MOV CSTTOP,F ;GENERATE NUMBER OF TIMES TO TRY
|
||
SUB C,F ;DEIFFERENCE OF TOP AND FIRST FREE
|
||
ASR F ;WORDS
|
||
FINPA1: MOV A,D ;COPY THE LENGTH
|
||
BIT E,(C)+ ;THIS ONE FREE?
|
||
BNE FINPA3 ;GOT ONE
|
||
FINPA4: SOB F,FINPA1 ;KEEP TRYING
|
||
BR FINPA8 ;NO GOOD
|
||
|
||
FINPA3: MOV C,B ;SAVE POINT TO START OF BLOCK+2
|
||
DEC D ;GOT ONE BLOCK, IS THAT ENOUGH?
|
||
BEQ FINPA9 ;YUP, WIN
|
||
FINPA5: BIT E,(C)+ ;IS NEXT ONE FREE?
|
||
BEQ FINPA4 ;NO, HAVE TO TRY ANOTHER PAGE
|
||
DEC D ;ONE MORE, ENOUGH?
|
||
BEQ FINPA9 ;YUP
|
||
SOB F,FINPA5 ;KEEP TRYING
|
||
INC NOFIT ;INCREMENT NUMBER OF TIMES THAT A PAGE WOULDN'T FIT
|
||
FINPA8: JMP ACRETS ;NO LUCK, GIVE UP
|
||
|
||
FINPA9: MOV B,F ;GET BACK THE POINTER TO THE START+2
|
||
TST -(F) ;BACK UP TOT HE REAL ENTRY
|
||
MOV F,C ;COPY IT
|
||
MOV A,D ;AND THE LENGTH
|
||
FINPA6: MOV 2(P),CSTPB-CST(C) ;THIS PAGE OCCUPIES THIS BLOCK
|
||
BIC E,(C)+ ;BLOCK IS NO LONGER FREE
|
||
SOB D,FINPA6
|
||
SUB A,FREECR ;TAKE THIS AWAY FROM FREE CORE
|
||
BNE FINP10 ;SOMETHING STILL FREE
|
||
MOV CSTTOP,CST1FR ;TOP IS FIRST FREE, IS NOTHING
|
||
BR FINPA7
|
||
|
||
FINP10: CMP F,CST1FR ;IS THIS WHAT USED TO BE FIRST FREE?
|
||
BNE FINPA7 ;NOPE
|
||
1$: BIT E,(C)+ ;IS THIS FREE?
|
||
BEQ 1$ ;LOOP UNTIL WE FIND THE FIRST FREE BLOCK
|
||
TST -(C) ;OVERSHOT
|
||
MOV C,CST1FR ;REPLACE WITH NEW FIRST FREE
|
||
FINPA7: SUB #CST,F ;GET THE BLOCK NUMBER
|
||
ASR F
|
||
MOV 2(P),B ;GET BACK POINTER TO THE PB
|
||
MOV F,PBCAR(B) ;AND PUT TI INTO THE PB
|
||
JSR F,ACRES
|
||
FINPA0: CLZ
|
||
RTS PC
|
||
;FLUSH CORE USED BY THE B IN B, PCLOSERING AS NEEDED
|
||
PBCFLS: BIT #PBVACR,(B) ;IS THE PAGE IN CORE?
|
||
BEQ PBCFR9 ;NO, DON'T NEED TO WORRY
|
||
SAVE B ;SAVE THE PB POINTER
|
||
MOV PBGIP(B),B ;GET A GIP FOR IT
|
||
JSR PC,PAGPCL ;PCLOSER ANYONE WHO MIGHT HACK THIS PAGE
|
||
JSR PC,PCLCLR ;I DON'T WANT TO BE PCLOSERED BY THIS!
|
||
REST B ;GET BACK PB POINTER
|
||
;FALL IN
|
||
;FREE THE BLOCKS BELONGING TO THE PAGE BLOCK POINTED TO BY B
|
||
PBCFRE: SAVE <A,C>
|
||
BIT #PBDISK!PBLOCK,(B) ;BETTER NOT BE LOCKED OR DISKING
|
||
; BUGC NE
|
||
BEQ 1$
|
||
JSR PC,BUGGER
|
||
1$: BIC #PBVACR,(B) ;NO LONGER VALID IN CORE
|
||
MOVB PBLEN(B),A ;GET THE LENGTH
|
||
INC A ;0=1
|
||
MOV PBCAR(B),C ;GET THE START
|
||
BEQ PBCFR2 ;SOMEONE ELSE ALREADY FREED HIS CORE
|
||
CLR PBCAR(B) ;NO LONGER VALID
|
||
ASL C ;CONVERT TO A WORD INDEX
|
||
ADD #CST,C ;POINTER INTO CST
|
||
CMP C,CST1FR ;IS THIS BEFORE THE FIRST FREE?
|
||
BHI PBCFR1 ;NO
|
||
MOV C,CST1FR ;NOW THIS IS FIRST FREE
|
||
PBCFR1: BIS #CSTFRB,(C) ;FREE THE BLOCK
|
||
CLR CSTPB-CST(C) ;DOESN'T BELONG TO ANYONE
|
||
INC FREECR ;ONE MORE FREE
|
||
TST (C)+ ;NEXT
|
||
SOB A,PBCFR1 ;AS MANY TIMES AS NEEDED
|
||
PBCFR2: REST <C,A>
|
||
PBCFR9: RTS PC
|
||
|
||
BUGGER: BIT #10,CSWR
|
||
BEQ 1$
|
||
BPT
|
||
1$: MOV ITM0A,A
|
||
BIS #PPCLSR,PFLAGS(A)
|
||
JSR PC,PCLCHK
|
||
BPT
|
||
|
||
.SBTTL FUPT HACKING ROUTINES
|
||
;GET A FUPT THAT POINTS AT A PB THAT REPRESENTS (B) BLOCKS OF FREE CORE
|
||
;ON EXIT, A CONTAINS A GIP TO THE NEW PAGE AND B POINTS TO THE PB
|
||
;Z IS SET IF NO SWAP SPACE IS AVAILABLE
|
||
;A SWITCH IS PUSHED THAT WILL DELETE THE PAGE IF PCLOSERED
|
||
FRCRGT: JSR PC,PBGET ;GET A PAGE BLOCK
|
||
JSR PC,FUPTGT ;GET A FUPT AND POINT IT AT THE PB
|
||
JSR PC,FINSWP ;TRY TO FIND SWAP SPACE FOR IT
|
||
BEQ FRCRG1 ;CAN'T
|
||
JSR PC,LSWPOP ;POP LOCK FOR FUPT
|
||
JSR PC,LSWPOP ;POP LOCK FOR PB
|
||
SAVE <B,A> ;NOW TO LOCK FPT A DIFFERENT WAY
|
||
MOV #LSPPCL,A ;RUN ROUTINE ON PCLOSER
|
||
CLR B ;NO ITEM
|
||
JSR PC,LOCKSW ;GET A LOCK BLOCK
|
||
MOV #FUPTFL,LCKWD1(A) ;ROUTINE
|
||
MOV (P),LCKWD2(A) ;FUPT POINTER
|
||
REST <A,B>
|
||
CLZ
|
||
RTS PC
|
||
FRCRG1: JSR PC,FRELSE ;FLUSH THE FUPT
|
||
JSR PC,FRELSE ;FLUSH THE PB
|
||
SEZ
|
||
RTS PC
|
||
|
||
;GET A FUPT TO POINT TO THE PB POINTED TO BY B
|
||
;COPY THE LENGTH FROM THE PB INTO THE FUPT
|
||
FUPTGT: SAVE <C,B>
|
||
MOV #FUPTFR,B ;FREE POINTER FOR FUPTS
|
||
JSR PC,FREEGT ;GET ONE
|
||
JSR PC,FREELK ;LOCK IT
|
||
MOV (P),B ;POINTER TO THE PB
|
||
MOV B,UPTPBP(A) ;POINT FPT AT IT
|
||
CLR FUPTPR(A) ;THE THING CURRENTLY IS NOT LOCKED BY A PROCESS
|
||
MOV #UPTEXB,UPTFLG(A) ;INIT THE FLAGS
|
||
MOVB PBLEN(B),UPTSTL(A) ;INIT THE LENGTH AND START
|
||
TST PBGIP(B) ;DOES THIS PB POINT TO OTHER UPTS?
|
||
BEQ FUPTG1 ;NO, EASY CASE
|
||
MOV PBGIP(B),B ;FIRST ONE IT POINTS TO IN CIRC LIST
|
||
JSR PC,UPTPLD ;PUSH AND LOAD
|
||
MOV UPTGIP(B),UPTGIP(A) ;POINT NEW ONE TO 2ND IN LIST
|
||
BIS #GIPBIT,A ;MAKE A A VALID GIP
|
||
MOV A,UPTGIP(A) ;POINT FIRST IN LIST AT NEW ONE
|
||
JSR PC,ITM2PO ;RESTORE ITEM2
|
||
FUPTG2: REST <B,C>
|
||
RTS PC
|
||
FUPTG1: MOV A,C ;COPY POINTER TO NEW FUPT
|
||
BIS #GIPBIT,A ;MAKE A VALID GIP
|
||
MOV A,PBGIP(B) ;POINT THE PB AT IT
|
||
MOV A,UPTGIP(C) ;AND POINT IT AT ITSELF
|
||
BR FUPTG2
|
||
|
||
;THIS PCLOSER ROUTINE FLUSHS A FUPT ASSUMMING IT HAS NO CIRCLAR LIST
|
||
;AND THE PAGE DOESN'T NEED TO BE SWAPPED BACK TO SOURCE
|
||
FUPTFL: MOV LCKWD2(B),B ;GET THE GIP
|
||
BIC #GIPBIT,B ;CONVERT TO FUPT POINTER
|
||
SAVE B ;WE'LL NEED IT OCCASIONALLY
|
||
MOV UPTPBP(B),B ;POINT TO THE PB
|
||
JSR PC,PBSFRE ;FREE THE SWAP SPACE
|
||
JSR PC,FPBFR ;FREE A FILE PAGE BLOCK
|
||
REST B ;GET FUPT POINTER BACK
|
||
MOV FUPTFR,A ;ONES FREE NOW
|
||
MOV B,FUPTFR ;NEW ONE
|
||
MOV A,(B) ;INTO LIST
|
||
RTS PC
|
||
|
||
;MAKES A GENERALIZED ITEM POINTER, B CONTAINS UPT NO, C CONTAINS SPHERE NO.
|
||
;THEN DELETES UPT, BY FALLING INTO UPTDL
|
||
SUPTDL: ASH #10.,B ;SET THE UPT NO. IN THE CORRECT BITS
|
||
ASH #-2,C ;FOR GIP
|
||
BIS C,B ;SET IN THE ITEM NO.
|
||
ASH #2,C
|
||
BIS #GIPBIT!GIPSPR,B ;SAY IT IS A GIP AND IN A SPHERE
|
||
;FALL INTO UPTDL
|
||
;THIS ROUTINE FLUSHS A UPT THAT MIGHT HAVE A CIRCULAR LIST
|
||
;AND THAT MIGHT POINT AT CORE THAT IS NOT VALID AT SOURCE
|
||
;NEEDLESS TO SAY, IT MIGHT HANG
|
||
;THE UPT IS POINTED TO BY B, WHICH MIGHT GET CLOBBERED
|
||
UPTDL: JSR PC,SAVAWB ;IN CASE WE AFFECT A MAPPED IN PAGE
|
||
JSR F,ACSAV
|
||
SAVE B ;SAVE THE ACTUAL GIP
|
||
JSR PC,UPTPLD ;LOAD UP THE UPT
|
||
SAVE B ;SAVE THE POINTER TO THE UPT
|
||
BIT #UPTABS,(B) ;ABSOLUTE PAGE?
|
||
BNE UPTDL7 ;YUP, EASY
|
||
TST (B) ;DOES IT EXIST?
|
||
BEQ UPTDL7 ;NO, JUST AS EASY
|
||
UPTDL4: MOV UPTPBP(B),B ;GET ITS PB POINTER
|
||
JSR PC,PBWAIT ;MAKE SURE PAGE IS STABLE
|
||
BIT #PBVAS,(B) ;IS IT VALID AT SOURCE?
|
||
BNE UPTDL1 ;YES, WE'RE SAFE
|
||
MOV 2(P),B ;GET BACK GIP POINTER TO IT
|
||
JSR PC,SWPIN ;SWAP IT IN
|
||
JSR PC,VALSRC ;VALIDATE IT AT THE SOURCE
|
||
JSR PC,GPWAIT ;WAIT FOR IT TO SETTLE DOWN
|
||
MOV (P),B ;GET ADDRESS BACK
|
||
BR UPTDL4 ;DOUBLE CHECK
|
||
UPTDL1: MOV (P),B ;GET BACK THE ADDRESS
|
||
CMP 2(P),UPTGIP(B) ;DOES IT POINT TO ITSELF?
|
||
BEQ UPTDL8 ;YES, EASY CASE
|
||
CLR E ;NO BITS SET YET
|
||
SAVE <UPTGIP(B),UPTGIP(B)> ;TWO COPIES OF WHAT IT POINTS TO
|
||
UPTDL2: MOV (P),B ;GET THE NEXT POINTER
|
||
JSR PC,UPTLD ;LOAD IT
|
||
MOV UPTGIP(B),(P) ;GET THE NEW NEXT
|
||
JSR PC,UPTEST ;SET BITS IN E ACCORDING TO UPT
|
||
CMP 6(P),(P) ;IS THE NEXT THING THE THING WE STARTED WITH?
|
||
BNE UPTDL2 ;NOPE, KEEP TRING
|
||
MOV 2(P),UPTGIP(B) ;THIS UPT POINTS AT WHAT WE WANT TO FLUSH
|
||
;2(P) IS WHAT THE THING WE ARE FLUSHING POINTS TO
|
||
;THUS, THIS INST FLUSHES THE UPT WE WANT TO FLUSH
|
||
MOV 6(P),B ;GET POINTER TO GIP BEING FLUSHED
|
||
JSR PC,UPTLD ;MAKE SURE THATS WHATS LOADED
|
||
MOV UPTPBP(B),B ;GET POINTER TO THE PB
|
||
CMP 6(P),PBGIP(B) ;WAS THIS THE ONE THE PB POINTED TO?
|
||
BNE 1$ ;NO, SAFE
|
||
MOV 2(P),PBGIP(B) ;DON'T LET THE PB GET LONELY
|
||
1$: CLR C ;ACCUMULATE STARTT
|
||
JSR PC,PBLFIX ;GO FIX UP THE PB TO ACCOMADATE ONLY WHAT'S LEFT
|
||
CMP (P)+,(P)+ ;FLUSH DUMMIES FROM STACK
|
||
UPTDL7: REST B ;GET BACK ORRIGINAL ADDRESS
|
||
BIT #GIPSPR,(P) ;IS IT A SPHERE UPT?
|
||
BNE UPTDL3 ;GO HANDLE THAT
|
||
;COME HERE FOR FUPT
|
||
UPTD.2: SAVE FUPTFR ;LINK INTO
|
||
MOV B,FUPTFR ;THE FREE LIST
|
||
UPTDL5: REST (B) ;THE FUPT
|
||
REST B ;GET BACK THE NOW USLESS GIP
|
||
JSR PC,ITMFLS ;FLUSH THIS IF IT MIGHT EVER GET LOADED SOMEPLACE
|
||
JSR PC,MAPRES
|
||
JMP ACRTP2
|
||
UPTDL3: BIT #UPTABS,(B) ;ABSOLUTE PAGE?
|
||
BNE UPTD.1 ;IGNORE
|
||
BIT #UPTEXB,(B) ;EXIST?
|
||
BEQ UPTD.1 ;NO, IGNORE
|
||
SAVE <A,B,C>
|
||
MOV ITM2A,A ;POINT TO SPHERE BEING AFFECTED
|
||
MOV SPHAPR(A),C ;NUMBER OF ACTIVE PROCESSES
|
||
MOV UPTPBP(B),B ;THE PB BEING AFFECTED
|
||
JSR PC,PBDACT ;DEACTIVE THIS MANY TIMES
|
||
REST <C,B,A>
|
||
UPTD.1: CLR -(P) ;TO CLOBBER UPT WHEN DONE
|
||
BIT #UPTDEI,(B) ;IS IT A D=I PAGE?
|
||
BEQ UPTDL0 ;NO
|
||
BIC #UPTIED,-8.*UPTLEN(B) ;DELETE CORESPONDING BIT INI PAGE
|
||
BR UPTDL5
|
||
UPTDL0: BIT #UPTIED,(B) ;IS IT THE I HALF?
|
||
BEQ UPTDL5 ;NOPE
|
||
BIC #UPTDEI,8.*UPTLEN(B) ;DELETE COORESPONDING BIT
|
||
BR UPTDL5
|
||
|
||
UPTDL8: MOV (P),B ;GET POINTER TO FUPT
|
||
MOV UPTPBP(B),B ;GET POINTER TO PB
|
||
MOV (B),C ;UGH, SAVE FLAGS
|
||
JSR PC,PBCFRE ;FREE THE CORE
|
||
JSR PC,PBSFRE ;FREE THE SWAP SPACE
|
||
JSR PC,FPBFR ;FREE FPB OR REGUALR PB
|
||
BIT #PBFILE,C ;IS IT A FILE PAGE?
|
||
BEQ UPTDL6 ;NO, NOTHING SPECIAL THEN
|
||
JSR PC,MFIPBD ;DELETEING A PB FROM AN MFI
|
||
UPTDL6: REST B
|
||
BIT #GIPSPR,(P) ;DELETED FROM SPHERE?
|
||
BEQ UPTD.2 ;NO, FREE FUPT
|
||
CLR -(P) ;YES, PREPARE TO CLOBBER UPT
|
||
BR UPTDL5
|
||
|
||
;FLUSH THE THING IN B FROM ANY ITEMS IT MIGHT GET LOADED INTO
|
||
;IN ENGLISH, CLOBBER THIS ITEM OFF OF STACKS AND ITEMN
|
||
ITMFLS: SAVE <A,C>
|
||
.IRPC N,<012>
|
||
CMP B,ITEM'N ;LOADED INTO THIS ITEM?
|
||
BNE ITMFL'N ;NOPE
|
||
MOV #-1,ITEM'N ;DUMMY ITEM
|
||
ITMFL'N: MOV ITM'N'D,A ;NUMBER OF FROBS ON THIS STACK
|
||
BEQ 1$ ;NONE
|
||
MOV ITM'N'P,C ;STACK POINTER
|
||
3$: CMP B,(C) ;SAME?
|
||
BNE 2$ ;NOPE
|
||
MOV #-1,(C) ;CLOBBER
|
||
2$: TST (C)+ ;NEXT
|
||
SOB A,3$
|
||
1$:
|
||
.ENDM
|
||
REST <C,A>
|
||
RTS PC
|
||
;SET BITS IN E CORESPONDING TO BLOCK STHE UPT POINTED TO
|
||
;BY B USES.
|
||
;CLOBBERS C AND D
|
||
UPTEST: MOVB UPTSTL(B),C ;GET START AND LENGTH
|
||
BLT EBSET2 ;NOT SET UP YET FOR THIS GUY
|
||
MOV C,D ;COPY IT
|
||
BIC #UPTLMS,D ;GET LENGTH
|
||
BIC #UPTSMS,C ;AND START
|
||
ASH #-UPTSSH,C ;SHIFT START
|
||
;ENTER HERE TO JUST SET THE BITS FOR THE START IN C AND LENGHT IN D
|
||
;CLOBBERS C AND D
|
||
EBSET: INC D ;0=>1
|
||
EBSET1: CMP #7,C ;CHECK THAT BLOCK IS OK
|
||
ERRORC LO,BAD ;BAD ARGUMENT TO CALL
|
||
BISB BMT(C),E ;SET BIT FOR THIS BLOCK
|
||
INC C ;NEXT BLOCK
|
||
SOB D,EBSET1 ;GO FOR THE WHOLE LENGTH
|
||
EBSET2: RTS PC
|
||
|
||
;CALL THIS TO FIX UP A PB TO CONFORM TO THE NEEDS REPRESENTED
|
||
;BY THE BITS IN E. B POINTS TO THE PB, C AND D GET CLOBBERED
|
||
PBLFIX: TST E ;ANY?
|
||
BEQ PBLFI9 ;NOPE
|
||
CLR C
|
||
PBLFI1: BITB BMT(C),E ;THIS BIT ON?
|
||
BNE PBLFI6 ;YUP, WE HAVE THE START
|
||
INC C ;ONE MORE
|
||
BR PBLFI1
|
||
PBLFI6: MOV #7,D ;NOW FROM THE OTHER END
|
||
PBLFI7: BITB BMT(D),E ;THIS ONE HERE?
|
||
BNE 1$ ;YUP
|
||
SOB D,PBLFI7 ;KEEP TRYING
|
||
1$: SUB C,D ;CONVERT END TO LENGTH
|
||
CMPB D,PBLEN(B) ;SAME LENGTH AS BEFORE?
|
||
BNE PBLFI4 ;NO, NEED TO FLUSH FROM CORE
|
||
MOVB PBRAN(B),E ;GET THE START
|
||
BIC #PBSTRT,E
|
||
ASH #-UPTSSH,E
|
||
CMP C,E ;STARTS THE SAME?
|
||
BEQ PBLFI5 ;YUP, NO NEED TO CHANGE
|
||
PBLFI4: JSR PC,PBCFLS ;FLUSH THE PB'S CORE
|
||
BIT #PBFILE,(B) ;SWAP TO SOURCE?
|
||
BEQ PBFLI8 ;YES, OK
|
||
BIC #PBVASS,(B) ;IT IS NOT VALID ON SWAP SPACE, MUST GET FROM SOURCE
|
||
PBFLI8: MOVB D,PBLEN(B) ;SET THE LENGTH
|
||
BICB #7,PBRAN(B) ;FLUSH OLD START
|
||
BISB C,PBRAN(B) ;SET IN NEW START
|
||
PBLFI5: RTS PC
|
||
PBLFI9: MOV #-1,D ;NO BLOCKS
|
||
BR PBLFI4
|
||
;PC LOSER ROUTINE TO CLOBBER A FUPTPR BACK TO ZERO
|
||
PRPFIX: MOV LCKWD2(B),A ;GET POINTER TO FUPT
|
||
CMP ITEM0,FUPTPR(A) ;DO I HAVE IT LOCKED?
|
||
BUGC NE ;UGH, I SHOULDN'T BE UNLOCKING IT!
|
||
CLR FUPTPR(A) ;UNLOCK
|
||
MOV UPTPBP(A),B ;THE PB BEING AFFECTED
|
||
MOV #1,C ;ONE PROCESS
|
||
JSR PC,PBDACT ;NO LONGER REFERS TO IT
|
||
RTS PC
|
||
|
||
;SET THE FUPTPR OF AN FUPT
|
||
;HANG UNTIL IT IS ZERO, THEN SET IT TO RUNNING PROCESS
|
||
;WITH A ROUTINE TO RUN WHEN THE LOCK IS POPED
|
||
FUPTLK: JSR F,ACSAV
|
||
BIC #GIPBIT,B ;CONVERT TO CORE ADDRESS
|
||
FUPTL3: TST FUPTPR(B) ;ALREADY LOCKED?
|
||
BEQ FUPTL1
|
||
CMP PRUNNG,FUPTPR(B) ;AM I THE GUY WHO HAS IT LOCKED?
|
||
BUGC EQ ;WILL NEVER BE AVAILABLE..
|
||
FUPTL2: JSR PC,SFLUSH ;WAIT
|
||
TST FUPTPR(B) ;TRY AGAIN
|
||
BNE FUPTL2
|
||
JSR PC,RUNME
|
||
BR FUPTL3
|
||
FUPTL1: MOV ITEM0,FUPTPR(B) ;SAY I USE THIS FUPT
|
||
MOV B,F ;SAVE POINTER TO IT
|
||
MOV #LSPRTN,A ;RUN THIS ROUTINE WHEN UNLOCKED
|
||
CLR B ;SAY THERE IS NO ITEM
|
||
JSR PC,LOCKSW ;LOCK A SWITCH
|
||
MOV #PRPFIX,LCKWD1(A) ;PUT IN THE ROUTINE TO RUN
|
||
MOV F,LCKWD2(A) ;POINTER TO THE FUPT TO FIX
|
||
MOV UPTPBP(F),B ;THE PB BEING AFFECTED
|
||
MOV #1,C ;ONE PROCESS
|
||
JSR PC,PBACT ;REFERES TO IT
|
||
FUPTL4: JMP ACRET
|
||
;ROUTINE TO FIX UP A PB TO BE A SPECIFIED START AND LENGTH
|
||
;CALL WITH PB POINTER IN B, DESIRED START IN C
|
||
;DESIRED LENGTH IN D
|
||
;ROUTINNE RETURNS WITH Z SET IF NOT ALL THE REQUESTED
|
||
;BLOCKS EXIST IN A FILE PAGE
|
||
PBSETU: JSR F,ACSAV
|
||
JSR PC,PBLONG ;GET THE NEEDED START AND LENGTH
|
||
;AND THE CURENT START AND LENGTH
|
||
BEQ PBSET1 ;NOT ALL BLOCKS OF FILE PAGE EXIST
|
||
CMPB #-1,PBLEN(B) ;IS THE PAGE NOT SET UP?
|
||
BEQ PBSET3 ;THEN JUST SET IT
|
||
CMP C,E ;IS NEEDED START = EXISTING?
|
||
BNE PBSET2 ;NO, NEED TO WORK
|
||
CMP D,F ;IS NEEDED LENGTH EQUAL ALSO?
|
||
BNE PBSET2 ;OH WELL...
|
||
JMP ACRETC ;NOTHING TO DO
|
||
|
||
PBSET2: BIT #PBVAS,PBFLAG(B) ;IS IT VALID AT SOURCE?
|
||
BNE PBSET3 ;YES, WE CAN CLOBBER THE PAGE
|
||
JSR PC,PBSWPI ;MAKE SURE PAGE IS IN CORE
|
||
JSR PC,PBVLSR ;VALIDATE THE PAGE AT SOURCE
|
||
JSR F,ACRES
|
||
BR PBSETU ;GO TRY IT ALL AGAIN
|
||
PBSET3: JSR PC,PBWAIT ;WAIT FOR DISKING TO DIE DOWN
|
||
JSR PC,PBCFLS ;FLUSH THE CORE
|
||
PBSET4: MOVB D,PBLEN(B) ;SET EH NEW LENGTH
|
||
BICB #7,PBRAN(B) ;CLEAR OLD START
|
||
BISB C,PBRAN(B) ;SET IN NEW START
|
||
JMP ACRETC
|
||
PBSET1: JMP ACRETS
|
||
|
||
;DO LENGTH COMPARISIONS FOR NEW AND OLD PB STARTS AND LENGTHS
|
||
;CALL WITH PB POINTER IN B, NEW START AND LENGTH IN C AND D
|
||
;RETURNS WITH NEEDED START AND LENGTH IN C AND D AND CURRENT
|
||
;START AND LENGTH IN E AND F
|
||
;RETURNS WITH Z SET IF SOME BLOCKS IN THE NEEDED PAGE ARE NON-EX
|
||
PBLONG: SAVE A
|
||
ADD C,D ;CONVERT LENGTH TO LAST BLOCK #
|
||
MOVB PBLEN(B),F ;GET CURRENT LENGTH
|
||
BLT PBLON2 ;PB NOT SET UP
|
||
MOVB PBRAN(B),E ;AND CURENT START
|
||
BIC #PBSTRT,E
|
||
ADD F,E ;;CONVERT TO END BLOCK
|
||
CMP C,E ;IS NEW START LESS THAN OLD START?
|
||
BLT PBLON1 ;YES, NEED TO EXPAND PAGE DOWN
|
||
MOV E,C ;THIS WILL BE THE REQUIRED START
|
||
CMP F,D ;IS NEW END PAST OLD END?
|
||
BLT PBLON2 ;YES, NEED TO EXPAND UP
|
||
MOV F,D ;OLD ONE IS HIGH ENOUGH
|
||
PBLON3: SUB C,D ;CONVERT BACK TO LENGTH
|
||
SUB E,F ;LIKEWISE
|
||
REST A
|
||
CLZ
|
||
RTS PC
|
||
|
||
PBLON1: CMP F,D ;IS NEW END PAST OLD END?
|
||
BLT PBLON2 ;YES, USE NEW
|
||
MOV F,D ;NO, USE OLD
|
||
PBLON2: BIT #PBFILE,PBFLAG(B) ;IS THIS A FILE PAGE?
|
||
BEQ PBLON3 ;NO, WE'RE DONE
|
||
MOV B,A ;COPY PB POINTER
|
||
ADD #PBSDA,A ;POINT AT SOURCE ADDRESSES
|
||
ADD C,A ;POINT AT
|
||
ADD C,A ;FIRST ONE WE REFERENCE
|
||
SAVE D ;SAVE END POINTER
|
||
SUB C,D ;CONVERT TO LENGTH
|
||
PBLON5: CMP #-1,(A)+ ;NON-EX BLOCK?
|
||
BEQ PBLON4 ;YOU CAN'T MAP THAT IN!
|
||
DEC D ;DONE ALL?
|
||
BGE PBLON5 ;NOT YET
|
||
REST D ;MADE IT THROUGH OK
|
||
BR PBLON3
|
||
PBLON4: REST <D,A>
|
||
SEZ ;TRYIED TO MAP IN NON-EX BLOCK
|
||
RTS PC
|
||
.SBTTL ITEM TABLE ROUTINES
|
||
.IIF NZ ITMADR!ITLINK,.ERROR NO, IT WON'T WORK WITH ITLINK OR ITADDR NON-ZERO
|
||
;CREATE AN ITEM OF SPECIFIED SIZE
|
||
;THE SIZE IS PUT INTO A; THE ITEM'S INDEX RETURNS IN B
|
||
;THE Z BIT IS SET IF THE ITEM CANNOT BE CREATED; OTHERWISE, IT IS CLEARED
|
||
;THIS MAKES NO ATTEMPT TO COMPRESS EXISTING ITEMS TO PRODUCE CONTIGOUS FREE SAPCE
|
||
;THAT FEATURE IS OF SOMEWHAT QUESTIONALBE VALUE, BUT MIGHT BE ADDED LATER
|
||
CRITEM: CMP #200,A ;CHECK THAT NO ONE ASKS FOR A BLOCK>4K
|
||
BUGC LE
|
||
MOV ITMFRE,B ;ATTEMPT TO GET A FREE ITEM
|
||
BEQ CRITM1 ;NO MORE AVAILABLE, GO LOSE
|
||
SAVE <C,D>
|
||
CRITM8: MOV A,C ;GET THE LENGTH
|
||
ASL C ;CONVERT IT TO AN INDEX
|
||
ADD #ITMATB,C ;INTO THE ALLOCATE TABLE
|
||
CLR D ;FOR THE LEFTOVER COUNT
|
||
CRITM3: TST (C)+ ;IS THERE A FREE ITEM BLOCK OF THIS SIZE?
|
||
BNE CRITM2 ;YES, GO USE IT
|
||
TST (D)+ ;ONE MORE TO FREE WHEN WE FINALLY FIND
|
||
;A BLOCK BIGGER THAN WHAT WE REALLY WANTED
|
||
CMP #ITMATB+400,C ;ARE WE ALREADY OFF THE TOP?
|
||
BNE CRITM3 ;NOPE, NOT YET
|
||
;IF WE GET HERE WE HAVE TO ALLOCATE A NEW BIG BLOCK
|
||
TST ITMBAL ;IS SOMEONE ELSE ALREADY ALLOCATING?
|
||
BEQ CRIT11 ;NO, GO LOCK THE SWTICH
|
||
CRIT13: JSR PC,SFLUSH ;WAIT FOR THE OTHER GUY TO BE DONE
|
||
TST ITMBAL ;DONE YET?
|
||
BNE CRIT13 ;NOPE
|
||
JSR PC,RUNME ;DONE, NOW SEE IF HE LEFT ENGOUGH FOR US
|
||
CRIT16: MOV ITMFRE,B ;HAVE TO GET ANOTHER ITEM
|
||
BEQ CRIT12 ;MAYBE OTHER PEOPLE TOOK THEM ALL
|
||
BR CRITM8 ;NOPE
|
||
CRIT11: SAVE A ;LOCK SWTCH SO NO ONE ELSE GETS TO THIS CODE
|
||
MOV #ITMBAL,A
|
||
MOV #-1,B ;USE ALL THE BITS
|
||
CLR C ;THE SWITCH IS INOT IN AN ITEM
|
||
JSR PC,LCKASW ;IN CASE WE HANG WAITING FOR A BLOCK
|
||
MOV #NITMBL,B ;FIND A FREE ITEM BLOCK SLOT
|
||
MOV #ITMBST,C
|
||
CRIT10: TST (C)+ ;NEGATIVE INDICATES FREE
|
||
BLT CRITM9 ;FOUND ONE!
|
||
SOB B,CRIT10 ;KEEP TRYING
|
||
JSR PC,LSWPOP ;LOSE, NO SPACE TO PUT ANOTHER BLOCK
|
||
REST A
|
||
CRIT12: REST <D,C>
|
||
CRITM1: SEZ ;INDICATE FAILURE
|
||
RTS PC
|
||
;NO, THIS ISN'T THE END OF THE ROUTINE!
|
||
CRITM2: MOV (B),ITMFRE ;NOW THE ITEM POINTED TO BY THIS ONE IS
|
||
;THE BEGINNING OF THE FREE LIST
|
||
MOVB A,ITLNGT(B) ;SET IN THE LENGTH
|
||
MOVB #ITACCD,ITACCS(B) ;AND THE ACCESS CODE
|
||
SAVE <E,F>
|
||
MOV -(C),E ;GET A POINTER TO THE NODE FOR THE FREE BLOCK
|
||
MOV (E),(C) ;SPLICE OUT THIS NODE
|
||
MOV 2(E),F ;ADDRESS OF THE BLOCK
|
||
MOV F,(B) ;PUT IT AWAY IN THE ITEM
|
||
MOV F,C ;COPY IT
|
||
BIC #170000,F ;GET THE ADDRESS PART
|
||
SAVE F ;AND SAVE IT FOR LATER
|
||
TST D ;IS THERE ANY LEFTOVER?
|
||
BEQ CRITM4 ;NO, JUST GO FREE THE NODE
|
||
TST -(D) ;CORRECT D, IT'S OVERENTHUSIASTIC
|
||
MOV ITMATB(D),(E) ;PUT THE NODE INTO THE LIST FOR THE LEFTOVER SIZE
|
||
MOV E,ITMATB(D) ;THERE!
|
||
ADD A,2(E) ;ADD THE AMOUNT USED TO THE ADDRESS
|
||
INC 2(E) ;SINCE ZERO IS ONE(?)
|
||
BR CRITM5 ;NOW GO USE WHAT WE GOT
|
||
CRITM4: MOV ITMAFR,(E) ;LINK IT BACK TO THE FREE LIST
|
||
MOV E,ITMAFR
|
||
CLR 2(E)
|
||
CRITM5: JSR PC,BITSET ;GRAB THE BLOCKS WE WANT
|
||
TST (P)+ ;FLUSH THE ADDRESS FROM THE STACK
|
||
SUB #ITMTAB,B
|
||
REST <F,E,D,C>
|
||
CLZ
|
||
RTS PC
|
||
CRITM9: MOV (P),A ;GET LENGTH OF THING WE'RE ALLOCATING
|
||
ASH #-4,A ;CHANGE TO 512 WORD BLOCKS
|
||
CMP #3,A ;IS IT BIGGER THAN 2K?
|
||
BLE 1$ ;IF SO, USE IT
|
||
MOV #3,A ;OTHERWISE, TRY FOR 2K
|
||
1$: JSR PC,ITMSEX ;EXPAND ITEM SPACE
|
||
ASH #4,A ;CONVERT BACK TO 32 WORD UNITS
|
||
ASH #4,B ;CONVERT TO AN AR-STYLE
|
||
BIS #17,A ;CONVERT TO DR-STYLE
|
||
JSR PC,LSWPOP
|
||
;DONE ALLOCATING CORE
|
||
MOV B,-(C) ;B GETS THE ADDRESS
|
||
SUB #ITMBST,C ;UN-RELATIVE IT
|
||
MOV A,ITMBNF(C) ;A GETS THE NUMBER OF BLOCKS GOBBLED
|
||
MOV ITMAFR,D ;GET AN ALLOCATE NODE
|
||
BUGC EQ ;THERE SHOULD ALWAYS BE ONE AVAILABLE
|
||
MOV (D),ITMAFR ;SPLICE IT OUT OF THE FREE LIST
|
||
SAVE C ;SAVE FOR LATER
|
||
ASH #11.,C ;PUT IT INTO THE HIGH FOUR BITS
|
||
ADD B,C ;COMBINE THE BLOCK ADDRESS AND THE BIG BLOCK NUMBER
|
||
MOV C,2(D) ;AND SAVE IT IN THE NODE
|
||
ASL A ;CONVERT SIZE OF BLOCK TO WORD OFFSET
|
||
MOV ITMATB(A),(D) ;SPLICE THIS NODE
|
||
MOV D,ITMATB(A) ;INTO LIST FOR THIS SIZE
|
||
ASR A ;RESTORE A
|
||
REST C ;GET THE INDEX INTO THE BLOCK VARIABLES
|
||
MOV ITMBTP(C),C ;ADDRESS OF THE BIT TABLE FOR THIS BLOCK
|
||
MOV C,D ;COPY POINTER TO BIT TABLE
|
||
MOV #8.,B ;THERE ARE 8 WORDS
|
||
CRIT14: MOV #-1,(C)+ ;FIRST, SET ALL BLOCKS AS USED
|
||
SOB B,CRIT14 ;DO 8 TIMES
|
||
INC A ;0 IS ONE BLOCK!
|
||
ASH #-4,A ;COVERT TO 512 WORD BLOCKS
|
||
CRIT15: CLR (D)+ ;THERE WILL ALWAYS BE AT LEAST ONE
|
||
SOB A,CRIT15 ;DO UP TO 8 TIMES
|
||
REST A
|
||
CMP #-1,PRUNNG ;ARE WE STILL IN TH EINIT CODE?
|
||
BNE 1$ ;NOPE
|
||
JMP CRIT16 ;THEN JUST RETRY IT
|
||
1$: JSR PC,PCLSET ;ALWAYS PCLOSER
|
||
JMP PCLCHK
|
||
;DELETE THE ITEM WHOSE ITEM NUMBER IS IN A
|
||
;A GETS CLOBBERED
|
||
;THIS MAKES NO ATTEMPT TO RETURN AN EMPTY BIG BLOCK
|
||
;THAT FEATURE SHOULD BE ADDED AS SOON AS POSSIBLE (PROBABLY)
|
||
DLITEM: JSR F,ACSAV
|
||
CLR -(P) ;SAVE A STACK WORD FOR TEMP
|
||
ADD #ITMTAB,A ;RELOCATE INDEX TO BE ACTUAL ADDRESS
|
||
TSTB ITACCS(A) ;IS THIS ITEM FOR REAL?
|
||
BUGC EQ ;OOPS!
|
||
MOV (A),E ;GET THE ADDRESS AND BLOCK # OF THE ITEM
|
||
MOVB ITLNGT(A),(P) ;SAVE THE LENGTH ON THE STACK
|
||
MOV ITMFRE,(A) ;PUT THE NEWLY-FREED NODE ON THE HEAD OF THE
|
||
CLRB ITACCS(A) ;MARK IT AS FREE
|
||
MOV A,ITMFRE ;FREE LIST. IT WON'T BE FREE LONG!
|
||
INC (P) ;CORRECT FOR OFFSET
|
||
MOV (P),F
|
||
MOV E,A
|
||
JSR PC,BITCLR ;CLEAR THE BITS OF THE BLOCK WE ARE FREEING
|
||
MOV #-1,C ;NOW SEE IF THE SPACE BEFORE THE BLOCK IS FREE
|
||
DEC E ;LOOK BEFORE THE BLOCK
|
||
JSR PC,CNTFRE ;GO SEE IF THERE'S ANYTHING WE CAN FREE
|
||
MOV E,F ;SAVE THE REAL BEGGING ADDRESS
|
||
ADD (P),E ;GO TO THE END OF THE SO-FAR FREE BLOCK
|
||
MOV #1,C ;NOW SEARCH FORWARD
|
||
JSR PC,CNTFRE ;GO SEE IF ANYTHING THERE AND FREE WHATEVER YOU FIND
|
||
MOV F,C ;GET THE REAL BEGGINING OF THE BLOCK
|
||
JSR PC,BLKFRE ;FREE THE BLOCK WE HAVE FOUND
|
||
TST (P)+ ;FLUSH THE COUNT FROM THE STACK
|
||
JMP ACRET
|
||
;EXPAND OR CONTRACT ITEM WHOSE INDEX IS IN B
|
||
;TO THE SIZE IN A
|
||
;CLEAR Z IF SUCCESSFUL, OTHERWISE SET Z
|
||
EXITEM: JSR F,ACSAV
|
||
EXITM4: TSTB ITACCS+ITMTAB(B) ;IS THIS ITEM FOR REAL?
|
||
BUGC EQ ;OOOPS!
|
||
CMPB A,ITLNGT+ITMTAB(B) ;WHAT IS THE RELATION OF THE DESIRED LENGTH
|
||
;TO THE CURRENT LENGHT?
|
||
BGT EXITM2 ;NEED TO ADD MORE TO THE ITEM
|
||
BEQ EXITM1 ;THE ITEM IS ALREADY THE DESIRED LENGTH
|
||
;GET HERE TO REMOVE EXTRA STUFF FROM ITEM
|
||
MOVB ITLNGT+ITMTAB(B),F ;GET THE CURRENT LENGTH
|
||
SUB A,F ;DIFFERENCE BETWEEN CURRENT AND DESIRED
|
||
SAVE F ;SAVE THE NUMBER OF BLOCKS TO BE FREED
|
||
MOV ITMADR+ITMTAB(B),E ;ADDRESS OF THE ITEM
|
||
MOVB A,ITLNGT+ITMTAB(B) ;SET THE NEW LENGTH INTO THE ITEM
|
||
ADD A,E ;GET TO THE END OF THE DESIRED PART
|
||
INC E ;CORRECT IT
|
||
MOV E,A ;MAKE THE ROUTINE HAPPY
|
||
JSR PC,BITCLR ;CLEAR THE NEWLY FREED AREA
|
||
MOV E,F ;SAVE THE ADDRESS OF THE BLOCK WE ARE ABOUT TO FREE
|
||
ADD (P),E ;END OF AREA WE KNOW TO BE FREE
|
||
MOV #1,C ;SEARCH FORWARD
|
||
JSR PC,CNTFRE ;LOOK FOR FREE BLOCKS AND FREE THOSE YOU FIND
|
||
MOV F,C ;PUT ADDRESS OF BLOCK INTO THE RIGHT PLACE
|
||
JSR PC,BLKFRE ;PUT FREE BLOCKS ON FREE LIST
|
||
TST (P)+ ;GET RID OF COUNT ON PDL
|
||
EXITM1: JMP ACRETC
|
||
;CONTINUED NEXT WEEK (ACTUALLY, NEXT PAGE)
|
||
;GET HERE IF MORE SPACE NEEDED FOR ITEM
|
||
EXITM2: MOV ITMADR+ITMTAB(B),E ;ADDRESS OF START OF ITEM
|
||
MOVB ITLNGT+ITMTAB(B),A ;GET CURRENT SIZE
|
||
ADD A,E ;TO GET END OF CURRENT BLOCK
|
||
INC E ;CORRECT IT
|
||
MOV E,D ;NOW FIND WHICH BLOCK
|
||
ASH #-11.,D
|
||
BIC #177741,D ;WORD INDEX
|
||
MOV #1,C ;NOW SEARCH FORWARD FOR FREE BLOCKS
|
||
JSR PC,CNTBLK
|
||
BLT EXITM3 ;FORGET THIS IF THERE AREN'T ANY
|
||
MOV (P),C ;GET THE DESIRED COUNT
|
||
INC A ;CORRECT THE AMOUNT FOUND
|
||
SUB A,C ;C=AMOUNT NEEDED-EXTRA FOUND
|
||
MOVB ITLNGT+ITMTAB(B),F ;THE AMOUNT WE ALREADY HAVE
|
||
CMP C,F ;WILL THE TOTAL BE ENOUGH?
|
||
BGT EXITM3 ;NO, FORGET IT
|
||
ADD A,F ;YES, WHAT IS THAT TOTAL?
|
||
MOVB F,ITLNGT+ITMTAB(B) ;THAT IS THE NEW ITEM LENGTH
|
||
MOV A,F ;SAVE THE NUMBER OF BLOCKS WE ARE STEALING
|
||
DEC A ;UNCORRECT IT
|
||
JSR PC,FINDEL ;DELETE IT FROM THE FREE LIST
|
||
MOV F,A ;GET THE COUNT BACK
|
||
MOV E,C ;MAKE THE ROUTINE HAPPY
|
||
SAVE E ;HAPPY!!??
|
||
JSR PC,BITSET ;INDICATE THOSE BLOCKS IN USE
|
||
TST (P)+ ;GET RID OF THE GARBAGE
|
||
MOV (P),A ;NOW, HOW MUCH DID WE REALLY WANT?
|
||
MOV 2(P),B ;FOR WHAT ITEM?
|
||
BR EXITM4 ;GO FLUSH ANY EXTRA WE TOOK
|
||
;GET HERE IF THE BLOCK CAN'T BE EXPANDED NICELY
|
||
EXITM3: MOV (P),A ;GET THE DESIRED SIZE
|
||
JSR PC,CRITEM ;GET AN ITEM OF THE RIGHT SIZE
|
||
BNE EXITM6 ;GOT IT, GO USE IT
|
||
JMP ACRETS ;LOSE, RESTORE AC'S AND GET OUT
|
||
;TO BE CONTINUED (NEXT PAGE)
|
||
EXITM6: MOV B,A ;LOAD THE NEW ITEM INTO THE MAP
|
||
JSR PC,ITM0PL ;PUSH AND LOAD
|
||
MOV A,C ;SAVE THE ADDRESS IT WAS LOADED AT
|
||
MOV 2(P),D ;THE ITEM WE WANT TO EXPAND (COPY)
|
||
MOV D,A ;LOAD IT INTO THE MAP TOO
|
||
JSR PC,ITM1PL ;PUSH AND LOAD
|
||
MOVB ITLNGT+ITMTAB(D),F ;GET THE LENGTH OF THE OLD THING
|
||
INC F ;CORRECT IT
|
||
ASH #5,F ;CONVERT TO WORDS
|
||
1$: MOV (A)+,(C)+ ;COPY THE BLOCK
|
||
SOB F,1$
|
||
JSR PC,ITM0PO ;POP ITEM0
|
||
JSR PC,ITM1PO ;POP ITEM1
|
||
MOV B,A ;SAVE THE NEW ITEM INDEX
|
||
ADD #ITMTAB,D ;MAKE AN ACTUAL ADDRESS
|
||
ADD #ITMTAB,B
|
||
MOV #ITMTEL/2,F ;NUMBER OF WORDS TO EXCAHNGE
|
||
EXITM5: MOV (B),E
|
||
MOV (D),(B)+
|
||
MOV E,(D)+
|
||
SOB F,EXITM5 ;EXCAHNGE OLD AND NEW ITEMS
|
||
JSR PC,DLITEM ;DELETE THE NEW ITEM SLOT WITH THE OLD ITEM CONTENTS!!
|
||
BR EXITM1 ;RETURN SUCESSFULLY, IF SOMEWHAT WEARILY
|
||
|
||
|
||
;CLEAR ITEM WHOSE INDEX IS IN B
|
||
;IT'S LENGTH IS IN A. IT IS ALSO LOADED INTO ITEM0
|
||
;AND ITEM0'S PDL IS PUSHED. A IS CLOBBERED TO THE ADDRESS OF THE ITEM
|
||
CLITEM: SAVE C ;FOR THE WORD COUNT
|
||
MOV A,C ;THE BLOCK COUNT
|
||
INC C ;CORRECTED
|
||
ASH #5,C ;CONVERT TO WORDS
|
||
MOV B,A ;THE ITEM TO CLEAR
|
||
JSR PC,ITM0PL ;GETS LOADED
|
||
ADD C,A ;POINT A TO THE END OF THE ITEM
|
||
ADD C,A ;SINCE C IS A WORD COUNT
|
||
1$: CLR -(A) ;CLEAR TE ITEM, CORRECTING A
|
||
SOB C,1$ ;CLEAR ALL THE WORDS
|
||
REST C
|
||
RTS PC
|
||
;SET THE BITS IN THE ITEM BLOCK BIT TABLE
|
||
;THE STARTING ADDRESS IS EXPECTED IN C AND 2(P)
|
||
;THE COUNT OF BLOCKS (UNCORRECTED) IS EXPECTED IN A (IT SHOULD NOT BE -1)
|
||
;CLOBBERS C,D,E AND F
|
||
BITSET: ASH #-11.,C ;GET THE BIG BLOCK NUMBER
|
||
BIC #177741,C
|
||
DEC ITMBNF(C) ;CORRECT FOR 0=1
|
||
SUB A,ITMBNF(C) ;THAT MANY FEWER BLOCKS AVAILABLE
|
||
MOV 2(P),E ;GET THE ADDRESS BACK
|
||
BIC #170000,E ;CLEAR BIG BLOCK BITS
|
||
MOV A,D ;AND A COUNT WE CAN MUNGE
|
||
SUB ITMBST(C),E ;CONVERT TO BLOCK WITHIN BIG BLOCK
|
||
ASHC #-3.,E ;FIGURE IT OUT YOURSELF
|
||
ASH #-13.,F
|
||
BIC #177770,F
|
||
ADD ITMBTP(C),E ;MAKE IT POINT INTO THE BIT TABLE
|
||
INC D ;SINCE 0=1
|
||
BITST1: BISB BMT(F),(E) ;SET THE BIT
|
||
INC F ;CHANGE THE BIT NUMBER
|
||
BIT #7,F ;HAVE WE JUMPED A BYTE?
|
||
BNE BITST2 ;NOT YET
|
||
CLR F ;NEW BIT NUMBER
|
||
INC E ;AND NEW BYTE NUMBER
|
||
BITST2: SOB D,BITST1 ;DO FOR HOWEVER MANY LITTLE BLOCKS
|
||
RTS PC
|
||
;CLEAR BITS IN THE BIT TABLE FOR THE ITEM BLOCK
|
||
;EXPECTS THE STARTING ADDRESS IN A AND THE COUNT (CORRECTED) IN F
|
||
;CLOBBERS A,B,D AND F
|
||
BITCLR: MOV A,D ;COPY IT
|
||
ASH #-11.,D ;TO GET THE BLOCK #
|
||
BIC #177741,D ;CLEAR BITS THAT MAY BE SET BY ASH
|
||
BIC #170000,A ;GET RID OF THE BLOCK NUMBER
|
||
SUB ITMBST(D),A ;AND MAKE RELATIVE TO START OF BLOCK
|
||
ASHC #-3,A ;KNOCK THE BIT ADDRESS OFF THE END
|
||
ASH #-13.,B ;AND PUT IT IN IT'S PLACE
|
||
BIC #177770,B ;OH FOR A LSH!
|
||
ADD ITMBTP(D),A ;ADDRESS IN THE BIT TABLE
|
||
ADD F,ITMBNF(D) ;MORE FREE SPACE!
|
||
;THIS IS WHERE THE RETURN BIG BLOCK STUFF SHOULD GO
|
||
BITCL1: BICB BMT(B),(A) ;THIS BLOCK NOW FREE
|
||
INC B ;GO TO NEXT BIT ADDRESS
|
||
BIT #7,B ;TO NEXT BYTE?
|
||
BNE BITCL2 ;NOT YET
|
||
CLR B ;ZEROTH BIT
|
||
INC A ;IN THE NEXT BYTE
|
||
BITCL2: SOB F,BITCL1 ;CLEAR UNTIL DEAD
|
||
RTS PC
|
||
;PUT AN ENTRY ON THE APPROPRIATE FREE LIST FOR THE BLOCK WE HAVE FREED
|
||
;EXPECTS THE COUNT (CORRECTED) ON 2(P), THE ADDESS OF THE BLOCK IN C
|
||
;CLOBBERS A AND B
|
||
BLKFRE: MOV 2(P),A ;AND IT'S LENGTH
|
||
DEC A ;SIGH
|
||
ASL A ;CONVERT THE LENGTH INTO A WORD INDEX
|
||
ADD #ITMATB,A ;NOW, THE ADDRESS IN THE ALLOCATE TABLE
|
||
MOV ITMAFR,B ;GET THE FIRST FREE ALLOCATE NODE
|
||
BUGC EQ ;WE SHOULD NEVER RUN OUT OF THESE!
|
||
MOV (B),ITMAFR ;SPLICE IT OUT
|
||
MOV (A),(B) ;SPLICE INTO THE LIST FOR THIS SIZE BLOCK
|
||
MOV B,(A) ;AND FIX THE POINTER TO THE LIST
|
||
MOV C,2(B) ;FINALLY, THE LOCATION OF THE NEWLY FREED BLOCK
|
||
RTS PC
|
||
|
||
|
||
;THIS ROUTINE IS SPECIAL FOR DLITEM
|
||
;IT FINDS FREE SPACE A TACKS IT ON TO EXISTING FREE SPACE
|
||
;NOTE THAT THE WORD AT 2(P) IS EXPECTED TO CONTAIN THE COUNT
|
||
;OF BLOCKS THAT HAVE BEEN FOUND TO BE FREE
|
||
;CLOBBERS A AND B ADDS THE NUMBER OF BLOCKS IT FINDS TO 2(P)
|
||
CNTFRE: JSR PC,CNTBLK ;AND IF SO, HOW MUCH?
|
||
BLT CNTFR1 ;NONE FREE THERE!
|
||
ADD A,2(P) ;SOME THERE, ADD TO PREVIOUS AMOUNT
|
||
INC 2(P) ;SIGH
|
||
FINDEL: JSR PC,FINBLK ;FIND THE BLOCK THAT IS FREE
|
||
DELBLK: MOV (A),(B) ;SPLICE THE NODE OUT OF THE LIST
|
||
MOV ITMAFR,(A) ;AND PUT THE FREED NODE ON THE FREE LIST
|
||
MOV A,ITMAFR ;NEW START OF FREE LIST
|
||
CNTFR1: RTS PC
|
||
;FIND A BLOCK OF A PARTICULAR SIZE THAT BEGINS AT A CERTAIN LOCATION
|
||
;SIZE IN A
|
||
;LOCATION IN E
|
||
;POINTER TO NODE IS RETURNED IN A
|
||
;POINTER TO PREVIOUS NODE IS RETURNED IN B
|
||
;(IT IS A BUG FOR THERE TO BE NO SUCH BLOCK!!!)
|
||
FINBLK: ASL A ;CONVERT THIS INTO A POINTER
|
||
ADD #ITMATB,A ;INTO THE ALLOCATE VECTOR
|
||
FINBL1: MOV A,B ;THE OLD ONE
|
||
MOV (A),A ;THE ONE IT POINTS TO
|
||
BUGC EQ ;MUST BE THERE!!
|
||
CMP 2(A),E ;IS THIS THE ONE?
|
||
BNE FINBL1 ;NOPE
|
||
RTS PC ;YES, WE'RE ALL SET
|
||
;FIND HOW MANY BLOCKS ARE FREE STARTING AT A GIVEN BLOCK AND
|
||
;LOOKING IN A GIVEN DIRETION
|
||
;E CONTAINS THE ABSOULUTE BLOCK NUMBER
|
||
;D CONTIANS THE INDEX OF THE BLOCK IT IS IN
|
||
;C CONTAINS THE DIRECTION (1=> FORWARD, -1=> BACKWARDS)
|
||
;A GETS -1 OR THE LENGTH OF WHAT'S FOUND
|
||
;CONDITON CODES ARE SET BY TST A, I.E. N IS CLEAR IF ANYTHING FOUND
|
||
;E GETS THE ADDRESS OF THE FIRST BLOCK IN THE CHUNK
|
||
CNTBLK: SAVE <F,B,E>
|
||
MOV #-1,A ;THE INTIAL COUNT
|
||
BIC #170000,E ;GET RID OF BLOCK #
|
||
SUB ITMBST(D),E ;MAKE IT RELATIVE TO START OF BLOCK
|
||
BLT CNTBL2 ;NO BLOCKS BEFORE BLOCK!
|
||
ASHC #-4,E ;GET THE BIT NUMBER
|
||
ASH #-12.,F ;AND THE WORD NUMBER
|
||
BIC #177760,F ;MAKE SURE THE BIT NUMBER IS RIGHT
|
||
ASL E ;MAKE A WORD ADDRESS
|
||
MOV #1,B ;THE FIRST BIT
|
||
ASH F,B ;SHIFT BY THE BIT NUMBER
|
||
ADD ITMBTP(D),E ;THE REAL BIT TABLE ADDRESS
|
||
CNTBL1: BIT B,(E) ;IS THIS ONE FREE?
|
||
BNE CNTBL2 ;THEN WE'RE DONE
|
||
INC A ;ANOTHER ONE FREE
|
||
;SHIFT ONE WAY OR THE OTHER
|
||
CLC ;CLEAR THE WAY FOR THE ROTATES
|
||
TST C ;WHICH WAY?
|
||
BLT CNTBL4 ;RIGHT
|
||
ROL B ;LEFT
|
||
BR CNTBL5
|
||
CNTBL4: ROR B ;RIGHT
|
||
CNTBL5: BNE CNTBL1 ;NOT DONE WITH WORD YET
|
||
ADD C,E ;ADJUST ADDRESS
|
||
ADD C,E ;IT IS A WORD ADDRESS
|
||
MOV #1,B ;RESET THE BIT
|
||
TST C ;UNLESS WE ARE LOOKING BACKWARDS
|
||
BGT CNTBL1 ;NOPE, FORWARDS
|
||
MOV #100000,B ;OOPS, BACKWARDS
|
||
BR CNTBL1
|
||
CNTBL2: REST E
|
||
TST C ;THIS IS OK FOR FORWARDS SEARCH
|
||
BGT CNTBL3
|
||
SUB A,E ;BUT MUST BE CORRECTED FOR BACKWARD
|
||
CNTBL3: REST <B,F>
|
||
TST A ;TO SET THE CONDITION CODES
|
||
RTS PC
|
||
;ROUTINES TO LOAD ITEMS INTO THE MAP AND TO PUSH AND POP THE ITEM STACKS
|
||
|
||
.IRPC X,<012> ;CONSTRUCT ROUTINES FOR EACH OF THE ITEM PAGES
|
||
;PUSH THE CURRENT ITEM FOR THIS PAGE ON THE STACK
|
||
;AND LOAD THE ITEM WHOSE INDEX IS IN A
|
||
ITM'X'PL: SUB #2,ITM'X'P ;DECREMENT THE STACK POINTER
|
||
MOV ITEM'X,@ITM'X'P ;STORE CURRENT ITEM ON STACK
|
||
INC ITM'X'D ;INDICATE PUSHED ONE MORE LEVEL
|
||
CMP #NITMPS,ITM'X'D ;ABOUT TO OVERFLOW?
|
||
BUGC LE
|
||
;FALL INTO THE LOAD ITEM ROUTINE
|
||
|
||
;LOAD ITEM WHOSE INDEX IS IN A INTO AN ITEM PAGE
|
||
;RETURN THE ADDRESS THAT THE ITEM WAS LOADED INTO IN A
|
||
ITM'X'LD:
|
||
TST A ;MAKE SURE ITEM NUMBER IS NON ZERO
|
||
BUGC EQ
|
||
SAVE PS
|
||
SPL 7
|
||
CLRB ITM'X'KB ;NO PAGE MAPPED IN
|
||
TST ITM'X'PB ;IS PREVIOUS ITEM A GIP?
|
||
BEQ ITM'X'L4 ;NOPE
|
||
BIT #100,ITM'X'DR ;WAS THIS GIP WRITTEN?
|
||
BEQ ITM'X'L4 ;NO, CAN IGNORE IT
|
||
SAVE B ;SAVE A REGISTER
|
||
MOV ITM'X'PB,B ;THE THING TO INDICATE WAS WRITTEN
|
||
JSR PC,ITMGWT ;GO MARK IT AS WRITTEN
|
||
REST B
|
||
ITM'X'L4: CLR ITM'X'PB
|
||
MOV A,ITEM'X ;THIS IS NOW THE CURRENT ITEM
|
||
BLT ITM'X'L1 ;NOT REALLY AN ITEM
|
||
MOV ITMTAB(A),ITM'X'AR ;SET THE AR
|
||
MOV ITMTAB+ITACCS(A),ITM'X'DR ;AND THE DR
|
||
ITM'X'L2:
|
||
REST PS
|
||
MOV #ITM'X'AD,A ;AND THE ADDRESS
|
||
RTS PC
|
||
ITM'X'L1: CMP A,#-1
|
||
BNE ITM'X'L3 ;ITS A GIP
|
||
CLR ITM'X'DR ;MAKE THE ITEM NXM
|
||
BR ITM'X'L2 ;GO FINISH
|
||
ITM'X'L3: SAVE <C,B,A> ;SAVE REG AND GIP AND LOAD UP A UPT
|
||
MOV #-1,ITEM'X ;SO WHEN WE POP ITEM2 WE WIN
|
||
JSR PC,ITMGIP
|
||
REST <ITEM'X> ;SET ITEM FIRST TO AVOID TIMING SCREW
|
||
MOV A,ITM'X'DR ;CAN ONLY RECURSE ONE LEVEL
|
||
MOV B,ITM'X'AR
|
||
MOV C,ITM'X'PB
|
||
MOVB #-1,ITM'X'KB ;LEGAL TO GET A PAGE TRAP ON THIS PAGE
|
||
REST <B,C> ;RESTORE REGISTER
|
||
BR ITM'X'L2
|
||
|
||
;POP THE TOP ITEM OFF THE STACK
|
||
ITM'X'PO: SAVE A ;DON'T CLOBBER A
|
||
DEC ITM'X'D ;INDICATE POPED ONE LEVEL
|
||
BUGC LT ;DID WE OVER POP?
|
||
MOV @ITM'X'P,A ;GET THE OLD THING
|
||
ADD #2,ITM'X'P ;FLUSH ITFROM THE PDL
|
||
JSR PC,ITM'X'LD ;LOAD THE OLD ITEM
|
||
REST A
|
||
RTS PC
|
||
.ENDM
|
||
;CLEAR THE VALID AT SWAP SPACE AND VALID AT SOURCE BITS OF THE GIP POINTED TO BY A
|
||
ITMGWT: BIT #PBVACR,PBFLAG(B) ;BETTER BE VALID IN CORE!
|
||
BUGC EQ ;UGH, GOT OUT BEFORE WE MAPPED IT OUT!
|
||
BIC #PBVASS!PBVAS,PBFLAG(B) ;CAN'T BE VALID AT SWAP SPACE OR SOURCE, WE'VE WRITTEN IT
|
||
RTS PC
|
||
|
||
ITMGIP: SAVE <D,E>
|
||
MOV A,B
|
||
JSR PC,UPTPLD ;RETURN ADDRESS OF UPT IN B
|
||
BIT #UPTABS,(B) ;CHECK THAT IT ISN'T AN ABSOLUTE PAGE
|
||
BUGC NE
|
||
MOV B,E ;COPY POINTER TO THE UPT
|
||
MOV UPTPBP(E),D ;GET A POINTER TO THE PB
|
||
BIT #PBVACR,PBFLAG(D) ;IS IT VALID IN CORE?
|
||
BEQ ITMGP2 ;NO, FORGET ABOUT IT
|
||
MOVB UPTSTL(E),A ;GET THE UPT START
|
||
BLT ITMGP2 ;NOT SET UP YET
|
||
BIC #UPTSMS,A ;CLEAR OTHER BITS
|
||
.IIF NZ 4-UPTSSH,ASH #4-UPTSSH,A ;SHIFT IF NEEDED
|
||
MOVB PBRAN(D),C ;GET THE PB START
|
||
BIC #PBSTRT,C ;CLEAR OTHER STUFF
|
||
ASH #4,C ;32.=512.
|
||
SUB A,C ;GET PBSTART-UPTSTART
|
||
NEG C ;CHANGE TO UPTSTART-PBSTART
|
||
MOV PBCAR(D),B ;THE PB START ADDRESS
|
||
ASH #4,B ;CONVERT TO 32 WORD BLOCKS
|
||
ADD C,B ;CORRECTED
|
||
MOVB UPTSTL(E),A ;GET START AND LENGTH AGAIN
|
||
BIC #UPTLMS,A ;GET LENGHT OF PAGE
|
||
ASH #4,A ;IN 32 WORD BLOCKS
|
||
SWAB A ;PUT IT INTO THE RIGHT PLACE
|
||
BIS #17_8.+4,A ;OTHERWISE FIX UP THE DR
|
||
ITMGP1: MOV D,C ;RETURN PB POINTER
|
||
REST <E,D>
|
||
JSR PC,ITM2PO
|
||
RTS PC
|
||
ITMGP2: CLR A ;NOBODY HOME
|
||
CLR D
|
||
BR ITMGP1
|
||
;RESTORE THE ITEM2 PDL OF TH EPROCESS POINTED TO BY A
|
||
ITM2RS: SAVE C
|
||
MOV A,C ;SAVE ANOTHER POINTER TO ITEM
|
||
ADD #PITM2P,C ;POINT AT ITEM2 STACK
|
||
MOV (C)+,A ;GET FIRST ITEM2
|
||
JSR PC,ITM2LD ;LOAD IT UP
|
||
ITM2R3: DEC PITM2C(B) ;ONE LESS TO LOAD
|
||
BLT ITM2R4 ;NO MORE
|
||
MOV (C)+,A ;GET NEXT ONE
|
||
JSR PC,ITM2PL ;LOAD
|
||
BR ITM2R3
|
||
ITM2R4: REST C
|
||
RTS PC
|
||
.SBTTL .RDMAP AND .MAP
|
||
;.RDMAP => READ THE MAP OF A SPHERE INTO THE USERS CORE.
|
||
;FIRST ARGUMENT IS THE SPHERE CAPABILITY OF THE MAP TO READ
|
||
;SECOND ARGUMENT IS A POINTER INTO THE USERS CORE, WHERE TO PUT
|
||
;MAP INFO. IT RETURNS 16 WORDS IN THE FOLLOWING FORMAT.
|
||
;BOTTOM 3 BITS ARE THE LENGTH OF THE PAGE., THE TOP BIT IS D=I, NEXT IS ABS
|
||
;NEXT IS FILE PAGE BIT.
|
||
ERDMAP: JSR PC,RETNSW ;GET THE SPHERE CAPABILITY
|
||
MOV A,B ;COPY IT
|
||
BIC #177400,B ;CLEAR THE EXTRA BITS
|
||
MOV ITM1A,A ;THE CURRENT SPHERE
|
||
JSR PC,GCLSTA ;FIND THE CPABILITY
|
||
BEQ RDMAP1 ;FAILED
|
||
ADD A,B ;POINT TO THE CAPABILITY DIRECTLY
|
||
CMPB (B),#.MSCAP ;IS IT A MS CAPABILITY
|
||
BEQ RDMAP2 ;YES, EVERYTHING IS OKAY
|
||
CMPB (B),#.SPCAP ;IS IT A SPHERE CAPABILITY
|
||
BEQ RDMAP2 ;YES, IT IS OKAY SO FAR
|
||
RDMAP1: ERROR BCT ;FAILED
|
||
RDMAP2: BIT #.SPCRR!.SPCRW,(B) ;DOES HE HAVE ACCESS
|
||
BEQ RDMAP1 ;NO
|
||
MOV 2(B),A ;THE SPHERE TO READ THE MAP FROM
|
||
JSR PC,ITM2LD ;LOAD IT UP
|
||
JSR PC,RETNSW ;GET THE POINTER INTO HIS CORE
|
||
MOV #20,B ;THE NUMBER OF WORDS WE ARE RETURNING
|
||
MOV A,C ;COPY IT
|
||
RDMAP3: MFPD (A) ;MAKE SURE ALL THE WORDS ARE WRITABLE
|
||
MTPD (A)+
|
||
SOB B,RDMAP3
|
||
MOV ITM2A,A ;POINTER TO THE UPTS
|
||
MOV #20,B ;NUMBER OF THEM
|
||
ADD #SUPTS,A ;POINT TO THE UPT'S DIRECTLY
|
||
RDMAP4: CLR D ;NO PAGE
|
||
BIT #UPTEXB,(A) ;HELLO?
|
||
BEQ RDMAP5 ;NOBODY HERE
|
||
BIT #UPTABS,(A) ;ABS PAGE?
|
||
BEQ 2$ ;NOPE
|
||
MOV UPTGIP(A),F ;LENGTH OF ABS PAGE
|
||
ASH #-12.,D ;IN 512 WORD BLOCKS
|
||
BIS #.PABS,D ;YUP
|
||
BR 3$
|
||
2$: MOVB UPTSTL(A),D ;GET START AND LENGTH
|
||
BIC #177760,D ;CLEAR EXTRA BITS TO GET LENGTH
|
||
BIT #PBFILE,@UPTPBP(A) ;FILE PAGE?
|
||
BEQ 3$ ;NOPE
|
||
BIS #.PFIL,D ;TELL HIM
|
||
3$: BIT #UPTDEI!UPTIED,(A) ;I=D?
|
||
BEQ 1$ ;NOPE
|
||
BIS #.PDEI,D ;TELL USER
|
||
1$: BIS #.CRRD,D ;READ ALLOWED
|
||
BIT #UPTRDO,(A) ;WRITE ALLOWED?
|
||
BNE 4$ ;NO, READ ONLY
|
||
BIS #.CRWRT,D ;WRITE ALLOWED
|
||
4$: BIT #UPTEXO,(A) ;DATA SPACE ALLOWED?
|
||
BEQ RDMAP5 ;YUP
|
||
BIS #.CREX,D ;EXECUTE ONLY
|
||
RDMAP5: SAVE D ;THE INFO WORD
|
||
MTPD (C)+ ;RETURN IT TO HIM
|
||
ADD #UPTLEN,A ;POINT TO THE NEXT ONE
|
||
SOB B,RDMAP4 ;DO ALL THE PAGES
|
||
JMP ERETCZ ;DONE
|
||
;.MAP
|
||
;CREATE A PAGE FOR A SPHERE,
|
||
;THE FIRST BYTE IS THE SPHERE CAPABILITY TO THE DESTINATION SPHERE
|
||
;THE SECOND IS THE ACCESS INFO (READ, WRITE, AND PRIVATE OR PUBLIC COPY)
|
||
;THE THIRD IS THE SOURCE OF THE PAGE
|
||
;(FILE ACCESS CAP. OR SPHERE CAP, -1 FOR FRESH PAGE, -2 FOR ABSOLUTE PAGE,
|
||
;OR -3 FOR JUST DELETE THIS PAGE)
|
||
;THE FOURTH IS THE UPT NO. OF THE PAGE TO CREATE
|
||
;(0-7 UPT NO. IS I SPACE, 10-17 IS D-SPACE, 20-27 IS I=D SPACE)
|
||
;THE FIFTH AND SIXTH ARE THE PAGE NO. IN SOURCE (IF FILE)
|
||
;THE SEVENTH IS THE START OF THE PAGE (IN 512. WORD BLOCKS)
|
||
;THE EIGHTH IS THE LENGTH-1" " " " " " "
|
||
;IF IT IS A REQUEST FOR A PUBLIC PAGE, AND IT IS PART OF A FILE AND HE
|
||
;IS ASKING FOR WRITE ACCESS, CLEAR THE BYTE AND WORD LEFT FLAGS IN MFI
|
||
;IF IT IS ANOTHER SPHERE, AND IT IS A REQUEST FOR A PUBLIC PAGE, AND HE
|
||
;IS ASKING FOR WRITE ACCESS, EXPAND THE PAGE, AND LINK THE UPT'S TOGETHER
|
||
EMAP: SUB #10,P ;MAKE 4 STORAGE CELLS
|
||
MOV P,D ;GET POINTER TO THE STORAGE
|
||
MOV #4,B ;THE NUMBER OF ARGS
|
||
EMAP1: JSR PC,RETNSW ;GET THE SPHERE CAP AND FLAGS
|
||
MOV A,(D)+ ;SAVE IT
|
||
SOB B,EMAP1
|
||
JSR PC,SAVAWB ;SAVE CURRENT A&W BITS
|
||
MOV (P),B ;THE SPHERE CAP
|
||
BIC #177400,B ;CLEAR THE EXTRA BITS
|
||
MOV ITM1A,A ;THE ADDRESS OF THE ITEM
|
||
JSR PC,GCLSTA ;FIND THE CAPABILITY
|
||
ERRORC EQ,BCN
|
||
ADD B,A ;MAKE A POINT TO THE SPHERE CAP
|
||
MOV (A),B ;GET THE TYPE AND FLAGS
|
||
ERRORC EQ,BCN
|
||
CMPB B,#.SPCAP ;IS IT A SPHERE CAPABILITY
|
||
BEQ EMAP3 ;YES
|
||
CMPB B,#.MSCAP ;IS IT A MASTER SPHERE CAPABILITY
|
||
BEQ EMAP3 ;YES
|
||
ERROR BCT ;BAD CAPABILITY TYPE
|
||
EMAP3: BIT #.SPCRW,B ;IS HE ALLOWED TO MODIFY THE CORE MAP?
|
||
ERRORC EQ,BAC ;BAD ACCESS
|
||
MOVB 3(P),B ;THE UPT NO.
|
||
CMP B,#30 ;IS IT A LEGAL PAGE
|
||
ERRORC HIS,BPN ;BAD PAGE NUMBER
|
||
MOV (P),C ;THE ACCESS
|
||
BIC #377,C ;CLEAR THE LOW BYTE
|
||
CLR E ;IN CASE THERE IS NO ACCESS
|
||
BIT #.CRRD,C ;ASKING FOR READ ACCESS
|
||
BEQ 1$ ;NO,
|
||
MOV #UPTRDO!UPTEXB,E ;SAY READ ONLY ACCESS
|
||
1$: BIT #.CRWRT,C ;ASKING FOR WRITE ACCESS
|
||
BEQ 2$ ;NO
|
||
MOV #UPTEXB,E ;SAY WRITE ACCESS
|
||
2$: BIT #.CREX,C ;ASKING FOR EXECUTE ONLY ACCESS
|
||
BEQ EMAP5 ;NO
|
||
CMPB 3(P),#10 ;BETTER BE AN I SPACE PAGE
|
||
ERRORC LT,BAC ;BAD ACCESS
|
||
EMAP5: CMP B,#20 ;IS IT I=D
|
||
BLT 1$ ;NO
|
||
SUB #10,B ;MAKE IT POINT TO THE D PAGE
|
||
1$: ASH #10.,B ;SET IT INTO CORRECT PLACE
|
||
MOV CLSEPI(A),F ;THE SPHERE AFFECTED
|
||
ASH #-2,F ;ITEMS ARE MULTIPLES OF 4
|
||
BIS B,F ;MAKE A GIP
|
||
BIS #GIPSPR!GIPBIT,F
|
||
MOV F,B ;GIP TO THE UPT TO DELETE
|
||
CMPB 2(P),#-4 ;IS IT A PAGE EXPAND REQUEST?
|
||
LBR EQ,PAGEXP ;YES
|
||
BITB #20,3(P) ;IS IT I=D
|
||
BEQ EMAP4 ;NO JUST DELETE CURRENT PAGE
|
||
JSR PC,UPTDL ;DELETE IT
|
||
SUB #<10_10.>,F ;MAKE IT POINT TO THE I UPT
|
||
MOV F,B ;COPY IT AGAIN
|
||
|
||
EMAP4: JSR PC,UPTDL ;DELETE THE UPT
|
||
MOVB 2(P),B ;THE SOURCE
|
||
CMP B,#-3 ;IS IT REQUEST FOR JUST FLUSHING PAGE
|
||
LBR EQ,EMAPRT ;JUST RETURN
|
||
TSTB B
|
||
BGE EMAP6 ;ITS A CAPABILITY
|
||
MOVB 6(P),D ;THE START
|
||
ERRORC LT,BAD ;BAD: NEGATIVE START
|
||
MOVB 7(P),C ;THE LENGTH OF THE BLOCK TO CREATE
|
||
ERRORC LT,BAD ;NO NEGATIVE LENGTHS
|
||
ADD C,D ;GET THE SUM OF THE LENGTH AND START
|
||
ERRORC VS,BAD ;OVER FLOW
|
||
CMP D,#10 ;IS THE SUM OF THE START AND LENGTH OVER 10
|
||
ERRORC GE,BAD ;YES, LOSE LOSE
|
||
CMP B,#-1 ;IS IT A REQUEST FOR A FRESH PAGE
|
||
LBR EQ,MAPFRS ;YES
|
||
CMP B,#-2 ;IS IT REQUEST FOR ABSOLUTE PAGE
|
||
BEQ MAPABS ;GET AN ABSOLUTE PAGE
|
||
ERROR BFUN
|
||
EMAP6: MOV ITM1A,A ;GET THE ADDRESS
|
||
JSR PC,GCLSTA ;GET THE OFFSET OF THE CAPABILITY
|
||
ERRORC EQ,BCN ;COULDN'T GET IT
|
||
ADD B,A ;MAKE A POINT DIRECTLY TO IT
|
||
MOV (A),B ;THE FLAGS WORD OF THE CAPABILITY
|
||
ERRORC EQ,BCN ;NO CAPABILITY
|
||
CMPB B,#.FACAP ;IS IT A FILE ACCESS CAPABILITY
|
||
LBR EQ,MAPFIL ;YES
|
||
.IF NZ NTVS
|
||
CMPB B,#.DSCAP ;IS IT A DISPLAY CAPABILITY
|
||
LBR EQ,MAPDS ;YES
|
||
.ENDC
|
||
CMPB B,#.SPCAP ;IS IT A SPHERE
|
||
BEQ MAPSPR ;YES
|
||
CMPB B,#.MSCAP ;IS IT A MASTER SPHERE
|
||
BEQ MAPSPR ;YES
|
||
ERROR BCT ;CAN'T MAP THIS TYPE
|
||
MAPSPR: CMP 4(P),#17 ;IS HE ASKING FOR A LEGAL PAGE?
|
||
ERRORC HI,BAD ;NO
|
||
MOV 2(A),A ;GET THE SPHERE
|
||
JSR PC,ITM1PL ;LOAD IT UP
|
||
ADD #SUPTS,A ;POINT TO THE FIRST UPTS
|
||
MOV 4(P),D ;THE PAGE NO.
|
||
MUL #UPTLEN,D ;GET THE LENGTH OF THE OFFSET
|
||
ADD D,A ;POINT TO THE UPT IN SPHERE
|
||
MOV F,B ;POINTER TO PAGE TO CREATE
|
||
JSR PC,UPTPLD ;LOAD IT UP
|
||
BIT #UPTRDO,(A) ;IS IT READ ONLY?
|
||
BEQ MAPSP3 ;NO, FINE
|
||
BIT #UPTRDO,E ;IS HE ASKING FOR READ ONLY?
|
||
ERRORC EQ,BAC ;BAD ACCESS
|
||
MAPSP3: MOV #UPTLEN/2,C ;THE LENGTH IN WORDS
|
||
MOV B,D ;COPY POINTER TO UPT
|
||
1$: MOV (A)+,(D)+ ;COPY UPT
|
||
SOB C,1$
|
||
BIC #UPTDEI!UPTIED,-UPTLEN(D) ;DONT WANT THE NEW PAGE D=I UNLESS HE ASKS
|
||
BIT #UPTABS,-UPTLEN(A) ;COPYING ABS PAGE?
|
||
BNE MAPSP2 ;YES, NO CIRC LIST
|
||
MOV F,-UPTLEN+UPTGIP(A) ;MAKE COPIED POINT TO THE COPY
|
||
MAPSP2: JSR PC,ITM1PO ;POP THE SPHERE WE COPIED
|
||
MAPSP1: JMP MAPFR2 ;TAKE CARE OF I=D, ETC.
|
||
MAPABS: BIT #UPTRDO,E ;HAD BETTER BE READ ONLY
|
||
ERRORC EQ,BAC
|
||
CMP C,#7
|
||
ERRORC HI,BAD
|
||
ASH #12.,C
|
||
BIS #7401,C ;SET IN ACCESS
|
||
MOV 4(P),A ;THE START IN 512. WORDS BLOCKS
|
||
CMP #256.,A ;HIGHER THAN THE HIGHEST BLOCK?
|
||
ERRORC LOS,BAD
|
||
ASH #4,A ;PUT IT INTO THE CORRECT BITS
|
||
MOV F,B
|
||
JSR PC,UPTPLD ;LOAD THE UPT
|
||
MOV #UPTABS!UPTEXB!UPTRDO,(B)+
|
||
MOV A,(B)+ ;SET IN UPTAR
|
||
MOV C,(B)+ ;SET IN UPTDR
|
||
SUB #6,B ;BACK UP THE POINTER TO THE START OF THE UPT
|
||
JMP MAPFR2 ;CHECK FOR I=D, ETC.
|
||
|
||
|
||
;HERE SET UP THE DISPLAY'S PAGES AS ABSOLUTE PAGES
|
||
.IFNZ NTKDIS+NTVS
|
||
MAPDS: .IFNZ NTVS
|
||
TST (A) ;TV OR TK?
|
||
BLT MAPTV
|
||
.ENDC
|
||
MOV 2(A),C ;THE ITEM OF THE DISPLAY
|
||
MOV F,B ;THE PLACE TO PUT IT
|
||
JSR PC,UPTPLD ;LOAD IT UP
|
||
MOV B,D ;COPY POINTER TO UPT
|
||
MOV #UPTABS!UPTEXB,(D)+
|
||
MOV ITMTAB(C),(D)+ ;SET IN THE AR
|
||
MOV ITMTAB+ITACCS(C),(D) ;SET IN THE DR
|
||
CLR E
|
||
MAPDS1: JMP MAPFR2 ;TAKE CARE OF D=I ETC.
|
||
.ENDC
|
||
|
||
.IFNZ NTVS
|
||
MAPTV: MOV F,B ;THE PAGE
|
||
JSR PC,UPTPLD ;LOAD IT
|
||
MOV 4(P),C ;DESIRED PAGE NUMBER
|
||
CMP #4,C ;IS IT A GOOD NUMBER?
|
||
ERRORC LO,BAD ;NOPE
|
||
BEQ MAPTV1 ;GIVE THE REGISTERS
|
||
ASH #7,C ;BLOCK NUMBER TO OFFSET
|
||
ADD #<128.-4-16.>_5,C ;WHERE THE TV GOES
|
||
MOV C,2(B) ;THE AR
|
||
MOV #77406,4(B) ;THE DR
|
||
BR MAPTV2 ;GO FINISH
|
||
MAPTV1: MOV #<TVINCR_-6>&1777!6000,2(B) ;THE AR
|
||
MOV #6,4(B) ;THE DR
|
||
MAPTV2: MOV #UPTABS!UPTEXB,(B) ;ABSOLUTE PAGE
|
||
JMP MAPFR2 ;I=D ETC
|
||
.ENDC
|
||
;A POINTS TO THE FA CAP.
|
||
;F IS GIP TO THE UPT TO CREATE
|
||
;E HAS ACCESS REQUESTED
|
||
MAPFIL: SAVE E ;SAVE ACCESS
|
||
BIT #UPTRDO,E ;IS ALL HE WANTS READ?
|
||
BNE 1$ ;YES, FINE
|
||
BIT #.FAWT,(A) ;DOES HE HAVE WRITE ACCESS?
|
||
ERRORC EQ,BAC ;BAD ACCESS
|
||
1$: MOV FAMFI(A),A ;GET THE RIGHT MFI
|
||
MOV 6(P),C ;GET THE PAGE NUMBER DESIRED
|
||
JSR PC,MAKFPB ;GET THE RIGHT PB
|
||
SAVE B ;SAVE PB POINTER
|
||
MOVB 13(P),D ;GET THE LENGTH
|
||
CMP #-1,D ;DOES HE WANT ALL WE GOT?
|
||
BNE MAPFI1 ;NOPE, SOMETHING ELSE
|
||
MOVB PBFLEN(B),D ;GET THE LENGTH
|
||
DEC D ;1=>0
|
||
ERRORC LT,BAD
|
||
MAPFI1: CMP #7,D ;IS LENGTH LEGAL?
|
||
ERRORC LO,BAD ;NOPE
|
||
MOVB 12(P),C ;GET START
|
||
CMP #7,C ;IS START LEGAL?
|
||
ERRORC LO,BAD ;NOPE
|
||
JSR PC,PBSETU ;FIX UP THE PB
|
||
ERRORC EQ,RPEF ;HE ASKED FOR TOO MUCH
|
||
TST PBDA(B) ;ALREADY GOT SWAP SPACE?
|
||
BNE MAPFI8 ;YUP, DON'T ALOCATE AGAIN
|
||
BIT #PBNOSW,PBFLAG(B) ;DON'T ALLOCATE SWAP SPACE?
|
||
BNE MAPFI8 ;RIGHT, I WON'T
|
||
JSR PC,FINSWP ;GET SOME, BUT DON'T CARE IF YOU LOSE
|
||
MAPFI8: MOV F,B ;COPY GIP
|
||
JSR PC,UPTPLD ;LOAD IT UP
|
||
ASH #UPTSSH,C ;PUT START INTO RIGHT PLACE
|
||
BIS C,D ;COMBINE WITH LENGTH
|
||
MOVB D,UPTSTL(B) ;SET UP IN NEW UPT
|
||
REST C ;GET BACK PB POINTER
|
||
MOV C,UPTPBP(B) ;POINT UPT AT PB
|
||
JSR PC,PCLCLR ;SAFE NOW
|
||
MOV PBGIP(C),E ;GET POINTER INTO CIRCULAR LIST
|
||
BEQ MAPFI2 ;THERE IS NONE
|
||
SAVE B ;SAVE POINTER INTO GIP
|
||
MOV E,B ;GET FIRST IN CIRC LIST
|
||
JSR PC,UPTPLD ;LOADED UP
|
||
SAVE UPTGIP(B) ;SAVE WHAT IT POINTS TO
|
||
MOV F,UPTGIP(B) ;POINT IT AT NEW THING
|
||
JSR PC,ITM2PO ;BACK UP
|
||
REST <E,B>
|
||
MOV E,UPTGIP(B) ;POINT NEW AT WHAT OLD POINTED AT
|
||
BR MAPFI3
|
||
MAPFI2: MOV F,PBGIP(C) ;POINT PB AT NEW CIRC LIST
|
||
MOV F,UPTGIP(B) ;OF ONE ITEM
|
||
MAPFI3: BIS #UPTEXB,(B) ;PAGE EXISTS
|
||
REST E ;GET ACCESS BACK
|
||
JMP MAPFR2
|
||
|
||
MAPFRS: MOV C,B ;THE SIZE OF THE PAGE
|
||
JSR PC,PBGET ;GET A PAGE BLOCK FOR THE NEW PAGE
|
||
JSR PC,FINSWP ;TRY TO FIND SOME SWAP SPACE FOR IT
|
||
BNE MAPFR1 ;GOT SOME
|
||
JSR PC,FRELSE ;FREE THE PB, WE LOST
|
||
ERROR NSS ;NO SWAP SPACE
|
||
MAPFR1: SAVE B ;SAVE POINTER TO PB
|
||
MOV F,PBGIP(B) ;NEW PB POINTS TO GIP BEING CREATED
|
||
MOV F,B ;THE GIP TO THE PAGE BEING CREATED
|
||
JSR PC,UPTPLD ;LOAD IT UP
|
||
MOV #UPTEXB,(B) ;FLAGS
|
||
REST A
|
||
MOVB PBLEN(A),UPTSTL(B) ;COPY THE LENGTH
|
||
MOV A,UPTPBP(B) ;GET THE PB POINTER
|
||
MOV F,UPTGIP(B) ;POINT TO YOURSELF
|
||
MAPFR2: BIC #UPTEXO!UPTRDO,(B) ;CLEAR OLD ACCESS
|
||
BIS E,(B) ;SET IN THE ACCESS
|
||
MOVB 3(P),C ;GET THE PAGE NO. AGAIN
|
||
BIT #UPTABS,(B) ;ABS PAGE?
|
||
BNE MAPFR4 ;IGNORE IT
|
||
BIT #UPTEXB,(B) ;DOES IT EXISTS?
|
||
BEQ MAPFR4 ;NO, IGNORE IT
|
||
SAVE <B,C>
|
||
MOV ITM2A,A ;GET SPHERE BEING AFFECTED
|
||
MOV SPHAPR(A),C ;NUMBER OF ACTIVE PROCESSES
|
||
CMP #20,(P) ;MAPPING IN TWICE?
|
||
BGT 1$ ;NOPE
|
||
ASL C ;TWICE AS MANY REFERENCES
|
||
1$: MOV UPTPBP(B),B ;THE AFFECTED PB
|
||
JSR PC,PBACT ;ACTIVATE PAGE
|
||
REST <C,B>
|
||
MAPFR4: CMP C,#20 ;IS IT A D=I PAGE
|
||
BLT MAPFR5 ;NOPE
|
||
MOV B,D ;COPY POINTER TO UPT
|
||
MOV B,E ;AND A POINTER TO THE DATA HALF
|
||
ADD #<UPTLEN*10>,E ;INTO THE SECOND HALF
|
||
MOV #UPTLEN/2,C ;THE LENGTH OF THE UPT
|
||
1$: MOV (D)+,(E)+ ;COPY THE UPT ENTRY
|
||
SOB C,1$ ;COPY ALL THE WORDS
|
||
SUB #UPTLEN,E ;MAKE IT POINT AT THE NEW ONE AGAIN
|
||
BIS #UPTIED,(B) ;ON THIS HALF, DATA=I
|
||
BIS #UPTDEI,(E) ;AND ON THIS HALF, THE OPPISTIE
|
||
MOV F,A ;COPY GIP TO DATA HALF
|
||
BIS #20000,F ;MAKE IT POINT TO THE TOP HALF
|
||
BIT #UPTABS,(B) ;ABS PAGE?
|
||
BNE MAPFR5 ;YES, NO CIRC LIST
|
||
MOV F,UPTGIP(B) ;POINT FIRST HALF AT SECOND
|
||
MAPFR5: JSR PC,ITM2PO ;POP THE SPHERE
|
||
EMAPRT: ADD #10,P ;POP OFF THE ARGUMENTS
|
||
EMAPR1: JSR PC,MAPRE1 ;MAKE SURE HIS MAP GETS MODIFIED IMMEDIATELY
|
||
MAPFR3: JMP ERETCZ ;SUCESS
|
||
|
||
PAGEXP: SAVE <E,F>
|
||
CMPB #20,7(P) ;IS HE ASKING TO AFFECT AN I=D PAGE?
|
||
BGT PAGEX1 ;NOPE
|
||
SAVE F ;SAVE THE D PART
|
||
SUB #<10_10.>,F ;GET THE D PART
|
||
MOV F,B ;FOR UPTLD
|
||
JSR PC,UPTLD ;POINT US AT THE UPT
|
||
BIT #UPTIED,(B) ;BETTER BE A D=I PAGE
|
||
ERRORC EQ,BAD
|
||
BR PAGEX2
|
||
PAGEX1: SAVE <#0> ;NO OTHER HALF
|
||
MOV F,B ;COPY FOR UPTLD
|
||
JSR PC,UPTLD
|
||
BIT #UPTDEI!UPTIED,(B) ;BETTER NOT BE D=I
|
||
ERRORC NE,BAD ;CAN ONLY DO BOTH TOGETHER NOW
|
||
PAGEX2: SAVE B
|
||
BIT #UPTRDO,E ;DOES HE WANT READ ONLY?
|
||
BNE 1$ ;CAN'T LOSE
|
||
BIT #UPTRDO,(B) ;OLD PAGE READ ONLY?
|
||
ERRORC NE,BAC ;YES, BAD ACCESS
|
||
1$: BIT #UPTEXB,(B) ;DOES THE PAGE EXIST?
|
||
ERRORC EQ,BAD ;NOPE
|
||
BIT #UPTABS,(B) ;ABSOLUTE PAGE?
|
||
ERRORC NE,BAD ;YUP
|
||
MOV UPTPBP(B),B ;GET PB POINTER
|
||
BIT #PBVAS,(B) ;IS IT VALID AT SOURCE?
|
||
BNE PAGEX3 ;YUP
|
||
MOV F,B ;GET THE GIP
|
||
JSR PC,SWPIN ;MAKE SURE IT IS IN
|
||
JSR PC,VALSRC ;GO AND VALIDATE IT
|
||
JSR PC,GPWAIT ;WAIT FOR IT TO BE OUT
|
||
REST <B,,F,E>
|
||
BR PAGEXP ;TRY AGAIN
|
||
PAGEX3: REST <B,(P)>
|
||
CLR E ;THIS WILL ACCUMULATE BITS
|
||
MOVB 12(P),C ;GET START
|
||
MOVB 13(P),D ;GET LENGTH
|
||
JSR PC,EBSET ;ACCUMLATE BITS FOR DESIRED THING
|
||
SAVE <F,UPTGIP(B)> ;PUT THE NEXT THING
|
||
PAGEX4: MOV (P),B ;GET CURRENT UPT
|
||
JSR PC,UPTLD ;LOAD IT UP
|
||
CMP 4(P),(P) ;IS CURRENT ONE THE I HALF OF THE D=I?
|
||
BEQ PAGEX5 ;YES, IGNORE IT
|
||
CMP 2(P),(P) ;HAVE WE GOTTEN BACK TO THE BEGGINING?
|
||
BEQ PAGEX6 ;YES, DONE
|
||
JSR PC,UPTEST ;ACCUMULATE MORE BITS
|
||
PAGEX5: MOV UPTGIP(B),(P) ;GET NEXT ONE
|
||
BR PAGEX4
|
||
PAGEX6: MOV UPTPBP(B),B ;GET THE PB
|
||
JSR PC,PBLFIX ;GO FIGURE OUT E AND SET UP THE PB APPROPRIATELY
|
||
MOV 2(P),B ;GET BACK THE ORIGINAL
|
||
JSR PC,UPTLD ;AND LOAD IT
|
||
ADD #6,P ;FLUSH TEMPS
|
||
MOVB 10(P),C ;GET DESIRED START
|
||
MOVB 11(P),D ;AND LENGTH
|
||
ASH #UPTSSH,C ;PUT START IN RIGHT PLACE
|
||
BIS C,D ;COMBINE THEM
|
||
MOVB D,UPTSTL(B) ;WE DID THE WORK, REAP THE BENIFITS
|
||
REST E ;GET DESIRED ACCESS
|
||
BIC #UPTEXO!UPTRDO,(B) ;CLEAR OLD ACCESS
|
||
BIS E,(B) ;SET NEW ACCESS
|
||
BIT #UPTIED,(B) ;DID WE DO ONLY HALF THE JOB?
|
||
BEQ PAGEX7 ;NO, NOT AN I=D
|
||
MOVB D,UPTSTL+<UPTLEN*10>(B) ;SET IN THE DATA HALF
|
||
BIC #UPTEXO!UPTRDO,<UPTLEN*10>(B) ;CLEAR OLD
|
||
BIS E,<UPTLEN*10>(B) ;SET NEW
|
||
PAGEX7: ADD #10,P ;FLUSH ARGS
|
||
JMP EMAPR1 ;AND RETURN
|
||
.STITL FILE ACCESS CAPABILITY ROUTINES, CREATE FA CAP
|
||
CCPRFA: JSR PC,GETWRD ;GET THE FLAG WORD FROM THE USER
|
||
BIT #.FARUT,A ;DOES HE WANT A ROOT DIR?
|
||
BNE CCFA.1 ;GO TRY FOR THAT
|
||
MOV A,C
|
||
MOV #0,D ;FOR NOW, ALL TEMP FILES ON DISK 0
|
||
JSR PC,CRDMFL ;CREATE A DUMMY MFI
|
||
MOV #MFDWDB!MFTMPF,MFLAGW(C) ;SAY IT IS DELETE WHEN DONE AND TEMPORARY
|
||
MOV #MFFILE!MFEOFB+<MFNAME-MFENHD+1>,MFENHD(C) ;SAY IT IS A FILE WITH NO BLOCK AT THE EOF, TIME AND DATE EXIST, DUMMY LENGTH
|
||
JSR PC,MFFEND ;SET UP VARIOUS WORDS
|
||
JSR PC,LSWPOP ;WON'T GET PCLOSERED
|
||
MOV A,B ;COPY ITEM POINTER
|
||
MOV #.FAEOF!.FARD!.FAWT!.FAAP!.FAAC!.FACAP,A ;GIVE HIM ALL PERRMISSIONS
|
||
CLR C
|
||
CLZ
|
||
RTS PC
|
||
|
||
;COME HERE TO CREATE A ROOT DIRECTORY
|
||
CCFA.1: BIC #177701,A ;WHCIHC DISK DOES HE WANT?
|
||
CMP #NDISKS*2,A ;BIGGER THAN BIGGEST DISK?
|
||
ERRORC LE,BAD ;THIS USED TO CRASH THE SYSTEM
|
||
TST MFBLNK(A) ;THAT ONE ALREADY EXIST?
|
||
ERRORC NE,BAD ;YES, BAD DISK
|
||
MOV A,D ;COPY DISK NUMBER
|
||
JSR PC,CRDMFL ;GET A MFI
|
||
MOV #MFOPNB!.FADIR!.FARUT,MFLAGW(C) ;NOT DONE OPENING, DIRECTORY, ROOT DIRECTORY, WRITE TO SOURCE
|
||
MOV #MFDIRE!MFLSTB!MFEOFB+<MFNAME-MFENHD+2>,MFENHD(C) ;DIRECTORY, EOF POINTS TO EXISTING BLOCK, TIME AND DATE EXIST, LENGTH OF DUMMY
|
||
MOVB #46,MFNAME+1(C) ;SKIP 46 (GETS YOU TO THE ROOT)
|
||
JSR PC,DIRENT ;THIS CONVERTS THE DUMMY MFI TO THE REAL THING
|
||
JSR PC,MFFEND ;SET STUFF UP
|
||
JSR PC,LSWPOP
|
||
MOV A,B ;COPY ITEM NUMBER
|
||
MOV #.FADIR!.FARD!.FAAP!.FAAC!.FACAP,A ;MOST PRIVILIGES, BUT NOT WRITE
|
||
CLR C
|
||
CLZ
|
||
RTS PC
|
||
|
||
;CREATE A DUMMY MFI FOR TEMP FILES AND ROOT DIRECTORIES
|
||
CRDMFL: JSR PC,CRMFI ;GET AN MFI
|
||
ERRORC EQ,NIS ;NO ITEM SPACE AVAILABLE FOR IT
|
||
MOV ITM2A,C ;POINT TO THE NEW MFI
|
||
MOV #377,MFNAME(C) ;NAME IS RUBOUT
|
||
MOV D,MFDISK(C) ;SET THE DISK # IN TH EMFI
|
||
MOV MFBLNK(D),MFDLNK(C) ;LINK THE NEW MFI
|
||
MOV A,MFBLNK(D) ;INTO THE LIST FOR THIS DISK
|
||
RTS PC
|
||
.SBTTL FILE CAPABILITY ROUTINES- RANDOM INVOKES
|
||
CAPRFA: REST <B,E,F>
|
||
MOV A,D ;OTHER PEOPLE EXPECT THIS HERE
|
||
SWAB B
|
||
BIC #177401,B
|
||
CMP B,#MFAHGH
|
||
LBR GT,CAPRC2
|
||
JMP @FATAB(B)
|
||
|
||
MFARE: MOV FAMFI(D),A ;RETURN EOF POINTER
|
||
JSR PC,ITM2LD
|
||
MOV MFPGNO(A),E
|
||
CLR F
|
||
ASHC #-3,E
|
||
ADD MFBYTP(A),F
|
||
MOV F,B
|
||
JSR PC,GIVPSW
|
||
MOV E,B
|
||
JSR PC,GIVPSW
|
||
BR MFARTN
|
||
|
||
MFACF: BIC #<-.FARD-.FAWT-.FAAP-.FAAC>-1,E ;CLEAR ACESS FLAGS
|
||
BIC E,(D)
|
||
BR MFARTN
|
||
|
||
MFASP: MOV F,FAFBP(D) ;SET FILE POINTER
|
||
BIC #160000,FAFBP(D)
|
||
ASHC #3,E
|
||
MOV E,FAFPN(D)
|
||
BIS #.FAEOF,(D) ;FORCE EOF CHECK
|
||
BR MFARTN
|
||
|
||
MFARP: MOV FAFPN(D),A ;RETURN POINTER
|
||
CLR B
|
||
ASHC #-3,A
|
||
ADD FAFBP(D),B
|
||
JSR PC,GIVPSW
|
||
MOV A,B
|
||
JSR PC,GIVPSW
|
||
MFARTN: JMP ERETCZ
|
||
|
||
;RETURN INFO ABOUT THE DISK A FILE IS ON
|
||
MFADI: MOV FAMFI(D),A ;GET THE MFI
|
||
JSR PC,ITM2LD ;LOAD IT UP
|
||
MOV MFDISK(A),C ;THE DISK NUMBER
|
||
MOV C,B ;THE DISK NUMBER
|
||
ASR B ;2=>1
|
||
JSR PC,GIVPSW ;BACK TO THE USER
|
||
MOV MFFREE(C),B ;NUMBER OF FREE BLOCKS
|
||
JSR PC,GIVPSW
|
||
BR MFARTN
|
||
|
||
;SET UP BIT TABLE FOR THE DISK THE BIT TABLE FILE IS ON
|
||
MFAMB: MOV FAMFI(D),A ;GET THE MFI
|
||
JSR PC,ITM2LD ;LOAD IT UP
|
||
MOV MFDISK(A),D ;GET DISK NUMBER
|
||
MOV MFBYTP(A),F ;GET LENGHT IN BYTES
|
||
DEC F ;MAKE 2000=1777
|
||
ASH #-10.,F ;CONVERT TO BLOCKS
|
||
CLR E ;START AT 0
|
||
CLR C ;ON PAGE ZERO
|
||
MOV ITEM2,A ;GET MFI AGAIN
|
||
JSR PC,MAKFPG ;MAKE A FUPT FOR THE BIT TABLE
|
||
BUGC EQ ;FAILED?
|
||
MOV C,A ;COPY THE UPT POINTER
|
||
JSR PC,ITM2LD ;LOAD THE BIT TABLE
|
||
MOV (A)+,B ;NUMBER OF BLOCKS ON EMPTY DISK
|
||
CLR MFFREE(D) ;NUMBER OF FREE BLOCKS
|
||
MOV C,MFBITS(D) ;SAVE MFI OF BIT TABLE
|
||
BIC #GIPBIT,C ;MAKE INTO FUPT ADDRESS
|
||
MOV UPTPBP(C),E ;GET PB POINT
|
||
BIS #PBNOSW!PBWCHK,(E) ;NEVER ASSIGN SWAP SPACE TO BIT TABLES AND WRITE-CHECK THEM
|
||
MFAMB1: MOV #16.,C ;NUMBER OF BITS/WORD
|
||
MOV (A)+,E ;GET A WORD OF BITS
|
||
MFAMB2: ROR E ;GET A BIT TO TEST
|
||
BCS 1$ ;NOT FREE
|
||
INC MFFREE(D) ;ONE MORE FREE
|
||
1$: DEC B ;PAST TOTAL BLOCKS?
|
||
BEQ MFAMB3 ;YUP
|
||
SOB C,MFAMB2 ;DO WHOLE WORD
|
||
BR MFAMB1 ;DO NEXT WORD
|
||
MFAMB3: JSR PC,LSWPOP
|
||
JMP ERETCZ ;RETURN
|
||
|
||
.SBTTL FILE ACCESS CAP ROUTINES-MUTATE
|
||
|
||
MFAMU: JSR PC,FAUPDL ;DELETE ANY UPT (IN CASE HE DID INPUT ON DIRECTORY)
|
||
CLR FAFBP(D) ;CLEAR THE FILE POINTER
|
||
CLR FAFPN(D)
|
||
JSR PC,MAKFNB ;MAKE UP A FILE NAME BLOCK
|
||
BNE MFAMU1 ;JSUT RETURN IF NOTHING THERE
|
||
JMP ERETCZ
|
||
MFAMU1: SAVE A ;SAVE POINTER TO THE NEW FNB
|
||
MOV FAMFI(D),A ;GET POINTER TO MFI
|
||
JSR PC,ITM2LD
|
||
BIT #.FADIR,MFLAGW(A) ;IS IT A DIRECTORY?
|
||
ERRORC EQ,BAC ;BAD CAPABILITY
|
||
MOV MFDISK(A),E ;THE DISK NUMBER
|
||
JSR PC,CRMFI ;CREATE AN MFI IN CASE WE NEED IT
|
||
ERRORC EQ,NIS ;NO ITEM SAPCE AVAILABLE
|
||
SAVE A ;SAVE POINTER TO THE NEW MFI
|
||
MOV ITM2A,C ;POINTER INTO MFI
|
||
MOV E,MFDISK(C) ;THE DISK NUMBER
|
||
MOV MFBLNK(E),MFDLNK(C) ;PUT THE NEW MFI
|
||
MOV A,MFBLNK(E) ;ONTO THE LIST FOR THIS DISK
|
||
MOV FAMFI(D),A ;GET BACK THE MFI
|
||
JSR PC,ITM2LD
|
||
MOV ITEM2,A ;POINTER TO THE MFI
|
||
MOV 2(P),B ;GET BACK POINTER TO THE FNB
|
||
JSR PC,DIRSER ;LOOK THE THING UP IN THE DIRECTORY
|
||
ERRORC EQ,FNF ;FILE NOT FOUND IN DIR
|
||
SAVE B ;SAVE POINTER INTO DIRECTORY
|
||
MOV 4(P),A ;POINTER TO THE FNB IN A
|
||
SAVE FNBFNO(A) ;GET NUMBER IN DIR, AS DETERMINED BY DIRSER
|
||
MOV FAMFI(D),B ;POINTER TO DIRECTORY
|
||
MOV C,FNBVER(A) ;SAVE AWAY THE EXACT VERSION NUMBER
|
||
JSR PC,MFISER ;SEARCH TROUGH THE MFIS FOR EXACT MATCH
|
||
;NOTE THAT THE DISK NUMBER IS STILL IN E...
|
||
BEQ MFAMU2 ;NONE FOUND, MUST CREATE NEW MFI
|
||
REST <E,B> ;GET BACK USELESS POINTER
|
||
MOV A,(P) ;SAVE INDEX OF PROPER MFI
|
||
JSR PC,ITM2LD ;LOAD UP THE MFI WE FOUND TO BE THE RIGHT THING
|
||
CMP E,MFIFNO(A) ;IS NUMBER IN DIR THE SAME?
|
||
BUGC NE ;UGH!
|
||
INC MFFREF(A) ;THERE IS ONE MORE CAP TO IT
|
||
JSR PC,LSWPOP ;DON'T NEED TO LOCK DIR ANY MORE
|
||
JSR PC,FRELSE ;FREE UP THE UNNEEDED MFI
|
||
BR MFAMU3 ;GO DO THE COMMON STUFF
|
||
|
||
MFAMU2: REST <E,B> ;GET BACK POINTER INTO DIR
|
||
SAVE D ;SAVE POINTER TO CAP
|
||
MOV (B),D ;GET HEADER WORD FROM DIR
|
||
MOV 2(P),A ;GET INDEX OF THE MFI
|
||
JSR PC,MFIEXP ;SEE IF MFI NEEDS EXPANDING
|
||
MOV E,MFIFNO(A) ;THE FILE NUMBER IN DIR, OBTAINED ABOVE
|
||
ADD #MFENHD,A ;POINT TO THE ENTRY PART OF THE MFI
|
||
ASR D ;CHANGE TO A COUNT
|
||
1$: MOV (B)+,(A)+ ;COPY FROM DIR
|
||
SOB D,1$
|
||
JSR PC,ITM1PO ;FLUSH MFI FROM THERE
|
||
MOV 2(P),A ;THE MFI AGAIN....
|
||
JSR PC,ITM2LD
|
||
MOV MFENHD(A),F ;GET HEADER WORD AGAIN
|
||
REST D
|
||
MOV FAMFI(D),MFBAKP(A) ;POINT AT PARENT
|
||
BIC #170777,F ;GET THE TYPE OF THE NEW ENTRY
|
||
CMP #MFDIRE,F ;IS IT A DIRECTORY?
|
||
BNE MFAMU4 ;NOPE, WE CAN RELAX
|
||
MOV (P),A ;GET THE MFI INDEX BACK
|
||
JSR PC,DIRENT ;GO DO THE MAGIC FOR THE DIRECTORY
|
||
|
||
MFAMU4: MOV (P),A ;MFI AGAIN
|
||
JSR PC,ITM2LD
|
||
JSR PC,MFFEND ;SET UP END POINTERS
|
||
BIC #MFOPNB,MFLAGW(A) ;OPEN NOW
|
||
JSR PC,LSWPOP ;FLUSH LOCK ON DIRECTROY
|
||
JSR PC,LSWPOP ;LOCK LOCK ON MFI WITHOUT DELETEING IT
|
||
MFAMU3: REST FAMFI(D) ;PUT INDEX OF PROPER MFI INTO CAP
|
||
MOV ITM2A,A ;POINTER TO MFI
|
||
BIT #.FADIR,MFLAGW(A)
|
||
BEQ 1$ ;NO, MUST BE A FILE
|
||
BIC #.FAWT,(D) ;MUSN'T WRITE ON DIR!
|
||
BR 2$
|
||
1$: BIC #.FADIR,(D) ;THIS IS NOT A DIR
|
||
BIS #.FAWT,(D) ;BUT YOU CAN WRITE ON IT
|
||
2$: CLR FAFPN(D) ;RESET POINTER
|
||
CLR FAFBP(D) ;TO BEGGINING OF FILE
|
||
BIS #.FAEOF,(D) ;SAY THAT WE ARE IN THE EOF BLOCK (EVEN THOUGH IT MIGHT NOT BE TRUE)
|
||
REST A ;GET BACK POINTER TO FNB
|
||
MOV FNBFNE(A),E ;GET WHAT USER'S POINTER SHOULD GET CLOBBERED TO
|
||
MOV ITM0A,A ;POINT TO OUR PROCESS BLOCK
|
||
MOV PUP(A),C ;USER'S PDL POINTER
|
||
ADD #2,C ;WANT TO CLOBBER HIS SECOND ARGUMENT
|
||
SAVE E ;TO SEND TO THE USER
|
||
MTPD (C) ;GIVE IT BACK TO HIM
|
||
JSR PC,LSWPOP ;FLUSH FNB
|
||
JMP MFAMU ;NOW GO AROUND AGAIN FOR THE NEXT NAME
|
||
;RETURN A BLOCK OF DATA ABOUT THE FILE THIS IS A CAPABILITY TO
|
||
;(F)= POINTS TO DESTINATION OF DATA
|
||
;(E)= NEGATIVE OF THE MAXIMUM NUMBER OF BYTES TO GIVE USER
|
||
|
||
MFARI: TST E ;IS IT NEGATIVE
|
||
BPL 1$
|
||
NEG E ;MAKE IT POSITIVE
|
||
1$: ASR E ;WE ONLY GIVE USER WORDS
|
||
BNE MFARI9
|
||
MOV #400,E ;GIVE HIM ALL THERE IS
|
||
MFARI9: SAVE (D) ;CAP. FLAGS
|
||
MTPD (F)+ ;GIVE USER FLAGS
|
||
MOV FAMFI(D),A
|
||
JSR PC,ITM2LD ;LOAD UP MFI
|
||
DEC E ;WORD COUNT
|
||
BEQ MFARI6
|
||
SAVE MFLAGW(A)
|
||
MTPD (F)+
|
||
ADD #MFENHD,A ;NOW POINTS TO ENTRY IN MFI
|
||
MOV 6(A),B ;EOF BYTE POINTER
|
||
ADD #1777,B ;ROUND IT UP
|
||
BIT #MFLSTB,(A) ;DOES THE LAST BLOCK EXIST
|
||
BEQ 1$
|
||
INC B ;CATCH TRICKY BOUNDARY PROBLEM
|
||
1$: BIC #1777,B
|
||
MOV 4(A),C ;EOF PAGE NUMBER
|
||
ASH #3,C ;BLOCK COUNT NOW
|
||
ADD C,B
|
||
DEC E ;WORD OCUNT
|
||
BEQ MFARI6
|
||
SAVE B ;LEGNTH OF FILE IN BLOCKS
|
||
MTPD (F)+
|
||
DEC E ;WORD OCUNT
|
||
BEQ MFARI6
|
||
SAVE 10(A) ;DATE
|
||
MTPD (F)+
|
||
DEC E ;WORD OCUNT
|
||
BEQ MFARI6
|
||
SAVE 12(A)
|
||
MTPD (F)+
|
||
JSR PC,MFNDNM ;MAKE A POINT TO NAME
|
||
CLR C
|
||
CLR B ;END OF NAME FLAG
|
||
SAVE #MFSENB ;SET UP CO-ROUTINE LINKAGE
|
||
MFARI1: BISB (A),C
|
||
TSTB (A)+
|
||
BGE MFARI2
|
||
BIC #200,C ;CLEAR HIGH BIT
|
||
INC B ;SET DONE FLAG
|
||
|
||
;FALLS INTO NEXT PAGE
|
||
;FALLS IN FROM ABOVE
|
||
|
||
MFARI2: JSR PC,@(P)+ ;GIVE HIM A BYTE
|
||
TST B
|
||
BEQ MFARI1 ;STILL MORE NAME
|
||
MOV ITM2A,A ;POINTER TO MFI
|
||
MOV MFVERN(A),B ;VERSION NUMBER
|
||
BLT MFARI8 ;NONE, DONE
|
||
BISB #'#,C ;INDICATE VERSION NUMBER
|
||
JSR PC,@(P)+ ;PASS TO USER
|
||
MOV #DECTAB,D ;POINTER TO TABLE OF NUMBERS
|
||
1$: CMP B,(D)+ ;IS NUMBER THIS BIG?
|
||
BGT 1$ ;NO, SUPRESS LEADING ZERO
|
||
TST -(D) ;WHAT WAS THAT AGAIN?
|
||
2$: CLR A ;CLEAR HIGH PART
|
||
DIV (D)+,A ;DIVIDE BY THIS POWER OF TEN
|
||
BISB A,C ;THE RESULT
|
||
ADD #60,C ;CONVERT TO DIGIT
|
||
JSR PC,@(P)+ ;PASS TO USER
|
||
TST (D) ;PAST END?
|
||
BNE 2$
|
||
MFARI8: JSR PC,@(P)+ ;ONE ZERO
|
||
JSR PC,@(P)+ ;MAKE SURE PASSED TO USER
|
||
TST (P)+
|
||
JMP ERETCZ ;RETURN
|
||
MFARI7: TST (P)+ ;POP CO-ROUTINE LINKAGE
|
||
MFARI6: CCC
|
||
SEV
|
||
JMP EMTRET
|
||
;CO-ROUTINE TO PUT BYTES INTO USER'S SPACE
|
||
MFSENB: SWAB C
|
||
JSR PC,@(P)+ ;THIS IS A CO-ROUTINE
|
||
SWAB C
|
||
DEC E ;WORD OCUNT
|
||
BEQ MFARI7
|
||
SAVE C
|
||
MTPD (F)+
|
||
CLR C
|
||
JSR PC,@(P)+ ;RETURN FROM CO-ROUTINE
|
||
BR MFSENB
|
||
MFNDNM: SAVE B ;(A)= POINTER TO ENTRY
|
||
MOV (A)+,B ;HEADER WORD
|
||
TST (A)+ ;SKIP VERSION NUMBER
|
||
BIT #MFEOFB,B ;TIEM DATE, EOF ETC?
|
||
BEQ 1$ ;NOPE
|
||
ADD #10,A ;SKIP EOF DATE AND TIME
|
||
1$: BIT #MFACCB,B ;ACCESS CODES?
|
||
BEQ MFND.2
|
||
MFND.1: ADD #2,A ;SKIP ACCESS CODES
|
||
TSTB (A)+
|
||
BLT MFND.1 ;MORE ACCESS CODES?
|
||
MFND.2: REST B
|
||
RTS PC ;DONE
|
||
.SBTTL DELETE FROM DIRECTORY
|
||
;COMMON BEGINNING FOR DELETE AND SUPER DELETE
|
||
MFACDL: MOV FAMFI(D),A ;GET THE FILE OR DIR MFI TO DELETE
|
||
JSR PC,ITM2LD ;LOAD IT
|
||
MOV MFBAKP(A),A ;GET DIR IT IS IN
|
||
JSR PC,ITM2LD ;LOAD IT
|
||
MOV MFIUPT(A),B ;FUPT FOR THE DIR ITSELF
|
||
JSR PC,FUPTLK ;LOCK THE DIR
|
||
MOV B,A
|
||
JSR PC,ITM2PL ;LOAD THE ACTUAL DIR
|
||
TST (A) ;MAKE SURE IT IS IN CORE
|
||
MOV FAMFI(D),A ;GET THE FILE OR DIR MFI TO DELETE
|
||
JSR PC,ITM2PL ;LOAD IT
|
||
BIT #MFOPNB!MFDWDB!MFTMPF,MFLAGW(A) ;ALREADY SORT OF GONE?
|
||
ERRORC NE,FNF ;WELL, NOT IN DIRECTORY ANYWAY
|
||
RTS PC
|
||
|
||
;SUPER DELETE, DELETE A DIR EVEN IF IT ISN'T EMPTY
|
||
MFASDL: JSR PC,MFACDL ;DO COMMON STUFF
|
||
BIT #.FADIR,MFLAGW(A) ;IS IT A DIR?
|
||
ERRORC EQ,BAD ;SUPER DELETE ISN'T NEEDED, SLAP HIS WRIST
|
||
CMP #1,MFFREF(A) ;IS THERE A FILE OPEN IN THIS DIR?
|
||
ERRORC NE,CDD ;DANGEROUS TO DELETE IF MORE THAN ONE CAP
|
||
BR MFADL2 ;GO DELETE IT, WHATEVER IT IS
|
||
|
||
;REGULAR DELETE
|
||
MFADL: JSR PC,MFACDL ;DO COMMON START
|
||
BIT #.FADIR,MFLAGW(A) ;IS IT A DIR?
|
||
BEQ MFADL2 ;IF A FILE, DON'T NEED EXTRA CHECKING
|
||
|
||
;CHECK THAT DIR IS EMPTY
|
||
MOV MFIUPT(A),B ;THE FUPT FOR THE ACTUAL DIR
|
||
JSR PC,FUPTLK ;MINE, ALL MINE!
|
||
MOV MFBYTP(A),C ;THE DIR'S EOF
|
||
MOV B,A
|
||
JSR PC,ITM2PL ;LOAD THE DIR
|
||
MOV #2,D ;DO TWICE
|
||
MFADL1: MOV (A),B ;GET HEADER WORD
|
||
INC B ;IN CASE COUNT IS ODD
|
||
BIC #177401,B ;EVEN IT
|
||
ADD B,A
|
||
SOB D,MFADL1
|
||
SUB ITM2A,A ;UNREALATIVE
|
||
CMP A,C ;SAME AS EOF?
|
||
ERRORC NE,CDD ;CAN'T DELETE DIRECTORY THAT ISN'T EMPTY
|
||
JSR PC,LSWPOP ;NON LONGER LOCKED
|
||
JSR PC,ITM2PO ;OR LOADED
|
||
MOV ITM2A,A ;RESTORE A
|
||
;FALLS THROUGH
|
||
;FALLS IN
|
||
MFADL2: BIS #MFDWDB,MFLAGW(A) ;DELETE BLOCKS WHEN MFI GOES AWAY
|
||
MOV MFIFNO(A),C ;FILE NUMBER BEFORE GETTING HACKED
|
||
MOV #-1,F ;ONE LESS FILE IN DIR
|
||
JSR PC,MFIUND ;ADJUST ANY ACTIVE MFIS ABOVE THIS FILE
|
||
JSR PC,ITM2PO ;POP TO ACTUAL DIRICTORY
|
||
MOV ITM2A,A ;POINT TO BEGINNING OF IT
|
||
MFADL3: MOV (A),B ;GET HEADER WORD OF ENTRY
|
||
INC B ;IN CASE ODD
|
||
BIC #177401,B ;EVEN IT OUT
|
||
ADD B,A ;POINT TO NEXT ENTRY
|
||
SOB C,MFADL3 ;TILL WE GET TO THE ONE WE'RE INTERESTED IN
|
||
MOV (A),F ;GET HEADER WORD
|
||
INC F ;IN CASE ODD
|
||
BIC #177401,F ;MAKE EVEN
|
||
MOV ITM2A,C ;POINT AT BEG OF DIR AGAIN
|
||
SUB F,MFBYTP-MFENHD(C) ;ADJUST EOF POINTER IN DIR
|
||
MOV A,B ;COPY POINTER TO ENTRY BEING FLUSHED
|
||
ADD F,B ;POINT TO BEG OF NEXT ENTRY
|
||
MOV ITM2A,C ;POINT TO BEGINNING
|
||
ADD MFBYTP-MFENHD(C),C ;POINT TO NEW END
|
||
MFADL4: CMP C,A ;ARE WE ABOUT TO COPY PAST THE END?
|
||
BEQ MFADL5 ;YUP
|
||
MOV (B)+,(A)+ ;COPY NE WORD
|
||
BR MFADL4
|
||
MFADL5: MOV ITEM2,B ;GIP TO THE DIR
|
||
JSR PC,ITM2PO ;MAP IT OUT
|
||
JSR PC,VALSRC ;ENTER REQUEST TO WRIT IT OUT
|
||
MOV ITM2A,A ;POINTER TO PARENT MFI
|
||
SUB F,MFBYTP(A) ;ADJUST EOF
|
||
ADD F,MFIUCF(A) ;AND FREE BYTES
|
||
JSR PC,LSWPOP
|
||
JMP ERETCZ
|
||
;DELETE THE BLOCKS BELONGING TO THE FILE WHOSE MFI IS IN ITEM2 AND DISK # IS IN D
|
||
MFIBFL: JSR F,ACSAV
|
||
MOV MFBITS(D),A ;GET THE RIGHT BIT TABLE
|
||
JSR PC,ITM2PL ;LOAD IT UP
|
||
TST (A) ;MAKE SURE IT IS SWAPPED IN
|
||
JSR PC,ITM2PO ;POP IT
|
||
MOV MFBITS(D),A ;GET AGAIN
|
||
JSR PC,ITM1PL ;THIS TIME INTO ITEM 1
|
||
MOV ITM2A,B ;POINTER INTO MFI
|
||
MOV MFBYTP(B),E ;EOF BYTE POINTER
|
||
ASH #-10.,E ;MAKE INTO BLOCK COUNT
|
||
INC E ;JUST FOR GOOD MEASURE
|
||
MOV MFPGNO(B),C ;GET PAGE EOF
|
||
ASH #3,C ;CONVERT TO BLOCKS
|
||
ADD E,C ;LAST BLOCK ADDRESS
|
||
MOV D,B ;SAVE DISK #
|
||
INC C ;FOR GOOD MEASURE
|
||
JSR PC,MFBLKG ;START STAREING AT BLOCKS
|
||
MFIBF1: CMP #-1,E ;REALLY THER?
|
||
BEQ MFIBF2 ;NO, IGNORE THIS ONE
|
||
CMP E,(A) ;BIGGER THAN BIGGEST?
|
||
BUGC HIS ;I HOPE NOT!
|
||
TST E ;ZERO?
|
||
BUGC EQ
|
||
SAVE E
|
||
MOV E,F ;COPY BLOCK NUMBER
|
||
BIC #177770,F ;GET BIT NUMBER
|
||
ASH #-3,E ;AND BYTE NUMBER
|
||
ADD A,E ;BYTE POINTER
|
||
BICB BMT(F),2(E) ;TABLE IS OFFSET BY 2
|
||
INC MFFREE(B) ;ONE MORE BLOCK FREE
|
||
REST E
|
||
MFIBF2: JSR PC,@(P)+ ;GET NEXT BLOCK
|
||
CMP D,C ;THIS THE LAST BLOCK?
|
||
BLOS MFIBF1 ;NO, KEEP GOING
|
||
TST (P)+ ;FLUSH LINKAGE
|
||
JSR PC,ITM1PO ;FLUSH BIT TABLE
|
||
MOV MFBITS(B),B ;GET THE GIP AGAIN
|
||
JSR PC,VALSRC ;SWAP TABLE OUT
|
||
JMP ACRET
|
||
;ADD A FILE OR DIR TO A DIR, AND MUTATE TO THAT DIR OR FILE
|
||
MFAAD: JSR PC,MAKFNB ;GET THE FILE NAME
|
||
ERRORC EQ,BFN ;NO FILE NAME???
|
||
CMP #-3,FNBVER(A) ;FOO< ?
|
||
ERRORC EQ,BFN ;CAN'T CREATE THAT
|
||
SAVE A ;SAVE POINTER TO THE FNB
|
||
MOV FAMFI(D),A ;GET THE DIR MFI
|
||
JSR PC,ITM2LD ;LOAD IT
|
||
BIT #.FADIR,MFLAGW(A) ;IT BETTER BE A DIR!
|
||
ERRORC EQ,BCT ;CAN'T INSERT INTO FILES!
|
||
BIT #MFDWDB,MFLAGW(A) ;STILL A VIABLE DIR?
|
||
ERRORC NE,BCT ;WELL, SORT OF
|
||
MOV MFDISK(A),E ;THE DISK THIS IS ON
|
||
JSR PC,CRMFI ;CREATE A MFI FOR THE ENTRY
|
||
ERRORC EQ,NIS ;NO ROOM
|
||
MOV ITM2A,C ;POINTER INTO MFI
|
||
MOV E,MFDISK(C) ;THE DISK NUMBER
|
||
MOV MFBLNK(E),MFDLNK(C) ;PUT THE NEW MFI
|
||
MOV A,MFBLNK(E) ;ONTO THE LIST FOR THIS DISK
|
||
MOV (P),F ;GET FNB POINTER
|
||
SAVE <A,D> ;SAVE MFI INDEX AND CAP POINTER
|
||
MOV FNBFNL(F),D ;GET NUMBER OF BYTES IN THE NAME
|
||
ADD #MFNAME-MFENHD,D ;ADD IN OVERHEAD IF FILE
|
||
SAVE D ;SAVE COMPUTED LENGTH
|
||
JSR PC,MFIEXP ;EXPAND IF NESSECARY
|
||
JSR PC,ITM1PO ;CRETINOUS MFIEXP PUSHES IT
|
||
REST <E,D> ;GET BACK COUNT, CAP POINTER
|
||
MOV FAMFI(D),A ;GET DIR MFI AGAIN
|
||
SAVE E ;SAVE REAL COUNT
|
||
INC E ;WE NEED TO
|
||
BIC #1,E ;EVEN THIS ONE OFF
|
||
JSR PC,DIRCMT ;COMMIT BYTES IN DIR
|
||
MOV FAMFI(D),A ;THE MFI WE HAVE A PSUEDO INFERIOR TO
|
||
JSR PC,ITM2PL ;LOAD IT
|
||
INC MFFREF(A) ;ONE MORE REF
|
||
JSR PC,ITM2PO ;POP IT
|
||
MOV ITM2A,A ;ADDRESS OF MFI WE ARE WORKING ON
|
||
MOV E,MFICBY(A) ;WE HAVE THIS MANY COMMITED FOR US
|
||
MOV FAMFI(D),MFBAKP(A) ;SET HIS BACK POINTER
|
||
REST E ;GET BACK REAL COUNT
|
||
BIS #MFFILE!MFEOFB,E ;LENGTH, ASSUMMED FILE
|
||
MOV E,MFENHD(A) ;HEADER WORD
|
||
;VERN WILL BE INSERTED WHEN WE KNOW IT
|
||
;EOF POINTER IS ALREADY 0
|
||
JSR PC,CMDATE ;GO COMPUTE DATE AND TIME
|
||
MOV FDATE,MFDATE(A) ;DATE
|
||
MOV FTIME,MFTIME(A) ;TIME
|
||
ADD #FNBFN,F ;POINT TO NAME IN FNB
|
||
ADD #MFNAME,A ;AND IN MFI
|
||
1$: MOVB (F)+,(A)+ ;ON BYTE AT A TIME
|
||
BGE 1$ ;TILL END SEEN
|
||
|
||
MOV FAMFI(D),A ;MFI OF DIR
|
||
JSR PC,ITM2LD ;FOR DIRSER
|
||
MOV FAMFI(D),A ;ALSO
|
||
MOV 2(P),B ;FNB POINTER
|
||
JSR PC,DIRSER ;LOOK FOR FILE IN DIR
|
||
BEQ MFAAD2 ;NOT THERE, THAT'S FINE
|
||
MOV 2(P),B ;FNB POINTER AGAIN
|
||
CMP #-2,FNBVER(B) ;ARE WE ADDING >?
|
||
ERRORC NE,EAE ;NO, FILE ALREADY EXISTS
|
||
INC C ;NEXT VERSION NUMBER
|
||
INC FNBFNO(B) ;GO TO NEXT SPOT IN DIR
|
||
BR MFAAD3 ;ADD THAT ONE
|
||
MFAAD2: MOV 2(P),B ;FNB AGAIN
|
||
MOV FNBVER(B),C ;SPECIFIED VERSION NUMBER
|
||
CMP #-2,C ;ARE WE ADDING >?
|
||
BNE MFAAD3
|
||
INC FNBFNO(B) ;GO TO NEXT SPOT
|
||
MOV #1,C ;VERSION NUMBER 1
|
||
MFAAD3: REST A ;GET BACK NEW MFI INDEX
|
||
JSR PC,ITM2LD ;LOAD IT UP
|
||
MOV C,MFVERN(A) ;GIVE IT THE CORRECT VERSION NUMBER
|
||
MOV FNBFNO(B),MFIFNO(A) ;AND FILE NUMBER
|
||
BIS #MFEBMB!MFNODR,MFLAGW(A) ;BEEN MODIFIED AND NOT YET IN DIR
|
||
MOV #1,F ;ADDING A FILE
|
||
JSR PC,MFIUND ;ADJUST OTHER FILES IN THE DIR
|
||
DEC MFIFNO(A) ;DON'T WANT JUST ADDED ENTRY ADJUSTED
|
||
JSR PC,MFFEND ;SET UP THE END POINTERS
|
||
JSR PC,LSWPOP ;POP LOCK ON DIR, MFIINS WILL RELOCK
|
||
JSR PC,MFIINS ;PUT IT INTO DIR
|
||
MOV FAMFI(D),A ;THE ABOUT TO BE SUPERIOR
|
||
JSR PC,ITM2PL ;LOAD IT
|
||
DEC MFFREF(A) ;NO EXTRA REFERENC ENOW
|
||
JSR PC,ITM2PO
|
||
MOV ITM2A,A
|
||
MOV ITEM2,FAMFI(D) ;MUTATE CAP
|
||
CLR FAFBP(D) ;CLEAR POINTER
|
||
CLR FAFPN(D)
|
||
BIT #.FADIR,MFLAGW(A) ;IS IT A DIR?
|
||
BNE 1$ ;YES, DON'T DO ANYTHING
|
||
BIS #.FAWT,(D) ;YOU CAN WRITE ON THE FILE YOU CREATED
|
||
BIC #.FADIR,(D) ;NO, MAKE CAP A FILE TOO
|
||
1$: BIC #MFOPNB,MFLAGW(A) ;NO LONGER BEING OPENED
|
||
TST (P)+ ;FLUSH FNB POINTER
|
||
JSR PC,LSWPOP ;DIR LOCK
|
||
JSR PC,LSWPOP ;MFI LOCK
|
||
JSR PC,LSWPOP ;FNB LOCK
|
||
JMP ERETCZ ;WIN
|
||
;COMMIT SPACE IN A DIR
|
||
;RESERVES (E) BYTES IN A DIR, GIVES ERROR IF NOT AVAILABLE
|
||
;SOMEDAY THIS WILL EXPAND THE DIR TO UP TO 8 BLOCKS
|
||
;CALL WITH DIR MFI IN A
|
||
DIRCMT: JSR F,ACSAV
|
||
JSR PC,ITM2PL ;LOAD THE DIR
|
||
INC E ;ALWAYS ALLOCATE
|
||
BIC #1,E ;AN EVEN NUMBER OF BYTES
|
||
CMP E,MFIUCF(A) ;DO THAT MANY UNCOMMITED FREE BYTES EXIST?
|
||
ERRORC HIS,DRF ;NOT ENOUGH, FULL DIR
|
||
SUB E,MFIUCF(A) ;COMMIT THAT MANY
|
||
JSR PC,ITM2PO ;POP DIR MFI
|
||
JMP ACRET
|
||
;CHANGE A FILE INTO A DIRECTORY
|
||
MFAMD: BIT #.FADIR,(D) ;IS IT ALREADY A DIR?
|
||
ERRORC NE,BAD ;YES!
|
||
MOV FAMFI(D),A ;THE MFI FOR THE FILE TO CONVERT
|
||
JSR PC,ITM2LD ;LOAD IT
|
||
MOV MFBAKP(A),A ;MFI OF PARENT DIR
|
||
ERRORC EQ,BAD ;UGH!
|
||
JSR PC,ITM2PL ;LAOD THAT
|
||
MOV MFIUPT(A),B ;GIP TO DIR
|
||
JSR PC,FUPTLK ;LOCK IT
|
||
MOV B,A
|
||
JSR PC,ITM2LD ;LOAD IT
|
||
TST (A) ;MAKE SURE IT'S SWAPPED IN
|
||
JSR PC,ITM2PO ;POP BACK TO FILE MFI
|
||
MOV ITM2A,A ;POINTER TO IT
|
||
TST MFPGNO(A) ;IS IT > 8 BLOCKS?
|
||
ERRORC NE,BAD ;YES, THAT'S A NO-NO
|
||
CMP #2000,MFBYTP(A) ;IS IT > 1 BLOCK?
|
||
ERRORC LT,BAD ;SO IS THAT
|
||
TST MFBYTP(A) ;BUT IS THERE SOMETHING THERE?
|
||
ERRORC EQ,BAD ;NOPE!
|
||
CLR FAFBP(D) ;SET FILE POINTER TO ZERO
|
||
MOV #2,C ;LIE A LITTLE
|
||
JSR PC,DKISET ;SET UP THE PAGE
|
||
MOV FAMFI(D),A ;GET THE MFI WE A FOOLING WITH
|
||
JSR PC,ITM1PL ;LOAD IT UP
|
||
MOV MFBAKP(A),B ;ITEM NUMBER OF PARENT
|
||
ERRORC EQ,BAD ;TEMP FILE?
|
||
CLR -(P) ;FOR TOTAL LENGTH
|
||
MOV #MFSLFE,F ;FOR THE SELF ENTRY
|
||
JSR PC,MFAMDC ;COPY ENTRY INTO DIR
|
||
MOV B,A ;THE PARENT OF THE NEW DIR
|
||
JSR PC,ITM1LD ;LOAD MFI OF PARENT
|
||
MOV E,B ;SAVE POINTER INTO DIR
|
||
MOV #MFPARE,F ;PARENT ENTRY
|
||
JSR PC,MFAMDC ;COPY PARENT INTO DIR
|
||
BIC #100000,(B) ;FLUSH THE EOF BIT
|
||
SUB #10,(B) ;FLUSH THE BYTES WE WILL FLUSH
|
||
MOV (B)+,E ;THE HEADER WORD
|
||
INC E
|
||
BIC #177401,E ;SAVE JUST COUNT
|
||
ASR E ;WORD COUNT
|
||
SUB #2,E ;HEADER+VERSION NUMBER
|
||
SUB #10,(P) ;ON THE STACK TOO
|
||
TST (B)+ ;PAST VERSION NUMBER
|
||
1$: MOV 10(B),(B)+
|
||
SOB E,1$
|
||
JSR PC,ITM1PO ;POP THE MFI
|
||
MOV ITM2A,A ;POINTER TO DIR
|
||
CLR 4(A) ;NUMBER OF REAL PAGES
|
||
MOV (P),6(A) ;NUMBER OF USED BYTES
|
||
JSR PC,ITM2PO ;GET RID OF PUSHED WHATEVER
|
||
MOV FAMFI(D),A ;THE MFI WE ARE HACKING
|
||
JSR PC,ITM2LD ;LOAD IT UP
|
||
MOV FAUPT(D),B ;UPT TO THE NEW DIR
|
||
JSR PC,VALSRC ;WRITE IT ON THE DISK
|
||
ADD #MFENHD,A ;POINT TO ENTYR IN MFI
|
||
MOV (A),B ;GET HEADER WORD
|
||
INC B
|
||
BIC #177401,B ;GET A BYTE COUNT
|
||
ASR B ;WORD
|
||
SUB #6,B ;LESS EOF+TIEM+DATE+HEADER+VERN
|
||
SAVE <A,B>
|
||
BIC #117000,(A) ;FLUSH TYPE AND EOF BIT
|
||
BIS #MFDIRE,(A) ;IT IS A DIR
|
||
SUB #10,(A)+ ;FLUSH 8. BYTES
|
||
TST (A)+ ;DON'T TOUCH VERN
|
||
MFAMD3: MOV 10(A),(A)+
|
||
SOB B,MFAMD3
|
||
JSR PC,LSWPOP
|
||
JSR PC,LSWPOP
|
||
JSR PC,MFIINS ;INSERT THIS INTO THE PARENT
|
||
REST <B,A>
|
||
ADD #10,(A) ;SET BACK THE LENGTH
|
||
BIS #100000,(A)+
|
||
TST (A)+ ;SKIP VERN
|
||
ADD B,A
|
||
ADD B,A ;GET TO THE END OF THE GOOD STUFF
|
||
MFAMD2: MOV -(A),10(A) ;COPY UP
|
||
SOB B,MFAMD2
|
||
MOV ITM2A,A
|
||
CLR MFPGNO(A)
|
||
REST MFBYTP(A) ;THE LENGHT OF THE DIR WAS COMPUTED A LONG TIME AGO
|
||
MOV FAUPT(D),MFIUPT(A)
|
||
CLR FAUPT(D)
|
||
CLR FAFBP(D)
|
||
CLR FAFPN(D)
|
||
BIS #.FADIR,(D) ;SAY THIS IS A DIR
|
||
BIC #.FAWT,(D) ;PREVENT WRITEING ON DIRS
|
||
BIS #.FADIR,MFLAGW(A) ;ALSO IN THE MFI
|
||
MOV #1,MFIDLN(A) ;ONE BLOCK LONG
|
||
MOV MFBYTP(A),C ;GET THE END OF THE DIRECTORY
|
||
NEG C
|
||
ADD #2000,C ;GET THE NUMBER OF FREE BYTES IN THIS DIRECTORY
|
||
MOV C,MFIUCF(A) ;THE NUMBER OF FREE BYTES IN THE DIRECTORY
|
||
JMP ERETCZ ;DONE???
|
||
|
||
MFAMDC: ADD #MFENHD,A ;POINT TO ENTRY ITSELF
|
||
MOV (A),C ;GET HEARER WORD
|
||
INC C ;ROUND UP
|
||
BIC #177401,C ;CLEAR CRAP
|
||
ADD C,2(P) ;SAVE LENGTH IN BYTES
|
||
ASR C ;FOR THE SOB
|
||
MOV (A)+,(E) ;COPY THIS INTO DIR
|
||
BIC #17000,(E) ;CLEAR OLD TYPE
|
||
BIS F,(E)+ ;CHANGE TO A SELF ENTRY
|
||
DEC C
|
||
MFAMD1: MOV (A)+,(E)+ ;A WORD AT A TIME
|
||
SOB C,MFAMD1
|
||
RTS PC
|
||
|
||
.SBTTL FILE CAPABILITIES-DIRECTORY HACKING
|
||
|
||
|
||
;SEARCH THE DIRECTORY POINTED TO BY THE MFI IN A FOR THE FILE POINTED
|
||
;TO BY THE FNB IN B
|
||
;RETURN IN A A POINTER TO WHERE WE SHOULD PUT A NEW FILE OF THIS NAME,
|
||
;AND IN B A POINTER TO THE "EXACT" MATCH IF ONE WAS FOUND.
|
||
;IF THE FNB HAS NO VERSION NUMBER OR A SPECIFIC VERSION NUMBER,
|
||
;THEN THE DIRECTORY ENTRY MUST HAVE THE SAME FOR AN EXACT MATCH
|
||
;IF THE FNB HAS < FOR A VERSION NUMBER, THE FIRST FILE
|
||
;WITH A VERSION NUMBER IS AN EXACT MATCH. IF THE FNB HAS
|
||
;> AS A VERSION NUMBER, THEN THE LAST FILE WITH THE RIGHT
|
||
;NAME AND A VERSION NUMBER IS AN EXACT MATCH. NOTE THAT
|
||
;> AND < NEVER EXACT MATCH TO A FILE WITH NO VERSION NUMBER,
|
||
;AND A FILE WITH NO VERSION NUMBER NEVER EXACT MATCHES A FILE
|
||
;WITH ONE
|
||
;THE VERSION NUMBER OF THE EXACT MATCH IS RETURNED IN C
|
||
;AND Z IS SET IF NO EXACT MATHC IS FOUND
|
||
;CALL WITH MFI LOADED INTO ITEM 2
|
||
;RETURNS WITH DIR LOADED INTO ITEM 2
|
||
DIRSER: JSR F,ACSAV
|
||
CLR 2(P) ;RETURNED B
|
||
MOV B,E ;COPY FNB POINTER
|
||
MOV #1,FNBFNO(E) ;FIRST FILE (WE SKIP THE SELF ENTRY)
|
||
MOV ITM2A,A ;POINTER TO MFI
|
||
MOV MFBYTP(A),F ;POINTER TO END OF DIRECTORY
|
||
MOV MFIUPT(A),B ;GIP FOR DIRECTORY
|
||
JSR PC,FUPTLK ;LOCK THE DIRECOTORY
|
||
MOV B,A ;COPY THE GIP
|
||
JSR PC,ITM2LD ;LOAD THE DIR OVER THE MFI
|
||
ADD A,F ;REAL END POINTER NOW
|
||
MOV (A),B ;FIRST WORD OF SELF ENTRY
|
||
INC B ;ROUND OFF BYTE COUNT
|
||
BIC #177401,B ;BYTE COUNT
|
||
ADD B,A ;SKIP SELF
|
||
;AND THEN SKIP THE PARENT ENTRY TOO
|
||
DIRSE1: INC FNBFNO(E) ;NEXT FILE
|
||
MOV (A),B ;GET FIRST WORD OF ENTRY
|
||
INC B ;ROUND OFF BYTE COUNT
|
||
BIC #177401,B ;GET BYTE COUNT
|
||
ADD B,A ;GO TO NEXT ENTRY
|
||
MOV A,(P) ;SAVE FOR CALLER
|
||
CMP A,F ;ARE WE AT OR PAST THE END?
|
||
BHIS DIRSE2 ;YUP, RETURN TO CALLER
|
||
JSR PC,NAMCMP ;COMPARE THE FILE NAMES
|
||
BGT DIRSE1 ;HAVEN'T GONE FAR ENOUGH YET
|
||
BLT DIRSE2 ;WE'VE GONE TOO FAR
|
||
MOV FNBVER(E),D ;MATCHED FILE NAMES, GET VERSION FROM FNB
|
||
INC D ;WAS IT NO VERSION?
|
||
BGE DIRSE4 ;YES, OR POSITIVE VERSION
|
||
CMP #-1,C ;NO VERSION ON THE DIR ENTRY?
|
||
BEQ DIRSE1 ;THEN IT CAN'T MATCH < OR >
|
||
MOV A,2(P) ;THIS A REAL MATCH FOR <, AND A POSSIBLE FOR >
|
||
MOV C,4(P) ;SO SAVE IT
|
||
INC D ;WAS IT >?
|
||
BEQ DIRSE1 ;SEE IF WE CAN FIND A BIGGER ONE
|
||
DIRSE2: CMP #-2,FNBVER(E) ;IS IT >?
|
||
BNE 1$ ;NOPE
|
||
DEC FNBFNO(E) ;CORRECT FILE NUMBER
|
||
1$: JSR F,ACRES ;RESTORE THE CLOBBERED RESGISTERS
|
||
TST B ;SET Z IF NO EXACT MATCH
|
||
RTS PC
|
||
DIRSE4: DEC D ;COMPENSATE FOR TEST
|
||
CMP D,C ;BOTH HAVE VERSIONS OR NO VERSION
|
||
BGT DIRSE1 ;FNB VERSION > FOUND VERSION, KEEP TRYING
|
||
BLT DIRSE2 ;FNB VERSION < FOUND, GIVE UP
|
||
MOV A,2(P) ;EXACT MATCH
|
||
MOV C,4(P) ;PREPARE TO RETURN
|
||
BR DIRSE2
|
||
;COMPARE THE NAME IN A FNB WITH THE NAME IN A DIRECTORY AN DECIDE
|
||
;IF THEY ARE GREATER, EQUAL OR LESS
|
||
;POINTER TO FNB IS IN E, POINTER TO DIR IS IN A
|
||
NAMCMP: SAVE <#0,A,B,E>
|
||
MOV A,B ;COPY DIRECTORY POINTER
|
||
ADD #FNBFN,E ;POINT TO FILE NAME IN FILE NAME BLOCK
|
||
MOV MFVERN-MFENHD(A),C ;GET VERSION NUMBER TO RETURN TO CALLER
|
||
ADD #MFVERN-MFENHD+2,A ;POINT TO POTENTIAL NAME
|
||
BIT #MFEOFB,(B) ;ARE THERE TIEM DATE ETC?
|
||
BEQ 1$ ;NOPE
|
||
ADD #10,A ;SKIP STUFF
|
||
1$: BIT #MFACCB,(B) ;ACCESS CODES?
|
||
BEQ NAMCM2 ;NOPE
|
||
NAMCM1: ADD #3,A ;SKIP ONE SET OF CODES
|
||
TSTB -1(A) ;LAST?
|
||
BLT NAMCM1 ;KEEP GOING
|
||
NAMCM2: CMPB (A)+,(E)+ ;COMPARE CHARACTERS
|
||
BNE NAMCM3 ;NOT EQUAL, GO FINISH UP
|
||
TSTB -1(A) ;DID THEY BOTH END?
|
||
BGE NAMCM2 ;NOPE
|
||
NAMCM4: REST <E,B,A>
|
||
TST (P)+ ;SET CONDITION CODES
|
||
RTS PC
|
||
NAMCM3: MOVB -(A),A ;GET LAST CHAR FROM DIRECTORY
|
||
MOV A,B ;COPY IT
|
||
MOVB -(E),E ;GET LAST FROM FNB
|
||
BIC #177600,A ;FLUSH CRAP
|
||
BIC #177600,E ;LIKEWISE
|
||
DEC 6(P) ;ASSUME FNB IS LESS
|
||
CMP E,A ;WHICH IS GREATER?
|
||
BLT NAMCM4 ;ASSUMED RIGHT
|
||
BGT NAMCM5 ;DIRETORY IS LESS
|
||
TST B ;TEST SIGN EXTENDED DIRECTORY CHARACTER
|
||
BGE NAMCM4 ;DIRETORY ENDED FIRST, FNB IS BIGGER
|
||
NAMCM5: MOV #1,6(P) ;DIRECTORY ENTRY IS SMALLER THAN FNB
|
||
BR NAMCM4
|
||
;SEARCH THROUGH ALL MFI'S FOR THE DISK IN E FOR THE FNB
|
||
;THAT IS IN A. IF FOUND, RETURN ITEM # IN A AND CLEAR Z
|
||
;CALL WITH MFI OF DIRECTORY IN B
|
||
;ELSE SET Z
|
||
MFISER: JSR F,ACSAV
|
||
MOV A,B ;COPY FNB POINTER
|
||
MOV A,C ;TWICE
|
||
ADD #FNBFN,B ;ACTUALLY POINT AT NAME
|
||
MOV MFBLNK(E),A ;FIRST MFI ON THE LIST
|
||
BEQ MFISE1 ;NOT FOUND
|
||
JSR PC,ITM2PL ;LOAD UP THE MFI
|
||
MFISE2: CMP MFBAKP(A),2(P) ;SAME DIRECTORY?
|
||
BNE MFISE6 ;NOPE
|
||
BIT #MFDWDB,MFLAGW(A) ;DELETE WHEN DONE?
|
||
BNE MFISE6 ;YES, FILE DOESN'T REALLY EXIST
|
||
MOV A,E ;COPY MFI POINTER
|
||
MOV B,F ;COPY FNB NAME POINTER
|
||
ADD #MFENHD,E ;POINT TO ENTRY
|
||
MOV E,D ;COPY THAT
|
||
ADD #4,E ;FIRST POSSIBLE PLACE FOR NAME
|
||
BIT #MFEOFB,(D) ;DOES IT HAVE EOF ETC?
|
||
BEQ 1$
|
||
ADD #10,E ;PUSH FORWARD...
|
||
1$: BIT #MFACCB,(D) ;ACCESS CODES?
|
||
BEQ MFISE3 ;NOPE
|
||
MFISE4: ADD #3,E ;SKIP ONE SET
|
||
TSTB -1(E) ;LAST SET?
|
||
BGE MFISE4 ;NOPE
|
||
MFISE3: CMPB (E)+,(F)+ ;COMPARE NAME BYTES
|
||
BNE MFISE6 ;NOT THE SAME NAME
|
||
TSTB -1(E) ;END OF NAMES?
|
||
BGE MFISE3 ;NOT YET
|
||
CMP MFVERN-MFENHD(D),FNBVER-FNBFN(B) ;SAME NAME, SAME VERSION?
|
||
BNE MFISE6 ;NOPE
|
||
BIT #.FALOK,MFLAGW(A) ;IS THE FILE LOCKED?
|
||
ERRORC NE,FLOK ;FILE LOCKED!
|
||
MOV ITEM2,(P) ;FOR THE CALLER
|
||
JSR PC,ITM2PO
|
||
JMP ACRETC
|
||
|
||
MFISE6: MOV MFDLNK(A),A ;NEXT MFI ON THIS DISK
|
||
BEQ MFISE7 ;NO MORE
|
||
JSR PC,ITM2LD ;LOAD THIS ONE
|
||
BR MFISE2 ;AND GIVE IT A TRY
|
||
|
||
MFISE7: JSR PC,ITM2PO
|
||
MFISE1: JMP ACRETS
|
||
;INSERT MFI IN ITEM 2 INTO IT'S DIRECTORY
|
||
MFIINS: JSR F,ACSAV
|
||
MOV ITEM2,F ;SAVE THE INDEX OF THE MFI BEING INSERTED
|
||
MOV ITM2A,A ;POINTER TO BEING INERTED MFI
|
||
MOV MFBAKP(A),A ;GET POINTER TO MFI OF DIR IT IS IN
|
||
JSR PC,ITM2PL ;LOAD THAT MFI
|
||
MOV MFIUPT(A),B ;NOW GET FUPT FOR THE DIRECTORY ITSELF
|
||
JSR PC,FUPTLK ;LOCK THE DIRECTROY
|
||
MOV MFBYTP(A),D ;SAVE THE EOF OF THE DIRECTORY
|
||
MOV F,A ;GET BACK THE MFI BEING INSERTED
|
||
JSR PC,ITM2PL ;LOAD IT FOR A SEC
|
||
MOV MFIFNO(A),E ;GET IT'S FILE NUMBER
|
||
MOV B,A ;NOW THE DIRECTORY ITSELF
|
||
JSR PC,ITM2LD ;LOAD OVER THE MFI
|
||
MFIIN1: MOV (A),C ;HEADER WORD
|
||
INC C ;MUST ROUND UP
|
||
BIC #177401,C ;TO EVENNESS
|
||
ADD C,A ;GO TO NEXT ENTRY
|
||
SOB E,MFIIN1 ;TILL WE GET WHERE WE'RE GOING
|
||
MOV A,B ;COPY POINTER TO ENTRY BEING REPLACED
|
||
MOV (B),E ;GET FIRST WORD
|
||
INC E ;AGAIN MUST ROUND UP
|
||
BIC #177401,E ;AND OFF
|
||
MOV F,A ;GET THE MFI AGAIN
|
||
JSR PC,ITM1PL ;LOAD INTO ITEM 1 THIS TIME
|
||
BIT #MFNODR,MFLAGW(A) ;ARE WE REPLACING IN DIR, OR JUST ADDING?
|
||
BEQ 1$ ;REPLACEING
|
||
CLR E ;ADDING, OLD ENTRY HAD ZERO LENGTH
|
||
1$: BIC #MFNODR!MFEBMB,MFLAGW(A) ;ENTRY WILL SOON BE SAFELY IN THE DIR
|
||
ADD #MFENHD,A ;POINT TO THE ENTRY ITSELF
|
||
MOV (A),C ;NOW WE NEED
|
||
INC C ;TO ROUND UP
|
||
BIC #177401,C ;AND OFF THE ENTRY WE ARE INSERTING
|
||
MOV E,F ;COPY LENGTH OF OLD ENTRY
|
||
SUB C,F ;GET DIFFERENCE IN LENGTHS OF NEW AND OLD
|
||
;IF ZERO, THEY ARE THE SAME
|
||
;IF POSITIVE, NEW ENTRY IS SHORTER
|
||
;IF NEGATIVE NEW ONE IS LONGER
|
||
SAVE <F,B> ;SAVE DIFFERENCE AND POINTER
|
||
MOV ITM2A,B ;GET POINTER TO BEG OF DIRECTORY
|
||
SUB F,MFBYTP-MFENHD(B) ;ADJUST THE BYTE COUNT IN THE SELF ENTRY
|
||
ADD B,D ;MAKE IT POINT INTO ITEM
|
||
MOV (P),B ;WE'LL GET IT IN THE MFI LATER
|
||
TST F ;CHECK SIGN OF DIFF
|
||
BLT MFIIN2 ;NEW IS LONGER THE USUAL CASE
|
||
BEQ MFIIN3 ;THEY ARE THE SAME, ANOTHER COMMON OCCURENCE
|
||
;HERE, THE NEW ENTRY IS SHORTER
|
||
;IF IT DOES HAPPEN, WE MUST COPY THE RIGHT NUMBER OF WORDS
|
||
;DOWN OVER THE OLD ENTRY
|
||
ADD C,B ;POINT PAST THE ENTRY BEING FLUSHED
|
||
ADD B,F ;PLACE TO COPY DOWN FROM
|
||
MFIIN4: CMP D,F ;ABOUT TO COPY STUFF FROM PAST END?
|
||
BEQ MFIIN3 ;YUP, DONE
|
||
MOV (F)+,(B)+ ;COPY A WORD
|
||
BR MFIIN4 ;CHECK AGAIN
|
||
;COME HERE IF WE HAVE TO COPY PART OF THE DIRECTORY UP
|
||
;TO MAKE ROOM FOR THE NEW LARGER ENTRY
|
||
MFIIN2: MOV D,B ;COPY THE END OF DIRETORY POINTER
|
||
SUB D,F ;THIS IS NEGATIVE OF <END OF DIR>+<AMOUNT BEING ADDED>
|
||
NEG F ;SO THIS POINTS TO NEW END OF DIR
|
||
MFIIN5: CMP B,(P) ;HAVE WE COPIED THE OLD ENTRY UP YET?
|
||
BEQ MFIIN3 ;YUP, GO FINISH UP
|
||
MOV -(B),-(F) ;UP YOU GO!
|
||
BR MFIIN5
|
||
;COME HERE WITH ROOM IN THE DIR FOR THE NEW ENTRY
|
||
MFIIN3: REST <B,F> ;B=> WHERE IT GOES, F IS DIFFERENCE IN SIZE
|
||
ASR C ;C WAS BYTES, NOW WORDS, LENGTH OF NEW ONE
|
||
1$: MOV (A)+,(B)+
|
||
SOB C,1$ ;COPY INTO DIR
|
||
MOV ITM1A,A ;POINTER TO MFI JUST PUT INTO DIR
|
||
MOV MFICBY(A),B ;GET NUMBER WE THOUGHT WE HAD COMMITTED IN DIR
|
||
CLR MFICBY(A) ;NOW NONE ARE COMMITTED
|
||
JSR PC,ITM1PO ;NO LONGER NEED INSERTED MFI
|
||
MOV ITEM2,E ;SAVE GIP OF DIR
|
||
JSR PC,ITM2PO ;NOR DIRECTORY
|
||
MOV ITM2A,A ;THIS SHOULD BE THE DIRECTORY MFI
|
||
ADD B,MFIUCF(A) ;FLUSH THE ONES WE THOUGHT WE NEEDED
|
||
ADD F,MFIUCF(A) ;BUT GRAB THE ONES WE USED
|
||
SUB F,MFBYTP(A) ;AND ADJUST EOF POINTER
|
||
MOV MFDISK(A),B ;DISK NUMBER FIE IS ON
|
||
MOV MFBITS(B),B ;GIP OF BIT TABLE
|
||
JSR PC,VALSRC ;MAKE SURE VALID AT SOURCE
|
||
MOV E,B ;GIP OF DIR
|
||
JSR PC,VALSRC ;VALIDATE AT SOURCE
|
||
ACRTP2: JSR PC,ITM2PO ;FLUSH DIR MFI
|
||
JMP ACRET
|
||
|
||
;FIX UP ANY MFI'S THAT ARE ABOVE A ENTRY BEING CREATED OR DELETED
|
||
;CALL WITH: NUMBER OF AFFECTED FILE IN C
|
||
;ITEM # OF DIRECTORY MFI IN D, DISK NUMBER IN E
|
||
;AMOUNT TO ADJUST BY IN F (I.E. 1 OR -1)
|
||
MFIUND: JSR F,ACSAV
|
||
MOV ITM2A,A
|
||
MOV MFBAKP(A),D ;DIR MFI
|
||
MOV MFIFNO(A),C ;FILE BEING ADDED OR DELETED
|
||
MOV MFDISK(A),E ;THE DISK IT IS ON
|
||
MOV MFBLNK(E),A ;GET FIRST MFI IN LIST
|
||
JSR PC,ITM2PL ;LOAD IT UP
|
||
MFINU4: CMP D,MFBAKP(A) ;IS THIS MFI IN THE RIGHT DIR?
|
||
BNE MFINU2 ;NOPE
|
||
CMP C,MFIFNO(A) ;SAME OR ABOVE BEING HACKED ENTRY?
|
||
BGT MFINU2 ;NO
|
||
ADD 12(P),MFIFNO(A) ;ADJUST THIS ONE
|
||
MFINU2: MOV MFDLNK(A),A ;GET NEXT IN LINE
|
||
BEQ MFINU3 ;NO MORE
|
||
JSR PC,ITM2LD ;LOAD OVER THE PREVIOUS ONE
|
||
BR MFINU4 ;KEEP LOOKING
|
||
MFINU3: JMP ACRTP2
|
||
.SBTTL FILE I/O CALLS
|
||
;DISK BYTE INPUT
|
||
DKBTI: MOV #1,C ;WE NEED ONLY 1 BYTE
|
||
JSR PC,DKISET ;SET UP TO DO IT
|
||
ERRORC EQ,RPEF,SV ;ATTEMPT TO READ PAST EOF?
|
||
MOVB (E),B ;GET THE BYTE
|
||
BIC #177400,B ;CLEAR THE TOP BYTE
|
||
JSR PC,GIVPSW ;GIVE IT TO THE USER
|
||
DKBTI1: JSR PC,ITM2PO ;POP THE FILE PAGE
|
||
JSR PC,LSWPOP ;POP THE LOCK ON THE FA
|
||
JSR PC,FAINC ;INCREMENT THE FILE POINTER
|
||
JMP ERETCZ ;AND RETURN HAPPILY
|
||
|
||
;DISK WORD INPUT
|
||
DKWDI: MOV #2,C ;THIS TIME WE NEED 2 BYTES
|
||
JSR PC,DKISET ;TRY TO GET THEM
|
||
ERRORC EQ,RPEF,SV ;PAST EOF
|
||
CMP #1,C ;DID WE GET ONLY 1?
|
||
BEQ DKWDI1 ;YUP, PAINFULLY CASE
|
||
MOVB 1(E),B ;GET HIGH BYTE
|
||
SWAB B ;INTO RIGHT PLACE
|
||
CLRB B ;MAKE ROOM FOR LOW BYTE
|
||
BISB (E),B ;PUT IT IN
|
||
JSR PC,GIVPSW ;PUT IT ONTO USER'S STACK
|
||
INC FAFBP(D) ;THIS CAN'T OVERFLOW THE PAGE
|
||
BR DKBTI1 ;GO CLEAN UP AND INC AGAIN
|
||
|
||
;IF ONLY 1 BYTE IS AVAILABLE, WE HAVE POTENTIAL PCLOSER PROBLEMS
|
||
DKWDI1: MOVB (E),-(P) ;GET THE FIRST BYTE
|
||
JSR PC,ITM2PO ;POP TH EFILE PAGE
|
||
JSR PC,LSWPOP ;FLUSH THE LOCK ON THE FA
|
||
JSR PC,FAINC ;GO TO THE NEXT FILE BYTE
|
||
MOV #LSPPCL,A ;RUN ON PCLOSER
|
||
MOV ITEM1,B ;THE SPHERE
|
||
JSR PC,LOCKSW ;GET A LOCK BLOCK
|
||
MOV #FAPDEC,LCKWD1(B) ;DEC POINTER ON PCLOSER
|
||
MOV D,LCKWD2(B) ;POINTER TO CAP
|
||
SUB ITM1A,LCKWD2(B) ;MAKE INTO OFFSET
|
||
MOV #1,C ;NOW ONLY NEED ONE MORE BYTE
|
||
JSR PC,DKISET ;MAKE UP THE NEW FUPT
|
||
ERRORC EQ,RPEF,SV ;OOOPS, EOF
|
||
MOVB (E),1(P) ;GET SECOND BYTE
|
||
REST B ;ASSEMBLED WORD INTO B
|
||
JSR PC,GIVPSW ;PASS TO THE USER
|
||
JSR PC,LSWPOP ;POP THE LOCK ON THE FA
|
||
BR DKBTI1 ;FINISH CLEANING UP AS USUAL
|
||
|
||
;INCREMENT THE FILE POINTER AND DO THE RIGHT THING ON OVERFLOW
|
||
FAINC: INC FAFBP(D) ;INC BYTE PART
|
||
FAINTS: CMP #20000,FAFBP(D) ;OVERFLOW?
|
||
BNE FAINC1 ;NOPE
|
||
CLR FAFBP(D) ;RESET BYTE PART
|
||
INC FAFPN(D) ;NEXT PAGE
|
||
FAINC1: RTS PC
|
||
|
||
;PCLOSER ROUTINE TO DECREMENT THE FILE POINTER
|
||
FAPDEC: MOV LCKWD2(B),B ;GET OFFSET
|
||
ADD A,B ;GET ADDRESS OF CAP
|
||
DEC FAFBP(B) ;BACK ONE BYTE
|
||
BNE FAPDE1 ;NO UNDERFLOW
|
||
MOV #17777,FAFBP(B) ;CORRECT FOR UNDERFLOW
|
||
DEC FAFPN(B) ;IN PAGE NUMBER TOO
|
||
FAPDE1: RTS PC
|
||
;DISK BLOCK IN ROUTINE
|
||
DKBKI: JSR PC,RETNSW ;GET THE NEGATIVE BYTE COUNT
|
||
MOV A,B ;SAVE IN B
|
||
JSR PC,RETNSW ;GET THE USER ADDRESS
|
||
DKBKI3: TST B ;DOES HE WANT ANY?
|
||
BEQ DKBKI4 ;NOPE, RETURN TO USER MODE
|
||
BIT #1,A ;ODD USER ADDRESS?
|
||
BNE DKBKBI ;GO INPUT EXACTLY ONE BYTE TO EVEN IT OFF
|
||
CMP #-1,B ;DOES THE USER WANT EXACTLY ONE BYTE?
|
||
BEQ DKBKBI ;GO GIVE HIM EXACTLY THAT
|
||
MOV B,C ;COPY BYTE COUNT
|
||
NEG C ;MAKE IT POSITIVE
|
||
SAVE <A,B> ;SAVE BYTE COUNT
|
||
JSR PC,DKISET ;SET UP TO TRANSFER THE STUFF
|
||
ERRORC EQ,RPEF,SV ;HE READ PAST THE EOF
|
||
REST <B,A>
|
||
CMP #1,C ;ONLY ONE BYTE?
|
||
BEQ DKBKB1 ;GO GIVE HIM THAT
|
||
ASR C ;CONVERT TO WORD COUNT
|
||
DKBKI6: SAVE C ;SAVE WORD COUNT
|
||
DKBKI1: MFPD (A) ;JUST TO MAKE SURE PAGE IS IN CORE
|
||
MOVB (E)+,(P) ;GET LOW BYTE
|
||
MOVB (E)+,1(P) ;GET HIGH ONE
|
||
MTPD (A)+ ;GIVE WORD TO USER
|
||
BIT #1777,A ;CROSS USER BLOCK BOUNDARY?
|
||
BEQ DKBKI2 ;YES, GO CLEAN UP IN CASE OF ERRROR ON NEXT BLOCK
|
||
SOB C,DKBKI1 ;FOR ALL AVAILABLE WORDS
|
||
BR DKBKI7 ;COUNTED OUT
|
||
DKBKI2: DEC C ;GOT A WORD WE HAVEN'T COUNTED YET
|
||
SUB C,(P) ;IF WE DIDN'T TAKE THEM ALL, DON'T COUNT THEM ALL
|
||
DKBKI7: MOV C,F ;BUT SAVE COUNT OF EXTRA WORDS
|
||
REST C ;GET COUNT OF WORDS WE TOOK
|
||
ASL C ;CONVERT TO BYTES
|
||
DKBKI5: ADD C,B ;ADJUST USER'S BYTE COUNT
|
||
JSR PC,DKUPDT ;UPDATE USER POINTERS
|
||
ADD C,FAFBP(D) ;UPDATE FILE POINTER
|
||
JSR PC,FAINTS ;TEST FOR INCREMTENT OVERFLOWING PAGE
|
||
MOV F,C ;GET COUNT OF LEFTOVER WORDS
|
||
BNE DKBKI6 ;JUST TRANSFER THEM
|
||
JSR PC,ITM2PO
|
||
JSR PC,LSWPOP ;FLUSH LOCK ON FUPT
|
||
BR DKBKI3 ;NONE, DO IT THE HARD WAY
|
||
DKBKI4: JMP DKBKEX ;RETURN TO THE USER
|
||
;COME HERE TO EVEN OUT THE WORLD. THIS WILL TRANSFER EXACTLY ONE BYTE
|
||
DKBKBI: MOV #1,C ;ONLY WANT 1 BYTES FROM THE FILE
|
||
SAVE <A,B>
|
||
JSR PC,DKISET ;SET IT UP
|
||
ERRORC EQ,RPEF,SV
|
||
REST <B,A>
|
||
DKBKB1: SAVE A ;SAVE REAL USER POINTER
|
||
BIC #1,A ;MAKE IT EVEN
|
||
MFPD (A) ;GET THE USER'S WORD
|
||
BIT #1,2(P) ;IS THE REAL POINTER ODD?
|
||
BEQ DKBKB2 ;NOPE, EVEN
|
||
MOVB (E),1(P) ;TRANSFER THE ODD BYTE
|
||
BR DKBKB3
|
||
DKBKB2: MOVB (E),(P) ;TRANSFER THE EVEN BYTE
|
||
DKBKB3: MTPD (A) ;RETURN MUNGED WORD TO THE USER
|
||
REST A ;GET THE REAL USER POINTER
|
||
INC A ;TRANSFERED ONE BYTE
|
||
CLR F ;NO EXTRA BYTES TO TRANSFER
|
||
BR DKBKI5 ;GO RETURN POINTERS AND CONTINUE TRANSFER
|
||
|
||
;RETURN THE USER'S POINTERS TO HIM TO WIN ON PCLOSER
|
||
DKUPDT: SAVE B ;SAVE BYTE COUNT
|
||
MOV A,B ;GET USER ADDRESS
|
||
JSR PC,GIVPSW ;TRANSFER BACK TO HIM
|
||
MOV (P),B ;BYTE COUNT
|
||
JSR PC,GIVPSW ;TRANSFER BACK
|
||
MOV ITM0A,B ;POINT TO PROCESS
|
||
ADD #4,PUPDLO(B) ;FIX UP STACK POINTER
|
||
REST B
|
||
RTS PC
|
||
;SET UP FOR A DISK INPUT CALL
|
||
;CALL THIS ROTUINE WITH THE DESIRED NUMBER OF BYTES IN C
|
||
;AND A POINTER TO THE FA CAP IN D
|
||
;IT WIL RETURN THE NUMBER OF BYTES AVAILABLE IN C
|
||
;AND A POINTER TO THE THE FIRST BYTE IN E
|
||
;IT WILL HAVE LOCKED THE FILE CAPABILITY AND LOADED THE FILE PAGE
|
||
;INTO ITEM 2
|
||
;IT SETS Z IF THERE ARE NO BYTES AVAILABLE, AND ERRORS OUT
|
||
;IF THE FILE POINTER IS BEYOND THE END OF FILE
|
||
;LOTS OF REGISTERS MIGHT GET CLOBBERED
|
||
DKISET: SAVE C ;SAVE # OF BYTES DESIRED
|
||
DKISE8: MOV FAUPT(D),B ;GET THE FUPT
|
||
BEQ DKISE2 ;NONE, GO MAKE ONE UP
|
||
CMP #-1,B ;IS SOMEONE ELSE IS MAKING ONE UP?
|
||
BEQ DKISE5 ;YUP, WAIT FOR HIM
|
||
BIC #GIPBIT,B ;MAKE INTO AN ADDRESS
|
||
TST FUPTPR(B) ;SOMEONE ELSE USING THE CAP?
|
||
BEQ DKISE1 ;NOPE, GRAB IT
|
||
DKISE5: JSR PC,SFLUSH ;WAIT
|
||
JSR PC,RUNME ;BUT NOT LONG
|
||
BR DKISE8 ;TRY AGAIN
|
||
DKISE1: JSR PC,FUPTLK ;LOCK THIS FUPT
|
||
MOV UPTPBP(B),E ;GET PB POINTER
|
||
CMP FAFPN(D),PBFPNO(E) ;IS THIS FUPT FOR TH EPAGE WE ARE ON?
|
||
BNE DKISE3 ;NOPE, GET A NEW ONE
|
||
MOVB UPTSTL(B),E ;GET THE START AND LENGTH
|
||
MOV E,F ;COPY
|
||
BIC #UPTSMS,E ;START
|
||
BIC #UPTLMS,F ;LENGTH
|
||
ASH #10.-UPTSSH,E ;START INTO BYTES
|
||
INC F ;0=>1
|
||
ASH #10.,F ;LENGTH INTO BYTES
|
||
ADD E,F ;LENGHT INTO END
|
||
CMP FAFBP(D),E ;ARE WE INTERESTED IN STUFF AFTER THE START?
|
||
BLT DKISE3 ;NOPE, BEFORE IT
|
||
CMP FAFBP(D),F ;AND BEFORE THE END?
|
||
BGE DKISE3 ;NOPE, AFTER IT
|
||
JSR PC,DKIEFC ;CHECK FOR THE EOF BEING IN THIS BLOCK
|
||
SUB FAFBP(D),F ;THAT'S HOW MANY BYTES THERE ARE AVAILABLE
|
||
MOV F,C ;WANT TO RETURN IT IN C
|
||
CMP C,(P) ;DO WE HAVE MORE THAN HE WANTS?
|
||
BLOS 1$ ;NOPE
|
||
MOV (P),C ;ONLY GIVE WHAT HE ASKS FOR (OR LESS)
|
||
1$: SAVE A
|
||
MOV FAUPT(D),A ;GET THE FILE PAGE
|
||
JSR PC,ITM2PL ;LOAD IT UP
|
||
SUB E,A ;SUBTRACT OFF THE PAGE START
|
||
MOV A,E ;COPY
|
||
ADD FAFBP(D),E ;AND ADD IN THE FILE POINTER
|
||
REST <A,> ;RESTORE A AND FLUSH SAVED C
|
||
TST C ;SET CONDITION CODES
|
||
RTS PC
|
||
|
||
;COME HERE IF THE CURENT FILE PAGE IS USLESS TO US
|
||
DKISE3: JSR PC,FAUPDL ;DELETE THE CURRENT UPT
|
||
JSR PC,LSWFLS ;FLUSH THE LOCK WE HAD ON IT
|
||
;FALL INTO MAKING A NEW FUPT THAT IS THE RIGHT THING
|
||
DKISE2: REST C ;WE WNAT TO PRESERVE
|
||
JSR F,ACSAV ;ALL THE REGISTERS NOW
|
||
MOV D,A ;COPY CAP POINTER
|
||
SUB ITM1A,A ;MAKE IT RELATIVE
|
||
ADD #FAUPT,A ;WANT TO LOCK THE FAUPT
|
||
MOV #-1,B ;LOCK ALL BITS
|
||
MOV ITEM1,C ;IN THE CURRENT SPHERE
|
||
JSR PC,LCKASW ;LOCK IT
|
||
MOV FAFPN(D),C ;THE PAGE NUMBER
|
||
MOV FAMFI(D),A ;NEED TO LOOK IN THE MFI
|
||
JSR PC,ITM2PL
|
||
MOV #20000,F ;DEFAULT END OF THIS PAGE
|
||
MOV FAFBP(D),E ;POINTER INTO PAGE
|
||
CMP C,MFPGNO(A) ;ARE WE ON THE EOF PAGE?
|
||
ERRORC HI,APEF ;NO, WE ARE BEYOND IT!
|
||
BLO DKISE6 ;NO, WE ARE BEFORE IT
|
||
CMP E,MFBYTP(A) ;IS FILE POINTER BEYOND EOF?
|
||
ERRORC HI,APEF ;ACCESS BEYOND END OF FILE IF SO
|
||
BIS #.FAEOF,(D) ;TELL THE WORLD TO BE CAREFUL
|
||
MOV MFBYTP(A),F ;END OF FILE IS END OF PAGE
|
||
DKISE6: MOV E,B ;COPY FILE POINTER
|
||
ADD 4(P),B ;ADD NUMBER OF BYTES CALLER WANTS TO IT
|
||
CMP B,F ;DOES CALLER WANT MORE THAN CAN FIT ON PAGE?
|
||
BHI 1$ ;YES, HE ONLY GETS WHAT FITS
|
||
MOV B,F ;GIVE HIM ONLY WHAT HE WANTS
|
||
1$: ASH #-10.,E ;CONVERT TO BLOCKS
|
||
DEC F ;MAKE 2000 INTO 1777
|
||
ASH #-10.,F ;THIS TOO
|
||
SUB E,F ;CONVERT END TO LENGTH
|
||
BGE DKISE4 ;THERE ARE SOEM BYTES AVAILABLE
|
||
BIT #MFLSTB,MFENHD(A) ;NO BYTES, BUT IS THE BLOCK THERE?
|
||
BEQ DKISE7 ;NOPE, NOTHING
|
||
CLR F ;YES, MAP IN THE BLOCK ANYWAY
|
||
DKISE4: MOV FAMFI(D),A ;GET THE MFI #
|
||
MOV FAFPN(D),C ;GET THE RIGHT PAGE NUMBER
|
||
JSR PC,MAKFPG ;MAKE A FILE PAGE
|
||
ERRORC EQ,APEF ;UGH, MUST HAVE HIT A HOLE!
|
||
JSR PC,LSWPOP ;LOCK ON JUST CREATED FUPT
|
||
JSR PC,LSWPOP ;LOCK ON FA CAP
|
||
MOV C,FAUPT(D) ;THE NEW FILE PAGE
|
||
JSR PC,ITM2PO ;FLUSH LOADED MFI
|
||
JSR F,ACRES
|
||
JMP DKISET ;TRY IT AGAIN
|
||
|
||
DKISE7: JSR PC,LSWPOP ;POP LOCK ON UPT OF FA
|
||
JSR PC,ITM2PO ;FLUSH MFI
|
||
JSR F,ACRES ;GET REGISTERS BACK
|
||
CLR C ;NOTE THAT NO BYTES ARE AVAIABLE
|
||
RTS PC ;AND RETURN
|
||
;ROUTINE TO ADJUST F IF THE PAGE IS THE LAST IN THE FILE
|
||
;AND F POINTS BEYOND TH EEND OF THE FILE
|
||
DKIEFC: BIT #.FAEOF,(D) ;ARE WE POSSIBLY IN THE LAST PAGE OF THE FILE?
|
||
BEQ DKIEF3 ;NO, DON'T WORRY
|
||
SAVE A
|
||
MOV FAMFI(D),A ;GET THE MFI
|
||
JSR PC,ITM2PL
|
||
CMP FAFPN(D),MFPGNO(A) ;ARE WE REALLY ON THE LAST PAGE>
|
||
BLO DKIEF1 ;NO, NO NEED TO WORRY
|
||
CMP F,MFBYTP(A) ;DOES THIS POINT PAST THE EOF?
|
||
BLOS DKIEF2 ;NOPE
|
||
MOV MFBYTP(A),F ;SET IT TO THE EOF
|
||
DKIEF2: JSR PC,ITM2PO
|
||
REST A
|
||
DKIEF3: RTS PC
|
||
DKIEF1: BIC #.FAEOF,(D) ;NO NEED TO WORRY FOR NOW
|
||
BR DKIEF2
|
||
|
||
;DELETE THE CURRENT UPT IF THE TRANSFER END ON AN EVEN BLOCK BOUNDARY
|
||
DKBECK: BIT #1777,FAFBP(D) ;ON BOUNDARY?
|
||
BNE FAUPD1 ;NOPE
|
||
FAUPDL: MOV FAUPT(D),B ;GET THE CURENNT PAGE
|
||
BEQ FAUPD1 ;NONE TO FLUSH
|
||
JSR PC,UPTDL ;FLUSH IT
|
||
CLR FAUPT(D) ;IT IS FLUSHED
|
||
FAUPD1: RTS PC
|
||
|
||
;DISK BYTE OUTPUT
|
||
DKBTO: BIT #.FAWT,(D) ;DOES HE HAVE WRITE ACCESS?
|
||
ERRORC EQ,BAC ;NOPE, DON'T LET HIM WRITE
|
||
MOV #1,C ;WANT TO INSERT 1 BYTE
|
||
JSR PC,DKOSET ;GET SPACE
|
||
JSR PC,RETNSW ;GET THE BYTE TO OUTPUT
|
||
MOVB A,(E) ;PUT INTO FILE
|
||
DKBTO1: JSR PC,ITM2PO ;THE FILE PAGE
|
||
JSR PC,FAEFIN ;INCREMENT FA POINTER AND MAYBE EOF
|
||
JSR PC,LSWPOP ;POP LOCK ON FUPT
|
||
JMP ERETCZ ;RETURN TO USER
|
||
|
||
;DISK WORD OUTPUT
|
||
DKWDO: BIT #.FAWT,(D) ;DOES HE HAVE WRITE ACCESS?
|
||
ERRORC EQ,BAC ;NOPE, DON'T LET HIM WRITE
|
||
BIT #.FAWD,A ;FIRST PART DONE?
|
||
BNE DKWDO2 ;YUP, GO DO SECOND PART
|
||
MOV #2,C ;WANT TO OUTPUT 2 BYTES
|
||
JSR PC,DKOSET ;TRY TO SET IT UP
|
||
CMP #2,C ;DID WE GET THEM?
|
||
BGT DKWDO1 ;NOPE, ONLY 1
|
||
JSR PC,RETNSW ;GET WORD TO OUTPUT
|
||
MOVB A,(E)+ ;OUTPUT FIRST BYTE
|
||
JSR PC,FAEFIN ;RECORD THAT BYTE
|
||
DKWDO3: SWAB A ;GET TOP BYTE
|
||
MOVB A,(E) ;OUTPUT THAT
|
||
BR DKBTO1 ;RETURN TO USER
|
||
DKWDO1: JSR PC,RETNSW ;GET WORD WE WANT TO OUTPUT
|
||
MOVB A,(E) ;OUTPUT FIRST BYTE
|
||
SAVE B ;SAVE FLAGS
|
||
MOV A,B ;GET WORD
|
||
JSR PC,GIVPSW ;GIVE BACK WORD
|
||
REST B ;GET FLAGS
|
||
BIS #.FAWD,B ;FIRST PART DONE
|
||
JSR PC,GIVPSW ;GIVE BACK FLAGS
|
||
JSR PC,ITM2PO ;FILE PAGE
|
||
JSR PC,FAEFIN ;FA POINTER AND EOF
|
||
JSR PC,LSWPOP ;LOCK ON PAGE
|
||
;TAKE ME NOW LORD!
|
||
DKWDO2: MOV #1,C ;ONLY HAVE TO OUTPUT 2ND BYTE
|
||
JSR PC,DKOSET ;MAKE ROOM
|
||
JSR PC,RETNSW ;GET THE WORD
|
||
BR DKWDO3 ;RETURN TOP BYTE
|
||
|
||
;DISK BLOCK OUT ROUTINE
|
||
DKBKO: BIT #.FAWT,(D) ;DOES HE HAVE WRITE ACCESS?
|
||
ERRORC EQ,BAC ;NOPE, DON'T LET HIM WRITE
|
||
JSR PC,RETNSW ;GET THE NEGATIVE BYTE COUNT
|
||
MOV A,B ;SAVE IN B
|
||
JSR PC,RETNSW ;GET THE USER ADDRESS
|
||
DKBKO3: TST B ;DOES HE WANT ANY?
|
||
BNE DKBKO4 ;YES, CONTINUE GETTING THEM
|
||
DKBKEX: JSR PC,DKBECK ;CHECK FOR END OF BLOCK
|
||
JMP ERETCZ ;RETURN TO THE USER
|
||
DKBKO4: BIT #1,A ;ODD USER ADDRESS?
|
||
BNE DKBKCI ;GO INPUT EXACTLY ONE BYTE TO EVEN IT OFF
|
||
CMP #-1,B ;DOES THE USER WANT EXACTLY ONE BYTE?
|
||
BEQ DKBKCI ;GO GIVE HIM EXACTLY THAT
|
||
MOV B,C ;COPY BYTE COUNT
|
||
NEG C ;MAKE IT POSITIVE
|
||
SAVE <A,B> ;SAVE BYTE COUNT
|
||
JSR PC,DKOSET ;SET UP TO TRANSFER THE STUFF
|
||
REST <B,A>
|
||
CMP #1,C ;ONLY ONE BYTE?
|
||
BEQ DKBKC1 ;GO GIVE HIM THAT
|
||
ASR C ;CONVERT TO WORD COUNT
|
||
DKBKO6: SAVE C ;SAVE WORD COUNT
|
||
DKBKO1: MFPD (A)+ ;GET WORD TO TRANSFER
|
||
MOVB (P),(E)+ ;INSERT LOW BYTE
|
||
MOVB 1(P),(E)+ ;INSERT HIGH ONE
|
||
TST (P)+ ;FLUSH WORD FROM STACK
|
||
BIT #1777,A ;CROSS USER BLOCK BOUNDARY?
|
||
BEQ DKBKO2 ;YES, GO CLEAN UP IN CASE OF ERRROR ON NEXT BLOCK
|
||
SOB C,DKBKO1 ;FOR ALL AVAILABLE WORDS
|
||
BR DKBKO7 ;COUNTED OUT
|
||
DKBKO2: DEC C ;GOT A WORD WE HAVEN'T COUNTED YET
|
||
SUB C,(P) ;IF WE DIDN'T TAKE THEM ALL, DON'T COUNT THEM ALL
|
||
DKBKO7: MOV C,F ;BUT SAVE COUNT OF EXTRA WORDS
|
||
REST C ;GET COUNT OF WORDS WE TOOK
|
||
ASL C ;CONVERT TO BYTES
|
||
DKBKO5: ADD C,B ;ADJUST USER'S BYTE COUNT
|
||
JSR PC,DKUPDT ;UPDATE USER POINTERS
|
||
ADD C,FAFBP(D) ;UPDATE FILE POINTER
|
||
JSR PC,FAEFTS ;TEST FOR INCREMTENT OVERFLOWING PAGE
|
||
MOV F,C ;GET COUNT OF LEFTOVER WORDS
|
||
BNE DKBKO6 ;JUST TRANSFER THEM
|
||
JSR PC,ITM2PO
|
||
JSR PC,LSWPOP ;POP THE SWITCH
|
||
BR DKBKO3 ;NONE, DO IT THE HARD WAY
|
||
;COME HERE TO EVEN OUT THE WORLD. THIS WILL TRANSFER EXACTLY ONE BYTE
|
||
DKBKCI: MOV #1,C ;ONLY WANT 1 BYTES FROM THE FILE
|
||
SAVE <A,B>
|
||
JSR PC,DKOSET ;SET IT UP
|
||
REST <B,A>
|
||
DKBKC1: SAVE A ;SAVE REAL USER POINTER
|
||
BIC #1,A ;MAKE IT EVEN
|
||
MFPD (A) ;GET THE USER'S WORD
|
||
BIT #1,2(P) ;IS THE REAL POINTER ODD?
|
||
BEQ DKBKC2 ;NOPE, EVEN
|
||
MOVB 1(P),(E) ;TRANSFER THE ODD BYTE
|
||
BR DKBKC3
|
||
DKBKC2: MOVB (P),(E) ;TRANSFER THE EVEN BYTE
|
||
DKBKC3: REST <,A> ;GET THE REAL USER POINTER
|
||
INC A ;TRANSFERED ONE BYTE
|
||
CLR F ;NO EXTRA BYTES TO TRANSFER
|
||
BR DKBKO5 ;GO RETURN POINTERS AND CONTINUE TRANSFER
|
||
;SETUP ROUTINE FOR DISK OUTPUT
|
||
;CALL WITH NUMBER OF BYTES YOU WANT TO OUTPUT IN C, RETURNS WITH
|
||
;NUMBER YOU CAN OUTPUT IN C
|
||
DKOSET: SAVE C ;SAVE NUMBER HE WANTS TO OUTPUT
|
||
JSR PC,DKISET ;SEE IF THERE ARE ANY BEFORE THE EOF
|
||
BNE DKOSE1 ;YES, LET HIM OUTPUT THAT MANY FOR NOW
|
||
MOV FAFBP(D),F ;GET THE POINTER INTO THIS PAGE
|
||
BIC #176000,F ;ARE WE AT THE END OF THE LAST BLOCK?
|
||
BEQ DKOSE2 ;PROBABLY SO
|
||
MOV #2000,C ;THIS MANY BYTES ARE IN A BLOCK
|
||
SUB F,C ;SO THIS MANY BYTES AREN'T USED IN THE LAST BLOCK
|
||
DKOSE1: CMP C,(P) ;DO WE HAVE MORE THAN HE WANTS?
|
||
BHIS 1$ ;YUP, GIVE HIM ONLY WHAT HE ASKED FOR
|
||
MOV C,(P) ;GIVE HIM ALL WE GOT
|
||
1$: REST C ;GET NUMBER WE HAVE FOR HIM
|
||
RTS PC
|
||
DKOSE2: REST C ;GET BACK C
|
||
JSR F,ACSAV ;AND SAVE THEM ALL
|
||
MOV FAMFI(D),A ;MFI FOR THIS FILE
|
||
JSR PC,ITM2PL ;LOAD IT UP
|
||
BIT #MFLSTB,MFENHD(A) ;DOES THE BLOCK THE EOF POINTS TO EXIST?
|
||
BEQ DKOSE3 ;NOPE, NEED A NEW BLOCK
|
||
DKOSE5: JSR PC,ITM2PO
|
||
JSR F,ACRES ;GET BACK THE REGISTERS
|
||
SAVE C ;SAVE WHAT THE USER WANTS
|
||
MOV #2000,C ;WE HAVE A WHOLE BLOCK TO GIVE HIM
|
||
BR DKOSE1 ;SEE IF HE WANTS IT
|
||
;COME HERE WHEN WE NEED A NEW BLOCK=> HAIR**2
|
||
DKOSE3: BIT #MFIBEB,MFLAGW(A) ;IS SOMEONE ELSE HACKING THIS?
|
||
BNE DKOSE8 ;YES, GO POUT
|
||
MOV #MFLAGW,A ;WORD TO LOCK BIT IN
|
||
MOV #MFIBEB,B ;BIT TO LOCK
|
||
MOV FAMFI(D),C ;IN THE MFI
|
||
JSR PC,LCKASW ;LOCK THE BIT
|
||
MOV ITM2A,A ;POINT TO MFI AGAIN
|
||
MOV MFENHD(A),D ;GET HEADER WORD
|
||
ADD #4,D ;MAY HAVE TO ADD BYTES TO ENTRY
|
||
MOV ITEM2,A ;THE MFI
|
||
JSR PC,MFIEXP ;MAYBE EXPAND ITEM
|
||
JSR PC,ITM1PO ;MFIEXP PUSHES IT...
|
||
MOV ITM2A,A ;POINTER TO MFI
|
||
TST MFBAKP(A) ;ROOT OR TEMP FILE?
|
||
BEQ DKOSE4 ;YES, NO NEED TO COMMIT
|
||
CMP #4,MFICBY(A) ;DO WE HAVE AT LEAST 4 BYTES COMMITTED?
|
||
BLE DKOSE4 ;YES, SAFE
|
||
MOV #6,E ;MIGHT AS WELL BE GREEDY
|
||
SUB MFICBY(A),E ;BUT NOT TOO GREEDY
|
||
INC E ;EVEN IT OFF
|
||
BIC #1,E
|
||
MOV MFBAKP(A),A ;POINT TO DIR ABOVE US
|
||
JSR PC,DIRCMT ;COMMIT THOSE BYTES ABOVE US
|
||
MOV ITM2A,A ;POINT AT OUT MFI AGAIN
|
||
ADD E,MFICBY(A) ;GOT THEM
|
||
DKOSE4: MOV MFDISK(A),D ;GET DISK NUMBER FILE IS ON
|
||
MOV MFBITS(D),B ;THE FUPT OF THE BIT TABLE
|
||
JSR PC,FUPTLK ;MAKE SURE I GET PCLOSERED IF IT IS SWAPPED OUT
|
||
MOV B,A
|
||
JSR PC,ITM2PL ;LOAD BIT TABLE
|
||
TST (A) ;SWAP IT IN
|
||
JSR PC,ITM2PO ;UNLOAD
|
||
MOV ITM2A,A ;POINT AT MFI AGAIN
|
||
MOV MFIPB(A),B ;POINT TO FIRST PB
|
||
BEQ DKOSE6 ;NONE
|
||
DKOSE7: CMP MFPGNO(A),PBFPNO(B) ;IS THIS THE EOF PB?
|
||
BNE DKOSE9 ;NOPE
|
||
DKOS.1: JSR PC,PBWAIT ;MAKE SURE IT ISN'T BEING HACKED
|
||
BIT #PBVAS,(B) ;VALID AT SOURCE?
|
||
BNE DKOS.2 ;YUP
|
||
JSR PC,PBVLSR ;VALIDATE AT SOURCE
|
||
BR DKOS.1
|
||
DKOS.2: BIT #PBSTS,(B) ;IS IT SWAP TO SOURCE?
|
||
BNE 1$ ;YES, VALID AT SWAP SPACE
|
||
BIC #PBVASS,(B) ;NOT VALID AT SWAP SPACE
|
||
1$: JSR PC,PBCFLS ;FLUSH ITS CORE
|
||
BR DKOSE6 ;DONE
|
||
DKOSE9: MOV PBFLNK(B),B ;NEXT
|
||
BNE DKOSE7 ;TRY AGAIN
|
||
DKOSE6: MOV MFENDB(A),E ;GET ADDRESS OF THE LAST BLOCK IN THE FILE
|
||
JSR PC,GETDBL ;GET A DISK BLOCK
|
||
JSR PC,ADDBLK ;ADD A BLOCK TO THE END OF THE MFI IN ITEM 2
|
||
TST B ;IS THERE A PB?
|
||
BEQ DKOS.3 ;NO
|
||
MOV MFBYTP(A),C ;BYTE POINTER IN LAST PAGE
|
||
ASH #-10.,C ;BLOCK # OF BLOCK JUST ADDED
|
||
ASL C ;IN BYTES
|
||
ADD B,C ;POINT INTO PB
|
||
MOV E,PBSDA(C) ;NEW BLOCK
|
||
INCB PBFLEN(B) ;INCREASE SIZE OF PAGE
|
||
DKOS.3: BIS #MFLSTB,MFENHD(A) ;THE EOF NOW POINTS TO AN EXISTING BLOCK
|
||
BIS #MFEBMB,MFLAGW(A) ;ENTRY HAS BEEN HACKED
|
||
JSR PC,LSWPOP ;FLUSH LOCK ON ENTRY
|
||
JSR PC,LSWPOP ;FLUSH LOCK ON BIT TABLE
|
||
BR DKOS.4
|
||
DKOSE8: JSR PC,SFLUSH ;WAIT FOR THE OTHER GUY TO FINISH EXPANDING ENTRY
|
||
BIT #MFIBEB,MFLAGW(A) ;DONE?
|
||
BNE DKOSE8 ;NOT YET
|
||
JSR PC,RUNME ;FINISHED
|
||
DKOS.4: JSR PC,ITM2PO ;POP MFI
|
||
JSR F,ACRES ;AND REGISTERS
|
||
JMP DKOSET ;TRY IT ALL AGAIN
|
||
;ADD A BLOCK TO THE END OF THE MFI IN ITEM2
|
||
ADDBLK: JSR F,ACSAV
|
||
MOV ITM2A,A ;POINT TO MFI
|
||
MOV MFENDP(A),B ;PLACE TO ADD STUFF
|
||
ADD A,B ;POINT INTO ITEM
|
||
MOV MFENDB(A),C ;LAST BLOCK WE HAD IN FILE
|
||
SUB E,C ;GET DIFFERENCE
|
||
NEG C ;MAKE POSITIVE
|
||
MOV E,MFENDB(A) ;NEW LAST BLOCK
|
||
JSR PC,@MFENDT(A) ;ROUTINE TO ADD NEXT BLOCK
|
||
SUB A,B ;UN RELOCATE
|
||
MOV B,MFENDP(A) ;NEW PLACE
|
||
MOV F,MFENDT(A) ;NEW DISPATCH
|
||
JMP ACRET
|
||
|
||
;COME HERE IF WE CAN'T ADD TO PREVIOUS BYTE
|
||
ADDNXT: INC B
|
||
;COME HERE IF THERE ARE NO BLOCKS IN FILE YET
|
||
ADDEMP: JSR PC,ADDBYT ;ADD A BYTE TO COUNTS
|
||
DEC C ;CHECK FOR EXACTLY 1
|
||
BEQ CNTADD ;ADD A COUNT TYPE
|
||
CMP #10,C ;LESS THAN 10 AWAY?
|
||
BHI SKGADD ;ADD A SKIP AND GET TYPE
|
||
CMP #100,C ;LESS THAN 100 AWAY?
|
||
BHI SKPADD ;ADD A SKIP TYPE
|
||
MOV MFENHD(A),C ;GET HEADER
|
||
BIC #177400,C ;GET COUNT
|
||
CMP #374,C ;IS THERE ROOM?
|
||
BGE ADDEM1 ;YES
|
||
DEC MFENHD(A) ;FLUSH BYTE ALREADY ADDED
|
||
INC MFICBY(A) ;RETURN COMMITED BYTE
|
||
ERROR FTL ;FILE TOO LONG
|
||
ADDEM1: JSR PC,ADDBYT ;MUST ADD
|
||
JSR PC,ADDBYT ;A SET ADDR TYPE
|
||
MOV B,C ;POINTER
|
||
MOVB #200,(C)+ ;THE TYPE, NO COUNT
|
||
MOVB E,(C)+ ;LOW BYTE
|
||
SWAB E ;GET HIGH BYTE
|
||
MOVB E,(C)+
|
||
MOV #ADDSET,F ;TYPE
|
||
RTS PC
|
||
|
||
CNTADD: MOVB #100,(B) ;COUNT BYTE
|
||
MOV #ADDCNT,F ;TYPE
|
||
RTS PC
|
||
|
||
SKGADD: ASH #3,C ;PUT SKIP INTO PLACE
|
||
BIS #300,C
|
||
MOVB C,(B)
|
||
MOV #ADDSKG,F
|
||
RTS PC
|
||
|
||
SKPADD: MOVB C,(B) ;SKIP BYTE
|
||
MOV #ADDNXT,F ;TYPE
|
||
RTS PC
|
||
|
||
ADDCNT: CMP #1,C ;NEXT?
|
||
BNE ADDNXT ;NOPE
|
||
MOVB (B),D ;GET OLD BYTE
|
||
BIC #177700,D ;GET COUNT SO FAR
|
||
CMP #37,D ;MAX YET?
|
||
BEQ ADDNXT
|
||
INCB (B) ;ONE MORE TIME!
|
||
MOV #ADDCNT,F ;THIS IS STILL A COUNT BYTE
|
||
RTS PC
|
||
|
||
ADDSKG: CMP #1,C ;NEXT?
|
||
BNE ADDNXT ;NOPE
|
||
MOVB (B),D ;GET OLD BYTE
|
||
BIC #177770,D ;GET COUNT
|
||
CMP #7,D ;GOING TO OVERFLOW
|
||
BEQ ADDNXT ;YES, GO ADD ANOTHER BYTE
|
||
INCB (B) ;ONE MORE
|
||
MOV #ADDSKG,F
|
||
RTS PC
|
||
|
||
ADDSET: CMP #1,C ;NEXT?
|
||
BNE ADDSE1 ;CAN'T ADD THE BLOCK
|
||
MOVB (B),D ;GET THE COUNT
|
||
BIC #177700,D ;COUNT
|
||
CMP #77,D ;WILL WE OVERFLOW
|
||
BEQ ADDSE1 ;YES
|
||
INCB (B) ;INC IT
|
||
MOV #ADDSET,F
|
||
RTS PC
|
||
ADDSE1: ADD #2,B ;SKIP THE CURENT ONE
|
||
BR ADDNXT
|
||
|
||
ADDHOL: CMP #-1,E ;ARE WE STILL HOLEY?
|
||
BNE ADDNXT ;NOPE
|
||
MOVB (B),D ;GET BYTE
|
||
BIC #177700,D ;GET COUNT
|
||
CMP #77,D ;ABOUT TO OVERFLOW?
|
||
BEQ ADDNXT
|
||
INCB (B)
|
||
MOV #ADDHOL,F
|
||
RTS PC
|
||
|
||
ADDBYT: SAVE B
|
||
MOV MFENHD(A),B ;GET HEADER
|
||
BIC #177400,B ;GET BYTE COUNT
|
||
CMP #377,B ;ABOUT TO OVERFLOW?
|
||
ERRORC EQ,FTL ;FILE TOO LONG
|
||
INC MFENHD(A) ;GOING TO ADD 1 BYTE AT LEAST
|
||
DEC MFICBY(A) ;ONE LESS COMMITED BYTE AVAILABLE
|
||
REST B
|
||
RTS PC
|
||
;GET A DISK BLOCK ON DISK (D)
|
||
;PREFERABLY CLOSE TO (E)
|
||
;IF THAT'S NOT AVAIABLE, TRY MFROVR(D)
|
||
GETDBL: JSR F,ACSAV
|
||
MOV D,C ;D IS USED FOR OTHER THINGS
|
||
TST MFFREE(C) ;ANY FREE?
|
||
ERRORC EQ,DFL ;DISK FULL
|
||
DEC MFFREE(C) ;GOING TO GRAB ONE
|
||
MOV MFBITS(C),A ;BIT TABLE FOR THIS DISK
|
||
JSR PC,ITM2PL ;LOAD IT
|
||
MOV (A),B ;NUMBER OF BLOCKS ON THE DISK
|
||
INC E ;GET ONE AFTER THIS ONE
|
||
BEQ GETDB3 ;IF THIS IS FIRST BLOCK IN A FILE, START ANYWHERE
|
||
MOV E,B ;END OF WORLD
|
||
ADD #77,B ;IS LONGEST USEFUL DISTANCE
|
||
CMP (A),B ;UNLESS IT IS BEYOND
|
||
BHIS 1$ ;THE REAL END
|
||
MOV (A),B ;IN WHCIH CASE USE THAT
|
||
1$: CMP B,E ;ARE WE AT END?
|
||
BEQ 2$ ;SKIP TRYING
|
||
JSR PC,TRYGET ;TRY TO GET ONE AFTER (E)
|
||
BNE GETDB4 ;WIN
|
||
2$: CMP MFROVR(C),E ;MIGHT THERE BE ANYTHING AFTER THE ROVER?
|
||
BLO GETDB2 ;MAYBE
|
||
CLR MFROVR(C) ;NO CHANCE, MIGHT AS WELL TRY HERE
|
||
GETDB2: MOV (A),B ;END OF WORLD
|
||
GETDB3: MOV MFROVR(C),E ;TRY AT THE ROVING POINTER
|
||
JSR PC,TRYGET ;TRY AFTER THE ROVER
|
||
BNE GETDB1 ;NOPE
|
||
CLR E ;I'LL TAKE ANYTHING!
|
||
JSR PC,TRYGET
|
||
BUGC EQ ;MFFREE SAID....
|
||
GETDB1: MOV D,MFROVR(C) ;SET ROVER AT FIRST FREE BLOCK
|
||
ADD #16.,MFROVR(C) ;MAKE IT ROVE
|
||
CMP MFROVR(C),(A) ;TOO FAR?
|
||
BLO GETDB4 ;NOPE
|
||
CLR MFROVR(C) ;BACK TOT HE BEGGINING
|
||
GETDB4: MOV D,10(P) ;CLOBBER E TO RETURN
|
||
BUGC EQ
|
||
JSR F,ACRES
|
||
JSR PC,ITM2PO
|
||
RTS PC
|
||
|
||
;TRY TO GET A BLOCK STARTING AT E AND ENDING AT B
|
||
TRYGET: SAVE <E,F>
|
||
MOV E,D ;COPY STARTING PLACE
|
||
ASHC #-3,E ;CONVERT STARTING ADDRESS
|
||
ASH #-13.,F ;INTO BYTE ADDRESS AND OFFSET
|
||
BIC #177770,F ;BYTE ADDRESS
|
||
ADD A,E ;OFFSETIFY
|
||
ADD #2,E ;INTO BIT TABLE
|
||
TRYGE1: BITB BMT(F),(E) ;FREE?
|
||
BEQ TRYGE2 ;YES, WIN
|
||
INC F ;NEXT BIT
|
||
BIC #177770,F ;ONLY 8 BITS/BYTE
|
||
BNE 1$ ;OVERFLOW?
|
||
INC E ;YES, TRY NEXT BYTE
|
||
1$: INC D ;NEXT BLOCK
|
||
CMP D,B ;OVER THE END?
|
||
BLO TRYGE1 ;NOT YET
|
||
REST <F,E>
|
||
SEZ
|
||
RTS PC
|
||
TRYGE2: BISB BMT(F),(E) ;GOBBLE THE BLOCK
|
||
REST <F,E>
|
||
CLZ ;WIN
|
||
RTS PC
|
||
;INCREMENT THE POINTER IN THE CURRENT FILE CAP, AND IF IT
|
||
;GOES BEYOND THE EOF INCREMENT THE EOF
|
||
FAEFIN: INC FAFBP(D) ;INCREMENT POINTER
|
||
FAEFTS: JSR PC,FAINTS ;TEST IT DIDN'T OVERFLOW
|
||
SAVE A
|
||
MOV FAMFI(D),A ;GET THE MFI
|
||
JSR PC,ITM2PL ;LOAD IT
|
||
CMP FAFPN(D),MFPGNO(A) ;AT EOF?
|
||
BLO FAEFT1 ;NO, BEFORE IT
|
||
BHI FAEFT2 ;NO, PAST IT
|
||
CMP FAFBP(D),MFBYTP(A) ;PAST EOF?
|
||
BLOS FAEFT1 ;NO, BEFORE IT
|
||
FAEFT2: MOV FAFPN(D),MFPGNO(A)
|
||
BIS #MFEBMB,MFLAGW(A) ;CHANGED ENTRY
|
||
MOV FAFBP(D),MFBYTP(A) ;UPDATE BYTE POINTER TOO
|
||
FAEFT1: BIT #1777,FAFBP(D) ;AT END OF BLOCK?
|
||
BNE 1$ ;NOPE
|
||
BIC #MFLSTB,MFENHD(A) ;NOT AT BEG OF BLOCK, EOF DOESN'T POINT AT EXTANT BLOCK
|
||
1$: REST A
|
||
JMP ITM2PO
|
||
.SBTTL FILE CAPABILITIES-LOWER LEVEL ROUTINES
|
||
;GET A FILE NAME FROM THE USER
|
||
;TAKES POINTER TO USER CORE IN E
|
||
;RETURNS WITH POINTER TO THE FILE NAME BLOCK IN A
|
||
;SAID BLOCK IS LOCKED, AND WILL BE RETURNED WHEN THE SWITCH IS POPED
|
||
;RETURNS WITH Z SET IF RAN OFF END OF USER'S STRING
|
||
;NO OTHER REGISTERS ARE DISTURBED
|
||
MAKFNB: JSR F,ACSAV
|
||
MAKFN1: JSR PC,GETUBY ;GET THE NEXT USER BYTE
|
||
BNE MAKFN2 ;SOMETHING THERE IF BYTE IS NON-ZERO
|
||
JSR F,ACRES ;NO NAME THERE
|
||
SEZ
|
||
RTS PC
|
||
MAKFN2: CMP #40,A ;IS IT JUST A SPACE?
|
||
BEQ MAKFN1
|
||
DEC E ;I'LL WANT THAT ONE AGAIN
|
||
MOV #FNBFRE,B ;GET A FILE NAME BLOCK
|
||
JSR PC,FREEGT ;STANDARD METHOD
|
||
SAVE A ;SAVE POINTER TO THING WE GOT
|
||
MOV #LSPRTN,A ;EXECUTE WHENEVER POPED
|
||
CLR B ;NO ITEM
|
||
JSR PC,LOCKSW ;GET A LOCK BLOCK
|
||
MOV #FNBULK,LCKWD1(A)
|
||
MOV (P),LCKWD2(A) ;SAVE POINTER TO THIS BLOCK IN THE LOCK BLOCK
|
||
REST B ;GET BACK THE POINTER
|
||
MOV #-1,FNBVER(B) ;NO VERSION YET
|
||
CLR FNBFNL(B) ;FILE NAME IS ZERO LONG
|
||
MOV B,C ;COPY POINTER TO THE BLOCK
|
||
ADD #FNBFN,C ;POINT TO THE FILE NAME PART
|
||
MOV #FNBNML,D ;MAX LENGTH OF NAME
|
||
MAKF.1: JSR PC,GETUBY ;GET THE NEXT BYTE
|
||
BEQ MAKF.2 ;GO FINISH UP IF BYTE IS ZERO
|
||
CMP #40,A ;ANOTHER TYPE OF END
|
||
BEQ MAKF.2
|
||
CMP #'#,A ;VERSION NUMBER INDICATOR
|
||
BEQ MAKF.3 ;GO PROCESS THAT
|
||
CMP #'",A ;QUOTED CHARACTER NEXT
|
||
BEQ MAKF.7 ;GO GOBBLE IT
|
||
CMP #'>,A ;GREATER THAN VERSION?
|
||
BEQ MAKF.4 ;YUP
|
||
CMP #'<,A ;LESS THAN?
|
||
BEQ MAKF.5 ;YUP
|
||
MAKF.8: INC FNBFNL(B) ;ONE MORE CHAR IN FILE NAME
|
||
MOVB A,(C)+ ;NOTHING SPECIAL, PUT IT INTO THE STRING
|
||
SOB D,MAKF.1 ;KEEP LOOKING FOR THE END
|
||
ERROR FNTL ;FILE NAME TOO LONG
|
||
MAKF.4: MOV #-2,D ;THE > MARKER
|
||
BR MAKF.9 ;GO PLACE IT
|
||
MAKF.5: MOV #-3,D ;THE < MARKER
|
||
MAKF.9: MOV D,FNBVER(B) ;PLACE IT IN THE BLOCK
|
||
MAKF.2: BISB #200,-(C) ;MARK THE END OF THE NAME
|
||
TST A ;IF THE LAST BYTE WAS A ZERO
|
||
BNE 1$
|
||
DEC E ;WE WANT TO BE SURE TO SEE IT THE NEXT TIME
|
||
1$: MOV E,FNBFNE(B) ;SAVE THE END POINTER INTO THE USER
|
||
MOV B,(P) ;RETURN THE POINTER TO THE BLOCK IN A
|
||
JMP ACRETC
|
||
|
||
MAKF.7: JSR PC,GETUBY ;GET A QUOTED CHARACTER
|
||
BR MAKF.8 ;AND STUFF IT INTO THE NAME
|
||
;COME HERE TO GET A VERSION NUMBER
|
||
MAKF.3: CLR D ;START NUMBER AT ZERO
|
||
MAKF.6: JSR PC,GETUBY ;GET THE NEXT BYTE
|
||
BEQ MAKF.9 ;GO INSERT NUMBER INTO BLOCK IF BYTE IS ZERO
|
||
CMP #40,A ;ANOTHER TERMINATOR?
|
||
BEQ MAKF.9 ;YUP
|
||
SUB #'0,A ;MAKE INTO BCD
|
||
ERRORC LT,BFN ;BAD FILE NAME, NON-NUMERIC
|
||
CMP #9.,A ;IS IT A NUMBER?
|
||
ERRORC LT,BFN ;BAD FILE NAME AGAIN
|
||
MUL #10.,D ;CONVERT TO DECIMAL
|
||
ERRORC CS,BFN ;NUMBER TOO BIG
|
||
ADD A,D
|
||
BR MAKF.6 ;GET NEXT DIGIT
|
||
;GET A BYTE FROM THE USER USING E AS A POINTER
|
||
;RETURN THE BYTE IN A AND INCREMENT E
|
||
;AND SET Z IF THE BYTE IS ZERO
|
||
GETUBY: SAVE E ;SAVE THE POINTER
|
||
BIC #1,E ;MAKE IT EVEN
|
||
MFPD (E) ;GET WORD FROM USER
|
||
BIT #1,2(P) ;WAS ORIGINAL POINTER ODD?
|
||
BEQ 1$ ;IF NOT, WORD ON STACK IS OK
|
||
SWAB (P) ;REVERSE BYTES TO GET ODD ONE
|
||
1$: REST <A,E> ;GET USERS WORD AND OLD POINTER
|
||
INC E ;UPDATE POINTER
|
||
BIC #177400,A ;CLEAR TOP BYTE
|
||
RTS PC
|
||
|
||
;PUT A BYTE INTO THE USERS CORE
|
||
;TAKE THE BYTE IN A, THE POINTER TO USER CORE IN E
|
||
;INCREMENTS E
|
||
;SETS Z IF ZERO BYTE TRANSFERED
|
||
PUTUBY: SAVE E
|
||
BIC #1,E ;MAKE THE POINTER EVEN
|
||
MFPD (E) ;GET WORD BYTE IS GOING INTO
|
||
BIT #1,2(P) ;WAS ORIGINAL ODD?
|
||
BNE 1$ ;YUP
|
||
MOVB A,(P) ;INSERT BYTE
|
||
BR 2$
|
||
1$: MOVB A,1(P) ;INSERT INTO ODD BYTE
|
||
2$: MTPD (E) ;RETURN MODIFIED WORD
|
||
REST E
|
||
INC E
|
||
TST A
|
||
RTS PC
|
||
|
||
;GET A WORD FROM THE USER, POSSIBLY ON AN ODD BOUNDARY
|
||
;RETURN THE WORD IN A
|
||
;AND ADD 2 TO E
|
||
GETWRD: JSR PC,GETUBY ;FIRST BYTE
|
||
SAVE A
|
||
JSR PC,GETUBY ;SECOND BYTE
|
||
SWAB A ;IS HIGH PART
|
||
BIS (P)+,A ;GET FULL WORD
|
||
RTS PC
|
||
|
||
;WHEN SWITCH IS POPED RETURN NODE TO FREE LIST
|
||
FNBULK: MOV FNBFRE,@LCKWD2(B) ;CLOBBER NODE BEING RETURNED
|
||
MOV LCKWD2(B),FNBFRE ;POINT FREE POINTER AT IT
|
||
RTS PC
|
||
;ROUTINE TO CREATE AN MFI AND RETURN POINTER TO IT IN A
|
||
;CLEAR Z IF YOU WIN
|
||
CRMFI: SAVE B
|
||
MOV #MFLEN,A ;THE LENGTH OF A BASIC MFI
|
||
JSR PC,CRITEM ;CREATE IT
|
||
BEQ CRMFI1 ;FAILED
|
||
SAVE B ;SAVE THE POINTER TO IT
|
||
JSR PC,CLITEM ;CLEAR OUT THE NEW ITEM
|
||
JSR PC,ITM0PO ;RECOVER FROM CLITEM
|
||
MOV (P),A ;GET BACK THE ITEM NUMBER
|
||
JSR PC,ITM2LD ;LOAD IT UP
|
||
MOV #ITMF,(A) ;YOU ARE AN MFI
|
||
MOV #MFLEN_6,MFELN(A) ;CURRENTLY THIS LONG
|
||
MOV #1,MFFREF(A) ;PRESUMABLY, THERE WILL SOON BE A CAPABILITY
|
||
MOV #MFOPNB,MFLAGW(A) ;ENTRY BEING OPENED
|
||
MOV #LSPPCL,A ;RUN ROUTINE ON PCLOSER
|
||
MOV (P),B ;FOR THIS ITEM
|
||
JSR PC,LOCKSW ;GET A LOCK BLOCK
|
||
MOV #MFIUNL,LCKWD1(A) ;MUST DO SPECIAL THINGS TO UNLOCK
|
||
REST <A,B> ;GET OLD B AND NEW A
|
||
CLZ ;INDICATE SUCCESS
|
||
RTS PC
|
||
CRMFI1: REST B
|
||
SEZ ;FAILURE
|
||
RTS PC
|
||
|
||
;ROUTINE TO FLUSH A REFERENCE TO AN MFI BY A FA OR INFERIOR DIRECTORY
|
||
;CALL WITH MFI ITEM # IN A
|
||
MFIDEL: SAVE A
|
||
JSR PC,ITM2PL ;LOAD UP THE ITEM
|
||
MFIDE3: DEC MFFREF(A) ;ONE LESS REFERENCE
|
||
BNE MFIDE1 ;BUT STILL NON-ZERO
|
||
BIT #MFEBMB,MFLAGW(A) ;HAS THE ENTRY BE MODIFIED?
|
||
BEQ MFIDE2 ;NO, IT CAN GO QUIETLY
|
||
BIT #MFDWDB,MFLAGW(A) ;DELETE WHEN DONE?
|
||
BNE MFIDE2 ;YUP, DON'T PUT IT BACK
|
||
INC MFFREF(A) ;IN CASE OF PCLOSER
|
||
JSR PC,MFIINS ;INSERT ENTRY INTO THE DIRECTORY
|
||
BR MFIDE3 ;RUN THAT BY AGAIN
|
||
|
||
MFIDE2: JSR PC,MFIDFL ;FLUSH THE STRANGE WAY, IF NESSESARY
|
||
BEQ MFIDE1 ;IT WAS
|
||
TST MFPBRF(A) ;ANY PAGES LEFT?
|
||
BNE MFIDE1 ;YES, DON'T FLUSH MFI
|
||
JSR PC,MFIUN ;BYE-BYE MFI
|
||
MFIDE1: JSR PC,ITM2PO
|
||
REST A
|
||
RTS PC
|
||
|
||
;ROUTINE TO FLUSH THE REFERENCE TO A FILE BY A PAGE BLOCK
|
||
;CALL WITH PB INDEX IN B
|
||
MFIPBD: JSR F,ACSAV
|
||
MOV PBMFIP(B),A ;THE MFI THIS PB IS FROM
|
||
JSR PC,ITM2PL
|
||
DEC MFPBRF(A) ;ONE LESS
|
||
BNE MFIPB1 ;STILL MORE THOUGH
|
||
TST MFFREF(A) ;ANY OTHER REFERENCES?
|
||
BNE MFIPB1 ;YUP
|
||
JSR PC,MFIUN ;FLUSH IT
|
||
MFIPB1: JMP ACRTP2
|
||
|
||
;THIS WILL FLUSH THE MFIUPT OF A DIRECTORY IF THERE IS
|
||
;ONE AND THERE IS ONLY ONE PB STILL HANGING AROUND
|
||
;AND THE FUPT FOR THE DIR POINTS AT ITSELF
|
||
;IF ALL THESE CONDIONS ARE TRUE, THEN DELETEING THE
|
||
;FUPT WILL CAUSE THE MFI TO GET FLUSHED BY A
|
||
;(POSSIBLY RECURSIVE) CALL THE MFIPBD, SO THAT
|
||
;THE CALLER SHOULD NOT TRY TO FINSH THE DELETEION
|
||
;HIMSELF. THIS ROUTINE SETS Z IF THIS IS THE CASE
|
||
MFIDFL: SAVE <B,C>
|
||
TST MFIUPT(A) ;IS THERE A MFIUPT (MEANING THIS IS A DIR)
|
||
BEQ MFIDF1 ;NOPE
|
||
MFIDF3: CMP #1,MFPBRF(A) ;IS THERE EXACTLY ONE PB?
|
||
BUGC NE ;UGH, HOW DO YOU GET MORE THAN ONE PB FOR A DIR?
|
||
MOV MFIUPT(A),B ;GET THE FUPT
|
||
MOV B,C ;COPY
|
||
BIC #GIPBIT,C ;MAKE INTO ADDRESS
|
||
CMP UPTGIP(C),B ;DOES IT POINT AT ITSELF?
|
||
BNE MFIDF1 ;NO, IT CAN STAY
|
||
MOV UPTPBP(C),B ;GET POINTER TO TH EPB
|
||
BIT #PBVAS,PBFLAG(B) ;IS IT VALID AT SOURCE?
|
||
BNE MFIDF2 ;YES, WIN
|
||
JSR PC,PBSWPI ;SWAP IN THE PAGE
|
||
JSR PC,PBVLSR ;VALIDATE AT SOURCE
|
||
BR MFIDF3 ;NOW CHECK THINGS AGAIN
|
||
MFIDF2: MOV C,B ;GET BACK FUPT
|
||
BIS #GIPBIT,B ;WELL, ALMOST
|
||
;WELL, ALMOST. HAVE TO WORRY ABOUT THE GUY ABOVE US GETTING FLUSHEDD
|
||
;GUESS WE BETTER DO IT OURSELVES...
|
||
JSR PC,UPTDL ;THIS OUGHT TO TAKE CARE OF EVERYTHING... (AND NOT HANG)
|
||
REST <C,B>
|
||
SEZ
|
||
RTS PC
|
||
MFIDF1: REST <C,B>
|
||
CLZ
|
||
RTS PC
|
||
|
||
;PCLOSER ROUTINE TO FLUSH AN INCOMPLETE MFI
|
||
MFIUNL: BIT #MFOPNB,MFLAGW(A) ;WE BETTER NOT BE DONE OPENING!
|
||
BUGC EQ ;OOPS
|
||
JSR PC,MFIUNX ;FLSUH THE MFI
|
||
RTS PC
|
||
|
||
|
||
;AS MFIUN, BUT FLUSH THE MFIUPT IF IT EXISTS ALSO
|
||
MFIUNX: SAVE <A,C,D,E>
|
||
MOV MFIUPT(A),B ;IF THERE IS AN ASSOCIATED FUPT...
|
||
BEQ MFIUL1 ;NOPE, NO NEED TO GET RID OF IT
|
||
JSR PC,UPTDL ;BETTER NOT HANG...
|
||
BR MFIUL1
|
||
;FLUSH A MFI THAT IS READY FOR FLUSHING, I.E. IS ASSUMED SAFELY PUT BACK INTO
|
||
;THE DIRECTORY AND ALL ASSOCIATED PAGES ARE WINNING, ETC.
|
||
;CALL WITH THE MFI LOADED INTO ITEM2 AND THE ADDRESS IN A
|
||
MFIUN: SAVE <A,C,D,E>
|
||
MFIUL1: MOV MFDISK(A),D ;GET THE DISK NUMBER
|
||
BIT #MFDWDB,MFLAGW(A) ;SHOULD THE FILE BE DELETED?
|
||
BEQ 1$ ;NOPE
|
||
BIT #MFSHRB,MFENHD(A) ;DOES IT SHARE BLOCKS?
|
||
BNE 1$ ;YES, DON'T RELEASE THEM
|
||
JSR PC,MFIBFL ;YES, GO FLUSH THE BLOCKS
|
||
1$: MOV MFDLNK(A),C ;THE ONE IT POINTS TO
|
||
MOV MFBLNK(D),A ;GET THE FIRST ITEM IN THE LIST FOR THIS DISK
|
||
MOV ITEM2,E ;GET ITEM NUMBER OF THE BEING FLUSHED MFI
|
||
CMP E,A ;FIRST ON THE LIST?
|
||
BEQ MFIUL2 ;YUP, THIS IS EASY
|
||
JSR PC,ITM2PL ;LOAD THE FIRST ON THE LIST
|
||
MFIUL3: CMP E,MFDLNK(A) ;THIS ONE?
|
||
BEQ MFIUL4 ;YUP
|
||
MOV MFDLNK(A),A ;GET NEXT
|
||
BUGC EQ ;END OF LIST?
|
||
JSR PC,ITM2LD
|
||
BR MFIUL3
|
||
MFIUL4: MOV C,MFDLNK(A) ;UNLINK THE BLOCK
|
||
JSR PC,ITM2PO
|
||
BR MFIUL5
|
||
MFIUL2: MOV C,MFBLNK(D) ;POINT ONE FURTHER DOWN THE LIST
|
||
MFIUL5: MOV ITM2A,A
|
||
MOV MFBAKP(A),A ;POINTER TO PARENT
|
||
BEQ MFIUL6 ;KNOW PARENT, BETTER BE A ROOT
|
||
JSR PC,MFIDEL ;RECURSE TO FLUSH A REFERENCE TO THE ABOVE DIRECTORY
|
||
MFIUL6: MOV ITEM2,A ;NOW GET THE ITEM NUMBER
|
||
JSR PC,DLITEM ;AND FLUSH THE MFI
|
||
REST <E,D,C,A>
|
||
RTS PC
|
||
;ROUTINE TO CONVERT AN MFI DESCRIBING THE FIRST BLOCK OF A DIRECTORY
|
||
;TO AN MFI FOR THE WHOLE DIRECOTRY
|
||
;THIS IS DONE BY READING THE SELF ENTRY IN THE DIRECTORY'S FIRST BLOCK
|
||
;AND COPYING IT INTO THE MFI
|
||
;A POINTS TO THE MFI BEING HACKED
|
||
DIRENT: JSR F,ACSAV
|
||
CLR C ;FOR PAGE ZERO
|
||
JSR PC,MAKFUP ;GET AN FUPT
|
||
JSR PC,PCLCLR ;WE'RE SAFE (I HOPE)
|
||
CLRB UPTSTL(C) ;FLUSH START AND LENGTH TO BE FOR ONE BLOCK PAGE
|
||
MOV UPTPBP(C),B ;GET THE PB
|
||
CLRB PBLEN(B) ;SAME FOR PB
|
||
JSR PC,ITM2PL ;LOAD THE MFI
|
||
BIS #GIPBIT,C ;CONVERT FUPT ADDRESS TO A GIP
|
||
MOV C,MFIUPT(A) ;FUPT FOR THE DIRECTORY
|
||
JSR PC,ITM2PO ;FLUSH THE MFI
|
||
MOV C,A ;COPY GIP TO THE PARTIAL DIRECTROY
|
||
JSR PC,ITM2PL ;LOAD UP THE DIRETORY
|
||
MOV A,E ;COPY POINTER TO IT
|
||
MOV (A),D ;HEADER WORD OF SELF ENTRY
|
||
MOV (P),A ;GET THE MFI AGAIN
|
||
JSR PC,MFIEXP ;GO EXPAND MFI IF NEEDED
|
||
ADD #MFENHD,A ;POINT TOT THE RIGHT PLACE IN THE MFI
|
||
ASR D ;CONVERT TO WORD COUNT
|
||
1$: MOV (E)+,(A)+ ;COPY A WORD
|
||
SOB D,1$
|
||
MOV ITM1A,A ;POINT TO MFI AGAIN
|
||
BIC #17000,MFENHD(A) ;FLUSH SELF TYPE
|
||
BIS #MFDIRE,MFENHD(A) ;MAKE IT A DIR ENTRY
|
||
JSR PC,ITM1PO ;POP MFI
|
||
JSR PC,ITM2PO ;POP DIRECTORY
|
||
MOV (P),A ;GET BACK MFI POINTER
|
||
JSR PC,ITM2PL ;LOAD IT
|
||
CLR C ;PAGE NUMBER DESIRED
|
||
MOV MFIUPT(A),A ;GET THE FUPT FOR THE DIR
|
||
BIC #GIPBIT,A ;CONVERT TO AN ADDRESS
|
||
MOV A,F ;SAVE THAT
|
||
MOV UPTPBP(A),B ;GET THE PAGE BLOCK POINTER FOR THE FUPT
|
||
BIS #PBNOSW!PBWCHK,(B) ;NEVER ASSIGN SWAP SPACE TO DIR, ALWAYS WRITE-CHECK IT
|
||
JSR PC,SWPPG ;FLUSH THE THING FROM CORE
|
||
JSR PC,PCLCLR ;DON'T PCLOSER SELF
|
||
MOV B,A ;COPY PB POINTER
|
||
JSR PC,FILFPB ;FILL IN TH EDISK ADDRESSES
|
||
MOVB PBFLEN(B),A ;GET THE LENGTH OF THIS FILE PAGE
|
||
DEC A ;NOW THIS IS NUMBER OF VALID BLOCKS-1
|
||
MOVB A,PBLEN(B) ;WHICH IS ALWAYS THE LENGTH OF THE PAGE
|
||
MOV ITM2A,F ;POINTER TO MFI
|
||
MOVB A,UPTSTL(F) ;FUPT'S LENGTH IS WHOLE THING AND START IS ZERO
|
||
INC A ;NOW NUMBER OF BLOCKS
|
||
MOV A,MFIDLN(F) ;IN CASE SOMEONE IS EVER INTERESTED....
|
||
ASH #10.,A ;CONVERT TO BYTES
|
||
SUB MFBYTP(F),A ;SUBTRACT NUMBER KNOW TO BE USED
|
||
MOV A,MFIUCF(F) ;THAT IS THE NUMBER OF "UNCOMMITED FREE BYTES"
|
||
BIC #MFOPNB,MFLAGW(F) ;DIRECTORY IS NOW OPEN FOR BUSINESS..
|
||
BIS #.FADIR,MFLAGW(F) ;NOTE IN MFI THAT THIS IS A DIR
|
||
JSR PC,ITM2PO
|
||
JMP ACRET
|
||
|
||
;TRY TO EPAND THE MFI IF IT WILL NEED TO BE EXPANDED
|
||
;TO TAKE AN ENTRY OF LENGTH IN D
|
||
;MFI NUMBER IN A
|
||
;D GETS INCREMENTED AND BIC #177400
|
||
MFIEXP: SAVE B
|
||
BIC #177400,D ;GET LENGTH OF SELF ENTRY IN BYTES
|
||
INC D ;MUST ROUND IT TO WORDS
|
||
JSR PC,ITM1PL ;LOAD THE MFI
|
||
CLR B
|
||
ADD D,B ;GET THE TOTAL LENGTH NEEDED FOR THE MFI
|
||
ADD #MFENHD,B ;ADD IN THE OVERHEAD
|
||
CMP B,MFELN(A) ;LONGER THAN THE MFI IS NOW?
|
||
BLT DIREX1 ;NO, WE'RE SAFE!
|
||
MOV B,A ;COPY THE NEEDED LENGTH
|
||
ASH #-6,A ;MAKE IT INTO 32 WORD BLOCKS
|
||
MOV ITEM1,B ;GET BACK THE ITEM NUMBER
|
||
JSR PC,ITM1PO ;CAN'T HAVE THIS PUSHED IF WE HANG
|
||
JSR PC,EXITEM ;EXPAND THE MFI
|
||
ERRORC EQ,NIS ;NOT ENOUGH SPACE
|
||
SAVE A ;SAVE THE NEW LENGTH
|
||
MOV B,A ;ITEM NUMBER AGAIN
|
||
JSR PC,ITM1PL ;LOAD AGAIN
|
||
REST B
|
||
INC B ;0=>1
|
||
ASH #6,B ;CONVERT TO BYTES
|
||
MOV B,MFELN(A) ;SET THE NEW LENGTH
|
||
DIREX1: REST B
|
||
RTS PC
|
||
|
||
;MAKE AN FUPT FOR A PAGE OF A FILE
|
||
;CALL WITH MFI POINTER IN A, PAGE NUMBER IN C
|
||
;RETURN POINTER TO FUPT IN C
|
||
MAKFUP: JSR F,ACSAV
|
||
MOV #FUPTFR,B ;FREE POINTER FOR FUPTS
|
||
JSR PC,FREEGT ;GET A FREE ONE
|
||
JSR PC,FREELK ;LOCK IT IN CASE OF PCLOSER
|
||
MOV #UPTEXB,(A) ;IT EXISTS, AT LEAST
|
||
CLR UPTGIP(A) ;DOESN'T HAVE A GIP POINTER
|
||
CLR FUPTPR(A) ;NO USER EITHER
|
||
MOV A,4(P) ;SAVE TO RETURN TO THE CALLER
|
||
MOV A,D ;SAVE POINTER TO FUPT
|
||
MOV (P),A ;GET BACK MFI POINTER
|
||
JSR PC,MAKFPB ;GO GET A PB FOR THAT PAGE
|
||
MOV B,UPTPBP(D) ;PB POINTER
|
||
MOV PBGIP(B),E ;GET THE POINTER TO THE CURRENT CIRCULAR LIST
|
||
BEQ MAKFU1 ;BRANCH IF THERE ISN'T ONE
|
||
MOV E,B ;COPY THE GIP
|
||
JSR PC,UPTPLD ;GET A GOOD POINTER TO THE GIP
|
||
MOV UPTGIP(B),UPTGIP(D) ;POINT THE NEW FUPT INTO THE LIST
|
||
BIS #GIPBIT,D ;MAKE A GIP POINTER FOR THE FUPT
|
||
MOV D,UPTGIP(B) ;AND POINT OLD GIP AT IT
|
||
JSR PC,ITM2PO ;PUSHED BY UPTPLD
|
||
BR MAKFU2 ;KEEP GOING
|
||
MAKFU1: MOV D,E ;COPY FUPT POINTER
|
||
BIS #GIPBIT,E ;MAKE A GIP OUT OF ONE OF THEM
|
||
MOV E,UPTGIP(D) ;POINT TO YOURSELF
|
||
MOV E,PBGIP(B) ;POINT TH EPB AT THIS NEW CIRCULAR LIST
|
||
MAKFU2: JSR PC,LSWPOP ;FLUSH THE LOCK ON THE PB
|
||
JSR PC,LSWPOP ;AND THE FUPT
|
||
JMP ACRET
|
||
|
||
;MAKE UP A FUPT FOR THE PAGE # IN C OF THE FILE
|
||
;WHOSE MFI IS IN A WITH START AND LENGTH IN E AND F
|
||
;RETURN POINTER TO THE FUPT IN C, UNLESS BLOCKS DON'T
|
||
;ALL EXIST, IN WHCIH CASE SET Z
|
||
MAKFPG: JSR F,ACSAV
|
||
MOV 12(P),F ;CALL TO ACSAV CLOBBERS F, RESTORE IT
|
||
JSR PC,MAKFUP ;MAKE UP THE FUPT
|
||
BIS #GIPBIT,C ;MAKFUP DOESN'T SET IT
|
||
MOV C,4(P) ;SAVE FOR THE CALLER
|
||
MOV #LSPPCL,A ;RUN ON PCLOSER
|
||
CLR B ;NO ITEM
|
||
JSR PC,LOCKSW
|
||
MOV #UPTPCD,LCKWD1(A) ;ROUTINE TO RUN
|
||
MOV C,LCKWD2(A) ;ON THIS UPT
|
||
BIC #GIPBIT,C ;CONVERT TO ADDRESS
|
||
MOV UPTPBP(C),B ;GET POINTER TO THE PB
|
||
MOV E,C ;START
|
||
MOV F,D ;LENGHT
|
||
JSR PC,PBSETU ;FIX UP THE PB
|
||
BEQ MAKFP1 ;LOSE
|
||
MOV 4(P),E ;GET BACK FUPT
|
||
BIC #GIPBIT,E ;CONVERT TO ADDRESS
|
||
ASH #UPTSSH,C ;GET START INTO RIGHT PLACE
|
||
BIS C,D ;COMBINE START AND LENGTH
|
||
MOVB D,UPTSTL(E) ;SET UP THE START AND LENGTH
|
||
JSR PC,PCLCLR ;SAVE NOW ON THE FPB
|
||
JMP ACRETC
|
||
|
||
MAKFP1: JSR PC,FRELSE ;FLUSH THE UPT
|
||
JMP ACRETS
|
||
|
||
;PCLOSER ROUTINE TO DELETE AN ITEM
|
||
;THIS WILL BE A REAL PROBLEM IF THIS EVER HANGS
|
||
UPTPCD: MOV LCKWD2(B),B
|
||
;FALL INTO UPT DEFERED DELETE
|
||
UPTDDL: SAVE <A,B>
|
||
MOV #DLUFRE,B
|
||
JSR PC,FREEGT ;THIS BETTER NOT HANG
|
||
MOV (P),DLUUPT(A) ;PUT IT IN THE NODE
|
||
CLR (A) ;FLUSH LINK WORD IN THE NODE
|
||
MOV #DLULST,B ;LIST OF NODES TO ACT ON
|
||
JSR PC,BLISTE ;GO TO THE END OF THE LIST
|
||
MOV A,(B) ;CLOBBER THIS NODE ONTO END OF LIST
|
||
REST <B,A>
|
||
RTS PC ;NOW HOPE THE SYSTEM DOES THE WORK
|
||
;FIND OR MAKE E A PB FOR A PAGE IN A FILE
|
||
;CALL WITH ITEM POINTER TO THE MFI IN A
|
||
;PAGE NUMBER DESIRED IN C
|
||
;RETURNS WITH POINTER TO PB IN B
|
||
MAKFPB: JSR F,ACSAV
|
||
JSR PC,FPBGET ;GET A BLOCK IN CASE WE NEED ONE
|
||
MOVB #-1,PBLEN(B) ;FLUSH THE LENGTH
|
||
MOV B,2(P) ;SAVE IT FOR LATER AND TO RETURN TO USER
|
||
MOV A,PBMFIP(B) ;POINT THE PB AT THE ASSOCIATED MFI
|
||
JSR PC,ITM2PL ;LOAD UP THE MFI
|
||
MOV MFIPB(A),B ;POINTER TO FIRST PB
|
||
BEQ MAKFP4 ;COULDN'T FIND ANY PBS
|
||
MAKFP6: CMP C,PBFPNO(B) ;IS THIS THE PAGE WE'RE LOOKING FOR?
|
||
BEQ MAKFP5 ;YUP, WIN
|
||
MOV PBFLNK(B),B ;GET THE NEXT ONE
|
||
BNE MAKFP6 ;TRY THE NEXT ONE IF IT EXISTS
|
||
MAKFP4: MOV 2(P),B ;GET THE PB POINTER BACK
|
||
MOV B,A ;MAKE A COPY OF IT
|
||
JSR PC,FILFPB ;FILL UP THE FPB WITH DISK ADDRESES
|
||
MOV ITM2A,A ;NOW LINK THE NEW THING
|
||
MOV MFIPB(A),PBFLNK(B) ;ONTO THE EXISTING LIST
|
||
MOV MFDISK(A),PBSDSK(B) ;COPY DISK NUMBER OUT OF MFI
|
||
MOV B,MFIPB(A) ;OF PBS FOR THIS FILE
|
||
INC MFPBRF(A) ;ONE MORE PB FOR THIS MFI
|
||
JSR PC,LSWPOP ;FLUSH SIMPLE LOCK ON BLOCK
|
||
MOV #FPBPFL,E ;PCLOSER ROUTINE IF WE GOT A NEW BLOCK
|
||
MAKFP9: MOV #LSPPCL,A ;RUN ROUTINE ON PCLOSER
|
||
CLR B ;NO ITEM
|
||
JSR PC,LOCKSW ;GET A LOCK BLOCK
|
||
MOV E,LCKWD1(A) ;ROUTINE
|
||
MOV 2(P),LCKWD2(A) ;FPB POINTER
|
||
JMP ACRTP2
|
||
MAKFP8: RTS PC
|
||
|
||
MAKFP5: JSR PC,PCLSET ;IN CASE WE HANG BEFORE WE HAVE IT SAFELY TUCKED AWAY
|
||
JSR PC,FRELSE ;FLUSH THE PB WE'RE NOT USING
|
||
MOV B,2(P) ;RETURN POINTER TO EXISTING PB
|
||
MOV #MAKFP8,E ;DUMMY PCLOSER IF WE GOT OLD BLOCK
|
||
BR MAKFP9
|
||
|
||
;FILL UP A FPB WITH DISK BLOCK NUMBERS
|
||
;CALL WITH PAGE NUMBER DESIRED IN C
|
||
;POINTER TO PB IN A
|
||
;CLOBBERS D AND E
|
||
FILFPB: ADD #PBSDA,A ;TO POINT AT THE BLOCK NUMBERS
|
||
ASH #3,C ;PAGE NUMBER=>BLOCK NUMBER
|
||
JSR PC,MFBLKG ;INITIALIZE COROUTINE AND VARIABLES
|
||
FILFP1: CMP C,D ;IS THSI THE RIGHT FIRST BLOCK NUMBER?
|
||
BEQ FILFP2 ;YUP, START GOBBLING
|
||
JSR PC,@(P)+ ;JUMP BACK
|
||
BR FILFP1 ;TO TRY AGAIN
|
||
FILFP2: ASH #-3,C ;BACK TO PAGE NUMBER
|
||
MOV C,PBFPNO(B) ;THIS IS THE PAGE FOR THIS PB
|
||
MOV #8.,C ;FOR 8 BLOCKS
|
||
CLRB PBFLEN(B) ;ZERO VALID BLOCKS
|
||
FILFP3: MOV E,(A)+ ;STORE IN THE PB
|
||
CMP #-1,E ;VALID BLOCK?
|
||
BEQ 1$ ;NOPE
|
||
INCB PBFLEN(B) ;ONE MORE THEN
|
||
1$: JSR PC,@(P)+ ;GET NEXT BLOCK
|
||
SOB C,FILFP3 ;CONTINUE TILL 8 DONE
|
||
TST (P)+ ;FLUSH COROUTINE LINK
|
||
RTS PC
|
||
|
||
;PCLOSER ROUTINE TO FLUSH A FILE PAGE BLOCK
|
||
;WHICH HAS NOT YET BECOME ASSOCIATED WITH AN FUPT
|
||
FPBPFL: MOV LCKWD2(B),B ;POINTER TO FUPT
|
||
TST PBGIP(B) ;DOES THE PAGE HAVE A GIP POINTER?
|
||
BUGC NE ;HAVE TO MORE THAN THIS THEN!
|
||
FPBFR: JSR PC,PBNSWP ;MAKE SURE IT IS NOT ON SWAP OUT LIST
|
||
BIT #PBLOCK!PBDISK,PBFLAG(B) ;IS THE PAGE MOVING?
|
||
BUGC NE ;ARG!
|
||
BIT #PBFILE,PBFLAG(B) ;REALLY A FILE PAGE?
|
||
BEQ PBFR ;FREE A REGULAR PB
|
||
MOV PBMFIP(B),A ;THE MFI FOR THIS FPB
|
||
BEQ FPBPF6 ;NONE
|
||
JSR PC,ITM2PL ;LOAD IT UP
|
||
CMP B,MFIPB(A) ;IS THIS ONE THE FIRST IN THE LIST
|
||
BEQ FPBPF1 ;YES
|
||
MOV MFIPB(A),A ;NO, CONTINUE DOWN LIST
|
||
FPBPF3: BUGC EQ ;RAN OFF THE END
|
||
CMP PBFLNK(A),B ;THIS ONE?
|
||
BEQ FPBPF2 ;YUP
|
||
MOV PBFLNK(A),A ;NEXT?
|
||
BR FPBPF3
|
||
FPBPF1: MOV PBFLNK(B),MFIPB(A) ;POINT IT AT THE NEXT IN THE LIST
|
||
BR FPBPF5 ;CONTINUE ON
|
||
FPBPF2: MOV PBFLNK(B),PBFLNK(A) ;LINK ME OUT OF THE LIST
|
||
FPBPF5: JSR PC,ITM2PO
|
||
FPBPF6: MOV FPBFRE,(B) ;MAKE THE NEW FREE ONE POINT AT THE FREE LIST
|
||
MOV B,FPBFRE ;NEW FREE LIST
|
||
RTS PC
|
||
PBFR: MOV PBFREL,(B) ;NEW FREE POINTS AT OLD
|
||
MOV B,PBFREL ;LIST POINTS AT NEW
|
||
RTS PC
|
||
;THIS ROUTINE TAKES A MFI IN ITEM2 AND SPITS OUT BLOCK NUMBERS
|
||
;FOR IT. IT USES THE GLOBAL VARIABLES ENTPNT, ENTEND AND ENDCNT,
|
||
;SO YOU BETTER NOT SCHEDULE OUT OF IT. IT MAINTAINS THE BLOCK NUMBER
|
||
;IN THE FILE IN D AND THE PYHSICAL BLOCK NUMBER IN E
|
||
;NON-EXISTANT BLOCKS COME BACK AS -1
|
||
;AFTER THE FIRST CALL IT IS A CO-ROUTINE
|
||
MFBLKG: SAVE <A,F>
|
||
CLR D ;START AT ZERO IN THE FILE
|
||
MOV #-1,E ;AND ZERO ON THE DISK (WELL, WILL BE AFTER FIRST INC)
|
||
MOV ITM2A,F ;POINT TO THE MFI
|
||
MOV F,A ;COPY POINTER
|
||
ADD #MFVERN+2,F ;POINT TO NAME IF NO TIME, DATE AND EOF
|
||
BIT #MFEOFB,MFENHD(A) ;TIME DATE ETC?
|
||
BEQ 1$ ;NOPE
|
||
ADD #10,F ;SKIP IT
|
||
1$: BIT #MFACCB,MFENHD(A) ;ACCESS CODES?
|
||
BEQ MFBLK2 ;NOPE
|
||
MFBLK1: ADD #3,F ;SKIP FIRST CODE GROUP
|
||
TSTB -1(F) ;WAS THAT THE LAST ONE?
|
||
BLT MFBLK2 ;AFRAID NOT
|
||
MFBLK2: TSTB (F)+ ;LAST CHAR OF NAME?
|
||
BGE MFBLK2 ;NOT YET
|
||
MOV F,ENTPNT ;THIS POINTS TO THE FIRST DESCRIPTOR BYTE
|
||
MOV MFENHD(A),F ;GET THE HEADER WORD
|
||
BIC #177400,F ;GET THE ENTRY LENGTH
|
||
ADD A,F ;POINT TO THE FIRST BYTE NOT IN THIS ENTRY
|
||
ADD #MFENHD,F ;NOW IT POINTS TO THE END
|
||
MOV F,ENTEND ;SAVE THAT QUANTITY
|
||
REST <F,A> ;NOW FOR THE MAIN LOOP
|
||
MFBLK3: CMP ENTPNT,ENTEND ;ARE WE AT OR PAST THE END?
|
||
BHIS MFBLK8 ;YUP, GIVE HIM -1'S
|
||
SAVE <A,B>
|
||
MOVB @ENTPNT,A ;GET A DESCRIPTOR BYTE
|
||
MOV A,B ;IN TWO PALCES
|
||
INC ENTPNT ;POINT TO NEXT ONE
|
||
BIC #177477,A ;GET THE TYPE
|
||
ASH #-5,A ;AS A BYTE INDEX
|
||
BIC #177700,B ;ALSO GET THE DATA BITS
|
||
INC E ;ALWAYS GO TO THE NEXT BLOCK
|
||
JMP @MFBLTB(A) ;GO TO THE RIGHT PLACE
|
||
|
||
;COME HERE FOR A SKIP AND GRAB ONE TYPE
|
||
MFBSKP: ADD B,E ;SKIP
|
||
REST <B,A>
|
||
JSR PC,@(P)+ ;GRAB ONE
|
||
INC D ;NEXT BLOCK IN FILE
|
||
BR MFBLK3 ;GO GET NEXT BLOCK
|
||
|
||
;COME HERE FOR A GRAB N BLOCKS TYPE
|
||
MFBGET: MOV B,ENTCNT ;GET THAT MANY BLOCKS
|
||
CMP #40,B ;MAYBE REALLY A HOLE IN THE FILE
|
||
BLE MFBGE2 ;YES, GO HOLIFY
|
||
MFBGE4: REST <B,A>
|
||
MFBGE1: JSR PC,@(P)+ ;GET ONE BLOCK
|
||
INC D ;NEXT IN FILE
|
||
DEC ENTCNT ;ANY MORE?
|
||
BLT MFBLK3 ;NO, GET NEXT BYTE
|
||
INC E ;NEXT ON DISK
|
||
BR MFBGE1
|
||
MFBGE2: SUB #40,ENTCNT ;REMOVE FLAG BIT
|
||
REST <B,A>
|
||
MFBGE3: MOV #-1,E ;NOTHINGNESS
|
||
JSR PC,@(P)+ ;RETURN IT
|
||
INC D ;NEXT BLOCK IN FILE
|
||
DEC ENTCNT ;MORE OF SAME?
|
||
BNE MFBGE3 ;YUP
|
||
BR MFBLK3 ;NO, NEXT BYTE
|
||
|
||
;COME HERE FOR A SET ADDRESS TYPE OF DESCRIPTOR
|
||
MFBSET: MOV B,ENTCNT ;SAVE THE COUNT
|
||
MOVB @ENTPNT,A ;GET NEXT BYTE
|
||
INC ENTPNT
|
||
BIC #177400,A ;LOSING SIGN EXTEND!
|
||
MOVB @ENTPNT,E ;AND HIGH ORDER BYTE
|
||
INC ENTPNT
|
||
SWAB E ;INTO RIGHT PLACE
|
||
BIC #377,E ;UNEXTEND AGAIN
|
||
ADD A,E ;WHOLE WORD
|
||
BR MFBGE4 ;GO DO REGULAR COUNT
|
||
|
||
;COME HERE FOR SKIP AND COUNT TYPE
|
||
MFBSKG: MOV B,A ;COPY DATA
|
||
ASH #-3,A ;GET THE SKIP
|
||
ADD A,E ;SKIP IT
|
||
BIC #177770,B ;GET THE COUNT
|
||
BR MFBGET ;TREAT LIKE REGULAR GET
|
||
|
||
;COME HERE ON END OF FILE, INFINITE NON-EX BLOCKS
|
||
MFBLK8: MOV #-1,E ;NO BLOCK HERE
|
||
MOV E,ENTCNT ;FLUSH ANY COUNT LEFT OVER
|
||
JSR PC,@(P)+ ;RETURN IT
|
||
INC D ;AND SO ON
|
||
BR MFBLK8 ;FOREVER
|
||
;SET UP THE VARIABLES IN THE MFI IN ITEM2
|
||
;SO WE CAN ADD BLOCKS TO IT
|
||
MFFEND: JSR F,ACSAV
|
||
MOV ITM2A,A ;POINTER TO MFI
|
||
MOV A,B
|
||
ADD #MFENHD,B ;POINT TO REAL ENTRY
|
||
MOV MFENHD(A),C ;GET HEADER WORD
|
||
BIC #177400,C ;GET LENGTH
|
||
ADD B,C ;MAKE END POINTER
|
||
BIT #MFEOFB,(B) ;TIEM DATE ETC?
|
||
BEQ 1$ ;NOPE
|
||
ADD #10,B ;YES, SKIP
|
||
1$: CMP (B)+,(B)+ ;SKIP HEADER WORD AND VERSION #
|
||
BIT #MFACCB,MFENHD(A) ;ACCESS CODES?
|
||
BEQ MFFEN2 ;NOPE
|
||
MFFEN1: ADD #2,B ;SKIP CODES
|
||
TSTB (B)+ ;LAST OF THEM?
|
||
BLT MFFEN1 ;NOT YET
|
||
MFFEN2: TSTB (B)+ ;LAST CHAR OF NAME?
|
||
BGE MFFEN2 ;KEEP GOING
|
||
MOV #-1,E ;NO BLOCK YET
|
||
MOV #ADDEMP,F ;ADD TO EMPTY DESC
|
||
MOV B,MFENDP(A) ;THE LAST GOOD BYTE
|
||
MFFEN3: CMP B,C ;AT END?
|
||
BHIS MFFEN8 ;YES, DONE
|
||
MOV B,MFENDP(A) ;THE LAST GOOD BYTE
|
||
MOVB (B),D ;GET DESC BYTE
|
||
BIC #177477,D ;GET TYPE
|
||
ASH #-5,D ;INTO BYTE INDEX
|
||
INC E ;NEXT BLOCK
|
||
JMP @MFENTB(D) ;GO SERVICE THE TYPE
|
||
|
||
MFESKP: MOVB (B)+,D ;GET BYTE AGAIN
|
||
BIC #177700,D ;GET AMOUNT TO SKIP
|
||
ADD D,E ;SKIP IT
|
||
MOV #ADDNXT,F ;CAN'T ADD TO THIS BYTE
|
||
BR MFFEN3 ;GET NEXT
|
||
|
||
MFEGET: MOV #ADDCNT,F ;ADD TO REGULAR COUNT
|
||
MOVB (B)+,D ;GET THE COUNT
|
||
BIC #177700,D
|
||
CMP D,#40 ;IS IT A HOLE?
|
||
BGE 1$ ;YES
|
||
ADD D,E
|
||
1$: MOV #-1,E ;RESET BLOCK NUMBER
|
||
MOV #ADDHOL,F ;ADD TO A HOLE
|
||
BR MFFEN3
|
||
|
||
MFESET: MOVB (B)+,F ;GET THE DESR FOR THE COUNT BITS
|
||
BIC #177700,F ;GET THE COUNT
|
||
MOVB (B)+,E ;GET LOW BYTE
|
||
BIC #177400,E
|
||
MOVB (B)+,D ;GET HIGH BYTE
|
||
SWAB D
|
||
BIC #377,D
|
||
BIS D,E ;GET ADDRESS
|
||
ADD F,E ;TAKE CARE OF THE COUNT
|
||
MOV #ADDSET,F ;ADD TO COUNT OF SET ADDRESS
|
||
BR MFFEN3
|
||
|
||
MFESKG: MOVB (B)+,D ;GET THE AMOUNT TO SKIP
|
||
MOV D,F ;COPY IT
|
||
BIC #177770,F ;GET THE COUNT
|
||
ADD F,E
|
||
ASH #-3,D ;THE HIGH 3 BITS OF THE 6
|
||
BIC #177770,D ;AR ETHE SKIP
|
||
ADD D,E
|
||
MOV #ADDSKG,F ;ADD TO GET SKIP TYPE
|
||
BR MFFEN3
|
||
|
||
MFFEN8: SUB A,MFENDP(A) ;MAKE IT RELATIVE TO BEGGINING
|
||
MOV F,MFENDT(A) ;TYPE DISPATCH FOR END
|
||
MOV E,MFENDB(A) ;BLOCK FOR END
|
||
JMP ACRET
|
||
.STITL RANDOM CAPABILITY ROUTINES
|
||
CAPRMS:
|
||
CAPRSP: MOVB 1(P),B ;GET FUNCTION
|
||
CMP B,#SPIHGH ;TOO HIGH?
|
||
ERRORC HIS,BFUN ;YUP
|
||
ASL B ;INDEX
|
||
JMP @SPITAB(B) ;GO DO IT
|
||
|
||
SPPTP: MOV A,F ;COPY POINTER TO THE SPHERE CAPABILITY
|
||
MOV 2(P),B ;THE PROCESS CAPABILITY POINTER
|
||
MOV ITM1A,A ;POINTER TO THE SPHERE IN THE MAP
|
||
JSR PC,GCLSTA ;FIND THE C-LIST
|
||
BEQ CPRSP1 ;COULDN'T FIND IT
|
||
ADD B,A ;POINT TO THE CAPABILITY DIRECTLY
|
||
CMP 2(A),ITEM0 ;IS IT THIS CURRENT PROCESS
|
||
BEQ CPRSP1 ;CAN'T DO IT.
|
||
BIT #.SPCAD,(F) ;CAN I ADD TO THE SPHERE
|
||
BEQ CPRSP2 ;NOPE
|
||
BIT #.PRWRA,(A) ;CAN I MOVE THIS PROCESS
|
||
BEQ CPRSP2 ;NOPE
|
||
MOV 2(A),A ;GET THE PROCESS NO.
|
||
MOV 2(F),B ;THE SPHERE NO.
|
||
JSR PC,PUTPRS ;PUT THE PROCESS INTO THAT SPHERE
|
||
BEQ CPRSP1 ;FAILED, MUST BE RUNNING OR TO MANY PROCESSES
|
||
CAPRS3: ADD #6,P ;POP THE OTHER ARGUMENTS
|
||
JMP ERETCZ ;DONE
|
||
CPRSP1: ERROR BCN ;BAD CAPABILITY NUMBER
|
||
CPRSP2: ERROR BAC ;BAD ACCESS
|
||
|
||
SPRCP: CLR F ;WHERE TO PUT WHAT FROM THERE
|
||
MOV 2(P),B ;THE C-LIST NUMBER TO INVESTIGATE
|
||
BIT #177400,B ;ANY BIT NUMBERS?
|
||
BNE CPRSP1 ;WELL NO CAPABILITY THERE
|
||
MOV 2(A),A ;THE SPHERE TO READ FROM
|
||
JSR PC,ITM1PL ;LOAD IT UP
|
||
MOV ITM1A,A ;THE PLACE TO INVESTIGATE IT AT
|
||
JSR PC,GCLSTA ;GET THE C-LIST ENTRY
|
||
BEQ CAPRS4 ;FAILED
|
||
ADD A,B ;POINT TO IT
|
||
MOVB (B),F ;COPY IT
|
||
BGE CAPRS2 ;THERE IS CAPABILITY THERE
|
||
CAPRS4: CLR F
|
||
CAPRS2: MOV F,B
|
||
JSR PC,GIVPSW ;GIVE HIM THE CAPABILITY
|
||
JSR PC,ITM1PO
|
||
BR CAPRS3
|
||
|
||
;STOP ALL PROCESSES EXCEPT ME
|
||
SPSTP: MOV #SPRSTP,F
|
||
BR SPKIL1
|
||
|
||
;START ALL PROCESSES
|
||
SPSTR: MOV #SPRSTR,F
|
||
BR SPKIL1
|
||
|
||
;KILL ALL PROCESSES EXCEPT ME
|
||
SPKIL: MOV #SPRKIL,F
|
||
SPKIL1: MOV 2(A),C ;SPHERE INDEX
|
||
JSR PC,(F) ;KILL THEM
|
||
BR CAPRS3 ;RETURN
|
||
|
||
;GET NUMBER OF PROCESSES IN A SPHERE
|
||
SPGNP: MOV 2(A),A ;SPHERE
|
||
JSR PC,ITM2LD ;LOAD IT
|
||
MOV SPHPRC(A),B ;NUMBER OF PROCESSES
|
||
JSR PC,GIVPSW ;PASS TO USER
|
||
BR CAPRS3
|
||
;GET PC AND PROCESS ID OF PROCESS #
|
||
SPPGT: JSR PC,GETFPR ;LOAD FIRST PROCESS INTO ITEM2
|
||
MOV 2(P),B ;THE PROCESS TO GET
|
||
BEQ SPPGT1 ;GOT THE ONE WE WANT LOADED
|
||
SPPGT2: MOV PSPHCP(A),A ;NEXT PROCESS
|
||
ERRORC LE,BAD ;NO SUCH THING
|
||
JSR PC,ITM2LD ;LOAD IT
|
||
SOB B,SPPGT2 ;TILL WE GET TO THE DESIRED ONE
|
||
SPPGT1: MOV PUPC(A),B ;THE GUY'S PC
|
||
JSR PC,GIVPSW ;RETURN IT
|
||
MOV PRSID1(A),B ;ID WORD ONE
|
||
JSR PC,GIVPSW ;RETURN
|
||
MOV PRSID2(A),B ;ID WORD TWO
|
||
JSR PC,GIVPSW
|
||
BR CAPRS3 ;RETURN
|
||
|
||
;GET A CAPABILITY TO A PROCESS IN THE SPHERE
|
||
SPGPC: JSR PC,GETFPR ;LAOD FIRST PROCESS INTO ITEM2
|
||
MOV ITEM1,C ;BEING CREATED IN EXECUTING SPHERE
|
||
MOV #-1,B ;CREATE IN FIRST FREE SLOT
|
||
JSR PC,CRCLST ;TRY TO CREATE
|
||
ERRORC CS,CLF ;C-LIST FULL
|
||
ADD ITM1A,A ;POINT AT ENTRY IN C LIST
|
||
MOV A,C ;SAVE THAT
|
||
MOV ITM2A,A ;POINT AT FIRST PROCESS
|
||
SPGPC1: CMP 4(P),PRSID1(A) ;SAME ID WORD 1?
|
||
BNE SPGPC2 ;NOPE
|
||
CMP 2(P),PRSID2(A) ;SAME ID WORD 2?
|
||
BEQ SPGPC3 ;YES, THSI IS THE ONE
|
||
SPGPC2: MOV PSPHCP(A),A ;NEXT PROCESS
|
||
ERRORC LE,BAD ;NO SUCH PROCESS
|
||
JSR PC,ITM2LD ;LOAD IT
|
||
BR SPGPC1 ;TRY AGAIN
|
||
SPGPC3: INC PRSREF(A) ;ONE MORE REFERENCE
|
||
MOV #.PRCAP!.PRWRA,(C) ;A PROCESS CAP
|
||
MOV ITEM2,2(C) ;THE ITEM FOR THE CAP
|
||
JSR PC,GIVPSW
|
||
JMP CAPRS3 ;RETURN
|
||
|
||
;SET THE ENTER ADDRESS
|
||
SPENT: CMPB (A),#.MSCAP ;MASTER SPHERE CAPABILITY
|
||
ERRORC NE,BCT ;BAD CAP TYPE
|
||
MOV 2(P),B ;GET THE ARGUMENT
|
||
BIT #1,B ;ODD
|
||
ERRORC NE,BAD ;BETTER NOT BE
|
||
MOV B,6(A) ;SET IN THE ENTER ADDRESS
|
||
BIC #.SPFES,(A) ;ALLOW ENTERS
|
||
JMP CAPRS3 ;DONE
|
||
|
||
;LOAD THE FIRST PROCESS IN THE SPHERE INTO ITEM2
|
||
GETFPR: MOV 2(A),A ;THE SPHERE
|
||
JSR PC,ITM2LD ;LAOD IT
|
||
MOV SPHPRP(A),A ;THE ZEROTH PROCESS
|
||
ERRORC LE,BAD ;THERE ISN'T ONE!
|
||
JMP ITM2LD ;LOAD THAT
|
||
|
||
.IFZ MBFLG
|
||
SPSTY:SPSTX:SPSMC: ERROR RNA ;NO MB11 ON THIS MACHINE!
|
||
.IFF
|
||
|
||
SPSTX: MOV #SPMBHX,F ;POINT TO X PART
|
||
BR SPSTY1 ;AND DO SAME AS Y
|
||
|
||
SPSTY: MOV #SPMBHY,F ;POINT TO Y PART
|
||
SPSTY1: MOV 2(A),A ;GET THE SPHERE ITEM
|
||
JSR PC,ITM2LD ;LOAD IT
|
||
MOV 4(P),B ;GET WORD WITH CONTROL BITS
|
||
MOV 2(P),C ;GET WORD WITH ADDRESS
|
||
BIT #177763,B ;ANYTHING OTHER THAN READ AND/OR WRITE TRAP SET?
|
||
ERRORC NE,BAD
|
||
BIT #1,C ;ODD ADDRESS TRAP ON?
|
||
ERRORC NE,BAD ;CAN'T DO THAT!
|
||
ADD A,F ;POINT INTO SPHERE AT RIGHT PLACE
|
||
SAVE <(F),2(F)> ;SAVE OLD VALUES
|
||
MOV B,(F) ;TRAP BITS
|
||
MOV C,2(F) ;ADDRESS
|
||
JSR PC,SPTRTS ;TEST THAT TRAP IS OK
|
||
BNE SPSTY2 ;YUP, WIN
|
||
REST <2(F),(F)> ;RESTORE OLD VALUES
|
||
ERROR BAD ;AND EXIT
|
||
SPSTY2: CMP (P)+,(P)+
|
||
JMP CAPRS3 ;EXIT WINNINGLY
|
||
|
||
;TEST THAT WE HAVE A CONSISTENT SET OF TESTS, NAMELY, THAT
|
||
;WE DON'T HAVE AN X<A<Y TEST THAT CROSSES A PAGE BOUNDARY
|
||
SPTRTS: BIT #MBXAYR!MBXAYW,SPMBCN(A) ;X<A<Y TRAP SET?
|
||
BEQ SPTRT1 ;NO, CAN'T LOSE
|
||
MOV SPMBLY(A),E ;GET Y REGISTER
|
||
CMP E,SPMBLX(A) ;IS Y>X?
|
||
BLO SPTRT2 ;NOPE, LOSER
|
||
BIC #17777,E ;CLEAR ALL BUT PAGE BITS
|
||
SUB SPMBLX(A),E
|
||
BEQ SPTRT1 ;THAT'S OK
|
||
COM E
|
||
BIT #170000,E
|
||
BNE SPTRT2 ;THAT'S NOT!
|
||
SPTRT1: CLZ
|
||
RTS PC
|
||
SPTRT2: SEZ
|
||
RTS PC
|
||
|
||
;SET MB11 CONTROL REGISTER
|
||
SPSMC: MOV 2(A),A
|
||
JSR PC,ITM2LD ;LOAD THE SPHERE UP
|
||
MOV 2(P),B ;GET THE ARG
|
||
BIT #176267,B ;THE USER DOESN'T GET TO HACK
|
||
;UNUSED BITS 170060
|
||
;NO INIT=4000, INT ON ALMOST OVERFLOW=2000
|
||
;DONE=200, LOW 3 FREEZE BITS=7
|
||
ERRORC NE,BAD
|
||
SAVE SPMBCN(A)
|
||
JSR PC,SPTRTS ;TEST THAT THIS TRAP IS A WIN
|
||
BNE SPSMC1 ;YUP
|
||
REST SPMBCN(A) ;RESTORE OLD TRAP
|
||
ERROR BAD
|
||
SPSMC1: TST (P)+
|
||
JMP CAPRS3 ;WIN, RETURN
|
||
|
||
|
||
.ENDC
|
||
|
||
|
||
CAPRQU: ERROR BFUN
|
||
CAPRCL: TST (P)+ ;GET RID OF FIRST ARGUMENT
|
||
MOV A,F ;COPY POINTER TO CAPABILITY
|
||
REST D ;IF < 0 GRAB CONSUMER, ELSE RELEASE IT
|
||
BMI CAPCL2 ;TRY TO GRAB IN
|
||
BIT #.CLCONS,(F) ;IS HE THE CONSUMER
|
||
BEQ CAPCL1 ;NO, RETURN SUCCESSFUL
|
||
MOV 2(F),A ;THE POINTER TO THE CL
|
||
JSR PC,ITM2LD ;LOAD IT UP
|
||
CLR CLCONP(A) ;CLEAR THE CONSUMER POINTER
|
||
BIC #.CLCONS,(F) ;CLEAR THE CONSUMER BIT
|
||
CAPCL1: TST (P)+ ;POP OFF OTHER ARG
|
||
JMP ERETCZ ;RETURN SUCESSFULP
|
||
CAPCL2: BIT #.CLCONS,(F) ;AM I THE CONSUMER ALREADY
|
||
BNE CAPCL1 ;YES, WIN
|
||
MOV 2(F),A ;THE POINTER TO THE CL
|
||
JSR PC,ITM2LD ;LOAD IT UP
|
||
TST CLCONP(A) ;IS SOME ONE ELSE CONSUMER
|
||
ERRORC NE,RNA ;YES, RESOURCE NOT AVAILABLE
|
||
MOV ITEM0,CLCONP(A) ;SAY I AM THE CONSUMER
|
||
BIS #.CLCONS,(F) ;SET THE BIT THAT SAYS SO
|
||
BR CAPCL1 ;RETURN SUCCESSFULL
|
||
|
||
|
||
;THIS CALL USES THE SAME CONVENTIONS ON READ/WRITE SELECT AS CAPRPR (40 BIT MEANS
|
||
;WRITE, CLEAR MEANS READ) IF WRITE, 40 => MOV,41 => BIS,42 => BIC.
|
||
CAPRTT: MOVB 1(P),B ;THE FUNCTION
|
||
MOV B,C ;COPY IT
|
||
BIC #40,B ;CLEAR THE WRITE BIT
|
||
CMP B,#NTTFNC ;IS IT LEAGL
|
||
ERRORC HI,BFUN ;BAD FUNCTION TYPE
|
||
CAPRT4: TST (P)+
|
||
MOV 2(A),A ;THE TTY ITEM
|
||
JSR PC,ITM2LD ;LOAD IT UP
|
||
CAPRT3: CMP ITEM1,TTITM(A) ;DO I OWN THE TTY
|
||
BEQ CAPRT1 ;YES
|
||
CAPRT2: JSR PC,LFLUSH ;WAIT FOR IT
|
||
MOV ITM2A,A ;POINT TO THE TTY
|
||
CMP ITEM1,TTITM(A) ;DO I OWN IT NOW
|
||
BNE CAPRT2 ;NO
|
||
JSR PC,RUNME ;LETS GO
|
||
BR CAPRT3 ;MAKE SURE
|
||
CAPRT1: ASL B ;CONVERT FUNCTION NUMBER TO WORD OFFSET
|
||
JMP @TTIVTB(B) ;DISPATCH TO TTY INVOKE FUNCTION
|
||
CAPRT5: TST (P)+ ;FLUSH THIRD ARG
|
||
JMP ERETCZ ;RETURN SUCESS FUL
|
||
|
||
;THIS SUBROUTINE CAN BE CALLED TO FORCE THE INVOK TO WAIT UNTIL THE
|
||
;OUTPUT BUFFER IS EMPTY
|
||
TOWAIT: TST TOQN(A) ;IS THERE ANYTHING IN OUTPUT QUE?
|
||
BEQ TOWAI2 ;NO
|
||
TOWAI1: JSR PC,LFLUSH ;GO AWAY FOR A WHILE
|
||
TST TOQN(A) ;IS THE QUE EMPTY YET?
|
||
BNE TOWAI1 ;NO, WAIT SOME MORE
|
||
JSR PC,RUNME ;GO AHEAD
|
||
BR TOWAIT ;MAKE SURE
|
||
TOWAI2: RTS PC
|
||
|
||
;RESET THE TTY'S IF WANTED
|
||
TTRST: BIT #TORST,2(P) ;RESET OUTPUT?
|
||
BEQ TTRST1 ;NO
|
||
BIC #TORST,2(P) ;TURN THE BIT OFF
|
||
SAVE PS
|
||
SPL 7
|
||
MOV TTLTTY(A),E ;THE LOGICAL TTY NUMBER
|
||
JSR PC,TYORT ;RESET OUTPUT
|
||
REST PS
|
||
TTRST1: BIT #TIRST,2(P) ;RESET INPUT?
|
||
BEQ TTRST2 ;NO
|
||
BIC #TIRST,2(P)
|
||
SAVE PS
|
||
SPL 7
|
||
JSR PC,TYIRT1 ;RESET INPUT QUE
|
||
JSR PC,TYBRT ;RESET INPUT BUFFER
|
||
REST PS
|
||
TTRST2: RTS PC
|
||
|
||
;MISCELLANEOUS TTY INVOKES
|
||
TTMOV: JSR PC,TTRST ;RESET TTY'S IF DESIRED
|
||
JSR PC,TOWAIT ;WAIT FOR BUFFER TO CLEAR
|
||
REST TTYST1(A) ;DO A MOVE INTO THE TTYST1 WORD
|
||
BR CAPRT5
|
||
TTBIS: JSR PC,TTRST ;RESET TTY'S IF DESIRED
|
||
JSR PC,TOWAIT ;WAIT FOR BUFFER TO CLEAR
|
||
BIS (P)+,TTYST1(A) ;DO A BIS ON THE WORD
|
||
BR CAPRT5
|
||
TTBIC: JSR PC,TOWAIT ;WAIT FOR BUFFER TO CLEAR
|
||
BIC (P)+,TTYST1(A) ;DO A BIC ON THE STATUS WORD
|
||
BR CAPRT5
|
||
TTBS2: JSR PC,TOWAIT ;WAIT FOR BUFFER TO CLEAR
|
||
BIS (P)+,TTYST2(A) ;SET BITS IN TTYST2
|
||
BR CAPRT5
|
||
TTBC2: JSR PC,TOWAIT ;WAIT FOR BUFFER TO CLEAR
|
||
BIC (P)+,TTYST2(A) ;CLEAR BITS IN TTYST2
|
||
BR CAPRT5
|
||
TTRD: JSR PC,TOWAIT ;WAIT FOR BUFFER TO CLEAR
|
||
MOV TTYST1(A),B ;GET THE WORD
|
||
BR TTCNO1 ;GIVE HIM THE WORD AND RETURN
|
||
TTCNO: JSR PC,TOWAIT ;WAIT FOR BUFFER TO CLEAR
|
||
MOV CHARNO(A),B ;GET THE WORD
|
||
TTCNO1: ADD #4,P
|
||
JSR PC,GIVPSW ;GIVE IT TO HIM
|
||
JMP ERETCZ ;SUCCESSFUL RETURN
|
||
TTMV2: JSR PC,TOWAIT ;WAIT FOR BUFFER TO CLEAR
|
||
REST TTYST2(A) ;SET TTYST2
|
||
BR CAPRT5
|
||
TTTYP: MOV TTLTTY(A),E ;THE LOGICAL TTY NO.
|
||
MOV TTYTBL(E),B ;THE INFO ABOUT WHAT KIND OF TTY IT IS
|
||
BR TTCNO1 ;RETURN IT TO THE USER
|
||
TTPEK: TST TIBN(A) ;ANY CHARACTERS?
|
||
BEQ TTPEK1 ;NO
|
||
MOV TIBO(A),B ;GET POINTER TO THE STUFF
|
||
ADD A,B ;MAKE IT UNRELATIVE
|
||
MOVB (B),B ;GET THE BYTE
|
||
BIC #177400,B ;CLEAR THE TOP BYTE
|
||
BR TTCNO1 ;RETURN THE VALUE
|
||
TTPEK1: MOV #-1,B ;RETURN -1
|
||
BR TTCNO1 ;AND GO RETURN IT
|
||
TTSPD: MOV TTLTTY(A),E ;THE LOGICAL TTY NO.
|
||
BIT #DHF,TTYTBL(E) ;IS IT A DH11?
|
||
ERRORC EQ,BAD ;DONT KNOW WHAT TO CALL IT (ALMOST RNA)
|
||
TTSPD1: SPL 5 ;STOP IT FROM CHANGING
|
||
BIT #TOTRAN,TTYST1(A) ;IS IT TRANSMITTING?
|
||
BEQ TTSPD3 ;NO, WE CAN MUNG IT
|
||
TTSPD2: SPL 0 ;LOWER PRIORITY
|
||
JSR PC,SFLUSH ;WAIT FOR A SHORT TIME
|
||
SPL 5
|
||
BIT #TOTRAN,TTYST1(A) ;TRANSMITTING?
|
||
BNE TTSPD2 ;YES
|
||
SPL 0
|
||
JSR PC,RUNME ;IT HAS STOPPED FOR A WHILE
|
||
BR TTSPD1 ;NOW TRY TO CHANGE THE SPEED
|
||
TTSPD3: SUB #NFDHTY,E ;GET THE DH LINE NO.
|
||
ASR E ;INTO A NUMBER
|
||
BIC #17,DH0SCR ;CLEAR THE LINE NO.
|
||
BIS E,DH0SCR ;SET IN THE NEW ONE
|
||
REST DH0LPR ;GET THE SPEED
|
||
SPL 0 ;BACK TO LOW LEVEL
|
||
TST (P)+ ;POP OFF EXTRA ARGUMENTS
|
||
JMP ERETCZ ;AND RETURN
|
||
|
||
|
||
TBRAK: REST TTBRKL(A) ;SET UP COUNT FOR THE BREAK
|
||
JSR PC,TOCINT ;CAUSE OUTPUT INTERRUPT
|
||
TST (P)+ ;POP OFF ARGUMENT
|
||
JMP ERETCZ ;RETURN
|
||
|
||
;SET LINE LENGTH
|
||
TTSLNL: REST LINEL(A)
|
||
JMP CAPRT5
|
||
|
||
|
||
;THIS TTY INVOK CAN BE USED TO IMPLEMENT CONTROL Z TYPE BREAKS. THE IDEA
|
||
;IS THAT THE USER JOB HAS A PROCESS WHICH SIMPLY MAKES THIS CALL TO CHECK
|
||
;FOR ONE OF THE BREAK CHARS. THE PROCESS HANGS UNTIL THE CALL SUCCEEDS
|
||
;WHICH DEPENDS ON THE ARGUMENT TO THE CALL. TWO CONDITIONS CAN MAKE THE
|
||
;CALL SUCCEED WHICH CORRESPOND TO THE TWO ARUGMENTS TO THE CALL. THE
|
||
;FIRST ARGUMENT IS A PAIR OF BYTES. IF ANY OF THE TYPED IN CHARS HAPPENS
|
||
;TO EQUAL ONE OF THESE BYTES THEN THE CALL SUCCEEDS. THE SECOND ARG IS
|
||
;A NUMBER SUCH THAT IF ANY OF THE TYPED IN CHARS IS LESS THAN THIS NUMBER
|
||
;THEN THE CALL ALSO SUCCEEDS. A TYPICAL NUMBER MIGHT BE 40, IN WHICH CASE,
|
||
;THE CALL WOULD SUCCEED ANY TIME A CONTROL CHAR WAS TYPED. THE ACTUAL CHAR
|
||
;TYPED IS RETURNED ON THE USER'S STACK. NOTE TWO INHERENT BUGS IN THIS CODE:
|
||
;FIRST, SINCE THE LAST CHAR IS CHECKED AT LONG-FLUSHED FREQUENCEY, A CHAR
|
||
;COULD POTENTIALLY GO BY WITHOUT BEING CHECKED, EG THE USER IS TYPING VERY FAST.
|
||
;SECOND, IF TWO PROCESSES MAKE THIS CALL, THEN THE FIRST ONE TO SUCCEED WILL
|
||
;CLEAR THE LAST CHAR WORD, SO THAT THE OTHER CANNOT SUCCEED.
|
||
TTBRK: REST B ;SECOND ARG IS A PAIR OF CHARS TO CHECK FOR
|
||
MOV B,C ;MAKE A COPY
|
||
SWAB C ;GET THE HIGH BYTE CHAR
|
||
BIC #177600,B ;CLEAN OFF THE CRUFT
|
||
BIC #177600,C ;AGAIN
|
||
REST E ;THIRD ARG IS THE NUMBER
|
||
JSR PC,TTBCHK ;SHOULD WE BREAK HERE?
|
||
BEQ TTBRK2 ;NO
|
||
TTBRK1: JSR PC,GIVPSW ;TTBCHK RETURNS VALUE IN B
|
||
JMP ERETCZ ;SUCCEED
|
||
TTBRK2: JSR PC,LFLUSH ;GO AWAY FOR A WHILE
|
||
JSR PC,TTBCHK ;SHOULD WE BREAK HERE
|
||
BEQ TTBRK2 ;NO
|
||
TTBRK3: JSR PC,RUNME ;AS IT SAYS...
|
||
BR TTBRK1 ;RESTART TO MAKE SURE
|
||
|
||
;THIS SUBROUTINE CHECKS IF THE BREAK PROCESS SHOULD BE RELEASED FOR ANY
|
||
;REASON AND SETS UP THE CHAR TO RETURN TO THE USER IS IT SHOULD. IT CLEARS
|
||
;Z IF THE BREAK SHOULD COMPLETE. EXPECTS CHECK CHARS IN B AND C, AND THE
|
||
;CHECK NUMBER IN E, LOW BYTE, FLAGS IN HIGH BYTE.
|
||
TTBCHK: MOV TLAST(A),F ;GET THE LAST CHAR TYPED
|
||
BEQ TTBCH0 ;JUST CHECK FOR MORE BREAK
|
||
CLR TLAST(A) ;SO WE DON'T GET THIS AGAIN
|
||
CMPB F,B ;IS IT ONE OF THE BYTES TO CHECK FOR?
|
||
BEQ TTBCH1 ;YES
|
||
CMPB F,C ;HOW ABOUT THE OTHER CHAR?
|
||
BEQ TTBCH1 ;YUP
|
||
CMPB F,E ;IS IT PERHAPS LESS THAN THE NUMBER?
|
||
BLT TTBCH1 ;YES
|
||
TTBCH0: BIT #.TTMBK,E ;DOES HE WANT TO DO MORE BREAKS?
|
||
BEQ TTBCH3 ;NO
|
||
BIT #.TMORM,TTYST1(A) ;IS MORE PROCESSING ENABLED?
|
||
BEQ TTBCH3 ;NO, HANG AROUND FOR A WHILE
|
||
BIT #.TMORF,TTYST1(A) ;IS MORE TRIGGERED?
|
||
BEQ TTBCH3 ;NO, HANG AROUND
|
||
MOV #.TTMBK,B ;TELL THE CALLER THIS IS A MORE BREAK
|
||
BR TTBCH2
|
||
TTBCH1: MOV F,B ;GET THE CHAR
|
||
BIC #177400,B ;CLEAR THE HIGH BYTE
|
||
BIS #.TTIBK,B ;TELL HIM THIS IS AN INPUT BREAK
|
||
CLR TLAST(A) ;FLUSH THE OLD LAST CHAR
|
||
TTBCH2: CLZ ;SUCCEED
|
||
RTS PC
|
||
TTBCH3: SEZ ;FAIL
|
||
RTS PC
|
||
|
||
.IFNZ NTVS
|
||
;TV INVOKES WHICH ARE ACTUALLY INVOKES OF TTY CAPABILITY
|
||
;TVATC ATTACHES A TV DISPLAY TO A TTY AND KEYBOARD. THE SECOND
|
||
;ARGUMENT TO THE INVOKE IS THE CAPABILITY INDEX OF THE DISPLAY.
|
||
TVATC: REST B ;GET THE DISPLAY CAPABILITY NUMBER
|
||
MOV #ITM1AD,A ;GET THE SPHERE ADDRESS IN B
|
||
JSR PC,GCLSTA ;GET THE OFFSET OF THE CAPABILITY INTO SPHERE
|
||
ERRORC EQ,BCN ;BAD C-LIST NUMBER
|
||
ADD B,A ;GCLSTA RETURNS THE OFFSET IN B
|
||
CMPB (A),#.DSCAP ;MAKE SURE ITS A DISPLAY CAP
|
||
MOV CLSEM0(A),B ;GET THE NUMBER OF THIS DISPLAY
|
||
ASR B ;CONVERT FROM WORD OFFSET TO NUMBER
|
||
SUB #NFTVDS,B ;MAKE SURE IT'S A TV DISPLAY
|
||
ERRORC LT,BAD ;NOPE
|
||
CMP B,#NTVS ;IN CASE THE CAP IS SCREWED UP
|
||
BUGC GE
|
||
MOV #ITM2AD,A ;ADDRESS OF THE TTY ITEM
|
||
MOVB TVDSBF(B),C ;GET THE BUFFER NUMBER OF THIS DISPLAY
|
||
BUGC LT ;IT HAD BETTER HAVE A BUFFER ASSIGNED
|
||
CMP C,#NTVCHN ;IN CASE IT'S SCREWED UP
|
||
BUGC GE
|
||
BIS #TVIOR,C ;START IN CURSOR IOR MODE
|
||
MOV C,TVBUF(A) ;GIVE THIS TV TTY A BUFFER
|
||
INCB TVDSRF(B) ;ONE MORE THING IS REFERENCING THIS BUFFER
|
||
MOV TTLTTY(A),B ;GET THE LOGICAL TTY NUMBER
|
||
MOVB #-TVBLTM,TVBLNK(B) ;TURN ON THE CURSOR FOR THIS TV
|
||
ADD #2,P ;POP THE THIRD ARG
|
||
JMP ERETCZ ;SUCCEED
|
||
|
||
;THE FOLLOWING INVOKE CAN BE USED TO CLEAR AND GENERALLY RESET THE SCREEN
|
||
TVCL: JSR PC,TOWAIT ;WAIT UNTIL THE OUTPUT BUFFER CLEARS
|
||
SAVE PS
|
||
SPL 7 ;TEMPORARILY
|
||
JSR PC,TVINIT ;INITIALIZE TV VARIABLES, PUSH THE FONT IN ITEM 1
|
||
BEQ TVCL1 ;IN CASE TVINIT FAILS
|
||
JSR PC,TVCS ;CLEAR THE SCREEN
|
||
CLR CHARNO(A) ;CURSOR IN POSITION 0. NOTE A SET UP BY TVINIT
|
||
CLR LINENO(A) ;CLEAR THE LINE NUMBER
|
||
JSR PC,ITM1PO ;POP THE FONT ITEM, SET UP BY TVINIT
|
||
REST PS ;BACK TO NORMAL PRIORITY
|
||
ADD #4,P ;CLEAN OFF THE ARGUMENTS
|
||
JMP ERETCZ ;SUCCEED
|
||
TVCL1: REST PS ;BACK TO NORMAL PRIORITY
|
||
ERROR BAD ;BAD, NOT TV
|
||
|
||
;THIS INVOK IS USED FOR REVERSING WHITE AND BLACK ON SCREEN
|
||
TVREV: SAVE PS
|
||
SPL 7
|
||
JSR PC,TVINIT ;INITIALIZE THE TV VARIABLES
|
||
BEQ TVREV1 ;IN CASE TVINIT FAILS
|
||
JSR PC,REVSCR ;DO THE REVERSE
|
||
JSR PC,ITM1PO ;POP THE FONT ITEM SET UP BY TVINIT
|
||
REST PS
|
||
ADD #4,P ;CLEAN UP
|
||
JMP ERETCZ ;SUCCEED
|
||
TVREV1: REST PS
|
||
ERROR BAD ;NOT A TV
|
||
|
||
;CHANGE THE FONT OF A TV
|
||
TVFNT: JSR PC,TOWAIT ;WAIT UNTIL THE BUFFER CLEARS
|
||
REST B ;THE NUMBER OF THE FONT THAT HE WANTS
|
||
BLT TVFNT1 ;ERROR, NO NEGATIVE FONT NUMBERS
|
||
CMP B,#NFONTS ;IS IT GREATER THAN THE NUMBER OF FONTS?
|
||
BGE TVFNT1 ;YES, ERROR
|
||
ASL B ;CONVERT TO WORD INDEX
|
||
MOV FNTITM(B),A ;GET THE FONT ITEM FOR THIS FONT
|
||
BLE TVFNT1 ;NONE
|
||
JSR PC,ITM1PL ;LOAD IT UP
|
||
MOV ITM2A,C ;ADDRESS OF THE TTY ITEM
|
||
MOV FNHIGH(A),D ;NUMBER OF LINES IN A CHAR
|
||
DEC D ;THIS IS USED FOR LOADING TVWC BY BLINK ETC
|
||
NEG D ;ALLOW 1 FOR LOADING TVRWIN. TVWC EXPECTS NEGATIVE COUNT.
|
||
MOV D,TVLCNT(C) ;LINES IN CHAR MINUS ONE
|
||
MOV FNLINE(A),TVHIGH(C) ;NUMBER OF CHAR LINES ON THE SCREEN
|
||
MOV FNLINL(A),LINEL(C) ;NUMBER OF CHARS PER LINE
|
||
MOV FNLSC(A),TVNLSC(C) ;NUMBER OF LINES TO SCROLL
|
||
JSR PC,ITM1PO ;POP THE FONT ITEM
|
||
MOV B,TVFONT(C) ;SET IN THE NUMBER FOR THIS FONT
|
||
MOV C,A ;COPY TTY ITEM ADDRESS
|
||
CLR -(P) ;PUSH A DUMMY ARGUMENT
|
||
JMP TVCL ;AND DO A CLEAR SCREEN BEFOR RETURNING
|
||
TVFNT1: ERROR BAD ;BAD ARGUMENTS
|
||
|
||
TVSET: JSR PC,TOWAIT ;WAIT FOR BUFFER TO CLEAR
|
||
BIT #40,C ;DOES HE WANT READ?
|
||
BNE TVSET1 ;NO WRITE
|
||
MOV TVCUR(A),B ;THE CHAR POSITION ON LINE
|
||
JSR PC,GIVPSW ;GIVE IT TO HIM
|
||
MOV TVLINE(A),B ;THE LINE NUMBER OF CURSOR
|
||
JSR PC,GIVPSW ;GIVE IT TO HIM
|
||
ADD #4,P ;POP THE ARGS
|
||
JMP ERETCZ ;SUCCEED
|
||
TVSET1: REST <C,D> ;TVLINE AND TVCUR
|
||
CMP C,TVHIGH(A) ;MAKE SURE IT'S LEGAL
|
||
BGE TVSET2 ;TOO HIGH
|
||
CMP D,LINEL(A) ;LENGTH OF A LINE
|
||
BGE TVSET2 ;CANNOT PUT IT THERE
|
||
SAVE PS
|
||
SPL 7 ;SO THE CURSOR WILL NOT GET CONFUSED
|
||
MOV C,TVLINE(A) ;SET THE TVLINE
|
||
MOV D,TVCUR(A) ;AND THE CHAR NO.
|
||
JSR PC,TVINIT ;LOAD UP FONT ITM ETC
|
||
BEQ TVSET3 ;IN CASE INIT FAILS
|
||
JSR PC,RSCUR ;RESET THE VARIABLES
|
||
JSR PC,ITM1PO ;POP THE FONT ITEM
|
||
REST PS ;BACK TO NORMAL PRIORITY
|
||
JMP ERETCZ ;SUCCEED
|
||
TVSET3: REST PS ;BACK TO NORMAL PRIORITY
|
||
TVSET2: ERROR BAD ;BAD ARGUMENTS
|
||
.ENDC
|
||
.IFNZ NTVS
|
||
TVOFF: JSR PC,TOWAIT ;WAIT UNTIL BUFFER CLEARS
|
||
BIT #.PRWRT,C ;DOES HE WANT TO READ OR WRITE
|
||
BNE TVOFF1 ;WRITE
|
||
MOV TVOFFL(A),B ;GET TVOFFL
|
||
JSR PC,GIVPSW ;RETURN IT TO USER
|
||
ADD #4,P ;POP THE ARGUMENTS
|
||
JMP ERETCZ ;SUCCEED
|
||
TVOFF1: MOV (P),TVOFFL(A) ;FIRST ARG GOES INTO TVOFFLE
|
||
JMP TVCL ;NOW CLEAR THE SCREEN BEFORE RETURNING
|
||
.ENDC
|
||
|
||
;RETURN THE WIDTH OF CHAR AND TV LINES PER CHAR LINE FOR CURRENT FONT
|
||
TVRFN:
|
||
.IFNZ NTVS
|
||
ADD #4,P ;NO ARGUMENTS
|
||
JSR PC,TVINIT ;LOAD UP THE FONT
|
||
ERRORC EQ,BAD ;BAD ARGUMENTS
|
||
MOV FNWIDE(B),E ;WIDTH OF A CHAR
|
||
MOV FNTLCL(B),F ;NUMBER OF TV LINES IN 1 CHAR LINE
|
||
JSR PC,ITM1PO ;POP THE FONT ITEM
|
||
MOV E,B
|
||
JSR PC,GIVPSW ;RETURN THE WIDTH
|
||
MOV F,B
|
||
JSR PC,GIVPSW ;RETURN THE HEIGHT
|
||
JMP ERETCZ ;SUCCEED
|
||
|
||
TVMOD: JSR PC,TOWAIT ;WAIT FOR THE BUFFER TO EMPTY
|
||
REST B ;GET THE NUMBER
|
||
BNE 1$ ;THERE IS A FUNCTION
|
||
2$: ERROR BAD ;BAD ARG
|
||
1$: CMP B,#.TVMOV ;IS IT A MOVE FUNCTINO
|
||
BHI 2$ ;BAD FUNCTION
|
||
ASH #6,B ;SHIFT IT TO RIGHT POSITION
|
||
MOV TVBUF(A),C ;GET THE BUFFER NUMBER
|
||
BIC #TVMOV,C ;CLEAR OUT THE OLD FUNCTION
|
||
BIS B,C ;IN WITH THE NEW FUNCTION
|
||
MOV C,TVBUF(A) ;PUT IT AWAY
|
||
TST (P)+ ;BYE TO THE THIRRD ARG
|
||
JMP ERETCZ
|
||
.IFF
|
||
ERROR+BFUN
|
||
.ENDC
|
||
|
||
|
||
CAPRDS: .IFZ NTKDIS+NTVS
|
||
BPT
|
||
.IFF
|
||
BITB #100,1(P) ;IS THIS AN OLD STYLE DISPLAY?
|
||
BNE CAPRD5 ;NO
|
||
.ENDC
|
||
CAPRD3: .IFZ NTKDIS
|
||
BPT
|
||
.IFF
|
||
TST (A) ;IS THIS AN OLD DISPLAY?
|
||
ERRORC LT,BCT ;NEW ONE
|
||
SAVE <A> ;POINTER TO CAP
|
||
MOV TKDPDL,A ;THE PDLS ETC
|
||
JSR PC,ITM2PL ;LOAD THEM TOO
|
||
REST <A,D>
|
||
SWAB D ;GET THE FUNCTION
|
||
TSTB D
|
||
BEQ CAPRD1 ;GO START THE DISPLAY
|
||
CMPB #1,D ;IS IT ONE?
|
||
BEQ CAPRD2 ;YES, STOP THE DISPLAY
|
||
ADD #4,P
|
||
JSR PC,ITM2PO
|
||
JMP BADEMT ;NAUGHTY!
|
||
CAPRD2: JSR PC,TKDSP ;STOP IT
|
||
CAPRD4: ADD #4,P
|
||
JSR PC,ITM2PO
|
||
JMP ERETCZ ;WIN
|
||
CAPRD1: JSR PC,TKDSP ;MAKE SURE IT IS STOPPED
|
||
ASL C
|
||
BIC #177760,C ;CONVERT DISPLAY NUMBER TO AN INDEX
|
||
ADD ITM2A,C ;POINT TO THE FIRST WORD EXECUTED FOR THIS DISPLAY
|
||
MOV (P),A ;THE START ADDRESS
|
||
BIS #DPUSHJ,A ;IT IS A PUSHJ
|
||
MOV A,(C)
|
||
BIC #100000,TKDRUN(D) ;START IT ON INT LEVEL
|
||
BR CAPRD4
|
||
.ENDC
|
||
|
||
;TV DISPLAY INVOKES. THESE ARE CALLED WITH A NEGATIVE
|
||
;FUNCTION NUMBERS.
|
||
CAPRD5: .IFZ NTVS
|
||
BPT
|
||
.IFF
|
||
MOV CLSEM0(A),C ;GET LOGICAL DISPLAY NUMBER
|
||
BGE 1$
|
||
MOVB C,E
|
||
BR 2$
|
||
1$: ASR C ;TV DISPLAYS USE BYTE DATA
|
||
SUB #NFTVDS,C ;GET THE TV NUMBER
|
||
BLT CAPRD6 ;IT'S A TK DISPLAY!!!
|
||
CMP C,#NTVS ;MAKE SURE IT'S LEGAL
|
||
BUGC GE ;TOO BIG
|
||
MOVB TVDSBF(C),E ;GET THE BUFFER OF THIS TV
|
||
2$: ASL E ;FOR NOW, WORD OFFSET
|
||
MOVB 1(P),B ;THE FUNCTION HE WANTS
|
||
TST (P)+ ;POP THE FIRST ARG
|
||
REST <C,D> ;THE OTHER TWO ARGS
|
||
BIC #100,B ;MAKE INTO SMALL INTEGER
|
||
CMP B,#TVDSIM ;IS IT A LEGAL FUNCTION?
|
||
BGE CAPRD6 ;NO!
|
||
ASL B ;OK, SO MAKE INTO WORD OFFSET
|
||
JSR PC,@TVDSIT(B) ;NOW EXECUTE THE FUNCTION
|
||
BEQ CAPRD6 ;IN CASE SOMETHING WENT WRONG
|
||
JMP ERETCZ ;EVERTHING'S OK, WE'RE DONE
|
||
CAPRD6: ERROR BFUN ;BAD FUNCTION
|
||
|
||
|
||
;READ THE CURSOR (OR TURTLE) POSITION
|
||
TVDSRC: MOV TVDSCX(E),B ;THE X POSITION
|
||
JSR PC,GIVPSW ;GIVE IT TO HIM
|
||
MOV TVDSCY(E),B ;THE Y POSITION
|
||
JSR PC,GIVPSW ;LAY IT ON HIM
|
||
CLZ ;SUCCEED
|
||
RTS PC
|
||
|
||
;SET THE CURSOR POSITION
|
||
;TVDSSC CHECKS THE NEW CURSOR POSITION AND UPDATES IT IF IT'S LEGAL
|
||
TVDSSC: TST C ;MAKE SURE IT'S POSITIVE
|
||
BLT TVDSS1 ;BAD
|
||
CMP C,#455. ;IS IT TOO HIGH?
|
||
BGE TVDSS1 ;YES
|
||
TST D ;THIS ALSO CANNOT BE NEGATIVE
|
||
BLT TVDSS1 ;BAD
|
||
CMP D,#576. ;IT X TOO HIGH?
|
||
BGE TVDSS1 ;YES!
|
||
MOV C,TVDSCY(E) ;THE NEW Y
|
||
MOV D,TVDSCX(E) ;AND THE NEW X
|
||
CLZ ;OK
|
||
RTS PC
|
||
TVDSS1: SEZ ;SOMETHING WENT WRONG
|
||
RTS PC
|
||
|
||
;TVDSNL DRAWS A LINE WITH THE PEN UP. IE, IT SETS THE CURSOR
|
||
;TO A RELATIVE POSITION JUST LIKE THE REAL LINE DRAWERS
|
||
TVDSNL: SAVE <C,D> ;GET SOME REGISTERS
|
||
MOV TVDSCY(E),A ;OLD Y POSITION
|
||
MOV TVDSCX(E),B ;OLD X POSITION
|
||
ADD A,C ;OLD X + DELTA X
|
||
ADD B,D ;OLD Y + DELTA Y
|
||
JSR PC,TVDSSC ;TRY TO UPDATE THE CURSOR
|
||
BEQ TVDSN1 ;SOMETHING WRONG WITH NEW POSITION
|
||
REST <D,C> ;PUT THE INCREMENTS BACK
|
||
CLZ ;SUCCEED
|
||
RTS PC
|
||
TVDSN1: ADD #4,P ;POP THE STUFF WE SAVED
|
||
SEZ ;FAIL
|
||
RTS PC
|
||
|
||
;TVDSIL IOR'S A LINE ON THE SCREEN
|
||
TVDSIL: JSR PC,TVDSNL ;UPDATE THE CURSOR
|
||
BEQ TVDSX2 ;SOMETHING WENT WRONG
|
||
ASR E ;GET THE TV BUFFER NUMBER
|
||
BIS #TVIOR,E ;IOR MODE
|
||
BR TVDSX1 ;DRAW THE LINE AND RETURN
|
||
|
||
;TVDSXL XOR'S A LINE ON THE SCREEN
|
||
TVDSXL: JSR PC,TVDSNL ;UPDATE THE CURSOR
|
||
BEQ TVDSX2 ;SOMETHING WRONG
|
||
ASR E ;GET THE BUFFER NUMBER
|
||
BIS #TVXOR,E ;XOR MODE
|
||
TVDSX1: JSR PC,DRAW ;DRAW THE LINE
|
||
CLZ ;SUCCEED
|
||
RTS PC
|
||
TVDSX2: SEZ ;FAIL
|
||
RTS PC
|
||
|
||
;TVDSCL CLEARS AN AREA OF THE SCREEN
|
||
TVDSCL: JSR PC,TVDSNL ;UPDATE THE CURSOR, CHECK BOUNDS
|
||
BEQ TVDSX2 ;FAIL
|
||
ASR E ;THE TV BUFFER NUMBER
|
||
JSR PC,SCRCLR ;CLEAR THE SCREEN
|
||
CLZ ;SUCCEED
|
||
RTS PC
|
||
|
||
.ENDC
|
||
TVSAVE:
|
||
.IFNZ NTVS
|
||
MOV ITM0A,B ;POINT TO PROCESS
|
||
BIT #PTVFLG,PFLAGS(B) ;ALREADY SAVING?
|
||
BNE TVSAV1 ;YUP
|
||
MOV #PRSLFP,A ;SIZE OF PROCESS WITH FLOATING POINT
|
||
MOV ITEM0,B ;THE ITEM INDEX OF THE PROCESS
|
||
JSR PC,EXITEM ;EXPAND THE PROCESS TO INCLUDE SPACE FOR FLOATING POINT AC'S
|
||
ERRORC EQ,NIS
|
||
MOV B,A
|
||
JSR PC,ITM0LD ;LOAD THE NEW PROCESS
|
||
BIS #PTVFLG,PFLAGS(A) ;INDICATE SAVING
|
||
ASR E ;CONVERT WORD OFFSET TO BUFFER NUMBER
|
||
MOVB E,TVSEL ;SET THE RIGHT VALUE INTO THE SELECT REGISTER
|
||
TVSAV1: CLZ
|
||
RTS PC
|
||
.IFF
|
||
ERROR BFUN
|
||
.ENDC
|
||
TVMAPS:
|
||
.IFNZ NTVS
|
||
JSR PC,SAVAWB ;SAVE ANY WRITTEN PAGES
|
||
MOV ITM0A,B ;POINTER TO PROCESS
|
||
MOVB C,PTVMAP(B) ;SET IT'S MAP WORD
|
||
JSR PC,MAPRE1 ;RELOAD MY MAP
|
||
JMP ERETCZ
|
||
.IFF
|
||
ERROR BFUN
|
||
.ENDC
|
||
.STITL CREATE CAPABILITY ROUTINES
|
||
GIVXX:
|
||
TAKXX:
|
||
CPYXX:
|
||
DELXX:
|
||
COPXX:
|
||
CAPRXX:
|
||
CCPRXX:
|
||
CCPRSP: ERROR BCT ;THE ZERO CAPABILITY
|
||
|
||
CPYCC:
|
||
CCPRCC: CLR B
|
||
MOV #.CCCAP,A ;THIS IS EASY
|
||
CCRTS: RTS PC
|
||
|
||
;CREATE A COLOR MAP CAP
|
||
CCPRCM: TST CMUSE ;ANYONE ELSE GOT IT?
|
||
ERRORC NE,RNA ;YES
|
||
CPYCM: INC CMUSE
|
||
CLR B ;NO ITEM
|
||
MOV #.CMCAP,A
|
||
RTS PC
|
||
|
||
;CREATE A MASTER SHPERE CAPABILITY
|
||
CCPRMS: JSR PC,CRSPHR ;CREATE THE ACTUAL SPHERE
|
||
BEQ CCRTS ;NO SPHERE AVAILABLE
|
||
MOV A,B ;THE ITEM NO OF THE SPHERE
|
||
MOV E,C ;ENTER ADDRESS IS 2ND ARG TO CALL
|
||
MOV #MSPCBT!.MSCAP,A ;THE TYPE AND FLAGS
|
||
RTS PC
|
||
;CREATE A PROCESS CAPABILITY
|
||
CCPRPR: JSR PC,CRPROC ;CREATE THE ACTUAL PROCESS
|
||
BEQ CCRTS ;NO PROCESS AVAILABLE
|
||
MOV A,B ;FOR THE LOCK ROUTINE
|
||
JSR PC,ITM0PL ;LOAD IT UP
|
||
MOV E,C ;GET THE STARTING ADRS FOR THE PROCESS
|
||
MOV C,PUPC(A) ;PUT THE STARTING ADRS. INTO ITS USER PC
|
||
JSR PC,ITM0PO ;GET BACK THE ORIGINAL PROCESS
|
||
MOV #.PRCAP!.PRWRA,A ;ITS A PROCESS CAPABILITY
|
||
RTS PC ;SUCCESS
|
||
CCPRTT: CMP E,#NTTYS ;IS IT A LEGAL TTY NO.
|
||
BGT CCPRT1 ;NOPE TO LARGE
|
||
ASL E ;TURN IT INTO THE WORD INDEX
|
||
TST TTYITM(E) ;IS THERE ALREADY A ITEM FOR THIS TTY
|
||
BGT CCPRT1 ;YES, THIS IS A BAD CALL THEN
|
||
BIT #MXEEF,TTYTBL(E) ;IS IT A MULTIPLEXOR?
|
||
BEQ CCPRT2 ;NO
|
||
SAVE E ;THE TTY NUMBER
|
||
MOVB TTYTBL(E),E ;GET THE NUMBER OF THE MULTIPLEXOR TTY
|
||
MOV TTYITM(E),A ;IS THERE A TTY FOR THE MULTIPLEXOR
|
||
BNE CCPRT3 ;YES, JUST CREATE THE MULTIPLEXEE
|
||
JSR PC,CRTTY ;CREATE THE TTY
|
||
BEQ CCPRT5 ;FAILED
|
||
;HERE PUT IN SOMETHING TO CLEAN UP IF IT LOSES
|
||
MOV B,A ;THE ITEM NO. OF MXOR
|
||
JSR PC,ITM2LD ;LOAD IT UP
|
||
ADD TOQI(A),A ;POINT TO START OF OUTPUT QUEUE
|
||
MOV #NFNLTY,D ;POINT TO PSEUDO TTYS
|
||
MOV #NNLTY,B ;NUMBER OF TTY'S TO CHECK
|
||
CCPRT7: CMPB TTYTBL(D),E ;IS IT THE MULTIPLEXOR?
|
||
BNE CCPRT8 ;NOT THIS ONE
|
||
MOVB D,(A)+ ;PUT IT INTO QUEUE
|
||
CCPRT8: TST (D)+ ;SKIP THIS TTY NEXT TIME
|
||
SOB B,CCPRT7
|
||
BR CCPRT6 ;NOW OPEN UP THE MULTIPLEXEE
|
||
CCPRT3: JSR PC,ITM2LD ;LOAD UP THE TTY
|
||
TST TTYU(A) ;IS IT REALLY OWNED OR JUST OPENED BY THE SYSTEM
|
||
BEQ CCPRT4 ;OPENED BY THE SYSTEM
|
||
CMP TTYU(A),CURUSR ;IS IT OPENED BY THE CURRENT USER
|
||
BNE CCPRT1 ;NO, SO HE LOSES ON THE OPEN
|
||
CCPRT4: INC TTYREF(A) ;INCREMENT ITS REFERENCE COUNT
|
||
CCPRT6: REST E ;GET BACK THE MULTIPLEXEE'S TTY NO.
|
||
CCPRT2: JSR PC,CRTTY ;CREATE THE TTY
|
||
BEQ CCPRT1 ;IT FAILED FOR SOME REASON
|
||
MOV #.TTCAP!.TTYI!.TTYO,A ;GIVE HIM I/O CAPABILITY
|
||
RTS PC
|
||
CCPRT5: TST (P)+
|
||
CCPRT1: SEZ
|
||
RTS PC
|
||
|
||
;CREATE A QUE CAPABILITY
|
||
CCPRQU: MOV E,C ;THE NUMBER OF PEOPLE WHO CAN LOCK THE QUE
|
||
JSR PC,CRQUE ;CREATE THE QUE
|
||
BEQ CCPRQ1 ;FAILED
|
||
CLR C ;NO DATA WORDS
|
||
MOV #.QUCAP,A ;THE TYPE
|
||
CCPRQ1: RTS PC
|
||
|
||
;CREATE A QUE ITEM, C CONTAINS THE NUMBER OF PEOPLE WHO CAN LOCK THE QUE
|
||
CRQUE: MOV #QUELEN,A ;LENGTH OF QUE
|
||
JSR PC,CRITEM ;CREATE THE ITEM
|
||
BEQ CRQUE2 ;FAILED
|
||
MOV B,A ;THE ITEM NO
|
||
JSR PC,ITM2PL ;LOAD TI
|
||
MOV #ITQUE,(A) ;SET THE TYPE
|
||
CLR QUECNT(A) ;NOONE ON THE QUE TO START
|
||
MOV C,QUENUM(A) ;THE NUMBER OF PEOPLE WHO CAN LOCK THE QUE
|
||
MOV #1,QUEREF(A) ;ASSUME THE GUY WHO CREATES IT IS GOING TO REFERENCE IT
|
||
MOV #QUESZ/2,QUEENO(A) ;THE NUMBER OF ENTRIES IN THE QUE
|
||
JSR PC,ITM2PO ;POP THE QUE
|
||
CLZ
|
||
RTS PC
|
||
CRQUE1: SEZ
|
||
CRQUE2: RTS PC
|
||
|
||
.IFZ 105
|
||
CCPRTR: TST PTRITM ;IS THERE ONE ALREADY
|
||
BNE CRQUE1 ;YES, LOSER
|
||
MOV #PTRLEN,A ;GET THE LENGTH
|
||
JSR PC,CRITEM ;CREATE THE ITEM
|
||
BEQ CRQUE2 ;FAILED FOR RANDOM REASON
|
||
MOV B,A ;GET THE ITEM NO.
|
||
JSR PC,ITM2PL ;LOAD IT UP
|
||
MOV #ITPTR,(A)+ ;SET IN THE TYPE
|
||
MOV #1,(A)+ ;THE REFERENCE COUNT
|
||
MOV #PTRBUF,(A) ;THE START OF THE BUFFER
|
||
MOV (A)+,(A)+ ;SET IN THE DATA OUT POINTER
|
||
CLR (A)+ ;NOTHING IN BUFFER CURRENTLY
|
||
JSR PC,ITM2PO ;POP IT
|
||
MOV B,PTRITM ;SAY THIS IS THE PTR ITEM
|
||
MOV #1,PTRSR ;SET THE INTERRUPT ENABLE
|
||
CLR C ;NO SECONDARY ITEM
|
||
MOV #.TRCAP,A
|
||
RTS PC
|
||
|
||
CCPRTP: TST PTPITM ;PAPER TAPBE ITEM
|
||
BNE CRQUE1 ;FAIL THERE ALREADY IS ON
|
||
MOV #PTPLEN,A ;GET THE LENGTH
|
||
JSR PC,CRITEM ;CREATE THE ITEM
|
||
BEQ CRQUE2 ;FAILED
|
||
MOV B,A ;COPy THE ITEM NO.
|
||
JSR PC,ITM2PL ;LOAD IT UP
|
||
MOV #ITPTP,(A)+ ;TYPE
|
||
MOV #1,(A)+ ;REFERENCE COUNT
|
||
MOV #PTPBUF,(A) ;THE POINNTER TO START
|
||
MOV (A)+,(A)+ ;SET IT IN
|
||
CLR (A)+ ;NOTHING IN THE BUFFER
|
||
JSR PC,ITM2PO ;POP IT
|
||
MOV #.TPCAP,A ;THE TYPE OF CAPABLITY
|
||
CLR C ;NOTHING
|
||
MOV B,PTPITM ;THE ITEM IS NOW HERE
|
||
RTS PC
|
||
.IFF
|
||
CCPRTR: MOV #PTRLEN,A ;LENGHT OF ITEM
|
||
MOV #ITPTR,C ;TYPE OF ITEM
|
||
MOV #PTRBUF,D ;POINTER TO BUFFER IN ITEM
|
||
MOV #.TRCAP,E ;TYPE OF CAPABILITY
|
||
MOV #PTRITM,F ;WHERE ITEM IS STORED
|
||
TST (F) ;ITEM ALREADY?
|
||
BNE CCPRT0 ;YES, HE IS GOING TO LOSE
|
||
INC PTRSR ;OTHERWISE START TAPE READER AGAIN
|
||
BR CCPRT0
|
||
|
||
CCPRTP: MOV #PTPLEN,A ;LENGHT OF ITEM
|
||
MOV #ITPTP,C ;TYPE OF ITEM
|
||
MOV #PTPBUF,D ;POINTER TO BUFFER IN ITEM
|
||
MOV #.TPCAP,E ;TYPE OF CAPABILITY
|
||
MOV #PTPITM,F ;WHERE ITEM IS STORED
|
||
CCPRT0: TST (F) ;IS THERE ALREADY AN ITEM?
|
||
BNE CRQUE1 ;YUP, LOSE
|
||
JSR PC,CRITEM ;TRY TO CREATE ONE
|
||
BEQ CRQUE2 ;CAN'T
|
||
MOV B,A ;CREATED ITEM
|
||
JSR PC,ITM2LD ;LOAD IT
|
||
MOV C,(A)+ ;SET IN THE TYPE
|
||
MOV #1,(A)+ ;SET IN THE REFERENCE COUNT
|
||
MOV D,(A) ;SET POINTER TO START OF BUFFER
|
||
MOV (A)+,(A)+ ;COPY IT
|
||
CLR (A)+ ;CLEAR CHAR COUNT
|
||
MOV E,A ;CAPABILITY TYPE
|
||
CLR C
|
||
MOV B,(F) ;THE ITEM FOR THIS DEVICE
|
||
RTS PC
|
||
.ENDC
|
||
;CREATE A CORE LINK CAPABILITY, LENGTH OF BUFFER IN E
|
||
CCPRCL: MOV E,A ;COPY LENGTH
|
||
BLE CRQUE1 ;BAD LENGTH
|
||
ADD #CLDATL,A ;ADD THE NUMBER OF DATA WORDS
|
||
ASH #-6,A ;GET THE LENGTH IN 32. WORD BLOCKS
|
||
CMP A,#1 ;IS IT MORE THAN 2 BLOCKS
|
||
BGT CRCL1 ;YES, MAKE AN FUPT FOR IT
|
||
JSR PC,CRITEM ;CREATE AN ITEM
|
||
BEQ CCPRQ1 ;FAILED
|
||
MOV B,A ;COPY THE ITEM NO. CREATED
|
||
JSR PC,ITM2PL ;LOAD IT UP
|
||
MOV #ITCL,(A)+ ;SET IN THE TYPE
|
||
MOV B,C ;GET THE ITEM NO.
|
||
CRCL2: MOV #1,(A)+ ;SET IN THE REFENCE COUNT
|
||
CLR (A)+ ;SAY THERE IS NO CONSUMER
|
||
CLR (A)+ ;CLEAR THE COUNT OF VALID DATA
|
||
MOV E,(A)+ ;SET IN THE NUMBER OF ENTRIES
|
||
MOV #CLDATL,(A) ;SET IN THE DATA IN POINTER
|
||
MOV (A)+,(A) ;SET IN THE DATA OUT POINTER
|
||
SAVE B
|
||
JSR PC,ITM2PO ;POP THE ITEM
|
||
MOV #.CLCAP,A ;THE TYPE
|
||
BIT #GIPBIT,C ;IS IT IN A SPHERE
|
||
BNE CRCL4 ;NO
|
||
REST B
|
||
CLZ
|
||
RTS PC
|
||
CRCL4: MOV (P),B ;THE GIP TO THE FUPT
|
||
BIC #GIPBIT,B
|
||
CLR FUPTPR(B) ;SAY NO ONE OWNS IT NOW
|
||
REST B
|
||
CLZ
|
||
RTS PC
|
||
CRCL1: ASH #-4,A ;CONVERT 32 WORD BLOCKS TO 512 WORD BLOCKS
|
||
MOV A,B ;COPY
|
||
MOV A,D ;TWICE
|
||
CMP #7,A ;MORE THAN 4K?
|
||
ERRORC LT,BAD ;BAD ARG
|
||
JSR PC,FRCRGT ;GET SOME FREE CORE
|
||
ERRORC EQ,NSS ;NO SWAP SPACE AVAILABLE
|
||
MOV B,A ;GIP FOR CREATED CORE
|
||
JSR PC,ITM2PL ;LOAD IT UP
|
||
MOV #ITCL,(A)+ ;SWAP IT IN
|
||
JSR PC,LSWPOP ;NOW WE ARE SURE TO RUN TO COMPLETION
|
||
BR CRCL2 ;GO FINISH UP
|
||
;CREATE DISPLAY CAPABILITY
|
||
CCPRDS: .IFZ NTKDIS+NTVS
|
||
ERROR RNA
|
||
.IFF
|
||
TST E ;DOES HE WANT THE ONE ASSOCIATED WITH TTY?
|
||
BGE CCPRD7 ;NO
|
||
MOV E,B ;THIS HAS THE CAP INDEX OF TTY IN HIGH BYTE
|
||
BIC #177600,B ;CLEAN OFF THE 377
|
||
MOV #ITM1AD,A ;ADDRESS OF THE SPHERE
|
||
JSR PC,GCLSTA ;GET THE OFFSET OF THE CAPABILITY INTO SPHERE
|
||
BEQ CCPR15 ;Z SET MEANS BAD CAPABILITY NUMBER PASSED TO GCLSTA
|
||
ADD B,A ;THE OFFSET IS RETURNED IN B, GET THE ADDRESS OF CAP
|
||
CMPB (A),#.TTCAP ;MAKE SURE IT WAS A TTY
|
||
BEQ CCPR19 ;IT WASN'T SO FAIL
|
||
CCPR15: JMP CCPR12
|
||
CCPR19: MOV CLSEPI(A),A ;GET THE TTY ITEM NUMBER
|
||
JSR PC,ITM2LD ;LOAD IT UP
|
||
MOV TTLTTY(A),C ;GET THE LOGICAL TTY NUMBER OF THIS TTY
|
||
BIT #TVF,TTYTBL(C) ;IS IT A TV?
|
||
BNE CCPRD8 ;YES
|
||
BIT #40000,E ;DOE SHE WANT A TV?
|
||
BNE CCPRD5 ;LOSE
|
||
TST TYDISP(C) ;DOES IT EXIST
|
||
BLT CCPRD5 ;NO
|
||
BIC #377,E ;CLEAR OUT THE TTY NO.
|
||
BIS TYDISP(C),E ;GET TK DISP NEAR TTY
|
||
.ENDC
|
||
.IFZ NTKDIS
|
||
SEZ
|
||
RTS PC ;NO TK DISPLAYS
|
||
.IFF
|
||
|
||
MOV #DISMAL,A ;START LOOKING FOR A SMALL ONE
|
||
BIT #400,E
|
||
BEQ 1$
|
||
MOV #DISBIG,A ;HE REALLY WANTS A BIG ONE
|
||
1$: CLR B ;INDEX TO DISPLAY TABLES
|
||
MOV #NTKDIS,C ;NUMBER OF BUFFERS AVAILABLE
|
||
CCPRD3: CMP #-1,TKDRUN(B) ;AVAILABLE?
|
||
BNE CCPRD1 ;NOPE
|
||
CMP A,TKDLEN(B) ;ADEQUATE SIZE?
|
||
BLE CCPRD2 ;YES!
|
||
CCPRD1: TST (B)+ ;NEXT!
|
||
SOB C,CCPRD3
|
||
CCPRD5: SEZ ;RAN OUT OF POSSIBLITES
|
||
RTS PC
|
||
CCPRD2: MOVB E,C ;GET THE DISPLAY NUMBER HE WANTS
|
||
ERRORC LT,RNA
|
||
CCPRD4: TSTB TKDOWN(C) ;IS THAT DISPLAY FREE?
|
||
BNE CCPRD5 ;NOPE, YOU LOSE
|
||
MOVB #1,TKDOWN(C) ;USED NOW!
|
||
JSR PC,TKDSTP ;MAKE SURE IT IS STOPPED
|
||
BIS #100000,C ;OWNED, BUT DON'T START IT YET
|
||
MOV C,TKDRUN(B) ;IT BELONGS TO HIM
|
||
MOV B,C ;INDEX TO TABLES IS FIRST MISC WORD
|
||
MOV TKDITM(C),D ;THE ITEM FOR THE DISPLAY
|
||
MOV ITMTAB(D),B ;GET THE ADDRESS IN 32 WORD BLOCKS
|
||
SUB TKDPDA,B ;SUBTRACT START OF DISPLAY WORLD IN 32 WORD BLOCKS
|
||
ASH #5,B
|
||
JSR PC,GIVPSW ;RETURN THE OFFSET IN WORDS
|
||
MOVB ITLNGT+ITMTAB(D),B ;LENGTH IN 32 WORDS
|
||
INC B ;MINUSE ONE
|
||
ASH #5,B ;MAKE IT WORDS
|
||
JSR PC,GIVPSW ;RETRUN IT
|
||
MOV D,B ;SO THE ITEM GETS SAVED
|
||
MOV #.DSCAP,A ;AND THE TYPE
|
||
RTS PC
|
||
TKDSP: MOV 6(A),D ;THE DISPLAY INDEX
|
||
BIS #100000,TKDRUN(D) ;SO INT LEVEL WON'T START IT
|
||
MOV TKDRUN(D),C ;THE DISPLAY NUMBER
|
||
TKDSTP: SAVE <C>
|
||
BIC #177400,C ;JUST THE DISPLAY
|
||
BIS #TKSTOP,C
|
||
MOV C,NGCSR
|
||
REST <C>
|
||
RTS PC
|
||
.ENDC
|
||
.IFNZ NTVS
|
||
CCPRD7: MOVB E,C ;NUMER OF THE DISPLAY HE WANTS
|
||
BLT CCPRDT
|
||
CMPB C,#NFTVDS+NTVS ;THERE ARE ONLY THIS MANY DISPLAYS
|
||
BGE CCPR12 ;TOO HIGH! FAIL.
|
||
SUB #NFTVDS,C ;CONVERT TO PHYSICAL TV NUMBER FOR INDEX TO TABLES
|
||
BLT CCPR12 ;TOO LOW! FAIL
|
||
BR CCPRD9
|
||
CCPRD8: BIT #40000,E ;DOE SHE WANT A TV?
|
||
BEQ CCPR12 ;NOPE, LOSE
|
||
SUB #NFTV,C ;GET THE PHYSICAL NUMBER OF THE KEYBOARD
|
||
ASR C ;THIS WILL BE THE SAME AS THE NUMBER OF THE TV
|
||
CCPRD9: TST FNTITM ;DOES FONT ZERO EXIST?
|
||
ERRORC EQ,DEVE ;NO, "DEVICE" ERROR
|
||
MOVB TVDSBF(C),D;DOES THIS TV ALREADY HAVE A BUFFER?
|
||
BGE CCPR11 ;YES, IT MUST ALREADY HAVE A TV BUFFER
|
||
JSR PC,GETTV
|
||
CCPR11: MOVB D,TVDSBF(C);ALLOCATE THIS BUFFER (D) TO THIS TV (C)
|
||
MOVB C,TVBUFF(D);SAY THAT THIS BUFFER IS ALLOCATED
|
||
INCB TVDSRF(C) ;ONE MORE PERSON IS REFERENCING THIS TV
|
||
ADD #NFTVDS,C ;FIRST RANDOM WORD IN CAP IS LOGICAL DISPLAY NUMBER
|
||
ASL C ;IT SHOULD BE A WORD INDEX INTO TABLES
|
||
CCPR10: MOV D,B ;FOR NOW, THE ADDRESS OF A TV BUFFER IS IRRELEVENT
|
||
JSR PC,GIVPSW ;RETURN A ZERO, JUST FOR COMPATABILITY
|
||
MOV #100000,B ;A TV BUFFER HAPPENS TO BE 16K WORDS LONG
|
||
JSR PC,GIVPSW ;MIGHT AS WELL GIVE IT TO HIM ANYWAY
|
||
CLR B ;RETURN THE FACT THAT THERE IS NO ITEM FOR TV DISPLAY
|
||
MOV #100000!.DSCAP,A ;THIS WILL BE A DISPLAY CAPABILITY
|
||
RTS PC ;NOTE THAT THE PREVIOUS INST. CAUSED Z CLEARED
|
||
CCPR12: SEZ ;FAIL
|
||
RTS PC
|
||
|
||
GETTV: MOV #NTVCHN,B ;THE NUMBER OF TV CHANNELS OR BUFFERS
|
||
CLR D ;OFFSET INTO THE TVBUFF TABLE
|
||
GETTV1: TSTB TVBUFF(D) ;IS THIS BUFFER FREE?
|
||
BLT GETTV2 ;YES (-1 MEANS FREE)
|
||
INC D ;TRY THE NEXT BUFFER
|
||
SOB B,GETTV1 ;ANY MORE BUFFERS LEFT?
|
||
ERROR RNA
|
||
GETTV2: RTS PC
|
||
|
||
CCPRDT: BIT #40000,E ;DOES HE WANT A TV?
|
||
BEQ CCPR12 ;NOPE
|
||
JSR PC,GETTV ;GET ONE
|
||
CLRB TVBUFF(D) ;MAKE IT USED
|
||
MOV D,C
|
||
BIS #100000,C
|
||
BR CCPR10
|
||
.ENDC
|
||
|
||
CCPRLP: MOV #PRTLEN,A ;GET THE ITEM ALLOCATED
|
||
JSR PC,CRITEM ;CREAT AN ITEM
|
||
ERRORC EQ,NIT ;NO ITEM
|
||
MOV B,A ;LOAD UP THE ITEM
|
||
TST LPTITM ;LPT UNUSED?
|
||
BEQ 1$ ;YES
|
||
JSR PC,DLITEM ;DELETE THE ITEM
|
||
ERROR RNA ;AND REPORT ERROR
|
||
1$: JSR PC,ITM2LD
|
||
MOV #ITLPT,(A)+ ;FILL IT IN
|
||
MOV #1,(A)+ ;REFERENCE COUNT
|
||
MOV #PRTEND,(A)+ ;POINT TO THE END OF THE PRINTER BUFFER
|
||
CLR (A)+ ;SET THE LINE COUNT TO 0
|
||
CLR (A)+ ;START IN PRINT MODE
|
||
MOV #PRTCSR,(A)+ ;SET IN POINTER TO THE PRINTER CONTROL STATUS REG.
|
||
MOV #LPTBUF,(A) ;PUT IN THE DATA IN POINTER
|
||
MOV (A)+,(A)+ ;COPY IT
|
||
CLR (A)+ ;CLEAR THE NUMBER OF BYTES IN BUFFER
|
||
CLR (A)+ ;NO BYTES TRANSFERED ON LAST TRANSFER
|
||
CLR (A)+ ;NO BYTES ON THE CURRENT LINE
|
||
CLR C ;NO DATA WORDS
|
||
MOV #.LPCAP,A ;TYPE OF CAP
|
||
MOV B,LPTITM ;TELL EVERYONE THAT THERE EXISTS ONE
|
||
MOV #2,PRTCSR ;DO A REMOTE RESET ON THE PRINTER
|
||
RTS PC ;DONE
|
||
.STITL PROCESS CAPABILITY ROUTINES
|
||
;INVOKE A PROCESS CAPABILITY, FUNCTION 0-7 IS USER'S REGISTERS
|
||
;10 IS USERS PS, 11-16 IS USERS FPP REGISTERS 17 IS FLOATING POINT STATUS
|
||
;40 BIT CLEAR MEANS READ (CURRENT VALUE PUSHED ON USERS STACK)
|
||
;40 BIT SET MEANS WRITE (2ND DATA WORD IS PLACED IN USERS REGISTER)
|
||
;A FUNCTION OF 20 ALLOWS READ/WRITE OF THE AVAILABILITY OF FPP
|
||
;IF READ, THE WORD RETURNED IS EITHER 1 (FLOATING POINT ENABLED) OR
|
||
;0 (NO FLOATING POINT). IF WRITE, THE SECOND WORD ON THE STACK MUST BE
|
||
;EITHER 1 OR 0. A FUNCTION OF 21 ALLOWS WRITE AND READ OF THE SUPERIOR STOP BIT.
|
||
;IF WRITE, 0 MEANS START THE PROCESS, 1 MEANS STOP IT. READ, NON ZERO MEANS STOPPED
|
||
;FUNCTIONS 23-25 MEAN READ AND WRITE THE FAULT WORDS 1-3
|
||
;FUNCTION 24 READS AND WRITES THE ERROR WORD
|
||
CAPRPR: REST C ;GET THE FUNCTION BYTE
|
||
ASH #-7,C ;TURN IT INTO A WORD INDEX
|
||
BIC #177001,C ;CLEAR EXTRA BITS
|
||
MOV C,D ;COPY IT
|
||
ASR D ;SHIFT IT BACK DOWN
|
||
BIC #.PRWRT*2,C ;CLEAR THE READ/WRITE BIT
|
||
BIT #.PRWRT,D ;IS HE WRITING
|
||
BEQ CPRPR1 ;NOPE
|
||
BIT #.PRWRA,(A) ;DOES HE HAVE WRITE ACCESS?
|
||
BNE CPRPR1 ;YES
|
||
CPRPR2: ADD #4,P
|
||
JMP BADEMT ;BARF
|
||
CPRPR1: CMP C,#PRHGH ;IS IT TO HIGH
|
||
BGE CPRPR2 ;YES
|
||
MOV 2(A),A ;ITEM OF THE PROCESS
|
||
JSR PC,ITM2LD ;LOAD IT UP
|
||
JMP @PRIVTB(C) ;DO THE FUNCTION
|
||
|
||
PRREG: ADD C,A ;MAKE A POINT TO THE REG (WELL ALMOST)
|
||
ADD #PUREGS,A ;POINT TO THE REGISTER IN DOUBT
|
||
PRRET: BIT #.PRWRT,D ;READING?
|
||
BNE REGWRT ;NOPE
|
||
MOV (A),B ;GET THE APPROPRIATE REG INTO B
|
||
PRRET1: JSR PC,GIVPSW ;GIVE IT TO HIM
|
||
ADD #4,P ;GET RID OF TWO ARGUMENTS
|
||
JMP ERETCZ ;WE WIN
|
||
REGWRT: REST (A) ;SECOND ARG GOES INTO REGISTER
|
||
PRRET0: TST (P)+ ;GET RID OF THIRD ARG
|
||
JMP ERETCZ ;WE WIN
|
||
;HERE IS PSW AND FLOATING REG READ
|
||
|
||
PRPSW: ADD #PUPS,A ;POINT TO THE PSW
|
||
MOVB 1(A),1(P) ;DONT LET HIM CHANGE MODE
|
||
BIC #340,(P) ;OR PRIORITY
|
||
BR PRRET ;RETURN IT OR WRITE IT
|
||
|
||
PRFREG: MOV (P),E ;GET POINTER TO DATA
|
||
MFPD (E)+ ;MAKE SURE WE CAN GIVE IT TO HIM
|
||
MFPD (E)+
|
||
MFPD (E)+
|
||
MFPD (E)+
|
||
ADD #10,P ;POP OFF THE STUFF
|
||
REST E ;POINTER TO DATA IS 2ND ARG
|
||
SUB #2*.PRFREG,C ;MAKE THIS AN INDEX TO A FLOATING REG
|
||
ASH #2,C ;EACH REGISTER IS 4 WORDS
|
||
BIT #PFPFLG,PFLAGS(A) ;DOES HE HAVE THE FPP ENABLED?
|
||
BEQ PRFLT3 ;NOPE
|
||
BIT #.PRWRT,D ;IS HE WRITING INTO THIS REG?
|
||
BNE PRWRT ;YEP
|
||
ADD C,A ;MAKE THE A POINT TO A FLOATING REG(ALMOST)
|
||
ADD #PFPPRG+10,A ;MAKE IT ABSOLUTELY POINT TO THE APPROPRIATE REG
|
||
SAVE <-(A),-(A),-(A),-(A)> ;SAVE THE FPP REGISTER
|
||
MTPD (E)+ ;GIVE HIM THE REGISTER IF YOU CAN
|
||
MTPD (E)+
|
||
MTPD (E)+
|
||
MTPD (E)+
|
||
PRFLT2: TST (P)+ ;THIRD ARG NOT USED
|
||
JMP ERETCZ
|
||
PRFLT3: ERROR BAC ;NO ACCESSS TO FPP
|
||
PRWRT: MFPD (E)+ ;GET THE REGISTER (IF WE CAN)
|
||
MFPD (E)+
|
||
MFPD (E)+
|
||
MFPD (E)+
|
||
ADD C,A ;MAKE THE A POINT TO A FLOATING REG(ALMOST)
|
||
ADD #PFPPRG+10,A ;MAKE IT ABSOLUTELY POINT TO THE APPROPRIATE REG
|
||
REST <-(A),-(A),-(A),-(A)> ;PUT THE REGISTER AWAY
|
||
BR PRFLT2 ;RETURN
|
||
|
||
PRFPST: BIT #PFPFLG,PFLAGS(A) ;DOES IT USE THE FPP
|
||
BEQ PRFLT3 ;NO LUSER
|
||
ADD #PFPPS,A ;POINT TO THE REGISTER
|
||
BIT #.PRWRT,D ;IS IT A WRITE
|
||
LBR ,PRRET ;TRANFER THE PROCESSOR STATUS
|
||
|
||
PRFPEN: BIT #.PRWRT,D ;IS HE WRITING
|
||
BNE FPPWRT ;YEP
|
||
CLR B ;ASSUME THAT THERE ISNT ANY FPP
|
||
BIT #PFPFLG,PFLAGS(A) ;DOES HE HAVE FPP
|
||
BEQ 1$ ;NOTHING HERE
|
||
INC B ;SAY HE HAS FPP
|
||
1$: JMP PRRET1 ;RETURN 1 ARG
|
||
|
||
FPPWRT: MOV ITEM2,B ;WE WANT THE ITEM TO DO IT TO
|
||
REST E ;GET THE FIRST ARG
|
||
CMP E,#1 ;IS IT A LEGAL ARG
|
||
BHI PRLOSE ;TO BIG
|
||
BEQ PWRT1 ;ITS A REQUEST FOR FPP
|
||
BIT #PFPFLG,PFLAGS(A) ;DOES HE ALREADY HAVE IT
|
||
BEQ PWRT2 ;NO, WHY BOTHER
|
||
MOV ITEM2,B ;THE ITEM INDEX OF WHAT TO SHRINK
|
||
MOV #PRSLNF,A ;TELL IT THE SIZE WE WANT
|
||
JSR PC,EXITEM ;SHRINK THIS ITEM
|
||
MOV ITEM2,A ;GET BACK THE ITEM
|
||
JSR PC,ITM2LD ;LOAD IT BACK UP IN ITS NEW FORM
|
||
BIC #PFPFLG,PFLAGS(A) ;SAY HE DOESN'T HAVE FPP
|
||
JMP PRRET0 ;RETURN SUCESSFUL
|
||
PWRT1: BIT #PFPFLG,PFLAGS(A) ;DOES HE ALREADY HAVE IT
|
||
BNE PWRT2 ;YES
|
||
MOV #PRSLFP,A ;THE LENGTH WE WANT IT TO BE
|
||
JSR PC,EXITEM ;EXPAND THE PROCESS
|
||
ERRORC EQ,NIT ;NO ITEM LARGE ENOUGH
|
||
MOV ITEM2,A ;THE NEW ITEM
|
||
JSR PC,ITM2LD ;LOAD IT UP
|
||
BIS #PFPFLG,PFLAGS(A) ;SAY WE HAVE FPP
|
||
MOV #40300,PFPPS(A) ;START WITH INT. DISABLED AND LONG AND DOUBLE
|
||
PWRT2: JMP PRRET0 ;RETURN NO ARG
|
||
PRLOSE: ERROR BFUN ;BAD FUNCTION
|
||
|
||
PRSTOP: ADD #PSTOP,A ;POINT TO THE STOP WORD
|
||
BIT #.PRWRT,D ;IS IT A WRITE
|
||
BNE PRSTP1 ;YES
|
||
MOV (A),B ;GET THE STOP WORD
|
||
JMP PRRET1 ;RETURN IT TO HIM
|
||
PRSTP1: CMP (P),#1 ;IS IT A ONE
|
||
BHI PRLOSE ;FAIL
|
||
BEQ PRSTP2 ;STOP IT
|
||
BIT #PSUPSB,(A) ;IS HE STOPPED BY A CAPABILITY
|
||
BEQ PRSTP3 ;NO, JUST RETURN
|
||
BIC #PSUPSB,(A) ;CLEAR THE BIT
|
||
MOV ITM2A,A ;POINT AT THE PROCESS
|
||
TST PSPHRP(A) ;IS IT IN A SPHERE?
|
||
ERRORC LE,BAD ;NO, DON'T TRY TO START IT
|
||
MOV ITEM2,A ;THE PROCESS
|
||
JSR PC,PSTPDC ;DECREMENT THE STOP COUNT
|
||
PRSTP3: TST (P)+ ;POP OFF THE ARG
|
||
JMP PRRET0 ;DONE
|
||
PRSTP2: BIT #PSUPSB,(A) ;HAS SOMEONE ELSE ALREADY STOPPED IT
|
||
BNE PRSTP3 ;SOMEONE BEAT US TO IT.
|
||
BIS #PSUPSB,(A) ;SET THE STOP BIT
|
||
MOV ITEM2,A ;THE PROCESS TO STOP
|
||
JSR PC,PSTPIN ;STOP IT
|
||
ADD #4,P ;POP ARGS
|
||
JMP ERETCZ
|
||
|
||
PRFAUL: SUB #.PRFAUL*2,C ;CREATE AN OFFSET
|
||
ADD C,A ;POINT TO IT
|
||
ADD #PFAULT,A ;GET THE FIRST FAULT WORD
|
||
BIT #.PRWRT,D ;IS IT A WRITE REQUEST
|
||
BNE PRFAUW ;WRITE REQUEST
|
||
MOV (A),B ;GET THE FAULT WORD
|
||
JMP PRRET1 ;RETURN IT
|
||
PRFAUW: TST (P) ;WRITING A ZERO?
|
||
BEQ PFAUW1 ;YES
|
||
PFAUW2: JMP PRRET ;CAUSE THE WRITE
|
||
PFAUW1: TST (A) ;IS IT FAULTED ALREADY
|
||
BEQ PFAUW2 ;NO
|
||
MOV PSPHRP-PFAULT(A),B ;POINTER TO THE SPHERE
|
||
BEQ 1$ ;NOT IN SPHERE?
|
||
JSR PC,FALTFX ;FIX THE FAULT
|
||
1$: JMP REGWRT
|
||
|
||
PRERR: ADD #PERRW,A
|
||
BR PFAUW2 ;DO THE READ/WRITE
|
||
PRERA: ADD #PERRAD,A
|
||
BR PFAUW2
|
||
|
||
CAPRLP: TST (P)+ ;GET RID OF FIRST ARGUMENT
|
||
CMP (P),#4 ;THE MAXIMUM SCALE FACTOR
|
||
ERRORC HI,BAD ;BAD ARUMENTS
|
||
MOV 2(A),A ;THE LPTITM
|
||
MOV A,B ;COPY IT FOR EXITEM
|
||
JSR PC,ITM2LD ;LOAD IT UP
|
||
CAPRL1: TST LPTPCT(A) ;GOT BYTES TO TRANSFER ON A LINE STILL
|
||
ERRORC NE,BFUN ;CANT UNTIL TRANSFER IS FINISHED
|
||
BIT #40100,@LPTCSR(A) ;IS THE INTERRUPT TURNED OFF?
|
||
BNE CAPRL2 ;NO FLUSH YOURSELF
|
||
TST LPTNUM(A) ;BYTES IN LINE BUFFER?
|
||
BEQ LPTMD1 ;FINE ITS EMPTY
|
||
CAPRL2: JSR PC,LFLUSH ;FLUSH YOURSELF
|
||
TST LPTPCT(A) ;GOT BYTES TO TRANSFER ON LINE?
|
||
BNE CAPRL3 ;CHECK THIS OUT IMMEDIATELY
|
||
BIT #40100,@LPTCSR(A) ;INTERRUPT OFF?
|
||
BNE CAPRL2 ;NO
|
||
TST LPTNUM(A) ;BYTES LEFT?
|
||
BNE CAPRL2 ;YES, FLUSH AWAY
|
||
CAPRL3: JSR PC,RUNME ;RUN ME
|
||
BR CAPRL1 ;MAKE SURE IT IS STILL DONE
|
||
LPTMD1: MOV #LPTBUF,LPTDAI(A) ;RESET THE POINTERS TO THE START
|
||
MOV #LPTBUF,LPTDAO(A) ;IN CASE WE WERE IN PLOT MODE, AND SHRINKING BUFFER
|
||
BIS #4,@LPTCSR(A) ;SET THE CLEAR BUFFER BIT (IN EITHER CSR, DONT MATTER)
|
||
MOV (P)+,LPTMOD(A) ;SET THE MODE
|
||
BEQ LPTPR ;INTO PRINT MODE
|
||
MOV #PLTCSR,LPTCSR(A) ;NOW IN PLOT MODE
|
||
MOV #PLTEND,LPTEND(A) ;POINT TO THE END OF THE BUFFER OF THE PLODDER
|
||
MOV #PLTLEN,A ;NEW LENGTH
|
||
BR LPTMD2 ;NOW RETURN
|
||
LPTPR: MOV #PRTCSR,LPTCSR(A)
|
||
MOV #PRTEND,LPTEND(A) ;POINT TO THE END OF THE PRINTER BUFFER
|
||
MOV #PRTLEN,A ;THE LENGTH IN PRINT MODE
|
||
LPTMD2: JSR PC,EXITEM ;DO THE RIGHT THING (EXPAND, CONTRACT, OR IGNORE)
|
||
TST (P)+ ;POP OFF LAST ARG
|
||
JMP ERETCZ ;RETURN
|
||
|
||
CAPRTR:
|
||
CAPRTP: ERROR BFUN
|
||
|
||
CPYCL: MOV #.CLCONS,E ;CLEAR THE CONSUMER FLAG ON COPY
|
||
MOV 2(F),B ;POINTER TO CORE LNK
|
||
BR CPYFA1 ;INCREMENT THE REFERENCE COUNT
|
||
CPYLP:
|
||
CPYTR:
|
||
CPYTP:
|
||
CPYQU: CLR E ;NO FLAGS TO CLEAR
|
||
BR CPYFA1 ;INCREMENT THE REFERENCE COUNT
|
||
;COPY PROCESS CAPABILITY, 2ND ARG SPECIFIES A MASK OF BITS TO
|
||
;BE CLEARED, NO BITS MAY BE SET.
|
||
CPYPR: BIC #377,E ;MAKE SURE YOU ONLY TOUCH THE TOP BYTE
|
||
BR CPYFA1 ;CREATE THE SPERE CAP.
|
||
|
||
CPYFA: BIS #<-.FARD-.FAWT-.FAAP-.FAAC>-177400,E
|
||
CLRB E
|
||
MOV FAMFI(F),B
|
||
CPYFA1: JSR PC,SPRINC
|
||
MOV (F),A ;THE FLAG WORD
|
||
BIC E,A
|
||
RTS PC
|
||
|
||
;COPY TTY CAPABILITY, SAME AS COPY SPHERE
|
||
CPYTT:
|
||
;COPY SPHERE CAPABILITY, ARGS SAME AS PROCESS CALL
|
||
CPYSP: MOV (F),A
|
||
BR CPYMS1
|
||
|
||
;COPY A MASTER SPHERE CAPABILITY, BECOMES A SPHERE CAP. 2ND ARG
|
||
;SPECIFIES A MASK OF BITS TO BE CLEARED DURING THE COPY
|
||
|
||
CPYMS: MOV #MSPCBT!.SPCAP,A
|
||
TST 4(F) ;IS THIS THE FIRST COPY OF A MASTER SPHERE?
|
||
BNE CPYMS1 ;NOPE
|
||
MOV D,10(F) ;MAKE THE MASTER SPHERE POINT TO ITSELF TEMPORARILY
|
||
MOV ITEM1,4(F) ;SET IN THE ITEM NO.
|
||
CPYMS1: MOV 2(F),B ;THE ITEM NO.
|
||
JSR PC,SPRINC ;INCREMENT SPERE'S REFERENCE COUNTER
|
||
BIC #377,E ;ONLY THE TOP BYTE IS SIGNIFICANT
|
||
BIC E,A ;CLEAR THE CORRECT BITS
|
||
MOV 2(P),E ;POINTER TO CAP DESTINATION
|
||
MOV 2(F),B ;THE ITEM NO. OF SPHERE OF MS CAP
|
||
MOV 4(F),4(E) ;POINTER TO NEXT SPHERE CAP
|
||
MOV 10(F),10(E) ;REST OF POINTER TO NEXT CIRCULAR LIST ENTRY
|
||
MOV ITEM1,4(F) ;THE FIRST SPHERE ON CIRCLE LIST IS THIS SPHERE
|
||
MOV 4(P),10(F) ;THE CAP. NO IS IN B
|
||
RTS PC
|
||
|
||
;COPY OF DISPLAY CAPABILITY IS NOT ALLOWED
|
||
CPYDS: ERROR BFUN
|
||
.STITL GIVE CAPABILIY ROUTINES
|
||
GIVSP: SAVE <A,B,C,D>
|
||
;A CONTAINS RELATIVE POINTER TO DEST. C-LIST ENTRY
|
||
;B THE C-LIST NO. OF DEST
|
||
;C THE SPHERE NO. OF DEST
|
||
MOV E,B ;THE C-LIST NO. OF THE SOURCE C-LIST ENTRY
|
||
MOV D,A ;THE POINTER TO THE SOURCE C-LIST ENTRY
|
||
JSR PC,FNBKPT ;FIND THE PREVIOUS ENTRY IN CIRCULAR LIST
|
||
MOV C,A ;THE PREVIOUS SPHERE
|
||
MOV D,B ;THE PREVIOUS C-LIST NO
|
||
JSR PC,ITM1PL ;LOAD IT UP
|
||
JSR PC,GCLSTA ;FIND IT
|
||
ADD A,B ;MAKE A POINT TO IT
|
||
MOV 2(P),4(B) ;CORRECT SPHERE POINTER
|
||
MOV 4(P),10(B) ;CORRECT C-LIST POINTER
|
||
JSR PC,ITM1PO ;POP THE SPHERE
|
||
REST <D,C,B,A>
|
||
;FALL THROUGH AND TRANSFER THE CAPABILITY
|
||
|
||
;MAY FALL THROUGH FROM GIVE SPHERE ROUTINE
|
||
GIVCC: ;CREATE CAP. GIV IS SAME AS PROCESS CAP. GIVE
|
||
GIVCM:
|
||
GIVTP:
|
||
GIVTR:
|
||
GIVTT:
|
||
GIVLP:
|
||
GIVQU:
|
||
GIVCL:
|
||
GIVFA:
|
||
GIVPR:
|
||
GIVDS: JSR PC,GIVPSW ;GIVE HIM THE WORD, (CAN'T FAIL FROM HERE ON IN)
|
||
SAVE A ;SAVE THE POINTER TO THE CAP TO GIVE
|
||
MOV C,A ;THE DESTINATION SPHERE
|
||
JSR PC,ITM2LD ;LOAD IT UP
|
||
ADD (P)+,A ;MAKE A POINT TO THE C-LIST ENTRY
|
||
MOV D,B ;POINTER TO THE CAPABILITY TO GIVE
|
||
MOV (B)+,(A)+ ;MOV THE CAPABILITY
|
||
MOV (B)+,(A)+
|
||
MOV (B)+,(A)+
|
||
MOV (B)+,(A)+
|
||
MOV (B)+,(A)+
|
||
CLR (D) ;GET RID OF IT
|
||
ADD #4,P ;POP OFF THE TWO ARGS
|
||
JMP ERETCZ
|
||
|
||
|
||
GIVMS: SAVE <A,D>
|
||
MOV C,A ;THE SPHERE THAT WE ARE GIVING TO
|
||
JSR PC,ITM2LD
|
||
MOV 2(D),D ;THE SPHERE THAT THE MS REFERS TO
|
||
MOV SMSSPT(A),A ;JUST CHECK THIS ONE'S SUPERIOR
|
||
GIVMS1: CMP A,D ;IS THE SUPERIOR SPHERE, THE ONE THE MS REFERS TO
|
||
BEQ GIVMS2 ;YES, WE MUST FAIL
|
||
CMP A,SYSSPR ;IS IT THE SYSTEM SPHERE
|
||
BEQ GIVMS3 ;YES, THEN GIVING IT AWAY IS FINE
|
||
JSR PC,ITM2LD ;LOAD UP THE SUPERIOR SPHERE
|
||
MOV SMSSPT(A),A ;GET THIS ONES SUPERIOR SPHERE
|
||
BR GIVMS1 ;GO BACK AND CHECK IT OUT
|
||
GIVMS2: ERROR BAD ;TRIED TO GIVE TO INFERIOR (NOT GOOD ENOUGH) SPHER
|
||
GIVMS3: MOV D,A ;THE SPHERE THE MS REFERS TO
|
||
JSR PC,ITM2LD ;LOAD IT UP
|
||
MOV C,SMSSPT(A) ;FIX ITS MASTER SPHERE POINTER
|
||
;(HERE FIX USER POINTER ALSO?)
|
||
REST <D,A>
|
||
BIS #.SPFES,(D) ;SUPRESS ENTERS UNLESS HE TURNS IT ON
|
||
BR GIVSP ;NOW GIVE IT AWAY LIKE A SPHERE
|
||
.STITL DELETE CAPABILITY ROUTINES
|
||
DELCM: DEC CMUSE ;ONE LESS CAP
|
||
DELCC: CLR (A) ;CLEAR THE FIRST WORD
|
||
CLZ
|
||
RTS PC
|
||
DELPR: CLR (A) ;FLUSH THE CAPABILITY
|
||
MOV 2(A),A ;GET THE ITEM INDEX
|
||
JSR PC,PSTPIN ;STOP HIM FROM RUNNING
|
||
SAVE A
|
||
JSR PC,DLPROC ;DEC PROCESSES REF COUNT
|
||
BEQ DELPR1 ;WE DELETED THE PROCESS
|
||
REST A ;GET THE PROCESS ITEM NO.
|
||
JSR PC,PSTPDC ;DECREMENT HIS STOP COUNT
|
||
CLZ
|
||
RTS PC
|
||
DELPR1: REST A ;GET BACK ITEM INDEX
|
||
CLZ
|
||
RTS PC
|
||
|
||
DELSP: SAVE A
|
||
MOV E,B ;THE CAP. NO. TO FLUSH
|
||
JSR PC,FNBKPT ;FIND THE PREVIOUS ENTRY
|
||
MOV (P),A ;GET THE ADDRESS BACK
|
||
MOV 4(A),E ;THIS SPHERE'S POINTER
|
||
MOV 10(A),F ;THE REST OF THE POINTER
|
||
MOV C,A ;THE PREVIOUS ENTRY'S SPHERE
|
||
JSR PC,ITM1PL ;LOAD IT UP
|
||
JSR PC,GCLSTA ;GET APOINTER TO IT
|
||
ADD A,B ;MAKE THE POINTER ABSOLUTE
|
||
TST B ;DOES IT EXIST
|
||
BUGC EQ ;YES
|
||
MOV E,4(B) ;SPLICE OUT ENTRY WE ARE DELETING
|
||
MOV F,10(B)
|
||
JSR PC,ITM1PO ;POP THE SPHERE
|
||
REST A
|
||
|
||
DELTP: SAVE A ;SAVE POINTER TO CAP
|
||
MOV 2(A),A ;THE ITEM
|
||
DELTP3: JSR PC,ITM2PL ;LOAD IT UP
|
||
CMP #1,PTPREF(A) ;IS THIS THE LAST ONE?
|
||
BNE DELTR1 ;NO, JUST DELETE IT
|
||
TST PTRNO(A) ;ANY CHARACTERS LEFT TO PUNCH?
|
||
BEQ DELTP4 ;NO
|
||
DELTP1: MOV ITEM2,A ;COPY ITEM NO.
|
||
JSR PC,ITM2PO ;POP IT
|
||
JSR PC,LFLUSH ;WAIT A LONG TIME
|
||
JSR PC,ITM2PL ;LOAD IT
|
||
CMP #1,PTPREF(A) ;ANOTHER CAP?
|
||
BNE DELTP2 ;YES
|
||
TST PTRNO(A) ;CHARACTERS LEFT?
|
||
BNE DELTP1 ;YES
|
||
DELTP2: MOV ITEM2,A
|
||
JSR PC,ITM2PO ;CLEAN UP A BIT
|
||
JSR PC,RUNME
|
||
BR DELTP3 ;CHECK TO MAKE SURE
|
||
DELTP4: CLR PTPITM
|
||
BR DELTR1
|
||
DELTR: SAVE A ;SAVE POINTER TO CAP
|
||
MOV 2(A),A ;GET THE TR ITEM
|
||
JSR PC,ITM2PL ;LOAD IT UP
|
||
CMP #1,PTRREF(A) ;REF COUNT 1
|
||
BNE DELTR1 ;NO
|
||
CLR PTRITM ;NO MORE PTR
|
||
DELTR1: JSR PC,ITM2PO ;POP IT
|
||
REST A ;GET BACK A AND DROP IN TO DELETE IT
|
||
|
||
;DELETE QUE CAPABILITY, JUST DEC REFERENCE COUNT, AND FLUSH CAP.
|
||
DELQU: CLR (A) ;FLUSH THE CAPABLITY
|
||
MOV 2(A),A ;THE ITEM INDEX OF THE SPRERE
|
||
JSR PC,SPRDEC ;DECREMENT SPHERE REF COUNT
|
||
CLZ
|
||
RTS PC
|
||
|
||
;DELETE CORE LINK JUST FLUSH IT AND CHECK REFERENCE COUNT
|
||
DELCL: BIT #.CLCONS,(A) ;AM I THE CONSUMER
|
||
BEQ DELQU ;YES
|
||
SAVE A
|
||
MOV 2(A),A ;THE ITEM OR GIP
|
||
JSR PC,ITM2PL
|
||
CLR CLCONP(A) ;SAY THERE IS NO MORE CONSUMER
|
||
JSR PC,ITM2PO
|
||
REST A
|
||
BR DELQU
|
||
|
||
;DELETE LINPRINTER CAPABILITY
|
||
DELLP: SAVE A ;SAVE THE CAPABILITY
|
||
MOV 2(A),A ;GET THE LPT ITEM
|
||
JSR PC,ITM2PL ;LAOD IT UP
|
||
DELLP2: CMP #1,LPTREF(A) ;IS HE THE ONLY ONE
|
||
BNE DELLP1 ;NO
|
||
JSR PC,LPTCHK ;CAN WE FLUSH HIM
|
||
BEQ DELLP3 ;YES
|
||
DELLP6: JSR PC,SFLUSH ;GO AWAY FOR A WHILE
|
||
CMP #1,LPTREF(A) ;STILL THE ONLY ONE?
|
||
BNE DELLP5 ;NO TRY AGAIN
|
||
JSR PC,LPTCHK ;SEE IF WE CAN FLUSH HIM
|
||
BNE DELLP6 ;CANT
|
||
DELLP5: JSR PC,RUNME ;RUN ME
|
||
BR DELLP2 ;JUST MAKE SURE
|
||
DELLP3: MOV ITEM2,A ;THE ITEM TO DELETE
|
||
CLR LPTITM ;SAY NO MORE ITEM
|
||
JSR PC,DLITEM ;BYE BYE
|
||
BR DELLP4
|
||
DELLP1: DEC LPTREF(A) ;DEC REF COUNT
|
||
DELLP4: JSR PC,ITM2PO ;POP IT
|
||
REST A ;POINTER TO THE CAPABILITY
|
||
CLR (A) ;DELETE IT
|
||
CLZ ;AND RETURN
|
||
RTS PC
|
||
|
||
LPTCHK: TST @LPTCSR(A) ;ERROR?
|
||
BMI LPTFLS ;YES, ALLOW IT TO BE FLUSHED
|
||
TST LPTNUM(A) ;ANY CHARACTERS?
|
||
BNE LPTNFL ;YES, DONT FLUSH ME YET...
|
||
TST LPTWCT(A) ;INTERRUPT DONE?
|
||
BEQ LPTFLS ;FLUSH IT
|
||
LPTNFL: CLZ
|
||
RTS PC
|
||
LPTFLS: SEZ
|
||
RTS PC
|
||
;DELETE TTY CAP, WAIT FOR END OF TRANSMISSION IF LAST CAPABILITY,
|
||
;THEN FLUSH ITEM AND CAPABILITY
|
||
DELTT: MOV A,F ;COPY THE TTY CAPABILITY POINTER
|
||
MOV 2(A),A ;GET THE TTY ITEM NO.
|
||
JSR PC,ITM2LD ;LOAD IT UP
|
||
DELTT1: CMP TTYREF(A),#1 ;AM I THE LAST
|
||
BGT DELTT6 ;NO
|
||
SPL 7 ;STOP TTY, AND CLOCK
|
||
BIT #TOTRAN,TTYST1(A) ;IS HE TRANSMITTING
|
||
BNE DELTT2 ;NO
|
||
TST TOQN(A) ;MORE TO PRINT
|
||
BEQ DELTT4 ;NO, DONT BOTHER
|
||
DELTT2: SPL 0 ;RESTORE LOW PRIORITY
|
||
JSR PC,LFLUSH ;LONG, LONG FLUSH
|
||
CMP TTYREF(A),#1 ;CHECK IF SOMEONE ELSE COPIED THIS ONE
|
||
BGT DELTT3 ;YES, DONE?
|
||
SPL 7
|
||
BIT #TOTRAN,TTYST1(A) ;TRANSMITTING
|
||
BNE DELTT2 ;YES
|
||
TST TOQN(A) ;CHARS TO BE OUTPUT
|
||
BNE DELTT2 ;NO
|
||
DELTT3: SPL 0
|
||
JSR PC,RUNME ;TRY ME AGAIN
|
||
BR DELTT1 ;JUST TO MAKE SURE
|
||
DELTT4: MOV TTLTTY(A),E ;THE LOGICAL TTY NO.
|
||
.IFNZ NTVS
|
||
BIT #TVF,TTYTBL(E) ;IS THIS A TV
|
||
BEQ DELTT7 ;NO
|
||
TST TVBUF(A) ;THE BUFFER NUMBER OF THIS TV
|
||
BLT DELTT7 ;NO BUFFER ASSIGNED TO THIS TV
|
||
MOV E,B ;THE LOGICAL TTY NUMBER
|
||
SUB #NFTV,B ;GET THE PHYSICAL NUMBER OF THIS TV
|
||
ASR B ;THIS IS A BYTE OFFSET
|
||
JSR PC,DELTV ;DECREMENT THE REFERENCE COUNT FOR THIS TV
|
||
CLR TVSTAT(E) ;TURN OFF BLINK AND INTERRUPT BITS
|
||
DELTT7:
|
||
.ENDC
|
||
CLR TTYITM(E) ;CLEAR THE ITEM NO.
|
||
SPL 0 ;CANT BE BOTHERER ANY MORE
|
||
MOV ITEM2,A ;DELETE THE TTY ITEM
|
||
JSR PC,DLITEM ;DELETE IT
|
||
DELTT5: CLR (F) ;FLUSH THE CAPABILITY
|
||
CLZ
|
||
RTS PC
|
||
DELTT6: DEC TTYREF(A) ;SAY ONE LESS CAPABILITY
|
||
BR DELTT5 ;FLUSH IT
|
||
|
||
|
||
DELFA: MOV A,D ;COPY POINTER TO CAP
|
||
MOV FAUPT(D),B ;GET THE GIP REFERED TO BY THE FILE
|
||
BEQ DELFA1 ;THERE IS NONE
|
||
JSR PC,UPTDL ;FLUSH IT
|
||
CLR FAUPT(D) ;AND OUR POINTER TO IT
|
||
DELFA1: MOV FAMFI(D),A ;GET POINTER TO THE MFI
|
||
JSR PC,MFIDEL ;ONE LESS REFERENCE TO THE MFI
|
||
CLR (D) ;FLUSH ACTUAL CAPABILITY
|
||
CLZ
|
||
RTS PC
|
||
|
||
;DELETE DISPLAY CAP
|
||
DELDS: .IFZ NTKDIS+NTVS
|
||
BPT ;CAN'T EXIST!
|
||
.IFF
|
||
MOV CLSEM0(A),B ;GET THE TABLE INDEX
|
||
.ENDC
|
||
.IFNZ NTVS
|
||
BLT DELDS9
|
||
CMP B,#NFTVDS*2 ;IS IT A TV DISPLAY?
|
||
BGE DELDS1 ;YES
|
||
.ENDC
|
||
.IFZ NTKDIS
|
||
BPT ;THERE SHOULDN'T BE ANY TK DISPLAYS
|
||
.IFF
|
||
MOV TKDRUN(B),C
|
||
MOV #-1,TKDRUN(B) ;RETURN THE DISPLAY
|
||
JSR PC,TKDSTP ;STOP THE DISPLAY
|
||
BIC #177770,C
|
||
CLRB TKDOWN(C)
|
||
CLR (A) ;FLUSH THE ACTUAL CAPABILITY
|
||
CLZ
|
||
RTS PC
|
||
.ENDC
|
||
.IFNZ NTVS
|
||
DELDS9: BIC #100000,B
|
||
MOVB #377,TVBUFF(B)
|
||
CLZ
|
||
RTS PC
|
||
|
||
DELDS1: ASR B ;CONVERT TO BYTE INDEX
|
||
SUB #NFTVDS,B ;CONVERT TO PHYSICAL TV NUMBER
|
||
JSR PC,DELTV ;IF REFCOUNT IS ZERO, THEN RELEASE THE BUFFER
|
||
BEQ DELDS2 ;IN CASE TVDEL LOSES FOR SOME REASON
|
||
CLR (A)
|
||
CLZ ;SUCCEED
|
||
RTS PC
|
||
DELDS2: SEZ ;FAIL
|
||
RTS PC
|
||
|
||
;DELTV DECREMENTS THE REFERENCE COUNT OF A TV AND RELEASES THE BUFFER
|
||
;OF THAT TV WHEN THE REF COUNT REACHES ZERO. IT EXPECTS THE PHYSICAL
|
||
;TV NUMBER IN B
|
||
DELTV: SAVE A
|
||
TST B
|
||
BLT DELTV2 ;THERE ARE NO NEGATIVE TV'S
|
||
CMP B,#NTVS ;IS THIS ONE A LEGAL TV
|
||
BGE DELTV2 ;NO
|
||
DECB TVDSRF(B) ;DECREMENT THE REFERENCE COUNT
|
||
BGT DELTV1 ;IF NOT ZERO, THEN WE'RE DONE
|
||
MOVB TVDSBF(B),A ;GET THE BUFFER NUMBER OF THE TV
|
||
BLT DELTV2 ;THIS SHOULD NOT BE NEGATIVE
|
||
CMP A,#NTVCHN ;IS THIS WITHIN THE TABLE?
|
||
BGE DELTV2 ;NO, FAIL
|
||
SAVE B
|
||
ASL B ;CONVERT TO WORD INDEX
|
||
MOV TVMAP(B),B ;GET THE RIGHT CONSOLE
|
||
BIS #17*400,B ;THE SOURCE IS THE BLANK CHANNEL
|
||
MOV B,VIDSW ;CONNECT THIS CONSOLE TO THE BLANK CHANNEL
|
||
REST B
|
||
MOVB #-1,TVDSBF(B) ;SAY THAT THIS TV HAS NO BUFFER
|
||
MOVB #-1,TVBUFF(A) ;SAY THAT THIS BUFFER HAS NO TV
|
||
DELTV1: REST A
|
||
CLZ
|
||
RTS PC
|
||
DELTV2: REST A
|
||
SEZ
|
||
RTS PC
|
||
.ENDC
|
||
|
||
DELMS: SAVE A ;SAVE POINTER TO CAP FOR END OF ROUTINE
|
||
CLR -(P)
|
||
MOV A,F ;FOR SPCPDL
|
||
JSR PC,SPCPDL
|
||
MOV 2(F),A ;THE ITEM OF THIS SPHERE
|
||
JSR PC,ITM1PL ;PUSH ONCE ONLY!
|
||
MOV ITEM1,A
|
||
DELMS2: JSR PC,ITM1LD ;LOAD IT UP
|
||
SUB D,SPHREF(A) ;FLUSH THE REFERENCES WE FLUSHED
|
||
CMP #1,SPHREF(A) ;WE SHOULD BE THE ONLY ONE LEFT
|
||
BUGC NE ;BUG IF NOT ZERO
|
||
MOV #-1,E ;FLAG TO STOP ALL PROCESSES
|
||
JSR PC,STPMS ;STOP!!!
|
||
DELMS9: CLR D ;POINTER INTO C-LIST
|
||
JSR PC,GNMSCP ;GET THE NEXT MSCAP
|
||
BEQ DELMS1 ;NONE, CAN FLUSH SPHERE AT THIS LEVEL NOW
|
||
INC (P) ;ONE MORE SPHERE DOWN
|
||
MOV 2(B),A ;POINTER TO THE ITEM
|
||
MOV B,F ;FOR THE CALL TO SPCPDL
|
||
MOV D,E ;THE CAP NUMBER
|
||
JSR PC,SPCPDL ;DELETE THE CIRC LIST
|
||
BR DELMS2 ;GO LOAD IT UP AND LOOK FOR MSCAPS IN IT
|
||
DELMS1: MOV #-1,A ;NEED TO PUSH THE ITEM TO USE IT
|
||
JSR PC,ITM0PL
|
||
DELMS3: MOV ITM1A,A ;ADDRESS OF SPHERE
|
||
MOV SPHPRP(A),A ;GET POINTER TO FIRST PROCESS
|
||
BEQ DELMS4 ;NONE LEFT
|
||
JSR PC,ITM0LD ;LOAD IT UP
|
||
JSR PC,REMPRS ;REMOVE IT FROM THE SPHERE
|
||
BR DELMS3 ;GET THEM ALL!
|
||
DELMS4: JSR PC,ITM0PO
|
||
CLR D ;C-LIST ENTRY COUNTER
|
||
MOV ITM1A,A
|
||
DELMS5: JSR PC,GNCLST ;GET THE NEXT REAL ONE
|
||
BEQ DELMS6 ;NO MORE
|
||
SAVE <A,B,D,ITEM1>
|
||
ADD #CLSELN,B ;POINT PAST IT
|
||
SAVE <-(B),-(B),-(B),-(B),-(B)> ;SAVE THE CAPABILITY
|
||
MOV P,A ;POINT TO IT
|
||
JSR PC,ITM1PO ;POP IT IN CASE WE GET STOPPED
|
||
MOV (A),B ;FIRST WORD OF CAP
|
||
ASL B ;TURN IT INTO A WORD INDEX
|
||
BIC #177001,B ;CLEAR THE EXTRA BITS
|
||
JSR PC,@DELTAB(B) ;DELETE THE CAPABILITY
|
||
BUGC EQ ;SUCCEEDED
|
||
ADD #CLSELN,P ;POP OFF STUFF
|
||
REST A ;THE ITEM NO.
|
||
JSR PC,ITM1PL ;LOAD IT BACK UP
|
||
REST <D,B,A>
|
||
CLR (B) ;MAKE IT NXM
|
||
INC D
|
||
BR DELMS5
|
||
;CONTINUES NEXT PAGE
|
||
DELMS6: MOV ITEM1,C ;THE ITEM THE GIP WILL BE IN
|
||
JSR F,ACSAV
|
||
CLR B ;THE PAGE WE WANT
|
||
JSR PC,ITM1PO
|
||
DELMS7: SAVE <C,B>
|
||
JSR PC,SUPTDL ;FLUSH THAT ONE
|
||
REST <B,C>
|
||
INC B ;NEXT ONE
|
||
CMP #20,B ;GOT TO THE LAST ONE YET?
|
||
BNE DELMS7 ;NOPE
|
||
JSR F,ACRES
|
||
MOV C,A ;THE SPHERE WE HAVE NOW FLUSHED
|
||
JSR PC,ITM1PL ;LOAD IT UP FOR A SEC
|
||
MOV SMSSPT(A),F ;GET THE SUPERIOR SPHERE INDEX
|
||
MOV SPRTPT(A),A ;POINTER TO THE PROCESS BLOCK FOR THE SPHER
|
||
MOV #PFREEQ,B ;MOVE IT TO THE FREE QUQUE
|
||
JSR PC,PRSAOD ;MARK THE PAGES
|
||
JSR PC,TQUEUE
|
||
MOV ITM1A,A
|
||
MOV SUSRPT(A),A ;THE USER
|
||
MOV PRTPPT(A),A ;GET THE ITEM
|
||
JSR PC,ITM1PO
|
||
JSR PC,USRDEL ;DELETE A REFERENCE TO HIM
|
||
MOV C,A ;THE ITEM NUM
|
||
JSR PC,DLITEM ;GONE!!!
|
||
MOV F,A ;NOW LOAD THE SUPERIOR
|
||
JSR PC,ITM1PL
|
||
DEC (P) ;AT TOP LEVEL?
|
||
BLT DELMS8 ;YES, GO FINISH UP
|
||
CLR D ;GET THE FIRST MSCAP IN THE SUPERIOR
|
||
JSR PC,GNMSCP
|
||
CLR (B) ;FLUSH CAP TO SPHERE WE JUST FLUSHED
|
||
BR DELMS9 ;GO FIND ANY OTHER MSCAPS
|
||
DELMS8: JSR PC,ITM1PO ;GET TO THE REAL SPHERE
|
||
REST <B,B> ;FLUSH COUNT, GET POINTER TO CAP
|
||
CLR (B) ;FLUSHED!
|
||
CLZ
|
||
RTS PC
|
||
;THIS ROUTINE TAKES POINTER TO CAPABILITY IN F, THE MSCAP NO. IN E
|
||
;IT DELETES THE CIRCULAR LIST ASSOCIATED WITH IT.
|
||
SPCPDL: SAVE A
|
||
CLR D
|
||
MOV ITEM1,A ;MAKE A BOGUS PUSH
|
||
JSR PC,ITM2PL
|
||
TST 4(F) ;IS THERE A CIRCULAR LIST
|
||
BEQ SPCPDN ;NO
|
||
MOV F,A ;RESTORE POINTER TO CAPABILITY
|
||
BR SPCPD3 ;A ALREADY POINT TO THE CAPABILITY AND DON'T WANT MSCAP TO GO AWAY
|
||
SPCPD4: CMP ITEM2,ITEM1 ;IS THIS THE SAME SPHERE AS WE STARTED WITH
|
||
BEQ SPCPD2 ;YES, DON'T BOTHER TO TEST THE C-LIST LOCK (WE ALREADY LOCKED IT)
|
||
TST SCLSLK(A) ;IS THE C-LIST LOCKED?
|
||
BLE SPCPD2 ;NO, JUST DELETE IT
|
||
MOV SCLSLK(A),A ;THE PROCESS THAT LOCKED IT
|
||
JSR PC,PRSPCL ;STOP HIM, (I WANT THAT C-LIST BAD)
|
||
MOV ITM2A,A ;GET THE ADDRESS BACK
|
||
TST SCLSLK(A) ;IT HAD BETTER BE 0
|
||
BUGC NE ;IT IS
|
||
SPCPD2: ADD B,A ;MAKE A POINT TO THE SPHERE CAPABILITY
|
||
CLR (A) ;MAKE THIS CAPABILITY GO AWAY
|
||
INC D ;KEEP COUNT OF FLUSHED CAPS
|
||
SPCPD3: MOV 10(A),B ;THE C-LIST NO. OF NEXT CAP.
|
||
MOV 4(A),A ;GET THE SPHERE POINTER TO THE NEXT CAPABILITY
|
||
BUGC EQ ;GOT IT
|
||
CMP A,ITEM1 ;IS THIS THE SAME SPHERE
|
||
BNE SPCPD1 ;NO
|
||
CMP B,E ;SAME AS THE MSCAP?
|
||
BEQ SPCPDN ;YES, WE ARE DONE
|
||
SPCPD1: CMP A,ITEM1 ;IS THIS THE CURRENT SPHERE
|
||
BEQ SPCPD5 ;YES, DON'T STOP IT
|
||
MOV A,C ;SAVE FOR SPRSTP
|
||
.IFNZ NPC
|
||
JSR PC,SPRRPC ;PCLOSER THE SPHERE
|
||
.IFF
|
||
JSR PC,SPRSTP ;STOP THE SPHERE
|
||
JSR PC,SPRSTR ;START IT
|
||
.ENDC
|
||
MOV C,A ;RESTORE THE SPHERE NO.
|
||
SPCPD5: JSR PC,ITM2LD ;LOAD THE NEXT SPHERE
|
||
MOV ITM2A,A ;GET THE ADDRESS
|
||
JSR PC,GCLSTA ;GET POINTER TO NEXT CAP
|
||
BNE SPCPD4 ;GO BACK AND TRY AGAIN
|
||
BPT ;ERF, SOMETHING IS SCREWED
|
||
SPCPDN: JSR PC,ITM2PO ;POP THE ITEM PUSHED
|
||
CLR 4(F) ;MAKE SURE THERE IS NO CIRCULAR LIST
|
||
CLR 10(F) ;DITTO
|
||
REST A
|
||
RTS PC
|
||
.STITL TAKE CAPABILITY ROUTINES
|
||
TAKSP: SAVE <A,B,C,D>
|
||
MOV C,A ;THE SPHERE OF THE TAKEE
|
||
SAVE ITEM1 ;CURRENT SPHERE NO.
|
||
JSR PC,ITM1PL ;LOAD IT UP
|
||
ADD D,A ;MAKE A POINT TO THE CAP
|
||
MOV E,B ;B IS THE C-LIST NO.
|
||
JSR PC,FNBKPT ;GET BACK POINTER
|
||
MOV C,A ;THE PREVIOUS SPHERE
|
||
MOV D,B ;THE PREVIOUS C-LIST NO.
|
||
JSR PC,ITM1LD ;LOAD IT UP
|
||
JSR PC,GCLSTA ;GET THE CAPABILITY
|
||
ADD A,B ;MAKE A POINT TO THE CAP.
|
||
TST (B) ;IS IT THERE
|
||
BUGC EQ ;YEP
|
||
REST 4(B) ;THE CURRENT SPHERE IS WHERE THIS SHOULD POINT
|
||
MOV 4(P),10(B) ;SET THE C-LIST NO. ALSO
|
||
JSR PC,ITM1PO ;POP THE ITEM STACK
|
||
REST <D,C,B,A>
|
||
TAKFA:
|
||
TAKTP:
|
||
TAKTR:
|
||
TAKLP:
|
||
TAKTT:
|
||
TAKPR:
|
||
TAKCL:
|
||
TAKQU:
|
||
TAKCM:
|
||
TAKDS:
|
||
TAKCC: JSR PC,GIVPSW ;GIVE THE USER THE C-LIST NO. OF DEST
|
||
SAVE A ;SAVE POINTER TO WHERE THE CAP. IS GOING
|
||
MOV C,A ;THE SPHERE TO TAKE FROM
|
||
JSR PC,ITM2PL ;LOAD IT UP
|
||
ADD D,A ;MAKE THE POINTER ABSOLUTE
|
||
REST B ;POINTER TO DESTINATION
|
||
SAVE A
|
||
MOV (A)+,(B)+
|
||
MOV (A)+,(B)+
|
||
MOV (A)+,(B)+
|
||
MOV (A)+,(B)+
|
||
MOV (A)+,(B)+
|
||
CLR @(P)+ ;FLUSH THE CAPABILITY
|
||
JSR PC,ITM2PO
|
||
ADD #4,P ;POP THE TWO ARGS
|
||
JMP ERETCZ
|
||
;THIS ROUTINE MAKES SURE THAT THE SPHERE STRUCTURE ALWAYS POINTS DOWN
|
||
TAKMS: SAVE <A,B,C>
|
||
SAVE ITEM1 ;THE SPHERE OF TAKER
|
||
MOV C,A ;THE SPHERE OF TAKEE
|
||
JSR PC, ITM1PL ;LOAD IT UP
|
||
ADD D,A ;MAKE A POINT TO THE CAPABILITY TO BE TAKEN
|
||
MOV 2(A),C ;THE SPHERE THAT THE MASTER SPHERE CAP. REFFERS TO
|
||
REST A ;GET THE TAKER'S SPHERE NO.
|
||
CMP C,A ;IS TAKING HIS OWN MASTER SPHERE CAPATILITY
|
||
BEQ TAKMS1 ;YES, DONT LET HIM
|
||
CMP C,SYSSPR ;IS HE TAKING THE SYSTEM SPHERE'S MASTER CAP. TO ITSELF
|
||
BEQ TAKMS1 ;YES DONT ALLOW HIM TO
|
||
TAKMS2: JSR PC,ITM1LD ;LOAD UP THE SPHERE
|
||
MOV SMSSPT(A),A ;GET THIS SPHERES MASTER SPHERES NO
|
||
CMP A,SYSSPR ;ARE WE AT THE ROOT OF THE SPHERE TREE
|
||
BEQ TAKMS3 ;YES
|
||
CMP C,A ;IS IT A SUPERIOR OF THE TAKER
|
||
BNE TAKMS2 ;NOPE, GET THE NEXT SUPERIOR
|
||
TAKMS1: JSR PC,ITM1PO
|
||
ERROR BAD ;CANT TAKE A SUPERIOR MS
|
||
TAKMS3: JSR PC,ITM1PO ;POP THE SPHERE
|
||
JSR PC,SPRSTP ;STOP THE SPHERE THAT THE MS CAP. REFERS TO
|
||
MOV C,B ;THE SPHERE THAT WE STOPPED
|
||
MOV #LSPRTN,A ;RUN A ROUTINE WHEN UNLOCKED
|
||
JSR PC,LOCKSW ;GET A LOCK
|
||
MOV #PCSPST,LCKWD1(A) ;START THE SPHERE WHEN IT IS NULOCKED
|
||
MOV ITEM0,B ;SAY WE LOCKED THE C-LIST
|
||
MOV #SCLSLK,A ;LOCK ITS C-LIST
|
||
JSR PC,LCKASW ;LOCK IT IF YOU CAN
|
||
MOV C,A ;THE SPHERE NO.
|
||
JSR PC,ITM2PL ;LOAD IT
|
||
MOV ITEM1,SMSSPT(A) ;UPDATE THE SUPERIOR SPHERE POINTER
|
||
MOV (P),A ;THE SPHERE THAT THE CAPABILITY IS IN
|
||
JSR PC,ITM2LD ;LOAD IT UP
|
||
ADD D,A ;POINT TO THE CAPABILITY
|
||
BIS #.SPFES,(D) ;SUPRESS ENTERS FOR NOW
|
||
JSR PC,ITM2PO ;POP THE SPHERE
|
||
REST <C,B,A>
|
||
JMP TAKSP ;UPDATE THE CIRCULAR PINTERS AND TAKE THE CAPABILITY
|
||
;INCREMENT SPHERE OR PROCESS REFERENCE COUNT, ITEM NO. IN C
|
||
;THIS DEPENDS ON THE SPHERE AND PROCESS REFERENCE COUNT BEING IN THE SAME PLACE
|
||
.IIF NZ SPHREF-PRSREF,.ERROR BARF IT WONT WORK
|
||
SPRINC: SAVE A ;DON'T CLOBBER A
|
||
MOV B,A ;GET THE ITEM NO.
|
||
JSR PC,ITM1PL ;LOAD THE SPERE
|
||
INC SPHREF(A) ;INC REFERENCE COUNT
|
||
JSR PC,ITM1PO ;RELOAD ORIGINAL ITEM1
|
||
REST A ;RESTORE IT
|
||
RTS PC
|
||
;DECREMENT REFERENCE COUNT OF CORE LINK OR PROCESS
|
||
;ITEM NUMBER IN A
|
||
SPRDEC: JSR PC,ITM1PL ;LOAD THE SPHERE
|
||
DEC SPHREF(A) ;DECREMENT THE REFERENCE COUNT
|
||
BEQ SPRDC1 ;NO ONE REFERS TO IT ANY MORE
|
||
JSR PC,ITM1PO ;POP THE ITEM STACK
|
||
RTS PC
|
||
SPRDC1: MOV ITEM1,A ;SAVE THE ITEM NO.
|
||
JSR PC,ITM1PO ;IN CASE WE GET STOPPED
|
||
BIT #GIPBIT,A ;IS IT A GIP
|
||
BNE SPRDC2 ;YES, MUST BE A FUPT
|
||
JSR PC,DLITEM ;DELETE THE ITEM
|
||
RTS PC
|
||
SPRDC2: SAVE B
|
||
MOV A,B ;COPY THE FUPT
|
||
JSR PC,UPTDL ;DELETE IT
|
||
REST B ;GET B BACK
|
||
RTS PC ;RETURN
|
||
.STITL I-O ROUTINES
|
||
EWRDI: MOV #WDITAB,F
|
||
BR IOTYPE
|
||
EWRDO: MOV #WDOTAB,F
|
||
BR IOTYPE
|
||
EBYTI: MOV #BTITAB,F
|
||
BR IOTYPE
|
||
EBYTO: MOV #BTOTAB,F
|
||
BR IOTYPE
|
||
EBLKI: MOV #BKITAB,F
|
||
BR IOTYPE
|
||
EBLKO: MOV #BKOTAB,F
|
||
|
||
IOTYPE: JSR PC,RETNSW ;GET THE CAP NO. OF THE IO DEVICE
|
||
MOV A,B ;CAP NO.IF IT IS NEGATIVE, WAIT FOR COMPLETION
|
||
MOV A,E ;CONTAINS FLAGS IN HIGH BYTE
|
||
BIC #177600,B ;CLEAR THE FLAG BITS
|
||
MOV ITM1A,A ;START OF SPHERE
|
||
JSR PC,GCLSTA ;GET THE CAPABILITY
|
||
BEQ IOTYP1 ;FAILED
|
||
ADD B,A ;MAKE A POINT TO THE CAP.
|
||
MOV A,D ;SAVE POINTER FOR IO ROUTINES
|
||
MOV (A),B ;GET FLAGS FOR CALLED ROUTINES
|
||
MOVB (A),C ;GET THE TYPE
|
||
ASL C ;INDEX
|
||
JMP @DOITAB(C) ;DISPATCH ON TYPE
|
||
DOIOCC: DOIOCM: DOIOSP: DOIOMS: DOIOPR: DOIOQU: DOIODS: DOIOXX:
|
||
IOTYP1: ERROR BCT ;NOT RECOGNIZE I-O CAPABILITY TYPE
|
||
;THESE ARE FOR MEANINGLESS OPERATIONS (OUTPUT TO THE TAPE READER)
|
||
LPBKI: LPWDI: LPBTI:
|
||
TRBKO: TRWDO: TRBTO:
|
||
TPBKI: TPWDI: TPBTI: ERROR BFUN ;BAD FUNCTION, FOR THIS DEVICE
|
||
;BRANCHES INTO NEXT PAGE
|
||
;BRANCHED INTO FROM PREVIOUS PAGE
|
||
DOIOTR: JMP @TRIDX*2(F) ;NOTHING TO DO
|
||
DOIOTP: JMP @TPIDX*2(F) ;DITTO
|
||
DOIOLP: JMP @LPIDX*2(F) ;DITTO
|
||
DOIOFA: JMP @DKIDX*2(F) ;THE DISK ROUTINES ARE FIRST IN TABLE
|
||
DOIOTT: MOV 2(D),A ;THE TTY ITEM NO.
|
||
JSR PC,ITM2LD
|
||
CMP ITEM1,TTITM(A) ;DO I CURRENTLY OWN IT
|
||
BNE DOIOT1 ;NOPE
|
||
JMP @TTIDX*2(F) ;THE TTY ROUTINES ARE SECOND IN TABLE
|
||
DOIOT1: JSR PC,LFLUSH ;FLUSH YOURSELF
|
||
CMP ITEM1,TTITM(A) ;DO I OWN IT NOW
|
||
BNE DOIOT1 ;NO, GO FLUSH YOURSEF AGAIN
|
||
JSR PC,RUNME ;I THINK I HAVE GOT THE TTY
|
||
BR DOIOTT ;GO TRY AGAIN
|
||
DOIOCL: MOV 2(D),A ;THE CORE LINK POINTER
|
||
BIT #GIPBIT,A ;IS IT A GIP (MEANS IT IS AN FUPT)
|
||
BEQ CLIO1 ;NO, JUST GO AHEAD
|
||
SAVE <B,F>
|
||
MOV A,B ;POINTER TO FUPT
|
||
JSR PC,FUPTLK
|
||
JSR PC,SWPIN ;SWAP IT IN
|
||
REST <F,B> ;NOW WE WILL GET PC-LOSERED IF IT GOES OUT AGAIN
|
||
CLIO1: JMP @CLIDX*2(F) ;THE CORE LINK ROUTINES ARE THIRD IN THE TABLES
|
||
.STITL CORE LINK ROUTINES
|
||
CLGTBY: TST CLCNT(A) ;ARE THERE ANY BYTES
|
||
BEQ CLGTB1 ;NO, RETURN SEZ
|
||
MOV CLDATO(A),D ;POINTER TO THE DATA OUT
|
||
ADD A,D ;MAKE THE POINTER ABSOLUTE
|
||
MOVB (D),D ;GET THE BYTE
|
||
DEC CLCNT(A) ;DECREMENT THE BYTE COUNT
|
||
INC CLDATO(A) ;INCREMENT THE POINTER
|
||
SAVE B ;GET A REGISTER
|
||
MOV CLNUM(A),B ;THE NUMBER OF ENTRIES IN BUFFER
|
||
ADD #CLDATL,B ;GET THE TOTAL MAXIMUM OFFSET
|
||
CMP CLDATO(A),B ;ARE WE AT THE END OF THE BUFFER
|
||
BLT 1$
|
||
MOV #CLDATL,CLDATO(A) ;RESET THE DATA OUT POINTER
|
||
1$: REST B
|
||
CLGTB1: RTS PC
|
||
|
||
CLCHAR: MOV CLCNT(A),B ;GET THE NUMBER OF CHARACTERS LEFT
|
||
RTS PC
|
||
|
||
CLDPBY: CMP CLCNT(A),CLNUM(A) ;ANY SPACE LEFT
|
||
BEQ CLGTB1 ;NO
|
||
SAVE B
|
||
MOV CLDATI(A),B ;THE DATA IN POINTER
|
||
ADD A,B ;MAKE THE POINTER ABSOLUE
|
||
MOVB D,(B) ;PUT IN THE BYTE
|
||
INC CLCNT(A) ;SAY ANOTHER CHARACTER
|
||
INC CLDATI(A) ;INCREMENT POINTER TO NEXT
|
||
MOV CLNUM(A),B ;GET THE NUMVER OF SLOTS
|
||
ADD #CLDATL,B ;GET THE TOTAL OFFSET
|
||
CMP CLDATI(A),B ;ARE WE AT THE END
|
||
BLT 1$
|
||
MOV #CLDATL,CLDATI(A) ;RESET THE POINTER
|
||
1$: REST B
|
||
RTS PC
|
||
CLO: JSR PC,CLDPBY ;DEPOSITE THE BYTE
|
||
BEQ CLO1 ;FAILED
|
||
RTS PC
|
||
CLO1: JSR PC,LFLUSH ;FLUSH YOURSELF
|
||
CMP CLCNT(A),CLNUM(A) ;IS IT STILL FULL
|
||
BEQ CLO1 ;YES
|
||
JSR PC,RUNME
|
||
BR CLO
|
||
|
||
STIOQ: JSR PC,TIOQ ;GET A CHARACTER
|
||
BIT #TILIPM,TTYST1(A) ;AM I IN LOGO INPUT MODE
|
||
BEQ STIOQ1 ;NO
|
||
CLR E ;CLEAR THE WAIT FLAG
|
||
STIOQ1: RTS PC
|
||
|
||
;SET UP LINE MODE
|
||
TTLINE: MOV 2(D),A ;LOAD THE TTY
|
||
JSR PC,ITM2LD ;LOAD IT UP
|
||
SAVE B
|
||
MOV #TIHPIT,B
|
||
ADD A,B
|
||
JSR PC,ACTSET ;SET UP TO BE ACTIVATED
|
||
REST B
|
||
BIT #TILIPM,TTYST1(A) ;IN LINE MODE?
|
||
BEQ TTLIN1 ;NO
|
||
TST TIEQTN(A) ;ANY CHARACTERS?
|
||
BNE TTLIN1 ;YES, JUST FORGET IT
|
||
BIS #TTHANG,TTYST2(A) ;SET THE HANG BIT
|
||
TTLIN1: RTS PC
|
||
|
||
LPOBYT: TST @LPTCSR(A) ;IS THERE AN ERROR?
|
||
BPL 1$ ;NO
|
||
BIC #100000,@LPTCSR(A) ;CLEAR THE ERROR IF POSSIBLE
|
||
ERROR BPN,SV ;PRINTER ERROR ERO
|
||
1$: MOV LPTEND(A),E ;POINTER TO THE END OF THE BUFFER
|
||
SUB #LPTBUF+1,E ;NUMBER OF SPOTS IN BUFFER-1 SO THAT PRINTER KLUDGE WILL WORK
|
||
CMP LPTNUM(A),E ;BUFFER FULL?
|
||
BHIS LPOBY1 ;YES
|
||
MOV LPTDAI(A),E ;GET THE BUFFER POINTER
|
||
ADD A,E ;POINT TO THE BUFFER
|
||
MOVB D,(E)+ ;PUT IT IN
|
||
SUB A,E ;MAKE IT RELATIVE AGAIN
|
||
CMP E,LPTEND(A) ;AT THE END YET
|
||
BLO LPOBY2 ;NO
|
||
MOV #LPTBUF,E ;RESET THE POINTER
|
||
LPOBY2: MOV E,LPTDAI(A) ;POINT TO THE NEXT DATA SLOT
|
||
INC LPTNUM(A) ;SAY ONE MORE BYTE THERE
|
||
RTS PC
|
||
LPOBY1: JSR PC,SFLUSH ;WAIT A WHILE
|
||
TST @LPTCSR(A) ;ERROR?
|
||
BMI LPOBY3 ;UNFLUSH YOURSELF IF THERE IS
|
||
CMP LPTNUM(A),E ;STILL FULL
|
||
BHIS LPOBY1 ;NOT EMPTY YET
|
||
LPOBY3: JSR PC,RUNME ;FINISHED
|
||
BR LPOBYT
|
||
|
||
LPO: JSR PC,LPOBYT ;OUTPUT THE BYTE
|
||
TST LPTMOD(A) ;IN PLOT MODE
|
||
BNE PLO ;YES
|
||
BIS #40000,@LPTCSR(A) ;SET INTERRUPT ENABLE
|
||
RTS PC
|
||
PLO: DEC LPTPCT(A) ;DECREMENT THE PLOTTER COUNT
|
||
BMI PLO1 ;GOT A BYTE
|
||
BNE PLO2 ;NOT DONE WITH THIS LINE
|
||
BIS #40000,@LPTCSR(A) ;SET INTERRUPT ENABLE
|
||
PLO2: RTS PC
|
||
PLO1: CMP LPTPCT(A),#-1 ;WAS THE COUNT 0?
|
||
BNE PLO3 ;NO
|
||
MOVB D,LPTPCT(A) ;SET IN THE BOTTOM BYTE
|
||
BR PLO2 ;DONE FOR NOW
|
||
PLO3: INC LPTPCT(A) ;GET BACK BYTE COUNT, BECAUSE WE DEC IT ONCE TO MANY
|
||
MOVB D,LPTPCT+1(A) ;SET IN THE TOP OF THE BYTE COUNT
|
||
MOV LPTPCT(A),D ;GET THE TOTAL COUNT
|
||
MUL LPTMOD(A),D ;GET THE TOTAL LENGTH OF LINE
|
||
BVS PLO4 ;OVERFLOW?
|
||
CMP D,#LINSIZ ;IS IT LONGER THAN THE LINE
|
||
BLOS PLO2 ;NO
|
||
PLO4: CLR LPTPCT(A) ;NO BYTES TO BE TRANSFERED ON THIS LINE
|
||
SUB #2,LPTDAI(A) ;RESET THE DATA IN POINTER
|
||
CMP LPTDAI(A),#LPTBUF ;IS IT BEFORE THE BUFFER
|
||
BHIS PLO5 ;NO, FORGET IT
|
||
ADD LPTEND(A),LPTDAI(A) ;UNWRAP IT
|
||
PLO5: SUB #2,LPTNUM(A) ;TWO FEWER BYTES
|
||
ERROR BFUN ;BAD FUNCTION
|
||
.STITL TTY AND CORE LINK INPUT ROUTINES
|
||
;THIS ROUTINE TAKES A CHARACTER FROM THE TTY POINTED TO BY THE CAPABILITY POINTED TO BY D
|
||
;AND PUTS IT ON THE TOP OF THE USERS STACK
|
||
TRBTI: SAVE <#TRGTBY,#TRCHAR>
|
||
BR TTBTI1 ;LOAD IT UP
|
||
CLBTI: SAVE <#CLGTBY,#CLCHAR> ;GET A BYTE
|
||
BIT #.CLCONS,B ;AM I THE CONSUMER
|
||
BEQ TTBTI4 ;NO, ERROR
|
||
BR TTBTI1
|
||
TTBTI: SAVE <#STIOQ,#CHARCK>
|
||
BIT #.TTYI,B ;DOES HE HAVE INPUT ACCESS
|
||
BEQ TTBTI4 ;NOPE
|
||
JSR PC,TTLINE ;SET UP LINE MODE
|
||
TTBTI1: MOV 2(D),A ;GET THE TTY ITEM NO
|
||
JSR PC,ITM2LD ;LOAD IT UP
|
||
JSR PC,@(P) ;GET THE NUMBER OF CHARACTERS INTO B
|
||
TST B ;EOF?
|
||
BMI TTBTI6
|
||
CMP B,#1 ;CAN WE GET ONE
|
||
BLT TTBTI3 ;NOPE
|
||
JSR PC,@2(P) ;GET IT
|
||
MOV D,B ;THE CHAR
|
||
JSR PC,GIVPSW ;GIVE IT TO THE USER
|
||
ADD #4,P
|
||
JMP ERETCZ
|
||
TTBTI3: MOV (P),C ;GET THE ADDRESS OF THE CHARACTER RETURNING ROUTINE
|
||
TTBTI5: TST E ;SHOULD WE WAIT
|
||
BMI TTBTI4 ;NOPE
|
||
JSR PC,LFLUSH ;GET RID OF YOURSELF FOR A LONG TIME
|
||
JSR PC,(C) ;IS THERE A CHARACTER
|
||
CMP B,#1 ;ANY CHARACTERS
|
||
BLT TTBTI5 ;NO
|
||
JSR PC,RUNME ;I CAN GET ONE NOW
|
||
BR TTBTI1 ;GO GET IN
|
||
TTBTI6: TTBTI4: ADD #4,P
|
||
JMP ERETSC
|
||
;THIS ROUTINE IS THE SAME AS THE TTBTI, EXCEPT IT RETURNS TWO CHARACTERS
|
||
;THE FIRST IN THE LOW ORDER BYTE, AND THE NEXT IN THE TOP ORDER BYTE
|
||
TRWDI: SAVE <#TRGTBY,#TRCHAR>
|
||
BR TTWDI1
|
||
CLWDI: SAVE <#CLGTBY,#CLCHAR> ;GET A BYTE
|
||
BIT #.CLCONS,B ;IS HE A CONSUMER
|
||
BEQ TTWDI3 ;NO
|
||
BR TTWDI1
|
||
TTWDI: SAVE <#STIOQ,#CHARCK>
|
||
BIT #.TTYI,B ;DOES HE HAVE INPUT ACCESS
|
||
BEQ TTWDI3 ;NOPE
|
||
JSR PC,TTLINE ;SET UP LINE MODE
|
||
TTWDI1: MOV 2(D),A ;THE TTY ITEM NO.
|
||
JSR PC,ITM2LD ;LOAD IT UP
|
||
TTWDI7: JSR PC,@(P) ;CHECK TO SEE IF THERE ARE ENOUGH
|
||
TST B ;EOF?
|
||
BMI TTBTI6 ;YES
|
||
CMP B,#2 ;2 BYTES LEFT
|
||
BLT TTWDI2 ;NOPE
|
||
JSR PC,@2(P) ;GET A BYTE
|
||
MOV D,B ;SAVE IT
|
||
BIC #177400,B ;CLEAR THE HIGH BYTE
|
||
JSR PC,@2(P) ;GET ANOTHER BYTE
|
||
SWAB D ;PUT IT INTO THE TOP BYTE
|
||
BIC #377,D ;CLEAR THE LOWER BYTE
|
||
BIS D,B ;PUT THEM BOTH IN THE SAME WORD
|
||
JSR PC,GIVPSW ;GIVE THE WORD TO THE USER
|
||
ADD #4,P
|
||
JMP ERETCZ ;RETURN SUCCESSFUL
|
||
TTWDI3: ERROR BAC
|
||
TTWDI4: JSR PC,@2(P)
|
||
MOV D,B ;THE CHARACTER
|
||
JSR PC,GIVPSW ;GIVE THE CHAR TO THE USERR
|
||
ADD #4,P
|
||
ERETSC: MOV ITM0A,A ;GET THE PROCESS ADDRESS
|
||
CLR PUPDLO(A) ;NOTHING GETS POPPED
|
||
SEZ!SEC
|
||
JMP EMTRET
|
||
TTWDI2:
|
||
TTWDI5: MOV (P),C ;THE ADDRESS OF THE ROUTINE THAT RETURNS NUMBER OF BYTES
|
||
TTWDI6: JSR PC,LFLUSH ;GET RID OF YOURSELF FOR A LONG TIME
|
||
JSR PC,(C) ;GET NUMBER OF CHARACTERS
|
||
CMP B,#2 ;ENOUGH CHARACTERS YET
|
||
BLT TTWDI6 ;NOPE
|
||
JSR PC,RUNME ;I THINK I HAVE GOT THEM
|
||
BR TTWDI7
|
||
;THIS ROUTINE TAKES A BLOCK OF CHARACTER FROM THE TTY, THE FIRST THING ON
|
||
;THE STACK IS THE NEGATIVE OF THE BYTE COUNT, THE SECOND IS A POINTER TO WHERE THE DATA
|
||
;GOES IN THE USERS D-SPACE
|
||
TRBKI: SAVE <#TRGTBY,#TRCHAR>
|
||
BR BKICOM
|
||
CLBKI: SAVE <#CLGTBY,#CLCHAR> ;GET A BYTE
|
||
BIT #.CLCONS,B ;AM I THE CONSUMER
|
||
BEQ TBKISZ ;NO LOSER
|
||
BR BKICOM
|
||
TTBKI: SAVE <#STIOQ,#CHARCK>
|
||
BIT #.TTYI,B ;DOES HE HAVE INPUT ACCESS
|
||
BEQ TBKISZ ;NO
|
||
JSR PC,TTLINE ;SET UP LINE MODE
|
||
BKICOM: JSR PC,RETNSW ;GET THE COUNT
|
||
MOV A,C ;SAVE IT
|
||
BPL TBKISZ ;ITS POSITIVE, WE WANT A NEGATIVE COUNT
|
||
JSR PC,RETNSW ;GET THE POINTER
|
||
TST C ;COUNT ZERO?
|
||
BEQ TBKICZ ;YES, MUST BE FINISHED
|
||
MOV A,F ;SAVE IT
|
||
ASR A ;SEE IF IT IS AT AN ODD ADRESS
|
||
BCC TBKI2 ;IT IS OK
|
||
MOV 2(D),A ;THE ITEM NO.
|
||
TBKI1: DEC F ;MAKE B POINT TO THE PREVIOUS WORD
|
||
MFPD (F) ;GET THE PREVIOUS WORD
|
||
SAVE (P)
|
||
MTPD (F) ;MAKE SURE WE CAN WRITE IT
|
||
JSR PC,ITM2LD
|
||
BR TBKI4
|
||
TBKI2: MOV 2(D),A ;THE TTY ITEM NO.
|
||
TBKI3: MFPD (F) ;MAKE SURE WE CAN WRITE THIS WORD
|
||
SAVE (P) ;SAVE IT
|
||
MTPD (F) ;MAKE VBERY SURE WE CAN WRITE IT
|
||
TBKI11: JSR PC,ITM2LD ;LOAD THE TTY
|
||
JSR PC,@2(P) ;CAN I GET A CHAR
|
||
CMP B,#1 ;IS THERE ONE
|
||
BLT TBKI5 ;FAILED
|
||
JSR PC,@4(P) ;GET THE CHARACTER
|
||
MOVB D,(P) ;SAVE THE FIRST CHAR
|
||
INC C ;INCREMENT THE COUNT
|
||
BEQ TBKIRT ;DONE IF ZERO
|
||
|
||
;BRANCHES INTO NEXT PAGE
|
||
;BRANCHES IN FROM ABOVE
|
||
|
||
TBKI4: JSR PC,@2(P) ;ARE THERE CHAR.
|
||
CMP B,#1
|
||
BLT TBKI9 ;NOPE
|
||
JSR PC,@4(P) ;GET THE CHARACTER
|
||
MOVB D,1(P) ;PUT IT IN THE TOP BYTE
|
||
MOV ITEM2,A
|
||
MTPD (F)+ ;RETURN THE CHARACTERS
|
||
INC C ;INC THE COUNT
|
||
BEQ TBKICZ ;IF ZERO WE ARE DONE
|
||
SAVE <A,B,C,F>
|
||
MOV ITM0A,A ;GET THE ADDRESS OF ITEM
|
||
MOV PUP(A),B ;THE PDL POINTER
|
||
ADD PUPDLO(A),B ;CORRECT IT
|
||
MTPD -(B) ;PUT BACK THE POINTER
|
||
MTPD -(B) ;PUT BACK THE COUNT
|
||
REST <B,A>
|
||
BR TBKI3 ;GO BACK FOR MORE
|
||
TBKI5:TBKI6: ADD #4,P
|
||
JMP ERETSC ;SET THE CARRY AND RETURN
|
||
TBKI7: SAVE C
|
||
MOV 4(P),C ;THE CHARACTER CHECKING ROUTINE
|
||
TBKI8: JSR PC,LFLUSH ;FLUSH YOURSELF
|
||
MOV ITM2A,A
|
||
JSR PC,(C) ;ANY CHARACTERS
|
||
CMP B,#1
|
||
BLT TBKI8 ;NOPE
|
||
MOV ITEM2,A ;SAVE IT FOR LATER
|
||
JSR PC,RUNME ;I THINK I HAVE GOT IT
|
||
REST C ;GET BACK RANDOM REG
|
||
BR TBKI11 ;GO GET THE CHAR
|
||
|
||
;BRANCHES INTO NEXT PAGE
|
||
;BRANCHES IN FROM ABOVE
|
||
|
||
TBKIRT: MTPD (F) ;GIVE IT BACK, WITH ONE BYTE CHANGED
|
||
TBKICZ: ADD #4,P ;POP OFF GARBAGE
|
||
JMP ERETCZ ;RETURN SUCCESSFUL
|
||
TBKISZ: ERROR BAC
|
||
TBKI9: MTPD (F) ;GIV IT BACK WITH BYTE MODIFIED
|
||
INC F ;CORRECT BYTE POINTER
|
||
MOV F,B ;GIVE HIM THE POINTER
|
||
JSR PC,GIVPSW
|
||
MOV C,B ;THE COUNT
|
||
JSR PC,GIVPSW ;GIVE IT TO HIM
|
||
TST B ;EOF ERROR?
|
||
BMI TBKI6 ;YES
|
||
SAVE C
|
||
MOV ITM0A,C ;POINT TO THE PROCESS
|
||
ADD #4,PUPDLO(C) ;CORRECT THE OFFSET
|
||
MOV 2(P),C ;THE CHARACTER CHECKING ROUTINE
|
||
BR TBKI12
|
||
TBKI10:TBKI12: JSR PC,LFLUSH ;FLUSH YOURSELF
|
||
MOV ITM2A,A
|
||
JSR PC,(C) ;ARE THERE CHARACTERS
|
||
CMP B,#1
|
||
BLT TBKI10 ;NOPE
|
||
MOV ITEM2,A ;SAVE FOR LATER
|
||
JSR PC,RUNME ;RUN ME, RUN ME
|
||
REST C
|
||
JMP TBKI1 ;FIX THE POINTER AND GET THE CHAR
|
||
.STITL CORE LINK AND TTY OUTPUT ROUTINES
|
||
;THIS ROUTINE TAKES A BYTE OFF THE TOP OF THE USERS STACK AND OUTPUTS IT TO THE TTY
|
||
LPBTO: SAVE <#LPO>
|
||
BR TTBTO2
|
||
TPBTO: SAVE <#TPO>
|
||
BR TTBTO2
|
||
CLBTO: SAVE <#CLO>
|
||
BR TTBTO2
|
||
TTBTO: SAVE <#TYO>
|
||
BIT #.TTYO,B ;DOES HE HAVE OUTPUT ACCESS
|
||
ERRORC EQ,BAC ;BAD ACCESS
|
||
TTBTO2: JSR PC,RETNSW ;GET THE CHARACTER TO TRANSMIT
|
||
MOV A,F ;SAVE IT
|
||
MOV 2(D),A ;THE TTY ITEM NO
|
||
JSR PC,ITM2LD ;LOAD IT UP
|
||
MOV F,D ;THE CHAR
|
||
JSR PC,@(P) ;SEND THE CHARACTER
|
||
TST (P)+ ;POP OFF THE ARGUMENT
|
||
JMP ERETCZ ;SUCESS
|
||
;THIS ROUTINE TAKES A WORD OFF THE USERS STACK AND OUTPUTS IT TO THE TTY
|
||
LPWDO: SAVE #LPO
|
||
BR TTWDO2
|
||
TPWDO: SAVE #TPO
|
||
BR TTWDO2
|
||
CLWDO: SAVE #CLO
|
||
BR TTWDO2
|
||
TTWDO: SAVE #TYO
|
||
BIT #.TTYO,B ;DOES HE HAVE OUTPUT ACCESS
|
||
BNE TTWDO2 ;NOPE
|
||
TTWDO1: ERROR BAC
|
||
TTWDO2: JSR PC,RETNSW ;GET THE CHARACTERS TO OUTPUT
|
||
MOV A,F ;SAVE THEM
|
||
TTWDO3: MOV 2(D),A ;THE TTY ITEM NO
|
||
TTWDO4: JSR PC,ITM2LD ;LOAD IT
|
||
BIT #.TTWD,E ;HAVE WE SENT THE FIRST BYTE YET?
|
||
BNE TTWDO5 ;YES
|
||
MOVB F,D ;COPY THE BYTE
|
||
JSR PC,@(P) ;SEND IT
|
||
BIS #.TTWD,E ;FIRST BYTE WRITTEN BIT
|
||
MOV F,B ;PUT BACK THE OUTPUT WORD
|
||
JSR PC,GIVPSW ;GIVE BACK TO USER
|
||
MOV E,B ;PUT FLAGS AND CAP NUMBER BACK THE WAY THEY WERE
|
||
JSR PC,GIVPSW ;GIVE BACK TO USER
|
||
JSR PC,RETNSW
|
||
JSR PC,RETNSW ;THIS IS THE WAY WE WERE CALLED
|
||
TTWDO5: SWAB F ;GET THE NEXT CHAR
|
||
MOVB F,D ;THE OTHER CHAR
|
||
MOV ITM2A,A
|
||
JSR PC,@(P) ;SEND IT ALSO
|
||
ADD #2,P ;POP THE ADDRESS
|
||
JMP ERETCZ ;SUCCESS
|
||
|
||
|
||
;CL AND TTY BLOCK OUTPUT
|
||
LPBKO: SAVE #LPO
|
||
BR TBKO1
|
||
TPBKO: SAVE #TPO
|
||
BR TBKO1
|
||
CLBKO: SAVE #CLO
|
||
BR TBKO1
|
||
TTBKO: SAVE #TYO
|
||
BIT #.TTYO,B ;DOES HE HAVE OUTPUT ACCESS
|
||
BNE TBKO1
|
||
TBKOSZ: ERROR BAC
|
||
TBKO1: MOV 2(D),A ;THE TTY ITEM
|
||
JSR PC,ITM2LD ;LOAD IT UP
|
||
JSR PC,RETNSW ;GET THE COUNT
|
||
MOV A,C ;SAVE IT
|
||
BPL TBKOSZ ;POSITIVE COUNT?
|
||
JSR PC,RETNSW ;GET THE POINTER
|
||
TST C ;IS THE COUNT 0?
|
||
BEQ TBKOCZ ;YES, MUST HAVE FINISHED
|
||
MOV A,F ;SAVE IT
|
||
MOV ITM2A,A ;GET THE ADDRESS OF THE TTY ITEM
|
||
BIT #1,F ;DOES POINTER POINT TO A BYTE?
|
||
BEQ TBKO2 ;NO, IT POINTS TO A WORD
|
||
DEC F ;MAKE IT POINT TO THE PREVIOUS WORD
|
||
MFPD (F) ;GET THE WORD
|
||
INC F ;GET BACK TO THE CORRECT POINTER
|
||
BR TBKO4 ;PRETEND YOU HAVE ALREADY SENT A CHARACTER
|
||
TBKO2:
|
||
TBKO3: MFPD (F) ;GET THE TWO CHARACTERS
|
||
MOVB (P),D ;THE FIRST CHARACTER
|
||
JSR PC,@2(P)
|
||
INC F
|
||
INC C ;INCREMENT THE COUNT
|
||
BEQ TBKORT ;DONE
|
||
JSR PC,TBKRSP ;RESET THE POINTERS IN USER SPACE
|
||
|
||
;BRANCHES INTO NEXT PAGE
|
||
;BRANCHES IN FROM ABOVE
|
||
|
||
TBKO4: MOVB 1(P),D ;THE SECOND CHAR
|
||
JSR PC,@2(P) ;PUT THE CHAR IN THE BUFFER
|
||
INC F ;THE POINTER
|
||
INC C ;INC THE COUNT
|
||
BEQ TBKORT ;DONE
|
||
JSR PC,TBKRSP ;RESET THE POINTERS IN USER SPACE
|
||
TST (P)+ ;POP OFF THE CHARACTERS
|
||
BR TBKO3 ;DO IT AGAIN
|
||
TBKORT: TST (P)+ ;POP OFF THE CHARACTERS
|
||
TBKOCZ: ADD #2,P ;POP OFF THE ROUTINE ADDRESSES
|
||
JMP ERETCZ
|
||
|
||
;THIS SUBROUTINE RESETS THE POINTERS SO THAT IS WE GET PC-LUSERED, WE'RE OK
|
||
TBKRSP: SAVE <A,B,C,F>
|
||
MOV ITM0A,A ;GET THE ADDRESS OF ITEM
|
||
MOV PUP(A),B ;THE PDL POINTER
|
||
ADD PUPDLO(A),B ;CORRECT IT
|
||
MTPD -(B) ;PUT BACK THE POINTER
|
||
MTPD -(B) ;PUT BACK THE COUNT
|
||
REST <B,A>
|
||
RTS PC
|
||
|
||
ACSAV: SAVE <E,D,C,B,A>
|
||
JMP (F)
|
||
|
||
ACRES: TST (P)+
|
||
REST <A,B,C,D,E>
|
||
RTS F
|
||
|
||
.SBTTL PROCESS HACKING ROUTINES
|
||
;CREATE PROCESS AND PUT IT ON THE STOPPED QUQUE
|
||
;RETURN ITEM NUMBER IN A AND CLEAR Z IF SUCESSFUL
|
||
;OTHERWISE SEET Z
|
||
;RETURN ADDRESS OF PROCESS TABLE ENTRY IN B
|
||
CRPROC: MOV #PRSLNF,A ;SIZE OF A PROCESS WITHOUT THE FLOATING POINT
|
||
JSR PC,CRITEM ;GET AN ITEM FOR IT
|
||
BEQ CRPRO1 ;NO ITEM, TOUGH LUCK
|
||
JSR PC,CLITEM ;CLEAR IT AND PUT IT IN ITEM0
|
||
MOV #ITPROC,(A) ;SET THE TYPE
|
||
BIS #PSUPSB,PSTOP(A) ;STOPPED!
|
||
INC PSTOPC(A) ;ONE FOR THE BIT
|
||
MOV #-1,PSPHRP(A) ;NO SPHERE AS OF NOW
|
||
MOV #-1,PITM2P(A) ;NO ITEMS EITHER
|
||
MOV #174000,PUPS(A) ;THE USER MODE PS
|
||
.IIF NZ TVS, MOV #-1,PTVMAP(A) ;DON'T MAP IN TV
|
||
INC NEWPRI ;GET TO NEXT RPOCESS ID #
|
||
BNE 1$
|
||
INC NEWPRI+2
|
||
1$: MOV NEWPRI,PRSID1(A) ;SET THE PROCESS ID
|
||
MOV NEWPRI+2,PRSID2(A)
|
||
MOV CURUSR,PRSUSR(A) ;CURRENT USER OWNS THIS
|
||
JSR PC,CURUIN ;TELL HIM HE OWNS ANOTHER PROCESS
|
||
|
||
;NOTE THAT CRUSER ENTERS HERE
|
||
;AND INTIALIZES THE VARIABLES THAT IT HAS IN COMMON WITH PROCESSES
|
||
CRUSR1: INC PRSREF(A) ;PRESUMABLY, THE GUY ASKING FOR IT WILL REFERENCE IT
|
||
MOV PFREEQ,PPRTPT(A) ;THE PROCESS BLOCK WE WILL SOON GOBBLE
|
||
JSR PC,ITM0PO ;NOW WE POP THE ITEM STACK
|
||
MOV PFREEQ,A ;GET A PROCESS TABLE ENTRY
|
||
BNE CRPRO2 ;GOT ONE!
|
||
MOV B,A ;AFTER ALL THAT WORK
|
||
JSR PC,DLITEM ;WE HAVE TO GIVE UP
|
||
CRPRO1: SEZ ;FAILURE
|
||
RTS PC
|
||
CRPRO2: MOV B,PRTPPT(A) ;SAVE THE ITEM # OF THE PROCESS IN THE PROCESS TABLE
|
||
MOV #IPRIOR,PRTPRI(A) ;EVERYONE STARTS OUT WITH THIS
|
||
SAVE B ;SAVE THE ITEM NUM
|
||
MOV CURUSR,B ;THE CURRENT USER BLOCK
|
||
CMP #-1,B ;ONLY THE VERY FIRST TIME (I HOPE)
|
||
BEQ CRPRO3
|
||
MOV PRTJTM(B),PRTJTM(A) ;START HIM AT A DISADVANTAGE
|
||
CRPRO3: MOV B,PRTUPT(A) ;THE USER CREATING THIS IS THE PROCESS'S USER
|
||
MOV #STOPQ,B ;MOVE FROM THE FREE Q TO THE STOPPED Q
|
||
JSR PC,TQUEUE
|
||
MOV A,B
|
||
POPACZ: REST A ;ITEM NUM
|
||
CLZ ;SUCESS
|
||
RTS PC
|
||
|
||
|
||
;KEEP THIS NEAR CRPROC
|
||
;CREATE A USER
|
||
;RETURN ITEM NUMBER IN A, ADDRESS OF PROCESS TABLE ENTRY IN B
|
||
;CLEAR Z IF SUCESSFUL, OTHERWISE SET IT
|
||
CRUSER: MOV #USRLEN,A ;THE LENGTH OF A USER
|
||
JSR PC,CRITEM ;DO IT!
|
||
BEQ CRPRO1 ;FAIL
|
||
JSR PC,CLITEM ;CLEAR THE ITEM
|
||
MOV #ITUSER,(A) ;SET THE TYPE
|
||
JSR PC,CRUSR1 ;USE A LOT OF CODE FROM CRPROC
|
||
;NOTE THAT THIS WILL LEAVE THE USER ON THE STOP QUEUE
|
||
;WHICH WILL CAUSE A PROBLEM IF THE SCHEDULER RUNS
|
||
;WHICH IT SHOULDN'T
|
||
BEQ CRPRO1 ;FAILURE
|
||
SAVE A ;SAVE THE ITEM INDEX
|
||
MOV B,A ;THE PROCESS TABLE ADDRESS
|
||
MOV #USERQ,B ;THE PLACE WHERE A USER BELONGS
|
||
JSR PC,TQUEUE ;TRANSFER TO USER QUEUE
|
||
MOV A,B
|
||
BR POPACZ ;SUCCESS
|
||
|
||
;DECREMENT REFERENCE COUNT OF PROCESS IN A
|
||
;WIPE IT OUT IFCOUNT REACHES ZERO
|
||
USRDEL: ;SAME THING FOR USER
|
||
DLPROC: SAVE B
|
||
JSR PC,ITM0PL
|
||
DEC PRSREF(A) ;ONE LESS REFERENCE
|
||
BNE DLPRO1 ;SOMEONE ELSE STILL REFERENCES IT
|
||
MOV ITM0A,A
|
||
MOV PPRTPT(A),A ;THE PROCESS TABLE ENTRY FOR IT
|
||
MOV #PFREEQ,B ;MAKE THE PROCESS TABLE ENTRY FREE
|
||
JSR PC,PRSAOD ;DEATVIATE PAGES FOR THIS PROCESS IF ACTIVE
|
||
JSR PC,TQUEUE
|
||
MOV ITM0A,A ;PROCESS AGAIN
|
||
CMP #ITPROC,(A) ;REALLY A PROCESS?
|
||
BNE DLPRO2 ;NO, PROBABLY A USER
|
||
MOV PRSUSR(A),A ;USER WHO OWNS IT
|
||
MOV PRTPPT(A),A ;THE ITEM OF THE USER
|
||
JSR PC,USRDEL ;ONE LESS FOR HIM
|
||
DLPRO2: MOV ITEM0,A
|
||
JSR PC,DLITEM ;FLUSH THE ACTUAL PROCESS
|
||
JSR PC,ITM0PO
|
||
REST B
|
||
SEZ ;SAY YOU DELETED IT
|
||
RTS PC
|
||
DLPRO1: JSR PC,ITM0PO
|
||
REST B
|
||
CLZ ;SAY YOU DIDN'T DELETE THE PROCESS
|
||
RTS PC
|
||
|
||
;INCREMENT REFERENC ECOUNT OF CURRENT USER
|
||
CURUIN: SAVE A
|
||
MOV CURUSR,A ;GET IT
|
||
MOV PRTPPT(A),A ;GET THE ITEM
|
||
JSR PC,ITM2PL ;LOAD IT
|
||
INC USRREF(A) ;INC IT
|
||
JSR PC,ITM2PO ;RESTORE
|
||
REST A
|
||
RTS PC
|
||
|
||
;TRANFER PROCESS TABLE ENTRY IN A
|
||
;FROM IT'S PRESENT QUEUE TO THE ONE IN B
|
||
TQUEUE: SAVE <C,PS>
|
||
SPL 7
|
||
;MUST SPL 7 HERE IF THE INT LEVEL LOOKS AT QUEUES BACKWARDS
|
||
MOV (A),C ;THE FORWARD POINTER OF THE ENTRY TO BE MOVED
|
||
MOV C,@PRTBCK(A) ;CORRECT THE FORWARD POINTER OF THE PREVIOUS ENTRY
|
||
TST C ;IS THERE A NEXT ENTRY?
|
||
BEQ 2$ ;NO, DON'T DO ANYTHING TO IT!
|
||
MOV PRTBCK(A),PRTBCK(C) ;CORRECT THE BACK POINTER OF THE NEXT ENTRY
|
||
;MAY SPL 0 HERE, THE ENTRY IS IN LIMBO FOR THE TIME BEING
|
||
2$: MOV (B),C ;GET THE CONTENTS OF THE QUEUE POINTER
|
||
MOV C,(A) ;POINT THE THING BEING MOVED AT THE BEGGINING OF THE QUEUE
|
||
MOV B,PRTBCK(A) ;CORRECT BACK POINTER OF THING WE ARE MOVING
|
||
;SPL 7 HERE IF YOU DID ABOVE
|
||
TST C ;IS THERE AN OLD FIRST ENTRY?
|
||
BEQ 1$ ;NO, DON'T DO ANYTHING TO IT!
|
||
MOV A,PRTBCK(C) ;FIX BACK POINTER OF OLD FIRST ENTRY ON NEW QUEUE
|
||
1$: MOV A,(B) ;FIX QUEUE POINTER ITSELF
|
||
;SPL 0
|
||
SAVE A
|
||
MOV PRTPPT(A),A ;GET THE ITEM NUMBER OF THE THING
|
||
JSR PC,ITM0PL
|
||
MOV QBIT(B),PQBIT(A) ;SET THE RIGHT Q-BIT
|
||
JSR PC,ITM0PO
|
||
REST A
|
||
REST <PS,C>
|
||
RTS PC
|
||
;PUT THE PROCESS WHO'S ITEM IS IN A
|
||
;INTO THE SPHERE WHOS ITEM IS IN B
|
||
;SHOULD FAIL FOR RUNNING PROCESS OR TOO MANY PROCESSES IN SPHERE (NOT YET)
|
||
;CLEARS Z ON SUCESS
|
||
PUTPRS: SAVE <A,B>
|
||
JSR PC,ITM0PL ;PUT THE PROCESS INTO ITEM 0
|
||
TST PSTOPC(A) ;IS IT STOPPED?
|
||
BEQ PUTPR2 ;NO, CAN'T MOVE IT THEN
|
||
JSR PC,REMPRS ;GET IT OUT OF ANY SPHERE IT IS IN
|
||
MOV (P),A ;GET THE SPHERE INDEX
|
||
JSR PC,ITM1PL ;LOAD IT UP
|
||
MOV ITM0A,B ;ADDRESS OF THE PROCESS
|
||
MOV SPHPRP(A),PSPHCP(B) ;POINT PROCESS TO BEG OF OLD LIST
|
||
MOV (P),PSPHRP(B) ;TELL PROCESS WHO IT BELONGS TO
|
||
MOV 2(P),SPHPRP(A) ;LINK IT INTO THE LIST
|
||
INC SPHPRC(A) ;ONE MORE PROCESS
|
||
INC PRSREF(B) ;INCREMENT THE REFERENCE COUNT
|
||
REST <B,A>
|
||
JSR PC,ITM0PO
|
||
JSR PC,ITM1PO
|
||
CLZ
|
||
RTS PC
|
||
PUTPR2: JSR PC,ITM0PO ;POP ITEM 0
|
||
REST <B,A>
|
||
SEZ ;SAY WE CAN'T DO IT
|
||
RTS PC
|
||
;REMOVE PROCESS IN ITEM0 (ADDRESS IN A) FROM WHATEVER SPHERE IT IS IN
|
||
;CLOBBERS B AND A
|
||
REMPRS: MOV PSPHRP(A),A ;POINTER TO SPHERE THIS BELONGS TO
|
||
BLE REMPR1 ;WHEW, NO SPHERE, IT'S EASY
|
||
JSR PC,ITM1PL ;GET THE SPHERE IT'S IN
|
||
MOV ITM0A,B ;ADDRESS OF THE PROCESS ITEM
|
||
CMP SPHPRP(A),ITEM0 ;DOES IT POINT DIRECTLY TO THE PROCESS?
|
||
BNE REMPR3 ;NO, GO SEARCH FO RIT
|
||
MOV PSPHCP(B),SPHPRP(A) ;SPLICE IT OUT OF THE LIST
|
||
BR REMP10 ;SKIP THIS LOAD
|
||
REMPR5: MOV PSPHRP(A),A ;GET THE SPHERE BACK
|
||
JSR PC,ITM1LD ;LOAD IT UP
|
||
REMP10: BIT #FAULT1!FAULT2!FAULT3,SFLAG(A) ;WAS IT STOPPED FOR FAULT
|
||
; BEQ REMPR9 ;NO
|
||
BR REMPR9 ;WELL BRUCE, I DON'T KNOW WHAT THIS CRAP IS FOR!!-RON
|
||
DEC PSTOPC(B) ;RESTART IT
|
||
BIC #PSPHSB,PSTOP(B) ;CLEAR THE SPHERE STOPPING IT BIT.
|
||
BGT REMPR8 ;WAS STOPPED FOR ANOTHER REASON
|
||
INC PSTOPC(B) ;STOP IT AGAIN BUT SAY SUPERIOR STOPPED IT
|
||
BIS #PSUPSB,PSTOP(B) ;OKAY FOR NOW
|
||
REMPR8: ADD #PFAULT,B ;POINT TO THE FIRST PHAULT WORD
|
||
TST (B)+ ;CHECK THE THREE PHAULT WORDS
|
||
BNE REMPR7
|
||
REMPR9: JSR PC,ITM1PO ;RESTORE ITEM 1
|
||
MOV ITM0A,A ;ADDRESS OF PROCESS
|
||
CLR PSPHRP(A) ;NO LONGER IN SPHERE
|
||
MOV ITEM0,A ;THE PROCESS
|
||
JSR PC,DLPROC ;DECREMTENT THE REF COUNT AND DELETE IF 0
|
||
REMPR1: RTS PC
|
||
REMPR7: MOV ITEM1,A ;THE SPHERE TO DO THE DEED ON
|
||
JSR PC,FALTFX ;FIX THE FAULT
|
||
CLR -(B) ;CLEAR THE FAULT WORDS
|
||
BR REMPR9 ;DONE
|
||
REMPR3: DEC SPHPRC(A) ;ONE LESS PROCESS
|
||
MOV SPHPRP(A),A ;GET THE FIRST PROCESS IN LINE
|
||
REMPR6: BUGC EQ ;IS THERE ANOTHER ONE?
|
||
JSR PC,ITM1LD ;PUT THIS PROCESS INTO ITEM1
|
||
CMP PSPHCP(A),ITEM0 ;DOES IT POINT TO PROCESS WE WANT TO SPLICE OUT?
|
||
BNE REMPR4 ;NOPE, KEEP TRYING
|
||
MOV ITM0A,B
|
||
MOV PSPHCP(B),PSPHCP(A) ;SPLICE IT OUT OF THE LIST
|
||
BR REMPR5 ;NOW WE CAN PUT IT WHERE WE WANT TO
|
||
REMPR4: MOV PSPHCP(A),A ;GET NEXT ONE
|
||
BR REMPR6 ;GO CHECK IT OUT
|
||
|
||
;DECREMENT STOP COUNT OF PROCESS
|
||
;IF IT REACHES ZERO, PUT PROCESS ONTO RUN Q
|
||
;ASSUMES PROCESS IS LOADED INTO ITEM 0
|
||
PSTPDC: SAVE A
|
||
JSR PC,ITM0PL
|
||
DEC PSTOPC(A) ;ONE LESS REASON TO BE STOPPED
|
||
BUGC LT ;SHOULD NOT GET NEGATIVE!
|
||
BGT PSTPD1 ;DON'T START IT YET
|
||
SAVE <B,C>
|
||
MOV PPRTPT(A),A ;POINTER TO THE PROCESS TABLE
|
||
MOV #ACTQ,B ;START HIM UP AT AN ADVANTAGE
|
||
JSR PC,PRSAOD
|
||
JSR PC,TQUEUE
|
||
REST <C,B>
|
||
PSTPD1: JSR PC,ITM0PO
|
||
REST A
|
||
RTS PC
|
||
;INCREMENT STOP COUNT OF PROCESS WHOSEITEM ISIN A
|
||
;IF THE COUNT WAS ZERO AND THE PROCESS WAS IN THE SYSTEM, PCLOSER IT
|
||
PSTPIN: JSR F,ACSAV
|
||
JSR PC,ITM0PL ;GET IT INTO THE MAP
|
||
TST PSTOPC(A) ;IS IT ALREADY NON-ZERO?
|
||
BNE PSTPI1 ;YES, JUST INCREMENT
|
||
MOV PPRTPT(A),A ;IT'S PROCESS TABLE ENTRY
|
||
MOV #STOPQ,B ;STOP THE PROCESS
|
||
JSR PC,PRSAOD ;DEACTIVE PAGES OF THIS PROCESS
|
||
JSR PC,TQUEUE
|
||
.IFNZ NPC
|
||
JSR PC,PRSRPC ;PCLOSER IT
|
||
.IFF
|
||
MOV ITM0A,A
|
||
TST PSPC(A) ;IN THE SYSTEM?
|
||
BEQ PSTPI1 ;NOPE, PC ISUSER MODE PC
|
||
CLR PSPC(A) ;CLEAR HIS PC
|
||
JSR PC,PRSUNL ;UNLOCK HIS SWITCHES
|
||
.ENDC
|
||
PSTPI1: INC PSTOPC(A) ;TELL THE WORLDHE IS STOPPED
|
||
JMP ACRTP0 ;POP 0 AND RESTORE REGISTERS
|
||
|
||
PRSRPC: CMP PRUNNG,ITEM0 ;NOT ADVISABLE TO DO THIS TO RUNNNG PROCESS
|
||
BUGC EQ
|
||
MOV ITM0A,A
|
||
TST PSPC(A) ;IN THE SYSTEM?
|
||
BEQ 1$ ;NOPE, PC ISUSER MODE PC
|
||
CLR PSPC(A) ;CLEAR HIS PC
|
||
JMP PRSUNL ;UNLOCK HIS SWITCHES
|
||
1$: RTS PC
|
||
|
||
;UNLOCK ALL THE SWITCHES OF THE GUY IN ITEM0
|
||
;IN "BEING PCLOSERED" MODE
|
||
;CAN BE EXPECTED TO CLOBBER MOST REGISTERS
|
||
PRSUNL: SAVE BPCLSR ;SAVE THE FLAG
|
||
MOV #1,BPCLSR ;SAY WE ARE PCLOSERING HIM
|
||
PSTPI2: MOV ITM0A,A
|
||
TST PLCKSL(A) ;ANY SWITCHES LOCKED
|
||
BEQ PSTPI3 ;NOPE
|
||
JSR PC,LSWPOP ;POP THE TOP SWITCH
|
||
BR PSTPI2
|
||
PSTPI3: REST BPCLSR ;DONE PCLOSERING HIM
|
||
RTS PC
|
||
|
||
;THIS IS WHERE WE GET AFTER SOMEONE SETS PIRQ AND PIRBRK DISPATCHES
|
||
;(NOTE THAT WE DON'T GET TO PIRBRK UNTIL ALL INTERUPTS HIGHER
|
||
;THAN CLKL HAVE EXITED. CLKL SHOULD BE THE LOWEST INTERUPT IN
|
||
;THE SYSTEM, SO IT ALWAYS INTERRUPTS DIRECTLY FROM
|
||
;THE MAIN PROGRAM LEVEL)
|
||
;STOP A PROCESS IF IT IS IN USER MODE
|
||
;IF IT FINDS THE PROCESS
|
||
;WAS IN USER MODE, IT ASSUMES THAT THE SECOND REGISTER SET
|
||
;WAS BEING USED, AND CLOBBERS SET 0 ARBITRAILY
|
||
;IT SAVES THE PROCESSES REGISTERS, THEN RETURNS TO WHOMEVER STARTED
|
||
;THE PROCESS BY DOING AN RTS PC
|
||
STOPPR: TST USRMOD ;ARE WE IN USER MODE?
|
||
BNE PIRRET ;NOPE, THE SYSTEM WILL STOP HIM
|
||
MOV PC,USRMOD ;NO LONGER IN USER MODE
|
||
TST (P)+ ;FLUSH THE SAVED A
|
||
JSR F,SPCPSP ;SAVE THE PC, THE PS AND P
|
||
JSR PC,PACSAV ;SAVE THE REST OF THE REGISTERS, INCLUDING THE FPP
|
||
JSR PC,SAVAWB ;SAVE THE A AND W BITS
|
||
JSR PC,TIMEUS ;GO CHARGE HIM FOR TIME USED
|
||
MOV #-1,PRUNNG ;NO PROCESS RUNNING NOW
|
||
CLR CDISP ;NO ONE AROUND
|
||
RTS PC ;(GULP!!) RETURN TO CALLER
|
||
PIRRET: REST A
|
||
CHECKP
|
||
RTT
|
||
;CHARGE USER FOR THE TIME HE HAS USED
|
||
;EXPECTS POINTER TO ITEM0 IN A. CLOBBERS B AND C
|
||
;AND SPHERE IN ITEM1
|
||
TIMEUS: MOV TUSED,B ;NUMBER OF TICKS HE USED
|
||
ASL B ;CONVERT TO HALF TICKS
|
||
BNE 1$ ;DID HE USE ANY TIME?
|
||
INC B ;EVERYONE USES AT LEAST ONE HALF-TICK
|
||
1$: ADD B,PTUSED(A) ;UPDATE HIS TIME USED
|
||
ADC PTUSED+2(A)
|
||
MUL #JTMUAC,B ;MULTIPLY BY THE ADDTIVE FACTOR
|
||
MOV PPRTPT(A),C ;POINTER TO PROCESS BLOCK
|
||
ADD B,PRTJTM(C) ;UPDATE THE PROCESS JTMU
|
||
MOV PRTUPT(C),C ;POINTER TO THE USER BLOCK
|
||
ADD B,PRTJTM(C) ;UPDATE THAT JTMU TOO
|
||
RTS PC
|
||
;ENTER THE RUNNING QUEUE
|
||
RUNME: TST ACTCHK
|
||
BNE RUNME1
|
||
SAVE <#ACTQ> ;PROPABLY WANT TO GO TO ACTIVE QUQUE FROM DORMANT
|
||
SAVE A
|
||
MOV ITM0A,A ;POINT TO PROCESS
|
||
BIT #DORQB,PQBIT(A) ;WAS IT DORMANT?
|
||
BNE FLUSH5 ;YES, GO TO ACTIVE STATE
|
||
MOV #RUNQ,2(P) ;NO, GO TO RUN STATE
|
||
BR FLUSH5
|
||
RUNME1: SAVE <#WINQ> ;I'M BEING ACTIVATED SO PUT ME ON WINQ
|
||
BR FLUSH
|
||
|
||
;ENTER THE SHORT FLUSHED QUEUE
|
||
SFLUSH:LFLUSH: ;ENTER A HANGING QUQUE
|
||
SAVE #DORQ ;IF WE ARE ALREADY RUNNING, BECOME DORMANT
|
||
SAVE A
|
||
MOV ITM0A,A ;POINT TO PROCESS
|
||
TST PSPC(A) ;ALREADY FLUSHED?
|
||
BEQ FLUSH5 ;NO, BECOME DORMANT
|
||
BIT #DORQB,PQBIT(A) ;DORMANT BEFORE?
|
||
BNE FLUSH5 ;STAY THAT WAY
|
||
MOV #IACTQ,2(P) ;STAY INACTIVE
|
||
BR FLUSH5
|
||
|
||
FLUSH: SAVE A ;GET A FREE REGISTER
|
||
MOV ITM0A,A ;THE RUNNING PROCESS IS ALWAYS ITEM 0
|
||
FLUSH5: ADD #PSREGS,A ;A POINTER TO THE SYSTEM REGISTERS FOR THE GUY
|
||
TST BPCLSR ;IS THIS GUY BEING PCLOSERED?
|
||
BUGC NE ;SHOULD NEVER HANG!
|
||
REST (A)+ ;GET BACK A
|
||
.IRPC X,<BCDEF>
|
||
MOV X,(A)+
|
||
.ENDM
|
||
MOV ITM0A,E
|
||
MOV PPRTPT(E),A ;POINTER TO PROCESS TABLE
|
||
MOV (P),B ;QUEUE TO MOV IT TO
|
||
JSR PC,PRSAOD ;ACTIVATE OR DEACTIVE PAGES IF APPROPRIATE
|
||
JSR PC,TQUEUE ;DO THE ACTUAL MOVE
|
||
MOV ITM0A,A
|
||
REST <B,E> ;GET THE QUEUE AGAIN
|
||
TST PSPC(A) ;WERE WE ALREADY FLUSHED?
|
||
BNE FLUSH2 ;YES
|
||
.IRPC X,<01>
|
||
TST ITM'X'D
|
||
BUGC NE ;HAD ITEMS PUSHED
|
||
.ENDM
|
||
CLR CDISP ;OLD GUY NOT RUNNING ANY MORE
|
||
JSR PC,PACSAV ;IN CASE USER'S REGISTERS NOT SAVED YET
|
||
JSR PC,TIMEUS ;CHARGE HIM FOR TIME USED
|
||
JSR PC,SAVAWB ;SAVE REFERENCED PAGES
|
||
JSR PC,PDLSAV ;SAVE THE SYSTEM PDL
|
||
MOV ITM1A,A ;POINT TO THE SPHERE
|
||
MOV SPRTPT(A),A ;POINT TO THE PROCESS TABLE ENTRY
|
||
FLUSH2: MOV ITM0A,A
|
||
MOV A,B ;COPY POINTER INTO ITEM
|
||
ADD #PITM2P+2,A ;POINT TO ITEM2 PDL
|
||
MOV ITM2D,C ;COUNT OF ITEMS PUSHED ON ITEM2 STACK
|
||
MOV C,PITM2C(B)
|
||
BEQ FLUSH4 ;NONE, EASY CASE
|
||
ASL C ;MAKE COUNT INTO INDEX
|
||
CMP #PIT2PL-2,C ;CHECK THAT THERE AREN'T TOO MANY PUSHED
|
||
BUGC LT
|
||
ADD C,A ;POINT TO END OF PDL AREA TO BE USED
|
||
ASR C ;CONVERT BACK TO COUNT
|
||
FLUSH3: MOV ITEM2,-(A) ;SAVE CURRENTLY LOADED ITEM
|
||
JSR PC,ITM2PO ;POP NEXT ONE
|
||
SOB C,FLUSH3
|
||
FLUSH4: MOV ITEM2,-(A) ;SAVE THE LAST ONE
|
||
MOV #-1,A ;DUMMY ITEM
|
||
JSR PC,ITM2LD ;LOAD TO FORCE W BITS ON ITEM2
|
||
MOV E,PSPC(B)
|
||
RTS PC
|
||
;START THE PROCESS WHOSE PROCESS TABLE ENTRY IS
|
||
;POINTED TO BY A
|
||
;WHEN PROCESS FINALLY STOPS, THE ROUTINE WILL RETURN
|
||
;CLOBBERS ALL REGISTERS
|
||
STPROC: MOV HSECS,LTPSTA ;SAVE THE LAST TIME A PROCESS WAS STARTED
|
||
MOV P,STPSVP ;SAVE P FOR ERROR RECOVERY
|
||
BIS #30000,PS ;MAKE SURE PREVIOUS MODE IS USER
|
||
SPL CLKL ;STOP US FROM GETTING STOPPED
|
||
BIC #CLKPIR,PIRQ ;MAKE SURE NO STOP PENDING
|
||
MOV PRTUPT(A),CURUSR ;THE GUY TO "CHARGE" FOR THIS RUN
|
||
CLR TUSED ;START COUNTING NOW
|
||
MOV PRTPPT(A),A ;GET THE PROCESS ITEM #
|
||
MOV A,PRUNNG ;THIS IS THE RUNING PROCESS
|
||
MOV A,CDISP ;SAY WHICH PROCESS IS RUNNING
|
||
JSR PC,ITM0LD ;IT IS EXPECTED TO BE IN ITEM0
|
||
MOV A,B ;SAVE THE POINTER TO IT
|
||
MOV PSPHRP(B),A ;GET A POINTER TO THE SPHERE
|
||
JSR PC,ITM1LD ;IT IS EPECTED IN ITEM1
|
||
JSR PC,PACRES ;RESTORE REGISTER SET 1
|
||
JSR PC,MAPRES ;RESTORE THE MAP
|
||
SAVE PUP(B) ;GET THE USER'S PDL POINTER
|
||
MTPI P ;RESTORE IT TO HIM
|
||
TST PSPC(B) ;IS HE RUNNING IN THE SYSTEM?
|
||
BNE STPRO1 ;YES, GO RESTORE OTHER THINGS
|
||
STPRO3: BIC #PPCLDF!PPCLSR!PFALTB,PFLAGS(B) ;THEN HE DOESN'T NEED TO BE PCLOSERED!
|
||
TST PFAULT(B) ;IS THERE A FAULT?
|
||
BEQ 1$ ;NO, JUST RETURN TO HIM
|
||
JMP CFAULT ;CAUSE THE MAGIC FAULT TO HAPPEN
|
||
1$: MOV P,PSP(B) ;WHERE THE PDL ENDS
|
||
SAVE <PUPS(B),PUPC(B)> ;HIS PROCESSOR STATUS AND HIS PROGRAM COUNTER
|
||
CLR USRMOD ;THE WORLD IS NOW IN USER MODE
|
||
CHECKP
|
||
RTT ;RETURN TO HIM IN USER MODE
|
||
|
||
STPRO1: BIT #PPCLSR,PFLAGS(B) ;SHOULD HE BE PCLOSERED?
|
||
BEQ STPRO2 ;NO
|
||
BIT #PPCLDF,PFLAGS(B) ;DEFERED?
|
||
BNE STPRO2 ;YUP
|
||
CLR PITM2C(B) ;FLUSH THE ITEM STACK
|
||
CLR PSPC(B)
|
||
MOV PC,BPCLSR ;HE'S BEING PCLOSERED
|
||
JSR PC,LSWCLR ;CLEAR THE SWITCHES
|
||
CLR BPCLSR
|
||
BR STPRO3 ;GO START IT IN USER MODE
|
||
|
||
STPRO2: JSR F,PDLRES ;RESTORE HIS SYSTEM PDL
|
||
MOV B,A ;POINTER TO PROCESS
|
||
JSR PC,ITM2RS ;RESTORE ITEM 2 PDL
|
||
SAVE <#30000,PSPC(B)> ;GET PS AND GET PC
|
||
MOV (P),OPSPC(B) ;SAVE FOR DEBUGGING
|
||
CLR PSPC(B) ;INDICATE NOT HUNG
|
||
MOV PC,USRMOD ;INDICATE THAT WE ARE NOT IN USER MODE
|
||
MOV B,A ;POINTER TO THE PROCESS
|
||
ADD #PSREGS+14,A ;THE SYSTEM REGISTERS
|
||
.IRPC X,FEDCBA
|
||
MOV -(A),X
|
||
.ENDM
|
||
CHECKP
|
||
RTT ;EXIT TO RIGHT PLACE IN THE SYSTEM
|
||
;SAVE THE USER'S PC, PS AND PDL POINTER
|
||
;CALL WITH JSR F,SPCPSP
|
||
;A GETS CLOBBERED TO ITEM 0 ADDRESS
|
||
;F GETS CLOBBERED TO VALUE OF THE USER'S P
|
||
;ITEM0 IS EXPECTED TO BE THE PROCESS
|
||
SPCPSP: TST (P)+
|
||
MOV ITM0A,A ;THE ADDRESS OF THE PROCESS IN THE MAP
|
||
REST <PUPC(A),PUPS(A)> ;SAVE HIS PC AND HIS PS
|
||
SAVEPP: MOV #30000,PS ;MAKE SURE PREVIOUS MODE IS RIGHT
|
||
MOV ITM0A,A
|
||
MFPD P ;GET HIS P
|
||
MOV (P),PUP(A) ;SAVE HIS PDL POINTER (PUP-P?)
|
||
RTS F ;RETURN WITH P IN F
|
||
;SAVE THE PROCESSES REGISTERS, INCLUDING THE FPP IF THAT IS ENABLED
|
||
;THE GENERAL REGISTERS ARE IN SET 1
|
||
;THE ADDRESS OF THE PROCESS ITEM IS EXPECTED IN A
|
||
;THE PROCESS ITEM IS EXPECTED TO BE IN THE MAP
|
||
PACSAV: SAVE A ;TO COMMUNICATE WITH THE OTHER REGISTER SET
|
||
BIT #PACSVF,PFLAGS(A) ;HAVE THE AC'S ALREADY BEEN SAVED?
|
||
BEQ PACSV2 ;ZERO=>SAVED
|
||
BIC #PACSVF,PFLAGS(A)
|
||
BIS #4000,PS ;CHANGE TO OTHER SET
|
||
SAVE A ;SAVE A OF SET 1
|
||
MOV 2(P),A ;GET A FROM SET 0
|
||
ADD #PUREGS,A ;POINT TO PALCE TO SAVE REGISTERS
|
||
REST (A)+ ;SAVE A OF SET 1
|
||
MOV B,(A)+ ;SAVE REST OF SET 1
|
||
MOV C,(A)+
|
||
MOV D,(A)+
|
||
MOV E,(A)+
|
||
MOV F,(A)+
|
||
BIC #4000,PS ;BACK TO SET 0
|
||
;NOTE THAT SET 0'S A HAS NOT BEEN CLOBBERED
|
||
BIT #PFPFLG,PFLAGS(A) ;HAS HE ENABLED THE FPP?
|
||
BEQ PACSV1 ;NOPE
|
||
STFPS PFPPS(A) ;STORE THE STATUS
|
||
ADD #PFPPRG,A ;POINT TO FPP REGISTERS
|
||
SETD ;SO WE SAVE ALL THE BITS
|
||
STD A,(A)+
|
||
STD B,(A)+
|
||
STD C,(A)+
|
||
STD D,(A)+ ;SAVE ALL WE CAN GET TO DIRECTLY
|
||
LDD E,A ;LAST 2 HAVE TO BE MOVED SPECIAL
|
||
STD A,(A)+
|
||
LDD F,A
|
||
STD A,(A)+
|
||
PACSV1: MOV (P),A ;POINT BACK TO THE ITEM START
|
||
BIT #PTVFLG,PFLAGS(A) ;SAVING TV REGISTERS?
|
||
BEQ PACSV2
|
||
MOV TVMSK,PTVMSK(A)
|
||
MOV TVINCR,PTVINC(A)
|
||
MOV TVSHR,PTVSHR(A)
|
||
MOV TVRADR,PTVRAD(A)
|
||
PACSV2: REST A
|
||
RTS PC
|
||
;RESTORE THE USER'S REGISTERS
|
||
;B IS EXPECTED TO CONTAIN A POINTER TO THE PROCESS ITEM
|
||
;NO REGISTERS ARE CLOBBERED (EXCEPT, OF COURSE, THE USER'S)
|
||
PACRES: SAVE B
|
||
BIT #PACSVF,PFLAGS(B) ;WERE THEY EVER SAVED?
|
||
BNE PACRS1 ;ONE=>NOT SAVED
|
||
BIS #PACSVF,PFLAGS(B)
|
||
BIS #4000,PS ;GO TO REGISTER SET 1
|
||
MOV (P),A ;GET THE POINTER TO THE ITEM
|
||
ADD #PUREGS+14,A ;CONVERT TO A REGISTER POINTER
|
||
.IRPC X,<FEDCBA>
|
||
MOV -(A),X
|
||
.ENDM
|
||
BIC #4000,PS ;BACK TO SET 0
|
||
BIT #PFPFLG,PFLAGS(B)
|
||
BEQ PACRS2 ;DOESN'T USE FPP
|
||
SETD ;RESTORE ALL BITS
|
||
ADD #PFPPRG+<16.*2>,B ;POINT TO REGISTERS E AND F FIRST
|
||
LDD (B)+,A
|
||
STD A,E
|
||
LDD (B)+,A
|
||
STD A,F
|
||
MOV (P),B
|
||
ADD #PFPPRG,B ;GO BACK FOR REG'S A THROUGH D
|
||
.IRPC X,<ABCD>
|
||
LDD (B)+,X
|
||
.ENDM
|
||
MOV (P),B
|
||
LDFPS PFPPS(B)
|
||
PACRS2: BIT #PTVFLG,PFLAGS(B)
|
||
BEQ PACRS1
|
||
MOV PTVMSK(B),TVMSK
|
||
MOV PTVINC(B),TVINCR
|
||
MOV PTVSHR(B),TVSHR
|
||
MOV PTVRAD(B),TVRADR
|
||
MOVB #73,TVSHR+1 ;SET THE THING INTO MEMORY
|
||
PACRS1: REST B
|
||
RTS PC
|
||
;RESTORE THE USER'S SYSTEM PDL
|
||
;CALLED WITH JSR F,PDLRES
|
||
;CLOBBERS A AND C AND F
|
||
;AS WELL AS PUSHING THINGS ONTO P
|
||
;EXPECTS A POINTER TO THE PROCESS ITEM IN B
|
||
PDLRES: TST (P)+
|
||
MOV PSP(B),A ;THE INCREMENT FOR THE STACK POINTER
|
||
MOV P,PSP(B) ;FOR PDLSAV, THE VALUE IT SHOULD HAVE AFTER SAVING
|
||
ASR A ;CONVERT TO COUNT
|
||
BEQ PDLRE1 ;NONE, DON'T LOOP
|
||
MOV B,C ;COPY POINTER TO ITEM
|
||
ADD #PPDL,C ;MAKE IT A POINTER TO THE PDL
|
||
PDLRE2: MOV (C)+,-(P) ;POP-PUSH
|
||
SOB A,PDLRE2
|
||
PDLRE1: JMP (F)
|
||
;SAVE THE SYSTEM PDL INTO THE PROCESS'S
|
||
;SYSTEM PDL AREA. SAVES UP TO WHAT IS INDICATED BY PSP
|
||
;CALLED WITH JSR PC,PDLSAV
|
||
;CLOBBERS A,B,C, AND F
|
||
;ALSO POPS STUFF OFF THE STACK
|
||
PDLSAV: REST F ;GET THE RETURN ADDRESS
|
||
MOV ITM0A,A ;GET A POINTER TO THE PROCESS
|
||
MOV PSP(A),B ;WHAT THE PDL POINTER SHOULD BE
|
||
MOV B,C
|
||
SUB P,B ;WHAT'S THE DIFFERENCE?
|
||
MOV B,PSP(A) ;SAVE THE OFFSET
|
||
BEQ PDLSA1 ;NONE, FORGET IT
|
||
BUGC LT ;MAKE SURE IT'S POSITIVE
|
||
CMP #PRPDLL,B ;IS IT PUSHED TO DEEP?
|
||
BUGC LE ;NAUTGHY!
|
||
ADD A,B ;MAKE A POINTER TO THE END OF
|
||
ADD #PPDL,B ;THE PROCESS'S PDL
|
||
PDLSA2: MOV (P)+,-(B) ;POP-PUSH
|
||
CMP C,P ;ARE WE DONE YET?
|
||
BNE PDLSA2 ;NOPE
|
||
PDLSA1: JMP (F)
|
||
|
||
;RETURN THE NEXT WOR DFROM THE USER'S PDL
|
||
;INCREMENT THE POP COUNT SO IT IS POPED IF THE CALL RETURNS
|
||
;THE WORD IS RETURNED IN A
|
||
RETNSW: SAVE B
|
||
MOV ITM0A,A ;ASSUME THE PROCESS IS ITEM 0
|
||
RETNS1: MOV PUP(A),B ;THE PDL POINTER
|
||
ADD PUPDLO(A),B ;THE OFFSET SO FAR
|
||
ADD #2,PUPDLO(A) ;POPPED ONE MORE THING
|
||
MFPD (B) ;GET THE WORD
|
||
MOV (P),A ;SAVE THE WORD
|
||
MTPD (B) ;MAKE SURE WE CAN WRITE IT BACK
|
||
REST B
|
||
RTS PC
|
||
;RETURN THE PREVIOUS WORD FROM THE USER'S STACK (THE ONE YOU GOT ALREADY)
|
||
;RETURNED IN A
|
||
RETPSW: SAVE B
|
||
MOV ITM0A,A
|
||
SUB #2,PUPDLO(A) ;BACK UP!
|
||
BR RETNS1 ;GO DO THE REST
|
||
|
||
:GIVE THE WORD IN B TO THE USER
|
||
GIVPSW: SAVE <A,C>
|
||
MOV ITM0A,A ;ASSUME PROCESS IS IN ITEM0
|
||
MOV PUP(A),C ;THE PDL POINTER
|
||
SUB #2,PUPDLO(A) ;DEC THE OFFSET
|
||
ADD PUPDLO(A),C ;MAKE IT CORRECTED
|
||
MFPD (C) ;TO COMPENSATE FOR PAGE LOSSAGE
|
||
MOV B,(P) ;WORD TO TRANSFER TO USER
|
||
MTPD (C) ;MOVE THE WORD
|
||
REST <C,A> ;RESTORE REGS
|
||
RTS PC
|
||
.SBTTL SPHERE HACKING ROUTINES
|
||
|
||
;CREATE A SPHERE
|
||
;RETURN THE INDEX OF THE ITEM IN A
|
||
CRSPHR: SAVE B
|
||
MOV #SPHLEN,A ;THE LENGTH OF A SPHERE (INITIALLY)
|
||
JSR PC,CRITEM ;MAKE ONE
|
||
BNE CRSPH1 ;DID IT SUCEED?
|
||
CRSPH0: REST B
|
||
SEZ ;INDICATE FAILURE
|
||
RTS PC ;NOPE
|
||
CRSPH1: JSR PC,CLITEM ;LOAD IT INTO ITEM0 AND CLEAR IT
|
||
MOV #ITSPHR,(A) ;SET THE TYPE
|
||
JSR PC,CURUIN ;INCREMENT THE CURENT USER
|
||
MOV CURUSR,SUSRPT(A) ;THE GUY WHO CREATES IT GETS "CHARGED" FOR IT
|
||
MOV #SICLST+<NCLSEB*CLSELN*2>,SCLSEP(A) ;THE LAST LOCATION USED
|
||
SAVE <C,B>
|
||
MOV A,B
|
||
ADD #SCLSTT,B ;GET AN ADDRESS POINTER TO THE INDEX TABLE
|
||
MOV #<MNCLSE/NCLSEB>/2,C ;NUMBER OF WORDS OF POINTERS
|
||
1$: MOV #-1,(B)+
|
||
SOB C,1$ ;INTIALIZE THEM TO POINT AT NOTHING
|
||
MOVB #1,-(B) ;EXPECT THE LAST ONE POINTS AT THE 2ND BLOCK
|
||
CLRB SCLSTT(A) ;AND THE FIRST TO THE FIRST
|
||
MOV CURSPH,SMSSPT(A)
|
||
MOV (P),B ;GET THE ITEM INDEX BACK
|
||
JSR PC,CRUSR1 ;INITIALIZE THE PROCESS TABLE ENTRY
|
||
BEQ CRSPH2
|
||
MOV B,A ;THE PROCESS TABLE ENTRY
|
||
MOV #SPHRQ,B ;THE PLACE TO PUT IT
|
||
JSR PC,TQUEUE ;MOVE IT
|
||
REST A ;THE ITEM #
|
||
REST C
|
||
REST B ;THE ORIGINAL CONTENTS OF B
|
||
CLZ ;SUCECESS
|
||
RTS PC
|
||
CRSPH2: REST <A,C>
|
||
BR CRSPH0
|
||
|
||
;SAVE THE A AND W BITS FOR THE CURRENT SPHERE
|
||
;THE SPHERE IS EXPECTED TO BE IN ITEM1, AND THE USER
|
||
;SEGMENTATION REGISTERS ARE EXPECTED TO REFLECT THIS SPHERE
|
||
SAVAWB: JSR F,ACSAV
|
||
.IFNZ NTVS
|
||
MOV ITM0A,A ;POINTER TO PROCESS
|
||
MOVB TVSEL,PTVMAP+1(A) ;SAVE VALUE OF SELECT REGISTER
|
||
.ENDC
|
||
MOV ITM1A,A ;ADDRESS OF ITEM1 IN THE MAP
|
||
ADD #SUPTS,A ;POINT TO THE UPTS DR
|
||
MOV #USRISD,B ;THE ACTUAL SEGMENTATION REGISTERS
|
||
MOV #20,C ;NUMBER OF SEGMENTS
|
||
SAVAW1: BIT #100,(B)+ ;THE SEGMENTER'S DR, W BIT
|
||
BEQ SAVAW2 ;NOT WRITTEN, CAN IGNORE IT
|
||
BIC #100,-2(B) ;FLUSH THE W BIT
|
||
TST (A) ;IS THE PAGE STILL THERE?
|
||
BEQ SAVAW2 ;NOPE, DELETED
|
||
BIT #7,-2(B) ;REAL PAGE?
|
||
BEQ SAVAW2 ;NOPE
|
||
BIT #UPTABS,(A) ;IS IT AN ABS PAGE?
|
||
BEQ 1$ ;NOPE, DO YOUR THING
|
||
BIS #100,4(A) ;SAVE THE W BIT IN THE GUYS DR, JUST FOR FUN
|
||
BR SAVAW2
|
||
1$: MOV UPTPBP(A),D ;GET PB POINTER
|
||
BIC #PBVASS!PBVAS,PBFLAG(D) ;NO LONGER VALID AT SOURCE OR SWAP SPACE
|
||
SAVAW2: ADD #UPTLEN,A ;TO THE NEXT UPT ENTRY
|
||
SOB C,SAVAW1
|
||
MOV #-1,CURSPH ;NO SPHERE MAPPED IN NOW!
|
||
JMP ACRET
|
||
.SBTTL SPHERE HACKING ROUTINES- C-LIST HANDLERS
|
||
;GET ADDRESS OF A C-LIST ENTRY
|
||
;A CONTAINS ADDRESS OF SPHERE IN MAP
|
||
;B CONTAINS C-LIST NUMBER
|
||
;B RETURNS OFFSET INTO SPHERE IF SUCESSFUL (Z CLEAR)
|
||
;OTHERWISE Z SET AND B CONTAINS SPHERE BYTE ADDRESS OF INDEX BYTE
|
||
GCLSTA: SAVE <D,C,A>
|
||
CMP B,#200 ;IS IT TO LARGE?
|
||
BHIS GCLST1 ;YES
|
||
CLR C ;FOR THE DIVIDE
|
||
MOV B,D ;SAVE C-LIST NUMBER
|
||
DIV #NCLSEB,C ;GET THE BLOCK AND OFFSET
|
||
ADD C,A ;CONVERT TO
|
||
ADD #SCLSTT,A ;ADDRESS OF INDEX BYTE
|
||
MOVB (A),B ;GET THE BYTE
|
||
BLT GCLST1 ;NEGATIVE IMPLIES NO STUCK BLOCK
|
||
MUL #NCLSEB*CLSELN,B ;RELATIVE ADDRESS OF BLOCK
|
||
MUL #CLSELN,D ;REMANDER
|
||
ADD D,B ;NOW WITHIN BLOCK
|
||
ADD #SICLST,B ;LESS RELATIVE
|
||
REST <A,C,D>
|
||
CLZ ;SUCESS
|
||
RTS PC
|
||
GCLST1: MOV A,B ;SAVE FOR THE CALLER
|
||
REST <A,C,D>
|
||
SEZ ;FAILURE
|
||
RTS PC
|
||
;ALWAYS GET THE ADDRESS OF A C-LIST ENTRY
|
||
;(CREATE IF NON-EXISTANT)
|
||
;B CONTAINSC-LIST NUMBER
|
||
;C CONTAINS ITEM NUMBER TO INSERT INTO
|
||
;A GETS CLOBBERED
|
||
;B RETURNS OFFSET INTO SPHERE IF SUCESSFUL (Z CLEARED)
|
||
;OTHERWISE, SET Z
|
||
AGCLSA: SAVE B
|
||
MOV C,A ;COPY SPHERE ITEM NUMBER
|
||
JSR PC,ITM1PL ;LOAD IT INTO THE MAP
|
||
JSR PC,GCLSTA ;SEE IF THE ENTRY IS ALREADY THERE
|
||
BNE AGCLS1 ;SUCESS, IT'S ALREADY THERE
|
||
MOV SCLSEP(A),A ;POINTER TO BEGGINING OF UNUSED SPACE
|
||
ADD #NCLSEB*CLSELN,A ;NEW END
|
||
JSR PC,ITM1PO ;IN CASE WE HANG
|
||
SAVE B
|
||
MOV C,B ;COPY SPHERE ITEM NUMBER
|
||
ASH #-6,A ;MAKE WORD SIZE INTO BLOCK SIZE
|
||
JSR PC,EXITEM ;MAKE SURE IT'S BIG ENOUGH
|
||
BEQ AGCLS2 ;FAILURE
|
||
MOV C,A ;ITEM WHERE THE NEW THING IS GOING
|
||
JSR PC,ITM1PL ;LOAD IT UP
|
||
MOV #NCLSEB*CLSELN/2,B ;NUMBER OF WORDS WE JUST ADDED
|
||
MOV SCLSEP(A),C ;POINTER TO OLD END+2
|
||
ADD #NCLSEB*CLSELN,SCLSEP(A) ;THE NEW END
|
||
SAVE D
|
||
MOV C,D ;FOR DIVIDE LATER
|
||
ADD A,C ;MAKE IT A REAL ADDRESS FOR CLEAR
|
||
1$: CLR (C)+ ;WIPE OUT NEW STUFF
|
||
SOB B,1$
|
||
CLR C ;FOR DIVIDE
|
||
SUB #SICLST,D ;MAKE IT RELATIVE
|
||
DIV #NCLSEB*CLSELN,C ;GET BLOCK NUMBER
|
||
MOV 2(P),B ;RESTORE BYTE POINTER
|
||
MOVB C,(B) ;NEW BLOCK NUMBER
|
||
MOV ITEM1,C ;THE SPHERE WE ARE HACKING
|
||
JSR PC,ITM1PO ;RESTORE ITEM 1
|
||
REST <D,,B>
|
||
BR GCLSTA ;TRY AGAIN
|
||
AGCLS1: JSR PC,ITM1PO ;POP THE ITEM WE PUSHED
|
||
TST (P)+
|
||
CLZ
|
||
RTS PC
|
||
AGCLS2: REST <,B>
|
||
SEZ
|
||
RTS PC
|
||
;GET THE ADDRESS OF A C-LIST ENTRY, ASSUMING THE SPHERE IS IN ITEM 1
|
||
;RETURN REAL ADDRESS IN A AND CLEAR Z, UNLESS YOU FAIL
|
||
AGCLAD: SAVE <B,C>
|
||
MOV ITEM1,C ;ASSUME THE SPHERE IS IN ITEM 1
|
||
JSR PC,AGCLSA ;GO GET THE ADDRESS
|
||
BEQ AGCLA1 ;FAILURE
|
||
MOV ITM1A,A ;GET THE ADDRESS IN THE MAP
|
||
ADD B,A ;MAKE A REAL ADDRESS
|
||
REST <C,B>
|
||
CLZ
|
||
RTS PC
|
||
AGCLA1: REST <C,B>
|
||
SEZ
|
||
RTS PC
|
||
|
||
|
||
;GET A POINTER TO THE NEXT EXISTANT C-LIST ENTRY
|
||
;ON ENTRY, A POINTS TO THE ITEM WITH THE SPHERE
|
||
;D IS THE FIRST C-LIST NUMBER TO CHECK
|
||
;B RETURNS POINTING TO THE C-LIST ENTRY
|
||
;D RETURNS POINTING TO THE C-LIST ENTRY
|
||
;CLEAR Z IF SUCESSFUL, SET OTHERWISE
|
||
GNCLST: CMP #MNCLSE,D ;AT THE LAST ENTRY?
|
||
BNE GNCLS3 ;NOT YET, TRY AGAIN
|
||
RTS PC ;AT END, NOTE THAT Z IS SET
|
||
GNCLS3: MOV D,B ;COPY THE C-LIST NUMBER
|
||
JSR PC,GCLSTA ;TRY TO GET POINTER
|
||
BEQ GNCLS1 ;NO SUCH BLOCK
|
||
ADD A,B ;MAKE A REAL POINTER
|
||
TST (B) ;ANYHTING THERE?
|
||
BEQ GNCLS2 ;NO, TRY NEXT ONE
|
||
RTS PC ;FOUND ONE, NOTE THAT Z IS CLEAR
|
||
GNCLS1: ADD #NCLSEB-1,D ;NEXT BLOCK
|
||
GNCLS2: INC D ;NEXT ENTRY
|
||
BR GNCLST
|
||
;CREATE A C-LIST ENTRY, ITEM OF SPHERE IN C, POSITION OF ENTRY
|
||
;TO BE CREATED IN B (-1 GETS THE FIRST AVAILABLE ENTRY), RETRURNS WITH Z CLEARED
|
||
;NORMALLY, SETS Z IF SLOT ISN'T AVAILABLE, AND SETS C IF NO SLOTS AVAILABLE
|
||
;ON NORMAL RETURN, B CONTAINS C-LIST NO. AND A CONTAINS ADDRESS OF ENTRY RELATIVE TO SPHERE
|
||
CRCLST: BIC #177400,B ;ONLY THE BOTTOM BYTE IS SIGINIFICANT
|
||
CMP #377,B ;IS IT -1
|
||
BNE CRCLS1 ;NO, FIGURE OUT WHICH ONE IT IS
|
||
MOV #MNCLSE-1,B ;START LOOKING AT THE TOP
|
||
CRCLS2: SAVE B ;THE CURRENT C-LIST NO.
|
||
JSR PC,AGCLSA ;GET A C-LIST ENTRY
|
||
BEQ CRCLS3 ;FAILED, BECAUSE NOT AVAILABLE
|
||
MOV C,A ;THE SPHERES ITEM NO.
|
||
JSR PC,ITM1PL ;LOAD IT UP
|
||
ADD B,A ;MAKE THE POINTER TO THE C-LIST ENTRY ABSOLUTE
|
||
TST (A) ;IS IT FREE
|
||
BEQ CRCLS4 ;YES RETURN SUCESSFUL
|
||
REST B
|
||
DEC B ;TRY THE NEXT C-LIST ENTRY
|
||
BEQ CRCLS5 ;NO MORE RETURN WITH CARRY SET
|
||
JSR PC,ITM1PO ;POP THE SPHERE
|
||
BR CRCLS2 ;TRY THE NEXT ONE
|
||
CRCLS1: SAVE B
|
||
JSR PC,AGCLSA ;GET A C-LIST ENTRY
|
||
BEQ CRCLS3 ;FAILED (NOT AVAILABLE)
|
||
MOV C,A ;SPHERES ITEM NO
|
||
JSR PC,ITM1PL ;LOAD UP THE SPHERE
|
||
ADD B,A ;MAKE THE POINTER ABSOLUTE
|
||
TST (A) ;IS TI FREE
|
||
BNE CRCLS6 ;NOPE
|
||
CRCLS4: REST B
|
||
SUB ITM1A,A ;MAKE IT RELATIVE AGAIN
|
||
JSR PC,ITM1PO ;POP THE SPHERE
|
||
CLZ!CLC ;CLEAR EVERYTHING
|
||
RTS PC
|
||
CRCLS6: REST B
|
||
CRCLS5: JSR PC,ITM1PO ;POP THE SHPERE
|
||
CLZ
|
||
SEC
|
||
RTS PC
|
||
CRCLS3: REST B
|
||
SEZ
|
||
RTS PC
|
||
;THIS ROUTINE TAKES A POINTER TO THE FIRST CAPABILITY OF A CIRCULAR
|
||
;LIST IN A AND THE C-LIST NO. OF THAT CAP IN B, AND RETURNS THE
|
||
;ITEM NO. (IN C) AND THE C-LIST NO. (IN D) OF THE C-LIST ENTRY THAT
|
||
;POINTS TO IT. THE C-LIST NO. OF THE ORIG. ENTRY IS IN B,AND THE ORIG.
|
||
;ITEM NO. IN A. RETURNS WITH Z SET IF NO CIRCULAR LIST
|
||
FNBKPT: TST 4(A) ;IS THERE A CIRCULAR LIST
|
||
BNE FNBPT1 ;YES
|
||
MOV ITEM1,C ;FAKE THE CIRCULAR LIST
|
||
MOV B,D ;COPY IT
|
||
RTS PC
|
||
FNBPT1: MOV ITEM1,A ;THE CURRENT ITEM NO.
|
||
SAVE <A,B> ;FOR REFERENCE LATER
|
||
FNBPT2: SAVE <A,B> ;SAVE CURRENT ITEM AND C-LIST
|
||
JSR PC,ITM1PL ;LOAD UP THIS SPHERE
|
||
JSR PC,GCLSTA ;GET ADDRESS OF C-LIST ENTRY
|
||
BUGC EQ ;DID WE SUCCEED
|
||
ADD A,B ;MAKE THE POINTER ABSOLUTE
|
||
MOV 4(B),A ;THE NEXT C-LIST NO.
|
||
MOV 10(B),B ;THE NEXT C-LIST ITEM
|
||
BUGC EQ ;THE ITEM SHOULDN'T BE 0
|
||
JSR PC,ITM1PO ;GET RID OF THIS ITEM
|
||
REST <D,C> ;GET THE OLD VALUES
|
||
CMP A,2(P) ;IS THE POINTER THE SAME AS THE ORIG.
|
||
BNE FNBPT2 ;NOPE FIND THE NEXT ONE
|
||
CMP B,(P) ;IS THE REST OF THE POINTER THE SAME
|
||
BNE FNBPT2 ;NOPE TRY AGAIN
|
||
ADD #4,P ;POP OFF THE ORIG. ITEM AND C-LIST NO.
|
||
CLZ
|
||
RTS PC
|
||
|
||
;PCLOSER ALL PROCESSES IN SPHERE
|
||
SPRRPC: SAVE F
|
||
MOV #RPCLSR,F
|
||
BR SPRKI1
|
||
|
||
RPCLSR: SAVE A
|
||
JSR PC,ITM0PL ;LOAD PROCESS BEING HACKED
|
||
JSR PC,PRSRPC ;PCLOSER IT
|
||
JSR PC,ITM0PO
|
||
REST A
|
||
RTS PC
|
||
|
||
;START SPHERE WITH INDEX IN C
|
||
SPRSTR: SAVE F
|
||
MOV #PSTPDC,F ;DECREMENT STOP COUNT
|
||
BR SPRKI1
|
||
|
||
;STOP SPHERE WITH INDEX IN C
|
||
SPRSTP: SAVE F
|
||
MOV #PSTPIN,F ;ROUTINE FOR EACH PROCESS
|
||
BR SPRKI1
|
||
|
||
;KILL ALL PROCESSES IN SPHERE INDEX IN C
|
||
SPRKIL: SAVE F
|
||
MOV #DLSPRO,F ;DELETE FROM SPHERE
|
||
SPRKI1: JSR PC,SPRPRH ;ALL IN SPHERE
|
||
REST F
|
||
RTS PC
|
||
|
||
DLSPRO: SAVE <B,A>
|
||
JSR PC,PSTPIN ;STOP PROCESS
|
||
JSR PC,ITM0PL ;LOAD PROCESS BEING HACKED
|
||
JSR PC,REMPRS ;REMOVE FROM SPHERE
|
||
JSR PC,ITM0PO
|
||
REST <A,B>
|
||
RTS PC
|
||
|
||
;HACK EACH OF PROCESSES IN SPHERE IN C WITH ROUTINE IN F
|
||
;EXCEPT THE CURRENTLY RUNNING PROCESS
|
||
SPRPRH: SAVE <A,B>
|
||
MOV #-1,A ;FOR THE BOGUS PUSH
|
||
JSR PC,ITM0PL ;CREATE A WORK CELL
|
||
MOV C,A ;THE SPHERE NO.
|
||
JSR PC,ITM1PL ;LOAD THE SPHERE
|
||
MOV SPHPRP(A),B ;GET POINTER TO THE FIRST PROCESS
|
||
JSR PC,ITM1PO ;POP THE SPHERE
|
||
BR SPRPH2 ;CHECK OUT THE FIRST PROCESS
|
||
SPRPH1: JSR PC,(F) ;HACK THE PROCESS
|
||
SPRPH2: MOV B,A ;PROCESS ABOUT TO HACK
|
||
BEQ SPRPH3 ;DONE
|
||
JSR PC,ITM0LD ;LOAD IT
|
||
MOV PSPHCP(A),B ;GET THE NEXT PROCESS
|
||
MOV ITEM0,A ;GET BACK PROCESS ITEM NUMBER
|
||
MOV #-1,ITEM0 ;CLOBBER ITEM0
|
||
CMP A,PRUNNG ;DONT STOP THE CURRENT PROCESS
|
||
BEQ SPRPH2 ;THIS IS IT
|
||
BR SPRPH1 ;YES
|
||
SPRPH3: JSR PC,ITM0PO ;POP THE WORK CELL
|
||
REST <B,A>
|
||
RTS PC
|
||
|
||
;PCLOSER ROUTINE FOR DECREMENTING SPHERE STOP COUNTS
|
||
PCSPST: SAVE <E,C,PRUNNG>
|
||
MOV LCKWD2(B),PRUNNG ;THE ONE NOT TO START (KLUDDDDGGGGE)
|
||
MOV ITEM2,C ;THE SPHERE IS LOADED INTO ITEM2
|
||
JSR PC,SPRSTR ;START ALL THE PROCESSES
|
||
REST <PRUNNG,C,E>
|
||
RTS PC
|
||
;THIS ROUTINE IS THE PC-LOSER ROUTINE FOR RESTARTING PROCESSES IN A SPHERE AND
|
||
;ALL INFERIOR SPHERES
|
||
PCMSST: MOV ITEM2,A ;GET THE SPHERE NO.
|
||
JSR PC,ITM1PL ;LOAD UP THE SPHERE
|
||
SAVE E ;KEEP E FROM BEING CLOBBERED
|
||
CLR E ;SAY WE SHOULD START THE PROCESSES
|
||
JSR PC,STPMS ;START THEM
|
||
REST E ;RESTORE E
|
||
JSR PC,ITM1PO ;POP THE SPHERE
|
||
RTS PC ;RETURN
|
||
|
||
;THIS ROUTINE EXPECTS THAT MS TO BE STOPPED OR STARTED TO BE LOADED IN ITEM1
|
||
;IF E IS < 0 THE SPHERE (AND INFERIORS ARE STOPPED, ELSE STARTED)
|
||
STPMS: JSR F,ACSAV ;SAVE THE AC'S
|
||
SAVE <#-1> ;FLAG THE TOP OF THE STACK
|
||
STPMS8: MOV ITEM1,C ;WHATEVER IS IN ITEM1 IS WHAT WE WANT TO STOP
|
||
TST E ;OR START
|
||
BLT STPMS1 ;STOPPING
|
||
JSR PC,SPRSTR ;STARTING
|
||
BR STPMS2
|
||
STPMS1: JSR PC,SPRSTP ;STOP IT
|
||
STPMS2: CLR D ;D IS THE CURRENT C-LIST ENTRY NUMBER
|
||
STPMS3: MOV ITM1A,A ;POINT TO THE CURRENT SPHERE
|
||
STPMS9: JSR PC,GNMSCP ;GET NEXT MS CAP
|
||
BEQ STPMS4 ;NO ONE HOME
|
||
SAVE <D> ;SAVE THE CONTINUATION POINT
|
||
MOV 2(B),A ;GET THE INDEX OF THE SPHERE POINTED TO
|
||
JSR PC,ITM1LD ;LOAD IT UP
|
||
BR STPMS8 ;GO STOP/START IT AND LOOK AT ITS C-LIST
|
||
STPMS4: REST D ;TRY TO POP TO SUPERIOR SPHERE
|
||
BLT STPMS6 ;GOT THE FLAG
|
||
MOV SMSSPT(A),A ;GET THE SUPERIOR
|
||
JSR PC,ITM1LD ;AND MAKE IT CURRENT
|
||
INC D ;NEXT C-LIST ENTRY
|
||
BR STPMS9 ;CONTINUE THROUGH ITS C-LIST
|
||
STPMS6: JMP ACRET
|
||
|
||
;GET NEXT MSCAP
|
||
;A POINTS TO THE SPHERE IN THE MAP
|
||
;D POINTS TO THE FIRST C-LIST ENTRY TO CHECK
|
||
;B GETS THE POINTER TO THE ENTRY
|
||
;D GETS THE NUMBER OF THE ENTRY
|
||
;SET Z ON FAILURE
|
||
GNMSC2: INC D ;LOOP TO NEXT ENTRY
|
||
GNMSCP: JSR PC,GNCLST ;GET THE NEXT C-LIST ENTRY
|
||
BEQ GNMSC1 ;NONE
|
||
CMPB #.MSCAP,(B) ;IS IT A MSCAP?
|
||
BNE GNMSC2 ;NO, TRY NEXT ONE
|
||
CLZ ;Z HAD BEEN SET, BUT WE WON SO CLEAR IT
|
||
GNMSC1: RTS PC ;RETRUN WITH Z SET OR CLEARED
|
||
|
||
;TAKES POINTER TO UPT IN B PCLOSERS EVERYONE NEAR THAT PAGE
|
||
PAGPCL: CMP #-1,B ;IS IT REALLY NULL?
|
||
BUGC EQ
|
||
SAVE <A,B>
|
||
MOV #-1,A ;BOGUS PUSH
|
||
JSR PC,ITM2PL ;LOAD UP NOTHING
|
||
PAGPLP: JSR PC,UPTLD ;LOAD A UPT
|
||
MOV ITEM2,A ;THE SPHERE TO PC-LOSER
|
||
BMI PAGL1 ;FUPT
|
||
JSR PC,SPRPCL ;PC-LOSER THAT SPHERE
|
||
PAGL2: MOV UPTGIP(B),B ;GET NEXT UPT
|
||
BEQ PAGDON ;NO MORE
|
||
CMP B,(P) ;IS IT THE SAME AS THE FIRST
|
||
BNE PAGPLP ;NO, PC-LOSER IT
|
||
PAGDON: REST <B,A>
|
||
JSR PC,ITM2PO ;POP THE SPHERE
|
||
PAGL3: RTS PC
|
||
PAGL1: MOV FUPTPR(B),A ;THE PROCESS THIS BELONGS TO
|
||
BLE PAGL2 ;NO ONE TRY NEXT UPT
|
||
JSR PC,PRSPCL ;PCLOSER PROCESS
|
||
BR PAGL2 ;TRY NEXT UPT
|
||
|
||
;PCLOSER SPHERE ITEM IN A
|
||
SPRPCL: SAVE A
|
||
MOV #-1,A
|
||
JSR PC,ITM0PL ;FOR A BOGUS PUSH
|
||
MOV (P),A ;GET BACK POINTER TO SPHERE
|
||
JSR PC,ITM1PL ;LOAD IT UP
|
||
MOV SPHPRP(A),A ;POINTER TO THE CURRENT PROCESS
|
||
JSR PC,ITM1PO ;POP SPHERE
|
||
TST A ;ARE THERE ANY PROCESSES
|
||
BEQ SPRPC2
|
||
SPRPC1: JSR PC,PRSPCL ;PCLOSER PROCESS
|
||
JSR PC,ITM0LD ;LOAD THE CURRENT PROCESS
|
||
MOV PSPHCP(A),A ;POINTER TO NEXT PROCESS
|
||
BNE SPRPC1 ;THERE IS ANOTHER
|
||
SPRPC2: JSR PC,ITM0PO ;POP THE BOGUS PUSH
|
||
REST A
|
||
RTS PC
|
||
|
||
;PCLOSER PROCESS ITEM IN A
|
||
PRSPCL: JSR F,ACSAV
|
||
JSR PC,ITM0PL ;LOAD THE PROCESS
|
||
TST PSTOPC(A) ;IS IT STOPPED ALREADY
|
||
BNE PRSPC1 ;YES
|
||
CMP ITEM0,PRUNNG ;IS THIS THE RUNNING PROCESS?
|
||
BEQ PRSPC3 ;DON'T UNLOCK SWITCHES, BUT SET FLAG
|
||
TST PSPC(A) ;IS IT IN SYSTEM
|
||
BEQ PRSPC1 ;NO
|
||
PRSPC3: BIS #PPCLSR,PFLAGS(A) ;SET BIT TO PCLOSER HIM
|
||
ACRTP0:
|
||
PRSPC1: JSR PC,ITM0PO ;POP PROCESS
|
||
ACRET: JSR F,ACRES
|
||
PRSPC2: RTS PC
|
||
|
||
;CHECK IF OUR OWN PCLOSER BIT IS SET AND PCLOSER IF IT IS
|
||
PCLCHK: SAVE A
|
||
MOV ITM0A,A ;ASSUME WE ARE LOADED IN ITEM0
|
||
BIT #PPCLSR,PFLAGS(A) ;IS IT ON?
|
||
BEQ PCLCH1 ;NO, JUST RETRUN
|
||
JSR PC,SFLUSH ;FLUSHING SHOULD CAUSE PCLOSERING TO HAPPEN
|
||
JSR PC,RUNME ;ACTUALLY, HAPPENS ON THE RUNME
|
||
BPT ;CAN'T GET HERE FROM THERE!
|
||
PCLCH1: REST A
|
||
RTS PC
|
||
|
||
PCLCLR: SAVE A ;WANT TO CLEAR OUR OWN PCLOSER BIT
|
||
MOV ITM0A,A ;ASSUME WE ARE LOADED IN 0
|
||
BIC #PPCLSR,PFLAGS(A) ;CLEAR IT
|
||
BR PCLCH1 ;AND RETURN
|
||
|
||
PCLSET: SAVE A ;WANT TO SET OUR OWN PCLOSER BIT
|
||
MOV ITM0A,A ;ASSUME WE ARE LOADED IN 0
|
||
BIC #PPCLDF,PFLAGS(A) ;CLEAR OUR DEFER BIT
|
||
BIS #PPCLSR,PFLAGS(A) ;SET IT
|
||
BR PCLCH1 ;AND RETURN
|
||
|
||
PCLDEF: SAVE A
|
||
MOV ITM0A,A
|
||
BIS #PPCLDF,PFLAGS(A)
|
||
BR PCLCH1
|
||
|
||
;PUSH ITEM2 AND THEN FALL INTO LOAD A UPT
|
||
;GIP IS IN B
|
||
;RETURN CORE ADDRESS IN B
|
||
|
||
UPTPLD: SAVE <A>
|
||
MOV #-1,A ;MAKE IT NXM
|
||
JSR PC,ITM2PL
|
||
REST <A>
|
||
UPTLD: TST B
|
||
BUGC EQ
|
||
BIT #GIPSPR,B ;THIS BIT SET IN SPHERE UPT
|
||
BNE UPTL.1
|
||
BIC #GIPBIT,B ;GET FUPT ADDRESS
|
||
RTS PC
|
||
UPTL.1: SAVE <A>
|
||
MOV B,A
|
||
BIC #GIPITM,A ;GET THE ITEM NUMBER
|
||
ASH #2,A ;CONVERT TO ITEM NUMBER
|
||
JSR PC,ITM2LD ;LOAD THE SPHERE OVER THIS ITEM
|
||
BIC #GIPUPT,B ;GET THE UPT NUMBER
|
||
SWAB B
|
||
ASH #-2,B ;GET THE UPT NO.
|
||
MUL #UPTLEN,B
|
||
ADD A,B
|
||
ADD #SUPTS,B
|
||
REST <A>
|
||
RTS PC
|
||
.SBTTL CLOCK AND PIRQ ROUTINES
|
||
;ENTERED BY AN INTERUPT FROM EITHER THE LINE CLOCK OR THE PROGRAMABLE
|
||
;CLOCK. HOPEFULLY, ONLY ONE OF THESE WILL BE ENABLED!
|
||
LCBRK:
|
||
PCBRK: JSR F,ACSAV ;SAVE THE ACS
|
||
JSR PC,SWCHEK
|
||
INC TIME ;INCREASE TIME-SINCE-SYSTEM UP
|
||
BNE 1$ ;OVERFLOW?
|
||
INC TIME+2 ;YUP
|
||
1$: DEC HSECNT ;TIME TO INC HSECS?
|
||
BGT 2$
|
||
INC HSECS
|
||
MOV #30.,HSECNT
|
||
DEC SECNT ;TIEM TO UPDATE SECONDS?
|
||
BGT 2$ ;NOPE
|
||
MOV #2,SECNT ;2 HALF SECS IN A SEC
|
||
JSR PC,DATEIN ;GO UPDATE SECS ETC.
|
||
2$:
|
||
BIS #100000,DH0SCR ;KLUDGE FOR DH11
|
||
.IIF NZ NTKDIS,JSR PC,TKDCLK ;KEEP DISPLAYS GOING
|
||
BIT #1,TIME ;DO THIS ONLY EVERY OTHER TICK
|
||
BNE 3$
|
||
BIS #TTYPIR,PIRQ ;CAUSE TTY'S TO GET PROCESED
|
||
3$: INC TUSED ;ONE MORE TICK FOR THIS USER
|
||
DEC STIMER ;MAINTAIN TIMERS
|
||
DEC LTIMER
|
||
DEC JTMUUP ;TIME TO UPDATE THE JTMUS?
|
||
BNE 4$ ;NOT YET
|
||
JSR PC,JTMUU ;GO UPDATE THEM
|
||
4$: DEC QUANT ;HAS THE CURRENT USER OVERSTAYED HIS WELCOME?
|
||
BGT CLKRET ;NO, RETURN TO MAIN PROGRAM
|
||
BIS #CLKPIR,PIRQ ;CAUSE THE STOP USER ROUTINE TO RUN
|
||
CLKRET: JSR F,ACRES ;RESTORE THE ACS
|
||
CHECKP
|
||
RTT
|
||
|
||
SWCHEK: MOV CSWR,SVCSR ;IS SWITCH REGISTER ZERO?
|
||
BNE 1$
|
||
MOV PC,LOOKSW ;YES, SAY WE SHOULD LOOK AT SWITCHES
|
||
1$: TST LOOKSW ;SHOULD WE LOOK AT SWITCHES?
|
||
BEQ SWCHE1 ;NOPE
|
||
BIT #100000,CSWR ;BPT SWITCH?
|
||
BUGC NE
|
||
BIT #1,CSWR ;INGNORE SWITCHES SWITCH
|
||
BEQ SWCHE1
|
||
CLR LOOKSW
|
||
SWCHE1: TST TIMCHK ;ARE WE RECORDING?
|
||
BEQ SWCHE2 ;NOPE
|
||
MOV 2+12.+2(P),A ;SWCHEK RETURN+PUSHED REGS+PC GETS YOU TO PS
|
||
BIC #177437,A ;GET LEVEL
|
||
ASH #-4,A
|
||
INC LEVTAB(A) ;ONE MORE TIME!
|
||
BIT #20000,CSWR ;STOP?
|
||
BNE SWCHE3 ;NOPE
|
||
CLR TIMCHK ;YES
|
||
RTS PC
|
||
SWCHE2: BIT #20000,CSWR ;SHOULD WE START?
|
||
BEQ SWCHE3 ;STILL ZERO
|
||
MOV #LEVTAB,A ;TABLE
|
||
MOV #8.,B ;LEVELS
|
||
1$: CLR (A)+
|
||
SOB B,1$
|
||
MOV PC,TIMCHK
|
||
SWCHE3: RTS PC
|
||
.IFNZ NTKDIS
|
||
TKDCLK: MOV TKDPDL,A ;THE PDL ITEM
|
||
JSR PC,ITM2PL ;LOAD IT UP
|
||
MOV A,F ;SAVE POINTER INTO IT
|
||
ADD #20,F ;MAKE IT POINT TO PDLS
|
||
CLR A ;THE DISPLAY NUMBER
|
||
CLR D ;THE DISPLAY*2
|
||
MOV #8.,C ;THERE ARE 8 DISPLAYS
|
||
TKDCL1: MOV TKDRUN(A),B ;IF RUNNING, WHICH DISPLAY I AM
|
||
BLT TKDCL2 ;NOT RUNNING
|
||
MOV B,D
|
||
SWAB B
|
||
MOV B,NGCSR ;CHECK THAT DISPLAY
|
||
BIT #TKRUN,NGCSR ;STILL RUNNING?
|
||
BNE TKDCL2 ;YUP
|
||
ASL D
|
||
BIC #17,F
|
||
ADD D,F
|
||
MOV TKDPDP(D),(F) ;RESTORE THE PDL POINTER
|
||
BIS #TKGO,B ;BIS DOESN'T WORK ON NGCSR
|
||
MOV B,NGCSR ;RESTART DISPLAY
|
||
TKDCL2: TST (A)+
|
||
SOB C,TKDCL1 ;DO THEM ALL
|
||
JSR PC,ITM2PO
|
||
RTS PC
|
||
.ENDC
|
||
|
||
DATEIN: MOV MONTH,A ;THE MONTH
|
||
MOVB MONS-1(A),DAYL ;SET THE LIMIT ON DAYS FOR THIS MONTH
|
||
MOV #SECOND,A ;POINT TO TABLES
|
||
MOV #SECONL,B ;THE LIMITS
|
||
MOV #RESETT,C ;VALUES TO RESET TO
|
||
DATEI1: INC (A) ;INCREMENT THIS
|
||
CMP (A),(B)+ ;HAS THIS OVERFLOWED?
|
||
BLT DATEI2 ;NO, DONE
|
||
MOV (C)+,(A)+ ;BACK TO BEGINNING OF MIN, HOUR, DAY, MON OR YEAR
|
||
BR DATEI1 ;GO DO NEXT
|
||
DATEI2: RTS PC
|
||
|
||
;ROUTINE ON LEVEL TTYL (2) TO PROCESS TVS AND TTYS
|
||
|
||
TTYBRK: REST A ;SAVED BY PIRBRK
|
||
JSR F,ACSAV
|
||
.IIF NZ NTVS,JSR PC,TVTICK ;PROCESS TV CHARS
|
||
JSR PC,CLKTTY ;PROCESS CHARACTERS
|
||
JSR F,ACRES
|
||
RTT
|
||
|
||
;THE GET/SET TIME CALL
|
||
ETIME: JSR PC,RETNSW ;GET POINTER WORD FROM STACK
|
||
MOV #6,B ;FOR THE SIX VARIABLES
|
||
1$: MFPD (A) ;GET WORD FROM USER
|
||
MTPD (A)+ ;MAKE SURE IT CAN BE PUT BACK
|
||
SOB B,1$
|
||
SUB #6*2,A ;BACK TO BEGINING
|
||
MOV #6,B
|
||
MOV #SECOND,C ;TABLE OF TIMES
|
||
SPL 7 ;AVOID TIMING ERROR
|
||
ETIME1: MFPD (A) ;GET WORD FROM USER
|
||
BGE ETIME2 ;HE DOESN'T WANT TO SET THIS WORD
|
||
BIC #100000,(P) ;CLEAR FLAG
|
||
MOV (P),(C) ;SET THIS ONE
|
||
ETIME2: MOV (C)+,(P) ;GET VALUE TO RETURN
|
||
MTPD (A)+ ;RETURN IT
|
||
SOB B,ETIME1
|
||
SPL 0
|
||
JMP ERETCZ
|
||
|
||
;COMPUTE THE DATE AND TIME WORDS FOR A FILE
|
||
CMDATE: JSR F,ACSAV
|
||
MOV #YEAR,C ;POINTER TO UPDATED DATE+TIME
|
||
TST (C)+ ;HAS YEAR BEEN SET?
|
||
BLT CMDAT2 ;NO, LEAVE FILE DATES -1
|
||
MOV #TSHIFT,D ;TABLE OF SHIFT COUNTS
|
||
MOV #5,E ;NUMBER OF PARTS
|
||
CLR B ;CLEAR LOW ORDER PATE OF 2 WORDS
|
||
SAVE PS
|
||
SPL 7
|
||
CMDAT1: BIS -(C),B ;SET THIS PART IN
|
||
ASHC (D)+,A ;SHIFT UP
|
||
SOB E,CMDAT1
|
||
MOV -(C),E ;SECONDS
|
||
ASR E
|
||
BIS E,B ;SECONDS GET DIVIDED BY 2
|
||
REST PS
|
||
MOV A,FDATE ;THE DATE
|
||
MOV B,FTIME ;AND TIME
|
||
CMDAT2: JMP ACRET
|
||
|
||
;THIS IS ENTERED BY THE PROGRAM INTERUPT REQUEST
|
||
;CURRENTLY IT IS ONLY USED FOR THE "CLOCK", BUT ITS DISPATCH
|
||
;TABLE COULD ACCOMADATE USES FOR OTHER LEVELS
|
||
PIRBRK: SAVE A ;SAVE A REGISTER
|
||
MOV PIRQ,A ;GET THE INTERUPT LEVEL
|
||
BIC #177761,A ;USE AS AN INDEX TO DISPATCH
|
||
BIC PIRBIT(A),PIRQ ;CLEAR THE RIGHT BIT
|
||
ASH #4,A ;GET PRIORITY INTO RIGHT BITS
|
||
MOVB A,PS ;SET PRIORITY OF PROCESSOR TO PRIORITY
|
||
;LEVEL RESPONSABLE FOR THIS INTERUPT
|
||
ASH #-4,A ;GET BACK FOR DISPATCHING
|
||
JMP @PIRDIS(A)
|
||
PIRLOS: BPT ;UNIMPLEMENTED LEVELS COME HERE
|
||
REST A
|
||
CHECKP
|
||
RTT
|
||
|
||
.SBTTL SCHEDULING ROUTINES
|
||
;THE SYSTEM'S MAIN LOOP
|
||
;ENTERED AT SCHED, NEVER EXITED
|
||
SCHED: JSR PC,CHKACT ;CHECK FOR PROCESSES TO BE ACTIVATED
|
||
SCHED4: MOV WINQ,A ;ANYBODY ON THE WINNERS QUEUE?
|
||
BEQ SCHED1 ;NOPE, TRY FOR THE LOSERS
|
||
MOV WQUANT,QUANT ;GIVE HIM A WINNERS QUANTUM
|
||
MOV #ACTQ,B ;DON'T LET HIM COME BACK HERE
|
||
JSR PC,TQUEUE ;MOVE HIM TO ACTIVE
|
||
JSR PC,STPROC ;START HIM UP
|
||
BR SCHED ;TRY FOR MORE WINNERS
|
||
SCHED1: MOV #DORQ,A ;SEE IF ANY OF TH EDORMANT GUYS WANT TO WAKE UP
|
||
JSR PC,CHKQ
|
||
TST LTIMER ;TIME TO CHECK THE SLOW GUYS?
|
||
BLT SCHED3 ;YUP
|
||
TST ACTQ ;ANYONE ACTIVE?
|
||
BEQ SCHED3 ;NO, GO CHECK THE SLOW GUYS ANYWAY
|
||
JSR PC,RUNBPS ;RUN THE BEST PROCESS
|
||
BR SCHED
|
||
SCHED3: MOV #LTIMEL,LTIMER ;RESET THE TIMER
|
||
MOV #IACTQ,A ;THE INACTIVE GUYS
|
||
JSR PC,CHKQ ;TRY TO PUT THEM ON THE RUN QUEUE OR ACTQ
|
||
SCHED5: MOV #RUNQ,A ;GUYS ON THE RUN QUE
|
||
JSR PC,GLQTIM ;GET THE ONE ON FOR THE LARGEST TIME
|
||
CMP #5*2,C ;IS IT > 5 SECS?
|
||
BGT SCHED7 ;NO, HE STAYS THERE
|
||
MOV #ACTQ,B ;HE GETS MOVED TO THE ACTIVE QUEUE
|
||
JSR PC,PRSAOD ;ACTIVEATE HIM
|
||
JSR PC,TQUEUE ;MOVE HIM
|
||
BR SCHED5 ;TRY FOR THE NEXT GUY WHO'S GOOD
|
||
|
||
SCHED7: TST WINQ ;WINNERS?
|
||
BNE SCHED ;GET THEM
|
||
TST ACTQ ;MODERATE WINNERS?
|
||
BNE SCHED ;THEM TOO
|
||
WAIT ;TWIDDLE THUMBS
|
||
BR SCHED ;AND TRY AGAIN
|
||
;UPDATE JTMUS ON ALL QUEUES
|
||
JTMUU: MOV #JTMUUT,JTMUUP ;RESTORE TIME TILL NEXT UPDATE
|
||
MOV #FIRSTQ,A ;BEGGINING OF THE QUEUE POINTERS
|
||
MOV #NQS,B ;NUMBER OF QUEUES THAT EXIST
|
||
JTMUU1: MOV (A),C ;POINTER TO BEGGINING OF QUEUE
|
||
BEQ JTMUU2 ;NOBODY THERE!
|
||
JTMUU4: MOV PRTJTM(C),F ;GET THE JTMU
|
||
BEQ JTMUU3 ;IT'S ALREADY ZERO, FORGET IT
|
||
CLR E ;FOR THE DIVIDE
|
||
DIV #JTMUDC,E ;FIND OUT HOW MUCH TO DECAY BY
|
||
INC E ;MAKE SURE IT EVENTUALLY GETS TO ZERO
|
||
SUB E,PRTJTM(C) ;DECAY IT
|
||
JTMUU3: MOV (C),C ;GO DOWN THE LINK
|
||
BNE JTMUU4 ;MORE ON THIS QUEUE
|
||
JTMUU2: ADD #QLEN,A ;GO TO NEXT QUEUE
|
||
SOB B,JTMUU1 ;GO THROUGH ALL QUEUES
|
||
RTS PC
|
||
|
||
;RETURN THE LENGTH OF TIME THE PROCESS TABLE ENTRY POINTED
|
||
;TO BY A HAS BEEN ON IT'S CURRENT QUEUE
|
||
GQTIME: MOV HSECS,C ;CURRENT TIME
|
||
SUB PRTTIM(A),C ;TIME ON QUEUE
|
||
RTS PC
|
||
|
||
;GET THE PROCESS THAT HAS BEEN ON THE Q IN A THE LONGEST TIME
|
||
;AND RETURN IT IN A, RETURN TIME ON Q IN C
|
||
;A AND C ARE ZERO IF NOT PROCESS ON Q
|
||
GLQTIM: JSR F,ACSAV
|
||
CLR D ;LONGEST TIME WE'VE FOUND
|
||
MOV #GLQTM,F ;"FLAG"
|
||
BR GQTIM
|
||
|
||
;SIMILAR TO GLQTIM, BUT FOR SHORTEST TIME
|
||
;C IS -1 IF NONE FOUN
|
||
GSQTIM: JSR F,ACSAV
|
||
MOV #-1,D ;SHORTEST TIME FOUND
|
||
MOV #GSQTM,F ;"FLAG"
|
||
GQTIM: CLR (P) ;SAVED A FOR RETURN
|
||
GQTIM1: MOV (A),A ;NEXT ONE
|
||
BEQ GQTIM2 ;NO MORE
|
||
JSR PC,GQTIME ;GET AMOUNT OF TIME ON QUEUE
|
||
JSR PC,(F) ;DO COMPARE
|
||
BHI GQTIM1 ;NOT A RECORD SETTER
|
||
MOV C,D ;NEW RECORD
|
||
MOV A,(P) ;BY NEW PROCESS
|
||
BR GQTIM1
|
||
GQTIM2: MOV D,4(P) ;SET C FOR RETURN
|
||
JMP ACRET
|
||
GLQTM: CMP D,C
|
||
RTS PC
|
||
GSQTM: CMP C,D
|
||
RTS PC
|
||
;CHECK RUNNABILITY OF A PROCESS
|
||
;PROCESS TABLE ENTRY IN A
|
||
;MIGHT CLOBBER ALL REGISTERS
|
||
CHKPRS: MOV PRTPPT(A),A ;GET THE ITEM
|
||
JSR PC,ITM0LD
|
||
CHKPRL: SAVE PSPC(A) ;GET THE PLACE TO CONTINUE IT AT
|
||
BUGC EQ ;MAKE SURE IT IS NON-ZERO
|
||
MOV A,B
|
||
MOV PSPHRP(A),A ;GET THE SPHERE
|
||
JSR PC,ITM1LD
|
||
MOV B,A ;RESTORE ITEM ADDRESS
|
||
JSR PC,ITM2RS ;RETORE THE ITEM2 STACK
|
||
MOV B,A
|
||
ADD #PSREGS+14,A ;POINTER TO REGISTERS
|
||
.IRPC X,<FEDCBA>
|
||
MOV -(A),X
|
||
.ENDM
|
||
RTS PC
|
||
|
||
;CHECK RUNNABLITY OF PROCESSES ON QUEUE IN A
|
||
;MAY CLOBBER ALL REGISTERS
|
||
CHKQ: SAVE (A)
|
||
CHKQ1: MOV (P),A ;GET THE NEXT IN LINE TO CHECK
|
||
BEQ CHKQ2 ;NO MORE
|
||
MOV (A),(P) ;LINK THROUGH FOR NEXT TIME
|
||
JSR PC,CHKPRS ;CHECK IT
|
||
BR CHKQ1
|
||
CHKQ2: REST A
|
||
RTS PC
|
||
|
||
;SET UP THE CURRENT PROCESS TO BE WOKEN UP BY THE BLOCK
|
||
;POINTED TO BY B
|
||
ACTSET: SAVE A
|
||
MOV PRUNNG,(B)+ ;STORE PROCESS ITEM
|
||
MOV ITM0A,A ;ASSUME CURRENT PROCESS IN ITEM 0
|
||
MOV PRSID1(A),(B)+ ;ID WORD 1
|
||
MOV PRSID2(A),(B)+ ;ID WORD 2
|
||
REST A
|
||
GOACT1: RTS PC
|
||
|
||
;TRY TO GOBBLE AN ACTIVATE BLOCK FOR THE PROCESS DESCRIBED
|
||
;IN THE 3 WORDS B POINTS TO
|
||
GOACT: TST (B) ;ANYTHING TO ACTIVATE?
|
||
BEQ GOACT1 ;NOPE
|
||
JSR F,ACSAV
|
||
MOV B,F ;COPY BLOCK POINTER
|
||
MOV (F),A ;ITEM
|
||
CLR (F)+ ;ONLY COME THIS WAY ONCE
|
||
MOV (F)+,B ;ID WORD 1
|
||
MOV (F)+,C ;ID WORD 2
|
||
JSR PC,PRSWAK ;GO GOBBLE BLOCK
|
||
JMP ACRET ;AND RETURN
|
||
|
||
|
||
;PUT PROCESS ON THE WAKE-UP QUICK LIST
|
||
;CALL WITH ITEM IN A, PROCESS ID WORD 1 IN B, PROCESS ID WORD 2 IN C
|
||
;IF CAN'T PUT IT ON LIST, JUST RETURNS....
|
||
PRSWAK: SAVE <PS,D>
|
||
SPL 7 ;DON'T INTERUPT ME
|
||
MOV ACTFRE,D ;GET A FREE BLOCK
|
||
BEQ PRSWA1 ;THERE ARE NONE
|
||
MOV (D),ACTFRE ;SPLICE IT OUT
|
||
MOV A,ACTITM(D) ;THE ITEM
|
||
MOV B,ACTPI1(D) ;PROCESS ID WORD 1
|
||
MOV C,ACTPI2(D) ;PROCESS ID WORD 2
|
||
MOV ACTLST,ACTLNK(D) ;LINK TH ENEW NODE
|
||
MOV D,ACTLST ;TO THE FRONT OF THE LIST
|
||
PRSWA1: REST <D,PS> ;RESTORE THE INT LEVEL AND D
|
||
RTS PC
|
||
|
||
;CHECK THE RUNABILITY OF ALL PROCESSES ON THE ACTLST
|
||
CHKACT: MOV PC,ACTCHK
|
||
SPL 7 ;SO THE LIST DOESN'T CHANGE
|
||
MOV ACTLST,E ;GET THE FIRST GUY
|
||
BEQ CHKAC1 ;NOBODY HOME
|
||
MOV (E),ACTLST ;SPLICE HIM OUT
|
||
SPL 0 ;OK NOW
|
||
MOV ACTITM(E),A ;THE ITEM
|
||
JSR PC,ITM0LD ;LOAD HIM UP
|
||
CMPB #ITACCD,ITM0DR ;IS THIS STILL A GOOD ITEM?
|
||
BNE CHKAC2 ;NOPE, FORGET THIS LOSER
|
||
CMP #ITPROC,(A) ;IS THIS THING I LOADED A PROCESS?
|
||
BNE CHKAC2 ;NO, CAN'T BE WHAT I WANT
|
||
CMP ACTPI2(E),PRSID2(A) ;DO THE IDS MATCH?
|
||
BNE CHKAC2 ;NOPE
|
||
BIT #RUNQB!STOPQB!WINQB!ACTQB,PQBIT(A) ;IS HE RUNNING OR STOPPED?
|
||
BNE CHKAC2 ;YUP
|
||
SAVE E
|
||
JSR PC,CHKPRL ;GO CHECK HIM OUT
|
||
REST E
|
||
CHKAC2: SPL 7
|
||
MOV ACTFRE,(E)
|
||
MOV E,ACTFRE ;PUT IT ON THE FREE LIST
|
||
BR CHKACT ;AND TRY AGAIN
|
||
CHKAC1: SPL 0
|
||
CLR ACTCHK
|
||
RTS PC
|
||
|
||
;RUN THE BEST PROCESS ON THE RUN QUEUE
|
||
;CLOBBERS ALL REGISTERS
|
||
RUNBPS: MOV ACTQ,A ;START OF GUYS TO RUN
|
||
BNE RUNBP1 ;SOME THERE FIND HIM
|
||
WAIT ;TWIDDLE YOUR THUMBS
|
||
RTS PC ;I GIVE UP!
|
||
RUNBP1: SAVE <#-1,#77777,#-1,#-1,#77777,A>
|
||
RUNBP2: MOV PRTUPT(A),B ;WHO IS THIS GUY'S USER?
|
||
CMP 6(P),B ;SAME GUY WHO IS ALREADY BEST?
|
||
BEQ RUNBP3 ;YES, GO SEE IF THIS PROCESS IS BETTER
|
||
MOV PRTPRI(B),E ;GET THE PRIORITY MULITPLE FOR THIS GUY
|
||
BIC #177760,E ;MASK IT TO 4 BITS
|
||
MUL PRTJTM(B),E ;GET THE NET PRIOTIRTY
|
||
CMP E,10(P) ;HIGH PART > THAN OLD HIGH PART?
|
||
BLO RUNBP4 ;NO, THIS USER IS BETTER!
|
||
BHI RUNBP6 ;YES, THIS USER NOT AS GOOD
|
||
CMP F,12(P) ;HIGH ORDER EQUAL, TRY LOW
|
||
BHIS RUNBP6 ;SAME OR WORSE
|
||
RUNBP4: MOV B,6(P) ;THIS IS THE NEW BEST USER
|
||
MOV E,10(P) ;AND HERE IS HIS PRIORITY
|
||
MOV F,12(P)
|
||
MOV PRTPRI(A),E ;NOW COMPUTE PRIORITY FOR THIS PROCESS
|
||
BIC #177760,E
|
||
MUL PRTJTM(A),E
|
||
RUNBP5: MOV A,(P) ;THIS IS NOW THE BEST PROCESS
|
||
MOV E,2(P) ;AND THIS IS IT'S PRIORITY
|
||
MOV F,4(P)
|
||
RUNBP6: MOV (A),A ;NEXT ONE ON THE QUEUE
|
||
BNE RUNBP2 ;GO SEE IF HE IS BETTER
|
||
REST A ;THIS ONE IS BEST
|
||
ADD #12,P ;FLUSH THE CRAP OFF THE STACK
|
||
MOV PQUANT,QUANT ;HOW LONG TO RUN HIM FOR
|
||
JMP STPROC ;GO TO IT (WILL RETURN TO CALLER OF RUNBPR)
|
||
RUNBP3: MOV PRTPRI(A),E ;SAME USER, IS THIS PROCESS BETTER?
|
||
BIC #177760,E
|
||
MUL PRTJTM(A),E
|
||
CMP E,2(P) ;IS THE HIGH PART BETTER?
|
||
BLO RUNBP5 ;YUP, HE'S NOW BEST
|
||
BHI RUNBP6 ;NOPE, OLD GUY IS BEST
|
||
CMP F,4(P) ;SAME HIGH PARTS, WHAT ABOUT LOW?
|
||
BHIS RUNBP6 ;OLD GUY BEST
|
||
BR RUNBP5 ;NEW GUY BEST
|
||
.SBTTL LOCK SWITCH ROUTINES
|
||
;GET A LOCKED SWITCH BLOCK AND STUFF THE TYPE AND ITEM INTO IT
|
||
;AND LINK IT INTO THE CURRENT PROCESS'S LOCKED LIST
|
||
;CALL WITH TYPE IN A, ITEM IN B
|
||
;PUTS ADDRESS OF BLOCK INTO A, CLOBBERS B
|
||
LOCKSW: TST LCKFRE ;ARE THERE ANY FREE LOCKS?
|
||
BNE LOCKS1 ;YES, GO GOBBLE
|
||
LOCKS3: BPT ;WE JUST RAN OUT OF LOCK BLOCKS!!!
|
||
;NO GARENTEES IF YOU PROCEED FROM HERE, BUT IT WILL TRY
|
||
JSR PC,SFLUSH ;WAIT A WHILE
|
||
TST LCKFRE ;TRY AGAIN
|
||
BNE LOCKS3 ;NONE YET
|
||
JSR PC,RUNME ;HOPEFULLY, WE CAN GET ONE NOW
|
||
BR LOCKSW ;TRY AGAIN
|
||
LOCKS1: SAVE <A,B>
|
||
MOV LCKFRE,A ;GET THE FREE LOCK BLOCK
|
||
MOV (A),LCKFRE ;SPLICE IT OUT
|
||
REST <LCKTIT(A),LCKDSP(A)> ;POP THE THING INTO THE TYPE AND ITEM
|
||
MOV ITM0A,B ;ADDRESS OF THE PROCESS
|
||
MOV PLCKSL(B),(A) ;PUT IT INTO LIST FOR THIS PROCESS
|
||
MOV A,PLCKSL(B)
|
||
MOV #-1,LCKWD1(A) ;LOCK NOT REALLY USED YET
|
||
CLR LCKWD2(A)
|
||
RTS PC
|
||
|
||
;CLEAR THE LOCKED SWITCH LIST
|
||
LSWCLR: SAVE A
|
||
MOV ITM0A,A
|
||
LSWCL2: TST PLCKSL(A) ;ANY LOCKED
|
||
BEQ LSWCL1 ;NOPE, ALL POPED
|
||
JSR PC,LSWPOP ;FLUSH ONE
|
||
BR LSWCL2 ;TRY AGAIN
|
||
LSWCL1: REST A
|
||
RTS PC
|
||
;LOCK A PARTICULAR SWITCH
|
||
;A HAS THE ADDRESS OF THE SWITCH, OR THE OFFSET INTO THE SPHERE
|
||
;B HAS THE BIT(S) WHICH ARE TO BE LOCKED
|
||
;C HAS THE ITEM NO THAT THE SWITCH IS IN (OR 0 IF ABSOLUTE)
|
||
LCKASW: TST INITSW ;NO SWITCHES LOCKED IN THE INIT CODE
|
||
BNE LOCKA5
|
||
SAVE <E,D,A,B>
|
||
MOV A,E ;COPY THE OFFSET
|
||
MOV #LSPONF,A ;THE TYPE OF LOCK
|
||
MOV C,B ;THE ITEM NO. OF THE SPHERE
|
||
JSR PC,LOCKSW ;GET A LOCK
|
||
REST B
|
||
MOV A,D ;SAVE POINTER TO THE LOCK
|
||
LOCKA2: MOV C,A ;THE SPHERE NO. THAT THE SWITCH IS IN
|
||
BEQ 1$ ;NO ITEM
|
||
JSR PC,ITM1PL ;LOAD IT UP
|
||
1$: ADD E,A ;MAKE A POINT TO THE SWITCH
|
||
BIT B,(A) ;IS THE LOCK UNLOCKED?
|
||
BEQ LOCKA1 ;YES
|
||
LOCKA3: TST C ;ANY ITEM PUSHES
|
||
BEQ 1$ ;NOPE
|
||
JSR PC,ITM1PO ;POP THE SPHERE
|
||
1$: JSR PC,SFLUSH ;TWIDDLE OUR THUMBS
|
||
MOV C,A ;THE SPHERE NO.
|
||
BEQ 2$ ;ABSLOLUTE SWITCH
|
||
JSR PC,ITM1PL ;LOAD IT UP
|
||
2$: ADD E,A ;MAKE A POINT TO THE SWITCH
|
||
BIT B,(A) ;IS IT UNLOCKED YET
|
||
BNE LOCKA3 ;NOT YET
|
||
TST C ;IS THE SWITCH IN AN ITEM
|
||
BEQ 3$ ;NOPE
|
||
JSR PC,ITM1PO ;POP THE SPHERE
|
||
3$: JSR PC,RUNME ;I THINK I HAVE GOT IT
|
||
BR LOCKA2 ;MAKE SURE
|
||
LOCKA1: BIS B,(A) ;LOCK THE SWITCH
|
||
TST C ;ANY ITEM PUSHED
|
||
BEQ 1$ ;NOPE
|
||
JSR PC,ITM1PO ;POP THE SPHERE
|
||
1$: REST A ;GET THE POINTER TO THE LOCK
|
||
MOV A,LCKWD1(D) ;SAY THIS LOCK IS USED
|
||
MOV B,LCKWD2(D) ;THE BITS LOCKED
|
||
REST <D,E> ;GET ORIGINAL CONTENTS OF D
|
||
LOCKA5: RTS PC
|
||
;POP THE TOP LOCK OFF THE LOCKED SWITCH LIST
|
||
LSWPOP: TST INITSW ;ARE WE IN INIT CODE?
|
||
BNE LSWPO2 ;NO SWITCHES EVER LOCKED
|
||
JSR F,ACSAV
|
||
MOV ITM0A,A ;ASSUME ITEM0 IS THE PROCESS WHICH IS UNLOCKING
|
||
MOV PLCKSL(A),B ;SPLICE LOCK OUT OF IT'S LIST
|
||
BUGC EQ ;ONLY SHOULD GET CALLED IF ANYTHING IS LOCKED
|
||
MOV (B),PLCKSL(A)
|
||
MOV LCKFRE,(B) ;PUT IT ONTO THE FREE LIST
|
||
MOV B,LCKFRE
|
||
CMP #-1,LCKWD1(B) ;IS IT FOR REAL?
|
||
BEQ LSWPR4 ;NOPE, WE HAVE "UNLOCKED" IT
|
||
MOV LCKTIT(B),A ;GET THE TYPE
|
||
BNE 1$ ;IF REALLY ONE THERE
|
||
MOV #-1,A ;MAKE ITEM NXM (FOR THE SAKE OF THE PUSH)
|
||
1$: JSR PC,ITM2PL
|
||
TST LCKTIT(B) ;IS THERE REALLY AN ITEM?
|
||
BNE 2$ ;YES
|
||
CLR A ;NONE
|
||
2$: JMP @LCKDSP(B) ;DISPATCH ON TYPE
|
||
|
||
LSPONF: ADD LCKWD1(B),A ;POINT INTO ITEM IF THERE IS ONE
|
||
BIC LCKWD2(B),(A) ;UNLOCK ON-OFF TYPE LOCK
|
||
LSWPOR: JSR PC,ITM2PO ;POP THE ITEM STACK
|
||
LSWPR4: JSR F,ACRES
|
||
LSWPO2: RTS PC
|
||
|
||
LSPPCL: TST BPCLSR ;IS HE BEING PCLSRED?
|
||
BEQ LSWPOR ;IF NO, GO AWAY
|
||
LSPRTN: JSR PC,@LCKWD1(B) ;BEING PCLSRED, RUN ROUTINE
|
||
BR LSWPOR ;ALL DONE WITH THIS SWITCH
|
||
LSPDEC: ADD LCKWD1(B),A ;GET ABSOULUTE ADDRESS
|
||
DEC (A) ;FIXUP THE FLAG
|
||
BNE LSWPOR ;IF NOT ZERO, ALL DONE
|
||
TST LCKWD2(B) ;IS THERE A ROUTINE TO RUN ON ZERO FLAG?
|
||
BEQ LSWPOR ;NO, FINISHED THEN
|
||
JSR PC,@LCKWD2(B) ;CALL THE ROUTINE
|
||
BR LSWPOR
|
||
|
||
LSPULN: TST BPCLSR ;PCLOSERING ?
|
||
BEQ LSWPOR ;NO, JUST POP
|
||
MOV @LCKWD2(B),A ;GET THE CONTENTS OF FREE LIST POINTER
|
||
MOV LCKWD1(B),@LCKWD2(B) ;POINT FREE LIST AT ENTRY TO BE FLUSHED
|
||
MOV A,@LCKWD1(B) ;AND FLUSHED ENTRY AT REST OF LIST
|
||
BR LSWPOR
|
||
|
||
;THE DELETE ON PCLOSERING ROUTINE, FOR THINGS THAT NEED ITEMS FLUSHED
|
||
PCLDLI: MOV ITEM2,A
|
||
JMP DLITEM ;THE LOADED ITEM IS GETTING FLUSHED
|
||
|
||
;POP A SWITCH WITHOUT DOING ANYTHING WITH IT
|
||
LSWFLS: SAVE <A,B>
|
||
MOV ITM0A,A ;POINT INTO PROCESS
|
||
MOV PLCKSL(A),B ;GET FIRST SWITCH
|
||
BUGC EQ ;NO SWITCH?
|
||
MOV (B),PLCKSL(A) ;FLUSH THIS ONE
|
||
MOV LCKFRE,(B) ;RETURN THE NODE
|
||
MOV B,LCKFRE ;TO THE FREE LIST
|
||
REST <B,A>
|
||
RTS PC
|
||
.SBTTL TRAP AND FAULT ROUTINS
|
||
ILLBRK: TSTB PS+1
|
||
BNE ILLBR1
|
||
1$: BPT
|
||
BR 1$
|
||
ILLBR1: MOV #100000+.ILLTF,C
|
||
BR CCFAUL
|
||
|
||
BEBRK: TSTB PS+1 ;DID IT COME FROM USER MODE?
|
||
BNE BEBRK1 ;YES
|
||
BPT
|
||
RTT
|
||
BEBRK1: MOV #100000+.BETF,C ;BEBRK FAULT
|
||
BR CCFAUL
|
||
|
||
IOTBRK: TSTB PS+1 ;DID IT COME FROM USER MODE
|
||
BNE IOTBR1 ;YES
|
||
BPT
|
||
RTT
|
||
IOTBR1: MOV #100000+.IOTTF,C
|
||
BR CCFAUL
|
||
|
||
FPPBRK: MOV ITM0A,A ;POINT TO ITEM
|
||
BIT #PFPFLG,PFLAGS(A) ;SAVING FPP FOR THIS GUY?
|
||
BEQ FPPBR1 ;NO, DON'T SAVE THE ERROR FOR HIM
|
||
STST PFEC(A) ;SAVE ERROR
|
||
FPPBR1: MOV #100000+.FPPTF,PFAULT(A) ;SET THE FAULT
|
||
BIS #CLKPIR,PIRQ ;SCHEDULE HIM OUT WITH THE ERROR
|
||
CHECKP
|
||
RTT
|
||
|
||
PARBRK: BPT
|
||
RTT
|
||
|
||
BPTBRK: TSTB PS+1 ;FROM USER MOD
|
||
BNE BPTBR1 ;YES
|
||
SAVE <RUGSTA,RUGVEC> ;SAVE THE STUFF FOR RUG
|
||
CHECKP
|
||
RTI ;RETURN TO RUG
|
||
BPTBR1: MOV #100000+.BPTTF,C ;SAY A BPT FAULT
|
||
CCFAUL: MOV PC,USRMOD ;IN THE SYSTEM NOW
|
||
JSR F,SPCPSP
|
||
MOV C,PFAULT(A) ;THE TYPE OF FAULT
|
||
;FALLS IN TO THE NEXT PAGE
|
||
;FALLS IN FROM PREVIOUS PAGE
|
||
CFAULT: SPL 0 ;JUST IN CASE
|
||
MOV STPSVP,P ;RESTORE STACK TO THE STATE IT WAS IN WHEN SHED CALLED US
|
||
JSR F,SAVEPP ;SAVE THE USERS PDL POINTER
|
||
TST (P)+ ;CAUSE SAVEPP LEAVES IT THERE, THAT'S WHY!
|
||
MOV PC,BPCLSR ;WE NEED TO PCLOSER HIM
|
||
JSR PC,LSWCLR ;TO FLUSH WHAT EVER HE WAS DOING
|
||
CLR BPCLSR
|
||
TST LOOKSW
|
||
BEQ CFAUL9 ;IGNORE SWITCHES
|
||
BIT #40000,CSWR
|
||
BEQ CFAUL9
|
||
BPT
|
||
CFAUL9: MOV ITEM1,C ;THE SPHERE TO STOP
|
||
CMP C,SYSSPR ;THE SYSTEM SPHERE?
|
||
BUGC EQ ;BPT IF IT IS THE SYSTEM SPHERE THAT FAULTED
|
||
JSR PC,SPRSTP ;STOP THE SPHERE
|
||
MOV ITM1A,A ;THE SUPERIOR SPHERE
|
||
BIS #FAULT1,SFLAG(A) ;SAY THERE IS A FAULT
|
||
MOV SMSSPT(A),A ;GET THE SUPERIOR SPHERE
|
||
JSR PC,ITM2LD ;LOAD IT UP
|
||
SAVE #177 ;THE FIRST CAPABILITY NO.
|
||
CFAUL2: MOV (P),B ;GET THE CAPAIBLITY NO.
|
||
JSR PC,GCLSTA
|
||
BEQ CFAUL3 ;COULDN'T GET IT
|
||
ADD A,B ;POINT TO IT DIRECTLY
|
||
CMPB (B),#.MSCAP ;IS IT MASTER SPHERE
|
||
BNE CFAUL3 ;NO
|
||
CMP 2(B),ITEM1 ;FOR THIS SPHERE
|
||
BEQ CFAUL4 ;YES
|
||
CFAUL3: DEC (P) ;THE COUNTER
|
||
BGE CFAUL2 ;TRY THE NEXT ONE
|
||
BPT ;COULDN'T FIND IT
|
||
TST (P)+
|
||
CFAUL5: MOV ITEM0,A ;PROCESS THAT FAULTED
|
||
JSR PC,PSTPIN ;INCREMENT MY STOP WORD NOW, AND PCLOSER MYSELF
|
||
SAVE <A,PC,#STOPQ>
|
||
JMP FLUSH ;LET THE PROCESS CREATED HANDLE IT
|
||
CFAUL4: BIT #.SPFES,(B) ;CAN I CAUSE AN ENTER
|
||
BNE CFAUL5 ;NO, FORGET IT
|
||
MOV 6(B),E ;THE ENTER ADDRESS
|
||
BIT #1,E ;DOES IT EXIST
|
||
BNE CFAUL5 ;NO
|
||
;FALLS THROUGH
|
||
;FALLS IN
|
||
CFAUL6: MOV ITEM2,C ;POINTER TO THE SUPERIOR SPHERE
|
||
MOV #-1,B ;PUT IT ANYWHERE
|
||
JSR PC,CRCLST ;CREATE A PACE FOR IT
|
||
BCS CFAUL5 ;C-LIST FULL FORGET IT
|
||
ADD ITM2A,A ;POINT TO THE C-LIST ENTRY
|
||
MOV #-1,(A) ;RESERVE IT
|
||
MOV A,F ;SAVE THE POINTER
|
||
MOV B,D ;SAVE THE CAPABILITY NO.
|
||
MOV #LSPPCL,A ;INCASE OF PC-LOSER
|
||
MOV ITEM2,B ;THE ITEM
|
||
JSR PC,LOCKSW ;RELEASE THE SLOT
|
||
MOV F,LCKWD2(A) ;POINT TO THE C-LIST SLOT
|
||
CFAUL7: MOV F,A ;POINTER TO FIRST CAPABILITY
|
||
MOV #.PRWRA!.PRCAP,(A)+ ;CREATE A PROCESS CAPABILITY TO THE FAULTING PROCESS
|
||
MOV ITEM0,(A)+ ;SET IN THE PROCESS ITEM NO.
|
||
MOV ITM0A,A
|
||
INC PRSREF(A)
|
||
JSR PC,CRPROC ;CREATE PROCESS
|
||
BEQ CFAUL5 ;FAILED
|
||
JSR PC,ITM0PL ;LOAD IT UP
|
||
DEC PRSREF(A) ;SINCE THERE WILL BE NO CAP TO IT, AND PUTPRS WILL INCREMENT IT
|
||
BIC #PSUPSB,PSTOP(A) ;CLEAR THE BIT
|
||
MOV E,PUPC(A) ;SET UP THE STARTING ADDRESS
|
||
ADD #PUREGS,A ;POINT TO THE REGISTERS
|
||
MOV D,(A)+ ;PUT IN CAPABILITY TO THE FAULTING PROCESS INTO %0
|
||
REST (A) ;PUT IN CAPABILITY OF MS CAPABILITY TO FAULTING SPHERE
|
||
MOV ITEM0,A ;COPY THE ITEM NO. OF THE FAULT HANDLER
|
||
MOV ITEM2,B ;THE SUPERIOR SPHERE
|
||
JSR PC,PUTPRS ;PUT THE PROCESS INTO THE SPHERE
|
||
MOV ITEM0,A
|
||
JSR PC,PSTPDC ;START IT
|
||
JSR PC,ITM0PO ;POP THE ITEM
|
||
JSR PC,LSWPOP ;POP LOCK ON CAP
|
||
JMP CFAUL5
|
||
|
||
;FIX THE FAULT FOR THE SPHERE IN B
|
||
FALTFX: SAVE <A,C> ;SAVE SOME REGS.
|
||
MOV B,A ;THE SPHERE
|
||
JSR PC,ITM1PL ;LOAD IT UP
|
||
BIT #FAULT1!FAULT2!FAULT3,SFLAG(A) ;IS THERE A FAULT
|
||
BUGC EQ ;JUST CHECKING
|
||
BIC #FAULT1!FAULT2!FAULT3,SFLAG(A) ;SAY NO MORE FAULT
|
||
MOV ITEM1,C ;GET THE SPHERE NO.
|
||
JSR PC,ITM1PO ;POP THE SPHERE
|
||
JSR PC,SPRSTR ;START IT UP
|
||
REST <C,A> ;CLEAN UP
|
||
RTS PC
|
||
|
||
TRPBRK: MOV #TRPBRV,A ;POINTER TO THE TRAP STUFF
|
||
JSR PC,USRTRP ;CHECK OUT THE TRAP
|
||
MOV ITM0A,A ;POINTER TO THE PROCESS
|
||
TSTB PS+1 ;IS IT FROM KERNEL MODE
|
||
BEQ TRPBR1 ;YES,
|
||
MOV #100000+.TRPTF,PFAULT(A) ;FAULT TYPE FOR BAD TRAP
|
||
JMP CFAULT ;JUST CAUSE THE FAULT
|
||
TRPBR1: .IRPC X,<012>
|
||
TRPIP'X: TST ITM'X'D ;ANY PUSHED?
|
||
BEQ TRPPD'X
|
||
JSR PC,ITM'X'PO
|
||
BR TRPIP'X
|
||
TRPPD'X:
|
||
.ENDM
|
||
MOV ITM0A,A
|
||
SUB #2,(P) ;POINT TO THE TRAP
|
||
MOV (P),PERRAD(A) ;SAVE SYSTEM ADDRESS WHERE ERROR HAPPENED
|
||
MFPI @(P) ;GET THE ACTUAL TRAP INSTRUCTION
|
||
REST B ;GET BACK THE INSCTRUCTION
|
||
MOV STPSVP,P ;RESTORE STACK TO THE STATE IT WAS IN WHEN SHED CALLED US
|
||
CCC ;CLEAR THE CONDITION CODES
|
||
SAVE PS ;SAVE A COPY OF THE PS TO MUNG
|
||
BIT #TRPZBT,B ;ARE WE SUPPOSED TO SET THE Z BIT?
|
||
BEQ 1$ ;NO
|
||
BIS #4,(P) ;SET IT
|
||
1$: BIT #TRPVBT,B ;ARE WE SUPPOSED TO SET THE V BIT?
|
||
BEQ 2$ ;NO
|
||
BIS #2,(P) ;SET IT
|
||
2$: BIC #177400!TRPZBT!TRPVBT,B ;CLEAR BITS
|
||
MOV B,PERRW(A) ;THAT'S THE ERROR TYPE
|
||
MOV PC,BPCLSR ;FLUSH SWITCHES
|
||
JSR PC,LSWCLR ;LIKE HE'S BEING PCLOSERED
|
||
CLR BPCLSR
|
||
JMP EMTRTP ;EMT RETURN SPECIAL ENTRY
|
||
|
||
;THIS ROUTINE EXPECTS A TO BE A POINTER TO THE TRAP VECTOR IN THE USERS CORE
|
||
;AND DECIDES IF IT IS A FAULT OR A TRAP THROUGH
|
||
USRTRP: TSTB PS+1 ;IS IT FROM KERNEL MODE
|
||
BNE USRTR1 ;NO
|
||
RTS PC ;TEMPORARY FOR TRAP TO WORK
|
||
USRTR1: MOV PC,USRMOD ;SAY WE ARE IN THE SYSTEM
|
||
REST E ;THE CALLING ADDRESS
|
||
MOV A,B ;SAVE THE POINTER TO THE TRAP
|
||
JSR F,SPCPSP ;SAVE HIS STUFF, AND F GETS USER P POINTER
|
||
SUB #2,PUPC(A) ;DECREMENT IT TO THE CALL IF PCLOSERED
|
||
;HERE IF NOT TRAP THROUGH JUST RETURN BY JMP (E)
|
||
MFPD -(F) ;GET THAT WORD
|
||
MFPD -(F) ;GET THE PC WORD
|
||
MFPI 2(B) ;ALL THIS TO PREVENT HANG BELOW
|
||
MFPI (B) ;PROBABLY UNNECCESSARY
|
||
ADD #10,P ;POP OFF THE EXTRA STUFF
|
||
SAVE <PUPS(A),PUPC(A)>
|
||
ADD #2,(P) ;MAKE IT LOOK LIKE REAL TRAP
|
||
MTPD (F)+ ;GIVE HIM THE PC
|
||
MTPD (F)+ ;AND THE PS
|
||
SUB #4,F
|
||
SAVE F ;THE NEW P
|
||
MTPI P ;GIVE IT BACK
|
||
MFPI 2(B) ;GET THE TRAP VECTOR STATUS
|
||
BIC #340,(P) ;CLEAR THE PRIORITY BITS
|
||
BIS #174000,(P) ;USER MODE, FOR SURE
|
||
MFPI (B) ;AND THE ADDRESS
|
||
SPL CLKL ;INHIBIT SCHEDULES
|
||
CLR USRMOD
|
||
CHECKP
|
||
RTT ;RETURN
|
||
.SBTTL EMT HANDLERS
|
||
;GET HERE WHEN A USER EXECUTES AN EMT
|
||
EMTBRK: CMPB #60,PS+1 ;MAKE SURE IT CAM FROM USER MODE
|
||
BUGC NE
|
||
MOV PC,USRMOD ;NOW WE AREIN THE SYSTEM!
|
||
JSR F,SPCPSP ;SAVE THE USER'S PC, PS AND PDL POINTER
|
||
CLR PUPDLO(A) ;NOTHING POPED YET
|
||
SUB #2,PUPC(A) ;POINT TO THE CALL ITSELF
|
||
MFPI @PUPC(A) ;GET THE ACTUAL CALL
|
||
REST B ;POP IT OFF THE STACK
|
||
ASL B ;CONVERT IT TO A WORD INDEX
|
||
BIC #177001,B ;8 BITS ARE SIGNIFICANT
|
||
BIC #PFALTB,PFLAGS(A) ;SET THE TEMPORARY FAULT BIT
|
||
BIT #400,B ;IS THE FAULT ON FAIL BIT SET?
|
||
BEQ 1$ ;NO
|
||
BIS #PFALTB,PFLAGS(A) ;SET THE TEMPORARY FAULT BIT
|
||
1$: BIC #400,B ;CLEAR THE TOP BIT
|
||
CMP #EMTHGH*2,B ;IS IT TOO HIGH?
|
||
BLOS BADEMT ;YUP, TELL HIM HE IS A LOSER
|
||
SAVE PS ;NOTE THAT TRACE TRAPS WILL ACT STRANGELY HERE
|
||
BIC #357,(P) ;PRIORITY 0
|
||
SAVE EMTDIS(B) ;DISPATCH ADDRESS
|
||
CHECKP
|
||
RTT
|
||
BADEMT: MOV ITM0A,A ;POINT TO THE PROCESS
|
||
MOV #100000+.EMTTF,PFAULT(A) ;CAPABILITY FAULT
|
||
JMP CFAULT
|
||
EGERRW: MOV #PERRW,E
|
||
EGERR1: ADD ITM0A,E ;POINT TO PROCESS
|
||
MOV (E)+,B ;HIS ERROR WORD
|
||
ERRORC EQ,NUL ;NO ERROR, GIVE HIM AN ERROR
|
||
JSR PC,GIVPSW ;GIVE HIM THE ERROR NUMBER
|
||
MOV (E),B ;AND THE ERROR ADDRESS IN THE SYSTEM
|
||
JSR PC,GIVPSW
|
||
CLR PERRW(A) ;NO ERROR FOR NEXT TIME
|
||
JMP ERETCZ
|
||
|
||
EGETID: MOV #PRSID1,E
|
||
BR EGERR1
|
||
|
||
EMFPI: JSR PC,RETNSW ;GET THE ADDRESS FROM THE STACK
|
||
BIC #1,A ;AVOID LOSSAGE
|
||
MFPI (A)
|
||
REST B
|
||
JSR PC,GIVPSW
|
||
JMP ERETCZ
|
||
|
||
ERUG: CMP CURSPH,SYSSPR
|
||
BNE BADEMT
|
||
BPT
|
||
MOV ITM0A,A ;POINTER TO PROCESS
|
||
MFPI @PUPC(A) ;GET WHAT SHOULD BE THE .RUG
|
||
BIC #200,(P) ;LOSE BIT
|
||
CMP #.RUG,(P)+ ;STILL A .RUG?
|
||
BEQ ENOOP ;YUP, JUST RETURN
|
||
SUB #2,PUPC(A) ;REEXECUTE THE CHANGED INSTRUCTION
|
||
|
||
;RETURN FROM EMT TO USER
|
||
ENOOP:
|
||
EMTRET: SAVE PS ;FOR THE CONDITION CODES
|
||
EMTRTP: MOV ITM0A,A ;PROCESS HAD BETTER BE THERE
|
||
EMTRE1:
|
||
CMP #PDL-4,P ;CROCK TO CATCH EMT'S THAT DON'T FULLY POP THE STAKC
|
||
BUGC NE
|
||
;THIS IS TEMPORARY INSTRUCTION
|
||
MOV #30000,PS ;MAKE SURE PREVIOUS MODE IS USER
|
||
TST PLCKSL(A) ;ANY LOCKED SWITCHES?
|
||
; BUGC NE ;YES, BUG
|
||
JSR PC,LSWCLR
|
||
EMTRE2:
|
||
.IRPC X,<012>
|
||
TST ITM'X'D
|
||
BUGC NE ;HAD ITEMS PUSHED
|
||
.ENDM
|
||
MOV #-1,A
|
||
JSR PC,ITM2LD ;CLOBBER LOADED ITEM 2
|
||
MOV ITM0A,A
|
||
BIT #4,(P) ;HAS THE CALL FAILED?
|
||
BEQ EMTRE4 ;BR IF NOT
|
||
CLR PUPDLO(A) ;NOTHING GETS POPPED
|
||
BIT #PFALTB!PFAILB,PFLAGS(A) ;SHOULD HE BE FAULTED
|
||
BNE BADEMT ;YES, IT IS A BADEMT
|
||
EMTRE4: BIC #PFALTB,PFLAGS(A) ;CERTAINLY NO LONGER A $ EMT
|
||
CLR PSPC(A) ;NOT IN THE SYS ANYMORE
|
||
MOVB #370,1(P) ;GO BACK TO USER MODE PROPERLY
|
||
BIT #20,PUPS(A) ;RESTORE TRAP BIT IF WAS SET
|
||
BEQ 1$
|
||
BIS #20,(P) ;SET THE TRAP BIT
|
||
1$: SAVE PUP(A) ;GET HIS OLD P ONTO MY STACK
|
||
ADD PUPDLO(A),(P) ;ANYTHING POPED FROM IT?
|
||
MTPI P ;RESTORE P FOR HIM
|
||
SAVE PUPC(A) ;PUT THE PC ON THE STACK NOW
|
||
ADD #2,(P) ;START HIM AFTER THE CALL
|
||
MOV A,B ;THE ITEM ADDRESS
|
||
JSR PC,PACRES ;RESTORE HIS AC'S
|
||
SPL CLKL ;PREVENT A SCHEDULE
|
||
CLR USRMOD ;THIS COULD CAUSE ONE
|
||
TST QUANT ;HAS HE OVERSTAYED HIS WELCOME?
|
||
BGE 2$ ;NO
|
||
BIS #CLKPIR,PIRQ ;GET HIM AFTER THE RTI
|
||
2$: CHECKP
|
||
RTI ;GO TO USER MODE
|
||
;PROCESS HACKING EMTS
|
||
;.FORK:
|
||
;1 ARGUMENT IS ADDRESS OF PLACE TO START NEW PROCESS
|
||
;CLEARS Z IF IT SUCEEDS IN CREATING A NEW PROCESS
|
||
EFORK: JSR PC,RETNSW
|
||
SAVE A
|
||
JSR PC,CRPROC ;ATTEMPT TO CREATE A PROCESS
|
||
BEQ EFORK1 ;FAIL
|
||
MOV CURSPH,B ;PUT IT INTO THE CURRENT PROCESS
|
||
JSR PC,PUTPRS
|
||
JSR PC,ITM0PL ;LOAD IT TEMPORARILLY
|
||
DEC PRSREF(A) ;IT IS ONE TO LARGE (SHOULD BE ONLY ONE)
|
||
BUGC LE
|
||
REST PUPC(A) ;SET ITS PC
|
||
BIC #PSUPSB,PSTOP(A) ;CLEAR THE STOP BIT
|
||
MOV ITEM0,A
|
||
JSR PC,PSTPDC ;GO START IT
|
||
MOV ITM0A,A
|
||
ADD #PUREGS,A ;MAKE A POINT TO THE OLD REGISTERS
|
||
BIS #4000,PS
|
||
SAVE <F,E,D,C,B,A>
|
||
BIC #4000,PS
|
||
MOV #6,E ;THE NUMBER TO COPY
|
||
1$: REST (A)+
|
||
SOB E,1$
|
||
JSR PC,ITM0PO ;POP ITEM STACK
|
||
ERETCZ: CCC ;SUCESS
|
||
EFORK1: JMP EMTRET
|
||
|
||
;.POOFF:
|
||
;NO ARGUMENT. MAKE THE PROCESS EXECUTING ITDISAPPEAR WITHOUT A TRACE
|
||
;CURRENTLY, THE PROCESS IS ONLY STOPPED
|
||
;IF THERE ARE ANY REFERENCES TO ITREMAINING
|
||
EPOOFF: MOV ITEM0,B ;THE PROCESS ITEM
|
||
JSR PC,SPRINC ;INCREMENT THE REFERENCE COUNT (SO IT DOESN'T DISAPPEAR
|
||
;IN REMPRS)
|
||
MOV ITM0A,A ;THE FOLLOWING IS ONLY DONE TO KEEP THINGS CONSISTENT
|
||
JSR PC,PACSAV
|
||
JSR PC,TIMEUS
|
||
JSR PC,SAVAWB
|
||
JSR PC,PDLSAV
|
||
MOV PRUNNG,A
|
||
JSR PC,PSTPIN ;INCREMENT THE STOP COUNT
|
||
MOV ITM0A,A ;PROCESS POINTER
|
||
JSR PC,REMPRS ;REMOVE IT FROM THE SPHERE IT IS IN
|
||
MOV PRUNNG,A
|
||
JMP DLPROC ;DECREMENT REFERENCE COUTN AND DELETE IF ZERO
|
||
;.INVOKE:
|
||
;1 ARG IS CAPABILITY NUMBER TO INVOKE AND MAYBE FLAGS
|
||
;MORE ARGS MAY BE TAKEN IF CAPABILTY WANTS THEM
|
||
;BUT THERE MUST ALWAYS BE 3 THINGS ON THE STACK AND 3 THINGS WILL BE POPPED
|
||
EINVOK: SUB #6,P ;CREATE 3 WORDS OF TEMP STORAGE FOR ARG
|
||
JSR PC,RETNSW ;GET THE TOP OF THE STACK
|
||
MOV A,(P) ;LOTS OF PEOPLE WILL WANT IT
|
||
JSR PC,RETNSW ;GET 2ND ARG
|
||
MOV A,2(P) ;SAVE IT
|
||
JSR PC,RETNSW ;GET 3RD ARG
|
||
MOV A,4(P) ;SAVE LAST ARG
|
||
MOV ITM1A,A ;GET ADDRESS OF SPHERE
|
||
MOV (P),B ;THE CAP NUMBER
|
||
BIC #177400,B ;CLEAR WHATEVER IS THERE
|
||
MOV B,E ;TO SAVE IT FOR LATER ROUTINES
|
||
JSR PC,GCLSTA ;SEE IF IT IS THERE
|
||
BEQ EIVOK1 ;LOSER
|
||
ADD B,A ;GET A REAL ADDRESS FOR CAP
|
||
MOV (A),B ;THE FIRST WORD OF CAP
|
||
BEQ EIVOK1 ;NOTHING THERE
|
||
CMP B,#-1
|
||
BEQ EIVOK1
|
||
ASL B ;TO A WORD ADDR
|
||
BIC #177001,B ;FLUSH EXTRA BITS
|
||
CMP B,#CAPHGH*2
|
||
BUGC GE ;IF THE CAPABLITY IS TOO BIG
|
||
MOVB 1(P),C ;THE FUNCTION
|
||
BITB #200,C ;IS IT A GENERAL REQUEST
|
||
BNE 1$
|
||
JMP @IVKCTB(B) ;GO TO THE RIGHT ROUTINE
|
||
1$: ASL C ;TURN IT INTO A WORD INDEX
|
||
BIC #177400,C ;CLEAR THE TOP BYTE
|
||
CMP C,#GENHGH
|
||
ERRORC GE,BFUN
|
||
JMP @GENDIS(C) ;GO TO THE GENERAL FUNCTION ROUTINE
|
||
EIVOK1: ERROR BAD
|
||
|
||
.IFNZ NPC
|
||
DELCAP: ADD #6,P ;POP OFF ALL THE ARGUMENTS
|
||
JSR PC,@DELTAB(B) ;DELETE ROUTINE FOR THIS CAPABILITY
|
||
BUGC EQ ;NOT BEING ABLE TO DELETE A CAP SHOULDN'T HAPPEN
|
||
MOV CURSPH,C ;SPHERE TO PCLOSER
|
||
JSR PC,SPRRPC ;REALLY PCLOSER IT
|
||
JMP ERETCZ
|
||
|
||
|
||
.IFF
|
||
DELCAP: MOV CURSPH,C ;THE CURRENT SPHERE MUST BE PCLOSERED
|
||
;Z JSR PC,SPRSTP ;STOP IT
|
||
;Z JSR PC,SPRSTR ;AND START IT UP
|
||
ADD #6,P ;POP OFF ALL THE ARGUMENTS
|
||
JSR PC,@DELTAB(B) ;DELETE ROUTINE FOR THIS CAPABILITY
|
||
JMP EMTRET ;RETURN WHATEVER FLAGS SET
|
||
.ENDC
|
||
CPYCAP: MOV A,F
|
||
MOV B,C ;FOR ROUTINES LATER
|
||
TST (P)+ ;ONLY WANT TWO ARGS
|
||
ADD #CPYTAB,C
|
||
JMP CPYCA1
|
||
GIVCAP: TST (P)+ ;FIRST ARG NO LONGER NEEDED
|
||
MOV (A),C ;TYPE AND FLAGS OF CAP TO USE WHEN GIVING AWAY
|
||
CMPB C,#.MSCAP ;IS IT A MASTER SPHERE CAPABILITY
|
||
BEQ GVCAP1 ;YES
|
||
CMPB C,#.SPCAP ;IS IT SPHERE CAP.
|
||
BEQ GVCAP1 ;YEP
|
||
GVCAP2: ADD #4,P ;POP OFF GARBAGE
|
||
JMP BADEMT
|
||
GVCAP1: BIT #.SPCAD,C ;DOES HE HAVE APPEND ACCESS
|
||
BEQ GVCAP2 ;NOPE, HE LOSES
|
||
MOV (P),B ;THE SECOND ARG SPECIFIES WHAT TO GIVE AWAY
|
||
BIC #177400,B ;GET THE GOOD BITS
|
||
MOV B,E ;TO SAVE IT FOR LATER
|
||
MOV A,C ;SAVE POINTER TO SPHERE OR MS CAP
|
||
MOV ITM1A,A ;FIND IT IN THIS SPHERE
|
||
JSR PC,GCLSTA ;FIND THE CAP.
|
||
BEQ GIVLOS ;CAN'T FIND IT
|
||
ADD A,B ;MAKE B POINT TO THE CAPABILITY
|
||
MOV B,D ;FOR LATER DELETION
|
||
MOV (B),F ;GET THE TYPE AND FLAGS
|
||
BEQ GIVLOS ;THERE ISN'T A CAPABILITY THERE
|
||
CMP #-1,F
|
||
BEQ GIVLOS
|
||
ASL F ;CHANGE IT TO A WORD INDEX
|
||
BIC #177001,F ;CLEAR EXTRA BITS
|
||
MOV 2(C),C ;GET THE SPHERE NO. THAT WE ARE GIVING TO
|
||
JSR PC,SPRSTP ;STOP IT
|
||
MOV C,B ;FOR THE LOCK ROUTINES
|
||
MOV #LSPRTN,A ;RUN A ROUTINE IF UNLOCKED
|
||
JSR PC,LOCKSW ;GET A LOCK
|
||
MOV #PCSPST,LCKWD1(A) ;START PROCESSES IF UNLOCKED
|
||
MOV #-1,B ;BECAUSE LCKASW DOES A BIT
|
||
MOV #SCLSLK,A ;C-LIST LOCK
|
||
JSR PC,LCKASW ;LOCK AN ITEM'S SWITCH
|
||
MOV C,A ;GET BACK THE SPHERE
|
||
JSR PC,ITM2PL ;LOAD IT UP
|
||
MOV PRUNNG,SCLSLK(A) ;PUT MY PROCESS NUMBER THERE
|
||
JSR PC,ITM2PO ;POP IT AGAIN
|
||
MOV 2(P),B ;WHERE TO PUT IT
|
||
JSR PC,CRCLST ;CREATE A C-LIST ENTRY IN HIS C-LIST
|
||
BCS GVCAP2 ;C-LIST FULL
|
||
BEQ GIVLOS ;DESTINATION OCCUPIED
|
||
SAVE <C,B,A>
|
||
MOV ITEM1,C ;THIS SPHERE
|
||
JSR PC,SPRSTP ;STOP IT (EXCEPT FOR ME)
|
||
MOV C,B ;THE ITEM FOR THE LOCKSW ROUTINES
|
||
MOV #LSPRTN,A ;RUN A ROUTINE WHEN UNLOCKED
|
||
JSR PC,LOCKSW ;LOCK THE SWITCH
|
||
MOV #PCSPST,LCKWD1(A) ;START THE PROCESSES WHEN UNLOCKED
|
||
MOV ITEM0,LCKWD2(A) ;START ALL THE PROCESSES, EXCEPT ME
|
||
REST <A,B,C>
|
||
JMP @GIVTAB(F) ;DISPATCH ON TYPE
|
||
GIVLOS: ERROR BAD
|
||
|
||
;THIS ROUTINE CALLS THE APPROPRIATE ROUTINE WITH INFO AS FOLLOWS
|
||
;A- POINTER TO CAP DEST.,C- SPHERE OF TAKEE, D-OFFSET OF TAKEE CAP.
|
||
;B-C LIST NO. OF DESTINATION,E-C LIST NO. OF TAKEE,F-DISPATCH TYPE
|
||
TAKCAP: TST (P)+ ;FIRST ARGUMENT NO LONGER NEEDED
|
||
MOV (A),C ;TYPE AND FLAGS OF CAP. TO USE WHEN TAKING AWAY
|
||
CMPB C,#.MSCAP ;MASTER SPHERE CAP.
|
||
BEQ TKCAP1 ;YES
|
||
CMPB C,#.SPCAP ;SPHERE CAP.?
|
||
BEQ TKCAP1 ;YES
|
||
TKCAP2: ADD #4,P ;POP OFF ARGS
|
||
JMP BADEMT
|
||
TKCAP1: BIT #.SPCLD,C ;CAN WE DELETE FROM THIS C-LIST
|
||
BEQ TKCAP2 ;NO!
|
||
MOV (P),B ;WHAT WE ARE SUPPOSED TO TAKE AWAY
|
||
BIC #177400,B ;GET THE GOOD BITS
|
||
MOV B,E ;THE C-LIST NO. OF TAKEE
|
||
MOV 2(A),A ;THE SPHERE NO. OF TAKEE
|
||
MOV A,C ;SAVE IT FOR LATER
|
||
JSR PC,ITM2PL ;LOAD IT UP
|
||
JSR PC,GCLSTA ;DOES THE CAP EXIST
|
||
BEQ TAKLOS ;NOPE
|
||
MOV B,D ;OFFSET OF TAKEE
|
||
ADD A,B ;MAKE B POINT TO IT
|
||
MOV (B),F ;CAPABILITY TYPE AND FLAGS
|
||
BEQ TAKLOS ;DOESN'T EXIST
|
||
CMP #-1,F
|
||
BEQ TAKLOS
|
||
JSR PC,ITM2PO ;DONE FOR NOW WITH THIS
|
||
ASL F ;TURN TYPE INTO WORD INDEX
|
||
BIC #177001,F ;CLEAR EXTRA BITS
|
||
JSR PC,SPRSTP ;STOP THE SPHERE OF TAKEE
|
||
MOV C,B ;FOR THE LOCK ROUTINE
|
||
MOV #LSPRTN,A ;RUN A ROUTINE WHEN UNLOCKED
|
||
JSR PC,LOCKSW ;GET A LOCK
|
||
MOV #PCSPST,LCKWD1(A) ;START THE SPHERE WHEN UNLOCKED
|
||
MOV #-1,B ;BECAUSE LCKASW DOES A BIT
|
||
MOV #SCLSLK,A ;LOCK THE SPHERES C-LIST
|
||
JSR PC,LCKASW ;LOCK AN ITEM'S SWITCH
|
||
MOV C,A ;GET THE SPHERE NO
|
||
JSR PC,ITM2PL ;LOAD IT BACK UP
|
||
MOV PRUNNG,SCLSLK(A) ;PUT MY ITEM NO. THERE
|
||
JSR PC,ITM2PO ;POP IT AGAIN
|
||
MOV 2(P),B ;THE DESTINATION IN TAKER
|
||
SAVE C ;SAVE SPHERE OF TAKEE
|
||
MOV ITEM1,C ;CREATE THE C-LIST ENTRY IN THIS SPHERE
|
||
JSR PC,CRCLST ;CREATE AN ENTRY
|
||
BCS TKCAP4 ;C-LIST FULL
|
||
BEQ TKCAP3 ;C-LIST DESTINATION OCCUPIED
|
||
ADD ITM1A,A ;MAKE A POINT ABSOLUTELY
|
||
REST C ;SPHERE OF TAKEE
|
||
JMP @TAKTAB(F)
|
||
TAKLOS: JSR PC,ITM2PO
|
||
BR TKCAP2
|
||
TKCAP3: JMP EIVOK1
|
||
TKCAP4: ADD #6,P
|
||
JMP BADEMT
|
||
|
||
;.SINK
|
||
;DISABLES FLOATING POINT FOR THIS PROCEEDURE
|
||
;ALWAYS SUCCEEDS
|
||
ESINK: MOV #PRSLNF,A ;SIZE OF A PROCESS WITHOUT FLOATING POINT AC'S
|
||
MOV ITEM0,B ;THE ITEM INDEX OF THE PROCESS
|
||
JSR PC,EXITEM ;SHRINK THE PROCESS IF NECESSARY
|
||
MOV ITM0A,A ;THE ADDRESS OF THE ITEM
|
||
BIC #PFPFLG,PFLAGS(A) ;CLEAR THE FLOATING POINT FLAG IN PROCESS
|
||
JMP ERETCZ
|
||
|
||
;.FLOAT
|
||
;ENABLES FLOATING POINT FOR THIS PROCEDURE
|
||
EFLOAT: MOV ITM0A,A
|
||
BIT #PFPFLG,PFLAGS(A)
|
||
BNE EFLOT2
|
||
MOV #PRSLFP,A ;SIZE OF PROCESS WITH FLOATING POINT
|
||
MOV ITEM0,B ;THE ITEM INDEX OF THE PROCESS
|
||
JSR PC,EXITEM ;EXPAND THE PROCESS TO INCLUDE SPACE FOR FLOATING POINT AC'S
|
||
BNE EFLOT1 ;IT FAILED
|
||
JMP EMTRET
|
||
EFLOT1: MOV B,A
|
||
JSR PC,ITM0LD ;LOAD THE NEW PROCESS
|
||
MOV #40300,PFPPS(A) ;START HIM WITH INT. DISABLED AND IN DOUBLE AND LONG MODE
|
||
BIS #PFPFLG,PFLAGS(A)
|
||
EFLOT2: JMP ERETCZ
|
||
|
||
;MAKE THE PROCESS EXECUTING THIS CALL, A USER, AND GIVE THE PROCESS TO THAT USER
|
||
;TAKES 3 ARGS, IF FIRST IS NON ZERO, PUT THE NAME OF THE USER INTO THE CURUSR
|
||
;LENGTH OF NAME IS SECOND ARG
|
||
;POINTER TO NAME IS THIRD
|
||
ECRUSR: JSR PC,RETNSW ;GET THE SWITCH
|
||
TST A
|
||
BGT ECRUS2 ;SET IN THE NAME
|
||
BLT ECRUS3 ;RETURN THE NAME
|
||
JSR PC,SYSCHK ;JUST CREATE NEW USER
|
||
JSR PC,CRUSER ;CREATE A USER
|
||
ERRORC EQ,NIT ;NO ITEM AVAILABLE
|
||
MOV ITM0A,F ;GET ADDRESS OF THE PROCESS
|
||
MOV PUP(F),E ;POINTER TO TOP OF PDL
|
||
SAVE #-1 ;PUSH A -1 ONTO USERS STACK
|
||
MTPD (E) ;PUT THE WORD BACK
|
||
MOV B,PRSUSR(F) ;THE NEW USER FOR THIS PROCESS
|
||
MOV PPRTPT(F),F ;THE PROCESS TABLE POINTER
|
||
MOV B,PRTUPT(F) ;SAY THE NEW USER IS THIS USER
|
||
MOV B,CURUSR ;SAY IT TO EVERYONE
|
||
ECRUS2: JSR PC,ECRSET ;SET UP
|
||
MOV #10.,F ;MAX LENGTH
|
||
1$: JSR PC,GETUBY ;GET A BYTE FROM THE USER
|
||
MOVB A,(B)+ ;SAVE THE BYTE
|
||
BEQ 2$ ;EXIT IF END OF STRING
|
||
SOB F,1$ ;GO FOR UP TO 10 CHARS
|
||
CLR -(B) ;TOO MANY CHARS
|
||
2$: JMP ERETCZ ;SUCESS
|
||
ECRUS1: ERROR BAD
|
||
ECRUS3: JSR PC,ECRSET ;SET UP
|
||
1$: MOVB (B)+,A
|
||
JSR PC,PUTUBY ;GIVE BYTE TO USER
|
||
BNE 1$ ;UNTIL END OF STRING
|
||
JMP ERETCZ
|
||
|
||
ECRSET: MOV CURUSR,B ;GET THE PROCESS TABLE ENTRY FOR USER
|
||
MOV PRTPPT(B),A ;ITEM NO. OF THE USER
|
||
JSR PC,ITM2LD ;LOAD IT UP
|
||
JSR PC,RETNSW ;GET THE NAME
|
||
MOV A,E ;SAVE ADDRESS
|
||
MOV ITM2A,B ;POINT TO USER
|
||
ADD #USRNAM,B ;POINT TO NAME
|
||
RTS PC
|
||
;.TTGIV
|
||
;GIVE TTY AWAY, THE FIRST ARGUMENT IS A MASTER SPHERE CAPABILITY
|
||
;THE SECOND IS A TELETYPE CAPABILITY
|
||
ETTGIV: JSR PC,RETNSW ;GET THE FIRST ARG
|
||
MOV A,B ;THE MASTER SPHERE CAPABILITY
|
||
BIC #177400,B ;CLEAR THE TOP BYTE
|
||
MOV ITM1A,A ;THE ADDRESS OF THE SPHERE IN THE MAP
|
||
JSR PC,GCLSTA ;FIND THE CAPABILITY
|
||
ERRORC EQ,RNA ;RESOURCE NOT AVAILABLE
|
||
ADD B,A ;MAKE A POINT TO THE SPHERE CAP
|
||
MOV (A),C ;THE TYPE AND FLAGS
|
||
BEQ TTGIV1 ;DOESN'T EXIST
|
||
CMPB C,#.MSCAP ;IS IT A MASTER SPHERE CAP.
|
||
BNE TTGIV1 ;NOPE, CAN'T DO IT
|
||
MOV 2(A),D ;THE SPHERE TO GIVE IT TO
|
||
JSR PC,RETNSW ;GET THE SECOND ARG
|
||
MOV A,B ;THE ARGUMENT
|
||
BIC #177400,B ;CLEAR THE TOP BYTE
|
||
MOV ITM1A,A
|
||
JSR PC,GCLSTA ;FIND THE CAPABILITY
|
||
BEQ TTGIV1 ;COULDN'T FIND IT
|
||
ADD B,A ;MAKE A POINT TO THE TTY CAP
|
||
MOV (A),C ;TYPE AND FLAGS
|
||
BEQ TTGIV1 ;DOESN'T EXIST
|
||
CMPB C,#.TTCAP ;IS IT A TTY CAPABILITY
|
||
BNE TTGIV1 ;NOPE
|
||
MOV 2(A),A ;THE MASTER TTY ITEM NO.
|
||
JSR PC,ITM2LD ;LOAD IT UP
|
||
MOV ITM1A,B ;POINTER TO THE CURRENT SPHERE
|
||
MOV CURSPH,C ;THE CURRETN SPHERE
|
||
TTGIV2: CMP C,TTITM(A) ;IS THIS SPHERE THE OWNER OF THE TTY
|
||
BEQ TTGIV4 ;YES
|
||
TTGIV3: JSR PC,LFLUSH ;WAIT FOR IT
|
||
CMP C,TTITM(A) ;DO I OWN IT NOW?
|
||
BNE TTGIV3 ;NO
|
||
JSR PC,RUNME ;TRY TO GET IT
|
||
BR TTGIV2 ;MAKE SURE
|
||
TTGIV4: MOV TTYST1(A),STTFG1(B) ;STORE THE CURRENT TTY STATUS
|
||
MOV TTYST2(A),STTFG2(B) ;STORE THE EXTRA STATUS WORD
|
||
MOV D,SIFTTY(B) ;NEW INFERIOR SPHERE
|
||
MOV D,A ;THE SPHERE WE ARE GIVING IT TO
|
||
JSR PC,ITM1PL ;BOGUS PUSH
|
||
MOV D,A
|
||
TTGIV5: JSR PC,ITM1LD ;LOAD UP THE INFERIOR SPHERE
|
||
MOV SIFTTY(A),A ;GET THE SPHERE IT GAVE THE TTY TO
|
||
BNE TTGIV5 ;HE GAVE IT AWAY
|
||
MOV ITM2A,B ;POINTER TO THE TTY ITEM
|
||
MOV ITM1A,A ;POINTER TO THE SPHER
|
||
MOV CURUSR,TTYU(B) ;FIX USER POINTER
|
||
MOV STTFG1(A),TTYST1(B) ;SET UP HIS STATUS
|
||
MOV STTFG2(A),TTYST2(B) ;SET UP HIS OTHER STATUS WORD
|
||
MOV ITEM1,TTITM(B) ;SET IN THE NEW OWNER
|
||
JSR PC,ITM1PO ;GET RID OF HIM
|
||
.IFNZ NPC
|
||
MOV CURSPH,C
|
||
JSR PC,SPRRPC ;PCLOSER EVERY (EXCEPT ME)
|
||
MOV ITM0A,A ;POINT TO ME
|
||
.IFF
|
||
MOV CURSPH,A
|
||
JSR PC,SPRPCL ;PCLOSER EVERY (EXCEPT ME)
|
||
MOV ITM0A,A ;POINT TO ME
|
||
BIC #PPCLSR,PFLAGS(A) ;CLEAR THE PCLOSER BIT
|
||
.ENDC
|
||
JMP ERETCZ ;SUCCESS
|
||
TTGIV1: ERROR BCN ;BAD CAPABILITY
|
||
|
||
;.TTGET
|
||
;GET THE TTY, THE ARGUMENT IS A TTY CAPABILITY
|
||
;HANGS UNTIL IT CAN GET THE TTY
|
||
ETTGET: JSR PC,RETNSW ;GET THE CAPABILITY NO. OF A TTY CAP.
|
||
MOV A,B ;GET THE TTY NO.
|
||
BIC #177400,B ;CLEAR THE EXTRA BITS
|
||
TTGET1: MOV ITM1A,A
|
||
JSR PC,GCLSTA ;FIND THE CAPABILITY
|
||
BEQ TTGIV1 ;COULDN'T FIND IT
|
||
ADD B,A ;MAKE A POINT TO THE CAPABILITY
|
||
CMPB (A),#.TTCAP ;IS IT A TTY CAP
|
||
BNE TTGIV1 ;NO, HE IS A LOSER
|
||
MOV 2(A),E ;GET THE TTY ITEM NO.
|
||
MOV CURSPH,C ;THE CURRENT SPHERE
|
||
TTGET2: MOV E,A ;THE TTY NUMBER
|
||
JSR PC,ITM1PL ;LOAD THE TTY ITEM
|
||
MOV TTITM(A),D ;THE CURRENT OWNER OF THE TTY
|
||
MOV D,A
|
||
CMP C,A ;DO I ALREADY OWN IT
|
||
BEQ TTGET5 ;YES, SUCCEED
|
||
TTGET3: JSR PC,ITM1LD ;LOAD THE ITEM
|
||
MOV SMSSPT(A),A ;THE MASTER OF THIS SPHERE
|
||
CMP A,C ;IS ITS SUPERIOR THE REQUESTOR
|
||
BEQ TTGET4 ;SUCESS
|
||
CMP SYSSPR,A ;ARE WE AT THE ROOT OF THE SPHERE STRUCTURE
|
||
BNE TTGET3 ;LINK THROUGH TO THE NEXT SPHERE
|
||
JSR PC,ITM1PO ;CLEAN UP THE STACK
|
||
JSR PC,LFLUSH ;GET RID OF YOURSELF FOR A LONG TIME
|
||
BR TTGET2 ;TRY AGAIN
|
||
TTGET4: MOV E,A ;THE TTY ITEM
|
||
JSR PC,ITM2LD ;LOAD IT UP
|
||
MOV A,B ;POINTER TO THE TTY ITEM
|
||
MOV D,A ;THE SPHERE THAT CURRENTLY OWNS IT
|
||
JSR PC,ITM1LD ;LOAD THE OWNER OF THE TTY
|
||
MOV TTYST1(B),STTFG1(A) ;STORE THE FLAGS
|
||
MOV TTYST2(B),STTFG2(A) ;STORE THE OTHER FLAGS
|
||
MOV CURUSR,TTYU(B) ;SET THE USER
|
||
MOV CURSPH,A ;THE NEW OWNER OF THE TTY
|
||
MOV A,TTITM(B) ;NOW EVERYONE KNOWS
|
||
JSR PC,ITM1LD ;LOAD THE NEW OWNER
|
||
MOV STTFG1(A),TTYST1(B) ;SET IN THE OLD FLAGS
|
||
MOV STTFG2(A),TTYST2(B) ;SET UP OTHER OLD FLAGS
|
||
.IFNZ NPC
|
||
MOV D,C ;THE OLD OWNER
|
||
JSR PC,SPRRPC ;AND HE GETS PCLOSERED
|
||
.IFF
|
||
MOV D,A ;THE OLD OWNER
|
||
JSR PC,SPRPCL ;AND HE GETS PCLOSERED
|
||
.ENDC
|
||
TTGET5: JSR PC,ITM1PO ;THIS WAS PUSHED SOMEWHERE
|
||
MOV ITM1A,A ;POINT TO THE SPHERE
|
||
CLR SIFTTY(A) ;NO INFERIOR NOW
|
||
JMP ERETCZ
|
||
;.SLEEP:
|
||
;1 ARG IS TOP 2 WORDS ON STACK (LOW ORDER IS TOP WORD)
|
||
;NEGATIVE=>NEGATIVE OF SYSTEM TIME TO CONTINUE
|
||
;POSITIVE=>NUMBER OF 60THS TO SLEEP
|
||
ESLEEP: MOV PUP(A),B ;GET HIS PDL POINTER
|
||
MFPD (B) ;GET TOP WORD
|
||
MOV (P),C ;SAVE IT IN C
|
||
MTPD (B)+ ;MAKE SURE WE CAN WRITE IT
|
||
MFPD (B) ;GET HIGH ORDER WORD
|
||
MOV (P),D ;SAVE IT IN D
|
||
MTPD (B) ;MAKE SURE WE CAN WRITE IT
|
||
MOV #4,PUPDLO(A) ;POP 2 THINGS IF SUCESSFUL
|
||
TST D ;IS IT NEGATIVE?
|
||
BLT ESLEE1 ;YES, GO SEE IF IT'S TIME YET
|
||
NEG C ;NEGATE DOUBLE WORD NUMBER
|
||
ADC D
|
||
NEG D
|
||
SUB TIME,C ;NOW COMPUTE NEGATIVE TIME TO WAKE UP
|
||
SBC D
|
||
SUB TIME+2,D
|
||
SAVE D ;NOW CLOBBER USER'S THING TO NEGATTIVE
|
||
MTPD (B) ;CLOBBER HIGH ORDER
|
||
SAVE C
|
||
MTPD -(B)
|
||
ESLEE1: JSR PC,ESLEEC ;CHECK IF TIME IS UP
|
||
BLT ESLEE4 ;NOPE SLEEP SOME MORE
|
||
JMP ERETCZ ;TIME IS UP, GO AWAY
|
||
ESLEE4: JSR PC,SFLUSH ;NOT LONG
|
||
ESLEE3: JSR PC,ESLEEC ;WELL, TIME UP NOW?
|
||
BLT ESLEE4 ;NOPE
|
||
JSR PC,RUNME ;ALL DONE
|
||
JMP ERETCZ ;GO RETURN TO USER
|
||
ESLEEC: MOV C,A ;COPY TIME TO WAKE UP
|
||
MOV D,B
|
||
ADD TIME,A
|
||
ADC B
|
||
ADD TIME+2,B
|
||
RTS PC
|
||
|
||
;RETURN THE SYSTEM STATUS BLOCK TO THE GUY AT THE PLACE HE PASES TO US
|
||
ESSTAT: JSR PC,RETNSW ;GET THE ONE ARGUMENT
|
||
MOV #SSTATS,B ;POINTER TO THE BLOCK WE GIVE HIM
|
||
MOV #NSTATS,C ;AMOUNT OF STUFF TO GIVE HIM
|
||
ESSTA1: MFPD (A) ;YEAH DEC!
|
||
MOV (B)+,(P) ;WHAT I REALLY WANT TO DO
|
||
MTPD (A)+ ;IS GIVE IT TO HIM
|
||
SOB C,ESSTA1
|
||
JMP ERETCZ
|
||
;.QUNLK
|
||
;THE FIRST ARG IS THE CAPABILITY NO. OF THE QUE CAP
|
||
EQUNLK: JSR PC,RETNSW ;GET THE FIRST ARG
|
||
MOV A,B ;GET THE CAP. NO
|
||
BIC #177400,B ;CLEAR THE SILLY BITS
|
||
MOV ITM1A,A ;THE ADDRESS OF THE SPHERE
|
||
JSR PC,GCLSTA ;FIND THE CAPABILITY
|
||
ERRORC EQ,BCN
|
||
ADD B,A ;MAKE A POINT TO THE CAPABILITY
|
||
CMPB (A),#.QUCAP ;IS IT A QUE CAPABILITY
|
||
ERRORC NE,BCT
|
||
MOV 2(A),A ;THE ITEM NO OF THE QUE
|
||
JSR PC,ITM2LD ;LOAD IT UP
|
||
INC QUENUM(A) ;UNLOCK (FEATURE: IF NEVER LOCKED, INCREASES MAX LOCKS)
|
||
JSR PC,QUECHK ;SHORT FLUSH FIRST GUY ON QUQUE
|
||
JMP ERETCZ
|
||
|
||
QUECHK: TST QUENUM(A) ;CAN ANYONE WIN?
|
||
BNE QUECH2 ;YES
|
||
QUECH1: RTS PC ;NO
|
||
QUECH2: TST QUECNT(A) ;IS ANYONE WAITING?
|
||
BEQ QUECH1 ;NO
|
||
MOV QUEQUE(A),A ;GET THE FIRST GUY WHO CAN WIN
|
||
JSR PC,ITM0PL ;LOAD HIM
|
||
SAVE <B,C>
|
||
MOV PRSID1(A),B ;ID WORD 1
|
||
MOV PRSID2(A),C ;ID WORD 2
|
||
MOV ITEM0,A ;THE ITEM
|
||
JSR PC,PRSWAK ;SET IT TO WAKE UP
|
||
REST <C,B>
|
||
JMP ITM0PO ;POP HIM OFF
|
||
|
||
;REMOVE THE GUY IN ITEM0 FROM THE QUE POINTED TO BY A
|
||
;IF HE HAS IT LOCKED, START SOMEONE ELSE, OTHERWISE JUST
|
||
;REMOVE HIM
|
||
PCQUNL: SAVE A
|
||
MOV QUECNT(A),F ;THE NUMBER OF PEOPLE ON THE QUE
|
||
BEQ QUNLK7
|
||
MOV F,A ;COPY THE COUNT
|
||
MOV F,C ;COPY IT AGAIN
|
||
ASL A ;TURN IT INTO A WORD INDEX
|
||
ADD (P),A ;MAKE IT LESS RELATIVE
|
||
ADD #QUEQUE,A ;MAKE A POINT TO THE START OF THE QUE
|
||
MOV ITEM0,B ;THE PERSON TO LOOK FOR
|
||
QUNLK1: CMP -(A),B ;IS HE HERE
|
||
BEQ QUNLK2 ;YES
|
||
SOB C,QUNLK1 ;TRY THE NEXT QUE ENTRY
|
||
QUNLK7: REST A
|
||
SEZ ;SAY HE WASN'T HERE
|
||
RTS PC
|
||
QUNLK2: SUB F,C ;THE NUMBER OF PEOPLE AFTER HIM
|
||
NEG C ;MAKE THE COUNT POSITIVE
|
||
SAVE C ;SAVE THE COUNT
|
||
BEQ QUNLK4 ;NOBODY AFTER HIM ON THE QUE
|
||
QUNLK3: MOV 2(A),(A)+ ;MOVE EVERYONE UP ONE SLOT ON THE QUE
|
||
SOB C,QUNLK3
|
||
QUNLK4: REST <C,A>
|
||
DEC QUECNT(A) ;ONE LESS PERSON ON THE QUE
|
||
JSR PC,QUECHK
|
||
QUNLK6: CLZ
|
||
RTS PC
|
||
;.QULK,;THE FIRST ARG IS THE CAPABILITY NO OF THE QUE TO LOCK
|
||
EQULK: JSR PC,RETNSW ;GET THE CAPABILITY NO
|
||
MOV A,B
|
||
BIC #177400,B ;CLEAR THE EXTRA BITS
|
||
MOV ITM1A,A
|
||
JSR PC,GCLSTA ;GET THE CAPABILITY
|
||
ERRORC EQ,BCN ;BAD C-LIST NUMBER
|
||
ADD B,A ;MAKE A POINT TO THE CAP
|
||
CMPB (A),#.QUCAP ;IS IT A QUE
|
||
ERRORC NE,BCT ;BAD TYPE
|
||
MOV 2(A),A ;THE ITEM NO OF THE QUE
|
||
JSR PC,ITM2LD ;LOAD IT
|
||
QULK5: MOV QUECNT(A),C ;THE NUMBER OF PEOPLE ON THE QUE
|
||
CMP C,QUEENO(A) ;IS THERE ROOM FOR ONE MORE
|
||
BEQ QULK4 ;NO, ENLARGE THE QUE
|
||
INC QUECNT(A) ;ONE MORE PERSON ON THE QUE
|
||
ASL C ;CHANGE IT INTO A WORD INDEX
|
||
ADD A,C ;MAKE C POINT TO THE QUE ENTRY (ALMOST)
|
||
MOV PRUNNG,QUEQUE(C) ;PUT HIM ON THE QUE
|
||
MOV ITEM2,B ;THE Q ITEM
|
||
MOV #LSPPCL,A ;RUN IF PCLOSERED
|
||
JSR PC,LOCKSW ;LOCK IT
|
||
MOV #PCQUNL,LCKWD1(A) ;FLUSH HIM FROM Q IF PCLOSERED
|
||
QULK9: MOV ITM2A,A
|
||
TST QUENUM(A) ;CAN I LOCK IT?
|
||
BEQ QULK1 ;NO, FULL
|
||
CMP PRUNNG,QUEQUE(A) ;AM I FIRST?
|
||
BNE QULK3 ;NO, SOMEONE ELSE BEFORE ME
|
||
DEC QUENUM(A) ;LOCK
|
||
DEC QUECNT(A) ;ONE LESS WAITING
|
||
BEQ QULK2 ;NO ONE WAITING NOW
|
||
MOV QUECNT(A),B
|
||
MOV A,C
|
||
ADD #QUEQUE,C
|
||
1$: MOV 2(C),(C)+ ;COPY ME OUT OF WAITING LIST
|
||
SOB B,1$
|
||
QULK2: JSR PC,LSWPOP ;FLUSH THE SWITCH
|
||
JSR PC,QUECHK ;START ANYONE ELSE
|
||
JMP ERETCZ
|
||
QULK3: JSR PC,QUECHK
|
||
MOV ITM2A,A
|
||
QULK1: JSR PC,LFLUSH ;WAIT A LONG TIME
|
||
TST QUENUM(A) ;CAN IT BE LOCKED?
|
||
BEQ QULK1 ;NOPE, WAIT
|
||
JSR PC,RUNME ;GIVE IT A TRY
|
||
BR QULK9
|
||
QULK4: MOV QUEENO(A),A ;THE NUMBER OF ENTRIES IN THE QUE
|
||
ASH #-6,A ;TURN IT INTO A ITEM SIZE
|
||
INC A ;WE WANT TO MAKE IT ONE SIZE LOARGER
|
||
MOV (P),B ;THE IUTEM NO FOR EXITEM
|
||
JSR PC,EXITEM ;EXPAND THE QUE
|
||
ERRORC EQ,NIT ;NO ITEM SPACE AVAILABLE
|
||
QULK6: ADD #32.,QUEENO(A) ;MADE IT 16. ENTRIES LARGER
|
||
BR QULK5 ;GO TRY TO LOCK IT
|
||
|
||
;.FONT CALL
|
||
;FIRST ARG IS FUNCTION,,FONT #
|
||
;SECOND ARG IS POINTER INTO USER CORE
|
||
;FUNCTION 0=> READ FONT INTO USER
|
||
;FUNCTION .PRWRT=> WRITE FONT FROM USER CORE
|
||
.IFNZ NTVS
|
||
EFONT: JSR PC,RETNSW ;GET THE FIRST ARG
|
||
MOV A,B ;SAVE IT
|
||
BIC #177400,A ;GET THE FONT #
|
||
CMP #NFONTS,A
|
||
ERRORC LE,BAD
|
||
SAVE A ;SAVE THE FONT NUMBER
|
||
JSR PC,RETNSW ;GET SECOND (USER ADDRESS)
|
||
SAVE A
|
||
BIT #.PRWRT*400,B ;WRITE TO USER OR FONT?
|
||
BNE EFONT9 ;GO TO WRITE THE FONT
|
||
BIC #177400,B
|
||
ASL B ;MAKE A WORD ADDRESS
|
||
MOV FNTITM(B),A ;GET THE FONT ITEM NUMBER
|
||
JSR PC,ITM2LD
|
||
;NOTE THAT IN CASE OF PCLOSERING, WE DO ALL THIS WORK AGAIN,
|
||
;BUT AT LEAST NO HARM IS DONE. BESIDES, IF THE FONT IS BEING
|
||
;READ INTO ONLY ONE PAGE, IT CAN ONLY LOSE THE FIRST TIME
|
||
;OF COURSE, IF THE USER BITES THE BAG, HIS POINTER DOESN'T POINT
|
||
;THE FACT OUT TO HIM.
|
||
MOV FNTEND(A),C ;GET THE END POINTER FOR THE FONT
|
||
BLE EFNTL ;CALL FAILS IF FONT NOT THERE
|
||
REST B ;GET BACK THE USER'S ADDRESS
|
||
ASR C ;FOR THE SOB
|
||
EFONT8: MFPD (B) ;LET'S HEAR IT FOR DEC!
|
||
MOV (A)+,(P) ;AND THE WORD JUST KEEP ON COMING!
|
||
MTPD (B)+ ;AND GOING
|
||
SOB C,EFONT8 ;LOTS OF TIMES
|
||
TST (P)+
|
||
JMP ERETCZ ;WIN
|
||
|
||
|
||
;THIS PART READS IN A FONT FROM USER
|
||
EFONT9: ADD #FNWIDE,A ;SET THE POINTER TO THE WIDTH
|
||
MFPD (A)+ ;GET WIDTH
|
||
REST C ;C WILL HOLD IT FOR A WHILE
|
||
CMP #16.,C
|
||
BLT EFNTL ;CAN'T HAVE A WIDTH OVER 16!
|
||
MFPD (A)+ ;HOW HIGH?
|
||
REST E ;E WILL KEEP THAT FOR A MINUTE
|
||
CMP #454.,E ;HIGHT OF SCREEN!
|
||
BLT EFNTL ;DON'T BE SILLY
|
||
MFPD (A)+ ;END OF FONT (LENGTH IN BYTES)
|
||
REST D ;KEEP IN D
|
||
CMP #20000,D ;IS IT MORE THAN 4K?
|
||
BLT EFNTL ;WELLL.....
|
||
MFPD (A)+ ;THE NUMBER OF TV LINES IN A CHAR LINE
|
||
REST F
|
||
CMP F,E ;THIS HAD BETTER BE GREATER OR EQUAL TO HEIGHT
|
||
BLT EFNTL ;OTHERWISE CHARS WON'T FIT IN A LINE
|
||
CMP F,#454. ;IT HAD ALSO BETTER BE LESS THAN OR EQUAL TO SCREEN SIZE
|
||
BGT EFNTL ;STRANGE CHARACTERS..
|
||
MOV D,F ;COPY THE BYTE COUNT OF THE FONT
|
||
ASR F ;FOR THE SOB
|
||
MOV (P),B ;GET BACK USER POINTER
|
||
EFONT1: MFPD (B)+ ;THIS LOOP PREVENTS US FROM
|
||
TST (P)+ ;GETTING SCREWED
|
||
SOB F,EFONT1 ;BY A PAGE NOT BEING IN CORE WHEN WE WANT IT
|
||
MOV (P),B ;NOW WE WILL CHECK THE LEGALITY OF THE POINTERS
|
||
ADD #FNTPNT,B ;POINT TO THE POINTER TABLE
|
||
MOV #128.,F ;FOR THE SOB
|
||
EFONT2: MFPD (B)+ ;GET A POINTER
|
||
TST (P) ;ZERO MEANS NO CHARATCER
|
||
BEQ EFONT3 ;WHICH IS FINE
|
||
CMP #<FNTPNT+256.>,(P) ;DEFS START AFTER TABLE
|
||
BGT EFNTL0 ;UGH
|
||
CMP D,(P) ;AND END AT (D)
|
||
BLT EFNTL0
|
||
EFONT3: TST (P)+ ;YOU'RE OK, POINTER
|
||
SOB F,EFONT2 ;CHECK ALL 128. OF THEM
|
||
MOV D,A ;LENGTH IN BYTES OF THE TABLE
|
||
ASH #-6,A ;NUMBER OF BLOCKS FOR CRITEM
|
||
JSR PC,CRITEM ;CREATE AN ITEM OF THE SIZE IN A
|
||
BEQ EFNTL ;CAN'T CREATE AN ITEM
|
||
MOV B,A ;CRITEM RETURNS THE INDEX IN B
|
||
JSR PC,ITM2LD ;LOAD UP THE ITEM WE JUST CREATED
|
||
REST C ;THE USER'S ADDRESS
|
||
ASR D ;CONVERT TO WORD COUNT
|
||
EFONT4: MFPD (C)+ ;READ THE USER'S DATA
|
||
REST (A)+ ;A IS INITIALLY SET BY THE ITM2LD CALL
|
||
SOB D,EFONT4 ;KEEP MOVING UNTIL WE GET ALL OF HIS DATA
|
||
MOV #454.,D ;THE NUMBER OF LINES ON A SCREEN
|
||
CLR C ;FOR THE DIVIDE
|
||
MOV ITM2A,A ;ADDRESS OF THE FONT ITEM
|
||
MOV #ITFNT,(A) ;SET THE TYPE OF THE ITEM
|
||
DIV FNTLCL(A),C ;FIND HOW MANY LINES FIT ON A SCREEN
|
||
CMP D,FNHIGH(A) ;THE LAST LINE DOES NOT NEED SEPARATOR SPACE
|
||
BLT EFON10 ;NOT ENOUGH ROOM FOR ANOTHER LINE
|
||
INC C ;WE CAN FIT IN ONE MORE LINE
|
||
SUB FNTLCL(A),D ;GET THE AMOUNT TO ADD TO NEXT LINE TO GET TO TOP
|
||
;FALLS THROUGH
|
||
;FALLS IN
|
||
EFON10: MOV C,FNLINE(A) ;THIS MANY LINES FIT ON A SCREEN
|
||
SAVE C
|
||
MOV D,C ;FOR THE MULTIPLY
|
||
MUL #110,C ;COMPUTE THE NUMBER OF BYTES LEFT OVER AT THE BOTTOM OF SCREEN
|
||
MOV D,FNREM(A) ;THIS NUMBER MAY BE NEGATIVE IF WE SQEEZED IN AN EXTRA LINE
|
||
MOV FNTLCL(A),C ;THE NUMBER OF TV LINES IN ONE CHAR LINE
|
||
MUL #110,C ;COMPUTE THE NUMBER OF BYTES IN ONE CHAR LINE
|
||
MOV D,FLFINC(A) ;THIS IS THE LINE FEED INCREMENT
|
||
REST D ;THE NUMBER OF LINES ON SCREEN
|
||
CLR C ;FOR THE DIVIDE
|
||
DIV #5,C ;5 SEEMS TO GIVE GOOD RESULTS
|
||
MOV C,FNLSC(A) ;THE NUMBER OF LINES TO SCROLL
|
||
MOV #576.,D ;NUMBER OF BITS ON A LINE
|
||
CLR C ;FOR THE DIVIDE
|
||
DIV FNWIDE(A),C ;DIVIDE BY THE NUMBER OF BITS PER CHAR
|
||
MOV C,FNLINL(A) ;GET THE NUMBER OF CHARS PER LINE
|
||
REST C ;THE FONT NUMBER
|
||
ASL C ;CONVERT TO WORD INDEX
|
||
MOV FNTITM(C),A ;GET THE ITEM INDEX OF THE CURRENT FONT WITH THIS NUM
|
||
MOV B,FNTITM(C) ;NOW THE NEW ITEM IT THIS FONT NUMBER
|
||
TST A ;WAS ANYTHING THERE?
|
||
BEQ EFONT5 ;NO
|
||
JSR PC,DLITEM ;DELETE THE OLD FONT
|
||
EFONT5: JMP ERETCZ ;WIN
|
||
EFNTL0: ADD #2,P ;POP SOME STUFF
|
||
EFNTL: ADD #4,P ;POP GARBAGE OFF THE STACK
|
||
EFNTL1: ERROR BAD ;LOSE
|
||
.ENDC
|
||
|
||
;THIS SYSTEM CALL ALLOWS CONTROL OF THE VIDEO SWITCH. BASICALLY,
|
||
;THE FIRST ARGUMENT SETS THE SOURCE IN VARIOUS MODES, AND THE
|
||
;SECOND ARGUMENT SETS THE DESTINATION IN SIMILAR MODES. FOR
|
||
;BOTH SOURCE AND DESTINATION ARGUMENTS, THE GENERAL FORM IS
|
||
;A NUMBER IN THE LOW BYTE AND A MODE IN THE HIGH BYTE. THE SOURCE
|
||
;USUALLY MEANS THE BUFFER ASSOCIATED WITH THE TV IMPLIED BY THE
|
||
;THE MODE AND NUMBER EXCEPT ABSOLUTE GOES DIRECTLY TO THE SWITCH.
|
||
;THE MODES ARE:
|
||
;.VIABS => JUST PUT THE NUMBER INTO THE APPROPRIATE PART OF SWITCH
|
||
;.VILOT => THE NUMBER IS THE LOGICAL NUMBER OF A TTY
|
||
; THE SAME NUMBER THAT IS USED IN THE CREATE INVOK.
|
||
;.VILOD => THE NUMBER IS THE LOGICAL NUMBER OF A DISPLAY
|
||
;.VICAM => THE NUMBER IS THE INDEX OF A CAPABILITY IN THE CALLER'S
|
||
; SPHERE, WHICH IS THE TTY OR DISPLAY TO SWITCH IN.
|
||
;
|
||
;IF THE CALL FAILS, IT IS GENERALLY BECAUSE THE NUMBER IN AN
|
||
;ARGUMENT IS INAPPROPRIATE FOR THE MODE, SUCH AS A LOGICAL
|
||
;TTY NUMBER THAT IS NOT A TV TTY, OR CAPABILITY THAT IS NOT
|
||
;THE APPROPRIATE TYPE ETC.
|
||
.IFNZ NTVS
|
||
EVIDSW: JSR PC,RETNSW ;GET THE FIRST ARGUMENT, THE SOURCE
|
||
MOV A,C ;THE VALUE IS RETURNED IN A
|
||
JSR PC,RETNSW ;GET THE SECOND ARG, THE DESTINATION
|
||
MOV A,D ;SAVE VALUE IN D
|
||
SWAB A ;GET DESTINATION MODE IN LOW BYTE
|
||
BIC #177600,D ;ISOLATE THE DESTINATION NUMBER
|
||
CMPB A,#.VICAM ;IS IT CAPABILITY MODE
|
||
BNE EVIDS2 ;NO
|
||
MOV D,B ;THE DESTINATION NUMBER IS CAPABILITY INDEX
|
||
MOV ITM1A,A ;ADDRESS OF THE SPHERE ITEM
|
||
JSR PC,GCLSTA ;GET THE OFFSET OF THE CAPABILITY INTO SPHERE
|
||
BEQ EVID15 ;ERROR, BAD CAPABILITY NUMBER
|
||
ADD A,B ;CONVERT OFFSET TO ABSOLUTE ADDRESS
|
||
CMPB (B),#.TTCAP ;IS DESTINATION A TTY?
|
||
BNE EVIDS1 ;NO
|
||
MOV CLSEPI(B),A ;THE TTY ITEM
|
||
JSR PC,ITM2LD ;LOAD IT UP
|
||
MOV TTLTTY(A),D ;THE LOGICAL TTY NUMBER - WORD OFFSET VERSION
|
||
ASR D ;CONVERT WORD OFFSET VERSION TO NUMBER
|
||
BR EVIDS3 ;CONTINUE LIKE LOGICAL TTY NUMBER
|
||
EVIDS1: CMPB (B),#.DSCAP ;IS DESTINATION A DISPLAY?
|
||
BNE EVID15 ;NO, BAD CAPABILITY TYPE ERROR
|
||
MOV CLSEM0(B),A ;THE LOGICAL DISPLAY NUMBER - WORD OFFSET
|
||
ASR A ;CONVERT WORD OFFSET VERSION TO NUMBER
|
||
BR EVIDS5 ;NOW CONTINUE LIKE LOGICAL DISPLAY NUMBER
|
||
EVIDS2: CMPB A,#.VILOT ;IS MODE LOGICAL TTY NUMBER MODE
|
||
BNE EVIDS4 ;NO
|
||
EVIDS3: SUB #NFTV/2,D ;CONVERT TO PHYSICAL TV NUMBER
|
||
BLT EVID15 ;ERROR, THIS TTY IS NOT A TV TTY
|
||
CMP D,#NTVS ;MAKE SURE ITS A VALIDE TV NUMBER
|
||
BGE EVID15 ;NO, BAD TTY NUMBER ERROR
|
||
ASL D ;GET WORD OFFSET
|
||
MOV TVMAP(D),D ;ARRANGE TO GET THE CORRECT MONITOR
|
||
BR EVIDS7 ;NOW PROCESS THE SOURCE ARGUMENT
|
||
EVIDS4: CMPB A,#.VILOD ;IS MODE LOGICAL DISPLAY NUMBER MODE
|
||
BNE EVIDS6 ;NO
|
||
EVIDS5: SUB #NFTVDS,D ;GET PHYSICAL TV NUMBER
|
||
BLT EVID15 ;BAD DISPLAY TYPE, MUST BE A TK DISPLAY
|
||
CMP D,#NTVS ;MAKE SURE THIS NUMBER IS LEGAL
|
||
BGE EVID15 ;ERROR, BAD DISPLAY NUMBER
|
||
ASL D ;GET WORD OFFSET
|
||
MOV TVMAP(D),D ;ARRANGE TO GET RIGHT MONITOR
|
||
BR EVIDS7 ;NOW PROCESS THE SOURCE ARGUMENT
|
||
EVIDS6: CMPB A,#.VIABS ;ABSOLUTE MODE?
|
||
BNE EVID15 ;NO, THERE ARE NO MORE LEGAL MODES SO ERROR
|
||
EVIDS7: MOV C,A ;GET SOURCE MODE
|
||
SWAB A ;GET MODE IN LOW BYTE
|
||
BIC #177600,C ;ISOLATE THE SOURCE NUMBER
|
||
CMPB A,#.VICAM ;CAPABILITY MODE?
|
||
BNE EVIDS9 ;NO
|
||
MOV C,B ;THE CAPABILITY NUMBER
|
||
MOV ITM1A,A ;SPHERE ITEM ADDRESS
|
||
JSR PC,GCLSTA ;GET THE OFFSET INTO THE SPHERE OF CAPABILITY
|
||
BEQ EVID15 ;BAD CAPABILITY NUMBER ERROR
|
||
ADD A,B ;GET THE ABSOLUTE ADDRESS OF CAPABILITY
|
||
CMPB (B),#.DSCAP ;IS IT A DISPLAY CAPABILITY?
|
||
BNE EVIDS8 ;NO
|
||
MOV CLSEM0(B),C ;GET LOGICAL DISPLAY NUMBER
|
||
ASR C ;CONVERT FROM WORD OFFSET VERSION TO NUMBER
|
||
BR EVID10 ;CONTINUE AS LOGICAL DISPLAY NUMBER
|
||
EVIDS8: CMPB (B),#.TTCAP ;IS CAPABILITY A TTY CAP?
|
||
BNE EVID15 ;BAD CAPABILITY TYPE ERROR
|
||
MOV CLSEPI(B),A ;GET THE TTY ITEM
|
||
BR EVID12 ;GET THE BUFFER ASSOCIATED WITH THIS TTY
|
||
EVIDS9: CMPB A,#.VILOD ;IS SOURCE MODE LOGICAL DISPLAY?
|
||
BNE EVID11 ;NO
|
||
EVID10: SUB #NFTVDS,C ;MAKE SURE IT'S A TV DISPLAY
|
||
BLT EVID15 ;ERROR, MUST BE A TK DISPLAY
|
||
CMP C,#NTVS ;MAKE SURE IT'S A VALID TV NUMBER
|
||
BGE EVID15 ;ERROR, IT'S NOT
|
||
MOVB TVDSBF(C),C ;GET THE BUFFER ASSIGNED TO THIS DISPLAY
|
||
BLT EVID15 ;NO BUFFER ASSIGNED TO THIS DISPLAY
|
||
BR EVID14 ;SWITCH IN THE NUMBERS
|
||
EVID11: CMPB A,#.VILOT ;IS SOURCE LOGICAL TTY NUMBER MODE?
|
||
BNE EVID13 ;NO
|
||
CMP C,#NTTYS ;IS THIS A VALID TTY NUMBER?
|
||
BGE EVID15 ;NO, ERROR
|
||
TST C ;MAKE ABSOLUTELY SURE
|
||
BLT EVID15 ;AHA! IT'S NEGATIVE, THEREFOR ERROR
|
||
ASL C ;CONVERT TO WORD OFFSET
|
||
MOV TTYITM(C),A ;GET THE ITEM FOR THIS TTY
|
||
BLE EVID15 ;THIS TTY HAS NO ITEM
|
||
EVID12: JSR PC,ITM2LD ;LOAD IT UP
|
||
MOV TVBUF(A),C ;GET THE BUFFER NUMBER FOR THIS TTY
|
||
BLT EVID15 ;ERROR, NO BUFFER ATTACHED TO THIS TTY
|
||
BIC #TVMOV,C ;CLEAR OUT THE ALU FUNCTION
|
||
BR EVID14 ;GO AHEAD AND SWITCH IN THE ARGUMENTS
|
||
EVID13: CMPB A,#.VIABS ;IS IT ABSOLUTE MODE?
|
||
BNE EVID15 ;NO MORE MODES, THUS ERROR
|
||
EVID14: SWAB D ;DESTINATION GOES IN HIGH BYTE
|
||
BIS D,C ;SOURCE IN LOW BYTE
|
||
MOV C,VIDSW ;SWITCH IT
|
||
JMP ERETCZ ;THAT'S ALL FOLKS.
|
||
EVID15: ERROR BAD ;SOMETHING WENT WRONG
|
||
|
||
;INVOK OF COLOR MAP
|
||
CAPRCM: TST (P)+ ;GET RID OF LAST ARG
|
||
REST <E,F> ;GET THE ONES WE NEED
|
||
BLT CPRCM1 ;BRANCH TO SET UP CORESPONDENCE
|
||
MOV #.CMRED!.CMGRN!.CMBLU,D ;SET UP FOR XOR
|
||
XOR D,F ;SO THEY LOOK SENSIBLE TO THE USER
|
||
MOV E,COLORD ;VALUE TO SET TO
|
||
MOV F,COLORA ;ADDRESS TO SET
|
||
|
||
CPRCM1: MOVB E,B ;COPY CAP NUMBER
|
||
MOV ITM1A,A ;POINT TO SPHERE
|
||
JSR PC,GCLSTA ;GET CAP
|
||
ERRORC EQ,BCN
|
||
ADD A,B ;POINT TO IT
|
||
CMPB (B),#.DSCAP ;IS IT A DISPLAY?
|
||
ERRORC NE,BCT ;NOPE
|
||
MOV CLSEM0(B),C ;GET DISPLAY NUMBER
|
||
ASR C ;CONVERT TO NUMBER
|
||
SUB #NFTVDS,C ;GET TV NUMBER
|
||
ERRORC LT,BCT ;OOOPS, IT IS A TK DIS
|
||
MOVB TVDSBF(C),C ;GET TV BUFFER NUMBER
|
||
ERRORC LT,BCT ;NO BUFFER?
|
||
|
||
|
||
|
||
|
||
|
||
|
||
|
||
|
||
|
||
|
||
|
||
.ENDC
|
||
|
||
.SBTTL INVOKE CAPABILITY ROUTINES
|
||
CAPRCC: TST (P)+ ;ONLY WANT TWO ARGS
|
||
ASL C ;THE CAPABILITY TYPE TO CREATE
|
||
CMP C,#CAPHGH ;IS HE ASKING FOR A NON-EXISTANT TYPE?
|
||
BGE CAPRC1 ;LOSER!
|
||
ADD #CCTAB,C
|
||
CPYCA1: MOV E,D ;CAP NUMBER
|
||
MOV 2(P),B ;CAP DESTINATION
|
||
MOV (P)+,(P) ;SECOND ARG
|
||
SAVE <C> ;ADDRESS OF ROUTINE
|
||
MOV ITEM1,C
|
||
JSR PC,CRCLST
|
||
BEQ CAPRC4 ;THE C-LIST ENTRY WAS USED
|
||
BCS CAPRC1 ;FULL C-LIST
|
||
ADD ITM1A,A ;MAKE A POINT ABSOLUTELY TO ENTRY
|
||
REST <C,E> ;ROUTINE ADDRESS AND SECOND ARG
|
||
SAVE <B,A>
|
||
MOV #-1,(A)+ ;SAVE THIS SPACE
|
||
CLR (A)+
|
||
CLR (A)+
|
||
CLR (A)+
|
||
CLR (A)+
|
||
MOV #LSPPCL,A
|
||
MOV ITEM1,B
|
||
JSR PC,LOCKSW
|
||
MOV (P),LCKWD2(A)
|
||
MOV #CAPRC5,LCKWD1(A)
|
||
MOV C,A ;ROUTINE ADDRESS
|
||
CLR C
|
||
JSR PC,@(A)
|
||
;THE ROUTINE WE CALL IS EXPECTED TO RETURN:
|
||
;IN A THE CAP TYPE AND FLAGS
|
||
;IN B THE PRIMARY ITEM
|
||
;THE SECONDARY ITEM IS NEVER RETURNED
|
||
;IN C THE FIRST MISC WORD
|
||
;THE SECOND MISC WORD IS NEVER RETURNED
|
||
;THE ROUTINE SHOULD SET Z IF IT FAILS, OTHERWISE CLEAR IT
|
||
BEQ CAPRC3 ;FAILURE
|
||
REST F
|
||
MOV A,(F)+ ;THE TYPE AND FLAGS
|
||
MOV B,(F)+ ;THE PRIMARY ITEM
|
||
TST (F)+ ;NO SECONDARY ITEM
|
||
MOV C,(F)+ ;THE 1ST MISC WORD
|
||
REST <B>
|
||
JSR PC,GIVPSW
|
||
JSR PC,LSWPOP ;LOCK ON CAP
|
||
JMP ERETCZ ;SUCESS
|
||
CAPRC1: CMP (P)+,(P)+
|
||
CAPRC2: JMP BADEMT
|
||
CAPRC3: CLR @(P) ;FREE CAP SLOT
|
||
CAPRC4: ERROR BCN ;FAIL
|
||
CAPRC5: MOV LCKWD2(B),B
|
||
CLR (B) ;RELEASE CAP SPACE
|
||
RTS PC
|
||
.SBTTL START THE WORLD ROUTINE
|
||
GO: RESET
|
||
MOV #PDL,P ;SET UP THE PDL
|
||
MOV #RUGVEC,A ;POINTER TO VECTOR STORAGE
|
||
MOV #BPTBRV,B ;THE VECOTR
|
||
MOV (B),(A)+ ;THE STUFF
|
||
MOV #BPTBRK,(B)+ ;SET UP OUR VECTOR
|
||
MOV (B),(A)+ ;STORE STATUS
|
||
MOV #340,(B)+ ;SET UP INFINITE PRIORITY
|
||
JSR PC,PARIN ;INITIALIZE THE PARITY STUFF
|
||
JSR PC,TYINIT ;INITIALIZE THE TTY'S
|
||
JSR PC,MAPSET ;SET UP THE INTIAL MAP
|
||
JSR PC,INITTB ;LINK UP LISTS
|
||
JSR PC,MEMTST ;SET UP MEMORY TABLES
|
||
JSR PC,CLKIN ;START UP THE CLOCK
|
||
;FALL THROUGH TO NEXT PAGE TO START UP THE SYSTEM PROCESS, ETC.
|
||
;FALLS IN FROM PREVIOUS PAGE
|
||
;START UP THE SYSTEM PROCESS
|
||
JSR PC,CRUSER ;CREATE A USER
|
||
MOV B,CURUSR ;HE IS THE CURRENT USER
|
||
MOV #2,PRTPRI(B) ;INCREASE HIS PRITORITY
|
||
JSR PC,CRSPHR ;CREATE A SPHERE FOR HIM
|
||
MOV A,SYSSPR ;THE SYSTEM SHPERE
|
||
MOV A,C ;SAVE THE SPHERE ITEM#
|
||
JSR PC,CRPROC ;CREATE A PROCESS
|
||
MOV C,B ;PUT THE SPHERE ITEM IN THE RIGHT PLACE
|
||
JSR PC,PUTPRS ;PUT THE PROCESS INTO THE SPHERE
|
||
MOV A,D ;SAVE THE PROCESS ITEM
|
||
JSR PC,ITM0LD ;MAKE PROCESS ITEM 0
|
||
MOV A,C ;SAVE ADDRESS
|
||
MOV B,A ;GET SPHERE ITEM #
|
||
JSR PC,ITM1LD ;MAKE SPHERE ITEM1
|
||
ADD #SUPTS,A ;GET A POINTER TO THE UPTS
|
||
MOV #20,D ;THERE ARE 20 PAGES
|
||
CLR E ;WE WILL SET UP MAP TO ABS CORE FOR THIS SPHERE
|
||
SYSJI1: MOV #UPTABS,(A)+ ;AN ABSOLUTE PAGE
|
||
MOV E,(A)+ ;THE AR
|
||
MOV #77406,(A)+ ;THE DR
|
||
ADD #200,E ;GO TO NEXT PAGE
|
||
BIC #176000,E ;FOR THE OVERFLOW INTO I SPACE
|
||
SOB D,SYSJI1 ;DO FOR 20 PAGES
|
||
CLR B ;CAPABILITY ZERO
|
||
JSR PC,AGCLAD ;GO GET THE ADDRESS
|
||
MOV #.CCCAP,(A) ;A CREATE CAPABILITY CAPABILITY
|
||
MOV #1,B ;CAPABILITY ONE
|
||
JSR PC,AGCLAD ;GO GET THE ADDRESS
|
||
MOV #.MSCAP,(A) ;MAKE IT A MASTER SPHERE CAPABILITY TO ITSELF (!!!!)
|
||
BIS #MSPCBT!.SPFES,(A)+ ;EVERYTHING AND NO ENTERS
|
||
MOV SYSSPR,(A) ;THSI IS IT
|
||
MOV #30.,E ;THE NUMBER OF SLOTS OF USERS TO TRY TO START
|
||
SAVE C ;SO THAT IT DOESN'T GET CLOBBERED
|
||
JSR PC,CCPRCL ;CREATE A CORE LINK
|
||
REST C
|
||
MOV B,TTYCL ;SET UP POINTER TO THE CORE LINK FOR TTY ROUTINES
|
||
MOV #2,B ;THE CAPABILITY 2
|
||
JSR PC,AGCLAD ;GET THE ADDRESS
|
||
MOV #.CLCAP!.CLCONS,(A)+ ;SET IN THE FLAGS
|
||
MOV TTYCL,B ;GET THE POINTER TO IT
|
||
MOV B,(A)+ ;SET IT IN
|
||
MOV B,A ;GET IT
|
||
JSR PC,ITM2LD ;LOAD IT
|
||
MOV ITEM0,CLCONP(A) ;SET IN CONSUMER POINTER
|
||
MOV #SYSJOB,PUPC(C) ;SET THE THINGS PROGRAM COUNTER
|
||
MOV #SYSJPD,PUP(C) ;AND ITS PDL POINTER
|
||
BIC #PSUPSB,PSTOP(C) ;CLEAR THE STOP BIT
|
||
MOV ITEM0,A
|
||
JSR PC,PSTPDC ;GO DECREMENT THE STOP COUNT AND PUT ON RUN Q
|
||
MOV #5*2,HSECS ;THE WORLD STARTS 5 SECONDS AGO (RUN THAT BY AGAIN???)
|
||
CLR INITSW ;EXITING INIT CODE
|
||
JMP SCHED ;GO GO GO!
|
||
;INITIALIZE THE CLOCK THAT EXISTS TO TICK AT 60. HZ
|
||
CLKIN: SAVE BEBRV ;FIND OUT WHICH CLOCK WE HAVE
|
||
MOV #CLKIN1,BEBRV ;GO TO GOPC FOR PROGRAMMABLE CLOCK
|
||
MOV #100,LCCS ;TRY TO START THE LINE CLOCK
|
||
BR CLKIN2 ;WON'T GET HERE IF UNSUCESSFUL
|
||
CLKIN1: SPL 0 ;IN CASE SET BY THE BREAK
|
||
CMP (P)+,(P)+ ;FLUSH SAVED THINGS
|
||
MOV #1666.,PCCB ;WE HAD BETTER HAVE A PROGRAMMABLE CLOCK!
|
||
MOV #111,PCCS ;LINE FEQUENCY, REPEAT INT, ETC.
|
||
CLKIN2: REST BEBRV ;WE HAVE SET UP THE CLOCK
|
||
RTS PC
|
||
|
||
;INIT THE TABLES AND HARDWARE REGISTERS ASSOCIATED WITH PARITY
|
||
PARIN: SAVE BEBRV ;TO TRAP NON-EX PARITY REGISTERS
|
||
MOV #PARIN1,BEBRV
|
||
MOV #PARREG,A ;POINT TO THE BEGINING OF THE TABLE
|
||
MOV #PARCSR,B ;POINT TO THE BEGGINING OF THE HARWARE REGISTERS
|
||
MOV B,C
|
||
MOV #20,D ;THERE MAY BE AS MANY AS 16. OF THEM
|
||
PARRCK: MOV #1,(B)+ ;ENABLE THE PARITY CHECKING
|
||
MOV C,(A)+ ;SKIPPED IF REG NOT THERE
|
||
PARIN2: ADD #2,C ;UPDATE THE POINTER TO THE REGISTER THAT IS STORED AWAY
|
||
SOB D,PARRCK
|
||
REST BEBRV
|
||
RTS PC
|
||
PARIN1: CMP (P)+,(P)+ ;CLEAR CRAP OFF STACK
|
||
SPL 0
|
||
BR PARIN2
|
||
;INITIALIZE VARIOUS TABLES
|
||
INITTB: MOV #INITLS,A ;THINGS TO LINK INTO FREE LISTS
|
||
INTLST: MOV (A)+,B ;GET THE TABLE ADDRESS
|
||
BEQ INTLS1 ;DONE WITH THESE THINGS
|
||
MOV (A)+,C ;GET THE ADDRESS OF THE FREE POINTER
|
||
MOV (A)+,D ;GET THE NUMBER OF THINGS
|
||
MOV (A)+,E ;GET THE LENGTH OF THEM
|
||
MOV B,(C) ;SET UP THE FREE POINTER
|
||
MOV B,C ;COPY POINTER INTO TABLE
|
||
INTLS2: ADD E,C ;POINTER TO NEXT ONE
|
||
MOV C,(B) ;GET PUT INTO THIS ONE
|
||
ADD E,B ;GO TO NEXT ONE
|
||
SOB D,INTLS2 ;HOWEVER MANY TIMES
|
||
BR INTLST
|
||
INTLS1: MOV #INITM1,A ;STUFF TO MAKE -1
|
||
INTM11: MOV #-1,(A)+
|
||
CMP #EINTM1,A
|
||
BNE INTM11
|
||
MOV #ITMBIT,A ;THE BIT TABLE POINTERS
|
||
MOV #ITMBTP,B
|
||
MOV #NITMBL,C
|
||
INTBT1: MOV A,(B)+ ;POINTER TO A BIT TABLE
|
||
ADD #22,A ;FURTHER ON
|
||
SOB C,INTBT1 ;FOR SO MANY BIT TABLES
|
||
RTS PC
|
||
;THIS SYSTEM CALL IS EXECUTED BY THE SYSSPR TO PROVIDE A PC
|
||
;TO DO SOME HOUSEKEEPING FUNCTIONS. IT DELETES UPTS PLACED ON THE DLU LIST
|
||
ESYSJB: JSR PC,SYSCHK
|
||
ESYSJ4: TST DLULST ;ANY ON THE LIST?
|
||
BNE ESYSJ3
|
||
JSR PC,SFLUSH
|
||
ESYSJ1: TST DLULST
|
||
BNE ESYSJ2
|
||
JSR PC,SFLUSH ;HANG
|
||
BR ESYSJ1 ;FOREVER
|
||
ESYSJ2: JSR PC,RUNME
|
||
ESYSJ3: MOV DLULST,A ;GET POINTER TO FIRST TO ACT ON
|
||
MOV DLUUPT(A),B ;GET THE UPT
|
||
JSR PC,UPTDL ;DELETE IT
|
||
INC SYSUPD ;SAY WE DID SOMETHING
|
||
MOV (A),DLULST ;FLUSH NODE FROM LIST
|
||
MOV DLUFRE,(A) ;ADD IT TO THE FREE LIST
|
||
MOV A,DLUFRE
|
||
BR ESYSJ4 ;TRY AGAIN
|
||
|
||
SYSCHK: CMP CURSPH,SYSSPR ;IS THIS THE SYSTEM SPHERE
|
||
ERRORC NE,SYS
|
||
RTS PC
|
||
|
||
SYSJOB: SAVE <#10,#MFITST,#.FACAP*400>
|
||
$INVOK ;MAKE A ROOT MFI
|
||
REST <A> ;ROOT CAP IN A
|
||
SAVE <#-1,#0,A>
|
||
BIS #.CPYCP,(P) ;COPY THE ROOT CAP
|
||
$INVOK
|
||
REST C
|
||
SAVE <#0,#MFIDSC,C>
|
||
BIS #.FAMU,(P) ;GET THE DESCRIPTOR FILE
|
||
$INVOK
|
||
SAVE <C,C> ;FOR THE WRDI
|
||
$WRDI
|
||
REST F ;GET THE BASE YEAR
|
||
$WRDI ;GET THE START
|
||
SAVE C
|
||
$WRDI ;AND LENGTH
|
||
SAVE <#0> ;DISK NUMBER
|
||
$ALLOC
|
||
SAVE <,,C> ;DELET ETHE CAP
|
||
BIS #.DELCP,(P)
|
||
$INVOK
|
||
SAVE <#-1,#0,A>
|
||
BIS #.CPYCP,(P) ;COPY THE ROOT CAP
|
||
$INVOK
|
||
REST <B> ;BITS CAP WIL BE IN B
|
||
SAVE <#0,#MFIBIT,B>
|
||
BIS #.FAMU,(P)
|
||
$INVOK
|
||
SAVE <#0,F,B>
|
||
BIS #.FAMB,(P) ;SET UP BIT TABLE
|
||
$INVOK
|
||
SAVE <,,B>
|
||
BIS #.DELCP,(P)
|
||
$INVOK ;DELETE CAP TO BITS FILE
|
||
SAVE <#-1,#0,A>
|
||
BIS #.CPYCP,(P)
|
||
$INVOK
|
||
REST C
|
||
SAVE <#0,#MFISYS,C>
|
||
BIS #.FAMU,(P) ;MUTATE THE ROOT
|
||
$INVOK
|
||
SAVE <#<7*400>,#0,#13777,#.CRWRT+1> ;SET UP FRESH PAGE IN PAGE 7-17
|
||
$MAP
|
||
MOV #ABSLD,A
|
||
MOV #<<ABSEND-ABSLOD>/2>,B ;NUMBER OF WORDS
|
||
MOV #160000,D ;TOP PAGE
|
||
1$: MOV (A)+,(D)+
|
||
SOB B,1$
|
||
MOV C,SYSFCP ;POINTER TO SYSTEM FILE CAPABILITY
|
||
SAVE <#<7*400>,#0,#10000+377,#.CRWRT+1> ;SET UP FRESH PAGE IN PAGE 0-10
|
||
$MAP
|
||
SAVE <#<7*400>,#0,#10400+377,#.CRWRT+1> ;SET UP FRESH PAGE IN PAGE 1-11
|
||
$MAP
|
||
JMP 160000 ;START IT UP
|
||
|
||
|
||
LSTILC=. ;PUT THIS AT THE LAST INSTRUCTION LOCATION
|
||
FSTFRB==<<<.!1777>+1>_-10.>&77 ;FIRST FREE BLOCK
|
||
.MACRO PAD A,B
|
||
.PRINT /A B
|
||
/
|
||
.ENDM
|
||
.IF2
|
||
PAD ^/SYSTEM END =/,\.
|
||
.IRP Y,<0,1,2,3>
|
||
.IRP X,<0.,1.,2.,3.,4.,5.,6.,7.,8.,9.>
|
||
.IIF Z <<<FSTFRB+1>/2>-Y''X>,PAD Y''X,<K>
|
||
.ENDM
|
||
.ENDM
|
||
.ENDC
|
||
.END GO
|