PCjs Machines

Home of the original IBM PC emulator for browsers.

Logo

PC-SIG Diskette Library (Disk #54)

[PCjs Machine "ibm5150"]

Waiting for machine "ibm5150" to load....

Information about “XMODEM”

XMODEM is a communications program that imposes no restrictions on
the contents of the data being transmitted.  Any kind of data may be
sent-- binary, ASCII, etc.

This IBM Asynchronous Communication Support Program provides software
needed to allow the personal computer to communicate with a wide variety
of computer systems including several IBM mainframe computers.  It
emphasizes great flexibility in communications and provides a protocol
for file transfer between personal computers.

The user must be technically competent in communications protocol to be
able to properly set selectable  parameters provided through various
menus.  A user-friendly design has been substantially ignored.

Features:
~ A 64K version named SHORTERM.BAS, and a 96K version
named LONGTERM.BAS
~ Automatic selection of screen width and an option to
bypass all intermediate menus
~ Preselected parameters for Display Selection and Dialing
Option for the Hayes Smartmodem
~ Download capability, including error trapping, file
directory printout, On/Off switching of data recording
for open files, and status indicator
~ Upload capability, including error trapping, file directory
printout, On/Off switching, status indication
~ Time/Date/Status line
~ Telephone/LOG-ON menu and function
~ Automatic enabling of error messages upon terminal startup
~ Error trapping routines supported in many areas for printer
applications
~ Changes to preset terminal parameters, facilitating program
initialization in full duplex mode and bypassing of menus.

System Requirements:  Some programs require BASIC; two disk drives,
modem

How to Start:  From DOS, enter TYPE TUTORIAL to access a tutorial on
IBM ASYNC COM PROGRAM.  To read the documentation on XMODEM, enter
TYPE MODEM.DOC. To run it, type XMODEM and press <ENTER>.

File Descriptions:

TUTORIAL      Tutorial for IBM ASYNC COM PROGRAM
DESCRIPT ION  Description for IBM ASYNC COM PROGRAM modifications
PROGRAMN OTE  Programming notes for IBM ASYNC COM PROGRAM modifications
LONGTERM BAS  96K version - see PROGRAMN.OTE
SHORTERM BAS  64K version - see PROGRAMN.OTE
XMODEM   DOC  Documentation for XMODEM.COM
XMODEM   ASM  Source code  (52K)
-------- ---  XMODEM
PROFEEL       Sony Profeel monitor modifications (Text file)
XMODEM   COM  Modem communication program  (DOS 1.1)

CRC.TXT

PC-SIG Disk No. #54, version v1_1

The following is a list of the file checksums which should be produced by
the CRCK4 program on disk #9 (and others).  If the CRC numbers do not match
you may have a bad file.  To use type:  CRCK4 <filespec>

CRCK4 output for this disk:


CRCK ver 4.2B (MS DOS VERSION )
CTL-S pauses, CTL-C aborts

--> FILE:  TUTORIAL.            CRC = 00 FB

--> FILE:  XMODEM  .ASM         CRC = B8 A1

--> FILE:  XMODEM  .DOC         CRC = BF C0

--> FILE:  XMODEM  .COM         CRC = B4 3D

--> FILE:  PROGRAMN.OTE         CRC = 07 59

--> FILE:  DESCRIPT.ION         CRC = 72 E1

--> FILE:  PROFEEL .            CRC = 14 0E

--> FILE:  SHORTERM.BAS         CRC = F0 63

--> FILE:  LONGTERM.BAS         CRC = 39 A7

 ---------------------> SUM OF CRCS = E5 EB

DONE

These and other Public Domain and user-supported programs from:

PC Software Interest Group
1125 Stewart Ct  Suite G
Sunnyvale, CA 94086
(408) 730-9291

LONGTERM.BAS

1 'LONGTERM.BAS ....Enhancements to IBM Async. Comm.   V1.02   (96KB)  4/24/82
2 'By Robert C. Rice, Upload/Download based on a program by Morris E. Thompson
115 DEF SEG=&H1700
200 CLEAR
210 IDSEG=&H1700
223 IF LEFT$(TIME$,4)="00:0" THEN NTME=TRUE ELSE NTME=FALSE
330 DIM ERM$(21) 'error msg array
400 DIM TRMNL$(ICN+1)
410 TRMNL$(1)="IBM VM/370"
420 TRMNL$(2)="IBM MVS TSO"
430 TRMNL$(3)="Half Duplex"
440 TRMNL$(4)="Full Duplex"
450 TRMNL$(5)="PC Computer"
460 TRMNL$(6)="User Defined"
605 DATA 1,1,0,0,0,0,1,0,0,0,0,0,0,0,0,1,1,0,0,0
615 DATA 1,1,0,0,0,0,1,0,0,0,0,0,0,0,0,1,1,0,0,0
625 DATA 1,1,1,0,0,0,1,1,0,1,1,1,0,0,1,1,1,0,0,0
635 DATA 1,1,1,0,0,1,1,0,1,1,1,1,0,0,1,1,1,0,0,0
645 DATA 1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,1,0,0,0
745 DATA 4,4,1,0,1,0,1,2,0,3,6,1,0,1,1,0,1,0,0,0
755 DATA 4,4,1,0,2,2,1,0,1,2,5,6,0,2,5,0,1,0,0,0
765 DATA 4,4,1,0,1,0,1,2,0,3,6,1,0,0,1,0,1,0,0,0
775 DATA 4,3,1,0,2,1,1,0,2,2,3,7,0,0,1,0,1,0,0,0
781 DATA 4,3,1,0,2,1,1,0,1,1,1,1,0,3,1,0,1,0,0,0
866 NA$(16)="Select Display"
867 NA$(17)="Select Modem Dial Option"
937 VDO=40:DEF SEG=0:IF(PEEK(&H410)AND &H30)=&H30 THEN IWT=80 ELSE IWT=VDO
938 WIDTH IWT:LOCATE 10,1,0:IF IWT=80 THEN S1PC=INT(IWT/4)+2 ELSE S1PC=1
939 PRINT SPC(S1PC):PRINT"       The IBM Personal Computer"
940 PRINT SPC(S1PC):PRINT"  Asynchronous Communications Support"
941 PRINT SPC(S1PC):PRINT"This 96KB Version Modified and Enhanced"
942 PRINT SPC(S1PC):PRINT"           by Robert C. Rice"
943 PRINT SPC(S1PC):PRINT"   Upload/Download based on a program"
944 PRINT SPC(S1PC):PRINT"         by Morris E. Thompson"
945 PRINT:PRINT
949 IF IWT=80 THEN S2PC=INT(IWT/4)+6 ELSE S2PC=5
950 COLOR 15,0:LOCATE ,S2PC
960 PRINT "Bypass intermediate menus (y/n)?";:COLOR 7,0
961 K$=INKEY$:IF K$="" THEN 961
965 IF K$="y" OR K$="Y" THEN OP1T=1:GOTO 970
966 IF K$="n" OR K$="N" THEN OP1T=0 ELSE GOSUB 20400:GOTO 961
1050 IF OP1T=0 THEN GOSUB 20200 ELSE IMEN=4:GOTO 1065
1066 TMSL$=TRMNL$(IMEN)
1170 TITLE$=TMSL$+" Terminal Feature"
1185 IF OP1T=0 THEN GOSUB 20200 ELSE IMEN=IMAX-2:GOTO 1500
1520 ON IP GOSUB 6000,6200,6400,9000,6800,7000,7200,7400,7500,7600,7625,7660,9000,9000,7800,7900,8000,9000,9000,9000
1800 GOSUB 35000 'Init. Term. Operation
1811 BKS$=CHR$(8):ENDD$=CHR$(79):HMNU$=CHR$(35):SMART=TRUE
1812 SNRC$=CHR$(31):HELP$=CHR$(63):IDSW$=CHR$(64):PRSW$=CHR$(65):LGSW$=CHR$(68)
1813 PLMX$=CHR$(25):UPSW$=CHR$(67):DIAL$=CHR$(66):HOME$=CHR$(71):BCSR$=CHR$(75)
1820 IDPR=FALSE:IPRR=FALSE:IPY=FALSE:LON=FALSE:ULON=FALSE:INIT=TRUE
2005 D%=512+ASC(BKS$):CALL SS(C%,T%,D%,E%)
2024 ISS=5:DTA%=1:T%=7:GOSUB 15000:GOSUB 2788
2025 PRINT"Starting up as a "+TMSL$+" Terminal"
2027 X=FRE("x"):PRINT:GOSUB 31000:GOSUB 31130
2480 LOCATE 25,IWT-17,0:PRINT"F5=HELP RECEIVING";:LOCATE 24,1,1
2531 IF LG THEN GOSUB 17310
2551 IF K$=PLMX$ OR K$=DIAL$ OR K$=LGSW$ OR K$=UPSW$ GOTO 2552 ELSE GOTO 2553
2552 E%=0:ERM$(0)="Must be SENDING to use that key":GOSUB 3600:GOTO 2500
2553 IF K$<>PRSW$ GOTO 2555
2554 IF IPRR THEN IPRR=FALSE:PTR$=" " ELSE IPRR=TRUE:PTR$="P"
2555 IF K$=GOMEN$ GOTO 2800
2556 IF K$=HELP$ THEN GOSUB 31000 ELSE IF K$=HMNU$ GOTO 2552
2602 ITEM=POS(X):LOCATE 25,IWT-17,0
2603 PRINT "F5=HELP   SENDING";
2710 CALL BR(C%,E%):PRINT "Break Sent"
2712 ON ERROR GOTO 3440:IF IPRR THEN LPRINT "Break Sent"
2713 ON ERROR GOTO 0
2751 IF K$=HOME$ THEN INIT=TRUE:LGGR=0:RETURN
2752 IF K$=BCSR$ THEN IF LGGR>0 THEN LGGR=LGGR-1:RETURN ELSE RETURN
2753 IF K$=ENDD$ THEN INIT=FALSE:LGGR=4:RETURN
2754 IF K$=HMNU$ THEN GOSUB 32580:RETURN
2755 IF K$=PLMX$ THEN PRINT "Max. Receive Buffer Space Used = ";LM:LM=0:RETURN
2756 IF K$<>LGSW$ THEN 2760
2757 E%=0:IF NOT LG THEN ERM$(0)="Logging File Not Open":GOSUB 3600:RETURN
2758 DNTSY=7:IF LON THEN LON=FALSE ELSE LON=TRUE:DNTSY=31
2759 GOSUB 33010:RETURN
2761 IF K$<>UPSW$ THEN 2765
2762 IF NOT IU THEN GOSUB 17520:RETURN
2763 UNTSY=7:IF ULON THEN ULON=FALSE ELSE ULON=TRUE:UNTSY=31
2764 GOSUB 33010:RETURN
2766 IF K$=HELP$ THEN GOSUB 31000:RETURN
2768 IF K$=DIAL$ AND INIT THEN GOSUB 32000:RETURN
2769 IF K$=DIAL$ AND NOT INIT THEN GOSUB 32420:RETURN
2775 IF IDPR THEN IDPR=FALSE :HXL$=" " ELSE IDPR=TRUE:HXL$="H"
2776 GOSUB 33010:RETURN
2783 IF IPRR THEN IPRR=FALSE ELSE IPRR=TRUE
2784 PTR$=" ":IF IPRR THEN PTR$="P"
2785 GOSUB 33010:RETURN
2803 IMAX=12:IT=MPARM(14)
2808 C$(3)="Return to BASIC (pause)"
2809 IF LG THEN C$(4)="Close log file: "+LG$ ELSE C$(4)="Open log file"
2810 IF IU THEN C$(5)="Close upload file: "+UP$ ELSE C$(5)="Open upload file"
2811 C$(6)="Terminate Comm. go to BASIC"
2812 C$(7)="Terminate Comm. go to DOS"
2813 IF IT=0 THEN IMAX=7:GOTO 2835
2814 C$(8)="Upload   (VM/370,TSO)"
2815 C$(9)="Download (VM/370,TSO)"
2820 C$(10)="Compare  (VM/370,TSO)"
2822 IF IT<3 THEN IMAX=10:GOTO 2835
2825 C$(11)="Transmit a Personal Computer File"
2830 C$(12)="Receive  a Personal Computer File"
2843 IF IMEN>7 AND IMEN<11 AND IT=3 THEN PRINT "Not Used between Personal Computers":GOTO 13370
2844 IF IMEN=2 THEN OP1T=0
2845 ON IMEN GOTO 3400,970,3430,17200,17410,34000,34010,14000,13000,13050,16200,16500
3100 ON ERROR GOTO 3440:IF IPRR THEN LPRINT B$;
3101 ON ERROR GOTO 0
3400 GOSUB 13030:IF JO THEN CALL SN(C%,XON$,E%)
3405 PRINT "Back as a "+TMSL$+" Terminal":IF MPARM(5)=1 GOTO 2601 ELSE GOTO 5000
3430 CLS:PRINT "You are back in BASIC."
3432 PRINT "Use F5 to return to Terminal Operation":KEY 5,"CONT"+CHR$(13):STOP
3435 KEY 5,"":GOTO 2800
3440 IF ERR=24 OR ERR=27 THEN 3445 ELSE 3450
3445 PTR$=" ":IPRR=FALSE:GOSUB 3540:E%=20:GOSUB 3600:GOSUB 33010:RESUME
3450 ON ERROR GOTO 0
3540 ERM$(20)="ERROR ="+STR$(ERR)+" ** Printer off"
3544 RETURN
3815 PRINT STRING$(40," ");
3825 PRINT STRING$(40," ");:LOCATE ,2:PRINT MSTK$(ICMP);
3955 IF (D% AND 4)>0 THEN E%=16:RETURN
5002 TERM$=LE$:TME=61
5106 IF RIGHT$(B$,1)<>BKS$ THEN 5110
5107 IF LEN(B$)>1 THEN B$=LEFT$(B$,LEN(B$)-2) ELSE GOSUB 2720:GOTO 5200
5110 IF LL<>IWT OR B$<>CR$ THEN PRINT B$;ELSE 5200
5113 ON ERROR GOTO 3440
5115 IF IPRR THEN LPRINT B$;
5116 ON ERROR GOTO 0
5200 GOSUB 33000:GOSUB 2590
5201 IF NOT IU GOTO 5205
5202 IF ULON THEN IF ISF THEN GOSUB 17510
5215 GOSUB 2750:IF K$=GOMEN$ GOTO 5290 ELSE GOTO 5030
5265 ON ERROR GOTO 3440:IF IPRR THEN LPRINT K$;
5266 ON ERROR GOTO 0
5290 IF JO THEN CALL SN(C%,XOFF$,E%)
5300 GOTO 2800
7900 'Menu for Display selection
7910 TITLE$="Display"
7920 C$(1)="Monochrome Display"
7930 C$(2)="Color Video Monitor"
7940 IMAX=2
7950 GOSUB 20200
7960 GOSUB 20100
7970 RETURN
8000 'Menu for Modem dial Option
8010 TITLE$="Type of Modem Dialing"
8020 C$(1)="Touch Tone"
8030 C$(2)="Pulse Dialing"
8040 IMAX=2
8050 GOSUB 20200
8060 GOSUB 20100
8070 RETURN
17200 IF LG THEN CLOSE#3:LG$="":LG=FALSE:DLN$=" ":GOTO 2800
17210 CLS:GOSUB 17660:PRINT "What is the name of the local file "
17220 PRINT "to which you wish to log?":PRINT "(ENTER alone returns to Menu)"
17230 INPUT X$:IF X$="" THEN 2800
17240 GOSUB 20300:LG$=Y$:ON ERROR GOTO 17260
17250 OPEN LG$ FOR APPEND AS 3:M$="":GOTO 17290
17260 IF ERR=67 THEN M$="Too many files open":GOTO 17280
17270 M$="FILE ACCESS FAILED. BASIC ERROR "+STR$(ERR)
17280 RESUME 17290
17290 ON ERROR GOTO 0:IF M$ <> "" THEN GOSUB 14032:GOTO 17230
17300 DLN$="L":DNTSY=31:LG=TRUE:LON=TRUE:GOTO 2800
17310 ON ERROR GOTO 17370
17320 IF NOT LON GOTO 17400 ELSE IF (LEN(LL$)+LEN(B$))<=255 GOTO 17350
17330 LLN=LEN(LL$):LL$=LL$+LEFT$(B$,255-LLN):PRINT#3,LL$
17340 LL$="":B$=RIGHT$(B$,LEN(B$)-255-LLN))
17350 LL$=LL$+B$:IF R$<>CR$ AND R$<>LE$ GOTO 17400
17360 PRINT#3,LEFT$(LL$,LEN(LL$)-1):LL$="":GOTO 17400
17370 IF ERR=61 THEN ERM$(0)="Disk full, Log file closed":GOTO 17390
17380 ERM$(0)="Disk Error, BASIC Err= "+STR$(ERR)
17390 E%=0:GOSUB 3600:LG=FALSE:LON=FALSE:DLN$=" ":GOSUB 33010:RESUME NEXT
17400 ON ERROR GOTO 0:RETURN
17405 'Upload
17410 IF IU THEN CLOSE#1:UP$="":IU=FALSE:ULON=FALSE:ULN$=" ":GOTO 2800
17420 CLS:GOSUB 17660:PRINT "What is the name of the local file "
17430 PRINT "which you wish to upload?":PRINT "(ENTER alone returns to Menu)"
17440 INPUT X$:IF X$="" THEN 2800 ELSE GOSUB 20300:LET UP$=Y$
17450 ON ERROR GOTO 17460:OPEN "I",1,UP$:M$="":GOTO 17490
17460 IF ERR=53 THEN M$="File "+UP$+" not found":GOTO 17480
17470 M$="File access failed. BASIC error "+STR$(ERR)
17480 RESUME 17490
17490 ON ERROR GOTO 0:IF M$<>"" THEN GOSUB 14032:GOTO 17440
17500 IU=TRUE:UNTSY=7:ULN$="U":ULON=FALSE:GOTO 2800
17510 T%=1:CALL BF(C%,T%,D%,E%):IF D%<>0 THEN RETURN
17520 IF NOT IU THEN ERM$(0)="Upload not active":E%=0:GOSUB 3600:RETURN
17530 IF EOF(1) THEN CLOSE#1:ERM$(0)="Upload complete, file closed" ELSE 17550
17540 E%=0:GOSUB 3600:IU=FALSE:ULON=FALSE:ULN$=" ":GOSUB 33010:UP$="":RETURN
17550 ON ERROR GOTO 17620:IF UL$="" THEN LINE INPUT#1,UL$:ON ERROR GOTO 0
17560 IF ILE THEN PRINT UL$
17570 ON ERROR GOTO 3440:IF IPRR THEN LPRINT UL$
17580 ON ERROR GOTO 0
17590 CALL SN(C%,UL$,E%):IF E%>-1 THEN GOSUB 3600
17600 CALL SN(C%,TSEND$,E%):IF E%>-1 THEN GOSUB 3600
17610 UL$="":RETURN
17620 CLOSE#1:UP$="":IU=FALSE:ULON=FALSE:ULN$=" ":GOSUB 33010:E%=0
17630 ERM$(0)="Disk Error, BASIC Err= "+STR$(ERR):GOSUB 3600:RESUME 17640
17640 ON ERROR GOTO 0:RETURN
17650 'Print files
17660 PRINT"If you wish a list of files,":PRINT"enter the drive designator(s),"
17670 PRINT "NO colons, or separators":PRINT "(ENTER alone to bypass)"
17680 INPUT "",DRV$:LDRV=LEN(DRV$):IF LDRV>2 THEN GOSUB 20400:GOTO 17660
17690 IF LDRV=0 GOTO 17740
17700 IF LDRV=1 THEN DR1$=DRV$ ELSE DR1$=LEFT$(DRV$,1):DR2$=RIGHT$(DRV$,1)
17710 ON ERROR GOTO 17750:FL1CK$=DR1$+":*.*":FL2CK$=DR2$+":*.*"
17720 CLS:PRINT "Drive ";DR1$:FILES FL1CK$:PRINT :PRINT
17730 IF LDRV=2 THEN PRINT "Drive ";DR2$:FILES FL2CK$:PRINT:PRINT
17740 ON ERROR GOTO 0:RETURN
17750 IF (ERL=17720)AND(ERR=53) THEN BEEP ELSE 17770
17760 CLS:PRINT"No files found":RESUME 17660
17770 IF (ERL=17720)AND(ERR=71) THEN BEEP ELSE 17790
17780 PRINT"Drive "+DR1$+" not ready":PRINT:RESUME 17660
17790 IF ERL=17720 THEN BEEP:PRINT "BASIC Error "+STR$(ERR):PRINT:RESUME 17730
17800 IF ERR=53 THEN BEEP ELSE 17820
17810 PRINT"No files found":PRINT:RESUME 17660
17820 IF ERR=71 THEN BEEP:PRINT"Drive "+DR2$+" not ready":RESUME 17660
17830 BEEP:PRINT "BASIC Error "+STR$(ERR):RESUME NEXT
30640 'Function key Help Menu
31000 COLOR 15:PRINT "F1 ";:COLOR 7:PRINT "- Send Break to Host"
31010 COLOR 15:PRINT "F2 ";:COLOR 7:PRINT "- Function Selection Menu"
31020 COLOR 15:PRINT "F3 ";:COLOR 7:PRINT "- Display Next Error Msg."
31030 COLOR 15:PRINT "F4 ";:COLOR 7:PRINT "- Error ON/OFF Switch"
31040 COLOR 15:PRINT "F5 ";:COLOR 7:PRINT "- Display Function Key Menu"
31050 COLOR 15:PRINT "F6 ";:COLOR 7:PRINT "- Hex Listing ON/OFF Switch"
31060 COLOR 15:PRINT "F7 ";:COLOR 7:PRINT "- Printer ON/OFF Switch"
31070 COLOR 15:PRINT "F8 ";:COLOR 7:PRINT "- Telephone/LOG-ON Menu"
31080 COLOR 15:PRINT "F9 ";:COLOR 7:PRINT "- Upload ON/OFF Switch"
31090 COLOR 15:PRINT "F10";:COLOR 7:PRINT "- Log File ON/OFF Switch"
31100 COLOR 15:PRINT "ALT H ";:COLOR 7:PRINT "- Telephone/LOG-ON Help Menu"
31110 COLOR 15:PRINT "ALT P ";:COLOR 7:PRINT "- Print Max.Rec.Buf.Used"
31115 COLOR 15:PRINT "ALT S ";:COLOR 7:PRINT "- Force to Send (Half Duplex)"
31116 IF MPARM(5)=2 GOTO 31120 ELSE PRINT"Depress ";:COLOR 15:PRINT"ALT S";
31117 COLOR 7:PRINT" before using ";:COLOR 15:PRINT"F6, F8-F10":COLOR 7
31120 PRINT:RETURN
31130 IF NOT SMART GOTO 31150
31140 PRINT "Insure ";:COLOR 15 :PRINT "CAPS LOCK ";:COLOR 7:PRINT"is on"
31150 PRINT "Depress ";:COLOR 15:PRINT "F2 ";:COLOR 7:PRINT "to open ";
31160 COLOR 15:PRINT "Log/Upload ";:COLOR 7:PRINT "files"
31170 PRINT "Use ";:COLOR 15:PRINT "F7 ";:COLOR 7:PRINT "if printout desired"
31180 PRINT "Depress ";:COLOR 15,0:PRINT "F8 ";:COLOR 7:PRINT "for ";
31190 COLOR 15:PRINT"Telephone/LOG-ON ";:COLOR 7:PRINT "menu":PRINT:RETURN
32000 LOCATE 24,1:FOR CLEER=0 TO 24:PRINT:NEXT CLEER:LGGR=0:TLN=9 'Max. 9
32010 X=FRE("x"):IF TLN=1 THEN TELE=1:GOTO 32160
32020 COLOR 15,0:PRINT "Enter ";:COLOR 7,0:PRINT "phone # ";:COLOR 15,0
32030 PRINT "selection ";:COLOR 7,0:PRINT "Depress ":COLOR 15
32040 PRINT "ESC";:COLOR 7:PRINT "ape to ";
32050 COLOR 15:PRINT "return ";:COLOR 7:PRINT "as a Terminal"
32060 PRINT:RESTORE 32320:FOR SELEC=1 TO TLN
32070 READ CPNY$,UL$,CTY$,TELCO$,GO,LOGIN$,IDPSW$:GOSUB 32090
32080 NEXT:PRINT:GOTO 32120
32090 COLOR 15,0:PRINT RIGHT$(STR$(SELEC),1);" ";:COLOR 7,0:GOSUB 32100:RETURN
32100 PRINT USING "\      \";CPNY$+" ";:PRINT UL$;" ";
32110 PRINT USING "\           \";CTY$+" ";TELCO$:RETURN
32120 DL$=INKEY$:TELE=VAL(DL$)
32130 IF DL$="" THEN GOSUB 33000:GOTO 32120
32140 IF DL$=CHR$(27) THEN GOSUB 32200:GOTO 3405
32150 IF (TELE<1) OR (TELE>TLN) THEN GOSUB 20400:GOTO 32120
32160 RESTORE 32320:FOR SELECT=1 TO TELE
32170 READ CPNY$,UL$,CTY$,TELCO$,GO,LOGIN$,IDPSW$:NEXT:IF NOT SMART GOTO 32270
32180 IF MPARM(17)=1 THEN UL$="ATDT"+UL$ ELSE UL$="ATDP"+UL$
32190 GOSUB 17590:GOSUB 32200:GOTO 32220
32200 LOCATE 24-(TLN+1),1,0:FOR CLEER=0 TO 24:PRINT STRING$(79," ")
32210 NEXT CLEER:LOCATE ,,1:RETURN
32220 COLOR 15,0:PRINT CPNY$;:COLOR 7,0
32230 PRINT " is being called via ";:COLOR 15,0:PRINT TELCO$:COLOR 7,0
32240 PRINT "To redial, Depress ";:COLOR 15,0:PRINT "HOME ";
32250 COLOR 7,0:PRINT "and ";:COLOR 15,0:PRINT "F8 ";
32260 COLOR 7,0:PRINT "and Redo":PRINT:GOTO 32280
32270 GOSUB 32200:PRINT"Place Call to "+CPNY$+" via "+TELCO$:PRINT"Ph. # "+UL$
32280 PRINT "Operating as "+TMSL$+" Terminal":PRINT"After CONNECT, use ";:COLOR 15
32290 PRINT"F8 ";:COLOR 7:PRINT "to ";:COLOR 15:PRINT "LOG-ON.":COLOR 7:PRINT
32300 ON ERROR GOTO 3440:IF IPRR THEN LPRINT CPNY$+" being called via ";TELCO$
32310 ON ERROR GOTO 0:INIT=FALSE:UL$="":RETURN
32320 DATA SOURCE,986-9503,Van Nuys,TYMNET,1,SOURCE11;PRIM;,ID TCA123 PASWRD
32330 DATA SOURCE,986-9803,Van Nuys,TYMNET,1,SOURCE11;PRIM;,ID TCA123 PASWRD
32340 DATA SOURCE,365-9277,Mission Hls,TYMNET,1,SOURCE11;PRIM;,ID TCA123 PASWRD
32350 DATA SOURCE,998-3331,Northridge,TYMNET,1,SOURCE13;PRIM;,ID TCA123 PASWRD -ON SYS11
32360 DATA SOURCE,992-0144,Woodland Hls,TELENET,2,C 30138,ID TCA123 PASWRD
32370 DATA SOURCE,822-9287,Canoga Park,TELENET,2,C 30138,ID TCA123 PASWRD
32380 DATA CSERVE,892-7211,Van Nuys,CSERVE,3,"77000,1100",PASS/WORD
32390 DATA CSERVE,781-8439,San Fernando,CSERVE,3,"77000,1100",PASS/WORD
32400 DATA CSERVE,365-2013,Mission Hls,TYMNET,4,"77000,1100",PASS/WORD
32410 DATA CSERVE,998-4872,Northridge,TYMNET,4,"77000,1100",PASS/WORD
32420 IF LGGR<>0 GOTO 32510 ELSE ON GO GOTO 32430,32440,32450,32460,32470,32500
32430 UUL$="A":GOSUB 32570:LGGR=1:RETURN
32440 UUL$=CHR$(13):GOSUB 32570:FOR D2LY=0 TO 500:NEXT:GOSUB 32570:GO=6:RETURN
32450 UUL$=CHR$(3):GOSUB 32570:LGGR=1:RETURN
32460 UUL$="A":GOSUB 32570:GO=GO+1:RETURN
32470 PRINT "Type CIS02 and ENTER for non-prime time"
32480 PRINT "Type CPS01 and ENTER for prime time use":PRINT
32490 PRINT "Use F8 key for rest of LOG-ON":LGGR=1:RETURN
32500 UL$="D1":GOSUB 17590:LGGR=1:RETURN
32510 ON LGGR GOTO 32520,32530,32540,32550
32520 UL$=LOGIN$:GOSUB 17590:LGGR=LGGR+1:RETURN
32530 UL$=IDPSW$:GOSUB 17590:LGGR=LGGR+1:RETURN
32540 E%=0:ERM$(0)="ERROR * Use ALT H for F8 Help Menu":GOSUB 3600:RETURN
32550 PRINT "DISCONNECTING":UUL$="+++":GOSUB 32570:FOR D2LY=0 TO 3000:NEXT
32560 UL$="ATH":GOSUB 17590:LGGR=0:INIT=TRUE:RETURN
32570 CALL SN(C%,UUL$,E%):IF E%>-1 THEN GOSUB 3600 ELSE RETURN
32580 PRINT :PRINT :COLOR 15:PRINT"  Telephone/LOG-ON Help Menu":COLOR 7:PRINT
32590 COLOR 15:PRINT "HOME ";:COLOR 7:PRINT "- Enables F8 from the beginning"
32600 PRINT "       telephone dialup menu.":PRINT
32610 COLOR 15:PRINT "F8   ";:COLOR 7:PRINT "- After dialup, Depress F8 "
32620 PRINT "       in response to LOG-ON requests.":PRINT
32630 COLOR 15:PRINT CHR$(27)+"--  ";:COLOR 7:PRINT "- Cursor left  (Numeric 4)
32640 PRINT "       Return to previous entry,"
32650 PRINT "       using Function Key F8.":PRINT
32660 COLOR 15:PRINT "END  ";:COLOR 7:PRINT "- Enables last entry using F8"
32670 PRINT "       (Hang up the phone)":PRINT :PRINT :RETURN
33000 IF VAL(MID$(TIME$,4,2))=TME THEN RETURN
33010 IF MPARM(5)<>2 THEN RETURN
33020 ITEM=POS(X):ICSR=CSRLIN:CLMN=IWT-(LEN(TIME$)+LEN(DATE$)+17)
33030 TMME$=LEFT$(TIME$,5):TME=VAL(RIGHT$(TMME$,2))
33040 HOUR=VAL(LEFT$(TMME$,2)):IF HOUR=0 THEN HOUR=12:APM$="AM ":GOTO 33070
33050 IF HOUR>12 THEN HOUR=HOUR-12:APM$="PM ":GOTO 33070
33060 IF HOUR=12 THEN APM$="PM " ELSE APM$="AM "
33070 HR$=STR$(HOUR):TMME$=HR$+RIGHT$(TMME$,3)+APM$
33080 LOCATE 25,CLMN,0:COLOR 15,0:PRINT USING "\\";HXL$;:PRINT USING "\\";PTR$;
33090 COLOR UNTSY:PRINT USING "\\";ULN$;:COLOR DNTSY:PRINT USING "\\";DLN$;
33100 COLOR 7,0:PRINT "F5=HELP ";:IF NOT NTME THEN PRINT TMME$;
33110 IF LEFT$(DATE$,2)<>"00" THEN PRINT DATE$;
33120 LOCATE ICSR,ITEM,1:RETURN
34000 GOSUB 34050:GOSUB 34040:CLS:NEW
34010 GOSUB 34050:PRINT "Insert DOS diskette in default drive"
34020 PRINT "Depress any key when ready"
34030 K$=INKEY$:IF K$="" THEN 34030 ELSE GOSUB 34040:SYSTEM
34040 CLOSE:OPEN "COM1:" AS 1:RETURN
34050 CLS:PRINT "TERMINATING COMM. PROGRAM"
34060 PRINT "ARE YOU SURE(Y/N)?"
34070 K$=INKEY$:IF K$="" THEN 34070
34080 IF K$="Y" OR K$="y" THEN RETURN
34090 IF K$="N" OR K$="n" THEN 2800
34100 GOSUB 20400:GOTO 34070
35000 IQ=MPARM(16):IF IQ=0 THEN RETURN
35010 ON IQ GOTO 35020,35040
35020 WIDTH 40:LOCATE ,,0:CLS:DEF SEG=0:A=PEEK(&H410):POKE &H410, A OR &H30
35030 WIDTH 80:IWT=80:LOCATE 1,1,0,12,13:RETURN
35040 LOCATE ,,0:CLS:DEF SEG=0:A=PEEK(&H410):POKE &H410,(A AND &HCF) OR &H20
35050 SCREEN 1:SCREEN 0:WIDTH VDO:IWT=VDO:LOCATE ,,0,6,7:RETURN

