home *** CD-ROM | disk | FTP | other *** search
/ CP/M / CPM_CDROM.iso / jsage / znode3 / uploads / ctlcv11b.lbr / CTRLCVT.ZZ0 / CTRLCVT.Z80
Encoding:
Text File  |  1993-06-07  |  20.4 KB  |  585 lines

  1.         TITLE   Control Character converter
  2. ;++
  3. ;       CTRLCVT
  4. ;       Control character sequence converter
  5. ;
  6. ;       V1.1 - CRA 26-MAY-1990
  7. ;       Linked with V4LIB versions and converted source to SLR format.
  8. ;
  9. ;--
  10.         ASEG
  11.         IF      Z33             ; Z3BASE not needed in this setup
  12. TRUE    EQU     0FFFFH
  13. FALSE   EQU     0000H
  14.         ELSE
  15.         .XLIST
  16.         MACLIB  Z3BASE
  17.         .LIST
  18.         ENDIF                   ; Z33
  19.         .XLIST
  20.         MACLIB  CTRLCVT         ; get rest of equates
  21.         .LIST
  22. ;+
  23. ;       Link with Z3LIB and SYSLIB, and possibly Z33LIB.
  24. ;-
  25.         IF      Z33
  26.         .REQUEST Z33LIB,Z3LIB,SYSLIB
  27.         ELSE
  28.         .REQUEST Z3LIB,SYSLIB
  29.         ENDIF
  30. ;+
  31. ;       Mark some public symbols for debugging when requested.
  32. ;       (SLR180 eliminates this need!)
  33. ;-
  34.         SUBTTL  Establish Environment
  35.         PAGE
  36. ;+
  37. ;       ZCPR3 Program Header for use with Z3INS or the auto-install feature
  38. ;       of ZCPR33.
  39. ;-
  40.         CSEG
  41.         IF      Z3ENV NE 0 OR Z33
  42. ;+
  43. ;       Set up the headers for an external environment descriptor.
  44. ;       Taking advantage of SLRNK's ability to load code at 103H, we leave
  45. ;       room for the leading jump to the entry point START, declared as
  46. ;       such in the END statement.
  47. ;-
  48.         DEFB    'Z3ENV'         ; This is a zcpr3 utility
  49.         DEFB    1               ; type 1 image (external environment)
  50.         IF      Z33
  51. Z3EADR: DEFW    0               ; will be filled in by ZCPR33
  52.         ELSE
  53. Z3EADR: DEFW    Z3ENV           ; place environment descriptor here
  54.         ENDIF                   ; Z33
  55.         ELSE
  56. ;+
  57. ;       Prepare the internal environment descriptor, even though this will
  58. ;       take more memory.
  59. ;-
  60.         MACLIB  SYSENV          ; construct type 2 image
  61. Z3EADR: SYSENV
  62.         ENDIF                   ; Z3ENV > 0 | Z33
  63.         SUBTTL  Initialize
  64.         PAGE
  65. ;+
  66. ;       Call the initialization routine.
  67. ;       How we obtain the descriptor depends on the type of environment
  68. ;       we have.
  69. ;-
  70. START:: IF      DEBUG           ; setup a dummy command line if debugging
  71.         LD      BC,CMDLNE-CMDLNB; place length
  72.         LD      DE,DMA          ; target
  73.         LD      HL,CMDLNB       ; command line dummy
  74.         LDIR                    ; place it
  75.         ENDIF                   ; DEBUG
  76.         IF      Z3ENV NE 0
  77.         LD      HL,(Z3EADR)     ; obtain environment descriptor
  78.         ELSE
  79.         LD      HL,Z3EADR       ; obtain descriptor from inline
  80.         ENDIF                   ; Z3ENV switch
  81.         CALL    Z3INIT##        ; tell library about it
  82. ;+
  83. ;       Check on the validity of the ZCPR33 environment.
  84. ;-
  85.         IF      Z33
  86.         CALL    Z33CHK##        ; find out if this is Z33able
  87.         JR      Z,Z33IS         ; yup
  88.         LD      A,0FFH          ; nope
  89. Z33SV:  LD      (Z33FLAG),A     ; save this
  90.         JR      HEAP
  91. Z33IS:  XOR     A               ; clear A
  92.         JR      Z33SV           ; fall around
  93.         ENDIF                   ; Z33
  94. ;+
  95. ;       Initialize allocation routines.
  96. ;-
  97. HEAP:   LD      A,1             ; indicate that we are providing bottom of heap
  98.         LD      HL,HEAPSTART    ; load bottom of heap
  99.         CALL    IALLOC##        ; establish allocation
  100. ;+
  101. ;       Print signon message if the QUIET flag is off.
  102. ;-
  103.         LD      HL,SIGNON
  104.         CALL    QPSTR##
  105.         CALL    QCRLF##
  106.         SUBTTL  Parse command line
  107.         PAGE
  108. ;+
  109. ;       See to it that we do not have a zero length argument string
  110. ;       (meaning that the user only typed in the command).
  111. ;-
  112.         LD      A,(DMA)         ; pick up length of string
  113.         CP      0               ; and check
  114.         JR      NZ,COPY1        ; we appear to have no arguments
  115.         LD      HL,NOARGS1      ; get 'No arguments' string
  116.         CALL    PSTR##          ; and print it
  117.         LD      A,8             ; set error #8
  118.         JP      ERROR           ; no more
  119. ;+
  120. ;       Change the command line from a counted string to a null terminated
  121. ;       string.
  122. ;-
  123. COPY1:  LD      C,A             ; BC = A
  124.         LD      B,0             ; zero MS byte
  125.         LD      HL,DMA+1        ; our source
  126.         ADD     HL,BC           ; make a new pointer
  127.         XOR     A               ; A = 0
  128.         LD      (HL),A          ; null terminate string
  129. ;+
  130. ;       Conduct ARGV-style token parsing on the command line.
  131. ;       The copied target line will be modified.
  132. ;-
  133.         LD      HL,DMA+1        ; obtain our now null-terminated string
  134.         LD      DE,TOKENP       ; set up token start
  135.         LD      A,0FFH          ; we want null-terminated tokens
  136.         CALL    ARGV##
  137.         JR      Z,ARGCHK        ; at least we have <= 2 arguments
  138.         LD      HL,ARGG1
  139.         CALL    PSTR##          ; too many arguments
  140.         LD      A,5             ; set error #5
  141.         JP      ERROR
  142. ;+
  143. ;       Begin to look at the arguments presented.
  144. ;       See if a '//' was passed, signifying a request for information.
  145. ;-
  146. ARGCHK: LD      HL,(TOKEN1)     ; pointer to first char in first arg
  147.         LD      A,'/'           ; get the help character
  148.         CP      (HL)            ; so far so good?
  149.         JR      NZ,TOKENS       ; nope, see about argument count
  150.         INC     HL              ; look at next spot
  151.         CP      (HL)            ; did we get two?
  152.         JR      NZ,TOKENS       ; nope
  153. ;+
  154. ;       Display relevant description information.
  155. ;-
  156.         IF      VERBOSE
  157.         IRPC    LB,12345
  158.         CALL    CRLF##          ;; flush a line first
  159.         LD      HL,DESCN&LB     ;; first line
  160.         CALL    PSTR##
  161.         ENDM
  162.         ELSE
  163.         IRPC    LB,12
  164.         CALL    CRLF##          ;; flush a line first
  165.         LD      HL,DESCN&LB     ;; first line
  166.         CALL    PSTR##
  167.         ENDM
  168.         ENDIF
  169.         RET                     ; that's it, we done
  170. ;+
  171. ;       Look at the number of arguments passed.
  172. ;-
  173. TOKENS: LD      A,(TOKENP+1)    ; get number of args found
  174.         CP      2               ; check against magic number
  175.         JR      Z,SEARCH        ; this is 2 args
  176.         LD      HL,ARGL1
  177.         CALL    PSTR##          ; too few arguments
  178.         LD      A,8             ; and set error 8
  179.         JP      ERROR
  180.         SUBTTL  Determine names of files
  181.         PAGE
  182. ;+
  183. ;       Parse the input file name first.
  184. ;-
  185. SEARCH: LD      HL,(TOKEN1)     ; set to input token
  186.         LD      DE,IFCB         ; set to input FCB
  187.         LD      A,1             ; search DU before DIR
  188.         CALL    ZPRSFN##        ; parse name
  189.         LD      A,BUFSIZE/128   ; set up the buffer size
  190.         LD      (ICBPAGES),A    ; and save it
  191.         LD      DE,BUFSIZE      ; set up buffer size
  192.         CALL    ALLOC##         ; request dynamic memory
  193.         LD      (ICBBUFA),HL    ; and save the returned address
  194. ;+
  195. ;       Now parse the output file name.
  196. ;-
  197.         LD      HL,(TOKEN2)     ; set to output token
  198.         LD      DE,OFCB         ; set to output FCB
  199.         LD      A,1             ; search DU before DIR
  200.         CALL    ZPRSFN##        ; parse this name
  201.         LD      A,BUFSIZE/128   ; set up the buffer size
  202.         LD      (OCBPAGES),A    ; and save it
  203.         LD      DE,BUFSIZE      ; set up buffer size
  204.         CALL    ALLOC##         ; request dynamic memory
  205.         LD      (OCBBUFA),HL    ; and save the returned address
  206. ;+
  207. ;       At this point, we use FXI$OPEN to open the input file with the
  208. ;       'multiblock' capability to ease disk accesses.
  209. ;-
  210.         LD      DE,IFCB         ; reestablish input file
  211.         CALL    Z3LOG##         ; and log it in
  212.         IF      VERBOSE         ; only necessary for verbosity
  213.         CALL    RETUD##         ; obtain this DU
  214.         LD      (IDU),BC        ; and save
  215.         ENDIF                   ; VERBOSE
  216.         LD      DE,ICB          ; now establish extended IOCB
  217.         CALL    FXI$OPEN##      ; open input file for reading
  218.         JR      NZ,OPENED       ; file is open
  219. ;+
  220. ;       This means that the file wasn't opened. Build up the messages
  221. ;       and return abnormally.
  222. ;-
  223.         LD      HL,ERRF1        ; first part
  224.         CALL    PSTR##
  225.         LD      HL,(TOKEN1)     ; file name
  226.         CALL    PSTR##
  227.         LD      HL,ERRF2        ; second part
  228.         CALL    PSTR##
  229.         LD      A,10            ; set error #10
  230.         JP      ERROR
  231. ;+
  232. ;       We opened the input file. Now we must get ready to create the
  233. ;       output file if it doesn't exist.
  234. ;-
  235. OPENED: LD      DE,OFCB         ; reestablish output file context
  236.         CALL    Z3LOG##         ; log in this DU
  237.         IF      VERBOSE         ; only necessary for verbosity
  238.         CALL    RETUD##         ; obtain this DU
  239.         LD      (ODU),BC        ; and save
  240.         ENDIF                   ; VERBOSE
  241.         LD      DE,OCB          ; now establish extended IOCB
  242.         CALL    FXO$OPEN##      ; open output file for writing
  243.         JR      NZ,CONVERT      ; if file is open, begin converting
  244. ;+
  245. ;       This file didn't get opened, either.
  246. ;-
  247.         LD      HL,ERRX1        ; first part
  248.         CALL    PSTR##
  249.         LD      HL,(TOKEN2)     ; file name
  250.         CALL    PSTR##
  251.         LD      HL,ERRX2        ; second part
  252.         CALL    PSTR##
  253.         LD      A,12            ; set error #12 (can't write)
  254.         JP      ERROR
  255.         SUBTTL  Conversion Main Loop
  256.         PAGE
  257. ;+
  258. ;       Conversion initialization.
  259. ;-
  260. CONVERT:IF      VERBOSE         ; this stuff only necessary if verbose
  261.         CALL    GETQUIET##      ; actions here contingent on quiet flag
  262.         JR      NZ,LOOP         ; we are quiet, skip initialization
  263. ;+
  264. ;       Initialize the counter for the number of characters converted.
  265. ;-
  266.         LD      HL,0            ; clear the counters
  267.         LD      (CONV),HL       ; clear 'converted' count
  268. ;+
  269. ;       Indicate what files we are converting.
  270. ;-
  271.         LD      HL,CNVM1        ; first message part
  272.         CALL    PSTR##          ; display it
  273.         LD      BC,(IDU)        ; get DU for input file
  274.         CALL    PDU             ; display the DU form
  275.         LD      A,':'           ; separator
  276.         CALL    COUT##          ; display this
  277.         LD      DE,IFCB         ; get input FCB
  278.         CALL    PFN             ; display file name in FCB
  279.         LD      HL,CNVM2        ; second message part
  280.         CALL    PSTR##          ; display it
  281.         LD      BC,(ODU)        ; get DU for output file
  282.         CALL    PDU             ; display the DU form
  283.         LD      A,':'           ; separator
  284.         CALL    COUT##          ; display this
  285.         LD      DE,OFCB         ; get output FCB
  286.         CALL    PFN             ; display file name in FCB
  287.         CALL    CRLF##          ; end of line. (TRON quote, can't help it)
  288.         ENDIF                   ; VERBOSE
  289. ;+
  290. ;       Main loop of the conversion code.
  291. ;-
  292. LOOP:   LD      DE,ICB
  293.         CALL    FX$GET##        ; obtain next character
  294.         JR      Z,COUNT         ; we are at end of file, so we will count
  295.         CP      CTRLFLAG        ; is character the control flag?
  296.         JR      NZ,WRITE        ; most characters fall through
  297. ;+
  298. ;       But this one does not fall through.
  299. ;       We'll have to get another character from the stream.
  300. ;-
  301.         CALL    FX$GET##        ; get another character
  302.         JR      Z,COUNT         ; hit end of file
  303.         CP      CTRLFLAG        ; if it's the same character, we wanted one
  304.         JR      Z,WRITE         ; treat the two identical char's as one
  305. ;+
  306. ;       Mask out the non-control characters.
  307. ;-
  308.         AND     CTRLMASK        ; our mask to pass these characters through
  309. ;+
  310. ;       Maintain our count of characters converted if verbose.
  311. ;-
  312.         IF      VERBOSE         ; only necessary when verbose (gasp)
  313.         LD      HL,CONV         ; get the point to increment
  314.         INC     (HL)
  315.         JR      NZ,WRITE        ; no carry
  316.         INC     HL              ; adjust pointer
  317.         INC     (HL)            ; and increment this
  318.         ENDIF                   ; VERBOSE
  319. ;+
  320. ;       This character is processed.
  321. ;       Write it out to the stream.
  322. ;-
  323. WRITE:  LD      DE,OCB
  324.         CALL    FX$PUT##        ; write converted character
  325.         JR      NZ,LOOP         ; no error, resume processing in loop
  326. ;+
  327. ;       A write error has occured (such as a full disk).
  328. ;       Indicate this is an error, close files, and exit.
  329. ;-
  330.         LD      HL,ERRW1
  331.         CALL    PSTR##          ; display error
  332.         CALL    DONE            ; close the files
  333.         LD      A,12            ; error code 12
  334.         JR      ERROR           ; and handle the errors
  335. ;+
  336. ;       Display the number of characters converted.
  337. ;-
  338. COUNT:
  339.         IF      VERBOSE         ; compile if verbose
  340.         CALL    GETQUIET##      ; get quiet state
  341.         JR      NZ,DONE         ; don't do this if quiet flag on
  342.         LD      A,' '           ; we like a space following all messages
  343.         CALL    COUT##          ; so we print one
  344.         LD      HL,(CONV)       ; get the count
  345.         CALL    PHLFDC##        ; display count in unjustified decimal
  346.         LD      HL,SUMM1        ; point to rest of message
  347.         CALL    PSTR##          ; and display it
  348.         ENDIF                   ; VERBOSE
  349. ;+
  350. ;       Close files.
  351. ;-
  352. DONE:   LD      DE,ICB
  353.         CALL    FXI$CLOSE##     ; close input file
  354.         LD      DE,OCB
  355.         CALL    FXO$CLOSE##     ; close output file
  356. ;+
  357. ;       Normal return. (and return point for calling DONE!)
  358. ;-
  359.         RET                     ; we done normally
  360.         SUBTTL  Error Handling
  361.         PAGE
  362. ;+
  363. ;       Here is where error handling is performed. For Z33, we can use
  364. ;       the special error codes for advanced error handling features.
  365. ;-
  366. ERROR:  PUSH    AF              ; save the error code
  367.         LD      A,0FFH          ; set up usual error stuff
  368.         CALL    PUTER2##        ; set the usual flag
  369.         POP     AF
  370.         IF      Z33             ; get into advanced stuff
  371.         LD      B,A             ; move error code into B
  372.         LD      A,0FFH          ; indicate external program error
  373.         CALL    INVERROR##      ; invoke error handler
  374.         JP      NZ,0            ; warm boot if Z33 isn't available
  375.         ENDIF                   ; Z33
  376.         RET                     ; otherwise make a clean exit
  377.         SUBTTL  Print the Disk and User Number
  378.         PAGE
  379. ;++
  380. ;       PDU
  381. ;       Display the Disk and User Number
  382. ;
  383. ;       Inputs:
  384. ;       BC - disk and user in a form returned from RETUD and GETUD, i.e.,
  385. ;       B = 0 for disk A, and C = user number
  386. ;
  387. ;       Outputs:
  388. ;       None.
  389. ;
  390. ;       Implicit Inputs:
  391. ;       None.
  392. ;
  393. ;       Inplicit Outputs:
  394. ;       Up to three characters are written to the console.
  395. ;
  396. ;       Side Effects:
  397. ;       Stack is affected.
  398. ;
  399. ;       Calls:
  400. ;       COUT, PAFDC
  401. ;--
  402.         PAGE
  403. PDU::   PUSH    AF              ; save flags and A
  404. ;+
  405. ;       Modify the count in B to make it a reasonable disk letter.
  406. ;-
  407.         LD      A,B
  408.         ADD     A,'A'           ; this is the offset
  409.         CALL    COUT##          ; display it
  410. ;+
  411. ;       Display the user number as decimal.
  412. ;-
  413.         LD      A,C
  414.         CALL    PAFDC##         ; display as decimal
  415. ;+
  416. ;       We done.
  417. ;-
  418.         POP     AF              ; restore A and flags
  419.         RET
  420. ;
  421.         SUBTTL  Print the file name and type
  422.         PAGE
  423. ;++
  424. ;       PFN
  425. ;       Display the File Name and Type
  426. ;
  427. ;       Inputs:
  428. ;       DE - FCB for file to display
  429. ;
  430. ;       Outputs:
  431. ;       None.
  432. ;
  433. ;       Implicit Inputs:
  434. ;       None.
  435. ;
  436. ;       Inplicit Outputs:
  437. ;       Up to 12 characters are written to the console, 8 for the file name
  438. ;       (blank padded), a period, and 3 for the file type (blank padded).
  439. ;       Bit 7 is cleared in all characters to prevent funny characters
  440. ;       from falling through.
  441. ;
  442. ;       Side Effects:
  443. ;       Stack is affected.
  444. ;
  445. ;       Calls:
  446. ;       COUT
  447. ;--
  448.         PAGE
  449. PFN::   PUSH    AF              ; save flags and A
  450.         PUSH    BC              ; and especially B
  451.         PUSH    HL              ; to save from clobbering
  452. ;+
  453. ;       Point the FCB to the first character in the file name and start
  454. ;       printing it to the screen.
  455. ;-
  456.         LD      H,D             ; move DE to HL
  457.         LD      L,E
  458.         INC     HL              ; position to first char in file name
  459.         LD      B,8             ; want 8 characters
  460. PN1:    LD      A,(HL)          ; get character
  461.         RES     7,A             ; clear bit 7
  462.         CALL    COUT##          ; print it
  463.         INC     HL              ; point to next
  464.         DJNZ    PN1             ; do exactly 8
  465. ;+
  466. ;       Now display the period.
  467. ;-
  468.         LD      A,'.'
  469.         CALL    COUT##          ; print the period
  470. ;+
  471. ;       Print the three characters in the file type.
  472. ;-
  473.         LD      B,3             ; want 3 characters
  474. PN2:    LD      A,(HL)          ; get character
  475.         RES     7,A             ; clear bit 7
  476.         CALL    COUT##          ; print it
  477.         INC     HL              ; poin to next
  478.         DJNZ    PN2             ; do exactly 3
  479. ;+
  480. ;       We done.
  481. ;-
  482.         POP     HL              ; restore what was used
  483.         POP     BC
  484.         POP     AF
  485.         RET                     ; we done
  486.         SUBTTL  Read only Storage Areas
  487.         PAGE
  488. ;+
  489. ;       Signon message.
  490. ;-
  491. SIGNON: DEFB    'CTRLCVT, Version '
  492.         DEFB    [VERSION / 10] + '0'
  493.         DEFB    '.'
  494.         DEFB    [VERSION MOD 10] + '0'
  495.         DEFB    '-'
  496.         DEFB    [MODF / 100] + '0'
  497.         DEFB    [MODF / 10 MOD 10] + '0'
  498.         DEFB    [MODF MOD 10] + '0'
  499.         DEFB    0
  500. ;+
  501. ;       Informational message pointers are kept here.
  502. ;-
  503.         IF      VERBOSE         ; only compile if requested
  504. CNVM1:  DEFZ    ' Converting '
  505. CNVM2:  DEFZ    ' to '
  506. SUMM1:  DEFZ    ' characters were converted'
  507.         ENDIF                   ; VERBOSE
  508. DESCN1: DEFZ    'Usage:'
  509. DESCN2: DEFZ    '  CTRLCVT [du:]filename.typ [du:]filename.typ'
  510.         IF      VERBOSE         ; additional help only if requested
  511. DESCN3: DEFZ    'where the first file specification is the input file to be'
  512. DESCN4: DEFZ    'converted, and the second file specification is the output'
  513. DESCN5: DEFZ    'file to which the converted output is written.'
  514.         ENDIF                   ; VERBOSE
  515. ;+
  516. ;       Error message pointers are kept here.
  517. ;-
  518. NOARGS1:DEFZ    ' No arguments on command line'
  519. ARGL1:  DEFZ    ' Too few arguments'
  520. ARGG1:  DEFZ    ' Too many arguments'
  521. ERRF1:  DEFZ    ' File '
  522. ERRF2:  DEFZ    ' NOT Found'
  523. ERRX1:  DEFZ    ' Can not open file '
  524. ERRX2:  DEFZ    ' for processing'
  525. ERRW1:  DEFZ    ' Write error'
  526. ;+
  527. ;       Command line for debugging.
  528. ;       We build a counted ASCII string (VAX/VMS terminology: .ASCIC)
  529. ;-
  530.         IF      DEBUG
  531. CMDLNB: DEFB    CMDLNE-CMDLIN   ; length
  532. CMDLIN: DEFB    ' TEST.TXT TEST.001'
  533. CMDLNE:
  534.         ENDIF                   ; DEBUG
  535.         SUBTTL  Read/Write Storage Areas
  536.         PAGE
  537.         DSEG
  538. ;+
  539. ;       Token pointer storage area.
  540. ;-
  541. TOKENP: DEFB    2               ; maximum of three tokens
  542.         DEFS    1               ; number we really found
  543. TOKEN1: DEFS    2               ; first token pointer
  544. TOKEN2: DEFS    2               ; second token pointer
  545. ;+
  546. ;       Input and output extended FCB's.
  547. ;-
  548. ICB:
  549. ICBPAGES:
  550.         DEFS    1               ; number of 128 byte pages to set up
  551.         DEFS    5               ; filled in by callee
  552. ICBBUFA:DEFW    1               ; address of input buffer
  553. IFCB:   DEFS    36
  554. ;
  555. OCB:
  556. OCBPAGES:
  557.         DEFS    1               ; number of 128 byte pages to set up
  558.         DEFS    5               ; filled in by callee
  559. OCBBUFA:DEFW    1               ; address of input buffer
  560. OFCB:   DEFS    36
  561. ;+
  562. ;       Counter storage area.
  563. ;-
  564.         IF      VERBOSE         ; also only compile if requested
  565. CONV:   DEFS    2               ; word for the converted total
  566. ;+
  567. ;       DU storage areas.
  568. ;-
  569. IDU:    DEFS    2               ; places to keep the two DU's
  570. ODU:    DEFS    2               ; where we can get at them
  571.         ENDIF                   ; VERBOSE
  572. ;+
  573. ;       Z33 or greater enabled flag.
  574. ;-
  575.         IF      Z33
  576. Z33FLAG:DEFS    1               ; flag: 0 if Z33 enabled, nonzero if not
  577.         ENDIF                   ; Z33
  578. ;+
  579. ;       End of data area.
  580. ;-
  581.         END     START           ; identify entry point for module
  582. rd for the converted total
  583. ;+
  584. ;       DU storage areas.
  585. ;-
  586.