* PROGRAM NAME: SUPPORT PACKAGE * AUTHOR: RICHARD CONN * DATE: 15 JAN 82 (W6BSK) * VERSION: 1.6 * PREVIOUS VERSIONS: 1.5 (26 JUN 81), 1.3 (18 APR 81), 1.4 (20 MAY 81) * 1.2 (21 MAR 81), 1.1 (04 MAR 81), 1.0 (01 JAN 81) VERS equ 15 ; Version Number * THE FOLLOWING EQUATE SHOULD BE CHANGED IF YOU HAVE A NON-STANDARD CP/M CPM$BASE EQU 0 ; BASE ADDRESS OF CP/M SYSTEM BDOS EQU CPM$BASE+5 FALSE equ 0 ; Define FALSE TRUE equ NOT FALSE * HOST PROGRAM SELECTION TERM EQU TRUE TERMBLS EQU FALSE XTERM EQU FALSE PHONECOM EQU FALSE INTERSYS EQU FALSE PRINT EQU FALSE * BASE ADDRESS SELECTION IF TERM BASE EQU 5100H ENDIF IF TERMBLS BASE EQU 2100H ENDIF IF PRINT BASE EQU 0E00H ENDIF IF PHONECOM BASE EQU 1200H ENDIF IF INTERSYS BASE EQU 0600H ENDIF IF XTERM BASE EQU 1000H ENDIF TI$REQUIRED EQU (TERM OR PHONECOM OR TERMBLS) ; TI REQUIRED FLAG A1$REQUIRED EQU XTERM ; A1 REQUIRED FLAG ************************************************************************* * * * **** Support Package **** * * * * SUPPORT.ASM, the Support Package Source File, is a group of * * machine-dependent subroutines which implement a number of functions * * beyond those implemented in the CP/M BIOS. The Support Package, * * hereafter referred to as SP, contains the routines necessary to * * interface with specific types of hardware for special applications * * with various mainline programs. The SP provides a machine-independ- * * ent interface with these machine-dependent routines. * * Like the CP/M BIOS, SP provides this interface via a JMP table * * at the beginning of the SP. The entries in this JMP table are * * ordered and precisely defined so that all SP's interface with the * * calling mainlines in exactly the same way regardless of the machine- * * dependent hardware controlled by the SP's. * * Because of the extreme machine-dependency of the SP's, a unique * * feature of these SP's is the first routine in the JMP table. This * * routine passes back to the caller three bytes (in the A, H, and L * * registers) which tell him which functional areas of the JMP table are * * operational and which are not. For example, the standard definition * * of the SP allows for two sets of Modem support routines, and bits 2 * * and 3 of the A register returned from this routine tells the caller * * if the hardware for these modems is available and these routines are * * implemented. Say, if just Modem 1 was implemented, the A register * * would contain the following information: * * * * --------------------------------- * * | x | x | x | x | 0 | 1 | x | x | x = don't care. * * --------------------------------- * * Bit Number: 7 6 5 4 3 2 1 0 * * * * The '1' in bit number 2 says Modem 1 is enabled and the '0' in bit * * number 3 says Modem 2 is not enabled. * * To maintain consistency of interface, the JMP table entries * * for the unimplemented routines are still present in the JMP table, * * but they do not do anything other than execute a return to the caller * * with a 0 in the A register and the Zero Flag Set. * * * * This file is a version of the Support Package as implemented * * with the following features: * * 1. CRT Screen Routines programmed for the VIO/C * * 2. TTY Routines programmed for the Teletype Model 43 * * 3. Modem 1 Routines programmed for the DCHayes * * 4. Modem 2 Routines programmed for a serial port * * 5. Alternate Device 1 programmed for the DJ/2D serial * * port * * 6. Alternate Device 2 NOT IMPLEMENTED * * 7. Alternate Device 3 NOT IMPLEMENTED * * 8. Telephone System Routines programmed for the * * DCHayes S100 Micromodem board. * * * ************************************************************************* Š * * **** Support Package JMP Table **** * ORG BASE ; BASE OF SUPPORT PACKAGE * Entry 0: Standard Support Package Routines JMP SP$STAT ; +000 SUPPORT PACKAGE STATUS ROUTINE JMP SP$END ; +003 SUPPORT PACKAGE LAST ADDRESS ROUTINE * Entry Point for Non-Implemented Routines NI: JMP SP$ERR ; +006 SUPPORT PACKAGE ERROR ROUTINE * Entry Point for Functions Requiring Console Output Through CP/M COUT: JMP SP$COUT ; +009 SUPPORT PACKAGE CONSOLE OUTPUT ROUTINE JMP SP$VERS ; +012 SUPPORT PACKAGE VERSION NUMBER * Entry 1: CRT Screen Routines JMP CRT$INI ; +015 CRT INITIALIZATION JMP CRT$FGND ; +018 CRT TO FOREGROUND JMP CRT$BGND ; +021 CRT TO BACKGROUND JMP CRT$CLS ; +024 CLEAR SCREEN ROUTINE JMP CRT$GXY ; +027 GOTO XY ROUTINE * Entry 2: TTY Routines JMP TT$INI ; +030 TTY INITIALIZATION JMP TT$ISTAT ; +033 TTY INPUT STATUS JMP TT$OSTAT ; +036 TTY OUTPUT STATUS JMP TT$IN ; +039 TTY INPUT ROUTINE JMP TT$OUT ; +042 TTY OUTPUT ROUTINE * Entry 3: Modem 1 Routines IF TI$REQUIRED ; IF M1 REQUIRED, THEN ... JMP M1$INI ; +045 MODEM 1 INITIALIZATION JMP M1$ISTAT ; +048 MODEM 1 INPUT STATUS JMP M1$OSTAT ; +051 MODEM 1 OUTPUT STATUS JMP M1$IN ; +054 MODEM 1 INPUT ROUTINE JMP M1$OUT ; +057 MODEM 1 OUTPUT ROUTINE JMP M1$BREAK ; +060 MODEM 1 BREAK ROUTINE ENDIF IF NOT TI$REQUIRED ; ELSE ... JMP NI JMP NI JMP NI JMP NI JMP NI JMP NI ENDIF * Entry 4: Modem 2 Routines JMP M2$INI ; +063 MODEM 2 INITIALIZATION JMP M2$ISTAT ; +066 MODEM 2 INPUT STATUS JMP M2$OSTAT ; +069 MODEM 2 OUTPUT STATUS JMP M2$IN ; +072 MODEM 2 INPUT JMP M2$OUT ; +075 MODEM 2 OUTPUT JMP M2$BREAK ; +078 MODEM 2 BREAK Š * Entry 5: Alternate 1 Routines IF A1$REQUIRED ; IF ALTERNATE 1 IS REQUIRED, THEN ... JMP A1$INI ; +081 ALTERNATE 1 INIT JMP A1$ISTAT ; +084 ALTERNATE 1 INPUT STATUS JMP A1$OSTAT ; +087 ALTERNATE 1 OUTPUT STATUS JMP A1$IN ; +090 ALTERNATE 1 INPUT JMP A1$OUT ; +093 ALTERNATE 1 OUTPUT ENDIF IF NOT A1$REQUIRED ; ELSE ... JMP NI JMP NI JMP NI JMP NI JMP NI ENDIF * Entry 6: Alternate 2 Routines JMP NI ; +096 JMP NI ; +099 JMP NI ; +102 JMP NI ; +105 JMP NI ; +108 * Entry 7: Alternate 3 Routines JMP NI ; +111 JMP NI ; +114 JMP NI ; +117 JMP NI ; +120 JMP NI ; +123 * Entry 8: Telephone System Interface Routines IF TI$REQUIRED ; IF TELEPHONE INTEFACE IS REQUIRED, THEN ... JMP TI$INI ; +126 INITIALIZATION JMP TI$ORG ; +129 SET ORIGINATE MODE JMP TI$ANS ; +132 SET ANSWER MODE JMP TI$PICK ; +135 PICK UP PHONE JMP TI$HANG ; +138 HANG UP PHONE JMP TI$WDT ; +141 WAIT UP TO 15 SECS FOR DIAL TONE JMP TI$WANS ; +144 WAIT UP TO 15 SECS FOR ANSWER JMP TI$RST ; +147 RING STATUS DETECT JMP TI$DST ; +150 DIAL TONE STATUS DETECT JMP TI$CST ; +153 CARRIER STATUS DETECT JMP TI$DSTRT ; +156 START DIALING JMP TI$DSTOP ; +159 STOP DIALING JMP TI$DIGIT ; +162 DIAL DIGIT JMP T100MS ; +165 0.1 SEC DELAY ROUTINE JMP TI$PREPANS ; +168 PREPARE FOR ANSWERING PHONE ENDIF IF NOT TI$REQUIRED ; ELSE ... JMP NI JMP NI JMP NI Š JMP NI JMP NI JMP NI JMP NI JMP NI JMP NI JMP NI JMP NI JMP NI JMP NI JMP NI JMP NI ENDIF * * STATUS TABLE -- This table contains the return status info * USER CUSTOMIZED! * STABLE: * A REG DB 0000$0001B ; ENABLE CRT DB 0000$0010B ; ENABLE TTY IF TI$REQUIRED ; ENABLE MODEM 1 IF REQUIRED DB 0000$0100B ; ENABLE MODEM 1 ENDIF IF NOT TI$REQUIRED DB 0000$0000B ; DISABLE MODEM 1 ENDIF DB 0000$1000B ; ENABLE MODEM 2 IF A1$REQUIRED ; ENABLE ALTERNATE 1 IF REQUIRED DB 0001$0000B ; ENABLE ALTERNATE 1 ENDIF IF NOT A1$REQUIRED DB 0000$0000B ; DISABLE ALTERNATE 1 ENDIF DB 0000$0000B ; DISABLE ALTERNATE 2 DB 0000$0000B ; DISABLE ALTERNATE 3 IF TI$REQUIRED ; ENABLE TELEPHONE INTERFACE IF REQUIRED DB 1000$0000B ; ENABLE TELEPHONE SYSTEM INTERFACE ENDIF IF NOT TI$REQUIRED DB 0000$0000B ; DISABLE TELEPHONE SYSTEM INTERFACE ENDIF * H REG DB 0000$0000B ; NI DB 0000$0000B DB 0000$0000B DB 0000$0000B DB 0000$0000B Š DB 0000$0000B DB 0000$0000B DB 0000$0000B * L REG DB 0000$0000B ; NI DB 0000$0000B DB 0000$0000B DB 0000$0000B DB 0000$0000B DB 0000$0000B DB 0000$0000B DB 0000$0000B * * **** End of Support Package JMP Table **** * * * Standard Support Package Routines * * * STATUS ROUTINE * THIS ROUTINE RETURNS THE STATUS OF THE LOGICAL SECTIONS OF THE SP * IN THE A REGISTER AND THE HL REGISTER PAIR * Input Parameters: None * Output Parameters: A, H, L = Status bytes (resp) * SP$STAT: PUSH B ; SAVE BC LXI H,STABLE ; STATUS TABLE CALL STAT ; LOAD 8 BITS INTO A PUSH PSW ; SAVE A CALL STAT ; LOAD 8 BITS INTO A PUSH PSW ; SAVE A CALL STAT ; LOAD 8 BITS INTO A MOV L,A ; L ENTRY POP PSW ; GET A MOV H,A ; H ENTRY POP PSW ; A ENTRY POP B ; RESTORE BC RET STAT: MVI B,8 ; 8 BITS XRA A ; A=0 STATL: ORA M ; MASK IN STATUS BIT INX H ; PT TO NEXT BYTE DCR B ; COUNT DOWN JNZ STATL ; CONTINUE IF NOT DONE RET * * END ROUTINE * THIS ROUTINE RETURNS THE END ADDRESS OF THE SUPPORT PACKAGE IN HL; * THIS ADDRESS IS THE ADDRESS OF THE PAGE IMMEDIATELY FOLLOWING THE SUPPORT * PACKAGE * Input Parameters: None * Output Parameters: HL = Address of next page after Support Package * SP$END: LXI H,ENDALL ; GET ADDRESS OF LAST BYTE IN PACKAGE MVI L,0 ; ROUND TO NEXT PAGE BOUNDARY INR H RET Š* * ERROR ROUTINE AND RETURN FOR NON-IMPLEMENTED ROUTINES * THIS ROUTINE ZEROES THE A REG AND SETS THE ZERO FLAG TO INDICATE NOT * IMPLEMENTED OR ERROR * Input Parameters: None * Output Parameters: A=0 and Zero Flag is Set * SP$ERR: XRA A ; A=0 AND ZERO FLAG SET RET * * CONSOLE INPUT ROUTINE * THIS ROUTINE INPUTS A CHAR IN THE A REGISTER FROM THE CP/M CONSOLE * DEVICE; ONLY PSW AFFECTED * Input Parameters: None * Output Parameters: A=Char * SP$CIN: PUSH H ; SAVE ALL REGS PUSH D PUSH B MVI C,1 ; CON: INPUT CALL BDOS ; CALL BDOS POP B ; RESTORE ALL REGS POP D POP H RET * * CONSOLE OUTPUT ROUTINE * THIS ROUTINE SENDS THE CHAR IN THE A REGISTER TO THE CP/M CONSOLE * DEVICE; NO REGISTERS ARE AFFECTED * Input Parameters: A=character to output * Output Parameters: None * SP$COUT: PUSH H ; SAVE ALL REGS PUSH D PUSH B PUSH PSW MVI C,2 ; CON: OUTPUT MOV E,A ; CHAR IN E CALL BDOS ; CALL BDOS POP PSW ; RESTORE ALL REGS POP B POP D POP H RET Š* * PRINT MESSAGE PTED TO BY RETURN ADDRESS; MESSAGE ENDS IN A ZERO * EXAMPLE OF USE: * CALL PRINT$MESSAGE * DB 'This is a test',0DH,0AH,0 * [ Rest of Code ] * NO REGISTERS ARE AFFECTED * PRINT$MESSAGE: XTHL ; GET RET ADR AND SAVE HL PUSH PSW ; SAVE PSW PM$LOOP: MOV A,M ; GET NEXT CHAR INX H ; PT TO NEXT CHAR ORA A ; 0=DONE JZ PM$DONE CALL SP$COUT ; PRINT CHAR JMP PM$LOOP PM$DONE: POP PSW ; RESTORE PSW XTHL ; PLACE RETURN ADDRESS AND RESTORE HL RET * * SUPPORT PACKAGE VERSION NUMBER * RETURN THE VERSION NUMBER OF THE SUPPORT PACKAGE IN THE A REG * NO OTHER REGISTERS ARE AFFECTED * SP$VERS: MVI A,VERS ; GET VERSION NUMBER RET * * End of Standard Support Package Routines * * * ENTRY 1: CRT Screen Routines * ... as implemented for IMSAI VIO/C board. * SWVIDEO equ 16H ;Reverse video command. ESCAPE equ 1BH ;Escape character and EQUALS equ 3DH ;Equal value for VIO/c. * * CRT Initialization * Function: To initialize the CRT * Input Parameters: None * Output Parameters: None * CRT$INI: PUSH PSW ; SAVE A CALL 0F800H ; Initialize system POP PSW ; RESTORE A CALL PRINT$MESSAGE DB 0DH,0AH,'** VIO/C initialized- **',0DH,0AH,0 RET * * CRT Foreground * Function: To set the CRT to Foreground Intensity * Input Parameters: None * Output Parameters: None * CRT$FGND: PUSH PSW ; SAVE A MVI A,ESCAPE CALL COUT MVI A,SWVIDEO ; SET FOREGROUND CALL COUT CALL CRT$PAUSE ; DELAY POP PSW RET * * CRT Background * Function: To set the CRT to Background Intensity * Input Parameters: None * Output Parameters: None * CRT$BGND: PUSH PSW ; SAVE A MVI A,ESCAPE ; SET BACKGROUND CALL COUT MVI A,SWVIDEO CALL COUT CALL CRT$PAUSE ; DELAY POP PSW RET Š * * CRT Clear Screen Routine * Function: To Clear the CRT Screen * Input Parameters: None * Output Parameters: None * CRT$CLS: PUSH PSW ; SAVE A MVI A,1AH ; CLEAR SCREEN CALL COUT CALL CRT$PAUSE POP PSW RET * PAUSE FOR CRT RESPONSE CRT$PAUSE: RET * * CRT GOTOXY Routine : MODIFIED for VIO/C * Function: Position cursor at XY coordinate on CRT Screen * Input Parameters: H=Row Number (1-24), L=Column Number (1-80); * H,L = 20 is upper left, but input is (1,1). * Also note row and columns must be interchanged. * Output Parameters: None * CRT$GXY: PUSH H ; SAVE REGS PUSH PSW PUSH B LXI B,2020H DAD B ; CONVERT TO VIO/C MVI A,ESCAPE ; CURSOR POSITIONING CALL COUT MVI A,EQUALS CALL COUT MOV A,L ; COLUMN CALL COUT MOV A,H ; ROW ADI ' '-1 ; ADJUST TO 0-23 CALL COUT POP B POP PSW ; RESTORE REGS POP H RET * * END of CRT Screen Routines * * * ENTRY 2: TTY Routines * ŠTTY$STAT equ 0EAH ; TTY Status Port TTY$DATA equ 0EBH ; TTY Data Port TTY$TRE equ 2 ; TRE Bit TTY$RRF equ 1 ; RRF Bit * * TTY Initialization * Function: To initialize the TTY Port * Input Parameters: None * Output Parameters: None * TT$INI: MVI A,3 ; RESET UART OUT TTY$STAT MVI A,5 ; 7 DATA, ODD PARITY, 2 STOP OUT TTY$STAT CALL PRINT$MESSAGE DB 0DH,0AH,'** TTY Initialized **',0DH,0AH,0 RET * * TTY Status * Function: To return byte ready (RRF) status * Input Parameters: None * Output Parameters: A=0 if no byte, A=0FFH if byte ready * TT$ISTAT: IN TTY$STAT ; GET STATUS BYTE ANI TTY$RRF ; DATA AVAILABLE? RZ ; ZERO IF NO DATA MVI A,0FFH ; LOAD WITH FF RET * * TTY Output Status * Function: To return buffer empty (TRE) status * Input Parameters: None * Output Parameters: A=0 if buffer full, A=0FFH if buffer empty (TRE) * TT$OSTAT: IN TTY$STAT ; GET STATUS BYTE ANI TTY$TRE ; BUFFER EMPTY? RZ ; ZERO IF NOT EMPTY MVI A,0FFH ; LOAD WITH FF RET * * TTY Input * Function: To return a byte in the A Reg from the TTY * Input Parameters: None Š* Output Parameters: A=byte (MSB NOT cleared) * TT$IN: CALL TT$ISTAT ; GET STATUS JZ TT$IN ; CONTINUE UNTIL DATA AVAILABLE IN TTY$DATA ; GET CHAR RET * * TTY Output * Function: To output the byte in the A Reg to the TTY * Input Parameters: A=byte * Output Parameters: None * TT$OUT: PUSH PSW ; SAVE BYTE TT$OUT$LOOP: CALL TT$OSTAT ; CHECK OUTPUT STATUS JZ TT$OUT$LOOP ; WAIT UNTIL EMPTY POP PSW ; GET BYTE OUT TTY$DATA ; OUTPUT IT RET * * END of TTY Routine * * ENTRY 3: Modem 1 Routines * * Modified for DCHayes S100 Modem * * Enable Modem 1 if TI Required IF TI$REQUIRED ; IF REQUIRED, THEN ... DCHS$DATA equ 080H ; DCHS Data Port DCHS$STAT equ 081H ; DCHS Status Port DCHS$CTRL equ 082H ; DCHS Control Port DCHS$TRE equ 2 ; TRANSMITTER REGISTER EMPTY DCHS$RRF equ 1 ; RECEIVE REGISTER FULL * * Modem 1 Initialization * Function: To initialize the Modem Port for Modem 1 * Input Parameters: None * Output Parameters: None * M1$INI: PUSH PSW PUSH B CALL PRINT$MESSAGE DB 0DH,0AH,'Modem 1 and Telephone Interface Baud Rate Selection' DB 0DH,0AH,' Select Baud Rate: 1=300 Baud, 2=110 Baud' DB 0DH,0AH,' Selection (1/2/=1)? ',0 CALL SP$CIN ; GET RESPONSE CPI '2' ; 110 BAUD? JZ TI$INI$B110 MVI A,B300 ; SELECT 300 BAUD DB 1 ; LXI B,XXXX INSTR TO COVER FOLLOWING MVI A,B600 TI$INI$B110: MVI A,B110 ; SELECT 110 BAUD STA BAUD POP B POP PSW JMP TI$INI ; INITIALIZE TELEPHONE INTERFACE * * Modem 1 Input Status * Function: To return byte ready (RRF) status * Input Parameters: None * Output Parameters: A=0 if no byte, A=0FFH if byte ready * M1$ISTAT: IN DCHS$STAT ; GET STATUS BYTE ANI DCHS$RRF ; DATA AVAILABLE? RZ ; ZERO IF NO DATA MVI A,0FFH ; LOAD WITH FF RET Š * * Modem 1 Output Status * Function: To return buffer empty (TRE) status * Input Parameters: None * Output Parameters: A=0 if buffer full, A=0FFH if buffer empty * M1$OSTAT: IN DCHS$STAT ; GET STATUS BYTE ANI DCHS$TRE ; BUFFER EMPTY? RZ ; ZERO IF FULL MVI A,0FFH ; LOAD WITH FF RET * * Modem 1 Input * Function: To return a byte in the A Reg from the Modem * Input Parameters: None * Output Parameters: A=byte (MSB NOT cleared) * M1$IN: CALL M1$ISTAT ; GET STATUS JZ M1$IN ; CONTINUE UNTIL DATA AVAILABLE IN DCHS$DATA ; GET BYTE RET * * Modem 1 Output * Function: To output the byte in the A Reg to the Modem * Input Parameters: A=byte * Output Parameters: None * M1$OUT: PUSH PSW ; SAVE BYTE M1$OUT$LOOP: CALL M1$OSTAT ; GET STATUS JZ M1$OUT$LOOP ; WAIT UNTIL EMPTY POP PSW ; GET BYTE OUT DCHS$DATA ; OUTPUT IT RET * * Modem 1 Break * Function: To return the status of the break function for Modem 1 * and to execute the break if function is available * Input Parameters: A=0 to return status, A=0FFH to break * Output Parameters: A=0 and Zero Flag Set if Break not supported * M1$BREAK: ORA A ; DETERMINE FUNCTION JNZ M1$BR1 M1$BR0: MVI A,0FFH ; DECLARE BREAK SUPPORTED ORA A ; SET FLAGS RET ŠM1$BR1: MVI A,0FH ; TRANSMIT BREAK OUT M1$CTRL$PORT CALL T100MS ; DELAY 0.34 SEC CALL T100MS CALL T100MS CALL T100MS ; 0.4 SEC MVI A,07H ; STOP BREAK OUT M1$CTRL$PORT CALL T100MS JMP M1$BR0 ; INDICATE BREAK SUPPORTED ENDIF ; TI$REQUIRED * * END of Modem 1 Routines * * * ENTRY 4: Modem 2 Routines * M2$STAT equ 0E8H ; Modem 2 Status Port M2$DATA equ 0E9H ; Modem 2 Data Port M2$TRE equ 2 ; TRE Bit M2$RRF equ 1 ; RRF Bit * * Modem 2 Initialization * Function: To initialize the Modem 2 Port * Input Parameters: None * Output Parameters: None * M2$INI: MVI A,3 ; RESET MODEM OUT M2$STAT MVI A,1$0001B ; 8 DATA BITS, NO PARITY, 2 STOP OUT M2$STAT CALL PRINT$MESSAGE DB 0DH,0AH,'** Modem 2 Initialized **',0DH,0AH,0 RET * * Modem 2 Input Status * Function: To return byte ready (RRF) status * Input Parameters: None * Output Parameters: A=0 if no byte, A=0FFH if byte ready * M2$ISTAT: IN M2$STAT ; GET STATUS BYTE ANI M2$RRF ; DATA AVAILABLE? RZ ; ZERO IF NO DATA MVI A,0FFH ; LOAD WITH FF RET * * Modem 2 Output Status * Function: To return buffer empty (TRE) status * Input Parameters: None * Output Parameters: A=0 if buffer full, A=0FFH if buffer empty (TRE) * M2$OSTAT: IN M2$STAT ; GET STATUS BYTE ANI M2$TRE ; TRE? RZ ; ZERO IF NOT EMPTY MVI A,0FFH ; LOAD WITH FF RET Š * * Modem 2 Input * Function: To return a byte in the A Reg from Modem 2 * Input Parameters: None * Output Parameters: A=byte (MSB NOT cleared) * M2$IN: CALL M2$ISTAT ; GET STATUS JZ M2$IN ; CONTINUE UNTIL DATA AVAILABLE IN M2$DATA ; GET CHAR RET * * Modem 2 Output * Function: To output the byte in the A Reg to Modem 2 * Input Parameters: A=byte * Output Parameters: None * M2$OUT: PUSH PSW ; SAVE BYTE M2$OUT$LOOP: CALL M2$OSTAT ; CHECK OUTPUT STATUS JZ M2$OUT$LOOP ; WAIT UNTIL EMPTY POP PSW ; GET BYTE OUT M2$DATA ; OUTPUT IT RET * * Modem 2 Break * Function: To return the status of the break function for Modem 1 * and to execute the break if function is available * Input Parameters: A=0 to return status, A=0FFH to break * Output Parameters: A=0 and Zero Flag Set if Break not supported * M2$BREAK: XRA A ; NOT SUPPORTED RET * * END of Modem 2 Routines * * * ENTRY 5: Alternate Device 1 Routines * * The routines implemented in this section are identical in nature to * the corresponding routines in the Modem sections with the lack of a Break * routine. Routines implemented are: * A1$INI, A1$ISTAT, A1$OSTAT, A1$IN, A1$OUT * * Enable Alternate 1 if Required * IF A1$REQUIRED ; IF REQUIRED, THEN ... * * The following are the I/O addresses and status bytes for the DJ/2D * board. * USTAT EQU 0E3F9H UDATA EQU 0E3F8H ISTAT EQU 4 OSTAT EQU 8 * * Alternate 1 Initialization * Function: To initialize the Alternate 1 Device * Input Parameters: None * Output Parameters: None * A1$INI: CALL PRINT$MESSAGE DB 0DH,0AH,'** Alternate 1 Initialized **',0DH,0AH,0 RET * * Alternate 1 Input Status * Function: To return byte ready (RRF) status * Input Parameters: None * Output Parameters: A=0 if no byte, A=0FFH if byte ready * A1$ISTAT: LDA USTAT ; GET STATUS BYTE CMA ; INVERT IT ANI ISTAT ; DATA AVAILABLE? RZ MVI A,0FFH ; LOAD WITH FF RET * * Alternate 1 Output Status * Function: To return buffer empty (TRE) status * Input Parameters: None * Output Parameters: A=0 if buffer full, A=0FFH if buffer empty (TRE) * ŠA1$OSTAT: LDA USTAT ; GET STATUS CMA ; INVERT IT ANI OSTAT ; TRE? RZ MVI A,0FFH ; LOAD WITH FF RET * * Alternate 1 Input * Function: To return a byte in the A Reg from Alternate 1 * Input Parameters: None * Output Parameters: A=byte (MSB NOT cleared) * A1$IN: CALL A1$ISTAT ; GET STATUS JZ A1$IN ; CONTINUE UNTIL DATA AVAILABLE LDA UDATA ; GET DATA CMA ; INVERT IT RET * * Alternate 1 Output * Function: To output the byte in the A Reg to Alternate 1 * Input Parameters: A=byte * Output Parameters: None * A1$OUT: PUSH PSW ; SAVE BYTE A1$OUT$LOOP: CALL A1$OSTAT ; CHECK OUTPUT STATUS JZ A1$OUT$LOOP ; WAIT UNTIL EMPTY POP PSW ; GET BYTE CMA ; INVERT IT STA UDATA ; OUTPUT IT CMA RET ENDIF ; ENABLE ALTERNATE 1 * * ENTRY 6: Alternate Device 2 Routines * * The routines implemented in this section are identical in nature to * the corresponding routines in the Modem sections with the lack of a Break * routine. Routines implemented are: * A2$INI, A2$ISTAT, A2$OSTAT, A2$IN, A2$OUT * * Alternate Device 2 NOT IMPLEMENTED at this time. * * * ENTRY 7: Alternate Device 3 Routines * * The routines implemented in this section are identical in nature to * the corresponding routines in the Modem sections with the lack of a Break * routine. Routines implemented are: * A3$INI, A3$ISTAT, A3$OSTAT, A3$IN, A3$OUT * * Alternate Device 3 NOT IMPLEMENTED at this time. * * * ENTRY 8: Telephone System Interface Routines * * Enable Telephone Interface if Required * IF TI$REQUIRED ; IF REQUIRED, THEN ... DATAPORT equ DCHS$DATA ; DCHS DATA PORT STATPORT equ DATAPORT+1 ; DCHS STATUS/CONTROL PORT RATEPORT equ DATAPORT+2 ; DCHS RATE GENERATOR/MODEM STATUS PORT TIMEPORT equ DATAPORT+3 ; DCHS 50 MS TIMER PORT CTRLPORT equ RATEPORT ; DCHS MODEM CONTROL PORT M1$CTRL$PORT equ CTRLPORT ; DCHS MODEM CONTROL PORT RESET equ 0 ; MODEM IDLE MODE CLEAR equ 3FH ; MODEM ANSWER IDLE MODE MAKEM equ 1 ; TELEPHONE LINE MAKE (OFF HOOK) BREKM equ 0 ; TELEPHONE LINE BREAK (ON HOOK) ORGIN equ 87H ; ORIGINATE MODE BIT ANSWR equ 81H ; ANSWER MODE BIT DTDET equ 2FH ; SWITCH MODEM FOR DIAL TONE DTMASK equ 1 ; DIAL TONE MASK BIT ANSMSK equ 10H ; ANSWER PHONE MASK BIT CTSMSK equ 4 ; CLEAR-TO-SEND MASK BIT RINGMSK equ 80H ; RING MASK BIT DTR3 equ 7FH ; DATA TERMINAL READY (300 BAUD) DTR6 equ 5FH ; DATA TERMINAL READY (600 BAUD) B110 equ 142 ; TIMER RATE FOR 110 BAUD B300 equ 52 ; TIMER RATE FOR 300 BAUD B600 equ 26 ; TIMER RATE FOR 600 BAUD D10PPS equ 250 ; TIMER DIALING RATE 0.1 SEC (10 PPS) D20PPS equ 125 ; TIMER DIALING RATE 0.05 SEC (20 PPS) TRATE equ 250 ; TIMER DELAY RATE (0.1 SEC) TMPUL equ 80H ; TIMER PULSES MASK BIT INTER equ 7 ; INTER-DIGIT TIME INTERVAL SETUART equ 0101$1100B ; 8 DATA BITS, NO PARITY, 2 STOP BITS * * Telephone Interface Buffers (Initialized Values) * BAUD: DB B300 ; BAUD RATE UART: DB SETUART ; UART SETTINGS DTRATE: DB DTR3 ; DATA TRANSMISSION RATE Š * * Telephone Interface Supporting Routines * MWAIT: IN RATEPORT ; WAIT FOR A MAKE INTERVAL ANI TMPUL JNZ MWAIT RET BWAIT: IN RATEPORT ; WAIT FOR A BREAK INTERVAL ANI TMPUL JZ BWAIT RET TIME15: ; WAIT UP TO 15 SECS FOR STATUS CHANGE IN D PUSH B ; 15 SECOND DELAY MVI C,150 ; 15 SECS TIME15$LOOP: CALL T100MS ; WAIT 0.1 SEC IN RATEPORT ; TEST STATUS ANA D ; MASK READY? JZ TIME15$DONE DCR C ; COUNT DOWN JNZ TIME15$LOOP * NO DIAL TONE XRA A ; A=0 POP B RET * DIAL TONE TIME15$DONE: MVI A,0FFH ; A=0FFH ORA A ; SET FLAGS POP B RET TIMER1: ; WAIT FOR NUMBER OF PULSES IN B CALL BWAIT CALL MWAIT DCR B ; COUNT DOWN JNZ TIMER1 RET * * Telephone Interface Initialization * Function: Initialize the Modem/UART Interface * Input Parameters: None * Output Parameters: None * TI$INI: CALL PRINT$MESSAGE DB 0DH,0AH,'** Modem 1 and Telephone Interface Initialized **' DB 0DH,0AH,0 RET Š * * Set Modem to Originate * Function: Set Modem to Originate Mode * Input Parameters: None * Output Parameters: None * TI$ORG: PUSH PSW MVI A,ORGIN ; ORIGINATE (SWITCH HOOK) OUT RATEPORT POP PSW RET * * Prepare Modem to Answer Phone * Function: To condition modem for answering phone * Input Parameters: None * Output Parameters: None * TI$PREPANS: PUSH PSW MVI A,CLEAR ; CLEAR MODEM TO IDLE OUT CTRLPORT MVI A,BREKM ; GO ON-HOOK OUT STATPORT POP PSW RET * * Set Modem to Answer * Function: Set Modem to Answer Mode * Input Parameters: None * Output Parameters: A=0 IF NOT SUCCESSFUL, A=0FFH IF SUCCESSFUL * TI$ANS: CALL T100MS ; WAIT 0.1 SEC CALL TI$RST ; STILL RINGING? JZ TI$ANSF MVI A,ANSWR ; ANSWER OUT STATPORT CALL T100MS ; WAIT 0.1 SEC MVI D,CTSMSK ; WAIT FOR CLEAR TO SEND CALL TIME15 RZ IN DATAPORT ; CLEAR UART LDA BAUD ; SET BAUD RATE OUT RATEPORT MVI A,0FFH ; SET OK ORA A ; SET FLAGS RET * FAILURE TO ANSWER TI$ANSF: XRA A ; A=0 RET Š * * Pick up telephone * Function: Place the telephone off hook * Input Parameters: None * Output Parameters: A=0 if no dial tone, A=0FFH if OK and dial tone * TI$PICK: MVI A,MAKEM ; PUT IN ORG MODE AND GO OFF HOOK OUT STATPORT JMP TI$WDT ; WAIT FOR DIAL TONE AND RET STATUS * * Hang up telephone * Function: Place the telephone on hook * Input Parameters: None * Output Parameters: None * TI$HANG: PUSH PSW MVI A,RESET ; IDLE MODEM OUT CTRLPORT OUT STATPORT * WAIT FOR PHONE TO DISCONNECT LINE TI$HANG$LOOP: IN RATEPORT ; GET STATUS ANI ANSMSK JZ TI$HANG$LOOP POP PSW RET * * Wait for Dial Tone * Function: Wait for dial tone for 15 secs * Input Parameters: None * Output Parameters: A=0 if no dial tone, A=0FFH if dial tone * TI$WDT: PUSH D ; SAVE DE MVI A,DTDET ; DIAL TONE DETECT OUT CTRLPORT MVI D,DTMASK ; LOOK FOR DIAL TONE TI$W15: CALL TIME15 ; 15 SEC DELAY POP D RET Š * * Wait for Answer * Function: Wait for answer on telephone for 15 secs * Input Parameters: None * Output Parameters: A=0 if no answer, A=0FFH if answer * TI$WANS: PUSH D ; SAVE DE MVI D,CTSMSK ; CLEAR TO SEND JMP TI$W15 ; WAIT FOR UP TO 15 SECS * * Ring Status Detect * Function: Determines if phone is ringing or not * Input Parameters: None * Output Parameters: A=0 if no ring, A=0FFH if ring * TI$RST: IN STATPORT ; GET STATUS ANI RINGMSK ; RINGING? JZ TI$YES XRA A ; A=0 FOR NO RING RET TI$YES: MVI A,0FFH ; A=0FFH FOR RING ORA A ; SET FLAGS RET * * Dial Tone Status Detect * Function: Detect presence of dial tone * Input Parameters: None * Output Parameters: A=0 if no dial tone, A=0FFH if dial tone * TI$DST: IN RATEPORT ; GET STATUS ANI DTMASK ; DIAL TONE? JZ TI$YES ; A=0FFH FOR DIAL TONE XRA A ; A=0 FOR NO DIAL TONE RET * * Carrier Status Detect * Function: Determine if carrier is present * Input Parameters: None * Output Parameters: A=0 if no carrier, A=0FFH if carrier * TI$CST: IN RATEPORT ; GET STATUS ANI CTSMSK ; CLEAR TO SEND? JZ TI$YES ; A=0FFH FOR CARRIER XRA A ; A=0 FOR NO CARRIER RET Š* * Start Dialing * Function: Initiate the dialing process * Input Parameters: None * Output Parameters: A=0 if no dial tone, A=0FFH if dial tone * TI$DSTRT: MVI A,RESET ; IDLE MODEM OUT CTRLPORT CALL TI$PICK ; PICK UP PHONE CALL TI$DST ; CHECK FOR DIAL TONE RET * * Stop Dialing * Function: Terminate the dialing process * Input Parameters: None * Output Parameters: A=0 if no answer, A=0FFH if answer * TI$DSTOP: LDA DTRATE ; SET DATA RATE OUT CTRLPORT CALL T100MS ; WAIT 0.1 SEC MVI D,CTSMSK ; WAIT FOR ANSWER CALL TIME15 RZ ; ABORT IF NO ANSWER * INITIALIZE UART INIT$UART: LDA UART ; INITIALIZE UART OUT STATPORT IN DATAPORT ; CLEAR UART LDA BAUD ; SET BAUD RATE OUT RATEPORT LDA DTRATE ; SET DATA RATE OUT CTRLPORT MVI A,0FFH ; OK ORA A ; SET FLAGS RET * * Dial Digit * Function: Dial an individual digit * Input Parameters: A=ASCII for digit to dial * Output Parameters: None * TI$DIGIT: PUSH PSW PUSH B SUI '0' ; CONVERT TO BINARY JC TI$DIGIT$SKIP ; SKIP INVALID DIGIT CPI 10 ; VALID? JNC TI$DIGIT$SKIP ; SKIP INVALID DIGIT ORA A ; IF ZERO, MAKE IT A 10 JNZ TI$DIAL0 Š MVI A,10 ; 0 TI$DIAL0: MOV C,A ; NUMBER (1-10) IN C * SET DIAL RATE MVI A,D20PPS ; 20 PPS OUT RATEPORT * WAIT FOR ZERO PULSE CALL MWAIT * WAIT FOR NON-ZERO PULSE CALL BWAIT * OUTPUT REQUIRED NUMBER OF PULSES TO DIAL (NUMBER IN C) TI$PULSE: MVI A,MAKEM ; START WITH A MAKE OUT STATPORT CALL MWAIT ; WAIT FOR MAKE INTERVAL MVI A,BREKM ; DO A BREAK OUT STATPORT CALL BWAIT ; WAIT FOR BREAK INTERVAL DCR C ; COUNT PULSES JNZ TI$PULSE MVI A,MAKEM ; WAIT FOR INTERDIGIT TIME ON LAST PULSE OUT STATPORT MVI B,INTER ; INTERDIGIT TIME CALL TIMER1 TI$DIGIT$SKIP: POP B ; RESTORE REGS POP PSW RET * * 0.1 Sec Delay Routine * Function: Pause for 0.1 Sec * Input Parameters: None * Output Parameters: None * T100MS: CALL T50MSEC ;100 MS DELAY T50MSEC PUSH PSW ;50 MS DELAY ROUTINE PUSH B MVI A,0FFH ;DUMMY LOAD TO TIMER OUT TIMEPORT TIMEOT IN STATPORT ANI 20H JZ TIMEOT ;TEST FOR 50 MS TIMEOUT POP B POP PSW RET ENDIF ; TI REQUIRED * * END of Telephone Interface Routines * Š * * End of Support Package * ORG BASE+600H ; SP IS ALWAYS 1.5K BYTES LONG ENDALL: DB 0 END