;Mein kleiner ANSI-Treiber
;Untersttzt auch LESS-Sequenzen (NROFF)
;Zapft nur den Int29 (Console Output) an, nicht aber Int2F, um die
;Deinstallation zu erleichtern -
;leider gibt es so keine standardm„áige Erkennungsroutine.
;Fr Selbst-Assemblierer: die PROLOG.ASM befindet sich unter
;"http://www.tu-chemnitz.de/~heha/hs_freeware/asmutil.zip"
include prolog.asm
org 0c0h
OldInt29 dd ?
last dw ? ;Die letzten beiden Buchstaben
argn db ? ;Anzahl der Argumente
argv db 5 dup (?) ;Argumentwerte
curv dw ? ;Cursor-Merker
org 100h
jmp start1
ctrl0 db 0c0h ;Allgemeine Zelle
;Bit7: ANSI-Treiber EIN
;Bit6: LESS-Treiber EIN
;Bit5: Letztes Zeichen war Ziffer
;Bit4: war mal Invers
;Bit3: war mal Hidden
;Bit2-0: alte VFarbe, falls Hidden
attrib db 7 ;Zeichenfarbe
NewInt29:
sti
push ax bx cx dx ds es
LD ds,cs
mov dx,40h
mov es,dx ;ins BIOS
mov dx,[last]
mov bl,7 ;Standardvorgabe
test [ctrl0],80h ;ANSI aktiv?
jz NoAnsi
;+++ ANSI-Behandlung +++
mov bl,[attrib]
cmp dx,27*256+'['
jnz NoAnsiSeq
call AnsiSeq
jr Exi
NoAnsiSeq:
cmp al,27 ;Escape?
jz FiltOut
cmp dl,27 ;Escape als vorangegangenes Zeichen?
jnz AnsiChr
cmp al,'['
jz FiltOut
push ax
mov al,dl
call PutColor
VID 0eh
pop ax
AnsiChr: test [ctrl0],40h ;DAZU noch LESS?
jz nigr ;nein, farbig ausgeben
NoAnsi: test [ctrl0],40h ;LESS aktiv?
jz PutOut
;+++ LESS-Behandlung +++
both: cmp dx,'_'*256+8 ;Underscore und Backstep?
jz nige ;zum Gelbling!
cmp dl,8
jnz nigr
cmp dh,al ;Gleicher Buchstabe?
jnz nigr ;grau oder ANSI-farben
;GRšN
and bl,not 0fh
or bl,2 ;Grn-Override
jr nigr
nige: ;GELB
and bl,not 0fh
or bl,0eh ;Gelb-Override
nigr: ;GRAU
call PutColor
cmp al,0ah ;Cursor Down?
jnz PutOut
push dx
call GetCursor ;PA: DX
cmp dh,[es:84h] ;Letzte Zeile?
jnz PutO1 ;nein, normal weiter
xor cx,cx
mov dl,[es:4ah] ;Rechte Spalte
dec dl
mov bh,[attrib]
VID 6,1 ;1 Zeile rollen
pop dx
mov al,0ah
jr FiltOut
PutO1: pop dx
;ohne alles ganz einfach
PutOut: VID 0eh
FiltOut: ;Gar nichts ausgeben, nur zurckhalten
xchg dh,dl
mov dl,al
mov [last],dx
Exi: pop es ds dx cx bx ax
iret
proc PutColor ;' ' mit Farbe BL ausgeben
cmp al,7
jz @@e
cmp al,8
jz @@e
cmp al,10
jz @@e
cmp al,13
jz @@e
push cx ax
mov bh,[es:62h]
mov cx,1
VID 9,' '
pop ax cx
@@e: ret
endp
proc AnsiSeq
push si
mov bl,[argn] ;Erst mal BX hinstellen
xor bh,bh
add bx,ofs argv-1
sub al,'0'
jc @@1
cmp al,10 ;Ziffer?
jnc @@1 ;nein
test [ctrl0],20h ;War eine Ziffer vorneweg?
jnz @@2 ;ja - nur Zahl bilden
inc [argn] ;nein - Neues Argument
inc bx
jr @@3 ;1. Ziffer eintragen
@@2: mov ah,[bx] ;Alte Ziffer verzehnfachen
add ah,ah
add ah,ah
add ah,[bx]
add ah,ah
add al,ah
@@3: mov [bx],al
or [ctrl0],20h
jr @@e
@@1:
add al,'0'
call subfunc
@@e: pop si
ret
endp
proc GetCursor
push bx
mov bl,[es:62h]
xor bh,bh
add bl,bl
mov dx,[es:50h+bx] ;GetCursor ohne BIOS-Ruf
pop bx
ret
endp
proc subfunc
mov si,ofs UPT
call upv
jc endansi ;Funktion nicht untersttzt
call GetCursor
cmp [argn],1 ;CY=1 wenn ARGN=0
call [wo si]
endansi:xor ax,ax
mov [last],ax ;L”schen der ANSI-Vergangenheit
mov [wo argn],ax ;Keine Argumente mehr
mov [wo argv+1],ax ;Argumente sicherheitshalber nullsetzen
and [ctrl0],not 20h ;Ende einer Ziffernfolge
ret
endp
upt: dvt ';',afsemi ;ANSI-Funktion fr Semikolon
dvt 'H',afh
dvt 'f',afh
dvt 'A',afa
dvt 'B',afb
dvt 'C',afc
dvt 'D',afd
dvt 's',afs
dvt 'u',afu
dvt 'J',afj
dvt 'K',afk
dvt 'm',afm
dvt '=',afgleich
dvt 'h',afx
dvt 'l',afx
db -1
;=== Hilfsfunktionen mit Stackkorrektur ===
afsemi: and [ctrl0],not 20h ;Ende einer Ziffernfolge
afgleich:
pop si ;Stack abr„umen
ret ;1 Ebene drber
;=== Cursorfunktionen ===
afa: sbb dh,[argv]
jnc setcur
xor dh,dh
jr setcur
afb: adc dh,[argv]
jc afb1
cmp dh,[es:84h] ;Letzte Zeile
jc setcur
afb1: mov dh,[es:84h]
jr setcur
afc: adc dl,[argv]
jc afc1
cmp dl,[es:4ah]
jc setcur
afc1: mov dl,[es:4ah]
dec dl
jr setcur
afd: sbb dl,[argv]
jnc setcur
xor dl,dl
jr setcur
afh: mov dx,[wo argv]
xchg dh,dl ;Vertauschen erforderlich
cmp dh,[es:84h]
ja retu
cmp dl,[es:4ah]
jc setcur ;zum Cursorpositionieren!
ret
;=== Zeilen- und Bildschirml”schen ===
afj: cmp [argv],2 ;mind. 1 Parameter, der "2" ist?
jnz retu ;nein, dann KEIN CLS
xor cx,cx
mov dl,[es:4ah] ;Spaltenzahl
dec dl
mov dh,[es:84h]
mov bh,[attrib]
VID 0600h ;Bildschirm l”schen
xor dx,dx
setcur: mov bh,[es:62h]
VID 02h ;Cursor zu 0/0
retu: ret
afk: mov cx,dx
mov dl,[es:4ah] ;Spaltenzahl
dec dl
mov bh,[attrib]
VID 0600h ;Zeilenrest l”schen
ret
;=== Cursor retten und wiederherstellen ===
afs: mov [curv],dx ;Cursorpos speichern
ret
afu: mov dx,[curv]
jr SetCur
;=== Farben und Attribute w„hlen ===
afm: mov bx,ofs argv ;zun„chst auf "argv"
mov cl,[argn]
xor ch,ch
jcxz retu
afml:
mov al,[bx]
cmp al,30
jc novf
cmp al,38
jnc novf
sub al,30
push bx
mov bx,ofs BRevTab
xlat
pop bx
mov ah,not 7
jr afm1 ;Neue Vordergrundfarbe
novf:
cmp al,40
jc nohf
cmp al,48
jnc nohf
sub al,40
push bx
mov bx,ofs BRevTab
xlat
pop bx
push cx
mov cl,4
rol al,cl ;High- und Low-Nibble vertauschen
pop cx
mov ah,not 70h
afm1: call atMani
jr afme
nohf:
mov si,ofs atUvt
call upv
jc afme
call [wo si]
afme:
inc bx ;n„chstes Argument
loop afml
ret
BRevTab: ;Bitreversionstabelle fr korrekte Farben
db 0,4,2,6,1,5,3,7
;+++ dazu Unterfunktionen +++
atReset:
mov [attrib],7 ;Blinken und Intensiv AUS, Standardfarbe
ret
atIntens:
or [attrib],8
ret
atUnderl:
mov ax,0f801h ;Vordergrund BLAU ergibt Underline
jr atMani ;Attribut manipulieren
atFlash:
or [attrib],80h
ret
atInvert:
mov ax,8870h
atMani:
and ah,[attrib] ;Alte HFarbe ausmaskieren
or al,ah
mov [attrib],al ;Neue Hintergrundfarbe (bzw. VFarbe)
atRetu: ret
atHide:
mov ax,8800h
jr atMani ;VFarbe:=HFarbe
atUvt: dvt 0,atReset
dvt 1,atIntens
dvt 4,atUnderl
dvt 5,atFlash
dvt 7,atInvert
dvt 8,atHide
db -1
;=== Videomodus w„hlen ===
afx: jc afxe ;wenn argn=0
mov al,[argv]
VID 0
afxe: ret
uv2: add si,3
proc upv ;Unterprogrammverteiler
cld
cmp [si],al
jz @@1
cmp [by si],-1 ;Abschluábyte?
cmc
jnc uv2
;CY=1 - Fehler: Funktion nicht untersttzt (Tabelle zu Ende)
@@1: inc si
ret
endp
ResEnd:
;===== Transientes Programmteil =====
SetLess:
mov ah,40h
jr SetBit
SetAnsi:
mov ah,80h
SetBit: lodsb
cmp al,'+'
jnz sa1
or [es:ctrl0],ah
jr scancl
sa1: cmp al,'-'
jnz scancl
not ah
and [es:ctrl0],ah
jr scancl
start1: ;Hier gehts richtig los!
Print Text0 ;Erst mal 'ne Message
mov cl,-1 ;Alle Bits setzen
DOS 3529h ;Alter Int29
SES <OldInt29>,bx
cmp bx,offset NewInt29
jne NotInst
mov si,110h
mov di,si
mov cx,40h ;128 Bytes der Speicherkopien vergleichen
cld
repe cmpsw ;Wenn okay dann CL=0!
jr IsInst
NotInst:
LD es,cs ;fein rckstellen!
IsInst: mov si,81h
cld
scancl: lodsb
cmp al,'-'
jz scancl
cmp al,'?'
je help
and al,not 20h
cmp al,'U'
je UnInst
cmp al,'H'
je help
cmp al,'A'
je SetAnsi
cmp al,'L'
je SetLess
cmp al,0dh
jne scancl
or cl,cl
jnz newinst
call OutInfo
jr LFOut
UnInst: mov dx,ofs Text2
or cl,cl
jnz TXTOut
lds dx,[es:OldInt29]
DOS 2529h ;den Interrupt zurckstellen
DOS 49h ;den Speicher ab es freigeben
LD ds,cs ;verpfuschtes Segment zurckholen
mov dx,ofs Text3
jr TXTOut
help: mov dx,ofs TextH
TXTOut: DOS 9
LFOut: PRINT nl$
DOS 4c00h
newinst:
call endansi ;ANSI AUS
mov dx,ofs NewInt29
DOS 2529h ;SetInt29
mov es,[2ch] ;Segment Environment
DOS 49h ;ENV-Speicher ab es freigeben
mov dx,ofs Text1 ;"geladen"
mov ax,cs
cmp ax,0a000h
jc newlow
mov dx,ofs Text1a ;"hochgeladen"
newlow: DOS 9
mov dx,ParaRes
DOS 3100h ;TSR
OutInfo: ;Statusanzeige
PRINT Text4
test [es:ctrl0],80h
call OnOff ;je nach Z-Flag
PRINT Text5
test [es:ctrl0],40h
call OnOff
ret
OnOff: mov dx,ofs off$
jz pOff
mov dx,ofs on$
pOff: DOS 9
ret
Text0 db 'ANSI 1.02 (haftmann#software): $'
Text1a db 'hoch'
Text1 db 'geladen, Speicherbedarf '
dcd %((ParaRes)*16+16)
db ' Bytes.',nl,'$'
Text2 db 'TSR nicht installiert oder verdeckt!$'
Text3 db 'vom Speicher entfernt.$'
Text4 db 'Status ANSI $'
Text5 db ', LESS $'
on$ db 'EIN (+)$'
off$ db 'AUS (-)$'
TextH db 'Kombinierter ANSI- und LESS-Treiber, FREEWARE',nl
db 'Parameter: (keiner) ANSI.COM laden oder Status anzeigen',nl
db ' /a{+|-} ANSI-Treiber ein/aus, Standard EIN',nl
db ' /l{+|-} LESS-Treiber ein/aus, Standard EIN',nl
db ' /h oder /? Diese Hilfe',nl
db ' /u TSR entfernen$'
nl$ db nl,'$'
ENDC
Detected encoding: UTF-8 | 0
|