SHORTERM.BAS

1 'SHORTERM.BAS ....Enhancements to IBM Async. Comm.   V1.04   (64KB)  4/24/82
2 'By Robert .C Rice, Upload/Download based on a program by Morris E. Thompson
223 IF LEFT$(TIME$,4)="00:0" THEN NTME=TRUE ELSE NTME=FALSE
225 IZF = 17 'max no. of features
235 ICN = 2 'set no. of terminals to be configured
330 DIM ERM$(21) 'error msg array
400 DIM TRMNL$(ICN+1)
410 TRMNL$(1)="Full Duplex"
420 TRMNL$(2)="PC Computer"
430 TRMNL$(3)="User Defined"
635 DATA 1,1,1,0,0,1,1,0,1,1,1,1,0,0,1,1,1
645 DATA 1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,1
775 DATA 4,3,1,0,2,1,1,0,2,2,3,7,0,0,1,0,1
781 DATA 4,3,1,0,2,1,1,0,1,1,1,1,0,3,1,0,1
866 NA$(16)="Select Display"
867 NA$(17)="Select Modem Dial Option"
937 VDO=40:DEF SEG=0:IF(PEEK(&H410)AND &H30)=&H30 THEN IWT=80 ELSE IWT=VDO
938 WIDTH IWT:LOCATE 10,1,0:IF IWT=80 THEN S1PC=INT(IWT/4)+2 ELSE S1PC=1
939 PRINT SPC(S1PC):PRINT"       The IBM Personal Computer"
940 PRINT SPC(S1PC):PRINT"  Asynchronous Communications Support"
941 PRINT SPC(S1PC):PRINT"This 64KB Version Modified and Enhanced"
942 PRINT SPC(S1PC):PRINT"           by Robert C. Rice"
943 PRINT SPC(S1PC):PRINT"   Upload/Download based on a program"
944 PRINT SPC(S1PC):PRINT"         by Morris E. Thompson"
945 PRINT:PRINT
949 IF IWT=80 THEN S2PC=INT(IWT/4)+6 ELSE S2PC=5
950 COLOR 15,0:LOCATE ,S2PC
960 PRINT "Bypass intermediate menus (y/n)?";:COLOR 7,0
961 K$=INKEY$:IF K$="" THEN 961
965 IF K$="y" OR K$="Y" THEN OP1T=1:GOTO 970
966 IF K$="n" OR K$="N" THEN OP1T=0 ELSE GOSUB 20400:GOTO 961
1004 C$(1) = "User Specified Full Duplex Term."
1005 C$(2) = "Personal Computer Communications"
1050 IF OP1T=0 THEN GOSUB 20200 ELSE IMEN=1:GOTO 1065
1066 TMSL$=TRMNL$(IMEN)
1170 TITLE$=TMSL$+" Terminal Feature"
1185 IF OP1T=0 THEN GOSUB 20200 ELSE IMEN=IMAX-2:GOTO 1500
1520 ON IP GOSUB 6000,6200,6400,9000,6800,7000,7200,7400,7500,7600,7625,7660,9000,9000,7800,7900,8000,9000,9000,9000
1800 GOSUB 35000 'Init. Term. Operation
1811 BKS$=CHR$(8):ENDD$=CHR$(79):HMNU$=CHR$(35):SMART=TRUE
1812 SNRC$=CHR$(31):HELP$=CHR$(63):IDSW$=CHR$(64):PRSW$=CHR$(65):LGSW$=CHR$(68)
1813 PLMX$=CHR$(25):UPSW$=CHR$(67):DIAL$=CHR$(66):HOME$=CHR$(71):BCSR$=CHR$(75)
1820 IDPR=FALSE:IPRR=FALSE:IPY=FALSE:LON=FALSE:ULON=FALSE:INIT=TRUE
2005 D%=512+ASC(BKS$):CALL SS(C%,T%,D%,E%)
2024 ISS=5:DTA%=1:T%=7:GOSUB 15000:GOSUB 2788
2025 PRINT"Starting up as a "+TMSL$+" Terminal"
2027 X=FRE("x"):PRINT:GOSUB 31000:GOSUB 31130
2531 IF LG THEN GOSUB 17310
2710 CALL BR(C%,E%):PRINT "Break Sent"
2712 ON ERROR GOTO 3440:IF IPRR THEN LPRINT "Break Sent"
2713 ON ERROR GOTO 0
2751 IF K$=HOME$ THEN INIT=TRUE:LGGR=0:RETURN
2752 IF K$=BCSR$ THEN IF LGGR>0 THEN LGGR=LGGR-1:RETURN ELSE RETURN
2753 IF K$=ENDD$ THEN INIT=FALSE:LGGR=4:RETURN
2754 IF K$=HMNU$ THEN GOSUB 32580:RETURN
2755 IF K$=PLMX$ THEN PRINT "Max. Receive Buffer Space Used = ";LM:LM=0:RETURN
2756 IF K$<>LGSW$ THEN 2760
2757 E%=0:IF NOT LG THEN ERM$(0)="Logging File Not Open":GOSUB 3600:RETURN
2758 DNTSY=7:IF LON THEN LON=FALSE ELSE LON=TRUE:DNTSY=31
2759 GOSUB 33010:RETURN
2761 IF K$<>UPSW$ THEN 2765
2762 IF NOT IU THEN GOSUB 17520:RETURN
2763 UNTSY=7:IF ULON THEN ULON=FALSE ELSE ULON=TRUE:UNTSY=31
2764 GOSUB 33010:RETURN
2766 IF K$=HELP$ THEN GOSUB 31000:RETURN
2768 IF K$=DIAL$ AND INIT THEN GOSUB 32000:RETURN
2769 IF K$=DIAL$ AND NOT INIT THEN GOSUB 32420:RETURN
2775 IF IDPR THEN IDPR=FALSE :HXL$=" " ELSE IDPR=TRUE:HXL$="H"
2776 GOSUB 33010:RETURN
2783 IF IPRR THEN IPRR=FALSE ELSE IPRR=TRUE
2784 PTR$=" ":IF IPRR THEN PTR$="P"
2785 GOSUB 33010:RETURN
2803 IMAX=9:IT=MPARM(14)
2808 C$(3)="Return to BASIC (pause)"
2809 IF LG THEN C$(4)="Close log file: "+LG$ ELSE C$(4)="Open log file"
2810 IF IU THEN C$(5)="Close upload file: "+UP$ ELSE C$(5)="Open upload file"
2811 C$(6)="Terminate Comm. go to BASIC"
2812 C$(7)="Terminate Comm. go to DOS"
2813 IF IT=0 THEN IMAX=7:GOTO 2835
2825 C$(8)="Transmit a Personal Computer File"
2830 C$(9)="Receive a Personal Computer File"
2844 IF IMEN=2 THEN OP1T=0
2845 ON IMEN GOTO 3400,970,3430,17200,17410,34000,34010,16200,16500
3100 ON ERROR GOTO 3440:IF IPRR THEN LPRINT B$;
3101 ON ERROR GOTO 0
3400 GOSUB 13030:IF JO THEN CALL SN(C%,XON$,E%)
3405 PRINT "Back as a "+TMSL$+" Terminal":IF MPARM(5)=1 GOTO 2601 ELSE GOTO 5000
3430 CLS:PRINT "You are back in BASIC."
3432 PRINT "Use F5 to return to Terminal Operation":KEY 5,"CONT"+CHR$(13):STOP
3435 KEY 5,"":GOTO 2800
3440 IF ERR=24 OR ERR=27 THEN 3445 ELSE 3450
3445 PTR$=" ":IPRR=FALSE:GOSUB 3540:E%=20:GOSUB 3600:GOSUB 33010:RESUME
3450 ON ERROR GOTO 0
3540 ERM$(20)="ERROR ="+STR$(ERR)+" ** Printer off"
3544 RETURN
3815 PRINT STRING$(40," ");
3825 PRINT STRING$(40," ");:LOCATE ,2:PRINT MSTK$(ICMP);
3955 IF (D% AND 4)>0 THEN E%=16:RETURN
5002 TERM$=LE$:TME=61
5106 IF RIGHT$(B$,1)<>BKS$ THEN 5110
5107 IF LEN(B$)>1 THEN B$=LEFT$(B$,LEN(B$)-2) ELSE GOSUB 2720:GOTO 5200
5110 IF LL<>IWT OR B$<>CR$ THEN PRINT B$;ELSE 5200
5113 ON ERROR GOTO 3440
5115 IF IPRR THEN LPRINT B$;
5116 ON ERROR GOTO 0
5200 GOSUB 33000:GOSUB 2590
5201 IF NOT IU GOTO 5205
5202 IF ULON THEN IF ISF THEN GOSUB 17510
5215 GOSUB 2750:IF K$=GOMEN$ GOTO 5290 ELSE GOTO 5030
5265 ON ERROR GOTO 3440:IF IPRR THEN LPRINT K$;
5266 ON ERROR GOTO 0
5290 IF JO THEN CALL SN(C%,XOFF$,E%)
5300 GOTO 2800
7900 'Menu for Display selection
7910 TITLE$="Display"
7920 C$(1)="Monochrome Display"
7930 C$(2)="Color Video Monitor"
7940 IMAX=2
7950 GOSUB 20200
7960 GOSUB 20100
7970 RETURN
8000 'Menu for Modem dial Option
8010 TITLE$="Type of Modem Dialing"
8020 C$(1)="Touch Tone"
8030 C$(2)="Pulse Dialing"
8040 IMAX=2
8050 GOSUB 20200
8060 GOSUB 20100
8070 RETURN
17200 IF LG THEN CLOSE#3:LG$="":LG=FALSE:DLN$=" ":GOTO 2800
17210 CLS:GOSUB 17660:PRINT "What is the name of the local file "
17220 PRINT "to which you wish to log?":PRINT "(ENTER alone returns to Menu)"
17230 INPUT X$:IF X$="" THEN 2800
17240 GOSUB 20300:LG$=Y$:ON ERROR GOTO 17260
17250 OPEN LG$ FOR APPEND AS 3:M$="":GOTO 17290
17260 IF ERR=67 THEN M$="Too many files open":GOTO 17280
17270 M$="FILE ACCESS FAILED. BASIC ERROR "+STR$(ERR)
17280 RESUME 17290
17290 ON ERROR GOTO 0:IF M$ <> "" THEN GOSUB 14032:GOTO 17230
17300 DLN$="L":DNTSY=31:LG=TRUE:LON=TRUE:GOTO 2800
17310 ON ERROR GOTO 17370
17320 IF NOT LON GOTO 17400 ELSE IF (LEN(LL$)+LEN(B$))<=255 GOTO 17350
17330 LLN=LEN(LL$):LL$=LL$+LEFT$(B$,255-LLN):PRINT#3,LL$
17340 LL$="":B$=RIGHT$(B$,LEN(B$)-255-LLN))
17350 LL$=LL$+B$:IF R$<>CR$ AND R$<>LE$ GOTO 17400
17360 PRINT#3,LEFT$(LL$,LEN(LL$)-1):LL$="":GOTO 17400
17370 IF ERR=61 THEN ERM$(0)="Disk full, Log file closed":GOTO 17390
17380 ERM$(0)="Disk Error, BASIC Err= "+STR$(ERR)
17390 E%=0:GOSUB 3600:LG=FALSE:LON=FALSE:DLN$=" ":GOSUB 33010:RESUME NEXT
17400 ON ERROR GOTO 0:RETURN
17405 'Upload
17410 IF IU THEN CLOSE#1:UP$="":IU=FALSE:ULON=FALSE:ULN$=" ":GOTO 2800
17420 CLS:GOSUB 17660:PRINT "What is the name of the local file "
17430 PRINT "which you wish to upload?":PRINT "(ENTER alone returns to Menu)"
17440 INPUT X$:IF X$="" THEN 2800 ELSE GOSUB 20300:LET UP$=Y$
17450 ON ERROR GOTO 17460:OPEN "I",1,UP$:M$="":GOTO 17490
17460 IF ERR=53 THEN M$="File "+UP$+" not found":GOTO 17480
17470 M$="File access failed. BASIC error "+STR$(ERR)
17480 RESUME 17490
17490 ON ERROR GOTO 0:IF M$<>"" THEN GOSUB 14032:GOTO 17440
17500 IU=TRUE:UNTSY=7:ULN$="U":ULON=FALSE:GOTO 2800
17510 T%=1:CALL BF(C%,T%,D%,E%):IF D%<>0 THEN RETURN
17520 IF NOT IU THEN ERM$(0)="Upload not active":E%=0:GOSUB 3600:RETURN
17530 IF EOF(1) THEN CLOSE#1:ERM$(0)="Upload complete, file closed" ELSE 17550
17540 E%=0:GOSUB 3600:IU=FALSE:ULON=FALSE:ULN$=" ":GOSUB 33010:UP$="":RETURN
17550 ON ERROR GOTO 17620:IF UL$="" THEN LINE INPUT#1,UL$:ON ERROR GOTO 0
17560 IF ILE THEN PRINT UL$
17570 ON ERROR GOTO 3440:IF IPRR THEN LPRINT UL$
17580 ON ERROR GOTO 0
17590 CALL SN(C%,UL$,E%):IF E%>-1 THEN GOSUB 3600
17600 CALL SN(C%,TSEND$,E%):IF E%>-1 THEN GOSUB 3600
17610 UL$="":RETURN
17620 CLOSE#1:UP$="":IU=FALSE:ULON=FALSE:ULN$=" ":GOSUB 33010:E%=0
17630 ERM$(0)="Disk Error, BASIC Err= "+STR$(ERR):GOSUB 3600:RESUME 17640
17640 ON ERROR GOTO 0:RETURN
17650 'Print files
17660 PRINT"If you wish a list of files,":PRINT"enter the drive designator(s),"
17670 PRINT "NO colons, or separators":PRINT "(ENTER alone to bypass)"
17680 INPUT "",DRV$:LDRV=LEN(DRV$):IF LDRV>2 THEN GOSUB 20400:GOTO 17660
17690 IF LDRV=0 GOTO 17740
17700 IF LDRV=1 THEN DR1$=DRV$ ELSE DR1$=LEFT$(DRV$,1):DR2$=RIGHT$(DRV$,1)
17710 ON ERROR GOTO 17750:FL1CK$=DR1$+":*.*":FL2CK$=DR2$+":*.*"
17720 CLS:PRINT "Drive ";DR1$:FILES FL1CK$:PRINT :PRINT
17730 IF LDRV=2 THEN PRINT "Drive ";DR2$:FILES FL2CK$:PRINT:PRINT
17740 ON ERROR GOTO 0:RETURN
17750 IF (ERL=17720)AND(ERR=53) THEN BEEP ELSE 17770
17760 CLS:PRINT"No files found":RESUME 17660
17770 IF (ERL=17720)AND(ERR=71) THEN BEEP ELSE 17790
17780 PRINT"Drive "+DR1$+" not ready":PRINT:RESUME 17660
17790 IF ERL=17720 THEN BEEP:PRINT "BASIC Error "+STR$(ERR):PRINT:RESUME 17730
17800 IF ERR=53 THEN BEEP ELSE 17820
17810 PRINT"No files found":PRINT:RESUME 17660
17820 IF ERR=71 THEN BEEP:PRINT"Drive "+DR2$+" not ready":RESUME 17660
17830 BEEP:PRINT "BASIC Error "+STR$(ERR):RESUME NEXT
31000 COLOR 15:PRINT "F1 ";:COLOR 7:PRINT "- Send Break to Host"
31010 COLOR 15:PRINT "F2 ";:COLOR 7:PRINT "- Function Selection Menu"
31020 COLOR 15:PRINT "F3 ";:COLOR 7:PRINT "- Display Next Error Msg."
31030 COLOR 15:PRINT "F4 ";:COLOR 7:PRINT "- Error ON/OFF Switch"
31040 COLOR 15:PRINT "F5 ";:COLOR 7:PRINT "- Display Function Key Menu"
31050 COLOR 15:PRINT "F6 ";:COLOR 7:PRINT "- Hex Listing ON/OFF Switch"
31060 COLOR 15:PRINT "F7 ";:COLOR 7:PRINT "- Printer ON/OFF Switch"
31070 COLOR 15:PRINT "F8 ";:COLOR 7:PRINT "- Telephone/LOG-ON Menu"
31080 COLOR 15:PRINT "F9 ";:COLOR 7:PRINT "- Upload ON/OFF Switch"
31090 COLOR 15:PRINT "F10";:COLOR 7:PRINT "- Log File ON/OFF Switch"
31100 COLOR 15:PRINT "ALT H ";:COLOR 7:PRINT "- Telephone/LOG-ON Help Menu"
31110 COLOR 15:PRINT "ALT P ";:COLOR 7:PRINT "- Print Max.Rec.Buf.Used"
31120 PRINT:RETURN
31130 IF NOT SMART GOTO 31150
31140 PRINT "Insure ";:COLOR 15 :PRINT "CAPS LOCK ";:COLOR 7:PRINT"is on"
31150 PRINT "Depress ";:COLOR 15:PRINT "F2 ";:COLOR 7:PRINT "to open ";
31160 COLOR 15:PRINT "Log/Upload ";:COLOR 7:PRINT "files"
31170 PRINT "Use ";:COLOR 15:PRINT "F7 ";:COLOR 7:PRINT "if printout desired"
31180 PRINT "Depress ";:COLOR 15,0:PRINT "F8 ";:COLOR 7:PRINT "for ";
31190 COLOR 15:PRINT"Telephone/LOG-ON ";:COLOR 7:PRINT "menu":PRINT:RETURN
32000 LOCATE 24,1:FOR CLEER=0 TO 24:PRINT:NEXT CLEER:LGGR=0:TLN=9 'Max. 9
32010 X=FRE("x"):IF TLN=1 THEN TELE=1:GOTO 32160
32020 COLOR 15,0:PRINT "Enter ";:COLOR 7,0:PRINT "phone # ";:COLOR 15,0
32030 PRINT "selection ";:COLOR 7,0:PRINT "Depress ":COLOR 15
32040 PRINT "ESC";:COLOR 7:PRINT "ape to ";
32050 COLOR 15:PRINT "return ";:COLOR 7:PRINT "as a Terminal"
32060 PRINT:RESTORE 32320:FOR SELEC=1 TO TLN
32070 READ CPNY$,UL$,CTY$,TELCO$,GO,LOGIN$,IDPSW$:GOSUB 32090
32080 NEXT:PRINT:GOTO 32120
32090 COLOR 15,0:PRINT RIGHT$(STR$(SELEC),1);" ";:COLOR 7,0:GOSUB 32100:RETURN
32100 PRINT USING "\      \";CPNY$+" ";:PRINT UL$;" ";
32110 PRINT USING "\           \";CTY$+" ";TELCO$:RETURN
32120 DL$=INKEY$:TELE=VAL(DL$)
32130 IF DL$="" THEN GOSUB 33000:GOTO 32120
32140 IF DL$=CHR$(27) THEN GOSUB 32200:GOTO 3405
32150 IF (TELE<1) OR (TELE>TLN) THEN GOSUB 20400:GOTO 32120
32160 RESTORE 32320:FOR SELECT=1 TO TELE
32170 READ CPNY$,UL$,CTY$,TELCO$,GO,LOGIN$,IDPSW$:NEXT:IF NOT SMART GOTO 32270
32180 IF MPARM(17)=1 THEN UL$="ATDT"+UL$ ELSE UL$="ATDP"+UL$
32190 GOSUB 17590:GOSUB 32200:GOTO 32220
32200 LOCATE 24-(TLN+1),1,0:FOR CLEER=0 TO 24:PRINT STRING$(79," ")
32210 NEXT CLEER:LOCATE ,,1:RETURN
32220 COLOR 15,0:PRINT CPNY$;:COLOR 7,0
32230 PRINT " is being called via ";:COLOR 15,0:PRINT TELCO$:COLOR 7,0
32240 PRINT "To redial, Depress ";:COLOR 15,0:PRINT "HOME ";
32250 COLOR 7,0:PRINT "and ";:COLOR 15,0:PRINT "F8 ";
32260 COLOR 7,0:PRINT "and Redo":PRINT:GOTO 32280
32270 GOSUB 32200:PRINT"Place Call to "+CPNY$+" via "+TELCO$:PRINT"Ph. # "+UL$
32280 PRINT "Operating as "+TMSL$+" Terminal":PRINT"After CONNECT, use ";:COLOR 15
32290 PRINT"F8 ";:COLOR 7:PRINT "to ";:COLOR 15:PRINT "LOG-ON.":COLOR 7:PRINT
32300 ON ERROR GOTO 3440:IF IPRR THEN LPRINT CPNY$+" being called via ";TELCO$
32310 ON ERROR GOTO 0:INIT=FALSE:UL$="":RETURN
32320 DATA SOURCE,986-9503,Van Nuys,TYMNET,1,SOURCE11;PRIM;,ID TCA123 PASWRD
32330 DATA SOURCE,986-9803,Van Nuys,TYMNET,1,SOURCE11;PRIM;,ID TCA123 PASWRD
32340 DATA SOURCE,365-9277,Mission Hls,TYMNET,1,SOURCE11;PRIM;,ID TCA123 PASWRD
32350 DATA SOURCE,998-3331,Northridge,TYMNET,1,SOURCE13;PRIM;,ID TCA123 PASWRD -ON SYS11
32360 DATA SOURCE,992-0144,Woodland Hls,TELENET,2,C 30138,ID TCA123 PASWRD
32370 DATA SOURCE,822-9287,Canoga Park,TELENET,2,C 30138,ID TCA123 PASWRD
32380 DATA CSERVE,892-7211,Van Nuys,CSERVE,3,"77000,1100",PASS/WORD
32390 DATA CSERVE,781-8439,San Fernando,CSERVE,3,"77000,1100",PASS/WORD
32400 DATA CSERVE,365-2013,Mission Hls,TYMNET,4,"77000,1100",PASS/WORD
32410 DATA CSERVE,998-4872,Northridge,TYMNET,4,"77000,1100",PASS/WORD
32420 IF LGGR<>0 GOTO 32510 ELSE ON GO GOTO 32430,32440,32450,32460,32470,32500
32430 UUL$="A":GOSUB 32570:LGGR=1:RETURN
32440 UUL$=CHR$(13):GOSUB 32570:FOR D2LY=0 TO 500:NEXT:GOSUB 32570:GO=6:RETURN
32450 UUL$=CHR$(3):GOSUB 32570:LGGR=1:RETURN
32460 UUL$="A":GOSUB 32570:GO=GO+1:RETURN
32470 PRINT "Type CIS02 and ENTER for non-prime time"
32480 PRINT "Type CPS01 and ENTER for prime time use":PRINT
32490 PRINT "Use F8 key for rest of LOG-ON":LGGR=1:RETURN
32500 UL$="D1":GOSUB 17590:LGGR=1:RETURN
32510 ON LGGR GOTO 32520,32530,32540,32550
32520 UL$=LOGIN$:GOSUB 17590:LGGR=LGGR+1:RETURN
32530 UL$=IDPSW$:GOSUB 17590:LGGR=LGGR+1:RETURN
32540 E%=0:ERM$(0)="ERROR * Use ALT H for F8 Help Menu":GOSUB 3600:RETURN
32550 PRINT "DISCONNECTING":UUL$="+++":GOSUB 32570:FOR D2LY=0 TO 3000:NEXT
32560 UL$="ATH":GOSUB 17590:LGGR=0:INIT=TRUE:RETURN
32570 CALL SN(C%,UUL$,E%):IF E%>-1 THEN GOSUB 3600 ELSE RETURN
32580 PRINT :PRINT :COLOR 15:PRINT"  Telephone/LOG-ON Help Menu":COLOR 7:PRINT
32590 COLOR 15:PRINT "HOME ";:COLOR 7:PRINT "- Enables F8 from the beginning"
32600 PRINT "       telephone dialup menu.":PRINT
32610 COLOR 15:PRINT "F8   ";:COLOR 7:PRINT "- After dialup, Depress F8 "
32620 PRINT "       in response to LOG-ON requests.":PRINT
32630 COLOR 15:PRINT CHR$(27)+"--  ";:COLOR 7:PRINT "- Cursor left  (Numeric 4)
32640 PRINT "       Return to previous entry,"
32650 PRINT "       using Function Key F8.":PRINT
32660 COLOR 15:PRINT "END  ";:COLOR 7:PRINT "- Enables last entry using F8"
32670 PRINT "       (Hang up the phone)":PRINT :PRINT :RETURN
33000 IF VAL(MID$(TIME$,4,2))=TME THEN RETURN
33010 IF MPARM(5)<>2 THEN RETURN
33020 ITEM=POS(X):ICSR=CSRLIN:CLMN=IWT-(LEN(TIME$)+LEN(DATE$)+17)
33030 TMME$=LEFT$(TIME$,5):TME=VAL(RIGHT$(TMME$,2))
33040 HOUR=VAL(LEFT$(TMME$,2)):IF HOUR=0 THEN HOUR=12:APM$="AM ":GOTO 33070
33050 IF HOUR>12 THEN HOUR=HOUR-12:APM$="PM ":GOTO 33070
33060 IF HOUR=12 THEN APM$="PM " ELSE APM$="AM "
33070 HR$=STR$(HOUR):TMME$=HR$+RIGHT$(TMME$,3)+APM$
33080 LOCATE 25,CLMN,0:COLOR 15,0:PRINT USING "\\";HXL$;:PRINT USING "\\";PTR$;
33090 COLOR UNTSY:PRINT USING "\\";ULN$;:COLOR DNTSY:PRINT USING "\\";DLN$;
33100 COLOR 7,0:PRINT "F5=HELP ";:IF NOT NTME THEN PRINT TMME$;
33110 IF LEFT$(DATE$,2)<>"00" THEN PRINT DATE$;
33120 LOCATE ICSR,ITEM,1:RETURN
34000 GOSUB 34050:GOSUB 34040:CLS:NEW
34010 GOSUB 34050:PRINT "Insert DOS diskette in default drive"
34020 PRINT "Depress any key when ready"
34030 K$=INKEY$:IF K$="" THEN 34030 ELSE GOSUB 34040:SYSTEM
34040 CLOSE:OPEN "COM1:" AS 1:RETURN
34050 CLS:PRINT "TERMINATING COMM. PROGRAM"
34060 PRINT "ARE YOU SURE(Y/N)?"
34070 K$=INKEY$:IF K$="" THEN 34070
34080 IF K$="Y" OR K$="y" THEN RETURN
34090 IF K$="N" OR K$="n" THEN 2800
34100 GOSUB 20400:GOTO 34070
35000 IQ=MPARM(16):IF IQ=0 THEN RETURN
35010 ON IQ GOTO 35020,35040
35020 WIDTH 40:LOCATE ,,0:CLS:DEF SEG=0:A=PEEK(&H410):POKE &H410, A OR &H30
35030 WIDTH 80:IWT=80:LOCATE 1,1,0,12,13:RETURN
35040 LOCATE ,,0:CLS:DEF SEG=0:A=PEEK(&H410):POKE &H410,(A AND &HCF) OR &H20
35050 SCREEN 1:SCREEN 0:WIDTH VDO:IWT=VDO:LOCATE ,,0,6,7:RETURN

