home *** CD-ROM | disk | FTP | other *** search
/ Simtel MSDOS - Coast to Coast / simteldosarchivecoasttocoast2.iso / asmutil / a86v322.zip / REV.8 < prev    next >
Text File  |  1987-04-07  |  4KB  |  87 lines

  1. ;---------------
  2. ;   REV
  3. ;---------------
  4.  
  5. ; REV is a filter that reverses all lines of standard input, and sends
  6. ;   the reversed lines to standard output.
  7.  
  8. DATA SEGMENT
  9.   ORG 02000         ; small model-- start data well beyond this program
  10. OBUFF:              ; output buffer
  11.   DB 02000 DUP (?)
  12. OBUFF_LIM:          ; limit signalling we are near the end of the output buffer
  13.   DB 0100 DUP (?)
  14. DATA ENDS
  15.  
  16. REV:
  17.   MOV BP,OBUFF         ; initialize the output buffer to empty
  18.   CALL VERIFY_NO_ARGS  ; verify that there were no arugments in the command tail
  19.   CALL PROCESS_INPUT   ; reverse all the line of standard input
  20.   CALL FLUSH_OUTPUT    ; flush the output buffer
  21.   JMP GOOD_EXIT        ; success-- exit back to the operating system
  22.  
  23.  
  24. ; VERIFY_NO_ARGS insures that there are no command-tail arguments at the
  25. ;   PSP buffer DS:080.  If there are, we abort with USAGE_MSG.
  26.  
  27. VERIFY_NO_ARGS:
  28.   MOV SI,080           ; point to the PSP command-tail
  29.   LODSB                ; fetch the length byte
  30.   CBW                  ; extend length AL into AX
  31.   XCHG CX,AX           ; swap the command tail length into CX
  32.   JCXZ RET             ; good return if there is no tail whatsoever
  33. L1:                    ; loop here for each byte of the command tail
  34.   LODSB                ; fetch a command-tail byte
  35.   CMP AL,' '           ; it had better be a blank or a control character
  36.   IF A JMP USAGE_EXIT  ; error exit if command tail has non-blank contents
  37.   LOOP L1              ; loop for the next command-tail byte
  38.   RET
  39.  
  40. USAGE_MSG:
  41.   DB 'usage: rev <in >out',0D,0A
  42. USAGE_SIZE EQU $ - USAGE_MSG
  43.  
  44.  
  45. ; PROCESS_LINE reverses the line of CX bytes pointed to by SI (and beyond by
  46. ;   DI), and copies the reversed line to the output buffer.
  47.  
  48. PROCESS_LINE:
  49.   DEC DI               ; decrement beyond-pointer back to linefeed
  50.   CMP B[DI-1],0D       ; is there also a CR terminating this line?
  51.   IF E DEC DI          ; if yes then decrment back to the CR, also
  52.   CALL REV_STRING      ; reverse the characters of the line
  53.   MOV DI,BP            ; fetch the output buffer pointer
  54.   REP MOVSB            ; copy the reversed line to the output buffer
  55.   MOV BP,DI            ; store the updated output buffer pointer
  56.   CMP BP,OBUFF_LIM     ; is the output buffer almost full?
  57.   JB RET               ; return if not
  58. FLUSH_OUTPUT:
  59.   PUSH AX,BX,CX,DX     ; preserve registers across call
  60.   MOV DX,OBUFF         ; point to the start of the output buffer
  61.   MOV CX,BP            ; point CX beyond the bytes we have placed in buffer
  62.   SUB CX,DX            ; calculate the number of bytes in the buffer
  63.   MOV BP,DX            ; reset the output pointer back to the buffer start
  64.   MOV BX,1             ; file handle for standard output is 1
  65.   CALL MWRITE          ; write the buffered bytes to standard output
  66.   POP DX,CX,BX,AX      ; restore clobbered registers
  67.   RET
  68.  
  69.  
  70. ; REV_STRING reverses the string running from DS:SI through DS:DI-1.  We do so
  71. ;    by repeatedly exchanging the bytes pointed to by each pointer, then moving
  72. ;    the pointers in towards each other, until they meet.
  73.  
  74. REV_STRING:
  75.   CMP SI,DI
  76.   JE RET
  77.   PUSH SI,DI        ; save registers across call
  78. L1:                 ; loop here for each pair of bytes
  79.   LODSB             ; fetch the SI-pointed byte
  80.   DEC DI            ; decrement DI to the last byte of the remaining string
  81.   XCHG AL,[DI]      ; exchange the SI-pointed byte with the DI-pointed byte
  82.   MOV [SI-1],AL     ; store the DI-pointed byte in the SI-pointed spot
  83.   CMP SI,DI         ; have SI and DI come together yet?
  84.   JB L1             ; loop if not to swap two more end-bytes
  85.   POP DI,SI         ; restore clobbered registers
  86.   RET               ; NoCarry set for disassembler MEMDIS_n's benefit
  87.