home *** CD-ROM | disk | FTP | other *** search
- Title 'MEX overlay for the PMMI version 2.2'
- ;
- ; Ignore the Title error message if using ASM.
- ;
- REV equ 22 ; overlay revision number
- LVL equ 'c' ; overlay level ( as in Revision 2.2a )
- ;
- ; MEX PMMI OVERLAY VERSION 1.0: written 04/27/84 by Ron Fowler
- ;
- ; " " " " 2.0: generally rewritten 9/18/84 by Fred M. Spinner
- ; " " " ' 2.1: rewritten 09/27/84 by Bill Norris
- ; " " " " 2.2: " 10/30/84 by Bill Norris
- ;
- ;
- ; Version 2.2 notes: Added 'SET EXTRA' command. This is a toggle
- ; that allows you to see on the console when
- ; certain overlay functions are invoked.
- ; Corrected a minor bug in the clear screen and
- ; clear to end of screen functions.
- ; Added 15 to SET PPS command.
- ; Added SET ONLINE ( SET OFFHOOK synonym )
- ; OFF-HOOK and ON-HOOK have been changed from
- ; scattered in-line calls to subroutines.
- ; Renamed SET FIDGET to SET ICD (intercall delay)
- ; Renamed SET IDG to SET IDD (interdigit delay)
- ; The default PMMI base port was changed to 80h
- ; in version 2.1 due to conflicts with several
- ; disk controller boards. If your PMMI is not
- ; addressed at this port, just use the SET BASE
- ; command (and CLONE) if you don't want to edit
- ; and re-assemble this file.
- ; Speeded up keyboard abort (^X and ^C). ^S also
- ; accepted here (during dialing of a number).
- ; Phone number '#' is replaced at dial time from
- ; the keyboard.
- ;
- ;
- ; Version 2.1 notes: Unifies scattered PMMI I/O; allows modification
- ; of the PMMI base port with SET BASE command.
- ; No PMMI I/O is done in-line. It is all done
- ; using subroutine calls. This should make all
- ; modifications simpler (including future
- ; changes to support MEX 2.x).
- ; Base port address is printed in signon message.
- ; SET FIDGET added (delay between calls).
- ; BASE/FIDGET changes are preserved through CLONEs.
- ; Uses BDOS 6 to force BUSY instead of using hard
- ; coded keyboard I/O for the CTRLX function. (See
- ; description in Version 2.0 notes below).
- ;
- ;
- ; Version 2.0 9/18/84: Numerous bugs repaired. The offhook command
- ; now actually takes the modem off hook. The DTR bytes were swapped
- ; in 1.1 so that baud rates over 300 would barf. This has been repaired
- ; The SET MODE command is no longer available. Use SET ORIG, ORG, or
- ; ORIGINATE and SET ANS or ANSWER to switch modes. The actual routine
- ; to switch modes has been re-written from scratch, also. Overlay version
- ; message more verbose (better looking, also) now. If your know your
- ; keyboard (terminal)'s Status and Data Port and also know the value
- ; (bit) to check for for keyboard input, you can also implement the CTRLX
- ; feature which is handy to have if you know a number is busy and you
- ; want to call the next, etc. without further delays. The keyboard info
- ; goes under KSTAT, KPORT, KBIT, and KVAL which mean Keyboard/Terminal status
- ; port, Keyboard data port, AND bit to status input, and value to check for
- ; after status is ANDed, respectively. Set CTRLX to YES if you have
- ; this information and want to use this feature, or set it to NO to use
- ; the standard MEX keyboard trap.
- ;
- ; Fred M. Spinner
- ;
- ;
- ; (V1.1) 05/17/84 (Jim Byram) : Small bugs repaired. Answer-mode
- ; bit (ANBIT) and originate-mode bit (ORBIT) were reversed; fixed
- ; SET MODE help message.
- ;
- ; This is a MEX overlay file for the PMMI modem. You can use it as
- ; a model for designing your own modem overlay (or you can use any
- ; existing MDM7 overlay, if available).
- ;
- ; If you use this as a template for writing your own overlay, and
- ; distribute it to others, please pare down these comments as much
- ; as possible (to keep the overlays small). I'll maintain this file
- ; with as many notes and references as possible, but this will hope-
- ; fully be the only "big" overlay.
- ;
- ; There are advantages to recoding your overlay to conform to the
- ; techniques presented here: MEX 2.0 will likely have a much simpler
- ; overlay structure; if you stick to the label names and coding
- ; suggestions used here, you'll easily be able to follow the overlay
- ; upgrade instructions when MEX 2.0 hits the streets. Also, you can
- ; make use of the MEX service processor to write a very versatile
- ; SET command (as done here).
- ;
- ; Note that all overlays may freely use memory up to 0CFFH. If your
- ; overlay must work with the MEX Smartmodem overlay (MXO-SMxx.ASM),
- ; the physical modem overlay should terminate by 0AFFH.
- ;
- ; For purposes of example, this is a "full-featured" MEX overlay. In
- ; practice, your overlay may be much simpler (all that is really re-
- ; quired is the modem I/O code; fancy stuff like the SET command, and
- ; even the disconnect routine, may be left open. You will need DIAL
- ; code, though, unless your modem doesn't support autodialing).
- ;
- ;------------------------------------------------------------
- ;
- ; Misc equates
- ;
- NO equ 0
- YES equ 0FFh
- TPA equ 100h
- CR equ 13
- LF equ 10
- BS equ 8
- TAB equ 9
- ESC equ 27
- CTRLX equ YES ;YES, if use ^X for fake "BUSY"
- CONTX equ 'X'-40h
-
-
- ;
- ; Equates used only by PMMI routines grouped together here.
- ;
- ;
- ; PMMI port definitions
- ;
- PORT equ 080h ;PMMI base port (data or status)
- ; PORT now also used by NITMOD.
-
- MODCT1 equ 0 ;modem control port (added to base port).
- MODDAT equ MODCT1+1 ;modem data port "
- BAUDRP equ MODCT1+2 ;modem baud rate port "
- MODCT2 equ MODCT1+3 ;modem status port "
- ;
- ; PMMI bit definitions
- ;
- MDRCVB equ 02h ;modem receive bit (DAV)
- MDRCVR equ 02h ;modem receive ready
- MDSNDB equ 01h ;modem send bit
- MDSNDR equ 01h ;modem send ready bit
- ;
- ;
- CTSMSK equ 4 ;mask for CTS bit
- BRKMSK equ 0FBh ;mask to set break
- PARMSK equ 0CFh ;mask to remove parity bits
- OPARIT equ 00h ;odd-parity bits
- EPARIT equ 20h ;even-parity bits
- NPARIT equ 10h ;no-parity bits
- MODEMK equ 0FCh ;mode mask
- ANMODE equ 1Eh ;answer mode
- ANBIT equ 2 ;answer-mode bit
- ORIGMD equ 1Dh ;originate mode
- ORBIT equ 1 ;originate-mode bit
- WTCTS equ 150 ;number of seconds (x5) to wait for the
- ;computer to answer after PMMI auto-dial
- ;100=20 sec, 150=30 sec, 255=51 sec.
- ;any number 0-255 acceptable
- ;
- ;
- ; Modem control command words
- ;
- BRKMASK equ 0 ;tele line on hook (break while dialing)
- CLEAR equ 3Fh ;idle mode
- DTMSK equ 1 ;dial tone mask
- MAKEM equ 1 ;tele line make (off hook)
- RBLMT equ 35 ;7 seconds to wait til no-ring-heard msg
- RBWAIT equ 50 ;5 second delay before redialing PMMI
- SMRWT equ 15 ;1.5 sec delay before redialing HAYES
- TMPUL equ 80h ;timer pulses mask bit
- TRATE equ 250 ;value for 0.1 second
- ;
- ;
- ; MEX service processor stuff ... MEX supports an overlay service
- ; processor, located at 0D00H (and maintained at this address from
- ; version to version). If your overlay needs to call BDOS for any
- ; reason, it should call MEX instead; function calls below about
- ; 240 are simply passed on to the BDOS (console and list I/O calls
- ; are specially handled to allow modem port queueing, which is why
- ; you should call MEX instead of BDOS). MEX uses function calls
- ; above about 244 for special overlay services (described below).
- ;
- ; Some sophisticated overlays may need to do file I/O; if so, use
- ; the PARSFN MEX call with a pointer to the FCB in DE to parse out
- ; the name. This FCB should support a spare byte immediately pre-
- ; ceeding the actual FCB (to contain user # information). If you've
- ; used MEX-10 for input instead of BDOS-10 (or you're parsing part
- ; of a SET command line that's already been input), then MEX will
- ; take care of DU specs, and set up the FCB accordingly. There-
- ; after all file I/O calls done through the MEX service processor
- ; will handle drive and user with no further effort necessary on
- ; the part of the programmer.
- ;
- MEX equ 0D00h ;address of the service processor
- INMDM equ 255 ;get char from port to A, CY=no more in 100 ms
- TIMER equ 254 ;delay 100ms * reg B
- TMDINP equ 253 ;B=# secs to wait for char, cy=no char
- CHEKCC equ 252 ;check for ^C from KBD, Z=present
- SNDRDY equ 251 ;test for modem-send ready
- RCVRDY equ 250 ;test for modem-receive ready
- SNDCHR equ 249 ;send a character to the modem (after sndrdy)
- RCVCHR equ 248 ;recv a char from modem (after rcvrdy)
- LOOKUP equ 247 ;table search: see CMDTBL comments for info
- PARSFN equ 246 ;parse filename from input stream
- BDPARS equ 245 ;parse baud-rate from input stream
- SBLANK equ 244 ;scan input stream to next non-blank
- EVALA equ 243 ;evaluate numeric from input stream
- LKAHED equ 242 ;get nxt char w/o removing from input
- GNC equ 241 ;get char from input, cy=1 if none
- ILP equ 240 ;inline print
- DECOUT equ 239 ;decimal output
- PRBAUD equ 238 ;print baud rate
- ;
- ;
- CONOUT equ 2 ;simulated BDOS function 2: console char out
- PRINT equ 9 ;simulated BDOS function 9: print string
- INBUF equ 10 ;input buffer, same structure as BDOS 10
- ;
- org TPA ;we begin
- ;
- ;
- ds 3 ;MEX has a JMP START here
- ;
- ; The following variables are located at the beginning of the program
- ; to facilitate modification without the need of re-assembly. They will
- ; be moved in MEX 2.0.
- ;
- PMODEM: db YES ;yes=PMMI modem \ / These 2 locations are not
- SMODEM: db NO ;yes=Smartmodem / \ referenced by MEX
- TPULSE: db 'T' ;T=touch, P=pulse (not referenced by MEX)
- CLOCK: db 55 ;clock speed x .1, up to 25.5 mhz.
- MSPEED: db 1 ;sets display time for sending a file
- ;0=110 1=300 2=450 3=600 4=710
- ;5=1200 6=2400 7=4800 8=9600 9=19200
- BYTDLY: db 5 ;default time to send character in
- ;terminal mode file transfer (0-9)
- ;0=0 delay, 1=10 ms, 5=50 ms, 9=90 ms
- CRDLY: db 5 ;end-of-line delay after CRLF in terminal
- ;mode file transfer for slow BBS systems
- ;0=0 delay, 1=100 ms, 5=500 ms, 9=900 ms
- COLUMS: db 5 ;number of directory columns
- SETFL: db YES ;yes=user-defined SET command
- SCRTST: db NO ;yes=if home cursor and clear screen
- ;routine at CLRSCRN
- db 0 ;was once ACKNAK, now spare
- BAKFLG: db NO ;yes=make .BAK file
- CRCDFL: db YES ;yes=default to CRC checking
- ;no=default to Checksum checking
- TOGCRC: db YES ;yes=allow toggling of Checksum to CRC
- CVTBS: db NO ;yes=convert backspace to rub
- TOGLBK: db YES ;yes=allow toggling of bksp to rub
- ADDLF: db NO ;no=no LF after CR to send file in
- ;terminal mode (added by remote echo)
- TOGLF: db YES ;yes=allow toggling of LF after CR
- TRNLOG: db YES ;yes=allow transmission of logon
- ;write logon sequence at location LOGON
- SAVCCP: db YES ;yes=do not overwrite CCP
- LOCNXT: db NO ;yes=local cmd if EXTCHR precedes
- ;no=not local cmd if EXTCHR precedes
- TOGLOC: db YES ;yes=allow toggling of LOCNXTCHR
- LSTTST: db YES ;yes=allow toggling of printer on/off
- ;in terminal mode. Set to no if using
- ;the printer port for the modem
- XOFTST: db NO ;yes=allow testing of XOFF from remote
- ;while sending a file in terminal mode
- XONWT: db NO ;yes=wait for XON after sending CR while
- ;transmitting a file in terminal mode
- TOGXOF: db YES ;yes=allow toggling of XOFF testing
- IGNCTL: db NO ;yes=do not send control characters
- ;above CTL-M to CRT in terminal mode
- ;no=send any incoming CTL-char to CRT
- EXTRA1: db 0 ;for future expansion
- EXTRA2: db 0 ;for future expansion
- BRKCHR: db '@'-40h ;^@ = Send a 300 ms. break tone
- NOCONN: db 'N'-40h ;^N = Disconnect from phone line
- LOGCHR: db 'L'-40h ;^L = Send logon
- LSTCHR: db 'P'-40h ;^P = Toggle printer
- UNSVCH: db 'R'-40h ;^R = Close input text buffer
- TRNCHR: db 'T'-40h ;^T = Transmit file to remote
- SAVCHR: db 'Y'-40h ;^Y = Open input text buffer
- EXTCHR: db '^'-40h ;^^ = Send next character
- PRATE: db 167 ;125=20pps dialing, 250=10pps
- db 0 ;not used
- ;
- ; Low-level modem I/O routines: this will be replaced with
- ; a jump table in MEX 2.0 (you can insert jumps here to longer
- ; routines if you'd like ... I'd recommend NOT putting part of
- ; a routine in this area, then jumping to the rest of the routine
- ; in the non-fixed area; that will complicate the 2.0 conversion)
-
- INCTL1: jmp iCTL1 ;in modem control port
- db 0,0,0,0,0,0,0
-
- OTDATA: jmp oDATA
- db 0,0,0,0,0,0,0
-
- INPORT: jmp iDATA
- db 0,0,0,0,0,0,0
-
-
- ; Bit-test routines. These will be merged with the above
- ; routines in MEX 2.0 to provide a more reasonable format
- ;
- MASKR: ani MDRCVB ;bit to test for receive ready
- ret
- TESTR: cpi MDRCVR ;value of receive bit when ready
- ret
- MASKS: ani MDSNDB ;bit to test for send ready
- ret
- TESTS: cpi MDSNDR ;value of send bit when ready
- ret
-
- ;
- ; Unused area: was once used for special PMMI functions,
- ; Now used only to retain compatibility with MDM overlays.
- ; You may use this area for any miscellaneous storage you'd
- ; like but the length of the area *must* be 12 bytes.
- ;
- ds 12
- ;
- ; Special modem function jump table: if your overlay cannot handle
- ; some of these, change the jump to "DS 3", so the code present in
- ; MEX will be retained. Thus, if your modem can't dial, change the
- ; JMP PDIAL at DIALV to DS 3, and MEX will print a "not-implemented"
- ; diagnostic for any commands that require dialing.
- ;
- ; DIALV dials the digit in A. See the comments at PDIAL for specs.
- ;
- ; DISCV disconnects the modem
- ;
- ; GOODBV is called just before MEX exits to CP/M. If your overlay
- ; requires some exit cleanup, do it here.
- ;
- ; INMODV is called when MEX starts up; use INMODV to initialize the modem.
- ;
- ; NEWBDV is used for phone-number baud rates and is called with a baud-rate
- ; code in the A register, value as follows:
- ;
- ; A=0: 110 baud A=1: 300 baud A=2: 450 baud
- ; A=3: 600 baud A=4: 710 baud A=5: 1200 baud
- ; A=6: 2400 baud A=7: 4800 baud A=8: 19200 baud
- ;
- ; If your overlay supports the passed baud rate, it should store the
- ; value passed in A at MSPEED (107H), and set the requested rate. If
- ; the value passed is not supported, you should simply return (with-
- ; out modifying MSPEED) -or- optionally request a baud-rate from the
- ; user interactively.
- ;
- ; NOPARV is called at the end of each file transfer; your overlay may simply
- ; return here, or you may want to restore parity if you set no-parity
- ; in the following vector (this is the case with the PMMI overlay).
- ;
- ; PARITV is called at the start of each file transfer; your overlay may simply
- ; return here, or you may want to enable parity detection (this is the
- ; case with the PMMI overlay).
- ;
- ; SETUPV is the user-defined command ... to use this routine to build your own
- ; MEX command, set the variable SETFL (117H) non-zero, and add your SET
- ; code. You can use the routine presented in the PMMI overlay as a
- ; guide for parsing, table lookup, etc.
- ;
- ; SPMENU is provided only for MDM compatibility, and is not used by MEX 1.0 for
- ; any purpose (it will be gone in MEX 2).
- ;
- ; VERSNV is called immediately after MEX prints its sign-on message at cold
- ; startup -- use this to identify your overlay in the sign-on message
- ; (include overlay version number in the line).
- ; BREAKV is provided for sending a BREAK (<ESC>-B in terminal mode). If your
- ; modem doesn't support BREAK, or you don't care to code a BREAK rou-
- ; tine, you may simply execute a RET instruction.
- ;
- LOGON: ds 2 ;needed for MDM compat, not ref'd by MEX
- DIALV: jmp PDIAL ;dial digit in A (see info at PDIAL)
- DISCV: jmp PDISC ;disconnect the modem
- GOODBV: jmp DUMMY ;called before exit to CP/M
- INMODV: jmp NITMOD ;initialization. Called at cold-start
- NEWBDV: jmp PBAUD ;set baud rate
- NOPARV: jmp NOPAR ;set modem for no-parity
- PARITV: jmp PARITY ;set modem parity
- SETUPV: jmp SETCMD ;SET cmd: jump to a RET if you don't write SET
- SPMENV: ds 3 ;not used with MEX
- VERSNV: jmp SYSVER ;Overlay's voice in the sign-on message
- BREAKV: jmp PBREAK ;send a break
- ;
- ; The following jump vector provides the overlay with access to special
- ; routines in the main program (retained and supported in the main pro-
- ; gram for MDM overlay compatibility). These should not be modified by
- ; the overlay.
- ;
- ; Note that for MEX 2.0 compatibility, you should not try to use these
- ; routines, since this table will go away with MEX 2.0 (use the MEX
- ; service call processor instead).
- ;
- ILPRTV: ds 3 ;replace with MEX function 9
- INBUFV: ds 3 ;replace with MEX function 10
- ILCMPV: ds 3 ;replace with table lookup funct. 247
- INMDMV: ds 3 ;replace with MEX function 255
- NXSCRV: ds 3 ;not supported by MEX (returns w/no action)
- TIMERV: ds 3 ;replace with MEX function 254
- ;
- ;
- ; Clear/screen and clear/end-of-screen. Each routine must use the
- ; full 9 bytes alloted (may be padded with nulls).
- ;
- ; These routines (and other screen routines that MEX 2.0 will sup-
- ; port) will be accessed through a jump table in 2.0, and will be
- ; located in an area that won't tie the screen functions to the
- ; modem overlay (as the MDM format does).
- ;
-
- CLREOS: lxi h,SCRTST
- lxi d,EOSMSG
- jmp PRMAYBE
-
-
- CLS: lxi h,SCRTST
- lxi d,CLSMSG
- jmp PRMAYBE
-
- ;
- ;------------------------------------------------------------
- ;
- ; *** END OF FIXED FORMAT AREA ***
- ;
- ;------------------------------------------------------------
- ;
-
- ; Data area
- ERRFLG: db 0 ;connection error code
- UCTLB: db ORIGMD ;uart-control byte image
- BAUDSV: db 52 ;current baud rate (dflt 300)
- MODCTB: db 07FH ;modem control byte
- INTERD: db 2 ;inter-digit delay in 100's of ms
- PRXTRA: db YES ; Diagnostic prints upon function usage
- WTNUM: db WTCTS ;
- OFFHK: db 0 ;
- ;
- BPTAB: db '0123456789ABCDEF', 80h
- NITBYT: db PORT ; Should be the PMMI base port. Original port
- ; is C0 hex. Recommended alternate is 80 hex.
- DIALFLG: db 0 ;
- ABOBYT: db 0 ;
- TEMP: dw 0 ;
-
-
- PRMAYBE: mov a,m
- ora a
- rz
- PRMBOK: mvi c,PRINT
- jmp MEX
-
- iCTL1: mvi a,MODCT1
- jmp BPIN
- iCTL2: mvi a,MODCT2
- jmp BPIN
- iDATA: mvi a,MODDAT ;in modem data port
- jmp BPIN
- iBDRP: mvi a,BAUDRP
- jmp BPIN
-
- oCTL1: push psw
- mvi a,MODCT1
- jmp BPOUT
- oCTL2: push psw
- mvi a,MODCT2
- jmp BPOUT
- oDATA: push psw ;out modem data port
- mvi a,MODDAT
- jmp BPOUT
- oBDRP: push psw
- mvi a,BAUDRP
- jmp BPOUT
-
- BPIN: push b
- mov b,a
- lda NITBYT
- add b
- sta BPINX+1
- BPINX: in $-$
- pop b
- ret
-
- BPOUT: push b
- mov b,a
- lda NITBYT
- add b
- sta BPOUTX+1
- pop b
- pop psw
- BPOUTX: out $-$
- ret
-
-
- ; Modem initialization. This overlay doesn't do any initialization.
- ; (if we did, we'd disconnect a call already in progress).
-
- NITMOD: lda NITBYT ; Convert hex byte to ascii nibble.
- rar
- rar
- rar
- rar
- ani 0Fh
- mvi d,0
- mov e,a
- lxi h,BPTAB
- dad d
- mov a,m
- sta BPMSG ; Store base port in sign-on message.
- mvi a,LVL
- sta LEVEL
- ret
-
-
- ; PMMI send-break routine
- PBREAK: lda MODCTB ;get the last modem control byte
- ani BRKMSK ;set the transmit break bit low
- call oCTL2 ;send it to the modem
- mvi b,2
- call TIMERV ;send a space tone for 200 ms.
- lda MODCTB ;get the last modem control byte
- call oCTL2 ;restore to normal
- lxi h,PRXTRA
- lxi d,BRKMSG
- jmp PRMAYBE
-
- BRKMSG: db '.break. $'
-
-
- ; Setup PMMI for odd/even parity.
- PARITY: lda UCTLB ;send what's in the image byte
- jmp oCTL1
-
-
- ; set no-parity
- NOPAR: lda UCTLB ;get uart/modem control byte
- ani PARMSK ;reset parity bits
- ori NPARIT ;add no-parity bits
- jmp oCTL1
-
-
- ; disconnect the modem
- PDISC: call HUKONN ; Hang up
- call oCTL2 ; clear DAV, ESD, etc
- push b ;
- lxi h,PRXTRA ;
- lxi d,DSC1MSG ;
- call PRMAYBE ;
- mvi b,20 ;wait for PMMI to disconnect (2 sec) %%* 1 to 2
- mvi c,TIMER ;0.1 second per timer interval
- call MEX ;
- lxi h,PRXTRA ;
- lxi d,DSC2MSG ;
- call PRMAYBE ;
- pop b ;
- ret ;
-
- DSC1MSG: db '.di$'
- DSC2MSG: db 'sc. $'
-
- ; exit routine
- DUMMY: ret ;we don't need one
- ;
- ;
- ;------------------------------------------------------------
- ;
- ; <PMMI DIALING ROUTINES BEGIN>
- ;
- ; This is the DIAL routine called by MEX to dial a digit. The digit
- ; to be dialed is passed in the A register. Note that two special
- ; codes must be intercepted as non-digits: 254 (start dial sequence)
- ; and 255 (end-dial sequence). Mex will always call DIAL with 254
- ; in the accumulator prior to dialing a number. Mex will also call
- ; dial with 255 in A as an indication that dialing is complete. Thus,
- ; the overlay may use these values to "block" the number, holding it
- ; in a buffer until it is completely assembled (we don't do this with
- ; the PMMI, however; we just dial the digits as they come in).
- ;
- ; After the 254-start-dial sequence, MEX will call the overlay with
- ; digits, one-at-a-time. MEX will make no assumptions about the dig-
- ; its, and will send each to the DIAL routine un-inspected (some modems,
- ; like the Smartmodem, allow special non-numeric characters in the
- ; phone number, and MEX may make no assumptions about these). This
- ; dialing routine validates digits, and ignores any except 0-9 and
- ; comma (uses comma to simulate Smartmodem delay).
- ;
- ; After receiving the end-dial sequence (255) the overlay must take
- ; whatever end-of-dial actions are necessary *including* waiting for
- ; carrier at the distant end. The overlay should monitor the keyboard
- ; during this wait (using the MEX keystat service call), and return
- ; an exit code to MEX in the A register, as follows:
- ;
- ; 0 - Carrier detected, connection established
- ; 1 - Far end busy (only for modems that can detect this condition)
- ; 2 - No answer (or timed out waiting for modem response)
- ; 3 - Keyboard abort (^C only: all others should be ignored)
- ; 4 - Error reported by modem
- ;
- ; <No other codes should be returned after an end-dial sequence>
- ;
- ; The overlay should not loop forever in the carrier-wait routine, but
- ; instead use either the overlay timer vector, or the INMDMV (timed 100
- ; ms character wait) service call routine.
- ;
- ; The DIAL routine is free to use any of the registers, but must return
- ; the above code after an end-dial sequence
- ;
- ;
- PDIAL: cpi 254 ;start-dial?
- jz STDIAL ;
- cpi 255 ;end-dial
- jz ENDIAL ;
- ;
- push psw ;
- mvi a,7 ;
- sta DIALFLG ;
- pop psw ;
- ;
- PDIAL1: cpi ',' ;smartmodem pause command
- jnz PDIAL2 ;if not pause, continue
- mvi b,10 ;delay 1 second
- jmp TIMOUT ;
-
-
- PDIAL2: cpi '#' ;
- jnz CKDIG ;
- mvi a,BS ;
- call PUT1C ;
- PDIAL3: call GET1C ;
- jz PDIAL3 ;
- call PUT1C ;
- jmp PDIAL1 ;
-
-
- CKDIG: cpi '9'+1 ; digits are 0-9
- rnc ; too big...
- sui '0' ;
- rc ; too small....
- jnz DIALIT ; just right...
- mvi a,10 ; convert zero to 10 pulses
-
- ; Send a digit to the modem.
- DIALIT: mov c,a ; save the digit
- lda ERRFLG ; before we try to dial...
- ora a ; ...check dialtone error flag
- rnz ; ...if no DT, exit now
- lda PRATE ; value for dial speed
- call oBDRP ;
- call WAITLO ; wait for timer lo
- call WAITHI ; wait for timer hi
-
- call GET1C ;
- DIAL1: cpi 3 ; ^C ?
- jz DIALX ;
- cpi 24 ; ^X ?
- jz DIALX ;
- cpi 19 ; ^S ?
- jnz DIGLP ;
-
- DIALP: call GET1C ; Wait for a character
- jz DIALP ;
- cpi 19 ;
- jmp DIGLP ;
- ;
- DIALX: sta ABOBYT ;
-
- DIGLP: lda ABOBYT ;
- ora a ;
- jnz DIGLP2 ;
- ;
- call HUKOFF ; Go off-hook
- call WAITLO ;
- call HUKONN ;
- call WAITHI ;
- DIGLP2: dcr c ;
- jnz DIGLP ; send rest of digit
- lda ABOBYT ;
- ora a ;
- rnz ;
- ;
- call HUKOFF ;
- lda INTERD ; get inter-digit delay
- mov b,a ;
- jmp TIMOUT ;
-
-
- ; Wait for negative edge of timer pulse
- WAITLO: call iBDRP
- ani TMPUL
- jnz WAITLO
- ret
-
-
- ; Wait for positive edge of timer pulse
- WAITHI: call iBDRP
- ani TMPUL
- jz WAITHI
- ret
-
-
- ; Start-dial sequence: disconnect, wait for dial-tone
- STDIAL: xra a ; reset error flag
- sta ERRFLG ;
- call PDISC ; on-hook
- call HUKOFF ;
- call PROFFH ; (possibly) print .off hook. message
-
- ; Wait routine will return with carry set if unable to get dialtone.
- mvi d,DTMSK ;dial tone mask
- mvi e,50 ;waits up to 10 sec. for dial tone
- call WAIT ;wait for dial tone
- rnc ;if dial tone within 10 seconds
-
- sta ERRFLG ;(action on error deferred until
- call PDISC ;no tone, hang up
- ret ; dialing is completed)
-
-
- ; End-dial sequence
- ENDIAL: call ENDIT ;close out dialing
- push psw ;
- xra a ;
- sta DIALFLG ;
- sta ABOBYT ;
- pop psw ;
- ora a ;successfully connected?
- rz ;exit now if so
- push psw ;nope, save the error code
- call PDISC ;shut down the modem
- pop psw ;
- ret ;
-
-
- ENDIT: lda ERRFLG ;no-dialtone error from STDIAL?
- ora a
- rnz ;if so, return the error here
- call OFF ;go off-hook
- lda UCTLB ;get uart/modem control byte
- call oCTL1 ;send it
- mvi d,4 ;clear-to-send mask
- ;
- lda WTNUM ;
- mov e,a ;
- call WAIT ;
- rnc ;return A=0 if good
- ;
- cpi 'C'-40h ;keyboard abort?
- rz ;if so return it
- ;
- if CTRLX ;
- cpi 1 ;Fake busy?
- rz ;Return if so
- endif ;CTRLX
- ;
- mvi a,2 ;nope, convert error to "no answer"
- ret ;
-
- ; <end of PMMI dialing routines>
- ;------------------------------------------------------------
-
-
- ; Go Off-Hook
- OFF: lda BAUDSV ;set current baud rate
- call oBDRP ;
- lda MODCTB ;Load current DTR
- call oCTL2 ;
- call HUKOFF ;
- lda UCTLB ;
- call oCTL1 ;
- mvi b,2 ;wait 200 ms %%* changed from 1 to 2.
- call TIMOUT ;
- lda DIALFLG ;
- ora a ;
- jz PRONLN ;
- xra a ;
- sta DIALFLG ;
- PRWAIT: lxi h,PRXTRA ;
- lxi d,WAITMSG ;
- jmp PRMAYBE ;
-
- PROFFH: lxi h,PRXTRA ;
- lxi d,OFFHMSG ;
- jmp PRMAYBE ;
-
- PRONLN: lxi h,PRXTRA ;
- lxi d,ONLNMSG ;
- jmp PRMAYBE ;
-
- OFFHMSG: db '.off-h. $' ; Force PMMI to on-line status.
- ONLNMSG: db '.on-line. $' ; Force PMMI to on-line status.
- WAITMSG: db '.wait. $' ; Force PMMI to " " and wait
- ; for either a carrier or timeout.
-
-
- HUKOFF: mvi a,255 ; Go Off-Hook
- sta OFFHK ;
- mvi a,MAKEM ;
- jmp oCTL1 ;
-
-
- HUKONN: xra a ; Go On-Hook
- sta OFFHK ;
- mvi a,BRKMASK ;
- jmp oCTL1 ;
-
-
-
-
- ; Time-out routine. Must be called with mask in D reg. for input at
- ; relative port 2 and number of seconds (times 10) in E reg.
- WAIT: mvi b,2 ; 200 ms
- call TIMOUT ; wait for timer to go high then low
- call iBDRP ; pmmiaddr+2 (modem status port)
- ana d ; (cts or dialtone mask)
- rz ; active low, so return on 0
-
- if not CTRLX ;
- mvi c,CHEKCC ;not yet, check for console-abort
- call MEX ;abort?
- mvi a,3 ;set error code 3 if abort active
- stc ;
- rz ;return if aborted
- endif ;not CTRLX
-
- if CTRLX ;
- lda ABOBYT ;
- ora a ;
- jz WAIT0 ;
- push psw ;
- xra a ;
- sta ABOBYT ;
- pop psw ;
- jmp WAIT1 ;
-
- WAIT0: call GET1C ;
- jz WAITOR ;
- ;
- WAIT1: cpi CONTX ;'^X?'
- jnz WAIT2 ;no, check for ^C
- call GET1C ;Clear out garbage
- mvi a,1 ;yes, return fake error code
- stc ;
- ret ;
- WAIT2: cpi 3 ;Duplicate MEX ^C trap
- jnz WAITOR ;Not ^C, continue
- call GET1C ;Clear out garbage
- mvi a,3 ;"ABORT" error
- stc ;Yes, pass error
- ret ;code and return
- endif ;CTRLX
-
-
- WAITOR: dcr e ;
- jnz WAIT ; nope, downcount
- inr a ; set error=4 (modem error); cy already set
- ret ;
-
-
- GET1C: push h
- push d
- push b
- mvi c,6
- mvi e,0FFh
- call 5
- pop b
- pop d
- pop h
- ani 7Fh
- ret
-
-
- PUT1C: push h
- push d
- push b
- mvi c,6
- mov e,a
- call 5
- pop b
- pop d
- pop h
- ret
-
-
- ; Set baud-rate code in A (if supported by your modem overlay). PMMI
- ; supports only five rates, which are validated here. NOTE: this routine
- ; (ie, the one vectored through NEWBDV) should update MSPEED with the
- ; passed code, but ONLY if that rate is supported by the hardware.
- PBAUD: push h ;don't alter anybody
- push d
- push b
- mov e,a ;code to DE
- mvi d,0
- lxi h,BAUDTB ;offset into table
- dad d
- mov a,m ;fetch code
- ora a ;0? (means unsupported code)
- stc ;return error for STBAUD caller
- jz PBEXIT ;exit if so
- call oBDRP ;good rate, set it
- sta BAUDSV ;save it
- mov a,e ;get speed code back
- sta MSPEED ;make it current
- call GETDTR ;get correct DTR based on baud rate
- sta MODCTB ;save the code
- call CARRCK ;is a connection in progress?
- jnz PBEXIT ;skip this if not
- lda MODCTB ;yep, set up DTR
- call oCTL2
-
- PBEXIT: lxi h,PRXTRA
- lxi d,BDSTMSG
- call PRMAYBE
- pop b ;all done
- pop d
- pop h
- ret
-
- BDSTMSG: db '.bd-rt. $'
-
- ; table of baud rate divisors for supported rates
- BAUDTB: db 142,052,035,026,022 ;110,300,450,610,710
- db 0,0,0,0,0 ;1200,2400,4800,9600,19200
-
-
- ; Sign-on message
- SYSVER: lxi d,LINMSG
- mvi c,PRINT
- call MEX
- lxi d,SOMESG
- mvi c,PRINT
- call MEX
- lxi d,bpmess
- mvi c,PRINT
- call MEX
- CARRSH: lxi d,NOMESG ;tell about carrier
- call CARRCK ;check for it
- mvi c,PRINT
- cz CMSG
- cnz MEX
- lxi d,LINMSG
- mvi c,PRINT
- call MEX
- lxi d,GRBMSG
- mvi c,PRINT
- call MEX
- ret
- CMSG: push psw
- mvi c,PRINT
- lxi d,CARMSG
- call MEX
- pop psw
- ret
-
-
- SOMESG: db '* PMMI overlay version - '
- db REV/10+'0'
- db '.'
- db REV MOD 10+'0'
- LEVEL: db ' *',CR,LF,'$'
- BPMESS: db '* Base port = '
- BPMSG: db 'x0 hex. *'
- NLMSG: db cr,lf,'$'
-
- NOMESG: db '* No carrier present. *$'
- CARMSG: db '* Carrier IS present. *$'
- LINMSG: db CR,LF,'********************************',CR,LF,'$'
- GRBMSG: db CR,LF,'$'
- ;
- ;
- ; get DTR port value based on baud rate
- ;
- GETDTR: lda BAUDSV
- cpi 52 ;>300?
- mvi a,05Fh ;set speed configuration (ARRRRRRGGGGHHHH.)
- rc ;done if so (Swapped in version 2.0)
- mvi a,07Fh ;reset speed config bit (ARRRRRRGGGGGHHHH.)
- ret
-
-
- ; check the PMMI for carrier-present (NZ=no)
- CARRCK: call iBDRP ;get status byte
- ani CTSMSK
- rnz
- push psw
- mvi a,255
- sta OFFHK
- pop psw
- ret
-
-
- ; Newline on console
- CRLF: mvi a,CR
- call TYPE
- mvi a,LF ;fall into TYPE
-
-
- ; type char in A on console
- TYPE: push h ;save 'em
- push d
- push b
- mov e,a ;align output character
- mvi c,CONOUT ;print via MEX
- call MEX
- pop b
- pop d
- pop h
- ret
-
-
- ; strings to clear-to-end-of-screen, and clear-screen
- ; Note: these are dummy strings, not intended to be displayed...
- EOSMSG: db ' -clr eos- $' ;clear to end-of-screen
- CLSMSG: db ' -clr all- $' ;clear whole screen
-
-
- ;
- ;------------------------------------------------------------
- ;
- ; The remainder of this overlay implements a very versatile
- ; SET command -- if you prefer not to write a SET for your
- ; modem, you may delete the code from here to the END statement.
- ;
- ;
- ; Control is passed here after MEX parses a SET command.
- ;
- SETCMD: mvi c,SBLANK ;any arguments?
- call MEX
- jc SETSHO ;if not, go print out values
- lxi d,CMDTBL ;parse command
- call TSRCH ;from table
- push h ;any address on stack
- rnc ;if we have one, execute it
- pop h ;nope, fix stack
- SETERR: lxi d,SETEMS ;print error
- mvi c,PRINT
- call MEX
- ret
- ;
- SETEMS: db CR,LF,'SET command error',CR,LF,'$'
- ;
- ; SET command table ... note that tables are constructed of command-
- ; name (terminated by high bit=1) followed by word-data-value returned
- ; in HL by MEX service processor LOOKUP. Table must be terminated by
- ; a binary zero.
- ;
- ; Note that LOOKUP attempts to find the next item in the input stream
- ; in the table passed to it in HL ... if found, the table data item is
- ; returned in HL; if not found, LOOKUP returns carry set.
- ;
- CMDTBL: db '?'+80h ; "set ?"
- dw STHELP ;
- db 'BAU','D'+80h ; "set baud"
- dw STBAUD ;
- db 'ID','D'+80h ; "set id"
- dw SETIDD ;
- db 'ANSWE','R'+80h ; "set answer"
- dw STANSW ;
- db 'AN','S'+80h ; "set ans" (same as above)
- dw STANSW ;
- db 'ORIGINAT','E'+80h ; "set originate"
- dw STORIG ;
- db 'ORI','G'+80h ; "set orig" (same as above)
- dw STORIG ;
- db 'OR','G'+80h ; "set org" (same as above)
- dw STORIG ;
- db 'OFFHOO','K'+80h ; "set offhook"
- dw OFF ;
- db 'ONLIN','E'+80h ; "set online" (same as offhook)
- dw OFF ;
- db 'ONHOO','K'+80h ; "set onhook"
- dw PDISC ;
- db 'OFFLIN','E'+80h ; "set offline" (same as onhook)
- dw PDISC ;
- db 'PP','S'+80h ; "set pps"
- dw SETPPS ;
- db 'BAS','E'+80h ; "set PMMI base port."
- dw SETBP ;
- db 'IC','D'+80h ; "set delay between calls"
- dw SETICD ;
- db 'EXTR','A'+80h ; "set extra print mode"
- dw SETXTRA ;
- db 'XYZZ','Y'+80h ;
- dw XYZZY ;
- ;
- db 0 ; <<=== table terminator
- ;
- ; SET <no-args>: print current statistics
- ;
- SETSHO: call SYSVER ;show carrier present/not present
- lxi h,SHOTBL ;get table of SHOW subroutines
- SETSLP: mov e,m ;get table address
- inx h
- mov d,m
- inx h
- mov a,d ;end of table?
- ora e
- rz ;exit if so
- push h ;save table pointer
- xchg ;adrs to HL
- call GOHL ;do it
- call CRLF ;print newline
- mvi c,CHEKCC ;check for console abort
- call MEX
- pop h ;it's done
- jnz SETSLP ;continue if no abort
- call CRLF
- ret
-
- GOHL: pchl
-
-
- ; table of SHOW subroutines
- SHOTBL: dw BDSHOW
- dw MDSHOW
- dw SHOICD
- dw SHOIDD
- dw SHOPPS
- dw SHOXTRA
- dw CRLF
- dw 0 ;<<== table terminator
-
- ;
- ; SET ? processor
- ;
- STHELP: lxi d,HLPMSG
- mvi c,PRINT
- call MEX
- ret
- ;
- ; The help message
- ;
- HLPMSG: db cr,lf,'SET command, for the PMMI S-100 modem (r.i.p.)'
- db cr,lf
- db cr,lf,'SET ANSWER <or> SET ANS ... put PMMI in answer mode'
- db cr,lf,'SET BASE <hex #> ... set new PMMI base port'
- db cr,lf,'SET BAUD <value> ... set baud rate'
- db cr,lf,' BAUD values allowed are: 110, 300, 450, 600, and 710'
- db cr,lf,'SET EXTRA <value> ... OFF if <value> == 0, else ON'
- db cr,lf,' EXTRA function diagnostics displayed: BAUD RATE, BREAK,'
- db cr,lf,' DISCONNECT, OFF-HOOK, and WAIT (for answer tone)'
- db cr,lf,'SET ICD <value>'
- db ' ... intercall delay; 150 == 30 seconds'
- db cr,lf,'SET IDD <value> ... interdigit delay in 100''s msec'
- db cr,lf,'SET OFFHOOK <or> SET ONLINE ... force PMMI online'
- db cr,lf,'SET ONHOOK <or> SET OFFHOOK ... disconnect without message'
- db cr,lf,'SET ORIGINATE <or> SET ORIG ... put PMMI in originate mode'
- db cr,lf,'SET PPS <value> ... may be 10, 15 or 20 pulses/sec.'
- db cr,lf
- db cr,lf, '$'
-
-
- ; SET BAUD processor
- STBAUD: mvi c,BDPARS ;function code
- call MEX ;let MEX look up code
- jc SETERR ;invalid code
- call PBAUD ;no, try to set it
- jc SETERR ;not-supported code
- BDSHOW: call ILPRT ;display baud
- db 'Baud rate: ', tab, ' ', 0
- lda MSPEED
- mvi c,PRBAUD ;use MEX routine
- call MEX
- ret
-
-
- ; SET MODE processor
- MDSHOW: call ILPRT ;show mode
- db 'Mode:', tab, tab, ' ', 0
- lda UCTLB ;get UART B image
- ani ORBIT ;orig?
- jz MDORIG
- call ILPRT
- db 'Originate', 0
- ret
-
- MDORIG: call ILPRT
- db 'Answer', 0
- ret
-
- STORIG: mvi l,ORBIT
- jmp CHGAO
-
- STANSW: mvi l,ANBIT
- CHGAO: lda UCTLB
- ani MODEMK
- ora l
- sta UCTLB
- call OHKBYT
- jnz MDSHOW
- call oCTL1
- call OFF
- jmp MDSHOW
-
- OHKBYT: lda OFFHK
- cma
- ora a
- ret
-
- ;
- ; SET PPS command processor
- ;
- SETPPS: lxi d,PPSTBL ;get value
- call TSRCH
- jc SETERR ;not found in table? error out
- mov a,l ;yep, set it
- sta PRATE
- SHOPPS: call ILPRT
- db 'PPS rate: ', tab, ' ', 0
- lda PRATE ;display PPS
- cpi 250
- jnz SHO2
- call ILPRT
- db '10', 0
- ret
- SHO2: cpi 125
- jnz SHO3
- call ILPRT
- db '20',0
- ret
- SHO3: call ILPRT
- db '15',0
- ret
-
-
- PPSTBL: db '1','0'+80H ;"set pps 10"
- dw 250
- db '1','5'+80h ;"set pps 15"
- dw 167
- db '2','0'+80H ;"set pps 20"
- dw 125
- db 0 ;<<=== table terminator
- ;
- ; SET IDIG command processor
- ;
- SETIDD: mvi c,EVALA
- call MEX ;get numeric
- mov a,h ;validate
- ora a
- jnz SETERR
- mov a,l
- sta INTERD ;set new rate
- SHOIDD: call ILPRT
- db 'Inter-digit delay: ', 0
- lda INTERD ;get value
- mov l,a ;move delay to HL
- mvi h,0
- mvi c,DECOUT ;print it
- call MEX
- call ILPRT
- db '00 ms',0
- ret
-
-
- ; Set BASE PORT command processor.
- SETBP: mvi c,SBLANK
- call MEX
- mvi c,GNC ;get char from input, cy=1 if none
- call MEX
- call UPPER
- mov l,a ; Character to test is in L.
- shld TEMP
-
- lxi b,BPTAB-1
- lxi d,10h
- lxi h,-10h
-
- SETLP: inx b ; Advance to next allowable character.
- dad d ; Add 10 hex to base port address.
- ldax b ;
- ora a ;
- jm SETNG ; Jump if character typed not in allowable set.
- push h ;
- lhld TEMP ;
- cmp l ; Valid port requested?
- shld TEMP ;
- pop h ; Restore new base port.
- jnz SETLP ; No match, try again.
- sta BPMSG ; Patch sign-on message with Port # (ascii).
- mov a,l ;
- sta NITBYT ; Save base port (hex) for I/O and for CLONING.
- ret
-
-
- BPNOGO: db 7, ' **** Invalid port ****', cr, lf, '$'
- SETNG: lxi d,BPNOGO
- mvi c,PRINT
- jmp MEX
-
-
- SETICD: mvi c,EVALA
- call MEX ;get numeric
- mov a,h ;validate
- ora a
- jnz SETERR
- mov a,l
- sta WTNUM ;set new rate
- SHOICD: call ILPRT
- db 'Inter-call delay: ', 0
- lda WTNUM ;get value
- mov l,a ;move delay to HL
- mvi h,0
- mvi c,DECOUT ;print it
- call MEX
- call ILPRT
- db ' ticks. (150 ticks=30 seconds)', 0
- ret
-
- SETXTRA: mvi c,EVALA
- call MEX
- mov a,h
- ora a
- jnz SETERR
- mov a,l
- sta PRXTRA
- SHOXTRA: call ILPRT
- db 'Extra print mode: ',0
- lda PRXTRA
- ora a
- lxi d,ONNMSG
- jnz SHOXT2
- lxi d,OFFMSG
- SHOXT2: jmp PRMBOK
-
- ONNMSG: db 'ON$'
- OFFMSG: db 'OFF$'
-
-
- ; Compare next input-stream item in table @DE; CY=1
- ; if not found, else HL=matched data item
- TSRCH: mvi c,LOOKUP ;get function code
- jmp MEX ;pass to MEX processor
-
-
- XYZZY: call ILPRT
- db 'Nothing happens...', 0
- ret
-
-
- ; Print in-line message
- ILPRT: mvi c,ILP ;get function code
- jmp MEX ;go do it
-
-
- TIMOUT: mvi c,TIMER ;
- jmp MEX ;
-
-
- UPPER: cpi 'a'
- rc
- cpi 'z'+1
- rnc
- sui 'a'-'A'
- ret
-
-
- ;------------------------------------------------------------
- ;
- ; End of PMMI MEX modem overlay
- ;
- ;------------------------------------------------------------
-
-
- end
-