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