home *** CD-ROM | disk | FTP | other *** search
/ ftp.barnyard.co.uk / 2015.02.ftp.barnyard.co.uk.tar / ftp.barnyard.co.uk / cpm / walnut-creek-CDROM / BEEHIVE / COMMS / HAMMODEM.ARC / HAMMODEM.ASM next >
Assembly Source File  |  1988-08-07  |  51KB  |  2,589 lines

  1.     TITLE    'HAM MODEM PROGRAM Version 1.0, 20 Feb 82'
  2. ;
  3. ;A CP/M file transfer program for simplex operation on Amateur Radio bands.
  4. ;Adapted from MODEM74.ASM by Phil Cary, W5TYF and Ken Shutt, K5GUU.
  5. ;
  6. ;CP/M MACRO (MAC) assembler required along with MODEM7.LIB
  7. ;
  8. ;Will asemble as is to run on a North Star with the modem on the right
  9. ;serial port.  Conditional equates to use features of the Heath/Zenith H-19
  10. ;terminal if h19term is set to true.
  11. ;
  12. ;May be patched under DDT or SID for other port assignments. Value of "timer"
  13. ;may be changed to accomodate different transmitter and receiver recovery
  14. ;characteristics, and call sign for CWID may be entered. See HAMMODEM.SET and
  15. ;HAMMODEM.DOC.
  16. ;
  17. ;HAMMODEM is adapted from MODEM74 for use in a simplex mode on
  18. ;the Amateur radio bands.  It has been used by the authors on 2 meter
  19. ;FM, both direct and through repeaters, at 1200 baud for several months.
  20. ;No testing has been done on SSB on the low bands, but it should work
  21. ;at the appropriate baud rates as long as there is little or no QRM.
  22. ;
  23. ;A simple modem must be interfaced to the ham rig.  A schematic and
  24. ;parts list for a modem using the EXAR 2211 and 2206 chips is available
  25. ;upon receipt of a s.a.s.e. to either of the following:
  26. ;
  27. ;    Phil Cary, W5TYF        Ken Shutt, K5GUU
  28. ;    748 Kenilworth Parkway        12433 Archery Drive
  29. ;    Baton Rouge, LA 70808        Baton Rouge, LA 70815
  30. ;    (504) 766-5255            (504) 275-0330
  31. ;
  32. ;No audio filtering has been needed in 2 meter operation, but probably
  33. ;would be required for SSB use.
  34. ;
  35. ;MODEM.ASM was originally created by Ward Christensen, with numerous
  36. ;revisions by Mark Zeigler, Jim Mills and others.  MODEM74.ASM was the
  37. ;basis for this version of HAMMODEM.  The CWID routines were borrowed
  38. ;from PACKET by Dale Heatherington, WA4DSY, Decatur, GA.
  39. ;
  40. ;We believe that all of the routines in MODEM74 and PACKET have at one time
  41. ;or the other been copyrighted and/or placed in the public domain for non-
  42. ;commercial use only.  The routines may be used but not sold by others.
  43. ;All new and changed code in HAMMODEM .ASM is in lower case.
  44. ;
  45. ;All of the features of MODEM74 such as batch mode, blind send, etc. have
  46. ;been retained.  All routines associated with the PMMI modem have been
  47. ;removed to conserve space.  All IMSAI and FRONTPANEL code has been
  48. ;removed.  The CRC method of error checking is used during file transfer
  49. ;and the CHECKSUM code has been removed.  CHECKSUM is still used for file
  50. ;names in the batch mode.  The E(cho) mode has been removed, and echo has
  51. ;been added to the T(erminal) mode.  Added other functions to T(erminal)
  52. ;mode to send a CWID and to send a line    that has previously been entered
  53. ;with the transmitter off. Conditional equates to use features of the
  54. ;Heath/Zenith H-19 terminal added. See HAMMODEM.DOC for further details.
  55.  
  56.     MACLIB MODEM7    ;CONTAINS CMDLINE, INBUF, INLNCOMP,
  57.             ;DIR, AND MFACCESS ROUTINES
  58.             ;changed to MODEM.LIB by Jim Mills
  59.             ;to differentiate from other 'MACROS.LIB'
  60.  
  61.  
  62. TRUE    EQU     0FFH
  63. FALSE    EQU     0
  64.  
  65. DBUFSIZ    EQU     16        ;BUFFER SIZE IN KBYTES
  66.  
  67. ;Modem Equates
  68.  
  69. MODCTLP    EQU    05h        ;MODEM CONTROL PORT
  70. modsftp equ    05h        ;Modem control port for shift/unshift
  71. MODDATP    EQU    04h        ;MODEM DATA PORT
  72. MODSNDB    EQU    1        ;MODEM SEND BIT (XMIT BUFF EMPTY)
  73. MODSNDR    EQU    1        ;MODEM SEND READY
  74. MODRCVB    EQU    2        ;MODEM RECEIVE BIT (DAV)
  75. MODRCVR    EQU    2        ;MODEM RECEIVE READY
  76.  
  77. ERRLIM    EQU    20        ;NUMBER OF TIMES TO RETRY
  78.                 ;SEND/RECEIVE ERRORS BEFORE QUIT
  79.             
  80. EXITCHR    EQU    'E'-40H        ; ^E = EXIT terminal mode
  81. TRANCHR    EQU    'T'-40H        ; ^T = TRANSFER CHARACTER
  82. CAN    EQU    'X'-40H        ; ^X = CANCEL SEND/RECEIVE
  83. EOFCHAR    EQU    'Z'-40H        ; ^Z = END OF FILE
  84. SAVECHR    EQU    'Y'-40H        ; ^Y = SAVE CHARACTER
  85. ESC    equ    '['-40h     ; ^[ = Escape
  86. EXTCHR    EQU    '^'-40H        ; ^^ = SEND NXT CHR
  87. SOH    EQU    1        ; START OF HEADER
  88. EOT    EQU    4        ; END OF TEXT
  89. ACK    EQU    6        ; ACKNOWLEDGE
  90. NAK    EQU    15H        ; NOT ACKNOWLEDGE
  91. BDNMCH    EQU    75H        ; BAD NAME MATCH
  92. OKNMCH    EQU    ACK        ; OKAY NAME MATCH
  93. LF    EQU    10        ; LINEFEED
  94. CR    EQU    13        ; CARRIAGE RETURN
  95. BELL    EQU    7        ; BELL CHARACTER
  96.  
  97.  
  98. BOTTRAM    SET     LAST+100H AND 0FF00H
  99.  
  100.     ORG    100H
  101.  
  102.     JMP    START
  103.  
  104. ;THESE ROUTINES ARE AT THE BEGINNING OF THE PROGRAM SO
  105. ;THEY CAN BE PATCHED BY A MONITER WITHOUT RE-ASSEMBLING
  106. ;THE PROGRAM.
  107.  
  108. mycall        db    '        '    ;ID call. Pad with spaces to 8 char.
  109. timer        dw    00dfh        ;Value for transmitter delay routine
  110. ptton        db    035h        ;DTR=0
  111. pttoff        db    037h        ;DTR=1
  112. mark        db    035h        ;Char to reset modem to mark state
  113. space        db    03ch        ;Char for modem to send steady space
  114. IN$MODCTLP    IN  MODCTLP ! RET    ;in modem control port
  115. OUT$MODCTLP    OUT MODCTLP ! RET    ;out modem control port
  116. out$modsftp    out modsftp ! ret    ;out modem cntrl port for shift/unshift
  117. IN$MODDATP    IN  MODDATP ! RET    ;in modem data port
  118. OUT$MODDATP    OUT MODDATP ! RET    ;out modem data port
  119. ANI$MODSNDB    ANI MODSNDB ! RET    ;bit to test for send ready
  120. CPI$MODSNDR    CPI MODSNDR ! RET    ;value of send bit when ready
  121. ANI$MODRCVB    ANI MODRCVB ! RET    ;bit to test for receive ready
  122. CPI$MODRCVR    CPI MODRCVR ! RET    ;value of receive bit when ready
  123. FASTCLK        DB    TRUE         ;4 MHz or greater
  124. BAKUPBYTE    DB     false        ;true=make .BAK file
  125. XPRFLG        DB    false        ;true=no menu, false=print menu
  126. h19term        equ    false        ;True=Heath/Zenith H-19 terminal
  127.  
  128. START:    LXI    H,0
  129.     DAD    SP        ;GET CP/M'S STACK
  130.     SHLD    STACK        ;SAVE IT
  131.     LXI    SP,STACK    ;START LOCAL STACK
  132.  
  133.     CALL    START1
  134.  
  135.     DB CR,LF,'HAMMODEM  Ver 1.0, 20 Feb 82.',cr,lf,lf
  136.     db 'Adapted from MODEM74 by Phil Cary, W5TYF and Ken Shutt, K5GUU.'
  137.     db cr,lf,lf,'MODEM.ASM originally written by Ward Christensen.'
  138.     db cr,lf,'Revisions through MODEM74 by Mark Zeiger, Jim Mills, '
  139.     db 'and others.',cr,lf,'$'
  140.  
  141. START1:    POP    D        ;GET ADDRESS OF ABOVE MESSAGE
  142.     MVI    C,PRINT        ;Call CPM print string
  143.     CALL    BDOS        ;..function
  144.  
  145.     CALL    INITADR        ;INITIALIZE ADDRESSES
  146.     MVI    A,TRUE        ; 0FFH
  147.     STA    NFILFLG        ;No file specified in Terminal mode
  148.     CMA            ; 0
  149.     STA    SAVEFLG
  150.     CALL    PROCOPT        ;PROCESS CONTROL OPTIONS
  151.     LDA    OPTION        ;GET MAIN OPTION
  152.     CPI    'X'        ;EXPERT FLAG?
  153.     JNZ    RESTART    ;NO
  154.     MVI    A,TRUE        ;YES
  155.     STA    XPRFLG        ;MAKE EXPERT
  156.     JMP    MENU
  157.  
  158. RESTART
  159.     LDA    OPTION        ;GET MAIN OPTION
  160.     CPI    ' '        ;NO OPTION SPEC'D?
  161.     JZ    MENU        ;TRUE, GO MENU
  162.     CPI    'M'        ;MENU ASKED FOR?
  163.     JZ    MENU2        ;YES, GO MENU
  164.     CALL    MOVEFCB
  165.     MVI    A,FALSE
  166.     STA    NFILFLG
  167.  
  168.     CALL    IN$MODDATP    ;GOBBLE UP GARBAGE..
  169.     CALL    IN$MODDATP    ;..CHARACTERS ON LINE
  170.  
  171.     LDA    OPTION        ;PROCESS MAIN OPTION
  172.     CPI    'T'        ;TERMINAL MODE?
  173.     JZ    DSKSAVE        ;YES
  174.     CPI    'S'        ;SEND A FILE?
  175.     JZ    SENDFIL        ;YES
  176.     CPI    'R'        ;RECEIVE A FILE?
  177.     JZ    RCVFIL        ;YES
  178.     JMP    MENU        ;NO OPTION SPEC'D, GO MENU
  179.  
  180. ;REVISED TERMINAL ROUTINE ALLOWING MEMORY SAVE
  181.             
  182. DSKSAVE    LDA    NFILFLG        ;NEW FILE FLAG
  183.     CPI    TRUE        ;OFFH? (TRUE=NORMAL TERMINAL MODE)
  184.     JZ    termint        ;YES
  185.     LDA    FCB+1        ;FIRST CHAR OF FILENAME
  186.     CPI    ' '        ;FILE SPEC'D
  187.     JNZ    GOODNM        ;YES, GOOD NAME
  188.     MVI    A,TRUE        ;0FFH
  189.     STA    NFILFLG    
  190.     CMA        
  191.     STA    SAVEFLG    
  192.     JMP    termint    
  193.  
  194. GOODNM    CALL    ERASFIL
  195.     CALL    MOVE2
  196.     LXI    D,FCB3
  197.     MVI    C,MAKE
  198.     CALL    BDOS
  199.     LXI    D,FCB3
  200.     MVI    C,OPEN
  201.     CALL    BDOS
  202.     LXI    H,BOTTRAM
  203.     SHLD    HLSAVE
  204.     MVI    A,FALSE
  205.     STA    NFILFLG
  206.  
  207. termint:
  208.     if    h19term
  209.     call    ilprt 
  210.     db    esc,'E',esc,'j'        ;Clear screen, save cursor position
  211.     db    esc,'x','1'        ;Enable 25th line
  212.     db    esc,'Y',56,33        ;Position cursor to L25,C2
  213.     db    esc,'p'            ;Reverse video on
  214.     db    '  f1=CWID | f2=TX Line | f3=TX File Blind '
  215.     db    '| f4=Toggle Save | f5=Exit To Menu  '
  216.     db    esc,'q',esc,'k',0    ;Reverse video off, restore cursor
  217.     endif
  218. ;
  219. TERM:    CALL    STAT        ;KEYPRESS?
  220.     JZ    TERML        ;NO, CHECK LINE
  221.     CALL    KEYIN        ;GET CHAR FROM KBD
  222.     MOV    B,A        ;SAVE
  223.     LDA    EXACFL
  224.     ORA    A        ;EXACT?
  225.     MVI    A,0
  226.     STA    EXACFL        ;CLR FOR NEXT TIME
  227.     MOV    A,B        ;RESTORE
  228.     JNZ    NOTOG
  229.     cpi    esc        ;^[?
  230.     jz    txcmd        ;Process second character
  231.     CPI    EXITCHR        ;^E?
  232.     JZ    trmexit        ;YES, RETURN TO MENU after reseting terminal
  233.     CPI    EXTCHR        ;^^?
  234.     JZ    EXTFLG        ;YES, SET FLAG FOR NXT CHAR
  235.     CPI    TRANCHR        ;TEST FOR TRANSFER REQUEST (^T)
  236.     CZ    TRANSFER    ;SEND-A-FILE (BLIND SEND)
  237.     JZ    TERM        ;LOOP
  238.     CPI    SAVECHR
  239.     JNZ    NOTOG    
  240.     LDA    NFILFLG        ;DO NOT ALLOW SAVE IF..
  241.     CPI    TRUE        ;..THIS FLAG IS SET.
  242.     JZ    TERML
  243.     LDA    SAVEFLG
  244.     CMA
  245.     STA    SAVEFLG
  246.     JMP    TERML
  247.  
  248. txcmd:    call     stat        ;Character at keyboard?
  249.     jz    txcmd        ;Loop till there is
  250.     call    keyin        ;Get it
  251.     cpi    'S'        ;Is it S?(ESC S or f1 function key on H-19)
  252.     cz    cwidrou        ;If so, go id in cw
  253.     cpi    'T'        ;Is it T?(ESC T or f2 function key on H-19)
  254.     cz    linesend    ;Set up to send a line of charaters
  255.     CPI    'W'        ;Is it W?(ESC W or f5 function key on H-19)
  256.     JZ    trmexit        ;Yes, reset terminal and return to menu
  257.     CPI    'U'        ;ESC U or f3?
  258.     CZ    TRANSFER    ;SEND-A-FILE (BLIND SEND)
  259.     JZ    TERM        ;LOOP
  260.     CPI    'V'        ;ESC V or f4?
  261.     JNZ    txcmd2
  262.     LDA    NFILFLG        ;DO NOT ALLOW SAVE IF..
  263.     CPI    TRUE        ;..THIS FLAG IS SET.
  264.     JZ    TERM    
  265.     LDA    SAVEFLG
  266.     CMA
  267.     STA    SAVEFLG
  268.     jmp    term
  269. txcmd2:    cpi     'Q'        ;Is it Q?(ESC Q or Red function key on H-19)
  270.     cz    txon        ;If so, turn on transmitter
  271.     cpi     'P'        ;Is it P?(ESC P or Blue function key on H-19)
  272.     cz    txoff        ;If so, turn off transmitter
  273.     cpi    'R'        ;R?(ESC R or White function key on H-19)
  274.     jnz    term        ;If not, go get another character
  275.     call    txon        ;If so, turn on transmitter
  276.     mvi    a,true        ;..and set AUTO TX OFF on CR
  277.     sta    autotx        ;..flag
  278.     jmp     term        ;Get another character 
  279.  
  280. linesend:
  281.     lxi    h,linebuf    ;Point to line buffer
  282. lineret:
  283.     call    stat        ;Character at keyboard
  284.     jz    lineret        ;Loop if not
  285.     call    keyin        ;Get character
  286.     cpi    cr        ;Is it a CR
  287.     push    psw        ;Save character and flags
  288.     mov    m,a        ;Put character in linebuf
  289.     call    type        ;Display the character
  290.     inx    h        ;Increment linebuf
  291.     PUSH    PSW
  292.     LDA    SAVEFLG
  293.     CPI    FALSE
  294.     JZ    lineret1
  295.     xchg            ;Hold linebuf pointer in DE
  296.     lhld    hlsave        ;Point to main save buffer
  297.     POP    PSW
  298.     MOV    M,A
  299.     INX    H
  300.     SHLD    HLSAVE        
  301.     xchg            ;Linebuf pointer back in HL
  302. lineret1:
  303.     pop    psw        ;Get flag back
  304.     jz    lineout        ;Send line if CR
  305.     jmp    lineret        ;Get another character if not CR
  306.  
  307. lineout:
  308.     lda    saveflg        ;First see if saving
  309.     jnz    lineout1
  310.     lhld    hlsave        ;If so, point to main save buffer
  311.     mvi    m,lf        ;..and put a LF in the file
  312.     inx    h
  313.     shld    hlsave
  314. lineout1:
  315.     call    crlf
  316.     call    txon
  317.     lxi    h,linebuf    ;Point to line buffer
  318. lineout2:
  319.     call    in$modctlp
  320.     call    ani$modsndb
  321.     call    cpi$modsndr
  322.     jnz    lineout2
  323.     mov    a,m        ;Get character
  324.     push     psw        ;Save character
  325.     call    out$moddatp    ;Send character
  326.     call    type        ;Echo it
  327.     inx    h        ;Increment line buffer
  328.     pop    psw         ;Get character
  329.     cpi    cr        ;Was it a CR
  330.     jnz    lineout2    ;Loop for next character if not
  331. lineout3:
  332.     call     in$modctlp     ;Get status
  333.     call     ani$modsndb    ;Mask ready bit
  334.     call     cpi$modsndr    ;Ready?
  335.     jnz    lineout3
  336.     mvi    a,lf        ;Else get LF
  337.     call    out$moddatp    ;..and send it
  338.     call    type        ;..and echo it
  339.     lda    saveflg        ;If saving
  340.     cpi    true        ;..then
  341.     jnz    lineout4
  342.     mvi    a,':'        ;..type a ":"
  343.     call    type        ;..at beginning of line
  344. lineout4:
  345.     call    txoff        ;Finished with line if CR
  346.     lhld    hlsave        ;Restore save buffer pointer to HL before ret
  347.     jmp    term        ;Return to terminal mode with xmitter off
  348.  
  349. trmexit:
  350.     if     h19term        ;Routine to reset H-19.  Erases entire screen,
  351.     call    ilprt        ;..disables 25th line and homes cursor
  352.     db    esc,'z',0
  353.     endif
  354.  
  355.     call     txoff        ;Be sure transmitter is off and
  356.     jmp    menu        ;..exit terminal mode to menu
  357.  
  358. EXTFLG:    MVI    A,TRUE
  359.     STA    EXACFL
  360.     JMP    TERML
  361.  
  362. NOTOG:    push    psw
  363. notog1:    call     in$modctlp     ;Get status
  364.     call     ani$modsndb    ;Mask ready bit
  365.     call     cpi$modsndr    ;Ready?
  366.     jnz    notog1
  367.     pop    psw
  368.     CALL    OUT$MODDATP
  369.     call    type
  370.     PUSH    PSW
  371.     LDA    SAVEFLG
  372.     CPI    FALSE
  373.     JZ    notog2
  374.     POP    PSW
  375.     MOV    M,A
  376.     INX    H
  377.     SHLD    HLSAVE        ;MENU COMMAND DESTROYS HL-REG..
  378.     push      psw
  379. notog2:    pop    psw
  380.     cpi    cr        ;Is it CR?
  381.     jnz    terml        ;Continue if not
  382. notog3:    call     in$modctlp     ;Get status
  383.     call     ani$modsndb    ;Mask ready bit
  384.     call     cpi$modsndr    ;Ready?
  385.     jnz    notog3
  386.     mvi    a,lf
  387.     call    out$moddatp
  388.     call    type
  389.     MOV    M,A
  390.     INX    H
  391.     SHLD    HLSAVE        ;MENU COMMAND DESTROYS HL-REG..
  392.     lda    autotx        ;Otherwise, get auto TXOFF on CR flag
  393.     cpi    true        ;See if it is set
  394.     cz    txoff        ;Turn off TX if set
  395.     mvi    a,false        ;..and reset
  396.     sta    autotx        ;..flag
  397.     lda    saveflg
  398.     cpi    true
  399.     jnz    terml
  400.     mvi    a,':'
  401.     call    type
  402.  
  403.  
  404. TERML:    CALL    IN$MODCTLP
  405.     CALL    ANI$MODRCVB
  406.     CALL    CPI$MODRCVR
  407.     JNZ    TERM
  408.     CALL    IN$MODDATP
  409.     CPI    0        ;CHECK FOR NULLS
  410.     JZ    TERM        ;DON'T PROCESS THEM
  411.     ANI    7FH        ;STRIP PARITY
  412.     CALL    TYPE
  413.     PUSH    PSW
  414.     LDA    SAVEFLG
  415.     CPI    FALSE
  416.     JZ    NOSAVE
  417.     POP    PSW
  418.     MOV    M,A
  419.     INX    H
  420.     SHLD    HLSAVE        ;MENU COMMAND DESTROYS HL-REG..
  421.  
  422. COLON:    CPI    LF        ;If linefeed
  423.     JNZ    NOCOLON        ;..TYPE ":" AFTER EACH LINE FEED..
  424.     MVI    A,':'        ;..WHEN MEMORY SAVE ACTIVE.
  425.     CALL    TYPE
  426.  
  427. NOCOLON:
  428.     LDA    7        ;CHECK TO SEE IF..
  429.     DCR    A        ;..PAGE BELOW BDOS HAS BEEN..
  430.     CMP    H        ;..REACHED AND DISKSAVE IS NEEDED.
  431.     CZ    INTDSKSV
  432.     JMP    TERM
  433.  
  434. NOSAVE:    POP    PSW
  435.     JMP    TERM
  436.  
  437. autotx:     db    false
  438. SAVEFLG: DB    FALSE
  439.  
  440. INTDSKSV:
  441.     call    ilprt
  442.     db     cr,lf,lf,'WARNING!!!  BUFFER AREA IS FULL.',cr,lf,bell
  443.     db    'Data is being lost while buffer contents is being'
  444.     db    'written to disk.',bell,cr,lf
  445.     db    'Save will continue after disk write.',bell
  446.     db    cr,lf,lf,0
  447.     CALL    NUMREC1
  448.     CALL    WRTDSK        ;WRITE THE RECORDS
  449.     lxi    h,bottram
  450.     shld    hlsave
  451.     RET
  452.  
  453. NUMRECS    MVI    M,EOFCHAR
  454.     INX    H
  455.     LXI    D,127
  456.     DAD    D
  457. NUMREC1    LXI    D,-(BOTTRAM)
  458.     DAD    D
  459.     MOV    A,L        ;DIVIDE HL BY 128..
  460.     ORA    A
  461.     RAL            ;..TO GET THE..
  462.     MOV    L,H        ;..NUMBER OF SECTORS
  463.     MVI    H,0
  464.     PUSH    PSW
  465.     DAD    H
  466.     POP    PSW
  467.     MVI    A,0
  468.     ADC    L
  469.     MOV    L,A        ;RETURNS WITH NUMBER OF..
  470.     RET            ;..128 BYTE RECORDS IN HL.
  471.  
  472. WRTDSK    LXI    D,BOTTRAM
  473. NEXTWRT    MVI    C,STDMA
  474.     CALL    BDOSRT
  475.     PUSH    D
  476.     LXI    D,FCB3
  477.     MVI    C,WRITE
  478.     CALL    BDOSRT
  479.     POP    D
  480.     XCHG
  481.     PUSH    D
  482.     LXI    D,128
  483.     DAD    D
  484.     POP    D
  485.     XCHG
  486.     DCX    H
  487.     MOV    A,H
  488.     ORA    L
  489.     JNZ    NEXTWRT
  490.     RET
  491.  
  492. CLOSE3    LXI    D,FCB3
  493.     MVI    C,CLOSE
  494.     CALL    BDOS
  495.     RET
  496.  
  497. BDOSRT    PUSH B ! PUSH D ! PUSH H ! PUSH PSW
  498.     CALL    BDOS
  499.     POP PSW ! POP H ! POP D ! POP B
  500.     RET
  501.  
  502. MOVE2    LXI    H,FCB3
  503.     CALL    INITFCBS
  504.     LXI    H,FCB
  505.     LXI    D,FCB3
  506.     MVI    B,12
  507.     CALL    MOVE
  508.     RET
  509.  
  510. ;FILE TRANSFER ROUTINE - CALLED WITH 
  511. ;CONTROL-T FROM TERMINAL ROUTINE.
  512. ;TRANSFER MAY BE CANCELLED WHILE SENDING BY USING CONTROL-X.
  513.  
  514. TRANSFER:
  515.     PUSH H ! PUSH D ! PUSH B ! PUSH PSW
  516.     LXI    H,FCB4
  517.     CALL    INITFCBS    ;INITIALIZES FCBS POINTED..
  518.     LXI    H,FCB+16    ;..TO BY HL REG.
  519.     CALL    INITFCBS
  520. GET:    CALL    GETNAME
  521.     LDA    CMDBUF+2    ;WAS FILE ENTERED
  522.     CPI    20H
  523.     JZ    TRANSL2
  524.     CALL    MOVE4
  525.     CALL    OPEN4
  526.     CPI    0FFH        ;RETURN WITH 0FFH MEANS
  527.     JNZ    CONTIN        ;FILE DOES NOT EXIST
  528. TRANSL1:    
  529.     CALL    ILPRT
  530.         DB    CR,LF,'++FILE DOES NOT EXIST++',CR,LF,0
  531. TRANSL2:    
  532.     CALL    ILPRT
  533.         DB    'TYPE "R" TO RETURN TO MODEM',CR,LF
  534.         DB    'TYPE "A" TO RE-ENTER NAME: ',BELL,0
  535.     CALL    KEYIN
  536.     CALL    UCASE
  537.     CALL    TYPE        ;ECHO RESPONSE
  538.     CALL    CRLF
  539.     CPI    'A'
  540.     JZ    GET
  541.     CPI    'R'
  542.     JZ    RETURN
  543.     JMP    TRANSL2
  544.  
  545. CONTIN:    call    txon
  546.     LXI    D,80H
  547.     MVI    C,STDMA
  548.     CALL    BDOS
  549. READMR:    CALL    READ80
  550.     CPI    1        ;END OF FILE
  551.     JZ    RETURNS
  552.     CPI    2        ;BAD READ
  553.     JZ    RETURNU
  554.     CALL    SEND80C
  555.     CPI    EOFCHAR        ;END OF FILE - OMIT IF OBJECT..
  556.     JZ    RETURNS        ;..CODE IS TO BE SENT.
  557.     CPI    CAN        ;CANCELLATION?
  558.     JZ    TRANCAN
  559.     JMP    READMR
  560. RETURNS:    
  561.     CALL    ILPRT
  562.         DB    CR,LF,'++FILE TRANSFER COMPLETED++',CR,LF,BELL,BELL,0
  563.     JMP    RETURN
  564. RETURNU:    
  565.     CALL    ILPRT
  566.         DB    CR,LF,'++FILE TRANSFER UNSUCCESSFUL++',CR,LF,BELL,BELL,0
  567.     JMP    RETURN
  568. TRANCAN:    
  569.     CALL    ILPRT
  570.         DB    CR,LF,CR,LF,'++ TRANSFER CANCELLED ++',CR,LF,BELL,BELL,0
  571. RETURN:    POP PSW ! POP B ! POP D ! POP H
  572.     call    txoff
  573.     RET
  574.  
  575. INITFCBS            ;ENTRY AT +2 WILL LEAVE..
  576.     MVI    M,0        ;..DRIVE NO. INTACT.
  577.     INX    H        ;WILL INITIALIZE AN FCB..
  578.     MVI    B,11        ;..POINTED TO BY HL-REG. FILLS 1ST POS
  579. LOOP10    MVI    M,' '        ;..WITH 0, NEXT 11 WITH..
  580.     INX    H        ;..WITH BLANKS, AND LAST..
  581.     DCR    B        ;..21 WITH NULLS.
  582.     JNZ    LOOP10
  583.     MVI    B,21
  584. LOOP11    MVI    M,0
  585.     INX    H
  586.     DCR    B
  587.     JNZ    LOOP11
  588.     RET
  589.  
  590. GETNAME    CALL ILPRT
  591.         DB CR,LF,'ENTER FILE NAME TO BE TRANSFERRED -  C/R TO QUIT: ',0
  592.     LXI    D,CMDBUF
  593.     CALL    INBUFF
  594.     CALL    CRLF
  595.     RET
  596.  
  597. MOVE4    LXI    D,CMDBUF
  598.     LXI    H,FCB4
  599.     CALL    CPMLINE
  600.     RET
  601.  
  602. OPEN4    LXI    D,FCB4
  603.     MVI    C,OPEN
  604.     CALL    BDOS
  605.     RET
  606.  
  607. READ80    LXI    D,FCB4
  608.     MVI    C,READ
  609.     CALL    BDOS
  610.     RET
  611.  
  612. SEND80C    MVI    B,80H
  613.     LXI    H,80H
  614. SENDCH1    MOV    A,M
  615.     CALL    MODOUT
  616.     CPI    EOFCHAR
  617.     RZ
  618.     CALL    STAT        ;TEST TO SEE IF
  619.     ORA    A        ;CANCELLATION REQUESTED
  620.     JZ    SKIP12
  621.     CALL    KEYIN
  622.     CPI    CAN
  623.     RZ
  624. SKIP12    INX    H
  625.     DCR    B
  626.     JNZ    SENDCH1
  627.     RET
  628.  
  629. MODOUT    PUSH    PSW
  630. MODOUTL    CALL    IN$MODCTLP
  631.     CALL    ANI$MODSNDB
  632.     CALL    CPI$MODSNDR
  633.     JNZ    MODOUTL
  634.     POP    PSW
  635.     CALL    OUT$MODDATP
  636.     CALL    TYPE
  637.     RET
  638.  
  639. FCB4    DS 33
  640.  
  641. ;UNCOMMENTED LINES ARE THOSE OF ORIGINAL MODEM PROGRAM.
  642.  
  643. ;        SEND A CP/M FILE
  644.  
  645. SENDFIL:
  646.     LDA    BATCHFLG    ;CHECK IF MULTIPLE FILE..
  647.     ORA    A        ;..MODE IS SET.
  648.     JNZ    SENDC1
  649.     MVI    A,TRUE        ;INDICATE BATCH SEND
  650.     STA    SENDFLG
  651.     LDA    FSTFLG        ;IF FIRST TIME THRU..
  652.     ORA    A        ;..SCAN THE COMMAND LINE..
  653.     CNZ    TNMBUF        ;..FOR MULTIPLE NAMES.
  654.     CALL    SENDFN        ;SENDS FILE NAME TO RECEIVER
  655.     JNC    SENDC2        ;CARRY SET MEANS NO MORE FILES.
  656.     MVI    A,'B'        ;STOP BATCH..
  657.     STA    BATCHFLG    ;..MODE OPTION.
  658.     call    txon
  659.     MVI    A,EOT        ;FINAL XFER END
  660.     CALL    SEND
  661.     call    txoff
  662.     JMP    DONE
  663. SENDC1    LDA    FCB+1
  664.     CPI    ' '
  665.     JZ    BLKFILE
  666. SENDC2    CALL    CNREC        ;GET NUMBER OF RECORDS
  667.     CALL    OPENFIL
  668.     CALL    WAITNAK
  669. SENDLP    CALL    RDSECT
  670.     JC    SENDEOF
  671.     CALL    INCRSNO
  672.     XRA    A
  673.     STA    ERRCT
  674.  
  675. SENDRPT:
  676.     call    txon
  677.     CALL    SENDHDR
  678.     CALL    SENDSEC
  679.     call    sendcrc    
  680.     call    txoff
  681.     CALL    GETACK
  682.     JC    SENDRPT
  683.     JMP    SENDLP
  684.  
  685. SENDEOF:
  686.     call    txon
  687.     MVI    A,EOT
  688.     CALL    SEND
  689.     call    txoff
  690.     CALL    GETACK
  691.     JC    SENDEOF
  692.     JMP    DONE
  693.  
  694. ;        RECEIVE A FILE
  695.  
  696. RCVFIL:    LDA    BATCHFLG    ;CHECK IF MULT..
  697.     ORA    A        ;..FILE MODE.
  698.     JNZ    RCVC1
  699.     MVI    A,FALSE        ;FLAG WHERE TO RETURN..
  700.     STA    SENDFLG        ;..FOR NEXT FILE TRANS.
  701.     CALL    GETFN        ;GET THE FILE NAME.
  702.     JNC    RCVC2        ;CARRY SET MEANS NO MORE FILES.
  703.     MVI    A,'B'        ;STOP BATCH..
  704.     STA    BATCHFLG    ;..MODE OPTION.
  705.     JMP    DONE
  706. RCVC1    LDA    FCB+1        ;MAKE SURE FILE IS NAMED
  707.     CPI    ' '
  708.     JZ    BLKFILE
  709.     JMP    RCVC3
  710. RCVC2    CALL    CKCPM2
  711.     CALL    CKBAKUP
  712. RCVC3    CALL    ERASFIL
  713.     CALL    MAKEFIL
  714.     LDA    QFLG
  715.     ORA    A
  716.     JNZ    rcvlp
  717.     LDA    BATCHFLG
  718.     ORA    A        ;DON'T PRINT MSSG IF..
  719.     JZ    rcvlp        ;..IN MULTI AND QUIET.
  720.     CALL    ILPRT
  721.     DB    'FILE OPEN, READY TO RECEIVE',CR,LF,0
  722. ;
  723. RCVLP    CALL    RCVSECT
  724.     JC    RCVEOT
  725.     CALL    WRSECT
  726.     CALL    INCRSNO
  727.     CALL    SENDACK
  728.     JMP    RCVLP
  729.  
  730. RCVEOT:    CALL    WRBLOCK
  731.     CALL    SENDACK
  732.     CALL    CLOSFIL
  733.     JMP    DONE
  734.     
  735. ;SUBROUTINES
  736. ;
  737. ;FSK CWID routine.
  738. ;ASCII to CW translate table
  739. ASCII$CW:
  740.     DB    5+10010000B    ; / -..-.
  741.     DB    5+11111000B    ;ZERO
  742.     DB    5+01111000B    ;1
  743.     DB    5+00111000B    ;2
  744.     DB    5+00011000B    ;3
  745.     DB    5+00001000B    ;4
  746.     DB    5+00000000B    ;5
  747.     DB    5+10000000B    ;6
  748.     DB    5+11000000B    ;7
  749.     DB    5+11100000B    ;8
  750.     DB    5+11110000B    ;9
  751.     DB    0        ;:  NOT USED
  752.     DB    0        ; ; NOT USED
  753.     DB    0        ; < NOT USED
  754.     DB    0        ; = NOT USED
  755.     DB    0        ; > NOT USED
  756.     DB    0        ; ? NOT USED
  757.     DB    0        ; @ NOT USED
  758.     DB    2+01000000B    ; A  .-
  759.     DB    4+10000000B    ;B -...
  760.     DB    4+10100000B    ; C -.-.
  761.     DB    3+10000000B    ; D -..
  762.     DB    1+00000000B    ; E .
  763.     DB    4+00100000B    ; F ..-.
  764.     DB    3+11000000B    ;G --.
  765.     DB    4+00000000B    ;H
  766.     DB    2+00000000B    ; I ..
  767.     DB    4+01110000B    ; J .---
  768.     DB    3+10100000B    ; K -.-
  769.     DB    4+01000000B    ; L .-..
  770.     DB    2+11000000B    ; M --
  771.     DB    2+10000000B    ; N -.
  772.     DB    3+11100000B    ; O ---
  773.     DB    4+01100000B    ; P .--.
  774.     DB    4+11010000B    ; Q --.-
  775.     DB    3+01000000B    ; R .-.
  776.     DB    3+00000000B    ; S ...
  777.     DB    1+10000000B    ; T -
  778.     DB    3+00100000B    ; U ..-
  779.     DB    4+00010000B    ; V ...-
  780.     DB    3+01100000B    ; W .--
  781.     DB    4+10010000B    ; X -..-
  782.     DB    4+10110000B    ; Y -.--
  783.     DB    4+11000000B    ; Z --..
  784. ;End of translate table
  785. ;
  786. ID$STRING:    DS    14    ;RESERVE 14 BYTES FOR ID STRING
  787. DE$STR:        DB    'DE '
  788.  
  789. cwidrou:    push psw ! push h ! push d ! push b
  790.         call    cwid
  791.         pop b ! pop d ! pop h ! pop psw
  792.         ret
  793.  
  794. CWID:    LXI    D,ID$STRING
  795.     LXI    H,DE$STR    ;POINT TO "DE" STRING
  796.     MVI    B,3
  797.     CALL    MOVE
  798.     LXI    H,MYCALL    ;PUT OUR CALL IN
  799.     MVI    B,8
  800.     CALL    MOVE
  801.     XCHG
  802.     MVI    M,' '        ;TRAILING SPACE
  803.     INX    H
  804.     MVI    M,0        ;NULL TERMINATES STRING
  805.     CALL    txon        ;KEY TRANSMITTER
  806.     CALL    shift        ;Send space tone
  807.  
  808.     LXI    H,ID$STRING
  809. CWID1:    MOV    A,M        ;GET A ASCII CHAR.
  810.     ORA    A        ;NULL?
  811.     JZ    txoff        ;QUIT IF NULL
  812.     CPI    '0'
  813.     JC    CWID2        ;IGNORE INVALID CHAR
  814.     PUSH    H
  815.     MOV    C,A
  816.     CALL    SEND$CW$CHAR    ;CONVERT TO CW AND SEND
  817.     POP    H
  818. CWID2:    INX    H
  819.     JMP    CWID1        ;LOOP TILL DONE
  820.  
  821. SEND$CW$CHAR:
  822.     PUSH    B
  823.     CALL    shift        ;Send space tone
  824.     MVI    C,2
  825.     CALL    DELAYX        ;WAIT 2 DOT TIMES
  826.     POP    B        ;GET ASCII CHARACTER BACK
  827.     LXI    H,ASCII$CW-2FH    ;POINT TO CONVERSION TABLE
  828.     MOV    A,C
  829.     CPI    20H        ;TEST FOR SPACE
  830.     JNZ    CW1
  831.     MVI    C,7        ;7 DOT TIMES FOR SPACE
  832.     JMP    DELAYX
  833. CW1:    MVI    B,0
  834.     DAD    B        ;INDEX INTO TABLE
  835.     MOV    A,M        ;GET CW CODE
  836.     ANI    7        ;KEEP COUNT
  837.     RZ            ;RETURN IF ZERO COUNT
  838.     MOV    B,A        ;PUT COUNT IN REG. B
  839.     MOV    A,M        ;GET CODE AGAIN
  840. CW2:    ADD    A        ;SHIFT MSB INTO CARRY
  841.     MVI    E,1        ;ASSUME A DOT
  842.     JNC    CW3        ;JUMP IF DOT
  843.     MVI    E,3        ;ELSE SET FOR DASH
  844. CW3:    PUSH    B        ;SAVE COUNT
  845.     PUSH    PSW        ;SAVE CODE
  846.     CALL    unshift        ;Send mark tone
  847.     MOV    C,E        ;GET TIME
  848.     CALL    DELAYX
  849.     CALL    shift        ;Send space tone
  850.     MVI    C,1
  851.     CALL    DELAYX        ;WAIT 1 DOT TIME
  852.     POP    PSW        ;RESTORE CODE
  853.     POP    B        ;RESTORE COUNT
  854.     DCR    B        ;COUNT DOWN
  855.     JNZ    CW2        ;LOOP TILL FINISHED
  856.     RET
  857.  
  858. ;THIS TIMES 1 DIT.
  859.  
  860. DELAYX: MOV    A,C
  861.     ORA    A
  862.     RZ
  863.     PUSH    B
  864.     PUSH    D
  865. DLY1:    LXI    D,50        ;50 MS DELAY
  866.     CALL    delayd
  867.     DCR    C
  868.     JNZ    DLY1
  869.     POP    D
  870.     POP    B
  871.     RET
  872. ;
  873. ;Frequency shift keying routines
  874. ;
  875. unshift:
  876.     PUSH    PSW
  877.     lda    mark
  878.     call    out$modsftp
  879.     POP    PSW
  880.     RET
  881. ;
  882. shift:
  883.     PUSH    PSW
  884.     lda    space
  885.     call    out$modsftp
  886.     POP    PSW
  887.     RET
  888. ;
  889. ;txon/txoff.     Key the transmitter by setting
  890. ;               DTR on and off with appropriate
  891. ;        delays.
  892. txon:    push    psw        ;SAVE A
  893.     lda    ptton        ;DTR=0
  894.     call     out$modctlp    ;Turn on transmitter
  895.     pop     psw        ;Get A
  896.     push    h        ;Save HL
  897.     lhld    timer        ;Get value of timer
  898.     call    delayh        ;Wait for full power
  899.     lhld     timer        ;Do it again
  900.         call    delayh        ;..yet
  901.     pop    h        ;Restore HL
  902.     ret
  903.  
  904. txoff:    push    psw        ;Save A
  905.     push     h        ;Save HL
  906.     lhld    timer        ;Get value of timer
  907.         call    delayh        ;Delay a little while other end is coming up
  908.     pop    h        ;Restore HL
  909. busy:    call     in$modctlp     ;Get status
  910.     call     ani$modsndb    ;Mask ready bit
  911.     call     cpi$modsndr    ;Ready?
  912.     jnz    busy        ;..No, wait
  913.     lda    pttoff         ;DTR=1
  914.     call     out$modctlp    ;Turn off transmitter
  915.     pop    psw        ;get A
  916.         call     in$moddatp    ;Clear garbage
  917.         call     in$moddatp    ;..again
  918.     ret
  919. ;
  920. ;
  921. ;This is a delay routine
  922. ;Enter at delayh with delay in ms. in HL or
  923. ;    enter at delayd with delay in ms. in DE
  924.  
  925. delayh:    xchg            
  926.     call    delayd
  927.     xchg
  928.     ret
  929.  
  930. delayd:    call    wait
  931.     dcx    d
  932.     mov    a,e
  933.     ora    d
  934.     jnz    delayd
  935.     ret
  936.  
  937. wait:    push    psw
  938.     lda    fastclk        ;FF=4 Mhz, 00=2 Mhz
  939.     ora    a
  940.     jz    wait1
  941.     mvi    a,216        ;Multiples of 108 for North Star(Z80)
  942.     jmp    wait2        ;..to give 1 millisecond delay
  943. wait1:    mvi    a,108        ;..in this routine.
  944. wait2:    dcr    a
  945.     nop
  946.     jnz    wait2
  947.     pop    psw
  948.     ret
  949. ;
  950.  
  951. SENDFN    LDA    QFLG
  952.     ORA    A
  953.     JZ    SWNAK
  954.     CALL    ILPRT
  955.     DB    'AWAITING NAME NAK',CR,LF,0
  956. SWNAK    CALL    WAITNLP
  957.     call    txon
  958.     MVI    A,ACK        ;GOT NAK, SEND ACK
  959.     CALL    SEND
  960.     call    txoff
  961.     LXI    H,FILECT
  962.     DCR    M
  963.     JM    NOMRNM
  964.     LHLD    NBSAVE        ;GET FILE NAME..
  965.     LXI    D,FCB        ;..IN FCB
  966.     MVI    B,12
  967.     CALL    MOVE
  968.     SHLD    NBSAVE
  969.     CALL    SENDNM        ;SEND IT
  970.     ORA    A        ;CLEAR CARRY
  971.     RET
  972. NOMRNM:    call    txon
  973.     MVI    A,EOT
  974.     CALL    SEND
  975.     call    txoff
  976.     STC
  977.     RET
  978.  
  979. SENDNM:    PUSH    H
  980. SENDNM1:
  981.     MVI    D,11        ;COUNT CHARS IN NAME
  982.     MVI    C,0        ;INIT CHECKSUM
  983.     LXI    H,FCB+1        ;ADDRESS NAME
  984. NAMLPS:    call    txon
  985.     MOV    A,M        ;SEND NAME
  986.     ANI    7FH        ;STRIP HIGH ORDER BIT SO CP/M 2..
  987.     CALL    SEND        ;..WON'T SEND R/O FILE DESIGNATION.
  988.     call    txoff
  989.     LDA    QFLG        ;SHOW NAME IF..
  990.     ORA    A        ;..QFLG NOT SET.
  991.     MOV    A,M
  992.     CNZ    TYPE
  993. ACKLP:    PUSH    B        ;SAVE CKSUM
  994.     MVI    B,2        ;WAIT FOR RECEIVER
  995.     CALL    recvdg        ;..TO ACKNOWLEDGE
  996.     POP    B        ;..GETTING LETTER
  997.     JC    SCKSER
  998.     CPI    ACK
  999.     JNZ    ACKLP
  1000.     INX    H        ;NEXT CHAR
  1001.     DCR    D
  1002.     JNZ    NAMLPS
  1003.     call    txon
  1004.     MVI    A,EOFCHAR    ;TELL RECEIVER END OF NAME
  1005.     CALL    SEND
  1006.     call    txoff
  1007.     LDA    QFLG
  1008.     ORA    A
  1009.     CNZ    CRLF
  1010.     MOV    D,C        ;SAVE CHECKSUM
  1011.     MVI    B,2    
  1012.     CALL    recvdg        ;GET CHECKSUM
  1013.     CMP    D        ;..FROM RECEIVER.
  1014.     JZ    NAMEOK
  1015. SCKSER:    call    txon
  1016.     MVI    A,BDNMCH    ;BAD NAME-TELL RECEIVER
  1017.     CALL    SEND
  1018.     call    txoff
  1019.     LDA    QFLG
  1020.     ORA    A
  1021.     JZ    SKCSER1
  1022.     CALL    ILPRT
  1023.     DB    'CHECKSUM ERROR',CR,LF,0
  1024. SKCSER1:            ;Do handshaking over
  1025.     CALL    WAITNLP    
  1026.     call    txon
  1027.     MVI    A,ACK
  1028.     CALL    SEND
  1029.     call    txoff
  1030.     JMP    SENDNM1
  1031. NAMEOK:    call    txon
  1032.     MVI    A,OKNMCH    ;GOOD NAME-TELL RECEIVER
  1033.     CALL    SEND
  1034.     call    txoff
  1035.     POP    H
  1036.     RET    
  1037.  
  1038. GETFN:    LXI     H,FCB
  1039.     CALL     INITFCBS+2    ;DOES NOT INITIALIZE DRIVE
  1040.     LDA     QFLG
  1041.     ORA     A
  1042.     JZ     GNAMELP
  1043.     CALL     ILPRT
  1044.     DB 'AWAITING FILE NAME',CR,LF,0
  1045. GNAMELP:
  1046.     CALL     HSNAK
  1047.     JC     GNAMELP
  1048.     CALL     GETNM        ;GET THE NAME
  1049.     CPI     EOT        ;IF EOT, THEN NO MORE FILES
  1050.     JZ     NOMRNMG
  1051.     ORA     A        ;CLEAR CARRY
  1052.     RET
  1053. NOMRNMG:
  1054.     STC
  1055.     RET
  1056.  
  1057. GETNM:    PUSH     H
  1058. GETNM1:    MVI     C,0        ;INIT CHECKSUM
  1059.     LXI     H,FCB+1
  1060. NAMELPG:
  1061.     MVI     B,5
  1062.     CALL     recvdg        ;GET CHAR
  1063.     JNC     GETNM3
  1064.     LDA     QFLG
  1065.     ORA     A
  1066.     JZ     GETNM2
  1067.     CALL     ILPRT
  1068.     DB 'TIME OUT RECEIVING FILENAME',CR,LF,0
  1069. GETNM2    JMP     GCKSER
  1070. GETNM3    CPI     EOT        ;IF EOT, THEN NO MORE FILES
  1071.     JZ     GNRET
  1072.     CPI     EOFCHAR        ;GOT END OF NAME
  1073.     JZ     ENDNAME
  1074.     MOV     M,A        ;PUT NAME IN FCB
  1075.     LDA     QFLG        ;TYPE IT IF NO QFLG
  1076.     ORA     A
  1077.     MOV     A,M
  1078.     CNZ     TYPE
  1079.     PUSH     B        ;SAVE CKSUM
  1080.     call    txon
  1081.     MVI     A,ACK        ;ACK GETTING LETTER
  1082.     CALL     SEND
  1083.     call    txoff
  1084.     POP     B
  1085.     INX     H        ;GET NEXT CHAR
  1086.     MOV     A,L        ;DON'T LET NOISE...
  1087.     CPI     7FH        ;..CAUSE OVERFLOW..
  1088.     JZ     GCKSER        ;..INTO PROGRAM AREA.
  1089.     JMP     NAMELPG
  1090. ENDNAME    LDA     QFLG
  1091.     ORA     A    
  1092.     CNZ     CRLF
  1093.     call    txon
  1094.     MOV     A,C        ;SEND CHECKSUM
  1095.     CALL     SEND
  1096.     call    txoff
  1097.     MVI     B,2
  1098.     CALL     recvdg        ;CHECKSUM GOOD?
  1099.     CPI     OKNMCH        ;YES IF OKNMCH SENT..
  1100.     JZ     GNRET        ;..ELSE DO OVER.
  1101. GCKSER    LXI     H,FCB        ;CLEAR FCB (EXCEPT DRIVE)..
  1102.     CALL     INITFCBS+2    ;..SINCE IT MIGHT BE DAMAGED..
  1103.     LDA     QFLG        ;..BY TOO MANY CHARS.
  1104.     ORA     A
  1105.     JZ     GCKSER1
  1106.     CALL     ILPRT
  1107.     DB 'CHECKSUM ERROR',CR,LF,0
  1108. GCKSER1    CALL     HSNAK        ;DO HANDSHAKING OVER
  1109.     JC     GCKSER1
  1110.     JMP     GETNM1
  1111. GNRET    POP     H
  1112.     RET
  1113.  
  1114. HSNAK:    call    txon
  1115.     MVI     A,NAK        ;SEND NAK UNTIL..
  1116.     CALL     SEND        ;..RECEIVING ACK.
  1117.     call    txoff
  1118.     CALL     CKABORT        ;DON'T GET HUNG UP HERE
  1119.     MVI     B,5        ;WAIT 2 SECONDS
  1120.     CALL     recvdg        ;..IN RECEIVE
  1121.     CPI     ACK        ;IF ACK,RETURN WITH..
  1122.     RZ            ;..CARRY CLEAR.
  1123.     STC
  1124.     RET
  1125.  
  1126. TNMBUF    MVI    A,FALSE        ;CALL FROM SENDFIL ONLY ONCE.
  1127.     STA    FSTFLG
  1128.     STA    FILECT
  1129.     CALL    SCAN
  1130.     LXI    H,NAMEBUF
  1131.     SHLD    NBSAVE        ;SAVE ADDR OF 1ST NAME
  1132. TNLP1    CALL    TRTOBUF
  1133.     LXI    H,FCB
  1134.     LXI    D,FCBBUF
  1135.     CALL    CPMLINE        ;PARSE NAME TO CP/M FORMAT
  1136. TNLP2    CALL    MFNAME        ;SEARCH FOR NAMES (* FORMAT)
  1137.     JC    NEXTNM
  1138.     LDA    FCB+10        ;IF CP/M 2 $SYS FILE..
  1139.     ANI    80H        ;..DON'T SEND
  1140.     JNZ    TNLP2
  1141.     LHLD    NBSAVE        ;GET NAME
  1142.     LXI    D,FCB        ;MOVE IT TO FCB
  1143.     XCHG
  1144.     MVI    B,12
  1145.     CALL    MOVE
  1146.     XCHG
  1147.     SHLD    NBSAVE        ;ADDR OF NEXT NAME
  1148.     LXI    H,FILECT    ;COUNT FILES FOUND
  1149.     INR    M
  1150.     JMP    TNLP2
  1151. NEXTNM    LXI    H,NAMECT    ;COUNT NAMES FOUND
  1152.     DCR    M
  1153.     JNZ    TNLP1
  1154.     LXI    H,NAMEBUF    ;SAVE START OF BUFFER
  1155.     SHLD    NBSAVE
  1156.     LDA    FILECT
  1157.     CPI    65        ;NO MORE THAN 64 TRANSFERS
  1158.     RC
  1159.     MVI    A,64        ;ONLY X'FER FIRST 64
  1160.     STA    FILECT
  1161.     RET
  1162.  
  1163. ;SCANS CMDBUF COUNTING NAMES AND PUTTING DELIMITER (SPACE)
  1164. ;AFTER LAST NAME
  1165.  
  1166. SCAN    PUSH     H
  1167.     LXI     H,NAMECT
  1168.     MVI     M,0
  1169.     LXI     H,CMDBUF+1    ;FIND END OF CMD LINE..
  1170.     MOV     C,M        ;..AND PUT SPACE THERE.
  1171.     MVI     B,0
  1172.     LXI     H,CMDBUF+2
  1173.     DAD     B
  1174.     MVI     M,20H
  1175.     LXI     H,CMDBUF+1
  1176.     MOV     B,M
  1177.     INR     B
  1178.     INR     B
  1179. SCANLP1    INX     H
  1180.     DCR     B
  1181.     JZ     DNSCAN
  1182.     MOV     A,M
  1183.     CPI     20H
  1184.     JNZ     SCANLP1
  1185. SCANLP2    INX     H        ;EAT EXTRA SPACES
  1186.     DCR     B
  1187.     JZ     DNSCAN
  1188.     MOV     A,M
  1189.     CPI     20H
  1190.     JZ     SCANLP2
  1191.     SHLD     BGNMS        ;SAVE START OF NAMES IN CMDBUF
  1192.     INR     B
  1193.     DCX     H
  1194. SCANLP3    INX     H
  1195.     DCR     B
  1196.     JZ     DNSCAN
  1197.     MOV     A,M
  1198.     CPI     20H
  1199.     JNZ     SCANLP3
  1200.     LDA     NAMECT        ;COUNTS NAMES
  1201.     INR     A
  1202.     STA     NAMECT
  1203. SCANLP4    INX     H        ;EAT SPACES
  1204.     DCR     B
  1205.     JZ     DNSCAN
  1206.     MOV     A,M
  1207.     CPI     20H
  1208.     JZ     SCANLP4
  1209.     JMP     SCANLP3
  1210. DNSCAN    MVI     M,20H        ;SPACE AFTER LAST CHAR
  1211.     POP     H
  1212.     RET
  1213.  
  1214. ;PLACES NEXT NAME IN BUFFER SO CPMLINE MAY PARSE IT
  1215.  
  1216. TRTOBUF    LHLD    BGNMS
  1217.     MVI    B,0
  1218.     LXI    D,FCBBUF+2
  1219. TBLP    MOV    A,M
  1220.     CPI    20H
  1221.     JZ    TRBFEND
  1222.     STAX    D
  1223.     INX    H
  1224.     INX    D
  1225.     INR    B        ;COUNT CHARS IN NAME
  1226.     JMP    TBLP
  1227. TRBFEND    INX    H
  1228.     MOV    A,M        ;EAT EXTRA SPACES
  1229.     CPI    20H
  1230.     JZ    TRBFEND
  1231.     SHLD    BGNMS
  1232.     LXI     H,FCBBUF+1    ;PUT # CHARS BEFORE NAME
  1233.     MOV     M,B
  1234.     RET
  1235.  
  1236. ;IN CP/M V.2, IF FILE IS R/O OR SYS, IT IS CHANGED TO 'BAK'.
  1237.  
  1238. CKCPM2    MVI    C,12
  1239.     CALL    BDOS
  1240.     ORA    A        ;RETURN 0 MEANS CP/M 1
  1241.     RZ
  1242.     MVI    C,STDMA
  1243.     LXI    D,80H
  1244.     CALL    BDOS
  1245.     MVI    C,SRCHF        ;SEARCH FOR FILE
  1246.     LXI    D,FCB
  1247.     CALL    BDOS
  1248.     CPI    0FFH
  1249.     RZ
  1250.     ADD A ! ADD A        ;MULT A-REG BY..
  1251.     ADD A ! ADD A        ;..32 TO FIND..
  1252.     ADD    A        ;..NAME IN DMA.
  1253.     LXI    H,80H
  1254.     ADD    L
  1255.     MOV    L,A        ;HL POINTS TO DIR NAME
  1256.     LXI    D,9
  1257.     DAD    D        ;POINT TO R/O ATTRIB BYTE
  1258.     MOV    A,M
  1259.     ANI    80H        ;TEST MSB
  1260.     JNZ    MKCHG        ;IF SET, MAKE CHANGE
  1261.     INX    H        ;CHECK SYSTEM ATTRIB BYTE
  1262.     MOV    A,M
  1263.     ANI    80H
  1264.     RZ            ;NOT $SYS OR $R/O
  1265.     DCX    H
  1266. MKCHG    LXI    D,-8
  1267.     DAD    D        ;POINT HL TO FILENAME + 1
  1268.     LXI    D,FCB+1        ;MOVE DIR NAME TO FCB..
  1269.     MVI    B,11        ;..WITHOUT CHANGING DRIVE.
  1270.     CALL    MOVE
  1271.     LXI    H,FCB+9        ;R/O ATTRIB
  1272.     MOV    A,M
  1273.     ANI    7FH        ;STRIP R/O ATTRIB
  1274.     MOV    M,A
  1275.     INX    H        ;SYS ATTRIB
  1276.     MOV    A,M
  1277.     ANI    7FH
  1278.     MOV    M,A
  1279.     LXI    D,FCB
  1280.     MVI    C,30        ;SET NEW ATTRIBS IN DIR
  1281.     CALL    BDOS
  1282.  
  1283. ;MAY BE CALLED BY CKBAKUP BELOW. ITS RETURN DONE HERE
  1284.  
  1285. PLANCHG    LXI    H,FCB        ;CHANGE NAME TO TYPE "BAK"
  1286.     LXI    D,6CH
  1287.     MVI    B,9        ;MOVE DRIVE AND NAME (NOT TYPE)
  1288.     CALL    MOVE
  1289.     LXI    H,75H        ;START OF TYPE IN FCB2
  1290.     MVI    M,'B'
  1291.     INX    H
  1292.     MVI    M,'A'
  1293.     INX    H
  1294.     MVI    M,'K'
  1295.     LXI    D,6CH
  1296.     MVI    C,ERASE        ;ERASE ANY PREV BACKUPS
  1297.     CALL    BDOS
  1298.     LXI    H,6CH        ;FCB2 DR FIELD SHOULD..
  1299.     MVI    M,0        ;..0 FOR RENAME.
  1300.     LXI    D,FCB
  1301.     MVI    C,23        ;RENAME
  1302.     CALL    BDOS
  1303.     RET
  1304.  
  1305. CKBAKUP    LDA    BAKUPBYTE
  1306.     ORA    A
  1307.     RZ
  1308.     MVI    C,SRCHF
  1309.     LXI    D,FCB
  1310.     CALL    BDOS
  1311.     INR    A
  1312.     RZ            ;FILE NOT FOUND
  1313.     JMP    PLANCHG        ;IN "CKCPM2" - RET DONE THERE
  1314.  
  1315. ;MULTI-FILE ACCESS SUBROUTINE FROM CP/M USER'S GROUP
  1316. ;FIXED BY MARK ZEIGER 8/17/80
  1317. ;CARRY IS SET IF NO MORE NAMES CAN BE FOUND
  1318.  
  1319. MFNAME    MFACCESS    ;A MACRO IN MACROS.LIB
  1320.  
  1321.  
  1322. RCVSECT    XRA    A
  1323.     STA    ERRCT
  1324. RCVRPT:    LDA    QFLG
  1325.     ORA    A
  1326.     JZ    RCVSQ
  1327.     CALL    ILPRT
  1328.     DB    CR,'AWAITING # ',0
  1329.     PUSH    H        ;SAVE IT
  1330.     LHLD    SECTNO        ;GET SECTOR NUMBER
  1331.     INX    H        ;BUMP IT
  1332.     CALL    DECOUT        ;PRINT SECTOR NUMBER IN DECIMAL
  1333.     CALL    ILPRT
  1334.     DB    ' (', 0
  1335.     CALL    DHXOUT        ;16 BIT HEX CONVERSION & OUTPUT
  1336.     CALL    ILPRT
  1337.     DB    'H)',0
  1338.     MOV    A,L        ;ONLY THE LOW BYTE IS USED BY THE PROGRAM
  1339.     POP    H        ;RESTORE IT
  1340. ;
  1341. RCVSQ:    MVI    B,2
  1342.     CALL    RECV
  1343.     JC    RCVSTOT
  1344.     CPI    SOH
  1345.     JZ    RCVSOH
  1346.     ORA    A
  1347.     JZ    RCVSQ
  1348.     CPI    EOT
  1349.     STC
  1350.     RZ
  1351.     MOV    B,A
  1352.     LDA    VSEEFLG
  1353.     ORA    A
  1354.     JZ    RCVSEH
  1355.     LDA    QFLG
  1356.     ORA    A
  1357.     JZ    RCVSERR
  1358.  
  1359. RCVSEH    call    ilprt
  1360.     db    cr,lf,0
  1361.     MOV    A,B
  1362.     CALL    HEXO
  1363.     CALL    ILPRT
  1364.     DB    'H RCD, NOT SOH',CR,LF,0
  1365.  
  1366. RCVSERR    MVI    B,1
  1367.     CALL    RECV
  1368.     JNC    RCVSERR
  1369.     call    txon
  1370.     MVI    A,NAK
  1371.     CALL    SEND
  1372.     call    txoff
  1373.     LDA    ERRCT
  1374.     INR    A
  1375.     STA    ERRCT
  1376.     CPI    ERRLIM
  1377.     JC    RCVRPT
  1378.     LDA    VSEEFLG
  1379.     ORA    A
  1380.     JZ    RCVCKQ
  1381.     LDA    QFLG
  1382.     ORA    A
  1383.     JZ    RCVSABT
  1384. RCVCKQ    CALL    CKQUIT
  1385.     JZ    RCVSECT
  1386. RCVSABT    CALL    CLOSFIL
  1387.     CALL    ERXIT
  1388.     DB CR,LF,'++    UNABLE TO RECEIVE BLOCK     --  ABORTING ++',CR,LF,'$'
  1389.  
  1390. RCVSTOT    LDA    VSEEFLG
  1391.     ORA    A
  1392.     JZ    RCVSPT
  1393.     LDA    QFLG
  1394.     ORA    A
  1395.     JZ    RCVSERR
  1396. RCVSPT    CALL    ILPRT
  1397.         DB    CR,LF,'++  TIMEOUT ++ ',0
  1398. RCVPRN    LDA    ERRCT
  1399.     CALL    HEXO
  1400.     CALL    CRLF
  1401.     JMP    RCVSERR
  1402.  
  1403. RCVSOH: MVI    B,1
  1404.     CALL    RECV
  1405.     JC    RCVSTOT
  1406.     MOV    D,A
  1407.     MVI    B,1
  1408.     CALL    RECV
  1409.     JC    RCVSTOT
  1410.     CMA
  1411.     CMP    D
  1412.     JZ    RCVDATA
  1413.     LDA    VSEEFLG
  1414.     ORA    A
  1415.     JZ    RCVBSE
  1416.     LDA    QFLG
  1417.     ORA    A
  1418.     JZ    RCVSERR
  1419. RCVBSE    CALL    ILPRT
  1420.         DB    CR,LF,'++  BAD SECTOR # IN HDR',CR,LF,0
  1421.     JMP    RCVSERR
  1422.  
  1423. RCVDATA    MOV    A,D
  1424.     STA    RCVSNO
  1425.     MVI    A,1
  1426.     STA    DATAFLG
  1427.     MVI    C,0
  1428.     call    clrcrc        ;clear crc counter
  1429.     LXI    H,80H
  1430.  
  1431. RCVCHR    MVI    B,1
  1432.     CALL    RECV
  1433.     JC    RCVSTOT
  1434.     MOV    M,A
  1435.     INR    L
  1436.     JNZ    RCVCHR
  1437.     mvi    e,2        ;nr of crc bytes
  1438. rcvcrc    mvi    b,1
  1439.     call    recv
  1440.     jc    rcvstot
  1441.     dcr    e
  1442.     jnz    rcvcrc
  1443.     call    chkcrc
  1444.     ora    a
  1445.     jz    chksnum
  1446.     lda    vseeflg
  1447.     ora    a
  1448.     jz    rcvcrer
  1449.     lda    qflg
  1450.     ora    a
  1451.     jz    rcvserr
  1452. ;
  1453. rcvcrer    call    ilprt
  1454.     db    cr,lf,'++CRC err++ ',0
  1455.     jmp    rcvprn
  1456.  
  1457. chksnum    LDA    RCVSNO
  1458.     MOV    B,A
  1459.     LDA    SECTNO
  1460.     CMP    B
  1461.     JZ    RECVACK
  1462.     INR    A
  1463.     CMP    B
  1464.     JNZ    ABORT
  1465.     RET
  1466.  
  1467. RECVACK    CALL    SENDACK
  1468.     JMP    RCVSECT
  1469.  
  1470. SENDACK:
  1471.     call    txon
  1472.     MVI    A,ACK
  1473.     CALL    SEND
  1474.     call    txoff
  1475.     RET
  1476.  
  1477. ;Transmitter is on when arrive here from SENDRPT
  1478.  
  1479. SENDHDR    LDA    QFLG
  1480.     ORA    A
  1481.     JZ    SENDHNM
  1482.     CALL    ILPRT
  1483.         DB    CR,'SEND # ',0
  1484.     PUSH    H
  1485.     LHLD    SECTNO        ;GET SECTOR NUMBER
  1486.     CALL    DECOUT        ;PRINT IT IN DECIMAL
  1487.     CALL    ILPRT
  1488.     DB    '  (',0
  1489.     CALL    DHXOUT        ;16 BIT HEX CONVERSION & OUTPUT
  1490.     CALL    ILPRT
  1491.     DB    'H)',0
  1492.     POP    H
  1493. SENDHNM    MVI    A,SOH
  1494.     CALL    SEND
  1495.     LDA    SECTNO
  1496.     CALL    SEND
  1497.     LDA    SECTNO
  1498.     CMA
  1499.     CALL    SEND
  1500.     RET
  1501.  
  1502. SENDSEC    MVI    A,1
  1503.     STA    DATAFLG
  1504.     MVI    C,0
  1505.     call    clrcrc
  1506.     LXI    H,80H
  1507. SENDC    MOV    A,M
  1508.     CALL    SEND
  1509.     INR    L
  1510.     JNZ    SENDC
  1511.     XRA    A
  1512.     STA    DATAFLG
  1513.     RET
  1514. ;
  1515. sendcrc    call    fincrc
  1516.     mov    a,d
  1517.     call    send
  1518.     mov    a,e
  1519.     call    send
  1520.     xra    a
  1521.     ret
  1522. ;
  1523. ;Transmitter turned of after return to SENDRPT
  1524. ;
  1525. GETACK    MVI    B,7
  1526.     CALL    RECVDG
  1527.     JC    GETATOT
  1528.     CPI    ACK
  1529.     RZ
  1530.     MOV    B,A
  1531.     LDA    QFLG
  1532.     ORA    A
  1533.     JZ    ACKERR
  1534.     CALL    ILPRT
  1535.     DB    CR,LF,0
  1536.     MOV    A,B
  1537.     CALL    HEXO
  1538.     CALL    ILPRT
  1539.         DB    'H RCD, NOT ACK',CR,LF,0
  1540. ACKERR    LDA    ERRCT
  1541.     INR    A
  1542.     STA    ERRCT
  1543.     CPI    ERRLIM
  1544.     RC
  1545.     LDA    VSEEFLG
  1546.     ORA    A
  1547.     JZ    GACKV
  1548.     LDA    QFLG
  1549.     ORA    A
  1550.     JZ    CSABORT
  1551. GACKV    CALL    CKQUIT
  1552.     STC
  1553.     RZ
  1554. CSABORT    CALL    ERXIT
  1555.     DB    CR,LF,'CAN''T SEND SECTOR -- ABORTING',CR,LF,'$'
  1556.  
  1557. GETATOT    LDA    QFLG
  1558.     ORA    A
  1559.     JZ    ACKERR
  1560.     CALL    ILPRT
  1561.         DB    CR,LF,'TIMEOUT ON ACK',CR,LF,0
  1562.     JMP    ACKERR
  1563.  
  1564. CKABORT:    
  1565.     CALL     STAT
  1566.     RZ
  1567.     CALL     KEYIN
  1568.     CPI     CAN
  1569.     RNZ
  1570.  
  1571. ABORT    LXI     SP,STACK
  1572. ABORTL    MVI     B,1
  1573.     CALL     RECV
  1574.     JNC     ABORTL
  1575.     call    txon
  1576.     MVI     A,CAN
  1577.     CALL     SEND
  1578.     call    txoff
  1579. ABORTW    MVI     B,1
  1580.     CALL     RECV
  1581.     JNC     ABORTW
  1582.     call    txon
  1583.     MVI     A,' '
  1584.     CALL     SEND
  1585.     call    txoff
  1586.     CALL     ILPRT
  1587.         DB CR,LF,'ROUTINE CANCELLED',CR,LF,BELL,0
  1588.     MVI     A,'B'        ;TURN MULTI-FILE MODE..
  1589.     STA     BATCHFLG    ;..OFF SO ROUTINE ENDS.
  1590.     JMP     DONETCE
  1591.  
  1592. INCRSNO    PUSH    H
  1593.     LHLD    SECTNO        ;GET SECTOR NUMBER
  1594.     INX    H        ;BUMP IT
  1595.     SHLD    SECTNO        ;STORE IT
  1596.     MOV    A,L
  1597.     POP    H
  1598.     RET
  1599.  
  1600. ERASFIL    LDA     BATCHFLG    ;DON'T ASK FOR ERASE..
  1601.     ORA     A        ;..IN MULTI-FILE MODE,..
  1602.     JZ     NOASK        ;..JUST DO IT.
  1603.     LXI     D,FCB
  1604.     MVI     C,SRCHF
  1605.     CALL     BDOS
  1606.     INR     A
  1607.     RZ
  1608.     CALL     ILPRT
  1609.         DB 'FILES EXISTS -- TYPE ''Y'' TO ERASE: ',BELL,0
  1610.     CALL     KEYIN
  1611.     PUSH     PSW
  1612.     CALL     TYPE
  1613.     POP     PSW
  1614.     CALL     UCASE
  1615.     CPI     'Y'
  1616.     JNZ     MENU
  1617.     CALL     CRLF
  1618.  
  1619. NOASK    LXI     D,FCB
  1620.     MVI     C,ERASE
  1621.     CALL     BDOS
  1622.     RET
  1623.  
  1624. BLKFILE    CALL     ILPRT    ;ROUTINE IF NO FILE IS NAMED FOR "SEND" OR "RECEIVE"
  1625.     DB CR,LF,'No file specified',CR,LF,BELL,0
  1626.     JMP     MENU
  1627.  
  1628. MAKEFIL    LXI     D,FCB
  1629.     MVI     C,MAKE
  1630.     CALL     BDOS
  1631.     INR     A
  1632.     RNZ
  1633.     CALL     ERXIT
  1634.     DB 'ERROR - CAN''T MAKE FILE',CR,LF
  1635.     DB 'DIRECTORY MUST BE FULL',CR,LF,'$'
  1636.  
  1637. CNREC:    MVI    C,FILSIZ    ;COMPUTE FILE SIZE FUNCTION IN CP/M 2.x
  1638.     LXI    D,FCB        ;POINT TO FILE CONTROL BLOCK
  1639.     CALL    BDOS
  1640.     LHLD    FCB+33        ;GET RECORD COUNT
  1641.     SHLD    RCNT        ;STORE IT
  1642.     LXI    H,0        ;ZERO HL
  1643.     SHLD    FCB+33        ;RESET RANDOM RECORD IN FCB
  1644.     RET
  1645.  
  1646. OPENFIL    LXI     D,FCB
  1647.     MVI     C,OPEN
  1648.     CALL     BDOS        
  1649.     INR     A
  1650.     JNZ     OPENOK
  1651.     CALL     ERXIT
  1652.     DB 'CAN''T OPEN FILE$'
  1653.  
  1654. OPENOK    LDA     BATCHFLG
  1655.     ORA     A
  1656.     JNZ     OPENOK1
  1657.     LDA     QFLG
  1658.     ORA     A
  1659.     RZ
  1660. OPENOK1    CALL     ILPRT
  1661.     DB    'FILE OPEN, SIZE: ',0
  1662.     LHLD    RCNT        ;GET RECORD COUNT
  1663.     CALL    DECOUT        ;PRINT NUMBER OF SECTORS IN DECIMAL
  1664.     CALL    ILPRT        ;PRINT
  1665.     DB    ' (',0
  1666.     CALL    DHXOUT
  1667.     CALL    ILPRT
  1668.     DB    'H) SECTORS',CR,LF,0
  1669.     RET
  1670.  
  1671. CLOSFIL    LXI     D,FCB
  1672.     MVI     C,CLOSE
  1673.     CALL     BDOS
  1674.     INR     A
  1675.     RNZ
  1676.     CALL     ERXIT
  1677.     DB 'CAN''T CLOSE FILE$'
  1678.  
  1679. RDSECT    LDA     SECINBF
  1680.     DCR     A
  1681.     STA     SECINBF
  1682.     JM     RDBLOCK
  1683.     LHLD     SECPTR
  1684.     LXI     D,80H
  1685.     CALL     MOVE128
  1686.     SHLD     SECPTR
  1687.     RET
  1688.  
  1689. RDBLOCK    LDA     EOFLG
  1690.     CPI     1
  1691.     STC
  1692.     RZ
  1693.     MVI     C,0
  1694.     LXI     D,DBUF
  1695. RDSECLP    PUSH     B
  1696.     PUSH     D
  1697.     MVI     C,STDMA
  1698.     CALL     BDOS
  1699.     LXI     D,FCB
  1700.     MVI     C,READ
  1701.     CALL     BDOS
  1702.     POP     D
  1703.     POP     B
  1704.     ORA     A
  1705.     JZ     RDSECOK
  1706.     DCR     A
  1707.     JZ     REOF
  1708.     CALL     ERXIT
  1709.     DB '++    FILE READ ERROR    ++$'
  1710.  
  1711. RDSECOK    LXI     H,80H
  1712.     DAD     D
  1713.     XCHG
  1714.     INR     C
  1715.     MOV     A,C
  1716.     CPI     DBUFSIZ*8    ;BUFFER SIZE IN 128 BYTE SECTORS
  1717.     JZ     RDBFULL
  1718.     JMP     RDSECLP
  1719. REOF    MVI     A,1
  1720.     STA     EOFLG
  1721.     MOV     A,C
  1722.  
  1723. RDBFULL    STA     SECINBF
  1724.     LXI     H,DBUF
  1725.     SHLD     SECPTR
  1726.     LXI     D,80H
  1727.     MVI     C,STDMA
  1728.     CALL     BDOS
  1729.     JMP     RDSECT
  1730.  
  1731. WRSECT    LHLD     SECPTR
  1732.     XCHG
  1733.     LXI     H,80H
  1734.     CALL     MOVE128
  1735.     XCHG
  1736.     SHLD    SECPTR
  1737.     LDA     SECINBF
  1738.     INR     A
  1739.     STA     SECINBF
  1740.     CPI     DBUFSIZ*8    ;BUFFER SIZE IN 128 BYTE SECTORS
  1741.     RNZ
  1742.  
  1743. WRBLOCK    LDA     SECINBF
  1744.     ORA     A
  1745.     RZ
  1746.     MOV     C,A
  1747.     LXI     D,DBUF
  1748. DKWRLP    PUSH     H
  1749.     PUSH     D
  1750.     PUSH     B
  1751.     MVI     C,STDMA
  1752.     CALL     BDOS
  1753.     LXI     D,FCB
  1754.     MVI     C,WRITE
  1755.     CALL     BDOS
  1756.     POP     B
  1757.     POP     D
  1758.     POP     H
  1759.     ORA     A
  1760.     JNZ     WRERR
  1761.     LXI     H,80H
  1762.     DAD     D
  1763.     XCHG
  1764.     DCR     C
  1765.     JNZ     DKWRLP
  1766.     XRA     A
  1767.     STA     SECINBF
  1768.     LXI     H,DBUF
  1769.     SHLD     SECPTR
  1770.     RET
  1771.  
  1772. WRERR:    call    txon
  1773.     MVI    C,CAN
  1774.     CALL    SEND
  1775.     call    txoff
  1776.     CALL    ERXIT
  1777.     DB    'ERROR WRITING FILE',CR,LF,'$'
  1778.  
  1779. ;---->    RECV: Receive a character
  1780.  
  1781. ;Timeout time is in B, in seconds. Entry via 'RECVDG' deletes garbage
  1782. ;characters on the line. For example, having just sent a sector, calling
  1783. ;RECVDG will delete any line noise induced characters LONG before the
  1784. ;ACK/NAK would be received.
  1785.  
  1786. RECVDG    EQU    $
  1787.     CALL    IN$MODDATP
  1788.     CALL    IN$MODDATP
  1789.  
  1790. RECV    PUSH    D
  1791.     LDA    FASTCLK
  1792.     ORA    A
  1793.     JZ    MSEC
  1794.     MOV    A,B
  1795.     ADD    A
  1796.     MOV    B,A
  1797.  
  1798. MSEC    LXI    D,15000
  1799.     CALL    CKABORT
  1800. MWTI    CALL    IN$MODCTLP
  1801.     CALL    ANI$MODRCVB
  1802.     CALL    CPI$MODRCVR
  1803.     JZ    MCHAR
  1804.     DCR    E
  1805.     JNZ    MWTI
  1806.     DCR    D
  1807.     JNZ    MWTI
  1808.     DCR    B
  1809.     JNZ    MSEC
  1810.     POP    D
  1811.     STC
  1812.     RET
  1813.  
  1814. MCHAR:    CALL    IN$MODDATP
  1815.     POP    D
  1816.     PUSH    PSW
  1817.     call    updcrc        ;calc crc
  1818.     ADD    C
  1819.     MOV    C,A
  1820.     LDA    RSEEFLG
  1821.     ORA    A
  1822.     JZ    MONIN
  1823.     LDA    VSEEFLG
  1824.     ORA    A
  1825.     JNZ    NOMONIN
  1826.     LDA    DATAFLG
  1827.     ORA    A
  1828.     JZ    NOMONIN
  1829. MONIN    POP    PSW
  1830.     PUSH    PSW
  1831.     CALL    SHOW
  1832. NOMONIN    POP    PSW
  1833.     ORA    A
  1834.     RET
  1835.  
  1836. SEND    PUSH    PSW
  1837.     LDA    SSEEFLG
  1838.     ORA    A
  1839.     JZ    MONOUT
  1840.     LDA    VSEEFLG
  1841.     ORA    A
  1842.     JNZ    NOMONOT
  1843.     LDA    DATAFLG
  1844.     ORA    A
  1845.     JZ    NOMONOT
  1846. MONOUT    POP    PSW
  1847.     PUSH    PSW
  1848.     CALL    SHOW
  1849. NOMONOT    POP    PSW
  1850.     PUSH    PSW
  1851.     call    updcrc        ;calc crc
  1852.     ADD    C
  1853.     MOV    C,A
  1854. SENDW    CALL    IN$MODCTLP
  1855.     CALL    ANI$MODSNDB
  1856.     CALL    CPI$MODSNDR
  1857.     JNZ    SENDW
  1858.     POP    PSW
  1859.     CALL    OUT$MODDATP
  1860.     RET
  1861.  
  1862. WAITNAK    LDA    VSEEFLG
  1863.     ORA    A
  1864.     JZ    WAITNPR
  1865.     LDA    QFLG
  1866.     ORA    A
  1867.     JZ    WAITNLP
  1868. WAITNPR    CALL    ILPRT
  1869.         DB    'AWAITING INITIAL NAK',CR,LF,0
  1870. WAITNLP    CALL    CKABORT        ;Now waits indefinetly here. ^X to cancel.
  1871.     MVI    B,2
  1872.     CALL    RECV
  1873.     CPI    NAK
  1874.     RZ
  1875.     JMP    WAITNLP
  1876. ;
  1877. INITADR
  1878.     LHLD     1
  1879.     LXI     D,3
  1880.     DAD     D
  1881.     SHLD     VSTAT+1
  1882.     DAD     D
  1883.     SHLD     VKEYIN+1
  1884.     DAD     D
  1885.     SHLD     VTYPE+1
  1886.     RET
  1887.  
  1888. PROCOPT
  1889.     LXI    D,FCB+1
  1890.     LDAX    D
  1891.     STA    OPTION
  1892. OPTLP    INX    D
  1893.     LDAX    D
  1894.     CPI    ' '
  1895.     JZ    ENDOPT
  1896.     LXI    H,OPTBL
  1897.     MVI    B,OPTBE-OPTBL
  1898. OPTCK    CMP    M
  1899.     JNZ    OPTNO
  1900.     MVI    M,0
  1901.     JMP    OPTLP
  1902. OPTNO    INX    H
  1903.     DCR    B
  1904.     JNZ    OPTCK
  1905.     JMP    BADOPT
  1906.  
  1907. ENDOPT: LDA    VSEEFLG
  1908.     ORA    A
  1909.     RNZ
  1910.     STA    QFLG
  1911.     RET
  1912.  
  1913. DONE:    LDA    BATCHFLG
  1914.     ORA    A
  1915.     JNZ    DONETCC
  1916.     LDA    QFLG
  1917.     ORA    A
  1918.     JZ    NMSTRNS
  1919.     LXI    H,FCB+1        ;PUT FILE NAME IN..
  1920.     LXI    D,FTRNMSG    ;..SPACES IN MESSAGE..
  1921.     MVI    B,8        ;..BELOW.
  1922.     CALL    MOVE
  1923.     INX    D        ;PUT FILE TYPE AFTER..
  1924.     MVI    B,3        ;..SKIPPING ONE SPACE..
  1925.     CALL    MOVE        ;..BELOW.    
  1926.     CALL    ILPRT
  1927.     db '  '            ;Leave a couple of spaces
  1928. FTRNMSG    DB '              TRANSFERRED',CR,LF,CR,LF,0    ;13 SPACES
  1929.  
  1930. NMSTRNS    LDA    FCB        ;SAVE DRIVE NO.
  1931.     STA    DISKNO
  1932.     LXI    H,FCB        ;BLANK OUT FILE CONTROL BLOCKS
  1933.     CALL    INITFCBS
  1934.     LDA    DISKNO        ;PUT DRIVE NUMBER BACK
  1935.     STA    FCB
  1936.     LXI    H,RESTSN    ;RESTORE SECTORE NUMBERS..
  1937.     LXI    D,SECTNOB    ;..FOR NEW FILE TRANSFER.
  1938.     MVI    B,SECTNOE-SECTNOB    ;ROUTINE ALSO DONE IN MENU.
  1939.     CALL    MOVE
  1940.     LDA    SENDFLG        ;GOES TO EITHER SEND OR..
  1941.     ORA    A        ;..RECEIVE FILE, DEPENDING..
  1942.     JNZ    SENDFIL        ;..UPON WHICH ROUTINE SET..
  1943.     JMP    RCVFIL        ;..THE FLAG IN MULTI-FILE MODE.
  1944.  
  1945. DONETCC    MVI    A,TRUE        ;INDICATE NO FILES BEING..
  1946.     STA    FSTFLG        ;RESET MULTIFILE TRANS
  1947.     STA    NFILFLG        ;..USED IN TERMINAL ROUTINE.
  1948.     CMA
  1949.     STA    SAVEFLG        ;STOP MEMORY SAVE IN TERM ROUTINE.
  1950.     LDA    VSEEFLG
  1951.     ORA    A
  1952.     JZ    DONETC
  1953.     LDA    QFLG
  1954.     ORA    A
  1955.     JZ    donetce
  1956. DONETC    CALL    ILPRT
  1957.         DB    CR,LF,'ALL TRANSFERS COMPLETED'
  1958.     DB    CR,LF,BELL,0
  1959. DONETCE:
  1960.     LDA    TERMFLG        ;SEE IF RETURN TO..
  1961.     ORA    A        ;..TERMINAL MODE..
  1962.     JNZ    MENU        ;..AFTER X'FER.
  1963.     CALL    CRLF
  1964.     JMP    termint
  1965.  
  1966.  
  1967. MOVEFCB    LXI     H,FCB+16
  1968.     LXI     D,FCB
  1969.     MVI     B,16
  1970.     CALL     MOVE
  1971.     XRA     A
  1972.     STA     FCBSNO
  1973.     STA     FCBEXT
  1974.     RET
  1975.  
  1976. SHOW    CPI     LF
  1977.     JZ     CTYPE
  1978.     CPI     CR
  1979.     JZ     CTYPE
  1980.     CPI     9
  1981.     JZ     CTYPE
  1982.     CPI     ' '
  1983.     JC     SHOWHEX
  1984.     CPI     7FH
  1985.     JC     CTYPE
  1986. SHOWHEX    PUSH     PSW
  1987.     MVI     A,'('
  1988.     CALL     CTYPE
  1989.     POP     PSW
  1990.     CALL     HEXO
  1991.     MVI     A,')'
  1992.     JMP     CTYPE
  1993.  
  1994. CTYPE    PUSH     B
  1995.     PUSH     D
  1996.     PUSH     H
  1997.     MOV     E,A
  1998.     MVI     C,WRCON
  1999.     CALL     BDOS
  2000.     POP     H
  2001.     POP     D
  2002.     POP     B
  2003.     RET
  2004.  
  2005. CRLF    PUSH     PSW
  2006.     MVI     A,CR
  2007.     CALL     TYPE
  2008.     MVI     A,LF
  2009.     CALL     TYPE
  2010.     POP     PSW
  2011.     RET
  2012.  
  2013. TYPE    PUSH     PSW
  2014.     PUSH     B
  2015.     PUSH     D
  2016.     PUSH     H
  2017.     MOV     C,A
  2018. VTYPE    CALL     $-$
  2019.     POP     H
  2020.     POP     D
  2021.     POP     B
  2022.     POP     PSW
  2023.     RET
  2024.  
  2025. STAT    PUSH     B
  2026.     PUSH     D
  2027.     PUSH     H
  2028. VSTAT    CALL     $-$
  2029.     POP     H
  2030.     POP     D
  2031.     POP     B
  2032.     ORA     A
  2033.     RET
  2034.  
  2035. KEYIN    PUSH     B
  2036.     PUSH     D
  2037.     PUSH     H
  2038. VKEYIN    CALL     $-$
  2039.     POP     H
  2040.     POP     D
  2041.     POP     B
  2042.     RET
  2043.  
  2044. UCASE    CPI     61H        ;CHANGES LOWER CASE CHARACTER..
  2045.     RC            ;..IN A-REG TO UPPER CASE.
  2046.     CPI     7BH
  2047.     RNC
  2048.     ANI     5FH
  2049.     RET
  2050.  
  2051. DECOUT:    PUSH    PSW
  2052.     PUSH    B
  2053.     PUSH    D
  2054.     PUSH    H
  2055.     LXI    B,-10
  2056.     LXI    D,-1
  2057.  
  2058. DECOU2:    DAD    B
  2059.     INX    D
  2060.     JC    DECOU2
  2061.     LXI    B,10
  2062.     DAD    B
  2063.     XCHG
  2064.     MOV    A,H
  2065.     ORA    L
  2066.     CNZ    DECOUT
  2067.     MOV    A,E
  2068.     ADI    '0'
  2069.     CALL    CTYPE
  2070.     POP    H
  2071.     POP    D
  2072.     POP    B
  2073.     POP    PSW
  2074.     RET
  2075.  
  2076. ;---->    DHXOUT: - double precision hex output routine.
  2077.  
  2078. DHXOUT:    PUSH    H
  2079.     PUSH    PSW
  2080.     MOV    A,H        ;GET MS BYTE
  2081.     CALL    HEXO        ;OUTPUT HIGH ORDER BYTE
  2082.     MOV    A,L        ;GET LS BYTE
  2083.     CALL    HEXO        ;OUTPUT LOW ORDER BYTE
  2084.     POP    PSW
  2085.     POP    H
  2086.     RET
  2087.  
  2088. HEXO    PUSH     PSW
  2089.     RAR
  2090.     RAR
  2091.     RAR
  2092.     RAR
  2093.     CALL     NIBBL
  2094.     POP     PSW
  2095. NIBBL    ANI     0FH
  2096.     CPI     10
  2097.     JC     ISNUM
  2098.     ADI     7
  2099. ISNUM    ADI     '0'
  2100.     JMP     TYPE
  2101.  
  2102. ;RETURNS W/ ZERO SET IF RETRY ASKED. IF MULTI-FILE MODE, THEN
  2103. ;NO QUESTIONS ASKED, JUST QUIT
  2104.  
  2105. CKQUIT    LDA     BATCHFLG
  2106.     ORA     A
  2107.     JNZ     CKQTASK        ;ASK FOR RETRY
  2108.     INR     A        ;RESET ZERO FLG
  2109.     RET
  2110. CKQTASK    XRA    A
  2111.     STA    ERRCT
  2112.     CALL    ILPRT
  2113.         DB    'MULTIPLE ERRORS ENCOUNTERED.',CR,LF
  2114.         DB    'TYPE Q TO QUIT, R TO RETRY:  ',BELL,0
  2115.     CALL    KEYIN
  2116.     PUSH    PSW
  2117.     CALL    CRLF
  2118.     POP    PSW
  2119.     CALL    UCASE        ;INSTEAD OF "ANI 5FH"
  2120.     CPI    'R'
  2121.     RZ
  2122.     CPI    'Q'
  2123.     JNZ    CKQUIT
  2124.     ORA    A
  2125.     RET
  2126.  
  2127. ILPRT    XTHL
  2128. ILPLP    MOV     A,M
  2129.     ORA     A
  2130.     JZ     ILPRET
  2131.     CALL     CTYPE
  2132.     INX     H
  2133.     JMP     ILPLP
  2134. ILPRET    XTHL
  2135.     RET
  2136.  
  2137. PRTMSG    MVI     C,PRINT
  2138.     JMP     BDOS
  2139.  
  2140. ERXIT    POP    D
  2141.     CALL    PRTMSG
  2142.     CALL    ILPRT
  2143.     DB    BELL,0
  2144.     LDA    BATCHFLG
  2145.     ORA    A
  2146.     JNZ    DONETCE
  2147.     MVI    A,'Q'        ;RESET QFLG
  2148.     STA    QFLG
  2149.     JMP    ABORT        ;ABORT OTHER COMPUTER
  2150.  
  2151. EXIT    LXI     D,80H
  2152.     MVI     C,STDMA
  2153.     CALL     BDOS
  2154.     JMP     0
  2155.  
  2156. MOVE128    MVI     B,128
  2157. MOVE    MOV     A,M
  2158.     STAX     D
  2159.     INX     H
  2160.     INX     D
  2161.     DCR     B
  2162.     JNZ     MOVE
  2163.     RET
  2164.  
  2165.  
  2166. ;INITIALIZES CP/M FILE CONTROL BLOCKS AT 5CH AND 6CH
  2167.  
  2168. SETFCB    LXI     D,CMDBUF
  2169.     LXI     H,FCB
  2170.     CALL     CPMLINE
  2171.     CALL     PROCOPT
  2172.  
  2173. CHECKNM    LDA    FCB+1        ;CHECK ON THE PRIMARY OPTION
  2174.     CPI    'M'        ;RETURN TO MENU
  2175.     RZ
  2176.     CPI    'T'
  2177.     JZ    TERMSEL
  2178.     CPI    'S'
  2179.     JZ    CKFILE
  2180.     CPI    'R'
  2181.     JNZ    BDOPT
  2182.     LDA    BATCHFLG    ;IF MULT FILE MODE, THEN..
  2183.     ORA    A        ;..RECV OPT DOES NOT NEED..
  2184.     RZ            ;..NAME.
  2185.     JMP    CKFILE
  2186. BDOPT    CALL    ILPRT
  2187.     DB    CR,LF,'++Bad Option++',CR,LF,0
  2188.     JMP    REENT
  2189. CKFILE    LDA    FCB+17        ;IF OPTION THAT NEEDS FILE NAME,..
  2190.     CPI    ' '        ;..THEN CHECK TO SEE IF NAME..
  2191.     RNZ            ;..EXISTS. IF NOT..
  2192. REENT    CALL    ILPRT        ;..DO EVERYTHING OVER.
  2193.         DB CR,LF,'Re-enter PRIMARY option and file name only: ',BELL,0
  2194.     LXI    D,CMDBUF
  2195.     CALL    INBUFF
  2196.     JMP    SETFCB
  2197.  
  2198. TERMSEL    LDA    FCB+17
  2199.     CPI    ' '
  2200.     JNZ    SAVAGN
  2201.     MVI    A,FALSE
  2202.     STA    SAVEFLG
  2203.     MVI    A,TRUE
  2204.     STA    NFILFLG
  2205.     CMA
  2206.     RET
  2207.  
  2208. SAVAGN    MVI    A,FALSE
  2209.     STA    NFILFLG
  2210.     RET
  2211.  
  2212. ;
  2213. ;************************************************************************
  2214. ;* CRCSUBS (Cyclic Redundancy Code Subroutines) version 1.20        *
  2215. ;* 8080 Mnemonics                            *
  2216. ;*                                    *
  2217. ;*         These subroutines will compute and check a true 16-bit        *
  2218. ;*    Cyclic Redundancy Code for a message of arbitrary length.    *
  2219. ;*                                    *
  2220. ;*    The  use  of this scheme will guarantee detection of all    *
  2221. ;*    single and double bit errors, all  errors  with  an  odd    *
  2222. ;*    number  of  error bits, all burst errors of length 16 or    *
  2223. ;*    less, 99.9969% of all 17-bit error bursts, and  99.9984%    *
  2224. ;*    of  all  possible  longer  error bursts.  (Ref: Computer    *
  2225. ;*    Networks, Andrew S.  Tanenbaum, Prentiss-Hall, 1981)        *
  2226. ;*                                    *
  2227. ;*    Designed & coded by Paul Hansknecht, June 13, 1981        *
  2228. ;*                                    *
  2229. ;*    Copyright (c) 1981, Carpenter Associates            *
  2230. ;*                Box 451                    *
  2231. ;*                Bloomfield Hills, MI 48013            *
  2232. ;*                313/855-3074                *
  2233. ;*                                    *
  2234. ;*    This program may be freely reproduced for non-profit use.    *
  2235. ;*                                    *
  2236. ;************************************************************************
  2237. ;
  2238. ;    ENTRY    CLRCRC,UPDCRC,FINCRC,CHKCRC
  2239. ;
  2240. CLRCRC:    EQU    $        ; Reset CRC Accumulator for a new message.
  2241.     PUSH    H
  2242.     LXI    H,0
  2243.     SHLD    CRCVAL
  2244.     POP    H
  2245.     RET
  2246. ;
  2247. UPDCRC:    EQU    $        ; Update CRC Accumulator using byte in (A).
  2248.     PUSH    PSW
  2249.     PUSH    B
  2250.     PUSH    H
  2251.     MVI    B,8
  2252.     MOV    C,A
  2253.     LHLD    CRCVAL
  2254. ;
  2255. UPDLOOP:MOV    A,C
  2256.     RLC
  2257.     MOV    C,A
  2258.     MOV    A,L
  2259.     RAL
  2260.     MOV    L,A
  2261.     MOV    A,H
  2262.     RAL
  2263.     MOV    H,A
  2264.     JNC    SKIPIT
  2265.     MOV    A,H        ; The generator is X^16 + X^12 + X^5 + 1
  2266.     XRI    10H        ; as recommended by CCITT.
  2267.     MOV    H,A        ; An alternate generator which is often
  2268.     MOV    A,L        ; used in synchronous transmission protocols
  2269.     XRI    21H        ; is X^16 + X^15 + X^2 + 1. This may be
  2270.     MOV    L,A        ; used by substituting XOR 80H for XOR 10H
  2271. SKIPIT:    DCR    B        ; and XOR 05H for XOR 21H in the adjacent code.
  2272.     JNZ    UPDLOOP
  2273.     SHLD    CRCVAL
  2274.     POP    H
  2275.     POP    B
  2276.     POP    PSW
  2277.     RET
  2278. ;
  2279. FINCRC:    EQU    $        ; Finish CRC calc for outbound message.
  2280.     PUSH    PSW
  2281.     XRA    A
  2282.     CALL    UPDCRC
  2283.     CALL    UPDCRC
  2284.     PUSH    H
  2285.     LHLD    CRCVAL
  2286.     MOV    D,H
  2287.     MOV    E,L
  2288.     POP    H
  2289.     POP    PSW
  2290.     RET
  2291. ;
  2292. CHKCRC:    EQU    $        ; Check CRC bytes of received message.
  2293.     PUSH    H
  2294.     LHLD    CRCVAL
  2295.     MOV    A,H
  2296.     ORA    L
  2297.     POP    H
  2298.     RZ
  2299.     MVI    A,0FFh
  2300.     RET
  2301. ;
  2302. CRCVAL:    DW    0
  2303. ;
  2304. MENU:    LXI    H,RESTSN    ;RESTORE SECTORE NUMBERS..
  2305.     LXI    D,SECTNOB    ;..FOR NEW FILE TRANSFER.
  2306.     MVI    B,SECTNOE-SECTNOB
  2307.     CALL    MOVE
  2308.     LXI    H,RESTROPT    ;RESTORE OPTION TABLE
  2309.     LXI    D,OPTBL
  2310.     MVI    B,OPTBE-OPTBL
  2311.     CALL    MOVE
  2312.     MVI    A,0
  2313.     STA    MFFLG1        ;RESET MFACCESS ROUTINE..
  2314.     CMA            ;..AND MULTI TRANS IN CASE..
  2315.     STA    FSTFLG        ;..OF ABORT.
  2316.  
  2317. MENU1:    LDA    XPRFLG        ;TEST IF MENU SHOULD BE SHOWN
  2318.     ORA    A
  2319.     JNZ    XPRT
  2320. MENU2:    CALL    ILPRT
  2321.     DB    CR,LF,CR,LF,0
  2322.  
  2323.     if    h19term
  2324.     call    ilprt
  2325.     db    esc,'E',0    ;Clear screen
  2326.     endif
  2327.  
  2328.     call    ilprt
  2329.     db    '*PRIMARY OPTIONS*                        *SECONDARY OPTIONS*'
  2330.     db    cr,lf,lf
  2331.     DB     'WRT- Write file to disk(terminal mode)   '
  2332.     db    'B- Multi file transfer(send or recv)',cr,lf
  2333.     DB     'DEL- Erase present file(terminal mode)   '
  2334.     db    'T- Return to Terminal after transfer',cr,lf
  2335.     DB     'RET- Return to terminal mode(save data)  '
  2336.     db    'Q- Quiet transfer(fatal messages only)',cr,lf
  2337.     DB    'XPR- Toggle expert mode (Menu on/off)    '
  2338.     db    'V- View what is sent and received',cr,lf
  2339.     DB    'DIR- List directory(may specify drive)   '
  2340.     db    'S- View what is sent during transfer',cr,lf
  2341.     DB    'CPM- Exit to CP/M                        '
  2342.     db    'R- View what is rcvd during transfer',cr,lf
  2343.     DB    'S  - Send CP/M file',CR,LF
  2344.     DB    'R  - Receive CP/M file',CR,LF
  2345.     DB    'T  - Terminal mode (optional file name)',CR,LF,lf
  2346.     db    '*TERMINAL MODE FUNCTIONS*',cr,lf,lf
  2347.  
  2348.     if      h19term
  2349.     db    'f1 Key   - Transmit CWID',cr,lf
  2350.     db    'f2 Key   - Send a line (Press f2 first, enter up to 80'
  2351.     db    ' characters then press CR)',cr,lf
  2352.     db    'f3 Key   - Initiate blind file transfer',cr,LF
  2353.     db    'f4 Key   - Toggle file save mode(File previously named'
  2354.     db    ' at "T")',cr,lf
  2355.     db    'f5 Key   - Exit terminal mode',cr,lf
  2356.     db    'Blue Key - Transmitter OFF',cr,lf
  2357.     db     'Red Key  - Transmitter ON',cr,lf
  2358.     db    'White Key- Transmitter ON, automatic OFF on CR',cr,0
  2359.     endif
  2360.  
  2361.     if not    h19term
  2362.     db    '^E   - Exit terminal mode',cr,lf
  2363.     db    '^Y   - Toggle file save mode(File previously named'
  2364.     db    ' at "T")',cr,lf
  2365.     db    '^T   - Initiate blind file transfer',cr,LF
  2366.     db    'ESC S- Transmit CWID',cr,lf
  2367.     db    'ESC T- Send a line (Enter ESC T first, enter up to 80'
  2368.     db    ' characters then press CR)',cr,lf
  2369.     db    'ESC P- Transmitter OFF',cr,lf
  2370.     db     'ESC Q- Transmitter ON',cr,lf
  2371.     db    'ESC R- Transmitter ON, automatic OFF on CR',cr,0
  2372.     endif
  2373.  
  2374. XPRT    CALL    ILPRT
  2375.     DB    CR,LF,CR,LF,'DEFAULT DRIVE: ',0
  2376.     MVI    C,25        ;CURRENT DISK FUNCTION
  2377.     CALL    BDOS
  2378.     ADI    41H        ;MAKE ASCII
  2379.     CALL    TYPE
  2380.     call    ilprt
  2381.     db    '   ',0
  2382.  
  2383.     if     h19term
  2384.     call    ilprt
  2385.     db    esc,'p',0
  2386.     endif
  2387.  
  2388.     CALL    ILPRT
  2389.     DB    ' Command? '
  2390.     DB    0
  2391.  
  2392.     if    h19term
  2393.     call    ilprt
  2394.     db    esc,'q',0
  2395.     endif
  2396.  
  2397. GETCMD    LXI    D,CMDBUF    ;ENTER COMMAND
  2398.     CALL    INBUFF
  2399.     CALL    CRLF
  2400.     LXI    D,CMDBUF+2    ;POINT TO COMMAND
  2401.     CALL    ILCOMP
  2402.     DB    'CPM',0
  2403.     JNC    EXIT
  2404.     CALL    ILCOMP
  2405.     DB    'DIR',0
  2406.     JNC    DIR
  2407.     CALL    ILCOMP
  2408.     DB    'RET',0
  2409.     JC    NXTOPT1        ;CARRY SET = NO MATCH
  2410.     LHLD    HLSAVE        ;RETURN TO TERMINAL..
  2411.     JMP    termint        ;..MODE WITH SAVE OPTION..
  2412.                 ;..IF PREVIOUSLY ENABLED.
  2413. NXTOPT1:
  2414.     CALL     ILCOMP
  2415.     DB     'WRT',0
  2416.     JNC     WRTFIL
  2417.     CALL     ILCOMP
  2418.     DB     'XPR',0
  2419.     JNC     XPRMODE
  2420.     CALL     ILCOMP
  2421.     DB     'DEL',0
  2422.     JNC     NEWFILE
  2423.  
  2424. NXTOPT2 PUSH     H
  2425.     LDA     CMDBUF+2
  2426.     LXI     H,COMPLIST
  2427.     CALL     COMPARE        ;COMPARES LIST POINTED TO BY HL..
  2428.     POP     H        ;..TO CHAR IN A-REG.
  2429.     JC     MENU1        ;CARRY SET = NO MATCH
  2430.  
  2431. DOOPT    PUSH     H        ;LOAD ORIGINAL FCB WITH TRANSFER..
  2432.     CALL     SETFCB        ;..CMDS AND GO TO BEGINNING OF..
  2433.     POP     H        ;..PROGRAM. WILL FOLLOW SAME LOGIC..
  2434.     JMP     RESTART        ;..AS IF PROGRAM WERE CALLED WITH..
  2435.                 ;..CP/M COMMAND LINE.
  2436.  
  2437.  
  2438. DIR    CALL     DIRLST
  2439.     JMP     XPRT
  2440.  
  2441. NEWFILE    LDA     FCB3+1
  2442.     CPI     ' '
  2443.     JZ     MENU1        ;IF NO FILE, DON'T ERASE
  2444.     LXI     D,FCB3
  2445.     MVI     C,ERASE
  2446.     CALL     BDOSRT
  2447.     MVI     A,TRUE        ;DO NOT ALLOW TERMINAL..
  2448.     STA     NFILFLG        ;..SAVE SINCE NO FILE..
  2449.     CMA            ;..SPECIFIED.
  2450.     STA     SAVEFLG
  2451.  
  2452.     LXI    H,FCB3
  2453.     CALL    INITFCBS
  2454.     JMP    MENU1
  2455.  
  2456. WRTFIL    LDA    NFILFLG
  2457.     CPI    TRUE
  2458.     JZ    MENU1
  2459.     LDA    FCB3+1        ;CHECK THAT FILE WAS REQUESTED
  2460.     CPI    ' '
  2461.     JZ    MENU1
  2462.     LHLD    HLSAVE
  2463.     CALL    NUMRECS        ;DISK WRITE ROUTINE AS USED IN..
  2464.     CALL    WRTDSK        ;..IN THE INTDSKSV ROUTINE.
  2465.     CALL    CLOSE3
  2466.     MVI    A,TRUE
  2467.     STA    NFILFLG
  2468.     CMA
  2469.     STA    SAVEFLG
  2470.  
  2471.     LXI    H,FCB3
  2472.     CALL    INITFCBS    ;BLANK OUT FCB SO WRITTEN FILE..
  2473.     JMP    MENU1        ;..CAN'T BE ERASED.
  2474.  
  2475. XPRMODE    LDA    XPRFLG
  2476.     CMA
  2477.     STA    XPRFLG
  2478.     JMP    MENU1
  2479.  
  2480.  
  2481. COMPARE    MOV    B,M        ;COMPARES A-REG WITH LIST..
  2482. COMPLP    INX    H        ;..ADDRESSED BY HL. FIRST ELEMENT..
  2483.     CMP    M        ;..OF LIST MUST BE NUMBER OF ELEMENTS..
  2484.     JZ    VALID        ;..BEING COMPARED. RETURNS WITH..
  2485.     DCR    B        ;..CARRY SET IF A-REG DOES NOT..
  2486.     JNZ    COMPLP        ;.. CONTAIN AN ELEMENT IN LIST.
  2487.     STC
  2488. VALID    RET
  2489. ;
  2490. ;
  2491. COMPLIST DB 4, 'S', 'R', 'T', 'M'
  2492.  
  2493. ILCOMP    INLNCOMP    ;A MACRO IN MACROS.LIB
  2494.  
  2495.  
  2496. INBUFF    INBUF        ;A MACRO IN "MACROS.LIB"
  2497.  
  2498. CPMLINE    CMDLINE        ;A MACRO IN "MACROS.LIB"
  2499.  
  2500. DIRLST    DIRLIST        ;A MACRO IN "MACROS.LIB"
  2501.  
  2502. NFILFLG    DB     FALSE    ;NORMALLY SET TO FALSE. ALLOWS WRITE TO..
  2503.             ;..MEMORY IN TERMINAL MODE.
  2504.  
  2505. OPTION    DB     0
  2506.  
  2507. OPTBL    EQU     $
  2508. QFLG    DB     'Q'
  2509. RSEEFLG    DB     'R'
  2510. SSEEFLG    DB     'S'
  2511. VSEEFLG    DB     'V'
  2512. TERMFLG DB     'T'
  2513. BATCHFLG DS     1    ;SET TO 'B' BY MENU. DOES NOT ALLOW MULTI-..
  2514. OPTBE    EQU     $    ;..FILE XFER WHEN PROGRAM INITIALLY CALLED.
  2515.  
  2516. RESTROPT        ;MUST BE IN SAME ORDER AS TABLE ABOVE
  2517.  
  2518.         DB     'Q','R','S','V','T','B'
  2519.  
  2520. RESTSN    DB     0,0,0,0,0
  2521.     DW     DBUF
  2522.     DB     0,0,0,0,0,0
  2523.  
  2524. SECTNOB    EQU     $
  2525. RCVSNO    DB     0
  2526. SECTNO    DW     0
  2527. ERRCT    DB     0
  2528. EOFLG    DB     0
  2529. SECPTR    DW     DBUF
  2530. SECINBF    DB     0
  2531. MAXEXT    DB     0
  2532. RCNT    DW     0
  2533. DATAFLG    DB     0
  2534. EXACFL    DB     0
  2535. SECTNOE    EQU     $
  2536.  
  2537. BADOPT    CALL     ILPRT
  2538.     DB 'INVALID OPTION',CR,LF,BELL,0
  2539.     JMP     MENU
  2540.  
  2541. FSTFLG    DB     TRUE
  2542.  
  2543. CMDBUF    DB     80H,0
  2544.     DS     80H
  2545. HLSAVE    DS     2
  2546. DISKNO    DS     1
  2547. SENDFLG    DS     1
  2548. NBSAVE    DS     2
  2549. BGNMS    DS     2
  2550. FILECT    DS     1
  2551. NAMECT    DS     1
  2552.  
  2553.     DS     60
  2554. STACK    DS     2
  2555. FCB3    DS     33
  2556. FCBBUF    DS     15
  2557. linebuf    ds     82
  2558. DBUF    EQU     $    
  2559. NAMEBUF    EQU DBUF+(DBUFSIZ*1024)    ;BUFFER FOR NAMES IN BATCH MODE. OVERFLOWS..
  2560.                 ;..ABOVE PROGRAM CODE.
  2561. ;    BDOS EQUATES
  2562.  
  2563. RDCON    EQU 1
  2564. WRCON    EQU 2
  2565. PRINT    EQU 9
  2566. RDBUF    EQU 10
  2567. CONST    EQU 11
  2568. OPEN    EQU 15
  2569. CLOSE    EQU 16
  2570. SRCHF    EQU 17
  2571. SRCHN    EQU 18
  2572. ERASE    EQU 19
  2573. READ    EQU 20
  2574. WRITE    EQU 21
  2575. MAKE    EQU 22
  2576. REN    EQU 23
  2577. STDMA    EQU 26
  2578. FILSIZ    EQU 35
  2579. BDOS    EQU 5
  2580. REIPL    EQU 0
  2581. FCB    EQU 5CH
  2582. FCBEXT    EQU FCB+12
  2583. FCBSNO    EQU FCB+32
  2584. FCBRNO    EQU FCB+32
  2585. FCB2    EQU 6CH
  2586.  
  2587. LAST    END 100H
  2588.