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 / CPM / PROGRAMS / SORT / SORTV-15.LBR / SORTV-15.ZQ0 / SORTV-15.Z80
Text File  |  2000-06-30  |  14KB  |  822 lines

  1. ;         SORTV.ASM ver 1.5
  2. ;        by Ward Christensen
  3. ;         (revised 1/26/86)
  4. ;
  5. ;Simple sort program for sorting lists of names,
  6. ;or any other variable length file, with CR/LF
  7. ;delimited records.
  8. ;
  9. ;This is a "simple" program: FILE MUST FIT IN MEMORY.
  10. ;
  11. ;01/26/86 Changed to z80 code and added ? wildcard skip character
  12. ;         for fixed column number sort. D. L. Anderton
  13. ;
  14. ;06/29/81 Cleaned up file and re-tabified it.  (KBP)
  15. ;
  16. ;06/22/81 Changed so MAC is not needed. Changed so alternate or
  17. ;      standard CP/M may be selected. By Ted Shapin.
  18. ;
  19. ;01/03/81 Change stack init.  By Keith Petersen, W8SDZ
  20. ;
  21. ;11/15/80 Add @ command (WLC)
  22. ;
  23. ;10/24/80 Originally written by Ward Christensen
  24. ;
  25. ;FORMAT:
  26. ;    SORTV input-name output-name
  27. ; OR    SORTV name
  28. ;
  29. ;If the second format is used, the file is read into
  30. ;memory, sorted, erased, created, and written back.
  31. ;
  32. ;    The sort will be based on the first characters
  33. ;    in the file, unless the command is followed by
  34. ;    an "@" sign, then a string (1 or more characters)
  35. ;    to skip.  If these are present, the line will be
  36. ;    sorted starting after one of these characters.
  37. ;
  38. ;Example: SORTV NAMES.SUB @.
  39. ;
  40. ;Will sort NAMES.SUB by filetype, since it skips past
  41. ;the "." before doing the compare.
  42. ;
  43. EOF    EQU    1AH
  44. CR    EQU    0DH
  45. LF    EQU    0AH
  46. ;
  47. BIAS    EQU    0        ;0 FOR STANDARD CP/M, 4200H FOR ALTERNATE CP/M
  48. ;
  49. ;BDOS/CBIOS EQUATES (VERSION 10)
  50. ;
  51. RDCON    EQU    1
  52. WRCON    EQU    2
  53. PRINT    EQU    9
  54. RDCONBF EQU    10
  55. CONST    EQU    11
  56. OPEN    EQU    15
  57. CLOSE    EQU    16
  58. SRCHF    EQU    17
  59. SRCHN    EQU    18
  60. ERASE    EQU    19
  61. READ    EQU    20
  62. WRITE    EQU    21
  63. MAKE    EQU    22
  64. REN    EQU    23
  65. STDMA    EQU    26
  66. BDOS    EQU    5+BIAS
  67. FCB    EQU    5CH+BIAS
  68. FCB2    EQU    6CH+BIAS
  69. FCBEXT    EQU    FCB+12
  70. FCBRNO    EQU    FCB+32
  71. ;
  72.     ORG    100H+BIAS
  73. ;
  74. ;INIT LOCAL STACK
  75. ;
  76.     LD    SP,STACK
  77. ;
  78.     CALL    START
  79.     DEFB    'SORTV rev 1.5'
  80.     DEFB    CR,LF,'$'
  81. ;
  82. START:    POP    DE        ;GET ID
  83.     LD    C,PRINT
  84.     CALL    BDOS        ;PRINT ID
  85. ;
  86. ;START OF PROGRAM EXECUTION
  87. ;
  88.     CALL    SVSKIP        ;SAVE SKIP INFO
  89.     CALL    CKNAMES        ;SEE THAT 2 NAMES ARE THERE
  90.     CALL    OPENIN        ;OPEN INPUT FILE
  91.     CALL    READN        ;READ THE NAMES
  92.     CALL    SORTN        ;SORT THE NAMES
  93.     CALL    WRITEN        ;WRITE THE NAMES
  94.     CALL    ERXIT
  95.     DEFB    '++DONE++$'
  96. ;
  97. ;====>    SUBROUTINES
  98. ;    ----------------
  99. ;
  100. ;====>    SAVE "SKIP TO" INFORMATION
  101. ;
  102. SVSKIP:    LD    HL,81H+BIAS
  103. ;
  104. SVSKL:    LD    A,(HL)
  105.     OR    A
  106.     RET    Z        ;NO 'SKIP TO'
  107.     CP    '@'        ;SKIP DELIMITER?
  108.     INC    HL
  109.     JP    NZ,SVSKL
  110.     LD    DE,SKIPC    ;CHARS TO SKIP
  111. ;
  112. SVSKL2:    LD    A,(HL)
  113.     LD    (DE),A
  114.     INC    HL
  115.     INC    DE
  116.     OR    A
  117.     JP    NZ,SVSKL2
  118.     RET    
  119. ;
  120. ;====>    CHECK THAT 2 NAMES WERE SUPPLIED
  121. ;
  122. CKNAMES:LD    A,(FCB+1)
  123.     CP    ' '
  124.     JP    Z,NONAME
  125.     LD    A,(FCB2+1)
  126.     CP    ' '
  127.     JP    Z,SAMENAM
  128.     CP    '@'        ;SKIP PARM?
  129.     JP    Z,SAMENAM
  130.     LD    HL,FCB2
  131.     LD    DE,OUTNAME
  132.     LD    BC,12
  133.     CALL    MOVER
  134.     RET    
  135. ;
  136. ;OUTPUT NAME = INPUT NAME
  137. ;
  138. SAMENAM:LD    HL,FCB
  139.     LD    DE,OUTNAME
  140.     LD    BC,12
  141.     CALL    MOVER
  142.     RET    
  143. ;
  144. NONAME:    CALL    ERXIT
  145.     DEFB    '++Error - ',CR,LF
  146.     DEFB    'Command format requires an '
  147.     DEFB    'input name, and an output name.$'
  148. ;
  149. ;====>    OPEN THE INPUT FILE
  150. ;
  151. OPENIN:    PUSH    BC
  152.     PUSH    DE
  153.     PUSH    HL
  154.     LD    C,OPEN
  155.     LD    DE,FCB
  156.     CALL    BDOS
  157.     POP    HL
  158.     POP    DE
  159.     POP    BC
  160.     INC    A
  161.     RET    NZ        ;SUCCESSFUL?  RETURN
  162.     CALL    ERXIT
  163.     DEFB    '++Input file not found$'
  164. ;
  165. ;====>    READ IN THE NAMES
  166. ;
  167. READN:    LD    HL,SBUFF    ;TO FIRST NAME
  168. ;
  169. READNL:    CALL    READL        ;READ ONE LINE
  170.     RET    C        ;GOT EOF, RETURN
  171.     CALL    CHAIN        ;CHAIN THINGS TOGETHER
  172.     JP    READNL
  173. ;
  174. ;====>    READ ONE LINE
  175. ;
  176. READL:    LD    (CURR),HL    ;SAVE CURR LINE PTR
  177.     XOR    A        ;GET 0
  178.     LD    (HL),A        ;INIT FORWARD
  179.     INC    HL        ;    POINTER
  180.     LD    (HL),A        ;    TO
  181.     INC    HL        ;    0
  182.     LD    DE,SKIPC    ;TO CK SKIP CHARS PRESENT
  183. ;
  184. READLLP:LD    A,(BDOS+2)    ;ARE WE
  185.     DEC    A        ;    OVER-
  186.     CP    H        ;    FLOW-
  187.     JP    Z,OFLO        ;    ING?
  188.     PUSH    DE
  189.     PUSH    HL
  190.     LD    HL,EXTFCB
  191.     CALL    RDBYTE        ;READ A BYTE
  192.     POP    HL
  193.     POP    DE
  194.     CP    EOF        ;SET CARRY
  195.     SCF            ;    AND RETURN
  196.     RET    Z        ;    IF EOF
  197.     LD    (HL),A        ;STORE CHAR
  198. ;TEST FOR SKIP CHAR FOUND
  199.     LD    B,A        ;SAVE FOR COMPARE
  200.     LD    A,(DE)
  201.     OR    A        ;NO MORE SKIP CHARS?
  202.     JP    Z,READLNS    ;NO MORE
  203. ;TEST FOR SKIP WILDCARD ?
  204.     CP    '?'
  205.     JP    Z,WLDCRD
  206. ;OR SKIP CHAR
  207.     CP    B        ;A SKIP CHAR?
  208.     JP    NZ,READLNS    ;NO, KEEP TRYIN.
  209. WLDCRD:    INC    DE        ;TO NEXT SKIP CHAR
  210. ;
  211. READLNS:INC    HL        ;POINT TO NEXT
  212.     LD    A,B        ;GET CHAR
  213.     CP    CR        ;END OF LINE?
  214.     JP    NZ,READLLP    ;    NO, LOOP.
  215.     PUSH    DE
  216.     PUSH    HL
  217.     LD    HL,EXTFCB
  218.     CALL    RDBYTE        ;GOBBLE UP LF
  219.     POP    HL
  220.     POP    DE
  221.     LD    A,(DE)        ;GET SKIP CHAR END
  222.     OR    A        ;TEST IT AND SET "NO EOF"
  223.     RET    Z
  224. ;ERROR - NO SKIP CHAR
  225.     LD    HL,(CURR)
  226.     INC    HL        ;SKIP
  227.     INC    HL        ;    POINTER
  228. ;
  229. ERPLP:    LD    E,(HL)
  230.     PUSH    BC
  231.     PUSH    DE
  232.     PUSH    HL
  233.     LD    C,WRCON
  234.     CALL    BDOS
  235.     POP    HL
  236.     POP    DE
  237.     POP    BC
  238.     LD    A,(HL)
  239.     INC    HL
  240.     CP    CR
  241.     JP    NZ,ERPLP
  242.     CALL    ERXIT
  243.     DEFB    LF,'++NO SKIP CHAR FOUND++$'
  244. ;
  245. OFLO:    CALL    ERXIT
  246.     DEFB    '++File won''t fit in memory$'
  247. ;
  248. ;====>    CHAIN RECORDS TOGETHER
  249. ;
  250. CHAIN:    PUSH    HL        ;SAVE POINTER
  251.     LD    HL,(CURR)    ;GET CURRENT
  252.     EX    DE,HL        ;    TO DE
  253.     LD    HL,(PREV)    ;PREV TO HL
  254.     LD    (HL),E        ;MOVE CURR
  255.     INC    HL        ;    TO
  256.     LD    (HL),D        ;    PREV
  257.     EX    DE,HL        ;THEN MOVE
  258.     LD    (PREV),HL    ;    PREV TO CURR
  259.     POP    HL
  260.     RET    
  261. ;
  262. ;====>    SORT THE NAMES
  263. ;
  264. SORTN:    XOR    A        ;SHOW NO
  265.     LD    (SWAPS),A    ;    SWAPS
  266.     LD    HL,PTR        ;POINT PREV
  267.     LD    (PREV),HL    ;    TO PTR
  268.     LD    HL,(PTR)    ;POINT TO FIRST
  269. ;
  270. ;HANDLE WIERD CASE OF ONLY ONE NAME
  271. ;
  272.     LD    A,(HL)        ;GET POINTER
  273.     INC    HL        ;POINT TO NEXT
  274.     OR    (HL)        ;OR TOGETHER
  275.     DEC    HL        ;BACK UP
  276.     RET    Z        ;RETURN IF ONLY ONE
  277. ;
  278. SORTL:    CALL    CMPR        ;COMPARE ENTRIES
  279.     CALL    C,SWAP        ;SWAP IF WRONG ORDER
  280.     CALL    NEXT        ;POINT TO NEXT
  281.     JP    NC,SORTL    ;LOOP IF MORE
  282.     LD    A,(SWAPS)    ;ANY
  283.     OR    A        ;    SWAPS?
  284.     JP    NZ,SORTN    ;YES, LOOP
  285.     RET            ;NO, RETURN
  286. ;
  287. ;---->    COMPARE TWO NAMES
  288. ;
  289. CMPR:    PUSH    HL        ;SAVE POINTER
  290.     LD    E,(HL)        ;GET NEXT
  291.     INC    HL        ;    POINTER
  292.     LD    D,(HL)        ;    TO DE
  293.     INC    DE        ;ALIGN POINTERS
  294. ;
  295. ;SKIP IF NECESSARY
  296. ;
  297.     LD    BC,SKIPC
  298. ;
  299. TSTSKIP:LD    A,(BC)
  300.     OR    A
  301.     JP    Z,COMPL        ;NO SKIP
  302.     INC    BC
  303. ;
  304. SKIP1:    INC    HL
  305.     CP    '?'
  306.     JP    Z,WLD2
  307.     CP    (HL)
  308.     JP    NZ,SKIP1
  309. WLD2:    EX    DE,HL        ;SWAP
  310. ;
  311. SKIP2:    INC    HL
  312.     CP    '?'
  313.     JP    Z,WLD3
  314.     CP    (HL)
  315.     JP    NZ,SKIP2
  316. WLD3:    EX    DE,HL        ;PUT THINGS BACK
  317.     JP    TSTSKIP
  318. ;
  319. COMPL:    INC    DE        ;TO NEXT
  320.     INC    HL        ;TO NEXT
  321.     LD    A,(DE)        ;GET ONE
  322.     CP    (HL)        ;COMPARE
  323.     JP    NZ,COMPNE    ;NO COMPARE
  324.     CP    CR        ;END?
  325.     JP    NZ,COMPL    ;    NO, LOOP
  326. ;
  327. COMPH:    POP    HL        ;RESTORE POINTER
  328.     RET            ;THEY ARE EQUAL
  329. ;
  330. ;COMPARE NOT EQUAL - SEE IF END OF ELEMENT,
  331. ;AND IF SO, CALL THEM EQUAL
  332. ;
  333. COMPNE:    LD    A,(HL)
  334.     CP    CR
  335.     JP    Z,COMPH
  336.     LD    A,(DE)
  337.     CP    (HL)
  338.     JP    COMPH        ;CARRY SET AS APPROP
  339. ;
  340. ;---->    SWAP ENTRIES
  341. ;
  342. ;LOGIC: PTR POINTS TO SOME ENTRY, WHICH POINTS
  343. ;TO ANOTHER ENTRY.  THEY ARE NOT IN ORDER.  THUS:
  344. ;POINT PTR TO THE SECOND, POINT THE SECOND TO
  345. ;THE FIRST, AND POINT THE FIRST TO WHAT THE
  346. ;SECOND USED TO POINT TO.
  347. ;
  348. SWAP:    LD    A,1
  349.     LD    (SWAPS),A    ;SHOW WE SWAPPED
  350. ;BC=NEXT
  351.     LD    C,(HL)
  352.     INC    HL
  353.     LD    B,(HL)
  354.     DEC    HL
  355. ;CHAIN CURRENT TO NEXT ONES CHAIN
  356.     LD    A,(BC)
  357.     LD    (HL),A
  358.     INC    BC
  359.     INC    HL
  360.     LD    A,(BC)
  361.     LD    (HL),A
  362.     DEC    BC
  363.     DEC    HL
  364. ;SAVE CURRENT POINTER IN DE
  365.     EX    DE,HL
  366. ;GET POINTER TO PREV
  367.     LD    HL,(PREV)
  368. ;POINT PREV TO NEXT
  369.     LD    (HL),C
  370.     INC    HL
  371.     LD    (HL),B
  372. ;STORE CURR IN NEXT
  373.     LD    A,E
  374.     LD    (BC),A
  375.     INC    BC
  376.     LD    A,D
  377.     LD    (BC),A
  378.     DEC    BC
  379. ;RESTORE CURRENT POINTER
  380.     EX    DE,HL
  381.     RET            ;CURRENT POINTER IN DE
  382. ;
  383. ;---->    GET NEXT ETRY, CARRY IF NOT 2 MORE
  384. ;
  385. NEXT:    LD    (PREV),HL    ;SAVE POINTER
  386.     LD    E,(HL)
  387.     INC    HL
  388.     LD    D,(HL)
  389.     EX    DE,HL        ;HL= NEXT
  390.     LD    A,H        ;CARRY ON
  391.     OR    L        ;    IF HL
  392.     SCF            ;    =
  393.     RET    Z        ;    0
  394.     LD    A,(HL)        ;GET
  395.     INC    HL        ;SEE IF THERE
  396.     OR    (HL)        ;    IS
  397.     DEC    HL        ;    ANOTHER
  398.     RET    NZ        ;THERE IS ANOTHER
  399.     SCF            ;SHOW NOT 2 TO SWAP
  400.     RET    
  401. ;
  402. ;====>    WRITE THE NAMES
  403. ;
  404. WRITEN:    LD    HL,0        ;INIT
  405.     LD    (EXTFCB+2),HL    ;    EFCB
  406.     XOR    A        ;INIT
  407.     LD    (FCBEXT),A    ;    THE
  408.     LD    (FCBRNO),A    ;    FCB
  409. ;RESTORE NAME
  410.     LD    HL,OUTNAME
  411.     LD    DE,FCB
  412.     LD    BC,12
  413.     CALL    MOVER
  414.     PUSH    BC
  415.     PUSH    DE
  416.     PUSH    HL
  417.     LD    C,ERASE
  418.     LD    DE,FCB
  419.     CALL    BDOS
  420.     POP    HL
  421.     POP    DE
  422.     POP    BC
  423.     PUSH    BC
  424.     PUSH    DE
  425.     PUSH    HL
  426.     LD    C,MAKE
  427.     LD    DE,FCB
  428.     CALL    BDOS
  429.     POP    HL
  430.     POP    DE
  431.     POP    BC
  432.     INC    A        ;MAKE OK?
  433.     JP    Z,BADOUT    ;    NO, ERROR
  434.     LD    HL,(PTR)    ;GET FIRST
  435. ;
  436. WNLP:    CALL    WRITEL        ;WRITE ONE LINE
  437.     JP    NC,WNLP        ;LOOP IF MORE
  438.     LD    A,EOF        ;WRITE EOF CHAR
  439.     PUSH    HL
  440.     LD    HL,EXTFCB
  441.     CALL    WRBYTE
  442.     POP    HL
  443.     LD    HL,EXTFCB    ;FLUSH
  444.     CALL    FLUSH        ;     BUFFERS
  445.     PUSH    BC
  446.     PUSH    DE
  447.     PUSH    HL
  448.     LD    C,STDMA        ;RESET DMA
  449.     LD    DE,80H+BIAS
  450.     CALL    BDOS
  451.     POP    HL
  452.     POP    DE
  453.     POP    BC
  454.     PUSH    BC
  455.     PUSH    DE
  456.     PUSH    HL
  457.     LD    C,CLOSE
  458.     LD    DE,FCB
  459.     CALL    BDOS
  460.     POP    HL
  461.     POP    DE
  462.     POP    BC
  463.     CALL    ERXIT        ;    AND EXIT
  464.     DEFB    '++DONE++$'
  465. ;
  466. WRITEL:    PUSH    HL        ;SAVE POINTER
  467.     INC    HL
  468. ;
  469. WRLP:    INC    HL        ;TO NEXT CHAR
  470.     LD    A,(HL)        ;GET CHAR
  471.     PUSH    HL
  472.     LD    HL,EXTFCB
  473.     CALL    WRBYTE        ;WRITE IT
  474.     POP    HL
  475.     LD    A,(HL)        ;SEE IF END
  476.     CP    CR        ;    OF LINE
  477.     JP    NZ,WRLP        ;NO, LOOP
  478.     LD    A,LF        ;OTHERWISE
  479.     PUSH    HL
  480.     LD    HL,EXTFCB
  481.     CALL    WRBYTE        ;WRITE LF
  482.     POP    HL
  483.     POP    HL        ;GET POINTER
  484.     LD    E,(HL)        ;GET
  485.     INC    HL        ;    FORWARD
  486.     LD    D,(HL)        ;    POINTER
  487.     EX    DE,HL        ;PUT IT IN HL
  488.     LD    A,H        ;IS POINTER
  489.     OR    L        ;    ZERO?
  490.     RET    NZ        ;NO, RETURN
  491.     SCF            ;CARRY SHOWS END
  492.     RET    
  493. ;
  494. BADOUT:    CALL    ERXIT
  495.     DEFB    '++Can''t make output file$'
  496. ;
  497. ;FOLLOWING FROM 'EQU10.LIB'---->
  498. ;
  499. ;MOVE, COMPARE SUBROUTINES
  500. ;
  501. MOVER:    LD    A,(HL)
  502.     LD    (DE),A
  503.     INC    HL
  504.     INC    DE
  505.     DEC    BC
  506.     LD    A,B
  507.     OR    C
  508.     JP    NZ,MOVER
  509.     RET    
  510. ;
  511. ;    FROM EQU10.LIB: AS OF 07/19/80
  512. ;
  513. ;RDBYTE, HL POINTS TO EXTENDED FCB:
  514. ;
  515. ;    2 BYTE BUFFER ADDR
  516. ;    2 BYTE "BYTES LEFT" (INIT TO 0)
  517. ;    1 BYTE BUFFER SIZE (IN PAGES)
  518. ;    2 BYTE FCB ADDRESS
  519. ;
  520. RDBYTE:    LD    E,(HL)
  521.     INC    HL
  522.     LD    D,(HL)        ;GET BUFFER ADDR
  523.     INC    HL
  524.     LD    C,(HL)
  525.     INC    HL
  526.     LD    B,(HL)        ;BC = BYTES LEFT
  527.     LD    A,B        ;GET COUNT
  528.     OR    C
  529.     JP    NZ,RDBNORD    ;NO READ
  530. ;
  531.     INC    HL        ;TO BUFFER SIZE
  532.     LD    A,(HL)        ;GET COUNT
  533.     ADD    A,A        ;MULTIPLY BY 2
  534.     LD    B,A        ;SECTOR COUNT IN B
  535.     INC    HL        ;TO FCB
  536.     PUSH    HL        ;SAVE FCB POINTER
  537.     LD    A,(HL)        ;GET..
  538.     INC    HL
  539.     LD    H,(HL)        ;..ADDR..
  540.     LD    L,A        ;..TO HL
  541. ;
  542. RDBLP:    LD    A,1AH        ;GET EOF CHAR
  543.     LD    (DE),A        ;SAVE IN CASE EOF
  544.     PUSH    DE        ;SAVE DMA ADDR
  545.     PUSH    HL        ;SAVE FCB ADDR
  546.     PUSH    BC
  547.     PUSH    DE
  548.     PUSH    HL
  549.     LD    C,STDMA
  550.     CALL    BDOS        ;SET DMA ADDR
  551.     POP    HL
  552.     POP    DE
  553.     POP    BC
  554.     POP    DE        ;GET FCB
  555.     PUSH    BC
  556.     PUSH    DE
  557.     PUSH    HL
  558.     LD    C,READ
  559.     CALL    BDOS
  560.     POP    HL
  561.     POP    DE
  562.     POP    BC
  563.     OR    A
  564.     POP    HL        ;HL=DMA, DE=FCB
  565.     JP    NZ,RDBRET    ;GOT EOF
  566.     LD    A,L
  567.     ADD    A,80H        ;TO NEXT BUFF
  568.     LD    L,A
  569.     LD    A,H
  570.     ADC    A,0
  571.     LD    H,A
  572.     EX    DE,HL        ;DMA TO DE, FCB TO HL
  573.     DEC    B        ;MORE SECTORS?
  574.     JP    NZ,RDBLP    ;YES, MORE
  575. ;
  576. RDBRET:    POP    HL        ;GET FCB POINTER
  577.     DEC    HL        ;TO LENGTH
  578.     LD    A,(HL)        ;GET LENGTH
  579.     DEC    HL        ;TO COUNT
  580.     LD    (HL),A        ;SET PAGE COUNT
  581.     DEC    HL        ;TO LO COUNT
  582.     DEC    HL        ;TO HI FCB
  583.     DEC    HL        ;TO EFCB START
  584.     JP    RDBYTE        ;LOOP THRU AGAIN
  585. ;
  586. RDBNORD:INC    HL        ;TO LENGTH
  587.     LD    A,(HL)        ;GET LENGTH (PAGES)
  588.     EX    DE,HL        ;BUFF TO HL
  589.     ADD    A,H
  590.     LD    H,A        ;HL = END OF BUFF
  591.     LD    A,L
  592.     SUB    C
  593.     LD    L,A
  594.     LD    A,H
  595.     SBC    A,B
  596.     LD    H,A        ;HL = DATA POINTER
  597.     LD    A,(HL)        ;GET BYTE
  598.     EX    DE,HL        ;EFCB BACK TO HL
  599.     CP    1AH        ;EOF?
  600.     RET    Z        ;YES, LEAVE POINTERS
  601.     DEC    BC        ;DECR COUNT
  602.     DEC    HL        ;"BYTES LEFT"
  603.     LD    (HL),B
  604.     DEC    HL
  605.     LD    (HL),C        ;STORE BACK COUNT
  606.     RET    
  607. ;
  608. ;SAMPLE EFCB:
  609. ;
  610. ;EFCB    DW    BUFF    ;BUFFER ADDR
  611. ;    DW    0    ;BYTES LEFT (OR TITE)
  612. ;    DB    20    ;BUFFER SIZE (IN PAGES)
  613. ;    DW    FCB    ;FCB ADDRESS
  614. ;
  615. ;
  616. ;WRBYTE, HL POINTS TO EXTENDED FCB:
  617. ;
  618. ;    2 BYTE BUFFER ADDR
  619. ;    2 BYTE "BYTES LEFT" (INIT TO 0)
  620. ;    1 BYTE BUFFER SIZE (IN PAGES)
  621. ;    2 BYTE FCB ADDRESS
  622. ;
  623. WRBYTE:    LD    E,(HL)
  624.     INC    HL
  625.     LD    D,(HL)        ;DE=BUF ADDR
  626.     INC    HL
  627.     LD    C,(HL)
  628.     INC    HL
  629.     LD    B,(HL)        ;BC=BYTES IN BUFF
  630.     PUSH    DE        ;SAVE FCB
  631.     EX    DE,HL
  632.     ADD    HL,BC        ;TO NEXT BYTE
  633.     LD    (HL),A        ;STORE IT
  634.     INC    BC        ;ONE MORE
  635.     EX    DE,HL
  636.     POP    DE
  637. ;
  638. ;SEE IF BUFFER IS FULL
  639. ;
  640.     INC    HL        ;GET
  641.     LD    A,(HL)        ;    SIZE
  642.     CP    B        ;FULL?
  643.     JP    NZ,WRBNOWR    ;NO WRITE
  644. ;
  645.     ADD    A,A        ;MULTIPLY BY 2
  646.     LD    B,A        ;SECTOR COUNT IN B
  647.     INC    HL        ;TO FCB
  648.     PUSH    HL        ;SAVE FCB POINTER
  649.     LD    A,(HL)        ;GET..
  650.     INC    HL        ;..FCB..
  651.     LD    H,(HL)        ;..ADDR..
  652.     LD    L,A        ;..TO HL
  653. ;
  654. WRBLP:    PUSH    DE        ;SAVE DMA ADDR
  655.     PUSH    HL        ;SAVE FCB ADDR
  656.     PUSH    BC
  657.     PUSH    DE
  658.     PUSH    HL
  659.     LD    C,STDMA
  660.     CALL    BDOS        ;SET DMA ADDR
  661.     POP    HL
  662.     POP    DE
  663.     POP    BC
  664.     POP    DE        ;GET FCB
  665.     PUSH    BC
  666.     PUSH    DE
  667.     PUSH    HL
  668.     LD    C,WRITE
  669.     CALL    BDOS
  670.     POP    HL
  671.     POP    DE
  672.     POP    BC
  673.     OR    A
  674.     POP    HL        ;HL=DMA, DE=FCB
  675.     JP    NZ,WRBERR    ;GOT ERR
  676.     LD    A,L
  677.     ADD    A,80H        ;TO NEXT BUFF
  678.     LD    L,A
  679.     LD    A,H
  680.     ADC    A,0
  681.     LD    H,A
  682.     EX    DE,HL        ;DMA TO DE, FCB TO HL
  683.     DEC    B        ;MORE SECTORS?
  684.     JP    NZ,WRBLP    ;YES, MORE
  685. ;
  686. WRBRET:    POP    HL        ;GET FCB POINTER
  687.     DEC    HL        ;TO LENGTH
  688.     DEC    HL        ;TO COUNT
  689.     LD    (HL),0        ;SET 0 TO WRITE
  690.     DEC    HL        ;TO LO COUNT
  691.     LD    (HL),0
  692.     PUSH    BC
  693.     PUSH    DE
  694.     PUSH    HL
  695.     LD    C,STDMA
  696.     LD    DE,80H+BIAS
  697.     CALL    BDOS
  698.     POP    HL
  699.     POP    DE
  700.     POP    BC
  701.     RET    
  702. ;
  703. WRBNOWR:DEC    HL        ;TO LENGTH
  704.     LD    (HL),B        ;SET NEW LENGTH
  705.     DEC    HL
  706.     LD    (HL),C
  707.     RET    
  708. ;
  709. ;FLUSH THE EFCB BUFFERS
  710. ;
  711. FLUSH:    LD    E,(HL)
  712.     INC    HL
  713.     LD    D,(HL)        ;DE=BUF ADDR
  714.     INC    HL
  715.     LD    C,(HL)
  716.     INC    HL
  717.     LD    B,(HL)        ;BC=BYTES IN BUFF
  718.     INC    HL        ;TO COUNT
  719.     LD    A,B
  720.     OR    C
  721.     RET    Z        ;NOTHING TO WRITE
  722.     LD    A,C        ;GET LOW COUNT
  723.     ADD    A,A        ;SHIFT HIGH TO CARRY
  724.     LD    A,B        ;GET LOW COUNTAL
  725.     RLA            ;MULT BY 2, + CARRY
  726.     INC    A        ;FUDGE FOR PARTIAL SECT
  727.     LD    B,A        ;SAVE SECTOR COUNT
  728.     INC    HL        ;TO FCB
  729.     LD    A,(HL)
  730.     INC    HL
  731.     LD    H,(HL)
  732.     LD    L,A        ;HL=FCB
  733. ;
  734. FLUSHL:    PUSH    BC
  735.     PUSH    DE
  736.     PUSH    HL
  737.     LD    C,STDMA
  738.     CALL    BDOS
  739.     POP    HL
  740.     POP    DE
  741.     POP    BC
  742.     EX    DE,HL
  743.     PUSH    BC
  744.     PUSH    DE
  745.     PUSH    HL
  746.     LD    C,WRITE
  747.     CALL    BDOS
  748.     POP    HL
  749.     POP    DE
  750.     POP    BC
  751.     EX    DE,HL
  752.     OR    A
  753.     JP    NZ,WRBERR
  754.     PUSH    HL
  755.     LD    HL,80H
  756.     ADD    HL,DE
  757.     EX    DE,HL
  758.     POP    HL
  759.     DEC    B
  760.     JP    NZ,FLUSHL
  761.     EX    DE,HL
  762.     PUSH    BC
  763.     PUSH    DE
  764.     PUSH    HL
  765.     LD    C,CLOSE
  766.     CALL    BDOS
  767.     POP    HL
  768.     POP    DE
  769.     POP    BC
  770.     INC    A
  771.     RET    NZ
  772.     CALL    ERXIT
  773.     DEFB    '++OUTPUT FILE CLOSE ERROR ++$'
  774. ;
  775. WRBERR:    CALL    ERXIT
  776.     DEFB    '++OUTPUT FILE WRITE ERROR++$'
  777. ;
  778. ;EXIT WITH ERROR MESSAGE
  779. ;
  780. MSGEXIT EQU    $        ;EXIT W/"INFORMATIONAL" MSG
  781. ;
  782. ERXIT:    POP    DE        ;GET MSG
  783.     LD    C,PRINT
  784.     CALL    BDOS
  785. ;
  786. ;EXIT, RESTORING STACK AND RETURN
  787. ;
  788. EXIT:    JP    0+BIAS
  789. ;
  790. ;====>    START OF WORK AREA
  791. ;
  792. EXTFCB:    DEFW    DKBUF
  793.     DEFW    0
  794.     DEFB    4
  795.     DEFW    FCB
  796. PREV:    DEFW    PTR        ;POINTER TO PREV POINTER
  797. SKIPC:    DEFB    0        ;SKIP CHARS END
  798.     DEFS    100        ;VARIABLE SKIP CHARS
  799. ;
  800.     DEFS    100        ;STACK AREA
  801. STACK    EQU    $
  802. ;
  803. OUTNAME:DEFS    12        ;OUTPUT FILENAME
  804. SWAPS:    DEFS    1
  805. CURR:    DEFS    2
  806. PTR:    DEFS    2        ;POINTER TO FIRST NAME
  807. ;
  808.     ORG    ($+255) AND 0FF00H;TO PAGE
  809. ;
  810. DKBUF:    DEFS    256*4        ;4 PAGES OF BUFFER
  811. SBUFF:    DEFS    0        ;NAMES READ IN HERE
  812. ;
  813.     END    
  814. WRITE
  815.     CALL    BDOS
  816.     POP    HL
  817.     POP    DE
  818.     POP    BC
  819.     EX    DE,HL
  820.     OR    A
  821.     JP    NZ,WRBERR
  822.