.title KOM .inclu "B:GLOBAL" ; Copyright (c) By Mikael Hybsch, Johannes Sj|gren, ; Anders Gripsborn and Peter R|stin ; This version of KOM was ; written at TEKLA, a PDP-11/70 at ]s| gymnasium, Stockholm, Sweden, ; by the copyright owners to be run under RSTS/E. ; Verification history: ; ; 28-Aug-84 Creation day (night). ; 21-Sep-84 Parser is almost finished. ; 03-Oct-84 The Main Lupe is working. ("SE TIDEN" works) ; 12-Oct-84 Parser is finished. ; 05-Nov-84 KOM recognizes a user's name and his password ; 09-Nov-84 Over 1000 persons created! (as a test) ; 01-Dec-84 KOM recognizes terminal type at start. ; 14-Mar-85 DISPLY works! We've actually seen it! ; 15-Mar-85 Sending letters and receiving them works. ; 19-Aug-85 (Buggy) first release. ; ; Development moved to Diana, a PDP-11/60 @ UFH. (RSTS/E V8.0-07) ; ; 13-Mar-86 Drops privileges before main loop ; 12-Aug-86 KOM Ver. 3 (Using RESLIB) is working. ; 30-Nov-87 Development of KOM Ver. 4 in progress. ; 06-Jan-88 KOM Ver. 4.1 is working. ; 19-Dec-88 KOM Ver. 5 with Internet support is rleased. ; ; ; All PSECTs must be defined HERE! sect null, d sect texts, d sect ovltbl, d ovltbl: sect code Text Enty, <" at PC "> Text Crosh, <<15><12>"?CRASH"> Text Tefis, <<15><12>"?FIS"> Text Teiot, <<15><12>"?FATAL"> Text Teemt, <<15><12>"?EMT"> Text Tefpp, <<15><12>"?FPP"> Text CRLF, <<15><12>> Text CR2LF, <<15><12><15><12>> Text RUB, <<10><40><10>> Text nog, <"?Can't RUN"> Text Pout2, <" at PC "> Text Pout, <", PC = "> Text Space, <" "> Text colon, <":"> Text ByMes, <"Bye (KOM)"<15><12><12>> Text tetrap, <<15><12>"?TRAP"> Text here, <"anywhere"<15><12>> Text Unprom, <" - "> Text ppromp, <" = "> Text admprm, <" -*- "> Text airfop, <" =*= "> Text EOS1, <"Tack f|r den h{r g}ngen."> Text EOS2, <" V{lkommen }ter!"> Text dhla, <"Du har l{st alla "> Text imma, <" inl{gg i "> ; Text NYI, <"%KOMNYI Not Yet Implemented!"> Text NYI, <"%KOMNYI"> Text nulabo, <"Inaktivitetstiden |verskriden."> .even sect null RTSBEG: NUL: sect code ; Main code begins here! komnyi: write #nyi ret clrxrb: push r0 mov #xrb, r1 mov #xrbsiz/2, r0 clrit: push r1 10$: clr (r1)+ sob r0, 10$ pop rts pc clrfqb: push r0 mov #firqb, r1 mov #fqbsiz/2, r0 br clrit wreg: .ttrst push mov sp, r1 add #10, r1 mov r1, -(sp) mov 2(sp), r1 push mov #7., r1 br 11$ 10$: movb #40, r0 call ttyout 11$: pop r0 call nout sob r1, 10$ pop rts pc dump: push mov r0, r2 ; Number of words to dump passed in r0 bic #1, r1 ; Make address even 10$: mov #10, r3 ; R1 points to dumpmemory. mov r1, r0 call nout push r1 write #colon pop r1 20$: mov #40, r0 call ttyout mov (r1)+, r0 call nout dec r2 beq 30$ sob r3, 20$ push r1 call PCRLF pop r1 br 10$ 30$: call PCRLF 40$: pop rts pc run: .name mov firqb+fqsiz, r4 call clrxrb mov #60, (r1)+ tst (r1)+ mov #1000, (r1)+ mov #15.*2, (r1)+ inc (r1) ; mov #1, (r1) .read call error mov #1000, r1 clr r3 mov #30, r2 47$: mov (r1)+, (r3)+ sob r2, 47$ mov @#40, r3 ; Start address of the program mov @#50, r2 ; High address of program mov @#56, r4 bne 25$ mov r2, r4 ash #-11., r4 inc r4 cmp msiz, r4 bhis 30$ 25$: mov r4, xrb .core call error 30$: sub #776, r2 mov @#44, r4 call clrxrb mov r2, (r1)+ ; Number of bytes to read tst (r1)+ mov #1000, (r1)+ mov #15.*2, (r1)+ .read call error clr me movb #RSTFQ, firqb+fqfun clrb firqb+fqfil calfip ; Close program file mov #4711, innept mov #LinLen,@#MaxLin ; Init for Input clr @#PTerm mov #-1, @#Line Clr @#Out mov #-1, UtmFlg clr @#TimLim ; No wait-time. jsr pc, (r3) ; Go for it! mov #jfsys, xrb+xrlen .clear ; Drop TMPPRV temporarily $$BEG: mov #stack, sp mov #ovlstk, ovlsp ; OverlayStackPointer. clr me clr KSW bis #UseRes, KSW clr mypriv call who mov #systm,r1 tst (r1) bne 20$ tst 2(r1) beq 30$ 20$: cmp SystmN, NrSyRe blos 30$ inc NrSyRe mov #FB1,r0 call CnvLet bcs 30$ ; Bad text! mov r0,r1 mov #7, r0 call disply ; Print system-message 30$: bit #xAU, myflag beq 40$ call vilka 40$: mainlp:: ; M A I N L U P E (loop the loop) setnam #0 ; Reset word-name to "KOM..." mov #stack, sp ; Restore stack-pointer. mov #ovlstk, ovlsp ; OverlayStackPointer. mov #SETID, r0 bit #xSL, @#MyFlag ; "Sluta" as default beq 10$ mov #SLUTA, r0 10$: clr nulcnt ; Null counter. call nexinl ; Check if any unread mov #CMDLST, r1 ; Set the right default command gos findcm tst r0 beq BadCmd mov FinPtr, defcmd call movpro ; Save prompter in user memory. call CTRLO mov #4712, Innept ; Flag for ctrl-c. PARSER #CMDLST, Prspri, r0, #TIMOUT ; Call Parser mov #4711, Innept call PCR2LF clr line tst level bne 20$ mov #1, level mov defcmd, Found 20$: mov Found, r1 call GetAdr call @(r1) ; Do it! RtFrML: call ccon call UtmOff call relink ; Update GRPLST clr commp br mainlp BadCmd: jmp bad ; Error! Exit! TIMOUT: bit #WaitEn, KSW bne 10$ inc nulcnt cmp nulcnt, #6*10. ; 10. min timeout. blos 10$ write #nulabo jmp sluta ; Swedish word for "stop". 10$: call relink clr r0 call nexinl ; Check if any unread tst r0 beq 100$ mov #CMDLST, r1 ; Set the right default command gos findcm tst r0 beq 100$ mov FinPtr, defcmd call movpro 100$: rts pc proc findcm ; Get text for command r0 from list begin ; pointed to by r1, r0=0 if no command mov r1, -(sp) ; found, otherwise r0 pointer to str 5$: beq 20$ ; and FinPtr are set to Cmd_Pointer. mov r1, FinPtr call GetAdr tst rPri1(r1) beq 8$ cmp (r1), r0 beq 10$ 8$: mov rNxt(r1), r1 br 5$ 10$: mov r1, r0 add #rStr, r0 br 30$ 20$: clr r0 30$: mov (sp)+, r1 ret nexinl: push r0 mov #LibInf, r1 call GetAdr mov 10(r1), edtnbr ; Text Edit # tst unrel ; Is there a list to read from? bne 20$ ; Yes. Do it! cmp myread, myhigh ; Any more letters to read? blo 10$ ; Yes! Build a list. cmp edtnbr, myclet beq 40$ 5$: mov me, r0 call GetHig mov r0, myhigh ; Read latest news and see it cmp myread, myhigh ; there is any unread letters blo 10$ ; Hit. beq 40$ ; Miss. iot ; You lose! 10$: call fixlet 20$: tst @unrel bne 30$ clr unrel call savel br 5$ 30$: mov #READl, (sp) ; Read next letter. jmp 500$ 40$: mov edtnbr, myclet tst curgrp ; Is there any list? beq 60$ ; No cmp thsgr, curgrp ; Are they equal? bne 50$ ; No tst lstlft bne 300$ write #dhla clr r0 mov hignum, r1 call deco16 write #imma mov curgrp, r0 call prtnam call PCR2LF 45$: call savem clr curgrp br 80$ 50$: tst lstlft beq 45$ tst thsgr beq 200$ gos CrTeLs, tst r0 bne 300$ ; Read more entries br 200$ ; Next meeting 60$: cmp edtnbr, mycinl beq 500$ 70$: mov Thsgr, r0 beq 80$ call GetHig cmp texrea, r0 beq 80$ mov r0, r1 gos CrTeLs, tst r0 bne 300$ mov r1, texrea call savem 80$: gos fndgrp ; Return meeting in r0 tst r0 bne 200$ mov edtnbr, mycinl br 500$ 200$: cmp curgrp, thsgr beq 300$ mov #Nextm, (sp) ; New meeting br 500$ 300$: push clr r2 mov lstptr, r3 sub #txtlst, r3 asr r3 div #20, r2 asl r2 mov #1, r4 ash r3, r4 bit r4, comflg(r2) bne 320$ pop mov #READi, (sp) br 500$ 320$: pop mov #READcc, (sp) br 500$ 400$: mov myclet, mycinl 500$: pop r0 rts pc save: call CCoff push tst me beq 100$ tst thsgr beq 2$ call savem 2$: call MtxBgn gos LockMe, <#FB3> ; Space optimization [881029/JS] mov PPN, 40(r1) mov Systm, 42(r1) mov Systm+2, 44(r1) mov NrSyRe, 46(r1) .date mov xrb, 70(r1) mov xrb+2, 72(r1) ; Save Time & date. mov mypoin, 104(r1) mov myread, 102(r1) inc 112(r1) gos Put <#1, , #FB3> ; Put person-block. gos get <#1, #2, #FB3, #1, #lock> ; Get info. mov #FB3+400, r1 cmp (r1), me beq 80$ mov me, r0 mov r1, r2 mov r1, r3 add #50.*2, r3 20$: cmp (r2)+, r0 beq 25$ cmp r2, r3 blo 20$ mov r1, r2 add #52.*2, r2 25$: mov r2, r3 tst -(r2) 30$: cmp r2, r1 blos 50$ 40$: mov -(r2), -(r3) br 30$ 50$: mov r0, (r1) 80$: gos put <#1,, #FB3> call MtxEnd 100$: mov #PreLst, r1 call GetAdr mov Job, r0 asl r0 asl r0 asl r0 add r1, r0 clr (r0) ; No-one present at this job. pop ret savel: call MtxBgn gos LockMe <#FB3> mov mypoin, 104(r1) mov myread, 102(r1) Gos Put <#1,, #FB3> ; Put person-block. call MtxEnd rts pc sluta: call ccoff Write #EOS1 gos save tst me beq 20$ bit #xBL, myflag beq 10$ mov #40, r0 call ttyout mov #29., r0 mov #'-, r1 gos string 10$: write #EOS2 20$: call pCRLF jmp $exit cc: mov (sp), r0 tst me beq cc2 mov Innept, r3 cmp r3, #4712 ; User was in main-lupe! beq 100$ cmp r3, #4711 ; Logged in? bne cc2 ; No, just exit! .ttnch ; Return to MainLoop mov #5, r0 20$: call releas ; Releas on all files sob r0, 20$ mov #70$, r2 30$: mov (r2)+, Firqb+FqFil beq 50$ clrb Firqb+FqFun calfip ; Close a chanel. br 30$ 50$: mov #ovlstk, ovlsp ; OverlayStackPointer. bic #UtmOn, KSW clr Line call pcrlf jmp RtFrML ; Return to Main-loop! 70$: .word 7*2, 11*2, 12*2, 0 ; IO-chanels to be closed. 100$: .ttrst call PCRLF jmp sluta cc2: .ttrst jmp $exit bye: movb firqb+fqjob, r0 ; kill own job. asrb r0 write #ByMes ; 'bye-message' call clrfqb movb #uu.chu, firqb+fqfun movb #377, firqb+35 movb r0, firqb+4 .uuo call error 10$: .exit crfis: call wreg write #tefis br crex cremt: call wreg write #teemt br crex traphd: push r5 mov 2(sp), r5 mov -(r5), r5 bit #200, r5 ; Ret-trap? bne 20$ ; Yepp! bic #177400, r5 cmp r5, #trptab-etrptb/2-1 bhi 10$ ; To big trap! asl r5 jsr pc, @trptab(r5) pop r5 rti 10$: pop r5 call wreg write #tetrap br crex 20$: bic #177600, r5 asl r5 add #10, sp add sp, r5 xor r5, sp xor sp, r5 xor r5, sp mov -(r5), -4(r5) mov -(r5), -(sp) mov -(r5), -(sp) mov -(r5), r5 rti ; --- This is the trap jump-table trptab: .word trp0 ; CLRFQB .word trp1 ; CLRXRB .word tron ; TRAP 2 .word troff ; TRAP 3 etrptb: trp0: call clrfqb rts pc trp1: call clrxrb rts pc tron: bis #20, 6(sp) rts pc troff: bic #20, 6(sp) rts pc criot: write #teiot write #pout2 pop r0 .erlog call nout call PCR2LF jmp sluta crfpp: call wreg write #tefpp br crex CRASH: write #crosh CREX: call PCRLF write #enty pop r0 call nout call PCRLF jmp $exit bad: mov firqb, -(sp) call PCRLF call wreg call PCRLF movb #uu.err, firqb+fqfun ;writes out a error messag movb (sp)+, firqb+fqerno ;err-number in .uuo call clrxrb mov #28., (r1) mov (r1)+, (r1)+ mov #firqb+4, (r1) .write bad32: write #pout2 pop r0 call nout call PCRLF jmp $exit nout: push mov #TmpStr+50+6, r3 ;addr is the output area (cvt%$) mov #6, r1 ;r1 is used as loop index 10$: mov r0, r2 ;r0 contains the word to be translated bic #177770, r2 add #60, r2 movb r2, -(r3) ash #-3, r0 bic #160000, r0 sob r1, 10$ call clrxrb mov #6., (r1)+ mov #6., (r1)+ mov #TmpStr+50, (r1) .write pop return bpt: push <@#Line, r0, r1> mov #-1, @#Line clrb xrb+xrci .postn tstb xrb+2 beq 10$ call PCRLF mov (sp), r1 10$: call wreg write #pout mov 6(sp), r0 call nout mov (r0), r0 push r0 mov #'/, r0 call ttyout pop r0 call nout call PCRLF pop rtt $exit: tst Job beq 10$ bit #UseRes, KSW beq 10$ mov Job, r0 clr Job mov #Mutex, r1 call GetAdr cmp 2(r1), r0 bne 10$ dec (r1)+ clr (r1) 10$: movb #RSTFQ, firqb+fqfun clrb firqb+fqfil CALFIP ; Close all open channels ; (esp. the database) .ttech ; Echo ON! call clrfqb ; Clear FIRQB movb #uu.trm, firqb+fqfun movb #377, firqb+5 ; Current KB movb #200, firqb+30 ; SET DELIMITER (No Delimiter) .uuo ; Turn off any previously set delimiter mov #firqb+fqnam1, r1 clr (r1)+ clr (r1)+ .rts ; Exit to job default KBM. .exit ; Safety catch (in case). errprt: call @#clrfqb ; FIRQB destroyed. movb #uu.err, @#firqb+fqfun mov r0, @#firqb+fqfil .uuo call @#clrxrb mov #28., r0 10$: tstb firqb+fqfil(r0) beq 20$ dec r0 br 10$ 20$: mov r0, (r1) mov (r1)+, (r1)+ mov #firqb+fqfil, (r1) .write rts pc error: tstb firqb bne 10$ rts pc 10$: jmp bad sect ..99.., d ; entry jump table to KOM +++ tbl:: .word pf.ner ; p.flag (no KBM) .word 0 ; p.dext .word 0 ; p.reserved msiz: .word 1 ; p.msiz .word crfis ; p.fis .word crash ; p.cras .word 0 ; p.strt .word 0 ; p.new .word run ; p.run .word bad ; p.bad .word bpt ; p.bpt .word criot ; p.iot .word cremt ; p.emt .word traphd ; p.trap .word crfpp ; p.fpp .word cc ; p.cc .word cc2 ; p.2cc xsiz: .word 20. ; p.size ;end of memory! .psect Buffer,lcl,abs,d,con ; Absolute memory area! . = 0 ; Low memory variables Line: .word ; Number of printed lines MaxLin: .word ; Form size (Max number of lines) Job: .word ; My job number Term: .word ; My terminal number PTerm: .word ; Pointer to terminal description. Width: .word ; Terminal width. KSW: .word ; KOM Status Word USW: .word ; User Status Word OWIde: .word ; Resedent Library identification OLIde: .word ; Window ID CurSeg: .word ; Current overlay segment. LibSiz: .word ResLim: .word ; Border between ResLib and Memory. EditNr: .word ; Edit # for groups HshSiz: .word ; # of entrys in hash-table HshEnd: .word ; Last block used for that table .=172 Readc: . = USRSP Readce: ; Unread letters . = CORCMN TmpStr: .blkb 132. ; Temporary string for common use. Tmp: .blkw 20. . =1000 ; Arrays. (Stacks) STKEND: .blkw 2000 STACK: ; User stack .word ; The safety-loving side of me ; requires this word! OVSEND: .blkw 100. ; Special stack for overlay OVLSTK: ; handeling. OVLSP: .word NXTADD: .word NXTSEG: .word .word ; These words are used to keep track of what to read and what not to read ; The rutines that keep track of this was completely rewritten @ 870704 txtlst: .blkw NRTEXT ; List of unread texts. comflg: .blkw +1 .word curgrp: .word ; Current group for which list are ; built. lstptr: .word ; Where in the list are we now? lstlft: .word ; Number of entries left. lnctre: .blkw 2 ; Last Non Comment Text Read. ltxtre: .blkw 2 ; Last Text Read. strec: .word ; MOTTAGET record to begin with. stpos: .word ; Position in that record. nctrec: .word ; Pointer to MOTTAGET-record for ; last non comment text placed in ; list. nctpos: .word ; Position in that record. nctext: .blkw 2 ; Text # for last non commment text. nctnum: .word ; Start "Lokal text number" lsttxt: .blkw 2 ; Text # for the last text in list. lowlim: .blkw 2 ; "Low-limit". higlim: .blkw 2 ; "High-limit". hignum: .word ; # of received texts. nwslft: .word ; # of unread texts not put in list. stnum: .word ; Start "Lokal text number" EOLSTV: ; End of variables for the list above. ; These words tells the rest of the program which group we currently ; went to and the status of it. thsgr: .word ; Current meeting. nodrec: .word ; Which one of my MEDLEMSSKAPSNODs ; are this meeting in? nodpos: .word ; Where in that node? texrea: .word ; # of text read, to save. ; (An aprox. to reality) startr: .word ; START-record (or Zero if none). ; Note: The following words (Utmnam-EOFBU) must be in this order!!! UtmNam: .blkw 3 ; Filename for "Utmatning.." UtmDev: .blkw 2 ; Device used by "Utmatning.." UtmPtr: .word ; These words are used by IO UtmBlk: .word FBU: .blkb 1000 ; Utmatning.. buffer EOFBU: ; Note: The following words ( until FB4) must be in this order!!! .word ; FB1's current block FB1: .blkb 1000 ; First file buffer. .word FB2: .blkb 1000 ; Filebuffer 2. .word FB3: .blkb 1000 ; 3'rd file buffer. .word FB4: ; 4'th file buffer. ; PARSER's comunication area. PProm: .word ; Uses the 4'th file buffer. CopyP: .byte Usel: .byte PSW: .word ; PARSER-STATUS-WORD Lnks: .blkb LnkMax .even LnkLvl: .word NrAmb: .word Ambp: .blkw MaxAmb Ambs: .blkw MaxAmb EoAmb: .word Level: .word ; Number of found Lists MinLvl: .word Minstr: .word Found: .blkw MaxLvl Strs: .blkw MaxLvl Lists: .blkw MaxLvl Prios: .blkw MaxLvl PStr1: .blkb 128. PStr2: .blkb 128. PStr3: .blkb 128. PTmp: .word LstCom: .word EOFB4: .iif LT EOFB4-FB4-1000 .=FB4+1000 ; Allocate rest of file buffer. ; Variables Out: .word ; Counter, used by IO UtmFlg: .word Systm: .blkw 2 ; System-message SystmN: .word ; Nr of times to show sys.-mes. CurBlk: .word ; Block pointer (used by DSPLY2) Innept: .word TimLim: .word ; Time Limit for read. LibIde: .word ; Resedent Library identification WinIde: .word ; Window ID. CurSek: .word ; Current maped sektion LstAdr: .word ; Temp. variables for cmd.-pointers. NxtAdr: .word LstMem: .word NxtMem: .word MemLim: .word Stat: .word ; Pointer to prompt (" - ") PrsPri: .word ; Priority to Parser. Me: .word ; My "account" number Myread: .word ; My number of receieved letters Mypoin: .word ; Direct pointer to current node 7. Myinlp: .word ; Pointer to beginning of "MEDLEMSSKAP" Myflag: .word ; My personal flags. Mypriv: .word ; My privileges MyHigh: .word ; My Highest received letter. MyRec: .word ; My record number. (Fys) MyNtRt: .word ; My Net Rights (bitmap of net-IDs) MyHdrW: .word ; My Header Word (bitmap of headers) NrSyRe: .word ; Nr of Read System-Messages. comttt: .word nxtcom: .word grcblk: .word grcptr: .word Commp: .word ; Comment marker! MyCInl: .word ; My current text (entry) MyCLet: .word ; My current text (letter) edtnbr: .word MHPtr: .word MHpos: .word PPN: .word ; Current project, prgramer number Thisl: .word ; A Pointer to "MOTTAGET" Oldl: .word ; Last read text (Fys) DefCmd: .word ; Pointer to default cmd. Show: .word ; Number of lines to be printed TextNr: .word ; Temporary variable Flgs: .word ; Flags (se below) UNREL: .word ; Pointer to readl. FinPtr: .word ; Used by findcm nulcnt: .word ; # of calls to TIMOUT. PrsPro: .blkb 80. ; Place to put parsers prompt. TTFlag: .word ; Terminal type flags TTdefs: .blkb 100 ; Storage for terminal definition .even DspDat: .blkw 2 DspFlg: DspFil: .blkw 2 ; by Disply for the @file .even ; feature! .even ; ++ .word ; These words must be like this. .word ; Used by crypt. crybuf: .blkw CODLEN/2 ; cryend: ; .word ; .word ; -- EoDPos: .word ; 1'st free space in DstBuf OrgTxt: .blkw 2 ; Orginal text # (long). DstBuf: .word ; Nr of Receivers. .word ; 1'st receiver. .word ; Pointer to next receiver. .word ; Nr of headers to 1'st receiver. .blkw 400 ; ... EoDBuf: .word ; Safty... EOMEM: ALIAS1: . = 100000 BASADR: ; Window for RESLIB .end