home *** CD-ROM | disk | FTP | other *** search
/ ftp.barnyard.co.uk / 2015.02.ftp.barnyard.co.uk.tar / ftp.barnyard.co.uk / cpm / walnut-creek-CDROM / ENTERPRS / CPM / UTILS / S / SPLIT13.LBR / SPLIT13.ZZ0 / SPLIT13.Z8°
Text File  |  2000-06-30  |  11KB  |  573 lines

  1. ;        File Splitter
  2. ;
  3. ;By  Guy Cousineau  1988-02-02
  4. ;
  5. ;This utility has no copyright and is
  6. ;being released to the public domain.  It
  7. ;has been thouroughly tested and should
  8. ;behave as advertized.  The author,
  9. ;however, will assume no responsibility
  10. ;for loss or damage resulting from the
  11. ;use of the program.  The source code
  12. ;only is being released; it should
  13. ;assemble easily with any Z80 assembler.
  14. ;
  15. ;comments or suggestions?
  16. ;
  17. ;    Guy Cousineau
  18. ;    1059 Hindley Street
  19. ;    Ottawa Ontario
  20. ;    K2B 5L9
  21. ;    613-829-6354
  22. ;        Ottawa RCPM (613) 829-2530
  23. ;
  24. ;Syntax SPLIT [d:]ufn [d:]nn [/n]
  25. ;
  26. ;Drive spec optional.
  27. ;If source and destination are the same,
  28. ;swap prompts will be given unless the
  29. ;'/n' option is used to create the split
  30. ;files on the same media.
  31. ;
  32. ;files are split in 16k segments unless
  33. ;overriden by 'nn'
  34. ;
  35. ;e.g. SPLIT long.doc 20 /n
  36. ;will split long.doc in 20k segments
  37. ;on the default drive with no disk swaps
  38. ;
  39. ;    Warning I
  40. ;The output files will have the same name
  41. ;except that the last 2 characters of the
  42. ;file type will have the section number
  43. ;starting at 01.  For example, splitting
  44. ;LONG.DOC would yield files LONG.D01
  45. ;LONG.D02, etc.  Be Sure Your Input File
  46. ;Does Not Have A Number In The Last Two
  47. ;Position.
  48. ;
  49. ;    Warning Ii
  50. ;
  51. ;The utility will not work with Wordstar
  52. ;type files with high bit set on <LF>.
  53. ;
  54. ;
  55. ;Revision History:
  56. ;
  57. ;    1.0    ??-??    first release
  58. ;    1.1    ??-??    introduced the noswap option
  59. ;    1.2    92-06    fixed split bug on files over 144k
  60. ;            added variable output file size
  61. ;    1.3    92-07    fixed write bug for generic CP/M
  62. ;
  63. ;System Equates
  64. ;
  65. GETKEY    EQU    1    ;Read keyboard
  66. PRINTC    EQU    2    ;Print character
  67. PRINT    EQU    9    ;Print string
  68. RESET    EQU    13    ;Log in drive for R/W
  69. OPEN    EQU    15    ;Open file
  70. CLOSE    EQU    16    ;Close file
  71. DELETE    EQU    19    ;Delete file
  72. READ    EQU    20    ;Read sequential
  73. WRITE    EQU    21    ;Write sequential
  74. MAKE    EQU    22    ;Make file
  75. GETDSK    EQU    25    ;Get current disk
  76. SETDMA    EQU    26    ;Set memory address for R/W
  77. ;
  78. FCB    EQU    5CH
  79. FCB2    EQU    6CH
  80. BDOS    EQU    5
  81. DMA    EQU    80H
  82. ;
  83.     ORG    100H
  84.     LD    (OLDSP),SP
  85.     LD    SP,STACK
  86. ;
  87.     LD    HL,FCB+1
  88.     LD    A,(HL)
  89.     LD    DE,SYNTAX
  90.     CP    ' '
  91.     JP    Z,QUIT        ;No file given, show syntax
  92. ;
  93. ;Check For Wild Cards
  94. ;
  95.     LD    BC,11
  96.     LD    A,'?'
  97.     CPIR
  98.     LD    DE,WILD
  99.     JP    Z,QUIT
  100. ;
  101. ;Check For Invalid Type
  102. ;
  103.     LD    DE,NUMERR
  104.     LD    A,(FCB+11)
  105.     CP    '1'        ;'0' is Ok
  106.     JR    C,NONUM
  107.     CP    '9'+1
  108.     JP    C,QUIT        ;if last digit between 1 and 9
  109. ;
  110. NONUM
  111.     XOR    A
  112.     LD    (FCB+12),A    ;extent
  113.     LD    (FCB+14),A    ;S2
  114.     LD    (FCB+32),A    ;record count
  115. ;
  116.     LD    HL,FCB        ;input file
  117.     LD    DE,WFCB        ;store it here for write
  118.     LD    BC,12
  119.     LDIR
  120. ;
  121.     LD    A,(FCB2)
  122.     OR    A        ;if none specified then same
  123.     JR    Z,SAMEDISK
  124.     LD    HL,FCB
  125.     CP    (HL)        ;if same as source drive
  126.     JR    Z,SAMEDISK
  127.     LD    (WFCB),A
  128.     LD    (SAMEDSK),A
  129.     XOR    A
  130.     LD    (SWAPFLG),A    ;if different clear swap flag
  131.     JR    SETDISK
  132. ;
  133. ;Check For Noswap
  134. ;
  135. SAMEDISK
  136.     LD    HL,DMA
  137.     LD    C,(HL)
  138.     LD    B,0
  139.     LD    A,'/'        ;option delimiter
  140.     CPIR
  141.     JR    NZ,SETDISK
  142.     LD    A,(HL)
  143.     AND    5FH
  144.     SUB    'N'
  145.     LD    (SWAPFLG),A    ;Will be zero only if 'n' or 'n'
  146. ;
  147. ;Set Default Drive To Actual
  148. ;Since Disk Reset Will Interfere
  149. ;
  150. SETDISK
  151.     LD    C,GETDSK
  152.     CALL    BDOS
  153.     LD    B,A
  154.     INC    B        ;adjust to drive code
  155.     LD    HL,FCB
  156.     LD    A,(HL)
  157.     OR    A
  158.     JR    NZ,SETD1
  159.     LD    (HL),B
  160. SETD1
  161.     LD    HL,WFCB
  162.     LD    A,(HL)
  163.     OR    A
  164.     JR    NZ,CHECKSIZE
  165.     LD    (HL),B
  166. ;
  167. ;check for override of default split size
  168. ;
  169. CHECKSIZE:
  170.     LD    HL,FCB+17    ;byte 1 of FCB 2
  171.     LD    A,(HL)        ;check to see
  172.     CP    ' '        ;if it is empty
  173.     JR    Z,SETLAST    ;then use default 16k
  174.     CP    '/'        ;or option character
  175.     JR    Z,SETLAST    ;
  176.     SUB    '0'        ;is it a number
  177.     JP    C,BADNUM    ;abort program
  178.     CP    10        ;make sure less than 10
  179.     JP    NC,BADNUM
  180.     LD    B,A        ;save a times 1
  181.     RLCA            ;2*a
  182.     RLCA            ;4*a
  183.     ADD    A,B        ;5*a
  184.     RLCA            ;10*a
  185.     LD    B,A        ;save in B temporarily
  186.     INC    HL        ;next byte
  187.     LD    A,(HL)        ;get it and check vailidity
  188.     SUB    '0'
  189.     JP    C,BADNUM
  190.     CP    10
  191.     JP    NC,BADNUM
  192.     ADD    A,B        ;add Tens to units just retrieved
  193.     CP    33
  194.     JP    NC,BADNUM    ;set max to 32k
  195. ;
  196. ;now turn it into records
  197. ;
  198.     LD    H,0
  199.     LD    L,A
  200.     ADD    HL,HL
  201.     ADD    HL,HL
  202.     ADD    HL,HL        ;*8
  203.     LD    A,L
  204.     LD    (PATCH1),A
  205.     LD    (PATCH2),A
  206.     LD    (PATCH3),A
  207.     ADD    HL,HL        ;*16
  208.     ADD    HL,HL        ;*32
  209.     ADD    HL,HL        ;*64
  210.     ADD    HL,HL        ;*128
  211.     ADD    HL,HL        ;*256
  212.     ADD    HL,HL        ;*512
  213.     ADD    HL,HL        ;*1024
  214.     LD    DE,BUFFER
  215.     ADD    HL,DE        ;get offset to end of buffer
  216.     LD    (PATCH4),HL
  217.     DEC    HL
  218.     DEC    HL
  219.     LD    (PATCH5),HL
  220. ;
  221. ;Set Last Character Of File Type To '0'
  222. ;
  223. SETLAST
  224.     LD    HL,WFCB+11    ;Last Digit Of File Type
  225.     LD    B,'0'
  226.     LD    (HL),B        ;Set Count To 0
  227.     DEC    HL
  228.     LD    (HL),B
  229.     DEC    HL
  230.     LD    A,(HL)        ;set first of fle type to '0' if blank
  231.     CP    ' '
  232.     JR    NZ,GO
  233.     LD    (HL),B    
  234. ;
  235. GO
  236.     LD    DE,START
  237.     CALL    PROMPT        ;in case we need a swap to start
  238. ;
  239. ;Find File And Open It
  240. ;
  241.     LD    DE,FCB
  242.     LD    C,OPEN
  243.     CALL    BDOS
  244.     LD    DE,NOFL        ;error message just in case
  245.     INC    A        ;255+1=0 on error
  246.     JP    Z,QUIT        ;show error and exit
  247. ;
  248. ;Zero Record Count
  249. ;
  250. READAGAIN
  251.     XOR    A
  252.     LD    (IRCNUM),A
  253. ;
  254.     LD    DE,FCB
  255.     PUSH    DE
  256. ;
  257. ;Set Up DMA For Read
  258. ;
  259.     LD    HL,BUFFER
  260.     LD    DE,(OBUFF)    ;Get read-in offset
  261.     ADD    HL,DE        ;write in file here
  262.     CALL    INCB1        ;set DMA and buffer
  263. ;
  264. ;Read Next Record Of File
  265. ;
  266.     LD    B,16*8        ;read 16k at a time
  267. PATCH1    EQU    $-1
  268. READF
  269.     POP    DE        ;FCB
  270.     PUSH    DE
  271.     PUSH    BC
  272.     LD    C,READ
  273.     CALL    BDOS
  274.     OR    A        ;=0 if good read and not EOF
  275.     JR    NZ,XDISK    ;get ready to write
  276.     CALL    INCBUF        ;increment DMA for next record
  277.     LD    HL,IRCNUM
  278.     LD    A,(HL)        ;In record count
  279.     INC    A
  280.     LD    (HL),A
  281.     CALL    DUMPIT        ;print value in A
  282.     POP    BC
  283.     DJNZ    READF
  284. ;
  285. ;Prompt For Disk Change
  286. ;
  287. XDISK
  288.     POP    DE        ;Clean up stack
  289.     LD    A,(SWAPFLG)
  290.     OR    A
  291.     JR    Z,NOSWAP
  292.     LD    DE,DDISK    ;Swap disk message
  293.     CALL    PROMPT
  294.     LD    C,RESET
  295.     CALL    BDOS
  296. ;
  297. ;Increment File Type
  298. ;
  299. NOSWAP
  300.     LD    HL,WFCB+11    ;Last digit of file type
  301.     LD    A,(HL)
  302.     INC    A
  303.     CP    '9'+1
  304.     JR    NZ,GOODNUMBER    ;just increment last digit
  305.     DEC    HL        ;move to previous
  306.     INC    (HL)        ;bump it up
  307.     INC    HL        ;back to last
  308.     LD    A,'0'        ;make it Zero
  309. GOODNUMBER:
  310.     LD    (HL),A
  311.     XOR    A
  312.     LD    (ORCNUM),A    ;output record count
  313.     LD    (WFCB+12),A    ;extent
  314.     LD    (WFCB+14),A    ;S2
  315.     LD    (WFCB+32),A    ;record number
  316. ;
  317. ;Delete File Name From Destination Disk
  318. ;
  319.     LD    DE,WFCB
  320.     PUSH    DE
  321.     LD    C,DELETE
  322.     CALL    BDOS
  323. ;
  324. ;Create New File
  325. ;    
  326.     POP    DE
  327.     PUSH    DE
  328.     LD    C,MAKE
  329.     CALL    BDOS
  330.     LD    DE,BADIR    ;error message
  331.     INC    A        ;255+1=0 on error
  332.     JR    Z,QUIT
  333. ;
  334. ;Find Last <LF> In File
  335. ;
  336.     LD    A,(IRCNUM)
  337.     CP    16*8        ;Read a full extent?
  338. PATCH2    EQU    $-1
  339.     JP    NZ,LASTWRITE
  340.     LD    HL,SAFEREC    ;safety buffer to read all of last extent
  341.     INC    (HL)        ;write one more record for each split
  342. ;
  343. ;Start At The End Of The Buffer -2 Characters
  344. ;If Either Of The Last 2 Characters Are <LF>
  345. ;We Will Get A Negative Offset Later.
  346. ;
  347.     LD    HL,BUFFER+16*1024-2
  348. PATCH5    EQU    $-2
  349.     LD    A,10        ;<LF>
  350.     LD    BC,-1        ;Make sure we find one
  351.     CPDR
  352. ;Presume One Is Found
  353.     INC    HL        ;Move back to last <LF>
  354.     INC    HL        ;Use next character after <LF>
  355.     LD    (LASTLF),HL    ;Save the address
  356.     LD    A,(HL)
  357.     LD    (LASTC),A    ;Save character
  358.     LD    (HL),26        ;Write EOF
  359. ;
  360. ;Set Up DMA For Write
  361. ;
  362. WRITE1
  363.     LD    HL,BUFFER    ;Write file from start of buffer
  364.     CALL    INCB1        ;set DMA
  365. ;
  366. ;Start To Write File
  367. ;    
  368. WRITEF
  369.     POP    DE        ;FCB
  370.     PUSH    DE
  371.     LD    C,WRITE
  372.     CALL    BDOS
  373.     LD    DE,BADFL    ;Write error message
  374.     OR    A
  375.     JP    NZ,QUIT
  376.     CALL    INCBUF        ;Get next DMA
  377.     LD    HL,ORCNUM    ;Records written
  378.     LD    A,(HL)
  379.     INC    A
  380.     LD    (HL),A
  381.     LD    B,A        ;Save count in B
  382.     CALL    DUMPIT
  383.     LD    A,(IRCNUM)    ;Amount to copy
  384.     SUB    B        ;Write as many as we read?
  385.     JR    NZ,WRITEF    ;Not done yet
  386. ;
  387. ;Close File
  388. ;
  389.     POP    DE        ;FCB
  390.     LD    C,CLOSE
  391.     CALL    BDOS
  392.     LD    DE,BDCLOSE    ;Error message
  393.     INC    A        ;255+1=0 on error
  394.     JR    Z,QUIT
  395. ;
  396. ;Write Output File Name To Screen
  397. ;
  398.     LD    A,32        ;Start with a space
  399.     CALL    PRCHR
  400.     LD    HL,WFCB+1    ;Name starts here
  401.     LD    B,11        ;Length of name
  402. FNAME1
  403.     LD    A,(HL)
  404.     CALL    PRCHR
  405.     INC    HL
  406.     DJNZ    FNAME1
  407. ;
  408. ;Check If Last Read
  409. ;
  410.     LD    A,(ORCNUM)
  411.     CP    16*8        ;Did we write 16k?
  412. PATCH3    EQU    $-1
  413.     JR    Z,NOTYET
  414.     LD    DE,DONE
  415. QUIT
  416.     LD    C,PRINT
  417.     CALL    BDOS
  418. QUIT1
  419.     LD    SP,(OLDSP)
  420.     RET
  421. ;
  422. ;bad number specification in output file size
  423. ;
  424. BADNUM:
  425.     LD    DE,BADSIZE
  426.     JR    QUIT
  427. ;
  428. ;***    End Of Program    ***
  429. ;
  430. ;Not Done Yet
  431. ;
  432. NOTYET
  433.     LD    DE,SDISK    ;Swap disk message
  434.     LD    A,(SWAPFLG)
  435.     OR    A
  436.     CALL    NZ,PROMPT
  437. ;
  438. ;Restore Old Character
  439. ;
  440.     LD    HL,(LASTLF)
  441.     LD    A,(LASTC)
  442.     LD    (HL),A
  443. ;
  444. ;Move From This Byte To End Of Read Buffer
  445. ;To Beginning Of Read Buffer
  446. ;And Calculate New Offset
  447. ;    
  448.     EX    DE,HL        ;DE=last character
  449.     LD    HL,BUFFER+1024*16 ;Normal buffer end
  450. PATCH4    EQU    $-2
  451.     LD    BC,(OBUFF)    ;Get read offset
  452.     ADD    HL,BC        ;Current end of data
  453.     XOR    A
  454.     SBC    HL,DE        ;New offset and bytes to relocate
  455.     LD    (OBUFF),HL
  456.     PUSH    HL
  457.     POP    BC        ;Bytes to move
  458.     EX    DE,HL        ;Start at last character
  459.     LD    DE,BUFFER    ;Move to here
  460.     LDIR
  461.     JP    READAGAIN
  462. ;
  463. ;Get Extra Record Count For Last Write
  464. ;
  465. LASTWRITE
  466.     LD    A,(SAFEREC)    ;Extra records to write
  467.     LD    B,A
  468.     LD    HL,ORCNUM    ;Output record number=0
  469. SAFE
  470.     DEC    (HL)        ;Set to -1, -2, Etc
  471.     DJNZ    SAFE
  472.     JP    WRITE1        ;Write out last segment
  473. ;
  474. ;
  475. ;***    Subroutines    ***
  476. ;
  477. ;Print Message In DE
  478. ;Get Keypress And Abort On ^c
  479. ;
  480. PROMPT    LD    C,PRINT
  481.     CALL    BDOS
  482.     LD    C,GETKEY
  483.     CALL    BDOS        ;Wait for keypress
  484.     CP    3        ;^c
  485.     JR    Z,QUIT1        ;if aborted
  486.     RET
  487. ;
  488. ;Advance DMA By 1 Record
  489. ;
  490. INCBUF    LD    HL,(TDMA)    ;Where it was
  491.     LD    DE,80H        ;Add 1 record
  492.     ADD    HL,DE
  493. INCB1    LD    (TDMA),HL
  494.     EX    DE,HL
  495.     LD    C,SETDMA
  496.     CALL    BDOS
  497.     RET
  498. ;
  499. ;Display A In Hex
  500. ;
  501. DUMPIT
  502.     PUSH    AF
  503.     LD    A,13        ;<CR>
  504.     CALL    PRCHR
  505.     POP    AF
  506.     PUSH    AF
  507.     RRCA
  508.     RRCA
  509.     RRCA
  510.     RRCA            ;Get high nibble
  511.     CALL    DUMP
  512.     POP    AF        ;Get low nibble
  513. DUMP
  514.     AND    0FH        ;Mask off top bits
  515.     ADD    A,'0'        ;Ascii offset
  516.     CP    '9'+1
  517.     JR    C,PRCHR        ;Not a hex digit
  518.     ADD    A,7        ;Offset for A-f display
  519. ;
  520. ;Falls Through To Print Routine
  521. ;
  522. PRCHR
  523.     PUSH    BC
  524.     PUSH    DE
  525.     PUSH    HL
  526.     LD    E,A        ;Character To Print
  527.     LD    C,PRINTC    ;Function
  528.     CALL    BDOS
  529.     POP    HL
  530.     POP    DE
  531.     POP    BC
  532.     RET
  533. ;
  534. ;Messages
  535. ;Note Wild Message Links To Syntax
  536. ;
  537. WILD    DB    7,'No Wild Cards Allowed',13,10
  538. SYNTAX    DB    'SYNTAX: SPLIT [d:]ufn [d:]nn [/N]'
  539.     DB    13,10,'Where /N means no disk swap'
  540.     DB    13,10,'and nn is the split size (default 16K)$'
  541. NUMERR    DB    7,'No numbers allowed in last character$'
  542. START    DB    12,9,'FILE SPLITTER V1.3',13,10
  543.     DB    9,'BY  Guy Cousineau',13,10,10
  544.     DB    7,'Insert source  (^C ABORTS)',13,10,10,'$'
  545. NOFL    DB    13,10,'Can''t find source$'
  546. DDISK    DB    7,' Records read--insert dest',10,'$'
  547. SDISK    DB    7,'  written',13,10,9,'  Insert source',10,'$'
  548. BADIR    DB    13,10,'No directory space$'
  549. BADFL    DB    13,10,'Bad write$'
  550. DONE    DB    13,10,7,9,'--ALL DONE--',13,10,'$'
  551. BDCLOSE    DB    13,10,'Can''t close file$'
  552. BADSIZE    DB    13,10,'Bad split size specification'
  553.     DB    13,10,'Must be between 10 and 32$'
  554. ;
  555. ;Data Storage Area
  556. ;
  557. SAMEDSK    DB    0        ;Source and destination same
  558. SWAPFLG    DB    1        ;Print Swap message
  559. SAFEREC    DB    0        ;Number of extra records to write at end
  560. IRCNUM    DB    0        ;Input record number count
  561. ORCNUM    DB    0        ;Output record number count
  562. OBUFF    DW    0        ;Offset between read and write buffers
  563. TDMA    DS    2        ;Save DMA address here
  564. OLDSP    DS    2
  565. LASTLF    DS    2        ;Save address of last found <LF>
  566. LASTC    DS    1        ;Save last charcater at EOF
  567. WFCB    DS    33
  568.     DS    20H        ;Generous stack space
  569. STACK
  570. BUFFER    EQU    $        ;Copy buffer starts here
  571.     END
  572. ;
  573.