home *** CD-ROM | disk | FTP | other *** search
Text File | 1994-09-02 | 39.0 KB | 1,618 lines |
- .sall
- .sfcond
- ; Program: ZBYE
- ; Author: Jay Denebeim
- ; Assembler: M80 Version 3.44 or greater. (SLRMAC ETB)
- version equ 12
- rev equ 'Z'
- ;
- ; ZCPR Bye RCP
- ;
- ; This program implements BYE as an RCP under ZCPR3. It handles all modem
- ; IO by replacing the console routines. All other functions are passed to
- ; the ZCPR CCP for execution. Where BYE normally uses equates, I.E. password
- ; connection, carrier lost commands, etc., ZBYE passes command lines to ZCPR.
- ; This should reduce the bugs introduced by tons of conditional assemblies
- ; that has plagued the recent versions of BYE. It has also allowed room to
- ; do more functions than BYE normally has done in the past. Please folks,
- ; lets keep the conditional assemblies down to a minimum.
- ;
- ; There are several new features in this program:
- ; Since its an RCP BYE can remain resident while the SYSOP is using
- ; the computer locally. ZBye will answer the phone while in this mode,
- ; and allow the operator to accept the call while in another program.
- ; A chat mode has been implemented, this allows either single way, or
- ; two way communication between the sysop and the caller.
- ; It will also allow changes of the Maximum drive and user area
- ; without disabling the modem IO.
- ;
- ; The function key descriptions:
- ; ^L - Toggle Local only IO. This toggles the modem IO on and off.
- ; ^O - Toggle Open access. This switches the wheel, maxdrive, and
- ; maxuser bytes of ZCPR3. NOTE: this is the location your
- ; BBS, XMODEM, and whatever else should check. Its no longer
- ; in the BYE header. Also, be sure to watch the user while
- ; he's on in this mode, either disable the modem, or be ready
- ; with the ^N.
- ; ^N - Nerdkey, Hang up on the bozo
- ; ^Q - Query the user, (CHAT mode), end with ^C. This is a very
- ; rudimentrary chat. If local only, he can't type back,
- ; but if not, its two way. Be sure to announce yourself
- ; 'cause ZBYE doesn't anounce when its going into chat mode.
- ; the only editing commands implimented are expansion of
- ; <cr> to <cr><lf>.
- ;
- ; To install this program, install your terminal dependent code following
- ; the .8080 psudo-op. ZBYE was set up to use MBYE overlays, these are either
- ; very similar, or identical to BYE2.x or 3.x overlays. Remember that
- ; EQUates can't have :'s in front of them for M80, so you'll probably have
- ; to do a global replace of :^IEQU with ^IEQU. I'd really appreciate it if
- ; you would send me a copy of your overlay when you finish it.
- ; You will also have to change the terminal dependent cursor
- ; functions to match your own system.
- ;
- ; This program is the first in a series of ZCPR RCPM software. Look for
- ; ZBBS, ZXMODEM, ZDIR, and ZCHAT at a RCPM near you.
- ;
- ; Copyright 1985, by Jay Denebeim. This program is released to the public
- ; domain. It can be freely given, but under no circumstances will this
- ; software be charged for, except a copying fee not to exceed the price of
- ; the media copied to.
- ;
- ; I hope you enjoy using this program as much as I enjoyed writing it.
- ; If you make any modifications to this program, or have any suggestions,
- ; please feel free to contact me.
- ; Thanks a bunch,
- ; Jay Denebeim
- ; 1800 Williamsburg Rd Apt 13-E <- NOTE: Address and phone number new.
- ; Durham, NC 27707
- ; (919) 489-1785 (voice)
- ; (919) 489-6737 (data)
- ;
- ;-----------------------------------------------------------------------
- ;
- ; Revision History:
- ;
- ; 1.2Z Extensive revisions to accomodate a dumb UART which cannot detect
- ; carrier or cause the modem to answer or hangup. Code reorganized
- ; to place all UART code in one place where it can be handled as
- ; an overlay, all modem code in another overlay (smart or dumb)
- ; and all terminal code in another overlay (25th line for status
- ; or not). Added conditional code generation to prevent meddling
- ; with the wheel byte if z3whl=0.
- ; Earl T. Boone
- ;
- ; 1.2A *** Release Version *** Fourth public release.
- ; Implemented answer routines for a dumb modem. Set the equate
- ; DUMB to yes and baud rate will be set by carriage return
- ; sence. Also moved initializing modem message to the right place.
- ; Jay Denebeim 09/08/85
- ;
- ; 1.1F Added equates for most major functions of this program. Also moved
- ; the command lines to the top of the file so they're easier to find.
- ; Please, when adding functions, make sure they turn all the way off
- ; CREF is great for finding code that isn't used when functions are
- ; turned off. Jay Denebeim 09/14/85
- ;
- ; 1.1E Added KILCALR equate. This switches on routines that will kill
- ; the caller if the byte at 0 is not equal to C3. NOTE: this brought
- ; the size over the limit on my system. The dumb modem routines
- ; are enough smaller that this will fit in dumb mode.
- ; Jay Denebeim 09/09/85
- ;
- ; 1.1D Added an equate to allow the printer to be enabled by the wheel.
- ; Set the LSTDEV equate to YES if you want the printer available
- ; while ZBye is running. Do be careful with this, most CP/M systems
- ; lock up if the printer is not on-line during an attempt to print.
- ; Don't run any programs that print remotely unless you're sure the
- ; printer is on-line. Jay Denebeim 08/19/85
- ;
- ; 1.1C *** Release Version *** Third public release.
- ; While modifing LUX4.0 to 4.1, I was reminded that time outs are
- ; very similar to carrier losses. So, the carrier loss interupt
- ; also means time out. To the program running under ZBYE, the reason
- ; for the loss of user isn't important. Jay Denebeim 02/15/85
- ;
- ; 1.1B Made Wheel on status line follow what the wheel was actually
- ; set to. Input Timed out msg was in the wrong place, and was erased
- ; when bye ran again. Jay Denebeim 02/02/85
- ;
- ; 1.1A *** Release Version *** Second public release.
- ; Cleaned up the comments, and stripped out the modem dependent
- ; routines. Jay Denebeim 01/11/85
- ; 1.0G Changed carrier lost routine to restart # 30 so that programs
- ; could do their own thing on CLOSS. Added check for wheel change
- ; so the sysop drives would follow the wheel.
- ; Jay Denebeim 01/11/85
- ; 1.0F Moved BYE initialization routines into low memory. This freed
- ; up some memory, and allowed another bit to implement another
- ; routine. This routine runs a set of programs before hanging
- ; the modem up Jay Denebeim 01/10/85
- ; 1.0E Moved local char status, and bye mode bytes into low memory
- ; so they will be available for other programs.
- ; Jay Denebeim 01/09/85
- ; 1.0D If wrong characters typed during local mode answer, the caller
- ; would get hung up on. Jay Denebeim 01/09/85
- ; 1.0C Reduced the size of the program. RCP was overflowing.
- ; Jay Denebeim 01/08/85
- ; 1.0B Answer phone while in local mode. Jay Denebeim 01/07/85
- ; 1.0A First public release. by - Jay Denebeim 12/23/84
- ;
- ;-----------------------------------------------------------------------
- ;
- ;
- ; Equates for this program
- ;
- .xlist
- maclib E:Z3BASE.LIB
- .list
- ;
- no equ 0
- yes equ not no
- cr equ 0dh ; carriage return
- lf equ 0ah ; line feed
- ;
- bdos equ 5
- bios equ 0
- ;
- mhz equ 20 ; CPU speed times 10
- closs equ 1 ; Number of seconds to wait after loss of carrier
- clrou equ 30h ; Routine to call on loss of carrier
- jump equ 0c3h ; 8080/Z80 jump instruction
- ;
- ; Conditional assembly macros. Use these to switch functions on and
- ; off.
- ;
- etb equ yes ; Special functions for Earl T Boone
- ;
- obye equ no ; Emulate BYE3.x ?
- dumb equ no ; Is this system running under a dumb modem?
- lstdev equ no ; Enable printer when wheel is set?
- kilcalr equ yes ; Kill the caller if memory location 0 <> C3
- timeout equ yes ; yes, auto logout for sleepy callers
- tomins equ 2 ; minutes to auto logout
- tmins equ ((tomins*mhz)+5)/10 ;(don't change this one...)
- statln equ no ; display the status on line 25
- ; (see terminal dependent section)
- chatf equ yes ; provide chat function
- lclans equ yes ; answer modem while in local mode
- ;
- cdrive equ 'E'-'@' ; Callers Maximum Drive
- cuser equ 31 ; Callers Maximum User Area
- ;
- lclst equ 003bh ; Local Console generated character flag
- bymode equ 003fh ; Bye control byte
- ;
- ; The BYE mode byte is bit mapped and has the following attributes:
- ;
- bymmio equ 80h ; 7 = Modem IO enable
- bymcio equ 40h ; 6 = Console IO enable
- bymica equ 20h ; 5 = Ignore Carrier
- bymncc equ 10h ; 4 = Next Caller Commands Running
- bymclc equ 08h ; 3 = Carrier Lost Commands Running
- bymnor equ 04h ; 2 = Normal Mode Commands Running
- bymaoc equ 02h ; 1 = Alert Operator on Call
- bymphu equ 01h ; 0 = Pre-Hangup Commands Running
- ;
- ;-----------------------------------------------------------------------
- ;
- ; Global Macros
- ;
- cmdln macro cmd
- local cmdst,msg,cmdend
- cmdst: dw z3cl+msg-cmdst
- db z3cls,0
- msg: db cmd
- db 0
- cmdend:
- endm
- ;-----------------------------------------------------------------------
- ;
- ; Command line macros
- ;
- byecl macro ; Executed during initialization
- cmdln 'BYE'
- endm
- ;
- gbcl macro ; Executed before normal disconnection
- cmdln 'BYE'
- endm
- ;
- nccl macro ; Executed between calls
- ; cmdln 'A0:;LDR RCPM.NDR;PATH A0:;BYE' ; JD's original
- cmdln 'A0:;PATH E0: A0: A15: E0:;BYE' ; ETB's revision
- endm
- ;
- nmcl macro ; Executed upon connection
- ; cmdln 'A0:;RBBS;MENU' ; JD's original
- cmdln 'E0:;LDSK B:;LDSK C:' ; ETB's revision
- endm
- ;
- clcl macro ; Executed if carrier lost
- cmdln 'BYE'
- endm
- ;
- tocl macro ; Executed if timed out
- cmdln 'BYE'
- endm
- ;
- kccl macro ; Executed if call killed by higher process
- cmdln 'BYE'
- endm
- ;
- ;-----------------------------------------------------------------------
- ; TPA starts here
- ;-----------------------------------------------------------------------
- ;
- ; Lets get this show on the road
- ;
- MACLIB Z80
- aseg
- org 100h
- ;
- ; Lets see if BYE is already resident.
- ;
- lxi h,rcp ; Point to RCP area
- lxi d,bybeg ; Point to RCP's name
- lxi b,5 ; Length of name
- chbye1: ldax d ; Get next char
- cci ; Is it the same?
- jrnz nbye ; Nope, re-locate the RCP
- jpo ybye ; If done, its there
- inx d ; Point to next char
- jr chbye1 ; Do it again
- ;
- nbye: mvi c,9
- lxi d,nbst
- call 5
- xra a
- sta lclst ; Clear out local status
- sta bymode ; and Bye's operating mode
- lxi h,bybeg
- lxi d,rcp
- lxi b,byend-bybeg
- ldir ; Re-Locate BYE
- mvi a,jump ; load A with JUMP instruction
- sta clrou ; and put in restart
- lxi h,lostit ; do the same
- shld clrou+1 ; with original closs command line
- call byeini
- jmp ybye
- nbst: db 'ZBye version '
- db '0'+(version/10), '.', '0'+(version mod 10), rev
- db ' - By Jay Denebeim Copyright (C) 1985',cr,lf
- db 'Making BYE',cr,lf,'$'
- ;
- ybye: lxi h,bye
- lxi d,z3cl
- lxi b,byelen
- ldir ; Load 'BYE' into command line
- ;
- jmp 0
- ;
- bye: byecl
- byelen equ $-bye
- ;
- byeini: lda z3env+2ch ; store away, sysop's Highest drive
- sta sdrive
- lda z3env+2dh ; and user area.
- sta suser
- lda fstprv ; Store first letter of private
- sta prvlet ; commands
- call newbio
- call clrbuf
- call modini
- mvi a,bymmio+bymcio+bymica+bymclc
- sta bymode
- ret
- ;
- ; The folowing code should logically be located in the UART and MODEM
- ; hardware specific overlay area of the code. It is located here
- ; to save space in the RCP by doing these initialization functions
- ; (only executed once) in the TPA.
- ;
- ; Initialize the UART (interface to modem)
- ;
- modini:
- call mdinit ; Initialize serial port
- mvi b,3
- call ldelay ; delay .3 sec
- call mdansw ; raise dtr
- call delay
- call set1200 ; 1200 baud
- call delay
- mvi a,bymmio+bymica
- sta bymode ; enable modem io
- if not dumb
- call prinlo ; reset modem
- db 'ATZ',cr+80h ; at this point we don't know
- ; whether the command will be echoed
- ; or whether the status will be
- ; numeric or verbal
- call l2char ; is it status
- cnz l2char ; if not - try again
- ;
- ; the next command will echo or not based strictly on the physical
- ; switches on the modem itself
- ;
- call prinlo ; set our way
- db 'ATS0=0' ; never answer
- db 'V0' ; numeric status codes
- db 'E0' ; no command echo
- db 'X1' ; extended status
- db 'M1',cr+80h ; speaker off at connect time
- call l2char ; get echo
- cnz l2char ; get status
- jnz modini ; status ok?
- endif ; dumb
- ret
- ;----------------------------------------------------------------------
- ; RCP starts here
- ;----------------------------------------------------------------------
- bybeg:
- .phase rcp
- db 'ZBYE ' ; RCP's name for ZCPR
- db 3 ; Command name length
- fstcmd: db 'BYE'
- dw start
- fstprv: db 'OFF'
- dw byeoff
- db 0
- ;
- start:
- pop h ; Get ZCPR3's return address
- shld z3ret ; Save it
- lxi h,bymode
- bit 0,m
- jnz prophu ; Process pre-hangup commands
- bit 1,m
- jnz prolcl ; Process a local exit
- bit 2,m
- jnz pronor ; Process a normal exit
- bit 3,m
- jnz proclc ; Carrier lost commands finished
- bit 4,m
- jnz proncc ; Next caller commands finished
- call prinpl
- db 'Invalid BYE mode! BYE terminating',7,cr,lf+80h
- jr byeof1
- ;
- byeoff:
- pop h ; Get ZCPR3's return address
- shld z3ret ; Save it
- byeof1: call oldbio
- mvi a,0
- sta rcp ; Disable RCP recognition
- sta fstcmd ; and for the CCP
- lxi h,bymode
- res 7,m ; Turn off modem IO
- if statln
- call prinlc
- enab25 no
- cls yes ; enable 25th line and clear screen
- endif ; statln
- call prinpl
- db 'Bye is gone',cr,lf+80h
- jmp exit
- ;
- ; Local storage initialized by loader
- sdrive: db 0 ; sysop's max drive
- suser: db 0 ; sysop's max user
- prvlet: db 0 ; priviledged letter
- ;
- ; Process pre-hangup commands
- ;
- prophu: mvi a,bymcio+bymmio+bymnor ;con enab, modem enab, normal caller
- sta bymode
- ;
- lxi h,gbcmd ; Load next command string
- lxi b,gblen
- lxi d,z3cl
- ldir
- jmp exit
- ;
- gbcmd: gbcl
- gblen equ $-gbcmd
- ;
- ; Process a local exit, actually a modified normal answer, but must check
- ; for carrier present.
- ;
- prolcl: call mdcarck
- jrz prolc1 ; If no carrier, just get ready for next call
- mvi a,0ffh ; set flag
- sta prlct1
- jr prolc2 ; get ready for next caller
- ;
- prlct1: ds 1
- ;
- ; Process a normal exit. This routine runs any programs to end the
- ; session, says Bye, hangs up the modem, turns off the modem IO,
- ; then runs the routines to get ready for the next caller.
- ;
- pronor: call prinpl
- db 'Goodbye, call again soon!',cr,lf+80h
- ;
- prolc1:
- call prtsta
- db 60,,13
- ;
- ; If carrier lost, no point in printing msg
- ;
- proclc:
- call mdinit
- prolc2: mvi a,bymcio+bymncc ;con enab, nxt calr mode
- sta bymode
- ;
- call clrbuf
- call ressec
- ;
- lxi h,nccmd ; Load next command string
- lxi d,z3cl
- lxi b,nclen
- ldir
- jmp exit
- ;
- nccmd: nccl
- nclen equ $-nccmd
- ;
- ; Ready for next caller. Set secure mode, then wait for arrival.
- ;
- proncc:
- call cursoff ; turn off cursor
- call prtsta
- db 40,,19
- call clrscr ; clear screen
- call setsec
- mvi a,bymcio+bymphu
- sta bymode
- lda prlct1 ; ending local mode ?
- cpi 0ffh
- push psw
- xra a
- sta prlct1 ; zero it anyway
- pop psw
- jrz pronc2
- call nxtcal
- pronc1: call modans
- call mdcarck ; No Carrier?
- jrz pronc1 ; Then loop
- pronc2:
- call curson ; turn cursor on
- call prtsta
- db 60,'Connected',0
- lxi h,bymode
- setb 7,m ; Make sure modem is on
- res 5,m ; and carrier significant
- call prinpl
- db 'Welcome to ZBoard',cr,lf
- db 'You are now running under ZBYE version '
- db '0'+(version/10), '.', '0'+(version mod 10), rev, cr, lf+80h
- ;
- lxi h,nmcmd ; Load normal entry command string
- lxi d,z3cl
- lxi b,nmlen
- ldir
- jmp exit
- ;
- nmcmd: nmcl
- nmlen equ $-nmcmd
- ;
- ; Set ZCPR into a secure mode
- ;
- if z3whl
- setsec: call usrdru
- xra a
- sta z3whl ; Clear the wheel
- sta fstprv ; And private commands
- ret
- ;
- ; Set highest drive and user area for caller.
- ;
- usrdru: mvi a,cdrive ; Set Caller's highest drive
- sta z3env+2ch
- mvi a,cuser
- sta z3env+2dh ; and user area.
- push psw
- push h
- call prtsta
- db 40,'Not Wheel',0
- pop h
- pop psw
- ret
- else
- setsec: ret ; not a secure system
- endif ;z3whl
- ;
- ; Set ZCPR into sysop mode
- ;
- if z3whl
- ressec: call sysdru
- xra a
- cma
- sta z3whl ; Set the wheel
- lda prvlet ; and private commands
- sta fstprv
- ret
- ;
- ; Set highest drive and user area for SysOp.
- ;
- sysdru: lda sdrive ; Set Sysop's highest drive
- sta z3env+2ch
- lda suser
- sta z3env+2dh ; and user area.
- call prtsta
- dc 40,' Wheel',0
- ret
- else
- ressec: ret ; not a secure system
- endif ;z3whl
- ;
- ; Clear ZCPR's internal buffers
- ;
- clrbuf: xra a
- ;
- if z3env
- lxi h,z3env+80h ; Clear TCAP area
- lxi d,z3env+81h
- lxi b,7eh ; TCAP length-1 (always?)
- mov m,a
- ldir
- endif ;z3env
- ;
- if shstk
- lxi h,shstk ; Clear Shell Stack
- lxi d,shstk+1
- lxi b,shstks*shsize-1
- mov m,a
- ldir
- endif ;shstk
- ;
- if z3msg
- lxi h,z3msg ; Clear Message Buffers
- lxi d,z3msg+1
- lxi b,4eh ; Message buffer length -1
- mov m,a
- ldir
- endif ;z3msg
- ;
- ret
- ;
- ; Answer modem and wait for carrier. Set baud as appropriate.
- ;
- modans:
- call prtsta
- db 30,'Awaiting Call',0
- mdans00 call modans0
- rz
- cpi 'C'-'@' ; Control C from console?
- jnz mdans00 ; Nope
- lxi h,bymode
- bit 1,m ; if in local bye active mode
- jnz mdans00 ; then forget the console
- res 7,m ; inhibit modem IO
- setb 1,m ; go into local bye active mode
- res 0,m ; make sure not in pre-hangup
- call ressec
- call curson ; turn on cursor
- call prtsta
- db 60,'Local',7
- if lclans
- jmp exit
- else
- jmp byeof1
- endif ; lclans
- ;
- ; Get ready for next caller
- ;
- nxtcal:
- if timeout
- xra a ; Clear timeout
- sta tocnt
- sta tocnt+1
- mvi a,tmins
- sta toval
- endif ;timeout
- ;
- call mdinit ; drop DTR
- mvi b,3
- call ldelay ; wait awhile
- call mdansw ; raise it
- call delay
- call set1200
- call delay
- call sync ; synchronize modem
- ;
- if lclans
- ; Check for call coming in during local mode. If so, answer it.
- ;
- chkcal: lda chkt1
- ora a
- rnz ; return if already doing function
- call mdcarck ; check for call still in progress
- jrnz chkca4 ; yup
- xra a
- sta chkt2 ; he's gone
- chkca4: lda chkt2
- ora a ; if this function already run
- rnz ; return to caller
- mov a,m ; Get BYMODE
- sta chkt1 ; indicate function running
- push psw
- res 6,m ; Turn off console
- setb 7,m ; Turn on modem
- setb 5,m ; Ignore Carrier
- call incmcl ; check for incoming call
- jz chkca1
- call mdcarck ; Got carrier?
- jz chkca1 ; Nope
- lxi h,bymode
- res 6,m
- push h
- call prinpl
- db cr,lf,'Asking SYSOP if you can get on.',cr,lf+80h
- call mdcarck ; Hung up?
- jz chkca1 ; Oh well
- chkca2: call oconst
- jrz chkca3
- call conin
- jr chkca2 ; Eat console characters if any
- chkca3: if statln
- call go25
- call prinlc
- curpos 0,24,no
- else
- call prinlc
- endif ; statln
- dc 'Caller, let on ? '
- call oconin
- sta chkt1
- if statln
- call no25
- endif ; statln
- call mdcarck ; Still with us?
- pop h
- jrz chkca1 ; Nope, his loss
- setb 7,m
- res 6,m ; Set for remote IO
- lda chkt1
- ani 'Y'
- cpi 'Y'
- jrz letliv ; If Y or y let him on
- call prinpl
- db 'Sorry, try again later',cr,lf+80h
- call nxtcal
- jr chkca1
- letliv: call prinpl
- db 'He will let you on soon, please hold',cr,lf+80h
- mvi a,0ffh
- sta chkt2 ; indicate call in progress
- chkca1: xra a
- sta chkt1 ; zero out storage
- pop psw ; Get original BYMODE
- sta bymode
- ret
- chkt1: ds 1
- chkt2: ds 1
- ;
- endif ; lclans
- ;
- ; Check for carrier available. If not there, return with zero flag set.
- ;
- carok: push h ; Do we care?
- lxi h,bymode
- bit 5,m
- pop h
- rnz ; Nope
- push b
- mvi b,closs*10
- carok1: call mdcarck ; Got carrier?
- jrnz carok2 ; Yup, great
- call delay ; nope, wait awhile
- djnz carok1 ; try again
- carok2: pop b
- ret
- ;
- ; Carrier lost. Drop Dead.
- ;
- lostit: lda clgat
- ora a
- jrnz lstit1 ; Check for no status gate
- ;
- call prtsta
- db 60,'Carrier Lost',0
- ;
- mvi a,bymcio+bymclc
- sta bymode
- lxi h,clcmd ; this is what we want to do
- lxi d,z3cl ; point to zcpr's command line
- lxi b,cllen
- ldir
- lstit1:
- mvi a,jump ; just to be safe
- sta 0
- xra a
- sta clgat ; Clear no status gate
- jmp 0 ; Gotta exit this way
- ;
- clcmd: clcl
- cllen equ $-clcmd
- clgat: db 0 ; gate for carrier lost command
- ;
- if timeout
- ;
- ; Must be too late at night. He's asleep.
- ; Input timed out.
- ;
- timout:
- if etb
- mvi a,0
- sta carion ; mark 'carrier off'
- endif
- mvi a,0ffh
- sta clgat ; Flag the timeout
- call prinpl
- db 'Input timed out',7,cr,lf+80h
- call prtsta
- db 60,'Timed Out',3
- ;
- mvi a,bymcio+bymclc
- sta bymode
- lxi h,tocmd ; this is what we want to do
- lxi d,z3cl ; point to zcpr's command line
- lxi b,tolng
- ldir
- rst clrou/8 ; Do a CLOSS restart
- ;
- tocmd: tocl
- tolng equ $-tocmd
- ;
- endif ;timeout
- ;
- if kilcalr ; allow programs to commit suicide
- ;
- ; Memory Location 0 not C3H program abort
- ; If the base of memory is not a jump instruction, this routine will
- ; be executed. It is similar to a carrier lost, or timeout routine.
- ; Any program which changes the byte will cause the caller to be
- ; dropped unceremoniously.
- ;
- kilcal: mvi a,0ffh
- sta clgat ; Set the gate
- mvi a,jump
- sta 0 ; replace the jump instruction
- call prtsta
- db 60,'Call Killed',1
- ;
- mvi a,bymcio+bymclc
- sta bymode
- lxi h,kccmd ; this is what we want to do
- lxi d,z3cl ; point to zcpr's command line
- lxi b,kclng
- ldir
- ; rst clrou ; Do a CLOSS restart
- rst clrou/8 ; assembler uses other syntax
- ;
- kccmd: kccl
- kclng equ $-kccmd
- endif ; kilcalr
- ;
- ; Routines which process local function keys.
- ;
- ; Here are the descriptions
- ; ^L - Toggle Local IO
- ; ^O - Toggle Open access
- ; ^N - Nerdkey, Hang up on the bozo
- ; ^Q - Query the user, (CHAT mode)
- ;
- fkeys: lxi h,bymode ; BYE in inactive state?
- bit 1,m
- rnz ; Yes, return
- cpi 'L'-'@' ; Control-L ?
- jrz toglcl ; if so, toggle local mode
- cpi 'O'-'@' ; Control-O ?
- jrz togope ; Yes? Toggle security
- cpi 'N'-'@' ; Control-N ?
- jz twitem ; Goodbye bozo
- ;
- if chatf
- cpi 'Q'-'@' ; Control-Q
- jz bychat ; Go into Chat Mode
- endif ;chatf
- ;
- ret ; Not a BYE function Key
- ;
- ; Toggle Local IO Mode
- ;
- toglcl: bit 7,m
- jrz toglc1 ; If set, reset it.
- res 7,m
- call prtsta
- db 51,'Local Disabled',0
- jr endfun
- toglc1: setb 7,m
- call prtsta
- db 51,'Local',8
- jr endfun
- ;
- ; Toggle Security
- ;
- togope: lda fstprv
- ora a ; Secure?
- jrz togop1 ; If so, remove it
- call setsec ; Turn on security
- jr endfun
- togop1: call ressec ; Turn it off
- jr endfun
- ;
- ; Hang up on the bum.
- ;
- twitem:
- call curson
- call prtsta
- db 60,'Twitted off',0
- jmp proclc ; Same as Carrier loss
- ;
- ; End Function Key routines
- ;
- endfun: xra a ; No character entered
- ret
- ;
- if chatf
- ;
- ; Bye's Chat Mode
- ;
- bychat:
- call conin ; pitch out the ^Q
- call prtsta
- db 46,'Chat',0
- call prinpl
- dc 'Chat',cr,lf
- bycha2: call conin ; end on control c
- cpi 'C'-'@'
- jrz bycha3
- bycha1: push psw
- push h
- push b
- mov c,a
- call conout
- pop b
- pop h
- pop psw
- push psw
- bit 7,m
- cz mconout ; print it to modem if not enabled
- pop psw
- cpi 'M'-'@'
- jrnz bycha2 ; Loop if not a carriage return
- mvi a,'J'-'@'
- jr bycha1 ; And append linefeed if there
- bycha3:
- call prinpl
- dc 'End Chat',cr,lf
- call prtsta
- db 46,,4
- jmp endfun
- ;
- endif ; chatf
- ;
- exit:
- z3ret equ $+1 ; point to code to modify
- jmp $-$ ; ZCPR's return address
- ;
- prinlc: lda bymode ; Get current Mode
- sta pritmp ; Save it
- res 7,a ; turn off modem IO
- setb 6,a ; turn on lcl IO
- sta bymode
- xtix ; print the string
- call print
- xtix
- lda pritmp ; restore mode
- sta bymode
- ret
- pritmp: db 0
- ;
- prinpl: xtix ; Get string starting address
- call print ; Print it
- xtix ; Since we're pointing to next code location
- ret ; Go there!
- ;
- prinlo: xtix ; Get string starting address
- call print ; Print it
- ; call delay ; My modem is too d**n slow
- xtix ; Since we're pointing to next code location
- ret ; Go there!
- ;
- print: ldx a,0 ; Get next char
- bit 7,a ; Check for Carry
- push psw
- res 7,a ; Mask Carry Bit
- mov c,a
- call conout ; Print it
- inxix ; point to next char
- pop psw
- rnz
- jr print
- ;
- ;
- ;.1 sec delay routine
- ;
- delay: push b
- lxi b,4167*(mhz/10)+417*(mhz mod 10) ; constant * MHz10x
- ;
- delay1: dcx b
- mov a,b
- ora c
- jrnz delay1
- pop b
- ret
- ;
- ;.001 sec delay routine
- ;
- sdelay: push b
- lxi b,42*(mhz/10)+4*(mhz mod 10) ; constant * MHz10x
- jr delay1
- ;
- ; Long delay routine, B contains # of .1 sec delays
- ;
- ldelay: call delay
- dcr b
- jrnz ldelay
- ret
- ;
- newbio: lhld bios+1 ; Point to bios start
- mvi l,0
- lxi d,tolst ; Point to storage table
- lxi b,tolen-tolst ; table length
- ldir ; Save old jump table
- lxi h,tnlst ; Point to new jump table
- lded bios+1
- mvi e,0
- lxi b,tnlen-tnlst
- ldir ; We are now running under BYE
- ret
- ;
- oldbio: lxi h,tolst ; Put things back the way they were
- lded bios+1
- mvi e,0
- lxi b,tolen-tolst
- ldir
- ret
- ;
- tolst:
- ocboot: jmp 0
- owboot: jmp 0 ; This will hold the BIOS routines
- oconst: jmp 0 ; BYE will modify
- oconin: jmp 0
- oconout: jmp 0
- olist: jmp 0
- opunch: jmp 0
- oreader: jmp 0
- tolen:
- ;
- tnlst:
- cboot:
- if obye ; Emulate Old BYE?
- jmp fakeit
- else
- jmp 0
- endif
- wboot: jmp owboot ; Here is the new jump table
- const: jmp bconst
- conin: jmp bconin
- conout: jmp bconout
- if lstdev ; retain printer for sysop?
- list: jmp whlst
- else
- list: jmp mconout
- endif ; lstdev
- punch: jmp bconout
- reader: jmp bconin
- tnlen:
- ;
- ; Structure to look like the old byes
- ;
- if obye
- fakeit: ds 15
- dw oconout
- db 'BYE'
- endif
- ;
- ; Routines patched in by BYE
- ;
- bconst:
- if z3whl
- lda z3whl
- lxi h,owheel ; check for wheel change
- cmp m
- jrz bcst3
- sta owheel
- ora a ; wheel set?
- cz usrdru ; then set remote dru
- cnz sysdru ; else set sysop dru
- endif ;z3whl
- bcst3: lxi h,bymode ; local console enabled?
- bit 6,m
- jrz bcst1 ; nope, don't check
- push h ; used later
- if lclans
- bit 1,m ; In local mode ?
- cnz chkcal ; check for a caller
- endif ; lclans
- lda lchar ; got an uneaten one?
- ora a
- jrnz bcst2 ; Yup, still have it
- call oconst ; check con status
- ora a
- pop h
- sta lchar ; flag local char
- sta lclst
- jrz bcst1 ; no char
- push h
- call oconin ; get local char
- call fkeys ; check and process local function keys
- bcst2: pop h
- sta lchar ; store away char
- ora a ; make flags follow a
- ret
- ;
- bcst1: bit 7,m ; Modem enabled?
- rz ; Nope, don't bother
- ;
- if kilcalr ; Kill caller if loc 0 <> jump
- lda 0
- cpi jump
- jnz kilcal ; Kill him if instructed by higher program
- endif ; kilcalr
- ;
- call carok ; Check for carrier
- jz clrou ; Fool dropped carrier on us
- call mdinst ; Check for modem status
- rnz ; Everything's hunkey dory
- ;
- if timeout
- push h
- lxi h,bymode
- bit 5,m ; Paying attention to carrier
- jrnz ndata
- lxi h,tocnt ;No data, incr. timeout counter
- inr m
- jrnz ndata ;don't timeout yet
- inx h
- inr m ;next byte of counter
- jrnz ndata
- lxi h,toval ;1 "minute", no data
- dcr m
- jrnz ndata ;still not timed out...
- jmp timout ;finally... timed out...
- ;
- ndata:
- xra a ;no character for sure
- pop h
- endif ; Timeout
- ;
- ret
- ;
- toval: ds 1
- tocnt: ds 2
- lchar: db 0
- owheel: db 0
- ;
- bconin: call bconst ; Wait for char avail
- ora a
- jrz bconin
- ;
- if timeout
- xra a ; Clear timeout
- sta tocnt
- sta tocnt+1
- mvi a,tmins
- sta toval
- endif ;timeout
- ;
- lxi h,bymode ; local con enabled?
- bit 6,m
- jrz bcin1 ; Nope, skip
- lda lchar ; Get local status
- ora a
- jrz bcin1 ; it was not local
- push psw
- xra a ; clear local character
- sta lchar ; hit.
- pop psw
- ret
- bcin1: jmp mdinp
- ;
- bconout:
- lxi h,bymode ; local con enabled?
- bit 7,m ; remote con enabled?
- jrz bcou1 ; nope, skip
- push h
- push b ; in case of trashed char
- call carok ; Check for carrier
- jz clrou ; Fool dropped carrier on us
- call mconout
- pop b
- pop h
- ;
- bcou1: bit 6,m
- rz ; nope, done
- call oconout ; print it
- ret
- ;
- if lstdev
- ;
- ; Wheel check for List Device
- ;
- whlst: sta wlst ; better to be safe than sorry.
- lda z3whl
- ora a ; is wheel set?
- lda wlst
- jz mconout ; nope, hope they like double characters.
- jmp olist ; let's hope there's a printer out there.
- ;
- wlst: ds 1
- endif ; lstdev
- ;
- ; Modem Conout routine
- ;
- mconout:
- call mdoutst
- jrz mconout ; wait till we can do it
- mov a,c
- call mdoutp ; do it
- ret
- ;
- ;---------------- Modem dependent routines start here ----------------------
- ;
- ; This should really be done as two entirely independent overlays -
- ; one for smart (Hayes compatible) modems and one for dumb. Then there
- ; would be no need for the if-else-endif.
- ;
- if not dumb ; smart "Hayes" modem
- modans0 call conin ; wait for a character
- mov b,a
- lda lclst
- ora a ; Was it a local char?
- mov a,b
- rnz ; yes - return with nz flag
- lxi h,bymode ; We're probably going to set a mode soon
- cpi '2' ; Is it a RING?
- jrz mdans1
- cpi '1' ; How 'bout connect 300?
- jrz mdans3
- cpi '5' ; connect 1200?
- jrz mdans4
- cpi '3' ; No Carrier
- jrnz modans0
- if etb
- xra a ; set z flag
- sta carion ; assume carrier on
- endif
- ret
- ;
- mdans1: res 6,m ; turn off local console
- push h
- call prinlo
- db 'ATA',cr+80h ; answer the phone
- pop h
- setb 6,m ; turn on local console
- jr modans0
- mdans3: call set300
- jrnz mdans7
- jr mdans5
- mdans4: call set1200
- jrnz mdans7
- mdans5: call delay
- res 5,m ; Carrier enabled
- if etb
- mvi a,0ffh
- sta carion ; mark 'carrier on'
- ; If hardware carrier detect is available leave this in else remove it
- mvi b,10 ; Check carrier for 1.0 seconds
- mdans6: call carok
- jrz mdans7
- call delay
- djnz mdans6
- endif ; etb
- ret
- mdans7: lxi h,bymode
- call nxtcal
- setb 5,m
- xra a
- ret
- ;
- sync: lxi h,bymode
- setb 7,m
- setb 5,m ; ignore carrier
- setb 6,m ; turn dual io on
- ret
- ;
- ; check for incoming call
- ;
- incmcl: call bconst ; char avail from modem?
- rz ; nope, continue
- incmcl1 call bconin ; Get modem char
- cpi '2' ; RING?
- jrz incmcl2
- xra a ; set z flag
- ret
- incmcl2 lxi h,bymode
- setb 1,m
- call mdans1 ; Answer the phone
- ori 0ffh ; set nz flag
- ret
- ;.............. this is the dumb modem overlay .....................
- else ; dumb modem
- modans0 call const
- jrz mdansC ; got a character?
- call conin
- mov b,a
- lda lclst
- ora a ; Was it a local char?
- mov a,b
- rnz ; yes
- mdansC call mdcarck ; someone here?
- jrz modans0 ; if so, set baud
- mdans8: mvi b,5 ; five tries to get baud right
- lxi h,bymode
- setb 6,m ; enable console IO
- setb 7,m ; enable modem IO
- mdans9: call mdcarck ; did they drop carrier?
- rz
- ;
- push b ; save 'em
- call set300 ; try 300 baud
- call conin
- pop b
- cpi cr ; did we get a CR?
- rz
- ;
- push b
- call set1200 ; try 1200 baud
- call conin
- pop b
- cpi cr ; did we get a CR?
- rz
- ;
- djnz mdans9
- call nxtcal ; somethings confused, hang up on 'em
- xra a ; set z flag
- ret
- ;
- sync: ret ; just return if dumb modem
- ;
- incmcl: ; check for incoming call
- call mdcarck ; someone on the line?
- rz ; nope
- call mdans8 ; set up for dumb remote caller
- ori 0ffh ; set nz flag
- ret
- endif ; dumb
- ;
- ; If you can put the phone on-hook and off-hook via the UART then this
- ; label and appropriate code should be in the UART overlay.
- ;
- ; The following code uses "smart" modem capabilities to compensate for
- ; the fact that my UART is so dumb. ETB
- ;
- mdansw
- lxi h,bymode ; save bymode
- mov a,m
- push psw
- setb 7,m ; modem on
- res 6,m ; console off
- setb 5,m
- mvi b,15
- call ldelay ; wait 1.5 sec before +++
- call prinlo
- db '++','+'+80h ; switch modem to command mode
- mvi b,15
- call ldelay ; wait 1.5 sec after +++
- call prinlo
- db 'ATH',cr+80h ; hang up phone
- call l2char ; get echo (if any)
- call l2char ; get status
- if etb
- lxi h,carion
- mvi m,0 ; set 'carrier off'
- endif
- lxi h,bymode
- pop psw ; restore bymode
- mov m,a
- ret
- ;
- ; .................................................................
- ;
- getc: lxi b,80*mhz ; nr times to try
- ; to get char from modem
- ; the nr of times to try is sensitive to the speed of the const function
- ; if zbye won't get started try raising the 80 to 160 or more. The only
- ; adverse effect should be to slow the program down some.
- getc3 push b
- call const ; check status
- pop b
- ora a
- jrnz getc2 ; char avail?
- dcx b ; no - count tries
- mov a,b
- ora c
- jrnz getc3 ; try again?
- stc ; i'm exhausted, lets quit
- ret
- getc2 call conin ; get the character
- ora a ; clear carry
- ret
- ;
- ; get characters from modem till it times out then test the last 2 chars
- ; to see if they are '0' and car ret.
- ;
- l2char lxi h,0 ; get last 2 chars from modem
- l2c2 push h
- call getc
- pop h
- jrc l2c1 ; no chars left
- mov h,l
- mov l,a
- jr l2c2
- l2c1
- mov a,h
- cpi '0'
- rnz
- mov a,l
- cpi cr
- ret
- ;
- ;------------------- Start of UART dependent routines ------------------
- ;
- ; the following code is specific for ETB's modem port and would have
- ; to be extensively modified for anyone else.
- ;
- dport equ 0e3f8h ; modem data port
- sport equ dport+1 ; modem status port
- ;
- dav equ 4 ; data available bit
- tbmt equ 8 ; transmit bufr empty bit
- err equ 13h ; overrun, framing, and parity error bits
- ;
- ; This routine is supposed to "turn off everyting on the modem, hang it up,
- ; and get it ready to wait for a RING. (DTR off)" but most of this is
- ; either impossible or undesireable on mys system. ETB
- ;
- mdinit ; initialize port
- lda dport ; discard existing data
- ret
- ;
- set300: ; 300 baud not supported
- ori 0ffh
- ret
- ;
- set1200 ; set 1200 baud
- ora a
- ret
- ;
- ; The following uses software 'carrier detect' because ETB's system
- ; does not provide hardware carrier detect.
- ;
- mdcarck
- lda carion ; is carrier on?
- ora a
- ret
- carion db 0ffh ; software 'carrier on' switch
- ;
- mdinst ; modem input status
- lda sport
- cma ; invert bits
- mov b,a ; save status
- ani dav ; data available?
- rz ; no
- mov a,b ; get stat back
- ani err ; check for errors
- jrz mdinst1 ; noerror
- lda dport ; discard data
- xra a ; clear status
- ret
- mdinst1 ori 0ffh ; data avail
- ret
- ;
- mdinp ; modem input
- lda dport ; get data
- cma ; invert bits
- ani 7fh ; delete hi bit
- ret
- ;
- mdoutst ; modem output status
- lda sport ; get status
- cma ; invert bits
- ani tbmt ; buffer empty?
- ret
- ;
- mdoutp ; modem output
- cma ; invert bits
- sta dport ; send data
- ret
- ;
- ;----------------- Start of Terminal dependent routines-------------------
- ;
- ; There are essentially 3 options available for printing status info on
- ; the local console;
- ;
- ; 1) print it on the "25th line" where it will not scroll. This is obtained
- ; by setting "statln equ yes" and then seeing to it that the code below
- ; corresponds to your particular terminal configuration.
- ;
- ; 2) print it just like any other info and let it scroll. This is obtained
- ; by setting "statln equ no". This option makes absolutely no unusual
- ; demands on the terminal and should run on any system.
- ;
- ; 3) don't print it at all. This is obtained by converting the subroutine
- ; prtsta into a dummy (ret instruction). If desired you may then discard
- ; most if not all of this overlay.
- ;
- ; These macros indicate the characters sequences to cause the specified
- ; action on a specific terminal. You will probably have to change the
- ; data below if you wish to use "line 25".
- ;
- if statln
- curpos macro x,y,last ; Position Cursor to X,Y (0 offset)
- db 1bh,'=',' '+y,' '+x+(80h and last)
- endm
- ;
- enab25 macro last ; Enable 25th line
- db 1bh,'C','7'+(80h and last)
- endm
- ;
- disab25 macro last ; Disable 25th line
- db 1bh,'B','7'+(80h and last)
- endm
- ;
- pucu macro last ; Push cursor
- db 1bh,'B','6'+(80h and last)
- endm
- ;
- pocu macro last ; Pop cursor
- db 1bh,'C','6'+(80h and last)
- endm
- ;
- cls macro last ; Clear Screen
- db 1ah+(80h and last)
- endm
- ;
- curof macro last ; Cursor off
- db 1bh,'C','4'+(80h and last)
- endm
- ;
- curon macro last ; Cursor on
- db 1bh,'B','4'+(80h and last)
- endm
- endif ; statln
- ;
- ; . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
- ;
- ;
- ; Print status information on the local terminal. The calling sequence
- ; is call prtsta
- ; db m,string,n
- ; where m is the column number on the screen where string is to be printed
- ; followed by n blanks.
- ;
- prtsta:
- ; ret ; to turn off all status reports
- ; activate this ret instruction
- xthl
- mov a,m ; get ptr to column
- inx h
- xthl
- if statln ; fancy terminal
- adi ' '+80h
- sta prtstax
- call prinlc
- enab25 no ; enable line 25
- pucu no ; push cursor
- curpos 0,24,yes ; move cursor
- prtstax equ $-1
- else ; plain terminal
- mov b,a
- ora a ; column 0?
- cnz tab ; print blanks til col is reached
- endif ; statln
- ;
- xthl ; point to string
- prtstas mov a,m ; get next char in string
- inx h ; increment ptr
- cpi 32 ; end of string?
- jrc prtsta2
- mov c,a
- push h
- call oconout ; print char on console
- pop h
- jr prtstas
- prtsta2 xthl ; return adr
- mov b,a ; nr blanks to print
- ora a
- cnz tab ; print them
- ;
- if statln
- call no25
- else
- call prinlc
- dc cr,lf
- endif ;statln
- ret
- ;
- go25:
- if statln
- call prinlc
- enab25 no ; enable 25th line
- pucu yes ; push cursor
- endif ; statln
- ret
- ;
- no25:
- if statln
- call prinlc
- pocu no ; pop cursor
- disab25 yes ; disable 25th line
- endif ; statln
- ret
- ;
- cursoff:
- if statln
- call prinlc
- curoff yes ; cursor off
- endif ; statln
- ret
- ;
- curson:
- if statln
- call prinlc
- curon yes ; cursor on
- endif ; statln
- ret
- ;
- clrscr:
- if statln
- call prinlc ; clear screen
- cls yes
- endif ; statln
- ret
- ;
- ; Print (on local console) number of spaces contained in B register.
- ;
- tab:
- push b
- mvi c,' '
- call oconout
- pop b
- djnz tab
- ret
- ;
- ;-------------------- End of terminal dependent routines ---------------------
- ;
- ; .z80
- ;
- ; if2 ; this is turned off because I use a one pass assembler ETB
- if $ ge (rcp+rcps*128)
- .printx ->This RCP is too large, don't try to run it.<-
- endif
- ; endif
- ;
- .dephase
- byend:
- end
- cp+rcps*128)
- . cls yes
- endif ; statln
- ret
- ;
- ; Print (on local console) number of spaces contained in B register.
- ;
- tab:
- push b
- mvi c,' '
- call oconout
- pop b
- djnz tab
- ret
- ;
- ;-------------------- End of terminal dependent routines ---------