;*; Updated on 31-Aug-89 at 1:41 PM by Steve Archuleta; edit time: 0:03:38
;*******************************
;* IntraNetwork CB *
;* *
;* by Dave Heyliger *
;* AMUS Staff *
;* *
;* NOTE: you need *
;* *
;* CB.M68 *
;* CBCLR.M68 *
;* CBSYS.M68 *
;*******************************
;%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
; "Go ahead... make me rich!"
;
; translated: THIS BABY IS FREE FOR ANYONE AND EVERYONE. The ONLY way
; this program will generate money is if someone decides
; to cheat, sell it, and get caught by me or other members
; etc. Then in come the lawyers and bingo: I'm rich!
;%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
;##########################################################################
; How it works, General Instructions, What You Need:
;
; CB works by storing pointers to user partitions of everyone who is on CB.
; When a user on CB modifies their "message" to other users, it changes a
; "hash" (the count of the number of characters). When there is a hash change
; OR a user quits OR a new user comes on, the messages are updated. CB offers
; unique "handles" for everyone who is on (SPECIAL TSASS VERSION uses
; INITIALS as the handle automatically). CB also offers dynamic screen editing
; that adds great effects! You will find CB addicting and fun - guaranteed.
;
; FOR CB TO WORK, you MUST modify this file. There are TWO versions contained
; in this source code file. 1) "PUBLIC" version and 2) "TSASS" version. For
; those who don't run TSASS (Dravac), you MUST comment out the "TSASS"
; portion and visa versa. It is clearly marked in the code, and it involves
; placing ";"s before an entire paragraph of code. After reading the code you
; will see where to place the series of ";"s.
; You will also need a funny file called CB.SYS. This is just a one block file
; that contains absoulely NOTHING! You MUST place CB.SYS in System Memory (it
; only takes up 512 bytes). You do this by storing CB.SYS on DSK0:[1,4] and
; from within your AMOSL.INI file you have a SYSTEM CB.SYS line before the
; final SYSTEM line. Reboot your system and you are ready to go. If you have
; the space, place CB.LIT (the assembled version of this file) on DSK0:[1,4]
; too so you can call up CB from anywhere. The file CB.SYS can be generated
; from a very small file called CBSYS.M68. Be sure to RENAME it to CB.SYS!
; Finally, a file called CBCLR.M68 creates CBCLR.LIT (CB Clear). If for any
; reason CB.SYS gets "mucked", type CBCLR and it will reset CBSYS to all "0"s.
;############################################################################
DEFINE HOME AA ;moves cursor "HOME" on your input line
MOVB #3,D1
LSLW D1,#10
MOVB AA,D1
TCRT
ENDM
;--- Image mode, no echo, no control-C, and get .OFDEF pointer (A3)
;
JOBIDX A6 ;A6 points to JCB
LEA A4,JOBTYP(A6) ;A4 points to processing word
ANDW #^B1111111101111111,@A4 ;set no ctrlc
MOV JOBTRM(A6),A4 ;A4 points to the terminal def. tbl.
ORW #T$IMI!T$ECS,@A4 ;Force image mode, suppress echo
GETIMP IMPSIZ,A3 ;A3 points to variables
;--- See if user wants to get on...
;
CBINI: PRTTAB 377,0 ;clear the screen
PRTTAB 2,1 ;tab over
TYPE < There are > ;start of msg
CALL SERCH ;fill CBSYS variable - find CB.SYS
CLR D1 ;data registers are funny, so clear
MOVB 20(A1),D1 ;D1 contains count of current users
PUSH D1 ;save the count
DCVT 0,OT$TRM ;blast out current number
TYPE < user(s) currently on.>
POP D1 ;retrieve the count
CMPB D1,#30 ;all full??
BNE ROOM ;nope, still some room
TYPECR < Sorry, but the airways are full!>
JMP QOFF ;type above msg and quit
ROOM: TYPE < Would you like to connect? y or n >
QON: SLEEP #2500. ;sleep a bit to not burn CPU
TCKI ;any input???
BNE QON ;waiting for reply still....
KBD ;get the reply
UCS ;create upper case for comparison
CMPB D1,#131 ;"Y"????
JNE QOFF ;nope, so quit
;--- TSASS LOGON ROUTINE
;
; Place semi-colons in front of this entire paragraph if you do NOT
; use TSASS!
;
; USRBAS A1 ;get the pseudo base of memory
; SUB #572,A1 ;A1 points to the initials
; LEA A5,GLOBAL(A3) ;time to .INI global message space
; MOVB #377,(A5)+ ;"ON" byte set (checked by others)
; MOVB #0,(A5)+ ;"HASH" set to zero (no input yet)
; MOVB #'[,(A5)+ ;move in the HANDLE information
; MOV #4,D4 ;four times we will do this:
;MOVHDL: MOVB (A1)+,(A5)+ ; move in the char
; DEC D4 ; one less char to move in
; BNE MOVHDL ; and get next char
;STLMOR: MOVB #'],(A5)+ ;move in more HANDLE info
; MOVB #40,(A5)+ ;a space
; MOVB #'-,(A5)+ ;a dash
; MOVB #40,(A5)+ ;a space
; CLRB @A5 ;a null
;--- PUBLIC LOGON ROUTINE
;
; Place semi-colons in front of this entire paragraph if you do
; use TSASS! (original version has this paragraph commented out)
;
LEA A5,GLOBAL(A3) ;time to .INI global message space
MOVB #377,(A5)+ ;"ON" byte set (checked by others)
MOVB #0,(A5)+ ;"HASH" set to zero (no input yet)
MOVB #'[,(A5)+ ;move in the HANDLE information
PRTTAB 4,30 ;tab to here
TYPE < Enter in a 4-letter handle ____>
PRTTAB 4,64 ;return tab to here
CLR D3 ;D3 will be a counter
LOGON: CMP D3,#4 ;all full?
JEQ APPEND ;yup, time to append some characters
KBD ;wait for ONE character
L1: CMPB D1,#177 ;rubout?
BNE L3 ;nope, don't do code below
CMPB D3,#0 ;rubout, but room?
BNE L2 ;if not "0" then room to go back
SCOLD: MOV #7,D1 ;get a bell
TTY ;beep
BR LOGON ;and try again
L2: PRTTAB 377,5 ;cursor left one column
MOVB #137,D1 ;put a "_" in D1
TTY ;blast it out
PRTTAB 377,5 ;move left back over the "_"
DECB D3 ;adjust count
DEC A5 ;adjust pointer
CLRB @A5 ;delete the character from the var.
JMP LOGON ;and ready for next key entry
L3: CMPB D1,#172 ;is it a z or more?
BGT SCOLD ;then ding
CMPB D1,#40 ;is it a space?
BEQ L4 ;then AOK
CMPB D1,#101 ;A or less?
BLT SCOLD ;then ding
L4: UCS ;convert to upper case
TTY ;type it out
MOVB D1,(A5)+ ;ok character
INC D3 ;count one more
JMP LOGON ;and do it again
APPEND:MOVB #'],(A5)+ ;move in more HANDLE info
MOVB #40,(A5)+ ;a space
MOVB #'-,(A5)+ ;a dash
MOVB #40,(A5)+ ;a space
CLRB @A5 ;a null
;--- fill in information about CB:
; 1) get the "permanent user count" from CB.SYS
; 2) get everyone else's global message location
; 3) place YOUR global message location in CB.SYS
;
CBINFO: CALL SERCH ;find CB.SYS
LEA A4,GLOBAL(A3) ;A4 gets global msg buffer
LEA A5,USRLST(A3) ;A5 points to user pointer array
LEA A2,PRMCNT(A3) ;A3 points to "perm" count
CBIN: JLOCK ;--------------------------------------------------------
INCB 20(A1) ;increment total user count in CBSYS
MOVB 20(A1),@A2 ;get the count into user memory
LEA A1,24(A1) ;point A1 to user pointers
NXTUSR: CMP @A1,#0 ;is there a user pointer?
BEQ INYOU ;if not, put yourself in
MOV (A1)+,(A5)+ ;else move in the user pointer
BR NXTUSR ;and get next user
INYOU: MOV A4,@A1 ;blast in your global ^ to CBSYS
JUNLOK ;--------------------------------------------------------
LEA A5,USRNUM(A3) ;record "variable" user number too
MOVB @A2,@A5 ;by saving the "permanent" count
;--- set the "flag" for all other users currently on CB.SYS modification
;
MOVB @A2,D3 ;move in a counter
DECB D3 ;don't count yourself!
CMPB D3,#0 ;only one on?
BEQ CBSCRN ;yup, so skip rest of this portion
LEA A5,USRLST(A3) ;else repoint A5 to pointer arrays
FLAGON: MOV (A5)+,A4 ;get a pointer
ADD #120,A4 ;bypass GLOBAL area
MOVB #1,@A4 ;turn on the FLAG
DECB D3 ;one less guy to do
BNE FLAGON ;if more, do it again
LEA A5,FLAG(A3) ;get YOUR flag
MOVB #1,@A5 ;and turn it on
;--- Generate the transmission screen - give directions
;
CBSCRN: PRTTAB 377,44 ;screen off
PRTTAB 377,0 ;clear screen
PRTTAB 377,13 ;dim on
PRTTAB 377,40 ;reverse on
TYPE < Hit [CR] to clear line >
PRTTAB 377,14 ;dim off
TYPE < IntraNetwork CB (1.0) >
PRTTAB 377,13 ;dim on
TYPE < ESCape to quit >
PRTTAB 377,41 ;reverse off
PRTTAB 377,14 ;dim off
PRTTAB 3,2 ;move to here
TYPE < YOU: > ;your prompt
PRTTAB 377,35 ;cursor off
PRTTAB 377,45 ;screen on
MOVB #10,D5 ;D5 is column of where YOU are editing
TOP:
;--- Main loop!
; if input to your terminal, process it
; if only one on, hang out
; if others on (and "hash" of msg has changed), type out messages
; if "new" user on or "old" user off, redo pointers and count
; and update individuals screen
;
SLEEP #500 ;hang out a bit so CPU don't burn
TCKI ;any input lately?
BNE X ;nope
CALL OWNINP ;yup, so get the input and return here
X: LEA A4,FLAG(A3) ;get the flag (modification of users)
CMPB @A4,#1 ;is it on??
BNE P ;nope, so dont adjust pointer array
MOV #7,D1 ;get a bell
TTY ;and inform that a new user is on
CALL UPDATE ;update the pointers and count
MORUSR: LEA A2,PRMCNT(A3) ;get the perm count
CMPB (A4)+,(A2)+ ;if usernumber < perminent count
BGE EUPDAT ; then don't clear bottom line
ONLESS: DEC A2 ;repoint A2 to "old" count
MOVB @A2,D3 ;setup D3 to bottom row number
PRTONE D3 ;move to the bottom row
LEA A2,SPACES ;get spaces
TTYL @A2 ;clear bottom row (1 less user on CB)
EUPDAT: LEA A2,PRMCNT(A3) ;always move the variable user count
LEA A1,USRNUM(A3) ;to the "permanent" non-variable count
MOVB @A1,(A2)+ ;move it on in
CMPB @A1,#1 ;only one on?
BNE CHKMSG ;nope, so check the messages
LEA A4,FLAG(A3) ;yup, so we need to clear the FLAG
CLRB @A4 ;like this!
BR TOP ;and return to top
CHKMSG: CALL GETMSG ;else get the message(s)
BR TOP ;and return to TOP
P: LEA A4,PRMCNT(A3) ;get the user number
CMPB @A4,#1 ;only one on?
BEQ TOP ;then be boring (sleep)
BR CHKMSG ;else examine others msgs
;--- UPDATE subroutine: updates user pointers and number of users on CB
;
UPDATE: LEA A4,CBSYS(A3) ;get the pointer to CB.SYS
MOV @A4,A1 ;and place the pointer into A1
LEA A4,USRNUM(A3) ;A4 points to user number
LEA A2,GLOBAL(A3) ;get YOUR user pointer
LEA A5,USRLST(A3) ;array of user pointers
JLOCK ;---------------------------------------------------
MOVB 20(A1),@A4 ;A4 gets user count
LEA A1,24(A1) ;point A1 to user pointers
NEXT1: CMP @A1,#0 ;is there a user pointer?
BEQ NOMORE ;nope, all done
CMP A2,@A1 ;YOUR user pointer???
BNE GRBUSR ;nope, so branch to grab user
ADD #4,A1 ;else bypass it
BR NEXT1 ;and try again
GRBUSR: MOV (A1)+,(A5)+ ;move in the user pointer
BR NEXT1 ;and try again
NOMORE: JUNLOK ;---------------------------------------------------
RTN
;--- DING subroutine - if past your CB "buffer", BEEP and instruct
;
DING: MOV #7,D1 ;get a bell
TTY ;BEEP!
PRTTAB 4,5 ;place cursor here
LEA A5,ERRMSG ;get the error message
TTYL @A5 ;blast out error message
TICKI: TCKI ;any input yet?
BEQ INPCHK ;yup, see if an OK key...([CR] or DEL)
SLEEP #2500 ;else don't burn CPU time
BR TICKI ;and try again
INPCHK: KBD ;get the key (only DEL and CR allowed)
CMPB D1,#177 ;rubout??
BEQ OKKEY ;then ok key
CMPB D1,#15 ;return??
BEQ OKKEY ;then ok key
MOV #7,D1 ;else get a bell
TTY ;and scold them again!
BR TICKI ;and give them another chance
OKKEY: PUSH D1 ;save the key
PRTTAB 4,5 ;back to the row
LEA A5,SPACES ;ready for clear
TTYL @A5 ;clear the ERROR message
POP D1 ;retrieve the key
CMPB D1,#15 ;[CR]??
JEQ HITCR ;yup, so clear out the message
CALL BCKONE ;nope, must be DEL, so process
RTN ;and return (from "OWNINP")
;--- if an ESC. key was hit, modify CB.SYS, return to AMOS, and set "flag".
;
EXIT: LEA A4,CBSYS(A3) ;get the pointer to CB.SYS
MOV @A4,A1 ;and place the pointer into A1
LEA A2,GLOBAL(A3) ;get YOUR user pointer
LEA A5,USRLST(A3) ;array of user pointers
JLOCK ;---------------------------------------------------
LEA A1,20(A1) ;point A1 to user count
DECB @A1 ;one less user on CB
ADD #4,A1 ;point to Global msg list
MOV A1,A4 ;A4 points there too
NEXT2: CMP @A1,#0 ;is there a user pointer?
BEQ FLGSET ;nope, time to set everones flags
CMP A2,@A1 ;YOUR user pointer? (we want this)
BNE NOTYOU ;nope, so leave it alone
BUMPEM: ADD #4,A4 ;bypass YOUR pointer (with A4 only)
MOV @A4,(A1)+ ;and bump this guy over YOUR pointer
CMP @A4,#0 ;more to bump?
BNE BUMPEM ;yup
BR FLGSET ;nope
NOTYOU: ADD #4,A1 ;get next location
ADD #4,A4 ;get next location
BR NEXT2 ;and get next user (maybe YOU now)
FLGSET: LEA A2,PRMCNT(A3) ;get the number of users
MOVB @A2,D3 ;D3 is our counter
CMPB D3,#1 ;only one on?
BEQ OFF ;yup, so no flags to set
LEA A5,USRLST(A3) ;A5 to start (old) pointer array
NXTFLG: MOV (A5)+,A4 ;get a pointer
ADD #120,A4 ;bypass GLOBAL area
MOVB #1,@A4 ;turn on the FLAG
DECB D3 ;one less guy to do
BNE NXTFLG ;if more, do it again
OFF: JUNLOK ;---------------------------------------------------
QOFF: JOBIDX A6 ;get JCB
LEA A4,JOBTYP(A6) ;get processing word
ORW #^B10000000,@A4 ;set controlc
MOV JOBTRM(A6),A4 ;get terminal definition stuff
ANDW #17774,@A4 ;return screen to normal
PRTTAB 377,0 ;clear the screen
PRTTAB 377,34 ;cursor on
EXIT ;return to AMOS
SERCH:
;--- Setup pointer to get find CB.SYS
;
LEA A2,BUFFER ;point A2 to ascii CB.SYS
LEA A4,CBSYS(A3) ;point A4 to variable CBSYS
FILNAM @A4 ;convert ascii CB.SYS ---> RAD50
SRCH @A4,A1 ;A1 points to CB.SYS
LEA A4,CBSYS(A3) ;A4 points to variable to hold pointer
MOV A1,@A4 ;move in the pointer to CBSYS
RTN
OWNINP:
;--- own user input to get
;
MOVB #10,D5 ;HOME location less data
LEA A5,GLOBAL(A3) ;message line
ADD #13,A5 ;bypass perminent info
FNDNUL: CMPB @A5,#0 ;at a null yet?
BEQ INKY ;yup
INC A5 ;else try next location
INCB D5 ;and move cursor position (hash+10)
BR FNDNUL ;and try again
INKY: HOME D5 ;move cursor to correct spot
SUBB #10,D5 ;make D5 be the hash value (sneaky!)
PUSHB D5 ;save this baby (it goes everywhere)
KBD ;get the input
CMPB D1,#40 ;space or less?
BLT SPECL ;yup, so special processing
CMPB D1,#177 ;chech for rubout
JLT BYPASS ;if NOT, bypass the following
YESRUB: CALL BCKONE ;RUBOUT, so erase, and
LEA A5,GLOBAL(A3) ;get the message space junk
INC A5 ;point past ON/OFF byte
POPB @A5 ;move in "new" hash value (from D5)
DECB @A5 ;one less in hash
RTN ;and return
SPECL: POPB D5 ;restore stack (from D5)
CMPB D1,#33 ;escape?
JEQ EXIT ;yup, time to EXIT
CMPB D1,#15 ;return?
BEQ HITCR ;yup, time to clear message
JMP NXTCHR ;else disregard bogus input
HITCR: LEA A5,GLOBAL(A3) ;get the message junk
INC A5 ;bypass ON/OFF byte
CLRB @A5
;hash now "0"
ADD #12,A5 ;bypass handle et.al.
MOVB #77,D3 ;number of nulls to move in
MORNUL: CLRB (A5)+ ;place in a null
DECB D3 ;one less null to blast
BNE MORNUL ;still more to clear
MOVB #10,D5 ;get ready to go home
HOME D5 ;home we are (cursor wise)
MOVB #120,D3 ;counter
MOVB #40,D1 ;space character
CLRYOU: TTY ;type out a space
DECB D3 ;one less space to type
BNE CLRYOU ;still more to type
RTN ;end of clearing transmission
BYPASS: POPB D5 ;restore stack (from D5)
CMP D5,#77 ;hash too big? (there is a limit!)
JGE DING ;yup, so inform user too many chrs
TTY ;else blast out new input character
MOVB D1,(A5)+ ;and store the character in edit
LEA A5,GLOBAL(A3) ;get the message space junk
INC A5 ;point past ON/OFF byte
MOVB D5,@A5 ;move in "new" hash value
INCB @A5 ;one more in hash (so new msg shows)
NXTCHR: TCKI ;any input waiting?
JEQ OWNINP ;yup, so repeat this section
RTN ;else return to main loop
;--- BCKONE subroutine - erases a character on transmission input
;
BCKONE: CMPB D5,#0 ;room to go back?
BLE NOROOM ;nope
DEC A5 ;move A5 back one
CLRB @A5 ;and null it
PRTTAB 377,5 ;backspace cursor
MOVB #40,D1 ;move in a space
TTY ;type it out
PRTTAB 377,5 ;and back up
DECB D5 ;column is one less
NOROOM: RTN ;done erasing
;--- GETMSG subroutine - analyse other users activities and act accordingly
;
GETMSG: LEA A1,FLAG(A3) ;get the flag
CMPB @A1,#1 ;major update on CB?
BNE NMAJOR ;nope, so don't type all msgs out
CALL ALLOUT ;yup - type all msgs no matter what
RTN ;and return to TOP
NMAJOR: CALL HSHCMP ;else just compare hashes (maybe type)
RTN ;and return to TOP
;--- ALLOUT subroutine: type out all msgs no matter what
;
ALLOUT: LEA A6,USRNUM(A3) ;get the number of user msgs to type
LEA A4,USRLST(A3) ;A4 points to user pointers
AO: CLR D4 ;D4 is our "space" counter register
MOV (A4)+,A5 ;A5 points to OTHERS global msg
CLR D3 ;D3 will be our row number
MOVB @A6,D3 ;first get the count
PRTONE D3 ;and tab to this row
JLOCK ;------------------------------------------------------
CMPB (A5)+,#377 ;CB ON??
BNE AOUL ;nope - unlock and continue
INC A5 ;bypass the hash code total
AOSTAR: CMPB @A5,#0 ;at a NULL yet??
BEQ AOUL ;yup, no more typing needed
INC D4 ;else one less space to type
MOVB (A5)+,D1 ;and get the character of the msg
TTY ;type it out
BR AOSTAR ;and see if we are at the NULL yet
AOUL: JUNLOK ;------------------------------------------------------
MOV #40,D1 ;get a space
SPCOUT: TTY ;type it out
INC D4 ;one less space to type
CMP D4,#107 ;last space out?
BLE SPCOUT ;nope
LEA A6,USRNUM(A3) ;get the user count
DECB @A6 ;one less user to mess with
CMPB @A6,#1 ;only you left?
BNE AO ;nope, do above all over again
CALL NXTGET ;update user count since it's mucked
RTN ;and return to TOP
;--- HSHCMP subroutine: compare hash codes, type msg out if different
;
HSHCMP: LEA A6,USRNUM(A3) ;get the user count
LEA A4,USRLST(A3) ;A4 points to user pointers
LEA A2,HASHES(A3) ;A3 points to hash codes
HC: MOV (A4)+,A5 ;A5 points to OTHERS global msg
PUSH A5 ;save the pointer
INC A5 ;point to the hash code
CMMB @A5,(A2)+ ;same hash as last time?
BNE NEWHSH ;no, different hash, so output
POP A5 ;else restore stack
LEA A6,USRNUM(A3) ;get the user count
DECB @A6 ;one less user to test
CMPB @A6,#1 ;only you left?
BNE HC ;nope, still more users on
CALL NXTGET ;else update user count
RTN ;and return to TOP
NEWHSH: DEC A2 ;different hash, so repoint A2
MOVB @A5,(A2)+ ;move in different hash for next time
MOV #11,D4 ;12 spaces we KNOW don't need typed
ADDB @A5,D4 ;plus hash (although a bit much)
POP A5 ;point to msg
CLR D3 ;D3 will be the row number
MOVB @A6,D3 ;add user count to the row number
ADD #5,D3 ;move it down by 5
JLOCK ;------------------------------------------------------
CMPB (A5)+,#377 ;CB ON??
BNE HCUL ;nope
CMPB (A5)+,#0 ;no message to type (due to [cr]?)
BNE STLSTF ;still stuff to type so branch
OVER D3,D4 ;tab over to here
CLR D4 ;D4 is our space counter
MOV #40,D1 ;D1 contains a space
CLRMSG: TTY ;start clearing the msg spc by spc
INC D4 ;one less space to type
CMP D4,#105 ;done clearing???
BLE CLRMSG ;nope
BR HCUL ;yup, blow by rest of JLOCK
STLSTF: SUB #7,D4 ;don't lose any characters.
OVER D3,D4 ;tab to here
DEC D4
ADD D4,A5 ;make A5 point to "end" of prev. msg
TTYL @A5 ;and then type out new additions
HCUL: JUNLOK ;------------------------------------------------------
MOV #40,D1 ;get a space
TTY ;type out a few spaces
TTY ;just incase of backrubs
LEA A6,USRNUM(A3) ;get the user count
DECB @A6 ;one less user
CMPB @A6,#1 ;only you left?
JNE HC ;nope, do this mess again
CALL NXTGET ;else update user count
RTN ;and return to TOP
;--- NXTGET subroutine: updates user count for TOP
;
NXTGET: LEA A1,USRNUM(A3) ;get user count (variable)
LEA A4,PRMCNT(A3) ;and the "permanent count"
MOVB @A4,(A1)+ ;reset variable user number
LEA A1,FLAG(A3) ;get the flag
CLRB @A1 ;clear it even if it is already clear
RTN ;and return to caller
BUFFER: ASCII /CB.SYS/ ;the file that is in SYSTEM memory
EVEN
SPACES: ASCII / /
BYTE 0
EVEN
ERRMSG: ASCII / End of buffer... hit [CR] to clear or RUBOUT to edit/
BYTE 0
EVEN