IT PARMS WILL BE 16 MOV E,M ;NOW MOVE PARMS INX H XCHG SHLD SPT XCHG MOV E,M INX H XCHG SHLD DRM XCHG MOV APLMODEMASM€ APLMODEMASM€APLMODEMASMAPLMODEM$$$PTED FOR THE APPLE ][ COMPUTER RUNNING CP/M WITH ;THE Z-80 SOFTCARD BY CHANGING THE EQUATES FOR THE ;VARIOUS APPLE MODEM CONFAPLMODEMASM€ APLMODEMASM€APLMODEMASMAPLMODEM$$$CHG CALL GTKSEC SHLD MAXSEC XCHG SHLD MAXTRK POP H POP PSW MOV M,A RET ; ;Temporary storage area ; BUFAD: DWAPLMODEMASM€ APLMODEMASM€APLMODEMASMAPLMODEM$$$ååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååAPLMODEMASM€ APLMODEMASM€APLMODEMASMAPLMODEM$$$DIRPOS: DB 0 FINDFL: DB 0 ;1=MUST POSITION AFTER FIND FTSW: DB 1 ;SEARCH W/O INCREMENT NOTPOS: DB 1 ;INITIALLY NOT POSITIONEDAPLMODEMASM€ APLMODEMASM€APLMODEMASMAPLMODEM$$$ååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååAPLMODEMASM€ APLMODEMASM€APLMODEMASMAPLMODEM$$$ BACK UP IN "CA0-7F,X" DUMTYP: DS 1 ; ;-------------------------------------------------- ;The disk parameter block ;is movAPLMODEMASM€ APLMODEMASM€APLMODEMASMAPLMODEM$$$ MICROMODEM II. ;IF YOU HAVE ANOTHER MODEM, YOU MUST CHANGE THE ;EQUATES TO FALSE FOR MMII AND TRUE FOR YOUR MODEM. ; * APLMODEMASM€ APLMODEMASM€APLMODEMASMAPLMODEM$$$GURATIONS: ; 1)DC HAYS MICROMODEM II ; 2)EXTERNAL MODEM THROUGH ONE OF THE FOLLOWING: ; a) CCS 7710 SERIAL INTERFACE ; b) APLMODEMASM€ APLMODEMASM€APLMODEMASMAPLMODEM$$$M BIOS ; CALL INITADR ; LDA FCB+1 ;GET PRIMARY OPTION CPI 'H' ;MODEM H(ELP)? JZ HELP ;..YES, GIVE HELP CPI 'X' ;MODEAPLMODEMASM€ APLMODEMASM€APLMODEMASMAPLMODEM$$$N BAUD RATE DEFAULTS TO ;300 - 1 STOP BIT. DO NOT CHANGE NEXT EQUATES ; ORIGMOD EQU 8EH ;OFF HOOK, 110 BAUD, CAR. ON, ORIG. APLMODEMASM€ APLMODEMASM€APLMODEMASMAPLMODEM$$$TUS PORT MODCTL2 EQU 0E0A5H ;2ND STATUS PORT MODDATP EQU 0E0A7H ;DATA PORT ENDIF ;MMII ; IF SSM ;SSM INTERFACE MODCTLP APLMODEMASM€ APLMODEMASM€APLMODEMASMAPLMODEM$$$E, IF USING D.C. HAYES MICROMODEM ][ CCS EQU FALSE ;TRUE, USING CCS 7710 SERIAL INTERFACE COMCARD EQU FALSE ;TRUE, USING APPLEAPLMODEMASM€ APLMODEMASM€APLMODEMASMAPLMODEM$$$U 'E'-40H ;CTL-E EXIT FROM T OR C DISCCHR EQU 'D'-40H ;CTL-D DISCONNECTS MODEM T/E ; FASTCLK EQU FALSE ;TRUE FOR 4 MHZ CLOCK APLMODEMASM€ APLMODEMASM€APLMODEMASMAPLMODEM$$$ace, but according to documentation I have ;been able to obtain, they should work using these equates. ; INITC1 EQU 03 ;1ST IAPLMODEMASM€ APLMODEMASM€APLMODEMASMAPLMODEM$$$EQU 1 ;START OF HEADER EOT EQU 4 ;END OF TRANSMISSION ACK EQU 6 ;ACKNOWLEDGE NAK EQU 15H ;NEG ACKNOWLEDGE CAN EQU 18H ;CANCEAPLMODEMASM€ APLMODEMASM€APLMODEMASMAPLMODEM$$$TLP EQU 0E0AEH ;STATUS MODDATP EQU 0E0AFH ;DATA ENDIF ;COMCARD ; IF MMII ;DC HAYES MICROMODEM ][ MODCTLP EQU 0E0A6H ;STAAPLMODEMASM€ APLMODEMASM€APLMODEMASMAPLMODEM$$$ '1/1/81',CR,LF,'$' ; START POP D ;GET ID MESSAGE MVI C,PRINT CALL BDOS ;PRINT ID MESSAGE ; ;INITIALIZE THE JMPS TO CP/APLMODEMASM€ APLMODEMASM€APLMODEMASMAPLMODEM$$$U 0 TRUE EQU NOT FALSE ; STDCPM EQU TRUE ;TRUE, IS STANDARD CP/M ; BASE EQU 0 ;CP/M BASE ADDRESS ; ;NOTE: IF DC HAYES THEAPLMODEMASM€ APLMODEMASM€APLMODEMASMAPLMODEM$$$ SERIAL PORT ; CALL INITMOD ; ;MOVE THE FILENAME FROM FCB 2 TO FCB 1 ; CALL MOVEFCB ; ;GOBBLE UP GARBAGE CHARS FROM THAPLMODEMASM€ APLMODEMASM€APLMODEMASMAPLMODEM$$$DEM PORT REQUIREMENTS ; INITREQ EQU FALSE ;TRUE, IF MODEM PORT INIT. REQ'D ; ;APPLE MODEM TYPES EQUATES MMII EQU TRUE ;TRUAPLMODEMASM€ APLMODEMASM€APLMODEMASMAPLMODEM$$$ADY MODRCVB EQU 1 ;BIT TO TEST FOR RECEIVE MODRCVR EQU 1 ;VALUE WHEN READY ; ERRLIM EQU 10 ;MAX ALLOWABLE ERRORS EXITCHR EQAPLMODEMASM€ APLMODEMASM€APLMODEMASMAPLMODEM$$$l for DATA ;and STATUS as the communication card. ;N.B.-->I have not tested this program for the SSM or ;Apple serial interfAPLMODEMASM€ APLMODEMASM€APLMODEMASMAPLMODEM$$$F THE FOLLOWING OPTION ;IS SELECTED: ; TIMESHR EQU FALSE ;TRUE TO MAKE BIT 7 HIGH ; ;DEFINE ASCII CHARACTERS USED ; SOH APLMODEMASM€ APLMODEMASM€APLMODEMASMAPLMODEM$$$IA MODDATP EQU 0E0A1H ;DATA PORT OF CCS ACIA (MOT 6850) ENDIF ;CCS ; IF COMCARD ;APPLE COMMUNCATIONS CARD MODCAPLMODEMASM€ APLMODEMASM€APLMODEMASMAPLMODEM$$$K FROM CP/M SHLD STACK ;..SAVE IT LXI SP,STACK ;SP=MY STACK CALL START ;GO PRINT ID DB 'APPLE ][ MODEM V1.1 as of ' DBAPLMODEMASM€ APLMODEMASM€APLMODEMASMAPLMODEM$$$SSM SERIAL INTERFACE ; c) APPLE COMMUNICATIONS INTERFACE ; d) APPLE SERIAL INTERFACE ; ;DEFINE FALSE AND TRUE ; FALSE EQAPLMODEMASM€ APLMODEMASM€APLMODEMASMAPLMODEM$$$M X(AMPLES)? JZ EXAM ;GIVE EXAMPLES ; ;SAVE PRIMARY OPTION, VALIDATE SECONDARY OPT. ; CALL PROCOPT ; ;INIT THE MODEM ORAPLMODEMASM€ APLMODEMASM€APLMODEMASMAPLMODEM$$$ ANSWMOD EQU 8AH ;OFF HOOK, 110 BAUD, CAR. ON, ANSW. ; ;IF YOU ARE USING AN EXTERNAL MODEM ;CHANGE THESE EQUATES FOR YOUR MOAPLMODEMASM€ APLMODEMASM€APLMODEMASMAPLMODEM$$$EQU 0E0A4H ;STATUS MODDATP EQU 0E0A5H ;DATA ENDIF ;SSM ; MODSNDB EQU 2 ;BIT TO TEST FOR SEND MODSNDR EQU 2 ;VALUE WHEN REAPLMODEMASM€ APLMODEMASM€APLMODEMASMAPLMODEM$$$ COMMUNICATIONS CARD SSM EQU FALSE ;TRUE, USING SSM SERIAL INTERFACE ; ;the Apple serial card apparently has the same protocoAPLMODEMASM€ APLMODEMASM€APLMODEMASMAPLMODEM$$$ ; ;SOME TIME-SHARE COMPUTERS REQUIRE TERMINALS TO ;HAVE BIT 7 HIGH (MARKING), SO IN THE TERMINAL ;MODE WE FORCE IT TO HIGH IAPLMODEMASM€ APLMODEMASM€APLMODEMASMAPLMODEM$$$NIT CHAR TO CTL PORT INITC2 EQU 17 ;2ND INIT CHAR TO CTL PORT ; IF CCS ;CCS CARD MODCTLP EQU 0E0A0H ;STATUS PORT OF CCS ACAPLMODEMASM€ APLMODEMASM€APLMODEMASMAPLMODEM$$$L LF EQU 10 ;LINEFEED CR EQU 13 ;CARRIAGE RETURN ; ORG BASE+100H ; ;INIT PRIVATE STACK LXI H,0 ;HL=0 DAD SP ;HL=STACAPLMODEMASM€ APLMODEMASM€APLMODEMASMAPLMODEM$$$E LINE ;PRIOR TO RECEIVE OR SEND ; LDA MODDATP LDA MODDATP ; ;JMP TO APPROPRIATE FUNCTION ; LDA OPTION ;GET PRIMARY OAPLMODEMASM€ APLMODEMASM€APLMODEMASMAPLMODEM$$$..FOR INITIAL NAK ; SENDLP CALL RDSECT ;READ A SECTOR JC SENDEOF ;SEND EOF IF DONE CALL INCRSNO ;BUMP SECTOR # XRA A ;ZEAPLMODEMASM€ APLMODEMASM€APLMODEMASMAPLMODEM$$$R' ;RECEIVE.. JZ RCVFIL ;..A FILE? ; ;INVALID OPTION ; JMP BADOPT ; * * * * * * * * * * * * * * * * * * * * * * * APLMODEMASM€ APLMODEMASM€APLMODEMASMAPLMODEM$$$ * * * * * * * * * * * * * * * * * * * * * * ; ;TERMINAL PROGRAM WITH ECHO - SEE NOTES ;UNDER "TERM" ABOVE ; ;C A U T IAPLMODEMASM€ APLMODEMASM€APLMODEMASMAPLMODEM$$$;COMPUTERS, CBBS'S, OR ANOTHER PROGRAM ;RUNING "MODEM E" (ECHO MODE) ; ;TYPE THE "EXITCHR" (ORIGINALLY CTL-E) TO EXIT. ;OR TAPLMODEMASM€ APLMODEMASM€APLMODEMASMAPLMODEM$$$R CALL STAT ;CHECK LOCAL KB JZ TRMECHO ;..NO CHAR CALL KEYIN ;GET LOCAL CHAR CPI EXITCHR ;END? JZ CKDIS ;YES, CK DISCOAPLMODEMASM€ APLMODEMASM€APLMODEMASMAPLMODEM$$$HR ;TIME TO END? JZ CKDIS ;YES, CK DISCONN CPI DISCCHR ;DISCONNECT REQUEST? JZ DISCONN ;YES, DO IT IF TIMESHR ORI 80H APLMODEMASM€ APLMODEMASM€APLMODEMASMAPLMODEM$$$ TYPE ;TYPE IT JMP TRMECHO ;LOOP ; * * * * * * * * * * * * * * * * * * * * * * * * SENDFIL: SENDS A CP/M FILE * * APLMODEMASM€ APLMODEMASM€APLMODEMASMAPLMODEM$$$ CALL TYPE ;TYPE IT JMP TERM ;LOOP ; * * * * * * * * * * * * * * * * * * * * * * * * TRMECHO: TERMINAL WITH ECHO * * APLMODEMASM€ APLMODEMASM€APLMODEMASMAPLMODEM$$$HECKSUMS, AND RE- ;TRANSMISSION ON ERRORS. ; SENDFIL CALL OPENFIL ;OPEN THE FILE MVI E,80 ;WAIT 80 SEC.. CALL WAITNAK ;APLMODEMASM€ APLMODEMASM€APLMODEMASMAPLMODEM$$$ CPI 'T' ;TERMINAL.. JZ TERM ;..MODE? ; CPI 'D' JZ DISCONN ; CPI 'S' ;SEND.. JZ SENDFIL ;..A FILE? ; CPI 'APLMODEMASM€ APLMODEMASM€APLMODEMASMAPLMODEM$$$SUM CALL GETACK ;GET THE ACK JC SENDRPT ;REPEAT IF NO ACK JMP SENDLP ;LOOP UNTIL EOF ; ;FILE SENT, SEND EOT'S ; SENDEOAPLMODEMASM€ APLMODEMASM€APLMODEMASMAPLMODEM$$$DOWN THE LINE, AND DISPLAYS CHARACTERS ;RECEIVED FROM THE LINE. THIS MAKES IT ;SUITABLE FOR COMMUNICATION WITH TIME SHARING APLMODEMASM€ APLMODEMASM€APLMODEMASMAPLMODEM$$$ ; TRMECHO LDA MODCTLP ;GET STATUS ANI MODRCVB ;ISOLATE READY BIT CPI MODRCVR ;ARE WE READY? JZ LINECHR ;YES, READ THE CHAPLMODEMASM€ APLMODEMASM€APLMODEMASMAPLMODEM$$$IT TO ;BE WRITTEN TO DISK ; TERM CALL STAT ;LOCAL CHAR KEYED? JZ TERML ;..NO, CHECK LINE CALL KEYIN ;GET CHAR CPI EXITCAPLMODEMASM€ APLMODEMASM€APLMODEMASMAPLMODEM$$$ ;..AND LOOP ; ;GOT CHAR FROM LINE ; LINECHR LDA MODDATP ;GET CHAR STA MODDATP ;ECHO IT ANI 7FH ;STRIP PARITY BIT CALLAPLMODEMASM€ APLMODEMASM€APLMODEMASMAPLMODEM$$$S ANI MODRCVB ;ISOLATE BIT CPI MODRCVR ;READY? JNZ TERM ;..NO, LOOP LDA MODDATP ;READ DATA ANI 7FH ;STRIP PARITY BIT APLMODEMASM€ APLMODEMASM€APLMODEMASMAPLMODEM$$$TO ANOTHER ;COMPUTER RUNNING MODEM WITH THE "R" (RECEIVE) ;OPTION. THE DATA IS SENT ONE SECTOR AT A ;TIME WITH HEADERS AND CAPLMODEMASM€ APLMODEMASM€APLMODEMASMAPLMODEM$$$PTION ; CPI 'C' ;(COMPAT W/EARLIER JZ TRMECHO ;OPTION "COMPUTER") ; CPI 'E' ;TERMINAL IN ECHO JZ TRMECHO ;..MODE? ; APLMODEMASM€ APLMODEMASM€APLMODEMASMAPLMODEM$$$RO ERROR.. STA ERRCT ;..COUNT ; SENDRPT CALL SENDHDR ;SEND A HEADER CALL SENDSEC ;SEND DATA SECTOR CALL SENDCKS ;SEND CKAPLMODEMASM€ APLMODEMASM€APLMODEMASMAPLMODEM$$$ * TERM: TERMINAL MODE * * * * * * * * * * * * * * * * * * * * * * * * ; ;THIS PROGRAM SIMPLY SENDS KEYED CHARACTERS ;APLMODEMASM€ APLMODEMASM€APLMODEMASMAPLMODEM$$$ O N DON'T RUN WITH BOTH COMPUTERS ;IN "ECHO" MODE - LINE ERRORS (OR ANY CHAR) ;WILL BE ECHOED BACK AND FORTH AD INFINITUM. APLMODEMASM€ APLMODEMASM€APLMODEMASMAPLMODEM$$$HE "DISCCHR" (ORIGINALLY CTL-D) TO DISCONN. ; ;A FUTURE ENHANCEMENT WILL BE TO WRITE THE ;RECEIVED DATA IN MEMORY, AND ALLOW APLMODEMASM€ APLMODEMASM€APLMODEMASMAPLMODEM$$$NN, EXIT CPI DISCCHR ;DISCONN? JZ DISCONN ;..YES, DO IT. STA MODDATP ;SEND CHAR CALL TYPE ;ECHO IT LOCALLY JMP TRMECHOAPLMODEMASM€ APLMODEMASM€APLMODEMASMAPLMODEM$$$;FORCE BIT 7 TO HIGH ENDIF ;TIMESHR STA MODDATP ;SEND THE CHAR ; ;SEE IF CHAR FROM LINE ; TERML LDA MODCTLP ;READ STATUAPLMODEMASM€ APLMODEMASM€APLMODEMASMAPLMODEM$$$ * * * * * * * * * * * * * * * * * * * * * * ; ;THE CP/M FILE SPECIFIED IN THE MODEM COMMAND ;IS TRANSFERRED OVER THE PHONE APLMODEMASM€ APLMODEMASM€APLMODEMASMAPLMODEM$$$F MVI A,EOT ;SEND.. CALL SEND ;..AN EOT CALL GETACK ;GET THE ACK JC SENDEOF ;LOOP IF NO ACK JMP DONE ;ALL DONE ; * * *APLMODEMASM€ APLMODEMASM€APLMODEMASMAPLMODEM$$$, BLOCK # COMPLEMENTED ; RCVSOH MVI B,1 ;TIMEOUT = 1 SEC CALL RECV ;GET SECTOR JC RCVSTOT ;GOT TIMEOUT MOV D,A ;D=BLK # APLMODEMASM€ APLMODEMASM€APLMODEMASMAPLMODEM$$$ CALL MAKEFIL ;..THEN MAKE NEW CALL ILPRT ;PRINT: DB 'FILE OPEN, READY TO RECEIVE',CR,LF,0 ; RCVLP CALL RCVSECT ;GET A SECAPLMODEMASM€ APLMODEMASM€APLMODEMASMAPLMODEM$$$ MOV B,A ;SAVE CHAR LDA VSEEFLG ;VIEWING.. ORA A ;..MODE? JZ RCVSEH ;YES, PRT.MSG LDA QFLG ;QUIET.. ORA A ;..MODE? APLMODEMASM€ APLMODEMASM€APLMODEMASMAPLMODEM$$$KE UPPER CASE CPI 'Y' ;WANT ERASED? JNZ CKDIS ;QUIT IF NOT ERASE ; ;ERASE OLD FILE ; LXI D,FCB ;POINT TO FCB MVI C,ERAPLMODEMASM€ APLMODEMASM€APLMODEMASMAPLMODEM$$$F ;..IT JM RDBLOCK ;EXHAUSTED? NEED MORE. LHLD SECPTR ;GET POINTER LXI D,BASE+80H ;TO DATA CALL MOVE128 ;MOVE TO BUFFERAPLMODEMASM€ APLMODEMASM€APLMODEMASMAPLMODEM$$$T LIMIT ; ;REACHED ERROR LIMIT ; LDA VSEEFLG ;VIEWING.. ORA A ;..FILE? JZ GACKV ;YES, ASK QUIT/RETRY LDA QFLG ;QUIET.APLMODEMASM€ APLMODEMASM€APLMODEMASMAPLMODEM$$$R ; RDSECLP PUSH B PUSH D MVI C,STDMA ;SET DMA.. CALL BDOS ;..ADDR LXI D,FCB MVI C,READ CALL BDOS POP D POP B APLMODEMASM€ APLMODEMASM€APLMODEMASMAPLMODEM$$$LG ;QUIET.. ORA A ;..MODE? JZ ACKERR ;YES, NO MSG CALL ILPRT ;PRINT: DB 'TIMEOUT ON ACK',CR,LF,0 JMP ACKERR ; ABORTAPLMODEMASM€ APLMODEMASM€APLMODEMASMAPLMODEM$$$ CAN'T MAKE FILE CALL ERXIT DB '++ERROR - CAN''T MAKE FILE',CR,LF DB '++DIRECTORY MUST BE FULL',CR,LF,'$' ; ;----> OPENFAPLMODEMASM€ APLMODEMASM€APLMODEMASMAPLMODEM$$$CONN. ; ;----> INCRSNO: INCREMENT SECTOR # ; INCRSNO LDA SECTNO ;INCR.. INR A ;..SECT.. STA SECTNO ;..NUMBER RET ; ;APLMODEMASM€ APLMODEMASM€APLMODEMASMAPLMODEM$$$T LENGTH: ',0 LDA FCB+15 ;GET # SECTORS CALL HEXO ;PRINT IN HEX CALL ILPRT ;PRINT: DB 'H',CR,LF,0 RET ; ;----> CLOSFAPLMODEMASM€ APLMODEMASM€APLMODEMASMAPLMODEM$$$E Y TO ERASE: ',0 CALL KEYIN ;GET CHAR PUSH PSW CALL TYPE ;ECHO CALL CRLF ;BACK TO START OF LINE POP PSW ANI 5FH ;MAAPLMODEMASM€ APLMODEMASM€APLMODEMASMAPLMODEM$$$D, THIS ROUTINE BUFFERS UP 16 ;SECTORS AT A TIME. ; RDSECT LDA SECINBF ;GET # SECT IN BUFF. DCR A ;DECREMENT.. STA SECINBAPLMODEMASM€ APLMODEMASM€APLMODEMASMAPLMODEM$$$; RDSECOK LXI H,80H ;ADD LENGTH OF ONE SECTOR... DAD D ;...TO NEXT BUFF XCHG ;BUFF TO DE INR C ;MORE SECTORS? MOV A,C APLMODEMASM€ APLMODEMASM€APLMODEMASMAPLMODEM$$$ JZ MONIN ;..YES ; ;CHECK IF "VIEWING" AND THIS IS A DATA CHAR ; LDA VSEEFLG ;VIEWING.. ORA A ;..DATA? JNZ NOMONIN ;..APLMODEMASM€ APLMODEMASM€APLMODEMASMAPLMODEM$$$ ;..POINTER LXI D,BASE+80H ;RESET.. MVI C,STDMA ;..DMA.. CALL BDOS ;..ADDR JMP RDSECT ;PASS SECT TO CALLER ; ;----> WRAPLMODEMASM€ APLMODEMASM€APLMODEMASMAPLMODEM$$$CALL BDOS ;..ADDR RET ; WRERR CALL RSDMA ;RESET DMA TO NORM. CALL ILPRT ;PRINT: DB '++ERROR WRITING FILE',CR,LF,0 JMP APLMODEMASM€ APLMODEMASM€APLMODEMASMAPLMODEM$$$RE CALL MOVE128 ;MOVE TO BUFFER XCHG ;SAVE NEXT.. SHLD SECPTR ;..BLOCK POINTER LDA SECINBF ;BUMP THE.. INR A ;..SECTOAPLMODEMASM€ APLMODEMASM€APLMODEMASMAPLMODEM$$$S "LONG" BEFORE THE ACK/NAK WOULD ;BE RECEIVED. ; RECVDG EQU $ ;RECEIVE W/GARBAGE DELETE LDA MODDATP ;GET A CHAR LDA MODDAPLMODEMASM€ APLMODEMASM€APLMODEMASMAPLMODEM$$$DISK BUFF ; DKWRLP PUSH H PUSH D PUSH B MVI C,STDMA ;SET DMA CALL BDOS ;TO BUFFER LXI D,FCB ;THEN WRITE MVI C,WRITAPLMODEMASM€ APLMODEMASM€APLMODEMASMAPLMODEM$$$DRCVR ;READY? JZ MCHAR ;GOT CHAR DCR E ;COUNT.. JNZ MWTI ;..DOWN.. DCR D ;..FOR.. JNZ MWTI ;..TIMEOUT DCR B ;MORE SEAPLMODEMASM€ APLMODEMASM€APLMODEMASMAPLMODEM$$$T # OF SECTORS LXI H,DBUF ;RESET BUFFER.. SHLD SECPTR ;..POINTER ; RSDMA LXI D,BASE+80H ;RESET.. MVI C,STDMA ;..DMA.. APLMODEMASM€ APLMODEMASM€APLMODEMASMAPLMODEM$$$;ADD TO CHECKSUM MOV C,A ;SAVE CHECKSUM ; ;CHECK IF MONITORING REC'D DATA ; LDA RSEEFLG ;SEE RECEIVED.. ORA A ;..DATA? APLMODEMASM€ APLMODEMASM€APLMODEMASMAPLMODEM$$$ MOV A,C ; ;BUFFER IS FULL, OR GOT EOF ; RDBFULL STA SECINBF ;STORE SECTOR COUNT LXI H,DBUF ;INIT BUFFER.. SHLD SECPTRAPLMODEMASM€ APLMODEMASM€APLMODEMASMAPLMODEM$$$TA ; MONIN POP PSW ;..IS DATA, PUSH PSW ;GET IT, CALL SHOW ;..AND SHOW IT ; NOMONIN POP PSW ;RESTORE CHAR ORA A ;CARRYAPLMODEMASM€ APLMODEMASM€APLMODEMASMAPLMODEM$$$INT "WRBLOCK" FLUSHES THE BUFFER AT EOF. ; WRSECT LHLD SECPTR ;GET BUFF ADDR XCHG ;TO DE FOR MOVE LXI H,BASE+80H ;FROM HEAPLMODEMASM€ APLMODEMASM€APLMODEMASMAPLMODEM$$$ARACTERS ON THE ;LINE. FOR EXAMPLE, HAVING JUST SENT A SECTOR, ;CALLING RECVDG WILL DELETE ANY LINE-NOISE-INDUCED ;CHARACTERAPLMODEMASM€ APLMODEMASM€APLMODEMASMAPLMODEM$$$CK LDA SECINBF ;# SECT IN BUFFER ORA A ;0 MEANS END OF FILE RZ ;NONE TO WRITE MOV C,A ;SAVE COUNT LXI D,DBUF ;POINT TO APLMODEMASM€ APLMODEMASM€APLMODEMASMAPLMODEM$$$;NEW TIME IN B ENDIF ; MSEC LXI D,50000 ;1 SEC DCR COUNT MWTI LDA MODCTLP ;CHECK STATUS ANI MODRCVB ;ISOLATE BIT CPI MOAPLMODEMASM€ APLMODEMASM€APLMODEMASMAPLMODEM$$$HL= NEXT BUFF XCHG ;TO DE FOR SETDMA DCR C ;MORE SECTORS? JNZ DKWRLP ;..YES, LOOP XRA A ;GET A ZERO STA SECINBF ;RESEAPLMODEMASM€ APLMODEMASM€APLMODEMASMAPLMODEM$$$HAR FROM MODEM ; MCHAR LDA MODDATP ;READ THE CHAR POP D ;RESTORE DE ; ;CALC CHECKSUM ; PUSH PSW ;SAVE THE CHAR ADD C APLMODEMASM€ APLMODEMASM€APLMODEMASMAPLMODEM$$$;GET COUNT CPI 16 ;DONE? JZ RDBFULL ;..YES, BUFF IS FULL JMP RDSECLP ;READ MORE ; REOF MVI A,1 STA EOFLG ;SET EOF FLAGAPLMODEMASM€ APLMODEMASM€APLMODEMASMAPLMODEM$$$NO ; ;"VIEW" REQUESTED. SHOW THE CHAR IT IS DATA ; LDA DATAFLG ;GET DATA FLAG ORA A ;TEST IT JZ NOMONIN ;..OFF, NOT DAAPLMODEMASM€ APLMODEMASM€APLMODEMASMAPLMODEM$$$SECT: WRITE A SECTOR ; ;WRITES THE SECTOR INTO A BUFFER. WHEN 16 ;HAVE BEEN WRITTEN, WRITES THE BLOCK TO DISK. ; ;ENTRY POAPLMODEMASM€ APLMODEMASM€APLMODEMASMAPLMODEM$$$ABORT ;EXIT ; ;----> RECV: RECEIVE A CHARACTER ; ;TIMEOUT TIME IS IN B, IN SECONDS. ENTRY VIA ;"RECVDG" DELETES GARBAGE CHAPLMODEMASM€ APLMODEMASM€APLMODEMASMAPLMODEM$$$R #.. STA SECINBF ;..IN THE BUFF CPI 16 ;HAVE WE 16? RNZ ;NO, RETURN ; ;----> WRBLOCK: WRITES A BLOCK TO DISK ; WRBLOAPLMODEMASM€ APLMODEMASM€APLMODEMASMAPLMODEM$$$ATP ;..TOTALLY PURGE UART ; RECV PUSH D ;SAVE ; IF FASTCLK ;4MHZ? MOV A,B ;GET TIME REQUEST ADD A ;DOUBLE IT MOV B,A APLMODEMASM€ APLMODEMASM€APLMODEMASMAPLMODEM$$$E ;..THE.. CALL BDOS ;..BLOCK POP B POP D POP H ORA A JNZ WRERR ;OOPS, ERROR LXI H,80H ;LENGTH OF 1 SECT DAD D ;APLMODEMASM€ APLMODEMASM€APLMODEMASMAPLMODEM$$$CONDS? JNZ MSEC ;YES, WAIT ; ;MODEM TIMED OUT RECEIVING ; POP D ;RESTORE D,E STC ;CARRY SHOWS TIMEOUT RET ; ;GOT CAPLMODEMASM€ APLMODEMASM€APLMODEMASMAPLMODEM$$$ OFF: NO ERROR RET ;FROM "RECV" ; ;----> SEND: SEND A CHARACTER TO THE MODEM ; SEND PUSH PSW ;SAVE THE CHAR ; ;CHECK IFAPLMODEMASM€ APLMODEMASM€APLMODEMASMAPLMODEM$$$ ; ENDOPT LDA VSEEFLG ;VIEW.. ORA A ;..ASKED FOR? RNZ ;..NO, RET FROM 'PROCOPT' STA QFLG ;YES, NO HDR/CKSUM PRT RET APLMODEMASM€ APLMODEMASM€APLMODEMASMAPLMODEM$$$..NO. ; MONOUT POP PSW ;GET THE CHAR PUSH PSW ;SAVE IT CALL SHOW ;SHOW IT ; NOMONOT POP PSW ;RESTORE CHAR PUSH PSW ;SAAPLMODEMASM€ APLMODEMASM€APLMODEMASMAPLMODEM$$$ADR LHLD BASE+1 ;GET WARM BOOT ADDR LXI D,3 ;LENGTH OF A 'JMP' DAD D ;TO CONSOLE STAT SHLD VSTAT+1 ;MODIFY CALL DAD D ;TAPLMODEMASM€ APLMODEMASM€APLMODEMASMAPLMODEM$$$TIAL NAK ; ;TO ENSURE NO DATA IS SENT UNTIL THE RECEIVING ;PROGRAM IS READY, THIS ROUTINE WAITS FOR THE ;THE FIRST TIMEOUT-NAPLMODEMASM€ APLMODEMASM€APLMODEMASMAPLMODEM$$$ THE APPROPRIATE ENTRY IN ;THE OPTION TABLE. FOR EXAMPLE, IF 'D' IS ;CODED (DISCONNECT) THEN THE 'D' STORED AT ;'DISCFLG' IAPLMODEMASM€ APLMODEMASM€APLMODEMASMAPLMODEM$$$LF,0 ; WAITNLP MVI B,1 ;TIMEOUT DELAY CALL RECV ;DID WE GET.. CPI NAK ;..A NAK? RZ ;YES, SEND BLOCK DCR E ;80 TRIES? APLMODEMASM€ APLMODEMASM€APLMODEMASMAPLMODEM$$$G, SINCE ;THERE WON'T BE A ' ' AFTER THE OPTION ;IF A BAUD RATE WAS SPECIFIED. ; CPI ' ' ;NO MORE OPT'NS? JZ ENDOPT ;..YEAPLMODEMASM€ APLMODEMASM€APLMODEMASMAPLMODEM$$$LLOW CHARACTERS SUCH AS CONTROL-C ;AND CONTROL-S TO BE KEYED WHILE IN TERMINAL ;MODE, WITHOUT CP/M INTERPRETING THEM. ; INITAPLMODEMASM€ APLMODEMASM€APLMODEMASMAPLMODEM$$$ DCR B ;MORE? JNZ OPTCK ;OPTION NOT IN TABLE JMP BADOPT ;SHOW BAD SUB OPTION ; ;IF "VIEW" WAS ASKED FOR, SET QUIET FLAGAPLMODEMASM€ APLMODEMASM€APLMODEMASMAPLMODEM$$$E FILE ; LDA VSEEFLG ;GET VIEW FLAG ORA A ;TEST IT JNZ NOMONOT ;NO LDA DATAFLG ;IS THIS ORA A ;..DATA? JZ NOMONOT ;APLMODEMASM€ APLMODEMASM€APLMODEMASMAPLMODEM$$$ ;..MODE? JZ DONECTE ;YES, CK TERM/ECHO ; DONETC CALL ILPRT DB CR,LF,'TRANSFER COMPLETE' DB CR,LF,0 ; ;CHECK IF TERMIAPLMODEMASM€ APLMODEMASM€APLMODEMASMAPLMODEM$$$EADY? JNZ SENDW ;..NO, WAIT POP PSW ;GET CHAR STA MODDATP ;OUTPUT IT RET ;FROM "SEND" ; ;----> WAITNAK: WAITS FOR INIAPLMODEMASM€ APLMODEMASM€APLMODEMASMAPLMODEM$$$COMMAND OPTIONS ; ;1) SAVES THE PRIMARY OPTION IN 'OPTION'; ;2) SCANS THE SUB-OPTION CHARACTERS, AND FOR ;EACH FOUND, ZEROSAPLMODEMASM€ APLMODEMASM€APLMODEMASMAPLMODEM$$$ LDA QFLG ;QUIET.. ORA A ;..MODE? JZ WAITNLP ;YES, SKIP MSG ; WAITNPR CALL ILPRT ;PRINT: DB 'AWAITING INITIAL NAK',CR,APLMODEMASM€ APLMODEMASM€APLMODEMASMAPLMODEM$$$ OPTLP INX D ;TO SECONDARY OPTION LDAX D ;GET CHAR ; ;IF YOU MOD THIS PROGRAM FOR >7 OPTIONS, ;YOU MUST CHANGE THE FOLLOWINAPLMODEMASM€ APLMODEMASM€APLMODEMASMAPLMODEM$$$RESSES OF VARIOUS ;JMP AND CALL INSTRUCTIONS, SO THAT CP/M BDOS ;IS BYPASSED WHILE ACCESSING THE CONSOLE. THIS ;IS DONE TO AAPLMODEMASM€ APLMODEMASM€APLMODEMASMAPLMODEM$$$;FOUND THE OPTION? JNZ OPTNO ;NO, DON'T SET IT MVI M,0 ;SET THE OPTION JMP OPTLP ;GET NEXT OPTION ; OPTNO INX H ;TO NEXTAPLMODEMASM€ APLMODEMASM€APLMODEMASMAPLMODEM$$$ MONITORING SENT DATA ; LDA SSEEFLG ;CHECK IF MONITORING.. ORA A ;..SENT DATA JZ MONOUT ;..YES ; ;CHECK IF "VIEWING" THAPLMODEMASM€ APLMODEMASM€APLMODEMASMAPLMODEM$$$;FROM 'PROCOPT' ; ;DONE - CLOSE UP SHOP ; DONE LDA VSEEFLG ;VIEWING? ORA A JZ DONETC ;SHOW MSG LDA QFLG ;QUIET ORA AAPLMODEMASM€ APLMODEMASM€APLMODEMASMAPLMODEM$$$VE IT ADD C ;CALC CKSUM MOV C,A ;SAVE CKSUM SENDW LDA MODCTLP ;GET STATUS ANI MODSNDB ;ISOLATE READY BIT CPI MODSNDR ;RAPLMODEMASM€ APLMODEMASM€APLMODEMASMAPLMODEM$$$O CONSOLE IN SHLD VKEYIN+1 ;MODIFY CALL DAD D ;TO CONSOLE OUT SHLD VTYPE+1 ;MODIFY CALL RET ; ;----> PROCOPT: PROCESS APLMODEMASM€ APLMODEMASM€APLMODEMASMAPLMODEM$$$AK FROM THE RECEIVER. ;(E) CONTAINS THE # OF SECONDS TO WAIT. ; WAITNAK LDA VSEEFLG ;VIEWING? ORA A JZ WAITNPR ;PRINT MSGAPLMODEMASM€ APLMODEMASM€APLMODEMASMAPLMODEM$$$S SET TO 0 SO IT CAN BE TESTED ;LATER. ; PROCOPT LXI D,FCB+1 ;TO PRIMARY OPT. LDAX D ;GET PRIMARY STA OPTION ;SAVE IT ; APLMODEMASM€ APLMODEMASM€APLMODEMASMAPLMODEM$$$ JZ ABORT ;YES, ABORT JMP WAITNLP ;NO, LOOP ; ;----> INITADR: INIT'S CP/M BDOS ADDRESSES ; ;THIS ROUTINE FILLS IN THE ADDAPLMODEMASM€ APLMODEMASM€APLMODEMASMAPLMODEM$$$S ;SET THE APPROP. OPT: STORE 0 IN IT LXI H,OPTBL ;HL = ADDR OF 'OAQDSRV' MVI B,OPTBE-OPTBL ;OPT TABLE LEN ; OPTCK CMP M APLMODEMASM€ APLMODEMASM€APLMODEMASMAPLMODEM$$$NAL OR ECHO SUB COMMAND ;WAS SPECIFIED ; DONECTE LDA TERMFLG ;TERM? ORA A JZ TERM ;..YES LDA ECHOFLG ;ECHO? ORA A JAPLMODEMASM€ APLMODEMASM€APLMODEMASMAPLMODEM$$$ GETBAUD LDA FCB+9 ;GET FILETYPE CPI ' ' ;DEFAULT? JNZ GETBAU1 ;NO - DO BAUD RATE STUFF MVI B,11H ;300 BAUD STATUS CODE ååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååJZ ILPRET ;..YES, RETURN CPI 1 ;PAUSE? JZ ILPAUSE ;..YES CALL CTYPE ;TYPE THE MSG ; ILPNEXT INX H ;TO NEXT CHAR JMP ILåååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååå ITSELF) IS ; DATAFLG DB 0 ;AT HEADER, FIRST ; ; ;SUB-OPTION TABLE. IF AN OPTION IS IN EFFECT, ; THE CHARACTER IS SET TO åååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååå ILPRET XTHL ;RESTORE HL RET ;PAST MSG ; ;----> PRTMSG: PRINTS MSG POINTED TO BY (DE) ; ;A '$' IS THE ENDING DELIMITER åååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååå WHAT'S SENT TERMFLG DB 'T' ;TO TERM AFTER XFER VSEEFLG DB 'V' ;VIEW MESSAGES (NO HDR, ETC) OPTBE EQU $ ;END OF OPTIONS ; RååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååHT ; NIBBL ANI 0FH ;ISOLATE DIGIT CPI 10 ;IS IS <10? JC ISNUM ;YES, NOT ALPHA ADI 7 ;ADD ALPHA BIAS ; ISNUM ADI '0' ;MååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååECTORS IN BUFFER DS 60 ;STACK AREA STACK DS 2 ;STACK POINTER ; ;16 SECTOR DISK BUFFER (OVERLAYS HELP MSGS) ; DBUF EQU $ ;ååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååYPE Q TO QUIT, R TO RETRY: ',0 CALL KEYIN ;QUIT/RETRY PUSH PSW CALL TYPE CALL CRLF POP PSW ANI 5FH ;MAKE UPPER CASE ååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååK ;GET ORIGINAL STACK SPHL ;RESTORE IT RET ;--EXIT-- TO CP/M ; ;MOVE 128 CHARACTERS ; MOVE128 MVI B,128 ;SET MOVE COUNååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååSE (MESSAGE 'PRESS RETURN TO CONTINUE') ; ILPRT XTHL ;SAVE HL, GET HL=MSG ; ILPLP MOV A,M ;GET CHAR ORA A ;END OF MSG? ååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååFLG IS USED BY THE "V" SUBCOMMAND - ;IT IS 0 WHEN A HEADER OR CKSUM IS BEING ;SENT/RCD, AND 1 IF "VIEWABLE" DATA (THE ;SECTORåååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååå'PRESS RETURN TO CONTINUE' DB CR,LF,0 CALL KEYIN ;GET ANY CHAR CPI 'C'-40H ;REBOOT? JZ EXIT ;YES. JMP ILPNEXT ;LOOP ;åååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååå ORIGFLG DB 'O' ;ORIGINATE MODE QFLG DB 'Q' ;QUIET TRANSFER (NO MSGS) RSEEFLG DB 'R' ;SEE WHAT'S RECEIVED SSEEFLG DB 'S' ;SEEååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååB 'COMMAND - ',CR,LF DB 'PRESS RETURN FOR HELP, CTL-C IF NOT',CR,LF,1,0 ; HELP CALL ILPRT DB 'Format for command is:',cr,låååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååå disk drives: ; ; - STANDARD 8" SINGLE DENSITY ; - MICROPOLIS MOD II ; - MICROMATION DOUBLE DENSITY ; - DIGITAL MICROSYSTEMåååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååå send a file',cr,lf DB ' R to receive a file',cr,lf DB ' T to act as a terminal',cr,lf DB ' E to act as a computer (echo d