TITLE   'MEXPLUS overlay for PMC Micromate 101, Version 1.1'

; MXH-MI10.ASM - MEXPLUS OVERLAY FOR PMC MICROMATE 101
;   Version 1.1  January 04/87
;       (Delete above TITLE if not assembling with MAC)

VER:    EQU     11              ; Version number


; History:

; 87/01/04 Fixed bug in NEWBD routine.  This routine destroyed HL, which
;          some modem overlays (like MXM-2416.ASM) required be preserved.
;          Also deleted some superfluous code.
;                               Ian Cottrell

; 85/12/28 Created from MXO-MI13.ASM
;                               Ian Cottrell,
;                               Dept Energy, Mines and Resources,
;                               Ottawa, Canada

; =   =   =   =   =   =   =   =   =   =   =   =   =   =   =   =   =   =
;       /////////////////////////////////////////
;       /                                       /
;       /       - - W A R N I N G - -           /
;       /                                       /
;       /    This code uses CP/M 3 dependent    /
;       /    stuff.                             /
;       /                                       /
;       /////////////////////////////////////////

; =   =   =   =   =   =   =   =   =   =   =   =   =   =   =   =   =   =
;
; Use the MEX "SET" command to change the baud rate when desired.  Use
; "SET" to see the current baud rate and "SET xxxx" to set to xxxx.  It
; starts out at the value specified for the MSPEED equate.  To change
; the default baud rate, use "SET" to set the desired rate, then "CLONE"
; MEX.
;
; =   =   =   =   =   =   =   =   =   =   =   =   =   =   =   =   =   =


BELL:   EQU     07H             ; Bell
CR:     EQU     0DH             ; Carriage return
ESC:    EQU     1BH             ; Escape
LF:     EQU     0AH             ; Linefeed

BDOS:   EQU     05H             ; BDOS entry point

YES:    EQU     0FFH
NO:     EQU     0

RVIDEO: EQU     YES             ; Yes if terminal supports reverse video
                               ; Be sure to set RON and ROFF to correct
                               ; values

; PMC Micromate Model 101 dependant stuff

PORT:   EQU     89H             ; PMC serial modem port
DPORT:  EQU     PORT            ; Modem data port
CPORT:  EQU     PORT+2          ; Modem control port
SPORT:  EQU     PORT+2          ; Modem status port
DAV:    EQU     01H             ; Data available
TBMT:   EQU     04H             ; Tranmit buffer empty
DCD:    EQU     08H             ; check for data carrier detect
RI:     EQU     10H             ; check for ring indicator

; Terminal definitions (currently set for Qume QVT-103)
; If your terminal uses less characters for these functions, set the
; extra ones to space (20H), starting from the 1st character.

ATT1:   EQU     20H             ; 1st character of reverse video sequence
ATT2:   EQU     0EH             ; 2nd character of reverse video sequence
RON:    EQU     'D'             ; 3rd character (rev vid on)
ROFF:   EQU     'E'             ; 3rd character (rev vid off)

CLR1:   EQU     20H             ; 1st character of clear screen functions
CLR:    EQU     18H             ; 2nd character (clear screen)
CLEOS:  EQU     17H             ; 2nd character (clear end of screen)

; =   =   =   =   =   =   =   =   =   =   =   =   =   =   =   =   =   =
; MEX Service Processor

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     100H

       DB      0C3H            ; Show that we're an 8080/Z-80 overlay
       DS      2               ; rest of the jump instruction

       DS      2               ; unused by MEX

       DB      'P'             ; T=touch, P=pulse (Smartmodem-only)     105H
CLOCK:  DB      40              ; Clock speed in MHz x10, 25.5 MHz max.  106H
                               ;    20=2 MHh, 37=3.68 MHz, 40=4 MHz, etc.
MSPEED: DB      5               ; 0=110 1=300 2=450 3=600 4=710 5=1200   107H
                               ;    6=2400 7=4800 8=9600 9=19200 default
BYTDLY: DB      2               ; 0=0 delay  1=10ms  5=50 ms - 9=90 ms   108H
                               ;    Default time to send char in terminal
                               ;    mode file transfer for slow BBS.
CRDLY:  DB      4               ; 0=0 delay 1=100 ms 5=500 ms - 9=900 ms 109H
                               ;    Default time for extra wait after CRLF
                               ;    in terminal mode file transfer
