;MODEM PORT EQUATES MDATA EQU 4 ;Modem data port MSTAT EQU 5 ;Modem status port MCNTR EQU 5 ;Modem control port MOMASK EQU 1 ;Mask for input available MIMASK EQU 2 ;Mask for output posible RESET EQU 01000000B ;Value for port reset MINIT1 EQU 01001111B ;Modem initialise value MINIT2 EQU 00010101B ; and second one PINIT1 EQU 01001110B ;Printer initialise value PINIT2 EQU 00010101B ; and second one ;CP/M EQUATES BASE EQU 0 ;Start of CP/M BDOS EQU BASE+5 ;OS calls CCP EQU 0C000H ;Console Command Processor address BIOS EQU 0D600H ;Basic I/O, first vector. TPA EQU 0100H ;Start or programs CONS EQU 6 ;Direct console output PRINT EQU 9 ;Print string ESC EQU 27 ORG TPA LXI D,ACTIV MVI C,PRINT CALL BDOS ;Print a message LHLD BASE+6 ;Get BDOS vector and save it SHLD BDOSTP ; for later if needed LXI H,STARTR ;Protect memory - this will always SHLD BASE+6 ; happen after a warm boot LHLD BIOS+09H+1 ;Check if already installed MOV A,H CPI CONSIN/256 ;Is jump already in? RZ ;Return to CP/M, hope that code ; is still sitting under CCP as ; no way of knowing where the ; vector is supposed to go LXI H,ENDP+1 LXI D,STARTR LXI B,ENDR-STARTR MOVLOP: MOV A,M ;Move routine up there STAX D INX H INX D DCX B MOV A,B ORA C JNZ MOVLOP LHLD BDOSTP ;Get saved BDOS vector SHLD STARTR+1 ;Install it LHLD BIOS+09H+1 ;Console input vector SHLD CONSIN+1 ;Save in my prog LXI H,CONSIN SHLD BIOS+09H+1 ;Trap calls to here RET ;Return to CP/M ;THIS MUST NOT BE A WARM BOOT. The reason is ; because this program does not worry about ; warm boots, hence should have this as an ; auto-execute command. If we booted here ; and have auto command , hey presto endless ; loop !! ACTIV: DT '(EXTCOM active)$' BDOSTP: DW 0 ;Temporary storage for BDOS vector ENDP: DB 0 ORG CCP-100H ;256 bytes of room STARTR: DB 0C3H DW 0 CONSIN: DB 0CDH ;CALL = back here when DW 0 ; done PUSH PSW ;Save status from routine ORA A ; ^@ is go to extcom JZ EXTCOM POP PSW RET ;Back to wherever... EXTCOM: LXI H,STARTR-1 SPHL ;Move to a new stack LXI D,SIGNON MVI C,PRINT CALL BDOS CALL INITIALISE START: CALL GETCHAR CNZ PUTMOD CALL GETMOD CNZ PUTCHAR JMP START INITIALISE: MVI A,RESET ;Set up the port for modem OUT MCNTR ;operation. Form : 8 data bits MVI A,MINIT1 ; 1 stop bit OUT MCNTR ; no parity MVI A,MINIT2 ; 300 baud OUT MCNTR RET GETCHAR: MVI C,CONS ;Console I/O function MVI E,0FFH ;Requesting input CALL BDOS ORA A ;If A=0, no character RZ CPI ESC ;Check for ESCape RNZ MVI A,RESET ;Set up port for printer OUT MCNTR ;operation. Form : 8 data bits MVI A,PINIT1 ; 1 stop bit OUT MCNTR ; no parity MVI A,PINIT2 ; 1200 baud OUT MCNTR ; JMP BASE ;Back to CP/M PUTMOD: STA TEMP ;Save character.. MVI B,100 ;Initialise counter NEXTLOOP: DCR B ;Drop counter. Finished ? RZ ;Go back if we are IN MSTAT ;Get modem status ANI MOMASK ;Is it ready ? JZ NEXTLOOP ;No, try again LDA TEMP ;Get chararacter back OUT MDATA ;Send it RET ;Lets go back TEMP: DB 0 ;Temporary storage GETMOD: IN MSTAT ;Get status ANI MIMASK ;Is it ready ? RZ ;Go back if not IN MDATA ORA A ;Reset Z flag RET PUTCHAR: ANI 07FH ;Strip any high bits MOV E,A ;Move char to output MVI C,CONS ;Function: direct I/O CALL BDOS ;Display it. RET SIGNON: DT 'EXTernal COMunications...(300 baud)...' DW 0A0DH DB '$' ENDR: DB 0