XMODEM.ASM

	TITLE	'MODEM FOR THE IBM PERSONAL COMPUTER: PC/DOS'
	PAGE	 63,132
;
;*    M  O  D  E  M   - -   FOR THE IBM PERSONAL COMPUTER	*
;*								*
;*    This program was developed from				*
;*	   MODEM.ASM  (Version 3.0)				*
;*	   for CP/M to CP/M file transfers			*
;*	BY Ward Christensen	    (CPM-UG Disk # 25)		*
;*    Refer to the last section of this source file for 	*
;*    a complete modification history and credits to		*
;*    those who contributed to this version.			*
;*								*
;* N O T I C E							*
;*    This program is supplied for your personal and		*
;*    non-commercial use only. No commercial use permitted.	*
;*    Users of this program are granted limited rights to	*
;*    reproduce and distribute this program, provided		*
;*    the following conditions are met: 			*
;*								*
;*    1) This program must be supplied in original form,	*
;*	 with no modifications. 				*
;*    2) Notices contained in this source file, and those	*
;*	 produced by the executable program, must not be	*
;*	 altered or removed.					*
;*    3) This program may not be sold. Providing this		*
;*	 program for consideration of any sort, including	*
;*	 copying or distribution fees, is prohibited.		*
;*    4) This program may not be used on timesharing		*
;*	 systems where fees are charged for access,		*
;*	 or or supplied as part of any other form of		*
;*	 rental access computing, without the express		*
;*	 written permission of the author.			*
;*								*
;*    PLEASE SEND PROBLEM REPORTS AND SUGGESTIONS		*
;*    TO:     John Chapman					*
;*	      844 S. Madison St.				*
;*	      Hinsdale, Illinois  60521 			*
;*	      Compuserve = 70205,1217				*
	SUBTTL	MACRO DEFINITIONS
	page
