home *** CD-ROM | disk | FTP | other *** search
- ; XLAT.ASM -- configurable char-to-char file converter
- ;
- ; Freeware by TapirSoft Gisbert W.Selke, Oct 89
- ;
-
- ; TASM xlat
- ; TLINK /T xlat
-
- Tab Equ 09h
- Return Equ 0Dh
- LineFeed Equ 0Ah
- CtrlZ Equ 1Ah
-
-
- CSEG Segment
- Assume CS:CSEG, DS:CSEG, ES:CSEG, SS:CSEG
-
- Org 0000h
- CSegOfs Label Byte ; start of core image
-
- Org 0080h
- CmdLine Label Byte
-
-
- Org 0100h
- Entry: Jmp Begin
-
- ;
- ; Data:
- ;
- ProgInfo db Low(Offset ProgVersion) ; file offset of patch info
- ProgName db Return, 'Configurable text file converter'
- CopyRight db Return, LineFeed
- db 'FreeWare by TapirSoft Gisbert W.Selke, Oct 1989'
- db Return, LineFeed
- Marker1 db '<<<< ' ; marker for patches
- Description db 'Identity mapping as a starting point '
- ; the length of the preceding string should remain at 40!
- Marker2 db ' >>>>', CtrlZ ; marker for patches
- EndHeader Label Byte
-
- ProgVersion db 'XLAT10' ; standard name and version
- DescOff db Low(Offset Description) ; file offset of descr. text
- DescLength db Marker2-Description ; length of description text
- InterNameOff dw (Offset InterName)-100h ; file offset of usage text
- MainTableOff dw MainTable-100h ; file offset of main table
-
- ; the next few lines fill the 'default' translation table with the identity
- ; mapping:
- MainTable Label Byte
- outcode = 0
- Rept 256
- db outcode
- outcode = outcode + 1
- EndM
- MainTableEnd Label Byte
-
- InverseFlag db 0 ; 0 = normal; 1 = inverse
-
- ReadErrString db 'Error reading from file', Return, LineFeed
- ReadErrEnd Label word
- WriteErrString db 'Error writing to file', Return, LineFeed
- WriteErrEnd Label word
-
-
- Begin: Cld ; All string directions forward
- Call ParseArgs ; scan command line
- Cmp InverseFlag, 0FFh ; illegal parrameter?
- Je Usage ; skip if so
- Cmp InverseFlag, 1 ; use inverted table?
- Je UseInverse ; skip if so
- Mov bx, Offset MainTable ; else use table as specified
- Push bx ; put on stack
- Jmp Short NextBuffer
-
- UseInverse: Call BuildInverse ; build inverse table
- Mov bx, Offset InverseTable ; use inverted table
- Push bx ; put address on stack
-
- NextBuffer: Mov ah, 3Fh ; read buffer from stdin
- Xor bx, bx
- Mov cx, BufferLength
- Mov dx, offset Buffer
- Mov si, dx ; jot down for later use
- Mov di, dx ; ditto
- Int 21h
-
- Jc ReadError ; jump if error on read
- Or ax, ax
- Jz FinishIt ; jump to end if no chars read
-
- Pop bx ; get back tranlation table address
- Mov cx, ax ; number of chars actually read
- Mov dx, ax ; also, save for later use
-
- ProcChar: Lodsb ; process characters
- Xlat ; translate according to table
- Stosb ; stuff it back in
- Loop ProcChar ; process next character, if available
-
- Push bx ; otherwise save table address
- Mov ah, 40h
- Mov bx, 1 ; write to stdout
- Mov cx, dx ; get back number of characters
- Mov dx, offset Buffer
- Int 21h
-
- Jc WriteError
- Cmp ax, cx
- Jne WriteError
-
- Jmp short NextBuffer ; get next buffer
-
-
- ;
- ; Handle read error:
- ;
-
- ReadError: Mov dx, Offset ReadErrString
- Mov cx, ReadErrEnd-ReadErrString
- Mov ah, 40h ; output message to stderr
- Mov bx, 2
- Int 21h
-
- Pop bx ; remove table address from stack
- Mov al, 02h ; set error flag
- Jmp Short Terminate
-
-
- ;
- ; Handle write error:
- ;
-
- WriteError: Mov dx, Offset WriteErrString
- Mov cx, WriteErrEnd-WriteErrString
- Mov ah, 40h ; output message to stderr
- Mov bx, 2
- Int 21h
-
- Pop bx ; remove table address from stack
- Mov al, 03h ; set error flag
- Jmp Short Terminate
-
-
- ;
- ; show usage screen:
- ;
-
- Usage: Mov dx, Offset ProgName ; display programme header
- Mov cx, ProgName-EndHeader
- Mov ah, 40h ; output message to stderr
- Mov bx, 2
- Int 21h
-
- Mov dx, Offset UsageText ; display usage screen
- Mov cx, UsageEnd-UsageText
- Mov ah, 40h ; output message to stderr
- Int 21h
- Mov al, 01h
- Jmp Short Terminate
-
-
- ;
- ; We are done.
- ;
-
-
- FinishIt: Pop bx ; remove table address from stack
- Xor al, al ; set no-error flag
- Jmp Short Terminate
-
-
- ;
- ; Terminate
- ;
-
- Terminate: Mov ah, 4Ch ; error flag was set elsewhere
- Int 21h ; Terminate
-
-
- ;
- ; Subroutines:
- ;
-
- BuildInverse Proc Near
- ;
- ; Build inverse mapping table as well as we can.
- ; Scan backwards; we assume that in case of non-injectivity,
- ; the preferrred values are the lower character codes
- ; (i.e., choose the lowest pre-image).
- ; (Just as well as any other assumption, but easier to imagine)
- ;
-
- Mov di, Offset InverseTable ; point to inverse table
- Xor ax, ax ; initialization value: 0
- Mov cx, 256 ; length of table
- Rep Stosb ; fill table
-
- Std ; scan original table backward
- Mov si, Offset MainTableEnd - 1; point to end of original table
- Mov cx, 256 ; length of table
- Xor dl, dl ; set dl to 'last char'
- ; Xor ax, ax ; ax is still 0
-
- BINext: Lodsb ; get next table entry
- Mov di, ax
- Dec dl
- Mov byte ptr [di+InverseTable], dl; Table[Maintable[dl]] <- dl
- Loop BINext
-
- Cld ; scan forward again
- Ret
- EndP BuildInverse
-
-
- ParseArgs Proc Near
- ;
- ; scan command line for arguments; only arguments supported:
- ; /i : use inverse mapping
- ; anything else : usage screen (sent to stderr)
- ;
-
- Mov si, Offset CmdLine + 1 ; point to command line
-
- PANext: Lodsb ; get next char
- Cmp al, Return ; at end?
- Je PADone ; if so, finish
- Cmp al, ' ' ; ignore this?
- Je PANext
- Cmp al, ',' ; ignore this?
- Je PANext
- Cmp al, Tab ; ignore this?
- Je PANext
- Cmp al, '/' ; switch char?
- Je PASwitch ; skip if so
- Cmp al, '-' ; switch char?
- Jne PAUsage ; skip if not
-
- PASwitch: Lodsb ; which switch?
- Or al, 20h ; convert to lower case
- Cmp al, 'i' ; request for inversion?
- Jne PAUsage ; skip if not
- Mov InverseFlag, 1 ; mark for to use inverse
- Jmp Short PANext ; and scan on
-
- PAUsage: Mov InverseFlag, 0FFh ; otherwise illegal arg
-
- PADone: Ret
- EndP ParseArgs
-
-
- ; room for inverted table:
- InverseTable Label Byte ; room for inverted table
- InverseTableEnd Equ InverseTable + 256 ; pointer to end of same
-
- ; text of usage screen, will be overwritten by InverseTable:
- UsageText db Return, LineFeed, 'Usage: '
- InterName db 'xlat [/i] <input >output', Return, LineFeed
- db ' Specifying /i will invert the mapping.'
- db Return, Linefeed
- UsageEnd Label Byte
-
- ;
- ; File Buffer
- ;
-
- Buffer Equ InverseTable + 256 ; file data buffer...
- BufferLength Equ (Offset CSegOfs - Offset buffer) - 40h ; free length
- ; (small stack is enough)
-
- CSEG EndS ; End of segment
- End Entry ; Denotes entry point
-