title 'Overlay for the Morrow Multi I/O Board and/or 8250 ACE' ; ; MXO-MM10.ASM -- MEX Overlay file for the Morrow Multi I/O Board. 05/28/84 ; REV EQU 10 ;V 1.0 ; ; This overlay adapts the MEX modem program to the Morrow Multi I/O board ; which uses the 8250 ACE. It also can be used with an 8250 ACE alone by ; setting MORMIO to FALSE. ; ; This overlay is capable of setting baud rate and setting port number ; (via the SET command), setting baud rate from the phone library, dis- ; connecting the modem, and sending a break. ; ; *NOTE* This overlay contains two conditionals and uses DTR to disconnect ; the modem. SET THE DISC EQU TO FALSE in MXO-SMxx.ASM if using that overlay. ; DISC is handled here with DTR. ; NO EQU 0 YES EQU NOT NO FALSE EQU NO TRUE EQU YES ; ; Set the following two equates as needed: ; MORMIO EQU TRUE ;true if using Morrow Multi I/O card, false for ; stand alone 8250 ACE. SMDM EQU TRUE ;True if using Smartmodem 1200, false and/or change ; code for other modems with Morrow Multi I/O ; ; Also, be sure to set your port address and desired baud rates below ; ; NOTE: I have tested this overlay to the extent possible with MORMIO, SMDM, ; or both FALSE. However, I could not conduct a full operational test since ; I do not have a properly configured machine. Please report any bugs, ; suggestions to: Phil Cary, Mesilla Valley RCP/M, (505) 524-6920. ; ; Calling conventions for the various overlay entry points are detailed more ; fully in the PMMI overlay (MXO-PMxx.ASM, where xx=revision number) ; ; History as a MEX overlay ; ; 05/28/84 - 1st version - Phil Cary, Mesilla Valley RCP/M ; ; Derived from: MXO-PM10.ASM, Ron Fowler ; MXO-SM11.ASM, Ron Fowler ; MXO-GB10.ASM, Ron Fowler ; SMDMM.ASM, Phil Cary (overlay for MDMxxx) ; ; MEX service processor stuff ; 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 ; PRINT EQU 9 ;BDOS/MEX print-string function call ; BELL EQU 7 ;bell TAB EQU 9 CR EQU 13 ;carriage return LF EQU 10 ;linefeed ESC EQU 1BH ;escape ; ; IF MORMIO ; ;These are the equates for the Morrow Multi I/O base port and group selection. ;Change as needed to match your configuration. ; ; Morrow Multi I/O port equates ; BPORT EQU 0F8H ;base port for Morrow Multi I/O GPORT EQU BPORT+7 ;group select port MPORT EQU 2 ;default group in use for modem ; (2nd serial port) ENDIF ; ; IF NOT MORMIO ; ; 8250 port equates ; BPORT EQU 00H ;If using stand alone 8250, put base port address here. ; ENDIF ; MODDAT: EQU BPORT ;data port(dlab=0) MODIER: EQU BPORT+1 ;interrupt enable register(dlab=0) MODLCR: EQU BPORT+3 ;line control register MODMCR: EQU BPORT+4 ;modem control register MODLSR: EQU BPORT+5 ;line status register LBAUDP: EQU BPORT ;LSB baud rate divisor latch(dlab=1) MBAUDP: EQU BPORT+1 ;MSB baud rate divisor latch(dlab=1) ; ;These are equates for the 8250 register masks or control words. ; ;line control register ; wls0 equ 00000001b ;for eight bit word wls1 equ 00000010b ;for eight bit word sbrk equ 01000000b ;set break dlab equ 10000000b ;baud rate divisor latch active ; ;modem control register ; dtr equ 00000001b ;DTR on ; ;line status register ; dr equ 00000001b ;data ready thre equ 00100000b ;transmitter holding register empty ; ; ; Baud rate parameters - change EQU to 0000h if you do not wish to support ; a particular baud rate. ; BD110: EQU 0417H ;110 baud BD300: EQU 0180H ;300 baud BD450: EQU 0120H ;450 baud BD600: EQU 00C0H ;600 baud BD710: EQU 0000H ;710 baud (not supported) BD1200: EQU 0060H ;1200 baud BD2400: EQU 0030H ;2400 baud BD4800: EQU 0018H ;4800 baud BD9600: EQU 000CH ;9600 baud BD19200 EQU 0006H ;19200 baud ; ORG 100H ; ; Change the clock speed to suit your system ; DS 3 ;(for "JMP START" instruction) DB NO ;yes=PMMI S-100 Modem 103H DB YES ;yes=HAYES Smartmodem, no=non-PMMI 104H DB 'T' ;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 5 ;0=0 delay 1=10ms 5=50 ms - 9=90 ms 108H ;default time to send character in ter- ;minal mode file transfer for slow BBS. CRDLY: DB 5 ;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 DB YES ;yes=resend a record after any non-ACK 10DH ;no=resend a record after a valid-NAK 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 LSTTST: DB YES ;yes=printer available on printer port 119H XOFTST: DB NO ;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 TOGXOF: 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'-40H ;^E = Exit to main menu 11FH BRKCHR: DB '@'-40H ;^@ = Send 300 ms. break tone 120H NOCONN: DB 'N'-40H ;^N = Disconnect from the phone line 121H LOGCHR: DB 'L'-40H ;^L = Send logon 122H LSTCHR: DB 'P'-40H ;^P = Toggle printer 123H UNSAVE: DB 'R'-40H ;^R = Close input text buffer 124H TRNCHR: DB 'T'-40H ;^T = Transmit file to remote 125H SAVCHR: DB 'Y'-40H ;^Y = Open input text buffer 126H EXTCHR: DB '^'-40H ;^^ = Send next character 127H DS 2 ;unused by MEX 128H ; INCTL1: JMP INSP ;go input status port 12AH DS 7 ; OTDATA: JMP OUTDP ;go output data port 134H DS 7 ; INPORT: JMP INDP ;go input data port 13EH DS 7 ; MASKR: ANI dr ! RET ;bit to test for receive ready 148H TESTR: CPI dr ! RET ;value of rcv. bit when ready 14BH MASKS: ANI thre ! RET ;bit to test for send ready 14EH TESTS: CPI thre ! RET ;value of send bit when ready 151H DS 12 ; 156H ; ; DS 2 ;for log on msg pointer DS 3 ;DIALV: not done here (maybe MXO-SM) 162H DISCV: JMP DISCON ;disconnect GOODBV: JMP GOODBY ; 168H INMODV: JMP NITMOD ;go to user written routine 16BH NEWBDV: JMP PBAUD ; 16EH RET ! NOP ! NOP ;NOPARV 171H RET ! NOP ! NOP ;PARITV 174H SETUPV: JMP SETCMD ; 177H DS 3 ;not used by MEX 17AH VERSNV: JMP SYSVER ; 17DH BREAKV: JMP SBREAK ; 180H ; ; Do not change the following six lines (they provide access to routines ; in MEX that are present to support MDM7 overlays -- they will likely ; be gone by MEX v2.0). ; ILPRTV: DS 3 ; 183H INBUFV DS 3 ; 186H ILCMPV: DS 3 ; 189H INMDMV: DS 3 ; 18CH DS 3 ; 18FH TIMERV DS 3 ; 192H ; ; Routine to clear to end of screen. If using CLREOS and CLRSCRN, set ; SCRTEST 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 ; 1A7H ; ; end of fixed area ; SYSVER: MVI C,ILP ;in-line print CALL MEX ; IF MORMIO ; DB 'Morrow Multi I/O at 0F8H V.' ; ENDIF ; IF NOT MORMIO ; DB 'Version for 8250 ACE V.' ; ENDIF ; DB REV/10+'0' DB '.' DB REV MOD 10+'0' DB CR,LF ; IF SMDM ; DB 'with Hayes Smartmodem 1200',CR,LF,LF ; ENDIF DB 0 ; MVI C,ILP CALL MEX DB 'Defaults- ',0 JMP TELL ; ; Routine to exit just prior to exit-to-cpm ; GOODBY: RET ;not done here ; ; Send break to remote ; SBREAK: MVI A,sbrk ;send break for 300ms CALL OUTCP PUSH B MVI B,3 MVI C,TIMER CALL MEX POP B MVI A,wls0+wls1 ;reset to normal 8 bits, 1 stop, dlab off CALL OUTCP RET ; ; Disconnect the modem ; DISCON: XRA A ;turn off DTR CALL OUTMP PUSH B MVI B,10 ;turn off DTR for 1000 ms.(my smartmodem MVI C,TIMER ;seems to require more than 300ms to hang up) CALL MEX POP B MVI A,dtr ;turn DTR back on CALL OUTMP RET ; ; Initialize the port with default baud rate(1200) ; NITMOD: PUSH H PUSH D PUSH B NITMO1: MVI A,5 ;default to 1200 baud STA MSPEED CALL SELGRP ;select morrow group XRA A ;disable 8250 interrupts OUT MODIER ;interrupt enable register MVI A,wls0+wls1+dlab ;8 bit word, 1 stop, baud rate div on out MODLCR LSBSPD: MVI A,60H ;default 'LSB' for 1200 baud OUT LBAUDP ;register for 'LSB' when dlab=1 MSBSPD: MVI A,00H ;default 'MSB' for 1200 baud OUT MBAUDP ;register for 'MSB' when dlab=1 ; ; finish up ; MVI A,wls0+wls1 ;8 bit, 1 stop, turn dlab off out MODLCR MVI A,dtr ;Be sure DTR is on out MODMCR ; IF SMDM ; ; for smartmodem only, send AT to set modem baudrate. LXI H,SMSET CALL SMSEND SMCLR MVI C,INMDM CALL MEX JNC SMCLR ENDIF ORA A ;no errors, clear carry for return to STBAUD POP B POP D POP H RET ; IF SMDM ; SMSEND: MVI C,SNDRDY ;WAIT FOR MODEM READY CALL MEX JNZ SMSEND MOV A,M ;FETCH NEXT CHARACTER INX H ORA A ;END? RZ ;DONE IF SO MOV B,A ;NO, POSITION FOR SENDING MVI C,SNDCHR ;NOPE, SEND THE CHARACTER CALL MEX JMP SMSEND ; SMSET: DB 'AT',CR,0 ;kick the modem ; ENDIF ; ; SET command: select baud rate, port number. Port number may be any of ; 1,2,, or 3, baud rate any of 110, 300, 450, 600, 1200, 2400, 4800 ; 9600, 19200. Special set-port syntax allows baud rate after port ; number. Examples: ; ; SET PORT 1 ; SET PORT 2 1200 ; SET PORT 3 300 ; SET BAUD 9600 ; SETCMD: MVI C,SBLANK ;any arguments? CALL MEX JC TELL ;if not, go display port/baud LXI D,CMDTBL MVI C,LOOKUP CALL MEX ;parse argument PUSH H ;save any parsed argument adrs on stack RNC ;if we have one, return to it POP H ;oops, input not found in table SETERR: MVI C,ILP ;inline print CALL MEX DB CR,LF,'SET command error',CR,LF,0 RET ; ; Argument table ; CMDTBL: DB '?'+80H ;help DW STHELP DB 'BAU','D'+80H ;"set baud" DW STBAUD ; IF MORMIO ; DB 'POR','T'+80H ;"set port" DW SETPOR ; ENDIF ; DB 0 ;<<=== table terminator ; ; "SET ?" processor ; STHELP: MVI C,ILP ;inline print CALL MEX DB CR,LF,'SET BAUD ' ; IF MORMIO ; DB CR,LF,'SET PORT ' DB CR,LF,'SET PORT ' ; ENDIF ; DB CR,LF,'Baud rate is one of:' DB CR,LF,' 110 300 450 600 1200 2400 4800 9600 19200' ; IF MORMIO ; DB CR,LF,'Port number is one of:' DB CR,LF,' 1, 2, or 3 for Morrow Multi I/O' ; ENDIF ; DB CR,LF,0 ;end of message RET ; ; "SET BAUD" processor ; STBAUD: MVI C,BDPARS ;function code: parse a baudrate CALL MEX ;let MEX look up code JC BDERR ;jump if invalid code CALL PBAUD ;no, try to set it JC BDERR ;if not one of ours, bomb out JMP TELL ;show the settings ; BDERR: MVI C,ILP CALL MEX DB 'Invalid baud rate selected',cr,lf,0 RET ; IF MORMIO ; ; SET PORT processor ; SETPOR: MVI C,SBLANK ;scan to argument CALL MEX JC SETERR ;if no arg, bomb out MVI C,GNC ;else consume it CALL MEX SUI '0' ;convert CPI 0 JZ PRTERR ;less than 1 CPI 3+1 JNC PRTERR ;more than 3 STA PORTS MVI C,SBLANK ;any thing more? CALL MEX JNC STBAUD ;if so, go parse as baud rate ; ENDIF ; TELL: ; IF MORMIO ; MVI C,ILP CALL MEX DB 'Port: ',0 LDA PORTS ADI '0' ;get port # in ASCII STA PORTAS MVI C,ILP CALL MEX PORTAS: DB ' , ',0 ; ENDIF ; MVI C,ILP ;inline print CALL MEX ;display baud DB 'Baud: ',0 LDA MSPEED ;get current baud rate MVI C,PRBAUD ;let MEX print it CALL MEX RET ; PRTERR: MVI C,ILP CALL MEX DB 'Invalid port selected',CR,LF,0 RET ; This routine sets baud rate passed as MSPEED code in A. ; Returns CY=1 if baud rate not supported (if supported, ; this routine must set the new MSPEED code). ; PBAUD: PUSH H ;don't alter anybody PUSH D PUSH B MOV E,A ;MSPEED code to DE MVI D,0 LXI H,BAUDTB ;offset into table DAD D DAD D ;each entry two bytes MOV A,M ;get LSB ORA A ;0? (means unsupported code) STC ;prep carry in case unsupported JZ PBEXIT ;exit if bad MOV A,E ;get MSPEED back STA NITMO1+1 ;store in NITMOD for execution MOV A,M ;get LSB of baud rate divisor STA LSBSPD+1 ;store in NITMOD for execution INX H ;bump to MSB MOV A,M ;get it STA MSBSPD+1 ;store it JMP NITMO1 ;go initialize the port/modem, ; carry reset there ; PBEXIT: POP B POP D POP H RET ; BAUDTB: DW BD110,BD300,BD450,BD600,BD710 DW BD1200,BD2400,BD4800,BD9600,BD19200 ; ; Port access routines ; ; Input ; INSP: CALL SELGRP ;select morrow group IN MODLSR ;get the status RET INDP: CALL SELGRP ;select morrow group IN MODDAT ;get the char RET ; ; Output ; OUTDP: PUSH PSW ;save the character CALL SELGRP ;select group POP PSW ;get char back OUT MODDAT ;and send it RET OUTMP: PUSH PSW ;save A CALL SELGRP ;select group POP PSW ;get A back OUT MODMCR ;send it to modem control register RET OUTCP: PUSH PSW ;save A CALL SELGRP ;select group POP PSW ;get A back OUT MODLCR ;send it to line control reg RET ; Select Morrow Multi I/O group(port) ; SELGRP: ; IF MORMIO ; LDA PORTS OUT GPORT ;select Morrow group # ; ENDIF ; RET ; IF MORMIO ; PORTS: DB MPORT ;default modem group(port) ; ENDIF ; ; Clear-to-end-of-screen and clear-screen sequences(H/Z 19) ; EOSMSG: DB ESC,'J','$' CLSMSG: DB ESC,'E','$' ; ; END