;
DOSCALL MACRO	FUNCTION,AREA ;INVOKE DOS SERVICE
	IFNB	<AREA>
	MOV	DX,OFFSET AREA	;SET PARAMETER OFFSET
	ENDIF
	MOV	AH,FUNCTION	;DOS FUNCTION CODE
	INT	21H		;INVOKE DOS SERVICE
	ENDM
;
PRCHAR	MACRO	CHAR	;PRINT A CHARACTER
	IFNB	<CHAR>
	MOV	DL,CHAR ;CHAR TO DL REG
	ENDIF
	DOSCALL DSPLO	; DOS PRINT CHARACTER FUNCTION
	ENDM
;
SCROLL	MACRO
	MOV	AX,600H ;AH=6 SCROLL, AL=0 ENTIRE WINDOW
	INT	10H	;INVOKE BIOS SCROLL ROUTINE
	ENDM
;
LOCATE	MACRO
	MOV	AH,2	;BIOS FUNCTION SELECT
	MOV	BH,0	;USE SCREEN 0
	INT	10H	;INVOKE BIOS CURSOR POSITIONING
	ENDM
;
;
	SUBTTL	EQUATES
	page
;
CANFLG	EQU	1		;NO CANCEL ABILITY
;
MODSNDB EQU	020H		;BIT TO TEST FOR SEND
MODSNDR EQU	020H		;VALUE WHEN READY
MODRCVB EQU	001H		;BIT TO TEST FOR RECEIVE
MODRCVR EQU	001H		;VALUE WHEN READY
;
BAUDRAT EQU	0C2H		;BAUD RATE OUTPUT
DTREADY EQU	01H		;MCR FLAG FOR DTR UP
;
;ORIGMOD EQU	1DH		;8 DATA, NO PARITY, ORIG
;ANSWMOD EQU	1EH		;8 DATA, NO PARITY, ANSW
;
INITREQ EQU	0		;MODEM INIT. REQ'D?INITC1       EQU     64H             ;FIRST INIT CHAR TO CTL PORT
INITC2	EQU	64H		;2ND INIT CHAR TO CTL PORT
;
FASTCLK EQU	1		;PUT 1 HERE FOR 4 MHZ CLOCK
ERRLIM	EQU	10		;MAX ALLOWABLE ERRORS
EXITCHR EQU	'W'-40H         ;CTL-W EXIT FROM T OR C
DISCCHR EQU	'D'-40H         ;CTL-D DISCONNECTS MODEM T/C
CTLCCHR EQU	'I'-40H         ;CTL-C REPLACEMENT (temporary)
CTLCHAR EQU	03H		;CTL-C ACTUAL	   (temporary)
;
;DEFINE ASCII CHARACTERS USED
;
SOH	EQU	01H		;START OF HEADER
EOT	EQU	04H		;END OF TRANSMISSION
ACK	EQU	06H		;ACKNOWLEDGE
LF	EQU	0AH		;LINEFEED
CR	EQU	0DH		;CARRIAGE RETURN
NAK	EQU	15H		;NEG ACKNOWLEDGE
CAN	EQU	18H		;CANCEL
FF	EQU	0CH		;FORM FEED (clear screen)
	PAGE
;
; PC DOS EQUATES (VERSION 1.1)
;
REIPL	EQU	0		;PROGRAM TERMINATE
RDCON	EQU	1		;KEYBOARD INPUT
WRCON	EQU	2		;DISPLAY OUTPUT
PRTCHR	EQU	5		;PRINTER OUTPUT, CHAR IN DL
DCON	EQU	6		;DIRECT CONSOLE I/O
PRINT	EQU	9		;PRINT STRING
CONST	EQU	11		;CONSOLE STAT
OPEN	EQU	15		;0FFH=NOT FOUND
CLOSE	EQU	16		;	"       "
SRCHF	EQU	17		;	"       "
SRCHN	EQU	18		;	"       "
ERASE	EQU	19		;NO RET CODE
READ	EQU	20		;0=OK, 1=EOF
WRITE	EQU	21		;0=OK, 1=ERR, 2=?, 0FFH=NO DIR SPC
MAKE	EQU	22		;0FFH=BAD
REN	EQU	23		;0FFH=BAD
STDMA	EQU	26		;SET DMA
FATADDR EQU	27		;FILE ALLOCATION TABLE ADDRESS
;
;
; d o s   f u n c t i o n s
;
;
DSPLO	EQU	2
PSTRING EQU	9
DRESET	EQU	0DH
SELDSK	EQU	0EH
SRCHF	EQU	11H
SRCHN	EQU	12H
CDISK	EQU	19H
SETDTA	EQU	1AH
FATADDR EQU	1BH
SETINTV EQU	25H
GETDATE EQU	2AH
GETTIME EQU	2CH
;
;
;
; PC DOS FCB EQUATES (VERSION 1.1)
;
INT20H	EQU	DS:00H
FCB	EQU	DS:5CH
FCBNAME EQU	DS:5DH
FCBEXT	EQU	DS:65H
FCBSZL	EQU	DS:6CH
FCBSZH	EQU	DS:6DH
FCBCR	EQU	DS:7CH
FCBRR	EQU	DS:7DH
FCB2	EQU	DS:6CH
	SUBTTL	'PREFIX, CONSTANTS AND WORKAREA'
	PAGE
MODEM	SEGMENT PUBLIC 'CODE'
	ASSUME	CS:MODEM,DS:MODEM,ES:MODEM
;
;	----------------
;	START OF ACTUAL PROGRAM AREA
;	----------------
	ORG	100H
MAIN	PROC	FAR
	JMP	STARTS
OPTION	DB	0		;PRIMARY OPTION
;
;DATAFLG 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 ITSELF) IS
;
DATAFLG DB	0		;AT HEADER, FIRST
;
;
;SUB-OPTION TABLE.  IF AN OPTION IS IN EFFECT,
;	THE CHARACTER IS SET TO BINARY 0
;
OPTBL	EQU	OFFSET $
ANSWFLG DB	'A'             ;ANSWER MODE
DISCFLG DB	'D'             ;DISCONNECT WHEN DONE
ECHOFLG DB	'E'             ;TO ECHO AFTER XFER
DUMYFLG DB	'U'             ;DEFAULT UART FLAG
INITFLG DB	'I'             ;TO INIT THE UART / MODEM
ORIGFLG DB	'O'             ;ORIGINATE MODE
QFLG	DB	'Q'             ;QUIET TRANSFER (NO MSGS)
RSEEFLG DB	'R'             ;SEE WHAT'S RECEIVED
SSEEFLG DB	'S'             ;SEE WHAT'S SENT
TERMFLG DB	'T'             ;TO TERM AFTER XFER
VSEEFLG DB	'V'             ;VIEW MESSAGES (NO HDR, ETC)
urt2flg db	'2'             ;second UART
urt3flg db	'3'             ;third UART
OPTBE	EQU	OFFSET $	;END OF OPTIONS
;
TABLESIZE EQU	OPTBE-OPTBL
;
;------------------------------------------------------------------
; ** added for COM1/2/3 Select support for PC		   8/82/jac
;------------------------------------------------------------------
;
;
OFFDATP EQU	0      ;DATA PORT		  OFFSET
OFFCTLP EQU	5      ;MODEM STATUS REGISTER	  OFFSET
OFFCTL2 EQU	4      ;MODEM CONTROL REGISTER	  OFFSET
OFFCTL3 EQU	3      ;LINE CONTROL REGISTER	  OFFSET
;
;
BASE1U	dw	03f8h	;base address uart 1 (COM1)
base2u	dw	02F8h	;base address uart 2 (COM2)
base3u	dw	01F8h	;base address uart 3 (COM3) ??NOT TESTED??;
;
MODDATP dw	0      ;3F8H	;DATA PORT
MODCTLP dw	0      ;3FDH	;MODEM STATUS REGISTER
MODCTL2 dw	0      ;3FCH	;MODEM CONTROL REGISTER
MODCTL3 dw	0      ;3FBH	;LINE CONTROL REGISTER
;
;
RCVSNO	DB	0		;SECT # RECEIVED
SECTNO	DB	0		;CURRENT SECTOR NUMBER
ERRCT	DB	0		;ERROR COUNT
;
;	FOLLOWING 3 USED BY DISK BUFFERING ROUTINES
;
EOFLG	DB	0		;EOF FLAG (1=TRUE)
SECPTR	DW	DBUF
SECINBF DB	0		;# OF SECTORS IN BUFFER
;
;	HELP MSGS
;
;
msg00	db	cr,lf
 db '+---------------------------------------------------------------------+',cr,lf
 db '| F                                                                   |',cr,lf
 db '| M  O  D  E  M   - -   FOR THE IBM PERSONAL COMPUTER  (PC/DOS 1.1)   |',cr,lf
 db '|                                                                     |',cr,lf
 DB '|                                      All Rights Reserved            |',cr,lf
 db '|---------------------------------------------------------------------|',cr,lf
 db '|                                                                     |',cr,lf
 db '|  N O T I C E :       Commercial use forbidden.                      |',cr,lf
 db '|                                                                     |',cr,lf
 db '|  This program is provided for personal and non-commercial use only. |',cr,lf
 db '|  Sale is forbidden.         Users of this program are granted       |',cr,lf
 db '|  limited rights to reproduce and distribute this program, provided  |',cr,lf
 db '|  that a) the program is not sold, or provided for consideration     |',cr,lf
 db '|  of any sort, including copying or distribution fees greater than   |',cr,lf
 db '|  the face value of the media and postage. and b) the program is     |',cr,lf
 db '|  provided in unmodified form, with this notice, and all other       |',cr,lf
 db '|  documentation intact.                                              |',cr,lf
 db '|                                                                     |',cr,lf
 db '+---------------------------------------------------------------------+',cr,lf
 db	cr,lf,0,1
;
;
MSG01	DB	CR,LF
;		 1234567890123456789012345678901234567890123456789012345678901234567890
	DB	'----  M  O  D  E  M  ----  ',cr,lf,cr,lf
	db	'Converted from  MODEM 3.0 by Ward Christensen     ',cr,lf
	DB	'Sale, or any other commercial use forbidden',cr,lf
	DB	'Version 3.2 for IBM PC/DOS',cr,lf
	DB	'      R  E  A  D  Y        ',cr,lf
	db	cr,lf,'$',1,0
MSG01A	DB	'File Open, Ready to Receive',CR,LF,0
MSG02	DB	'Awaiting #',0
MSG03A	DB	'h rcd, not soh',CR,LF,0
MSG03	DB	'+++ TIMEOUT +++',0
MSG04	DB	'++ Bad Sector # in Hdr',CR,LF,0
MSG05	DB	'++ CKSUM ++',0
MSG06	DB	'Send # ',0
MSG07	DB	'h rcvd, not ack ',CR,LF,0
MSG08	DB	'Timeout on ack',CR,LF,0
MSG09	DB	'Modem Program Cancelled ',CR,LF,0
MSG10	DB	'File exists, Type Y to erase ',0
MSG11	DB	'Can not open file$'
MSG12	DB	'File open, Extent Length ',0
MSG13	DB	'Awaiting Initial nak',CR,LF,0
MSG14	DB	cr,lf,'Transfer Complete',CR,LF,0
MSG15	DB	cr,lf,'Press Return to Disconnect',0
MSG16	DB	'++ DISCONNECTED ++',0
MSG17	DB	cr,lf,'++ Do not Forget - The Modem is'
	DB	'NOT Disconnected',CR,LF,0
;	DB	'Use "M3 D" to Disconnect',CR,LF,0
MSG18	DB	'Multiple errors encountered. '
	DB	'Type Q to quit, R to Retry ',0
MSG19	DB	CR,LF,'Press Return to Continue'
	DB	CR,LF,0
MSG20	DB	'++ Unable to Receive Block'
	DB	CR,LF,'++ ABORTING ++$'
MSG21	DB	'Can not Send Sector '
	DB	'- ABORTING',CR,LF,'$'
MSG22	DB	'++ ERROR - Can not make file',CR,LF
	DB	'++ Directory must be full',CR,LF,'$'
MSG22A	DB	'++ Can not Close Files ++$'
MSG23	DB	'++ File Read ERROR ++$'
MSG24	DB	'++ ERROR Writing File ++',CR,LF,'$'
MSG25	DB	'Invalid option on modem command',CR,LF
	DB	'PRESS RETURN FOR HELP, CTL-C IF NOT',CR,LF,1,0
MSG26	DB	'Format for command is',CR,LF,CR,LF
	DB	'MODEM # FILENAME',CR,LF,CR,LF
	DB	'Where # is a 1 character primary option,',CR,LF
	DB	' which may be followed by sub-options,',CR,LF
;	DB	' and by ".xxx" to set baud rate to xxx'
	DB	CR,LF,CR,LF,1
	DB	'Primary Options',CR,LF
	DB	'    S to 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 data)',CR,LF
;	DB	'    D to disconnect the phone'
;	DB	'    (S100 modems only)',CR,LF
	DB	'    H to print this help file'
	DB	CR,LF,CR,LF,1
	DB	'Secondary options',CR,LF
;	DB	'    A answer mode',CR,LF
;	DB	'    O originate mode',CR,LF
;	DB	'    D disconnect after execution',CR,LF
;	DB	'    I initialize uart  to defaults 300,n,8,1',CR,LF
	DB	'    T go to terminal mode after file xfer',CR,LF
	DB	'    E go to echo mode after file xfer',CR,LF
	DB	'    Q quiet mode - no status msgs',CR,LF
	DB	'    R show chars received',CR,LF
	DB	'    S show chars sent',CR,LF
	DB	'    V view file sent/received (no status)',CR,LF
;	DB	'    2 switch to COM2: - second rs232 port',CR,LF
;	DB	'    3 switch to COM3: - third  rs232 port',CR,LF
	DB	CR,LF,'FOR EXAMPLES, TYPE MODEM X',CR,LF,1,0
MSG27	DB	'Send file, ',CR,LF
	DB	'    MODEM S fn.ft',CR,LF
	DB	'Send another file',CR,LF
	DB	'    MODEM S fn.ft',CR,LF
;	DB	'Then send a third file at 450 baud and disconnect'
;	DB	CR,LF,'    MODEM SD.450 fn.ft',CR,LF
	DB	'Act as a terminal ',CR,LF
	DB	'    MODEM T',CR,LF
	DB	' Use ctl-D to disconnect)',CR,LF
	DB	'Receive file,  view it',CR,LF
	DB	'    MODEM RV fn.ft',CR,LF,1,0
;
DBUF	DB	128*16 DUP(?)	;16 LOGICAL SECTOR BUFFER # 1
				;   (* Four physical sectors)
	DB	128*16 DUP(?)	;16 LOGICAL SECTOR BUFFER # 2
				;   (* Four physical sectors)
				 TOTAL = one track on PC/DOS (8/512)
;	DB	'POOT'
	SUBTTL	'MAIN PROGRAM SECTION'
	PAGE
STARTS:
;
;=============================================================================
;
;	CLEAR THE SCREEN (cursor = 1,1)
;
	push	dx
	SUB	CX,CX		;UPPER LEFT CORNER
	MOV	DX,184FH	;BOTTOM RIGHT CORNER
	MOV	BH,7		;NORMAL ATTRIB FOR CLS
	SCROLL			;INVOKE BIOS TO CLEAR SCREEN
	SUB	DX,DX		;POINT TO ROW 1,COL 1
	LOCATE			;SET THE CURSOR TO TOP LEFT
;
;	PRINT THE STARTUP MESSAGE
;
	MOV	DX,OFFSET MSG01 ;GET ID MESSAGE
	MOV	CL,PRINT
	CALL	BDOS		;PRINT ID MESSAGE
	pop	dx
;
;=============================================================================
;
;
;SAVE PRIMARY OPTION, VALIDATE SECONDARY OPT.
;
	CALL	PROCOPT
