From 09b703a29e0f78f197fa07c5a886d7b06b9c37d4 Mon Sep 17 00:00:00 2001 From: Lars Brinkhoff Date: Fri, 21 Oct 2022 18:10:50 +0200 Subject: [PATCH] SYSSPR - System Sphere for SITS. --- build/misc.tcl | 4 + build/timestamps.txt | 2 + src/sits/sitss.syms | 250 ++++++ src/sits/sysspr.238 | 1914 ++++++++++++++++++++++++++++++++++++++++++ 4 files changed, 2170 insertions(+) create mode 100755 src/sits/sitss.syms create mode 100755 src/sits/sysspr.238 diff --git a/build/misc.tcl b/build/misc.tcl index 46e1b51f..504f4649 100644 --- a/build/misc.tcl +++ b/build/misc.tcl @@ -1638,6 +1638,10 @@ expect ":KILL" respond "*" ":palx salv\r" expect ":KILL" +# System Sphere for SITS. +respond "*" ":palx sysspr\r" +expect ":KILL" + # TORTIS respond "*" ":midas;324 radia;_tortis\r" expect ":KILL" diff --git a/build/timestamps.txt b/build/timestamps.txt index 73778b56..0914c386 100644 --- a/build/timestamps.txt +++ b/build/timestamps.txt @@ -1909,7 +1909,9 @@ sits/docum.66 197607010317.17 sits/salv.175 197711241704.25 sits/sitmac.6 197609212250.40 sits/sits.119 197712281629.08 +sits/sitss.syms 197711281648.44 sits/styi.207 197702231829.55 +sits/sysspr.238 197706031415.49 sits/todo.23 197509192206.00 sits/tvtty.70 197610131613.46 sra/usefmt.9 198905011133.08 diff --git a/src/sits/sitss.syms b/src/sits/sitss.syms new file mode 100755 index 00000000..9eef9fa3 --- /dev/null +++ b/src/sits/sitss.syms @@ -0,0 +1,250 @@ +.NLIST +.TIMGI==10 +.TOEDM==2 +.TIMGO==20 +.FADL==4000 +.TTIBK==400 +.TTMBK==10000 +.TVMAP==107 +.TVSAV==106 +$TTGET==104212 +.XXCAP==0 +.TTWD==40000 +.POOFF==104002 +.TTEDM==1000 +.PFIL==2000 +.FALNK==100000 +.TTGET==104012 +$FORK==104201 +.FALOK==4000 +.FARP==3000 +.TVSET==17 +$TTGIV==104211 +.TVOFF==20 +.FORK==104001 +$BYTI==104215 +.TTYI==20000 +.TTGIV==104011 +.VILOD==2 +.VILOT==1 +.PLENM==177770 +.BYTI==104015 +$VIDSW==104227 +.FARUT==10000 +.TLIPM==1000 +.TTSLN==25 +.TVCL==6 +.VIDSW==104027 +.TTCNO==4 +$FONT==104225 +$BYTO==104216 +.TICTF==20000 +.TTYO==10000 +.TMORF==100000 +.TICTM==10000 +.TMORM==40000 +.TTMOV==0 +.TVMOD==23 +.TTSPD==12 +.TVIOR==1 +.TVMOV==3 +.TICVM==400 +.PRERA==24 +.FONT==104025 +.BYTO==104016 +.PRWRA==10000 +.PRERR==22 +.PRWRT==40 +.TSCRL==1 +.FPPTF==7 +.BPTTF==3 +.TTWRT==40 +.PRSTO==21 +.TVATC==5 +.TTMV2==11 +.EBAC==2 +.EBAD==3 +.EEAE==15 +$RUG==104230 +.GIVCP==101000 +$SSTAT==104226 +$GETID==104234 +.RUG==104030 +.MSCAP==2 +.SSTAT==104026 +.SPRCP==1 +.CMRED==2000 +.GETID==104034 +.QUCAP==7 +.CRRD==400 +$SINK==104204 +.EDSKE==31 +.SPFES==4000 +.EBCN==4 +$WRDI==104213 +.SINK==104004 +.SPPGT==5 +.CMBIT==100000 +.WRDI==104013 +$GERRW==104231 +.ENUL==0 +.CMBLU==400 +.EBCT==5 +.GERRW==104031 +$WRDO==104214 +.WRDO==104014 +.EDEVE==12 +.ENIS==22 +.ENSS==24 +.ENIT==23 +.CRPRI==4000 +.ESYS==27 +.SPPTP==0 +.SPPTT==0 +$MAP==104221 +.MAP==104021 +$RDMAP==104224 +.FACAP==6 +.FAMB==7000 +.TBRAK==24 +.FAAC==40000 +.RDMAP==104024 +.FAAD==5000 +.FAMD==13000 +.FAWD==2000 +.FASDL==12000 +$FLOAT==104205 +.VICAM==3 +.DELCP==100000 +.FACF==0 +.VIABS==0 +.TIRBM==40 +.FLOAT==104005 +.PRFAU==23 +$BLKI==104217 +.PRRD==0 +.TTBC2==16 +.TTRD==3 +.PRREG==0 +.BLKI==104017 +.TTPEK==22 +.FAEOF==1000 +.FAAP==20000 +.FASP==2000 +.TVREV==10 +.TVRFN==21 +$BLKO==104220 +.PABS==40000 +.TTBIC==2 +.TTBIS==1 +.FAWT==10000 +.BLKO==104020 +$NOOP==104200 +.FAMU==6000 +.TERST==4000 +.RDOTF==11 +.NOOP==104000 +.TIRST==1 +.TTHNG==10 +.PRFPE==20 +.PRFPS==17 +.TVFNT==14 +.TOTRN==4 +.TVXOR==2 +.TORST==2000 +.PRFRE==11 +.TTBRK==7 +.PRPSW==10 +.TTBS2==15 +.TRPTF==6 +.TVDSC==105 +.TVDSI==103 +.TVDSN==102 +.TVDSR==100 +.TVDSS==101 +.TVDSX==104 +.NXMTF==12 +.CCCAP==1 +.TTTYP==13 +.EDVBE==32 +.ECDD==11 +.EAPEF==1 +.ECLF==30 +.CLCAP==10 +.EDRF==14 +.CMCAP==15 +.EFNF==17 +$SLEEP==104203 +.SPCAD==40000 +$MFPI==104235 +.SPCAP==3 +.ERNA==25 +.SLEEP==104003 +.CPYCP==100400 +.MFPI==104035 +.EDFL==13 +.ERPEF==26 +.EBFN==6 +.EBPN==10 +.EFTL==21 +.SPKIL==2 +.EFLOK==16 +$ALLOC==104222 +$QULK==104207 +$INVOK==104206 +.SPCLC==10000 +.SPCLD==20000 +$SYSJB==104233 +$QUNLK==104210 +.SPCLR==1 +.ALLOC==104022 +.QULK==104007 +.CLCON==400 +.SPSMC==13 +.EBFUN==7 +.INVOK==104006 +.SPGNP==6 +.SPENT==10 +.SYSJB==104033 +.QUNLK==104010 +.EFNTL==20 +.SPGPC==7 +.CMGRN==1000 +$CRUSR==104223 +.SPCRE==2000 +.SLETF==10 +.ILLTF==2 +.SPCRR==400 +.SPCRW==1000 +.EMTTF==5 +.CRWRT==1000 +.IOTTF==4 +.CRUSR==104023 +.SPSTP==3 +.SPSTR==4 +.SPSTX==11 +.SPSTY==12 +.CREX==2000 +.FALB==100000 +.PACCM==174377 +.TAKCP==101400 +.FARD==4000 +.FARE==1000 +$TIME==104232 +.TIECM==200 +.BETF==1 +.TIEDM==100 +.FADI==11000 +.FARI==10000 +.TIME==104032 +.LPCAP==14 +.TPCAP==13 +.FADIR==40000 +.TIQF==2 +.PRCAP==4 +.TRCAP==12 +.PDEI==100000 +.DSCAP==11 +$POOFF==104202 +.TTCAP==5 +.LIST diff --git a/src/sits/sysspr.238 b/src/sits/sysspr.238 new file mode 100755 index 00000000..ca94f28e --- /dev/null +++ b/src/sits/sysspr.238 @@ -0,0 +1,1914 @@ +.TITLE SYSTEM SPHERE +VERN==%FNAM2 + +.ABS +%COMPAT==0 +;STOP LISTING OF SYMBOLS AND SITMAC +.NLIST +.INSRT SITS;SITSS SYMS +.INSRT SITS;SITMAC > +.LIST + .STITLE MACROS +.MACRO ERRORF TEXT,DELCPS,ROTTEN + ERR FERRROT,,,ROTTEN +.ENDM +.MACRO ERROR TEXT,DELCPS,ROTTEN + ERR ERRROT,,,ROTTEN +.ENDM +.MACRO ERR ROT,TEXT,DELCPS,ROTTEN + JSR E,ROT + .ASCIZ ÔEXTŠ .EVEN + .IRP CAP, + CAP + .ENDM + .WORD 0 + .IIF NB ROTTEN, .WORD ROTTEN + .IIF B ROTTEN, .WORD 0 +.ENDM +.MACRO TYPE TEXT + JSR E,TYPES + .ASCIZ ÔEXTŠ .EVEN +.ENDM +.MACRO DELCAP X + MOV X'(F),A + JSR PC,DELCP + CLR X'(F) +.ENDM + .STITLE RANDOM VARIABLES + +MNPRSS==20. +PRPDLL==40. +LOGLLN==100. +LUNAM==15. +LREALN==25. +LDIRP==30. +LUCMD==10. +NDISKS==4 ;TO BE REPLACED BY A .EVAL +.=200 + +SSTATS:: +SVERN: 0 +STIME: .BLKW 2 +CSR: 0 +LOOKSW: 0 +RANDOM: .BLKW 20. +QUES: 1 ;NUMBER OF PEOPLE + LGGINQ ;QUEUE POINTER + 1 + LODRQ + 1 + USERIQ + MNPRSS + PRSQ + 0 ;END OF TABLE +DISKS: NDISKS ;LATER, USE .EVAL +MXNAME==10. ;MAX LENGTH OF NAME IN WORDS +DNAME: .BLKW 5 ;BITS, LENGTH, DATE, TIME +DNAM: .BLKW MXNAME ;ACTUAL NAME +DNAMEP: .REPT NDISKS ;NDISKS IS MAX NUBMER OF DISKS WHEN PUT IN .EVAL + DNAMES+<.RPCNT*MXNAME*2> + .ENDR + 0 ;TO FIND END OF TABLE +DNAMES: .BLKW MXNAME*NDISKS +DBUGTY: 0 ;0=> ALLOW LOGGINS ON ALL TTYS, NUMBER =>ALLOW LOGGIN ON ONLY THIS TTY +LGGINQ: -1 ;ONE USER QUEUE TO LOGGIN +OUTSKI: 0 ;REASON FOR LOGIN QUIT +LODRQ: -1 ;ONE USER QUEUE TO GET TO THE LOADER +PRSQLP:: ;PDL POINTER FOR LOCKING PRSQ +PRSQ: -1 ;MNPRS QUEUE (LIMITS NUMBER OF ACTIVE PROCESSES) +POINT: 0 +NBYTES: 0 +PAGE: 0 +BLKSRT: 0 +INFER: 0 ;NON-ZERO => RUNNING AS INFERIOR +DEMTTY: 100000 ;TTY NUMBER OF DEMONS +FLTELC: 0 ;FAULT ENTRY LOCK +DEMONC: .+2 ;POINTER TO DEMON COMMANDS + .ASCIZ /LOAD . FNT +/ ;CURRENTLY, JUST LOAD FONT +SITUPM: .ASCII /SITS IS UP!î/ +SITUML==.-SITUPM +SITDBM: .ASCII /SITS IS BEING DEBUGGEDî/ +SITDBL==.-SITDBM +DDTLOD: .ASCIZ /. DDT/ +LOGLOD: .ASCIZ /. SLOGO/ +BITBLK: .ASCIZ /BITS/ +DESBLK: .ASCIZ /DESCR/ +USERD: .ASCIZ /USERS/ +SYSNAM: .ASCIZ /SYSSPR/ +MAILNM: .ASCIZ /MAIL/ +SMALNM: .ASCIZ /MAIL SYSTEM/ + .EVEN +TMPFL: 0 +LODSMP: .BLKB 8. ;PAGE MAP +LODSPA: -1 ;PAGE CURRENTLY IN MY MAP OF INFERIOR SPHERE +LZRFIL: .ASCIZ /USRINFO USERS/ +.EVEN +LENGTH: 0 +BLKLEN==300 +BLOCK: .BLKB BLKLEN +FILCPL: 0 +LZRTBL: .WORD UREALN,LREALN,UDIRP,LDIRP,UCMD,LUCMD,0 +OUTSKY: 0 +ROTBLK: 0 ;DATA BLOCK TO MAKE ROOT DIR + + .STITLE COMMAND TABLE +.MACRO CMD CMD,ADDR + .ASCIZ ĂMDŠ .EVEN + .IF B ADDR + .IF DF CMD + CMD + .IFF + NOCMD + .ENDC + .IFF + .IF DF ADDR + ADDR + .IFF + NOCMD + .ENDC + .ENDC +NCMDS==NCMDS+1 +.ENDM +NCMDS==0 + +CMDTAB: CMD ?,HELP + CMD CO,CONTIN + CMD CONTINUE + CMD D,DDT + CMD DDT + CMD GUN + CMD HELP + CMD KILL + CMD L,LOADGO + CMD LO,LOGO + CMD LOAD,LOADGO + CMD LOGO + CMD LOGOUT + CMD GOODBYE,LOGOUT + CMD ONLINE + CMD PEEK + CMD PERMIT + CMD RS,RSTART + CMD RSTART + CMD SEND + CMD SYSKILL + CMD SYSSPR +;VARIABLES FOR USER INFO +USERIQ: -1 ;QUEUE FOR HACKING USER INFO +USRHI: 0 ;HIGHEST USER INDEX IN USE +HIPAG: LSTBLK ;LAST PAGE BEING USED +HIBLK: LSTPGL ;LENGTH OF LAST PAGE +CORTOP: LSTLOC ;FIRST NXM LOCATION + .STITLE PROCESS BLOCKS +.MACRO PRSVAR NAME,LENGTH,ENAME + .IIF NB NAME,NAME==. + .IF NB LENGTH + .=.+LENGTH + .EVEN + TPBLN==TPBLN+LENGTH + .IFF + .=.+2 + TPBLN==TPBLN+2 + .ENDC + .IIF NB ENAME,ENAME==. +.ENDM + +.MACRO EPRSBD + .IIF GT TPBLN-PBLN,PBLN==TPBLN + TPBLN==0 + .=PRSBLK +.ENDM + +SPRUBT: .BLKW 200 ;MAP SPHERE TO USER BLOCK +TPBLN==0 +PBLN==0 +.IIF GE 400-.,.=400 +PRSBLK: +;PROSSES BLOCK DEFS FOR LOGINS + PRSVAR PRBFRE ;THE PRCOSS BLOCK FREE WORD, FOR ALL BLOCKS + PRSVAR ,PRPDLL,PRPDL ;THE PDL, SAME FOR ALL PROCESS BLOCKS + PRSVAR PRPDLP ;POINTER TO USERS PDL TOP + ;STUFF AFTER HERE IS ZEROED IN THE PROCESS BLOCK INIT + PRSVAR LOGLIN,LOGLLN ;THE LOGIN NAME + PRSVAR DEMONX ;NON-ZERO=>DEMON + PRSVAR UBLKP ;POINTER TO USER BLOCK IF THERE IS ONE + PRSVAR PRID1 + PRSVAR PRID2 + PRSVAR TTYCP + PRSVAR TTYNO + PRSVAR FILCP + PRSVAR SPRCP + PRSVAR PRSCP + PRSVAR TMPCP + PRSVAR FLTSPR + PRSVAR FLTPRS +EPRSBD +.=PRSBLK+ + .=.+100 +MASPPD:: ;THE MASTER PROCESS PDL +PATCH:PAT: .=.+200 + .STITLE SYSTEM INIT CODE +START: MOV #MASPPD,P + CLR INFER ;PROBABLY WE ARE RUNNING AT TOP LEVEL + TST -(P) ;BUT TO CHECK + SAVE <#3,#<1*400>+1> ;WE'LL CHECK FOR A CAP IN 3 + $INVOK ;WHICH SHOULD ONLY EXIST IN INFERIOR SPHERES + TST (P)+ ;WELL, ANYHTING THERE? + BEQ 1$ ;NOPE, I ALWAYS KNEW I WAS SUPERIOR + MOV PC,INFER ;I FEEL SO HUMILIATED +1$: BNE 2$ + SAVE <#SYSNAM,#1> + $CRUSR ;ADD NAME "SYSSPR" TO SYSSPR USER + SAVE #SYSPRS + .FORK + BEQ .-2 +2$: MOV #7,A ;FLUSH ANY EXTRA PAGES WE GOT +START2: CMP #LSTBLK,A ;IS THIS THE LAST BLOCK WE WANT? + BEQ START3 ;YES, STOP FLUSHING + CMP -(P),-(P) ;DON'T NEED FOR DELETE + SAVE <#20*400+375> + BISB A,1(P) + SAVE <#1> + $MAP + SOB A,START2 +START3: SAVE <#LSTPGL_8.+0> ;LENGTH OF LAST PAGE + TST -(P) ;UNUSED + SAVE <#<20+LSTBLK>_8.+374,#1> ;EXPAND IN THIS SPHERE + $MAP ;MUST SUCEED, REALLY CONTACTING + CLR A ;DISK NUMBER TO HACK + MOV #ROTBLK,B ;POINTER TO THE ROOT CREATION BLOCK + MOV #10,C ;PLACE FOR THE FIRST AUX ROOT CAPABILITY + MOV DISKS,D ;NUMBER OF DISKS + BR OPNDS1 ;GET THE NAME OF THE ALREADY EXISTING ROOT +OPNDSK: TST INFER ;INFERIOR? + BNE OPNDS1 ;DON'T GET ROOTS + MOV A,(B) ;THE NEXT ROOT TO OPEN + BIS #.FARUT,(B) ;SAY WE WNAT A ROOT + SAVE ;CREATE A ROOT CAPABILITY + $INVOK ;OPEN THAT DISK + TST (P)+ ;RETURNS IT ANY WAY + SAVE <#-1,#0,C> ;COPY IT + BIS #.CPYCP,(P) + $INVOK + REST E ;THE CAPABILITY TO ROOT + SAVE <#-1,#0,C> ;COPY IT + BIS #.CPYCP,(P) + $INVOK + REST F ;THE CAPABILITY TO ROOT + SAVE <#0,#DESBLK,F> + BIS #.FAMU,(P) ;MUTATE TO THE DESCR FILE + .INVOK + BEQ 2$ ;LOST + SAVE <#0,#BITBLK,E> + BIS #.FAMU,(P) ;MUTATE TO THE BITS FILE + .INVOK + BNE 1$ ;GOT IT OK + CMP (P)+,(P)+ + MOV A,(P) + MOV E,A ;COPY CAP NUMBER + BR 3$ +2$: CMP (P)+,(P)+ + MOV A,(P) + MOV F,A +3$: JSR PC,DELCP ;DELETE THE CAP + REST A + BR OPNDS1 +1$: SAVE <,,E> ;CAPABILITY TO THE BITS FILE + BIS #.FAMB,(P) ;MAKE IT THE BIT FILE + $INVOK + SAVE A + MOV E,A + JSR PC,DELCP + MOV F,A + JSR PC,DELCP + REST A +OPNDS1: SAVE <#DNAME,#<5+MXNAME>*2,C> + BIS #.FARI,(P) ;WANT TO GET DISK NAME + .INVOK + BNE 1$ ;I GUESS THSI DISK DOESN'T EXIST + ADD #6,P ;FLUSH ARGS + BR 2$ ;IGNORE THIS DISK +1$: MOV DNAMEP(A),E ;POINTER TO NAME BLOCK + MOV #DNAM,F ;POINTER TO NAME READ IN + MOVB (F)+,(E)+ + BNE .-2 + ADD #2,A ;NEXT DISK NUMBER + INC C ;POINT TO THE NEXT CAPABILITY +2$: DEC D + BEQ START4 + JMP OPNDSK + +SYSPRS: .SYSJB ;PROVIDE SYSTEM WITH A PROCESS TO PLAY WITH + .RUG ;SHOULDN'T EVER RETURN!! + ;INIT THE VARIABLES +START4: CLR A ;INIT THE FREE WORDS OF THE PROCESS BLOCKS + MOV #MNPRSS,B +START1: MOV #-1,PRBFRE(A) + ADD #PBLN,A ;NEXT! + SOB B,START1 + MOV #QUES,A +START6: SAVE <#-1,(A)+> + BEQ START5 ;NO MORE QUEUES TO MAKE + SAVE <#<.QUCAP*400>+0> ;CREATE QUEUE CAPABILITY + $INVOK ;FOR PROCESS CREATION + REST @(A)+ ;THE GENERATED CAPABILITY + BR START6 +START5: CMP (P)+,(P)+ +;TYPE SITS IS UP ON ALL TTYS + TST INFER ;INFERIOR SYSPR? + BNE INFERI ;MADE IN HONG KONG +OPENL: SAVE <#-1,#0,#.CPYCP+10> ;GET FILE CAP. + $INVOK + REST FILCPL + SAVE <#0,#FILNAM,FILCPL> ;OPEN FILE + BIS #.FAMU,(P) + .INVOK + BEQ GOON ;NO LOSER FILE + SAVE <#1,FILCPL> ;PUT A 1 IN FIRST WORD + $WRDO + SAVE FILCPL + .WRDI + BEQ MTFILE ;MT LOSER FILE, DELETE IT +GOON: JSR PC,DCAP + CLR B ;TTY TO TYPE "SITS UP" ON + MOV #20,E ;NUMBER OF TTYS TO TYPE ON + JMP SITUPL +DELETE: SAVE <#0,#0,FILCPL> ;DELETE EMPTY FILE + BIS #.FADL,(P) + $INVOK +DCAP: SAVE <#0,#0,FILCPL> ; + BIS #.DELCP,(P) + $INVOK + RTS PC +MTFILE: JSR PC,DELETE + JMP OPENL +SITUPL: SAVE <#-1,B,#<.TTCAP*400>+0> ;CREATE CAPABILITY TO TTY + .INVOK + BEQ SITUPD ;IF ERROR MUST BE LAST ONE + REST ;CAPABILITY CREATED + SAVE <#SITUPM,#-SITUML,C> + $BLKO + MOV #SITUDC,A ;START INITED PROCESS AT DELETE CAPABILTY ROUTINE + JSR PC,IPRS ;GO CREATE ANOTHER PROCESS AND START IT AT STUPID + INC B ;GO TO NEXT TTY + SOB E,SITUPL ;TRY THE NEXT ONE + MOV #DEMON,A ;START THE DEMON PROCESS + JSR PC,IPRS ;GO CREATE OTHER PROCESS AND START IT AT DEMON + BR SITUPD +SITUDC: MOV C,A + JSR PC,DELCP + JMP FLSPRS ;MY WORK IS DONE + +INFERI: MOV #3,A ;THE TTY CAP SHOULD BE IN BOTH 2 AND 3 + JSR PC,DELCP ;AND WE ONLY NEED ONE OF THEM + MOV #2,C ;WHCIH WILL BECOME THE USERS TTY + MOV #STUPID,A ;START HIM LOOKING FOR LOGIN + JMP INTPRS ;HAVE TO GET A PROCESS BLOCK + .STITLE START UP INVIDUAL USERS +SITUPD: SAVE <#2> ;THE CORE LINK CAPABILITY + .BYTI ;GET A BYTE + REST ;SAAVE THE TTY # FOR THE PROCESS WE WILL CREATE + MOV #LOGIN,A ;THIS IS WHERE THE NEW PROCESS WILL "RETURN" TO + JSR PC,IPRS ;CREATE PROCESS AND START AT LOGIN + BR SITUPD +LOGIN: SAVE <#-1,C,#.TTCAP*400+0> ;TO CREATE TTY CAP + .INVOK + BNE .+6 ;IF THE CALL FAILS + JMP FLSPRS ;GIVE UP + MOV C,TTYNO(F) + REST C +STUPID: MOV C,TTYCP(F) ;SAVE THE TTY CAPABILITY + TST -(P) + SAVE <#.TIMGI!.TICVM!.TICTM,TTYCP(F)> ;SET TTY MODE + MOVB #.TTMOV,1(P) + $INVOK + SAVE <,,TTYCP(F)> + BIS #.TTTYP*400,(P) ;GET FLAGS FROM TTY TABLE + $INVOK + BIT #200,(P)+ ;BIT 200 IS THE TV FLAG + BEQ TVCHK1 ;IS NOT A TV + JSR PC,TVSETU ;YES, GO SET IT UP +TVCHK1: SAVE <#SSTATS> + $SSTAT + BIT #10,CSR ;IN DEBUG MODE? + BEQ LOG1 ;NO + MOV TTYNO(F),B ;THE TTY NUMBER + BEQ LOG1 ;ALWAYS ALLOWED ON CONSOLE 0 + CMP B,DBUGTY ;IS THIS TTY THE ALLOWED TTY? + BEQ LOG1 ;YES, CONTINUE... + TYPE <îSYSTEM BEING DEBUGGEDî> + SAVE <#0,#2*60.> ;IF HE IS ON A TV + $SLEEP ;HE'LL HAVE 2 SECONDS TO READ THIS + JMP LOGOUT +LOG1: TYPE <îSYSSPR.> + MOV #VERN,B + JSR PC,DTYPE + TYPE < SITS.> + MOV SVERN,B + JSR PC,DTYPE + JSR PC,CRLF +LOGIN1: JSR PC,GTUBLK ;MAKE ME A USER BLOCK + ERRORF ,,LOGOUT +;PRINT SYSTEM MAIL + BIT #10,CSR ;DEBUG MODE? + BNE 3$ + TST TTYNO(F) ;CONSOLE ZERO? + BEQ 3$ + MOV #SMALNM,C ;MUTATE TO SYSTEM MAIL FILE + JSR PC,MUTFIL ;ADDR OF FILE NAME IN C + BEQ 3$ ;DON'T PRINT IF MUTATE FAILED + JSR PC,PRMAIL ;PRINT MAIL FILE +3$: JSR PC,UDELCP ;DELETE CAP. IN USER BLK (UBLK) +;END OF PRINT SYSTEM MAIL + +NOUSR: +LGGIN: TYPE + JSR PC,GETLIN ;GET HIS LOSER NAME + CMP #".?,(E) ;IS HE SPECIAL + BNE .+6 +NOLOG: JMP CLOOP ;YES, LOG HIM IN + SAVE ;NO, TRY TO LOCK THE QUEUE + $QULK + SAVE <#-1,#0,#.CPYCP+10> ;GET FILE CAPABILITY + .INVOK + BEQ LUZE1 + REST FILCPL + SAVE <#0,#LZRFIL,FILCPL> + BIS #.FAMU,(P) + .INVOK + BEQ LUZE1 ;FAILED. + MOV #UNAME,B ;MAKE A POINTER + ADD UBLKP(F),B ;TO THE USER NAME IN THE USER BLOCK + MOVB (E)+,(B)+ + BNE .-2 ;COPY IT IN + SAVE FILCPL + .WRDI + JSR PC,GETBLK ;GET FIRST BLOCK FROM OLD FILE +BACK: MOV #LOGLIN,E ;RESET POINTER TO BEG OF INPUT BUFFR + ADD F,E +BACK1: CMPB (B),(E)+ ;COMP LOSER NAMES (1 LETTER) + BEQ SAME ;IF ALIKE GO TO SAME + BGT NUNSCH ;NO SUCH LOSER IN FILE + JSR PC,GETBLK ;GET A NEW ONE + BR BACK ;TRY AGAIN +SAME: TSTB (B)+ ;ARE EQUAL BYTES ZERO?? + BEQ FOUND ;YES, WE'VE GOT HIM + BR BACK1 ;NO, CMP NEXT LETTER + +LUZE1: CLR OUTSKI + BR NUN1 + +LUZE2: JMP CLOOP +NUNSCH: MOV #1,OUTSKI +NUN1: JSR PC,LGQUL + TST OUTSKI + BEQ LUZE2 + TYPE + JMP LGGIN ;TRY AGAIN + +LGQUL: MOV FILCPL,A + JSR PC,DELCP ;DELETE FILE CAPABILITY + CLR FILCPL + SAVE + $QUNLK + RTS PC + +FOUND: MOV #LOGLIN,E ;POINT TO THE LOGIN LINE + ADD F,E ;POINT DIRECTLY + TST INFER + BNE 1$ ;DON'T CREATE USER IF INFERIOR + SAVE ;SAVE POINTERS TO NAME AND FLAG + .CRUSR + ERRORF ,<>,LOGOUT +1$: MOV #LZRTBL,A ;GET ADDRESS OF TABLE +FOUND1: MOV (A)+,C ;MOVE ENTRY INTO C + BEQ HAVIT ;ZERO ENTRY, DONE + ADD UBLKP(F),C ;POINT INTO USER BLOCK + MOV (A)+,D ;GET THE MAX LENGTH +FOUND2: MOVB (B)+,(C)+ ;MOVE THE GUYS DATA INTO RIGHT BLOCK + BEQ FOUND1 ;IF THE STRING ENDS + SOB D,FOUND2 ;IF DOESN'T END, TRY TILL RUN OUT OF ROOM + CLRB -(C) ;MARK THE END OF THE STRING + BR FOUND1 ;AND GO FOR TH ENEXT THING + +HAVIT: MOV FILCPL,A ;DELETE FILE CAP + JSR PC,DELCP + CLR FILCPL ;GET RID OF FILE CAP + MOV #UCMD,A ;POINTER TO HIS COMAND BLOCK + ADD UBLKP(F),A + MOV #LOGLIN,B ;MUST TRANSFER TO HIS "TYPED" LINE + ADD F,B + MOV B,E ;POINTER FOR CLOOPD + MOVB (A)+,(B)+ + BNE .-2 + SAVE + $QUNLK + +;PRINT USER'S MAIL FILE + MOV #MAILNM,C ;MUTATE TO MAIL DIRECTORY + JSR PC,MUTFIL ;FILE NAME IN C + BEQ NOPRM1 ;NO FURTHER ACTION IF OPER. FAILED + + MOV #UNAME,C + ADD UBLKP(F),C ;POINT TO USER NAME + JSR PC,MUTFL1 ;MUTATE TO USER'S MAIL FILE + BEQ NOPRM1 ;NO FURTH. OPER. IF NO MAIL + + TYPE + JSR PC,TYI ;GET USER'S ANSWER + CMPB #'Y,A ;CHAR RETURNED IN A + BNE NOPRM1 ;DON'T PRINT IF CHAR NOT A "Y" + + JSR PC,PRMAIL ;PRINT MAIL FILE + TYPE + JSR PC,TYI ;GET ANSWER + CMPB #'Y,A + BNE NOPRM1 ;DON'T DELETE IF NOT A "Y" + JSR PC,UDELFI ;DELETE USER MAIL FILE + +NOPRM1: JSR PC,UDELCP ;DELETE CAP. TO THE FILE +;END OF PRINT MAIL FILE + + TSTB (E) ;WAS HIS DEFALT EMPTY? + BEQ 1$ + JMP CLOOPD ;NO, LOG HIM IN +1$: JMP CLOOP ;YES, ASK HIM WHAT TO DO + +GETBLK: SAVE FILCPL ;GET ENTRY LENGTH + .WRDI + BEQ GOOF + REST LENGTH ;GET LENGTH IN LENGTH AND F + BNE 5$ + JMP NUNSCH ;ZERO LENGTH, PUT IN NEW ENTRY OR QUIT +5$: CMP #-BLKLEN,LENGTH ;MAKE SURE BLOCK ISN'T TOO LONG + BHIS GOOF1 ;TOO LONG + SAVE <#BLOCK,LENGTH,FILCPL> ;GET ENTRY + .BLKI + BEQ GOOF1 + MOV #BLOCK,B ;START OF ENTRY IN B + RTS PC +GOOF: TYPE +GOOF2: JSR PC,LGQUL + BR CLOOP ;LOG HIM IN THE OLD WAY +GOOF1: TYPE + BR GOOF2 ;LOG HIM IN THE OLD WAY + .STITLE MAIN COMMAND LOOP +CLOOP1: INC E ;FLUSH A CHAR AT BEG OF LINE + BR CLOOP2 ;AND TRY AGAIN +CLOOP: MOV PRPDLP(F),P ;RESET PDL TO BE SURE + MOV #'#,A + JSR PC,TYO + JSR PC,GETLIN + BEQ CLOOP +CLOOP2: CMPB #':,(E) ;IGNORE : + BEQ CLOOP1 ;AT BEG OF LINE + CMPB #' ,(E) ;ALSO SPACE + BEQ CLOOP1 + TSTB (E) ;AT END OF LINE? + BEQ CLOOP ;TRY FOR ANOTHER +CLOOPD: MOV #NCMDS,A ;THE DEMON ENTERS HERE (AND SIGNS IN, PLEASE?) + MOV #CMDTAB,B +CMDLOP: MOV E,C +CMDLO3: CMPB (B)+,(C)+ + BNE CMDLO1 ;NOT THIS CMD + TSTB (B) ;END OF CMD NAME? + BNE CMDLO2 ;NO, MAYBE THIS CMD + CMPB #40,(C) ;IS THE CHAR A SEPERATOR? + BLT CMDLO1 ;NOPE, NOT THIS CMD + ADD #2,B ;THIS CMD, GET DISPATCH + BIC #1,B ;TO .EVEN + JSR PC,@(B) ;GO EXECUTE CMD + BR CLOOP +CMDLO1: TSTB (B)+ ;END OF CMD NAME? + BNE CMDLO1 ;NOPE + INC B ;ALIGN TO .EVEN + BIC #1,B + TST (B)+ ;SKIP DISPATCH ADDR + SOB A,CMDLOP ;CHECK NEXT ONE IF ANY + ERROR + +NOCMD: ERROR + +CMDLO2: CMPB #40,(C) ;HAVE WE HIT A SEPERATOR? + BGE CMDLO1 ;YES, NOT THIS CMD + BR CMDLO3 ;NO, MAYBE THIS CMD + +HELP: MOV #CMDTAB,D ;POINT AT COMMANDS + MOV #NCMDS,E ;NUMBER OF COMMANDS +HELP1: MOVB (D)+,A ;GET CHAR + BEQ HELP2 ;END OF CMD? + JSR PC,TYO + BR HELP1 +HELP2: ADD #3,D ;GET PAST DISPATCH ADDRESS + BIC #1,D ;AND ON EVEN LOC + JSR PC,CRLF + SOB E,HELP1 ;DO FOR ALL CMDS + RTS PC + DDT: MOV #DDTLOD,C + TST FLTSPR(F) ;IS THERE A SPHERE TO DEBUG? + BNE DDT1 + JMP LOADGO +DDT1: JSR PC,LOAD ;LOAD THE DDT AND GIVE IT THE STANDARD CAPS + CMP -(P),-(P) ;.... USED BELOW... + SAVE <#-1,FLTSPR(F),SPRCP(F)> + BIS #.GIVCP,(P) ;GIVE HIM THE SPHERE + .INVOK + ERRORF , + MOV (P),A ;IN CASE WE LOSE + CLR FLTSPR(F) + SAVE ;USE RETURN FROM PREVIOUS .INVOK AND ONE DUMMY FROM ABOVE + MOVB #.PRREG+1+.PRWRT,1(P) ;HIS R1 GETS WRITTEN + .INVOK + SAVE <#-1,FLTPRS(F),SPRCP(F)> + BIS #.GIVCP,(P) ;GIVE THE PROCESS + .INVOK + ERRORF ,,DDTFP + CLR FLTPRS(F) + SAVE ;USE RETURN FROM PREVIOUS .INVOK AND 2ND DUMMY + MOVB #.PRREG+0+.PRWRT,1(P) ;HIS R0 GETS THE PROCESS + .INVOK + JMP GOGO ;NOW GO START THE DDT + +DDTFP: SAVE <#-1,A,SPRCP(F)> ;TRY TO GET BACK THE SPHERE! + .INVOK ;GOOD LUCK + ERRORF , + REST ;GOT IT BACK AT LEAST! + MOV SPRCP(F),A ;DELETE THE DDT THAT WE LOST WITH + JMP DELCP ;AND RETURN TO THE ERROR ROUTINE + +LOGO: MOV #LOGLOD,C + JMP LOADGO + +LOGOUT: MOV UBLKP(F),A + CMP #-1,A ;DOES HE REALLY HAVE A USER BOLCK? + BEQ LOGOU1 + SUB #2,UREF(A) ;I DON'T WANT IT ANYMORE +LOGOU1: TST INFER ;DON'T LOGOIFY + BNE 1$ ;IF INFERIOR + JSR PC,LOGOTV ;GO LOGOIFY IT IF IT IS A TV +1$: ERROR ,,FLSPRS + +KILL: JSR PC,KILLSP + DELCAP FLTSPR + DELCAP FLTPRS + RTS PC + +KILLSP: DELCAP SPRCP + DELCAP PRSCP + RTS PC + +RSTART: TST SPRCP(F) ;DOES HE HAVE A REGULAR SPHERE + BEQ 1$ +2$: ERROR +1$: MOV FLTSPR(F),SPRCP(F) ;MAKE FAULTED SPHERE REAL ONE + CLR FLTSPR(F) ;DON'T KEEP TWO COPIES + SAVE <,,SPRCP(F)> + BEQ 2$ + BIS #.SPKIL*400,(P) ;TO KILL ALL PROCESSES + $INVOK + JSR PC,PUTPRS ;PUT A PROCESS INTO THE SPHERE SET TO THE START ADDR + JMP GOGO ;GO START IT UP + +CONTIN: TST SPRCP(F) ;DOES HE SOMEHOW HAVE A REAL SPHERE? + BEQ CONTI1 ;NO, MAYBE HAS A FAULTED ONE +CONTI2: ERROR ;CAN'T CONTINUE A REAL SPHERE + ;(HOW DID HE GET HERE, ANYWAY??) +CONTI1: MOV FLTSPR(F),SPRCP(F) ;MAKE THE FAULTED SPHERE THE REAL ONE + BEQ CONTI2 ;HE DIDN' HAVE A FAULTED SPHERE EITHER! + CLR FLTSPR(F) ;FLUSH THE FAULTED SPHERE + MOV FLTPRS(F),PRSCP(F) ;FLAULTED PROCESS=>PROCESS + BEQ CONTI3 ;IF NO FAULTED PROCESS, HE GOT HERE BY SOMEONE SYSSPRING HIM + CLR FLTPRS(F) + JMP GOGO ;NOW GO CONTINUE IT (I HOPE) +CONTI3: JSR PC,GIVTTY ;PASS DOWN THE TTY + JMP GOGO3 + + + .STITLE LOAD A SPHERE AND START IT +LOAD: JSR PC,KILLSP + SAVE <#-1,#FLTENT,#.MSCAP*400+0> + .INVOK + ERRORF + MOV (P),A + REST + ASL A ;CHANGE TO WORD INDEX + MOV UBLKP(F),SPRUBT(A) ;SAVE THE USER BLOCK POINTER FOR THIS SPHERES + JSR PC,MUTFIL ;MUTATE TO FILE + ERRORF , + TSTB (C)+ ;TRY TO FIND + BNE .-2 ;THE END OF THE STRING + DEC C + CMPB #40,-(C) ;LOOK FOR LAST BLANK + BLT .-4 ;OR OTHER CONTROL + INC C ;CORRECT THE AUTO DECREMENT + MOV UBLKP(F),A ;GET POINTER TO USER BLOCK + ADD #UCMD,A ;POINT TO HIS COMMAND FROB + MOV #LUCMD,B ;THE LARGEST COMMAND LENGTH +LOAD3: MOVB (C)+,(A)+ + BEQ LOAD2 + SOB B,LOAD3 + CLR -(A) +LOAD2: JSR PC,ABSLOD ;TRY TO LOAD IT + JSR PC,PUTPRS ;CREATE PROCESS WITH PC SET TO START + CLR A ;THE CREATE CAPABILITY + JSR PC,COPCPS ;GOES INTO CAP 0 + ERRORF , + MOV SPRCP(F),A ;THE SPHERE CAP + MOV #1,B ;GOES INTO CAP 1 + JSR PC,COPCP + ERRORF , + TST DEMONX(F) ;IS IT A DEMON? + BNE LOAD1 ;THE DEMON PROCESSES DON'T HAVE TTYS + MOV TTYCP(F),A ;THE TTY CAP + MOV #2,B ;GOES INTO CAP 2 + JSR PC,COPCP + ERRORF , + MOV TTYCP(F),A ;AND ALSO + MOV #3,B ;INTO CAP 3 + JSR PC,COPCP + ERRORF , +LOAD1: JSR PC,COPFLC ;FROM 10 TO 10 + ERRORF , + JSR PC,SETDEF ;GIVE HIM HIS DEFAULT DIR + RTS PC + +;MUTATE TO FILE WHOSE NAME POINTED TO BY REG. C +MUTFIL: SAVE <#-1,#0,#.CPYCP+10> + .INVOK + ERRORF , + REST FILCP(F) +MUTFL1: SAVE <#0,C,FILCP(F)> + BIS #.FAMU,(P) + .INVOK ;TRY TO LOOKUP THE FILE + BNE 4$ + ADD #6,P ;POP ARG'S SINCE CALL FAILED + SEZ ;SET Z FOR CALLING PROG. TO TEST +4$: RTS PC + + LOADGO: JSR PC,LOAD +GOGO: DELCAP FLTSPR ;IN CASE HE JUST WANTS TO FLUSH HIS FAULTED SPHERE + DELCAP FLTPRS ;AND PROCESS + JSR PC,GIVTTY + TST -(P) + CLR -(P) + SAVE + BIS #<.PRFAUL+.PRWRT>*400,(P) + .INVOK ;CLEAR THE FAULT WORD (TO MAKE SURE) + BEQ GOGO2 + TST -(P) + CLR -(P) + SAVE + BIS #<.PRSTOP+.PRWRT>*400,(P) + .INVOK ;START THE PROCESS +GOGO2: ERRORF , +GOGO3: MOV UBLKP(F),A ;POINT TO HIS USER BLOCK + MOV SPRCP(F),USPRCP(A) + MOV #-1,UPRSBL(A) ;INDICATE IN THE USER BLOCK HE HAS NO PROCESS BLOCK + DELCAP PRSCP + JMP FLSPRS + +GIVTTY: TST DEMONX(F) ;IS THIS A DEMON? + BNE GIVTT1 + SAVE + .TTGIV + ERRORF , +GIVTT1: RTS PC + +PUTPRS: MOV UBLKP(F),A ;POINTER TO USER BLOCK + SAVE <#-1,USTART(A),#.PRCAP*400+0> + .INVOK ;CREATE A PROCESS CAPABILITY + ERRORF , + REST + TST -(P) + SAVE + .INVOK ;PUT THE PROCESS INTO THE SPHERE + ERRORF , + RTS PC + SETDEF: SAVE + MOV UBLKP(F),E ;GET POINTER TO USER BLOCK + CLR A ;THE DISK TO GET THE DIR OFF OF + ADD #UDIRP,E ;POINT TO HIS DIR POINTER + MOV E,B ;SAVE A COPY +1$: TSTB (E) + BEQ SETDE8 ;NO DISKEE, NO DEFAULTEE + CMPB #';,(E)+ ;FIND END OF DISK NAME + BNE 1$ + CLR A ;POSSIBLE NAME MATCH +SETDN2: MOV DNAMEP(A),C + BEQ SETDE9 ;NO MATCH! + SAVE B ;SAVE POINTER TO BEG +1$: CMPB (B)+,(C)+ + BEQ 1$ + CMPB #';,-1(B) ;END OF DEFAULT? + BNE SETDN3 ;NOPE + TSTB -1(C) ;END OF NAME? + BNE SETDN3 ;NOPE + REST B ;MATCH THEN + ASR A ;MAKE INTO DISK CAP NUMBER + BR SETDE1 ;AND SET THAT ONE +SETDN3: TST (A)+ ;NEXT DISK + REST B + BR SETDN2 ;TRY NEXT ONE + +SETDE1: ADD #10,A ;POINT INTO DISK CAPS + JSR PC,COPTMP ;COPY INTO TMPCP + BEQ SETDE9 + MOV E,D ;SAVE POINTER TO REST OF STRING +SETDE3: CMPB #40,(D) ;A SPACE? + BEQ SETDE4 + SAVE <#0,#USERD,TMPCP(F)> + BIS #.FAMU,(P) ;TRY TO GET USER FILE + .INVOK + BEQ SETDE2 +SETDE4: SAVE <#0,E,TMPCP(F)> ;GET TO REAL DIR + BIS #.FAMU,(P) + .INVOK + BEQ SETDE2 + MOV #4,B ;DEF DIR GOES TO CAP 4 + JSR PC,COPCPX ;GIVE TO INFERIOR + BEQ SETDE9 +SETDE8: REST + RTS PC + +SETDE2: ADD #6,P ;CORRECT STACK +SETDE9: TYPE + JSR PC,DELTMP + BR SETDE8 + + + +;COPY CAPABILITY FROM US INTO HIM +;CAPABILITY TO COPY IN A, PLACE TO COPY TO IN B +COPCPS: MOV A,B ;SPECIAL, COPY INTO SAME PLACE +COPCP: JSR PC,COPTMP ;COPY A TO TEMP CAP + BEQ CPCPL2 +COPCPX: SAVE ;GIVE IT AWAY + BIS #.GIVCP,(P) + .INVOK + BEQ CPCPL1 ;CAN'T GET RID OF IT! + TST (P)+ ;CAPABI;ITY TO IT + CLR TMPCP(F) + CLZ + RTS PC +CPCPL1: ADD #6,P + SEZ +CPCPL2: RTS PC + +COPTMP: SAVE <#-1,#0,A> ;MAKE A COPY OF THE ONE WE WANT TO GIVE AWAY + BIS #.CPYCP,(P) + .INVOK + BEQ CPCPL1 ;LOSE, CAN'T COPY IT + REST TMPCP(F) ;SO WE CAN DELETE IT IF WE LOSE + RTS PC + +;COPY THE FILE CAPABILITYS DOWN TO THE INFERIOR SPHERE +COPFLC: MOV #10,A ;THE FIRST CAP TO TRY + MOV #10,C ;THE NUMBER OF THEM TO TRY +COPFL1: SAVE <,A,#401> ;TO CHECK THE CAP WE HAVE + $INVOK + TST (P)+ ;IS THERE ANYTHIN GTHERE? + BEQ COPFL2 ;DON'T COPY NOTHING + JSR PC,COPCPS ;COPY IF THERE IS ONE + BEQ COPFL3 ;COPY FAILED +COPFL2: INC A ;NEXT! + SOB C,COPFL1 + CLZ ;INDICATE SUCESS +COPFL3: RTS PC + .STITLE PROCESS CREATION AND DELETETION +;ENTER FROM A .FORK WITH THE START ADDRESS OF THE NEW +;PROCESS IN A. PROCESS WILL GET A PROCESS BLOCK ALLOCATED +;AND HAVE IT'S PDL POINTER SET BEFORE WE START IT UP +INTPRS: MOV #PRSQLP,P ;SPECIAL PDL TO LOCK AND UNLOCK Q + $QULK ;LOCK THE PROCESS QUEUE + MOV #-PBLN,F ;FIND A PROCESS BLOCK + ;NOTE THAT ONE MUST EXIST, SINCE LOCK WON +INTPR1: ADD #PBLN,F ;GO TO NEXT BLOCK + INC PRBFRE(F) ;TEST TO SEE IF THE BLOCK IS FREE, CLAIM IT + ;IF IT IS (NOTE THAT THIS WINS ALWAYS) + BNE INTPR1 ;SINCE CORRECT BRANCH IS DETERMINED ONLY + ;BY THE PREVIOUS INSTRUCTION + MOV F,P ;NOT REALLY, DON'T PUSH YET + ADD #PRPDL,P ;NOW YOU CAN PUSH AWAY! + MOV P,PRPDLP(F) + SAVE + MOV F,B + ADD #PRPDLP+2,B + MOV #>/2,A + CLR (B)+ ;TO ALL ZEROS + SOB A,.-2 + MOV #-1,UBLKP(F) ;MAKE IT CLEAR THAT WE DON'T HAVE A USER BLOCK + $GETID + REST + REST + RTS PC + +;JSR PC,IPRS TO DO A .FORK AND HAVE THE NEW PROCESS JUMP +;TO INTPRS +IPRS: SAVE <#INTPRS> ;TO GET THE PROCESS BLOCK + .FORK + BEQ .-2 ;WAIT UNTIL WE SUCEED + RTS PC + +;THIS IS WHERE OLD PROCESSES GO TO DIE +FLSPRS: TST INFER ;IF WE ARE AN INFERIOR + BEQ .+4 + BPT ;SIGNAL OUR SUPERIOR + MOV #-1,PRBFRE(F) ;WE WON'T EVER USE THE PDL AGAIN + MOV #PRSQLP,P ;EXCEPT FOR THE SPECIAL PDL + $QUNLK ;FOR LOCKING AND UNLOCKING QUEUE + $POOFF ;GONE AND FORGOTTEN (I HOPE) + ;ABSOLUTE LOADER +;ENTER WITH CAP TO FILE IN A, CAP TO SPHERE IN B +ABSLOD: SAVE + .QULK ;ONLY ONE LOAD AT A TIME IS ALLOWED + CLR PAGE + CLR BLKSRT + CLR NBYTES + MOV #-1,LODSPA ;MAKE SURE WE DON'T THINK WE HAVE THE PAGE MAPPED IN + MOV #10,C ;FOR ALL 8. PAGES IN THE SHPERE (I=D) + MOV #LODSMP,D ;CLEAR OUT THE MAP BYTES +ABSLO1: MOVB #-1,(D)+ + SOB C,ABSLO1 + ;C IS CHECKSUM + ;D IS CORE ADDRESS + ;E IS BYTE COUNT + CLR C ;CLEAR CHECKSUM + JSR PC,GWORD ;GET THE FIRST WORD OF THE FILE + TST A ;IS IT A ZERO? + BNE ABSLP4 ;MUST BE ABSOLUTE FORMAT FILE + JMP PLOAD ;ELSE IT IS A PURE FORMAT FILE + + +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 +ABSLP4: JSR PC,GWORD ;GET THE COUNT + MOV A,E ;SAVE IT + JSR PC,GWORD ;GET THE ADDRESS + MOV A,D + SUB #6,E ;IS IT THE START BLOCK? + BEQ ABSSRT ;YUP +ABSLP1: JSR PC,GBYTE + MOV D,B ;CHECK THAT THIS PAGE IS MAPPED IN + ASH #-13.,B ;CONVERT TO PAGE # + BIC #177770,B ;CAUSE THERE IS NO LSH + TSTB LODSMP(B) ;IS IT EXTANT? + BGE ABSLP2 ;YES + SAVE <#<7*400+0>,#0,#-1,SPRCP(F)> + BIS #.CRWRT,(P) ;GIVE CORE WRITE CAPABILITY + MOVB B,3(P) + BISB #20,3(P) + .MAP ;WHEW! GET THE NEW PAGE! + ERRORF ,, + MOVB #7,LODSMP(B) + JSR PC,PAGLOD ;PUT THE NEW PAGE INTO OUR MAP + MOV #160000,B ;TO CLEAR CORE +ABSLP3: CLR (B)+ + TST B + BNE ABSLP3 + BR ABSLP5 ;NO NEED TO PLACE THIS PAGE. + ;NOW HERW WE CHECK THAT THE PAGE MAPPED IN IS THE ONE WE +;ARE ABOUT TO REFERENCE, AND FIX IT IF IT ISN'T! +ABSLP2: JSR PC,PAGLOD ;PUT THE PAGE INTO OUR MAP IF NEEDED +ABSLP5: MOV D,B + BIS #160000,B ;MUST RELOCATE ADDRESS + MOVB A,(B) + INC D + SOB E,ABSLP1 + JSR PC,GBYTE ;THE CHECKSUM + TSTB C + BEQ ABSLOP +ABLDBC: ERROR ,, +ABSSRT: JSR PC,GBYTE ;GET CHECKSUM + TSTB C + BNE ABLDBC +ABSSR1: MOV FILCP(F),A + JSR PC,DELCP + CLR FILCP(F) + MOV UBLKP(F),A ;POINT TO HIS USER BLOCK + MOV D,USTART(A) ;SAVE HIS START ADDRESS THERE +ALQULK: CMP -(P),-(P) + SAVE <#26*400+375,#1> + $MAP + CMP -(P),-(P) + SAVE <#27*400+375,#1> ;TO DELETE PAGES 6 AND 7 + $MAP + SAVE LODRQ + $QUNLK + RTS PC + +PAGLOD: CMP B,LODSPA ;IS THAT THE CURRENTLY MAPED IN PAGE? + BEQ PAGLO1 ;YES, YOU WIN + MOV B,LODSPA ;WILL BE + SAVE <#<7*400>+0,B,SPRCP(F),#.CRWRT+1> ;TO MAP INTO OURSELF + MOVB #27,3(P) ;INTO TOP I=D PAGE + .MAP + ERRORF <.MAP FAILED???>,, +PAGLO1: RTS PC + GBYTE: TST NBYTES + BNE GBYTE1 + SAVE + BIS #26*400,(P) + SAVE <#.CRRD+1> + .MAP + ERRORF ,, + MOV #2000,NBYTES + MOV #140000,POINT + INC BLKSRT + CMP #10,BLKSRT + BNE GBYTE1 + CLR BLKSRT + INC PAGE +GBYTE1: MOVB @POINT,A + INC POINT + DEC NBYTES + ADD A,C + RTS PC + +GWORD: JSR PC,GBYTE + SAVE A + JSR PC,GBYTE + MOVB A,1(P) + REST A + RTS PC + +DELTMP: SAVE A + MOV TMPCP(F),A + CLR TMPCP(F) + JSR PC,DELCP + REST A + RTS PC + +DELCP: TST A ;IS THERE A CAP TO FLUSH? + BLE DELCP1 ;NOPE + CMP -(P),-(P) + SAVE A ;THE CAPABILITY + BIS #.DELCP,(P) ;THE DELETE FUNCTION + $INVOK + ASL A + CLR SPRUBT(A) ;KLUDGE, DELETE TTY OF DELETED SPHERE + ASR A +DELCP1: RTS PC + +;PURE LOAD A FILE +;THE MAP DATA IS ASSUMED TO ALREADY BE IN PAGE 26 +BUFPAG==27 +BUFADR=*20000 +MAPPAG==26 +MAPADR=*20000 + +PLOAD: CLR C ;THE CURRENT FILE PAGE + CLR D ;PAGE NUMBER + MOV #MAPADR+2,E ;POINTER TO MAP DATA +PLOAD1: MOV (E)+,A ;IS THERE ANY DATA ON THIS PAGE? + BEQ PLOAD4 ;NO + BIT #.PFIL,A ;IS IT PART OF FILE? + BEQ PLOAD4 ;NO + MOV D,B ;GET A COPY OF THE PAGE NUMBER + BIT #.PDEI,A ;IS IT AN I=D PAGE? + BEQ PLOAD2 ;NO + CMP D,#10 ;ARE WE ON D SPACE YET? + BGE PLOAD4 ;YES, NO NEED TO LOAD THIS PAGE + ADD #20,B ;SO WE WILL MAP IN AN I=D PAGE +PLOAD2: INC C ;THE DATA IS ON THE NEXT FILE PAGE + BIT #1000,A ;WILL HE HAVE WRITE ACCESS TO THIS PAGE? + BNE PLOAD3 ;YES + JSR PC,PLDRRD ;LOAD A READ ONLY PAGE + BR PLOAD4 ;GO ON TO NEXT PAGE +PLOAD3: JSR PC,PLDWRT ;LOAD A READ-WRITE PAGE +PLOAD4: INC D ;GO TO NEXT PAGE + CMP D,#20 ;HAVE WE CHECKED ALL THE PAGES? + BLT PLOAD1 ;NO + MOV (E),D ;THE STARTING ADDRESS + JMP ABSSR1 ;CLEAN UP AND RETURN + +;PURE LOAD A READ ONLY PAGE +PLDRRD: BIC #.PLENM,A ;ISOLATE THE LENGTH + SWAB A ;PUT THE LENGTH IN HIGH BYTE, 0 IN LOW BYTE + SAVE A ;LENGTH OF PAGE,,OFFSET IN PAGE + SAVE C ;PAGE NUMBER IN THE FILE + SAVE FILCP(F) ;FILE CAPABILITY, THE SOURCE OF THE PAGE + MOVB B,1(P) ;THE PAGE NUMBER TO CREATE IN SPHERE + SAVE SPRCP(F) ;THE DESTINATION, THE SPHERE WE ARE CREATING + BIS #.CRRD,(P) ;THIS IS A READ ONLY PAGE + .MAP ;MAP THIS PAGE INTO THE SPHERE + ERRORF ,, + RTS PC + +;PURE LOAD A READ-WRITE PAGE +PLDWRT: BIC #.PLENM,A ;ISOLATE THE LENGTH + SAVE ;SAVE THE SPHERE PAGE NUMBER AND LENGTH + SWAB A ;PUT LENGTH IN HIGH BYTE, 0 IN LOW + SAVE A ;LENGTH,,OFFSET + TST -(P) ;PAGE NUMBER IRRELEVANT + SAVE #BUFPAG*400+377 ;DESTINATION PAGE,,SOURCE=FRESH PAGE + SAVE #.CRWRT+1 ;READ-WRITE ACCESS,,DESTINATION=SYSSPR + .MAP ;CREATE A FRESH BUFFER PAGE + ERRORF ,, + MOV C,A ;THE PAGE NUMBER IN FILE + MUL #20000,A ;GET THE BYTE ADDRESS FOR THIS PAGE + SAVE + BIS #.FASP,(P) ;SET FILE POINTER + .INVOK ;SET THE POINTER TO THE RIGHT PAGE IN FILE + ERRORF ,, + MOV (P),A ;THE LENGTH OF THE PAGE IN BLOCKS + INC A ;BECAUSE 0 MEANS 1 BLOCK LONG + MUL #2000,A ;OBTAIN LENGTH IN BYTES + NEG B ;SINCE BLKI LIKES NEGATIVE COUNT + SAVE <#BUFADR,B,FILCP(F)> + .BLKI ;READ IN THE DATA OF THIS PAGE INTO THE BUFFER + ERRORF ,, + REST ;LENGTH AND SPHERE PAGE + SWAB A ;PUT THE LENGTH IN HIGH BYTE + SAVE A ;LENGTH,,OFFSET IN PAGE + SAVE #BUFPAG-20 ;SOURCE PAGE NUMBER + SAVE #1 ;SOURCE IS SYSSPR + MOVB B,1(P) ;THE PAGE NUMBER IN THE SPHERE + SAVE SPRCP(F) ;DESTINATION SPHERE + BIS #.CRWRT,(P) ;GIVE HIM READ-WRITE ACCESS + .MAP ;MAP THE BUFFER PAGE INTO THE SPHERE + ERRORF ,, + RTS PC + +FLTENT: MOV A,C ;SAVE THE CAPABILITY TO THE PROCESS + MOV #FLTEN1,A ;DON'T HAVE A PDL TO JSR ON + JMP INTPRS ;GO ALLOCATE A PROCESS BLOCK + +FLTEN1: INC FLTELC ;INDICATE WE ARE STARTING TO FAULT + MOV C,FLTPRS(F) ;SAVE THE FAULTED PROCESS + JSR PC,TTYGET + BEQ .+6 ;RETURNS EQ IF NOT DEMON + JMP LOGOUT ;LOGOUT DEMON WHEN IT FAULTS + SAVE <#0,#0,C> + BIS #.PRFAUL*400,(P) + $INVOK ;READ THE PROCESS FAULT WORD + REST A + CMPB A,#.IOTTF ;FOR NOW, IOT MEANS LOGOUT + BNE .+6 ;ANYTHING ELSE IS AN ERROR + JMP LOGOUT + TYPE + JMP CLOOP + +TTYGET: MOV B,FLTSPR(F) ;AND SPHERE + ASL B ;CHANGE SPHERE CAP NUMBER TO WORD INDEX + MOV SPRUBT(B),B ;USER BLOCK FOR THIS SPHERE + CLR UPRLOC(B) ;IF SOMEONE IS TRING TO GUN ME, TELL HIM HE LOST + DEC FLTELC ;NOW WE CAN UNLOCK + MOV B,UBLKP(F) + MOV F,UPRSBL(B) ;YOU POINT AT ME AND I'LL POINT AT YOU + MOV UTTYNO(B),TTYNO(F) ;RETORE HIS TTY NUMBER + BGE FLTEN2 ;IF IT IS A DEMON, TTY NO IS NEG + MOV PC,DEMONX(F) + RTS PC ;RETURN WITH Z CLEAR +FLTEN2: SAVE UTTYCP(B) + MOV (P),TTYCP(F) ;RESTORE THE ONE IN THE PROCESS BLOCK + $TTGET ;GET CONTROL OF IT + SEZ + RTS PC + +DEMON: MOV PC,DEMONX(F) ;I AM A DEMON PROCESS! + INC DEMTTY ;INC THE DEMON TTY NUMBER + MOV DEMTTY,TTYNO(F) ;AND HOPE NO OTHER DEMON STARTS AND CAUSES + ;2 DEMONS TO HAVE THE SAME NUMBER + JSR PC,GTUBLK ;TRY FOR A USER BLOCK + BEQ .-4 ;KEEP TRYING TILL YOU WIN + MOV #LOGLIN,A ;THE LOGIN LINE + ADD F,A ;OF THIS PROCESS +DEMON2: MOVB @DEMONC,B ;POINTER TO DEMON COMMANDS + BEQ DEMON1 ;NO MORE COMMANDS + INC DEMONC + CMP #12,B ;IGNORE LF + BEQ DEMON2 + CMP #15,B ;CR IS END OF LINE + BEQ DEMON3 + MOVB B,(A)+ ;SAVE THIS CHAR + BR DEMON2 ;AND GET MORE +DEMON3: CLRB (A)+ ;END OF LINE MARKER + MOV #DEMON,A ;GOT TO KEEP GOING + JSR PC,IPRS ;SEND SOMEONE TO LOOK AFTER THE STORE + MOV #LOGLIN,E + ADD F,E + JMP CLOOPD ;WHILST I GO DO MY THING +DEMON1: JMP LOGOUT ;NO MORE COMMANDS, I CAN DISAPPEAR + .STITLE UTILITY ROUTINES +;READ A LINE FROM TTY INTO THE LOGLIN BUFFER +;RETURN WITH Z CLEAR IF ANYTHING TYPED BEFORE +;AFTER LAST CHAR THERE IS A ZERO IN THE BUFFER +;D POINTS TO LAST CHAR IN THE BUFFER +GETLIN: MOV #LOGLIN,E + ADD F,E ;GET ADDRESS OF BEG OF LINE BUFFER + MOV E,D ;SAVE IT IN D + MOV #LOGLLN-1,C ;LENGTH OF BUFFER-1 +GETLI3: JSR PC,GETLI1 ;GET A NON-RUBOUT +GETLI7: CMP #15,A ;RETURN? + BEQ GETLI2 + JSR PC,TYO ;ECHO IT + MOVB A,(D)+ ;SAVE TEH CHARACTER + SOB C,GETLI3 ;# CHARS/LINE - 1 +GETLI4: JSR PC,GETLI1 ;GET A NON-RUBOUT + CMP #15,A + BEQ GETLI2 + TST C ;ANY SPACE IN BUFFER? + BNE GETLI3 + BR GETLI4 +GETLI2: JSR PC,CRLF + CLRB (D) ;TERM. WITH A "0" BYTE + CMP D,E ;WAS ANYTHING TYPED? + RTS PC + +;IGNORE ALL CHAR'S AFTER 99 UNTIL GET A +;PERMIT RUBOUT ON 100TH CHAR +GETLI1: JSR PC,TYI ;GET A CHAR + CMPB #177,A ;IS IT A RUBOUT? + BEQ GETL10 + RTS PC ;NO, RETURN WITH IT +GETL10: CMP E,D ;ANYTHING TO RUB? + BEQ GETLI1 ;NOPE + JSR PC,SLTYPE ;TYPE THE OPEN SLASH +GETLI5: MOVB -(D),A + JSR PC,TYO ;ECHO RUBBED OUT CHAR + INC C ;ONE MORE SPACE IN BUFFER + CMP E,D ;ALL RUBBED OUT? + BEQ GETLI6 ;MAKE OFF HE HIT OTHER CHAR + JSR PC,TYI ;GET NEXT CHAR + CMP #177,A ;IS IT ANOTHER RUBBOUT? + BEQ GETLI5 + JMP SLTYPE +GETLI6: JSR PC,SLTYPE ;END SLASH + JSR PC,CRLF + BR GETLI1 + + +SLTYPE: SAVE + MOVB #'\,A + JSR PC,TYO ;TELL HIM HE IS RUBBING OUT + REST + RTS PC + +FERRROT: BEQ ERRROT + +;THIS CODING EXEC. IF NO ERROR: DOES NOTHING! + TSTB (E)+ ;THE ASCIZ. SKIP TEXT + BNE .-2 + INC E ;ALIGN TO .EVEN + BIC #1,E + TST (E)+ ;SKIP CAPS + BNE .-2 + TST (E)+ ;SKIP ROUTINE, AND FALL THROUGH + RTS E + +ERRROT: MOVB (E)+,A ;SKIP TEXT IF NULL + BEQ ERRRO1 + TST DEMONX(F) ;FOR DEMONS + BNE ERRROT ;DON'T SAY A WORD + JSR PC,TYO ;PRINT TEXT CHAR BY CHAR + BR ERRROT +ERRRO1: INC E ;ALIGN TO .EVEN + BIC #1,E + TST DEMONX(F) + BNE ERRRO3 ;AND DON'T CRLF EITHER + JSR PC,CRLF +ERRRO3: MOV (E)+,B ;CAPABILITY TO FLUSH + BEQ ERRRO2 + ADD F,B ;IN HIS PROCESS BLOCK + MOV (B),A ;THE CAP + JSR PC,DELCP ;DELETE SPECIFIED CAP'S, + CLR (B) + BR ERRRO3 +ERRRO2: JSR PC,DELTMP ;AND TEMPORARY CAP + MOV (E)+,A ;THE ROUTINE TO CALL + BEQ .+4 + JSR PC,(A) + MOV #PRPDL,P ;TO RESET THE PDL + ADD F,P + JMP CLOOP + TVSETU: TST INFER + BNE TVSET1 + SAVE <#-1,#140000,#.DSCAP*400+0> ;CREATE A DISPLAY + MOVB TTYCP(F),2(P) ;FOR THIS TTY CAP + .INVOK ;TRY TO GET A DISPLAY + BEQ NOTV ;TOUGH LUCK BUNKY + MOV (P)+,A ;SAVE CAP TO DISPLAY + CMP (P)+,(P)+ ;EXTRA STUFF NO GOOD FOR TV DISPLAY + TST -(P) + SAVE A ;CAP TO DISPLAY AGAIN + SAVE TTYCP(F) ;TO ATTACH KEYBOARD TO TTY + MOVB #.TVATC,1(P) ;USE DUMMY FROM ABOVE, DS CAP ON STACK AND THIS + $INVOK ;SHOULD NEVER FAIL + JSR PC,DELCP ;NOW WE CAN GET RID OF THE DISPLAY CAP + CMP -(P),-(P) ;DUMMIES + SAVE TTYCP(F) + MOVB #.TVCL,1(P) ;CLEAR SCREEN FUNCTION + $INVOK + CMP -(P),-(P) ;DUMMIES + SAVE TTYCP(F) + MOVB #.TVREV,1(P) ;REVERSE SCREEN + $INVOK + SAVE <,#0,TTYCP(F)> + MOVB #.TVFNT,1(P) + .INVOK ;SET FONT 0 + BEQ NOFONT + SAVE TTYCP(F) + MOVB #.VICAM,1(P) ;TTY IS DEST + SAVE (P) ;AND SOURCE + $VIDSW ;SWITCH! +TVSET1: RTS PC + +NOTV: ADD #6,P ;POP ARGS OF FAILED CALL OFF + .GERRW ;GET THE REASON + BEQ 1$ + TST (P)+ ;COPY ERROR CODE + CMP #.EDEVE,(P)+ ;"DEVICE" ERROR? + BEQ TVSETU ;YES, TRY AGAIN +1$: JSR PC,LOGOTV ;DISPLAY "LOGO" FOR 3 SECONDS +NOFONT: MOV TTYCP(F),A ;DELETE THE TTY AND GO AWAY + JSR PC,DELCP + CLR TTYCP(F) + JMP FLSPRS + +LOGOTV: TST TTYNO(F) ;IS IT A DEMON OR A REAL TTY? + BLT LOGOT1 ;DEMON + SAVE <,,TTYCP(F)> ;GET THE TTY + MOVB #.TTTYP,1(P) ;READ THE TYPE + $INVOK + BIT #200,(P)+ ;CHECK IF IT IS A TV + BEQ LOGOT1 ;NOT A TV + SAVE TTYCP(F) + MOVB #.VICAM,1(P) ;TTY IS DEST + SAVE <#<.VIABS*400>+16> ;AND "LOGO" IS SOURCE + $VIDSW ;TO TELL HIM HE HAS LOST + SAVE <#0,#60.*1> ;FOR 3 SECONDS + $SLEEP + SAVE TTYCP(F) + MOVB #.VICAM,1(P) ;TTY IS DEST + SAVE <#<.VIABS*400>+17> ;AND BLANKNESS IS SOURCE + $VIDSW ;TO TELL HIM HE HAS LOST +LOGOT1: RTS PC + TYO: SAVE + $BYTO ;TYPE THE CHARACTER + RTS PC + +TYI: SAVE + $BYTI ;GET AN INPUT CHARACTER + REST ;PUT IT IN A + CMPB #'Z-100,A ;CHECK FOR ^Z + BNE TYI1 + TST INFER ;IF IT IS AN INFERIOR + BEQ .+4 + BPT + BR TYI +TYI1: RTS PC + +CRLF: SAVE + MOV #15,A + JSR PC,TYO + REST + RTS PC + +;PRINT ASCIZ STRING POINTED TO BY A +TYPEIT: SAVE +TYPEI2: MOVB @(P),A + BEQ TYPEI1 + JSR PC,TYO + INC (P) + BR TYPEI2 +TYPEI1: REST + RTS PC + +TYPES: SAVE +TYPES1: MOVB (E)+,A + BEQ TYPES2 + JSR PC,TYO + BR TYPES1 +TYPES2: INC E ;ALIGN TO .EVEN + BIC #1,E + REST + RTS E + +;GO TO THE COLUMN SPECIFIED IN B +TCOLUM: SAVE + SAVE <,,TTYCP(F)> + MOVB #.TTCNO,1(P) ;WANT THE CHAR NO + $INVOK + REST C + MOV #' ,A +TCOLU1: CMP B,C ;AR EWE WHERE WE WANT TO BE YET + BLE TCOLU2 ;YUP + JSR PC,TYO ;ONE MORE TIME + INC C ;UPDATE CHARNO + BR TCOLU1 +TCOLU2: REST + RTS PC + ;CONVERT BCD NUMBER TO ASCII NUMBER +NTYO: ADD #'0,A + JMP TYO + +;TYPE DECIMAL INTEGER IN B +DTYPE: MOV C,-(P) + MOV #10.,C + JSR PC,RTYPE +DTYPEX: MOV (P)+,C + RTS PC + +RTYPE: CLR A + DIV C,A + BEQ DTYPE1 + MOV B,-(P) + MOV A,B + JSR PC,RTYPE + MOV (P)+,B +DTYPE1: MOV B,A + JMP NTYO + +;TYPE B IN OCTAL +OTYPE: MOV C,-(P) + MOV #10,C + JSR PC,RTYPE + MOV (P)+,C + RTS PC + +;TYPE B AS SIGNED 16 BIT NUMBER +SNTYPE: TST B + BPL DTYPE + MOV #'-,A + JSR PC,TYO + NEG B + JMP DTYPE ;TYPE AS A DECIMAL NUMBER + + +;PRINT A MAIL FILE: "SYSTEM" OR A USER FILE +PRMAIL: SAVE ;SAVE FILE CAP. FOR PROCESS + .BYTI ;READ FILE A BYTE AT A TIME + BEQ 2$ ;Z SET WHEN END OF FILE + REST A ;PUT CHARACTER IN A + JSR PC,TYO ;PRINT IT + BR PRMAIL ;GET ANOTHER CHAR +2$: TST (P)+ ;EOF: CALL FAILED, SO FILCP(F) STILL ON STACK + RTS PC + +;DELETE CAP. TO A UBLK FILCP +UDELCP: MOV FILCP(F),A + JSR PC,DELCP + CLR FILCP(F) + RTS PC + + +;DELETE FILE SPECIFIED BY A UBLK'S FILCP +;SETS Z IF INVOK FAILS; Z CLEAR IF SUCCEEDS + +UDELFI: SAVE <#0,#0,FILCP(F)> + BIS #.FADL,(P) + .INVOK + BNE 1$ + ADD #6,P ;POP ARG'S WHEN FAIL + SEZ +1$: RTS PC + + .STITLE USER BLOCK MANAGEMENT +;GET A USER BLOCK +;RETURN THE INDEX OF IT IN A +;IF THERE IS NONE AVAILABLE, SEZ +GTUBLK: CLR A ;START AT THE BOTTOM +GTUBL1: CMP A,USRHI ;HAVE WE ALLOCATED THIS HIGH BEFORE? + BHIS GTUBL2 ;NO, MAY HAVE TO GET MORE CORE + INC UREF(A) ;GOBBLE THE BLOCK IF IT IS AVAIABLE + BEQ GTUBL3 ;YES, IT'S MINE! + DEC UREF(A) ;DIDN'T GET IT, REMOVE ALL CLAIM TO IT + ADD #LUBLK,A ;GO TO NEXT ONE + BR GTUBL1 +GTUBL3: SAVE + MOV A,B ;POINT AT THE BLOCK + MOV #LUBLK/2-1,C ;TO CLEAR THE BLOCK + ADD #UBLK+2,B ;DON'T CLEAR REF COUNT!! + CLR (B)+ + SOB C,.-2 + MOV TTYNO(F),UTTYNO(A) ;SET UP HIS TTY NUMBER + MOV TTYCP(F),UTTYCP(A) ;AND CAPABILITY + MOV A,UBLKP(F) ;AND POINT THE PROCESS BLOCK HERE + MOV F,UPRSBL(A) ;RETURN THE COMPLIMENT + INC UREF(A) ;REF COUNT OF >=1 INDICATES VALID BLOCK + REST + CLZ ;SUCCESS + RTS PC + +;COME HERE IF WE MAY HAVE TO ALLOCATE MORE CORE +GTUBL2: SAVE USERIQ ;HOW SMART IS THE USER? + $QULK ;PREVENT TIMING PROBLEMS +GTUBL8: MOV USRHI,A + ADD #UBLK+LUBLK,A + CMP A,CORTOP ;GARENTEE IT IS WITHIN BOUNDS + BHI GTUBL7 ;NOT THERE YET, WORRY ABOUT IT + MOV USRHI,A + MOV #-1,UREF(A) + ADD #LUBLK,USRHI ;A NEW RECORD + SAVE USERIQ ;EVEN IF HE ISN'T SO BRIGHT + $QUNLK ;UNLOCK THE USER DATA BASE LOCK + BR GTUBLK + +;COME HERE IF WE REALLY DO NEED MORE CORE +GTUBL7: MOV USRHI,A + ADD #2000,CORTOP ;ASSUME SUCCESS + INC HIBLK ;ONE MORE 512 WORD BLOCK + CMP #10,HIBLK ;OVERFLOW TO NEXT PAGE? + BLE GTUBL5 ;YUP + CLR -(P) ;THE START IS ZERO + MOVB HIBLK,1(P) ;THE LENGTH IS THIS + TST -(P) ;DUMMY + SAVE <#20_8.+374,#1> ;EXPAND PAGE IN ME + BISB HIPAG,3(P) ;THE I=D PAGE THAT IS HIGHEST + .MAP ;TRY THE EXPAND + BNE GTUBL8 ;NOW GO GOBBLE THE BLOCK + DEC HIBLK ;DIDN'T GET WHAT WE THOUGHT WE WOULD GET +GTUBL9: ADD #10,P +GTUBL6: SUB #2000,CORTOP ;HAD HIGHER EXPECTATIONS THAN THIS + SAVE USERIQ ;DUMB USER + $QUNLK ;LET SOMEONE ELSE TRY IT LATER + SEZ ;SEZ ME, THAT'S SEZ WHO! + RTS PC + +;GET HERE IF WE HAVE TO GET ANOTHER PAGE +GTUBL5: CMP #LSTBLK+2,HIPAG ;DON'T GET SILLY + BLE GTUBL6 + CLR HIBLK ;START WITH A 512 WORD PAGE + INC HIPAG + CLR -(P) ;ZERO START AND LENGTH + TST -(P) ;NOT USED + SAVE <#20_8.+377,#.CRWRT+1> ;NEW PAGE IN THIS SPHERE + BISB HIPAG,3(P) + .MAP ;TRY + BNE GTUBL8 ;GOT IT + MOV #7,HIBLK ;BACKTRACK + DEC HIPAG + BR GTUBL9 ;GO FAIL + ;FIND A USER BLOCK FOR LISTING PURPOSES +;FINDS BLOCKS SEQUENTIALLY BY TTY NUMBER +;INPUT IN B IS THE FIRST TTY NO WE WILL FIND ACCEPTABLE +;OUTPUT- IN A THE USER INDEX OF THE USER WE FOUND +;IN D THE TTY NUMBER OF THAT USER +;IN B THE TTY NUMBER+1 OF THAT USER +;SEZ IF NO USER FOUND >= TO THE TTY NUMBER IN B +FNUBLK: CLR C ;FIRST USER BLOCK + MOV #-1,D ;LEAST SO FAR +FNUBL3: INC UREF(C) ;MARK THAT I'M LOOKING AT IT + CMP #2,UREF(C) ;IF IT IS VALID THEN UREF=1, SO MY INC MAKES IT 2 + BLE FNUBL2 ;FOUND A BLOCK WITH VALID DATA +FNUBL5: DEC UREF(C) ;I DON'T WANT IT THEN +FNUBL6: ADD #LUBLK,C ;GO TO NEXT ONE + CMP C,USRHI ;IS THAT VALID? + BLO FNUBL3 + MOV D,B ;IF THERE WAS ONE FOUND +FNUBL7: INC B ;TEHN THIS IS THE NEXT ONE TO LOOK FOR + CMP #-1,D ;SEZ IF THERE WASN'T A GOOD ONE FOUND + RTS PC +FNUBL2: CMP B,UTTYNO(C) ;IS IT THE TTY WE'RE LOOKING FOR? + BEQ FNUBL4 ;YES, WIN + BHI FNUBL5 ;NO, TO LOW + CMP D,UTTYNO(C) ;IS IT LOWER THAN ANY OTHERS WE'VE FOUND? + BLO FNUBL5 ;NO + CMP #-1,D ;WAS THERE A PREVIOUS LOW ONE? + BEQ .+6 ;NO + DEC UREF(A) ;YES, I DON'T WANT IT NOW + MOV UTTYNO(C),D ;YES, IT IS LOWEST SO FAR + MOV C,A ;REMEMBER THE NEW ONE + BR FNUBL6 ;MAYBE THERE IS A LOWER ONE? +FNUBL4: CMP #-1,D ;HAD WE MAYBE HAD ONE BEFORE? + BEQ .+6 + DEC UREF(A) ;DEFINITELY DON'T WANT THAT NOW + MOV B,D ;THE ONE WE FOUND + MOV C,A ;IS DEFINITELY WHAT WE WANT + BR FNUBL7 + ;CALL WITH C POINTING TO A STRING WHICH SPECIFIES EITHER A UNAME +;OR A TTY NUMBER. TTY NUMBERS BEGIN WITH # OR *. # IS REAL USER +;AND * IS DEMON +;RETURNS WITH A POINTING TO THE USER BLOCK, WHICH HAS BEEN GOBBLED +;IF THE GUY IS FOUND +FINUSR: SAVE ;SAVE SOME REGS + CMPB #' ,(C)+ ;FLUSH LEADING SPACES + BEQ .-4 + TSTB -(C) ;DID WE FALL OFF THE END? + BEQ FINUS1 + MOV C,(P) ;CLOBBER E ON THE STACK + CMPB #'*,(C) ;DOES HE WANT A DEMON? + BEQ FINUS2 ;YUP + CMPB #'#,(C) ;DOES HE WANT A REGULAR TTY? + BEQ FINUS3 ;YUP +;COMES HERE FOR FINDING A UNAME + CLR A +FINUS4: INC UREF(A) ;GOBBLE THE BLOCK + CMP #2,UREF(A) ;VALID DATA? + BLE FINUS6 ;GOT GOOD BLOCK +FINU11: DEC UREF(A) ;DON'T WANT IT + ADD #LUBLK,A ;NEXT ONE + CMP A,USRHI + BLO FINUS4 +FINUS1: REST + SEZ + RTS PC +FINUS6: MOV A,E ;POTENITIAL WINNER + ADD #UNAME,E ;CHECK HIS NAME + MOV (P),D +FINU10: CMPB (E)+,(D) + BNE FINU11 + TSTB (D)+ ;END OF NAMES? + BNE FINU10 ;NOPE +FINUS8: REST + CLZ + RTS PC + +FINUS3: JSR PC,GNUM + BEQ FINUS1 + BR FINUS7 +FINUS2: JSR PC,GNUM ;GET NUMBER + BEQ FINUS1 ;NO NUMBER? + BIS #100000,B ;A DEMON +FINUS7: MOV B,E ;COPY TTY NUMBER DESIRED + JSR PC,FNUBLK ;TRY TO FIND HIM + BEQ FINUS1 ;NO SUCH GUY + INC E ;FNUBLK INCS B + CMP B,E ;IS IT WHAT WE WANTED? + BEQ FINUS8 ;YUP! + DEC UREF(A) ;I DON'T WANT IT THEN + BR FINUS1 + +GNUM: CLR B ;ACCUMULATE NUM IN B + CLR E ;FLAG FOR NUMBER SEEN + INC C ;SKIP # OR * +GNUM1: MOVB (C)+,A ;GET NEXT CHAR + SUB #'0,A ;REDUCE TO BCD + BLT GNUM2 ;BAD DIGIT? + CMP #'9-'0,A ;BAD DIGIT? + BLT GNUM2 + INC E ;SAW AT LEAST ONE GOOD DIGIT + MUL #10.,B ;PUT NEW DIGIT ON END + ADD A,B + BR GNUM1 +GNUM2: TST E ;SET CONDITION CODES + RTS PC + PEEK: CLR B ;THE FIRST TTY NUMBER +PEEK1: JSR PC,FNUBLK ;FIND THE NEXT USER BLOCK + BNE .+4 + RTS PC + JSR PC,PEEKT ;TYPE THE LINE + BR PEEK1 + +PEEKT: SAVE ;SAVE THE NEXT TTY NUMBER + MOV UTTYNO(A),B ;IS IT A DEMON OR A REGULAR GUY? + BLT PEEK2 ;A DEMON + TYPE + BR PEEK3 +PEEK2: TYPE + BIC #100000,B ;FLUSH THE DEMON BIT +PEEK3: JSR PC,DTYPE + MOV (P),A ;GET BACK THE UBLK PONTER + CMP #-1,UPRSBL(A) ;IS HE IN SYSSPR? + BEQ PEEK6 + TYPE <*> +PEEK6: MOV #8.,B ;GO TO COL 8 + JSR PC,TCOLUM + MOV (P),A ;POINT TO THE USER BLOCK + ADD #UNAME,A ;POINT TO THE UNAME + TST (A) ;ANYONE HOME? + BEQ PEEK4 ;NOPE + JSR PC,TYPEIT ;TYPE HIS UNAME + MOV #18.,B ;NOW GO TO 18 + JSR PC,TCOLUM + MOV (P),A ;POINT TO USER BLOCK AGAIN + ADD #UREALN,A ;POINT TO REAL NAME + JSR PC,TYPEIT +PEEK5: MOV #38.,B ;MOVE TO COL 38 + JSR PC,TCOLUM + MOV (P),A ;POINT TO USER BLOCK + ADD #UCMD,A ;POINT TO COMMAND + JSR PC,TYPEIT ;AND TYPE IT OUT + JSR PC,CRLF + REST + DEC UREF(A) ;I'M NOT LOOKING AT IT ANY MORE + RTS PC + +PEEK4: TYPE < ???> ;DON'T KNOW WHO THE HELL THIS IS + BR PEEK5 + +ONLINE: JSR PC,FINUSR ;TRY TO FIND HIM + BNE ONLIN1 ;GOT HIM +ONLIN2: TYPE + RTS PC +ONLIN1: MOV UTTYNO(A),D ;GET HIS TTY NUMBER + JMP PEEKT ;TYPE HIS PEEK LINE + + +GUN1: TST B + BEQ GUN3 + TYPE + BR GUN4 +GUN3: TYPE +GUN4: TYPE < USER WHO IS ALREADY IN SYSSPRî> + RTS PC + +SYSSPR: MOV PC,B ;FLAG FOR SYSSPR + BR GUN2 +GUN: CLR B ;FLAG FOR GUN +GUN2: JSR PC,FINUSR ;TRY TO FIND HIM TO GUN HIM + BEQ ONLIN2 ;CAN'T GUN HIM IF YOU CAN'T FIND HIM + CMP A,UBLKP(F) ;TRYING TO HACK YOURSELF? + BEQ GUN10 + INC FLTELC ;SAY THAT I AM "FAULTING" SOMEONE + INC UPRLOC(A) ;LOCK FROM PROCESSES +1$: CMP #1,FLTELC ;IS ANY ONE ENTRYING ON A FAULT? + BNE 1$ ;WAIT UNTIL DONE (UGH) + TST UPRLOC(A) ;DID SOMEONE GET BY? + BEQ GUN1 ;YUP, SIGH + MOV A,E ;SAVE POINTER TO THE USER BLOCK + MOV UBLKP(F),D ;POINT TO YOURSELF + INC UREF(D) ;LEAVE YOURSELF AROUND FOR HIM TO TYPE OUT + CMP #-1,UPRSBL(A) ;IS HE ALREADY IN SYSSPR? + BNE GUN9 ;SPECIAL IF HE IS ALREADY IN SYSSPR + MOV #GUNNER,A ;SOMEONE TO DO THE DIRTY WORK + JMP IPRS ;A NEW PROCESS + +GUN9: SAVE <,,#.SPSTP*400+1> ;STOP ALL PROCESSES IN SPHERE EXCEPT ME + $INVOK + DEC FLTELC ;HOPE FOR THE BEST (EXPECT THE WORST) + JSR PC,DELTMP + MOV UPRSBL(A),E ;POINTER TO PROCESS BLOCK OF GUY I'M GUNNING + SAVE + $INVOK ;GET CAP TO HIM + REST TMPCP(F) ;GET CAP TO PROCESS + SAVE <,B,#<.PRWRT+.PRREG+2>*400> ;SET REG C + BIS TMPCP(F),(P) + $INVOK + SAVE <,D,#<.PRWRT+.PRREG+3>*400> ;SET REG D + BIS TMPCP(F),(P) + $INVOK + SAVE <,#GUNSLF,#<.PRWRT+.PRREG+7>*400> + BIS TMPCP(F),(P) + $INVOK ;SET PC + JSR PC,DELTMP + SAVE <,,#.SPSTR*400+1> + $INVOK + RTS PC + +GUN10: MOV B,C + MOV A,D + BR GUNSLF ;REALLY GUNNIGN YOURSELF + + +GUNNER: MOV B,C ;SAVE THE GUN/SYSSPR FLAG + MOV USPRCP(E),B ;GET THE SPHERE CAP TO SPHERE WE ARE HACKING + JSR PC,TTYGET ;GET HIS TTY FROM HIM +GUNSLF: TST C ;DID HE WANT TO GO TO SYSSPR? + BNE GUNNR1 + TYPE + MOV D,A ;POINT TO THE BAD GUY + JSR PC,PEEKT ;TELL ALL ABOUT HIM + SAVE <#0,#3*60.> ;IF HE IS ON A TV + $SLEEP ;HE'LL HAVE 3 SECONDS TO READ THIS + JMP LOGOUT ;BEFORE WE FLUSH HIM +GUNNR1: TYPE + MOV D,A + JSR PC,PEEKT + JMP CLOOP + SEND: SAVE C ;SAVE POINTER TO THE NAME TO SEND TO + JSR PC,FINUSR ;IS THE GUY LOGGED IN? + BNE SEND7 + TST (P)+ + JMP ONLIN2 +SEND7: DEC UREF(A) ;DON'T HOLD ON T HIM RIGHT NOW + SAVE <#-1,#TMPFL,#.FACAP*400+0> + .INVOK +SEND5: ERRORF , + REST FILCP(F) + MOV FILCP(F),E ;KEEP THIS HANDY +SEND1: JSR PC,TYI ;GET A CHAR + CMP #177,A ;RUBBOUT? + BEQ SEND2 + CMP #'G-100,A ;QUIT? + BEQ SEND3 + CMP #'C-100,A ;END OF MESSAGE? + BEQ SEND4 + JSR PC,TYO + SAVE ;E=FILCP(F) + .BYTO + BEQ SEND5 + BR SEND1 + +SEND2: SAVE <,,E> + BIS #.FARP,(P) ;READ THE FILE POINTER + $INVOK + DEC 2(P) ;BACK UP TO PREVIOUS CHAR + BLT SEND6 ;NO PREVIOUS CHAR + MOV 2(P),B ;SAVE POINTER + SAVE E ;E=FILCP(F) + BIS #.FASP,(P) + $INVOK ;SET POINTER BACK + SAVE E + $BYTI + REST A + JSR PC,TYO + SAVE + BIS #.FASP,(P) + $INVOK + BR SEND1 + +SEND6: CMP (P)+,(P)+ + JSR PC,CRLF + BR SEND1 + +SEND3: ERROR , + +SEND4: REST C + JSR PC,FINUSR + ERRORF , + MOV A,E + MOV UTTYCP(E),A + JSR PC,COPTMP + ERRORF , + SAVE TMPCP(F) + $TTGET ;MAKE SURE WE HAVE CONTROL + SAVE <#0,#0,FILCP(F)> + BIS #.FASP,(P) + $INVOK +SENDLP: SAVE FILCP(F) + .BYTI + BEQ SENDL1 + SAVE TMPCP(F) + $BYTO + BR SENDLP +SENDL1: CMP UPRSBL(E),#-1 ;IN ANOTHER JOB? + BNE SENDL2 ;NO, JUST LEAVE HIM IN SYSSPR + SAVE + $TTGIV +SENDL2: ERROR , + + +;KILL THE WHOLE &%$# SYSTEM +SYSKIL: TST TTYNO(F) ;IS HE ON TTY 0? + BEQ 1$ ;YES, OK +2$: ERROR +1$: SAVE <#SSTATS> + $SSTAT ;TO READ THE SWITCHES + BIT #4,CSR ;IS SWITCH 2 UP? + BEQ 2$ ;NOPE + SAVE <,,#.SPKIL*400+1> ;KILL ALL IN SYSSPR BUT ME + $INVOK + MOV #177,A ;START AT THE TOP +3$: SAVE <,,A> + BIS #.DELCP,(P) + .INVOK + BNE 5$ + ADD #6,P +5$: DEC A + CMP #1,A ;DON'T WANT TO DELETE MS CAP TO OURSELF! + BNE 3$ +4$: .RUG + BR 4$ + +PERMIT: CMPB (C)+,#40 ;IS IT A SPACE? + BEQ PERMIT ;NO + DEC C ;TO POINT TO THE FIRST BYTE NON BLANK + DEC C ;THIS IS BECAUSE GNUM INCREMENTS IT + JSR PC,GNUM ;GET A NUMBER + BEQ PRMITL ;LOSES IF NO NUMBER + MOV B,DBUGTY ;SET THE NEW TTY TO ALLOW +PRMITL: RTS PC + + .STITLE USER BLOCKS +;THE USER BLOCKS START HERE AND GROW UPWARD AS NEEDED +UBLK:: +UREF: 0 ;THE REFERENCE COUNT (MUST BE FIRST!!!!) +UPRSBL: 0 ;NON ZERO=> I HAVE A PROCESS BLOCK +UTTYNO: 0 ;MY TTY NUMBER +UTTYCP: 0 ;CAP TO MY TTY +USPRCP: 0 ;CAP TO MY SPHERE (NOT GARENTEED CORRECT IF A PROCESS BLOCK EXISTS) +USTART: 0 ;HIS STARTING LOCATION +UPRLOC: 0 ;LOCK ON THIS PROCESS BLOCK (FOR GUN) +UNAME: .BLKB LUNAM ;THE UNAME (WHAT HE TYPED TO LOGIN) +UREALN: .BLKB LREALN ;HIS REAL NAME +UDIRP: .BLKB LDIRP ;PATH TO HIS DEFAULT DIRECTORY +UCMD: .BLKB LUCMD ;SOMETHING TO TELL WHAT HE'S DOING + .EVEN +LUBLK==.-UBLK + +LSTBLK==._-13. ;LAST PAGE +LSTPGL==<._-10.>- ;LENGTH F LAST PAGE +LSTLOC==<.!1777>+1 ;FIRST NXM LOCATION +FSTFRB==&77 +.MACRO PAD A,B +.PRINT /A B +/ +.ENDM +.IF2 +PAD ^/SYSSPR END =/,\. +.IRP Y,<0,1,2,3> +.IRP X,<0.,1.,2.,3.,4.,5.,6.,7.,8.,9.> +.IIF Z <</2>-Y''X>,PAD Y''X, +.ENDM +.ENDM +.ENDC + .END START + \ No newline at end of file