; PACKET89.ASM ; Derived 12/15/89 from the MODEM Controller, MPLINK ; (H19/H89 version of 7/1/81) ; ;PLINK IS A CP/M TRANSIENT COMMAND WHICH ALLOWS THE USER TO ;ESTABLISH A COMMUNICATIONS LINK WITH A REMOTE COMPUTER ; ; ORIGINAL BY L.E. HUGHES EDCAM JULY, 1977 ; ; WITH HEATH EQUATES ADDED BY TOM JORGENSON. ; Optional Triger characters by Steve Vinokuroff. ; ; Revised by Ray Isenson, N6UEÅtoï interface pacetô NCNÃ and ; give control of the Lineprinter to the BDOS (12/89) ; ;This version is modified to use the H19/H89 special function keys. ;It will run on a non-Heath CPU using the H19 terminal; however, if ;such a system is used, the following equate should be set to zero: ; H8ORH89 EQU 1 ;IF H8 OR H89 COMPUTER SET TO 1 ; ; ;PLINK CURRENTLY SUPPORTS TWO WAY TRANSFER OF TEXT FILES ;BETWEEN THE CP/M DISK AND THE REMOTE COMPUTER. THE FOLLOWING ;CONTROL CODES MAY BE INITIATED FROM THE CONSOLE KEYBOARD: ; ; **************************************************** ; * COMMANDS: * ; * * ; * F1 KEY SAVE INCOMING ASCII IN RAM BUFFER * ; * FOR LATER TRANSFER TO DISK * ; * F2 KEY WRITE RAM BUFFER TO DISK - ASKS * ; * FOR DRIVE AND FILENAME.TYP * ; * F3 KEY TRANSMIT ASCII FILE TO MODEM. * ; * ASKS FOR DRIVE AND FILENAME.TYP * ; * F4 KEY AUTO LOGON * ; * F5 KEY COPY TO PRINTER SWITCH * ; * RED KEY EXIT PLINK TO CP/M WARM BOOT * ; * CONTROL-C ABORT FILE SEND TO MODEM * ; * DELETE BACKSPACE WHEN IN COMMAND MODE * ; * ASKING FOR FILENAME * ; * BACKSPACE SAME AS DELETE * ; * CONTROL-U ABORT CURRENT LINE WHEN IN COMMAND * ; * MODE ASKING FOR FILENAME * ; * * ; **************************************************** ; ; ;SET NUMBER OF DRIVES FOR PARTICULAR SYSTEM ; E.G. 2 = A,B 5 = A,B,C,D,E ; NUMDRV EQU 5 ;ALLOW A: AND B: ONLY ; ; ;BDOS ENTRY POINT AND FUNCTION CODES ; BASE SET 0 ;STANDARD CPM ; BDOS EQU BASE+5 RESDSK EQU 13 ;RESET DISK SYSTEM OFFC EQU 15 ;OPEN FILE CFFC EQU 16 ;CLOSE FILE DFFC EQU 19 ;DELETE FILE RRFC EQU 20 ;READ RECORD WRFC EQU 21 ;WRITE RECORD MFFC EQU 22 ;MAKE FILE LSTOUT EQU 5 ;PRINTER OUTPUT ; ;DEFAULT FCB AND FIELD DEFINITIONS ; FCB EQU BASE+5CH FN EQU 1 ;FILE NAME FIELD (REL) FT EQU 9 ;FILE TYPE FIELD (REL) EX EQU 12 ;FILE EXTENT FIELD (REL) NR EQU 32 ;NEXT RECORD FIELD (REL) DBUF EQU BASE+80H ;DEFAULT DISK BUFFER ADDRESS ; ;ASCII CONTROL CHARACTERS ; CR EQU 0DH ;CARRIAGE RETURN LF EQU 0AH ;LINE FEED DEL EQU 7FH ;DELETE (RUBOUT) BELL EQU 07H ;BELL SIGNAL TAB EQU 09H ;HORIZONTAL TAB XON EQU 11H ;X-ON CHARACTER NULL EQU 00H ;NULL CHAR ESC EQU 1BH ;ESCAPE BL EQU 20H ;BLANK (SPACE) ; ; ;SPECIAL HEATH ONLY BIOS EQUATES ; TICCNT EQU 0BH ;2 MSEC COUNTER ; ; ;THE FOLLOWING "TRIGER" EQUATE IS SET TO "LF" (LINEFEED) ;BY DEFAULT. AN OPTIONAL TRIGER CHAR MAY BE PASSED VIA FCB1 ; ; IE: KERNEL B WILL SET TRIGER TO "BELL" ; ;THE FOLLOWING OPTIONS ARE ALLOWED ; ; 1. B = BELL 07H ; 2. X = XON 11H ; 3. U = UPLOAD NO TRIGER CHECK AT ALL ;ANY OTHER ASCII CHARACTER MAY BE PASSED THROUGH FCB1 ; ; TRIGER EQU LF ;DEFAULT VALUE ; ; ;WARNING CHARACTER FOR LOW MEMORY ; WRNSIG EQU BELL ;IF YOU HAVE ONE, PUT 'BELL' HERE ;...ELSE PUT '*' HERE. ; ;MODEM I/O PORT ADDRESSES ; MODD EQU 330Q ;MODEM BASE PORT MODS EQU MODD+5 ;MODEM STATUS PORT ; ; ;MODEM STATUS PORT BIT DEFINITIONS ; MTBE EQU 20H ;TRANSMITTER READY FLAG MRDA EQU 1H ;RECEIVER READY FLAG MXOR EQU 21H ;TO COMPLEMENT MTBE AND MRDA ; ; **MAIN PROGRAM** ; ORG BASE+100H ; ; LINK: CALL INIT ;INITIALIZE ; ; MAIN LOOP ; LINK3: CALL CITEST ;JUMP IF NO DATA FROM CONSOLE JZ LINK4 CALL RCC ;ELSE READ CONSOLE DATA CPI ESC CZ PCC ;CALL PCC IF ESC (FUNCTION KEY) JZ LINK4 ;JUMP IF PCC HANDLED CHAR ORI 80H ;ELSE SET VALID DATA BIT STA INCH ;AND STORE IN INPUT CHAR BUFFER LINK4: LDA OUTCH ;JUMP IF NO DATA FOR CONSOLE ORA A JP LINK5 ANI 7FH ;ELSE DISCARD VALID DATA BIT CALL WCC ;SEND CHAR TO CONSOLE XRA A ;THEN CLEAR OUTPUT CHAR BUFFER STA OUTCH LINK5: CALL MITEST ;JUMP IF NO DATA FROM MODEM JZ LINK6 CALL RMC2 ;ELSE READ MODEM DATA CALL SAVE ;SAVE CHAR IN TEXT BUFFER IF FLAG ON ORI 80H ;SET DATA VALID BIT STA OUTCH ;STORE IN OUTPUT CHAR BUFFER LINK6: CALL MOTEST ;JUMP IF MODEM XMIT BUFFER BUSY JZ LINK7 LDA INCH ;JUMP IF NO DATA FOR MODEM ORA A JP LINK7 ANI 7FH ;DISCARD VALID DATA BIT OUT MODD ;OUTPUT CHAR TO MODEM XRA A ;...THEN CLEAR INPUT CHAR BUFFER STA INCH LINK7: JMP LINK3 ;END OF MAIN LOOP ; ; PCC - PROCESS CONTROL CHARACTER ; ;BECAUSE THIS SECTION USES THE HEATH HARDWARE CLOCK, THE PROGRAM ;WILL NOT RUN ON OTHER CP/M 2.X SYSTEMS UNLESS A SOFTWARE TIMING ;LOOP IS SUBSTITUTED FOR THE NEXT 8 STATEMENTS. THOSE 8 STATEMENTS ;ARE NOT NECESSARY UNLESS ONE WISHES TO SEND 'ESC' CHARACTERS ;FROM THE CONSOLE TO THE MODEM. WITHOUT THESE TIMING STATEMENTS ;'ESC' MUST BE HIT TWICE TO BE TRANSMITTED ONCE. ; PCC: EQU $ IF H8ORH89 LDA TICCNT ;CHECK FOR SPECIAL FUNCTION KEY ADI 10 ;WAIT 20 MSEC FOR NEXT CHAR MOV C,A ESCTIM: LDA TICCNT CMP C JZ PCC6 ;IF TOO LONG, NOT SPEC FUCNTION KEY CALL CITEST JZ ESCTIM ;LOOP UNTIL CONSOLE INPUT ENDIF CALL RCC ;ESC RECEIVED, GET NEXT CHAR FOR FUNCTION CPI 'Q' ;'RED' KEY MEANS EXIT TO CP/M JNZ PCC1 PUSH H LHLD SIZE MOV A,H ORA L LXI H,TBNE CNZ WCS ;PRINT 'TEXT BUFFER NOT EMPTY' LXI H,AYS ;PRINT 'ARE YOU SURE' CALL WCS POP H CALL RCC ;GET ANSWER CALL WCC ;ECHO IT ANI 5FH ;MAKE UPPER CASE CPI 'Y' ;YES? JZ PCCEX ;EXIT CALL WCCR ;CRLF XRA A ;TELL LINK TO IGNORE THIS CHARACTER RET ; PCC1: CPI 'U' ;'F3' KEY FOR TRANSMIT FILE JNZ PCC2 CALL STF ;TRANSMIT TEXT FILE TO MODEM XRA A ;TELL LINK TO IGNORE THIS CHARACTER RET ; PCC2: CPI 'S' ;'F1' KEY MEANS SAVE ALL IN RAM JNZ PCC3 MVI A,1 ;TURN ON TEXT SAVE FLAG STA FLAG LXI H,PCCMR ;PRINT 'SAVING INCOMING TEXT IN MEMORY' CALL WCS XRA A ;TELL LINK TO IGNORE THIS CHARACTER RET ; PCC3: CPI 'T' ;'F2' KEY MEANS SAVE RAM TEXT TO FILE JNZ PCC4 XRA A ;TURN OFF TEXT SAVE FLAG STA FLAG CALL WTB ;WRITE TEXT BUFFER TO DISK XRA A RET ; PCC4: CPI 'V' ;'F4' KEY MEANS AUTO LOGON JNZ PCC5 LXI H,ALMSG CALL WCS ;PRINT 'AUTO LOGON' LXI H,ALBUF AUTOL: MOV A,M INX H CPI 'Z'-40H ;AUTOLOG DONE ON ^Z JZ ALBRK ANA A ;ZERO MEANS EOS JZ STRFIN CALL WMC CALL RMWC ;READ MODEM, WCC IF AVAILABLE JMP AUTOL ; STRFIN: CALL CITEST ;INPUT FROM CONSOLE JNZ ALBRK ;ABORT IF SO CALL MITEST JZ STRFIN ;WAIT FOR CHAR FROM MODEM CALL RMC2 CALL WCC CPI ':' ;NEXT STRING IF MODEM SENDS ':' JZ AUTOL CPI '+' JZ AUTOL JMP STRFIN ;KEEP WAITING FOR ':' OR '+' ; RMWC: CALL MITEST ;READ MODEM & WRITE CONSOLE IF CHAR RZ CALL RMC2 JMP WCC ; ALBRK: XRA A RET ; ALBUF: DB 'A',0 DB 'CIS02',CR,0 DB CR,0 DB 0 DB '70000,0000',CR,0 DB 'PASSWORD',CR,0 DB 'Z'-40H DB 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0 ; PCC5: CPI 'W' ;'F5' KEY MEANS COPY TO PRINTER JNZ PCC6 LXI H,PRTFLG MOV A,M CMA MOV M,A ;COMPLEMENT PRINT FLAG ANA A LXI H,PRTOFF ;PRINT 'OFF' JZ PRTLAB LXI H,PRTON ;PRINT 'ON' PRTLAB: CALL WCSNP XRA A RET ; PCC6: ANA A ;LET LINK HANDLE ALL OTHER CONT. CODES RET ; PCCEX: LXI H,DISMS ;PRINT 'EXIT TO CP/M' CALL WCS JMP BASE ;EXIT TO WARM BOOT ; TBNE: DB CR,LF,BELL,'CAUTION: TEXT BUFFER NOT EMPTY',0 AYS: DB CR,LF,'EXIT TO CP/M - ARE YOU SURE (Y OR N)?',0 DISMS: DB CR,LF,'+++ EXIT TO CP/M +++',CR,LF DB ESC,'j',ESC,'Y',BL+24,BL,ESC,'l',ESC,'k',0 ALMSG: DB CR,LF,'AUTOMATIC LOGON',CR,LF,0 PCCMR: DB CR,LF,'SAVING INCOMING TEXT IN MEMORY',CR,LF,0 ; ; STF - SEND TEXT FILE (TO MODEM) ; STF: CALL GFN ;GET NAME OF DISK FILE TO SEND JC STF6 ;JUMP IF FILE NAME ERROR CALL OPEN ;TRY TO OPEN SPECIFIED FILE CPI 255 ;JUMP IF FILE NOT FOUND JZ STF7 STF1: CALL READ ;READ NEXT RECORD INTO DBUF CPI 1 ;JUMP IF END-OF-FILE JZ STF5 LXI H,DBUF ;POINT TO DISK BUFFER MVI C,128 STF2: CALL CCTEST ;CHECK FOR ^C FROM CONSOLE MOV A,M ;FETCH NEXT CHAR FROM DBUF INX H CPI 'Z'-40H ;JUMP IF END-OF-FILE CHARACTER JZ STF5 OVERL2 CPI LF ;IGNORE LINE FEEDS JZ STF4 CALL WMC ;WRITE CHARACTER TO MODEM CALL WCC ;WRITE CHARACTER TO CONSOLE OVERL1 CPI CR ;JUMP IF NOT CARRIAGE RETURN JNZ STF4 STF3: CALL CCTEST ;CHECK FOR ^C ABORT CALL MITEST ;WAIT FOR NEXT MODEM CHARACTER JZ STF3 CALL RMC2 ;CHECK MODEM FOR TRIGGER CHAR. OVERLY CPI TRIGER JNZ STF3 CALL WCCR ;SEND CRLF TO CONSOLE STF4: DCR C ;LOOP THRU REST OF DBUF JNZ STF2 JMP STF1 ;GO GET NEXT RECORD FROM DISK ; STF5: LXI H,STFSM ;PRINT 'FILE SEND COMPLETE' CALL WCS RET ; STF6: LXI H,STFS1 ;PRINT 'FILE NAME ERROR' CALL WCS RET ; STF7: LXI H,STFS2 ;PRINT 'FILE NOT FOUND' CALL WCS RET ; CCTEST: CALL CITEST ;CHAR FROM CONSOLE? RZ ;IF NO CALL RCC CPI 'C'-40H RNZ ;IGNORE IF NOT ^C POP PSW ;CLEAR *RET* FROM STACK LXI H,STFSA ;PRINT 'FILE SEND ABORTED' CALL WCS RET ; STFSM: DB 'FILE SEND COMPLETE',CR,LF,0 STFS1: DB 'FILE NAME ERROR',CR,LF,0 STFS2: DB 'FILE NOT FOUND',CR,LF,0 STFSA: DB CR,LF,'FILE SEND ABORTED',CR,LF,0 ; ; SAVE - SAVE CHAR IN TEXT BUFFER IF FLAG ON ; ; ENTRY CONDITIONS ; A - CHARACTER TO SAVE ; SAVE: PUSH PSW LDA FLAG ORA A JNZ SAVE1 POP PSW RET ; SAVE1: POP PSW CPI DEL ;RUBOUT (DEL) ? RZ ;YES, IGNORE IT CPI 20H ;TEST FOR CONTROL CHARACTERS JNC SAVE2 ;JUMP IF NOT CONTROL CHAR. CPI CR ;ALLOW CR TO BE SAVED JZ SAVE2 CPI LF ;ALLOW LF TO BE SAVED JZ SAVE2 CPI TAB ;ALLOW TAB TO BE SAVED JZ SAVE2 RET ;IGNORE ALL OTHER CONTROL CHARS. ; SAVE2: PUSH H LHLD SIZE ;SIZE = SIZE + 1 INX H SHLD SIZE LHLD PTR MOV M,A INX H SHLD PTR PUSH PSW LHLD BREM DCX H SHLD BREM MVI A,0FFH CMP H JZ SAVEAB ;ABORT IF TBUF FILLED MVI A,3 CMP H MVI A,WRNSIG ;SIGNAL CONSOLE RUNNING OUT OF SPACE CNC WCC PUSH H ;HL = BYTES LEFT IN BUFFER LXI H,BRPOS ;POSITION ON 25TH LINE CALL WCSNP ;CONSOLE WRITE WITHOUT PRINTER POP H CALL DECOUT ;OUTPUT HL AS DECIMAL LXI H,RESCP CALL WCSNP ;RESTORE CURSOR POSITION POP PSW POP H RET ; BRPOS: DB ESC,'j',ESC,'Y',BL+24,BL+75,ESC,'p',0 PRTON: DB ESC,'j',ESC,'Y',BL+24,BL+38,ESC,'pon',ESC,'q ',ESC,'k',0 PRTOFF: DB ESC,'j',ESC,'Y',BL+24,BL+38,ESC,'poff' RESCP: DB ESC,'q',ESC,'k',0 ; ; SAVEAB - RAN OUT OF ROOM, ISSUE MESSAGE AND FLOW ; THROUGH TO DISK SAVE ROUTINE ; SAVEND: DB BELL,CR,LF,'ABORTING - NO ROOM LEFT',0 ; SAVEAB: LXI SP,STACK+64 ;REINITIALIZE STACK LXI H,SAVEND ;PRINT 'ABORTING - NO ROOM LEFT' CALL WCS LXI H,LINK ;SET UP RETURN ADDRESS PUSH H ;LEAVE IT ON THE STACK ; ; WTB - WRITE TEXT BUFFER TO DISK ; WTB: LHLD SIZE ;JUMP IF TEXT BUFFER EMPTY MOV A,L ORA H JZ WTB5 MVI C,RESDSK ;RESET IN CASE READ-ONLY CALL BDOS CALL GFN ;GET FILE NAME JC WTB6 ;JUMP IF FILE NAME ERROR CALL DELT ;DELETE OLD FILE, IF ANY CALL MAKE ;MAKE NEW FILE LHLD SIZE ;DE = TBUF SIZE XCHG LXI H,DBUF ;TOP OF STACK POINTS TO DBUF PUSH H LXI H,TBUF ;HL POINTS TO TBUF WTB1: MVI C,128 ;DISK BUFFER SIZE WTB2: MOV A,M ;FETCH NEXT BYTE OF TBUF INX H XTHL MOV M,A ;STORE IN DBUF INX H XTHL DCX D ;SIZE = SIZE - 1 MOV A,D ;EXIT LOOP IF SIZE = 0 ORA E JZ WTB3 DCR C ;LOOP UNTIL DBUF FULL JNZ WTB2 CALL WRITE ;WRITE FULL DBUF TO DISK JNZ NOWRT ;IF WRITE NOT SUCCESSFUL XTHL ;TOP OF STACK POINTS TO DBUF LXI H,DBUF XTHL JMP WTB1 ;LOOP UNTIL END OF TBUF ; WTB3: POP H ;HL POINTS TO CURRENT PLACE IN DBUF WTB4: MVI M,'Z'-40H ;STORE EOF CODE INX H DCR C ;LOOP THRU REST OF DBUF JNZ WTB4 CALL WRITE ;WRITE LAST SECTOR TO DISK JNZ NOWRT1 ;IF WRITE NOT SUCCESSFUL CALL CLOSE ;CLEAN UP ACT AND GO HOME LXI H,TBUF ;CLEAR TEXT BUFFER SHLD PTR LXI H,0 SHLD SIZE LXI H,BRPOS ;SET CURSOR TO WRITE BYTES REMAINING CALL WCSNP LHLD BLEN SHLD BREM ;REMAINING BUFFER IF BUFFER LENGTH CALL DECOUT LXI H,RESCP ;RESTORE CURSOR POSITION CALL WCSNP LXI H,WTBSM ;PRINT 'BUFFER SAVED ON DISK' CALL WCS RET ; NOWRT: POP H ;WRITE FAILS, CLEAR STACK NOWRT1: LXI H,NWMSG CALL WCS ;TELL USER TO TRY AGAIN JMP WTB ; WTB5: LXI H,WTBS1 ;PRINT 'TEXT BUFFER EMPTY' CALL WCS RET ; WTB6: LXI H,WTBS2 ;PRINT 'FILE NAME ERROR' CALL WCS RET ; NWMSG: DB CR,LF,BELL,'DISK OVERFLOW - DO AGAIN',CR,LF,0 WTBSM: DB CR,LF,'BUFFER SAVED ON DISK',CR,LF DB 'MEMORY SAVE CANCELLED',CR,LF,0 WTBS1: DB 'TEXT BUFFER EMPTY',CR,LF,0 WTBS2: DB 'FILE NAME ERROR',CR,LF,0 ; ; WCS - WRITE CONSOLE STRING ; ; ; ENTRY CONDITIONS ; HL - POINTS TO STRING (TERM BY ZERO BYTE) ; WCS: MOV A,M INX H ORA A RZ CALL WCC JMP WCS ; ; WCSNP - WRITE CONSOLE STRING WITHOUT PRINTER OUTPUT ; ; ; ENTRY CONDITIONS ; HL - POINTS TO STRING (TERM BY ZERO BYTE) ; WCSNP: MOV A,M INX H ORA A RZ CALL WCCNP JMP WCSNP ; ; WCCR - WRITE CONSOLE CARRIAGE RETURN (AND LINE FEED) ; WCCR: MVI A,CR CALL WCC MVI A,LF ; ; WCC - WRITE CONSOLE CHARACTER ; ; ENTRY CONDITIONS: ; A - CHARACTER TO WRITE ; WCC: PUSH PSW PUSH B PUSH D PUSH H MOV C,A ;GET CHARACTER FOR CBIOS PUSH B WCCAL: CALL $-$ ;MODIFIED BY INIT. POP B ;C = CHAR LDA PRTFLG ANA A CNZ PRTOUT ;IF SIMULTANEOUS LISTING WANTED POP H POP D POP B POP PSW RET ; ;SEND CHARACTER TO PRINTER ; VALUE IN (C) ; ; PRTOUT: MOV A,C ;MOVE CHARACTER TO A ANI 7FH ;STRIP 8TH BIT FROM CHARACTER MVI C,LSTOUT;GET LIST OUTPUT FUNCTION MOV E,A ;PUT CHARACTER IN E CALL BDOS ;PRINT THE CHARACTER RET ; WCCNP - WRITE CONSOLE CHARACTER WITHOUT PRINTER OUTPUT ; ; ENTRY CONDITIONS: ; A - CHARACTER TO WRITE ; WCCNP: PUSH PSW PUSH B PUSH D PUSH H MOV C,A ;GET CHARACTER FOR CBIOS WCCAL1: CALL $-$ ;MODIFIED BY INIT. POP H POP D POP B POP PSW RET ; ; RCS - READ CONSOLE STRING (WITH ECHO) ; ; EXIT CONDITIONS ; B - NUMBER OF CHARACTERS READ (<255) ; HL - POINTS TO LAST CHAR STORED (CR) ; RCS: LXI H,IBUF MVI B,0 RCS1: CALL RCC ;READ NEXT CHAR FROM CONSOLE CPI DEL ;JUMP IF NOT DEL JNZ RCS2 INR B ;IGNORE DEL IF IBUF ALREADY EMPTY DCR B JZ RCS1 DCX H ;ELSE DISCARD LAST CHAR MOV A,M ;ECHO DISCARDED CHAR TO CONSOLE CALL WCC DCR B ;DECREMENT COUNT JMP RCS1 ; AND LOOP ; RCS2: CPI 'U'-40H ;JUMP IF NOT CONTROL U JNZ RCS3 CALL WCCR ;ELSE ABORT CURRENT LINE JMP RCS ; AND START OVER ; RCS3: CALL WCC ;ECHO CHAR TO CONSOLE MOV M,A ;STORE CHAR IN IBUF INR B ;INCREMENT COUNT CPI CR ;JUMP IF CARRIAGE RETURN JZ RCS4 INX H ;ELSE ADVANCE POINTER JMP RCS1 ; AND LOOP ; RCS4: MVI A,LF ;ISSUE LINE FEED AND RETURN CALL WCC RET ; ; RCC - READ CONSOLE CHARACTER ; ; EXIT CONDITIONS ; A - CHARACTER READ ; RCC: PUSH B PUSH D PUSH H RCCAL: CALL $-$ ;MODIFIED BY INIT. POP H POP D POP B RET ; ; WMC - WRITE MODEM CHARACTER ; ; ENTRY CONDITIONS ; A - CHARACTER TO WRITE ; ; WMC: PUSH PSW WMCL: IN MODS XRI MXOR ANI MTBE JNZ WMCL POP PSW ANI 7FH ;STRIP PARITY BIT OUT MODD RET ; WMS: MOV A,M ;WRITE STRING TO MODEM INX H ORA A RZ CALL WMC JMP WMS ; ; RMC - READ MODEM CHARACTER ; ; EXIT CONDITIONS: ; A - CHARACTER READ ; ; RMC: IN MODS XRI MXOR ANI MRDA JNZ RMC RMC2: IN MODD ANI 7FH RET ; ; ; GFN - GET FILE NAME ; GFN: LXI H,GFNSD ;PRINT 'WHICH DRIVE?' CALL WCS CALL RCC ;GET ANSWER FROM CONSOLE CALL WCC ;ECHO IT TO CONSOLE ANI 5FH ;MAKE UPPER CASE SUI 'A'-1 JC GFN ;REQUIRE ALPHABETIC JZ GFN CPI NUMDRV+1 JNC GFN STA FCB GFNB: LXI H,GFNS1 ;PRINT 'FILENAME? ' CALL WCS CALL RCS ;READ RESPONSE INTO IBUF LXI H,FCB+FN ;BLANK FILL FN AND FT FIELDS MVI C,11 GFN1: MVI M,BL INX H DCR C JNZ GFN1 LXI H,IBUF ;POINT TO INPUT BUFFER LXI D,FCB+FN ;SCAN OFF FN FIELD MVI C,9 GFN2: MOV A,M ;FETCH NEXT CHAR FROM IBUF INX H CPI 61H ;IF LC, CONVERT TO UC JC GFN2A SUI 20H GFN2A: CPI CR ;JUMP IF END OF LINE JZ GFN5 CPI '.' ;JUMP IF END OF NAME JZ GFN3 STAX D ;ELSE STORE CHAR IN FN FIELD INX D DCR C ;LOOP IF 8 OR LESS CHARS SO FAR JNZ GFN2 JMP GFN6 ;ELSE TAKE ERROR EXIT ; GFN3: LXI D,FCB+FT ;SCAN OFF FT FIELD MVI C,4 GFN4: MOV A,M ;FETCH NEXT CHAR FROM IBUF INX H CPI 61H ;IF LC, CONVERT TO UC JC GFN4A SUI 20H GFN4A: CPI CR ;JUMP IF END OF LINE JZ GFN5 STAX D ;ELSE STORE CHAR IN FT FIELD INX D DCR C ;LOOP IF 3 OR LESS CHARS SO FAR JNZ GFN4 JMP GFN6 ;ELSE TAKE ERROR EXIT ; GFN5: XRA A STA FCB+EX ;SET EXTENT NUMBER TO ZERO STA FCB+NR ;SET RECORD NUMBER TO ZERO STC ;CLEAR ERROR FLAG AND RETURN CMC RET ; GFN6: STC ;SET ERROR FLAG AND RETURN RET ; GFNSD: DB CR,LF,'WHICH DRIVE? ',0 GFNS1: DB CR,LF,'FILENAME? ',0 ; ; OPEN - OPEN DISK FILE ; OPEN: PUSH H PUSH D PUSH B LXI D,FCB MVI C,OFFC CALL BDOS POP B POP D POP H RET ; ; READ - READ RECORD FROM DISK FILE ; READ: PUSH H PUSH D PUSH B LXI D,FCB MVI C,RRFC CALL BDOS POP B POP D POP H RET ; ; CLOSE - CLOSE DISK FILE ; CLOSE: PUSH H PUSH D PUSH B LXI D,FCB MVI C,CFFC CALL BDOS POP B POP D POP H RET ; ; DELT - DELETE DISK FILE ; DELT: PUSH H PUSH D PUSH B LXI D,FCB MVI C,DFFC CALL BDOS POP B POP D POP H RET ; ; WRITE - WRITE RECORD TO DISK ; WRITE: PUSH H PUSH D PUSH B LXI D,FCB MVI C,WRFC CALL BDOS ANA A ;SET 'Z' FLAG FOR ERROR POP B POP D POP H RET ; ; MAKE - MAKE NEW DISK FILE ; MAKE: PUSH H PUSH D PUSH B LXI D,FCB MVI C,MFFC CALL BDOS POP B POP D POP H RET ; ; CITEST - CHECK CONSOLE INPUT STATUS ; CITEST: PUSH B PUSH D PUSH H CITCAL: CALL $-$ ;MODIFIED BY INIT. ORA A ;SET ZERO FLAG POP H POP D POP B RET ;ZERO FLAG CARRIES ANSWER ; ; MITEST - CHECK MODEM INPUT STATUS ; MITEST: IN MODS ;GET MODEM UART STATUS XRI MXOR ;INVERT HIGH-TRUE BITS ANI MRDA ;ANY DATA AVAILABLE? MVI A,0 JNZ MITST1 CMA MITST1: ORA A RET ;ZERO FLAG CARRIES ANSWER ; ; ; MOTEST - CHECK MODEM OUTPUT STATUS ; ; MOTEST: IN MODS ;GET MODEM UART STATUS XRI MXOR ;INVERT HIGH-TRUE BITS ANI MTBE ;UART READY FOR CHARACTER? MVI A,0 JNZ MOTST1 ;ZERO FLAG CARRIES ANSWER CMA MOTST1: ORA A ;SET ZERO FLAG IF READY RET ; ;DECIMAL PRINT SUBROUTINE ;PRINTS H,L AS A DECIMAL NO. ; DECOUT LXI D,-10000 CALL PRTDGT ;PRINT 10'S OF THOUSANDS LXI D,-1000 CALL PRTDGT ;PRINT THOUSANDS LXI D,-100 CALL PRTDGT ;PRINT HUNDREDS LXI D,-10 CALL PRTDGT ;PRINT TENS LXI D,-1 PRTDGT MVI C,'0'-1 ;INITIALIZE COUNT PUSH H ;SO INITIAL INX SP'S WON'T HURT PRT1 INR C ;BUMP COUNT OF SUCCESSFUL SUBTR. INX SP ;"POP" STACK W/O ALTERING REGISTERS INX SP PUSH H ;SAVE H,L DAD D ;DO 1 SUBTRACTION JC PRT1 ;IF RESULT STILL POS., DO IT AGAIN POP H ;RESTORE LAST GOOD VALUE TO H,L MOV A,C JMP WCCNP ;PRINT CHAR & RET ; ; DATA AREA ; BLEN: DS 2 ;BUFFER LENGTH BREM: DS 2 ;BYTES TBUF REMAINING PRTFLG: DB 0 ;PRINTER OFF IF ZERO INCH: DS 1 ;INPUT CHAR BUFFER (TO CYBER) OUTCH: DS 1 ;OUTPUT CHAR BUFFER (FROM CIBER) STACK: DS 80 ;LOCAL STACK IBUF: DS 256 ;INPUT BUFFER ; ; TEXT BUFFER ; FLAG: DS 1 ;TEXT SAVE FLAG PTR: DS 2 ;TEXT BUFFER POINTER SIZE: DS 2 ;TEXT BUFFER SIZE TBUF: EQU $ ;START OF TEXT BUFFER ; ;INITIAL CODE IS PLACED HERE TO SAVE SPACE (BUFFER OVERWRITES IT) ; INIT: POP H ;SAVE RETURN ADDRESS LXI SP,STACK+64 ;CREATE LOCAL STACK PUSH H ;RESTORE RETURN ADDRES TO STACK LHLD BASE+1 ;POINT TO CP/M JMP TABLE LXI D,3 ;GET READY TO ADD 3 DAD D ;POINT TO CON STATUS JMP SHLD CITCAL+1 ;MODIFY CALL ADRS DAD D ;POINT TO CON IN JMP SHLD RCCAL+1 ;MODIFY CALL ADRS DAD D ;POINT TO CON OUT JMP SHLD WCCAL+1 ;MODIFY CALL ADRS SHLD WCCAL1+1 LDA FCB+1 ;SEE IF OPTIONAL TRIGER CHAR CPI 20H ;BLANK.. ? JZ SKP ;..BLANK SO USE DEFAULT "LF" CPI 'B' ;BELL WANTED JZ TRGBEL CPI 'X' ;XON WANTED JZ TRGXON CPI 'U' ;UPLOADING NO CHECKING FOR TRIGER JZ TRGUPL ; SETTRG STA OVERLY+1 ;STORE THE CHARACTER AS IS THEN JMP SKP ; TRGBEL MVI A,BELL JMP SETTRG ; TRGXON MVI A,XON JMP SETTRG ; TRGUPL XRA A ;ZERO OUT JUMP STA OVERL1+1 ;CHANGE CHECK FOR C/R TO NULL STA OVERL2+1 ;AND SEND LINEFEEDS AS WELL ; SKP EQU $ ; ; XRA A ;CLEAR CHAR BUFFERS STA INCH STA OUTCH STA FLAG ;CLEAR TEXT SAVE FLAG LXI H,TBUF ;SET PTR TO TBUF SHLD PTR LXI H,0 ;SIZE = 0 SHLD SIZE LHLD BASE+6 MVI L,0 DCR H ;HL = MAX TBUF TOP LXI D,-TBUF DAD D ;HL = MAX TBUF LEN SHLD BLEN SHLD BREM ;BUFFER BYTES REMAINING LXI H,LINKMS ;PRINT SIGN-ON MESSAGE CALL WCSNP LHLD BLEN ;PRINT BUFFER ON 25TH LINE CALL DECOUT LXI H,RESCP CALL WCSNP RET ;RETURN TO MAIN LOOP ; LINKMS: DB ESC,'E',ESC,'Y',BL+5,BL+22 DB 'H/Z-89 TNC CONTROLLER - RSI - DEC 89' DB CR,LF,LF,LF DB ESC,'x1',ESC,'j',ESC,'Y',BL+24,BL+5 DB ESC,'pSave',ESC,'q ' DB ESC,'pFile',ESC,'q ' DB ESC,'pSend',ESC,'q ' DB ESC,'pN/A',ESC,'q ' DB ESC,'pPrint off',ESC,'q' DB ESC,'Y',BL+24,BL+53,ESC,'pExit',ESC,'q ' DB ESC,'pBuffer = ',0 ; END LINK0