;			IF WE RETURN FROM PROCOPT, A VALID
;			ACTION OPTION (not help or examples)
;			WAS FOUND .. PROCESSING CONTINUES
;
;INIT THE MODEM OR SERIAL PORT	 (dtr UP always - THEN CHECK FOR "i" OPT.
;
	CALL	INITMOD
;
;MOVE THE FILENAME FROM FCB 2 TO FCB 1
;
	CALL	MOVEFCB
;
;
;GOBBLE UP GARBAGE CHARS FROM THE LINE
;PRIOR TO RECEIVE OR SEND
;
	PUSH	DX
	MOV	DX,MODDATP
	IN	AL,DX
	IN	AL,DX
	POP	DX
;
;JMP TO APPROPRIATE FUNCTION
;
	MOV	AL,OPTION	;GET PRIMARY OPTION
;
	CMP	AL,'C'          ;(COMPAT W/EARLIER
	JNZ	L00001
	JMP	TRMECHO 	;OPTION "COMPUTER")
;
L00001: CMP	AL,'E'          ;TERMINAL IN ECHO
	JNZ	L00002
	JMP	TRMECHO 	;..MODE?;
L00002: CMP	AL,'T'          ;TERMINAL..
	JNZ	L00003
	JMP	TERM		;..MODE?;
L00003	LABEL	NEAR
;	CMP	AL,'D'
;	JNZ	L00004
;	JMP	DISCONN
;L00004  LABEL	 NEAR
;
	CMP	AL,'S'          ;SEND..
	JNZ	L00005
	JMP	SENDFIL 	;..A FILE?;
L00005: CMP	AL,'R'          ;RECEIVE..
	JNZ	L00006
	JMP	RCVFIL		;..A FILE?;
;INVALID OPTION
;

L00006: JMP	BADOPT		;BAD OPTIONS !
;
;RETURN TO PC DOS VIA INT 20H IN SEGMENT PREFIX
;
EXIT:	PUSH	ES		;SET RETURN SEGMENT TO STACK
	SUB	AX,AX		;CLEAR A REGISTER
	PUSH	AX		;PUT ZERO RETURN ADDR TO STACK
	RET			;FAR RETURN TO FORCE CS TO ...
MAIN	ENDP			;.. POINT TO SEGMENT PREFIX
; * * * * * * * * * * * * * * * * * * * *
;					*
;	TERM: TERMINAL MODE		*
;					*
; * * * * * * * * * * * * * * * * * * * *
;
;THIS PROGRAM SIMPLY SENDS KEYED CHARACTERS
;DOWN THE LINE, AND DISPLAYS CHARACTERS
;RECEIVED FROM THE LINE.  THIS MAKES IT
;SUITABLE FOR COMMUNICATION WITH TIME SHARING
;COMPUTERS, CBBS'S, OR ANOTHER PROGRAM
;RUNING "MODEM E" (ECHO MODE)
;
;TYPEZZ THE "EXITCHR" (ORIGINALLY CTL-E) TO EXIT.
;OR THE "DISCCHR" (ORIGINALLY CTL-D) TO DISCONN.
;
;A FUTURE ENHANCEMENT WILL BE TO WRITE THE
;RECEIVED DATA IN MEMORY, AND ALLOW IT TO
;BE WRITTEN TO DISK
;
TERM	PROC	NEAR
	CALL	STAT		;LOCAL CHAR KEYED?	JNZ	L00007
	JMP	TERML		;..NO, CHECK LINE
L00007: CALL	KEYIN		;GET CHAR
	CMP	AL,EXITCHR	;TIME TO END?	JNZ	L00008
	JMP	CKDIS		;YES, CK DISCONN
L00008: CMP	AL,DISCCHR	;DISCONNECT REQUEST?	JNZ	L00009
	JMP	DISCONN 	;YES, DO IT
L00009: PUSH	DX
	MOV	DX,MODDATP
	OUT	DX,AL		;SEND THE CHAR
	POP	DX
;
;SEE IF CHAR FROM LINE
;
TERML:	PUSH	DX
	MOV	DX,MODCTLP
	IN	AL,DX		;READ STATUS
	POP	DX
	AND	AL,MODRCVB	;ISOLATE BIT
	CMP	AL,MODRCVR	;READY? JZ	L00010
	JMP	TERM		;..NO, LOOP
L00010: PUSH	DX
	MOV	DX,MODDATP
	IN	AL,DX		;READ DATA
	POP	DX
	CALL	TYPEZZ		;TYPEZZ IT
	JMP	TERM		;LOOP
TERM	ENDP
;
; * * * * * * * * * * * * * * * * * * * *
;					*
;	TRMECHO: TERMINAL WITH ECHO	*
;					*
; * * * * * * * * * * * * * * * * * * * *
;
;TERMINAL PROGRAM WITH ECHO - SEE NOTES
;UNDER "TERM" ABOVE
;
;C A U T I O N	 DON'T RUN WITH BOTH COMPUTERS
;IN "ECHO" MODE - LINE ERRORS (OR ANY CHAR)
;WILL BE ECHOED BACK AND FORTH AD INFINITUM.
;
TRMECHO PROC	NEAR
	PUSH	DX
	MOV	DX,MODCTLP
	IN	AL,DX		;GET STATUS
	POP	DX
	AND	AL,MODRCVB	;ISOLATE READY BIT
	CMP	AL,MODRCVR	;ARE WE READY?	JNZ	L00011
	JMP	LINECHR 	;YES, READ THE CHR
L00011: CALL	STAT		;CHECK LOCAL KB
	JNZ	L00012
	JMP	TRMECHO 	;..NO CHAR
L00012: CALL	KEYIN		;GET LOCAL CHAR
	CMP	AL,EXITCHR	;END?	JNZ	L00013
	JMP	CKDIS		;YES, CK DISCONN, EXIT
L00013: CMP	AL,DISCCHR	;DISCONN?	JNZ	L00014
	JMP	DISCONN 	;..YES, DO IT.
L00014: PUSH	DX
	MOV	DX,MODDATP
	OUT	DX,AL		;SEND CHAR
	POP	DX
	CALL	TYPEZZ		;ECHO IT LOCALLY
	JMP	TRMECHO 	;..AND LOOP
;
;GOT CHAR FROM LINE
;
LINECHR:
	PUSH	DX
	MOV	DX,MODDATP
	IN	AL,DX		;GET CHAR
	OUT	DX,AL		;ECHO IT
	POP	DX
	CALL	TYPEZZ		;TYPEZZ IT
	JMP	TRMECHO 	;LOOP
TRMECHO ENDP
;
; * * * * * * * * * * * * * * * * * * * *
;					*
;	SENDFIL: SENDS A CP/M FILE	*
;					*
; * * * * * * * * * * * * * * * * * * * *
;
;THE CP/M FILE SPECIFIED IN THE MODEM COMMAND
;IS TRANSFERRED OVER THE PHONE TO ANOTHER
;COMPUTER RUNNING MODEM WITH THE "R" (RECEIVE)
;OPTION.  THE DATA IS SENT ONE SECTOR AT A
;TIME WITH HEADERS AND CHECKSUMS, AND RE-
;TRANSMISSION ON ERRORS.
;
SENDFIL PROC	NEAR
	CALL	OPENFIL 	;OPEN THE FILE
	MOV	DL,80		;WAIT 80 SEC..
	CALL	WAITNAK 	;..FOR INITIAL NAK
SENDLP: CALL	RDSECT		;READ A SECTOR
	JAE	L00016
	JMP	SENDEOF 	;SEND EOF IF DONE
L00016: CALL	INCRSNO 	;BUMP SECTOR #
	XOR	AL,AL		;ZERO ERROR..
	MOV	ERRCT,AL	;..COUNT
SENDRPT:
	CALL	SENDHDR 	;SEND A HEADER
	CALL	SENDSEC 	;SEND DATA SECTOR
	CALL	SENDCKS 	;SEND CKSUM
	CALL	GETACK		;GET THE ACK
	JAE	L00017
	JMP	SENDRPT 	;REPEAT IF NO ACK
L00017: JMP	SENDLP		;LOOP UNTIL EOF
;
;FILE SENT, SEND EOT'S
;
SENDEOF:
	MOV	AL,EOT		;SEND..
	CALL	SEND		;..AN EOT
	CALL	GETACK		;GET THE ACK
	JAE	L00018
	JMP	SENDEOF 	;LOOP IF NO ACK
L00018: JMP	DONE		;ALL DONE
SENDFIL ENDP
;
; * * * * * * * * * * * * * * * * * * * *
;					*
;	RCVFIL: RECEIVE A FILE		*
;					*
; * * * * * * * * * * * * * * * * * * * *
;
;RECEIVES A FILE IN BLOCK FORMAT AS SENT
;BY ANOTHER PERSON DOING "MODEM S FN.FT".
;
RCVFIL	PROC	NEAR
	CALL	ERASFIL 	;ERASE THE FILE
	CALL	MAKEFIL 	;..THEN MAKE NEW
	MOV	AL,QFLG 	;SEE IF IN QUIET MODE
	OR	AL,AL
	JZ	L00019
	JMP	RCVLP		;NOT IN QUIET MODE, SKIP MSG
L00019: PUSH	BX
	MOV	BX,OFFSET MSG01A
	CALL	ILPRT		;PRINT:
	POP	BX
RCVLP:	CALL	RCVSECT 	;GET A SECTOR
	JAE	L00020
	JMP	RCVEOT		;GOT EOT
L00020: CALL	WRSECT		;WRITE THE SECTOR
	CALL	INCRSNO 	;BUMP SECTOR #
	CALL	SENDACK 	;ACK THE SECTOR
	JMP	RCVLP		;LOOP UNTIL EOF
;
;GOT EOT ON SECTOR - FLUSH BUFFERS, END
;
RCVEOT: CALL	WRBLOCK 	;WRITE THE LAST BLOCK
	CALL	SENDACK 	;ACK THE SECTOR
	CALL	CLOSFIL 	;CLOSE THE FILE
	MOV	AL,QFLG 	;QUIET..
	OR	AL,AL		;..MODE?	JNZ	L00021
	JMP	CKDIS		;YES, CK DISCONN, END.
L00021: JMP	DONE		;DISCONN IF REQ'D
RCVFIL	ENDP
;
; * * * * * * * * * * * * * * * * * * * *
;					*
;		SUBROUTINES		*
;					*
; * * * * * * * * * * * * * * * * * * * *
;
;
;---->	RCVSECT: RECEIVE A SECTOR
;
;RETURNS WITH CARRY SET IF EOT RECEIVED.
;
RCVSECT PROC	NEAR
	XOR	AL,AL		;GET 0
	MOV	ERRCT,AL	;INIT ERROR COUNT
RCVRPT: MOV	AL,QFLG 	;QUIET? OR	AL,AL
	JNZ	L00022
	JMP	RCVSQ		;YES, NO STAT MSG.
L00022: PUSH	BX
	MOV	BX,OFFSET MSG02
	CALL	ILPRT		;PRINT:
	POP	BX
	MOV	AL,SECTNO	;GET SECTOR #
	INC	AL		;(REAL INR LATER)
	CALL	HEXO		;PRINT IN HEX
	CALL	CRLF		;..THEN CRLF
;
RCVSQ:	MOV	CH,10		;10 SEC TIMEOUT
	CALL	RECV		;GET SOH/EOT
	JAE	L00023
	JMP	RCVSTOT 	;TIMEOUT
L00023: CMP	AL,SOH		;GET SOH?	JNZ	L00024
	JMP	RCVSOH		;..YES
;
;EARLIER VERS. OF MODEM PROG SENT SOME NULLS -
;IGNORE THEM
;
L00024: OR	AL,AL		;00 FROM SPEED CHECK?	JNZ	L00025
	JMP	RCVSQ		;YES, IGNORE IT
L00025: CMP	AL,EOT		;END OF TRANSFER?	STC			;RETURN WITH CARRY..
	JNZ	L00026
	RET			;..SET IF EOT
;
;DIDN'T GET SOH  OR EOT -
;
L00026: MOV	CH,AL		;SAVE CHAR
	MOV	AL,VSEEFLG	;VIEWING..
	OR	AL,AL		;..MODE?	JNZ	L00027
	JMP	RCVSEH		;YES, PRT.MSG
L00027: MOV	AL,QFLG 	;QUIET..
	OR	AL,AL		;..MODE?	JNZ	RCVSEH
	JMP	RCVSERR 	;YES, SKIP MSG
RCVSEH: MOV	AL,CH		;GET CHAR
	CALL	HEXO		;SHOW IN HEX
	PUSH	BX
	MOV	BX,OFFSET MSG03
	CALL	ILPRT		;PRINT:
	POP	BX
;
;DIDN'T GET VALID HEADER - PURGE THE LINE,
;THEN SEND NAK.
;
RCVSERR:
	MOV	CH,1		;WAIT FOR 1 SEC..
	CALL	RECV		;..WITH NO CHARS
	JNAE	L00029
	JMP	RCVSERR 	;LOOP UNTIL SENDER DONE
L00029: MOV	AL,NAK		;SEND..
	CALL	SEND		;..THE NAK
	MOV	AL,ERRCT	;ABORT IF..
	INC	AL		;..WE HAVE REACHED..
	MOV	ERRCT,AL	;..THE ERROR..
	CMP	AL,ERRLIM	;..LIMIT?	JAE	L00030
	JMP	RCVRPT		;..NO, TRY AGAIN
;
;10 ERRORS IN A ROW -
;
L00030: MOV	AL,VSEEFLG	;VIEWING..
	OR	AL,AL		;..FILE?	JNZ	L00031
	JMP	RCVCKQ		;YES, ASK RETRY/QUIT
L00031: MOV	AL,QFLG 	;QUIET..
	OR	AL,AL		;..MODE?	JNZ	RCVCKQ
	JMP	RCVSABT 	;ABORT
RCVCKQ: CALL	CKQUIT		;RETRY/QUIT?	JNZ	RCVSABT
	JMP	RCVSECT 	;TRY AGAIN
;
RCVSABT:
	CALL	CLOSFIL 	;KEEP WHATEVER WE GOT
	MOV	DX,OFFSET MSG20
	CALL	ERXIT
;
;TIMEDOUT ON RECEIVE
;
RCVSTOT:
	STI
	MOV	AL,VSEEFLG	;VIEWING..
	OR	AL,AL		;..MODE?	JNZ	L00034
	JMP	RCVSPT		;YES, PRT MSG
L00034: MOV	AL,QFLG 	;QUIET..
	OR	AL,AL		;..MODE?	JNZ	RCVSPT
	JMP	RCVSERR 	;YES, NO MSG
RCVSPT: PUSH	BX
	MOV	BX,OFFSET MSG03
	CALL	ILPRT
	POP	BX
RCVPRN: MOV	AL,ERRCT	;PRINT ERROR..
	CALL	HEXO		;..COUNT
	CALL	CRLF
	JMP	RCVSERR 	;BUMP ERR CT, ETC.
;
;GOT SOH - GET BLOCK #, BLOCK # COMPLEMENTED
;
RCVSOH: MOV	CH,1		;TIMEOUT = 1 SEC
	CALL	RECV		;GET SECTOR
	JAE	L00036
	JMP	RCVSTOT 	;GOT TIMEOUT
L00036: MOV	DH,AL		;D=BLK #
	MOV	CH,1		;TIMEOUT = 1 SEC
	CALL	RECV		;GET CMA'D SECT #
	JAE	L00037
	JMP	RCVSTOT 	;TIMEOUT
L00037: NOT	AL		;CALC COMPLEMENT
	CMP	AL,DH		;GOOD SECTOR #? JNZ	L00038
	JMP	RCVDATA 	;YES, GET DATA
;
;GOT BAD SECTOR #
;
L00038: MOV	AL,VSEEFLG	;VIEWING..
	OR	AL,AL		;..MODE?	JNZ	L00039
	JMP	RCVBSE		;..YES, PRT MSG
L00039: MOV	AL,QFLG 	;QUIET..
	OR	AL,AL		;..MODE?	JNZ	RCVBSE
	JMP	RCVSERR 	;..YES, NO MSG
;
RCVBSE: PUSH	BX
	MOV	BX,OFFSET MSG04
	CALL	ILPRT		;PRINT:
	POP	BX
	JMP	RCVSERR 	;BUMP ERROR CT.
;
;
RCVDATA:
	MOV	AL,DH		;GET SECTOR #
	MOV	RCVSNO,AL	;SAVE IT
	MOV	AL,1		;SHOW..
	MOV	DATAFLG,AL	;GETTING DATA
	MOV	CL,0		;INIT CKSUM
	MOV	BX,80H		;POINT TO BUFFER
	CLI
RCVCHR: MOV	CH,1		;1 SEC TIMEOUT
	CALL	RECV		;GET CHAR
	JAE	L00041
	JMP	RCVSTOT 	;TIMEOUT
L00041: MOV	BYTE PTR [BX],AL ;STORE CHAR
	INC	BL		;DONE?	JZ	L00042
	JMP	RCVCHR		;NO, LOOP
;
;VERIFY CHECKSUM
;
L00042: MOV	DH,CL		;SAVE CHECKSUM
	XOR	AL,AL		;SHOW..
	MOV	DATAFLG,AL	;..END OF DATA
	MOV	CH,1		;TIMEOUT LEN.
	CALL	RECV		;GET CHECKSUM
	JAE	L00043
	JMP	RCVSTOT 	;TIMEOUT
L00043: STI
	CMP	AL,DH		;CHECKSUM OK?	JZ	L00044
	JMP	RCVCERR 	;NO, ERROR
;
;GOT A SECTOR, IT'S A DUP IF = PREV,
;	OR OK IF = 1 + PREV SECTOR
;
L00044: MOV	AL,RCVSNO	;GET RECEIVED
	MOV	CH,AL		;SAVE IT
	MOV	AL,SECTNO	;GET PREV
	CMP	AL,CH		;PREV REPEATED? JNZ	L00045
	JMP	RECVACK 	;ACK TO CATCH UP
L00045: INC	AL		;CALC NEXT SECTOR #
	CMP	AL,CH		;MATCH? JZ	L00046
	JMP	ABORT		;NO MATCH - STOP SENDER, EXIT
L00046: RET			;CARRY OFF - NO ERRORS
;
;GOT CKSUM
;
RCVCERR:
	MOV	AL,VSEEFLG	;VIEWING..
	OR	AL,AL		;..MODE?	JNZ	L00047
	JMP	RCVCPR		;..YES, PRT MSG
L00047: MOV	AL,QFLG 	;QUIET..
	OR	AL,AL		;..MODE?	JNZ	RCVCPR
	JMP	RCVSERR 	;YES, NO MSG
RCVCPR: PUSH	BX
	MOV	BX,OFFSET MSG05
	CALL	ILPRT
	POP	BX
	JMP	RCVPRN		;PRINT ERROR #
;
;PREV SECT REPEATED, DUE TO THE LAST ACK
;BEING GARBAGED.  ACK IT SO SENDER WILL CATCH UP
;
RECVACK:
	CALL	SENDACK 	;SEND THE ACK,
	JMP	RCVSECT 	;GET NEXT BLOCK
;
;SEND AN ACK FOR THE SECTOR
;
SENDACK:
	MOV	AL,ACK		;GET ACK
	CALL	SEND		;..AND SEND IT
	RET
RCVSECT ENDP
;
;---->	SENDHDR: SEND THE SECTOR HEADER
;
;SEND: (SOH) (BLOCK #) (COMPLEMENTED BLOCK #)
;
SENDHDR PROC	NEAR
	MOV	AL,QFLG 	;QUIET..
	OR	AL,AL		;..MODE?	JNZ	L00049
	JMP	SENDHNM 	;YES, SKIP STATUS MSG.
L00049: PUSH	BX
	MOV	BX,OFFSET MSG06
	CALL	ILPRT		;PRINT:
	POP	BX
	MOV	AL,SECTNO	;PRINT..
	CALL	HEXO		;..SECT #
	CALL	CRLF		;..THEN CR/LF
;
SENDHNM:
	MOV	AL,SOH		;SEND..
	CALL	SEND		;..SOH,
	MOV	AL,SECTNO	;THEN SEND..
	CALL	SEND		;..SECTOR #
	MOV	AL,SECTNO	;THEN SENDOR #
	NOT	AL		;..COMPLEMENTED..
	CALL	SEND		;..SECTOR #
	RET			;FROM SENDHDR
SENDHDR ENDP
;
;---->	SENDSEC: SEND THE DATA SECTOR
;
;WHILE SENDING THE SECTOR, THE "DATAFLG" IS SET
;SUCH THAT IF "V" (VIEW THE FILE) WAS REQUESTED,
;THE "SHOW" ROUTINE WILL PRINT THE DATA, BUT NOT
;THE HDR OR CKSUM, OR ANY NON-FATAL MSGS.
;
SENDSEC PROC	NEAR
	MOV	AL,1		;SHOW NOW AT DATA..
	MOV	DATAFLG,AL	;..FOR VIEW COMMAND
	MOV	CL,0		;INIT CKSUM
	MOV	BX,80H		;POINT TO BUFFER
SENDC:	MOV	AL,BYTE PTR [BX] ;GET A CHAR
	CALL	SEND		;SEND IT
	INC	BL		;POINT TO NEXT CHAR
	JZ	L00050
	JMP	SENDC		;LOOP IF <100H
L00050: XOR	AL,AL		;SHOW NOT INTO DATA..
	MOV	DATAFLG,AL	;..FOR VIEW COMMAND
	RET			;FROM SENDSEC
SENDSEC ENDP
;
;---->	SENDCKS: SEND THE CHECKSUM
;
SENDCKS PROC	NEAR
	MOV	AL,CL		;SEND THE..
	CALL	SEND		;..CHECKSUM
	RET			;FROM SENDCKS
SENDCKS ENDP
;
;---->	GETACK: GET THE ACK ON THE SECTOR
;
;RETURNS WITH CARRY CLEAR IF ACK RECEIVED.
;IF AN ACK IS NOT RECEIVED, THE ERROR COUNT
;IS INCREMENTED, AND IF LESS THAN "ERRLIM",
;CARRY IS SET AND CONTROL RETURNS.  IF THE
;ERROR COUNT IS AT "ERRLIM", THE PROGRAM
;ABORTS IF IN "QUIET" MODE, OR ASKS THE
;USER FOR QUIT/RETRY IF NOT.
;
GETACK	PROC	NEAR
	MOV	CH,10		;WAIT 10 SECONDS MAX
	CALL	RECVDG		;RECV W/GARBAGE COLLECT
	JAE	L00051
	JMP	GESATOT 	;TIMED OUT
L00051: CMP	AL,ACK		;OK? (CARRY OFF IF =)
	JNZ	L00052
	RET			;YES, RET FROM GETACK
;
L00052	LABEL	NEAR
	IF	CANFLG
	CMP	AL,CAN		;CANCEL TRANSMISSION?	JNZ	L00053
	JMP	ABORT		;..YES
L00053	LABEL	NEAR
	ENDIF
;
	MOV	CH,AL		;SAVE CHAR
	MOV	AL,QFLG 	;QUIET..
	OR	AL,AL		;..MODE?	JNZ	L00054
	JMP	ACKERR		;..YES, NO MSG
L00054: MOV	AL,CH		;GET CHAR
	CALL	HEXO		;PRINT IN HEX
	PUSH	BX
	MOV	BX,OFFSET MSG07
	CALL	ILPRT		;PRINT:
	POP	BX
;
;TIMEOUT OR ERROR ON ACK - BUMP ERROR COUNT
;
ACKERR: MOV	AL,ERRCT	;GET COUNT
	INC	AL		;BUMP IT
	MOV	ERRCT,AL	;SAVE BACK
	CMP	AL,ERRLIM	;AT LIMIT?	JNB	L00055
	RET			;NOT AT LIMIT
;
;REACHED ERROR LIMIT
;
L00055: MOV	AL,VSEEFLG	;VIEWING..
	OR	AL,AL		;..FILE?	JNZ	L00056
	JMP	GACKV		;YES, ASK QUIT/RETRY
L00056: MOV	AL,QFLG 	;QUIET..
	OR	AL,AL		;..MODE?	JNZ	GACKV
	JMP	CSABORT 	;..YES, NO MCG
GACKV:	CALL	CKQUIT		;SEE IF WANT TO QUIT
	STC			;TO SHOW NO ACK
	JNZ	CSABORT
	RET			;KEEP ON TRYIN'
CSABORT:
	MOV	DX,OFFSET MSG21
	CALL	ERXIT
GETACK	ENDP
;
;TIMEOUT GETTING ACK
;
GESATOT PROC	NEAR
	MOV	AL,QFLG 	;QUIET..
	OR	AL,AL		;..MODE?	JNZ	L00059
	JMP	ACKERR		;YES, NO MSG
L00059: PUSH	BX
	MOV	BX,OFFSET MSG08
	CALL	ILPRT		;PRINT:
	POP	BX
	JMP	ACKERR
GESATOT ENDP
;
;---->	CKABORT: CHECK FOR LOCAL ABORT
;
;IF THE USER WANTS TO CANCEL THE TRANSMISSION,
;TYPING CTL-X WILL ABORT IT.  NOTE THIS TEST
;IS NOT MADE IF IN QUIET (NO CONSOLE I/O) MODE.
;
CKABORT PROC	NEAR
	MOV	AL,VSEEFLG	;VIEWING?	OR	AL,AL
	JNZ	L00060
	JMP	CKABGO		;YES, CHECK
L00060: MOV	AL,QFLG 	;SUPPRESSED..
	OR	AL,AL		;..CONSOLE I/O? JNZ	L00061
	RET			;YES, NO TEST
;
L00061	LABEL	NEAR
	IF NOT CANFLG
	RET
	ENDIF
;
CKABGO: CALL	STAT		;KEY PRESSED?	JNZ	L00062
	RET			;NOTHING FROM KEYBOARD
L00062: CALL	KEYIN		;GET DATA
	CMP	AL,EXITCHR	;TIME TO END?	JZ	ABORT
	RET			;NO, CONTINUE
;
ABORT:	NOP			;LEA	SP,STACK
ABORTL: MOV	CH,1		;1 SEC. W/O CHARS.
	CALL	RECV
	JNAE	L00064
	JMP	ABORTL		;LOOP UNTIL SENDER DONE
L00064: MOV	AL,CAN		;CONTROL X
	CALL	SEND		;STOP SENDING END
ABORTW: MOV	CH,1		;1 SEC W/O CHARS.
	CALL	RECV
	JNAE	L00065
	JMP	ABORTW		;LOOP UNTIL SENDER DONE
L00065: MOV	AL,' '          ;GET A SPACE...
	CALL	SEND		;TO CLEAR OUT CONTROL X
	PUSH	BX
	MOV	BX,OFFSET MSG09
	CALL	ILPRT		;EXIT WITH ABORT MSG
	POP	BX
	JMP	CKDIS		;CHECK FOR DISCONN.
CKABORT ENDP
;
;---->	INCRSNO: INCREMENT SECTOR #
;
INCRSNO PROC	NEAR
	MOV	AL,SECTNO	;INCR..
	INC	AL		;..SECT..
	MOV	SECTNO,AL	;..NUMBER
	RET
INCRSNO ENDP
;
;---->	ERASFIL: ERASE THE INCOMING FILE.
;
;IF IT EXISTS, ASK IF IT MAY BE ERASED.
;
ERASFIL PROC	NEAR
	MOV	DX,OFFSET FCB	;POINT TO CTL BLOCK
	MOV	CL,SRCHF	;SEE IF IT..
	CALL	BDOS		;..EXISTS
	INC	AL		;FOUND? JNZ	L00066
	RET			;..NO, RETURN
L00066: PUSH	BX
	MOV	BX,OFFSET MSG10
	CALL	ILPRT		;PRINT:
	POP	BX
	CALL	KEYIN		;GET CHAR
	LAHF
	XCHG	AL,AH
	PUSH	AX
	XCHG	AL,AH
	CALL	TYPEZZ		;ECHO
	POP	AX
	XCHG	AL,AH
	SAHF
	AND	AL,5FH		;MAKE UPPER CASE
	CMP	AL,'Y'          ;WANT ERASED?   JZ      L00067
	JMP	CKDIS		;QUIT IF NOT ERASE
L00067: CALL	CRLF		;BACK TO START OF LINE
;
;ERASE OLD FILE
;
	MOV	DX,OFFSET FCB	;POINT TO FCB
	MOV	CL,ERASE	;GET BDOS FNC
	CALL	BDOS		;DO THE ERASE
	RET			;FROM "ERASFIL"
ERASFIL ENDP
;
;---->	MAKEFIL: MAKES THE FILE TO BE RECEIVED
;
MAKEFIL PROC	NEAR
	MOV	DX,OFFSET FCB	;POINT TO FCB
	MOV	CL,MAKE 	;GET BDOS FNC
	CALL	BDOS		;TO THE MAKE
	INC	AL		;FF=BAD?	JZ	L00068
	RET			;OPEN OK
;DIRECTORY FULL - CAN'T MAKE FILE
L00068: MOV	DX,OFFSET MSG22
	CALL	ERXIT
MAKEFIL ENDP
;
;---->	OPENFIL: OPENS THE FILE TO BE SENT
;
OPENFIL PROC	NEAR
	MOV	DX,OFFSET FCB	;POINT TO FILE
	MOV	CL,OPEN 	;GET FUNCTION
	CALL	BDOS		;OPEN IT
	INC	AL		;OPEN OK?	JZ	L00069
	JMP	OPENOK		;..YES
L00069: PUSH	DX
	MOV	DX,OFFSET MSG11
	CALL	ERXIT		;..NO, ABORT
	POP	DX
;
OPENOK:
	PUSH	X
	MOV	BX,OFFSET MSG12
	CALL	ILPRT		;PRINT:
	POP	BX
	MOV	AL,FCBSZH	;GET FILE SIZE HIGH ORDER
	CALL	HEXO		;PRINT IN HEX
	MOV	AL,FCBSZL	;GET FILE SIZE LOW ORDER
	CALL	HEXO		;PRINT IN HEX
	MOV	AL,'H'
	CALL	TYPEZZ		;PRINT 'H' AFTER NUMBER
	CALL	CRLF		;..THEN CRLF
	RET
OPENFIL ENDP
;
;---->	CLOSFIL: CLOSES THE RECEIVED FILE
;
CLOSFIL PROC	NEAR
	MOV	DX,OFFSET FCB	;POINT TO FILE
	MOV	CL,CLOSE	;GET FUNCTION
	CALL	BDOS		;CLOSE IT
	INC	AL		;CLOSE OK?	JZ	L00070
	RET			;..YES, RETURN
L00070: MOV	DX,OFFSET MSG22A
	CALL	ERXIT		;..NO, ABORT
CLOSFIL ENDP
;
;---->	RDSECT: READS A SECTOR
;
;FOR SPEED, THIS ROUTINE BUFFERS UP 16
;SECTORS AT A TIME.
;
RDSECT	PROC	NEAR
	MOV	AL,SECINBF	;GET # SECT IN BUFF.
	DEC	AL		;DECREMENT..
	MOV	SECINBF,AL	;..IT
	JNS	L00071
	JMP	RDBLOCK 	;EXHAUSTED?  NEED MORE.
L00071: MOV	BX,SECPTR	;GET POINTER
	MOV	DX,80H		;TO DATA
	CALL	MOVE128 	;MOVE TO BUFFER
	MOV	SECPTR,BX	;SAVE BUFFER POINTER
	RET			;FROM "READSEC"
;
;BUFFER IS EMPTY - READ IN ANOTHER BLOCK OF 16
;
RDBLOCK LABEL	NEAR
	MOV	AL,EOFLG	;GET EOF FLAG
	CMP	AL,1		;IS IT SET/
	STC			;TO SHOW EOF
	JNZ	L00072
	RET			;GOT EOF
L00072: MOV	CL,0		;SECTORS IN BLOCK
	LEA	DX,DBUF 	;TO DISK BUFFER
RDSECLP LABEL	NEAR
	PUSH	CX
	PUSH	DX
	MOV	CL,STDMA	;SET DMA..
	CALL	BDOS		;..ADDR
	MOV	DX,OFFSET FCB
	MOV	CL,READ
	CALL	BDOS
	POP	DX
	POP	CX
	OR	AL,AL		;READ OK?	JNZ	L00073
	JMP	RDSECOK 	;YES
L00073: DEC	AL		;EOF?	JZ	REOF		; 1 = EOF (regular)
	DEC	AL
	JZ	L00074		; 2 = ERROR (trans area too small)
	DEC	AL
	JZ	REOF		; 3 = EOF (partial block)
	JMP	L00074		; ALL OTHER RETURNS CONSIDERED ERROR !!!
;
;READ ERROR
;
L00074: MOV	DX,OFFSET MSG23
	CALL	ERXIT
;
RDSECOK:
	MOV	BX,80H
	PUSH	SI
	PUSHF
	ADD	BX,DX
	RCR	SI,1
	POPF
	RCL	SI,1
	POP	SI		;TO NEXT BUFF
	XCHG	BX,DX		;BUFF TO DE
	INC	CL		;MORE SECTORS?	MOV	AL,CL		;GET COUNT
	CMP	AL,16		;DONE?	JNZ	L00075
	JMP	RDBFULL 	;..YES, BUFF IS FULL
L00075: JMP	RDSECLP 	;READ MORE
;
REOF:	MOV	AL,1
	MOV	EOFLG,AL	;SET EOF FLAG
	MOV	AL,CL
;
;BUFFER IS FULL, OR GOT EOF
;
RDBFULL:
	MOV	SECINBF,AL	;STORE SECTOR COUNT
	MOV	BX,OFFSET DBUF	;INIT BUFFER..
	MOV	SECPTR,BX	;..POINTER
	MOV	DX,80H		;RESET..
	MOV	CL,STDMA	;..DMA..
	CALL	BDOS		;..ADDR
	JMP	RDSECT		;PASS SECT TO CALLER
RDSECT	ENDP
;
;---->	WRSECT: WRITE A SECTOR
;
;WRITES THE SECTOR INTO A BUFFER.  WHEN 16
;HAVE BEEN WRITTEN, WRITES THE BLOCK TO DISK.
;
;ENTRY POINT "WRBLOCK" FLUSHES THE BUFFER AT EOF.
;
WRSECT	PROC	NEAR
	MOV	BX,SECPTR	;GET BUFF ADDR
	XCHG	BX,DX		;TO DE FOR MOVE
	MOV	BX,80H		;FROM HERE
	CALL	MOVE128 	;MOVE TO BUFFER
	XCHG	BX,DX		;SAVE NEXT..
	MOV	SECPTR,BX	;..BLOCK POINTER
	MOV	AL,SECINBF	;BUMP THE..
	INC	AL		;..SECTOR #..
	MOV	SECINBF,AL	;..IN THE BUFF
	CMP	AL,16		;HAVE WE 16?	JZ	WRBLOCK
	RET			;NO, RETURN
;
;---->	WRBLOCK: WRITES A BLOCK TO DISK
;
WRBLOCK:
	MOV	AL,SECINBF	;# SECT IN BUFFER
	OR	AL,AL		;0 MEANS END OF FILE
	JNZ	L00077
	RET			;NONE TO WRITE
L00077: MOV	CL,AL		;SAVE COUNT
	LEA	DX,DBUF 	;POINT TO DISK BUFF
DKWRLP: PUSH	BX
	PUSH	DX
	PUSH	CX
	MOV	CL,STDMA	;SET DMA
	CALL	BDOS		;TO BUFFER
	MOV	DX,OFFSET FCB	;THEN WRITE
	MOV	CL,WRITE	;..THE..
	CALL	BDOS		;..BLOCK
	POP	CX
	POP	DX
	POP	BX
	OR	AL,AL
	JZ	L00078
	JMP	WRERR		;OOPS, ERROR
L00078: MOV	BX,80H		;LENGTH OF 1 SECT
	PUSH	SI
	PUSHF
	ADD	BX,DX
	RCR	SI,1
	POPF
	RCL	SI,1
	POP	SI		;HL= NEXT BUFF
	XCHG	BX,DX		;TO DE FOR SETDMA
	DEC	CL		;MORE SECTORS?		JZ	L00079
	JMP	DKWRLP		;..YES, LOOP
L00079: XOR	AL,AL		;GET A ZERO
	MOV	SECINBF,AL	;RESET # OF SECTORS
	MOV	BX,OFFSET DBUF	;RESET BUFFER..
	MOV	SECPTR,BX	;..POINTER
;
	MOV	DX,80H		;07/13/79 MOD..
	MOV	CL,STDMA	;..TO RESET..
	CALL	BDOS		;..DMA ADDR.
;
	RET
;
WRERR:	MOV	CL,CAN		;CANCEL..
	CALL	SEND		;..SENDER
	MOV	DX,OFFSET MSG24
	CALL	ERXIT		;EXIT W/MSG:
WRSECT	ENDP
;
;---->	RECV: RECEIVE A CHARACTER
;
;TIMEOUT TIME IS IN B, IN SECONDS.  ENTRY VIA
;"RECVDG" DELETES GARBAGE CHARACTERS ON THE
;LINE.	FOR EXAMPLE, HAVING JUST SENT A SECTOR,
;CALLING RECVDG WILL DELETE ANY LINE-NOISE-INDUCED
;CHARACTERS "LONG" BEFORE THE ACK/NAK WOULD
;BE RECEIVED.
;
RECCHAR PROC	NEAR
RECVDG	LABEL	NEAR		;RECEIVE W/GARBAGE DELETE
	PUSH	DX
	MOV	DX,MODDATP
	IN	AL,DX		;GET A CHAR
	IN	AL,DX		;..TOTALLY PURGE UART
	POP	DX
;
RECV:	PUSH	DX		;SAVE
;
	IF	FASTCLK 	;4MHZ?	MOV	AL,CH		;GET TIME REQUEST
	ADD	AL,AL		;DOUBLE IT
	MOV	CH,AL		;NEW TIME IN B
	ENDIF
;
MSEC:	MOV	DX,50000	;1 SEC DCR COUNT
	CALL	CKABORT 	;CHECK FOR EXIT REQUEST
MWTI:	PUSH	DX
	MOV	DX,MODCTLP
	IN	AL,DX		;CHECK STATUS
	POP	DX
	AND	AL,MODRCVB	;ISOLATE BIT
	CMP	AL,MODRCVR	;READY? JNZ	L00080
	JMP	MCHAR		;GOT CHAR
L00080: DEC	DL		;COUNT..
	JZ	L00081
	JMP	MWTI		;..DOWN..
L00081: DEC	DH		;..FOR..
	JZ	L00082
	JMP	MWTI		;..TIMEOUT
L00082: DEC	CH		;MORE SECONDS?	JZ	L00083
	JMP	MSEC		;YES, WAIT
;
;MODEM TIMED OUT RECEIVING
;
L00083: POP	DX		;RESTORE D,E
	STC			;CARRY SHOWS TIMEOUT
	RET
;
;GOT CHAR FROM MODEM
;
MCHAR:	PUSH	DX
	MOV	DX,MODDATP
	IN	AL,DX		;READ THE CHAR
	POP	DX
	POP	DX		;RESTORE DE
;
;CALC CHECKSUM
;
	LAHF
	XCHG	AL,AH
	PUSH	AX
	XCHG	AL,AH		;SAVE THE CHAR
	ADD	AL,CL		;ADD TO CHECKSUM
	MOV	CL,AL		;SAVE CHECKSUM
;
;CHECK IF MONITORING REC'D DATA
;
	MOV	AL,RSEEFLG	;SEE RECEIVED..
	OR	AL,AL		;..DATA?	JNZ	L00084
	JMP	MONIN		;..YES
;
;CHECK IF "VIEWING" AND THIS IS A DATA CHAR
;
L00084: MOV	AL,VSEEFLG	;VIEWING..
	OR	AL,AL		;..DATA?	JZ	L00085
	JMP	NOMONIN 	;..NO
;
;"VIEW" REQUESTED.  SHOW THE CHAR IT IS DATA
;
L00085: MOV	AL,DATAFLG	;GET DATA FLAG
	OR	AL,AL		;TEST IT
	JNZ	MONIN
	JMP	NOMONIN 	;..OFF, NOT DATA
MONIN:	POP	AX
	XCHG	AL,AH
	SAHF			;..IS DATA,
	LAHF
	XCHG	AL,AH
	PUSH	AX
	XCHG	AL,AH		;GET IT,
	CALL	SHOW		;..AND SHOW IT
NOMONIN:
	POP	AX
	XCHG	AL,AH
	SAHF			;RESTORE CHAR
	OR	AL,AL		;CARRY OFF: NO ERROR
	RET			;FROM "RECV"
RECCHAR ENDP
;
;---->	SEND: SEND A CHARACTER TO THE MODEM
;
SEND	PROC	NEAR
	LAHF
	XCHG	AL,AH
	PUSH	AX
	XCHG	AL,AH		;SAVE THE CHAR
;
;CHECK IF MONITORING SENT DATA
;
	MOV	AL,SSEEFLG	;CHECK IF MONITORING..
	OR	AL,AL		;..SENT DATA
	JNZ	L00087
	JMP	MONOUT		;..YES
;
;CHECK IF "VIEWING" THE FILE
;
L00087: MOV	AL,VSEEFLG	;GET VIEW FLAG
	OR	AL,AL		;TEST IT
	JZ	L00088
	JMP	NOMONOT 	;NO
L00088: MOV	AL,DATAFLG	;IS THIS
	OR	AL,AL		;..DATA?	JNZ	MONOUT
	JMP	NOMONOT 	;..NO.
MONOUT: POP	AX
	XCHG	AL,AH
	SAHF			;GET THE CHAR
	LAHF
	XCHG	AL,AH
	PUSH	AX
	XCHG	AL,AH		;SAVE IT
	CALL	SHOW		;SHOW IT
NOMONOT:
	POP	AX
	XCHG	AL,AH
	SAHF			;RESTORE CHAR
	LAHF
	XCHG	AL,AH
	PUSH	AX
	XCHG	AL,AH		;SAVE IT
	ADD	AL,CL		;CALC CKSUM
	MOV	CL,AL		;SAVE CKSUM
SENDW:	PUSH	DX
	MOV	DX,MODCTLP
	IN	AL,DX		;GET STATUS
	POP	DX
	AND	AL,MODSNDB	;ISOLATE READY BIT
	CMP	AL,MODSNDR	;READY? JZ	L00090
	JMP	SENDW		;..NO, WAIT
L00090: POP	AX
	XCHG	AL,AH
	SAHF			;GET CHAR
	PUSH	DX
	MOV	DX,MODDATP
	OUT	DX,AL		;OUTPUT IT
	POP	DX
	RET			;FROM "SEND"
SEND	ENDP
;
;---->	WAITNAK: WAITS FOR INITIAL NAK
;
;TO ENSURE NO DATA IS SENT UNTIL THE RECEIVING
;PROGRAM IS READY, THIS ROUTINE WAITS FOR THE
;THE FIRST TIMEOUT-NAK FROM THE RECEIVER.  (E)
;CONTAINS THE # OF SECONDS TO WAIT.
;
WAITNAK PROC	NEAR
	MOV	AL,VSEEFLG	;VIEWING?	OR	AL,AL
	JNZ	L00091
	JMP	WAITNPR 	;PRINT MSG
L00091: MOV	AL,QFLG 	;QUIET..
	OR	AL,AL		;..MODE?	JNZ	WAITNPR
	JMP	WAITNLP 	;YES, SKIP MSG
WAITNPR LABEL	NEAR
	PUSH	BX
	MOV	BX,OFFSET MSG13
	CALL	ILPRT		;PRINT:
	POP	BX
WAITNLP LABEL	NEAR
	CALL	CKABORT 	;ABORT IF LOCAL CTL-X
	MOV	CH,1		;TIMEOUT DELAY
	CALL	RECV		;DID WE GET..
	CMP	AL,NAK		;..A NAK?	JNZ	L00093
	RET			;YES, SEND BLOCK
;
L00093	LABEL	NEAR
	IF CANFLG
	CMP	AL,CAN		;CTL-X FROM REMOTE?	JNZ	L00094
	JMP	ABORT		;..YES, ABORT
L00094	LABEL	NEAR
	ENDIF
;
	DEC	DL		;80 TRIES?	JNZ	L00095
	JMP	ABORT		;YES, ABORT
L00095: JMP	WAITNLP 	;NO, LOOP
WAITNAK ENDP
;
;
;---->	PROCOPT: PROCESS COMMAND OPTIONS
;
;1) SAVES THE PRIMARY OPTION IN 'OPTION';
;2) IF OPTION 'H' (HELP) IS ASKED FOR,
;TRANSFERS DIRECTLY TO THE HELP PRINT;
;3) SCANS THE SUB-OPTION CHARACTERS, AND FOR
;EACH FOUND, ZEROS THE APPROPRIATE ENTRY IN
;THE OPTION TABLE.  FOR EXAMPLE, IF 'D' IS
;CODED (DISCONNECT) THEN THE 'D' STORED AT
;'DISCFLG' IS SET TO 0 SO IT CAN BE TESTED
;LATER.
;
PROCOPT PROC	NEAR
	MOV	DX,OFFSET FCBNAME ;TO PRIMARY OPT.
	XCHG	BX,DX
	MOV	AL,ES:[BX]	;GET PRIMARY OPT.
	XCHG	BX,DX
	MOV	OPTION,AL	;SAVE IT
	CMP	AL,'X'          ;MODEM EXAMPLES?        JNZ     L00096
	JMP	EXAM		;..YES, GIVE EXAMPLES