COLUMS: DB      5               ; Number of DIR columns shown            10AH
SETFLG: DB      YES             ; Yes=user-added Setup routine           10BH
SCRTST: DB      YES             ; Cursor control routine                 10CH
       DS      1               ; unused by MEX
BAKFLG: DB      NO              ; Yes=change any file same name to .BAK  10EH
CRCDFL: DB      YES             ; Yes=default to CRC checking            10FH
TOGCRC: DB      YES             ; Yes=allow toggling of CRC to Checksum  110H
CVTBS:  DB      NO              ; Yes=convert backspace to rub           111H
TOGLBK: DB      YES             ; Yes=allow toggling of bksp to rub      112H
ADDLF:  DB      NO              ; No=no LF after CR to send file in      113H
                               ;    terminal mode (added by remote echo)
TOGLF:  DB      YES             ; Yes=allow toggling of LF after CR      114H
       DB      YES             ; Yes=allow transmission of logon        115H
                               ;    write logon sequence at location LOGON
SAVCCP: DB      YES             ; Yes=do not overwrite CCP               116H
       DB      NO              ; Yes=local command if EXTCHR precedes   117H
                               ; No=external command if EXTCHR precedes
       DB      YES             ; Yes=allow toggling of LOCONEXTCHR      118H
LSTST:  DB      NO              ; Yes=printer available on printer port  119H
XOFTST: DB      YES             ; Yes=checks for XOFF from remote while  11AH
                               ;    sending a file in terminal mode
XONWT:  DB      NO              ; Yes=wait for XON after CR while        11BH
                               ;    sending a file in terminal mode
TOGF    DB      YES             ; Yes=allow toggling of XOFF checking    11CH
IGNCTL: DB      YES             ; Yes=CTL-chars above ^M not displayed   11DH
EXTRA1: DB      0               ; For future expansion                   11EH
EXITCHR:DB      'E'             ; E = Exit to main menu                  11FH
BRKCHR: DB      '@'             ; @ = Send 300 ms. break tone            120H
NOCONN: DB      'D'             ; D = Disconnect from the phone line     121H
LOGCHR: DB      'L'             ; L = Send logon                         122H
LSTCHR: DB      'P'             ; P = Toggle printer                     123H
UNSAVE: DB      'U'             ; U = Close input text buffer            124H
TRANCHR:DB      'T'             ; T = Transmit file to remote            125H
SAVECHR:DB      'S'             ; S = Open input text buffer             126H
EXTCHR: DB      '^'             ; ^ = Send next character                127H

       DS      2               ;                                        128H

INCTL1: XRA     A               ; Output 00H to command port             12AH
       OUT     CPORT           ;                                        12BH
       MVI     A,10H           ; Output 10H to command port             12DH
       OUT     CPORT           ;                                        12FH
       IN      SPORT           ; Get status bits.                       131H
       RET                     ;                                        133H
;
OTDATA: OUT     DPORT           ; Out modem data port                    134H
       RET

       DS      7               ;                                        137H

INPORT: IN      DPORT           ; In modem data port                     13EH
       RET

       DS      7               ;                                        141H

MASKR:  ANI DAV                 ; Bit to test for receive ready          148H
       RET

TESTR:  CPI DAV                 ; Value of rcv. bit when ready           14BH
       RET

MASKS:  ANI TBMT                ; Bit to test for send ready             14EH
       RET

TESTS:  CPI TBMT                ; Value of send bit when ready           151H
       RET

DCDTST: JMP     DCDVEC          ; Data carrier detect                    154H
RNGDET: JMP     RNGVEC          ; ring detect                            157H

       DB      0,0,0,0,0       ; reserved space, assumed 0

SMDISC: DS      3               ; smartmodem disconnect (not here)
DIALV:  DS      3               ; DIALV:  not done here (maybe MXO-SM)

DISCV:  JMP     DISCON          ; Disconnect modem                       165H
GOODBV: JMP     GOODBY          ; Reset port                             168H
INMODV: JMP     NITMOD          ; Initialize port                        16BH
NEWBDV: JMP     NEWBD           ; Set new baud rate                      16EH

       RET                     ; NOPARV                                 171H
       NOP
       NOP

       RET                     ; PARITV                                 174H
       NOP
       NOP

SETUPV: JMP     SETCMD          ;                                        177H

       DS      3               ; Not used by MEX                        17AH

VERSNV: JMP     SYSVER          ;                                        17DH
BREAKV: JMP     SBREAK          ;                                        180H

