home *** CD-ROM | disk | FTP | other *** search
/ CP/M / CPM_CDROM.iso / simtel / sigm / vols000 / vol008 / plnk1018.asm < prev    next >
Encoding:
Assembly Source File  |  1984-04-29  |  20.4 KB  |  1,017 lines

  1. ;            PLINK.ASM
  2. ;         (latest version OCT 18 1980)
  3. ;
  4. ;     PLINK - SUPPORT COMMUNICATIONS LINK WITH CYBER
  5. ;
  6. ;PLINK IS A CP/M TRANSIENT COMMAND WHICH ALLOWS THE USER TO
  7. ;ESTABLISH A COMMUNICATIONS LINK WITH A REMOTE COMPUTER
  8. ;
  9. ;    ORIGINAL BY L.E. HUGHES    EDCAM    JULY, 1977
  10. ;
  11. ;       This version by Keith Petersen, W8SDZ.
  12. ;       WITH HEATH EQUATES ADDED BY TOM JORGENSON
  13. ;
  14. ; TRS-80 MODEL 1 mods by Steve Vinokuroff, Vanc CBBS
  15. ; Optional Triger characters by Steve Vinokuroff
  16. ; TRS-80 mods by Dennis Breckenridge, Burnaby CBBS
  17. ; D.C.Hayes mods by Bruce Ratoff, Iselin NJ Remote CP/M
  18. ;
  19. ;This program currently supports the following modems
  20. ; or computers via conditional assembly.
  21. ;
  22. ;    1. PMMI   modem
  23. ;    2. ANY serial i/o board (TUART INCLUDED)
  24. ;    3. TRS-80 model 1
  25. ;    4. TRS-80 model 2
  26. ;    5. HEATH H8 WITH 8251 UART AT PORT 330Q
  27. ;    6. D.C.Hayes 80-103A or Micromodem 100
  28. ;
  29. ;
  30. ;-->NOTE: IF ASSEMBLED AS WRITTEN WILL WORK WITH D.C.Hayes 80-103A
  31. ;      OR MICROMODEM 100 AT PORT 90H
  32. ;
  33. ;PLINK CURRENTLY SUPPORTS TWO WAY TRANSFER OF TEXT FILES
  34. ;BETWEEN THE CP/M DISK AND THE REMOTE COMPUTER. THE FOLLOWING
  35. ;CONTROL CODES MAY BE INITIATED FROM THE CONSOLE KEYBOARD:
  36. ;
  37. ;    ****************************************************
  38. ;    *              COMMANDS:                  *
  39. ;    *                           *
  40. ;    *  CONTROL E    EXIT PLINK TO CP/M WARM BOOT       *
  41. ;    *  CONTROL T    TRANSMIT ASCII FILE TO MODEM.      *
  42. ;    *        ASKS FOR DRIVE AND FILENAME.TYP    *
  43. ;    *  CONTROL C    ABORT FILE SEND TO MODEM       *
  44. ;    *  CONTROL Y    SAVE INCOMING ASCII IN RAM BUFFER  *
  45. ;    *        FOR LATER TRANSFER TO DISK       *
  46. ;    *  CONTROL Q    WRITE RAM BUFFER TO DISK - ASKS    *
  47. ;    *        FOR DRIVE AND FILENAME.TYP       *
  48. ;    *  DELETE    BACKSPACE WHEN IN COMMAND MODE       *
  49. ;    *        ASKING FOR FILENAME           *
  50. ;    *  CONTROL U    ABORT CURRENT LINE WHEN IN COMMAND *
  51. ;    *        MODE ASKING FOR FILENAME       *
  52. ;    *                           *
  53. ;    *  (NOTE: ALL OTHER CONTROL CODES ARE PASSED TO    *
  54. ;    *      MODEM OUTPUT)                   *
  55. ;    ****************************************************
  56. ;
  57. ;
  58. ;CONDITIONAL ASSEMBLY SWITCHES <<-- SET FOR YOUR SYSTEM
  59. ;
  60. TUART    SET    0    ;CROMEMCO TUART I/O BOARD
  61. PMMI    EQU    0    ;PUT A 1 HERE IF YOU HAVE A PMMI
  62. DCH    EQU    1    ;PUT A 1 HERE IF YOU HAVE A D.C.HAYES
  63. TRS1    EQU    0    ;PUT A 1 HERE IF YOU HAVE TRS80-MOD1
  64. TRSPT    EQU    0    ;PUT 1 HERE IF YOU HAVE TRS80-MOD2
  65.             ;USING PICKLES & TROUT CP/M 2.X
  66. H84    EQU    0    ;PUT 1 HERE IF YOU HAVE H8/H8-4
  67.     IF    H84
  68. TUART    SET    1
  69.     ENDIF
  70. ;
  71. INIT$REQUIRED    EQU    1 ;PUT 1 HERE IF INITIALIZATION NEEDED
  72. ;
  73.     IF    TRS1 OR PMMI OR TUART OR DCH
  74. PORT    EQU    1
  75.     ENDIF
  76. ;
  77.     IF    TRSPT
  78. PORT    EQU    0    ;STILL NEED THE SWITCH
  79.     ENDIF
  80. ;
  81. ;
  82. ;
  83. ;BDOS ENTRY POINT AND FUNCTION CODES
  84. ;
  85.     IF    NOT    TRS1
  86. BASE    SET    0    ;STANDARD CPM
  87.     ENDIF
  88. ;
  89.     IF    TRS1 OR H84
  90. BASE    SET    4200H    ;TRS-80 MODEL 1 CP/M BASE ADDRESS
  91.     ENDIF
  92. ;
  93. BDOS    EQU    BASE+5
  94. RESDSK    EQU    13    ;RESET DISK SYSTEM
  95. OFFC    EQU    15    ;OPEN FILE
  96. CFFC    EQU    16    ;CLOSE FILE 
  97. DFFC    EQU    19    ;DELETE FILE
  98. RRFC    EQU    20    ;READ RECORD
  99. WRFC    EQU    21    ;WRITE RECORD 
  100. MFFC    EQU    22    ;MAKE FILE
  101. ;
  102. ;    TRS80 PICKLES AND TROUT SIO CALLS
  103. ;    OFFSET BY -3 THAT IS ADD 3 TO ALL CALLS
  104. ;
  105. SETSIO    EQU    30H    ;SET UP Z80 SIO
  106. SIOTST    EQU    33H    ;READ SIO STATUS
  107. SIOINP    EQU    36H    ;INPUT A CHAR
  108. SIOOUT    EQU    39H    ;OUTPUT A CHAR
  109. ;
  110. ;DEFAULT FCB AND FIELD DEFINITIONS 
  111. ;
  112. FCB    EQU    BASE+5CH
  113. FN    EQU    1    ;FILE NAME FIELD (REL)
  114. FT    EQU    9    ;FILE TYPE FIELD (REL)
  115. EX    EQU    12    ;FILE EXTENT FIELD (REL)
  116. NR    EQU    32    ;NEXT RECORD FIELD (REL)
  117. DBUF    EQU    BASE+80H ;DEFAULT DISK BUFFER ADDRESS
  118. ;
  119. ;ASCII CONTROL CHARACTERS
  120. ;
  121. CR    EQU    0DH    ;CARRIAGE RETURN
  122. LF    EQU    0AH    ;LINE FEED
  123. DEL    EQU    7FH    ;DELETE (RUBOUT)
  124. BELL    EQU    07H    ;BELL SIGNAL
  125. TAB    EQU    09H    ;HORIZONTAL TAB
  126. XON    EQU    11H    ;X-ON CHARACTER
  127. NULL    EQU    00H    ;NULL CHAR
  128. ;
  129. ;THE FOLLOWING "TRIGER" EQUATE IS SET TO "LF" (LINEFEED)
  130. ;BY DEFAULT. AN OPTIONAL TRIGER CHAR MAY BE PASSED VIA FCB1
  131. ;
  132. ; IE:  PLINK B        WILL SET TRIGER TO "BELL"
  133. ;
  134. ;THE FOLLOWING OPTIONS ARE ALLOWED
  135. ;
  136. ;    1. B = BELL  07H
  137. ;    2. X = XON   11H
  138. ;    3. U = UPLOAD NO TRIGER CHECK AT ALL
  139. ;ANY OTHER ASCII CHARACTER MAY BE PASSED THROUGH FCB1
  140. ;
  141. ;
  142. TRIGER    EQU    LF    ;DEFAULT VALUE
  143. ;
  144. ;
  145. ;WARNING CHARACTER FOR LOW MEMORY
  146. ;
  147. WRNSIG    EQU    BELL    ;IF YOU HAVE ONE, PUT 'BELL' HERE
  148.             ;...ELSE PUT '*' HERE.
  149. ;
  150. ;MODEM I/O PORT ADDRESSES
  151. ;
  152.     IF    PMMI
  153. MODD    EQU    0C1H    ;MODEM DATA PORT
  154. MODS    EQU    0C0H    ;MODEM STATUS PORT
  155. MODINIT    EQU    29H    ;INITIALIZE BYTE ORIGINATE,
  156.             ;7 DATA, EVEN PARITY, 1 STOP
  157.     ENDIF
  158. ;
  159.     IF    DCH
  160. MODD    EQU    90H    ;MODEM DATA PORT
  161. MODS    EQU    91H    ;MODEM STATUS PORT
  162. MODINIT    EQU    05H    ;7 DATA, EVEN PARITY, 1 STOP
  163.     ENDIF
  164. ;
  165.     IF    TRS1
  166. MODD    EQU    0EBH    ;TRS80 MOD 1 RS232 DATA PORT
  167. MODS    EQU    0EAH    ; AND THE RS232 STATUS PORT
  168.     ENDIF
  169. ;
  170.     IF    TUART
  171. MODD    EQU    0D8H    ;<<--MODIFY FOR YOURS
  172. MODS    EQU    0DDH    ;<<--MODIFY FOR YOURS
  173.     ENDIF
  174. ;
  175. ;MODEM STATUS PORT BIT DEFINITIONS
  176. ;
  177.     IF    PMMI
  178. MTBE    EQU    01H    ;MODEM TRANS. BUFFER READY FLAG
  179. MRDA    EQU    02H    ;MODEM RECEIVE DATA AVAIL. FLAG
  180. MXOR    EQU    03H    ;MASK TO MAKE MTBE AND MRDA "LOW TRUE"
  181.     ENDIF
  182. ;
  183.     IF    DCH
  184. MTBE    EQU    02H    ;MODEM TRANS. BUFFER READY FLAG
  185. MRDA    EQU    01H    ;MODEM RECEIVE DATA AVAIL. FLAG
  186. MXOR    EQU    03H
  187.     ENDIF
  188. ;
  189.     IF    TRS1
  190. MTBE    EQU    40H    ;TRS80 MOD1 RS232 BUFFER READY
  191. MRDA    EQU    80H    ;MODEM RECEIVE DATA AVAIL.
  192. MXOR    EQU    0C0H
  193.     ENDIF
  194. ;
  195.     IF    TUART    ;<<--OR ANY OTHER SERIAL I/O
  196. MTBE    EQU    20H    ;<<--MODIFY FOR YOURS
  197. MRDA    EQU    1H    ;<<--MODIFY FOR YOURS
  198. MXOR    EQU    21H    ;<<--MODIFY FOR YOURS
  199.     ENDIF
  200. ;
  201. ;    **MAIN PROGRAM**
  202. ;
  203.     ORG    BASE+100H
  204. ;
  205. LINK:    LXI    SP,STACK+64    ;CREATE LOCAL STACK 
  206.     LHLD    BASE+1    ;POINT TO CP/M JMP TABLE
  207.     LXI    D,3    ;GET READY TO ADD 3
  208.     DAD    D    ;POINT TO CON STATUS JMP
  209.     SHLD    CITCAL+1 ;MODIFY CALL ADRS
  210.     DAD    D    ;POINT TO CON IN JMP
  211.     SHLD    RCCAL+1    ;MODIFY CALL ADRS
  212.     DAD    D    ;POINT TO CON OUT JMP
  213.     SHLD    WCCAL+1    ;MODIFY CALL ADRS
  214.     LDA    FCB+1    ;SEE IF OPTIONAL TRIGER CHAR
  215.     CPI    20H    ;BLANK.. ?
  216.     JZ    SKP    ;..BLANK SO USE DEFAULT "LF"
  217.     CPI    'B'    ;BELL WANTED
  218.     JZ    TRGBEL
  219.     CPI    'X'    ;XON WANTED
  220.     JZ    TRGXON
  221.     CPI    'U'    ;UPLOADING NO CHECKING FOR TRIGER
  222.     JZ    TRGUPL
  223. ;
  224. SETTRG    STA    OVERLY+1 ;STORE THE CHARACTER AS IS THEN
  225.     JMP    SKP
  226. ;
  227. TRGBEL    MVI    A,BELL
  228.     JMP    SETTRG
  229. ;
  230. TRGXON    MVI    A,XON
  231.     JMP    SETTRG
  232. ;
  233. TRGUPL    XRA    A        ;ZERO OUT JUMP
  234.     STA    OVERL1+1    ;CHANGE CHECK FOR C/R TO NULL
  235.     STA    OVERL2+1    ;AND SEND LINEFEEDS AS WELL
  236.     JMP    SKP
  237. ;
  238. SKP    EQU    $
  239.     IF    H84
  240.     MVI A,80H;    SET DLAB BIT IN 8250 UART
  241.     OUT 0DBH;    8250 AT PORT D8H (330Q)
  242.     NOP ! NOP ! NOP
  243.     NOP ! NOP
  244.     MVI A,01H;    MSB OF BAUD RATE DIVISOR
  245.     OUT 0D9H;    ...TO UART
  246.     NOP ! NOP ! NOP
  247.     NOP ! NOP
  248.     MVI A,80H;    LSB OF BAUD RATE DIVISOR
  249.     OUT 0D8H;    ...TO UART
  250.     NOP ! NOP ! NOP
  251.     NOP ! NOP
  252.     MVI A,03H;    8 BITS, 1 STOP BIT, NO PARITY, DLAB RESET
  253.     OUT 0DBH;    ...TO UART
  254.     NOP ! NOP ! NOP
  255.     NOP ! NOP
  256.     MVI A,0;    RESET CONTROL REGISTER
  257.     OUT 0DCH;    ...TO UART
  258.     JMP    CONT
  259.     ENDIF
  260.     IF    INIT$REQUIRED AND NOT H84 OR PMMI AND NOT H84
  261.     MVI    A,MODINIT
  262.     OUT    MODS    ;INITIALIZE MODEM PORT
  263.     ENDIF
  264. ;
  265.     IF    TUART
  266.     MVI    A,80H    ;DSR ON BIT 7 PARL PORT B
  267.     OUT    54H
  268.     ENDIF
  269. ;
  270.     IF    TRSPT        ;MUST SET UP SERIAL CHANNEL
  271. RESET:    LXI    H,INITR        ;STORE RETURN ADDRESS
  272.     PUSH    H
  273.     LHLD    1
  274.     LXI    D,SETSIO    ;SIO SETUP ROUTINE
  275.     DAD    D
  276.     PUSH    H        ;STORE ON STACK
  277.     MVI    C,00H        ;NO PARITY CHAN-A
  278.     MVI    D,0E6H        ;8 bits ,1 STOP
  279.     MVI    E,3        ;300 BAUD
  280.     MVI    L,00H        ;DISABLE EXT/ACK SIO FUNCTIONS
  281.     MVI    H,'S'-40H    ;CONTROL S (X-ON)
  282.     RET            ;TROUGH SETUP PROG
  283. INITR    NOP            ;DO IT TO IT
  284.     ENDIF
  285. ;
  286.     IF    TRS1        ;INIT FOR TRS80 MOD1 RS232
  287.     OUT    0E8H        ;RESET RS232
  288.     IN    0E9H        ;READ THE SWITCHES
  289.     ANI    0F8H
  290.     ORI    5
  291.     OUT    0EAH        ;SET DSR AND CTS
  292.     MVI    A,55H        ;300 BAUD
  293.     OUT    0E9H
  294.     ENDIF
  295. ;
  296. ;
  297.     IF    PORT
  298.     IN    MODD         ;CLEAR MODEM UART READ BUFFERS
  299.     IN    MODD 
  300.     ENDIF
  301. ;
  302. CONT    XRA    A    ;CLEAR CHAR BUFFERS 
  303.     STA    INCH 
  304.     STA    OUTCH
  305.     STA    FLAG    ;CLEAR TEXT SAVE FLAG 
  306.     LXI    H,TBUF    ;SET PTR TO TBUF
  307.     SHLD    PTR
  308.     LXI    H,0    ;SIZE = 0 
  309.     SHLD    SIZE 
  310.     LXI    H,LINKMS  ;PRINT SIGN-ON MESSAGE
  311.     CALL    WCS
  312. ;
  313. ;     MAIN LOOP 
  314. ;
  315. LINK3:    CALL    CITEST    ;JUMP IF NO DATA FROM CONSOLE 
  316.     JZ    LINK4
  317.     CALL    RCC    ;ELSE READ CONSOLE DATA
  318.     CPI    20H
  319.     CC    PCC    ;CALL PCC IF CONTROL CHAR
  320.     JC    LINK4    ;JUMP IF PCC HANDLED CHAR 
  321.     ORI    80H    ;ELSE SET VALID DATA BIT
  322.     STA    INCH    ;AND STORE IN INPUT CHAR BUFFER 
  323. LINK4:    LDA    OUTCH    ;JUMP IF NO DATA FOR CONSOLE
  324.     ORA    A
  325.     JP    LINK5
  326.     ANI    7FH    ;ELSE DISCARD VALID DATA BIT
  327.     CALL    WCC    ;SEND CHAR TO CONSOLE 
  328.     XRA    A    ;THEN CLEAR OUTPUT CHAR BUFFER
  329.     STA    OUTCH
  330. LINK5:    CALL    MITEST    ;JUMP IF NO DATA FROM MODEM 
  331.     JZ    LINK6
  332.     CALL    RMC2    ;ELSE READ MODEM DATA
  333.     CALL    SAVE    ;SAVE CHAR IN TEXT BUFFER IF FLAG ON
  334.     ORI    80H    ;SET DATA VALID BIT 
  335.     STA    OUTCH    ;STORE IN OUTPUT CHAR BUFFER
  336. LINK6:    CALL    MOTEST    ;JUMP IF MODEM XMIT BUFFER BUSY 
  337.     JZ    LINK7
  338.     LDA    INCH    ;JUMP IF NO DATA FOR MODEM
  339.     ORA    A
  340.     JP    LINK7
  341.     ANI    7FH    ;DISCARD VALID DATA BIT
  342. ;
  343.     IF    PORT
  344.     OUT    MODD    ;OUTPUT CHAR TO MODEM 
  345.     ENDIF
  346. ;
  347.     IF    TRSPT
  348.     PUSH    B    ;STORE REGISTERS
  349.     PUSH    H
  350.     PUSH    D
  351.     CALL    WMC    ;SEND CHAR
  352.     POP    D
  353.     POP    H
  354.     POP    B
  355.     ENDIF
  356. ;
  357.     XRA    A    ;...THEN CLEAR INPUT CHAR BUFFER 
  358.     STA    INCH 
  359. LINK7:    JMP    LINK3    ;END OF MAIN LOOP 
  360. ;
  361. LINKMS:    DB    CR,LF,'PLINK as of 25-SEP-80'
  362.     DB    CR,LF,LF,'READY',CR,LF,LF,0
  363. ;
  364. ;     PCC - PROCESS CONTROL CHARACTER 
  365. ;
  366. PCC:    CPI    'E'-40H    ;JUMP OUT IF CTRL E
  367.     JNZ    PCC1 
  368.     PUSH    H
  369.     LXI    H,AYS    ;PRINT 'ARE YOU SURE'
  370.     CALL    WCS
  371.     POP    H
  372.     CALL    RCC    ;GET ANSWER
  373.     CALL    WCC    ;ECHO IT
  374.     ANI    5FH    ;MAKE UPPER CASE
  375.     CPI    'Y'    ;YES?
  376.     JZ    PCCEX    ;EXIT
  377.     CALL    WCCR    ;CRLF
  378.     STC        ;TELL LINK TO IGNORE THIS CHARACTER 
  379. ;
  380.     IF    TRSPT
  381.     POP    PSW    ;GOBBLE UP CALL ADDRESS
  382.     JMP    RESET    ;RE-INITIALIZE SIO
  383.     ENDIF
  384. ;
  385.     IF    PORT
  386.     RET
  387.     ENDIF
  388. ;
  389. PCC1:    CPI    'T'-40H    ;JUMP IF NOT CONTROL-T
  390.     JNZ    PCC2 
  391.     CALL    STF    ;TRANSMIT TEXT FILE TO MODEM
  392.     STC        ;TELL LINK TO IGNORE THIS CHARACTER 
  393.     RET 
  394. ;
  395. PCC2:    CPI    'Y'-40H    ;JUMP IF NOT CONTROL-Y
  396.     JNZ    PCC3 
  397.     MVI    A,1    ;TURN ON TEXT SAVE FLAG 
  398.     STA    FLAG 
  399.     LXI    H,PCCMR    ;PRINT 'SAVING INCOMING TEXT IN MEMORY'
  400.     CALL    WCS
  401.     STC        ;TELL LINK TO IGNORE THIS CHARACTER
  402.     RET 
  403. ;
  404. PCC3:    CPI    'Q'-40H    ;JUMP IF NOT CONTROL-Q
  405.     JNZ    PCC4 
  406.     XRA    A    ;TURN OFF TEXT SAVE FLAG
  407.     STA    FLAG 
  408.     CALL    WTB    ;WRITE TEXT BUFFER TO DISK
  409.     STC 
  410.     RET 
  411. ;
  412. PCC4:    STC        ;LET LINK HANDLE ALL OTHER CONT. CODES
  413.     CMC 
  414.     RET 
  415. ;
  416. PCCEX:    LXI    H,DISMS    ;PRINT 'MODEM NOT DISCONNECTED'
  417.     CALL    WCS
  418.     JMP    BASE    ;EXIT TO WARM BOOT
  419. ;
  420. AYS:    DB    CR,LF,'EXIT TO CP/M - ARE YOU SURE (Y OR N)?',0
  421.     IF    PMMI OR DCH
  422. DISMS:    DB    CR,LF,'++DON''T FORGET - THE MODEM '
  423.     DB    'IS NOT DISCONNECTED++',CR,LF
  424.     DB    'USE "MODEM D" TO DISCONNECT',0
  425.     ENDIF
  426. ;
  427.     IF    NOT PMMI AND NOT DCH
  428. DISMS:    DB    CR,LF,'+++ EXIT TO CP/M +++',CR,LF,0
  429.     ENDIF
  430. ;
  431. PCCMR:    DB    CR,LF,'SAVING INCOMING TEXT IN MEMORY',CR,LF,0
  432. ;
  433. ;     STF - SEND TEXT FILE (TO MODEM) 
  434. ;
  435. STF:    CALL    GFN    ;GET NAME OF DISK FILE TO SEND
  436.     JC    STF6    ;JUMP IF FILE NAME ERROR
  437.     CALL    OPEN    ;TRY TO OPEN SPECIFIED FILE 
  438.     CPI    255    ;JUMP IF FILE NOT FOUND 
  439.     JZ    STF7 
  440. STF1:    CALL    READ    ;READ NEXT RECORD INTO DBUF 
  441.     CPI    1    ;JUMP IF END-OF-FILE
  442.     JZ    STF5 
  443.     LXI    H,DBUF     ;POINT TO DISK BUFFER 
  444.     MVI    C,128
  445. STF2:    MOV    A,M    ;FETCH NEXT CHAR FROM DBUF
  446.     INX    H
  447.     CPI    'Z'-40H    ;JUMP IF END-OF-FILE CHARACTER
  448.     JZ    STF5 
  449. OVERL2    CPI    LF    ;IGNORE LINE FEEDS
  450.     JZ    STF4 
  451.     CALL    WMC    ;WRITE CHARACTER TO MODEM 
  452.     CALL    WCC    ;WRITE CHARACTER TO CONSOLE 
  453. OVERL1    CPI    CR    ;JUMP IF NOT CARRIAGE RETURN
  454.     JNZ    STF4 
  455. STF3:    CALL    CITEST    ;CHECK CONSOLE DATA READY
  456.     JZ    STF3A    ;NO DATA THERE
  457.     CALL    RCC    ;GET CONSOLE CHARACTER
  458.     CPI    'C'-40H    ;CONTROL C ABORTS IT
  459.     JZ    STF8
  460. STF3A:    CALL    MITEST    ;WAIT FOR NEXT MODEM KHARACTER
  461.     JZ    STF3
  462.     CALL    RMC2    ;CHECK MODEM FOR TRIGGER CHAR.
  463. OVERLY    CPI    TRIGER
  464.     JNZ    STF3 
  465.     CALL    WCCR    ;SEND CRLF TO CONSOLE
  466. STF4:    DCR    C    ;LOOP THRU REST OF DBUF 
  467.     JNZ    STF2 
  468.     JMP    STF1    ;GO GET NEXT RECORD FROM DISK 
  469. ;
  470. STF5:    LXI    H,STFSM    ;PRINT 'FILE SEND COMPLETE'
  471.     CALL    WCS
  472.     RET 
  473. ;
  474. STF6:    LXI    H,STFS1    ;PRINT 'FILE NAME ERROR'
  475.     CALL    WCS
  476.     RET 
  477. ;
  478. STF7:    LXI    H,STFS2    ;PRINT 'FILE NOT FOUND' 
  479.     CALL    WCS
  480.     RET 
  481. ;
  482. STF8:    LXI    H,STFSA    ;PRINT 'FILE SEND ABORTED'
  483.     CALL    WCS
  484.     RET
  485. ;
  486. STFSM:    DB    'FILE SEND COMPLETE',CR,LF,0
  487. STFS1:    DB    'FILE NAME ERROR',CR,LF,0
  488. STFS2:    DB    'FILE NOT FOUND',CR,LF,0 
  489. STFSA:    DB    CR,LF,'FILE SEND ABORTED',CR,LF,0
  490. ;
  491. ;     SAVE - SAVE CHAR IN TEXT BUFFER IF FLAG ON
  492. ;     ENTRY CONDITIONS
  493. ;        A - CHARACTER TO SAVE
  494. ;
  495. SAVE:    PUSH    PSW
  496.     LDA    FLAG 
  497.     ORA    A
  498.     JNZ    SAVE1
  499.     POP    PSW
  500.     RET 
  501. ;
  502. SAVE1:    POP    PSW
  503.     CPI    DEL    ;RUBOUT (DEL) ?
  504.     RZ        ;YES, IGNORE IT
  505.     CPI    20H    ;TEST FOR CONTROL CHARACTERS
  506.     JNC    SAVE2    ;JUMP IF NOT CONTROL CHAR.
  507.     CPI    CR    ;ALLOW CR TO BE SAVED
  508.     JZ    SAVE2
  509.     CPI    LF    ;ALLOW LF TO BE SAVED
  510.     JZ    SAVE2
  511.     CPI    TAB    ;ALLOW TAB TO BE SAVED
  512.     JZ    SAVE2
  513.     RET        ;IGNORE ALL OTHER CONTROL CHARS.
  514. ;
  515. SAVE2:    PUSH    H
  516.     LHLD    SIZE    ;SIZE = SIZE + 1
  517.     INX    H
  518.     SHLD    SIZE 
  519.     LHLD    PTR
  520.     MOV    M,A
  521.     INX    H
  522.     SHLD    PTR
  523.     PUSH    PSW
  524.     LDA    BASE+7    ;GET SYSTEM SIZE
  525.     SUI    1    ;SO WE DONT CRASH CP/M
  526.     CMP    H    ;ARE WE OUT OF ROOM?
  527.     JZ    SAVEAB    ;YES, ABORT
  528.     SUI    4    ;LEAVE SOME ROOM (1K)
  529.     CMP    H
  530.     MVI    A,WRNSIG  ;SIGNAL CONSOLE RUNNING OUT OF SPACE
  531.     CC    WCC
  532.     POP    PSW
  533.     POP    H
  534.     RET 
  535. ;
  536. ;    SAVEAB - RAN OUT OF ROOM, ISSUE MESSAGE AND FLOW
  537. ;         THROUGH TO DISK SAVE ROUTINE
  538. ;
  539. SAVEND:    DB    BELL,CR,LF,'ABORTING - NO ROOM LEFT',0
  540. ;
  541. SAVEAB:    LXI    SP,STACK+64  ;REINITIALIZE STACK
  542.     LXI    H,SAVEND  ;PRINT 'ABORTING - NO ROOM LEFT'
  543.     CALL    WCS
  544.     LXI    H,LINK    ;SET UP RETURN ADDRESS
  545.     PUSH    H    ;LEAVE IT ON THE STACK
  546. ;
  547. ;     WTB - WRITE TEXT BUFFER TO DISK 
  548. ;
  549. WTB:    LHLD    SIZE    ;JUMP IF TEXT BUFFER EMPTY
  550.     MOV    A,L
  551.     ORA    H
  552.     JZ    WTB5 
  553.     MVI    C,RESDSK ;RESET IN CASE READ-ONLY
  554.     CALL    BDOS
  555.     CALL    GFN    ;GET FILE NAME
  556.     JC    WTB6    ;JUMP IF FILE NAME ERROR
  557.     CALL    DELT    ;DELETE OLD FILE, IF ANY
  558.     CALL    MAKE    ;MAKE NEW FILE
  559.     LHLD    SIZE    ;DE = TBUF SIZE 
  560.     XCHG
  561.     LXI    H,DBUF    ;TOP OF STACK POINTS TO DBUF
  562.     PUSH    H
  563.     LXI    H,TBUF    ;HL POINTS TO TBUF
  564. WTB1:    MVI    C,128    ;DISK BUFFER SIZE 
  565. WTB2:    MOV    A,M    ;FETCH NEXT BYTE OF TBUF
  566.     INX    H
  567.     XTHL
  568.     MOV    M,A    ;STORE IN DBUF
  569.     INX    H
  570.     XTHL
  571.     DCX    D    ;SIZE = SIZE - 1
  572.     MOV    A,D    ;EXIT LOOP IF SIZE = 0
  573.     ORA    E
  574.     JZ    WTB3 
  575.     DCR    C    ;LOOP UNTIL DBUF FULL 
  576.     JNZ    WTB2 
  577.     CALL    WRITE    ;WRITE FULL DBUF TO DISK
  578.     XTHL        ;TOP OF STACK POINTS TO DBUF
  579.     LXI    H,DBUF 
  580.     XTHL
  581.     JMP    WTB1    ;LOOP UNTIL END OF TBUF 
  582. ;
  583. WTB3:    POP    H    ;HL POINTS TO CURRENT PLACE IN DBUF 
  584. WTB4:    MVI    M,'Z'-40H ;STORE EOF CODE 
  585.     INX    H
  586.     DCR    C    ;LOOP THRU REST OF DBUF 
  587.     JNZ    WTB4 
  588.     CALL    WRITE    ;WRITE LAST SECTOR TO DISK
  589.     CALL    CLOSE    ;CLEAN UP ACT AND GO HOME 
  590.     LXI    H,TBUF    ;CLEAR TEXT BUFFER
  591.     SHLD    PTR
  592.     LXI    H,0
  593.     SHLD    SIZE 
  594.     LXI    H,WTBSM    ;PRINT 'BUFFER SAVED ON DISK'
  595.     CALL    WCS
  596.     RET 
  597. ;
  598. WTB5:    LXI    H,WTBS1    ;PRINT 'TEXT BUFFER EMPTY'
  599.     CALL    WCS
  600.     RET 
  601. ;
  602. WTB6:    LXI    H,WTBS2    ;PRINT 'FILE NAME ERROR'
  603.     CALL    WCS
  604.     RET 
  605. ;
  606. WTBSM:    DB    CR,LF,'BUFFER SAVED ON DISK',CR,LF
  607.     DB    'MEMORY SAVE CANCELLED',CR,LF,0
  608. WTBS1:    DB    'TEXT BUFFER EMPTY',CR,LF,0
  609. WTBS2:    DB    'FILE NAME ERROR',CR,LF,0
  610. ;
  611. ;     WCS - WRITE CONSOLE STRING
  612. ;
  613. ;     ENTRY CONDITIONS
  614. ;        HL - POINTS TO STRING (TERM BY ZERO BYTE)
  615. ;
  616. WCS:    MOV    A,M
  617.     INX    H
  618.     ORA    A
  619.     RZ
  620.     CALL    WCC
  621.     JMP    WCS
  622. ;
  623. ;     WCCR - WRITE CONSOLE CARRIAGE RETURN (AND LINE FEED)
  624. ;
  625. WCCR:    MVI    A,CR 
  626.     CALL    WCC
  627.     MVI    A,LF 
  628. ;
  629. ;     WCC - WRITE CONSOLE CHARACTER 
  630. ;     ENTRY CONDITIONS: 
  631. ;        A - CHARACTER TO WRITE 
  632. ;
  633. WCC:    PUSH    PSW
  634.     PUSH    B
  635.     PUSH    D
  636.     PUSH    H
  637.     MOV    C,A    ;GET CHARACTER FOR CBIOS
  638. WCCAL:    CALL    $-$    ;MODIFIED BY INIT.
  639.     POP    H
  640.     POP    D
  641.     POP    B
  642.     POP    PSW
  643.     RET 
  644. ;
  645. ;     RCS - READ CONSOLE STRING (WITH ECHO) 
  646. ;     EXIT CONDITIONS 
  647. ;        B - NUMBER OF CHARACTERS READ (<255) 
  648. ;        HL - POINTS TO LAST CHAR STORED (CR) 
  649. ;
  650. RCS:    LXI    H,IBUF 
  651.     MVI    B,0
  652. RCS1:    CALL    RCC    ;READ NEXT CHAR FROM CONSOLE
  653.     CPI    DEL    ;JUMP IF NOT DEL
  654.     JNZ    RCS2 
  655.     INR    B    ;IGNORE DEL IF IBUF ALREADY EMPTY 
  656.     DCR    B
  657.     JZ    RCS1 
  658.     DCX    H    ;ELSE DISCARD LAST CHAR 
  659.     MOV    A,M    ;ECHO DISCARDED CHAR TO CONSOLE 
  660.     CALL    WCC
  661.     DCR    B    ;DECREMENT COUNT
  662.     JMP    RCS1    ;    AND LOOP 
  663. ;
  664. RCS2:    CPI    'U'-40H    ;JUMP IF NOT CONTROL U
  665.     JNZ    RCS3 
  666.     CALL    WCCR    ;ELSE ABORT CURRENT LINE
  667.     JMP    RCS    ;    AND START OVER 
  668. ;
  669. RCS3:    CALL    WCC    ;ECHO CHAR TO CONSOLE 
  670.     MOV    M,A    ;STORE CHAR IN IBUF 
  671.     INR    B    ;INCREMENT COUNT
  672.     CPI    CR    ;JUMP IF CARRIAGE RETURN
  673.     JZ    RCS4
  674.     INX    H    ;ELSE ADVANCE POINTER 
  675.     JMP    RCS1    ;    AND LOOP 
  676. ;
  677. RCS4:    MVI    A,LF    ;ISSUE LINE FEED AND RETURN 
  678.     CALL    WCC
  679.     RET 
  680. ;
  681. ;     RCC - READ CONSOLE CHARACTER
  682. ;     EXIT CONDITIONS 
  683. ;        A - CHARACTER READ 
  684. ;
  685. RCC:    PUSH    B
  686.     PUSH    D
  687.     PUSH    H
  688. RCCAL:    CALL    $-$    ;MODIFIED BY INI\.
  689.     POP    H
  690.     POP    D
  691.     POP    B
  692.     RET 
  693. ;
  694. ;     WMC - WRITE MODEM CHARACTER 
  695. ;     ENTRY CONDITIONS
  696. ;        A - CHARACTER TO WRITE 
  697. ;
  698. ;
  699.     IF    PORT
  700. WMC:    PUSH    PSW
  701. WMCL:    IN    MODS 
  702.     XRI    MXOR
  703.     ANI    MTBE
  704.     JNZ    WMCL
  705.     POP    PSW
  706.     ANI    7FH    ;STRIP PARITY BIT
  707.     OUT    MODD 
  708.     RET 
  709.     ENDIF
  710. ;
  711.     IF    TRSPT
  712. WMC:    PUSH    H
  713.     PUSH    D
  714.     PUSH    PSW
  715. WMCL:    CALL    MOTEST    ;TEST STATUS
  716.     JZ    WMCL    ;LOOP TILL TX EMPTY
  717.     POP    PSW    ;RESTORE CHAR
  718.     ANI    7FH    ;STRIP PARITY
  719.     PUSH    B    ;STORE B
  720.     MOV    C,A    ;PUT CHAR INTO C
  721.     MVI    B,00H    ;CHANNEL A
  722.     LXI    H,WMCRE    ;STORE RETURN ADDRESS
  723.     PUSH    H
  724.     LHLD    1    ;GET BASE ADDRESS
  725.     LXI    D,SIOOUT
  726.     DAD    D
  727.     PCHL        ;JUMP TO IT
  728. WMCRE:    POP    B    ;RESTORE IT
  729.     POP    D
  730.     POP    H
  731.     RET
  732.     ENDIF
  733. ;
  734. ;     RMC - READ MODEM CHARACTER
  735. ;     EXIT CONDITIONS:
  736. ;        A - CHARACTER READ 
  737. ;
  738. ;
  739.     IF    PORT
  740. RMC:    IN    MODS 
  741.     XRI    MXOR
  742.     ANI    MRDA
  743.     JNZ    RMC
  744. RMC2:    IN    MODD 
  745.     ANI    7FH 
  746.     RET 
  747.     ENDIF
  748. ;
  749.     IF    TRSPT
  750. RMC:    CALL    MITEST    ;CHAR AVAILABLE
  751.     JZ    RMC    ;LOOP IF NOT READY
  752. RMC2:    PUSH    B    ;STORE B
  753.     PUSH    D
  754.     PUSH    H
  755.     MVI    B,00H    ;CHANNEL A
  756.     LXI    H,RMCRE    ;RETURN ADDRESS
  757.     PUSH    H
  758.     LHLD    1
  759.     LXI    D,SIOINP
  760.     DAD    D
  761.     PCHL
  762. RMCRE:    POP    H
  763.     POP    D
  764.     POP    B
  765.     ANI    7FH    ;STRIP PARITY
  766.     RET
  767.     ENDIF
  768. ;
  769. ;
  770. ;     GFN - GET FILE NAME 
  771. ;
  772. GFN:    LXI    H,GFNSD    ;PRINT 'WHICH DRIVE?'
  773.     CALL    WCS
  774.     CALL    RCC    ;GET ANSWER FROM CONSOLE
  775.     CALL    WCC    ;ECHO IT TO CONSOLE
  776.     ANI    5FH    ;MAKE UPPER CASE
  777.     SUI    'A'-1
  778.     JC    GFN    ;REQUIRE ALPHABETIC
  779.     JZ    GFN
  780.     CPI    17    ;ALLOW 16 DRIVES (AS IN CP/M 2.X)
  781.     JNC    GFN
  782.     STA    FCB
  783. GFNB:    LXI    H,GFNS1    ;PRINT 'FILENAME? ' 
  784.     CALL    WCS
  785.     CALL    RCS    ;READ RESPONSE INTO IBUF
  786.     LXI    H,FCB+FN  ;BLANK FILL FN AND FT FIELDS
  787.     MVI    C,11 
  788. GFN1:    MVI    M,' '
  789.     INX    H
  790.     DCR    C
  791.     JNZ    GFN1 
  792.     LXI    H,IBUF    ;POINT TO INPUT BUFFER
  793.     LXI    D,FCB+FN  ;SCAN OFF FN FIELD
  794.     MVI    C,9
  795. GFN2:    MOV    A,M    ;FETCH NEXT CHAR FROM IBUF
  796.     INX    H
  797.     CPI    61H    ;IF LC, CONVERT TO UC 
  798.     JC    GFN2A
  799.     SUI    20H
  800. GFN2A:    CPI    CR    ;JUMP IF END OF LINE
  801.     JZ    GFN5 
  802.     CPI    '.'    ;JUMP IF END OF NAME
  803.     JZ    GFN3 
  804.     STAX    D    ;ELSE STORE CHAR IN FN FIELD
  805.     INX    D
  806.     DCR    C    ;LOOP IF 8 OR LESS CHARS SO FAR
  807.     JNZ    GFN2 
  808.     JMP    GFN6    ;ELSE TAKE ERROR EXIT 
  809. ;
  810. GFN3:    LXI    D,FCB+FT  ;SCAN OFF FT FIELD
  811.     MVI    C,4
  812. GFN4:    MOV    A,M    ;FETCH NEXT CHAR FROM IBUF
  813.     INX    H
  814.     CPI    61H    ;IF LC, CONVERT TO UC 
  815.     JC    GFN4A
  816.     SUI    20H
  817. GFN4A:    CPI    CR    ;JUMP IF END OF LINE
  818.     JZ    GFN5 
  819.     STAX    D    ;ELSE STORE CHAR IN FT FIELD
  820.     INX    D
  821.     DCR    C    ;LOOP IF 3 OR LESS CHARS SO FAR
  822.     JNZ    GFN4 
  823.     JMP    GFN6    ;ELSE TAKE ERROR EXIT 
  824. ;
  825. GFN5:    XRA    A
  826.     STA    FCB+EX    ;SET EXTENT NUMBER TO ZERO
  827.     STA    FCB+NR    ;SET RECORD NUMBER TO ZERO
  828.     STC        ;CLEAR ERROR FLAG AND RETURN
  829.     CMC 
  830.     RET 
  831. ;
  832. GFN6:    STC        ;SET ERROR FLAG AND RETURN
  833.     RET 
  834. ;
  835. GFNSD:    DB    CR,LF,'WHICH DRIVE? ',0
  836. GFNS1:    DB    CR,LF,'FILENAME? ',0 
  837. ;
  838. ;     OPEN - OPEN DISK FILE 
  839. ;
  840. OPEN:    PUSH    H
  841.     PUSH    D
  842.     PUSH    B
  843.     LXI    D,FCB
  844.     MVI    C,OFFC 
  845.     CALL    BDOS 
  846.     POP    B
  847.     POP    D
  848.     POP    H
  849.     RET 
  850. ;
  851. ;     READ - READ RECORD FROM DISK FILE 
  852. ;
  853. READ:    PUSH    H
  854.     PUSH    D
  855.     PUSH    B
  856.     LXI    D,FCB
  857.     MVI    C,RRFC 
  858.     CALL    BDOS 
  859.     POP    B
  860.     POP    D
  861.     POP    H
  862.     RET 
  863. ;
  864. ;     CLOSE - CLOSE DISK FILE 
  865. ;
  866. CLOSE:    PUSH    H
  867.     PUSH    D
  868.     PUSH    B
  869.     LXI    D,FCB
  870.     MVI    C,CFFC 
  871.     CALL    BDOS 
  872.     POP    B
  873.     POP    D
  874.     POP    H
  875.     RET 
  876. ;
  877. ;     DELT - DELETE DISK FILE 
  878. ;
  879. DELT:    PUSH    H
  880.     PUSH    D
  881.     PUSH    B
  882.     LXI    D,FCB
  883.     MVI    C,DFFC 
  884.     CALL    BDOS 
  885.     POP    B
  886.     POP    D
  887.     POP    H
  888.     RET 
  889. ;
  890. ;     WRITE - WRITE RECORD TO DISK
  891. ;
  892. WRITE:    PUSH    H
  893.     PUSH    D
  894.     PUSH    B
  895.     LXI    D,FCB
  896.     MVI    C,WRFC 
  897.     CALL    BDOS 
  898.     POP    B
  899.     POP    D
  900.     POP    H
  901.     RET 
  902. ;
  903. ;     MAKE - MAKE NEW DISK FILE 
  904. ;
  905. MAKE:    PUSH    H
  906.     PUSH    D
  907.     PUSH    B
  908.     LXI    D,FCB
  909.     MVI    C,MFFC
  910.     CALL    BDOS 
  911.     POP    B
  912.     POP    D
  913.     POP    H
  914.     RET 
  915. ;
  916. ;    CITEST - CHECK CONSOLE INPUT STATUS
  917. ;
  918. CITEST:    PUSH    B
  919.     PUSH    D
  920.     PUSH    H
  921. CITCAL:    CALL    $-$    ;MODIFIED BY INIT.
  922.     ORA    A    ;SET ZERO FLAG
  923.     POP    H
  924.     POP    D
  925.     POP    B
  926.     RET        ;ZERO FLAG CARRIES ANSWER
  927. ;
  928. ;    MITEST - CHECK MODEM INPUT STATUS
  929. ;
  930.     IF    PORT
  931. MITEST:    IN    MODS    ;GET MODEM UART STATUS
  932.     XRI    MXOR    ;INVERT HIGH-TRUE BITS
  933.     ANI    MRDA    ;ANY DATA AVAILABLE?
  934.     MVI    A,0
  935.     JNZ    MITST1
  936.     CMA
  937. MITST1:    ORA    A
  938.     RET        ;ZERO FLAG CARRIES ANSWER
  939.     ENDIF
  940. ;
  941. ;
  942.     IF    TRSPT
  943. ;
  944. MITEST:    PUSH    B
  945.     PUSH    H
  946.     PUSH    D
  947.     MVI    B,00    ;CHANNEL A
  948.     LXI    H,MITSTR
  949.     PUSH    H
  950.     LHLD    1
  951.     LXI    D,SIOTST
  952.     DAD    D
  953.     PCHL
  954. MITSTR:    POP    D
  955.     POP    H
  956.     ANI    01    ;TX EMPTY
  957.     POP    B
  958.     RET        ;ZERO FLAG HOLDS THE ANSWER
  959.     ENDIF
  960. ;
  961. ;    MOTEST - CHECK MODEM OUTPUT STATUS
  962. ;
  963. ;
  964.     IF    PORT
  965. MOTEST:    IN    MODS    ;GET MODEM UART STATUS
  966.     XRI    MXOR    ;INVERT HIGH-TRUE BITS
  967.     ANI    MTBE    ;UART READY FOR CHARACTER?
  968.     MVI    A,0
  969.     JNZ    MOTST1    ;ZERO FLAG CARRIES ANSWER
  970.     CMA
  971. MOTST1:    ORA    A    ;SET ZERO FLAG IF READY
  972.     RET
  973.     ENDIF
  974. ;
  975.     IF    TRSPT
  976. MOTEST:    PUSH    B
  977.     PUSH    H
  978.     PUSH    D
  979.     MVI    B,00    ;CHANNEL A
  980.     LXI    H,MOTSTR
  981.     PUSH    H
  982.     LHLD    1
  983.     LXI    D,SIOTST
  984.     DAD    D
  985.     PCHL
  986. MOTSTR:    ANI    02    ;BUFFER EMPTY
  987.     POP    D
  988.     POP    H
  989.     POP    B
  990.     RET
  991.     ENDIF
  992. ;
  993. ;     DATA AREA 
  994. ;
  995. INCH:    DS    1    ;INPUT CHAR BUFFER (TO CYBER) 
  996. OUTCH:    DS    1    ;OUTPUT CHAR BUFFER (FROM CIBER)
  997. STACK:    DS    80    ;LOCAL STACK
  998. IBUF:    DS    256    ;INPUT BUFFER 
  999. ;
  1000. ;     TEXT BUFFER 
  1001. ;
  1002. FLAG:    DS    1    ;TEXT SAVE FLAG 
  1003. PTR:    DS    2    ;TEXT BUFFER POINTER
  1004. SIZE:    DS    2    ;TEXT BUFFER SIZE 
  1005. TBUF:    EQU    $    ;START OF TEXT BUFFER 
  1006. ;
  1007.     END    LINK
  1008. ;
  1009.  
  1010.