home *** CD-ROM | disk | FTP | other *** search
/ OS/2 Shareware BBS: 10 Tools / 10-Tools.zip / sd386v50.zip / sd386src.zip / ENCODE.ASM < prev    next >
Assembly Source File  |  1992-03-02  |  8KB  |  283 lines

  1.         page    ,132
  2.         title   Text Encode/Decode Routines
  3.         subttl  Copyright (C) 1988 by IBM (Written 5/88 by Jim Christensen)
  4.         name    ENCODE
  5.  
  6.         .386
  7.  
  8. _TEXT   SEGMENT  DWORD USE32 PUBLIC 'CODE'
  9. _TEXT      ENDS
  10. _DATA   SEGMENT  DWORD USE32 PUBLIC 'DATA'
  11.         align 4
  12. _DATA      ENDS
  13.         ASSUME   CS: FLAT, DS: FLAT, SS: FLAT, ES: FLAT
  14. PUBLIC  Encode
  15. PUBLIC  Decode
  16. _TEXT SEGMENT  DWORD USE32 PUBLIC 'CODE'
  17.  
  18. TAB             equ 009h
  19. SPACE           equ 020h
  20. LOWZONE         equ 010h
  21. HIGHZONE        equ 0A0h
  22. MAXPERRUN       equ 256-HIGHZONE-1
  23.  
  24. ;------------------------------------------------------------------------------;
  25. ; name          Encode --
  26. ;
  27. ; synopsis      n = Encode( LineOfText, OutputBuffer, LineLength );
  28. ;
  29. ;               uint n;                 /* # bytes returned in OutputBuffer */
  30. ;               char *LineOfText;       /* input line of text */
  31. ;               char *OutputBuffer;     /* output buffer */
  32. ;               ushort LineLength;      /* # bytes given in LineOfText */
  33. ;
  34. ; description   This routine
  35. ;
  36. ; assumptions   The OutputBuffer is large enough to hold the encoded line.
  37. ;------------------------------------------------------------------------------;
  38.  
  39. ;       EAX = work,  EBX = work,  ECX = input length,  EDX = current column
  40. ;       ds:ESI = input string,  es:EDI = output buffer
  41.  
  42. LineOfText   = 8
  43. OutputBuffer = 12
  44. LineLength   = 16
  45.  
  46. Encode  PROC    NEAR
  47.         enter   0,0
  48.         push    ESI
  49.         push    EDI
  50.         push    EBX
  51.         push    ECX
  52.         push    EDX
  53.  
  54.         mov     ESI, [EBP+LineOfText]   ;ds:ESI -> LineOfText
  55.         mov     EDI, [EBP+OutputBuffer] ;es:EDI -> OutputBuffer
  56.         mov     ECX, [EBP+LineLength]
  57.         xor     EDX, EDX                ;current column
  58.         jmp     short Restart
  59.  
  60. GotTab0:
  61.         mov     al, SPACE
  62.         mov     EBX, EDX
  63.         sub     EBX, 7                  ;EBX = (dx + 1) - 8
  64.         neg     EBX
  65.         and     EBX, 7                  ;EBX = # of additional spaces
  66.         jz      IgnoreTab0
  67.  
  68.         dec     ECX                      ;count tab char
  69.         add     EBX, ECX
  70.         dec     EBX
  71.         or      ECX, ECX                 ;set ZF=1 iff ECX=0
  72.         jmp     Rescan
  73.  
  74. ;       Get the next char into AL.  There is no previous char in AH.
  75. Restart:
  76.         jcxz    Fini
  77.         lodsb
  78.         cmp     al, TAB
  79.         je      GotTab0
  80.  
  81. IgnoreTab0:
  82.         xchg    al, ah
  83.         dec     ECX
  84.         jz      Done
  85.  
  86. ;       Get the next char into AL.  AH contains the previous
  87. ;       char, and has not yet been written to the output buffer.
  88. NextByte:
  89.         lodsb                           ;(ah,al) = (prev,next) chars
  90.         cmp     al, TAB
  91.         je      GotTab
  92.  
  93. IgnoreTab:
  94.         cmp     al, ah
  95.         je      GotRun
  96.  
  97.         xchg    al, ah                  ;(ah,al) = (next,prev) chars
  98.         cmp     al, HIGHZONE
  99.         jae     EscapeChar
  100.  
  101. OutputChar:
  102.         stosb
  103.         inc     EDX
  104.  
  105.         loop    NextByte
  106.  
  107. Done:
  108.         xchg    al, ah
  109.         cmp     al, HIGHZONE
  110.         jae     EscapeLast
  111.         stosb
  112. Fini:
  113.         xchg    EAX, EDI
  114.         sub     EAX, [EBP+OutputBuffer] ;EAX = # of bytes put into output buffer
  115.  
  116.         pop     EDX
  117.         pop     ECX
  118.         pop     EBX
  119.         pop     EDI
  120.         pop     ESI
  121.         leave
  122.         ret
  123.  
  124. EscapeChar:
  125.         mov     byte ptr es:[EDI], HIGHZONE + 1
  126.         inc     EDI
  127.         jmp     OutputChar
  128.  
  129. EscapeLast:
  130.         xchg    al, ah
  131.         mov     al, HIGHZONE + 1
  132.         stosw
  133.         jmp     Fini
  134.  
  135. GotTab:
  136.         mov     al, SPACE
  137.         mov     EBX, EDX
  138.         sub     EBX, 6                  ;EBX = (dx + 2) - 8
  139.         neg     EBX
  140.         and     EBX, 7                  ;EBX = # of additional spaces
  141.         jz      IgnoreTab
  142.  
  143.         dec     ECX                     ;count tab char
  144.         add     EBX, ECX
  145.         cmp     ah, SPACE
  146.         je      Rescan
  147.         dec     EBX
  148.  
  149.         xchg    al, ah
  150.         cmp     al, HIGHZONE
  151.         jae     EscapePreTab
  152. OutputPreTab:
  153.         stosb
  154.         inc     EDX
  155.  
  156.         xchg    al, ah
  157.         or      ECX, ECX                ;set ZF=1 iff ECX=0
  158.         jmp     short Rescan
  159.  
  160. EscapePreTab:
  161.         mov     byte ptr es:[EDI], HIGHZONE + 1
  162.         inc     EDI
  163.         jmp     OutputPreTab
  164.  
  165. GotRun:
  166.         dec     ECX                      ;count 2nd char of run (ZF=1 iff ECX=0)
  167.         mov     EBX, ECX
  168.  
  169. ;  Here ECX = # bytes togo, EBX-ECX = (# in run) - 2, EDX = column before run
  170. Rescan:
  171.         xchg    ESI, EDI
  172.         repe    scasb                   ;if ECX=0 initially, then ZF=1 required
  173.         xchg    ESI, EDI
  174.  
  175.         je      EndRun                  ;jump if scan ended on equal comapre
  176.         cmp     al, SPACE
  177.         jne     BackUp
  178.         cmp     byte ptr [ESI-1], TAB
  179.         jne     BackUp
  180.  
  181.         mov     EAX, EBX
  182.         sub     EAX, ECX  ;EAX = # of chars after 1st two including tab
  183.         add     EAX, EDX  ;EAX = current column - 2 counting tab for 1 space
  184.         sub     EAX, 6
  185.         neg     EAX
  186.         and     EAX, 7                   ;EAX = # of additional spaces
  187.         add     EBX, EAX                 ;backup start of run by that #
  188.         mov     EAX, SPACE + 256*SPACE
  189.         or      ECX, ECX                 ;set ZF=1 iff ECX=0
  190.         jmp     Rescan
  191. BackUp:
  192.         dec     ESI
  193.         inc     ECX
  194. EndRun:
  195.         sub     EBX, ECX               ;EBX = # of matching chars after 1st two
  196.         add     EBX, 2
  197.         add     EDX, EBX
  198. ChkMax:
  199.         cmp     EBX, MAXPERRUN
  200.         jbe     LastRun
  201.  
  202.         mov     al, HIGHZONE + MAXPERRUN
  203.         stosb
  204.         mov     al, ah
  205.         stosb
  206.         sub     EBX, MAXPERRUN
  207.         jmp     ChkMax
  208. LastRun:
  209.         add     bl, HIGHZONE
  210.         xchg    EAX, EBX
  211.         stosb
  212.         xchg    EAX, EBX
  213.         stosb
  214.         jmp     Restart
  215. Encode  endp
  216.  
  217.  
  218. ;------------------------------------------------------------------------------;
  219. ; name          Decode --
  220. ;
  221. ; synopsis      n = Decode( EncodedText, OutputBuffer );
  222. ;
  223. ;               uint n;                 /* # bytes returned in OutputBuffer */
  224. ;               char *EncodedText;      /* input encoded line */
  225. ;               char *OutputBuffer;     /* output buffer */
  226. ;
  227. ; description   This routine
  228. ;
  229. ; assumptions   The decoded text is truncated after 255 characters.
  230. ;------------------------------------------------------------------------------;
  231.  
  232. EncodedText  = 8
  233. OutputBuffer = 12
  234.  
  235. Decode  PROC    NEAR
  236.         enter   0,0
  237.         push    ESI
  238.         push    EDI
  239.         push    ECX
  240.         push    EDX
  241.  
  242.         mov     ESI, [EBP+EncodedText]
  243.         mov     EDI, [EBP+OutputBuffer]
  244.         mov     ECX, 255         ;max # bytes for output buffer
  245. dc10:
  246.         lodsb
  247.         cmp     al, LOWZONE
  248.         jb      dc20
  249.         cmp     al, HIGHZONE
  250.         jae     dc30
  251.         stosb
  252.         loop    dc10
  253. dc20:
  254.         xchg    EAX, EDI
  255.         sub     EAX, [EBP+OutputBuffer]  ;EAX=# of bytes put into output buffer
  256.  
  257.         pop     EDX
  258.         pop     ECX
  259.         pop     EDI
  260.         pop     ESI
  261.         leave
  262.         ret
  263. dc30:
  264.         sub     al, HIGHZONE
  265.         MOVSX   EAX, AL         ; sign extend "HIGHZONE"         107
  266.         sub     ECX, EAX
  267.         jbe     dc40
  268.         xchg    EAX, ECX        ;ECX = repeat count
  269.         xchg    EAX, EDX        ;EDX = residual buffer count
  270.         lodsb                   ;al = repeat char
  271.         rep     stosb
  272.         mov     ECX, EDX
  273.         jmp     dc10
  274. dc40:
  275.         add     EDX, EAX        ;ECX = residual buffer count
  276.         lodsb                   ;al = repeat char
  277.         rep     stosb
  278.         jmp     dc20
  279. Decode  endp
  280.  
  281. _TEXT   ends
  282.         end
  283.