L00096: CMP	AL,'H'          ;MODEM H(ELP)?  JNZ     OPTLP
	JMP	HELP		;..YES, GIVE HELP
OPTLP:	PUSHF
	INC	DX		;TO SECONDARY OPTION
	POPF
	XCHG	BX,DX
	MOV	AL,ES:[BX]	;GET CHAR
	XCHG	BX,DX
;
;IF YOU MOD THIS PROGRAM FOR >7 OPTIONS,
;YOU MUST CHANGE THE FOLLOWING, SINCE
;THERE WON'T BE A ' ' AFTER THE OPTION
;IF A BAUD RATE WAS SPECIFIED.
;
	CMP	AL,' '          ;NO MORE OPT'NS?        JNZ     L00097
	JMP	ENDOPT		;..YES
;SET THE APPROP. OPT: STORE 0 IN IT
L00097: MOV	BX,OFFSET OPTBL ;HL = ADDR OF 'OAQDSRV'
	MOV	CX,TABLESIZE	;OPT TABLE LEN
OPTCK:	CMP	AL,BYTE PTR [BX] ;FOUND THE OPTION?	JZ	L00098
	JMP	OPTNO		;NO, DON'T SET IT
L00098: MOV	BYTE PTR [BX],0 ;SET THE OPTION
	JMP	OPTLP		;GET NEXT OPTION
