home *** CD-ROM | disk | FTP | other *** search
/ Columbia Kermit / kermit.zip / os968ka / k6osys.asm < prev    next >
Assembly Source File  |  2020-01-01  |  62KB  |  1,288 lines

  1.           nam       Kermit68K
  2.           ttl       OS-9/68000 Dependent module (part 1)
  3.  
  4. *         Kermit68K: source file K68SYS.A
  5. *
  6. * Author: Roberto Bagnara (Bagnara@Iboinfn.Bitnet),
  7. * Bologna University, Physics Department, May 1987.
  8. *
  9. * All rights reserved to Bologna University, Italy.
  10. *
  11. * Permission is granted to any individual or institution
  12. * to use, copy, or redistribute this software so long as
  13. * it  is not  sold for  profit, provided  this copyright
  14. * notice is retained.
  15. *
  16. * OS9/68000 Modifications performed by Steve Williams
  17. * University of Texas at Austin, March 1987
  18. *
  19. *  Revision History:
  20. *    Edition  Date      Author  Description
  21. *       0     87/03/25  spw     Initial implementation for OS-9/68K
  22. *       1     87/04/22  spw     Added code for ChanCtrl
  23. *       2     87/04/23  spw     Modifications to SysInit to handle command line
  24. *       3     87/05/05  spw     Changes to ChanCtrl and SysInit
  25. *       4     87/06/05  spw     Stripped parity bit on OutChar to Terminal
  26. *       5     87/06/20  spw     Added line-feed stripping to Terminal output
  27. *       6     87/07/02  spw     Rejoined sys, sy2 and sy3 for distribution
  28.  
  29.           use       DefsFile
  30.  
  31. Edition   set       6
  32.           psect     K68sys,0,0,Edition,0,0
  33.  
  34. ********************************* InpChar *****************************
  35. *                                                                     *
  36. *  Try to read a character from the specified logical channel.        *
  37. *                                                                     *
  38. *         Entry conditions : D1.B logical channel number              *
  39. *                                                                     *
  40. *         Exit  conditions : D0.B character received, if any          *
  41. *                            D1.B Completion Code (see below)         *
  42. *                                                                     *
  43. *              CC symbol        Meaning                               *
  44. *                                                                     *
  45. *              AllOk            No errors, character in D0            *
  46. *              BadChan          Inexistent channel                    *
  47. *              ResChan          Access reserved, permission denied    *
  48. *              DevNotRd         Device not ready (e.g. unmounted)     *
  49. *              NotInpCh         Input impossible on this channel      *
  50. *              NotOpRd          File not open for read                *
  51. *              UnrInpF          Unrecoverable failure during input    *
  52. *              InChLost         Input character lost                  *
  53. *              InpBreak         Break received on input               *
  54. *              BufEmpty         Input buffer empty                    *
  55. *              BufOvflw         Input buffer overflow                 *
  56. *              EndOfFil         End of file reached on input          *
  57. *                                                                     *
  58. *  NOTES:  This routine uses a0, d0, and d1, and restores a0          *
  59. ***********************************************************************
  60. InpChar:  move.l    a0,-(sp)           Save working register.
  61.           clr.w     -(sp)              Make a temporary buffer on the stack
  62.           add.w     d1,d1              Convert to offset in path numbers table
  63.           lea       Pathnums(a6),a0    Base of path numbers table
  64.           move.w    (a0,d1.w),d0       Get the OS-9 path number
  65.           bne.s     InpChar1           Has logical channel been used yet?
  66.           move.b    #NotOpRd,d1        No, complain
  67.           bra.s     InpChar3
  68.  
  69. InpChar1  move.w    #SS_Ready,d1       Check to see if data available
  70.           os9       I$GetStt
  71.           bcc.s     InpChar2           Data ready, go and read it.
  72.           cmp.w     #E$NotRdy,d1       The not ready code (means no data)
  73.           bne.s     InpChar5           Another OS-9 error code
  74.           move.b    #BufEmpty,d1       Tell caller no data ready
  75.           bra.s     InpChar3
  76.  
  77. InpChar2  lea       1(sp),a0           pass address of buffer
  78.           moveq     #1,d1              Read one character
  79.           os9       I$Read
  80.           bcs.s     InpChar5           An OS-9 error
  81.           move.b    #AllOk,d1          Everything OK
  82. InpChar3  move.w    (sp)+,d0           Get the character read
  83.           move.l    (sp)+,a0           Restore working register
  84.           rts
  85.  
  86. InpChar5  cmp.b     #E$FNA,d1          A permission violation?
  87.           bne.s     InpChar6
  88.           move.b    #ResChan,d1
  89.           bra.s     InpChar3
  90. InpChar6  cmp.b     #E$EOF,d1          End of file?
  91.           bne.s     InpChar7
  92.           move.b    #EndOfFil,d1
  93.           bra.s     InpChar3
  94. InpChar7  move.w    #$0707,-(sp)
  95.           moveq     #2,d0
  96.           move.l    sp,a0
  97.           moveq     #1,d1
  98.           os9       I$Write
  99.           addq      #2,sp
  100.           move.b    #UnrInpF,d1
  101.           bra.s     InpChar3
  102.  
  103. ********************************* OutChar *****************************
  104. *                                                                     *
  105. *  Try to write a character to the specified logical channel.         *
  106. *                                                                     *
  107. *         Entry conditions : D0.B character to write                  *
  108. *                            D1.B logical channel number              *
  109. *                                                                     *
  110. *         Exit  conditions : D0.B character just sent                 *
  111. *                            D1.B Completion Code (see below)         *
  112. *                                                                     *
  113. *              CC symbol        Meaning                               *
  114. *                                                                     *
  115. *              AllOk            No errors                             *
  116. *              BadChan          Inexistent channel                    *
  117. *              ResChan          Access reserved, permission denied    *
  118. *              DevNotRd         Device not ready (e.g. unmounted)     *
  119. *              NotOutCh         Output impossible on this channel     *
  120. *              NotOpWr          File not open for write               *
  121. *              UnrOutF          Unrecoverable failure during output   *
  122. *              DevFull          Device full, not enough space         *
  123. *                                                                     *
  124. *  NOTES:  This routine uses a0, d0, and d1, and restores a0          *
  125. ***********************************************************************
  126. OutChar:  move.l    a0,-(sp)           Save working pointer reg.
  127.           cmp       #Terminal,d1       Output to terminal?
  128.           seq       TermFlag(a6)
  129.           bne.s     OutChar0
  130.           and.w     #$007f,d0          Strip the parity bit
  131.           cmp.b     #Asc_LF,d0         Is it a linefeed?
  132.           bne.s     OutChar_0
  133.           tst.b     CR_Last(a6)        Did we just do a CR?
  134.           beq.s     OutChar_0          ...no, so go ahead and print it.
  135.           clr.b     CR_Last(a6)        OK for next LF to be printed
  136.           move.l    (sp)+,a0           Restore working reg
  137.           rts
  138.  
  139. OutChar_0 cmp.b     #Asc_CR,d0         Is carriage return?
  140.           seq       CR_Last(a6)        Set the flag.
  141.  
  142. OutChar0  move.w    d0,-(sp)           Save the character being written
  143.           lea       Pathnums(a6),a0    Get path number table base address
  144.           add.w     d1,d1              Offset in table for this logical channel
  145.           move.w    (a0,d1.w),d0       Get OS-9 output path for channel
  146.           bne.s     OutChar2           It is open, so go ahead with write
  147.           move.b    #NotOpWr,d1
  148.  
  149. OutChar1  move.w    (sp)+,d0           get the character written
  150.           move.l    (sp)+,a0           get the old contents of the pointer
  151.           rts
  152.  
  153. OutChar2  lea       1(sp),a0           Point to character (in memory on stack)
  154.           moveq     #1,d1              ...and get ready
  155.           tst       TermFlag(a6)       Output to terminal?
  156.           beq.s     OutChar21          ...no, use I$Write
  157.           tst.b     CR_Last(a6)        a Carriage return?
  158.           beq.s     OutChar21          ...no, use I$Write
  159.           os9       I$WritLn           Use WritLn to make sure...
  160.           bra.s     OutChar22          ...that CR is handled properly.
  161. OutChar21 os9       I$Write            Just write the character in plain mode
  162. OutChar22 bcs.s     OutChar3           Something went wrong
  163.           move.b    #AllOk,d1
  164.           bra.s     OutChar1           Exit through clean-up routine
  165.  
  166. OutChar3  cmp.b     #E$Full,d1         Device full?
  167.           bne.s     OutChar4
  168.           move.b    #DevFull,d1
  169.           bra.s     OutChar1
  170.  
  171. OutChar4  cmp.b     #E$NotRdy,d1       Device not ready?
  172.           bne.s     OutChar5
  173.           move.b    #DevNotRd,d1
  174.           bra.s     OutChar1
  175.  
  176. OutChar5  cmp.b     #E$FNA,d1          Permission violation?
  177.           bne.s     OutChar6
  178.           move.b    #ResChan,d1
  179.           bra.s     OutChar1
  180.  
  181. OutChar6  move.b    #UnrOutF,d1
  182.           bra.s     OutChar1
  183.  
  184. ********************************* ChanCtrl ****************************
  185. *                                                                     *
  186. *  Performs control operations on logical channels.                   *
  187. *                                                                     *
  188. *         Entry conditions : D0.B Request Code (see below)            *
  189. *                                                                     *
  190. *              RC symbol        Meaning                               *
  191. *                                                                     *
  192. *              SetBaud          Set baud rate on port                 *
  193. *              RawMode          Enable raw mode                       *
  194. *              TextMode         Enable text mode                      *
  195. *              DoXCntrl         Enable XON/XOFF protocol              *
  196. *              NoXCntrl         Disable XON/XOFF protocol             *
  197. *              SndBreak         Send a break over RS 232 C line       *
  198. *              ClrInpBf         Clear input buffer                    *
  199. *              ClrOutBf         Clear output buffer                   *
  200. *                                                                     *
  201. *                            D1.B channel number                      *
  202. *                            D2.L additional data (only requested     *
  203. *                                 baud rate now)                      *
  204. *                                                                     *
  205. *         Exit  conditions : D0.B Completion Code (see below)         *
  206. *                                                                     *
  207. *              CC symbol        Meaning                               *
  208. *                                                                     *
  209. *              AllOk            No errors                             *
  210. *              BadChan          Inexistent channel                    *
  211. *              ResChan          Access reserved, permission denied    *
  212. *              DevNotRd         Device not ready (e.g. unmounted)     *
  213. *              BadCtReq         I/O control request code invalid      *
  214. *                                                                     *
  215. ***********************************************************************
  216. ChanCtrl: add.w     d0,d0              Get offset into jump table
  217.           move.w    ChanRCLk(pc,d0.w),d0 Get offset to start of routine
  218.           jmp       ChanRCLk(pc,d0.w)  Jump into it.
  219.  
  220. ChanRCLk  dc.w      CCSetBaud-ChanRCLk
  221.           dc.w      CCRawMode-ChanRCLk
  222.           dc.w      CCTxtMode-ChanRCLk
  223.           dc.w      CCDoXON-ChanRCLk
  224.           dc.w      CCNoXON-ChanRCLk
  225.           dc.w      CCSndBrk-ChanRCLk
  226.           dc.w      CCClrBuf-ChanRCLk
  227.  
  228. *  Set Baud rate
  229. *
  230. *  This routine simply changes the PD_BAU parameter in the path descriptor of
  231. *  the designated logical channel.  Standard OS-9 baud rates are supported,
  232. *  as per the table listed below and in the SCF section of the OS-9/68000
  233. *  Technical Manual.
  234. *
  235. *  Note:  although many OS9 serial port drivers support software selectable
  236. *  baud rates, many will only set the baud rate when they are first INIZed.
  237. *  The standard 6850 ACIA driver falls in this class.  It is a relatively
  238. *  simple procedure to add on-the-fly baud rate selection to the Read and
  239. *  Write routines of most drivers, if source code is available, and if the
  240. *  hardware supports baud rate selection.
  241.  
  242. CCSetBaud move.l    a0,-(sp)
  243.           lea       BaudRates(pc),a0   Point to baud rate table.
  244. SetBaud2  move.l    (a0)+,d0           Get a baud rate/code number pair
  245.           bmi       CCError            Past end of table
  246.           cmp.w     d0,d2              Baud rates match?
  247.           bne.s     SetBaud2           No, check another
  248.  
  249.           swap      d0                 Get the baud rate code number
  250.           move      d0,d2              Save it around the I$GetStt call
  251.  
  252.           add       d1,d1              Offset to path number table
  253.           lea       Pathnums(a6),a0
  254.           move      (a0,d1),d0         Get the path number
  255.           lea       OptBuff(a6),a0     Point to the options buffer
  256.           moveq     #SS_Opt,d1
  257.           os9       I$GetStt
  258.           bcs       CCError
  259.  
  260.           move.b    d2,PD_BAU-PD_OPT(a0) Set the baud rate
  261.  
  262.           moveq     #SS_Opt,d1
  263.           os9       I$SetStt
  264.           bcs       CCError
  265.           move.l    (sp)+,a0           Restore working register.
  266.           moveq     #AllOk,d0
  267.           rts
  268.  
  269. BaudRates dc.w      0,50      These are the OS-9 baud rate numbers/buad rates
  270.           dc.w      1,75      Found in the Technical Manual section on SCF
  271.           dc.w      2,110
  272.           dc.w      3,134     NOTE:  Not all device drivers support baud rate
  273.           dc.w      4,150     selection after the device has been INIZed!!
  274.           dc.w      5,300
  275.           dc.w      6,600
  276.           dc.w      7,1200
  277.           dc.w      8,1800
  278.           dc.w      9,2000
  279.           dc.w      10,2400
  280.           dc.w      11,3600
  281.           dc.w      12,4800
  282.           dc.w      13,7200
  283.           dc.w      14,9600
  284.           dc.w      15,19200
  285.           dc.w      -1,-1     Mark end of table.
  286.  
  287. *  Send break out RS232 line
  288. *
  289. *  This routine relies on an undocumented feature of the I$GetStt call
  290. *  It may not (and probably won't) work on very many serial drivers.
  291.  
  292. CCSndBrk  move.l    a0,-(sp)
  293.           add       d1,d1              Offset into path table
  294.           lea       Pathnums(a6),a0
  295.           move      (a0,d1),d0         Path number to use
  296.           moveq     #SS_Break,d1       Request a break
  297.           os9       I$SetStt
  298.           bcs       CCError
  299.           move.l    (sp)+,a0
  300.           moveq     #AllOk,d0
  301.           rts
  302.  
  303. CCError   move.l    (sp)+,a0
  304.           moveq     #BadCtReq,d0
  305.           rts
  306.  
  307. *  Raw Mode--sets options suitable for raw (binary) data transfer mode
  308.  
  309. CCRawMode move.l    a0,-(sp)
  310.           add.w     d1,d1              Get offset into path number lookup table
  311.           lea       Pathnums(a6),a0    Get base of input path lookup table
  312.           move.w    (a0,d1.w),d0       Get the OS9 path number
  313.           lea       OptBuff(a6),a0     ...point to a buffer
  314.           move.w    #SS_Opt,d1         ...and read in the option block
  315.           os9       I$GetStt
  316.           bcs       CCError
  317.  
  318.           clr.b     PD_EKO-PD_OPT(a0)  No echo
  319.           clr.b     PD_PAU-PD_OPT(a0)  No page pause
  320.           clr.b     PD_EOF-PD_OPT(a0)  No end of file character
  321.           clr.b     PD_PSC-PD_OPT(a0)  No pause character
  322.           clr.b     PD_INT-PD_OPT(a0)  No interrupt character
  323.           clr.b     PD_QUT-PD_OPT(a0)  No abort character
  324.  
  325.           moveq     #SS_Opt,d1         Now, set 'em back
  326.           os9       I$SetStt
  327.           bcs       CCError
  328.           move.l    (sp)+,a0
  329.           moveq     #AllOk,d0          No error
  330.           rts
  331.  
  332. *  Text Mode--sets options suitable for text transfer mode
  333.  
  334. CCTxtMode move.l    a0,-(sp)
  335.           add.w     d1,d1              Get offset into path number lookup table
  336.           lea       Pathnums(a6),a0
  337.           move.w    (a0,d1.w),d0       Get the OS9 path number
  338.  
  339.           moveq     #255,d1
  340.           os9       I$GetStt
  341.  
  342.           lea       OptBuff(a6),a0     Restore the text mode options
  343.           move.w    #SS_Opt,d1         ...and read in the option block
  344.           os9       I$GetStt
  345.           bcs       CCError
  346.  
  347.           clr.b     PD_EKO-PD_OPT(a0)  No echo
  348.           clr.b     PD_PAU-PD_OPT(a0)  No page pause
  349.           clr.b     PD_EOF-PD_OPT(a0)  No end of file character
  350.           clr.b     PD_PSC-PD_OPT(a0)  No pause character
  351.           clr.b     PD_INT-PD_OPT(a0)  No interrupt character
  352.           clr.b     PD_QUT-PD_OPT(a0)  No abort character
  353.  
  354.           move.w    #SS_Opt,d1
  355.           os9       I$SetStt           Set to raw mode
  356.           bcs       CCError
  357.           move.l    (sp)+,a0
  358.           moveq     #AllOk,d0          No error
  359.           rts
  360.  
  361. *  DoXON--turns on XON/XOFF processing
  362.  
  363. CCDoXON   move.l    a0,-(sp)
  364.           add.w     d1,d1
  365.           lea       Pathnums(a6),a0
  366.           move.w    (a0,d1.w),d0       Get the OS9 path number
  367.           lea       OptBuff(a6),a0
  368.           move.w    #SS_Opt,d1         ...and read in the option block
  369.           os9       I$GetStt
  370.           bcs       CCError
  371.  
  372.           move.b    #Asc_DC1,PD_XON-PD_OPT(a0)
  373.           move.b    #Asc_DC3,PD_XOFF-PD_OPT(a0)
  374.  
  375.           move.w    #SS_Opt,d1
  376.           os9       I$SetStt           Set to XON/XOFF mode
  377.           bcs       CCError
  378.           move.l    (sp)+,a0
  379.           moveq     #AllOk,d0          No error
  380.           rts
  381.  
  382. *  NoXON--This turns XON/XOFF processing off for the selected path.
  383.  
  384. CCNoXON   move.l    a0,-(sp)
  385.           add.w     d1,d1
  386.           lea       Pathnums(a6),a0
  387.           move.w    (a0,d1.w),d0       Get the OS9 path number
  388.           lea       OptBuff(a6),a0
  389.           move.w    #SS_Opt,d1         ...and read in the option block
  390.           os9       I$GetStt
  391.           bcs       CCError
  392.  
  393.           clr.b     PD_XON-PD_OPT(a0)
  394.           clr.b     PD_XOFF-PD_OPT(a0)
  395.  
  396.           move.w    #SS_Opt,d1
  397.           os9       I$SetStt           Set to XON/XOFF mode
  398.           bcs       CCError
  399.           move.l    (sp)+,a0
  400.           moveq     #AllOk,d0          No error
  401.           rts
  402.  
  403. *  Clear out the input buffer.
  404. *
  405. *  This routine uses the OS-9 I$GetStt call with the SS_Ready function request
  406. *  to determine how much data is available.  Most OS-9 drivers implement the
  407. *  SS_Ready function code, but some of them incorrectly return 0 or 1 instead
  408. *  the true number of characters in the buffer.  Due to this the routine will
  409. *  check multiple times.
  410.  
  411. CCClrBuf  move.l    a0,-(sp)
  412.           add.w     d1,d1              Offset into path number lookup table
  413.           lea       Pathnums(a6),a0
  414.           move      (a0,d1.w),d0       Get the actual OS-9 path number
  415.  
  416. CCClrB2   moveq     #SS_Ready,d1
  417.           os9       I$GetStt           Check for data available
  418.           bcs.s     CCClrB3            D1 SHOULD return number of chars in buff
  419.  
  420.           lea       ShellCmd(a6),a0    An unused buffer for reading
  421.           os9       I$Read             Try to read the characters in the buffer
  422.           bcc.s     CCClrB2            Check one more time for data.
  423.  
  424. CCClrB3   cmp.w     #E$NotRdy,d1       Is the error data not ready?
  425.           beq.s     CCClrB4            ...yes, we've flushed the buffer
  426.  
  427.           cmp.w     #E$Read,d1         Was it a buffer over-run?
  428.           beq.s     CCClrB2            Go back and empty some more.
  429.  
  430. CCClrB4   move.l    (sp)+,a0
  431.           moveq     #AllOk,d0
  432.           rts
  433.  
  434. ********************************* SysInit *****************************
  435. *                                                                     *
  436. *  Initialize any system dependent thing.                             *
  437. *                                                                     *
  438. *         Entry conditions : none                                     *
  439. *                                                                     *
  440. *         Exit  conditions : none                                     *
  441. *                                                                     *
  442. *  OS-9/68000 Notes:                                                  *
  443. *    This routine grabs the command line parameter list and makes     *
  444. *  sure that it is null-terminated (OS-9 usually puts a carriage      *
  445. *  return or two).  Also, in order to avoid possible problems with    *
  446. *  locking up the user's terminal, the I$GetStt function SS_DevNm     *
  447. *  is used to open an independent path to the user's terminal.        *
  448. *  I$Dup is not used, because any changes made to the option          *
  449. *  section would have to be remembered and un-done before Kermit      *
  450. *  could safely exit.  This was a major problem in debugging since    *
  451. *  crashing Kermit locked up the terminal until this solution was     *
  452. *  used.                                                              *
  453. ***********************************************************************
  454. SysInit:  move.l    a5,CmdLinPt(a6)    Save address of command line parms
  455.           move.l    a5,a0
  456. SysInit2  move.b    (a0)+,d0
  457.           beq.s     SysInit3
  458.           cmp.b     #Asc_CR,d0
  459.           bne.s     SysInit2
  460.           clr.b     -(a0)              Make sure it is NULL terminated!!
  461.  
  462. *  Connect the Terminal channel to the same device as stdin
  463.  
  464. SysInit3  clr       d0                 Stdin
  465.           moveq     #SS_DevNm,d1       Ask for name of device
  466.           lea       ShellCmd(a6),a0    An empty buffer to retrieve name
  467.           move.b    #'/',(a0)+
  468.           os9       I$GetStt           Find out the name.
  469.           bcs.s     SysInit4
  470.  
  471.           moveq     #RdWrOp,d0         Want a read/write access
  472.           moveq     #Terminal,d1       ...to the terminal
  473.           lea       ShellCmd(a6),a0
  474.           bsr       FilOpen            open it up.
  475.           tst.b     d0
  476.           beq.s     SysInit4
  477.  
  478. *  Set proper terminal operating modes
  479.  
  480.           moveq     #Terminal,d1       Channel number of terminal
  481.           bsr       CCTxtMode          Set text mode I/O parameters.
  482.           rts
  483.  
  484. *  OS-9 reported an error while we were trying to initialize the terminal
  485.  
  486. SysInit4  lea       SysInErr(pc),a0
  487.           moveq     #1,d0              Stdout
  488.           moveq     #127,d1            Long length
  489.           os9       I$WritLn
  490.           os9       F$Exit
  491.  
  492. SysInErr  dc.b      "Can't initialize terminal path properly, exiting."
  493.           dc.b      Asc_CR,Asc_Nul
  494.           align
  495.  
  496.  
  497. ********************************* SysExod *****************************
  498. *                                                                     *
  499. *  Return control to system.                                          *
  500. *                                                                     *
  501. *         Entry conditions : D0.B completion code, exit status        *
  502. *                                                                     *
  503. *         Exit  conditions : none                                     *
  504. *                                                                     *
  505. ***********************************************************************
  506. SysExod:  clr.b     d1                 No error
  507.           os9       F$Exit             Closes all files for us, exits to system
  508.  
  509.  
  510. ******************************** GetCmdLP *****************************
  511. *                                                                     *
  512. *  Try to return a pointer to the command line, null terminated.      *
  513. *                                                                     *
  514. *         Entry conditions : none                                     *
  515. *                                                                     *
  516. *         Exit  conditions : A0.L pointer to the command line, if any *
  517. *                            D0.B completion code                     *
  518. *                                                                     *
  519. ***********************************************************************
  520. GetCmdLP: move.l    CmdLinPt(a6),a0
  521.           tst.b     (a0)               Command line null?
  522.           sne       d0                 Set completion code accordingly
  523.           RTS
  524.           pag
  525.           nam       Kermit68K
  526.           ttl       OS-9/68000 Dependent module (part 2)
  527.  
  528. *         Kermit68K: source file K68SY2
  529. *
  530. * Author: Roberto Bagnara (Bagnara@Iboinfn.Bitnet),
  531. * Bologna University, Physics Department, May 1987.
  532. *
  533. * All rights reserved to Bologna University, Italy.
  534. *
  535. * Permission is granted to any individual or institution
  536. * to use, copy, or redistribute this software so long as
  537. * it  is not  sold for  profit, provided  this copyright
  538. * notice is retained.
  539. *
  540. * OS9/68000 Modifications performed by Steve Williams
  541. * University of Texas at Austin, June, 1987
  542. *
  543. *  Revision History:
  544. *    Edition  Date      Author  Description
  545. *       0     87/03/25  spw     Initial implementation for OS-9/68K
  546. *       1     87/04/16  spw     Rough code for ExpandFN (no wildcarding)
  547. *       2     87/04/22  spw     Changes to SysExod
  548. *       3     87/04/24  spw     Added the System services
  549. *       4     87/05/05  spw     Revised FilOpen, FilClose for new path number
  550. *                               handling.  Split ExpandFN, GetNxtF, CRemTLoc,
  551. *                               NewName, and Sleep to k68os9p3.a
  552. *       5     87/06/05  spw     Added SysCommd handling to System function
  553.  
  554. ********************************** System *****************************
  555. *                                                                     *
  556. *  Performs system commands. Called with a request code and 0, 1 or 2 *
  557. *  null terminated argument strings, depending on request code.       *
  558. *                                                                     *
  559. *         Entry conditions : D0.B Request Code (see below)            *
  560. *                                                                     *
  561. *         RC symbol             Meaning                               *
  562. *                                                                     *
  563. *         SysCommd              Forward command to operating system   *
  564. *         Directry              Display a directory listing           *
  565. *         SpacInfo              Display informations about disk usage *
  566. *         DeletFil              Delete file(s)                        *
  567. *         CopyFile              Copy file(s)                          *
  568. *         ChangDir              Change the default directory          *
  569. *         PrntFile              Print file(s)                         *
  570. *         RenamFil              Rename file(s)                        *
  571. *         TypeFile              Type file(s)                          *
  572. *                                                                     *
  573. *                            A0.L pointer to argument 1 (see below)   *
  574. *                            A1.L pointer to argument 2 (see below)   *
  575. *                                                                     *
  576. *         RC symbol             Arguments number and meaning          *
  577. *                                                                     *
  578. *         Directry              0 or 1  directory path                *
  579. *         SpacInfo              0 or 1  device or account name        *
  580. *         DeletFil              1       file name                     *
  581. *         CopyFile              2       source and target file names  *
  582. *         ChangDir              0 or 1  path to new directory         *
  583. *         PrntFile              1       file name                     *
  584. *         RenamFil              2       old and new file names        *
  585. *         TypeFile              1       file name                     *
  586. *                                                                     *
  587. *         Exit  conditions : D0.B completion code                     *
  588. *                                                                     *
  589. *  NOTES:  This routine saves all of the registers that it uses and   *
  590. *    restores all of them on return, except of course, d0             *
  591. ***********************************************************************
  592. System:   movem.l   d1-d4/a0-a3,-(sp)      Save the working registers.
  593.           add.w     d0,d0                  Compute offset in...
  594.           move.w    SysCmdTbl(pc,d0.w),d1  ...command routine offset table
  595.           jmp       SysCmdTbl(pc,d1.w)     Jump to the routine.
  596.  
  597. SysCmdTbl dc.w      SysHandle-SysCmdTbl  for SysCommd
  598.           dc.w      SysFork-SysCmdTbl    for Directry
  599.           dc.w      SysFork-SysCmdTbl    for SpacInfo
  600.           dc.w      FilDel_0-SysCmdTbl   DeletFil
  601.           dc.w      SysFork-SysCmdTbl    CopyFile
  602.           dc.w      SysCWD-SysCmdTbl     ChangDir
  603.           dc.w      SysFork-SysCmdTbl    PrntFile
  604.           dc.w      SysFork-SysCmdTbl    Rename
  605.           dc.w      SysFork-SysCmdTbl    TypeFile
  606.  
  607. SysHandle lea       ShellCmd(a6),a1
  608. SysHnd_1  move.b    (a0)+,(a1)+        Move the command line to the shell buffer
  609.           bne.s     SysHnd_1
  610.           bra.s     SysFork3
  611.           rts
  612.  
  613. SysCWD    tst.b     (a0)               Null string?
  614.           beq.s     SysCWD2
  615.           move.w    #Updat_,d0         Change data directory
  616.           os9       I$ChgDir
  617. SysCWD2   scc       d0                 Set condition code
  618.           movem.l   (sp)+,d1-d4/a0-a3
  619.           rts
  620.  
  621. *  Come here for those commands that we can just fork to a shell
  622.  
  623. SysFork   move.w    ShellOff(pc,d0.w),d1  Got offset to string in string table
  624.           move.w    ShellOps(pc,d0.w),d2  Get number of operands.
  625.           lea       ShellOff(pc,d1.w),a2  Got address of string.
  626.           lea       ShellCmd(a6),a3       Need to set up the shell command
  627.           bra.s     SysFork2
  628.  
  629. *  Table of number of command arguments for each command.  For those commands
  630. *  with optional arguments, these are the maximum number of arguments.
  631. *
  632. *  The -1 entries in this table are for the commands that are taken care
  633. *  of directly in Kermit.
  634.  
  635. ShellOps  dc.w     -1                  SysCmd
  636.           dc.w      1                  Directry
  637.           dc.w      1                  SpacInfo
  638.           dc.w     -1                  DeletFil
  639.           dc.w      2                  CopyFile
  640.           dc.w     -1                  ChangDir
  641.           dc.w      1                  PrntFile
  642.           dc.w      2                  RenamFil
  643.           dc.w      1                  TypeFile
  644.  
  645. *  Table of offsets to the actual command strings
  646.  
  647. ShellOff  dc.w     -1                  SysCmd
  648.           dc.w      Directry-ShellOff
  649.           dc.w      SpacInfo-ShellOff
  650.           dc.w     -1
  651.           dc.w      CopyFile-ShellOff
  652.           dc.w     -1
  653.           dc.w      PrntFile-ShellOff
  654.           dc.w      RenamFil-ShellOff
  655.           dc.w      TypeFile-ShellOff
  656.  
  657. *  Build the shell paramter list in ShellCmd(a6)
  658.  
  659. SysFork2  move.b    (a2)+,(a3)+        Move byte of the command name
  660.           bne.s     SysFork2
  661.           move.b    #' ',-1(a3)        Put in a space separator
  662.  
  663.           move.l    a0,a2              Move on-deck to batter's box
  664.           move.l    a1,a0              In the hole -> on-deck
  665.           dbf       d2,SysFork2        Go until the parameters are out.
  666.  
  667.           move.b    #Asc_CR,-1(a3)     Terminate the command with a CR
  668.           clr.b     (a3)               ...and then a nul
  669.  
  670. *  Fork a shell to process the newly constructed command line at this point,
  671. *  the registers a0-a3 and d2-d4 have been stacked with a movem instruction.
  672.  
  673. SysFork3  move.w    #(Prgrm<<8)+Objct,d0
  674.           moveq     #0,d1              No extra memory
  675.           move.l    a3,d2              End of parameter list
  676.           lea       ShellCmd(a6),a1    Beginning of parameter list
  677.           sub.l     a1,d2              Length of parameter list
  678.           lea       ShellNam(pc),a0    Address of shell's name
  679.           move.w    #3,d3              Inherit all my stdio paths.
  680.           clr.w     d4                 Don't care about the priority
  681.  
  682.           os9       F$Fork
  683.           bcs.s     SysErr             Error, must put terminal back...
  684. *                                      ...to proper mode.
  685.  
  686. *  Wait for the child process to die.
  687.  
  688.           os9       F$Wait
  689.  
  690. SysErr    scc       d0                 If no OS-9 error, return good completion.
  691.           movem.l   (sp)+,d1-d4/a0-a3
  692.           RTS
  693.  
  694. Directry  dc.b      "dir",Asc_Nul
  695. SpacInfo  dc.b      "free",Asc_Nul
  696. CopyFile  dc.b      "copy",Asc_Nul
  697. PrntFile  dc.b      "list >/p",Asc_Nul
  698. RenamFil  dc.b      "rename",Asc_Nul
  699. TypeFile  dc.b      "list",Asc_Nul
  700.  
  701. ShellNam: dc.b      "Shell",Asc_Nul
  702.           align
  703.  
  704. ********************************* FilOpen *****************************
  705. *                                                                     *
  706. *  Open a disk file or an I/O channel.                                *
  707. *                                                                     *
  708. *         Entry conditions : D0.B Request Code (see below)            *
  709. *                                                                     *
  710. *              RC symbol        Meaning                               *
  711. *                                                                     *
  712. *              RdWrOp           Open for read/write                   *
  713. *              ReadOp           Open for read                         *
  714. *              WriteOp          Open for write                        *
  715. *              AppendOp         Open for append                       *
  716. *                                                                     *
  717. *                            D1.B logical channel number.             *
  718. *                            A0.L points to file name null terminated *
  719. *                                                                     *
  720. *         Exit  conditions : D0.B completion code                     *
  721. *                            A0.L still points to the file name       *
  722. *                                                                     *
  723. ***********************************************************************
  724. FilOpen:  movem.l   d1-d3/a0-a1,-(sp)   Save the working registers
  725.           move.w    d0,d2               Save a copy of the file access mode
  726.           add.w     d1,d1               Convert channel number to offset...
  727. *                                       ...in OS-9 lookup table
  728.           move.w    d1,d3               Save a copy of the logical...
  729. *                                       ...(Kermit68K) channel number
  730.           add.w     d0,d0               Compute offset into lookup table...
  731. *                                       ...for mode
  732.           lea       OS9OpCd(pc),a1
  733.           move.w    (a1,d0.w),d0        Get the OS-9 open code corresponding
  734.  
  735. FilOp_1   cmp.w     #WriteOp,d2         Are we going to write to file?
  736.           beq.s     FilOp_6             Yes, handle differently.
  737.  
  738.           os9       I$Open              No, try to open it
  739.           bcc.s     FilOp_2             No error on the open
  740.  
  741.           cmp.w     #E$PNNF,d1          Path name not found?
  742.           bne.s     FilOp_5             Other error, get out of here.
  743.           cmp.w     #ReadOp,d2          Trying to read this file?
  744.           beq.s     FilOp_5             Can't read from inexistent files
  745.  
  746.           move.w    d2,d0               Get the access mode value again
  747.           add.w     d0,d0
  748.           lea       OS9OpCd(pc),a1
  749.           move.w    (a1,d0.w),d0        Get the access mode needed
  750.           move.w    #Updat_,d1          Set read/write permanent permission bits
  751.           move.l    (sp),a0             Restore the file name address
  752.           os9       I$Create            Create the file
  753.           bcs.s     FilOp_5             Can't even come close to open, get out
  754.  
  755. *  Connect the logical channel to the returned OS-9 path number
  756.  
  757. FilOp_2   lea       Pathnums(a6),a0     Set the path number
  758.           move.w    d0,(a0,d3.w)
  759.           cmp.b     #AppendOp,d2        Doing an append?
  760.           bne.s     FilOp_4             No, leave the file where it is...
  761. *                                       ...(d0 is non-zero)
  762.  
  763. *  For an append, find out how big the file is (with I$GetStt)
  764. *  and then seek to end
  765.  
  766.           move.w    #SS_Ready,d1        Going to find out how big the file is.
  767.           os9       I$GetStt
  768.           bcs.s     FilOp_5
  769.           move.l    d2,d1               Copy the current size
  770.           os9       I$Seek              So we can seek to current end + 1
  771.           bcs.s     FilOp_5
  772.  
  773. FilOp_4   st        d0                  return good completion
  774.           movem.l   (sp)+,d1-d3/a0-a1
  775.           rts
  776.  
  777. FilOp_5   sf        d0                  return bad completion code.
  778.           movem.l   (sp)+,d1-d3/a0-a1   restore the working registers
  779.           rts
  780.  
  781. *  Code to handle opening for write access
  782.  
  783. FilOp_6   bsr       FilDelet            Try to delete the file
  784.           move.w    #Write_,d0          Write mode access
  785.           move.w    #Updat_,d1          Read and write attributes (permanent)
  786.           os9       I$Create
  787.           bcs.s     FilOp_5             Error, quit now.
  788.           bra       FilOp_2             Go into code to set path number properly
  789.  
  790. *  Lookup/translation table to convert the open request modes of Kermit68K to
  791. *  the standard modes of OS-9
  792.  
  793. OS9OpCd   dc.w      Updat_              OS-9 Updat_ mode <--> RdWrOp of Kermit
  794.           dc.w      Read_               <--> ReadOp of Kermit
  795.           dc.w      Write_              <--> WriteOp of Kermit
  796.           dc.w      Write_              <--> AppendOp of Kermit (with seek)
  797.  
  798. ******************************** FilClose *****************************
  799. *                                                                     *
  800. *  Close a disk file or an I/O channel.                               *
  801. *                                                                     *
  802. *         Entry conditions : D1.B logical channel number.             *
  803. *                                                                     *
  804. *         Exit  conditions : D0.B completion code                     *
  805. *                                                                     *
  806. ***********************************************************************
  807. FilClose: movem.l   d1/a0,-(sp)
  808.  
  809.           add.w     d1,d1               Double channel number for offset
  810.           lea       Pathnums(a6),a0     Base of path number lookup table
  811.           move.w    (a0,d1.w),d0        Get the path number for the channel
  812.  
  813.           clr.w     (a0,d1.w)           Mark path as unused
  814.           tst.w     d0                  Was the path ever used?
  815.           beq.s     FilCls_1            ...no, don't close it.
  816.           os9       I$Close             Close the path
  817.  
  818. FilCls_1  movem.l   (sp)+,d1/a0
  819.           st        d0                  return success
  820.           RTS
  821.  
  822. ********************************* FilDelet ****************************
  823. *                                                                     *
  824. *  Delete a file.                                                     *
  825. *                                                                     *
  826. *         Entry conditions : A0.L points to file name null terminated *
  827. *                                                                     *
  828. *         Exit  conditions : D0.B completion code                     *
  829. *                                                                     *
  830. ***********************************************************************
  831. FilDel_0  movem.l   (sp)+,d1-d4/a0-a3   Restore regs pushed by System
  832. FilDelet: move.l    a0,-(sp)            I$Delete clobbers a0
  833.           move.w    #Read_,d0           Get the file in current DATA directory
  834.           os9       I$Delete
  835.           scc       d0                  Return success
  836.           move.l    (sp)+,a0            Restore file name pointer
  837.           rts
  838.           align
  839.           pag
  840.           nam       Kermit68K
  841.           ttl       OS-9/68000 Dependent module (part 3)
  842.  
  843. *         Kermit68K: source file K68SY3
  844. *
  845. * Author: Roberto Bagnara (Bagnara@Iboinfn.Bitnet),
  846. * Bologna University, Physics Department, February 1987.
  847. *
  848. * All rights reserved to Bologna University, Italy.
  849. *
  850. * Permission is granted to any individual or institution
  851. * to use, copy, or redistribute this software so long as
  852. * it  is not  sold for  profit, provided  this copyright
  853. * notice is retained.
  854. *
  855. * OS9/68000 Modifications performed by Steve Williams
  856. * University of Texas at Austin, June, 1987
  857. *
  858. *  Revision History:
  859. *    Edition  Date      Author  Description
  860. *       0     87/05/05  spw     Separated from k68os9p2.a
  861. *       1     87/05/25  spw     Added code to handle wildcards
  862. *       2     87/06/05  spw     Added CLocTRem for converted file names
  863.  
  864. ********************************* ExpandFN ****************************
  865. *                                                                     *
  866. *  Expand a wildcard file name into an array of file names, returns   *
  867. *  the number of files that match the passed string, with data        *
  868. *  structures set up so that the first file name (if any) will be     *
  869. *  returned by the next GetNxtF call.                                 *
  870. *                                                                     *
  871. *         Entry conditions : A0.L points to file name null terminated *
  872. *                                                                     *
  873. *         Exit  conditions : D0.L number of matches found, negative   *
  874. *                                 if too many matches for user buffer *
  875. *                            A0.L still points to the file name       *
  876. *                                                                     *
  877. ***********************************************************************
  878. ExpandFN: movem.l   d1-d4/a0-a3,-(sp)   Save working registers
  879.           moveq     #0,d0               Clear character pointer.
  880.           lea       FNBuffer(a6),a1     Point to first file name in buffer
  881.           move.l    a1,NextFile(a6)     Save address of first file name
  882. ExpFN_1   move.b    (a0,d0.l),d1
  883.           move.b    d1,(a1,d0.l)        Copy the file name.
  884.           beq.s     ExpFN_2             End of string and no wild card
  885.           cmp.b     #'?',d1
  886.           beq.s     ExpandWC            Handle the wildcard case.
  887.           cmp.b     #'*',d1
  888.           beq.s     ExpandWC            Do wildcard expansion.
  889.           addq      #1,d0
  890.           bra.s     ExpFN_1
  891.  
  892. ExpFN_2   moveq     #1,d0     One match
  893.           move.l    d0,NumFiles(a6)     Set up for GetNxtF
  894.           movem.l   (sp)+,d1-d4/a0-a3
  895.           rts
  896.  
  897. *  The file name contains wildcards a0 still points to beginning of
  898. *  wild card file name.
  899. *
  900. *  This version will handle wildcards if they are in the current directory.
  901.  
  902. ExpandWC  move.b    #'/',d0             Going to look for a directory specifier.
  903.           move.l    a0,a1               Copy beginning of string pointer.
  904.           sf        d1                  Haven't found a directory terminator
  905.           moveq     #64,d2              Set a limiting count
  906.  
  907. ExpWC_1   cmp.b     (a1),d0             Is this a directory separator?
  908.           seq       d3                  Set a flag
  909.           or.b      d3,d1               Keep a permanent indicator
  910.           tst.b     (a1)+               End of string?
  911.           dbeq      d2,ExpWC_1          Go back until we find end of string.
  912.  
  913.           tst.b     d1                  Was there a directory separator?
  914.           beq.s     ExpWC_2             ...no, do the expansion.
  915.  
  916.           move.l    a0,-(sp)            Save the file name pointer
  917.           lea       BadWCMsg(pc),a0
  918.           moveq     #1,d0               Stdout
  919.           moveq     #127,d1             Long length
  920.           os9       I$WritLn
  921.           move.l    (sp)+,a0            Restore the file name pointer
  922.  
  923.           moveq     #0,d0               Signal no matches
  924.           move.l    d0,NumFiles(a6)
  925.           movem.l   (sp)+,d1-d4/a0-a3
  926.           rts
  927.  
  928. BadWCMsg  dc.b      "Wildcarded filenames must be in current directory."
  929.           dc.b      Asc_CR,Asc_Nul
  930.           align
  931.  
  932. *  The files should all be in the current directory, so a shell can be forked
  933. *  to execute an 'echo' command which will return a list of matches.
  934.  
  935. ExpWC_2   lea       EchoOpts(pc),a1     Pointer to the option list needed
  936.           lea       ShellCmd(a6),a2     Point to parameter list
  937.  
  938. ExpWC_3   move.b    (a1)+,(a2)+         Set up the command options
  939.           bne.s     ExpWC_3
  940.  
  941.           subq      #1,a2               Backup
  942.           move.l    a0,a1               Copy file name pointer
  943. ExpWC_4   move.b    (a1)+,(a2)+         Set up the wild card name
  944.           bne.s     ExpWC_4
  945.  
  946. * Set up a pipe to read back the output of the echo command
  947.  
  948.           moveq     #1,d0               StdOut
  949.           os9       I$Dup               Duplicate current standard output path
  950.           move      d0,-(sp)            Save the duplicated path number
  951.           moveq     #1,d0
  952.           os9       I$Close             close stdout
  953.           lea       PipeName(pc),a0
  954.           move.w    #Updat_,d0          I need to read, he needs to write
  955.           os9       I$Open              Open up the pipe (it will become path 1)
  956.  
  957. *  Now that the pipe is open, fork a shell to process the command
  958.  
  959.           move.w    #(Prgrm<<8)+Objct,d0
  960.           moveq     #0,d1               No extra memory
  961.           move.l    a2,d2               End of parameter list
  962.           lea       ShellCmd(a6),a1     Beginning of parameter list
  963.           sub.l     a1,d2               Length of parameter list
  964.           lea       ShellNam(pc),a0     Address of shell command name
  965.           move.w    #3,d3               Inherit all my stdio paths.
  966.           clr.w     d4                  Don't care about the priority
  967.           os9       F$Fork
  968.  
  969. *  Now, read the lines of output that match the wild card.
  970.  
  971.           lea       FNBuffer(a6),a0     Pointer to where to put file name
  972.           moveq     #0,d3               Counter for file names.
  973.  
  974. ExpWC_5   moveq     #1,d0               The path number of the pipe
  975.           moveq     #80,d1              read a line's worth
  976.           os9       I$ReadLn            read a line
  977.           bcs.s     ExpWC_8             End of file?
  978.  
  979. *  Got a name read in, now, update the pointer and count and go back for more
  980.  
  981.           move.b    #Asc_CR,d0
  982. ExpWC_6   cmp.b     (a0)+,d0            Is it a Carriage return?
  983.           bne.s     ExpWC_6             ...no, go back.
  984.  
  985.           clr.b     -1(a0)              Change the CR to a string terminator
  986.           addq      #1,d3               Bump the file name count
  987.           cmp.l     #50,d3              A limit on the number of files
  988.           blo.s     ExpWC_5
  989.  
  990. *  too many file names matched, so read pipe until empty then quit.
  991.  
  992. ExpWC_7   lea       FNBuffer(a6),a0
  993.           moveq     #1,d0
  994.           moveq     #80,d1
  995.           os9       I$ReadLn
  996.           bcc.s     ExpWC_7
  997.           moveq     #-1,d3              Signal too many matches
  998.  
  999. ExpWC_8   os9       F$Wait              Wait for the child to exit.
  1000.           moveq     #1,d0               Must close the pipe
  1001.           os9       I$Close
  1002.           move.w    (sp),d0             Get the saved path number for our stdout
  1003.           os9       I$Dup
  1004.           move.w    (sp)+,d0            Close the duplicated stdout
  1005.           os9       I$Close
  1006.           move.l    d3,NumFiles(a6)
  1007.           move.l    d3,d0               Return number of files matching.
  1008.           movem.l   (sp)+,d1-d4/a0-a3
  1009.           rts
  1010.  
  1011. PipeName  dc.b      "/pipe",0
  1012. EchoOpts  dc.b      "echo -n ",0
  1013.           align
  1014.  
  1015. ********************************* GetNxtF *****************************
  1016. *                                                                     *
  1017. *  Get the next file name from the list created by ExpandFN, returns  *
  1018. *  a true completion code if there's another file, copying its name   *
  1019. *  into the target string, or false if no more file names in list.    *
  1020. *                                                                     *
  1021. *         Entry conditions : A0.L points to the target string         *
  1022. *                                                                     *
  1023. *         Exit  conditions : D0.B completion code                     *
  1024. *                            A0.L points to the target string         *
  1025. *                                                                     *
  1026. ***********************************************************************
  1027. GetNxtF:  move.l    NumFiles(a6),d0     any left to get?
  1028.           beq.s     GetNF_2             No, so get on out of here.
  1029.  
  1030.           subq      #1,d0
  1031.           move.l    d0,NumFiles(a6)     Re-set number of files left
  1032.           movem.l   a0-a1,-(sp)
  1033.           movea.l   NextFile(a6),a1     Get address of this file name string
  1034.  
  1035. GetNF_1   move.b    (a1)+,(a0)+         Move a byte
  1036.           bne.s     GetNF_1             Until null encountered
  1037.           move.l    a1,NextFile(a6)     Save updated pointer
  1038.           movem.l   (sp)+,a0-a1
  1039.           st        d0                  true result
  1040.           rts
  1041.  
  1042. GetNF_2   sf        d0                  false result
  1043.           rts
  1044.  
  1045.  
  1046. ********************************* CRemTLoc ****************************
  1047. *                                                                     *
  1048. *  Convert filenames from remote system in a form suitable for the    *
  1049. *  local system.                                                      *
  1050. *                                                                     *
  1051. *         Entry conditions : A0.L points to the string to be          *
  1052. *                                 converted                           *
  1053. *                                                                     *
  1054. *         Exit  conditions : A0.L points to the same string suitably  *
  1055. *                                 converted                           *
  1056. *                                                                     *
  1057. *  OS-9/68000 Notes:                                                  *
  1058. *    This routine will replace any illegal punctuation characters     *
  1059. *  including the directory separator '/' and device raw-mode specifer *
  1060. *  '@' with the underline character, which is legal for OS-9 path     *
  1061. *  names.                                                             *
  1062. ***********************************************************************
  1063. CRemTLoc: move.l    d1,-(sp)
  1064.           clr.w     d0                  Zero out counter
  1065.           moveq     #FilNamML-1,d1      File name string maximum length in OS-9
  1066. CRTL_1    tst.b     (a0,d0.w)           Find length of string.
  1067.           beq.s     CRTL_2              Found the null
  1068.           addq      #1,d0               Keep counting
  1069.           dbf       d1,CRTL_1           ...until length exceeded
  1070.           clr.b     0(a0,d0.w)          Terminate the string properly.
  1071.  
  1072. CRTL_2    subq      #1,d0               Backup to last byte of string
  1073. CRTL_3    move.b    0(a0,d0.w),d1
  1074.           cmp.b     #'/',d1
  1075.           beq.s     CRTL_4              A slash foul (means a directory).
  1076.           cmp.b     #'.',d1
  1077.           beq.s     CRTL_5              A period is ok
  1078.           cmp.b     #'_',d1
  1079.           beq.s     CRTL_5              An underscore is ok
  1080.           cmp.b     #'0',d1
  1081.           blo.s     CRTL_4              Other punctuation $20-$2f is foul
  1082.           cmp.b     #'9',d1
  1083.           bls.s     CRTL_5              Digits are OK
  1084.           cmp.b     #'A',d1
  1085.           blo.s     CRTL_4              ':;<=>?@' are bad
  1086.           cmp.b     #'Z',d1
  1087.           bls.s     CRTL_5              Capital letters ok
  1088.           cmp.b     #'a',d1
  1089.           blo.s     CRTL_4              '[\]^' are bad
  1090.           cmp.b     #'z',d1
  1091.           bls.s     CRTL_5              Lower case letters OK
  1092. CRTL_4    move.b    #'_',0(a0,d0.w)     Replace the illegal character
  1093. CRTL_5    dbf       d0,CRTL_3           Loop backwards through the string
  1094.  
  1095.           move.b    (a0),d0             Check first character of string...
  1096. *                                       ...for alphabetic
  1097.           cmp.b     #'A',d0
  1098.           blo.s     CRTL_6              Less than 'A' -> not alpha
  1099.           cmp.b     #'Z',d0
  1100.           bls.s     CRTL_7              In 'A'..'Z' -> alpha
  1101.           cmp.b     #'a',d0
  1102.           blo.s     CRTL_6              Less than 'a' -> not alpha
  1103.           cmp.b     #'z',d0
  1104.           bls.s     CRTL_7              In 'a'..'z' -> alpha
  1105. CRTL_6    sf        d0                  Invalid file name
  1106.           move.l    (sp)+,d1            restore working reg.
  1107.           rts
  1108. CRTL_7    st        d0                  Valid file name
  1109.           move.l    (sp)+,d1            restore working reg.
  1110.           rts
  1111.  
  1112. ********************************* CLocTRem ****************************
  1113. *                                                                     *
  1114. *  Convert filenames in local system syntax in a form suitable for    *
  1115. *  the remote Kermit system. The job that this routine must do is     *
  1116. *  explained here in detail.                                          *
  1117. *                                                                     *
  1118. *  Adapted from the "Kermit Protocol Manual", Sixth Edition, p. 16    *
  1119. *                                                                     *
  1120. *   1. Delete all pathnames and attributes from the file              *
  1121. *      specification. The file name should not contain directory      *
  1122. *      or device names  if it does, it may cause the recipient to     *
  1123. *      try to store the file in an inaccessible or nonexistent area,  *
  1124. *      or it may result in a very strange filename.                   *
  1125. *                                                                     *
  1126. *   2. After stripping any pathname, convert the remainder of the     *
  1127. *      file specification to the form "name.type", with no            *
  1128. *      restriction on length (except that it fit in the data field    *
  1129. *      of the F packet), and:                                         *
  1130. *                                                                     *
  1131. *         a. Include no more than one dot.                            *
  1132. *         b. Not begin or end with a dot.                             *
  1133. *         c. The name and type fields contain digits and uppercase    *
  1134. *            letters only.                                            *
  1135. *                                                                     *
  1136. *         Entry conditions : A0.L points to the string to be          *
  1137. *                                 converted                           *
  1138. *                                                                     *
  1139. *         Exit  conditions : A0.L points to the same string suitably  *
  1140. *                                 converted                           *
  1141. *                                                                     *
  1142. ***********************************************************************
  1143. CLocTRem: movem.l   d1-d3/a1,-(sp)
  1144.           clr.w     d0                  Zero out counter
  1145.           moveq     #FilNamML-1,d1      File name string Maximum length in OS-9
  1146. CTRL_1    tst.b     (a0,d0.w)           Find length of string.
  1147.           beq.s     CTRL_2              Found the null
  1148.           addq      #1,d0               Keep counting
  1149.           dbf       d1,CTRL_1           ...until length exceeded
  1150.           clr.b     0(a0,d0.w)          Terminate the string properly.
  1151.  
  1152. CTRL_2    move.l    a0,a1               point to start of string
  1153.           move.w    d0,d3               Save string length
  1154.           subq      #1,d0               one less for dbf loop.
  1155.  
  1156. *  Is there a leading pathname?
  1157.  
  1158.           move.b    #'/',d1             Looking for a directory mark.
  1159. CTRL_21   cmp.b     (a1,d0.w),d1
  1160.           dbeq      d0,CTRL_21          Exit loop when one found.
  1161.           bne       CTRL_29             None found
  1162.  
  1163. *  Move the simple file name forward in the name buffer.
  1164.  
  1165.           lea       1(a1,d0.w),a1       Point to first character of file name
  1166.           move.w    d3,d1               Get original length of string.
  1167.           sub.w     d0,d1               Get length of simple file name.
  1168.           subq      #1,d1               ...minus one for dbf loop
  1169. CTRL_22   move.b    (a1,d1.w),(a0,d1.w) Move the simple file name forward
  1170.           dbf       d1,CTRL_22
  1171.  
  1172. *  Restore the counter and pointer for the next loop
  1173.  
  1174. CTRL_29   move.l    a0,a1               Copy start of string address
  1175.           move.w    d3,d0               Get count of string length
  1176.           subq      #1,d0               ...minus one for the dbf loop.
  1177.  
  1178. *  Replace any punctuation with periods.
  1179.  
  1180. CTRL_3    move.b    (a1)+,d1
  1181.           cmp.b     #'0',d1
  1182.           blo.s     CTRL_4              Punctuation $20-$2f is foul
  1183.           cmp.b     #'9',d1
  1184.           bls.s     CTRL_5              Digits are OK
  1185.           cmp.b     #'A',d1
  1186.           blo.s     CTRL_4              ':;<=>?@' are bad
  1187.           cmp.b     #'Z',d1
  1188.           bls.s     CTRL_5              Capital letters ok
  1189.           cmp.b     #'a',d1
  1190.           blo.s     CTRL_4              '[\]^' are bad
  1191.           cmp.b     #'z',d1
  1192.           bls.s     CTRL_5              Lower case letters OK
  1193. CTRL_4    move.b    #'.',-1(a1)         Replace the illegal character
  1194. CTRL_5    dbf       d0,CTRL_3           Loop backwards through the string
  1195.  
  1196. *  Make the string all capitals
  1197.  
  1198.           move.l    a0,a1               Point to start of string
  1199.           move.w    d3,d0               Count of characters.
  1200.           subq.w    #1,d0               Account for dbf loop.
  1201.  
  1202. CTRL_6    move.b    (a1)+,d1            Get a byte of string.
  1203.           cmp.b     #'a',d1
  1204.           blo.s     CTRL_7              Less than 'a' -> not lower case alpha
  1205.           cmp.b     #'z',d1
  1206.           bhi.s     CTRL_7              Not in 'a'..'z' -> not lower case alpha
  1207.           sub.b     #'a'-'A',d1
  1208.           move.b    d1,-1(a1)           Replace character
  1209. CTRL_7    dbf       d0,CTRL_6           Go back for more.
  1210.  
  1211. *  Can't begin or end with a '.'
  1212.  
  1213.           move.b    #'.',d1
  1214.           cmp.b     (a0),d1             Is first character a period?
  1215.           bne.s     CTRL_8
  1216.           move.b    #'X',(a0)           Replace with an 'X'
  1217. CTRL_8    cmp.b     -1(a0,d3),d1        Last character a period?
  1218.           bne.s     CTRL_9
  1219.           move.b    #'X',-1(a0,d3)
  1220.  
  1221.  
  1222. * Replace all but first period with 'X'
  1223.  
  1224. CTRL_9    move.l    a0,a1               Point to start of string.
  1225.           sf        d2                  Haven't found a period yet.
  1226.           move      d3,d0               Counter
  1227.           subq      #1,d0               account for dbf loop.
  1228.  
  1229. CTRL_10   cmp.b     (a1)+,d1            Get a byte of the string
  1230.           bne.s     CTRL_12             Not a period, leave it alone
  1231.           tst.b     d2                  Seen a period?
  1232.           beq.s     CTRL_11             ...not yet, leave this one alone
  1233.  
  1234.           move.b    #'X',-1(a1)         mask out the period
  1235. CTRL_11   st        d2                  We've seen a period now.
  1236. CTRL_12   dbf       d0,CTRL_10
  1237.           st        d0                  Valid file name
  1238.           movem.l   (sp)+,d1-d3/a1
  1239.           rts
  1240.  
  1241. ********************************** NewName ****************************
  1242. *                                                                     *
  1243. *  Make a new name for the given file to avoid file name collisions.  *
  1244. *                                                                     *
  1245. *         Entry conditions : A0.L points to the file name string      *
  1246. *                                                                     *
  1247. *         Exit  conditions : A0.L points to the same string suitably  *
  1248. *                                 modified                            *
  1249. *                                                                     *
  1250. *  OS-9 Note:  This routine just places an underscore character at    *
  1251. *    beginning of the file name to rename it.                         *
  1252. ***********************************************************************
  1253. NewName:  move.l    a1,-(sp)
  1254.           move.l    a0,a1               Copy string pointer
  1255.           moveq     #FilNamML-2,d0      Start from the end of longest file name
  1256.  
  1257. NewNm_1   move.b    0(a0,d0.w),1(a0,d0.w) Move the current name one byte forward
  1258.           dbf       d0,NewNm_1          Keep counting back through string
  1259.  
  1260.           move.b    #'_',(a0)           Put an underscore at start of string
  1261.           clr.b     FilNamML(a0)        Make sure string is null terminated.
  1262.           st        d0                  Set a good completion code
  1263.           move.l    (sp)+,a1
  1264.           rts
  1265.  
  1266. ********************************** Sleep ******************************
  1267. *                                                                     *
  1268. *  Puts the process to sleep.                                         *
  1269. *                                                                     *
  1270. *         Entry conditions : D0.B time interval to wait (seconds)     *
  1271. *                                                                     *
  1272. *         Exit  conditions : none                                     *
  1273. *                                                                     *
  1274. ***********************************************************************
  1275. Sleep:    move.l    d1,-(sp)
  1276.           ext.w     d0                  Need to pass a long tick count
  1277.           ext.l     d0                  ...extending some more.
  1278.           asl.l     #8,d0               Compute 256ths of second to sleep
  1279.           moveq     #31,d1              Need to set the high bit...
  1280.           bset      d1,d0               ...of the tick count, in order...
  1281.           os9       F$Sleep             ...to achieve system independence.
  1282.           move.l    (sp)+,d1
  1283.           rts
  1284.  
  1285.           align
  1286.           ends
  1287.           end
  1288.