; Do not change the following line

       DS      18

; Routine to clear to end of screen.  If using CLREOS and CLRSCRN, set
; SCRNTEST to YES at 010AH (above).

CLREOS: LXI     D,EOSMSG        ;                                        195H
       MVI     C,PRINT
       CALL    MEX
       RET

CLS:    LXI     D,CLSMSG        ;                                        19EH
       MVI     C,PRINT
       CALL    MEX
       RET

; End of fixed area ... from here to 1FFH is reserved

       ORG     200H            ; new boundary for MEXPLUS

SYSVER: MVI     C,ILP
       CALL    MEX
       DB      'MEXPLUS version '
       DB      VER/10+'0'
       DB      '.'
       DB      VER MOD 10+'0'
       DB      ' for PMC Micromate Model 101 - '
       DB      CR,LF
       DB      'Default Baud Rate: '

        IF     RVIDEO
       DB      ATT1,ATT2,RON
        ENDIF
       DB      0
       LDA     MSPEED
       MVI     C,PRBAUD
       CALL    MEX

        IF     RVIDEO
       MVI     C,ILP
       CALL    MEX
       DB      ATT1,ATT2,ROFF,0
        ENDIF
       RET

; Routine called just prior to exit to CP/M

GOODBY: RET

; Return data carrier detect (DCD) status
;        0   = no carrier
;        255 = carrier present
;        254 = we don't know (DCD not supported)

DCDVEC: MVI     A,254           ; Return 'we don't know'
;       CALL    INCTL1          ; Get status
;       ANI     DCD             ; Test for DCD
;       MVI     A,255           ; Assume it's there
;       RNZ                     ; It was!
;       XRA     A               ; No it wasn't
       RET

; Return ring indicator status
;        0   = not ringing
;        255 = ring detected
;        254 = we don't know (RI not supported)

RNGVEC: MVI     A,254           ; Return 'we don't know'
       RET

; Routine to send a 300 ms break tone to reset some time-sharing
; computers.

SBREAK: MVI     A,5             ; Select register 5
       OUT     CPORT
       MVI     A,0F8H          ; Send break
SBRK1:  OUT     CPORT
       MVI     B,3             ; Delay 300 ms
       MVI     C,TIMER
       CALL    MEX
       MVI     A,5             ; Register 5 again
       OUT     CPORT
       MVI     A,0E8H          ; Reset to normal (8 bits, DTR on, etc.)
       OUT     CPORT
       RET

; Routine to set DTR low for 300 ms to hang-up modem

DISCON: MVI     A,5             ; Select register 5
       OUT     CPORT
       MVI     A,068H          ; Drop DTR (and send break)
       JMP     SBRK1           ; Save a litte code here


; You can use this area for any special initialization or setup you may
; wish to include.  Each must end with a RET. You can check the other
; available overlays for ideas how to write your own routines if that
; may be of some help.

NITMOD: LDA     MSPEED          ; Get MSPEED value
       PUSH    H               ; Save HL (needed by some modem overlays)
       LXI     H,BRTBL         ; Calculate required value
       MVI     D,0             ;   to send to baud
       MOV     E,A             ;      rate register
       DAD     D
       MOV     A,M             ; Reg A now contains correct value
       ORA     A               ; Was value zero?
       JNZ     NITMOD1         ; If not zero, continue
       LDA     BD1200          ; Else, default to 1200 baud
NITMOD1:PUSH    PSW             ; Save baud rate value
       MVI     C,32H           ; Function: direct bios call.
       LXI     D,BIOSPB        ; BIOS parameter block
       CALL    BDOS
       LXI     D,8+7           ; Index to BAUD rate in 2nd
       DAD     D               ; Entry. (i.e. MODEM)
       POP     D               ; Get new code back (in D)
       MOV     A,M             ; Best not to change high
       ANI     0F0H            ;    nibble, whatever it is.
       ORA     D               ; Put new code in table.
       MOV     M,A
       MVI     C,32H           ; Function: direct bios call.
       LXI     D,BIOSPB1       ; Initialize device means to
       CALL    BDOS            ; Set BAUD rate to PMC.
       IN      DPORT           ; Clear any incoming chars
       IN      DPORT           ; Try once more
       XRA     A               ; Clear the 'A' reg
       POP     H               ; Now restore HL
       RET

;Allow baud rate change w SET cmd