OPTNO:	PUSHF
	INC	BX
	POPF			;TO NEXT
	DEC	CX		;MORE?	JZ	L00099
	JMP	OPTCK
;OPTION NOT IN TABLE
L00099: JMP	BADOPT		;SHOW BAD SUB OPTION
;
;IF "VIEW" WAS ASKED FOR, SET QUIET FLAG
;
ENDOPT: MOV	AL,VSEEFLG	;VIEW..
	OR	AL,AL		;..ASKED FOR?	JZ	L00100
	RET			;..NO, RET FROM 'PROCOPT'
L00100: MOV	QFLG,AL 	;YES, NO HDR/CKSUM PRT
	RET			;FROM 'PROCOPT'
PROCOPT ENDP
;
;DONE - CLOSE UP SHOP
;
DONE	PROC	NEAR
	MOV	AL,VSEEFLG	;VIEWING?	OR	AL,AL
	JNZ	L00101
	JMP	DONETC		;SHOW MSG
L00101: MOV	AL,QFLG 	;QUIET
	OR	AL,AL		;..MODE?	JNZ	DONETC
	JMP	DONECTE 	;YES, CK TERM/ECHO
DONETC: PUSH	BX
	MOV	BX,OFFSET MSG14
	CALL	ILPRT
	POP	BX
;
;CHECK IF TERMINAL OR ECHO SUB COMMAND
;WAS SPECIFIED
;
DONECTE:
	MOV	AL,TERMFLG	;TERM?	OR	AL,AL
	JNZ	L00103
	JMP	TERM		;..YES
L00103: MOV	AL,ECHOFLG	;ECHO?	OR	AL,AL
	JNZ	CKDIS
	JMP	TRMECHO 	;..YES
;
;FALL INTO 'CKDIS'
;
;---->	CKDIS: CHECK IF DISCONNECT REQUESTED
;
;THIS ROUTINE IS JUMPED TO AT THE END OF
;PROCESSING, AND DISCONNECTS THE PHONE IF
;'D' WAS SPECIFIED AS A SUB-OPTION.
;
CKDIS:	MOV	AL,DISCFLG	;CHECK 'D' FLAG
	OR	AL,AL		;REQUESTED?;							x d x
;	IF	NOT PMMI			     x e x
;	JZ	L00106				     x l x
;	JMP	EXIT				     x e x
;L00106  LABEL	NEAR				     x t x
;	ENDIF					     x e x
;						     x d x
;AWAIT C/R TO DISC. SO WE DON'T LOSE THE PHONE
;
	PUSH	BX
	MOV	BX,OFFSET MSG15
	CALL	ILPRT
	POP	BX
	CALL	KEYIN
	LAHF
	XCHG	AL,AH
	PUSH	AX
	XCHG	AL,AH
	CALL	CRLF
	POP	AX
	XCHG	AL,AH
	SAHF
	CMP	AL,0DH
	JZ	DISCONN
	JMP	CKDIS			;ASK AGAIN
;
;---->	DISCONN: DISCONNECT THE PHONE
;
DISCONN LABEL	NEAR
	PUSH	BX
	MOV	BX,OFFSET MSG16
	CALL	ILPRT			;PRINT:
	POP	BX
	JMP	EXIT
DONE	ENDP
;
;NO DISCONNECT, TYPEZZ MSG AS REMINDER THAT PHONE'S
;ON HOOK
;
;
;---->	INITMOD: INITIALIZED THE MODEM
;
;THIS ROUTINE IS USED TO INITIALIZE SERIAL
;PORT USED BY THE PROGRAM.  IT INCLUDES SUPPORT FOR
;SELECTING WHICH OF THE THREE UARTS SUPPORTED BY THE IBM/PC
;ARCHITECTURE WILL BE USED FOR THIS TRANSMISSION
;
;
;
INITMOD PROC	NEAR
;
;	ONLY THE "dtr up" PORTION OF THIS MODEM INITIALIZATION,
;	[and THE PORT SELECTION]
;	IS STATIC -- ALL OTHER PORT SETUP IS DONE EXTERNALLY, OR BY
;	THE "I" SECONDARY OPTION - WHICH DEFAULTS THE COMx PORT
;	TO 300 baud, 8 bits, 1stop bit, AND  n o  parity
;
;
	MOV	BX,BASE1U		;POINT TO A UART
	XOR	AX,AX
	CMP	AL,URT3FLG		;IS 3 REQUESTED (flags zeroed if found)
	JNE	INIT1			;CONTINUE IF NOT
	MOV	BX,BASE3U		;IF YES, POINT TO 3
	JMP	INIT2			; AND DO PORT SETUP
INIT1:	CMP	AL,URT2FLG	       ;IS 2 REQUESTED
	JNE	INIT2			;DEFAULT TO ONE IF NOT
	MOV	BX,BASE2U		;OR POINT TO TWO  AND
;					; DO THE PORT POINTER SETUP
;
;	SETUP POINTERS TO THE UART PORTS     (SUPPORTS 3)
;
INIT2:	MOV	AX,BX			;BUILD
	ADD	AX,OFFDATP		;
	MOV	MODDATP,AX		;     MODDATP
	MOV	AX,BX			;BUILD
	ADD	AX,OFFCTLP		;
	MOV	MODCTLP,AX		;MSR  MODCTLP
	MOV	AX,BX			;BUILD
	ADD	AX,OFFCTL2		;
	MOV	MODCTL2,AX		;MCR  MODCTL2
	MOV	AX,BX			;BUILD
	ADD	AX,OFFCTL3		;
	MOV	MODCTL3,AX		;LCR  MODCTL3
;
;
;	NOW THAT A PORT [COM1 COM2 or COM3] IS SELECTED
;		put up dtr FOR POOR FOLKS WITH
;		COMMERCIAL MODEMS THAT REQUIRE IT.
;		(poor folks, of course, is a relative term)
;
;					;
	MOV	AL,DTREADY		;OUTPUT DTR UP
	PUSH	DX			;  REQUEST TO
	MOV	DX,MODCTL2		;MODEM CONTROL REGISTER
	OUT	DX,AL			;
;
;	check for uart init request -- set COMx TO 300,N,8,1 IF 0
;
	MOV	al,DUMYFLG
	or	al,al
	jnz	noinit
	push	dx
	mov	dx,3fbh
	mov	al,80h
	out	dx,al
	mov	dx,3f9h
	mov	al,01h
	out	dx,al
	mov	dx,3f8h
	mov	al,80h
	out	dx,al
	mov	dx,3fbh
	mov	al,03h
	out	dx,al
;
;	the above sequence defaults the modem to 300,n,8,1 ..
;
NOINIT: POP	DX		;RESTORE DX BEFORE LEAVING
	RET
INITMOD ENDP
;
;---->	MOVEFCB: MOVES FCB(2) TO FCB
;
;I ATTEMPTED TO MAKE THE MODEM COMMAND 'NATURAL',
;I.E. MODEM SEND FILENAME (MODEM S FN.FT) RATHER
;THAT MODEM FILENAME SEND (MODEM FN.FT S) SO THIS
;ROUTINE MOVES THE FILENAME FROM THE SECOND FCB
;TO THE FIRST
;
MOVEFCB PROC	NEAR
	MOV	BX,OFFSET FCB2	;FROM
	MOV	DX,OFFSET FCB	;TO
	MOV	CH,16		;LEN
	PUSH	DS		;SAVE DS
	PUSH	ES		;MOVE ES ...
	POP	DS		;... TO DS
	CALL	MOVE		;DO THE MOVE
	POP	DS		;RESTORE DS
	XOR	AL,AL		;GET 0
	MOV	FCBCR,AL	;ZERO CURRENT RECORD
	MOV	FCBRR,AL	;..AND RANDOM RECORD
	RET
MOVEFCB ENDP
;
;---->	SHOW: SHOWS CHAR SENT/RECEIVED
;
;CR, LF, AND TAB ARE SHOWN.  ALL OTHER
;NON-PRINTABLE CHARACTERS ARE SHOWN IN
;HEX AS (XX)
;
SHOW	PROC	NEAR
	CMP	AL,LF		;LF?	JNZ	L00122
	JMP	CTYPEZZ 	;..YES, TYPEZZ IT
L00122: CMP	AL,CR		;CR?	JNZ	L00123
	JMP	CTYPEZZ 	;..YES, TYPEZZ IT
L00123: CMP	AL,09		;TAB
	JNZ	L00124
	JMP	CTYPEZZ 	;..YES, TYPEZZ IT
L00124: CMP	AL,' '          ;CTL-CHR?       JAE     L00125
	JMP	SHOWHEX 	;YES, SHOW IN HEX
L00125: CMP	AL,7FH		;DEL?	JAE	SHOWHEX
	JMP	CTYPEZZ 	;NO, TYPEZZ THE CHAR
SHOWHEX LABEL	NEAR
	LAHF
	XCHG	AL,AH
	PUSH	AX
	XCHG	AL,AH		;SAVE THE CHAR
	MOV	AL,'('          ;TYPEZZ..
	CALL	CTYPEZZ 	;..'('
	POP	AX
	XCHG	AL,AH
	SAHF			;THEN..
	CALL	HEXO		;..THE CHAR
	MOV	AL,')'          ;THEN..
	JMP	CTYPEZZ 	;..')' AND RETURN.
;
;---->	CTYPEZZ: TYPEZZS VIA CP/M SO TABS ARE EXPANDED
;
CTYPEZZ LABEL	NEAR
	PUSH	CX		;SAVE..
	PUSH	DX		;..ALL..
	PUSH	BX		;..REGS
	MOV	DL,AL		;CHAR TO E
	MOV	CL,WRCON	;GET BDOS FNC
	CALL	BDOS		;PRIN THE CHR
	POP	BX		;RESTORE..
	POP	DX		;..ALL..
	POP	CX		;..REGS
	RET			;FROM "CTYPEZZ"
SHOW	ENDP
;
CRLF	PROC	NEAR
	MOV	AL,CR
	CALL	TYPEZZ
	MOV	AL,LF
CRLF	ENDP
;
;---->	TYPEZZ: TYPEZZ VIA DIRECT BDOS ACCESS
;
;THIS ROUTINE BYPASSES CP/M'S CTL-S, CTL-C
;TESTS.
;
TYPEZZ	PROC	NEAR
	LAHF
	XCHG	AL,AH
	PUSH	AX
	XCHG	AL,AH		;SAVE CHAR
	PUSH	CX		;AND B
VTYPEZZ LABEL	NEAR
	MOV	CL,DCON 	;GET BDOS FNC
	MOV	DL,AL
	CALL	BDOS
	POP	CX
	POP	AX
	XCHG	AL,AH
	SAHF
	RET			;FROM "TYPEZZ"
