home *** CD-ROM | disk | FTP | other *** search
- page 75,132
- codeseg segment para 'code'
- assume cs:codeseg,ds:codeseg,es:codeseg
- ;=======================================================================
- ;= EXPAND_TABS =
- ;= ----------- =
- ;= Function: Expand tab characters into blanks (TABLINE-->NOTABLINE =
- ;= =
- ;= Call: EXPAND_TABS(var TABLINE,NOTABLINE:lstring); =
- ;= where TABLINE = input line (may have tabs in it). =
- ;= NOTABLINE = final line =
- ;= =
- ;= Calling parameter offsets (frame contents): =
- ;= +00,02,04 caller's BP, IP, CS registers =
- ;= +06 address of lstring NOTABLINE =
- ;= +08 max length of lstring NOTABLINE =
- ;= +10 address of lstring TABLINE =
- ;= +12 max length of lstring TABLINE =
- ;=======================================================================
- EXPAND_TABS proc far
- public EXPAND_TABS ;use from Pascal
- push bp ;save callers frame pointer
- mov bp,sp ;set frame pointer
- mov si,[bp+6] ;SI=A(NOTABLINE)
- mov byte ptr [si],0 ;default length of NOTABLINE = 0
- mov bx,[bp+10] ;address of TABLINE in caller's DS seg
- sub cx,cx ;CX = 0
- mov cl,[bx] ;CX = current TABLINE length
- inc bx ;skip TABLINE[0] = lstring length
- push es ;save caller's extra seg reg.
- jcxz exrtrn ;don't process if nothing in string
- ;------ Set ES to DS for 'Scan ------
- mov ax,ds ;ES & DS are used by scan(SCAB & SCAW)
- mov es,ax ;instructions and must get data that is
- ;defined in the caller's DS area.
- push cx ;save length of TABLINE
- ;------ Are there any tab char? ------
- mov di,bx ;DI= offset fo 1st element of TABLINE
- cld ;clear DF, causing incr thru TABLINE
- mov al,09H ;Compare char 9 = TAB
- REPNE scasb ;scan TABLINE for AX char - repeat CX
- pop cx ;CX= length of TABLINE
- je yestabs ;JMP=> tabs found
- ;------ Is line all blank? ------
- mov di,bx ;DI= offset of 1st element of TABLINE
- mov al,20H ;Compare char = blank
- REPE scasb ;scan TABLINE for non blnk, CX times
- je exrtrn ;return if all blank (leave length=0)
- mov si,[bp+10] ;------Move TABLINE to NOTABLINE------
- mov di,[bp+6] ;A(NOTABLINE)
- sub cx,cx ;
- mov cl,[si] ;length of TABLINE
- inc cx ;include byte 0 in move
- REP movsb ;TABLINE -> NOTABLINE
- jmp short exrtrn ;exit
- ;------ Process tab character ------
- yestabs: sub dx,dx ;DX=last col of TABLINE processed
- dec bx ;BX= A(TABLINE[0])
- mov di,bx ;DI= A(TABLINE[0])
- ; === GET_BYTE ===
- tabloop: inc dx ;incr TABLINE pointer
- mov bx,dx ;get updated pointer
- mov al,[bx][di] ;get nxt byte = A(TABLINE)+pointer
- ; =================
- cmp al,09H ;is this a tab char?
- je tabfound ;jmp if tab
- call PUT_BYTE ;put AL to NOTABLINE
- jmp short tabend ;
- tabfound:sub ax,ax ;
- mov al,[si] ;AX= col position of nxt char
- push cx ;save counter
- mov cx,8 ;COLUMN/8
- div cl ;AX/CL --> AL=Quotient AH=Remainder
- sub cl,ah ;CX= 8-(COLmod 8) = # blanks to insert
- mov al,20H ;blank char
- tabblnk: call PUT_BYTE ;put it into NOTABLINE
- loop short tabblnk ;repeat for all blanks to fill in
- pop cx ;get length left in NOTABLINE
- tabend: loop short tabloop ;do all NOTABLINE char
- ;---- Return to calling program ----
- exrtrn: pop es ;restore caller's ES
- pop bp ;restore caller's frame pointer
- ret 8
- ;------------ DATA--------------
- COL_IN db 0 ;current col in NOTABLINE
- ;(1st chr is length of expanded string)
- EXPAND_TABS endp ;
- ;========= PUT_BYTE =========
- PUT_BYTE proc near ;Move AL to nxt byte of NOTABLINE
- inc byte ptr [si] ;incr NOTABLINE[0] = lstring length
- sub bx,bx ;
- mov bl,byte ptr [si];pointer to nxt byte
- add bx,si ;A(NOTABLINE)+next byte
- mov [bx],al ;save byte
- ret ;return to calling point
- PUT_BYTE endp ;===================================
- codeseg ends ;end segment
- end ;end assembly