home *** CD-ROM | disk | FTP | other *** search
/ Oakland CPM Archive / oakcpm.iso / cpmug / cpmug047.ark / MODEM7.ASM < prev    next >
Assembly Source File  |  1984-04-29  |  48KB  |  2,589 lines

  1. ;        CP/M MODEM PROGRAM
  2.  
  3. ;THE FOLLOWING IS AN EXTENSIVE REVISION OF THE CP/M MODEM PROGRAM
  4. ;CREATED BY WARD CHRISTENSEN FOR THE CP/M USERS LIBRARY.
  5. ;IT ALSO INCORPORATES ROUTINES FOUND IN THE POTOMAC MICRO-MAGIC MODEM
  6. ;MANUAL WHICH MAY BE USED IF YOU HAVE A PMMI MODEM BOARD.
  7.  
  8. ;THE ADDITIONAL ROUTINES ARE COPYRIGHTED (1980) BY:
  9.  
  10. ;Mark M. Zeiger        and    James K. Mills
  11. ;198-01B 67th Ave.        824 Jordan Place
  12. ;Flushing, N.Y. 11365        Rockford, IL  61108
  13. ;(212) 454-6985            (815) 398-0579
  14.  
  15. ;Permission is grant pmmi auto-dial function, 255 MAX.
  16.  
  17. CHGBAUD    EQU 'B'-40H        ;USED IN TERMINAL MODE TO CHANGE
  18.                 ;BAUD RATE 'ON THE FLY'
  19. ERRLIM    EQU 10            ;NUMBER OF TIMES TO RETRY
  20.                 ;SEND/RECEIVE ERRORS BEFORE QUIT
  21. EXITCHR    EQU 'E'-40H    ; ^E = EXIT WITHOUT DISCONNECT
  22. DISCCHR    EQU 'D'-40H    ; ^D = DISCONNECT
  23. TRANCHR    EQU 'T'-40H    ; ^T = TRANSFER CHARACTER
  24. CAN    EQU 'X'-40H    ; ^X = CANCEL SEND/RECEIVE
  25. EOFCHAR    EQU 'Z'-40H    ; ^Z = END OF FILE
  26. SAVECHR    EQU 'Y'-40H    ; ^Y = SAVE CHARACTER
  27. XOFF    EQU 'S'-40H    ; ^S = XOFF CHARACTER
  28. XON    ES
  29.  
  30. PORT    EQU 0E0H        ;PMMI BASE ADDRESS
  31.  
  32. MODCTLP    EQU PORT        ;MODEM CONTROL PORT
  33. MODSNDB    EQU 1            ;MODEM SEND BIT (XMIT BUFF EMPTY)
  34. MODSNDR    EQU 1            ;MODEM SEND READY
  35. MODRCVB    EQU 2            ;MODEM RECEIVE BIT (DAV)
  36. MODRCVR    EQU 2            ;MODEM RECEIVE READY
  37. MODDATP    EQU PORT+1        ;MODEM DATA PORT
  38. BAUDRP    EQU PORT+2        ;BAUD RATE PORT
  39. MODCTL2    EQU PORT+3        ;2ND MODEM CONTROL PORT
  40. ORIGMOD    EQU 1DH            ;ORIGINATE MODE
  41. ANSWMOD    EQU 1EH            ;ANSWER MODE
  42.  
  43. WAITCTS    EQU    255    ;number of seconds X 10 to wait for computer
  44.             ;tone afterING
  45. ;THE PROGRAM.
  46.  
  47. PMMIBYTE    DB TRUE            ;true=pmmi modem
  48. IMSAIBYTE    DB FALSE        ;true=imsai front panel
  49. FASTCLK        DB FALSE        ;4 MHz or greater
  50. BAKUPBYTE    DB TRUE         ;true=make .BAK file
  51. XPRFLG        DB TRUE            ;true=no menu, false=print menu
  52. PULSERATE    DB 125            ;125 FOR 20PPS, 250 FOR 10PPS dialing
  53. IN$MODCTLP    IN  MODCTLP ! RET    ;in modem control port
  54. OUT$MODDATP    OUT MODDATP ! RET    ;out modem data port
  55. ANI$MODSNDB    ANI MODSNDB ! RET    ;bit to test for send ready
  56. CPI$MODSNDR    CPI MODSNDR ! RET    ;value of send bit when rEQU 'Q'-40H    ; ^Q = XON CHARACTER
  57. SOH    EQU 1        ; START OF HEADER
  58. EOT    EQU 4        ; END OF TEXT
  59. ACK    EQU 6        ; ACKNOWLEDGE
  60. NAK    EQU 15H        ; NOT ACKNOWLEDGE
  61. BDNMCH    EQU 75H        ; BAD NAME MATCH
  62. OKNMCH    EQU ACK        ; OKAY NAME MATCH
  63. LF    EQU 10        ; LINEFEED
  64. CR    EQU 13        ; CARRIAGE RETURN
  65. BELL    EQU 7        ; BELL CHARACTER
  66. FRONTPAN EQU 0FFH    ; IMSAI FRONT PANEL
  67.  
  68. BOTTRAM    SET LAST+100H AND 0FF00H
  69.  
  70.     ORG 100H
  71.  
  72.     JMP START
  73.  
  74. ;THESE ROUTINES ARE AT THE BEGINNING OF THE PROGRAM SO
  75. ;THEY CAN BE PATCHED BY A MONITER WITHOUT RE-ASSEMBLRY TABLE FOR DIALING FROM LIBRARY
  76. ; OF NUMBERS STORED IN THESE DB'S AT ASSEMBLY-TIME.
  77. ; EACH DB MUST BE 30 CHARACTERS LONG FOR PROPER OPERATION.
  78. ; A 'DB 0' INDICATES NO DIALING, PROGRAM WILL DISCONNECT
  79. ; AND RETURN TO COMMAND MODE.  LAST DB MUST BE DB 0. UP TO
  80. ; 26 NUMBERS ARE ALLOWED.
  81.  
  82. ;        '----5---10---15---20---25---30'
  83. NUMBLIB    DB    'A=Atlanta CBBS  1-404-394-4220'    ;'A'
  84.     DB    'B=Chicago CBBS  1-312-545-8086'    ;'B'
  85.     DB    'C=Calamity Clif 1-312-234-9257'    ;'C'
  86.     DB    'D=Detroit CP/M* 1-313-588-7054'    ;'D'
  87.     eady
  88. IN$MODDATP    IN  MODDATP ! RET    ;in modem data port
  89. ANI$MODRCVB    ANI MODRCVB ! RET    ;bit to test for receive ready
  90. CPI$MODRCVR    CPI MODRCVR ! RET    ;value of receive bit when ready
  91. JMP$INITMOD    JMP INITMOD        ;to initialize port, if necessary
  92. OUT$MODCTLP    OUT MODCTLP ! RET    ;out modem control port
  93. IN$BAUDRP    IN  BAUDRP  ! RET    ;in baudrate port
  94. OUT$BAUDRP    OUT BAUDRP  ! RET    ;out baudrate port
  95. OUT$MODCTL2    OUT MODCTL2 ! RET    ;out modem control port #2
  96.  
  97. CRFLAG    DB 0    ;CONTINUOUS REDIAL FLAG
  98.  
  99. ; PHONE NUMBER LIBRA'
  100.     DB    'Q=                            '    ;'Q'
  101.     DB    'R=                            '    ;'R'
  102.     DB    'S=SOURCE/Rockford     398-6090'    ;'S'
  103.     DB    'T=                            '    ;'T'
  104.     DB    'U=                            '    ;'U'
  105.     DB    'V=                            '    ;'V'
  106.     DB    'W=                            '    ;'W'
  107.     DB    'X=                            '    ;'X'
  108.     DB    'Y=                            '    ;'Y'
  109.     DB    'Z=                            '    ;'Z'
  110.     DB    0                    ; end
  111.  
  112. START    LXI H,0
  113.     DAD SP        ;GET CP/M'S STACK
  114.     SHLD STACK    ;SAVEed to use, but not to sell, these routines.
  115.  
  116. ;LAST REVISION 12/18/80 -- changed disconnect timing
  117.  
  118.  
  119.     MACLIB MODEM    ;CONTAINS CMDLINE, INBUF, INLNCOMP,
  120.             ;DIR, AND MFACCESS ROUTINES
  121.             ;changed to MODEM.LIB by Jim Mills
  122.             ;to differentiate from other 'MACROS.LIB'
  123.  
  124. ; minor revision 10/26/80 to allow 25-second 'wait' after pmmi
  125. ; autodial -- longer time required for Chicago CBBS*.  Jim Mills.
  126. ; * CBBS is a trademark of Ward Christensen and Randy Suess.
  127.  
  128. TRUE    EQU 0FFH
  129. FALSE    EQU 0
  130.  
  131. ; PMMI EQUAT'
  132.     DB    'Q=                            '    ;'Q'
  133.     DB    'R=                            '    ;'R'
  134.     DB    'S=SOURCE/Rockford     398-6090'    ;'S'
  135.     DB    'T=                            '    ;'T'
  136.     DB    'U=                            '    ;'U'
  137.     DB    'V=                            '    ;'V'
  138.     DB    'W=                            '    ;'W'
  139.     DB    'X=                            '    ;'X'
  140.     DB    'Y=                            '    ;'Y'
  141.     DB    'Z=                            '    ;'Z'
  142.     DB    0                    ; end
  143.  
  144. START    LXI H,0
  145.     DAD SP        ;GET CP/M'S STACK
  146.     SHLD STACK    ;SAVE IT
  147.     LXI SP,STACK    ;START LOCAL STACK
  148.  
  149.     CALL START1
  150.  
  151.     DB CR,LF,'MODEM7 as of 12/18/80',cr,lf
  152.     DB 'Originally Written by Ward Christensen',cr,lf
  153.     DB 'Revisions by Mark M. Zeiger, Jim Mills',cr,lf,'$'
  154.  
  155.  
  156. START1    POP D        ;GET ADDRESS OF ABOVE MESSAGE
  157.     MVI C,PRINT    ; 9
  158.     CALL BDOS
  159.  
  160.     CALL INITADR    ;INITIALIZE ADDRESSES
  161.     MVI A,TRUE    ; 0FFH
  162.     STA NFILFLG
  163.     CMA        ; 0
  164.     STA SAVEFLG
  165.     OUT FRONTPAN    ; IMSAI
  166.  
  167.     CALL PROCOPT    ;PROCESS CONTROL OPTIONS
  168.     LDA OPTION    ;GET MAIN OPTION
  169.     CPI 'X'        ;EXPERT FLAG?
  170.     JNZ RESTART    ;NO
  171.     MVI A,TRUE    ;YES
  172.     STA XPRFLG    ;MAKE EXPERT
  173.     JMP MENU
  174.  
  175. RESTART
  176.     LDA OPTION    ;GET MAIN OPTION
  177.     MOV B,A        ;SAVE IT
  178.     LDA PMMIBYTE    ;PMMI?
  179.     ORA A        ;SET FLAGS
  180.     MOV A,B        ;GET OPTION BACK
  181.     JZ S1        ;NOT PMMI
  182.     CPI 'C'        ;CALL (DIAL) FUNCTION?
  183.     JZ DIALPL    ;YES, GO TO IT
  184.  
  185. S1    CPI ' '            ;NO OPTION SPEC'D?
  186.     JZ MENU            ;TRUE, GO MENU
  187.     CPI 'M'            ;MENU ASKED FOR?
  188.     JZ MENU            ;YES, GO MENU
  189.     CALL JMP$INITMOD    ;
  190.     CALL MOVEFCB
  191.     MVI A,FALSE
  192.     STA NFILFLG
  193.  
  194.     CALL IN$MODDATP        ;GOBBLE UP GARBAGE..
  195.     CALL IN$MODDATP        ;..CHARACTERS ON LINE
  196.  
  197.     LDA OPTION    ;PROCESS MAIN OPTION
  198.     CPI 'E'        ;ECHO MODE?
  199.     JZ TRMECHO    ;YES
  200.     CPI 'T'        ;TERMINAL MODE?
  201.     JZ DSKSAVE    ;YES
  202.  
  203.     CPI 'S'        ;SEND A FILE?
  204.     JZ SENDFIL    ;YES
  205.     CPI 'R'        ;RECEIVE A FILE?
  206.     JZ RCVFIL    ;YES
  207.     CPI 'D'        ;DISCONNECT?
  208.     JZ DISCON1    ;YES, DISCONNECT & GO MENU
  209.     JMP MENU    ;NO OPTION SPEC'D, GO MENU
  210.  
  211. ;REVISED TERMINAL ROUTINE ALLOWING MEMORY SAVE
  212.  
  213. DSKSAVE    LDA NFILFLG    ;NEW FILE FLAG
  214.     CPI TRUE    ;OFFH? (TRUE=NORMAL TERMINAL MODE)
  215.     JZ TERM        ;YES
  216.     LDA FCB+1    ;FIRST CHAR OF FILENAME
  217.     CPI ' '        ;FILE SPEC'D
  218.     JNZ GOODNM    ;YES, GOOD NAME
  219.     MVI A,TRUE    ;0FFH
  220.     STA NFILFLG    ;
  221.     CMA        ; 0
  222.     STA SAVEFLG    ;
  223.     OUT FRONTPAN    ;0FFH PORT FOR IMSAI FRONT PANEL
  224.     JMP TERM    ;
  225.  
  226. GOODNM    CALL ERASFIL
  227.     CALL MOVE2
  228.     LXI D,FCB3
  229.     MVI C,MAKE
  230.     CALL BDOS
  231.     LXI D,FCB3
  232.     MVI C,OPEN
  233.     CALL BDOS
  234.     LXI H,BOTTRAM
  235.     SHLD HLSAVE
  236.     MVI A,FALSE
  237.     STA NFILFLG
  238.  
  239. TERM    CALL STAT    ;KEYPRESS?
  240.     JZ TERML    ;NO, CHECK LINE
  241.     CALL KEYIN    ;GET CHAR FROM KBD
  242.     CPI EXITCHR    ;^E?
  243.     JZ MENU        ;YES, RETURN TO MENU
  244.     CPI DISCCHR    ;^D?
  245.     JZ DISCON1    ;YES, DISCONNECT & RETURN TO MENU
  246.  
  247.     CPI TRANCHR    ;TEST FOR TRANSFER REQUEST (^T)
  248.     CZ TRANSFER    ;SEND-A-FILE (BLIND SEND)
  249.     JZ TERM        ;LOOP
  250.  
  251.     MOV B,A
  252.     LDA PMMIBYTE
  253.     ORA A
  254.     MOV A,B
  255.     JZ S2
  256.     CPI CHGBAUD
  257.     PUSH PSW
  258.     PUSH H
  259.     CZ NEWBAUD
  260.     POP H
  261.     POP PSW
  262.     CPI CHGBAUD    ;^B?
  263.     JZ TERML
  264.  
  265. S2    CPI SAVECHR
  266.     JNZ NOTOG
  267.     LDA NFILFLG    ;DO NOT ALLOW SAVE IF..
  268.     CPI TRUE    ;..THIS FLAG IS SET.
  269.     JZ TERML
  270.     LDA SAVEFLG
  271.     CMA
  272.     STA SAVEFLG
  273.     JMP TERML
  274.  
  275. NOTOG    CALL OUT$MODDATP
  276.  
  277. TERML    CALL IN$MODCTLP
  278.     CALL ANI$MODRCVB
  279.     CALL CPI$MODRCVR
  280.     JNZ TERM
  281.     CALL IN$MODDATP
  282.     CPI 0        ;CHECK FOR NULLS
  283.     JZ TERM        ;DON'T PROCESS THEM
  284.     ANI 7FH        ;STRIP PARITY
  285.     CALL TYPE
  286.     PUSH PSW
  287.     LDA SAVEFLG
  288.     CPI FALSE
  289.     JZ NOSAVE
  290.     POP PSW
  291.     MOV M,A
  292.     INX H
  293.     SHLD HLSAVE    ;MENU COMMAND DESTROYS HL-REG..
  294.             ;..GET HL WHEN ENTERING VIA 'RET' CMD.
  295.     MOV B,A
  296.     LDA IMSAIBYTE
  297.     ORA A
  298.     MOV A,B
  299.     JZ COLON
  300.     CMA        ;FRONT PANEL SHOWS CHARS WHEN..
  301.     OUT FRONTPAN    ;..MEMORY SAVE IS ACTIVE.
  302.     JMP NOCOLON
  303. COLON    CPI LF        ;IF NO FRONT PANEL, THEN..
  304.     JNZ NOCOLON    ;..TYPE ":" AFTER EACH LINE FEED..
  305.     MVI A,':'    ;..WHEN MEMORY SAVE ACTIVE.
  306.     CALL TYPE
  307. NOCOLON    LDA 7        ;CHECK TO SEE IF..
  308.     DCR A        ;..PAGE BELOW BDOS HAS BEEN..
  309.     CMP H        ;..REACHED AND DISKSAVE IS NEEDED.
  310.     CZ INTDSKSV
  311.  
  312.     JMP TERM
  313. NOSAVE    POP PSW
  314.     JMP TERM
  315.  
  316. SAVEFLG     DB FALSE
  317. LASTBYT1 DB 0
  318. LASTBYT2 DB 0
  319.  
  320. INTDSKSV
  321.     MVI A,XOFF    ;SEND A CTRL-S TO STOP..
  322.     CALL OUT$MODDATP    ;..REMOTE COMPUTER OUTPUT.
  323.  
  324.     MVI D,0        ;D IS THE BUFFER COUNT
  325.     CALL INMODEM    ;GET LAST BYTES SENT..
  326.     STA LASTBYT1    ;..AFTER CTRL-S.
  327.     CALL INMODEM    ;ADD MORE CALLS TO INMODEM..
  328.     STA LASTBYT2    ;..AND STA LASTBYT# IF YOU ARE..
  329.             ;..LOSING BYTES WHEN MEMORY IS FULL.
  330.     PUSH D
  331.     CALL NUMREC1
  332.     CALL WRTDSK    ;WRITE THE RECORDS
  333.     POP D
  334.  
  335.     LXI H,BOTTRAM
  336.     INR D
  337.     DCR D        ;TEST BUFFER COUNT FOR ZERO
  338.     JZ CTRLQ
  339.     LDA LASTBYT1    ;GET THE LAST BYTES THAT WERE..
  340.     MOV M,A        ;..SAVED AND PUT THEM IN..
  341.     INX H        ;..BOTTRAM.
  342.     CALL TYPE
  343.     DCR D
  344.     JZ CTRLQ
  345.     LDA LASTBYT2
  346.     MOV M,A
  347.     INX H
  348.     CALL TYPE
  349.  
  350. CTRLQ    MVI A,XON    ;SEND START CHARACTER..
  351.     CALL OUT$MODDATP    ;..TO REMOTE COMPUTER.
  352.  
  353.     RET
  354.  
  355. ;THIS SUBROUTINE WILL LOOP UNTIL THE MODEM RECEIVES A CHARACTER
  356. ;OR 100 MILLISECONDS. IF A CHARACTER IS RECEIVED, A FLAG IS SET
  357. ;TO STORE THE CHARACTER. A MAXIMUM OF TWO CHARACTERS ARE STORED,
  358. ;BUT MORE MAY BE STORED IF DESIRED (SEE COMMENT IN "INTDSKSV"
  359. ;ABOVE).
  360.  
  361. INMODEM    LDA FASTCLK
  362.     ORA A
  363.     JZ SLOW
  364.     LXI B,2500
  365.     JMP TIMERL
  366. SLOW    LXI B,1250
  367. TIMERL    CALL IN$MODCTLP
  368.     CALL ANI$MODRCVB
  369.     CALL CPI$MODRCVR
  370.     JZ GETBYTE
  371.     DCX B
  372.     MOV A,B
  373.     ORA C
  374.     JNZ TIMERL
  375.     RET
  376. GETBYTE    CALL IN$MODDATP
  377.     INR D
  378.     RET
  379.  
  380. NUMRECS    MVI M,EOFCHAR
  381.     INX H
  382.     LXI D,127
  383.     DAD D
  384. NUMREC1    LXI D,-(BOTTRAM)
  385.     DAD D
  386.  
  387.     MOV A,L        ;DIVIDE HL BY 128..
  388.     ORA A
  389.     RAL        ;..TO GET THE..
  390.     MOV L,H        ;..NUMBER OF SECTORS
  391.     MVI H,0
  392.     PUSH PSW
  393.     DAD H
  394.     POP PSW
  395.     MVI A,0
  396.     ADC L
  397.     MOV L,A        ;RETURNS WITH NUMBER OF..
  398.     RET        ;..128 BYTE RECORDS IN HL.
  399.  
  400. WRTDSK    LXI D,BOTTRAM
  401. NEXTWRT    MVI C,STDMA
  402.     CALL BDOSRT
  403.     PUSH D
  404.     LXI D,FCB3
  405.     MVI C,WRITE
  406.     CALL BDOSRT
  407.     POP D
  408.     XCHG
  409.     PUSH D
  410.     LXI D,128
  411.     DAD D
  412.     POP D
  413.     XCHG
  414.     DCX H
  415.     MOV A,H
  416.     ORA L
  417.     JNZ NEXTWRT
  418.     RET
  419.  
  420. CLOSE3    LXI D,FCB3
  421.     MVI C,CLOSE
  422.     CALL BDOS
  423.     RET
  424.  
  425. BDOSRT    PUSH B ! PUSH D ! PUSH H ! PUSH PSW
  426.     CALL BDOS
  427.     POP PSW ! POP H ! POP D ! POP B
  428.     RET
  429.  
  430. MOVE2    LXI H,FCB3
  431.     CALL INITFCBS
  432.     LXI H,FCB
  433.     LXI D,FCB3
  434.     MVI B,12
  435.     CALL MOVE
  436.     RET
  437.  
  438. ;FILE TRANSFER ROUTINE - CALLED WITH 
  439. ;CONTROL-T FROM TERMINAL ROUTINE.
  440. ;TRANSFER MAY BE CANCELLED WHILE SENDING BY USING CONTROL-X.
  441.  
  442. TRANSFER
  443.     PUSH H ! PUSH D ! PUSH B ! PUSH PSW
  444.     LXI H,FCB4
  445.     CALL INITFCBS    ;INITIALIZES FCBS POINTED..
  446.     LXI H,FCB+16    ;..TO BY HL REG.
  447.     CALL INITFCBS
  448. GET    CALL GETNAME
  449.     LDA CMDBUF+2    ;WAS FILE ENTERED
  450.     CPI 20H
  451.     JZ TRANSL2
  452.     CALL MOVE4
  453.     CALL OPEN4
  454.     CPI 0FFH    ;RETURN WITH 0FFH MEANS
  455.     JNZ CONTIN    ;FILE DOES NOT EXIST
  456. TRANSL1    CALL ILPRT
  457.         DB CR,LF,'++FILE DOES NOT EXIST++',CR,LF,0
  458. TRANSL2    CALL ILPRT
  459.         DB 'TYPE "R" TO RETURN TO MODEM',CR,LF
  460.         DB 'TYPE "A" TO RE-ENTER NAME: ',BELL,0
  461.     CALL KEYIN
  462.     CALL UCASE
  463.     CALL TYPE    ;ECHO RESPONSE
  464.     CALL CRLF
  465.     CPI 'A'
  466.     JZ GET
  467.     CPI 'R'
  468.     JZ RETURN
  469.     JMP TRANSL2
  470.  
  471. CONTIN    LXI D,80H
  472.     MVI C,STDMA
  473.     CALL BDOS
  474. READMR    CALL READ80
  475.     CPI 1        ;END OF FILE
  476.     JZ RETURNS
  477.     CPI 2        ;BAD READ
  478.     JZ RETURNU
  479.     CALL SEND80C
  480.     CPI EOFCHAR    ;END OF FILE - OMIT IF OBJECT..
  481.     JZ RETURNS    ;..CODE IS TO BE SENT.
  482.     CPI CAN        ;CANCELLATION?
  483.     JZ TRANCAN
  484.     JMP READMR
  485. RETURNS    CALL ILPRT
  486.         DB CR,LF,'++FILE TRANSFER COMPLETED++',CR,LF,BELL,0
  487.     JMP RETURN
  488. RETURNU    CALL ILPRT
  489.         DB CR,LF,'++FILE TRANSFER UNSUCCESSFUL++',CR,LF,BELL,0
  490.     JMP RETURN
  491. TRANCAN    CALL ILPRT
  492.         DB CR,LF,CR,LF,'++ TRANSFER CANCELLED ++',CR,LF,BELL,0
  493. RETURN    POP PSW ! POP B ! POP D ! POP H
  494.     RET
  495.  
  496. INITFCBS        ;ENTRY AT +2 WILL LEAVE..
  497.     MVI M,0        ;..DRIVE NO. INTACT.
  498.     INX H        ;WILL INITIALIZE AN FCB..
  499.     MVI B,11    ;..POINTED TO BY HL-REG. FILLS 1ST POS
  500. LOOP10    MVI M,' '    ;..WITH 0, NEXT 11 WITH..
  501.     INX H        ;..WITH BLANKS, AND LAST..
  502.     DCR B        ;..21 WITH NULLS.
  503.     JNZ LOOP10
  504.     MVI B,21
  505. LOOP11    MVI M,0
  506.     INX H
  507.     DCR B
  508.     JNZ LOOP11
  509.     RET
  510.  
  511. GETNAME    CALL ILPRT
  512.         DB CR,LF,'ENTER FILE NAME TO BE TRANSFERRED -  C/R TO QUIT: ',0
  513.     LXI D,CMDBUF
  514.     CALL INBUFF
  515.     CALL CRLF
  516.     RET
  517.  
  518. MOVE4    LXI D,CMDBUF
  519.     LXI H,FCB4
  520.     CALL CPMLINE
  521.     RET
  522.  
  523. OPEN4    LXI D,FCB4
  524.     MVI C,OPEN
  525.     CALL BDOS
  526.     RET
  527.  
  528. READ80    LXI D,FCB4
  529.     MVI C,READ
  530.     CALL BDOS
  531.     RET
  532.  
  533. SEND80C    MVI B,80H
  534.     LXI H,80H
  535. SENDCH1    MOV A,M
  536.     CALL MODOUT
  537.     CPI EOFCHAR
  538.     RZ
  539.     CALL STAT    ;TEST TO SEE IF
  540.     ORA A        ;CANCELLATION REQUESTED
  541.     JZ SKIP12
  542.     CALL KEYIN
  543.     CPI CAN
  544.     RZ
  545. SKIP12    INX H
  546.     DCR B
  547.     JNZ SENDCH1
  548.     RET
  549.  
  550. MODOUT    PUSH PSW
  551. MODOUTL    CALL IN$MODCTLP
  552.     CALL ANI$MODSNDB
  553.     CALL CPI$MODSNDR
  554.     JNZ MODOUTL
  555.     POP PSW
  556.     CALL OUT$MODDATP
  557.     CALL TYPE
  558.     RET
  559.  
  560. FCB4    DS 33
  561.  
  562. ;TERMINAL ECHO MODE
  563.  
  564. TRMECHO    CALL IN$MODCTLP
  565.     CALL ANI$MODRCVB
  566.     CALL CPI$MODRCVR
  567.     JZ LINECHR
  568.     CALL STAT
  569.     JZ TRMECHO
  570.     CALL KEYIN
  571.     CPI EXITCHR
  572.     JZ MENU
  573.  
  574.     MOV B,A
  575.     LDA PMMIBYTE
  576.     ORA A
  577.     MOV A,B
  578.     JZ S3
  579.     CPI CHGBAUD    ;SAME ROUTINE AS IN TERMINAL MODE
  580.     PUSH PSW
  581.     CZ NEWBAUD
  582.     POP PSW
  583.     CPI CHGBAUD
  584.  
  585.     JZ TRMECHO
  586. S3    CALL OUT$MODDATP
  587.     CALL TYPE
  588.     JMP TRMECHO
  589.  
  590. LINECHR    CALL IN$MODDATP
  591.     CALL OUT$MODDATP
  592.     CALL TYPE
  593.     JMP TRMECHO
  594.  
  595. ;UNCOMMENTED LINES ARE THOSE OF ORIGINAL MODEM PROGRAM.
  596. ;COMMENTS DENOTE MY ADDITIONS.
  597.  
  598. ;        SEND A CP/M FILE
  599.  
  600. SENDFIL    LDA BATCHFLG    ;CHECK IF MULTIPLE FILE..
  601.     ORA A        ;..MODE IS SET.
  602.     JNZ SENDC1
  603.     MVI A,TRUE    ;INDICATE BATCH SEND
  604.     STA SENDFLG
  605.     LDA FSTFLG    ;IF FIRST TIME THRU..
  606.     ORA A        ;..SCAN THE COMMAND LINE..
  607.     CNZ TNMBUF    ;..FOR MULTIPLE NAMES.
  608.     CALL SENDFN    ;SENDS FILE NAME TO RECEIVER
  609.     JNC SENDC2    ;CARRY SET MEANS NO MORE FILES.
  610.     MVI A,'B'    ;STOP BATCH..
  611.     STA BATCHFLG    ;..MODE OPTION.
  612.     MVI A,EOT    ;FINAL XFER END
  613.     CALL SEND
  614.     JMP DONE
  615. SENDC1    LDA FCB+1
  616.     CPI ' '
  617.     JZ BLKFILE
  618. SENDC2    CALL OPENFIL
  619.     MVI E,80
  620.     CALL WAITNAK
  621. SENDLP    CALL RDSECT
  622.     JC SENDEOF
  623.     CALL INCRSNO
  624.     XRA A
  625.     STA ERRCT
  626. SENDRPT    CALL SENDHDR
  627.     CALL SENDSEC
  628.     CALL SENDCKS
  629.     CALL GETACK
  630.     JC SENDRPT
  631.     JMP SENDLP
  632.  
  633. SENDEOF    MVI A,EOT
  634.     CALL SEND
  635.     CALL GETACK
  636.     JC SENDEOF
  637.     JMP DONE
  638.  
  639. ;        RECEIVE A FILE
  640.  
  641. RCVFIL    LDA BATCHFLG    ;CHECK IF MULT..
  642.     ORA A        ;..FILE MODE.
  643.     JNZ RCVC1
  644.     MVI A,FALSE    ;FLAG WHERE TO RETURN..
  645.     STA SENDFLG    ;..FOR NEXT FILE TRANS.
  646.     CALL GETFN    ;GET THE FILE NAME.
  647.     JNC RCVC2    ;CARRY SET MEANS NO MORE FILES.
  648.     MVI A,'B'    ;STOP BATCH..
  649.     STA BATCHFLG    ;..MODE OPTION.
  650.     JMP DONE
  651. RCVC1    LDA FCB+1    ;MAKE SURE FILE IS NAMED
  652.     CPI ' '
  653.     JZ BLKFILE
  654.     JMP RCVC3
  655. RCVC2    CALL CKCPM2
  656.     CALL CKBAKUP
  657. RCVC3    CALL ERASFIL
  658.     CALL MAKEFIL
  659.     LDA QFLG
  660.     ORA A
  661.     JNZ RCVLP
  662.     LDA BATCHFLG
  663.     ORA A        ;DON'T PRINT MSSG IF..
  664.     JZ RCVLP    ;..IN MULTI AND QUIET.
  665.     CALL ILPRT
  666.     DB 'FILE OPEN, READY TO RECEIVE',CR,LF,0
  667. RCVLP    CALL RCVSECT
  668.     JC RCVEOT
  669.     CALL WRSECT
  670.     CALL INCRSNO
  671.     CALL SENDACK
  672.     JMP RCVLP
  673.  
  674. RCVEOT    CALL WRBLOCK
  675.     CALL SENDACK
  676.     CALL CLOSFIL
  677.     JMP DONE
  678.     
  679. ;SUBROUTINES
  680.  
  681. SENDFN    LDA QFLG
  682.     ORA A
  683.     JZ SWNAK
  684.     CALL ILPRT
  685.     DB 'AWAITING NAME NAK',CR,LF,0
  686. SWNAK    MVI E,80
  687.     CALL WAITNLP
  688.     MVI A,ACK    ;GOT NAK, SEND ACK
  689.     CALL SEND
  690.     LXI H,FILECT
  691.     DCR M
  692.     JM NOMRNM
  693.     LHLD NBSAVE    ;GET FILE NAME..
  694.     LXI D,FCB    ;..IN FCB
  695.     MVI B,12
  696.     CALL MOVE
  697.     SHLD NBSAVE
  698.     CALL SENDNM    ;SEND IT
  699.     ORA A        ;CLEAR CARRY
  700.     RET
  701. NOMRNM    MVI A,EOT
  702.     CALL SEND
  703.     STC
  704.     RET
  705.  
  706. SENDNM    PUSH H
  707. SENDNM1    MVI D,11    ;COUNT CHARS IN NAME
  708.     MVI C,0        ;INIT CHECKSUM
  709.     LXI H,FCB+1    ;ADDRESS NAME
  710. NAMLPS    MOV A,M        ;SEND NAME
  711.     ANI 7FH        ;STRIP HIGH ORDER BIT SO CP/M 2..
  712.     CALL SEND    ;..WON'T SEND R/O FILE DESIGNATION.
  713.     LDA QFLG    ;SHOW NAME IF..
  714.     ORA A        ;..QFLG NOT SET.
  715.     MOV A,M
  716.     CNZ TYPE
  717. ACKLP    PUSH B        ;SAVE CKSUM
  718.     MVI B,1        ;WAIT FOR RECEIVER..
  719.     CALL RECV    ;..TO ACKNOWLEDGE..
  720.     POP B        ;..GETTING LETTER.
  721.     JC SCKSER
  722.     CPI ACK
  723.     JNZ ACKLP
  724.     INX H        ;NEXT CHAR
  725.     DCR D
  726.     JNZ NAMLPS
  727.     MVI A,EOFCHAR    ;TELL RECEIVER END OF NAME
  728.     CALL SEND
  729.     LDA QFLG
  730.     ORA A
  731.     CNZ CRLF
  732.     MOV D,C        ;SAVE CHECKSUM
  733.     MVI B,1
  734.     CALL RECV    ;GET CHECKSUM..
  735.     CMP D        ;..FROM RECEIVER.
  736.     JZ NAMEOK
  737. SCKSER    MVI A,BDNMCH    ;BAD NAME-TELL RECEIVER
  738.     CALL SEND
  739.     LDA QFLG
  740.     ORA A
  741.     JZ SKCSER1
  742.     CALL ILPRT
  743.     DB 'CHECKSUM ERROR',CR,LF,0
  744. SKCSER1    MVI E,80    ;DO HANDSHAKING OVER
  745.     CALL WAITNLP    ;DON'T PRINT "AWAITING NAK" MSG
  746.     MVI A,ACK
  747.     CALL SEND
  748.     JMP SENDNM1
  749. NAMEOK    MVI A,OKNMCH    ;GOOD NAME-TELL RECEIVER
  750.     CALL SEND
  751.     POP H
  752.     RET    
  753.  
  754. GETFN    LXI H,FCB
  755.     CALL INITFCBS+2    ;DOES NOT INITIALIZE DRIVE
  756.     LDA QFLG
  757.     ORA A
  758.     JZ GNAMELP
  759.     CALL ILPRT
  760.     DB 'AWAITING FILE NAME',CR,LF,0
  761. GNAMELP    CALL HSNAK
  762.     JC GNAMELP
  763.     CALL GETNM    ;GET THE NAME
  764.     CPI EOT        ;IF EOT, THEN NO MORE FILES
  765.     JZ NOMRNMG
  766.     ORA A        ;CLEAR CARRY
  767.     RET
  768. NOMRNMG    STC
  769.     RET
  770.  
  771. GETNM    PUSH H
  772. GETNM1    MVI C,0        ;INIT CHECKSUM
  773.     LXI H,FCB+1
  774. NAMELPG    MVI B,5
  775.     CALL RECV    ;GET CHAR
  776.     JNC GETNM3
  777.     LDA QFLG
  778.     ORA A
  779.     JZ GETNM2
  780.     CALL ILPRT
  781.     DB 'TIME OUT RECEIVING FILENAME',CR,LF,0
  782. GETNM2    JMP GCKSER
  783. GETNM3    CPI EOT        ;IF EOT, THEN NO MORE FILES
  784.     JZ GNRET
  785.     CPI EOFCHAR    ;GOT END OF NAME
  786.     JZ ENDNAME
  787.     MOV M,A        ;PUT NAME IN FCB
  788.     LDA QFLG    ;TYPE IT IF NO QFLG
  789.     ORA A
  790.     MOV A,M
  791.     CNZ TYPE
  792.     PUSH B        ;SAVE CKSUM
  793.     MVI A,ACK    ;ACK GETTING LETTER
  794.     CALL SEND
  795.     POP B
  796.     INX H        ;GET NEXT CHAR
  797.     MOV A,L        ;DON'T LET NOISE...
  798.     CPI 7FH        ;..CAUSE OVERFLOW..
  799.     JZ GCKSER    ;..INTO PROGRAM AREA.
  800.     JMP NAMELPG
  801. ENDNAME    LDA QFLG
  802.     ORA A
  803.     CNZ CRLF
  804.     MOV A,C        ;SEND CHECKSUM
  805.     CALL SEND
  806.     MVI B,1
  807.     CALL RECV    ;CHECKSUM GOOD?
  808.     CPI OKNMCH    ;YES IF OKNMCH SENT..
  809.     JZ GNRET    ;..ELSE DO OVER.
  810. GCKSER    LXI H,FCB    ;CLEAR FCB (EXCEPT DRIVE)..
  811.     CALL INITFCBS+2    ;..SINCE IT MIGHT BE DAMAGED..
  812.     LDA QFLG    ;..BY TOO MANY CHARS.
  813.     ORA A
  814.     JZ GCKSER1
  815.     CALL ILPRT
  816.     DB 'CHECKSUM ERROR',CR,LF,0
  817. GCKSER1    CALL HSNAK    ;DO HANDSHAKING OVER
  818.     JC GCKSER1
  819.     JMP GETNM1
  820. GNRET    POP H
  821.     RET
  822.  
  823. HSNAK    MVI A,NAK    ;SEND NAK UNTIL..
  824.     CALL SEND    ;..RECEIVING ACK.
  825.     CALL CKABORT    ;DON'T GET HUNG UP HERE
  826.     MVI B,2        ;WAIT 2 SECONDS..
  827.     CALL RECV    ;..IN RECEIVE.
  828.     CPI CAN        ;IF SENDER ABORTS..
  829.     JZ ABORT    ;..DURING NAME TRANSFER.
  830.     CPI ACK        ;IF NAK,RETURN WITH..
  831.     RZ        ;..CARRY CLEAR.
  832.     STC
  833.     RET
  834.  
  835. TNMBUF    MVI A,FALSE    ;CALL FROM SENDFIL ONLY ONCE.
  836.     STA FSTFLG
  837.     STA FILECT
  838.     CALL SCAN
  839.     LXI H,NAMEBUF
  840.     SHLD NBSAVE    ;SAVE ADDR OF 1ST NAME
  841. TNLP1    CALL TRTOBUF
  842.     LXI H,FCB
  843.     LXI D,FCBBUF
  844.     CALL CPMLINE    ;PARSE NAME TO CP/M FORMAT
  845. TNLP2    CALL MFNAME    ;SEARCH FOR NAMES (* FORMAT)
  846.     JC NEXTNM
  847.     LDA FCB+10    ;IF CP/M 2 $SYS FILE..
  848.     ANI 80H        ;..DON'T SEND
  849.     JNZ TNLP2
  850.     LHLD NBSAVE    ;GET NAME
  851.     LXI D,FCB    ;MOVE IT TO FCB
  852.     XCHG
  853.     MVI B,12
  854.     CALL MOVE
  855.     XCHG
  856.     SHLD NBSAVE    ;ADDR OF NEXT NAME
  857.     LXI H,FILECT    ;COUNT FILES FOUND
  858.     INR M
  859.     JMP TNLP2
  860. NEXTNM    LXI H,NAMECT    ;COUNT NAMES FOUND
  861.     DCR M
  862.     JNZ TNLP1
  863.     LXI H,NAMEBUF    ;SAVE START OF BUFFER
  864.     SHLD NBSAVE
  865.     LDA FILECT
  866.     CPI 65        ;NO MORE THAN 64 TRANSFERS
  867.     RC
  868.     MVI A,64    ;ONLY X'FER FIRST 64
  869.     STA FILECT
  870.     RET
  871.  
  872. ;SCANS CMDBUF COUNTING NAMES AND PUTTING DELIMITER (SPACE)
  873. ;AFTER LAST NAME
  874.  
  875. SCAN    PUSH H
  876.     LXI H,NAMECT
  877.     MVI M,0
  878.     LXI H,CMDBUF+1    ;FIND END OF CMD LINE..
  879.     MOV C,M        ;..AND PUT SPACE THERE.
  880.     MVI B,0
  881.     LXI H,CMDBUF+2
  882.     DAD B
  883.     MVI M,20H
  884.     LXI H,CMDBUF+1
  885.     MOV B,M
  886.     INR B
  887.     INR B
  888. SCANLP1    INX H
  889.     DCR B
  890.     JZ DNSCAN
  891.     MOV A,M
  892.     CPI 20H
  893.     JNZ SCANLP1
  894. SCANLP2    INX H        ;EAT EXTRA SPACES
  895.     DCR B
  896.     JZ DNSCAN
  897.     MOV A,M
  898.     CPI 20H
  899.     JZ SCANLP2
  900.     SHLD BGNMS    ;SAVE START OF NAMES IN CMDBUF
  901.     INR B
  902.     DCX H
  903. SCANLP3    INX H
  904.     DCR B
  905.     JZ DNSCAN
  906.     MOV A,M
  907.     CPI 20H
  908.     JNZ SCANLP3
  909.     LDA NAMECT    ;COUNTS NAMES
  910.     INR A
  911.     STA NAMECT
  912. SCANLP4    INX H        ;EAT SPACES
  913.     DCR B
  914.     JZ DNSCAN
  915.     MOV A,M
  916.     CPI 20H
  917.     JZ SCANLP4
  918.     JMP SCANLP3
  919. DNSCAN    MVI M,20H    ;SPACE AFTER LAST CHAR
  920.     POP H
  921.     RET
  922.  
  923. ;PLACES NEXT NAME IN BUFFER SO CPMLINE MAY PARSE IT
  924.  
  925. TRTOBUF    LHLD BGNMS
  926.     MVI B,0
  927.     LXI D,FCBBUF+2
  928. TBLP    MOV A,M
  929.     CPI 20H
  930.     JZ TRBFEND
  931.     STAX D
  932.     INX H
  933.     INX D
  934.     INR B        ;COUNT CHARS IN NAME
  935.     JMP TBLP
  936. TRBFEND    INX H
  937.     MOV A,M        ;EAT EXTRA SPACES
  938.     CPI 20H
  939.     JZ TRBFEND
  940.     SHLD BGNMS
  941.     LXI H,FCBBUF+1    ;PUT # CHARS BEFORE NAME
  942.     MOV M,B
  943.     RET
  944.  
  945. ;IN CP/M V.2, IF FILE IS R/O OR SYS, IT IS CHANGED TO 'BAK'.
  946.  
  947. CKCPM2    MVI C,12
  948.     CALL BDOS
  949.     ORA A        ;RETURN 0 MEANS CP/M 1
  950.     RZ
  951.     MVI C,STDMA
  952.     LXI D,80H
  953.     CALL BDOS
  954.     MVI C,SRCHF    ;SEARCH FOR FILE
  955.     LXI D,FCB
  956.     CALL BDOS
  957.     CPI 0FFH
  958.     RZ
  959.     ADD A ! ADD A    ;MULT A-REG BY..
  960.     ADD A ! ADD A    ;..32 TO FIND..
  961.     ADD A        ;..NAME IN DMA.
  962.     LXI H,80H
  963.     ADD L
  964.     MOV L,A        ;HL POINTS TO DIR NAME
  965.     LXI D,9
  966.     DAD D        ;POINT TO R/O ATTRIB BYTE
  967.     MOV A,M
  968.     ANI 80H        ;TEST MSB
  969.     JNZ MKCHG    ;IF SET, MAKE CHANGE
  970.     INX H        ;CHECK SYSTEM ATTRIB BYTE
  971.     MOV A,M
  972.     ANI 80H
  973.     RZ        ;NOT $SYS OR $R/O
  974.     DCX H
  975. MKCHG    LXI D,-8
  976.     DAD D        ;POINT HL TO FILENAME + 1
  977.     LXI D,FCB+1    ;MOVE DIR NAME TO FCB..
  978.     MVI B,11    ;..WITHOUT CHANGING DRIVE.
  979.     CALL MOVE
  980.     LXI H,FCB+9    ;R/O ATTRIB
  981.     MOV A,M
  982.     ANI 7FH        ;STRIP R/O ATTRIB
  983.     MOV M,A
  984.     INX H        ;SYS ATTRIB
  985.     MOV A,M
  986.     ANI 7FH
  987.     MOV M,A
  988.     LXI D,FCB
  989.     MVI C,30    ;SET NEW ATTRIBS IN DIR
  990.     CALL BDOS
  991.  
  992. ;MAY BE CALLED BY CKBAKUP BELOW. ITS RETURN DONE HERE
  993.  
  994. PLANCHG    LXI H,FCB    ;CHANGE NAME TO TYPE "BAK"
  995.     LXI D,6CH
  996.     MVI B,9        ;MOVE DRIVE AND NAME (NOT TYPE)
  997.     CALL MOVE
  998.     LXI H,75H    ;START OF TYPE IN FCB2
  999.     MVI M,'B'
  1000.     INX H
  1001.     MVI M,'A'
  1002.     INX H
  1003.     MVI M,'K'
  1004.     LXI D,6CH
  1005.     MVI C,ERASE    ;ERASE ANY PREV BACKUPS
  1006.     CALL BDOS
  1007.     LXI H,6CH    ;FCB2 DR FIELD SHOULD..
  1008.     MVI M,0        ;..0 FOR RENAME.
  1009.     LXI D,FCB
  1010.     MVI C,23    ;RENAME
  1011.     CALL BDOS
  1012.     RET
  1013.  
  1014. CKBAKUP    LDA BAKUPBYTE
  1015.     ORA A
  1016.     RZ
  1017.     MVI C,SRCHF
  1018.     LXI D,FCB
  1019.     CALL BDOS
  1020.     INR A
  1021.     RZ        ;FILE NOT FOUND
  1022.     JMP PLANCHG    ;IN "CKCPM2" - RET DONE THERE
  1023.  
  1024. ;MULTI-FILE ACCESS SUBROUTINE FROM CP/M USER'S GROUP
  1025. ;FIXED BY MARK ZEIGER 8/17/80
  1026. ;CARRY IS SET IF NO MORE NAMES CAN BE FOUND
  1027.  
  1028. MFNAME    MFACCESS    ;A MACRO IN MACROS.LIB
  1029.  
  1030.  
  1031. RCVSECT    XRA A
  1032.     STA ERRCT
  1033. RCVRPT    LDA QFLG
  1034.     ORA A
  1035.     JZ RCVSQ
  1036.     CALL ILPRT
  1037.     DB 'AWAITING #',0
  1038.     LDA SECTNO
  1039.     INR A
  1040.     CALL HEXO
  1041.     CALL CRLF
  1042. RCVSQ    MVI B,7        ;10 IN ORIG PROG
  1043.     CALL RECV
  1044.     JC RCVSTOT
  1045.     CPI CAN        ;CHECK FOR CANCEL..
  1046.     JZ ABORT    ;..REQUEST FROM SENDER.
  1047.     CPI SOH
  1048.     JZ RCVSOH
  1049.     ORA A
  1050.     JZ RCVSQ
  1051.     CPI EOT
  1052.     STC
  1053.     RZ
  1054.     MOV B,A
  1055.     LDA VSEEFLG
  1056.     ORA A
  1057.     JZ RCVSEH
  1058.     LDA QFLG
  1059.     ORA A
  1060.     JZ RCVSERR
  1061. RCVSEH    MOV A,B
  1062.     CALL HEXO
  1063.     CALL ILPRT
  1064.         DB 'H RCD, NOT SOH',CR,LF,0
  1065.  
  1066. RCVSERR    MVI B,1
  1067.     CALL RECV
  1068.     JNC RCVSERR
  1069.     MVI A,NAK
  1070.     CALL SEND
  1071.     LDA ERRCT
  1072.     INR A
  1073.     STA ERRCT
  1074.     CPI ERRLIM
  1075.     JC RCVRPT
  1076.     LDA VSEEFLG
  1077.     ORA A
  1078.     JZ RCVCKQ
  1079.     LDA QFLG
  1080.     ORA A
  1081.     JZ RCVSABT
  1082. RCVCKQ    CALL CKQUIT
  1083.     JZ RCVSECT
  1084. RCVSABT    CALL CLOSFIL
  1085.     CALL ERXIT
  1086.     DB '++    UNABLE TO RECEIVE BLOCK     --  ABORTING ++',CR,LF,'$'
  1087.  
  1088. RCVSTOT    LDA VSEEFLG
  1089.     ORA A
  1090.     JZ RCVSPT
  1091.     LDA QFLG
  1092.     ORA A
  1093.     JZ RCVSERR
  1094. RCVSPT    CALL ILPRT
  1095.         DB '++  TIMEOUT ++ ',0
  1096. RCVPRN    LDA ERRCT
  1097.     CALL HEXO
  1098.     CALL CRLF
  1099.     JMP RCVSERR
  1100.  
  1101. RCVSOH    MVI B,1
  1102.     CALL RECV
  1103.     JC RCVSTOT
  1104.     MOV D,A
  1105.     MVI B,1
  1106.     CALL RECV
  1107.     JC RCVSTOT
  1108.     CMA
  1109.     CMP D
  1110.     JZ RCVDATA
  1111.     LDA VSEEFLG
  1112.     ORA A
  1113.     JZ RCVBSE
  1114.     LDA QFLG
  1115.     ORA A
  1116.     JZ RCVSERR
  1117. RCVBSE    CALL ILPRT
  1118.         DB '++  BAD SECTOR # IN HDR',CR,LF,0
  1119.     JMP RCVSERR
  1120.  
  1121. RCVDATA    MOV A,D
  1122.     STA RCVSNO
  1123.     MVI A,1
  1124.     STA DATAFLG
  1125.     MVI C,0
  1126.     LXI H,80H
  1127.  
  1128. RCVCHR    MVI B,1
  1129.     CALL RECV
  1130.     JC RCVSTOT
  1131.     MOV M,A
  1132.     INR L
  1133.     JNZ RCVCHR
  1134.     MOV D,C
  1135.     XRA A
  1136.     STA DATAFLG
  1137.     MVI B,1
  1138.     CALL RECV
  1139.     JC RCVSTOT
  1140.     CMP D
  1141.     JNZ RCVCERR
  1142.     LDA RCVSNO
  1143.     MOV B,A
  1144.     LDA SECTNO
  1145.     CMP B
  1146.     JZ RECVACK
  1147.     INR A
  1148.     CMP B
  1149.     JNZ ABORT
  1150.     RET
  1151.  
  1152. RCVCERR    LDA VSEEFLG
  1153.     ORA A
  1154.     JZ RCVCPR
  1155.     LDA QFLG
  1156.     ORA A
  1157.     JZ RCVSERR
  1158. RCVCPR    CALL ILPRT
  1159.         DB '++  CKSUM ++ ',0
  1160.     JMP RCVPRN
  1161.  
  1162. RECVACK    CALL SENDACK
  1163.     JMP RCVSECT
  1164.  
  1165. SENDACK    MVI A,ACK
  1166.     CALL SEND
  1167.     RET
  1168.  
  1169. SENDHDR    LDA QFLG
  1170.     ORA A
  1171.     JZ SENDHNM
  1172.     CALL ILPRT
  1173.         DB 'SEND # ',0
  1174.     LDA SECTNO
  1175.     CALL HEXO
  1176.     CALL CRLF
  1177. SENDHNM    MVI A,SOH
  1178.     CALL SEND
  1179.     LDA SECTNO
  1180.     CALL SEND
  1181.     LDA SECTNO
  1182.     CMA
  1183.     CALL SEND
  1184.     RET
  1185.  
  1186. SENDSEC    MVI A,1
  1187.     STA DATAFLG
  1188.     MVI C,0
  1189.     LXI H,80H
  1190. SENDC    MOV A,M
  1191.     CALL SEND
  1192.     INR L
  1193.     JNZ SENDC
  1194.     XRA A
  1195.     STA DATAFLG
  1196.     RET
  1197.  
  1198. SENDCKS    MOV A,C
  1199.     CALL SEND
  1200.     RET
  1201.  
  1202. GETACK    MVI B,7        ;10 IN ORIG PROG
  1203.     CALL RECVDG
  1204.     JC GETATOT
  1205.     CPI ACK
  1206.     RZ
  1207.     CPI CAN
  1208.     JZ ABORT
  1209.     MOV B,A
  1210.     LDA QFLG
  1211.     ORA A
  1212.     JZ ACKERR
  1213.     MOV A,B
  1214.     CALL HEXO
  1215.     CALL ILPRT
  1216.         DB 'H RCD, NOT ACK',CR,LF,0
  1217. ACKERR    LDA ERRCT
  1218.     INR A
  1219.     STA ERRCT
  1220.     CPI ERRLIM
  1221.     RC
  1222.     LDA VSEEFLG
  1223.     ORA A
  1224.     JZ GACKV
  1225.     LDA QFLG
  1226.     ORA A
  1227.     JZ CSABORT
  1228. GACKV    CALL CKQUIT
  1229.     STC
  1230.     RZ
  1231. CSABORT    CALL ERXIT
  1232.     DB 'CAN''T SEND SECTOR -- ABORTING',CR,LF,'$'
  1233.  
  1234. GETATOT    LDA QFLG
  1235.     ORA A
  1236.     JZ ACKERR
  1237.     CALL ILPRT
  1238.         DB 'TIMEOUT ON ACK',CR,LF,0
  1239.     JMP ACKERR
  1240.  
  1241. CKABORT    LDA VSEEFLG
  1242.     ORA A
  1243.     JZ CKABGO
  1244.     LDA QFLG
  1245.     ORA A
  1246.     RZ
  1247. CKABGO    CALL STAT
  1248.     RZ
  1249.     CALL KEYIN
  1250.     CPI CAN
  1251.     RNZ
  1252.  
  1253. ABORT    LXI SP,STACK
  1254. ABORTL    MVI B,1
  1255.     CALL RECV
  1256.     JNC ABORTL
  1257.     MVI A,CAN
  1258.     CALL SEND
  1259. ABORTW    MVI B,1
  1260.     CALL RECV
  1261.     JNC ABORTW
  1262.     MVI A,' '
  1263.     CALL SEND
  1264.     CALL ILPRT
  1265.         DB 'ROUTINE CANCELLED',CR,LF,BELL,0
  1266.     MVI A,'B'        ;TURN MULTI-FILE MODE..
  1267.     STA BATCHFLG        ;..OFF SO ROUTINE ENDS.
  1268.     JMP DONETCE
  1269.  
  1270. INCRSNO    LDA SECTNO
  1271.     INR A
  1272.     STA SECTNO
  1273.     RET
  1274.  
  1275. ERASFIL    LDA BATCHFLG        ;DON'T ASK FOR ERASE..
  1276.     ORA A            ;..IN MULTI-FILE MODE,..
  1277.     JZ NOASK        ;..JUST DO IT.
  1278.     LXI D,FCB
  1279.     MVI C,SRCHF
  1280.     CALL BDOS
  1281.     INR A
  1282.     RZ
  1283.     CALL ILPRT
  1284.         DB 'FILES EXISTS -- TYPE ''Y'' TO ERASE: ',BELL,0
  1285.     CALL KEYIN
  1286.     PUSH PSW
  1287.     CALL TYPE
  1288.     POP PSW
  1289.     CALL UCASE
  1290.     CPI 'Y'
  1291.     JNZ MENU
  1292.     CALL CRLF
  1293.  
  1294. NOASK    LXI D,FCB
  1295.     MVI C,ERASE
  1296.     CALL BDOS
  1297.     RET
  1298.  
  1299. BLKFILE    CALL ILPRT    ;ROUTINE IF NO FILE IS NAMED FOR "SEND" OR "RECEIVE"
  1300.     DB CR,LF,'No file specified',CR,LF,BELL,0
  1301.     JMP MENU
  1302.  
  1303. MAKEFIL    LXI D,FCB
  1304.     MVI C,MAKE
  1305.     CALL BDOS
  1306.     INR A
  1307.     RNZ
  1308.     CALL ERXIT
  1309.     DB 'ERROR - CAN''T MAKE FILE',CR,LF
  1310.     DB 'DIRECTORY MUST BE FULL',CR,LF,'$'
  1311.  
  1312. OPENFIL    LXI D,FCB
  1313.     MVI C,OPEN
  1314.     CALL BDOS
  1315.     INR A
  1316.     JNZ OPENOK
  1317.     CALL ERXIT
  1318.     DB 'CAN''T OPEN FILE$'
  1319.  
  1320. OPENOK    LDA BATCHFLG
  1321.     ORA A
  1322.     JNZ OPENOK1
  1323.     LDA QFLG
  1324.     ORA A
  1325.     RZ
  1326. OPENOK1    CALL ILPRT
  1327.         DB 'FILE OPEN - EXTENT LENGTH: ',0
  1328.     LDA FCB+15
  1329.     CALL HEXO
  1330.     MVI A,'H'
  1331.     CALL TYPE
  1332.     CALL CRLF
  1333.     RET
  1334.  
  1335. CLOSFIL    LXI D,FCB
  1336.     MVI C,CLOSE
  1337.     CALL BDOS
  1338.     INR A
  1339.     RNZ
  1340.     CALL ERXIT
  1341.     DB 'CAN''T CLOSE FILE$'
  1342.  
  1343. RDSECT    LDA SECINBF
  1344.     DCR A
  1345.     STA SECINBF
  1346.     JM RDBLOCK
  1347.     LHLD SECPTR
  1348.     LXI D,80H
  1349.     CALL MOVE128
  1350.     SHLD SECPTR
  1351.     RET
  1352.  
  1353. RDBLOCK    LDA EOFLG
  1354.     CPI 1
  1355.     STC
  1356.     RZ
  1357.     MVI C,0
  1358.     LXI D,DBUF
  1359. RDSECLP    PUSH B
  1360.     PUSH D
  1361.     MVI C,STDMA
  1362.     CALL BDOS
  1363.     LXI D,FCB
  1364.     MVI C,READ
  1365.     CALL BDOS
  1366.     POP D
  1367.     POP B
  1368.     ORA A
  1369.     JZ RDSECOK
  1370.     DCR A
  1371.     JZ REOF
  1372.     CALL ERXIT
  1373.     DB '++    FILE READ ERROR    ++$'
  1374.  
  1375. RDSECOK    LXI H,80H
  1376.     DAD D
  1377.     XCHG
  1378.     INR C
  1379.     MOV A,C
  1380.     CPI 16
  1381.     JZ RDBFULL
  1382.     JMP RDSECLP
  1383. REOF    MVI A,1
  1384.     STA EOFLG
  1385.     MOV A,C
  1386.  
  1387. RDBFULL    STA SECINBF
  1388.     LXI H,DBUF
  1389.     SHLD SECPTR
  1390.     LXI D,80H
  1391.     MVI C,STDMA
  1392.     CALL BDOS
  1393.     JMP RDSECT
  1394.  
  1395. WRSECT    LHLD SECPTR
  1396.     XCHG
  1397.     LXI H,80H
  1398.     CALL MOVE128
  1399.     XCHG
  1400.     SHLD SECPTR
  1401.     LDA SECINBF
  1402.     INR A
  1403.     STA SECINBF
  1404.     CPI 16
  1405.     RNZ
  1406.  
  1407. WRBLOCK    LDA SECINBF
  1408.     ORA A
  1409.     RZ
  1410.     MOV C,A
  1411.     LXI D,DBUF
  1412. DKWRLP    PUSH H
  1413.     PUSH D
  1414.     PUSH B
  1415.     MVI C,STDMA
  1416.     CALL BDOS
  1417.     LXI D,FCB
  1418.     MVI C,WRITE
  1419.     CALL BDOS
  1420.     POP B
  1421.     POP D
  1422.     POP H
  1423.     ORA A
  1424.     JNZ WRERR
  1425.     LXI H,80H
  1426.     DAD D
  1427.     XCHG
  1428.     DCR C
  1429.     JNZ DKWRLP
  1430.     XRA A
  1431.     STA SECINBF
  1432.     LXI H,DBUF
  1433.     SHLD SECPTR
  1434.     RET
  1435.  
  1436. WRERR    MVI C,CAN
  1437.     CALL SEND
  1438.     CALL ERXIT
  1439.     DB 'ERROR WRITING FILE',CR,LF,'$'
  1440.  
  1441. RECVDG    EQU $
  1442.     CALL IN$MODDATP
  1443.     CALL IN$MODDATP
  1444.  
  1445. RECV    PUSH D
  1446.  
  1447.     LDA FASTCLK
  1448.     ORA A
  1449.     JZ MSEC
  1450.     MOV A,B
  1451.     ADD A
  1452.     MOV B,A
  1453.  
  1454. MSEC    LXI D,15000        ;60% OF ORIG 50000
  1455.     CALL CKABORT
  1456. MWTI    CALL IN$MODCTLP
  1457.     CALL ANI$MODRCVB
  1458.     CALL CPI$MODRCVR
  1459.     JZ MCHAR
  1460.     DCR E
  1461.     JNZ MWTI
  1462.     DCR D
  1463.     JNZ MWTI
  1464.     DCR B
  1465.     JNZ MSEC
  1466.     POP D
  1467.     STC
  1468.     RET
  1469.  
  1470. MCHAR    CALL IN$MODDATP
  1471.     POP D
  1472.     PUSH PSW
  1473.     ADD C
  1474.     MOV C,A
  1475.     LDA RSEEFLG
  1476.     ORA A
  1477.     JZ MONIN
  1478.     LDA VSEEFLG
  1479.     ORA A
  1480.     JNZ NOMONIN
  1481.     LDA DATAFLG
  1482.     ORA A
  1483.     JZ NOMONIN
  1484. MONIN    POP PSW
  1485.     PUSH PSW
  1486.     CALL SHOW
  1487. NOMONIN    POP PSW
  1488.     ORA A
  1489.     RET
  1490.  
  1491. SEND    PUSH PSW
  1492.     LDA SSEEFLG
  1493.     ORA A
  1494.     JZ MONOUT
  1495.     LDA VSEEFLG
  1496.     ORA A
  1497.     JNZ NOMONOT
  1498.     LDA DATAFLG
  1499.     ORA A
  1500.     JZ NOMONOT
  1501. MONOUT    POP PSW
  1502.     PUSH PSW
  1503.     CALL SHOW
  1504. NOMONOT    POP PSW
  1505.     PUSH PSW
  1506.     ADD C
  1507.     MOV C,A
  1508. SENDW    CALL IN$MODCTLP
  1509.     CALL ANI$MODSNDB
  1510.     CALL CPI$MODSNDR
  1511.     JNZ SENDW
  1512.     POP PSW
  1513.     CALL OUT$MODDATP
  1514.     RET
  1515.  
  1516. WAITNAK    LDA VSEEFLG
  1517.     ORA A
  1518.     JZ WAITNPR
  1519.     LDA QFLG
  1520.     ORA A
  1521.     JZ WAITNLP
  1522. WAITNPR    CALL ILPRT
  1523.         DB 'AWAITING INITIAL NAK',CR,LF,0
  1524. WAITNLP    CALL CKABORT
  1525.     MVI B,1
  1526.     CALL RECV
  1527.     CPI NAK
  1528.     RZ
  1529.     CPI CAN
  1530.     JZ ABORT
  1531.     DCR E
  1532.     JZ ABORT
  1533.     JMP WAITNLP
  1534.  
  1535. INITADR
  1536.     LHLD 1
  1537.     LXI D,3
  1538.     DAD D
  1539.     SHLD VSTAT+1
  1540.     DAD D
  1541.     SHLD VKEYIN+1
  1542.     DAD D
  1543.     SHLD VTYPE+1
  1544.     LDA PMMIBYTE
  1545.     ORA A
  1546.     JZ JMP$INITMOD        ;RETURN DONE FROM THIS ROUTINE..
  1547.     LDA IN$MODCTLP+1    ;..IF NOT PMMI
  1548.     STA OUT$MODCTLP+1
  1549.     INR A
  1550.     STA OUT$MODDATP+1
  1551.     STA IN$MODDATP+1
  1552.     INR A
  1553.     STA IN$BAUDRP+1
  1554.     STA OUT$BAUDRP+1
  1555.     INR A
  1556.     STA OUT$MODCTL2+1
  1557.     RET
  1558.  
  1559. PROCOPT
  1560.     LXI D,FCB+1
  1561.     LDAX D
  1562.     STA OPTION
  1563. OPTLP    INX D
  1564.     LDAX D
  1565.     CPI ' '
  1566.     JZ ENDOPT
  1567.     LXI H,OPTBL
  1568.     MVI B,OPTBE-OPTBL
  1569. OPTCK    CMP M
  1570.     JNZ OPTNO
  1571.     MVI M,0
  1572.     JMP OPTLP
  1573. OPTNO    INX H
  1574.     DCR B
  1575.     JNZ OPTCK
  1576.     JMP BADOPT
  1577.  
  1578. ENDOPT    LDA VSEEFLG
  1579.     ORA A
  1580.     RNZ
  1581.     STA QFLG
  1582.     RET
  1583.  
  1584. DONE    LDA BATCHFLG
  1585.     ORA A
  1586.     JNZ DONETCC
  1587.     LDA QFLG
  1588.     ORA A
  1589.     JZ NMSTRNS
  1590.     LXI H,FCB+1        ;PUT FILE NAME IN..
  1591.     LXI D,FTRNMSG        ;..SPACES IN MESSAGE..
  1592.     MVI B,8            ;..BELOW.
  1593.     CALL MOVE
  1594.     INX D            ;PUT FILE TYPE AFTER..
  1595.     MVI B,3            ;..SKIPPING ONE SPACE..
  1596.     CALL MOVE        ;..BELOW.    
  1597.     CALL ILPRT
  1598. FTRNMSG    DB '              TRANSFERRED',CR,LF,CR,LF,0    ;13 SPACES
  1599.  
  1600. NMSTRNS    LDA FCB            ;SAVE DRIVE NO.
  1601.     STA DISKNO
  1602.     LXI H,FCB        ;BLANK OUT FILE CONTROL BLOCKS
  1603.     CALL INITFCBS
  1604.     LDA DISKNO        ;PUT DRIVE NUMBER BACK
  1605.     STA FCB
  1606.     LXI H,RESTSN        ;RESTORE SECTORE NUMBERS..
  1607.     LXI D,SECTNOB        ;..FOR NEW FILE TRANSFER.
  1608.     MVI B,SECTNOE-SECTNOB    ;ROUTINE ALSO DONE IN MENU.
  1609.     CALL MOVE
  1610.     LDA SENDFLG        ;GOES TO EITHER SEND OR..
  1611.     ORA A            ;..RECEIVE FILE, DEPENDING..
  1612.     JNZ SENDFIL        ;..UPON WHICH ROUTINE SET..
  1613.     JMP RCVFIL        ;..THE FLAG IN MULTI-FILE MODE.
  1614.  
  1615. DONETCC    MVI A,TRUE        ;INDICATE NO FILES BEING..
  1616.     STA FSTFLG        ;RESET MULTIFILE TRANS
  1617.     STA NFILFLG        ;..USED IN TERMINAL ROUTINE.
  1618.     CMA
  1619.     OUT FRONTPAN
  1620.     STA SAVEFLG        ;STOP MEMORY SAVE IN TERM ROUTINE.
  1621.     LDA VSEEFLG
  1622.     ORA A
  1623.     JZ DONETC
  1624.     LDA QFLG
  1625.     ORA A
  1626.     JZ donetca
  1627. DONETC    CALL ILPRT
  1628.         DB  CR,LF,'ALL TRANSFERS COMPLETED'
  1629.     DB CR,LF,BELL,0
  1630. donetca    lda    discflg        ;see if disconnect when thru
  1631.     ora    a
  1632.     jnz    donetce        ;no, don't disconnect
  1633. donetcb    call    ilprt
  1634.  
  1635.     db    cr,lf,'++PRESS RETURN TO DISCONNECT++',bell,cr,lf,0
  1636.  
  1637.     mvi    c,rdcon
  1638.     call    bdos        ;wait for response
  1639.     cpi    0dh        ;carriage return
  1640.     jnz    donetcb        ;nope
  1641.  
  1642.     call    ilprt
  1643.  
  1644.     db    cr,lf,'++DISCONNECTED++',cr,lf,0
  1645.  
  1646.     call    disconnt    ;hang-up the pmmi
  1647.     jmp    exit        ;go to CP/M
  1648.  
  1649. DONETCE    LDA TERMFLG        ;SEE IF RETURN TO..
  1650.     ORA A            ;..TERMINAL MODE..
  1651.     JNZ MENU        ;..AFTER X'FER.
  1652.     CALL CRLF
  1653.     JMP TERM
  1654.  
  1655. INITMOD
  1656. SETBAUD    LDA PMMIBYTE
  1657.     ORA A
  1658.     RZ
  1659.     LDA ANSWFLG    ;IF ANSWER OR ORIGINATE MODE..
  1660.     ORA A        ;..IS NOT REQUESTED OR NO..
  1661.     JNZ SKIPB1    ;..BAUDRATE SPECIFIED, THEN..
  1662.     CALL GETBAUD    ;..ROUTINE RETURNS WITH CHANGE..
  1663.     JMP FIXBAUD    ;..OF BAUD. IF OPT REQUESTED,..
  1664. SKIPB1    LDA ORIGFLG    ;..A BLANK FORCES 300 BAUD..
  1665.     ORA A        ;..ELSE A 0 FROM NEWBAUD..
  1666.     JNZ SKIPB2    ;..FORCES 300 BAUD.
  1667.     CALL GETBAUD
  1668.     JMP FIXBAUD
  1669. SKIPB2    LDA FCB+9
  1670.     CPI 0        ;IF ZERO, NEWBAUD WANTS 300
  1671.     JZ SKIPB3
  1672.     CPI ' '
  1673.     RZ
  1674.     JMP SKIPB4
  1675. SKIPB3    MVI A,' '    ;FORCE 300 BAUD
  1676.     STA FCB + 9
  1677. SKIPB4    CALL GETBAUD
  1678. FIXBAUD    CALL OUT$BAUDRP
  1679.     CPI 52
  1680.     MVI A,5FH
  1681.     JC GT300
  1682.     MVI A,7FH
  1683. GT300    CALL OUT$MODCTL2
  1684.  
  1685.     LDA ORIGFLG
  1686.     ORA A
  1687.     MVI A,ORIGMOD
  1688.     JZ OFFHOOK
  1689.     LDA ANSWFLG
  1690.     ORA A
  1691.     MVI A,ANSWMOD
  1692.     RNZ
  1693.  
  1694. OFFHOOK    LXI H,4000
  1695. OFFDLY    DCR L
  1696.     JNZ OFFDLY
  1697.     DCR H
  1698.     JNZ OFFDLY
  1699.     CALL OUT$MODCTLP
  1700.     RET
  1701.  
  1702. GETBAUD    LDA FCB+9
  1703.     CPI ' '
  1704.     MVI A,52
  1705.     RZ
  1706.     LDA FCB+9
  1707.     CPI 0
  1708.     MVI A,52
  1709.     RZ
  1710.  
  1711.     LXI D,FCB+9
  1712.     LXI H,0
  1713. DECLP    LDAX D
  1714.     INX D
  1715.     CPI ' '
  1716.     JZ DECLP
  1717.     CPI '0'
  1718.     JC BADRATE
  1719.     CPI '9'+1
  1720.     JNC BADRATE
  1721.     SUI '0'
  1722.  
  1723.     MOV B,H
  1724.     MOV C,L
  1725.     DAD H
  1726.     DAD H
  1727.     DAD B
  1728.     DAD H
  1729.     ADD L
  1730.     MOV L,A
  1731.     JNZ DIGNC
  1732.     INR H
  1733. DIGNC    MOV A,E
  1734.     CPI FCB+12
  1735.     JNZ DECLP
  1736.  
  1737.     MOV A,H
  1738.     CMA
  1739.     MOV D,A
  1740.     MOV A,L
  1741.     CMA
  1742.     MOV E,A
  1743.     INX D
  1744.     LXI H,15625
  1745.     LXI B,-1
  1746. DIVLP    INX B
  1747.     DAD D
  1748.     JC DIVLP
  1749.     MOV A,B
  1750.     ORA A
  1751.     MOV A,C
  1752.     RZ
  1753.  
  1754. BADRATE    CALL ERXIT
  1755.     DB '++    INVALID    BAUD RATE ++$'
  1756.  
  1757. MOVEFCB    LXI H,FCB+16
  1758.     LXI D,FCB
  1759.     MVI B,16
  1760.     CALL MOVE
  1761.     XRA A
  1762.     STA FCBSNO
  1763.     STA FCBEXT
  1764.     RET
  1765.  
  1766. SHOW    CPI LF
  1767.     JZ CTYPE
  1768.     CPI CR
  1769.     JZ CTYPE
  1770.     CPI 9
  1771.     JZ CTYPE
  1772.     CPI ' '
  1773.     JC SHOWHEX
  1774.     CPI 7FH
  1775.     JC CTYPE
  1776. SHOWHEX    PUSH PSW
  1777.     MVI A,'('
  1778.     CALL CTYPE
  1779.     POP PSW
  1780.     CALL HEXO
  1781.     MVI A,')'
  1782.     JMP CTYPE
  1783.  
  1784. CTYPE    PUSH B
  1785.     PUSH D
  1786.     PUSH H
  1787.     MOV E,A
  1788.     MVI C,WRCON
  1789.     CALL BDOS
  1790.     POP H
  1791.     POP D
  1792.     POP B
  1793.     RET
  1794.  
  1795. CRLF    PUSH PSW
  1796.     MVI A,CR
  1797.     CALL TYPE
  1798.     MVI A,LF
  1799.     CALL TYPE
  1800.     POP PSW
  1801.     RET
  1802.  
  1803. TYPE    PUSH PSW
  1804.     PUSH B
  1805.     PUSH D
  1806.     PUSH H
  1807.     MOV C,A
  1808. VTYPE    CALL $-$
  1809.     POP H
  1810.     POP D
  1811.     POP B
  1812.     POP PSW
  1813.     RET
  1814.  
  1815. STAT    PUSH B
  1816.     PUSH D
  1817.     PUSH H
  1818. VSTAT    CALL $-$
  1819.     POP H
  1820.     POP D
  1821.     POP B
  1822.     ORA A
  1823.     RET
  1824.  
  1825. KEYIN    PUSH B
  1826.     PUSH D
  1827.     PUSH H
  1828. VKEYIN    CALL $-$
  1829.     POP H
  1830.     POP D
  1831.     POP B
  1832.     RET
  1833.  
  1834. UCASE    CPI 61H        ;CHANGES LOWER CASE CHARACTER..
  1835.     RC        ;..IN A-REG TO UPPER CASE.
  1836.     CPI 7BH
  1837.     RNC
  1838.     ANI 5FH
  1839.     RET
  1840.  
  1841. HEXO    PUSH PSW
  1842.     RAR
  1843.     RAR
  1844.     RAR
  1845.     RAR
  1846.     CALL NIBBL
  1847.     POP PSW
  1848. NIBBL    ANI 0FH
  1849.     CPI 10
  1850.     JC ISNUM
  1851.     ADI 7
  1852. ISNUM    ADI '0'
  1853.     JMP TYPE
  1854.  
  1855. ;RETURNS W/ ZERO SET IF RETRY ASKED. IF MULTI-FILE MODE, THEN
  1856. ;NO QUESTIONS ASKED, JUST QUIT
  1857.  
  1858. CKQUIT    LDA BATCHFLG
  1859.     ORA A
  1860.     JNZ CKQTASK    ;ASK FOR RETRY
  1861.     INR A        ;RESET ZERO FLG
  1862.     RET
  1863. CKQTASK    XRA A
  1864.     STA ERRCT
  1865.     CALL ILPRT
  1866.         DB 'MULTIPLE ERRORS ENCOUNTERED.',CR,LF
  1867.         DB 'TYPE Q TO QUIT, R TO RETRY:  ',BELL,0
  1868.     CALL KEYIN
  1869.     PUSH PSW
  1870.     CALL CRLF
  1871.     POP PSW
  1872.     CALL UCASE    ;INSTEAD OF "ANI 5FH"
  1873.     CPI 'R'
  1874.     RZ
  1875.     CPI 'Q'
  1876.     JNZ CKQUIT
  1877.     ORA A
  1878.     RET
  1879.  
  1880. ILPRT    XTHL
  1881. ILPLP    MOV A,M
  1882.     ORA A
  1883.     JZ ILPRET
  1884.     CALL CTYPE
  1885.     INX H
  1886.     JMP ILPLP
  1887. ILPRET    XTHL
  1888.     RET
  1889.  
  1890. PRTMSG    MVI C,PRINT
  1891.     JMP BDOS
  1892.  
  1893. ERXIT    POP D
  1894.     CALL PRTMSG
  1895.     CALL ILPRT
  1896.     DB BELL,0
  1897.     LDA BATCHFLG
  1898.     ORA A
  1899.     JNZ DONETCE
  1900.     MVI A,'Q'        ;RESET QFLG
  1901.     STA QFLG
  1902.     JMP ABORT        ;ABORT OTHER COMPUTER
  1903.  
  1904. EXIT    LXI D,80H
  1905.     MVI C,STDMA
  1906.     CALL BDOS
  1907.     JMP 0
  1908.  
  1909. MOVE128    MVI B,128
  1910. MOVE    MOV A,M
  1911.     STAX D
  1912.     INX H
  1913.     INX D
  1914.     DCR B
  1915.     JNZ MOVE
  1916.     RET
  1917.  
  1918. ;DIALING ROUTINES TAKEN (AND GREATLY MODIFIED) FROM PMMI MANUAL.
  1919.  
  1920. ;MODEM CONTROL COMMAND WORDS
  1921.  
  1922. CLEAR    EQU 3FH        ;IDLE MODE
  1923. MAKEM    EQU 1        ;TELE LINE MAKE (OFF HOOK)
  1924. BRKM    EQU 0        ;TELE LINE ON HOOK (BREAK DURING DIALING)
  1925. DTMSK    EQU 1        ;DIAL TONE MASK
  1926. TMPUL    EQU 80H        ;TIMER PULSES MASK BIT
  1927. TRATE    EQU 250        ;VALUE FOR 0.1 SECOND
  1928.  
  1929.  
  1930. DIALPL    LDA    PMMIBYTE    ;FLAG FOR PMMI OPERATION
  1931.     ORA    A        ;SET FLAGS
  1932.     RZ            ;PMMI FALSE, RETURN
  1933. 7    XRA    A        ; 0
  1934. 7    STA    CRFLAG        ;CONTINUOUS REDIAL FLAG
  1935.     CALL    DIALPL0        ; DISCONNECT, RECONNECT, WAIT DIAL TONE
  1936. 7    JC    DILAGN        ;ASK IF TRY AGAIN
  1937. 7    LXI    H,CMDBUF+1    ;POINT # OF CHARS IN BUFF
  1938. 7    MOV    A,M        ;GET # OF CHARS
  1939. 7    CPI    4        ;4 OR MORE CHARS TYPED BEFORE <CR>?
  1940. 7    JC    ENTNUM        ;NO, ASK FOR NUMBER
  1941. 7    LXI    H,CMDBUF+5    ;POINT TO NUMBER TO DIAL
  1942. 7    JMP    DIAL10        ;CHECK IF LIB #, & DIAL
  1943.  
  1944. DIALPL0    CALL DISCONNT
  1945.     CALL ILPRT
  1946.         DB CR,LF,'WAITING FOR DIAL TONE',CR,LF,0
  1947.  
  1948.     MVI A,MAKEM    ;MAKE MAKE (OFF-HOOK)
  1949.     CALL OUT$MODCTLP;DO IT
  1950.     MVI D,DTMSK    ;DIAL TONE MASK
  1951.     MVI C,100    ;10 SECOND WAIT
  1952.     CALL WAIT    ;WAIT FOR DIAL TONE
  1953. 7    NOP        ;DELAY
  1954.  
  1955. ; WAIT SUBROUTINE WILL RETURN WITH CARRY SET IF UNABLE TO
  1956. ; GET DIALTONE, ELSE CARRY NOT SET MEANS DIALTONE RECEIVED
  1957.  
  1958.     RNC        ;IF DIAL TONE WITHIN 10 SECONDS
  1959.     CALL ILPRT    ;ELSE, MESSAGE AND RETURN WITH CARRY SET
  1960.     DB CR,LF
  1961.     DB '++NO DIAL TONE AFTER 10 SECONDS++',CR,LF,0
  1962.     STC
  1963.     RET
  1964.  
  1965. ENTNUM:    ;this is all the set-up for the print at entnum2.
  1966.  
  1967. 7    mvi    c,13        ;number of lines to move
  1968. 7    lxi    h,numblib    ;address of source memory
  1969. 7    lxi    d,dbuf        ;address of target memory
  1970. 7    call    newline        ;start with CRLF
  1971. 7    stax    d        ;+LF
  1972. 7    inx    d        ;and bump it
  1973.  
  1974. entnum1:
  1975. 7    mvi    b,30        ;number of bytes to move
  1976. 7    call    move        ;move to buffer
  1977. 7    call    spaces        ;2 entries + 3 spaces = 63 characters
  1978. 7    mvi    b,30
  1979. 7    call    move
  1980. 7    call    newline
  1981. 7    dcr    c        ;number of lines to print
  1982. 7    jz    entnum2
  1983. 7    jmp    entnum1
  1984.  
  1985. newline:            ;puts CR-LF at memory pointed by DE
  1986. 7    mvi    a,cr        ;CR
  1987. 7    stax    d        ;store it
  1988. 7    mvi    a,lf        ;LF
  1989. 7    inx    d        ;bump pointer
  1990. 7    stax    d        ;store LF
  1991. 7    inx    d        ;bump pointer
  1992. 7    ret
  1993.  
  1994. spaces:
  1995. 7    mvi    a,20H        ;space
  1996. 7    stax d ! inx d        ; 1
  1997. 7    stax d ! inx d        ; 2
  1998. 7    stax d ! inx d        ; 3
  1999. 7    ret
  2000.  
  2001. entnum2:
  2002.     mvi    a,'$'
  2003.     stax    d
  2004.     mvi    c,print
  2005.     lxi    d,dbuf    ;point to table of numbers to print
  2006.     call    bdos
  2007.     call    crlf
  2008.  
  2009.     CALL ILPRT
  2010.     DB 'ENTER NUMBER OR LIBRARY LETTER - TYPE C/R WHEN FINISHED,',CR,LF
  2011.     DB 'CTRL-X CANCELS WHILE DIALING:        ',0
  2012.  
  2013.     LXI D,CMDBUF
  2014.     CALL INBUFF
  2015.  
  2016. DIALLP1    LDA CMDBUF+1
  2017.     ORA A            ;NULL MEANS <CR> WAS TYPED
  2018.     JZ BORTIT        ;ABORT DIALING, RETURN TO MENU
  2019.  
  2020.     LXI    H,CMDBUF+2    ;FIRST TYPED CHAR OF NUMBER TO DIAL
  2021. 7 ;
  2022. 7 ; ENTER THIS ROUTINE WITH HL POINTING TO NUMBER TO DIAL
  2023. 7 ;
  2024. DIAL10:
  2025. 7    MVI    B,'A'        ;FIRST LETTER OF ALPHABET
  2026. 7    MVI    E,0        ;COUNTS NUMBER OF LETTERS TO MATCH
  2027. 7    MVI    C,26        ;NUMBER OF LETTERS IN ALPHABET
  2028. 7    MOV    A,M        ;GET CHAR BUFFER
  2029. DIAL11:
  2030. 7    CMP    B        ;NUMBER FROM TABLE?
  2031. 7    JZ    LIBSET
  2032. 7    INR    B        ;MAKE NEXT LETTER (A-Z)
  2033. 7    INR    E        ;COUNT UP
  2034.     DCR    C        ;COUNT DOWN
  2035. 7    JZ    DIALLPX        ;NOT A LETTER
  2036. 7    JMP    DIAL11        ;LOOP
  2037.  
  2038. LIBSET:
  2039. 7    LXI    H,NUMBLIB    ;PHONE NUMBER LIBRARY
  2040. 7    LXI    B,30        ;LENGTH OF LIBRARY ENTRY
  2041. 7    MOV    A,E        ;NUMBER OF TIMES TO ADD 30 TO HL
  2042. 7    ORA    A        ;SET FLAGS
  2043. 7    JZ    DIAL13
  2044.  
  2045. DIAL12:
  2046. 7    MOV    A,M        ;GET FIRST CHAR OF SELECTED LIB ENTRY
  2047. 7    ORA    A        ;SET FLAGS
  2048. 7    JZ    DIALLP2        ;SEND BADLIB MSG
  2049. 7    DAD    B        ;INCREMENT HL BY 30
  2050. 7    DCR    E        ;COUNTDOWN
  2051. 7    JNZ    DIAL12        ;NOT THERE YET, LOOP
  2052.  
  2053. DIAL13:
  2054. 7    MVI    E,30        ;NUMBER OF CHARACTERS TO GET FROM TABLE
  2055. 7    JMP    DIALLP2
  2056.  
  2057. DIALLPX    LDA CMDBUF+1
  2058.     MOV E,A            ;NUMBER OF CHARS IN BUFF
  2059.     LXI H,CMDBUF+2        ;POINT FIRST CHAR
  2060.  
  2061. DIALLP2    MOV A,M            ;GET FIRST # FROM BUFFER
  2062. 7 ;
  2063. 7 ; ROUTINE TO PRINT 'BADLIB' MESSAGE AND ABORT IF NULL ENCOUNTERED
  2064. 7 ;
  2065. 7    ORA    A        ;SET FLAGS
  2066. 7    PUSH    D        ;SAVE DE REGISTERS
  2067. 7    LXI    D,BADLIB    ;BAD LIBRARY NUMBER IF NULL
  2068. 7    MVI    C,PRINT        ; 9
  2069. 7    PUSH    PSW        ;SAVE A AND FLAGS
  2070. 7    CZ    BDOS
  2071. 7    POP    PSW        ;RESTORE A AND FLAGS
  2072. 7    POP    D        ;RESTORE DE REGISTERS
  2073. 7    JZ    BORTIT        ;ABORT
  2074. ;
  2075. ; DIAL A DIGIT, CHECK KBD FOR ABORT
  2076. ;
  2077.     CALL DIAL        ;DIAL IT
  2078.     CALL STAT        ; KEYPRESS?
  2079.     ORA A            ;SET FLAGS
  2080.     CNZ KEYIN        ;YES, GO GET IT
  2081.     CPI CAN            ; ^X?
  2082.     JZ BORTIT        ;YES, ABORT
  2083.     INX H            ;BUMP POINTER
  2084.     PUSH D            ;SAVE DE
  2085.     PUSH H            ;SAVE HL
  2086.     MVI B,1            ;WAIT 1 TIME INTERVAL
  2087.     CALL TIMER
  2088.     POP H            ;RESTORE HL
  2089.     POP D            ;RESTORE DE
  2090.     DCR E            ;COUNT DOWN CHARS IN BUFF
  2091.     JNZ DIALLP2        ;NOT DONE, LOOP
  2092.     JZ DIALDN        ;DIALING DONE
  2093.  
  2094. DISCONNT
  2095.     XRA A            ;0
  2096.     CALL OUT$MODCTL2    ;CLEAR DAV, ESD, ETC
  2097.     CALL OUT$MODCTLP    ;HANG-UP
  2098.     PUSH B
  2099.     MVI B,8            ;wait for PMMI to disconnect
  2100.     CALL TIMER
  2101.     POP B
  2102.     RET
  2103.  
  2104. TIMER    MVI A,TRATE    ;TRATE 250, VALUE FOR .1 SEC INTERVAL
  2105.     CALL OUT$BAUDRP    ;B-REG CONTAINS NUMBER OF .1 SEC INTERVALS
  2106. TIMES    CALL IN$BAUDRP    ;TO COUNT
  2107.     ANI TMPUL
  2108.     JZ TIMES    ;WAIT FOR TIMER TO GO HIGH
  2109. TIMEE    CALL IN$BAUDRP
  2110.     ANI TMPUL
  2111.     JNZ TIMEE    ;WAIT FOR TIMER TO GO LOW
  2112.     DCR B
  2113.     JNZ TIMES
  2114.     RET
  2115.  
  2116. BORTIT    CALL DISCONNT
  2117.     JMP MENU
  2118.  
  2119. ;AUTO DIALER
  2120.  
  2121. DIAL    CALL    TYPE    ;PRINT WHATEVER CHARACTER, DASHES, ETC.
  2122.     CPI 30H
  2123.     RC        ;DIGIT MUST BE AT LEAST 0..
  2124.     CPI 3AH
  2125.     RNC        ;..AND NOT MORE THAN 9
  2126.     ANI 0FH        ;STRIP ASCII -- COULD ALSO DO SUI 30H ('0')
  2127.     CPI 0
  2128.     JNZ DIALS
  2129.     MVI A,10    ;CONVERT ZERO TO 10 PULSES
  2130. DIALS    MOV C,A
  2131.     LDA PULSERATE    ;CONTAINS VALUE FOR DIAL SPEED
  2132.     CALL OUT$BAUDRP
  2133. DIALC    CALL IN$BAUDRP
  2134.     ANI TMPUL
  2135.     JNZ DIALC
  2136. DIALB    CALL IN$BAUDRP
  2137.     ANI TMPUL
  2138.     JZ DIALB
  2139. MAKEP    MVI A,MAKEM
  2140.     CALL OUT$MODCTLP
  2141. TIMEM    CALL IN$BAUDRP
  2142.     ANI TMPUL
  2143.     JNZ TIMEM
  2144.     MVI A,BRKM
  2145.     CALL OUT$MODCTLP
  2146. TIMEB    CALL IN$BAUDRP
  2147.     ANI TMPUL
  2148.     JZ TIMEB
  2149.     DCR C
  2150.     JNZ MAKEP
  2151.     MVI A,MAKEM
  2152.     CALL OUT$MODCTLP
  2153.     MVI B,2
  2154.     CALL TIMER
  2155.     RET
  2156.  
  2157. ;TIME OUT ROUTINE. MUST BE CALLED WITH MASK IN D REG FOR INPUT
  2158. ;AT RELATIVE PORT 2 AND NUMBER OF SECONDS * 10 IN C REG.
  2159.  
  2160. WAIT    MVI B,1    
  2161.     CALL TIMER    ;WAIT FOR TIMER TO GO HIGH THEN LOW
  2162.     CALL IN$BAUDRP    ;PMMIADDR+2 (MODEM STATUS PORT)
  2163.     ANA D        ;(CTS or DIALTONE MASK)
  2164.     RZ        ;ACTIVE LOW, SO RETURN ON 0
  2165.  
  2166. 7      PUSH B    ;SAVE..
  2167. 7      PUSH D    ;..ACTIVE REG'S
  2168. 7      CALL STAT    ;KEYPRESS?
  2169. 7      ORA A        ;SET FLAGS
  2170. 7      CNZ KEYIN    ;YES, GET CHAR
  2171. 7      CPI CAN    ;^X?
  2172. 7      JZ WAIT1    ;YES, DISCONNECT, JMP TO MENU
  2173. 7      POP D        ;RESTORE..
  2174. 7      POP B        ;..REGS
  2175.  
  2176.     DCR C        ;COUNT-DOWN
  2177.     JNZ WAIT
  2178.     STC        ;SET CARRY TO INDICATE MASK NOT SET
  2179.     RET
  2180.  
  2181. WAIT1:
  2182. 7    POP D        ;RESET..
  2183. 7    POP B        ;..STACK
  2184. 7    JMP DISCON1    ;DISCONNECT
  2185.  
  2186. HANGP    MVI A,CLEAR
  2187.     CALL OUT$MODCTL2
  2188.     MVI A,0
  2189.     CALL OUT$MODCTLP
  2190.     RET
  2191.  
  2192. DIALDN    CALL CRLF
  2193.     MVI A,07FH        ;TURN ON DTR
  2194.     CALL OUT$MODCTL2    ;TIMER RATE?
  2195.  
  2196.     MVI B,1
  2197.     CALL TIMER    ;WAIT FOR MODEM TO TURN ON DTR
  2198.  
  2199.     MVI A,5DH    ;2 STOP BITS, NO PARITY, 8 DATA BITS
  2200.             ;+ NO DISCONNECT AFTER 17 SECS
  2201.     CALL OUT$MODCTLP
  2202.  
  2203.     MVI D,4        ;CLEAR TO SEND MASK
  2204.     MVI C,waitcts    ;wait time for cts (25.5 SEC MAX)
  2205.     CALL WAIT
  2206.  
  2207.     JNC CONMADE    ;CONNECTION MADE
  2208.  
  2209.     CALL DISCONNT
  2210. DILAGN:
  2211. 7    LDA CRFLAG    ;CONTINUOUS REDIAL FLAG
  2212. 7    ORA A
  2213. 7    JNZ DILAGN0
  2214.     CALL ILPRT
  2215.     DB CR,LF,'No answer after time-out.  Redial? (Y/N/C): ',BELL,0
  2216.  
  2217.     CALL KEYIN    ;GET RESPONSE
  2218.     CALL TYPE    ;ECHO IT
  2219.     CALL UCASE    ;ANI 5FH
  2220.     CALL CRLF    ;NEW LINE
  2221.     CPI 'N'        ;REDIAL?
  2222.     JZ MENU        ;NO, GO MENU
  2223.     CPI 'Y'        ;REDIAL?
  2224.     JZ DILAGN0    ;YES, REDIAL
  2225. 7    CPI 'C'        ;CONTINUOUS REDIAL?
  2226. 7    JNZ DILAGN    ;INVALID RESPONSE, ASK AGAIN
  2227. 7    XRA A ! CMA    ;0FFH
  2228. 7    STA CRFLAG    ;CONTINUOUS REDIAL FLAG
  2229. 7 DILAGN0:
  2230. 7    mvi b,50    ;5 seconds wait for pmmi reset
  2231. 7    call timer    ;else busy tone may be sensed as dialtone
  2232.     CALL DIALPL0    ;WAIT FOR DIAL TONE
  2233.     JNC DIALLP1    ;DIAL NUMBER
  2234. 7    JMP DILAGN    ;NO DIAL TONE AFTER 10 SECS
  2235.  
  2236. CONMADE    CALL ILPRT
  2237.         DB CR,LF,'Connection established - Select options: ',BELL,0
  2238. DILAGN1
  2239. 7    CALL STAT    ;KEYPRESS?
  2240. 7    ORA A        ;SET FLAGS
  2241. 7    JNZ GETCMD    ;KEY PRESSED, GO GET OPTIONS
  2242. 7    MVI A,BELL
  2243. 7    CALL TYPE    ;RING BELL
  2244. 7    JMP DILAGN1    ;LOOP
  2245.  
  2246.  
  2247. ;INITIALIZES CP/M FILE CONTROL BLOCKS AT 5CH AND 6CH
  2248.  
  2249. SETFCB    LXI D,CMDBUF
  2250.     LXI H,FCB
  2251.     CALL CPMLINE
  2252.     CALL PROCOPT
  2253.  
  2254. CHECKNM    LDA FCB+1    ;CHECK ON THE PRIMARY OPTION
  2255.     CPI 'E'        ;RETURN IF ECHO OPTION
  2256.     RZ
  2257.     CPI 'M'        ;RETURN TO MENU
  2258.     RZ
  2259.     MOV B,A
  2260.     LDA PMMIBYTE
  2261.     ORA A
  2262.     MOV A,B
  2263.     JZ S4
  2264.     CPI 'C'
  2265.     RZ
  2266. S4    CPI 'T'
  2267.     JZ TERMSEL
  2268.     CPI 'S'
  2269.     JZ CKFILE
  2270.     CPI 'R'
  2271.     JNZ BDOPT
  2272.     LDA BATCHFLG    ;IF MULT FILE MODE, THEN..
  2273.     ORA A        ;..RECV OPT DOES NOT NEED..
  2274.     RZ        ;..NAME.
  2275.     JMP CKFILE
  2276. BDOPT    CALL ILPRT
  2277.     DB CR,LF,'++Bad Option++',CR,LF,0
  2278.     JMP REENT
  2279. CKFILE    LDA FCB+17    ;IF OPTION THAT NEEDS FILE NAME,..
  2280.     CPI ' '        ;..THEN CHECK TO SEE IF NAME..
  2281.     RNZ        ;..EXISTS. IF NOT..
  2282. REENT    CALL ILPRT    ;..DO EVERYTHING OVER.
  2283.         DB CR,LF,'Re-enter PRIMARY option and file name only: ',BELL,0
  2284.     LXI D,CMDBUF
  2285.     CALL INBUFF
  2286.     JMP SETFCB
  2287.  
  2288. TERMSEL    LDA FCB+17
  2289.     CPI ' '
  2290.     JNZ SAVAGN
  2291.     MVI A,FALSE
  2292.     STA SAVEFLG
  2293.     MVI A,TRUE
  2294.     STA NFILFLG
  2295.     CMA
  2296.     OUT FRONTPAN
  2297.     RET
  2298. SAVAGN    MVI A,FALSE
  2299.     STA NFILFLG
  2300.     RET
  2301.  
  2302. NEWBAUD    LDA PMMIBYTE
  2303.     ORA A
  2304.     RZ
  2305.     CALL ILPRT
  2306.     DB 'Enter New Baudrate: ',0
  2307.     LXI H,FCB+9
  2308.     MVI M,0        ;PUTS A ZERO IN FIRST POSITION SO AS TO
  2309. LOOP5    CALL KEYIN    ;FORCE THE DEFAULT OPTION OF 300 BAUD.
  2310.     CPI CR        ;CARRIAGE RET ENTERS BAUD RATE
  2311.     JNZ CONNEWB    ;GOES TO THE ESTABLISHED ROUTINE - RETURN TO MAIN
  2312.     CALL CRLF    ;PROGRAM IS DONE THERE.
  2313.     JMP SETBAUD
  2314. CONNEWB    CPI 30H        ;MAKE SURE IT'S..
  2315.     JC LOOP5    ;..A DIGIT, ELSE..
  2316.     CPI 3AH        ;..DON'T ACCEPT IT.
  2317.     JNC LOOP5
  2318.     MOV M,A
  2319.     MOV C,A
  2320.     CALL TYPE    ;ECHO THE CHARACTER ENTERED
  2321.     INX H
  2322.     JMP LOOP5
  2323.  
  2324. MENU    LXI H,RESTSN        ;RESTORE SECTORE NUMBERS..
  2325.     LXI D,SECTNOB        ;..FOR NEW FILE TRANSFER.
  2326.     MVI B,SECTNOE-SECTNOB
  2327.     CALL MOVE
  2328.     LXI H,RESTROPT        ;RESTORE OPTION TABLE
  2329.     LXI D,OPTBL
  2330.     MVI B,OPTBE-OPTBL
  2331.     CALL MOVE
  2332.     MVI A,0
  2333.     STA MFFLG1        ;RESET MFACCESS ROUTINE..
  2334.     CMA            ;..AND MULTI TRANS IN CASE..
  2335.     STA FSTFLG        ;..OF ABORT.
  2336.  
  2337. MENU1    LDA XPRFLG        ;TEST IF MENU SHOULD BE SHOWN
  2338.     ORA A
  2339.     JNZ XPRT
  2340.     CALL ILPRT
  2341.     DB CR,LF,CR,LF
  2342.     DB 'WRT   - Write file to disk (from terminal mode)',CR,LF
  2343.     DB 'DEL   - Erase present file (from terminal mode)',CR,LF
  2344.     DB 'RET   - Return to terminal mode with no loss of data',CR,LF,0
  2345.     LDA PMMIBYTE
  2346.     ORA A
  2347.     JZ S5
  2348.     CALL ILPRT
  2349.     DB 'DSC   - Disconnect',CR,LF
  2350.     DB 'CAL   - Dial number',CR,LF,0
  2351. S5    CALL ILPRT
  2352.     DB 'XPR   - Toggle expert mode (Menu on/off)',CR,LF
  2353.     DB 'DIR   - List directory (may specify drive)',CR,LF
  2354.     DB 'CPM   - Exit to CP/M',CR,LF
  2355.     DB 'S     - Send CP/M file',CR,LF
  2356.     DB 'R     - Receive CP/M file',CR,LF
  2357.     DB 'T     - Terminal mode (optional file name)',CR,LF
  2358.     DB 'E     - Terminal mode with echo',CR,LF,0
  2359. XPRT    CALL ILPRT
  2360.     DB CR,LF,CR,LF,'DEFAULT DRIVE: ',0
  2361.     MVI C,25    ;CURRENT DISK FUNCTION
  2362.     CALL BDOS
  2363.     ADI 41H        ;MAKE ASCII
  2364.     CALL TYPE
  2365.     CALL ILPRT
  2366.     DB CR,LF,CR,LF,'Command: '
  2367.     DB 0
  2368.  
  2369. GETCMD    LXI D,CMDBUF        ;ENTER COMMAND
  2370.     CALL INBUFF
  2371.     CALL CRLF
  2372.     LXI D,CMDBUF+2        ;POINT TO COMMAND
  2373.     CALL ILCOMP
  2374.     DB 'CPM',0
  2375.     JNC EXIT
  2376.     CALL ILCOMP
  2377.     DB 'DIR',0
  2378.     JNC DIR
  2379.     CALL ILCOMP
  2380.     DB 'RET',0
  2381.     JC NXTOPT1        ;CARRY SET = NO MATCH
  2382.     LHLD HLSAVE        ;RETURN TO TERMINAL..
  2383.     JMP TERM        ;..MODE WITH SAVE OPTION..
  2384.                 ;..IF PREVIOUSLY ENABLED.
  2385. NXTOPT1
  2386.     LDA PMMIBYTE
  2387.     ORA A
  2388.     JZ S6
  2389.     CALL ILCOMP        ;DE SET FROM 1ST ILCOMP CALL
  2390.     DB 'DSC',0
  2391.     JNC DISCON1
  2392. S6    CALL ILCOMP
  2393.     DB 'WRT',0
  2394.     JNC WRTFIL
  2395.     CALL ILCOMP
  2396.     DB 'XPR',0
  2397.     JNC XPRMODE
  2398.     CALL ILCOMP
  2399.     DB 'DEL',0
  2400.     JNC NEWFILE
  2401.     LDA PMMIBYTE
  2402.     ORA A
  2403.     JZ NXTOPT2
  2404.     CALL ILCOMP
  2405.     DB 'CAL',0
  2406.     JC NXTOPT2
  2407.     MVI A,1            ;FORCE 1 IN CHAR COUNT OF..
  2408.     STA CMDBUF+1        ;..CMDBUF SO THAT IT ONLY..
  2409.     JMP DOOPT        ;..LOOKS AT 'C' FOR DIAL
  2410.  
  2411. NXTOPT2 PUSH H
  2412.     LDA CMDBUF+2
  2413.     LXI H,COMPLIST
  2414.     CALL COMPARE        ;COMPARES LIST POINTED TO BY HL..
  2415.     POP H            ;..TO CHAR IN A-REG.
  2416.     JC MENU1        ;CARRY SET = NO MATCH
  2417.  
  2418. DOOPT    PUSH H            ;LOAD ORIGINAL FCB WITH TRANSFER..
  2419.     CALL SETFCB        ;..CMDS AND GO TO BEGINNING OF..
  2420.     POP H            ;..PROGRAM. WILL FOLLOW SAME LOGIC..
  2421.     JMP RESTART        ;..AS IF PROGRAM WERE CALLED WITH..
  2422.                 ;..CP/M COMMAND LINE.
  2423.  
  2424. DISCON1    LDA PMMIBYTE
  2425.     ORA A
  2426.     JZ MENU
  2427.     CALL DISCONNT
  2428.     CALL ILPRT
  2429.     DB CR,LF,'++DISCONNECTED++',CR,LF,BELL,0
  2430.     JMP MENU1
  2431.  
  2432. DIR    CALL DIRLST
  2433.     JMP XPRT
  2434.  
  2435. NEWFILE    LDA FCB3+1
  2436.     CPI ' '
  2437.     JZ MENU1    ;IF NO FILE, DON'T ERASE
  2438.     LXI D,FCB3
  2439.     MVI C,ERASE
  2440.     CALL BDOSRT
  2441.     MVI A,TRUE    ;DO NOT ALLOW TERMINAL..
  2442.     STA NFILFLG    ;..SAVE SINCE NO FILE..
  2443.     CMA        ;..SPECIFIED.
  2444.     STA SAVEFLG
  2445.     OUT FRONTPAN
  2446.     LXI H,FCB3
  2447.     CALL INITFCBS
  2448.     JMP MENU1
  2449.  
  2450. WRTFIL    LDA NFILFLG
  2451.     CPI TRUE
  2452.     JZ MENU1
  2453.     LDA FCB3+1    ;CHECK THAT FILE WAS REQUESTED
  2454.     CPI ' '
  2455.     JZ MENU1
  2456.     LHLD HLSAVE
  2457.     CALL NUMRECS    ;DISK WRITE ROUTINE AS USED IN..
  2458.     CALL WRTDSK    ;..IN THE INTDSKSV ROUTINE.
  2459.     CALL CLOSE3
  2460.     MVI A,TRUE
  2461.     STA NFILFLG
  2462.     CMA
  2463.     STA SAVEFLG
  2464.     OUT FRONTPAN
  2465.     LXI H,FCB3
  2466.     CALL INITFCBS    ;BLANK OUT FCB SO WRITTEN FILE..
  2467.     JMP MENU1    ;..CAN'T BE ERASED.
  2468.  
  2469. XPRMODE    LDA XPRFLG
  2470.     CMA
  2471.     STA XPRFLG
  2472.     JMP MENU1
  2473.  
  2474.  
  2475. COMPARE    MOV B,M            ;COMPARES A-REG WITH LIST..
  2476. COMPLP    INX H            ;..ADDRESSED BY HL. FIRST ELEMENT..
  2477.     CMP M            ;..OF LIST MUST BE NUMBER OF ELEMENTS..
  2478.     JZ VALID        ;..BEING COMPARED. RETURNS WITH..
  2479.     DCR B            ;..CARRY SET IF A-REG DOES NOT..
  2480.     JNZ COMPLP        ;.. CONTAIN AN ELEMENT IN LIST.
  2481.     STC
  2482. VALID    RET
  2483.  
  2484. COMPLIST DB 4, 'S', 'R', 'T', 'E'
  2485.  
  2486. ILCOMP    INLNCOMP    ;A MACRO IN MACROS.LIB
  2487.  
  2488.  
  2489. INBUFF    INBUF        ;A MACRO IN "MACROS.LIB"
  2490.  
  2491. ;IF ABOVE ROUTINE DOES NOT LET YOU EDIT IN A PROPER MANNER,
  2492. ;THEN THE MACRO MAY BE SUBSTITUTED FOR THE FOLLOWING ROUTINE:
  2493.  
  2494. ;INBUFF    MVI C,RDBUF
  2495. ;    CALL BDOSRT
  2496. ;    RET        ;BUT BE CAREFUL OF CONTROL-C
  2497.  
  2498.  
  2499. CPMLINE    CMDLINE        ;A MACRO IN "MACROS.LIB"
  2500.  
  2501. DIRLST    DIRLIST        ;A MACRO IN "MACROS.LIB"
  2502.  
  2503. NFILFLG    DB FALSE    ;NORMALLY SET TO FALSE. ALLOWS WRITE TO..
  2504.             ;..MEMORY IN TERMINAL MODE.
  2505.  
  2506. OPTION    DB 0
  2507.  
  2508. OPTBL    EQU $
  2509. ANSWFLG    DB 'A'
  2510. DISCFLG    DB 'D'
  2511. ORIGFLG    DB 'O'
  2512. QFLG    DB 'Q'
  2513. RSEEFLG    DB 'R'
  2514. SSEEFLG    DB 'S'
  2515. VSEEFLG    DB 'V'
  2516. TERMFLG DB 'T'
  2517. BATCHFLG DS 1    ;SET TO 'B' BY MENU. DOES NOT ALLOW MULTI-..
  2518. OPTBE    EQU $    ;..FILE XFER WHEN PROGRAM INITIALLY CALLED.
  2519.  
  2520. RESTROPT    ;MUST BE IN SAME ORDER AS TABLE ABOVE
  2521.  
  2522.     DB 'A','D','O','Q','R','S','V','T','B'
  2523.  
  2524. RESTSN    DB 0,0,0,0
  2525.     DW DBUF
  2526.     DB 0
  2527.     DB 0
  2528.  
  2529. SECTNOB    EQU $
  2530. RCVSNO    DB 0
  2531. SECTNO    DB 0
  2532. ERRCT    DB 0
  2533. EOFLG    DB 0
  2534. SECPTR    DW DBUF
  2535. SECINBF    DB 0
  2536. DATAFLG    DB 0
  2537. SECTNOE    EQU $
  2538.  
  2539. BADOPT    CALL ILPRT
  2540.     DB 'INVALID OPTION',CR,LF,BELL,0
  2541.     JMP MENU
  2542.  
  2543. FSTFLG    DB TRUE
  2544.  
  2545. CMDBUF    DB 80H,0
  2546.     DS 80H
  2547. BADLIB    DB    CR,LF,'++BAD LIBRARY NUMBER CALLED++',CR,LF,'$'
  2548. HLSAVE    DS 2
  2549. DISKNO    DS 1
  2550. SENDFLG    DS 1
  2551. NBSAVE    DS 2
  2552. BGNMS    DS 2
  2553. FILECT    DS 1
  2554. NAMECT    DS 1
  2555.  
  2556.     DS 40
  2557. STACK    DS 2
  2558. FCB3    DS 33
  2559. FCBBUF    DS 15
  2560. DBUF    DS 16*128    ;16 SECTOR DISK BUFFER
  2561. NAMEBUF    DS 1        ;BUFFER FOR NAMES IN BATCH MODE. OVERFLOWS..
  2562.             ;..ABOVE PROGRAM CODE.
  2563. ;    BDOS EQUATES
  2564.  
  2565. RDCON    EQU 1
  2566. WRCON    EQU 2
  2567. PRINT    EQU 9
  2568. RDBUF    EQU 10
  2569. CONST    EQU 11
  2570. OPEN    EQU 15
  2571. CLOSE    EQU 16
  2572. SRCHF    EQU 17
  2573. SRCHN    EQU 18
  2574. ERASE    EQU 19
  2575. READ    EQU 20
  2576. WRITE    EQU 21
  2577. MAKE    EQU 22
  2578. REN    EQU 23
  2579. STDMA    EQU 26
  2580. BDOS    EQU 5
  2581. REIPL    EQU 0
  2582. FCB    EQU 5CH
  2583. FCBEXT    EQU FCB+12
  2584. FCBSNO    EQU FCB+32
  2585. FCBRNO    EQU FCB+32
  2586. FCB2    EQU 6CH
  2587.  
  2588. LAST    END 100H
  2589.