; M7QX-3.ASM -- Epson QX-10 overlay file for VALDOCS 1.1X 06/06/84 ; ; Overlay file for MDM730 (and later), Epson QX-10, and the ; D.C. Hayes Smartmodem 300 or 1200, US Robotics modems, the ; Anchor Automation Signalman Mark XII, Prometheus, or similiar ; modems which use the DC Hayes Smartmodem protocols. It is ; designed to be used with a .SYS extent as a VALDOCS applica- ; tion from the enu of Applications, un specific program, ; or xit to TPM options. It will also run under TPM-II ; without VALDOCS (using a .SYS or .COM extent) or under ; CP/M A2.21 or B2.20 if given a .COM file extent. It ; incorporates the special SET menu advantages of Bruce ; Ratoff's ATXMODEM, plus it offers the ability to toggle ; on or off the 7th bit mask. This permits the use of QX-10 ; graphics when desired, but retains the ability to use this ; same program on mainframes such as Compuserve. This overlay ; is specifically tailored to MDM730 and makes direct calls to ; addresses in the main program. You must change these addresses ; to use this overlay with a later MDM7XX series program. ; For standardization among the four operating systems used on ; the QX-10, I have chosen ^B for the sendbreak character, ; and ^Z to transmit control characters above ^M to the remote. ; ;****************************************************************************** ; ; NOTE: All improvements to this overlay intended for distribution must be ; compatible with VALDOCS. Send all updates to either the Technical RCPM/RBBS ; (313)846-6127, or CompuServe CP/MIG (PCS-47), Area XA0 along with a message ; addressed to the SYSOP. They, in turn, will make official release. If you ; wish to discuss the overlay, leave a message for Chris Hopkins, 71026,1407 on ; CompuServe's EpsOnLine SIG (PCS-19), or EMAIL. ; ;****************************************************************************** ; ; Switch settings for the D.C. Hayes Smartmodem and Smartmodem 1200 are: ; ; SW1 SW2 SW3 SW4 SW5 SW6 SW7 SW8 ; UP ANY ANY ANY ANY UP ANY* DN ; ; These settings are compatible with those used in VALDOCS MAIL to prevent ; unnecessary changing of settings. This program resets switches 2 thru 5 ; by software, so their physical settings have no effect. ; ; *Depends on type of telephone jack used. ;..... ; You will want to look this file over carefully. There are a number of ; options that you can use to configure the program to suit your taste. ; ; Edit this file for your preferences then follow the "TO USE:" example ; shown below. ; ; TO USE: First edit this file, filling in answers for your own ; preferences. Assemble with ASM.COM or equivalent ; assembler to obtain a file named M7QX-3.HEX. Then ; use DDT to overlay the HEX file on the original .COM file: ; ; A>DDT MDM730.COM ; DDT VERS 2.2 ; NEXT PC ; 4A00 0100 ; -IM7QX-3.HEX (note the "I" command) ; -R ("R" loads in the .HEX file) ; NEXT PC ; 4A00 0000 ; -G0 (return to CP/M) ; A>SAVE 73 QXMDM3.SYS (now have a modified .SYS file) ; (can also make a .COM file now) ; ; = = = = = = = = = = = = = = = = = = = ; 06/06/84 - Renamed to M7QX-3.ASM and added addresses for MDM740.ASM. ; - Added BYEBYE messages for CP/M, TPM and VALDOCS. ; - Corrected error in hardware initiation that forgot to tell the ; QX-10 baudrate timer the speed in use according to the CMOS. ; - Corrected timing problem in VALDOCS during ^T text transfer. ; - Corrected GOODBYE and SENDBRK to reset to parameters that were in ; use before the break. Previously, it always reset to 8 bit words, ; 1 stop bit and no parity. ; - Corrected timing problems for VALDOCS by placing CLOCKSET routine ; at START. Previously, timing set did not occur until INITMOD. ; -Chris Hopkins ; 04/15/84 - Removed macros to allow assembly using ASM.COM, and revised to ; work with MDM730. ; - Added cursor control routines for signon. ; - Added toggle in SET command to allow selection of QX-10 graphics ; for use in the terminal mode. Subsequent selection of 7-bit ; words or 8-bit words with the 7th bit masked cancels the ; graphics selection. - Chris Hopkins ; 03/11/84 - Renamed to M7QX-2.ASM and revised to work with MDM727. ; - Added subroutines to provide [ Using TPM ], [ Using CP/M ] and ; [ Using VALDOCS ] statements following signon message. - CH ; 01/22/84 - Revised M712QS.ASM to fit MDM718-720, renamed overlay to ; M7QX-1.ASM to conform to new format. ; - Added sendbreak routine and revised signon - Chris Hopkins ; 10/13/83 - Checks for CP/M or TPM to prevent crashing CP/M ; with TPM backdoor calls. - BRR ; 10/11/83 - Detects presence of SYSINIT and uses its interrupt-driven ; serial routines if present. - BRR ; 10/10/83 - Stop bits, parity, word size in SETUPR - BRR ; 08/14/83 - Cosmetic changes only for MDM712 - Bruce Ratoff ; 07/26/83 - QX-10 version created from GP file - Bruce Ratoff ; 07/01/83 - Revised to work with MDM711 - Irv Hoff ; 07/01/83 - Revised to work with MDM710 - Irv Hoff ; 05/27/83 - Updated to work with MDM709 - Irv Hoff ; 05/15/83 - Revised to work with MDM708 - Irv Hoff ; 04/11/83 - Updated to work with MDM707 - Irv Hoff ; 04/04/83 - First version of this file - Irv Hoff ; ; = = = = = = = = = = = = = = = = = ; BELL: EQU 07H ;bell CR: EQU 0DH ;carriage return ESC: EQU 1BH ;escape LF: EQU 0AH ;linefeed ; YES: EQU 0FFH NO: EQU 0 ; ;------------------------------------------------------------------------------ ; The following equates are addresses in the main program of MDM730.COM. If ; this overlay is adapted to a later version, these may have to be changed. ; PMMIMENU: EQU 09EDH ;addr of SPCLMENU in basic program ;available as extra patch area. ;For MDM730 use 09EDH ;For MDM740 use 0A78H ;Must match byte of basic program. ; START: EQU 13CAH ;addr of START in basic program. ;For MDM730-740 use 13CAH ; SPEED4: EQU 1A7EH ;addr of SPEED4 in basic program. ;For MDM730-740 use 1A7EH ; TERML: EQU 1F01H ;addr of TERML in basic program. ;Use 1F01 for MDM730-740 ; GRAFMASK: EQU TERML+10 ;addr of 7th bit mask in TERML ; BYEBYE: EQU 404DH ;addr of BYEBYE in basic program. ;For MDM730-740 use 404DH ; ;------------------------------------------------------------------------------ ; The following information is specific to the Epson QX-10. ; PORT: EQU 011H ;QX-10 base port MODCTL1: EQU PORT+2 ;Modem control port MODDATP: EQU PORT ;Modem data in port MODDATO: EQU PORT ;Modem data out port TPORTS: EQU 007H ;Baud rate setup port TPORTC: EQU 006H ;Baud rate counter port MODRCVB: EQU 1 ;Bit to test for receive MODRCVR: EQU 1 ;Value when ready MODSNDB: EQU 4 ;Bit to test for send MODSNDR: EQU 4 ;Value when ready CRAM: EQU 35 ;CMOS RAM baud rate storage MOSADR: EQU 3DH ;CMOS RAM address port MOSDAT: EQU 3CH ;CMOS RAM data port ; ORG 100H ;..... ; Change the clock speed to suit your system ; DS 3 ;(for "JMP START" instruction) PMMIMODEM: DB NO ;yes=PMMI S-100 Modem, no=non-PMMI 103H AUTODIAL: DB YES ;yes=HAYES Smartmodem or lookalike 104H TOUCHPULSE: 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 1 ;When booting up, the program will set 107H ;this flag to match the QX-10's current ;CMOS baud rate. BYTDLY: DB 5 ;0=0 delay, 1=10ms, 5=50ms - 9=90ms 108H ;default time to send character in ter- ;minal mode file transfer for slow BBS. CRDLY: DB 5 ;0=0 delay, 1=100ms, 5=500ms - 9=900ms 109H ;default time for extra wait after CRLF ;in terminal mode file transfer NOOFCOL: DB 5 ;number of DIR columns shown 10AH SETUPTST: DB YES ;yes=user-added SETUP routine 10BH SCRNTEST: DB YES ;Cursor control routine 10CH RETRY: DB YES ;yes=reset the error limit to try again 10DH ;no=abort after 10 consecutive errors ;(ARPANET users should select yes) BAKUPBYTE: DB YES ;yes=change any file same name to .BAK 10EH CRCDFLT: DB YES ;yes=default to CRC checking 10FH TOGGLECRC: DB YES ;yes=allow toggling of CRC to Checksum 110H CONVRUB: DB NO ;yes=convert rub to backspace 111H TOGGLERUB: DB YES ;yes=allow toggling of rub to backspace 112H ADDLF: DB NO ;no=no LF after CR to send file in 113H ;terminal mode (added by remote echo) TOGGLELF: DB YES ;yes=allow toggling of LF after CR 114H TRANLOGON: DB YES ;yes=allow transmission of logon 115H ;write logon sequence at location LOGON SAVCCP: DB NO ;yes=do not overwrite CCP 116H LOCONEXTCHR: DB NO ;yes=local command if EXTCHR precedes 117H ;no=external command if EXTCHR precedes TOGGLELOC: DB YES ;yes=allow toggling of LOCONEXTCHR 118H LSTTST: DB YES ;yes=printer available on printer port 119H XOFFTST: DB NO ;yes=checks for XOFF from remote while 11AH ;sending a file in terminal mode XONWAIT: DB NO ;yes=wait for XON after CR while 11BH ;sending a file in terminal mode TOGXOFF: DB YES ;yes=allow toggling of XOFF checking 11CH IGNORCTL: DB NO ;yes=CTL-chars above ^M not displayed 11DH TPMFLG: DB NO ;set by the program, always no here 11EH VALFLG: DB NO ;set by the program, always no here 11FH BRKCHR: DB 'B'-40H ;^B = Send 300 ms. break tone 120H ;(CP/M A & B don't permit CONTROL-@) NOCONNCT: 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 TRANCHR: DB 'T'-40H ;^T = Transmit file to remote 125H SAVECHR: DB 'Y'-40H ;^Y = Open input text buffer 126H EXTCHR: DB 'Z'-40H ;^Z = Send next character 127H ;(CP/M A doesn't permit CONTROL-^ while ;..CP/M B requires SHIFT CONTROL-^ to get ;..the character, so we standardized with this) DS 2 ; 128H ;..... ; Handles in/out ports for data and status: ; IN$MODCTL1: IN MODCTL1 ! RET ;in modem control port 12AH ;INITMOD makes this a jump to SYSI$STAT ;when run under VALDOCS DS 7 ;spares OUT$MODDATP: OUT MODDATP ! RET ;out modem data port 134H ;INITMOD makes this a jump to SYSI$OUT ;when run under VALDOCS DS 7 ;spares IN$MODDATP: IN MODDATP ! RET ;in modem data port 13EH ;INITMOD makes this a jump to SYSI$IN ;when run under VALDOCS DS 7 ;spares ANI$MODRCVB: ANI MODRCVB ! RET ;bit to test for receive ready 148H CPI$MODRCVR: CPI MODRCVR ! RET ;value of rcv. bit when ready 14BH ANI$MODSNDB: ANI MODSNDB ! RET ;bit to test for send ready 14EH CPI$MODSNDR: CPI MODSNDR ! RET ;value of send bit when ready 151H DS 6 ;bypasses PMMI routines 156H ; OUT$MODCTL1: RET ! NOP ! NOP ;out modem control port #1 15AH OUT$MODCTL2: RET ! NOP ! NOP ;out modem control port #2 15DH ; LOGONPTR: DW LOGON ;for user message. 160H DS 3 ;do not change 162H JMP$DISCONNT: RET ! NOP ! NOP ;not needed with QX-10/Smartmdm 165H JMP$GOODBYE: JMP GOODBYE ; 168H JMP$INITMOD: JMP INITMOD ;go to user written routine 16BH RET ! NOP ! NOP ;(by-passes PMMI routine) 16EH RET ! NOP ! NOP ;(by-passes PMMI routine) 171H RET ! NOP ! NOP ;(by-passes PMMI routine) 174H JMP$SETUPR: JMP SETUPR ; 177H JMP$SPCLMENU: JMP SPCLMENU ; 17AH JMP$SYSVER: JMP SYSVER ; 17DH JMP$BREAK: JMP SENDBRK ;INITMOD makes this a 180H ;jump to SYSI$BREAK when run ;under VALDOCS ; Do not change the following six lines. They go to specific locations in the ; main program, not the overlay. ; JMP$ILPRT: DS 3 ; 183H JMP$INBUF: DS 3 ; 186H JMP$INLNCOMP: DS 3 ; 189H JMP$INMODEM: DS 3 ; 18CH JMP$NXTSCRN: DS 3 ; 18FH JMP$TIMER: DS 3 ; 192H ;..... ; Routine to clear to end of screen. If using CLREOS and CLRSCRN, set ; SCRNTEST to YES at 010CH (above). Room allowed for four bytes. Last zero ; needed for stopping the string display. Any extra zeros just act as NOPs. ; CLREOS: CALL JMP$ILPRT ; 195H DB ESC,059H,0,0,0 ;Hex code for ESC Y 198H RET ; 19DH ; CLRSCRN: CALL JMP$ILPRT ; 19EH DB 01AH,0,0,0,0 ;Hex for Control Z 1A1H RET ; 1A6H ;..... ; NOTE: You can change the SYSVER and LOGON messages to be longer or ; shorter. The following overlay routines must terminate before 0400H. ; SYSVER: CALL CPMMODE ;Set CP/M emulation mode 1A7H CALL CLRSCRN ; CALL JMP$ILPRT ; DB ESC,3DH,2AH,3DH,'WELCOME TO QX-MODEM' DB ESC,3DH,2CH,3DH,'For the Epson QX-10' DB ESC,3DH,2EH,3FH,0 RET ;..... ; You can put a message at this location which will be called up with ; CTL-L if TRANLOGON has been set TRUE. In this overlay version, approximately ; 8 bytes are available for LOGON message. A common usage of this feature is ; 'FIRSTNAME;LASTNAME;PASSWORD' separated by semi-colons for use in signing ; on to remote bulletin boards with only one keystroke. The logon capability ; has lost much of its importance with the addition of function keys to the ; program. The length of this overlay has left little room for the logon ; sequence. End with a 0. ; LOGON: DB 'Hello',CR,LF,0 ;..... ; Sets DTR low for 300ms ; GOODBYE: MVI A,5 ;point to register 5 OUT MODCTL1 LDA TXBYT ;fetch the most recent TXBYT sent ANI 7FH ;set the DTR bit low ; GOODBYE1: OUT MODCTL1 ;send it MVI B,3 ;delay 300ms CALL JMP$TIMER MVI A,5 ;point to register 5 OUT MODCTL1 LDA TXBYT ;restore previous condition by sending OUT MODCTL1 ;..the original TXBYT RET ;..... ; This is a continuation of BYEBYE from end of overlay. ; BYEBYE1: RZ ;if CP/M, back to main program LDA VALFLG ;if not CP/M, is it VALDOCS? ORA A CZ TPMMSG ;no? then print TPM CNZ VALMSG ;if yes, then VALDOCS RET ;back to main program ;..... ; The following SENDBRK routine sends a break tone to reset some time-share ; computers, such as BRS After Dark and Dialog's Knowledge Index. However, it ; will usually cause an immediate disconnect when on line with an RBBS/RCPM ; system. This routine is automatically replaced by SYSI$BREAK if run under ; VALDOCS. ; SENDBRK: MVI A,5 ;point to register 5 OUT MODCTL1 LDA TXBYT ;get TXBYT currently in use ORI 10H ;turn sendbreak bit on JMP GOODBYE1 ;..... ; This routine shuttles from TPM to CP/M ; CPMMODE: LXI D,0CCCCH ;Put request for CP/M in D reg BDOSMODE: MVI C,12 JMP 5 ;...... ; This routine sets the CLOCK equate for computations at the very beginning of ; the main program. ; CLOCKSET: LXI H,0 ;Set HL to 0 since these three bytes ;were stolen from main program START ;subroutine CALL CPMMODE ;get system version MOV A,E CPI 'T' ;is this CP/M? RNZ ;if CP/M, quit here MVI A,YES ;store flag saying TPM in use STA TPMFLG LXI D,0 CALL BACKDOOR ;if VALDOCS SYSINIT module is not ;loaded, returns 0FFH in A register INR A RZ ;If no SYSINIT, quit here MVI A,YES ;tell flag that VALDOCS is loaded STA VALFLG MVI A,2 ;Replace clock value with this to STA CLOCK ;..reduce apparent speed for overhead ;..calls if using VALDOCS RET ;..... ; This routine checks to see what system the program is running under. It ; announces it at signon and, if VALDOCS SYSINIT module is loaded, it rewrites ; code to direct the use of backdoor subroutines needed by VALDOCS. ; INITMOD: CALL JMP$ILPRT DB '[ Using ',0 LDA TPMFLG ;is this CP/M or TPM? ORA A PUSH PSW CZ CPMMSG ;if CP/M, go get message POP PSW JZ NOSYSINIT ;..and go back to work LDA VALFLG ;we're this far, must be TPM or VALDOCS ORA A ;which is it? PUSH PSW CZ TPMMSG ;if TPM, go get message POP PSW JZ NOSYSINIT ;..and then skip ahead CALL VALMSG ;now this far, must be VALDOCS MVI A,0C3H ;Mod modem I/O to use BACKDOOR routines STA IN$MODCTL1 STA OUT$MODDATP STA IN$MODDATP LXI H,SYSI$STAT SHLD IN$MODCTL1+1 LXI H,SYSI$OUT SHLD OUT$MODDATP+1 LXI H,SYSI$IN SHLD IN$MODDATP+1 LXI H,SYSI$BREAK SHLD JMP$BREAK+1 MVI A,2 STA ANI$MODSNDB+1 STA CPI$MODSNDR+1 MVI A,11H ;load op code for LXI D and then store STA SPEED4 ;..speed to insure correct... LXI H,1275 ;..timing is used under VALDOCS... SHLD SPEED4+1 ;..for ^T text transfers MVI A,0 ;put NOP to fill STA SPEED4+3 LXI D,4FFH ;Re-enable BACKDOOR interrupt stuff CALL BACKDOOR ;..... ; If SYSINIT was not loaded, program comes here to see if carrier is present ; (DCD active), and then reset the modem if not. ; NOSYSINIT: CALL JMP$ILPRT ;send cursor to bottom of page DB ESC,3DH,36H,20H,0 MVI A,CRAM ;point to QX-10 CMOS baud rate address DI ;disable interrupts OUT MOSADR ; IN MOSDAT ;get CMOS status byte EI ;enable interrupts ANI 0FH ;set flags & strip off all but baudrate CPI 3 ;operating at 300 baud? JNZ TEST1200 ;if not, see if 1200 LXI H,CSPDTBL+12 ;if 300, point to that speed in table NOSYSINIT1: MOV E,M ;load baudrate into D-E INX H MOV D,M XCHG ;now put it in H-L CALL FINDRATE ;tell the timer and set MSPEED flag NOSYSINIT2: CALL SIOINIT ;send out default SIO initialization CALL IN$MODCTL1 ;look at status of DCD ANI 8 ;is connection active? RNZ ;if yes, initialization already done LXI H,MDMRESET CALL SEND ;Reset the modem RET ;..... ; If baudrate set on CMOS was not 300, program comes here to see if it is 1200 ; baud. If not, a prompt is called to allow user to set either 300 or 1200. ; The Smartmodem can only be addressed at those two speeds. ; TEST1200: CPI 5 ;is it 1200 baud? PUSH PSW ;save the flags CNZ AGAIN ;if not, means we weren't at 300 or ;1200, so get a SET prompt to fix. POP PSW ;bring flags back JNZ NOSYSINIT2 ;continue with new speed from prompt LXI H,CSPDTBL+20 ;was 1200, so point to 1200 in table JMP NOSYSINIT1 ;back to work ;..... ; This series of bytes initialize the Smartmodem, and are taken from the ; owner's manual. ; MDMRESET: DB 'ATE1M1Q0V1S0=0S11=55',CR,0 ;E1=set switch 4, echo on in local cmd ;M1=speaker on til carrier detect ;Q0=set switch 3, result codes sent ;V1=set switch 2, word result codes ;S0=0=set switch 5, mdm will not answer ;S11=55=touchtone dial speed ;CR,0=send it. Must end with a zero ; CPMMSG: CALL JMP$ILPRT DB 'CP/M ]',0 RET ; TPMMSG: CALL JMP$ILPRT DB 'TPM ]',0 RET ; VALMSG: CALL JMP$ILPRT DB 'VALDOCS ]',0 RET ;..... ; This subroutine is used in place of SENDBRK when running under VALDOCS ; SYSI$BREAK: PUSH D LXI D,07FFH ;send break CALL BACKDOOR MVI B,3 ;wait 300ms CALL JMP$TIMER LXI D,0700H ;turn sendbreak off CALL BACKDOOR POP D RET ;..... ; This subroutine is called in place of IN MODCTL1 when running under VALDOCS ; SYSI$STAT: PUSH D MVI D,3 ;Get SYSINIT serial port status byte ;and return it in the A register CALL BACKDOOR POP D RET ; ;..... ; This subroutine is called in place of OUT MODDATP when running under VALDOCS ; SYSI$OUT: PUSH D PUSH PSW MOV E,A ;get char to send from A and move to E MVI D,2 ;send it CALL BACKDOOR POP PSW POP D RET ; ;...... ; This subroutine is called in place of IN MODDATP when running under VALDOCS ; SYSI$IN: PUSH D MVI D,1 ;receive a character, put it in A CALL BACKDOOR POP D RET ;..... ; This back door subroutine (BDS03) provides support for the B side of ; the 7201 MPSCC, otherwise known as the "serial port", when using VALDOCS. ; BACKDOOR: PUSH H ;Save unused registers PUSH B PUSH D ;Save BACKDOOR call arguments LXI D,0AAAAH ;Set TPM mode CALL BDOSMODE POP D ;Get back BACKDOOR arguments LXI B,(3 SHL 8)+40 ;Function codes for BACKDOOR serial ;routines, 3 (BDS03) in the B reg ;and 40 in the C reg. CALL 5 ;Call TPM PUSH PSW ;Save result of BACKDOOR call CALL CPMMODE ;Go back into CP/M mode POP PSW ;Restore BACKDOOR result POP B ;Restore registers POP H RET ;..... ; Sends out the serial I/O initialization ; SIOINIT: PUSH H MVI C,MODCTL1 ;modem control port MVI B,MINLEN ;length of modem init table LXI H,MINTBL ;point to init table DB 0EDH,0B3H ;sneak in Z80 op code to OTIR the init ;table POP H RET ;..... ; Modem initialization table. Default settings: 8 bit words, no parity, 1 stop ; bit, transmit and receive enabled. ; MINTBL: DB 4 ;point to register 4 PARBYT: DB 44H ;the parity byte DB 3 ;point to register 3 RXBYT: DB 0C1H ;the receive byte DB 5 ;point to register 5 TXBYT: DB 0EAH ;the transmit byte MINLEN: EQU $-MINTBL ; EVNPAR: LXI B,0FC03H SETPAR: LDA PARBYT ANA B ORA C STA PARBYT SETPXX: CALL SIOINIT JMP GDLUP ;go back for another parameter ; ODDPAR: LXI B,0FC01H JMP SETPAR ; NOPAR: LXI B,0FC00H JMP SETPAR ; ONESTOP: LXI B,0F304H JMP SETPAR ; TWOSTOP: LXI B,0F30CH JMP SETPAR ; BIT7: MVI A,7FH ;load mask in A STA GRAFMASK ;store it in main program TERML routine MVI A,41H STA RXBYT MVI A,0AAH BIT7XX: STA TXBYT JMP SETPXX ; GRAFON: MVI A,0FFH ;load mask in A STA GRAFMASK ;store it at TERML, lets 7th bit pass JMP BIT8 ; GRAFOFF: MVI A,7FH ;load mask in A STA GRAFMASK ;store it at TERML, stops 7th bit BIT8: MVI A,0C1H STA RXBYT MVI A,0EAH JMP BIT7XX ;..... ; Make modem's speed flag match QX-10's ; SETMSPEED: MVI A,CRAM ;point to baudrate address DI ;stop interrupts OUT MOSADR IN MOSDAT ;get status byte EI ;ok to interrupt now ANI 0FH ;strip all but baudrate, set flags LXI H,MSPDTBL ;load HL with table address ADD L ;make the conversion MOV L,A ; JNC SETMSPD2 ;carry? if not, jump INR H ;if yes, increment MSB of pointer ; SETMSPD2: MOV A,M ;move table value to register A STA MSPEED ;store it at MSPEED RET ; ;..... ; This table gives MSPEED values for QX-10 CMOS baud rate values. ; Note that lower rates do not match and approximations are used. ; MSPDTBL: DB 0,0,0,1,3,5,6,7,8,2 ; TBLADR: DW 0 ; ;****************************************************************************** ; NOTE: All above overlay routines must end before 0400H ;****************************************************************************** ; ORG PMMIMENU ;pop over to second patch area ;(overlays PMMI special menu) ;..... ; Clock speed table. This gives the timer chip divisors for each baud rate. ; Must be in same order as MSPDTBL. ; CSPDTBL: DW 110,1135 ; 0 DW 135,924 ; 1 DW 150,832 ; 2 DW 300,416 ; 3 DW 600,208 ; 4 DW 1200,104 ; 5 DW 2400,52 ; 6 DW 4800,26 ; 7 DW 9600,13 ; 8 DW 450,277 ; 9 ; NXTARG: CALL SCNTOB RC ; SCNNB: LDAX D CPI ' ' RNZ INX D DCR B JNZ SCNNB STC RET ; SCNTOB: LDAX D CPI ' ' RZ RC INX D DCR B JNZ SCNTOB STC RET ; KEYBUF: DB 10 DB 0,0,0,0,0,0 DB 0,0,0,0,0,0 ;..... ; Send a string to the Smartmodem ; SEND: MOV A,M ;Get a character INX H ORA A ;End of the string? RZ MOV C,A ;No, send it CALL PUT CALL JMP$INMODEM ;Eat echo JMP SEND ; PUT: CALL IN$MODCTL1 ;Get modem status CALL ANI$MODSNDB ;Test send bits CALL CPI$MODSNDR JNZ PUT MOV A,C JMP OUT$MODDATP ;..... ; The following routine changes the baud rate, parity and word length for ; the QX-10 from the SET menu. ; SETUPR: LDAX D ;Look at passed-in byte count CPI 5 ;Enuf for possible baud rate? JC AGAIN ;No, prompt for one MOV B,A ;Save byte count INX D ;Point to first byte CALL NXTARG ;Skip to next argument MOV A,B JNC SETUP1 ; AGAIN: CALL JMP$ILPRT DB 'Enter Baud Rate and/or Options: ',0 LXI D,KEYBUF CALL JMP$INBUF ;read baud rate from console LXI D,KEYBUF+1 LDAX D INX D ; SETUP1: MOV L,A ;Force null at end of buffer MVI H,0 DAD D MVI M,0 LXI H,0 ; GDLUP: LDAX D INX D ORA A JZ GDONE CPI ' ' ;Ignore spaces JZ GDLUP SUI '0' ;Try for digit JC BADRATE CPI 10 JNC BADRATE MOV B,H MOV C,L DAD H DAD H DAD B DAD H MVI B,0 MOV C,A DAD B JMP GDLUP ; BADRATE: ADI '0' ;Fix bias from conversion routine CPI 'E' ;Check option letters for JZ EVNPAR ;Even parity CPI 'O' JZ ODDPAR ;Odd parity CPI 'N' JZ NOPAR ;No parity CPI 'S' JZ ONESTOP ;One stop bit CPI 'T' JZ TWOSTOP ;Two stop bits CPI 'A' JZ BIT7 ;ASCII mode (7 data bits) CPI 'B' JZ GRAFOFF ;Binary mode (8 data bits) with 7th bit ;masked CPI 'G' JZ GRAFON ;8 data bits, but with no masking to ;permit use of QX-10 graphics in ;terminal mode CALL JMP$ILPRT ;Anything else gets error DB CR,LF,'[ Invalid rate ]',CR,LF,0 JMP AGAIN ; GDONE: MOV A,H ORA L JZ QUIT ;..... ; Enter here with baud rate in HL to set baud rate of timer. ; FINDRATE: PUSH H ;save baud rate LXI H,CSPDTBL ;load table address SHLD TBLADR ;store it there POP H ;get baud back LXI B,0A00H ; CLP: PUSH H LHLD TBLADR ;get address back MOV E,M ;move value to E INX H ;advance pointer MOV D,M ;other half in D INX H XTHL XCHG ;switch ORA A ;prepare for true subtract by clearing DB 0EDH,52H ;sneak in Z80 op code to SBC HL,DE XCHG ;switch again XTHL JZ DOIT INX H INX H SHLD TBLADR POP H INR C DCR B JNZ CLP JMP BADRATE ; DOIT: POP D MVI A,0B6H OUT TPORTS MOV A,M INX H OUT TPORTC MOV A,M OUT TPORTC CALL IN$MODDATP CALL IN$MODDATP MVI A,CRAM DI ;Disable interrupts OUT MOSADR MOV A,C OUT MOSDAT EI ;Enable interrupts ; QUIT: JMP SETMSPEED ;..... ; This special menu is unavailable without putting the actual address of ; SPCLMENU (in the basic program) in the overlay above at the PMMIMENU equate. ; SPCLMENU: CALL JMP$NXTSCRN CALL JMP$ILPRT DB ' Additional SET options for QX-10',cr,lf,lf DB ' Parity:',cr,lf DB ' E - Even',cr,lf DB ' O - Odd',cr,lf DB ' N - None',cr,lf,lf DB ' Stop bits:',cr,lf DB ' S - Single (1)',cr,lf DB ' T - Two (2)',cr,lf,lf DB ' Data bits (word length):',cr,lf DB ' A - ASCII mode (7 data bits)',cr,lf DB ' B - Binary mode (8 data bits)',cr,lf DB ' G - Graphics mode (8 data bits, no masking)' DB CR,LF,LF DB ' Examples:',cr,lf DB ' SET 300ETA',cr,lf DB ' SET B',cr,lf DB ' SET NSG 1200',cr,lf DB 0 RET ; ;****************************************************************************** ; NOTE: THE ABOVE MUST TERMINATE PRIOR TO 0CBB FOR MDM730 THRU MDM740. ;****************************************************************************** ; ;..... ; This routine modifies the basic program to call CLOCKSET before timing rates ; are computed. The overlayed bytes (LXI H,0) are placed at the beginning ; of CLOCKSET. ; ORG START CALL CLOCKSET ;..... ; This subroutine overlays BYEBYE of basic program to add capability of send- ; ing correct signoff messages as program exits through BYE command. ; ORG BYEBYE+20 DB CR,LF,'[ Exit to ',0 LDA TPMFLG ;is this CP/M or TPM? ORA A CZ CPMMSG ;if CP/M, go get message CALL BYEBYE1 ;go continue this ; END ;