home *** CD-ROM | disk | FTP | other *** search
/ CP/M / CPM_CDROM.iso / cpm / submit / subgen12.lbr / SUBGEN12.AQM / SUBGEN12.ASM
Assembly Source File  |  1985-12-03  |  19KB  |  898 lines

  1. ;=================================================================
  2. ;
  3. ;           SUBGEN.ASM Version 1.2
  4. ;               (Original - Feb/82)
  5. ;
  6. ;          Submit File Generator Program
  7. ;
  8. ;           By Steve Pritchard
  9. ;
  10. ;        of Solutions Canada Inc.
  11. ;           83 Cummer Ave,
  12. ;           Willowdale, Ontario
  13. ;           M2M 2E6   (416)-223-7549
  14. ;
  15. ;
  16. ;         Copyrighted(1982) by Steve Pritchard
  17. ;
  18. ; PERMISSION IS GIVEN FOR USE AND FOR DISTRIBUTION OF THESE ROUTINES
  19. ;
  20. ;       BUT THEY ARE NOT TO BE SOLD FOR PROFIT.
  21. ;
  22. ;
  23. ;=================================================================
  24. ;
  25. ; Fixes/Updates in reverse order.
  26. ;
  27. ; Feb/26/82 - Fix telephone number.  Fix a couple of comments.
  28. ;          Suggest 'M' option. (Steve Pritchard)
  29. ;          Added msg on how to get help.    
  30. ;
  31. ; Feb/24/82 - Remove attribute flags from match testing, remove
  32. ;          limit on file capacity (W. Earnest)
  33. ;
  34. ; Feb/12/82 - Original. Lifted mostly from FMAP by WARD CHRISTENSEN
  35. ;
  36. ;-----------------------------------------------------------------
  37. ;
  38. ;Possible Extensions
  39. ;
  40. ;(1) -     Multiple disk drives. Would need expanded sort capability and
  41. ;    probably drive substitute character.
  42. ;
  43. ;(2) -    Since the file match logic is in SUBGEN in can be expanded
  44. ;    beyond CP/Ms wildcard approach.
  45. ;
  46. ;(3) -  Multiple file search capability by 'M' option to cause prompt
  47. ;    for more than one search argument.  Thus could do *.ASM and 
  48. ;    *.PLI in one pass.
  49. ;
  50. ;=================================================================
  51. ;
  52. ;
  53. ;        ---  PGM Generation Options ---
  54. ;
  55. FALSE    EQU    0
  56. TRUE    EQU    NOT FALSE
  57. ;
  58. RMAC    EQU    FALSE
  59. FNFTMRK    EQU    '@'        ;char used to signal fn.ft substitute point
  60. ;
  61. DEFP    EQU    FALSE        ;default Prompt option
  62. DEFH    EQU    FALSE        ;     header option
  63. DEFT    EQU    FALSE        ;     trailer option
  64. DEFNOT    EQU    FALSE        ;     not (invert) option
  65. DEFLOG    EQU    TRUE        ;     log option
  66. ;
  67. ;=================================================================
  68. ;
  69. ;         LET WORK BEGIN ........
  70. ;
  71.     IF    RMAC
  72.     ASEG            ; FOR RMAC
  73.     ENDIF
  74. ;
  75. ;        -----     EQUATES   -------
  76. ;
  77. ;
  78. FCB    EQU    5CH        ;SYSTEM FCB
  79. CR    EQU    13
  80. LF    EQU    10
  81. ELEN    EQU    8+3        ;length of entry
  82. ;
  83. ; BDOS EQUATES
  84. ;
  85. RDCHR    EQU    1        ;READ CHAR FROM CONSOLE
  86. WRCHR    EQU    2        ;WRITE CHR TO CONSOLE
  87. PRINT    EQU    9        ;PRINT CONSOLE BUFF
  88. RCBUF    EQU    10        ;READ CONSOLE BUFFER
  89. CONST    EQU    11        ;CHECK CONS STAT
  90. FOPEN    EQU    15        ;0FFH=NOT FOUND
  91. FCLOSE    EQU    16        ;   "    "
  92. FSRCHF    EQU    17        ;   "    "
  93. FSRCHN    EQU    18        ;   "    "
  94. ERASE    EQU    19        ;NO RET CODE
  95. FREAD    EQU    20        ;0=OK, 1=EOF
  96. FWRTE    EQU    21        ;0=OK, 1=ERR, 2=?, 255=NO DIR SPC
  97. FMAKE    EQU    22        ;255=BAD
  98. FREN    EQU    23        ;255=BAD
  99. FDMA    EQU    26
  100. BDOS    EQU    5
  101. REBOOT    EQU    0
  102. ;
  103. ;
  104. ;
  105. ;        ------  MAINLINE  --------
  106. ;
  107. ;
  108. ;        PROGRAM INITIATION
  109. ;
  110.  
  111.     ORG    100H
  112.     JMP    START
  113. VERSION    DB          'SUBGEN - February 26/82 Ver 1.2' 
  114.     DB    CR,LF,'Copyright(1982) Steve Pritchard'
  115.     DB    CR,LF
  116.     DB    CR,LF,'use    SUBGEN ?   for help info'
  117.     DB    CR,LF
  118.     DB    '$'    
  119. HELP    DB    CR,LF,'Command format:SUBGEN [d:afn.ft] [options]'
  120.     DB    CR,LF
  121.     DB    CR,LF,'It will generate SUBGEN.SUB from d:afn.ft file match'
  122.     DB    CR,LF,'under control of skeleton obtained from prompt'
  123.     DB    CR,LF,'and will substitute fn.ft where ever it finds the'
  124.     DB    CR,LF,'character '
  125.     DB    FNFTMRK,' (Try a . suffix and prefix too)'
  126.     DB    CR,LF
  127.     DB    CR,LF,'Options are:-'
  128.     DB    CR,LF,'P = prompt on each file for n, y or CR'
  129.     DB    CR,LF,'H = generate header(s) before body'
  130.     DB    CR,LF,'T = generate trailer(s) after body'
  131.     DB    CR,LF,'- = invert select logic'
  132.     DB    CR,LF,'L = invert default logging option'
  133.     DB    CR,LF,'$'
  134. START    LXI    H,0
  135.     DAD    SP
  136.     SHLD    STACK
  137.     LXI    SP,STACK
  138. ;
  139. ;        MAIN PROGRAM FLOW
  140. ;
  141.     CALL    INIT        ;initialize
  142.     CALL    DIRLOAD        ;load directory into memory
  143.     CALL    OPENFILE    ;open output file
  144.     CALL    TYPEHIT        ;type number of hits
  145.     LHLD    COUNT        ;check number found
  146.     MOV    A,H
  147.     ORA    L
  148.     JZ    EXIT        ;return no work
  149.     CALL    SORTDIR        ;sort dir entries
  150.     CALL    FORMBUF        ;form pretty buffer
  151.     CALL    WHEADER        ;write file header(s) if reqd
  152.     CALL    SKELIN        ;read standard format line(s)
  153.     CALL    WFILE        ;write body of file
  154.     CALL    WTRAIL        ;write file trailer(s) if reqd
  155. EXIT    CALL    CLSEFILE    ;close output file
  156.     NOP    ! NOP ! NOP    ;JMP 0 FOR DDT
  157.     LHLD    STACK
  158.     SPHL
  159.     RET
  160. ;============================================================
  161. ;               1ST LEVEL ROUTINES
  162. ;============================================================
  163. ;
  164. ;        INITIALIZE
  165. ;
  166. INIT    LXI    D,VERSION    ;T/ON help if ? in FCB1 pos 1
  167.     LDA    FCB+1
  168.     CPI    '?'
  169.     JNZ    INIT03
  170.     LDA    FCB+2        ;check if just ?
  171.     CPI    ' '
  172.     JNZ    INIT03        ;must be CP/M *.*
  173.     LXI    D,HELP        ;yes - so print and quit
  174.     CALL    WRCON
  175.     JMP    EXIT        ;out in a hurry
  176. INIT03    CALL    WRCON
  177.     CALL    SAVEOPT        ;save options
  178.     LXI    H,FCB+1        ;format FCB to ????????.???
  179.     MVI    B,ELEN        ;FN+FT count
  180. QLOOP    MVI    M,'?'        ;store '?' in FCB
  181.     INX    H
  182.     DCR    B
  183.     JNZ    QLOOP
  184.     RET
  185. ;
  186. ;        LOAD THE DIRECTORY (SELECTED) INTO MEMORY
  187. ;
  188. DIRLOAD    MVI    C,FSRCHF     ;search first
  189. DIRL10    LXI    D,FCB
  190.     CALL    BDOS        ;read first
  191.     INR    A        ;some?
  192.     RZ            ;jmp no to done
  193.     CALL    SELENT        ;select entry
  194.     MVI    C,FSRCHN    ;search next
  195.     JMP    DIRL10        ;repeat
  196. ;
  197. ;        OPEN OUTPUT FILE
  198. ;
  199. OPENFILE
  200.     LXI    D,MYFCB        ;open file
  201.     MVI    C,ERASE
  202.     CALL    BDOS
  203.     LXI    D,MYFCB
  204.     MVI    C,FMAKE
  205.     CALL    BDOS
  206.     INR    A
  207.     RNZ
  208.     CALL    ERXIT        ;abort type error
  209.     DB    '>> File MAKE error'
  210.     DB    CR,LF,'$'
  211.  
  212. ;
  213. ;        SORT THE SAVED ENTRIES
  214. ;
  215. SORTDIR    LHLD    COUNT        ;init the order table
  216.     PUSH    H        ;file count on stack
  217.     XCHG
  218.     LHLD    NEXTT
  219.     SHLD    AORDER        ;pointer table start
  220.     PUSH    H
  221.     DAD    D        ;2 bytes per file
  222.     DAD    D
  223.     SHLD    NEXTT        ;new table limit
  224.     POP    H
  225.     LXI    D,TABLE
  226.     LXI    B,ELEN        ;entry length
  227. ;
  228. BLDORD    MOV    M,E        ;save lo ord addr
  229.     INX    H
  230.     MOV    M,D        ;save hi ord addr
  231.     INX    H
  232.     XCHG            ;table addr in HL
  233.     DAD    B        ;point to next entry
  234.     XCHG
  235.     XTHL            ;count from stack
  236.     DCX    H
  237.     MOV    A,H
  238.     ORA    L        ;test cpunt
  239.     XTHL            ;back to stack
  240.     JNZ    BLDORD        ;..yes
  241.     POP    H        ;clean up stack of count
  242.     LHLD    COUNT        ;get count
  243.     SHLD    SCOUNT        ;save as # to sort
  244.     DCX    H        ;only 1 entry?
  245.     MOV    A,H
  246.     ORA    L
  247.     JZ    SORTDONE    ;..yes, so skip sort
  248. ;
  249. SORT    XRA    A        ;get a zero
  250.     STA    SWITCH        ;show none switched
  251.     LHLD    SCOUNT        ;get count
  252.     DCX    H        ;use 1 less
  253.     SHLD    TEMP        ;save # to compare
  254.     SHLD    SCOUNT        ;save highest entry
  255.     MOV    A,H
  256.     ORA    L
  257.     JZ    SORTDONE    ;exit if no more
  258.     LHLD    AORDER     ;point to order table
  259. ;
  260. SORTLP    MVI    A,ELEN        ;length of compare
  261.     CALL    COMPR        ;compare 2 entries
  262.     CM    SWAP        ;swap if not in order
  263.     INX    H        ;bump order
  264.     INX    H        ;..table pointer
  265.     PUSH    H
  266.     LHLD    TEMP        ;get count
  267.     DCX    H
  268.     SHLD    TEMP
  269.     MOV    A,H
  270.     ORA    L
  271.     POP    H    
  272.     JNZ    SORTLP        ;continue
  273. ;
  274. ;ONE PASS OF SORT DONE
  275.     LDA    SWITCH        ;any swaps done?
  276.     ORA    A
  277.     JNZ    SORT        ;jmp yes to repeat another pass
  278. ;
  279. SORTDONE
  280.     RET
  281. ;
  282. ;        TYPE NUMBER OF HITS
  283. ;
  284. TYPEHIT    LHLD    COUNT
  285.     MOV    A,H
  286.     ORA    A
  287.     JNZ    THIT02
  288.     MOV    A,L
  289.     CPI    1
  290.     JZ    THIT10
  291. THIT02    LXI    D,HITM1
  292.     CALL    WRCON
  293.     LHLD    COUNT
  294.     CALL    DECPRT
  295.     LXI    D,HITM3
  296. THIT05    CALL    WRCON
  297.     RET
  298. THIT10    LXI    D,HITM2
  299.     LXI    H,HITM4-1
  300.     MVI    M,' '
  301.     JMP    THIT05
  302. HITM1    DB    'There are $'
  303. HITM2    DB    'There is 1'
  304. HITM3    DB    ' selected files'
  305. HITM4    DB    CR,LF,'$'
  306. ;
  307. ;        WRITE HEADER RECORDS IF REQD
  308. ;
  309. WHEADER    LDA    OPTH        ;see if requested
  310.     ORA    A
  311.     RZ            ;return not
  312.     LXI    H,PRHDR        ;Header prompt
  313.     CALL    CONCOPY        ;copy console input to file
  314.     RET
  315. ;
  316. ;        INPUT SKELETON LINES
  317. ;
  318. SKELIN    LHLD    NEXTT        ;skel lines start where
  319.     SHLD    FSKEL        ;dir entries stop
  320.     SHLD    LSKEL
  321. SKEL10    LXI    D,PRSKEL    ;skeleton prompt
  322.     CALL    WRCON
  323.     LXI    D,TBUF        ;input a line from console
  324.     MVI    C,RCBUF    
  325.     CALL    BDOS
  326.     CALL    TYPECR
  327.     LDA    TBUF+1        ;check for data
  328.     ORA    A
  329.     JZ    SKEL50        ;jmp no    
  330. ;
  331.     MOV    B,A        ;move entry to save area
  332.     LXI    D,TBUF+2    ;input data
  333.     LHLD    LSKEL        ;output location
  334. SKEL30    LDAX    D        ;pick up byte
  335.     MOV    M,A        ;move it
  336.     INX    D
  337.     INX    H
  338.     DCR    B
  339.     JNZ    SKEL30        ;until done
  340.     MVI    M,CR        ;add crlf
  341.     INX    H
  342.     MVI    M,LF
  343.     INX    H
  344.     SHLD    LSKEL        ;remember where we are
  345.     JMP    SKEL10        ;try again
  346. ;
  347. SKEL50    LHLD    FSKEL        ;see if any entries
  348.     CALL    FLEND        ; .by doing a compare
  349.     JNZ    SKEL60        ;jmp there are some
  350.     LHLD    LSKEL        ;else default to FMAP output
  351.     MVI    M,FNFTMRK
  352.     INX    H
  353.     MVI    M,CR        ;and trailer
  354.     INX    H
  355.     MVI    M,LF
  356.     INX    H
  357.     SHLD    LSKEL        ;and save
  358. SKEL60    RET            ;return    
  359. ;
  360. ;        WRITE OUTPUT FILE
  361. ;
  362. WFILE    LHLD    COUNT        ;number of entries to write
  363.     MOV    C,L
  364.     MOV    B,H
  365.     LHLD    AORDER        ;first entry
  366. WFILE10    MOV    E,M        ;indirect adr
  367.     INX    H
  368.     MOV    D,M
  369.     INX    H
  370.     PUSH    H        ;save where we are
  371.     XCHG            ;now HL has entry adr
  372.     CALL    WENTRY        ;write entry
  373.     POP    H        ;ready for next
  374.     DCX    B
  375.     MOV    A,B
  376.     ORA    C
  377.     JNZ    WFILE10        ;until done
  378.     RET
  379. ;
  380. ;        WRITE TRAILERS IF REQD
  381. ;
  382. WTRAIL    LDA    OPTT        ;see if requested
  383.     ORA    A
  384.     RZ            ;return not
  385.     LXI    H,PRTRLR    ;trailr prompt
  386.     CALL    CONCOPY        ;copy console input to file
  387.     RET
  388. ;
  389. ;        CLOSE OUTPUT FILE
  390. ;
  391. CLSEFILE
  392.     MVI    A,'Z'-40H    ;write eof mark
  393.     CALL    FILCHR
  394.     CALL    WRSEC        ;and then the sector
  395.     LXI    D,MYFCB        ;close file
  396.     MVI    C,FCLOSE    ;function
  397.     CALL    BDOS
  398.     RET
  399. ;
  400. ;==========================================================
  401. ;        LEVEL 2 OR MORE ROUTINES
  402. ;==========================================================
  403. ;
  404. ;        SAVE OPTIONS AND INPUT FILE NAME
  405. ;
  406. SAVEOPT    LXI    D,FCB+1        ;move file name to FNFTMAT
  407.     LXI    H,FNFTMAT
  408.     MVI    B,8        ;FN portion
  409.     MVI    C,0        ;first loop sw
  410.     LDA    FCB+1        ;format to *.* if reqd
  411.     CPI    ' '
  412.     JNZ    SOPT20
  413.     MVI    A,'*'        ;yes - do it
  414.     STA    FCB+1
  415.     STA    FCB+1+8
  416. SOPT20    LDAX    D        ;pick up next byte
  417.     CPI    '*'        ;need expanding?
  418.     JNZ    SOPT30        ;no
  419. SOPT25    MVI    M,'?'        ;so do it
  420.     INX    H
  421.     INX    D
  422.     DCR    B
  423.     JNZ    SOPT25        ;until
  424.     JMP    SOPT40
  425. SOPT30    MOV    M,A        ;copy byte across
  426.     INX    H
  427.     INX    D
  428.     DCR    B
  429.     JNZ    SOPT20        ;until
  430. SOPT40    MOV    A,C        ;FT portion
  431.     ORA    A
  432.     MVI    B,3
  433.     MVI    C,1        ;2nd time sw
  434.     JZ    SOPT20        ;jmp only once so far
  435. ;
  436.     LXI    D,FCB+17-1    ;Pick up options section
  437. SOPT50    INX    D        ;next byte
  438.     LDAX    D        ;next option byte
  439.     CPI    ' '        ;test for end
  440.     JZ    SOPT60        ; .yes    
  441.     CPI    00H        ;DDT support
  442.     JZ    SOPT60
  443.     MVI    B,(OPTTABE-OPTTAB)/2
  444.     LXI    H,OPTTAB+1
  445. SOPT53    CMP    M        ;hit
  446.     JZ    SOPT55        ;jmp yes
  447.     INX    H        ;no - try next
  448.     INX    H
  449.     DCR    B
  450.     JNZ    SOPT53
  451.     STA    SOPTMSG-1
  452.     CALL    ERXIT        ;quit
  453.     DB    CR,LF
  454.     DB    '>> Invalid option=x'
  455. SOPTMSG    DB    '$'
  456. SOPT55    DCX    H        ;have a hit
  457.     MOV    A,M        ;invert hit flag
  458.     XRI    TRUE        ;from default selected at sysgen
  459.     MOV    M,A        ;and store back
  460.     JMP    SOPT50
  461. SOPT60    RET            ;return all options set
  462. ;
  463. ;        COMPARE HL TO LSKEL. NZ=NOT EQUAL
  464. ;
  465. FLEND    XCHG            ;do a subtract
  466.     LHLD    LSKEL
  467.     MOV    A,E
  468.     SUB    L
  469.     MOV    A,D
  470.     SBB    H
  471.     RET            ;return with carry set
  472. ;
  473. ;        SELECT ENTRY IF REQUIRED
  474. ;
  475. ;point to dir entry 
  476. SELENT    DCR    A        ;undo prev 'INR A'
  477.     ANI    3        ;make mod4
  478.     ADD    A        ;multiply...
  479.     ADD    A        ;..by 32 because
  480.     ADD    A        ;..each dir
  481.     ADD    A        ;..entry is 32
  482.     ADD    A        ;..bytes long
  483.     LXI    H,81H        ;point to buffer (first FN.FT entry)
  484.     ADD    L        ;point to entry
  485.     MOV    L,A        ;save (CAN'T CARRY TO H)
  486.     SHLD    SVEPOS        ;save position
  487.     CALL    FNFTMTC        ;match to FNFT wanted and NOT sw invert
  488.     RNZ            ;return unwanted
  489.     LDA    OPTP        ;user want ultimate overide
  490.     CPI    TRUE
  491.     JNZ    SELE30        ;no - so accept into table
  492.     CALL    CONFIRM
  493.     RNZ            ;user does not want it
  494. SELE30
  495. ;move entry to table
  496.     LHLD    SVEPOS        ;entry to save
  497.     XCHG            ;entry to DE
  498.     LHLD    NEXTT        ;next table entry to HL
  499.     MVI    B,ELEN        ;name entry length
  500. TMOVE    LDAX    D        ;get entry char
  501.     ANI    7FH        ;less attributes
  502.     MOV    M,A        ;store in table
  503.     INX    D
  504.     INX    H
  505.     DCR    B        ;more?
  506.     JNZ    TMOVE
  507.     SHLD    NEXTT        ;save updated table addr
  508.     LHLD    COUNT        ;get prev count
  509.     INX    H
  510.     SHLD    COUNT
  511.     RET
  512. ;
  513. ;        COPY CONSOLE TO DISK FILE FOR HEADER/TRAILER
  514. ;
  515. CONCOPY    PUSH    H        ;save prompt location
  516. COPC10    POP    D        ;write prompt
  517.     PUSH    D
  518.     CALL    WRCON
  519.     LXI    D,TBUF        ;read reply
  520.     MVI    C,RCBUF
  521.     CALL    BDOS
  522.     CALL    TYPECR
  523.     LDA    TBUF+1        ;length of reply
  524.     ORA    A        ;test length
  525.     JZ    COPC99        ;return null line
  526.     LXI    H,TBUF+2    ;not so write entry to file
  527.     MOV    B,A
  528. COPC20    MOV    A,M        ;this one
  529.     CALL    FILCHR        ;write it
  530.     INX    H        ;next
  531.     DCR    B        ;until
  532.     JNZ    COPC20
  533.     MVI    A,CR        ;write CRLF to file
  534.     CALL    FILCHR
  535.     MVI    A,LF
  536.     CALL    FILCHR
  537.     JMP    COPC10        ;repeat
  538. COPC99    POP    H        ;clean up stack
  539.     RET
  540. ;
  541. ;        MATCH DIR ENTRY TO FN.FT SPECIFIED 
  542. ;
  543. ;            AND POSSIBLY INVERT MATCH
  544. FNFTMTC    LHLD    SVEPOS        ;entry to check
  545.     LXI    D,FNFTMAT    ;master entry
  546.     MVI    B,ELEN        ;number bytes to compare
  547. FNFT10    MOV    A,M
  548.     ANI    7FH        ;remove flag bit
  549.     MOV    C,A        ;for compare
  550.     LDAX    D        ;next byte from master
  551.     CMP    C        ;to dir entry
  552.     JZ    FNFT30        ;jmp ok
  553.     CPI    '?'        ;master = ?
  554.     JNZ    FNFT40        ;no - match not equal
  555. FNFT30    INX    H        ;repeat for next byte
  556.     INX    D
  557.     DCR    B        ;until
  558.     JNZ    FNFT10
  559. ;                ;nz=no match, z=match
  560. FNFT40    LDA    OPTNOT        ;invert option flag
  561.     PUSH    PSW        ;save compare results
  562.     ORA    A        ;nz = invert
  563.     JZ    FNFT50        ;not so leave intact
  564.     POP    PSW        ;get back result
  565.     JNZ    FNFT45        ;was zero so make it NZ
  566.     ORI    1        ;by ORI
  567.     RET            ;and leave
  568. FNFT45    XRA    A        ;was NZ so make it Z
  569.     RET            ;and leave
  570. FNFT50    POP    PSW        ;no invert so restore
  571.     RET            ;return nz=no, z = yes
  572. ;
  573. ;        CONFIRM ENTRY REQUIRED OR NOT
  574. CONFIRM    LHLD    SVEPOS
  575.     MVI    B,8    
  576.     CALL    TYPENB
  577.     MVI    A,'.'
  578.     CALL    TYPE
  579.     MVI    B,3
  580.     CALL    TYPENB
  581.     MVI    A,'?'
  582.     CALL    TYPE
  583.     MVI    C,RDCHR        ;read reply
  584.     CALL    BDOS
  585.     PUSH    A
  586.     CALL    TYPECR        ;get to newline
  587.     POP    A
  588.     CPI    CR        ;look for ans
  589.     JNZ    CONF10
  590.     MVI    A,'Y'        ;CR=YES
  591. CONF10    ORI    020H        ;make lower case
  592.     CPI    'y'        ;affirmative
  593.     RZ            ;return yes=z
  594.     CPI    'n'        ;must be n
  595.     JNZ    CONFIRM        ;not so try again
  596.     ORI    1        ;set nz = no
  597.     RET
  598. ;
  599. ;        WRITES ENTRY MAKING FN.FT SUBSTITUTION
  600. ;    
  601. WENTRY    SHLD    SVEPOS        ;save position
  602.     PUSH    B
  603.     PUSH    D
  604.     PUSH    H        ;and caller regs
  605.     LHLD    FSKEL        ;first pos of skeleton
  606. WENT10    MOV    A,M        ;process next char
  607.     CPI    FNFTMRK        ;special marker for FN.FT substitute
  608.     JZ    WENT20        ;yes - do that
  609.     CALL    FILCHR        ;no -write character to file
  610. WENT15    INX    H        ;next byte
  611.     PUSH    H        ;save status
  612.     CALL    FLEND        ;test end of skeleton
  613.     POP    H        ;and back again
  614.     JNZ    WENT10        ;there is more
  615.     JMP    WENT99        ;done
  616. WENT20    PUSH    H        ;save where we are
  617.     MVI    C,0        ;type of subst sw. 0=FN.FT, 1=FN, 2=FT
  618.     INX    H        ;see if nxt byte is .
  619.     MVI    A,'.'
  620.     CMP    M
  621.     JNZ    WENT22
  622.     MVI    C,1        ;it is so only do FN substitute
  623.     JMP    WENT25
  624. WENT22    DCX    H
  625.     DCX    H        ;try previous
  626.     CMP    M
  627.     JNZ    WENT25
  628.     MVI    C,2        ;FT only
  629. WENT25    POP    H        ;reload ptr to skeleton
  630.     PUSH    H
  631.     MOV    A,C        ;sw
  632.     CPI    2
  633.     JZ    WENT30        ;do FN
  634.     LHLD    SVEPOS
  635.     MVI    B,8
  636.     CALL    FILCHRNB    ;write FN but no blanks
  637. WENT30    MOV    A,C        ;sw again
  638.     ORA    A        ;see if need period
  639.     JNZ    WENT35        ;jmp no
  640.     MVI    A,'.'
  641.     CALL    FILCHR        ;write period
  642. WENT35    MOV    A,C        ;see if need FN.FT
  643.     CPI    1
  644.     JZ    WENT40        ;no
  645.     MVI    B,3
  646.     LHLD    SVEPOS
  647.     LXI    D,8
  648.     DAD    D
  649.     CALL    FILCHRNB    ;write filetype
  650. WENT40    POP    H        ;reload current ptr &
  651.     JMP    WENT15        ;return to mainline
  652. WENT99    POP    H        ;exit
  653.     POP    D
  654.     POP    B
  655.     RET    
  656. ;
  657. ;        TYPE CHAR IN A
  658. ;
  659. TYPE    PUSH    B
  660.     PUSH    D
  661.     PUSH    H
  662.     MOV    E,A
  663.     MVI    C,WRCHR
  664.     CALL    BDOS
  665.     POP    H
  666.     POP     D
  667.     POP    B
  668.     RET
  669. ;
  670. ;        WRITE MESSAGE ON CONSOLE
  671. ;          (D->msg $)
  672. ;
  673. WRCON    MVI    C,PRINT
  674.     JMP    BDOS
  675. ;
  676. ;        TYPE MSG HL POINTS TO, B HAS LENGTH
  677. ;
  678.  
  679. TYPEIT    MOV    A,M
  680.     CALL    TYPE
  681.     INX    H
  682.     DCR    B
  683.     JNZ    TYPEIT
  684.     RET
  685. ;
  686. ;        ERROR EXIT
  687. ;
  688. ERXIT    POP    D    ;GET MSG
  689.     MVI    C,PRINT
  690.     CALL    BDOS
  691.     JMP    EXIT
  692. ;
  693. ;        WRITE CHAR IN A TO FILE
  694. ;        (SAVES ALL REGS INCLUDING A)
  695. FILCHR    PUSH    PSW
  696.     PUSH    H
  697.     LHLD    BUFAD        ;current buffer adr
  698.     MOV    M,A
  699.     INX    H
  700.     SHLD    BUFAD
  701.     MOV    A,H        ;see if full buffer
  702.     DCR    A
  703.     CZ    WRSEC        ;yes so write sector
  704.     POP    H
  705.     LDA    OPTLOG        ;test if log chosen
  706.     ORA    A
  707.     JZ    FILC80        ;not so do not type
  708.     POP    PSW
  709.     PUSH    PSW        ;get char and type
  710.     CALL    TYPE
  711. FILC80    POP    PSW        ;restore char
  712.     RET
  713. ;
  714. ;        WRITE A SECTOR
  715. ;
  716. WRSEC    PUSH    B
  717.     PUSH    D
  718.     LXI    D,MYFCB
  719.     MVI    C,FWRTE
  720.     CALL    BDOS
  721.     ORA    A
  722.     JZ    WROK
  723.     CALL    ERXIT
  724.     DB    CR,LF
  725.     DB    '>> WRITE ERROR$'
  726. WROK    CALL    FORMBUF        ;clean up buffer
  727.     POP    D
  728.     POP    B
  729.     RET
  730. ;
  731. ;        TYPE ALL BUT SPACES
  732. ;        (HL -> msg, B has length)
  733. ;
  734. TYPENB    MOV    A,M        ;ignore spaces
  735.     CPI    ' '
  736.     JZ    TPNB10
  737.     CALL    TYPE
  738. TPNB10    INX    H
  739.     DCR    B
  740.     JNZ    TYPENB
  741.     RET
  742. ;
  743. ;        TYPE CRLF
  744. ;
  745. TYPECR    PUSH    A
  746.     MVI    A,CR
  747.     CALL     TYPE
  748.     MVI    A,LF
  749.     CALL    TYPE
  750.     POP    A
  751.     RET
  752. ;
  753. ;        WRITE ALL BUT SPACES TO FILE
  754. ;        (HL -> msg, B has length)
  755. ;
  756. FILCHRNB
  757.     MOV    A,M        ;ignore spaces
  758.     CPI    ' '
  759.     JZ    FILB10
  760.     CALL    FILCHR
  761. FILB10    INX    H
  762.      DCR    B
  763.     JNZ    FILCHRNB
  764.     RET
  765. ;
  766. ;        FORMAT A BUFFER AND SET UP CONTROL WORDS
  767. ;
  768. FORMBUF    PUSH    H
  769.     PUSH    A
  770.     LXI    H,080H        ;address of buffer
  771.     SHLD    BUFAD        ;save it
  772.     MVI    A,128
  773. FBUF10    MVI    M,'Z'-040H    ;set to EOF
  774.     INX    H
  775.     DCR    A
  776.     JNZ    FBUF10
  777.     POP    A
  778.     POP    H
  779.     RET
  780. ;
  781. ;        COMPARE ROUTINE FOR SORT
  782. ;        (A has number bytes to compare)
  783. ;
  784. COMPR    PUSH    H        ;save table addr
  785.     MOV    E,M        ;load lo
  786.     INX    H
  787.     MOV    D,M        ;load hi
  788.     INX    H
  789.     MOV    C,M
  790.     INX    H
  791.     MOV    B,M
  792. ;BC, DE now point to entries to be compared
  793.     XCHG
  794.     MOV    E,A        ;better reg
  795. CMPLP    LDAX    B
  796.     CMP    M
  797.     INX    H
  798.     INX    B
  799.     JNZ    CMPL80        ;out with not equal status
  800.     DCR    E
  801.     JNZ    CMPLP
  802.     XRA    A        ;ensure zero cc
  803. CMPL80    POP    H
  804.     RET            ;cond code tells all
  805. ;
  806. ;        SWAP ENTRIES IN THE ORDER TABLE
  807. SWAP    MVI    A,1
  808.     STA    SWITCH        ;show a swap was made
  809.     MOV    C,M
  810.     INX    H
  811.     PUSH    H        ;save table addr+1
  812.     MOV    B,M
  813.     INX    H
  814.     MOV    E,M
  815.     MOV    M,C
  816.     INX    H
  817.     MOV    D,M
  818.     MOV    M,B
  819.     POP    H
  820.     MOV    M,D
  821.     DCX    H        ;back pointer to correct position
  822.     MOV    M,E
  823.     RET
  824. ;
  825. ;         Print    HL in decimal with leading zero    suppression
  826. ;
  827. ;                 (Found in SD-41, Author unknown)
  828. ;
  829. DECPRT:    SUB    A        ;Clear leading zero flag
  830.     STA    LZFLG
  831.     LXI    D,-1000        ;Print 1000's digit
  832.     CALL    DIGIT
  833.     LXI    D,-100        ;Etc.
  834.     CALL    DIGIT
  835.     LXI    D,-10
  836.     CALL    DIGIT
  837.     MVI    A,'0'        ;Get 1's digit
  838.     ADD    L
  839.     JMP    TYPE
  840. DIGIT:    MVI    B,'0'        ;Start off with    ASCII 0
  841. DIGLP:    PUSH    H        ;Save current remainder
  842.     DAD    D        ;Subtract
  843.     JNC    DIGEX        ;Quit on overflow
  844.     POP    PSW        ;Throw away remainder
  845.     INR    B        ;Bump digit
  846.     JMP    DIGLP        ;Loop back
  847. DIGEX:    POP    H        ;Restore pointer
  848.     MOV    A,B
  849.     CPI    '0'        ;Zero digit?
  850.     JNZ    DIGNZ        ;No, type it
  851.     LDA    LZFLG        ;Leading zero?
  852.     ORA    A
  853.     MVI    A,'0'
  854.     JNZ    TYPE        ;Print digit
  855.     RET            ;no leading spaces for 0s
  856. DIGNZ:    STA    LZFLG        ;Set leading zero flag so next zero prints
  857.     JMP    TYPE        ;And print digit
  858. LZFLG    DB    0
  859. ;===================================================================
  860. ;        VARIABLES  AND   CONSTANTS
  861. ;===================================================================
  862. ;
  863. NEXTT    DW    TABLE        ;NEXT TABLE ENTRY
  864. COUNT    DW    0        ;ENTRY COUNT
  865. BUFAD    DW    80H        ;OUTPUT ADDR
  866. OPTTAB    EQU    $        ;OPTIONS-nonzero mean selected
  867. OPTP    DB    DEFP,'P'    ;prompt for selection yae/nae
  868. OPTH    DB    DEFH,'H'    ;ask for header
  869. OPTT    DB    DEFT,'T'    ;ask for trailer
  870. OPTNOT    DB    DEFNOT,'-'    ;invert selection criteria
  871. OPTLOG    DB    DEFLOG,'L'    ;log results to console
  872. OPTTABE    EQU    $
  873. ;
  874. PRSKEL    DB    'Skeleton? $'
  875. PRHDR    DB    'Header? $'
  876. PRTRLR    DB    'Trailer? $'
  877. ;
  878. FSKEL    DW    0        ;Position of first skel rec byte
  879. LSKEL    DW    0        ; last byte+1
  880. MYFCB    DB    0,'SUBGEN  SUB',0
  881.     DS    19
  882.     DB    0
  883. TBUF    DB    127    ;CONSOLE INPUT BUFFER
  884.     DS    127
  885. FNFTMAT    DS    11        ;match mask
  886. SCOUNT    DS    2        ;# TO SORT
  887. SVEPOS    DS    2        ;save position
  888. AORDER    DS    2        ;ORDER TABLE ADDRESS
  889. TEMP    DS    2    ;SAVE DIR ENTRY
  890. SWITCH    DS    1        ;SWAP SWITCH FOR SORT
  891.     DS    80    ;STACK AREA
  892. STACK    DS    2    ;SAVE OLD STACK HERE
  893. TABLE    EQU    $    ;READ ENTRIES IN HERE
  894.     END    100H
  895.  
  896. 1        ;SWAP SWITCH FOR SO