TYPEZZ	ENDP
;
;KEYBOARD STATUS
;
;	This routine has been changed from CP/M-86: the service for
;	MS-DOS differs in several respects.. [CP/M version uses
;	x'FE' in DL and calls "DCON" which isn't supported
;	in MSDOS .. SO we use the CONSOLE STATUS service.
;
;
STAT	PROC	NEAR
	MOV	CL,CONST	;GET BDOS FNC
;	MOV	DL,0FfH 	;**Conventions changed from CP/M !!!
	CALL	BDOS
	OR	AL,AL		;0 => NOT READY
;				;AL = FF if char ready: else =00
	RET
STAT	ENDP
;
;KEYBOARD INPUT
;
;	This routine should be changed to use direct BIOS interface.
;	with the current BDOS call [DCON = 6] the CTRL-BREAK and
;	CTRL-C sequences are intercepted and interpreted as
;	termination requests
;
;
;
KEYIN	PROC	NEAR
	MOV	CL,DCON 	;GET BDOS FNC
	MOV	DL,0FFH
	CALL	BDOS
	JZ	KEYIN		;ZERO FLAG SET IF NO CHARACTER
	CMP	AL,CTLCCHR
	JNE	KEY001
	MOV	AL,CTLCHAR
	ret			;return if ctl-c to be sent
;
;	SPECIAL FUNCTION KEY SUPPORT
;				      **ALT-C ==> transmits CTRL-C
;	Support will be added here for
;	use of ALT-? keyins for shuch things as BAUD rate shift,
;	mode changes (quiet/noisy On/Off of R,S,Q secondary optns.)
;
;
key001: cmp	al,0
	je	altkey
	RET			;return if not "00" for special function code
altkey: mov	cl,dcon 	;set bdos function
	mov	dl,0ffh 	;ask for character
	call	bdos
	jz	altkey		;spin until second code
;	if we got here it should be a special scan code
;
	cmp	al,46		;replace
	jne	akey01		;	ALT-C
	mov	al,ctlchar	;  WITH
	ret			;	CTRL-C
AKEY01: CMP	AL,59
	JNL	AKEY02
	RET
AKEY02: CMP	AL,68
	JL	AKEY03
	RET
AKEY03: NOP
	NOP
	RET
KEYIN	ENDP
;
;HEX OUTPUT
;
HEXO	PROC	NEAR
	LAHF
	XCHG	AL,AH
	PUSH	AX
	XCHG	AL,AH		;SAVE FOR RIGHT DIGIT
	RCR	AL,1		;RIGHT..
	RCR	AL,1		;..JUSTIFY..
	RCR	AL,1		;..LEFT..
	RCR	AL,1		;..DIGIT..
	CALL	NIBBL		;PRINT LEFT DIGIT
	POP	AX
	XCHG	AL,AH
	SAHF			;RESTORE RIGHT
NIBBL:	AND	AL,0FH		;ISOLATE DIGIT
	CMP	AL,10		;IS IS <10?	JAE	L00127
	JMP	ISNUM		;YES, NOT ALPHA
L00127: ADD	AL,7		;ADD ALPHA BIAS
ISNUM:	ADD	AL,'0'          ;MAKE PRINTABLE
	JMP	TYPEZZ		;..THEN TYPEZZ IT
HEXO	ENDP
;
;---->	CKQUIT: QUIT/RETRY AFTER MULTIPLE ERRS.
;
;RETURNS W/ ZERO SET IF "RETRY" ASKED FOR
;
CKQUIT	PROC	NEAR
	XOR	AL,AL		;ZERO..
	MOV	ERRCT,AL	;..ERROR COUNT
	PUSH	BX
	MOV	BX,OFFSET MSG18
	CALL	ILPRT		;PRINT:
	POP	BX
	CALL	KEYIN		;QUIT/RETRY
	LAHF
	XCHG	AL,AH
	PUSH	AX
	XCHG	AL,AH
	CALL	CRLF
	POP	AX
	XCHG	AL,AH
	SAHF
	AND	AL,5FH		;MAKE UPPER CASE
	CMP	AL,'R'          ;RETRY? JNZ     L00128
	RET			;'KEEP ON TRUCKIN'
L00128: CMP	AL,'Q'          ;QUIT?  JZ      L00129
	JMP	CKQUIT		;NO, ASK AGAIN
L00129: OR	AL,AL		;SET NON-ZERO
	RET
CKQUIT	ENDP
;
;---->	ILPRT: INLINE PRINT OF MSG
;
;THE CALL TO ILPRT IS FOLLOWED BY A MESSAGE,
;BINARY 0 AS THE END.  BINARY 1 MAY BE USED TO
;PAUSE (MESSAGE 'PRESS RETURN TO CONTINUE')
;
ILPRT	PROC	NEAR
ILPLP:	MOV	AL,BYTE PTR[BX]
	OR	AL,AL		;END OF MSG?	JNZ	L00130
	JMP	ILPRET		;..YES, RETURN
L00130: CMP	AL,1		;PAUSE? JNZ	L00131
	JMP	ILPAUSE 	;..YES
L00131: CALL	CTYPEZZ 	;TYPEZZ THE MSG
ILPNEXT:
	PUSHF
	INC	BX
	POPF			;TO NEXT CHAR
	JMP	ILPLP		;LOOP
;
;PAUSE WHILE TYPING HELP SO INFO DOESN'T
;	SCROLL OFF OF VIDEO SCREENS
;
ILPAUSE:
	PUSH	BX
	MOV	BX,OFFSET MSG19
	CALL	ILPRT		;PRINT:
	POP	BX
	CALL	KEYIN		;GET ANY CHAR
	CMP	AL,'C'-40H      ;REBOOT?        JNZ     L09132          ;EXIT IF QUITCHAR
	JMP	EXIT
L09132: CMP	AL,'I'-40H      ;ALT REBOOT?    JNZ     L00132          ;
	JMP	EXIT		;YES.
L00132: JMP	ILPNEXT 	;LOOP
ILPRET: RET			;PAST MSG
ILPRT	ENDP
;
;---->	PRTMSG: PRINTS MSG POINTED TO BY (DE)
;
;A '$' IS THE ENDING DELIMITER FOR THE PRINT.
;NO REGISTERS SAVED.
;
PRTMSG	PROC	NEAR
	MOV	CL,PRINT	;GET BDOS FNC
	JMP	BDOS		;PRINT MESSAGE, RETURN
PRTMSG	ENDP
;
;---->	ERXIT: EXIT PRINTING MSG FOLLOWING CALL
;
ERXIT	PROC	NEAR
	POP	BX		;GET MESSAGE
	CALL	PRTMSG		;PRINT IT
	CALL	CKDIS		;DISCONNECT?	JMP	EXIT		;RETURN TO PC DOS
ERXIT	ENDP
;
;MOVE 128 CHARACTERS
;
MOVE128 PROC	NEAR
	MOV	CH,128		;SET MOVE COUNT
;
;MOVE FROM (HL) TO (DE) LENGTH IN (B)
;
MOVE:	MOV	AL,BYTE PTR [BX] ;GET A CHAR
	XCHG	BX,DX
	MOV	[BX],AL
	XCHG	BX,DX		;STORE IT
	PUSHF
	INC	BX
	POPF			;TO NEXT "FROM"
	PUSHF
	INC	DX
	POPF			;TO NEXT "TO"
	DEC	CH		;MORE?	JZ	L00133
	JMP	MOVE		;..YES, LOOP
L00133: RET			;..NO, RETURN
MOVE128 ENDP
;
BDOS	PROC	NEAR
	PUSH	BX
	PUSH	CX
	PUSH	DX
	MOV	AH,CL		;MOVE FNC FOR PC DOS
	INT	21H		;INVOKE PC DOS SERVICE
	POP	DX
	POP	CX
	POP	BX
	RET
BDOS	ENDP
;
BADOPT: CALL	TYPEZZ
	PUSH	BX
	MOV	BX,OFFSET MSG25
	CALL	ILPRT
	POP	BX
HELP:	PUSH	BX
	MOV	BX,OFFSET MSG26
	CALL	ILPRT
	POP	BX
	JMP	copyrt
EXAM:	PUSH	BX
	MOV	BX,OFFSET MSG27
	CALL	ILPRT
	POP	BX
	JMP	copyrt
;
;  Print Limited license with "HELP" request output
;
copyrt: CALL	STAT
;
;	CLEAR THE SCREEN (cursor = 1,1)
;
	SUB	CX,CX		;UPPER LEFT CORNER
	MOV	DX,184FH	;BOTTOM RIGHT CORNER
	MOV	BH,7		;NORMAL ATTRIB FOR CLS
	SCROLL			;INVOKE BIOS TO CLEAR SCREEN
	SUB	DX,DX		;POINT TO ROW 1,COL 1
	LOCATE			;SET THE CURSOR TO TOP LEFT
;
;	PRINT COPYRIGHT NOTICE	AND PAUSE
;
	mov	bx,offset msg00 ;point to copyright notice
	call	ilprt		; go print it (PAUSE)
;
;	RETURN TO CALLER
;
	jmp	exit
;
;
;
MODEM	ENDS
	SUBTTL	'MODIFICATION HISTORY AND CREDITS'
	PAGE
;
;* * * * * * * * * * * * * * * * * * * * * * * * *
;*						 *
;*   THIS PROGRAM DOCUMENTED IN "MODEM.DOC"      *
;*						 *
;* * * * * * * * * * * * * * * * * * * * * * * * *
;* THIS PROGRAM WAS "MODEM.ASM" BUT and then was *
;* TEMPORARILY NAMED "MODEM2.ASM" SO PEOPLE      *
;* WILL REALIZE IT IS AN ENHANCEMENT OF 	 *
;* THE ORIGINAL PROGRAM "MODEM.ASM" ON CP/M      *
;* USER'S GROUP DISK 25.                         *
;* * * * * * * * * * * * * * * * * * * * * * * * *
;
;PLEASE PASS ON MODS, BUGS, ETC, SO YOUR
;FIXES OR ENHANCEMENTS MAY BE SHARED BY ALL,
;
;Please send to the bottom name on the list,
;	OR TO ALL OF US - if you can afford
;			  the time
;
;	Ward Christensen
;	688 E. 154th St. #5D
;	Dolton, Il. 60419
;
;	(312) 849-6279
;
;You may send a self-addressed stamped postcard
;to be informed of changes/bugs as they become
;known.     [CP/M Version]
;
;
;
;	05/08/82
;Modified for CP/M 86 and the IBM PC
; by Randy Suess
;    5219 Warwick
;    Chicago, Ill 60641
;    312-545 7535
;
;	06/03/82
;Modified for PC DOS and the IBM PC
;by Rick Mallinak
;   22451 Franklin Dr.
;   Richton Park, Ill 60471
;   (312) 481-6459
;
;	08/11/82
;Repaired for PC DOS 1.1 and IBM PC
;by John Chapman
;   844 S. Madison St.
;   Hinsdale Illinois 60521
;   (312) 325-3081
;		  CS: 70205,1217
;
;
;
;	--------------------
;	MODIFICATION HISTORY
;	--------------------
;
;	09/23/77
;ORIGINALLY WRITTEN BY WARD CHRISTENSEN
;
;	04/26/79
;REWRITTEN BY WARD CHRISTENSEN TO COMBINE
;IMPROVEMENTS TO THE ORIGINAL MADE BY WARD
;AND BY KEITH PETERSEN, W8SDZ, AND SUGGESTIONS
;BY JIM BELL WHICH KEITH IMPLEMENTED.  SEE
;MODEM.DOC FOR ADDITIONAL HISTORICAL
;INFORMATION AND DOCUMENSATION.
;
;	05/09/79
;ALLOW 'T' AND 'E' SUB-OPTIONS TO GO TO TERMINAL
;OR ECHO MODEM AFTER TRANSFERRING A FILE.  (WLC)
;
;	05/22/79
;ADD FEATURE TO MAKE RECEIVE FILE ROUTINE SAY
;FILE SUCCESSFULLY OPENED, WHEN IN QUIET MODE.
;MOVE INITIAL GOBBLE GARBAGE INPUTS TO BEFORE
;COMMAND CPI'S SO ALL MODES ARE CLEARED. CHANGE
;INITIAL SEND WAIT TO 80 SECS TO ALLOW MORE TIME
;FOR RECEIVING END TO COME UP. ADD 'H' AFTER MSG
;THAT SHOWS NUMBER OF SECTORS IN EXTENT ABOUT TO
;BE SENT.  (KBP)
;
;	05/24/79
;FIX MISSING RETURN INSTRUCTION AT END OF
;INITIALIZATION ROUTINE.  (KBP)
;
;	07/13/79
;PUT IN RESET OF DMA ADDR TO 80H AFTER
;FILE RECEIVE, BECAUSE "SUBMIT" UNDER CP/M
;DOESN'T RESET IT BEFORE READING THE
;NEXT SUBMITTED COMMAND. /// ALSO DELETE
;CODE FOR "CANCEL" AS IT'S JUST TOO EASY
;TO INTENTIONALLY GET A CANCEL AS A
;GARBAGED LINE CHARACTER.
;
;;
;	    05/82
;
;Rewitten for CP/M-86 by Randy Suess
; Changes mainly to interface with
; the CP/M-86 BDOS services
;
;	    06/82
;
;Randy's version altered by Rick Mallinak
;to beacceptable to PC/DOS assembler.
;Comments added and changes made to
;support multiple segment version
;
;	    08/82		       ********CURRENT VERSION***********
;
;Rick's PC/DOS version reworked
;to: a) RUn as a .COM file by
;returning to single segment image;
;b)terminal bugs repaired,; c) code
;added to 'bring up' DTR as program
;starts up [necessary for non-autodial
;commercial modems]; and c) both
;source and execution time messages
;added to prevent Resale or Commmercial
;use of this program.
;
;
;
	END	MAIN

XMODEM.DOC

MODEM PROTOCOL OVERVIEW  178 lines, 7.5K

1/1/82 by Ward Christensen.  I will maintain a master copy of
this.  Please pass on changes or suggestions via CBBS/Chicago
at (312) 545-8086, or by voice at (312) 849-6279.

NOTE this does not include things which I am not familiar with,
such as the CRC option implemented by John Mahr.

Last Rev: (none)

At the request of Rick Mallinak on behalf of the guys at
Standard Oil with IBM P.C.s, as well as several previous
requests, I finally decided to put my modem protocol into
writing.  It had been previously formally published only in the
AMRAD newsletter.

	Table of Contents
1. DEFINITIONS
2. TRANSMISSION MEDIUM LEVEL PROTOCOL
3. MESSAGE BLOCK LEVEL PROTOCOL
4. FILE LEVEL PROTOCOL
5. DATA FLOW EXAMPLE INCLUDING ERROR RECOVERY
6. PROGRAMMING TIPS.

-------- 1. DEFINITIONS.
<soh>	01H
<eot>	04H
<ack>	05H
<nak>	15H
<can>	18H

-------- 2. TRANSMISSION MEDIUM LEVEL PROTOCOL
Asynchronous, 8 data bits, no parity, one stop bit.

    The protocol imposes no restrictions on the contents of the
data being transmitted.  No control characters are looked for
in the 128-byte data messages.	Absolutely any kind of data may
be sent - binary, ASCII, etc.  The protocol has not formally
been adopted to a 7-bit environment for the transmission of
ASCII-only (or unpacked-hex) data , although it could be simply
by having both ends agree to AND the protocol-dependent data
with 7F hex before validating it.  I specifically am referring
to the checksum, and the block numbers and their ones-
complement.
    Those wishing to maintain compatibility of the CP/M file
structure, i.e. to allow modemming ASCII files to or from CP/M
systems should follow this data format:
  * ASCII tabs used (09H); tabs set every 8.
  * Lines terminated by CR/LF (0DH 0AH)
  * End-of-file indicated by ^Z, 1AH.  (one or more)
  * Data is variable length, i.e. should be considered a
    continuous stream of data bytes, broken into 128-byte
    chunks purely for the purpose of transmission.
  * A CP/M "peculiarity": If the data ends exactly on a
    128-byte boundary, i.e. CR in 127, and LF in 128, a
    subsequent sector containing the ^Z EOF character(s)
    is optional, but is preferred.  Some utilities or
    user programs still do not handle EOF without ^Zs.
  * The last block sent is no different from others, i.e.
    there is no "short block".

-------- 3. MESSAGE BLOCK LEVEL PROTOCOL
 Each block of the transfer looks like:
<SOH><blk #><255-blk #><--128 data bytes--><cksum>
    in which:
<SOH>	    = 01 hex
<blk #>     = binary number, starts at 01 increments by 1, and
	      wraps 0FFH to 00H (not to 01)
<255-blk #> = blk # after going thru 8080 "CMA" instr, i.e.
	      each bit complemented in the 8-bit block number.
	      Formally, this is the "ones complement".
<cksum>     = the sum of the data bytes only.  Toss any carry.

-------- 4. FILE LEVEL PROTOCOL

---- 4A. COMMON TO BOTH SENDER AND RECEIVER:

    All errors are retried 10 times.  For versions running with
an operator (i.e. NOT with XMODEM), a message is typed after 10
errors asking the operator whether to "retry or quit".
    Some versions of the protocol use <can>, ASCII ^X, to
cancel transmission.  This was never adopted as a standard, as
having a single "abort" character makes the transmission
susceptible to false termination due to an <ack> <nak> or <soh>
being corrupted into a <can> and canceling transmission.
    The protocol may be considered "receiver driven", that is,
the sender need not automatically re-transmit, although it does
in the current implementations.

---- 4B. RECEIVE PROGRAM CONSIDERATIONS:
    The receiver has a 10-second timeout.  It sends a <nak>
every time it times out.  The receiver's first timeout, which
sends a <nak>, signals the transmitter to start.  Optionally,
the receiver could send a <nak> immediately, in case the sender
was ready.  This would save the initial 10 second timeout.
However, the receiver MUST continue to timeout every 10 seconds
in case the sender wasn't ready.
    Once into a receiving a block, the receiver goes into a
one-second timeout for each character and the checksum.  If the
receiver wishes to <nak> a block for any reason (invalid
header, timeout receiving data), it must wait for the line to
clear.	See "programming tips" for ideas
    Synchronizing:  If a valid block number is received, it
will be: 1) the expected one, in which case everything is fine;
or 2) a repeat of the previously received block.  This should
be considered OK, and only indicates that the receivers <ack>
got glitched, and the sender re-transmitted; 3) any other block
number indicates a fatal loss of synchronization, such as the
rare case of the sender getting a line-glitch that looked like
an <ack>.  Abort the transmission, sending a <can>

---- 4C. SENDING PROGRAM CONSIDERATIONS.

    While waiting for transmission to begin, the sender has
only a single very long timeout, say one minute.  In the
current protocol, the sender has a 10 second timeout before
retrying.  I suggest NOT doing this, and letting the protocol
be completely receiver-driven.	This will be compatible with
existing programs.
    When the sender has no more data, it sends an <eot>, and
awaits an <ack>, resending the <eot> if it doesn't get one.
Again, the protocol could be receiver-driven, with the sender
only having the high-level 1-minute timeout to abort.


-------- 5. DATA FLOW EXAMPLE INCLUDING ERROR RECOVERY

Here is a sample of the data flow, sending a 3-block message.
It includes the two most common line hits - a garbaged block,
and an <ack> reply getting garbaged.  <xx> represents the
checksum byte.

SENDER					RECEIVER
				times out after 10 seconds,
			<---		<nak>
<soh> 01 FE -data- <xx> --->
			<---		<ack>
<soh> 02 FD -data- xx	--->	(data gets line hit)
			<---		<nak>
<soh> 02 FD -data- xx	--->
			<---		<ack>
<soh> 03 FC -data- xx	--->
   (ack gets garbaged)	<---		<ack>
<soh> 03 FC -data- xx	--->		<ack>
<eot>			--->
			<---		<ack>

-------- 6. PROGRAMMING TIPS.

* The character-receive subroutine should be called with a
parameter specifying the number of seconds to wait.  The
receiver should first call it with a time of 10, then <nak> and
try again, 10 times.
  After receiving the <soh>, the receiver should call the
character receive subroutine with a 1-second timeout, for the
remainder of the message and the <cksum>.  Since they are sent
as a continuous stream, timing out of this implies a serious
like glitch that caused, say, 127 characters to be seen instead
of 128.

* When the receiver wishes to <nak>, it should call a "PURGE"
subroutine, to wait for the line to clear.  Recall the sender
tosses any characters in its UART buffer immediately upon
completing sending a block, to ensure no glitches were mis-
interpreted.
  The most common technique is for "PURGE" to call the
character receive subroutine, specifying a 1-second timeout,
and looping back to PURGE until a timeout occurs.  The <nak> is
then sent, ensuring the other end will see it.

* You may wish to add code recommended by Jonh Mahr to your
character receive routine - to set an error flag if the UART
shows framing error, or overrun.  This will help catch a few
more glitches - the most common of which is a hit in the high
bits of the byte in two consecutive bytes.  The <cksum> comes
out OK since counting in 1-byte produces the same result of
adding 80H + 80H as with adding 00H + 00H.


Directory of PC-SIG Library Disk #0054

 Volume in drive A has no label
 Directory of A:\

CRC      TXT       983  11-09-84  10:55a
CRCK4    COM      1536  10-21-82   7:54p
DESCRIPT ION     27426   5-16-82
LONGTERM BAS     17611   7-27-84  10:08a
PROFEEL           2499   5-16-82
PROGRAMN OTE     27934   5-16-82
SHORTERM BAS     16342   7-27-84  10:05a
TUTORIAL         15293   5-16-82
XMODEM   ASM     52521   4-02-83   7:36a
XMODEM   COM      9728   3-29-83   9:16p
XMODEM   DOC      7621   3-29-83   6:35p
       11 file(s)     179494 bytes
                      138240 bytes free