home *** CD-ROM | disk | FTP | other *** search
- Title Resident printer translator
-
- ; XLATR.ASM -- configurable resident char-to-char print converter
- ; see usage text below on how to use it
- ;
- ; Freeware by TapirSoft Gisbert W.Selke, Aug 90
- ;
-
- ; TASM xlatr
- ; TLINK /T xlatr
-
- ; DOS interrupt calls:
- Printer Equ 17h ; printer interrupt
- DOSCall Equ 21h ; DOS interrupt
- DOSTSR Equ 3100h ; TSR interrupt
-
- ; DOS function numbers:
- PrintString Equ 09h ; output string to StdOut
- GetPrinterVec Equ 3517h ; get address of printer vector
- SetPrinterVec Equ 2517h ; set address of printer vector
- FreeMemory Equ 49h ; free memory
- Finish Equ 4C00h ; return to DOS
-
- ; our call number:
- SpecialFunc Equ 02Ah ; marker for special services
-
- ; some special characters:
- Tab Equ 09h
- LineFeed Equ 0Ah
- Return Equ 0Dh
- CtrlZ Equ 1Ah
-
- CSeg Segment
- Assume CS:CSeg, DS:CSeg
-
- Org 0080h
- CmdLine Label Byte ; pointer to command line
- XMainTable2 Label Byte ; - will be overwritten by
- Org $ + 2 ; translation table
- MainTable2 Label Byte
-
- Org 100h
-
- Start: Jmp Transient ; Go to transient code
-
- ;
- ; Informational data:
- ;
-
- ProgInfo db Low(Offset ProgVersion) ; file offset of patch info
- ProgName db Return, 'Configurable resident printer driver'
- CopyRight db Return, LineFeed
- db 'FreeWare by TapirSoft Gisbert W.Selke, Aug 1990'
- db Return, LineFeed
- Marker1 db '<<<< ' ; marker for patches
- Description db 'Identity mapping as a starting point '
- ; the length of the preceding string should always remain 40!
- Marker2 db ' >>>>', CtrlZ ; marker for patches
- EndHeader Label Byte
-
- ProgVersion db 'XLAT11' ; 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
-
- Org $ - 5 ; overwrite unneeded data
-
- OldPI Label DWord ; old printer interrupt:
- OldPIOfs Label Word ; first offset,
- Org $ + 2
- OldPISeg Label Word ; then seg
- Org $ + 2
- ActFlag Label Byte ; 0 = is active
- Org $ + 1
-
- CheckStart Equ $ ; resident code starts here
-
- Printerceptor Proc Far
- Assume CS:CSeg, DS:CSeg
-
- Sti ; Turn interrupts back on
- Cmp ah, SpecialFunc ; check for special codes
- Jne GoOn ; if none, process normally
- Cmp al, 'u' ; unloading requested?
- Jne CheckDes ; if not, try more
- Mov dx, cs:OldPIOfs ; otherwise start removal
- Mov ax, cs:OldPISeg
- Mov ds, ax
- Mov ax, SetPrinterVec ; Reestablish old INT 17h handler
- Int DOSCall
- Mov ax, cs ; Return our segment
- IRet
-
- CheckDes: Cmp al, 'd' ; desactivation requested?
- Je SetFlag ; yes -> fill in flag
- Cmp al, 'a' ; activation requested?
- Je ClrFlag ; yes -> fill in flag
- Or al, al ; toggle requested?
- Jne GoOn ; no -> process normally
- Mov al, 'd'
- Sub al, cs:ActFlag
- Jmp Short SetFlag
- ClrFlag: Xor al, al ; set to 0
- SetFlag: Mov cs:ActFlag, al
- IRet
-
- GoOn: Or ah, ah ; is it print char call?
- Jnz PassIt ; no -> ordinary call
- Cmp cs:ActFlag, 0 ; are we active?
- Jne PassIt ; if not -> don't touch
- Push bx ; preserve old BX
- Mov bx, Offset MainTable2 ; point to xlation table
- Xlat cs:MainTable2 ; translate
- Pop bx ; restore old bx
- PassIt: PushF ; Push flags to...
-
- Assume ds:Nothing ; ... simulate ...
- Call OldPi ; ... interrupt call
- IRet
-
- CheckLength = $ - CheckStart
-
- Printerceptor EndP
-
- PrinterceptorEnd Label Byte
-
- Transient: Cld ; all string intructions forward
- Mov dx, Offset InterName ; show our name
- Mov ah, PrintString ;
- Int DOSCall
- Mov dx, Offset Predicate ; ... and first part of
- Mov ah, PrintString ; completion message
- Int DOSCall
- Call ParseArgs
- Cmp ah, 'h' ; show usage screen?
- Je Usage
- Call CheckPresence ; Check if we are already there
- Cmp ah, 'l' ; load request?
- Je Install
-
- Cmp ah, 'u' ; unload request?
- Je Unload
-
- Or cx, cx ; are we already loaded?
- Jnz DoInstall ; if not, load.
-
- XChg ah, al ; function code into al
- Mov ah, SpecialFunc ; special code into ah
- Int Printer ; must be 'a', 'd', 0
- Or al, al ; return code?
- Jz Activated ; if 0: is now activated
- Mov dx, Offset DesactivateMsg
- Jmp Short ShowMsg
-
- Activated: Mov dx, Offset ActivateMsg
- Jmp Short ShowMsg
-
- Unload: Or cx, cx ; are we already loaded?
- Jz DoUnload ; if so, do the unloading
- Mov dx, Offset UnloadedMsg
- Jmp Short ShowMsg
-
- DoUnload: XChg ah, al
- Mov ah, SpecialFunc
- Push ds ; save our data segment address
- Int Printer ; routine's seg returned in ax
- Pop ds ; retrieve data segment address
- Mov es, ax ; memory of routine:
- Mov ah, FreeMemory ; free it!
- Int DOSCall
- Mov dx, Offset UnloadMsg ; report unloading
- Jmp Short ShowMsg
-
- ;
- ; show usage screen:
- ;
-
- Usage: Mov dx, Offset ProgName ; display programme header
- Mov cx, ProgName-EndHeader
- Mov ah, 40h ; output message to stdout
- Mov bx, 1
- Int DOSCall
-
- Mov dx, Offset UsageText ; display usage screen, part 1
- Mov ah, PrintString ; output message
- Int DOSCall
- Mov dx, Offset UsageText2 ; display usage screen, part 2
-
- ShowMsg: Mov ah, PrintString ; output message
- Int DOSCall
-
- Mov ax, Finish ; terminate without error
- Int DOSCall
-
- ;
- ; the following is the installation code:
- ;
-
- Install: Or cx, cx ; are we already there?
- Jnz DoInstall
-
- Mov dx, Offset LoadedMsg ; if so, say so; do nothing else
- Jmp Short ShowMsg
-
- DoInstall: Mov ax, GetPrinterVec ; Get address of old INT 17h
- Int DOSCall ; handler...
- Mov OldPIOfs, bx ; and save it
- Mov OldPISeg, es
-
- Mov dx, Offset Printerceptor; Replace old handler pointer
- Mov ax, SetPrinterVec ; with one pointing to ourselves
- Int DOSCall
-
- Xor al, al ; mark active
- Mov ActFlag, al
-
- Mov si, Offset XMainTable ; the dirty bits: relocate
- Mov di, Offset XMainTable2 ; translation table over
- Push ds ; cmd line in PSP
- Pop es
- Mov cx, MainTableEnd - XMainTable
- Rep MovsB
-
- Mov dx, Offset LoadMsg ; boast success
- Mov ah, PrintString
- Int DOSCall
-
- Mov es, ds:[2Ch] ; environment segment:
- Mov ah, FreeMemory ; free it!
- Int DOSCall
-
- Mov dx, Offset PrinterceptorEnd ; calculate our resident
- Mov cx, 4 ; length
- ShR dx, cl
- Inc dx
- Mov ax, DOSTSR
- Int DOSCall ; Terminate and stay resident
-
-
- ParseArgs Proc Near
- ;
- ; scan command line for arguments; only arguments supported:
- ; /l : load into memory
- ; /u : unload
- ; /d : desactivate
- ; /a : activate
- ; nothing : load or toggle
- ; anything else : usage screen
- ; return cmd letter (lower case) in ah; 0 if no arg, 'h' if illegal args
- ;
-
- Mov si, Offset CmdLine + 1 ; point to command line
- Xor ah, ah ; init cmd marker
-
- 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: Or ah, ah ; cmd already found?
- Jnz PAUsage ; illegal if so!
- Lodsb ; which switch?
- Or al, 20h ; convert to lower case
- Cmp al, 'l' ; request loading?
- Je PAOK ; skip if so
- Cmp al, 'u' ; request unloading?
- Je PAOK ; skip if so
- Cmp al, 'd' ; request desactivation?
- Je PAOK ; skip if so
- Cmp al, 'a' ; request for activation?
- Jne PAUsage ; skip if not
- PAOK: XChg ah, al ; store cmd
- Jmp Short PANext ; and scan on
-
- PAUsage: Mov ah, 'h' ; otherwise illegal arg
-
- PADone: Ret
- EndP ParseArgs
-
- CheckPresence Proc Near
- ;
- ; Check whether we are already in memory.
- ; Iff so, CX = 0.
- ; Modifies si, di, cx
- ;
- Push ax ; save ax on stack
- Mov ax,GetPrinterVec ; get pointer to Int 17h handler
- Int DOSCall ; in ES:BX
- Mov di, bx ; move offset into DI
- Mov si, Offset Printerceptor ; our address in DS:SI
- Mov cx, CheckLength ; length to check
- Rep Cmpsb ; check all those bytes
- Pop ax ; restore ax
- Ret ; result code is in cx
- CheckPresence EndP
-
- ;
- ; Usage info:
- ;
-
- UsageText db Return, LineFeed, 'Usage: '
- InterName db 'xlatr $'
- UsageText2 db '[/x]', Return, LineFeed, 'where', Return, LineFeed
- db 'x=L to load into memory', Return, LineFeed
- db 'x=U to unload', Return, LineFeed
- db 'x=D to desactivate', Return, LineFeed
- db 'x=A to activate', Return, LineFeed
- db 'no argument loads or toggles status', Return, LineFeed
- db Return, LineFeed, '$'
-
- Predicate db 'has been $' ; miserly storing activity info
- UnloadMsg db 'un'
- LoadMsg db 'loaded.$'
- DesactivateMsg db 'des'
- ActivateMsg db 'activated.$'
- UnloadedMsg db 'un'
- LoadedMsg db 'loaded already.$'
-
-
- XMainTable db 0, Return ; to keep memory mappers happy
- ; (after relocation over PSP)
-
- ; 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
-
- CSeg EndS
- End Start
-