SETCMD: MVI     C,SBLANK        ; Any arguments
       CALL    MEX
       JC      TELL            ; If not, go display baud
       LXI     D,CMDTBL
       MVI     C,LOOKUP
       CALL    MEX             ; Parse argument
       PUSH    H               ; Save any arg addrs on stack
       RNC                     ; If we have one, return to it
       POP     H               ; Oops, input not found in table
       MVI     C,ILP
       CALL    MEX             ; Tell user input not valid
       DB      '++ Incorrect Entry ++',CR,LF,BELL,0
       RET

CMDTBL: DB      '30','0'+80H
       DW      OK300
       DB      '60','0'+80H
       DW      OK600
       DB      '120','0'+80H
       DW      OK1200
       DB      '240','0'+80H
       DW      OK2400
       DB      '480','0'+80H
       DW      OK4800
       DB      '960','0'+80H
       DW      OK9600
       DB      '1920','0'+80H
       DW      OK1920
       DB      0               ; End of table

TELL:   MVI     C,ILP
       CALL    MEX             ; Print current baud rate
       DB      CR,LF,'Baud rate is now: '

        IF     RVIDEO
       DB      ATT1,ATT2,RON
        ENDIF

       DB      0
       LDA     MSPEED
       MVI     C,PRBAUD
       CALL    MEX

        IF     RVIDEO
       MVI     C,ILP
       CALL    MEX
       DB      ATT1,ATT2,ROFF,0
        ENDIF

       RET

OK300:  MVI     A,1             ; MSPEED 300 baud value
       JMP     BDSET           ; Go do it

OK600:  MVI     A,3
       JMP     BDSET

OK1200: MVI     A,5
       JMP     BDSET

OK2400: MVI     A,6
       JMP     BDSET

OK4800: MVI     A,7
       JMP     BDSET

OK9600: MVI     A,8
       JMP     BDSET

OK1920: MVI     A,9

BDSET:  STA     MSPEED          ; Update MSPEED
       JMP     NITMOD

BAUDMCH:PUSH    PSW             ; Save MSPEED value
       PUSH    H               ; Save baud code
       MVI     C,32H           ; Function: direct bios call.
       LXI     D,BIOSPB        ; BIOS parameter block
       CALL    5
       LXI     D,8+7           ; Index to BAUD rate in 2nd
       DAD     D               ; Entry. (i.e. MODEM)
       POP     D               ; Get new code back.
       MOV     A,M             ; Best not to change high
       ANI     0F0H            ; Nibble, whatever it is.
       ORA     E               ; Put new code in table.
       MOV     M,A

       MVI     C,32H           ; Function: direct bios call.
       LXI     D,BIOSPB1       ; Initialize device means to
       CALL    5               ; Set BAUD rate to PMC.
       POP     PSW             ; Restore MSPEED value
       STA     MSPEED          ; Set it
       RET

NEWBD:  CPI     1
       JZ      BDSET
       CPI     3
       JZ      BDSET
       CPI     5
       JZ      BDSET
       CPI     6
       JZ      BDSET
       CPI     7
       JZ      BDSET
       CPI     8
       JZ      BDSET
       CPI     9
       JZ      BDSET
       RET

; Table of Baud Rate Parameters

BRTBL:  EQU     $

BD110:  DB      00H             ; 110 baud not supported
BD300:  DB      06H
BD450:  DB      00H             ; 450 baud not supported
BD600:  DB      07H
BD710:  DB      00H             ; 710 baud not supported
BD1200: DB      08H
BD2400: DB      0AH
BD4800: DB      0CH
BD9600: DB      0EH
BD1920: DB      0FH

BIOSPB  DB      20              ; BIOS fcn: return devtbl address
       DB      0               ; A-reg contents
       DW      0               ; BC-reg contents
       DW      0               ; DE-reg contents
       DW      0               ; HL-reg contents

BIOSPB1 DB      21              ; BIOS fcn: initialize device in C-reg
       DB      0               ; A-reg contents
       DB      1               ; C-reg (= 1 for MODEM)
       DB      0               ; B-reg
       DW      0               ; DE-reg
       DW      0               ; HL-reg


BAUDBUF:DB      10,0
       DS      10

EOSMSG: DB      CLR1,CLEOS,0,0,0,'$'    ; Clear to end of screen
CLSMSG: DB      CLR1,CLR,0,0,0,'$'      ; Clear screen

       END